Merge branch 'master' of /home/davem/src/GIT/linux-2.6/

Conflicts:
	include/net/tcp.h
diff --git a/Documentation/ABI/stable/sysfs-driver-qla2xxx b/Documentation/ABI/stable/sysfs-driver-qla2xxx
new file mode 100644
index 0000000..9a59d84
--- /dev/null
+++ b/Documentation/ABI/stable/sysfs-driver-qla2xxx
@@ -0,0 +1,8 @@
+What:		/sys/bus/pci/drivers/qla2xxx/.../devices/*
+Date:		September 2009
+Contact:	QLogic Linux Driver <linux-driver@qlogic.com>
+Description:	qla2xxx-udev.sh currently looks for uevent CHANGE events to
+		signal a firmware-dump has been generated by the driver and is
+		ready for retrieval.
+Users:		qla2xxx-udev.sh.  Proposed changes should be mailed to
+		linux-driver@qlogic.com
diff --git a/Documentation/ABI/testing/procfs-diskstats b/Documentation/ABI/testing/procfs-diskstats
index 9923390..f91a973 100644
--- a/Documentation/ABI/testing/procfs-diskstats
+++ b/Documentation/ABI/testing/procfs-diskstats
@@ -8,7 +8,7 @@
 		 1 - major number
 		 2 - minor mumber
 		 3 - device name
-		 4 - reads completed succesfully
+		 4 - reads completed successfully
 		 5 - reads merged
 		 6 - sectors read
 		 7 - time spent reading (ms)
diff --git a/Documentation/ABI/testing/sysfs-block b/Documentation/ABI/testing/sysfs-block
index 5f3beda..d2f9033 100644
--- a/Documentation/ABI/testing/sysfs-block
+++ b/Documentation/ABI/testing/sysfs-block
@@ -4,7 +4,7 @@
 Description:
 		The /sys/block/<disk>/stat files displays the I/O
 		statistics of disk <disk>. They contain 11 fields:
-		 1 - reads completed succesfully
+		 1 - reads completed successfully
 		 2 - reads merged
 		 3 - sectors read
 		 4 - time spent reading (ms)
diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb
index 7772928..deb6b48 100644
--- a/Documentation/ABI/testing/sysfs-bus-usb
+++ b/Documentation/ABI/testing/sysfs-bus-usb
@@ -144,3 +144,16 @@
 
 		Write a 1 to force the device to disconnect
 		(equivalent to unplugging a wired USB device).
+
+What:		/sys/bus/usb/drivers/.../remove_id
+Date:		November 2009
+Contact:	CHENG Renquan <rqcheng@smu.edu.sg>
+Description:
+		Writing a device ID to this file will remove an ID
+		that was dynamically added via the new_id sysfs entry.
+		The format for the device ID is:
+		idVendor idProduct.	After successfully
+		removing an ID, the driver will no longer support the
+		device.  This is useful to ensure auto probing won't
+		match the driver to the device.  For example:
+		# echo "046d c315" > /sys/bus/usb/drivers/foo/remove_id
diff --git a/Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc b/Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc
index 4e8106f..25b1e75 100644
--- a/Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc
+++ b/Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc
@@ -23,3 +23,16 @@
                 Since this relates to security (specifically, the
                 lifetime of PTKs and GTKs) it should not be changed
                 from the default.
+
+What:           /sys/class/uwb_rc/uwbN/wusbhc/wusb_phy_rate
+Date:           August 2009
+KernelVersion:  2.6.32
+Contact:        David Vrabel <david.vrabel@csr.com>
+Description:
+                The maximum PHY rate to use for all connected devices.
+                This is only of limited use for testing and
+                development as the hardware's automatic rate
+                adaptation is better then this simple control.
+
+                Refer to [ECMA-368] section 10.3.1.1 for the value to
+                use.
diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
index a703b9e..974e29f 100644
--- a/Documentation/ABI/testing/sysfs-devices-system-cpu
+++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
@@ -136,6 +136,24 @@
 		See files in Documentation/cpuidle/ for more information.
 
 
+What:		/sys/devices/system/cpu/cpu#/cpufreq/*
+Date:		pre-git history
+Contact:	cpufreq@vger.kernel.org
+Description:	Discover and change clock speed of CPUs
+
+		Clock scaling allows you to change the clock speed of the
+		CPUs on the fly. This is a nice method to save battery
+		power, because the lower the clock speed, the less power
+		the CPU consumes.
+
+		There are many knobs to tweak in this directory.
+
+		See files in Documentation/cpu-freq/ for more information.
+
+		In particular, read Documentation/cpu-freq/user-guide.txt
+		to learn how to control the knobs.
+
+
 What:      /sys/devices/system/cpu/cpu*/cache/index*/cache_disable_X
 Date:      August 2008
 KernelVersion:	2.6.27
diff --git a/Documentation/DMA-mapping.txt b/Documentation/DMA-mapping.txt
index 01f24e9..ecad88d 100644
--- a/Documentation/DMA-mapping.txt
+++ b/Documentation/DMA-mapping.txt
@@ -214,7 +214,7 @@
 Here is pseudo-code showing how this might be done:
 
 	#define PLAYBACK_ADDRESS_BITS	DMA_BIT_MASK(32)
-	#define RECORD_ADDRESS_BITS	0x00ffffff
+	#define RECORD_ADDRESS_BITS	DMA_BIT_MASK(24)
 
 	struct my_sound_card *card;
 	struct pci_dev *pdev;
@@ -224,14 +224,14 @@
 		card->playback_enabled = 1;
 	} else {
 		card->playback_enabled = 0;
-		printk(KERN_WARN "%s: Playback disabled due to DMA limitations.\n",
+		printk(KERN_WARNING "%s: Playback disabled due to DMA limitations.\n",
 		       card->name);
 	}
 	if (!pci_set_dma_mask(pdev, RECORD_ADDRESS_BITS)) {
 		card->record_enabled = 1;
 	} else {
 		card->record_enabled = 0;
-		printk(KERN_WARN "%s: Record disabled due to DMA limitations.\n",
+		printk(KERN_WARNING "%s: Record disabled due to DMA limitations.\n",
 		       card->name);
 	}
 
diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl
index 94a20fe..f9a6e2c 100644
--- a/Documentation/DocBook/device-drivers.tmpl
+++ b/Documentation/DocBook/device-drivers.tmpl
@@ -293,10 +293,23 @@
 
   <chapter id="input_subsystem">
      <title>Input Subsystem</title>
+     <sect1><title>Input core</title>
 !Iinclude/linux/input.h
 !Edrivers/input/input.c
 !Edrivers/input/ff-core.c
 !Edrivers/input/ff-memless.c
+     </sect1>
+     <sect1><title>Polled input devices</title>
+!Iinclude/linux/input-polldev.h
+!Edrivers/input/input-polldev.c
+     </sect1>
+     <sect1><title>Matrix keyboars/keypads</title>
+!Iinclude/linux/input/matrix_keypad.h
+     </sect1>
+     <sect1><title>Sparse keymap support</title>
+!Iinclude/linux/input/sparse-keymap.h
+!Edrivers/input/sparse-keymap.c
+     </sect1>
   </chapter>
 
   <chapter id="spi">
diff --git a/Documentation/DocBook/dvb/dvbapi.xml b/Documentation/DocBook/dvb/dvbapi.xml
index 4fc5b23..63c528f 100644
--- a/Documentation/DocBook/dvb/dvbapi.xml
+++ b/Documentation/DocBook/dvb/dvbapi.xml
@@ -30,6 +30,14 @@
 <revhistory>
 <!-- Put document revisions here, newest first. -->
 <revision>
+	<revnumber>2.0.2</revnumber>
+	<date>2009-10-25</date>
+	<authorinitials>mcc</authorinitials>
+	<revremark>
+		documents FE_SET_FRONTEND_TUNE_MODE and FE_DISHETWORK_SEND_LEGACY_CMD ioctls.
+	</revremark>
+</revision>
+<revision>
 <revnumber>2.0.1</revnumber>
 <date>2009-09-16</date>
 <authorinitials>mcc</authorinitials>
@@ -85,3 +93,8 @@
     &sub-examples;
   </chapter>
 <!-- END OF CHAPTERS -->
+  <appendix id="frontend_h">
+    <title>DVB Frontend Header File</title>
+    &sub-frontend-h;
+  </appendix>
+
diff --git a/Documentation/DocBook/dvb/dvbproperty.xml b/Documentation/DocBook/dvb/dvbproperty.xml
new file mode 100644
index 0000000..5f57c7c
--- /dev/null
+++ b/Documentation/DocBook/dvb/dvbproperty.xml
@@ -0,0 +1,318 @@
+<section id="FE_GET_PROPERTY">
+<title>FE_GET_PROPERTY/FE_SET_PROPERTY</title>
+
+<section id="isdbt">
+	<title>ISDB-T frontend</title>
+	<para>This section describes shortly what are the possible parameters in the Linux
+		DVB-API called "S2API" and now DVB API 5 in order to tune an ISDB-T/ISDB-Tsb
+		demodulator:</para>
+
+	<para>This ISDB-T/ISDB-Tsb API extension should reflect all information
+		needed to tune any ISDB-T/ISDB-Tsb hardware. Of course it is possible
+		that some very sophisticated devices won't need certain parameters to
+		tune.</para>
+
+	<para>The information given here should help application writers to know how
+		to handle ISDB-T and ISDB-Tsb hardware using the Linux DVB-API.</para>
+
+	<para>The details given here about ISDB-T and ISDB-Tsb are just enough to
+		basically show the dependencies between the needed parameter values,
+		but surely some information is left out. For more detailed information
+		see the following documents:</para>
+
+	<para>ARIB STD-B31 - "Transmission System for Digital Terrestrial
+		Television Broadcasting" and</para>
+	<para>ARIB TR-B14 - "Operational Guidelines for Digital Terrestrial
+		Television Broadcasting".</para>
+
+	<para>In order to read this document one has to have some knowledge the
+		channel structure in ISDB-T and ISDB-Tsb. I.e. it has to be known to
+		the reader that an ISDB-T channel consists of 13 segments, that it can
+		have up to 3 layer sharing those segments, and things like that.</para>
+
+	<para>Parameters used by ISDB-T and ISDB-Tsb.</para>
+
+	<section id="isdbt-parms">
+		<title>Parameters that are common with DVB-T and ATSC</title>
+
+		<section id="isdbt-freq">
+			<title><constant>DTV_FREQUENCY</constant></title>
+
+			<para>Central frequency of the channel.</para>
+
+			<para>For ISDB-T the channels are usally transmitted with an offset of 143kHz. E.g. a
+				valid frequncy could be 474143 kHz. The stepping is bound to the bandwidth of
+				the channel which is 6MHz.</para>
+
+			<para>As in ISDB-Tsb the channel consists of only one or three segments the
+				frequency step is 429kHz, 3*429 respectively. As for ISDB-T the
+				central frequency of the channel is expected.</para>
+		</section>
+
+		<section id="isdbt-bw">
+			<title><constant>DTV_BANDWIDTH_HZ</constant> (optional)</title>
+
+			<para>Possible values:</para>
+
+			<para>For ISDB-T it should be always 6000000Hz (6MHz)</para>
+			<para>For ISDB-Tsb it can vary depending on the number of connected segments</para>
+
+			<para>Note: Hardware specific values might be given here, but standard
+				applications should not bother to set a value to this field as
+				standard demods are ignoring it anyway.</para>
+
+			<para>Bandwidth in ISDB-T is fixed (6MHz) or can be easily derived from
+				other parameters (DTV_ISDBT_SB_SEGMENT_IDX,
+				DTV_ISDBT_SB_SEGMENT_COUNT).</para>
+		</section>
+
+		<section id="isdbt-delivery-sys">
+			<title><constant>DTV_DELIVERY_SYSTEM</constant></title>
+
+			<para>Possible values: <constant>SYS_ISDBT</constant></para>
+		</section>
+
+		<section id="isdbt-tx-mode">
+			<title><constant>DTV_TRANSMISSION_MODE</constant></title>
+
+			<para>ISDB-T supports three carrier/symbol-size: 8K, 4K, 2K. It is called
+				'mode' in the standard: Mode 1 is 2K, mode 2 is 4K, mode 3 is 8K</para>
+
+			<para>Possible values: <constant>TRANSMISSION_MODE_2K</constant>, <constant>TRANSMISSION_MODE_8K</constant>,
+				<constant>TRANSMISSION_MODE_AUTO</constant>, <constant>TRANSMISSION_MODE_4K</constant></para>
+
+			<para>If <constant>DTV_TRANSMISSION_MODE</constant> is set the <constant>TRANSMISSION_MODE_AUTO</constant> the
+				hardware will try to find the correct FFT-size (if capable) and will
+				use TMCC to fill in the missing parameters.</para>
+
+			<para><constant>TRANSMISSION_MODE_4K</constant> is added at the same time as the other new parameters.</para>
+		</section>
+
+		<section id="isdbt-guard-interval">
+			<title><constant>DTV_GUARD_INTERVAL</constant></title>
+
+			<para>Possible values: <constant>GUARD_INTERVAL_1_32</constant>, <constant>GUARD_INTERVAL_1_16</constant>, <constant>GUARD_INTERVAL_1_8</constant>,
+				<constant>GUARD_INTERVAL_1_4</constant>, <constant>GUARD_INTERVAL_AUTO</constant></para>
+
+			<para>If <constant>DTV_GUARD_INTERVAL</constant> is set the <constant>GUARD_INTERVAL_AUTO</constant> the hardware will
+				try to find the correct guard interval (if capable) and will use TMCC to fill
+				in the missing parameters.</para>
+		</section>
+	</section>
+	<section id="isdbt-new-parms">
+		<title>ISDB-T only parameters</title>
+
+		<section id="isdbt-part-rec">
+			<title><constant>DTV_ISDBT_PARTIAL_RECEPTION</constant></title>
+
+			<para><constant>If DTV_ISDBT_SOUND_BROADCASTING</constant> is '0' this bit-field represents whether
+				the channel is in partial reception mode or not.</para>
+
+			<para>If '1' <constant>DTV_ISDBT_LAYERA_*</constant> values are assigned to the center segment and
+				<constant>DTV_ISDBT_LAYERA_SEGMENT_COUNT</constant> has to be '1'.</para>
+
+			<para>If in addition <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'
+				<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> represents whether this ISDB-Tsb channel
+				is consisting of one segment and layer or three segments and two layers.</para>
+
+			<para>Possible values: 0, 1, -1 (AUTO)</para>
+		</section>
+
+		<section id="isdbt-sound-bcast">
+			<title><constant>DTV_ISDBT_SOUND_BROADCASTING</constant></title>
+
+			<para>This field represents whether the other DTV_ISDBT_*-parameters are
+				referring to an ISDB-T and an ISDB-Tsb channel. (See also
+				<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>).</para>
+
+			<para>Possible values: 0, 1, -1 (AUTO)</para>
+		</section>
+
+		<section id="isdbt-sb-ch-id">
+			<title><constant>DTV_ISDBT_SB_SUBCHANNEL_ID</constant></title>
+
+			<para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
+
+			<para>(Note of the author: This might not be the correct description of the
+				<constant>SUBCHANNEL-ID</constant> in all details, but it is my understanding of the technical
+				background needed to program a device)</para>
+
+			<para>An ISDB-Tsb channel (1 or 3 segments) can be broadcasted alone or in a
+				set of connected ISDB-Tsb channels. In this set of channels every
+				channel can be received independently. The number of connected
+				ISDB-Tsb segment can vary, e.g. depending on the frequency spectrum
+				bandwidth available.</para>
+
+			<para>Example: Assume 8 ISDB-Tsb connected segments are broadcasted. The
+				broadcaster has several possibilities to put those channels in the
+				air: Assuming a normal 13-segment ISDB-T spectrum he can align the 8
+				segments from position 1-8 to 5-13 or anything in between.</para>
+
+			<para>The underlying layer of segments are subchannels: each segment is
+				consisting of several subchannels with a predefined IDs. A sub-channel
+				is used to help the demodulator to synchronize on the channel.</para>
+
+			<para>An ISDB-T channel is always centered over all sub-channels. As for
+				the example above, in ISDB-Tsb it is no longer as simple as that.</para>
+
+			<para><constant>The DTV_ISDBT_SB_SUBCHANNEL_ID</constant> parameter is used to give the
+				sub-channel ID of the segment to be demodulated.</para>
+
+			<para>Possible values: 0 .. 41, -1 (AUTO)</para>
+		</section>
+
+		<section id="isdbt-sb-seg-idx">
+
+			<title><constant>DTV_ISDBT_SB_SEGMENT_IDX</constant></title>
+
+			<para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
+
+			<para><constant>DTV_ISDBT_SB_SEGMENT_IDX</constant> gives the index of the segment to be
+				demodulated for an ISDB-Tsb channel where several of them are
+				transmitted in the connected manner.</para>
+
+			<para>Possible values: 0 .. <constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant> - 1</para>
+
+			<para>Note: This value cannot be determined by an automatic channel search.</para>
+		</section>
+
+		<section id="isdbt-sb-seg-cnt">
+			<title><constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant></title>
+
+			<para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
+
+			<para><constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant> gives the total count of connected ISDB-Tsb
+				channels.</para>
+
+			<para>Possible values: 1 .. 13</para>
+
+			<para>Note: This value cannot be determined by an automatic channel search.</para>
+		</section>
+
+		<section id="isdb-hierq-layers">
+			<title>Hierarchical layers</title>
+
+			<para>ISDB-T channels can be coded hierarchically. As opposed to DVB-T in
+				ISDB-T hierarchical layers can be decoded simultaneously. For that
+				reason a ISDB-T demodulator has 3 viterbi and 3 reed-solomon-decoders.</para>
+
+			<para>ISDB-T has 3 hierarchical layers which each can use a part of the
+				available segments. The total number of segments over all layers has
+				to 13 in ISDB-T.</para>
+
+			<section id="isdbt-layer-ena">
+				<title><constant>DTV_ISDBT_LAYER_ENABLED</constant></title>
+
+				<para>Hierarchical reception in ISDB-T is achieved by enabling or disabling
+					layers in the decoding process. Setting all bits of
+					<constant>DTV_ISDBT_LAYER_ENABLED</constant> to '1' forces all layers (if applicable) to be
+					demodulated. This is the default.</para>
+
+				<para>If the channel is in the partial reception mode
+					(<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> = 1) the central segment can be decoded
+					independently of the other 12 segments. In that mode layer A has to
+					have a <constant>SEGMENT_COUNT</constant> of 1.</para>
+
+				<para>In ISDB-Tsb only layer A is used, it can be 1 or 3 in ISDB-Tsb
+					according to <constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>. <constant>SEGMENT_COUNT</constant> must be filled
+					accordingly.</para>
+
+				<para>Possible values: 0x1, 0x2, 0x4 (|-able)</para>
+
+				<para><constant>DTV_ISDBT_LAYER_ENABLED[0:0]</constant> - layer A</para>
+				<para><constant>DTV_ISDBT_LAYER_ENABLED[1:1]</constant> - layer B</para>
+				<para><constant>DTV_ISDBT_LAYER_ENABLED[2:2]</constant> - layer C</para>
+				<para><constant>DTV_ISDBT_LAYER_ENABLED[31:3]</constant> unused</para>
+			</section>
+
+			<section id="isdbt-layer-fec">
+				<title><constant>DTV_ISDBT_LAYER*_FEC</constant></title>
+
+				<para>Possible values: <constant>FEC_AUTO</constant>, <constant>FEC_1_2</constant>, <constant>FEC_2_3</constant>, <constant>FEC_3_4</constant>, <constant>FEC_5_6</constant>, <constant>FEC_7_8</constant></para>
+			</section>
+
+			<section id="isdbt-layer-mod">
+				<title><constant>DTV_ISDBT_LAYER*_MODULATION</constant></title>
+
+				<para>Possible values: <constant>QAM_AUTO</constant>, QP<constant>SK, QAM_16</constant>, <constant>QAM_64</constant>, <constant>DQPSK</constant></para>
+
+				<para>Note: If layer C is <constant>DQPSK</constant> layer B has to be <constant>DQPSK</constant>. If layer B is <constant>DQPSK</constant>
+					and <constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>=0 layer has to be <constant>DQPSK</constant>.</para>
+			</section>
+
+			<section id="isdbt-layer-seg-cnt">
+				<title><constant>DTV_ISDBT_LAYER*_SEGMENT_COUNT</constant></title>
+
+				<para>Possible values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1 (AUTO)</para>
+
+				<para>Note: Truth table for <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> and
+					<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> and <constant>LAYER</constant>*_SEGMENT_COUNT</para>
+
+				<informaltable id="isdbt-layer_seg-cnt-table">
+					<tgroup cols="6">
+
+						<tbody>
+							<row>
+								<entry>PR</entry>
+								<entry>SB</entry>
+								<entry>Layer A width</entry>
+								<entry>Layer B width</entry>
+								<entry>Layer C width</entry>
+								<entry>total width</entry>
+							</row>
+
+							<row>
+								<entry>0</entry>
+								<entry>0</entry>
+								<entry>1 .. 13</entry>
+								<entry>1 .. 13</entry>
+								<entry>1 .. 13</entry>
+								<entry>13</entry>
+							</row>
+
+							<row>
+								<entry>1</entry>
+								<entry>0</entry>
+								<entry>1</entry>
+								<entry>1 .. 13</entry>
+								<entry>1 .. 13</entry>
+								<entry>13</entry>
+							</row>
+
+							<row>
+								<entry>0</entry>
+								<entry>1</entry>
+								<entry>1</entry>
+								<entry>0</entry>
+								<entry>0</entry>
+								<entry>1</entry>
+							</row>
+
+							<row>
+								<entry>1</entry>
+								<entry>1</entry>
+								<entry>1</entry>
+								<entry>2</entry>
+								<entry>0</entry>
+								<entry>13</entry>
+							</row>
+						</tbody>
+
+					</tgroup>
+				</informaltable>
+
+			</section>
+
+			<section id="isdbt_layer_t_interl">
+				<title><constant>DTV_ISDBT_LAYER*_TIME_INTERLEAVING</constant></title>
+
+				<para>Possible values: 0, 1, 2, 3, -1 (AUTO)</para>
+
+				<para>Note: The real inter-leaver depth-names depend on the mode (fft-size); the values
+					here are referring to what can be found in the TMCC-structure -
+					independent of the mode.</para>
+			</section>
+		</section>
+	</section>
+</section>
+</section>
diff --git a/Documentation/DocBook/dvb/frontend.h.xml b/Documentation/DocBook/dvb/frontend.h.xml
new file mode 100644
index 0000000..b99644f
--- /dev/null
+++ b/Documentation/DocBook/dvb/frontend.h.xml
@@ -0,0 +1,415 @@
+<programlisting>
+/*
+ * frontend.h
+ *
+ * Copyright (C) 2000 Marcus Metzler &lt;marcus@convergence.de&gt;
+ *                  Ralph  Metzler &lt;ralph@convergence.de&gt;
+ *                  Holger Waechtler &lt;holger@convergence.de&gt;
+ *                  Andre Draszik &lt;ad@convergence.de&gt;
+ *                  for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * 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 Lesser 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.
+ *
+ */
+
+#ifndef _DVBFRONTEND_H_
+#define _DVBFRONTEND_H_
+
+#include &lt;linux/types.h&gt;
+
+typedef enum fe_type {
+        FE_QPSK,
+        FE_QAM,
+        FE_OFDM,
+        FE_ATSC
+} fe_type_t;
+
+
+typedef enum fe_caps {
+        FE_IS_STUPID                    = 0,
+        FE_CAN_INVERSION_AUTO           = 0x1,
+        FE_CAN_FEC_1_2                  = 0x2,
+        FE_CAN_FEC_2_3                  = 0x4,
+        FE_CAN_FEC_3_4                  = 0x8,
+        FE_CAN_FEC_4_5                  = 0x10,
+        FE_CAN_FEC_5_6                  = 0x20,
+        FE_CAN_FEC_6_7                  = 0x40,
+        FE_CAN_FEC_7_8                  = 0x80,
+        FE_CAN_FEC_8_9                  = 0x100,
+        FE_CAN_FEC_AUTO                 = 0x200,
+        FE_CAN_QPSK                     = 0x400,
+        FE_CAN_QAM_16                   = 0x800,
+        FE_CAN_QAM_32                   = 0x1000,
+        FE_CAN_QAM_64                   = 0x2000,
+        FE_CAN_QAM_128                  = 0x4000,
+        FE_CAN_QAM_256                  = 0x8000,
+        FE_CAN_QAM_AUTO                 = 0x10000,
+        FE_CAN_TRANSMISSION_MODE_AUTO   = 0x20000,
+        FE_CAN_BANDWIDTH_AUTO           = 0x40000,
+        FE_CAN_GUARD_INTERVAL_AUTO      = 0x80000,
+        FE_CAN_HIERARCHY_AUTO           = 0x100000,
+        FE_CAN_8VSB                     = 0x200000,
+        FE_CAN_16VSB                    = 0x400000,
+        FE_HAS_EXTENDED_CAPS            = 0x800000,   /* We need more bitspace for newer APIs, indicate this. */
+        FE_CAN_2G_MODULATION            = 0x10000000, /* frontend supports "2nd generation modulation" (DVB-S2) */
+        FE_NEEDS_BENDING                = 0x20000000, /* not supported anymore, don't use (frontend requires frequency bending) */
+        FE_CAN_RECOVER                  = 0x40000000, /* frontend can recover from a cable unplug automatically */
+        FE_CAN_MUTE_TS                  = 0x80000000  /* frontend can stop spurious TS data output */
+} fe_caps_t;
+
+
+struct dvb_frontend_info {
+        char       name[128];
+        fe_type_t  type;
+        __u32      frequency_min;
+        __u32      frequency_max;
+        __u32      frequency_stepsize;
+        __u32      frequency_tolerance;
+        __u32      symbol_rate_min;
+        __u32      symbol_rate_max;
+        __u32      symbol_rate_tolerance;       /* ppm */
+        __u32      notifier_delay;              /* DEPRECATED */
+        fe_caps_t  caps;
+};
+
+
+/**
+ *  Check out the DiSEqC bus spec available on http://www.eutelsat.org/ for
+ *  the meaning of this struct...
+ */
+struct dvb_diseqc_master_cmd {
+        __u8 msg [6];   /*  { framing, address, command, data [3] } */
+        __u8 msg_len;   /*  valid values are 3...6  */
+};
+
+
+struct dvb_diseqc_slave_reply {
+        __u8 msg [4];   /*  { framing, data [3] } */
+        __u8 msg_len;   /*  valid values are 0...4, 0 means no msg  */
+        int  timeout;   /*  return from ioctl after timeout ms with */
+};                      /*  errorcode when no message was received  */
+
+
+typedef enum fe_sec_voltage {
+        SEC_VOLTAGE_13,
+        SEC_VOLTAGE_18,
+        SEC_VOLTAGE_OFF
+} fe_sec_voltage_t;
+
+
+typedef enum fe_sec_tone_mode {
+        SEC_TONE_ON,
+        SEC_TONE_OFF
+} fe_sec_tone_mode_t;
+
+
+typedef enum fe_sec_mini_cmd {
+        SEC_MINI_A,
+        SEC_MINI_B
+} fe_sec_mini_cmd_t;
+
+
+typedef enum fe_status {
+        FE_HAS_SIGNAL   = 0x01,   /* found something above the noise level */
+        FE_HAS_CARRIER  = 0x02,   /* found a DVB signal  */
+        FE_HAS_VITERBI  = 0x04,   /* FEC is stable  */
+        FE_HAS_SYNC     = 0x08,   /* found sync bytes  */
+        FE_HAS_LOCK     = 0x10,   /* everything's working... */
+        FE_TIMEDOUT     = 0x20,   /* no lock within the last ~2 seconds */
+        FE_REINIT       = 0x40    /* frontend was reinitialized,  */
+} fe_status_t;                    /* application is recommended to reset */
+                                  /* DiSEqC, tone and parameters */
+
+typedef enum fe_spectral_inversion {
+        INVERSION_OFF,
+        INVERSION_ON,
+        INVERSION_AUTO
+} fe_spectral_inversion_t;
+
+
+typedef enum fe_code_rate {
+        FEC_NONE = 0,
+        FEC_1_2,
+        FEC_2_3,
+        FEC_3_4,
+        FEC_4_5,
+        FEC_5_6,
+        FEC_6_7,
+        FEC_7_8,
+        FEC_8_9,
+        FEC_AUTO,
+        FEC_3_5,
+        FEC_9_10,
+} fe_code_rate_t;
+
+
+typedef enum fe_modulation {
+        QPSK,
+        QAM_16,
+        QAM_32,
+        QAM_64,
+        QAM_128,
+        QAM_256,
+        QAM_AUTO,
+        VSB_8,
+        VSB_16,
+        PSK_8,
+        APSK_16,
+        APSK_32,
+        DQPSK,
+} fe_modulation_t;
+
+typedef enum fe_transmit_mode {
+        TRANSMISSION_MODE_2K,
+        TRANSMISSION_MODE_8K,
+        TRANSMISSION_MODE_AUTO,
+        TRANSMISSION_MODE_4K
+} fe_transmit_mode_t;
+
+typedef enum fe_bandwidth {
+        BANDWIDTH_8_MHZ,
+        BANDWIDTH_7_MHZ,
+        BANDWIDTH_6_MHZ,
+        BANDWIDTH_AUTO
+} fe_bandwidth_t;
+
+
+typedef enum fe_guard_interval {
+        GUARD_INTERVAL_1_32,
+        GUARD_INTERVAL_1_16,
+        GUARD_INTERVAL_1_8,
+        GUARD_INTERVAL_1_4,
+        GUARD_INTERVAL_AUTO
+} fe_guard_interval_t;
+
+
+typedef enum fe_hierarchy {
+        HIERARCHY_NONE,
+        HIERARCHY_1,
+        HIERARCHY_2,
+        HIERARCHY_4,
+        HIERARCHY_AUTO
+} fe_hierarchy_t;
+
+
+struct dvb_qpsk_parameters {
+        __u32           symbol_rate;  /* symbol rate in Symbols per second */
+        fe_code_rate_t  fec_inner;    /* forward error correction (see above) */
+};
+
+struct dvb_qam_parameters {
+        __u32           symbol_rate; /* symbol rate in Symbols per second */
+        fe_code_rate_t  fec_inner;   /* forward error correction (see above) */
+        fe_modulation_t modulation;  /* modulation type (see above) */
+};
+
+struct dvb_vsb_parameters {
+        fe_modulation_t modulation;  /* modulation type (see above) */
+};
+
+struct dvb_ofdm_parameters {
+        fe_bandwidth_t      bandwidth;
+        fe_code_rate_t      code_rate_HP;  /* high priority stream code rate */
+        fe_code_rate_t      code_rate_LP;  /* low priority stream code rate */
+        fe_modulation_t     constellation; /* modulation type (see above) */
+        fe_transmit_mode_t  transmission_mode;
+        fe_guard_interval_t guard_interval;
+        fe_hierarchy_t      hierarchy_information;
+};
+
+
+struct dvb_frontend_parameters {
+        __u32 frequency;     /* (absolute) frequency in Hz for QAM/OFDM/ATSC */
+                             /* intermediate frequency in kHz for QPSK */
+        fe_spectral_inversion_t inversion;
+        union {
+                struct dvb_qpsk_parameters qpsk;
+                struct dvb_qam_parameters  qam;
+                struct dvb_ofdm_parameters ofdm;
+                struct dvb_vsb_parameters vsb;
+        } u;
+};
+
+
+struct dvb_frontend_event {
+        fe_status_t status;
+        struct dvb_frontend_parameters parameters;
+};
+
+/* S2API Commands */
+#define DTV_UNDEFINED           0
+#define DTV_TUNE                1
+#define DTV_CLEAR               2
+#define DTV_FREQUENCY           3
+#define DTV_MODULATION          4
+#define DTV_BANDWIDTH_HZ        5
+#define DTV_INVERSION           6
+#define DTV_DISEQC_MASTER       7
+#define DTV_SYMBOL_RATE         8
+#define DTV_INNER_FEC           9
+#define DTV_VOLTAGE             10
+#define DTV_TONE                11
+#define DTV_PILOT               12
+#define DTV_ROLLOFF             13
+#define DTV_DISEQC_SLAVE_REPLY  14
+
+/* Basic enumeration set for querying unlimited capabilities */
+#define DTV_FE_CAPABILITY_COUNT 15
+#define DTV_FE_CAPABILITY       16
+#define DTV_DELIVERY_SYSTEM     17
+
+/* ISDB-T and ISDB-Tsb */
+#define DTV_ISDBT_PARTIAL_RECEPTION     18
+#define DTV_ISDBT_SOUND_BROADCASTING    19
+
+#define DTV_ISDBT_SB_SUBCHANNEL_ID      20
+#define DTV_ISDBT_SB_SEGMENT_IDX        21
+#define DTV_ISDBT_SB_SEGMENT_COUNT      22
+
+#define DTV_ISDBT_LAYERA_FEC                    23
+#define DTV_ISDBT_LAYERA_MODULATION             24
+#define DTV_ISDBT_LAYERA_SEGMENT_COUNT          25
+#define DTV_ISDBT_LAYERA_TIME_INTERLEAVING      26
+
+#define DTV_ISDBT_LAYERB_FEC                    27
+#define DTV_ISDBT_LAYERB_MODULATION             28
+#define DTV_ISDBT_LAYERB_SEGMENT_COUNT          29
+#define DTV_ISDBT_LAYERB_TIME_INTERLEAVING      30
+
+#define DTV_ISDBT_LAYERC_FEC                    31
+#define DTV_ISDBT_LAYERC_MODULATION             32
+#define DTV_ISDBT_LAYERC_SEGMENT_COUNT          33
+#define DTV_ISDBT_LAYERC_TIME_INTERLEAVING      34
+
+#define DTV_API_VERSION         35
+
+#define DTV_CODE_RATE_HP        36
+#define DTV_CODE_RATE_LP        37
+#define DTV_GUARD_INTERVAL      38
+#define DTV_TRANSMISSION_MODE   39
+#define DTV_HIERARCHY           40
+
+#define DTV_ISDBT_LAYER_ENABLED 41
+
+#define DTV_ISDBS_TS_ID         42
+
+#define DTV_MAX_COMMAND                         DTV_ISDBS_TS_ID
+
+typedef enum fe_pilot {
+        PILOT_ON,
+        PILOT_OFF,
+        PILOT_AUTO,
+} fe_pilot_t;
+
+typedef enum fe_rolloff {
+        ROLLOFF_35, /* Implied value in DVB-S, default for DVB-S2 */
+        ROLLOFF_20,
+        ROLLOFF_25,
+        ROLLOFF_AUTO,
+} fe_rolloff_t;
+
+typedef enum fe_delivery_system {
+        SYS_UNDEFINED,
+        SYS_DVBC_ANNEX_AC,
+        SYS_DVBC_ANNEX_B,
+        SYS_DVBT,
+        SYS_DSS,
+        SYS_DVBS,
+        SYS_DVBS2,
+        SYS_DVBH,
+        SYS_ISDBT,
+        SYS_ISDBS,
+        SYS_ISDBC,
+        SYS_ATSC,
+        SYS_ATSCMH,
+        SYS_DMBTH,
+        SYS_CMMB,
+        SYS_DAB,
+} fe_delivery_system_t;
+
+struct dtv_cmds_h {
+        char    *name;          /* A display name for debugging purposes */
+
+        __u32   cmd;            /* A unique ID */
+
+        /* Flags */
+        __u32   set:1;          /* Either a set or get property */
+        __u32   buffer:1;       /* Does this property use the buffer? */
+        __u32   reserved:30;    /* Align */
+};
+
+struct dtv_property {
+        __u32 cmd;
+        __u32 reserved[3];
+        union {
+                __u32 data;
+                struct {
+                        __u8 data[32];
+                        __u32 len;
+                        __u32 reserved1[3];
+                        void *reserved2;
+                } buffer;
+        } u;
+        int result;
+} __attribute__ ((packed));
+
+/* num of properties cannot exceed DTV_IOCTL_MAX_MSGS per ioctl */
+#define DTV_IOCTL_MAX_MSGS 64
+
+struct dtv_properties {
+        __u32 num;
+        struct dtv_property *props;
+};
+
+#define <link linkend="FE_GET_PROPERTY">FE_SET_PROPERTY</link>            _IOW('o', 82, struct dtv_properties)
+#define <link linkend="FE_GET_PROPERTY">FE_GET_PROPERTY</link>            _IOR('o', 83, struct dtv_properties)
+
+
+/**
+ * When set, this flag will disable any zigzagging or other "normal" tuning
+ * behaviour. Additionally, there will be no automatic monitoring of the lock
+ * status, and hence no frontend events will be generated. If a frontend device
+ * is closed, this flag will be automatically turned off when the device is
+ * reopened read-write.
+ */
+#define FE_TUNE_MODE_ONESHOT 0x01
+
+
+#define <link linkend="FE_GET_INFO">FE_GET_INFO</link>                _IOR('o', 61, struct dvb_frontend_info)
+
+#define <link linkend="FE_DISEQC_RESET_OVERLOAD">FE_DISEQC_RESET_OVERLOAD</link>   _IO('o', 62)
+#define <link linkend="FE_DISEQC_SEND_MASTER_CMD">FE_DISEQC_SEND_MASTER_CMD</link>  _IOW('o', 63, struct dvb_diseqc_master_cmd)
+#define <link linkend="FE_DISEQC_RECV_SLAVE_REPLY">FE_DISEQC_RECV_SLAVE_REPLY</link> _IOR('o', 64, struct dvb_diseqc_slave_reply)
+#define <link linkend="FE_DISEQC_SEND_BURST">FE_DISEQC_SEND_BURST</link>       _IO('o', 65)  /* fe_sec_mini_cmd_t */
+
+#define <link linkend="FE_SET_TONE">FE_SET_TONE</link>                _IO('o', 66)  /* fe_sec_tone_mode_t */
+#define <link linkend="FE_SET_VOLTAGE">FE_SET_VOLTAGE</link>             _IO('o', 67)  /* fe_sec_voltage_t */
+#define <link linkend="FE_ENABLE_HIGH_LNB_VOLTAGE">FE_ENABLE_HIGH_LNB_VOLTAGE</link> _IO('o', 68)  /* int */
+
+#define <link linkend="FE_READ_STATUS">FE_READ_STATUS</link>             _IOR('o', 69, fe_status_t)
+#define <link linkend="FE_READ_BER">FE_READ_BER</link>                _IOR('o', 70, __u32)
+#define <link linkend="FE_READ_SIGNAL_STRENGTH">FE_READ_SIGNAL_STRENGTH</link>    _IOR('o', 71, __u16)
+#define <link linkend="FE_READ_SNR">FE_READ_SNR</link>                _IOR('o', 72, __u16)
+#define <link linkend="FE_READ_UNCORRECTED_BLOCKS">FE_READ_UNCORRECTED_BLOCKS</link> _IOR('o', 73, __u32)
+
+#define <link linkend="FE_SET_FRONTEND">FE_SET_FRONTEND</link>            _IOW('o', 76, struct dvb_frontend_parameters)
+#define <link linkend="FE_GET_FRONTEND">FE_GET_FRONTEND</link>            _IOR('o', 77, struct dvb_frontend_parameters)
+#define <link linkend="FE_SET_FRONTEND_TUNE_MODE">FE_SET_FRONTEND_TUNE_MODE</link>  _IO('o', 81) /* unsigned int */
+#define <link linkend="FE_GET_EVENT">FE_GET_EVENT</link>               _IOR('o', 78, struct dvb_frontend_event)
+
+#define <link linkend="FE_DISHNETWORK_SEND_LEGACY_CMD">FE_DISHNETWORK_SEND_LEGACY_CMD</link> _IO('o', 80) /* unsigned int */
+
+#endif /*_DVBFRONTEND_H_*/
+</programlisting>
diff --git a/Documentation/DocBook/dvb/frontend.xml b/Documentation/DocBook/dvb/frontend.xml
index 9d89a7b..300ba1f 100644
--- a/Documentation/DocBook/dvb/frontend.xml
+++ b/Documentation/DocBook/dvb/frontend.xml
@@ -73,7 +73,8 @@
 <section id="frontend_info">
 <title>frontend information</title>
 
-<para>Information about the frontend ca be queried with FE_GET_INFO.</para>
+<para>Information about the frontend ca be queried with
+	<link linkend="FE_GET_INFO">FE_GET_INFO</link>.</para>
 
 <programlisting>
 	struct dvb_frontend_info {
@@ -338,7 +339,7 @@
 <entry align="char">
 <para>This system call opens a named frontend device (/dev/dvb/adapter0/frontend0)
  for subsequent use. Usually the first thing to do after a successful open is to
- find out the frontend type with FE_GET_INFO.</para>
+ find out the frontend type with <link linkend="FE_GET_INFO">FE_GET_INFO</link>.</para>
 <para>The device can be opened in read-only mode, which only allows monitoring of
  device status and statistics, or read/write mode, which allows any kind of use
  (e.g. performing tuning operations.)
@@ -478,7 +479,7 @@
  </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_read_status">
+<section id="FE_READ_STATUS">
 <title>FE_READ_STATUS</title>
 <para>DESCRIPTION
 </para>
@@ -492,7 +493,7 @@
 </para>
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
-<para>int ioctl(int fd, int request = FE_READ_STATUS,
+<para>int ioctl(int fd, int request = <link linkend="FE_READ_STATUS">FE_READ_STATUS</link>,
  fe_status_t &#x22C6;status);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
@@ -511,7 +512,7 @@
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_READ_STATUS for this command.</para>
+<para>Equals <link linkend="FE_READ_STATUS">FE_READ_STATUS</link> for this command.</para>
 </entry>
  </row><row><entry
  align="char">
@@ -542,7 +543,7 @@
  </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_read_ber">
+<section id="FE_READ_BER">
 <title>FE_READ_BER</title>
 <para>DESCRIPTION
 </para>
@@ -557,7 +558,7 @@
 </para>
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
-<para>int ioctl(int fd, int request = FE_READ_BER,
+<para>int ioctl(int fd, int request = <link linkend="FE_READ_BER">FE_READ_BER</link>,
  uint32_t &#x22C6;ber);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
@@ -575,7 +576,7 @@
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_READ_BER for this command.</para>
+<para>Equals <link linkend="FE_READ_BER">FE_READ_BER</link> for this command.</para>
 </entry>
  </row><row><entry
  align="char">
@@ -619,7 +620,7 @@
  </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_read_snr">
+<section id="FE_READ_SNR">
 <title>FE_READ_SNR</title>
 
 <para>DESCRIPTION
@@ -634,7 +635,7 @@
 </para>
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
-<para>int ioctl(int fd, int request = FE_READ_SNR, int16_t
+<para>int ioctl(int fd, int request = <link linkend="FE_READ_SNR">FE_READ_SNR</link>, int16_t
  &#x22C6;snr);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
@@ -652,7 +653,7 @@
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_READ_SNR for this command.</para>
+<para>Equals <link linkend="FE_READ_SNR">FE_READ_SNR</link> for this command.</para>
 </entry>
  </row><row><entry
  align="char">
@@ -697,7 +698,7 @@
  </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_read_signal_strength">
+<section id="FE_READ_SIGNAL_STRENGTH">
 <title>FE_READ_SIGNAL_STRENGTH</title>
 <para>DESCRIPTION
 </para>
@@ -712,7 +713,7 @@
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
 <para>int ioctl( int fd, int request =
- FE_READ_SIGNAL_STRENGTH, int16_t &#x22C6;strength);</para>
+ <link linkend="FE_READ_SIGNAL_STRENGTH">FE_READ_SIGNAL_STRENGTH</link>, int16_t &#x22C6;strength);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
 
@@ -730,7 +731,7 @@
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_READ_SIGNAL_STRENGTH for this
+<para>Equals <link linkend="FE_READ_SIGNAL_STRENGTH">FE_READ_SIGNAL_STRENGTH</link> for this
  command.</para>
 </entry>
  </row><row><entry
@@ -775,7 +776,7 @@
  </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_read_ub">
+<section id="FE_READ_UNCORRECTED_BLOCKS">
 <title>FE_READ_UNCORRECTED_BLOCKS</title>
 <para>DESCRIPTION
 </para>
@@ -797,7 +798,7 @@
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
 <para>int ioctl( int fd, int request =
- FE_READ_UNCORRECTED_BLOCKS, uint32_t &#x22C6;ublocks);</para>
+ <link linkend="FE_READ_UNCORRECTED_BLOCKS">FE_READ_UNCORRECTED_BLOCKS</link>, uint32_t &#x22C6;ublocks);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
 <para>PARAMETERS
@@ -814,7 +815,7 @@
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_READ_UNCORRECTED_BLOCKS for this
+<para>Equals <link linkend="FE_READ_UNCORRECTED_BLOCKS">FE_READ_UNCORRECTED_BLOCKS</link> for this
  command.</para>
 </entry>
  </row><row><entry
@@ -852,7 +853,7 @@
  </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_set_fe">
+<section id="FE_SET_FRONTEND">
 <title>FE_SET_FRONTEND</title>
 <para>DESCRIPTION
 </para>
@@ -861,8 +862,8 @@
 <para>This ioctl call starts a tuning operation using specified parameters. The result
  of this call will be successful if the parameters were valid and the tuning could
  be initiated. The result of the tuning operation in itself, however, will arrive
- asynchronously as an event (see documentation for FE_GET_EVENT and
- FrontendEvent.) If a new FE_SET_FRONTEND operation is initiated before
+ asynchronously as an event (see documentation for <link linkend="FE_GET_EVENT">FE_GET_EVENT</link> and
+ FrontendEvent.) If a new <link linkend="FE_SET_FRONTEND">FE_SET_FRONTEND</link> operation is initiated before
  the previous one was completed, the previous operation will be aborted in favor
  of the new one. This command requires read/write access to the device.</para>
 </entry>
@@ -872,7 +873,7 @@
 </para>
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
-<para>int ioctl(int fd, int request = FE_SET_FRONTEND,
+<para>int ioctl(int fd, int request = <link linkend="FE_SET_FRONTEND">FE_SET_FRONTEND</link>,
  struct dvb_frontend_parameters &#x22C6;p);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
@@ -890,7 +891,7 @@
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_SET_FRONTEND for this command.</para>
+<para>Equals <link linkend="FE_SET_FRONTEND">FE_SET_FRONTEND</link> for this command.</para>
 </entry>
  </row><row><entry
  align="char">
@@ -928,7 +929,7 @@
 </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_get_fe">
+<section id="FE_GET_FRONTEND">
 <title>FE_GET_FRONTEND</title>
 <para>DESCRIPTION
 </para>
@@ -943,7 +944,7 @@
 </para>
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
-<para>int ioctl(int fd, int request = FE_GET_FRONTEND,
+<para>int ioctl(int fd, int request = <link linkend="FE_GET_FRONTEND">FE_GET_FRONTEND</link>,
  struct dvb_frontend_parameters &#x22C6;p);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
@@ -962,7 +963,7 @@
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_SET_FRONTEND for this command.</para>
+<para>Equals <link linkend="FE_SET_FRONTEND">FE_SET_FRONTEND</link> for this command.</para>
 </entry>
  </row><row><entry
  align="char">
@@ -1003,7 +1004,7 @@
 
 </section>
 
-<section id="frontend_get_event">
+<section id="FE_GET_EVENT">
 <title>FE_GET_EVENT</title>
 <para>DESCRIPTION
 </para>
@@ -1024,7 +1025,8 @@
  rather small (room for 8 events), the queue must be serviced regularly to avoid
  overflow. If an overflow happens, the oldest event is discarded from the queue,
  and an error (EOVERFLOW) occurs the next time the queue is read. After
- reporting the error condition in this fashion, subsequent FE_GET_EVENT
+ reporting the error condition in this fashion, subsequent
+ <link linkend="FE_GET_EVENT">FE_GET_EVENT</link>
  calls will return events from the queue as usual.</para>
 </entry>
  </row><row><entry
@@ -1057,7 +1059,7 @@
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_GET_EVENT for this command.</para>
+<para>Equals <link linkend="FE_GET_EVENT">FE_GET_EVENT</link> for this command.</para>
 </entry>
  </row><row><entry
  align="char">
@@ -1115,7 +1117,7 @@
 </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_get_info">
+<section id="FE_GET_INFO">
 <title>FE_GET_INFO</title>
 <para>DESCRIPTION
 </para>
@@ -1130,7 +1132,7 @@
 
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
-<para> int ioctl(int fd, int request = FE_GET_INFO, struct
+<para> int ioctl(int fd, int request = <link linkend="FE_GET_INFO">FE_GET_INFO</link>, struct
  dvb_frontend_info &#x22C6;info);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
@@ -1149,7 +1151,7 @@
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_GET_INFO for this command.</para>
+<para>Equals <link linkend="FE_GET_INFO">FE_GET_INFO</link> for this command.</para>
 </entry>
  </row><row><entry
  align="char">
@@ -1181,7 +1183,7 @@
 </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_diseqc_reset_overload">
+<section id="FE_DISEQC_RESET_OVERLOAD">
 <title>FE_DISEQC_RESET_OVERLOAD</title>
 <para>DESCRIPTION
 </para>
@@ -1199,7 +1201,7 @@
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
 <para>int ioctl(int fd, int request =
- FE_DISEQC_RESET_OVERLOAD);</para>
+ <link linkend="FE_DISEQC_RESET_OVERLOAD">FE_DISEQC_RESET_OVERLOAD</link>);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
 <para>PARAMETERS
@@ -1216,7 +1218,7 @@
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_DISEQC_RESET_OVERLOAD for this
+<para>Equals <link linkend="FE_DISEQC_RESET_OVERLOAD">FE_DISEQC_RESET_OVERLOAD</link> for this
  command.</para>
 </entry>
  </row></tbody></tgroup></informaltable>
@@ -1247,7 +1249,7 @@
 </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_diseqc_send_master_cmd">
+<section id="FE_DISEQC_SEND_MASTER_CMD">
 <title>FE_DISEQC_SEND_MASTER_CMD</title>
 <para>DESCRIPTION
 </para>
@@ -1261,7 +1263,7 @@
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
 <para>int ioctl(int fd, int request =
- FE_DISEQC_SEND_MASTER_CMD, struct
+ <link linkend="FE_DISEQC_SEND_MASTER_CMD">FE_DISEQC_SEND_MASTER_CMD</link>, struct
  dvb_diseqc_master_cmd &#x22C6;cmd);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
@@ -1280,7 +1282,7 @@
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_DISEQC_SEND_MASTER_CMD for this
+<para>Equals <link linkend="FE_DISEQC_SEND_MASTER_CMD">FE_DISEQC_SEND_MASTER_CMD</link> for this
  command.</para>
 </entry>
  </row><row><entry
@@ -1335,7 +1337,7 @@
 </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_diseqc_recv_slave_reply">
+<section id="FE_DISEQC_RECV_SLAVE_REPLY">
 <title>FE_DISEQC_RECV_SLAVE_REPLY</title>
 <para>DESCRIPTION
 </para>
@@ -1350,7 +1352,7 @@
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
 <para>int ioctl(int fd, int request =
- FE_DISEQC_RECV_SLAVE_REPLY, struct
+ <link linkend="FE_DISEQC_RECV_SLAVE_REPLY">FE_DISEQC_RECV_SLAVE_REPLY</link>, struct
  dvb_diseqc_slave_reply &#x22C6;reply);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
@@ -1369,7 +1371,7 @@
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_DISEQC_RECV_SLAVE_REPLY for this
+<para>Equals <link linkend="FE_DISEQC_RECV_SLAVE_REPLY">FE_DISEQC_RECV_SLAVE_REPLY</link> for this
  command.</para>
 </entry>
  </row><row><entry
@@ -1423,7 +1425,7 @@
  </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_diseqc_send_burst">
+<section id="FE_DISEQC_SEND_BURST">
 <title>FE_DISEQC_SEND_BURST</title>
 <para>DESCRIPTION
 </para>
@@ -1438,7 +1440,7 @@
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
 <para>int ioctl(int fd, int request =
- FE_DISEQC_SEND_BURST, fe_sec_mini_cmd_t burst);</para>
+ <link linkend="FE_DISEQC_SEND_BURST">FE_DISEQC_SEND_BURST</link>, fe_sec_mini_cmd_t burst);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
 
@@ -1456,7 +1458,7 @@
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_DISEQC_SEND_BURST for this command.</para>
+<para>Equals <link linkend="FE_DISEQC_SEND_BURST">FE_DISEQC_SEND_BURST</link> for this command.</para>
 </entry>
  </row><row><entry
  align="char">
@@ -1509,7 +1511,7 @@
 </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_set_tone">
+<section id="FE_SET_TONE">
 <title>FE_SET_TONE</title>
 <para>DESCRIPTION
 </para>
@@ -1523,7 +1525,7 @@
 </para>
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
-<para>int ioctl(int fd, int request = FE_SET_TONE,
+<para>int ioctl(int fd, int request = <link linkend="FE_SET_TONE">FE_SET_TONE</link>,
  fe_sec_tone_mode_t tone);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
@@ -1541,7 +1543,7 @@
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_SET_TONE for this command.</para>
+<para>Equals <link linkend="FE_SET_TONE">FE_SET_TONE</link> for this command.</para>
 </entry>
  </row><row><entry
  align="char">
@@ -1592,7 +1594,7 @@
 </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="fe_set_voltage">
+<section id="FE_SET_VOLTAGE">
 <title>FE_SET_VOLTAGE</title>
 <para>DESCRIPTION
 </para>
@@ -1606,7 +1608,7 @@
 </para>
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
-<para>int ioctl(int fd, int request = FE_SET_VOLTAGE,
+<para>int ioctl(int fd, int request = <link linkend="FE_SET_VOLTAGE">FE_SET_VOLTAGE</link>,
  fe_sec_voltage_t voltage);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
@@ -1625,7 +1627,7 @@
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_SET_VOLTAGE for this command.</para>
+<para>Equals <link linkend="FE_SET_VOLTAGE">FE_SET_VOLTAGE</link> for this command.</para>
 </entry>
  </row><row><entry
  align="char">
@@ -1677,7 +1679,7 @@
  </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_enable_high_lnb_volt">
+<section id="FE_ENABLE_HIGH_LNB_VOLTAGE">
 <title>FE_ENABLE_HIGH_LNB_VOLTAGE</title>
 <para>DESCRIPTION
 </para>
@@ -1694,7 +1696,7 @@
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
 <para>int ioctl(int fd, int request =
- FE_ENABLE_HIGH_LNB_VOLTAGE, int high);</para>
+ <link linkend="FE_ENABLE_HIGH_LNB_VOLTAGE">FE_ENABLE_HIGH_LNB_VOLTAGE</link>, int high);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
 
@@ -1712,7 +1714,7 @@
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_SET_VOLTAGE for this command.</para>
+<para>Equals <link linkend="FE_SET_VOLTAGE">FE_SET_VOLTAGE</link> for this command.</para>
 </entry>
  </row><row><entry
  align="char">
@@ -1762,5 +1764,82 @@
 </entry>
  </row></tbody></tgroup></informaltable>
 </section>
+
+<section id="FE_SET_FRONTEND_TUNE_MODE">
+<title>FE_SET_FRONTEND_TUNE_MODE</title>
+<para>DESCRIPTION</para>
+<informaltable><tgroup cols="1"><tbody><row>
+<entry align="char">
+<para>Allow setting tuner mode flags to the frontend.</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+
+<para>SYNOPSIS</para>
+<informaltable><tgroup cols="1"><tbody><row>
+<entry align="char">
+<para>int ioctl(int fd, int request =
+<link linkend="FE_SET_FRONTEND_TUNE_MODE">FE_SET_FRONTEND_TUNE_MODE</link>, unsigned int flags);</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+
+<para>PARAMETERS</para>
+<informaltable><tgroup cols="2"><tbody><row>
+<entry align="char">
+	<para>unsigned int flags</para>
+</entry>
+<entry align="char">
+<para>
+FE_TUNE_MODE_ONESHOT When set, this flag will disable any zigzagging or other "normal" tuning behaviour. Additionally, there will be no automatic monitoring of the lock status, and hence no frontend events will be generated. If a frontend device is closed, this flag will be automatically turned off when the device is reopened read-write.
+</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>ERRORS</para>
+<informaltable><tgroup cols="2"><tbody><row>
+<entry align="char"><para>EINVAL</para></entry>
+<entry align="char"><para>Invalid argument.</para></entry>
+ </row></tbody></tgroup></informaltable>
 </section>
-&sub-isdbt;
+
+<section id="FE_DISHNETWORK_SEND_LEGACY_CMD">
+	<title>FE_DISHNETWORK_SEND_LEGACY_CMD</title>
+<para>DESCRIPTION</para>
+<informaltable><tgroup cols="1"><tbody><row>
+<entry align="char">
+<para>WARNING: This is a very obscure legacy command, used only at stv0299 driver. Should not be used on newer drivers.</para>
+<para>It provides a non-standard method for selecting Diseqc voltage on the frontend, for Dish Network legacy switches.</para>
+<para>As support for this ioctl were added in 2004, this means that such dishes were already legacy in 2004.</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+
+<para>SYNOPSIS</para>
+<informaltable><tgroup cols="1"><tbody><row>
+<entry align="char">
+<para>int ioctl(int fd, int request =
+	<link linkend="FE_DISHNETWORK_SEND_LEGACY_CMD">FE_DISHNETWORK_SEND_LEGACY_CMD</link>, unsigned long cmd);</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+
+<para>PARAMETERS</para>
+<informaltable><tgroup cols="2"><tbody><row>
+<entry align="char">
+	<para>unsigned long cmd</para>
+</entry>
+<entry align="char">
+<para>
+sends the specified raw cmd to the dish via DISEqC.
+</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>ERRORS</para>
+<informaltable><tgroup cols="1"><tbody><row>
+<entry align="char">
+	<para>There are no errors in use for this call</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+</section>
+
+</section>
+
+&sub-dvbproperty;
diff --git a/Documentation/DocBook/dvb/isdbt.xml b/Documentation/DocBook/dvb/isdbt.xml
deleted file mode 100644
index 9285522..0000000
--- a/Documentation/DocBook/dvb/isdbt.xml
+++ /dev/null
@@ -1,314 +0,0 @@
-<section id="isdbt">
-	<title>ISDB-T frontend</title>
-	<para>This section describes shortly what are the possible parameters in the Linux
-		DVB-API called "S2API" and now DVB API 5 in order to tune an ISDB-T/ISDB-Tsb
-		demodulator:</para>
-
-	<para>This ISDB-T/ISDB-Tsb API extension should reflect all information
-		needed to tune any ISDB-T/ISDB-Tsb hardware. Of course it is possible
-		that some very sophisticated devices won't need certain parameters to
-		tune.</para>
-
-	<para>The information given here should help application writers to know how
-		to handle ISDB-T and ISDB-Tsb hardware using the Linux DVB-API.</para>
-
-	<para>The details given here about ISDB-T and ISDB-Tsb are just enough to
-		basically show the dependencies between the needed parameter values,
-		but surely some information is left out. For more detailed information
-		see the following documents:</para>
-
-	<para>ARIB STD-B31 - "Transmission System for Digital Terrestrial
-		Television Broadcasting" and</para>
-	<para>ARIB TR-B14 - "Operational Guidelines for Digital Terrestrial
-		Television Broadcasting".</para>
-
-	<para>In order to read this document one has to have some knowledge the
-		channel structure in ISDB-T and ISDB-Tsb. I.e. it has to be known to
-		the reader that an ISDB-T channel consists of 13 segments, that it can
-		have up to 3 layer sharing those segments, and things like that.</para>
-
-	<para>Parameters used by ISDB-T and ISDB-Tsb.</para>
-
-	<section id="isdbt-parms">
-		<title>Parameters that are common with DVB-T and ATSC</title>
-
-		<section id="isdbt-freq">
-			<title><constant>DTV_FREQUENCY</constant></title>
-
-			<para>Central frequency of the channel.</para>
-
-			<para>For ISDB-T the channels are usally transmitted with an offset of 143kHz. E.g. a
-				valid frequncy could be 474143 kHz. The stepping is bound to the bandwidth of
-				the channel which is 6MHz.</para>
-
-			<para>As in ISDB-Tsb the channel consists of only one or three segments the
-				frequency step is 429kHz, 3*429 respectively. As for ISDB-T the
-				central frequency of the channel is expected.</para>
-		</section>
-
-		<section id="isdbt-bw">
-			<title><constant>DTV_BANDWIDTH_HZ</constant> (optional)</title>
-
-			<para>Possible values:</para>
-
-			<para>For ISDB-T it should be always 6000000Hz (6MHz)</para>
-			<para>For ISDB-Tsb it can vary depending on the number of connected segments</para>
-
-			<para>Note: Hardware specific values might be given here, but standard
-				applications should not bother to set a value to this field as
-				standard demods are ignoring it anyway.</para>
-
-			<para>Bandwidth in ISDB-T is fixed (6MHz) or can be easily derived from
-				other parameters (DTV_ISDBT_SB_SEGMENT_IDX,
-				DTV_ISDBT_SB_SEGMENT_COUNT).</para>
-		</section>
-
-		<section id="isdbt-delivery-sys">
-			<title><constant>DTV_DELIVERY_SYSTEM</constant></title>
-
-			<para>Possible values: <constant>SYS_ISDBT</constant></para>
-		</section>
-
-		<section id="isdbt-tx-mode">
-			<title><constant>DTV_TRANSMISSION_MODE</constant></title>
-
-			<para>ISDB-T supports three carrier/symbol-size: 8K, 4K, 2K. It is called
-				'mode' in the standard: Mode 1 is 2K, mode 2 is 4K, mode 3 is 8K</para>
-
-			<para>Possible values: <constant>TRANSMISSION_MODE_2K</constant>, <constant>TRANSMISSION_MODE_8K</constant>,
-				<constant>TRANSMISSION_MODE_AUTO</constant>, <constant>TRANSMISSION_MODE_4K</constant></para>
-
-			<para>If <constant>DTV_TRANSMISSION_MODE</constant> is set the <constant>TRANSMISSION_MODE_AUTO</constant> the
-				hardware will try to find the correct FFT-size (if capable) and will
-				use TMCC to fill in the missing parameters.</para>
-
-			<para><constant>TRANSMISSION_MODE_4K</constant> is added at the same time as the other new parameters.</para>
-		</section>
-
-		<section id="isdbt-guard-interval">
-			<title><constant>DTV_GUARD_INTERVAL</constant></title>
-
-			<para>Possible values: <constant>GUARD_INTERVAL_1_32</constant>, <constant>GUARD_INTERVAL_1_16</constant>, <constant>GUARD_INTERVAL_1_8</constant>,
-				<constant>GUARD_INTERVAL_1_4</constant>, <constant>GUARD_INTERVAL_AUTO</constant></para>
-
-			<para>If <constant>DTV_GUARD_INTERVAL</constant> is set the <constant>GUARD_INTERVAL_AUTO</constant> the hardware will
-				try to find the correct guard interval (if capable) and will use TMCC to fill
-				in the missing parameters.</para>
-		</section>
-	</section>
-	<section id="isdbt-new-parms">
-		<title>ISDB-T only parameters</title>
-
-		<section id="isdbt-part-rec">
-			<title><constant>DTV_ISDBT_PARTIAL_RECEPTION</constant></title>
-
-			<para><constant>If DTV_ISDBT_SOUND_BROADCASTING</constant> is '0' this bit-field represents whether
-				the channel is in partial reception mode or not.</para>
-
-			<para>If '1' <constant>DTV_ISDBT_LAYERA_*</constant> values are assigned to the center segment and
-				<constant>DTV_ISDBT_LAYERA_SEGMENT_COUNT</constant> has to be '1'.</para>
-
-			<para>If in addition <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'
-				<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> represents whether this ISDB-Tsb channel
-				is consisting of one segment and layer or three segments and two layers.</para>
-
-			<para>Possible values: 0, 1, -1 (AUTO)</para>
-		</section>
-
-		<section id="isdbt-sound-bcast">
-			<title><constant>DTV_ISDBT_SOUND_BROADCASTING</constant></title>
-
-			<para>This field represents whether the other DTV_ISDBT_*-parameters are
-				referring to an ISDB-T and an ISDB-Tsb channel. (See also
-				<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>).</para>
-
-			<para>Possible values: 0, 1, -1 (AUTO)</para>
-		</section>
-
-		<section id="isdbt-sb-ch-id">
-			<title><constant>DTV_ISDBT_SB_SUBCHANNEL_ID</constant></title>
-
-			<para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
-
-			<para>(Note of the author: This might not be the correct description of the
-				<constant>SUBCHANNEL-ID</constant> in all details, but it is my understanding of the technical
-				background needed to program a device)</para>
-
-			<para>An ISDB-Tsb channel (1 or 3 segments) can be broadcasted alone or in a
-				set of connected ISDB-Tsb channels. In this set of channels every
-				channel can be received independently. The number of connected
-				ISDB-Tsb segment can vary, e.g. depending on the frequency spectrum
-				bandwidth available.</para>
-
-			<para>Example: Assume 8 ISDB-Tsb connected segments are broadcasted. The
-				broadcaster has several possibilities to put those channels in the
-				air: Assuming a normal 13-segment ISDB-T spectrum he can align the 8
-				segments from position 1-8 to 5-13 or anything in between.</para>
-
-			<para>The underlying layer of segments are subchannels: each segment is
-				consisting of several subchannels with a predefined IDs. A sub-channel
-				is used to help the demodulator to synchronize on the channel.</para>
-
-			<para>An ISDB-T channel is always centered over all sub-channels. As for
-				the example above, in ISDB-Tsb it is no longer as simple as that.</para>
-
-			<para><constant>The DTV_ISDBT_SB_SUBCHANNEL_ID</constant> parameter is used to give the
-				sub-channel ID of the segment to be demodulated.</para>
-
-			<para>Possible values: 0 .. 41, -1 (AUTO)</para>
-		</section>
-
-		<section id="isdbt-sb-seg-idx">
-
-			<title><constant>DTV_ISDBT_SB_SEGMENT_IDX</constant></title>
-
-			<para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
-
-			<para><constant>DTV_ISDBT_SB_SEGMENT_IDX</constant> gives the index of the segment to be
-				demodulated for an ISDB-Tsb channel where several of them are
-				transmitted in the connected manner.</para>
-
-			<para>Possible values: 0 .. <constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant> - 1</para>
-
-			<para>Note: This value cannot be determined by an automatic channel search.</para>
-		</section>
-
-		<section id="isdbt-sb-seg-cnt">
-			<title><constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant></title>
-
-			<para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
-
-			<para><constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant> gives the total count of connected ISDB-Tsb
-				channels.</para>
-
-			<para>Possible values: 1 .. 13</para>
-
-			<para>Note: This value cannot be determined by an automatic channel search.</para>
-		</section>
-
-		<section id="isdb-hierq-layers">
-			<title>Hierarchical layers</title>
-
-			<para>ISDB-T channels can be coded hierarchically. As opposed to DVB-T in
-				ISDB-T hierarchical layers can be decoded simultaneously. For that
-				reason a ISDB-T demodulator has 3 viterbi and 3 reed-solomon-decoders.</para>
-
-			<para>ISDB-T has 3 hierarchical layers which each can use a part of the
-				available segments. The total number of segments over all layers has
-				to 13 in ISDB-T.</para>
-
-			<section id="isdbt-layer-ena">
-				<title><constant>DTV_ISDBT_LAYER_ENABLED</constant></title>
-
-				<para>Hierarchical reception in ISDB-T is achieved by enabling or disabling
-					layers in the decoding process. Setting all bits of
-					<constant>DTV_ISDBT_LAYER_ENABLED</constant> to '1' forces all layers (if applicable) to be
-					demodulated. This is the default.</para>
-
-				<para>If the channel is in the partial reception mode
-					(<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> = 1) the central segment can be decoded
-					independently of the other 12 segments. In that mode layer A has to
-					have a <constant>SEGMENT_COUNT</constant> of 1.</para>
-
-				<para>In ISDB-Tsb only layer A is used, it can be 1 or 3 in ISDB-Tsb
-					according to <constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>. <constant>SEGMENT_COUNT</constant> must be filled
-					accordingly.</para>
-
-				<para>Possible values: 0x1, 0x2, 0x4 (|-able)</para>
-
-				<para><constant>DTV_ISDBT_LAYER_ENABLED[0:0]</constant> - layer A</para>
-				<para><constant>DTV_ISDBT_LAYER_ENABLED[1:1]</constant> - layer B</para>
-				<para><constant>DTV_ISDBT_LAYER_ENABLED[2:2]</constant> - layer C</para>
-				<para><constant>DTV_ISDBT_LAYER_ENABLED[31:3]</constant> unused</para>
-			</section>
-
-			<section id="isdbt-layer-fec">
-				<title><constant>DTV_ISDBT_LAYER*_FEC</constant></title>
-
-				<para>Possible values: <constant>FEC_AUTO</constant>, <constant>FEC_1_2</constant>, <constant>FEC_2_3</constant>, <constant>FEC_3_4</constant>, <constant>FEC_5_6</constant>, <constant>FEC_7_8</constant></para>
-			</section>
-
-			<section id="isdbt-layer-mod">
-				<title><constant>DTV_ISDBT_LAYER*_MODULATION</constant></title>
-
-				<para>Possible values: <constant>QAM_AUTO</constant>, QP<constant>SK, QAM_16</constant>, <constant>QAM_64</constant>, <constant>DQPSK</constant></para>
-
-				<para>Note: If layer C is <constant>DQPSK</constant> layer B has to be <constant>DQPSK</constant>. If layer B is <constant>DQPSK</constant>
-					and <constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>=0 layer has to be <constant>DQPSK</constant>.</para>
-			</section>
-
-			<section id="isdbt-layer-seg-cnt">
-				<title><constant>DTV_ISDBT_LAYER*_SEGMENT_COUNT</constant></title>
-
-				<para>Possible values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1 (AUTO)</para>
-
-				<para>Note: Truth table for <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> and
-					<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> and <constant>LAYER</constant>*_SEGMENT_COUNT</para>
-
-				<informaltable id="isdbt-layer_seg-cnt-table">
-					<tgroup cols="6">
-
-						<tbody>
-							<row>
-								<entry>PR</entry>
-								<entry>SB</entry>
-								<entry>Layer A width</entry>
-								<entry>Layer B width</entry>
-								<entry>Layer C width</entry>
-								<entry>total width</entry>
-							</row>
-
-							<row>
-								<entry>0</entry>
-								<entry>0</entry>
-								<entry>1 .. 13</entry>
-								<entry>1 .. 13</entry>
-								<entry>1 .. 13</entry>
-								<entry>13</entry>
-							</row>
-
-							<row>
-								<entry>1</entry>
-								<entry>0</entry>
-								<entry>1</entry>
-								<entry>1 .. 13</entry>
-								<entry>1 .. 13</entry>
-								<entry>13</entry>
-							</row>
-
-							<row>
-								<entry>0</entry>
-								<entry>1</entry>
-								<entry>1</entry>
-								<entry>0</entry>
-								<entry>0</entry>
-								<entry>1</entry>
-							</row>
-
-							<row>
-								<entry>1</entry>
-								<entry>1</entry>
-								<entry>1</entry>
-								<entry>2</entry>
-								<entry>0</entry>
-								<entry>13</entry>
-							</row>
-						</tbody>
-
-					</tgroup>
-				</informaltable>
-
-			</section>
-
-			<section id="isdbt_layer_t_interl">
-				<title><constant>DTV_ISDBT_LAYER*_TIME_INTERLEAVING</constant></title>
-
-				<para>Possible values: 0, 1, 2, 3, -1 (AUTO)</para>
-
-				<para>Note: The real inter-leaver depth-names depend on the mode (fft-size); the values
-					here are referring to what can be found in the TMCC-structure -
-					independent of the mode.</para>
-			</section>
-		</section>
-	</section>
-</section>
diff --git a/Documentation/DocBook/genericirq.tmpl b/Documentation/DocBook/genericirq.tmpl
index c671a01..1448b33 100644
--- a/Documentation/DocBook/genericirq.tmpl
+++ b/Documentation/DocBook/genericirq.tmpl
@@ -417,8 +417,8 @@
       </para>
       <para>
 	To make use of the split implementation, replace the call to
-	__do_IRQ by a call to desc->chip->handle_irq() and associate
-        the appropriate handler function to desc->chip->handle_irq().
+	__do_IRQ by a call to desc->handle_irq() and associate
+        the appropriate handler function to desc->handle_irq().
 	In most cases the generic handler implementations should
 	be sufficient.
      </para>
diff --git a/Documentation/DocBook/kernel-hacking.tmpl b/Documentation/DocBook/kernel-hacking.tmpl
index 992e67e..7b3f493 100644
--- a/Documentation/DocBook/kernel-hacking.tmpl
+++ b/Documentation/DocBook/kernel-hacking.tmpl
@@ -352,7 +352,7 @@
   </para>
 
   <programlisting>
-if (signal_pending()) 
+if (signal_pending(current))
         return -ERESTARTSYS;
   </programlisting>
 
diff --git a/Documentation/DocBook/media-entities.tmpl b/Documentation/DocBook/media-entities.tmpl
index 0eb43c1..bb5ab74 100644
--- a/Documentation/DocBook/media-entities.tmpl
+++ b/Documentation/DocBook/media-entities.tmpl
@@ -280,7 +280,7 @@
 <!ENTITY sub-v4l2 SYSTEM "v4l/v4l2.xml">
 <!ENTITY sub-intro SYSTEM "dvb/intro.xml">
 <!ENTITY sub-frontend SYSTEM "dvb/frontend.xml">
-<!ENTITY sub-isdbt SYSTEM "dvb/isdbt.xml">
+<!ENTITY sub-dvbproperty SYSTEM "dvb/dvbproperty.xml">
 <!ENTITY sub-demux SYSTEM "dvb/demux.xml">
 <!ENTITY sub-video SYSTEM "dvb/video.xml">
 <!ENTITY sub-audio SYSTEM "dvb/audio.xml">
@@ -288,6 +288,7 @@
 <!ENTITY sub-net SYSTEM "dvb/net.xml">
 <!ENTITY sub-kdapi SYSTEM "dvb/kdapi.xml">
 <!ENTITY sub-examples SYSTEM "dvb/examples.xml">
+<!ENTITY sub-frontend-h SYSTEM "dvb/frontend.h.xml">
 <!ENTITY sub-dvbapi SYSTEM "dvb/dvbapi.xml">
 <!ENTITY sub-media SYSTEM "media.xml">
 <!ENTITY sub-media-entities SYSTEM "media-entities.tmpl">
diff --git a/Documentation/DocBook/mtdnand.tmpl b/Documentation/DocBook/mtdnand.tmpl
index df0d089..f508a8a 100644
--- a/Documentation/DocBook/mtdnand.tmpl
+++ b/Documentation/DocBook/mtdnand.tmpl
@@ -362,7 +362,7 @@
 	<sect1 id="Multiple_chip_control">
 		<title>Multiple chip control</title>
 		<para>
-			The nand driver can control chip arrays. Therefor the
+			The nand driver can control chip arrays. Therefore the
 			board driver must provide an own select_chip function. This
 			function must (de)select the requested chip.
 			The function pointer in the nand_chip structure must
diff --git a/Documentation/DocBook/v4l/controls.xml b/Documentation/DocBook/v4l/controls.xml
index f492acc..f464506 100644
--- a/Documentation/DocBook/v4l/controls.xml
+++ b/Documentation/DocBook/v4l/controls.xml
@@ -281,10 +281,28 @@
 <constant>V4L2_COLORFX_SEPIA</constant> (2).</entry>
 	  </row>
 	  <row>
+	    <entry><constant>V4L2_CID_ROTATE</constant></entry>
+	    <entry>integer</entry>
+	    <entry>Rotates the image by specified angle. Common angles are 90,
+	    270 and 180. Rotating the image to 90 and 270 will reverse the height
+	    and width of the display window. It is necessary to set the new height and
+	    width of the picture using the &VIDIOC-S-FMT; ioctl according to
+	    the rotation angle selected.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_BG_COLOR</constant></entry>
+	    <entry>integer</entry>
+	    <entry>Sets the background color on the current output device.
+	    Background color needs to be specified in the RGB24 format. The
+	    supplied 32 bit value is interpreted as bits 0-7 Red color information,
+	    bits 8-15 Green color information, bits 16-23 Blue color
+	    information and bits 24-31 must be zero.</entry>
+	  </row>
+	  <row>
 	    <entry><constant>V4L2_CID_LASTP1</constant></entry>
 	    <entry></entry>
 	    <entry>End of the predefined control IDs (currently
-<constant>V4L2_CID_COLORFX</constant> + 1).</entry>
+<constant>V4L2_CID_BG_COLOR</constant> + 1).</entry>
 	  </row>
 	  <row>
 	    <entry><constant>V4L2_CID_PRIVATE_BASE</constant></entry>
diff --git a/Documentation/DocBook/v4l/pixfmt.xml b/Documentation/DocBook/v4l/pixfmt.xml
index 7d396a3..885968d 100644
--- a/Documentation/DocBook/v4l/pixfmt.xml
+++ b/Documentation/DocBook/v4l/pixfmt.xml
@@ -770,6 +770,11 @@
 	    <entry>'S920'</entry>
 	    <entry>YUV 4:2:0 format of the gspca sn9c20x driver.</entry>
 	  </row>
+	  <row id="V4L2-PIX-FMT-STV0680">
+	    <entry><constant>V4L2_PIX_FMT_STV0680</constant></entry>
+	    <entry>'S680'</entry>
+	    <entry>Bayer format of the gspca stv0680 driver.</entry>
+	  </row>
 	  <row id="V4L2-PIX-FMT-WNVA">
 	    <entry><constant>V4L2_PIX_FMT_WNVA</constant></entry>
 	    <entry>'WNVA'</entry>
diff --git a/Documentation/DocBook/v4l/videodev2.h.xml b/Documentation/DocBook/v4l/videodev2.h.xml
index 9700206..3e282ed 100644
--- a/Documentation/DocBook/v4l/videodev2.h.xml
+++ b/Documentation/DocBook/v4l/videodev2.h.xml
@@ -363,6 +363,7 @@
 #define <link linkend="V4L2-PIX-FMT-OV511">V4L2_PIX_FMT_OV511</link>    v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */
 #define <link linkend="V4L2-PIX-FMT-OV518">V4L2_PIX_FMT_OV518</link>    v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */
 #define <link linkend="V4L2-PIX-FMT-TM6000">V4L2_PIX_FMT_TM6000</link>   v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */
+#define <link linkend="V4L2-PIX-FMT-STV0680">V4L2_PIX_FMT_STV0680</link>  v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */
 
 /*
  *      F O R M A T   E N U M E R A T I O N
@@ -492,7 +493,7 @@
                                  * you do, leave them untouched.
                                  * Inluding less markers will make the
                                  * resulting code smaller, but there will
-                                 * be fewer aplications which can read it.
+                                 * be fewer applications which can read it.
                                  * The presence of the APP and COM marker
                                  * is influenced by APP_len and COM_len
                                  * ONLY, not by this property! */
@@ -565,6 +566,7 @@
 #define V4L2_FBUF_CAP_LOCAL_ALPHA       0x0010
 #define V4L2_FBUF_CAP_GLOBAL_ALPHA      0x0020
 #define V4L2_FBUF_CAP_LOCAL_INV_ALPHA   0x0040
+#define V4L2_FBUF_CAP_SRC_CHROMAKEY     0x0080
 /*  Flags for the 'flags' field. */
 #define V4L2_FBUF_FLAG_PRIMARY          0x0001
 #define V4L2_FBUF_FLAG_OVERLAY          0x0002
@@ -572,6 +574,7 @@
 #define V4L2_FBUF_FLAG_LOCAL_ALPHA      0x0008
 #define V4L2_FBUF_FLAG_GLOBAL_ALPHA     0x0010
 #define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA  0x0020
+#define V4L2_FBUF_FLAG_SRC_CHROMAKEY    0x0040
 
 struct <link linkend="v4l2-clip">v4l2_clip</link> {
         struct <link linkend="v4l2-rect">v4l2_rect</link>        c;
@@ -914,8 +917,10 @@
 #define V4L2_CID_AUTOBRIGHTNESS                 (V4L2_CID_BASE+32)
 #define V4L2_CID_BAND_STOP_FILTER               (V4L2_CID_BASE+33)
 
+#define V4L2_CID_ROTATE                         (V4L2_CID_BASE+34)
+#define V4L2_CID_BG_COLOR                       (V4L2_CID_BASE+35)
 /* last CID + 1 */
-#define V4L2_CID_LASTP1                         (V4L2_CID_BASE+34)
+#define V4L2_CID_LASTP1                         (V4L2_CID_BASE+36)
 
 /*  MPEG-class control IDs defined by V4L2 */
 #define V4L2_CID_MPEG_BASE                      (V4L2_CTRL_CLASS_MPEG | 0x900)
diff --git a/Documentation/DocBook/v4l/vidioc-g-fbuf.xml b/Documentation/DocBook/v4l/vidioc-g-fbuf.xml
index f701706..e7dda48 100644
--- a/Documentation/DocBook/v4l/vidioc-g-fbuf.xml
+++ b/Documentation/DocBook/v4l/vidioc-g-fbuf.xml
@@ -336,6 +336,13 @@
 inverted alpha channel of the framebuffer or VGA signal. Alpha
 blending makes no sense for destructive overlays.</entry>
 	  </row>
+	  <row>
+	    <entry><constant>V4L2_FBUF_CAP_SRC_CHROMAKEY</constant></entry>
+	    <entry>0x0080</entry>
+	    <entry>The device supports Source Chroma-keying. Framebuffer pixels
+with the chroma-key colors are replaced by video pixels, which is exactly opposite of
+<constant>V4L2_FBUF_CAP_CHROMAKEY</constant></entry>
+	  </row>
 	</tbody>
       </tgroup>
     </table>
@@ -411,6 +418,16 @@
 output = framebuffer pixel * (1 - alpha) + video pixel * alpha. The
 actual alpha depth depends on the framebuffer pixel format.</entry>
 	  </row>
+	  <row>
+	    <entry><constant>V4L2_FBUF_FLAG_SRC_CHROMAKEY</constant></entry>
+	    <entry>0x0040</entry>
+	    <entry>Use source chroma-keying. The source chroma-key color is
+determined by the <structfield>chromakey</structfield> field of
+&v4l2-window; and negotiated with the &VIDIOC-S-FMT; ioctl, see <xref
+linkend="overlay" /> and <xref linkend="osd" />.
+Both chroma-keying are mutual exclusive to each other, so same
+<structfield>chromakey</structfield> field of &v4l2-window; is being used.</entry>
+	  </row>
 	</tbody>
       </tgroup>
     </table>
diff --git a/Documentation/DocBook/writing-an-alsa-driver.tmpl b/Documentation/DocBook/writing-an-alsa-driver.tmpl
index 7a2e0e9..0d0f7b4 100644
--- a/Documentation/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/DocBook/writing-an-alsa-driver.tmpl
@@ -5318,7 +5318,7 @@
       pages of the given size and map them onto the virtually contiguous
       memory.  The virtual pointer is addressed in runtime-&gt;dma_area.
       The physical address (runtime-&gt;dma_addr) is set to zero,
-      because the buffer is physically non-contigous.
+      because the buffer is physically non-contiguous.
       The physical address table is set up in sgbuf-&gt;table.
       You can get the physical address at a certain offset via
       <function>snd_pcm_sgbuf_get_addr()</function>. 
diff --git a/Documentation/arm/OMAP/DSS b/Documentation/arm/OMAP/DSS
new file mode 100644
index 0000000..0af0e9e
--- /dev/null
+++ b/Documentation/arm/OMAP/DSS
@@ -0,0 +1,317 @@
+OMAP2/3 Display Subsystem
+-------------------------
+
+This is an almost total rewrite of the OMAP FB driver in drivers/video/omap
+(let's call it DSS1). The main differences between DSS1 and DSS2 are DSI,
+TV-out and multiple display support, but there are lots of small improvements
+also.
+
+The DSS2 driver (omapdss module) is in arch/arm/plat-omap/dss/, and the FB,
+panel and controller drivers are in drivers/video/omap2/. DSS1 and DSS2 live
+currently side by side, you can choose which one to use.
+
+Features
+--------
+
+Working and tested features include:
+
+- MIPI DPI (parallel) output
+- MIPI DSI output in command mode
+- MIPI DBI (RFBI) output
+- SDI output
+- TV output
+- All pieces can be compiled as a module or inside kernel
+- Use DISPC to update any of the outputs
+- Use CPU to update RFBI or DSI output
+- OMAP DISPC planes
+- RGB16, RGB24 packed, RGB24 unpacked
+- YUV2, UYVY
+- Scaling
+- Adjusting DSS FCK to find a good pixel clock
+- Use DSI DPLL to create DSS FCK
+
+Tested boards include:
+- OMAP3 SDP board
+- Beagle board
+- N810
+
+omapdss driver
+--------------
+
+The DSS driver does not itself have any support for Linux framebuffer, V4L or
+such like the current ones, but it has an internal kernel API that upper level
+drivers can use.
+
+The DSS driver models OMAP's overlays, overlay managers and displays in a
+flexible way to enable non-common multi-display configuration. In addition to
+modelling the hardware overlays, omapdss supports virtual overlays and overlay
+managers. These can be used when updating a display with CPU or system DMA.
+
+Panel and controller drivers
+----------------------------
+
+The drivers implement panel or controller specific functionality and are not
+usually visible to users except through omapfb driver.  They register
+themselves to the DSS driver.
+
+omapfb driver
+-------------
+
+The omapfb driver implements arbitrary number of standard linux framebuffers.
+These framebuffers can be routed flexibly to any overlays, thus allowing very
+dynamic display architecture.
+
+The driver exports some omapfb specific ioctls, which are compatible with the
+ioctls in the old driver.
+
+The rest of the non standard features are exported via sysfs. Whether the final
+implementation will use sysfs, or ioctls, is still open.
+
+V4L2 drivers
+------------
+
+V4L2 is being implemented in TI.
+
+From omapdss point of view the V4L2 drivers should be similar to framebuffer
+driver.
+
+Architecture
+--------------------
+
+Some clarification what the different components do:
+
+    - Framebuffer is a memory area inside OMAP's SRAM/SDRAM that contains the
+      pixel data for the image. Framebuffer has width and height and color
+      depth.
+    - Overlay defines where the pixels are read from and where they go on the
+      screen. The overlay may be smaller than framebuffer, thus displaying only
+      part of the framebuffer. The position of the overlay may be changed if
+      the overlay is smaller than the display.
+    - Overlay manager combines the overlays in to one image and feeds them to
+      display.
+    - Display is the actual physical display device.
+
+A framebuffer can be connected to multiple overlays to show the same pixel data
+on all of the overlays. Note that in this case the overlay input sizes must be
+the same, but, in case of video overlays, the output size can be different. Any
+framebuffer can be connected to any overlay.
+
+An overlay can be connected to one overlay manager. Also DISPC overlays can be
+connected only to DISPC overlay managers, and virtual overlays can be only
+connected to virtual overlays.
+
+An overlay manager can be connected to one display. There are certain
+restrictions which kinds of displays an overlay manager can be connected:
+
+    - DISPC TV overlay manager can be only connected to TV display.
+    - Virtual overlay managers can only be connected to DBI or DSI displays.
+    - DISPC LCD overlay manager can be connected to all displays, except TV
+      display.
+
+Sysfs
+-----
+The sysfs interface is mainly used for testing. I don't think sysfs
+interface is the best for this in the final version, but I don't quite know
+what would be the best interfaces for these things.
+
+The sysfs interface is divided to two parts: DSS and FB.
+
+/sys/class/graphics/fb? directory:
+mirror		0=off, 1=on
+rotate		Rotation 0-3 for 0, 90, 180, 270 degrees
+rotate_type	0 = DMA rotation, 1 = VRFB rotation
+overlays	List of overlay numbers to which framebuffer pixels go
+phys_addr	Physical address of the framebuffer
+virt_addr	Virtual address of the framebuffer
+size		Size of the framebuffer
+
+/sys/devices/platform/omapdss/overlay? directory:
+enabled		0=off, 1=on
+input_size	width,height (ie. the framebuffer size)
+manager		Destination overlay manager name
+name
+output_size	width,height
+position	x,y
+screen_width	width
+global_alpha   	global alpha 0-255 0=transparent 255=opaque
+
+/sys/devices/platform/omapdss/manager? directory:
+display				Destination display
+name
+alpha_blending_enabled		0=off, 1=on
+trans_key_enabled		0=off, 1=on
+trans_key_type			gfx-destination, video-source
+trans_key_value			transparency color key (RGB24)
+default_color			default background color (RGB24)
+
+/sys/devices/platform/omapdss/display? directory:
+ctrl_name	Controller name
+mirror		0=off, 1=on
+update_mode	0=off, 1=auto, 2=manual
+enabled		0=off, 1=on
+name
+rotate		Rotation 0-3 for 0, 90, 180, 270 degrees
+timings		Display timings (pixclock,xres/hfp/hbp/hsw,yres/vfp/vbp/vsw)
+		When writing, two special timings are accepted for tv-out:
+		"pal" and "ntsc"
+panel_name
+tear_elim	Tearing elimination 0=off, 1=on
+
+There are also some debugfs files at <debugfs>/omapdss/ which show information
+about clocks and registers.
+
+Examples
+--------
+
+The following definitions have been made for the examples below:
+
+ovl0=/sys/devices/platform/omapdss/overlay0
+ovl1=/sys/devices/platform/omapdss/overlay1
+ovl2=/sys/devices/platform/omapdss/overlay2
+
+mgr0=/sys/devices/platform/omapdss/manager0
+mgr1=/sys/devices/platform/omapdss/manager1
+
+lcd=/sys/devices/platform/omapdss/display0
+dvi=/sys/devices/platform/omapdss/display1
+tv=/sys/devices/platform/omapdss/display2
+
+fb0=/sys/class/graphics/fb0
+fb1=/sys/class/graphics/fb1
+fb2=/sys/class/graphics/fb2
+
+Default setup on OMAP3 SDP
+--------------------------
+
+Here's the default setup on OMAP3 SDP board. All planes go to LCD. DVI
+and TV-out are not in use. The columns from left to right are:
+framebuffers, overlays, overlay managers, displays. Framebuffers are
+handled by omapfb, and the rest by the DSS.
+
+FB0 --- GFX  -\            DVI
+FB1 --- VID1 --+- LCD ---- LCD
+FB2 --- VID2 -/   TV ----- TV
+
+Example: Switch from LCD to DVI
+----------------------
+
+w=`cat $dvi/timings | cut -d "," -f 2 | cut -d "/" -f 1`
+h=`cat $dvi/timings | cut -d "," -f 3 | cut -d "/" -f 1`
+
+echo "0" > $lcd/enabled
+echo "" > $mgr0/display
+fbset -fb /dev/fb0 -xres $w -yres $h -vxres $w -vyres $h
+# at this point you have to switch the dvi/lcd dip-switch from the omap board
+echo "dvi" > $mgr0/display
+echo "1" > $dvi/enabled
+
+After this the configuration looks like:
+
+FB0 --- GFX  -\         -- DVI
+FB1 --- VID1 --+- LCD -/   LCD
+FB2 --- VID2 -/   TV ----- TV
+
+Example: Clone GFX overlay to LCD and TV
+-------------------------------
+
+w=`cat $tv/timings | cut -d "," -f 2 | cut -d "/" -f 1`
+h=`cat $tv/timings | cut -d "," -f 3 | cut -d "/" -f 1`
+
+echo "0" > $ovl0/enabled
+echo "0" > $ovl1/enabled
+
+echo "" > $fb1/overlays
+echo "0,1" > $fb0/overlays
+
+echo "$w,$h" > $ovl1/output_size
+echo "tv" > $ovl1/manager
+
+echo "1" > $ovl0/enabled
+echo "1" > $ovl1/enabled
+
+echo "1" > $tv/enabled
+
+After this the configuration looks like (only relevant parts shown):
+
+FB0 +-- GFX  ---- LCD ---- LCD
+     \- VID1 ---- TV  ---- TV
+
+Misc notes
+----------
+
+OMAP FB allocates the framebuffer memory using the OMAP VRAM allocator.
+
+Using DSI DPLL to generate pixel clock it is possible produce the pixel clock
+of 86.5MHz (max possible), and with that you get 1280x1024@57 output from DVI.
+
+Rotation and mirroring currently only supports RGB565 and RGB8888 modes. VRFB
+does not support mirroring.
+
+VRFB rotation requires much more memory than non-rotated framebuffer, so you
+probably need to increase your vram setting before using VRFB rotation. Also,
+many applications may not work with VRFB if they do not pay attention to all
+framebuffer parameters.
+
+Kernel boot arguments
+---------------------
+
+vram=<size>
+	- Amount of total VRAM to preallocate. For example, "10M". omapfb
+	  allocates memory for framebuffers from VRAM.
+
+omapfb.mode=<display>:<mode>[,...]
+	- Default video mode for specified displays. For example,
+	  "dvi:800x400MR-24@60".  See drivers/video/modedb.c.
+	  There are also two special modes: "pal" and "ntsc" that
+	  can be used to tv out.
+
+omapfb.vram=<fbnum>:<size>[@<physaddr>][,...]
+	- VRAM allocated for a framebuffer. Normally omapfb allocates vram
+	  depending on the display size. With this you can manually allocate
+	  more or define the physical address of each framebuffer. For example,
+	  "1:4M" to allocate 4M for fb1.
+
+omapfb.debug=<y|n>
+	- Enable debug printing. You have to have OMAPFB debug support enabled
+	  in kernel config.
+
+omapfb.test=<y|n>
+	- Draw test pattern to framebuffer whenever framebuffer settings change.
+	  You need to have OMAPFB debug support enabled in kernel config.
+
+omapfb.vrfb=<y|n>
+	- Use VRFB rotation for all framebuffers.
+
+omapfb.rotate=<angle>
+	- Default rotation applied to all framebuffers.
+	  0 - 0 degree rotation
+	  1 - 90 degree rotation
+	  2 - 180 degree rotation
+	  3 - 270 degree rotation
+
+omapfb.mirror=<y|n>
+	- Default mirror for all framebuffers. Only works with DMA rotation.
+
+omapdss.def_disp=<display>
+	- Name of default display, to which all overlays will be connected.
+	  Common examples are "lcd" or "tv".
+
+omapdss.debug=<y|n>
+	- Enable debug printing. You have to have DSS debug support enabled in
+	  kernel config.
+
+TODO
+----
+
+DSS locking
+
+Error checking
+- Lots of checks are missing or implemented just as BUG()
+
+System DMA update for DSI
+- Can be used for RGB16 and RGB24P modes. Probably not for RGB24U (how
+  to skip the empty byte?)
+
+OMAP1 support
+- Not sure if needed
+
diff --git a/Documentation/cpu-freq/cpu-drivers.txt b/Documentation/cpu-freq/cpu-drivers.txt
index 75a58d1..6c30e93 100644
--- a/Documentation/cpu-freq/cpu-drivers.txt
+++ b/Documentation/cpu-freq/cpu-drivers.txt
@@ -92,9 +92,9 @@
 				(in kHz) which is supported by 
 				this CPU
 policy->cpuinfo.transition_latency   the time it takes on this CPU to
-				switch between two frequencies (if
-				appropriate, else specify
-				CPUFREQ_ETERNAL)
+				switch between two frequencies in
+				nanoseconds (if appropriate, else
+				specify CPUFREQ_ETERNAL)
 
 policy->cur			The current operating frequency of
 				this CPU (if appropriate)
diff --git a/Documentation/cpu-freq/user-guide.txt b/Documentation/cpu-freq/user-guide.txt
index 2a5b850..04f6b32 100644
--- a/Documentation/cpu-freq/user-guide.txt
+++ b/Documentation/cpu-freq/user-guide.txt
@@ -203,6 +203,17 @@
 				the frequency the kernel thinks the CPU runs
 				at.
 
+bios_limit :			If the BIOS tells the OS to limit a CPU to
+				lower frequencies, the user can read out the
+				maximum available frequency from this file.
+				This typically can happen through (often not
+				intended) BIOS settings, restrictions
+				triggered through a service processor or other
+				BIOS/HW based implementations.
+				This does not cover thermal ACPI limitations
+				which can be detected through the generic
+				thermal driver.
+
 If you have selected the "userspace" governor which allows you to
 set the CPU operating frequency to a specific value, you can read out
 the current frequency in
diff --git a/Documentation/dvb/README.dvb-usb b/Documentation/dvb/README.dvb-usb
index bf2a9cd..c8238e4 100644
--- a/Documentation/dvb/README.dvb-usb
+++ b/Documentation/dvb/README.dvb-usb
@@ -85,7 +85,7 @@
 	     - moved transfer control (pid filter, fifo control) from usb driver to frontend, it seems
 	       better settled there (added xfer_ops-struct)
 	     - created a common files for frontends (mc/p/mb)
-  2004-09-28 - added support for a new device (Unkown, vendor ID is Hyper-Paltek)
+  2004-09-28 - added support for a new device (Unknown, vendor ID is Hyper-Paltek)
   2004-09-20 - added support for a new device (Compro DVB-U2000), thanks
 	       to Amaury Demol for reporting
 	     - changed usb TS transfer method (several urbs, stopping transfer
diff --git a/Documentation/edac.txt b/Documentation/edac.txt
index 06f8f46..79c5332 100644
--- a/Documentation/edac.txt
+++ b/Documentation/edac.txt
@@ -80,7 +80,7 @@
 
 	broken_parity_status
 
-as is located in /sys/devices/pci<XXX>/0000:XX:YY.Z directorys for
+as is located in /sys/devices/pci<XXX>/0000:XX:YY.Z directories for
 PCI devices.
 
 FUTURE HARDWARE SCANNING
@@ -288,9 +288,8 @@
 
 	'ue_noinfo_count'
 
-	This attribute file displays the number of UEs that
-	have occurred have occurred with  no informations as to which DIMM
-	slot is having errors.
+	This attribute file displays the number of UEs that have occurred
+	with no information as to which DIMM slot is having errors.
 
 
 Total Correctable Errors count attribute file:
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 591e944..2a4d779 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -483,3 +483,10 @@
 Who:	Alok N Kataria <akataria@vmware.com>
 
 ----------------------------
+
+What:	adt7473 hardware monitoring driver
+When:	February 2010
+Why:	Obsoleted by the adt7475 driver.
+Who:	Jean Delvare <khali@linux-fr.org>
+
+---------------------------
diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX
index f15621e..7001782 100644
--- a/Documentation/filesystems/00-INDEX
+++ b/Documentation/filesystems/00-INDEX
@@ -36,6 +36,8 @@
 	- info about directory notification in Linux.
 ecryptfs.txt
 	- docs on eCryptfs: stacked cryptographic filesystem for Linux.
+exofs.txt
+	- info, usage, mount options, design about EXOFS.
 ext2.txt
 	- info, mount options and specifications for the Ext2 filesystem.
 ext3.txt
diff --git a/Documentation/filesystems/exofs.txt b/Documentation/filesystems/exofs.txt
index 0ced74c..abd2a9b 100644
--- a/Documentation/filesystems/exofs.txt
+++ b/Documentation/filesystems/exofs.txt
@@ -60,13 +60,13 @@
 
    mkfs.exofs --pid=65536 --format /dev/osd0
 
-   The --format is optional if not specified no OSD_FORMAT will be
-   preformed and a clean file system will be created in the specified pid,
+   The --format is optional. If not specified, no OSD_FORMAT will be
+   performed and a clean file system will be created in the specified pid,
    in the available space of the target. (Use --format=size_in_meg to limit
    the total LUN space available)
 
-   If pid already exist it will be deleted and a new one will be created in it's
-   place. Be careful.
+   If pid already exists, it will be deleted and a new one will be created in
+   its place. Be careful.
 
    An exofs lives inside a single OSD partition. You can create multiple exofs
    filesystems on the same device using multiple pids.
@@ -81,7 +81,7 @@
 
 7. For reference (See do-exofs example script):
 	do-exofs start - an example of how to perform the above steps.
-	do-exofs stop -  an example of how to unmount the file system.
+	do-exofs stop - an example of how to unmount the file system.
 	do-exofs format - an example of how to format and mkfs a new exofs.
 
 8. Extra compilation flags (uncomment in fs/exofs/Kbuild):
@@ -104,8 +104,8 @@
     exofs specific options: Options are separated by commas (,)
 		pid=<integer> - The partition number to mount/create as
                                 container of the filesystem.
-                                This option is mandatory
-                to=<integer>  - Timeout in ticks for a single command
+                                This option is mandatory.
+                to=<integer>  - Timeout in ticks for a single command.
                                 default is (60 * HZ) [for debugging only]
 
 ===============================================================================
@@ -116,7 +116,7 @@
   with a special ID (defined in common.h).
   Information included in the file system control block is used to fill the
   in-memory superblock structure at mount time. This object is created before
-  the file system is used by mkexofs.c It contains information such as:
+  the file system is used by mkexofs.c. It contains information such as:
 	- The file system's magic number
 	- The next inode number to be allocated
 
@@ -134,8 +134,8 @@
   attributes. This applies to both regular files and other types (directories,
   device files, symlinks, etc.).
 
-* Credentials are generated per object (inode and superblock) when they is
-  created in memory (read off disk or created). The credential works for all
+* Credentials are generated per object (inode and superblock) when they are
+  created in memory (read from disk or created). The credential works for all
   operations and is used as long as the object remains in memory.
 
 * Async OSD operations are used whenever possible, but the target may execute
@@ -145,7 +145,8 @@
   from executing in reverse order:
 	- The following are handled with the OBJ_CREATED and OBJ_2BCREATED
 	  flags. OBJ_CREATED is set when we know the object exists on the OSD -
-	  in create's callback function, and when we successfully do a read_inode.
+	  in create's callback function, and when we successfully do a
+	  read_inode.
 	  OBJ_2BCREATED is set in the beginning of the create function, so we
 	  know that we should wait.
 		- create/delete: delete should wait until the object is created
diff --git a/Documentation/filesystems/ext3.txt b/Documentation/filesystems/ext3.txt
index 05d5cf1..867c5b50 100644
--- a/Documentation/filesystems/ext3.txt
+++ b/Documentation/filesystems/ext3.txt
@@ -32,8 +32,8 @@
 			identified through its new major/minor numbers encoded
 			in devnum.
 
-noload			Don't load the journal on mounting. Note that this forces
-			mount of inconsistent filesystem, which can lead to
+norecovery		Don't load the journal on mounting. Note that this forces
+noload			mount of inconsistent filesystem, which can lead to
 			various problems.
 
 data=journal		All data are committed into the journal prior to being
diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt
index 6d94e06..af6885c 100644
--- a/Documentation/filesystems/ext4.txt
+++ b/Documentation/filesystems/ext4.txt
@@ -153,8 +153,8 @@
 			identified through its new major/minor numbers encoded
 			in devnum.
 
-noload			Don't load the journal on mounting.  Note that
-                     	if the filesystem was not unmounted cleanly,
+norecovery		Don't load the journal on mounting.  Note that
+noload			if the filesystem was not unmounted cleanly,
                      	skipping the journal replay will lead to the
                      	filesystem containing inconsistencies that can
                      	lead to any number of problems.
@@ -353,6 +353,12 @@
 			system crashes before the delayed allocation
 			blocks are forced to disk.
 
+discard		Controls whether ext4 should issue discard/TRIM
+nodiscard(*)		commands to the underlying block device when
+			blocks are freed.  This is useful for SSD devices
+			and sparse/thinly-provisioned LUNs, but it is off
+			by default until sufficient testing has been done.
+
 Data Mode
 =========
 There are 3 different data modes:
diff --git a/Documentation/filesystems/nilfs2.txt b/Documentation/filesystems/nilfs2.txt
index 01539f4..4949fca 100644
--- a/Documentation/filesystems/nilfs2.txt
+++ b/Documentation/filesystems/nilfs2.txt
@@ -49,8 +49,7 @@
 NILFS2 supports the following mount options:
 (*) == default
 
-barrier=on(*)		This enables/disables barriers. barrier=off disables
-			it, barrier=on enables it.
+nobarrier		Disables barriers.
 errors=continue(*)	Keep going on a filesystem error.
 errors=remount-ro	Remount the filesystem read-only on an error.
 errors=panic		Panic and halt the machine if an error occurs.
@@ -71,6 +70,10 @@
 			blocks.  That means, it is guaranteed that no
 			overtaking of events occurs in the recovered file
 			system after a crash.
+norecovery		Disable recovery of the filesystem on mount.
+			This disables every write access on the device for
+			read-only mounts or snapshots.  This option will fail
+			for r/w mounts on an unclean volume.
 
 NILFS2 usage
 ============
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index 4af0018..94b9f20 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -1089,8 +1089,8 @@
 includes (but  is not limited  to) those  created by  calls to the  fork() and
 clone() system calls.
 
-The  "procs_running" line gives the  number of processes  currently running on
-CPUs.
+The "procs_running" line gives the total number of threads that are
+running or ready to run (i.e., the total number of runnable threads).
 
 The   "procs_blocked" line gives  the  number of  processes currently blocked,
 waiting for I/O to complete.
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index 623f094..3de2f32 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -472,7 +472,7 @@
 writing out the whole address_space.
 
 The Writeback tag is used by filemap*wait* and sync_page* functions,
-via wait_on_page_writeback_range, to wait for all writeback to
+via filemap_fdatawait_range, to wait for all writeback to
 complete.  While waiting ->sync_page (if defined) will be called on
 each page that is found to require writeback.
 
diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt
index fa4dc07..e4e7daed2 100644
--- a/Documentation/gpio.txt
+++ b/Documentation/gpio.txt
@@ -380,7 +380,7 @@
 
 Most often a gpio_chip is part of an instance-specific structure with state
 not exposed by the GPIO interfaces, such as addressing, power management,
-and more.  Chips such as codecs will have complex non-GPIO state,
+and more.  Chips such as codecs will have complex non-GPIO state.
 
 Any debugfs dump method should normally ignore signals which haven't been
 requested as GPIOs.  They can use gpiochip_is_requested(), which returns
@@ -531,7 +531,7 @@
 		This file exists only if the pin can be configured as an
 		interrupt generating input pin.
 
-GPIO controllers have paths like /sys/class/gpio/chipchip42/ (for the
+GPIO controllers have paths like /sys/class/gpio/gpiochip42/ (for the
 controller implementing GPIOs starting at #42) and have the following
 read-only attributes:
 
diff --git a/Documentation/hwmon/adt7473 b/Documentation/hwmon/adt7473
index 1cbf671..446612b 100644
--- a/Documentation/hwmon/adt7473
+++ b/Documentation/hwmon/adt7473
@@ -9,6 +9,8 @@
 
 Author: Darrick J. Wong
 
+This driver is depreacted, please use the adt7475 driver instead.
+
 Description
 -----------
 
diff --git a/Documentation/hwmon/adt7475 b/Documentation/hwmon/adt7475
index a2b1abe..0502f2b 100644
--- a/Documentation/hwmon/adt7475
+++ b/Documentation/hwmon/adt7475
@@ -1,87 +1,117 @@
-This describes the interface for the ADT7475 driver:
+Kernel driver adt7475
+=====================
 
-(there are 4 fans, numbered fan1 to fan4):
+Supported chips:
+  * Analog Devices ADT7473
+    Prefix: 'adt7473'
+    Addresses scanned: I2C 0x2C, 0x2D, 0x2E
+    Datasheet: Publicly available at the On Semiconductors website
+  * Analog Devices ADT7475
+    Prefix: 'adt7475'
+    Addresses scanned: I2C 0x2E
+    Datasheet: Publicly available at the On Semiconductors website
+  * Analog Devices ADT7476
+    Prefix: 'adt7476'
+    Addresses scanned: I2C 0x2C, 0x2D, 0x2E
+    Datasheet: Publicly available at the On Semiconductors website
+  * Analog Devices ADT7490
+    Prefix: 'adt7490'
+    Addresses scanned: I2C 0x2C, 0x2D, 0x2E
+    Datasheet: Publicly available at the On Semiconductors website
 
-fanX_input		Read the current speed of the fan (in RPMs)
-fanX_min		Read/write the minimum speed of the fan.  Dropping
-			below this sets an alarm.
+Authors:
+	Jordan Crouse
+	Hans de Goede
+	Darrick J. Wong (documentation)
+	Jean Delvare
 
-(there are three PWMs, numbered pwm1 to pwm3):
 
-pwmX			Read/write the current duty cycle of the PWM.  Writes
-			only have effect when auto mode is turned off (see
-			below).  Range is 0 - 255.
+Description
+-----------
 
-pwmX_enable		Fan speed control method:
+This driver implements support for the Analog Devices ADT7473, ADT7475,
+ADT7476 and ADT7490 chip family. The ADT7473 and ADT7475 differ only in
+minor details. The ADT7476 has additional features, including extra voltage
+measurement inputs and VID support. The ADT7490 also has additional
+features, including extra voltage measurement inputs and PECI support. All
+the supported chips will be collectively designed by the name "ADT747x" in
+the rest of this document.
 
-			0 - No control (fan at full speed)
-			1 - Manual fan speed control (using pwm[1-*])
-			2 - Automatic fan speed control
+The ADT747x uses the 2-wire interface compatible with the SMBus 2.0
+specification. Using an analog to digital converter it measures three (3)
+temperatures and two (2) or more voltages. It has four (4) 16-bit counters
+for measuring fan speed. There are three (3) PWM outputs that can be used
+to control fan speed.
 
-pwmX_auto_channels_temp	Select which channels affect this PWM
+A sophisticated control system for the PWM outputs is designed into the
+ADT747x that allows fan speed to be adjusted automatically based on any of the
+three temperature sensors. Each PWM output is individually adjustable and
+programmable. Once configured, the ADT747x will adjust the PWM outputs in
+response to the measured temperatures without further host intervention.
+This feature can also be disabled for manual control of the PWM's.
 
-			1 - TEMP1 controls PWM
-			2 - TEMP2 controls PWM
-			4 - TEMP3 controls PWM
-			6 - TEMP2 and TEMP3 control PWM
-			7 - All three inputs control PWM
+Each of the measured inputs (voltage, temperature, fan speed) has
+corresponding high/low limit values. The ADT747x will signal an ALARM if
+any measured value exceeds either limit.
 
-pwmX_freq		Read/write the PWM frequency in Hz. The number
-			should be one of the following:
+The ADT747x samples all inputs continuously. The driver will not read
+the registers more often than once every other second. Further,
+configuration data is only read once per minute.
 
-			11 Hz
-			14 Hz
-			22 Hz
-			29 Hz
-			35 Hz
-			44 Hz
-			58 Hz
-			88 Hz
+Chip Differences Summary
+------------------------
 
-pwmX_auto_point1_pwm	Read/write the minimum PWM duty cycle in automatic mode
+ADT7473:
+  * 2 voltage inputs
+  * system acoustics optimizations (not implemented)
 
-pwmX_auto_point2_pwm	Read/write the maximum PWM duty cycle in automatic mode
+ADT7475:
+  * 2 voltage inputs
 
-(there are three temperature settings numbered temp1 to temp3):
+ADT7476:
+  * 5 voltage inputs
+  * VID support
 
-tempX_input		Read the current temperature.  The value is in milli
-			degrees of Celsius.
+ADT7490:
+  * 6 voltage inputs
+  * 1 Imon input (not implemented)
+  * PECI support (not implemented)
+  * 2 GPIO pins (not implemented)
+  * system acoustics optimizations (not implemented)
 
-tempX_max		Read/write the upper temperature limit - exceeding this
-			will cause an alarm.
+Special Features
+----------------
 
-tempX_min		Read/write the lower temperature limit - exceeding this
-			will cause an alarm.
+The ADT747x has a 10-bit ADC and can therefore measure temperatures
+with a resolution of 0.25 degree Celsius. Temperature readings can be
+configured either for two's complement format or "Offset 64" format,
+wherein 64 is subtracted from the raw value to get the temperature value.
 
-tempX_offset		Read/write the temperature adjustment offset
+The datasheet is very detailed and describes a procedure for determining
+an optimal configuration for the automatic PWM control.
 
-tempX_crit		Read/write the THERM limit for remote1.
+Fan Speed Control
+-----------------
 
-tempX_crit_hyst		Set the temperature value below crit where the
-			fans will stay on - this helps drive the temperature
-			low enough so it doesn't stay near the edge and
-			cause THERM to keep tripping.
+The driver exposes two trip points per PWM channel.
 
-tempX_auto_point1_temp	Read/write the minimum temperature where the fans will
-			turn on in automatic mode.
+point1: Set the PWM speed at the lower temperature bound
+point2: Set the PWM speed at the higher temperature bound
 
-tempX_auto_point2_temp	Read/write the maximum temperature over which the fans
-			will run in automatic mode.  tempX_auto_point1_temp
-			and tempX_auto_point2_temp together define the
-			range of automatic control.
+The ADT747x will scale the PWM linearly between the lower and higher PWM
+speed when the temperature is between the two temperature boundaries.
+Temperature boundaries are associated to temperature channels rather than
+PWM outputs, and a given PWM output can be controlled by several temperature
+channels. As a result, the ADT747x may compute more than one PWM value
+for a channel at a given time, in which case the maximum value (fastest
+fan speed) is applied. PWM values range from 0 (off) to 255 (full speed).
 
-tempX_alarm		Read a 1 if the max/min alarm is set
-tempX_fault		Read a 1 if either temp1 or temp3 diode has a fault
+Fan speed may be set to maximum when the temperature sensor associated with
+the PWM control exceeds temp#_max.
 
-(There are two voltage settings, in1 and in2):
+Notes
+-----
 
-inX_input		Read the current voltage on VCC.  Value is in
-			millivolts.
-
-inX_min			read/write the minimum voltage limit.
-			Dropping below this causes an alarm.
-
-inX_max			read/write the maximum voltage limit.
-			Exceeding this causes an alarm.
-
-inX_alarm		Read a 1 if the max/min alarm is set.
+The nVidia binary driver presents an ADT7473 chip via an on-card i2c bus.
+Unfortunately, they fail to set the i2c adapter class, so this driver may
+fail to find the chip until the nvidia driver is patched.
diff --git a/Documentation/hwmon/f71882fg b/Documentation/hwmon/f71882fg
index bee4c30..a7952c2 100644
--- a/Documentation/hwmon/f71882fg
+++ b/Documentation/hwmon/f71882fg
@@ -14,6 +14,10 @@
     Prefix: 'f71882fg'
     Addresses scanned: none, address read from Super I/O config space
     Datasheet: Available from the Fintek website
+  * Fintek F71889FG
+    Prefix: 'f71889fg'
+    Addresses scanned: none, address read from Super I/O config space
+    Datasheet: Should become available on the Fintek website soon
   * Fintek F8000
     Prefix: 'f8000'
     Addresses scanned: none, address read from Super I/O config space
@@ -51,6 +55,12 @@
 motherboard, so the driver assumes that the BIOS set the method
 properly.
 
+Note that the lowest numbered temperature zone trip point corresponds to
+to the border between the highest and one but highest temperature zones, and
+vica versa. So the temperature zone trip points 1-4 (or 1-2) go from high temp
+to low temp! This is how things are implemented in the IC, and the driver
+mimicks this.
+
 There are 2 modes to specify the speed of the fan, PWM duty cycle (or DC
 voltage) mode, where 0-100% duty cycle (0-100% of 12V) is specified. And RPM
 mode where the actual RPM of the fan (as measured) is controlled and the speed
diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87
index 659315d..f9ba96c 100644
--- a/Documentation/hwmon/it87
+++ b/Documentation/hwmon/it87
@@ -86,7 +86,6 @@
 the Vcore voltage of the processor. The early IT8712F have 5 VID pins,
 the IT8716F and late IT8712F have 6. They are shared with other functions
 though, so the functionality may not be available on a given system.
-The driver dumbly assume it is there.
 
 The IT8718F and IT8720F also features VID inputs (up to 8 pins) but the value
 is stored in the Super-I/O configuration space. Due to technical limitations,
diff --git a/Documentation/hwmon/mc13783-adc b/Documentation/hwmon/mc13783-adc
new file mode 100644
index 0000000..044531a
--- /dev/null
+++ b/Documentation/hwmon/mc13783-adc
@@ -0,0 +1,50 @@
+Kernel driver mc13783-adc
+=========================
+
+Supported chips:
+  * Freescale Atlas MC13783
+    Prefix: 'mc13783_adc'
+    Datasheet: http://www.freescale.com/files/rf_if/doc/data_sheet/MC13783.pdf?fsrch=1
+
+Authors:
+    Sascha Hauer <s.hauer@pengutronix.de>
+    Luotao Fu <l.fu@pengutronix.de>
+
+Description
+-----------
+
+The Freescale MC13783 is a Power Management and Audio Circuit. Among
+other things it contains a 10-bit A/D converter. The converter has 16
+channels which can be used in different modes.
+The A/D converter has a resolution of 2.25mV. Channels 0-4 have
+a dedicated meaning with chip internal scaling applied. Channels 5-7
+can be used as general purpose inputs or alternatively in a dedicated
+mode. Channels 12-15 are occupied by the touchscreen if it's active.
+
+Currently the driver only supports channels 2 and 5-15 with no alternative
+modes for channels 5-7.
+
+See this table for the meaning of the different channels and their chip
+internal scaling:
+
+Channel	Signal						Input Range	Scaling
+-------------------------------------------------------------------------------
+0	Battery Voltage (BATT)				2.50 - 4.65V	-2.40V
+1	Battery Current (BATT - BATTISNS)		-50 - 50 mV	x20
+2	Application Supply (BP)				2.50 - 4.65V	-2.40V
+3	Charger Voltage (CHRGRAW)			0 - 10V /	/5
+							0 - 20V		/10
+4	Charger Current (CHRGISNSP-CHRGISNSN)		-0.25V - 0.25V	x4
+5	General Purpose ADIN5 / Battery Pack Thermistor	0 - 2.30V	No
+6	General Purpose ADIN6 / Backup Voltage (LICELL)	0 - 2.30V /	No /
+							1.50 - 3.50V	-1.20V
+7	General Purpose ADIN7 / UID / Die Temperature	0 - 2.30V /	No /
+							0 - 2.55V /	x0.9 / No
+8	General Purpose ADIN8				0 - 2.30V	No
+9	General Purpose ADIN9				0 - 2.30V	No
+10	General Purpose ADIN10				0 - 2.30V	No
+11	General Purpose ADIN11				0 - 2.30V	No
+12	General Purpose TSX1 / Touchscreen X-plate 1	0 - 2.30V	No
+13	General Purpose TSX2 / Touchscreen X-plate 2	0 - 2.30V	No
+14	General Purpose TSY1 / Touchscreen Y-plate 1	0 - 2.30V	No
+15	General Purpose TSY2 / Touchscreen Y-plate 2	0 - 2.30V	No
diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface
index 82def88..3de6b0b 100644
--- a/Documentation/hwmon/sysfs-interface
+++ b/Documentation/hwmon/sysfs-interface
@@ -225,8 +225,6 @@
 		to PWM output channels.
 		RW
 
-OR
-
 temp[1-*]_auto_point[1-*]_pwm
 temp[1-*]_auto_point[1-*]_temp
 temp[1-*]_auto_point[1-*]_temp_hyst
@@ -235,6 +233,15 @@
 		to temperature channels.
 		RW
 
+There is a third case where trip points are associated to both PWM output
+channels and temperature channels: the PWM values are associated to PWM
+output channels while the temperature values are associated to temperature
+channels. In that case, the result is determined by the mapping between
+temperature inputs and PWM outputs. When several temperature inputs are
+mapped to a given PWM output, this leads to several candidate PWM values.
+The actual result is up to the chip, but in general the highest candidate
+value (fastest fan speed) wins.
+
 
 ****************
 * Temperatures *
diff --git a/Documentation/hwmon/w83627hf b/Documentation/hwmon/w83627hf
index 6ee36db..44dd2bc 100644
--- a/Documentation/hwmon/w83627hf
+++ b/Documentation/hwmon/w83627hf
@@ -32,8 +32,6 @@
 Module Parameters
 -----------------
 
-* force_addr: int
-  Initialize the ISA address of the sensors
 * force_i2c: int
   Initialize the I2C address of the sensors
 * init: int
@@ -70,3 +68,30 @@
 For further information on this driver see the w83781d driver documentation.
 
 [1] http://www.lm-sensors.org/browser/lm-sensors/trunk/doc/vid
+
+Forcing the address
+-------------------
+
+The driver used to have a module parameter named force_addr, which could
+be used to force the base I/O address of the hardware monitoring block.
+This was meant as a workaround for mainboards with a broken BIOS. This
+module parameter is gone for technical reasons. If you need this feature,
+you can obtain the same result by using the isaset tool (part of
+lm-sensors) before loading the driver:
+
+# Enter the Super I/O config space
+isaset -y -f 0x2e 0x87
+isaset -y -f 0x2e 0x87
+
+# Select the hwmon logical device
+isaset -y 0x2e 0x2f 0x07 0x0b
+
+# Set the base I/O address (to 0x290 in this example)
+isaset -y 0x2e 0x2f 0x60 0x02
+isaset -y 0x2e 0x2f 0x61 0x90
+
+# Exit the Super-I/O config space
+isaset -y -f 0x2e 0xaa
+
+The above sequence assumes a Super-I/O config space at 0x2e/0x2f, but
+0x4e/0x4f is also possible.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 495a39a..3f886e2 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2663,6 +2663,8 @@
 			to a common usb-storage quirk flag as follows:
 				a = SANE_SENSE (collect more than 18 bytes
 					of sense data);
+				b = BAD_SENSE (don't collect more than 18
+					bytes of sense data);
 				c = FIX_CAPACITY (decrease the reported
 					device capacity by one sector);
 				h = CAPACITY_HEURISTICS (decrease the
@@ -2747,6 +2749,15 @@
 			Default is 1, i.e. UTF-8 mode is enabled for all
 			newly opened terminals.
 
+	vt.global_cursor_default=
+			[VT]
+			Format=<-1|0|1>
+			Set system-wide default for whether a cursor
+			is shown on new VTs. Default is -1,
+			i.e. cursors will be created by default unless
+			overridden by individual drivers. 0 will hide
+			cursors, 1 will display them.
+
 	waveartist=	[HW,OSS]
 			Format: <io>,<irq>,<dma>,<dma2>
 
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index 098de5b..4220851 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -304,7 +304,7 @@
 	addr = mmap(NULL, getpagesize() * num,
 		    PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, fd, 0);
 	if (addr == MAP_FAILED)
-		err(1, "Mmaping %u pages of /dev/zero", num);
+		err(1, "Mmapping %u pages of /dev/zero", num);
 
 	/*
 	 * One neat mmap feature is that you can close the fd, and it
diff --git a/Documentation/c2port.txt b/Documentation/misc-devices/c2port.txt
similarity index 100%
rename from Documentation/c2port.txt
rename to Documentation/misc-devices/c2port.txt
diff --git a/Documentation/ics932s401 b/Documentation/misc-devices/ics932s401
similarity index 100%
rename from Documentation/ics932s401
rename to Documentation/misc-devices/ics932s401
diff --git a/Documentation/oops-tracing.txt b/Documentation/oops-tracing.txt
index b152e81..c10c022 100644
--- a/Documentation/oops-tracing.txt
+++ b/Documentation/oops-tracing.txt
@@ -257,6 +257,8 @@
 
  10: 'W' if a warning has previously been issued by the kernel.
 
+ 11: 'C' if a staging driver has been loaded.
+
 The primary reason for the 'Tainted: ' string is to tell kernel
 debuggers if this is a clean kernel or if anything unusual has
 occurred.  Tainting is permanent: even if an offending module is
diff --git a/Documentation/power/regulator/consumer.txt b/Documentation/power/regulator/consumer.txt
index 5f83fd2..cdebb51 100644
--- a/Documentation/power/regulator/consumer.txt
+++ b/Documentation/power/regulator/consumer.txt
@@ -104,7 +104,7 @@
 
 Consumers can control their supply current limit by calling :-
 
-int regulator_set_current_limit(regulator, min_uV, max_uV);
+int regulator_set_current_limit(regulator, min_uA, max_uA);
 
 Where min_uA and max_uA are the minimum and maximum acceptable current limit in
 microamps.
diff --git a/Documentation/powerpc/dts-bindings/xilinx.txt b/Documentation/powerpc/dts-bindings/xilinx.txt
index 80339fe..ea68046 100644
--- a/Documentation/powerpc/dts-bindings/xilinx.txt
+++ b/Documentation/powerpc/dts-bindings/xilinx.txt
@@ -292,4 +292,15 @@
        - reg-offset : A value of 3 is required
        - reg-shift : A value of 2 is required
 
+      vii) Xilinx USB Host controller
+
+      The Xilinx USB host controller is EHCI compatible but with a different
+      base address for the EHCI registers, and it is always a big-endian
+      USB Host controller. The hardware can be configured as high speed only,
+      or high speed/full speed hybrid.
+
+      Required properties:
+      - xlnx,support-usb-fs: A value 0 means the core is built as high speed
+                             only. A value 1 means the core also supports
+                             full speed devices.
 
diff --git a/Documentation/scsi/ChangeLog.megaraid_sas b/Documentation/scsi/ChangeLog.megaraid_sas
index c851ef4..17ffa06 100644
--- a/Documentation/scsi/ChangeLog.megaraid_sas
+++ b/Documentation/scsi/ChangeLog.megaraid_sas
@@ -1,3 +1,65 @@
+1 Release Date    : Tues.  July 28, 2009 10:12:45 PST 2009 -
+			(emaild-id:megaraidlinux@lsi.com)
+			Bo Yang
+
+2 Current Version : 00.00.04.12
+3 Older Version   : 00.00.04.10
+
+1.	Change the AEN sys PD update from scsi_scan to
+	scsi_add_device and scsi_remove_device.
+2.	Takeoff the debug print-out in aen_polling routine.
+
+1 Release Date    : Thur.  July 02, 2009 10:12:45 PST 2009 -
+			(emaild-id:megaraidlinux@lsi.com)
+			Bo Yang
+
+2 Current Version : 00.00.04.10
+3 Older Version   : 00.00.04.08
+
+1.	Add the 3 mins timeout during the controller initialize.
+2.	Add the fix for 64bit sense date errors.
+
+1 Release Date    : Tues. May 05, 2009 10:12:45 PST 2009 -
+			(emaild-id:megaraidlinux@lsi.com)
+			Bo Yang
+
+2 Current Version : 00.00.04.08
+3 Older Version   : 00.00.04.06
+
+1.	Add the fix of pending in FW after deleted the logic drives.
+2.	Add the fix of deallocating memory after get pdlist.
+
+1 Release Date    : Tues. March 26, 2009 10:12:45 PST 2009 -
+			(emaild-id:megaraidlinux@lsi.com)
+			Bo Yang
+
+2 Current Version : 00.00.04.06
+3 Older Version   : 00.00.04.04
+
+1.	Add the fix of the driver cmd empty fix of the driver cmd empty.
+2.	Add the fix of the driver MSM AEN CMD cause the system slow.
+
+1 Release Date    : Tues. March 03, 2009 10:12:45 PST 2009 -
+			(emaild-id:megaraidlinux@lsi.com)
+			Bo Yang
+
+2 Current Version : 00.00.04.04
+3 Older Version   : 00.00.04.01
+
+1.	Add the Tape drive fix to the driver: If the command is for
+	the tape device, set the pthru timeout to the os layer timeout value.
+
+2.	Add Poll_wait mechanism to Gen-2 Linux driv.
+		In the aen handler, driver needs to wakeup poll handler similar to
+		the way it raises SIGIO.
+
+3.	Add new controller new SAS2 support to the driver.
+
+4.	Report the unconfigured PD (system PD) to OS.
+
+5.	Add the IEEE SGL support to the driver
+
+6.	Reasign the Application cmds to SAS2 controller
 
 1 Release Date    : Thur.July. 24 11:41:51 PST 2008 -
                        (emaild-id:megaraidlinux@lsi.com)
@@ -185,7 +247,7 @@
 	Disks are exposed with WCE=1. User is advised to enable Write Back
 	mode only when the controller has battery backup. At this time
 	Synhronize cache is not supported by the FW. Driver will short-cycle
-	the cmd and return sucess without sending down to FW.
+	the cmd and return success without sending down to FW.
 
 1 Release Date    : Sun Jan. 14 11:21:32 PDT 2007 -
 		 Sumant Patro <Sumant.Patro@lsil.com>/Bo Yang
diff --git a/Documentation/serial/hayes-esp.txt b/Documentation/serial/hayes-esp.txt
deleted file mode 100644
index 09b5d58..0000000
--- a/Documentation/serial/hayes-esp.txt
+++ /dev/null
@@ -1,154 +0,0 @@
-HAYES ESP DRIVER VERSION 2.1
-
-A big thanks to the people at Hayes, especially Alan Adamson.  Their support
-has enabled me to provide enhancements to the driver.
-
-Please report your experiences with this driver to me (arobinso@nyx.net).  I
-am looking for both positive and negative feedback.
-
-*** IMPORTANT CHANGES FOR 2.1 ***
-Support for PIO mode.  Five situations will cause PIO mode to be used:
-1) A multiport card is detected.  PIO mode will always be used.  (8 port cards
-do not support DMA).
-2) The DMA channel is set to an invalid value (anything other than 1 or 3).
-3) The DMA buffer/channel could not be allocated.  The port will revert to PIO
-mode until it is reopened.
-4) Less than a specified number of bytes need to be transferred to/from the
-FIFOs.  PIO mode will be used for that transfer only.
-5) A port needs to do a DMA transfer and another port is already using the
-DMA channel.  PIO mode will be used for that transfer only.
-
-Since the Hayes ESP seems to conflict with other cards (notably sound cards)
-when using DMA, DMA is turned off by default.  To use DMA, it must be turned
-on explicitly, either with the "dma=" option described below or with
-setserial.  A multiport card can be forced into DMA mode by using setserial;
-however, most multiport cards don't support DMA.
-
-The latest version of setserial allows the enhanced configuration of the ESP
-card to be viewed and modified.
-***
-
-This package contains the files needed to compile a module to support the Hayes
-ESP card.  The drivers are basically a modified version of the serial drivers.
-
-Features:
-
-- Uses the enhanced mode of the ESP card, allowing a wider range of
-  interrupts and features than compatibility mode
-- Uses DMA and 16 bit PIO mode to transfer data to and from the ESP's FIFOs,
-  reducing CPU load
-- Supports primary and secondary ports
-
-
-If the driver is compiled as a module, the IRQs to use can be specified by
-using the irq= option.  The format is:
-
-irq=[0x100],[0x140],[0x180],[0x200],[0x240],[0x280],[0x300],[0x380]
-
-The address in brackets is the base address of the card.  The IRQ of
-nonexistent cards can be set to 0.  If an IRQ of a card that does exist is set
-to 0, the driver will attempt to guess at the correct IRQ.  For example, to set
-the IRQ of the card at address 0x300 to 12, the insmod command would be:
-
-insmod esp irq=0,0,0,0,0,0,12,0
-
-The custom divisor can be set by using the divisor= option.  The format is the
-same as for the irq= option.  Each divisor value is a series of hex digits,
-with each digit representing the divisor to use for a corresponding port.  The
-divisor value is constructed RIGHT TO LEFT.  Specifying a nonzero divisor value
-will automatically set the spd_cust flag.  To calculate the divisor to use for
-a certain baud rate, divide the port's base baud (generally 921600) by the
-desired rate.  For example, to set the divisor of the primary port at 0x300 to
-4 and the divisor of the secondary port at 0x308 to 8, the insmod command would
-be:
-
-insmod esp divisor=0,0,0,0,0,0,0x84,0
-
-The dma= option can be used to set the DMA channel.  The channel can be either
-1 or 3.  Specifying any other value will force the driver to use PIO mode.
-For example, to set the DMA channel to 3, the insmod command would be:
-
-insmod esp dma=3
-
-The rx_trigger= and tx_trigger= options can be used to set the FIFO trigger
-levels.  They specify when the ESP card should send an interrupt.  Larger
-values will decrease the number of interrupts; however, a value too high may
-result in data loss.  Valid values are 1 through 1023, with 768 being the
-default.  For example, to set the receive trigger level to 512 bytes and the
-transmit trigger level to 700 bytes, the insmod command would be:
-
-insmod esp rx_trigger=512 tx_trigger=700
-
-The flow_off= and flow_on= options can be used to set the hardware flow off/
-flow on levels.  The flow on level must be lower than the flow off level, and
-the flow off level should be higher than rx_trigger.  Valid values are 1
-through 1023, with 1016 being the default flow off level and 944 being the
-default flow on level.  For example, to set the flow off level to 1000 bytes
-and the flow on level to 935 bytes, the insmod command would be:
-
-insmod esp flow_off=1000 flow_on=935
-
-The rx_timeout= option can be used to set the receive timeout value.  This
-value indicates how long after receiving the last character that the ESP card
-should wait before signalling an interrupt.  Valid values are 0 though 255,
-with 128 being the default.  A value too high will increase latency, and a
-value too low will cause unnecessary interrupts.  For example, to set the
-receive timeout to 255, the insmod command would be:
-
-insmod esp rx_timeout=255
-
-The pio_threshold= option sets the threshold (in number of characters) for
-using PIO mode instead of DMA mode.  For example, if this value is 32,
-transfers of 32 bytes or less will always use PIO mode.
-
-insmod esp pio_threshold=32
-
-Multiple options can be listed on the insmod command line by separating each
-option with a space.  For example:
-
-insmod esp dma=3 trigger=512
-
-The esp module can be automatically loaded when needed.  To cause this to
-happen, add the following lines to /etc/modprobe.conf (replacing the last line
-with options for your configuration):
-
-alias char-major-57 esp
-alias char-major-58 esp
-options esp irq=0,0,0,0,0,0,3,0 divisor=0,0,0,0,0,0,0x4,0
-
-You may also need to run 'depmod -a'.
-
-Devices must be created manually.  To create the devices, note the output from
-the module after it is inserted.  The output will appear in the location where
-kernel messages usually appear (usually /var/adm/messages).  Create two devices
-for each 'tty' mentioned, one with major of 57 and the other with major of 58.
-The minor number should be the same as the tty number reported.  The commands
-would be (replace ? with the tty number):
-
-mknod /dev/ttyP? c 57 ?
-mknod /dev/cup? c 58 ?
-
-For example, if the following line appears:
-
-Oct 24 18:17:23 techno kernel: ttyP8 at 0x0140 (irq = 3) is an ESP primary port
-
-...two devices should be created:
-
-mknod /dev/ttyP8 c 57 8
-mknod /dev/cup8 c 58 8
-
-You may need to set the permissions on the devices:
-
-chmod 666 /dev/ttyP*
-chmod 666 /dev/cup*
-
-The ESP module and the serial module should not conflict (they can be used at
-the same time).  After the ESP module has been loaded the ports on the ESP card
-will no longer be accessible by the serial driver.
-
-If I/O errors are experienced when accessing the port, check for IRQ and DMA
-conflicts ('cat /proc/interrupts' and 'cat /proc/dma' for a list of IRQs and
-DMAs currently in use).
-
-Enjoy!
-Andrew J. Robinson <arobinso@nyx.net>
diff --git a/Documentation/serial/tty.txt b/Documentation/serial/tty.txt
index 8e65c44..5e5349a 100644
--- a/Documentation/serial/tty.txt
+++ b/Documentation/serial/tty.txt
@@ -42,7 +42,8 @@
 open()		-	Called when the line discipline is attached to
 			the terminal. No other call into the line
 			discipline for this tty will occur until it
-			completes successfully. Can sleep.
+			completes successfully. Returning an error will
+			prevent the ldisc from being attached. Can sleep.
 
 close()		-	This is called on a terminal when the line
 			discipline is being unplugged. At the point of
@@ -52,7 +53,7 @@
 hangup()	-	Called when the tty line is hung up.
 			The line discipline should cease I/O to the tty.
 			No further calls into the ldisc code will occur.
-			Can sleep.
+			The return value is ignored. Can sleep.
 
 write()		-	A process is writing data through the line
 			discipline.  Multiple write calls are serialized
@@ -83,6 +84,10 @@
 			that might be for the ldisc. Multiple ioctl calls
 			may occur in parallel. May sleep. 
 
+compat_ioctl()	-	Called when a 32 bit ioctl is handed to the tty layer
+			that might be for the ldisc. Multiple ioctl calls
+			may occur in parallel. May sleep.
+
 Driver Side Interfaces:
 
 receive_buf()	-	Hand buffers of bytes from the driver to the ldisc
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
index 9000cd8..e93afff 100644
--- a/Documentation/sound/alsa/HD-Audio-Models.txt
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
@@ -126,6 +126,7 @@
   mb5		Macbook 5,1
   mbp3		Macbook Pro rev3
   imac24	iMac 24'' with jack detection
+  imac91	iMac 9,1
   w2jc		ASUS W2JC
   3stack-2ch-dig	3-jack with SPDIF I/O (ALC883)
   alc883-6stack-dig	6-jack digital with SPDIF I/O (ALC883)
diff --git a/Documentation/sound/alsa/HD-Audio.txt b/Documentation/sound/alsa/HD-Audio.txt
index 7b8a5f9..6325bec 100644
--- a/Documentation/sound/alsa/HD-Audio.txt
+++ b/Documentation/sound/alsa/HD-Audio.txt
@@ -624,11 +624,13 @@
 the widget information and adjusting the amp values, as well as the
 proc-compatible output.
 
-The hda-analyzer is a part of alsa.git repository in
-alsa-project.org:
+The hda-analyzer:
 
 - http://git.alsa-project.org/?p=alsa.git;a=tree;f=hda-analyzer
 
+is a part of alsa.git repository in alsa-project.org:
+
+- git://git.alsa-project.org/alsa.git
 
 Codecgraph
 ~~~~~~~~~~
diff --git a/Documentation/spi/spi-summary b/Documentation/spi/spi-summary
index deab51d..4884cb3 100644
--- a/Documentation/spi/spi-summary
+++ b/Documentation/spi/spi-summary
@@ -538,7 +538,7 @@
 The bulk of the driver will be managing the I/O queue fed by transfer().
 
 That queue could be purely conceptual.  For example, a driver used only
-for low-frequency sensor acess might be fine using synchronous PIO.
+for low-frequency sensor access might be fine using synchronous PIO.
 
 But the queue will probably be very real, using message->queue, PIO,
 often DMA (especially if the root filesystem is in SPI flash), and
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
index a028b92..8f7a0e7 100644
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -139,9 +139,9 @@
 core_pipe_limit:
 
 This sysctl is only applicable when core_pattern is configured to pipe core
-files to user space helper a (when the first character of core_pattern is a '|',
+files to a user space helper (when the first character of core_pattern is a '|',
 see above).  When collecting cores via a pipe to an application, it is
-occasionally usefull for the collecting application to gather data about the
+occasionally useful for the collecting application to gather data about the
 crashing process from its /proc/pid directory.  In order to do this safely, the
 kernel must wait for the collecting process to exit, so as not to remove the
 crashing processes proc files prematurely.  This in turn creates the possibility
@@ -152,7 +152,7 @@
 processes above that value are noted via the kernel log and their cores are
 skipped.  0 is a special value, indicating that unlimited processes may be
 captured in parallel, but that no waiting will take place (i.e. the collecting
-process is not guaranteed access to /proc/<crahing pid>/).  This value defaults
+process is not guaranteed access to /proc/<crashing pid>/).  This value defaults
 to 0.
 
 ==============================================================
diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt
index a6e360d..fc5790d 100644
--- a/Documentation/sysctl/vm.txt
+++ b/Documentation/sysctl/vm.txt
@@ -370,7 +370,7 @@
 mmap_min_addr
 
 This file indicates the amount of address space  which a user process will
-be restricted from mmaping.  Since kernel null dereference bugs could
+be restricted from mmapping.  Since kernel null dereference bugs could
 accidentally operate based on the information in the first couple of pages
 of memory userspace processes should not be allowed to write to them.  By
 default this value is set to 0 and no protections will be enforced by the
diff --git a/Documentation/timers/hpet.txt b/Documentation/timers/hpet.txt
index 04763a3..16d25e6 100644
--- a/Documentation/timers/hpet.txt
+++ b/Documentation/timers/hpet.txt
@@ -3,7 +3,7 @@
 The High Precision Event Timer (HPET) hardware follows a specification
 by Intel and Microsoft which can be found at
 
-	http://www.intel.com/technology/architecture/hpetspec.htm
+	http://www.intel.com/hardwaredesign/hpetspec_1.pdf
 
 Each HPET has one fixed-rate counter (at 10+ MHz, hence "High Precision")
 and up to 32 comparators.  Normally three or more comparators are provided,
diff --git a/Documentation/usb/power-management.txt b/Documentation/usb/power-management.txt
index ad64261..c7c1dc2 100644
--- a/Documentation/usb/power-management.txt
+++ b/Documentation/usb/power-management.txt
@@ -2,7 +2,7 @@
 
 		 Alan Stern <stern@rowland.harvard.edu>
 
-			    October 5, 2007
+			    November 10, 2009
 
 
 
@@ -123,9 +123,9 @@
 
 	power/level
 
-		This file contains one of three words: "on", "auto",
-		or "suspend".  You can write those words to the file
-		to change the device's setting.
+		This file contains one of two words: "on" or "auto".
+		You can write those words to the file to change the
+		device's setting.
 
 		"on" means that the device should be resumed and
 		autosuspend is not allowed.  (Of course, system
@@ -134,10 +134,10 @@
 		"auto" is the normal state in which the kernel is
 		allowed to autosuspend and autoresume the device.
 
-		"suspend" means that the device should remain
-		suspended, and autoresume is not allowed.  (But remote
-		wakeup may still be allowed, since it is controlled
-		separately by the power/wakeup attribute.)
+		(In kernels up to 2.6.32, you could also specify
+		"suspend", meaning that the device should remain
+		suspended and autoresume was not allowed.  This
+		setting is no longer supported.)
 
 	power/autosuspend
 
@@ -313,13 +313,14 @@
 that it supports autosuspend by setting the .supports_autosuspend flag
 in its usb_driver structure.  It is then responsible for informing the
 USB core whenever one of its interfaces becomes busy or idle.  The
-driver does so by calling these five functions:
+driver does so by calling these six functions:
 
 	int  usb_autopm_get_interface(struct usb_interface *intf);
 	void usb_autopm_put_interface(struct usb_interface *intf);
-	int  usb_autopm_set_interface(struct usb_interface *intf);
 	int  usb_autopm_get_interface_async(struct usb_interface *intf);
 	void usb_autopm_put_interface_async(struct usb_interface *intf);
+	void usb_autopm_get_interface_no_resume(struct usb_interface *intf);
+	void usb_autopm_put_interface_no_suspend(struct usb_interface *intf);
 
 The functions work by maintaining a counter in the usb_interface
 structure.  When intf->pm_usage_count is > 0 then the interface is
@@ -331,11 +332,13 @@
 associated with the device itself rather than any of its interfaces.
 This field is used only by the USB core.)
 
-The driver owns intf->pm_usage_count; it can modify the value however
-and whenever it likes.  A nice aspect of the non-async usb_autopm_*
-routines is that the changes they make are protected by the usb_device
-structure's PM mutex (udev->pm_mutex); however drivers may change
-pm_usage_count without holding the mutex.  Drivers using the async
+Drivers must not modify intf->pm_usage_count directly; its value
+should be changed only be using the functions listed above.  Drivers
+are responsible for insuring that the overall change to pm_usage_count
+during their lifetime balances out to 0 (it may be necessary for the
+disconnect method to call usb_autopm_put_interface() one or more times
+to fulfill this requirement).  The first two routines use the PM mutex
+in struct usb_device for mutual exclusion; drivers using the async
 routines are responsible for their own synchronization and mutual
 exclusion.
 
@@ -347,11 +350,6 @@
 	attempts an autosuspend if the new value is <= 0 and the
 	device isn't suspended.
 
-	usb_autopm_set_interface() leaves pm_usage_count alone.
-	It attempts an autoresume if the value is > 0 and the device
-	is suspended, and it attempts an autosuspend if the value is
-	<= 0 and the device isn't suspended.
-
 	usb_autopm_get_interface_async() and
 	usb_autopm_put_interface_async() do almost the same things as
 	their non-async counterparts.  The differences are: they do
@@ -360,13 +358,11 @@
 	such as an URB's completion handler, but when they return the
 	device will not generally not yet be in the desired state.
 
-There also are a couple of utility routines drivers can use:
-
-	usb_autopm_enable() sets pm_usage_cnt to 0 and then calls
-	usb_autopm_set_interface(), which will attempt an autosuspend.
-
-	usb_autopm_disable() sets pm_usage_cnt to 1 and then calls
-	usb_autopm_set_interface(), which will attempt an autoresume.
+	usb_autopm_get_interface_no_resume() and
+	usb_autopm_put_interface_no_suspend() merely increment or
+	decrement the pm_usage_count value; they do not attempt to
+	carry out an autoresume or an autosuspend.  Hence they can be
+	called in an atomic context.
 
 The conventional usage pattern is that a driver calls
 usb_autopm_get_interface() in its open routine and
@@ -400,11 +396,11 @@
 Normally a driver would set this flag in its probe method, at which
 time the device is guaranteed not to be autosuspended.)
 
-The usb_autopm_* routines have to run in a sleepable process context;
-they must not be called from an interrupt handler or while holding a
-spinlock.  In fact, the entire autosuspend mechanism is not well geared
-toward interrupt-driven operation.  However there is one thing a
-driver can do in an interrupt handler:
+The synchronous usb_autopm_* routines have to run in a sleepable
+process context; they must not be called from an interrupt handler or
+while holding a spinlock.  In fact, the entire autosuspend mechanism
+is not well geared toward interrupt-driven operation.  However there
+is one thing a driver can do in an interrupt handler:
 
 	usb_mark_last_busy(struct usb_device *udev);
 
@@ -423,15 +419,16 @@
 
 External suspend calls should never be allowed to fail in this way,
 only autosuspend calls.  The driver can tell them apart by checking
-udev->auto_pm; this flag will be set to 1 for internal PM events
-(autosuspend or autoresume) and 0 for external PM events.
+the PM_EVENT_AUTO bit in the message.event argument to the suspend
+method; this bit will be set for internal PM events (autosuspend) and
+clear for external PM events.
 
 Many of the ingredients in the autosuspend framework are oriented
 towards interfaces: The usb_interface structure contains the
 pm_usage_cnt field, and the usb_autopm_* routines take an interface
 pointer as their argument.  But somewhat confusingly, a few of the
-pieces (usb_mark_last_busy() and udev->auto_pm) use the usb_device
-structure instead.  Drivers need to keep this straight; they can call
+pieces (i.e., usb_mark_last_busy()) use the usb_device structure
+instead.  Drivers need to keep this straight; they can call
 interface_to_usbdev() to find the device structure for a given
 interface.
 
diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885
index 5f33d84..7539e8f 100644
--- a/Documentation/video4linux/CARDLIST.cx23885
+++ b/Documentation/video4linux/CARDLIST.cx23885
@@ -24,3 +24,5 @@
  23 -> Magic-Pro ProHDTV Extreme 2                         [14f1:8657]
  24 -> Hauppauge WinTV-HVR1850                             [0070:8541]
  25 -> Compro VideoMate E800                               [1858:e800]
+ 26 -> Hauppauge WinTV-HVR1290                             [0070:8551]
+ 27 -> Mygica X8558 PRO DMB-TH                             [14f1:8578]
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
index 3385f8b..7ec3c4e 100644
--- a/Documentation/video4linux/CARDLIST.cx88
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -81,3 +81,4 @@
  80 -> Hauppauge WinTV-IR Only                             [0070:9290]
  81 -> Leadtek WinFast DTV1800 Hybrid                      [107d:6654]
  82 -> WinFast DTV2000 H rev. J                            [107d:6f2b]
+ 83 -> Prof 7301 DVB-S/S2                                  [b034:3034]
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
index b8afef4..0c166ff 100644
--- a/Documentation/video4linux/CARDLIST.em28xx
+++ b/Documentation/video4linux/CARDLIST.em28xx
@@ -1,5 +1,5 @@
   0 -> Unknown EM2800 video grabber             (em2800)        [eb1a:2800]
-  1 -> Unknown EM2750/28xx video grabber        (em2820/em2840) [eb1a:2710,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883,eb1a:2868]
+  1 -> Unknown EM2750/28xx video grabber        (em2820/em2840) [eb1a:2710,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2862,eb1a:2870,eb1a:2881,eb1a:2883,eb1a:2868]
   2 -> Terratec Cinergy 250 USB                 (em2820/em2840) [0ccd:0036]
   3 -> Pinnacle PCTV USB 2                      (em2820/em2840) [2304:0208]
   4 -> Hauppauge WinTV USB 2                    (em2820/em2840) [2040:4200,2040:4201]
@@ -69,3 +69,4 @@
  71 -> Silvercrest Webcam 1.3mpix               (em2820/em2840)
  72 -> Gadmei UTV330+                           (em2861)
  73 -> Reddo DVB-C USB TV Box                   (em2870)
+ 74 -> Actionmaster/LinXcel/Digitus VC211A      (em2800)
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index 2620d60..fce1e7e 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -172,3 +172,5 @@
 171 -> Beholder BeholdTV X7                     [5ace:7595]
 172 -> RoverMedia TV Link Pro FM                [19d1:0138]
 173 -> Zolid Hybrid TV Tuner PCI                [1131:2004]
+174 -> Asus Europa Hybrid OEM                   [1043:4847]
+175 -> Leadtek Winfast DTV1000S                 [107d:6655]
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt
index 3f61825..319d983 100644
--- a/Documentation/video4linux/gspca.txt
+++ b/Documentation/video4linux/gspca.txt
@@ -6,7 +6,8 @@
 
 xxxx		vend:prod
 ----
-spca501		0000:0000	MystFromOri Unknow Camera
+spca501		0000:0000	MystFromOri Unknown Camera
+spca508		0130:0130	Clone Digital Webcam 11043
 m5602		0402:5602	ALi Video Camera Controller
 spca501		040a:0002	Kodak DVC-325
 spca500		040a:0300	Kodak EZ200
@@ -37,6 +38,7 @@
 ov519		041e:4060	Creative Live! VISTA VF0350
 ov519		041e:4061	Creative Live! VISTA VF0400
 ov519		041e:4064	Creative Live! VISTA VF0420
+ov519		041e:4067	Creative Live! Cam Video IM (VF0350)
 ov519		041e:4068	Creative Live! VISTA VF0470
 spca561		0458:7004	Genius VideoCAM Express V2
 sunplus		0458:7006	Genius Dsc 1.3 Smart
@@ -68,12 +70,12 @@
 zc3xx		046d:08a6	Logitech QCim
 zc3xx		046d:08a7	Logitech QuickCam Image
 zc3xx		046d:08a9	Logitech Notebook Deluxe
-zc3xx		046d:08aa	Labtec Webcam  Notebook
+zc3xx		046d:08aa	Labtec Webcam Notebook
 zc3xx		046d:08ac	Logitech QuickCam Cool
 zc3xx		046d:08ad	Logitech QCCommunicate STX
 zc3xx		046d:08ae	Logitech QuickCam for Notebooks
 zc3xx		046d:08af	Logitech QuickCam Cool
-zc3xx		046d:08b9	Logitech QC IM ???
+zc3xx		046d:08b9	Logitech QuickCam Express
 zc3xx		046d:08d7	Logitech QCam STX
 zc3xx		046d:08d9	Logitech QuickCam IM/Connect
 zc3xx		046d:08d8	Logitech Notebook Deluxe
@@ -82,7 +84,7 @@
 spca500		046d:0900	Logitech Inc. ClickSmart 310
 spca500		046d:0901	Logitech Inc. ClickSmart 510
 sunplus		046d:0905	Logitech ClickSmart 820
-tv8532		046d:0920	QC Express
+tv8532		046d:0920	Logitech QuickCam Express
 tv8532		046d:0921	Labtec Webcam
 spca561		046d:0928	Logitech QC Express Etch2
 spca561		046d:0929	Labtec Webcam Elch2
@@ -91,7 +93,7 @@
 spca561		046d:092c	Logitech QC chat Elch2
 spca561		046d:092d	Logitech QC Elch2
 spca561		046d:092e	Logitech QC Elch2
-spca561		046d:092f	Logitech  QuickCam Express Plus
+spca561		046d:092f	Logitech QuickCam Express Plus
 sunplus		046d:0960	Logitech ClickSmart 420
 sunplus		0471:0322	Philips DMVC1300K
 zc3xx		0471:0325	Philips SPC 200 NC
@@ -187,7 +189,6 @@
 sonixj		06f8:3008	Hercules Deluxe Optical Glass
 pac7311		06f8:3009	Hercules Classic Link
 spca508		0733:0110	ViewQuest VQ110
-spca508		0130:0130	Clone Digital Webcam 11043
 spca501		0733:0401	Intel Create and Share
 spca501		0733:0402	ViewQuest M318B
 spca505		0733:0430	Intel PC Camera Pro
@@ -202,6 +203,7 @@
 spca500		08ca:0103	Aiptek PocketDV
 sunplus		08ca:0104	Aiptek PocketDVII 1.3
 sunplus		08ca:0106	Aiptek Pocket DV3100+
+mr97310a	08ca:0110	Trust Spyc@m 100
 mr97310a	08ca:0111	Aiptek PenCam VGA+
 sunplus		08ca:2008	Aiptek Mini PenCam 2 M
 sunplus		08ca:2010	Aiptek PocketCam 3M
@@ -222,7 +224,7 @@
 pac207		093a:2461	HP Webcam
 pac207		093a:2463	Philips SPC 220 NC
 pac207		093a:2464	Labtec Webcam 1200
-pac207		093a:2468	PAC207
+pac207		093a:2468	Webcam WB-1400T
 pac207		093a:2470	Genius GF112
 pac207		093a:2471	Genius VideoCam ge111
 pac207		093a:2472	Genius VideoCam ge110
@@ -230,7 +232,7 @@
 pac207		093a:2476	Genius e-Messenger 112
 pac7311		093a:2600	PAC7311 Typhoon
 pac7311		093a:2601	Philips SPC 610 NC
-pac7311		093a:2603	PAC7312
+pac7311		093a:2603	Philips SPC 500 NC
 pac7311		093a:2608	Trust WB-3300p
 pac7311		093a:260e	Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350
 pac7311		093a:260f	SnakeCam
@@ -239,6 +241,7 @@
 pac7311		093a:2622	Genius Eye 312
 pac7311		093a:2624	PAC7302
 pac7311		093a:2626	Labtec 2200
+pac7311		093a:2628	Genius iLook 300
 pac7311		093a:2629	Genious iSlim 300
 pac7311		093a:262a	Webcam 300k
 pac7311		093a:262c	Philips SPC 230 NC
@@ -250,7 +253,7 @@
 zc3xx		0ac8:301b	Z-Star zc301b
 zc3xx		0ac8:303b	Vimicro 0x303b
 zc3xx		0ac8:305b	Z-star Vimicro zc0305b
-zc3xx		0ac8:307b	Ldlc VC302+Ov7620
+zc3xx		0ac8:307b	PC Camera (ZS0211)
 vc032x		0ac8:c001	Sony embedded vimicro
 vc032x		0ac8:c002	Sony embedded vimicro
 vc032x		0ac8:c301	Samsung Q1 Ultra Premium
diff --git a/Documentation/video4linux/si4713.txt b/Documentation/video4linux/si4713.txt
index 25abdb7..2e7392a 100644
--- a/Documentation/video4linux/si4713.txt
+++ b/Documentation/video4linux/si4713.txt
@@ -164,7 +164,7 @@
 
 The device can also be configured using the available sub channels for
 transmission. To do that use S/G_MODULATOR ioctl and configure txsubchans properly.
-Refer to v4l2-spec for proper use of this ioctl.
+Refer to the V4L2 API specification for proper use of this ioctl.
 
 Testing
 =======
diff --git a/Documentation/video4linux/zr364xx.txt b/Documentation/video4linux/zr364xx.txt
index 7f3d195..d98e4d3 100644
--- a/Documentation/video4linux/zr364xx.txt
+++ b/Documentation/video4linux/zr364xx.txt
@@ -66,3 +66,4 @@
 0x0a17  0x004e   Pentax          Optio 50
 0x041e  0x405d   Creative        DiVi CAM 516
 0x08ca  0x2102   Aiptek          DV T300
+0x06d6  0x003d   Trust           Powerc@m 910Z
diff --git a/Documentation/vm/page-types.c b/Documentation/vm/page-types.c
index 4793c6a..ea44ea5 100644
--- a/Documentation/vm/page-types.c
+++ b/Documentation/vm/page-types.c
@@ -301,7 +301,7 @@
 		present = (flags >> i) & 1;
 		if (!page_flag_names[i]) {
 			if (present)
-				fatal("unkown flag bit %d\n", i);
+				fatal("unknown flag bit %d\n", i);
 			continue;
 		}
 		buf[j++] = present ? page_flag_names[i][0] : '_';
diff --git a/Documentation/vm/slub.txt b/Documentation/vm/slub.txt
index 510917f..b37300e 100644
--- a/Documentation/vm/slub.txt
+++ b/Documentation/vm/slub.txt
@@ -245,7 +245,7 @@
 has the length of 8 characters. However, a 8 character string needs a
 terminating 0. That zero has overwritten the first byte of the Redzone field.
 After reporting the details of the issue encountered the FIX SLUB message
-tell us that SLUB has restored the Redzone to its proper value and then
+tells us that SLUB has restored the Redzone to its proper value and then
 system operations continue.
 
 Emergency operations:
diff --git a/MAINTAINERS b/MAINTAINERS
index 04390e9..93a0743 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -327,6 +327,13 @@
 S:	Maintained
 F:	drivers/macintosh/therm_adt746x.c
 
+ADT7475 HARDWARE MONITOR DRIVER
+M:	Jean Delvare <khali@linux-fr.org>
+L:	lm-sensors@lm-sensors.org
+S:	Maintained
+F:	Documentation/hwmon/adt7475
+F:	drivers/hwmon/adt7475.c
+
 ADVANSYS SCSI DRIVER
 M:	Matthew Wilcox <matthew@wil.cx>
 L:	linux-scsi@vger.kernel.org
@@ -486,13 +493,6 @@
 F:	drivers/net/appletalk/
 F:	net/appletalk/
 
-APPLETOUCH TOUCHPAD DRIVER
-M:	Johannes Berg <johannes@sipsolutions.net>
-L:	linux-input@vger.kernel.org
-S:	Maintained
-F:	Documentation/input/appletouch.txt
-F:	drivers/input/mouse/appletouch.c
-
 ARC FRAMEBUFFER DRIVER
 M:	Jaya Kumar <jayalk@intworks.biz>
 S:	Maintained
@@ -2423,7 +2423,9 @@
 L:	lm-sensors@lm-sensors.org
 W:	http://www.lm-sensors.org/
 S:	Orphan
+F:	Documentation/hwmon/
 F:	drivers/hwmon/
+F:	include/linux/hwmon*.h
 
 HARDWARE RANDOM NUMBER GENERATOR CORE
 M:	Matt Mackall <mpm@selenic.com>
@@ -3139,6 +3141,7 @@
 F:	Documentation/s390/kvm.txt
 F:	arch/s390/include/asm/kvm*
 F:	arch/s390/kvm/
+F:	drivers/s390/kvm/
 
 KEXEC
 M:	Eric Biederman <ebiederm@xmission.com>
@@ -3318,6 +3321,12 @@
 F:	Documentation/hwmon/lis3lv02d
 F:	drivers/hwmon/lis3lv02d.*
 
+LM73 HARDWARE MONITOR DRIVER
+M:	Guillaume Ligneul <guillaume.ligneul@gmail.com>
+L:	lm-sensors@lm-sensors.org
+S:	Maintained
+F:	drivers/hwmon/lm73.c
+
 LM83 HARDWARE MONITOR DRIVER
 M:	Jean Delvare <khali@linux-fr.org>
 L:	lm-sensors@lm-sensors.org
@@ -3894,6 +3903,23 @@
 S:	Maintained
 F:	drivers/video/omap/
 
+OMAP DISPLAY SUBSYSTEM SUPPORT (DSS2)
+M:	Tomi Valkeinen <tomi.valkeinen@nokia.com>
+L:	linux-omap@vger.kernel.org
+L:	linux-fbdev@vger.kernel.org (moderated for non-subscribers)
+S:	Maintained
+F:	drivers/video/omap2/dss/
+F:	drivers/video/omap2/vrfb.c
+F:	drivers/video/omap2/vram.c
+F:	Documentation/arm/OMAP/DSS
+
+OMAP FRAMEBUFFER SUPPORT (FOR DSS2)
+M:	Tomi Valkeinen <tomi.valkeinen@nokia.com>
+L:	linux-omap@vger.kernel.org
+L:	linux-fbdev@vger.kernel.org (moderated for non-subscribers)
+S:	Maintained
+F:	drivers/video/omap2/omapfb/
+
 OMAP MMC SUPPORT
 M:	Jarkko Lavinen <jarkko.lavinen@nokia.com>
 L:	linux-omap@vger.kernel.org
@@ -4195,6 +4221,13 @@
 S:	Supported
 F:	drivers/scsi/pmcraid.*
 
+PMC SIERRA PM8001 DRIVER
+M:	jack_wang@usish.com
+M:	lindar_liu@usish.com
+L:	linux-scsi@vger.kernel.org
+S:	Supported
+F:	drivers/scsi/pm8001/
+
 POSIX CLOCKS and TIMERS
 M:	Thomas Gleixner <tglx@linutronix.de>
 S:	Supported
@@ -4553,6 +4586,7 @@
 W:	http://www.ibm.com/developerworks/linux/linux390/
 S:	Supported
 F:	arch/s390/
+F:	drivers/s390/
 
 S390 NETWORK DRIVERS
 M:	Ursula Braun <ursula.braun@de.ibm.com>
@@ -4568,6 +4602,7 @@
 M:	Ralph Wuerthner <ralph.wuerthner@de.ibm.com>
 M:	linux390@de.ibm.com
 L:	linux-s390@vger.kernel.org
+W:	http://www.ibm.com/developerworks/linux/linux390/
 S:	Supported
 F:	drivers/s390/crypto/
 
@@ -5317,7 +5352,7 @@
 F:	drivers/scsi/u14-34f.c
 
 UBI FILE SYSTEM (UBIFS)
-M:	Artem Bityutskiy <dedekind@infradead.org>
+M:	Artem Bityutskiy <dedekind1@gmail.com>
 M:	Adrian Hunter <adrian.hunter@nokia.com>
 L:	linux-mtd@lists.infradead.org
 T:	git git://git.infradead.org/ubifs-2.6.git
@@ -5368,7 +5403,7 @@
 F:	include/linux/cdrom.h
 
 UNSORTED BLOCK IMAGES (UBI)
-M:	Artem Bityutskiy <dedekind@infradead.org>
+M:	Artem Bityutskiy <dedekind1@gmail.com>
 W:	http://www.linux-mtd.infradead.org/
 L:	linux-mtd@lists.infradead.org
 T:	git git://git.infradead.org/ubi-2.6.git
@@ -5644,9 +5679,11 @@
 F:	drivers/net/wireless/rndis_wlan.c
 
 USB XHCI DRIVER
-M:	Sarah Sharp <sarah.a.sharp@intel.com>
+M:	Sarah Sharp <sarah.a.sharp@linux.intel.com>
 L:	linux-usb@vger.kernel.org
 S:	Supported
+F:	drivers/usb/host/xhci*
+F:	drivers/usb/host/pci-quirks*
 
 USB ZC0301 DRIVER
 M:	Luca Risolia <luca.risolia@studio.unibo.it>
@@ -5768,6 +5805,14 @@
 S:	Maintained
 F:	drivers/net/vmxnet3/
 
+VMware PVSCSI driver
+M:	Alok Kataria <akataria@vmware.com>
+M:	VMware PV-Drivers <pv-drivers@vmware.com>
+L:	linux-scsi@vger.kernel.org
+S:	Maintained
+F:	drivers/scsi/vmw_pvscsi.c
+F:	drivers/scsi/vmw_pvscsi.h
+
 VOLTAGE AND CURRENT REGULATOR FRAMEWORK
 M:	Liam Girdwood <lrg@slimlogic.co.uk>
 M:	Mark Brown <broonie@opensource.wolfsonmicro.com>
diff --git a/arch/alpha/include/asm/fcntl.h b/arch/alpha/include/asm/fcntl.h
index 25da001..21b1117 100644
--- a/arch/alpha/include/asm/fcntl.h
+++ b/arch/alpha/include/asm/fcntl.h
@@ -1,8 +1,6 @@
 #ifndef _ALPHA_FCNTL_H
 #define _ALPHA_FCNTL_H
 
-/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
-   located on an ext2 file system */
 #define O_CREAT		 01000	/* not fcntl */
 #define O_TRUNC		 02000	/* not fcntl */
 #define O_EXCL		 04000	/* not fcntl */
@@ -10,13 +8,28 @@
 
 #define O_NONBLOCK	 00004
 #define O_APPEND	 00010
-#define O_SYNC		040000
+#define O_DSYNC		040000	/* used to be O_SYNC, see below */
 #define O_DIRECTORY	0100000	/* must be a directory */
 #define O_NOFOLLOW	0200000 /* don't follow links */
 #define O_LARGEFILE	0400000 /* will be set by the kernel on every open */
 #define O_DIRECT	02000000 /* direct disk access - should check with OSF/1 */
 #define O_NOATIME	04000000
 #define O_CLOEXEC	010000000 /* set close_on_exec */
+/*
+ * Before Linux 2.6.32 only O_DSYNC semantics were implemented, but using
+ * the O_SYNC flag.  We continue to use the existing numerical value
+ * for O_DSYNC semantics now, but using the correct symbolic name for it.
+ * This new value is used to request true Posix O_SYNC semantics.  It is
+ * defined in this strange way to make sure applications compiled against
+ * new headers get at least O_DSYNC semantics on older kernels.
+ *
+ * This has the nice side-effect that we can simply test for O_DSYNC
+ * wherever we do not care if O_DSYNC or O_SYNC is used.
+ *
+ * Note: __O_SYNC must never be used directly.
+ */
+#define __O_SYNC	020000000
+#define O_SYNC		(__O_SYNC|O_DSYNC)
 
 #define F_GETLK		7
 #define F_SETLK		8
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 9a3334a..62619f2 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -178,25 +178,18 @@
 		unsigned long, prot, unsigned long, flags, unsigned long, fd,
 		unsigned long, off)
 {
-	struct file *file = NULL;
-	unsigned long ret = -EBADF;
+	unsigned long ret = -EINVAL;
 
 #if 0
 	if (flags & (_MAP_HASSEMAPHORE | _MAP_INHERIT | _MAP_UNALIGNED))
 		printk("%s: unimplemented OSF mmap flags %04lx\n", 
 			current->comm, flags);
 #endif
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	down_write(&current->mm->mmap_sem);
-	ret = do_mmap(file, addr, len, prot, flags, off);
-	up_write(&current->mm->mmap_sem);
-	if (file)
-		fput(file);
+	if ((off + PAGE_ALIGN(len)) < off)
+		goto out;
+	if (off & ~PAGE_MASK)
+		goto out;
+	ret = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
  out:
 	return ret;
 }
diff --git a/arch/alpha/mm/numa.c b/arch/alpha/mm/numa.c
index 10b4035..7b2c56d 100644
--- a/arch/alpha/mm/numa.c
+++ b/arch/alpha/mm/numa.c
@@ -197,7 +197,7 @@
 	}
 
 	if (bootmap_start == -1)
-		panic("couldn't find a contigous place for the bootmap");
+		panic("couldn't find a contiguous place for the bootmap");
 
 	/* Allocate the bootmap and mark the whole MM as reserved.  */
 	bootmap_size = init_bootmem_node(NODE_DATA(nid), bootmap_start,
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
index 7713a08..37bda5f 100644
--- a/arch/arm/common/scoop.c
+++ b/arch/arm/common/scoop.c
@@ -82,7 +82,7 @@
 {
 	struct scoop_dev *sdev = container_of(chip, struct scoop_dev, gpio);
 
-	/* XXX: I'm usure,  but it seems so */
+	/* XXX: I'm unsure, but it seems so */
 	return ioread16(sdev->base + SCOOP_GPRR) & (1 << (offset + 1));
 }
 
diff --git a/arch/arm/configs/da830_omapl137_defconfig b/arch/arm/configs/da830_omapl137_defconfig
deleted file mode 100644
index 7c8e38f..0000000
--- a/arch/arm/configs/da830_omapl137_defconfig
+++ /dev/null
@@ -1,1254 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc2-davinci1
-# Wed May 13 15:33:29 2009
-#
-CONFIG_ARM=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_GENERIC_GPIO=y
-CONFIG_GENERIC_TIME=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_MMU=y
-# CONFIG_NO_IOPORT is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_HAVE_LATENCYTOP_SUPPORT=y
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_ZONE_DMA=y
-CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_VECTORS_BASE=0xffff0000
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_POSIX_MQUEUE_SYSCTL=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_AUDIT is not set
-
-#
-# RCU Subsystem
-#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
-# CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
-# CONFIG_RELAY is not set
-# CONFIG_NAMESPACES is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_RD_GZIP=y
-# CONFIG_RD_BZIP2 is not set
-# CONFIG_RD_LZMA is not set
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL=y
-CONFIG_ANON_INODES=y
-CONFIG_EMBEDDED=y
-CONFIG_UID16=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
-CONFIG_EVENTFD=y
-CONFIG_SHMEM=y
-CONFIG_AIO=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLUB_DEBUG=y
-CONFIG_COMPAT_BRK=y
-# CONFIG_SLAB is not set
-CONFIG_SLUB=y
-# CONFIG_SLOB is not set
-# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
-CONFIG_HAVE_OPROFILE=y
-# CONFIG_KPROBES is not set
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-CONFIG_HAVE_CLK=y
-# CONFIG_SLOW_WORK is not set
-CONFIG_HAVE_GENERIC_DMA_COHERENT=y
-CONFIG_SLABINFO=y
-CONFIG_RT_MUTEXES=y
-CONFIG_BASE_SMALL=0
-CONFIG_MODULES=y
-# CONFIG_MODULE_FORCE_LOAD is not set
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_BLK_DEV_INTEGRITY is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-# CONFIG_FREEZER is not set
-
-#
-# System Type
-#
-# CONFIG_ARCH_AAEC2000 is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_REALVIEW is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_EP93XX is not set
-# CONFIG_ARCH_GEMINI is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_NETX is not set
-# CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_IOP13XX is not set
-# CONFIG_ARCH_IOP32X is not set
-# CONFIG_ARCH_IOP33X is not set
-# CONFIG_ARCH_IXP23XX is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_KIRKWOOD is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
-# CONFIG_ARCH_LOKI is not set
-# CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_MXC is not set
-# CONFIG_ARCH_ORION5X is not set
-# CONFIG_ARCH_PNX4008 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_MMP is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_S3C64XX is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_LH7A40X is not set
-CONFIG_ARCH_DAVINCI=y
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_MSM is not set
-# CONFIG_ARCH_W90X900 is not set
-CONFIG_CP_INTC=y
-
-#
-# TI DaVinci Implementations
-#
-
-#
-# DaVinci Core Type
-#
-# CONFIG_ARCH_DAVINCI_DM644x is not set
-# CONFIG_ARCH_DAVINCI_DM646x is not set
-# CONFIG_ARCH_DAVINCI_DM355 is not set
-CONFIG_ARCH_DAVINCI_DA830=y
-
-#
-# DaVinci Board Type
-#
-CONFIG_MACH_DAVINCI_DA830_EVM=y
-CONFIG_DAVINCI_MUX=y
-# CONFIG_DAVINCI_MUX_DEBUG is not set
-# CONFIG_DAVINCI_MUX_WARNINGS is not set
-CONFIG_DAVINCI_RESET_CLOCKS=y
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_ARM926T=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV5TJ=y
-CONFIG_CPU_PABRT_NOIFAR=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_COPY_V4WB=y
-CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-
-#
-# Processor Features
-#
-CONFIG_ARM_THUMB=y
-# CONFIG_CPU_ICACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_DISABLE is not set
-CONFIG_CPU_DCACHE_WRITETHROUGH=y
-# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-# CONFIG_OUTER_CACHE is not set
-CONFIG_COMMON_CLKDEV=y
-
-#
-# Bus support
-#
-# CONFIG_PCI_SYSCALL is not set
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_PCCARD is not set
-
-#
-# Kernel Features
-#
-CONFIG_TICK_ONESHOT=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-CONFIG_VMSPLIT_3G=y
-# CONFIG_VMSPLIT_2G is not set
-# CONFIG_VMSPLIT_1G is not set
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PREEMPT=y
-CONFIG_HZ=100
-CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-CONFIG_ARCH_FLATMEM_HAS_HOLES=y
-# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
-# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
-# CONFIG_HIGHMEM is not set
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4096
-# CONFIG_PHYS_ADDR_T_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
-CONFIG_BOUNCE=y
-CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
-CONFIG_LEDS=y
-# CONFIG_LEDS_CPU is not set
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE=""
-# CONFIG_XIP_KERNEL is not set
-# CONFIG_KEXEC is not set
-
-#
-# CPU Power Management
-#
-# CONFIG_CPU_IDLE is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-# CONFIG_VFP is not set
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_HAVE_AOUT=y
-# CONFIG_BINFMT_AOUT is not set
-# CONFIG_BINFMT_MISC is not set
-
-#
-# Power management options
-#
-# CONFIG_PM is not set
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_INET_XFRM_MODE_TRANSPORT=y
-CONFIG_INET_XFRM_MODE_TUNNEL=y
-CONFIG_INET_XFRM_MODE_BEET=y
-# CONFIG_INET_LRO is not set
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_DEFAULT_TCP_CONG="cubic"
-# CONFIG_TCP_MD5SIG is not set
-CONFIG_IPV6=m
-# CONFIG_IPV6_PRIVACY is not set
-# CONFIG_IPV6_ROUTER_PREF is not set
-# CONFIG_IPV6_OPTIMISTIC_DAD is not set
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_IPCOMP is not set
-# CONFIG_IPV6_MIP6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
-CONFIG_INET6_XFRM_MODE_TRANSPORT=m
-CONFIG_INET6_XFRM_MODE_TUNNEL=m
-CONFIG_INET6_XFRM_MODE_BEET=m
-# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
-CONFIG_IPV6_SIT=m
-CONFIG_IPV6_NDISC_NODETYPE=y
-# CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPV6_MULTIPLE_TABLES is not set
-# CONFIG_IPV6_MROUTE is not set
-# CONFIG_NETWORK_SECMARK is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_NETFILTER_ADVANCED=y
-
-#
-# Core Netfilter Configuration
-#
-# CONFIG_NETFILTER_NETLINK_QUEUE is not set
-# CONFIG_NETFILTER_NETLINK_LOG is not set
-# CONFIG_NF_CONNTRACK is not set
-# CONFIG_NETFILTER_XTABLES is not set
-# CONFIG_IP_VS is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_NF_DEFRAG_IPV4 is not set
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_IP6_NF_QUEUE is not set
-# CONFIG_IP6_NF_IPTABLES is not set
-# CONFIG_IP_DCCP is not set
-# CONFIG_IP_SCTP is not set
-# CONFIG_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_NET_DSA is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_PHONET is not set
-# CONFIG_NET_SCHED is not set
-# CONFIG_DCB is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_CAN is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-# CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
-# CONFIG_WIMAX is not set
-# CONFIG_RFKILL is not set
-# CONFIG_NET_9P is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-# CONFIG_DEBUG_DRIVER is not set
-# CONFIG_DEBUG_DEVRES is not set
-# CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_CONNECTOR is not set
-# CONFIG_MTD is not set
-# CONFIG_PARPORT is not set
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=m
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=1
-CONFIG_BLK_DEV_RAM_SIZE=32768
-# CONFIG_BLK_DEV_XIP is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH is not set
-CONFIG_MISC_DEVICES=y
-# CONFIG_ICS932S401 is not set
-# CONFIG_ENCLOSURE_SERVICES is not set
-# CONFIG_ISL29003 is not set
-# CONFIG_C2PORT is not set
-
-#
-# EEPROM support
-#
-CONFIG_EEPROM_AT24=y
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_EEPROM_93CX6 is not set
-CONFIG_HAVE_IDE=y
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-# CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=m
-CONFIG_SCSI_DMA=y
-# CONFIG_SCSI_TGT is not set
-# CONFIG_SCSI_NETLINK is not set
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=m
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-# CONFIG_SCSI_SCAN_ASYNC is not set
-CONFIG_SCSI_WAIT_SCAN=m
-
-#
-# SCSI Transports
-#
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_LIBSAS is not set
-# CONFIG_SCSI_SRP_ATTRS is not set
-CONFIG_SCSI_LOWLEVEL=y
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_LIBFC is not set
-# CONFIG_LIBFCOE is not set
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_DH is not set
-# CONFIG_SCSI_OSD_INITIATOR is not set
-# CONFIG_ATA is not set
-# CONFIG_MD is not set
-CONFIG_NETDEVICES=y
-CONFIG_COMPAT_NET_DEV_OPS=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_MACVLAN is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
-# CONFIG_VETH is not set
-CONFIG_PHYLIB=y
-
-#
-# MII PHY device drivers
-#
-# CONFIG_MARVELL_PHY is not set
-# CONFIG_DAVICOM_PHY is not set
-# CONFIG_QSEMI_PHY is not set
-CONFIG_LXT_PHY=y
-# CONFIG_CICADA_PHY is not set
-# CONFIG_VITESSE_PHY is not set
-# CONFIG_SMSC_PHY is not set
-# CONFIG_BROADCOM_PHY is not set
-# CONFIG_ICPLUS_PHY is not set
-# CONFIG_REALTEK_PHY is not set
-# CONFIG_NATIONAL_PHY is not set
-# CONFIG_STE10XP is not set
-CONFIG_LSI_ET1011C_PHY=y
-# CONFIG_FIXED_PHY is not set
-# CONFIG_MDIO_BITBANG is not set
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-# CONFIG_AX88796 is not set
-# CONFIG_SMC91X is not set
-CONFIG_TI_DAVINCI_EMAC=y
-# CONFIG_DM9000 is not set
-# CONFIG_ETHOC is not set
-# CONFIG_SMC911X is not set
-# CONFIG_SMSC911X is not set
-# CONFIG_DNET is not set
-# CONFIG_IBM_NEW_EMAC_ZMII is not set
-# CONFIG_IBM_NEW_EMAC_RGMII is not set
-# CONFIG_IBM_NEW_EMAC_TAH is not set
-# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
-# CONFIG_B44 is not set
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-
-#
-# Enable WiMAX (Networking options) to see the WiMAX drivers
-#
-# CONFIG_WAN is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-CONFIG_NETCONSOLE=y
-# CONFIG_NETCONSOLE_DYNAMIC is not set
-CONFIG_NETPOLL=y
-CONFIG_NETPOLL_TRAP=y
-CONFIG_NET_POLL_CONTROLLER=y
-# CONFIG_ISDN is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-# CONFIG_INPUT_POLLDEV is not set
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=m
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-CONFIG_INPUT_EVDEV=m
-CONFIG_INPUT_EVBUG=m
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=m
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-CONFIG_KEYBOARD_XTKBD=m
-# CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_STOWAWAY is not set
-CONFIG_KEYBOARD_GPIO=y
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TABLET is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
-# CONFIG_TOUCHSCREEN_AD7879 is not set
-# CONFIG_TOUCHSCREEN_FUJITSU is not set
-# CONFIG_TOUCHSCREEN_GUNZE is not set
-# CONFIG_TOUCHSCREEN_ELO is not set
-# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
-# CONFIG_TOUCHSCREEN_MTOUCH is not set
-# CONFIG_TOUCHSCREEN_INEXIO is not set
-# CONFIG_TOUCHSCREEN_MK712 is not set
-# CONFIG_TOUCHSCREEN_PENMOUNT is not set
-# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
-# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
-# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
-# CONFIG_TOUCHSCREEN_TSC2007 is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-CONFIG_SERIO_SERPORT=y
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-# CONFIG_VT_CONSOLE is not set
-CONFIG_HW_CONSOLE=y
-# CONFIG_VT_HW_CONSOLE_BINDING is not set
-CONFIG_DEVKMEM=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=3
-CONFIG_SERIAL_8250_RUNTIME_UARTS=3
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=m
-# CONFIG_HW_RANDOM_TIMERIOMEM is not set
-# CONFIG_R3964 is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_TCG_TPM is not set
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_HELPER_AUTO=y
-
-#
-# I2C Hardware Bus support
-#
-
-#
-# I2C system bus drivers (mostly embedded / system-on-chip)
-#
-CONFIG_I2C_DAVINCI=y
-# CONFIG_I2C_GPIO is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_SIMTEC is not set
-
-#
-# External I2C/SMBus adapter drivers
-#
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_TAOS_EVM is not set
-
-#
-# Other I2C/SMBus bus drivers
-#
-# CONFIG_I2C_PCA_PLATFORM is not set
-# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_MAX6875 is not set
-# CONFIG_SENSORS_TSL2550 is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-# CONFIG_SPI is not set
-CONFIG_ARCH_REQUIRE_GPIOLIB=y
-CONFIG_GPIOLIB=y
-# CONFIG_DEBUG_GPIO is not set
-# CONFIG_GPIO_SYSFS is not set
-
-#
-# Memory mapped GPIO expanders:
-#
-
-#
-# I2C GPIO expanders:
-#
-# CONFIG_GPIO_MAX732X is not set
-# CONFIG_GPIO_PCA953X is not set
-CONFIG_GPIO_PCF857X=m
-
-#
-# PCI GPIO expanders:
-#
-
-#
-# SPI GPIO expanders:
-#
-# CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON is not set
-# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-
-#
-# Watchdog Device Drivers
-#
-# CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_DAVINCI_WATCHDOG is not set
-CONFIG_SSB_POSSIBLE=y
-
-#
-# Sonics Silicon Backplane
-#
-# CONFIG_SSB is not set
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_CORE is not set
-# CONFIG_MFD_SM501 is not set
-# CONFIG_MFD_ASIC3 is not set
-# CONFIG_HTC_EGPIO is not set
-# CONFIG_HTC_PASIC3 is not set
-# CONFIG_TPS65010 is not set
-# CONFIG_TWL4030_CORE is not set
-# CONFIG_MFD_TMIO is not set
-# CONFIG_MFD_T7L66XB is not set
-# CONFIG_MFD_TC6387XB is not set
-# CONFIG_MFD_TC6393XB is not set
-# CONFIG_PMIC_DA903X is not set
-# CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_WM8350_I2C is not set
-# CONFIG_MFD_PCF50633 is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
-
-#
-# Graphics support
-#
-# CONFIG_VGASTATE is not set
-# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Display device support
-#
-# CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_SOUND=m
-# CONFIG_SOUND_OSS_CORE is not set
-CONFIG_SND=m
-CONFIG_SND_TIMER=m
-CONFIG_SND_PCM=m
-CONFIG_SND_JACK=y
-# CONFIG_SND_SEQUENCER is not set
-# CONFIG_SND_MIXER_OSS is not set
-# CONFIG_SND_PCM_OSS is not set
-# CONFIG_SND_HRTIMER is not set
-# CONFIG_SND_DYNAMIC_MINORS is not set
-CONFIG_SND_SUPPORT_OLD_API=y
-CONFIG_SND_VERBOSE_PROCFS=y
-# CONFIG_SND_VERBOSE_PRINTK is not set
-# CONFIG_SND_DEBUG is not set
-CONFIG_SND_DRIVERS=y
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
-CONFIG_SND_ARM=y
-CONFIG_SND_SOC=m
-CONFIG_SND_DAVINCI_SOC=m
-CONFIG_SND_SOC_I2C_AND_SPI=m
-# CONFIG_SND_SOC_ALL_CODECS is not set
-# CONFIG_SOUND_PRIME is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_USB_MUSB_HOST is not set
-# CONFIG_USB_MUSB_PERIPHERAL is not set
-# CONFIG_USB_MUSB_OTG is not set
-# CONFIG_USB_GADGET_MUSB_HDRC is not set
-# CONFIG_USB_GADGET_AT91 is not set
-# CONFIG_USB_GADGET_ATMEL_USBA is not set
-# CONFIG_USB_GADGET_FSL_USB2 is not set
-# CONFIG_USB_GADGET_LH7A40X is not set
-# CONFIG_USB_GADGET_OMAP is not set
-# CONFIG_USB_GADGET_PXA25X is not set
-# CONFIG_USB_GADGET_PXA27X is not set
-# CONFIG_USB_GADGET_S3C2410 is not set
-# CONFIG_USB_GADGET_IMX is not set
-# CONFIG_USB_GADGET_M66592 is not set
-# CONFIG_USB_GADGET_AMD5536UDC is not set
-# CONFIG_USB_GADGET_FSL_QE is not set
-# CONFIG_USB_GADGET_CI13XXX is not set
-# CONFIG_USB_GADGET_NET2280 is not set
-# CONFIG_USB_GADGET_GOKU is not set
-# CONFIG_USB_GADGET_DUMMY_HCD is not set
-# CONFIG_USB_ZERO is not set
-# CONFIG_USB_ETH is not set
-# CONFIG_USB_GADGETFS is not set
-# CONFIG_USB_FILE_STORAGE is not set
-# CONFIG_USB_G_SERIAL is not set
-# CONFIG_USB_MIDI_GADGET is not set
-# CONFIG_USB_G_PRINTER is not set
-# CONFIG_USB_CDC_COMPOSITE is not set
-# CONFIG_MMC is not set
-# CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY is not set
-# CONFIG_NEW_LEDS is not set
-CONFIG_RTC_LIB=y
-# CONFIG_RTC_CLASS is not set
-# CONFIG_DMADEVICES is not set
-# CONFIG_AUXDISPLAY is not set
-# CONFIG_REGULATOR is not set
-# CONFIG_UIO is not set
-# CONFIG_STAGING is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-# CONFIG_EXT3_FS_SECURITY is not set
-# CONFIG_EXT4_FS is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
-CONFIG_XFS_FS=m
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_POSIX_ACL is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_DEBUG is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_BTRFS_FS is not set
-CONFIG_DNOTIFY=y
-CONFIG_INOTIFY=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=m
-# CONFIG_FUSE_FS is not set
-
-#
-# Caches
-#
-# CONFIG_FSCACHE is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_PROC_PAGE_MONITOR=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_POSIX_ACL is not set
-# CONFIG_HUGETLB_PAGE is not set
-# CONFIG_CONFIGFS_FS is not set
-CONFIG_MISC_FILESYSTEMS=y
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-CONFIG_CRAMFS=y
-# CONFIG_SQUASHFS is not set
-# CONFIG_VXFS_FS is not set
-CONFIG_MINIX_FS=m
-# CONFIG_OMFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
-CONFIG_NETWORK_FILESYSTEMS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
-# CONFIG_NFS_V4 is not set
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V3_ACL is not set
-# CONFIG_NFSD_V4 is not set
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_KARMA_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
-# CONFIG_SYSV68_PARTITION is not set
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-CONFIG_NLS_UTF8=m
-# CONFIG_DLM is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_WARN_DEPRECATED=y
-CONFIG_ENABLE_MUST_CHECK=y
-CONFIG_FRAME_WARN=1024
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-CONFIG_DEBUG_FS=y
-# CONFIG_HEADERS_CHECK is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SHIRQ is not set
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
-CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
-CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
-CONFIG_SCHED_DEBUG=y
-# CONFIG_SCHEDSTATS is not set
-CONFIG_TIMER_STATS=y
-# CONFIG_DEBUG_OBJECTS is not set
-# CONFIG_SLUB_DEBUG_ON is not set
-# CONFIG_SLUB_STATS is not set
-CONFIG_DEBUG_PREEMPT=y
-CONFIG_DEBUG_RT_MUTEXES=y
-CONFIG_DEBUG_PI_LIST=y
-# CONFIG_RT_MUTEX_TESTER is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_LOCK_ALLOC is not set
-# CONFIG_PROVE_LOCKING is not set
-# CONFIG_LOCK_STAT is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-# CONFIG_DEBUG_KOBJECT is not set
-CONFIG_DEBUG_BUGVERBOSE=y
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_VM is not set
-# CONFIG_DEBUG_WRITECOUNT is not set
-# CONFIG_DEBUG_MEMORY_INIT is not set
-# CONFIG_DEBUG_LIST is not set
-# CONFIG_DEBUG_SG is not set
-# CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
-# CONFIG_RCU_TORTURE_TEST is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-# CONFIG_BACKTRACE_SELF_TEST is not set
-# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
-# CONFIG_FAULT_INJECTION is not set
-# CONFIG_LATENCYTOP is not set
-# CONFIG_SYSCTL_SYSCALL_CHECK is not set
-# CONFIG_PAGE_POISONING is not set
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
-# CONFIG_FUNCTION_TRACER is not set
-# CONFIG_IRQSOFF_TRACER is not set
-# CONFIG_PREEMPT_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
-# CONFIG_STACK_TRACER is not set
-# CONFIG_KMEMTRACE is not set
-# CONFIG_WORKQUEUE_TRACER is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_DYNAMIC_DEBUG is not set
-# CONFIG_SAMPLES is not set
-CONFIG_HAVE_ARCH_KGDB=y
-# CONFIG_KGDB is not set
-CONFIG_ARM_UNWIND=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-# CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_LL is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_CRYPTO=y
-
-#
-# Crypto core or helper
-#
-# CONFIG_CRYPTO_FIPS is not set
-# CONFIG_CRYPTO_MANAGER is not set
-# CONFIG_CRYPTO_MANAGER2 is not set
-# CONFIG_CRYPTO_GF128MUL is not set
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-# CONFIG_CRYPTO_AUTHENC is not set
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Authenticated Encryption with Associated Data
-#
-# CONFIG_CRYPTO_CCM is not set
-# CONFIG_CRYPTO_GCM is not set
-# CONFIG_CRYPTO_SEQIV is not set
-
-#
-# Block modes
-#
-# CONFIG_CRYPTO_CBC is not set
-# CONFIG_CRYPTO_CTR is not set
-# CONFIG_CRYPTO_CTS is not set
-# CONFIG_CRYPTO_ECB is not set
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_PCBC is not set
-# CONFIG_CRYPTO_XTS is not set
-
-#
-# Hash modes
-#
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_XCBC is not set
-
-#
-# Digest
-#
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_RMD128 is not set
-# CONFIG_CRYPTO_RMD160 is not set
-# CONFIG_CRYPTO_RMD256 is not set
-# CONFIG_CRYPTO_RMD320 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_WP512 is not set
-
-#
-# Ciphers
-#
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_SALSA20 is not set
-# CONFIG_CRYPTO_SEED is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-
-#
-# Compression
-#
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_ZLIB is not set
-# CONFIG_CRYPTO_LZO is not set
-
-#
-# Random Number Generation
-#
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-# CONFIG_CRYPTO_HW is not set
-# CONFIG_BINARY_PRINTF is not set
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-CONFIG_GENERIC_FIND_LAST_BIT=y
-CONFIG_CRC_CCITT=m
-# CONFIG_CRC16 is not set
-CONFIG_CRC_T10DIF=m
-# CONFIG_CRC_ITU_T is not set
-CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_DECOMPRESS_GZIP=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
-CONFIG_NLATTR=y
diff --git a/arch/arm/configs/da850_omapl138_defconfig b/arch/arm/configs/da850_omapl138_defconfig
deleted file mode 100644
index 842a70b..0000000
--- a/arch/arm/configs/da850_omapl138_defconfig
+++ /dev/null
@@ -1,1229 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-davinci1
-# Mon Jun 29 07:54:15 2009
-#
-CONFIG_ARM=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_GENERIC_GPIO=y
-CONFIG_GENERIC_TIME=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_MMU=y
-# CONFIG_NO_IOPORT is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_HAVE_LATENCYTOP_SUPPORT=y
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_ZONE_DMA=y
-CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_VECTORS_BASE=0xffff0000
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_POSIX_MQUEUE_SYSCTL=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_AUDIT is not set
-
-#
-# RCU Subsystem
-#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
-# CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
-# CONFIG_RELAY is not set
-# CONFIG_NAMESPACES is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_RD_GZIP=y
-# CONFIG_RD_BZIP2 is not set
-# CONFIG_RD_LZMA is not set
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL=y
-CONFIG_ANON_INODES=y
-CONFIG_EMBEDDED=y
-CONFIG_UID16=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
-CONFIG_EVENTFD=y
-CONFIG_SHMEM=y
-CONFIG_AIO=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLUB_DEBUG=y
-CONFIG_COMPAT_BRK=y
-# CONFIG_SLAB is not set
-CONFIG_SLUB=y
-# CONFIG_SLOB is not set
-# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
-CONFIG_HAVE_OPROFILE=y
-# CONFIG_KPROBES is not set
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-CONFIG_HAVE_CLK=y
-# CONFIG_SLOW_WORK is not set
-CONFIG_HAVE_GENERIC_DMA_COHERENT=y
-CONFIG_SLABINFO=y
-CONFIG_RT_MUTEXES=y
-CONFIG_BASE_SMALL=0
-CONFIG_MODULES=y
-# CONFIG_MODULE_FORCE_LOAD is not set
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_BLK_DEV_INTEGRITY is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-# CONFIG_FREEZER is not set
-
-#
-# System Type
-#
-# CONFIG_ARCH_AAEC2000 is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_REALVIEW is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_EP93XX is not set
-# CONFIG_ARCH_GEMINI is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_NETX is not set
-# CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_IOP13XX is not set
-# CONFIG_ARCH_IOP32X is not set
-# CONFIG_ARCH_IOP33X is not set
-# CONFIG_ARCH_IXP23XX is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_KIRKWOOD is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
-# CONFIG_ARCH_LOKI is not set
-# CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_MXC is not set
-# CONFIG_ARCH_ORION5X is not set
-# CONFIG_ARCH_PNX4008 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_MMP is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_S3C64XX is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_LH7A40X is not set
-CONFIG_ARCH_DAVINCI=y
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_MSM is not set
-# CONFIG_ARCH_W90X900 is not set
-CONFIG_CP_INTC=y
-
-#
-# TI DaVinci Implementations
-#
-
-#
-# DaVinci Core Type
-#
-# CONFIG_ARCH_DAVINCI_DM644x is not set
-# CONFIG_ARCH_DAVINCI_DM355 is not set
-# CONFIG_ARCH_DAVINCI_DM646x is not set
-# CONFIG_ARCH_DAVINCI_DA830 is not set
-CONFIG_ARCH_DAVINCI_DA850=y
-CONFIG_ARCH_DAVINCI_DA8XX=y
-# CONFIG_ARCH_DAVINCI_DM365 is not set
-
-#
-# DaVinci Board Type
-#
-CONFIG_MACH_DAVINCI_DA850_EVM=y
-CONFIG_DAVINCI_MUX=y
-# CONFIG_DAVINCI_MUX_DEBUG is not set
-# CONFIG_DAVINCI_MUX_WARNINGS is not set
-CONFIG_DAVINCI_RESET_CLOCKS=y
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_ARM926T=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV5TJ=y
-CONFIG_CPU_PABRT_NOIFAR=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_COPY_V4WB=y
-CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-
-#
-# Processor Features
-#
-CONFIG_ARM_THUMB=y
-# CONFIG_CPU_ICACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-# CONFIG_OUTER_CACHE is not set
-CONFIG_COMMON_CLKDEV=y
-
-#
-# Bus support
-#
-# CONFIG_PCI_SYSCALL is not set
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_PCCARD is not set
-
-#
-# Kernel Features
-#
-CONFIG_TICK_ONESHOT=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-CONFIG_VMSPLIT_3G=y
-# CONFIG_VMSPLIT_2G is not set
-# CONFIG_VMSPLIT_1G is not set
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PREEMPT=y
-CONFIG_HZ=100
-CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-# CONFIG_ARCH_HAS_HOLES_MEMORYMODEL is not set
-# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
-# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
-# CONFIG_HIGHMEM is not set
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4096
-# CONFIG_PHYS_ADDR_T_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
-CONFIG_BOUNCE=y
-CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
-CONFIG_LEDS=y
-# CONFIG_LEDS_CPU is not set
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE=""
-# CONFIG_XIP_KERNEL is not set
-# CONFIG_KEXEC is not set
-
-#
-# CPU Power Management
-#
-# CONFIG_CPU_IDLE is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-# CONFIG_VFP is not set
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_HAVE_AOUT=y
-# CONFIG_BINFMT_AOUT is not set
-# CONFIG_BINFMT_MISC is not set
-
-#
-# Power management options
-#
-# CONFIG_PM is not set
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_INET_XFRM_MODE_TRANSPORT=y
-CONFIG_INET_XFRM_MODE_TUNNEL=y
-CONFIG_INET_XFRM_MODE_BEET=y
-# CONFIG_INET_LRO is not set
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_DEFAULT_TCP_CONG="cubic"
-# CONFIG_TCP_MD5SIG is not set
-CONFIG_IPV6=m
-# CONFIG_IPV6_PRIVACY is not set
-# CONFIG_IPV6_ROUTER_PREF is not set
-# CONFIG_IPV6_OPTIMISTIC_DAD is not set
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_IPCOMP is not set
-# CONFIG_IPV6_MIP6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
-CONFIG_INET6_XFRM_MODE_TRANSPORT=m
-CONFIG_INET6_XFRM_MODE_TUNNEL=m
-CONFIG_INET6_XFRM_MODE_BEET=m
-# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
-CONFIG_IPV6_SIT=m
-CONFIG_IPV6_NDISC_NODETYPE=y
-# CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPV6_MULTIPLE_TABLES is not set
-# CONFIG_IPV6_MROUTE is not set
-# CONFIG_NETWORK_SECMARK is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_NETFILTER_ADVANCED=y
-
-#
-# Core Netfilter Configuration
-#
-# CONFIG_NETFILTER_NETLINK_QUEUE is not set
-# CONFIG_NETFILTER_NETLINK_LOG is not set
-# CONFIG_NF_CONNTRACK is not set
-# CONFIG_NETFILTER_XTABLES is not set
-# CONFIG_IP_VS is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_NF_DEFRAG_IPV4 is not set
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_IP6_NF_QUEUE is not set
-# CONFIG_IP6_NF_IPTABLES is not set
-# CONFIG_IP_DCCP is not set
-# CONFIG_IP_SCTP is not set
-# CONFIG_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_NET_DSA is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_PHONET is not set
-# CONFIG_NET_SCHED is not set
-# CONFIG_DCB is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_CAN is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-# CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
-# CONFIG_WIMAX is not set
-# CONFIG_RFKILL is not set
-# CONFIG_NET_9P is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-# CONFIG_DEBUG_DRIVER is not set
-# CONFIG_DEBUG_DEVRES is not set
-# CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_CONNECTOR is not set
-# CONFIG_MTD is not set
-# CONFIG_PARPORT is not set
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=m
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=1
-CONFIG_BLK_DEV_RAM_SIZE=32768
-# CONFIG_BLK_DEV_XIP is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH is not set
-CONFIG_MISC_DEVICES=y
-# CONFIG_ICS932S401 is not set
-# CONFIG_ENCLOSURE_SERVICES is not set
-# CONFIG_ISL29003 is not set
-# CONFIG_C2PORT is not set
-
-#
-# EEPROM support
-#
-CONFIG_EEPROM_AT24=y
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_EEPROM_93CX6 is not set
-CONFIG_HAVE_IDE=y
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-# CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=m
-CONFIG_SCSI_DMA=y
-# CONFIG_SCSI_TGT is not set
-# CONFIG_SCSI_NETLINK is not set
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=m
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-# CONFIG_SCSI_SCAN_ASYNC is not set
-CONFIG_SCSI_WAIT_SCAN=m
-
-#
-# SCSI Transports
-#
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_LIBSAS is not set
-# CONFIG_SCSI_SRP_ATTRS is not set
-CONFIG_SCSI_LOWLEVEL=y
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_LIBFC is not set
-# CONFIG_LIBFCOE is not set
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_DH is not set
-# CONFIG_SCSI_OSD_INITIATOR is not set
-# CONFIG_ATA is not set
-# CONFIG_MD is not set
-CONFIG_NETDEVICES=y
-CONFIG_COMPAT_NET_DEV_OPS=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_MACVLAN is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
-# CONFIG_VETH is not set
-CONFIG_PHYLIB=y
-
-#
-# MII PHY device drivers
-#
-# CONFIG_MARVELL_PHY is not set
-# CONFIG_DAVICOM_PHY is not set
-# CONFIG_QSEMI_PHY is not set
-CONFIG_LXT_PHY=y
-# CONFIG_CICADA_PHY is not set
-# CONFIG_VITESSE_PHY is not set
-# CONFIG_SMSC_PHY is not set
-# CONFIG_BROADCOM_PHY is not set
-# CONFIG_ICPLUS_PHY is not set
-# CONFIG_REALTEK_PHY is not set
-# CONFIG_NATIONAL_PHY is not set
-# CONFIG_STE10XP is not set
-CONFIG_LSI_ET1011C_PHY=y
-# CONFIG_FIXED_PHY is not set
-# CONFIG_MDIO_BITBANG is not set
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-# CONFIG_AX88796 is not set
-# CONFIG_SMC91X is not set
-# CONFIG_TI_DAVINCI_EMAC is not set
-# CONFIG_DM9000 is not set
-# CONFIG_ETHOC is not set
-# CONFIG_SMC911X is not set
-# CONFIG_SMSC911X is not set
-# CONFIG_DNET is not set
-# CONFIG_IBM_NEW_EMAC_ZMII is not set
-# CONFIG_IBM_NEW_EMAC_RGMII is not set
-# CONFIG_IBM_NEW_EMAC_TAH is not set
-# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
-# CONFIG_B44 is not set
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-
-#
-# Enable WiMAX (Networking options) to see the WiMAX drivers
-#
-# CONFIG_WAN is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-CONFIG_NETCONSOLE=y
-# CONFIG_NETCONSOLE_DYNAMIC is not set
-CONFIG_NETPOLL=y
-CONFIG_NETPOLL_TRAP=y
-CONFIG_NET_POLL_CONTROLLER=y
-# CONFIG_ISDN is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-# CONFIG_INPUT_POLLDEV is not set
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=m
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-CONFIG_INPUT_EVDEV=m
-CONFIG_INPUT_EVBUG=m
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=m
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-CONFIG_KEYBOARD_XTKBD=m
-# CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_STOWAWAY is not set
-CONFIG_KEYBOARD_GPIO=y
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TABLET is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
-# CONFIG_TOUCHSCREEN_AD7879 is not set
-# CONFIG_TOUCHSCREEN_FUJITSU is not set
-# CONFIG_TOUCHSCREEN_GUNZE is not set
-# CONFIG_TOUCHSCREEN_ELO is not set
-# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
-# CONFIG_TOUCHSCREEN_MTOUCH is not set
-# CONFIG_TOUCHSCREEN_INEXIO is not set
-# CONFIG_TOUCHSCREEN_MK712 is not set
-# CONFIG_TOUCHSCREEN_PENMOUNT is not set
-# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
-# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
-# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
-# CONFIG_TOUCHSCREEN_TSC2007 is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-CONFIG_SERIO_SERPORT=y
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-# CONFIG_VT_CONSOLE is not set
-CONFIG_HW_CONSOLE=y
-# CONFIG_VT_HW_CONSOLE_BINDING is not set
-CONFIG_DEVKMEM=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=3
-CONFIG_SERIAL_8250_RUNTIME_UARTS=3
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=m
-# CONFIG_HW_RANDOM_TIMERIOMEM is not set
-# CONFIG_R3964 is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_TCG_TPM is not set
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_HELPER_AUTO=y
-
-#
-# I2C Hardware Bus support
-#
-
-#
-# I2C system bus drivers (mostly embedded / system-on-chip)
-#
-CONFIG_I2C_DAVINCI=y
-# CONFIG_I2C_GPIO is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_SIMTEC is not set
-
-#
-# External I2C/SMBus adapter drivers
-#
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_TAOS_EVM is not set
-
-#
-# Other I2C/SMBus bus drivers
-#
-# CONFIG_I2C_PCA_PLATFORM is not set
-# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_MAX6875 is not set
-# CONFIG_SENSORS_TSL2550 is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-# CONFIG_SPI is not set
-CONFIG_ARCH_REQUIRE_GPIOLIB=y
-CONFIG_GPIOLIB=y
-# CONFIG_DEBUG_GPIO is not set
-# CONFIG_GPIO_SYSFS is not set
-
-#
-# Memory mapped GPIO expanders:
-#
-
-#
-# I2C GPIO expanders:
-#
-# CONFIG_GPIO_MAX732X is not set
-# CONFIG_GPIO_PCA953X is not set
-CONFIG_GPIO_PCF857X=m
-
-#
-# PCI GPIO expanders:
-#
-
-#
-# SPI GPIO expanders:
-#
-# CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON is not set
-# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-
-#
-# Watchdog Device Drivers
-#
-# CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_DAVINCI_WATCHDOG is not set
-CONFIG_SSB_POSSIBLE=y
-
-#
-# Sonics Silicon Backplane
-#
-# CONFIG_SSB is not set
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_CORE is not set
-# CONFIG_MFD_SM501 is not set
-# CONFIG_MFD_ASIC3 is not set
-# CONFIG_HTC_EGPIO is not set
-# CONFIG_HTC_PASIC3 is not set
-# CONFIG_TPS65010 is not set
-# CONFIG_TWL4030_CORE is not set
-# CONFIG_MFD_TMIO is not set
-# CONFIG_MFD_T7L66XB is not set
-# CONFIG_MFD_TC6387XB is not set
-# CONFIG_MFD_TC6393XB is not set
-# CONFIG_PMIC_DA903X is not set
-# CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_WM8350_I2C is not set
-# CONFIG_MFD_PCF50633 is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
-
-#
-# Graphics support
-#
-# CONFIG_VGASTATE is not set
-# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Display device support
-#
-# CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_SOUND=m
-# CONFIG_SOUND_OSS_CORE is not set
-CONFIG_SND=m
-CONFIG_SND_TIMER=m
-CONFIG_SND_PCM=m
-CONFIG_SND_JACK=y
-# CONFIG_SND_SEQUENCER is not set
-# CONFIG_SND_MIXER_OSS is not set
-# CONFIG_SND_PCM_OSS is not set
-# CONFIG_SND_HRTIMER is not set
-# CONFIG_SND_DYNAMIC_MINORS is not set
-CONFIG_SND_SUPPORT_OLD_API=y
-CONFIG_SND_VERBOSE_PROCFS=y
-# CONFIG_SND_VERBOSE_PRINTK is not set
-# CONFIG_SND_DEBUG is not set
-CONFIG_SND_DRIVERS=y
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
-CONFIG_SND_ARM=y
-CONFIG_SND_SOC=m
-CONFIG_SND_DAVINCI_SOC=m
-CONFIG_SND_SOC_I2C_AND_SPI=m
-# CONFIG_SND_SOC_ALL_CODECS is not set
-# CONFIG_SOUND_PRIME is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_MMC is not set
-# CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY is not set
-# CONFIG_NEW_LEDS is not set
-CONFIG_RTC_LIB=y
-# CONFIG_RTC_CLASS is not set
-# CONFIG_DMADEVICES is not set
-# CONFIG_AUXDISPLAY is not set
-# CONFIG_REGULATOR is not set
-# CONFIG_UIO is not set
-# CONFIG_STAGING is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-# CONFIG_EXT3_FS_SECURITY is not set
-# CONFIG_EXT4_FS is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
-CONFIG_XFS_FS=m
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_POSIX_ACL is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_DEBUG is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_BTRFS_FS is not set
-CONFIG_DNOTIFY=y
-CONFIG_INOTIFY=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=m
-# CONFIG_FUSE_FS is not set
-
-#
-# Caches
-#
-# CONFIG_FSCACHE is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_PROC_PAGE_MONITOR=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_POSIX_ACL is not set
-# CONFIG_HUGETLB_PAGE is not set
-# CONFIG_CONFIGFS_FS is not set
-CONFIG_MISC_FILESYSTEMS=y
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-CONFIG_CRAMFS=y
-# CONFIG_SQUASHFS is not set
-# CONFIG_VXFS_FS is not set
-CONFIG_MINIX_FS=m
-# CONFIG_OMFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
-CONFIG_NETWORK_FILESYSTEMS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
-# CONFIG_NFS_V4 is not set
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V3_ACL is not set
-# CONFIG_NFSD_V4 is not set
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_KARMA_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
-# CONFIG_SYSV68_PARTITION is not set
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-CONFIG_NLS_UTF8=m
-# CONFIG_DLM is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_WARN_DEPRECATED=y
-CONFIG_ENABLE_MUST_CHECK=y
-CONFIG_FRAME_WARN=1024
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-CONFIG_DEBUG_FS=y
-# CONFIG_HEADERS_CHECK is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SHIRQ is not set
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
-CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
-CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
-CONFIG_SCHED_DEBUG=y
-# CONFIG_SCHEDSTATS is not set
-CONFIG_TIMER_STATS=y
-# CONFIG_DEBUG_OBJECTS is not set
-# CONFIG_SLUB_DEBUG_ON is not set
-# CONFIG_SLUB_STATS is not set
-CONFIG_DEBUG_PREEMPT=y
-CONFIG_DEBUG_RT_MUTEXES=y
-CONFIG_DEBUG_PI_LIST=y
-# CONFIG_RT_MUTEX_TESTER is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_LOCK_ALLOC is not set
-# CONFIG_PROVE_LOCKING is not set
-# CONFIG_LOCK_STAT is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-# CONFIG_DEBUG_KOBJECT is not set
-CONFIG_DEBUG_BUGVERBOSE=y
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_VM is not set
-# CONFIG_DEBUG_WRITECOUNT is not set
-# CONFIG_DEBUG_MEMORY_INIT is not set
-# CONFIG_DEBUG_LIST is not set
-# CONFIG_DEBUG_SG is not set
-# CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
-# CONFIG_RCU_TORTURE_TEST is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-# CONFIG_BACKTRACE_SELF_TEST is not set
-# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
-# CONFIG_FAULT_INJECTION is not set
-# CONFIG_LATENCYTOP is not set
-# CONFIG_SYSCTL_SYSCALL_CHECK is not set
-# CONFIG_PAGE_POISONING is not set
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
-# CONFIG_FUNCTION_TRACER is not set
-# CONFIG_IRQSOFF_TRACER is not set
-# CONFIG_PREEMPT_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
-# CONFIG_STACK_TRACER is not set
-# CONFIG_KMEMTRACE is not set
-# CONFIG_WORKQUEUE_TRACER is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_DYNAMIC_DEBUG is not set
-# CONFIG_SAMPLES is not set
-CONFIG_HAVE_ARCH_KGDB=y
-# CONFIG_KGDB is not set
-CONFIG_ARM_UNWIND=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-# CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_LL is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_CRYPTO=y
-
-#
-# Crypto core or helper
-#
-# CONFIG_CRYPTO_FIPS is not set
-# CONFIG_CRYPTO_MANAGER is not set
-# CONFIG_CRYPTO_MANAGER2 is not set
-# CONFIG_CRYPTO_GF128MUL is not set
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-# CONFIG_CRYPTO_AUTHENC is not set
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Authenticated Encryption with Associated Data
-#
-# CONFIG_CRYPTO_CCM is not set
-# CONFIG_CRYPTO_GCM is not set
-# CONFIG_CRYPTO_SEQIV is not set
-
-#
-# Block modes
-#
-# CONFIG_CRYPTO_CBC is not set
-# CONFIG_CRYPTO_CTR is not set
-# CONFIG_CRYPTO_CTS is not set
-# CONFIG_CRYPTO_ECB is not set
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_PCBC is not set
-# CONFIG_CRYPTO_XTS is not set
-
-#
-# Hash modes
-#
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_XCBC is not set
-
-#
-# Digest
-#
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_RMD128 is not set
-# CONFIG_CRYPTO_RMD160 is not set
-# CONFIG_CRYPTO_RMD256 is not set
-# CONFIG_CRYPTO_RMD320 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_WP512 is not set
-
-#
-# Ciphers
-#
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_SALSA20 is not set
-# CONFIG_CRYPTO_SEED is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-
-#
-# Compression
-#
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_ZLIB is not set
-# CONFIG_CRYPTO_LZO is not set
-
-#
-# Random Number Generation
-#
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-# CONFIG_CRYPTO_HW is not set
-# CONFIG_BINARY_PRINTF is not set
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-CONFIG_GENERIC_FIND_LAST_BIT=y
-CONFIG_CRC_CCITT=m
-# CONFIG_CRC16 is not set
-CONFIG_CRC_T10DIF=m
-# CONFIG_CRC_ITU_T is not set
-CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_DECOMPRESS_GZIP=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
-CONFIG_NLATTR=y
diff --git a/arch/arm/configs/da8xx_omapl_defconfig b/arch/arm/configs/da8xx_omapl_defconfig
new file mode 100644
index 0000000..50bd25a
--- /dev/null
+++ b/arch/arm/configs/da8xx_omapl_defconfig
@@ -0,0 +1,1332 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc5
+# Thu Oct 22 12:19:19 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+CONFIG_ARCH_DAVINCI=y
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+CONFIG_CP_INTC=y
+
+#
+# TI DaVinci Implementations
+#
+
+#
+# DaVinci Core Type
+#
+# CONFIG_ARCH_DAVINCI_DM644x is not set
+# CONFIG_ARCH_DAVINCI_DM355 is not set
+# CONFIG_ARCH_DAVINCI_DM646x is not set
+CONFIG_ARCH_DAVINCI_DA830=y
+CONFIG_ARCH_DAVINCI_DA850=y
+CONFIG_ARCH_DAVINCI_DA8XX=y
+# CONFIG_ARCH_DAVINCI_DM365 is not set
+
+#
+# DaVinci Board Type
+#
+CONFIG_MACH_DAVINCI_DA830_EVM=y
+CONFIG_DA830_UI=y
+CONFIG_DA830_UI_LCD=y
+# CONFIG_DA830_UI_NAND is not set
+CONFIG_MACH_DAVINCI_DA850_EVM=y
+CONFIG_DA850_UI_EXP=y
+CONFIG_DA850_UI_NONE=y
+# CONFIG_DA850_UI_RMII is not set
+CONFIG_DAVINCI_MUX=y
+# CONFIG_DAVINCI_MUX_DEBUG is not set
+# CONFIG_DAVINCI_MUX_WARNINGS is not set
+CONFIG_DAVINCI_RESET_CLOCKS=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+CONFIG_CPU_DCACHE_WRITETHROUGH=y
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_LEDS=y
+# CONFIG_LEDS_CPU is not set
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=m
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_NF_DEFRAG_IPV4 is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# IPv6: Netfilter Configuration
+#
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=32768
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+CONFIG_EEPROM_AT24=y
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+CONFIG_LXT_PHY=y
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+CONFIG_LSI_ET1011C_PHY=y
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+CONFIG_TI_DAVINCI_EMAC=y
+# CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+CONFIG_NETCONSOLE=y
+# CONFIG_NETCONSOLE_DYNAMIC is not set
+CONFIG_NETPOLL=y
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=m
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=m
+CONFIG_INPUT_EVBUG=m
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+CONFIG_KEYBOARD_ATKBD=m
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+CONFIG_KEYBOARD_XTKBD=m
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+# CONFIG_VT_CONSOLE is not set
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=3
+CONFIG_SERIAL_8250_RUNTIME_UARTS=3
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_DAVINCI=y
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCF857X=y
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_DAVINCI_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+CONFIG_REGULATOR_TPS6507X=y
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_DAVINCI is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_FB_DA8XX=y
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_SOUND=m
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_SOC=m
+CONFIG_SND_DAVINCI_SOC=m
+# CONFIG_SND_DA830_SOC_EVM is not set
+# CONFIG_SND_DA850_SOC_EVM is not set
+CONFIG_SND_SOC_I2C_AND_SPI=m
+# CONFIG_SND_SOC_ALL_CODECS is not set
+# CONFIG_SOUND_PRIME is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_XFS_FS=m
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_DEBUG is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+CONFIG_MINIX_FS=m
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+CONFIG_DEBUG_PREEMPT=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_PI_LIST=y
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=m
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig
index ddffe39..bd656e8 100644
--- a/arch/arm/configs/davinci_all_defconfig
+++ b/arch/arm/configs/davinci_all_defconfig
@@ -1,14 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc3-davinci1
-# Fri Jul 17 08:26:52 2009
+# Linux kernel version: 2.6.32-rc4
+# Mon Oct 12 14:13:12 2009
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -46,11 +45,12 @@
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
@@ -91,17 +91,15 @@
 CONFIG_AIO=y
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_KPROBES=y
@@ -145,6 +143,7 @@
 #
 # System Type
 #
+CONFIG_MMU=y
 # CONFIG_ARCH_AAEC2000 is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_REALVIEW is not set
@@ -159,6 +158,7 @@
 # CONFIG_ARCH_STMP3XXX is not set
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
 # CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IOP32X is not set
 # CONFIG_ARCH_IOP33X is not set
@@ -181,11 +181,13 @@
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_S3C2410 is not set
 # CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_U300 is not set
 CONFIG_ARCH_DAVINCI=y
 # CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
 CONFIG_AINTC=y
 CONFIG_ARCH_DAVINCI_DMx=y
 
@@ -208,6 +210,7 @@
 #
 CONFIG_MACH_DAVINCI_EVM=y
 CONFIG_MACH_SFFSDR=y
+CONFIG_MACH_NEUROS_OSD2=y
 CONFIG_MACH_DAVINCI_DM355_EVM=y
 CONFIG_MACH_DM355_LEOPARD=y
 CONFIG_MACH_DAVINCI_DM6467_EVM=y
@@ -224,7 +227,7 @@
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
-CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_PABRT_LEGACY=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_COPY_V4WB=y
 CONFIG_CPU_TLB_V4WBI=y
@@ -239,6 +242,7 @@
 # CONFIG_CPU_DCACHE_DISABLE is not set
 # CONFIG_CPU_DCACHE_WRITETHROUGH is not set
 # CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
 CONFIG_COMMON_CLKDEV=y
 
 #
@@ -259,6 +263,8 @@
 # CONFIG_VMSPLIT_2G is not set
 # CONFIG_VMSPLIT_1G is not set
 CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_HZ=100
 CONFIG_AEABI=y
@@ -280,6 +286,7 @@
 CONFIG_VIRT_TO_BUS=y
 CONFIG_HAVE_MLOCK=y
 CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_LEDS=y
 # CONFIG_LEDS_CPU is not set
@@ -412,6 +419,7 @@
 # CONFIG_IP6_NF_IPTABLES is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -452,6 +460,7 @@
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
@@ -461,9 +470,9 @@
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=m
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_AFS_PARTS is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -499,7 +508,7 @@
 CONFIG_MTD_CFI_I2=y
 # CONFIG_MTD_CFI_I4 is not set
 # CONFIG_MTD_CFI_I8 is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_INTELEXT=m
 CONFIG_MTD_CFI_AMDSTD=m
 # CONFIG_MTD_CFI_STAA is not set
 CONFIG_MTD_CFI_UTIL=m
@@ -694,12 +703,10 @@
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
 
@@ -734,6 +741,7 @@
 CONFIG_NETPOLL_TRAP=y
 CONFIG_NET_POLL_CONTROLLER=y
 # CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
 
 #
 # Input device support
@@ -745,10 +753,7 @@
 #
 # Userland interfaces
 #
-CONFIG_INPUT_MOUSEDEV=m
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_JOYDEV is not set
 CONFIG_INPUT_EVDEV=m
 CONFIG_INPUT_EVBUG=m
@@ -757,12 +762,16 @@
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
 CONFIG_KEYBOARD_ATKBD=m
+# CONFIG_QT2160 is not set
 # CONFIG_KEYBOARD_LKKBD is not set
 CONFIG_KEYBOARD_GPIO=y
 # CONFIG_KEYBOARD_MATRIX is not set
 # CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
 # CONFIG_KEYBOARD_SUNKBD is not set
 CONFIG_KEYBOARD_XTKBD=m
@@ -777,6 +786,7 @@
 # CONFIG_TOUCHSCREEN_GUNZE is not set
 # CONFIG_TOUCHSCREEN_ELO is not set
 # CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
 # CONFIG_TOUCHSCREEN_MTOUCH is not set
 # CONFIG_TOUCHSCREEN_INEXIO is not set
 # CONFIG_TOUCHSCREEN_MK712 is not set
@@ -787,7 +797,17 @@
 # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
 # CONFIG_TOUCHSCREEN_TSC2007 is not set
 # CONFIG_TOUCHSCREEN_W90X900 is not set
-# CONFIG_INPUT_MISC is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+# CONFIG_INPUT_UINPUT is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+CONFIG_INPUT_DM355EVM=m
+CONFIG_INPUT_DM365EVM=m
 
 #
 # Hardware I/O ports
@@ -828,13 +848,13 @@
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=m
-# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -868,13 +888,17 @@
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
@@ -889,7 +913,7 @@
 #
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
-CONFIG_GPIO_PCF857X=m
+CONFIG_GPIO_PCF857X=y
 
 #
 # PCI GPIO expanders:
@@ -898,10 +922,19 @@
 #
 # SPI GPIO expanders:
 #
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
 # CONFIG_SENSORS_AD7414 is not set
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
@@ -950,6 +983,7 @@
 # CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
@@ -959,9 +993,7 @@
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -988,7 +1020,7 @@
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_MFD_ASIC3 is not set
-# CONFIG_MFD_DM355EVM_MSP is not set
+CONFIG_MFD_DM355EVM_MSP=y
 # CONFIG_HTC_EGPIO is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TPS65010 is not set
@@ -999,9 +1031,11 @@
 # CONFIG_MFD_TC6393XB is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
 #
@@ -1013,9 +1047,9 @@
 CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB_DDC is not set
 # CONFIG_FB_BOOT_VESA_SUPPORT is not set
-# CONFIG_FB_CFB_FILLRECT is not set
-# CONFIG_FB_CFB_COPYAREA is not set
-# CONFIG_FB_CFB_IMAGEBLIT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
 # CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
 # CONFIG_FB_SYS_FILLRECT is not set
 # CONFIG_FB_SYS_COPYAREA is not set
@@ -1032,6 +1066,7 @@
 # Frame buffer hardware drivers
 #
 # CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_DAVINCI=y
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
@@ -1101,7 +1136,6 @@
 # CONFIG_SOUND_PRIME is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=m
-# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
 
 #
@@ -1130,6 +1164,7 @@
 CONFIG_HID_EZKEY=m
 # CONFIG_HID_KYE is not set
 CONFIG_HID_GYRATION=m
+# CONFIG_HID_TWINHAN is not set
 # CONFIG_HID_KENSINGTON is not set
 CONFIG_HID_LOGITECH=m
 # CONFIG_LOGITECH_FF is not set
@@ -1176,6 +1211,7 @@
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
 # CONFIG_USB_R8A66597_HCD is not set
 # CONFIG_USB_HWA_HCD is not set
@@ -1269,6 +1305,7 @@
 # CONFIG_USB_GADGET_LH7A40X is not set
 # CONFIG_USB_GADGET_OMAP is not set
 # CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
 # CONFIG_USB_GADGET_PXA27X is not set
 # CONFIG_USB_GADGET_S3C_HSOTG is not set
 # CONFIG_USB_GADGET_IMX is not set
@@ -1286,6 +1323,7 @@
 # CONFIG_USB_AUDIO is not set
 CONFIG_USB_ETH=m
 CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
 CONFIG_USB_GADGETFS=m
 CONFIG_USB_FILE_STORAGE=m
 # CONFIG_USB_FILE_STORAGE_TEST is not set
@@ -1316,8 +1354,10 @@
 # MMC/SD/SDIO Host Controller Drivers
 #
 # CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+CONFIG_MMC_DAVINCI=m
 # CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY is not set
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=m
 
@@ -1345,6 +1385,7 @@
 #
 # iptables trigger is under Netfilter config (LED target)
 #
+# CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=m
 
@@ -1370,6 +1411,7 @@
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_DM355EVM is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1399,8 +1441,11 @@
 #
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
-# CONFIG_REGULATOR is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -1429,6 +1474,7 @@
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
@@ -1500,7 +1546,6 @@
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1596,6 +1641,7 @@
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -1634,11 +1680,14 @@
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
@@ -1663,7 +1712,7 @@
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
-CONFIG_ARM_UNWIND=y
+# CONFIG_ARM_UNWIND is not set
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_ERRORS=y
 # CONFIG_DEBUG_STACK_USAGE is not set
@@ -1681,7 +1730,6 @@
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 # CONFIG_CRYPTO_MANAGER is not set
 # CONFIG_CRYPTO_MANAGER2 is not set
 # CONFIG_CRYPTO_GF128MUL is not set
@@ -1713,11 +1761,13 @@
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/arm/configs/omap_3430sdp_defconfig b/arch/arm/configs/omap_3430sdp_defconfig
index 8482958..592457c 100644
--- a/arch/arm/configs/omap_3430sdp_defconfig
+++ b/arch/arm/configs/omap_3430sdp_defconfig
@@ -963,10 +963,32 @@
 #
 # CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
-CONFIG_FB_OMAP=y
-# CONFIG_FB_OMAP_LCDC_EXTERNAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_FB_OMAP_LCD_VGA is not set
 # CONFIG_FB_OMAP_BOOTLOADER_INIT is not set
-CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE=2
+CONFIG_OMAP2_VRAM=y
+CONFIG_OMAP2_VRFB=y
+CONFIG_OMAP2_DSS=y
+CONFIG_OMAP2_VRAM_SIZE=4
+CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y
+# CONFIG_OMAP2_DSS_RFBI is not set
+CONFIG_OMAP2_DSS_VENC=y
+# CONFIG_OMAP2_DSS_SDI is not set
+# CONFIG_OMAP2_DSS_DSI is not set
+# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set
+CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0
+CONFIG_FB_OMAP2=y
+CONFIG_FB_OMAP2_DEBUG_SUPPORT=y
+# CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE is not set
+CONFIG_FB_OMAP2_NUM_FBS=3
+
+#
+# OMAP2/3 Display Device Drivers
+#
+CONFIG_PANEL_GENERIC=y
+CONFIG_PANEL_SHARP_LS037V7DW01=y
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
diff --git a/arch/arm/include/asm/mman.h b/arch/arm/include/asm/mman.h
index 8eebf89..41f99c5 100644
--- a/arch/arm/include/asm/mman.h
+++ b/arch/arm/include/asm/mman.h
@@ -1 +1,4 @@
 #include <asm-generic/mman.h>
+
+#define arch_mmap_check(addr, len, flags) \
+	(((flags) & MAP_FIXED && (addr) < FIRST_USER_ADDRESS) ? -EINVAL : 0)
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index f58c115..9314a2d 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -172,7 +172,7 @@
 /* 160 */	CALL(sys_sched_get_priority_min)
 		CALL(sys_sched_rr_get_interval)
 		CALL(sys_nanosleep)
-		CALL(sys_arm_mremap)
+		CALL(sys_mremap)
 		CALL(sys_setresuid16)
 /* 165 */	CALL(sys_getresuid16)
 		CALL(sys_ni_syscall)		/* vm86 */
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index f0fe95b..2c1db77 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -416,12 +416,12 @@
 		tst	r5, #PGOFF_MASK
 		moveq	r5, r5, lsr #PAGE_SHIFT - 12
 		streq	r5, [sp, #4]
-		beq	do_mmap2
+		beq	sys_mmap_pgoff
 		mov	r0, #-EINVAL
 		mov	pc, lr
 #else
 		str	r5, [sp, #4]
-		b	do_mmap2
+		b	sys_mmap_pgoff
 #endif
 ENDPROC(sys_mmap2)
 
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index 78ecaac..ae4027b 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -28,41 +28,6 @@
 #include <linux/ipc.h>
 #include <linux/uaccess.h>
 
-extern unsigned long do_mremap(unsigned long addr, unsigned long old_len,
-			       unsigned long new_len, unsigned long flags,
-			       unsigned long new_addr);
-
-/* common code for old and new mmaps */
-inline long do_mmap2(
-	unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags,
-	unsigned long fd, unsigned long pgoff)
-{
-	int error = -EINVAL;
-	struct file * file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	if (flags & MAP_FIXED && addr < FIRST_USER_ADDRESS)
-		goto out;
-
-	error = -EBADF;
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-
 struct mmap_arg_struct {
 	unsigned long addr;
 	unsigned long len;
@@ -84,29 +49,11 @@
 	if (a.offset & ~PAGE_MASK)
 		goto out;
 
-	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+	error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
 out:
 	return error;
 }
 
-asmlinkage unsigned long
-sys_arm_mremap(unsigned long addr, unsigned long old_len,
-	       unsigned long new_len, unsigned long flags,
-	       unsigned long new_addr)
-{
-	unsigned long ret = -EINVAL;
-
-	if (flags & MREMAP_FIXED && new_addr < FIRST_USER_ADDRESS)
-		goto out;
-
-	down_write(&current->mm->mmap_sem);
-	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
-	up_write(&current->mm->mmap_sem);
-
-out:
-	return ret;
-}
-
 /*
  * Perform the select(nd, in, out, ex, tv) and mmap() system
  * calls.
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index a57af3e..809114d 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -866,6 +866,57 @@
 
 
 /* --------------------------------------------------------------------
+ *  Touchscreen
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) || defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC_MODULE)
+static u64 tsadcc_dmamask = DMA_BIT_MASK(32);
+static struct at91_tsadcc_data tsadcc_data;
+
+static struct resource tsadcc_resources[] = {
+	[0] = {
+		.start	= AT91SAM9G45_BASE_TSC,
+		.end	= AT91SAM9G45_BASE_TSC + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9G45_ID_TSC,
+		.end	= AT91SAM9G45_ID_TSC,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device at91sam9g45_tsadcc_device = {
+	.name		= "atmel_tsadcc",
+	.id		= -1,
+	.dev		= {
+				.dma_mask		= &tsadcc_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &tsadcc_data,
+	},
+	.resource	= tsadcc_resources,
+	.num_resources	= ARRAY_SIZE(tsadcc_resources),
+};
+
+void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data)
+{
+	if (!data)
+		return;
+
+	at91_set_gpio_input(AT91_PIN_PD20, 0);	/* AD0_XR */
+	at91_set_gpio_input(AT91_PIN_PD21, 0);	/* AD1_XL */
+	at91_set_gpio_input(AT91_PIN_PD22, 0);	/* AD2_YT */
+	at91_set_gpio_input(AT91_PIN_PD23, 0);	/* AD3_TB */
+
+	tsadcc_data = *data;
+	platform_device_register(&at91sam9g45_tsadcc_device);
+}
+#else
+void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
  *  RTT
  * -------------------------------------------------------------------- */
 
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index d345f54..53aaa94 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -622,6 +622,7 @@
 
 #if defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) || defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC_MODULE)
 static u64 tsadcc_dmamask = DMA_BIT_MASK(32);
+static struct at91_tsadcc_data tsadcc_data;
 
 static struct resource tsadcc_resources[] = {
 	[0] = {
@@ -642,22 +643,27 @@
 	.dev		= {
 				.dma_mask		= &tsadcc_dmamask,
 				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &tsadcc_data,
 	},
 	.resource	= tsadcc_resources,
 	.num_resources	= ARRAY_SIZE(tsadcc_resources),
 };
 
-void __init at91_add_device_tsadcc(void)
+void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data)
 {
+	if (!data)
+		return;
+
 	at91_set_A_periph(AT91_PIN_PA17, 0);	/* AD0_XR */
 	at91_set_A_periph(AT91_PIN_PA18, 0);	/* AD1_XL */
 	at91_set_A_periph(AT91_PIN_PA19, 0);	/* AD2_YT */
 	at91_set_A_periph(AT91_PIN_PA20, 0);	/* AD3_TB */
 
+	tsadcc_data = *data;
 	platform_device_register(&at91sam9rl_tsadcc_device);
 }
 #else
-void __init at91_add_device_tsadcc(void) {}
+void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) {}
 #endif
 
 
diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c
index 1cf4d86..98f9f4b 100644
--- a/arch/arm/mach-at91/board-sam9m10g45ek.c
+++ b/arch/arm/mach-at91/board-sam9m10g45ek.c
@@ -229,6 +229,16 @@
 
 
 /*
+ * Touchscreen
+ */
+static struct at91_tsadcc_data ek_tsadcc_data = {
+	.adc_clock		= 300000,
+	.pendet_debounce	= 0x0d,
+	.ts_sample_hold_time	= 0x0a,
+};
+
+
+/*
  * GPIO Buttons
  */
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
@@ -379,6 +389,8 @@
 	at91_add_device_i2c(0, NULL, 0);
 	/* LCD Controller */
 	at91_add_device_lcdc(&ek_lcdc_data);
+	/* Touch Screen */
+	at91_add_device_tsadcc(&ek_tsadcc_data);
 	/* Push Buttons */
 	ek_add_device_buttons();
 	/* AC97 */
diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c
index bd28e98..7ac20f3 100644
--- a/arch/arm/mach-at91/board-sam9rlek.c
+++ b/arch/arm/mach-at91/board-sam9rlek.c
@@ -243,6 +243,16 @@
 
 
 /*
+ * Touchscreen
+ */
+static struct at91_tsadcc_data ek_tsadcc_data = {
+	.adc_clock		= 1000000,
+	.pendet_debounce	= 0x0f,
+	.ts_sample_hold_time	= 0x03,
+};
+
+
+/*
  * GPIO Buttons
  */
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
@@ -310,7 +320,7 @@
 	/* AC97 */
 	at91_add_device_ac97(&ek_ac97_data);
 	/* Touch Screen Controller */
-	at91_add_device_tsadcc();
+	at91_add_device_tsadcc(&ek_tsadcc_data);
 	/* LEDs */
 	at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
 	/* Push Buttons */
diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
index 2295d80..bb6f6a7 100644
--- a/arch/arm/mach-at91/include/mach/board.h
+++ b/arch/arm/mach-at91/include/mach/board.h
@@ -187,7 +187,12 @@
 extern void __init at91_add_device_isi(void);
 
  /* Touchscreen Controller */
-extern void __init at91_add_device_tsadcc(void);
+struct at91_tsadcc_data {
+	unsigned int    adc_clock;
+	u8		pendet_debounce;
+	u8		ts_sample_hold_time;
+};
+extern void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data);
 
 /* CAN */
 struct at91_can_data {
diff --git a/arch/arm/mach-bcmring/include/csp/reg.h b/arch/arm/mach-bcmring/include/csp/reg.h
index e5f60bf..56654d2 100644
--- a/arch/arm/mach-bcmring/include/csp/reg.h
+++ b/arch/arm/mach-bcmring/include/csp/reg.h
@@ -16,7 +16,7 @@
 /**
 *  @file    reg.h
 *
-*  @brief   Generic register defintions used in CSP
+*  @brief   Generic register definitions used in CSP
 */
 /****************************************************************************/
 
diff --git a/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h
index 375066a..cbf334d 100644
--- a/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h
+++ b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h
@@ -83,7 +83,7 @@
 *  @brief   Get next available transaction width
 *
 *
-*  @return  On sucess  : Next avail able transaction width
+*  @return  On success  : Next available transaction width
 *           On failure : dmacHw_TRANSACTION_WIDTH_8
 *
 *  @note
diff --git a/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h b/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h
index 86bb58d..ad58cf8 100644
--- a/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h
+++ b/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h
@@ -16,7 +16,7 @@
 /**
 *  @file    mm_addr.h
 *
-*  @brief   Memory Map address defintions
+*  @brief   Memory Map address definitions
 *
 *  @note
 *     None
diff --git a/arch/arm/mach-bcmring/include/mach/dma.h b/arch/arm/mach-bcmring/include/mach/dma.h
index 847980c..1f2c531 100644
--- a/arch/arm/mach-bcmring/include/mach/dma.h
+++ b/arch/arm/mach-bcmring/include/mach/dma.h
@@ -651,7 +651,7 @@
 /**
 *   Creates a descriptor ring from a memory mapping.
 *
-*   @return 0 on sucess, error code otherwise.
+*   @return 0 on success, error code otherwise.
 */
 /****************************************************************************/
 
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
index 40866c6..033bfed 100644
--- a/arch/arm/mach-davinci/Kconfig
+++ b/arch/arm/mach-davinci/Kconfig
@@ -32,11 +32,13 @@
         bool "DA830/OMAP-L137 based system"
 	select CP_INTC
 	select ARCH_DAVINCI_DA8XX
+	select CPU_DCACHE_WRITETHROUGH # needed on silicon revs 1.0, 1.1
 
 config ARCH_DAVINCI_DA850
 	bool "DA850/OMAP-L138 based system"
 	select CP_INTC
 	select ARCH_DAVINCI_DA8XX
+	select ARCH_HAS_CPUFREQ
 
 config ARCH_DAVINCI_DA8XX
 	bool
@@ -63,6 +65,13 @@
 	  Say Y here to select the Lyrtech Small Form Factor
 	  Software Defined Radio (SFFSDR) board.
 
+config MACH_NEUROS_OSD2
+	bool "Neuros OSD2 Open Television Set Top Box"
+	depends on ARCH_DAVINCI_DM644x
+	help
+	  Configure this option to specify the whether the board used
+	  for development is a Neuros OSD2 Open Set Top Box.
+
 config MACH_DAVINCI_DM355_EVM
 	bool "TI DM355 EVM"
 	default ARCH_DAVINCI_DM355
@@ -98,16 +107,66 @@
 	bool "TI DA830/OMAP-L137 Reference Platform"
 	default ARCH_DAVINCI_DA830
 	depends on ARCH_DAVINCI_DA830
+	select GPIO_PCF857X
 	help
 	  Say Y here to select the TI DA830/OMAP-L137 Evaluation Module.
 
+choice
+	prompt "Select DA830/OMAP-L137 UI board peripheral"
+	depends on MACH_DAVINCI_DA830_EVM
+	help
+	  The presence of UI card on the DA830/OMAP-L137 EVM is detected
+	  automatically based on successful probe of the I2C based GPIO
+	  expander on that board. This option selected in this menu has
+	  an effect only in case of a successful UI card detection.
+
+config DA830_UI_LCD
+	bool "LCD"
+	help
+	  Say Y here to use the LCD as a framebuffer or simple character
+	  display.
+
+config DA830_UI_NAND
+	bool "NAND flash"
+	help
+	  Say Y here to use the NAND flash.  Do not forget to setup
+	  the switch correctly.
+endchoice
+
 config MACH_DAVINCI_DA850_EVM
 	bool "TI DA850/OMAP-L138 Reference Platform"
 	default ARCH_DAVINCI_DA850
 	depends on ARCH_DAVINCI_DA850
+	select GPIO_PCA953X
 	help
 	  Say Y here to select the TI DA850/OMAP-L138 Evaluation Module.
 
+choice
+	prompt "Select peripherals connected to expander on UI board"
+	depends on MACH_DAVINCI_DA850_EVM
+	help
+	  The presence of User Interface (UI) card on the DA850/OMAP-L138
+	  EVM is detected automatically based on successful probe of the I2C
+	  based GPIO expander on that card. This option selected in this
+	  menu has an effect only in case of a successful UI card detection.
+
+config DA850_UI_NONE
+	bool "No peripheral is enabled"
+	help
+	  Say Y if you do not want to enable any of the peripherals connected
+	  to TCA6416 expander on DA850/OMAP-L138 EVM UI card
+
+config DA850_UI_RMII
+	bool "RMII Ethernet PHY"
+	help
+	  Say Y if you want to use the RMII PHY on the DA850/OMAP-L138 EVM.
+	  This PHY is found on the UI daughter card that is supplied with
+	  the EVM.
+	  NOTE: Please take care while choosing this option, MII PHY will
+	  not be functional if RMII mode is selected.
+
+endchoice
+
 config DAVINCI_MUX
 	bool "DAVINCI multiplexing support"
 	depends on ARCH_DAVINCI
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile
index 2e11e84..eeb9230 100644
--- a/arch/arm/mach-davinci/Makefile
+++ b/arch/arm/mach-davinci/Makefile
@@ -23,9 +23,14 @@
 # Board specific
 obj-$(CONFIG_MACH_DAVINCI_EVM)  	+= board-dm644x-evm.o
 obj-$(CONFIG_MACH_SFFSDR)		+= board-sffsdr.o
+obj-$(CONFIG_MACH_NEUROS_OSD2)		+= board-neuros-osd2.o
 obj-$(CONFIG_MACH_DAVINCI_DM355_EVM)	+= board-dm355-evm.o
 obj-$(CONFIG_MACH_DM355_LEOPARD)	+= board-dm355-leopard.o
 obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM)	+= board-dm646x-evm.o
 obj-$(CONFIG_MACH_DAVINCI_DM365_EVM)	+= board-dm365-evm.o
 obj-$(CONFIG_MACH_DAVINCI_DA830_EVM)	+= board-da830-evm.o
 obj-$(CONFIG_MACH_DAVINCI_DA850_EVM)	+= board-da850-evm.o
+
+# Power Management
+obj-$(CONFIG_CPU_FREQ)			+= cpufreq.o
+obj-$(CONFIG_CPU_IDLE)			+= cpuidle.o
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
index bfbb639..31dc990 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -10,51 +10,194 @@
  * or implied.
  */
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/console.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
 #include <linux/i2c.h>
+#include <linux/i2c/pcf857x.h>
 #include <linux/i2c/at24.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/common.h>
-#include <mach/irqs.h>
 #include <mach/cp_intc.h>
+#include <mach/mux.h>
+#include <mach/nand.h>
 #include <mach/da8xx.h>
-#include <mach/asp.h>
+#include <mach/usb.h>
 
 #define DA830_EVM_PHY_MASK		0x0
 #define DA830_EVM_MDIO_FREQUENCY	2200000	/* PHY bus frequency */
 
-static struct at24_platform_data da830_evm_i2c_eeprom_info = {
-	.byte_len	= SZ_256K / 8,
-	.page_size	= 64,
-	.flags		= AT24_FLAG_ADDR16,
-	.setup		= davinci_get_mac_addr,
-	.context	= (void *)0x7f00,
+#define DA830_EMIF25_ASYNC_DATA_CE3_BASE	0x62000000
+#define DA830_EMIF25_CONTROL_BASE		0x68000000
+
+/*
+ * USB1 VBUS is controlled by GPIO1[15], over-current is reported on GPIO2[4].
+ */
+#define ON_BD_USB_DRV	GPIO_TO_PIN(1, 15)
+#define ON_BD_USB_OVC	GPIO_TO_PIN(2, 4)
+
+static const short da830_evm_usb11_pins[] = {
+	DA830_GPIO1_15, DA830_GPIO2_4,
+	-1
 };
 
-static struct i2c_board_info __initdata da830_evm_i2c_devices[] = {
-	{
-		I2C_BOARD_INFO("24c256", 0x50),
-		.platform_data	= &da830_evm_i2c_eeprom_info,
-	},
-	{
-		I2C_BOARD_INFO("tlv320aic3x", 0x18),
+static da8xx_ocic_handler_t da830_evm_usb_ocic_handler;
+
+static int da830_evm_usb_set_power(unsigned port, int on)
+{
+	gpio_set_value(ON_BD_USB_DRV, on);
+	return 0;
+}
+
+static int da830_evm_usb_get_power(unsigned port)
+{
+	return gpio_get_value(ON_BD_USB_DRV);
+}
+
+static int da830_evm_usb_get_oci(unsigned port)
+{
+	return !gpio_get_value(ON_BD_USB_OVC);
+}
+
+static irqreturn_t da830_evm_usb_ocic_irq(int, void *);
+
+static int da830_evm_usb_ocic_notify(da8xx_ocic_handler_t handler)
+{
+	int irq 	= gpio_to_irq(ON_BD_USB_OVC);
+	int error	= 0;
+
+	if (handler != NULL) {
+		da830_evm_usb_ocic_handler = handler;
+
+		error = request_irq(irq, da830_evm_usb_ocic_irq, IRQF_DISABLED |
+				    IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+				    "OHCI over-current indicator", NULL);
+		if (error)
+			printk(KERN_ERR "%s: could not request IRQ to watch "
+			       "over-current indicator changes\n", __func__);
+	} else
+		free_irq(irq, NULL);
+
+	return error;
+}
+
+static struct da8xx_ohci_root_hub da830_evm_usb11_pdata = {
+	.set_power	= da830_evm_usb_set_power,
+	.get_power	= da830_evm_usb_get_power,
+	.get_oci	= da830_evm_usb_get_oci,
+	.ocic_notify	= da830_evm_usb_ocic_notify,
+
+	/* TPS2065 switch @ 5V */
+	.potpgt		= (3 + 1) / 2,	/* 3 ms max */
+};
+
+static irqreturn_t da830_evm_usb_ocic_irq(int irq, void *dev_id)
+{
+	da830_evm_usb_ocic_handler(&da830_evm_usb11_pdata, 1);
+	return IRQ_HANDLED;
+}
+
+static __init void da830_evm_usb_init(void)
+{
+	u32 cfgchip2;
+	int ret;
+
+	/*
+	 * Set up USB clock/mode in the CFGCHIP2 register.
+	 * FYI:  CFGCHIP2 is 0x0000ef00 initially.
+	 */
+	cfgchip2 = __raw_readl(DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP2_REG));
+
+	/* USB2.0 PHY reference clock is 24 MHz */
+	cfgchip2 &= ~CFGCHIP2_REFFREQ;
+	cfgchip2 |=  CFGCHIP2_REFFREQ_24MHZ;
+
+	/*
+	 * Select internal reference clock for USB 2.0 PHY
+	 * and use it as a clock source for USB 1.1 PHY
+	 * (this is the default setting anyway).
+	 */
+	cfgchip2 &= ~CFGCHIP2_USB1PHYCLKMUX;
+	cfgchip2 |=  CFGCHIP2_USB2PHYCLKMUX;
+
+	/*
+	 * We have to override VBUS/ID signals when MUSB is configured into the
+	 * host-only mode -- ID pin will float if no cable is connected, so the
+	 * controller won't be able to drive VBUS thinking that it's a B-device.
+	 * Otherwise, we want to use the OTG mode and enable VBUS comparators.
+	 */
+	cfgchip2 &= ~CFGCHIP2_OTGMODE;
+#ifdef	CONFIG_USB_MUSB_HOST
+	cfgchip2 |=  CFGCHIP2_FORCE_HOST;
+#else
+	cfgchip2 |=  CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN;
+#endif
+
+	__raw_writel(cfgchip2, DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP2_REG));
+
+	/* USB_REFCLKIN is not used. */
+	ret = davinci_cfg_reg(DA830_USB0_DRVVBUS);
+	if (ret)
+		pr_warning("%s: USB 2.0 PinMux setup failed: %d\n",
+			   __func__, ret);
+	else {
+		/*
+		 * TPS2065 switch @ 5V supplies 1 A (sustains 1.5 A),
+		 * with the power on to power good time of 3 ms.
+		 */
+		ret = da8xx_register_usb20(1000, 3);
+		if (ret)
+			pr_warning("%s: USB 2.0 registration failed: %d\n",
+				   __func__, ret);
 	}
-};
 
-static struct davinci_i2c_platform_data da830_evm_i2c_0_pdata = {
-	.bus_freq	= 100,	/* kHz */
-	.bus_delay	= 0,	/* usec */
-};
+	ret = da8xx_pinmux_setup(da830_evm_usb11_pins);
+	if (ret) {
+		pr_warning("%s: USB 1.1 PinMux setup failed: %d\n",
+			   __func__, ret);
+		return;
+	}
+
+	ret = gpio_request(ON_BD_USB_DRV, "ON_BD_USB_DRV");
+	if (ret) {
+		printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port "
+		       "power control: %d\n", __func__, ret);
+		return;
+	}
+	gpio_direction_output(ON_BD_USB_DRV, 0);
+
+	ret = gpio_request(ON_BD_USB_OVC, "ON_BD_USB_OVC");
+	if (ret) {
+		printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port "
+		       "over-current indicator: %d\n", __func__, ret);
+		return;
+	}
+	gpio_direction_input(ON_BD_USB_OVC);
+
+	ret = da8xx_register_usb11(&da830_evm_usb11_pdata);
+	if (ret)
+		pr_warning("%s: USB 1.1 registration failed: %d\n",
+			   __func__, ret);
+}
 
 static struct davinci_uart_config da830_evm_uart_config __initdata = {
 	.enabled_uarts = 0x7,
 };
 
+static const short da830_evm_mcasp1_pins[] = {
+	DA830_AHCLKX1, DA830_ACLKX1, DA830_AFSX1, DA830_AHCLKR1, DA830_AFSR1,
+	DA830_AMUTE1, DA830_AXR1_0, DA830_AXR1_1, DA830_AXR1_2, DA830_AXR1_5,
+	DA830_ACLKR1, DA830_AXR1_6, DA830_AXR1_7, DA830_AXR1_8, DA830_AXR1_10,
+	DA830_AXR1_11,
+	-1
+};
+
 static u8 da830_iis_serializer_direction[] = {
 	RX_MODE,	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,
 	INACTIVE_MODE,	TX_MODE,	INACTIVE_MODE,	INACTIVE_MODE,
@@ -74,6 +217,271 @@
 	.rxnumevt	= 1,
 };
 
+/*
+ * GPIO2[1] is used as MMC_SD_WP and GPIO2[2] as MMC_SD_INS.
+ */
+static const short da830_evm_mmc_sd_pins[] = {
+	DA830_MMCSD_DAT_0, DA830_MMCSD_DAT_1, DA830_MMCSD_DAT_2,
+	DA830_MMCSD_DAT_3, DA830_MMCSD_DAT_4, DA830_MMCSD_DAT_5,
+	DA830_MMCSD_DAT_6, DA830_MMCSD_DAT_7, DA830_MMCSD_CLK,
+	DA830_MMCSD_CMD,   DA830_GPIO2_1,     DA830_GPIO2_2,
+	-1
+};
+
+#define DA830_MMCSD_WP_PIN		GPIO_TO_PIN(2, 1)
+
+static int da830_evm_mmc_get_ro(int index)
+{
+	return gpio_get_value(DA830_MMCSD_WP_PIN);
+}
+
+static struct davinci_mmc_config da830_evm_mmc_config = {
+	.get_ro			= da830_evm_mmc_get_ro,
+	.wires			= 4,
+	.max_freq		= 50000000,
+	.caps			= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
+	.version		= MMC_CTLR_VERSION_2,
+};
+
+static inline void da830_evm_init_mmc(void)
+{
+	int ret;
+
+	ret = da8xx_pinmux_setup(da830_evm_mmc_sd_pins);
+	if (ret) {
+		pr_warning("da830_evm_init: mmc/sd mux setup failed: %d\n",
+				ret);
+		return;
+	}
+
+	ret = gpio_request(DA830_MMCSD_WP_PIN, "MMC WP");
+	if (ret) {
+		pr_warning("da830_evm_init: can not open GPIO %d\n",
+			   DA830_MMCSD_WP_PIN);
+		return;
+	}
+	gpio_direction_input(DA830_MMCSD_WP_PIN);
+
+	ret = da8xx_register_mmcsd0(&da830_evm_mmc_config);
+	if (ret) {
+		pr_warning("da830_evm_init: mmc/sd registration failed: %d\n",
+				ret);
+		gpio_free(DA830_MMCSD_WP_PIN);
+	}
+}
+
+/*
+ * UI board NAND/NOR flashes only use 8-bit data bus.
+ */
+static const short da830_evm_emif25_pins[] = {
+	DA830_EMA_D_0, DA830_EMA_D_1, DA830_EMA_D_2, DA830_EMA_D_3,
+	DA830_EMA_D_4, DA830_EMA_D_5, DA830_EMA_D_6, DA830_EMA_D_7,
+	DA830_EMA_A_0, DA830_EMA_A_1, DA830_EMA_A_2, DA830_EMA_A_3,
+	DA830_EMA_A_4, DA830_EMA_A_5, DA830_EMA_A_6, DA830_EMA_A_7,
+	DA830_EMA_A_8, DA830_EMA_A_9, DA830_EMA_A_10, DA830_EMA_A_11,
+	DA830_EMA_A_12, DA830_EMA_BA_0, DA830_EMA_BA_1, DA830_NEMA_WE,
+	DA830_NEMA_CS_2, DA830_NEMA_CS_3, DA830_NEMA_OE, DA830_EMA_WAIT_0,
+	-1
+};
+
+#if defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE)
+#define HAS_MMC	1
+#else
+#define HAS_MMC	0
+#endif
+
+#ifdef CONFIG_DA830_UI_NAND
+static struct mtd_partition da830_evm_nand_partitions[] = {
+	/* bootloader (U-Boot, etc) in first sector */
+	[0] = {
+		.name		= "bootloader",
+		.offset		= 0,
+		.size		= SZ_128K,
+		.mask_flags	= MTD_WRITEABLE,	/* force read-only */
+	},
+	/* bootloader params in the next sector */
+	[1] = {
+		.name		= "params",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_128K,
+		.mask_flags	= MTD_WRITEABLE,	/* force read-only */
+	},
+	/* kernel */
+	[2] = {
+		.name		= "kernel",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_2M,
+		.mask_flags	= 0,
+	},
+	/* file system */
+	[3] = {
+		.name		= "filesystem",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= MTDPART_SIZ_FULL,
+		.mask_flags	= 0,
+	}
+};
+
+/* flash bbt decriptors */
+static uint8_t da830_evm_nand_bbt_pattern[] = { 'B', 'b', 't', '0' };
+static uint8_t da830_evm_nand_mirror_pattern[] = { '1', 't', 'b', 'B' };
+
+static struct nand_bbt_descr da830_evm_nand_bbt_main_descr = {
+	.options	= NAND_BBT_LASTBLOCK | NAND_BBT_CREATE |
+			  NAND_BBT_WRITE | NAND_BBT_2BIT |
+			  NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+	.offs		= 2,
+	.len		= 4,
+	.veroffs	= 16,
+	.maxblocks	= 4,
+	.pattern	= da830_evm_nand_bbt_pattern
+};
+
+static struct nand_bbt_descr da830_evm_nand_bbt_mirror_descr = {
+	.options	= NAND_BBT_LASTBLOCK | NAND_BBT_CREATE |
+			  NAND_BBT_WRITE | NAND_BBT_2BIT |
+			  NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+	.offs		= 2,
+	.len		= 4,
+	.veroffs	= 16,
+	.maxblocks	= 4,
+	.pattern	= da830_evm_nand_mirror_pattern
+};
+
+static struct davinci_nand_pdata da830_evm_nand_pdata = {
+	.parts		= da830_evm_nand_partitions,
+	.nr_parts	= ARRAY_SIZE(da830_evm_nand_partitions),
+	.ecc_mode	= NAND_ECC_HW,
+	.ecc_bits	= 4,
+	.options	= NAND_USE_FLASH_BBT,
+	.bbt_td		= &da830_evm_nand_bbt_main_descr,
+	.bbt_md		= &da830_evm_nand_bbt_mirror_descr,
+};
+
+static struct resource da830_evm_nand_resources[] = {
+	[0] = {		/* First memory resource is NAND I/O window */
+		.start	= DA830_EMIF25_ASYNC_DATA_CE3_BASE,
+		.end	= DA830_EMIF25_ASYNC_DATA_CE3_BASE + PAGE_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {		/* Second memory resource is AEMIF control registers */
+		.start	= DA830_EMIF25_CONTROL_BASE,
+		.end	= DA830_EMIF25_CONTROL_BASE + SZ_32K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device da830_evm_nand_device = {
+	.name		= "davinci_nand",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &da830_evm_nand_pdata,
+	},
+	.num_resources	= ARRAY_SIZE(da830_evm_nand_resources),
+	.resource	= da830_evm_nand_resources,
+};
+
+static inline void da830_evm_init_nand(int mux_mode)
+{
+	int ret;
+
+	if (HAS_MMC) {
+		pr_warning("WARNING: both MMC/SD and NAND are "
+				"enabled, but they share AEMIF pins.\n"
+				"\tDisable MMC/SD for NAND support.\n");
+		return;
+	}
+
+	ret = da8xx_pinmux_setup(da830_evm_emif25_pins);
+	if (ret)
+		pr_warning("da830_evm_init: emif25 mux setup failed: %d\n",
+				ret);
+
+	ret = platform_device_register(&da830_evm_nand_device);
+	if (ret)
+		pr_warning("da830_evm_init: NAND device not registered.\n");
+
+	gpio_direction_output(mux_mode, 1);
+}
+#else
+static inline void da830_evm_init_nand(int mux_mode) { }
+#endif
+
+#ifdef CONFIG_DA830_UI_LCD
+static inline void da830_evm_init_lcdc(int mux_mode)
+{
+	int ret;
+
+	ret = da8xx_pinmux_setup(da830_lcdcntl_pins);
+	if (ret)
+		pr_warning("da830_evm_init: lcdcntl mux setup failed: %d\n",
+				ret);
+
+	ret = da8xx_register_lcdc(&sharp_lcd035q3dg01_pdata);
+	if (ret)
+		pr_warning("da830_evm_init: lcd setup failed: %d\n", ret);
+
+	gpio_direction_output(mux_mode, 0);
+}
+#else
+static inline void da830_evm_init_lcdc(int mux_mode) { }
+#endif
+
+static struct at24_platform_data da830_evm_i2c_eeprom_info = {
+	.byte_len	= SZ_256K / 8,
+	.page_size	= 64,
+	.flags		= AT24_FLAG_ADDR16,
+	.setup		= davinci_get_mac_addr,
+	.context	= (void *)0x7f00,
+};
+
+static int __init da830_evm_ui_expander_setup(struct i2c_client *client,
+		int gpio, unsigned ngpio, void *context)
+{
+	gpio_request(gpio + 6, "UI MUX_MODE");
+
+	/* Drive mux mode low to match the default without UI card */
+	gpio_direction_output(gpio + 6, 0);
+
+	da830_evm_init_lcdc(gpio + 6);
+
+	da830_evm_init_nand(gpio + 6);
+
+	return 0;
+}
+
+static int da830_evm_ui_expander_teardown(struct i2c_client *client, int gpio,
+		unsigned ngpio, void *context)
+{
+	gpio_free(gpio + 6);
+	return 0;
+}
+
+static struct pcf857x_platform_data __initdata da830_evm_ui_expander_info = {
+	.gpio_base	= DAVINCI_N_GPIO,
+	.setup		= da830_evm_ui_expander_setup,
+	.teardown	= da830_evm_ui_expander_teardown,
+};
+
+static struct i2c_board_info __initdata da830_evm_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("24c256", 0x50),
+		.platform_data	= &da830_evm_i2c_eeprom_info,
+	},
+	{
+		I2C_BOARD_INFO("tlv320aic3x", 0x18),
+	},
+	{
+		I2C_BOARD_INFO("pcf8574", 0x3f),
+		.platform_data	= &da830_evm_ui_expander_info,
+	},
+};
+
+static struct davinci_i2c_platform_data da830_evm_i2c_0_pdata = {
+	.bus_freq	= 100,	/* kHz */
+	.bus_delay	= 0,	/* usec */
+};
+
 static __init void da830_evm_init(void)
 {
 	struct davinci_soc_info *soc_info = &davinci_soc_info;
@@ -94,6 +502,8 @@
 		pr_warning("da830_evm_init: i2c0 registration failed: %d\n",
 				ret);
 
+	da830_evm_usb_init();
+
 	soc_info->emac_pdata->phy_mask = DA830_EVM_PHY_MASK;
 	soc_info->emac_pdata->mdio_max_freq = DA830_EVM_MDIO_FREQUENCY;
 	soc_info->emac_pdata->rmii_en = 1;
@@ -117,12 +527,18 @@
 	i2c_register_board_info(1, da830_evm_i2c_devices,
 			ARRAY_SIZE(da830_evm_i2c_devices));
 
-	ret = da8xx_pinmux_setup(da830_mcasp1_pins);
+	ret = da8xx_pinmux_setup(da830_evm_mcasp1_pins);
 	if (ret)
 		pr_warning("da830_evm_init: mcasp1 mux setup failed: %d\n",
 				ret);
 
-	da8xx_init_mcasp(1, &da830_evm_snd_data);
+	da8xx_register_mcasp(1, &da830_evm_snd_data);
+
+	da830_evm_init_mmc();
+
+	ret = da8xx_register_rtc();
+	if (ret)
+		pr_warning("da830_evm_init: rtc setup failed: %d\n", ret);
 }
 
 #ifdef CONFIG_SERIAL_8250_CONSOLE
@@ -146,7 +562,7 @@
 	da830_init();
 }
 
-MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP L137 EVM")
+MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137 EVM")
 	.phys_io	= IO_PHYS,
 	.io_pg_offst	= (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
 	.boot_params	= (DA8XX_DDR_BASE + 0x100),
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index c759d72..62b98bf 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -12,36 +12,38 @@
  * or implied.
  */
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/i2c.h>
 #include <linux/i2c/at24.h>
+#include <linux/i2c/pca953x.h>
 #include <linux/gpio.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
+#include <linux/regulator/machine.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/common.h>
-#include <mach/irqs.h>
 #include <mach/cp_intc.h>
 #include <mach/da8xx.h>
 #include <mach/nand.h>
+#include <mach/mux.h>
 
 #define DA850_EVM_PHY_MASK		0x1
 #define DA850_EVM_MDIO_FREQUENCY	2200000 /* PHY bus frequency */
 
+#define DA850_LCD_PWR_PIN		GPIO_TO_PIN(2, 8)
 #define DA850_LCD_BL_PIN		GPIO_TO_PIN(2, 15)
-#define DA850_LCD_PWR_PIN		GPIO_TO_PIN(8, 10)
 
 #define DA850_MMCSD_CD_PIN		GPIO_TO_PIN(4, 0)
 #define DA850_MMCSD_WP_PIN		GPIO_TO_PIN(4, 1)
 
+#define DA850_MII_MDIO_CLKEN_PIN	GPIO_TO_PIN(2, 6)
+
 static struct mtd_partition da850_evm_norflash_partition[] = {
 	{
 		.name           = "NOR filesystem",
@@ -143,10 +145,149 @@
 	.resource	= da850_evm_nandflash_resource,
 };
 
+static struct platform_device *da850_evm_devices[] __initdata = {
+	&da850_evm_nandflash_device,
+	&da850_evm_norflash_device,
+};
+
+#define DA8XX_AEMIF_CE2CFG_OFFSET	0x10
+#define DA8XX_AEMIF_ASIZE_16BIT		0x1
+
+static void __init da850_evm_init_nor(void)
+{
+	void __iomem *aemif_addr;
+
+	aemif_addr = ioremap(DA8XX_AEMIF_CTL_BASE, SZ_32K);
+
+	/* Configure data bus width of CS2 to 16 bit */
+	writel(readl(aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET) |
+		DA8XX_AEMIF_ASIZE_16BIT,
+		aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET);
+
+	iounmap(aemif_addr);
+}
+
+static u32 ui_card_detected;
+
+#if defined(CONFIG_MMC_DAVINCI) || \
+    defined(CONFIG_MMC_DAVINCI_MODULE)
+#define HAS_MMC 1
+#else
+#define HAS_MMC 0
+#endif
+
+static __init void da850_evm_setup_nor_nand(void)
+{
+	int ret = 0;
+
+	if (ui_card_detected & !HAS_MMC) {
+		ret = da8xx_pinmux_setup(da850_nand_pins);
+		if (ret)
+			pr_warning("da850_evm_init: nand mux setup failed: "
+					"%d\n", ret);
+
+		ret = da8xx_pinmux_setup(da850_nor_pins);
+		if (ret)
+			pr_warning("da850_evm_init: nor mux setup failed: %d\n",
+				ret);
+
+		da850_evm_init_nor();
+
+		platform_add_devices(da850_evm_devices,
+					ARRAY_SIZE(da850_evm_devices));
+	}
+}
+
+#ifdef CONFIG_DA850_UI_RMII
+static inline void da850_evm_setup_emac_rmii(int rmii_sel)
+{
+	struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+	soc_info->emac_pdata->rmii_en = 1;
+	gpio_set_value(rmii_sel, 0);
+}
+#else
+static inline void da850_evm_setup_emac_rmii(int rmii_sel) { }
+#endif
+
+static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio,
+						unsigned ngpio, void *c)
+{
+	int sel_a, sel_b, sel_c, ret;
+
+	sel_a = gpio + 7;
+	sel_b = gpio + 6;
+	sel_c = gpio + 5;
+
+	ret = gpio_request(sel_a, "sel_a");
+	if (ret) {
+		pr_warning("Cannot open UI expander pin %d\n", sel_a);
+		goto exp_setup_sela_fail;
+	}
+
+	ret = gpio_request(sel_b, "sel_b");
+	if (ret) {
+		pr_warning("Cannot open UI expander pin %d\n", sel_b);
+		goto exp_setup_selb_fail;
+	}
+
+	ret = gpio_request(sel_c, "sel_c");
+	if (ret) {
+		pr_warning("Cannot open UI expander pin %d\n", sel_c);
+		goto exp_setup_selc_fail;
+	}
+
+	/* deselect all functionalities */
+	gpio_direction_output(sel_a, 1);
+	gpio_direction_output(sel_b, 1);
+	gpio_direction_output(sel_c, 1);
+
+	ui_card_detected = 1;
+	pr_info("DA850/OMAP-L138 EVM UI card detected\n");
+
+	da850_evm_setup_nor_nand();
+
+	da850_evm_setup_emac_rmii(sel_a);
+
+	return 0;
+
+exp_setup_selc_fail:
+	gpio_free(sel_b);
+exp_setup_selb_fail:
+	gpio_free(sel_a);
+exp_setup_sela_fail:
+	return ret;
+}
+
+static int da850_evm_ui_expander_teardown(struct i2c_client *client,
+					unsigned gpio, unsigned ngpio, void *c)
+{
+	/* deselect all functionalities */
+	gpio_set_value(gpio + 5, 1);
+	gpio_set_value(gpio + 6, 1);
+	gpio_set_value(gpio + 7, 1);
+
+	gpio_free(gpio + 5);
+	gpio_free(gpio + 6);
+	gpio_free(gpio + 7);
+
+	return 0;
+}
+
+static struct pca953x_platform_data da850_evm_ui_expander_info = {
+	.gpio_base	= DAVINCI_N_GPIO,
+	.setup		= da850_evm_ui_expander_setup,
+	.teardown	= da850_evm_ui_expander_teardown,
+};
+
 static struct i2c_board_info __initdata da850_evm_i2c_devices[] = {
 	{
 		I2C_BOARD_INFO("tlv320aic3x", 0x18),
-	}
+	},
+	{
+		I2C_BOARD_INFO("tca6416", 0x20),
+		.platform_data = &da850_evm_ui_expander_info,
+	},
 };
 
 static struct davinci_i2c_platform_data da850_evm_i2c_0_pdata = {
@@ -158,11 +299,6 @@
 	.enabled_uarts = 0x7,
 };
 
-static struct platform_device *da850_evm_devices[] __initdata = {
-	&da850_evm_nandflash_device,
-	&da850_evm_norflash_device,
-};
-
 /* davinci da850 evm audio machine driver */
 static u8 da850_iis_serializer_direction[] = {
 	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,
@@ -198,6 +334,8 @@
 	.get_ro		= da850_evm_mmc_get_ro,
 	.get_cd		= da850_evm_mmc_get_cd,
 	.wires		= 4,
+	.max_freq	= 50000000,
+	.caps		= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
 	.version	= MMC_CTLR_VERSION_2,
 };
 
@@ -233,57 +371,228 @@
 	return 0;
 }
 
-#define DA8XX_AEMIF_CE2CFG_OFFSET	0x10
-#define DA8XX_AEMIF_ASIZE_16BIT		0x1
+/* TPS65070 voltage regulator support */
 
-static void __init da850_evm_init_nor(void)
+/* 3.3V */
+struct regulator_consumer_supply tps65070_dcdc1_consumers[] = {
+	{
+		.supply = "usb0_vdda33",
+	},
+	{
+		.supply = "usb1_vdda33",
+	},
+};
+
+/* 3.3V or 1.8V */
+struct regulator_consumer_supply tps65070_dcdc2_consumers[] = {
+	{
+		.supply = "dvdd3318_a",
+	},
+	{
+		.supply = "dvdd3318_b",
+	},
+	{
+		.supply = "dvdd3318_c",
+	},
+};
+
+/* 1.2V */
+struct regulator_consumer_supply tps65070_dcdc3_consumers[] = {
+	{
+		.supply = "cvdd",
+	},
+};
+
+/* 1.8V LDO */
+struct regulator_consumer_supply tps65070_ldo1_consumers[] = {
+	{
+		.supply = "sata_vddr",
+	},
+	{
+		.supply = "usb0_vdda18",
+	},
+	{
+		.supply = "usb1_vdda18",
+	},
+	{
+		.supply = "ddr_dvdd18",
+	},
+};
+
+/* 1.2V LDO */
+struct regulator_consumer_supply tps65070_ldo2_consumers[] = {
+	{
+		.supply = "sata_vdd",
+	},
+	{
+		.supply = "pll0_vdda",
+	},
+	{
+		.supply = "pll1_vdda",
+	},
+	{
+		.supply = "usbs_cvdd",
+	},
+	{
+		.supply = "vddarnwa1",
+	},
+};
+
+struct regulator_init_data tps65070_regulator_data[] = {
+	/* dcdc1 */
+	{
+		.constraints = {
+			.min_uV = 3150000,
+			.max_uV = 3450000,
+			.valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+				REGULATOR_CHANGE_STATUS),
+			.boot_on = 1,
+		},
+		.num_consumer_supplies = ARRAY_SIZE(tps65070_dcdc1_consumers),
+		.consumer_supplies = tps65070_dcdc1_consumers,
+	},
+
+	/* dcdc2 */
+	{
+		.constraints = {
+			.min_uV = 1710000,
+			.max_uV = 3450000,
+			.valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+				REGULATOR_CHANGE_STATUS),
+			.boot_on = 1,
+		},
+		.num_consumer_supplies = ARRAY_SIZE(tps65070_dcdc2_consumers),
+		.consumer_supplies = tps65070_dcdc2_consumers,
+	},
+
+	/* dcdc3 */
+	{
+		.constraints = {
+			.min_uV = 950000,
+			.max_uV = 1320000,
+			.valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+				REGULATOR_CHANGE_STATUS),
+			.boot_on = 1,
+		},
+		.num_consumer_supplies = ARRAY_SIZE(tps65070_dcdc3_consumers),
+		.consumer_supplies = tps65070_dcdc3_consumers,
+	},
+
+	/* ldo1 */
+	{
+		.constraints = {
+			.min_uV = 1710000,
+			.max_uV = 1890000,
+			.valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+				REGULATOR_CHANGE_STATUS),
+			.boot_on = 1,
+		},
+		.num_consumer_supplies = ARRAY_SIZE(tps65070_ldo1_consumers),
+		.consumer_supplies = tps65070_ldo1_consumers,
+	},
+
+	/* ldo2 */
+	{
+		.constraints = {
+			.min_uV = 1140000,
+			.max_uV = 1320000,
+			.valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+				REGULATOR_CHANGE_STATUS),
+			.boot_on = 1,
+		},
+		.num_consumer_supplies = ARRAY_SIZE(tps65070_ldo2_consumers),
+		.consumer_supplies = tps65070_ldo2_consumers,
+	},
+};
+
+static struct i2c_board_info __initdata da850evm_tps65070_info[] = {
+	{
+		I2C_BOARD_INFO("tps6507x", 0x48),
+		.platform_data = &tps65070_regulator_data[0],
+	},
+};
+
+static int __init pmic_tps65070_init(void)
 {
-	void __iomem *aemif_addr;
-
-	aemif_addr = ioremap(DA8XX_AEMIF_CTL_BASE, SZ_32K);
-
-	/* Configure data bus width of CS2 to 16 bit */
-	writel(readl(aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET) |
-		DA8XX_AEMIF_ASIZE_16BIT,
-		aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET);
-
-	iounmap(aemif_addr);
+	return i2c_register_board_info(1, da850evm_tps65070_info,
+					ARRAY_SIZE(da850evm_tps65070_info));
 }
 
-#if defined(CONFIG_MTD_PHYSMAP) || \
-    defined(CONFIG_MTD_PHYSMAP_MODULE)
-#define HAS_NOR 1
-#else
-#define HAS_NOR 0
-#endif
+static const short da850_evm_lcdc_pins[] = {
+	DA850_GPIO2_8, DA850_GPIO2_15,
+	-1
+};
 
-#if defined(CONFIG_MMC_DAVINCI) || \
-    defined(CONFIG_MMC_DAVINCI_MODULE)
-#define HAS_MMC 1
-#else
-#define HAS_MMC 0
-#endif
+static int __init da850_evm_config_emac(void)
+{
+	void __iomem *cfg_chip3_base;
+	int ret;
+	u32 val;
+	struct davinci_soc_info *soc_info = &davinci_soc_info;
+	u8 rmii_en = soc_info->emac_pdata->rmii_en;
+
+	if (!machine_is_davinci_da850_evm())
+		return 0;
+
+	cfg_chip3_base = DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP3_REG);
+
+	val = __raw_readl(cfg_chip3_base);
+
+	if (rmii_en) {
+		val |= BIT(8);
+		ret = da8xx_pinmux_setup(da850_rmii_pins);
+		pr_info("EMAC: RMII PHY configured, MII PHY will not be"
+							" functional\n");
+	} else {
+		val &= ~BIT(8);
+		ret = da8xx_pinmux_setup(da850_cpgmac_pins);
+		pr_info("EMAC: MII PHY configured, RMII PHY will not be"
+							" functional\n");
+	}
+
+	if (ret)
+		pr_warning("da850_evm_init: cpgmac/rmii mux setup failed: %d\n",
+				ret);
+
+	/* configure the CFGCHIP3 register for RMII or MII */
+	__raw_writel(val, cfg_chip3_base);
+
+	ret = davinci_cfg_reg(DA850_GPIO2_6);
+	if (ret)
+		pr_warning("da850_evm_init:GPIO(2,6) mux setup "
+							"failed\n");
+
+	ret = gpio_request(DA850_MII_MDIO_CLKEN_PIN, "mdio_clk_en");
+	if (ret) {
+		pr_warning("Cannot open GPIO %d\n",
+					DA850_MII_MDIO_CLKEN_PIN);
+		return ret;
+	}
+
+	/* Enable/Disable MII MDIO clock */
+	gpio_direction_output(DA850_MII_MDIO_CLKEN_PIN, rmii_en);
+
+	soc_info->emac_pdata->phy_mask = DA850_EVM_PHY_MASK;
+	soc_info->emac_pdata->mdio_max_freq = DA850_EVM_MDIO_FREQUENCY;
+
+	ret = da8xx_register_emac();
+	if (ret)
+		pr_warning("da850_evm_init: emac registration failed: %d\n",
+				ret);
+
+	return 0;
+}
+device_initcall(da850_evm_config_emac);
 
 static __init void da850_evm_init(void)
 {
-	struct davinci_soc_info *soc_info = &davinci_soc_info;
 	int ret;
 
-	ret = da8xx_pinmux_setup(da850_nand_pins);
+	ret = pmic_tps65070_init();
 	if (ret)
-		pr_warning("da850_evm_init: nand mux setup failed: %d\n",
+		pr_warning("da850_evm_init: TPS65070 PMIC init failed: %d\n",
 				ret);
 
-	ret = da8xx_pinmux_setup(da850_nor_pins);
-	if (ret)
-		pr_warning("da850_evm_init: nor mux setup failed: %d\n",
-				ret);
-
-	da850_evm_init_nor();
-
-	platform_add_devices(da850_evm_devices,
-				ARRAY_SIZE(da850_evm_devices));
-
 	ret = da8xx_register_edma();
 	if (ret)
 		pr_warning("da850_evm_init: edma registration failed: %d\n",
@@ -299,19 +608,6 @@
 		pr_warning("da850_evm_init: i2c0 registration failed: %d\n",
 				ret);
 
-	soc_info->emac_pdata->phy_mask = DA850_EVM_PHY_MASK;
-	soc_info->emac_pdata->mdio_max_freq = DA850_EVM_MDIO_FREQUENCY;
-	soc_info->emac_pdata->rmii_en = 0;
-
-	ret = da8xx_pinmux_setup(da850_cpgmac_pins);
-	if (ret)
-		pr_warning("da850_evm_init: cpgmac mux setup failed: %d\n",
-				ret);
-
-	ret = da8xx_register_emac();
-	if (ret)
-		pr_warning("da850_evm_init: emac registration failed: %d\n",
-				ret);
 
 	ret = da8xx_register_watchdog();
 	if (ret)
@@ -319,11 +615,6 @@
 				ret);
 
 	if (HAS_MMC) {
-		if (HAS_NOR)
-			pr_warning("WARNING: both NOR Flash and MMC/SD are "
-				"enabled, but they share AEMIF pins.\n"
-				"\tDisable one of them.\n");
-
 		ret = da8xx_pinmux_setup(da850_mmcsd0_pins);
 		if (ret)
 			pr_warning("da850_evm_init: mmcsd0 mux setup failed:"
@@ -365,22 +656,42 @@
 		pr_warning("da850_evm_init: mcasp mux setup failed: %d\n",
 				ret);
 
-	da8xx_init_mcasp(0, &da850_evm_snd_data);
+	da8xx_register_mcasp(0, &da850_evm_snd_data);
 
 	ret = da8xx_pinmux_setup(da850_lcdcntl_pins);
 	if (ret)
 		pr_warning("da850_evm_init: lcdcntl mux setup failed: %d\n",
 				ret);
 
+	/* Handle board specific muxing for LCD here */
+	ret = da8xx_pinmux_setup(da850_evm_lcdc_pins);
+	if (ret)
+		pr_warning("da850_evm_init: evm specific lcd mux setup "
+				"failed: %d\n",	ret);
+
 	ret = da850_lcd_hw_init();
 	if (ret)
 		pr_warning("da850_evm_init: lcd initialization failed: %d\n",
 				ret);
 
-	ret = da8xx_register_lcdc();
+	ret = da8xx_register_lcdc(&sharp_lk043t1dg01_pdata);
 	if (ret)
 		pr_warning("da850_evm_init: lcdc registration failed: %d\n",
 				ret);
+
+	ret = da8xx_register_rtc();
+	if (ret)
+		pr_warning("da850_evm_init: rtc setup failed: %d\n", ret);
+
+	ret = da850_register_cpufreq();
+	if (ret)
+		pr_warning("da850_evm_init: cpufreq registration failed: %d\n",
+				ret);
+
+	ret = da8xx_register_cpuidle();
+	if (ret)
+		pr_warning("da850_evm_init: cpuidle registration failed: %d\n",
+				ret);
 }
 
 #ifdef CONFIG_SERIAL_8250_CONSOLE
diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
index 77e8067..a9b650d 100644
--- a/arch/arm/mach-davinci/board-dm355-evm.c
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -9,15 +9,13 @@
  * or implied.
  */
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
-#include <linux/dma-mapping.h>
+#include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/nand.h>
 #include <linux/i2c.h>
-#include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/clk.h>
 #include <linux/videodev2.h>
@@ -25,20 +23,15 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/eeprom.h>
 
-#include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/flash.h>
 
-#include <mach/hardware.h>
 #include <mach/dm355.h>
-#include <mach/psc.h>
-#include <mach/common.h>
 #include <mach/i2c.h>
 #include <mach/serial.h>
 #include <mach/nand.h>
 #include <mach/mmc.h>
+#include <mach/usb.h>
 
 #define DAVINCI_ASYNC_EMIF_CONTROL_BASE		0x01e10000
 #define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE	0x02000000
@@ -86,8 +79,9 @@
 	.mask_chipsel		= BIT(14),
 	.parts			= davinci_nand_partitions,
 	.nr_parts		= ARRAY_SIZE(davinci_nand_partitions),
-	.ecc_mode		= NAND_ECC_HW_SYNDROME,
+	.ecc_mode		= NAND_ECC_HW,
 	.options		= NAND_USE_FLASH_BBT,
+	.ecc_bits		= 4,
 };
 
 static struct resource davinci_nand_resources[] = {
@@ -344,7 +338,7 @@
 	gpio_request(2, "usb_id_toggle");
 	gpio_direction_output(2, USB_ID_VALUE);
 	/* irlml6401 switches over 1A in under 8 msec */
-	setup_usb(500, 8);
+	davinci_setup_usb(1000, 8);
 
 	davinci_setup_mmc(0, &dm355evm_mmc_config);
 	davinci_setup_mmc(1, &dm355evm_mmc_config);
diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c
index 84ad5d1..21f32eb 100644
--- a/arch/arm/mach-davinci/board-dm355-leopard.c
+++ b/arch/arm/mach-davinci/board-dm355-leopard.c
@@ -8,34 +8,27 @@
  * warranty of any kind, whether express or implied.
  */
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
-#include <linux/dma-mapping.h>
+#include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/nand.h>
 #include <linux/i2c.h>
-#include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/clk.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/eeprom.h>
 
-#include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/flash.h>
 
-#include <mach/hardware.h>
 #include <mach/dm355.h>
-#include <mach/psc.h>
-#include <mach/common.h>
 #include <mach/i2c.h>
 #include <mach/serial.h>
 #include <mach/nand.h>
 #include <mach/mmc.h>
+#include <mach/usb.h>
 
 #define DAVINCI_ASYNC_EMIF_CONTROL_BASE		0x01e10000
 #define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE	0x02000000
@@ -270,7 +263,7 @@
 	gpio_request(2, "usb_id_toggle");
 	gpio_direction_output(2, USB_ID_VALUE);
 	/* irlml6401 switches over 1A in under 8 msec */
-	setup_usb(500, 8);
+	davinci_setup_usb(1000, 8);
 
 	davinci_setup_mmc(0, &dm355leopard_mmc_config);
 	davinci_setup_mmc(1, &dm355leopard_mmc_config);
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index 52dd804..289fe1b 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -13,9 +13,8 @@
  * GNU General Public License for more details.
  */
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
-#include <linux/dma-mapping.h>
+#include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/io.h>
 #include <linux/clk.h>
@@ -24,20 +23,19 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/nand.h>
-#include <asm/setup.h>
+#include <linux/input.h>
+
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/map.h>
+
 #include <mach/mux.h>
-#include <mach/hardware.h>
 #include <mach/dm365.h>
-#include <mach/psc.h>
 #include <mach/common.h>
 #include <mach/i2c.h>
 #include <mach/serial.h>
 #include <mach/mmc.h>
 #include <mach/nand.h>
-
+#include <mach/keyscan.h>
 
 static inline int have_imager(void)
 {
@@ -144,6 +142,7 @@
 	.nr_parts		= ARRAY_SIZE(davinci_nand_partitions),
 	.ecc_mode		= NAND_ECC_HW,
 	.options		= NAND_USE_FLASH_BBT,
+	.ecc_bits		= 4,
 };
 
 static struct resource davinci_nand_resources[] = {
@@ -176,11 +175,16 @@
 	.context	= (void *)0x7f00,
 };
 
+static struct snd_platform_data dm365_evm_snd_data;
+
 static struct i2c_board_info i2c_info[] = {
 	{
 		I2C_BOARD_INFO("24c256", 0x50),
 		.platform_data	= &eeprom_info,
 	},
+	{
+		I2C_BOARD_INFO("tlv320aic3x", 0x18),
+	},
 };
 
 static struct davinci_i2c_platform_data i2c_pdata = {
@@ -188,6 +192,38 @@
 	.bus_delay	= 0	/* usec */,
 };
 
+#ifdef CONFIG_KEYBOARD_DAVINCI
+static unsigned short dm365evm_keymap[] = {
+	KEY_KP2,
+	KEY_LEFT,
+	KEY_EXIT,
+	KEY_DOWN,
+	KEY_ENTER,
+	KEY_UP,
+	KEY_KP1,
+	KEY_RIGHT,
+	KEY_MENU,
+	KEY_RECORD,
+	KEY_REWIND,
+	KEY_KPMINUS,
+	KEY_STOP,
+	KEY_FASTFORWARD,
+	KEY_KPPLUS,
+	KEY_PLAYPAUSE,
+	0
+};
+
+static struct davinci_ks_platform_data dm365evm_ks_data = {
+	.keymap		= dm365evm_keymap,
+	.keymapsize	= ARRAY_SIZE(dm365evm_keymap),
+	.rep		= 1,
+	/* Scan period = strobe + interval */
+	.strobe		= 0x5,
+	.interval	= 0x2,
+	.matrix_type	= DAVINCI_KEYSCAN_MATRIX_4X4,
+};
+#endif
+
 static int cpld_mmc_get_cd(int module)
 {
 	if (!cpld)
@@ -472,6 +508,13 @@
 
 	/* maybe setup mmc1/etc ... _after_ mmc0 */
 	evm_init_cpld();
+
+	dm365_init_asp(&dm365_evm_snd_data);
+	dm365_init_rtc();
+
+#ifdef CONFIG_KEYBOARD_DAVINCI
+	dm365_init_ks(&dm365evm_ks_data);
+#endif
 }
 
 static __init void dm365_evm_irq_init(void)
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index 1213a00..fd0398b 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -9,45 +9,34 @@
  * or implied.
  */
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
-#include <linux/leds.h>
-#include <linux/memory.h>
-
 #include <linux/i2c.h>
 #include <linux/i2c/pcf857x.h>
 #include <linux/i2c/at24.h>
-#include <linux/etherdevice.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
-#include <linux/io.h>
 #include <linux/phy.h>
 #include <linux/clk.h>
 #include <linux/videodev2.h>
 
 #include <media/tvp514x.h>
 
-#include <asm/setup.h>
 #include <asm/mach-types.h>
-
 #include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/flash.h>
 
 #include <mach/dm644x.h>
 #include <mach/common.h>
 #include <mach/i2c.h>
 #include <mach/serial.h>
 #include <mach/mux.h>
-#include <mach/psc.h>
 #include <mach/nand.h>
 #include <mach/mmc.h>
-#include <mach/emac.h>
+#include <mach/usb.h>
 
 #define DM644X_EVM_PHY_MASK		(0x2)
 #define DM644X_EVM_MDIO_FREQUENCY	(2200000) /* PHY bus frequency */
@@ -477,7 +466,7 @@
 	/* irlml6401 switches over 1A, in under 8 msec;
 	 * now it can be managed by nDRV_VBUS ...
 	 */
-	setup_usb(500, 8);
+	davinci_setup_usb(1000, 8);
 
 	return 0;
 }
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index 24e0e13..8d0b0e0 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -17,38 +17,28 @@
  **************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/major.h>
-#include <linux/root_dev.h>
-#include <linux/dma-mapping.h>
-#include <linux/serial.h>
-#include <linux/serial_8250.h>
 #include <linux/leds.h>
 #include <linux/gpio.h>
-#include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/i2c/at24.h>
 #include <linux/i2c/pcf857x.h>
-#include <linux/etherdevice.h>
 
 #include <media/tvp514x.h>
 
-#include <asm/setup.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/flash.h>
 
 #include <mach/dm646x.h>
 #include <mach/common.h>
-#include <mach/psc.h>
 #include <mach/serial.h>
 #include <mach/i2c.h>
-#include <mach/mmc.h>
-#include <mach/emac.h>
+#include <mach/nand.h>
 
 #if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
     defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
@@ -57,6 +47,11 @@
 #define HAS_ATA 0
 #endif
 
+#define DAVINCI_ASYNC_EMIF_CONTROL_BASE		0x20008000
+#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE	0x42000000
+
+#define NAND_BLOCK_SIZE		SZ_128K
+
 /* CPLD Register 0 bits to control ATA */
 #define DM646X_EVM_ATA_RST		BIT(0)
 #define DM646X_EVM_ATA_PWD		BIT(1)
@@ -92,6 +87,63 @@
 	.enabled_uarts = (1 << 0),
 };
 
+/* Note: We are setting first partition as 'bootloader' constituting UBL, U-Boot
+ * and U-Boot environment this avoids dependency on any particular combination
+ * of UBL, U-Boot or flashing tools etc.
+ */
+static struct mtd_partition davinci_nand_partitions[] = {
+	{
+		/* UBL, U-Boot with environment */
+		.name		= "bootloader",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 16 * NAND_BLOCK_SIZE,
+		.mask_flags	= MTD_WRITEABLE,	/* force read-only */
+	}, {
+		.name		= "kernel",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_4M,
+		.mask_flags	= 0,
+	}, {
+		.name		= "filesystem",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= MTDPART_SIZ_FULL,
+		.mask_flags	= 0,
+	}
+};
+
+static struct davinci_nand_pdata davinci_nand_data = {
+	.mask_cle 		= 0x80000,
+	.mask_ale 		= 0x40000,
+	.parts			= davinci_nand_partitions,
+	.nr_parts		= ARRAY_SIZE(davinci_nand_partitions),
+	.ecc_mode		= NAND_ECC_HW,
+	.options		= 0,
+};
+
+static struct resource davinci_nand_resources[] = {
+	{
+		.start		= DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
+		.end		= DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= DAVINCI_ASYNC_EMIF_CONTROL_BASE,
+		.end		= DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device davinci_nand_device = {
+	.name			= "davinci_nand",
+	.id			= 0,
+
+	.num_resources		= ARRAY_SIZE(davinci_nand_resources),
+	.resource		= davinci_nand_resources,
+
+	.dev			= {
+		.platform_data	= &davinci_nand_data,
+	},
+};
+
 /* CPLD Register 0 Client: used for I/O Control */
 static int cpld_reg0_probe(struct i2c_client *client,
 			   const struct i2c_device_id *id)
@@ -142,7 +194,7 @@
 	{ .name = "DS4", .active_low = 1, },
 };
 
-static __initconst struct gpio_led_platform_data evm_led_data = {
+static const struct gpio_led_platform_data evm_led_data = {
 	.num_leds = ARRAY_SIZE(evm_leds),
 	.leds     = evm_leds,
 };
@@ -647,6 +699,8 @@
 	dm646x_init_mcasp0(&dm646x_evm_snd_data[0]);
 	dm646x_init_mcasp1(&dm646x_evm_snd_data[1]);
 
+	platform_device_register(&davinci_nand_device);
+
 	if (HAS_ATA)
 		dm646x_init_ide();
 
diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c
new file mode 100644
index 0000000..bd9ca07
--- /dev/null
+++ b/arch/arm/mach-davinci/board-neuros-osd2.c
@@ -0,0 +1,323 @@
+/*
+ * Neuros Technologies OSD2 board support
+ *
+ * Modified from original 644X-EVM board support.
+ * 2008 (c) Neuros Technology, LLC.
+ * 2009 (c) Jorge Luis Zapata Muga <jorgeluis.zapata@gmail.com>
+ * 2009 (c) Andrey A. Porodko <Andrey.Porodko@gmail.com>
+ *
+ * The Neuros OSD 2.0 is the hardware component of the Neuros Open
+ * Internet Television Platform. Hardware is very close to TI
+ * DM644X-EVM board. It has:
+ * 	DM6446M02 module with 256MB NAND, 256MB RAM, TLV320AIC32 AIC,
+ * 	USB, Ethernet, SD/MMC, UART, THS8200, TVP7000 for video.
+ * 	Additionaly realtime clock, IR remote control receiver,
+ * 	IR Blaster based on MSP430 (firmware although is different
+ * 	from used in DM644X-EVM), internal ATA-6 3.5” HDD drive
+ * 	with PATA interface, two muxed red-green leds.
+ *
+ * For more information please refer to
+ * 		http://wiki.neurostechnology.com/index.php/OSD_2.0_HD
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/dm644x.h>
+#include <mach/i2c.h>
+#include <mach/serial.h>
+#include <mach/mux.h>
+#include <mach/nand.h>
+#include <mach/mmc.h>
+#include <mach/usb.h>
+
+#define NEUROS_OSD2_PHY_MASK		0x2
+#define NEUROS_OSD2_MDIO_FREQUENCY	2200000 /* PHY bus frequency */
+
+#define DAVINCI_CFC_ATA_BASE		 0x01C66000
+
+#define DAVINCI_ASYNC_EMIF_CONTROL_BASE	 0x01e00000
+#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
+
+#define LXT971_PHY_ID			0x001378e2
+#define LXT971_PHY_MASK			0xfffffff0
+
+#define	NTOSD2_AUDIOSOC_I2C_ADDR	0x18
+#define	NTOSD2_MSP430_I2C_ADDR		0x59
+#define	NTOSD2_MSP430_IRQ		2
+
+/* Neuros OSD2 has a Samsung 256 MByte NAND flash (Dev ID of 0xAA,
+ * 2048 blocks in the device, 64 pages per block, 2048 bytes per
+ * page.
+ */
+
+#define NAND_BLOCK_SIZE		SZ_128K
+
+struct mtd_partition davinci_ntosd2_nandflash_partition[] = {
+	{
+		/* UBL (a few copies) plus U-Boot */
+		.name		= "bootloader",
+		.offset		= 0,
+		.size		= 15 * NAND_BLOCK_SIZE,
+		.mask_flags	= MTD_WRITEABLE, /* force read-only */
+	}, {
+		/* U-Boot environment */
+		.name		= "params",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 1 * NAND_BLOCK_SIZE,
+		.mask_flags	= 0,
+	}, {
+		/* Kernel */
+		.name		= "kernel",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_4M,
+		.mask_flags	= 0,
+	}, {
+		/* File System */
+		.name		= "filesystem",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= MTDPART_SIZ_FULL,
+		.mask_flags	= 0,
+	}
+	/* A few blocks at end hold a flash Bad Block Table. */
+};
+
+static struct davinci_nand_pdata davinci_ntosd2_nandflash_data = {
+	.parts		= davinci_ntosd2_nandflash_partition,
+	.nr_parts	= ARRAY_SIZE(davinci_ntosd2_nandflash_partition),
+	.ecc_mode	= NAND_ECC_HW,
+	.options	= NAND_USE_FLASH_BBT,
+};
+
+static struct resource davinci_ntosd2_nandflash_resource[] = {
+	{
+		.start		= DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
+		.end		= DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= DAVINCI_ASYNC_EMIF_CONTROL_BASE,
+		.end		= DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device davinci_ntosd2_nandflash_device = {
+	.name		= "davinci_nand",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &davinci_ntosd2_nandflash_data,
+	},
+	.num_resources	= ARRAY_SIZE(davinci_ntosd2_nandflash_resource),
+	.resource	= davinci_ntosd2_nandflash_resource,
+};
+
+static u64 davinci_fb_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device davinci_fb_device = {
+	.name		= "davincifb",
+	.id		= -1,
+	.dev = {
+		.dma_mask		= &davinci_fb_dma_mask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.num_resources = 0,
+};
+
+static struct resource ide_resources[] = {
+	{
+		.start		= DAVINCI_CFC_ATA_BASE,
+		.end		= DAVINCI_CFC_ATA_BASE + 0x7ff,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= IRQ_IDE,
+		.end		= IRQ_IDE,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static u64 ide_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device ide_dev = {
+	.name		= "palm_bk3710",
+	.id		= -1,
+	.resource	= ide_resources,
+	.num_resources	= ARRAY_SIZE(ide_resources),
+	.dev = {
+		.dma_mask		= &ide_dma_mask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+};
+
+static struct snd_platform_data dm644x_ntosd2_snd_data;
+
+static struct gpio_led ntosd2_leds[] = {
+	{ .name = "led1_green", .gpio = GPIO(10), },
+	{ .name = "led1_red",   .gpio = GPIO(11), },
+	{ .name = "led2_green", .gpio = GPIO(12), },
+	{ .name = "led2_red",   .gpio = GPIO(13), },
+};
+
+static struct gpio_led_platform_data ntosd2_leds_data = {
+	.num_leds	= ARRAY_SIZE(ntosd2_leds),
+	.leds		= ntosd2_leds,
+};
+
+static struct platform_device ntosd2_leds_dev = {
+	.name = "leds-gpio",
+	.id   = -1,
+	.dev = {
+		.platform_data 		= &ntosd2_leds_data,
+	},
+};
+
+
+static struct platform_device *davinci_ntosd2_devices[] __initdata = {
+	&davinci_fb_device,
+	&ntosd2_leds_dev,
+};
+
+static struct davinci_uart_config uart_config __initdata = {
+	.enabled_uarts = (1 << 0),
+};
+
+static void __init davinci_ntosd2_map_io(void)
+{
+	dm644x_init();
+}
+
+/*
+ I2C initialization
+*/
+static struct davinci_i2c_platform_data ntosd2_i2c_pdata = {
+	.bus_freq	= 20 /* kHz */,
+	.bus_delay	= 100 /* usec */,
+};
+
+static struct i2c_board_info __initdata ntosd2_i2c_info[] =  {
+};
+
+static	int ntosd2_init_i2c(void)
+{
+	int	status;
+
+	davinci_init_i2c(&ntosd2_i2c_pdata);
+	status = gpio_request(NTOSD2_MSP430_IRQ, ntosd2_i2c_info[0].type);
+	if (status == 0) {
+		status = gpio_direction_input(NTOSD2_MSP430_IRQ);
+		if (status == 0) {
+			status = gpio_to_irq(NTOSD2_MSP430_IRQ);
+			if (status > 0) {
+				ntosd2_i2c_info[0].irq = status;
+				i2c_register_board_info(1,
+					ntosd2_i2c_info,
+					ARRAY_SIZE(ntosd2_i2c_info));
+			}
+		}
+	}
+	return status;
+}
+
+static struct davinci_mmc_config davinci_ntosd2_mmc_config = {
+	.wires		= 4,
+	.version	= MMC_CTLR_VERSION_1
+};
+
+
+#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
+	defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
+#define HAS_ATA 1
+#else
+#define HAS_ATA 0
+#endif
+
+#if defined(CONFIG_MTD_NAND_DAVINCI) || \
+	defined(CONFIG_MTD_NAND_DAVINCI_MODULE)
+#define HAS_NAND 1
+#else
+#define HAS_NAND 0
+#endif
+
+static __init void davinci_ntosd2_init(void)
+{
+	struct clk *aemif_clk;
+	struct davinci_soc_info *soc_info = &davinci_soc_info;
+	int	status;
+
+	aemif_clk = clk_get(NULL, "aemif");
+	clk_enable(aemif_clk);
+
+	if (HAS_ATA) {
+		if (HAS_NAND)
+			pr_warning("WARNING: both IDE and Flash are "
+				"enabled, but they share AEMIF pins.\n"
+				"\tDisable IDE for NAND/NOR support.\n");
+		davinci_cfg_reg(DM644X_HPIEN_DISABLE);
+		davinci_cfg_reg(DM644X_ATAEN);
+		davinci_cfg_reg(DM644X_HDIREN);
+		platform_device_register(&ide_dev);
+	} else if (HAS_NAND) {
+		davinci_cfg_reg(DM644X_HPIEN_DISABLE);
+		davinci_cfg_reg(DM644X_ATAEN_DISABLE);
+
+		/* only one device will be jumpered and detected */
+		if (HAS_NAND)
+			platform_device_register(
+					&davinci_ntosd2_nandflash_device);
+	}
+
+	platform_add_devices(davinci_ntosd2_devices,
+				ARRAY_SIZE(davinci_ntosd2_devices));
+
+	/* Initialize I2C interface specific for this board */
+	status = ntosd2_init_i2c();
+	if (status < 0)
+		pr_warning("davinci_ntosd2_init: msp430 irq setup failed:"
+						"	 %d\n", status);
+
+	davinci_serial_init(&uart_config);
+	dm644x_init_asp(&dm644x_ntosd2_snd_data);
+
+	soc_info->emac_pdata->phy_mask = NEUROS_OSD2_PHY_MASK;
+	soc_info->emac_pdata->mdio_max_freq = NEUROS_OSD2_MDIO_FREQUENCY;
+
+	davinci_setup_usb(1000, 8);
+	/*
+	 * Mux the pins to be GPIOs, VLYNQEN is already done at startup.
+	 * The AEAWx are five new AEAW pins that can be muxed by separately.
+	 * They are a bitmask for GPIO management. According TI
+	 * documentation (http://www.ti.com/lit/gpn/tms320dm6446) to employ
+	 * gpio(10,11,12,13) for leds any combination of bits works except
+	 * four last. So we are to reset all five.
+	 */
+	davinci_cfg_reg(DM644X_AEAW0);
+	davinci_cfg_reg(DM644X_AEAW1);
+	davinci_cfg_reg(DM644X_AEAW2);
+	davinci_cfg_reg(DM644X_AEAW3);
+	davinci_cfg_reg(DM644X_AEAW4);
+
+	davinci_setup_mmc(0, &davinci_ntosd2_mmc_config);
+}
+
+static __init void davinci_ntosd2_irq_init(void)
+{
+	davinci_irq_init();
+}
+
+MACHINE_START(NEUROS_OSD2, "Neuros OSD2")
+	/* Maintainer: Neuros Technologies <neuros@groups.google.com> */
+	.phys_io	= IO_PHYS,
+	.io_pg_offst	= (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
+	.boot_params	= (DAVINCI_DDR_BASE + 0x100),
+	.map_io		 = davinci_ntosd2_map_io,
+	.init_irq	= davinci_ntosd2_irq_init,
+	.timer		= &davinci_timer,
+	.init_machine = davinci_ntosd2_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c
index 7acdfd8a..08d373b 100644
--- a/arch/arm/mach-davinci/board-sffsdr.c
+++ b/arch/arm/mach-davinci/board-sffsdr.c
@@ -23,35 +23,24 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
-#include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
-#include <linux/gpio.h>
-
 #include <linux/i2c.h>
 #include <linux/i2c/at24.h>
-#include <linux/etherdevice.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
-#include <linux/mtd/physmap.h>
-#include <linux/io.h>
 
-#include <asm/setup.h>
 #include <asm/mach-types.h>
-
 #include <asm/mach/arch.h>
-#include <asm/mach/map.h>
 #include <asm/mach/flash.h>
 
 #include <mach/dm644x.h>
 #include <mach/common.h>
 #include <mach/i2c.h>
 #include <mach/serial.h>
-#include <mach/psc.h>
 #include <mach/mux.h>
+#include <mach/usb.h>
 
 #define SFFSDR_PHY_MASK		(0x2)
 #define SFFSDR_MDIO_FREQUENCY	(2200000) /* PHY bus frequency */
@@ -107,11 +96,6 @@
 	.resource	= davinci_sffsdr_nandflash_resource,
 };
 
-static struct emac_platform_data sffsdr_emac_pdata = {
-	.phy_mask	= SFFSDR_PHY_MASK,
-	.mdio_max_freq	= SFFSDR_MDIO_FREQUENCY,
-};
-
 static struct at24_platform_data eeprom_info = {
 	.byte_len	= (64*1024) / 8,
 	.page_size	= 32,
@@ -164,7 +148,7 @@
 	davinci_serial_init(&uart_config);
 	soc_info->emac_pdata->phy_mask = SFFSDR_PHY_MASK;
 	soc_info->emac_pdata->mdio_max_freq = SFFSDR_MDIO_FREQUENCY;
-	setup_usb(0, 0); /* We support only peripheral mode. */
+	davinci_setup_usb(0, 0); /* We support only peripheral mode. */
 
 	/* mux VLYNQ pins */
 	davinci_cfg_reg(DM644X_VLYNQEN);
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
index 83d54d5..baece65 100644
--- a/arch/arm/mach-davinci/clock.c
+++ b/arch/arm/mach-davinci/clock.c
@@ -17,8 +17,8 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
-#include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/delay.h>
 
 #include <mach/hardware.h>
 
@@ -42,8 +42,7 @@
 	if (clk->parent)
 		__clk_enable(clk->parent);
 	if (clk->usecount++ == 0 && (clk->flags & CLK_PSC))
-		davinci_psc_config(psc_domain(clk), clk->psc_ctlr,
-				clk->lpsc, 1);
+		davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, 1);
 }
 
 static void __clk_disable(struct clk *clk)
@@ -51,8 +50,7 @@
 	if (WARN_ON(clk->usecount == 0))
 		return;
 	if (--clk->usecount == 0 && !(clk->flags & CLK_PLL))
-		davinci_psc_config(psc_domain(clk), clk->psc_ctlr,
-				clk->lpsc, 0);
+		davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, 0);
 	if (clk->parent)
 		__clk_disable(clk->parent);
 }
@@ -99,19 +97,73 @@
 	if (clk == NULL || IS_ERR(clk))
 		return -EINVAL;
 
+	if (clk->round_rate)
+		return clk->round_rate(clk, rate);
+
 	return clk->rate;
 }
 EXPORT_SYMBOL(clk_round_rate);
 
+/* Propagate rate to children */
+static void propagate_rate(struct clk *root)
+{
+	struct clk *clk;
+
+	list_for_each_entry(clk, &root->children, childnode) {
+		if (clk->recalc)
+			clk->rate = clk->recalc(clk);
+		propagate_rate(clk);
+	}
+}
+
 int clk_set_rate(struct clk *clk, unsigned long rate)
 {
+	unsigned long flags;
+	int ret = -EINVAL;
+
+	if (clk == NULL || IS_ERR(clk))
+		return ret;
+
+	spin_lock_irqsave(&clockfw_lock, flags);
+	if (clk->set_rate)
+		ret = clk->set_rate(clk, rate);
+	if (ret == 0) {
+		if (clk->recalc)
+			clk->rate = clk->recalc(clk);
+		propagate_rate(clk);
+	}
+	spin_unlock_irqrestore(&clockfw_lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	unsigned long flags;
+
 	if (clk == NULL || IS_ERR(clk))
 		return -EINVAL;
 
-	/* changing the clk rate is not supported */
-	return -EINVAL;
+	/* Cannot change parent on enabled clock */
+	if (WARN_ON(clk->usecount))
+		return -EINVAL;
+
+	mutex_lock(&clocks_mutex);
+	clk->parent = parent;
+	list_del_init(&clk->childnode);
+	list_add(&clk->childnode, &clk->parent->children);
+	mutex_unlock(&clocks_mutex);
+
+	spin_lock_irqsave(&clockfw_lock, flags);
+	if (clk->recalc)
+		clk->rate = clk->recalc(clk);
+	propagate_rate(clk);
+	spin_unlock_irqrestore(&clockfw_lock, flags);
+
+	return 0;
 }
-EXPORT_SYMBOL(clk_set_rate);
+EXPORT_SYMBOL(clk_set_parent);
 
 int clk_register(struct clk *clk)
 {
@@ -123,16 +175,24 @@
 			clk->name, clk->parent->name))
 		return -EINVAL;
 
+	INIT_LIST_HEAD(&clk->children);
+
 	mutex_lock(&clocks_mutex);
 	list_add_tail(&clk->node, &clocks);
+	if (clk->parent)
+		list_add_tail(&clk->childnode, &clk->parent->children);
 	mutex_unlock(&clocks_mutex);
 
 	/* If rate is already set, use it */
 	if (clk->rate)
 		return 0;
 
+	/* Else, see if there is a way to calculate it */
+	if (clk->recalc)
+		clk->rate = clk->recalc(clk);
+
 	/* Otherwise, default to parent rate */
-	if (clk->parent)
+	else if (clk->parent)
 		clk->rate = clk->parent->rate;
 
 	return 0;
@@ -146,6 +206,7 @@
 
 	mutex_lock(&clocks_mutex);
 	list_del(&clk->node);
+	list_del(&clk->childnode);
 	mutex_unlock(&clocks_mutex);
 }
 EXPORT_SYMBOL(clk_unregister);
@@ -166,11 +227,11 @@
 			continue;
 
 		/* ignore if in Disabled or SwRstDisable states */
-		if (!davinci_psc_is_clk_active(ck->psc_ctlr, ck->lpsc))
+		if (!davinci_psc_is_clk_active(ck->gpsc, ck->lpsc))
 			continue;
 
 		pr_info("Clocks: disable unused %s\n", ck->name);
-		davinci_psc_config(psc_domain(ck), ck->psc_ctlr, ck->lpsc, 0);
+		davinci_psc_config(psc_domain(ck), ck->gpsc, ck->lpsc, 0);
 	}
 	spin_unlock_irq(&clockfw_lock);
 
@@ -179,50 +240,62 @@
 late_initcall(clk_disable_unused);
 #endif
 
-static void clk_sysclk_recalc(struct clk *clk)
+static unsigned long clk_sysclk_recalc(struct clk *clk)
 {
 	u32 v, plldiv;
 	struct pll_data *pll;
+	unsigned long rate = clk->rate;
 
 	/* If this is the PLL base clock, no more calculations needed */
 	if (clk->pll_data)
-		return;
+		return rate;
 
 	if (WARN_ON(!clk->parent))
-		return;
+		return rate;
 
-	clk->rate = clk->parent->rate;
+	rate = clk->parent->rate;
 
 	/* Otherwise, the parent must be a PLL */
 	if (WARN_ON(!clk->parent->pll_data))
-		return;
+		return rate;
 
 	pll = clk->parent->pll_data;
 
 	/* If pre-PLL, source clock is before the multiplier and divider(s) */
 	if (clk->flags & PRE_PLL)
-		clk->rate = pll->input_rate;
+		rate = pll->input_rate;
 
 	if (!clk->div_reg)
-		return;
+		return rate;
 
 	v = __raw_readl(pll->base + clk->div_reg);
 	if (v & PLLDIV_EN) {
 		plldiv = (v & PLLDIV_RATIO_MASK) + 1;
 		if (plldiv)
-			clk->rate /= plldiv;
+			rate /= plldiv;
 	}
+
+	return rate;
 }
 
-static void __init clk_pll_init(struct clk *clk)
+static unsigned long clk_leafclk_recalc(struct clk *clk)
+{
+	if (WARN_ON(!clk->parent))
+		return clk->rate;
+
+	return clk->parent->rate;
+}
+
+static unsigned long clk_pllclk_recalc(struct clk *clk)
 {
 	u32 ctrl, mult = 1, prediv = 1, postdiv = 1;
 	u8 bypass;
 	struct pll_data *pll = clk->pll_data;
+	unsigned long rate = clk->rate;
 
 	pll->base = IO_ADDRESS(pll->phys_base);
 	ctrl = __raw_readl(pll->base + PLLCTL);
-	clk->rate = pll->input_rate = clk->parent->rate;
+	rate = pll->input_rate = clk->parent->rate;
 
 	if (ctrl & PLLCTL_PLLEN) {
 		bypass = 0;
@@ -255,9 +328,9 @@
 	}
 
 	if (!bypass) {
-		clk->rate /= prediv;
-		clk->rate *= mult;
-		clk->rate /= postdiv;
+		rate /= prediv;
+		rate *= mult;
+		rate /= postdiv;
 	}
 
 	pr_debug("PLL%d: input = %lu MHz [ ",
@@ -270,9 +343,91 @@
 		pr_debug("* %d ", mult);
 	if (postdiv > 1)
 		pr_debug("/ %d ", postdiv);
-	pr_debug("] --> %lu MHz output.\n", clk->rate / 1000000);
+	pr_debug("] --> %lu MHz output.\n", rate / 1000000);
+
+	return rate;
 }
 
+/**
+ * davinci_set_pllrate - set the output rate of a given PLL.
+ *
+ * Note: Currently tested to work with OMAP-L138 only.
+ *
+ * @pll: pll whose rate needs to be changed.
+ * @prediv: The pre divider value. Passing 0 disables the pre-divider.
+ * @pllm: The multiplier value. Passing 0 leads to multiply-by-one.
+ * @postdiv: The post divider value. Passing 0 disables the post-divider.
+ */
+int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
+					unsigned int mult, unsigned int postdiv)
+{
+	u32 ctrl;
+	unsigned int locktime;
+
+	if (pll->base == NULL)
+		return -EINVAL;
+
+	/*
+	 *  PLL lock time required per OMAP-L138 datasheet is
+	 * (2000 * prediv)/sqrt(pllm) OSCIN cycles. We approximate sqrt(pllm)
+	 * as 4 and OSCIN cycle as 25 MHz.
+	 */
+	if (prediv) {
+		locktime = ((2000 * prediv) / 100);
+		prediv = (prediv - 1) | PLLDIV_EN;
+	} else {
+		locktime = 20;
+	}
+	if (postdiv)
+		postdiv = (postdiv - 1) | PLLDIV_EN;
+	if (mult)
+		mult = mult - 1;
+
+	ctrl = __raw_readl(pll->base + PLLCTL);
+
+	/* Switch the PLL to bypass mode */
+	ctrl &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN);
+	__raw_writel(ctrl, pll->base + PLLCTL);
+
+	/*
+	 * Wait for 4 OSCIN/CLKIN cycles to ensure that the PLLC has switched
+	 * to bypass mode. Delay of 1us ensures we are good for all > 4MHz
+	 * OSCIN/CLKIN inputs. Typically the input is ~25MHz.
+	 */
+	udelay(1);
+
+	/* Reset and enable PLL */
+	ctrl &= ~(PLLCTL_PLLRST | PLLCTL_PLLDIS);
+	__raw_writel(ctrl, pll->base + PLLCTL);
+
+	if (pll->flags & PLL_HAS_PREDIV)
+		__raw_writel(prediv, pll->base + PREDIV);
+
+	__raw_writel(mult, pll->base + PLLM);
+
+	if (pll->flags & PLL_HAS_POSTDIV)
+		__raw_writel(postdiv, pll->base + POSTDIV);
+
+	/*
+	 * Wait for PLL to reset properly, OMAP-L138 datasheet says
+	 * 'min' time = 125ns
+	 */
+	udelay(1);
+
+	/* Bring PLL out of reset */
+	ctrl |= PLLCTL_PLLRST;
+	__raw_writel(ctrl, pll->base + PLLCTL);
+
+	udelay(locktime);
+
+	/* Remove PLL from bypass mode */
+	ctrl |= PLLCTL_PLLEN;
+	__raw_writel(ctrl, pll->base + PLLCTL);
+
+	return 0;
+}
+EXPORT_SYMBOL(davinci_set_pllrate);
+
 int __init davinci_clk_init(struct davinci_clk *clocks)
   {
 	struct davinci_clk *c;
@@ -281,12 +436,23 @@
 	for (c = clocks; c->lk.clk; c++) {
 		clk = c->lk.clk;
 
-		if (clk->pll_data)
-			clk_pll_init(clk);
+		if (!clk->recalc) {
 
-		/* Calculate rates for PLL-derived clocks */
-		else if (clk->flags & CLK_PLL)
-			clk_sysclk_recalc(clk);
+			/* Check if clock is a PLL */
+			if (clk->pll_data)
+				clk->recalc = clk_pllclk_recalc;
+
+			/* Else, if it is a PLL-derived clock */
+			else if (clk->flags & CLK_PLL)
+				clk->recalc = clk_sysclk_recalc;
+
+			/* Otherwise, it is a leaf clock (PSC clock) */
+			else if (clk->parent)
+				clk->recalc = clk_leafclk_recalc;
+		}
+
+		if (clk->recalc)
+			clk->rate = clk->recalc(clk);
 
 		if (clk->lpsc)
 			clk->flags |= CLK_PSC;
@@ -352,9 +518,8 @@
 	/* REVISIT show device associations too */
 
 	/* cost is now small, but not linear... */
-	list_for_each_entry(clk, &clocks, node) {
-		if (clk->parent == parent)
-			dump_clock(s, nest + NEST_DELTA, clk);
+	list_for_each_entry(clk, &parent->children, childnode) {
+		dump_clock(s, nest + NEST_DELTA, clk);
 	}
 }
 
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
index 27233cb..c92d77a 100644
--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -22,6 +22,10 @@
 /* PLL/Reset register offsets */
 #define PLLCTL          0x100
 #define PLLCTL_PLLEN    BIT(0)
+#define PLLCTL_PLLPWRDN	BIT(1)
+#define PLLCTL_PLLRST	BIT(3)
+#define PLLCTL_PLLDIS	BIT(4)
+#define PLLCTL_PLLENSRC	BIT(5)
 #define PLLCTL_CLKMODE  BIT(8)
 
 #define PLLM		0x110
@@ -65,15 +69,20 @@
 	const char		*name;
 	unsigned long		rate;
 	u8			usecount;
-	u8			flags;
 	u8			lpsc;
-	u8			psc_ctlr;
+	u8			gpsc;
+	u32			flags;
 	struct clk              *parent;
+	struct list_head	children; 	/* list of children */
+	struct list_head	childnode;	/* parent's child list node */
 	struct pll_data         *pll_data;
 	u32                     div_reg;
+	unsigned long (*recalc) (struct clk *);
+	int (*set_rate) (struct clk *clk, unsigned long rate);
+	int (*round_rate) (struct clk *clk, unsigned long rate);
 };
 
-/* Clock flags */
+/* Clock flags: SoC-specific flags start at BIT(16) */
 #define ALWAYS_ENABLED		BIT(1)
 #define CLK_PSC                 BIT(2)
 #define PSC_DSP                 BIT(3) /* PSC uses DSP domain, not ARM */
@@ -94,6 +103,8 @@
 	}
 
 int davinci_clk_init(struct davinci_clk *clocks);
+int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
+				unsigned int mult, unsigned int postdiv);
 
 extern struct platform_device davinci_wdt_device;
 
diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c
index 61ede19..c2de94c 100644
--- a/arch/arm/mach-davinci/common.c
+++ b/arch/arm/mach-davinci/common.c
@@ -86,6 +86,8 @@
 	dip = davinci_get_id(davinci_soc_info.jtag_id);
 	if (!dip) {
 		ret = -EINVAL;
+		pr_err("Unknown DaVinci JTAG ID 0x%x\n",
+						davinci_soc_info.jtag_id);
 		goto err;
 	}
 
@@ -104,5 +106,5 @@
 	return;
 
 err:
-	pr_err("davinci_common_init: SoC Initialization failed\n");
+	panic("davinci_common_init: SoC Initialization failed\n");
 }
diff --git a/arch/arm/mach-davinci/cp_intc.c b/arch/arm/mach-davinci/cp_intc.c
index 96c8e97..52b287c 100644
--- a/arch/arm/mach-davinci/cp_intc.c
+++ b/arch/arm/mach-davinci/cp_intc.c
@@ -10,9 +10,6 @@
  */
 
 #include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
 #include <linux/irq.h>
 #include <linux/io.h>
 
diff --git a/arch/arm/mach-davinci/cpufreq.c b/arch/arm/mach-davinci/cpufreq.c
new file mode 100644
index 0000000..d3fa6de
--- /dev/null
+++ b/arch/arm/mach-davinci/cpufreq.c
@@ -0,0 +1,226 @@
+/*
+ * CPU frequency scaling for DaVinci
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Based on linux/arch/arm/plat-omap/cpu-omap.c. Original Copyright follows:
+ *
+ *  Copyright (C) 2005 Nokia Corporation
+ *  Written by Tony Lindgren <tony@atomide.com>
+ *
+ *  Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Updated to support OMAP3
+ * Rajendra Nayak <rnayak@ti.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.
+ */
+#include <linux/types.h>
+#include <linux/cpufreq.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+#include <mach/cpufreq.h>
+#include <mach/common.h>
+
+#include "clock.h"
+
+struct davinci_cpufreq {
+	struct device *dev;
+	struct clk *armclk;
+};
+static struct davinci_cpufreq cpufreq;
+
+static int davinci_verify_speed(struct cpufreq_policy *policy)
+{
+	struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
+	struct cpufreq_frequency_table *freq_table = pdata->freq_table;
+	struct clk *armclk = cpufreq.armclk;
+
+	if (freq_table)
+		return cpufreq_frequency_table_verify(policy, freq_table);
+
+	if (policy->cpu)
+		return -EINVAL;
+
+	cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+				     policy->cpuinfo.max_freq);
+
+	policy->min = clk_round_rate(armclk, policy->min * 1000) / 1000;
+	policy->max = clk_round_rate(armclk, policy->max * 1000) / 1000;
+	cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+						policy->cpuinfo.max_freq);
+	return 0;
+}
+
+static unsigned int davinci_getspeed(unsigned int cpu)
+{
+	if (cpu)
+		return 0;
+
+	return clk_get_rate(cpufreq.armclk) / 1000;
+}
+
+static int davinci_target(struct cpufreq_policy *policy,
+				unsigned int target_freq, unsigned int relation)
+{
+	int ret = 0;
+	unsigned int idx;
+	struct cpufreq_freqs freqs;
+	struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
+	struct clk *armclk = cpufreq.armclk;
+
+	/*
+	 * Ensure desired rate is within allowed range.  Some govenors
+	 * (ondemand) will just pass target_freq=0 to get the minimum.
+	 */
+	if (target_freq < policy->cpuinfo.min_freq)
+		target_freq = policy->cpuinfo.min_freq;
+	if (target_freq > policy->cpuinfo.max_freq)
+		target_freq = policy->cpuinfo.max_freq;
+
+	freqs.old = davinci_getspeed(0);
+	freqs.new = clk_round_rate(armclk, target_freq * 1000) / 1000;
+	freqs.cpu = 0;
+
+	if (freqs.old == freqs.new)
+		return ret;
+
+	cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER,
+			dev_driver_string(cpufreq.dev),
+			"transition: %u --> %u\n", freqs.old, freqs.new);
+
+	ret = cpufreq_frequency_table_target(policy, pdata->freq_table,
+						freqs.new, relation, &idx);
+	if (ret)
+		return -EINVAL;
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+	/* if moving to higher frequency, up the voltage beforehand */
+	if (pdata->set_voltage && freqs.new > freqs.old)
+		pdata->set_voltage(idx);
+
+	ret = clk_set_rate(armclk, idx);
+
+	/* if moving to lower freq, lower the voltage after lowering freq */
+	if (pdata->set_voltage && freqs.new < freqs.old)
+		pdata->set_voltage(idx);
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+	return ret;
+}
+
+static int __init davinci_cpu_init(struct cpufreq_policy *policy)
+{
+	int result = 0;
+	struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
+	struct cpufreq_frequency_table *freq_table = pdata->freq_table;
+
+	if (policy->cpu != 0)
+		return -EINVAL;
+
+	/* Finish platform specific initialization */
+	if (pdata->init) {
+		result = pdata->init();
+		if (result)
+			return result;
+	}
+
+	policy->cur = policy->min = policy->max = davinci_getspeed(0);
+
+	if (freq_table) {
+		result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+		if (!result)
+			cpufreq_frequency_table_get_attr(freq_table,
+							policy->cpu);
+	} else {
+		policy->cpuinfo.min_freq = policy->min;
+		policy->cpuinfo.max_freq = policy->max;
+	}
+
+	policy->min = policy->cpuinfo.min_freq;
+	policy->max = policy->cpuinfo.max_freq;
+	policy->cur = davinci_getspeed(0);
+
+	/*
+	 * Time measurement across the target() function yields ~1500-1800us
+	 * time taken with no drivers on notification list.
+	 * Setting the latency to 2000 us to accomodate addition of drivers
+	 * to pre/post change notification list.
+	 */
+	policy->cpuinfo.transition_latency = 2000 * 1000;
+	return 0;
+}
+
+static int davinci_cpu_exit(struct cpufreq_policy *policy)
+{
+	cpufreq_frequency_table_put_attr(policy->cpu);
+	return 0;
+}
+
+static struct freq_attr *davinci_cpufreq_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+static struct cpufreq_driver davinci_driver = {
+	.flags		= CPUFREQ_STICKY,
+	.verify		= davinci_verify_speed,
+	.target		= davinci_target,
+	.get		= davinci_getspeed,
+	.init		= davinci_cpu_init,
+	.exit		= davinci_cpu_exit,
+	.name		= "davinci",
+	.attr		= davinci_cpufreq_attr,
+};
+
+static int __init davinci_cpufreq_probe(struct platform_device *pdev)
+{
+	struct davinci_cpufreq_config *pdata = pdev->dev.platform_data;
+
+	if (!pdata)
+		return -EINVAL;
+	if (!pdata->freq_table)
+		return -EINVAL;
+
+	cpufreq.dev = &pdev->dev;
+
+	cpufreq.armclk = clk_get(NULL, "arm");
+	if (IS_ERR(cpufreq.armclk)) {
+		dev_err(cpufreq.dev, "Unable to get ARM clock\n");
+		return PTR_ERR(cpufreq.armclk);
+	}
+
+	return cpufreq_register_driver(&davinci_driver);
+}
+
+static int __exit davinci_cpufreq_remove(struct platform_device *pdev)
+{
+	clk_put(cpufreq.armclk);
+
+	return cpufreq_unregister_driver(&davinci_driver);
+}
+
+static struct platform_driver davinci_cpufreq_driver = {
+	.driver = {
+		.name	 = "cpufreq-davinci",
+		.owner	 = THIS_MODULE,
+	},
+	.remove = __exit_p(davinci_cpufreq_remove),
+};
+
+static int __init davinci_cpufreq_init(void)
+{
+	return platform_driver_probe(&davinci_cpufreq_driver,
+							davinci_cpufreq_probe);
+}
+late_initcall(davinci_cpufreq_init);
+
diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c
new file mode 100644
index 0000000..97a90f3
--- /dev/null
+++ b/arch/arm/mach-davinci/cpuidle.c
@@ -0,0 +1,197 @@
+/*
+ * CPU idle for DaVinci SoCs
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated. http://www.ti.com/
+ *
+ * Derived from Marvell Kirkwood CPU idle code
+ * (arch/arm/mach-kirkwood/cpuidle.c)
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/cpuidle.h>
+#include <linux/io.h>
+#include <asm/proc-fns.h>
+
+#include <mach/cpuidle.h>
+
+#define DAVINCI_CPUIDLE_MAX_STATES	2
+
+struct davinci_ops {
+	void (*enter) (u32 flags);
+	void (*exit) (u32 flags);
+	u32 flags;
+};
+
+/* fields in davinci_ops.flags */
+#define DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN	BIT(0)
+
+static struct cpuidle_driver davinci_idle_driver = {
+	.name	= "cpuidle-davinci",
+	.owner	= THIS_MODULE,
+};
+
+static DEFINE_PER_CPU(struct cpuidle_device, davinci_cpuidle_device);
+static void __iomem *ddr2_reg_base;
+
+#define DDR2_SDRCR_OFFSET	0xc
+#define DDR2_SRPD_BIT		BIT(23)
+#define DDR2_LPMODEN_BIT	BIT(31)
+
+static void davinci_save_ddr_power(int enter, bool pdown)
+{
+	u32 val;
+
+	val = __raw_readl(ddr2_reg_base + DDR2_SDRCR_OFFSET);
+
+	if (enter) {
+		if (pdown)
+			val |= DDR2_SRPD_BIT;
+		else
+			val &= ~DDR2_SRPD_BIT;
+		val |= DDR2_LPMODEN_BIT;
+	} else {
+		val &= ~(DDR2_SRPD_BIT | DDR2_LPMODEN_BIT);
+	}
+
+	__raw_writel(val, ddr2_reg_base + DDR2_SDRCR_OFFSET);
+}
+
+static void davinci_c2state_enter(u32 flags)
+{
+	davinci_save_ddr_power(1, !!(flags & DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN));
+}
+
+static void davinci_c2state_exit(u32 flags)
+{
+	davinci_save_ddr_power(0, !!(flags & DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN));
+}
+
+static struct davinci_ops davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = {
+	[1] = {
+		.enter	= davinci_c2state_enter,
+		.exit	= davinci_c2state_exit,
+	},
+};
+
+/* Actual code that puts the SoC in different idle states */
+static int davinci_enter_idle(struct cpuidle_device *dev,
+						struct cpuidle_state *state)
+{
+	struct davinci_ops *ops = cpuidle_get_statedata(state);
+	struct timeval before, after;
+	int idle_time;
+
+	local_irq_disable();
+	do_gettimeofday(&before);
+
+	if (ops && ops->enter)
+		ops->enter(ops->flags);
+	/* Wait for interrupt state */
+	cpu_do_idle();
+	if (ops && ops->exit)
+		ops->exit(ops->flags);
+
+	do_gettimeofday(&after);
+	local_irq_enable();
+	idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
+			(after.tv_usec - before.tv_usec);
+	return idle_time;
+}
+
+static int __init davinci_cpuidle_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct cpuidle_device *device;
+	struct davinci_cpuidle_config *pdata = pdev->dev.platform_data;
+	struct resource *ddr2_regs;
+	resource_size_t len;
+
+	device = &per_cpu(davinci_cpuidle_device, smp_processor_id());
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "cannot get platform data\n");
+		return -ENOENT;
+	}
+
+	ddr2_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!ddr2_regs) {
+		dev_err(&pdev->dev, "cannot get DDR2 controller register base");
+		return -ENODEV;
+	}
+
+	len = resource_size(ddr2_regs);
+
+	ddr2_regs = request_mem_region(ddr2_regs->start, len, ddr2_regs->name);
+	if (!ddr2_regs)
+		return -EBUSY;
+
+	ddr2_reg_base = ioremap(ddr2_regs->start, len);
+	if (!ddr2_reg_base) {
+		ret = -ENOMEM;
+		goto ioremap_fail;
+	}
+
+	ret = cpuidle_register_driver(&davinci_idle_driver);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register driver\n");
+		goto driver_register_fail;
+	}
+
+	/* Wait for interrupt state */
+	device->states[0].enter = davinci_enter_idle;
+	device->states[0].exit_latency = 1;
+	device->states[0].target_residency = 10000;
+	device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
+	strcpy(device->states[0].name, "WFI");
+	strcpy(device->states[0].desc, "Wait for interrupt");
+
+	/* Wait for interrupt and DDR self refresh state */
+	device->states[1].enter = davinci_enter_idle;
+	device->states[1].exit_latency = 10;
+	device->states[1].target_residency = 10000;
+	device->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
+	strcpy(device->states[1].name, "DDR SR");
+	strcpy(device->states[1].desc, "WFI and DDR Self Refresh");
+	if (pdata->ddr2_pdown)
+		davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN;
+	cpuidle_set_statedata(&device->states[1], &davinci_states[1]);
+
+	device->state_count = DAVINCI_CPUIDLE_MAX_STATES;
+
+	ret = cpuidle_register_device(device);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register device\n");
+		goto device_register_fail;
+	}
+
+	return 0;
+
+device_register_fail:
+	cpuidle_unregister_driver(&davinci_idle_driver);
+driver_register_fail:
+	iounmap(ddr2_reg_base);
+ioremap_fail:
+	release_mem_region(ddr2_regs->start, len);
+	return ret;
+}
+
+static struct platform_driver davinci_cpuidle_driver = {
+	.driver = {
+		.name	= "cpuidle-davinci",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init davinci_cpuidle_init(void)
+{
+	return platform_driver_probe(&davinci_cpuidle_driver,
+						davinci_cpuidle_probe);
+}
+device_initcall(davinci_cpuidle_init);
+
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index 19b2748..b22b5cf 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -8,22 +8,17 @@
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
-#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/clk.h>
-#include <linux/platform_device.h>
 
 #include <asm/mach/map.h>
 
-#include <mach/clock.h>
 #include <mach/psc.h>
-#include <mach/mux.h>
 #include <mach/irqs.h>
 #include <mach/cputype.h>
 #include <mach/common.h>
 #include <mach/time.h>
 #include <mach/da8xx.h>
-#include <mach/asp.h>
 
 #include "clock.h"
 #include "mux.h"
@@ -193,14 +188,14 @@
 	.name		= "uart1",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_UART1,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk uart2_clk = {
 	.name		= "uart2",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_UART2,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk spi0_clk = {
@@ -213,98 +208,98 @@
 	.name		= "spi1",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_SPI1,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk ecap0_clk = {
 	.name		= "ecap0",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_ECAP,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk ecap1_clk = {
 	.name		= "ecap1",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_ECAP,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk ecap2_clk = {
 	.name		= "ecap2",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_ECAP,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk pwm0_clk = {
 	.name		= "pwm0",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_PWM,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk pwm1_clk = {
 	.name		= "pwm1",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_PWM,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk pwm2_clk = {
 	.name		= "pwm2",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_PWM,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk eqep0_clk = {
 	.name		= "eqep0",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA830_LPSC1_EQEP,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk eqep1_clk = {
 	.name		= "eqep1",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA830_LPSC1_EQEP,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk lcdc_clk = {
 	.name		= "lcdc",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_LCDC,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk mcasp0_clk = {
 	.name		= "mcasp0",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_McASP0,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk mcasp1_clk = {
 	.name		= "mcasp1",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA830_LPSC1_McASP1,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk mcasp2_clk = {
 	.name		= "mcasp2",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA830_LPSC1_McASP2,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk usb20_clk = {
 	.name		= "usb20",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_USB20,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk aemif_clk = {
@@ -332,36 +327,36 @@
 	.name		= "emac",
 	.parent		= &pll0_sysclk4,
 	.lpsc		= DA8XX_LPSC1_CPGMAC,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk gpio_clk = {
 	.name		= "gpio",
 	.parent		= &pll0_sysclk4,
 	.lpsc		= DA8XX_LPSC1_GPIO,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk i2c1_clk = {
 	.name		= "i2c1",
 	.parent		= &pll0_sysclk4,
 	.lpsc		= DA8XX_LPSC1_I2C,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk usb11_clk = {
 	.name		= "usb11",
 	.parent		= &pll0_sysclk4,
 	.lpsc		= DA8XX_LPSC1_USB11,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk emif3_clk = {
 	.name		= "emif3",
 	.parent		= &pll0_sysclk5,
 	.lpsc		= DA8XX_LPSC1_EMIF3C,
+	.gpsc		= 1,
 	.flags		= ALWAYS_ENABLED,
-	.psc_ctlr	= 1,
 };
 
 static struct clk arm_clk = {
@@ -411,7 +406,7 @@
 	CLK(NULL,		"pwm2",		&pwm2_clk),
 	CLK("eqep.0",		NULL,		&eqep0_clk),
 	CLK("eqep.1",		NULL,		&eqep1_clk),
-	CLK("da830_lcdc",	NULL,		&lcdc_clk),
+	CLK("da8xx_lcdc.0",	NULL,		&lcdc_clk),
 	CLK("davinci-mcasp.0",	NULL,		&mcasp0_clk),
 	CLK("davinci-mcasp.1",	NULL,		&mcasp1_clk),
 	CLK("davinci-mcasp.2",	NULL,		&mcasp2_clk),
@@ -1143,7 +1138,21 @@
 		.part_no	= 0xb7df,
 		.manufacturer	= 0x017,	/* 0x02f >> 1 */
 		.cpu_id		= DAVINCI_CPU_ID_DA830,
-		.name		= "da830/omap l137",
+		.name		= "da830/omap-l137 rev1.0",
+	},
+	{
+		.variant	= 0x8,
+		.part_no	= 0xb7df,
+		.manufacturer	= 0x017,
+		.cpu_id		= DAVINCI_CPU_ID_DA830,
+		.name		= "da830/omap-l137 rev1.1",
+	},
+	{
+		.variant	= 0x9,
+		.part_no	= 0xb7df,
+		.manufacturer	= 0x017,
+		.cpu_id		= DAVINCI_CPU_ID_DA830,
+		.name		= "da830/omap-l137 rev2.0",
 	},
 };
 
@@ -1178,13 +1187,11 @@
 static struct davinci_soc_info davinci_soc_info_da830 = {
 	.io_desc		= da830_io_desc,
 	.io_desc_num		= ARRAY_SIZE(da830_io_desc),
-	.jtag_id_base		= IO_ADDRESS(DA8XX_JTAG_ID_REG),
 	.ids			= da830_ids,
 	.ids_num		= ARRAY_SIZE(da830_ids),
 	.cpu_clks		= da830_clks,
 	.psc_bases		= da830_psc_bases,
 	.psc_bases_num		= ARRAY_SIZE(da830_psc_bases),
-	.pinmux_base		= IO_ADDRESS(DA8XX_BOOT_CFG_BASE + 0x120),
 	.pinmux_pins		= da830_pins,
 	.pinmux_pins_num	= ARRAY_SIZE(da830_pins),
 	.intc_base		= (void __iomem *)DA8XX_CP_INTC_VIRT,
@@ -1201,5 +1208,13 @@
 
 void __init da830_init(void)
 {
+	da8xx_syscfg_base = ioremap(DA8XX_SYSCFG_BASE, SZ_4K);
+	if (WARN(!da8xx_syscfg_base, "Unable to map syscfg module"))
+		return;
+
+	davinci_soc_info_da830.jtag_id_base =
+					DA8XX_SYSCFG_VIRT(DA8XX_JTAG_ID_REG);
+	davinci_soc_info_da830.pinmux_base = DA8XX_SYSCFG_VIRT(0x120);
+
 	davinci_common_init(&davinci_soc_info_da830);
 }
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 192d719..717806c 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -11,31 +11,41 @@
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
-#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/clk.h>
 #include <linux/platform_device.h>
+#include <linux/cpufreq.h>
+#include <linux/regulator/consumer.h>
 
 #include <asm/mach/map.h>
 
-#include <mach/clock.h>
 #include <mach/psc.h>
-#include <mach/mux.h>
 #include <mach/irqs.h>
 #include <mach/cputype.h>
 #include <mach/common.h>
 #include <mach/time.h>
 #include <mach/da8xx.h>
+#include <mach/cpufreq.h>
 
 #include "clock.h"
 #include "mux.h"
 
+/* SoC specific clock flags */
+#define DA850_CLK_ASYNC3	BIT(16)
+
 #define DA850_PLL1_BASE		0x01e1a000
 #define DA850_TIMER64P2_BASE	0x01f0c000
 #define DA850_TIMER64P3_BASE	0x01f0d000
 
 #define DA850_REF_FREQ		24000000
 
+#define CFGCHIP3_ASYNC3_CLKSRC	BIT(4)
+#define CFGCHIP0_PLL_MASTER_LOCK	BIT(4)
+
+static int da850_set_armrate(struct clk *clk, unsigned long rate);
+static int da850_round_armrate(struct clk *clk, unsigned long rate);
+static int da850_set_pll0rate(struct clk *clk, unsigned long armrate);
+
 static struct pll_data pll0_data = {
 	.num		= 1,
 	.phys_base	= DA8XX_PLL0_BASE,
@@ -52,6 +62,7 @@
 	.parent		= &ref_clk,
 	.pll_data	= &pll0_data,
 	.flags		= CLK_PLL,
+	.set_rate	= da850_set_pll0rate,
 };
 
 static struct clk pll0_aux_clk = {
@@ -210,16 +221,16 @@
 	.name		= "tpcc1",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA850_LPSC1_TPCC1,
+	.gpsc		= 1,
 	.flags		= CLK_PSC | ALWAYS_ENABLED,
-	.psc_ctlr	= 1,
 };
 
 static struct clk tptc2_clk = {
 	.name		= "tptc2",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA850_LPSC1_TPTC2,
+	.gpsc		= 1,
 	.flags		= ALWAYS_ENABLED,
-	.psc_ctlr	= 1,
 };
 
 static struct clk uart0_clk = {
@@ -232,14 +243,16 @@
 	.name		= "uart1",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_UART1,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
+	.flags		= DA850_CLK_ASYNC3,
 };
 
 static struct clk uart2_clk = {
 	.name		= "uart2",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_UART2,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
+	.flags		= DA850_CLK_ASYNC3,
 };
 
 static struct clk aintc_clk = {
@@ -253,22 +266,22 @@
 	.name		= "gpio",
 	.parent		= &pll0_sysclk4,
 	.lpsc		= DA8XX_LPSC1_GPIO,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk i2c1_clk = {
 	.name		= "i2c1",
 	.parent		= &pll0_sysclk4,
 	.lpsc		= DA8XX_LPSC1_I2C,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk emif3_clk = {
 	.name		= "emif3",
 	.parent		= &pll0_sysclk5,
 	.lpsc		= DA8XX_LPSC1_EMIF3C,
+	.gpsc		= 1,
 	.flags		= ALWAYS_ENABLED,
-	.psc_ctlr	= 1,
 };
 
 static struct clk arm_clk = {
@@ -276,6 +289,8 @@
 	.parent		= &pll0_sysclk6,
 	.lpsc		= DA8XX_LPSC0_ARM,
 	.flags		= ALWAYS_ENABLED,
+	.set_rate	= da850_set_armrate,
+	.round_rate	= da850_round_armrate,
 };
 
 static struct clk rmii_clk = {
@@ -287,21 +302,22 @@
 	.name		= "emac",
 	.parent		= &pll0_sysclk4,
 	.lpsc		= DA8XX_LPSC1_CPGMAC,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk mcasp_clk = {
 	.name		= "mcasp",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_McASP0,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
+	.flags		= DA850_CLK_ASYNC3,
 };
 
 static struct clk lcdc_clk = {
 	.name		= "lcdc",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_LCDC,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk mmcsd_clk = {
@@ -404,6 +420,14 @@
 	MUX_CFG(DA850, MII_RXD_0,	3,	28,	15,	8,	false)
 	MUX_CFG(DA850, MDIO_CLK,	4,	0,	15,	8,	false)
 	MUX_CFG(DA850, MDIO_D,		4,	4,	15,	8,	false)
+	MUX_CFG(DA850, RMII_TXD_0,	14,	12,	15,	8,	false)
+	MUX_CFG(DA850, RMII_TXD_1,	14,	8,	15,	8,	false)
+	MUX_CFG(DA850, RMII_TXEN,	14,	16,	15,	8,	false)
+	MUX_CFG(DA850, RMII_CRS_DV,	15,	4,	15,	8,	false)
+	MUX_CFG(DA850, RMII_RXD_0,	14,	24,	15,	8,	false)
+	MUX_CFG(DA850, RMII_RXD_1,	14,	20,	15,	8,	false)
+	MUX_CFG(DA850, RMII_RXER,	14,	28,	15,	8,	false)
+	MUX_CFG(DA850, RMII_MHZ_50_CLK,	15,	0,	15,	0,	false)
 	/* McASP function */
 	MUX_CFG(DA850,	ACLKR,		0,	0,	15,	1,	false)
 	MUX_CFG(DA850,	ACLKX,		0,	4,	15,	1,	false)
@@ -506,8 +530,9 @@
 	MUX_CFG(DA850, EMA_WAIT_1,	6,	24,	15,	1,	false)
 	MUX_CFG(DA850, NEMA_CS_2,	7,	0,	15,	1,	false)
 	/* GPIO function */
+	MUX_CFG(DA850, GPIO2_6,		6,	4,	15,	8,	false)
+	MUX_CFG(DA850, GPIO2_8,		5,	28,	15,	8,	false)
 	MUX_CFG(DA850, GPIO2_15,	5,	0,	15,	8,	false)
-	MUX_CFG(DA850, GPIO8_10,	18,	28,	15,	8,	false)
 	MUX_CFG(DA850, GPIO4_0,		10,	28,	15,	8,	false)
 	MUX_CFG(DA850, GPIO4_1,		10,	24,	15,	8,	false)
 #endif
@@ -547,6 +572,14 @@
 	-1
 };
 
+const short da850_rmii_pins[] __initdata = {
+	DA850_RMII_TXD_0, DA850_RMII_TXD_1, DA850_RMII_TXEN,
+	DA850_RMII_CRS_DV, DA850_RMII_RXD_0, DA850_RMII_RXD_1,
+	DA850_RMII_RXER, DA850_RMII_MHZ_50_CLK, DA850_MDIO_CLK,
+	DA850_MDIO_D,
+	-1
+};
+
 const short da850_mcasp_pins[] __initdata = {
 	DA850_AHCLKX, DA850_ACLKX, DA850_AFSX,
 	DA850_AHCLKR, DA850_ACLKR, DA850_AFSR, DA850_AMUTE,
@@ -555,12 +588,11 @@
 };
 
 const short da850_lcdcntl_pins[] __initdata = {
-	DA850_LCD_D_1, DA850_LCD_D_2, DA850_LCD_D_3, DA850_LCD_D_4,
-	DA850_LCD_D_5, DA850_LCD_D_6, DA850_LCD_D_7, DA850_LCD_D_8,
-	DA850_LCD_D_9, DA850_LCD_D_10, DA850_LCD_D_11, DA850_LCD_D_12,
-	DA850_LCD_D_13, DA850_LCD_D_14, DA850_LCD_D_15, DA850_LCD_PCLK,
-	DA850_LCD_HSYNC, DA850_LCD_VSYNC, DA850_NLCD_AC_ENB_CS, DA850_GPIO2_15,
-	DA850_GPIO8_10,
+	DA850_LCD_D_0, DA850_LCD_D_1, DA850_LCD_D_2, DA850_LCD_D_3,
+	DA850_LCD_D_4, DA850_LCD_D_5, DA850_LCD_D_6, DA850_LCD_D_7,
+	DA850_LCD_D_8, DA850_LCD_D_9, DA850_LCD_D_10, DA850_LCD_D_11,
+	DA850_LCD_D_12, DA850_LCD_D_13, DA850_LCD_D_14, DA850_LCD_D_15,
+	DA850_LCD_PCLK, DA850_LCD_HSYNC, DA850_LCD_VSYNC, DA850_NLCD_AC_ENB_CS,
 	-1
 };
 
@@ -790,16 +822,221 @@
 	.clocksource_id	= T0_TOP,
 };
 
+static void da850_set_async3_src(int pllnum)
+{
+	struct clk *clk, *newparent = pllnum ? &pll1_sysclk2 : &pll0_sysclk2;
+	struct davinci_clk *c;
+	unsigned int v;
+	int ret;
+
+	for (c = da850_clks; c->lk.clk; c++) {
+		clk = c->lk.clk;
+		if (clk->flags & DA850_CLK_ASYNC3) {
+			ret = clk_set_parent(clk, newparent);
+			WARN(ret, "DA850: unable to re-parent clock %s",
+								clk->name);
+		}
+       }
+
+	v = __raw_readl(DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP3_REG));
+	if (pllnum)
+		v |= CFGCHIP3_ASYNC3_CLKSRC;
+	else
+		v &= ~CFGCHIP3_ASYNC3_CLKSRC;
+	__raw_writel(v, DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP3_REG));
+}
+
+#ifdef CONFIG_CPU_FREQ
+/*
+ * Notes:
+ * According to the TRM, minimum PLLM results in maximum power savings.
+ * The OPP definitions below should keep the PLLM as low as possible.
+ *
+ * The output of the PLLM must be between 400 to 600 MHz.
+ * This rules out prediv of anything but divide-by-one for 24Mhz OSC input.
+ */
+struct da850_opp {
+	unsigned int	freq;	/* in KHz */
+	unsigned int	prediv;
+	unsigned int	mult;
+	unsigned int	postdiv;
+	unsigned int	cvdd_min; /* in uV */
+	unsigned int	cvdd_max; /* in uV */
+};
+
+static const struct da850_opp da850_opp_300 = {
+	.freq		= 300000,
+	.prediv		= 1,
+	.mult		= 25,
+	.postdiv	= 2,
+	.cvdd_min	= 1140000,
+	.cvdd_max	= 1320000,
+};
+
+static const struct da850_opp da850_opp_200 = {
+	.freq		= 200000,
+	.prediv		= 1,
+	.mult		= 25,
+	.postdiv	= 3,
+	.cvdd_min	= 1050000,
+	.cvdd_max	= 1160000,
+};
+
+static const struct da850_opp da850_opp_96 = {
+	.freq		= 96000,
+	.prediv		= 1,
+	.mult		= 20,
+	.postdiv	= 5,
+	.cvdd_min	= 950000,
+	.cvdd_max	= 1050000,
+};
+
+#define OPP(freq) 		\
+	{				\
+		.index = (unsigned int) &da850_opp_##freq,	\
+		.frequency = freq * 1000, \
+	}
+
+static struct cpufreq_frequency_table da850_freq_table[] = {
+	OPP(300),
+	OPP(200),
+	OPP(96),
+	{
+		.index		= 0,
+		.frequency	= CPUFREQ_TABLE_END,
+	},
+};
+
+#ifdef CONFIG_REGULATOR
+static struct regulator *cvdd;
+
+static int da850_set_voltage(unsigned int index)
+{
+	struct da850_opp *opp;
+
+	if (!cvdd)
+		return -ENODEV;
+
+	opp = (struct da850_opp *) da850_freq_table[index].index;
+
+	return regulator_set_voltage(cvdd, opp->cvdd_min, opp->cvdd_max);
+}
+
+static int da850_regulator_init(void)
+{
+	cvdd = regulator_get(NULL, "cvdd");
+	if (WARN(IS_ERR(cvdd), "Unable to obtain voltage regulator for CVDD;"
+					" voltage scaling unsupported\n")) {
+		return PTR_ERR(cvdd);
+	}
+
+	return 0;
+}
+#endif
+
+static struct davinci_cpufreq_config cpufreq_info = {
+	.freq_table = &da850_freq_table[0],
+#ifdef CONFIG_REGULATOR
+	.init = da850_regulator_init,
+	.set_voltage = da850_set_voltage,
+#endif
+};
+
+static struct platform_device da850_cpufreq_device = {
+	.name			= "cpufreq-davinci",
+	.dev = {
+		.platform_data	= &cpufreq_info,
+	},
+};
+
+int __init da850_register_cpufreq(void)
+{
+	return platform_device_register(&da850_cpufreq_device);
+}
+
+static int da850_round_armrate(struct clk *clk, unsigned long rate)
+{
+	int i, ret = 0, diff;
+	unsigned int best = (unsigned int) -1;
+
+	rate /= 1000; /* convert to kHz */
+
+	for (i = 0; da850_freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
+		diff = da850_freq_table[i].frequency - rate;
+		if (diff < 0)
+			diff = -diff;
+
+		if (diff < best) {
+			best = diff;
+			ret = da850_freq_table[i].frequency;
+		}
+	}
+
+	return ret * 1000;
+}
+
+static int da850_set_armrate(struct clk *clk, unsigned long index)
+{
+	struct clk *pllclk = &pll0_clk;
+
+	return clk_set_rate(pllclk, index);
+}
+
+static int da850_set_pll0rate(struct clk *clk, unsigned long index)
+{
+	unsigned int prediv, mult, postdiv;
+	struct da850_opp *opp;
+	struct pll_data *pll = clk->pll_data;
+	unsigned int v;
+	int ret;
+
+	opp = (struct da850_opp *) da850_freq_table[index].index;
+	prediv = opp->prediv;
+	mult = opp->mult;
+	postdiv = opp->postdiv;
+
+	/* Unlock writing to PLL registers */
+	v = __raw_readl(DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP0_REG));
+	v &= ~CFGCHIP0_PLL_MASTER_LOCK;
+	__raw_writel(v, DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP0_REG));
+
+	ret = davinci_set_pllrate(pll, prediv, mult, postdiv);
+	if (WARN_ON(ret))
+		return ret;
+
+	return 0;
+}
+#else
+int __init da850_register_cpufreq(void)
+{
+	return 0;
+}
+
+static int da850_set_armrate(struct clk *clk, unsigned long rate)
+{
+	return -EINVAL;
+}
+
+static int da850_set_pll0rate(struct clk *clk, unsigned long armrate)
+{
+	return -EINVAL;
+}
+
+static int da850_round_armrate(struct clk *clk, unsigned long rate)
+{
+	return clk->rate;
+}
+#endif
+
+
 static struct davinci_soc_info davinci_soc_info_da850 = {
 	.io_desc		= da850_io_desc,
 	.io_desc_num		= ARRAY_SIZE(da850_io_desc),
-	.jtag_id_base		= IO_ADDRESS(DA8XX_JTAG_ID_REG),
 	.ids			= da850_ids,
 	.ids_num		= ARRAY_SIZE(da850_ids),
 	.cpu_clks		= da850_clks,
 	.psc_bases		= da850_psc_bases,
 	.psc_bases_num		= ARRAY_SIZE(da850_psc_bases),
-	.pinmux_base		= IO_ADDRESS(DA8XX_BOOT_CFG_BASE + 0x120),
 	.pinmux_pins		= da850_pins,
 	.pinmux_pins_num	= ARRAY_SIZE(da850_pins),
 	.intc_base		= (void __iomem *)DA8XX_CP_INTC_VIRT,
@@ -816,5 +1053,22 @@
 
 void __init da850_init(void)
 {
+	da8xx_syscfg_base = ioremap(DA8XX_SYSCFG_BASE, SZ_4K);
+	if (WARN(!da8xx_syscfg_base, "Unable to map syscfg module"))
+		return;
+
+	davinci_soc_info_da850.jtag_id_base =
+					DA8XX_SYSCFG_VIRT(DA8XX_JTAG_ID_REG);
+	davinci_soc_info_da850.pinmux_base = DA8XX_SYSCFG_VIRT(0x120);
+
 	davinci_common_init(&davinci_soc_info_da850);
+
+	/*
+	 * Move the clock source of Async3 domain to PLL1 SYSCLK2.
+	 * This helps keeping the peripherals on this domain insulated
+	 * from CPU frequency changes caused by DVFS. The firmware sets
+	 * both PLL0 and PLL1 to the same frequency so, there should not
+	 * be any noticible change even in non-DVFS use cases.
+	 */
+	da850_set_async3_src(1);
 }
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index 58ad5b6..dd2d32c 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -10,8 +10,6 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  */
-#include <linux/module.h>
-#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
@@ -21,7 +19,7 @@
 #include <mach/common.h>
 #include <mach/time.h>
 #include <mach/da8xx.h>
-#include <video/da8xx-fb.h>
+#include <mach/cpuidle.h>
 
 #include "clock.h"
 
@@ -30,6 +28,7 @@
 #define DA8XX_TPTC1_BASE		0x01c08400
 #define DA8XX_WDOG_BASE			0x01c21000 /* DA8XX_TIMER64P1_BASE */
 #define DA8XX_I2C0_BASE			0x01c22000
+#define DA8XX_RTC_BASE			0x01C23000
 #define DA8XX_EMAC_CPPI_PORT_BASE	0x01e20000
 #define DA8XX_EMAC_CPGMACSS_BASE	0x01e22000
 #define DA8XX_EMAC_CPGMAC_BASE		0x01e23000
@@ -43,6 +42,8 @@
 #define DA8XX_MDIO_REG_OFFSET		0x4000
 #define DA8XX_EMAC_CTRL_RAM_SIZE	SZ_8K
 
+void __iomem *da8xx_syscfg_base;
+
 static struct plat_serial8250_port da8xx_serial_pdata[] = {
 	{
 		.mapbase	= DA8XX_UART0_BASE,
@@ -282,6 +283,11 @@
 	.resource	= da8xx_emac_resources,
 };
 
+int __init da8xx_register_emac(void)
+{
+	return platform_device_register(&da8xx_emac_device);
+}
+
 static struct resource da830_mcasp1_resources[] = {
 	{
 		.name	= "mcasp1",
@@ -338,12 +344,7 @@
 	.resource	= da850_mcasp_resources,
 };
 
-int __init da8xx_register_emac(void)
-{
-	return platform_device_register(&da8xx_emac_device);
-}
-
-void __init da8xx_init_mcasp(int id, struct snd_platform_data *pdata)
+void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata)
 {
 	/* DA830/OMAP-L137 has 3 instances of McASP */
 	if (cpu_is_davinci_da830() && id == 1) {
@@ -379,10 +380,16 @@
 	.raster_order		= 0,
 };
 
-static struct da8xx_lcdc_platform_data da850_evm_lcdc_pdata = {
-	.manu_name = "sharp",
-	.controller_data = &lcd_cfg,
-	.type = "Sharp_LK043T1DG01",
+struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata = {
+	.manu_name		= "sharp",
+	.controller_data	= &lcd_cfg,
+	.type			= "Sharp_LCD035Q3DG01",
+};
+
+struct da8xx_lcdc_platform_data sharp_lk043t1dg01_pdata = {
+	.manu_name		= "sharp",
+	.controller_data	= &lcd_cfg,
+	.type			= "Sharp_LK043T1DG01",
 };
 
 static struct resource da8xx_lcdc_resources[] = {
@@ -398,19 +405,17 @@
 	},
 };
 
-static struct platform_device da850_lcdc_device = {
+static struct platform_device da8xx_lcdc_device = {
 	.name		= "da8xx_lcdc",
 	.id		= 0,
 	.num_resources	= ARRAY_SIZE(da8xx_lcdc_resources),
 	.resource	= da8xx_lcdc_resources,
-	.dev = {
-		.platform_data = &da850_evm_lcdc_pdata,
-	}
 };
 
-int __init da8xx_register_lcdc(void)
+int __init da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata)
 {
-	return platform_device_register(&da850_lcdc_device);
+	da8xx_lcdc_device.dev.platform_data = pdata;
+	return platform_device_register(&da8xx_lcdc_device);
 }
 
 static struct resource da8xx_mmcsd0_resources[] = {
@@ -448,3 +453,66 @@
 	da8xx_mmcsd0_device.dev.platform_data = config;
 	return platform_device_register(&da8xx_mmcsd0_device);
 }
+
+static struct resource da8xx_rtc_resources[] = {
+	{
+		.start		= DA8XX_RTC_BASE,
+		.end		= DA8XX_RTC_BASE + SZ_4K - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+	{ /* timer irq */
+		.start		= IRQ_DA8XX_RTC,
+		.end		= IRQ_DA8XX_RTC,
+		.flags		= IORESOURCE_IRQ,
+	},
+	{ /* alarm irq */
+		.start		= IRQ_DA8XX_RTC,
+		.end		= IRQ_DA8XX_RTC,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device da8xx_rtc_device = {
+	.name           = "omap_rtc",
+	.id             = -1,
+	.num_resources	= ARRAY_SIZE(da8xx_rtc_resources),
+	.resource	= da8xx_rtc_resources,
+};
+
+int da8xx_register_rtc(void)
+{
+	/* Unlock the rtc's registers */
+	__raw_writel(0x83e70b13, IO_ADDRESS(DA8XX_RTC_BASE + 0x6c));
+	__raw_writel(0x95a4f1e0, IO_ADDRESS(DA8XX_RTC_BASE + 0x70));
+
+	return platform_device_register(&da8xx_rtc_device);
+}
+
+static struct resource da8xx_cpuidle_resources[] = {
+	{
+		.start		= DA8XX_DDR2_CTL_BASE,
+		.end		= DA8XX_DDR2_CTL_BASE + SZ_32K - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+/* DA8XX devices support DDR2 power down */
+static struct davinci_cpuidle_config da8xx_cpuidle_pdata = {
+	.ddr2_pdown	= 1,
+};
+
+
+static struct platform_device da8xx_cpuidle_device = {
+	.name			= "cpuidle-davinci",
+	.num_resources		= ARRAY_SIZE(da8xx_cpuidle_resources),
+	.resource		= da8xx_cpuidle_resources,
+	.dev = {
+		.platform_data	= &da8xx_cpuidle_pdata,
+	},
+};
+
+int __init da8xx_register_cpuidle(void)
+{
+	return platform_device_register(&da8xx_cpuidle_device);
+}
+
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c
index a55b650..1479496 100644
--- a/arch/arm/mach-davinci/devices.c
+++ b/arch/arm/mach-davinci/devices.c
@@ -9,15 +9,11 @@
  * (at your option) any later version.
  */
 
-#include <linux/module.h>
-#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/io.h>
 
-#include <asm/mach/map.h>
-
 #include <mach/hardware.h>
 #include <mach/i2c.h>
 #include <mach/irqs.h>
@@ -177,7 +173,7 @@
 			mmcsd1_resources[0].start = DM365_MMCSD1_BASE;
 			mmcsd1_resources[0].end = DM365_MMCSD1_BASE +
 							SZ_4K - 1;
-			mmcsd0_resources[2].start = IRQ_DM365_SDIOINT1;
+			mmcsd1_resources[2].start = IRQ_DM365_SDIOINT1;
 		} else
 			break;
 
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index 0596700..dedf4d4 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -8,7 +8,6 @@
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
-#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/clk.h>
 #include <linux/serial_8250.h>
@@ -21,7 +20,6 @@
 #include <asm/mach/map.h>
 
 #include <mach/dm355.h>
-#include <mach/clock.h>
 #include <mach/cputype.h>
 #include <mach/edma.h>
 #include <mach/psc.h>
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index e815174..2ec619e 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -12,7 +12,6 @@
  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
-#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/clk.h>
 #include <linux/serial_8250.h>
@@ -23,7 +22,6 @@
 #include <asm/mach/map.h>
 
 #include <mach/dm365.h>
-#include <mach/clock.h>
 #include <mach/cputype.h>
 #include <mach/edma.h>
 #include <mach/psc.h>
@@ -32,6 +30,8 @@
 #include <mach/time.h>
 #include <mach/serial.h>
 #include <mach/common.h>
+#include <mach/asp.h>
+#include <mach/keyscan.h>
 
 #include "clock.h"
 #include "mux.h"
@@ -369,7 +369,7 @@
 
 static struct clk usb_clk = {
 	.name		= "usb",
-	.parent		= &pll2_sysclk1,
+	.parent		= &pll1_aux_clk,
 	.lpsc		= DAVINCI_LPSC_USB,
 };
 
@@ -456,7 +456,7 @@
 	CLK(NULL, "usb", &usb_clk),
 	CLK("davinci_emac.1", NULL, &emac_clk),
 	CLK("voice_codec", NULL, &voicecodec_clk),
-	CLK("soc-audio.0", NULL, &asp0_clk),
+	CLK("davinci-asp.0", NULL, &asp0_clk),
 	CLK(NULL, "rto", &rto_clk),
 	CLK(NULL, "mjcp", &mjcp_clk),
 	CLK(NULL, NULL, NULL),
@@ -531,7 +531,7 @@
 MUX_CFG(DM365,  EMAC_MDIO,	3,   1,     1,    1,     false)
 MUX_CFG(DM365,  EMAC_MDCLK,	3,   0,     1,    1,     false)
 
-MUX_CFG(DM365,	KEYPAD,		2,   0,     0x3f, 0x3f,  false)
+MUX_CFG(DM365,	KEYSCAN,	2,   0,     0x3f, 0x3f,  false)
 
 MUX_CFG(DM365,	PWM0,		1,   0,     3,    2,     false)
 MUX_CFG(DM365,	PWM0_G23,	3,   26,    3,    3,     false)
@@ -603,6 +603,9 @@
 INT_CFG(DM365,  INT_IMX1_DISABLE,    24,    1,    0,     false)
 INT_CFG(DM365,  INT_NSF_ENABLE,      25,    1,    1,     false)
 INT_CFG(DM365,  INT_NSF_DISABLE,     25,    1,    0,     false)
+
+EVT_CFG(DM365,	EVT2_ASP_TX,         0,     1,    0,     false)
+EVT_CFG(DM365,	EVT3_ASP_RX,         1,     1,    0,     false)
 #endif
 };
 
@@ -696,6 +699,7 @@
 	[IRQ_I2C]			= 3,
 	[IRQ_UARTINT0]			= 3,
 	[IRQ_UARTINT1]			= 3,
+	[IRQ_DM365_RTCINT]		= 3,
 	[IRQ_DM365_SPIINT0_0]		= 3,
 	[IRQ_DM365_SPIINT3_0]		= 3,
 	[IRQ_DM365_GPIO0]		= 3,
@@ -806,6 +810,50 @@
 	.resource		= edma_resources,
 };
 
+static struct resource dm365_asp_resources[] = {
+	{
+		.start	= DAVINCI_DM365_ASP0_BASE,
+		.end	= DAVINCI_DM365_ASP0_BASE + SZ_8K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= DAVINCI_DMA_ASP0_TX,
+		.end	= DAVINCI_DMA_ASP0_TX,
+		.flags	= IORESOURCE_DMA,
+	},
+	{
+		.start	= DAVINCI_DMA_ASP0_RX,
+		.end	= DAVINCI_DMA_ASP0_RX,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+static struct platform_device dm365_asp_device = {
+	.name		= "davinci-asp",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(dm365_asp_resources),
+	.resource	= dm365_asp_resources,
+};
+
+static struct resource dm365_rtc_resources[] = {
+	{
+		.start = DM365_RTC_BASE,
+		.end = DM365_RTC_BASE + SZ_1K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_DM365_RTCINT,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dm365_rtc_device = {
+	.name = "rtc_davinci",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(dm365_rtc_resources),
+	.resource = dm365_rtc_resources,
+};
+
 static struct map_desc dm365_io_desc[] = {
 	{
 		.virtual	= IO_VIRT,
@@ -822,6 +870,28 @@
 	},
 };
 
+static struct resource dm365_ks_resources[] = {
+	{
+		/* registers */
+		.start = DM365_KEYSCAN_BASE,
+		.end = DM365_KEYSCAN_BASE + SZ_1K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		/* interrupt */
+		.start = IRQ_DM365_KEYINT,
+		.end = IRQ_DM365_KEYINT,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dm365_ks_device = {
+	.name		= "davinci_keyscan",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(dm365_ks_resources),
+	.resource	= dm365_ks_resources,
+};
+
 /* Contents of JTAG ID register used to identify exact cpu type */
 static struct davinci_id dm365_ids[] = {
 	{
@@ -907,6 +977,33 @@
 	.sram_len		= SZ_32K,
 };
 
+void __init dm365_init_asp(struct snd_platform_data *pdata)
+{
+	davinci_cfg_reg(DM365_MCBSP0_BDX);
+	davinci_cfg_reg(DM365_MCBSP0_X);
+	davinci_cfg_reg(DM365_MCBSP0_BFSX);
+	davinci_cfg_reg(DM365_MCBSP0_BDR);
+	davinci_cfg_reg(DM365_MCBSP0_R);
+	davinci_cfg_reg(DM365_MCBSP0_BFSR);
+	davinci_cfg_reg(DM365_EVT2_ASP_TX);
+	davinci_cfg_reg(DM365_EVT3_ASP_RX);
+	dm365_asp_device.dev.platform_data = pdata;
+	platform_device_register(&dm365_asp_device);
+}
+
+void __init dm365_init_ks(struct davinci_ks_platform_data *pdata)
+{
+	davinci_cfg_reg(DM365_KEYSCAN);
+	dm365_ks_device.dev.platform_data = pdata;
+	platform_device_register(&dm365_ks_device);
+}
+
+void __init dm365_init_rtc(void)
+{
+	davinci_cfg_reg(DM365_INT_PRTCSS);
+	platform_device_register(&dm365_rtc_device);
+}
+
 void __init dm365_init(void)
 {
 	davinci_common_init(&davinci_soc_info_dm365);
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index d6e0fa5..2cd0081 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -8,7 +8,6 @@
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
-#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/clk.h>
 #include <linux/serial_8250.h>
@@ -18,7 +17,6 @@
 #include <asm/mach/map.h>
 
 #include <mach/dm644x.h>
-#include <mach/clock.h>
 #include <mach/cputype.h>
 #include <mach/edma.h>
 #include <mach/irqs.h>
@@ -370,6 +368,11 @@
 MUX_CFG(DM644X, HPIEN_DISABLE,	0,   29,    1,	  0,	 true)
 
 MUX_CFG(DM644X, AEAW,		0,   0,     31,	  31,	 true)
+MUX_CFG(DM644X, AEAW0,		0,   0,     1,	  0,	 true)
+MUX_CFG(DM644X, AEAW1,		0,   1,     1,	  0,	 true)
+MUX_CFG(DM644X, AEAW2,		0,   2,     1,	  0,	 true)
+MUX_CFG(DM644X, AEAW3,		0,   3,     1,	  0,	 true)
+MUX_CFG(DM644X, AEAW4,		0,   4,     1,	  0,	 true)
 
 MUX_CFG(DM644X, MSTK,		1,   9,     1,	  0,	 false)
 
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 0976049..829a44b 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -8,7 +8,6 @@
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
-#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/clk.h>
 #include <linux/serial_8250.h>
@@ -18,7 +17,6 @@
 #include <asm/mach/map.h>
 
 #include <mach/dm646x.h>
-#include <mach/clock.h>
 #include <mach/cputype.h>
 #include <mach/edma.h>
 #include <mach/irqs.h>
@@ -789,7 +787,14 @@
 		.part_no	= 0xb770,
 		.manufacturer	= 0x017,
 		.cpu_id		= DAVINCI_CPU_ID_DM6467,
-		.name		= "dm6467",
+		.name		= "dm6467_rev1.x",
+	},
+	{
+		.variant	= 0x1,
+		.part_no	= 0xb770,
+		.manufacturer	= 0x017,
+		.cpu_id		= DAVINCI_CPU_ID_DM6467,
+		.name		= "dm6467_rev3.x",
 	},
 };
 
diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c
index f2e57d2..648fbb7 100644
--- a/arch/arm/mach-davinci/dma.c
+++ b/arch/arm/mach-davinci/dma.c
@@ -18,22 +18,13 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
-#include <linux/spinlock.h>
-#include <linux/compiler.h>
 #include <linux/io.h>
 
-#include <mach/cputype.h>
-#include <mach/memory.h>
-#include <mach/hardware.h>
-#include <mach/irqs.h>
 #include <mach/edma.h>
-#include <mach/mux.h>
-
 
 /* Offsets matching "struct edmacc_param" */
 #define PARM_OPT		0x00
@@ -509,43 +500,59 @@
 	return IRQ_HANDLED;
 }
 
-static int reserve_contiguous_params(int ctlr, unsigned int id,
-				     unsigned int num_params,
-				     unsigned int start_param)
+static int reserve_contiguous_slots(int ctlr, unsigned int id,
+				     unsigned int num_slots,
+				     unsigned int start_slot)
 {
 	int i, j;
-	unsigned int count = num_params;
+	unsigned int count = num_slots;
+	int stop_slot = start_slot;
+	DECLARE_BITMAP(tmp_inuse, EDMA_MAX_PARAMENTRY);
 
-	for (i = start_param; i < edma_info[ctlr]->num_slots; ++i) {
+	for (i = start_slot; i < edma_info[ctlr]->num_slots; ++i) {
 		j = EDMA_CHAN_SLOT(i);
-		if (!test_and_set_bit(j, edma_info[ctlr]->edma_inuse))
+		if (!test_and_set_bit(j, edma_info[ctlr]->edma_inuse)) {
+			/* Record our current beginning slot */
+			if (count == num_slots)
+				stop_slot = i;
+
 			count--;
+			set_bit(j, tmp_inuse);
+
 			if (count == 0)
 				break;
-		else if (id == EDMA_CONT_PARAMS_FIXED_EXACT)
-			break;
-		else
-			count = num_params;
+		} else {
+			clear_bit(j, tmp_inuse);
+
+			if (id == EDMA_CONT_PARAMS_FIXED_EXACT) {
+				stop_slot = i;
+				break;
+			} else
+				count = num_slots;
+		}
 	}
 
 	/*
 	 * We have to clear any bits that we set
-	 * if we run out parameter RAMs, i.e we do find a set
-	 * of contiguous parameter RAMs but do not find the exact number
-	 * requested as we may reach the total number of parameter RAMs
+	 * if we run out parameter RAM slots, i.e we do find a set
+	 * of contiguous parameter RAM slots but do not find the exact number
+	 * requested as we may reach the total number of parameter RAM slots
 	 */
-	if (count) {
-		for (j = i - num_params + count + 1; j <= i ; ++j)
+	if (i == edma_info[ctlr]->num_slots)
+		stop_slot = i;
+
+	for (j = start_slot; j < stop_slot; j++)
+		if (test_bit(j, tmp_inuse))
 			clear_bit(j, edma_info[ctlr]->edma_inuse);
 
+	if (count)
 		return -EBUSY;
-	}
 
-	for (j = i - num_params + 1; j <= i; ++j)
+	for (j = i - num_slots + 1; j <= i; ++j)
 		memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(j),
 			&dummy_paramset, PARM_SIZE);
 
-	return EDMA_CTLR_CHAN(ctlr, i - num_params + 1);
+	return EDMA_CTLR_CHAN(ctlr, i - num_slots + 1);
 }
 
 /*-----------------------------------------------------------------------*/
@@ -743,26 +750,27 @@
 /**
  * edma_alloc_cont_slots- alloc contiguous parameter RAM slots
  * The API will return the starting point of a set of
- * contiguous PARAM's that have been requested
+ * contiguous parameter RAM slots that have been requested
  *
  * @id: can only be EDMA_CONT_PARAMS_ANY or EDMA_CONT_PARAMS_FIXED_EXACT
  * or EDMA_CONT_PARAMS_FIXED_NOT_EXACT
- * @count: number of contiguous Paramter RAM's
- * @param  - the start value of Parameter RAM that should be passed if id
+ * @count: number of contiguous Paramter RAM slots
+ * @slot  - the start value of Parameter RAM slot that should be passed if id
  * is EDMA_CONT_PARAMS_FIXED_EXACT or EDMA_CONT_PARAMS_FIXED_NOT_EXACT
  *
  * If id is EDMA_CONT_PARAMS_ANY then the API starts looking for a set of
- * contiguous Parameter RAMs from parameter RAM 64 in the case of DaVinci SOCs
- * and 32 in the case of Primus
+ * contiguous Parameter RAM slots from parameter RAM 64 in the case of
+ * DaVinci SOCs and 32 in the case of DA8xx SOCs.
  *
  * If id is EDMA_CONT_PARAMS_FIXED_EXACT then the API starts looking for a
- * set of contiguous parameter RAMs from the "param" that is passed as an
+ * set of contiguous parameter RAM slots from the "slot" that is passed as an
  * argument to the API.
  *
  * If id is EDMA_CONT_PARAMS_FIXED_NOT_EXACT then the API initially tries
- * starts looking for a set of contiguous parameter RAMs from the "param"
+ * starts looking for a set of contiguous parameter RAMs from the "slot"
  * that is passed as an argument to the API. On failure the API will try to
- * find a set of contiguous Parameter RAMs in the remaining Parameter RAMs
+ * find a set of contiguous Parameter RAM slots from the remaining Parameter
+ * RAM slots
  */
 int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count)
 {
@@ -771,12 +779,13 @@
 	 * the number of channels and lesser than the total number
 	 * of slots
 	 */
-	if (slot < edma_info[ctlr]->num_channels ||
-		slot >= edma_info[ctlr]->num_slots)
+	if ((id != EDMA_CONT_PARAMS_ANY) &&
+		(slot < edma_info[ctlr]->num_channels ||
+		slot >= edma_info[ctlr]->num_slots))
 		return -EINVAL;
 
 	/*
-	 * The number of parameter RAMs requested cannot be less than 1
+	 * The number of parameter RAM slots requested cannot be less than 1
 	 * and cannot be more than the number of slots minus the number of
 	 * channels
 	 */
@@ -786,11 +795,11 @@
 
 	switch (id) {
 	case EDMA_CONT_PARAMS_ANY:
-		return reserve_contiguous_params(ctlr, id, count,
+		return reserve_contiguous_slots(ctlr, id, count,
 						 edma_info[ctlr]->num_channels);
 	case EDMA_CONT_PARAMS_FIXED_EXACT:
 	case EDMA_CONT_PARAMS_FIXED_NOT_EXACT:
-		return reserve_contiguous_params(ctlr, id, count, slot);
+		return reserve_contiguous_slots(ctlr, id, count, slot);
 	default:
 		return -EINVAL;
 	}
@@ -799,21 +808,21 @@
 EXPORT_SYMBOL(edma_alloc_cont_slots);
 
 /**
- * edma_free_cont_slots - deallocate DMA parameter RAMs
- * @slot: first parameter RAM of a set of parameter RAMs to be freed
- * @count: the number of contiguous parameter RAMs to be freed
+ * edma_free_cont_slots - deallocate DMA parameter RAM slots
+ * @slot: first parameter RAM of a set of parameter RAM slots to be freed
+ * @count: the number of contiguous parameter RAM slots to be freed
  *
  * This deallocates the parameter RAM slots allocated by
  * edma_alloc_cont_slots.
  * Callers/applications need to keep track of sets of contiguous
- * parameter RAMs that have been allocated using the edma_alloc_cont_slots
+ * parameter RAM slots that have been allocated using the edma_alloc_cont_slots
  * API.
  * Callers are responsible for ensuring the slots are inactive, and will
  * not be activated.
  */
 int edma_free_cont_slots(unsigned slot, int count)
 {
-	unsigned ctlr;
+	unsigned ctlr, slot_to_free;
 	int i;
 
 	ctlr = EDMA_CTLR(slot);
@@ -826,11 +835,11 @@
 
 	for (i = slot; i < slot + count; ++i) {
 		ctlr = EDMA_CTLR(i);
-		slot = EDMA_CHAN_SLOT(i);
+		slot_to_free = EDMA_CHAN_SLOT(i);
 
-		memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot),
+		memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot_to_free),
 			&dummy_paramset, PARM_SIZE);
-		clear_bit(slot, edma_info[ctlr]->edma_inuse);
+		clear_bit(slot_to_free, edma_info[ctlr]->edma_inuse);
 	}
 
 	return 0;
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c
index f6ea9db..744755b 100644
--- a/arch/arm/mach-davinci/gpio.c
+++ b/arch/arm/mach-davinci/gpio.c
@@ -12,23 +12,14 @@
 
 #include <linux/errno.h>
 #include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/bitops.h>
 
-#include <mach/cputype.h>
-#include <mach/irqs.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
 #include <mach/gpio.h>
 
 #include <asm/mach/irq.h>
 
-
 static DEFINE_SPINLOCK(gpio_lock);
 
 struct davinci_gpio {
diff --git a/arch/arm/mach-davinci/include/mach/asp.h b/arch/arm/mach-davinci/include/mach/asp.h
index e07f70e..834725f 100644
--- a/arch/arm/mach-davinci/include/mach/asp.h
+++ b/arch/arm/mach-davinci/include/mach/asp.h
@@ -11,6 +11,9 @@
 #define DAVINCI_ASP0_BASE	0x01E02000
 #define DAVINCI_ASP1_BASE	0x01E04000
 
+/* Bases of dm365 register banks */
+#define DAVINCI_DM365_ASP0_BASE	0x01D02000
+
 /* Bases of dm646x register banks */
 #define	DAVINCI_DM646X_MCASP0_REG_BASE		0x01D01000
 #define DAVINCI_DM646X_MCASP1_REG_BASE		0x01D01800
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index 1fd3917..6ca2c9a 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -20,12 +20,6 @@
 extern void __iomem *davinci_intc_base;
 extern int davinci_intc_type;
 
-/* parameters describe VBUS sourcing for host mode */
-extern void setup_usb(unsigned mA, unsigned potpgt_msec);
-
-/* parameters describe VBUS sourcing for host mode */
-extern void setup_usb(unsigned mA, unsigned potpgt_msec);
-
 struct davinci_timer_instance {
 	void __iomem	*base;
 	u32		bottom_irq;
diff --git a/arch/arm/mach-davinci/include/mach/cpufreq.h b/arch/arm/mach-davinci/include/mach/cpufreq.h
new file mode 100644
index 0000000..3c089cf
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/cpufreq.h
@@ -0,0 +1,26 @@
+/*
+ * TI DaVinci CPUFreq platform support.
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc. http://www.ti.com/
+ *
+ * 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.
+ */
+#ifndef _MACH_DAVINCI_CPUFREQ_H
+#define _MACH_DAVINCI_CPUFREQ_H
+
+#include <linux/cpufreq.h>
+
+struct davinci_cpufreq_config {
+	struct cpufreq_frequency_table *freq_table;
+	int (*set_voltage) (unsigned int index);
+	int (*init) (void);
+};
+
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/cpuidle.h b/arch/arm/mach-davinci/include/mach/cpuidle.h
new file mode 100644
index 0000000..cbfc6a9
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/cpuidle.h
@@ -0,0 +1,17 @@
+/*
+ * TI DaVinci cpuidle platform support
+ *
+ * 2009 (C) Texas Instruments, Inc. http://www.ti.com/
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+#ifndef _MACH_DAVINCI_CPUIDLE_H
+#define _MACH_DAVINCI_CPUIDLE_H
+
+struct davinci_cpuidle_config {
+	u32 ddr2_pdown;
+};
+
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index d4095d0..9070491 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -11,12 +11,17 @@
 #ifndef __ASM_ARCH_DAVINCI_DA8XX_H
 #define __ASM_ARCH_DAVINCI_DA8XX_H
 
+#include <video/da8xx-fb.h>
+
 #include <mach/serial.h>
 #include <mach/edma.h>
 #include <mach/i2c.h>
 #include <mach/emac.h>
 #include <mach/asp.h>
 #include <mach/mmc.h>
+#include <mach/usb.h>
+
+extern void __iomem *da8xx_syscfg_base;
 
 /*
  * The cp_intc interrupt controller for the da8xx isn't in the same
@@ -29,11 +34,15 @@
 #define DA8XX_CP_INTC_SIZE	SZ_8K
 #define DA8XX_CP_INTC_VIRT	(IO_VIRT - DA8XX_CP_INTC_SIZE - SZ_4K)
 
-#define DA8XX_BOOT_CFG_BASE	(IO_PHYS + 0x14000)
+#define DA8XX_SYSCFG_BASE	(IO_PHYS + 0x14000)
+#define DA8XX_SYSCFG_VIRT(x)	(da8xx_syscfg_base + (x))
+#define DA8XX_JTAG_ID_REG	0x18
+#define DA8XX_CFGCHIP0_REG	0x17c
+#define DA8XX_CFGCHIP2_REG	0x184
+#define DA8XX_CFGCHIP3_REG	0x188
 
 #define DA8XX_PSC0_BASE		0x01c10000
 #define DA8XX_PLL0_BASE		0x01c11000
-#define DA8XX_JTAG_ID_REG	0x01c14018
 #define DA8XX_TIMER64P0_BASE	0x01c20000
 #define DA8XX_TIMER64P1_BASE	0x01c21000
 #define DA8XX_GPIO_BASE		0x01e26000
@@ -43,6 +52,7 @@
 #define DA8XX_AEMIF_CS2_BASE	0x60000000
 #define DA8XX_AEMIF_CS3_BASE	0x62000000
 #define DA8XX_AEMIF_CTL_BASE	0x68000000
+#define DA8XX_DDR2_CTL_BASE	0xb0000000
 
 #define PINMUX0			0x00
 #define PINMUX1			0x04
@@ -71,13 +81,20 @@
 int da8xx_register_edma(void);
 int da8xx_register_i2c(int instance, struct davinci_i2c_platform_data *pdata);
 int da8xx_register_watchdog(void);
+int da8xx_register_usb20(unsigned mA, unsigned potpgt);
+int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata);
 int da8xx_register_emac(void);
-int da8xx_register_lcdc(void);
+int da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata);
 int da8xx_register_mmcsd0(struct davinci_mmc_config *config);
-void __init da8xx_init_mcasp(int id, struct snd_platform_data *pdata);
+void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata);
+int da8xx_register_rtc(void);
+int da850_register_cpufreq(void);
+int da8xx_register_cpuidle(void);
 
 extern struct platform_device da8xx_serial_device;
 extern struct emac_platform_data da8xx_emac_pdata;
+extern struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata;
+extern struct da8xx_lcdc_platform_data sharp_lk043t1dg01_pdata;
 
 extern const short da830_emif25_pins[];
 extern const short da830_spi0_pins[];
@@ -110,6 +127,7 @@
 extern const short da850_i2c0_pins[];
 extern const short da850_i2c1_pins[];
 extern const short da850_cpgmac_pins[];
+extern const short da850_rmii_pins[];
 extern const short da850_mcasp_pins[];
 extern const short da850_lcdcntl_pins[];
 extern const short da850_mmcsd0_pins[];
diff --git a/arch/arm/mach-davinci/include/mach/dm365.h b/arch/arm/mach-davinci/include/mach/dm365.h
index 09db434..f1710a3 100644
--- a/arch/arm/mach-davinci/include/mach/dm365.h
+++ b/arch/arm/mach-davinci/include/mach/dm365.h
@@ -16,6 +16,8 @@
 #include <linux/platform_device.h>
 #include <mach/hardware.h>
 #include <mach/emac.h>
+#include <mach/asp.h>
+#include <mach/keyscan.h>
 
 #define DM365_EMAC_BASE			(0x01D07000)
 #define DM365_EMAC_CNTRL_OFFSET		(0x0000)
@@ -24,6 +26,14 @@
 #define DM365_EMAC_MDIO_OFFSET		(0x4000)
 #define DM365_EMAC_CNTRL_RAM_SIZE	(0x2000)
 
+/* Base of key scan register bank */
+#define DM365_KEYSCAN_BASE		(0x01C69400)
+
+#define DM365_RTC_BASE			(0x01C69000)
+
 void __init dm365_init(void);
+void __init dm365_init_asp(struct snd_platform_data *pdata);
+void __init dm365_init_ks(struct davinci_ks_platform_data *pdata);
+void __init dm365_init_rtc(void);
 
 #endif /* __ASM_ARCH_DM365_H */
diff --git a/arch/arm/mach-davinci/include/mach/dm644x.h b/arch/arm/mach-davinci/include/mach/dm644x.h
index 0efb738..44e8f0f 100644
--- a/arch/arm/mach-davinci/include/mach/dm644x.h
+++ b/arch/arm/mach-davinci/include/mach/dm644x.h
@@ -22,7 +22,6 @@
 #ifndef __ASM_ARCH_DM644X_H
 #define __ASM_ARCH_DM644X_H
 
-#include <linux/platform_device.h>
 #include <mach/hardware.h>
 #include <mach/emac.h>
 #include <mach/asp.h>
diff --git a/arch/arm/mach-davinci/include/mach/irqs.h b/arch/arm/mach-davinci/include/mach/irqs.h
index 3c918a7..354af71 100644
--- a/arch/arm/mach-davinci/include/mach/irqs.h
+++ b/arch/arm/mach-davinci/include/mach/irqs.h
@@ -217,6 +217,7 @@
 #define IRQ_DM365_SDIOINT0	23
 #define IRQ_DM365_MMCINT1	27
 #define IRQ_DM365_PWMINT3	28
+#define IRQ_DM365_RTCINT	29
 #define IRQ_DM365_SDIOINT1	31
 #define IRQ_DM365_SPIINT0_0	42
 #define IRQ_DM365_SPIINT3_0	43
diff --git a/arch/arm/mach-davinci/include/mach/keyscan.h b/arch/arm/mach-davinci/include/mach/keyscan.h
new file mode 100644
index 0000000..b4e21a2
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/keyscan.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2009 Texas Instruments, Inc
+ *
+ * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef DAVINCI_KEYSCAN_H
+#define DAVINCI_KEYSCAN_H
+
+#include <linux/io.h>
+
+enum davinci_matrix_types {
+	DAVINCI_KEYSCAN_MATRIX_4X4,
+	DAVINCI_KEYSCAN_MATRIX_5X3,
+};
+
+struct davinci_ks_platform_data {
+	unsigned short	*keymap;
+	u32		keymapsize;
+	u8		rep:1;
+	u8		strobe;
+	u8		interval;
+	u8		matrix_type;
+};
+
+#endif
+
diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h
index bb84893..b60c693 100644
--- a/arch/arm/mach-davinci/include/mach/mux.h
+++ b/arch/arm/mach-davinci/include/mach/mux.h
@@ -40,6 +40,11 @@
 
 	/* AEAW functions */
 	DM644X_AEAW,
+	DM644X_AEAW0,
+	DM644X_AEAW1,
+	DM644X_AEAW2,
+	DM644X_AEAW3,
+	DM644X_AEAW4,
 
 	/* Memory Stick */
 	DM644X_MSTK,
@@ -237,8 +242,8 @@
 	DM365_EMAC_MDIO,
 	DM365_EMAC_MDCLK,
 
-	/* Keypad */
-	DM365_KEYPAD,
+	/* Key Scan */
+	DM365_KEYSCAN,
 
 	/* PWM */
 	DM365_PWM0,
@@ -774,6 +779,14 @@
 	DA850_MII_RXD_0,
 	DA850_MDIO_CLK,
 	DA850_MDIO_D,
+	DA850_RMII_TXD_0,
+	DA850_RMII_TXD_1,
+	DA850_RMII_TXEN,
+	DA850_RMII_CRS_DV,
+	DA850_RMII_RXD_0,
+	DA850_RMII_RXD_1,
+	DA850_RMII_RXER,
+	DA850_RMII_MHZ_50_CLK,
 
 	/* McASP function */
 	DA850_ACLKR,
@@ -881,8 +894,9 @@
 	DA850_NEMA_CS_2,
 
 	/* GPIO function */
+	DA850_GPIO2_6,
+	DA850_GPIO2_8,
 	DA850_GPIO2_15,
-	DA850_GPIO8_10,
 	DA850_GPIO4_0,
 	DA850_GPIO4_1,
 };
diff --git a/arch/arm/mach-davinci/include/mach/system.h b/arch/arm/mach-davinci/include/mach/system.h
index 8e4f10f..5a7d758 100644
--- a/arch/arm/mach-davinci/include/mach/system.h
+++ b/arch/arm/mach-davinci/include/mach/system.h
@@ -11,9 +11,6 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
-#include <linux/io.h>
-#include <mach/hardware.h>
-
 extern void davinci_watchdog_reset(void);
 
 static inline void arch_idle(void)
diff --git a/arch/arm/mach-davinci/include/mach/usb.h b/arch/arm/mach-davinci/include/mach/usb.h
new file mode 100644
index 0000000..e0bc4ab
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/usb.h
@@ -0,0 +1,59 @@
+/*
+ * USB related definitions
+ *
+ * Copyright (C) 2009 MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_USB_H
+#define __ASM_ARCH_USB_H
+
+/* DA8xx CFGCHIP2 (USB 2.0 PHY Control) register bits */
+#define CFGCHIP2_PHYCLKGD	(1 << 17)
+#define CFGCHIP2_VBUSSENSE	(1 << 16)
+#define CFGCHIP2_RESET		(1 << 15)
+#define CFGCHIP2_OTGMODE	(3 << 13)
+#define CFGCHIP2_NO_OVERRIDE	(0 << 13)
+#define CFGCHIP2_FORCE_HOST	(1 << 13)
+#define CFGCHIP2_FORCE_DEVICE 	(2 << 13)
+#define CFGCHIP2_FORCE_HOST_VBUS_LOW (3 << 13)
+#define CFGCHIP2_USB1PHYCLKMUX	(1 << 12)
+#define CFGCHIP2_USB2PHYCLKMUX	(1 << 11)
+#define CFGCHIP2_PHYPWRDN	(1 << 10)
+#define CFGCHIP2_OTGPWRDN	(1 << 9)
+#define CFGCHIP2_DATPOL 	(1 << 8)
+#define CFGCHIP2_USB1SUSPENDM	(1 << 7)
+#define CFGCHIP2_PHY_PLLON	(1 << 6)	/* override PLL suspend */
+#define CFGCHIP2_SESENDEN	(1 << 5)	/* Vsess_end comparator */
+#define CFGCHIP2_VBDTCTEN	(1 << 4)	/* Vbus comparator */
+#define CFGCHIP2_REFFREQ	(0xf << 0)
+#define CFGCHIP2_REFFREQ_12MHZ	(1 << 0)
+#define CFGCHIP2_REFFREQ_24MHZ	(2 << 0)
+#define CFGCHIP2_REFFREQ_48MHZ	(3 << 0)
+
+struct	da8xx_ohci_root_hub;
+
+typedef void (*da8xx_ocic_handler_t)(struct da8xx_ohci_root_hub *hub,
+				     unsigned port);
+
+/* Passed as the platform data to the OHCI driver */
+struct	da8xx_ohci_root_hub {
+	/* Switch the port power on/off */
+	int	(*set_power)(unsigned port, int on);
+	/* Read the port power status */
+	int	(*get_power)(unsigned port);
+	/* Read the port over-current indicator */
+	int	(*get_oci)(unsigned port);
+	/* Over-current indicator change notification (pass NULL to disable) */
+	int	(*ocic_notify)(da8xx_ocic_handler_t handler);
+
+	/* Time from power on to power good (in 2 ms units) */
+	u8	potpgt;
+};
+
+void davinci_setup_usb(unsigned mA, unsigned potpgt_ms);
+
+#endif	/* ifndef __ASM_ARCH_USB_H */
diff --git a/arch/arm/mach-davinci/mux.c b/arch/arm/mach-davinci/mux.c
index 898905e..f757e83 100644
--- a/arch/arm/mach-davinci/mux.c
+++ b/arch/arm/mach-davinci/mux.c
@@ -19,7 +19,6 @@
 #include <linux/module.h>
 #include <linux/spinlock.h>
 
-#include <mach/hardware.h>
 #include <mach/mux.h>
 #include <mach/common.h>
 
diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c
index a78b657..04a3cb7 100644
--- a/arch/arm/mach-davinci/psc.c
+++ b/arch/arm/mach-davinci/psc.c
@@ -19,14 +19,11 @@
  *
  */
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/io.h>
 
 #include <mach/cputype.h>
-#include <mach/hardware.h>
 #include <mach/psc.h>
-#include <mach/mux.h>
 
 /* PSC register offsets */
 #define EPCPR		0x070
diff --git a/arch/arm/mach-davinci/serial.c b/arch/arm/mach-davinci/serial.c
index c530c73..7ce5ba0 100644
--- a/arch/arm/mach-davinci/serial.c
+++ b/arch/arm/mach-davinci/serial.c
@@ -28,14 +28,8 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 
-#include <asm/irq.h>
-#include <mach/hardware.h>
 #include <mach/serial.h>
-#include <mach/irqs.h>
 #include <mach/cputype.h>
-#include <mach/common.h>
-
-#include "clock.h"
 
 static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
 					   int offset)
diff --git a/arch/arm/mach-davinci/sram.c b/arch/arm/mach-davinci/sram.c
index 4f1fc9b..db0f778 100644
--- a/arch/arm/mach-davinci/sram.c
+++ b/arch/arm/mach-davinci/sram.c
@@ -9,15 +9,12 @@
  * (at your option) any later version.
  */
 #include <linux/module.h>
-#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/genalloc.h>
 
 #include <mach/common.h>
-#include <mach/memory.h>
 #include <mach/sram.h>
 
-
 static struct gen_pool *sram_pool;
 
 void *sram_alloc(size_t len, dma_addr_t *dma)
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
index 0d1b6d4..42d985b 100644
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -14,20 +14,14 @@
 #include <linux/interrupt.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
-#include <linux/spinlock.h>
 #include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/err.h>
-#include <linux/device.h>
 #include <linux/platform_device.h>
 
 #include <mach/hardware.h>
-#include <asm/system.h>
-#include <asm/irq.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
-#include <asm/errno.h>
-#include <mach/io.h>
 #include <mach/cputype.h>
 #include <mach/time.h>
 #include "clock.h"
diff --git a/arch/arm/mach-davinci/usb.c b/arch/arm/mach-davinci/usb.c
index 06f5593..31f0cbe 100644
--- a/arch/arm/mach-davinci/usb.c
+++ b/arch/arm/mach-davinci/usb.c
@@ -1,21 +1,21 @@
 /*
  * USB
  */
-#include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 
 #include <linux/usb/musb.h>
-#include <linux/usb/otg.h>
 
 #include <mach/common.h>
-#include <mach/hardware.h>
 #include <mach/irqs.h>
 #include <mach/cputype.h>
+#include <mach/usb.h>
 
-#define DAVINCI_USB_OTG_BASE 0x01C64000
+#define DAVINCI_USB_OTG_BASE	0x01c64000
+
+#define DA8XX_USB0_BASE 	0x01e00000
+#define DA8XX_USB1_BASE 	0x01e25000
 
 #if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
 static struct musb_hdrc_eps_bits musb_eps[] = {
@@ -85,10 +85,10 @@
 	.num_resources  = ARRAY_SIZE(usb_resources),
 };
 
-void __init setup_usb(unsigned mA, unsigned potpgt_msec)
+void __init davinci_setup_usb(unsigned mA, unsigned potpgt_ms)
 {
-	usb_data.power = mA / 2;
-	usb_data.potpgt = potpgt_msec / 2;
+	usb_data.power = mA > 510 ? 255 : mA / 2;
+	usb_data.potpgt = (potpgt_ms + 1) / 2;
 
 	if (cpu_is_davinci_dm646x()) {
 		/* Override the defaults as DM6467 uses different IRQs. */
@@ -100,11 +100,77 @@
 	platform_device_register(&usb_dev);
 }
 
+#ifdef CONFIG_ARCH_DAVINCI_DA8XX
+static struct resource da8xx_usb20_resources[] = {
+	{
+		.start		= DA8XX_USB0_BASE,
+		.end		= DA8XX_USB0_BASE + SZ_64K - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= IRQ_DA8XX_USB_INT,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+int __init da8xx_register_usb20(unsigned mA, unsigned potpgt)
+{
+	usb_data.clock  = "usb20";
+	usb_data.power	= mA > 510 ? 255 : mA / 2;
+	usb_data.potpgt = (potpgt + 1) / 2;
+
+	usb_dev.resource = da8xx_usb20_resources;
+	usb_dev.num_resources = ARRAY_SIZE(da8xx_usb20_resources);
+
+	return platform_device_register(&usb_dev);
+}
+#endif	/* CONFIG_DAVINCI_DA8XX */
+
 #else
 
-void __init setup_usb(unsigned mA, unsigned potpgt_msec)
+void __init davinci_setup_usb(unsigned mA, unsigned potpgt_ms)
 {
 }
 
+#ifdef CONFIG_ARCH_DAVINCI_DA8XX
+int __init da8xx_register_usb20(unsigned mA, unsigned potpgt)
+{
+	return 0;
+}
+#endif
+
 #endif  /* CONFIG_USB_MUSB_HDRC */
 
+#ifdef	CONFIG_ARCH_DAVINCI_DA8XX
+static struct resource da8xx_usb11_resources[] = {
+	[0] = {
+		.start	= DA8XX_USB1_BASE,
+		.end	= DA8XX_USB1_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_DA8XX_IRQN,
+		.end	= IRQ_DA8XX_IRQN,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static u64 da8xx_usb11_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device da8xx_usb11_device = {
+	.name		= "ohci",
+	.id		= 0,
+	.dev = {
+		.dma_mask		= &da8xx_usb11_dma_mask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.num_resources	= ARRAY_SIZE(da8xx_usb11_resources),
+	.resource	= da8xx_usb11_resources,
+};
+
+int __init da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata)
+{
+	da8xx_usb11_device.dev.platform_data = pdata;
+	return platform_device_register(&da8xx_usb11_device);
+}
+#endif	/* CONFIG_DAVINCI_DA8XX */
diff --git a/arch/arm/mach-lh7a40x/include/mach/hardware.h b/arch/arm/mach-lh7a40x/include/mach/hardware.h
index 48e827d..59d2ace 100644
--- a/arch/arm/mach-lh7a40x/include/mach/hardware.h
+++ b/arch/arm/mach-lh7a40x/include/mach/hardware.h
@@ -31,7 +31,7 @@
 /*
  * This __REG() version gives the same results as the one above,  except
  * that we are fooling gcc somehow so it generates far better and smaller
- * assembly code for access to contigous registers.  It's a shame that gcc
+ * assembly code for access to contiguous registers.  It's a shame that gcc
  * doesn't guess this by itself.
  */
 #include <asm/types.h>
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
index 5a275ba..71e1a3f 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 #include <linux/input.h>
 #include <linux/clk.h>
+#include <linux/omapfb.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
@@ -32,7 +33,6 @@
 #include <plat/keypad.h>
 #include <plat/common.h>
 #include <plat/dsp_common.h>
-#include <plat/omapfb.h>
 #include <plat/hwa742.h>
 #include <plat/lcd_mipid.h>
 #include <plat/mmc.h>
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 491364e..5bda9fd 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -37,6 +37,7 @@
 #include <plat/common.h>
 #include <plat/dma.h>
 #include <plat/gpmc.h>
+#include <plat/display.h>
 
 #include <plat/control.h>
 #include <plat/gpmc-smc91x.h>
@@ -152,31 +153,152 @@
 	},
 };
 
-static struct platform_device sdp3430_lcd_device = {
-	.name		= "sdp2430_lcd",
+
+#define SDP3430_LCD_PANEL_BACKLIGHT_GPIO	8
+#define SDP3430_LCD_PANEL_ENABLE_GPIO		5
+
+static unsigned backlight_gpio;
+static unsigned enable_gpio;
+static int lcd_enabled;
+static int dvi_enabled;
+
+static void __init sdp3430_display_init(void)
+{
+	int r;
+
+	enable_gpio    = SDP3430_LCD_PANEL_ENABLE_GPIO;
+	backlight_gpio = SDP3430_LCD_PANEL_BACKLIGHT_GPIO;
+
+	r = gpio_request(enable_gpio, "LCD reset");
+	if (r) {
+		printk(KERN_ERR "failed to get LCD reset GPIO\n");
+		goto err0;
+	}
+
+	r = gpio_request(backlight_gpio, "LCD Backlight");
+	if (r) {
+		printk(KERN_ERR "failed to get LCD backlight GPIO\n");
+		goto err1;
+	}
+
+	gpio_direction_output(enable_gpio, 0);
+	gpio_direction_output(backlight_gpio, 0);
+
+	return;
+err1:
+	gpio_free(enable_gpio);
+err0:
+	return;
+}
+
+static int sdp3430_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+	if (dvi_enabled) {
+		printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
+		return -EINVAL;
+	}
+
+	gpio_direction_output(enable_gpio, 1);
+	gpio_direction_output(backlight_gpio, 1);
+
+	lcd_enabled = 1;
+
+	return 0;
+}
+
+static void sdp3430_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+	lcd_enabled = 0;
+
+	gpio_direction_output(enable_gpio, 0);
+	gpio_direction_output(backlight_gpio, 0);
+}
+
+static int sdp3430_panel_enable_dvi(struct omap_dss_device *dssdev)
+{
+	if (lcd_enabled) {
+		printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
+		return -EINVAL;
+	}
+
+	dvi_enabled = 1;
+
+	return 0;
+}
+
+static void sdp3430_panel_disable_dvi(struct omap_dss_device *dssdev)
+{
+	dvi_enabled = 0;
+}
+
+static int sdp3430_panel_enable_tv(struct omap_dss_device *dssdev)
+{
+	return 0;
+}
+
+static void sdp3430_panel_disable_tv(struct omap_dss_device *dssdev)
+{
+}
+
+
+static struct omap_dss_device sdp3430_lcd_device = {
+	.name			= "lcd",
+	.driver_name		= "sharp_ls_panel",
+	.type			= OMAP_DISPLAY_TYPE_DPI,
+	.phy.dpi.data_lines	= 16,
+	.platform_enable	= sdp3430_panel_enable_lcd,
+	.platform_disable	= sdp3430_panel_disable_lcd,
+};
+
+static struct omap_dss_device sdp3430_dvi_device = {
+	.name			= "dvi",
+	.driver_name		= "generic_panel",
+	.type			= OMAP_DISPLAY_TYPE_DPI,
+	.phy.dpi.data_lines	= 24,
+	.platform_enable	= sdp3430_panel_enable_dvi,
+	.platform_disable	= sdp3430_panel_disable_dvi,
+};
+
+static struct omap_dss_device sdp3430_tv_device = {
+	.name			= "tv",
+	.driver_name		= "venc",
+	.type			= OMAP_DISPLAY_TYPE_VENC,
+	.phy.venc.type		= OMAP_DSS_VENC_TYPE_SVIDEO,
+	.platform_enable	= sdp3430_panel_enable_tv,
+	.platform_disable	= sdp3430_panel_disable_tv,
+};
+
+
+static struct omap_dss_device *sdp3430_dss_devices[] = {
+	&sdp3430_lcd_device,
+	&sdp3430_dvi_device,
+	&sdp3430_tv_device,
+};
+
+static struct omap_dss_board_info sdp3430_dss_data = {
+	.num_devices	= ARRAY_SIZE(sdp3430_dss_devices),
+	.devices	= sdp3430_dss_devices,
+	.default_device	= &sdp3430_lcd_device,
+};
+
+static struct platform_device sdp3430_dss_device = {
+	.name		= "omapdss",
 	.id		= -1,
+	.dev		= {
+		.platform_data = &sdp3430_dss_data,
+	},
 };
 
-static struct regulator_consumer_supply sdp3430_vdac_supply = {
-	.supply		= "vdac",
-	.dev		= &sdp3430_lcd_device.dev,
-};
-
-static struct regulator_consumer_supply sdp3430_vdvi_supply = {
-	.supply		= "vdvi",
-	.dev		= &sdp3430_lcd_device.dev,
+static struct regulator_consumer_supply sdp3430_vdda_dac_supply = {
+	.supply		= "vdda_dac",
+	.dev		= &sdp3430_dss_device.dev,
 };
 
 static struct platform_device *sdp3430_devices[] __initdata = {
-	&sdp3430_lcd_device,
-};
-
-static struct omap_lcd_config sdp3430_lcd_config __initdata = {
-	.ctrl_name	= "internal",
+	&sdp3430_dss_device,
 };
 
 static struct omap_board_config_kernel sdp3430_config[] __initdata = {
-	{ OMAP_TAG_LCD,		&sdp3430_lcd_config },
 };
 
 static void __init omap_3430sdp_init_irq(void)
@@ -392,22 +514,34 @@
 					| REGULATOR_CHANGE_STATUS,
 	},
 	.num_consumer_supplies	= 1,
-	.consumer_supplies	= &sdp3430_vdac_supply,
+	.consumer_supplies	= &sdp3430_vdda_dac_supply,
 };
 
 /* VPLL2 for digital video outputs */
+static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
+	{
+		.supply		= "vdvi",
+		.dev		= &sdp3430_lcd_device.dev,
+	},
+	{
+		.supply		= "vdds_dsi",
+		.dev		= &sdp3430_dss_device.dev,
+	}
+};
+
 static struct regulator_init_data sdp3430_vpll2 = {
 	.constraints = {
 		.name			= "VDVI",
 		.min_uV			= 1800000,
 		.max_uV			= 1800000,
+		.apply_uV		= true,
 		.valid_modes_mask	= REGULATOR_MODE_NORMAL
 					| REGULATOR_MODE_STANDBY,
 		.valid_ops_mask		= REGULATOR_CHANGE_MODE
 					| REGULATOR_CHANGE_STATUS,
 	},
-	.num_consumer_supplies	= 1,
-	.consumer_supplies	= &sdp3430_vdvi_supply,
+	.num_consumer_supplies	= ARRAY_SIZE(sdp3430_vpll2_supplies),
+	.consumer_supplies	= sdp3430_vpll2_supplies,
 };
 
 static struct twl4030_codec_audio_data sdp3430_audio = {
@@ -521,6 +655,7 @@
 	omap_serial_init();
 	usb_musb_init();
 	board_smc91x_init();
+	sdp3430_display_init();
 	enable_board_wakeup_source();
 	usb_ehci_init(&ehci_pdata);
 }
diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c
index e70e7e0..845b478 100644
--- a/arch/arm/mach-omap2/clock24xx.c
+++ b/arch/arm/mach-omap2/clock24xx.c
@@ -116,10 +116,10 @@
 	CLK(NULL,	"mdm_ick",	&mdm_ick,	CK_243X),
 	CLK(NULL,	"mdm_osc_ck",	&mdm_osc_ck,	CK_243X),
 	/* DSS domain clocks */
-	CLK("omapfb",	"ick",		&dss_ick,	CK_243X | CK_242X),
-	CLK("omapfb",	"dss1_fck",	&dss1_fck,	CK_243X | CK_242X),
-	CLK("omapfb",	"dss2_fck",	&dss2_fck,	CK_243X | CK_242X),
-	CLK("omapfb",	"tv_fck",	&dss_54m_fck,	CK_243X | CK_242X),
+	CLK("omapdss",	"ick",		&dss_ick,	CK_243X | CK_242X),
+	CLK("omapdss",	"dss1_fck",	&dss1_fck,	CK_243X | CK_242X),
+	CLK("omapdss",	"dss2_fck",	&dss2_fck,	CK_243X | CK_242X),
+	CLK("omapdss",	"tv_fck",	&dss_54m_fck,	CK_243X | CK_242X),
 	/* L3 domain clocks */
 	CLK(NULL,	"core_l3_ck",	&core_l3_ck,	CK_243X | CK_242X),
 	CLK(NULL,	"ssi_fck",	&ssi_ssr_sst_fck, CK_243X | CK_242X),
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 9f2feaf..ecbb5cd 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -236,13 +236,13 @@
 	CLK("omap_rng",	"ick",		&rng_ick,	CK_343X),
 	CLK(NULL,	"sha11_ick",	&sha11_ick,	CK_343X),
 	CLK(NULL,	"des1_ick",	&des1_ick,	CK_343X),
-	CLK("omapfb",	"dss1_fck",	&dss1_alwon_fck_3430es1, CK_3430ES1),
-	CLK("omapfb",	"dss1_fck",	&dss1_alwon_fck_3430es2, CK_3430ES2),
-	CLK("omapfb",	"tv_fck",	&dss_tv_fck,	CK_343X),
-	CLK("omapfb",	"video_fck",	&dss_96m_fck,	CK_343X),
-	CLK("omapfb",	"dss2_fck",	&dss2_alwon_fck, CK_343X),
-	CLK("omapfb",	"ick",		&dss_ick_3430es1,	CK_3430ES1),
-	CLK("omapfb",	"ick",		&dss_ick_3430es2,	CK_3430ES2),
+	CLK("omapdss",	"dss1_fck",	&dss1_alwon_fck_3430es1, CK_3430ES1),
+	CLK("omapdss",	"dss1_fck",	&dss1_alwon_fck_3430es2, CK_3430ES2),
+	CLK("omapdss",	"tv_fck",	&dss_tv_fck,	CK_343X),
+	CLK("omapdss",	"video_fck",	&dss_96m_fck,	CK_343X),
+	CLK("omapdss",	"dss2_fck",	&dss2_alwon_fck, CK_343X),
+	CLK("omapdss",	"ick",		&dss_ick_3430es1,	CK_3430ES1),
+	CLK("omapdss",	"ick",		&dss_ick_3430es2,	CK_3430ES2),
 	CLK(NULL,	"cam_mclk",	&cam_mclk,	CK_343X),
 	CLK(NULL,	"cam_ick",	&cam_ick,	CK_343X),
 	CLK(NULL,	"csi2_96m_fck",	&csi2_96m_fck,	CK_343X),
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 59d28b2..6a4d8e4 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -22,17 +22,18 @@
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/clk.h>
+#include <linux/omapfb.h>
 
 #include <asm/tlb.h>
 
 #include <asm/mach/map.h>
 
 #include <plat/mux.h>
-#include <plat/omapfb.h>
 #include <plat/sram.h>
 #include <plat/sdrc.h>
 #include <plat/gpmc.h>
 #include <plat/serial.h>
+#include <plat/vram.h>
 
 #ifndef CONFIG_ARCH_OMAP4	/* FIXME: Remove this once clkdev is ready */
 #include "clock.h"
@@ -264,6 +265,7 @@
 	omap2_check_revision();
 	omap_sram_init();
 	omapfb_reserve_sdram();
+	omap_vram_reserve_sdram();
 }
 
 /*
diff --git a/arch/arm/mach-omap2/sdrc.c b/arch/arm/mach-omap2/sdrc.c
index 9a59219..cbfbd14 100644
--- a/arch/arm/mach-omap2/sdrc.c
+++ b/arch/arm/mach-omap2/sdrc.c
@@ -160,3 +160,19 @@
 	sdrc_write_reg(l, SDRC_POWER);
 	omap2_sms_save_context();
 }
+
+void omap2_sms_write_rot_control(u32 val, unsigned ctx)
+{
+	sms_write_reg(val, SMS_ROT_CONTROL(ctx));
+}
+
+void omap2_sms_write_rot_size(u32 val, unsigned ctx)
+{
+	sms_write_reg(val, SMS_ROT_SIZE(ctx));
+}
+
+void omap2_sms_write_rot_physical_ba(u32 val, unsigned ctx)
+{
+	sms_write_reg(val, SMS_ROT_PHYSICAL_BA(ctx));
+}
+
diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c
index 36dc541..bdf96eb 100644
--- a/arch/arm/mach-orion5x/pci.c
+++ b/arch/arm/mach-orion5x/pci.c
@@ -463,7 +463,7 @@
 	writel(win_enable, PCI_BAR_ENABLE);
 
 	/*
-	 * Disable automatic update of address remaping when writing to BARs.
+	 * Disable automatic update of address remapping when writing to BARs.
 	 */
 	orion5x_setbits(PCI_ADDR_DECODE_CTRL, 1);
 }
diff --git a/arch/arm/mach-pxa/include/mach/palmld.h b/arch/arm/mach-pxa/include/mach/palmld.h
index 8721b80..ae536e8 100644
--- a/arch/arm/mach-pxa/include/mach/palmld.h
+++ b/arch/arm/mach-pxa/include/mach/palmld.h
@@ -91,7 +91,7 @@
 /* BATTERY */
 #define PALMLD_BAT_MAX_VOLTAGE		4000	/* 4.00V maximum voltage */
 #define PALMLD_BAT_MIN_VOLTAGE		3550	/* 3.55V critical voltage */
-#define PALMLD_BAT_MAX_CURRENT		0	/* unknokn */
+#define PALMLD_BAT_MAX_CURRENT		0	/* unknown */
 #define PALMLD_BAT_MIN_CURRENT		0	/* unknown */
 #define PALMLD_BAT_MAX_CHARGE		1	/* unknown */
 #define PALMLD_BAT_MIN_CHARGE		1	/* unknown */
diff --git a/arch/arm/mach-pxa/include/mach/palmt5.h b/arch/arm/mach-pxa/include/mach/palmt5.h
index d15662a..6baf746 100644
--- a/arch/arm/mach-pxa/include/mach/palmt5.h
+++ b/arch/arm/mach-pxa/include/mach/palmt5.h
@@ -66,7 +66,7 @@
 /* BATTERY */
 #define PALMT5_BAT_MAX_VOLTAGE		4000	/* 4.00v current voltage */
 #define PALMT5_BAT_MIN_VOLTAGE		3550	/* 3.55v critical voltage */
-#define PALMT5_BAT_MAX_CURRENT		0	/* unknokn */
+#define PALMT5_BAT_MAX_CURRENT		0	/* unknown */
 #define PALMT5_BAT_MIN_CURRENT		0	/* unknown */
 #define PALMT5_BAT_MAX_CHARGE		1	/* unknown */
 #define PALMT5_BAT_MIN_CHARGE		1	/* unknown */
diff --git a/arch/arm/mach-pxa/include/mach/palmtc.h b/arch/arm/mach-pxa/include/mach/palmtc.h
index 3dc9b07..3f9dd3f 100644
--- a/arch/arm/mach-pxa/include/mach/palmtc.h
+++ b/arch/arm/mach-pxa/include/mach/palmtc.h
@@ -68,7 +68,7 @@
 /* BATTERY */
 #define PALMTC_BAT_MAX_VOLTAGE		4000	/* 4.00V maximum voltage */
 #define PALMTC_BAT_MIN_VOLTAGE		3550	/* 3.55V critical voltage */
-#define PALMTC_BAT_MAX_CURRENT		0	/* unknokn */
+#define PALMTC_BAT_MAX_CURRENT		0	/* unknown */
 #define PALMTC_BAT_MIN_CURRENT		0	/* unknown */
 #define PALMTC_BAT_MAX_CHARGE		1	/* unknown */
 #define PALMTC_BAT_MIN_CHARGE		1	/* unknown */
diff --git a/arch/arm/mach-pxa/include/mach/palmte2.h b/arch/arm/mach-pxa/include/mach/palmte2.h
index 1236134..f89e989 100644
--- a/arch/arm/mach-pxa/include/mach/palmte2.h
+++ b/arch/arm/mach-pxa/include/mach/palmte2.h
@@ -59,7 +59,7 @@
 /* BATTERY */
 #define PALMTE2_BAT_MAX_VOLTAGE		4000	/* 4.00v current voltage */
 #define PALMTE2_BAT_MIN_VOLTAGE		3550	/* 3.55v critical voltage */
-#define PALMTE2_BAT_MAX_CURRENT		0	/* unknokn */
+#define PALMTE2_BAT_MAX_CURRENT		0	/* unknown */
 #define PALMTE2_BAT_MIN_CURRENT		0	/* unknown */
 #define PALMTE2_BAT_MAX_CHARGE		1	/* unknown */
 #define PALMTE2_BAT_MIN_CHARGE		1	/* unknown */
diff --git a/arch/arm/mach-pxa/include/mach/palmtx.h b/arch/arm/mach-pxa/include/mach/palmtx.h
index 1be0db6..10abc4f 100644
--- a/arch/arm/mach-pxa/include/mach/palmtx.h
+++ b/arch/arm/mach-pxa/include/mach/palmtx.h
@@ -94,7 +94,7 @@
 /* BATTERY */
 #define PALMTX_BAT_MAX_VOLTAGE		4000	/* 4.00v current voltage */
 #define PALMTX_BAT_MIN_VOLTAGE		3550	/* 3.55v critical voltage */
-#define PALMTX_BAT_MAX_CURRENT		0	/* unknokn */
+#define PALMTX_BAT_MAX_CURRENT		0	/* unknown */
 #define PALMTX_BAT_MIN_CURRENT		0	/* unknown */
 #define PALMTX_BAT_MAX_CHARGE		1	/* unknown */
 #define PALMTX_BAT_MIN_CHARGE		1	/* unknown */
diff --git a/arch/arm/mach-pxa/include/mach/palmz72.h b/arch/arm/mach-pxa/include/mach/palmz72.h
index 2806ef6..2bbcf70 100644
--- a/arch/arm/mach-pxa/include/mach/palmz72.h
+++ b/arch/arm/mach-pxa/include/mach/palmz72.h
@@ -49,7 +49,7 @@
 /* Battery */
 #define PALMZ72_BAT_MAX_VOLTAGE		4000	/* 4.00v current voltage */
 #define PALMZ72_BAT_MIN_VOLTAGE		3550	/* 3.55v critical voltage */
-#define PALMZ72_BAT_MAX_CURRENT		0	/* unknokn */
+#define PALMZ72_BAT_MAX_CURRENT		0	/* unknown */
 #define PALMZ72_BAT_MIN_CURRENT		0	/* unknown */
 #define PALMZ72_BAT_MAX_CHARGE		1	/* unknown */
 #define PALMZ72_BAT_MIN_CHARGE		1	/* unknown */
diff --git a/arch/arm/mach-s3c2400/Kconfig b/arch/arm/mach-s3c2400/Kconfig
index deab072..fdd8f5e 100644
--- a/arch/arm/mach-s3c2400/Kconfig
+++ b/arch/arm/mach-s3c2400/Kconfig
@@ -1,13 +1,7 @@
-# arch/arm/mach-s3c2400/Kconfig
-#
 # Copyright 2007 Simtec Electronics
 #
 # Licensed under GPLv2
 
-
-
 menu "S3C2400 Machines"
 
-
 endmenu
-
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index dd1fcc7..5547318 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -1,5 +1,3 @@
-# arch/arm/mach-s3c2410/Kconfig
-#
 # Copyright 2007 Simtec Electronics
 #
 # Licensed under GPLv2
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig
index c2bdc46..9a8c065 100644
--- a/arch/arm/mach-s3c2412/Kconfig
+++ b/arch/arm/mach-s3c2412/Kconfig
@@ -1,5 +1,3 @@
-# arch/arm/mach-s3c2412/Kconfig
-#
 # Copyright 2007 Simtec Electronics
 #
 # Licensed under GPLv2
@@ -90,6 +88,4 @@
 	help
 	  Say Y here if you are using an VSTMS board
 
-
 endmenu
-
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
index cf10e14..8087935 100644
--- a/arch/arm/mach-s3c2440/Kconfig
+++ b/arch/arm/mach-s3c2440/Kconfig
@@ -1,5 +1,3 @@
-# arch/arm/mach-s3c2440/Kconfig
-#
 # Copyright 2007 Simtec Electronics
 #
 # Licensed under GPLv2
@@ -122,4 +120,3 @@
 	  available via various sources. It can come with a 3.5" or 7" touch LCD.
 
 endmenu
-
diff --git a/arch/arm/mach-s3c2442/Kconfig b/arch/arm/mach-s3c2442/Kconfig
index 103e913..8d38118 100644
--- a/arch/arm/mach-s3c2442/Kconfig
+++ b/arch/arm/mach-s3c2442/Kconfig
@@ -1,5 +1,3 @@
-# arch/arm/mach-s3c2442/Kconfig
-#
 # Copyright 2007 Simtec Electronics
 #
 # Licensed under GPLv2
@@ -36,6 +34,4 @@
 	help
 	   Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone
 
-
 endmenu
-
diff --git a/arch/arm/mach-s3c2443/Kconfig b/arch/arm/mach-s3c2443/Kconfig
index 212141b..4314c44 100644
--- a/arch/arm/mach-s3c2443/Kconfig
+++ b/arch/arm/mach-s3c2443/Kconfig
@@ -1,5 +1,3 @@
-# arch/arm/mach-s3c2443/Kconfig
-#
 # Copyright 2007 Simtec Electronics
 #
 # Licensed under GPLv2
diff --git a/arch/arm/mach-s3c6400/Kconfig b/arch/arm/mach-s3c6400/Kconfig
index 770b720..a250bf6 100644
--- a/arch/arm/mach-s3c6400/Kconfig
+++ b/arch/arm/mach-s3c6400/Kconfig
@@ -1,5 +1,3 @@
-# arch/arm/mach-s3c6400/Kconfig
-#
 # Copyright 2008 Openmoko, Inc.
 #	Simtec Electronics, Ben Dooks <ben@simtec.co.uk>
 #
diff --git a/arch/arm/mach-s3c6400/setup-sdhci.c b/arch/arm/mach-s3c6400/setup-sdhci.c
index b93dafb..1039937 100644
--- a/arch/arm/mach-s3c6400/setup-sdhci.c
+++ b/arch/arm/mach-s3c6400/setup-sdhci.c
@@ -30,7 +30,7 @@
 	[0] = "hsmmc",
 	[1] = "hsmmc",
 	[2] = "mmc_bus",
-	/* [3] = "48m", - note not succesfully used yet */
+	/* [3] = "48m", - note not successfully used yet */
 };
 
 void s3c6400_setup_sdhci_cfg_card(struct platform_device *dev,
diff --git a/arch/arm/mach-s3c6410/Kconfig b/arch/arm/mach-s3c6410/Kconfig
index 72d4b11..162f456 100644
--- a/arch/arm/mach-s3c6410/Kconfig
+++ b/arch/arm/mach-s3c6410/Kconfig
@@ -1,5 +1,3 @@
-# arch/arm/mach-s3c6410/Kconfig
-#
 # Copyright 2008 Openmoko, Inc.
 # Copyright 2008 Simtec Electronics
 #
diff --git a/arch/arm/mach-s3c6410/setup-sdhci.c b/arch/arm/mach-s3c6410/setup-sdhci.c
index 20666f3..816d2d9 100644
--- a/arch/arm/mach-s3c6410/setup-sdhci.c
+++ b/arch/arm/mach-s3c6410/setup-sdhci.c
@@ -30,7 +30,7 @@
 	[0] = "hsmmc",
 	[1] = "hsmmc",
 	[2] = "mmc_bus",
-	/* [3] = "48m", - note not succesfully used yet */
+	/* [3] = "48m", - note not successfully used yet */
 };
 
 
diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
index 0dd2b8c..27ec167 100644
--- a/arch/arm/mach-s5pc100/Kconfig
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -1,5 +1,3 @@
-# arch/arm/mach-s5pc100/Kconfig
-#
 # Copyright 2009 Samsung Electronics Co.
 #	Byungho Min <bhmin@samsung.com>
 #
diff --git a/arch/arm/mach-sa1100/dma.c b/arch/arm/mach-sa1100/dma.c
index cb4521a..ad66035 100644
--- a/arch/arm/mach-sa1100/dma.c
+++ b/arch/arm/mach-sa1100/dma.c
@@ -65,7 +65,7 @@
 
 
 /**
- *	sa1100_request_dma - allocate one of the SA11x0's DMA chanels
+ *	sa1100_request_dma - allocate one of the SA11x0's DMA channels
  *	@device: The SA11x0 peripheral targeted by this request
  *	@device_id: An ascii name for the claiming device
  *	@callback: Function to be called when the DMA completes
diff --git a/arch/arm/mach-u300/include/mach/u300-regs.h b/arch/arm/mach-u300/include/mach/u300-regs.h
index 88333df..56721a0 100644
--- a/arch/arm/mach-u300/include/mach/u300-regs.h
+++ b/arch/arm/mach-u300/include/mach/u300-regs.h
@@ -6,7 +6,7 @@
  * Copyright (C) 2006-2009 ST-Ericsson AB
  * License terms: GNU General Public License (GPL) version 2
  * Basic register address definitions in physical memory and
- * some block defintions for core devices like the timer.
+ * some block definitions for core devices like the timer.
  * Author: Linus Walleij <linus.walleij@stericsson.com>
  */
 
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index 2b79964..f5abc51 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -54,7 +54,8 @@
 	 * We enforce the MAP_FIXED case.
 	 */
 	if (flags & MAP_FIXED) {
-		if (aliasing && flags & MAP_SHARED && addr & (SHMLBA - 1))
+		if (aliasing && flags & MAP_SHARED &&
+		    (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
 			return -EINVAL;
 		return addr;
 	}
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index 4cbca9d..996cbac 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -9,6 +9,7 @@
 obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o
 obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
 obj-$(CONFIG_MXC_PWM)  += pwm.o
+obj-$(CONFIG_USB_EHCI_MXC) += ehci.o
 obj-$(CONFIG_MXC_ULPI) += ulpi.o
 obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o
 obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o
diff --git a/arch/arm/plat-mxc/ehci.c b/arch/arm/plat-mxc/ehci.c
new file mode 100644
index 0000000..41599be
--- /dev/null
+++ b/arch/arm/plat-mxc/ehci.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * 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.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/mxc_ehci.h>
+
+#define USBCTRL_OTGBASE_OFFSET	0x600
+
+#define MX31_OTG_SIC_SHIFT	29
+#define MX31_OTG_SIC_MASK	(0xf << MX31_OTG_SIC_SHIFT)
+#define MX31_OTG_PM_BIT		(1 << 24)
+
+#define MX31_H2_SIC_SHIFT	21
+#define MX31_H2_SIC_MASK	(0xf << MX31_H2_SIC_SHIFT)
+#define MX31_H2_PM_BIT		(1 << 16)
+#define MX31_H2_DT_BIT		(1 << 5)
+
+#define MX31_H1_SIC_SHIFT	13
+#define MX31_H1_SIC_MASK	(0xf << MX31_H1_SIC_SHIFT)
+#define MX31_H1_PM_BIT		(1 << 8)
+#define MX31_H1_DT_BIT		(1 << 4)
+
+int mxc_set_usbcontrol(int port, unsigned int flags)
+{
+	unsigned int v;
+
+	if (cpu_is_mx31()) {
+		v = readl(IO_ADDRESS(MX31_OTG_BASE_ADDR +
+				     USBCTRL_OTGBASE_OFFSET));
+
+		switch (port) {
+		case 0:	/* OTG port */
+			v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT);
+			v |= (flags & MXC_EHCI_INTERFACE_MASK)
+					<< MX31_OTG_SIC_SHIFT;
+			if (flags & MXC_EHCI_POWER_PINS_ENABLED)
+				v |= MX31_OTG_PM_BIT;
+
+			break;
+		case 1: /* H1 port */
+			v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT);
+			v |= (flags & MXC_EHCI_INTERFACE_MASK)
+						<< MX31_H1_SIC_SHIFT;
+			if (flags & MXC_EHCI_POWER_PINS_ENABLED)
+				v |= MX31_H1_PM_BIT;
+
+			if (!(flags & MXC_EHCI_TTL_ENABLED))
+				v |= MX31_H1_DT_BIT;
+
+			break;
+		case 2:	/* H2 port */
+			v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT);
+			v |= (flags & MXC_EHCI_INTERFACE_MASK)
+						<< MX31_H2_SIC_SHIFT;
+			if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
+				v |= MX31_H2_PM_BIT;
+
+			if (!(flags & MXC_EHCI_TTL_ENABLED))
+				v |= MX31_H2_DT_BIT;
+
+			break;
+		}
+
+		writel(v, IO_ADDRESS(MX31_OTG_BASE_ADDR +
+				     USBCTRL_OTGBASE_OFFSET));
+		return 0;
+	}
+
+	printk(KERN_WARNING
+		"%s() unable to setup USBCONTROL for this CPU\n", __func__);
+	return -EINVAL;
+}
+EXPORT_SYMBOL(mxc_set_usbcontrol);
+
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
index eaabd4e..e1fc6da 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx3.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
@@ -112,7 +112,7 @@
  * setups a single pin:
  * 	- reserves the pin so that it is not claimed by another driver
  * 	- setups the iomux according to the configuration
- * 	- if the pin is configured as a GPIO, we claim it throug kernel gpiolib
+ * 	- if the pin is configured as a GPIO, we claim it through kernel gpiolib
  */
 int mxc_iomux_alloc_pin(const unsigned int pin, const char *label);
 /*
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h b/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h
index 9f13061..3887f3f 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h
@@ -48,7 +48,7 @@
  * setups a single pin:
  * 	- reserves the pin so that it is not claimed by another driver
  * 	- setups the iomux according to the configuration
- * 	- if the pin is configured as a GPIO, we claim it throug kernel gpiolib
+ * 	- if the pin is configured as a GPIO, we claim it through kernel gpiolib
  */
 int mxc_iomux_alloc_pin(const unsigned int pin_mode, const char *label);
 /*
diff --git a/arch/arm/plat-mxc/include/mach/mxc_ehci.h b/arch/arm/plat-mxc/include/mach/mxc_ehci.h
new file mode 100644
index 0000000..8f79623
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_ehci.h
@@ -0,0 +1,37 @@
+#ifndef __INCLUDE_ASM_ARCH_MXC_EHCI_H
+#define __INCLUDE_ASM_ARCH_MXC_EHCI_H
+
+/* values for portsc field */
+#define MXC_EHCI_PHY_LOW_POWER_SUSPEND	(1 << 23)
+#define MXC_EHCI_FORCE_FS		(1 << 24)
+#define MXC_EHCI_UTMI_8BIT		(0 << 28)
+#define MXC_EHCI_UTMI_16BIT		(1 << 28)
+#define MXC_EHCI_SERIAL			(1 << 29)
+#define MXC_EHCI_MODE_UTMI		(0 << 30)
+#define MXC_EHCI_MODE_PHILIPS		(1 << 30)
+#define MXC_EHCI_MODE_ULPI		(2 << 30)
+#define MXC_EHCI_MODE_SERIAL		(3 << 30)
+
+/* values for flags field */
+#define MXC_EHCI_INTERFACE_DIFF_UNI	(0 << 0)
+#define MXC_EHCI_INTERFACE_DIFF_BI	(1 << 0)
+#define MXC_EHCI_INTERFACE_SINGLE_UNI	(2 << 0)
+#define MXC_EHCI_INTERFACE_SINGLE_BI	(3 << 0)
+#define MXC_EHCI_INTERFACE_MASK		(0xf)
+
+#define MXC_EHCI_POWER_PINS_ENABLED	(1 << 5)
+#define MXC_EHCI_TTL_ENABLED		(1 << 6)
+
+struct mxc_usbh_platform_data {
+	int (*init)(struct platform_device *pdev);
+	int (*exit)(struct platform_device *pdev);
+
+	unsigned int		 portsc;
+	unsigned int		 flags;
+	struct otg_transceiver	*otg;
+};
+
+int mxc_set_usbcontrol(int port, unsigned int flags);
+
+#endif /* __INCLUDE_ASM_ARCH_MXC_EHCI_H */
+
diff --git a/arch/arm/plat-mxc/pwm.c b/arch/arm/plat-mxc/pwm.c
index 5cdbd60..4ff6dfe 100644
--- a/arch/arm/plat-mxc/pwm.c
+++ b/arch/arm/plat-mxc/pwm.c
@@ -94,7 +94,7 @@
 		 * register to follow the ratio of duty_ns vs. period_ns
 		 * accordingly.
 		 *
-		 * This is good enought for programming the brightness of
+		 * This is good enough for programming the brightness of
 		 * the LCD backlight.
 		 *
 		 * The real implementation would divide PERCLK[0] first by
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index be4ce07..d17375e 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -1252,7 +1252,7 @@
  * 					      OMAP_DMA_DYNAMIC_CHAIN
  * @params - Channel parameters
  *
- * @return - Succes : 0
+ * @return - Success : 0
  * 	     Failure: -EINVAL/-ENOMEM
  */
 int omap_request_dma_chain(int dev_id, const char *dev_name,
diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
index 78a4ce5..d3eea4f 100644
--- a/arch/arm/plat-omap/fb.c
+++ b/arch/arm/plat-omap/fb.c
@@ -28,13 +28,13 @@
 #include <linux/platform_device.h>
 #include <linux/bootmem.h>
 #include <linux/io.h>
+#include <linux/omapfb.h>
 
 #include <mach/hardware.h>
 #include <asm/mach/map.h>
 
 #include <plat/board.h>
 #include <plat/sram.h>
-#include <plat/omapfb.h>
 
 #if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
 
@@ -55,6 +55,10 @@
 	.num_resources = 0,
 };
 
+void omapfb_set_platform_data(struct omapfb_platform_data *data)
+{
+}
+
 static inline int ranges_overlap(unsigned long start1, unsigned long size1,
 				 unsigned long start2, unsigned long size2)
 {
@@ -327,7 +331,33 @@
 
 arch_initcall(omap_init_fb);
 
-#else
+#elif defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
+
+static u64 omap_fb_dma_mask = ~(u32)0;
+static struct omapfb_platform_data omapfb_config;
+
+static struct platform_device omap_fb_device = {
+	.name		= "omapfb",
+	.id		= -1,
+	.dev = {
+		.dma_mask		= &omap_fb_dma_mask,
+		.coherent_dma_mask	= ~(u32)0,
+		.platform_data		= &omapfb_config,
+	},
+	.num_resources = 0,
+};
+
+void omapfb_set_platform_data(struct omapfb_platform_data *data)
+{
+	omapfb_config = *data;
+}
+
+static inline int omap_init_fb(void)
+{
+	return platform_device_register(&omap_fb_device);
+}
+
+arch_initcall(omap_init_fb);
 
 void omapfb_reserve_sdram(void) {}
 unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
@@ -339,5 +369,20 @@
 	return 0;
 }
 
+#else
+
+void omapfb_set_platform_data(struct omapfb_platform_data *data)
+{
+}
+
+void omapfb_reserve_sdram(void) {}
+unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
+				  unsigned long sram_vstart,
+				  unsigned long sram_size,
+				  unsigned long start_avail,
+				  unsigned long size_avail)
+{
+	return 0;
+}
 
 #endif
diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h
new file mode 100644
index 0000000..c66e464
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/display.h
@@ -0,0 +1,575 @@
+/*
+ * linux/include/asm-arm/arch-omap/display.h
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ASM_ARCH_OMAP_DISPLAY_H
+#define __ASM_ARCH_OMAP_DISPLAY_H
+
+#include <linux/list.h>
+#include <linux/kobject.h>
+#include <linux/device.h>
+#include <asm/atomic.h>
+
+#define DISPC_IRQ_FRAMEDONE		(1 << 0)
+#define DISPC_IRQ_VSYNC			(1 << 1)
+#define DISPC_IRQ_EVSYNC_EVEN		(1 << 2)
+#define DISPC_IRQ_EVSYNC_ODD		(1 << 3)
+#define DISPC_IRQ_ACBIAS_COUNT_STAT	(1 << 4)
+#define DISPC_IRQ_PROG_LINE_NUM		(1 << 5)
+#define DISPC_IRQ_GFX_FIFO_UNDERFLOW	(1 << 6)
+#define DISPC_IRQ_GFX_END_WIN		(1 << 7)
+#define DISPC_IRQ_PAL_GAMMA_MASK	(1 << 8)
+#define DISPC_IRQ_OCP_ERR		(1 << 9)
+#define DISPC_IRQ_VID1_FIFO_UNDERFLOW	(1 << 10)
+#define DISPC_IRQ_VID1_END_WIN		(1 << 11)
+#define DISPC_IRQ_VID2_FIFO_UNDERFLOW	(1 << 12)
+#define DISPC_IRQ_VID2_END_WIN		(1 << 13)
+#define DISPC_IRQ_SYNC_LOST		(1 << 14)
+#define DISPC_IRQ_SYNC_LOST_DIGIT	(1 << 15)
+#define DISPC_IRQ_WAKEUP		(1 << 16)
+
+struct omap_dss_device;
+struct omap_overlay_manager;
+
+enum omap_display_type {
+	OMAP_DISPLAY_TYPE_NONE		= 0,
+	OMAP_DISPLAY_TYPE_DPI		= 1 << 0,
+	OMAP_DISPLAY_TYPE_DBI		= 1 << 1,
+	OMAP_DISPLAY_TYPE_SDI		= 1 << 2,
+	OMAP_DISPLAY_TYPE_DSI		= 1 << 3,
+	OMAP_DISPLAY_TYPE_VENC		= 1 << 4,
+};
+
+enum omap_plane {
+	OMAP_DSS_GFX	= 0,
+	OMAP_DSS_VIDEO1	= 1,
+	OMAP_DSS_VIDEO2	= 2
+};
+
+enum omap_channel {
+	OMAP_DSS_CHANNEL_LCD	= 0,
+	OMAP_DSS_CHANNEL_DIGIT	= 1,
+};
+
+enum omap_color_mode {
+	OMAP_DSS_COLOR_CLUT1	= 1 << 0,  /* BITMAP 1 */
+	OMAP_DSS_COLOR_CLUT2	= 1 << 1,  /* BITMAP 2 */
+	OMAP_DSS_COLOR_CLUT4	= 1 << 2,  /* BITMAP 4 */
+	OMAP_DSS_COLOR_CLUT8	= 1 << 3,  /* BITMAP 8 */
+	OMAP_DSS_COLOR_RGB12U	= 1 << 4,  /* RGB12, 16-bit container */
+	OMAP_DSS_COLOR_ARGB16	= 1 << 5,  /* ARGB16 */
+	OMAP_DSS_COLOR_RGB16	= 1 << 6,  /* RGB16 */
+	OMAP_DSS_COLOR_RGB24U	= 1 << 7,  /* RGB24, 32-bit container */
+	OMAP_DSS_COLOR_RGB24P	= 1 << 8,  /* RGB24, 24-bit container */
+	OMAP_DSS_COLOR_YUV2	= 1 << 9,  /* YUV2 4:2:2 co-sited */
+	OMAP_DSS_COLOR_UYVY	= 1 << 10, /* UYVY 4:2:2 co-sited */
+	OMAP_DSS_COLOR_ARGB32	= 1 << 11, /* ARGB32 */
+	OMAP_DSS_COLOR_RGBA32	= 1 << 12, /* RGBA32 */
+	OMAP_DSS_COLOR_RGBX32	= 1 << 13, /* RGBx32 */
+
+	OMAP_DSS_COLOR_GFX_OMAP2 =
+		OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
+		OMAP_DSS_COLOR_CLUT4 | OMAP_DSS_COLOR_CLUT8 |
+		OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_RGB16 |
+		OMAP_DSS_COLOR_RGB24U | OMAP_DSS_COLOR_RGB24P,
+
+	OMAP_DSS_COLOR_VID_OMAP2 =
+		OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U |
+		OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_YUV2 |
+		OMAP_DSS_COLOR_UYVY,
+
+	OMAP_DSS_COLOR_GFX_OMAP3 =
+		OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
+		OMAP_DSS_COLOR_CLUT4 | OMAP_DSS_COLOR_CLUT8 |
+		OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_ARGB16 |
+		OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U |
+		OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_ARGB32 |
+		OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32,
+
+	OMAP_DSS_COLOR_VID1_OMAP3 =
+		OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_RGB16 |
+		OMAP_DSS_COLOR_RGB24U | OMAP_DSS_COLOR_RGB24P |
+		OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_UYVY,
+
+	OMAP_DSS_COLOR_VID2_OMAP3 =
+		OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_ARGB16 |
+		OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U |
+		OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_YUV2 |
+		OMAP_DSS_COLOR_UYVY | OMAP_DSS_COLOR_ARGB32 |
+		OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32,
+};
+
+enum omap_lcd_display_type {
+	OMAP_DSS_LCD_DISPLAY_STN,
+	OMAP_DSS_LCD_DISPLAY_TFT,
+};
+
+enum omap_dss_load_mode {
+	OMAP_DSS_LOAD_CLUT_AND_FRAME	= 0,
+	OMAP_DSS_LOAD_CLUT_ONLY		= 1,
+	OMAP_DSS_LOAD_FRAME_ONLY	= 2,
+	OMAP_DSS_LOAD_CLUT_ONCE_FRAME	= 3,
+};
+
+enum omap_dss_trans_key_type {
+	OMAP_DSS_COLOR_KEY_GFX_DST = 0,
+	OMAP_DSS_COLOR_KEY_VID_SRC = 1,
+};
+
+enum omap_rfbi_te_mode {
+	OMAP_DSS_RFBI_TE_MODE_1 = 1,
+	OMAP_DSS_RFBI_TE_MODE_2 = 2,
+};
+
+enum omap_panel_config {
+	OMAP_DSS_LCD_IVS		= 1<<0,
+	OMAP_DSS_LCD_IHS		= 1<<1,
+	OMAP_DSS_LCD_IPC		= 1<<2,
+	OMAP_DSS_LCD_IEO		= 1<<3,
+	OMAP_DSS_LCD_RF			= 1<<4,
+	OMAP_DSS_LCD_ONOFF		= 1<<5,
+
+	OMAP_DSS_LCD_TFT		= 1<<20,
+};
+
+enum omap_dss_venc_type {
+	OMAP_DSS_VENC_TYPE_COMPOSITE,
+	OMAP_DSS_VENC_TYPE_SVIDEO,
+};
+
+enum omap_display_caps {
+	OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE	= 1 << 0,
+	OMAP_DSS_DISPLAY_CAP_TEAR_ELIM		= 1 << 1,
+};
+
+enum omap_dss_update_mode {
+	OMAP_DSS_UPDATE_DISABLED = 0,
+	OMAP_DSS_UPDATE_AUTO,
+	OMAP_DSS_UPDATE_MANUAL,
+};
+
+enum omap_dss_display_state {
+	OMAP_DSS_DISPLAY_DISABLED = 0,
+	OMAP_DSS_DISPLAY_ACTIVE,
+	OMAP_DSS_DISPLAY_SUSPENDED,
+};
+
+/* XXX perhaps this should be removed */
+enum omap_dss_overlay_managers {
+	OMAP_DSS_OVL_MGR_LCD,
+	OMAP_DSS_OVL_MGR_TV,
+};
+
+enum omap_dss_rotation_type {
+	OMAP_DSS_ROT_DMA = 0,
+	OMAP_DSS_ROT_VRFB = 1,
+};
+
+/* clockwise rotation angle */
+enum omap_dss_rotation_angle {
+	OMAP_DSS_ROT_0   = 0,
+	OMAP_DSS_ROT_90  = 1,
+	OMAP_DSS_ROT_180 = 2,
+	OMAP_DSS_ROT_270 = 3,
+};
+
+enum omap_overlay_caps {
+	OMAP_DSS_OVL_CAP_SCALE = 1 << 0,
+	OMAP_DSS_OVL_CAP_DISPC = 1 << 1,
+};
+
+enum omap_overlay_manager_caps {
+	OMAP_DSS_OVL_MGR_CAP_DISPC = 1 << 0,
+};
+
+/* RFBI */
+
+struct rfbi_timings {
+	int cs_on_time;
+	int cs_off_time;
+	int we_on_time;
+	int we_off_time;
+	int re_on_time;
+	int re_off_time;
+	int we_cycle_time;
+	int re_cycle_time;
+	int cs_pulse_width;
+	int access_time;
+
+	int clk_div;
+
+	u32 tim[5];             /* set by rfbi_convert_timings() */
+
+	int converted;
+};
+
+void omap_rfbi_write_command(const void *buf, u32 len);
+void omap_rfbi_read_data(void *buf, u32 len);
+void omap_rfbi_write_data(const void *buf, u32 len);
+void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
+		u16 x, u16 y,
+		u16 w, u16 h);
+int omap_rfbi_enable_te(bool enable, unsigned line);
+int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
+			     unsigned hs_pulse_time, unsigned vs_pulse_time,
+			     int hs_pol_inv, int vs_pol_inv, int extif_div);
+
+/* DSI */
+void dsi_bus_lock(void);
+void dsi_bus_unlock(void);
+int dsi_vc_dcs_write(int channel, u8 *data, int len);
+int dsi_vc_dcs_write_nosync(int channel, u8 *data, int len);
+int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen);
+int dsi_vc_set_max_rx_packet_size(int channel, u16 len);
+int dsi_vc_send_null(int channel);
+int dsi_vc_send_bta_sync(int channel);
+
+/* Board specific data */
+struct omap_dss_board_info {
+	int (*get_last_off_on_transaction_id)(struct device *dev);
+	int num_devices;
+	struct omap_dss_device **devices;
+	struct omap_dss_device *default_device;
+};
+
+struct omap_video_timings {
+	/* Unit: pixels */
+	u16 x_res;
+	/* Unit: pixels */
+	u16 y_res;
+	/* Unit: KHz */
+	u32 pixel_clock;
+	/* Unit: pixel clocks */
+	u16 hsw;	/* Horizontal synchronization pulse width */
+	/* Unit: pixel clocks */
+	u16 hfp;	/* Horizontal front porch */
+	/* Unit: pixel clocks */
+	u16 hbp;	/* Horizontal back porch */
+	/* Unit: line clocks */
+	u16 vsw;	/* Vertical synchronization pulse width */
+	/* Unit: line clocks */
+	u16 vfp;	/* Vertical front porch */
+	/* Unit: line clocks */
+	u16 vbp;	/* Vertical back porch */
+};
+
+#ifdef CONFIG_OMAP2_DSS_VENC
+/* Hardcoded timings for tv modes. Venc only uses these to
+ * identify the mode, and does not actually use the configs
+ * itself. However, the configs should be something that
+ * a normal monitor can also show */
+const extern struct omap_video_timings omap_dss_pal_timings;
+const extern struct omap_video_timings omap_dss_ntsc_timings;
+#endif
+
+struct omap_overlay_info {
+	bool enabled;
+
+	u32 paddr;
+	void __iomem *vaddr;
+	u16 screen_width;
+	u16 width;
+	u16 height;
+	enum omap_color_mode color_mode;
+	u8 rotation;
+	enum omap_dss_rotation_type rotation_type;
+	bool mirror;
+
+	u16 pos_x;
+	u16 pos_y;
+	u16 out_width;	/* if 0, out_width == width */
+	u16 out_height;	/* if 0, out_height == height */
+	u8 global_alpha;
+};
+
+struct omap_overlay {
+	struct kobject kobj;
+	struct list_head list;
+
+	/* static fields */
+	const char *name;
+	int id;
+	enum omap_color_mode supported_modes;
+	enum omap_overlay_caps caps;
+
+	/* dynamic fields */
+	struct omap_overlay_manager *manager;
+	struct omap_overlay_info info;
+
+	/* if true, info has been changed, but not applied() yet */
+	bool info_dirty;
+
+	int (*set_manager)(struct omap_overlay *ovl,
+		struct omap_overlay_manager *mgr);
+	int (*unset_manager)(struct omap_overlay *ovl);
+
+	int (*set_overlay_info)(struct omap_overlay *ovl,
+			struct omap_overlay_info *info);
+	void (*get_overlay_info)(struct omap_overlay *ovl,
+			struct omap_overlay_info *info);
+
+	int (*wait_for_go)(struct omap_overlay *ovl);
+};
+
+struct omap_overlay_manager_info {
+	u32 default_color;
+
+	enum omap_dss_trans_key_type trans_key_type;
+	u32 trans_key;
+	bool trans_enabled;
+
+	bool alpha_enabled;
+};
+
+struct omap_overlay_manager {
+	struct kobject kobj;
+	struct list_head list;
+
+	/* static fields */
+	const char *name;
+	int id;
+	enum omap_overlay_manager_caps caps;
+	int num_overlays;
+	struct omap_overlay **overlays;
+	enum omap_display_type supported_displays;
+
+	/* dynamic fields */
+	struct omap_dss_device *device;
+	struct omap_overlay_manager_info info;
+
+	bool device_changed;
+	/* if true, info has been changed but not applied() yet */
+	bool info_dirty;
+
+	int (*set_device)(struct omap_overlay_manager *mgr,
+		struct omap_dss_device *dssdev);
+	int (*unset_device)(struct omap_overlay_manager *mgr);
+
+	int (*set_manager_info)(struct omap_overlay_manager *mgr,
+			struct omap_overlay_manager_info *info);
+	void (*get_manager_info)(struct omap_overlay_manager *mgr,
+			struct omap_overlay_manager_info *info);
+
+	int (*apply)(struct omap_overlay_manager *mgr);
+	int (*wait_for_go)(struct omap_overlay_manager *mgr);
+};
+
+struct omap_dss_device {
+	struct device dev;
+
+	enum omap_display_type type;
+
+	union {
+		struct {
+			u8 data_lines;
+		} dpi;
+
+		struct {
+			u8 channel;
+			u8 data_lines;
+		} rfbi;
+
+		struct {
+			u8 datapairs;
+		} sdi;
+
+		struct {
+			u8 clk_lane;
+			u8 clk_pol;
+			u8 data1_lane;
+			u8 data1_pol;
+			u8 data2_lane;
+			u8 data2_pol;
+
+			struct {
+				u16 regn;
+				u16 regm;
+				u16 regm3;
+				u16 regm4;
+
+				u16 lp_clk_div;
+
+				u16 lck_div;
+				u16 pck_div;
+			} div;
+
+			bool ext_te;
+			u8 ext_te_gpio;
+		} dsi;
+
+		struct {
+			enum omap_dss_venc_type type;
+			bool invert_polarity;
+		} venc;
+	} phy;
+
+	struct {
+		struct omap_video_timings timings;
+
+		int acbi;	/* ac-bias pin transitions per interrupt */
+		/* Unit: line clocks */
+		int acb;	/* ac-bias pin frequency */
+
+		enum omap_panel_config config;
+
+		u8 recommended_bpp;
+
+		struct omap_dss_device *ctrl;
+	} panel;
+
+	struct {
+		u8 pixel_size;
+		struct rfbi_timings rfbi_timings;
+		struct omap_dss_device *panel;
+	} ctrl;
+
+	int reset_gpio;
+
+	int max_backlight_level;
+
+	const char *name;
+
+	/* used to match device to driver */
+	const char *driver_name;
+
+	void *data;
+
+	struct omap_dss_driver *driver;
+
+	/* helper variable for driver suspend/resume */
+	bool activate_after_resume;
+
+	enum omap_display_caps caps;
+
+	struct omap_overlay_manager *manager;
+
+	enum omap_dss_display_state state;
+
+	int (*enable)(struct omap_dss_device *dssdev);
+	void (*disable)(struct omap_dss_device *dssdev);
+
+	int (*suspend)(struct omap_dss_device *dssdev);
+	int (*resume)(struct omap_dss_device *dssdev);
+
+	void (*get_resolution)(struct omap_dss_device *dssdev,
+			u16 *xres, u16 *yres);
+	int (*get_recommended_bpp)(struct omap_dss_device *dssdev);
+
+	int (*check_timings)(struct omap_dss_device *dssdev,
+			struct omap_video_timings *timings);
+	void (*set_timings)(struct omap_dss_device *dssdev,
+			struct omap_video_timings *timings);
+	void (*get_timings)(struct omap_dss_device *dssdev,
+			struct omap_video_timings *timings);
+	int (*update)(struct omap_dss_device *dssdev,
+			       u16 x, u16 y, u16 w, u16 h);
+	int (*sync)(struct omap_dss_device *dssdev);
+	int (*wait_vsync)(struct omap_dss_device *dssdev);
+
+	int (*set_update_mode)(struct omap_dss_device *dssdev,
+			enum omap_dss_update_mode);
+	enum omap_dss_update_mode (*get_update_mode)
+		(struct omap_dss_device *dssdev);
+
+	int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
+	int (*get_te)(struct omap_dss_device *dssdev);
+
+	u8 (*get_rotate)(struct omap_dss_device *dssdev);
+	int (*set_rotate)(struct omap_dss_device *dssdev, u8 rotate);
+
+	bool (*get_mirror)(struct omap_dss_device *dssdev);
+	int (*set_mirror)(struct omap_dss_device *dssdev, bool enable);
+
+	int (*run_test)(struct omap_dss_device *dssdev, int test);
+	int (*memory_read)(struct omap_dss_device *dssdev,
+			void *buf, size_t size,
+			u16 x, u16 y, u16 w, u16 h);
+
+	int (*set_wss)(struct omap_dss_device *dssdev, u32 wss);
+	u32 (*get_wss)(struct omap_dss_device *dssdev);
+
+	/* platform specific  */
+	int (*platform_enable)(struct omap_dss_device *dssdev);
+	void (*platform_disable)(struct omap_dss_device *dssdev);
+	int (*set_backlight)(struct omap_dss_device *dssdev, int level);
+	int (*get_backlight)(struct omap_dss_device *dssdev);
+};
+
+struct omap_dss_driver {
+	struct device_driver driver;
+
+	int (*probe)(struct omap_dss_device *);
+	void (*remove)(struct omap_dss_device *);
+
+	int (*enable)(struct omap_dss_device *display);
+	void (*disable)(struct omap_dss_device *display);
+	int (*suspend)(struct omap_dss_device *display);
+	int (*resume)(struct omap_dss_device *display);
+	int (*run_test)(struct omap_dss_device *display, int test);
+
+	void (*setup_update)(struct omap_dss_device *dssdev,
+			u16 x, u16 y, u16 w, u16 h);
+
+	int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
+	int (*wait_for_te)(struct omap_dss_device *dssdev);
+
+	u8 (*get_rotate)(struct omap_dss_device *dssdev);
+	int (*set_rotate)(struct omap_dss_device *dssdev, u8 rotate);
+
+	bool (*get_mirror)(struct omap_dss_device *dssdev);
+	int (*set_mirror)(struct omap_dss_device *dssdev, bool enable);
+
+	int (*memory_read)(struct omap_dss_device *dssdev,
+			void *buf, size_t size,
+			u16 x, u16 y, u16 w, u16 h);
+};
+
+int omap_dss_register_driver(struct omap_dss_driver *);
+void omap_dss_unregister_driver(struct omap_dss_driver *);
+
+int omap_dss_register_device(struct omap_dss_device *);
+void omap_dss_unregister_device(struct omap_dss_device *);
+
+void omap_dss_get_device(struct omap_dss_device *dssdev);
+void omap_dss_put_device(struct omap_dss_device *dssdev);
+#define for_each_dss_dev(d) while ((d = omap_dss_get_next_device(d)) != NULL)
+struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from);
+struct omap_dss_device *omap_dss_find_device(void *data,
+		int (*match)(struct omap_dss_device *dssdev, void *data));
+
+int omap_dss_start_device(struct omap_dss_device *dssdev);
+void omap_dss_stop_device(struct omap_dss_device *dssdev);
+
+int omap_dss_get_num_overlay_managers(void);
+struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
+
+int omap_dss_get_num_overlays(void);
+struct omap_overlay *omap_dss_get_overlay(int num);
+
+typedef void (*omap_dispc_isr_t) (void *arg, u32 mask);
+int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
+int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
+
+int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout);
+int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
+		unsigned long timeout);
+
+#define to_dss_driver(x) container_of((x), struct omap_dss_driver, driver)
+#define to_dss_device(x) container_of((x), struct omap_dss_device, dev)
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/omap16xx.h b/arch/arm/plat-omap/include/plat/omap16xx.h
index 0e69b50..7560b4d 100644
--- a/arch/arm/plat-omap/include/plat/omap16xx.h
+++ b/arch/arm/plat-omap/include/plat/omap16xx.h
@@ -124,7 +124,7 @@
 #define TIPB_SWITCH_BASE		 (0xfffbc800)
 #define OMAP16XX_MMCSD2_SSW_MPU_CONF	(TIPB_SWITCH_BASE + 0x160)
 
-/* UART3 Registers Maping through MPU bus */
+/* UART3 Registers Mapping through MPU bus */
 #define UART3_RHR               (OMAP_UART3_BASE + 0)
 #define UART3_THR               (OMAP_UART3_BASE + 0)
 #define UART3_DLL               (OMAP_UART3_BASE + 0)
diff --git a/arch/arm/plat-omap/include/plat/omapfb.h b/arch/arm/plat-omap/include/plat/omapfb.h
deleted file mode 100644
index bfef7ab..0000000
--- a/arch/arm/plat-omap/include/plat/omapfb.h
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * File: arch/arm/plat-omap/include/mach/omapfb.h
- *
- * Framebuffer driver for TI OMAP boards
- *
- * Copyright (C) 2004 Nokia Corporation
- * Author: Imre Deak <imre.deak@nokia.com>
- *
- * 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.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#ifndef __OMAPFB_H
-#define __OMAPFB_H
-
-#include <asm/ioctl.h>
-#include <asm/types.h>
-
-/* IOCTL commands. */
-
-#define OMAP_IOW(num, dtype)	_IOW('O', num, dtype)
-#define OMAP_IOR(num, dtype)	_IOR('O', num, dtype)
-#define OMAP_IOWR(num, dtype)	_IOWR('O', num, dtype)
-#define OMAP_IO(num)		_IO('O', num)
-
-#define OMAPFB_MIRROR		OMAP_IOW(31, int)
-#define OMAPFB_SYNC_GFX		OMAP_IO(37)
-#define OMAPFB_VSYNC		OMAP_IO(38)
-#define OMAPFB_SET_UPDATE_MODE	OMAP_IOW(40, int)
-#define OMAPFB_GET_CAPS		OMAP_IOR(42, struct omapfb_caps)
-#define OMAPFB_GET_UPDATE_MODE	OMAP_IOW(43, int)
-#define OMAPFB_LCD_TEST		OMAP_IOW(45, int)
-#define OMAPFB_CTRL_TEST	OMAP_IOW(46, int)
-#define OMAPFB_UPDATE_WINDOW_OLD OMAP_IOW(47, struct omapfb_update_window_old)
-#define OMAPFB_SET_COLOR_KEY	OMAP_IOW(50, struct omapfb_color_key)
-#define OMAPFB_GET_COLOR_KEY	OMAP_IOW(51, struct omapfb_color_key)
-#define OMAPFB_SETUP_PLANE	OMAP_IOW(52, struct omapfb_plane_info)
-#define OMAPFB_QUERY_PLANE	OMAP_IOW(53, struct omapfb_plane_info)
-#define OMAPFB_UPDATE_WINDOW	OMAP_IOW(54, struct omapfb_update_window)
-#define OMAPFB_SETUP_MEM	OMAP_IOW(55, struct omapfb_mem_info)
-#define OMAPFB_QUERY_MEM	OMAP_IOW(56, struct omapfb_mem_info)
-
-#define OMAPFB_CAPS_GENERIC_MASK	0x00000fff
-#define OMAPFB_CAPS_LCDC_MASK		0x00fff000
-#define OMAPFB_CAPS_PANEL_MASK		0xff000000
-
-#define OMAPFB_CAPS_MANUAL_UPDATE	0x00001000
-#define OMAPFB_CAPS_TEARSYNC		0x00002000
-#define OMAPFB_CAPS_PLANE_RELOCATE_MEM	0x00004000
-#define OMAPFB_CAPS_PLANE_SCALE		0x00008000
-#define OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE	0x00010000
-#define OMAPFB_CAPS_WINDOW_SCALE	0x00020000
-#define OMAPFB_CAPS_WINDOW_OVERLAY	0x00040000
-#define OMAPFB_CAPS_WINDOW_ROTATE	0x00080000
-#define OMAPFB_CAPS_SET_BACKLIGHT	0x01000000
-
-/* Values from DSP must map to lower 16-bits */
-#define OMAPFB_FORMAT_MASK		0x00ff
-#define OMAPFB_FORMAT_FLAG_DOUBLE	0x0100
-#define OMAPFB_FORMAT_FLAG_TEARSYNC	0x0200
-#define OMAPFB_FORMAT_FLAG_FORCE_VSYNC	0x0400
-#define OMAPFB_FORMAT_FLAG_ENABLE_OVERLAY	0x0800
-#define OMAPFB_FORMAT_FLAG_DISABLE_OVERLAY	0x1000
-
-#define OMAPFB_EVENT_READY	1
-#define OMAPFB_EVENT_DISABLED	2
-
-#define OMAPFB_MEMTYPE_SDRAM		0
-#define OMAPFB_MEMTYPE_SRAM		1
-#define OMAPFB_MEMTYPE_MAX		1
-
-enum omapfb_color_format {
-	OMAPFB_COLOR_RGB565 = 0,
-	OMAPFB_COLOR_YUV422,
-	OMAPFB_COLOR_YUV420,
-	OMAPFB_COLOR_CLUT_8BPP,
-	OMAPFB_COLOR_CLUT_4BPP,
-	OMAPFB_COLOR_CLUT_2BPP,
-	OMAPFB_COLOR_CLUT_1BPP,
-	OMAPFB_COLOR_RGB444,
-	OMAPFB_COLOR_YUY422,
-};
-
-struct omapfb_update_window {
-	__u32 x, y;
-	__u32 width, height;
-	__u32 format;
-	__u32 out_x, out_y;
-	__u32 out_width, out_height;
-	__u32 reserved[8];
-};
-
-struct omapfb_update_window_old {
-	__u32 x, y;
-	__u32 width, height;
-	__u32 format;
-};
-
-enum omapfb_plane {
-	OMAPFB_PLANE_GFX = 0,
-	OMAPFB_PLANE_VID1,
-	OMAPFB_PLANE_VID2,
-};
-
-enum omapfb_channel_out {
-	OMAPFB_CHANNEL_OUT_LCD = 0,
-	OMAPFB_CHANNEL_OUT_DIGIT,
-};
-
-struct omapfb_plane_info {
-	__u32 pos_x;
-	__u32 pos_y;
-	__u8  enabled;
-	__u8  channel_out;
-	__u8  mirror;
-	__u8  reserved1;
-	__u32 out_width;
-	__u32 out_height;
-	__u32 reserved2[12];
-};
-
-struct omapfb_mem_info {
-	__u32 size;
-	__u8  type;
-	__u8  reserved[3];
-};
-
-struct omapfb_caps {
-	__u32 ctrl;
-	__u32 plane_color;
-	__u32 wnd_color;
-};
-
-enum omapfb_color_key_type {
-	OMAPFB_COLOR_KEY_DISABLED = 0,
-	OMAPFB_COLOR_KEY_GFX_DST,
-	OMAPFB_COLOR_KEY_VID_SRC,
-};
-
-struct omapfb_color_key {
-	__u8  channel_out;
-	__u32 background;
-	__u32 trans_key;
-	__u8  key_type;
-};
-
-enum omapfb_update_mode {
-	OMAPFB_UPDATE_DISABLED = 0,
-	OMAPFB_AUTO_UPDATE,
-	OMAPFB_MANUAL_UPDATE
-};
-
-#ifdef __KERNEL__
-
-#include <linux/completion.h>
-#include <linux/interrupt.h>
-#include <linux/fb.h>
-#include <linux/mutex.h>
-
-#include <plat/board.h>
-
-#define OMAP_LCDC_INV_VSYNC             0x0001
-#define OMAP_LCDC_INV_HSYNC             0x0002
-#define OMAP_LCDC_INV_PIX_CLOCK         0x0004
-#define OMAP_LCDC_INV_OUTPUT_EN         0x0008
-#define OMAP_LCDC_HSVS_RISING_EDGE      0x0010
-#define OMAP_LCDC_HSVS_OPPOSITE         0x0020
-
-#define OMAP_LCDC_SIGNAL_MASK		0x003f
-
-#define OMAP_LCDC_PANEL_TFT		0x0100
-
-#define OMAPFB_PLANE_XRES_MIN		8
-#define OMAPFB_PLANE_YRES_MIN		8
-
-#ifdef CONFIG_ARCH_OMAP1
-#define OMAPFB_PLANE_NUM		1
-#else
-#define OMAPFB_PLANE_NUM		3
-#endif
-
-struct omapfb_device;
-
-struct lcd_panel {
-	const char	*name;
-	int		config;		/* TFT/STN, signal inversion */
-	int		bpp;		/* Pixel format in fb mem */
-	int		data_lines;	/* Lines on LCD HW interface */
-
-	int		x_res, y_res;
-	int		pixel_clock;	/* In kHz */
-	int		hsw;		/* Horizontal synchronization
-					   pulse width */
-	int		hfp;		/* Horizontal front porch */
-	int		hbp;		/* Horizontal back porch */
-	int		vsw;		/* Vertical synchronization
-					   pulse width */
-	int		vfp;		/* Vertical front porch */
-	int		vbp;		/* Vertical back porch */
-	int		acb;		/* ac-bias pin frequency */
-	int		pcd;		/* pixel clock divider.
-					   Obsolete use pixel_clock instead */
-
-	int		(*init)		(struct lcd_panel *panel,
-					 struct omapfb_device *fbdev);
-	void		(*cleanup)	(struct lcd_panel *panel);
-	int		(*enable)	(struct lcd_panel *panel);
-	void		(*disable)	(struct lcd_panel *panel);
-	unsigned long	(*get_caps)	(struct lcd_panel *panel);
-	int		(*set_bklight_level)(struct lcd_panel *panel,
-					     unsigned int level);
-	unsigned int	(*get_bklight_level)(struct lcd_panel *panel);
-	unsigned int	(*get_bklight_max)  (struct lcd_panel *panel);
-	int		(*run_test)	(struct lcd_panel *panel, int test_num);
-};
-
-struct extif_timings {
-	int cs_on_time;
-	int cs_off_time;
-	int we_on_time;
-	int we_off_time;
-	int re_on_time;
-	int re_off_time;
-	int we_cycle_time;
-	int re_cycle_time;
-	int cs_pulse_width;
-	int access_time;
-
-	int clk_div;
-
-	u32 tim[5];		/* set by extif->convert_timings */
-
-	int converted;
-};
-
-struct lcd_ctrl_extif {
-	int  (*init)		(struct omapfb_device *fbdev);
-	void (*cleanup)		(void);
-	void (*get_clk_info)	(u32 *clk_period, u32 *max_clk_div);
-	unsigned long (*get_max_tx_rate)(void);
-	int  (*convert_timings)	(struct extif_timings *timings);
-	void (*set_timings)	(const struct extif_timings *timings);
-	void (*set_bits_per_cycle)(int bpc);
-	void (*write_command)	(const void *buf, unsigned int len);
-	void (*read_data)	(void *buf, unsigned int len);
-	void (*write_data)	(const void *buf, unsigned int len);
-	void (*transfer_area)	(int width, int height,
-				 void (callback)(void * data), void *data);
-	int  (*setup_tearsync)	(unsigned pin_cnt,
-				 unsigned hs_pulse_time, unsigned vs_pulse_time,
-				 int hs_pol_inv, int vs_pol_inv, int div);
-	int  (*enable_tearsync) (int enable, unsigned line);
-
-	unsigned long		max_transmit_size;
-};
-
-struct omapfb_notifier_block {
-	struct notifier_block	nb;
-	void			*data;
-	int			plane_idx;
-};
-
-typedef int (*omapfb_notifier_callback_t)(struct notifier_block *,
-					  unsigned long event,
-					  void *fbi);
-
-struct omapfb_mem_region {
-	u32		paddr;
-	void __iomem	*vaddr;
-	unsigned long	size;
-	u8		type;		/* OMAPFB_PLANE_MEM_* */
-	unsigned	alloc:1;	/* allocated by the driver */
-	unsigned	map:1;		/* kernel mapped by the driver */
-};
-
-struct omapfb_mem_desc {
-	int				region_cnt;
-	struct omapfb_mem_region	region[OMAPFB_PLANE_NUM];
-};
-
-struct lcd_ctrl {
-	const char	*name;
-	void		*data;
-
-	int		(*init)		  (struct omapfb_device *fbdev,
-					   int ext_mode,
-					   struct omapfb_mem_desc *req_md);
-	void		(*cleanup)	  (void);
-	void		(*bind_client)	  (struct omapfb_notifier_block *nb);
-	void		(*get_caps)	  (int plane, struct omapfb_caps *caps);
-	int		(*set_update_mode)(enum omapfb_update_mode mode);
-	enum omapfb_update_mode (*get_update_mode)(void);
-	int		(*setup_plane)	  (int plane, int channel_out,
-					   unsigned long offset,
-					   int screen_width,
-					   int pos_x, int pos_y, int width,
-					   int height, int color_mode);
-	int		(*set_rotate)	  (int angle);
-	int		(*setup_mem)	  (int plane, size_t size,
-					   int mem_type, unsigned long *paddr);
-	int		(*mmap)		  (struct fb_info *info,
-					   struct vm_area_struct *vma);
-	int		(*set_scale)	  (int plane,
-					   int orig_width, int orig_height,
-					   int out_width, int out_height);
-	int		(*enable_plane)	  (int plane, int enable);
-	int		(*update_window)  (struct fb_info *fbi,
-					   struct omapfb_update_window *win,
-					   void (*callback)(void *),
-					   void *callback_data);
-	void		(*sync)		  (void);
-	void		(*suspend)	  (void);
-	void		(*resume)	  (void);
-	int		(*run_test)	  (int test_num);
-	int		(*setcolreg)	  (u_int regno, u16 red, u16 green,
-					   u16 blue, u16 transp,
-					   int update_hw_mem);
-	int		(*set_color_key)  (struct omapfb_color_key *ck);
-	int		(*get_color_key)  (struct omapfb_color_key *ck);
-};
-
-enum omapfb_state {
-	OMAPFB_DISABLED	= 0,
-	OMAPFB_SUSPENDED= 99,
-	OMAPFB_ACTIVE	= 100
-};
-
-struct omapfb_plane_struct {
-	int				idx;
-	struct omapfb_plane_info	info;
-	enum omapfb_color_format	color_mode;
-	struct omapfb_device		*fbdev;
-};
-
-struct omapfb_device {
-	int			state;
-	int                     ext_lcdc;               /* Using external
-                                                           LCD controller */
-	struct mutex		rqueue_mutex;
-
-	int			palette_size;
-	u32			pseudo_palette[17];
-
-	struct lcd_panel	*panel;			/* LCD panel */
-	const struct lcd_ctrl	*ctrl;			/* LCD controller */
-	const struct lcd_ctrl	*int_ctrl;		/* internal LCD ctrl */
-	struct lcd_ctrl_extif	*ext_if;		/* LCD ctrl external
-							   interface */
-	struct device		*dev;
-	struct fb_var_screeninfo	new_var;	/* for mode changes */
-
-	struct omapfb_mem_desc		mem_desc;
-	struct fb_info			*fb_info[OMAPFB_PLANE_NUM];
-};
-
-struct omapfb_platform_data {
-	struct omap_lcd_config		lcd;
-	struct omapfb_mem_desc		mem_desc;
-	void				*ctrl_platform_data;
-};
-
-#ifdef CONFIG_ARCH_OMAP1
-extern struct lcd_ctrl omap1_lcd_ctrl;
-#else
-extern struct lcd_ctrl omap2_disp_ctrl;
-#endif
-
-extern void omapfb_reserve_sdram(void);
-extern void omapfb_register_panel(struct lcd_panel *panel);
-extern void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval);
-extern void omapfb_notify_clients(struct omapfb_device *fbdev,
-				  unsigned long event);
-extern int  omapfb_register_client(struct omapfb_notifier_block *nb,
-				   omapfb_notifier_callback_t callback,
-				   void *callback_data);
-extern int  omapfb_unregister_client(struct omapfb_notifier_block *nb);
-extern int  omapfb_update_window_async(struct fb_info *fbi,
-				       struct omapfb_update_window *win,
-				       void (*callback)(void *),
-				       void *callback_data);
-
-/* in arch/arm/plat-omap/fb.c */
-extern void omapfb_set_ctrl_platform_data(void *pdata);
-
-#endif /* __KERNEL__ */
-
-#endif /* __OMAPFB_H */
diff --git a/arch/arm/plat-omap/include/plat/sdrc.h b/arch/arm/plat-omap/include/plat/sdrc.h
index f704030..7b76f50 100644
--- a/arch/arm/plat-omap/include/plat/sdrc.h
+++ b/arch/arm/plat-omap/include/plat/sdrc.h
@@ -94,7 +94,10 @@
 
 /* SMS register offsets - read/write with sms_{read,write}_reg() */
 
-#define SMS_SYSCONFIG		0x010
+#define SMS_SYSCONFIG			0x010
+#define SMS_ROT_CONTROL(context)	(0x180 + 0x10 * context)
+#define SMS_ROT_SIZE(context)		(0x184 + 0x10 * context)
+#define SMS_ROT_PHYSICAL_BA(context)	(0x188 + 0x10 * context)
 /* REVISIT: fill in other SMS registers here */
 
 
@@ -129,6 +132,10 @@
 void omap2_sms_save_context(void);
 void omap2_sms_restore_context(void);
 
+void omap2_sms_write_rot_control(u32 val, unsigned ctx);
+void omap2_sms_write_rot_size(u32 val, unsigned ctx);
+void omap2_sms_write_rot_physical_ba(u32 val, unsigned ctx);
+
 #ifdef CONFIG_ARCH_OMAP2
 
 struct memory_timings {
diff --git a/arch/arm/plat-omap/include/plat/vram.h b/arch/arm/plat-omap/include/plat/vram.h
new file mode 100644
index 0000000..edd4987
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/vram.h
@@ -0,0 +1,62 @@
+/*
+ * VRAM manager for OMAP
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.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.
+ *
+ * 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.
+ */
+
+#ifndef __OMAP_VRAM_H__
+#define __OMAP_VRAM_H__
+
+#include <linux/types.h>
+
+#define OMAP_VRAM_MEMTYPE_SDRAM		0
+#define OMAP_VRAM_MEMTYPE_SRAM		1
+#define OMAP_VRAM_MEMTYPE_MAX		1
+
+extern int omap_vram_add_region(unsigned long paddr, size_t size);
+extern int omap_vram_free(unsigned long paddr, size_t size);
+extern int omap_vram_alloc(int mtype, size_t size, unsigned long *paddr);
+extern int omap_vram_reserve(unsigned long paddr, size_t size);
+extern void omap_vram_get_info(unsigned long *vram, unsigned long *free_vram,
+		unsigned long *largest_free_block);
+
+#ifdef CONFIG_OMAP2_VRAM
+extern void omap_vram_set_sdram_vram(u32 size, u32 start);
+extern void omap_vram_set_sram_vram(u32 size, u32 start);
+
+extern void omap_vram_reserve_sdram(void);
+extern unsigned long omap_vram_reserve_sram(unsigned long sram_pstart,
+					    unsigned long sram_vstart,
+					    unsigned long sram_size,
+					    unsigned long pstart_avail,
+					    unsigned long size_avail);
+#else
+static inline void omap_vram_set_sdram_vram(u32 size, u32 start) { }
+static inline void omap_vram_set_sram_vram(u32 size, u32 start) { }
+
+static inline void omap_vram_reserve_sdram(void) { }
+static inline unsigned long omap_vram_reserve_sram(unsigned long sram_pstart,
+					    unsigned long sram_vstart,
+					    unsigned long sram_size,
+					    unsigned long pstart_avail,
+					    unsigned long size_avail)
+{
+	return 0;
+}
+#endif
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/vrfb.h b/arch/arm/plat-omap/include/plat/vrfb.h
new file mode 100644
index 0000000..d8a03ce
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/vrfb.h
@@ -0,0 +1,50 @@
+/*
+ * VRFB Rotation Engine
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.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.
+ *
+ * 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.
+ */
+
+#ifndef __OMAP_VRFB_H__
+#define __OMAP_VRFB_H__
+
+#define OMAP_VRFB_LINE_LEN 2048
+
+struct vrfb {
+	u8 context;
+	void __iomem *vaddr[4];
+	unsigned long paddr[4];
+	u16 xres;
+	u16 yres;
+	u16 xoffset;
+	u16 yoffset;
+	u8 bytespp;
+	bool yuv_mode;
+};
+
+extern int omap_vrfb_request_ctx(struct vrfb *vrfb);
+extern void omap_vrfb_release_ctx(struct vrfb *vrfb);
+extern void omap_vrfb_adjust_size(u16 *width, u16 *height,
+		u8 bytespp);
+extern u32 omap_vrfb_min_phys_size(u16 width, u16 height, u8 bytespp);
+extern u16 omap_vrfb_max_height(u32 phys_size, u16 width, u8 bytespp);
+extern void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
+		u16 width, u16 height,
+		unsigned bytespp, bool yuv_mode);
+extern int omap_vrfb_map_angle(struct vrfb *vrfb, u16 height, u8 rot);
+extern void omap_vrfb_restore_context(void);
+
+#endif /* __VRFB_H */
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index 3e92366..ad2bf07 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -28,6 +28,7 @@
 #include <plat/sram.h>
 #include <plat/board.h>
 #include <plat/cpu.h>
+#include <plat/vram.h>
 
 #include <plat/control.h>
 
@@ -185,6 +186,13 @@
 				       omap_sram_start + SRAM_BOOTLOADER_SZ,
 				       omap_sram_size - SRAM_BOOTLOADER_SZ);
 	omap_sram_size -= reserved;
+
+	reserved = omap_vram_reserve_sram(omap_sram_start, omap_sram_base,
+			omap_sram_size,
+			omap_sram_start + SRAM_BOOTLOADER_SZ,
+			omap_sram_size - SRAM_BOOTLOADER_SZ);
+	omap_sram_size -= reserved;
+
 	omap_sram_ceil = omap_sram_base + omap_sram_size;
 }
 
diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig
index e139a72..9e9d028 100644
--- a/arch/arm/plat-s3c/Kconfig
+++ b/arch/arm/plat-s3c/Kconfig
@@ -1,5 +1,3 @@
-# arch/arm/plat-s3c/Kconfig
-#
 # Copyright 2007 Simtec Electronics
 #
 # Licensed under GPLv2
diff --git a/arch/arm/plat-s3c/pwm.c b/arch/arm/plat-s3c/pwm.c
index 4fdc5b3..ef019f2 100644
--- a/arch/arm/plat-s3c/pwm.c
+++ b/arch/arm/plat-s3c/pwm.c
@@ -368,7 +368,7 @@
 	return ret;
 }
 
-static int s3c_pwm_remove(struct platform_device *pdev)
+static int __devexit s3c_pwm_remove(struct platform_device *pdev)
 {
 	struct pwm_device *pwm = platform_get_drvdata(pdev);
 
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
index 20fbf93..342647e 100644
--- a/arch/arm/plat-s3c24xx/Kconfig
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -1,5 +1,3 @@
-# arch/arm/plat-s3c24xx/Kconfig
-#
 # Copyright 2007 Simtec Electronics
 #
 # Licensed under GPLv2
diff --git a/arch/arm/plat-s3c24xx/adc.c b/arch/arm/plat-s3c24xx/adc.c
index df47322..ce47627 100644
--- a/arch/arm/plat-s3c24xx/adc.c
+++ b/arch/arm/plat-s3c24xx/adc.c
@@ -365,7 +365,7 @@
 	return ret;
 }
 
-static int s3c_adc_remove(struct platform_device *pdev)
+static int __devexit s3c_adc_remove(struct platform_device *pdev)
 {
 	struct adc_device *adc = platform_get_drvdata(pdev);
 
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
index f65192d..f0ea794 100644
--- a/arch/arm/plat-s3c24xx/dma.c
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -1403,11 +1403,13 @@
 		ord = &dma_order->channels[channel];
 
 		for (ch = 0; ch < dma_channels; ch++) {
+			int tmp;
 			if (!is_channel_valid(ord->list[ch]))
 				continue;
 
-			if (s3c2410_chans[ord->list[ch]].in_use == 0) {
-				ch = ord->list[ch] & ~DMA_CH_VALID;
+			tmp = ord->list[ch] & ~DMA_CH_VALID;
+			if (s3c2410_chans[tmp].in_use == 0) {
+				ch = tmp;
 				goto found;
 			}
 		}
diff --git a/arch/arm/plat-s3c24xx/include/plat/map.h b/arch/arm/plat-s3c24xx/include/plat/map.h
index c4d1334..bd534d3 100644
--- a/arch/arm/plat-s3c24xx/include/plat/map.h
+++ b/arch/arm/plat-s3c24xx/include/plat/map.h
@@ -64,7 +64,7 @@
 /* the calculation for the VA of this must ensure that
  * it is the same distance apart from the UART in the
  * phsyical address space, as the initial mapping for the IO
- * is done as a 1:1 maping. This puts it (currently) at
+ * is done as a 1:1 mapping. This puts it (currently) at
  * 0xFA800000, which is not in the way of any current mapping
  * by the base system.
 */
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index ef0f521..ad0d44e 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -522,6 +522,8 @@
 	__raw_writel(intmod, S3C2410_INTMOD);
 	return 0;
 }
+
+EXPORT_SYMBOL_GPL(s3c24xx_set_fiq);
 #endif
 
 
diff --git a/arch/arm/plat-s3c64xx/Kconfig b/arch/arm/plat-s3c64xx/Kconfig
index bcfa778..e6da87a 100644
--- a/arch/arm/plat-s3c64xx/Kconfig
+++ b/arch/arm/plat-s3c64xx/Kconfig
@@ -1,5 +1,3 @@
-# arch/arm/plat-s3c64xx/Kconfig
-#
 # Copyright 2008 Openmoko, Inc.
 # Copyright 2008 Simtec Electronics
 #	Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig
index 1608e62..b7b9e91 100644
--- a/arch/arm/plat-s5pc1xx/Kconfig
+++ b/arch/arm/plat-s5pc1xx/Kconfig
@@ -1,5 +1,3 @@
-# arch/arm/plat-s5pc1xx/Kconfig
-#
 # Copyright 2009 Samsung Electronics Co.
 #	Byungho Min <bhmin@samsung.com>
 #
diff --git a/arch/avr32/boards/hammerhead/Kconfig b/arch/avr32/boards/hammerhead/Kconfig
index fda2331..5c13d78 100644
--- a/arch/avr32/boards/hammerhead/Kconfig
+++ b/arch/avr32/boards/hammerhead/Kconfig
@@ -24,7 +24,7 @@
 	bool "Atmel AC97 Sound support"
 	help
 	  This enables Sound support for the Hammerhead board. You may
-	  also go trough the ALSA settings to get it working.
+	  also go through the ALSA settings to get it working.
 
 	  Choose 'Y' here if you have ordered a Corona daugther board and
 	  want to make your board funky.
diff --git a/arch/avr32/include/asm/syscalls.h b/arch/avr32/include/asm/syscalls.h
index 483d666..66a1972 100644
--- a/arch/avr32/include/asm/syscalls.h
+++ b/arch/avr32/include/asm/syscalls.h
@@ -29,10 +29,6 @@
 			       struct pt_regs *);
 asmlinkage int sys_rt_sigreturn(struct pt_regs *);
 
-/* kernel/sys_avr32.c */
-asmlinkage long sys_mmap2(unsigned long, unsigned long, unsigned long,
-			  unsigned long, unsigned long, off_t);
-
 /* mm/cache.c */
 asmlinkage int sys_cacheflush(int, void __user *, size_t);
 
diff --git a/arch/avr32/kernel/sys_avr32.c b/arch/avr32/kernel/sys_avr32.c
index 5d2daea..459349b 100644
--- a/arch/avr32/kernel/sys_avr32.c
+++ b/arch/avr32/kernel/sys_avr32.c
@@ -5,39 +5,8 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/file.h>
-#include <linux/mm.h>
 #include <linux/unistd.h>
 
-#include <asm/mman.h>
-#include <asm/uaccess.h>
-#include <asm/syscalls.h>
-
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-			  unsigned long prot, unsigned long flags,
-			  unsigned long fd, off_t offset)
-{
-	int error = -EBADF;
-	struct file *file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			return error;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, offset);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-	return error;
-}
-
 int kernel_execve(const char *file, char **argv, char **envp)
 {
 	register long scno asm("r8") = __NR_execve;
diff --git a/arch/avr32/kernel/syscall-stubs.S b/arch/avr32/kernel/syscall-stubs.S
index f7244cd..0447a3e 100644
--- a/arch/avr32/kernel/syscall-stubs.S
+++ b/arch/avr32/kernel/syscall-stubs.S
@@ -61,7 +61,7 @@
 __sys_mmap2:
 	pushm	lr
 	st.w	--sp, ARG6
-	call	sys_mmap2
+	call	sys_mmap_pgoff
 	sub	sp, -4
 	popm	pc
 
diff --git a/arch/blackfin/include/asm/fcntl.h b/arch/blackfin/include/asm/fcntl.h
index 8727b2b..251c911 100644
--- a/arch/blackfin/include/asm/fcntl.h
+++ b/arch/blackfin/include/asm/fcntl.h
@@ -7,8 +7,6 @@
 #ifndef _BFIN_FCNTL_H
 #define _BFIN_FCNTL_H
 
-/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
-   located on an ext2 file system */
 #define O_DIRECTORY	 040000	/* must be a directory */
 #define O_NOFOLLOW	0100000	/* don't follow links */
 #define O_DIRECT	0200000	/* direct disk access hint - currently ignored */
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index 5cc7e2e..4587642 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -215,22 +215,18 @@
 /*
  * sys_execve() executes a new program.
  */
-
 asmlinkage int sys_execve(char __user *name, char __user * __user *argv, char __user * __user *envp)
 {
 	int error;
 	char *filename;
 	struct pt_regs *regs = (struct pt_regs *)((&name) + 6);
 
-	lock_kernel();
 	filename = getname(name);
 	error = PTR_ERR(filename);
 	if (IS_ERR(filename))
-		goto out;
+		return error;
 	error = do_execve(filename, argv, envp, regs);
 	putname(filename);
- out:
-	unlock_kernel();
 	return error;
 }
 
diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c
index afcef12..2e7f8e1 100644
--- a/arch/blackfin/kernel/sys_bfin.c
+++ b/arch/blackfin/kernel/sys_bfin.c
@@ -22,39 +22,6 @@
 #include <asm/cacheflush.h>
 #include <asm/dma.h>
 
-/* common code for old and new mmaps */
-static inline long
-do_mmap2(unsigned long addr, unsigned long len,
-	 unsigned long prot, unsigned long flags,
-	 unsigned long fd, unsigned long pgoff)
-{
-	int error = -EBADF;
-	struct file *file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
- out:
-	return error;
-}
-
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-			  unsigned long prot, unsigned long flags,
-			  unsigned long fd, unsigned long pgoff)
-{
-	return do_mmap2(addr, len, prot, flags, fd, pgoff);
-}
-
 asmlinkage void *sys_sram_alloc(size_t size, unsigned long flags)
 {
 	return sram_alloc_with_lsl(size, flags);
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index 6b7325d..78cb3d3 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -619,7 +619,7 @@
 
 /*
  * Similar to get_user, do some address checking, then dereference
- * Return true on sucess, false on bad address
+ * Return true on success, false on bad address
  */
 static bool get_instruction(unsigned short *val, unsigned short *address)
 {
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h
index e06f411..f9fd2b2 100644
--- a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h
+++ b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h
@@ -542,7 +542,7 @@
 #define HMDMA0_CONTROL		0xFFC03300	/* Handshake MDMA0 Control Register					*/
 #define HMDMA0_ECINIT		0xFFC03304	/* HMDMA0 Initial Edge Count Register				*/
 #define HMDMA0_BCINIT		0xFFC03308	/* HMDMA0 Initial Block Count Register				*/
-#define HMDMA0_ECURGENT		0xFFC0330C	/* HMDMA0 Urgent Edge Count Threshhold Register		*/
+#define HMDMA0_ECURGENT		0xFFC0330C	/* HMDMA0 Urgent Edge Count Threshold Register		*/
 #define HMDMA0_ECOVERFLOW	0xFFC03310	/* HMDMA0 Edge Count Overflow Interrupt Register	*/
 #define HMDMA0_ECOUNT		0xFFC03314	/* HMDMA0 Current Edge Count Register				*/
 #define HMDMA0_BCOUNT		0xFFC03318	/* HMDMA0 Current Block Count Register				*/
@@ -550,7 +550,7 @@
 #define HMDMA1_CONTROL		0xFFC03340	/* Handshake MDMA1 Control Register					*/
 #define HMDMA1_ECINIT		0xFFC03344	/* HMDMA1 Initial Edge Count Register				*/
 #define HMDMA1_BCINIT		0xFFC03348	/* HMDMA1 Initial Block Count Register				*/
-#define HMDMA1_ECURGENT		0xFFC0334C	/* HMDMA1 Urgent Edge Count Threshhold Register		*/
+#define HMDMA1_ECURGENT		0xFFC0334C	/* HMDMA1 Urgent Edge Count Threshold Register		*/
 #define HMDMA1_ECOVERFLOW	0xFFC03350	/* HMDMA1 Edge Count Overflow Interrupt Register	*/
 #define HMDMA1_ECOUNT		0xFFC03354	/* HMDMA1 Current Edge Count Register				*/
 #define HMDMA1_BCOUNT		0xFFC03358	/* HMDMA1 Current Block Count Register				*/
diff --git a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h
index f821700..b9dbb73 100644
--- a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h
+++ b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h
@@ -544,7 +544,7 @@
 #define HMDMA0_CONTROL		0xFFC03300	/* Handshake MDMA0 Control Register					*/
 #define HMDMA0_ECINIT		0xFFC03304	/* HMDMA0 Initial Edge Count Register				*/
 #define HMDMA0_BCINIT		0xFFC03308	/* HMDMA0 Initial Block Count Register				*/
-#define HMDMA0_ECURGENT		0xFFC0330C	/* HMDMA0 Urgent Edge Count Threshhold Register		*/
+#define HMDMA0_ECURGENT		0xFFC0330C	/* HMDMA0 Urgent Edge Count Threshold Register		*/
 #define HMDMA0_ECOVERFLOW	0xFFC03310	/* HMDMA0 Edge Count Overflow Interrupt Register	*/
 #define HMDMA0_ECOUNT		0xFFC03314	/* HMDMA0 Current Edge Count Register				*/
 #define HMDMA0_BCOUNT		0xFFC03318	/* HMDMA0 Current Block Count Register				*/
@@ -552,7 +552,7 @@
 #define HMDMA1_CONTROL		0xFFC03340	/* Handshake MDMA1 Control Register					*/
 #define HMDMA1_ECINIT		0xFFC03344	/* HMDMA1 Initial Edge Count Register				*/
 #define HMDMA1_BCINIT		0xFFC03348	/* HMDMA1 Initial Block Count Register				*/
-#define HMDMA1_ECURGENT		0xFFC0334C	/* HMDMA1 Urgent Edge Count Threshhold Register		*/
+#define HMDMA1_ECURGENT		0xFFC0334C	/* HMDMA1 Urgent Edge Count Threshold Register		*/
 #define HMDMA1_ECOVERFLOW	0xFFC03350	/* HMDMA1 Edge Count Overflow Interrupt Register	*/
 #define HMDMA1_ECOUNT		0xFFC03354	/* HMDMA1 Current Edge Count Register				*/
 #define HMDMA1_BCOUNT		0xFFC03358	/* HMDMA1 Current Block Count Register				*/
diff --git a/arch/blackfin/mach-bf537/include/mach/defBF534.h b/arch/blackfin/mach-bf537/include/mach/defBF534.h
index cebb14f..a6d20ca 100644
--- a/arch/blackfin/mach-bf537/include/mach/defBF534.h
+++ b/arch/blackfin/mach-bf537/include/mach/defBF534.h
@@ -934,7 +934,7 @@
 #define HMDMA0_CONTROL		0xFFC03300	/* Handshake MDMA0 Control Register                                     */
 #define HMDMA0_ECINIT		0xFFC03304	/* HMDMA0 Initial Edge Count Register                           */
 #define HMDMA0_BCINIT		0xFFC03308	/* HMDMA0 Initial Block Count Register                          */
-#define HMDMA0_ECURGENT		0xFFC0330C	/* HMDMA0 Urgent Edge Count Threshhold Register         */
+#define HMDMA0_ECURGENT		0xFFC0330C	/* HMDMA0 Urgent Edge Count Threshold Register         */
 #define HMDMA0_ECOVERFLOW	0xFFC03310	/* HMDMA0 Edge Count Overflow Interrupt Register        */
 #define HMDMA0_ECOUNT		0xFFC03314	/* HMDMA0 Current Edge Count Register                           */
 #define HMDMA0_BCOUNT		0xFFC03318	/* HMDMA0 Current Block Count Register                          */
@@ -942,7 +942,7 @@
 #define HMDMA1_CONTROL		0xFFC03340	/* Handshake MDMA1 Control Register                                     */
 #define HMDMA1_ECINIT		0xFFC03344	/* HMDMA1 Initial Edge Count Register                           */
 #define HMDMA1_BCINIT		0xFFC03348	/* HMDMA1 Initial Block Count Register                          */
-#define HMDMA1_ECURGENT		0xFFC0334C	/* HMDMA1 Urgent Edge Count Threshhold Register         */
+#define HMDMA1_ECURGENT		0xFFC0334C	/* HMDMA1 Urgent Edge Count Threshold Register         */
 #define HMDMA1_ECOVERFLOW	0xFFC03350	/* HMDMA1 Edge Count Overflow Interrupt Register        */
 #define HMDMA1_ECOUNT		0xFFC03354	/* HMDMA1 Current Edge Count Register                           */
 #define HMDMA1_BCOUNT		0xFFC03358	/* HMDMA1 Current Block Count Register                          */
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF544.h b/arch/blackfin/mach-bf548/include/mach/defBF544.h
index dd414ae..39f588d 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF544.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF544.h
@@ -491,7 +491,7 @@
 #define                   HMDMA0_CONTROL  0xffc04500   /* Handshake MDMA0 Control Register */
 #define                    HMDMA0_ECINIT  0xffc04504   /* Handshake MDMA0 Initial Edge Count Register */
 #define                    HMDMA0_BCINIT  0xffc04508   /* Handshake MDMA0 Initial Block Count Register */
-#define                  HMDMA0_ECURGENT  0xffc0450c   /* Handshake MDMA0 Urgent Edge Count Threshhold Register */
+#define                  HMDMA0_ECURGENT  0xffc0450c   /* Handshake MDMA0 Urgent Edge Count Threshold Register */
 #define                HMDMA0_ECOVERFLOW  0xffc04510   /* Handshake MDMA0 Edge Count Overflow Interrupt Register */
 #define                    HMDMA0_ECOUNT  0xffc04514   /* Handshake MDMA0 Current Edge Count Register */
 #define                    HMDMA0_BCOUNT  0xffc04518   /* Handshake MDMA0 Current Block Count Register */
@@ -501,7 +501,7 @@
 #define                   HMDMA1_CONTROL  0xffc04540   /* Handshake MDMA1 Control Register */
 #define                    HMDMA1_ECINIT  0xffc04544   /* Handshake MDMA1 Initial Edge Count Register */
 #define                    HMDMA1_BCINIT  0xffc04548   /* Handshake MDMA1 Initial Block Count Register */
-#define                  HMDMA1_ECURGENT  0xffc0454c   /* Handshake MDMA1 Urgent Edge Count Threshhold Register */
+#define                  HMDMA1_ECURGENT  0xffc0454c   /* Handshake MDMA1 Urgent Edge Count Threshold Register */
 #define                HMDMA1_ECOVERFLOW  0xffc04550   /* Handshake MDMA1 Edge Count Overflow Interrupt Register */
 #define                    HMDMA1_ECOUNT  0xffc04554   /* Handshake MDMA1 Current Edge Count Register */
 #define                    HMDMA1_BCOUNT  0xffc04558   /* Handshake MDMA1 Current Block Count Register */
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF547.h b/arch/blackfin/mach-bf548/include/mach/defBF547.h
index 5a9dbab..c4dcf30 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF547.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF547.h
@@ -470,7 +470,7 @@
 #define                   HMDMA0_CONTROL  0xffc04500   /* Handshake MDMA0 Control Register */
 #define                    HMDMA0_ECINIT  0xffc04504   /* Handshake MDMA0 Initial Edge Count Register */
 #define                    HMDMA0_BCINIT  0xffc04508   /* Handshake MDMA0 Initial Block Count Register */
-#define                  HMDMA0_ECURGENT  0xffc0450c   /* Handshake MDMA0 Urgent Edge Count Threshhold Register */
+#define                  HMDMA0_ECURGENT  0xffc0450c   /* Handshake MDMA0 Urgent Edge Count Threshold Register */
 #define                HMDMA0_ECOVERFLOW  0xffc04510   /* Handshake MDMA0 Edge Count Overflow Interrupt Register */
 #define                    HMDMA0_ECOUNT  0xffc04514   /* Handshake MDMA0 Current Edge Count Register */
 #define                    HMDMA0_BCOUNT  0xffc04518   /* Handshake MDMA0 Current Block Count Register */
@@ -480,7 +480,7 @@
 #define                   HMDMA1_CONTROL  0xffc04540   /* Handshake MDMA1 Control Register */
 #define                    HMDMA1_ECINIT  0xffc04544   /* Handshake MDMA1 Initial Edge Count Register */
 #define                    HMDMA1_BCINIT  0xffc04548   /* Handshake MDMA1 Initial Block Count Register */
-#define                  HMDMA1_ECURGENT  0xffc0454c   /* Handshake MDMA1 Urgent Edge Count Threshhold Register */
+#define                  HMDMA1_ECURGENT  0xffc0454c   /* Handshake MDMA1 Urgent Edge Count Threshold Register */
 #define                HMDMA1_ECOVERFLOW  0xffc04550   /* Handshake MDMA1 Edge Count Overflow Interrupt Register */
 #define                    HMDMA1_ECOUNT  0xffc04554   /* Handshake MDMA1 Current Edge Count Register */
 #define                    HMDMA1_BCOUNT  0xffc04558   /* Handshake MDMA1 Current Block Count Register */
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF548.h b/arch/blackfin/mach-bf548/include/mach/defBF548.h
index 82cd593..a507998 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF548.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF548.h
@@ -853,7 +853,7 @@
 #define                   HMDMA0_CONTROL  0xffc04500   /* Handshake MDMA0 Control Register */
 #define                    HMDMA0_ECINIT  0xffc04504   /* Handshake MDMA0 Initial Edge Count Register */
 #define                    HMDMA0_BCINIT  0xffc04508   /* Handshake MDMA0 Initial Block Count Register */
-#define                  HMDMA0_ECURGENT  0xffc0450c   /* Handshake MDMA0 Urgent Edge Count Threshhold Register */
+#define                  HMDMA0_ECURGENT  0xffc0450c   /* Handshake MDMA0 Urgent Edge Count Threshold Register */
 #define                HMDMA0_ECOVERFLOW  0xffc04510   /* Handshake MDMA0 Edge Count Overflow Interrupt Register */
 #define                    HMDMA0_ECOUNT  0xffc04514   /* Handshake MDMA0 Current Edge Count Register */
 #define                    HMDMA0_BCOUNT  0xffc04518   /* Handshake MDMA0 Current Block Count Register */
@@ -863,7 +863,7 @@
 #define                   HMDMA1_CONTROL  0xffc04540   /* Handshake MDMA1 Control Register */
 #define                    HMDMA1_ECINIT  0xffc04544   /* Handshake MDMA1 Initial Edge Count Register */
 #define                    HMDMA1_BCINIT  0xffc04548   /* Handshake MDMA1 Initial Block Count Register */
-#define                  HMDMA1_ECURGENT  0xffc0454c   /* Handshake MDMA1 Urgent Edge Count Threshhold Register */
+#define                  HMDMA1_ECURGENT  0xffc0454c   /* Handshake MDMA1 Urgent Edge Count Threshold Register */
 #define                HMDMA1_ECOVERFLOW  0xffc04550   /* Handshake MDMA1 Edge Count Overflow Interrupt Register */
 #define                    HMDMA1_ECOUNT  0xffc04554   /* Handshake MDMA1 Current Edge Count Register */
 #define                    HMDMA1_BCOUNT  0xffc04558   /* Handshake MDMA1 Current Block Count Register */
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF549.h b/arch/blackfin/mach-bf548/include/mach/defBF549.h
index 6fc6e39..f7f0435 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF549.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF549.h
@@ -1024,7 +1024,7 @@
 #define                   HMDMA0_CONTROL  0xffc04500   /* Handshake MDMA0 Control Register */
 #define                    HMDMA0_ECINIT  0xffc04504   /* Handshake MDMA0 Initial Edge Count Register */
 #define                    HMDMA0_BCINIT  0xffc04508   /* Handshake MDMA0 Initial Block Count Register */
-#define                  HMDMA0_ECURGENT  0xffc0450c   /* Handshake MDMA0 Urgent Edge Count Threshhold Register */
+#define                  HMDMA0_ECURGENT  0xffc0450c   /* Handshake MDMA0 Urgent Edge Count Threshold Register */
 #define                HMDMA0_ECOVERFLOW  0xffc04510   /* Handshake MDMA0 Edge Count Overflow Interrupt Register */
 #define                    HMDMA0_ECOUNT  0xffc04514   /* Handshake MDMA0 Current Edge Count Register */
 #define                    HMDMA0_BCOUNT  0xffc04518   /* Handshake MDMA0 Current Block Count Register */
@@ -1034,7 +1034,7 @@
 #define                   HMDMA1_CONTROL  0xffc04540   /* Handshake MDMA1 Control Register */
 #define                    HMDMA1_ECINIT  0xffc04544   /* Handshake MDMA1 Initial Edge Count Register */
 #define                    HMDMA1_BCINIT  0xffc04548   /* Handshake MDMA1 Initial Block Count Register */
-#define                  HMDMA1_ECURGENT  0xffc0454c   /* Handshake MDMA1 Urgent Edge Count Threshhold Register */
+#define                  HMDMA1_ECURGENT  0xffc0454c   /* Handshake MDMA1 Urgent Edge Count Threshold Register */
 #define                HMDMA1_ECOVERFLOW  0xffc04550   /* Handshake MDMA1 Edge Count Overflow Interrupt Register */
 #define                    HMDMA1_ECOUNT  0xffc04554   /* Handshake MDMA1 Current Edge Count Register */
 #define                    HMDMA1_BCOUNT  0xffc04558   /* Handshake MDMA1 Current Block Count Register */
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index a50637a..f3f8bb4 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -1422,7 +1422,7 @@
 	.long _sys_ni_syscall	/* streams2 */
 	.long _sys_vfork		/* 190 */
 	.long _sys_getrlimit
-	.long _sys_mmap2
+	.long _sys_mmap_pgoff
 	.long _sys_truncate64
 	.long _sys_ftruncate64
 	.long _sys_stat64	/* 195 */
diff --git a/arch/cris/arch-v10/mm/fault.c b/arch/cris/arch-v10/mm/fault.c
index 087a209..ed60588 100644
--- a/arch/cris/arch-v10/mm/fault.c
+++ b/arch/cris/arch-v10/mm/fault.c
@@ -80,8 +80,7 @@
 	 * do_page_fault may have flushed the TLB so we have to restore
 	 * the MMU registers.
 	 */
-	local_save_flags(flags);
-	local_irq_disable();
+	local_irq_save(flags);
 	pmd = (pmd_t *)(pgd + pgd_index(address));
 	if (pmd_none(*pmd))
 		goto exit;
diff --git a/arch/cris/arch-v10/mm/tlb.c b/arch/cris/arch-v10/mm/tlb.c
index 4a496e4..21d78c5 100644
--- a/arch/cris/arch-v10/mm/tlb.c
+++ b/arch/cris/arch-v10/mm/tlb.c
@@ -134,28 +134,6 @@
 	local_irq_restore(flags);
 }
 
-/* dump the entire TLB for debug purposes */
-
-#if 0
-void
-dump_tlb_all(void)
-{
-	int i;
-	unsigned long flags;
-
-	printk("TLB dump. LO is: pfn | reserved | global | valid | kernel | we  |\n");
-
-	local_save_flags(flags);
-	local_irq_disable();
-	for(i = 0; i < NUM_TLB_ENTRIES; i++) {
-		*R_TLB_SELECT = ( IO_FIELD(R_TLB_SELECT, index, i) );
-		printk("Entry %d: HI 0x%08lx, LO 0x%08lx\n",
-		       i, *R_TLB_HI, *R_TLB_LO);
-	}
-	local_irq_restore(flags);
-}
-#endif
-
 /*
  * Initialize the context related info for a new mm_struct
  * instance.
diff --git a/arch/cris/kernel/sys_cris.c b/arch/cris/kernel/sys_cris.c
index 2ad962c..c2bbb1a 100644
--- a/arch/cris/kernel/sys_cris.c
+++ b/arch/cris/kernel/sys_cris.c
@@ -26,31 +26,6 @@
 #include <asm/uaccess.h>
 #include <asm/segment.h>
 
-/* common code for old and new mmaps */
-static inline long
-do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
-        unsigned long flags, unsigned long fd, unsigned long pgoff)
-{
-        int error = -EBADF;
-        struct file * file = NULL;
-
-        flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-        if (!(flags & MAP_ANONYMOUS)) {
-                file = fget(fd);
-                if (!file)
-                        goto out;
-        }
-
-        down_write(&current->mm->mmap_sem);
-        error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-        up_write(&current->mm->mmap_sem);
-
-        if (file)
-                fput(file);
-out:
-        return error;
-}
-
 asmlinkage unsigned long old_mmap(unsigned long __user *args)
 {        
 	unsigned long buffer[6];
@@ -63,7 +38,7 @@
 	if (buffer[5] & ~PAGE_MASK) /* verify that offset is on page boundary */
 		goto out;
 
-	err = do_mmap2(buffer[0], buffer[1], buffer[2], buffer[3],
+	err = sys_mmap_pgoff(buffer[0], buffer[1], buffer[2], buffer[3],
                        buffer[4], buffer[5] >> PAGE_SHIFT);
 out:
 	return err;
@@ -73,7 +48,8 @@
 sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
           unsigned long flags, unsigned long fd, unsigned long pgoff)
 {
-        return do_mmap2(addr, len, prot, flags, fd, pgoff);
+	/* bug(?): 8Kb pages here */
+        return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
 }
 
 /*
diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c
index 4a7cdd9..380df1a 100644
--- a/arch/cris/mm/fault.c
+++ b/arch/cris/mm/fault.c
@@ -209,7 +209,7 @@
 	/* Are we prepared to handle this kernel fault?
 	 *
 	 * (The kernel has valid exception-points in the source
-	 *  when it acesses user-memory. When it fails in one
+	 *  when it accesses user-memory. When it fails in one
 	 *  of those points, we find it in a table and do a jump
 	 *  to some fixup code that loads an appropriate error
 	 *  code)
diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c
index 9042559..21d0fd1 100644
--- a/arch/frv/kernel/process.c
+++ b/arch/frv/kernel/process.c
@@ -255,15 +255,12 @@
 	int error;
 	char * filename;
 
-	lock_kernel();
 	filename = getname(name);
 	error = PTR_ERR(filename);
 	if (IS_ERR(filename))
-		goto out;
+		return error;
 	error = do_execve(filename, argv, envp, __frame);
 	putname(filename);
- out:
-	unlock_kernel();
 	return error;
 }
 
diff --git a/arch/frv/kernel/sys_frv.c b/arch/frv/kernel/sys_frv.c
index 2b6b528..1d3d4c9 100644
--- a/arch/frv/kernel/sys_frv.c
+++ b/arch/frv/kernel/sys_frv.c
@@ -31,9 +31,6 @@
 			  unsigned long prot, unsigned long flags,
 			  unsigned long fd, unsigned long pgoff)
 {
-	int error = -EBADF;
-	struct file * file = NULL;
-
 	/* As with sparc32, make sure the shift for mmap2 is constant
 	   (12), no matter what PAGE_SIZE we have.... */
 
@@ -41,70 +38,11 @@
 	   trying to map something we can't */
 	if (pgoff & ((1 << (PAGE_SHIFT - 12)) - 1))
 		return -EINVAL;
-	pgoff >>= PAGE_SHIFT - 12;
 
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
+	return sys_mmap_pgoff(addr, len, prot, flags, fd,
+			      pgoff >> (PAGE_SHIFT - 12));
 }
 
-#if 0 /* DAVIDM - do we want this */
-struct mmap_arg_struct64 {
-	__u32 addr;
-	__u32 len;
-	__u32 prot;
-	__u32 flags;
-	__u64 offset; /* 64 bits */
-	__u32 fd;
-};
-
-asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
-{
-	int error = -EFAULT;
-	struct file * file = NULL;
-	struct mmap_arg_struct64 a;
-	unsigned long pgoff;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-
-	if ((long)a.offset & ~PAGE_MASK)
-		return -EINVAL;
-
-	pgoff = a.offset >> PAGE_SHIFT;
-	if ((a.offset >> PAGE_SHIFT) != pgoff)
-		return -EINVAL;
-
-	if (!(a.flags & MAP_ANONYMOUS)) {
-		error = -EBADF;
-		file = fget(a.fd);
-		if (!file)
-			goto out;
-	}
-	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-#endif
-
 /*
  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
  *
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
index e2f33d0..bd883fa 100644
--- a/arch/h8300/kernel/process.c
+++ b/arch/h8300/kernel/process.c
@@ -218,15 +218,12 @@
 	char * filename;
 	struct pt_regs *regs = (struct pt_regs *) ((unsigned char *)&dummy-4);
 
-	lock_kernel();
 	filename = getname(name);
 	error = PTR_ERR(filename);
 	if (IS_ERR(filename))
-		goto out;
+		return error;
 	error = do_execve(filename, argv, envp, regs);
 	putname(filename);
-out:
-	unlock_kernel();
 	return error;
 }
 
diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c
index 8cb5d73..b5969db 100644
--- a/arch/h8300/kernel/sys_h8300.c
+++ b/arch/h8300/kernel/sys_h8300.c
@@ -26,39 +26,6 @@
 #include <asm/traps.h>
 #include <asm/unistd.h>
 
-/* common code for old and new mmaps */
-static inline long do_mmap2(
-	unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags,
-	unsigned long fd, unsigned long pgoff)
-{
-	int error = -EBADF;
-	struct file * file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags,
-	unsigned long fd, unsigned long pgoff)
-{
-	return do_mmap2(addr, len, prot, flags, fd, pgoff);
-}
-
 /*
  * Perform the select(nd, in, out, ex, tv) and mmap() system
  * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
@@ -87,58 +54,12 @@
 	if (a.offset & ~PAGE_MASK)
 		goto out;
 
-	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+	error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
+			       a.offset >> PAGE_SHIFT);
 out:
 	return error;
 }
 
-#if 0 /* DAVIDM - do we want this */
-struct mmap_arg_struct64 {
-	__u32 addr;
-	__u32 len;
-	__u32 prot;
-	__u32 flags;
-	__u64 offset; /* 64 bits */
-	__u32 fd;
-};
-
-asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
-{
-	int error = -EFAULT;
-	struct file * file = NULL;
-	struct mmap_arg_struct64 a;
-	unsigned long pgoff;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-
-	if ((long)a.offset & ~PAGE_MASK)
-		return -EINVAL;
-
-	pgoff = a.offset >> PAGE_SHIFT;
-	if ((a.offset >> PAGE_SHIFT) != pgoff)
-		return -EINVAL;
-
-	if (!(a.flags & MAP_ANONYMOUS)) {
-		error = -EBADF;
-		file = fget(a.fd);
-		if (!file)
-			goto out;
-	}
-	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-#endif
-
 struct sel_arg_struct {
 	unsigned long n;
 	fd_set *inp, *outp, *exp;
diff --git a/arch/h8300/kernel/syscalls.S b/arch/h8300/kernel/syscalls.S
index 4eb67fa..2d69881 100644
--- a/arch/h8300/kernel/syscalls.S
+++ b/arch/h8300/kernel/syscalls.S
@@ -206,7 +206,7 @@
 	.long SYMBOL_NAME(sys_ni_syscall)	/* streams2 */
 	.long SYMBOL_NAME(sys_vfork)            /* 190 */
 	.long SYMBOL_NAME(sys_getrlimit)
-	.long SYMBOL_NAME(sys_mmap2)
+	.long SYMBOL_NAME(sys_mmap_pgoff)
 	.long SYMBOL_NAME(sys_truncate64)
 	.long SYMBOL_NAME(sys_ftruncate64)
 	.long SYMBOL_NAME(sys_stat64)		/* 195 */
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index 674a837..f332e3f 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -1381,7 +1381,7 @@
 #endif
 
 			/*
-			** Not virtually contigous.
+			** Not virtually contiguous.
 			** Terminate prev chunk.
 			** Start a new chunk.
 			**
diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S
index 10c3751..2fd7479 100644
--- a/arch/ia64/ia32/ia32_entry.S
+++ b/arch/ia64/ia32/ia32_entry.S
@@ -79,7 +79,7 @@
 (p6)	br.cond.spnt .ia32_strace_check_retval
 	;;					// prevent RAW on r8
 END(ia32_ret_from_clone)
-	// fall thrugh
+	// fall through
 GLOBAL_ENTRY(ia32_ret_from_syscall)
 	PT_REGS_UNWIND_INFO(0)
 
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index 429ec96..045b746 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -858,6 +858,9 @@
 
 	prot = get_prot32(prot);
 
+	if (flags & MAP_HUGETLB)
+		return -ENOMEM;
+
 #if PAGE_SHIFT > IA32_PAGE_SHIFT
 	mutex_lock(&ia32_mmap_mutex);
 	{
diff --git a/arch/ia64/include/asm/perfmon_default_smpl.h b/arch/ia64/include/asm/perfmon_default_smpl.h
index 48822c0..74724b2 100644
--- a/arch/ia64/include/asm/perfmon_default_smpl.h
+++ b/arch/ia64/include/asm/perfmon_default_smpl.h
@@ -67,7 +67,7 @@
         unsigned long   ip;                     /* where did the overflow interrupt happened  */
         unsigned long   tstamp;                 /* ar.itc when entering perfmon intr. handler */
 
-        unsigned short  cpu;                    /* cpu on which the overfow occured */
+        unsigned short  cpu;                    /* cpu on which the overflow occured */
         unsigned short  set;                    /* event set active when overflow ocurred   */
         int    		tgid;              	/* thread group id (for NPTL, this is getpid()) */
 } pfm_default_smpl_entry_t;
diff --git a/arch/ia64/include/asm/sn/shubio.h b/arch/ia64/include/asm/sn/shubio.h
index 22a6f18..6052422 100644
--- a/arch/ia64/include/asm/sn/shubio.h
+++ b/arch/ia64/include/asm/sn/shubio.h
@@ -3289,7 +3289,7 @@
 #define IIO_IIDSR_LVL_SHIFT     0
 #define IIO_IIDSR_LVL_MASK      0x000000ff
 
-/* Xtalk timeout threshhold register (IIO_IXTT) */
+/* Xtalk timeout threshold register (IIO_IXTT) */
 #define IXTT_RRSP_TO_SHFT	55	/* read response timeout */
 #define IXTT_RRSP_TO_MASK	(0x1FULL << IXTT_RRSP_TO_SHFT)
 #define IXTT_RRSP_PS_SHFT	32	/* read responsed TO prescalar */
diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h
index 9c72e36..10a8f21 100644
--- a/arch/ia64/include/asm/unistd.h
+++ b/arch/ia64/include/asm/unistd.h
@@ -311,7 +311,7 @@
 #define __NR_preadv			1319
 #define __NR_pwritev			1320
 #define __NR_rt_tgsigqueueinfo		1321
-#define __NR_rt_recvmmsg		1322
+#define __NR_recvmmsg			1322
 
 #ifdef __KERNEL__
 
diff --git a/arch/ia64/include/asm/xen/hypervisor.h b/arch/ia64/include/asm/xen/hypervisor.h
index 88afb54..67455c2 100644
--- a/arch/ia64/include/asm/xen/hypervisor.h
+++ b/arch/ia64/include/asm/xen/hypervisor.h
@@ -37,35 +37,9 @@
 #include <xen/interface/xen.h>
 #include <xen/interface/version.h>	/* to compile feature.c */
 #include <xen/features.h>		/* to comiple xen-netfront.c */
+#include <xen/xen.h>
 #include <asm/xen/hypercall.h>
 
-/* xen_domain_type is set before executing any C code by early_xen_setup */
-enum xen_domain_type {
-	XEN_NATIVE,	/* running on bare hardware */
-	XEN_PV_DOMAIN,	/* running in a PV domain */
-	XEN_HVM_DOMAIN,	/* running in a Xen hvm domain*/
-};
-
-#ifdef CONFIG_XEN
-extern enum xen_domain_type xen_domain_type;
-#else
-#define xen_domain_type		XEN_NATIVE
-#endif
-
-#define xen_domain()		(xen_domain_type != XEN_NATIVE)
-#define xen_pv_domain()		(xen_domain() &&			\
-				 xen_domain_type == XEN_PV_DOMAIN)
-#define xen_hvm_domain()	(xen_domain() &&			\
-				 xen_domain_type == XEN_HVM_DOMAIN)
-
-#ifdef CONFIG_XEN_DOM0
-#define xen_initial_domain()	(xen_pv_domain() &&			\
-				 (xen_start_info->flags & SIF_INITDOMAIN))
-#else
-#define xen_initial_domain()	(0)
-#endif
-
-
 #ifdef CONFIG_XEN
 extern struct shared_info *HYPERVISOR_shared_info;
 extern struct start_info *xen_start_info;
diff --git a/arch/ia64/kernel/esi.c b/arch/ia64/kernel/esi.c
index d5764a3..b091111 100644
--- a/arch/ia64/kernel/esi.c
+++ b/arch/ia64/kernel/esi.c
@@ -84,7 +84,7 @@
 		      case ESI_DESC_ENTRY_POINT:
 			break;
 		      default:
-			printk(KERN_WARNING "Unkown table type %d found in "
+			printk(KERN_WARNING "Unknown table type %d found in "
 			       "ESI table, ignoring rest of table\n", *p);
 			return -ENODEV;
 		}
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 402698b..599b233 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -3517,7 +3517,7 @@
  * IA64_THREAD_DBG_VALID set. This indicates a task which was
  * able to use the debug registers for debugging purposes via
  * ptrace(). Therefore we know it was not using them for
- * perfmormance monitoring, so we only decrement the number
+ * performance monitoring, so we only decrement the number
  * of "ptraced" debug register users to keep the count up to date
  */
 int
diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
index 92ed83f..609d500 100644
--- a/arch/ia64/kernel/sys_ia64.c
+++ b/arch/ia64/kernel/sys_ia64.c
@@ -100,51 +100,7 @@
 asmlinkage unsigned long
 ia64_brk (unsigned long brk)
 {
-	unsigned long rlim, retval, newbrk, oldbrk;
-	struct mm_struct *mm = current->mm;
-
-	/*
-	 * Most of this replicates the code in sys_brk() except for an additional safety
-	 * check and the clearing of r8.  However, we can't call sys_brk() because we need
-	 * to acquire the mmap_sem before we can do the test...
-	 */
-	down_write(&mm->mmap_sem);
-
-	if (brk < mm->end_code)
-		goto out;
-	newbrk = PAGE_ALIGN(brk);
-	oldbrk = PAGE_ALIGN(mm->brk);
-	if (oldbrk == newbrk)
-		goto set_brk;
-
-	/* Always allow shrinking brk. */
-	if (brk <= mm->brk) {
-		if (!do_munmap(mm, newbrk, oldbrk-newbrk))
-			goto set_brk;
-		goto out;
-	}
-
-	/* Check against unimplemented/unmapped addresses: */
-	if ((newbrk - oldbrk) > RGN_MAP_LIMIT || REGION_OFFSET(newbrk) > RGN_MAP_LIMIT)
-		goto out;
-
-	/* Check against rlimit.. */
-	rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
-	if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
-		goto out;
-
-	/* Check against existing mmap mappings. */
-	if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE))
-		goto out;
-
-	/* Ok, looks good - let it rip. */
-	if (do_brk(oldbrk, newbrk-oldbrk) != oldbrk)
-		goto out;
-set_brk:
-	mm->brk = brk;
-out:
-	retval = mm->brk;
-	up_write(&mm->mmap_sem);
+	unsigned long retval = sys_brk(brk);
 	force_successful_syscall_return();
 	return retval;
 }
@@ -185,39 +141,6 @@
 	return 0;
 }
 
-static inline unsigned long
-do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, unsigned long pgoff)
-{
-	struct file *file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			return -EBADF;
-
-		if (!file->f_op || !file->f_op->mmap) {
-			addr = -ENODEV;
-			goto out;
-		}
-	}
-
-	/* Careful about overflows.. */
-	len = PAGE_ALIGN(len);
-	if (!len || len > TASK_SIZE) {
-		addr = -EINVAL;
-		goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-out:	if (file)
-		fput(file);
-	return addr;
-}
-
 /*
  * mmap2() is like mmap() except that the offset is expressed in units
  * of PAGE_SIZE (instead of bytes).  This allows to mmap2() (pieces
@@ -226,7 +149,7 @@
 asmlinkage unsigned long
 sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, long pgoff)
 {
-	addr = do_mmap2(addr, len, prot, flags, fd, pgoff);
+	addr = sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
 	if (!IS_ERR((void *) addr))
 		force_successful_syscall_return();
 	return addr;
@@ -238,7 +161,7 @@
 	if (offset_in_page(off) != 0)
 		return -EINVAL;
 
-	addr = do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
+	addr = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
 	if (!IS_ERR((void *) addr))
 		force_successful_syscall_return();
 	return addr;
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index 4990495..a35c661 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -473,7 +473,7 @@
 {
 }
 
-void update_vsyscall(struct timespec *wall, struct clocksource *c)
+void update_vsyscall(struct timespec *wall, struct clocksource *c, u32 mult)
 {
         unsigned long flags;
 
@@ -481,7 +481,7 @@
 
         /* copy fsyscall clock data */
         fsyscall_gtod_data.clk_mask = c->mask;
-        fsyscall_gtod_data.clk_mult = c->mult;
+        fsyscall_gtod_data.clk_mult = mult;
         fsyscall_gtod_data.clk_shift = c->shift;
         fsyscall_gtod_data.clk_fsys_mmio = c->fsys_mmio;
         fsyscall_gtod_data.clk_cycle_last = c->cycle_last;
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index c0fca2c..df639db7 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -131,6 +131,7 @@
 }
 
 struct pci_root_info {
+	struct acpi_device *bridge;
 	struct pci_controller *controller;
 	char *name;
 };
@@ -297,9 +298,20 @@
 	window->offset = offset;
 
 	if (insert_resource(root, &window->resource)) {
-		printk(KERN_ERR "alloc 0x%llx-0x%llx from %s for %s failed\n",
-			window->resource.start, window->resource.end,
-			root->name, info->name);
+		dev_err(&info->bridge->dev,
+			"can't allocate host bridge window %pR\n",
+			&window->resource);
+	} else {
+		if (offset)
+			dev_info(&info->bridge->dev, "host bridge window %pR "
+				 "(PCI address [%#llx-%#llx])\n",
+				 &window->resource,
+				 window->resource.start - offset,
+				 window->resource.end - offset);
+		else
+			dev_info(&info->bridge->dev,
+				 "host bridge window %pR\n",
+				 &window->resource);
 	}
 
 	return AE_OK;
@@ -319,8 +331,9 @@
 		    (res->end - res->start < 16))
 			continue;
 		if (j >= PCI_BUS_NUM_RESOURCES) {
-			printk("Ignoring range [%#llx-%#llx] (%lx)\n",
-					res->start, res->end, res->flags);
+			dev_warn(&bus->dev,
+				 "ignoring host bridge window %pR (no space)\n",
+				 res);
 			continue;
 		}
 		bus->resource[j++] = res;
@@ -364,6 +377,7 @@
 			goto out3;
 
 		sprintf(name, "PCI Bus %04x:%02x", domain, bus);
+		info.bridge = device;
 		info.controller = controller;
 		info.name = name;
 		acpi_walk_resources(device->handle, METHOD_NAME__CRS,
@@ -720,9 +734,6 @@
 	return ret;
 }
 
-/* It's defined in drivers/pci/pci.c */
-extern u8 pci_cache_line_size;
-
 /**
  * set_pci_cacheline_size - determine cacheline size for PCI devices
  *
@@ -731,7 +742,7 @@
  *
  * Code mostly taken from arch/ia64/kernel/palinfo.c:cache_info().
  */
-static void __init set_pci_cacheline_size(void)
+static void __init set_pci_dfl_cacheline_size(void)
 {
 	unsigned long levels, unique_caches;
 	long status;
@@ -751,7 +762,7 @@
 			"(status=%ld)\n", __func__, status);
 		return;
 	}
-	pci_cache_line_size = (1 << cci.pcci_line_size) / 4;
+	pci_dfl_cache_line_size = (1 << cci.pcci_line_size) / 4;
 }
 
 u64 ia64_dma_get_required_mask(struct device *dev)
@@ -782,7 +793,7 @@
 
 static int __init pcibios_init(void)
 {
-	set_pci_cacheline_size();
+	set_pci_dfl_cacheline_size();
 	return 0;
 }
 
diff --git a/arch/ia64/sn/kernel/io_acpi_init.c b/arch/ia64/sn/kernel/io_acpi_init.c
index fd50ff9..66f633b 100644
--- a/arch/ia64/sn/kernel/io_acpi_init.c
+++ b/arch/ia64/sn/kernel/io_acpi_init.c
@@ -390,7 +390,7 @@
 	pcidev_match.handle = NULL;
 
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, rootbus_handle, ACPI_UINT32_MAX,
-			    find_matching_device, &pcidev_match, NULL);
+			    find_matching_device, NULL, &pcidev_match, NULL);
 
 	if (!pcidev_match.handle) {
 		printk(KERN_ERR
diff --git a/arch/m32r/kernel/sys_m32r.c b/arch/m32r/kernel/sys_m32r.c
index 305ac85..d3c865c 100644
--- a/arch/m32r/kernel/sys_m32r.c
+++ b/arch/m32r/kernel/sys_m32r.c
@@ -76,30 +76,6 @@
 	return oldval;
 }
 
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags,
-	unsigned long fd, unsigned long pgoff)
-{
-	int error = -EBADF;
-	struct file *file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-
 /*
  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
  *
diff --git a/arch/m32r/kernel/syscall_table.S b/arch/m32r/kernel/syscall_table.S
index aa3bf4c..60536e2 100644
--- a/arch/m32r/kernel/syscall_table.S
+++ b/arch/m32r/kernel/syscall_table.S
@@ -191,7 +191,7 @@
 	.long sys_ni_syscall		/* streams2 */
 	.long sys_vfork			/* 190 */
 	.long sys_getrlimit
-	.long sys_mmap2
+	.long sys_mmap_pgoff
 	.long sys_truncate64
 	.long sys_ftruncate64
 	.long sys_stat64		/* 195 */
diff --git a/arch/m68k/ifpsp060/src/fpsp.S b/arch/m68k/ifpsp060/src/fpsp.S
index 6c1a9a2..73613b5 100644
--- a/arch/m68k/ifpsp060/src/fpsp.S
+++ b/arch/m68k/ifpsp060/src/fpsp.S
@@ -753,7 +753,7 @@
 
 	bra.l		_real_ovfl
 
-# overflow occurred but is disabled. meanwhile, inexact is enabled. therefore,
+# overflow occurred but is disabled. meanwhile, inexact is enabled. Therefore,
 # we must jump to real_inex().
 fovfl_inex_on:
 
@@ -1015,7 +1015,7 @@
 
 	bra.l		_real_unfl
 
-# undeflow occurred but is disabled. meanwhile, inexact is enabled. therefore,
+# underflow occurred but is disabled. meanwhile, inexact is enabled. Therefore,
 # we must jump to real_inex().
 funfl_inex_on:
 
@@ -2963,7 +2963,7 @@
 
 	tst.w		%d0			# is instr fmovm?
 	bmi.b		iea_dis_fmovm		# yes
-# instruction is using an extended precision immediate operand. therefore,
+# instruction is using an extended precision immediate operand. Therefore,
 # the total instruction length is 16 bytes.
 iea_dis_immed:
 	mov.l		&0x10,%d0		# 16 bytes of instruction
@@ -9624,7 +9624,7 @@
 	bge.b		sok_norm2		# thank goodness no
 
 # the multiply factor that we're trying to create should be a denorm
-# for the multiply to work. therefore, we're going to actually do a
+# for the multiply to work. Therefore, we're going to actually do a
 # multiply with a denorm which will cause an unimplemented data type
 # exception to be put into the machine which will be caught and corrected
 # later. we don't do this with the DENORMs above because this method
@@ -12216,7 +12216,7 @@
 
 #
 # operand will underflow AND underflow or inexact is enabled.
-# therefore, we must return the result rounded to extended precision.
+# Therefore, we must return the result rounded to extended precision.
 #
 fin_sd_unfl_ena:
 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
@@ -12746,7 +12746,7 @@
 
 #
 # The destination was In Range and the source was a ZERO. The result,
-# therefore, is an INF w/ the proper sign.
+# Therefore, is an INF w/ the proper sign.
 # So, determine the sign and return a new INF (w/ the j-bit cleared).
 #
 	global		fdiv_inf_load		# global for fsgldiv
@@ -12996,7 +12996,7 @@
 
 #
 # operand will underflow AND underflow is enabled.
-# therefore, we must return the result rounded to extended precision.
+# Therefore, we must return the result rounded to extended precision.
 #
 fneg_sd_unfl_ena:
 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
@@ -13611,7 +13611,7 @@
 
 #
 # operand will underflow AND underflow is enabled.
-# therefore, we must return the result rounded to extended precision.
+# Therefore, we must return the result rounded to extended precision.
 #
 fabs_sd_unfl_ena:
 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
@@ -14973,7 +14973,7 @@
 
 #
 # the ZEROes have opposite signs:
-# - therefore, we return +ZERO if the rounding modes are RN,RZ, or RP.
+# - Therefore, we return +ZERO if the rounding modes are RN,RZ, or RP.
 # - -ZERO is returned in the case of RM.
 #
 fadd_zero_2_chk_rm:
@@ -15425,7 +15425,7 @@
 
 #
 # the ZEROes have the same signs:
-# - therefore, we return +ZERO if the rounding mode is RN,RZ, or RP
+# - Therefore, we return +ZERO if the rounding mode is RN,RZ, or RP
 # - -ZERO is returned in the case of RM.
 #
 fsub_zero_2_chk_rm:
@@ -15693,7 +15693,7 @@
 
 #
 # operand will underflow AND underflow is enabled.
-# therefore, we must return the result rounded to extended precision.
+# Therefore, we must return the result rounded to extended precision.
 #
 fsqrt_sd_unfl_ena:
 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
@@ -21000,7 +21000,7 @@
 	tst.l		%d0
 	bne.b		fout_pack_set
 # "mantissa" is all zero which means that the answer is zero. but, the '040
-# algorithm allows the exponent to be non-zero. the 881/2 do not. therefore,
+# algorithm allows the exponent to be non-zero. the 881/2 do not. Therefore,
 # if the mantissa is zero, I will zero the exponent, too.
 # the question now is whether the exponents sign bit is allowed to be non-zero
 # for a zero, also...
@@ -21743,7 +21743,7 @@
 	rts
 
 #									#
-# dnrm_lp(): normalize exponent/mantissa to specified threshhold	#
+# dnrm_lp(): normalize exponent/mantissa to specified threshold		#
 #									#
 # INPUT:								#
 #	%a0	   : points to the operand to be denormalized		#
@@ -22402,7 +22402,7 @@
 	bgt.b		unnorm_nrm_zero		# yes; denorm only until exp = 0
 
 #
-# exponent would not go < 0. therefore, number stays normalized
+# exponent would not go < 0. Therefore, number stays normalized
 #
 	sub.w		%d0, %d1		# shift exponent value
 	mov.w		FTEMP_EX(%a0), %d0	# load old exponent
diff --git a/arch/m68k/ifpsp060/src/pfpsp.S b/arch/m68k/ifpsp060/src/pfpsp.S
index 51b9f7d..e71ba0a 100644
--- a/arch/m68k/ifpsp060/src/pfpsp.S
+++ b/arch/m68k/ifpsp060/src/pfpsp.S
@@ -752,7 +752,7 @@
 
 	bra.l		_real_ovfl
 
-# overflow occurred but is disabled. meanwhile, inexact is enabled. therefore,
+# overflow occurred but is disabled. meanwhile, inexact is enabled. Therefore,
 # we must jump to real_inex().
 fovfl_inex_on:
 
@@ -1014,7 +1014,7 @@
 
 	bra.l		_real_unfl
 
-# undeflow occurred but is disabled. meanwhile, inexact is enabled. therefore,
+# underflow occurred but is disabled. meanwhile, inexact is enabled. Therefore,
 # we must jump to real_inex().
 funfl_inex_on:
 
@@ -2962,7 +2962,7 @@
 
 	tst.w		%d0			# is instr fmovm?
 	bmi.b		iea_dis_fmovm		# yes
-# instruction is using an extended precision immediate operand. therefore,
+# instruction is using an extended precision immediate operand. Therefore,
 # the total instruction length is 16 bytes.
 iea_dis_immed:
 	mov.l		&0x10,%d0		# 16 bytes of instruction
@@ -5865,7 +5865,7 @@
 	rts
 
 #									#
-# dnrm_lp(): normalize exponent/mantissa to specified threshhold	#
+# dnrm_lp(): normalize exponent/mantissa to specified threshold		#
 #									#
 # INPUT:								#
 #	%a0	   : points to the operand to be denormalized		#
@@ -6524,7 +6524,7 @@
 	bgt.b		unnorm_nrm_zero		# yes; denorm only until exp = 0
 
 #
-# exponent would not go < 0. therefore, number stays normalized
+# exponent would not go < 0. Therefore, number stays normalized
 #
 	sub.w		%d0, %d1		# shift exponent value
 	mov.w		FTEMP_EX(%a0), %d0	# load old exponent
@@ -7901,7 +7901,7 @@
 	tst.l		%d0
 	bne.b		fout_pack_set
 # "mantissa" is all zero which means that the answer is zero. but, the '040
-# algorithm allows the exponent to be non-zero. the 881/2 do not. therefore,
+# algorithm allows the exponent to be non-zero. the 881/2 do not. Therefore,
 # if the mantissa is zero, I will zero the exponent, too.
 # the question now is whether the exponents sign bit is allowed to be non-zero
 # for a zero, also...
@@ -8647,7 +8647,7 @@
 
 #
 # operand will underflow AND underflow or inexact is enabled.
-# therefore, we must return the result rounded to extended precision.
+# Therefore, we must return the result rounded to extended precision.
 #
 fin_sd_unfl_ena:
 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
@@ -9177,7 +9177,7 @@
 
 #
 # The destination was In Range and the source was a ZERO. The result,
-# therefore, is an INF w/ the proper sign.
+# Therefore, is an INF w/ the proper sign.
 # So, determine the sign and return a new INF (w/ the j-bit cleared).
 #
 	global		fdiv_inf_load		# global for fsgldiv
@@ -9427,7 +9427,7 @@
 
 #
 # operand will underflow AND underflow is enabled.
-# therefore, we must return the result rounded to extended precision.
+# Therefore, we must return the result rounded to extended precision.
 #
 fneg_sd_unfl_ena:
 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
@@ -10042,7 +10042,7 @@
 
 #
 # operand will underflow AND underflow is enabled.
-# therefore, we must return the result rounded to extended precision.
+# Therefore, we must return the result rounded to extended precision.
 #
 fabs_sd_unfl_ena:
 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
@@ -11404,7 +11404,7 @@
 
 #
 # the ZEROes have opposite signs:
-# - therefore, we return +ZERO if the rounding modes are RN,RZ, or RP.
+# - Therefore, we return +ZERO if the rounding modes are RN,RZ, or RP.
 # - -ZERO is returned in the case of RM.
 #
 fadd_zero_2_chk_rm:
@@ -11856,7 +11856,7 @@
 
 #
 # the ZEROes have the same signs:
-# - therefore, we return +ZERO if the rounding mode is RN,RZ, or RP
+# - Therefore, we return +ZERO if the rounding mode is RN,RZ, or RP
 # - -ZERO is returned in the case of RM.
 #
 fsub_zero_2_chk_rm:
@@ -12124,7 +12124,7 @@
 
 #
 # operand will underflow AND underflow is enabled.
-# therefore, we must return the result rounded to extended precision.
+# Therefore, we must return the result rounded to extended precision.
 #
 fsqrt_sd_unfl_ena:
 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
diff --git a/arch/m68k/include/asm/bootinfo.h b/arch/m68k/include/asm/bootinfo.h
index fb8a06b..67e7a78 100644
--- a/arch/m68k/include/asm/bootinfo.h
+++ b/arch/m68k/include/asm/bootinfo.h
@@ -145,7 +145,7 @@
 
     /*
      *  Macintosh hardware profile data - unused, see macintosh.h for
-     *  resonable type values
+     *  reasonable type values
      */
 
 #define BI_MAC_VIA1BASE		0x8010	/* Mac VIA1 base address (always present) */
diff --git a/arch/m68k/include/asm/processor.h b/arch/m68k/include/asm/processor.h
index 74fd674..cbd3d47 100644
--- a/arch/m68k/include/asm/processor.h
+++ b/arch/m68k/include/asm/processor.h
@@ -165,6 +165,8 @@
 	eip; })
 #define	KSTK_ESP(tsk)	((tsk) == current ? rdusp() : (tsk)->thread.usp)
 
+#define task_pt_regs(tsk)	((struct pt_regs *) ((tsk)->thread.esp0))
+
 #define cpu_relax()	barrier()
 
 #endif
diff --git a/arch/m68k/include/asm/ptrace.h b/arch/m68k/include/asm/ptrace.h
index a6ab663..ee4011c 100644
--- a/arch/m68k/include/asm/ptrace.h
+++ b/arch/m68k/include/asm/ptrace.h
@@ -86,7 +86,7 @@
 extern void show_regs(struct pt_regs *);
 
 /*
- * These are defined as per linux/ptrace.h, which see.
+ * These are defined as per linux/ptrace.h.
  */
 struct task_struct;
 
diff --git a/arch/m68k/include/asm/thread_info_no.h b/arch/m68k/include/asm/thread_info_no.h
index c2bde5e..a6512bf 100644
--- a/arch/m68k/include/asm/thread_info_no.h
+++ b/arch/m68k/include/asm/thread_info_no.h
@@ -12,8 +12,6 @@
 
 #ifdef __KERNEL__
 
-#ifndef __ASSEMBLY__
-
 /*
  * Size of kernel stack for each process. This must be a power of 2...
  */
@@ -28,6 +26,8 @@
  */
 #define THREAD_SIZE (PAGE_SIZE<<THREAD_SIZE_ORDER)
 
+#ifndef __ASSEMBLY__
+
 /*
  * low level task data.
  */
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c
index 7deb402..218f441 100644
--- a/arch/m68k/kernel/sys_m68k.c
+++ b/arch/m68k/kernel/sys_m68k.c
@@ -29,37 +29,16 @@
 #include <asm/page.h>
 #include <asm/unistd.h>
 
-/* common code for old and new mmaps */
-static inline long do_mmap2(
-	unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags,
-	unsigned long fd, unsigned long pgoff)
-{
-	int error = -EBADF;
-	struct file * file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-
 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
 	unsigned long prot, unsigned long flags,
 	unsigned long fd, unsigned long pgoff)
 {
-	return do_mmap2(addr, len, prot, flags, fd, pgoff);
+	/*
+	 * This is wrong for sun3 - there PAGE_SIZE is 8Kb,
+	 * so we need to shift the argument down by 1; m68k mmap64(3)
+	 * (in libc) expects the last argument of mmap2 in 4Kb units.
+	 */
+	return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
 }
 
 /*
@@ -90,58 +69,12 @@
 	if (a.offset & ~PAGE_MASK)
 		goto out;
 
-	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+	error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
+			       a.offset >> PAGE_SHIFT);
 out:
 	return error;
 }
 
-#if 0
-struct mmap_arg_struct64 {
-	__u32 addr;
-	__u32 len;
-	__u32 prot;
-	__u32 flags;
-	__u64 offset; /* 64 bits */
-	__u32 fd;
-};
-
-asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
-{
-	int error = -EFAULT;
-	struct file * file = NULL;
-	struct mmap_arg_struct64 a;
-	unsigned long pgoff;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-
-	if ((long)a.offset & ~PAGE_MASK)
-		return -EINVAL;
-
-	pgoff = a.offset >> PAGE_SHIFT;
-	if ((a.offset >> PAGE_SHIFT) != pgoff)
-		return -EINVAL;
-
-	if (!(a.flags & MAP_ANONYMOUS)) {
-		error = -EBADF;
-		file = fget(a.fd);
-		if (!file)
-			goto out;
-	}
-	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-#endif
-
 struct sel_arg_struct {
 	unsigned long n;
 	fd_set __user *inp, *outp, *exp;
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index e2201b9..064f591 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -533,6 +533,13 @@
 	default y
 	depends on (AVNET5282)
 
+config UBOOT
+	bool "Support for U-Boot command line parameters"
+	help
+	  If you say Y here kernel will try to collect command
+	  line parameters from the initial u-boot stack.
+	default n
+
 config 4KSTACKS
 	bool "Use 4Kb for kernel stacks instead of 8Kb"
 	default y
diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c
index 8f8f4ab..5c9ecd4 100644
--- a/arch/m68knommu/kernel/process.c
+++ b/arch/m68knommu/kernel/process.c
@@ -352,15 +352,12 @@
 	char * filename;
 	struct pt_regs *regs = (struct pt_regs *) &name;
 
-	lock_kernel();
 	filename = getname(name);
 	error = PTR_ERR(filename);
 	if (IS_ERR(filename))
-		goto out;
+		return error;
 	error = do_execve(filename, argv, envp, regs);
 	putname(filename);
-out:
-	unlock_kernel();
 	return error;
 }
 
diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c
index 5c2bb3e..ba92b90 100644
--- a/arch/m68knommu/kernel/setup.c
+++ b/arch/m68knommu/kernel/setup.c
@@ -29,6 +29,8 @@
 #include <linux/bootmem.h>
 #include <linux/seq_file.h>
 #include <linux/init.h>
+#include <linux/initrd.h>
+#include <linux/root_dev.h>
 
 #include <asm/setup.h>
 #include <asm/irq.h>
@@ -52,7 +54,6 @@
 void (*mach_halt)(void);
 void (*mach_power_off)(void);
 
-
 #ifdef CONFIG_M68000
 	#define CPU "MC68000"
 #endif
@@ -111,6 +112,69 @@
 extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end;
 extern int _ramstart, _ramend;
 
+#if defined(CONFIG_UBOOT)
+/*
+ * parse_uboot_commandline
+ *
+ * Copies u-boot commandline arguments and store them in the proper linux
+ * variables.
+ *
+ * Assumes:
+ *	_init_sp global contains the address in the stack pointer when the
+ *	kernel starts (see head.S::_start)
+ *
+ *	U-Boot calling convention:
+ *	(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
+ *
+ *	_init_sp can be parsed as such
+ *
+ *	_init_sp+00 = u-boot cmd after jsr into kernel (skip)
+ *	_init_sp+04 = &kernel board_info (residual data)
+ *	_init_sp+08 = &initrd_start
+ *	_init_sp+12 = &initrd_end
+ *	_init_sp+16 = &cmd_start
+ *	_init_sp+20 = &cmd_end
+ *
+ *	This also assumes that the memory locations pointed to are still
+ *	unmodified. U-boot places them near the end of external SDRAM.
+ *
+ * Argument(s):
+ *	commandp = the linux commandline arg container to fill.
+ *	size     = the sizeof commandp.
+ *
+ * Returns:
+ */
+void parse_uboot_commandline(char *commandp, int size)
+{
+	extern unsigned long _init_sp;
+	unsigned long *sp;
+	unsigned long uboot_kbd;
+	unsigned long uboot_initrd_start, uboot_initrd_end;
+	unsigned long uboot_cmd_start, uboot_cmd_end;
+
+
+	sp = (unsigned long *)_init_sp;
+	uboot_kbd = sp[1];
+	uboot_initrd_start = sp[2];
+	uboot_initrd_end = sp[3];
+	uboot_cmd_start = sp[4];
+	uboot_cmd_end = sp[5];
+
+	if (uboot_cmd_start && uboot_cmd_end)
+		strncpy(commandp, (const char *)uboot_cmd_start, size);
+#if defined(CONFIG_BLK_DEV_INITRD)
+	if (uboot_initrd_start && uboot_initrd_end &&
+		(uboot_initrd_end > uboot_initrd_start)) {
+		initrd_start = uboot_initrd_start;
+		initrd_end = uboot_initrd_end;
+		ROOT_DEV = Root_RAM0;
+		printk(KERN_INFO "initrd at 0x%lx:0x%lx\n",
+			initrd_start, initrd_end);
+	}
+#endif /* if defined(CONFIG_BLK_DEV_INITRD) */
+}
+#endif /* #if defined(CONFIG_UBOOT) */
+
 void __init setup_arch(char **cmdline_p)
 {
 	int bootmap_size;
@@ -128,7 +192,24 @@
 #if defined(CONFIG_BOOTPARAM)
 	strncpy(&command_line[0], CONFIG_BOOTPARAM_STRING, sizeof(command_line));
 	command_line[sizeof(command_line) - 1] = 0;
-#endif
+#endif /* CONFIG_BOOTPARAM */
+
+#if defined(CONFIG_UBOOT)
+	/* CONFIG_UBOOT and CONFIG_BOOTPARAM defined, concatenate cmdline */
+	#if defined(CONFIG_BOOTPARAM)
+		/* Add the whitespace separator */
+		command_line[strlen(CONFIG_BOOTPARAM_STRING)] = ' ';
+		/* Parse uboot command line into the rest of the buffer */
+		parse_uboot_commandline(
+			&command_line[(strlen(CONFIG_BOOTPARAM_STRING)+1)],
+			(sizeof(command_line) -
+			(strlen(CONFIG_BOOTPARAM_STRING)+1)));
+	/* Only CONFIG_UBOOT defined, create cmdline */
+	#else
+		parse_uboot_commandline(&command_line[0], sizeof(command_line));
+	#endif /* CONFIG_BOOTPARAM */
+	command_line[sizeof(command_line) - 1] = 0;
+#endif /* CONFIG_UBOOT */
 
 	printk(KERN_INFO "\x0F\r\n\nuClinux/" CPU "\n");
 
@@ -204,6 +285,13 @@
 	free_bootmem(memory_start, memory_end - memory_start);
 	reserve_bootmem(memory_start, bootmap_size, BOOTMEM_DEFAULT);
 
+#if defined(CONFIG_UBOOT) && defined(CONFIG_BLK_DEV_INITRD)
+	if ((initrd_start > 0) && (initrd_start < initrd_end) &&
+			(initrd_end < memory_end))
+		reserve_bootmem(initrd_start, initrd_end - initrd_start,
+				 BOOTMEM_DEFAULT);
+#endif /* if defined(CONFIG_BLK_DEV_INITRD) */
+
 	/*
 	 * Get kmalloc into gear.
 	 */
diff --git a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c
index efdd090..b67cbc7 100644
--- a/arch/m68knommu/kernel/sys_m68k.c
+++ b/arch/m68knommu/kernel/sys_m68k.c
@@ -27,39 +27,6 @@
 #include <asm/cacheflush.h>
 #include <asm/unistd.h>
 
-/* common code for old and new mmaps */
-static inline long do_mmap2(
-	unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags,
-	unsigned long fd, unsigned long pgoff)
-{
-	int error = -EBADF;
-	struct file * file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags,
-	unsigned long fd, unsigned long pgoff)
-{
-	return do_mmap2(addr, len, prot, flags, fd, pgoff);
-}
-
 /*
  * Perform the select(nd, in, out, ex, tv) and mmap() system
  * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
@@ -88,9 +55,8 @@
 	if (a.offset & ~PAGE_MASK)
 		goto out;
 
-	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+	error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
+				a.offset >> PAGE_SHIFT);
 out:
 	return error;
 }
diff --git a/arch/m68knommu/kernel/syscalltable.S b/arch/m68knommu/kernel/syscalltable.S
index 23535cc..486837e 100644
--- a/arch/m68knommu/kernel/syscalltable.S
+++ b/arch/m68knommu/kernel/syscalltable.S
@@ -210,7 +210,7 @@
 	.long sys_ni_syscall	/* streams2 */
 	.long sys_vfork		/* 190 */
 	.long sys_getrlimit
-	.long sys_mmap2
+	.long sys_mmap_pgoff
 	.long sys_truncate64
 	.long sys_ftruncate64
 	.long sys_stat64	/* 195 */
diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S
index 2736a5e..9f1784f 100644
--- a/arch/m68knommu/kernel/vmlinux.lds.S
+++ b/arch/m68knommu/kernel/vmlinux.lds.S
@@ -8,6 +8,8 @@
  */
 
 #include <asm-generic/vmlinux.lds.h>
+#include <asm/page.h>
+#include <asm/thread_info.h>
 
 #if defined(CONFIG_RAMKERNEL)
 #define	RAM_START	CONFIG_KERNELBASE
@@ -15,7 +17,7 @@
 #define	TEXT		ram
 #define	DATA		ram
 #define	INIT		ram
-#define	BSS		ram
+#define	BSSS		ram
 #endif
 #if defined(CONFIG_ROMKERNEL) || defined(CONFIG_HIMEMKERNEL)
 #define	RAM_START	CONFIG_RAMBASE
@@ -27,7 +29,7 @@
 #define	TEXT		rom
 #define	DATA		ram
 #define	INIT		ram
-#define	BSS		ram
+#define	BSSS		ram
 #endif
 
 #ifndef DATA_ADDR
@@ -147,40 +149,19 @@
 		. = ALIGN(4);
 		_sdata = . ;
 		DATA_DATA
-		. = ALIGN(32);
-		*(.data.cacheline_aligned)
-		. = ALIGN(8192) ;
-		*(.data.init_task)
+		CACHELINE_ALIGNED_DATA(32)
+		INIT_TASK_DATA(THREAD_SIZE)
 		_edata = . ;
 	} > DATA
 
-	.init : {
-		. = ALIGN(4096);
+	.init.text : {
+		. = ALIGN(PAGE_SIZE);
 		__init_begin = .;
-		_sinittext = .;
-		INIT_TEXT
-		_einittext = .;
-		INIT_DATA
-		. = ALIGN(16);
-		__setup_start = .;
-		*(.init.setup)
-		__setup_end = .;
-		__initcall_start = .;
-		INITCALLS
-		__initcall_end = .;
-		__con_initcall_start = .;
-		*(.con_initcall.init)
-		__con_initcall_end = .;
-		__security_initcall_start = .;
-		*(.security_initcall.init)
-		__security_initcall_end = .;
-#ifdef CONFIG_BLK_DEV_INITRD
-		. = ALIGN(4);
-		__initramfs_start = .;
-		*(.init.ramfs)
-		__initramfs_end = .;
-#endif
-		. = ALIGN(4096);
+	} > INIT
+	INIT_TEXT_SECTION(PAGE_SIZE) > INIT
+	INIT_DATA_SECTION(16) > INIT
+	.init.data : {
+		. = ALIGN(PAGE_SIZE);
 		__init_end = .;
 	} > INIT
 
@@ -192,7 +173,7 @@
 		. = ALIGN(4) ;
 		_ebss = . ;
 	 	_end = . ;
-	} > BSS
+	} > BSSS
 
 	DISCARDS
 }
diff --git a/arch/m68knommu/platform/523x/gpio.c b/arch/m68knommu/platform/523x/gpio.c
index f02840d..a8842dc 100644
--- a/arch/m68knommu/platform/523x/gpio.c
+++ b/arch/m68knommu/platform/523x/gpio.c
@@ -30,7 +30,8 @@
 			.direction_output	= mcf_gpio_direction_output,
 			.get			= mcf_gpio_get_value,
 			.set			= mcf_gpio_set_value,
-			.ngpio			= 8,
+			.base			= 1,
+			.ngpio			= 7,
 		},
 		.pddr				= MCFEPORT_EPDDR,
 		.podr				= MCFEPORT_EPDR,
@@ -244,7 +245,7 @@
 			.get			= mcf_gpio_get_value,
 			.set			= mcf_gpio_set_value_fast,
 			.base			= 96,
-			.ngpio			= 4,
+			.ngpio			= 8,
 		},
 		.pddr				= MCFGPIO_PDDR_TIMER,
 		.podr				= MCFGPIO_PODR_TIMER,
diff --git a/arch/m68knommu/platform/527x/gpio.c b/arch/m68knommu/platform/527x/gpio.c
index 1028142..0b56e19 100644
--- a/arch/m68knommu/platform/527x/gpio.c
+++ b/arch/m68knommu/platform/527x/gpio.c
@@ -31,7 +31,8 @@
 			.direction_output	= mcf_gpio_direction_output,
 			.get			= mcf_gpio_get_value,
 			.set			= mcf_gpio_set_value,
-			.ngpio			= 8,
+			.base			= 1,
+			.ngpio			= 7,
 		},
 		.pddr				= MCFEPORT_EPDDR,
 		.podr				= MCFEPORT_EPDR,
@@ -263,7 +264,8 @@
 			.direction_output	= mcf_gpio_direction_output,
 			.get			= mcf_gpio_get_value,
 			.set			= mcf_gpio_set_value,
-			.ngpio			= 8,
+			.base			= 1,
+			.ngpio			= 7,
 		},
 		.pddr				= MCFEPORT_EPDDR,
 		.podr				= MCFEPORT_EPDR,
diff --git a/arch/m68knommu/platform/528x/gpio.c b/arch/m68knommu/platform/528x/gpio.c
index ec59395..eedaf0a 100644
--- a/arch/m68knommu/platform/528x/gpio.c
+++ b/arch/m68knommu/platform/528x/gpio.c
@@ -31,7 +31,7 @@
 			.get			= mcf_gpio_get_value,
 			.set			= mcf_gpio_set_value,
 			.base			= 1,
-			.ngpio			= 8,
+			.ngpio			= 7,
 		},
 		.pddr				= MCFEPORT_EPDDR,
 		.podr				= MCFEPORT_EPDR,
diff --git a/arch/m68knommu/platform/coldfire/clk.c b/arch/m68knommu/platform/coldfire/clk.c
index 7cdbf44..9f1260c 100644
--- a/arch/m68knommu/platform/coldfire/clk.c
+++ b/arch/m68knommu/platform/coldfire/clk.c
@@ -9,6 +9,7 @@
 /***************************************************************************/
 
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/clk.h>
 #include <asm/coldfire.h>
 
@@ -18,23 +19,27 @@
 {
 	return NULL;
 }
+EXPORT_SYMBOL(clk_get);
 
 int clk_enable(struct clk *clk)
 {
 	return 0;
 }
+EXPORT_SYMBOL(clk_enable);
 
 void clk_disable(struct clk *clk)
 {
 }
+EXPORT_SYMBOL(clk_disable);
 
 void clk_put(struct clk *clk)
 {
 }
+EXPORT_SYMBOL(clk_put);
 
 unsigned long clk_get_rate(struct clk *clk)
 {
 	return MCF_CLK;
 }
-
+EXPORT_SYMBOL(clk_get_rate);
 /***************************************************************************/
diff --git a/arch/m68knommu/platform/coldfire/head.S b/arch/m68knommu/platform/coldfire/head.S
index 2b0d73c..4b91aa2 100644
--- a/arch/m68knommu/platform/coldfire/head.S
+++ b/arch/m68knommu/platform/coldfire/head.S
@@ -106,6 +106,9 @@
 .global _ramvec
 .global	_ramstart
 .global	_ramend
+#if defined(CONFIG_UBOOT)
+.global	_init_sp
+#endif
 
 /*****************************************************************************/
 
@@ -124,6 +127,10 @@
 .long	0
 _ramend:
 .long	0
+#if defined(CONFIG_UBOOT)
+_init_sp:
+.long	0
+#endif
 
 /*****************************************************************************/
 
@@ -137,6 +144,9 @@
 _start:
 	nop					/* filler */
 	movew	#0x2700, %sr			/* no interrupts */
+#if defined(CONFIG_UBOOT)
+	movel	%sp,_init_sp			/* save initial stack pointer */
+#endif
 
 	/*
 	 *	Do any platform or board specific setup now. Most boards
diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c
index 07cabed..9f3c205 100644
--- a/arch/microblaze/kernel/sys_microblaze.c
+++ b/arch/microblaze/kernel/sys_microblaze.c
@@ -62,46 +62,14 @@
 	return error;
 }
 
-asmlinkage long
-sys_mmap2(unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags,
-	unsigned long fd, unsigned long pgoff)
-{
-	struct file *file = NULL;
-	int ret = -EBADF;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file) {
-			printk(KERN_INFO "no fd in mmap\r\n");
-			goto out;
-		}
-	}
-
-	down_write(&current->mm->mmap_sem);
-	ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-	if (file)
-		fput(file);
-out:
-	return ret;
-}
-
 asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
 			unsigned long prot, unsigned long flags,
 			unsigned long fd, off_t pgoff)
 {
-	int err = -EINVAL;
+	if (pgoff & ~PAGE_MASK)
+		return -EINVAL;
 
-	if (pgoff & ~PAGE_MASK) {
-		printk(KERN_INFO "no pagemask in mmap\r\n");
-		goto out;
-	}
-
-	err = sys_mmap2(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT);
-out:
-	return err;
+	return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT);
 }
 
 /*
diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S
index c1ab1dc..b96f365 100644
--- a/arch/microblaze/kernel/syscall_table.S
+++ b/arch/microblaze/kernel/syscall_table.S
@@ -196,7 +196,7 @@
 	.long sys_ni_syscall		/* reserved for streams2 */
 	.long sys_vfork		/* 190 */
 	.long sys_getrlimit
-	.long sys_mmap2			/* mmap2 */
+	.long sys_mmap_pgoff		/* mmap2 */
 	.long sys_truncate64
 	.long sys_ftruncate64
 	.long sys_stat64		/* 195 */
diff --git a/arch/microblaze/lib/memcpy.c b/arch/microblaze/lib/memcpy.c
index 6a907c5..cc2108b 100644
--- a/arch/microblaze/lib/memcpy.c
+++ b/arch/microblaze/lib/memcpy.c
@@ -9,7 +9,7 @@
  * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
  * http://www.embedded.com/showArticle.jhtml?articleID=19205567
  *
- * Attempts were made, unsuccesfully, to contact the original
+ * Attempts were made, unsuccessfully, to contact the original
  * author of this code (Michael Morrow, Intel).  Below is the original
  * copyright notice.
  *
diff --git a/arch/microblaze/lib/memmove.c b/arch/microblaze/lib/memmove.c
index d4e9f49..0929198 100644
--- a/arch/microblaze/lib/memmove.c
+++ b/arch/microblaze/lib/memmove.c
@@ -9,7 +9,7 @@
  * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
  * http://www.embedded.com/showArticle.jhtml?articleID=19205567
  *
- * Attempts were made, unsuccesfully, to contact the original
+ * Attempts were made, unsuccessfully, to contact the original
  * author of this code (Michael Morrow, Intel).  Below is the original
  * copyright notice.
  *
diff --git a/arch/microblaze/lib/memset.c b/arch/microblaze/lib/memset.c
index 941dc8f..4df851d 100644
--- a/arch/microblaze/lib/memset.c
+++ b/arch/microblaze/lib/memset.c
@@ -9,7 +9,7 @@
  * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
  * http://www.embedded.com/showArticle.jhtml?articleID=19205567
  *
- * Attempts were made, unsuccesfully, to contact the original
+ * Attempts were made, unsuccessfully, to contact the original
  * author of this code (Michael Morrow, Intel).  Below is the original
  * copyright notice.
  *
diff --git a/arch/mips/include/asm/fcntl.h b/arch/mips/include/asm/fcntl.h
index 2a52333..7c6681a 100644
--- a/arch/mips/include/asm/fcntl.h
+++ b/arch/mips/include/asm/fcntl.h
@@ -10,7 +10,7 @@
 
 
 #define O_APPEND	0x0008
-#define O_SYNC		0x0010
+#define O_DSYNC		0x0010	/* used to be O_SYNC, see below */
 #define O_NONBLOCK	0x0080
 #define O_CREAT         0x0100	/* not fcntl */
 #define O_TRUNC		0x0200	/* not fcntl */
@@ -18,6 +18,21 @@
 #define O_NOCTTY	0x0800	/* not fcntl */
 #define FASYNC		0x1000	/* fcntl, for BSD compatibility */
 #define O_LARGEFILE	0x2000	/* allow large file opens */
+/*
+ * Before Linux 2.6.32 only O_DSYNC semantics were implemented, but using
+ * the O_SYNC flag.  We continue to use the existing numerical value
+ * for O_DSYNC semantics now, but using the correct symbolic name for it.
+ * This new value is used to request true Posix O_SYNC semantics.  It is
+ * defined in this strange way to make sure applications compiled against
+ * new headers get at least O_DSYNC semantics on older kernels.
+ *
+ * This has the nice side-effect that we can simply test for O_DSYNC
+ * wherever we do not care if O_DSYNC or O_SYNC is used.
+ *
+ * Note: __O_SYNC must never be used directly.
+ */
+#define __O_SYNC	0x4000
+#define O_SYNC		(__O_SYNC|O_DSYNC)
 #define O_DIRECT	0x8000	/* direct disk access hint */
 
 #define F_GETLK		14
diff --git a/arch/mips/include/asm/mach-pnx833x/gpio.h b/arch/mips/include/asm/mach-pnx833x/gpio.h
index 8de0eb9..ed3a88d 100644
--- a/arch/mips/include/asm/mach-pnx833x/gpio.h
+++ b/arch/mips/include/asm/mach-pnx833x/gpio.h
@@ -24,7 +24,7 @@
 
 /* BIG FAT WARNING: races danger!
    No protections exist here. Current users are only early init code,
-   when locking is not needed because no cuncurency yet exists there,
+   when locking is not needed because no concurrency yet exists there,
    and GPIO IRQ dispatcher, which does locking.
    However, if many uses will ever happen, proper locking will be needed
    - including locking between different uses
diff --git a/arch/mips/include/asm/sgi/ioc.h b/arch/mips/include/asm/sgi/ioc.h
index 343ed15..57a9719 100644
--- a/arch/mips/include/asm/sgi/ioc.h
+++ b/arch/mips/include/asm/sgi/ioc.h
@@ -164,7 +164,7 @@
 	u32 _unused5;
 	u8 _write[3];
 	volatile u8 write;
-#define SGIOC_WRITE_NTHRESH	0x01	/* use 4.5db threshhold */
+#define SGIOC_WRITE_NTHRESH	0x01	/* use 4.5db threshold */
 #define SGIOC_WRITE_TPSPEED	0x02	/* use 100ohm TP speed */
 #define SGIOC_WRITE_EPSEL	0x04	/* force cable mode: 1=AUI 0=TP */
 #define SGIOC_WRITE_EASEL	0x08	/* 1=autoselect 0=manual cable selection */
diff --git a/arch/mips/include/asm/sibyte/sb1250_mac.h b/arch/mips/include/asm/sibyte/sb1250_mac.h
index b6faf08..591b906 100644
--- a/arch/mips/include/asm/sibyte/sb1250_mac.h
+++ b/arch/mips/include/asm/sibyte/sb1250_mac.h
@@ -212,7 +212,7 @@
 #define G_MAC_TXD_WEIGHT1(x)        _SB_GETVALUE(x, S_MAC_TXD_WEIGHT1, M_MAC_TXD_WEIGHT1)
 
 /*
- * MAC Fifo Threshhold registers (Table 9-14)
+ * MAC Fifo Threshold registers (Table 9-14)
  * Register: MAC_THRSH_CFG_0
  * Register: MAC_THRSH_CFG_1
  * Register: MAC_THRSH_CFG_2
diff --git a/arch/mips/include/asm/sn/sn0/hubio.h b/arch/mips/include/asm/sn/sn0/hubio.h
index d0c29d4..31c76c0 100644
--- a/arch/mips/include/asm/sn/sn0/hubio.h
+++ b/arch/mips/include/asm/sn/sn0/hubio.h
@@ -825,7 +825,7 @@
 	struct {
 	    u64	rsvd1:	15,
 		error:	1,	/* Widget rcvd wr resp pkt w/ error */
-		ovflow:	5,	/* Over flow count. perf measurement */
+		ovflow:	5,	/* Overflow count. perf measurement */
 		fire_and_forget: 1, /* Launch Write without response */
 		mode:	2,	/* Widget operation Mode	*/
 		rsvd2:	2,
diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h
index df6a430..c7f1bfe 100644
--- a/arch/mips/include/asm/time.h
+++ b/arch/mips/include/asm/time.h
@@ -84,8 +84,16 @@
 #endif
 }
 
-extern void clocksource_set_clock(struct clocksource *cs, unsigned int clock);
-extern void clockevent_set_clock(struct clock_event_device *cd,
-		unsigned int clock);
+static inline void clocksource_set_clock(struct clocksource *cs,
+					 unsigned int clock)
+{
+	clocksource_calc_mult_shift(cs, clock, 4);
+}
+
+static inline void clockevent_set_clock(struct clock_event_device *cd,
+					unsigned int clock)
+{
+	clockevents_calc_mult_shift(cd, clock, 4);
+}
 
 #endif /* _ASM_TIME_H */
diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c
index ad4e017..80e2ba6 100644
--- a/arch/mips/kernel/kspd.c
+++ b/arch/mips/kernel/kspd.c
@@ -82,6 +82,7 @@
 #define MTSP_O_SHLOCK		0x0010
 #define MTSP_O_EXLOCK		0x0020
 #define MTSP_O_ASYNC		0x0040
+/* XXX: check which of these is actually O_SYNC vs O_DSYNC */
 #define MTSP_O_FSYNC		O_SYNC
 #define MTSP_O_NOFOLLOW		0x0100
 #define MTSP_O_SYNC		0x0080
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 1a2793e..f042563 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -67,28 +67,13 @@
 	unsigned long, prot, unsigned long, flags, unsigned long, fd,
 	unsigned long, pgoff)
 {
-	struct file * file = NULL;
 	unsigned long error;
 
 	error = -EINVAL;
 	if (pgoff & (~PAGE_MASK >> 12))
 		goto out;
-	pgoff >>= PAGE_SHIFT-12;
-
-	if (!(flags & MAP_ANONYMOUS)) {
-		error = -EBADF;
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-	if (file)
-		fput(file);
-
+	error = sys_mmap_pgoff(addr, len, prot, flags, fd,
+			       pgoff >> (PAGE_SHIFT-12));
 out:
 	return error;
 }
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index 24630fd..a38e3ee 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -1331,7 +1331,7 @@
 		if (!((asid += ASID_INC) & ASID_MASK) ) {
 			if (cpu_has_vtag_icache)
 				flush_icache_all();
-			/* Traverse all online CPUs (hack requires contigous range) */
+			/* Traverse all online CPUs (hack requires contiguous range) */
 			for_each_online_cpu(i) {
 				/*
 				 * We don't need to worry about our own CPU, nor those of
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index fe0d798..3f7f466 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -93,7 +93,8 @@
 		 * We do not accept a shared mapping if it would violate
 		 * cache aliasing constraints.
 		 */
-		if ((flags & MAP_SHARED) && (addr & shm_align_mask))
+		if ((flags & MAP_SHARED) &&
+		    ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask))
 			return -EINVAL;
 		return addr;
 	}
@@ -129,31 +130,6 @@
 	}
 }
 
-/* common code for old and new mmaps */
-static inline unsigned long
-do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
-        unsigned long flags, unsigned long fd, unsigned long pgoff)
-{
-	unsigned long error = -EBADF;
-	struct file * file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-
 SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len,
 	unsigned long, prot, unsigned long, flags, unsigned long,
 	fd, off_t, offset)
@@ -164,7 +140,7 @@
 	if (offset & ~PAGE_MASK)
 		goto out;
 
-	result = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+	result = sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
 
 out:
 	return result;
@@ -177,7 +153,7 @@
 	if (pgoff & (~PAGE_MASK >> 12))
 		return -EINVAL;
 
-	return do_mmap2(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT-12));
+	return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT-12));
 }
 
 save_static_function(sys_fork);
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index 1f467d5..fb74974 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -71,39 +71,6 @@
 
 unsigned int mips_hpt_frequency;
 
-void __init clocksource_set_clock(struct clocksource *cs, unsigned int clock)
-{
-	u64 temp;
-	u32 shift;
-
-	/* Find a shift value */
-	for (shift = 32; shift > 0; shift--) {
-		temp = (u64) NSEC_PER_SEC << shift;
-		do_div(temp, clock);
-		if ((temp >> 32) == 0)
-			break;
-	}
-	cs->shift = shift;
-	cs->mult = (u32) temp;
-}
-
-void __cpuinit clockevent_set_clock(struct clock_event_device *cd,
-	unsigned int clock)
-{
-	u64 temp;
-	u32 shift;
-
-	/* Find a shift value */
-	for (shift = 32; shift > 0; shift--) {
-		temp = (u64) clock << shift;
-		do_div(temp, NSEC_PER_SEC);
-		if ((temp >> 32) == 0)
-			break;
-	}
-	cd->shift = shift;
-	cd->mult = (u32) temp;
-}
-
 /*
  * This function exists in order to cause an error due to a duplicate
  * definition if platform code should have its own implementation.  The hook
diff --git a/arch/mips/loongson/common/mem.c b/arch/mips/loongson/common/mem.c
index 7c92f79..e94ef15 100644
--- a/arch/mips/loongson/common/mem.c
+++ b/arch/mips/loongson/common/mem.c
@@ -26,7 +26,7 @@
 /* override of arch/mips/mm/cache.c: __uncached_access */
 int __uncached_access(struct file *file, unsigned long addr)
 {
-	if (file->f_flags & O_SYNC)
+	if (file->f_flags & O_DSYNC)
 		return 1;
 
 	return addr >= __pa(high_memory) ||
diff --git a/arch/mips/math-emu/dp_sub.c b/arch/mips/math-emu/dp_sub.c
index b30c5b1..a2127d6 100644
--- a/arch/mips/math-emu/dp_sub.c
+++ b/arch/mips/math-emu/dp_sub.c
@@ -110,7 +110,7 @@
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		DPDNORMX;
-		/* FAAL THOROUGH */
+		/* FALL THROUGH */
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
 		/* normalize ym,ye */
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 694d51f..102b2df 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -194,7 +194,7 @@
 
 int __weak __uncached_access(struct file *file, unsigned long addr)
 {
-	if (file->f_flags & O_SYNC)
+	if (file->f_flags & O_DSYNC)
 		return 1;
 
 	return addr >= __pa(high_memory);
diff --git a/arch/mips/txx9/generic/smsc_fdc37m81x.c b/arch/mips/txx9/generic/smsc_fdc37m81x.c
index a2b2d62..8ebc384 100644
--- a/arch/mips/txx9/generic/smsc_fdc37m81x.c
+++ b/arch/mips/txx9/generic/smsc_fdc37m81x.c
@@ -117,7 +117,7 @@
 	if (chip_id == SMSC_FDC37M81X_CHIP_ID)
 		smsc_fdc37m81x_config_end();
 	else {
-		printk(KERN_WARNING "%s: unknow chip id 0x%02x\n", __func__,
+		printk(KERN_WARNING "%s: unknown chip id 0x%02x\n", __func__,
 		       chip_id);
 		g_smsc_fdc37m81x_base = 0;
 	}
diff --git a/arch/mn10300/include/asm/mman.h b/arch/mn10300/include/asm/mman.h
index 8eebf89..db5c53da 100644
--- a/arch/mn10300/include/asm/mman.h
+++ b/arch/mn10300/include/asm/mman.h
@@ -1 +1,6 @@
 #include <asm-generic/mman.h>
+
+#define MIN_MAP_ADDR	PAGE_SIZE	/* minimum fixed mmap address */
+
+#define arch_mmap_check(addr, len, flags) \
+	(((flags) & MAP_FIXED && (addr) < MIN_MAP_ADDR) ? -EINVAL : 0)
diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S
index a94e7ea..c9ee6c0 100644
--- a/arch/mn10300/kernel/entry.S
+++ b/arch/mn10300/kernel/entry.S
@@ -578,7 +578,7 @@
 	.long sys_ni_syscall	/* reserved for streams2 */
 	.long sys_vfork		/* 190 */
 	.long sys_getrlimit
-	.long sys_mmap2
+	.long sys_mmap_pgoff
 	.long sys_truncate64
 	.long sys_ftruncate64
 	.long sys_stat64	/* 195 */
diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c
index 892cce8..ec8a21d 100644
--- a/arch/mn10300/kernel/process.c
+++ b/arch/mn10300/kernel/process.c
@@ -275,16 +275,12 @@
 	char *filename;
 	int error;
 
-	lock_kernel();
-
 	filename = getname(name);
 	error = PTR_ERR(filename);
-	if (!IS_ERR(filename)) {
-		error = do_execve(filename, argv, envp, __frame);
-		putname(filename);
-	}
-
-	unlock_kernel();
+	if (IS_ERR(filename))
+		return error;
+	error = do_execve(filename, argv, envp, __frame);
+	putname(filename);
 	return error;
 }
 
diff --git a/arch/mn10300/kernel/sys_mn10300.c b/arch/mn10300/kernel/sys_mn10300.c
index 8ca5af0..17cc6ce 100644
--- a/arch/mn10300/kernel/sys_mn10300.c
+++ b/arch/mn10300/kernel/sys_mn10300.c
@@ -23,47 +23,13 @@
 
 #include <asm/uaccess.h>
 
-#define MIN_MAP_ADDR	PAGE_SIZE	/* minimum fixed mmap address */
-
-/*
- * memory mapping syscall
- */
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-			  unsigned long prot, unsigned long flags,
-			  unsigned long fd, unsigned long pgoff)
-{
-	struct file *file = NULL;
-	long error = -EINVAL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	if (flags & MAP_FIXED && addr < MIN_MAP_ADDR)
-		goto out;
-
-	error = -EBADF;
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-
 asmlinkage long old_mmap(unsigned long addr, unsigned long len,
 			 unsigned long prot, unsigned long flags,
 			 unsigned long fd, unsigned long offset)
 {
 	if (offset & ~PAGE_MASK)
 		return -EINVAL;
-	return sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+	return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
 }
 
 struct sel_arg_struct {
diff --git a/arch/parisc/include/asm/fcntl.h b/arch/parisc/include/asm/fcntl.h
index 1e1c824..f357fc6 100644
--- a/arch/parisc/include/asm/fcntl.h
+++ b/arch/parisc/include/asm/fcntl.h
@@ -1,14 +1,13 @@
 #ifndef _PARISC_FCNTL_H
 #define _PARISC_FCNTL_H
 
-/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
-   located on an ext2 file system */
 #define O_APPEND	000000010
 #define O_BLKSEEK	000000100 /* HPUX only */
 #define O_CREAT		000000400 /* not fcntl */
 #define O_EXCL		000002000 /* not fcntl */
 #define O_LARGEFILE	000004000
-#define O_SYNC		000100000
+#define __O_SYNC	000100000
+#define O_SYNC		(__O_SYNC|O_DSYNC)
 #define O_NONBLOCK	000200004 /* HPUX has separate NDELAY & NONBLOCK */
 #define O_NOCTTY	000400000 /* not fcntl */
 #define O_DSYNC		001000000 /* HPUX only */
diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c
index 75099ef..f9f6783 100644
--- a/arch/parisc/kernel/perf.c
+++ b/arch/parisc/kernel/perf.c
@@ -24,7 +24,7 @@
  *
  *  This driver programs the PCX-U/PCX-W performance counters
  *  on the PA-RISC 2.0 chips.  The driver keeps all images now
- *  internally to the kernel to hopefully eliminate the possiblity
+ *  internally to the kernel to hopefully eliminate the possibility
  *  of a bad image halting the CPU.  Also, there are different
  *  images for the PCX-W and later chips vs the PCX-U chips.
  *
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index 71b3195..9147391 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -110,37 +110,14 @@
 	return addr;
 }
 
-static unsigned long do_mmap2(unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags, unsigned long fd,
-	unsigned long pgoff)
-{
-	struct file * file = NULL;
-	unsigned long error = -EBADF;
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file != NULL)
-		fput(file);
-out:
-	return error;
-}
-
 asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len,
 	unsigned long prot, unsigned long flags, unsigned long fd,
 	unsigned long pgoff)
 {
 	/* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE
 	   we have. */
-	return do_mmap2(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT - 12));
+	return sys_mmap_pgoff(addr, len, prot, flags, fd,
+			      pgoff >> (PAGE_SHIFT - 12));
 }
 
 asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
@@ -148,7 +125,8 @@
 		unsigned long offset)
 {
 	if (!(offset & ~PAGE_MASK)) {
-		return do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+		return sys_mmap_pgoff(addr, len, prot, flags, fd,
+					offset >> PAGE_SHIFT);
 	} else {
 		return -EINVAL;
 	}
diff --git a/arch/powerpc/include/asm/reg_fsl_emb.h b/arch/powerpc/include/asm/reg_fsl_emb.h
index 1e180a5..0de404d 100644
--- a/arch/powerpc/include/asm/reg_fsl_emb.h
+++ b/arch/powerpc/include/asm/reg_fsl_emb.h
@@ -39,7 +39,7 @@
 #define PMRN_PMLCB2	0x112	/* PM Local Control B2 */
 #define PMRN_PMLCB3	0x113	/* PM Local Control B3 */
 
-#define PMLCB_THRESHMUL_MASK	0x0700	/* Threshhold Multiple Field */
+#define PMLCB_THRESHMUL_MASK	0x0700	/* Threshold Multiple Field */
 #define PMLCB_THRESHMUL_SHIFT	8
 
 #define PMLCB_THRESHOLD_MASK	0x003f	/* Threshold Field */
diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c
index 641c74b..b6bd1ea 100644
--- a/arch/powerpc/kernel/kgdb.c
+++ b/arch/powerpc/kernel/kgdb.c
@@ -52,7 +52,7 @@
 	{ 0x2030, 0x08 /* SIGFPE */  },		/* spe fp data */
 	{ 0x2040, 0x08 /* SIGFPE */  },		/* spe fp data */
 	{ 0x2050, 0x08 /* SIGFPE */  },		/* spe fp round */
-	{ 0x2060, 0x0e /* SIGILL */  },		/* performace monitor */
+	{ 0x2060, 0x0e /* SIGILL */  },		/* performance monitor */
 	{ 0x2900, 0x08 /* SIGFPE */  },		/* apu unavailable */
 	{ 0x3100, 0x0e /* SIGALRM */ },		/* fixed interval timer */
 	{ 0x3200, 0x02 /* SIGINT */  }, 	/* watchdog */
diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
index c04832c..3370e62 100644
--- a/arch/powerpc/kernel/syscalls.c
+++ b/arch/powerpc/kernel/syscalls.c
@@ -140,7 +140,6 @@
 			unsigned long prot, unsigned long flags,
 			unsigned long fd, unsigned long off, int shift)
 {
-	struct file * file = NULL;
 	unsigned long ret = -EINVAL;
 
 	if (!arch_validate_prot(prot))
@@ -151,20 +150,8 @@
 			goto out;
 		off >>= shift;
 	}
-		
-	ret = -EBADF;
-	if (!(flags & MAP_ANONYMOUS)) {
-		if (!(file = fget(fd)))
-			goto out;
-	}
 
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	down_write(&current->mm->mmap_sem);
-	ret = do_mmap_pgoff(file, addr, len, prot, flags, off);
-	up_write(&current->mm->mmap_sem);
-	if (file)
-		fput(file);
+	ret = sys_mmap_pgoff(addr, len, prot, flags, fd, off);
 out:
 	return ret;
 }
diff --git a/arch/powerpc/kernel/tau_6xx.c b/arch/powerpc/kernel/tau_6xx.c
index c3a56d6..a753b72 100644
--- a/arch/powerpc/kernel/tau_6xx.c
+++ b/arch/powerpc/kernel/tau_6xx.c
@@ -59,7 +59,7 @@
 	mtspr(SPRN_THRM1, THRM1_THRES(tau[cpu].low) | THRM1_V | THRM1_TIE | THRM1_TID);
 
 	/* setup THRM2,
-	 * threshold, valid bit, enable interrupts, interrupt when above threshhold
+	 * threshold, valid bit, enable interrupts, interrupt when above threshold
 	 */
 	mtspr (SPRN_THRM2, THRM1_THRES(tau[cpu].high) | THRM1_V | THRM1_TIE);
 #else
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 36707de..674800b 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -834,7 +834,8 @@
 	return (cycle_t)get_tb();
 }
 
-void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
+void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
+		     u32 mult)
 {
 	u64 t2x, stamp_xsec;
 
@@ -847,7 +848,7 @@
 
 	/* XXX this assumes clock->shift == 22 */
 	/* 4611686018 ~= 2^(20+64-22) / 1e9 */
-	t2x = (u64) clock->mult * 4611686018ULL;
+	t2x = (u64) mult * 4611686018ULL;
 	stamp_xsec = (u64) xtime.tv_nsec * XSEC_PER_SEC;
 	do_div(stamp_xsec, 1000000000);
 	stamp_xsec += (u64) xtime.tv_sec * XSEC_PER_SEC;
@@ -924,7 +925,7 @@
 	*dec = decrementer_clockevent;
 	dec->cpumask = cpumask_of(cpu);
 
-	printk(KERN_DEBUG "clockevent: %s mult[%lx] shift[%d] cpu[%d]\n",
+	printk(KERN_DEBUG "clockevent: %s mult[%x] shift[%d] cpu[%d]\n",
 	       dec->name, dec->mult, dec->shift, cpu);
 
 	clockevents_register_device(dec);
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index 137dc22..d84d192 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -721,7 +721,7 @@
 
 #ifdef CONFIG_PPC64
 	/*
-	 * Fill up the "systemcfg" stuff for backward compatiblity
+	 * Fill up the "systemcfg" stuff for backward compatibility
 	 */
 	strcpy((char *)vdso_data->eye_catcher, "SYSTEMCFG:PPC64");
 	vdso_data->version.major = SYSTEMCFG_MAJOR;
diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c
index ae06c62..2c9e522 100644
--- a/arch/powerpc/oprofile/op_model_cell.c
+++ b/arch/powerpc/oprofile/op_model_cell.c
@@ -248,7 +248,7 @@
 	 * There is no debug setup required for the cycles event.
 	 * Note that only events in the same group can be used.
 	 * Otherwise, there will be conflicts in correctly routing
-	 * the signals on the debug bus.  It is the responsiblity
+	 * the signals on the debug bus.  It is the responsibility
 	 * of the OProfile user tool to check the events are in
 	 * the same group.
 	 */
@@ -1594,7 +1594,7 @@
 		 * to a latch.  The new values (interrupt setting bits, reset
 		 * counter value etc.) are not copied to the actual registers
 		 * until the performance monitor is enabled.  In order to get
-		 * this to work as desired, the permormance monitor needs to
+		 * this to work as desired, the performance monitor needs to
 		 * be disabled while writing to the latches.  This is a
 		 * HW design issue.
 		 */
@@ -1668,7 +1668,7 @@
 		 * to a latch.	The new values (interrupt setting bits, reset
 		 * counter value etc.) are not copied to the actual registers
 		 * until the performance monitor is enabled.  In order to get
-		 * this to work as desired, the permormance monitor needs to
+		 * this to work as desired, the performance monitor needs to
 		 * be disabled while writing to the latches.  This is a
 		 * HW design issue.
 		 */
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
index dd43114..da110bd 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
@@ -100,7 +100,7 @@
 };
 
 /* ======================================================================== */
-/* PCI configuration acess                                                  */
+/* PCI configuration access                                                 */
 /* ======================================================================== */
 
 static int
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index e81403b..ab2027c 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -302,7 +302,7 @@
  *  1 -> Skip the device but act as if the access was successfull
  *       (return 0xff's on reads, eventually, cache config space
  *       accesses in a later version)
- * -1 -> Hide the device (unsuccessful acess)
+ * -1 -> Hide the device (unsuccessful access)
  */
 static int u3_ht_skip_device(struct pci_controller *hose,
 			     struct pci_bus *bus, unsigned int devfn)
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index ae3c4db..bafc3f8 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -160,7 +160,7 @@
 
 	dp = ((unsigned int*)tbl->it_base) + index;
 
-	/* On U3, all memory is contigous, so we can move this
+	/* On U3, all memory is contiguous, so we can move this
 	 * out of the loop.
 	 */
 	l = npages;
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 16c6730..c802352 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -220,23 +220,8 @@
 	bool
 	default y
 
-config S390_SWITCH_AMODE
-	bool "Switch kernel/user addressing modes"
-	help
-	  This option allows to switch the addressing modes of kernel and user
-	  space. The kernel parameter switch_amode=on will enable this feature,
-	  default is disabled. Enabling this (via kernel parameter) on machines
-	  earlier than IBM System z9-109 EC/BC will reduce system performance.
-
-	  Note that this option will also be selected by selecting the execute
-	  protection option below. Enabling the execute protection via the
-	  noexec kernel parameter will also switch the addressing modes,
-	  independent of the switch_amode kernel parameter.
-
-
 config S390_EXEC_PROTECT
 	bool "Data execute protection"
-	select S390_SWITCH_AMODE
 	help
 	  This option allows to enable a buffer overflow protection for user
 	  space programs and it also selects the addressing mode option above.
diff --git a/arch/s390/crypto/prng.c b/arch/s390/crypto/prng.c
index b49c00c..a320990 100644
--- a/arch/s390/crypto/prng.c
+++ b/arch/s390/crypto/prng.c
@@ -6,7 +6,6 @@
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/smp_lock.h>
 #include <linux/miscdevice.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -49,7 +48,6 @@
 
 static int prng_open(struct inode *inode, struct file *file)
 {
-	cycle_kernel_lock();
 	return nonseekable_open(inode, file);
 }
 
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index ab44644..f4e53c6 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -185,7 +185,6 @@
 CONFIG_COMPAT=y
 CONFIG_SYSVIPC_COMPAT=y
 CONFIG_AUDIT_ARCH=y
-CONFIG_S390_SWITCH_AMODE=y
 CONFIG_S390_EXEC_PROTECT=y
 
 #
diff --git a/arch/s390/include/asm/atomic.h b/arch/s390/include/asm/atomic.h
index ae7c8f9..2a113d6 100644
--- a/arch/s390/include/asm/atomic.h
+++ b/arch/s390/include/asm/atomic.h
@@ -21,7 +21,7 @@
 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
 
 #define __CS_LOOP(ptr, op_val, op_string) ({				\
-	typeof(ptr->counter) old_val, new_val;				\
+	int old_val, new_val;						\
 	asm volatile(							\
 		"	l	%0,%2\n"				\
 		"0:	lr	%1,%0\n"				\
@@ -38,7 +38,7 @@
 #else /* __GNUC__ */
 
 #define __CS_LOOP(ptr, op_val, op_string) ({				\
-	typeof(ptr->counter) old_val, new_val;				\
+	int old_val, new_val;						\
 	asm volatile(							\
 		"	l	%0,0(%3)\n"				\
 		"0:	lr	%1,%0\n"				\
@@ -143,7 +143,7 @@
 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
 
 #define __CSG_LOOP(ptr, op_val, op_string) ({				\
-	typeof(ptr->counter) old_val, new_val;				\
+	long long old_val, new_val;					\
 	asm volatile(							\
 		"	lg	%0,%2\n"				\
 		"0:	lgr	%1,%0\n"				\
@@ -160,7 +160,7 @@
 #else /* __GNUC__ */
 
 #define __CSG_LOOP(ptr, op_val, op_string) ({				\
-	typeof(ptr->counter) old_val, new_val;				\
+	long long old_val, new_val;					\
 	asm volatile(							\
 		"	lg	%0,0(%3)\n"				\
 		"0:	lgr	%1,%0\n"				\
diff --git a/arch/s390/include/asm/ccwdev.h b/arch/s390/include/asm/ccwdev.h
index 2a54195..f4bd346 100644
--- a/arch/s390/include/asm/ccwdev.h
+++ b/arch/s390/include/asm/ccwdev.h
@@ -142,6 +142,8 @@
 extern int ccw_device_set_options_mask(struct ccw_device *, unsigned long);
 extern int ccw_device_set_options(struct ccw_device *, unsigned long);
 extern void ccw_device_clear_options(struct ccw_device *, unsigned long);
+int ccw_device_is_pathgroup(struct ccw_device *cdev);
+int ccw_device_is_multipath(struct ccw_device *cdev);
 
 /* Allow for i/o completion notification after primary interrupt status. */
 #define CCWDEV_EARLY_NOTIFICATION	0x0001
@@ -151,6 +153,8 @@
 #define CCWDEV_DO_PATHGROUP             0x0004
 /* Allow forced onlining of boxed devices. */
 #define CCWDEV_ALLOW_FORCE              0x0008
+/* Try to use multipath mode. */
+#define CCWDEV_DO_MULTIPATH		0x0010
 
 extern int ccw_device_start(struct ccw_device *, struct ccw1 *,
 			    unsigned long, __u8, unsigned long);
diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h
index f23961a..258ba88 100644
--- a/arch/s390/include/asm/cputime.h
+++ b/arch/s390/include/asm/cputime.h
@@ -183,6 +183,7 @@
 	unsigned long long idle_count;
 	unsigned long long idle_enter;
 	unsigned long long idle_time;
+	int nohz_delay;
 };
 
 DECLARE_PER_CPU(struct s390_idle_data, s390_idle);
@@ -198,4 +199,11 @@
 		vtime_start_cpu();
 }
 
+static inline int s390_nohz_delay(int cpu)
+{
+	return per_cpu(s390_idle, cpu).nohz_delay != 0;
+}
+
+#define arch_needs_cpu(cpu) s390_nohz_delay(cpu)
+
 #endif /* _S390_CPUTIME_H */
diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h
index fc7edd6..976e273 100644
--- a/arch/s390/include/asm/mmu_context.h
+++ b/arch/s390/include/asm/mmu_context.h
@@ -36,7 +36,7 @@
 		mm->context.has_pgste = 1;
 		mm->context.alloc_pgste = 1;
 	} else {
-		mm->context.noexec = s390_noexec;
+		mm->context.noexec = (user_mode == SECONDARY_SPACE_MODE);
 		mm->context.has_pgste = 0;
 		mm->context.alloc_pgste = 0;
 	}
@@ -58,7 +58,7 @@
 	pgd_t *pgd = mm->pgd;
 
 	S390_lowcore.user_asce = mm->context.asce_bits | __pa(pgd);
-	if (switch_amode) {
+	if (user_mode != HOME_SPACE_MODE) {
 		/* Load primary space page table origin. */
 		pgd = mm->context.noexec ? get_shadow_table(pgd) : pgd;
 		S390_lowcore.user_exec_asce = mm->context.asce_bits | __pa(pgd);
diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h
index ddad590..68940d0 100644
--- a/arch/s390/include/asm/pgalloc.h
+++ b/arch/s390/include/asm/pgalloc.h
@@ -143,7 +143,8 @@
 	spin_lock_init(&mm->context.list_lock);
 	INIT_LIST_HEAD(&mm->context.crst_list);
 	INIT_LIST_HEAD(&mm->context.pgtable_list);
-	return (pgd_t *) crst_table_alloc(mm, s390_noexec);
+	return (pgd_t *)
+		crst_table_alloc(mm, user_mode == SECONDARY_SPACE_MODE);
 }
 #define pgd_free(mm, pgd) crst_table_free(mm, (unsigned long *) pgd)
 
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index 60a7b1a..e2fa79c 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -169,12 +169,13 @@
  * STL Segment-Table-Length:  Segment-table length (STL+1*16 entries -> up to 2048)
  *
  * A 64 bit pagetable entry of S390 has following format:
- * |                     PFRA                         |0IP0|  OS  |
+ * |			 PFRA			      |0IPC|  OS  |
  * 0000000000111111111122222222223333333333444444444455555555556666
  * 0123456789012345678901234567890123456789012345678901234567890123
  *
  * I Page-Invalid Bit:    Page is not available for address-translation
  * P Page-Protection Bit: Store access not possible for page
+ * C Change-bit override: HW is not required to set change bit
  *
  * A 64 bit segmenttable entry of S390 has following format:
  * |        P-table origin                              |      TT
@@ -218,6 +219,7 @@
  */
 
 /* Hardware bits in the page table entry */
+#define _PAGE_CO	0x100		/* HW Change-bit override */
 #define _PAGE_RO	0x200		/* HW read-only bit  */
 #define _PAGE_INVALID	0x400		/* HW invalid bit    */
 
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h
index e37478e..52a779c 100644
--- a/arch/s390/include/asm/setup.h
+++ b/arch/s390/include/asm/setup.h
@@ -49,17 +49,12 @@
 
 void detect_memory_layout(struct mem_chunk chunk[]);
 
-#ifdef CONFIG_S390_SWITCH_AMODE
-extern unsigned int switch_amode;
-#else
-#define switch_amode	(0)
-#endif
+#define PRIMARY_SPACE_MODE	0
+#define ACCESS_REGISTER_MODE	1
+#define SECONDARY_SPACE_MODE	2
+#define HOME_SPACE_MODE		3
 
-#ifdef CONFIG_S390_EXEC_PROTECT
-extern unsigned int s390_noexec;
-#else
-#define s390_noexec	(0)
-#endif
+extern unsigned int user_mode;
 
 /*
  * Machine features detected in head.S
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h
index a868b27..2ab1141 100644
--- a/arch/s390/include/asm/smp.h
+++ b/arch/s390/include/asm/smp.h
@@ -1,57 +1,22 @@
 /*
- *  include/asm-s390/smp.h
- *
- *  S390 version
- *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
- *               Martin Schwidefsky (schwidefsky@de.ibm.com)
- *               Heiko Carstens (heiko.carstens@de.ibm.com)
+ *    Copyright IBM Corp. 1999,2009
+ *    Author(s): Denis Joseph Barrow,
+ *		 Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ *		 Heiko Carstens <heiko.carstens@de.ibm.com>,
  */
 #ifndef __ASM_SMP_H
 #define __ASM_SMP_H
 
-#include <linux/threads.h>
-#include <linux/cpumask.h>
-#include <linux/bitops.h>
+#ifdef CONFIG_SMP
 
-#if defined(__KERNEL__) && defined(CONFIG_SMP) && !defined(__ASSEMBLY__)
-
-#include <asm/lowcore.h>
-#include <asm/sigp.h>
-#include <asm/ptrace.h>
 #include <asm/system.h>
-
-/*
-  s390 specific smp.c headers
- */
-typedef struct
-{
-	int        intresting;
-	sigp_ccode ccode; 
-	__u32      status;
-	__u16      cpu;
-} sigp_info;
+#include <asm/sigp.h>
 
 extern void machine_restart_smp(char *);
 extern void machine_halt_smp(void);
 extern void machine_power_off_smp(void);
 
-#define NO_PROC_ID		0xFF		/* No processor magic marker */
-
-/*
- *	This magic constant controls our willingness to transfer
- *	a process across CPUs. Such a transfer incurs misses on the L1
- *	cache, and on a P6 or P5 with multiple L2 caches L2 hits. My
- *	gut feeling is this will vary by board in value. For a board
- *	with separate L2 cache it probably depends also on the RSS, and
- *	for a board with shared L2 cache it ought to decay fast as other
- *	processes are run.
- */
- 
-#define PROC_CHANGE_PENALTY	20		/* Schedule penalty */
-
 #define raw_smp_processor_id()	(S390_lowcore.cpu_nr)
-#define cpu_logical_map(cpu)	(cpu)
 
 extern int __cpu_disable (void);
 extern void __cpu_die (unsigned int cpu);
@@ -64,7 +29,9 @@
 extern void arch_send_call_function_single_ipi(int cpu);
 extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
 
-#endif
+extern union save_area *zfcpdump_save_areas[NR_CPUS + 1];
+
+#endif /* CONFIG_SMP */
 
 #ifdef CONFIG_HOTPLUG_CPU
 extern int smp_rescan_cpus(void);
@@ -72,5 +39,4 @@
 static inline int smp_rescan_cpus(void) { return 0; }
 #endif
 
-extern union save_area *zfcpdump_save_areas[NR_CPUS + 1];
-#endif
+#endif /* __ASM_SMP_H */
diff --git a/arch/s390/include/asm/sockios.h b/arch/s390/include/asm/sockios.h
index f4fc16c..6f60eee 100644
--- a/arch/s390/include/asm/sockios.h
+++ b/arch/s390/include/asm/sockios.h
@@ -1,21 +1,6 @@
-/*
- *  include/asm-s390/sockios.h
- *
- *  S390 version
- *
- *  Derived from "include/asm-i386/sockios.h"
- */
+#ifndef _ASM_S390_SOCKIOS_H
+#define _ASM_S390_SOCKIOS_H
 
-#ifndef __ARCH_S390_SOCKIOS__
-#define __ARCH_S390_SOCKIOS__
-
-/* Socket-level I/O control calls. */
-#define FIOSETOWN 	0x8901
-#define SIOCSPGRP	0x8902
-#define FIOGETOWN	0x8903
-#define SIOCGPGRP	0x8904
-#define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
-#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
+#include <asm-generic/sockios.h>
 
 #endif
diff --git a/arch/s390/include/asm/termbits.h b/arch/s390/include/asm/termbits.h
index 58731853..71bf6ac 100644
--- a/arch/s390/include/asm/termbits.h
+++ b/arch/s390/include/asm/termbits.h
@@ -1,206 +1,6 @@
-/*
- *  include/asm-s390/termbits.h
- *
- *  S390 version
- *
- *  Derived from "include/asm-i386/termbits.h"
- */
+#ifndef _ASM_S390_TERMBITS_H
+#define _ASM_S390_TERMBITS_H
 
-#ifndef __ARCH_S390_TERMBITS_H__
-#define __ARCH_S390_TERMBITS_H__
-
-#include <linux/posix_types.h>
-
-typedef unsigned char	cc_t;
-typedef unsigned int	speed_t;
-typedef unsigned int	tcflag_t;
-
-#define NCCS 19
-struct termios {
-	tcflag_t c_iflag;		/* input mode flags */
-	tcflag_t c_oflag;		/* output mode flags */
-	tcflag_t c_cflag;		/* control mode flags */
-	tcflag_t c_lflag;		/* local mode flags */
-	cc_t c_line;			/* line discipline */
-	cc_t c_cc[NCCS];		/* control characters */
-};
-
-struct termios2 {
-	tcflag_t c_iflag;		/* input mode flags */
-	tcflag_t c_oflag;		/* output mode flags */
-	tcflag_t c_cflag;		/* control mode flags */
-	tcflag_t c_lflag;		/* local mode flags */
-	cc_t c_line;			/* line discipline */
-	cc_t c_cc[NCCS];		/* control characters */
-	speed_t c_ispeed;		/* input speed */
-	speed_t c_ospeed;		/* output speed */
-};
-
-struct ktermios {
-	tcflag_t c_iflag;		/* input mode flags */
-	tcflag_t c_oflag;		/* output mode flags */
-	tcflag_t c_cflag;		/* control mode flags */
-	tcflag_t c_lflag;		/* local mode flags */
-	cc_t c_line;			/* line discipline */
-	cc_t c_cc[NCCS];		/* control characters */
-	speed_t c_ispeed;		/* input speed */
-	speed_t c_ospeed;		/* output speed */
-};
-
-/* c_cc characters */
-#define VINTR 0
-#define VQUIT 1
-#define VERASE 2
-#define VKILL 3
-#define VEOF 4
-#define VTIME 5
-#define VMIN 6
-#define VSWTC 7
-#define VSTART 8
-#define VSTOP 9
-#define VSUSP 10
-#define VEOL 11
-#define VREPRINT 12
-#define VDISCARD 13
-#define VWERASE 14
-#define VLNEXT 15
-#define VEOL2 16
-
-/* c_iflag bits */
-#define IGNBRK	0000001
-#define BRKINT	0000002
-#define IGNPAR	0000004
-#define PARMRK	0000010
-#define INPCK	0000020
-#define ISTRIP	0000040
-#define INLCR	0000100
-#define IGNCR	0000200
-#define ICRNL	0000400
-#define IUCLC	0001000
-#define IXON	0002000
-#define IXANY	0004000
-#define IXOFF	0010000
-#define IMAXBEL	0020000
-#define IUTF8	0040000
-
-/* c_oflag bits */
-#define OPOST	0000001
-#define OLCUC	0000002
-#define ONLCR	0000004
-#define OCRNL	0000010
-#define ONOCR	0000020
-#define ONLRET	0000040
-#define OFILL	0000100
-#define OFDEL	0000200
-#define NLDLY	0000400
-#define   NL0	0000000
-#define   NL1	0000400
-#define CRDLY	0003000
-#define   CR0	0000000
-#define   CR1	0001000
-#define   CR2	0002000
-#define   CR3	0003000
-#define TABDLY	0014000
-#define   TAB0	0000000
-#define   TAB1	0004000
-#define   TAB2	0010000
-#define   TAB3	0014000
-#define   XTABS	0014000
-#define BSDLY	0020000
-#define   BS0	0000000
-#define   BS1	0020000
-#define VTDLY	0040000
-#define   VT0	0000000
-#define   VT1	0040000
-#define FFDLY	0100000
-#define   FF0	0000000
-#define   FF1	0100000
-
-/* c_cflag bit meaning */
-#define CBAUD	0010017
-#define  B0	0000000		/* hang up */
-#define  B50	0000001
-#define  B75	0000002
-#define  B110	0000003
-#define  B134	0000004
-#define  B150	0000005
-#define  B200	0000006
-#define  B300	0000007
-#define  B600	0000010
-#define  B1200	0000011
-#define  B1800	0000012
-#define  B2400	0000013
-#define  B4800	0000014
-#define  B9600	0000015
-#define  B19200	0000016
-#define  B38400	0000017
-#define EXTA B19200
-#define EXTB B38400
-#define CSIZE	0000060
-#define   CS5	0000000
-#define   CS6	0000020
-#define   CS7	0000040
-#define   CS8	0000060
-#define CSTOPB	0000100
-#define CREAD	0000200
-#define PARENB	0000400
-#define PARODD	0001000
-#define HUPCL	0002000
-#define CLOCAL	0004000
-#define CBAUDEX 0010000
-#define  BOTHER  0010000
-#define  B57600  0010001
-#define  B115200 0010002
-#define  B230400 0010003
-#define  B460800 0010004
-#define   B500000 0010005
-#define   B576000 0010006
-#define   B921600 0010007
-#define  B1000000 0010010
-#define  B1152000 0010011
-#define  B1500000 0010012
-#define  B2000000 0010013
-#define  B2500000 0010014
-#define  B3000000 0010015
-#define  B3500000 0010016
-#define  B4000000 0010017
-#define CIBAUD	  002003600000	/* input baud rate */
-#define CMSPAR	  010000000000		/* mark or space (stick) parity */
-#define CRTSCTS	  020000000000		/* flow control */
-
-#define IBSHIFT	  16		/* Shift from CBAUD to CIBAUD */
-
-/* c_lflag bits */
-#define ISIG	0000001
-#define ICANON	0000002
-#define XCASE	0000004
-#define ECHO	0000010
-#define ECHOE	0000020
-#define ECHOK	0000040
-#define ECHONL	0000100
-#define NOFLSH	0000200
-#define TOSTOP	0000400
-#define ECHOCTL	0001000
-#define ECHOPRT	0002000
-#define ECHOKE	0004000
-#define FLUSHO	0010000
-#define PENDIN	0040000
-#define IEXTEN	0100000
-
-/* tcflow() and TCXONC use these */
-#define	TCOOFF		0
-#define	TCOON		1
-#define	TCIOFF		2
-#define	TCION		3
-
-/* tcflush() and TCFLSH use these */
-#define	TCIFLUSH	0
-#define	TCOFLUSH	1
-#define	TCIOFLUSH	2
-
-/* tcsetattr uses these */
-#define	TCSANOW		0
-#define	TCSADRAIN	1
-#define	TCSAFLUSH	2
+#include <asm-generic/termbits.h>
 
 #endif
diff --git a/arch/s390/include/asm/todclk.h b/arch/s390/include/asm/todclk.h
deleted file mode 100644
index c7f6205..0000000
--- a/arch/s390/include/asm/todclk.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * File...........: linux/include/asm/todclk.h
- * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
- * Bugreports.to..: <Linux390@de.ibm.com>
- * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
- *
- * History of changes (starts July 2000)
- */
-
-#ifndef __ASM_TODCLK_H
-#define __ASM_TODCLK_H
-
-#ifdef __KERNEL__
-
-#define TOD_uSEC (0x1000ULL)
-#define TOD_mSEC (1000 * TOD_uSEC)
-#define TOD_SEC (1000 * TOD_mSEC)
-#define TOD_MIN (60 * TOD_SEC)
-#define TOD_HOUR (60 * TOD_MIN)
-
-#endif
-
-#endif
diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h
index 8377e91..cbf0a87 100644
--- a/arch/s390/include/asm/uaccess.h
+++ b/arch/s390/include/asm/uaccess.h
@@ -93,6 +93,8 @@
 extern struct uaccess_ops uaccess_mvcos_switch;
 extern struct uaccess_ops uaccess_pt;
 
+extern int __handle_fault(unsigned long, unsigned long, int);
+
 static inline int __put_user_fn(size_t size, void __user *ptr, void *x)
 {
 	size = uaccess.copy_to_user_small(size, ptr, x);
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index c7be8e1..683f638 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -44,6 +44,7 @@
 obj-$(CONFIG_FUNCTION_TRACER)	+= $(if $(CONFIG_64BIT),mcount64.o,mcount.o)
 obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
+obj-$(CONFIG_FTRACE_SYSCALLS)  += ftrace.o
 
 # Kexec part
 S390_KEXEC_OBJS := machine_kexec.o crash.o
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index fda1a81..22c9e55 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -31,14 +31,8 @@
 #include <linux/shm.h>
 #include <linux/slab.h>
 #include <linux/uio.h>
-#include <linux/nfs_fs.h>
 #include <linux/quota.h>
 #include <linux/module.h>
-#include <linux/sunrpc/svc.h>
-#include <linux/nfsd/nfsd.h>
-#include <linux/nfsd/cache.h>
-#include <linux/nfsd/xdr.h>
-#include <linux/nfsd/syscall.h>
 #include <linux/poll.h>
 #include <linux/personality.h>
 #include <linux/stat.h>
@@ -630,38 +624,6 @@
 	u32	offset;
 };
 
-/* common code for old and new mmaps */
-static inline long do_mmap2(
-	unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags,
-	unsigned long fd, unsigned long pgoff)
-{
-	struct file * file = NULL;
-	unsigned long error = -EBADF;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	if (!IS_ERR((void *) error) && error + len >= 0x80000000ULL) {
-		/* Result is out of bounds.  */
-		do_munmap(current->mm, addr, len);
-		error = -ENOMEM;
-	}
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:    
-	return error;
-}
-
-
 asmlinkage unsigned long
 old32_mmap(struct mmap_arg_struct_emu31 __user *arg)
 {
@@ -675,7 +637,8 @@
 	if (a.offset & ~PAGE_MASK)
 		goto out;
 
-	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); 
+	error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
+			       a.offset >> PAGE_SHIFT);
 out:
 	return error;
 }
@@ -688,7 +651,7 @@
 
 	if (copy_from_user(&a, arg, sizeof(a)))
 		goto out;
-	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
+	error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
 out:
 	return error;
 }
diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h
index 45e9092..cb97afc 100644
--- a/arch/s390/kernel/compat_linux.h
+++ b/arch/s390/kernel/compat_linux.h
@@ -4,10 +4,6 @@
 #include <linux/compat.h>
 #include <linux/socket.h>
 #include <linux/syscalls.h>
-#include <linux/nfs_fs.h>
-#include <linux/sunrpc/svc.h>
-#include <linux/nfsd/nfsd.h>
-#include <linux/nfsd/export.h>
 
 /* Macro that masks the high order bit of an 32 bit pointer and converts it*/
 /*       to a 64 bit pointer */
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index 6a25080..d984a2a 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -83,6 +83,8 @@
 	slr	%r0,%r0 		# set cpuid to zero
 	sigp	%r1,%r0,0x12		# switch to esame mode
 	sam64				# switch to 64 bit mode
+	llgfr	%r13,%r13		# clear high-order half of base reg
+	lmh	%r0,%r15,.Lzero64-.LPG1(%r13)	# clear high-order half
 	lctlg	%c0,%c15,.Lctl-.LPG1(%r13)	# load control registers
 	lg	%r12,.Lparmaddr-.LPG1(%r13)	# pointer to parameter area
 					# move IPL device to lowcore
@@ -127,6 +129,7 @@
 .L4malign:.quad 0xffffffffffc00000
 .Lscan2g:.quad	0x80000000 + 0x20000 - 8	# 2GB + 128K - 8
 .Lnop:	.long	0x07000700
+.Lzero64:.fill	16,4,0x0
 #ifdef CONFIG_ZFCPDUMP
 .Lcurrent_cpu:
 	.long 0x0
diff --git a/arch/s390/kernel/s390_ext.c b/arch/s390/kernel/s390_ext.c
index 0de305b..59618bc 100644
--- a/arch/s390/kernel/s390_ext.c
+++ b/arch/s390/kernel/s390_ext.c
@@ -126,6 +126,8 @@
 		/* Serve timer interrupts first. */
 		clock_comparator_work();
 	kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
+	if (code != 0x1004)
+		__get_cpu_var(s390_idle).nohz_delay = 1;
         index = ext_hash(code);
 	for (p = ext_int_hash[index]; p; p = p->next) {
 		if (likely(p->code == code))
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 061479f..0663287 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -305,9 +305,8 @@
 }
 early_param("mem", early_parse_mem);
 
-#ifdef CONFIG_S390_SWITCH_AMODE
-unsigned int switch_amode = 0;
-EXPORT_SYMBOL_GPL(switch_amode);
+unsigned int user_mode = HOME_SPACE_MODE;
+EXPORT_SYMBOL_GPL(user_mode);
 
 static int set_amode_and_uaccess(unsigned long user_amode,
 				 unsigned long user32_amode)
@@ -340,23 +339,29 @@
  */
 static int __init early_parse_switch_amode(char *p)
 {
-	switch_amode = 1;
+	if (user_mode != SECONDARY_SPACE_MODE)
+		user_mode = PRIMARY_SPACE_MODE;
 	return 0;
 }
 early_param("switch_amode", early_parse_switch_amode);
 
-#else /* CONFIG_S390_SWITCH_AMODE */
-static inline int set_amode_and_uaccess(unsigned long user_amode,
-					unsigned long user32_amode)
+static int __init early_parse_user_mode(char *p)
 {
+	if (p && strcmp(p, "primary") == 0)
+		user_mode = PRIMARY_SPACE_MODE;
+#ifdef CONFIG_S390_EXEC_PROTECT
+	else if (p && strcmp(p, "secondary") == 0)
+		user_mode = SECONDARY_SPACE_MODE;
+#endif
+	else if (!p || strcmp(p, "home") == 0)
+		user_mode = HOME_SPACE_MODE;
+	else
+		return 1;
 	return 0;
 }
-#endif /* CONFIG_S390_SWITCH_AMODE */
+early_param("user_mode", early_parse_user_mode);
 
 #ifdef CONFIG_S390_EXEC_PROTECT
-unsigned int s390_noexec = 0;
-EXPORT_SYMBOL_GPL(s390_noexec);
-
 /*
  * Enable execute protection?
  */
@@ -364,8 +369,7 @@
 {
 	if (!strncmp(p, "off", 3))
 		return 0;
-	switch_amode = 1;
-	s390_noexec = 1;
+	user_mode = SECONDARY_SPACE_MODE;
 	return 0;
 }
 early_param("noexec", early_parse_noexec);
@@ -373,7 +377,7 @@
 
 static void setup_addressing_mode(void)
 {
-	if (s390_noexec) {
+	if (user_mode == SECONDARY_SPACE_MODE) {
 		if (set_amode_and_uaccess(PSW_ASC_SECONDARY,
 					  PSW32_ASC_SECONDARY))
 			pr_info("Execute protection active, "
@@ -381,7 +385,7 @@
 		else
 			pr_info("Execute protection active, "
 				"mvcos not available\n");
-	} else if (switch_amode) {
+	} else if (user_mode == PRIMARY_SPACE_MODE) {
 		if (set_amode_and_uaccess(PSW_ASC_PRIMARY, PSW32_ASC_PRIMARY))
 			pr_info("Address spaces switched, "
 				"mvcos available\n");
@@ -411,7 +415,7 @@
 	lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
 	lc->restart_psw.addr =
 		PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
-	if (switch_amode)
+	if (user_mode != HOME_SPACE_MODE)
 		lc->restart_psw.mask |= PSW_ASC_HOME;
 	lc->external_new_psw.mask = psw_kernel_bits;
 	lc->external_new_psw.addr =
diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c
index e9d94f6..86a74c9 100644
--- a/arch/s390/kernel/sys_s390.c
+++ b/arch/s390/kernel/sys_s390.c
@@ -32,32 +32,6 @@
 #include <asm/uaccess.h>
 #include "entry.h"
 
-/* common code for old and new mmaps */
-static inline long do_mmap2(
-	unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags,
-	unsigned long fd, unsigned long pgoff)
-{
-	long error = -EBADF;
-	struct file * file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-
 /*
  * Perform the select(nd, in, out, ex, tv) and mmap() system
  * calls. Linux for S/390 isn't able to handle more than 5
@@ -81,7 +55,7 @@
 
 	if (copy_from_user(&a, arg, sizeof(a)))
 		goto out;
-	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
+	error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
 out:
 	return error;
 }
@@ -98,7 +72,7 @@
 	if (a.offset & ~PAGE_MASK)
 		goto out;
 
-	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+	error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
 out:
 	return error;
 }
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 34162a0..65065ac 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -214,7 +214,8 @@
 	return &clocksource_tod;
 }
 
-void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
+void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
+		     u32 mult)
 {
 	if (clock != &clocksource_tod)
 		return;
@@ -334,7 +335,7 @@
 	sw0 = atomic_read(sw_ptr);
 	*clock = get_clock();
 	sw1 = atomic_read(sw_ptr);
-	put_cpu_var(clock_sync_sync);
+	put_cpu_var(clock_sync_word);
 	if (sw0 == sw1 && (sw0 & 0x80000000U))
 		/* Success: time is in sync. */
 		return 0;
@@ -384,7 +385,7 @@
 
 	sw_ptr = &get_cpu_var(clock_sync_word);
 	rc = (atomic_read(sw_ptr) & 0x80000000U) != 0;
-	put_cpu_var(clock_sync_sync);
+	put_cpu_var(clock_sync_word);
 	return rc;
 }
 
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c
index adfb32a..5f99e66 100644
--- a/arch/s390/kernel/vdso.c
+++ b/arch/s390/kernel/vdso.c
@@ -86,7 +86,8 @@
 	unsigned int facility_list;
 
 	facility_list = stfl();
-	vd->ectg_available = switch_amode && (facility_list & 1);
+	vd->ectg_available =
+		user_mode != HOME_SPACE_MODE && (facility_list & 1);
 }
 
 #ifdef CONFIG_64BIT
@@ -114,7 +115,7 @@
 
 	lowcore->vdso_per_cpu_data = __LC_PASTE;
 
-	if (!switch_amode || !vdso_enabled)
+	if (user_mode == HOME_SPACE_MODE || !vdso_enabled)
 		return 0;
 
 	segment_table = __get_free_pages(GFP_KERNEL, SEGMENT_ORDER);
@@ -160,7 +161,7 @@
 	unsigned long segment_table, page_table, page_frame;
 	u32 *psal, *aste;
 
-	if (!switch_amode || !vdso_enabled)
+	if (user_mode == HOME_SPACE_MODE || !vdso_enabled)
 		return;
 
 	psal = (u32 *)(addr_t) lowcore->paste[4];
@@ -184,7 +185,7 @@
 
 static void vdso_init_cr5(void)
 {
-	if (switch_amode && vdso_enabled)
+	if (user_mode != HOME_SPACE_MODE && vdso_enabled)
 		on_each_cpu(__vdso_init_cr5, NULL, 1);
 }
 #endif /* CONFIG_64BIT */
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index c41bb0d..b59a812 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -167,6 +167,8 @@
 	/* Wait for external, I/O or machine check interrupt. */
 	psw.mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_IO | PSW_MASK_EXT;
 
+	idle->nohz_delay = 0;
+
 	/* Check if the CPU timer needs to be reprogrammed. */
 	if (vq->do_spt) {
 		__u64 vmax = VTIMER_MAX_SLICE;
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig
index bf164fc..6ee55ae 100644
--- a/arch/s390/kvm/Kconfig
+++ b/arch/s390/kvm/Kconfig
@@ -20,7 +20,6 @@
 	depends on HAVE_KVM && EXPERIMENTAL
 	select PREEMPT_NOTIFIERS
 	select ANON_INODES
-	select S390_SWITCH_AMODE
 	---help---
 	  Support hosting paravirtualized guest machines using the SIE
 	  virtualization capability on the mainframe. This should work
diff --git a/arch/s390/lib/uaccess_mvcos.c b/arch/s390/lib/uaccess_mvcos.c
index 58da3f4..60455f1 100644
--- a/arch/s390/lib/uaccess_mvcos.c
+++ b/arch/s390/lib/uaccess_mvcos.c
@@ -162,7 +162,6 @@
 	return size;
 }
 
-#ifdef CONFIG_S390_SWITCH_AMODE
 static size_t strnlen_user_mvcos(size_t count, const char __user *src)
 {
 	char buf[256];
@@ -200,7 +199,6 @@
 	} while ((len_str == len) && (done < count));
 	return done;
 }
-#endif /* CONFIG_S390_SWITCH_AMODE */
 
 struct uaccess_ops uaccess_mvcos = {
 	.copy_from_user = copy_from_user_mvcos_check,
@@ -215,7 +213,6 @@
 	.futex_atomic_cmpxchg = futex_atomic_cmpxchg_std,
 };
 
-#ifdef CONFIG_S390_SWITCH_AMODE
 struct uaccess_ops uaccess_mvcos_switch = {
 	.copy_from_user = copy_from_user_mvcos,
 	.copy_from_user_small = copy_from_user_mvcos,
@@ -228,4 +225,3 @@
 	.futex_atomic_op = futex_atomic_op_pt,
 	.futex_atomic_cmpxchg = futex_atomic_cmpxchg_pt,
 };
-#endif
diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c
index cb5d59e..404f2de 100644
--- a/arch/s390/lib/uaccess_pt.c
+++ b/arch/s390/lib/uaccess_pt.c
@@ -23,86 +23,21 @@
 
 	pgd = pgd_offset(mm, addr);
 	if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
-		return NULL;
+		return (pte_t *) 0x3a;
 
 	pud = pud_offset(pgd, addr);
 	if (pud_none(*pud) || unlikely(pud_bad(*pud)))
-		return NULL;
+		return (pte_t *) 0x3b;
 
 	pmd = pmd_offset(pud, addr);
 	if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
-		return NULL;
+		return (pte_t *) 0x10;
 
 	return pte_offset_map(pmd, addr);
 }
 
-static int __handle_fault(struct mm_struct *mm, unsigned long address,
-			  int write_access)
-{
-	struct vm_area_struct *vma;
-	int ret = -EFAULT;
-	int fault;
-
-	if (in_atomic())
-		return ret;
-	down_read(&mm->mmap_sem);
-	vma = find_vma(mm, address);
-	if (unlikely(!vma))
-		goto out;
-	if (unlikely(vma->vm_start > address)) {
-		if (!(vma->vm_flags & VM_GROWSDOWN))
-			goto out;
-		if (expand_stack(vma, address))
-			goto out;
-	}
-
-	if (!write_access) {
-		/* page not present, check vm flags */
-		if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
-			goto out;
-	} else {
-		if (!(vma->vm_flags & VM_WRITE))
-			goto out;
-	}
-
-survive:
-	fault = handle_mm_fault(mm, vma, address, write_access ? FAULT_FLAG_WRITE : 0);
-	if (unlikely(fault & VM_FAULT_ERROR)) {
-		if (fault & VM_FAULT_OOM)
-			goto out_of_memory;
-		else if (fault & VM_FAULT_SIGBUS)
-			goto out_sigbus;
-		BUG();
-	}
-	if (fault & VM_FAULT_MAJOR)
-		current->maj_flt++;
-	else
-		current->min_flt++;
-	ret = 0;
-out:
-	up_read(&mm->mmap_sem);
-	return ret;
-
-out_of_memory:
-	up_read(&mm->mmap_sem);
-	if (is_global_init(current)) {
-		yield();
-		down_read(&mm->mmap_sem);
-		goto survive;
-	}
-	printk("VM: killing process %s\n", current->comm);
-	return ret;
-
-out_sigbus:
-	up_read(&mm->mmap_sem);
-	current->thread.prot_addr = address;
-	current->thread.trap_no = 0x11;
-	force_sig(SIGBUS, current);
-	return ret;
-}
-
-static size_t __user_copy_pt(unsigned long uaddr, void *kptr,
-			     size_t n, int write_user)
+static __always_inline size_t __user_copy_pt(unsigned long uaddr, void *kptr,
+					     size_t n, int write_user)
 {
 	struct mm_struct *mm = current->mm;
 	unsigned long offset, pfn, done, size;
@@ -114,12 +49,17 @@
 	spin_lock(&mm->page_table_lock);
 	do {
 		pte = follow_table(mm, uaddr);
-		if (!pte || !pte_present(*pte) ||
-		    (write_user && !pte_write(*pte)))
+		if ((unsigned long) pte < 0x1000)
 			goto fault;
+		if (!pte_present(*pte)) {
+			pte = (pte_t *) 0x11;
+			goto fault;
+		} else if (write_user && !pte_write(*pte)) {
+			pte = (pte_t *) 0x04;
+			goto fault;
+		}
 
 		pfn = pte_pfn(*pte);
-
 		offset = uaddr & (PAGE_SIZE - 1);
 		size = min(n - done, PAGE_SIZE - offset);
 		if (write_user) {
@@ -137,7 +77,7 @@
 	return n - done;
 fault:
 	spin_unlock(&mm->page_table_lock);
-	if (__handle_fault(mm, uaddr, write_user))
+	if (__handle_fault(uaddr, (unsigned long) pte, write_user))
 		return n - done;
 	goto retry;
 }
@@ -146,30 +86,31 @@
  * Do DAT for user address by page table walk, return kernel address.
  * This function needs to be called with current->mm->page_table_lock held.
  */
-static unsigned long __dat_user_addr(unsigned long uaddr)
+static __always_inline unsigned long __dat_user_addr(unsigned long uaddr)
 {
 	struct mm_struct *mm = current->mm;
-	unsigned long pfn, ret;
+	unsigned long pfn;
 	pte_t *pte;
 	int rc;
 
-	ret = 0;
 retry:
 	pte = follow_table(mm, uaddr);
-	if (!pte || !pte_present(*pte))
+	if ((unsigned long) pte < 0x1000)
 		goto fault;
+	if (!pte_present(*pte)) {
+		pte = (pte_t *) 0x11;
+		goto fault;
+	}
 
 	pfn = pte_pfn(*pte);
-	ret = (pfn << PAGE_SHIFT) + (uaddr & (PAGE_SIZE - 1));
-out:
-	return ret;
+	return (pfn << PAGE_SHIFT) + (uaddr & (PAGE_SIZE - 1));
 fault:
 	spin_unlock(&mm->page_table_lock);
-	rc = __handle_fault(mm, uaddr, 0);
+	rc = __handle_fault(uaddr, (unsigned long) pte, 0);
 	spin_lock(&mm->page_table_lock);
-	if (rc)
-		goto out;
-	goto retry;
+	if (!rc)
+		goto retry;
+	return 0;
 }
 
 size_t copy_from_user_pt(size_t n, const void __user *from, void *to)
@@ -234,8 +175,12 @@
 	spin_lock(&mm->page_table_lock);
 	do {
 		pte = follow_table(mm, uaddr);
-		if (!pte || !pte_present(*pte))
+		if ((unsigned long) pte < 0x1000)
 			goto fault;
+		if (!pte_present(*pte)) {
+			pte = (pte_t *) 0x11;
+			goto fault;
+		}
 
 		pfn = pte_pfn(*pte);
 		offset = uaddr & (PAGE_SIZE-1);
@@ -249,9 +194,8 @@
 	return done + 1;
 fault:
 	spin_unlock(&mm->page_table_lock);
-	if (__handle_fault(mm, uaddr, 0)) {
+	if (__handle_fault(uaddr, (unsigned long) pte, 0))
 		return 0;
-	}
 	goto retry;
 }
 
@@ -284,7 +228,7 @@
 {
 	struct mm_struct *mm = current->mm;
 	unsigned long offset_from, offset_to, offset_max, pfn_from, pfn_to,
-		      uaddr, done, size;
+		      uaddr, done, size, error_code;
 	unsigned long uaddr_from = (unsigned long) from;
 	unsigned long uaddr_to = (unsigned long) to;
 	pte_t *pte_from, *pte_to;
@@ -298,17 +242,28 @@
 retry:
 	spin_lock(&mm->page_table_lock);
 	do {
+		write_user = 0;
+		uaddr = uaddr_from;
 		pte_from = follow_table(mm, uaddr_from);
-		if (!pte_from || !pte_present(*pte_from)) {
-			uaddr = uaddr_from;
-			write_user = 0;
+		error_code = (unsigned long) pte_from;
+		if (error_code < 0x1000)
+			goto fault;
+		if (!pte_present(*pte_from)) {
+			error_code = 0x11;
 			goto fault;
 		}
 
+		write_user = 1;
+		uaddr = uaddr_to;
 		pte_to = follow_table(mm, uaddr_to);
-		if (!pte_to || !pte_present(*pte_to) || !pte_write(*pte_to)) {
-			uaddr = uaddr_to;
-			write_user = 1;
+		error_code = (unsigned long) pte_to;
+		if (error_code < 0x1000)
+			goto fault;
+		if (!pte_present(*pte_to)) {
+			error_code = 0x11;
+			goto fault;
+		} else if (!pte_write(*pte_to)) {
+			error_code = 0x04;
 			goto fault;
 		}
 
@@ -329,7 +284,7 @@
 	return n - done;
 fault:
 	spin_unlock(&mm->page_table_lock);
-	if (__handle_fault(mm, uaddr, write_user))
+	if (__handle_fault(uaddr, error_code, write_user))
 		return n - done;
 	goto retry;
 }
diff --git a/arch/s390/math-emu/math.c b/arch/s390/math-emu/math.c
index 3ee78cc..cd4e9c1 100644
--- a/arch/s390/math-emu/math.c
+++ b/arch/s390/math-emu/math.c
@@ -2088,7 +2088,7 @@
         __u16 opc = *((__u16 *) opcode);
 
         if ((opc & 0x90) == 0) {           /* test if rx in {0,2,4,6} */
-                /* we got an exception therfore ry can't be in {0,2,4,6} */
+                /* we got an exception therefore ry can't be in {0,2,4,6} */
 		asm volatile(		/* load rx from fp_regs.fprs[ry] */
 			"	bras	1,0f\n"
 			"	ld	0,0(%1)\n"
@@ -2118,7 +2118,7 @@
         __u16 opc = *((__u16 *) opcode);
 
         if ((opc & 0x90) == 0) {           /* test if rx in {0,2,4,6} */
-                /* we got an exception therfore ry can't be in {0,2,4,6} */
+                /* we got an exception therefore ry can't be in {0,2,4,6} */
 		asm volatile(		/* load rx from fp_regs.fprs[ry] */
 			"	bras	1,0f\n"
 			"	le	0,0(%1)\n"
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
index ff58779..76a3637 100644
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -18,6 +18,7 @@
 #include <linux/swap.h>
 #include <linux/kthread.h>
 #include <linux/oom.h>
+#include <linux/suspend.h>
 
 #include <asm/pgalloc.h>
 #include <asm/uaccess.h>
@@ -44,6 +45,7 @@
 static volatile long cmm_timed_pages_target;
 static long cmm_timeout_pages;
 static long cmm_timeout_seconds;
+static int cmm_suspended;
 
 static struct cmm_page_array *cmm_page_list;
 static struct cmm_page_array *cmm_timed_page_list;
@@ -147,9 +149,9 @@
 
 	while (1) {
 		rc = wait_event_interruptible(cmm_thread_wait,
-			(cmm_pages != cmm_pages_target ||
-			 cmm_timed_pages != cmm_timed_pages_target ||
-			 kthread_should_stop()));
+			(!cmm_suspended && (cmm_pages != cmm_pages_target ||
+			 cmm_timed_pages != cmm_timed_pages_target)) ||
+			 kthread_should_stop());
 		if (kthread_should_stop() || rc == -ERESTARTSYS) {
 			cmm_pages_target = cmm_pages;
 			cmm_timed_pages_target = cmm_timed_pages;
@@ -410,6 +412,38 @@
 
 static struct ctl_table_header *cmm_sysctl_header;
 
+static int cmm_suspend(void)
+{
+	cmm_suspended = 1;
+	cmm_free_pages(cmm_pages, &cmm_pages, &cmm_page_list);
+	cmm_free_pages(cmm_timed_pages, &cmm_timed_pages, &cmm_timed_page_list);
+	return 0;
+}
+
+static int cmm_resume(void)
+{
+	cmm_suspended = 0;
+	cmm_kick_thread();
+	return 0;
+}
+
+static int cmm_power_event(struct notifier_block *this,
+			   unsigned long event, void *ptr)
+{
+	switch (event) {
+	case PM_POST_HIBERNATION:
+		return cmm_resume();
+	case PM_HIBERNATION_PREPARE:
+		return cmm_suspend();
+	default:
+		return NOTIFY_DONE;
+	}
+}
+
+static struct notifier_block cmm_power_notifier = {
+	.notifier_call = cmm_power_event,
+};
+
 static int
 cmm_init (void)
 {
@@ -418,7 +452,7 @@
 #ifdef CONFIG_CMM_PROC
 	cmm_sysctl_header = register_sysctl_table(cmm_dir_table);
 	if (!cmm_sysctl_header)
-		goto out;
+		goto out_sysctl;
 #endif
 #ifdef CONFIG_CMM_IUCV
 	rc = smsg_register_callback(SMSG_PREFIX, cmm_smsg_target);
@@ -428,17 +462,21 @@
 	rc = register_oom_notifier(&cmm_oom_nb);
 	if (rc < 0)
 		goto out_oom_notify;
+	rc = register_pm_notifier(&cmm_power_notifier);
+	if (rc)
+		goto out_pm;
 	init_waitqueue_head(&cmm_thread_wait);
 	init_timer(&cmm_timer);
 	cmm_thread_ptr = kthread_run(cmm_thread, NULL, "cmmthread");
 	rc = IS_ERR(cmm_thread_ptr) ? PTR_ERR(cmm_thread_ptr) : 0;
-	if (!rc)
-		goto out;
-	/*
-	 * kthread_create failed. undo all the stuff from above again.
-	 */
-	unregister_oom_notifier(&cmm_oom_nb);
+	if (rc)
+		goto out_kthread;
+	return 0;
 
+out_kthread:
+	unregister_pm_notifier(&cmm_power_notifier);
+out_pm:
+	unregister_oom_notifier(&cmm_oom_nb);
 out_oom_notify:
 #ifdef CONFIG_CMM_IUCV
 	smsg_unregister_callback(SMSG_PREFIX, cmm_smsg_target);
@@ -446,8 +484,8 @@
 #endif
 #ifdef CONFIG_CMM_PROC
 	unregister_sysctl_table(cmm_sysctl_header);
+out_sysctl:
 #endif
-out:
 	return rc;
 }
 
@@ -455,6 +493,7 @@
 cmm_exit(void)
 {
 	kthread_stop(cmm_thread_ptr);
+	unregister_pm_notifier(&cmm_power_notifier);
 	unregister_oom_notifier(&cmm_oom_nb);
 	cmm_free_pages(cmm_pages, &cmm_pages, &cmm_page_list);
 	cmm_free_pages(cmm_timed_pages, &cmm_timed_pages, &cmm_timed_page_list);
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 6d50746..fc102e7 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -34,16 +34,15 @@
 #include <asm/pgtable.h>
 #include <asm/s390_ext.h>
 #include <asm/mmu_context.h>
+#include <asm/compat.h>
 #include "../kernel/entry.h"
 
 #ifndef CONFIG_64BIT
 #define __FAIL_ADDR_MASK 0x7ffff000
-#define __FIXUP_MASK 0x7fffffff
 #define __SUBCODE_MASK 0x0200
 #define __PF_RES_FIELD 0ULL
 #else /* CONFIG_64BIT */
 #define __FAIL_ADDR_MASK -4096L
-#define __FIXUP_MASK ~0L
 #define __SUBCODE_MASK 0x0600
 #define __PF_RES_FIELD 0x8000000000000000ULL
 #endif /* CONFIG_64BIT */
@@ -52,11 +51,15 @@
 extern int sysctl_userprocess_debug;
 #endif
 
-#ifdef CONFIG_KPROBES
-static inline int notify_page_fault(struct pt_regs *regs, long err)
+#define VM_FAULT_BADCONTEXT	0x010000
+#define VM_FAULT_BADMAP		0x020000
+#define VM_FAULT_BADACCESS	0x040000
+
+static inline int notify_page_fault(struct pt_regs *regs)
 {
 	int ret = 0;
 
+#ifdef CONFIG_KPROBES
 	/* kprobe_running() needs smp_processor_id() */
 	if (!user_mode(regs)) {
 		preempt_disable();
@@ -64,15 +67,9 @@
 			ret = 1;
 		preempt_enable();
 	}
-
+#endif
 	return ret;
 }
-#else
-static inline int notify_page_fault(struct pt_regs *regs, long err)
-{
-	return 0;
-}
-#endif
 
 
 /*
@@ -100,57 +97,50 @@
 
 /*
  * Returns the address space associated with the fault.
- * Returns 0 for kernel space, 1 for user space and
- * 2 for code execution in user space with noexec=on.
+ * Returns 0 for kernel space and 1 for user space.
  */
-static inline int check_space(struct task_struct *tsk)
+static inline int user_space_fault(unsigned long trans_exc_code)
 {
 	/*
-	 * The lowest two bits of S390_lowcore.trans_exc_code
-	 * indicate which paging table was used.
+	 * The lowest two bits of the translation exception
+	 * identification indicate which paging table was used.
 	 */
-	int desc = S390_lowcore.trans_exc_code & 3;
-
-	if (desc == 3)	/* Home Segment Table Descriptor */
-		return switch_amode == 0;
-	if (desc == 2)	/* Secondary Segment Table Descriptor */
-		return tsk->thread.mm_segment.ar4;
-#ifdef CONFIG_S390_SWITCH_AMODE
-	if (unlikely(desc == 1)) { /* STD determined via access register */
-		/* %a0 always indicates primary space. */
-		if (S390_lowcore.exc_access_id != 0) {
-			save_access_regs(tsk->thread.acrs);
-			/*
-			 * An alet of 0 indicates primary space.
-			 * An alet of 1 indicates secondary space.
-			 * Any other alet values generate an
-			 * alen-translation exception.
-			 */
-			if (tsk->thread.acrs[S390_lowcore.exc_access_id])
-				return tsk->thread.mm_segment.ar4;
-		}
-	}
-#endif
-	/* Primary Segment Table Descriptor */
-	return switch_amode << s390_noexec;
+	trans_exc_code &= 3;
+	if (trans_exc_code == 2)
+		/* Access via secondary space, set_fs setting decides */
+		return current->thread.mm_segment.ar4;
+	if (user_mode == HOME_SPACE_MODE)
+		/* User space if the access has been done via home space. */
+		return trans_exc_code == 3;
+	/*
+	 * If the user space is not the home space the kernel runs in home
+	 * space. Access via secondary space has already been covered,
+	 * access via primary space or access register is from user space
+	 * and access via home space is from the kernel.
+	 */
+	return trans_exc_code != 3;
 }
 
 /*
  * Send SIGSEGV to task.  This is an external routine
  * to keep the stack usage of do_page_fault small.
  */
-static void do_sigsegv(struct pt_regs *regs, unsigned long error_code,
-		       int si_code, unsigned long address)
+static noinline void do_sigsegv(struct pt_regs *regs, long int_code,
+				int si_code, unsigned long trans_exc_code)
 {
 	struct siginfo si;
+	unsigned long address;
 
+	address = trans_exc_code & __FAIL_ADDR_MASK;
+	current->thread.prot_addr = address;
+	current->thread.trap_no = int_code;
 #if defined(CONFIG_SYSCTL) || defined(CONFIG_PROCESS_DEBUG)
 #if defined(CONFIG_SYSCTL)
 	if (sysctl_userprocess_debug)
 #endif
 	{
 		printk("User process fault: interruption code 0x%lX\n",
-		       error_code);
+		       int_code);
 		printk("failing address: %lX\n", address);
 		show_regs(regs);
 	}
@@ -161,13 +151,14 @@
 	force_sig_info(SIGSEGV, &si, current);
 }
 
-static void do_no_context(struct pt_regs *regs, unsigned long error_code,
-			  unsigned long address)
+static noinline void do_no_context(struct pt_regs *regs, long int_code,
+				   unsigned long trans_exc_code)
 {
 	const struct exception_table_entry *fixup;
+	unsigned long address;
 
 	/* Are we prepared to handle this kernel fault?  */
-	fixup = search_exception_tables(regs->psw.addr & __FIXUP_MASK);
+	fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN);
 	if (fixup) {
 		regs->psw.addr = fixup->fixup | PSW_ADDR_AMODE;
 		return;
@@ -177,129 +168,149 @@
 	 * Oops. The kernel tried to access some bad page. We'll have to
 	 * terminate things with extreme prejudice.
 	 */
-	if (check_space(current) == 0)
+	address = trans_exc_code & __FAIL_ADDR_MASK;
+	if (!user_space_fault(trans_exc_code))
 		printk(KERN_ALERT "Unable to handle kernel pointer dereference"
 		       " at virtual kernel address %p\n", (void *)address);
 	else
 		printk(KERN_ALERT "Unable to handle kernel paging request"
 		       " at virtual user address %p\n", (void *)address);
 
-	die("Oops", regs, error_code);
+	die("Oops", regs, int_code);
 	do_exit(SIGKILL);
 }
 
-static void do_low_address(struct pt_regs *regs, unsigned long error_code)
+static noinline void do_low_address(struct pt_regs *regs, long int_code,
+				    unsigned long trans_exc_code)
 {
 	/* Low-address protection hit in kernel mode means
 	   NULL pointer write access in kernel mode.  */
 	if (regs->psw.mask & PSW_MASK_PSTATE) {
 		/* Low-address protection hit in user mode 'cannot happen'. */
-		die ("Low-address protection", regs, error_code);
+		die ("Low-address protection", regs, int_code);
 		do_exit(SIGKILL);
 	}
 
-	do_no_context(regs, error_code, 0);
+	do_no_context(regs, int_code, trans_exc_code);
 }
 
-static void do_sigbus(struct pt_regs *regs, unsigned long error_code,
-		      unsigned long address)
+static noinline void do_sigbus(struct pt_regs *regs, long int_code,
+			       unsigned long trans_exc_code)
 {
 	struct task_struct *tsk = current;
-	struct mm_struct *mm = tsk->mm;
 
-	up_read(&mm->mmap_sem);
 	/*
 	 * Send a sigbus, regardless of whether we were in kernel
 	 * or user mode.
 	 */
-	tsk->thread.prot_addr = address;
-	tsk->thread.trap_no = error_code;
+	tsk->thread.prot_addr = trans_exc_code & __FAIL_ADDR_MASK;
+	tsk->thread.trap_no = int_code;
 	force_sig(SIGBUS, tsk);
-
-	/* Kernel mode? Handle exceptions or die */
-	if (!(regs->psw.mask & PSW_MASK_PSTATE))
-		do_no_context(regs, error_code, address);
 }
 
 #ifdef CONFIG_S390_EXEC_PROTECT
-static int signal_return(struct mm_struct *mm, struct pt_regs *regs,
-			 unsigned long address, unsigned long error_code)
+static noinline int signal_return(struct pt_regs *regs, long int_code,
+				  unsigned long trans_exc_code)
 {
 	u16 instruction;
 	int rc;
-#ifdef CONFIG_COMPAT
-	int compat;
-#endif
 
-	pagefault_disable();
 	rc = __get_user(instruction, (u16 __user *) regs->psw.addr);
-	pagefault_enable();
-	if (rc)
-		return -EFAULT;
 
-	up_read(&mm->mmap_sem);
-	clear_tsk_thread_flag(current, TIF_SINGLE_STEP);
-#ifdef CONFIG_COMPAT
-	compat = is_compat_task();
-	if (compat && instruction == 0x0a77)
-		sys32_sigreturn();
-	else if (compat && instruction == 0x0aad)
-		sys32_rt_sigreturn();
-	else
-#endif
-	if (instruction == 0x0a77)
-		sys_sigreturn();
-	else if (instruction == 0x0aad)
-		sys_rt_sigreturn();
-	else {
-		current->thread.prot_addr = address;
-		current->thread.trap_no = error_code;
-		do_sigsegv(regs, error_code, SEGV_MAPERR, address);
-	}
+	if (!rc && instruction == 0x0a77) {
+		clear_tsk_thread_flag(current, TIF_SINGLE_STEP);
+		if (is_compat_task())
+			sys32_sigreturn();
+		else
+			sys_sigreturn();
+	} else if (!rc && instruction == 0x0aad) {
+		clear_tsk_thread_flag(current, TIF_SINGLE_STEP);
+		if (is_compat_task())
+			sys32_rt_sigreturn();
+		else
+			sys_rt_sigreturn();
+	} else
+		do_sigsegv(regs, int_code, SEGV_MAPERR, trans_exc_code);
 	return 0;
 }
 #endif /* CONFIG_S390_EXEC_PROTECT */
 
+static noinline void do_fault_error(struct pt_regs *regs, long int_code,
+				    unsigned long trans_exc_code, int fault)
+{
+	int si_code;
+
+	switch (fault) {
+	case VM_FAULT_BADACCESS:
+#ifdef CONFIG_S390_EXEC_PROTECT
+		if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_SECONDARY &&
+		    (trans_exc_code & 3) == 0) {
+			signal_return(regs, int_code, trans_exc_code);
+			break;
+		}
+#endif /* CONFIG_S390_EXEC_PROTECT */
+	case VM_FAULT_BADMAP:
+		/* Bad memory access. Check if it is kernel or user space. */
+		if (regs->psw.mask & PSW_MASK_PSTATE) {
+			/* User mode accesses just cause a SIGSEGV */
+			si_code = (fault == VM_FAULT_BADMAP) ?
+				SEGV_MAPERR : SEGV_ACCERR;
+			do_sigsegv(regs, int_code, si_code, trans_exc_code);
+			return;
+		}
+	case VM_FAULT_BADCONTEXT:
+		do_no_context(regs, int_code, trans_exc_code);
+		break;
+	default: /* fault & VM_FAULT_ERROR */
+		if (fault & VM_FAULT_OOM)
+			pagefault_out_of_memory();
+		else if (fault & VM_FAULT_SIGBUS) {
+			do_sigbus(regs, int_code, trans_exc_code);
+			/* Kernel mode? Handle exceptions or die */
+			if (!(regs->psw.mask & PSW_MASK_PSTATE))
+				do_no_context(regs, int_code, trans_exc_code);
+		} else
+			BUG();
+		break;
+	}
+}
+
 /*
  * This routine handles page faults.  It determines the address,
  * and the problem, and then passes it off to one of the appropriate
  * routines.
  *
- * error_code:
+ * interruption code (int_code):
  *   04       Protection           ->  Write-Protection  (suprression)
  *   10       Segment translation  ->  Not present       (nullification)
  *   11       Page translation     ->  Not present       (nullification)
  *   3b       Region third trans.  ->  Not present       (nullification)
  */
-static inline void
-do_exception(struct pt_regs *regs, unsigned long error_code, int write)
+static inline int do_exception(struct pt_regs *regs, int access,
+			       unsigned long trans_exc_code)
 {
 	struct task_struct *tsk;
 	struct mm_struct *mm;
 	struct vm_area_struct *vma;
 	unsigned long address;
-	int space;
-	int si_code;
 	int fault;
 
-	if (notify_page_fault(regs, error_code))
-		return;
+	if (notify_page_fault(regs))
+		return 0;
 
 	tsk = current;
 	mm = tsk->mm;
 
-	/* get the failing address and the affected space */
-	address = S390_lowcore.trans_exc_code & __FAIL_ADDR_MASK;
-	space = check_space(tsk);
-
 	/*
 	 * Verify that the fault happened in user space, that
 	 * we are not in an interrupt and that there is a 
 	 * user context.
 	 */
-	if (unlikely(space == 0 || in_atomic() || !mm))
-		goto no_context;
+	fault = VM_FAULT_BADCONTEXT;
+	if (unlikely(!user_space_fault(trans_exc_code) || in_atomic() || !mm))
+		goto out;
 
+	address = trans_exc_code & __FAIL_ADDR_MASK;
 	/*
 	 * When we get here, the fault happened in the current
 	 * task's user address space, so we can switch on the
@@ -309,42 +320,26 @@
 	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
 	down_read(&mm->mmap_sem);
 
-	si_code = SEGV_MAPERR;
+	fault = VM_FAULT_BADMAP;
 	vma = find_vma(mm, address);
 	if (!vma)
-		goto bad_area;
+		goto out_up;
 
-#ifdef CONFIG_S390_EXEC_PROTECT
-	if (unlikely((space == 2) && !(vma->vm_flags & VM_EXEC)))
-		if (!signal_return(mm, regs, address, error_code))
-			/*
-			 * signal_return() has done an up_read(&mm->mmap_sem)
-			 * if it returns 0.
-			 */
-			return;
-#endif
-
-	if (vma->vm_start <= address)
-		goto good_area;
-	if (!(vma->vm_flags & VM_GROWSDOWN))
-		goto bad_area;
-	if (expand_stack(vma, address))
-		goto bad_area;
-/*
- * Ok, we have a good vm_area for this memory access, so
- * we can handle it..
- */
-good_area:
-	si_code = SEGV_ACCERR;
-	if (!write) {
-		/* page not present, check vm flags */
-		if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
-			goto bad_area;
-	} else {
-		if (!(vma->vm_flags & VM_WRITE))
-			goto bad_area;
+	if (unlikely(vma->vm_start > address)) {
+		if (!(vma->vm_flags & VM_GROWSDOWN))
+			goto out_up;
+		if (expand_stack(vma, address))
+			goto out_up;
 	}
 
+	/*
+	 * Ok, we have a good vm_area for this memory access, so
+	 * we can handle it..
+	 */
+	fault = VM_FAULT_BADACCESS;
+	if (unlikely(!(vma->vm_flags & access)))
+		goto out_up;
+
 	if (is_vm_hugetlb_page(vma))
 		address &= HPAGE_MASK;
 	/*
@@ -352,18 +347,11 @@
 	 * make sure we exit gracefully rather than endlessly redo
 	 * the fault.
 	 */
-	fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0);
-	if (unlikely(fault & VM_FAULT_ERROR)) {
-		if (fault & VM_FAULT_OOM) {
-			up_read(&mm->mmap_sem);
-			pagefault_out_of_memory();
-			return;
-		} else if (fault & VM_FAULT_SIGBUS) {
-			do_sigbus(regs, error_code, address);
-			return;
-		}
-		BUG();
-	}
+	fault = handle_mm_fault(mm, vma, address,
+				(access == VM_WRITE) ? FAULT_FLAG_WRITE : 0);
+	if (unlikely(fault & VM_FAULT_ERROR))
+		goto out_up;
+
 	if (fault & VM_FAULT_MAJOR) {
 		tsk->maj_flt++;
 		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
@@ -373,74 +361,69 @@
 		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
 				     regs, address);
 	}
-        up_read(&mm->mmap_sem);
 	/*
 	 * The instruction that caused the program check will
 	 * be repeated. Don't signal single step via SIGTRAP.
 	 */
 	clear_tsk_thread_flag(tsk, TIF_SINGLE_STEP);
-        return;
-
-/*
- * Something tried to access memory that isn't in our memory map..
- * Fix it, but check if it's kernel or user first..
- */
-bad_area:
+	fault = 0;
+out_up:
 	up_read(&mm->mmap_sem);
-
-	/* User mode accesses just cause a SIGSEGV */
-	if (regs->psw.mask & PSW_MASK_PSTATE) {
-		tsk->thread.prot_addr = address;
-		tsk->thread.trap_no = error_code;
-		do_sigsegv(regs, error_code, si_code, address);
-		return;
-	}
-
-no_context:
-	do_no_context(regs, error_code, address);
+out:
+	return fault;
 }
 
-void __kprobes do_protection_exception(struct pt_regs *regs,
-				       long error_code)
+void __kprobes do_protection_exception(struct pt_regs *regs, long int_code)
 {
+	unsigned long trans_exc_code = S390_lowcore.trans_exc_code;
+	int fault;
+
 	/* Protection exception is supressing, decrement psw address. */
-	regs->psw.addr -= (error_code >> 16);
+	regs->psw.addr -= (int_code >> 16);
 	/*
 	 * Check for low-address protection.  This needs to be treated
 	 * as a special case because the translation exception code
 	 * field is not guaranteed to contain valid data in this case.
 	 */
-	if (unlikely(!(S390_lowcore.trans_exc_code & 4))) {
-		do_low_address(regs, error_code);
+	if (unlikely(!(trans_exc_code & 4))) {
+		do_low_address(regs, int_code, trans_exc_code);
 		return;
 	}
-	do_exception(regs, 4, 1);
+	fault = do_exception(regs, VM_WRITE, trans_exc_code);
+	if (unlikely(fault))
+		do_fault_error(regs, 4, trans_exc_code, fault);
 }
 
-void __kprobes do_dat_exception(struct pt_regs *regs, long error_code)
+void __kprobes do_dat_exception(struct pt_regs *regs, long int_code)
 {
-	do_exception(regs, error_code & 0xff, 0);
+	unsigned long trans_exc_code = S390_lowcore.trans_exc_code;
+	int access, fault;
+
+	access = VM_READ | VM_EXEC | VM_WRITE;
+#ifdef CONFIG_S390_EXEC_PROTECT
+	if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_SECONDARY &&
+	    (trans_exc_code & 3) == 0)
+		access = VM_EXEC;
+#endif
+	fault = do_exception(regs, access, trans_exc_code);
+	if (unlikely(fault))
+		do_fault_error(regs, int_code & 255, trans_exc_code, fault);
 }
 
 #ifdef CONFIG_64BIT
-void __kprobes do_asce_exception(struct pt_regs *regs, unsigned long error_code)
+void __kprobes do_asce_exception(struct pt_regs *regs, long int_code)
 {
-	struct mm_struct *mm;
+	unsigned long trans_exc_code = S390_lowcore.trans_exc_code;
+	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *vma;
-	unsigned long address;
-	int space;
 
-	mm = current->mm;
-	address = S390_lowcore.trans_exc_code & __FAIL_ADDR_MASK;
-	space = check_space(current);
-
-	if (unlikely(space == 0 || in_atomic() || !mm))
+	if (unlikely(!user_space_fault(trans_exc_code) || in_atomic() || !mm))
 		goto no_context;
 
 	local_irq_enable();
 
 	down_read(&mm->mmap_sem);
-	vma = find_vma(mm, address);
+	vma = find_vma(mm, trans_exc_code & __FAIL_ADDR_MASK);
 	up_read(&mm->mmap_sem);
 
 	if (vma) {
@@ -450,17 +433,38 @@
 
 	/* User mode accesses just cause a SIGSEGV */
 	if (regs->psw.mask & PSW_MASK_PSTATE) {
-		current->thread.prot_addr = address;
-		current->thread.trap_no = error_code;
-		do_sigsegv(regs, error_code, SEGV_MAPERR, address);
+		do_sigsegv(regs, int_code, SEGV_MAPERR, trans_exc_code);
 		return;
 	}
 
 no_context:
-	do_no_context(regs, error_code, address);
+	do_no_context(regs, int_code, trans_exc_code);
 }
 #endif
 
+int __handle_fault(unsigned long uaddr, unsigned long int_code, int write_user)
+{
+	struct pt_regs regs;
+	int access, fault;
+
+	regs.psw.mask = psw_kernel_bits;
+	if (!irqs_disabled())
+		regs.psw.mask |= PSW_MASK_IO | PSW_MASK_EXT;
+	regs.psw.addr = (unsigned long) __builtin_return_address(0);
+	regs.psw.addr |= PSW_ADDR_AMODE;
+	uaddr &= PAGE_MASK;
+	access = write_user ? VM_WRITE : VM_READ;
+	fault = do_exception(&regs, access, uaddr | 2);
+	if (unlikely(fault)) {
+		if (fault & VM_FAULT_OOM) {
+			pagefault_out_of_memory();
+			fault = 0;
+		} else if (fault & VM_FAULT_SIGBUS)
+			do_sigbus(&regs, int_code, uaddr);
+	}
+	return fault ? -EFAULT : 0;
+}
+
 #ifdef CONFIG_PFAULT 
 /*
  * 'pfault' pseudo page faults routines.
@@ -522,7 +526,7 @@
 		: : "a" (&refbk), "m" (refbk) : "cc");
 }
 
-static void pfault_interrupt(__u16 error_code)
+static void pfault_interrupt(__u16 int_code)
 {
 	struct task_struct *tsk;
 	__u16 subcode;
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 2757c56..ad621e0 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -269,7 +269,7 @@
 	struct mm_struct *mm, *old_mm;
 
 	/* Do we have switched amode? If no, we cannot do sie */
-	if (!switch_amode)
+	if (user_mode == HOME_SPACE_MODE)
 		return -EINVAL;
 
 	/* Do we have pgstes? if yes, we are done */
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
index 5f91a38..300ab01 100644
--- a/arch/s390/mm/vmem.c
+++ b/arch/s390/mm/vmem.c
@@ -70,8 +70,12 @@
 		pte = alloc_bootmem(PTRS_PER_PTE * sizeof(pte_t));
 	if (!pte)
 		return NULL;
-	clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY,
-		    PTRS_PER_PTE * sizeof(pte_t));
+	if (MACHINE_HAS_HPAGE)
+		clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY | _PAGE_CO,
+			    PTRS_PER_PTE * sizeof(pte_t));
+	else
+		clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY,
+			    PTRS_PER_PTE * sizeof(pte_t));
 	return pte;
 }
 
@@ -112,7 +116,8 @@
 		if (MACHINE_HAS_HPAGE && !(address & ~HPAGE_MASK) &&
 		    (address + HPAGE_SIZE <= start + size) &&
 		    (address >= HPAGE_SIZE)) {
-			pte_val(pte) |= _SEGMENT_ENTRY_LARGE;
+			pte_val(pte) |= _SEGMENT_ENTRY_LARGE |
+					_SEGMENT_ENTRY_CO;
 			pmd_val(*pm_dir) = pte_val(pte);
 			address += HPAGE_SIZE - PAGE_SIZE;
 			continue;
diff --git a/arch/score/kernel/sys_score.c b/arch/score/kernel/sys_score.c
index 0012494..856ed68 100644
--- a/arch/score/kernel/sys_score.c
+++ b/arch/score/kernel/sys_score.c
@@ -36,34 +36,16 @@
 sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
 	  unsigned long flags, unsigned long fd, unsigned long pgoff)
 {
-	int error = -EBADF;
-	struct file *file = NULL;
-
-	if (pgoff & (~PAGE_MASK >> 12))
-		return -EINVAL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			return error;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-
-	return error;
+	return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
 }
 
 asmlinkage long
 sys_mmap(unsigned long addr, unsigned long len, unsigned long prot,
-	unsigned long flags, unsigned long fd, off_t pgoff)
+	unsigned long flags, unsigned long fd, off_t offset)
 {
-	return sys_mmap2(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT);
+	if (unlikely(offset & ~PAGE_MASK))
+		return -EINVAL;
+	return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
 }
 
 asmlinkage long
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 88cdeb9..0031a69 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -16,7 +16,9 @@
 	select HAVE_IOREMAP_PROT if MMU
 	select HAVE_ARCH_TRACEHOOK
 	select HAVE_DMA_API_DEBUG
+	select HAVE_DMA_ATTRS
 	select HAVE_PERF_EVENTS
+	select PERF_USE_VMALLOC
 	select HAVE_KERNEL_GZIP
 	select HAVE_KERNEL_BZIP2
 	select HAVE_KERNEL_LZMA
@@ -37,6 +39,7 @@
 	select HAVE_FTRACE_MCOUNT_RECORD
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_FUNCTION_TRACE_MCOUNT_TEST
+	select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE
 	select HAVE_FUNCTION_GRAPH_TRACER
 	select HAVE_ARCH_KGDB
 	select ARCH_HIBERNATION_POSSIBLE if MMU
@@ -170,6 +173,12 @@
 config IO_TRAPPED
 	bool
 
+config DMA_COHERENT
+	bool
+
+config DMA_NONCOHERENT
+	def_bool !DMA_COHERENT
+
 source "init/Kconfig"
 
 source "kernel/Kconfig.freezer"
@@ -220,6 +229,7 @@
 
 config CPU_SHX3
 	bool
+	select DMA_COHERENT
 
 config ARCH_SHMOBILE
 	bool
@@ -761,17 +771,6 @@
 	default "0x00010000" if PAGE_SIZE_64KB
 	default "0x00000000"
 
-config UBC_WAKEUP
-	bool "Wakeup UBC on startup"
-	depends on CPU_SH4 && !CPU_SH4A
-	help
-	  Selecting this option will wakeup the User Break Controller (UBC) on
-	  startup. Although the UBC is left in an awake state when the processor
-	  comes up, some boot loaders misbehave by putting the UBC to sleep in a
-	  power saving state, which causes issues with things like ptrace().
-
-	  If unsure, say N.
-
 choice
 	prompt "Kernel command line"
 	optional
@@ -818,7 +817,13 @@
 	 Dreamcast with a serial line terminal or a remote network
 	 connection.
 
-source "arch/sh/drivers/pci/Kconfig"
+config PCI
+	bool "PCI support"
+	depends on SYS_SUPPORTS_PCI
+	help
+	  Find out whether you have a PCI motherboard. PCI is the name of a
+	  bus system, i.e. the way the CPU talks to the other stuff inside
+	  your box. If you have PCI, say Y, otherwise N.
 
 source "drivers/pci/pcie/Kconfig"
 
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index 66e40aa..ac17c5a 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -78,6 +78,9 @@
 defaultimage-$(CONFIG_SH_SH7785LCR)		:= uImage
 defaultimage-$(CONFIG_SH_RSK)			:= uImage
 defaultimage-$(CONFIG_SH_URQUELL)		:= uImage
+defaultimage-$(CONFIG_SH_MIGOR)			:= uImage
+defaultimage-$(CONFIG_SH_AP325RXA)		:= uImage
+defaultimage-$(CONFIG_SH_7724_SOLUTION_ENGINE)	:= uImage
 defaultimage-$(CONFIG_SH_7206_SOLUTION_ENGINE)	:= vmlinux
 defaultimage-$(CONFIG_SH_7619_SOLUTION_ENGINE)	:= vmlinux
 
@@ -136,6 +139,7 @@
 machdir-$(CONFIG_SH_EDOSK7705)			+= mach-edosk7705
 machdir-$(CONFIG_SH_HIGHLANDER)			+= mach-highlander
 machdir-$(CONFIG_SH_MIGOR)			+= mach-migor
+machdir-$(CONFIG_SH_AP325RXA)			+= mach-ap325rxa
 machdir-$(CONFIG_SH_KFR2R09)			+= mach-kfr2r09
 machdir-$(CONFIG_SH_ECOVEC)			+= mach-ecovec24
 machdir-$(CONFIG_SH_SDK7780)			+= mach-sdk7780
diff --git a/arch/sh/boards/Makefile b/arch/sh/boards/Makefile
index 7baa210..ce0f263 100644
--- a/arch/sh/boards/Makefile
+++ b/arch/sh/boards/Makefile
@@ -1,7 +1,6 @@
 #
 # Specific board support, not covered by a mach group.
 #
-obj-$(CONFIG_SH_AP325RXA)	+= board-ap325rxa.o
 obj-$(CONFIG_SH_MAGIC_PANEL_R2)	+= board-magicpanelr2.o
 obj-$(CONFIG_SH_SH7785LCR)	+= board-sh7785lcr.o
 obj-$(CONFIG_SH_URQUELL)	+= board-urquell.o
diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c
deleted file mode 100644
index 2d08073..0000000
--- a/arch/sh/boards/board-ap325rxa.c
+++ /dev/null
@@ -1,606 +0,0 @@
-/*
- * Renesas - AP-325RXA
- * (Compatible with Algo System ., LTD. - AP-320A)
- *
- * Copyright (C) 2008 Renesas Solutions Corp.
- * Author : Yusuke Goda <goda.yuske@renesas.com>
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
-#include <linux/mtd/sh_flctl.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/smsc911x.h>
-#include <linux/gpio.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/spi_gpio.h>
-#include <media/ov772x.h>
-#include <media/soc_camera.h>
-#include <media/soc_camera_platform.h>
-#include <media/sh_mobile_ceu.h>
-#include <video/sh_mobile_lcdc.h>
-#include <asm/io.h>
-#include <asm/clock.h>
-#include <cpu/sh7723.h>
-
-static struct smsc911x_platform_config smsc911x_config = {
-	.phy_interface	= PHY_INTERFACE_MODE_MII,
-	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
-	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
-	.flags		= SMSC911X_USE_32BIT,
-};
-
-static struct resource smsc9118_resources[] = {
-	[0] = {
-		.start	= 0xb6080000,
-		.end	= 0xb60fffff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 35,
-		.end	= 35,
-		.flags	= IORESOURCE_IRQ,
-	}
-};
-
-static struct platform_device smsc9118_device = {
-	.name		= "smsc911x",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(smsc9118_resources),
-	.resource	= smsc9118_resources,
-	.dev		= {
-		.platform_data = &smsc911x_config,
-	},
-};
-
-/*
- * AP320 and AP325RXA has CPLD data in NOR Flash(0xA80000-0xABFFFF).
- * If this area erased, this board can not boot.
- */
-static struct mtd_partition ap325rxa_nor_flash_partitions[] = {
-	{
-		.name = "uboot",
-		.offset = 0,
-		.size = (1 * 1024 * 1024),
-		.mask_flags = MTD_WRITEABLE,	/* Read-only */
-	}, {
-		.name = "kernel",
-		.offset = MTDPART_OFS_APPEND,
-		.size = (2 * 1024 * 1024),
-	}, {
-		.name = "free-area0",
-		.offset = MTDPART_OFS_APPEND,
-		.size = ((7 * 1024 * 1024) + (512 * 1024)),
-	}, {
-		.name = "CPLD-Data",
-		.offset = MTDPART_OFS_APPEND,
-		.mask_flags = MTD_WRITEABLE,	/* Read-only */
-		.size = (1024 * 128 * 2),
-	}, {
-		.name = "free-area1",
-		.offset = MTDPART_OFS_APPEND,
-		.size = MTDPART_SIZ_FULL,
-	},
-};
-
-static struct physmap_flash_data ap325rxa_nor_flash_data = {
-	.width		= 2,
-	.parts		= ap325rxa_nor_flash_partitions,
-	.nr_parts	= ARRAY_SIZE(ap325rxa_nor_flash_partitions),
-};
-
-static struct resource ap325rxa_nor_flash_resources[] = {
-	[0] = {
-		.name	= "NOR Flash",
-		.start	= 0x00000000,
-		.end	= 0x00ffffff,
-		.flags	= IORESOURCE_MEM,
-	}
-};
-
-static struct platform_device ap325rxa_nor_flash_device = {
-	.name		= "physmap-flash",
-	.resource	= ap325rxa_nor_flash_resources,
-	.num_resources	= ARRAY_SIZE(ap325rxa_nor_flash_resources),
-	.dev		= {
-		.platform_data = &ap325rxa_nor_flash_data,
-	},
-};
-
-static struct mtd_partition nand_partition_info[] = {
-	{
-		.name	= "nand_data",
-		.offset	= 0,
-		.size	= MTDPART_SIZ_FULL,
-	},
-};
-
-static struct resource nand_flash_resources[] = {
-	[0] = {
-		.start	= 0xa4530000,
-		.end	= 0xa45300ff,
-		.flags	= IORESOURCE_MEM,
-	}
-};
-
-static struct sh_flctl_platform_data nand_flash_data = {
-	.parts		= nand_partition_info,
-	.nr_parts	= ARRAY_SIZE(nand_partition_info),
-	.flcmncr_val	= FCKSEL_E | TYPESEL_SET | NANWF_E,
-	.has_hwecc	= 1,
-};
-
-static struct platform_device nand_flash_device = {
-	.name		= "sh_flctl",
-	.resource	= nand_flash_resources,
-	.num_resources	= ARRAY_SIZE(nand_flash_resources),
-	.dev		= {
-		.platform_data = &nand_flash_data,
-	},
-};
-
-#define FPGA_LCDREG	0xB4100180
-#define FPGA_BKLREG	0xB4100212
-#define FPGA_LCDREG_VAL	0x0018
-#define PORT_MSELCRB	0xA4050182
-#define PORT_HIZCRC	0xA405015C
-#define PORT_DRVCRA	0xA405018A
-#define PORT_DRVCRB	0xA405018C
-
-static void ap320_wvga_power_on(void *board_data)
-{
-	msleep(100);
-
-	/* ASD AP-320/325 LCD ON */
-	ctrl_outw(FPGA_LCDREG_VAL, FPGA_LCDREG);
-
-	/* backlight */
-	gpio_set_value(GPIO_PTS3, 0);
-	ctrl_outw(0x100, FPGA_BKLREG);
-}
-
-static void ap320_wvga_power_off(void *board_data)
-{
-	/* backlight */
-	ctrl_outw(0, FPGA_BKLREG);
-	gpio_set_value(GPIO_PTS3, 1);
-
-	/* ASD AP-320/325 LCD OFF */
-	ctrl_outw(0, FPGA_LCDREG);
-}
-
-static struct sh_mobile_lcdc_info lcdc_info = {
-	.clock_source = LCDC_CLK_EXTERNAL,
-	.ch[0] = {
-		.chan = LCDC_CHAN_MAINLCD,
-		.bpp = 16,
-		.interface_type = RGB18,
-		.clock_divider = 1,
-		.lcd_cfg = {
-			.name = "LB070WV1",
-			.xres = 800,
-			.yres = 480,
-			.left_margin = 32,
-			.right_margin = 160,
-			.hsync_len = 8,
-			.upper_margin = 63,
-			.lower_margin = 80,
-			.vsync_len = 1,
-			.sync = 0, /* hsync and vsync are active low */
-		},
-		.lcd_size_cfg = { /* 7.0 inch */
-			.width = 152,
-			.height = 91,
-		},
-		.board_cfg = {
-			.display_on = ap320_wvga_power_on,
-			.display_off = ap320_wvga_power_off,
-		},
-	}
-};
-
-static struct resource lcdc_resources[] = {
-	[0] = {
-		.name	= "LCDC",
-		.start	= 0xfe940000, /* P4-only space */
-		.end	= 0xfe942fff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 28,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device lcdc_device = {
-	.name		= "sh_mobile_lcdc_fb",
-	.num_resources	= ARRAY_SIZE(lcdc_resources),
-	.resource	= lcdc_resources,
-	.dev		= {
-		.platform_data	= &lcdc_info,
-	},
-	.archdata = {
-		.hwblk_id = HWBLK_LCDC,
-	},
-};
-
-static void camera_power(int val)
-{
-	gpio_set_value(GPIO_PTZ5, val); /* RST_CAM/RSTB */
-	mdelay(10);
-}
-
-#ifdef CONFIG_I2C
-/* support for the old ncm03j camera */
-static unsigned char camera_ncm03j_magic[] =
-{
-	0x87, 0x00, 0x88, 0x08, 0x89, 0x01, 0x8A, 0xE8,
-	0x1D, 0x00, 0x1E, 0x8A, 0x21, 0x00, 0x33, 0x36,
-	0x36, 0x60, 0x37, 0x08, 0x3B, 0x31, 0x44, 0x0F,
-	0x46, 0xF0, 0x4B, 0x28, 0x4C, 0x21, 0x4D, 0x55,
-	0x4E, 0x1B, 0x4F, 0xC7, 0x50, 0xFC, 0x51, 0x12,
-	0x58, 0x02, 0x66, 0xC0, 0x67, 0x46, 0x6B, 0xA0,
-	0x6C, 0x34, 0x7E, 0x25, 0x7F, 0x25, 0x8D, 0x0F,
-	0x92, 0x40, 0x93, 0x04, 0x94, 0x26, 0x95, 0x0A,
-	0x99, 0x03, 0x9A, 0xF0, 0x9B, 0x14, 0x9D, 0x7A,
-	0xC5, 0x02, 0xD6, 0x07, 0x59, 0x00, 0x5A, 0x1A,
-	0x5B, 0x2A, 0x5C, 0x37, 0x5D, 0x42, 0x5E, 0x56,
-	0xC8, 0x00, 0xC9, 0x1A, 0xCA, 0x2A, 0xCB, 0x37,
-	0xCC, 0x42, 0xCD, 0x56, 0xCE, 0x00, 0xCF, 0x1A,
-	0xD0, 0x2A, 0xD1, 0x37, 0xD2, 0x42, 0xD3, 0x56,
-	0x5F, 0x68, 0x60, 0x87, 0x61, 0xA3, 0x62, 0xBC,
-	0x63, 0xD4, 0x64, 0xEA, 0xD6, 0x0F,
-};
-
-static int camera_probe(void)
-{
-	struct i2c_adapter *a = i2c_get_adapter(0);
-	struct i2c_msg msg;
-	int ret;
-
-	if (!a)
-		return -ENODEV;
-
-	camera_power(1);
-	msg.addr = 0x6e;
-	msg.buf = camera_ncm03j_magic;
-	msg.len = 2;
-	msg.flags = 0;
-	ret = i2c_transfer(a, &msg, 1);
-	camera_power(0);
-
-	return ret;
-}
-
-static int camera_set_capture(struct soc_camera_platform_info *info,
-			      int enable)
-{
-	struct i2c_adapter *a = i2c_get_adapter(0);
-	struct i2c_msg msg;
-	int ret = 0;
-	int i;
-
-	camera_power(0);
-	if (!enable)
-		return 0; /* no disable for now */
-
-	camera_power(1);
-	for (i = 0; i < ARRAY_SIZE(camera_ncm03j_magic); i += 2) {
-		u_int8_t buf[8];
-
-		msg.addr = 0x6e;
-		msg.buf = buf;
-		msg.len = 2;
-		msg.flags = 0;
-
-		buf[0] = camera_ncm03j_magic[i];
-		buf[1] = camera_ncm03j_magic[i + 1];
-
-		ret = (ret < 0) ? ret : i2c_transfer(a, &msg, 1);
-	}
-
-	return ret;
-}
-
-static int ap325rxa_camera_add(struct soc_camera_link *icl, struct device *dev);
-static void ap325rxa_camera_del(struct soc_camera_link *icl);
-
-static struct soc_camera_platform_info camera_info = {
-	.format_name = "UYVY",
-	.format_depth = 16,
-	.format = {
-		.pixelformat = V4L2_PIX_FMT_UYVY,
-		.colorspace = V4L2_COLORSPACE_SMPTE170M,
-		.width = 640,
-		.height = 480,
-	},
-	.bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
-	SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
-	.set_capture = camera_set_capture,
-	.link = {
-		.bus_id		= 0,
-		.add_device	= ap325rxa_camera_add,
-		.del_device	= ap325rxa_camera_del,
-		.module_name	= "soc_camera_platform",
-	},
-};
-
-static void dummy_release(struct device *dev)
-{
-}
-
-static struct platform_device camera_device = {
-	.name		= "soc_camera_platform",
-	.dev		= {
-		.platform_data	= &camera_info,
-		.release	= dummy_release,
-	},
-};
-
-static int ap325rxa_camera_add(struct soc_camera_link *icl,
-			       struct device *dev)
-{
-	if (icl != &camera_info.link || camera_probe() <= 0)
-		return -ENODEV;
-
-	camera_info.dev = dev;
-
-	return platform_device_register(&camera_device);
-}
-
-static void ap325rxa_camera_del(struct soc_camera_link *icl)
-{
-	if (icl != &camera_info.link)
-		return;
-
-	platform_device_unregister(&camera_device);
-	memset(&camera_device.dev.kobj, 0,
-	       sizeof(camera_device.dev.kobj));
-}
-#endif /* CONFIG_I2C */
-
-static int ov7725_power(struct device *dev, int mode)
-{
-	camera_power(0);
-	if (mode)
-		camera_power(1);
-
-	return 0;
-}
-
-static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
-	.flags = SH_CEU_FLAG_USE_8BIT_BUS,
-};
-
-static struct resource ceu_resources[] = {
-	[0] = {
-		.name	= "CEU",
-		.start	= 0xfe910000,
-		.end	= 0xfe91009f,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start  = 52,
-		.flags  = IORESOURCE_IRQ,
-	},
-	[2] = {
-		/* place holder for contiguous memory */
-	},
-};
-
-static struct platform_device ceu_device = {
-	.name		= "sh_mobile_ceu",
-	.id             = 0, /* "ceu0" clock */
-	.num_resources	= ARRAY_SIZE(ceu_resources),
-	.resource	= ceu_resources,
-	.dev		= {
-		.platform_data	= &sh_mobile_ceu_info,
-	},
-	.archdata = {
-		.hwblk_id = HWBLK_CEU,
-	},
-};
-
-struct spi_gpio_platform_data sdcard_cn3_platform_data = {
-	.sck = GPIO_PTD0,
-	.mosi = GPIO_PTD1,
-	.miso = GPIO_PTD2,
-	.num_chipselect = 1,
-};
-
-static struct platform_device sdcard_cn3_device = {
-	.name		= "spi_gpio",
-	.dev	= {
-		.platform_data	= &sdcard_cn3_platform_data,
-	},
-};
-
-static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = {
-	{
-		I2C_BOARD_INFO("pcf8563", 0x51),
-	},
-};
-
-static struct i2c_board_info ap325rxa_i2c_camera[] = {
-	{
-		I2C_BOARD_INFO("ov772x", 0x21),
-	},
-};
-
-static struct ov772x_camera_info ov7725_info = {
-	.buswidth	= SOCAM_DATAWIDTH_8,
-	.flags		= OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
-	.edgectrl	= OV772X_AUTO_EDGECTRL(0xf, 0),
-	.link = {
-		.bus_id		= 0,
-		.power		= ov7725_power,
-		.board_info	= &ap325rxa_i2c_camera[0],
-		.i2c_adapter_id	= 0,
-		.module_name	= "ov772x",
-	},
-};
-
-static struct platform_device ap325rxa_camera[] = {
-	{
-		.name	= "soc-camera-pdrv",
-		.id	= 0,
-		.dev	= {
-			.platform_data = &ov7725_info.link,
-		},
-	}, {
-		.name	= "soc-camera-pdrv",
-		.id	= 1,
-		.dev	= {
-			.platform_data = &camera_info.link,
-		},
-	},
-};
-
-static struct platform_device *ap325rxa_devices[] __initdata = {
-	&smsc9118_device,
-	&ap325rxa_nor_flash_device,
-	&lcdc_device,
-	&ceu_device,
-	&nand_flash_device,
-	&sdcard_cn3_device,
-	&ap325rxa_camera[0],
-	&ap325rxa_camera[1],
-};
-
-static struct spi_board_info ap325rxa_spi_devices[] = {
-	{
-		.modalias = "mmc_spi",
-		.max_speed_hz = 5000000,
-		.chip_select = 0,
-		.controller_data = (void *) GPIO_PTD5,
-	},
-};
-
-static int __init ap325rxa_devices_setup(void)
-{
-	/* LD3 and LD4 LEDs */
-	gpio_request(GPIO_PTX5, NULL); /* RUN */
-	gpio_direction_output(GPIO_PTX5, 1);
-	gpio_export(GPIO_PTX5, 0);
-
-	gpio_request(GPIO_PTX4, NULL); /* INDICATOR */
-	gpio_direction_output(GPIO_PTX4, 0);
-	gpio_export(GPIO_PTX4, 0);
-
-	/* SW1 input */
-	gpio_request(GPIO_PTF7, NULL); /* MODE */
-	gpio_direction_input(GPIO_PTF7);
-	gpio_export(GPIO_PTF7, 0);
-
-	/* LCDC */
-	gpio_request(GPIO_FN_LCDD15, NULL);
-	gpio_request(GPIO_FN_LCDD14, NULL);
-	gpio_request(GPIO_FN_LCDD13, NULL);
-	gpio_request(GPIO_FN_LCDD12, NULL);
-	gpio_request(GPIO_FN_LCDD11, NULL);
-	gpio_request(GPIO_FN_LCDD10, NULL);
-	gpio_request(GPIO_FN_LCDD9, NULL);
-	gpio_request(GPIO_FN_LCDD8, NULL);
-	gpio_request(GPIO_FN_LCDD7, NULL);
-	gpio_request(GPIO_FN_LCDD6, NULL);
-	gpio_request(GPIO_FN_LCDD5, NULL);
-	gpio_request(GPIO_FN_LCDD4, NULL);
-	gpio_request(GPIO_FN_LCDD3, NULL);
-	gpio_request(GPIO_FN_LCDD2, NULL);
-	gpio_request(GPIO_FN_LCDD1, NULL);
-	gpio_request(GPIO_FN_LCDD0, NULL);
-	gpio_request(GPIO_FN_LCDLCLK_PTR, NULL);
-	gpio_request(GPIO_FN_LCDDCK, NULL);
-	gpio_request(GPIO_FN_LCDVEPWC, NULL);
-	gpio_request(GPIO_FN_LCDVCPWC, NULL);
-	gpio_request(GPIO_FN_LCDVSYN, NULL);
-	gpio_request(GPIO_FN_LCDHSYN, NULL);
-	gpio_request(GPIO_FN_LCDDISP, NULL);
-	gpio_request(GPIO_FN_LCDDON, NULL);
-
-	/* LCD backlight */
-	gpio_request(GPIO_PTS3, NULL);
-	gpio_direction_output(GPIO_PTS3, 1);
-
-	/* CEU */
-	gpio_request(GPIO_FN_VIO_CLK2, NULL);
-	gpio_request(GPIO_FN_VIO_VD2, NULL);
-	gpio_request(GPIO_FN_VIO_HD2, NULL);
-	gpio_request(GPIO_FN_VIO_FLD, NULL);
-	gpio_request(GPIO_FN_VIO_CKO, NULL);
-	gpio_request(GPIO_FN_VIO_D15, NULL);
-	gpio_request(GPIO_FN_VIO_D14, NULL);
-	gpio_request(GPIO_FN_VIO_D13, NULL);
-	gpio_request(GPIO_FN_VIO_D12, NULL);
-	gpio_request(GPIO_FN_VIO_D11, NULL);
-	gpio_request(GPIO_FN_VIO_D10, NULL);
-	gpio_request(GPIO_FN_VIO_D9, NULL);
-	gpio_request(GPIO_FN_VIO_D8, NULL);
-
-	gpio_request(GPIO_PTZ7, NULL);
-	gpio_direction_output(GPIO_PTZ7, 0); /* OE_CAM */
-	gpio_request(GPIO_PTZ6, NULL);
-	gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */
-	gpio_request(GPIO_PTZ5, NULL);
-	gpio_direction_output(GPIO_PTZ5, 0); /* RST_CAM */
-	gpio_request(GPIO_PTZ4, NULL);
-	gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */
-
-	ctrl_outw(ctrl_inw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
-
-	/* FLCTL */
-	gpio_request(GPIO_FN_FCE, NULL);
-	gpio_request(GPIO_FN_NAF7, NULL);
-	gpio_request(GPIO_FN_NAF6, NULL);
-	gpio_request(GPIO_FN_NAF5, NULL);
-	gpio_request(GPIO_FN_NAF4, NULL);
-	gpio_request(GPIO_FN_NAF3, NULL);
-	gpio_request(GPIO_FN_NAF2, NULL);
-	gpio_request(GPIO_FN_NAF1, NULL);
-	gpio_request(GPIO_FN_NAF0, NULL);
-	gpio_request(GPIO_FN_FCDE, NULL);
-	gpio_request(GPIO_FN_FOE, NULL);
-	gpio_request(GPIO_FN_FSC, NULL);
-	gpio_request(GPIO_FN_FWE, NULL);
-	gpio_request(GPIO_FN_FRB, NULL);
-
-	ctrl_outw(0, PORT_HIZCRC);
-	ctrl_outw(0xFFFF, PORT_DRVCRA);
-	ctrl_outw(0xFFFF, PORT_DRVCRB);
-
-	platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20);
-
-	i2c_register_board_info(0, ap325rxa_i2c_devices,
-				ARRAY_SIZE(ap325rxa_i2c_devices));
-
-	spi_register_board_info(ap325rxa_spi_devices,
-				ARRAY_SIZE(ap325rxa_spi_devices));
-
-	return platform_add_devices(ap325rxa_devices,
-				ARRAY_SIZE(ap325rxa_devices));
-}
-arch_initcall(ap325rxa_devices_setup);
-
-/* Return the board specific boot mode pin configuration */
-static int ap325rxa_mode_pins(void)
-{
-	/* MD0=0, MD1=0, MD2=0: Clock Mode 0
-	 * MD3=0: 16-bit Area0 Bus Width
-	 * MD5=1: Little Endian
-	 * TSTMD=1, MD8=1: Test Mode Disabled
-	 */
-	return MODE_PIN5 | MODE_PIN8;
-}
-
-static struct sh_machine_vector mv_ap325rxa __initmv = {
-	.mv_name = "AP-325RXA",
-	.mv_mode_pins = ap325rxa_mode_pins,
-};
diff --git a/arch/sh/boards/mach-ap325rxa/Makefile b/arch/sh/boards/mach-ap325rxa/Makefile
new file mode 100644
index 0000000..4cf1774
--- /dev/null
+++ b/arch/sh/boards/mach-ap325rxa/Makefile
@@ -0,0 +1,2 @@
+obj-y	 := setup.o sdram.o
+
diff --git a/arch/sh/boards/mach-ap325rxa/sdram.S b/arch/sh/boards/mach-ap325rxa/sdram.S
new file mode 100644
index 0000000..db24fbe
--- /dev/null
+++ b/arch/sh/boards/mach-ap325rxa/sdram.S
@@ -0,0 +1,69 @@
+/*
+ * AP325RXA sdram self/auto-refresh setup code
+ *
+ *  Copyright (C) 2009 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/sys.h>
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/suspend.h>
+#include <asm/romimage-macros.h>
+
+/* code to enter and leave self-refresh. must be self-contained.
+ * this code will be copied to on-chip memory and executed from there.
+ */
+	.balign 4
+ENTRY(ap325rxa_sdram_enter_start)
+
+	/* SBSC: disable power down and put in self-refresh mode */
+	mov.l	1f, r4
+	mov.l	2f, r1
+	mov.l	@r4, r2
+	or	r1, r2
+	mov.l   3f, r3
+	and	r3, r2
+	mov.l	r2, @r4
+
+	rts
+	 nop
+
+	.balign 4
+1:	.long	0xfe400008 /* SDCR0 */
+2:	.long	0x00000400
+3:	.long	0xffff7fff
+ENTRY(ap325rxa_sdram_enter_end)
+
+	.balign 4
+ENTRY(ap325rxa_sdram_leave_start)
+
+	/* SBSC: set auto-refresh mode */
+	mov.l	1f, r4
+	mov.l	@r4, r0
+	mov.l   4f, r1
+	and	r1, r0
+	mov.l	r0, @r4
+	mov.l	6f, r4
+	mov.l	8f, r0
+	mov.l	@r4, r1
+	mov	#-1, r4
+	add	r4, r1
+	or	r1, r0
+	mov.l	7f, r1
+	mov.l	r0, @r1
+
+	rts
+	 nop
+
+	.balign 4
+1:	.long	0xfe400008 /* SDCR0 */
+4:	.long	0xfffffbff
+6:	.long   0xfe40001c /* RTCOR */
+7:	.long   0xfe400018 /* RTCNT */
+8:	.long   0xa55a0000
+ENTRY(ap325rxa_sdram_leave_end)
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
new file mode 100644
index 0000000..cf9dc12
--- /dev/null
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -0,0 +1,657 @@
+/*
+ * Renesas - AP-325RXA
+ * (Compatible with Algo System ., LTD. - AP-320A)
+ *
+ * Copyright (C) 2008 Renesas Solutions Corp.
+ * Author : Yusuke Goda <goda.yuske@renesas.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/sh_flctl.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/smsc911x.h>
+#include <linux/gpio.h>
+#include <media/ov772x.h>
+#include <media/soc_camera.h>
+#include <media/soc_camera_platform.h>
+#include <media/sh_mobile_ceu.h>
+#include <video/sh_mobile_lcdc.h>
+#include <asm/io.h>
+#include <asm/clock.h>
+#include <asm/suspend.h>
+#include <cpu/sh7723.h>
+
+static struct smsc911x_platform_config smsc911x_config = {
+	.phy_interface	= PHY_INTERFACE_MODE_MII,
+	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+	.flags		= SMSC911X_USE_32BIT,
+};
+
+static struct resource smsc9118_resources[] = {
+	[0] = {
+		.start	= 0xb6080000,
+		.end	= 0xb60fffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 35,
+		.end	= 35,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device smsc9118_device = {
+	.name		= "smsc911x",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(smsc9118_resources),
+	.resource	= smsc9118_resources,
+	.dev		= {
+		.platform_data = &smsc911x_config,
+	},
+};
+
+/*
+ * AP320 and AP325RXA has CPLD data in NOR Flash(0xA80000-0xABFFFF).
+ * If this area erased, this board can not boot.
+ */
+static struct mtd_partition ap325rxa_nor_flash_partitions[] = {
+	{
+		.name = "uboot",
+		.offset = 0,
+		.size = (1 * 1024 * 1024),
+		.mask_flags = MTD_WRITEABLE,	/* Read-only */
+	}, {
+		.name = "kernel",
+		.offset = MTDPART_OFS_APPEND,
+		.size = (2 * 1024 * 1024),
+	}, {
+		.name = "free-area0",
+		.offset = MTDPART_OFS_APPEND,
+		.size = ((7 * 1024 * 1024) + (512 * 1024)),
+	}, {
+		.name = "CPLD-Data",
+		.offset = MTDPART_OFS_APPEND,
+		.mask_flags = MTD_WRITEABLE,	/* Read-only */
+		.size = (1024 * 128 * 2),
+	}, {
+		.name = "free-area1",
+		.offset = MTDPART_OFS_APPEND,
+		.size = MTDPART_SIZ_FULL,
+	},
+};
+
+static struct physmap_flash_data ap325rxa_nor_flash_data = {
+	.width		= 2,
+	.parts		= ap325rxa_nor_flash_partitions,
+	.nr_parts	= ARRAY_SIZE(ap325rxa_nor_flash_partitions),
+};
+
+static struct resource ap325rxa_nor_flash_resources[] = {
+	[0] = {
+		.name	= "NOR Flash",
+		.start	= 0x00000000,
+		.end	= 0x00ffffff,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device ap325rxa_nor_flash_device = {
+	.name		= "physmap-flash",
+	.resource	= ap325rxa_nor_flash_resources,
+	.num_resources	= ARRAY_SIZE(ap325rxa_nor_flash_resources),
+	.dev		= {
+		.platform_data = &ap325rxa_nor_flash_data,
+	},
+};
+
+static struct mtd_partition nand_partition_info[] = {
+	{
+		.name	= "nand_data",
+		.offset	= 0,
+		.size	= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct resource nand_flash_resources[] = {
+	[0] = {
+		.start	= 0xa4530000,
+		.end	= 0xa45300ff,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct sh_flctl_platform_data nand_flash_data = {
+	.parts		= nand_partition_info,
+	.nr_parts	= ARRAY_SIZE(nand_partition_info),
+	.flcmncr_val	= FCKSEL_E | TYPESEL_SET | NANWF_E,
+	.has_hwecc	= 1,
+};
+
+static struct platform_device nand_flash_device = {
+	.name		= "sh_flctl",
+	.resource	= nand_flash_resources,
+	.num_resources	= ARRAY_SIZE(nand_flash_resources),
+	.dev		= {
+		.platform_data = &nand_flash_data,
+	},
+};
+
+#define FPGA_LCDREG	0xB4100180
+#define FPGA_BKLREG	0xB4100212
+#define FPGA_LCDREG_VAL	0x0018
+#define PORT_MSELCRB	0xA4050182
+#define PORT_HIZCRC	0xA405015C
+#define PORT_DRVCRA	0xA405018A
+#define PORT_DRVCRB	0xA405018C
+
+static void ap320_wvga_power_on(void *board_data)
+{
+	msleep(100);
+
+	/* ASD AP-320/325 LCD ON */
+	ctrl_outw(FPGA_LCDREG_VAL, FPGA_LCDREG);
+
+	/* backlight */
+	gpio_set_value(GPIO_PTS3, 0);
+	ctrl_outw(0x100, FPGA_BKLREG);
+}
+
+static void ap320_wvga_power_off(void *board_data)
+{
+	/* backlight */
+	ctrl_outw(0, FPGA_BKLREG);
+	gpio_set_value(GPIO_PTS3, 1);
+
+	/* ASD AP-320/325 LCD OFF */
+	ctrl_outw(0, FPGA_LCDREG);
+}
+
+static struct sh_mobile_lcdc_info lcdc_info = {
+	.clock_source = LCDC_CLK_EXTERNAL,
+	.ch[0] = {
+		.chan = LCDC_CHAN_MAINLCD,
+		.bpp = 16,
+		.interface_type = RGB18,
+		.clock_divider = 1,
+		.lcd_cfg = {
+			.name = "LB070WV1",
+			.xres = 800,
+			.yres = 480,
+			.left_margin = 32,
+			.right_margin = 160,
+			.hsync_len = 8,
+			.upper_margin = 63,
+			.lower_margin = 80,
+			.vsync_len = 1,
+			.sync = 0, /* hsync and vsync are active low */
+		},
+		.lcd_size_cfg = { /* 7.0 inch */
+			.width = 152,
+			.height = 91,
+		},
+		.board_cfg = {
+			.display_on = ap320_wvga_power_on,
+			.display_off = ap320_wvga_power_off,
+		},
+	}
+};
+
+static struct resource lcdc_resources[] = {
+	[0] = {
+		.name	= "LCDC",
+		.start	= 0xfe940000, /* P4-only space */
+		.end	= 0xfe942fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 28,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device lcdc_device = {
+	.name		= "sh_mobile_lcdc_fb",
+	.num_resources	= ARRAY_SIZE(lcdc_resources),
+	.resource	= lcdc_resources,
+	.dev		= {
+		.platform_data	= &lcdc_info,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_LCDC,
+	},
+};
+
+static void camera_power(int val)
+{
+	gpio_set_value(GPIO_PTZ5, val); /* RST_CAM/RSTB */
+	mdelay(10);
+}
+
+#ifdef CONFIG_I2C
+/* support for the old ncm03j camera */
+static unsigned char camera_ncm03j_magic[] =
+{
+	0x87, 0x00, 0x88, 0x08, 0x89, 0x01, 0x8A, 0xE8,
+	0x1D, 0x00, 0x1E, 0x8A, 0x21, 0x00, 0x33, 0x36,
+	0x36, 0x60, 0x37, 0x08, 0x3B, 0x31, 0x44, 0x0F,
+	0x46, 0xF0, 0x4B, 0x28, 0x4C, 0x21, 0x4D, 0x55,
+	0x4E, 0x1B, 0x4F, 0xC7, 0x50, 0xFC, 0x51, 0x12,
+	0x58, 0x02, 0x66, 0xC0, 0x67, 0x46, 0x6B, 0xA0,
+	0x6C, 0x34, 0x7E, 0x25, 0x7F, 0x25, 0x8D, 0x0F,
+	0x92, 0x40, 0x93, 0x04, 0x94, 0x26, 0x95, 0x0A,
+	0x99, 0x03, 0x9A, 0xF0, 0x9B, 0x14, 0x9D, 0x7A,
+	0xC5, 0x02, 0xD6, 0x07, 0x59, 0x00, 0x5A, 0x1A,
+	0x5B, 0x2A, 0x5C, 0x37, 0x5D, 0x42, 0x5E, 0x56,
+	0xC8, 0x00, 0xC9, 0x1A, 0xCA, 0x2A, 0xCB, 0x37,
+	0xCC, 0x42, 0xCD, 0x56, 0xCE, 0x00, 0xCF, 0x1A,
+	0xD0, 0x2A, 0xD1, 0x37, 0xD2, 0x42, 0xD3, 0x56,
+	0x5F, 0x68, 0x60, 0x87, 0x61, 0xA3, 0x62, 0xBC,
+	0x63, 0xD4, 0x64, 0xEA, 0xD6, 0x0F,
+};
+
+static int camera_probe(void)
+{
+	struct i2c_adapter *a = i2c_get_adapter(0);
+	struct i2c_msg msg;
+	int ret;
+
+	if (!a)
+		return -ENODEV;
+
+	camera_power(1);
+	msg.addr = 0x6e;
+	msg.buf = camera_ncm03j_magic;
+	msg.len = 2;
+	msg.flags = 0;
+	ret = i2c_transfer(a, &msg, 1);
+	camera_power(0);
+
+	return ret;
+}
+
+static int camera_set_capture(struct soc_camera_platform_info *info,
+			      int enable)
+{
+	struct i2c_adapter *a = i2c_get_adapter(0);
+	struct i2c_msg msg;
+	int ret = 0;
+	int i;
+
+	camera_power(0);
+	if (!enable)
+		return 0; /* no disable for now */
+
+	camera_power(1);
+	for (i = 0; i < ARRAY_SIZE(camera_ncm03j_magic); i += 2) {
+		u_int8_t buf[8];
+
+		msg.addr = 0x6e;
+		msg.buf = buf;
+		msg.len = 2;
+		msg.flags = 0;
+
+		buf[0] = camera_ncm03j_magic[i];
+		buf[1] = camera_ncm03j_magic[i + 1];
+
+		ret = (ret < 0) ? ret : i2c_transfer(a, &msg, 1);
+	}
+
+	return ret;
+}
+
+static int ap325rxa_camera_add(struct soc_camera_link *icl, struct device *dev);
+static void ap325rxa_camera_del(struct soc_camera_link *icl);
+
+static struct soc_camera_platform_info camera_info = {
+	.format_name = "UYVY",
+	.format_depth = 16,
+	.format = {
+		.pixelformat = V4L2_PIX_FMT_UYVY,
+		.colorspace = V4L2_COLORSPACE_SMPTE170M,
+		.width = 640,
+		.height = 480,
+	},
+	.bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
+	SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
+	.set_capture = camera_set_capture,
+	.link = {
+		.bus_id		= 0,
+		.add_device	= ap325rxa_camera_add,
+		.del_device	= ap325rxa_camera_del,
+		.module_name	= "soc_camera_platform",
+	},
+};
+
+static void dummy_release(struct device *dev)
+{
+}
+
+static struct platform_device camera_device = {
+	.name		= "soc_camera_platform",
+	.dev		= {
+		.platform_data	= &camera_info,
+		.release	= dummy_release,
+	},
+};
+
+static int ap325rxa_camera_add(struct soc_camera_link *icl,
+			       struct device *dev)
+{
+	if (icl != &camera_info.link || camera_probe() <= 0)
+		return -ENODEV;
+
+	camera_info.dev = dev;
+
+	return platform_device_register(&camera_device);
+}
+
+static void ap325rxa_camera_del(struct soc_camera_link *icl)
+{
+	if (icl != &camera_info.link)
+		return;
+
+	platform_device_unregister(&camera_device);
+	memset(&camera_device.dev.kobj, 0,
+	       sizeof(camera_device.dev.kobj));
+}
+#endif /* CONFIG_I2C */
+
+static int ov7725_power(struct device *dev, int mode)
+{
+	camera_power(0);
+	if (mode)
+		camera_power(1);
+
+	return 0;
+}
+
+static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
+	.flags = SH_CEU_FLAG_USE_8BIT_BUS,
+};
+
+static struct resource ceu_resources[] = {
+	[0] = {
+		.name	= "CEU",
+		.start	= 0xfe910000,
+		.end	= 0xfe91009f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 52,
+		.flags  = IORESOURCE_IRQ,
+	},
+	[2] = {
+		/* place holder for contiguous memory */
+	},
+};
+
+static struct platform_device ceu_device = {
+	.name		= "sh_mobile_ceu",
+	.id             = 0, /* "ceu0" clock */
+	.num_resources	= ARRAY_SIZE(ceu_resources),
+	.resource	= ceu_resources,
+	.dev		= {
+		.platform_data	= &sh_mobile_ceu_info,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_CEU,
+	},
+};
+
+static struct resource sdhi0_cn3_resources[] = {
+	[0] = {
+		.name	= "SDHI0",
+		.start	= 0x04ce0000,
+		.end	= 0x04ce01ff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 101,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device sdhi0_cn3_device = {
+	.name		= "sh_mobile_sdhi",
+	.id             = 0, /* "sdhi0" clock */
+	.num_resources	= ARRAY_SIZE(sdhi0_cn3_resources),
+	.resource	= sdhi0_cn3_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_SDHI0,
+	},
+};
+
+static struct resource sdhi1_cn7_resources[] = {
+	[0] = {
+		.name	= "SDHI1",
+		.start	= 0x04cf0000,
+		.end	= 0x04cf01ff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 24,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device sdhi1_cn7_device = {
+	.name		= "sh_mobile_sdhi",
+	.id             = 1, /* "sdhi1" clock */
+	.num_resources	= ARRAY_SIZE(sdhi1_cn7_resources),
+	.resource	= sdhi1_cn7_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_SDHI1,
+	},
+};
+
+static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("pcf8563", 0x51),
+	},
+};
+
+static struct i2c_board_info ap325rxa_i2c_camera[] = {
+	{
+		I2C_BOARD_INFO("ov772x", 0x21),
+	},
+};
+
+static struct ov772x_camera_info ov7725_info = {
+	.buswidth	= SOCAM_DATAWIDTH_8,
+	.flags		= OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
+	.edgectrl	= OV772X_AUTO_EDGECTRL(0xf, 0),
+	.link = {
+		.bus_id		= 0,
+		.power		= ov7725_power,
+		.board_info	= &ap325rxa_i2c_camera[0],
+		.i2c_adapter_id	= 0,
+		.module_name	= "ov772x",
+	},
+};
+
+static struct platform_device ap325rxa_camera[] = {
+	{
+		.name	= "soc-camera-pdrv",
+		.id	= 0,
+		.dev	= {
+			.platform_data = &ov7725_info.link,
+		},
+	}, {
+		.name	= "soc-camera-pdrv",
+		.id	= 1,
+		.dev	= {
+			.platform_data = &camera_info.link,
+		},
+	},
+};
+
+static struct platform_device *ap325rxa_devices[] __initdata = {
+	&smsc9118_device,
+	&ap325rxa_nor_flash_device,
+	&lcdc_device,
+	&ceu_device,
+	&nand_flash_device,
+	&sdhi0_cn3_device,
+	&sdhi1_cn7_device,
+	&ap325rxa_camera[0],
+	&ap325rxa_camera[1],
+};
+
+extern char ap325rxa_sdram_enter_start;
+extern char ap325rxa_sdram_enter_end;
+extern char ap325rxa_sdram_leave_start;
+extern char ap325rxa_sdram_leave_end;
+
+static int __init ap325rxa_devices_setup(void)
+{
+	/* register board specific self-refresh code */
+	sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF,
+					&ap325rxa_sdram_enter_start,
+					&ap325rxa_sdram_enter_end,
+					&ap325rxa_sdram_leave_start,
+					&ap325rxa_sdram_leave_end);
+
+	/* LD3 and LD4 LEDs */
+	gpio_request(GPIO_PTX5, NULL); /* RUN */
+	gpio_direction_output(GPIO_PTX5, 1);
+	gpio_export(GPIO_PTX5, 0);
+
+	gpio_request(GPIO_PTX4, NULL); /* INDICATOR */
+	gpio_direction_output(GPIO_PTX4, 0);
+	gpio_export(GPIO_PTX4, 0);
+
+	/* SW1 input */
+	gpio_request(GPIO_PTF7, NULL); /* MODE */
+	gpio_direction_input(GPIO_PTF7);
+	gpio_export(GPIO_PTF7, 0);
+
+	/* LCDC */
+	gpio_request(GPIO_FN_LCDD15, NULL);
+	gpio_request(GPIO_FN_LCDD14, NULL);
+	gpio_request(GPIO_FN_LCDD13, NULL);
+	gpio_request(GPIO_FN_LCDD12, NULL);
+	gpio_request(GPIO_FN_LCDD11, NULL);
+	gpio_request(GPIO_FN_LCDD10, NULL);
+	gpio_request(GPIO_FN_LCDD9, NULL);
+	gpio_request(GPIO_FN_LCDD8, NULL);
+	gpio_request(GPIO_FN_LCDD7, NULL);
+	gpio_request(GPIO_FN_LCDD6, NULL);
+	gpio_request(GPIO_FN_LCDD5, NULL);
+	gpio_request(GPIO_FN_LCDD4, NULL);
+	gpio_request(GPIO_FN_LCDD3, NULL);
+	gpio_request(GPIO_FN_LCDD2, NULL);
+	gpio_request(GPIO_FN_LCDD1, NULL);
+	gpio_request(GPIO_FN_LCDD0, NULL);
+	gpio_request(GPIO_FN_LCDLCLK_PTR, NULL);
+	gpio_request(GPIO_FN_LCDDCK, NULL);
+	gpio_request(GPIO_FN_LCDVEPWC, NULL);
+	gpio_request(GPIO_FN_LCDVCPWC, NULL);
+	gpio_request(GPIO_FN_LCDVSYN, NULL);
+	gpio_request(GPIO_FN_LCDHSYN, NULL);
+	gpio_request(GPIO_FN_LCDDISP, NULL);
+	gpio_request(GPIO_FN_LCDDON, NULL);
+
+	/* LCD backlight */
+	gpio_request(GPIO_PTS3, NULL);
+	gpio_direction_output(GPIO_PTS3, 1);
+
+	/* CEU */
+	gpio_request(GPIO_FN_VIO_CLK2, NULL);
+	gpio_request(GPIO_FN_VIO_VD2, NULL);
+	gpio_request(GPIO_FN_VIO_HD2, NULL);
+	gpio_request(GPIO_FN_VIO_FLD, NULL);
+	gpio_request(GPIO_FN_VIO_CKO, NULL);
+	gpio_request(GPIO_FN_VIO_D15, NULL);
+	gpio_request(GPIO_FN_VIO_D14, NULL);
+	gpio_request(GPIO_FN_VIO_D13, NULL);
+	gpio_request(GPIO_FN_VIO_D12, NULL);
+	gpio_request(GPIO_FN_VIO_D11, NULL);
+	gpio_request(GPIO_FN_VIO_D10, NULL);
+	gpio_request(GPIO_FN_VIO_D9, NULL);
+	gpio_request(GPIO_FN_VIO_D8, NULL);
+
+	gpio_request(GPIO_PTZ7, NULL);
+	gpio_direction_output(GPIO_PTZ7, 0); /* OE_CAM */
+	gpio_request(GPIO_PTZ6, NULL);
+	gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */
+	gpio_request(GPIO_PTZ5, NULL);
+	gpio_direction_output(GPIO_PTZ5, 0); /* RST_CAM */
+	gpio_request(GPIO_PTZ4, NULL);
+	gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */
+
+	ctrl_outw(ctrl_inw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
+
+	/* FLCTL */
+	gpio_request(GPIO_FN_FCE, NULL);
+	gpio_request(GPIO_FN_NAF7, NULL);
+	gpio_request(GPIO_FN_NAF6, NULL);
+	gpio_request(GPIO_FN_NAF5, NULL);
+	gpio_request(GPIO_FN_NAF4, NULL);
+	gpio_request(GPIO_FN_NAF3, NULL);
+	gpio_request(GPIO_FN_NAF2, NULL);
+	gpio_request(GPIO_FN_NAF1, NULL);
+	gpio_request(GPIO_FN_NAF0, NULL);
+	gpio_request(GPIO_FN_FCDE, NULL);
+	gpio_request(GPIO_FN_FOE, NULL);
+	gpio_request(GPIO_FN_FSC, NULL);
+	gpio_request(GPIO_FN_FWE, NULL);
+	gpio_request(GPIO_FN_FRB, NULL);
+
+	ctrl_outw(0, PORT_HIZCRC);
+	ctrl_outw(0xFFFF, PORT_DRVCRA);
+	ctrl_outw(0xFFFF, PORT_DRVCRB);
+
+	platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20);
+
+	/* SDHI0 - CN3 - SD CARD */
+	gpio_request(GPIO_FN_SDHI0CD_PTD, NULL);
+	gpio_request(GPIO_FN_SDHI0WP_PTD, NULL);
+	gpio_request(GPIO_FN_SDHI0D3_PTD, NULL);
+	gpio_request(GPIO_FN_SDHI0D2_PTD, NULL);
+	gpio_request(GPIO_FN_SDHI0D1_PTD, NULL);
+	gpio_request(GPIO_FN_SDHI0D0_PTD, NULL);
+	gpio_request(GPIO_FN_SDHI0CMD_PTD, NULL);
+	gpio_request(GPIO_FN_SDHI0CLK_PTD, NULL);
+
+	/* SDHI1 - CN7 - MICRO SD CARD */
+	gpio_request(GPIO_FN_SDHI1CD, NULL);
+	gpio_request(GPIO_FN_SDHI1D3, NULL);
+	gpio_request(GPIO_FN_SDHI1D2, NULL);
+	gpio_request(GPIO_FN_SDHI1D1, NULL);
+	gpio_request(GPIO_FN_SDHI1D0, NULL);
+	gpio_request(GPIO_FN_SDHI1CMD, NULL);
+	gpio_request(GPIO_FN_SDHI1CLK, NULL);
+
+	i2c_register_board_info(0, ap325rxa_i2c_devices,
+				ARRAY_SIZE(ap325rxa_i2c_devices));
+
+	return platform_add_devices(ap325rxa_devices,
+				ARRAY_SIZE(ap325rxa_devices));
+}
+arch_initcall(ap325rxa_devices_setup);
+
+/* Return the board specific boot mode pin configuration */
+static int ap325rxa_mode_pins(void)
+{
+	/* MD0=0, MD1=0, MD2=0: Clock Mode 0
+	 * MD3=0: 16-bit Area0 Bus Width
+	 * MD5=1: Little Endian
+	 * TSTMD=1, MD8=1: Test Mode Disabled
+	 */
+	return MODE_PIN5 | MODE_PIN8;
+}
+
+static struct sh_machine_vector mv_ap325rxa __initmv = {
+	.mv_name = "AP-325RXA",
+	.mv_mode_pins = ap325rxa_mode_pins,
+};
diff --git a/arch/sh/boards/mach-ecovec24/Makefile b/arch/sh/boards/mach-ecovec24/Makefile
index 51f8521..e69bc82 100644
--- a/arch/sh/boards/mach-ecovec24/Makefile
+++ b/arch/sh/boards/mach-ecovec24/Makefile
@@ -6,4 +6,4 @@
 # for more details.
 #
 
-obj-y	 := setup.o
\ No newline at end of file
+obj-y	 := setup.o sdram.o
\ No newline at end of file
diff --git a/arch/sh/boards/mach-ecovec24/sdram.S b/arch/sh/boards/mach-ecovec24/sdram.S
new file mode 100644
index 0000000..8334400
--- /dev/null
+++ b/arch/sh/boards/mach-ecovec24/sdram.S
@@ -0,0 +1,52 @@
+/*
+ * Ecovec24 sdram self/auto-refresh setup code
+ *
+ *  Copyright (C) 2009 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/sys.h>
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/suspend.h>
+#include <asm/romimage-macros.h>
+
+/* code to enter and leave self-refresh. must be self-contained.
+ * this code will be copied to on-chip memory and executed from there.
+ */
+	.balign 4
+ENTRY(ecovec24_sdram_enter_start)
+
+	/* DBSC: put memory in self-refresh mode */
+
+	ED 0xFD000010, 0x00000000 /* DBEN */
+	ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+	ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+	ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+	ED 0xFD000040, 0x00000001 /* DBRFPDN0 */
+
+	rts
+	 nop
+
+ENTRY(ecovec24_sdram_enter_end)
+
+	.balign 4
+ENTRY(ecovec24_sdram_leave_start)
+
+	/* DBSC: put memory in auto-refresh mode */
+
+	ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+	WAIT 1
+	ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+	ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+	ED 0xFD000010, 0x00000001 /* DBEN */
+	ED 0xFD000040, 0x00010000 /* DBRFPDN0 */
+
+	rts
+	 nop
+
+ENTRY(ecovec24_sdram_leave_end)
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 3b1ceb4..826e623 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -20,12 +20,14 @@
 #include <linux/i2c.h>
 #include <linux/i2c/tsc2007.h>
 #include <linux/input.h>
+#include <linux/input/sh_keysc.h>
+#include <linux/mfd/sh_mobile_sdhi.h>
 #include <video/sh_mobile_lcdc.h>
 #include <media/sh_mobile_ceu.h>
 #include <asm/heartbeat.h>
 #include <asm/sh_eth.h>
-#include <asm/sh_keysc.h>
 #include <asm/clock.h>
+#include <asm/suspend.h>
 #include <cpu/sh7724.h>
 
 /*
@@ -147,6 +149,9 @@
 	},
 	.num_resources = ARRAY_SIZE(sh_eth_resources),
 	.resource = sh_eth_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_ETHER,
+	},
 };
 
 /* USB0 host */
@@ -185,30 +190,18 @@
 	.resource	= usb0_host_resources,
 };
 
-/*
- * USB1
- *
- * CN5 can use both host/function,
- * and we can determine it by checking PTB[3]
- *
- * This time only USB1 host is supported.
- */
+/* USB1 host/function */
 void usb1_port_power(int port, int power)
 {
-	if (!gpio_get_value(GPIO_PTB3)) {
-		printk(KERN_ERR "USB1 function is not supported\n");
-		return;
-	}
-
 	gpio_set_value(GPIO_PTB5, power);
 }
 
-static struct r8a66597_platdata usb1_host_data = {
+static struct r8a66597_platdata usb1_common_data = {
 	.on_chip = 1,
 	.port_power = usb1_port_power,
 };
 
-static struct resource usb1_host_resources[] = {
+static struct resource usb1_common_resources[] = {
 	[0] = {
 		.start	= 0xa4d90000,
 		.end	= 0xa4d90124 - 1,
@@ -221,16 +214,16 @@
 	},
 };
 
-static struct platform_device usb1_host_device = {
-	.name		= "r8a66597_hcd",
+static struct platform_device usb1_common_device = {
+	/* .name will be added in arch_setup */
 	.id		= 1,
 	.dev = {
 		.dma_mask		= NULL,         /*  not use dma */
 		.coherent_dma_mask	= 0xffffffff,
-		.platform_data		= &usb1_host_data,
+		.platform_data		= &usb1_common_data,
 	},
-	.num_resources	= ARRAY_SIZE(usb1_host_resources),
-	.resource	= usb1_host_resources,
+	.num_resources	= ARRAY_SIZE(usb1_common_resources),
+	.resource	= usb1_common_resources,
 };
 
 /* LCDC */
@@ -428,16 +421,90 @@
 	.irq		= IRQ0,
 };
 
+/* SHDI0 */
+static void sdhi0_set_pwr(struct platform_device *pdev, int state)
+{
+	gpio_set_value(GPIO_PTB6, state);
+}
+
+static struct sh_mobile_sdhi_info sdhi0_info = {
+	.set_pwr = sdhi0_set_pwr,
+};
+
+static struct resource sdhi0_resources[] = {
+	[0] = {
+		.name	= "SDHI0",
+		.start  = 0x04ce0000,
+		.end    = 0x04ce01ff,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 101,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device sdhi0_device = {
+	.name           = "sh_mobile_sdhi",
+	.num_resources  = ARRAY_SIZE(sdhi0_resources),
+	.resource       = sdhi0_resources,
+	.id             = 0,
+	.dev	= {
+		.platform_data	= &sdhi0_info,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_SDHI0,
+	},
+};
+
+/* SHDI1 */
+static void sdhi1_set_pwr(struct platform_device *pdev, int state)
+{
+	gpio_set_value(GPIO_PTB7, state);
+}
+
+static struct sh_mobile_sdhi_info sdhi1_info = {
+	.set_pwr = sdhi1_set_pwr,
+};
+
+static struct resource sdhi1_resources[] = {
+	[0] = {
+		.name	= "SDHI1",
+		.start  = 0x04cf0000,
+		.end    = 0x04cf01ff,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 24,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device sdhi1_device = {
+	.name           = "sh_mobile_sdhi",
+	.num_resources  = ARRAY_SIZE(sdhi1_resources),
+	.resource       = sdhi1_resources,
+	.id             = 1,
+	.dev	= {
+		.platform_data	= &sdhi1_info,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_SDHI1,
+	},
+};
+
 static struct platform_device *ecovec_devices[] __initdata = {
 	&heartbeat_device,
 	&nor_flash_device,
 	&sh_eth_device,
 	&usb0_host_device,
-	&usb1_host_device, /* USB1 host support */
+	&usb1_common_device,
 	&lcdc_device,
 	&ceu0_device,
 	&ceu1_device,
 	&keysc_device,
+	&sdhi0_device,
+	&sdhi1_device,
 };
 
 #define EEPROM_ADDR 0x50
@@ -466,12 +533,9 @@
 	return buf;
 }
 
-#define MAC_LEN 6
-static void __init sh_eth_init(void)
+static void __init sh_eth_init(struct sh_eth_plat_data *pd)
 {
 	struct i2c_adapter *a = i2c_get_adapter(1);
-	struct clk *eth_clk;
-	u8 mac[MAC_LEN];
 	int i;
 
 	if (!a) {
@@ -479,39 +543,30 @@
 		return;
 	}
 
-	eth_clk = clk_get(NULL, "eth0");
-	if (!eth_clk) {
-		pr_err("can not get eth0 clk\n");
-		return;
-	}
-
 	/* read MAC address frome EEPROM */
-	for (i = 0; i < MAC_LEN; i++) {
-		mac[i] = mac_read(a, 0x10 + i);
+	for (i = 0; i < sizeof(pd->mac_addr); i++) {
+		pd->mac_addr[i] = mac_read(a, 0x10 + i);
 		msleep(10);
 	}
-
-	/* clock enable */
-	clk_enable(eth_clk);
-
-	/* reset sh-eth */
-	ctrl_outl(0x1, SH_ETH_ADDR + 0x0);
-
-	/* set MAC addr */
-	ctrl_outl((mac[0] << 24) |
-		  (mac[1] << 16) |
-		  (mac[2] <<  8) |
-		  (mac[3] <<  0), SH_ETH_MAHR);
-	ctrl_outl((mac[4] <<  8) |
-		  (mac[5] <<  0), SH_ETH_MALR);
-
-	clk_put(eth_clk);
 }
 
 #define PORT_HIZA 0xA4050158
 #define IODRIVEA  0xA405018A
+
+extern char ecovec24_sdram_enter_start;
+extern char ecovec24_sdram_enter_end;
+extern char ecovec24_sdram_leave_start;
+extern char ecovec24_sdram_leave_end;
+
 static int __init arch_setup(void)
 {
+	/* register board specific self-refresh code */
+	sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF,
+					&ecovec24_sdram_enter_start,
+					&ecovec24_sdram_enter_end,
+					&ecovec24_sdram_leave_start,
+					&ecovec24_sdram_leave_end);
+
 	/* enable STATUS0, STATUS2 and PDSTATUS */
 	gpio_request(GPIO_FN_STATUS0, NULL);
 	gpio_request(GPIO_FN_STATUS2, NULL);
@@ -561,6 +616,14 @@
 	ctrl_outw(0x0600, 0xa40501d4);
 	ctrl_outw(0x0600, 0xa4050192);
 
+	if (gpio_get_value(GPIO_PTB3)) {
+		printk(KERN_INFO "USB1 function is selected\n");
+		usb1_common_device.name = "r8a66597_udc";
+	} else {
+		printk(KERN_INFO "USB1 host is selected\n");
+		usb1_common_device.name = "r8a66597_hcd";
+	}
+
 	/* enable LCDC */
 	gpio_request(GPIO_FN_LCDD23,   NULL);
 	gpio_request(GPIO_FN_LCDD22,   NULL);
@@ -603,8 +666,8 @@
 	gpio_direction_output(GPIO_PTR1, 0);
 	gpio_direction_output(GPIO_PTA2, 0);
 
-	/* I/O buffer drive ability is low */
-	ctrl_outw((ctrl_inw(IODRIVEA) & ~0x00c0) | 0x0040 , IODRIVEA);
+	/* I/O buffer drive ability is high */
+	ctrl_outw((ctrl_inw(IODRIVEA) & ~0x00c0) | 0x0080 , IODRIVEA);
 
 	if (gpio_get_value(GPIO_PTE6)) {
 		/* DVI */
@@ -710,6 +773,33 @@
 	gpio_direction_input(GPIO_PTR5);
 	gpio_direction_input(GPIO_PTR6);
 
+	/* enable SDHI0 (needs DS2.4 set to ON) */
+	gpio_request(GPIO_FN_SDHI0CD,  NULL);
+	gpio_request(GPIO_FN_SDHI0WP,  NULL);
+	gpio_request(GPIO_FN_SDHI0CMD, NULL);
+	gpio_request(GPIO_FN_SDHI0CLK, NULL);
+	gpio_request(GPIO_FN_SDHI0D3,  NULL);
+	gpio_request(GPIO_FN_SDHI0D2,  NULL);
+	gpio_request(GPIO_FN_SDHI0D1,  NULL);
+	gpio_request(GPIO_FN_SDHI0D0,  NULL);
+	gpio_request(GPIO_PTB6, NULL);
+	gpio_direction_output(GPIO_PTB6, 0);
+
+	/* enable SDHI1 (needs DS2.6,7 set to ON,OFF) */
+	gpio_request(GPIO_FN_SDHI1CD,  NULL);
+	gpio_request(GPIO_FN_SDHI1WP,  NULL);
+	gpio_request(GPIO_FN_SDHI1CMD, NULL);
+	gpio_request(GPIO_FN_SDHI1CLK, NULL);
+	gpio_request(GPIO_FN_SDHI1D3,  NULL);
+	gpio_request(GPIO_FN_SDHI1D2,  NULL);
+	gpio_request(GPIO_FN_SDHI1D1,  NULL);
+	gpio_request(GPIO_FN_SDHI1D0,  NULL);
+	gpio_request(GPIO_PTB7, NULL);
+	gpio_direction_output(GPIO_PTB7, 0);
+
+	/* I/O buffer drive ability is high for SDHI1 */
+	ctrl_outw((ctrl_inw(IODRIVEA) & ~0x3000) | 0x2000 , IODRIVEA);
+
 	/* enable I2C device */
 	i2c_register_board_info(1, i2c1_devices,
 				ARRAY_SIZE(i2c1_devices));
@@ -721,12 +811,11 @@
 
 static int __init devices_setup(void)
 {
-	sh_eth_init();
+	sh_eth_init(&sh_eth_plat);
 	return 0;
 }
 device_initcall(devices_setup);
 
-
 static struct sh_machine_vector mv_ecovec __initmv = {
 	.mv_name	= "R0P7724 (EcoVec)",
 };
diff --git a/arch/sh/boards/mach-highlander/setup.c b/arch/sh/boards/mach-highlander/setup.c
index 566e69d..f663c14 100644
--- a/arch/sh/boards/mach-highlander/setup.c
+++ b/arch/sh/boards/mach-highlander/setup.c
@@ -384,7 +384,7 @@
 
 static int highlander_irq_demux(int irq)
 {
-	if (irq >= HL_NR_IRL || !irl2irq[irq])
+	if (irq >= HL_NR_IRL || irq < 0 || !irl2irq[irq])
 		return irq;
 
 	return irl2irq[irq];
diff --git a/arch/sh/boards/mach-kfr2r09/Makefile b/arch/sh/boards/mach-kfr2r09/Makefile
index 5d58678..4e577a3 100644
--- a/arch/sh/boards/mach-kfr2r09/Makefile
+++ b/arch/sh/boards/mach-kfr2r09/Makefile
@@ -1,2 +1,2 @@
-obj-y	 := setup.o
+obj-y	 := setup.o sdram.o
 obj-$(CONFIG_FB_SH_MOBILE_LCDC)	+=  lcd_wqvga.o
diff --git a/arch/sh/boards/mach-kfr2r09/sdram.S b/arch/sh/boards/mach-kfr2r09/sdram.S
new file mode 100644
index 0000000..0c9f55b
--- /dev/null
+++ b/arch/sh/boards/mach-kfr2r09/sdram.S
@@ -0,0 +1,80 @@
+/*
+ * KFR2R09 sdram self/auto-refresh setup code
+ *
+ *  Copyright (C) 2009 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/sys.h>
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/suspend.h>
+#include <asm/romimage-macros.h>
+
+/* code to enter and leave self-refresh. must be self-contained.
+ * this code will be copied to on-chip memory and executed from there.
+ */
+	.balign 4
+ENTRY(kfr2r09_sdram_enter_start)
+
+	/* DBSC: put memory in self-refresh mode */
+
+	ED 0xFD000010, 0x00000000 /* DBEN */
+	ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+	ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+	ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+	ED 0xFD000040, 0x00000001 /* DBRFPDN0 */
+
+	rts
+	 nop
+
+ENTRY(kfr2r09_sdram_enter_end)
+
+	.balign 4
+ENTRY(kfr2r09_sdram_leave_start)
+
+	/* DBSC: put memory in auto-refresh mode */
+
+	mov.l	@(SH_SLEEP_MODE, r5), r0
+	tst	#SUSP_SH_RSTANDBY, r0
+	bf	resume_rstandby
+
+	ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+	WAIT 1
+	ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+	ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+	ED 0xFD000010, 0x00000001 /* DBEN */
+	ED 0xFD000040, 0x00010000 /* DBRFPDN0 */
+
+	rts
+	 nop
+
+resume_rstandby:
+
+	/* DBSC: re-initialize and put in auto-refresh */
+
+	ED 0xFD000108, 0x40000301 /* DBPDCNT0 */
+	ED 0xFD000020, 0x011B0002 /* DBCONF */
+	ED 0xFD000030, 0x03060E02 /* DBTR0 */
+	ED 0xFD000034, 0x01020102 /* DBTR1 */
+	ED 0xFD000038, 0x01090406 /* DBTR2 */
+	ED 0xFD000008, 0x00000004 /* DBKIND */
+	ED 0xFD000040, 0x00000001 /* DBRFPDN0 */
+	ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+	ED 0xFD000018, 0x00000001 /* DBCKECNT */
+	WAIT 1
+	ED 0xFD000010, 0x00000001 /* DBEN */
+	ED 0xFD000044, 0x000004AF /* DBRFPDN1 */
+	ED 0xFD000048, 0x20CF0037 /* DBRFPDN2 */
+	ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+	ED 0xFD000108, 0x40000300 /* DBPDCNT0 */
+	ED 0xFD000040, 0x00010000 /* DBRFPDN0 */
+
+	rts
+	 nop
+
+ENTRY(kfr2r09_sdram_leave_end)
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
index c08d33f..87438d6 100644
--- a/arch/sh/boards/mach-kfr2r09/setup.c
+++ b/arch/sh/boards/mach-kfr2r09/setup.c
@@ -16,13 +16,16 @@
 #include <linux/clk.h>
 #include <linux/gpio.h>
 #include <linux/input.h>
+#include <linux/input/sh_keysc.h>
 #include <linux/i2c.h>
 #include <linux/usb/r8a66597.h>
+#include <media/soc_camera.h>
+#include <media/sh_mobile_ceu.h>
 #include <video/sh_mobile_lcdc.h>
+#include <asm/suspend.h>
 #include <asm/clock.h>
 #include <asm/machvec.h>
 #include <asm/io.h>
-#include <asm/sh_keysc.h>
 #include <cpu/sh7724.h>
 #include <mach/kfr2r09.h>
 
@@ -212,11 +215,154 @@
 	.resource	= kfr2r09_usb0_gadget_resources,
 };
 
+static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
+	.flags = SH_CEU_FLAG_USE_8BIT_BUS,
+};
+
+static struct resource kfr2r09_ceu_resources[] = {
+	[0] = {
+		.name	= "CEU",
+		.start	= 0xfe910000,
+		.end	= 0xfe91009f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 52,
+		.end  = 52,
+		.flags  = IORESOURCE_IRQ,
+	},
+	[2] = {
+		/* place holder for contiguous memory */
+	},
+};
+
+static struct platform_device kfr2r09_ceu_device = {
+	.name		= "sh_mobile_ceu",
+	.id             = 0, /* "ceu0" clock */
+	.num_resources	= ARRAY_SIZE(kfr2r09_ceu_resources),
+	.resource	= kfr2r09_ceu_resources,
+	.dev	= {
+		.platform_data	= &sh_mobile_ceu_info,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_CEU0,
+	},
+};
+
+static struct i2c_board_info kfr2r09_i2c_camera = {
+	I2C_BOARD_INFO("rj54n1cb0c", 0x50),
+};
+
+static struct clk *camera_clk;
+
+#define DRVCRB 0xA405018C
+static int camera_power(struct device *dev, int mode)
+{
+	int ret;
+
+	if (mode) {
+		long rate;
+
+		camera_clk = clk_get(NULL, "video_clk");
+		if (IS_ERR(camera_clk))
+			return PTR_ERR(camera_clk);
+
+		/* set VIO_CKO clock to 25MHz */
+		rate = clk_round_rate(camera_clk, 25000000);
+		ret = clk_set_rate(camera_clk, rate);
+		if (ret < 0)
+			goto eclkrate;
+
+		/* set DRVCRB
+		 *
+		 * use 1.8 V for VccQ_VIO
+		 * use 2.85V for VccQ_SR
+		 */
+		ctrl_outw((ctrl_inw(DRVCRB) & ~0x0003) | 0x0001, DRVCRB);
+
+		/* reset clear */
+		ret = gpio_request(GPIO_PTB4, NULL);
+		if (ret < 0)
+			goto eptb4;
+		ret = gpio_request(GPIO_PTB7, NULL);
+		if (ret < 0)
+			goto eptb7;
+
+		ret = gpio_direction_output(GPIO_PTB4, 1);
+		if (!ret)
+			ret = gpio_direction_output(GPIO_PTB7, 1);
+		if (ret < 0)
+			goto egpioout;
+		msleep(1);
+
+		ret = clk_enable(camera_clk);	/* start VIO_CKO */
+		if (ret < 0)
+			goto eclkon;
+
+		return 0;
+	}
+
+	ret = 0;
+
+	clk_disable(camera_clk);
+eclkon:
+	gpio_set_value(GPIO_PTB7, 0);
+egpioout:
+	gpio_set_value(GPIO_PTB4, 0);
+	gpio_free(GPIO_PTB7);
+eptb7:
+	gpio_free(GPIO_PTB4);
+eptb4:
+eclkrate:
+	clk_put(camera_clk);
+	return ret;
+}
+
+static struct soc_camera_link rj54n1_link = {
+	.power		= camera_power,
+	.board_info	= &kfr2r09_i2c_camera,
+	.i2c_adapter_id	= 1,
+	.module_name	= "rj54n1cb0c",
+};
+
+static struct platform_device kfr2r09_camera = {
+	.name	= "soc-camera-pdrv",
+	.id	= 0,
+	.dev	= {
+		.platform_data = &rj54n1_link,
+	},
+};
+
+static struct resource kfr2r09_sh_sdhi0_resources[] = {
+	[0] = {
+		.name	= "SDHI0",
+		.start  = 0x04ce0000,
+		.end    = 0x04ce01ff,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 101,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device kfr2r09_sh_sdhi0_device = {
+	.name           = "sh_mobile_sdhi",
+	.num_resources  = ARRAY_SIZE(kfr2r09_sh_sdhi0_resources),
+	.resource       = kfr2r09_sh_sdhi0_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_SDHI0,
+	},
+};
+
 static struct platform_device *kfr2r09_devices[] __initdata = {
 	&kfr2r09_nor_flash_device,
 	&kfr2r09_nand_flash_device,
 	&kfr2r09_sh_keysc_device,
 	&kfr2r09_sh_lcdc_device,
+	&kfr2r09_ceu_device,
+	&kfr2r09_camera,
+	&kfr2r09_sh_sdhi0_device,
 };
 
 #define BSC_CS0BCR 0xfec10004
@@ -268,11 +414,59 @@
 
 	return 0;
 }
+
+static int kfr2r09_serial_i2c_setup(void)
+{
+	struct i2c_adapter *a;
+	struct i2c_msg msg;
+	unsigned char buf[2];
+	int ret;
+
+	a = i2c_get_adapter(0);
+	if (!a)
+		return -ENODEV;
+
+	/* set bit 6 (the 7th bit) of chip at 0x09, register 0x13 */
+	buf[0] = 0x13;
+	msg.addr = 0x09;
+	msg.buf = buf;
+	msg.len = 1;
+	msg.flags = 0;
+	ret = i2c_transfer(a, &msg, 1);
+	if (ret != 1)
+		return -ENODEV;
+
+	buf[0] = 0;
+	msg.addr = 0x09;
+	msg.buf = buf;
+	msg.len = 1;
+	msg.flags = I2C_M_RD;
+	ret = i2c_transfer(a, &msg, 1);
+	if (ret != 1)
+		return -ENODEV;
+
+	buf[1] = buf[0] | (1 << 6);
+	buf[0] = 0x13;
+	msg.addr = 0x09;
+	msg.buf = buf;
+	msg.len = 2;
+	msg.flags = 0;
+	ret = i2c_transfer(a, &msg, 1);
+	if (ret != 1)
+		return -ENODEV;
+
+	return 0;
+}
 #else
 static int kfr2r09_usb0_gadget_i2c_setup(void)
 {
 	return -ENODEV;
 }
+
+static int kfr2r09_serial_i2c_setup(void)
+{
+	return -ENODEV;
+}
 #endif
 
 static int kfr2r09_usb0_gadget_setup(void)
@@ -299,11 +493,27 @@
 	return 0;
 }
 
+extern char kfr2r09_sdram_enter_start;
+extern char kfr2r09_sdram_enter_end;
+extern char kfr2r09_sdram_leave_start;
+extern char kfr2r09_sdram_leave_end;
+
 static int __init kfr2r09_devices_setup(void)
 {
+	/* register board specific self-refresh code */
+	sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF |
+					SUSP_SH_RSTANDBY,
+					&kfr2r09_sdram_enter_start,
+					&kfr2r09_sdram_enter_end,
+					&kfr2r09_sdram_leave_start,
+					&kfr2r09_sdram_leave_end);
+
 	/* enable SCIF1 serial port for YC401 console support */
 	gpio_request(GPIO_FN_SCIF1_RXD, NULL);
 	gpio_request(GPIO_FN_SCIF1_TXD, NULL);
+	kfr2r09_serial_i2c_setup(); /* ECONTMSK(bit6=L10ONEN) set 1 */
+	gpio_request(GPIO_PTG3, NULL); /* HPON_ON */
+	gpio_direction_output(GPIO_PTG3, 1); /* HPON_ON = H */
 
 	/* setup NOR flash at CS0 */
 	ctrl_outl(0x36db0400, BSC_CS0BCR);
@@ -361,6 +571,32 @@
 	if (kfr2r09_usb0_gadget_setup() == 0)
 		platform_device_register(&kfr2r09_usb0_gadget_device);
 
+	/* CEU */
+	gpio_request(GPIO_FN_VIO_CKO, NULL);
+	gpio_request(GPIO_FN_VIO0_CLK, NULL);
+	gpio_request(GPIO_FN_VIO0_VD, NULL);
+	gpio_request(GPIO_FN_VIO0_HD, NULL);
+	gpio_request(GPIO_FN_VIO0_FLD, NULL);
+	gpio_request(GPIO_FN_VIO0_D7, NULL);
+	gpio_request(GPIO_FN_VIO0_D6, NULL);
+	gpio_request(GPIO_FN_VIO0_D5, NULL);
+	gpio_request(GPIO_FN_VIO0_D4, NULL);
+	gpio_request(GPIO_FN_VIO0_D3, NULL);
+	gpio_request(GPIO_FN_VIO0_D2, NULL);
+	gpio_request(GPIO_FN_VIO0_D1, NULL);
+	gpio_request(GPIO_FN_VIO0_D0, NULL);
+
+	platform_resource_setup_memory(&kfr2r09_ceu_device, "ceu", 4 << 20);
+
+	/* SDHI0 connected to yc304 */
+	gpio_request(GPIO_FN_SDHI0CD, NULL);
+	gpio_request(GPIO_FN_SDHI0D3, NULL);
+	gpio_request(GPIO_FN_SDHI0D2, NULL);
+	gpio_request(GPIO_FN_SDHI0D1, NULL);
+	gpio_request(GPIO_FN_SDHI0D0, NULL);
+	gpio_request(GPIO_FN_SDHI0CMD, NULL);
+	gpio_request(GPIO_FN_SDHI0CLK, NULL);
+
 	return platform_add_devices(kfr2r09_devices,
 				    ARRAY_SIZE(kfr2r09_devices));
 }
diff --git a/arch/sh/boards/mach-migor/Makefile b/arch/sh/boards/mach-migor/Makefile
index 5f231dd..4601a89 100644
--- a/arch/sh/boards/mach-migor/Makefile
+++ b/arch/sh/boards/mach-migor/Makefile
@@ -1,2 +1,2 @@
-obj-y	 := setup.o
+obj-y	 := setup.o sdram.o
 obj-$(CONFIG_SH_MIGOR_QVGA)	+=  lcd_qvga.o
diff --git a/arch/sh/boards/mach-migor/sdram.S b/arch/sh/boards/mach-migor/sdram.S
new file mode 100644
index 0000000..614aa3a
--- /dev/null
+++ b/arch/sh/boards/mach-migor/sdram.S
@@ -0,0 +1,69 @@
+/*
+ * Migo-R sdram self/auto-refresh setup code
+ *
+ *  Copyright (C) 2009 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/sys.h>
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/suspend.h>
+#include <asm/romimage-macros.h>
+
+/* code to enter and leave self-refresh. must be self-contained.
+ * this code will be copied to on-chip memory and executed from there.
+ */
+	.balign 4
+ENTRY(migor_sdram_enter_start)
+
+	/* SBSC: disable power down and put in self-refresh mode */
+	mov.l	1f, r4
+	mov.l	2f, r1
+	mov.l	@r4, r2
+	or	r1, r2
+	mov.l   3f, r3
+	and	r3, r2
+	mov.l	r2, @r4
+
+	rts
+	 nop
+
+	.balign 4
+1:	.long	0xfe400008 /* SDCR0 */
+2:	.long	0x00000400
+3:	.long	0xffff7fff
+ENTRY(migor_sdram_enter_end)
+
+	.balign 4
+ENTRY(migor_sdram_leave_start)
+
+	/* SBSC: set auto-refresh mode */
+	mov.l	1f, r4
+	mov.l	@r4, r0
+	mov.l   4f, r1
+	and	r1, r0
+	mov.l	r0, @r4
+	mov.l	6f, r4
+	mov.l	8f, r0
+	mov.l	@r4, r1
+	mov	#-1, r4
+	add	r4, r1
+	or	r1, r0
+	mov.l	7f, r1
+	mov.l	r0, @r1
+
+	rts
+	 nop
+
+	.balign 4
+1:	.long	0xfe400008 /* SDCR0 */
+4:	.long	0xfffffbff
+6:	.long   0xfe40001c /* RTCOR */
+7:	.long   0xfe400018 /* RTCNT */
+8:	.long   0xa55a0000
+ENTRY(migor_sdram_leave_end)
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 6ed1fd3..9099b6d 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -11,6 +11,7 @@
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/input.h>
+#include <linux/input/sh_keysc.h>
 #include <linux/mtd/physmap.h>
 #include <linux/mtd/nand.h>
 #include <linux/i2c.h>
@@ -18,8 +19,6 @@
 #include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/gpio.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/spi_gpio.h>
 #include <video/sh_mobile_lcdc.h>
 #include <media/sh_mobile_ceu.h>
 #include <media/ov772x.h>
@@ -27,7 +26,7 @@
 #include <asm/clock.h>
 #include <asm/machvec.h>
 #include <asm/io.h>
-#include <asm/sh_keysc.h>
+#include <asm/suspend.h>
 #include <mach/migor.h>
 #include <cpu/sh7722.h>
 
@@ -390,17 +389,25 @@
 	},
 };
 
-struct spi_gpio_platform_data sdcard_cn9_platform_data = {
-	.sck = GPIO_PTD0,
-	.mosi = GPIO_PTD1,
-	.miso = GPIO_PTD2,
-	.num_chipselect = 1,
+static struct resource sdhi_cn9_resources[] = {
+	[0] = {
+		.name	= "SDHI",
+		.start	= 0x04ce0000,
+		.end	= 0x04ce01ff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 101,
+		.flags  = IORESOURCE_IRQ,
+	},
 };
 
-static struct platform_device sdcard_cn9_device = {
-	.name		= "spi_gpio",
-	.dev	= {
-		.platform_data	= &sdcard_cn9_platform_data,
+static struct platform_device sdhi_cn9_device = {
+	.name		= "sh_mobile_sdhi",
+	.num_resources	= ARRAY_SIZE(sdhi_cn9_resources),
+	.resource	= sdhi_cn9_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_SDHI,
 	},
 };
 
@@ -467,23 +474,24 @@
 	&migor_ceu_device,
 	&migor_nor_flash_device,
 	&migor_nand_flash_device,
-	&sdcard_cn9_device,
+	&sdhi_cn9_device,
 	&migor_camera[0],
 	&migor_camera[1],
 };
 
-static struct spi_board_info migor_spi_devices[] = {
-	{
-		.modalias = "mmc_spi",
-		.max_speed_hz = 5000000,
-		.chip_select = 0,
-		.controller_data = (void *) GPIO_PTD5,
-	},
-};
+extern char migor_sdram_enter_start;
+extern char migor_sdram_enter_end;
+extern char migor_sdram_leave_start;
+extern char migor_sdram_leave_end;
 
 static int __init migor_devices_setup(void)
 {
-
+	/* register board specific self-refresh code */
+	sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF,
+					&migor_sdram_enter_start,
+					&migor_sdram_enter_end,
+					&migor_sdram_leave_start,
+					&migor_sdram_leave_end);
 #ifdef CONFIG_PM
 	/* Let D11 LED show STATUS0 */
 	gpio_request(GPIO_FN_STATUS0, NULL);
@@ -525,6 +533,16 @@
 	gpio_request(GPIO_PTA1, NULL);
 	gpio_direction_input(GPIO_PTA1);
 
+	/* SDHI */
+	gpio_request(GPIO_FN_SDHICD, NULL);
+	gpio_request(GPIO_FN_SDHIWP, NULL);
+	gpio_request(GPIO_FN_SDHID3, NULL);
+	gpio_request(GPIO_FN_SDHID2, NULL);
+	gpio_request(GPIO_FN_SDHID1, NULL);
+	gpio_request(GPIO_FN_SDHID0, NULL);
+	gpio_request(GPIO_FN_SDHICMD, NULL);
+	gpio_request(GPIO_FN_SDHICLK, NULL);
+
 	/* Touch Panel */
 	gpio_request(GPIO_FN_IRQ6, NULL);
 
@@ -612,9 +630,6 @@
 	i2c_register_board_info(0, migor_i2c_devices,
 				ARRAY_SIZE(migor_i2c_devices));
 
-	spi_register_board_info(migor_spi_devices,
-				ARRAY_SIZE(migor_spi_devices));
-
 	return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices));
 }
 arch_initcall(migor_devices_setup);
diff --git a/arch/sh/boards/mach-r2d/irq.c b/arch/sh/boards/mach-r2d/irq.c
index c70fece..78d7b27 100644
--- a/arch/sh/boards/mach-r2d/irq.c
+++ b/arch/sh/boards/mach-r2d/irq.c
@@ -116,7 +116,7 @@
 
 int rts7751r2d_irq_demux(int irq)
 {
-	if (irq >= R2D_NR_IRL || !irl2irq[irq])
+	if (irq >= R2D_NR_IRL || irq < 0 || !irl2irq[irq])
 		return irq;
 
 	return irl2irq[irq];
diff --git a/arch/sh/boards/mach-se/7722/irq.c b/arch/sh/boards/mach-se/7722/irq.c
index 02d21a3..4eb31ac 100644
--- a/arch/sh/boards/mach-se/7722/irq.c
+++ b/arch/sh/boards/mach-se/7722/irq.c
@@ -16,15 +16,17 @@
 #include <asm/io.h>
 #include <mach-se/mach/se7722.h>
 
+unsigned int se7722_fpga_irq[SE7722_FPGA_IRQ_NR] = { 0, };
+
 static void disable_se7722_irq(unsigned int irq)
 {
-	unsigned int bit = irq - SE7722_FPGA_IRQ_BASE;
+	unsigned int bit = (unsigned int)get_irq_chip_data(irq);
 	ctrl_outw(ctrl_inw(IRQ01_MASK) | 1 << bit, IRQ01_MASK);
 }
 
 static void enable_se7722_irq(unsigned int irq)
 {
-	unsigned int bit = irq - SE7722_FPGA_IRQ_BASE;
+	unsigned int bit = (unsigned int)get_irq_chip_data(irq);
 	ctrl_outw(ctrl_inw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK);
 }
 
@@ -38,18 +40,15 @@
 static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc)
 {
 	unsigned short intv = ctrl_inw(IRQ01_STS);
-	struct irq_desc *ext_desc;
-	unsigned int ext_irq = SE7722_FPGA_IRQ_BASE;
+	unsigned int ext_irq = 0;
 
 	intv &= (1 << SE7722_FPGA_IRQ_NR) - 1;
 
-	while (intv) {
-		if (intv & 1) {
-			ext_desc = irq_desc + ext_irq;
-			handle_level_irq(ext_irq, ext_desc);
-		}
-		intv >>= 1;
-		ext_irq++;
+	for (; intv; intv >>= 1, ext_irq++) {
+		if (!(intv & 1))
+			continue;
+
+		generic_handle_irq(se7722_fpga_irq[ext_irq]);
 	}
 }
 
@@ -63,11 +62,18 @@
 	ctrl_outw(0, IRQ01_MASK);       /* disable all irqs */
 	ctrl_outw(0x2000, 0xb03fffec);  /* mrshpc irq enable */
 
-	for (i = 0; i < SE7722_FPGA_IRQ_NR; i++)
-		set_irq_chip_and_handler_name(SE7722_FPGA_IRQ_BASE + i,
+	for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) {
+		se7722_fpga_irq[i] = create_irq();
+		if (se7722_fpga_irq[i] < 0)
+			return;
+
+		set_irq_chip_and_handler_name(se7722_fpga_irq[i],
 					      &se7722_irq_chip,
 					      handle_level_irq, "level");
 
+		set_irq_chip_data(se7722_fpga_irq[i], (void *)i);
+	}
+
 	set_irq_chained_handler(IRQ0_IRQ, se7722_irq_demux);
 	set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
 
diff --git a/arch/sh/boards/mach-se/7722/setup.c b/arch/sh/boards/mach-se/7722/setup.c
index 3637407..b1cb942 100644
--- a/arch/sh/boards/mach-se/7722/setup.c
+++ b/arch/sh/boards/mach-se/7722/setup.c
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 #include <linux/ata_platform.h>
 #include <linux/input.h>
+#include <linux/input/sh_keysc.h>
 #include <linux/smc91x.h>
 #include <mach-se/mach/se7722.h>
 #include <mach-se/mach/mrshpc.h>
@@ -21,7 +22,6 @@
 #include <asm/clock.h>
 #include <asm/io.h>
 #include <asm/heartbeat.h>
-#include <asm/sh_keysc.h>
 #include <cpu/sh7722.h>
 
 /* Heartbeat */
@@ -60,8 +60,7 @@
 		.flags  = IORESOURCE_MEM,
 	},
 	[1] = {
-		.start  = SMC_IRQ,
-		.end    = SMC_IRQ,
+		/* Filled in later */
 		.flags  = IORESOURCE_IRQ,
 	},
 };
@@ -90,8 +89,7 @@
 		.flags  = IORESOURCE_IO,
 	},
 	[2] = {
-		.start  = MRSHPC_IRQ0,
-		.end    = MRSHPC_IRQ0,
+		/* Filled in later */
 		.flags  = IORESOURCE_IRQ,
 	},
 };
@@ -153,6 +151,14 @@
 static int __init se7722_devices_setup(void)
 {
 	mrshpc_setup_windows();
+
+	/* Wire-up dynamic vectors */
+	cf_ide_resources[2].start = cf_ide_resources[2].end =
+		se7722_fpga_irq[SE7722_FPGA_IRQ_MRSHPC0];
+
+	smc91x_eth_resources[1].start = smc91x_eth_resources[1].end =
+		se7722_fpga_irq[SE7722_FPGA_IRQ_SMC];
+
 	return platform_add_devices(se7722_devices, ARRAY_SIZE(se7722_devices));
 }
 device_initcall(se7722_devices_setup);
@@ -193,6 +199,5 @@
 static struct sh_machine_vector mv_se7722 __initmv = {
 	.mv_name                = "Solution Engine 7722" ,
 	.mv_setup               = se7722_setup ,
-	.mv_nr_irqs		= SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_NR,
 	.mv_init_irq		= init_se7722_IRQ,
 };
diff --git a/arch/sh/boards/mach-se/7724/Makefile b/arch/sh/boards/mach-se/7724/Makefile
index 349cbd6..a08b368 100644
--- a/arch/sh/boards/mach-se/7724/Makefile
+++ b/arch/sh/boards/mach-se/7724/Makefile
@@ -7,4 +7,4 @@
 #
 #
 
-obj-y	 := setup.o irq.o
\ No newline at end of file
+obj-y	 := setup.o irq.o sdram.o
diff --git a/arch/sh/boards/mach-se/7724/sdram.S b/arch/sh/boards/mach-se/7724/sdram.S
new file mode 100644
index 0000000..9040167
--- /dev/null
+++ b/arch/sh/boards/mach-se/7724/sdram.S
@@ -0,0 +1,52 @@
+/*
+ * MS7724SE sdram self/auto-refresh setup code
+ *
+ *  Copyright (C) 2009 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/sys.h>
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/suspend.h>
+#include <asm/romimage-macros.h>
+
+/* code to enter and leave self-refresh. must be self-contained.
+ * this code will be copied to on-chip memory and executed from there.
+ */
+	.balign 4
+ENTRY(ms7724se_sdram_enter_start)
+
+	/* DBSC: put memory in self-refresh mode */
+
+	ED 0xFD000010, 0x00000000 /* DBEN */
+	ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+	ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+	ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+	ED 0xFD000040, 0x00000001 /* DBRFPDN0 */
+
+	rts
+	 nop
+
+ENTRY(ms7724se_sdram_enter_end)
+
+	.balign 4
+ENTRY(ms7724se_sdram_leave_start)
+
+	/* DBSC: put memory in auto-refresh mode */
+
+	ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+	WAIT 1
+	ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+	ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+	ED 0xFD000010, 0x00000001 /* DBEN */
+	ED 0xFD000040, 0x00010000 /* DBRFPDN0 */
+
+	rts
+	 nop
+
+ENTRY(ms7724se_sdram_leave_end)
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index 0894bba..4b0f0c0 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -19,6 +19,7 @@
 #include <linux/smc91x.h>
 #include <linux/gpio.h>
 #include <linux/input.h>
+#include <linux/input/sh_keysc.h>
 #include <linux/usb/r8a66597.h>
 #include <video/sh_mobile_lcdc.h>
 #include <media/sh_mobile_ceu.h>
@@ -27,7 +28,7 @@
 #include <asm/heartbeat.h>
 #include <asm/sh_eth.h>
 #include <asm/clock.h>
-#include <asm/sh_keysc.h>
+#include <asm/suspend.h>
 #include <cpu/sh7724.h>
 #include <mach-se/mach/se7724.h>
 
@@ -451,6 +452,52 @@
 	.resource	= sh7724_usb1_gadget_resources,
 };
 
+static struct resource sdhi0_cn7_resources[] = {
+	[0] = {
+		.name	= "SDHI0",
+		.start  = 0x04ce0000,
+		.end    = 0x04ce01ff,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 101,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device sdhi0_cn7_device = {
+	.name           = "sh_mobile_sdhi",
+	.id		= 0,
+	.num_resources  = ARRAY_SIZE(sdhi0_cn7_resources),
+	.resource       = sdhi0_cn7_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_SDHI0,
+	},
+};
+
+static struct resource sdhi1_cn8_resources[] = {
+	[0] = {
+		.name	= "SDHI1",
+		.start  = 0x04cf0000,
+		.end    = 0x04cf01ff,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 24,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device sdhi1_cn8_device = {
+	.name           = "sh_mobile_sdhi",
+	.id		= 1,
+	.num_resources  = ARRAY_SIZE(sdhi1_cn8_resources),
+	.resource       = sdhi1_cn8_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_SDHI1,
+	},
+};
+
 static struct platform_device *ms7724se_devices[] __initdata = {
 	&heartbeat_device,
 	&smc91x_eth_device,
@@ -463,6 +510,8 @@
 	&sh7724_usb0_host_device,
 	&sh7724_usb1_gadget_device,
 	&fsi_device,
+	&sdhi0_cn7_device,
+	&sdhi1_cn8_device,
 };
 
 #define EEPROM_OP   0xBA206000
@@ -487,7 +536,7 @@
 static void __init sh_eth_init(void)
 {
 	int i;
-	u16 mac[3];
+	u16 mac;
 
 	/* check EEPROM status */
 	if (!sh_eth_is_eeprom_ready())
@@ -501,16 +550,10 @@
 		if (!sh_eth_is_eeprom_ready())
 			return;
 
-		mac[i] = ctrl_inw(EEPROM_DATA);
-		mac[i] = ((mac[i] & 0xFF) << 8) | (mac[i] >> 8); /* swap */
+		mac = ctrl_inw(EEPROM_DATA);
+		sh_eth_plat.mac_addr[i << 1] = mac & 0xff;
+		sh_eth_plat.mac_addr[(i << 1) + 1] = mac >> 8;
 	}
-
-	/* reset sh-eth */
-	ctrl_outl(0x1, SH_ETH_ADDR + 0x0);
-
-	/* set MAC addr */
-	ctrl_outl(((mac[0] << 16) | (mac[1])), SH_ETH_MAHR);
-	ctrl_outl((mac[2]), SH_ETH_MALR);
 }
 
 #define SW4140    0xBA201000
@@ -527,11 +570,22 @@
 #define SW41_G    0x4000
 #define SW41_H    0x8000
 
+extern char ms7724se_sdram_enter_start;
+extern char ms7724se_sdram_enter_end;
+extern char ms7724se_sdram_leave_start;
+extern char ms7724se_sdram_leave_end;
+
 static int __init devices_setup(void)
 {
 	u16 sw = ctrl_inw(SW4140); /* select camera, monitor */
 	struct clk *fsia_clk;
 
+	/* register board specific self-refresh code */
+	sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF,
+					&ms7724se_sdram_enter_start,
+					&ms7724se_sdram_enter_end,
+					&ms7724se_sdram_leave_start,
+					&ms7724se_sdram_leave_end);
 	/* Reset Release */
 	ctrl_outw(ctrl_inw(FPGA_OUT) &
 		  ~((1 << 1)  | /* LAN */
@@ -701,6 +755,26 @@
 	clk_set_rate(&fsimcka_clk, 11000);
 	clk_put(fsia_clk);
 
+	/* SDHI0 connected to cn7 */
+	gpio_request(GPIO_FN_SDHI0CD, NULL);
+	gpio_request(GPIO_FN_SDHI0WP, NULL);
+	gpio_request(GPIO_FN_SDHI0D3, NULL);
+	gpio_request(GPIO_FN_SDHI0D2, NULL);
+	gpio_request(GPIO_FN_SDHI0D1, NULL);
+	gpio_request(GPIO_FN_SDHI0D0, NULL);
+	gpio_request(GPIO_FN_SDHI0CMD, NULL);
+	gpio_request(GPIO_FN_SDHI0CLK, NULL);
+
+	/* SDHI1 connected to cn8 */
+	gpio_request(GPIO_FN_SDHI1CD, NULL);
+	gpio_request(GPIO_FN_SDHI1WP, NULL);
+	gpio_request(GPIO_FN_SDHI1D3, NULL);
+	gpio_request(GPIO_FN_SDHI1D2, NULL);
+	gpio_request(GPIO_FN_SDHI1D1, NULL);
+	gpio_request(GPIO_FN_SDHI1D0, NULL);
+	gpio_request(GPIO_FN_SDHI1CMD, NULL);
+	gpio_request(GPIO_FN_SDHI1CLK, NULL);
+
 	/*
 	 * enable SH-Eth
 	 *
diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c
index fd56a71..b51b1fc 100644
--- a/arch/sh/boot/compressed/misc.c
+++ b/arch/sh/boot/compressed/misc.c
@@ -131,7 +131,7 @@
 #ifdef CONFIG_SUPERH64
 	output_addr = (CONFIG_MEMORY_START + 0x2000);
 #else
-	output_addr = PHYSADDR((unsigned long)&_text+PAGE_SIZE);
+	output_addr = __pa((unsigned long)&_text+PAGE_SIZE);
 #ifdef CONFIG_29BIT
 	output_addr |= P2SEG;
 #endif
diff --git a/arch/sh/boot/romimage/Makefile b/arch/sh/boot/romimage/Makefile
index 5806eee..f473a24 100644
--- a/arch/sh/boot/romimage/Makefile
+++ b/arch/sh/boot/romimage/Makefile
@@ -4,16 +4,22 @@
 # create an image suitable for burning to flash from zImage
 #
 
-targets		:= vmlinux head.o
+targets		:= vmlinux head.o zeropage.bin piggy.o
 
 OBJECTS = $(obj)/head.o
-LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext 0 -e romstart
+LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext 0 -e romstart \
+		   -T $(obj)/../../kernel/vmlinux.lds
 
 $(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o FORCE
 	$(call if_changed,ld)
 	@:
 
+OBJCOPYFLAGS += -j .empty_zero_page
+
+$(obj)/zeropage.bin: vmlinux FORCE
+	$(call if_changed,objcopy)
+
 LDFLAGS_piggy.o := -r --format binary --oformat $(ld-bfd) -T
 
-$(obj)/piggy.o: $(obj)/vmlinux.scr arch/sh/boot/zImage FORCE
+$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/zeropage.bin arch/sh/boot/zImage FORCE
 	$(call if_changed,ld)
diff --git a/arch/sh/boot/romimage/head.S b/arch/sh/boot/romimage/head.S
index 219bc62..93e779a 100644
--- a/arch/sh/boot/romimage/head.S
+++ b/arch/sh/boot/romimage/head.S
@@ -5,6 +5,44 @@
  */
 
 .text
+	#include <asm/page.h>
+
 	.global	romstart
 romstart:
+	/* include board specific setup code */
 #include <mach/romimage.h>
+
+	/* copy the empty_zero_page contents to where vmlinux expects it */
+	mova	empty_zero_page_src, r0
+	mov.l	empty_zero_page_dst, r1
+	mov	#(PAGE_SHIFT - 4), r4
+	mov	#1, r3
+	shld	r4, r3 /* r3 = PAGE_SIZE / 16 */
+
+1:
+	mov.l	@r0, r4
+	mov.l	@(4, r0), r5
+	mov.l	@(8, r0), r6
+	mov.l	@(12, r0), r7
+	add	#16,r0
+	mov.l	r4, @r1
+	mov.l	r5, @(4, r1)
+	mov.l	r6, @(8, r1)
+	mov.l	r7, @(12, r1)
+	dt	r3
+	add	#16,r1
+	bf	1b
+
+	/* jump to the zImage entry point located after the zero page data */
+	mov	#PAGE_SHIFT, r4
+	mov	#1, r1
+	shld	r4, r1
+	mova	empty_zero_page_src, r0
+	add	r1, r0
+	jmp	@r0
+	 nop
+
+	.align 2
+empty_zero_page_dst:
+	.long	_text
+empty_zero_page_src:
diff --git a/arch/sh/drivers/dma/dma-sysfs.c b/arch/sh/drivers/dma/dma-sysfs.c
index 347ee11..1ee631d 100644
--- a/arch/sh/drivers/dma/dma-sysfs.c
+++ b/arch/sh/drivers/dma/dma-sysfs.c
@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/sysdev.h>
 #include <linux/platform_device.h>
-#include <linux/module.h>
 #include <linux/err.h>
 #include <linux/string.h>
 #include <asm/dma.h>
@@ -21,7 +20,6 @@
 static struct sysdev_class dma_sysclass = {
 	.name = "dma",
 };
-EXPORT_SYMBOL(dma_sysclass);
 
 static ssize_t dma_show_devices(struct sys_device *dev,
 				struct sysdev_attribute *attr, char *buf)
diff --git a/arch/sh/drivers/pci/Kconfig b/arch/sh/drivers/pci/Kconfig
deleted file mode 100644
index e8db585..0000000
--- a/arch/sh/drivers/pci/Kconfig
+++ /dev/null
@@ -1,19 +0,0 @@
-config PCI
-	bool "PCI support"
-	depends on SYS_SUPPORTS_PCI
-	help
-	  Find out whether you have a PCI motherboard. PCI is the name of a
-	  bus system, i.e. the way the CPU talks to the other stuff inside
-	  your box. If you have PCI, say Y, otherwise N.
-
-config SH_PCIDMA_NONCOHERENT
-	bool "Cache and PCI noncoherent"
-	depends on PCI
-	default y
-	help
-	  Enable this option if your platform does not have a CPU cache which
-	  remains coherent with PCI DMA. It is safest to say 'Y', although you
-	  will see better performance if you can say 'N', because the PCI DMA
-	  code will not have to flush the CPU's caches. If you have a PCI host
-	  bridge integrated with your SH CPU, refer carefully to the chip specs
-	  to see if you can say 'N' here. Otherwise, leave it as 'Y'.
diff --git a/arch/sh/include/asm/addrspace.h b/arch/sh/include/asm/addrspace.h
index 80d4081..99d6b3e 100644
--- a/arch/sh/include/asm/addrspace.h
+++ b/arch/sh/include/asm/addrspace.h
@@ -28,9 +28,6 @@
 /* Returns the privileged segment base of a given address  */
 #define PXSEG(a)	(((unsigned long)(a)) & 0xe0000000)
 
-/* Returns the physical address of a PnSEG (n=1,2) address   */
-#define PHYSADDR(a)	(((unsigned long)(a)) & 0x1fffffff)
-
 #if defined(CONFIG_29BIT) || defined(CONFIG_PMB_FIXED)
 /*
  * Map an address to a certain privileged segment
@@ -60,5 +57,11 @@
 #define P3_ADDR_MAX		P4SEG
 #endif
 
+#ifndef __ASSEMBLY__
+#ifdef CONFIG_PMB
+extern int __in_29bit_mode(void);
+#endif /* CONFIG_PMB */
+#endif /* __ASSEMBLY__ */
+
 #endif /* __KERNEL__ */
 #endif /* __ASM_SH_ADDRSPACE_H */
diff --git a/arch/sh/include/asm/atomic.h b/arch/sh/include/asm/atomic.h
index e8e7813..b16388d 100644
--- a/arch/sh/include/asm/atomic.h
+++ b/arch/sh/include/asm/atomic.h
@@ -78,11 +78,10 @@
 #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
 
-/* Atomic operations are already serializing on SH */
-#define smp_mb__before_atomic_dec()	barrier()
-#define smp_mb__after_atomic_dec()	barrier()
-#define smp_mb__before_atomic_inc()	barrier()
-#define smp_mb__after_atomic_inc()	barrier()
+#define smp_mb__before_atomic_dec()	smp_mb()
+#define smp_mb__after_atomic_dec()	smp_mb()
+#define smp_mb__before_atomic_inc()	smp_mb()
+#define smp_mb__after_atomic_inc()	smp_mb()
 
 #include <asm-generic/atomic-long.h>
 #include <asm-generic/atomic64.h>
diff --git a/arch/sh/include/asm/bitops.h b/arch/sh/include/asm/bitops.h
index ebe595b..98511e4 100644
--- a/arch/sh/include/asm/bitops.h
+++ b/arch/sh/include/asm/bitops.h
@@ -26,8 +26,8 @@
 /*
  * clear_bit() doesn't provide any barrier for the compiler.
  */
-#define smp_mb__before_clear_bit()	barrier()
-#define smp_mb__after_clear_bit()	barrier()
+#define smp_mb__before_clear_bit()	smp_mb()
+#define smp_mb__after_clear_bit()	smp_mb()
 
 #ifdef CONFIG_SUPERH32
 static inline unsigned long ffz(unsigned long word)
diff --git a/arch/sh/include/asm/bugs.h b/arch/sh/include/asm/bugs.h
index 46260fc..02a19a1 100644
--- a/arch/sh/include/asm/bugs.h
+++ b/arch/sh/include/asm/bugs.h
@@ -14,11 +14,15 @@
 
 #include <asm/processor.h>
 
+extern void select_idle_routine(void);
+
 static void __init check_bugs(void)
 {
 	extern unsigned long loops_per_jiffy;
 	char *p = &init_utsname()->machine[2]; /* "sh" */
 
+	select_idle_routine();
+
 	current_cpu_data.loops_per_jiffy = loops_per_jiffy;
 
 	switch (current_cpu_data.family) {
diff --git a/arch/sh/include/asm/dma-mapping.h b/arch/sh/include/asm/dma-mapping.h
index 69d56dd..87ced13 100644
--- a/arch/sh/include/asm/dma-mapping.h
+++ b/arch/sh/include/asm/dma-mapping.h
@@ -1,193 +1,52 @@
 #ifndef __ASM_SH_DMA_MAPPING_H
 #define __ASM_SH_DMA_MAPPING_H
 
-#include <linux/mm.h>
-#include <linux/scatterlist.h>
-#include <linux/dma-debug.h>
-#include <asm/cacheflush.h>
-#include <asm/io.h>
+extern struct dma_map_ops *dma_ops;
+extern void no_iommu_init(void);
+
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
+{
+	return dma_ops;
+}
+
 #include <asm-generic/dma-coherent.h>
+#include <asm-generic/dma-mapping-common.h>
 
-extern struct bus_type pci_bus_type;
+static inline int dma_supported(struct device *dev, u64 mask)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
 
-#define dma_supported(dev, mask)	(1)
+	if (ops->dma_supported)
+		return ops->dma_supported(dev, mask);
+
+	return 1;
+}
 
 static inline int dma_set_mask(struct device *dev, u64 mask)
 {
+	struct dma_map_ops *ops = get_dma_ops(dev);
+
 	if (!dev->dma_mask || !dma_supported(dev, mask))
 		return -EIO;
+	if (ops->set_dma_mask)
+		return ops->set_dma_mask(dev, mask);
 
 	*dev->dma_mask = mask;
 
 	return 0;
 }
 
-void *dma_alloc_coherent(struct device *dev, size_t size,
-			 dma_addr_t *dma_handle, gfp_t flag);
-
-void dma_free_coherent(struct device *dev, size_t size,
-		       void *vaddr, dma_addr_t dma_handle);
-
 void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 		    enum dma_data_direction dir);
 
 #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
 #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+
+#ifdef CONFIG_DMA_COHERENT
 #define dma_is_consistent(d, h) (1)
-
-static inline dma_addr_t dma_map_single(struct device *dev,
-					void *ptr, size_t size,
-					enum dma_data_direction dir)
-{
-	dma_addr_t addr = virt_to_phys(ptr);
-
-#if defined(CONFIG_PCI) && !defined(CONFIG_SH_PCIDMA_NONCOHERENT)
-	if (dev->bus == &pci_bus_type)
-		return addr;
+#else
+#define dma_is_consistent(d, h) (0)
 #endif
-	dma_cache_sync(dev, ptr, size, dir);
-
-	debug_dma_map_page(dev, virt_to_page(ptr),
-			   (unsigned long)ptr & ~PAGE_MASK, size,
-			   dir, addr, true);
-
-	return addr;
-}
-
-static inline void dma_unmap_single(struct device *dev, dma_addr_t addr,
-				    size_t size, enum dma_data_direction dir)
-{
-	debug_dma_unmap_page(dev, addr, size, dir, true);
-}
-
-static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
-			     int nents, enum dma_data_direction dir)
-{
-	int i;
-
-	for (i = 0; i < nents; i++) {
-#if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT)
-		dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir);
-#endif
-		sg[i].dma_address = sg_phys(&sg[i]);
-		sg[i].dma_length = sg[i].length;
-	}
-
-	debug_dma_map_sg(dev, sg, nents, i, dir);
-
-	return nents;
-}
-
-static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
-				int nents, enum dma_data_direction dir)
-{
-	debug_dma_unmap_sg(dev, sg, nents, dir);
-}
-
-static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
-				      unsigned long offset, size_t size,
-				      enum dma_data_direction dir)
-{
-	return dma_map_single(dev, page_address(page) + offset, size, dir);
-}
-
-static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
-				  size_t size, enum dma_data_direction dir)
-{
-	dma_unmap_single(dev, dma_address, size, dir);
-}
-
-static inline void __dma_sync_single(struct device *dev, dma_addr_t dma_handle,
-				   size_t size, enum dma_data_direction dir)
-{
-#if defined(CONFIG_PCI) && !defined(CONFIG_SH_PCIDMA_NONCOHERENT)
-	if (dev->bus == &pci_bus_type)
-		return;
-#endif
-	dma_cache_sync(dev, phys_to_virt(dma_handle), size, dir);
-}
-
-static inline void dma_sync_single_range(struct device *dev,
-					 dma_addr_t dma_handle,
-					 unsigned long offset, size_t size,
-					 enum dma_data_direction dir)
-{
-#if defined(CONFIG_PCI) && !defined(CONFIG_SH_PCIDMA_NONCOHERENT)
-	if (dev->bus == &pci_bus_type)
-		return;
-#endif
-	dma_cache_sync(dev, phys_to_virt(dma_handle) + offset, size, dir);
-}
-
-static inline void __dma_sync_sg(struct device *dev, struct scatterlist *sg,
-			       int nelems, enum dma_data_direction dir)
-{
-	int i;
-
-	for (i = 0; i < nelems; i++) {
-#if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT)
-		dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir);
-#endif
-		sg[i].dma_address = sg_phys(&sg[i]);
-		sg[i].dma_length = sg[i].length;
-	}
-}
-
-static inline void dma_sync_single_for_cpu(struct device *dev,
-					   dma_addr_t dma_handle, size_t size,
-					   enum dma_data_direction dir)
-{
-	__dma_sync_single(dev, dma_handle, size, dir);
-	debug_dma_sync_single_for_cpu(dev, dma_handle, size, dir);
-}
-
-static inline void dma_sync_single_for_device(struct device *dev,
-					      dma_addr_t dma_handle,
-					      size_t size,
-					      enum dma_data_direction dir)
-{
-	__dma_sync_single(dev, dma_handle, size, dir);
-	debug_dma_sync_single_for_device(dev, dma_handle, size, dir);
-}
-
-static inline void dma_sync_single_range_for_cpu(struct device *dev,
-						 dma_addr_t dma_handle,
-						 unsigned long offset,
-						 size_t size,
-						 enum dma_data_direction direction)
-{
-	dma_sync_single_for_cpu(dev, dma_handle+offset, size, direction);
-	debug_dma_sync_single_range_for_cpu(dev, dma_handle,
-					    offset, size, direction);
-}
-
-static inline void dma_sync_single_range_for_device(struct device *dev,
-						    dma_addr_t dma_handle,
-						    unsigned long offset,
-						    size_t size,
-						    enum dma_data_direction direction)
-{
-	dma_sync_single_for_device(dev, dma_handle+offset, size, direction);
-	debug_dma_sync_single_range_for_device(dev, dma_handle,
-					       offset, size, direction);
-}
-
-
-static inline void dma_sync_sg_for_cpu(struct device *dev,
-				       struct scatterlist *sg, int nelems,
-				       enum dma_data_direction dir)
-{
-	__dma_sync_sg(dev, sg, nelems, dir);
-	debug_dma_sync_sg_for_cpu(dev, sg, nelems, dir);
-}
-
-static inline void dma_sync_sg_for_device(struct device *dev,
-					  struct scatterlist *sg, int nelems,
-					  enum dma_data_direction dir)
-{
-	__dma_sync_sg(dev, sg, nelems, dir);
-	debug_dma_sync_sg_for_device(dev, sg, nelems, dir);
-}
 
 static inline int dma_get_cache_alignment(void)
 {
@@ -200,20 +59,50 @@
 
 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
+	struct dma_map_ops *ops = get_dma_ops(dev);
+
+	if (ops->mapping_error)
+		return ops->mapping_error(dev, dma_addr);
+
 	return dma_addr == 0;
 }
 
-#define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+				       dma_addr_t *dma_handle, gfp_t gfp)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
+	void *memory;
 
-extern int
-dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
-			    dma_addr_t device_addr, size_t size, int flags);
+	if (dma_alloc_from_coherent(dev, size, dma_handle, &memory))
+		return memory;
+	if (!ops->alloc_coherent)
+		return NULL;
 
-extern void
-dma_release_declared_memory(struct device *dev);
+	memory = ops->alloc_coherent(dev, size, dma_handle, gfp);
+	debug_dma_alloc_coherent(dev, size, *dma_handle, memory);
 
-extern void *
-dma_mark_declared_memory_occupied(struct device *dev,
-				  dma_addr_t device_addr, size_t size);
+	return memory;
+}
+
+static inline void dma_free_coherent(struct device *dev, size_t size,
+				     void *vaddr, dma_addr_t dma_handle)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
+
+	WARN_ON(irqs_disabled());	/* for portability */
+
+	if (dma_release_from_coherent(dev, get_order(size), vaddr))
+		return;
+
+	debug_dma_free_coherent(dev, size, vaddr, dma_handle);
+	if (ops->free_coherent)
+		ops->free_coherent(dev, size, vaddr, dma_handle);
+}
+
+/* arch/sh/mm/consistent.c */
+extern void *dma_generic_alloc_coherent(struct device *dev, size_t size,
+					dma_addr_t *dma_addr, gfp_t flag);
+extern void dma_generic_free_coherent(struct device *dev, size_t size,
+				      void *vaddr, dma_addr_t dma_handle);
 
 #endif /* __ASM_SH_DMA_MAPPING_H */
diff --git a/arch/sh/include/asm/dwarf.h b/arch/sh/include/asm/dwarf.h
index ced6795..bdccbbf 100644
--- a/arch/sh/include/asm/dwarf.h
+++ b/arch/sh/include/asm/dwarf.h
@@ -194,6 +194,12 @@
 #define DWARF_ARCH_RA_REG	17
 
 #ifndef __ASSEMBLY__
+
+#include <linux/compiler.h>
+#include <linux/bug.h>
+#include <linux/list.h>
+#include <linux/module.h>
+
 /*
  * Read either the frame pointer (r14) or the stack pointer (r15).
  * NOTE: this MUST be inlined.
@@ -241,6 +247,12 @@
 
 	unsigned long flags;
 #define DWARF_CIE_Z_AUGMENTATION	(1 << 0)
+
+	/*
+	 * 'mod' will be non-NULL if this CIE came from a module's
+	 * .eh_frame section.
+	 */
+	struct module *mod;
 };
 
 /**
@@ -255,6 +267,12 @@
 	unsigned char *instructions;
 	unsigned char *end;
 	struct list_head link;
+
+	/*
+	 * 'mod' will be non-NULL if this FDE came from a module's
+	 * .eh_frame section.
+	 */
+	struct module *mod;
 };
 
 /**
@@ -364,6 +382,12 @@
 
 extern struct dwarf_frame *dwarf_unwind_stack(unsigned long,
 					      struct dwarf_frame *);
+extern void dwarf_free_frame(struct dwarf_frame *);
+
+extern int module_dwarf_finalize(const Elf_Ehdr *, const Elf_Shdr *,
+				 struct module *);
+extern void module_dwarf_cleanup(struct module *);
+
 #endif /* !__ASSEMBLY__ */
 
 #define CFI_STARTPROC	.cfi_startproc
@@ -391,6 +415,10 @@
 static inline void dwarf_unwinder_init(void)
 {
 }
+
+#define module_dwarf_finalize(hdr, sechdrs, me)	(0)
+#define module_dwarf_cleanup(mod)		do { } while (0)
+
 #endif
 
 #endif /* CONFIG_DWARF_UNWINDER */
diff --git a/arch/sh/include/asm/fixmap.h b/arch/sh/include/asm/fixmap.h
index 721fcc4..5ac1e40 100644
--- a/arch/sh/include/asm/fixmap.h
+++ b/arch/sh/include/asm/fixmap.h
@@ -14,9 +14,9 @@
 #define _ASM_FIXMAP_H
 
 #include <linux/kernel.h>
+#include <linux/threads.h>
 #include <asm/page.h>
 #ifdef CONFIG_HIGHMEM
-#include <linux/threads.h>
 #include <asm/kmap_types.h>
 #endif
 
@@ -46,9 +46,15 @@
  * fix-mapped?
  */
 enum fixed_addresses {
-#define FIX_N_COLOURS 16
+	/*
+	 * The FIX_CMAP entries are used by kmap_coherent() to get virtual
+	 * addresses which are of a known color, and so their values are
+	 * important. __fix_to_virt(FIX_CMAP_END - n) must give an address
+	 * which is the same color as a page (n<<PAGE_SHIFT).
+	 */
+#define FIX_N_COLOURS 8
 	FIX_CMAP_BEGIN,
-	FIX_CMAP_END = FIX_CMAP_BEGIN + FIX_N_COLOURS,
+	FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS) - 1,
 	FIX_UNCACHED,
 #ifdef CONFIG_HIGHMEM
 	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
diff --git a/arch/sh/include/asm/fpu.h b/arch/sh/include/asm/fpu.h
index 1d3aee0..fb6bbb9 100644
--- a/arch/sh/include/asm/fpu.h
+++ b/arch/sh/include/asm/fpu.h
@@ -18,16 +18,15 @@
 
 struct task_struct;
 
-extern void save_fpu(struct task_struct *__tsk, struct pt_regs *regs);
+extern void save_fpu(struct task_struct *__tsk);
+void fpu_state_restore(struct pt_regs *regs);
 #else
 
+#define save_fpu(tsk)		do { } while (0)
 #define release_fpu(regs)	do { } while (0)
 #define grab_fpu(regs)		do { } while (0)
+#define fpu_state_restore(regs)	do { } while (0)
 
-static inline void save_fpu(struct task_struct *tsk, struct pt_regs *regs)
-{
-	clear_tsk_thread_flag(tsk, TIF_USEDFPU);
-}
 #endif
 
 struct user_regset;
@@ -39,19 +38,28 @@
 		      unsigned int pos, unsigned int count,
 		      void *kbuf, void __user *ubuf);
 
+static inline void __unlazy_fpu(struct task_struct *tsk, struct pt_regs *regs)
+{
+	if (task_thread_info(tsk)->status & TS_USEDFPU) {
+		task_thread_info(tsk)->status &= ~TS_USEDFPU;
+		save_fpu(tsk);
+		release_fpu(regs);
+	} else
+		tsk->fpu_counter = 0;
+}
+
 static inline void unlazy_fpu(struct task_struct *tsk, struct pt_regs *regs)
 {
 	preempt_disable();
-	if (test_tsk_thread_flag(tsk, TIF_USEDFPU))
-		save_fpu(tsk, regs);
+	__unlazy_fpu(tsk, regs);
 	preempt_enable();
 }
 
 static inline void clear_fpu(struct task_struct *tsk, struct pt_regs *regs)
 {
 	preempt_disable();
-	if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) {
-		clear_tsk_thread_flag(tsk, TIF_USEDFPU);
+	if (task_thread_info(tsk)->status & TS_USEDFPU) {
+		task_thread_info(tsk)->status &= ~TS_USEDFPU;
 		release_fpu(regs);
 	}
 	preempt_enable();
diff --git a/arch/sh/include/asm/ftrace.h b/arch/sh/include/asm/ftrace.h
index 12f3a31..13e9966 100644
--- a/arch/sh/include/asm/ftrace.h
+++ b/arch/sh/include/asm/ftrace.h
@@ -35,4 +35,21 @@
 #endif /* __ASSEMBLY__ */
 #endif /* CONFIG_FUNCTION_TRACER */
 
+#ifndef __ASSEMBLY__
+
+/* arch/sh/kernel/return_address.c */
+extern void *return_address(unsigned int);
+
+#define HAVE_ARCH_CALLER_ADDR
+
+#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+#define CALLER_ADDR1 ((unsigned long)return_address(1))
+#define CALLER_ADDR2 ((unsigned long)return_address(2))
+#define CALLER_ADDR3 ((unsigned long)return_address(3))
+#define CALLER_ADDR4 ((unsigned long)return_address(4))
+#define CALLER_ADDR5 ((unsigned long)return_address(5))
+#define CALLER_ADDR6 ((unsigned long)return_address(6))
+
+#endif /* __ASSEMBLY__ */
+
 #endif /* __ASM_SH_FTRACE_H */
diff --git a/arch/sh/include/asm/gpio.h b/arch/sh/include/asm/gpio.h
index 61f93da..f8d9a73 100644
--- a/arch/sh/include/asm/gpio.h
+++ b/arch/sh/include/asm/gpio.h
@@ -20,7 +20,7 @@
 #endif
 
 #define ARCH_NR_GPIOS 512
-#include <asm-generic/gpio.h>
+#include <linux/sh_pfc.h>
 
 #ifdef CONFIG_GPIOLIB
 
@@ -53,84 +53,4 @@
 
 #endif /* CONFIG_GPIOLIB */
 
-typedef unsigned short pinmux_enum_t;
-typedef unsigned short pinmux_flag_t;
-
-#define PINMUX_TYPE_NONE            0
-#define PINMUX_TYPE_FUNCTION        1
-#define PINMUX_TYPE_GPIO            2
-#define PINMUX_TYPE_OUTPUT          3
-#define PINMUX_TYPE_INPUT           4
-#define PINMUX_TYPE_INPUT_PULLUP    5
-#define PINMUX_TYPE_INPUT_PULLDOWN  6
-
-#define PINMUX_FLAG_TYPE            (0x7)
-#define PINMUX_FLAG_WANT_PULLUP     (1 << 3)
-#define PINMUX_FLAG_WANT_PULLDOWN   (1 << 4)
-
-#define PINMUX_FLAG_DBIT_SHIFT      5
-#define PINMUX_FLAG_DBIT            (0x1f << PINMUX_FLAG_DBIT_SHIFT)
-#define PINMUX_FLAG_DREG_SHIFT      10
-#define PINMUX_FLAG_DREG            (0x3f << PINMUX_FLAG_DREG_SHIFT)
-
-struct pinmux_gpio {
-	pinmux_enum_t enum_id;
-	pinmux_flag_t flags;
-};
-
-#define PINMUX_GPIO(gpio, data_or_mark) [gpio] = { data_or_mark }
-#define PINMUX_DATA(data_or_mark, ids...) data_or_mark, ids, 0
-
-struct pinmux_cfg_reg {
-	unsigned long reg, reg_width, field_width;
-	unsigned long *cnt;
-	pinmux_enum_t *enum_ids;
-};
-
-#define PINMUX_CFG_REG(name, r, r_width, f_width) \
-	.reg = r, .reg_width = r_width, .field_width = f_width,		\
-	.cnt = (unsigned long [r_width / f_width]) {}, \
-	.enum_ids = (pinmux_enum_t [(r_width / f_width) * (1 << f_width)]) \
-
-struct pinmux_data_reg {
-	unsigned long reg, reg_width, reg_shadow;
-	pinmux_enum_t *enum_ids;
-};
-
-#define PINMUX_DATA_REG(name, r, r_width) \
-	.reg = r, .reg_width = r_width,	\
-	.enum_ids = (pinmux_enum_t [r_width]) \
-
-struct pinmux_range {
-	pinmux_enum_t begin;
-	pinmux_enum_t end;
-	pinmux_enum_t force;
-};
-
-struct pinmux_info {
-	char *name;
-	pinmux_enum_t reserved_id;
-	struct pinmux_range data;
-	struct pinmux_range input;
-	struct pinmux_range input_pd;
-	struct pinmux_range input_pu;
-	struct pinmux_range output;
-	struct pinmux_range mark;
-	struct pinmux_range function;
-
-	unsigned first_gpio, last_gpio;
-
-	struct pinmux_gpio *gpios;
-	struct pinmux_cfg_reg *cfg_regs;
-	struct pinmux_data_reg *data_regs;
-
-	pinmux_enum_t *gpio_data;
-	unsigned int gpio_data_size;
-
-	unsigned long *gpio_in_use;
-	struct gpio_chip chip;
-};
-
-int register_pinmux(struct pinmux_info *pip);
-
 #endif /* __ASM_SH_GPIO_H */
diff --git a/arch/sh/include/asm/hardirq.h b/arch/sh/include/asm/hardirq.h
index a5be4af..48b1913 100644
--- a/arch/sh/include/asm/hardirq.h
+++ b/arch/sh/include/asm/hardirq.h
@@ -1,9 +1,16 @@
 #ifndef __ASM_SH_HARDIRQ_H
 #define __ASM_SH_HARDIRQ_H
 
-extern void ack_bad_irq(unsigned int irq);
-#define ack_bad_irq ack_bad_irq
+#include <linux/threads.h>
+#include <linux/irq.h>
 
-#include <asm-generic/hardirq.h>
+typedef struct {
+	unsigned int __softirq_pending;
+	unsigned int __nmi_count;		/* arch dependent */
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+
+extern void ack_bad_irq(unsigned int irq);
 
 #endif /* __ASM_SH_HARDIRQ_H */
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index 5be45ea..512cd3e 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -90,15 +90,11 @@
 #define ctrl_outl		__raw_writel
 #define ctrl_outq		__raw_writeq
 
+extern unsigned long generic_io_base;
+
 static inline void ctrl_delay(void)
 {
-#ifdef CONFIG_CPU_SH4
-	__raw_readw(CCN_PVR);
-#elif defined(P2SEG)
-	__raw_readw(P2SEG);
-#else
-#error "Need a dummy address for delay"
-#endif
+	__raw_readw(generic_io_base);
 }
 
 #define __BUILD_MEMORY_STRING(bwlq, type)				\
@@ -186,8 +182,6 @@
 
 #define IO_SPACE_LIMIT 0xffffffff
 
-extern unsigned long generic_io_base;
-
 /*
  * This function provides a method for the generic case where a
  * board-specific ioport_map simply needs to return the port + some
@@ -246,7 +240,7 @@
 static inline void __iomem *
 __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
 {
-#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED)
+#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED) && !defined(CONFIG_PMB)
 	unsigned long last_addr = offset + size - 1;
 #endif
 	void __iomem *ret;
@@ -255,7 +249,7 @@
 	if (ret)
 		return ret;
 
-#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED)
+#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED) && !defined(CONFIG_PMB)
 	/*
 	 * For P1 and P2 space this is trivial, as everything is already
 	 * mapped. Uncached access for P1 addresses are done through P2.
diff --git a/arch/sh/include/asm/irqflags.h b/arch/sh/include/asm/irqflags.h
index 46e71da..a741153 100644
--- a/arch/sh/include/asm/irqflags.h
+++ b/arch/sh/include/asm/irqflags.h
@@ -1,34 +1,9 @@
 #ifndef __ASM_SH_IRQFLAGS_H
 #define __ASM_SH_IRQFLAGS_H
 
-#ifdef CONFIG_SUPERH32
-#include "irqflags_32.h"
-#else
-#include "irqflags_64.h"
-#endif
+#define RAW_IRQ_DISABLED	0xf0
+#define RAW_IRQ_ENABLED		0x00
 
-#define raw_local_save_flags(flags) \
-		do { (flags) = __raw_local_save_flags(); } while (0)
-
-static inline int raw_irqs_disabled_flags(unsigned long flags)
-{
-	return (flags != 0);
-}
-
-static inline int raw_irqs_disabled(void)
-{
-	unsigned long flags = __raw_local_save_flags();
-
-	return raw_irqs_disabled_flags(flags);
-}
-
-#define raw_local_irq_save(flags) \
-		do { (flags) = __raw_local_irq_save(); } while (0)
-
-static inline void raw_local_irq_restore(unsigned long flags)
-{
-	if ((flags & 0xf0) != 0xf0)
-		raw_local_irq_enable();
-}
+#include <asm-generic/irqflags.h>
 
 #endif /* __ASM_SH_IRQFLAGS_H */
diff --git a/arch/sh/include/asm/irqflags_32.h b/arch/sh/include/asm/irqflags_32.h
deleted file mode 100644
index 60218f5..0000000
--- a/arch/sh/include/asm/irqflags_32.h
+++ /dev/null
@@ -1,99 +0,0 @@
-#ifndef __ASM_SH_IRQFLAGS_32_H
-#define __ASM_SH_IRQFLAGS_32_H
-
-static inline void raw_local_irq_enable(void)
-{
-	unsigned long __dummy0, __dummy1;
-
-	__asm__ __volatile__ (
-		"stc	sr, %0\n\t"
-		"and	%1, %0\n\t"
-#ifdef CONFIG_CPU_HAS_SR_RB
-		"stc	r6_bank, %1\n\t"
-		"or	%1, %0\n\t"
-#endif
-		"ldc	%0, sr\n\t"
-		: "=&r" (__dummy0), "=r" (__dummy1)
-		: "1" (~0x000000f0)
-		: "memory"
-	);
-}
-
-static inline void raw_local_irq_disable(void)
-{
-	unsigned long flags;
-
-	__asm__ __volatile__ (
-		"stc	sr, %0\n\t"
-		"or	#0xf0, %0\n\t"
-		"ldc	%0, sr\n\t"
-		: "=&z" (flags)
-		: /* no inputs */
-		: "memory"
-	);
-}
-
-static inline void set_bl_bit(void)
-{
-	unsigned long __dummy0, __dummy1;
-
-	__asm__ __volatile__ (
-		"stc	sr, %0\n\t"
-		"or	%2, %0\n\t"
-		"and	%3, %0\n\t"
-		"ldc	%0, sr\n\t"
-		: "=&r" (__dummy0), "=r" (__dummy1)
-		: "r" (0x10000000), "r" (0xffffff0f)
-		: "memory"
-	);
-}
-
-static inline void clear_bl_bit(void)
-{
-	unsigned long __dummy0, __dummy1;
-
-	__asm__ __volatile__ (
-		"stc	sr, %0\n\t"
-		"and	%2, %0\n\t"
-		"ldc	%0, sr\n\t"
-		: "=&r" (__dummy0), "=r" (__dummy1)
-		: "1" (~0x10000000)
-		: "memory"
-	);
-}
-
-static inline unsigned long __raw_local_save_flags(void)
-{
-	unsigned long flags;
-
-	__asm__ __volatile__ (
-		"stc	sr, %0\n\t"
-		"and	#0xf0, %0\n\t"
-		: "=&z" (flags)
-		: /* no inputs */
-		: "memory"
-	);
-
-	return flags;
-}
-
-static inline unsigned long __raw_local_irq_save(void)
-{
-	unsigned long flags, __dummy;
-
-	__asm__ __volatile__ (
-		"stc	sr, %1\n\t"
-		"mov	%1, %0\n\t"
-		"or	#0xf0, %0\n\t"
-		"ldc	%0, sr\n\t"
-		"mov	%1, %0\n\t"
-		"and	#0xf0, %0\n\t"
-		: "=&z" (flags), "=&r" (__dummy)
-		: /* no inputs */
-		: "memory"
-	);
-
-	return flags;
-}
-
-#endif /* __ASM_SH_IRQFLAGS_32_H */
diff --git a/arch/sh/include/asm/irqflags_64.h b/arch/sh/include/asm/irqflags_64.h
deleted file mode 100644
index 88f6522..0000000
--- a/arch/sh/include/asm/irqflags_64.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef __ASM_SH_IRQFLAGS_64_H
-#define __ASM_SH_IRQFLAGS_64_H
-
-#include <cpu/registers.h>
-
-#define SR_MASK_LL	0x00000000000000f0LL
-#define SR_BL_LL	0x0000000010000000LL
-
-static inline void raw_local_irq_enable(void)
-{
-	unsigned long long __dummy0, __dummy1 = ~SR_MASK_LL;
-
-	__asm__ __volatile__("getcon	" __SR ", %0\n\t"
-			     "and	%0, %1, %0\n\t"
-			     "putcon	%0, " __SR "\n\t"
-			     : "=&r" (__dummy0)
-			     : "r" (__dummy1));
-}
-
-static inline void raw_local_irq_disable(void)
-{
-	unsigned long long __dummy0, __dummy1 = SR_MASK_LL;
-
-	__asm__ __volatile__("getcon	" __SR ", %0\n\t"
-			     "or	%0, %1, %0\n\t"
-			     "putcon	%0, " __SR "\n\t"
-			     : "=&r" (__dummy0)
-			     : "r" (__dummy1));
-}
-
-static inline void set_bl_bit(void)
-{
-	unsigned long long __dummy0, __dummy1 = SR_BL_LL;
-
-	__asm__ __volatile__("getcon	" __SR ", %0\n\t"
-			     "or	%0, %1, %0\n\t"
-			     "putcon	%0, " __SR "\n\t"
-			     : "=&r" (__dummy0)
-			     : "r" (__dummy1));
-
-}
-
-static inline void clear_bl_bit(void)
-{
-	unsigned long long __dummy0, __dummy1 = ~SR_BL_LL;
-
-	__asm__ __volatile__("getcon	" __SR ", %0\n\t"
-			     "and	%0, %1, %0\n\t"
-			     "putcon	%0, " __SR "\n\t"
-			     : "=&r" (__dummy0)
-			     : "r" (__dummy1));
-}
-
-static inline unsigned long __raw_local_save_flags(void)
-{
-	unsigned long long __dummy = SR_MASK_LL;
-	unsigned long flags;
-
-	__asm__ __volatile__ (
-		"getcon	" __SR ", %0\n\t"
-		"and	%0, %1, %0"
-		: "=&r" (flags)
-		: "r" (__dummy));
-
-	return flags;
-}
-
-static inline unsigned long __raw_local_irq_save(void)
-{
-	unsigned long long __dummy0, __dummy1 = SR_MASK_LL;
-	unsigned long flags;
-
-	__asm__ __volatile__ (
-		"getcon	" __SR ", %1\n\t"
-		"or	%1, r63, %0\n\t"
-		"or	%1, %2, %1\n\t"
-		"putcon	%1, " __SR "\n\t"
-		"and	%0, %2, %0"
-		: "=&r" (flags), "=&r" (__dummy0)
-		: "r" (__dummy1));
-
-	return flags;
-}
-
-#endif /* __ASM_SH_IRQFLAGS_64_H */
diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h
index f596303..c7426ad 100644
--- a/arch/sh/include/asm/mmu.h
+++ b/arch/sh/include/asm/mmu.h
@@ -7,12 +7,16 @@
 #define PMB_PASCR		0xff000070
 #define PMB_IRMCR		0xff000078
 
+#define PASCR_SE		0x80000000
+
 #define PMB_ADDR		0xf6100000
 #define PMB_DATA		0xf7100000
 #define PMB_ENTRY_MAX		16
 #define PMB_E_MASK		0x0000000f
 #define PMB_E_SHIFT		8
 
+#define PMB_PFN_MASK		0xff000000
+
 #define PMB_SZ_16M		0x00000000
 #define PMB_SZ_64M		0x00000010
 #define PMB_SZ_128M		0x00000080
@@ -62,17 +66,10 @@
 };
 
 /* arch/sh/mm/pmb.c */
-int __set_pmb_entry(unsigned long vpn, unsigned long ppn,
-		    unsigned long flags, int *entry);
-int set_pmb_entry(struct pmb_entry *pmbe);
-void clear_pmb_entry(struct pmb_entry *pmbe);
-struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn,
-			    unsigned long flags);
-void pmb_free(struct pmb_entry *pmbe);
 long pmb_remap(unsigned long virt, unsigned long phys,
 	       unsigned long size, unsigned long flags);
 void pmb_unmap(unsigned long addr);
+int pmb_init(void);
 #endif /* __ASSEMBLY__ */
 
 #endif /* __MMU_H */
-
diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h
index 4163950..67f3999 100644
--- a/arch/sh/include/asm/pci.h
+++ b/arch/sh/include/asm/pci.h
@@ -3,8 +3,6 @@
 
 #ifdef __KERNEL__
 
-#include <linux/dma-mapping.h>
-
 /* Can be used to override the logic in pci_scan_bus for skipping
    already-configured bus numbers - to be used for buggy BIOSes
    or architectures with incomplete PCI setup by the loader */
@@ -54,30 +52,18 @@
  * address space.  The networking and block device layers use
  * this boolean for bounce buffer decisions.
  */
-#define PCI_DMA_BUS_IS_PHYS	(1)
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/scatterlist.h>
-#include <linux/string.h>
-#include <asm/io.h>
+#define PCI_DMA_BUS_IS_PHYS	(dma_ops->is_phys)
 
 /* pci_unmap_{single,page} being a nop depends upon the
  * configuration.
  */
-#ifdef CONFIG_SH_PCIDMA_NONCOHERENT
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)	\
-	dma_addr_t ADDR_NAME;
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)		\
-	__u32 LEN_NAME;
-#define pci_unmap_addr(PTR, ADDR_NAME)			\
-	((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)		\
-	(((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME)			\
-	((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL)		\
-	(((PTR)->LEN_NAME) = (VAL))
+#ifdef CONFIG_DMA_NONCOHERENT
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)	dma_addr_t ADDR_NAME;
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)		__u32 LEN_NAME;
+#define pci_unmap_addr(PTR, ADDR_NAME)		((PTR)->ADDR_NAME)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)	(((PTR)->ADDR_NAME) = (VAL))
+#define pci_unmap_len(PTR, LEN_NAME)		((PTR)->LEN_NAME)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL)	(((PTR)->LEN_NAME) = (VAL))
 #else
 #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
 #define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
diff --git a/arch/sh/include/asm/perf_event.h b/arch/sh/include/asm/perf_event.h
index 11a3022..3d0c9f3 100644
--- a/arch/sh/include/asm/perf_event.h
+++ b/arch/sh/include/asm/perf_event.h
@@ -1,8 +1,35 @@
 #ifndef __ASM_SH_PERF_EVENT_H
 #define __ASM_SH_PERF_EVENT_H
 
-/* SH only supports software events through this interface. */
-static inline void set_perf_event_pending(void) {}
+struct hw_perf_event;
+
+#define MAX_HWEVENTS	2
+
+struct sh_pmu {
+	const char	*name;
+	unsigned int	num_events;
+	void		(*disable_all)(void);
+	void		(*enable_all)(void);
+	void		(*enable)(struct hw_perf_event *, int);
+	void		(*disable)(struct hw_perf_event *, int);
+	u64		(*read)(int);
+	int		(*event_map)(int);
+	unsigned int	max_events;
+	unsigned long	raw_event_mask;
+	const int	(*cache_events)[PERF_COUNT_HW_CACHE_MAX]
+				       [PERF_COUNT_HW_CACHE_OP_MAX]
+				       [PERF_COUNT_HW_CACHE_RESULT_MAX];
+};
+
+/* arch/sh/kernel/perf_event.c */
+extern int register_sh_pmu(struct sh_pmu *);
+extern int reserve_pmc_hardware(void);
+extern void release_pmc_hardware(void);
+
+static inline void set_perf_event_pending(void)
+{
+	/* Nothing to see here, move along. */
+}
 
 #define PERF_EVENT_INDEX_OFFSET	0
 
diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h
index 4f3efa7..ba3046e 100644
--- a/arch/sh/include/asm/pgtable.h
+++ b/arch/sh/include/asm/pgtable.h
@@ -75,13 +75,31 @@
 #define USER_PTRS_PER_PGD	(TASK_SIZE/PGDIR_SIZE)
 #define FIRST_USER_ADDRESS	0
 
-#ifdef CONFIG_32BIT
-#define PHYS_ADDR_MASK		0xffffffff
+#define PHYS_ADDR_MASK29		0x1fffffff
+#define PHYS_ADDR_MASK32		0xffffffff
+
+#ifdef CONFIG_PMB
+static inline unsigned long phys_addr_mask(void)
+{
+	/* Is the MMU in 29bit mode? */
+	if (__in_29bit_mode())
+		return PHYS_ADDR_MASK29;
+
+	return PHYS_ADDR_MASK32;
+}
+#elif defined(CONFIG_32BIT)
+static inline unsigned long phys_addr_mask(void)
+{
+	return PHYS_ADDR_MASK32;
+}
 #else
-#define PHYS_ADDR_MASK		0x1fffffff
+static inline unsigned long phys_addr_mask(void)
+{
+	return PHYS_ADDR_MASK29;
+}
 #endif
 
-#define PTE_PHYS_MASK		(PHYS_ADDR_MASK & PAGE_MASK)
+#define PTE_PHYS_MASK		(phys_addr_mask() & PAGE_MASK)
 #define PTE_FLAGS_MASK		(~(PTE_PHYS_MASK) << PAGE_SHIFT)
 
 #ifdef CONFIG_SUPERH32
diff --git a/arch/sh/include/asm/pgtable_32.h b/arch/sh/include/asm/pgtable_32.h
index c0d359c..b354355 100644
--- a/arch/sh/include/asm/pgtable_32.h
+++ b/arch/sh/include/asm/pgtable_32.h
@@ -108,7 +108,7 @@
 #define _PAGE_CLEAR_FLAGS	(_PAGE_PROTNONE | _PAGE_ACCESSED | _PAGE_FILE)
 #endif
 
-#define _PAGE_FLAGS_HARDWARE_MASK	(PHYS_ADDR_MASK & ~(_PAGE_CLEAR_FLAGS))
+#define _PAGE_FLAGS_HARDWARE_MASK	(phys_addr_mask() & ~(_PAGE_CLEAR_FLAGS))
 
 /* Hardware flags, page size encoding */
 #if !defined(CONFIG_MMU)
diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h
index 9a87149..1f3d6fa 100644
--- a/arch/sh/include/asm/processor_32.h
+++ b/arch/sh/include/asm/processor_32.h
@@ -56,6 +56,7 @@
 #define SR_DSP		0x00001000
 #define SR_IMASK	0x000000f0
 #define SR_FD		0x00008000
+#define SR_MD		0x40000000
 
 /*
  * DSP structure and data
@@ -136,7 +137,7 @@
 extern void release_thread(struct task_struct *);
 
 /* Prepare to copy thread state - unlazy all lazy status */
-#define prepare_to_copy(tsk)	do { } while (0)
+void prepare_to_copy(struct task_struct *tsk);
 
 /*
  * create a kernel thread without removing it from tasklists
diff --git a/arch/sh/include/asm/scatterlist.h b/arch/sh/include/asm/scatterlist.h
index 327cc2e..e38d1d4 100644
--- a/arch/sh/include/asm/scatterlist.h
+++ b/arch/sh/include/asm/scatterlist.h
@@ -1,7 +1,7 @@
 #ifndef __ASM_SH_SCATTERLIST_H
 #define __ASM_SH_SCATTERLIST_H
 
-#define ISA_DMA_THRESHOLD	PHYS_ADDR_MASK
+#define ISA_DMA_THRESHOLD	phys_addr_mask()
 
 #include <asm-generic/scatterlist.h>
 
diff --git a/arch/sh/include/asm/sh_keysc.h b/arch/sh/include/asm/sh_keysc.h
deleted file mode 100644
index 4a65b1e..0000000
--- a/arch/sh/include/asm/sh_keysc.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef __ASM_KEYSC_H__
-#define __ASM_KEYSC_H__
-
-#define SH_KEYSC_MAXKEYS 30
-
-struct sh_keysc_info {
-	enum { SH_KEYSC_MODE_1, SH_KEYSC_MODE_2, SH_KEYSC_MODE_3 } mode;
-	int scan_timing; /* 0 -> 7, see KYCR1, SCN[2:0] */
-	int delay;
-	int kycr2_delay;
-	int keycodes[SH_KEYSC_MAXKEYS];
-};
-
-#endif /* __ASM_KEYSC_H__ */
diff --git a/arch/sh/include/asm/suspend.h b/arch/sh/include/asm/suspend.h
index 5c8ea28..fe9c2a1 100644
--- a/arch/sh/include/asm/suspend.h
+++ b/arch/sh/include/asm/suspend.h
@@ -2,6 +2,7 @@
 #define _ASM_SH_SUSPEND_H
 
 #ifndef __ASSEMBLY__
+#include <linux/notifier.h>
 static inline int arch_prepare_suspend(void) { return 0; }
 
 #include <asm/ptrace.h>
@@ -19,6 +20,69 @@
 static inline void sh_mobile_setup_cpuidle(void) {}
 #endif
 
+/* notifier chains for pre/post sleep hooks */
+extern struct atomic_notifier_head sh_mobile_pre_sleep_notifier_list;
+extern struct atomic_notifier_head sh_mobile_post_sleep_notifier_list;
+
+/* priority levels for notifiers */
+#define SH_MOBILE_SLEEP_BOARD	0
+#define SH_MOBILE_SLEEP_CPU	1
+#define SH_MOBILE_PRE(x)	(x)
+#define SH_MOBILE_POST(x)	(-(x))
+
+/* board code registration function for self-refresh assembly snippets */
+void sh_mobile_register_self_refresh(unsigned long flags,
+				     void *pre_start, void *pre_end,
+				     void *post_start, void *post_end);
+
+/* register structure for address/data information */
+struct sh_sleep_regs {
+	unsigned long stbcr;
+	unsigned long bar;
+
+	/* MMU */
+	unsigned long pteh;
+	unsigned long ptel;
+	unsigned long ttb;
+	unsigned long tea;
+	unsigned long mmucr;
+	unsigned long ptea;
+	unsigned long pascr;
+	unsigned long irmcr;
+
+	/* Cache */
+	unsigned long ccr;
+	unsigned long ramcr;
+};
+
+/* data area for low-level sleep code */
+struct sh_sleep_data {
+	/* current sleep mode (SUSP_SH_...) */
+	unsigned long mode;
+
+	/* addresses of board specific self-refresh snippets */
+	unsigned long sf_pre;
+	unsigned long sf_post;
+
+	/* address of resume code */
+	unsigned long resume;
+
+	/* register state saved and restored by the assembly code */
+	unsigned long vbr;
+	unsigned long spc;
+	unsigned long sr;
+	unsigned long sp;
+
+	/* structure for keeping register addresses */
+	struct sh_sleep_regs addr;
+
+	/* structure for saving/restoring register state */
+	struct sh_sleep_regs data;
+};
+
+/* a bitmap of supported sleep modes (SUSP_SH..) */
+extern unsigned long sh_mobile_sleep_supported;
+
 #endif
 
 /* flags passed to assembly suspend code */
@@ -27,5 +91,6 @@
 #define SUSP_SH_RSTANDBY	(1 << 2) /* SH-Mobile R-standby mode */
 #define SUSP_SH_USTANDBY	(1 << 3) /* SH-Mobile U-standby mode */
 #define SUSP_SH_SF		(1 << 4) /* Enable self-refresh */
+#define SUSP_SH_MMU		(1 << 5) /* Save/restore MMU and cache */
 
 #endif /* _ASM_SH_SUSPEND_H */
diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h
index b5c5acd..c15415b 100644
--- a/arch/sh/include/asm/system.h
+++ b/arch/sh/include/asm/system.h
@@ -171,10 +171,6 @@
 BUILD_TRAP_HANDLER(fpu_state_restore);
 BUILD_TRAP_HANDLER(nmi);
 
-#ifdef CONFIG_BUG
-extern void handle_BUG(struct pt_regs *);
-#endif
-
 #define arch_align_stack(x) (x)
 
 struct mem_access {
diff --git a/arch/sh/include/asm/system_32.h b/arch/sh/include/asm/system_32.h
index 607d413..06814f5 100644
--- a/arch/sh/include/asm/system_32.h
+++ b/arch/sh/include/asm/system_32.h
@@ -232,4 +232,33 @@
 				   unsigned long r6, unsigned long r7,
 				   struct pt_regs __regs);
 
+static inline void set_bl_bit(void)
+{
+	unsigned long __dummy0, __dummy1;
+
+	__asm__ __volatile__ (
+		"stc	sr, %0\n\t"
+		"or	%2, %0\n\t"
+		"and	%3, %0\n\t"
+		"ldc	%0, sr\n\t"
+		: "=&r" (__dummy0), "=r" (__dummy1)
+		: "r" (0x10000000), "r" (0xffffff0f)
+		: "memory"
+	);
+}
+
+static inline void clear_bl_bit(void)
+{
+	unsigned long __dummy0, __dummy1;
+
+	__asm__ __volatile__ (
+		"stc	sr, %0\n\t"
+		"and	%2, %0\n\t"
+		"ldc	%0, sr\n\t"
+		: "=&r" (__dummy0), "=r" (__dummy1)
+		: "1" (~0x10000000)
+		: "memory"
+	);
+}
+
 #endif /* __ASM_SH_SYSTEM_32_H */
diff --git a/arch/sh/include/asm/system_64.h b/arch/sh/include/asm/system_64.h
index 8e4a03e..ab1dd91 100644
--- a/arch/sh/include/asm/system_64.h
+++ b/arch/sh/include/asm/system_64.h
@@ -12,6 +12,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  */
+#include <cpu/registers.h>
 #include <asm/processor.h>
 
 /*
@@ -47,4 +48,29 @@
 	return (unsigned long long)(signed long long)(signed long)val;
 }
 
+#define SR_BL_LL	0x0000000010000000LL
+
+static inline void set_bl_bit(void)
+{
+	unsigned long long __dummy0, __dummy1 = SR_BL_LL;
+
+	__asm__ __volatile__("getcon	" __SR ", %0\n\t"
+			     "or	%0, %1, %0\n\t"
+			     "putcon	%0, " __SR "\n\t"
+			     : "=&r" (__dummy0)
+			     : "r" (__dummy1));
+
+}
+
+static inline void clear_bl_bit(void)
+{
+	unsigned long long __dummy0, __dummy1 = ~SR_BL_LL;
+
+	__asm__ __volatile__("getcon	" __SR ", %0\n\t"
+			     "and	%0, %1, %0\n\t"
+			     "putcon	%0, " __SR "\n\t"
+			     : "=&r" (__dummy0)
+			     : "r" (__dummy1));
+}
+
 #endif /* __ASM_SH_SYSTEM_64_H */
diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h
index bdeb9d4..1f3d927 100644
--- a/arch/sh/include/asm/thread_info.h
+++ b/arch/sh/include/asm/thread_info.h
@@ -19,6 +19,7 @@
 	struct task_struct	*task;		/* main task structure */
 	struct exec_domain	*exec_domain;	/* execution domain */
 	unsigned long		flags;		/* low level flags */
+	__u32			status;		/* thread synchronous flags */
 	__u32			cpu;
 	int			preempt_count; /* 0 => preemptable, <0 => BUG */
 	mm_segment_t		addr_limit;	/* thread address space */
@@ -50,6 +51,7 @@
 	.task		= &tsk,			\
 	.exec_domain	= &default_exec_domain,	\
 	.flags		= 0,			\
+	.status		= 0,			\
 	.cpu		= 0,			\
 	.preempt_count	= INIT_PREEMPT_COUNT,	\
 	.addr_limit	= KERNEL_DS,		\
@@ -111,13 +113,11 @@
 #define TIF_SYSCALL_TRACE	0	/* syscall trace active */
 #define TIF_SIGPENDING		1	/* signal pending */
 #define TIF_NEED_RESCHED	2	/* rescheduling necessary */
-#define TIF_RESTORE_SIGMASK	3	/* restore signal mask in do_signal() */
 #define TIF_SINGLESTEP		4	/* singlestepping active */
 #define TIF_SYSCALL_AUDIT	5	/* syscall auditing active */
 #define TIF_SECCOMP		6	/* secure computing */
 #define TIF_NOTIFY_RESUME	7	/* callback before returning to user */
 #define TIF_SYSCALL_TRACEPOINT	8	/* for ftrace syscall instrumentation */
-#define TIF_USEDFPU		16	/* FPU was used by this task this quantum (SMP) */
 #define TIF_POLLING_NRFLAG	17	/* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE		18
 #define TIF_FREEZE		19	/* Freezing for suspend */
@@ -125,13 +125,11 @@
 #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
-#define _TIF_RESTORE_SIGMASK	(1 << TIF_RESTORE_SIGMASK)
 #define _TIF_SINGLESTEP		(1 << TIF_SINGLESTEP)
 #define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
 #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
 #define _TIF_SYSCALL_TRACEPOINT	(1 << TIF_SYSCALL_TRACEPOINT)
-#define _TIF_USEDFPU		(1 << TIF_USEDFPU)
 #define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)
 #define _TIF_FREEZE		(1 << TIF_FREEZE)
 
@@ -149,13 +147,33 @@
 /* work to do on any return to u-space */
 #define _TIF_ALLWORK_MASK	(_TIF_SYSCALL_TRACE | _TIF_SIGPENDING      | \
 				 _TIF_NEED_RESCHED  | _TIF_SYSCALL_AUDIT   | \
-				 _TIF_SINGLESTEP    | _TIF_RESTORE_SIGMASK | \
-				 _TIF_NOTIFY_RESUME | _TIF_SYSCALL_TRACEPOINT)
+				 _TIF_SINGLESTEP    | _TIF_NOTIFY_RESUME   | \
+				 _TIF_SYSCALL_TRACEPOINT)
 
 /* work to do on interrupt/exception return */
 #define _TIF_WORK_MASK		(_TIF_ALLWORK_MASK & ~(_TIF_SYSCALL_TRACE | \
 				 _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP))
 
+/*
+ * Thread-synchronous status.
+ *
+ * This is different from the flags in that nobody else
+ * ever touches our thread-synchronous status, so we don't
+ * have to worry about atomic accesses.
+ */
+#define TS_RESTORE_SIGMASK	0x0001	/* restore signal mask in do_signal() */
+#define TS_USEDFPU		0x0002	/* FPU used by this task this quantum */
+
+#ifndef __ASSEMBLY__
+#define HAVE_SET_RESTORE_SIGMASK	1
+static inline void set_restore_sigmask(void)
+{
+	struct thread_info *ti = current_thread_info();
+	ti->status |= TS_RESTORE_SIGMASK;
+	set_bit(TIF_SIGPENDING, (unsigned long *)&ti->flags);
+}
+#endif	/* !__ASSEMBLY__ */
+
 #endif /* __KERNEL__ */
 
 #endif /* __ASM_SH_THREAD_INFO_H */
diff --git a/arch/sh/include/asm/topology.h b/arch/sh/include/asm/topology.h
index 65e7bd2..37cdadd 100644
--- a/arch/sh/include/asm/topology.h
+++ b/arch/sh/include/asm/topology.h
@@ -40,6 +40,14 @@
 
 #endif
 
+#define mc_capable()    (1)
+
+const struct cpumask *cpu_coregroup_mask(unsigned int cpu);
+
+extern cpumask_t cpu_core_map[NR_CPUS];
+
+#define topology_core_cpumask(cpu)	(&cpu_core_map[cpu])
+
 #include <asm-generic/topology.h>
 
 #endif /* _ASM_SH_TOPOLOGY_H */
diff --git a/arch/sh/include/asm/ubc.h b/arch/sh/include/asm/ubc.h
index 4ca4b77..9bf9616 100644
--- a/arch/sh/include/asm/ubc.h
+++ b/arch/sh/include/asm/ubc.h
@@ -60,16 +60,5 @@
 #define BRCR_UBDE		(1 << 0)
 #endif
 
-#ifndef __ASSEMBLY__
-/* arch/sh/kernel/cpu/ubc.S */
-extern void ubc_sleep(void);
-
-#ifdef CONFIG_UBC_WAKEUP
-extern void ubc_wakeup(void);
-#else
-#define ubc_wakeup()	do { } while (0)
-#endif
-#endif
-
 #endif /* __KERNEL__ */
 #endif /* __ASM_SH_UBC_H */
diff --git a/arch/sh/include/asm/watchdog.h b/arch/sh/include/asm/watchdog.h
index 2fe7cee..19dfff5 100644
--- a/arch/sh/include/asm/watchdog.h
+++ b/arch/sh/include/asm/watchdog.h
@@ -2,6 +2,8 @@
  * include/asm-sh/watchdog.h
  *
  * Copyright (C) 2002, 2003 Paul Mundt
+ * Copyright (C) 2009 Siemens AG
+ * Copyright (C) 2009 Valentin Sitdikov
  *
  * 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
@@ -61,6 +63,61 @@
 #define WTCSR_CKS_2048	0x06
 #define WTCSR_CKS_4096	0x07
 
+#if defined(CONFIG_CPU_SUBTYPE_SH7785) || defined(CONFIG_CPU_SUBTYPE_SH7780)
+/**
+ * 	sh_wdt_read_cnt - Read from Counter
+ * 	Reads back the WTCNT value.
+ */
+static inline __u32 sh_wdt_read_cnt(void)
+{
+	return ctrl_inl(WTCNT_R);
+}
+
+/**
+ *	sh_wdt_write_cnt - Write to Counter
+ *	@val: Value to write
+ *
+ *	Writes the given value @val to the lower byte of the timer counter.
+ *	The upper byte is set manually on each write.
+ */
+static inline void sh_wdt_write_cnt(__u32 val)
+{
+	ctrl_outl((WTCNT_HIGH << 24) | (__u32)val, WTCNT);
+}
+
+/**
+ *	sh_wdt_write_bst - Write to Counter
+ *	@val: Value to write
+ *
+ *	Writes the given value @val to the lower byte of the timer counter.
+ *	The upper byte is set manually on each write.
+ */
+static inline void sh_wdt_write_bst(__u32 val)
+{
+	ctrl_outl((WTBST_HIGH << 24) | (__u32)val, WTBST);
+}
+/**
+ * 	sh_wdt_read_csr - Read from Control/Status Register
+ *
+ *	Reads back the WTCSR value.
+ */
+static inline __u32 sh_wdt_read_csr(void)
+{
+	return ctrl_inl(WTCSR_R);
+}
+
+/**
+ * 	sh_wdt_write_csr - Write to Control/Status Register
+ * 	@val: Value to write
+ *
+ * 	Writes the given value @val to the lower byte of the control/status
+ * 	register. The upper byte is set manually on each write.
+ */
+static inline void sh_wdt_write_csr(__u32 val)
+{
+	ctrl_outl((WTCSR_HIGH << 24) | (__u32)val, WTCSR);
+}
+#else
 /**
  * 	sh_wdt_read_cnt - Read from Counter
  * 	Reads back the WTCNT value.
@@ -103,6 +160,6 @@
 {
 	ctrl_outw((WTCSR_HIGH << 8) | (__u16)val, WTCSR);
 }
-
+#endif /* CONFIG_CPU_SUBTYPE_SH7785 || CONFIG_CPU_SUBTYPE_SH7780 */
 #endif /* __KERNEL__ */
 #endif /* __ASM_SH_WATCHDOG_H */
diff --git a/arch/sh/include/cpu-sh4/cpu/watchdog.h b/arch/sh/include/cpu-sh4/cpu/watchdog.h
index 259f6a0..7672301 100644
--- a/arch/sh/include/cpu-sh4/cpu/watchdog.h
+++ b/arch/sh/include/cpu-sh4/cpu/watchdog.h
@@ -2,6 +2,8 @@
  * include/asm-sh/cpu-sh4/watchdog.h
  *
  * Copyright (C) 2002, 2003 Paul Mundt
+ * Copyright (C) 2009 Siemens AG
+ * Copyright (C) 2009 Sitdikov Valentin
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -10,9 +12,20 @@
 #ifndef __ASM_CPU_SH4_WATCHDOG_H
 #define __ASM_CPU_SH4_WATCHDOG_H
 
+#if defined(CONFIG_CPU_SUBTYPE_SH7785) || defined(CONFIG_CPU_SUBTYPE_SH7780)
+/* Prefix definition */
+#define WTBST_HIGH	0x55
+/* Register definitions */
+#define WTCNT_R		0xffcc0010 /*WDTCNT*/
+#define WTCSR		0xffcc0004 /*WDTCSR*/
+#define WTCNT		0xffcc0000 /*WDTST*/
+#define WTST		WTCNT
+#define WTBST		0xffcc0008 /*WDTBST*/
+#else
 /* Register definitions */
 #define WTCNT		0xffc00008
 #define WTCSR		0xffc0000c
+#endif
 
 /* Bit definitions */
 #define WTCSR_TME	0x80
diff --git a/arch/sh/include/mach-common/mach/titan.h b/arch/sh/include/mach-common/mach/titan.h
index 03f3583..4a674d2 100644
--- a/arch/sh/include/mach-common/mach/titan.h
+++ b/arch/sh/include/mach-common/mach/titan.h
@@ -1,5 +1,5 @@
 /*
- * Platform defintions for Titan
+ * Platform definitions for Titan
  */
 #ifndef _ASM_SH_TITAN_H
 #define _ASM_SH_TITAN_H
diff --git a/arch/sh/include/mach-ecovec24/mach/partner-jet-setup.txt b/arch/sh/include/mach-ecovec24/mach/partner-jet-setup.txt
index 8b8e4fa..cc737b8 100644
--- a/arch/sh/include/mach-ecovec24/mach/partner-jet-setup.txt
+++ b/arch/sh/include/mach-ecovec24/mach/partner-jet-setup.txt
@@ -22,13 +22,12 @@
 LIST "setup clocks"
 ED 0xa4150024, 0x00004000
 ED 0xa4150000, 0x8E003508
-ED 0xa4150004, 0x00000000
 
 WAIT 1
 
 LIST "BSC"
 ED 0xff800020, 0xa5a50000
-ED 0xfec10000, 0x00000013
+ED 0xfec10000, 0x00001013
 ED 0xfec10004, 0x11110400
 ED 0xfec10024, 0x00000440
 
diff --git a/arch/sh/include/mach-se/mach/se7722.h b/arch/sh/include/mach-se/mach/se7722.h
index e971d9a..16505bf 100644
--- a/arch/sh/include/mach-se/mach/se7722.h
+++ b/arch/sh/include/mach-se/mach/se7722.h
@@ -92,18 +92,11 @@
 #define SE7722_FPGA_IRQ_MRSHPC1	3 /* IRQ1 */
 #define SE7722_FPGA_IRQ_MRSHPC2	4 /* IRQ1 */
 #define SE7722_FPGA_IRQ_MRSHPC3	5 /* IRQ1 */
-
 #define SE7722_FPGA_IRQ_NR	6
-#define SE7722_FPGA_IRQ_BASE	110
-
-#define MRSHPC_IRQ3    	(SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC3)
-#define MRSHPC_IRQ2    	(SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC2)
-#define MRSHPC_IRQ1    	(SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC1)
-#define MRSHPC_IRQ0    	(SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC0)
-#define SMC_IRQ		(SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_SMC)
-#define USB_IRQ		(SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_USB)
 
 /* arch/sh/boards/se/7722/irq.c */
+extern unsigned int se7722_fpga_irq[];
+
 void init_se7722_IRQ(void);
 
 #define __IO_PREFIX		se7722
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index a2d0a40..0471a3e 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -9,8 +9,12 @@
 CFLAGS_REMOVE_ftrace.o = -pg
 endif
 
-obj-y	:= debugtraps.o dumpstack.o idle.o io.o io_generic.o irq.o	\
-	   machvec.o nmi_debug.o process_$(BITS).o ptrace_$(BITS).o	\
+CFLAGS_REMOVE_return_address.o = -pg
+
+obj-y	:= debugtraps.o dma-nommu.o dumpstack.o 			\
+	   idle.o io.o io_generic.o irq.o				\
+	   irq_$(BITS).o machvec.o nmi_debug.o process_$(BITS).o 	\
+	   ptrace_$(BITS).o return_address.o				\
 	   setup.o signal_$(BITS).o sys_sh.o sys_sh$(BITS).o		\
 	   syscalls_$(BITS).o time.o topology.o traps.o			\
 	   traps_$(BITS).o unwinder.o
@@ -28,13 +32,13 @@
 obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
 obj-$(CONFIG_IO_TRAPPED)	+= io_trapped.o
 obj-$(CONFIG_KPROBES)		+= kprobes.o
-obj-$(CONFIG_GENERIC_GPIO)	+= gpio.o
 obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
 obj-$(CONFIG_FTRACE_SYSCALLS)	+= ftrace.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
 obj-$(CONFIG_DUMP_CODE)		+= disassemble.o
 obj-$(CONFIG_HIBERNATION)	+= swsusp.o
 obj-$(CONFIG_DWARF_UNWINDER)	+= dwarf.o
+obj-$(CONFIG_PERF_EVENTS)	+= perf_event.o perf_callchain.o
 
 obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)	+= localtimer.o
 
diff --git a/arch/sh/kernel/asm-offsets.c b/arch/sh/kernel/asm-offsets.c
index d218e80..08a2be7 100644
--- a/arch/sh/kernel/asm-offsets.c
+++ b/arch/sh/kernel/asm-offsets.c
@@ -34,5 +34,28 @@
 	DEFINE(PBE_NEXT, offsetof(struct pbe, next));
 	DEFINE(SWSUSP_ARCH_REGS_SIZE, sizeof(struct swsusp_arch_regs));
 #endif
+
+	DEFINE(SH_SLEEP_MODE, offsetof(struct sh_sleep_data, mode));
+	DEFINE(SH_SLEEP_SF_PRE, offsetof(struct sh_sleep_data, sf_pre));
+	DEFINE(SH_SLEEP_SF_POST, offsetof(struct sh_sleep_data, sf_post));
+	DEFINE(SH_SLEEP_RESUME, offsetof(struct sh_sleep_data, resume));
+	DEFINE(SH_SLEEP_VBR, offsetof(struct sh_sleep_data, vbr));
+	DEFINE(SH_SLEEP_SPC, offsetof(struct sh_sleep_data, spc));
+	DEFINE(SH_SLEEP_SR, offsetof(struct sh_sleep_data, sr));
+	DEFINE(SH_SLEEP_SP, offsetof(struct sh_sleep_data, sp));
+	DEFINE(SH_SLEEP_BASE_ADDR, offsetof(struct sh_sleep_data, addr));
+	DEFINE(SH_SLEEP_BASE_DATA, offsetof(struct sh_sleep_data, data));
+	DEFINE(SH_SLEEP_REG_STBCR, offsetof(struct sh_sleep_regs, stbcr));
+	DEFINE(SH_SLEEP_REG_BAR, offsetof(struct sh_sleep_regs, bar));
+	DEFINE(SH_SLEEP_REG_PTEH, offsetof(struct sh_sleep_regs, pteh));
+	DEFINE(SH_SLEEP_REG_PTEL, offsetof(struct sh_sleep_regs, ptel));
+	DEFINE(SH_SLEEP_REG_TTB, offsetof(struct sh_sleep_regs, ttb));
+	DEFINE(SH_SLEEP_REG_TEA, offsetof(struct sh_sleep_regs, tea));
+	DEFINE(SH_SLEEP_REG_MMUCR, offsetof(struct sh_sleep_regs, mmucr));
+	DEFINE(SH_SLEEP_REG_PTEA, offsetof(struct sh_sleep_regs, ptea));
+	DEFINE(SH_SLEEP_REG_PASCR, offsetof(struct sh_sleep_regs, pascr));
+	DEFINE(SH_SLEEP_REG_IRMCR, offsetof(struct sh_sleep_regs, irmcr));
+	DEFINE(SH_SLEEP_REG_CCR, offsetof(struct sh_sleep_regs, ccr));
+	DEFINE(SH_SLEEP_REG_RAMCR, offsetof(struct sh_sleep_regs, ramcr));
 	return 0;
 }
diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile
index 3d6b931..d97c803 100644
--- a/arch/sh/kernel/cpu/Makefile
+++ b/arch/sh/kernel/cpu/Makefile
@@ -15,7 +15,6 @@
 
 # Common interfaces.
 
-obj-$(CONFIG_UBC_WAKEUP)	+= ubc.o
 obj-$(CONFIG_SH_ADC)		+= adc.o
 obj-$(CONFIG_SH_CLK_CPG)	+= clock-cpg.o
 
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index e932ebe..89b4b76 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -75,16 +75,11 @@
 	/*
 	 * Future proofing.
 	 *
-	 * Disable support for slottable sleep instruction
-	 * and non-nop instructions in the rte delay slot.
+	 * Disable support for slottable sleep instruction, non-nop
+	 * instructions in the rte delay slot, and associative writes to
+	 * the memory-mapped cache array.
 	 */
-	expmask &= ~(EXPMASK_RTEDS | EXPMASK_BRDSSLP);
-
-	/*
-	 * Enable associative writes to the memory-mapped cache array
-	 * until the cache flush ops have been rewritten.
-	 */
-	expmask |= EXPMASK_MMCAW;
+	expmask &= ~(EXPMASK_RTEDS | EXPMASK_BRDSSLP | EXPMASK_MMCAW);
 
 	__raw_writel(expmask, EXPMASK);
 	ctrl_barrier();
@@ -311,12 +306,12 @@
 	if (fpu_disabled) {
 		printk("FPU Disabled\n");
 		current_cpu_data.flags &= ~CPU_HAS_FPU;
-		disable_fpu();
 	}
 
 	/* FPU initialization */
+	disable_fpu();
 	if ((current_cpu_data.flags & CPU_HAS_FPU)) {
-		clear_thread_flag(TIF_USEDFPU);
+		current_thread_info()->status &= ~TS_USEDFPU;
 		clear_used_math();
 	}
 
@@ -338,17 +333,6 @@
 	}
 #endif
 
-	/*
-	 * Some brain-damaged loaders decided it would be a good idea to put
-	 * the UBC to sleep. This causes some issues when it comes to things
-	 * like PTRACE_SINGLESTEP or doing hardware watchpoints in GDB.  So ..
-	 * we wake it up and hope that all is well.
-	 */
-#ifdef CONFIG_SUPERH32
-	if (raw_smp_processor_id() == 0)
-		ubc_wakeup();
-#endif
-
 	speculative_execution_init();
 	expmask_init();
 }
diff --git a/arch/sh/kernel/cpu/sh2a/fpu.c b/arch/sh/kernel/cpu/sh2a/fpu.c
index 6df2fb9..d395ce5 100644
--- a/arch/sh/kernel/cpu/sh2a/fpu.c
+++ b/arch/sh/kernel/cpu/sh2a/fpu.c
@@ -25,14 +25,12 @@
 
 /*
  * Save FPU registers onto task structure.
- * Assume called with FPU enabled (SR.FD=0).
  */
 void
-save_fpu(struct task_struct *tsk, struct pt_regs *regs)
+save_fpu(struct task_struct *tsk)
 {
 	unsigned long dummy;
 
-	clear_tsk_thread_flag(tsk, TIF_USEDFPU);
 	enable_fpu();
 	asm volatile("sts.l	fpul, @-%0\n\t"
 		     "sts.l	fpscr, @-%0\n\t"
@@ -60,7 +58,6 @@
 		     : "memory");
 
 	disable_fpu();
-	release_fpu(regs);
 }
 
 static void
@@ -598,31 +595,31 @@
 	struct task_struct *tsk = current;
 	TRAP_HANDLER_DECL;
 
-	save_fpu(tsk, regs);
+	__unlazy_fpu(tsk, regs);
 	if (ieee_fpe_handler(regs)) {
 		tsk->thread.fpu.hard.fpscr &=
 			~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK);
 		grab_fpu(regs);
 		restore_fpu(tsk);
-		set_tsk_thread_flag(tsk, TIF_USEDFPU);
+		task_thread_info(tsk)->status |= TS_USEDFPU;
 		return;
 	}
 
 	force_sig(SIGFPE, tsk);
 }
 
-BUILD_TRAP_HANDLER(fpu_state_restore)
+void fpu_state_restore(struct pt_regs *regs)
 {
 	struct task_struct *tsk = current;
-	TRAP_HANDLER_DECL;
 
 	grab_fpu(regs);
-	if (!user_mode(regs)) {
+	if (unlikely(!user_mode(regs))) {
 		printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
+		BUG();
 		return;
 	}
 
-	if (used_math()) {
+	if (likely(used_math())) {
 		/* Using the FPU again.  */
 		restore_fpu(tsk);
 	} else	{
@@ -630,5 +627,13 @@
 		fpu_init();
 		set_used_math();
 	}
-	set_tsk_thread_flag(tsk, TIF_USEDFPU);
+	task_thread_info(tsk)->status |= TS_USEDFPU;
+	tsk->fpu_counter++;
+}
+
+BUILD_TRAP_HANDLER(fpu_state_restore)
+{
+	TRAP_HANDLER_DECL;
+
+	fpu_state_restore(regs);
 }
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S
index bb407ef..3f7e2a2 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -297,41 +297,8 @@
 !
 	.balign 	256,0,256
 general_exception:
-#ifndef CONFIG_CPU_SUBTYPE_SHX3
 	bra	handle_exception
 	 sts	pr, k3		! save original pr value in k3
-#else
-	mov.l	1f, k4
-	mov.l	@k4, k4
-
-	! Is EXPEVT larger than 0x800?
-	mov	#0x8, k0
-	shll8	k0
-	cmp/hs	k0, k4
-	bf	0f
-
-	! then add 0x580 (k2 is 0xd80 or 0xda0)
-	mov	#0x58, k0
-	shll2	k0
-	shll2	k0
-	add	k0, k4
-0:
-	! Setup stack and save DSP context (k0 contains original r15 on return)
-	bsr	prepare_stack
-	 nop
-
-	! Save registers / Switch to bank 0
-	mov		k4, k2		! keep vector in k2
-	mov.l	1f, k4		! SR bits to clear in k4
-	bsr	save_regs	! needs original pr value in k3
-	 nop
-
-	bra	handle_exception_special
-	 nop
-
-	.align	2
-1:	.long	EXPEVT
-#endif
 
 ! prepare_stack()
 ! - roll back gRB
diff --git a/arch/sh/kernel/cpu/sh4/Makefile b/arch/sh/kernel/cpu/sh4/Makefile
index 203b183..3a1dbc7 100644
--- a/arch/sh/kernel/cpu/sh4/Makefile
+++ b/arch/sh/kernel/cpu/sh4/Makefile
@@ -9,6 +9,11 @@
 obj-$(CONFIG_SH_FPU)			+= fpu.o softfloat.o
 obj-$(CONFIG_SH_STORE_QUEUES)		+= sq.o
 
+# Perf events
+perf-$(CONFIG_CPU_SUBTYPE_SH7750)	:= perf_event.o
+perf-$(CONFIG_CPU_SUBTYPE_SH7750S)	:= perf_event.o
+perf-$(CONFIG_CPU_SUBTYPE_SH7091)	:= perf_event.o
+
 # CPU subtype setup
 obj-$(CONFIG_CPU_SUBTYPE_SH7750)	+= setup-sh7750.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7750R)	+= setup-sh7750.o
@@ -27,4 +32,5 @@
 # Additional clocks by subtype
 clock-$(CONFIG_CPU_SUBTYPE_SH4_202)	+= clock-sh4-202.o
 
-obj-y	+= $(clock-y)
+obj-y					+= $(clock-y)
+obj-$(CONFIG_PERF_EVENTS)		+= $(perf-y)
diff --git a/arch/sh/kernel/cpu/sh4/fpu.c b/arch/sh/kernel/cpu/sh4/fpu.c
index e3ea541..e97857a 100644
--- a/arch/sh/kernel/cpu/sh4/fpu.c
+++ b/arch/sh/kernel/cpu/sh4/fpu.c
@@ -41,13 +41,11 @@
 
 /*
  * Save FPU registers onto task structure.
- * Assume called with FPU enabled (SR.FD=0).
  */
-void save_fpu(struct task_struct *tsk, struct pt_regs *regs)
+void save_fpu(struct task_struct *tsk)
 {
 	unsigned long dummy;
 
-	clear_tsk_thread_flag(tsk, TIF_USEDFPU);
 	enable_fpu();
 	asm volatile ("sts.l	fpul, @-%0\n\t"
 		      "sts.l	fpscr, @-%0\n\t"
@@ -92,7 +90,6 @@
 		      :"memory");
 
 	disable_fpu();
-	release_fpu(regs);
 }
 
 static void restore_fpu(struct task_struct *tsk)
@@ -285,7 +282,6 @@
 		/* fcnvsd */
 		struct task_struct *tsk = current;
 
-		save_fpu(tsk, regs);
 		if ((tsk->thread.fpu.hard.fpscr & FPSCR_CAUSE_ERROR))
 			/* FPU error */
 			denormal_to_double(&tsk->thread.fpu.hard,
@@ -462,7 +458,7 @@
 	struct task_struct *tsk = current;
 	TRAP_HANDLER_DECL;
 
-	save_fpu(tsk, regs);
+	__unlazy_fpu(tsk, regs);
 	fpu_exception_flags = 0;
 	if (ieee_fpe_handler(regs)) {
 		tsk->thread.fpu.hard.fpscr &=
@@ -473,7 +469,7 @@
 		tsk->thread.fpu.hard.fpscr |= (fpu_exception_flags >> 10);
 		grab_fpu(regs);
 		restore_fpu(tsk);
-		set_tsk_thread_flag(tsk, TIF_USEDFPU);
+		task_thread_info(tsk)->status |= TS_USEDFPU;
 		if ((((tsk->thread.fpu.hard.fpscr & FPSCR_ENABLE_MASK) >> 7) &
 		     (fpu_exception_flags >> 2)) == 0) {
 			return;
@@ -483,18 +479,18 @@
 	force_sig(SIGFPE, tsk);
 }
 
-BUILD_TRAP_HANDLER(fpu_state_restore)
+void fpu_state_restore(struct pt_regs *regs)
 {
 	struct task_struct *tsk = current;
-	TRAP_HANDLER_DECL;
 
 	grab_fpu(regs);
-	if (!user_mode(regs)) {
+	if (unlikely(!user_mode(regs))) {
 		printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
+		BUG();
 		return;
 	}
 
-	if (used_math()) {
+	if (likely(used_math())) {
 		/* Using the FPU again.  */
 		restore_fpu(tsk);
 	} else {
@@ -502,5 +498,13 @@
 		fpu_init();
 		set_used_math();
 	}
-	set_tsk_thread_flag(tsk, TIF_USEDFPU);
+	task_thread_info(tsk)->status |= TS_USEDFPU;
+	tsk->fpu_counter++;
+}
+
+BUILD_TRAP_HANDLER(fpu_state_restore)
+{
+	TRAP_HANDLER_DECL;
+
+	fpu_state_restore(regs);
 }
diff --git a/arch/sh/kernel/cpu/sh4/perf_event.c b/arch/sh/kernel/cpu/sh4/perf_event.c
new file mode 100644
index 0000000..7f9ecc9
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4/perf_event.c
@@ -0,0 +1,253 @@
+/*
+ * Performance events support for SH7750-style performance counters
+ *
+ *  Copyright (C) 2009  Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/perf_event.h>
+#include <asm/processor.h>
+
+#define PM_CR_BASE	0xff000084	/* 16-bit */
+#define PM_CTR_BASE	0xff100004	/* 32-bit */
+
+#define PMCR(n)		(PM_CR_BASE + ((n) * 0x04))
+#define PMCTRH(n)	(PM_CTR_BASE + 0x00 + ((n) * 0x08))
+#define PMCTRL(n)	(PM_CTR_BASE + 0x04 + ((n) * 0x08))
+
+#define PMCR_PMM_MASK	0x0000003f
+
+#define PMCR_CLKF	0x00000100
+#define PMCR_PMCLR	0x00002000
+#define PMCR_PMST	0x00004000
+#define PMCR_PMEN	0x00008000
+
+static struct sh_pmu sh7750_pmu;
+
+/*
+ * There are a number of events supported by each counter (33 in total).
+ * Since we have 2 counters, each counter will take the event code as it
+ * corresponds to the PMCR PMM setting. Each counter can be configured
+ * independently.
+ *
+ *	Event Code	Description
+ *	----------	-----------
+ *
+ *	0x01		Operand read access
+ *	0x02		Operand write access
+ *	0x03		UTLB miss
+ *	0x04		Operand cache read miss
+ *	0x05		Operand cache write miss
+ *	0x06		Instruction fetch (w/ cache)
+ *	0x07		Instruction TLB miss
+ *	0x08		Instruction cache miss
+ *	0x09		All operand accesses
+ *	0x0a		All instruction accesses
+ *	0x0b		OC RAM operand access
+ *	0x0d		On-chip I/O space access
+ *	0x0e		Operand access (r/w)
+ *	0x0f		Operand cache miss (r/w)
+ *	0x10		Branch instruction
+ *	0x11		Branch taken
+ *	0x12		BSR/BSRF/JSR
+ *	0x13		Instruction execution
+ *	0x14		Instruction execution in parallel
+ *	0x15		FPU Instruction execution
+ *	0x16		Interrupt
+ *	0x17		NMI
+ *	0x18		trapa instruction execution
+ *	0x19		UBCA match
+ *	0x1a		UBCB match
+ *	0x21		Instruction cache fill
+ *	0x22		Operand cache fill
+ *	0x23		Elapsed time
+ *	0x24		Pipeline freeze by I-cache miss
+ *	0x25		Pipeline freeze by D-cache miss
+ *	0x27		Pipeline freeze by branch instruction
+ *	0x28		Pipeline freeze by CPU register
+ *	0x29		Pipeline freeze by FPU
+ */
+
+static const int sh7750_general_events[] = {
+	[PERF_COUNT_HW_CPU_CYCLES]		= 0x0023,
+	[PERF_COUNT_HW_INSTRUCTIONS]		= 0x000a,
+	[PERF_COUNT_HW_CACHE_REFERENCES]	= 0x0006,	/* I-cache */
+	[PERF_COUNT_HW_CACHE_MISSES]		= 0x0008,	/* I-cache */
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x0010,
+	[PERF_COUNT_HW_BRANCH_MISSES]		= -1,
+	[PERF_COUNT_HW_BUS_CYCLES]		= -1,
+};
+
+#define C(x)	PERF_COUNT_HW_CACHE_##x
+
+static const int sh7750_cache_events
+			[PERF_COUNT_HW_CACHE_MAX]
+			[PERF_COUNT_HW_CACHE_OP_MAX]
+			[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+	[ C(L1D) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = 0x0001,
+			[ C(RESULT_MISS)   ] = 0x0004,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = 0x0002,
+			[ C(RESULT_MISS)   ] = 0x0005,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+	},
+
+	[ C(L1I) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = 0x0006,
+			[ C(RESULT_MISS)   ] = 0x0008,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+	},
+
+	[ C(LL) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+	},
+
+	[ C(DTLB) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0x0003,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+	},
+
+	[ C(ITLB) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0x0007,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+	},
+
+	[ C(BPU) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+	},
+};
+
+static int sh7750_event_map(int event)
+{
+	return sh7750_general_events[event];
+}
+
+static u64 sh7750_pmu_read(int idx)
+{
+	return (u64)((u64)(__raw_readl(PMCTRH(idx)) & 0xffff) << 32) |
+			   __raw_readl(PMCTRL(idx));
+}
+
+static void sh7750_pmu_disable(struct hw_perf_event *hwc, int idx)
+{
+	unsigned int tmp;
+
+	tmp = __raw_readw(PMCR(idx));
+	tmp &= ~(PMCR_PMM_MASK | PMCR_PMEN);
+	__raw_writew(tmp, PMCR(idx));
+}
+
+static void sh7750_pmu_enable(struct hw_perf_event *hwc, int idx)
+{
+	__raw_writew(__raw_readw(PMCR(idx)) | PMCR_PMCLR, PMCR(idx));
+	__raw_writew(hwc->config | PMCR_PMEN | PMCR_PMST, PMCR(idx));
+}
+
+static void sh7750_pmu_disable_all(void)
+{
+	int i;
+
+	for (i = 0; i < sh7750_pmu.num_events; i++)
+		__raw_writew(__raw_readw(PMCR(i)) & ~PMCR_PMEN, PMCR(i));
+}
+
+static void sh7750_pmu_enable_all(void)
+{
+	int i;
+
+	for (i = 0; i < sh7750_pmu.num_events; i++)
+		__raw_writew(__raw_readw(PMCR(i)) | PMCR_PMEN, PMCR(i));
+}
+
+static struct sh_pmu sh7750_pmu = {
+	.name		= "SH7750",
+	.num_events	= 2,
+	.event_map	= sh7750_event_map,
+	.max_events	= ARRAY_SIZE(sh7750_general_events),
+	.raw_event_mask	= PMCR_PMM_MASK,
+	.cache_events	= &sh7750_cache_events,
+	.read		= sh7750_pmu_read,
+	.disable	= sh7750_pmu_disable,
+	.enable		= sh7750_pmu_enable,
+	.disable_all	= sh7750_pmu_disable_all,
+	.enable_all	= sh7750_pmu_enable_all,
+};
+
+static int __init sh7750_pmu_init(void)
+{
+	/*
+	 * Make sure this CPU actually has perf counters.
+	 */
+	if (!(boot_cpu_data.flags & CPU_HAS_PERF_COUNTER)) {
+		pr_notice("HW perf events unsupported, software events only.\n");
+		return -ENODEV;
+	}
+
+	return register_sh_pmu(&sh7750_pmu);
+}
+arch_initcall(sh7750_pmu_init);
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile
index 490d5dc..33bab47 100644
--- a/arch/sh/kernel/cpu/sh4a/Makefile
+++ b/arch/sh/kernel/cpu/sh4a/Makefile
@@ -44,3 +44,4 @@
 obj-y				+= $(clock-y)
 obj-$(CONFIG_SMP)		+= $(smp-y)
 obj-$(CONFIG_GENERIC_GPIO)	+= $(pinmux-y)
+obj-$(CONFIG_PERF_EVENTS)	+= perf_event.o
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
index dfe9192..9db7438 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
@@ -152,7 +152,7 @@
 	SH_CLK_DIV6("fsia_clk", &div3_clk, FCLKACR, 0),
 	SH_CLK_DIV6("fsib_clk", &div3_clk, FCLKBCR, 0),
 	SH_CLK_DIV6("irda_clk", &div3_clk, IRDACLKCR, 0),
-	SH_CLK_DIV6("spu_clk", &div3_clk, SPUCLKCR, 0),
+	SH_CLK_DIV6("spu_clk", &div3_clk, SPUCLKCR, CLK_ENABLE_ON_INIT),
 };
 
 #define R_CLK (&r_clk)
diff --git a/arch/sh/kernel/cpu/sh4a/perf_event.c b/arch/sh/kernel/cpu/sh4a/perf_event.c
new file mode 100644
index 0000000..eddc219
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/perf_event.c
@@ -0,0 +1,269 @@
+/*
+ * Performance events support for SH-4A performance counters
+ *
+ *  Copyright (C) 2009  Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/perf_event.h>
+#include <asm/processor.h>
+
+#define PPC_CCBR(idx)	(0xff200800 + (sizeof(u32) * idx))
+#define PPC_PMCTR(idx)	(0xfc100000 + (sizeof(u32) * idx))
+
+#define CCBR_CIT_MASK	(0x7ff << 6)
+#define CCBR_DUC	(1 << 3)
+#define CCBR_CMDS	(1 << 1)
+#define CCBR_PPCE	(1 << 0)
+
+#define PPC_PMCAT	0xfc100080
+
+#define PMCAT_OVF3	(1 << 27)
+#define PMCAT_CNN3	(1 << 26)
+#define PMCAT_CLR3	(1 << 25)
+#define PMCAT_OVF2	(1 << 19)
+#define PMCAT_CLR2	(1 << 17)
+#define PMCAT_OVF1	(1 << 11)
+#define PMCAT_CNN1	(1 << 10)
+#define PMCAT_CLR1	(1 << 9)
+#define PMCAT_OVF0	(1 << 3)
+#define PMCAT_CLR0	(1 << 1)
+
+static struct sh_pmu sh4a_pmu;
+
+/*
+ * Supported raw event codes:
+ *
+ *	Event Code	Description
+ *	----------	-----------
+ *
+ *	0x0000		number of elapsed cycles
+ *	0x0200		number of elapsed cycles in privileged mode
+ *	0x0280		number of elapsed cycles while SR.BL is asserted
+ *	0x0202		instruction execution
+ *	0x0203		instruction execution in parallel
+ *	0x0204		number of unconditional branches
+ *	0x0208		number of exceptions
+ *	0x0209		number of interrupts
+ *	0x0220		UTLB miss caused by instruction fetch
+ *	0x0222		UTLB miss caused by operand access
+ *	0x02a0		number of ITLB misses
+ *	0x0028		number of accesses to instruction memories
+ *	0x0029		number of accesses to instruction cache
+ *	0x002a		instruction cache miss
+ *	0x022e		number of access to instruction X/Y memory
+ *	0x0030		number of reads to operand memories
+ *	0x0038		number of writes to operand memories
+ *	0x0031		number of operand cache read accesses
+ *	0x0039		number of operand cache write accesses
+ *	0x0032		operand cache read miss
+ *	0x003a		operand cache write miss
+ *	0x0236		number of reads to operand X/Y memory
+ *	0x023e		number of writes to operand X/Y memory
+ *	0x0237		number of reads to operand U memory
+ *	0x023f		number of writes to operand U memory
+ *	0x0337		number of U memory read buffer misses
+ *	0x02b4		number of wait cycles due to operand read access
+ *	0x02bc		number of wait cycles due to operand write access
+ *	0x0033		number of wait cycles due to operand cache read miss
+ *	0x003b		number of wait cycles due to operand cache write miss
+ */
+
+/*
+ * Special reserved bits used by hardware emulators, read values will
+ * vary, but writes must always be 0.
+ */
+#define PMCAT_EMU_CLR_MASK	((1 << 24) | (1 << 16) | (1 << 8) | (1 << 0))
+
+static const int sh4a_general_events[] = {
+	[PERF_COUNT_HW_CPU_CYCLES]		= 0x0000,
+	[PERF_COUNT_HW_INSTRUCTIONS]		= 0x0202,
+	[PERF_COUNT_HW_CACHE_REFERENCES]	= 0x0029,	/* I-cache */
+	[PERF_COUNT_HW_CACHE_MISSES]		= 0x002a,	/* I-cache */
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x0204,
+	[PERF_COUNT_HW_BRANCH_MISSES]		= -1,
+	[PERF_COUNT_HW_BUS_CYCLES]		= -1,
+};
+
+#define C(x)	PERF_COUNT_HW_CACHE_##x
+
+static const int sh4a_cache_events
+			[PERF_COUNT_HW_CACHE_MAX]
+			[PERF_COUNT_HW_CACHE_OP_MAX]
+			[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+	[ C(L1D) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = 0x0031,
+			[ C(RESULT_MISS)   ] = 0x0032,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = 0x0039,
+			[ C(RESULT_MISS)   ] = 0x003a,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+	},
+
+	[ C(L1I) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = 0x0029,
+			[ C(RESULT_MISS)   ] = 0x002a,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+	},
+
+	[ C(LL) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = 0x0030,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = 0x0038,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+	},
+
+	[ C(DTLB) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = 0x0222,
+			[ C(RESULT_MISS)   ] = 0x0220,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+	},
+
+	[ C(ITLB) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0x02a0,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+	},
+
+	[ C(BPU) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+	},
+};
+
+static int sh4a_event_map(int event)
+{
+	return sh4a_general_events[event];
+}
+
+static u64 sh4a_pmu_read(int idx)
+{
+	return __raw_readl(PPC_PMCTR(idx));
+}
+
+static void sh4a_pmu_disable(struct hw_perf_event *hwc, int idx)
+{
+	unsigned int tmp;
+
+	tmp = __raw_readl(PPC_CCBR(idx));
+	tmp &= ~(CCBR_CIT_MASK | CCBR_DUC);
+	__raw_writel(tmp, PPC_CCBR(idx));
+}
+
+static void sh4a_pmu_enable(struct hw_perf_event *hwc, int idx)
+{
+	unsigned int tmp;
+
+	tmp = __raw_readl(PPC_PMCAT);
+	tmp &= ~PMCAT_EMU_CLR_MASK;
+	tmp |= idx ? PMCAT_CLR1 : PMCAT_CLR0;
+	__raw_writel(tmp, PPC_PMCAT);
+
+	tmp = __raw_readl(PPC_CCBR(idx));
+	tmp |= (hwc->config << 6) | CCBR_CMDS | CCBR_PPCE;
+	__raw_writel(tmp, PPC_CCBR(idx));
+
+	__raw_writel(__raw_readl(PPC_CCBR(idx)) | CCBR_DUC, PPC_CCBR(idx));
+}
+
+static void sh4a_pmu_disable_all(void)
+{
+	int i;
+
+	for (i = 0; i < sh4a_pmu.num_events; i++)
+		__raw_writel(__raw_readl(PPC_CCBR(i)) & ~CCBR_DUC, PPC_CCBR(i));
+}
+
+static void sh4a_pmu_enable_all(void)
+{
+	int i;
+
+	for (i = 0; i < sh4a_pmu.num_events; i++)
+		__raw_writel(__raw_readl(PPC_CCBR(i)) | CCBR_DUC, PPC_CCBR(i));
+}
+
+static struct sh_pmu sh4a_pmu = {
+	.name		= "SH-4A",
+	.num_events	= 2,
+	.event_map	= sh4a_event_map,
+	.max_events	= ARRAY_SIZE(sh4a_general_events),
+	.raw_event_mask	= 0x3ff,
+	.cache_events	= &sh4a_cache_events,
+	.read		= sh4a_pmu_read,
+	.disable	= sh4a_pmu_disable,
+	.enable		= sh4a_pmu_enable,
+	.disable_all	= sh4a_pmu_disable_all,
+	.enable_all	= sh4a_pmu_enable_all,
+};
+
+static int __init sh4a_pmu_init(void)
+{
+	/*
+	 * Make sure this CPU actually has perf counters.
+	 */
+	if (!(boot_cpu_data.flags & CPU_HAS_PERF_COUNTER)) {
+		pr_notice("HW perf events unsupported, software events only.\n");
+		return -ENODEV;
+	}
+
+	return register_sh_pmu(&sh4a_pmu);
+}
+arch_initcall(sh4a_pmu_init);
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
index f3851fd..845e89c 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
@@ -20,6 +20,8 @@
 #include <linux/uio_driver.h>
 #include <linux/sh_timer.h>
 #include <linux/io.h>
+#include <linux/notifier.h>
+#include <asm/suspend.h>
 #include <asm/clock.h>
 #include <asm/mmzone.h>
 #include <cpu/sh7724.h>
@@ -202,7 +204,7 @@
 	[0] = {
 		.name	= "VEU3F0",
 		.start	= 0xfe920000,
-		.end	= 0xfe9200cb - 1,
+		.end	= 0xfe9200cb,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
@@ -234,7 +236,7 @@
 	[0] = {
 		.name	= "VEU3F1",
 		.start	= 0xfe924000,
-		.end	= 0xfe9240cb - 1,
+		.end	= 0xfe9240cb,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
@@ -523,6 +525,70 @@
 	},
 };
 
+/* SPU2DSP0 */
+static struct uio_info spu0_platform_data = {
+	.name = "SPU2DSP0",
+	.version = "0",
+	.irq = 86,
+};
+
+static struct resource spu0_resources[] = {
+	[0] = {
+		.name	= "SPU2DSP0",
+		.start	= 0xFE200000,
+		.end	= 0xFE2FFFFF,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		/* place holder for contiguous memory */
+	},
+};
+
+static struct platform_device spu0_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 4,
+	.dev = {
+		.platform_data	= &spu0_platform_data,
+	},
+	.resource	= spu0_resources,
+	.num_resources	= ARRAY_SIZE(spu0_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_SPU,
+	},
+};
+
+/* SPU2DSP1 */
+static struct uio_info spu1_platform_data = {
+	.name = "SPU2DSP1",
+	.version = "0",
+	.irq = 87,
+};
+
+static struct resource spu1_resources[] = {
+	[0] = {
+		.name	= "SPU2DSP1",
+		.start	= 0xFE300000,
+		.end	= 0xFE3FFFFF,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		/* place holder for contiguous memory */
+	},
+};
+
+static struct platform_device spu1_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 5,
+	.dev = {
+		.platform_data	= &spu1_platform_data,
+	},
+	.resource	= spu1_resources,
+	.num_resources	= ARRAY_SIZE(spu1_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_SPU,
+	},
+};
+
 static struct platform_device *sh7724_devices[] __initdata = {
 	&cmt_device,
 	&tmu0_device,
@@ -539,6 +605,8 @@
 	&veu0_device,
 	&veu1_device,
 	&jpu_device,
+	&spu0_device,
+	&spu1_device,
 };
 
 static int __init sh7724_devices_setup(void)
@@ -547,6 +615,8 @@
 	platform_resource_setup_memory(&veu0_device, "veu0", 2 << 20);
 	platform_resource_setup_memory(&veu1_device, "veu1", 2 << 20);
 	platform_resource_setup_memory(&jpu_device,  "jpu",  2 << 20);
+	platform_resource_setup_memory(&spu0_device, "spu0", 2 << 20);
+	platform_resource_setup_memory(&spu1_device, "spu1", 2 << 20);
 
 	return platform_add_devices(sh7724_devices,
 				    ARRAY_SIZE(sh7724_devices));
@@ -827,3 +897,193 @@
 {
 	register_intc_controller(&intc_desc);
 }
+
+static struct {
+	/* BSC */
+	unsigned long mmselr;
+	unsigned long cs0bcr;
+	unsigned long cs4bcr;
+	unsigned long cs5abcr;
+	unsigned long cs5bbcr;
+	unsigned long cs6abcr;
+	unsigned long cs6bbcr;
+	unsigned long cs4wcr;
+	unsigned long cs5awcr;
+	unsigned long cs5bwcr;
+	unsigned long cs6awcr;
+	unsigned long cs6bwcr;
+	/* INTC */
+	unsigned short ipra;
+	unsigned short iprb;
+	unsigned short iprc;
+	unsigned short iprd;
+	unsigned short ipre;
+	unsigned short iprf;
+	unsigned short iprg;
+	unsigned short iprh;
+	unsigned short ipri;
+	unsigned short iprj;
+	unsigned short iprk;
+	unsigned short iprl;
+	unsigned char imr0;
+	unsigned char imr1;
+	unsigned char imr2;
+	unsigned char imr3;
+	unsigned char imr4;
+	unsigned char imr5;
+	unsigned char imr6;
+	unsigned char imr7;
+	unsigned char imr8;
+	unsigned char imr9;
+	unsigned char imr10;
+	unsigned char imr11;
+	unsigned char imr12;
+	/* RWDT */
+	unsigned short rwtcnt;
+	unsigned short rwtcsr;
+	/* CPG */
+	unsigned long irdaclk;
+	unsigned long spuclk;
+} sh7724_rstandby_state;
+
+static int sh7724_pre_sleep_notifier_call(struct notifier_block *nb,
+					  unsigned long flags, void *unused)
+{
+	if (!(flags & SUSP_SH_RSTANDBY))
+		return NOTIFY_DONE;
+
+	/* BCR */
+	sh7724_rstandby_state.mmselr = __raw_readl(0xff800020); /* MMSELR */
+	sh7724_rstandby_state.mmselr |= 0xa5a50000;
+	sh7724_rstandby_state.cs0bcr = __raw_readl(0xfec10004); /* CS0BCR */
+	sh7724_rstandby_state.cs4bcr = __raw_readl(0xfec10010); /* CS4BCR */
+	sh7724_rstandby_state.cs5abcr = __raw_readl(0xfec10014); /* CS5ABCR */
+	sh7724_rstandby_state.cs5bbcr = __raw_readl(0xfec10018); /* CS5BBCR */
+	sh7724_rstandby_state.cs6abcr = __raw_readl(0xfec1001c); /* CS6ABCR */
+	sh7724_rstandby_state.cs6bbcr = __raw_readl(0xfec10020); /* CS6BBCR */
+	sh7724_rstandby_state.cs4wcr = __raw_readl(0xfec10030); /* CS4WCR */
+	sh7724_rstandby_state.cs5awcr = __raw_readl(0xfec10034); /* CS5AWCR */
+	sh7724_rstandby_state.cs5bwcr = __raw_readl(0xfec10038); /* CS5BWCR */
+	sh7724_rstandby_state.cs6awcr = __raw_readl(0xfec1003c); /* CS6AWCR */
+	sh7724_rstandby_state.cs6bwcr = __raw_readl(0xfec10040); /* CS6BWCR */
+
+	/* INTC */
+	sh7724_rstandby_state.ipra = __raw_readw(0xa4080000); /* IPRA */
+	sh7724_rstandby_state.iprb = __raw_readw(0xa4080004); /* IPRB */
+	sh7724_rstandby_state.iprc = __raw_readw(0xa4080008); /* IPRC */
+	sh7724_rstandby_state.iprd = __raw_readw(0xa408000c); /* IPRD */
+	sh7724_rstandby_state.ipre = __raw_readw(0xa4080010); /* IPRE */
+	sh7724_rstandby_state.iprf = __raw_readw(0xa4080014); /* IPRF */
+	sh7724_rstandby_state.iprg = __raw_readw(0xa4080018); /* IPRG */
+	sh7724_rstandby_state.iprh = __raw_readw(0xa408001c); /* IPRH */
+	sh7724_rstandby_state.ipri = __raw_readw(0xa4080020); /* IPRI */
+	sh7724_rstandby_state.iprj = __raw_readw(0xa4080024); /* IPRJ */
+	sh7724_rstandby_state.iprk = __raw_readw(0xa4080028); /* IPRK */
+	sh7724_rstandby_state.iprl = __raw_readw(0xa408002c); /* IPRL */
+	sh7724_rstandby_state.imr0 = __raw_readb(0xa4080080); /* IMR0 */
+	sh7724_rstandby_state.imr1 = __raw_readb(0xa4080084); /* IMR1 */
+	sh7724_rstandby_state.imr2 = __raw_readb(0xa4080088); /* IMR2 */
+	sh7724_rstandby_state.imr3 = __raw_readb(0xa408008c); /* IMR3 */
+	sh7724_rstandby_state.imr4 = __raw_readb(0xa4080090); /* IMR4 */
+	sh7724_rstandby_state.imr5 = __raw_readb(0xa4080094); /* IMR5 */
+	sh7724_rstandby_state.imr6 = __raw_readb(0xa4080098); /* IMR6 */
+	sh7724_rstandby_state.imr7 = __raw_readb(0xa408009c); /* IMR7 */
+	sh7724_rstandby_state.imr8 = __raw_readb(0xa40800a0); /* IMR8 */
+	sh7724_rstandby_state.imr9 = __raw_readb(0xa40800a4); /* IMR9 */
+	sh7724_rstandby_state.imr10 = __raw_readb(0xa40800a8); /* IMR10 */
+	sh7724_rstandby_state.imr11 = __raw_readb(0xa40800ac); /* IMR11 */
+	sh7724_rstandby_state.imr12 = __raw_readb(0xa40800b0); /* IMR12 */
+
+	/* RWDT */
+	sh7724_rstandby_state.rwtcnt = __raw_readb(0xa4520000); /* RWTCNT */
+	sh7724_rstandby_state.rwtcnt |= 0x5a00;
+	sh7724_rstandby_state.rwtcsr = __raw_readb(0xa4520004); /* RWTCSR */
+	sh7724_rstandby_state.rwtcsr |= 0xa500;
+	__raw_writew(sh7724_rstandby_state.rwtcsr & 0x07, 0xa4520004);
+
+	/* CPG */
+	sh7724_rstandby_state.irdaclk = __raw_readl(0xa4150018); /* IRDACLKCR */
+	sh7724_rstandby_state.spuclk = __raw_readl(0xa415003c); /* SPUCLKCR */
+
+	return NOTIFY_DONE;
+}
+
+static int sh7724_post_sleep_notifier_call(struct notifier_block *nb,
+					   unsigned long flags, void *unused)
+{
+	if (!(flags & SUSP_SH_RSTANDBY))
+		return NOTIFY_DONE;
+
+	/* BCR */
+	__raw_writel(sh7724_rstandby_state.mmselr, 0xff800020); /* MMSELR */
+	__raw_writel(sh7724_rstandby_state.cs0bcr, 0xfec10004); /* CS0BCR */
+	__raw_writel(sh7724_rstandby_state.cs4bcr, 0xfec10010); /* CS4BCR */
+	__raw_writel(sh7724_rstandby_state.cs5abcr, 0xfec10014); /* CS5ABCR */
+	__raw_writel(sh7724_rstandby_state.cs5bbcr, 0xfec10018); /* CS5BBCR */
+	__raw_writel(sh7724_rstandby_state.cs6abcr, 0xfec1001c); /* CS6ABCR */
+	__raw_writel(sh7724_rstandby_state.cs6bbcr, 0xfec10020); /* CS6BBCR */
+	__raw_writel(sh7724_rstandby_state.cs4wcr, 0xfec10030); /* CS4WCR */
+	__raw_writel(sh7724_rstandby_state.cs5awcr, 0xfec10034); /* CS5AWCR */
+	__raw_writel(sh7724_rstandby_state.cs5bwcr, 0xfec10038); /* CS5BWCR */
+	__raw_writel(sh7724_rstandby_state.cs6awcr, 0xfec1003c); /* CS6AWCR */
+	__raw_writel(sh7724_rstandby_state.cs6bwcr, 0xfec10040); /* CS6BWCR */
+
+	/* INTC */
+	__raw_writew(sh7724_rstandby_state.ipra, 0xa4080000); /* IPRA */
+	__raw_writew(sh7724_rstandby_state.iprb, 0xa4080004); /* IPRB */
+	__raw_writew(sh7724_rstandby_state.iprc, 0xa4080008); /* IPRC */
+	__raw_writew(sh7724_rstandby_state.iprd, 0xa408000c); /* IPRD */
+	__raw_writew(sh7724_rstandby_state.ipre, 0xa4080010); /* IPRE */
+	__raw_writew(sh7724_rstandby_state.iprf, 0xa4080014); /* IPRF */
+	__raw_writew(sh7724_rstandby_state.iprg, 0xa4080018); /* IPRG */
+	__raw_writew(sh7724_rstandby_state.iprh, 0xa408001c); /* IPRH */
+	__raw_writew(sh7724_rstandby_state.ipri, 0xa4080020); /* IPRI */
+	__raw_writew(sh7724_rstandby_state.iprj, 0xa4080024); /* IPRJ */
+	__raw_writew(sh7724_rstandby_state.iprk, 0xa4080028); /* IPRK */
+	__raw_writew(sh7724_rstandby_state.iprl, 0xa408002c); /* IPRL */
+	__raw_writeb(sh7724_rstandby_state.imr0, 0xa4080080); /* IMR0 */
+	__raw_writeb(sh7724_rstandby_state.imr1, 0xa4080084); /* IMR1 */
+	__raw_writeb(sh7724_rstandby_state.imr2, 0xa4080088); /* IMR2 */
+	__raw_writeb(sh7724_rstandby_state.imr3, 0xa408008c); /* IMR3 */
+	__raw_writeb(sh7724_rstandby_state.imr4, 0xa4080090); /* IMR4 */
+	__raw_writeb(sh7724_rstandby_state.imr5, 0xa4080094); /* IMR5 */
+	__raw_writeb(sh7724_rstandby_state.imr6, 0xa4080098); /* IMR6 */
+	__raw_writeb(sh7724_rstandby_state.imr7, 0xa408009c); /* IMR7 */
+	__raw_writeb(sh7724_rstandby_state.imr8, 0xa40800a0); /* IMR8 */
+	__raw_writeb(sh7724_rstandby_state.imr9, 0xa40800a4); /* IMR9 */
+	__raw_writeb(sh7724_rstandby_state.imr10, 0xa40800a8); /* IMR10 */
+	__raw_writeb(sh7724_rstandby_state.imr11, 0xa40800ac); /* IMR11 */
+	__raw_writeb(sh7724_rstandby_state.imr12, 0xa40800b0); /* IMR12 */
+
+	/* RWDT */
+	__raw_writew(sh7724_rstandby_state.rwtcnt, 0xa4520000); /* RWTCNT */
+	__raw_writew(sh7724_rstandby_state.rwtcsr, 0xa4520004); /* RWTCSR */
+
+	/* CPG */
+	__raw_writel(sh7724_rstandby_state.irdaclk, 0xa4150018); /* IRDACLKCR */
+	__raw_writel(sh7724_rstandby_state.spuclk, 0xa415003c); /* SPUCLKCR */
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block sh7724_pre_sleep_notifier = {
+	.notifier_call = sh7724_pre_sleep_notifier_call,
+	.priority = SH_MOBILE_PRE(SH_MOBILE_SLEEP_CPU),
+};
+
+static struct notifier_block sh7724_post_sleep_notifier = {
+	.notifier_call = sh7724_post_sleep_notifier_call,
+	.priority = SH_MOBILE_POST(SH_MOBILE_SLEEP_CPU),
+};
+
+static int __init sh7724_sleep_setup(void)
+{
+	atomic_notifier_chain_register(&sh_mobile_pre_sleep_notifier_list,
+				       &sh7724_pre_sleep_notifier);
+
+	atomic_notifier_chain_register(&sh_mobile_post_sleep_notifier_list,
+				       &sh7724_post_sleep_notifier);
+	return 0;
+}
+arch_initcall(sh7724_sleep_setup);
+
diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
index e848443..c7ba916 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
@@ -15,6 +15,15 @@
 #include <linux/sh_timer.h>
 #include <asm/mmzone.h>
 
+/*
+ * This intentionally only registers SCIF ports 0, 1, and 3. SCIF 2
+ * INTEVT values overlap with the FPU EXPEVT ones, requiring special
+ * demuxing in the exception dispatch path.
+ *
+ * As this overlap is something that never should have made it in to
+ * silicon in the first place, we just refuse to deal with the port at
+ * all rather than adding infrastructure to hack around it.
+ */
 static struct plat_sci_port sci_platform_data[] = {
 	{
 		.mapbase	= 0xffc30000,
@@ -27,11 +36,6 @@
 		.type		= PORT_SCIF,
 		.irqs		= { 44, 45, 47, 46 },
 	}, {
-		.mapbase	= 0xffc50000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 48, 49, 51, 50 },
-	}, {
 		.mapbase	= 0xffc60000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
@@ -268,7 +272,11 @@
 	UNUSED = 0,
 
 	/* interrupt sources */
-	IRL, IRQ0, IRQ1, IRQ2, IRQ3,
+	IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
+	IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
+	IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
+	IRL_HHLL, IRL_HHLH, IRL_HHHL,
+	IRQ0, IRQ1, IRQ2, IRQ3,
 	HUDII,
 	TMU0, TMU1, TMU2, TMU3, TMU4, TMU5,
 	PCII0, PCII1, PCII2, PCII3, PCII4,
@@ -291,7 +299,7 @@
 	INTICI4, INTICI5, INTICI6, INTICI7,
 
 	/* interrupt groups */
-	PCII56789, SCIF0, SCIF1, SCIF2, SCIF3,
+	IRL, PCII56789, SCIF0, SCIF1, SCIF2, SCIF3,
 	DMAC0, DMAC1,
 };
 
@@ -309,8 +317,6 @@
 	INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760),
 	INTC_VECT(SCIF1_ERI, 0x780), INTC_VECT(SCIF1_RXI, 0x7a0),
 	INTC_VECT(SCIF1_BRI, 0x7c0), INTC_VECT(SCIF1_TXI, 0x7e0),
-	INTC_VECT(SCIF2_ERI, 0x800), INTC_VECT(SCIF2_RXI, 0x820),
-	INTC_VECT(SCIF2_BRI, 0x840), INTC_VECT(SCIF2_TXI, 0x860),
 	INTC_VECT(SCIF3_ERI, 0x880), INTC_VECT(SCIF3_RXI, 0x8a0),
 	INTC_VECT(SCIF3_BRI, 0x8c0), INTC_VECT(SCIF3_TXI, 0x8e0),
 	INTC_VECT(DMAC0_DMINT0, 0x900), INTC_VECT(DMAC0_DMINT1, 0x920),
@@ -344,10 +350,13 @@
 };
 
 static struct intc_group groups[] __initdata = {
+	INTC_GROUP(IRL, IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
+		   IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
+		   IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
+		   IRL_HHLL, IRL_HHLH, IRL_HHHL),
 	INTC_GROUP(PCII56789, PCII5, PCII6, PCII7, PCII8, PCII9),
 	INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
 	INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
-	INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI),
 	INTC_GROUP(SCIF3, SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI),
 	INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
 		   DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
@@ -419,14 +428,14 @@
 
 /* External interrupt pins in IRL mode */
 static struct intc_vect vectors_irl[] __initdata = {
-	INTC_VECT(IRL, 0x200), INTC_VECT(IRL, 0x220),
-	INTC_VECT(IRL, 0x240), INTC_VECT(IRL, 0x260),
-	INTC_VECT(IRL, 0x280), INTC_VECT(IRL, 0x2a0),
-	INTC_VECT(IRL, 0x2c0), INTC_VECT(IRL, 0x2e0),
-	INTC_VECT(IRL, 0x300), INTC_VECT(IRL, 0x320),
-	INTC_VECT(IRL, 0x340), INTC_VECT(IRL, 0x360),
-	INTC_VECT(IRL, 0x380), INTC_VECT(IRL, 0x3a0),
-	INTC_VECT(IRL, 0x3c0),
+	INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
+	INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
+	INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
+	INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0),
+	INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320),
+	INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360),
+	INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0),
+	INTC_VECT(IRL_HHHL, 0x3c0),
 };
 
 static DECLARE_INTC_DESC(intc_desc_irl, "shx3-irl", vectors_irl, groups,
diff --git a/arch/sh/kernel/cpu/sh4a/smp-shx3.c b/arch/sh/kernel/cpu/sh4a/smp-shx3.c
index 185ec39..5863e0c 100644
--- a/arch/sh/kernel/cpu/sh4a/smp-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/smp-shx3.c
@@ -14,6 +14,13 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 
+#define STBCR_REG(phys_id) (0xfe400004 | (phys_id << 12))
+#define RESET_REG(phys_id) (0xfe400008 | (phys_id << 12))
+
+#define STBCR_MSTP	0x00000001
+#define STBCR_RESET	0x00000002
+#define STBCR_LTSLP	0x80000000
+
 static irqreturn_t ipi_interrupt_handler(int irq, void *arg)
 {
 	unsigned int message = (unsigned int)(long)arg;
@@ -21,9 +28,9 @@
 	unsigned int offs = 4 * cpu;
 	unsigned int x;
 
-	x = ctrl_inl(0xfe410070 + offs); /* C0INITICI..CnINTICI */
+	x = __raw_readl(0xfe410070 + offs); /* C0INITICI..CnINTICI */
 	x &= (1 << (message << 2));
-	ctrl_outl(x, 0xfe410080 + offs); /* C0INTICICLR..CnINTICICLR */
+	__raw_writel(x, 0xfe410080 + offs); /* C0INTICICLR..CnINTICICLR */
 
 	smp_message_recv(message);
 
@@ -37,6 +44,9 @@
 
 	init_cpu_possible(cpumask_of(cpu));
 
+	/* Enable light sleep for the boot CPU */
+	__raw_writel(__raw_readl(STBCR_REG(cpu)) | STBCR_LTSLP, STBCR_REG(cpu));
+
 	__cpu_number_map[0] = 0;
 	__cpu_logical_map[0] = 0;
 
@@ -66,32 +76,23 @@
 			    "IPI", (void *)(long)i);
 }
 
-#define STBCR_REG(phys_id) (0xfe400004 | (phys_id << 12))
-#define RESET_REG(phys_id) (0xfe400008 | (phys_id << 12))
-
-#define STBCR_MSTP	0x00000001
-#define STBCR_RESET	0x00000002
-#define STBCR_LTSLP	0x80000000
-
-#define STBCR_AP_VAL	(STBCR_RESET | STBCR_LTSLP)
-
 void plat_start_cpu(unsigned int cpu, unsigned long entry_point)
 {
-	ctrl_outl(entry_point, RESET_REG(cpu));
+	__raw_writel(entry_point, RESET_REG(cpu));
 
-	if (!(ctrl_inl(STBCR_REG(cpu)) & STBCR_MSTP))
-		ctrl_outl(STBCR_MSTP, STBCR_REG(cpu));
+	if (!(__raw_readl(STBCR_REG(cpu)) & STBCR_MSTP))
+		__raw_writel(STBCR_MSTP, STBCR_REG(cpu));
 
-	while (!(ctrl_inl(STBCR_REG(cpu)) & STBCR_MSTP))
+	while (!(__raw_readl(STBCR_REG(cpu)) & STBCR_MSTP))
 		cpu_relax();
 
 	/* Start up secondary processor by sending a reset */
-	ctrl_outl(STBCR_AP_VAL, STBCR_REG(cpu));
+	__raw_writel(STBCR_RESET | STBCR_LTSLP, STBCR_REG(cpu));
 }
 
 int plat_smp_processor_id(void)
 {
-	return ctrl_inl(0xff000048); /* CPIDR */
+	return __raw_readl(0xff000048); /* CPIDR */
 }
 
 void plat_send_ipi(unsigned int cpu, unsigned int message)
@@ -100,5 +101,5 @@
 
 	BUG_ON(cpu >= 4);
 
-	ctrl_outl(1 << (message << 2), addr); /* C0INTICI..CnINTICI */
+	__raw_writel(1 << (message << 2), addr); /* C0INTICI..CnINTICI */
 }
diff --git a/arch/sh/kernel/cpu/sh5/entry.S b/arch/sh/kernel/cpu/sh5/entry.S
index b0aacf6..8f13f73 100644
--- a/arch/sh/kernel/cpu/sh5/entry.S
+++ b/arch/sh/kernel/cpu/sh5/entry.S
@@ -933,7 +933,7 @@
 
 	pta	restore_all, tr1
 
-	movi	(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r8
+	movi	_TIF_SIGPENDING, r8
 	and	r8, r7, r8
 	pta	work_notifysig, tr0
 	bne	r8, ZERO, tr0
diff --git a/arch/sh/kernel/cpu/shmobile/cpuidle.c b/arch/sh/kernel/cpu/shmobile/cpuidle.c
index 1c504bd..83972aa 100644
--- a/arch/sh/kernel/cpu/shmobile/cpuidle.c
+++ b/arch/sh/kernel/cpu/shmobile/cpuidle.c
@@ -87,25 +87,31 @@
 
 	dev->safe_state = state;
 
-	state = &dev->states[i++];
-	snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
-	strncpy(state->desc, "SuperH Sleep Mode [SF]", CPUIDLE_DESC_LEN);
-	state->exit_latency = 100;
-	state->target_residency = 1 * 2;
-	state->power_usage = 1;
-	state->flags = 0;
-	state->flags |= CPUIDLE_FLAG_TIME_VALID;
-	state->enter = cpuidle_sleep_enter;
+	if (sh_mobile_sleep_supported & SUSP_SH_SF) {
+		state = &dev->states[i++];
+		snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
+		strncpy(state->desc, "SuperH Sleep Mode [SF]",
+			CPUIDLE_DESC_LEN);
+		state->exit_latency = 100;
+		state->target_residency = 1 * 2;
+		state->power_usage = 1;
+		state->flags = 0;
+		state->flags |= CPUIDLE_FLAG_TIME_VALID;
+		state->enter = cpuidle_sleep_enter;
+	}
 
-	state = &dev->states[i++];
-	snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
-	strncpy(state->desc, "SuperH Mobile Standby Mode [SF]", CPUIDLE_DESC_LEN);
-	state->exit_latency = 2300;
-	state->target_residency = 1 * 2;
-	state->power_usage = 1;
-	state->flags = 0;
-	state->flags |= CPUIDLE_FLAG_TIME_VALID;
-	state->enter = cpuidle_sleep_enter;
+	if (sh_mobile_sleep_supported & SUSP_SH_STANDBY) {
+		state = &dev->states[i++];
+		snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
+		strncpy(state->desc, "SuperH Mobile Standby Mode [SF]",
+			CPUIDLE_DESC_LEN);
+		state->exit_latency = 2300;
+		state->target_residency = 1 * 2;
+		state->power_usage = 1;
+		state->flags = 0;
+		state->flags |= CPUIDLE_FLAG_TIME_VALID;
+		state->enter = cpuidle_sleep_enter;
+	}
 
 	dev->state_count = i;
 
diff --git a/arch/sh/kernel/cpu/shmobile/pm.c b/arch/sh/kernel/cpu/shmobile/pm.c
index ee3c2aa..ca029a4 100644
--- a/arch/sh/kernel/cpu/shmobile/pm.c
+++ b/arch/sh/kernel/cpu/shmobile/pm.c
@@ -15,6 +15,13 @@
 #include <linux/suspend.h>
 #include <asm/suspend.h>
 #include <asm/uaccess.h>
+#include <asm/cacheflush.h>
+
+/*
+ * Notifier lists for pre/post sleep notification
+ */
+ATOMIC_NOTIFIER_HEAD(sh_mobile_pre_sleep_notifier_list);
+ATOMIC_NOTIFIER_HEAD(sh_mobile_post_sleep_notifier_list);
 
 /*
  * Sleep modes available on SuperH Mobile:
@@ -26,30 +33,105 @@
 #define SUSP_MODE_SLEEP		(SUSP_SH_SLEEP)
 #define SUSP_MODE_SLEEP_SF	(SUSP_SH_SLEEP | SUSP_SH_SF)
 #define SUSP_MODE_STANDBY_SF	(SUSP_SH_STANDBY | SUSP_SH_SF)
+#define SUSP_MODE_RSTANDBY	(SUSP_SH_RSTANDBY | SUSP_SH_MMU | SUSP_SH_SF)
+ /*
+  * U-standby mode is unsupported since it needs bootloader hacks
+  */
 
-/*
- * The following modes are not there yet:
- *
- * R-standby mode is unsupported, but will be added in the future
- * U-standby mode is low priority since it needs bootloader hacks
- */
-
-#define ILRAM_BASE 0xe5200000
-
-extern const unsigned char sh_mobile_standby[];
-extern const unsigned int sh_mobile_standby_size;
+#ifdef CONFIG_CPU_SUBTYPE_SH7724
+#define RAM_BASE 0xfd800000 /* RSMEM */
+#else
+#define RAM_BASE 0xe5200000 /* ILRAM */
+#endif
 
 void sh_mobile_call_standby(unsigned long mode)
 {
-	void *onchip_mem = (void *)ILRAM_BASE;
-	void (*standby_onchip_mem)(unsigned long, unsigned long) = onchip_mem;
+	void *onchip_mem = (void *)RAM_BASE;
+	struct sh_sleep_data *sdp = onchip_mem;
+	void (*standby_onchip_mem)(unsigned long, unsigned long);
+
+	/* code located directly after data structure */
+	standby_onchip_mem = (void *)(sdp + 1);
+
+	atomic_notifier_call_chain(&sh_mobile_pre_sleep_notifier_list,
+				   mode, NULL);
+
+	/* flush the caches if MMU flag is set */
+	if (mode & SUSP_SH_MMU)
+		flush_cache_all();
 
 	/* Let assembly snippet in on-chip memory handle the rest */
-	standby_onchip_mem(mode, ILRAM_BASE);
+	standby_onchip_mem(mode, RAM_BASE);
+
+	atomic_notifier_call_chain(&sh_mobile_post_sleep_notifier_list,
+				   mode, NULL);
+}
+
+extern char sh_mobile_sleep_enter_start;
+extern char sh_mobile_sleep_enter_end;
+
+extern char sh_mobile_sleep_resume_start;
+extern char sh_mobile_sleep_resume_end;
+
+unsigned long sh_mobile_sleep_supported = SUSP_SH_SLEEP;
+
+void sh_mobile_register_self_refresh(unsigned long flags,
+				     void *pre_start, void *pre_end,
+				     void *post_start, void *post_end)
+{
+	void *onchip_mem = (void *)RAM_BASE;
+	void *vp;
+	struct sh_sleep_data *sdp;
+	int n;
+
+	/* part 0: data area */
+	sdp = onchip_mem;
+	sdp->addr.stbcr = 0xa4150020; /* STBCR */
+	sdp->addr.bar = 0xa4150040; /* BAR */
+	sdp->addr.pteh = 0xff000000; /* PTEH */
+	sdp->addr.ptel = 0xff000004; /* PTEL */
+	sdp->addr.ttb = 0xff000008; /* TTB */
+	sdp->addr.tea = 0xff00000c; /* TEA */
+	sdp->addr.mmucr = 0xff000010; /* MMUCR */
+	sdp->addr.ptea = 0xff000034; /* PTEA */
+	sdp->addr.pascr = 0xff000070; /* PASCR */
+	sdp->addr.irmcr = 0xff000078; /* IRMCR */
+	sdp->addr.ccr = 0xff00001c; /* CCR */
+	sdp->addr.ramcr = 0xff000074; /* RAMCR */
+	vp = sdp + 1;
+
+	/* part 1: common code to enter sleep mode */
+	n = &sh_mobile_sleep_enter_end - &sh_mobile_sleep_enter_start;
+	memcpy(vp, &sh_mobile_sleep_enter_start, n);
+	vp += roundup(n, 4);
+
+	/* part 2: board specific code to enter self-refresh mode */
+	n = pre_end - pre_start;
+	memcpy(vp, pre_start, n);
+	sdp->sf_pre = (unsigned long)vp;
+	vp += roundup(n, 4);
+
+	/* part 3: board specific code to resume from self-refresh mode */
+	n = post_end - post_start;
+	memcpy(vp, post_start, n);
+	sdp->sf_post = (unsigned long)vp;
+	vp += roundup(n, 4);
+
+	/* part 4: common code to resume from sleep mode */
+	WARN_ON(vp > (onchip_mem + 0x600));
+	vp = onchip_mem + 0x600; /* located at interrupt vector */
+	n = &sh_mobile_sleep_resume_end - &sh_mobile_sleep_resume_start;
+	memcpy(vp, &sh_mobile_sleep_resume_start, n);
+	sdp->resume = (unsigned long)vp;
+
+	sh_mobile_sleep_supported |= flags;
 }
 
 static int sh_pm_enter(suspend_state_t state)
 {
+	if (!(sh_mobile_sleep_supported & SUSP_MODE_STANDBY_SF))
+		return -ENXIO;
+
 	local_irq_disable();
 	set_bl_bit();
 	sh_mobile_call_standby(SUSP_MODE_STANDBY_SF);
@@ -65,13 +147,6 @@
 
 static int __init sh_pm_init(void)
 {
-	void *onchip_mem = (void *)ILRAM_BASE;
-
-	/* Copy the assembly snippet to the otherwise ununsed ILRAM */
-	memcpy(onchip_mem, sh_mobile_standby, sh_mobile_standby_size);
-	wmb();
-	ctrl_barrier();
-
 	suspend_set_ops(&sh_pm_ops);
 	sh_mobile_setup_cpuidle();
 	return 0;
diff --git a/arch/sh/kernel/cpu/shmobile/pm_runtime.c b/arch/sh/kernel/cpu/shmobile/pm_runtime.c
index 7c615b1..6dcb816 100644
--- a/arch/sh/kernel/cpu/shmobile/pm_runtime.c
+++ b/arch/sh/kernel/cpu/shmobile/pm_runtime.c
@@ -45,12 +45,14 @@
 
 	dev_dbg(d, "__platform_pm_runtime_resume() [%d]\n", hwblk);
 
-	if (d->driver && d->driver->pm && d->driver->pm->runtime_resume) {
+	if (d->driver) {
 		hwblk_enable(hwblk_info, hwblk);
 		ret = 0;
 
 		if (test_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags)) {
-			ret = d->driver->pm->runtime_resume(d);
+			if (d->driver->pm && d->driver->pm->runtime_resume)
+				ret = d->driver->pm->runtime_resume(d);
+
 			if (!ret)
 				clear_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags);
 			else
@@ -73,12 +75,15 @@
 
 	dev_dbg(d, "__platform_pm_runtime_suspend() [%d]\n", hwblk);
 
-	if (d->driver && d->driver->pm && d->driver->pm->runtime_suspend) {
+	if (d->driver) {
 		BUG_ON(!test_bit(PDEV_ARCHDATA_FLAG_IDLE, &ad->flags));
+		ret = 0;
 
-		hwblk_enable(hwblk_info, hwblk);
-		ret = d->driver->pm->runtime_suspend(d);
-		hwblk_disable(hwblk_info, hwblk);
+		if (d->driver->pm && d->driver->pm->runtime_suspend) {
+			hwblk_enable(hwblk_info, hwblk);
+			ret = d->driver->pm->runtime_suspend(d);
+			hwblk_disable(hwblk_info, hwblk);
+		}
 
 		if (!ret) {
 			set_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags);
diff --git a/arch/sh/kernel/cpu/shmobile/sleep.S b/arch/sh/kernel/cpu/shmobile/sleep.S
index a439e6c..e9dd7fa 100644
--- a/arch/sh/kernel/cpu/shmobile/sleep.S
+++ b/arch/sh/kernel/cpu/shmobile/sleep.S
@@ -20,79 +20,103 @@
  * Kernel mode register usage, see entry.S:
  *	k0	scratch
  *	k1	scratch
- *	k4	scratch
  */
 #define k0	r0
 #define k1	r1
-#define k4	r4
 
-/* manage self-refresh and enter standby mode.
+/* manage self-refresh and enter standby mode. must be self-contained.
  * this code will be copied to on-chip memory and executed from there.
  */
+	.balign 4
+ENTRY(sh_mobile_sleep_enter_start)
 
-	.balign 	4096,0,4096
-ENTRY(sh_mobile_standby)
+	/* save mode flags */
+	mov.l	r4, @(SH_SLEEP_MODE, r5)
 
 	/* save original vbr */
-	stc	vbr, r1
-	mova	saved_vbr, r0
-	mov.l	r1, @r0
+	stc	vbr, r0
+	mov.l	r0, @(SH_SLEEP_VBR, r5)
 
 	/* point vbr to our on-chip memory page */
 	ldc	r5, vbr
 
 	/* save return address */
-	mova	saved_spc, r0
-	sts	pr, r5
-	mov.l	r5, @r0
+	sts	pr, r0
+	mov.l	r0, @(SH_SLEEP_SPC, r5)
 
 	/* save sr */
-	mova	saved_sr, r0
-	stc	sr, r5
-	mov.l	r5, @r0
+	stc	sr, r0
+	mov.l	r0, @(SH_SLEEP_SR, r5)
 
-	/* save mode flags */
-	mova	saved_mode, r0
-	mov.l	r4, @r0
+	/* save sp */
+	mov.l	r15, @(SH_SLEEP_SP, r5)
 
-	/* put mode flags in r0 */
-	mov	r4, r0
+	/* save stbcr */
+	bsr     save_register
+	 mov    #SH_SLEEP_REG_STBCR, r0
 
+	/* save mmu and cache context if needed */
+	mov.l	@(SH_SLEEP_MODE, r5), r0
+	tst	#SUSP_SH_MMU, r0
+	bt	skip_mmu_save_disable
+
+       /* save mmu state */
+	bsr	save_register
+	 mov	#SH_SLEEP_REG_PTEH, r0
+
+	bsr	save_register
+	 mov	#SH_SLEEP_REG_PTEL, r0
+
+	bsr	save_register
+	 mov	#SH_SLEEP_REG_TTB, r0
+
+	bsr	save_register
+	 mov	#SH_SLEEP_REG_TEA, r0
+
+	bsr	save_register
+	 mov	#SH_SLEEP_REG_MMUCR, r0
+
+	bsr	save_register
+	 mov	#SH_SLEEP_REG_PTEA, r0
+
+	bsr	save_register
+	 mov	#SH_SLEEP_REG_PASCR, r0
+
+	bsr	save_register
+	 mov	#SH_SLEEP_REG_IRMCR, r0
+
+	/* invalidate TLBs and disable the MMU */
+	bsr	get_register
+	 mov	#SH_SLEEP_REG_MMUCR, r0
+	mov	#4, r1
+	mov.l	r1, @r0
+	icbi	@r0
+
+	/* save cache registers and disable caches */
+	bsr	save_register
+	 mov	#SH_SLEEP_REG_CCR, r0
+
+	bsr	save_register
+	 mov	#SH_SLEEP_REG_RAMCR, r0
+
+	bsr	get_register
+	 mov	#SH_SLEEP_REG_CCR, r0
+	mov	#0, r1
+	mov.l	r1, @r0
+	icbi	@r0
+
+skip_mmu_save_disable:
+	/* call self-refresh entering code if needed */
+	mov.l	@(SH_SLEEP_MODE, r5), r0
 	tst	#SUSP_SH_SF, r0
 	bt	skip_set_sf
-#ifdef CONFIG_CPU_SUBTYPE_SH7724
-	/* DBSC: put memory in self-refresh mode */
-	mov.l	dben_reg, r4
-	mov.l	dben_data0, r1
-	mov.l	r1, @r4
 
-	mov.l	dbrfpdn0_reg, r4
-	mov.l	dbrfpdn0_data0, r1
-	mov.l	r1, @r4
-
-	mov.l	dbcmdcnt_reg, r4
-	mov.l	dbcmdcnt_data0, r1
-	mov.l	r1, @r4
-
-	mov.l	dbcmdcnt_reg, r4
-	mov.l	dbcmdcnt_data1, r1
-	mov.l	r1, @r4
-
-	mov.l	dbrfpdn0_reg, r4
-	mov.l	dbrfpdn0_data1, r1
-	mov.l	r1, @r4
-#else
-	/* SBSC: disable power down and put in self-refresh mode */
-	mov.l	1f, r4
-	mov.l	2f, r1
-	mov.l	@r4, r2
-	or	r1, r2
-	mov.l   3f, r3
-	and	r3, r2
-	mov.l	r2, @r4
-#endif
+	mov.l	@(SH_SLEEP_SF_PRE, r5), r0
+	jsr	@r0
+	 nop
 
 skip_set_sf:
+	mov.l	@(SH_SLEEP_MODE, r5), r0
 	tst	#SUSP_SH_STANDBY, r0
 	bt	test_rstandby
 
@@ -104,6 +128,12 @@
 	tst	#SUSP_SH_RSTANDBY, r0
 	bt	test_ustandby
 
+	/* setup BAR register */
+	bsr	get_register
+	 mov	#SH_SLEEP_REG_BAR, r0
+	mov.l	@(SH_SLEEP_RESUME, r5), r1
+	mov.l	r1, @r0
+
 	/* set mode to "r-standby mode" */
 	bra	do_sleep
 	 mov	#0x20, r1
@@ -123,124 +153,136 @@
 
 do_sleep:
 	/* setup and enter selected standby mode */
-	mov.l	5f, r4
-	mov.l	r1, @r4
+	bsr     get_register
+	 mov    #SH_SLEEP_REG_STBCR, r0
+	mov.l	r1, @r0
 again:
 	sleep
 	bra	again
 	 nop
 
-restore_jump_vbr:
+save_register:
+	add	#SH_SLEEP_BASE_ADDR, r0
+	mov.l	@(r0, r5), r1
+	add	#-SH_SLEEP_BASE_ADDR, r0
+	mov.l	@r1, r1
+	add	#SH_SLEEP_BASE_DATA, r0
+	mov.l	r1, @(r0, r5)
+	add	#-SH_SLEEP_BASE_DATA, r0
+	rts
+	 nop
+
+get_register:
+	add	#SH_SLEEP_BASE_ADDR, r0
+	mov.l	@(r0, r5), r0
+	rts
+	 nop
+ENTRY(sh_mobile_sleep_enter_end)
+
+	.balign 4
+ENTRY(sh_mobile_sleep_resume_start)
+
+	/* figure out start address */
+	bsr	0f
+	 nop
+0:
+	sts	pr, k1
+	mov.l	1f, k0
+	and	k0, k1
+
+	/* store pointer to data area in VBR */
+	ldc	k1, vbr
+
+	/* setup sr with saved sr */
+	mov.l	@(SH_SLEEP_SR, k1), k0
+	ldc	k0, sr
+
+	/* now: user register set! */
+	stc	vbr, r5
+
 	/* setup spc with return address to c code */
-	mov.l	saved_spc, k0
-	ldc	k0, spc
+	mov.l	@(SH_SLEEP_SPC, r5), r0
+	ldc	r0, spc
 
 	/* restore vbr */
-	mov.l	saved_vbr, k0
-	ldc	k0, vbr
+	mov.l	@(SH_SLEEP_VBR, r5), r0
+	ldc	r0, vbr
 
 	/* setup ssr with saved sr */
-	mov.l	saved_sr, k0
-	ldc	k0, ssr
+	mov.l	@(SH_SLEEP_SR, r5), r0
+	ldc	r0, ssr
 
-	/* get mode flags */
-	mov.l	saved_mode, k0
+	/* restore sp */
+	mov.l   @(SH_SLEEP_SP, r5), r15
 
-done_sleep:
-	/* reset standby mode to sleep mode */
-	mov.l	5f, k4
-	mov	#0x00, k1
-	mov.l	k1, @k4
+	/* restore sleep mode register */
+	bsr     restore_register
+	 mov    #SH_SLEEP_REG_STBCR, r0
 
-	tst	#SUSP_SH_SF, k0
+	/* call self-refresh resume code if needed */
+	mov.l	@(SH_SLEEP_MODE, r5), r0
+	tst	#SUSP_SH_SF, r0
 	bt	skip_restore_sf
 
-#ifdef CONFIG_CPU_SUBTYPE_SH7724
-	/* DBSC: put memory in auto-refresh mode */
-	mov.l	dbrfpdn0_reg, k4
-	mov.l	dbrfpdn0_data0, k1
-	mov.l	k1, @k4
+	mov.l	@(SH_SLEEP_SF_POST, r5), r0
+	jsr	@r0
+	 nop
 
-	nop /* sleep 140 ns */
-	nop
-	nop
-	nop
-
-	mov.l	dbcmdcnt_reg, k4
-	mov.l	dbcmdcnt_data0, k1
-	mov.l	k1, @k4
-
-	mov.l	dbcmdcnt_reg, k4
-	mov.l	dbcmdcnt_data1, k1
-	mov.l	k1, @k4
-
-	mov.l	dben_reg, k4
-	mov.l	dben_data1, k1
-	mov.l	k1, @k4
-
-	mov.l	dbrfpdn0_reg, k4
-	mov.l	dbrfpdn0_data2, k1
-	mov.l	k1, @k4
-#else
-	/* SBSC: set auto-refresh mode */
-	mov.l	1f, k4
-	mov.l	@k4, k0
-	mov.l   4f, k1
-	and	k1, k0
-	mov.l	k0, @k4
-	mov.l	6f, k4
-	mov.l	8f, k0
-	mov.l	@k4, k1
-	mov	#-1, k4
-	add	k4, k1
-	or	k1, k0
-	mov.l	7f, k1
-	mov.l	k0, @k1
-#endif
 skip_restore_sf:
-	/* jump to vbr vector */
-	mov.l	saved_vbr, k0
-	mov.l	offset_vbr, k4
-	add	k4, k0
-	jmp	@k0
+	/* restore mmu and cache state if needed */
+	mov.l	@(SH_SLEEP_MODE, r5), r0
+	tst	#SUSP_SH_MMU, r0
+	bt	skip_restore_mmu
+
+	/* restore mmu state */
+	bsr	restore_register
+	 mov	#SH_SLEEP_REG_PTEH, r0
+
+	bsr	restore_register
+	 mov	#SH_SLEEP_REG_PTEL, r0
+
+	bsr	restore_register
+	 mov	#SH_SLEEP_REG_TTB, r0
+
+	bsr	restore_register
+	 mov	#SH_SLEEP_REG_TEA, r0
+
+	bsr	restore_register
+	 mov	#SH_SLEEP_REG_PTEA, r0
+
+	bsr	restore_register
+	 mov	#SH_SLEEP_REG_PASCR, r0
+
+	bsr	restore_register
+	 mov	#SH_SLEEP_REG_IRMCR, r0
+
+	bsr	restore_register
+	 mov	#SH_SLEEP_REG_MMUCR, r0
+	icbi	@r0
+
+	/* restore cache settings */
+	bsr	restore_register
+	 mov	#SH_SLEEP_REG_RAMCR, r0
+	icbi	@r0
+
+	bsr	restore_register
+	 mov	#SH_SLEEP_REG_CCR, r0
+	icbi	@r0
+
+skip_restore_mmu:
+	rte
+	 nop
+
+restore_register:
+	add	#SH_SLEEP_BASE_DATA, r0
+	mov.l	@(r0, r5), r1
+	add	#-SH_SLEEP_BASE_DATA, r0
+	add	#SH_SLEEP_BASE_ADDR, r0
+	mov.l	@(r0, r5), r0
+	mov.l	r1, @r0
+	rts
 	 nop
 
 	.balign 4
-saved_mode:	.long	0
-saved_spc:	.long	0
-saved_sr:	.long	0
-saved_vbr:	.long	0
-offset_vbr:	.long	0x600
-#ifdef CONFIG_CPU_SUBTYPE_SH7724
-dben_reg:	.long	0xfd000010 /* DBEN */
-dben_data0:	.long	0
-dben_data1:	.long	1
-dbrfpdn0_reg:	.long	0xfd000040 /* DBRFPDN0 */
-dbrfpdn0_data0:	.long	0
-dbrfpdn0_data1:	.long	1
-dbrfpdn0_data2:	.long	0x00010000
-dbcmdcnt_reg:	.long	0xfd000014 /* DBCMDCNT */
-dbcmdcnt_data0:	.long	2
-dbcmdcnt_data1:	.long	4
-#else
-1:	.long	0xfe400008 /* SDCR0 */
-2:	.long	0x00000400
-3:	.long	0xffff7fff
-4:	.long	0xfffffbff
-#endif
-5:	.long	0xa4150020 /* STBCR */
-6:	.long   0xfe40001c /* RTCOR */
-7:	.long   0xfe400018 /* RTCNT */
-8:	.long   0xa55a0000
-
-
-/* interrupt vector @ 0x600 */
-	.balign 	0x400,0,0x400
-	.long	0xdeadbeef
-	.balign 	0x200,0,0x200
-	bra	restore_jump_vbr
-	 nop
-sh_mobile_standby_end:
-
-ENTRY(sh_mobile_standby_size)
-	.long sh_mobile_standby_end - sh_mobile_standby
+1:	.long	~0x7ff
+ENTRY(sh_mobile_sleep_resume_end)
diff --git a/arch/sh/kernel/cpu/ubc.S b/arch/sh/kernel/cpu/ubc.S
deleted file mode 100644
index 8192307..0000000
--- a/arch/sh/kernel/cpu/ubc.S
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * arch/sh/kernel/cpu/ubc.S
- *
- * Set of management routines for the User Break Controller (UBC)
- *
- * Copyright (C) 2002 Paul Mundt
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-#include <linux/linkage.h>
-#include <asm/ubc.h>
-
-#define STBCR2		0xffc00010
-
-ENTRY(ubc_sleep)
-	mov	#0, r0
-
-	mov.l	1f, r1		! Zero out UBC_BBRA ..
-	mov.w	r0, @r1
-
-	mov.l	2f, r1		! .. same for BBRB ..
-	mov.w	r0, @r1
-
-	mov.l	3f, r1		! .. and again for BRCR.
-	mov.w	r0, @r1
-
-	mov.w	@r1, r0		! Dummy read BRCR
-
-	mov.l	4f, r1		! Set MSTP5 in STBCR2
-	mov.b	@r1, r0
-	or	#0x01, r0
-	mov.b	r0, @r1
-
-	mov.b	@r1, r0		! Two dummy reads ..
-	mov.b	@r1, r0
-
-	rts
-	nop
-
-ENTRY(ubc_wakeup)
-	mov.l	4f, r1		! Clear MSTP5
-	mov.b	@r1, r0
-	and	#0xfe, r0
-	mov.b	r0, @r1
-
-	mov.b	@r1, r0		! Two more dummy reads ..
-	mov.b	@r1, r0
-
-	rts
-	nop
-
-1:	.long	UBC_BBRA
-2:	.long	UBC_BBRB
-3:	.long	UBC_BRCR
-4:	.long	STBCR2
-
diff --git a/arch/sh/kernel/dma-nommu.c b/arch/sh/kernel/dma-nommu.c
new file mode 100644
index 0000000..3c55b87
--- /dev/null
+++ b/arch/sh/kernel/dma-nommu.c
@@ -0,0 +1,82 @@
+/*
+ * DMA mapping support for platforms lacking IOMMUs.
+ *
+ * Copyright (C) 2009  Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+
+static dma_addr_t nommu_map_page(struct device *dev, struct page *page,
+				 unsigned long offset, size_t size,
+				 enum dma_data_direction dir,
+				 struct dma_attrs *attrs)
+{
+	dma_addr_t addr = page_to_phys(page) + offset;
+
+	WARN_ON(size == 0);
+	dma_cache_sync(dev, page_address(page) + offset, size, dir);
+
+	return addr;
+}
+
+static int nommu_map_sg(struct device *dev, struct scatterlist *sg,
+			int nents, enum dma_data_direction dir,
+			struct dma_attrs *attrs)
+{
+	struct scatterlist *s;
+	int i;
+
+	WARN_ON(nents == 0 || sg[0].length == 0);
+
+	for_each_sg(sg, s, nents, i) {
+		BUG_ON(!sg_page(s));
+
+		dma_cache_sync(dev, sg_virt(s), s->length, dir);
+
+		s->dma_address = sg_phys(s);
+		s->dma_length = s->length;
+	}
+
+	return nents;
+}
+
+#ifdef CONFIG_DMA_NONCOHERENT
+static void nommu_sync_single(struct device *dev, dma_addr_t addr,
+			      size_t size, enum dma_data_direction dir)
+{
+	dma_cache_sync(dev, phys_to_virt(addr), size, dir);
+}
+
+static void nommu_sync_sg(struct device *dev, struct scatterlist *sg,
+			  int nelems, enum dma_data_direction dir)
+{
+	struct scatterlist *s;
+	int i;
+
+	for_each_sg(sg, s, nelems, i)
+		dma_cache_sync(dev, sg_virt(s), s->length, dir);
+}
+#endif
+
+struct dma_map_ops nommu_dma_ops = {
+	.alloc_coherent		= dma_generic_alloc_coherent,
+	.free_coherent		= dma_generic_free_coherent,
+	.map_page		= nommu_map_page,
+	.map_sg			= nommu_map_sg,
+#ifdef CONFIG_DMA_NONCOHERENT
+	.sync_single_for_device	= nommu_sync_single,
+	.sync_sg_for_device	= nommu_sync_sg,
+#endif
+	.is_phys		= 1,
+};
+
+void __init no_iommu_init(void)
+{
+	if (dma_ops)
+		return;
+	dma_ops = &nommu_dma_ops;
+}
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c
index d76a231..3576b70 100644
--- a/arch/sh/kernel/dwarf.c
+++ b/arch/sh/kernel/dwarf.c
@@ -20,6 +20,7 @@
 #include <linux/list.h>
 #include <linux/mempool.h>
 #include <linux/mm.h>
+#include <linux/elf.h>
 #include <linux/ftrace.h>
 #include <asm/dwarf.h>
 #include <asm/unwinder.h>
@@ -530,7 +531,18 @@
 }
 
 /**
- *	dwarf_unwind_stack - recursively unwind the stack
+ *	dwarf_free_frame - free the memory allocated for @frame
+ *	@frame: the frame to free
+ */
+void dwarf_free_frame(struct dwarf_frame *frame)
+{
+	dwarf_frame_free_regs(frame);
+	mempool_free(frame, dwarf_frame_pool);
+}
+
+/**
+ *	dwarf_unwind_stack - unwind the stack
+ *
  *	@pc: address of the function to unwind
  *	@prev: struct dwarf_frame of the previous stackframe on the callstack
  *
@@ -548,9 +560,9 @@
 	unsigned long addr;
 
 	/*
-	 * If this is the first invocation of this recursive function we
-	 * need get the contents of a physical register to get the CFA
-	 * in order to begin the virtual unwinding of the stack.
+	 * If we're starting at the top of the stack we need get the
+	 * contents of a physical register to get the CFA in order to
+	 * begin the virtual unwinding of the stack.
 	 *
 	 * NOTE: the return address is guaranteed to be setup by the
 	 * time this function makes its first function call.
@@ -593,9 +605,8 @@
 	fde = dwarf_lookup_fde(pc);
 	if (!fde) {
 		/*
-		 * This is our normal exit path - the one that stops the
-		 * recursion. There's two reasons why we might exit
-		 * here,
+		 * This is our normal exit path. There are two reasons
+		 * why we might exit here,
 		 *
 		 *	a) pc has no asscociated DWARF frame info and so
 		 *	we don't know how to unwind this frame. This is
@@ -637,10 +648,10 @@
 
 		} else {
 			/*
-			 * Again, this is the first invocation of this
-			 * recurisve function. We need to physically
-			 * read the contents of a register in order to
-			 * get the Canonical Frame Address for this
+			 * Again, we're starting from the top of the
+			 * stack. We need to physically read
+			 * the contents of a register in order to get
+			 * the Canonical Frame Address for this
 			 * function.
 			 */
 			frame->cfa = dwarf_read_arch_reg(frame->cfa_register);
@@ -670,13 +681,12 @@
 	return frame;
 
 bail:
-	dwarf_frame_free_regs(frame);
-	mempool_free(frame, dwarf_frame_pool);
+	dwarf_free_frame(frame);
 	return NULL;
 }
 
 static int dwarf_parse_cie(void *entry, void *p, unsigned long len,
-			   unsigned char *end)
+			   unsigned char *end, struct module *mod)
 {
 	struct dwarf_cie *cie;
 	unsigned long flags;
@@ -772,6 +782,8 @@
 	cie->initial_instructions = p;
 	cie->instructions_end = end;
 
+	cie->mod = mod;
+
 	/* Add to list */
 	spin_lock_irqsave(&dwarf_cie_lock, flags);
 	list_add_tail(&cie->link, &dwarf_cie_list);
@@ -782,7 +794,7 @@
 
 static int dwarf_parse_fde(void *entry, u32 entry_type,
 			   void *start, unsigned long len,
-			   unsigned char *end)
+			   unsigned char *end, struct module *mod)
 {
 	struct dwarf_fde *fde;
 	struct dwarf_cie *cie;
@@ -831,6 +843,8 @@
 	fde->instructions = p;
 	fde->end = end;
 
+	fde->mod = mod;
+
 	/* Add to list. */
 	spin_lock_irqsave(&dwarf_fde_lock, flags);
 	list_add_tail(&fde->link, &dwarf_fde_list);
@@ -854,10 +868,8 @@
 	while (1) {
 		frame = dwarf_unwind_stack(return_addr, _frame);
 
-		if (_frame) {
-			dwarf_frame_free_regs(_frame);
-			mempool_free(_frame, dwarf_frame_pool);
-		}
+		if (_frame)
+			dwarf_free_frame(_frame);
 
 		_frame = frame;
 
@@ -867,6 +879,9 @@
 		return_addr = frame->return_addr;
 		ops->address(data, return_addr, 1);
 	}
+
+	if (frame)
+		dwarf_free_frame(frame);
 }
 
 static struct unwinder dwarf_unwinder = {
@@ -896,6 +911,158 @@
 }
 
 /**
+ *	dwarf_parse_section - parse DWARF section
+ *	@eh_frame_start: start address of the .eh_frame section
+ *	@eh_frame_end: end address of the .eh_frame section
+ *	@mod: the kernel module containing the .eh_frame section
+ *
+ *	Parse the information in a .eh_frame section.
+ */
+static int dwarf_parse_section(char *eh_frame_start, char *eh_frame_end,
+			       struct module *mod)
+{
+	u32 entry_type;
+	void *p, *entry;
+	int count, err = 0;
+	unsigned long len = 0;
+	unsigned int c_entries, f_entries;
+	unsigned char *end;
+
+	c_entries = 0;
+	f_entries = 0;
+	entry = eh_frame_start;
+
+	while ((char *)entry < eh_frame_end) {
+		p = entry;
+
+		count = dwarf_entry_len(p, &len);
+		if (count == 0) {
+			/*
+			 * We read a bogus length field value. There is
+			 * nothing we can do here apart from disabling
+			 * the DWARF unwinder. We can't even skip this
+			 * entry and move to the next one because 'len'
+			 * tells us where our next entry is.
+			 */
+			err = -EINVAL;
+			goto out;
+		} else
+			p += count;
+
+		/* initial length does not include itself */
+		end = p + len;
+
+		entry_type = get_unaligned((u32 *)p);
+		p += 4;
+
+		if (entry_type == DW_EH_FRAME_CIE) {
+			err = dwarf_parse_cie(entry, p, len, end, mod);
+			if (err < 0)
+				goto out;
+			else
+				c_entries++;
+		} else {
+			err = dwarf_parse_fde(entry, entry_type, p, len,
+					      end, mod);
+			if (err < 0)
+				goto out;
+			else
+				f_entries++;
+		}
+
+		entry = (char *)entry + len + 4;
+	}
+
+	printk(KERN_INFO "DWARF unwinder initialised: read %u CIEs, %u FDEs\n",
+	       c_entries, f_entries);
+
+	return 0;
+
+out:
+	return err;
+}
+
+#ifdef CONFIG_MODULES
+int module_dwarf_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
+			  struct module *me)
+{
+	unsigned int i, err;
+	unsigned long start, end;
+	char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+
+	start = end = 0;
+
+	for (i = 1; i < hdr->e_shnum; i++) {
+		/* Alloc bit cleared means "ignore it." */
+		if ((sechdrs[i].sh_flags & SHF_ALLOC)
+		    && !strcmp(secstrings+sechdrs[i].sh_name, ".eh_frame")) {
+			start = sechdrs[i].sh_addr;
+			end = start + sechdrs[i].sh_size;
+			break;
+		}
+	}
+
+	/* Did we find the .eh_frame section? */
+	if (i != hdr->e_shnum) {
+		err = dwarf_parse_section((char *)start, (char *)end, me);
+		if (err) {
+			printk(KERN_WARNING "%s: failed to parse DWARF info\n",
+			       me->name);
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ *	module_dwarf_cleanup - remove FDE/CIEs associated with @mod
+ *	@mod: the module that is being unloaded
+ *
+ *	Remove any FDEs and CIEs from the global lists that came from
+ *	@mod's .eh_frame section because @mod is being unloaded.
+ */
+void module_dwarf_cleanup(struct module *mod)
+{
+	struct dwarf_fde *fde;
+	struct dwarf_cie *cie;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dwarf_cie_lock, flags);
+
+again_cie:
+	list_for_each_entry(cie, &dwarf_cie_list, link) {
+		if (cie->mod == mod)
+			break;
+	}
+
+	if (&cie->link != &dwarf_cie_list) {
+		list_del(&cie->link);
+		kfree(cie);
+		goto again_cie;
+	}
+
+	spin_unlock_irqrestore(&dwarf_cie_lock, flags);
+
+	spin_lock_irqsave(&dwarf_fde_lock, flags);
+
+again_fde:
+	list_for_each_entry(fde, &dwarf_fde_list, link) {
+		if (fde->mod == mod)
+			break;
+	}
+
+	if (&fde->link != &dwarf_fde_list) {
+		list_del(&fde->link);
+		kfree(fde);
+		goto again_fde;
+	}
+
+	spin_unlock_irqrestore(&dwarf_fde_lock, flags);
+}
+#endif /* CONFIG_MODULES */
+
+/**
  *	dwarf_unwinder_init - initialise the dwarf unwinder
  *
  *	Build the data structures describing the .dwarf_frame section to
@@ -906,19 +1073,10 @@
  */
 static int __init dwarf_unwinder_init(void)
 {
-	u32 entry_type;
-	void *p, *entry;
-	int count, err = 0;
-	unsigned long len;
-	unsigned int c_entries, f_entries;
-	unsigned char *end;
+	int err;
 	INIT_LIST_HEAD(&dwarf_cie_list);
 	INIT_LIST_HEAD(&dwarf_fde_list);
 
-	c_entries = 0;
-	f_entries = 0;
-	entry = &__start_eh_frame;
-
 	dwarf_frame_cachep = kmem_cache_create("dwarf_frames",
 			sizeof(struct dwarf_frame), 0,
 			SLAB_PANIC | SLAB_HWCACHE_ALIGN | SLAB_NOTRACK, NULL);
@@ -937,47 +1095,9 @@
 					 mempool_free_slab,
 					 dwarf_reg_cachep);
 
-	while ((char *)entry < __stop_eh_frame) {
-		p = entry;
-
-		count = dwarf_entry_len(p, &len);
-		if (count == 0) {
-			/*
-			 * We read a bogus length field value. There is
-			 * nothing we can do here apart from disabling
-			 * the DWARF unwinder. We can't even skip this
-			 * entry and move to the next one because 'len'
-			 * tells us where our next entry is.
-			 */
-			goto out;
-		} else
-			p += count;
-
-		/* initial length does not include itself */
-		end = p + len;
-
-		entry_type = get_unaligned((u32 *)p);
-		p += 4;
-
-		if (entry_type == DW_EH_FRAME_CIE) {
-			err = dwarf_parse_cie(entry, p, len, end);
-			if (err < 0)
-				goto out;
-			else
-				c_entries++;
-		} else {
-			err = dwarf_parse_fde(entry, entry_type, p, len, end);
-			if (err < 0)
-				goto out;
-			else
-				f_entries++;
-		}
-
-		entry = (char *)entry + len + 4;
-	}
-
-	printk(KERN_INFO "DWARF unwinder initialised: read %u CIEs, %u FDEs\n",
-	       c_entries, f_entries);
+	err = dwarf_parse_section(__start_eh_frame, __stop_eh_frame, NULL);
+	if (err)
+		goto out;
 
 	err = unwinder_register(&dwarf_unwinder);
 	if (err)
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index 3eb8493..f0abd58 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -133,7 +133,7 @@
 	! r8: current_thread_info
 	! t:  result of "tst	#_TIF_NEED_RESCHED, r0"
 	bf/s	work_resched
-	 tst	#(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r0
+	 tst	#_TIF_SIGPENDING, r0
 work_notifysig:
 	bt/s	__restore_all
 	 mov	r15, r4
diff --git a/arch/sh/kernel/ftrace.c b/arch/sh/kernel/ftrace.c
index 2c48e26..b6f41c1 100644
--- a/arch/sh/kernel/ftrace.c
+++ b/arch/sh/kernel/ftrace.c
@@ -62,6 +62,150 @@
 	return ftrace_replaced_code;
 }
 
+/*
+ * Modifying code must take extra care. On an SMP machine, if
+ * the code being modified is also being executed on another CPU
+ * that CPU will have undefined results and possibly take a GPF.
+ * We use kstop_machine to stop other CPUS from exectuing code.
+ * But this does not stop NMIs from happening. We still need
+ * to protect against that. We separate out the modification of
+ * the code to take care of this.
+ *
+ * Two buffers are added: An IP buffer and a "code" buffer.
+ *
+ * 1) Put the instruction pointer into the IP buffer
+ *    and the new code into the "code" buffer.
+ * 2) Wait for any running NMIs to finish and set a flag that says
+ *    we are modifying code, it is done in an atomic operation.
+ * 3) Write the code
+ * 4) clear the flag.
+ * 5) Wait for any running NMIs to finish.
+ *
+ * If an NMI is executed, the first thing it does is to call
+ * "ftrace_nmi_enter". This will check if the flag is set to write
+ * and if it is, it will write what is in the IP and "code" buffers.
+ *
+ * The trick is, it does not matter if everyone is writing the same
+ * content to the code location. Also, if a CPU is executing code
+ * it is OK to write to that code location if the contents being written
+ * are the same as what exists.
+ */
+#define MOD_CODE_WRITE_FLAG (1 << 31)	/* set when NMI should do the write */
+static atomic_t nmi_running = ATOMIC_INIT(0);
+static int mod_code_status;		/* holds return value of text write */
+static void *mod_code_ip;		/* holds the IP to write to */
+static void *mod_code_newcode;		/* holds the text to write to the IP */
+
+static unsigned nmi_wait_count;
+static atomic_t nmi_update_count = ATOMIC_INIT(0);
+
+int ftrace_arch_read_dyn_info(char *buf, int size)
+{
+	int r;
+
+	r = snprintf(buf, size, "%u %u",
+		     nmi_wait_count,
+		     atomic_read(&nmi_update_count));
+	return r;
+}
+
+static void clear_mod_flag(void)
+{
+	int old = atomic_read(&nmi_running);
+
+	for (;;) {
+		int new = old & ~MOD_CODE_WRITE_FLAG;
+
+		if (old == new)
+			break;
+
+		old = atomic_cmpxchg(&nmi_running, old, new);
+	}
+}
+
+static void ftrace_mod_code(void)
+{
+	/*
+	 * Yes, more than one CPU process can be writing to mod_code_status.
+	 *    (and the code itself)
+	 * But if one were to fail, then they all should, and if one were
+	 * to succeed, then they all should.
+	 */
+	mod_code_status = probe_kernel_write(mod_code_ip, mod_code_newcode,
+					     MCOUNT_INSN_SIZE);
+
+	/* if we fail, then kill any new writers */
+	if (mod_code_status)
+		clear_mod_flag();
+}
+
+void ftrace_nmi_enter(void)
+{
+	if (atomic_inc_return(&nmi_running) & MOD_CODE_WRITE_FLAG) {
+		smp_rmb();
+		ftrace_mod_code();
+		atomic_inc(&nmi_update_count);
+	}
+	/* Must have previous changes seen before executions */
+	smp_mb();
+}
+
+void ftrace_nmi_exit(void)
+{
+	/* Finish all executions before clearing nmi_running */
+	smp_mb();
+	atomic_dec(&nmi_running);
+}
+
+static void wait_for_nmi_and_set_mod_flag(void)
+{
+	if (!atomic_cmpxchg(&nmi_running, 0, MOD_CODE_WRITE_FLAG))
+		return;
+
+	do {
+		cpu_relax();
+	} while (atomic_cmpxchg(&nmi_running, 0, MOD_CODE_WRITE_FLAG));
+
+	nmi_wait_count++;
+}
+
+static void wait_for_nmi(void)
+{
+	if (!atomic_read(&nmi_running))
+		return;
+
+	do {
+		cpu_relax();
+	} while (atomic_read(&nmi_running));
+
+	nmi_wait_count++;
+}
+
+static int
+do_ftrace_mod_code(unsigned long ip, void *new_code)
+{
+	mod_code_ip = (void *)ip;
+	mod_code_newcode = new_code;
+
+	/* The buffers need to be visible before we let NMIs write them */
+	smp_mb();
+
+	wait_for_nmi_and_set_mod_flag();
+
+	/* Make sure all running NMIs have finished before we write the code */
+	smp_mb();
+
+	ftrace_mod_code();
+
+	/* Make sure the write happens before clearing the bit */
+	smp_mb();
+
+	clear_mod_flag();
+	wait_for_nmi();
+
+	return mod_code_status;
+}
+
 static int ftrace_modify_code(unsigned long ip, unsigned char *old_code,
 		       unsigned char *new_code)
 {
@@ -86,7 +230,7 @@
 		return -EINVAL;
 
 	/* replace the text with the new text */
-	if (probe_kernel_write((void *)ip, new_code, MCOUNT_INSN_SIZE))
+	if (do_ftrace_mod_code(ip, new_code))
 		return -EPERM;
 
 	flush_icache_range(ip, ip + MCOUNT_INSN_SIZE);
diff --git a/arch/sh/kernel/gpio.c b/arch/sh/kernel/gpio.c
deleted file mode 100644
index d22e5af..0000000
--- a/arch/sh/kernel/gpio.c
+++ /dev/null
@@ -1,584 +0,0 @@
-/*
- * Pinmuxed GPIO support for SuperH.
- *
- * Copyright (C) 2008 Magnus Damm
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/bitops.h>
-#include <linux/gpio.h>
-
-static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
-{
-	if (enum_id < r->begin)
-		return 0;
-
-	if (enum_id > r->end)
-		return 0;
-
-	return 1;
-}
-
-static unsigned long gpio_read_raw_reg(unsigned long reg,
-				       unsigned long reg_width)
-{
-	switch (reg_width) {
-	case 8:
-		return ctrl_inb(reg);
-	case 16:
-		return ctrl_inw(reg);
-	case 32:
-		return ctrl_inl(reg);
-	}
-
-	BUG();
-	return 0;
-}
-
-static void gpio_write_raw_reg(unsigned long reg,
-			       unsigned long reg_width,
-			       unsigned long data)
-{
-	switch (reg_width) {
-	case 8:
-		ctrl_outb(data, reg);
-		return;
-	case 16:
-		ctrl_outw(data, reg);
-		return;
-	case 32:
-		ctrl_outl(data, reg);
-		return;
-	}
-
-	BUG();
-}
-
-static void gpio_write_bit(struct pinmux_data_reg *dr,
-			   unsigned long in_pos, unsigned long value)
-{
-	unsigned long pos;
-
-	pos = dr->reg_width - (in_pos + 1);
-
-#ifdef DEBUG
-	pr_info("write_bit addr = %lx, value = %ld, pos = %ld, "
-		"r_width = %ld\n",
-		dr->reg, !!value, pos, dr->reg_width);
-#endif
-
-	if (value)
-		set_bit(pos, &dr->reg_shadow);
-	else
-		clear_bit(pos, &dr->reg_shadow);
-
-	gpio_write_raw_reg(dr->reg, dr->reg_width, dr->reg_shadow);
-}
-
-static int gpio_read_reg(unsigned long reg, unsigned long reg_width,
-			 unsigned long field_width, unsigned long in_pos)
-{
-	unsigned long data, mask, pos;
-
-	data = 0;
-	mask = (1 << field_width) - 1;
-	pos = reg_width - ((in_pos + 1) * field_width);
-
-#ifdef DEBUG
-	pr_info("read_reg: addr = %lx, pos = %ld, "
-		"r_width = %ld, f_width = %ld\n",
-		reg, pos, reg_width, field_width);
-#endif
-
-	data = gpio_read_raw_reg(reg, reg_width);
-	return (data >> pos) & mask;
-}
-
-static void gpio_write_reg(unsigned long reg, unsigned long reg_width,
-			   unsigned long field_width, unsigned long in_pos,
-			   unsigned long value)
-{
-	unsigned long mask, pos;
-
-	mask = (1 << field_width) - 1;
-	pos = reg_width - ((in_pos + 1) * field_width);
-
-#ifdef DEBUG
-	pr_info("write_reg addr = %lx, value = %ld, pos = %ld, "
-		"r_width = %ld, f_width = %ld\n",
-		reg, value, pos, reg_width, field_width);
-#endif
-
-	mask = ~(mask << pos);
-	value = value << pos;
-
-	switch (reg_width) {
-	case 8:
-		ctrl_outb((ctrl_inb(reg) & mask) | value, reg);
-		break;
-	case 16:
-		ctrl_outw((ctrl_inw(reg) & mask) | value, reg);
-		break;
-	case 32:
-		ctrl_outl((ctrl_inl(reg) & mask) | value, reg);
-		break;
-	}
-}
-
-static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio)
-{
-	struct pinmux_gpio *gpiop = &gpioc->gpios[gpio];
-	struct pinmux_data_reg *data_reg;
-	int k, n;
-
-	if (!enum_in_range(gpiop->enum_id, &gpioc->data))
-		return -1;
-
-	k = 0;
-	while (1) {
-		data_reg = gpioc->data_regs + k;
-
-		if (!data_reg->reg_width)
-			break;
-
-		for (n = 0; n < data_reg->reg_width; n++) {
-			if (data_reg->enum_ids[n] == gpiop->enum_id) {
-				gpiop->flags &= ~PINMUX_FLAG_DREG;
-				gpiop->flags |= (k << PINMUX_FLAG_DREG_SHIFT);
-				gpiop->flags &= ~PINMUX_FLAG_DBIT;
-				gpiop->flags |= (n << PINMUX_FLAG_DBIT_SHIFT);
-				return 0;
-			}
-		}
-		k++;
-	}
-
-	BUG();
-
-	return -1;
-}
-
-static void setup_data_regs(struct pinmux_info *gpioc)
-{
-	struct pinmux_data_reg *drp;
-	int k;
-
-	for (k = gpioc->first_gpio; k <= gpioc->last_gpio; k++)
-		setup_data_reg(gpioc, k);
-
-	k = 0;
-	while (1) {
-		drp = gpioc->data_regs + k;
-
-		if (!drp->reg_width)
-			break;
-
-		drp->reg_shadow = gpio_read_raw_reg(drp->reg, drp->reg_width);
-		k++;
-	}
-}
-
-static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio,
-			struct pinmux_data_reg **drp, int *bitp)
-{
-	struct pinmux_gpio *gpiop = &gpioc->gpios[gpio];
-	int k, n;
-
-	if (!enum_in_range(gpiop->enum_id, &gpioc->data))
-		return -1;
-
-	k = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT;
-	n = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT;
-	*drp = gpioc->data_regs + k;
-	*bitp = n;
-	return 0;
-}
-
-static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id,
-			  struct pinmux_cfg_reg **crp, int *indexp,
-			  unsigned long **cntp)
-{
-	struct pinmux_cfg_reg *config_reg;
-	unsigned long r_width, f_width;
-	int k, n;
-
-	k = 0;
-	while (1) {
-		config_reg = gpioc->cfg_regs + k;
-
-		r_width = config_reg->reg_width;
-		f_width = config_reg->field_width;
-
-		if (!r_width)
-			break;
-		for (n = 0; n < (r_width / f_width) * 1 << f_width; n++) {
-			if (config_reg->enum_ids[n] == enum_id) {
-				*crp = config_reg;
-				*indexp = n;
-				*cntp = &config_reg->cnt[n / (1 << f_width)];
-				return 0;
-			}
-		}
-		k++;
-	}
-
-	return -1;
-}
-
-static int get_gpio_enum_id(struct pinmux_info *gpioc, unsigned gpio,
-			    int pos, pinmux_enum_t *enum_idp)
-{
-	pinmux_enum_t enum_id = gpioc->gpios[gpio].enum_id;
-	pinmux_enum_t *data = gpioc->gpio_data;
-	int k;
-
-	if (!enum_in_range(enum_id, &gpioc->data)) {
-		if (!enum_in_range(enum_id, &gpioc->mark)) {
-			pr_err("non data/mark enum_id for gpio %d\n", gpio);
-			return -1;
-		}
-	}
-
-	if (pos) {
-		*enum_idp = data[pos + 1];
-		return pos + 1;
-	}
-
-	for (k = 0; k < gpioc->gpio_data_size; k++) {
-		if (data[k] == enum_id) {
-			*enum_idp = data[k + 1];
-			return k + 1;
-		}
-	}
-
-	pr_err("cannot locate data/mark enum_id for gpio %d\n", gpio);
-	return -1;
-}
-
-static void write_config_reg(struct pinmux_info *gpioc,
-			     struct pinmux_cfg_reg *crp,
-			     int index)
-{
-	unsigned long ncomb, pos, value;
-
-	ncomb = 1 << crp->field_width;
-	pos = index / ncomb;
-	value = index % ncomb;
-
-	gpio_write_reg(crp->reg, crp->reg_width, crp->field_width, pos, value);
-}
-
-static int check_config_reg(struct pinmux_info *gpioc,
-			    struct pinmux_cfg_reg *crp,
-			    int index)
-{
-	unsigned long ncomb, pos, value;
-
-	ncomb = 1 << crp->field_width;
-	pos = index / ncomb;
-	value = index % ncomb;
-
-	if (gpio_read_reg(crp->reg, crp->reg_width,
-			  crp->field_width, pos) == value)
-		return 0;
-
-	return -1;
-}
-
-enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE };
-
-static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
-			      int pinmux_type, int cfg_mode)
-{
-	struct pinmux_cfg_reg *cr = NULL;
-	pinmux_enum_t enum_id;
-	struct pinmux_range *range;
-	int in_range, pos, index;
-	unsigned long *cntp;
-
-	switch (pinmux_type) {
-
-	case PINMUX_TYPE_FUNCTION:
-		range = NULL;
-		break;
-
-	case PINMUX_TYPE_OUTPUT:
-		range = &gpioc->output;
-		break;
-
-	case PINMUX_TYPE_INPUT:
-		range = &gpioc->input;
-		break;
-
-	case PINMUX_TYPE_INPUT_PULLUP:
-		range = &gpioc->input_pu;
-		break;
-
-	case PINMUX_TYPE_INPUT_PULLDOWN:
-		range = &gpioc->input_pd;
-		break;
-
-	default:
-		goto out_err;
-	}
-
-	pos = 0;
-	enum_id = 0;
-	index = 0;
-	while (1) {
-		pos = get_gpio_enum_id(gpioc, gpio, pos, &enum_id);
-		if (pos <= 0)
-			goto out_err;
-
-		if (!enum_id)
-			break;
-
-		in_range = enum_in_range(enum_id, &gpioc->function);
-		if (!in_range && range) {
-			in_range = enum_in_range(enum_id, range);
-
-			if (in_range && enum_id == range->force)
-				continue;
-		}
-
-		if (!in_range)
-			continue;
-
-		if (get_config_reg(gpioc, enum_id, &cr, &index, &cntp) != 0)
-			goto out_err;
-
-		switch (cfg_mode) {
-		case GPIO_CFG_DRYRUN:
-			if (!*cntp || !check_config_reg(gpioc, cr, index))
-				continue;
-			break;
-
-		case GPIO_CFG_REQ:
-			write_config_reg(gpioc, cr, index);
-			*cntp = *cntp + 1;
-			break;
-
-		case GPIO_CFG_FREE:
-			*cntp = *cntp - 1;
-			break;
-		}
-	}
-
-	return 0;
- out_err:
-	return -1;
-}
-
-static DEFINE_SPINLOCK(gpio_lock);
-
-static struct pinmux_info *chip_to_pinmux(struct gpio_chip *chip)
-{
-	return container_of(chip, struct pinmux_info, chip);
-}
-
-static int sh_gpio_request(struct gpio_chip *chip, unsigned offset)
-{
-	struct pinmux_info *gpioc = chip_to_pinmux(chip);
-	struct pinmux_data_reg *dummy;
-	unsigned long flags;
-	int i, ret, pinmux_type;
-
-	ret = -EINVAL;
-
-	if (!gpioc)
-		goto err_out;
-
-	spin_lock_irqsave(&gpio_lock, flags);
-
-	if ((gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE)
-		goto err_unlock;
-
-	/* setup pin function here if no data is associated with pin */
-
-	if (get_data_reg(gpioc, offset, &dummy, &i) != 0)
-		pinmux_type = PINMUX_TYPE_FUNCTION;
-	else
-		pinmux_type = PINMUX_TYPE_GPIO;
-
-	if (pinmux_type == PINMUX_TYPE_FUNCTION) {
-		if (pinmux_config_gpio(gpioc, offset,
-				       pinmux_type,
-				       GPIO_CFG_DRYRUN) != 0)
-			goto err_unlock;
-
-		if (pinmux_config_gpio(gpioc, offset,
-				       pinmux_type,
-				       GPIO_CFG_REQ) != 0)
-			BUG();
-	}
-
-	gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
-	gpioc->gpios[offset].flags |= pinmux_type;
-
-	ret = 0;
- err_unlock:
-	spin_unlock_irqrestore(&gpio_lock, flags);
- err_out:
-	return ret;
-}
-
-static void sh_gpio_free(struct gpio_chip *chip, unsigned offset)
-{
-	struct pinmux_info *gpioc = chip_to_pinmux(chip);
-	unsigned long flags;
-	int pinmux_type;
-
-	if (!gpioc)
-		return;
-
-	spin_lock_irqsave(&gpio_lock, flags);
-
-	pinmux_type = gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE;
-	pinmux_config_gpio(gpioc, offset, pinmux_type, GPIO_CFG_FREE);
-	gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
-	gpioc->gpios[offset].flags |= PINMUX_TYPE_NONE;
-
-	spin_unlock_irqrestore(&gpio_lock, flags);
-}
-
-static int pinmux_direction(struct pinmux_info *gpioc,
-			    unsigned gpio, int new_pinmux_type)
-{
-	int pinmux_type;
-	int ret = -EINVAL;
-
-	if (!gpioc)
-		goto err_out;
-
-	pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE;
-
-	switch (pinmux_type) {
-	case PINMUX_TYPE_GPIO:
-		break;
-	case PINMUX_TYPE_OUTPUT:
-	case PINMUX_TYPE_INPUT:
-	case PINMUX_TYPE_INPUT_PULLUP:
-	case PINMUX_TYPE_INPUT_PULLDOWN:
-		pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE);
-		break;
-	default:
-		goto err_out;
-	}
-
-	if (pinmux_config_gpio(gpioc, gpio,
-			       new_pinmux_type,
-			       GPIO_CFG_DRYRUN) != 0)
-		goto err_out;
-
-	if (pinmux_config_gpio(gpioc, gpio,
-			       new_pinmux_type,
-			       GPIO_CFG_REQ) != 0)
-		BUG();
-
-	gpioc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE;
-	gpioc->gpios[gpio].flags |= new_pinmux_type;
-
-	ret = 0;
- err_out:
-	return ret;
-}
-
-static int sh_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
-{
-	struct pinmux_info *gpioc = chip_to_pinmux(chip);
-	unsigned long flags;
-	int ret;
-
-	spin_lock_irqsave(&gpio_lock, flags);
-	ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_INPUT);
-	spin_unlock_irqrestore(&gpio_lock, flags);
-
-	return ret;
-}
-
-static void sh_gpio_set_value(struct pinmux_info *gpioc,
-			     unsigned gpio, int value)
-{
-	struct pinmux_data_reg *dr = NULL;
-	int bit = 0;
-
-	if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
-		BUG();
-	else
-		gpio_write_bit(dr, bit, value);
-}
-
-static int sh_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
-				    int value)
-{
-	struct pinmux_info *gpioc = chip_to_pinmux(chip);
-	unsigned long flags;
-	int ret;
-
-	sh_gpio_set_value(gpioc, offset, value);
-	spin_lock_irqsave(&gpio_lock, flags);
-	ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_OUTPUT);
-	spin_unlock_irqrestore(&gpio_lock, flags);
-
-	return ret;
-}
-
-static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
-{
-	struct pinmux_data_reg *dr = NULL;
-	int bit = 0;
-
-	if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0) {
-		BUG();
-		return 0;
-	}
-
-	return gpio_read_reg(dr->reg, dr->reg_width, 1, bit);
-}
-
-static int sh_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
-	return sh_gpio_get_value(chip_to_pinmux(chip), offset);
-}
-
-static void sh_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
-{
-	sh_gpio_set_value(chip_to_pinmux(chip), offset, value);
-}
-
-int register_pinmux(struct pinmux_info *pip)
-{
-	struct gpio_chip *chip = &pip->chip;
-
-	pr_info("sh pinmux: %s handling gpio %d -> %d\n",
-		pip->name, pip->first_gpio, pip->last_gpio);
-
-	setup_data_regs(pip);
-
-	chip->request = sh_gpio_request;
-	chip->free = sh_gpio_free;
-	chip->direction_input = sh_gpio_direction_input;
-	chip->get = sh_gpio_get;
-	chip->direction_output = sh_gpio_direction_output;
-	chip->set = sh_gpio_set;
-
-	WARN_ON(pip->first_gpio != 0); /* needs testing */
-
-	chip->label = pip->name;
-	chip->owner = THIS_MODULE;
-	chip->base = pip->first_gpio;
-	chip->ngpio = (pip->last_gpio - pip->first_gpio) + 1;
-
-	return gpiochip_add(chip);
-}
diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S
index a78be74..1151ecd 100644
--- a/arch/sh/kernel/head_32.S
+++ b/arch/sh/kernel/head_32.S
@@ -33,7 +33,7 @@
 	.long	1		/* LOADER_TYPE */
 	.long	0x00000000	/* INITRD_START */
 	.long	0x00000000	/* INITRD_SIZE */
-#ifdef CONFIG_32BIT
+#if defined(CONFIG_32BIT) && defined(CONFIG_PMB_FIXED)
 	.long	0x53453f00 + 32	/* "SE?" = 32 bit */
 #else
 	.long	0x53453f00 + 29	/* "SE?" = 29 bit */
diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c
index 27ff2dc..aaff003 100644
--- a/arch/sh/kernel/idle.c
+++ b/arch/sh/kernel/idle.c
@@ -21,7 +21,7 @@
 #include <asm/atomic.h>
 
 static int hlt_counter;
-void (*pm_idle)(void);
+void (*pm_idle)(void) = NULL;
 void (*pm_power_off)(void);
 EXPORT_SYMBOL(pm_power_off);
 
@@ -39,48 +39,92 @@
 }
 __setup("hlt", hlt_setup);
 
-void default_idle(void)
+static inline int hlt_works(void)
 {
-	if (!hlt_counter) {
-		clear_thread_flag(TIF_POLLING_NRFLAG);
-		smp_mb__after_clear_bit();
-		set_bl_bit();
-		stop_critical_timings();
-
-		while (!need_resched())
-			cpu_sleep();
-
-		start_critical_timings();
-		clear_bl_bit();
-		set_thread_flag(TIF_POLLING_NRFLAG);
-	} else
-		while (!need_resched())
-			cpu_relax();
+	return !hlt_counter;
 }
 
+/*
+ * On SMP it's slightly faster (but much more power-consuming!)
+ * to poll the ->work.need_resched flag instead of waiting for the
+ * cross-CPU IPI to arrive. Use this option with caution.
+ */
+static void poll_idle(void)
+{
+	local_irq_enable();
+	while (!need_resched())
+		cpu_relax();
+}
+
+void default_idle(void)
+{
+	if (hlt_works()) {
+		clear_thread_flag(TIF_POLLING_NRFLAG);
+		smp_mb__after_clear_bit();
+
+		if (!need_resched()) {
+			local_irq_enable();
+			cpu_sleep();
+		} else
+			local_irq_enable();
+
+		set_thread_flag(TIF_POLLING_NRFLAG);
+	} else
+		poll_idle();
+}
+
+/*
+ * The idle thread. There's no useful work to be done, so just try to conserve
+ * power and have a low exit latency (ie sit in a loop waiting for somebody to
+ * say that they'd like to reschedule)
+ */
 void cpu_idle(void)
 {
+	unsigned int cpu = smp_processor_id();
+
 	set_thread_flag(TIF_POLLING_NRFLAG);
 
 	/* endless idle loop with no priority at all */
 	while (1) {
-		void (*idle)(void) = pm_idle;
-
-		if (!idle)
-			idle = default_idle;
-
 		tick_nohz_stop_sched_tick(1);
-		while (!need_resched())
-			idle();
-		tick_nohz_restart_sched_tick();
 
+		while (!need_resched() && cpu_online(cpu)) {
+			check_pgt_cache();
+			rmb();
+
+			local_irq_disable();
+			/* Don't trace irqs off for idle */
+			stop_critical_timings();
+			pm_idle();
+			/*
+			 * Sanity check to ensure that pm_idle() returns
+			 * with IRQs enabled
+			 */
+			WARN_ON(irqs_disabled());
+			start_critical_timings();
+		}
+
+		tick_nohz_restart_sched_tick();
 		preempt_enable_no_resched();
 		schedule();
 		preempt_disable();
-		check_pgt_cache();
 	}
 }
 
+void __cpuinit select_idle_routine(void)
+{
+	/*
+	 * If a platform has set its own idle routine, leave it alone.
+	 */
+	if (pm_idle)
+		return;
+
+	if (hlt_works())
+		pm_idle = default_idle;
+	else
+		pm_idle = poll_idle;
+}
+
 static void do_nothing(void *unused)
 {
 }
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c
index b8fa652..e1e1dbd 100644
--- a/arch/sh/kernel/io_generic.c
+++ b/arch/sh/kernel/io_generic.c
@@ -24,7 +24,7 @@
 #define dummy_read()
 #endif
 
-unsigned long generic_io_base;
+unsigned long generic_io_base = 0;
 
 u8 generic_inb(unsigned long port)
 {
@@ -147,8 +147,10 @@
 
 void __iomem *generic_ioport_map(unsigned long addr, unsigned int size)
 {
+#ifdef P1SEG
 	if (PXSEG(addr) >= P1SEG)
 		return (void __iomem *)addr;
+#endif
 
 	return (void __iomem *)(addr + generic_io_base);
 }
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index eac7da7..e1913f2 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -37,7 +37,15 @@
  */
 static int show_other_interrupts(struct seq_file *p, int prec)
 {
+	int j;
+
+	seq_printf(p, "%*s: ", prec, "NMI");
+	for_each_online_cpu(j)
+		seq_printf(p, "%10u ", irq_stat[j].__nmi_count);
+	seq_printf(p, "  Non-maskable interrupts\n");
+
 	seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count));
+
 	return 0;
 }
 
@@ -255,6 +263,12 @@
 {
 	plat_irq_setup();
 
+	/*
+	 * Pin any of the legacy IRQ vectors that haven't already been
+	 * grabbed by the platform
+	 */
+	reserve_irq_legacy();
+
 	/* Perform the machine specific initialisation */
 	if (sh_mv.mv_init_irq)
 		sh_mv.mv_init_irq();
diff --git a/arch/sh/kernel/irq_32.c b/arch/sh/kernel/irq_32.c
new file mode 100644
index 0000000..e33ab15
--- /dev/null
+++ b/arch/sh/kernel/irq_32.c
@@ -0,0 +1,57 @@
+/*
+ * SHcompact irqflags support
+ *
+ * Copyright (C) 2006 - 2009 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/irqflags.h>
+#include <linux/module.h>
+
+void notrace raw_local_irq_restore(unsigned long flags)
+{
+	unsigned long __dummy0, __dummy1;
+
+	if (flags == RAW_IRQ_DISABLED) {
+		__asm__ __volatile__ (
+			"stc	sr, %0\n\t"
+			"or	#0xf0, %0\n\t"
+			"ldc	%0, sr\n\t"
+			: "=&z" (__dummy0)
+			: /* no inputs */
+			: "memory"
+		);
+	} else {
+		__asm__ __volatile__ (
+			"stc	sr, %0\n\t"
+			"and	%1, %0\n\t"
+#ifdef CONFIG_CPU_HAS_SR_RB
+			"stc	r6_bank, %1\n\t"
+			"or	%1, %0\n\t"
+#endif
+			"ldc	%0, sr\n\t"
+			: "=&r" (__dummy0), "=r" (__dummy1)
+			: "1" (~RAW_IRQ_DISABLED)
+			: "memory"
+		);
+	}
+}
+EXPORT_SYMBOL(raw_local_irq_restore);
+
+unsigned long notrace __raw_local_save_flags(void)
+{
+	unsigned long flags;
+
+	__asm__ __volatile__ (
+		"stc	sr, %0\n\t"
+		"and	#0xf0, %0\n\t"
+		: "=&z" (flags)
+		: /* no inputs */
+		: "memory"
+	);
+
+	return flags;
+}
+EXPORT_SYMBOL(__raw_local_save_flags);
diff --git a/arch/sh/kernel/irq_64.c b/arch/sh/kernel/irq_64.c
new file mode 100644
index 0000000..32365ba
--- /dev/null
+++ b/arch/sh/kernel/irq_64.c
@@ -0,0 +1,51 @@
+/*
+ * SHmedia irqflags support
+ *
+ * Copyright (C) 2006 - 2009 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/irqflags.h>
+#include <linux/module.h>
+#include <cpu/registers.h>
+
+void notrace raw_local_irq_restore(unsigned long flags)
+{
+	unsigned long long __dummy;
+
+	if (flags == RAW_IRQ_DISABLED) {
+		__asm__ __volatile__ (
+			"getcon	" __SR ", %0\n\t"
+			"or	%0, %1, %0\n\t"
+			"putcon	%0, " __SR "\n\t"
+			: "=&r" (__dummy)
+			: "r" (RAW_IRQ_DISABLED)
+		);
+	} else {
+		__asm__ __volatile__ (
+			"getcon	" __SR ", %0\n\t"
+			"and	%0, %1, %0\n\t"
+			"putcon	%0, " __SR "\n\t"
+			: "=&r" (__dummy)
+			: "r" (~RAW_IRQ_DISABLED)
+		);
+	}
+}
+EXPORT_SYMBOL(raw_local_irq_restore);
+
+unsigned long notrace __raw_local_save_flags(void)
+{
+	unsigned long flags;
+
+	__asm__ __volatile__ (
+		"getcon	" __SR ", %0\n\t"
+		"and	%0, %1, %0"
+		: "=&r" (flags)
+		: "r" (RAW_IRQ_DISABLED)
+	);
+
+	return flags;
+}
+EXPORT_SYMBOL(__raw_local_save_flags);
diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c
index 7ea2704..76f2802 100644
--- a/arch/sh/kernel/machine_kexec.c
+++ b/arch/sh/kernel/machine_kexec.c
@@ -46,12 +46,6 @@
  */
 int machine_kexec_prepare(struct kimage *image)
 {
-	/* older versions of kexec-tools are passing
-	 * the zImage entry point as a virtual address.
-	 */
-	if (image->start != PHYSADDR(image->start))
-		return -EINVAL; /* upgrade your kexec-tools */
-
 	return 0;
 }
 
diff --git a/arch/sh/kernel/machvec.c b/arch/sh/kernel/machvec.c
index cbce639..1652340 100644
--- a/arch/sh/kernel/machvec.c
+++ b/arch/sh/kernel/machvec.c
@@ -135,5 +135,9 @@
 	if (!sh_mv.mv_nr_irqs)
 		sh_mv.mv_nr_irqs = NR_IRQS;
 
+#ifdef P2SEG
 	__set_io_port_base(P2SEG);
+#else
+	__set_io_port_base(0);
+#endif
 }
diff --git a/arch/sh/kernel/module.c b/arch/sh/kernel/module.c
index c2efdcd..43adddf 100644
--- a/arch/sh/kernel/module.c
+++ b/arch/sh/kernel/module.c
@@ -32,6 +32,7 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <asm/unaligned.h>
+#include <asm/dwarf.h>
 
 void *module_alloc(unsigned long size)
 {
@@ -145,10 +146,16 @@
 		    const Elf_Shdr *sechdrs,
 		    struct module *me)
 {
-	return module_bug_finalize(hdr, sechdrs, me);
+	int ret = 0;
+
+	ret |= module_dwarf_finalize(hdr, sechdrs, me);
+	ret |= module_bug_finalize(hdr, sechdrs, me);
+
+	return ret;
 }
 
 void module_arch_cleanup(struct module *mod)
 {
 	module_bug_cleanup(mod);
+	module_dwarf_cleanup(mod);
 }
diff --git a/arch/sh/kernel/perf_callchain.c b/arch/sh/kernel/perf_callchain.c
new file mode 100644
index 0000000..24ea837
--- /dev/null
+++ b/arch/sh/kernel/perf_callchain.c
@@ -0,0 +1,98 @@
+/*
+ * Performance event callchain support - SuperH architecture code
+ *
+ * Copyright (C) 2009  Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/perf_event.h>
+#include <linux/percpu.h>
+#include <asm/unwinder.h>
+#include <asm/ptrace.h>
+
+static inline void callchain_store(struct perf_callchain_entry *entry, u64 ip)
+{
+	if (entry->nr < PERF_MAX_STACK_DEPTH)
+		entry->ip[entry->nr++] = ip;
+}
+
+static void callchain_warning(void *data, char *msg)
+{
+}
+
+static void
+callchain_warning_symbol(void *data, char *msg, unsigned long symbol)
+{
+}
+
+static int callchain_stack(void *data, char *name)
+{
+	return 0;
+}
+
+static void callchain_address(void *data, unsigned long addr, int reliable)
+{
+	struct perf_callchain_entry *entry = data;
+
+	if (reliable)
+		callchain_store(entry, addr);
+}
+
+static const struct stacktrace_ops callchain_ops = {
+	.warning	= callchain_warning,
+	.warning_symbol	= callchain_warning_symbol,
+	.stack		= callchain_stack,
+	.address	= callchain_address,
+};
+
+static void
+perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry)
+{
+	callchain_store(entry, PERF_CONTEXT_KERNEL);
+	callchain_store(entry, regs->pc);
+
+	unwind_stack(NULL, regs, NULL, &callchain_ops, entry);
+}
+
+static void
+perf_do_callchain(struct pt_regs *regs, struct perf_callchain_entry *entry)
+{
+	int is_user;
+
+	if (!regs)
+		return;
+
+	is_user = user_mode(regs);
+
+	if (!current || current->pid == 0)
+		return;
+
+	if (is_user && current->state != TASK_RUNNING)
+		return;
+
+	/*
+	 * Only the kernel side is implemented for now.
+	 */
+	if (!is_user)
+		perf_callchain_kernel(regs, entry);
+}
+
+/*
+ * No need for separate IRQ and NMI entries.
+ */
+static DEFINE_PER_CPU(struct perf_callchain_entry, callchain);
+
+struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
+{
+	struct perf_callchain_entry *entry = &__get_cpu_var(callchain);
+
+	entry->nr = 0;
+
+	perf_do_callchain(regs, entry);
+
+	return entry;
+}
diff --git a/arch/sh/kernel/perf_event.c b/arch/sh/kernel/perf_event.c
new file mode 100644
index 0000000..7ff0943
--- /dev/null
+++ b/arch/sh/kernel/perf_event.c
@@ -0,0 +1,312 @@
+/*
+ * Performance event support framework for SuperH hardware counters.
+ *
+ *  Copyright (C) 2009  Paul Mundt
+ *
+ * Heavily based on the x86 and PowerPC implementations.
+ *
+ * x86:
+ *  Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
+ *  Copyright (C) 2009 Jaswinder Singh Rajput
+ *  Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *  Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
+ *
+ * ppc:
+ *  Copyright 2008-2009 Paul Mackerras, IBM Corporation.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/perf_event.h>
+#include <asm/processor.h>
+
+struct cpu_hw_events {
+	struct perf_event	*events[MAX_HWEVENTS];
+	unsigned long		used_mask[BITS_TO_LONGS(MAX_HWEVENTS)];
+	unsigned long		active_mask[BITS_TO_LONGS(MAX_HWEVENTS)];
+};
+
+DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
+
+static struct sh_pmu *sh_pmu __read_mostly;
+
+/* Number of perf_events counting hardware events */
+static atomic_t num_events;
+/* Used to avoid races in calling reserve/release_pmc_hardware */
+static DEFINE_MUTEX(pmc_reserve_mutex);
+
+/*
+ * Stub these out for now, do something more profound later.
+ */
+int reserve_pmc_hardware(void)
+{
+	return 0;
+}
+
+void release_pmc_hardware(void)
+{
+}
+
+static inline int sh_pmu_initialized(void)
+{
+	return !!sh_pmu;
+}
+
+/*
+ * Release the PMU if this is the last perf_event.
+ */
+static void hw_perf_event_destroy(struct perf_event *event)
+{
+	if (!atomic_add_unless(&num_events, -1, 1)) {
+		mutex_lock(&pmc_reserve_mutex);
+		if (atomic_dec_return(&num_events) == 0)
+			release_pmc_hardware();
+		mutex_unlock(&pmc_reserve_mutex);
+	}
+}
+
+static int hw_perf_cache_event(int config, int *evp)
+{
+	unsigned long type, op, result;
+	int ev;
+
+	if (!sh_pmu->cache_events)
+		return -EINVAL;
+
+	/* unpack config */
+	type = config & 0xff;
+	op = (config >> 8) & 0xff;
+	result = (config >> 16) & 0xff;
+
+	if (type >= PERF_COUNT_HW_CACHE_MAX ||
+	    op >= PERF_COUNT_HW_CACHE_OP_MAX ||
+	    result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
+		return -EINVAL;
+
+	ev = (*sh_pmu->cache_events)[type][op][result];
+	if (ev == 0)
+		return -EOPNOTSUPP;
+	if (ev == -1)
+		return -EINVAL;
+	*evp = ev;
+	return 0;
+}
+
+static int __hw_perf_event_init(struct perf_event *event)
+{
+	struct perf_event_attr *attr = &event->attr;
+	struct hw_perf_event *hwc = &event->hw;
+	int config = -1;
+	int err;
+
+	if (!sh_pmu_initialized())
+		return -ENODEV;
+
+	/*
+	 * All of the on-chip counters are "limited", in that they have
+	 * no interrupts, and are therefore unable to do sampling without
+	 * further work and timer assistance.
+	 */
+	if (hwc->sample_period)
+		return -EINVAL;
+
+	/*
+	 * See if we need to reserve the counter.
+	 *
+	 * If no events are currently in use, then we have to take a
+	 * mutex to ensure that we don't race with another task doing
+	 * reserve_pmc_hardware or release_pmc_hardware.
+	 */
+	err = 0;
+	if (!atomic_inc_not_zero(&num_events)) {
+		mutex_lock(&pmc_reserve_mutex);
+		if (atomic_read(&num_events) == 0 &&
+		    reserve_pmc_hardware())
+			err = -EBUSY;
+		else
+			atomic_inc(&num_events);
+		mutex_unlock(&pmc_reserve_mutex);
+	}
+
+	if (err)
+		return err;
+
+	event->destroy = hw_perf_event_destroy;
+
+	switch (attr->type) {
+	case PERF_TYPE_RAW:
+		config = attr->config & sh_pmu->raw_event_mask;
+		break;
+	case PERF_TYPE_HW_CACHE:
+		err = hw_perf_cache_event(attr->config, &config);
+		if (err)
+			return err;
+		break;
+	case PERF_TYPE_HARDWARE:
+		if (attr->config >= sh_pmu->max_events)
+			return -EINVAL;
+
+		config = sh_pmu->event_map(attr->config);
+		break;
+	}
+
+	if (config == -1)
+		return -EINVAL;
+
+	hwc->config |= config;
+
+	return 0;
+}
+
+static void sh_perf_event_update(struct perf_event *event,
+				   struct hw_perf_event *hwc, int idx)
+{
+	u64 prev_raw_count, new_raw_count;
+	s64 delta;
+	int shift = 0;
+
+	/*
+	 * Depending on the counter configuration, they may or may not
+	 * be chained, in which case the previous counter value can be
+	 * updated underneath us if the lower-half overflows.
+	 *
+	 * Our tactic to handle this is to first atomically read and
+	 * exchange a new raw count - then add that new-prev delta
+	 * count to the generic counter atomically.
+	 *
+	 * As there is no interrupt associated with the overflow events,
+	 * this is the simplest approach for maintaining consistency.
+	 */
+again:
+	prev_raw_count = atomic64_read(&hwc->prev_count);
+	new_raw_count = sh_pmu->read(idx);
+
+	if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count,
+			     new_raw_count) != prev_raw_count)
+		goto again;
+
+	/*
+	 * Now we have the new raw value and have updated the prev
+	 * timestamp already. We can now calculate the elapsed delta
+	 * (counter-)time and add that to the generic counter.
+	 *
+	 * Careful, not all hw sign-extends above the physical width
+	 * of the count.
+	 */
+	delta = (new_raw_count << shift) - (prev_raw_count << shift);
+	delta >>= shift;
+
+	atomic64_add(delta, &event->count);
+}
+
+static void sh_pmu_disable(struct perf_event *event)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx = hwc->idx;
+
+	clear_bit(idx, cpuc->active_mask);
+	sh_pmu->disable(hwc, idx);
+
+	barrier();
+
+	sh_perf_event_update(event, &event->hw, idx);
+
+	cpuc->events[idx] = NULL;
+	clear_bit(idx, cpuc->used_mask);
+
+	perf_event_update_userpage(event);
+}
+
+static int sh_pmu_enable(struct perf_event *event)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx = hwc->idx;
+
+	if (test_and_set_bit(idx, cpuc->used_mask)) {
+		idx = find_first_zero_bit(cpuc->used_mask, sh_pmu->num_events);
+		if (idx == sh_pmu->num_events)
+			return -EAGAIN;
+
+		set_bit(idx, cpuc->used_mask);
+		hwc->idx = idx;
+	}
+
+	sh_pmu->disable(hwc, idx);
+
+	cpuc->events[idx] = event;
+	set_bit(idx, cpuc->active_mask);
+
+	sh_pmu->enable(hwc, idx);
+
+	perf_event_update_userpage(event);
+
+	return 0;
+}
+
+static void sh_pmu_read(struct perf_event *event)
+{
+	sh_perf_event_update(event, &event->hw, event->hw.idx);
+}
+
+static const struct pmu pmu = {
+	.enable		= sh_pmu_enable,
+	.disable	= sh_pmu_disable,
+	.read		= sh_pmu_read,
+};
+
+const struct pmu *hw_perf_event_init(struct perf_event *event)
+{
+	int err = __hw_perf_event_init(event);
+	if (unlikely(err)) {
+		if (event->destroy)
+			event->destroy(event);
+		return ERR_PTR(err);
+	}
+
+	return &pmu;
+}
+
+void hw_perf_event_setup(int cpu)
+{
+	struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu);
+
+	memset(cpuhw, 0, sizeof(struct cpu_hw_events));
+}
+
+void hw_perf_enable(void)
+{
+	if (!sh_pmu_initialized())
+		return;
+
+	sh_pmu->enable_all();
+}
+
+void hw_perf_disable(void)
+{
+	if (!sh_pmu_initialized())
+		return;
+
+	sh_pmu->disable_all();
+}
+
+int register_sh_pmu(struct sh_pmu *pmu)
+{
+	if (sh_pmu)
+		return -EBUSY;
+	sh_pmu = pmu;
+
+	pr_info("Performance Events: %s support registered\n", pmu->name);
+
+	WARN_ON(pmu->num_events > MAX_HWEVENTS);
+
+	return 0;
+}
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index 0673c47..d8af889 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -134,7 +134,10 @@
 	regs.regs[5] = (unsigned long)fn;
 
 	regs.pc = (unsigned long)kernel_thread_helper;
-	regs.sr = (1 << 30);
+	regs.sr = SR_MD;
+#if defined(CONFIG_SH_FPU)
+	regs.sr |= SR_FD;
+#endif
 
 	/* Ok, create the new process.. */
 	pid = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
@@ -142,6 +145,7 @@
 
 	return pid;
 }
+EXPORT_SYMBOL(kernel_thread);
 
 /*
  * Free current thread data structures etc..
@@ -186,6 +190,16 @@
 
 	return fpvalid;
 }
+EXPORT_SYMBOL(dump_fpu);
+
+/*
+ * This gets called before we allocate a new thread and copy
+ * the current task into it.
+ */
+void prepare_to_copy(struct task_struct *tsk)
+{
+	unlazy_fpu(tsk, task_pt_regs(tsk));
+}
 
 asmlinkage void ret_from_fork(void);
 
@@ -195,16 +209,10 @@
 {
 	struct thread_info *ti = task_thread_info(p);
 	struct pt_regs *childregs;
-#if defined(CONFIG_SH_FPU) || defined(CONFIG_SH_DSP)
+#if defined(CONFIG_SH_DSP)
 	struct task_struct *tsk = current;
 #endif
 
-#if defined(CONFIG_SH_FPU)
-	unlazy_fpu(tsk, regs);
-	p->thread.fpu = tsk->thread.fpu;
-	copy_to_stopped_child_used_math(p);
-#endif
-
 #if defined(CONFIG_SH_DSP)
 	if (is_dsp_enabled(tsk)) {
 		/* We can use the __save_dsp or just copy the struct:
@@ -224,6 +232,8 @@
 	} else {
 		childregs->regs[15] = (unsigned long)childregs;
 		ti->addr_limit = KERNEL_DS;
+		ti->status &= ~TS_USEDFPU;
+		p->fpu_counter = 0;
 	}
 
 	if (clone_flags & CLONE_SETTLS)
@@ -288,9 +298,13 @@
 __notrace_funcgraph struct task_struct *
 __switch_to(struct task_struct *prev, struct task_struct *next)
 {
-#if defined(CONFIG_SH_FPU)
+	struct thread_struct *next_t = &next->thread;
+
 	unlazy_fpu(prev, task_pt_regs(prev));
-#endif
+
+	/* we're going to use this soon, after a few expensive things */
+	if (next->fpu_counter > 5)
+		prefetch(&next_t->fpu.hard);
 
 #ifdef CONFIG_MMU
 	/*
@@ -321,6 +335,14 @@
 #endif
 	}
 
+	/*
+	 * If the task has used fpu the last 5 timeslices, just do a full
+	 * restore of the math state immediately to avoid the trap; the
+	 * chances of needing FPU soon are obviously high now
+	 */
+	if (next->fpu_counter > 5)
+		fpu_state_restore(task_pt_regs(next));
+
 	return prev;
 }
 
diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c
index 1192398..359b8a2 100644
--- a/arch/sh/kernel/process_64.c
+++ b/arch/sh/kernel/process_64.c
@@ -335,6 +335,7 @@
 	return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
 		      &regs, 0, NULL, NULL);
 }
+EXPORT_SYMBOL(kernel_thread);
 
 /*
  * Free current thread data structures etc..
@@ -417,6 +418,7 @@
 	return 0; /* Task didn't use the fpu at all. */
 #endif
 }
+EXPORT_SYMBOL(dump_fpu);
 
 asmlinkage void ret_from_fork(void);
 
diff --git a/arch/sh/kernel/return_address.c b/arch/sh/kernel/return_address.c
new file mode 100644
index 0000000..df3ab58
--- /dev/null
+++ b/arch/sh/kernel/return_address.c
@@ -0,0 +1,54 @@
+/*
+ * arch/sh/kernel/return_address.c
+ *
+ * Copyright (C) 2009  Matt Fleming
+ * Copyright (C) 2009  Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/kernel.h>
+#include <asm/dwarf.h>
+
+#ifdef CONFIG_DWARF_UNWINDER
+
+void *return_address(unsigned int depth)
+{
+	struct dwarf_frame *frame;
+	unsigned long ra;
+	int i;
+
+	for (i = 0, frame = NULL, ra = 0; i <= depth; i++) {
+		struct dwarf_frame *tmp;
+
+		tmp = dwarf_unwind_stack(ra, frame);
+
+		if (frame)
+			dwarf_free_frame(frame);
+
+		frame = tmp;
+
+		if (!frame || !frame->return_addr)
+			break;
+
+		ra = frame->return_addr;
+	}
+
+	/* Failed to unwind the stack to the specified depth. */
+	WARN_ON(i != depth + 1);
+
+	if (frame)
+		dwarf_free_frame(frame);
+
+	return (void *)ra;
+}
+
+#else
+
+void *return_address(unsigned int depth)
+{
+	return NULL;
+}
+
+#endif
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 99b4fb5..5a947a2 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -453,6 +453,10 @@
 
 	paging_init();
 
+#ifdef CONFIG_PMB_ENABLE
+	pmb_init();
+#endif
+
 #ifdef CONFIG_SMP
 	plat_smp_setup();
 #endif
diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c
index 444cce3..3896f26 100644
--- a/arch/sh/kernel/sh_ksyms_32.c
+++ b/arch/sh/kernel/sh_ksyms_32.c
@@ -1,37 +1,11 @@
 #include <linux/module.h>
-#include <linux/smp.h>
-#include <linux/user.h>
-#include <linux/elfcore.h>
-#include <linux/sched.h>
-#include <linux/in6.h>
-#include <linux/interrupt.h>
-#include <linux/vmalloc.h>
-#include <linux/pci.h>
-#include <linux/irq.h>
-#include <asm/sections.h>
-#include <asm/processor.h>
-#include <asm/uaccess.h>
+#include <linux/string.h>
+#include <linux/uaccess.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
 #include <asm/checksum.h>
-#include <asm/io.h>
-#include <asm/delay.h>
-#include <asm/tlbflush.h>
-#include <asm/cacheflush.h>
-#include <asm/ftrace.h>
+#include <asm/sections.h>
 
-extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
-
-/* platform dependent support */
-EXPORT_SYMBOL(dump_fpu);
-EXPORT_SYMBOL(kernel_thread);
-EXPORT_SYMBOL(strlen);
-
-/* PCI exports */
-#ifdef CONFIG_PCI
-EXPORT_SYMBOL(pci_alloc_consistent);
-EXPORT_SYMBOL(pci_free_consistent);
-#endif
-
-/* mem exports */
 EXPORT_SYMBOL(memchr);
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(memset);
@@ -40,6 +14,13 @@
 EXPORT_SYMBOL(__udelay);
 EXPORT_SYMBOL(__ndelay);
 EXPORT_SYMBOL(__const_udelay);
+EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(csum_partial);
+EXPORT_SYMBOL(csum_partial_copy_generic);
+EXPORT_SYMBOL(copy_page);
+EXPORT_SYMBOL(__clear_user);
+EXPORT_SYMBOL(_ebss);
+EXPORT_SYMBOL(empty_zero_page);
 
 #define DECLARE_EXPORT(name)		\
 	extern void name(void);EXPORT_SYMBOL(name)
@@ -107,30 +88,6 @@
 DECLARE_EXPORT(__udivsi3_i4);
 DECLARE_EXPORT(__sdivsi3_i4i);
 DECLARE_EXPORT(__udivsi3_i4i);
-
-#if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \
-	defined(CONFIG_SH7705_CACHE_32KB))
-/* needed by some modules */
-EXPORT_SYMBOL(flush_cache_all);
-EXPORT_SYMBOL(flush_cache_range);
-EXPORT_SYMBOL(flush_dcache_page);
-#endif
-
 #ifdef CONFIG_MCOUNT
 DECLARE_EXPORT(mcount);
 #endif
-EXPORT_SYMBOL(csum_partial);
-EXPORT_SYMBOL(csum_partial_copy_generic);
-#ifdef CONFIG_IPV6
-EXPORT_SYMBOL(csum_ipv6_magic);
-#endif
-EXPORT_SYMBOL(copy_page);
-EXPORT_SYMBOL(__clear_user);
-EXPORT_SYMBOL(_ebss);
-EXPORT_SYMBOL(empty_zero_page);
-
-#ifndef CONFIG_CACHE_OFF
-EXPORT_SYMBOL(__flush_purge_region);
-EXPORT_SYMBOL(__flush_wback_region);
-EXPORT_SYMBOL(__flush_invalidate_region);
-#endif
diff --git a/arch/sh/kernel/sh_ksyms_64.c b/arch/sh/kernel/sh_ksyms_64.c
index d008e17..45afa5c 100644
--- a/arch/sh/kernel/sh_ksyms_64.c
+++ b/arch/sh/kernel/sh_ksyms_64.c
@@ -24,16 +24,6 @@
 #include <asm/delay.h>
 #include <asm/irq.h>
 
-extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
-
-/* platform dependent support */
-EXPORT_SYMBOL(dump_fpu);
-EXPORT_SYMBOL(kernel_thread);
-
-#ifdef CONFIG_VT
-EXPORT_SYMBOL(screen_info);
-#endif
-
 EXPORT_SYMBOL(__put_user_asm_b);
 EXPORT_SYMBOL(__put_user_asm_w);
 EXPORT_SYMBOL(__put_user_asm_l);
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index 3db3742..12815ce 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -67,7 +67,8 @@
 
 	current->state = TASK_INTERRUPTIBLE;
 	schedule();
-	set_thread_flag(TIF_RESTORE_SIGMASK);
+	set_restore_sigmask();
+
 	return -ERESTARTNOHAND;
 }
 
@@ -590,7 +591,7 @@
 	if (try_to_freeze())
 		goto no_signal;
 
-	if (test_thread_flag(TIF_RESTORE_SIGMASK))
+	if (current_thread_info()->status & TS_RESTORE_SIGMASK)
 		oldset = &current->saved_sigmask;
 	else
 		oldset = &current->blocked;
@@ -602,12 +603,13 @@
 		/* Whee!  Actually deliver the signal.  */
 		if (handle_signal(signr, &ka, &info, oldset,
 				  regs, save_r0) == 0) {
-			/* a signal was successfully delivered; the saved
+			/*
+			 * A signal was successfully delivered; the saved
 			 * sigmask will have been stored in the signal frame,
 			 * and will be restored by sigreturn, so we can simply
-			 * clear the TIF_RESTORE_SIGMASK flag */
-			if (test_thread_flag(TIF_RESTORE_SIGMASK))
-				clear_thread_flag(TIF_RESTORE_SIGMASK);
+			 * clear the TS_RESTORE_SIGMASK flag
+			 */
+			current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
 
 			tracehook_signal_handler(signr, &info, &ka, regs,
 					test_thread_flag(TIF_SINGLESTEP));
@@ -631,10 +633,12 @@
 		}
 	}
 
-	/* if there's no signal to deliver, we just put the saved sigmask
-	 * back */
-	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
-		clear_thread_flag(TIF_RESTORE_SIGMASK);
+	/*
+	 * If there's no signal to deliver, we just put the saved sigmask
+	 * back.
+	 */
+	if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
+		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
 		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
 	}
 }
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index 74793c8..feb3ddd 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -101,7 +101,7 @@
 	if (try_to_freeze())
 		goto no_signal;
 
-	if (test_thread_flag(TIF_RESTORE_SIGMASK))
+	if (current_thread_info()->status & TS_RESTORE_SIGMASK)
 		oldset = &current->saved_sigmask;
 	else if (!oldset)
 		oldset = &current->blocked;
@@ -115,11 +115,9 @@
 			/*
 			 * If a signal was successfully delivered, the
 			 * saved sigmask is in its frame, and we can
-			 * clear the TIF_RESTORE_SIGMASK flag.
+			 * clear the TS_RESTORE_SIGMASK flag.
 			 */
-			if (test_thread_flag(TIF_RESTORE_SIGMASK))
-				clear_thread_flag(TIF_RESTORE_SIGMASK);
-
+			current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
 			tracehook_signal_handler(signr, &info, &ka, regs, 0);
 			return 1;
 		}
@@ -146,8 +144,8 @@
 	}
 
 	/* No signal to deliver -- put the saved sigmask back */
-	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
-		clear_thread_flag(TIF_RESTORE_SIGMASK);
+	if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
+		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
 		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
 	}
 
@@ -176,6 +174,7 @@
 	while (1) {
 		current->state = TASK_INTERRUPTIBLE;
 		schedule();
+		set_restore_sigmask();
 		regs->pc += 4;    /* because sys_sigreturn decrements the pc */
 		if (do_signal(regs, &saveset)) {
 			/* pc now points at signal handler. Need to decrement
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index 160db10..983e079 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -122,7 +122,9 @@
 	stack_start.bss_start = 0; /* don't clear bss for secondary cpus */
 	stack_start.start_kernel_fn = start_secondary;
 
-	flush_cache_all();
+	flush_icache_range((unsigned long)&stack_start,
+			   (unsigned long)&stack_start + sizeof(stack_start));
+	wmb();
 
 	plat_start_cpu(cpu, (unsigned long)_stext);
 
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
index 8aa5d1c..71399cd 100644
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -28,37 +28,13 @@
 #include <asm/cacheflush.h>
 #include <asm/cachectl.h>
 
-static inline long
-do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
-	 unsigned long flags, int fd, unsigned long pgoff)
-{
-	int error = -EBADF;
-	struct file *file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-
 asmlinkage int old_mmap(unsigned long addr, unsigned long len,
 	unsigned long prot, unsigned long flags,
 	int fd, unsigned long off)
 {
 	if (off & ~PAGE_MASK)
 		return -EINVAL;
-	return do_mmap2(addr, len, prot, flags, fd, off>>PAGE_SHIFT);
+	return sys_mmap_pgoff(addr, len, prot, flags, fd, off>>PAGE_SHIFT);
 }
 
 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
@@ -74,7 +50,7 @@
 
 	pgoff >>= PAGE_SHIFT - 12;
 
-	return do_mmap2(addr, len, prot, flags, fd, pgoff);
+	return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
 }
 
 /*
diff --git a/arch/sh/kernel/topology.c b/arch/sh/kernel/topology.c
index 0838942..9b0b633 100644
--- a/arch/sh/kernel/topology.c
+++ b/arch/sh/kernel/topology.c
@@ -16,6 +16,32 @@
 
 static DEFINE_PER_CPU(struct cpu, cpu_devices);
 
+cpumask_t cpu_core_map[NR_CPUS];
+
+static cpumask_t cpu_coregroup_map(unsigned int cpu)
+{
+	/*
+	 * Presently all SH-X3 SMP cores are multi-cores, so just keep it
+	 * simple until we have a method for determining topology..
+	 */
+	return cpu_possible_map;
+}
+
+const struct cpumask *cpu_coregroup_mask(unsigned int cpu)
+{
+	return &cpu_core_map[cpu];
+}
+
+int arch_update_cpu_topology(void)
+{
+	unsigned int cpu;
+
+	for_each_possible_cpu(cpu)
+		cpu_core_map[cpu] = cpu_coregroup_map(cpu);
+
+	return 0;
+}
+
 static int __init topology_init(void)
 {
 	int i, ret;
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index a8396f3..7b03633 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -9,8 +9,8 @@
 #include <asm/unwinder.h>
 #include <asm/system.h>
 
-#ifdef CONFIG_BUG
-void handle_BUG(struct pt_regs *regs)
+#ifdef CONFIG_GENERIC_BUG
+static void handle_BUG(struct pt_regs *regs)
 {
 	const struct bug_entry *bug;
 	unsigned long bugaddr = regs->pc;
@@ -81,7 +81,7 @@
 		       SIGTRAP) == NOTIFY_STOP)
 		return;
 
-#ifdef CONFIG_BUG
+#ifdef CONFIG_GENERIC_BUG
 	if (__kernel_text_address(instruction_pointer(regs))) {
 		insn_size_t insn = *(insn_size_t *)instruction_pointer(regs);
 		if (insn == TRAPA_BUG_OPCODE)
@@ -95,9 +95,11 @@
 
 BUILD_TRAP_HANDLER(nmi)
 {
+	unsigned int cpu = smp_processor_id();
 	TRAP_HANDLER_DECL;
 
 	nmi_enter();
+	nmi_count(cpu)++;
 
 	switch (notify_die(DIE_NMI, "NMI", regs, 0, vec & 0xff, SIGINT)) {
 	case NOTIFY_OK:
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 7a2ee3a..3da5a12 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -25,6 +25,7 @@
 #include <linux/kexec.h>
 #include <linux/limits.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/sysfs.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -68,61 +69,49 @@
 	"signal+warn"
 };
 
-static int
-proc_alignment_read(char *page, char **start, off_t off, int count, int *eof,
-		    void *data)
+static int alignment_proc_show(struct seq_file *m, void *v)
 {
-	char *p = page;
-	int len;
-
-	p += sprintf(p, "User:\t\t%lu\n", se_user);
-	p += sprintf(p, "System:\t\t%lu\n", se_sys);
-	p += sprintf(p, "Half:\t\t%lu\n", se_half);
-	p += sprintf(p, "Word:\t\t%lu\n", se_word);
-	p += sprintf(p, "DWord:\t\t%lu\n", se_dword);
-	p += sprintf(p, "Multi:\t\t%lu\n", se_multi);
-	p += sprintf(p, "User faults:\t%i (%s)\n", se_usermode,
+	seq_printf(m, "User:\t\t%lu\n", se_user);
+	seq_printf(m, "System:\t\t%lu\n", se_sys);
+	seq_printf(m, "Half:\t\t%lu\n", se_half);
+	seq_printf(m, "Word:\t\t%lu\n", se_word);
+	seq_printf(m, "DWord:\t\t%lu\n", se_dword);
+	seq_printf(m, "Multi:\t\t%lu\n", se_multi);
+	seq_printf(m, "User faults:\t%i (%s)\n", se_usermode,
 			se_usermode_action[se_usermode]);
-	p += sprintf(p, "Kernel faults:\t%i (fixup%s)\n", se_kernmode_warn,
+	seq_printf(m, "Kernel faults:\t%i (fixup%s)\n", se_kernmode_warn,
 			se_kernmode_warn ? "+warn" : "");
-
-	len = (p - page) - off;
-	if (len < 0)
-		len = 0;
-
-	*eof = (len <= count) ? 1 : 0;
-	*start = page + off;
-
-	return len;
+	return 0;
 }
 
-static int proc_alignment_write(struct file *file, const char __user *buffer,
-				unsigned long count, void *data)
+static int alignment_proc_open(struct inode *inode, struct file *file)
 {
+	return single_open(file, alignment_proc_show, NULL);
+}
+
+static ssize_t alignment_proc_write(struct file *file,
+		const char __user *buffer, size_t count, loff_t *pos)
+{
+	int *data = PDE(file->f_path.dentry->d_inode)->data;
 	char mode;
 
 	if (count > 0) {
 		if (get_user(mode, buffer))
 			return -EFAULT;
 		if (mode >= '0' && mode <= '5')
-			se_usermode = mode - '0';
+			*data = mode - '0';
 	}
 	return count;
 }
 
-static int proc_alignment_kern_write(struct file *file, const char __user *buffer,
-				     unsigned long count, void *data)
-{
-	char mode;
-
-	if (count > 0) {
-		if (get_user(mode, buffer))
-			return -EFAULT;
-		if (mode >= '0' && mode <= '1')
-			se_kernmode_warn = mode - '0';
-	}
-	return count;
-}
+static const struct file_operations alignment_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= alignment_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= alignment_proc_write,
+};
 #endif
 
 static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
@@ -945,14 +934,9 @@
 	set_exception_table_evt(0x800, do_reserved_inst);
 	set_exception_table_evt(0x820, do_illegal_slot_inst);
 #elif defined(CONFIG_SH_FPU)
-#ifdef CONFIG_CPU_SUBTYPE_SHX3
-	set_exception_table_evt(0xd80, fpu_state_restore_trap_handler);
-	set_exception_table_evt(0xda0, fpu_state_restore_trap_handler);
-#else
 	set_exception_table_evt(0x800, fpu_state_restore_trap_handler);
 	set_exception_table_evt(0x820, fpu_state_restore_trap_handler);
 #endif
-#endif
 
 #ifdef CONFIG_CPU_SH2
 	set_exception_table_vec(TRAP_ADDRESS_ERROR, address_error_trap_handler);
@@ -1011,20 +995,16 @@
 	if (!dir)
 		return -ENOMEM;
 
-	res = create_proc_entry("alignment", S_IWUSR | S_IRUGO, dir);
+	res = proc_create_data("alignment", S_IWUSR | S_IRUGO, dir,
+			       &alignment_proc_fops, &se_usermode);
 	if (!res)
 		return -ENOMEM;
 
-	res->read_proc = proc_alignment_read;
-	res->write_proc = proc_alignment_write;
-
-        res = create_proc_entry("kernel_alignment", S_IWUSR | S_IRUGO, dir);
+        res = proc_create_data("kernel_alignment", S_IWUSR | S_IRUGO, dir,
+			       &alignment_proc_fops, &se_kernmode_warn);
         if (!res)
                 return -ENOMEM;
 
-        res->read_proc = proc_alignment_read;
-        res->write_proc = proc_alignment_kern_write;
-
 	return 0;
 }
 
diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile
index a969b47..dab4d21 100644
--- a/arch/sh/lib/Makefile
+++ b/arch/sh/lib/Makefile
@@ -2,7 +2,7 @@
 # Makefile for SuperH-specific library files..
 #
 
-lib-y  = delay.o memset.o memmove.o memchr.o \
+lib-y  = delay.o memmove.o memchr.o \
 	 checksum.o strlen.o div64.o div64-generic.o
 
 # Extracted from libgcc
@@ -23,8 +23,11 @@
 memcpy-y			:= memcpy.o
 memcpy-$(CONFIG_CPU_SH4)	:= memcpy-sh4.o
 
+memset-y			:= memset.o
+memset-$(CONFIG_CPU_SH4)	:= memset-sh4.o
+
 lib-$(CONFIG_MMU)		+= copy_page.o __clear_user.o
 lib-$(CONFIG_MCOUNT)		+= mcount.o
-lib-y				+= $(memcpy-y) $(udivsi3-y)
+lib-y				+= $(memcpy-y) $(memset-y) $(udivsi3-y)
 
 EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/lib/memset-sh4.S b/arch/sh/lib/memset-sh4.S
new file mode 100644
index 0000000..1a6e32c
--- /dev/null
+++ b/arch/sh/lib/memset-sh4.S
@@ -0,0 +1,107 @@
+/*
+ * "memset" implementation for SH4
+ *
+ * Copyright (C) 1999  Niibe Yutaka
+ * Copyright (c) 2009  STMicroelectronics Limited
+ * Author: Stuart Menefy <stuart.menefy:st.com>
+ */
+
+/*
+ *            void *memset(void *s, int c, size_t n);
+ */
+
+#include <linux/linkage.h>
+
+ENTRY(memset)
+	mov	#12,r0
+	add	r6,r4
+	cmp/gt	r6,r0
+	bt/s	40f		! if it's too small, set a byte at once
+	 mov	r4,r0
+	and	#3,r0
+	cmp/eq	#0,r0
+	bt/s	2f		! It's aligned
+	 sub	r0,r6
+1:
+	dt	r0
+	bf/s	1b
+	 mov.b	r5,@-r4
+2:				! make VVVV
+	extu.b	r5,r5
+	swap.b	r5,r0		!   V0
+	or	r0,r5		!   VV
+	swap.w	r5,r0		! VV00
+	or	r0,r5		! VVVV
+
+	! Check if enough bytes need to be copied to be worth the big loop
+	mov	#0x40, r0	! (MT)
+	cmp/gt	r6,r0		! (MT)  64 > len => slow loop
+
+	bt/s	22f
+	 mov	r6,r0
+
+	! align the dst to the cache block size if necessary
+	mov	r4, r3
+	mov	#~(0x1f), r1
+
+	and	r3, r1
+	cmp/eq	r3, r1
+
+	bt/s	11f		! dst is already aligned
+	 sub	r1, r3		! r3-r1 -> r3
+	shlr2	r3		! number of loops
+
+10:	mov.l	r5,@-r4
+	dt	r3
+	bf/s	10b
+	 add	#-4, r6
+
+11:	! dst is 32byte aligned
+	mov	r6,r2
+	mov	#-5,r0
+	shld	r0,r2		! number of loops
+
+	add	#-32, r4
+	mov	r5, r0
+12:
+	movca.l	r0,@r4
+	mov.l	r5,@(4, r4)
+	mov.l	r5,@(8, r4)
+	mov.l	r5,@(12,r4)
+	mov.l	r5,@(16,r4)
+	mov.l	r5,@(20,r4)
+	add	#-0x20, r6
+	mov.l	r5,@(24,r4)
+	dt	r2
+	mov.l	r5,@(28,r4)
+	bf/s	12b
+	 add	#-32, r4
+
+	add	#32, r4
+	mov	#8, r0
+	cmp/ge	r0, r6
+	bf	40f
+
+	mov	r6,r0
+22:
+	shlr2	r0
+	shlr	r0		! r0 = r6 >> 3
+3:
+	dt	r0
+	mov.l	r5,@-r4		! set 8-byte at once
+	bf/s	3b
+	 mov.l	r5,@-r4
+	!
+	mov	#7,r0
+	and	r0,r6
+
+	! fill bytes (length may be zero)
+40:	tst	r6,r6
+	bt	5f
+4:
+	dt	r6
+	bf/s	4b
+	 mov.b	r5,@-r4
+5:
+	rts
+	 mov	r4,r0
diff --git a/arch/sh/math-emu/math.c b/arch/sh/math-emu/math.c
index ac2d7ab..d6c15ca 100644
--- a/arch/sh/math-emu/math.c
+++ b/arch/sh/math-emu/math.c
@@ -558,7 +558,7 @@
 					    (finsn >> 8) & 0xf);
 			tsk->thread.fpu.hard.fpscr &=
 				~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK);
-			set_tsk_thread_flag(tsk, TIF_USEDFPU);
+			task_thread_info(tsk)->status |= TS_USEDFPU;
 		} else {
 			info.si_signo = SIGFPE;
 			info.si_errno = 0;
@@ -619,10 +619,10 @@
 	struct task_struct *tsk = current;
 	struct sh_fpu_soft_struct *fpu = &(tsk->thread.fpu.soft);
 
-	if (!test_tsk_thread_flag(tsk, TIF_USEDFPU)) {
+	if (!(task_thread_info(tsk)->status & TS_USEDFPU)) {
 		/* initialize once. */
 		fpu_init(fpu);
-		set_tsk_thread_flag(tsk, TIF_USEDFPU);
+		task_thread_info(tsk)->status |= TS_USEDFPU;
 	}
 
 	return fpu_emulate(inst, fpu, regs);
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index 7f7b52f..0e7ba8e 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -82,8 +82,7 @@
 
 config PMB_ENABLE
 	bool "Support 32-bit physical addressing through PMB"
-	depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7757 || CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785)
-	select 32BIT
+	depends on MMU && EXPERIMENTAL && CPU_SH4A
 	default y
 	help
 	  If you say Y here, physical addressing will be extended to
@@ -97,8 +96,7 @@
 
 config PMB
 	bool "PMB"
-	depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7757 || CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785)
-	select 32BIT
+	depends on MMU && EXPERIMENTAL && CPU_SH4A
 	help
 	  If you say Y here, physical addressing will be extended to
 	  32-bits through the SH-4A PMB. If this is not set, legacy
@@ -106,9 +104,7 @@
 
 config PMB_FIXED
 	bool "fixed PMB"
-	depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7757 || \
-					   CPU_SUBTYPE_SH7780 || \
-					   CPU_SUBTYPE_SH7785)
+	depends on MMU && EXPERIMENTAL && CPU_SH4A
 	select 32BIT
 	help
 	  If this option is enabled, fixed PMB mappings are inherited
@@ -258,6 +254,15 @@
 
 source "mm/Kconfig"
 
+config SCHED_MC
+	bool "Multi-core scheduler support"
+	depends on SMP
+	default y
+	help
+	  Multi-core scheduler support improves the CPU scheduler's decision
+	  making when dealing with multi-core CPU chips at a cost of slightly
+	  increased overhead in some places. If unsure say N here.
+
 endmenu
 
 menu "Cache configuration"
diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile
index 3759bf8..8a70535 100644
--- a/arch/sh/mm/Makefile
+++ b/arch/sh/mm/Makefile
@@ -33,8 +33,7 @@
 endif
 
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
-obj-$(CONFIG_PMB)		+= pmb.o
-obj-$(CONFIG_PMB_FIXED)		+= pmb-fixed.o
+obj-$(CONFIG_PMB_ENABLE)	+= pmb.o
 obj-$(CONFIG_NUMA)		+= numa.o
 
 # Special flags for fault_64.o.  This puts restrictions on the number of
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index b7f235c..f36a08b 100644
--- a/arch/sh/mm/cache-sh4.c
+++ b/arch/sh/mm/cache-sh4.c
@@ -2,7 +2,7 @@
  * arch/sh/mm/cache-sh4.c
  *
  * Copyright (C) 1999, 2000, 2002  Niibe Yutaka
- * Copyright (C) 2001 - 2007  Paul Mundt
+ * Copyright (C) 2001 - 2009  Paul Mundt
  * Copyright (C) 2003  Richard Curnow
  * Copyright (c) 2007 STMicroelectronics (R&D) Ltd.
  *
@@ -15,6 +15,8 @@
 #include <linux/io.h>
 #include <linux/mutex.h>
 #include <linux/fs.h>
+#include <linux/highmem.h>
+#include <asm/pgtable.h>
 #include <asm/mmu_context.h>
 #include <asm/cacheflush.h>
 
@@ -23,21 +25,12 @@
  * flushing. Anything exceeding this will simply flush the dcache in its
  * entirety.
  */
-#define MAX_DCACHE_PAGES	64	/* XXX: Tune for ways */
 #define MAX_ICACHE_PAGES	32
 
 static void __flush_cache_one(unsigned long addr, unsigned long phys,
 			       unsigned long exec_offset);
 
 /*
- * This is initialised here to ensure that it is not placed in the BSS.  If
- * that were to happen, note that cache_init gets called before the BSS is
- * cleared, so this would get nulled out which would be hopeless.
- */
-static void (*__flush_dcache_segment_fn)(unsigned long, unsigned long) =
-	(void (*)(unsigned long, unsigned long))0xdeadbeef;
-
-/*
  * Write back the range of D-cache, and purge the I-cache.
  *
  * Called from kernel/module.c:sys_init_module and routine for a.out format,
@@ -97,15 +90,15 @@
 	unsigned long flags, exec_offset = 0;
 
 	/*
-	 * All types of SH-4 require PC to be in P2 to operate on the I-cache.
-	 * Some types of SH-4 require PC to be in P2 to operate on the D-cache.
+	 * All types of SH-4 require PC to be uncached to operate on the I-cache.
+	 * Some types of SH-4 require PC to be uncached to operate on the D-cache.
 	 */
 	if ((boot_cpu_data.flags & CPU_HAS_P2_FLUSH_BUG) ||
 	    (start < CACHE_OC_ADDRESS_ARRAY))
-		exec_offset = 0x20000000;
+		exec_offset = cached_to_uncached;
 
 	local_irq_save(flags);
-	__flush_cache_one(start | SH_CACHE_ASSOC, P1SEGADDR(phys), exec_offset);
+	__flush_cache_one(start, phys, exec_offset);
 	local_irq_restore(flags);
 }
 
@@ -124,7 +117,7 @@
 	else
 #endif
 	{
-		unsigned long phys = PHYSADDR(page_address(page));
+		unsigned long phys = page_to_phys(page);
 		unsigned long addr = CACHE_OC_ADDRESS_ARRAY;
 		int i, n;
 
@@ -159,10 +152,27 @@
 	local_irq_restore(flags);
 }
 
-static inline void flush_dcache_all(void)
+static void flush_dcache_all(void)
 {
-	(*__flush_dcache_segment_fn)(0UL, boot_cpu_data.dcache.way_size);
-	wmb();
+	unsigned long addr, end_addr, entry_offset;
+
+	end_addr = CACHE_OC_ADDRESS_ARRAY +
+		(current_cpu_data.dcache.sets <<
+		 current_cpu_data.dcache.entry_shift) *
+			current_cpu_data.dcache.ways;
+
+	entry_offset = 1 << current_cpu_data.dcache.entry_shift;
+
+	for (addr = CACHE_OC_ADDRESS_ARRAY; addr < end_addr; ) {
+		__raw_writel(0, addr); addr += entry_offset;
+		__raw_writel(0, addr); addr += entry_offset;
+		__raw_writel(0, addr); addr += entry_offset;
+		__raw_writel(0, addr); addr += entry_offset;
+		__raw_writel(0, addr); addr += entry_offset;
+		__raw_writel(0, addr); addr += entry_offset;
+		__raw_writel(0, addr); addr += entry_offset;
+		__raw_writel(0, addr); addr += entry_offset;
+	}
 }
 
 static void sh4_flush_cache_all(void *unused)
@@ -171,89 +181,13 @@
 	flush_icache_all();
 }
 
-static void __flush_cache_mm(struct mm_struct *mm, unsigned long start,
-			     unsigned long end)
-{
-	unsigned long d = 0, p = start & PAGE_MASK;
-	unsigned long alias_mask = boot_cpu_data.dcache.alias_mask;
-	unsigned long n_aliases = boot_cpu_data.dcache.n_aliases;
-	unsigned long select_bit;
-	unsigned long all_aliases_mask;
-	unsigned long addr_offset;
-	pgd_t *dir;
-	pmd_t *pmd;
-	pud_t *pud;
-	pte_t *pte;
-	int i;
-
-	dir = pgd_offset(mm, p);
-	pud = pud_offset(dir, p);
-	pmd = pmd_offset(pud, p);
-	end = PAGE_ALIGN(end);
-
-	all_aliases_mask = (1 << n_aliases) - 1;
-
-	do {
-		if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) {
-			p &= PMD_MASK;
-			p += PMD_SIZE;
-			pmd++;
-
-			continue;
-		}
-
-		pte = pte_offset_kernel(pmd, p);
-
-		do {
-			unsigned long phys;
-			pte_t entry = *pte;
-
-			if (!(pte_val(entry) & _PAGE_PRESENT)) {
-				pte++;
-				p += PAGE_SIZE;
-				continue;
-			}
-
-			phys = pte_val(entry) & PTE_PHYS_MASK;
-
-			if ((p ^ phys) & alias_mask) {
-				d |= 1 << ((p & alias_mask) >> PAGE_SHIFT);
-				d |= 1 << ((phys & alias_mask) >> PAGE_SHIFT);
-
-				if (d == all_aliases_mask)
-					goto loop_exit;
-			}
-
-			pte++;
-			p += PAGE_SIZE;
-		} while (p < end && ((unsigned long)pte & ~PAGE_MASK));
-		pmd++;
-	} while (p < end);
-
-loop_exit:
-	addr_offset = 0;
-	select_bit = 1;
-
-	for (i = 0; i < n_aliases; i++) {
-		if (d & select_bit) {
-			(*__flush_dcache_segment_fn)(addr_offset, PAGE_SIZE);
-			wmb();
-		}
-
-		select_bit <<= 1;
-		addr_offset += PAGE_SIZE;
-	}
-}
-
 /*
  * Note : (RPC) since the caches are physically tagged, the only point
  * of flush_cache_mm for SH-4 is to get rid of aliases from the
  * D-cache.  The assumption elsewhere, e.g. flush_cache_range, is that
  * lines can stay resident so long as the virtual address they were
  * accessed with (hence cache set) is in accord with the physical
- * address (i.e. tag).  It's no different here.  So I reckon we don't
- * need to flush the I-cache, since aliases don't matter for that.  We
- * should try that.
+ * address (i.e. tag).  It's no different here.
  *
  * Caller takes mm->mmap_sem.
  */
@@ -264,33 +198,7 @@
 	if (cpu_context(smp_processor_id(), mm) == NO_CONTEXT)
 		return;
 
-	/*
-	 * If cache is only 4k-per-way, there are never any 'aliases'.  Since
-	 * the cache is physically tagged, the data can just be left in there.
-	 */
-	if (boot_cpu_data.dcache.n_aliases == 0)
-		return;
-
-	/*
-	 * Don't bother groveling around the dcache for the VMA ranges
-	 * if there are too many PTEs to make it worthwhile.
-	 */
-	if (mm->nr_ptes >= MAX_DCACHE_PAGES)
-		flush_dcache_all();
-	else {
-		struct vm_area_struct *vma;
-
-		/*
-		 * In this case there are reasonably sized ranges to flush,
-		 * iterate through the VMA list and take care of any aliases.
-		 */
-		for (vma = mm->mmap; vma; vma = vma->vm_next)
-			__flush_cache_mm(mm, vma->vm_start, vma->vm_end);
-	}
-
-	/* Only touch the icache if one of the VMAs has VM_EXEC set. */
-	if (mm->exec_vm)
-		flush_icache_all();
+	flush_dcache_all();
 }
 
 /*
@@ -303,44 +211,63 @@
 {
 	struct flusher_data *data = args;
 	struct vm_area_struct *vma;
+	struct page *page;
 	unsigned long address, pfn, phys;
-	unsigned int alias_mask;
+	int map_coherent = 0;
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd;
+	pte_t *pte;
+	void *vaddr;
 
 	vma = data->vma;
-	address = data->addr1;
+	address = data->addr1 & PAGE_MASK;
 	pfn = data->addr2;
 	phys = pfn << PAGE_SHIFT;
+	page = pfn_to_page(pfn);
 
 	if (cpu_context(smp_processor_id(), vma->vm_mm) == NO_CONTEXT)
 		return;
 
-	alias_mask = boot_cpu_data.dcache.alias_mask;
+	pgd = pgd_offset(vma->vm_mm, address);
+	pud = pud_offset(pgd, address);
+	pmd = pmd_offset(pud, address);
+	pte = pte_offset_kernel(pmd, address);
 
-	/* We only need to flush D-cache when we have alias */
-	if ((address^phys) & alias_mask) {
-		/* Loop 4K of the D-cache */
-		flush_cache_one(
-			CACHE_OC_ADDRESS_ARRAY | (address & alias_mask),
-			phys);
-		/* Loop another 4K of the D-cache */
-		flush_cache_one(
-			CACHE_OC_ADDRESS_ARRAY | (phys & alias_mask),
-			phys);
+	/* If the page isn't present, there is nothing to do here. */
+	if (!(pte_val(*pte) & _PAGE_PRESENT))
+		return;
+
+	if ((vma->vm_mm == current->active_mm))
+		vaddr = NULL;
+	else {
+		/*
+		 * Use kmap_coherent or kmap_atomic to do flushes for
+		 * another ASID than the current one.
+		 */
+		map_coherent = (current_cpu_data.dcache.n_aliases &&
+			!test_bit(PG_dcache_dirty, &page->flags) &&
+			page_mapped(page));
+		if (map_coherent)
+			vaddr = kmap_coherent(page, address);
+		else
+			vaddr = kmap_atomic(page, KM_USER0);
+
+		address = (unsigned long)vaddr;
 	}
 
-	alias_mask = boot_cpu_data.icache.alias_mask;
-	if (vma->vm_flags & VM_EXEC) {
-		/*
-		 * Evict entries from the portion of the cache from which code
-		 * may have been executed at this address (virtual).  There's
-		 * no need to evict from the portion corresponding to the
-		 * physical address as for the D-cache, because we know the
-		 * kernel has never executed the code through its identity
-		 * translation.
-		 */
-		flush_cache_one(
-			CACHE_IC_ADDRESS_ARRAY | (address & alias_mask),
-			phys);
+	if (pages_do_alias(address, phys))
+		flush_cache_one(CACHE_OC_ADDRESS_ARRAY |
+			(address & shm_align_mask), phys);
+
+	if (vma->vm_flags & VM_EXEC)
+		flush_icache_all();
+
+	if (vaddr) {
+		if (map_coherent)
+			kunmap_coherent(vaddr);
+		else
+			kunmap_atomic(vaddr, KM_USER0);
 	}
 }
 
@@ -373,24 +300,10 @@
 	if (boot_cpu_data.dcache.n_aliases == 0)
 		return;
 
-	/*
-	 * Don't bother with the lookup and alias check if we have a
-	 * wide range to cover, just blow away the dcache in its
-	 * entirety instead. -- PFM.
-	 */
-	if (((end - start) >> PAGE_SHIFT) >= MAX_DCACHE_PAGES)
-		flush_dcache_all();
-	else
-		__flush_cache_mm(vma->vm_mm, start, end);
+	flush_dcache_all();
 
-	if (vma->vm_flags & VM_EXEC) {
-		/*
-		 * TODO: Is this required???  Need to look at how I-cache
-		 * coherency is assured when new programs are loaded to see if
-		 * this matters.
-		 */
+	if (vma->vm_flags & VM_EXEC)
 		flush_icache_all();
-	}
 }
 
 /**
@@ -464,245 +377,6 @@
 	} while (--way_count != 0);
 }
 
-/*
- * Break the 1, 2 and 4 way variants of this out into separate functions to
- * avoid nearly all the overhead of having the conditional stuff in the function
- * bodies (+ the 1 and 2 way cases avoid saving any registers too).
- *
- * We want to eliminate unnecessary bus transactions, so this code uses
- * a non-obvious technique.
- *
- * Loop over a cache way sized block of, one cache line at a time. For each
- * line, use movca.a to cause the current cache line contents to be written
- * back, but without reading anything from main memory. However this has the
- * side effect that the cache is now caching that memory location. So follow
- * this with a cache invalidate to mark the cache line invalid. And do all
- * this with interrupts disabled, to avoid the cache line being accidently
- * evicted while it is holding garbage.
- *
- * This also breaks in a number of circumstances:
- * - if there are modifications to the region of memory just above
- *   empty_zero_page (for example because a breakpoint has been placed
- *   there), then these can be lost.
- *
- *   This is because the the memory address which the cache temporarily
- *   caches in the above description is empty_zero_page. So the
- *   movca.l hits the cache (it is assumed that it misses, or at least
- *   isn't dirty), modifies the line and then invalidates it, losing the
- *   required change.
- *
- * - If caches are disabled or configured in write-through mode, then
- *   the movca.l writes garbage directly into memory.
- */
-static void __flush_dcache_segment_writethrough(unsigned long start,
-					        unsigned long extent_per_way)
-{
-	unsigned long addr;
-	int i;
-
-	addr = CACHE_OC_ADDRESS_ARRAY | (start & cpu_data->dcache.entry_mask);
-
-	while (extent_per_way) {
-		for (i = 0; i < cpu_data->dcache.ways; i++)
-			__raw_writel(0, addr + cpu_data->dcache.way_incr * i);
-
-		addr += cpu_data->dcache.linesz;
-		extent_per_way -= cpu_data->dcache.linesz;
-	}
-}
-
-static void __flush_dcache_segment_1way(unsigned long start,
-					unsigned long extent_per_way)
-{
-	unsigned long orig_sr, sr_with_bl;
-	unsigned long base_addr;
-	unsigned long way_incr, linesz, way_size;
-	struct cache_info *dcache;
-	register unsigned long a0, a0e;
-
-	asm volatile("stc sr, %0" : "=r" (orig_sr));
-	sr_with_bl = orig_sr | (1<<28);
-	base_addr = ((unsigned long)&empty_zero_page[0]);
-
-	/*
-	 * The previous code aligned base_addr to 16k, i.e. the way_size of all
-	 * existing SH-4 D-caches.  Whilst I don't see a need to have this
-	 * aligned to any better than the cache line size (which it will be
-	 * anyway by construction), let's align it to at least the way_size of
-	 * any existing or conceivable SH-4 D-cache.  -- RPC
-	 */
-	base_addr = ((base_addr >> 16) << 16);
-	base_addr |= start;
-
-	dcache = &boot_cpu_data.dcache;
-	linesz = dcache->linesz;
-	way_incr = dcache->way_incr;
-	way_size = dcache->way_size;
-
-	a0 = base_addr;
-	a0e = base_addr + extent_per_way;
-	do {
-		asm volatile("ldc %0, sr" : : "r" (sr_with_bl));
-		asm volatile("movca.l r0, @%0\n\t"
-			     "ocbi @%0" : : "r" (a0));
-		a0 += linesz;
-		asm volatile("movca.l r0, @%0\n\t"
-			     "ocbi @%0" : : "r" (a0));
-		a0 += linesz;
-		asm volatile("movca.l r0, @%0\n\t"
-			     "ocbi @%0" : : "r" (a0));
-		a0 += linesz;
-		asm volatile("movca.l r0, @%0\n\t"
-			     "ocbi @%0" : : "r" (a0));
-		asm volatile("ldc %0, sr" : : "r" (orig_sr));
-		a0 += linesz;
-	} while (a0 < a0e);
-}
-
-static void __flush_dcache_segment_2way(unsigned long start,
-					unsigned long extent_per_way)
-{
-	unsigned long orig_sr, sr_with_bl;
-	unsigned long base_addr;
-	unsigned long way_incr, linesz, way_size;
-	struct cache_info *dcache;
-	register unsigned long a0, a1, a0e;
-
-	asm volatile("stc sr, %0" : "=r" (orig_sr));
-	sr_with_bl = orig_sr | (1<<28);
-	base_addr = ((unsigned long)&empty_zero_page[0]);
-
-	/* See comment under 1-way above */
-	base_addr = ((base_addr >> 16) << 16);
-	base_addr |= start;
-
-	dcache = &boot_cpu_data.dcache;
-	linesz = dcache->linesz;
-	way_incr = dcache->way_incr;
-	way_size = dcache->way_size;
-
-	a0 = base_addr;
-	a1 = a0 + way_incr;
-	a0e = base_addr + extent_per_way;
-	do {
-		asm volatile("ldc %0, sr" : : "r" (sr_with_bl));
-		asm volatile("movca.l r0, @%0\n\t"
-			     "movca.l r0, @%1\n\t"
-			     "ocbi @%0\n\t"
-			     "ocbi @%1" : :
-			     "r" (a0), "r" (a1));
-		a0 += linesz;
-		a1 += linesz;
-		asm volatile("movca.l r0, @%0\n\t"
-			     "movca.l r0, @%1\n\t"
-			     "ocbi @%0\n\t"
-			     "ocbi @%1" : :
-			     "r" (a0), "r" (a1));
-		a0 += linesz;
-		a1 += linesz;
-		asm volatile("movca.l r0, @%0\n\t"
-			     "movca.l r0, @%1\n\t"
-			     "ocbi @%0\n\t"
-			     "ocbi @%1" : :
-			     "r" (a0), "r" (a1));
-		a0 += linesz;
-		a1 += linesz;
-		asm volatile("movca.l r0, @%0\n\t"
-			     "movca.l r0, @%1\n\t"
-			     "ocbi @%0\n\t"
-			     "ocbi @%1" : :
-			     "r" (a0), "r" (a1));
-		asm volatile("ldc %0, sr" : : "r" (orig_sr));
-		a0 += linesz;
-		a1 += linesz;
-	} while (a0 < a0e);
-}
-
-static void __flush_dcache_segment_4way(unsigned long start,
-					unsigned long extent_per_way)
-{
-	unsigned long orig_sr, sr_with_bl;
-	unsigned long base_addr;
-	unsigned long way_incr, linesz, way_size;
-	struct cache_info *dcache;
-	register unsigned long a0, a1, a2, a3, a0e;
-
-	asm volatile("stc sr, %0" : "=r" (orig_sr));
-	sr_with_bl = orig_sr | (1<<28);
-	base_addr = ((unsigned long)&empty_zero_page[0]);
-
-	/* See comment under 1-way above */
-	base_addr = ((base_addr >> 16) << 16);
-	base_addr |= start;
-
-	dcache = &boot_cpu_data.dcache;
-	linesz = dcache->linesz;
-	way_incr = dcache->way_incr;
-	way_size = dcache->way_size;
-
-	a0 = base_addr;
-	a1 = a0 + way_incr;
-	a2 = a1 + way_incr;
-	a3 = a2 + way_incr;
-	a0e = base_addr + extent_per_way;
-	do {
-		asm volatile("ldc %0, sr" : : "r" (sr_with_bl));
-		asm volatile("movca.l r0, @%0\n\t"
-			     "movca.l r0, @%1\n\t"
-			     "movca.l r0, @%2\n\t"
-			     "movca.l r0, @%3\n\t"
-			     "ocbi @%0\n\t"
-			     "ocbi @%1\n\t"
-			     "ocbi @%2\n\t"
-			     "ocbi @%3\n\t" : :
-			     "r" (a0), "r" (a1), "r" (a2), "r" (a3));
-		a0 += linesz;
-		a1 += linesz;
-		a2 += linesz;
-		a3 += linesz;
-		asm volatile("movca.l r0, @%0\n\t"
-			     "movca.l r0, @%1\n\t"
-			     "movca.l r0, @%2\n\t"
-			     "movca.l r0, @%3\n\t"
-			     "ocbi @%0\n\t"
-			     "ocbi @%1\n\t"
-			     "ocbi @%2\n\t"
-			     "ocbi @%3\n\t" : :
-			     "r" (a0), "r" (a1), "r" (a2), "r" (a3));
-		a0 += linesz;
-		a1 += linesz;
-		a2 += linesz;
-		a3 += linesz;
-		asm volatile("movca.l r0, @%0\n\t"
-			     "movca.l r0, @%1\n\t"
-			     "movca.l r0, @%2\n\t"
-			     "movca.l r0, @%3\n\t"
-			     "ocbi @%0\n\t"
-			     "ocbi @%1\n\t"
-			     "ocbi @%2\n\t"
-			     "ocbi @%3\n\t" : :
-			     "r" (a0), "r" (a1), "r" (a2), "r" (a3));
-		a0 += linesz;
-		a1 += linesz;
-		a2 += linesz;
-		a3 += linesz;
-		asm volatile("movca.l r0, @%0\n\t"
-			     "movca.l r0, @%1\n\t"
-			     "movca.l r0, @%2\n\t"
-			     "movca.l r0, @%3\n\t"
-			     "ocbi @%0\n\t"
-			     "ocbi @%1\n\t"
-			     "ocbi @%2\n\t"
-			     "ocbi @%3\n\t" : :
-			     "r" (a0), "r" (a1), "r" (a2), "r" (a3));
-		asm volatile("ldc %0, sr" : : "r" (orig_sr));
-		a0 += linesz;
-		a1 += linesz;
-		a2 += linesz;
-		a3 += linesz;
-	} while (a0 < a0e);
-}
-
 extern void __weak sh4__flush_region_init(void);
 
 /*
@@ -710,32 +384,11 @@
  */
 void __init sh4_cache_init(void)
 {
-	unsigned int wt_enabled = !!(__raw_readl(CCR) & CCR_CACHE_WT);
-
 	printk("PVR=%08x CVR=%08x PRR=%08x\n",
 		ctrl_inl(CCN_PVR),
 		ctrl_inl(CCN_CVR),
 		ctrl_inl(CCN_PRR));
 
-	if (wt_enabled)
-		__flush_dcache_segment_fn = __flush_dcache_segment_writethrough;
-	else {
-		switch (boot_cpu_data.dcache.ways) {
-		case 1:
-			__flush_dcache_segment_fn = __flush_dcache_segment_1way;
-			break;
-		case 2:
-			__flush_dcache_segment_fn = __flush_dcache_segment_2way;
-			break;
-		case 4:
-			__flush_dcache_segment_fn = __flush_dcache_segment_4way;
-			break;
-		default:
-			panic("unknown number of cache ways\n");
-			break;
-		}
-	}
-
 	local_flush_icache_range	= sh4_flush_icache_range;
 	local_flush_dcache_page		= sh4_flush_dcache_page;
 	local_flush_cache_all		= sh4_flush_cache_all;
diff --git a/arch/sh/mm/cache-sh5.c b/arch/sh/mm/cache-sh5.c
index 467ff8e..eb4cc4e 100644
--- a/arch/sh/mm/cache-sh5.c
+++ b/arch/sh/mm/cache-sh5.c
@@ -563,7 +563,7 @@
 
 static void sh5_flush_dcache_page(void *page)
 {
-	sh64_dcache_purge_phy_page(page_to_phys(page));
+	sh64_dcache_purge_phy_page(page_to_phys((struct page *)page));
 	wmb();
 }
 
diff --git a/arch/sh/mm/cache-sh7705.c b/arch/sh/mm/cache-sh7705.c
index 2601935..f527fb7 100644
--- a/arch/sh/mm/cache-sh7705.c
+++ b/arch/sh/mm/cache-sh7705.c
@@ -141,7 +141,7 @@
 	if (mapping && !mapping_mapped(mapping))
 		set_bit(PG_dcache_dirty, &page->flags);
 	else
-		__flush_dcache_page(PHYSADDR(page_address(page)));
+		__flush_dcache_page(__pa(page_address(page)));
 }
 
 static void __uses_jump_to_uncached sh7705_flush_cache_all(void *args)
diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c
index a2dc7f9..e9415d3 100644
--- a/arch/sh/mm/cache.c
+++ b/arch/sh/mm/cache.c
@@ -27,8 +27,11 @@
 void (*local_flush_cache_sigtramp)(void *args) = cache_noop;
 
 void (*__flush_wback_region)(void *start, int size);
+EXPORT_SYMBOL(__flush_wback_region);
 void (*__flush_purge_region)(void *start, int size);
+EXPORT_SYMBOL(__flush_purge_region);
 void (*__flush_invalidate_region)(void *start, int size);
+EXPORT_SYMBOL(__flush_invalidate_region);
 
 static inline void noop__flush_region(void *start, int size)
 {
@@ -161,14 +164,21 @@
 {
 	cacheop_on_each_cpu(local_flush_cache_all, NULL, 1);
 }
+EXPORT_SYMBOL(flush_cache_all);
 
 void flush_cache_mm(struct mm_struct *mm)
 {
+	if (boot_cpu_data.dcache.n_aliases == 0)
+		return;
+
 	cacheop_on_each_cpu(local_flush_cache_mm, mm, 1);
 }
 
 void flush_cache_dup_mm(struct mm_struct *mm)
 {
+	if (boot_cpu_data.dcache.n_aliases == 0)
+		return;
+
 	cacheop_on_each_cpu(local_flush_cache_dup_mm, mm, 1);
 }
 
@@ -195,11 +205,13 @@
 
 	cacheop_on_each_cpu(local_flush_cache_range, (void *)&data, 1);
 }
+EXPORT_SYMBOL(flush_cache_range);
 
 void flush_dcache_page(struct page *page)
 {
 	cacheop_on_each_cpu(local_flush_dcache_page, page, 1);
 }
+EXPORT_SYMBOL(flush_dcache_page);
 
 void flush_icache_range(unsigned long start, unsigned long end)
 {
@@ -265,7 +277,11 @@
 
 void __init cpu_cache_init(void)
 {
-	unsigned int cache_disabled = !(__raw_readl(CCR) & CCR_CACHE_ENABLE);
+	unsigned int cache_disabled = 0;
+
+#ifdef CCR
+	cache_disabled = !(__raw_readl(CCR) & CCR_CACHE_ENABLE);
+#endif
 
 	compute_alias(&boot_cpu_data.icache);
 	compute_alias(&boot_cpu_data.dcache);
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
index e098ec1..902967e 100644
--- a/arch/sh/mm/consistent.c
+++ b/arch/sh/mm/consistent.c
@@ -15,11 +15,15 @@
 #include <linux/dma-mapping.h>
 #include <linux/dma-debug.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <asm/cacheflush.h>
 #include <asm/addrspace.h>
 
 #define PREALLOC_DMA_DEBUG_ENTRIES	4096
 
+struct dma_map_ops *dma_ops;
+EXPORT_SYMBOL(dma_ops);
+
 static int __init dma_init(void)
 {
 	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
@@ -27,15 +31,12 @@
 }
 fs_initcall(dma_init);
 
-void *dma_alloc_coherent(struct device *dev, size_t size,
-			   dma_addr_t *dma_handle, gfp_t gfp)
+void *dma_generic_alloc_coherent(struct device *dev, size_t size,
+				 dma_addr_t *dma_handle, gfp_t gfp)
 {
 	void *ret, *ret_nocache;
 	int order = get_order(size);
 
-	if (dma_alloc_from_coherent(dev, size, dma_handle, &ret))
-		return ret;
-
 	ret = (void *)__get_free_pages(gfp, order);
 	if (!ret)
 		return NULL;
@@ -57,35 +58,26 @@
 
 	*dma_handle = virt_to_phys(ret);
 
-	debug_dma_alloc_coherent(dev, size, *dma_handle, ret_nocache);
-
 	return ret_nocache;
 }
-EXPORT_SYMBOL(dma_alloc_coherent);
 
-void dma_free_coherent(struct device *dev, size_t size,
-			 void *vaddr, dma_addr_t dma_handle)
+void dma_generic_free_coherent(struct device *dev, size_t size,
+			       void *vaddr, dma_addr_t dma_handle)
 {
 	int order = get_order(size);
 	unsigned long pfn = dma_handle >> PAGE_SHIFT;
 	int k;
 
-	WARN_ON(irqs_disabled());	/* for portability */
-
-	if (dma_release_from_coherent(dev, order, vaddr))
-		return;
-
-	debug_dma_free_coherent(dev, size, vaddr, dma_handle);
 	for (k = 0; k < (1 << order); k++)
 		__free_pages(pfn_to_page(pfn + k), 0);
+
 	iounmap(vaddr);
 }
-EXPORT_SYMBOL(dma_free_coherent);
 
 void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 		    enum dma_data_direction direction)
 {
-#ifdef CONFIG_CPU_SH5
+#if defined(CONFIG_CPU_SH5) || defined(CONFIG_PMB)
 	void *p1addr = vaddr;
 #else
 	void *p1addr = (void*) P1SEGADDR((unsigned long)vaddr);
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index 8173e38..432acd0 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -15,6 +15,7 @@
 #include <linux/pagemap.h>
 #include <linux/percpu.h>
 #include <linux/io.h>
+#include <linux/dma-mapping.h>
 #include <asm/mmu_context.h>
 #include <asm/tlb.h>
 #include <asm/cacheflush.h>
@@ -186,11 +187,21 @@
 	set_fixmap_nocache(FIX_UNCACHED, __pa(&__uncached_start));
 }
 
+/*
+ * Early initialization for any I/O MMUs we might have.
+ */
+static void __init iommu_init(void)
+{
+	no_iommu_init();
+}
+
 void __init mem_init(void)
 {
 	int codesize, datasize, initsize;
 	int nid;
 
+	iommu_init();
+
 	num_physpages = 0;
 	high_memory = NULL;
 
@@ -323,4 +334,12 @@
 }
 EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
 #endif
+
 #endif /* CONFIG_MEMORY_HOTPLUG */
+
+#ifdef CONFIG_PMB
+int __in_29bit_mode(void)
+{
+	return !(ctrl_inl(PMB_PASCR) & PASCR_SE);
+}
+#endif /* CONFIG_PMB */
diff --git a/arch/sh/mm/kmap.c b/arch/sh/mm/kmap.c
index 16e01b5..15d74ea42 100644
--- a/arch/sh/mm/kmap.c
+++ b/arch/sh/mm/kmap.c
@@ -39,7 +39,9 @@
 	pagefault_disable();
 
 	idx = FIX_CMAP_END -
-		((addr & current_cpu_data.dcache.alias_mask) >> PAGE_SHIFT);
+		(((addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1)) +
+		 (FIX_N_COLOURS * smp_processor_id()));
+
 	vaddr = __fix_to_virt(idx);
 
 	BUG_ON(!pte_none(*(kmap_coherent_pte - idx)));
diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c
index d2984fa..afeb710 100644
--- a/arch/sh/mm/mmap.c
+++ b/arch/sh/mm/mmap.c
@@ -54,7 +54,8 @@
 		/* We do not accept a shared mapping if it would violate
 		 * cache aliasing constraints.
 		 */
-		if ((flags & MAP_SHARED) && (addr & shm_align_mask))
+		if ((flags & MAP_SHARED) &&
+		    ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask))
 			return -EINVAL;
 		return addr;
 	}
diff --git a/arch/sh/mm/numa.c b/arch/sh/mm/numa.c
index 9b784fd..6c52444 100644
--- a/arch/sh/mm/numa.c
+++ b/arch/sh/mm/numa.c
@@ -60,7 +60,7 @@
 	unsigned long bootmem_paddr;
 
 	/* Don't allow bogus node assignment */
-	BUG_ON(nid > MAX_NUMNODES || nid == 0);
+	BUG_ON(nid > MAX_NUMNODES || nid <= 0);
 
 	start_pfn = start >> PAGE_SHIFT;
 	end_pfn = end >> PAGE_SHIFT;
diff --git a/arch/sh/mm/pmb-fixed.c b/arch/sh/mm/pmb-fixed.c
deleted file mode 100644
index 43c8eac..0000000
--- a/arch/sh/mm/pmb-fixed.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * arch/sh/mm/fixed_pmb.c
- *
- * Copyright (C) 2009  Renesas Solutions Corp.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/io.h>
-#include <asm/mmu.h>
-#include <asm/mmu_context.h>
-
-static int __uses_jump_to_uncached fixed_pmb_init(void)
-{
-	int i;
-	unsigned long addr, data;
-
-	jump_to_uncached();
-
-	for (i = 0; i < PMB_ENTRY_MAX; i++) {
-		addr = PMB_DATA + (i << PMB_E_SHIFT);
-		data = ctrl_inl(addr);
-		if (!(data & PMB_V))
-			continue;
-
-		if (data & PMB_C) {
-#if defined(CONFIG_CACHE_WRITETHROUGH)
-			data |= PMB_WT;
-#elif defined(CONFIG_CACHE_WRITEBACK)
-			data &= ~PMB_WT;
-#else
-			data &= ~(PMB_C | PMB_WT);
-#endif
-		}
-		ctrl_outl(data, addr);
-	}
-
-	back_to_cached();
-
-	return 0;
-}
-arch_initcall(fixed_pmb_init);
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c
index aade311..280f6a1 100644
--- a/arch/sh/mm/pmb.c
+++ b/arch/sh/mm/pmb.c
@@ -35,29 +35,9 @@
 
 static void __pmb_unmap(struct pmb_entry *);
 
-static struct kmem_cache *pmb_cache;
+static struct pmb_entry pmb_entry_list[NR_PMB_ENTRIES];
 static unsigned long pmb_map;
 
-static struct pmb_entry pmb_init_map[] = {
-	/* vpn         ppn         flags (ub/sz/c/wt) */
-
-	/* P1 Section Mappings */
-	{ 0x80000000, 0x00000000, PMB_SZ_64M  | PMB_C, },
-	{ 0x84000000, 0x04000000, PMB_SZ_64M  | PMB_C, },
-	{ 0x88000000, 0x08000000, PMB_SZ_128M | PMB_C, },
-	{ 0x90000000, 0x10000000, PMB_SZ_64M  | PMB_C, },
-	{ 0x94000000, 0x14000000, PMB_SZ_64M  | PMB_C, },
-	{ 0x98000000, 0x18000000, PMB_SZ_64M  | PMB_C, },
-
-	/* P2 Section Mappings */
-	{ 0xa0000000, 0x00000000, PMB_UB | PMB_SZ_64M  | PMB_WT, },
-	{ 0xa4000000, 0x04000000, PMB_UB | PMB_SZ_64M  | PMB_WT, },
-	{ 0xa8000000, 0x08000000, PMB_UB | PMB_SZ_128M | PMB_WT, },
-	{ 0xb0000000, 0x10000000, PMB_UB | PMB_SZ_64M  | PMB_WT, },
-	{ 0xb4000000, 0x14000000, PMB_UB | PMB_SZ_64M  | PMB_WT, },
-	{ 0xb8000000, 0x18000000, PMB_UB | PMB_SZ_64M  | PMB_WT, },
-};
-
 static inline unsigned long mk_pmb_entry(unsigned int entry)
 {
 	return (entry & PMB_E_MASK) << PMB_E_SHIFT;
@@ -73,81 +53,68 @@
 	return mk_pmb_entry(entry) | PMB_DATA;
 }
 
-static DEFINE_SPINLOCK(pmb_list_lock);
-static struct pmb_entry *pmb_list;
-
-static inline void pmb_list_add(struct pmb_entry *pmbe)
+static int pmb_alloc_entry(void)
 {
-	struct pmb_entry **p, *tmp;
+	unsigned int pos;
 
-	p = &pmb_list;
-	while ((tmp = *p) != NULL)
-		p = &tmp->next;
+repeat:
+	pos = find_first_zero_bit(&pmb_map, NR_PMB_ENTRIES);
 
-	pmbe->next = tmp;
-	*p = pmbe;
+	if (unlikely(pos > NR_PMB_ENTRIES))
+		return -ENOSPC;
+
+	if (test_and_set_bit(pos, &pmb_map))
+		goto repeat;
+
+	return pos;
 }
 
-static inline void pmb_list_del(struct pmb_entry *pmbe)
-{
-	struct pmb_entry **p, *tmp;
-
-	for (p = &pmb_list; (tmp = *p); p = &tmp->next)
-		if (tmp == pmbe) {
-			*p = tmp->next;
-			return;
-		}
-}
-
-struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn,
-			    unsigned long flags)
+static struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn,
+				   unsigned long flags, int entry)
 {
 	struct pmb_entry *pmbe;
+	int pos;
 
-	pmbe = kmem_cache_alloc(pmb_cache, GFP_KERNEL);
+	if (entry == PMB_NO_ENTRY) {
+		pos = pmb_alloc_entry();
+		if (pos < 0)
+			return ERR_PTR(pos);
+	} else {
+		if (test_bit(entry, &pmb_map))
+			return ERR_PTR(-ENOSPC);
+		pos = entry;
+	}
+
+	pmbe = &pmb_entry_list[pos];
 	if (!pmbe)
 		return ERR_PTR(-ENOMEM);
 
 	pmbe->vpn	= vpn;
 	pmbe->ppn	= ppn;
 	pmbe->flags	= flags;
-
-	spin_lock_irq(&pmb_list_lock);
-	pmb_list_add(pmbe);
-	spin_unlock_irq(&pmb_list_lock);
+	pmbe->entry	= pos;
 
 	return pmbe;
 }
 
-void pmb_free(struct pmb_entry *pmbe)
+static void pmb_free(struct pmb_entry *pmbe)
 {
-	spin_lock_irq(&pmb_list_lock);
-	pmb_list_del(pmbe);
-	spin_unlock_irq(&pmb_list_lock);
+	int pos = pmbe->entry;
 
-	kmem_cache_free(pmb_cache, pmbe);
+	pmbe->vpn	= 0;
+	pmbe->ppn	= 0;
+	pmbe->flags	= 0;
+	pmbe->entry	= 0;
+
+	clear_bit(pos, &pmb_map);
 }
 
 /*
  * Must be in P2 for __set_pmb_entry()
  */
-int __set_pmb_entry(unsigned long vpn, unsigned long ppn,
-		    unsigned long flags, int *entry)
+static void __set_pmb_entry(unsigned long vpn, unsigned long ppn,
+			    unsigned long flags, int pos)
 {
-	unsigned int pos = *entry;
-
-	if (unlikely(pos == PMB_NO_ENTRY))
-		pos = find_first_zero_bit(&pmb_map, NR_PMB_ENTRIES);
-
-repeat:
-	if (unlikely(pos > NR_PMB_ENTRIES))
-		return -ENOSPC;
-
-	if (test_and_set_bit(pos, &pmb_map)) {
-		pos = find_first_zero_bit(&pmb_map, NR_PMB_ENTRIES);
-		goto repeat;
-	}
-
 	ctrl_outl(vpn | PMB_V, mk_pmb_addr(pos));
 
 #ifdef CONFIG_CACHE_WRITETHROUGH
@@ -161,35 +128,21 @@
 #endif
 
 	ctrl_outl(ppn | flags | PMB_V, mk_pmb_data(pos));
-
-	*entry = pos;
-
-	return 0;
 }
 
-int __uses_jump_to_uncached set_pmb_entry(struct pmb_entry *pmbe)
+static void __uses_jump_to_uncached set_pmb_entry(struct pmb_entry *pmbe)
 {
-	int ret;
-
 	jump_to_uncached();
-	ret = __set_pmb_entry(pmbe->vpn, pmbe->ppn, pmbe->flags, &pmbe->entry);
+	__set_pmb_entry(pmbe->vpn, pmbe->ppn, pmbe->flags, pmbe->entry);
 	back_to_cached();
-
-	return ret;
 }
 
-void __uses_jump_to_uncached clear_pmb_entry(struct pmb_entry *pmbe)
+static void __uses_jump_to_uncached clear_pmb_entry(struct pmb_entry *pmbe)
 {
 	unsigned int entry = pmbe->entry;
 	unsigned long addr;
 
-	/*
-	 * Don't allow clearing of wired init entries, P1 or P2 access
-	 * without a corresponding mapping in the PMB will lead to reset
-	 * by the TLB.
-	 */
-	if (unlikely(entry < ARRAY_SIZE(pmb_init_map) ||
-		     entry >= NR_PMB_ENTRIES))
+	if (unlikely(entry >= NR_PMB_ENTRIES))
 		return;
 
 	jump_to_uncached();
@@ -202,8 +155,6 @@
 	ctrl_outl(ctrl_inl(addr) & ~PMB_V, addr);
 
 	back_to_cached();
-
-	clear_bit(entry, &pmb_map);
 }
 
 
@@ -239,23 +190,17 @@
 
 again:
 	for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) {
-		int ret;
-
 		if (size < pmb_sizes[i].size)
 			continue;
 
-		pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag);
+		pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag,
+				 PMB_NO_ENTRY);
 		if (IS_ERR(pmbe)) {
 			err = PTR_ERR(pmbe);
 			goto out;
 		}
 
-		ret = set_pmb_entry(pmbe);
-		if (ret != 0) {
-			pmb_free(pmbe);
-			err = -EBUSY;
-			goto out;
-		}
+		set_pmb_entry(pmbe);
 
 		phys	+= pmb_sizes[i].size;
 		vaddr	+= pmb_sizes[i].size;
@@ -292,11 +237,16 @@
 
 void pmb_unmap(unsigned long addr)
 {
-	struct pmb_entry **p, *pmbe;
+	struct pmb_entry *pmbe = NULL;
+	int i;
 
-	for (p = &pmb_list; (pmbe = *p); p = &pmbe->next)
-		if (pmbe->vpn == addr)
-			break;
+	for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) {
+		if (test_bit(i, &pmb_map)) {
+			pmbe = &pmb_entry_list[i];
+			if (pmbe->vpn == addr)
+				break;
+		}
+	}
 
 	if (unlikely(!pmbe))
 		return;
@@ -306,13 +256,22 @@
 
 static void __pmb_unmap(struct pmb_entry *pmbe)
 {
-	WARN_ON(!test_bit(pmbe->entry, &pmb_map));
+	BUG_ON(!test_bit(pmbe->entry, &pmb_map));
 
 	do {
 		struct pmb_entry *pmblink = pmbe;
 
-		if (pmbe->entry != PMB_NO_ENTRY)
-			clear_pmb_entry(pmbe);
+		/*
+		 * We may be called before this pmb_entry has been
+		 * entered into the PMB table via set_pmb_entry(), but
+		 * that's OK because we've allocated a unique slot for
+		 * this entry in pmb_alloc() (even if we haven't filled
+		 * it yet).
+		 *
+		 * Therefore, calling clear_pmb_entry() is safe as no
+		 * other mapping can be using that slot.
+		 */
+		clear_pmb_entry(pmbe);
 
 		pmbe = pmblink->link;
 
@@ -320,42 +279,34 @@
 	} while (pmbe);
 }
 
-static void pmb_cache_ctor(void *pmb)
+#ifdef CONFIG_PMB
+int __uses_jump_to_uncached pmb_init(void)
 {
-	struct pmb_entry *pmbe = pmb;
-
-	memset(pmb, 0, sizeof(struct pmb_entry));
-
-	pmbe->entry = PMB_NO_ENTRY;
-}
-
-static int __uses_jump_to_uncached pmb_init(void)
-{
-	unsigned int nr_entries = ARRAY_SIZE(pmb_init_map);
-	unsigned int entry, i;
-
-	BUG_ON(unlikely(nr_entries >= NR_PMB_ENTRIES));
-
-	pmb_cache = kmem_cache_create("pmb", sizeof(struct pmb_entry), 0,
-				      SLAB_PANIC, pmb_cache_ctor);
+	unsigned int i;
+	long size, ret;
 
 	jump_to_uncached();
 
 	/*
-	 * Ordering is important, P2 must be mapped in the PMB before we
-	 * can set PMB.SE, and P1 must be mapped before we jump back to
-	 * P1 space.
+	 * Insert PMB entries for the P1 and P2 areas so that, after
+	 * we've switched the MMU to 32-bit mode, the semantics of P1
+	 * and P2 are the same as in 29-bit mode, e.g.
+	 *
+	 *	P1 - provides a cached window onto physical memory
+	 *	P2 - provides an uncached window onto physical memory
 	 */
-	for (entry = 0; entry < nr_entries; entry++) {
-		struct pmb_entry *pmbe = pmb_init_map + entry;
+	size = __MEMORY_START + __MEMORY_SIZE;
 
-		__set_pmb_entry(pmbe->vpn, pmbe->ppn, pmbe->flags, &entry);
-	}
+	ret = pmb_remap(P1SEG, 0x00000000, size, PMB_C);
+	BUG_ON(ret != size);
+
+	ret = pmb_remap(P2SEG, 0x00000000, size, PMB_WT | PMB_UB);
+	BUG_ON(ret != size);
 
 	ctrl_outl(0, PMB_IRMCR);
 
 	/* PMB.SE and UB[7] */
-	ctrl_outl((1 << 31) | (1 << 7), PMB_PASCR);
+	ctrl_outl(PASCR_SE | (1 << 7), PMB_PASCR);
 
 	/* Flush out the TLB */
 	i =  ctrl_inl(MMUCR);
@@ -366,7 +317,53 @@
 
 	return 0;
 }
-arch_initcall(pmb_init);
+#else
+int __uses_jump_to_uncached pmb_init(void)
+{
+	int i;
+	unsigned long addr, data;
+
+	jump_to_uncached();
+
+	for (i = 0; i < PMB_ENTRY_MAX; i++) {
+		struct pmb_entry *pmbe;
+		unsigned long vpn, ppn, flags;
+
+		addr = PMB_DATA + (i << PMB_E_SHIFT);
+		data = ctrl_inl(addr);
+		if (!(data & PMB_V))
+			continue;
+
+		if (data & PMB_C) {
+#if defined(CONFIG_CACHE_WRITETHROUGH)
+			data |= PMB_WT;
+#elif defined(CONFIG_CACHE_WRITEBACK)
+			data &= ~PMB_WT;
+#else
+			data &= ~(PMB_C | PMB_WT);
+#endif
+		}
+		ctrl_outl(data, addr);
+
+		ppn = data & PMB_PFN_MASK;
+
+		flags = data & (PMB_C | PMB_WT | PMB_UB);
+		flags |= data & PMB_SZ_MASK;
+
+		addr = PMB_ADDR + (i << PMB_E_SHIFT);
+		data = ctrl_inl(addr);
+
+		vpn = data & PMB_PFN_MASK;
+
+		pmbe = pmb_alloc(vpn, ppn, flags, i);
+		WARN_ON(IS_ERR(pmbe));
+	}
+
+	back_to_cached();
+
+	return 0;
+}
+#endif /* CONFIG_PMB */
 
 static int pmb_seq_show(struct seq_file *file, void *iter)
 {
@@ -434,15 +431,18 @@
 static int pmb_sysdev_suspend(struct sys_device *dev, pm_message_t state)
 {
 	static pm_message_t prev_state;
+	int i;
 
 	/* Restore the PMB after a resume from hibernation */
 	if (state.event == PM_EVENT_ON &&
 	    prev_state.event == PM_EVENT_FREEZE) {
 		struct pmb_entry *pmbe;
-		spin_lock_irq(&pmb_list_lock);
-		for (pmbe = pmb_list; pmbe; pmbe = pmbe->next)
-			set_pmb_entry(pmbe);
-		spin_unlock_irq(&pmb_list_lock);
+		for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) {
+			if (test_bit(i, &pmb_map)) {
+				pmbe = &pmb_entry_list[i];
+				set_pmb_entry(pmbe);
+			}
+		}
 	}
 	prev_state = state;
 	return 0;
diff --git a/arch/sh/oprofile/Makefile b/arch/sh/oprofile/Makefile
index 8e6eec9..4886c5c 100644
--- a/arch/sh/oprofile/Makefile
+++ b/arch/sh/oprofile/Makefile
@@ -7,7 +7,3 @@
 		timer_int.o )
 
 oprofile-y	:= $(DRIVER_OBJS) common.o backtrace.o
-
-oprofile-$(CONFIG_CPU_SUBTYPE_SH7750S)	+= op_model_sh7750.o
-oprofile-$(CONFIG_CPU_SUBTYPE_SH7750)	+= op_model_sh7750.o
-oprofile-$(CONFIG_CPU_SUBTYPE_SH7091)	+= op_model_sh7750.o
diff --git a/arch/sh/oprofile/common.c b/arch/sh/oprofile/common.c
index 44f4e31..ac60493 100644
--- a/arch/sh/oprofile/common.c
+++ b/arch/sh/oprofile/common.c
@@ -20,9 +20,6 @@
 #include <asm/processor.h>
 #include "op_impl.h"
 
-extern struct op_sh_model op_model_sh7750_ops __weak;
-extern struct op_sh_model op_model_sh4a_ops __weak;
-
 static struct op_sh_model *model;
 
 static struct op_counter_config ctr[20];
@@ -94,33 +91,14 @@
 	 */
 	ops->backtrace = sh_backtrace;
 
-	switch (current_cpu_data.type) {
-	/* SH-4 types */
-	case CPU_SH7750:
-	case CPU_SH7750S:
-		lmodel = &op_model_sh7750_ops;
-		break;
-
-        /* SH-4A types */
-	case CPU_SH7763:
-	case CPU_SH7770:
-	case CPU_SH7780:
-	case CPU_SH7781:
-	case CPU_SH7785:
-	case CPU_SH7786:
-	case CPU_SH7723:
-	case CPU_SH7724:
-	case CPU_SHX3:
-		lmodel = &op_model_sh4a_ops;
-		break;
-
-	/* SH4AL-DSP types */
-	case CPU_SH7343:
-	case CPU_SH7722:
-	case CPU_SH7366:
-		lmodel = &op_model_sh4a_ops;
-		break;
-	}
+	/*
+	 * XXX
+	 *
+	 * All of the SH7750/SH-4A counters have been converted to perf,
+	 * this infrastructure hook is left for other users until they've
+	 * had a chance to convert over, at which point all of this
+	 * will be deleted.
+	 */
 
 	if (!lmodel)
 		return -ENODEV;
diff --git a/arch/sh/oprofile/op_impl.h b/arch/sh/oprofile/op_impl.h
index 4d50997..1244479 100644
--- a/arch/sh/oprofile/op_impl.h
+++ b/arch/sh/oprofile/op_impl.h
@@ -6,7 +6,7 @@
 	unsigned long enabled;
 	unsigned long event;
 
-	unsigned long long count;
+	unsigned long count;
 
 	/* Dummy values for userspace tool compliance */
 	unsigned long kernel;
diff --git a/arch/sh/oprofile/op_model_sh7750.c b/arch/sh/oprofile/op_model_sh7750.c
deleted file mode 100644
index c892c7c..0000000
--- a/arch/sh/oprofile/op_model_sh7750.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * arch/sh/oprofile/op_model_sh7750.c
- *
- * OProfile support for SH7750/SH7750S Performance Counters
- *
- * Copyright (C) 2003 - 2008  Paul Mundt
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-#include <linux/kernel.h>
-#include <linux/oprofile.h>
-#include <linux/profile.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/fs.h>
-#include "op_impl.h"
-
-#define PM_CR_BASE	0xff000084	/* 16-bit */
-#define PM_CTR_BASE	0xff100004	/* 32-bit */
-
-#define PMCR(n)		(PM_CR_BASE + ((n) * 0x04))
-#define PMCTRH(n)	(PM_CTR_BASE + 0x00 + ((n) * 0x08))
-#define PMCTRL(n)	(PM_CTR_BASE + 0x04 + ((n) * 0x08))
-
-#define PMCR_PMM_MASK	0x0000003f
-
-#define PMCR_CLKF	0x00000100
-#define PMCR_PMCLR	0x00002000
-#define PMCR_PMST	0x00004000
-#define PMCR_PMEN	0x00008000
-
-struct op_sh_model op_model_sh7750_ops;
-
-#define NR_CNTRS	2
-
-static struct sh7750_ppc_register_config {
-	unsigned int ctrl;
-	unsigned long cnt_hi;
-	unsigned long cnt_lo;
-} regcache[NR_CNTRS];
-
-/*
- * There are a number of events supported by each counter (33 in total).
- * Since we have 2 counters, each counter will take the event code as it
- * corresponds to the PMCR PMM setting. Each counter can be configured
- * independently.
- *
- *	Event Code	Description
- *	----------	-----------
- *
- *	0x01		Operand read access
- *	0x02		Operand write access
- *	0x03		UTLB miss
- *	0x04		Operand cache read miss
- *	0x05		Operand cache write miss
- *	0x06		Instruction fetch (w/ cache)
- *	0x07		Instruction TLB miss
- *	0x08		Instruction cache miss
- *	0x09		All operand accesses
- *	0x0a		All instruction accesses
- *	0x0b		OC RAM operand access
- *	0x0d		On-chip I/O space access
- *	0x0e		Operand access (r/w)
- *	0x0f		Operand cache miss (r/w)
- *	0x10		Branch instruction
- *	0x11		Branch taken
- *	0x12		BSR/BSRF/JSR
- *	0x13		Instruction execution
- *	0x14		Instruction execution in parallel
- *	0x15		FPU Instruction execution
- *	0x16		Interrupt
- *	0x17		NMI
- *	0x18		trapa instruction execution
- *	0x19		UBCA match
- *	0x1a		UBCB match
- *	0x21		Instruction cache fill
- *	0x22		Operand cache fill
- *	0x23		Elapsed time
- *	0x24		Pipeline freeze by I-cache miss
- *	0x25		Pipeline freeze by D-cache miss
- *	0x27		Pipeline freeze by branch instruction
- *	0x28		Pipeline freeze by CPU register
- *	0x29		Pipeline freeze by FPU
- *
- * Unfortunately we don't have a native exception or interrupt for counter
- * overflow (although since these counters can run for 16.3 days without
- * overflowing, it's not really necessary).
- *
- * OProfile on the other hand likes to have samples taken periodically, so
- * for now we just piggyback the timer interrupt to get the expected
- * behavior.
- */
-
-static int sh7750_timer_notify(struct pt_regs *regs)
-{
-	oprofile_add_sample(regs, 0);
-	return 0;
-}
-
-static u64 sh7750_read_counter(int counter)
-{
-	return (u64)((u64)(__raw_readl(PMCTRH(counter)) & 0xffff) << 32) |
-			   __raw_readl(PMCTRL(counter));
-}
-
-/*
- * Files will be in a path like:
- *
- *  /<oprofilefs mount point>/<counter number>/<file>
- *
- * So when dealing with <file>, we look to the parent dentry for the counter
- * number.
- */
-static inline int to_counter(struct file *file)
-{
-	const unsigned char *name = file->f_path.dentry->d_parent->d_name.name;
-
-	return (int)simple_strtol(name, NULL, 10);
-}
-
-/*
- * XXX: We have 48-bit counters, so we're probably going to want something
- * more along the lines of oprofilefs_ullong_to_user().. Truncating to
- * unsigned long works fine for now though, as long as we don't attempt to
- * profile for too horribly long.
- */
-static ssize_t sh7750_read_count(struct file *file, char __user *buf,
-				 size_t count, loff_t *ppos)
-{
-	int counter = to_counter(file);
-	u64 val = sh7750_read_counter(counter);
-
-	return oprofilefs_ulong_to_user((unsigned long)val, buf, count, ppos);
-}
-
-static ssize_t sh7750_write_count(struct file *file, const char __user *buf,
-				  size_t count, loff_t *ppos)
-{
-	int counter = to_counter(file);
-	unsigned long val;
-
-	if (oprofilefs_ulong_from_user(&val, buf, count))
-		return -EFAULT;
-
-	/*
-	 * Any write will clear the counter, although only 0 should be
-	 * written for this purpose, as we do not support setting the
-	 * counter to an arbitrary value.
-	 */
-	WARN_ON(val != 0);
-
-	__raw_writew(__raw_readw(PMCR(counter)) | PMCR_PMCLR, PMCR(counter));
-
-	return count;
-}
-
-static const struct file_operations count_fops = {
-	.read		= sh7750_read_count,
-	.write		= sh7750_write_count,
-};
-
-static int sh7750_ppc_create_files(struct super_block *sb, struct dentry *dir)
-{
-	return oprofilefs_create_file(sb, dir, "count", &count_fops);
-}
-
-static void sh7750_ppc_reg_setup(struct op_counter_config *ctr)
-{
-	unsigned int counters = op_model_sh7750_ops.num_counters;
-	int i;
-
-	for (i = 0; i < counters; i++) {
-		regcache[i].ctrl	= 0;
-		regcache[i].cnt_hi	= 0;
-		regcache[i].cnt_lo	= 0;
-
-		if (!ctr[i].enabled)
-			continue;
-
-		regcache[i].ctrl |= ctr[i].event | PMCR_PMEN | PMCR_PMST;
-		regcache[i].cnt_hi = (unsigned long)((ctr->count >> 32) & 0xffff);
-		regcache[i].cnt_lo = (unsigned long)(ctr->count & 0xffffffff);
-	}
-}
-
-static void sh7750_ppc_cpu_setup(void *args)
-{
-	unsigned int counters = op_model_sh7750_ops.num_counters;
-	int i;
-
-	for (i = 0; i < counters; i++) {
-		__raw_writew(0, PMCR(i));
-		__raw_writel(regcache[i].cnt_hi, PMCTRH(i));
-		__raw_writel(regcache[i].cnt_lo, PMCTRL(i));
-	}
-}
-
-static void sh7750_ppc_cpu_start(void *args)
-{
-	unsigned int counters = op_model_sh7750_ops.num_counters;
-	int i;
-
-	for (i = 0; i < counters; i++)
-		__raw_writew(regcache[i].ctrl, PMCR(i));
-}
-
-static void sh7750_ppc_cpu_stop(void *args)
-{
-	unsigned int counters = op_model_sh7750_ops.num_counters;
-	int i;
-
-	/* Disable the counters */
-	for (i = 0; i < counters; i++)
-		__raw_writew(__raw_readw(PMCR(i)) & ~PMCR_PMEN, PMCR(i));
-}
-
-static inline void sh7750_ppc_reset(void)
-{
-	unsigned int counters = op_model_sh7750_ops.num_counters;
-	int i;
-
-	/* Clear the counters */
-	for (i = 0; i < counters; i++)
-		__raw_writew(__raw_readw(PMCR(i)) | PMCR_PMCLR, PMCR(i));
-}
-
-static int sh7750_ppc_init(void)
-{
-	sh7750_ppc_reset();
-
-	return register_timer_hook(sh7750_timer_notify);
-}
-
-static void sh7750_ppc_exit(void)
-{
-	unregister_timer_hook(sh7750_timer_notify);
-
-	sh7750_ppc_reset();
-}
-
-struct op_sh_model op_model_sh7750_ops = {
-	.cpu_type	= "sh/sh7750",
-	.num_counters	= NR_CNTRS,
-	.reg_setup	= sh7750_ppc_reg_setup,
-	.cpu_setup	= sh7750_ppc_cpu_setup,
-	.cpu_start	= sh7750_ppc_cpu_start,
-	.cpu_stop	= sh7750_ppc_cpu_stop,
-	.init		= sh7750_ppc_init,
-	.exit		= sh7750_ppc_exit,
-	.create_files	= sh7750_ppc_create_files,
-};
diff --git a/arch/sparc/include/asm/fcntl.h b/arch/sparc/include/asm/fcntl.h
index d4d9c9d..3b9cfb3 100644
--- a/arch/sparc/include/asm/fcntl.h
+++ b/arch/sparc/include/asm/fcntl.h
@@ -1,14 +1,12 @@
 #ifndef _SPARC_FCNTL_H
 #define _SPARC_FCNTL_H
 
-/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
-   located on an ext2 file system */
 #define O_APPEND	0x0008
 #define FASYNC		0x0040	/* fcntl, for BSD compatibility */
 #define O_CREAT		0x0200	/* not fcntl */
 #define O_TRUNC		0x0400	/* not fcntl */
 #define O_EXCL		0x0800	/* not fcntl */
-#define O_SYNC		0x2000
+#define O_DSYNC		0x2000	/* used to be O_SYNC, see below */
 #define O_NONBLOCK	0x4000
 #if defined(__sparc__) && defined(__arch64__)
 #define O_NDELAY	0x0004
@@ -20,6 +18,21 @@
 #define O_DIRECT        0x100000 /* direct disk access hint */
 #define O_NOATIME	0x200000
 #define O_CLOEXEC	0x400000
+/*
+ * Before Linux 2.6.32 only O_DSYNC semantics were implemented, but using
+ * the O_SYNC flag.  We continue to use the existing numerical value
+ * for O_DSYNC semantics now, but using the correct symbolic name for it.
+ * This new value is used to request true Posix O_SYNC semantics.  It is
+ * defined in this strange way to make sure applications compiled against
+ * new headers get at least O_DSYNC semantics on older kernels.
+ *
+ * This has the nice side-effect that we can simply test for O_DSYNC
+ * wherever we do not care if O_DSYNC or O_SYNC is used.
+ *
+ * Note: __O_SYNC must never be used directly.
+ */
+#define __O_SYNC	0x800000
+#define O_SYNC		(__O_SYNC|O_DSYNC)
 
 #define F_GETOWN	5	/*  for sockets. */
 #define F_SETOWN	6	/*  for sockets. */
diff --git a/arch/sparc/include/asm/pci_64.h b/arch/sparc/include/asm/pci_64.h
index b63e51c..b0576df 100644
--- a/arch/sparc/include/asm/pci_64.h
+++ b/arch/sparc/include/asm/pci_64.h
@@ -16,8 +16,6 @@
 
 #define PCI_IRQ_NONE		0xffffffff
 
-#define PCI_CACHE_LINE_BYTES	64
-
 static inline void pcibios_set_master(struct pci_dev *dev)
 {
 	/* No special bus mastering setup handling */
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index c686486..b85374f 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -1081,3 +1081,10 @@
 	*start = rp->start - offset;
 	*end = rp->end - offset;
 }
+
+static int __init pcibios_init(void)
+{
+	pci_dfl_cache_line_size = 64 >> 2;
+	return 0;
+}
+subsys_initcall(pcibios_init);
diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c
index 00abe87..dc0ac19 100644
--- a/arch/sparc/kernel/sys_sparc32.c
+++ b/arch/sparc/kernel/sys_sparc32.c
@@ -564,28 +564,6 @@
 	return do_sys_open(AT_FDCWD, filename, flags, mode);
 }
 
-extern unsigned long do_mremap(unsigned long addr,
-	unsigned long old_len, unsigned long new_len,
-	unsigned long flags, unsigned long new_addr);
-                
-asmlinkage unsigned long sys32_mremap(unsigned long addr,
-	unsigned long old_len, unsigned long new_len,
-	unsigned long flags, u32 __new_addr)
-{
-	unsigned long ret = -EINVAL;
-	unsigned long new_addr = __new_addr;
-
-	if (unlikely(sparc_mmap_check(addr, old_len)))
-		goto out;
-	if (unlikely(sparc_mmap_check(new_addr, new_len)))
-		goto out;
-	down_write(&current->mm->mmap_sem);
-	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
-	up_write(&current->mm->mmap_sem);
-out:
-	return ret;       
-}
-
 long sys32_lookup_dcookie(unsigned long cookie_high,
 			  unsigned long cookie_low,
 			  char __user *buf, size_t len)
diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c
index 03035c8..3a82e65 100644
--- a/arch/sparc/kernel/sys_sparc_32.c
+++ b/arch/sparc/kernel/sys_sparc_32.c
@@ -45,7 +45,8 @@
 		/* We do not accept a shared mapping if it would violate
 		 * cache aliasing constraints.
 		 */
-		if ((flags & MAP_SHARED) && (addr & (SHMLBA - 1)))
+		if ((flags & MAP_SHARED) &&
+		    ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
 			return -EINVAL;
 		return addr;
 	}
@@ -79,15 +80,6 @@
 	}
 }
 
-asmlinkage unsigned long sparc_brk(unsigned long brk)
-{
-	if(ARCH_SUN4C) {
-		if ((brk & 0xe0000000) != (current->mm->brk & 0xe0000000))
-			return current->mm->brk;
-	}
-	return sys_brk(brk);
-}
-
 /*
  * sys_pipe() is the normal C calling standard for creating
  * a pipe. It's not the way unix traditionally does this, though.
@@ -234,31 +226,6 @@
 }
 
 /* Linux version of mmap */
-static unsigned long do_mmap2(unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags, unsigned long fd,
-	unsigned long pgoff)
-{
-	struct file * file = NULL;
-	unsigned long retval = -EBADF;
-
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	len = PAGE_ALIGN(len);
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	down_write(&current->mm->mmap_sem);
-	retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return retval;
-}
 
 asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len,
 	unsigned long prot, unsigned long flags, unsigned long fd,
@@ -266,14 +233,16 @@
 {
 	/* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE
 	   we have. */
-	return do_mmap2(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT - 12));
+	return sys_mmap_pgoff(addr, len, prot, flags, fd,
+			      pgoff >> (PAGE_SHIFT - 12));
 }
 
 asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
 	unsigned long prot, unsigned long flags, unsigned long fd,
 	unsigned long off)
 {
-	return do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
+	/* no alignment check? */
+	return sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
 }
 
 long sparc_remap_file_pages(unsigned long start, unsigned long size,
@@ -287,27 +256,6 @@
 				    (pgoff >> (PAGE_SHIFT - 12)), flags);
 }
 
-extern unsigned long do_mremap(unsigned long addr,
-	unsigned long old_len, unsigned long new_len,
-	unsigned long flags, unsigned long new_addr);
-                
-asmlinkage unsigned long sparc_mremap(unsigned long addr,
-	unsigned long old_len, unsigned long new_len,
-	unsigned long flags, unsigned long new_addr)
-{
-	unsigned long ret = -EINVAL;
-
-	if (unlikely(sparc_mmap_check(addr, old_len)))
-		goto out;
-	if (unlikely(sparc_mmap_check(new_addr, new_len)))
-		goto out;
-	down_write(&current->mm->mmap_sem);
-	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
-	up_write(&current->mm->mmap_sem);
-out:
-	return ret;       
-}
-
 /* we come to here via sys_nis_syscall so it can setup the regs argument */
 asmlinkage unsigned long
 c_sys_nis_syscall (struct pt_regs *regs)
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index e2d1024..cfa0e19 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -317,10 +317,14 @@
 unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags)
 {
 	unsigned long align_goal, addr = -ENOMEM;
+	unsigned long (*get_area)(struct file *, unsigned long,
+				  unsigned long, unsigned long, unsigned long);
+
+	get_area = current->mm->get_unmapped_area;
 
 	if (flags & MAP_FIXED) {
 		/* Ok, don't mess with it. */
-		return get_unmapped_area(NULL, orig_addr, len, pgoff, flags);
+		return get_area(NULL, orig_addr, len, pgoff, flags);
 	}
 	flags &= ~MAP_SHARED;
 
@@ -333,7 +337,7 @@
 		align_goal = (64UL * 1024);
 
 	do {
-		addr = get_unmapped_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags);
+		addr = get_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags);
 		if (!(addr & ~PAGE_MASK)) {
 			addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL);
 			break;
@@ -351,7 +355,7 @@
 	 * be obtained.
 	 */
 	if (addr & ~PAGE_MASK)
-		addr = get_unmapped_area(NULL, orig_addr, len, pgoff, flags);
+		addr = get_area(NULL, orig_addr, len, pgoff, flags);
 
 	return addr;
 }
@@ -399,18 +403,6 @@
 	}
 }
 
-SYSCALL_DEFINE1(sparc_brk, unsigned long, brk)
-{
-	/* People could try to be nasty and use ta 0x6d in 32bit programs */
-	if (test_thread_flag(TIF_32BIT) && brk >= STACK_TOP32)
-		return current->mm->brk;
-
-	if (unlikely(straddles_64bit_va_hole(current->mm->brk, brk)))
-		return current->mm->brk;
-
-	return sys_brk(brk);
-}
-                                                                
 /*
  * sys_pipe() is the normal C calling standard for creating
  * a pipe. It's not the way unix traditionally does this, though.
@@ -568,23 +560,13 @@
 		unsigned long, prot, unsigned long, flags, unsigned long, fd,
 		unsigned long, off)
 {
-	struct file * file = NULL;
-	unsigned long retval = -EBADF;
+	unsigned long retval = -EINVAL;
 
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	len = PAGE_ALIGN(len);
-
-	down_write(&current->mm->mmap_sem);
-	retval = do_mmap(file, addr, len, prot, flags, off);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
+	if ((off + PAGE_ALIGN(len)) < off)
+		goto out;
+	if (off & ~PAGE_MASK)
+		goto out;
+	retval = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
 out:
 	return retval;
 }
@@ -614,12 +596,6 @@
 
 	if (test_thread_flag(TIF_32BIT))
 		goto out;
-	if (unlikely(new_len >= VA_EXCLUDE_START))
-		goto out;
-	if (unlikely(sparc_mmap_check(addr, old_len)))
-		goto out;
-	if (unlikely(sparc_mmap_check(new_addr, new_len)))
-		goto out;
 
 	down_write(&current->mm->mmap_sem);
 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
diff --git a/arch/sparc/kernel/systbls.h b/arch/sparc/kernel/systbls.h
index a63c5d2..d2f999a 100644
--- a/arch/sparc/kernel/systbls.h
+++ b/arch/sparc/kernel/systbls.h
@@ -9,7 +9,6 @@
 struct new_utsname;
 
 extern asmlinkage unsigned long sys_getpagesize(void);
-extern asmlinkage unsigned long sparc_brk(unsigned long brk);
 extern asmlinkage long sparc_pipe(struct pt_regs *regs);
 extern asmlinkage long sys_ipc(unsigned int call, int first,
 			       unsigned long second,
diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S
index ceb1530..801fc8e 100644
--- a/arch/sparc/kernel/systbls_32.S
+++ b/arch/sparc/kernel/systbls_32.S
@@ -19,7 +19,7 @@
 /*0*/	.long sys_restart_syscall, sys_exit, sys_fork, sys_read, sys_write
 /*5*/	.long sys_open, sys_close, sys_wait4, sys_creat, sys_link
 /*10*/  .long sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys_mknod
-/*15*/	.long sys_chmod, sys_lchown16, sparc_brk, sys_nis_syscall, sys_lseek
+/*15*/	.long sys_chmod, sys_lchown16, sys_brk, sys_nis_syscall, sys_lseek
 /*20*/	.long sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16
 /*25*/	.long sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_pause
 /*30*/	.long sys_utime, sys_lchown, sys_fchown, sys_access, sys_nice
@@ -67,7 +67,7 @@
 /*235*/	.long sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
 /*240*/	.long sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
 /*245*/	.long sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep
-/*250*/	.long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
+/*250*/	.long sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
 /*255*/	.long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
 /*260*/	.long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
 /*265*/	.long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S
index cc8e786..e575b46 100644
--- a/arch/sparc/kernel/systbls_64.S
+++ b/arch/sparc/kernel/systbls_64.S
@@ -21,7 +21,7 @@
 /*0*/	.word sys_restart_syscall, sys32_exit, sys_fork, sys_read, sys_write
 /*5*/	.word sys32_open, sys_close, sys32_wait4, sys32_creat, sys_link
 /*10*/  .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod
-/*15*/	.word sys_chmod, sys_lchown16, sys_sparc_brk, sys32_perfctr, sys32_lseek
+/*15*/	.word sys_chmod, sys_lchown16, sys_brk, sys32_perfctr, sys32_lseek
 /*20*/	.word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16
 /*25*/	.word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys_pause
 /*30*/	.word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice
@@ -68,7 +68,7 @@
 	.word compat_sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys32_mlockall
 /*240*/	.word sys_munlockall, sys32_sched_setparam, sys32_sched_getparam, sys32_sched_setscheduler, sys32_sched_getscheduler
 	.word sys_sched_yield, sys32_sched_get_priority_max, sys32_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep
-/*250*/	.word sys32_mremap, compat_sys_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl
+/*250*/	.word sys_mremap, compat_sys_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl
 	.word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep
 /*260*/	.word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun
 	.word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
@@ -96,7 +96,7 @@
 /*0*/	.word sys_restart_syscall, sparc_exit, sys_fork, sys_read, sys_write
 /*5*/	.word sys_open, sys_close, sys_wait4, sys_creat, sys_link
 /*10*/  .word sys_unlink, sys_nis_syscall, sys_chdir, sys_chown, sys_mknod
-/*15*/	.word sys_chmod, sys_lchown, sys_sparc_brk, sys_perfctr, sys_lseek
+/*15*/	.word sys_chmod, sys_lchown, sys_brk, sys_perfctr, sys_lseek
 /*20*/	.word sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid
 /*25*/	.word sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_nis_syscall
 /*30*/	.word sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice
diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c
index da1218e..63f73ae 100644
--- a/arch/sparc/kernel/time_64.c
+++ b/arch/sparc/kernel/time_64.c
@@ -847,7 +847,7 @@
 	sparc64_clockevent.min_delta_ns =
 		clockevent_delta2ns(0xF, &sparc64_clockevent);
 
-	printk("clockevent: mult[%lx] shift[%d]\n",
+	printk("clockevent: mult[%ux] shift[%d]\n",
 	       sparc64_clockevent.mult, sparc64_clockevent.shift);
 
 	setup_sparc64_timer();
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
index eb24032..d22f9e5 100644
--- a/arch/um/drivers/mmapper_kern.c
+++ b/arch/um/drivers/mmapper_kern.c
@@ -16,7 +16,7 @@
 #include <linux/miscdevice.h>
 #include <linux/module.h>
 #include <linux/mm.h>
-#include <linux/smp_lock.h>
+
 #include <asm/uaccess.h>
 #include "mem_user.h"
 
@@ -78,7 +78,6 @@
 
 static int mmapper_open(struct inode *inode, struct file *file)
 {
-	cycle_kernel_lock();
 	return 0;
 }
 
@@ -115,18 +114,16 @@
 	v_buf = (char *) find_iomem("mmapper", &mmapper_size);
 	if (mmapper_size == 0) {
 		printk(KERN_ERR "mmapper_init - find_iomem failed\n");
-		goto out;
+		return -ENODEV;
 	}
+	p_buf = __pa(v_buf);
 
 	err = misc_register(&mmapper_dev);
 	if (err) {
 		printk(KERN_ERR "mmapper - misc_register failed, err = %d\n",
 		       err);
-		goto out;
+		return err;;
 	}
-
-	p_buf = __pa(v_buf);
-out:
 	return 0;
 }
 
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
index 6eabb70..4949044 100644
--- a/arch/um/drivers/random.c
+++ b/arch/um/drivers/random.c
@@ -7,7 +7,6 @@
  * of the GNU General Public License, incorporated herein by reference.
  */
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/interrupt.h>
@@ -34,8 +33,6 @@
 
 static int rng_dev_open (struct inode *inode, struct file *filp)
 {
-	cycle_kernel_lock();
-
 	/* enforce read-only access to this chrdev */
 	if ((filp->f_mode & FMODE_READ) == 0)
 		return -EINVAL;
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c
index a4625c7..cccab85 100644
--- a/arch/um/kernel/syscall.c
+++ b/arch/um/kernel/syscall.c
@@ -8,6 +8,7 @@
 #include "linux/mm.h"
 #include "linux/sched.h"
 #include "linux/utsname.h"
+#include "linux/syscalls.h"
 #include "asm/current.h"
 #include "asm/mman.h"
 #include "asm/uaccess.h"
@@ -37,31 +38,6 @@
 	return ret;
 }
 
-/* common code for old and new mmaps */
-long sys_mmap2(unsigned long addr, unsigned long len,
-	       unsigned long prot, unsigned long flags,
-	       unsigned long fd, unsigned long pgoff)
-{
-	long error = -EBADF;
-	struct file * file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
- out:
-	return error;
-}
-
 long old_mmap(unsigned long addr, unsigned long len,
 	      unsigned long prot, unsigned long flags,
 	      unsigned long fd, unsigned long offset)
@@ -70,7 +46,7 @@
 	if (offset & ~PAGE_MASK)
 		goto out;
 
-	err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+	err = sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
  out:
 	return err;
 }
diff --git a/arch/um/sys-i386/shared/sysdep/syscalls.h b/arch/um/sys-i386/shared/sysdep/syscalls.h
index 9056981..e778767 100644
--- a/arch/um/sys-i386/shared/sysdep/syscalls.h
+++ b/arch/um/sys-i386/shared/sysdep/syscalls.h
@@ -20,7 +20,3 @@
 #define EXECUTE_SYSCALL(syscall, regs) \
 	((long (*)(struct syscall_args)) \
 	 (*sys_call_table[syscall]))(SYSCALL_ARGS(&regs->regs))
-
-extern long sys_mmap2(unsigned long addr, unsigned long len,
-		      unsigned long prot, unsigned long flags,
-		      unsigned long fd, unsigned long pgoff);
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 1b2182b..32a1918 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1332,7 +1332,9 @@
 	  kernel, it won't hurt.
 
 config MTRR
-	bool "MTRR (Memory Type Range Register) support"
+	bool
+	default y
+	prompt "MTRR (Memory Type Range Register) support" if EMBEDDED
 	---help---
 	  On Intel P6 family processors (Pentium Pro, Pentium II and later)
 	  the Memory Type Range Registers (MTRRs) may be used to control
@@ -1398,7 +1400,8 @@
 
 config X86_PAT
 	bool
-	prompt "x86 PAT support"
+	default y
+	prompt "x86 PAT support" if EMBEDDED
 	depends on MTRR
 	---help---
 	  Use PAT attributes to setup page level cache control.
@@ -1604,7 +1607,7 @@
 	depends on X86_32 || IA32_EMULATION
 	---help---
 	  Map the 32-bit VDSO to the predictable old-style address too.
-	---help---
+
 	  Say N here if you are running a sufficiently recent glibc
 	  version (2.3.3 or later), to remove the high-mapped
 	  VDSO mapping and to exclusively use the randomized VDSO.
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 5e99762..08e442b 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -301,15 +301,11 @@
 
 #
 # Define implied options from the CPU selection here
-config X86_L1_CACHE_BYTES
+config X86_INTERNODE_CACHE_SHIFT
 	int
-	default "128" if MPSC
-	default "64" if GENERIC_CPU || MK8 || MCORE2 || MATOM || X86_32
-
-config X86_INTERNODE_CACHE_BYTES
-	int
-	default "4096" if X86_VSMP
-	default X86_L1_CACHE_BYTES if !X86_VSMP
+	default "12" if X86_VSMP
+	default "7" if NUMA
+	default X86_L1_CACHE_SHIFT
 
 config X86_CMPXCHG
 	def_bool X86_64 || (X86_32 && !M386)
@@ -317,9 +313,9 @@
 config X86_L1_CACHE_SHIFT
 	int
 	default "7" if MPENTIUM4 || MPSC
+	default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU
 	default "4" if X86_ELAN || M486 || M386 || MGEODEGX1
 	default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
-	default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU
 
 config X86_XADD
 	def_bool y
diff --git a/arch/x86/Makefile_32.cpu b/arch/x86/Makefile_32.cpu
index cbf0776..1255d95 100644
--- a/arch/x86/Makefile_32.cpu
+++ b/arch/x86/Makefile_32.cpu
@@ -46,6 +46,13 @@
 # cpu entries
 cflags-$(CONFIG_X86_GENERIC) 	+= $(call tune,generic,$(call tune,i686))
 
+# Work around the pentium-mmx code generator madness of gcc4.4.x which
+# does stack alignment by generating horrible code _before_ the mcount
+# prologue (push %ebp, mov %esp, %ebp) which breaks the function graph
+# tracer assumptions. For i686, generic, core2 this is set by the
+# compiler anyway
+cflags-$(CONFIG_FUNCTION_GRAPH_TRACER) += $(call cc-option,-maccumulate-outgoing-args)
+
 # Bug fix for binutils: this option is required in order to keep
 # binutils from generating NOPL instructions against our will.
 ifneq ($(CONFIG_X86_P6_NOP),y)
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
index 077e1b6..faff0dc 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -107,8 +107,7 @@
 	lgdt	gdt(%ebp)
 
 	/* Enable PAE mode */
-	xorl	%eax, %eax
-	orl	$(X86_CR4_PAE), %eax
+	movl	$(X86_CR4_PAE), %eax
 	movl	%eax, %cr4
 
  /*
diff --git a/arch/x86/boot/compressed/vmlinux.lds.S b/arch/x86/boot/compressed/vmlinux.lds.S
index f4193bb..a6f1a59 100644
--- a/arch/x86/boot/compressed/vmlinux.lds.S
+++ b/arch/x86/boot/compressed/vmlinux.lds.S
@@ -4,6 +4,7 @@
 
 #undef i386
 
+#include <asm/cache.h>
 #include <asm/page_types.h>
 
 #ifdef CONFIG_X86_64
@@ -46,7 +47,7 @@
 		*(.data.*)
 		_edata = . ;
 	}
-	. = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
+	. = ALIGN(L1_CACHE_BYTES);
 	.bss : {
 		_bss = . ;
 		*(.bss)
diff --git a/arch/x86/boot/video.c b/arch/x86/boot/video.c
index d42da38..f767164 100644
--- a/arch/x86/boot/video.c
+++ b/arch/x86/boot/video.c
@@ -27,6 +27,12 @@
 
 	boot_params.screen_info.orig_x = oreg.dl;
 	boot_params.screen_info.orig_y = oreg.dh;
+
+	if (oreg.ch & 0x20)
+		boot_params.screen_info.flags |= VIDEO_FLAGS_NOCURSOR;
+
+	if ((oreg.ch & 0x1f) > (oreg.cl & 0x1f))
+		boot_params.screen_info.flags |= VIDEO_FLAGS_NOCURSOR;
 }
 
 static void store_video_mode(void)
diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
index cfb0010..1a58ad8 100644
--- a/arch/x86/crypto/Makefile
+++ b/arch/x86/crypto/Makefile
@@ -12,6 +12,7 @@
 obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o
 obj-$(CONFIG_CRYPTO_SALSA20_X86_64) += salsa20-x86_64.o
 obj-$(CONFIG_CRYPTO_AES_NI_INTEL) += aesni-intel.o
+obj-$(CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL) += ghash-clmulni-intel.o
 
 obj-$(CONFIG_CRYPTO_CRC32C_INTEL) += crc32c-intel.o
 
@@ -24,3 +25,5 @@
 salsa20-x86_64-y := salsa20-x86_64-asm_64.o salsa20_glue.o
 
 aesni-intel-y := aesni-intel_asm.o aesni-intel_glue.o
+
+ghash-clmulni-intel-y := ghash-clmulni-intel_asm.o ghash-clmulni-intel_glue.o
diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S
index eb0566e..20bb0e1a 100644
--- a/arch/x86/crypto/aesni-intel_asm.S
+++ b/arch/x86/crypto/aesni-intel_asm.S
@@ -16,6 +16,7 @@
  */
 
 #include <linux/linkage.h>
+#include <asm/inst.h>
 
 .text
 
@@ -122,103 +123,72 @@
 	movups 0x10(%rsi), %xmm2	# other user key
 	movaps %xmm2, (%rcx)
 	add $0x10, %rcx
-	# aeskeygenassist $0x1, %xmm2, %xmm1	# round 1
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x01
+	AESKEYGENASSIST 0x1 %xmm2 %xmm1		# round 1
 	call _key_expansion_256a
-	# aeskeygenassist $0x1, %xmm0, %xmm1
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x01
+	AESKEYGENASSIST 0x1 %xmm0 %xmm1
 	call _key_expansion_256b
-	# aeskeygenassist $0x2, %xmm2, %xmm1	# round 2
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x02
+	AESKEYGENASSIST 0x2 %xmm2 %xmm1		# round 2
 	call _key_expansion_256a
-	# aeskeygenassist $0x2, %xmm0, %xmm1
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x02
+	AESKEYGENASSIST 0x2 %xmm0 %xmm1
 	call _key_expansion_256b
-	# aeskeygenassist $0x4, %xmm2, %xmm1	# round 3
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x04
+	AESKEYGENASSIST 0x4 %xmm2 %xmm1		# round 3
 	call _key_expansion_256a
-	# aeskeygenassist $0x4, %xmm0, %xmm1
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x04
+	AESKEYGENASSIST 0x4 %xmm0 %xmm1
 	call _key_expansion_256b
-	# aeskeygenassist $0x8, %xmm2, %xmm1	# round 4
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x08
+	AESKEYGENASSIST 0x8 %xmm2 %xmm1		# round 4
 	call _key_expansion_256a
-	# aeskeygenassist $0x8, %xmm0, %xmm1
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x08
+	AESKEYGENASSIST 0x8 %xmm0 %xmm1
 	call _key_expansion_256b
-	# aeskeygenassist $0x10, %xmm2, %xmm1	# round 5
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x10
+	AESKEYGENASSIST 0x10 %xmm2 %xmm1	# round 5
 	call _key_expansion_256a
-	# aeskeygenassist $0x10, %xmm0, %xmm1
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x10
+	AESKEYGENASSIST 0x10 %xmm0 %xmm1
 	call _key_expansion_256b
-	# aeskeygenassist $0x20, %xmm2, %xmm1	# round 6
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x20
+	AESKEYGENASSIST 0x20 %xmm2 %xmm1	# round 6
 	call _key_expansion_256a
-	# aeskeygenassist $0x20, %xmm0, %xmm1
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x20
+	AESKEYGENASSIST 0x20 %xmm0 %xmm1
 	call _key_expansion_256b
-	# aeskeygenassist $0x40, %xmm2, %xmm1	# round 7
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x40
+	AESKEYGENASSIST 0x40 %xmm2 %xmm1	# round 7
 	call _key_expansion_256a
 	jmp .Ldec_key
 .Lenc_key192:
 	movq 0x10(%rsi), %xmm2		# other user key
-	# aeskeygenassist $0x1, %xmm2, %xmm1	# round 1
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x01
+	AESKEYGENASSIST 0x1 %xmm2 %xmm1		# round 1
 	call _key_expansion_192a
-	# aeskeygenassist $0x2, %xmm2, %xmm1	# round 2
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x02
+	AESKEYGENASSIST 0x2 %xmm2 %xmm1		# round 2
 	call _key_expansion_192b
-	# aeskeygenassist $0x4, %xmm2, %xmm1	# round 3
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x04
+	AESKEYGENASSIST 0x4 %xmm2 %xmm1		# round 3
 	call _key_expansion_192a
-	# aeskeygenassist $0x8, %xmm2, %xmm1	# round 4
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x08
+	AESKEYGENASSIST 0x8 %xmm2 %xmm1		# round 4
 	call _key_expansion_192b
-	# aeskeygenassist $0x10, %xmm2, %xmm1	# round 5
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x10
+	AESKEYGENASSIST 0x10 %xmm2 %xmm1	# round 5
 	call _key_expansion_192a
-	# aeskeygenassist $0x20, %xmm2, %xmm1	# round 6
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x20
+	AESKEYGENASSIST 0x20 %xmm2 %xmm1	# round 6
 	call _key_expansion_192b
-	# aeskeygenassist $0x40, %xmm2, %xmm1	# round 7
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x40
+	AESKEYGENASSIST 0x40 %xmm2 %xmm1	# round 7
 	call _key_expansion_192a
-	# aeskeygenassist $0x80, %xmm2, %xmm1	# round 8
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x80
+	AESKEYGENASSIST 0x80 %xmm2 %xmm1	# round 8
 	call _key_expansion_192b
 	jmp .Ldec_key
 .Lenc_key128:
-	# aeskeygenassist $0x1, %xmm0, %xmm1	# round 1
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x01
+	AESKEYGENASSIST 0x1 %xmm0 %xmm1		# round 1
 	call _key_expansion_128
-	# aeskeygenassist $0x2, %xmm0, %xmm1	# round 2
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x02
+	AESKEYGENASSIST 0x2 %xmm0 %xmm1		# round 2
 	call _key_expansion_128
-	# aeskeygenassist $0x4, %xmm0, %xmm1	# round 3
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x04
+	AESKEYGENASSIST 0x4 %xmm0 %xmm1		# round 3
 	call _key_expansion_128
-	# aeskeygenassist $0x8, %xmm0, %xmm1	# round 4
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x08
+	AESKEYGENASSIST 0x8 %xmm0 %xmm1		# round 4
 	call _key_expansion_128
-	# aeskeygenassist $0x10, %xmm0, %xmm1	# round 5
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x10
+	AESKEYGENASSIST 0x10 %xmm0 %xmm1	# round 5
 	call _key_expansion_128
-	# aeskeygenassist $0x20, %xmm0, %xmm1	# round 6
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x20
+	AESKEYGENASSIST 0x20 %xmm0 %xmm1	# round 6
 	call _key_expansion_128
-	# aeskeygenassist $0x40, %xmm0, %xmm1	# round 7
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x40
+	AESKEYGENASSIST 0x40 %xmm0 %xmm1	# round 7
 	call _key_expansion_128
-	# aeskeygenassist $0x80, %xmm0, %xmm1	# round 8
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x80
+	AESKEYGENASSIST 0x80 %xmm0 %xmm1	# round 8
 	call _key_expansion_128
-	# aeskeygenassist $0x1b, %xmm0, %xmm1	# round 9
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x1b
+	AESKEYGENASSIST 0x1b %xmm0 %xmm1	# round 9
 	call _key_expansion_128
-	# aeskeygenassist $0x36, %xmm0, %xmm1	# round 10
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x36
+	AESKEYGENASSIST 0x36 %xmm0 %xmm1	# round 10
 	call _key_expansion_128
 .Ldec_key:
 	sub $0x10, %rcx
@@ -231,8 +201,7 @@
 .align 4
 .Ldec_key_loop:
 	movaps (%rdi), %xmm0
-	# aesimc %xmm0, %xmm1
-	.byte 0x66, 0x0f, 0x38, 0xdb, 0xc8
+	AESIMC %xmm0 %xmm1
 	movaps %xmm1, (%rsi)
 	add $0x10, %rdi
 	sub $0x10, %rsi
@@ -274,51 +243,37 @@
 	je .Lenc192
 	add $0x20, TKEYP
 	movaps -0x60(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 	movaps -0x50(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 .align 4
 .Lenc192:
 	movaps -0x40(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 	movaps -0x30(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 .align 4
 .Lenc128:
 	movaps -0x20(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 	movaps -0x10(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 	movaps (TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 	movaps 0x10(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 	movaps 0x20(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 	movaps 0x30(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 	movaps 0x40(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 	movaps 0x50(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 	movaps 0x60(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 	movaps 0x70(TKEYP), KEY
-	# aesenclast KEY, STATE	# last round
-	.byte 0x66, 0x0f, 0x38, 0xdd, 0xc2
+	AESENCLAST KEY STATE
 	ret
 
 /*
@@ -353,135 +308,79 @@
 	je .L4enc192
 	add $0x20, TKEYP
 	movaps -0x60(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 	movaps -0x50(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 #.align 4
 .L4enc192:
 	movaps -0x40(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 	movaps -0x30(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 #.align 4
 .L4enc128:
 	movaps -0x20(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 	movaps -0x10(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 	movaps (TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 	movaps 0x10(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 	movaps 0x20(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 	movaps 0x30(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 	movaps 0x40(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 	movaps 0x50(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 	movaps 0x60(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 	movaps 0x70(TKEYP), KEY
-	# aesenclast KEY, STATE1	# last round
-	.byte 0x66, 0x0f, 0x38, 0xdd, 0xc2
-	# aesenclast KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdd, 0xe2
-	# aesenclast KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdd, 0xea
-	# aesenclast KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdd, 0xf2
+	AESENCLAST KEY STATE1		# last round
+	AESENCLAST KEY STATE2
+	AESENCLAST KEY STATE3
+	AESENCLAST KEY STATE4
 	ret
 
 /*
@@ -518,51 +417,37 @@
 	je .Ldec192
 	add $0x20, TKEYP
 	movaps -0x60(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 	movaps -0x50(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 .align 4
 .Ldec192:
 	movaps -0x40(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 	movaps -0x30(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 .align 4
 .Ldec128:
 	movaps -0x20(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 	movaps -0x10(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 	movaps (TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 	movaps 0x10(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 	movaps 0x20(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 	movaps 0x30(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 	movaps 0x40(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 	movaps 0x50(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 	movaps 0x60(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 	movaps 0x70(TKEYP), KEY
-	# aesdeclast KEY, STATE		# last round
-	.byte 0x66, 0x0f, 0x38, 0xdf, 0xc2
+	AESDECLAST KEY STATE
 	ret
 
 /*
@@ -597,135 +482,79 @@
 	je .L4dec192
 	add $0x20, TKEYP
 	movaps -0x60(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 	movaps -0x50(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 .align 4
 .L4dec192:
 	movaps -0x40(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 	movaps -0x30(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 .align 4
 .L4dec128:
 	movaps -0x20(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 	movaps -0x10(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 	movaps (TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 	movaps 0x10(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 	movaps 0x20(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 	movaps 0x30(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 	movaps 0x40(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 	movaps 0x50(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 	movaps 0x60(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 	movaps 0x70(TKEYP), KEY
-	# aesdeclast KEY, STATE1	# last round
-	.byte 0x66, 0x0f, 0x38, 0xdf, 0xc2
-	# aesdeclast KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdf, 0xe2
-	# aesdeclast KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdf, 0xea
-	# aesdeclast KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdf, 0xf2
+	AESDECLAST KEY STATE1		# last round
+	AESDECLAST KEY STATE2
+	AESDECLAST KEY STATE3
+	AESDECLAST KEY STATE4
 	ret
 
 /*
diff --git a/arch/x86/crypto/ghash-clmulni-intel_asm.S b/arch/x86/crypto/ghash-clmulni-intel_asm.S
new file mode 100644
index 0000000..1eb7f90
--- /dev/null
+++ b/arch/x86/crypto/ghash-clmulni-intel_asm.S
@@ -0,0 +1,157 @@
+/*
+ * Accelerated GHASH implementation with Intel PCLMULQDQ-NI
+ * instructions. This file contains accelerated part of ghash
+ * implementation. More information about PCLMULQDQ can be found at:
+ *
+ * http://software.intel.com/en-us/articles/carry-less-multiplication-and-its-usage-for-computing-the-gcm-mode/
+ *
+ * Copyright (c) 2009 Intel Corp.
+ *   Author: Huang Ying <ying.huang@intel.com>
+ *	     Vinodh Gopal
+ *	     Erdinc Ozturk
+ *	     Deniz Karakoyunlu
+ *
+ * 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.
+ */
+
+#include <linux/linkage.h>
+#include <asm/inst.h>
+
+.data
+
+.align 16
+.Lbswap_mask:
+	.octa 0x000102030405060708090a0b0c0d0e0f
+.Lpoly:
+	.octa 0xc2000000000000000000000000000001
+.Ltwo_one:
+	.octa 0x00000001000000000000000000000001
+
+#define DATA	%xmm0
+#define SHASH	%xmm1
+#define T1	%xmm2
+#define T2	%xmm3
+#define T3	%xmm4
+#define BSWAP	%xmm5
+#define IN1	%xmm6
+
+.text
+
+/*
+ * __clmul_gf128mul_ble:	internal ABI
+ * input:
+ *	DATA:			operand1
+ *	SHASH:			operand2, hash_key << 1 mod poly
+ * output:
+ *	DATA:			operand1 * operand2 mod poly
+ * changed:
+ *	T1
+ *	T2
+ *	T3
+ */
+__clmul_gf128mul_ble:
+	movaps DATA, T1
+	pshufd $0b01001110, DATA, T2
+	pshufd $0b01001110, SHASH, T3
+	pxor DATA, T2
+	pxor SHASH, T3
+
+	PCLMULQDQ 0x00 SHASH DATA	# DATA = a0 * b0
+	PCLMULQDQ 0x11 SHASH T1		# T1 = a1 * b1
+	PCLMULQDQ 0x00 T3 T2		# T2 = (a1 + a0) * (b1 + b0)
+	pxor DATA, T2
+	pxor T1, T2			# T2 = a0 * b1 + a1 * b0
+
+	movaps T2, T3
+	pslldq $8, T3
+	psrldq $8, T2
+	pxor T3, DATA
+	pxor T2, T1			# <T1:DATA> is result of
+					# carry-less multiplication
+
+	# first phase of the reduction
+	movaps DATA, T3
+	psllq $1, T3
+	pxor DATA, T3
+	psllq $5, T3
+	pxor DATA, T3
+	psllq $57, T3
+	movaps T3, T2
+	pslldq $8, T2
+	psrldq $8, T3
+	pxor T2, DATA
+	pxor T3, T1
+
+	# second phase of the reduction
+	movaps DATA, T2
+	psrlq $5, T2
+	pxor DATA, T2
+	psrlq $1, T2
+	pxor DATA, T2
+	psrlq $1, T2
+	pxor T2, T1
+	pxor T1, DATA
+	ret
+
+/* void clmul_ghash_mul(char *dst, const be128 *shash) */
+ENTRY(clmul_ghash_mul)
+	movups (%rdi), DATA
+	movups (%rsi), SHASH
+	movaps .Lbswap_mask, BSWAP
+	PSHUFB_XMM BSWAP DATA
+	call __clmul_gf128mul_ble
+	PSHUFB_XMM BSWAP DATA
+	movups DATA, (%rdi)
+	ret
+
+/*
+ * void clmul_ghash_update(char *dst, const char *src, unsigned int srclen,
+ *			   const be128 *shash);
+ */
+ENTRY(clmul_ghash_update)
+	cmp $16, %rdx
+	jb .Lupdate_just_ret	# check length
+	movaps .Lbswap_mask, BSWAP
+	movups (%rdi), DATA
+	movups (%rcx), SHASH
+	PSHUFB_XMM BSWAP DATA
+.align 4
+.Lupdate_loop:
+	movups (%rsi), IN1
+	PSHUFB_XMM BSWAP IN1
+	pxor IN1, DATA
+	call __clmul_gf128mul_ble
+	sub $16, %rdx
+	add $16, %rsi
+	cmp $16, %rdx
+	jge .Lupdate_loop
+	PSHUFB_XMM BSWAP DATA
+	movups DATA, (%rdi)
+.Lupdate_just_ret:
+	ret
+
+/*
+ * void clmul_ghash_setkey(be128 *shash, const u8 *key);
+ *
+ * Calculate hash_key << 1 mod poly
+ */
+ENTRY(clmul_ghash_setkey)
+	movaps .Lbswap_mask, BSWAP
+	movups (%rsi), %xmm0
+	PSHUFB_XMM BSWAP %xmm0
+	movaps %xmm0, %xmm1
+	psllq $1, %xmm0
+	psrlq $63, %xmm1
+	movaps %xmm1, %xmm2
+	pslldq $8, %xmm1
+	psrldq $8, %xmm2
+	por %xmm1, %xmm0
+	# reduction
+	pshufd $0b00100100, %xmm2, %xmm1
+	pcmpeqd .Ltwo_one, %xmm1
+	pand .Lpoly, %xmm1
+	pxor %xmm1, %xmm0
+	movups %xmm0, (%rdi)
+	ret
diff --git a/arch/x86/crypto/ghash-clmulni-intel_glue.c b/arch/x86/crypto/ghash-clmulni-intel_glue.c
new file mode 100644
index 0000000..cbcc8d8
--- /dev/null
+++ b/arch/x86/crypto/ghash-clmulni-intel_glue.c
@@ -0,0 +1,333 @@
+/*
+ * Accelerated GHASH implementation with Intel PCLMULQDQ-NI
+ * instructions. This file contains glue code.
+ *
+ * Copyright (c) 2009 Intel Corp.
+ *   Author: Huang Ying <ying.huang@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.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/crypto.h>
+#include <crypto/algapi.h>
+#include <crypto/cryptd.h>
+#include <crypto/gf128mul.h>
+#include <crypto/internal/hash.h>
+#include <asm/i387.h>
+
+#define GHASH_BLOCK_SIZE	16
+#define GHASH_DIGEST_SIZE	16
+
+void clmul_ghash_mul(char *dst, const be128 *shash);
+
+void clmul_ghash_update(char *dst, const char *src, unsigned int srclen,
+			const be128 *shash);
+
+void clmul_ghash_setkey(be128 *shash, const u8 *key);
+
+struct ghash_async_ctx {
+	struct cryptd_ahash *cryptd_tfm;
+};
+
+struct ghash_ctx {
+	be128 shash;
+};
+
+struct ghash_desc_ctx {
+	u8 buffer[GHASH_BLOCK_SIZE];
+	u32 bytes;
+};
+
+static int ghash_init(struct shash_desc *desc)
+{
+	struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
+
+	memset(dctx, 0, sizeof(*dctx));
+
+	return 0;
+}
+
+static int ghash_setkey(struct crypto_shash *tfm,
+			const u8 *key, unsigned int keylen)
+{
+	struct ghash_ctx *ctx = crypto_shash_ctx(tfm);
+
+	if (keylen != GHASH_BLOCK_SIZE) {
+		crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
+		return -EINVAL;
+	}
+
+	clmul_ghash_setkey(&ctx->shash, key);
+
+	return 0;
+}
+
+static int ghash_update(struct shash_desc *desc,
+			 const u8 *src, unsigned int srclen)
+{
+	struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
+	struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
+	u8 *dst = dctx->buffer;
+
+	kernel_fpu_begin();
+	if (dctx->bytes) {
+		int n = min(srclen, dctx->bytes);
+		u8 *pos = dst + (GHASH_BLOCK_SIZE - dctx->bytes);
+
+		dctx->bytes -= n;
+		srclen -= n;
+
+		while (n--)
+			*pos++ ^= *src++;
+
+		if (!dctx->bytes)
+			clmul_ghash_mul(dst, &ctx->shash);
+	}
+
+	clmul_ghash_update(dst, src, srclen, &ctx->shash);
+	kernel_fpu_end();
+
+	if (srclen & 0xf) {
+		src += srclen - (srclen & 0xf);
+		srclen &= 0xf;
+		dctx->bytes = GHASH_BLOCK_SIZE - srclen;
+		while (srclen--)
+			*dst++ ^= *src++;
+	}
+
+	return 0;
+}
+
+static void ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx)
+{
+	u8 *dst = dctx->buffer;
+
+	if (dctx->bytes) {
+		u8 *tmp = dst + (GHASH_BLOCK_SIZE - dctx->bytes);
+
+		while (dctx->bytes--)
+			*tmp++ ^= 0;
+
+		kernel_fpu_begin();
+		clmul_ghash_mul(dst, &ctx->shash);
+		kernel_fpu_end();
+	}
+
+	dctx->bytes = 0;
+}
+
+static int ghash_final(struct shash_desc *desc, u8 *dst)
+{
+	struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
+	struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
+	u8 *buf = dctx->buffer;
+
+	ghash_flush(ctx, dctx);
+	memcpy(dst, buf, GHASH_BLOCK_SIZE);
+
+	return 0;
+}
+
+static struct shash_alg ghash_alg = {
+	.digestsize	= GHASH_DIGEST_SIZE,
+	.init		= ghash_init,
+	.update		= ghash_update,
+	.final		= ghash_final,
+	.setkey		= ghash_setkey,
+	.descsize	= sizeof(struct ghash_desc_ctx),
+	.base		= {
+		.cra_name		= "__ghash",
+		.cra_driver_name	= "__ghash-pclmulqdqni",
+		.cra_priority		= 0,
+		.cra_flags		= CRYPTO_ALG_TYPE_SHASH,
+		.cra_blocksize		= GHASH_BLOCK_SIZE,
+		.cra_ctxsize		= sizeof(struct ghash_ctx),
+		.cra_module		= THIS_MODULE,
+		.cra_list		= LIST_HEAD_INIT(ghash_alg.base.cra_list),
+	},
+};
+
+static int ghash_async_init(struct ahash_request *req)
+{
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
+	struct ahash_request *cryptd_req = ahash_request_ctx(req);
+	struct cryptd_ahash *cryptd_tfm = ctx->cryptd_tfm;
+
+	if (!irq_fpu_usable()) {
+		memcpy(cryptd_req, req, sizeof(*req));
+		ahash_request_set_tfm(cryptd_req, &cryptd_tfm->base);
+		return crypto_ahash_init(cryptd_req);
+	} else {
+		struct shash_desc *desc = cryptd_shash_desc(cryptd_req);
+		struct crypto_shash *child = cryptd_ahash_child(cryptd_tfm);
+
+		desc->tfm = child;
+		desc->flags = req->base.flags;
+		return crypto_shash_init(desc);
+	}
+}
+
+static int ghash_async_update(struct ahash_request *req)
+{
+	struct ahash_request *cryptd_req = ahash_request_ctx(req);
+
+	if (!irq_fpu_usable()) {
+		struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+		struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
+		struct cryptd_ahash *cryptd_tfm = ctx->cryptd_tfm;
+
+		memcpy(cryptd_req, req, sizeof(*req));
+		ahash_request_set_tfm(cryptd_req, &cryptd_tfm->base);
+		return crypto_ahash_update(cryptd_req);
+	} else {
+		struct shash_desc *desc = cryptd_shash_desc(cryptd_req);
+		return shash_ahash_update(req, desc);
+	}
+}
+
+static int ghash_async_final(struct ahash_request *req)
+{
+	struct ahash_request *cryptd_req = ahash_request_ctx(req);
+
+	if (!irq_fpu_usable()) {
+		struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+		struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
+		struct cryptd_ahash *cryptd_tfm = ctx->cryptd_tfm;
+
+		memcpy(cryptd_req, req, sizeof(*req));
+		ahash_request_set_tfm(cryptd_req, &cryptd_tfm->base);
+		return crypto_ahash_final(cryptd_req);
+	} else {
+		struct shash_desc *desc = cryptd_shash_desc(cryptd_req);
+		return crypto_shash_final(desc, req->result);
+	}
+}
+
+static int ghash_async_digest(struct ahash_request *req)
+{
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
+	struct ahash_request *cryptd_req = ahash_request_ctx(req);
+	struct cryptd_ahash *cryptd_tfm = ctx->cryptd_tfm;
+
+	if (!irq_fpu_usable()) {
+		memcpy(cryptd_req, req, sizeof(*req));
+		ahash_request_set_tfm(cryptd_req, &cryptd_tfm->base);
+		return crypto_ahash_digest(cryptd_req);
+	} else {
+		struct shash_desc *desc = cryptd_shash_desc(cryptd_req);
+		struct crypto_shash *child = cryptd_ahash_child(cryptd_tfm);
+
+		desc->tfm = child;
+		desc->flags = req->base.flags;
+		return shash_ahash_digest(req, desc);
+	}
+}
+
+static int ghash_async_setkey(struct crypto_ahash *tfm, const u8 *key,
+			      unsigned int keylen)
+{
+	struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
+	struct crypto_ahash *child = &ctx->cryptd_tfm->base;
+	int err;
+
+	crypto_ahash_clear_flags(child, CRYPTO_TFM_REQ_MASK);
+	crypto_ahash_set_flags(child, crypto_ahash_get_flags(tfm)
+			       & CRYPTO_TFM_REQ_MASK);
+	err = crypto_ahash_setkey(child, key, keylen);
+	crypto_ahash_set_flags(tfm, crypto_ahash_get_flags(child)
+			       & CRYPTO_TFM_RES_MASK);
+
+	return 0;
+}
+
+static int ghash_async_init_tfm(struct crypto_tfm *tfm)
+{
+	struct cryptd_ahash *cryptd_tfm;
+	struct ghash_async_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	cryptd_tfm = cryptd_alloc_ahash("__ghash-pclmulqdqni", 0, 0);
+	if (IS_ERR(cryptd_tfm))
+		return PTR_ERR(cryptd_tfm);
+	ctx->cryptd_tfm = cryptd_tfm;
+	crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
+				 sizeof(struct ahash_request) +
+				 crypto_ahash_reqsize(&cryptd_tfm->base));
+
+	return 0;
+}
+
+static void ghash_async_exit_tfm(struct crypto_tfm *tfm)
+{
+	struct ghash_async_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	cryptd_free_ahash(ctx->cryptd_tfm);
+}
+
+static struct ahash_alg ghash_async_alg = {
+	.init		= ghash_async_init,
+	.update		= ghash_async_update,
+	.final		= ghash_async_final,
+	.setkey		= ghash_async_setkey,
+	.digest		= ghash_async_digest,
+	.halg = {
+		.digestsize	= GHASH_DIGEST_SIZE,
+		.base = {
+			.cra_name		= "ghash",
+			.cra_driver_name	= "ghash-clmulni",
+			.cra_priority		= 400,
+			.cra_flags		= CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC,
+			.cra_blocksize		= GHASH_BLOCK_SIZE,
+			.cra_type		= &crypto_ahash_type,
+			.cra_module		= THIS_MODULE,
+			.cra_list		= LIST_HEAD_INIT(ghash_async_alg.halg.base.cra_list),
+			.cra_init		= ghash_async_init_tfm,
+			.cra_exit		= ghash_async_exit_tfm,
+		},
+	},
+};
+
+static int __init ghash_pclmulqdqni_mod_init(void)
+{
+	int err;
+
+	if (!cpu_has_pclmulqdq) {
+		printk(KERN_INFO "Intel PCLMULQDQ-NI instructions are not"
+		       " detected.\n");
+		return -ENODEV;
+	}
+
+	err = crypto_register_shash(&ghash_alg);
+	if (err)
+		goto err_out;
+	err = crypto_register_ahash(&ghash_async_alg);
+	if (err)
+		goto err_shash;
+
+	return 0;
+
+err_shash:
+	crypto_unregister_shash(&ghash_alg);
+err_out:
+	return err;
+}
+
+static void __exit ghash_pclmulqdqni_mod_exit(void)
+{
+	crypto_unregister_ahash(&ghash_async_alg);
+	crypto_unregister_shash(&ghash_alg);
+}
+
+module_init(ghash_pclmulqdqni_mod_init);
+module_exit(ghash_pclmulqdqni_mod_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("GHASH Message Digest Algorithm, "
+		   "acclerated by PCLMULQDQ-NI");
+MODULE_ALIAS("ghash");
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index 4eefdca..53147ad 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -696,7 +696,7 @@
 	.quad quiet_ni_syscall		/* streams2 */
 	.quad stub32_vfork            /* 190 */
 	.quad compat_sys_getrlimit
-	.quad sys32_mmap2
+	.quad sys_mmap_pgoff
 	.quad sys32_truncate64
 	.quad sys32_ftruncate64
 	.quad sys32_stat64		/* 195 */
diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c
index df82c0e..422572c 100644
--- a/arch/x86/ia32/sys_ia32.c
+++ b/arch/x86/ia32/sys_ia32.c
@@ -155,9 +155,6 @@
 asmlinkage long sys32_mmap(struct mmap_arg_struct __user *arg)
 {
 	struct mmap_arg_struct a;
-	struct file *file = NULL;
-	unsigned long retval;
-	struct mm_struct *mm ;
 
 	if (copy_from_user(&a, arg, sizeof(a)))
 		return -EFAULT;
@@ -165,22 +162,8 @@
 	if (a.offset & ~PAGE_MASK)
 		return -EINVAL;
 
-	if (!(a.flags & MAP_ANONYMOUS)) {
-		file = fget(a.fd);
-		if (!file)
-			return -EBADF;
-	}
-
-	mm = current->mm;
-	down_write(&mm->mmap_sem);
-	retval = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags,
+	return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
 			       a.offset>>PAGE_SHIFT);
-	if (file)
-		fput(file);
-
-	up_write(&mm->mmap_sem);
-
-	return retval;
 }
 
 asmlinkage long sys32_mprotect(unsigned long start, size_t len,
@@ -483,30 +466,6 @@
 	return ret;
 }
 
-asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
-			    unsigned long prot, unsigned long flags,
-			    unsigned long fd, unsigned long pgoff)
-{
-	struct mm_struct *mm = current->mm;
-	unsigned long error;
-	struct file *file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			return -EBADF;
-	}
-
-	down_write(&mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&mm->mmap_sem);
-
-	if (file)
-		fput(file);
-	return error;
-}
-
 asmlinkage long sys32_olduname(struct oldold_utsname __user *name)
 {
 	char *arch = "x86_64";
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
index 4518dc5..60d2b2d 100644
--- a/arch/x86/include/asm/acpi.h
+++ b/arch/x86/include/asm/acpi.h
@@ -118,7 +118,7 @@
 extern unsigned long acpi_wakeup_address;
 
 /* early initialization routine */
-extern void acpi_reserve_bootmem(void);
+extern void acpi_reserve_wakeup_memory(void);
 
 /*
  * Check if the CPU can handle C2 and deeper
@@ -158,6 +158,7 @@
 
 #ifdef CONFIG_ACPI_NUMA
 extern int acpi_numa;
+extern int acpi_get_nodes(struct bootnode *physnodes);
 extern int acpi_scan_nodes(unsigned long start, unsigned long end);
 #define NR_NODE_MEMBLKS (MAX_NUMNODES*2)
 extern void acpi_fake_nodes(const struct bootnode *fake_nodes,
diff --git a/arch/x86/include/asm/cache.h b/arch/x86/include/asm/cache.h
index 549860d..2f9047c 100644
--- a/arch/x86/include/asm/cache.h
+++ b/arch/x86/include/asm/cache.h
@@ -9,12 +9,13 @@
 
 #define __read_mostly __attribute__((__section__(".data.read_mostly")))
 
+#define INTERNODE_CACHE_SHIFT CONFIG_X86_INTERNODE_CACHE_SHIFT
+#define INTERNODE_CACHE_BYTES (1 << INTERNODE_CACHE_SHIFT)
+
 #ifdef CONFIG_X86_VSMP
-/* vSMP Internode cacheline shift */
-#define INTERNODE_CACHE_SHIFT (12)
 #ifdef CONFIG_SMP
 #define __cacheline_aligned_in_smp					\
-	__attribute__((__aligned__(1 << (INTERNODE_CACHE_SHIFT))))	\
+	__attribute__((__aligned__(INTERNODE_CACHE_BYTES)))		\
 	__page_aligned_data
 #endif
 #endif
diff --git a/arch/x86/include/asm/cacheflush.h b/arch/x86/include/asm/cacheflush.h
index 9076add..634c40a 100644
--- a/arch/x86/include/asm/cacheflush.h
+++ b/arch/x86/include/asm/cacheflush.h
@@ -177,6 +177,7 @@
 #ifdef CONFIG_DEBUG_RODATA
 void mark_rodata_ro(void);
 extern const int rodata_test_data;
+extern int kernel_set_to_readonly;
 void set_kernel_text_rw(void);
 void set_kernel_text_ro(void);
 #else
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 9cfc88b..613700f 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -248,6 +248,7 @@
 #define cpu_has_x2apic		boot_cpu_has(X86_FEATURE_X2APIC)
 #define cpu_has_xsave		boot_cpu_has(X86_FEATURE_XSAVE)
 #define cpu_has_hypervisor	boot_cpu_has(X86_FEATURE_HYPERVISOR)
+#define cpu_has_pclmulqdq	boot_cpu_has(X86_FEATURE_PCLMULQDQ)
 
 #if defined(CONFIG_X86_INVLPG) || defined(CONFIG_X86_64)
 # define cpu_has_invlpg		1
diff --git a/arch/x86/include/asm/desc_defs.h b/arch/x86/include/asm/desc_defs.h
index 9d66848..278441f 100644
--- a/arch/x86/include/asm/desc_defs.h
+++ b/arch/x86/include/asm/desc_defs.h
@@ -12,9 +12,9 @@
 #include <linux/types.h>
 
 /*
- * FIXME: Acessing the desc_struct through its fields is more elegant,
+ * FIXME: Accessing the desc_struct through its fields is more elegant,
  * and should be the one valid thing to do. However, a lot of open code
- * still touches the a and b acessors, and doing this allow us to do it
+ * still touches the a and b accessors, and doing this allow us to do it
  * incrementally. We keep the signature as a struct, rather than an union,
  * so we can get rid of it transparently in the future -- glommer
  */
diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index 40b4e61..761249e 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -61,6 +61,12 @@
 	struct e820entry map[E820_X_MAX];
 };
 
+#define ISA_START_ADDRESS	0xa0000
+#define ISA_END_ADDRESS		0x100000
+
+#define BIOS_BEGIN		0x000a0000
+#define BIOS_END		0x00100000
+
 #ifdef __KERNEL__
 /* see comment in arch/x86/kernel/e820.c */
 extern struct e820map e820;
@@ -126,16 +132,19 @@
 extern void e820_reserve_resources_late(void);
 extern void setup_memory_map(void);
 extern char *default_machine_specific_memory_setup(void);
+
+/*
+ * Returns true iff the specified range [s,e) is completely contained inside
+ * the ISA region.
+ */
+static inline bool is_ISA_range(u64 s, u64 e)
+{
+	return s >= ISA_START_ADDRESS && e <= ISA_END_ADDRESS;
+}
+
 #endif /* __KERNEL__ */
 #endif /* __ASSEMBLY__ */
 
-#define ISA_START_ADDRESS	0xa0000
-#define ISA_END_ADDRESS		0x100000
-#define is_ISA_range(s, e) ((s) >= ISA_START_ADDRESS && (e) < ISA_END_ADDRESS)
-
-#define BIOS_BEGIN		0x000a0000
-#define BIOS_END		0x00100000
-
 #ifdef __KERNEL__
 #include <linux/ioport.h>
 
diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index 456a304..8a024ba 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -157,19 +157,6 @@
 
 #define compat_elf_check_arch(x)	elf_check_arch_ia32(x)
 
-static inline void start_ia32_thread(struct pt_regs *regs, u32 ip, u32 sp)
-{
-	loadsegment(fs, 0);
-	loadsegment(ds, __USER32_DS);
-	loadsegment(es, __USER32_DS);
-	load_gs_index(0);
-	regs->ip = ip;
-	regs->sp = sp;
-	regs->flags = X86_EFLAGS_IF;
-	regs->cs = __USER32_CS;
-	regs->ss = __USER32_DS;
-}
-
 static inline void elf_common_init(struct thread_struct *t,
 				   struct pt_regs *regs, const u16 ds)
 {
@@ -191,11 +178,8 @@
 #define	COMPAT_ELF_PLAT_INIT(regs, load_addr)		\
 	elf_common_init(&current->thread, regs, __USER_DS)
 
-#define	compat_start_thread(regs, ip, sp)		\
-do {							\
-	start_ia32_thread(regs, ip, sp);		\
-	set_fs(USER_DS);				\
-} while (0)
+void start_thread_ia32(struct pt_regs *regs, u32 new_ip, u32 new_sp);
+#define compat_start_thread start_thread_ia32
 
 #define COMPAT_SET_PERSONALITY(ex)			\
 do {							\
diff --git a/arch/x86/include/asm/entry_arch.h b/arch/x86/include/asm/entry_arch.h
index f5693c8..8e8ec66 100644
--- a/arch/x86/include/asm/entry_arch.h
+++ b/arch/x86/include/asm/entry_arch.h
@@ -34,7 +34,7 @@
 		 smp_invalidate_interrupt)
 #endif
 
-BUILD_INTERRUPT(generic_interrupt, GENERIC_INTERRUPT_VECTOR)
+BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR)
 
 /*
  * every pentium local APIC has two 'local interrupts', with a
diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
index 108eb6f..0f85764 100644
--- a/arch/x86/include/asm/hardirq.h
+++ b/arch/x86/include/asm/hardirq.h
@@ -12,7 +12,7 @@
 	unsigned int apic_timer_irqs;	/* arch dependent */
 	unsigned int irq_spurious_count;
 #endif
-	unsigned int generic_irqs;	/* arch dependent */
+	unsigned int x86_platform_ipis;	/* arch dependent */
 	unsigned int apic_perf_irqs;
 	unsigned int apic_pending_irqs;
 #ifdef CONFIG_SMP
diff --git a/arch/x86/include/asm/hpet.h b/arch/x86/include/asm/hpet.h
index 1c22cb0..5d89fd2 100644
--- a/arch/x86/include/asm/hpet.h
+++ b/arch/x86/include/asm/hpet.h
@@ -65,11 +65,12 @@
 /* hpet memory map physical address */
 extern unsigned long hpet_address;
 extern unsigned long force_hpet_address;
+extern u8 hpet_blockid;
 extern int hpet_force_user;
 extern int is_hpet_enabled(void);
 extern int hpet_enable(void);
 extern void hpet_disable(void);
-extern unsigned long hpet_readl(unsigned long a);
+extern unsigned int hpet_readl(unsigned int a);
 extern void force_hpet_resume(void);
 
 extern void hpet_msi_unmask(unsigned int irq);
@@ -78,9 +79,9 @@
 extern void hpet_msi_read(unsigned int irq, struct msi_msg *msg);
 
 #ifdef CONFIG_PCI_MSI
-extern int arch_setup_hpet_msi(unsigned int irq);
+extern int arch_setup_hpet_msi(unsigned int irq, unsigned int id);
 #else
-static inline int arch_setup_hpet_msi(unsigned int irq)
+static inline int arch_setup_hpet_msi(unsigned int irq, unsigned int id)
 {
 	return -EINVAL;
 }
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index 6e12426..08c48a8 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -27,7 +27,7 @@
 
 /* Interrupt handlers registered during init_IRQ */
 extern void apic_timer_interrupt(void);
-extern void generic_interrupt(void);
+extern void x86_platform_ipi(void);
 extern void error_interrupt(void);
 extern void perf_pending_interrupt(void);
 
@@ -119,7 +119,7 @@
 /* SMP */
 extern void smp_apic_timer_interrupt(struct pt_regs *);
 extern void smp_spurious_interrupt(struct pt_regs *);
-extern void smp_generic_interrupt(struct pt_regs *);
+extern void smp_x86_platform_ipi(struct pt_regs *);
 extern void smp_error_interrupt(struct pt_regs *);
 #ifdef CONFIG_X86_IO_APIC
 extern asmlinkage void smp_irq_move_cleanup_interrupt(void);
diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h
index 0b20bbb..ebfb8a9 100644
--- a/arch/x86/include/asm/i387.h
+++ b/arch/x86/include/asm/i387.h
@@ -10,6 +10,8 @@
 #ifndef _ASM_X86_I387_H
 #define _ASM_X86_I387_H
 
+#ifndef __ASSEMBLY__
+
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
 #include <linux/regset.h>
@@ -411,4 +413,9 @@
 	}
 }
 
+#endif /* __ASSEMBLY__ */
+
+#define PSHUFB_XMM5_XMM0 .byte 0x66, 0x0f, 0x38, 0x00, 0xc5
+#define PSHUFB_XMM5_XMM6 .byte 0x66, 0x0f, 0x38, 0x00, 0xf5
+
 #endif /* _ASM_X86_I387_H */
diff --git a/arch/x86/include/asm/inst.h b/arch/x86/include/asm/inst.h
new file mode 100644
index 0000000..14cf526
--- /dev/null
+++ b/arch/x86/include/asm/inst.h
@@ -0,0 +1,150 @@
+/*
+ * Generate .byte code for some instructions not supported by old
+ * binutils.
+ */
+#ifndef X86_ASM_INST_H
+#define X86_ASM_INST_H
+
+#ifdef __ASSEMBLY__
+
+	.macro XMM_NUM opd xmm
+	.ifc \xmm,%xmm0
+	\opd = 0
+	.endif
+	.ifc \xmm,%xmm1
+	\opd = 1
+	.endif
+	.ifc \xmm,%xmm2
+	\opd = 2
+	.endif
+	.ifc \xmm,%xmm3
+	\opd = 3
+	.endif
+	.ifc \xmm,%xmm4
+	\opd = 4
+	.endif
+	.ifc \xmm,%xmm5
+	\opd = 5
+	.endif
+	.ifc \xmm,%xmm6
+	\opd = 6
+	.endif
+	.ifc \xmm,%xmm7
+	\opd = 7
+	.endif
+	.ifc \xmm,%xmm8
+	\opd = 8
+	.endif
+	.ifc \xmm,%xmm9
+	\opd = 9
+	.endif
+	.ifc \xmm,%xmm10
+	\opd = 10
+	.endif
+	.ifc \xmm,%xmm11
+	\opd = 11
+	.endif
+	.ifc \xmm,%xmm12
+	\opd = 12
+	.endif
+	.ifc \xmm,%xmm13
+	\opd = 13
+	.endif
+	.ifc \xmm,%xmm14
+	\opd = 14
+	.endif
+	.ifc \xmm,%xmm15
+	\opd = 15
+	.endif
+	.endm
+
+	.macro PFX_OPD_SIZE
+	.byte 0x66
+	.endm
+
+	.macro PFX_REX opd1 opd2
+	.if (\opd1 | \opd2) & 8
+	.byte 0x40 | ((\opd1 & 8) >> 3) | ((\opd2 & 8) >> 1)
+	.endif
+	.endm
+
+	.macro MODRM mod opd1 opd2
+	.byte \mod | (\opd1 & 7) | ((\opd2 & 7) << 3)
+	.endm
+
+	.macro PSHUFB_XMM xmm1 xmm2
+	XMM_NUM pshufb_opd1 \xmm1
+	XMM_NUM pshufb_opd2 \xmm2
+	PFX_OPD_SIZE
+	PFX_REX pshufb_opd1 pshufb_opd2
+	.byte 0x0f, 0x38, 0x00
+	MODRM 0xc0 pshufb_opd1 pshufb_opd2
+	.endm
+
+	.macro PCLMULQDQ imm8 xmm1 xmm2
+	XMM_NUM clmul_opd1 \xmm1
+	XMM_NUM clmul_opd2 \xmm2
+	PFX_OPD_SIZE
+	PFX_REX clmul_opd1 clmul_opd2
+	.byte 0x0f, 0x3a, 0x44
+	MODRM 0xc0 clmul_opd1 clmul_opd2
+	.byte \imm8
+	.endm
+
+	.macro AESKEYGENASSIST rcon xmm1 xmm2
+	XMM_NUM aeskeygen_opd1 \xmm1
+	XMM_NUM aeskeygen_opd2 \xmm2
+	PFX_OPD_SIZE
+	PFX_REX aeskeygen_opd1 aeskeygen_opd2
+	.byte 0x0f, 0x3a, 0xdf
+	MODRM 0xc0 aeskeygen_opd1 aeskeygen_opd2
+	.byte \rcon
+	.endm
+
+	.macro AESIMC xmm1 xmm2
+	XMM_NUM aesimc_opd1 \xmm1
+	XMM_NUM aesimc_opd2 \xmm2
+	PFX_OPD_SIZE
+	PFX_REX aesimc_opd1 aesimc_opd2
+	.byte 0x0f, 0x38, 0xdb
+	MODRM 0xc0 aesimc_opd1 aesimc_opd2
+	.endm
+
+	.macro AESENC xmm1 xmm2
+	XMM_NUM aesenc_opd1 \xmm1
+	XMM_NUM aesenc_opd2 \xmm2
+	PFX_OPD_SIZE
+	PFX_REX aesenc_opd1 aesenc_opd2
+	.byte 0x0f, 0x38, 0xdc
+	MODRM 0xc0 aesenc_opd1 aesenc_opd2
+	.endm
+
+	.macro AESENCLAST xmm1 xmm2
+	XMM_NUM aesenclast_opd1 \xmm1
+	XMM_NUM aesenclast_opd2 \xmm2
+	PFX_OPD_SIZE
+	PFX_REX aesenclast_opd1 aesenclast_opd2
+	.byte 0x0f, 0x38, 0xdd
+	MODRM 0xc0 aesenclast_opd1 aesenclast_opd2
+	.endm
+
+	.macro AESDEC xmm1 xmm2
+	XMM_NUM aesdec_opd1 \xmm1
+	XMM_NUM aesdec_opd2 \xmm2
+	PFX_OPD_SIZE
+	PFX_REX aesdec_opd1 aesdec_opd2
+	.byte 0x0f, 0x38, 0xde
+	MODRM 0xc0 aesdec_opd1 aesdec_opd2
+	.endm
+
+	.macro AESDECLAST xmm1 xmm2
+	XMM_NUM aesdeclast_opd1 \xmm1
+	XMM_NUM aesdeclast_opd2 \xmm2
+	PFX_OPD_SIZE
+	PFX_REX aesdeclast_opd1 aesdeclast_opd2
+	.byte 0x0f, 0x38, 0xdf
+	MODRM 0xc0 aesdeclast_opd1 aesdeclast_opd2
+	.endm
+#endif
+
+#endif
diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
index ffd700f..5458380 100644
--- a/arch/x86/include/asm/irq.h
+++ b/arch/x86/include/asm/irq.h
@@ -37,7 +37,7 @@
 extern void irq_force_complete_move(int);
 #endif
 
-extern void (*generic_interrupt_extension)(void);
+extern void (*x86_platform_ipi_callback)(void);
 extern void native_init_IRQ(void);
 extern bool handle_irq(unsigned irq, struct pt_regs *regs);
 
diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h
index 5b21f0e..6a635bd 100644
--- a/arch/x86/include/asm/irq_vectors.h
+++ b/arch/x86/include/asm/irq_vectors.h
@@ -106,7 +106,7 @@
 /*
  * Generic system vector for platform specific use
  */
-#define GENERIC_INTERRUPT_VECTOR	0xed
+#define X86_PLATFORM_IPI_VECTOR		0xed
 
 /*
  * Performance monitoring pending work vector:
diff --git a/arch/x86/include/asm/k8.h b/arch/x86/include/asm/k8.h
index c2d1f3b..f70e600 100644
--- a/arch/x86/include/asm/k8.h
+++ b/arch/x86/include/asm/k8.h
@@ -4,13 +4,16 @@
 #include <linux/pci.h>
 
 extern struct pci_device_id k8_nb_ids[];
+struct bootnode;
 
 extern int early_is_k8_nb(u32 value);
 extern struct pci_dev **k8_northbridges;
 extern int num_k8_northbridges;
 extern int cache_k8_northbridges(void);
 extern void k8_flush_garts(void);
-extern int k8_scan_nodes(unsigned long start, unsigned long end);
+extern int k8_get_nodes(struct bootnode *nodes);
+extern int k8_numa_init(unsigned long start_pfn, unsigned long end_pfn);
+extern int k8_scan_nodes(void);
 
 #ifdef CONFIG_K8_NB
 static inline struct pci_dev *node_to_k8_nb_misc(int node)
diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
index ef51b50..c24ca9a 100644
--- a/arch/x86/include/asm/microcode.h
+++ b/arch/x86/include/asm/microcode.h
@@ -12,6 +12,8 @@
 enum ucode_state { UCODE_ERROR, UCODE_OK, UCODE_NFOUND };
 
 struct microcode_ops {
+	void (*init)(struct device *device);
+	void (*fini)(void);
 	enum ucode_state (*request_microcode_user) (int cpu,
 				const void __user *buf, size_t size);
 
diff --git a/arch/x86/include/asm/mmzone_32.h b/arch/x86/include/asm/mmzone_32.h
index ede6998..91df7c5 100644
--- a/arch/x86/include/asm/mmzone_32.h
+++ b/arch/x86/include/asm/mmzone_32.h
@@ -47,7 +47,7 @@
 /*
  * generic node memory support, the following assumptions apply:
  *
- * 1) memory comes in 64Mb contigious chunks which are either present or not
+ * 1) memory comes in 64Mb contiguous chunks which are either present or not
  * 2) we will not have more than 64Gb in total
  *
  * for now assume that 64Gb is max amount of RAM for whole system
diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index 61d90b1..d8bf23a 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -71,12 +71,7 @@
 
 static inline void find_smp_config(void)
 {
-	x86_init.mpparse.find_smp_config(1);
-}
-
-static inline void early_find_smp_config(void)
-{
-	x86_init.mpparse.find_smp_config(0);
+	x86_init.mpparse.find_smp_config();
 }
 
 #ifdef CONFIG_X86_MPPARSE
@@ -89,7 +84,7 @@
 # else
 #  define default_mpc_oem_bus_info NULL
 # endif
-extern void default_find_smp_config(unsigned int reserve);
+extern void default_find_smp_config(void);
 extern void default_get_smp_config(unsigned int early);
 #else
 static inline void early_reserve_e820_mpc_new(void) { }
@@ -97,7 +92,7 @@
 #define default_mpc_apic_id NULL
 #define default_smp_read_mpc_oem NULL
 #define default_mpc_oem_bus_info NULL
-#define default_find_smp_config x86_init_uint_noop
+#define default_find_smp_config x86_init_noop
 #define default_get_smp_config x86_init_uint_noop
 #endif
 
diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h
index 6473f5c..642fe34 100644
--- a/arch/x86/include/asm/page_types.h
+++ b/arch/x86/include/asm/page_types.h
@@ -49,7 +49,8 @@
 extern unsigned long init_memory_mapping(unsigned long start,
 					 unsigned long end);
 
-extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn);
+extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn,
+				int acpi, int k8);
 extern void free_initmem(void);
 
 #endif	/* !__ASSEMBLY__ */
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index b399988..b4bf9a9 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -118,11 +118,27 @@
 
 /* pci-mmconfig.c */
 
+/* "PCI MMCONFIG %04x [bus %02x-%02x]" */
+#define PCI_MMCFG_RESOURCE_NAME_LEN (22 + 4 + 2 + 2)
+
+struct pci_mmcfg_region {
+	struct list_head list;
+	struct resource res;
+	u64 address;
+	char __iomem *virt;
+	u16 segment;
+	u8 start_bus;
+	u8 end_bus;
+	char name[PCI_MMCFG_RESOURCE_NAME_LEN];
+};
+
 extern int __init pci_mmcfg_arch_init(void);
 extern void __init pci_mmcfg_arch_free(void);
+extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus);
 
-extern struct acpi_mcfg_allocation *pci_mmcfg_config;
-extern int pci_mmcfg_config_num;
+extern struct list_head pci_mmcfg_list;
+
+#define PCI_MMCFG_BUS_OFFSET(bus)      ((bus) << 20)
 
 /*
  * AMD Fam10h CPUs are buggy, and cannot access MMIO config space
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index af6fd36..a34c785 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -16,6 +16,8 @@
 
 #ifndef __ASSEMBLY__
 
+#include <asm/x86_init.h>
+
 /*
  * ZERO_PAGE is a global shared page that is always zero: used
  * for zero-mapped memory areas etc..
@@ -270,9 +272,9 @@
 					 unsigned long new_flags)
 {
 	/*
-	 * PAT type is always WB for ISA. So no need to check.
+	 * PAT type is always WB for untracked ranges, so no need to check.
 	 */
-	if (is_ISA_range(paddr, paddr + size - 1))
+	if (x86_platform.is_untracked_pat_range(paddr, paddr + size))
 		return 1;
 
 	/*
diff --git a/arch/x86/include/asm/proto.h b/arch/x86/include/asm/proto.h
index 621f56d..4009f65 100644
--- a/arch/x86/include/asm/proto.h
+++ b/arch/x86/include/asm/proto.h
@@ -5,18 +5,19 @@
 
 /* misc architecture specific prototypes */
 
-extern void early_idt_handler(void);
+void early_idt_handler(void);
 
-extern void system_call(void);
-extern void syscall_init(void);
+void system_call(void);
+void syscall_init(void);
 
-extern void ia32_syscall(void);
-extern void ia32_cstar_target(void);
-extern void ia32_sysenter_target(void);
+void ia32_syscall(void);
+void ia32_cstar_target(void);
+void ia32_sysenter_target(void);
 
-extern void syscall32_cpu_init(void);
+void syscall32_cpu_init(void);
 
-extern void check_efer(void);
+void x86_configure_nx(void);
+void x86_report_nx(void);
 
 extern int reboot_force;
 
diff --git a/arch/x86/include/asm/sections.h b/arch/x86/include/asm/sections.h
index 1b7ee5d..0a52424 100644
--- a/arch/x86/include/asm/sections.h
+++ b/arch/x86/include/asm/sections.h
@@ -2,7 +2,13 @@
 #define _ASM_X86_SECTIONS_H
 
 #include <asm-generic/sections.h>
+#include <asm/uaccess.h>
 
 extern char __brk_base[], __brk_limit[];
+extern struct exception_table_entry __stop___ex_table[];
+
+#if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA)
+extern char __end_rodata_hpage_align[];
+#endif
 
 #endif	/* _ASM_X86_SECTIONS_H */
diff --git a/arch/x86/include/asm/sigcontext.h b/arch/x86/include/asm/sigcontext.h
index 72e5a44..04459d2 100644
--- a/arch/x86/include/asm/sigcontext.h
+++ b/arch/x86/include/asm/sigcontext.h
@@ -124,7 +124,7 @@
 	 * fpstate is really (struct _fpstate *) or (struct _xstate *)
 	 * depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved
 	 * bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end
-	 * of extended memory layout. See comments at the defintion of
+	 * of extended memory layout. See comments at the definition of
 	 * (struct _fpx_sw_bytes)
 	 */
 	void __user *fpstate;		/* zero when no FPU/extended context */
@@ -219,7 +219,7 @@
 	 * fpstate is really (struct _fpstate *) or (struct _xstate *)
 	 * depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved
 	 * bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end
-	 * of extended memory layout. See comments at the defintion of
+	 * of extended memory layout. See comments at the definition of
 	 * (struct _fpx_sw_bytes)
 	 */
 	void __user *fpstate;		/* zero when no FPU/extended context */
diff --git a/arch/x86/include/asm/sys_ia32.h b/arch/x86/include/asm/sys_ia32.h
index 9af9dec..4a5a089e 100644
--- a/arch/x86/include/asm/sys_ia32.h
+++ b/arch/x86/include/asm/sys_ia32.h
@@ -57,9 +57,6 @@
 asmlinkage long sys32_personality(unsigned long);
 asmlinkage long sys32_sendfile(int, int, compat_off_t __user *, s32);
 
-asmlinkage long sys32_mmap2(unsigned long, unsigned long, unsigned long,
-			    unsigned long, unsigned long, unsigned long);
-
 struct oldold_utsname;
 struct old_utsname;
 asmlinkage long sys32_olduname(struct oldold_utsname __user *);
diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h
index 372b76e..1bb6e39 100644
--- a/arch/x86/include/asm/syscalls.h
+++ b/arch/x86/include/asm/syscalls.h
@@ -55,8 +55,6 @@
 struct oldold_utsname;
 struct old_utsname;
 
-asmlinkage long sys_mmap2(unsigned long, unsigned long, unsigned long,
-			  unsigned long, unsigned long, unsigned long);
 asmlinkage int old_mmap(struct mmap_arg_struct __user *);
 asmlinkage int old_select(struct sel_arg_struct __user *);
 asmlinkage int sys_ipc(uint, int, int, int, void __user *, long);
diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h
index 80e2984..b414d2b 100644
--- a/arch/x86/include/asm/uv/uv_bau.h
+++ b/arch/x86/include/asm/uv/uv_bau.h
@@ -55,7 +55,7 @@
 #define DESC_STATUS_SOURCE_TIMEOUT	3
 
 /*
- * source side threshholds at which message retries print a warning
+ * source side thresholds at which message retries print a warning
  */
 #define SOURCE_TIMEOUT_LIMIT		20
 #define DESTINATION_TIMEOUT_LIMIT	20
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index d8e7145..ea0e8ea 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -26,7 +26,7 @@
 	void (*smp_read_mpc_oem)(struct mpc_table *mpc);
 	void (*mpc_oem_pci_bus)(struct mpc_bus *m);
 	void (*mpc_oem_bus_info)(struct mpc_bus *m, char *name);
-	void (*find_smp_config)(unsigned int reserve);
+	void (*find_smp_config)(void);
 	void (*get_smp_config)(unsigned int early);
 };
 
@@ -125,12 +125,14 @@
  * @calibrate_tsc:		calibrate TSC
  * @get_wallclock:		get time from HW clock like RTC etc.
  * @set_wallclock:		set time back to HW clock
+ * @is_untracked_pat_range	exclude from PAT logic
  */
 struct x86_platform_ops {
 	unsigned long (*calibrate_tsc)(void);
 	unsigned long (*get_wallclock)(void);
 	int (*set_wallclock)(unsigned long nowtime);
 	void (*iommu_shutdown)(void);
+	bool (*is_untracked_pat_range)(u64 start, u64 end);
 };
 
 extern struct x86_init_ops x86_init;
diff --git a/arch/x86/include/asm/xen/hypervisor.h b/arch/x86/include/asm/xen/hypervisor.h
index d5b7e90..396ff4c 100644
--- a/arch/x86/include/asm/xen/hypervisor.h
+++ b/arch/x86/include/asm/xen/hypervisor.h
@@ -37,31 +37,4 @@
 extern struct shared_info *HYPERVISOR_shared_info;
 extern struct start_info *xen_start_info;
 
-enum xen_domain_type {
-	XEN_NATIVE,		/* running on bare hardware    */
-	XEN_PV_DOMAIN,		/* running in a PV domain      */
-	XEN_HVM_DOMAIN,		/* running in a Xen hvm domain */
-};
-
-#ifdef CONFIG_XEN
-extern enum xen_domain_type xen_domain_type;
-#else
-#define xen_domain_type		XEN_NATIVE
-#endif
-
-#define xen_domain()		(xen_domain_type != XEN_NATIVE)
-#define xen_pv_domain()		(xen_domain() &&			\
-				 xen_domain_type == XEN_PV_DOMAIN)
-#define xen_hvm_domain()	(xen_domain() &&			\
-				 xen_domain_type == XEN_HVM_DOMAIN)
-
-#ifdef CONFIG_XEN_DOM0
-#include <xen/interface/xen.h>
-
-#define xen_initial_domain()	(xen_pv_domain() && \
-				 xen_start_info->flags & SIF_INITDOMAIN)
-#else  /* !CONFIG_XEN_DOM0 */
-#define xen_initial_domain()	(0)
-#endif	/* CONFIG_XEN_DOM0 */
-
 #endif /* _ASM_X86_XEN_HYPERVISOR_H */
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 67e929b..fb1035c 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -624,6 +624,7 @@
 	}
 
 	hpet_address = hpet_tbl->address.address;
+	hpet_blockid = hpet_tbl->sequence;
 
 	/*
 	 * Some broken BIOSes advertise HPET at 0x0. We really do not
@@ -1122,7 +1123,7 @@
 	if (!acpi_sci_override_gsi)
 		acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0);
 
-	/* Fill in identity legacy mapings where no override */
+	/* Fill in identity legacy mappings where no override */
 	mp_config_acpi_legacy_irqs();
 
 	count =
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index ca93638..82e5086 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -78,12 +78,9 @@
 #ifndef CONFIG_64BIT
 	store_gdt((struct desc_ptr *)&header->pmode_gdt);
 
-	header->pmode_efer_low = nx_enabled;
-	if (header->pmode_efer_low & 1) {
-		/* This is strange, why not save efer, always? */
-		rdmsr(MSR_EFER, header->pmode_efer_low,
-			header->pmode_efer_high);
-	}
+	if (rdmsr_safe(MSR_EFER, &header->pmode_efer_low,
+		       &header->pmode_efer_high))
+		header->pmode_efer_low = header->pmode_efer_high = 0;
 #endif /* !CONFIG_64BIT */
 
 	header->pmode_cr0 = read_cr0();
@@ -119,29 +116,32 @@
 
 
 /**
- * acpi_reserve_bootmem - do _very_ early ACPI initialisation
+ * acpi_reserve_wakeup_memory - do _very_ early ACPI initialisation
  *
  * We allocate a page from the first 1MB of memory for the wakeup
  * routine for when we come back from a sleep state. The
  * runtime allocator allows specification of <16MB pages, but not
  * <1MB pages.
  */
-void __init acpi_reserve_bootmem(void)
+void __init acpi_reserve_wakeup_memory(void)
 {
+	unsigned long mem;
+
 	if ((&wakeup_code_end - &wakeup_code_start) > WAKEUP_SIZE) {
 		printk(KERN_ERR
 		       "ACPI: Wakeup code way too big, S3 disabled.\n");
 		return;
 	}
 
-	acpi_realmode = (unsigned long)alloc_bootmem_low(WAKEUP_SIZE);
+	mem = find_e820_area(0, 1<<20, WAKEUP_SIZE, PAGE_SIZE);
 
-	if (!acpi_realmode) {
+	if (mem == -1L) {
 		printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n");
 		return;
 	}
-
-	acpi_wakeup_address = virt_to_phys((void *)acpi_realmode);
+	acpi_realmode = (unsigned long) phys_to_virt(mem);
+	acpi_wakeup_address = mem;
+	reserve_early(mem, mem + WAKEUP_SIZE, "ACPI WAKEUP");
 }
 
 
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index 32fb091..1c0fb4d 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -1783,7 +1783,7 @@
 			goto out;
 
 		/*
-		 * aperture was sucessfully enlarged by 128 MB, try
+		 * aperture was successfully enlarged by 128 MB, try
 		 * allocation again
 		 */
 		goto retry;
@@ -2490,7 +2490,7 @@
 	struct pci_dev *dev = NULL;
 	u16 devid;
 
-	/* allocate passthroug domain */
+	/* allocate passthrough domain */
 	pt_domain = protection_domain_alloc();
 	if (!pt_domain)
 		return -ENOMEM;
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
index 7ffc399..9c4a6f7 100644
--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -1336,6 +1336,9 @@
 		iommu_detected = 1;
 		amd_iommu_detected = 1;
 		x86_init.iommu.iommu_init = amd_iommu_init;
+
+		/* Make sure ACS will be enabled */
+		pci_request_acs();
 	}
 }
 
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index ad8c75b..efb2b9c 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -647,7 +647,7 @@
 	calibration_result = (delta * APIC_DIVISOR) / LAPIC_CAL_LOOPS;
 
 	apic_printk(APIC_VERBOSE, "..... delta %ld\n", delta);
-	apic_printk(APIC_VERBOSE, "..... mult: %ld\n", lapic_clockevent.mult);
+	apic_printk(APIC_VERBOSE, "..... mult: %u\n", lapic_clockevent.mult);
 	apic_printk(APIC_VERBOSE, "..... calibration result: %u\n",
 		    calibration_result);
 
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index c0b4468..d5d498f 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3267,7 +3267,8 @@
  * MSI message composition
  */
 #ifdef CONFIG_PCI_MSI
-static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
+static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq,
+			   struct msi_msg *msg, u8 hpet_id)
 {
 	struct irq_cfg *cfg;
 	int err;
@@ -3301,7 +3302,10 @@
 		irte.dest_id = IRTE_DEST(dest);
 
 		/* Set source-id of interrupt request */
-		set_msi_sid(&irte, pdev);
+		if (pdev)
+			set_msi_sid(&irte, pdev);
+		else
+			set_hpet_sid(&irte, hpet_id);
 
 		modify_irte(irq, &irte);
 
@@ -3466,7 +3470,7 @@
 	int ret;
 	struct msi_msg msg;
 
-	ret = msi_compose_msg(dev, irq, &msg);
+	ret = msi_compose_msg(dev, irq, &msg, -1);
 	if (ret < 0)
 		return ret;
 
@@ -3599,7 +3603,7 @@
 	int ret;
 	struct msi_msg msg;
 
-	ret = msi_compose_msg(NULL, irq, &msg);
+	ret = msi_compose_msg(NULL, irq, &msg, -1);
 	if (ret < 0)
 		return ret;
 	dmar_msi_write(irq, &msg);
@@ -3639,6 +3643,19 @@
 
 #endif /* CONFIG_SMP */
 
+static struct irq_chip ir_hpet_msi_type = {
+	.name = "IR-HPET_MSI",
+	.unmask = hpet_msi_unmask,
+	.mask = hpet_msi_mask,
+#ifdef CONFIG_INTR_REMAP
+	.ack = ir_ack_apic_edge,
+#ifdef CONFIG_SMP
+	.set_affinity = ir_set_msi_irq_affinity,
+#endif
+#endif
+	.retrigger = ioapic_retrigger_irq,
+};
+
 static struct irq_chip hpet_msi_type = {
 	.name = "HPET_MSI",
 	.unmask = hpet_msi_unmask,
@@ -3650,20 +3667,36 @@
 	.retrigger = ioapic_retrigger_irq,
 };
 
-int arch_setup_hpet_msi(unsigned int irq)
+int arch_setup_hpet_msi(unsigned int irq, unsigned int id)
 {
 	int ret;
 	struct msi_msg msg;
 	struct irq_desc *desc = irq_to_desc(irq);
 
-	ret = msi_compose_msg(NULL, irq, &msg);
+	if (intr_remapping_enabled) {
+		struct intel_iommu *iommu = map_hpet_to_ir(id);
+		int index;
+
+		if (!iommu)
+			return -1;
+
+		index = alloc_irte(iommu, irq, 1);
+		if (index < 0)
+			return -1;
+	}
+
+	ret = msi_compose_msg(NULL, irq, &msg, id);
 	if (ret < 0)
 		return ret;
 
 	hpet_msi_write(irq, &msg);
 	desc->status |= IRQ_MOVE_PCNTXT;
-	set_irq_chip_and_handler_name(irq, &hpet_msi_type, handle_edge_irq,
-		"edge");
+	if (irq_remapped(irq))
+		set_irq_chip_and_handler_name(irq, &ir_hpet_msi_type,
+					      handle_edge_irq, "edge");
+	else
+		set_irq_chip_and_handler_name(irq, &hpet_msi_type,
+					      handle_edge_irq, "edge");
 
 	return 0;
 }
diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c
index 07cdbdc..98c4665 100644
--- a/arch/x86/kernel/apic/numaq_32.c
+++ b/arch/x86/kernel/apic/numaq_32.c
@@ -264,11 +264,6 @@
 static __init void early_check_numaq(void)
 {
 	/*
-	 * Find possible boot-time SMP configuration:
-	 */
-	early_find_smp_config();
-
-	/*
 	 * get boot-time SMP configuration:
 	 */
 	if (smp_found_config)
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c
index 130c4b9..b684bb3 100644
--- a/arch/x86/kernel/apic/x2apic_uv_x.c
+++ b/arch/x86/kernel/apic/x2apic_uv_x.c
@@ -30,10 +30,22 @@
 #include <asm/apic.h>
 #include <asm/ipi.h>
 #include <asm/smp.h>
+#include <asm/x86_init.h>
 
 DEFINE_PER_CPU(int, x2apic_extra_bits);
 
 static enum uv_system_type uv_system_type;
+static u64 gru_start_paddr, gru_end_paddr;
+
+static inline bool is_GRU_range(u64 start, u64 end)
+{
+	return start >= gru_start_paddr && end <= gru_end_paddr;
+}
+
+static bool uv_is_untracked_pat_range(u64 start, u64 end)
+{
+	return is_ISA_range(start, end) || is_GRU_range(start, end);
+}
 
 static int early_get_nodeid(void)
 {
@@ -49,6 +61,7 @@
 static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
 	if (!strcmp(oem_id, "SGI")) {
+		x86_platform.is_untracked_pat_range =  uv_is_untracked_pat_range;
 		if (!strcmp(oem_table_id, "UVL"))
 			uv_system_type = UV_LEGACY_APIC;
 		else if (!strcmp(oem_table_id, "UVX"))
@@ -385,8 +398,12 @@
 	int shift = UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT;
 
 	gru.v = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR);
-	if (gru.s.enable)
+	if (gru.s.enable) {
 		map_high("GRU", gru.s.base, shift, max_pnode, map_wb);
+		gru_start_paddr = ((u64)gru.s.base << shift);
+		gru_end_paddr = gru_start_paddr + (1UL << shift) * (max_pnode + 1);
+
+	}
 }
 
 static __init void map_mmr_high(int max_pnode)
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index a4ec8b6..c1afa99 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1136,7 +1136,7 @@
 	wrmsrl(MSR_KERNEL_GS_BASE, 0);
 	barrier();
 
-	check_efer();
+	x86_configure_nx();
 	if (cpu != 0)
 		enable_x2apic();
 
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
index 8b581d3..d2e7c77 100644
--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -764,14 +764,15 @@
 };
 
 static struct cpufreq_driver acpi_cpufreq_driver = {
-	.verify = acpi_cpufreq_verify,
-	.target = acpi_cpufreq_target,
-	.init = acpi_cpufreq_cpu_init,
-	.exit = acpi_cpufreq_cpu_exit,
-	.resume = acpi_cpufreq_resume,
-	.name = "acpi-cpufreq",
-	.owner = THIS_MODULE,
-	.attr = acpi_cpufreq_attr,
+	.verify		= acpi_cpufreq_verify,
+	.target		= acpi_cpufreq_target,
+	.bios_limit	= acpi_processor_get_bios_limit,
+	.init		= acpi_cpufreq_cpu_init,
+	.exit		= acpi_cpufreq_cpu_exit,
+	.resume		= acpi_cpufreq_resume,
+	.name		= "acpi-cpufreq",
+	.owner		= THIS_MODULE,
+	.attr		= acpi_cpufreq_attr,
 };
 
 static int __init acpi_cpufreq_init(void)
diff --git a/arch/x86/kernel/cpu/cpufreq/longhaul.c b/arch/x86/kernel/cpu/cpufreq/longhaul.c
index cabd2fa..7e7eea4 100644
--- a/arch/x86/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/x86/kernel/cpu/cpufreq/longhaul.c
@@ -885,7 +885,7 @@
 
 	/* Find ACPI data for processor */
 	acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
-				ACPI_UINT32_MAX, &longhaul_walk_callback,
+				ACPI_UINT32_MAX, &longhaul_walk_callback, NULL,
 				NULL, (void *)&pr);
 
 	/* Check ACPI support for C3 state */
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
index f10dea4..cb01dac 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
@@ -164,7 +164,7 @@
 	}
 
 	/* cpuinfo and default policy values */
-	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+	policy->cpuinfo.transition_latency = 200000;
 	policy->cur = busfreq * max_multiplier;
 
 	result = cpufreq_frequency_table_cpuinfo(policy, clock_ratio);
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
index d47c775..9a97116 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
@@ -714,14 +714,17 @@
 };
 
 static struct cpufreq_driver powernow_driver = {
-	.verify	= powernow_verify,
-	.target	= powernow_target,
-	.get	= powernow_get,
-	.init	= powernow_cpu_init,
-	.exit	= powernow_cpu_exit,
-	.name	= "powernow-k7",
-	.owner	= THIS_MODULE,
-	.attr	= powernow_table_attr,
+	.verify		= powernow_verify,
+	.target		= powernow_target,
+	.get		= powernow_get,
+#ifdef CONFIG_X86_POWERNOW_K7_ACPI
+	.bios_limit	= acpi_processor_get_bios_limit,
+#endif
+	.init		= powernow_cpu_init,
+	.exit		= powernow_cpu_exit,
+	.name		= "powernow-k7",
+	.owner		= THIS_MODULE,
+	.attr		= powernow_table_attr,
 };
 
 static int __init powernow_init(void)
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
index 3f12dab..a9df944 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
@@ -1118,7 +1118,7 @@
 static int powernowk8_target(struct cpufreq_policy *pol,
 		unsigned targfreq, unsigned relation)
 {
-	cpumask_t oldmask;
+	cpumask_var_t oldmask;
 	struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
 	u32 checkfid;
 	u32 checkvid;
@@ -1131,9 +1131,13 @@
 	checkfid = data->currfid;
 	checkvid = data->currvid;
 
-	/* only run on specific CPU from here on */
-	oldmask = current->cpus_allowed;
-	set_cpus_allowed_ptr(current, &cpumask_of_cpu(pol->cpu));
+	/* only run on specific CPU from here on. */
+	/* This is poor form: use a workqueue or smp_call_function_single */
+	if (!alloc_cpumask_var(&oldmask, GFP_KERNEL))
+		return -ENOMEM;
+
+	cpumask_copy(oldmask, tsk_cpumask(current));
+	set_cpus_allowed_ptr(current, cpumask_of(pol->cpu));
 
 	if (smp_processor_id() != pol->cpu) {
 		printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
@@ -1193,7 +1197,8 @@
 	ret = 0;
 
 err_out:
-	set_cpus_allowed_ptr(current, &oldmask);
+	set_cpus_allowed_ptr(current, oldmask);
+	free_cpumask_var(oldmask);
 	return ret;
 }
 
@@ -1393,14 +1398,15 @@
 };
 
 static struct cpufreq_driver cpufreq_amd64_driver = {
-	.verify = powernowk8_verify,
-	.target = powernowk8_target,
-	.init = powernowk8_cpu_init,
-	.exit = __devexit_p(powernowk8_cpu_exit),
-	.get = powernowk8_get,
-	.name = "powernow-k8",
-	.owner = THIS_MODULE,
-	.attr = powernow_k8_attr,
+	.verify		= powernowk8_verify,
+	.target		= powernowk8_target,
+	.bios_limit	= acpi_processor_get_bios_limit,
+	.init		= powernowk8_cpu_init,
+	.exit		= __devexit_p(powernowk8_cpu_exit),
+	.get		= powernowk8_get,
+	.name		= "powernow-k8",
+	.owner		= THIS_MODULE,
+	.attr		= powernow_k8_attr,
 };
 
 /* driver entry point for init */
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
index 3ae5a7a..2ce8e0b 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
@@ -39,7 +39,7 @@
 
 /* speedstep_processor
  */
-static unsigned int speedstep_processor;
+static enum speedstep_processor speedstep_processor;
 
 static u32 pmbase;
 
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
index f4c290b..ad0083a 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
@@ -34,7 +34,7 @@
  *                   GET PROCESSOR CORE SPEED IN KHZ                 *
  *********************************************************************/
 
-static unsigned int pentium3_get_frequency(unsigned int processor)
+static unsigned int pentium3_get_frequency(enum speedstep_processor processor)
 {
 	/* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */
 	struct {
@@ -227,7 +227,7 @@
 
 
 /* Warning: may get called from smp_call_function_single. */
-unsigned int speedstep_get_frequency(unsigned int processor)
+unsigned int speedstep_get_frequency(enum speedstep_processor processor)
 {
 	switch (processor) {
 	case SPEEDSTEP_CPU_PCORE:
@@ -380,7 +380,7 @@
  *                     DETECT SPEEDSTEP SPEEDS                       *
  *********************************************************************/
 
-unsigned int speedstep_get_freqs(unsigned int processor,
+unsigned int speedstep_get_freqs(enum speedstep_processor processor,
 				  unsigned int *low_speed,
 				  unsigned int *high_speed,
 				  unsigned int *transition_latency,
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h
index 2b6c04e..70d9cea 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h
@@ -11,18 +11,18 @@
 
 
 /* processors */
-
-#define SPEEDSTEP_CPU_PIII_C_EARLY	0x00000001  /* Coppermine core */
-#define SPEEDSTEP_CPU_PIII_C		0x00000002  /* Coppermine core */
-#define SPEEDSTEP_CPU_PIII_T		0x00000003  /* Tualatin core */
-#define SPEEDSTEP_CPU_P4M		0x00000004  /* P4-M  */
-
+enum speedstep_processor {
+	SPEEDSTEP_CPU_PIII_C_EARLY = 0x00000001,  /* Coppermine core */
+	SPEEDSTEP_CPU_PIII_C	   = 0x00000002,  /* Coppermine core */
+	SPEEDSTEP_CPU_PIII_T	   = 0x00000003,  /* Tualatin core */
+	SPEEDSTEP_CPU_P4M	   = 0x00000004,  /* P4-M  */
 /* the following processors are not speedstep-capable and are not auto-detected
  * in speedstep_detect_processor(). However, their speed can be detected using
  * the speedstep_get_frequency() call. */
-#define SPEEDSTEP_CPU_PM		0xFFFFFF03  /* Pentium M  */
-#define SPEEDSTEP_CPU_P4D		0xFFFFFF04  /* desktop P4  */
-#define SPEEDSTEP_CPU_PCORE		0xFFFFFF05  /* Core */
+	SPEEDSTEP_CPU_PM	   = 0xFFFFFF03,  /* Pentium M  */
+	SPEEDSTEP_CPU_P4D	   = 0xFFFFFF04,  /* desktop P4  */
+	SPEEDSTEP_CPU_PCORE	   = 0xFFFFFF05,  /* Core */
+};
 
 /* speedstep states -- only two of them */
 
@@ -31,10 +31,10 @@
 
 
 /* detect a speedstep-capable processor */
-extern unsigned int speedstep_detect_processor (void);
+extern enum speedstep_processor speedstep_detect_processor(void);
 
 /* detect the current speed (in khz) of the processor */
-extern unsigned int speedstep_get_frequency(unsigned int processor);
+extern unsigned int speedstep_get_frequency(enum speedstep_processor processor);
 
 
 /* detect the low and high speeds of the processor. The callback
@@ -42,7 +42,7 @@
  * SPEEDSTEP_LOW; the second argument is zero so that no
  * cpufreq_notify_transition calls are initiated.
  */
-extern unsigned int speedstep_get_freqs(unsigned int processor,
+extern unsigned int speedstep_get_freqs(enum speedstep_processor processor,
 	unsigned int *low_speed,
 	unsigned int *high_speed,
 	unsigned int *transition_latency,
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c b/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c
index befea08..04d73c1 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c
@@ -35,7 +35,7 @@
 static unsigned int smi_sig;
 
 /* info about the processor */
-static unsigned int speedstep_processor;
+static enum speedstep_processor speedstep_processor;
 
 /*
  * There are only two frequency states for each processor. Values
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 40e1835..c900b73 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -263,8 +263,12 @@
 	/* Don't do the funky fallback heuristics the AMD version employs
 	   for now. */
 	node = apicid_to_node[apicid];
-	if (node == NUMA_NO_NODE || !node_online(node))
+	if (node == NUMA_NO_NODE)
 		node = first_node(node_online_map);
+	else if (!node_online(node)) {
+		/* reuse the value from init_cpu_to_node() */
+		node = cpu_to_node(cpu);
+	}
 	numa_set_node(cpu, node);
 
 	printk(KERN_INFO "CPU %d/0x%x -> Node %d\n", cpu, apicid, node);
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index 0df4c2b..6c40f6b 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -94,7 +94,7 @@
 	{ 0xd1, LVL_3,    1024 },	/* 4-way set assoc, 64 byte line size */
 	{ 0xd2, LVL_3,    2048 },	/* 4-way set assoc, 64 byte line size */
 	{ 0xd6, LVL_3,    1024 },	/* 8-way set assoc, 64 byte line size */
-	{ 0xd7, LVL_3,    2038 },	/* 8-way set assoc, 64 byte line size */
+	{ 0xd7, LVL_3,    2048 },	/* 8-way set assoc, 64 byte line size */
 	{ 0xd8, LVL_3,    4096 },	/* 12-way set assoc, 64 byte line size */
 	{ 0xdc, LVL_3,    2048 },	/* 12-way set assoc, 64 byte line size */
 	{ 0xdd, LVL_3,    4096 },	/* 12-way set assoc, 64 byte line size */
@@ -102,6 +102,9 @@
 	{ 0xe2, LVL_3,    2048 },	/* 16-way set assoc, 64 byte line size */
 	{ 0xe3, LVL_3,    4096 },	/* 16-way set assoc, 64 byte line size */
 	{ 0xe4, LVL_3,    8192 },	/* 16-way set assoc, 64 byte line size */
+	{ 0xea, LVL_3,    12288 },	/* 24-way set assoc, 64 byte line size */
+	{ 0xeb, LVL_3,    18432 },	/* 24-way set assoc, 64 byte line size */
+	{ 0xec, LVL_3,    24576 },	/* 24-way set assoc, 64 byte line size */
 	{ 0x00, 0, 0}
 };
 
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index 0bcaa38..d7ebf25 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -2016,9 +2016,11 @@
 		break;
 	case CPU_DOWN_FAILED:
 	case CPU_DOWN_FAILED_FROZEN:
-		t->expires = round_jiffies(jiffies +
+		if (!mce_ignore_ce && check_interval) {
+			t->expires = round_jiffies(jiffies +
 					   __get_cpu_var(mce_next_interval));
-		add_timer_on(t, cpu);
+			add_timer_on(t, cpu);
+		}
 		smp_call_function_single(cpu, mce_reenable_cpu, &action, 1);
 		break;
 	case CPU_POST_DEAD:
diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c
index 73c86db..09b1698 100644
--- a/arch/x86/kernel/cpu/mtrr/cleanup.c
+++ b/arch/x86/kernel/cpu/mtrr/cleanup.c
@@ -170,6 +170,41 @@
 	return start1 - start2;
 }
 
+static int __init clean_sort_range(struct res_range *range, int az)
+{
+	int i, j, k = az - 1, nr_range = 0;
+
+	for (i = 0; i < k; i++) {
+		if (range[i].end)
+			continue;
+		for (j = k; j > i; j--) {
+			if (range[j].end) {
+				k = j;
+				break;
+			}
+		}
+		if (j == i)
+			break;
+		range[i].start = range[k].start;
+		range[i].end   = range[k].end;
+		range[k].start = 0;
+		range[k].end   = 0;
+		k--;
+	}
+	/* count it */
+	for (i = 0; i < az; i++) {
+		if (!range[i].end) {
+			nr_range = i;
+			break;
+		}
+	}
+
+	/* sort them */
+	sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
+
+	return nr_range;
+}
+
 #define BIOS_BUG_MSG KERN_WARNING \
 	"WARNING: BIOS bug: VAR MTRR %d contains strange UC entry under 1M, check with your system vendor!\n"
 
@@ -223,22 +258,18 @@
 		subtract_range(range, extra_remove_base,
 				 extra_remove_base + extra_remove_size  - 1);
 
-	/* get new range num */
-	nr_range = 0;
-	for (i = 0; i < RANGE_NUM; i++) {
-		if (!range[i].end)
-			continue;
-		nr_range++;
-	}
 	if  (debug_print) {
 		printk(KERN_DEBUG "After UC checking\n");
-		for (i = 0; i < nr_range; i++)
+		for (i = 0; i < RANGE_NUM; i++) {
+			if (!range[i].end)
+				continue;
 			printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n",
 				 range[i].start, range[i].end + 1);
+		}
 	}
 
 	/* sort the ranges */
-	sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
+	nr_range = clean_sort_range(range, RANGE_NUM);
 	if  (debug_print) {
 		printk(KERN_DEBUG "After sorting\n");
 		for (i = 0; i < nr_range; i++)
@@ -689,8 +720,6 @@
 			continue;
 		if (!size)
 			type = MTRR_NUM_TYPES;
-		if (type == MTRR_TYPE_WRPROT)
-			type = MTRR_TYPE_UNCACHABLE;
 		num[type]++;
 	}
 
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index c1bbed1..ab1a8a8 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -1286,7 +1286,7 @@
 		return 0;
 
 	/*
-	 * If we are way outside a reasoable range then just skip forward:
+	 * If we are way outside a reasonable range then just skip forward:
 	 */
 	if (unlikely(left <= -period)) {
 		left = period;
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 4deb8fc..63bca79 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -977,8 +977,8 @@
 #endif
 apicinterrupt LOCAL_TIMER_VECTOR \
 	apic_timer_interrupt smp_apic_timer_interrupt
-apicinterrupt GENERIC_INTERRUPT_VECTOR \
-	generic_interrupt smp_generic_interrupt
+apicinterrupt X86_PLATFORM_IPI_VECTOR \
+	x86_platform_ipi smp_x86_platform_ipi
 
 #ifdef CONFIG_SMP
 apicinterrupt INVALIDATE_TLB_VECTOR_START+0 \
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index 5a1b975..3096892 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -189,9 +189,26 @@
 	nmi_wait_count++;
 }
 
+static inline int
+within(unsigned long addr, unsigned long start, unsigned long end)
+{
+	return addr >= start && addr < end;
+}
+
 static int
 do_ftrace_mod_code(unsigned long ip, void *new_code)
 {
+	/*
+	 * On x86_64, kernel text mappings are mapped read-only with
+	 * CONFIG_DEBUG_RODATA. So we use the kernel identity mapping instead
+	 * of the kernel text mapping to modify the kernel text.
+	 *
+	 * For 32bit kernels, these mappings are same and we can use
+	 * kernel identity mapping to modify code.
+	 */
+	if (within(ip, (unsigned long)_text, (unsigned long)_etext))
+		ip = (unsigned long)__va(__pa(ip));
+
 	mod_code_ip = (void *)ip;
 	mod_code_newcode = new_code;
 
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index 050c278..7fd318b 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -18,6 +18,8 @@
 #include <asm/asm-offsets.h>
 #include <asm/setup.h>
 #include <asm/processor-flags.h>
+#include <asm/msr-index.h>
+#include <asm/cpufeature.h>
 #include <asm/percpu.h>
 
 /* Physical address */
@@ -297,25 +299,27 @@
 	orl %edx,%eax
 	movl %eax,%cr4
 
-	btl $5, %eax		# check if PAE is enabled
-	jnc 6f
+	testb $X86_CR4_PAE, %al		# check if PAE is enabled
+	jz 6f
 
 	/* Check if extended functions are implemented */
 	movl $0x80000000, %eax
 	cpuid
-	cmpl $0x80000000, %eax
-	jbe 6f
+	/* Value must be in the range 0x80000001 to 0x8000ffff */
+	subl $0x80000001, %eax
+	cmpl $(0x8000ffff-0x80000001), %eax
+	ja 6f
 	mov $0x80000001, %eax
 	cpuid
 	/* Execute Disable bit supported? */
-	btl $20, %edx
+	btl $(X86_FEATURE_NX & 31), %edx
 	jnc 6f
 
 	/* Setup EFER (Extended Feature Enable Register) */
-	movl $0xc0000080, %ecx
+	movl $MSR_EFER, %ecx
 	rdmsr
 
-	btsl $11, %eax
+	btsl $_EFER_NX, %eax
 	/* Make changes effective */
 	wrmsr
 
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index 22db86a..2d8b503 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -262,11 +262,11 @@
 	.quad	x86_64_start_kernel
 	ENTRY(initial_gs)
 	.quad	INIT_PER_CPU_VAR(irq_stack_union)
-	__FINITDATA
 
 	ENTRY(stack_start)
 	.quad  init_thread_union+THREAD_SIZE-8
 	.word  0
+	__FINITDATA
 
 bad_address:
 	jmp bad_address
@@ -340,6 +340,7 @@
 	i = i + 1 ;					\
 	.endr
 
+	.data
 	/*
 	 * This default setting generates an ident mapping at address 0x100000
 	 * and a mapping for the kernel that precisely maps virtual address
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index dedc2bd..ba6e658 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -33,6 +33,7 @@
  * HPET address is set in acpi/boot.c, when an ACPI entry exists
  */
 unsigned long				hpet_address;
+u8					hpet_blockid; /* OS timer block num */
 #ifdef CONFIG_PCI_MSI
 static unsigned long			hpet_num_timers;
 #endif
@@ -47,12 +48,12 @@
 	char				name[10];
 };
 
-unsigned long hpet_readl(unsigned long a)
+inline unsigned int hpet_readl(unsigned int a)
 {
 	return readl(hpet_virt_address + a);
 }
 
-static inline void hpet_writel(unsigned long d, unsigned long a)
+static inline void hpet_writel(unsigned int d, unsigned int a)
 {
 	writel(d, hpet_virt_address + a);
 }
@@ -167,7 +168,7 @@
 
 static void hpet_reserve_msi_timers(struct hpet_data *hd);
 
-static void hpet_reserve_platform_timers(unsigned long id)
+static void hpet_reserve_platform_timers(unsigned int id)
 {
 	struct hpet __iomem *hpet = hpet_virt_address;
 	struct hpet_timer __iomem *timer = &hpet->hpet_timers[2];
@@ -205,7 +206,7 @@
 
 }
 #else
-static void hpet_reserve_platform_timers(unsigned long id) { }
+static void hpet_reserve_platform_timers(unsigned int id) { }
 #endif
 
 /*
@@ -246,7 +247,7 @@
 
 static void hpet_start_counter(void)
 {
-	unsigned long cfg = hpet_readl(HPET_CFG);
+	unsigned int cfg = hpet_readl(HPET_CFG);
 	cfg |= HPET_CFG_ENABLE;
 	hpet_writel(cfg, HPET_CFG);
 }
@@ -271,7 +272,7 @@
 
 static void hpet_enable_legacy_int(void)
 {
-	unsigned long cfg = hpet_readl(HPET_CFG);
+	unsigned int cfg = hpet_readl(HPET_CFG);
 
 	cfg |= HPET_CFG_LEGACY;
 	hpet_writel(cfg, HPET_CFG);
@@ -314,7 +315,7 @@
 static void hpet_set_mode(enum clock_event_mode mode,
 			  struct clock_event_device *evt, int timer)
 {
-	unsigned long cfg, cmp, now;
+	unsigned int cfg, cmp, now;
 	uint64_t delta;
 
 	switch (mode) {
@@ -323,7 +324,7 @@
 		delta = ((uint64_t)(NSEC_PER_SEC/HZ)) * evt->mult;
 		delta >>= evt->shift;
 		now = hpet_readl(HPET_COUNTER);
-		cmp = now + (unsigned long) delta;
+		cmp = now + (unsigned int) delta;
 		cfg = hpet_readl(HPET_Tn_CFG(timer));
 		/* Make sure we use edge triggered interrupts */
 		cfg &= ~HPET_TN_LEVEL;
@@ -339,7 +340,7 @@
 		 * (See AMD-8111 HyperTransport I/O Hub Data Sheet,
 		 * Publication # 24674)
 		 */
-		hpet_writel((unsigned long) delta, HPET_Tn_CMP(timer));
+		hpet_writel((unsigned int) delta, HPET_Tn_CMP(timer));
 		hpet_start_counter();
 		hpet_print_config();
 		break;
@@ -383,13 +384,24 @@
 	hpet_writel(cnt, HPET_Tn_CMP(timer));
 
 	/*
-	 * We need to read back the CMP register to make sure that
-	 * what we wrote hit the chip before we compare it to the
-	 * counter.
+	 * We need to read back the CMP register on certain HPET
+	 * implementations (ATI chipsets) which seem to delay the
+	 * transfer of the compare register into the internal compare
+	 * logic. With small deltas this might actually be too late as
+	 * the counter could already be higher than the compare value
+	 * at that point and we would wait for the next hpet interrupt
+	 * forever. We found out that reading the CMP register back
+	 * forces the transfer so we can rely on the comparison with
+	 * the counter register below. If the read back from the
+	 * compare register does not match the value we programmed
+	 * then we might have a real hardware problem. We can not do
+	 * much about it here, but at least alert the user/admin with
+	 * a prominent warning.
 	 */
-	WARN_ON_ONCE((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt);
+	WARN_ONCE(hpet_readl(HPET_Tn_CMP(timer)) != cnt,
+		  KERN_WARNING "hpet: compare register read back failed.\n");
 
-	return (s32)((u32)hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0;
+	return (s32)(hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0;
 }
 
 static void hpet_legacy_set_mode(enum clock_event_mode mode,
@@ -415,7 +427,7 @@
 void hpet_msi_unmask(unsigned int irq)
 {
 	struct hpet_dev *hdev = get_irq_data(irq);
-	unsigned long cfg;
+	unsigned int cfg;
 
 	/* unmask it */
 	cfg = hpet_readl(HPET_Tn_CFG(hdev->num));
@@ -425,7 +437,7 @@
 
 void hpet_msi_mask(unsigned int irq)
 {
-	unsigned long cfg;
+	unsigned int cfg;
 	struct hpet_dev *hdev = get_irq_data(irq);
 
 	/* mask it */
@@ -467,7 +479,7 @@
 
 static int hpet_setup_msi_irq(unsigned int irq)
 {
-	if (arch_setup_hpet_msi(irq)) {
+	if (arch_setup_hpet_msi(irq, hpet_blockid)) {
 		destroy_irq(irq);
 		return -EINVAL;
 	}
@@ -584,6 +596,8 @@
 	unsigned int num_timers_used = 0;
 	int i;
 
+	if (boot_cpu_has(X86_FEATURE_ARAT))
+		return;
 	id = hpet_readl(HPET_ID);
 
 	num_timers = ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT);
@@ -598,7 +612,7 @@
 
 	for (i = start_timer; i < num_timers - RESERVE_TIMERS; i++) {
 		struct hpet_dev *hdev = &hpet_devs[num_timers_used];
-		unsigned long cfg = hpet_readl(HPET_Tn_CFG(i));
+		unsigned int cfg = hpet_readl(HPET_Tn_CFG(i));
 
 		/* Only consider HPET timer with MSI support */
 		if (!(cfg & HPET_TN_FSB_CAP))
@@ -813,7 +827,7 @@
  */
 int __init hpet_enable(void)
 {
-	unsigned long id;
+	unsigned int id;
 	int i;
 
 	if (!is_hpet_capable())
@@ -872,10 +886,8 @@
 
 	if (id & HPET_ID_LEGSUP) {
 		hpet_legacy_clockevent_register();
-		hpet_msi_capability_lookup(2);
 		return 1;
 	}
-	hpet_msi_capability_lookup(0);
 	return 0;
 
 out_nohpet:
@@ -908,9 +920,17 @@
 	if (!hpet_virt_address)
 		return -ENODEV;
 
+	if (hpet_readl(HPET_ID) & HPET_ID_LEGSUP)
+		hpet_msi_capability_lookup(2);
+	else
+		hpet_msi_capability_lookup(0);
+
 	hpet_reserve_platform_timers(hpet_readl(HPET_ID));
 	hpet_print_config();
 
+	if (boot_cpu_has(X86_FEATURE_ARAT))
+		return 0;
+
 	for_each_online_cpu(cpu) {
 		hpet_cpuhp_notify(NULL, CPU_ONLINE, (void *)(long)cpu);
 	}
@@ -925,7 +945,7 @@
 void hpet_disable(void)
 {
 	if (is_hpet_capable()) {
-		unsigned long cfg = hpet_readl(HPET_CFG);
+		unsigned int cfg = hpet_readl(HPET_CFG);
 
 		if (hpet_legacy_int_enabled) {
 			cfg &= ~HPET_CFG_LEGACY;
@@ -965,8 +985,8 @@
 static struct rtc_time hpet_alarm_time;
 static unsigned long hpet_pie_count;
 static u32 hpet_t1_cmp;
-static unsigned long hpet_default_delta;
-static unsigned long hpet_pie_delta;
+static u32 hpet_default_delta;
+static u32 hpet_pie_delta;
 static unsigned long hpet_pie_limit;
 
 static rtc_irq_handler irq_handler;
@@ -1017,7 +1037,8 @@
  */
 int hpet_rtc_timer_init(void)
 {
-	unsigned long cfg, cnt, delta, flags;
+	unsigned int cfg, cnt, delta;
+	unsigned long flags;
 
 	if (!is_hpet_enabled())
 		return 0;
@@ -1027,7 +1048,7 @@
 
 		clc = (uint64_t) hpet_clockevent.mult * NSEC_PER_SEC;
 		clc >>= hpet_clockevent.shift + DEFAULT_RTC_SHIFT;
-		hpet_default_delta = (unsigned long) clc;
+		hpet_default_delta = clc;
 	}
 
 	if (!(hpet_rtc_flags & RTC_PIE) || hpet_pie_limit)
@@ -1113,7 +1134,7 @@
 		clc = (uint64_t) hpet_clockevent.mult * NSEC_PER_SEC;
 		do_div(clc, freq);
 		clc >>= hpet_clockevent.shift;
-		hpet_pie_delta = (unsigned long) clc;
+		hpet_pie_delta = clc;
 	}
 	return 1;
 }
@@ -1127,7 +1148,7 @@
 
 static void hpet_rtc_timer_reinit(void)
 {
-	unsigned long cfg, delta;
+	unsigned int cfg, delta;
 	int lost_ints = -1;
 
 	if (unlikely(!hpet_rtc_flags)) {
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index fee6cc2..664bcb7 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -18,7 +18,7 @@
 atomic_t irq_err_count;
 
 /* Function pointer for generic interrupt vector handling */
-void (*generic_interrupt_extension)(void) = NULL;
+void (*x86_platform_ipi_callback)(void) = NULL;
 
 /*
  * 'what should we do if we get a hw irq event on an illegal vector'.
@@ -72,10 +72,10 @@
 		seq_printf(p, "%10u ", irq_stats(j)->apic_pending_irqs);
 	seq_printf(p, "  Performance pending work\n");
 #endif
-	if (generic_interrupt_extension) {
+	if (x86_platform_ipi_callback) {
 		seq_printf(p, "%*s: ", prec, "PLT");
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", irq_stats(j)->generic_irqs);
+			seq_printf(p, "%10u ", irq_stats(j)->x86_platform_ipis);
 		seq_printf(p, "  Platform interrupts\n");
 	}
 #ifdef CONFIG_SMP
@@ -187,8 +187,8 @@
 	sum += irq_stats(cpu)->apic_perf_irqs;
 	sum += irq_stats(cpu)->apic_pending_irqs;
 #endif
-	if (generic_interrupt_extension)
-		sum += irq_stats(cpu)->generic_irqs;
+	if (x86_platform_ipi_callback)
+		sum += irq_stats(cpu)->x86_platform_ipis;
 #ifdef CONFIG_SMP
 	sum += irq_stats(cpu)->irq_resched_count;
 	sum += irq_stats(cpu)->irq_call_count;
@@ -251,9 +251,9 @@
 }
 
 /*
- * Handler for GENERIC_INTERRUPT_VECTOR.
+ * Handler for X86_PLATFORM_IPI_VECTOR.
  */
-void smp_generic_interrupt(struct pt_regs *regs)
+void smp_x86_platform_ipi(struct pt_regs *regs)
 {
 	struct pt_regs *old_regs = set_irq_regs(regs);
 
@@ -263,10 +263,10 @@
 
 	irq_enter();
 
-	inc_irq_stat(generic_irqs);
+	inc_irq_stat(x86_platform_ipis);
 
-	if (generic_interrupt_extension)
-		generic_interrupt_extension();
+	if (x86_platform_ipi_callback)
+		x86_platform_ipi_callback();
 
 	irq_exit();
 
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index 40f3077..d593222 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -200,8 +200,8 @@
 	/* self generated IPI for local APIC timer */
 	alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
 
-	/* generic IPI for platform specific use */
-	alloc_intr_gate(GENERIC_INTERRUPT_VECTOR, generic_interrupt);
+	/* IPI for X86 platform specific use */
+	alloc_intr_gate(X86_PLATFORM_IPI_VECTOR, x86_platform_ipi);
 
 	/* IPI vectors for APIC spurious and error interrupts */
 	alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c
index 20a5b36..dd74fe72 100644
--- a/arch/x86/kernel/kgdb.c
+++ b/arch/x86/kernel/kgdb.c
@@ -86,9 +86,15 @@
 	gdb_regs[GDB_DS]	= regs->ds;
 	gdb_regs[GDB_ES]	= regs->es;
 	gdb_regs[GDB_CS]	= regs->cs;
-	gdb_regs[GDB_SS]	= __KERNEL_DS;
 	gdb_regs[GDB_FS]	= 0xFFFF;
 	gdb_regs[GDB_GS]	= 0xFFFF;
+	if (user_mode_vm(regs)) {
+		gdb_regs[GDB_SS] = regs->ss;
+		gdb_regs[GDB_SP] = regs->sp;
+	} else {
+		gdb_regs[GDB_SS] = __KERNEL_DS;
+		gdb_regs[GDB_SP] = kernel_stack_pointer(regs);
+	}
 #else
 	gdb_regs[GDB_R8]	= regs->r8;
 	gdb_regs[GDB_R9]	= regs->r9;
@@ -101,8 +107,8 @@
 	gdb_regs32[GDB_PS]	= regs->flags;
 	gdb_regs32[GDB_CS]	= regs->cs;
 	gdb_regs32[GDB_SS]	= regs->ss;
-#endif
 	gdb_regs[GDB_SP]	= kernel_stack_pointer(regs);
+#endif
 }
 
 /**
@@ -220,8 +226,7 @@
 			dr7 |= ((breakinfo[breakno].len << 2) |
 				 breakinfo[breakno].type) <<
 			       ((breakno << 2) + 16);
-			if (breakno >= 0 && breakno <= 3)
-				set_debugreg(breakinfo[breakno].addr, breakno);
+			set_debugreg(breakinfo[breakno].addr, breakno);
 
 		} else {
 			if ((dr7 & breakbit) && !breakinfo[breakno].enabled) {
@@ -395,7 +400,6 @@
 		/* set the trace bit if we're stepping */
 		if (remcomInBuffer[0] == 's') {
 			linux_regs->flags |= X86_EFLAGS_TF;
-			kgdb_single_step = 1;
 			atomic_set(&kgdb_cpu_doing_single_step,
 				   raw_smp_processor_id());
 		}
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
index 1f3186c..5b8c750 100644
--- a/arch/x86/kernel/kprobes.c
+++ b/arch/x86/kernel/kprobes.c
@@ -481,7 +481,7 @@
 
 /*
  * Interrupts are disabled on entry as trap3 is an interrupt gate and they
- * remain disabled thorough out this function.
+ * remain disabled throughout this function.
  */
 static int __kprobes kprobe_handler(struct pt_regs *regs)
 {
@@ -818,7 +818,7 @@
 
 /*
  * Interrupts are disabled on entry as trap1 is an interrupt gate and they
- * remain disabled thoroughout this function.
+ * remain disabled throughout this function.
  */
 static int __kprobes post_kprobe_handler(struct pt_regs *regs)
 {
diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c
index c843f84..a3fa43b 100644
--- a/arch/x86/kernel/machine_kexec_32.c
+++ b/arch/x86/kernel/machine_kexec_32.c
@@ -158,8 +158,7 @@
 {
 	int error;
 
-	if (nx_enabled)
-		set_pages_x(image->control_code_page, 1);
+	set_pages_x(image->control_code_page, 1);
 	error = machine_kexec_alloc_page_tables(image);
 	if (error)
 		return error;
@@ -173,8 +172,7 @@
  */
 void machine_kexec_cleanup(struct kimage *image)
 {
-	if (nx_enabled)
-		set_pages_nx(image->control_code_page, 1);
+	set_pages_nx(image->control_code_page, 1);
 	machine_kexec_free_page_tables(image);
 }
 
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c
index f4c538b..63123d9 100644
--- a/arch/x86/kernel/microcode_amd.c
+++ b/arch/x86/kernel/microcode_amd.c
@@ -33,6 +33,9 @@
 #define UCODE_EQUIV_CPU_TABLE_TYPE 0x00000000
 #define UCODE_UCODE_TYPE           0x00000001
 
+const struct firmware *firmware;
+static int supported_cpu;
+
 struct equiv_cpu_entry {
 	u32	installed_cpu;
 	u32	fixed_errata_mask;
@@ -71,17 +74,14 @@
 
 static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig)
 {
-	struct cpuinfo_x86 *c = &cpu_data(cpu);
 	u32 dummy;
 
-	memset(csig, 0, sizeof(*csig));
-	if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) {
-		printk(KERN_WARNING "microcode: CPU%d: AMD CPU family 0x%x not "
-		       "supported\n", cpu, c->x86);
+	if (!supported_cpu)
 		return -1;
-	}
+
+	memset(csig, 0, sizeof(*csig));
 	rdmsr(MSR_AMD64_PATCH_LEVEL, csig->rev, dummy);
-	printk(KERN_INFO "microcode: CPU%d: patch_level=0x%x\n", cpu, csig->rev);
+	pr_info("microcode: CPU%d: patch_level=0x%x\n", cpu, csig->rev);
 	return 0;
 }
 
@@ -103,22 +103,15 @@
 		i++;
 	}
 
-	if (!equiv_cpu_id) {
-		printk(KERN_WARNING "microcode: CPU%d: cpu revision "
-		       "not listed in equivalent cpu table\n", cpu);
+	if (!equiv_cpu_id)
 		return 0;
-	}
 
-	if (mc_header->processor_rev_id != equiv_cpu_id) {
-		printk(KERN_ERR	"microcode: CPU%d: patch mismatch "
-		       "(processor_rev_id: %x, equiv_cpu_id: %x)\n",
-		       cpu, mc_header->processor_rev_id, equiv_cpu_id);
+	if (mc_header->processor_rev_id != equiv_cpu_id)
 		return 0;
-	}
 
 	/* ucode might be chipset specific -- currently we don't support this */
 	if (mc_header->nb_dev_id || mc_header->sb_dev_id) {
-		printk(KERN_ERR "microcode: CPU%d: loading of chipset "
+		pr_err(KERN_ERR "microcode: CPU%d: loading of chipset "
 		       "specific code not yet supported\n", cpu);
 		return 0;
 	}
@@ -148,14 +141,12 @@
 
 	/* check current patch id and patch's id for match */
 	if (rev != mc_amd->hdr.patch_id) {
-		printk(KERN_ERR "microcode: CPU%d: update failed "
+		pr_err("microcode: CPU%d: update failed "
 		       "(for patch_level=0x%x)\n", cpu, mc_amd->hdr.patch_id);
 		return -1;
 	}
 
-	printk(KERN_INFO "microcode: CPU%d: updated (new patch_level=0x%x)\n",
-	       cpu, rev);
-
+	pr_info("microcode: CPU%d: updated (new patch_level=0x%x)\n", cpu, rev);
 	uci->cpu_sig.rev = rev;
 
 	return 0;
@@ -178,18 +169,15 @@
 		return NULL;
 
 	if (section_hdr[0] != UCODE_UCODE_TYPE) {
-		printk(KERN_ERR "microcode: error: invalid type field in "
+		pr_err("microcode: error: invalid type field in "
 		       "container file section header\n");
 		return NULL;
 	}
 
 	total_size = (unsigned long) (section_hdr[4] + (section_hdr[5] << 8));
 
-	printk(KERN_DEBUG "microcode: size %u, total_size %u\n",
-	       size, total_size);
-
 	if (total_size > size || total_size > UCODE_MAX_SIZE) {
-		printk(KERN_ERR "microcode: error: size mismatch\n");
+		pr_err("microcode: error: size mismatch\n");
 		return NULL;
 	}
 
@@ -218,15 +206,14 @@
 	size = buf_pos[2];
 
 	if (buf_pos[1] != UCODE_EQUIV_CPU_TABLE_TYPE || !size) {
-		printk(KERN_ERR "microcode: error: invalid type field in "
+		pr_err("microcode: error: invalid type field in "
 		       "container file section header\n");
 		return 0;
 	}
 
 	equiv_cpu_table = (struct equiv_cpu_entry *) vmalloc(size);
 	if (!equiv_cpu_table) {
-		printk(KERN_ERR "microcode: failed to allocate "
-		       "equivalent CPU table\n");
+		pr_err("microcode: failed to allocate equivalent CPU table\n");
 		return 0;
 	}
 
@@ -259,8 +246,7 @@
 
 	offset = install_equiv_cpu_table(ucode_ptr);
 	if (!offset) {
-		printk(KERN_ERR "microcode: failed to create "
-		       "equivalent cpu table\n");
+		pr_err("microcode: failed to create equivalent cpu table\n");
 		return UCODE_ERROR;
 	}
 
@@ -308,33 +294,27 @@
 
 static enum ucode_state request_microcode_fw(int cpu, struct device *device)
 {
-	const char *fw_name = "amd-ucode/microcode_amd.bin";
-	const struct firmware *firmware;
 	enum ucode_state ret;
 
-	if (request_firmware(&firmware, fw_name, device)) {
-		printk(KERN_ERR "microcode: failed to load file %s\n", fw_name);
+	if (firmware == NULL)
 		return UCODE_NFOUND;
-	}
 
 	if (*(u32 *)firmware->data != UCODE_MAGIC) {
-		printk(KERN_ERR "microcode: invalid UCODE_MAGIC (0x%08x)\n",
+		pr_err("microcode: invalid UCODE_MAGIC (0x%08x)\n",
 		       *(u32 *)firmware->data);
 		return UCODE_ERROR;
 	}
 
 	ret = generic_load_microcode(cpu, firmware->data, firmware->size);
 
-	release_firmware(firmware);
-
 	return ret;
 }
 
 static enum ucode_state
 request_microcode_user(int cpu, const void __user *buf, size_t size)
 {
-	printk(KERN_INFO "microcode: AMD microcode update via "
-	       "/dev/cpu/microcode not supported\n");
+	pr_info("microcode: AMD microcode update via "
+		"/dev/cpu/microcode not supported\n");
 	return UCODE_ERROR;
 }
 
@@ -346,7 +326,32 @@
 	uci->mc = NULL;
 }
 
+void init_microcode_amd(struct device *device)
+{
+	const char *fw_name = "amd-ucode/microcode_amd.bin";
+	struct cpuinfo_x86 *c = &boot_cpu_data;
+
+	WARN_ON(c->x86_vendor != X86_VENDOR_AMD);
+
+	if (c->x86 < 0x10) {
+		pr_warning("microcode: AMD CPU family 0x%x not supported\n",
+			   c->x86);
+		return;
+	}
+	supported_cpu = 1;
+
+	if (request_firmware(&firmware, fw_name, device))
+		pr_err("microcode: failed to load file %s\n", fw_name);
+}
+
+void fini_microcode_amd(void)
+{
+	release_firmware(firmware);
+}
+
 static struct microcode_ops microcode_amd_ops = {
+	.init				  = init_microcode_amd,
+	.fini				  = fini_microcode_amd,
 	.request_microcode_user           = request_microcode_user,
 	.request_microcode_fw             = request_microcode_fw,
 	.collect_cpu_info                 = collect_cpu_info_amd,
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c
index 2bcad39..e68aae3 100644
--- a/arch/x86/kernel/microcode_core.c
+++ b/arch/x86/kernel/microcode_core.c
@@ -391,7 +391,7 @@
 	struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
 	enum ucode_state ustate;
 
-	if (uci->valid)
+	if (uci->valid && uci->mc)
 		ustate = microcode_resume_cpu(cpu);
 	else
 		ustate = microcode_init_cpu(cpu);
@@ -518,6 +518,9 @@
 		return PTR_ERR(microcode_pdev);
 	}
 
+	if (microcode_ops->init)
+		microcode_ops->init(&microcode_pdev->dev);
+
 	get_online_cpus();
 	mutex_lock(&microcode_mutex);
 
@@ -561,6 +564,9 @@
 
 	platform_device_unregister(microcode_pdev);
 
+	if (microcode_ops->fini)
+		microcode_ops->fini();
+
 	microcode_ops = NULL;
 
 	pr_info("Microcode Update Driver: v" MICROCODE_VERSION " removed.\n");
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index 5be95ef..35a57c9 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -667,36 +667,18 @@
 	 */
 }
 
-static void __init smp_reserve_bootmem(struct mpf_intel *mpf)
+static void __init smp_reserve_memory(struct mpf_intel *mpf)
 {
 	unsigned long size = get_mpc_size(mpf->physptr);
-#ifdef CONFIG_X86_32
-	/*
-	 * We cannot access to MPC table to compute table size yet,
-	 * as only few megabytes from the bottom is mapped now.
-	 * PC-9800's MPC table places on the very last of physical
-	 * memory; so that simply reserving PAGE_SIZE from mpf->physptr
-	 * yields BUG() in reserve_bootmem.
-	 * also need to make sure physptr is below than max_low_pfn
-	 * we don't need reserve the area above max_low_pfn
-	 */
-	unsigned long end = max_low_pfn * PAGE_SIZE;
 
-	if (mpf->physptr < end) {
-		if (mpf->physptr + size > end)
-			size = end - mpf->physptr;
-		reserve_bootmem_generic(mpf->physptr, size, BOOTMEM_DEFAULT);
-	}
-#else
-	reserve_bootmem_generic(mpf->physptr, size, BOOTMEM_DEFAULT);
-#endif
+	reserve_early(mpf->physptr, mpf->physptr+size, "MP-table mpc");
 }
 
-static int __init smp_scan_config(unsigned long base, unsigned long length,
-				  unsigned reserve)
+static int __init smp_scan_config(unsigned long base, unsigned long length)
 {
 	unsigned int *bp = phys_to_virt(base);
 	struct mpf_intel *mpf;
+	unsigned long mem;
 
 	apic_printk(APIC_VERBOSE, "Scan SMP from %p for %ld bytes.\n",
 			bp, length);
@@ -717,12 +699,10 @@
 			printk(KERN_INFO "found SMP MP-table at [%p] %llx\n",
 			       mpf, (u64)virt_to_phys(mpf));
 
-			if (!reserve)
-				return 1;
-			reserve_bootmem_generic(virt_to_phys(mpf), sizeof(*mpf),
-						BOOTMEM_DEFAULT);
+			mem = virt_to_phys(mpf);
+			reserve_early(mem, mem + sizeof(*mpf), "MP-table mpf");
 			if (mpf->physptr)
-				smp_reserve_bootmem(mpf);
+				smp_reserve_memory(mpf);
 
 			return 1;
 		}
@@ -732,7 +712,7 @@
 	return 0;
 }
 
-void __init default_find_smp_config(unsigned int reserve)
+void __init default_find_smp_config(void)
 {
 	unsigned int address;
 
@@ -744,9 +724,9 @@
 	 * 2) Scan the top 1K of base RAM
 	 * 3) Scan the 64K of bios
 	 */
-	if (smp_scan_config(0x0, 0x400, reserve) ||
-	    smp_scan_config(639 * 0x400, 0x400, reserve) ||
-	    smp_scan_config(0xF0000, 0x10000, reserve))
+	if (smp_scan_config(0x0, 0x400) ||
+	    smp_scan_config(639 * 0x400, 0x400) ||
+	    smp_scan_config(0xF0000, 0x10000))
 		return;
 	/*
 	 * If it is an SMP machine we should know now, unless the
@@ -767,7 +747,7 @@
 
 	address = get_bios_ebda();
 	if (address)
-		smp_scan_config(address, 0x400, reserve);
+		smp_scan_config(address, 0x400);
 }
 
 #ifdef CONFIG_X86_IO_APIC
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index a98fe88..c95c8f4 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -349,26 +349,42 @@
 	return err;
 }
 
-void
-start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
+static void
+start_thread_common(struct pt_regs *regs, unsigned long new_ip,
+		    unsigned long new_sp,
+		    unsigned int _cs, unsigned int _ss, unsigned int _ds)
 {
 	loadsegment(fs, 0);
-	loadsegment(es, 0);
-	loadsegment(ds, 0);
+	loadsegment(es, _ds);
+	loadsegment(ds, _ds);
 	load_gs_index(0);
 	regs->ip		= new_ip;
 	regs->sp		= new_sp;
 	percpu_write(old_rsp, new_sp);
-	regs->cs		= __USER_CS;
-	regs->ss		= __USER_DS;
-	regs->flags		= 0x200;
+	regs->cs		= _cs;
+	regs->ss		= _ss;
+	regs->flags		= X86_EFLAGS_IF;
 	set_fs(USER_DS);
 	/*
 	 * Free the old FP and other extended state
 	 */
 	free_thread_xstate(current);
 }
-EXPORT_SYMBOL_GPL(start_thread);
+
+void
+start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
+{
+	start_thread_common(regs, new_ip, new_sp,
+			    __USER_CS, __USER_DS, 0);
+}
+
+#ifdef CONFIG_IA32_EMULATION
+void start_thread_ia32(struct pt_regs *regs, u32 new_ip, u32 new_sp)
+{
+	start_thread_common(regs, new_ip, new_sp,
+			    __USER32_CS, __USER32_DS, __USER32_DS);
+}
+#endif
 
 /*
  *	switch_to(x,y) should switch tasks from x to y.
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c
index 6c3b2c6..18093d7 100644
--- a/arch/x86/kernel/quirks.c
+++ b/arch/x86/kernel/quirks.c
@@ -499,6 +499,7 @@
 {
 	struct pci_dev *nb_ht;
 	unsigned int devfn;
+	u32 node;
 	u32 val;
 
 	devfn = PCI_DEVFN(PCI_SLOT(dev->devfn), 0);
@@ -507,7 +508,13 @@
 		return;
 
 	pci_read_config_dword(nb_ht, 0x60, &val);
-	set_dev_node(&dev->dev, val & 7);
+	node = val & 7;
+	/*
+	 * Some hardware may return an invalid node ID,
+	 * so check it first:
+	 */
+	if (node_online(node))
+		set_dev_node(&dev->dev, node);
 	pci_dev_put(nb_ht);
 }
 
diff --git a/arch/x86/kernel/reboot_fixups_32.c b/arch/x86/kernel/reboot_fixups_32.c
index 61a8377..201eab6 100644
--- a/arch/x86/kernel/reboot_fixups_32.c
+++ b/arch/x86/kernel/reboot_fixups_32.c
@@ -80,6 +80,7 @@
 			continue;
 
 		cur->reboot_fixup(dev);
+		pci_dev_put(dev);
 	}
 }
 
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 82e88cd..946a311 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -106,6 +106,7 @@
 #include <asm/percpu.h>
 #include <asm/topology.h>
 #include <asm/apicdef.h>
+#include <asm/k8.h>
 #ifdef CONFIG_X86_64
 #include <asm/numa_64.h>
 #endif
@@ -487,42 +488,11 @@
 
 #ifdef CONFIG_KEXEC
 
-/**
- * Reserve @size bytes of crashkernel memory at any suitable offset.
- *
- * @size: Size of the crashkernel memory to reserve.
- * Returns the base address on success, and -1ULL on failure.
- */
-static
-unsigned long long __init find_and_reserve_crashkernel(unsigned long long size)
-{
-	const unsigned long long alignment = 16<<20; 	/* 16M */
-	unsigned long long start = 0LL;
-
-	while (1) {
-		int ret;
-
-		start = find_e820_area(start, ULONG_MAX, size, alignment);
-		if (start == -1ULL)
-			return start;
-
-		/* try to reserve it */
-		ret = reserve_bootmem_generic(start, size, BOOTMEM_EXCLUSIVE);
-		if (ret >= 0)
-			return start;
-
-		start += alignment;
-	}
-}
-
 static inline unsigned long long get_total_mem(void)
 {
 	unsigned long long total;
 
-	total = max_low_pfn - min_low_pfn;
-#ifdef CONFIG_HIGHMEM
-	total += highend_pfn - highstart_pfn;
-#endif
+	total = max_pfn - min_low_pfn;
 
 	return total << PAGE_SHIFT;
 }
@@ -542,21 +512,25 @@
 
 	/* 0 means: find the address automatically */
 	if (crash_base <= 0) {
-		crash_base = find_and_reserve_crashkernel(crash_size);
+		const unsigned long long alignment = 16<<20;	/* 16M */
+
+		crash_base = find_e820_area(alignment, ULONG_MAX, crash_size,
+				 alignment);
 		if (crash_base == -1ULL) {
-			pr_info("crashkernel reservation failed. "
-				"No suitable area found.\n");
+			pr_info("crashkernel reservation failed - No suitable area found.\n");
 			return;
 		}
 	} else {
-		ret = reserve_bootmem_generic(crash_base, crash_size,
-					BOOTMEM_EXCLUSIVE);
-		if (ret < 0) {
-			pr_info("crashkernel reservation failed - "
-				"memory is in use\n");
+		unsigned long long start;
+
+		start = find_e820_area(crash_base, ULONG_MAX, crash_size,
+				 1<<20);
+		if (start != crash_base) {
+			pr_info("crashkernel reservation failed - memory is in use.\n");
 			return;
 		}
 	}
+	reserve_early(crash_base, crash_base + crash_size, "CRASH KERNEL");
 
 	printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
 			"for crashkernel (System RAM: %ldMB)\n",
@@ -699,6 +673,9 @@
 
 void __init setup_arch(char **cmdline_p)
 {
+	int acpi = 0;
+	int k8 = 0;
+
 #ifdef CONFIG_X86_32
 	memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
 	visws_early_detect();
@@ -791,21 +768,18 @@
 	strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
 	*cmdline_p = command_line;
 
-#ifdef CONFIG_X86_64
 	/*
-	 * Must call this twice: Once just to detect whether hardware doesn't
-	 * support NX (so that the early EHCI debug console setup can safely
-	 * call set_fixmap(), and then again after parsing early parameters to
-	 * honor the respective command line option.
+	 * x86_configure_nx() is called before parse_early_param() to detect
+	 * whether hardware doesn't support NX (so that the early EHCI debug
+	 * console setup can safely call set_fixmap()). It may then be called
+	 * again from within noexec_setup() during parsing early parameters
+	 * to honor the respective command line option.
 	 */
-	check_efer();
-#endif
+	x86_configure_nx();
 
 	parse_early_param();
 
-#ifdef CONFIG_X86_64
-	check_efer();
-#endif
+	x86_report_nx();
 
 	/* Must be before kernel pagetables are setup */
 	vmi_activate();
@@ -901,6 +875,13 @@
 
 	reserve_brk();
 
+#ifdef CONFIG_ACPI_SLEEP
+	/*
+	 * Reserve low memory region for sleep support.
+	 * even before init_memory_mapping
+	 */
+	acpi_reserve_wakeup_memory();
+#endif
 	init_gbpages();
 
 	/* max_pfn_mapped is updated here */
@@ -927,6 +908,8 @@
 
 	reserve_initrd();
 
+	reserve_crashkernel();
+
 	vsmp_init();
 
 	io_delay_init();
@@ -938,27 +921,24 @@
 
 	early_acpi_boot_init();
 
-#ifdef CONFIG_ACPI_NUMA
-	/*
-	 * Parse SRAT to discover nodes.
-	 */
-	acpi_numa_init();
-#endif
-
-	initmem_init(0, max_pfn);
-
-#ifdef CONFIG_ACPI_SLEEP
-	/*
-	 * Reserve low memory region for sleep support.
-	 */
-	acpi_reserve_bootmem();
-#endif
 	/*
 	 * Find and reserve possible boot-time SMP configuration:
 	 */
 	find_smp_config();
 
-	reserve_crashkernel();
+#ifdef CONFIG_ACPI_NUMA
+	/*
+	 * Parse SRAT to discover nodes.
+	 */
+	acpi = acpi_numa_init();
+#endif
+
+#ifdef CONFIG_K8_NUMA
+	if (!acpi)
+		k8 = !k8_numa_init(0, max_pfn);
+#endif
+
+	initmem_init(0, max_pfn, acpi, k8);
 
 #ifdef CONFIG_X86_64
 	/*
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 324f2a4..29e6744 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -687,7 +687,7 @@
 		.done	= COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
 	};
 
-	INIT_WORK(&c_idle.work, do_fork_idle);
+	INIT_WORK_ON_STACK(&c_idle.work, do_fork_idle);
 
 	alternatives_smp_switch(1);
 
@@ -713,6 +713,7 @@
 
 	if (IS_ERR(c_idle.idle)) {
 		printk("failed fork for CPU %d\n", cpu);
+		destroy_work_on_stack(&c_idle.work);
 		return PTR_ERR(c_idle.idle);
 	}
 
@@ -831,6 +832,7 @@
 		smpboot_restore_warm_reset_vector();
 	}
 
+	destroy_work_on_stack(&c_idle.work);
 	return boot_error;
 }
 
diff --git a/arch/x86/kernel/sys_i386_32.c b/arch/x86/kernel/sys_i386_32.c
index 1884a8d..dee1ff7 100644
--- a/arch/x86/kernel/sys_i386_32.c
+++ b/arch/x86/kernel/sys_i386_32.c
@@ -24,31 +24,6 @@
 
 #include <asm/syscalls.h>
 
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-			  unsigned long prot, unsigned long flags,
-			  unsigned long fd, unsigned long pgoff)
-{
-	int error = -EBADF;
-	struct file *file = NULL;
-	struct mm_struct *mm = current->mm;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-
 /*
  * Perform the select(nd, in, out, ex, tv) and mmap() system
  * calls. Linux/i386 didn't use to be able to handle more than
@@ -77,7 +52,7 @@
 	if (a.offset & ~PAGE_MASK)
 		goto out;
 
-	err = sys_mmap2(a.addr, a.len, a.prot, a.flags,
+	err = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags,
 			a.fd, a.offset >> PAGE_SHIFT);
 out:
 	return err;
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index 45e00eb..8aa2057 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -23,26 +23,11 @@
 		unsigned long, fd, unsigned long, off)
 {
 	long error;
-	struct file *file;
-
 	error = -EINVAL;
 	if (off & ~PAGE_MASK)
 		goto out;
 
-	error = -EBADF;
-	file = NULL;
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
+	error = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
 out:
 	return error;
 }
diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S
index 70c2125..15228b5 100644
--- a/arch/x86/kernel/syscall_table_32.S
+++ b/arch/x86/kernel/syscall_table_32.S
@@ -191,7 +191,7 @@
 	.long sys_ni_syscall	/* reserved for streams2 */
 	.long ptregs_vfork	/* 190 */
 	.long sys_getrlimit
-	.long sys_mmap2
+	.long sys_mmap_pgoff
 	.long sys_truncate64
 	.long sys_ftruncate64
 	.long sys_stat64	/* 195 */
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c
index 1740c85..364d015ef 100644
--- a/arch/x86/kernel/tlb_uv.c
+++ b/arch/x86/kernel/tlb_uv.c
@@ -817,10 +817,8 @@
 	 */
 	apicid = blade_to_first_apicid(blade);
 	pa = uv_read_global_mmr64(pnode, UVH_BAU_DATA_CONFIG);
-	if ((pa & 0xff) != UV_BAU_MESSAGE) {
-		uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG,
+	uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG,
 				      ((apicid << 32) | UV_BAU_MESSAGE));
-	}
 	return 0;
 }
 
diff --git a/arch/x86/kernel/uv_time.c b/arch/x86/kernel/uv_time.c
index 583f11d..3c84aa0 100644
--- a/arch/x86/kernel/uv_time.c
+++ b/arch/x86/kernel/uv_time.c
@@ -74,7 +74,7 @@
  */
 static struct uv_rtc_timer_head		**blade_info __read_mostly;
 
-static int				uv_rtc_enable;
+static int				uv_rtc_evt_enable;
 
 /*
  * Hardware interface routines
@@ -90,7 +90,7 @@
 	pnode = uv_apicid_to_pnode(apicid);
 	val = (1UL << UVH_IPI_INT_SEND_SHFT) |
 	      (apicid << UVH_IPI_INT_APIC_ID_SHFT) |
-	      (GENERIC_INTERRUPT_VECTOR << UVH_IPI_INT_VECTOR_SHFT);
+	      (X86_PLATFORM_IPI_VECTOR << UVH_IPI_INT_VECTOR_SHFT);
 
 	uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
 }
@@ -115,7 +115,7 @@
 	uv_write_global_mmr64(pnode, UVH_EVENT_OCCURRED0_ALIAS,
 		UVH_EVENT_OCCURRED0_RTC1_MASK);
 
-	val = (GENERIC_INTERRUPT_VECTOR << UVH_RTC1_INT_CONFIG_VECTOR_SHFT) |
+	val = (X86_PLATFORM_IPI_VECTOR << UVH_RTC1_INT_CONFIG_VECTOR_SHFT) |
 		((u64)cpu_physical_id(cpu) << UVH_RTC1_INT_CONFIG_APIC_ID_SHFT);
 
 	/* Set configuration */
@@ -123,7 +123,10 @@
 	/* Initialize comparator value */
 	uv_write_global_mmr64(pnode, UVH_INT_CMPB, expires);
 
-	return (expires < uv_read_rtc(NULL) && !uv_intr_pending(pnode));
+	if (uv_read_rtc(NULL) <= expires)
+		return 0;
+
+	return !uv_intr_pending(pnode);
 }
 
 /*
@@ -223,6 +226,7 @@
 
 	next_cpu = head->next_cpu;
 	*t = expires;
+
 	/* Will this one be next to go off? */
 	if (next_cpu < 0 || bcpu == next_cpu ||
 			expires < head->cpu[next_cpu].expires) {
@@ -231,7 +235,7 @@
 			*t = ULLONG_MAX;
 			uv_rtc_find_next_timer(head, pnode);
 			spin_unlock_irqrestore(&head->lock, flags);
-			return 1;
+			return -ETIME;
 		}
 	}
 
@@ -244,7 +248,7 @@
  *
  * Returns 1 if this timer was pending.
  */
-static int uv_rtc_unset_timer(int cpu)
+static int uv_rtc_unset_timer(int cpu, int force)
 {
 	int pnode = uv_cpu_to_pnode(cpu);
 	int bid = uv_cpu_to_blade_id(cpu);
@@ -256,14 +260,15 @@
 
 	spin_lock_irqsave(&head->lock, flags);
 
-	if (head->next_cpu == bcpu && uv_read_rtc(NULL) >= *t)
+	if ((head->next_cpu == bcpu && uv_read_rtc(NULL) >= *t) || force)
 		rc = 1;
 
-	*t = ULLONG_MAX;
-
-	/* Was the hardware setup for this timer? */
-	if (head->next_cpu == bcpu)
-		uv_rtc_find_next_timer(head, pnode);
+	if (rc) {
+		*t = ULLONG_MAX;
+		/* Was the hardware setup for this timer? */
+		if (head->next_cpu == bcpu)
+			uv_rtc_find_next_timer(head, pnode);
+	}
 
 	spin_unlock_irqrestore(&head->lock, flags);
 
@@ -310,32 +315,32 @@
 		break;
 	case CLOCK_EVT_MODE_UNUSED:
 	case CLOCK_EVT_MODE_SHUTDOWN:
-		uv_rtc_unset_timer(ced_cpu);
+		uv_rtc_unset_timer(ced_cpu, 1);
 		break;
 	}
 }
 
 static void uv_rtc_interrupt(void)
 {
-	struct clock_event_device *ced = &__get_cpu_var(cpu_ced);
 	int cpu = smp_processor_id();
+	struct clock_event_device *ced = &per_cpu(cpu_ced, cpu);
 
 	if (!ced || !ced->event_handler)
 		return;
 
-	if (uv_rtc_unset_timer(cpu) != 1)
+	if (uv_rtc_unset_timer(cpu, 0) != 1)
 		return;
 
 	ced->event_handler(ced);
 }
 
-static int __init uv_enable_rtc(char *str)
+static int __init uv_enable_evt_rtc(char *str)
 {
-	uv_rtc_enable = 1;
+	uv_rtc_evt_enable = 1;
 
 	return 1;
 }
-__setup("uvrtc", uv_enable_rtc);
+__setup("uvrtcevt", uv_enable_evt_rtc);
 
 static __init void uv_rtc_register_clockevents(struct work_struct *dummy)
 {
@@ -350,27 +355,32 @@
 {
 	int rc;
 
-	if (!uv_rtc_enable || !is_uv_system() || generic_interrupt_extension)
+	if (!is_uv_system())
 		return -ENODEV;
 
-	generic_interrupt_extension = uv_rtc_interrupt;
-
 	clocksource_uv.mult = clocksource_hz2mult(sn_rtc_cycles_per_second,
 				clocksource_uv.shift);
 
+	/* If single blade, prefer tsc */
+	if (uv_num_possible_blades() == 1)
+		clocksource_uv.rating = 250;
+
 	rc = clocksource_register(&clocksource_uv);
-	if (rc) {
-		generic_interrupt_extension = NULL;
+	if (rc)
+		printk(KERN_INFO "UV RTC clocksource failed rc %d\n", rc);
+	else
+		printk(KERN_INFO "UV RTC clocksource registered freq %lu MHz\n",
+			sn_rtc_cycles_per_second/(unsigned long)1E6);
+
+	if (rc || !uv_rtc_evt_enable || x86_platform_ipi_callback)
 		return rc;
-	}
 
 	/* Setup and register clockevents */
 	rc = uv_rtc_allocate_timers();
-	if (rc) {
-		clocksource_unregister(&clocksource_uv);
-		generic_interrupt_extension = NULL;
-		return rc;
-	}
+	if (rc)
+		goto error;
+
+	x86_platform_ipi_callback = uv_rtc_interrupt;
 
 	clock_event_device_uv.mult = div_sc(sn_rtc_cycles_per_second,
 				NSEC_PER_SEC, clock_event_device_uv.shift);
@@ -383,11 +393,19 @@
 
 	rc = schedule_on_each_cpu(uv_rtc_register_clockevents);
 	if (rc) {
-		clocksource_unregister(&clocksource_uv);
-		generic_interrupt_extension = NULL;
+		x86_platform_ipi_callback = NULL;
 		uv_rtc_deallocate_timers();
+		goto error;
 	}
 
+	printk(KERN_INFO "UV RTC clockevents registered\n");
+
+	return 0;
+
+error:
+	clocksource_unregister(&clocksource_uv);
+	printk(KERN_INFO "UV RTC clockevents failed rc %d\n", rc);
+
 	return rc;
 }
 arch_initcall(uv_rtc_setup_clock);
diff --git a/arch/x86/kernel/visws_quirks.c b/arch/x86/kernel/visws_quirks.c
index abda6f5..34a279a 100644
--- a/arch/x86/kernel/visws_quirks.c
+++ b/arch/x86/kernel/visws_quirks.c
@@ -197,7 +197,7 @@
 	apic_version[m->apicid] = ver;
 }
 
-static void __init visws_find_smp_config(unsigned int reserve)
+static void __init visws_find_smp_config(void)
 {
 	struct mpc_cpu *mp = phys_to_virt(CO_CPU_TAB_PHYS);
 	unsigned short ncpus = readw(phys_to_virt(CO_CPU_NUM_PHYS));
diff --git a/arch/x86/kernel/vmiclock_32.c b/arch/x86/kernel/vmiclock_32.c
index 611b9e2..74c92bb 100644
--- a/arch/x86/kernel/vmiclock_32.c
+++ b/arch/x86/kernel/vmiclock_32.c
@@ -226,7 +226,7 @@
 	evt->min_delta_ns = clockevent_delta2ns(1, evt);
 	evt->cpumask = cpumask_of(cpu);
 
-	printk(KERN_WARNING "vmi: registering clock event %s. mult=%lu shift=%u\n",
+	printk(KERN_WARNING "vmi: registering clock event %s. mult=%u shift=%u\n",
 	       evt->name, evt->mult, evt->shift);
 	clockevents_register_device(evt);
 }
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 3c68fe2..f3f2104 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -41,6 +41,32 @@
 jiffies_64 = jiffies;
 #endif
 
+#if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA)
+/*
+ * On 64-bit, align RODATA to 2MB so that even with CONFIG_DEBUG_RODATA
+ * we retain large page mappings for boundaries spanning kernel text, rodata
+ * and data sections.
+ *
+ * However, kernel identity mappings will have different RWX permissions
+ * to the pages mapping to text and to the pages padding (which are freed) the
+ * text section. Hence kernel identity mappings will be broken to smaller
+ * pages. For 64-bit, kernel text and kernel identity mappings are different,
+ * so we can enable protection checks that come with CONFIG_DEBUG_RODATA,
+ * as well as retain 2MB large page mappings for kernel text.
+ */
+#define X64_ALIGN_DEBUG_RODATA_BEGIN	. = ALIGN(HPAGE_SIZE);
+
+#define X64_ALIGN_DEBUG_RODATA_END				\
+		. = ALIGN(HPAGE_SIZE);				\
+		__end_rodata_hpage_align = .;
+
+#else
+
+#define X64_ALIGN_DEBUG_RODATA_BEGIN
+#define X64_ALIGN_DEBUG_RODATA_END
+
+#endif
+
 PHDRS {
 	text PT_LOAD FLAGS(5);          /* R_E */
 	data PT_LOAD FLAGS(7);          /* RWE */
@@ -90,7 +116,9 @@
 
 	EXCEPTION_TABLE(16) :text = 0x9090
 
+	X64_ALIGN_DEBUG_RODATA_BEGIN
 	RO_DATA(PAGE_SIZE)
+	X64_ALIGN_DEBUG_RODATA_END
 
 	/* Data */
 	.data : AT(ADDR(.data) - LOAD_OFFSET) {
@@ -107,13 +135,13 @@
 
 		PAGE_ALIGNED_DATA(PAGE_SIZE)
 
-		CACHELINE_ALIGNED_DATA(CONFIG_X86_L1_CACHE_BYTES)
+		CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)
 
 		DATA_DATA
 		CONSTRUCTORS
 
 		/* rarely changed data like cpu maps */
-		READ_MOSTLY_DATA(CONFIG_X86_INTERNODE_CACHE_BYTES)
+		READ_MOSTLY_DATA(INTERNODE_CACHE_BYTES)
 
 		/* End of data section */
 		_edata = .;
@@ -137,12 +165,12 @@
 		*(.vsyscall_0)
 	} :user
 
-	. = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
+	. = ALIGN(L1_CACHE_BYTES);
 	.vsyscall_fn : AT(VLOAD(.vsyscall_fn)) {
 		*(.vsyscall_fn)
 	}
 
-	. = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
+	. = ALIGN(L1_CACHE_BYTES);
 	.vsyscall_gtod_data : AT(VLOAD(.vsyscall_gtod_data)) {
 		*(.vsyscall_gtod_data)
 	}
@@ -166,7 +194,7 @@
 	}
 	vgetcpu_mode = VVIRT(.vgetcpu_mode);
 
-	. = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
+	. = ALIGN(L1_CACHE_BYTES);
 	.jiffies : AT(VLOAD(.jiffies)) {
 		*(.jiffies)
 	}
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index e02d92d..9055e58 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -73,7 +73,8 @@
 	write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags);
 }
 
-void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
+void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
+		     u32 mult)
 {
 	unsigned long flags;
 
@@ -82,7 +83,7 @@
 	vsyscall_gtod_data.clock.vread = clock->vread;
 	vsyscall_gtod_data.clock.cycle_last = clock->cycle_last;
 	vsyscall_gtod_data.clock.mask = clock->mask;
-	vsyscall_gtod_data.clock.mult = clock->mult;
+	vsyscall_gtod_data.clock.mult = mult;
 	vsyscall_gtod_data.clock.shift = clock->shift;
 	vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec;
 	vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec;
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index d11c5ff..ccd179d 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -13,6 +13,7 @@
 #include <asm/e820.h>
 #include <asm/time.h>
 #include <asm/irq.h>
+#include <asm/pat.h>
 #include <asm/tsc.h>
 #include <asm/iommu.h>
 
@@ -80,4 +81,5 @@
 	.get_wallclock			= mach_get_cmos_time,
 	.set_wallclock			= mach_set_rtc_mmss,
 	.iommu_shutdown			= iommu_shutdown_noop,
+	.is_untracked_pat_range		= is_ISA_range,
 };
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 73ffd55..d406c52 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -146,10 +146,6 @@
 	use_gbpages = direct_gbpages;
 #endif
 
-	set_nx();
-	if (nx_enabled)
-		printk(KERN_INFO "NX (Execute Disable) protection: active\n");
-
 	/* Enable PSE if available */
 	if (cpu_has_pse)
 		set_in_cr4(X86_CR4_PSE);
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 30938c1..c973f8e 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -412,7 +412,7 @@
 	pkmap_page_table = pte;
 }
 
-static void __init add_one_highpage_init(struct page *page, int pfn)
+static void __init add_one_highpage_init(struct page *page)
 {
 	ClearPageReserved(page);
 	init_page_count(page);
@@ -445,7 +445,7 @@
 		if (!pfn_valid(node_pfn))
 			continue;
 		page = pfn_to_page(node_pfn);
-		add_one_highpage_init(page, node_pfn);
+		add_one_highpage_init(page);
 	}
 
 	return 0;
@@ -703,8 +703,8 @@
 }
 
 #ifndef CONFIG_NEED_MULTIPLE_NODES
-void __init initmem_init(unsigned long start_pfn,
-				  unsigned long end_pfn)
+void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn,
+				int acpi, int k8)
 {
 #ifdef CONFIG_HIGHMEM
 	highstart_pfn = highend_pfn = max_pfn;
@@ -997,7 +997,7 @@
 const int rodata_test_data = 0xC3;
 EXPORT_SYMBOL_GPL(rodata_test_data);
 
-static int kernel_set_to_readonly;
+int kernel_set_to_readonly __read_mostly;
 
 void set_kernel_text_rw(void)
 {
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 5a4398a..5198b9b 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -568,7 +568,8 @@
 }
 
 #ifndef CONFIG_NUMA
-void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn)
+void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn,
+				int acpi, int k8)
 {
 	unsigned long bootmap_size, bootmap;
 
@@ -694,12 +695,12 @@
 const int rodata_test_data = 0xC3;
 EXPORT_SYMBOL_GPL(rodata_test_data);
 
-static int kernel_set_to_readonly;
+int kernel_set_to_readonly;
 
 void set_kernel_text_rw(void)
 {
-	unsigned long start = PFN_ALIGN(_stext);
-	unsigned long end = PFN_ALIGN(__start_rodata);
+	unsigned long start = PFN_ALIGN(_text);
+	unsigned long end = PFN_ALIGN(__stop___ex_table);
 
 	if (!kernel_set_to_readonly)
 		return;
@@ -707,13 +708,18 @@
 	pr_debug("Set kernel text: %lx - %lx for read write\n",
 		 start, end);
 
+	/*
+	 * Make the kernel identity mapping for text RW. Kernel text
+	 * mapping will always be RO. Refer to the comment in
+	 * static_protections() in pageattr.c
+	 */
 	set_memory_rw(start, (end - start) >> PAGE_SHIFT);
 }
 
 void set_kernel_text_ro(void)
 {
-	unsigned long start = PFN_ALIGN(_stext);
-	unsigned long end = PFN_ALIGN(__start_rodata);
+	unsigned long start = PFN_ALIGN(_text);
+	unsigned long end = PFN_ALIGN(__stop___ex_table);
 
 	if (!kernel_set_to_readonly)
 		return;
@@ -721,14 +727,21 @@
 	pr_debug("Set kernel text: %lx - %lx for read only\n",
 		 start, end);
 
+	/*
+	 * Set the kernel identity mapping for text RO.
+	 */
 	set_memory_ro(start, (end - start) >> PAGE_SHIFT);
 }
 
 void mark_rodata_ro(void)
 {
-	unsigned long start = PFN_ALIGN(_stext), end = PFN_ALIGN(__end_rodata);
+	unsigned long start = PFN_ALIGN(_text);
 	unsigned long rodata_start =
 		((unsigned long)__start_rodata + PAGE_SIZE - 1) & PAGE_MASK;
+	unsigned long end = (unsigned long) &__end_rodata_hpage_align;
+	unsigned long text_end = PAGE_ALIGN((unsigned long) &__stop___ex_table);
+	unsigned long rodata_end = PAGE_ALIGN((unsigned long) &__end_rodata);
+	unsigned long data_start = (unsigned long) &_sdata;
 
 	printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
 	       (end - start) >> 10);
@@ -751,6 +764,14 @@
 	printk(KERN_INFO "Testing CPA: again\n");
 	set_memory_ro(start, (end-start) >> PAGE_SHIFT);
 #endif
+
+	free_init_pages("unused kernel memory",
+			(unsigned long) page_address(virt_to_page(text_end)),
+			(unsigned long)
+				 page_address(virt_to_page(rodata_start)));
+	free_init_pages("unused kernel memory",
+			(unsigned long) page_address(virt_to_page(rodata_end)),
+			(unsigned long) page_address(virt_to_page(data_start)));
 }
 
 #endif
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 2feb9bd..c246d25 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -281,30 +281,6 @@
 }
 EXPORT_SYMBOL(ioremap_cache);
 
-static void __iomem *ioremap_default(resource_size_t phys_addr,
-					unsigned long size)
-{
-	unsigned long flags;
-	void __iomem *ret;
-	int err;
-
-	/*
-	 * - WB for WB-able memory and no other conflicting mappings
-	 * - UC_MINUS for non-WB-able memory with no other conflicting mappings
-	 * - Inherit from confliting mappings otherwise
-	 */
-	err = reserve_memtype(phys_addr, phys_addr + size,
-				_PAGE_CACHE_WB, &flags);
-	if (err < 0)
-		return NULL;
-
-	ret = __ioremap_caller(phys_addr, size, flags,
-			       __builtin_return_address(0));
-
-	free_memtype(phys_addr, phys_addr + size);
-	return ret;
-}
-
 void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size,
 				unsigned long prot_val)
 {
@@ -380,7 +356,7 @@
 	if (page_is_ram(start >> PAGE_SHIFT))
 		return __va(phys);
 
-	addr = (void __force *)ioremap_default(start, PAGE_SIZE);
+	addr = (void __force *)ioremap_cache(start, PAGE_SIZE);
 	if (addr)
 		addr = (void *)((unsigned long)addr | (phys & ~PAGE_MASK));
 
diff --git a/arch/x86/mm/k8topology_64.c b/arch/x86/mm/k8topology_64.c
index 268f825..970ed57 100644
--- a/arch/x86/mm/k8topology_64.c
+++ b/arch/x86/mm/k8topology_64.c
@@ -24,6 +24,9 @@
 #include <asm/apic.h>
 #include <asm/k8.h>
 
+static struct bootnode __initdata nodes[8];
+static nodemask_t __initdata nodes_parsed = NODE_MASK_NONE;
+
 static __init int find_northbridge(void)
 {
 	int num;
@@ -54,18 +57,6 @@
 	 * need to get boot_cpu_id so can use that to create apicid_to_node
 	 * in k8_scan_nodes()
 	 */
-	/*
-	 * Find possible boot-time SMP configuration:
-	 */
-#ifdef CONFIG_X86_MPPARSE
-	early_find_smp_config();
-#endif
-#ifdef CONFIG_ACPI
-	/*
-	 * Read APIC information from ACPI tables.
-	 */
-	early_acpi_boot_init();
-#endif
 #ifdef CONFIG_X86_MPPARSE
 	/*
 	 * get boot-time SMP configuration:
@@ -76,12 +67,26 @@
 	early_init_lapic_mapping();
 }
 
-int __init k8_scan_nodes(unsigned long start, unsigned long end)
+int __init k8_get_nodes(struct bootnode *physnodes)
 {
-	unsigned numnodes, cores, bits, apicid_base;
+	int i;
+	int ret = 0;
+
+	for_each_node_mask(i, nodes_parsed) {
+		physnodes[ret].start = nodes[i].start;
+		physnodes[ret].end = nodes[i].end;
+		ret++;
+	}
+	return ret;
+}
+
+int __init k8_numa_init(unsigned long start_pfn, unsigned long end_pfn)
+{
+	unsigned long start = PFN_PHYS(start_pfn);
+	unsigned long end = PFN_PHYS(end_pfn);
+	unsigned numnodes;
 	unsigned long prevbase;
-	struct bootnode nodes[8];
-	int i, j, nb, found = 0;
+	int i, nb, found = 0;
 	u32 nodeid, reg;
 
 	if (!early_pci_allowed())
@@ -91,16 +96,15 @@
 	if (nb < 0)
 		return nb;
 
-	printk(KERN_INFO "Scanning NUMA topology in Northbridge %d\n", nb);
+	pr_info("Scanning NUMA topology in Northbridge %d\n", nb);
 
 	reg = read_pci_config(0, nb, 0, 0x60);
 	numnodes = ((reg >> 4) & 0xF) + 1;
 	if (numnodes <= 1)
 		return -1;
 
-	printk(KERN_INFO "Number of nodes %d\n", numnodes);
+	pr_info("Number of physical nodes %d\n", numnodes);
 
-	memset(&nodes, 0, sizeof(nodes));
 	prevbase = 0;
 	for (i = 0; i < 8; i++) {
 		unsigned long base, limit;
@@ -111,28 +115,28 @@
 		nodeid = limit & 7;
 		if ((base & 3) == 0) {
 			if (i < numnodes)
-				printk("Skipping disabled node %d\n", i);
+				pr_info("Skipping disabled node %d\n", i);
 			continue;
 		}
 		if (nodeid >= numnodes) {
-			printk("Ignoring excess node %d (%lx:%lx)\n", nodeid,
-			       base, limit);
+			pr_info("Ignoring excess node %d (%lx:%lx)\n", nodeid,
+				base, limit);
 			continue;
 		}
 
 		if (!limit) {
-			printk(KERN_INFO "Skipping node entry %d (base %lx)\n",
-			       i, base);
+			pr_info("Skipping node entry %d (base %lx)\n",
+				i, base);
 			continue;
 		}
 		if ((base >> 8) & 3 || (limit >> 8) & 3) {
-			printk(KERN_ERR "Node %d using interleaving mode %lx/%lx\n",
-			       nodeid, (base>>8)&3, (limit>>8) & 3);
+			pr_err("Node %d using interleaving mode %lx/%lx\n",
+			       nodeid, (base >> 8) & 3, (limit >> 8) & 3);
 			return -1;
 		}
-		if (node_isset(nodeid, node_possible_map)) {
-			printk(KERN_INFO "Node %d already present. Skipping\n",
-			       nodeid);
+		if (node_isset(nodeid, nodes_parsed)) {
+			pr_info("Node %d already present, skipping\n",
+				nodeid);
 			continue;
 		}
 
@@ -141,8 +145,8 @@
 		limit |= (1<<24)-1;
 		limit++;
 
-		if (limit > max_pfn << PAGE_SHIFT)
-			limit = max_pfn << PAGE_SHIFT;
+		if (limit > end)
+			limit = end;
 		if (limit <= base)
 			continue;
 
@@ -154,24 +158,24 @@
 		if (limit > end)
 			limit = end;
 		if (limit == base) {
-			printk(KERN_ERR "Empty node %d\n", nodeid);
+			pr_err("Empty node %d\n", nodeid);
 			continue;
 		}
 		if (limit < base) {
-			printk(KERN_ERR "Node %d bogus settings %lx-%lx.\n",
+			pr_err("Node %d bogus settings %lx-%lx.\n",
 			       nodeid, base, limit);
 			continue;
 		}
 
 		/* Could sort here, but pun for now. Should not happen anyroads. */
 		if (prevbase > base) {
-			printk(KERN_ERR "Node map not sorted %lx,%lx\n",
+			pr_err("Node map not sorted %lx,%lx\n",
 			       prevbase, base);
 			return -1;
 		}
 
-		printk(KERN_INFO "Node %d MemBase %016lx Limit %016lx\n",
-		       nodeid, base, limit);
+		pr_info("Node %d MemBase %016lx Limit %016lx\n",
+			nodeid, base, limit);
 
 		found++;
 
@@ -180,18 +184,29 @@
 
 		prevbase = base;
 
-		node_set(nodeid, node_possible_map);
+		node_set(nodeid, nodes_parsed);
 	}
 
 	if (!found)
 		return -1;
+	return 0;
+}
 
+int __init k8_scan_nodes(void)
+{
+	unsigned int bits;
+	unsigned int cores;
+	unsigned int apicid_base;
+	int i;
+
+	BUG_ON(nodes_empty(nodes_parsed));
+	node_possible_map = nodes_parsed;
 	memnode_shift = compute_hash_shift(nodes, 8, NULL);
 	if (memnode_shift < 0) {
-		printk(KERN_ERR "No NUMA node hash function found. Contact maintainer\n");
+		pr_err("No NUMA node hash function found. Contact maintainer\n");
 		return -1;
 	}
-	printk(KERN_INFO "Using node hash shift of %d\n", memnode_shift);
+	pr_info("Using node hash shift of %d\n", memnode_shift);
 
 	/* use the coreid bits from early_identify_cpu */
 	bits = boot_cpu_data.x86_coreid_bits;
@@ -200,14 +215,12 @@
 	/* need to get boot_cpu_id early for system with apicid lifting */
 	early_get_boot_cpu_id();
 	if (boot_cpu_physical_apicid > 0) {
-		printk(KERN_INFO "BSP APIC ID: %02x\n",
-				 boot_cpu_physical_apicid);
+		pr_info("BSP APIC ID: %02x\n", boot_cpu_physical_apicid);
 		apicid_base = boot_cpu_physical_apicid;
 	}
 
-	for (i = 0; i < 8; i++) {
-		if (nodes[i].start == nodes[i].end)
-			continue;
+	for_each_node_mask(i, node_possible_map) {
+		int j;
 
 		e820_register_active_regions(i,
 				nodes[i].start >> PAGE_SHIFT,
diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c
index 11a4ad4..07bcc30 100644
--- a/arch/x86/mm/kmmio.c
+++ b/arch/x86/mm/kmmio.c
@@ -203,7 +203,7 @@
  */
 /*
  * Interrupts are disabled on entry as trap3 is an interrupt gate
- * and they remain disabled thorough out this function.
+ * and they remain disabled throughout this function.
  */
 int kmmio_handler(struct pt_regs *regs, unsigned long addr)
 {
@@ -302,7 +302,7 @@
 
 /*
  * Interrupts are disabled on entry as trap1 is an interrupt gate
- * and they remain disabled thorough out this function.
+ * and they remain disabled throughout this function.
  * This must always get called as the pair to kmmio_handler().
  */
 static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs)
diff --git a/arch/x86/mm/numa_32.c b/arch/x86/mm/numa_32.c
index d253006..b20760c 100644
--- a/arch/x86/mm/numa_32.c
+++ b/arch/x86/mm/numa_32.c
@@ -347,8 +347,8 @@
 		(ulong) node_remap_end_vaddr[nid]);
 }
 
-void __init initmem_init(unsigned long start_pfn,
-				  unsigned long end_pfn)
+void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn,
+				int acpi, int k8)
 {
 	int nid;
 	long kva_target_pfn;
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index 459913b..83bbc70 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -239,8 +239,14 @@
 	bootmap = early_node_mem(nodeid, bootmap_start, end,
 				 bootmap_pages<<PAGE_SHIFT, PAGE_SIZE);
 	if (bootmap == NULL)  {
-		if (nodedata_phys < start || nodedata_phys >= end)
-			free_bootmem(nodedata_phys, pgdat_size);
+		if (nodedata_phys < start || nodedata_phys >= end) {
+			/*
+			 * only need to free it if it is from other node
+			 * bootmem
+			 */
+			if (nid != nodeid)
+				free_bootmem(nodedata_phys, pgdat_size);
+		}
 		node_data[nodeid] = NULL;
 		return;
 	}
@@ -306,8 +312,71 @@
 
 #ifdef CONFIG_NUMA_EMU
 /* Numa emulation */
+static struct bootnode nodes[MAX_NUMNODES] __initdata;
+static struct bootnode physnodes[MAX_NUMNODES] __initdata;
 static char *cmdline __initdata;
 
+static int __init setup_physnodes(unsigned long start, unsigned long end,
+					int acpi, int k8)
+{
+	int nr_nodes = 0;
+	int ret = 0;
+	int i;
+
+#ifdef CONFIG_ACPI_NUMA
+	if (acpi)
+		nr_nodes = acpi_get_nodes(physnodes);
+#endif
+#ifdef CONFIG_K8_NUMA
+	if (k8)
+		nr_nodes = k8_get_nodes(physnodes);
+#endif
+	/*
+	 * Basic sanity checking on the physical node map: there may be errors
+	 * if the SRAT or K8 incorrectly reported the topology or the mem=
+	 * kernel parameter is used.
+	 */
+	for (i = 0; i < nr_nodes; i++) {
+		if (physnodes[i].start == physnodes[i].end)
+			continue;
+		if (physnodes[i].start > end) {
+			physnodes[i].end = physnodes[i].start;
+			continue;
+		}
+		if (physnodes[i].end < start) {
+			physnodes[i].start = physnodes[i].end;
+			continue;
+		}
+		if (physnodes[i].start < start)
+			physnodes[i].start = start;
+		if (physnodes[i].end > end)
+			physnodes[i].end = end;
+	}
+
+	/*
+	 * Remove all nodes that have no memory or were truncated because of the
+	 * limited address range.
+	 */
+	for (i = 0; i < nr_nodes; i++) {
+		if (physnodes[i].start == physnodes[i].end)
+			continue;
+		physnodes[ret].start = physnodes[i].start;
+		physnodes[ret].end = physnodes[i].end;
+		ret++;
+	}
+
+	/*
+	 * If no physical topology was detected, a single node is faked to cover
+	 * the entire address space.
+	 */
+	if (!ret) {
+		physnodes[ret].start = start;
+		physnodes[ret].end = end;
+		ret = 1;
+	}
+	return ret;
+}
+
 /*
  * Setups up nid to range from addr to addr + size.  If the end
  * boundary is greater than max_addr, then max_addr is used instead.
@@ -315,11 +384,9 @@
  * allocation past addr and -1 otherwise.  addr is adjusted to be at
  * the end of the node.
  */
-static int __init setup_node_range(int nid, struct bootnode *nodes, u64 *addr,
-				   u64 size, u64 max_addr)
+static int __init setup_node_range(int nid, u64 *addr, u64 size, u64 max_addr)
 {
 	int ret = 0;
-
 	nodes[nid].start = *addr;
 	*addr += size;
 	if (*addr >= max_addr) {
@@ -335,12 +402,111 @@
 }
 
 /*
+ * Sets up nr_nodes fake nodes interleaved over physical nodes ranging from addr
+ * to max_addr.  The return value is the number of nodes allocated.
+ */
+static int __init split_nodes_interleave(u64 addr, u64 max_addr,
+						int nr_phys_nodes, int nr_nodes)
+{
+	nodemask_t physnode_mask = NODE_MASK_NONE;
+	u64 size;
+	int big;
+	int ret = 0;
+	int i;
+
+	if (nr_nodes <= 0)
+		return -1;
+	if (nr_nodes > MAX_NUMNODES) {
+		pr_info("numa=fake=%d too large, reducing to %d\n",
+			nr_nodes, MAX_NUMNODES);
+		nr_nodes = MAX_NUMNODES;
+	}
+
+	size = (max_addr - addr - e820_hole_size(addr, max_addr)) / nr_nodes;
+	/*
+	 * Calculate the number of big nodes that can be allocated as a result
+	 * of consolidating the remainder.
+	 */
+	big = ((size & ~FAKE_NODE_MIN_HASH_MASK) & nr_nodes) /
+		FAKE_NODE_MIN_SIZE;
+
+	size &= FAKE_NODE_MIN_HASH_MASK;
+	if (!size) {
+		pr_err("Not enough memory for each node.  "
+			"NUMA emulation disabled.\n");
+		return -1;
+	}
+
+	for (i = 0; i < nr_phys_nodes; i++)
+		if (physnodes[i].start != physnodes[i].end)
+			node_set(i, physnode_mask);
+
+	/*
+	 * Continue to fill physical nodes with fake nodes until there is no
+	 * memory left on any of them.
+	 */
+	while (nodes_weight(physnode_mask)) {
+		for_each_node_mask(i, physnode_mask) {
+			u64 end = physnodes[i].start + size;
+			u64 dma32_end = PFN_PHYS(MAX_DMA32_PFN);
+
+			if (ret < big)
+				end += FAKE_NODE_MIN_SIZE;
+
+			/*
+			 * Continue to add memory to this fake node if its
+			 * non-reserved memory is less than the per-node size.
+			 */
+			while (end - physnodes[i].start -
+				e820_hole_size(physnodes[i].start, end) < size) {
+				end += FAKE_NODE_MIN_SIZE;
+				if (end > physnodes[i].end) {
+					end = physnodes[i].end;
+					break;
+				}
+			}
+
+			/*
+			 * If there won't be at least FAKE_NODE_MIN_SIZE of
+			 * non-reserved memory in ZONE_DMA32 for the next node,
+			 * this one must extend to the boundary.
+			 */
+			if (end < dma32_end && dma32_end - end -
+			    e820_hole_size(end, dma32_end) < FAKE_NODE_MIN_SIZE)
+				end = dma32_end;
+
+			/*
+			 * If there won't be enough non-reserved memory for the
+			 * next node, this one must extend to the end of the
+			 * physical node.
+			 */
+			if (physnodes[i].end - end -
+			    e820_hole_size(end, physnodes[i].end) < size)
+				end = physnodes[i].end;
+
+			/*
+			 * Avoid allocating more nodes than requested, which can
+			 * happen as a result of rounding down each node's size
+			 * to FAKE_NODE_MIN_SIZE.
+			 */
+			if (nodes_weight(physnode_mask) + ret >= nr_nodes)
+				end = physnodes[i].end;
+
+			if (setup_node_range(ret++, &physnodes[i].start,
+						end - physnodes[i].start,
+						physnodes[i].end) < 0)
+				node_clear(i, physnode_mask);
+		}
+	}
+	return ret;
+}
+
+/*
  * Splits num_nodes nodes up equally starting at node_start.  The return value
  * is the number of nodes split up and addr is adjusted to be at the end of the
  * last node allocated.
  */
-static int __init split_nodes_equally(struct bootnode *nodes, u64 *addr,
-				      u64 max_addr, int node_start,
+static int __init split_nodes_equally(u64 *addr, u64 max_addr, int node_start,
 				      int num_nodes)
 {
 	unsigned int big;
@@ -388,7 +554,7 @@
 					break;
 				}
 			}
-		if (setup_node_range(i, nodes, addr, end - *addr, max_addr) < 0)
+		if (setup_node_range(i, addr, end - *addr, max_addr) < 0)
 			break;
 	}
 	return i - node_start + 1;
@@ -399,12 +565,12 @@
  * always assigned to a final node and can be asymmetric.  Returns the number of
  * nodes split.
  */
-static int __init split_nodes_by_size(struct bootnode *nodes, u64 *addr,
-				      u64 max_addr, int node_start, u64 size)
+static int __init split_nodes_by_size(u64 *addr, u64 max_addr, int node_start,
+				      u64 size)
 {
 	int i = node_start;
 	size = (size << 20) & FAKE_NODE_MIN_HASH_MASK;
-	while (!setup_node_range(i++, nodes, addr, size, max_addr))
+	while (!setup_node_range(i++, addr, size, max_addr))
 		;
 	return i - node_start;
 }
@@ -413,15 +579,15 @@
  * Sets up the system RAM area from start_pfn to last_pfn according to the
  * numa=fake command-line option.
  */
-static struct bootnode nodes[MAX_NUMNODES] __initdata;
-
-static int __init numa_emulation(unsigned long start_pfn, unsigned long last_pfn)
+static int __init numa_emulation(unsigned long start_pfn,
+			unsigned long last_pfn, int acpi, int k8)
 {
 	u64 size, addr = start_pfn << PAGE_SHIFT;
 	u64 max_addr = last_pfn << PAGE_SHIFT;
 	int num_nodes = 0, num = 0, coeff_flag, coeff = -1, i;
+	int num_phys_nodes;
 
-	memset(&nodes, 0, sizeof(nodes));
+	num_phys_nodes = setup_physnodes(addr, max_addr, acpi, k8);
 	/*
 	 * If the numa=fake command-line is just a single number N, split the
 	 * system RAM into N fake nodes.
@@ -429,7 +595,8 @@
 	if (!strchr(cmdline, '*') && !strchr(cmdline, ',')) {
 		long n = simple_strtol(cmdline, NULL, 0);
 
-		num_nodes = split_nodes_equally(nodes, &addr, max_addr, 0, n);
+		num_nodes = split_nodes_interleave(addr, max_addr,
+							num_phys_nodes, n);
 		if (num_nodes < 0)
 			return num_nodes;
 		goto out;
@@ -456,8 +623,8 @@
 			size = ((u64)num << 20) & FAKE_NODE_MIN_HASH_MASK;
 			if (size)
 				for (i = 0; i < coeff; i++, num_nodes++)
-					if (setup_node_range(num_nodes, nodes,
-						&addr, size, max_addr) < 0)
+					if (setup_node_range(num_nodes, &addr,
+						size, max_addr) < 0)
 						goto done;
 			if (!*cmdline)
 				break;
@@ -473,7 +640,7 @@
 	if (addr < max_addr) {
 		if (coeff_flag && coeff < 0) {
 			/* Split remaining nodes into num-sized chunks */
-			num_nodes += split_nodes_by_size(nodes, &addr, max_addr,
+			num_nodes += split_nodes_by_size(&addr, max_addr,
 							 num_nodes, num);
 			goto out;
 		}
@@ -482,7 +649,7 @@
 			/* Split remaining nodes into coeff chunks */
 			if (coeff <= 0)
 				break;
-			num_nodes += split_nodes_equally(nodes, &addr, max_addr,
+			num_nodes += split_nodes_equally(&addr, max_addr,
 							 num_nodes, coeff);
 			break;
 		case ',':
@@ -490,8 +657,8 @@
 			break;
 		default:
 			/* Give one final node */
-			setup_node_range(num_nodes, nodes, &addr,
-					 max_addr - addr, max_addr);
+			setup_node_range(num_nodes, &addr, max_addr - addr,
+					 max_addr);
 			num_nodes++;
 		}
 	}
@@ -505,14 +672,10 @@
 	}
 
 	/*
-	 * We need to vacate all active ranges that may have been registered by
-	 * SRAT and set acpi_numa to -1 so that srat_disabled() always returns
-	 * true.  NUMA emulation has succeeded so we will not scan ACPI nodes.
+	 * We need to vacate all active ranges that may have been registered for
+	 * the e820 memory map.
 	 */
 	remove_all_active_ranges();
-#ifdef CONFIG_ACPI_NUMA
-	acpi_numa = -1;
-#endif
 	for_each_node_mask(i, node_possible_map) {
 		e820_register_active_regions(i, nodes[i].start >> PAGE_SHIFT,
 						nodes[i].end >> PAGE_SHIFT);
@@ -524,7 +687,8 @@
 }
 #endif /* CONFIG_NUMA_EMU */
 
-void __init initmem_init(unsigned long start_pfn, unsigned long last_pfn)
+void __init initmem_init(unsigned long start_pfn, unsigned long last_pfn,
+				int acpi, int k8)
 {
 	int i;
 
@@ -532,23 +696,22 @@
 	nodes_clear(node_online_map);
 
 #ifdef CONFIG_NUMA_EMU
-	if (cmdline && !numa_emulation(start_pfn, last_pfn))
+	if (cmdline && !numa_emulation(start_pfn, last_pfn, acpi, k8))
 		return;
 	nodes_clear(node_possible_map);
 	nodes_clear(node_online_map);
 #endif
 
 #ifdef CONFIG_ACPI_NUMA
-	if (!numa_off && !acpi_scan_nodes(start_pfn << PAGE_SHIFT,
-					  last_pfn << PAGE_SHIFT))
+	if (!numa_off && acpi && !acpi_scan_nodes(start_pfn << PAGE_SHIFT,
+						  last_pfn << PAGE_SHIFT))
 		return;
 	nodes_clear(node_possible_map);
 	nodes_clear(node_online_map);
 #endif
 
 #ifdef CONFIG_K8_NUMA
-	if (!numa_off && !k8_scan_nodes(start_pfn<<PAGE_SHIFT,
-					last_pfn<<PAGE_SHIFT))
+	if (!numa_off && k8 && !k8_scan_nodes())
 		return;
 	nodes_clear(node_possible_map);
 	nodes_clear(node_online_map);
@@ -601,6 +764,25 @@
 early_param("numa", numa_setup);
 
 #ifdef CONFIG_NUMA
+
+static __init int find_near_online_node(int node)
+{
+	int n, val;
+	int min_val = INT_MAX;
+	int best_node = -1;
+
+	for_each_online_node(n) {
+		val = node_distance(node, n);
+
+		if (val < min_val) {
+			min_val = val;
+			best_node = n;
+		}
+	}
+
+	return best_node;
+}
+
 /*
  * Setup early cpu_to_node.
  *
@@ -632,7 +814,7 @@
 		if (node == NUMA_NO_NODE)
 			continue;
 		if (!node_online(node))
-			continue;
+			node = find_near_online_node(node);
 		numa_set_node(cpu, node);
 	}
 }
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index dd38bfb..1d4eb93 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -279,6 +279,22 @@
 		   __pa((unsigned long)__end_rodata) >> PAGE_SHIFT))
 		pgprot_val(forbidden) |= _PAGE_RW;
 
+#if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA)
+	/*
+	 * Once the kernel maps the text as RO (kernel_set_to_readonly is set),
+	 * kernel text mappings for the large page aligned text, rodata sections
+	 * will be always read-only. For the kernel identity mappings covering
+	 * the holes caused by this alignment can be anything that user asks.
+	 *
+	 * This will preserve the large page mappings for kernel text/data
+	 * at no extra cost.
+	 */
+	if (kernel_set_to_readonly &&
+	    within(address, (unsigned long)_text,
+		   (unsigned long)__end_rodata_hpage_align))
+		pgprot_val(forbidden) |= _PAGE_RW;
+#endif
+
 	prot = __pgprot(pgprot_val(prot) & ~pgprot_val(forbidden));
 
 	return prot;
@@ -1069,12 +1085,18 @@
 
 int set_memory_x(unsigned long addr, int numpages)
 {
+	if (!(__supported_pte_mask & _PAGE_NX))
+		return 0;
+
 	return change_page_attr_clear(&addr, numpages, __pgprot(_PAGE_NX), 0);
 }
 EXPORT_SYMBOL(set_memory_x);
 
 int set_memory_nx(unsigned long addr, int numpages)
 {
+	if (!(__supported_pte_mask & _PAGE_NX))
+		return 0;
+
 	return change_page_attr_set(&addr, numpages, __pgprot(_PAGE_NX), 0);
 }
 EXPORT_SYMBOL(set_memory_nx);
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index e78cd0e..ae9648e 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -20,6 +20,7 @@
 #include <asm/cacheflush.h>
 #include <asm/processor.h>
 #include <asm/tlbflush.h>
+#include <asm/x86_init.h>
 #include <asm/pgtable.h>
 #include <asm/fcntl.h>
 #include <asm/e820.h>
@@ -355,9 +356,6 @@
  * - _PAGE_CACHE_UC_MINUS
  * - _PAGE_CACHE_UC
  *
- * req_type will have a special case value '-1', when requester want to inherit
- * the memory type from mtrr (if WB), existing PAT, defaulting to UC_MINUS.
- *
  * If new_type is NULL, function will return an error if it cannot reserve the
  * region with req_type. If new_type is non-NULL, function will return
  * available type in new_type in case of no error. In case of any error
@@ -377,9 +375,7 @@
 	if (!pat_enabled) {
 		/* This is identical to page table setting without PAT */
 		if (new_type) {
-			if (req_type == -1)
-				*new_type = _PAGE_CACHE_WB;
-			else if (req_type == _PAGE_CACHE_WC)
+			if (req_type == _PAGE_CACHE_WC)
 				*new_type = _PAGE_CACHE_UC_MINUS;
 			else
 				*new_type = req_type & _PAGE_CACHE_MASK;
@@ -388,7 +384,7 @@
 	}
 
 	/* Low ISA region is always mapped WB in page table. No need to track */
-	if (is_ISA_range(start, end - 1)) {
+	if (x86_platform.is_untracked_pat_range(start, end)) {
 		if (new_type)
 			*new_type = _PAGE_CACHE_WB;
 		return 0;
@@ -499,7 +495,7 @@
 		return 0;
 
 	/* Low ISA region is always mapped WB. No need to track */
-	if (is_ISA_range(start, end - 1))
+	if (x86_platform.is_untracked_pat_range(start, end))
 		return 0;
 
 	is_range_ram = pat_pagerange_is_ram(start, end);
@@ -582,7 +578,7 @@
 	int rettype = _PAGE_CACHE_WB;
 	struct memtype *entry;
 
-	if (is_ISA_range(paddr, paddr + PAGE_SIZE - 1))
+	if (x86_platform.is_untracked_pat_range(paddr, paddr + PAGE_SIZE))
 		return rettype;
 
 	if (pat_pagerange_is_ram(paddr, paddr + PAGE_SIZE)) {
@@ -708,9 +704,8 @@
 	if (!range_is_allowed(pfn, size))
 		return 0;
 
-	if (file->f_flags & O_SYNC) {
+	if (file->f_flags & O_DSYNC)
 		flags = _PAGE_CACHE_UC_MINUS;
-	}
 
 #ifdef CONFIG_X86_32
 	/*
@@ -1018,8 +1013,10 @@
 
 static int __init pat_memtype_list_init(void)
 {
-	debugfs_create_file("pat_memtype_list", S_IRUSR, arch_debugfs_dir,
-				NULL, &memtype_fops);
+	if (pat_enabled) {
+		debugfs_create_file("pat_memtype_list", S_IRUSR,
+				    arch_debugfs_dir, NULL, &memtype_fops);
+	}
 	return 0;
 }
 
diff --git a/arch/x86/mm/setup_nx.c b/arch/x86/mm/setup_nx.c
index 513d8ed..a3250aa 100644
--- a/arch/x86/mm/setup_nx.c
+++ b/arch/x86/mm/setup_nx.c
@@ -3,10 +3,8 @@
 #include <linux/init.h>
 
 #include <asm/pgtable.h>
+#include <asm/proto.h>
 
-int nx_enabled;
-
-#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
 static int disable_nx __cpuinitdata;
 
 /*
@@ -22,48 +20,41 @@
 	if (!str)
 		return -EINVAL;
 	if (!strncmp(str, "on", 2)) {
-		__supported_pte_mask |= _PAGE_NX;
 		disable_nx = 0;
 	} else if (!strncmp(str, "off", 3)) {
 		disable_nx = 1;
-		__supported_pte_mask &= ~_PAGE_NX;
 	}
+	x86_configure_nx();
 	return 0;
 }
 early_param("noexec", noexec_setup);
-#endif
 
-#ifdef CONFIG_X86_PAE
-void __init set_nx(void)
+void __cpuinit x86_configure_nx(void)
 {
-	unsigned int v[4], l, h;
-
-	if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
-		cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
-
-		if ((v[3] & (1 << 20)) && !disable_nx) {
-			rdmsr(MSR_EFER, l, h);
-			l |= EFER_NX;
-			wrmsr(MSR_EFER, l, h);
-			nx_enabled = 1;
-			__supported_pte_mask |= _PAGE_NX;
-		}
-	}
-}
-#else
-void set_nx(void)
-{
-}
-#endif
-
-#ifdef CONFIG_X86_64
-void __cpuinit check_efer(void)
-{
-	unsigned long efer;
-
-	rdmsrl(MSR_EFER, efer);
-	if (!(efer & EFER_NX) || disable_nx)
+	if (cpu_has_nx && !disable_nx)
+		__supported_pte_mask |= _PAGE_NX;
+	else
 		__supported_pte_mask &= ~_PAGE_NX;
 }
-#endif
 
+void __init x86_report_nx(void)
+{
+	if (!cpu_has_nx) {
+		printk(KERN_NOTICE "Notice: NX (Execute Disable) protection "
+		       "missing in CPU or disabled in BIOS!\n");
+	} else {
+#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
+		if (disable_nx) {
+			printk(KERN_INFO "NX (Execute Disable) protection: "
+			       "disabled by kernel command line option\n");
+		} else {
+			printk(KERN_INFO "NX (Execute Disable) protection: "
+			       "active\n");
+		}
+#else
+		/* 32bit non-PAE kernel, NX cannot be used */
+		printk(KERN_NOTICE "Notice: NX (Execute Disable) protection "
+		       "cannot be enabled: non-PAE kernel!\n");
+#endif
+	}
+}
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c
index 9d7ce96..d890754 100644
--- a/arch/x86/mm/srat_64.c
+++ b/arch/x86/mm/srat_64.c
@@ -290,8 +290,6 @@
 
 	printk(KERN_INFO "SRAT: Node %u PXM %u %lx-%lx\n", node, pxm,
 	       start, end);
-	e820_register_active_regions(node, start >> PAGE_SHIFT,
-				     end >> PAGE_SHIFT);
 
 	if (ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) {
 		update_nodes_add(node, start, end);
@@ -338,6 +336,19 @@
 
 void __init acpi_numa_arch_fixup(void) {}
 
+int __init acpi_get_nodes(struct bootnode *physnodes)
+{
+	int i;
+	int ret = 0;
+
+	for_each_node_mask(i, nodes_parsed) {
+		physnodes[ret].start = nodes[i].start;
+		physnodes[ret].end = nodes[i].end;
+		ret++;
+	}
+	return ret;
+}
+
 /* Use the information discovered above to actually set up the nodes. */
 int __init acpi_scan_nodes(unsigned long start, unsigned long end)
 {
@@ -350,11 +361,6 @@
 	for (i = 0; i < MAX_NUMNODES; i++)
 		cutoff_node(i, start, end);
 
-	if (!nodes_cover_memory(nodes)) {
-		bad_srat();
-		return -1;
-	}
-
 	memnode_shift = compute_hash_shift(node_memblk_range, num_node_memblks,
 					   memblk_nodeid);
 	if (memnode_shift < 0) {
@@ -364,6 +370,14 @@
 		return -1;
 	}
 
+	for_each_node_mask(i, nodes_parsed)
+		e820_register_active_regions(i, nodes[i].start >> PAGE_SHIFT,
+						nodes[i].end >> PAGE_SHIFT);
+	if (!nodes_cover_memory(nodes)) {
+		bad_srat();
+		return -1;
+	}
+
 	/* Account for nodes with cpus and no memory */
 	nodes_or(node_possible_map, nodes_parsed, cpu_nodes_parsed);
 
@@ -454,7 +468,6 @@
 	for (i = 0; i < num_nodes; i++)
 		if (fake_nodes[i].start != fake_nodes[i].end)
 			node_set(i, nodes_parsed);
-	WARN_ON(!nodes_cover_memory(fake_nodes));
 }
 
 static int null_slit_node_compare(int a, int b)
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 36fe08e..65b58e4 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -8,6 +8,7 @@
 
 #include <asm/tlbflush.h>
 #include <asm/mmu_context.h>
+#include <asm/cache.h>
 #include <asm/apic.h>
 #include <asm/uv/uv.h>
 
@@ -43,7 +44,7 @@
 		spinlock_t tlbstate_lock;
 		DECLARE_BITMAP(flush_cpumask, NR_CPUS);
 	};
-	char pad[CONFIG_X86_INTERNODE_CACHE_BYTES];
+	char pad[INTERNODE_CACHE_BYTES];
 } ____cacheline_internodealigned_in_smp;
 
 /* State is put into the per CPU data section, but padded
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
index d49202e..564b008 100644
--- a/arch/x86/pci/Makefile
+++ b/arch/x86/pci/Makefile
@@ -15,3 +15,8 @@
 
 obj-y				+= common.o early.o
 obj-y				+= amd_bus.o
+obj-$(CONFIG_X86_64)		+= bus_numa.o intel_bus.o
+
+ifeq ($(CONFIG_PCI_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 1014eb4..959e548 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -7,6 +7,7 @@
 #include <asm/pci_x86.h>
 
 struct pci_root_info {
+	struct acpi_device *bridge;
 	char *name;
 	unsigned int res_num;
 	struct resource *res;
@@ -58,6 +59,30 @@
 	return false;
 }
 
+static void
+align_resource(struct acpi_device *bridge, struct resource *res)
+{
+	int align = (res->flags & IORESOURCE_MEM) ? 16 : 4;
+
+	/*
+	 * Host bridge windows are not BARs, but the decoders on the PCI side
+	 * that claim this address space have starting alignment and length
+	 * constraints, so fix any obvious BIOS goofs.
+	 */
+	if (!IS_ALIGNED(res->start, align)) {
+		dev_printk(KERN_DEBUG, &bridge->dev,
+			   "host bridge window %pR invalid; "
+			   "aligning start to %d-byte boundary\n", res, align);
+		res->start &= ~(align - 1);
+	}
+	if (!IS_ALIGNED(res->end + 1, align)) {
+		dev_printk(KERN_DEBUG, &bridge->dev,
+			   "host bridge window %pR invalid; "
+			   "aligning end to %d-byte boundary\n", res, align);
+		res->end = ALIGN(res->end, align) - 1;
+	}
+}
+
 static acpi_status
 setup_resource(struct acpi_resource *acpi_res, void *data)
 {
@@ -91,11 +116,12 @@
 	start = addr.minimum + addr.translation_offset;
 	end = start + addr.address_length - 1;
 	if (info->res_num >= max_root_bus_resources) {
-		printk(KERN_WARNING "PCI: Failed to allocate 0x%lx-0x%lx "
-			"from %s for %s due to _CRS returning more than "
-			"%d resource descriptors\n", (unsigned long) start,
-			(unsigned long) end, root->name, info->name,
-			max_root_bus_resources);
+		if (pci_probe & PCI_USE__CRS)
+			printk(KERN_WARNING "PCI: Failed to allocate "
+			       "0x%lx-0x%lx from %s for %s due to _CRS "
+			       "returning more than %d resource descriptors\n",
+			       (unsigned long) start, (unsigned long) end,
+			       root->name, info->name, max_root_bus_resources);
 		return AE_OK;
 	}
 
@@ -105,14 +131,28 @@
 	res->start = start;
 	res->end = end;
 	res->child = NULL;
+	align_resource(info->bridge, res);
+
+	if (!(pci_probe & PCI_USE__CRS)) {
+		dev_printk(KERN_DEBUG, &info->bridge->dev,
+			   "host bridge window %pR (ignored)\n", res);
+		return AE_OK;
+	}
 
 	if (insert_resource(root, res)) {
-		printk(KERN_ERR "PCI: Failed to allocate 0x%lx-0x%lx "
-			"from %s for %s\n", (unsigned long) res->start,
-			(unsigned long) res->end, root->name, info->name);
+		dev_err(&info->bridge->dev,
+			"can't allocate host bridge window %pR\n", res);
 	} else {
 		info->bus->resource[info->res_num] = res;
 		info->res_num++;
+		if (addr.translation_offset)
+			dev_info(&info->bridge->dev, "host bridge window %pR "
+				 "(PCI address [%#llx-%#llx])\n",
+				 res, res->start - addr.translation_offset,
+				 res->end - addr.translation_offset);
+		else
+			dev_info(&info->bridge->dev,
+				 "host bridge window %pR\n", res);
 	}
 	return AE_OK;
 }
@@ -124,6 +164,12 @@
 	struct pci_root_info info;
 	size_t size;
 
+	if (!(pci_probe & PCI_USE__CRS))
+		dev_info(&device->dev,
+			 "ignoring host bridge windows from ACPI; "
+			 "boot with \"pci=use_crs\" to use them\n");
+
+	info.bridge = device;
 	info.bus = bus;
 	info.res_num = 0;
 	acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource,
@@ -163,8 +209,9 @@
 #endif
 
 	if (domain && !pci_domains_supported) {
-		printk(KERN_WARNING "PCI: Multiple domains not supported "
-		       "(dom %d, bus %d)\n", domain, busnum);
+		printk(KERN_WARNING "pci_bus %04x:%02x: "
+		       "ignored (multiple domains not supported)\n",
+		       domain, busnum);
 		return NULL;
 	}
 
@@ -188,7 +235,8 @@
 	 */
 	sd = kzalloc(sizeof(*sd), GFP_KERNEL);
 	if (!sd) {
-		printk(KERN_ERR "PCI: OOM, not probing PCI bus %02x\n", busnum);
+		printk(KERN_WARNING "pci_bus %04x:%02x: "
+		       "ignored (out of memory)\n", domain, busnum);
 		return NULL;
 	}
 
@@ -209,9 +257,7 @@
 	} else {
 		bus = pci_create_bus(NULL, busnum, &pci_root_ops, sd);
 		if (bus) {
-			if (pci_probe & PCI_USE__CRS)
-				get_current_resources(device, busnum, domain,
-							bus);
+			get_current_resources(device, busnum, domain, bus);
 			bus->subordinate = pci_scan_child_bus(bus);
 		}
 	}
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c
index 572ee97..95ecbd4 100644
--- a/arch/x86/pci/amd_bus.c
+++ b/arch/x86/pci/amd_bus.c
@@ -6,10 +6,10 @@
 
 #ifdef CONFIG_X86_64
 #include <asm/pci-direct.h>
-#include <asm/mpspec.h>
-#include <linux/cpumask.h>
 #endif
 
+#include "bus_numa.h"
+
 /*
  * This discovers the pcibus <-> node mapping on AMD K8.
  * also get peer root bus resource for io,mmio
@@ -17,67 +17,6 @@
 
 #ifdef CONFIG_X86_64
 
-/*
- * sub bus (transparent) will use entres from 3 to store extra from root,
- * so need to make sure have enought slot there, increase PCI_BUS_NUM_RESOURCES?
- */
-#define RES_NUM 16
-struct pci_root_info {
-	char name[12];
-	unsigned int res_num;
-	struct resource res[RES_NUM];
-	int bus_min;
-	int bus_max;
-	int node;
-	int link;
-};
-
-/* 4 at this time, it may become to 32 */
-#define PCI_ROOT_NR 4
-static int pci_root_num;
-static struct pci_root_info pci_root_info[PCI_ROOT_NR];
-
-void x86_pci_root_bus_res_quirks(struct pci_bus *b)
-{
-	int i;
-	int j;
-	struct pci_root_info *info;
-
-	/* don't go for it if _CRS is used already */
-	if (b->resource[0] != &ioport_resource ||
-	    b->resource[1] != &iomem_resource)
-		return;
-
-	/* if only one root bus, don't need to anything */
-	if (pci_root_num < 2)
-		return;
-
-	for (i = 0; i < pci_root_num; i++) {
-		if (pci_root_info[i].bus_min == b->number)
-			break;
-	}
-
-	if (i == pci_root_num)
-		return;
-
-	printk(KERN_DEBUG "PCI: peer root bus %02x res updated from pci conf\n",
-			b->number);
-
-	info = &pci_root_info[i];
-	for (j = 0; j < info->res_num; j++) {
-		struct resource *res;
-		struct resource *root;
-
-		res = &info->res[j];
-		b->resource[j] = res;
-		if (res->flags & IORESOURCE_IO)
-			root = &ioport_resource;
-		else
-			root = &iomem_resource;
-		insert_resource(root, res);
-	}
-}
-
 #define RANGE_NUM 16
 
 struct res_range {
@@ -130,52 +69,6 @@
 	}
 }
 
-static void __init update_res(struct pci_root_info *info, size_t start,
-			      size_t end, unsigned long flags, int merge)
-{
-	int i;
-	struct resource *res;
-
-	if (!merge)
-		goto addit;
-
-	/* try to merge it with old one */
-	for (i = 0; i < info->res_num; i++) {
-		size_t final_start, final_end;
-		size_t common_start, common_end;
-
-		res = &info->res[i];
-		if (res->flags != flags)
-			continue;
-
-		common_start = max((size_t)res->start, start);
-		common_end = min((size_t)res->end, end);
-		if (common_start > common_end + 1)
-			continue;
-
-		final_start = min((size_t)res->start, start);
-		final_end = max((size_t)res->end, end);
-
-		res->start = final_start;
-		res->end = final_end;
-		return;
-	}
-
-addit:
-
-	/* need to add that */
-	if (info->res_num >= RES_NUM)
-		return;
-
-	res = &info->res[info->res_num];
-	res->name = info->name;
-	res->flags = flags;
-	res->start = start;
-	res->end = end;
-	res->child = NULL;
-	info->res_num++;
-}
-
 struct pci_hostbridge_probe {
 	u32 bus;
 	u32 slot;
@@ -230,7 +123,6 @@
 	int j;
 	unsigned bus;
 	unsigned slot;
-	int found;
 	int node;
 	int link;
 	int def_node;
@@ -247,7 +139,7 @@
 	if (!early_pci_allowed())
 		return -1;
 
-	found = 0;
+	found_all_numa_early = 0;
 	for (i = 0; i < ARRAY_SIZE(pci_probes); i++) {
 		u32 id;
 		u16 device;
@@ -261,12 +153,12 @@
 		device = (id>>16) & 0xffff;
 		if (pci_probes[i].vendor == vendor &&
 		    pci_probes[i].device == device) {
-			found = 1;
+			found_all_numa_early = 1;
 			break;
 		}
 	}
 
-	if (!found)
+	if (!found_all_numa_early)
 		return 0;
 
 	pci_root_num = 0;
@@ -488,7 +380,7 @@
 		info = &pci_root_info[i];
 		res_num = info->res_num;
 		busnum = info->bus_min;
-		printk(KERN_DEBUG "bus: [%02x,%02x] on node %x link %x\n",
+		printk(KERN_DEBUG "bus: [%02x, %02x] on node %x link %x\n",
 		       info->bus_min, info->bus_max, info->node, info->link);
 		for (j = 0; j < res_num; j++) {
 			res = &info->res[j];
diff --git a/arch/x86/pci/bus_numa.c b/arch/x86/pci/bus_numa.c
new file mode 100644
index 0000000..145df00
--- /dev/null
+++ b/arch/x86/pci/bus_numa.c
@@ -0,0 +1,101 @@
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include "bus_numa.h"
+
+int pci_root_num;
+struct pci_root_info pci_root_info[PCI_ROOT_NR];
+int found_all_numa_early;
+
+void x86_pci_root_bus_res_quirks(struct pci_bus *b)
+{
+	int i;
+	int j;
+	struct pci_root_info *info;
+
+	/* don't go for it if _CRS is used already */
+	if (b->resource[0] != &ioport_resource ||
+	    b->resource[1] != &iomem_resource)
+		return;
+
+	if (!pci_root_num)
+		return;
+
+	/* for amd, if only one root bus, don't need to do anything */
+	if (pci_root_num < 2 && found_all_numa_early)
+		return;
+
+	for (i = 0; i < pci_root_num; i++) {
+		if (pci_root_info[i].bus_min == b->number)
+			break;
+	}
+
+	if (i == pci_root_num)
+		return;
+
+	printk(KERN_DEBUG "PCI: peer root bus %02x res updated from pci conf\n",
+			b->number);
+
+	info = &pci_root_info[i];
+	for (j = 0; j < info->res_num; j++) {
+		struct resource *res;
+		struct resource *root;
+
+		res = &info->res[j];
+		b->resource[j] = res;
+		if (res->flags & IORESOURCE_IO)
+			root = &ioport_resource;
+		else
+			root = &iomem_resource;
+		insert_resource(root, res);
+	}
+}
+
+void __init update_res(struct pci_root_info *info, size_t start,
+			      size_t end, unsigned long flags, int merge)
+{
+	int i;
+	struct resource *res;
+
+	if (start > end)
+		return;
+
+	if (!merge)
+		goto addit;
+
+	/* try to merge it with old one */
+	for (i = 0; i < info->res_num; i++) {
+		size_t final_start, final_end;
+		size_t common_start, common_end;
+
+		res = &info->res[i];
+		if (res->flags != flags)
+			continue;
+
+		common_start = max((size_t)res->start, start);
+		common_end = min((size_t)res->end, end);
+		if (common_start > common_end + 1)
+			continue;
+
+		final_start = min((size_t)res->start, start);
+		final_end = max((size_t)res->end, end);
+
+		res->start = final_start;
+		res->end = final_end;
+		return;
+	}
+
+addit:
+
+	/* need to add that */
+	if (info->res_num >= RES_NUM)
+		return;
+
+	res = &info->res[info->res_num];
+	res->name = info->name;
+	res->flags = flags;
+	res->start = start;
+	res->end = end;
+	res->child = NULL;
+	info->res_num++;
+}
diff --git a/arch/x86/pci/bus_numa.h b/arch/x86/pci/bus_numa.h
new file mode 100644
index 0000000..adbc23f
--- /dev/null
+++ b/arch/x86/pci/bus_numa.h
@@ -0,0 +1,27 @@
+#ifdef CONFIG_X86_64
+
+/*
+ * sub bus (transparent) will use entres from 3 to store extra from
+ * root, so need to make sure we have enough slot there, Should we
+ * increase PCI_BUS_NUM_RESOURCES?
+ */
+#define RES_NUM 16
+struct pci_root_info {
+	char name[12];
+	unsigned int res_num;
+	struct resource res[RES_NUM];
+	int bus_min;
+	int bus_max;
+	int node;
+	int link;
+};
+
+/* 4 at this time, it may become to 32 */
+#define PCI_ROOT_NR 4
+extern int pci_root_num;
+extern struct pci_root_info pci_root_info[PCI_ROOT_NR];
+extern int found_all_numa_early;
+
+extern void update_res(struct pci_root_info *info, size_t start,
+			      size_t end, unsigned long flags, int merge);
+#endif
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 1331fcf..d2552c6 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -410,8 +410,6 @@
 	return bus;
 }
 
-extern u8 pci_cache_line_size;
-
 int __init pcibios_init(void)
 {
 	struct cpuinfo_x86 *c = &boot_cpu_data;
@@ -422,15 +420,19 @@
 	}
 
 	/*
-	 * Assume PCI cacheline size of 32 bytes for all x86s except K7/K8
-	 * and P4. It's also good for 386/486s (which actually have 16)
+	 * Set PCI cacheline size to that of the CPU if the CPU has reported it.
+	 * (For older CPUs that don't support cpuid, we se it to 32 bytes
+	 * It's also good for 386/486s (which actually have 16)
 	 * as quite a few PCI devices do not support smaller values.
 	 */
-	pci_cache_line_size = 32 >> 2;
-	if (c->x86 >= 6 && c->x86_vendor == X86_VENDOR_AMD)
-		pci_cache_line_size = 64 >> 2;	/* K7 & K8 */
-	else if (c->x86 > 6 && c->x86_vendor == X86_VENDOR_INTEL)
-		pci_cache_line_size = 128 >> 2;	/* P4 */
+	if (c->x86_clflush_size > 0) {
+		pci_dfl_cache_line_size = c->x86_clflush_size >> 2;
+		printk(KERN_DEBUG "PCI: pci_cache_line_size set to %d bytes\n",
+			pci_dfl_cache_line_size << 2);
+	} else {
+ 		pci_dfl_cache_line_size = 32 >> 2;
+		printk(KERN_DEBUG "PCI: Unknown cacheline size. Setting to 32 bytes\n");
+	}
 
 	pcibios_resource_survey();
 
diff --git a/arch/x86/pci/early.c b/arch/x86/pci/early.c
index aaf26ae..d1067d5 100644
--- a/arch/x86/pci/early.c
+++ b/arch/x86/pci/early.c
@@ -12,8 +12,6 @@
 	u32 v;
 	outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
 	v = inl(0xcfc);
-	if (v != 0xffffffff)
-		pr_debug("%x reading 4 from %x: %x\n", slot, offset, v);
 	return v;
 }
 
@@ -22,7 +20,6 @@
 	u8 v;
 	outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
 	v = inb(0xcfc + (offset&3));
-	pr_debug("%x reading 1 from %x: %x\n", slot, offset, v);
 	return v;
 }
 
@@ -31,28 +28,24 @@
 	u16 v;
 	outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
 	v = inw(0xcfc + (offset&2));
-	pr_debug("%x reading 2 from %x: %x\n", slot, offset, v);
 	return v;
 }
 
 void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset,
 				    u32 val)
 {
-	pr_debug("%x writing to %x: %x\n", slot, offset, val);
 	outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
 	outl(val, 0xcfc);
 }
 
 void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val)
 {
-	pr_debug("%x writing to %x: %x\n", slot, offset, val);
 	outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
 	outb(val, 0xcfc + (offset&3));
 }
 
 void write_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset, u16 val)
 {
-	pr_debug("%x writing to %x: %x\n", slot, offset, val);
 	outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
 	outw(val, 0xcfc + (offset&2));
 }
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index b22d13b..5dc9e8c 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -129,7 +129,9 @@
 					continue;
 				if (!r->start ||
 				    pci_claim_resource(dev, idx) < 0) {
-					dev_info(&dev->dev, "BAR %d: can't allocate resource\n", idx);
+					dev_info(&dev->dev,
+						 "can't reserve window %pR\n",
+						 r);
 					/*
 					 * Something is wrong with the region.
 					 * Invalidate the resource to prevent
@@ -144,16 +146,29 @@
 	}
 }
 
+struct pci_check_idx_range {
+	int start;
+	int end;
+};
+
 static void __init pcibios_allocate_resources(int pass)
 {
 	struct pci_dev *dev = NULL;
-	int idx, disabled;
+	int idx, disabled, i;
 	u16 command;
 	struct resource *r;
 
+	struct pci_check_idx_range idx_range[] = {
+		{ PCI_STD_RESOURCES, PCI_STD_RESOURCE_END },
+#ifdef CONFIG_PCI_IOV
+		{ PCI_IOV_RESOURCES, PCI_IOV_RESOURCE_END },
+#endif
+	};
+
 	for_each_pci_dev(dev) {
 		pci_read_config_word(dev, PCI_COMMAND, &command);
-		for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) {
+		for (i = 0; i < ARRAY_SIZE(idx_range); i++)
+		for (idx = idx_range[i].start; idx <= idx_range[i].end; idx++) {
 			r = &dev->resource[idx];
 			if (r->parent)		/* Already allocated */
 				continue;
@@ -164,12 +179,12 @@
 			else
 				disabled = !(command & PCI_COMMAND_MEMORY);
 			if (pass == disabled) {
-				dev_dbg(&dev->dev, "resource %#08llx-%#08llx (f=%lx, d=%d, p=%d)\n",
-					(unsigned long long) r->start,
-					(unsigned long long) r->end,
-					r->flags, disabled, pass);
+				dev_dbg(&dev->dev,
+					"BAR %d: reserving %pr (d=%d, p=%d)\n",
+					idx, r, disabled, pass);
 				if (pci_claim_resource(dev, idx) < 0) {
-					dev_info(&dev->dev, "BAR %d: can't allocate resource\n", idx);
+					dev_info(&dev->dev,
+						 "can't reserve %pR\n", r);
 					/* We'll assign a new address later */
 					r->end -= r->start;
 					r->start = 0;
@@ -182,7 +197,7 @@
 				/* Turn the ROM off, leave the resource region,
 				 * but keep it unregistered. */
 				u32 reg;
-				dev_dbg(&dev->dev, "disabling ROM\n");
+				dev_dbg(&dev->dev, "disabling ROM %pR\n", r);
 				r->flags &= ~IORESOURCE_ROM_ENABLE;
 				pci_read_config_dword(dev,
 						dev->rom_base_reg, &reg);
@@ -282,6 +297,15 @@
 		return -EINVAL;
 
 	prot = pgprot_val(vma->vm_page_prot);
+
+	/*
+ 	 * Return error if pat is not enabled and write_combine is requested.
+ 	 * Caller can followup with UC MINUS request and add a WC mtrr if there
+ 	 * is a free mtrr slot.
+ 	 */
+	if (!pat_enabled && write_combine)
+		return -EINVAL;
+
 	if (pat_enabled && write_combine)
 		prot |= _PAGE_CACHE_WC;
 	else if (pat_enabled || boot_cpu_data.x86 > 3)
diff --git a/arch/x86/pci/intel_bus.c b/arch/x86/pci/intel_bus.c
new file mode 100644
index 0000000..b7a55dc
--- /dev/null
+++ b/arch/x86/pci/intel_bus.c
@@ -0,0 +1,90 @@
+/*
+ * to read io range from IOH pci conf, need to do it after mmconfig is there
+ */
+
+#include <linux/delay.h>
+#include <linux/dmi.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <asm/pci_x86.h>
+
+#include "bus_numa.h"
+
+static inline void print_ioh_resources(struct pci_root_info *info)
+{
+	int res_num;
+	int busnum;
+	int i;
+
+	printk(KERN_DEBUG "IOH bus: [%02x, %02x]\n",
+			info->bus_min, info->bus_max);
+	res_num = info->res_num;
+	busnum = info->bus_min;
+	for (i = 0; i < res_num; i++) {
+		struct resource *res;
+
+		res = &info->res[i];
+		printk(KERN_DEBUG "IOH bus: %02x index %x %s: [%llx, %llx]\n",
+			busnum, i,
+			(res->flags & IORESOURCE_IO) ? "io port" :
+							"mmio",
+			res->start, res->end);
+	}
+}
+
+#define IOH_LIO			0x108
+#define IOH_LMMIOL		0x10c
+#define IOH_LMMIOH		0x110
+#define IOH_LMMIOH_BASEU	0x114
+#define IOH_LMMIOH_LIMITU	0x118
+#define IOH_LCFGBUS		0x11c
+
+static void __devinit pci_root_bus_res(struct pci_dev *dev)
+{
+	u16 word;
+	u32 dword;
+	struct pci_root_info *info;
+	u16 io_base, io_end;
+	u32 mmiol_base, mmiol_end;
+	u64 mmioh_base, mmioh_end;
+	int bus_base, bus_end;
+
+	if (pci_root_num >= PCI_ROOT_NR) {
+		printk(KERN_DEBUG "intel_bus.c: PCI_ROOT_NR is too small\n");
+		return;
+	}
+
+	info = &pci_root_info[pci_root_num];
+	pci_root_num++;
+
+	pci_read_config_word(dev, IOH_LCFGBUS, &word);
+	bus_base = (word & 0xff);
+	bus_end = (word & 0xff00) >> 8;
+	sprintf(info->name, "PCI Bus #%02x", bus_base);
+	info->bus_min = bus_base;
+	info->bus_max = bus_end;
+
+	pci_read_config_word(dev, IOH_LIO, &word);
+	io_base = (word & 0xf0) << (12 - 4);
+	io_end = (word & 0xf000) | 0xfff;
+	update_res(info, io_base, io_end, IORESOURCE_IO, 0);
+
+	pci_read_config_dword(dev, IOH_LMMIOL, &dword);
+	mmiol_base = (dword & 0xff00) << (24 - 8);
+	mmiol_end = (dword & 0xff000000) | 0xffffff;
+	update_res(info, mmiol_base, mmiol_end, IORESOURCE_MEM, 0);
+
+	pci_read_config_dword(dev, IOH_LMMIOH, &dword);
+	mmioh_base = ((u64)(dword & 0xfc00)) << (26 - 10);
+	mmioh_end = ((u64)(dword & 0xfc000000) | 0x3ffffff);
+	pci_read_config_dword(dev, IOH_LMMIOH_BASEU, &dword);
+	mmioh_base |= ((u64)(dword & 0x7ffff)) << 32;
+	pci_read_config_dword(dev, IOH_LMMIOH_LIMITU, &dword);
+	mmioh_end |= ((u64)(dword & 0x7ffff)) << 32;
+	update_res(info, mmioh_base, mmioh_end, IORESOURCE_MEM, 0);
+
+	print_ioh_resources(info);
+}
+
+/* intel IOH */
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x342e, pci_root_bus_res);
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 602c172d..b19d1e5 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -15,48 +15,98 @@
 #include <linux/acpi.h>
 #include <linux/sfi_acpi.h>
 #include <linux/bitmap.h>
-#include <linux/sort.h>
+#include <linux/dmi.h>
 #include <asm/e820.h>
 #include <asm/pci_x86.h>
 #include <asm/acpi.h>
 
 #define PREFIX "PCI: "
 
-/* aperture is up to 256MB but BIOS may reserve less */
-#define MMCONFIG_APER_MIN	(2 * 1024*1024)
-#define MMCONFIG_APER_MAX	(256 * 1024*1024)
-
 /* Indicate if the mmcfg resources have been placed into the resource table. */
 static int __initdata pci_mmcfg_resources_inserted;
 
-static __init int extend_mmcfg(int num)
+LIST_HEAD(pci_mmcfg_list);
+
+static __init void pci_mmconfig_remove(struct pci_mmcfg_region *cfg)
 {
-	struct acpi_mcfg_allocation *new;
-	int new_num = pci_mmcfg_config_num + num;
-
-	new = kzalloc(sizeof(pci_mmcfg_config[0]) * new_num, GFP_KERNEL);
-	if (!new)
-		return -1;
-
-	if (pci_mmcfg_config) {
-		memcpy(new, pci_mmcfg_config,
-			 sizeof(pci_mmcfg_config[0]) * new_num);
-		kfree(pci_mmcfg_config);
-	}
-	pci_mmcfg_config = new;
-
-	return 0;
+	if (cfg->res.parent)
+		release_resource(&cfg->res);
+	list_del(&cfg->list);
+	kfree(cfg);
 }
 
-static __init void fill_one_mmcfg(u64 addr, int segment, int start, int end)
+static __init void free_all_mmcfg(void)
 {
-	int i = pci_mmcfg_config_num;
+	struct pci_mmcfg_region *cfg, *tmp;
 
-	pci_mmcfg_config_num++;
-	pci_mmcfg_config[i].address = addr;
-	pci_mmcfg_config[i].pci_segment = segment;
-	pci_mmcfg_config[i].start_bus_number = start;
-	pci_mmcfg_config[i].end_bus_number = end;
+	pci_mmcfg_arch_free();
+	list_for_each_entry_safe(cfg, tmp, &pci_mmcfg_list, list)
+		pci_mmconfig_remove(cfg);
+}
+
+static __init void list_add_sorted(struct pci_mmcfg_region *new)
+{
+	struct pci_mmcfg_region *cfg;
+
+	/* keep list sorted by segment and starting bus number */
+	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
+		if (cfg->segment > new->segment ||
+		    (cfg->segment == new->segment &&
+		     cfg->start_bus >= new->start_bus)) {
+			list_add_tail(&new->list, &cfg->list);
+			return;
+		}
+	}
+	list_add_tail(&new->list, &pci_mmcfg_list);
+}
+
+static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
+							int end, u64 addr)
+{
+	struct pci_mmcfg_region *new;
+	int num_buses;
+	struct resource *res;
+
+	if (addr == 0)
+		return NULL;
+
+	new = kzalloc(sizeof(*new), GFP_KERNEL);
+	if (!new)
+		return NULL;
+
+	new->address = addr;
+	new->segment = segment;
+	new->start_bus = start;
+	new->end_bus = end;
+
+	list_add_sorted(new);
+
+	num_buses = end - start + 1;
+	res = &new->res;
+	res->start = addr + PCI_MMCFG_BUS_OFFSET(start);
+	res->end = addr + PCI_MMCFG_BUS_OFFSET(num_buses) - 1;
+	res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+	snprintf(new->name, PCI_MMCFG_RESOURCE_NAME_LEN,
+		 "PCI MMCONFIG %04x [bus %02x-%02x]", segment, start, end);
+	res->name = new->name;
+
+	printk(KERN_INFO PREFIX "MMCONFIG for domain %04x [bus %02x-%02x] at "
+	       "%pR (base %#lx)\n", segment, start, end, &new->res,
+	       (unsigned long) addr);
+
+	return new;
+}
+
+struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus)
+{
+	struct pci_mmcfg_region *cfg;
+
+	list_for_each_entry(cfg, &pci_mmcfg_list, list)
+		if (cfg->segment == segment &&
+		    cfg->start_bus <= bus && bus <= cfg->end_bus)
+			return cfg;
+
+	return NULL;
 }
 
 static const char __init *pci_mmcfg_e7520(void)
@@ -68,11 +118,9 @@
 	if (win == 0x0000 || win == 0xf000)
 		return NULL;
 
-	if (extend_mmcfg(1) == -1)
+	if (pci_mmconfig_add(0, 0, 255, win << 16) == NULL)
 		return NULL;
 
-	fill_one_mmcfg(win << 16, 0, 0, 255);
-
 	return "Intel Corporation E7520 Memory Controller Hub";
 }
 
@@ -114,11 +162,9 @@
 	if ((pciexbar & mask) >= 0xf0000000U)
 		return NULL;
 
-	if (extend_mmcfg(1) == -1)
+	if (pci_mmconfig_add(0, 0, (len >> 20) - 1, pciexbar & mask) == NULL)
 		return NULL;
 
-	fill_one_mmcfg(pciexbar & mask, 0, 0, (len >> 20) - 1);
-
 	return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub";
 }
 
@@ -127,7 +173,7 @@
 	u32 low, high, address;
 	u64 base, msr;
 	int i;
-	unsigned segnbits = 0, busnbits;
+	unsigned segnbits = 0, busnbits, end_bus;
 
 	if (!(pci_probe & PCI_CHECK_ENABLE_AMD_MMCONF))
 		return NULL;
@@ -161,11 +207,13 @@
 		busnbits = 8;
 	}
 
-	if (extend_mmcfg(1 << segnbits) == -1)
-		return NULL;
-
+	end_bus = (1 << busnbits) - 1;
 	for (i = 0; i < (1 << segnbits); i++)
-		fill_one_mmcfg(base + (1<<28) * i, i, 0, (1 << busnbits) - 1);
+		if (pci_mmconfig_add(i, 0, end_bus,
+				     base + (1<<28) * i) == NULL) {
+			free_all_mmcfg();
+			return NULL;
+		}
 
 	return "AMD Family 10h NB";
 }
@@ -190,7 +238,7 @@
 	/*
 	 * do check if amd fam10h already took over
 	 */
-	if (!acpi_disabled || pci_mmcfg_config_num || mcp55_checked)
+	if (!acpi_disabled || !list_empty(&pci_mmcfg_list) || mcp55_checked)
 		return NULL;
 
 	mcp55_checked = true;
@@ -213,16 +261,14 @@
 		if (!(extcfg & extcfg_enable_mask))
 			continue;
 
-		if (extend_mmcfg(1) == -1)
-			continue;
-
 		size_index = (extcfg & extcfg_size_mask) >> extcfg_size_shift;
 		base = extcfg & extcfg_base_mask[size_index];
 		/* base could > 4G */
 		base <<= extcfg_base_lshift;
 		start = (extcfg & extcfg_start_mask) >> extcfg_start_shift;
 		end = start + extcfg_sizebus[size_index] - 1;
-		fill_one_mmcfg(base, 0, start, end);
+		if (pci_mmconfig_add(0, start, end, base) == NULL)
+			continue;
 		mcp55_mmconf_found++;
 	}
 
@@ -253,45 +299,27 @@
 	  0x0369, pci_mmcfg_nvidia_mcp55 },
 };
 
-static int __init cmp_mmcfg(const void *x1, const void *x2)
-{
-	const typeof(pci_mmcfg_config[0]) *m1 = x1;
-	const typeof(pci_mmcfg_config[0]) *m2 = x2;
-	int start1, start2;
-
-	start1 = m1->start_bus_number;
-	start2 = m2->start_bus_number;
-
-	return start1 - start2;
-}
-
 static void __init pci_mmcfg_check_end_bus_number(void)
 {
-	int i;
-	typeof(pci_mmcfg_config[0]) *cfg, *cfgx;
-
-	/* sort them at first */
-	sort(pci_mmcfg_config, pci_mmcfg_config_num,
-		 sizeof(pci_mmcfg_config[0]), cmp_mmcfg, NULL);
+	struct pci_mmcfg_region *cfg, *cfgx;
 
 	/* last one*/
-	if (pci_mmcfg_config_num > 0) {
-		i = pci_mmcfg_config_num - 1;
-		cfg = &pci_mmcfg_config[i];
-		if (cfg->end_bus_number < cfg->start_bus_number)
-			cfg->end_bus_number = 255;
-	}
+	cfg = list_entry(pci_mmcfg_list.prev, typeof(*cfg), list);
+	if (cfg)
+		if (cfg->end_bus < cfg->start_bus)
+			cfg->end_bus = 255;
+
+	if (list_is_singular(&pci_mmcfg_list))
+		return;
 
 	/* don't overlap please */
-	for (i = 0; i < pci_mmcfg_config_num - 1; i++) {
-		cfg = &pci_mmcfg_config[i];
-		cfgx = &pci_mmcfg_config[i+1];
+	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
+		if (cfg->end_bus < cfg->start_bus)
+			cfg->end_bus = 255;
 
-		if (cfg->end_bus_number < cfg->start_bus_number)
-			cfg->end_bus_number = 255;
-
-		if (cfg->end_bus_number >= cfgx->start_bus_number)
-			cfg->end_bus_number = cfgx->start_bus_number - 1;
+		cfgx = list_entry(cfg->list.next, typeof(*cfg), list);
+		if (cfg != cfgx && cfg->end_bus >= cfgx->start_bus)
+			cfg->end_bus = cfgx->start_bus - 1;
 	}
 }
 
@@ -306,8 +334,7 @@
 	if (!raw_pci_ops)
 		return 0;
 
-	pci_mmcfg_config_num = 0;
-	pci_mmcfg_config = NULL;
+	free_all_mmcfg();
 
 	for (i = 0; i < ARRAY_SIZE(pci_mmcfg_probes); i++) {
 		bus =  pci_mmcfg_probes[i].bus;
@@ -322,45 +349,22 @@
 			name = pci_mmcfg_probes[i].probe();
 
 		if (name)
-			printk(KERN_INFO "PCI: Found %s with MMCONFIG support.\n",
+			printk(KERN_INFO PREFIX "%s with MMCONFIG support\n",
 			       name);
 	}
 
 	/* some end_bus_number is crazy, fix it */
 	pci_mmcfg_check_end_bus_number();
 
-	return pci_mmcfg_config_num != 0;
+	return !list_empty(&pci_mmcfg_list);
 }
 
 static void __init pci_mmcfg_insert_resources(void)
 {
-#define PCI_MMCFG_RESOURCE_NAME_LEN 24
-	int i;
-	struct resource *res;
-	char *names;
-	unsigned num_buses;
+	struct pci_mmcfg_region *cfg;
 
-	res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res),
-			pci_mmcfg_config_num, GFP_KERNEL);
-	if (!res) {
-		printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n");
-		return;
-	}
-
-	names = (void *)&res[pci_mmcfg_config_num];
-	for (i = 0; i < pci_mmcfg_config_num; i++, res++) {
-		struct acpi_mcfg_allocation *cfg = &pci_mmcfg_config[i];
-		num_buses = cfg->end_bus_number - cfg->start_bus_number + 1;
-		res->name = names;
-		snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN,
-			 "PCI MMCONFIG %u [%02x-%02x]", cfg->pci_segment,
-			 cfg->start_bus_number, cfg->end_bus_number);
-		res->start = cfg->address + (cfg->start_bus_number << 20);
-		res->end = res->start + (num_buses << 20) - 1;
-		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-		insert_resource(&iomem_resource, res);
-		names += PCI_MMCFG_RESOURCE_NAME_LEN;
-	}
+	list_for_each_entry(cfg, &pci_mmcfg_list, list)
+		insert_resource(&iomem_resource, &cfg->res);
 
 	/* Mark that the resources have been inserted. */
 	pci_mmcfg_resources_inserted = 1;
@@ -437,11 +441,12 @@
 typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type);
 
 static int __init is_mmconf_reserved(check_reserved_t is_reserved,
-		u64 addr, u64 size, int i,
-		typeof(pci_mmcfg_config[0]) *cfg, int with_e820)
+				    struct pci_mmcfg_region *cfg, int with_e820)
 {
+	u64 addr = cfg->res.start;
+	u64 size = resource_size(&cfg->res);
 	u64 old_size = size;
-	int valid = 0;
+	int valid = 0, num_buses;
 
 	while (!is_reserved(addr, addr + size, E820_RESERVED)) {
 		size >>= 1;
@@ -450,19 +455,25 @@
 	}
 
 	if (size >= (16UL<<20) || size == old_size) {
-		printk(KERN_NOTICE
-		       "PCI: MCFG area at %Lx reserved in %s\n",
-			addr, with_e820?"E820":"ACPI motherboard resources");
+		printk(KERN_INFO PREFIX "MMCONFIG at %pR reserved in %s\n",
+		       &cfg->res,
+		       with_e820 ? "E820" : "ACPI motherboard resources");
 		valid = 1;
 
 		if (old_size != size) {
-			/* update end_bus_number */
-			cfg->end_bus_number = cfg->start_bus_number + ((size>>20) - 1);
-			printk(KERN_NOTICE "PCI: updated MCFG configuration %d: base %lx "
-			       "segment %hu buses %u - %u\n",
-			       i, (unsigned long)cfg->address, cfg->pci_segment,
-			       (unsigned int)cfg->start_bus_number,
-			       (unsigned int)cfg->end_bus_number);
+			/* update end_bus */
+			cfg->end_bus = cfg->start_bus + ((size>>20) - 1);
+			num_buses = cfg->end_bus - cfg->start_bus + 1;
+			cfg->res.end = cfg->res.start +
+			    PCI_MMCFG_BUS_OFFSET(num_buses) - 1;
+			snprintf(cfg->name, PCI_MMCFG_RESOURCE_NAME_LEN,
+				 "PCI MMCONFIG %04x [bus %02x-%02x]",
+				 cfg->segment, cfg->start_bus, cfg->end_bus);
+			printk(KERN_INFO PREFIX
+			       "MMCONFIG for %04x [bus%02x-%02x] "
+			       "at %pR (base %#lx) (size reduced!)\n",
+			       cfg->segment, cfg->start_bus, cfg->end_bus,
+			       &cfg->res, (unsigned long) cfg->address);
 		}
 	}
 
@@ -471,45 +482,26 @@
 
 static void __init pci_mmcfg_reject_broken(int early)
 {
-	typeof(pci_mmcfg_config[0]) *cfg;
-	int i;
+	struct pci_mmcfg_region *cfg;
 
-	if ((pci_mmcfg_config_num == 0) ||
-	    (pci_mmcfg_config == NULL) ||
-	    (pci_mmcfg_config[0].address == 0))
-		return;
-
-	for (i = 0; i < pci_mmcfg_config_num; i++) {
+	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
 		int valid = 0;
-		u64 addr, size;
-
-		cfg = &pci_mmcfg_config[i];
-		addr = cfg->start_bus_number;
-		addr <<= 20;
-		addr += cfg->address;
-		size = cfg->end_bus_number + 1 - cfg->start_bus_number;
-		size <<= 20;
-		printk(KERN_NOTICE "PCI: MCFG configuration %d: base %lx "
-		       "segment %hu buses %u - %u\n",
-		       i, (unsigned long)cfg->address, cfg->pci_segment,
-		       (unsigned int)cfg->start_bus_number,
-		       (unsigned int)cfg->end_bus_number);
 
 		if (!early && !acpi_disabled)
-			valid = is_mmconf_reserved(is_acpi_reserved, addr, size, i, cfg, 0);
+			valid = is_mmconf_reserved(is_acpi_reserved, cfg, 0);
 
 		if (valid)
 			continue;
 
 		if (!early)
-			printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not"
-			       " reserved in ACPI motherboard resources\n",
-			       cfg->address);
+			printk(KERN_ERR FW_BUG PREFIX
+			       "MMCONFIG at %pR not reserved in "
+			       "ACPI motherboard resources\n", &cfg->res);
 
 		/* Don't try to do this check unless configuration
 		   type 1 is available. how about type 2 ?*/
 		if (raw_pci_ops)
-			valid = is_mmconf_reserved(e820_all_mapped, addr, size, i, cfg, 1);
+			valid = is_mmconf_reserved(e820_all_mapped, cfg, 1);
 
 		if (!valid)
 			goto reject;
@@ -518,34 +510,41 @@
 	return;
 
 reject:
-	printk(KERN_INFO "PCI: Not using MMCONFIG.\n");
-	pci_mmcfg_arch_free();
-	kfree(pci_mmcfg_config);
-	pci_mmcfg_config = NULL;
-	pci_mmcfg_config_num = 0;
+	printk(KERN_INFO PREFIX "not using MMCONFIG\n");
+	free_all_mmcfg();
 }
 
 static int __initdata known_bridge;
 
-static int acpi_mcfg_64bit_base_addr __initdata = FALSE;
-
-/* The physical address of the MMCONFIG aperture.  Set from ACPI tables. */
-struct acpi_mcfg_allocation *pci_mmcfg_config;
-int pci_mmcfg_config_num;
-
-static int __init acpi_mcfg_oem_check(struct acpi_table_mcfg *mcfg)
+static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg,
+					struct acpi_mcfg_allocation *cfg)
 {
-	if (!strcmp(mcfg->header.oem_id, "SGI"))
-		acpi_mcfg_64bit_base_addr = TRUE;
+	int year;
 
-	return 0;
+	if (cfg->address < 0xFFFFFFFF)
+		return 0;
+
+	if (!strcmp(mcfg->header.oem_id, "SGI"))
+		return 0;
+
+	if (mcfg->header.revision >= 1) {
+		if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) &&
+		    year >= 2010)
+			return 0;
+	}
+
+	printk(KERN_ERR PREFIX "MCFG region for %04x [bus %02x-%02x] at %#llx "
+	       "is above 4GB, ignored\n", cfg->pci_segment,
+	       cfg->start_bus_number, cfg->end_bus_number, cfg->address);
+	return -EINVAL;
 }
 
 static int __init pci_parse_mcfg(struct acpi_table_header *header)
 {
 	struct acpi_table_mcfg *mcfg;
+	struct acpi_mcfg_allocation *cfg_table, *cfg;
 	unsigned long i;
-	int config_size;
+	int entries;
 
 	if (!header)
 		return -EINVAL;
@@ -553,38 +552,33 @@
 	mcfg = (struct acpi_table_mcfg *)header;
 
 	/* how many config structures do we have */
-	pci_mmcfg_config_num = 0;
+	free_all_mmcfg();
+	entries = 0;
 	i = header->length - sizeof(struct acpi_table_mcfg);
 	while (i >= sizeof(struct acpi_mcfg_allocation)) {
-		++pci_mmcfg_config_num;
+		entries++;
 		i -= sizeof(struct acpi_mcfg_allocation);
 	};
-	if (pci_mmcfg_config_num == 0) {
+	if (entries == 0) {
 		printk(KERN_ERR PREFIX "MMCONFIG has no entries\n");
 		return -ENODEV;
 	}
 
-	config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config);
-	pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL);
-	if (!pci_mmcfg_config) {
-		printk(KERN_WARNING PREFIX
-		       "No memory for MCFG config tables\n");
-		return -ENOMEM;
-	}
-
-	memcpy(pci_mmcfg_config, &mcfg[1], config_size);
-
-	acpi_mcfg_oem_check(mcfg);
-
-	for (i = 0; i < pci_mmcfg_config_num; ++i) {
-		if ((pci_mmcfg_config[i].address > 0xFFFFFFFF) &&
-		    !acpi_mcfg_64bit_base_addr) {
-			printk(KERN_ERR PREFIX
-			       "MMCONFIG not in low 4GB of memory\n");
-			kfree(pci_mmcfg_config);
-			pci_mmcfg_config_num = 0;
+	cfg_table = (struct acpi_mcfg_allocation *) &mcfg[1];
+	for (i = 0; i < entries; i++) {
+		cfg = &cfg_table[i];
+		if (acpi_mcfg_check_entry(mcfg, cfg)) {
+			free_all_mmcfg();
 			return -ENODEV;
 		}
+
+		if (pci_mmconfig_add(cfg->pci_segment, cfg->start_bus_number,
+				   cfg->end_bus_number, cfg->address) == NULL) {
+			printk(KERN_WARNING PREFIX
+			       "no memory for MCFG entries\n");
+			free_all_mmcfg();
+			return -ENOMEM;
+		}
 	}
 
 	return 0;
@@ -614,9 +608,7 @@
 
 	pci_mmcfg_reject_broken(early);
 
-	if ((pci_mmcfg_config_num == 0) ||
-	    (pci_mmcfg_config == NULL) ||
-	    (pci_mmcfg_config[0].address == 0))
+	if (list_empty(&pci_mmcfg_list))
 		return;
 
 	if (pci_mmcfg_arch_init())
@@ -648,9 +640,7 @@
 	 */
 	if ((pci_mmcfg_resources_inserted == 1) ||
 	    (pci_probe & PCI_PROBE_MMCONF) == 0 ||
-	    (pci_mmcfg_config_num == 0) ||
-	    (pci_mmcfg_config == NULL) ||
-	    (pci_mmcfg_config[0].address == 0))
+	    list_empty(&pci_mmcfg_list))
 		return 1;
 
 	/*
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c
index f10a7e9..90d5fd47 100644
--- a/arch/x86/pci/mmconfig_32.c
+++ b/arch/x86/pci/mmconfig_32.c
@@ -27,18 +27,10 @@
  */
 static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn)
 {
-	struct acpi_mcfg_allocation *cfg;
-	int cfg_num;
+	struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
 
-	for (cfg_num = 0; cfg_num < pci_mmcfg_config_num; cfg_num++) {
-		cfg = &pci_mmcfg_config[cfg_num];
-		if (cfg->pci_segment == seg &&
-		    (cfg->start_bus_number <= bus) &&
-		    (cfg->end_bus_number >= bus))
-			return cfg->address;
-	}
-
-	/* Fall back to type 0 */
+	if (cfg)
+		return cfg->address;
 	return 0;
 }
 
@@ -47,7 +39,7 @@
  */
 static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn)
 {
-	u32 dev_base = base | (bus << 20) | (devfn << 12);
+	u32 dev_base = base | PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12);
 	int cpu = smp_processor_id();
 	if (dev_base != mmcfg_last_accessed_device ||
 	    cpu != mmcfg_last_accessed_cpu) {
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c
index 94349f8..e783841 100644
--- a/arch/x86/pci/mmconfig_64.c
+++ b/arch/x86/pci/mmconfig_64.c
@@ -12,38 +12,15 @@
 #include <asm/e820.h>
 #include <asm/pci_x86.h>
 
-/* Static virtual mapping of the MMCONFIG aperture */
-struct mmcfg_virt {
-	struct acpi_mcfg_allocation *cfg;
-	char __iomem *virt;
-};
-static struct mmcfg_virt *pci_mmcfg_virt;
-
-static char __iomem *get_virt(unsigned int seg, unsigned bus)
-{
-	struct acpi_mcfg_allocation *cfg;
-	int cfg_num;
-
-	for (cfg_num = 0; cfg_num < pci_mmcfg_config_num; cfg_num++) {
-		cfg = pci_mmcfg_virt[cfg_num].cfg;
-		if (cfg->pci_segment == seg &&
-		    (cfg->start_bus_number <= bus) &&
-		    (cfg->end_bus_number >= bus))
-			return pci_mmcfg_virt[cfg_num].virt;
-	}
-
-	/* Fall back to type 0 */
-	return NULL;
-}
+#define PREFIX "PCI: "
 
 static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
 {
-	char __iomem *addr;
+	struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
 
-	addr = get_virt(seg, bus);
-	if (!addr)
-		return NULL;
- 	return addr + ((bus << 20) | (devfn << 12));
+	if (cfg && cfg->virt)
+		return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12));
+	return NULL;
 }
 
 static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
@@ -109,42 +86,30 @@
 	.write =	pci_mmcfg_write,
 };
 
-static void __iomem * __init mcfg_ioremap(struct acpi_mcfg_allocation *cfg)
+static void __iomem * __init mcfg_ioremap(struct pci_mmcfg_region *cfg)
 {
 	void __iomem *addr;
 	u64 start, size;
+	int num_buses;
 
-	start = cfg->start_bus_number;
-	start <<= 20;
-	start += cfg->address;
-	size = cfg->end_bus_number + 1 - cfg->start_bus_number;
-	size <<= 20;
+	start = cfg->address + PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
+	num_buses = cfg->end_bus - cfg->start_bus + 1;
+	size = PCI_MMCFG_BUS_OFFSET(num_buses);
 	addr = ioremap_nocache(start, size);
-	if (addr) {
-		printk(KERN_INFO "PCI: Using MMCONFIG at %Lx - %Lx\n",
-		       start, start + size - 1);
-		addr -= cfg->start_bus_number << 20;
-	}
+	if (addr)
+		addr -= PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
 	return addr;
 }
 
 int __init pci_mmcfg_arch_init(void)
 {
-	int i;
-	pci_mmcfg_virt = kzalloc(sizeof(*pci_mmcfg_virt) *
-				 pci_mmcfg_config_num, GFP_KERNEL);
-	if (pci_mmcfg_virt == NULL) {
-		printk(KERN_ERR "PCI: Can not allocate memory for mmconfig structures\n");
-		return 0;
-	}
+	struct pci_mmcfg_region *cfg;
 
-	for (i = 0; i < pci_mmcfg_config_num; ++i) {
-		pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i];
-		pci_mmcfg_virt[i].virt = mcfg_ioremap(&pci_mmcfg_config[i]);
-		if (!pci_mmcfg_virt[i].virt) {
-			printk(KERN_ERR "PCI: Cannot map mmconfig aperture for "
-					"segment %d\n",
-				pci_mmcfg_config[i].pci_segment);
+	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
+		cfg->virt = mcfg_ioremap(cfg);
+		if (!cfg->virt) {
+			printk(KERN_ERR PREFIX "can't map MMCONFIG at %pR\n",
+			       &cfg->res);
 			pci_mmcfg_arch_free();
 			return 0;
 		}
@@ -155,19 +120,12 @@
 
 void __init pci_mmcfg_arch_free(void)
 {
-	int i;
+	struct pci_mmcfg_region *cfg;
 
-	if (pci_mmcfg_virt == NULL)
-		return;
-
-	for (i = 0; i < pci_mmcfg_config_num; ++i) {
-		if (pci_mmcfg_virt[i].virt) {
-			iounmap(pci_mmcfg_virt[i].virt + (pci_mmcfg_virt[i].cfg->start_bus_number << 20));
-			pci_mmcfg_virt[i].virt = NULL;
-			pci_mmcfg_virt[i].cfg = NULL;
+	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
+		if (cfg->virt) {
+			iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus));
+			cfg->virt = NULL;
 		}
 	}
-
-	kfree(pci_mmcfg_virt);
-	pci_mmcfg_virt = NULL;
 }
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index dfbf70e..2b26dd5 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -27,7 +27,9 @@
 #include <linux/page-flags.h>
 #include <linux/highmem.h>
 #include <linux/console.h>
+#include <linux/pci.h>
 
+#include <xen/xen.h>
 #include <xen/interface/xen.h>
 #include <xen/interface/version.h>
 #include <xen/interface/physdev.h>
@@ -138,24 +140,23 @@
  */
 void xen_vcpu_restore(void)
 {
-	if (have_vcpu_info_placement) {
-		int cpu;
+	int cpu;
 
-		for_each_online_cpu(cpu) {
-			bool other_cpu = (cpu != smp_processor_id());
+	for_each_online_cpu(cpu) {
+		bool other_cpu = (cpu != smp_processor_id());
 
-			if (other_cpu &&
-			    HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL))
-				BUG();
+		if (other_cpu &&
+		    HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL))
+			BUG();
 
+		xen_setup_runstate_info(cpu);
+
+		if (have_vcpu_info_placement)
 			xen_vcpu_setup(cpu);
 
-			if (other_cpu &&
-			    HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL))
-				BUG();
-		}
-
-		BUG_ON(!have_vcpu_info_placement);
+		if (other_cpu &&
+		    HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL))
+			BUG();
 	}
 }
 
@@ -1093,10 +1094,8 @@
 
 	__supported_pte_mask |= _PAGE_IOMAP;
 
-#ifdef CONFIG_X86_64
 	/* Work out if we support NX */
-	check_efer();
-#endif
+	x86_configure_nx();
 
 	xen_setup_features();
 
@@ -1178,10 +1177,16 @@
 		add_preferred_console("xenboot", 0, NULL);
 		add_preferred_console("tty", 0, NULL);
 		add_preferred_console("hvc", 0, NULL);
+	} else {
+		/* Make sure ACS will be enabled */
+		pci_request_acs();
 	}
+		
 
 	xen_raw_console_write("about to get started...\n");
 
+	xen_setup_runstate_info(0);
+
 	/* Start the world */
 #ifdef CONFIG_X86_32
 	i386_start_kernel();
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 3bf7b1d..bf4cd6b 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -185,7 +185,7 @@
 }
 
 /* Build the parallel p2m_top_mfn structures */
-static void __init xen_build_mfn_list_list(void)
+void xen_build_mfn_list_list(void)
 {
 	unsigned pfn, idx;
 
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index fe03eee..64757c0 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -73,7 +73,7 @@
 
 	xen_setup_cpu_clockevents();
 
-	cpu_set(cpu, cpu_online_map);
+	set_cpu_online(cpu, true);
 	percpu_write(cpu_state, CPU_ONLINE);
 	wmb();
 
@@ -295,6 +295,7 @@
 		(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/suspend.c b/arch/x86/xen/suspend.c
index 95be7b4..987267f 100644
--- a/arch/x86/xen/suspend.c
+++ b/arch/x86/xen/suspend.c
@@ -1,4 +1,5 @@
 #include <linux/types.h>
+#include <linux/clockchips.h>
 
 #include <xen/interface/xen.h>
 #include <xen/grant_table.h>
@@ -27,6 +28,8 @@
 
 void xen_post_suspend(int suspend_cancelled)
 {
+	xen_build_mfn_list_list();
+
 	xen_setup_shared_info();
 
 	if (suspend_cancelled) {
@@ -44,7 +47,19 @@
 
 }
 
+static void xen_vcpu_notify_restore(void *data)
+{
+	unsigned long reason = (unsigned long)data;
+
+	/* Boot processor notified via generic timekeeping_resume() */
+	if ( smp_processor_id() == 0)
+		return;
+
+	clockevents_notify(reason, NULL);
+}
+
 void xen_arch_resume(void)
 {
-	/* nothing */
+	smp_call_function(xen_vcpu_notify_restore,
+			       (void *)CLOCK_EVT_NOTIFY_RESUME, 1);
 }
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index 0a5aa44..9d1f853 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -100,7 +100,7 @@
 	return per_cpu(runstate, vcpu).state == RUNSTATE_runnable;
 }
 
-static void setup_runstate_info(int cpu)
+void xen_setup_runstate_info(int cpu)
 {
 	struct vcpu_register_runstate_memory_area area;
 
@@ -434,7 +434,7 @@
 		name = "<timer kasprintf failed>";
 
 	irq = bind_virq_to_irqhandler(VIRQ_TIMER, cpu, xen_timer_interrupt,
-				      IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING,
+				      IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING|IRQF_TIMER,
 				      name, NULL);
 
 	evt = &per_cpu(xen_clock_events, cpu);
@@ -442,8 +442,6 @@
 
 	evt->cpumask = cpumask_of(cpu);
 	evt->irq = irq;
-
-	setup_runstate_info(cpu);
 }
 
 void xen_teardown_timer(int cpu)
@@ -494,6 +492,7 @@
 
 	setup_force_cpu_cap(X86_FEATURE_TSC);
 
+	xen_setup_runstate_info(cpu);
 	xen_setup_timer(cpu);
 	xen_setup_cpu_clockevents();
 }
diff --git a/arch/x86/xen/xen-asm_64.S b/arch/x86/xen/xen-asm_64.S
index 02f496a..53adefd 100644
--- a/arch/x86/xen/xen-asm_64.S
+++ b/arch/x86/xen/xen-asm_64.S
@@ -96,7 +96,7 @@
 	pushq $__USER32_CS
 	pushq %rcx
 
-	pushq $VGCF_in_syscall
+	pushq $0
 1:	jmp hypercall_iret
 ENDPATCH(xen_sysret32)
 RELOC(xen_sysret32, 1b+1)
@@ -151,7 +151,7 @@
 ENTRY(xen_sysenter_target)
 	lea 16(%rsp), %rsp	/* strip %rcx, %r11 */
 	mov $-ENOSYS, %rax
-	pushq $VGCF_in_syscall
+	pushq $0
 	jmp hypercall_iret
 ENDPROC(xen_syscall32_target)
 ENDPROC(xen_sysenter_target)
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index 355fa6b..f9153a3 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -25,6 +25,7 @@
 
 void xen_setup_mfn_list_list(void);
 void xen_setup_shared_info(void);
+void xen_build_mfn_list_list(void);
 void xen_setup_machphys_mapping(void);
 pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn);
 void xen_ident_map_ISA(void);
@@ -41,6 +42,7 @@
 
 void xen_init_irq_ops(void);
 void xen_setup_timer(int cpu);
+void xen_setup_runstate_info(int cpu);
 void xen_teardown_timer(int cpu);
 cycle_t xen_clocksource_read(void);
 void xen_setup_cpu_clockevents(void);
diff --git a/arch/xtensa/include/asm/syscall.h b/arch/xtensa/include/asm/syscall.h
index 05cebf8..4352dbe 100644
--- a/arch/xtensa/include/asm/syscall.h
+++ b/arch/xtensa/include/asm/syscall.h
@@ -13,8 +13,6 @@
 asmlinkage long xtensa_execve(char*, char**, char**, struct pt_regs*);
 asmlinkage long xtensa_clone(unsigned long, unsigned long, struct pt_regs*);
 asmlinkage long xtensa_pipe(int __user *);
-asmlinkage long xtensa_mmap2(unsigned long, unsigned long, unsigned long,
-    			     unsigned long, unsigned long, unsigned long);
 asmlinkage long xtensa_ptrace(long, long, long, long);
 asmlinkage long xtensa_sigreturn(struct pt_regs*);
 asmlinkage long xtensa_rt_sigreturn(struct pt_regs*);
diff --git a/arch/xtensa/include/asm/unistd.h b/arch/xtensa/include/asm/unistd.h
index 4e55dc7..fbf318b 100644
--- a/arch/xtensa/include/asm/unistd.h
+++ b/arch/xtensa/include/asm/unistd.h
@@ -189,7 +189,7 @@
 /* File Map / Shared Memory Operations */
 
 #define __NR_mmap2 				 80
-__SYSCALL( 80, xtensa_mmap2, 6)
+__SYSCALL( 80, sys_mmap_pgoff, 6)
 #define __NR_munmap 				 81
 __SYSCALL( 81, sys_munmap, 2)
 #define __NR_mprotect 				 82
diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c
index ac15ecb..1e67bab 100644
--- a/arch/xtensa/kernel/syscall.c
+++ b/arch/xtensa/kernel/syscall.c
@@ -57,31 +57,6 @@
 	return error;
 }
 
-
-asmlinkage long xtensa_mmap2(unsigned long addr, unsigned long len,
-   			     unsigned long prot, unsigned long flags,
-			     unsigned long fd, unsigned long pgoff)
-{
-	int error = -EBADF;
-	struct file * file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-
 asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg)
 {
 	unsigned long ret;
diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c
index 4c559cf..e60a1f5 100644
--- a/arch/xtensa/platforms/iss/console.c
+++ b/arch/xtensa/platforms/iss/console.c
@@ -196,7 +196,7 @@
 	.release	= single_release,
 };
 
-static struct tty_operations serial_ops = {
+static const struct tty_operations serial_ops = {
 	.open = rs_open,
 	.close = rs_close,
 	.write = rs_write,
diff --git a/block/blk-iopoll.c b/block/blk-iopoll.c
index ca56420..58916af 100644
--- a/block/blk-iopoll.c
+++ b/block/blk-iopoll.c
@@ -28,7 +28,7 @@
  * Description:
  *     Add this blk_iopoll structure to the pending poll list and trigger the
  *     raise of the blk iopoll softirq. The driver must already have gotten a
- *     succesful return from blk_iopoll_sched_prep() before calling this.
+ *     successful return from blk_iopoll_sched_prep() before calling this.
  **/
 void blk_iopoll_sched(struct blk_iopoll *iop)
 {
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 26b5dd0..81c185a 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -440,6 +440,15 @@
 	  See also:
 	  <http://planeta.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html>
 
+config CRYPTO_GHASH_CLMUL_NI_INTEL
+	tristate "GHASH digest algorithm (CLMUL-NI accelerated)"
+	depends on (X86 || UML_X86) && 64BIT
+	select CRYPTO_SHASH
+	select CRYPTO_CRYPTD
+	help
+	  GHASH is message digest algorithm for GCM (Galois/Counter Mode).
+	  The implementation is accelerated by CLMUL-NI of Intel.
+
 comment "Ciphers"
 
 config CRYPTO_AES
diff --git a/crypto/ansi_cprng.c b/crypto/ansi_cprng.c
index 3aa6e38..2bc3321 100644
--- a/crypto/ansi_cprng.c
+++ b/crypto/ansi_cprng.c
@@ -85,7 +85,7 @@
  * Returns DEFAULT_BLK_SZ bytes of random data per call
  * returns 0 if generation succeded, <0 if something went wrong
  */
-static int _get_more_prng_bytes(struct prng_context *ctx)
+static int _get_more_prng_bytes(struct prng_context *ctx, int cont_test)
 {
 	int i;
 	unsigned char tmp[DEFAULT_BLK_SZ];
@@ -132,7 +132,7 @@
 			 */
 			if (!memcmp(ctx->rand_data, ctx->last_rand_data,
 					DEFAULT_BLK_SZ)) {
-				if (fips_enabled) {
+				if (cont_test) {
 					panic("cprng %p Failed repetition check!\n",
 						ctx);
 				}
@@ -185,16 +185,14 @@
 }
 
 /* Our exported functions */
-static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx)
+static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx,
+				int do_cont_test)
 {
 	unsigned char *ptr = buf;
 	unsigned int byte_count = (unsigned int)nbytes;
 	int err;
 
 
-	if (nbytes < 0)
-		return -EINVAL;
-
 	spin_lock_bh(&ctx->prng_lock);
 
 	err = -EINVAL;
@@ -220,7 +218,7 @@
 
 remainder:
 	if (ctx->rand_data_valid == DEFAULT_BLK_SZ) {
-		if (_get_more_prng_bytes(ctx) < 0) {
+		if (_get_more_prng_bytes(ctx, do_cont_test) < 0) {
 			memset(buf, 0, nbytes);
 			err = -EINVAL;
 			goto done;
@@ -247,7 +245,7 @@
 	 */
 	for (; byte_count >= DEFAULT_BLK_SZ; byte_count -= DEFAULT_BLK_SZ) {
 		if (ctx->rand_data_valid == DEFAULT_BLK_SZ) {
-			if (_get_more_prng_bytes(ctx) < 0) {
+			if (_get_more_prng_bytes(ctx, do_cont_test) < 0) {
 				memset(buf, 0, nbytes);
 				err = -EINVAL;
 				goto done;
@@ -356,7 +354,7 @@
 {
 	struct prng_context *prng = crypto_rng_ctx(tfm);
 
-	return get_prng_bytes(rdata, dlen, prng);
+	return get_prng_bytes(rdata, dlen, prng, 0);
 }
 
 /*
@@ -404,19 +402,79 @@
 	}
 };
 
+#ifdef CONFIG_CRYPTO_FIPS
+static int fips_cprng_get_random(struct crypto_rng *tfm, u8 *rdata,
+			    unsigned int dlen)
+{
+	struct prng_context *prng = crypto_rng_ctx(tfm);
+
+	return get_prng_bytes(rdata, dlen, prng, 1);
+}
+
+static int fips_cprng_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen)
+{
+	u8 rdata[DEFAULT_BLK_SZ];
+	int rc;
+
+	struct prng_context *prng = crypto_rng_ctx(tfm);
+
+	rc = cprng_reset(tfm, seed, slen);
+
+	if (!rc)
+		goto out;
+
+	/* this primes our continuity test */
+	rc = get_prng_bytes(rdata, DEFAULT_BLK_SZ, prng, 0);
+	prng->rand_data_valid = DEFAULT_BLK_SZ;
+
+out:
+	return rc;
+}
+
+static struct crypto_alg fips_rng_alg = {
+	.cra_name		= "fips(ansi_cprng)",
+	.cra_driver_name	= "fips_ansi_cprng",
+	.cra_priority		= 300,
+	.cra_flags		= CRYPTO_ALG_TYPE_RNG,
+	.cra_ctxsize		= sizeof(struct prng_context),
+	.cra_type		= &crypto_rng_type,
+	.cra_module		= THIS_MODULE,
+	.cra_list		= LIST_HEAD_INIT(rng_alg.cra_list),
+	.cra_init		= cprng_init,
+	.cra_exit		= cprng_exit,
+	.cra_u			= {
+		.rng = {
+			.rng_make_random	= fips_cprng_get_random,
+			.rng_reset		= fips_cprng_reset,
+			.seedsize = DEFAULT_PRNG_KSZ + 2*DEFAULT_BLK_SZ,
+		}
+	}
+};
+#endif
 
 /* Module initalization */
 static int __init prng_mod_init(void)
 {
-	if (fips_enabled)
-		rng_alg.cra_priority += 200;
+	int rc = 0;
 
-	return crypto_register_alg(&rng_alg);
+	rc = crypto_register_alg(&rng_alg);
+#ifdef CONFIG_CRYPTO_FIPS
+	if (rc)
+		goto out;
+
+	rc = crypto_register_alg(&fips_rng_alg);
+
+out:
+#endif
+	return rc;
 }
 
 static void __exit prng_mod_fini(void)
 {
 	crypto_unregister_alg(&rng_alg);
+#ifdef CONFIG_CRYPTO_FIPS
+	crypto_unregister_alg(&fips_rng_alg);
+#endif
 	return;
 }
 
diff --git a/crypto/cryptd.c b/crypto/cryptd.c
index 3533582..f8ae0d9 100644
--- a/crypto/cryptd.c
+++ b/crypto/cryptd.c
@@ -711,6 +711,13 @@
 }
 EXPORT_SYMBOL_GPL(cryptd_ahash_child);
 
+struct shash_desc *cryptd_shash_desc(struct ahash_request *req)
+{
+	struct cryptd_hash_request_ctx *rctx = ahash_request_ctx(req);
+	return &rctx->desc;
+}
+EXPORT_SYMBOL_GPL(cryptd_shash_desc);
+
 void cryptd_free_ahash(struct cryptd_ahash *tfm)
 {
 	crypto_free_ahash(&tfm->base);
diff --git a/crypto/digest.c b/crypto/digest.c
deleted file mode 100644
index 5d3f130..0000000
--- a/crypto/digest.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Cryptographic API.
- *
- * Digest operations.
- *
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option) 
- * any later version.
- *
- */
-
-#include <crypto/internal/hash.h>
-#include <crypto/scatterwalk.h>
-#include <linux/mm.h>
-#include <linux/errno.h>
-#include <linux/hardirq.h>
-#include <linux/highmem.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/scatterlist.h>
-
-#include "internal.h"
-
-static int init(struct hash_desc *desc)
-{
-	struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);
-
-	tfm->__crt_alg->cra_digest.dia_init(tfm);
-	return 0;
-}
-
-static int update2(struct hash_desc *desc,
-		   struct scatterlist *sg, unsigned int nbytes)
-{
-	struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);
-	unsigned int alignmask = crypto_tfm_alg_alignmask(tfm);
-
-	if (!nbytes)
-		return 0;
-
-	for (;;) {
-		struct page *pg = sg_page(sg);
-		unsigned int offset = sg->offset;
-		unsigned int l = sg->length;
-
-		if (unlikely(l > nbytes))
-			l = nbytes;
-		nbytes -= l;
-
-		do {
-			unsigned int bytes_from_page = min(l, ((unsigned int)
-							   (PAGE_SIZE)) - 
-							   offset);
-			char *src = crypto_kmap(pg, 0);
-			char *p = src + offset;
-
-			if (unlikely(offset & alignmask)) {
-				unsigned int bytes =
-					alignmask + 1 - (offset & alignmask);
-				bytes = min(bytes, bytes_from_page);
-				tfm->__crt_alg->cra_digest.dia_update(tfm, p,
-								      bytes);
-				p += bytes;
-				bytes_from_page -= bytes;
-				l -= bytes;
-			}
-			tfm->__crt_alg->cra_digest.dia_update(tfm, p,
-							      bytes_from_page);
-			crypto_kunmap(src, 0);
-			crypto_yield(desc->flags);
-			offset = 0;
-			pg++;
-			l -= bytes_from_page;
-		} while (l > 0);
-
-		if (!nbytes)
-			break;
-		sg = scatterwalk_sg_next(sg);
-	}
-
-	return 0;
-}
-
-static int update(struct hash_desc *desc,
-		  struct scatterlist *sg, unsigned int nbytes)
-{
-	if (WARN_ON_ONCE(in_irq()))
-		return -EDEADLK;
-	return update2(desc, sg, nbytes);
-}
-
-static int final(struct hash_desc *desc, u8 *out)
-{
-	struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);
-	unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);
-	struct digest_alg *digest = &tfm->__crt_alg->cra_digest;
-
-	if (unlikely((unsigned long)out & alignmask)) {
-		unsigned long align = alignmask + 1;
-		unsigned long addr = (unsigned long)crypto_tfm_ctx(tfm);
-		u8 *dst = (u8 *)ALIGN(addr, align) +
-			  ALIGN(tfm->__crt_alg->cra_ctxsize, align);
-
-		digest->dia_final(tfm, dst);
-		memcpy(out, dst, digest->dia_digestsize);
-	} else
-		digest->dia_final(tfm, out);
-
-	return 0;
-}
-
-static int nosetkey(struct crypto_hash *tfm, const u8 *key, unsigned int keylen)
-{
-	crypto_hash_clear_flags(tfm, CRYPTO_TFM_RES_MASK);
-	return -ENOSYS;
-}
-
-static int setkey(struct crypto_hash *hash, const u8 *key, unsigned int keylen)
-{
-	struct crypto_tfm *tfm = crypto_hash_tfm(hash);
-
-	crypto_hash_clear_flags(hash, CRYPTO_TFM_RES_MASK);
-	return tfm->__crt_alg->cra_digest.dia_setkey(tfm, key, keylen);
-}
-
-static int digest(struct hash_desc *desc,
-		  struct scatterlist *sg, unsigned int nbytes, u8 *out)
-{
-	if (WARN_ON_ONCE(in_irq()))
-		return -EDEADLK;
-
-	init(desc);
-	update2(desc, sg, nbytes);
-	return final(desc, out);
-}
-
-int crypto_init_digest_ops(struct crypto_tfm *tfm)
-{
-	struct hash_tfm *ops = &tfm->crt_hash;
-	struct digest_alg *dalg = &tfm->__crt_alg->cra_digest;
-
-	if (dalg->dia_digestsize > PAGE_SIZE / 8)
-		return -EINVAL;
-	
-	ops->init	= init;
-	ops->update	= update;
-	ops->final	= final;
-	ops->digest	= digest;
-	ops->setkey	= dalg->dia_setkey ? setkey : nosetkey;
-	ops->digestsize	= dalg->dia_digestsize;
-	
-	return 0;
-}
-
-void crypto_exit_digest_ops(struct crypto_tfm *tfm)
-{
-}
-
-static int digest_async_nosetkey(struct crypto_ahash *tfm_async, const u8 *key,
-			unsigned int keylen)
-{
-	crypto_ahash_clear_flags(tfm_async, CRYPTO_TFM_RES_MASK);
-	return -ENOSYS;
-}
-
-static int digest_async_setkey(struct crypto_ahash *tfm_async, const u8 *key,
-			unsigned int keylen)
-{
-	struct crypto_tfm    *tfm        = crypto_ahash_tfm(tfm_async);
-	struct digest_alg    *dalg       = &tfm->__crt_alg->cra_digest;
-
-	crypto_ahash_clear_flags(tfm_async, CRYPTO_TFM_RES_MASK);
-	return dalg->dia_setkey(tfm, key, keylen);
-}
-
-static int digest_async_init(struct ahash_request *req)
-{
-	struct crypto_tfm *tfm  = req->base.tfm;
-	struct digest_alg *dalg = &tfm->__crt_alg->cra_digest;
-
-	dalg->dia_init(tfm);
-	return 0;
-}
-
-static int digest_async_update(struct ahash_request *req)
-{
-	struct crypto_tfm *tfm = req->base.tfm;
-	struct hash_desc  desc = {
-		.tfm   = __crypto_hash_cast(tfm),
-		.flags = req->base.flags,
-	};
-
-	update(&desc, req->src, req->nbytes);
-	return 0;
-}
-
-static int digest_async_final(struct ahash_request *req)
-{
-	struct crypto_tfm *tfm  = req->base.tfm;
-	struct hash_desc  desc = {
-		.tfm   = __crypto_hash_cast(tfm),
-		.flags = req->base.flags,
-	};
-
-	final(&desc, req->result);
-	return 0;
-}
-
-static int digest_async_digest(struct ahash_request *req)
-{
-	struct crypto_tfm *tfm  = req->base.tfm;
-	struct hash_desc  desc = {
-		.tfm   = __crypto_hash_cast(tfm),
-		.flags = req->base.flags,
-	};
-
-	return digest(&desc, req->src, req->nbytes, req->result);
-}
-
-int crypto_init_digest_ops_async(struct crypto_tfm *tfm)
-{
-	struct ahash_tfm  *crt  = &tfm->crt_ahash;
-	struct digest_alg *dalg = &tfm->__crt_alg->cra_digest;
-
-	if (dalg->dia_digestsize > PAGE_SIZE / 8)
-		return -EINVAL;
-
-	crt->init       = digest_async_init;
-	crt->update     = digest_async_update;
-	crt->final      = digest_async_final;
-	crt->digest     = digest_async_digest;
-	crt->setkey     = dalg->dia_setkey ? digest_async_setkey :
-						digest_async_nosetkey;
-	crt->digestsize = dalg->dia_digestsize;
-
-	return 0;
-}
diff --git a/crypto/hash.c b/crypto/hash.c
deleted file mode 100644
index cb86b19..0000000
--- a/crypto/hash.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Cryptographic Hash operations.
- * 
- * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option) 
- * any later version.
- */
-
-#include <crypto/internal/hash.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/seq_file.h>
-
-#include "internal.h"
-
-static unsigned int crypto_hash_ctxsize(struct crypto_alg *alg, u32 type,
-					u32 mask)
-{
-	return alg->cra_ctxsize;
-}
-
-static int hash_setkey_unaligned(struct crypto_hash *crt, const u8 *key,
-		                 unsigned int keylen)
-{
-	struct crypto_tfm *tfm = crypto_hash_tfm(crt);
-	struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
-	unsigned long alignmask = crypto_hash_alignmask(crt);
-	int ret;
-	u8 *buffer, *alignbuffer;
-	unsigned long absize;
-
-	absize = keylen + alignmask;
-	buffer = kmalloc(absize, GFP_ATOMIC);
-	if (!buffer)
-		return -ENOMEM;
-
-	alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
-	memcpy(alignbuffer, key, keylen);
-	ret = alg->setkey(crt, alignbuffer, keylen);
-	memset(alignbuffer, 0, keylen);
-	kfree(buffer);
-	return ret;
-}
-
-static int hash_setkey(struct crypto_hash *crt, const u8 *key,
-		       unsigned int keylen)
-{
-	struct crypto_tfm *tfm = crypto_hash_tfm(crt);
-	struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
-	unsigned long alignmask = crypto_hash_alignmask(crt);
-
-	if ((unsigned long)key & alignmask)
-		return hash_setkey_unaligned(crt, key, keylen);
-
-	return alg->setkey(crt, key, keylen);
-}
-
-static int hash_async_setkey(struct crypto_ahash *tfm_async, const u8 *key,
-			unsigned int keylen)
-{
-	struct crypto_tfm  *tfm      = crypto_ahash_tfm(tfm_async);
-	struct crypto_hash *tfm_hash = __crypto_hash_cast(tfm);
-	struct hash_alg    *alg      = &tfm->__crt_alg->cra_hash;
-
-	return alg->setkey(tfm_hash, key, keylen);
-}
-
-static int hash_async_init(struct ahash_request *req)
-{
-	struct crypto_tfm *tfm = req->base.tfm;
-	struct hash_alg   *alg = &tfm->__crt_alg->cra_hash;
-	struct hash_desc  desc = {
-		.tfm = __crypto_hash_cast(tfm),
-		.flags = req->base.flags,
-	};
-
-	return alg->init(&desc);
-}
-
-static int hash_async_update(struct ahash_request *req)
-{
-	struct crypto_tfm *tfm = req->base.tfm;
-	struct hash_alg   *alg = &tfm->__crt_alg->cra_hash;
-	struct hash_desc  desc = {
-		.tfm = __crypto_hash_cast(tfm),
-		.flags = req->base.flags,
-	};
-
-	return alg->update(&desc, req->src, req->nbytes);
-}
-
-static int hash_async_final(struct ahash_request *req)
-{
-	struct crypto_tfm *tfm = req->base.tfm;
-	struct hash_alg   *alg = &tfm->__crt_alg->cra_hash;
-	struct hash_desc  desc = {
-		.tfm = __crypto_hash_cast(tfm),
-		.flags = req->base.flags,
-	};
-
-	return alg->final(&desc, req->result);
-}
-
-static int hash_async_digest(struct ahash_request *req)
-{
-	struct crypto_tfm *tfm = req->base.tfm;
-	struct hash_alg   *alg = &tfm->__crt_alg->cra_hash;
-	struct hash_desc  desc = {
-		.tfm = __crypto_hash_cast(tfm),
-		.flags = req->base.flags,
-	};
-
-	return alg->digest(&desc, req->src, req->nbytes, req->result);
-}
-
-static int crypto_init_hash_ops_async(struct crypto_tfm *tfm)
-{
-	struct ahash_tfm *crt = &tfm->crt_ahash;
-	struct hash_alg  *alg = &tfm->__crt_alg->cra_hash;
-
-	crt->init       = hash_async_init;
-	crt->update     = hash_async_update;
-	crt->final      = hash_async_final;
-	crt->digest     = hash_async_digest;
-	crt->setkey     = hash_async_setkey;
-	crt->digestsize = alg->digestsize;
-
-	return 0;
-}
-
-static int crypto_init_hash_ops_sync(struct crypto_tfm *tfm)
-{
-	struct hash_tfm *crt = &tfm->crt_hash;
-	struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
-
-	crt->init       = alg->init;
-	crt->update     = alg->update;
-	crt->final      = alg->final;
-	crt->digest     = alg->digest;
-	crt->setkey     = hash_setkey;
-	crt->digestsize = alg->digestsize;
-
-	return 0;
-}
-
-static int crypto_init_hash_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
-{
-	struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
-
-	if (alg->digestsize > PAGE_SIZE / 8)
-		return -EINVAL;
-
-	if ((mask & CRYPTO_ALG_TYPE_HASH_MASK) != CRYPTO_ALG_TYPE_HASH_MASK)
-		return crypto_init_hash_ops_async(tfm);
-	else
-		return crypto_init_hash_ops_sync(tfm);
-}
-
-static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg)
-	__attribute__ ((unused));
-static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg)
-{
-	seq_printf(m, "type         : hash\n");
-	seq_printf(m, "blocksize    : %u\n", alg->cra_blocksize);
-	seq_printf(m, "digestsize   : %u\n", alg->cra_hash.digestsize);
-}
-
-const struct crypto_type crypto_hash_type = {
-	.ctxsize = crypto_hash_ctxsize,
-	.init = crypto_init_hash_ops,
-#ifdef CONFIG_PROC_FS
-	.show = crypto_hash_show,
-#endif
-};
-EXPORT_SYMBOL_GPL(crypto_hash_type);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Generic cryptographic hash type");
diff --git a/crypto/proc.c b/crypto/proc.c
index 1c38733..58fef67 100644
--- a/crypto/proc.c
+++ b/crypto/proc.c
@@ -109,13 +109,6 @@
 		seq_printf(m, "max keysize  : %u\n",
 					alg->cra_cipher.cia_max_keysize);
 		break;
-		
-	case CRYPTO_ALG_TYPE_DIGEST:
-		seq_printf(m, "type         : digest\n");
-		seq_printf(m, "blocksize    : %u\n", alg->cra_blocksize);
-		seq_printf(m, "digestsize   : %u\n",
-		           alg->cra_digest.dia_digestsize);
-		break;
 	case CRYPTO_ALG_TYPE_COMPRESS:
 		seq_printf(m, "type         : compression\n");
 		break;
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 6d5b746..7620bfc 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -1201,7 +1201,7 @@
 		      unsigned int tcount)
 {
 	const char *algo = crypto_tfm_alg_driver_name(crypto_rng_tfm(tfm));
-	int err, i, j, seedsize;
+	int err = 0, i, j, seedsize;
 	u8 *seed;
 	char result[32];
 
@@ -1943,6 +1943,15 @@
 			}
 		}
 	}, {
+		.alg = "ghash",
+		.test = alg_test_hash,
+		.suite = {
+			.hash = {
+				.vecs = ghash_tv_template,
+				.count = GHASH_TEST_VECTORS
+			}
+		}
+	}, {
 		.alg = "hmac(md5)",
 		.test = alg_test_hash,
 		.suite = {
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 9963b18..fb76517 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -1003,6 +1003,21 @@
 	},
 };
 
+#define GHASH_TEST_VECTORS 1
+
+static struct hash_testvec ghash_tv_template[] =
+{
+	{
+
+		.key	= "\xdf\xa6\xbf\x4d\xed\x81\xdb\x03\xff\xca\xff\x95\xf8\x30\xf0\x61",
+		.ksize	= 16,
+		.plaintext = "\x95\x2b\x2a\x56\xa5\x60\x04a\xc0\xb3\x2b\x66\x56\xa0\x5b\x40\xb6",
+		.psize	= 16,
+		.digest	= "\xda\x53\xeb\x0a\xd2\xc5\x5b\xb6"
+			  "\x4f\xc4\x80\x2c\xc3\xfe\xda\x60",
+	},
+};
+
 /*
  * HMAC-MD5 test vectors from RFC2202
  * (These need to be fixed to not use strlen).
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 48bbdbe..26e434a 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -1,5 +1,3 @@
-# drivers/Kconfig
-
 menu "Device Drivers"
 
 source "drivers/base/Kconfig"
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 7702118..c7b10b4 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -19,6 +19,7 @@
 
 # All the builtin files are in the "acpi." module_param namespace.
 acpi-y				+= osl.o utils.o reboot.o
+acpi-y				+= hest.o
 
 # sleep related files
 acpi-y				+= wakeup.o
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index 28ccdbc..3597d73 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -537,7 +537,7 @@
 
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
 				     ACPI_UINT32_MAX,
-				     acpi_memory_register_notify_handler,
+				     acpi_memory_register_notify_handler, NULL,
 				     NULL, NULL);
 
 	if (ACPI_FAILURE(status)) {
@@ -561,7 +561,7 @@
 	 */
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
 				     ACPI_UINT32_MAX,
-				     acpi_memory_deregister_notify_handler,
+				     acpi_memory_deregister_notify_handler, NULL,
 				     NULL, NULL);
 
 	if (ACPI_FAILURE(status))
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
index e7973bc..7423052 100644
--- a/drivers/acpi/acpica/Makefile
+++ b/drivers/acpi/acpica/Makefile
@@ -28,7 +28,7 @@
 acpi-y += nsaccess.o  nsload.o    nssearch.o  nsxfeval.o \
 	 nsalloc.o   nseval.o    nsnames.o   nsutils.o   nsxfname.o \
 	 nsdump.o    nsinit.o    nsobject.o  nswalk.o    nsxfobj.o  \
-	 nsparse.o   nspredef.o  nsrepair.o
+	 nsparse.o   nspredef.o  nsrepair.o  nsrepair2.o
 
 acpi-$(ACPI_FUTURE_USAGE) += nsdumpdv.o
 
diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h
index 3acd9c6..7d9ba6e 100644
--- a/drivers/acpi/acpica/acmacros.h
+++ b/drivers/acpi/acpica/acmacros.h
@@ -341,6 +341,7 @@
 #define ACPI_ERROR_NAMESPACE(s, e)      acpi_ns_report_error (AE_INFO, s, e);
 #define ACPI_ERROR_METHOD(s, n, p, e)   acpi_ns_report_method_error (AE_INFO, s, n, p, e);
 #define ACPI_WARN_PREDEFINED(plist)     acpi_ut_predefined_warning plist
+#define ACPI_INFO_PREDEFINED(plist)     acpi_ut_predefined_info plist
 
 #else
 
@@ -349,6 +350,8 @@
 #define ACPI_ERROR_NAMESPACE(s, e)
 #define ACPI_ERROR_METHOD(s, n, p, e)
 #define ACPI_WARN_PREDEFINED(plist)
+#define ACPI_INFO_PREDEFINED(plist)
+
 #endif		/* ACPI_NO_ERROR_MESSAGES */
 
 /*
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h
index 09a2764..ab83919 100644
--- a/drivers/acpi/acpica/acnamesp.h
+++ b/drivers/acpi/acpica/acnamesp.h
@@ -104,7 +104,8 @@
 		       acpi_handle start_object,
 		       u32 max_depth,
 		       u32 flags,
-		       acpi_walk_callback user_function,
+		       acpi_walk_callback pre_order_visit,
+		       acpi_walk_callback post_order_visit,
 		       void *context, void **return_value);
 
 struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node
@@ -272,7 +273,8 @@
 			  acpi_object_handler handler, void **data);
 
 /*
- * nsrepair - return object repair for predefined methods/objects
+ * nsrepair - General return object repair for all
+ * predefined methods/objects
  */
 acpi_status
 acpi_ns_repair_object(struct acpi_predefined_data *data,
@@ -285,6 +287,16 @@
 			    union acpi_operand_object **obj_desc_ptr);
 
 /*
+ * nsrepair2 - Return object repair for specific
+ * predefined methods/objects
+ */
+acpi_status
+acpi_ns_complex_repairs(struct acpi_predefined_data *data,
+			struct acpi_namespace_node *node,
+			acpi_status validate_status,
+			union acpi_operand_object **return_object_ptr);
+
+/*
  * nssearch - Namespace searching and entry
  */
 acpi_status
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h
index 863a264..3a451a2 100644
--- a/drivers/acpi/acpica/acutils.h
+++ b/drivers/acpi/acpica/acutils.h
@@ -386,6 +386,8 @@
 
 union acpi_operand_object *acpi_ut_create_package_object(u32 count);
 
+union acpi_operand_object *acpi_ut_create_integer_object(u64 value);
+
 union acpi_operand_object *acpi_ut_create_buffer_object(acpi_size buffer_size);
 
 union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size);
@@ -481,6 +483,11 @@
 			   char *pathname,
 			   u8 node_flags, const char *format, ...);
 
+void ACPI_INTERNAL_VAR_XFACE
+acpi_ut_predefined_info(const char *module_name,
+			u32 line_number,
+			char *pathname, u8 node_flags, const char *format, ...);
+
 /* Values for Base above (16=Hex, 10=Decimal) */
 
 #define ACPI_ANY_BASE        0
diff --git a/drivers/acpi/acpica/dsinit.c b/drivers/acpi/acpica/dsinit.c
index 3aae13f..f23fa0b 100644
--- a/drivers/acpi/acpica/dsinit.c
+++ b/drivers/acpi/acpica/dsinit.c
@@ -192,7 +192,7 @@
 	status =
 	    acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
 				   ACPI_NS_WALK_UNLOCK, acpi_ds_init_one_object,
-				   &info, NULL);
+				   NULL, &info, NULL);
 	if (ACPI_FAILURE(status)) {
 		ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
 	}
diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c
index 7d077bb..0ba19f8 100644
--- a/drivers/acpi/acpica/dsmthdat.c
+++ b/drivers/acpi/acpica/dsmthdat.c
@@ -409,13 +409,11 @@
 		/* If slack enabled, init the local_x/arg_x to an Integer of value zero */
 
 		if (acpi_gbl_enable_interpreter_slack) {
-			object =
-			    acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+			object = acpi_ut_create_integer_object((u64) 0);
 			if (!object) {
 				return_ACPI_STATUS(AE_NO_MEMORY);
 			}
 
-			object->integer.value = 0;
 			node->object = object;
 		}
 
diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c
index 507e1f0..9bc1ba0 100644
--- a/drivers/acpi/acpica/dsobject.c
+++ b/drivers/acpi/acpica/dsobject.c
@@ -486,7 +486,7 @@
 		 *
 		 * Note: technically, this is an error, from ACPI spec: "It is an error
 		 * for NumElements to be less than the number of elements in the
-		 * PackageList". However, we just print an error message and
+		 * PackageList". However, we just print a message and
 		 * no exception is returned. This provides Windows compatibility. Some
 		 * BIOSs will alter the num_elements on the fly, creating this type
 		 * of ill-formed package object.
@@ -510,9 +510,9 @@
 			arg = arg->common.next;
 		}
 
-		ACPI_WARNING((AE_INFO,
-			    "Package List length (0x%X) larger than NumElements count (0x%X), truncated\n",
-			    i, element_count));
+		ACPI_INFO((AE_INFO,
+			   "Actual Package length (0x%X) is larger than NumElements field (0x%X), truncated\n",
+			   i, element_count));
 	} else if (i < element_count) {
 		/*
 		 * Arg list (elements) was exhausted, but we did not reach num_elements count.
diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c
index 6de3a99..10fc785 100644
--- a/drivers/acpi/acpica/dswload.c
+++ b/drivers/acpi/acpica/dswload.c
@@ -639,26 +639,42 @@
 		break;
 
 	case AML_SCOPE_OP:
-		/*
-		 * The Path is an object reference to an existing object.
-		 * Don't enter the name into the namespace, but look it up
-		 * for use later.
-		 */
-		status =
-		    acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
-				   object_type, ACPI_IMODE_EXECUTE,
-				   ACPI_NS_SEARCH_PARENT, walk_state, &(node));
-		if (ACPI_FAILURE(status)) {
-#ifdef ACPI_ASL_COMPILER
-			if (status == AE_NOT_FOUND) {
-				status = AE_OK;
-			} else {
-				ACPI_ERROR_NAMESPACE(buffer_ptr, status);
+
+		/* Special case for Scope(\) -> refers to the Root node */
+
+		if (op && (op->named.node == acpi_gbl_root_node)) {
+			node = op->named.node;
+
+			status =
+			    acpi_ds_scope_stack_push(node, object_type,
+						     walk_state);
+			if (ACPI_FAILURE(status)) {
+				return_ACPI_STATUS(status);
 			}
+		} else {
+			/*
+			 * The Path is an object reference to an existing object.
+			 * Don't enter the name into the namespace, but look it up
+			 * for use later.
+			 */
+			status =
+			    acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
+					   object_type, ACPI_IMODE_EXECUTE,
+					   ACPI_NS_SEARCH_PARENT, walk_state,
+					   &(node));
+			if (ACPI_FAILURE(status)) {
+#ifdef ACPI_ASL_COMPILER
+				if (status == AE_NOT_FOUND) {
+					status = AE_OK;
+				} else {
+					ACPI_ERROR_NAMESPACE(buffer_ptr,
+							     status);
+				}
 #else
-			ACPI_ERROR_NAMESPACE(buffer_ptr, status);
+				ACPI_ERROR_NAMESPACE(buffer_ptr, status);
 #endif
-			return_ACPI_STATUS(status);
+				return_ACPI_STATUS(status);
+			}
 		}
 
 		/*
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c
index a60aaa7..2479209 100644
--- a/drivers/acpi/acpica/evgpeblk.c
+++ b/drivers/acpi/acpica/evgpeblk.c
@@ -945,8 +945,8 @@
 
 	status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device,
 					ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
-					acpi_ev_save_method_info, gpe_block,
-					NULL);
+					acpi_ev_save_method_info, NULL,
+					gpe_block, NULL);
 
 	/* Return the new block */
 
@@ -1022,8 +1022,8 @@
 		status =
 		    acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
 					   ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
-					   acpi_ev_match_prw_and_gpe, &gpe_info,
-					   NULL);
+					   acpi_ev_match_prw_and_gpe, NULL,
+					   &gpe_info, NULL);
 	}
 
 	/*
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c
index 98c7f9c..0bc807c 100644
--- a/drivers/acpi/acpica/evregion.c
+++ b/drivers/acpi/acpica/evregion.c
@@ -51,6 +51,10 @@
 ACPI_MODULE_NAME("evregion")
 
 /* Local prototypes */
+static u8
+acpi_ev_has_default_handler(struct acpi_namespace_node *node,
+			    acpi_adr_space_type space_id);
+
 static acpi_status
 acpi_ev_reg_run(acpi_handle obj_handle,
 		u32 level, void *context, void **return_value);
@@ -142,6 +146,50 @@
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_ev_has_default_handler
+ *
+ * PARAMETERS:  Node                - Namespace node for the device
+ *              space_id            - The address space ID
+ *
+ * RETURN:      TRUE if default handler is installed, FALSE otherwise
+ *
+ * DESCRIPTION: Check if the default handler is installed for the requested
+ *              space ID.
+ *
+ ******************************************************************************/
+
+static u8
+acpi_ev_has_default_handler(struct acpi_namespace_node *node,
+			    acpi_adr_space_type space_id)
+{
+	union acpi_operand_object *obj_desc;
+	union acpi_operand_object *handler_obj;
+
+	/* Must have an existing internal object */
+
+	obj_desc = acpi_ns_get_attached_object(node);
+	if (obj_desc) {
+		handler_obj = obj_desc->device.handler;
+
+		/* Walk the linked list of handlers for this object */
+
+		while (handler_obj) {
+			if (handler_obj->address_space.space_id == space_id) {
+				if (handler_obj->address_space.handler_flags &
+				    ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
+					return (TRUE);
+				}
+			}
+
+			handler_obj = handler_obj->address_space.next;
+		}
+	}
+
+	return (FALSE);
+}
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_ev_initialize_op_regions
  *
  * PARAMETERS:  None
@@ -169,12 +217,18 @@
 
 	for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
 		/*
-		 * TBD: Make sure handler is the DEFAULT handler, otherwise
-		 * _REG will have already been run.
+		 * Make sure the installed handler is the DEFAULT handler. If not the
+		 * default, the _REG methods will have already been run (when the
+		 * handler was installed)
 		 */
-		status = acpi_ev_execute_reg_methods(acpi_gbl_root_node,
-						     acpi_gbl_default_address_spaces
-						     [i]);
+		if (acpi_ev_has_default_handler(acpi_gbl_root_node,
+						acpi_gbl_default_address_spaces
+						[i])) {
+			status =
+			    acpi_ev_execute_reg_methods(acpi_gbl_root_node,
+							acpi_gbl_default_address_spaces
+							[i]);
+		}
 	}
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
@@ -235,23 +289,20 @@
 	 *  connection status 1 for connecting the handler, 0 for disconnecting
 	 *  the handler (Passed as a parameter)
 	 */
-	args[0] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+	args[0] =
+	    acpi_ut_create_integer_object((u64) region_obj->region.space_id);
 	if (!args[0]) {
 		status = AE_NO_MEMORY;
 		goto cleanup1;
 	}
 
-	args[1] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+	args[1] = acpi_ut_create_integer_object((u64) function);
 	if (!args[1]) {
 		status = AE_NO_MEMORY;
 		goto cleanup2;
 	}
 
-	/* Setup the parameter objects */
-
-	args[0]->integer.value = region_obj->region.space_id;
-	args[1]->integer.value = function;
-	args[2] = NULL;
+	args[2] = NULL;		/* Terminate list */
 
 	/* Execute the method, no return value */
 
@@ -971,8 +1022,8 @@
 	 */
 	status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
 					ACPI_NS_WALK_UNLOCK,
-					acpi_ev_install_handler, handler_obj,
-					NULL);
+					acpi_ev_install_handler, NULL,
+					handler_obj, NULL);
 
       unlock_and_exit:
 	return_ACPI_STATUS(status);
@@ -1008,7 +1059,7 @@
 	 */
 	status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
 					ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
-					&space_id, NULL);
+					NULL, &space_id, NULL);
 
 	return_ACPI_STATUS(status);
 }
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c
index 24afef8..46adfa5 100644
--- a/drivers/acpi/acpica/exconfig.c
+++ b/drivers/acpi/acpica/exconfig.c
@@ -170,14 +170,12 @@
 
 		/* Table not found, return an Integer=0 and AE_OK */
 
-		ddb_handle = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+		ddb_handle = acpi_ut_create_integer_object((u64) 0);
 		if (!ddb_handle) {
 			return_ACPI_STATUS(AE_NO_MEMORY);
 		}
 
-		ddb_handle->integer.value = 0;
 		*return_desc = ddb_handle;
-
 		return_ACPI_STATUS(AE_OK);
 	}
 
diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c
index 37d0d39..51d5f22 100644
--- a/drivers/acpi/acpica/exconvrt.c
+++ b/drivers/acpi/acpica/exconvrt.c
@@ -167,7 +167,7 @@
 
 	/* Create a new integer */
 
-	return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+	return_desc = acpi_ut_create_integer_object(result);
 	if (!return_desc) {
 		return_ACPI_STATUS(AE_NO_MEMORY);
 	}
@@ -177,7 +177,6 @@
 
 	/* Save the Result */
 
-	return_desc->integer.value = result;
 	acpi_ex_truncate_for32bit_table(return_desc);
 	*result_desc = return_desc;
 	return_ACPI_STATUS(AE_OK);
diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c
index 0b33d6c..1588a2d 100644
--- a/drivers/acpi/acpica/exfield.c
+++ b/drivers/acpi/acpica/exfield.c
@@ -162,13 +162,12 @@
 	} else {
 		/* Field will fit within an Integer (normal case) */
 
-		buffer_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+		buffer_desc = acpi_ut_create_integer_object((u64) 0);
 		if (!buffer_desc) {
 			return_ACPI_STATUS(AE_NO_MEMORY);
 		}
 
 		length = acpi_gbl_integer_byte_width;
-		buffer_desc->integer.value = 0;
 		buffer = &buffer_desc->integer.value;
 	}
 
diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c
index 9635d21..752fe48 100644
--- a/drivers/acpi/acpica/exoparg1.c
+++ b/drivers/acpi/acpica/exoparg1.c
@@ -100,12 +100,12 @@
 
 		/* Create a return object of type Integer */
 
-		return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+		return_desc =
+		    acpi_ut_create_integer_object(acpi_os_get_timer());
 		if (!return_desc) {
 			status = AE_NO_MEMORY;
 			goto cleanup;
 		}
-		return_desc->integer.value = acpi_os_get_timer();
 		break;
 
 	default:		/*  Unknown opcode  */
@@ -599,7 +599,7 @@
 	switch (walk_state->opcode) {
 	case AML_LNOT_OP:	/* LNot (Operand) */
 
-		return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+		return_desc = acpi_ut_create_integer_object((u64) 0);
 		if (!return_desc) {
 			status = AE_NO_MEMORY;
 			goto cleanup;
@@ -702,13 +702,11 @@
 
 		/* Allocate a descriptor to hold the type. */
 
-		return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+		return_desc = acpi_ut_create_integer_object((u64) type);
 		if (!return_desc) {
 			status = AE_NO_MEMORY;
 			goto cleanup;
 		}
-
-		return_desc->integer.value = type;
 		break;
 
 	case AML_SIZE_OF_OP:	/* size_of (source_object) */
@@ -777,13 +775,11 @@
 		 * Now that we have the size of the object, create a result
 		 * object to hold the value
 		 */
-		return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+		return_desc = acpi_ut_create_integer_object(value);
 		if (!return_desc) {
 			status = AE_NO_MEMORY;
 			goto cleanup;
 		}
-
-		return_desc->integer.value = value;
 		break;
 
 	case AML_REF_OF_OP:	/* ref_of (source_object) */
@@ -946,24 +942,24 @@
 					 * NOTE: index into a buffer is NOT a pointer to a
 					 * sub-buffer of the main buffer, it is only a pointer to a
 					 * single element (byte) of the buffer!
-					 */
-					return_desc =
-					    acpi_ut_create_internal_object
-					    (ACPI_TYPE_INTEGER);
-					if (!return_desc) {
-						status = AE_NO_MEMORY;
-						goto cleanup;
-					}
-
-					/*
+					 *
 					 * Since we are returning the value of the buffer at the
 					 * indexed location, we don't need to add an additional
 					 * reference to the buffer itself.
 					 */
-					return_desc->integer.value =
-					    temp_desc->buffer.
-					    pointer[operand[0]->reference.
-						    value];
+					return_desc =
+					    acpi_ut_create_integer_object((u64)
+									  temp_desc->
+									  buffer.
+									  pointer
+									  [operand
+									   [0]->
+									   reference.
+									   value]);
+					if (!return_desc) {
+						status = AE_NO_MEMORY;
+						goto cleanup;
+					}
 					break;
 
 				case ACPI_TYPE_PACKAGE:
diff --git a/drivers/acpi/acpica/exoparg6.c b/drivers/acpi/acpica/exoparg6.c
index ae43f76..295542e 100644
--- a/drivers/acpi/acpica/exoparg6.c
+++ b/drivers/acpi/acpica/exoparg6.c
@@ -253,18 +253,15 @@
 		}
 
 		/* Create an integer for the return value */
+		/* Default return value is ACPI_INTEGER_MAX if no match found */
 
-		return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+		return_desc = acpi_ut_create_integer_object(ACPI_INTEGER_MAX);
 		if (!return_desc) {
 			status = AE_NO_MEMORY;
 			goto cleanup;
 
 		}
 
-		/* Default return value if no match found */
-
-		return_desc->integer.value = ACPI_INTEGER_MAX;
-
 		/*
 		 * Examine each element until a match is found. Both match conditions
 		 * must be satisfied for a match to occur. Within the loop,
diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c
index 2bad613..2deb986 100644
--- a/drivers/acpi/acpica/nsdump.c
+++ b/drivers/acpi/acpica/nsdump.c
@@ -634,8 +634,8 @@
 	(void)acpi_ns_walk_namespace(type, start_handle, max_depth,
 				     ACPI_NS_WALK_NO_UNLOCK |
 				     ACPI_NS_WALK_TEMP_NODES,
-				     acpi_ns_dump_one_object, (void *)&info,
-				     NULL);
+				     acpi_ns_dump_one_object, NULL,
+				     (void *)&info, NULL);
 }
 #endif				/* ACPI_FUTURE_USAGE */
 
diff --git a/drivers/acpi/acpica/nsdumpdv.c b/drivers/acpi/acpica/nsdumpdv.c
index 0fe87f1..36be7f0 100644
--- a/drivers/acpi/acpica/nsdumpdv.c
+++ b/drivers/acpi/acpica/nsdumpdv.c
@@ -131,7 +131,8 @@
 
 	status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, sys_bus_handle,
 					ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
-					acpi_ns_dump_one_device, NULL, NULL);
+					acpi_ns_dump_one_device, NULL, NULL,
+					NULL);
 }
 
 #endif
diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c
index 846d113..f771e97 100644
--- a/drivers/acpi/acpica/nseval.c
+++ b/drivers/acpi/acpica/nseval.c
@@ -366,33 +366,49 @@
 acpi_ns_exec_module_code(union acpi_operand_object *method_obj,
 			 struct acpi_evaluate_info *info)
 {
-	union acpi_operand_object *root_obj;
+	union acpi_operand_object *parent_obj;
+	struct acpi_namespace_node *parent_node;
+	acpi_object_type type;
 	acpi_status status;
 
 	ACPI_FUNCTION_TRACE(ns_exec_module_code);
 
+	/*
+	 * Get the parent node. We cheat by using the next_object field
+	 * of the method object descriptor.
+	 */
+	parent_node = ACPI_CAST_PTR(struct acpi_namespace_node,
+				    method_obj->method.next_object);
+	type = acpi_ns_get_type(parent_node);
+
+	/* Must clear next_object (acpi_ns_attach_object needs the field) */
+
+	method_obj->method.next_object = NULL;
+
 	/* Initialize the evaluation information block */
 
 	ACPI_MEMSET(info, 0, sizeof(struct acpi_evaluate_info));
-	info->prefix_node = acpi_gbl_root_node;
+	info->prefix_node = parent_node;
 
 	/*
-	 * Get the currently attached root object. Add a reference, because the
+	 * Get the currently attached parent object. Add a reference, because the
 	 * ref count will be decreased when the method object is installed to
-	 * the root node.
+	 * the parent node.
 	 */
-	root_obj = acpi_ns_get_attached_object(acpi_gbl_root_node);
-	acpi_ut_add_reference(root_obj);
+	parent_obj = acpi_ns_get_attached_object(parent_node);
+	if (parent_obj) {
+		acpi_ut_add_reference(parent_obj);
+	}
 
-	/* Install the method (module-level code) in the root node */
+	/* Install the method (module-level code) in the parent node */
 
-	status = acpi_ns_attach_object(acpi_gbl_root_node, method_obj,
+	status = acpi_ns_attach_object(parent_node, method_obj,
 				       ACPI_TYPE_METHOD);
 	if (ACPI_FAILURE(status)) {
 		goto exit;
 	}
 
-	/* Execute the root node as a control method */
+	/* Execute the parent node as a control method */
 
 	status = acpi_ns_evaluate(info);
 
@@ -401,15 +417,19 @@
 
 	/* Detach the temporary method object */
 
-	acpi_ns_detach_object(acpi_gbl_root_node);
+	acpi_ns_detach_object(parent_node);
 
-	/* Restore the original root object */
+	/* Restore the original parent object */
 
-	status =
-	    acpi_ns_attach_object(acpi_gbl_root_node, root_obj,
-				  ACPI_TYPE_DEVICE);
+	if (parent_obj) {
+		status = acpi_ns_attach_object(parent_node, parent_obj, type);
+	} else {
+		parent_node->type = (u8)type;
+	}
 
       exit:
-	acpi_ut_remove_reference(root_obj);
+	if (parent_obj) {
+		acpi_ut_remove_reference(parent_obj);
+	}
 	return_VOID;
 }
diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c
index 1d5b360..4f8abac 100644
--- a/drivers/acpi/acpica/nsinit.c
+++ b/drivers/acpi/acpica/nsinit.c
@@ -96,7 +96,7 @@
 	/* Walk entire namespace from the supplied root */
 
 	status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
-				     ACPI_UINT32_MAX, acpi_ns_init_one_object,
+				     ACPI_UINT32_MAX, acpi_ns_init_one_object, NULL,
 				     &info, NULL);
 	if (ACPI_FAILURE(status)) {
 		ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
@@ -156,7 +156,8 @@
 
 	status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
 					ACPI_UINT32_MAX, FALSE,
-					acpi_ns_find_ini_methods, &info, NULL);
+					acpi_ns_find_ini_methods, NULL, &info,
+					NULL);
 	if (ACPI_FAILURE(status)) {
 		goto error_exit;
 	}
@@ -189,7 +190,8 @@
 
 	status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
 					ACPI_UINT32_MAX, FALSE,
-					acpi_ns_init_one_device, &info, NULL);
+					acpi_ns_init_one_device, NULL, &info,
+					NULL);
 
 	ACPI_FREE(info.evaluate_info);
 	if (ACPI_FAILURE(status)) {
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c
index f8427af..b05f429 100644
--- a/drivers/acpi/acpica/nspredef.c
+++ b/drivers/acpi/acpica/nspredef.c
@@ -232,6 +232,12 @@
 		status = acpi_ns_check_package(data, return_object_ptr);
 	}
 
+	/*
+	 * Perform additional, more complicated repairs on a per-name
+	 * basis.
+	 */
+	status = acpi_ns_complex_repairs(data, node, status, return_object_ptr);
+
 check_validation_status:
 	/*
 	 * If the object validation failed or if we successfully repaired one
@@ -601,7 +607,8 @@
 		 * there is only one entry). We may be able to repair this by
 		 * wrapping the returned Package with a new outer Package.
 		 */
-		if ((*elements)->common.type != ACPI_TYPE_PACKAGE) {
+		if (*elements
+		    && ((*elements)->common.type != ACPI_TYPE_PACKAGE)) {
 
 			/* Create the new outer package and populate it */
 
@@ -673,6 +680,7 @@
 	union acpi_operand_object *sub_package;
 	union acpi_operand_object **sub_elements;
 	acpi_status status;
+	u8 non_trailing_null = FALSE;
 	u32 expected_count;
 	u32 i;
 	u32 j;
@@ -680,6 +688,45 @@
 	/* Validate each sub-Package in the parent Package */
 
 	for (i = 0; i < count; i++) {
+		/*
+		 * Handling for NULL package elements. For now, we will simply allow
+		 * a parent package with trailing NULL elements. This can happen if
+		 * the package was defined to be longer than the initializer list.
+		 * This is legal as per the ACPI specification. It is often used
+		 * to allow for dynamic initialization of a Package.
+		 *
+		 * A future enhancement may be to simply truncate the package to
+		 * remove the trailing NULL elements.
+		 */
+		if (!(*elements)) {
+			if (!non_trailing_null) {
+
+				/* Ensure the remaining elements are all NULL */
+
+				for (j = 1; j < (count - i + 1); j++) {
+					if (elements[j]) {
+						non_trailing_null = TRUE;
+					}
+				}
+
+				if (!non_trailing_null) {
+
+					/* Ignore the trailing NULL elements */
+
+					return (AE_OK);
+				}
+			}
+
+			/* There are trailing non-null elements, issue warning */
+
+			ACPI_WARN_PREDEFINED((AE_INFO, data->pathname,
+					      data->node_flags,
+					      "Found NULL element at package index %u",
+					      i));
+			elements++;
+			continue;
+		}
+
 		sub_package = *elements;
 		sub_elements = sub_package->package.elements;
 
diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c
index db2b2a9..d563f1a 100644
--- a/drivers/acpi/acpica/nsrepair.c
+++ b/drivers/acpi/acpica/nsrepair.c
@@ -44,6 +44,7 @@
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "acnamesp.h"
+#include "acinterp.h"
 #include "acpredef.h"
 
 #define _COMPONENT          ACPI_NAMESPACE
@@ -76,7 +77,13 @@
 	union acpi_operand_object *return_object = *return_object_ptr;
 	union acpi_operand_object *new_object;
 	acpi_size length;
+	acpi_status status;
 
+	/*
+	 * At this point, we know that the type of the returned object was not
+	 * one of the expected types for this predefined name. Attempt to
+	 * repair the object. Only a limited number of repairs are possible.
+	 */
 	switch (return_object->common.type) {
 	case ACPI_TYPE_BUFFER:
 
@@ -111,43 +118,94 @@
 		 */
 		ACPI_MEMCPY(new_object->string.pointer,
 			    return_object->buffer.pointer, length);
+		break;
 
-		/*
-		 * If the original object is a package element, we need to:
-		 * 1. Set the reference count of the new object to match the
-		 *    reference count of the old object.
-		 * 2. Decrement the reference count of the original object.
-		 */
-		if (package_index != ACPI_NOT_PACKAGE_ELEMENT) {
-			new_object->common.reference_count =
-			    return_object->common.reference_count;
+	case ACPI_TYPE_INTEGER:
 
-			if (return_object->common.reference_count > 1) {
-				return_object->common.reference_count--;
+		/* 1) Does the method/object legally return a buffer? */
+
+		if (expected_btypes & ACPI_RTYPE_BUFFER) {
+			/*
+			 * Convert the Integer to a packed-byte buffer. _MAT needs
+			 * this sometimes, if a read has been performed on a Field
+			 * object that is less than or equal to the global integer
+			 * size (32 or 64 bits).
+			 */
+			status =
+			    acpi_ex_convert_to_buffer(return_object,
+						      &new_object);
+			if (ACPI_FAILURE(status)) {
+				return (status);
 			}
-
-			ACPI_WARN_PREDEFINED((AE_INFO, data->pathname,
-					      data->node_flags,
-					      "Converted Buffer to expected String at index %u",
-					      package_index));
-		} else {
-			ACPI_WARN_PREDEFINED((AE_INFO, data->pathname,
-					      data->node_flags,
-					      "Converted Buffer to expected String"));
 		}
 
-		/* Delete old object, install the new return object */
+		/* 2) Does the method/object legally return a string? */
 
-		acpi_ut_remove_reference(return_object);
-		*return_object_ptr = new_object;
-		data->flags |= ACPI_OBJECT_REPAIRED;
-		return (AE_OK);
+		else if (expected_btypes & ACPI_RTYPE_STRING) {
+			/*
+			 * The only supported Integer-to-String conversion is to convert
+			 * an integer of value 0 to a NULL string. The last element of
+			 * _BIF and _BIX packages occasionally need this fix.
+			 */
+			if (return_object->integer.value != 0) {
+				return (AE_AML_OPERAND_TYPE);
+			}
+
+			/* Allocate a new NULL string object */
+
+			new_object = acpi_ut_create_string_object(0);
+			if (!new_object) {
+				return (AE_NO_MEMORY);
+			}
+		} else {
+			return (AE_AML_OPERAND_TYPE);
+		}
+		break;
 
 	default:
-		break;
+
+		/* We cannot repair this object */
+
+		return (AE_AML_OPERAND_TYPE);
 	}
 
-	return (AE_AML_OPERAND_TYPE);
+	/* Object was successfully repaired */
+
+	/*
+	 * If the original object is a package element, we need to:
+	 * 1. Set the reference count of the new object to match the
+	 *    reference count of the old object.
+	 * 2. Decrement the reference count of the original object.
+	 */
+	if (package_index != ACPI_NOT_PACKAGE_ELEMENT) {
+		new_object->common.reference_count =
+		    return_object->common.reference_count;
+
+		if (return_object->common.reference_count > 1) {
+			return_object->common.reference_count--;
+		}
+
+		ACPI_INFO_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+				      "Converted %s to expected %s at index %u",
+				      acpi_ut_get_object_type_name
+				      (return_object),
+				      acpi_ut_get_object_type_name(new_object),
+				      package_index));
+	} else {
+		ACPI_INFO_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+				      "Converted %s to expected %s",
+				      acpi_ut_get_object_type_name
+				      (return_object),
+				      acpi_ut_get_object_type_name
+				      (new_object)));
+	}
+
+	/* Delete old object, install the new return object */
+
+	acpi_ut_remove_reference(return_object);
+	*return_object_ptr = new_object;
+	data->flags |= ACPI_OBJECT_REPAIRED;
+	return (AE_OK);
 }
 
 /*******************************************************************************
@@ -196,8 +254,8 @@
 	*obj_desc_ptr = pkg_obj_desc;
 	data->flags |= ACPI_OBJECT_REPAIRED;
 
-	ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
-			      "Incorrectly formed Package, attempting repair"));
+	ACPI_INFO_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+			      "Repaired Incorrectly formed Package"));
 
 	return (AE_OK);
 }
diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c
new file mode 100644
index 0000000..d07b686
--- /dev/null
+++ b/drivers/acpi/acpica/nsrepair2.c
@@ -0,0 +1,540 @@
+/******************************************************************************
+ *
+ * Module Name: nsrepair2 - Repair for objects returned by specific
+ *                          predefined methods
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2009, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acnamesp.h"
+
+#define _COMPONENT          ACPI_NAMESPACE
+ACPI_MODULE_NAME("nsrepair2")
+
+/*
+ * Information structure and handler for ACPI predefined names that can
+ * be repaired on a per-name basis.
+ */
+typedef
+acpi_status(*acpi_repair_function) (struct acpi_predefined_data *data,
+				    union acpi_operand_object **return_object_ptr);
+
+typedef struct acpi_repair_info {
+	char name[ACPI_NAME_SIZE];
+	acpi_repair_function repair_function;
+
+} acpi_repair_info;
+
+/* Local prototypes */
+
+static const struct acpi_repair_info *acpi_ns_match_repairable_name(struct
+								    acpi_namespace_node
+								    *node);
+
+static acpi_status
+acpi_ns_repair_ALR(struct acpi_predefined_data *data,
+		   union acpi_operand_object **return_object_ptr);
+
+static acpi_status
+acpi_ns_repair_PSS(struct acpi_predefined_data *data,
+		   union acpi_operand_object **return_object_ptr);
+
+static acpi_status
+acpi_ns_repair_TSS(struct acpi_predefined_data *data,
+		   union acpi_operand_object **return_object_ptr);
+
+static acpi_status
+acpi_ns_check_sorted_list(struct acpi_predefined_data *data,
+			  union acpi_operand_object *return_object,
+			  u32 expected_count,
+			  u32 sort_index,
+			  u8 sort_direction, char *sort_key_name);
+
+static acpi_status
+acpi_ns_remove_null_elements(union acpi_operand_object *package);
+
+static acpi_status
+acpi_ns_sort_list(union acpi_operand_object **elements,
+		  u32 count, u32 index, u8 sort_direction);
+
+/* Values for sort_direction above */
+
+#define ACPI_SORT_ASCENDING     0
+#define ACPI_SORT_DESCENDING    1
+
+/*
+ * This table contains the names of the predefined methods for which we can
+ * perform more complex repairs.
+ *
+ * _ALR: Sort the list ascending by ambient_illuminance if necessary
+ * _PSS: Sort the list descending by Power if necessary
+ * _TSS: Sort the list descending by Power if necessary
+ */
+static const struct acpi_repair_info acpi_ns_repairable_names[] = {
+	{"_ALR", acpi_ns_repair_ALR},
+	{"_PSS", acpi_ns_repair_PSS},
+	{"_TSS", acpi_ns_repair_TSS},
+	{{0, 0, 0, 0}, NULL}	/* Table terminator */
+};
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_complex_repairs
+ *
+ * PARAMETERS:  Data                - Pointer to validation data structure
+ *              Node                - Namespace node for the method/object
+ *              validate_status     - Original status of earlier validation
+ *              return_object_ptr   - Pointer to the object returned from the
+ *                                    evaluation of a method or object
+ *
+ * RETURN:      Status. AE_OK if repair was successful. If name is not
+ *              matched, validate_status is returned.
+ *
+ * DESCRIPTION: Attempt to repair/convert a return object of a type that was
+ *              not expected.
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_ns_complex_repairs(struct acpi_predefined_data *data,
+			struct acpi_namespace_node *node,
+			acpi_status validate_status,
+			union acpi_operand_object **return_object_ptr)
+{
+	const struct acpi_repair_info *predefined;
+	acpi_status status;
+
+	/* Check if this name is in the list of repairable names */
+
+	predefined = acpi_ns_match_repairable_name(node);
+	if (!predefined) {
+		return (validate_status);
+	}
+
+	status = predefined->repair_function(data, return_object_ptr);
+	return (status);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_match_repairable_name
+ *
+ * PARAMETERS:  Node                - Namespace node for the method/object
+ *
+ * RETURN:      Pointer to entry in repair table. NULL indicates not found.
+ *
+ * DESCRIPTION: Check an object name against the repairable object list.
+ *
+ *****************************************************************************/
+
+static const struct acpi_repair_info *acpi_ns_match_repairable_name(struct
+								    acpi_namespace_node
+								    *node)
+{
+	const struct acpi_repair_info *this_name;
+
+	/* Search info table for a repairable predefined method/object name */
+
+	this_name = acpi_ns_repairable_names;
+	while (this_name->repair_function) {
+		if (ACPI_COMPARE_NAME(node->name.ascii, this_name->name)) {
+			return (this_name);
+		}
+		this_name++;
+	}
+
+	return (NULL);		/* Not found */
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_repair_ALR
+ *
+ * PARAMETERS:  Data                - Pointer to validation data structure
+ *              return_object_ptr   - Pointer to the object returned from the
+ *                                    evaluation of a method or object
+ *
+ * RETURN:      Status. AE_OK if object is OK or was repaired successfully
+ *
+ * DESCRIPTION: Repair for the _ALR object. If necessary, sort the object list
+ *              ascending by the ambient illuminance values.
+ *
+ *****************************************************************************/
+
+static acpi_status
+acpi_ns_repair_ALR(struct acpi_predefined_data *data,
+		   union acpi_operand_object **return_object_ptr)
+{
+	union acpi_operand_object *return_object = *return_object_ptr;
+	acpi_status status;
+
+	status = acpi_ns_check_sorted_list(data, return_object, 2, 1,
+					   ACPI_SORT_ASCENDING,
+					   "AmbientIlluminance");
+
+	return (status);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_repair_TSS
+ *
+ * PARAMETERS:  Data                - Pointer to validation data structure
+ *              return_object_ptr   - Pointer to the object returned from the
+ *                                    evaluation of a method or object
+ *
+ * RETURN:      Status. AE_OK if object is OK or was repaired successfully
+ *
+ * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list
+ *              descending by the power dissipation values.
+ *
+ *****************************************************************************/
+
+static acpi_status
+acpi_ns_repair_TSS(struct acpi_predefined_data *data,
+		   union acpi_operand_object **return_object_ptr)
+{
+	union acpi_operand_object *return_object = *return_object_ptr;
+	acpi_status status;
+
+	status = acpi_ns_check_sorted_list(data, return_object, 5, 1,
+					   ACPI_SORT_DESCENDING,
+					   "PowerDissipation");
+
+	return (status);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_repair_PSS
+ *
+ * PARAMETERS:  Data                - Pointer to validation data structure
+ *              return_object_ptr   - Pointer to the object returned from the
+ *                                    evaluation of a method or object
+ *
+ * RETURN:      Status. AE_OK if object is OK or was repaired successfully
+ *
+ * DESCRIPTION: Repair for the _PSS object. If necessary, sort the object list
+ *              by the CPU frequencies. Check that the power dissipation values
+ *              are all proportional to CPU frequency (i.e., sorting by
+ *              frequency should be the same as sorting by power.)
+ *
+ *****************************************************************************/
+
+static acpi_status
+acpi_ns_repair_PSS(struct acpi_predefined_data *data,
+		   union acpi_operand_object **return_object_ptr)
+{
+	union acpi_operand_object *return_object = *return_object_ptr;
+	union acpi_operand_object **outer_elements;
+	u32 outer_element_count;
+	union acpi_operand_object **elements;
+	union acpi_operand_object *obj_desc;
+	u32 previous_value;
+	acpi_status status;
+	u32 i;
+
+	/*
+	 * Entries (sub-packages) in the _PSS Package must be sorted by power
+	 * dissipation, in descending order. If it appears that the list is
+	 * incorrectly sorted, sort it. We sort by cpu_frequency, since this
+	 * should be proportional to the power.
+	 */
+	status = acpi_ns_check_sorted_list(data, return_object, 6, 0,
+					   ACPI_SORT_DESCENDING,
+					   "CpuFrequency");
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	/*
+	 * We now know the list is correctly sorted by CPU frequency. Check if
+	 * the power dissipation values are proportional.
+	 */
+	previous_value = ACPI_UINT32_MAX;
+	outer_elements = return_object->package.elements;
+	outer_element_count = return_object->package.count;
+
+	for (i = 0; i < outer_element_count; i++) {
+		elements = (*outer_elements)->package.elements;
+		obj_desc = elements[1];	/* Index1 = power_dissipation */
+
+		if ((u32) obj_desc->integer.value > previous_value) {
+			ACPI_WARN_PREDEFINED((AE_INFO, data->pathname,
+					      data->node_flags,
+					      "SubPackage[%u,%u] - suspicious power dissipation values",
+					      i - 1, i));
+		}
+
+		previous_value = (u32) obj_desc->integer.value;
+		outer_elements++;
+	}
+
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_check_sorted_list
+ *
+ * PARAMETERS:  Data                - Pointer to validation data structure
+ *              return_object       - Pointer to the top-level returned object
+ *              expected_count      - Minimum length of each sub-package
+ *              sort_index          - Sub-package entry to sort on
+ *              sort_direction      - Ascending or descending
+ *              sort_key_name       - Name of the sort_index field
+ *
+ * RETURN:      Status. AE_OK if the list is valid and is sorted correctly or
+ *              has been repaired by sorting the list.
+ *
+ * DESCRIPTION: Check if the package list is valid and sorted correctly by the
+ *              sort_index. If not, then sort the list.
+ *
+ *****************************************************************************/
+
+static acpi_status
+acpi_ns_check_sorted_list(struct acpi_predefined_data *data,
+			  union acpi_operand_object *return_object,
+			  u32 expected_count,
+			  u32 sort_index,
+			  u8 sort_direction, char *sort_key_name)
+{
+	u32 outer_element_count;
+	union acpi_operand_object **outer_elements;
+	union acpi_operand_object **elements;
+	union acpi_operand_object *obj_desc;
+	u32 i;
+	u32 previous_value;
+	acpi_status status;
+
+	/* The top-level object must be a package */
+
+	if (return_object->common.type != ACPI_TYPE_PACKAGE) {
+		return (AE_AML_OPERAND_TYPE);
+	}
+
+	/*
+	 * Detect any NULL package elements and remove them from the
+	 * package.
+	 *
+	 * TBD: We may want to do this for all predefined names that
+	 * return a variable-length package of packages.
+	 */
+	status = acpi_ns_remove_null_elements(return_object);
+	if (status == AE_NULL_ENTRY) {
+		ACPI_INFO_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+				      "NULL elements removed from package"));
+
+		/* Exit if package is now zero length */
+
+		if (!return_object->package.count) {
+			return (AE_NULL_ENTRY);
+		}
+	}
+
+	outer_elements = return_object->package.elements;
+	outer_element_count = return_object->package.count;
+	if (!outer_element_count) {
+		return (AE_AML_PACKAGE_LIMIT);
+	}
+
+	previous_value = 0;
+	if (sort_direction == ACPI_SORT_DESCENDING) {
+		previous_value = ACPI_UINT32_MAX;
+	}
+
+	/* Examine each subpackage */
+
+	for (i = 0; i < outer_element_count; i++) {
+
+		/* Each element of the top-level package must also be a package */
+
+		if ((*outer_elements)->common.type != ACPI_TYPE_PACKAGE) {
+			return (AE_AML_OPERAND_TYPE);
+		}
+
+		/* Each sub-package must have the minimum length */
+
+		if ((*outer_elements)->package.count < expected_count) {
+			return (AE_AML_PACKAGE_LIMIT);
+		}
+
+		elements = (*outer_elements)->package.elements;
+		obj_desc = elements[sort_index];
+
+		if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
+			return (AE_AML_OPERAND_TYPE);
+		}
+
+		/*
+		 * The list must be sorted in the specified order. If we detect a
+		 * discrepancy, issue a warning and sort the entire list
+		 */
+		if (((sort_direction == ACPI_SORT_ASCENDING) &&
+		     (obj_desc->integer.value < previous_value)) ||
+		    ((sort_direction == ACPI_SORT_DESCENDING) &&
+		     (obj_desc->integer.value > previous_value))) {
+			status =
+			    acpi_ns_sort_list(return_object->package.elements,
+					      outer_element_count, sort_index,
+					      sort_direction);
+			if (ACPI_FAILURE(status)) {
+				return (status);
+			}
+
+			data->flags |= ACPI_OBJECT_REPAIRED;
+
+			ACPI_INFO_PREDEFINED((AE_INFO, data->pathname,
+					      data->node_flags,
+					      "Repaired unsorted list - now sorted by %s",
+					      sort_key_name));
+			return (AE_OK);
+		}
+
+		previous_value = (u32) obj_desc->integer.value;
+		outer_elements++;
+	}
+
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_remove_null_elements
+ *
+ * PARAMETERS:  obj_desc            - A Package object
+ *
+ * RETURN:      Status. AE_NULL_ENTRY means that one or more elements were
+ *              removed.
+ *
+ * DESCRIPTION: Remove all NULL package elements and update the package count.
+ *
+ *****************************************************************************/
+
+static acpi_status
+acpi_ns_remove_null_elements(union acpi_operand_object *obj_desc)
+{
+	union acpi_operand_object **source;
+	union acpi_operand_object **dest;
+	acpi_status status = AE_OK;
+	u32 count;
+	u32 new_count;
+	u32 i;
+
+	count = obj_desc->package.count;
+	new_count = count;
+
+	source = obj_desc->package.elements;
+	dest = source;
+
+	/* Examine all elements of the package object */
+
+	for (i = 0; i < count; i++) {
+		if (!*source) {
+			status = AE_NULL_ENTRY;
+			new_count--;
+		} else {
+			*dest = *source;
+			dest++;
+		}
+		source++;
+	}
+
+	if (status == AE_NULL_ENTRY) {
+
+		/* NULL terminate list and update the package count */
+
+		*dest = NULL;
+		obj_desc->package.count = new_count;
+	}
+
+	return (status);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_sort_list
+ *
+ * PARAMETERS:  Elements            - Package object element list
+ *              Count               - Element count for above
+ *              Index               - Sort by which package element
+ *              sort_direction      - Ascending or Descending sort
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Sort the objects that are in a package element list.
+ *
+ * NOTE: Assumes that all NULL elements have been removed from the package.
+ *
+ *****************************************************************************/
+
+static acpi_status
+acpi_ns_sort_list(union acpi_operand_object **elements,
+		  u32 count, u32 index, u8 sort_direction)
+{
+	union acpi_operand_object *obj_desc1;
+	union acpi_operand_object *obj_desc2;
+	union acpi_operand_object *temp_obj;
+	u32 i;
+	u32 j;
+
+	/* Simple bubble sort */
+
+	for (i = 1; i < count; i++) {
+		for (j = (count - 1); j >= i; j--) {
+			obj_desc1 = elements[j - 1]->package.elements[index];
+			obj_desc2 = elements[j]->package.elements[index];
+
+			if (((sort_direction == ACPI_SORT_ASCENDING) &&
+			     (obj_desc1->integer.value >
+			      obj_desc2->integer.value))
+			    || ((sort_direction == ACPI_SORT_DESCENDING)
+				&& (obj_desc1->integer.value <
+				    obj_desc2->integer.value))) {
+				temp_obj = elements[j - 1];
+				elements[j - 1] = elements[j];
+				elements[j] = temp_obj;
+			}
+		}
+	}
+
+	return (AE_OK);
+}
diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c
index 35539df..d7e6b52 100644
--- a/drivers/acpi/acpica/nswalk.c
+++ b/drivers/acpi/acpica/nswalk.c
@@ -165,24 +165,27 @@
  *              max_depth           - Depth to which search is to reach
  *              Flags               - Whether to unlock the NS before invoking
  *                                    the callback routine
- *              user_function       - Called when an object of "Type" is found
- *              Context             - Passed to user function
- *              return_value        - from the user_function if terminated early.
- *                                    Otherwise, returns NULL.
+ *              pre_order_visit     - Called during tree pre-order visit
+ *                                    when an object of "Type" is found
+ *              post_order_visit    - Called during tree post-order visit
+ *                                    when an object of "Type" is found
+ *              Context             - Passed to user function(s) above
+ *              return_value        - from the user_function if terminated
+ *                                    early. Otherwise, returns NULL.
  * RETURNS:     Status
  *
  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
  *              starting (and ending) at the node specified by start_handle.
- *              The user_function is called whenever a node that matches
- *              the type parameter is found.  If the user function returns
+ *              The callback function is called whenever a node that matches
+ *              the type parameter is found. If the callback function returns
  *              a non-zero value, the search is terminated immediately and
  *              this value is returned to the caller.
  *
  *              The point of this procedure is to provide a generic namespace
  *              walk routine that can be called from multiple places to
- *              provide multiple services;  the User Function can be tailored
- *              to each task, whether it is a print function, a compare
- *              function, etc.
+ *              provide multiple services; the callback function(s) can be
+ *              tailored to each task, whether it is a print function,
+ *              a compare function, etc.
  *
  ******************************************************************************/
 
@@ -191,7 +194,8 @@
 		       acpi_handle start_node,
 		       u32 max_depth,
 		       u32 flags,
-		       acpi_walk_callback user_function,
+		       acpi_walk_callback pre_order_visit,
+		       acpi_walk_callback post_order_visit,
 		       void *context, void **return_value)
 {
 	acpi_status status;
@@ -200,6 +204,7 @@
 	struct acpi_namespace_node *parent_node;
 	acpi_object_type child_type;
 	u32 level;
+	u8 node_previously_visited = FALSE;
 
 	ACPI_FUNCTION_TRACE(ns_walk_namespace);
 
@@ -212,7 +217,7 @@
 	/* Null child means "get first node" */
 
 	parent_node = start_node;
-	child_node = NULL;
+	child_node = acpi_ns_get_next_node(parent_node, NULL);
 	child_type = ACPI_TYPE_ANY;
 	level = 1;
 
@@ -221,102 +226,129 @@
 	 * started. When Level is zero, the loop is done because we have
 	 * bubbled up to (and passed) the original parent handle (start_entry)
 	 */
-	while (level > 0) {
-
-		/* Get the next node in this scope.  Null if not found */
-
+	while (level > 0 && child_node) {
 		status = AE_OK;
+
+		/* Found next child, get the type if we are not searching for ANY */
+
+		if (type != ACPI_TYPE_ANY) {
+			child_type = child_node->type;
+		}
+
+		/*
+		 * Ignore all temporary namespace nodes (created during control
+		 * method execution) unless told otherwise. These temporary nodes
+		 * can cause a race condition because they can be deleted during
+		 * the execution of the user function (if the namespace is
+		 * unlocked before invocation of the user function.) Only the
+		 * debugger namespace dump will examine the temporary nodes.
+		 */
+		if ((child_node->flags & ANOBJ_TEMPORARY) &&
+		    !(flags & ACPI_NS_WALK_TEMP_NODES)) {
+			status = AE_CTRL_DEPTH;
+		}
+
+		/* Type must match requested type */
+
+		else if (child_type == type) {
+			/*
+			 * Found a matching node, invoke the user callback function.
+			 * Unlock the namespace if flag is set.
+			 */
+			if (flags & ACPI_NS_WALK_UNLOCK) {
+				mutex_status =
+				    acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+				if (ACPI_FAILURE(mutex_status)) {
+					return_ACPI_STATUS(mutex_status);
+				}
+			}
+
+			/*
+			 * Invoke the user function, either pre-order or post-order
+			 * or both.
+			 */
+			if (!node_previously_visited) {
+				if (pre_order_visit) {
+					status =
+					    pre_order_visit(child_node, level,
+							    context,
+							    return_value);
+				}
+			} else {
+				if (post_order_visit) {
+					status =
+					    post_order_visit(child_node, level,
+							     context,
+							     return_value);
+				}
+			}
+
+			if (flags & ACPI_NS_WALK_UNLOCK) {
+				mutex_status =
+				    acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+				if (ACPI_FAILURE(mutex_status)) {
+					return_ACPI_STATUS(mutex_status);
+				}
+			}
+
+			switch (status) {
+			case AE_OK:
+			case AE_CTRL_DEPTH:
+
+				/* Just keep going */
+				break;
+
+			case AE_CTRL_TERMINATE:
+
+				/* Exit now, with OK status */
+
+				return_ACPI_STATUS(AE_OK);
+
+			default:
+
+				/* All others are valid exceptions */
+
+				return_ACPI_STATUS(status);
+			}
+		}
+
+		/*
+		 * Depth first search: Attempt to go down another level in the
+		 * namespace if we are allowed to.  Don't go any further if we have
+		 * reached the caller specified maximum depth or if the user
+		 * function has specified that the maximum depth has been reached.
+		 */
+		if (!node_previously_visited &&
+		    (level < max_depth) && (status != AE_CTRL_DEPTH)) {
+			if (child_node->child) {
+
+				/* There is at least one child of this node, visit it */
+
+				level++;
+				parent_node = child_node;
+				child_node =
+				    acpi_ns_get_next_node(parent_node, NULL);
+				continue;
+			}
+		}
+
+		/* No more children, re-visit this node */
+
+		if (!node_previously_visited) {
+			node_previously_visited = TRUE;
+			continue;
+		}
+
+		/* No more children, visit peers */
+
 		child_node = acpi_ns_get_next_node(parent_node, child_node);
 		if (child_node) {
+			node_previously_visited = FALSE;
+		}
 
-			/* Found next child, get the type if we are not searching for ANY */
+		/* No peers, re-visit parent */
 
-			if (type != ACPI_TYPE_ANY) {
-				child_type = child_node->type;
-			}
-
-			/*
-			 * Ignore all temporary namespace nodes (created during control
-			 * method execution) unless told otherwise. These temporary nodes
-			 * can cause a race condition because they can be deleted during
-			 * the execution of the user function (if the namespace is
-			 * unlocked before invocation of the user function.) Only the
-			 * debugger namespace dump will examine the temporary nodes.
-			 */
-			if ((child_node->flags & ANOBJ_TEMPORARY) &&
-			    !(flags & ACPI_NS_WALK_TEMP_NODES)) {
-				status = AE_CTRL_DEPTH;
-			}
-
-			/* Type must match requested type */
-
-			else if (child_type == type) {
-				/*
-				 * Found a matching node, invoke the user callback function.
-				 * Unlock the namespace if flag is set.
-				 */
-				if (flags & ACPI_NS_WALK_UNLOCK) {
-					mutex_status =
-					    acpi_ut_release_mutex
-					    (ACPI_MTX_NAMESPACE);
-					if (ACPI_FAILURE(mutex_status)) {
-						return_ACPI_STATUS
-						    (mutex_status);
-					}
-				}
-
-				status =
-				    user_function(child_node, level, context,
-						  return_value);
-
-				if (flags & ACPI_NS_WALK_UNLOCK) {
-					mutex_status =
-					    acpi_ut_acquire_mutex
-					    (ACPI_MTX_NAMESPACE);
-					if (ACPI_FAILURE(mutex_status)) {
-						return_ACPI_STATUS
-						    (mutex_status);
-					}
-				}
-
-				switch (status) {
-				case AE_OK:
-				case AE_CTRL_DEPTH:
-
-					/* Just keep going */
-					break;
-
-				case AE_CTRL_TERMINATE:
-
-					/* Exit now, with OK status */
-
-					return_ACPI_STATUS(AE_OK);
-
-				default:
-
-					/* All others are valid exceptions */
-
-					return_ACPI_STATUS(status);
-				}
-			}
-
-			/*
-			 * Depth first search: Attempt to go down another level in the
-			 * namespace if we are allowed to.  Don't go any further if we have
-			 * reached the caller specified maximum depth or if the user
-			 * function has specified that the maximum depth has been reached.
-			 */
-			if ((level < max_depth) && (status != AE_CTRL_DEPTH)) {
-				if (child_node->child) {
-
-					/* There is at least one child of this node, visit it */
-
-					level++;
-					parent_node = child_node;
-					child_node = NULL;
-				}
-			}
-		} else {
+		else {
 			/*
 			 * No more children of this node (acpi_ns_get_next_node failed), go
 			 * back upwards in the namespace tree to the node's parent.
@@ -324,6 +356,8 @@
 			level--;
 			child_node = parent_node;
 			parent_node = acpi_ns_get_parent_node(parent_node);
+
+			node_previously_visited = TRUE;
 		}
 	}
 
diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c
index 4929dbd..f2bd1da 100644
--- a/drivers/acpi/acpica/nsxfeval.c
+++ b/drivers/acpi/acpica/nsxfeval.c
@@ -433,8 +433,11 @@
  * PARAMETERS:  Type                - acpi_object_type to search for
  *              start_object        - Handle in namespace where search begins
  *              max_depth           - Depth to which search is to reach
- *              user_function       - Called when an object of "Type" is found
- *              Context             - Passed to user function
+ *              pre_order_visit     - Called during tree pre-order visit
+ *                                    when an object of "Type" is found
+ *              post_order_visit    - Called during tree post-order visit
+ *                                    when an object of "Type" is found
+ *              Context             - Passed to user function(s) above
  *              return_value        - Location where return value of
  *                                    user_function is put if terminated early
  *
@@ -443,16 +446,16 @@
  *
  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
  *              starting (and ending) at the object specified by start_handle.
- *              The user_function is called whenever an object that matches
- *              the type parameter is found.  If the user function returns
+ *              The callback function is called whenever an object that matches
+ *              the type parameter is found. If the callback function returns
  *              a non-zero value, the search is terminated immediately and this
  *              value is returned to the caller.
  *
  *              The point of this procedure is to provide a generic namespace
  *              walk routine that can be called from multiple places to
- *              provide multiple services;  the User Function can be tailored
- *              to each task, whether it is a print function, a compare
- *              function, etc.
+ *              provide multiple services; the callback function(s) can be
+ *              tailored to each task, whether it is a print function,
+ *              a compare function, etc.
  *
  ******************************************************************************/
 
@@ -460,7 +463,8 @@
 acpi_walk_namespace(acpi_object_type type,
 		    acpi_handle start_object,
 		    u32 max_depth,
-		    acpi_walk_callback user_function,
+		    acpi_walk_callback pre_order_visit,
+		    acpi_walk_callback post_order_visit,
 		    void *context, void **return_value)
 {
 	acpi_status status;
@@ -469,7 +473,8 @@
 
 	/* Parameter validation */
 
-	if ((type > ACPI_TYPE_LOCAL_MAX) || (!max_depth) || (!user_function)) {
+	if ((type > ACPI_TYPE_LOCAL_MAX) ||
+	    (!max_depth) || (!pre_order_visit && !post_order_visit)) {
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
@@ -501,8 +506,9 @@
 	}
 
 	status = acpi_ns_walk_namespace(type, start_object, max_depth,
-					ACPI_NS_WALK_UNLOCK, user_function,
-					context, return_value);
+					ACPI_NS_WALK_UNLOCK, pre_order_visit,
+					post_order_visit, context,
+					return_value);
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 
@@ -681,8 +687,8 @@
 
 	status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
 					ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
-					acpi_ns_get_device_callback, &info,
-					return_value);
+					acpi_ns_get_device_callback, NULL,
+					&info, return_value);
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 	return_ACPI_STATUS(status);
diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c
index cd7995b..0988e4a 100644
--- a/drivers/acpi/acpica/psloop.c
+++ b/drivers/acpi/acpica/psloop.c
@@ -87,7 +87,8 @@
 			  union acpi_parse_object *op, acpi_status status);
 
 static void
-acpi_ps_link_module_code(u8 *aml_start, u32 aml_length, acpi_owner_id owner_id);
+acpi_ps_link_module_code(union acpi_parse_object *parent_op,
+			 u8 *aml_start, u32 aml_length, acpi_owner_id owner_id);
 
 /*******************************************************************************
  *
@@ -479,11 +480,14 @@
 				 */
 				if (walk_state->pass_number ==
 				    ACPI_IMODE_LOAD_PASS1) {
-					acpi_ps_link_module_code(aml_op_start,
-								 walk_state->
+					acpi_ps_link_module_code(op->common.
+								 parent,
+								 aml_op_start,
+								 (u32)
+								 (walk_state->
 								 parser_state.
 								 pkg_end -
-								 aml_op_start,
+								 aml_op_start),
 								 walk_state->
 								 owner_id);
 				}
@@ -598,7 +602,8 @@
  *
  * FUNCTION:    acpi_ps_link_module_code
  *
- * PARAMETERS:  aml_start           - Pointer to the AML
+ * PARAMETERS:  parent_op           - Parent parser op
+ *              aml_start           - Pointer to the AML
  *              aml_length          - Length of executable AML
  *              owner_id            - owner_id of module level code
  *
@@ -611,11 +616,13 @@
  ******************************************************************************/
 
 static void
-acpi_ps_link_module_code(u8 *aml_start, u32 aml_length, acpi_owner_id owner_id)
+acpi_ps_link_module_code(union acpi_parse_object *parent_op,
+			 u8 *aml_start, u32 aml_length, acpi_owner_id owner_id)
 {
 	union acpi_operand_object *prev;
 	union acpi_operand_object *next;
 	union acpi_operand_object *method_obj;
+	struct acpi_namespace_node *parent_node;
 
 	/* Get the tail of the list */
 
@@ -639,11 +646,24 @@
 			return;
 		}
 
+		if (parent_op->common.node) {
+			parent_node = parent_op->common.node;
+		} else {
+			parent_node = acpi_gbl_root_node;
+		}
+
 		method_obj->method.aml_start = aml_start;
 		method_obj->method.aml_length = aml_length;
 		method_obj->method.owner_id = owner_id;
 		method_obj->method.flags |= AOPOBJ_MODULE_LEVEL;
 
+		/*
+		 * Save the parent node in next_object. This is cheating, but we
+		 * don't want to expand the method object.
+		 */
+		method_obj->method.next_object =
+		    ACPI_CAST_PTR(union acpi_operand_object, parent_node);
+
 		if (!prev) {
 			acpi_gbl_module_code_list = method_obj;
 		} else {
diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c
index 70838e9..4df8f13 100644
--- a/drivers/acpi/acpica/psparse.c
+++ b/drivers/acpi/acpica/psparse.c
@@ -610,17 +610,13 @@
 					    implicit_return_obj) {
 						previous_walk_state->
 						    implicit_return_obj =
-						    acpi_ut_create_internal_object
-						    (ACPI_TYPE_INTEGER);
+						    acpi_ut_create_integer_object
+						    ((u64) 0);
 						if (!previous_walk_state->
 						    implicit_return_obj) {
 							return_ACPI_STATUS
 							    (AE_NO_MEMORY);
 						}
-
-						previous_walk_state->
-						    implicit_return_obj->
-						    integer.value = 0;
 					}
 
 					/* Restart the calling control method */
diff --git a/drivers/acpi/acpica/psxface.c b/drivers/acpi/acpica/psxface.c
index dd9731c..12934ad 100644
--- a/drivers/acpi/acpica/psxface.c
+++ b/drivers/acpi/acpica/psxface.c
@@ -306,14 +306,12 @@
 	 */
 	if (acpi_gbl_enable_interpreter_slack) {
 		walk_state->implicit_return_obj =
-		    acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+		    acpi_ut_create_integer_object((u64) 0);
 		if (!walk_state->implicit_return_obj) {
 			status = AE_NO_MEMORY;
 			acpi_ds_delete_walk_state(walk_state);
 			goto cleanup;
 		}
-
-		walk_state->implicit_return_obj->integer.value = 0;
 	}
 
 	/* Parse the AML */
diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c
index 61f6315..6c6a513 100644
--- a/drivers/acpi/acpica/utmisc.c
+++ b/drivers/acpi/acpica/utmisc.c
@@ -1161,3 +1161,45 @@
 	ACPI_COMMON_MSG_SUFFIX;
 	va_end(args);
 }
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_predefined_info
+ *
+ * PARAMETERS:  module_name     - Caller's module name (for error output)
+ *              line_number     - Caller's line number (for error output)
+ *              Pathname        - Full pathname to the node
+ *              node_flags      - From Namespace node for the method/object
+ *              Format          - Printf format string + additional args
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Info messages for the predefined validation module. Messages
+ *              are only emitted the first time a problem with a particular
+ *              method/object is detected. This prevents a flood of
+ *              messages for methods that are repeatedly evaluated.
+ *
+ ******************************************************************************/
+
+void ACPI_INTERNAL_VAR_XFACE
+acpi_ut_predefined_info(const char *module_name,
+			u32 line_number,
+			char *pathname, u8 node_flags, const char *format, ...)
+{
+	va_list args;
+
+	/*
+	 * Warning messages for this method/object will be disabled after the
+	 * first time a validation fails or an object is successfully repaired.
+	 */
+	if (node_flags & ANOBJ_EVALUATED) {
+		return;
+	}
+
+	acpi_os_printf("ACPI Info for %s: ", pathname);
+
+	va_start(args, format);
+	acpi_os_vprintf(format, args);
+	ACPI_COMMON_MSG_SUFFIX;
+	va_end(args);
+}
diff --git a/drivers/acpi/acpica/utobject.c b/drivers/acpi/acpica/utobject.c
index 0207b62..42e658b 100644
--- a/drivers/acpi/acpica/utobject.c
+++ b/drivers/acpi/acpica/utobject.c
@@ -190,6 +190,35 @@
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_ut_create_integer_object
+ *
+ * PARAMETERS:  initial_value       - Initial value for the integer
+ *
+ * RETURN:      Pointer to a new Integer object, null on failure
+ *
+ * DESCRIPTION: Create an initialized integer object
+ *
+ ******************************************************************************/
+
+union acpi_operand_object *acpi_ut_create_integer_object(u64 initial_value)
+{
+	union acpi_operand_object *integer_desc;
+
+	ACPI_FUNCTION_TRACE(ut_create_integer_object);
+
+	/* Create and initialize a new integer object */
+
+	integer_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+	if (!integer_desc) {
+		return_PTR(NULL);
+	}
+
+	integer_desc->integer.value = initial_value;
+	return_PTR(integer_desc);
+}
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_ut_create_buffer_object
  *
  * PARAMETERS:  buffer_size            - Size of buffer to be created
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 642bb30..5faf6c2 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -258,7 +258,7 @@
 	acpi_walk_namespace(ACPI_TYPE_DEVICE,
 			    ACPI_ROOT_OBJECT,
 			    ACPI_UINT32_MAX,
-			    container_walk_namespace_cb, &action, NULL);
+			    container_walk_namespace_cb, NULL, &action, NULL);
 
 	return (0);
 }
@@ -271,7 +271,7 @@
 	acpi_walk_namespace(ACPI_TYPE_DEVICE,
 			    ACPI_ROOT_OBJECT,
 			    ACPI_UINT32_MAX,
-			    container_walk_namespace_cb, &action, NULL);
+			    container_walk_namespace_cb, NULL, &action, NULL);
 
 	acpi_bus_unregister_driver(&acpi_container_driver);
 
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 7338b6a..30be3c1 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -1030,8 +1030,8 @@
 
 	/* Find dependent devices */
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-			    ACPI_UINT32_MAX, find_dock_devices, dock_station,
-			    NULL);
+			    ACPI_UINT32_MAX, find_dock_devices, NULL,
+			    dock_station, NULL);
 
 	/* add the dock station as a device dependent on itself */
 	dd = alloc_dock_dependent_device(handle);
@@ -1127,11 +1127,11 @@
 
 	/* look for a dock station */
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-			    ACPI_UINT32_MAX, find_dock, NULL, NULL);
+			    ACPI_UINT32_MAX, find_dock, NULL, NULL, NULL);
 
 	/* look for bay */
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-			ACPI_UINT32_MAX, find_bay, NULL, NULL);
+			ACPI_UINT32_MAX, find_bay, NULL, NULL, NULL);
 	if (!dock_station_count) {
 		printk(KERN_INFO PREFIX "No dock devices found.\n");
 		return 0;
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index baef28c..75b147f 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -820,7 +820,7 @@
 
 	/* Find and register all query methods */
 	acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1,
-			    acpi_ec_register_query_methods, ec, NULL);
+			    acpi_ec_register_query_methods, NULL, ec, NULL);
 
 	if (!first_ec)
 		first_ec = ec;
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index c6645f2..4c8fcff 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -113,7 +113,7 @@
 	if (!parent)
 		return NULL;
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, parent,
-			    1, do_acpi_find_child, &find, NULL);
+			    1, do_acpi_find_child, NULL, &find, NULL);
 	return find.handle;
 }
 
diff --git a/drivers/acpi/hest.c b/drivers/acpi/hest.c
new file mode 100644
index 0000000..4bb18c9
--- /dev/null
+++ b/drivers/acpi/hest.c
@@ -0,0 +1,135 @@
+#include <linux/acpi.h>
+#include <linux/pci.h>
+
+#define PREFIX "ACPI: "
+
+static inline unsigned long parse_acpi_hest_ia_machine_check(struct acpi_hest_ia_machine_check *p)
+{
+	return sizeof(*p) +
+		(sizeof(struct acpi_hest_ia_error_bank) * p->num_hardware_banks);
+}
+
+static inline unsigned long parse_acpi_hest_ia_corrected(struct acpi_hest_ia_corrected *p)
+{
+	return sizeof(*p) +
+		(sizeof(struct acpi_hest_ia_error_bank) * p->num_hardware_banks);
+}
+
+static inline unsigned long parse_acpi_hest_ia_nmi(struct acpi_hest_ia_nmi *p)
+{
+	return sizeof(*p);
+}
+
+static inline unsigned long parse_acpi_hest_generic(struct acpi_hest_generic *p)
+{
+	return sizeof(*p);
+}
+
+static inline unsigned int hest_match_pci(struct acpi_hest_aer_common *p, struct pci_dev *pci)
+{
+	return	(0           == pci_domain_nr(pci->bus) &&
+		 p->bus      == pci->bus->number &&
+		 p->device   == PCI_SLOT(pci->devfn) &&
+		 p->function == PCI_FUNC(pci->devfn));
+}
+
+static unsigned long parse_acpi_hest_aer(void *hdr, int type, struct pci_dev *pci, int *firmware_first)
+{
+	struct acpi_hest_aer_common *p = hdr + sizeof(struct acpi_hest_header);
+	unsigned long rc=0;
+	u8 pcie_type = 0;
+	u8 bridge = 0;
+	switch (type) {
+	case ACPI_HEST_TYPE_AER_ROOT_PORT:
+		rc = sizeof(struct acpi_hest_aer_root);
+		pcie_type = PCI_EXP_TYPE_ROOT_PORT;
+		break;
+	case ACPI_HEST_TYPE_AER_ENDPOINT:
+		rc = sizeof(struct acpi_hest_aer);
+		pcie_type = PCI_EXP_TYPE_ENDPOINT;
+		break;
+	case ACPI_HEST_TYPE_AER_BRIDGE:
+		rc = sizeof(struct acpi_hest_aer_bridge);
+		if ((pci->class >> 16) == PCI_BASE_CLASS_BRIDGE)
+			bridge = 1;
+		break;
+	}
+
+	if (p->flags & ACPI_HEST_GLOBAL) {
+		if ((pci->is_pcie && (pci->pcie_type == pcie_type)) || bridge)
+			*firmware_first = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST);
+	}
+	else
+		if (hest_match_pci(p, pci))
+			*firmware_first = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST);
+	return rc;
+}
+
+static int acpi_hest_firmware_first(struct acpi_table_header *stdheader, struct pci_dev *pci)
+{
+	struct acpi_table_hest *hest = (struct acpi_table_hest *)stdheader;
+	void *p = (void *)hest + sizeof(*hest); /* defined by the ACPI 4.0 spec */
+	struct acpi_hest_header *hdr = p;
+
+	int i;
+	int firmware_first = 0;
+	static unsigned char printed_unused = 0;
+	static unsigned char printed_reserved = 0;
+
+	for (i=0, hdr=p; p < (((void *)hest) + hest->header.length) && i < hest->error_source_count; i++) {
+		switch (hdr->type) {
+		case ACPI_HEST_TYPE_IA32_CHECK:
+			p += parse_acpi_hest_ia_machine_check(p);
+			break;
+		case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
+			p += parse_acpi_hest_ia_corrected(p);
+			break;
+		case ACPI_HEST_TYPE_IA32_NMI:
+			p += parse_acpi_hest_ia_nmi(p);
+			break;
+		/* These three should never appear */
+		case ACPI_HEST_TYPE_NOT_USED3:
+		case ACPI_HEST_TYPE_NOT_USED4:
+		case ACPI_HEST_TYPE_NOT_USED5:
+			if (!printed_unused) {
+				printk(KERN_DEBUG PREFIX
+				       "HEST Error Source list contains an obsolete type (%d).\n", hdr->type);
+				printed_unused = 1;
+			}
+			break;
+		case ACPI_HEST_TYPE_AER_ROOT_PORT:
+		case ACPI_HEST_TYPE_AER_ENDPOINT:
+		case ACPI_HEST_TYPE_AER_BRIDGE:
+			p += parse_acpi_hest_aer(p, hdr->type, pci, &firmware_first);
+			break;
+		case ACPI_HEST_TYPE_GENERIC_ERROR:
+			p += parse_acpi_hest_generic(p);
+			break;
+		/* These should never appear either */
+		case ACPI_HEST_TYPE_RESERVED:
+		default:
+			if (!printed_reserved) {
+				printk(KERN_DEBUG PREFIX
+				       "HEST Error Source list contains a reserved type (%d).\n", hdr->type);
+				printed_reserved = 1;
+			}
+			break;
+		}
+	}
+	return firmware_first;
+}
+
+int acpi_hest_firmware_first_pci(struct pci_dev *pci)
+{
+	acpi_status status = AE_NOT_FOUND;
+	struct acpi_table_header *hest = NULL;
+	status = acpi_get_table(ACPI_SIG_HEST, 1, &hest);
+
+	if (ACPI_SUCCESS(status)) {
+		if (acpi_hest_firmware_first(hest, pci)) {
+			return 1;
+		}
+	}
+	return 0;
+}
+EXPORT_SYMBOL_GPL(acpi_hest_firmware_first_pci);
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index 202dd0c..2be2fb6 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -283,22 +283,24 @@
 
 int __init acpi_numa_init(void)
 {
+	int ret = 0;
+
 	/* SRAT: Static Resource Affinity Table */
 	if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
 		acpi_table_parse_srat(ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY,
 				      acpi_parse_x2apic_affinity, NR_CPUS);
 		acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
 				      acpi_parse_processor_affinity, NR_CPUS);
-		acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
-				      acpi_parse_memory_affinity,
-				      NR_NODE_MEMBLKS);
+		ret = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
+					    acpi_parse_memory_affinity,
+					    NR_NODE_MEMBLKS);
 	}
 
 	/* SLIT: System Locality Information Table */
 	acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit);
 
 	acpi_numa_arch_fixup();
-	return 0;
+	return ret;
 }
 
 int acpi_get_pxm(acpi_handle h)
diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c
index 45da2ba..11f2197 100644
--- a/drivers/acpi/pci_slot.c
+++ b/drivers/acpi/pci_slot.c
@@ -219,12 +219,12 @@
 
 	dbg("p2p bridge walk, pci_bus = %x\n", dev->subordinate->number);
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				     user_function, &child_context, NULL);
+				     user_function, NULL, &child_context, NULL);
 	if (ACPI_FAILURE(status))
 		goto out;
 
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				     walk_p2p_bridge, &child_context, NULL);
+				     walk_p2p_bridge, NULL, &child_context, NULL);
 out:
 	pci_dev_put(dev);
 	return AE_OK;
@@ -277,12 +277,12 @@
 
 	dbg("root bridge walk, pci_bus = %x\n", pci_bus->number);
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				     user_function, &context, NULL);
+				     user_function, NULL, &context, NULL);
 	if (ACPI_FAILURE(status))
 		return status;
 
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				     walk_p2p_bridge, &context, NULL);
+				     walk_p2p_bridge, NULL, &context, NULL);
 	if (ACPI_FAILURE(status))
 		err("%s: walk_p2p_bridge failure - %d\n", __func__, status);
 
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index ec742a4..cb4283f 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -1102,7 +1102,7 @@
 	acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
 			    ACPI_ROOT_OBJECT,
 			    ACPI_UINT32_MAX,
-			    processor_walk_namespace_cb, &action, NULL);
+			    processor_walk_namespace_cb, NULL, &action, NULL);
 #endif
 	register_hotcpu_notifier(&acpi_cpu_notifier);
 }
@@ -1115,7 +1115,7 @@
 	acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
 			    ACPI_ROOT_OBJECT,
 			    ACPI_UINT32_MAX,
-			    processor_walk_namespace_cb, &action, NULL);
+			    processor_walk_namespace_cb, NULL, &action, NULL);
 #endif
 	unregister_hotcpu_notifier(&acpi_cpu_notifier);
 }
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 8ba0ed0..01e366d 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -167,6 +167,19 @@
 		return cpufreq_update_policy(pr->id);
 }
 
+int acpi_processor_get_bios_limit(int cpu, unsigned int *limit)
+{
+	struct acpi_processor *pr;
+
+	pr = per_cpu(processors, cpu);
+	if (!pr || !pr->performance || !pr->performance->state_count)
+		return -ENODEV;
+	*limit = pr->performance->states[pr->performance_platform_limit].
+		core_frequency * 1000;
+	return 0;
+}
+EXPORT_SYMBOL(acpi_processor_get_bios_limit);
+
 void acpi_processor_ppc_init(void)
 {
 	if (!cpufreq_register_notifier
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 14a7481..ff9f622 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1332,7 +1332,7 @@
 	status = acpi_bus_check_add(handle, 0, ops, &device);
 	if (ACPI_SUCCESS(status))
 		acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
-				    acpi_bus_check_add, ops, &device);
+				    acpi_bus_check_add, NULL, ops, &device);
 
 	if (child)
 		*child = device;
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 575593a..fc2f26b 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -7,7 +7,7 @@
  * video_detect.c:
  * Provides acpi_is_video_device() for early scanning of ACPI devices in scan.c
  * There a Linux specific (Spec does not provide a HID for video devices) is
- * assinged
+ * assigned
  *
  * After PCI devices are glued with ACPI devices
  * acpi_get_pci_dev() can be called to identify ACPI graphics
@@ -83,16 +83,16 @@
 	if (!device)
 		return 0;
 
-	/* Does this device able to support video switching ? */
+	/* Is this device able to support video switching ? */
 	if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) ||
 	    ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy)))
 		video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING;
 
-	/* Does this device able to retrieve a video ROM ? */
+	/* Is this device able to retrieve a video ROM ? */
 	if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy)))
 		video_caps |= ACPI_VIDEO_ROM_AVAILABLE;
 
-	/* Does this device able to configure which video head to be POSTed ? */
+	/* Is this device able to configure which video head to be POSTed ? */
 	if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy)) &&
 	    ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy)) &&
 	    ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy)))
@@ -101,7 +101,7 @@
 	/* Only check for backlight functionality if one of the above hit. */
 	if (video_caps)
 		acpi_walk_namespace(ACPI_TYPE_DEVICE, device->handle,
-				    ACPI_UINT32_MAX, acpi_backlight_cap_match,
+				    ACPI_UINT32_MAX, acpi_backlight_cap_match, NULL,
 				    &video_caps, NULL);
 
 	return video_caps;
@@ -137,7 +137,7 @@
  *
  * if NULL is passed as argument all ACPI devices are enumerated and
  * all graphics capabilities of physically present devices are
- * summerized and returned. This is cached and done only once.
+ * summarized and returned. This is cached and done only once.
  */
 long acpi_video_get_capabilities(acpi_handle graphics_handle)
 {
@@ -151,7 +151,7 @@
 	if (!graphics_handle) {
 		/* Only do the global walk through all graphics devices once */
 		acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-				    ACPI_UINT32_MAX, find_video,
+				    ACPI_UINT32_MAX, find_video, NULL,
 				    &caps, NULL);
 		/* There might be boot param flags set already... */
 		acpi_video_support |= caps;
@@ -173,7 +173,7 @@
 			return 0;
 		}
 		acpi_walk_namespace(ACPI_TYPE_DEVICE, graphics_handle,
-				    ACPI_UINT32_MAX, find_video,
+				    ACPI_UINT32_MAX, find_video, NULL,
 				    &caps, NULL);
 	}
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "We have 0x%lX video support %s %s\n",
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 0c6155f..19136a7 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -599,7 +599,7 @@
 	{ 0x27DF, 0x1028, 0x02b0 },	/* ICH7 on unknown Dell */
 	{ 0x27DF, 0x1043, 0x1267 },	/* ICH7 on Asus W5F */
 	{ 0x27DF, 0x103C, 0x30A1 },	/* ICH7 on HP Compaq nc2400 */
-	{ 0x27DF, 0x103C, 0x361a },	/* ICH7 on unkown HP  */
+	{ 0x27DF, 0x103C, 0x361a },	/* ICH7 on unknown HP  */
 	{ 0x27DF, 0x1071, 0xD221 },	/* ICH7 on Hercules EC-900 */
 	{ 0x27DF, 0x152D, 0x0778 },	/* ICH7 on unknown Intel */
 	{ 0x24CA, 0x1025, 0x0061 },	/* ICH4 on ACER Aspire 2023WLMi */
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 62e6b9e..1683ebd 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1208,6 +1208,7 @@
  *	ata_scsi_change_queue_depth - SCSI callback for queue depth config
  *	@sdev: SCSI device to configure queue depth for
  *	@queue_depth: new queue depth
+ *	@reason: calling context
  *
  *	This is libata standard hostt->change_queue_depth callback.
  *	SCSI will call into this callback when user tries to set queue
@@ -1219,12 +1220,16 @@
  *	RETURNS:
  *	Newly configured queue depth.
  */
-int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
+int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth,
+				int reason)
 {
 	struct ata_port *ap = ata_shost_to_port(sdev->host);
 	struct ata_device *dev;
 	unsigned long flags;
 
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (queue_depth < 1 || queue_depth == sdev->queue_depth)
 		return sdev->queue_depth;
 
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 51eb1e2..efa8773 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -736,7 +736,7 @@
 
 		/*
 		 * Use io*16_rep() accessors here as well to avoid pointlessly
-		 * swapping bytes to and fro on the big endian machines...
+		 * swapping bytes to and from on the big endian machines...
 		 */
 		if (rw == READ) {
 			ioread16_rep(data_addr, pad, 1);
@@ -776,7 +776,7 @@
 	void __iomem *data_addr = ap->ioaddr.data_addr;
 	unsigned int words = buflen >> 2;
 	int slop = buflen & 3;
-	
+
 	if (!(ap->pflags & ATA_PFLAG_PIO32))
 		return ata_sff_data_xfer(dev, buf, buflen, rw);
 
@@ -795,7 +795,7 @@
 
 		/*
 		 * Use io*_rep() accessors here as well to avoid pointlessly
-		 * swapping bytes to and fro on the big endian machines...
+		 * swapping bytes to and from on the big endian machines...
 		 */
 		if (rw == READ) {
 			if (slop < 3)
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c
index 403f561..71cef9a 100644
--- a/drivers/ata/pata_cs5535.c
+++ b/drivers/ata/pata_cs5535.c
@@ -4,7 +4,7 @@
  *			  Alan Cox <alan@lxorguk.ukuu.org.uk>
  *
  * based upon cs5535.c from AMD <Jens.Altmann@amd.com> as cleaned up and
- * made readable and Linux style by Wolfgang Zuleger <wolfgang.zuleger@gmx.de
+ * made readable and Linux style by Wolfgang Zuleger <wolfgang.zuleger@gmx.de>
  * and Alexander Kiausch <alex.kiausch@t-online.de>
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
index 8a5d35b..ce4136e 100644
--- a/drivers/ata/sata_fsl.c
+++ b/drivers/ata/sata_fsl.c
@@ -43,9 +43,9 @@
 	/*
 	 * SATA-FSL host controller supports a max. of (15+1) direct PRDEs, and
 	 * chained indirect PRDEs upto a max count of 63.
-	 * We are allocating an array of 63 PRDEs contigiously, but PRDE#15 will
+	 * We are allocating an array of 63 PRDEs contiguously, but PRDE#15 will
 	 * be setup as an indirect descriptor, pointing to it's next
-	 * (contigious) PRDE. Though chained indirect PRDE arrays are
+	 * (contiguous) PRDE. Though chained indirect PRDE arrays are
 	 * supported,it will be more efficient to use a direct PRDT and
 	 * a single chain/link to indirect PRDE array/PRDT.
 	 */
@@ -314,7 +314,7 @@
 	u32 ttl_dwords = 0;
 
 	/*
-	 * NOTE : direct & indirect prdt's are contigiously allocated
+	 * NOTE : direct & indirect prdt's are contiguously allocated
 	 */
 	struct prde *prd = (struct prde *)&((struct command_desc *)
 					    cmd_desc)->prdt;
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 1eb4e02..0c82d33 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -1975,7 +1975,7 @@
 	ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
 
 	if (strncmp(model_num, "Maxtor", 6) == 0) {
-		ata_scsi_change_queue_depth(sdev, 1);
+		ata_scsi_change_queue_depth(sdev, 1, SCSI_QDEPTH_DEFAULT);
 		ata_dev_printk(dev, KERN_NOTICE,
 			"Disabling SWNCQ mode (depth %x)\n", sdev->queue_depth);
 	}
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
index b2c1b37..f734b34 100644
--- a/drivers/atm/iphase.c
+++ b/drivers/atm/iphase.c
@@ -1132,7 +1132,7 @@
                     IF_ERR(printk(" cause: packet time out\n");)
                 }
                 else {
-                    IF_ERR(printk(" cause: buffer over flow\n");)
+                    IF_ERR(printk(" cause: buffer overflow\n");)
                 }
 		goto out_free_desc;
 	}  
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 6bee6af..f1290cb 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -56,7 +56,14 @@
  */
 const char *dev_driver_string(const struct device *dev)
 {
-	return dev->driver ? dev->driver->name :
+	struct device_driver *drv;
+
+	/* dev->driver can change to NULL underneath us because of unbinding,
+	 * so be careful about accessing it.  dev->bus and dev->class should
+	 * never change once they are set, so they don't need special care.
+	 */
+	drv = ACCESS_ONCE(dev->driver);
+	return drv ? drv->name :
 			(dev->bus ? dev->bus->name :
 			(dev->class ? dev->class->name : ""));
 }
@@ -987,6 +994,8 @@
 	device_remove_class_symlinks(dev);
  SymlinkError:
 	if (MAJOR(dev->devt))
+		devtmpfs_delete_node(dev);
+	if (MAJOR(dev->devt))
 		device_remove_sys_dev_entry(dev);
  devtattrError:
 	if (MAJOR(dev->devt))
@@ -1728,8 +1737,5 @@
 			dev->driver->shutdown(dev);
 		}
 	}
-	kobject_put(sysfs_dev_char_kobj);
-	kobject_put(sysfs_dev_block_kobj);
-	kobject_put(dev_kobj);
 	async_synchronize_full();
 }
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 979d159..ee95c76 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -188,7 +188,7 @@
  * @dev: device to try to bind to the driver
  *
  * This function returns -ENODEV if the device is not registered,
- * 1 if the device is bound sucessfully and 0 otherwise.
+ * 1 if the device is bound successfully and 0 otherwise.
  *
  * This function must be called with @dev->sem held.  When called for a
  * USB interface, @dev->parent->sem must be held as well.
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index a1cb5af..50375bb 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -32,6 +32,8 @@
 static int dev_mount;
 #endif
 
+static rwlock_t dirlock;
+
 static int __init mount_param(char *str)
 {
 	dev_mount = simple_strtoul(str, NULL, 0);
@@ -74,47 +76,35 @@
 	dentry = lookup_create(&nd, 1);
 	if (!IS_ERR(dentry)) {
 		err = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
+		if (!err)
+			/* mark as kernel-created inode */
+			dentry->d_inode->i_private = &dev_mnt;
 		dput(dentry);
 	} else {
 		err = PTR_ERR(dentry);
 	}
-	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
 
+	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
 	path_put(&nd.path);
 	return err;
 }
 
 static int create_path(const char *nodepath)
 {
-	char *path;
-	struct nameidata nd;
-	int err = 0;
+	int err;
 
-	path = kstrdup(nodepath, GFP_KERNEL);
-	if (!path)
-		return -ENOMEM;
-
-	err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
-			      path, LOOKUP_PARENT, &nd);
-	if (err == 0) {
-		struct dentry *dentry;
-
-		/* create directory right away */
-		dentry = lookup_create(&nd, 1);
-		if (!IS_ERR(dentry)) {
-			err = vfs_mkdir(nd.path.dentry->d_inode,
-					dentry, 0755);
-			dput(dentry);
-		}
-		mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
-
-		path_put(&nd.path);
-	} else if (err == -ENOENT) {
+	read_lock(&dirlock);
+	err = dev_mkdir(nodepath, 0755);
+	if (err == -ENOENT) {
+		char *path;
 		char *s;
 
 		/* parent directories do not exist, create them */
+		path = kstrdup(nodepath, GFP_KERNEL);
+		if (!path)
+			return -ENOMEM;
 		s = path;
-		while (1) {
+		for (;;) {
 			s = strchr(s, '/');
 			if (!s)
 				break;
@@ -125,9 +115,9 @@
 			s[0] = '/';
 			s++;
 		}
+		kfree(path);
 	}
-
-	kfree(path);
+	read_unlock(&dirlock);
 	return err;
 }
 
@@ -156,34 +146,40 @@
 		mode |= S_IFCHR;
 
 	curr_cred = override_creds(&init_cred);
+
 	err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
 			      nodename, LOOKUP_PARENT, &nd);
 	if (err == -ENOENT) {
-		/* create missing parent directories */
 		create_path(nodename);
 		err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
 				      nodename, LOOKUP_PARENT, &nd);
-		if (err)
-			goto out;
 	}
+	if (err)
+		goto out;
 
 	dentry = lookup_create(&nd, 0);
 	if (!IS_ERR(dentry)) {
-		int umask;
-
-		umask = sys_umask(0000);
 		err = vfs_mknod(nd.path.dentry->d_inode,
 				dentry, mode, dev->devt);
-		sys_umask(umask);
-		/* mark as kernel created inode */
-		if (!err)
+		if (!err) {
+			struct iattr newattrs;
+
+			/* fixup possibly umasked mode */
+			newattrs.ia_mode = mode;
+			newattrs.ia_valid = ATTR_MODE;
+			mutex_lock(&dentry->d_inode->i_mutex);
+			notify_change(dentry, &newattrs);
+			mutex_unlock(&dentry->d_inode->i_mutex);
+
+			/* mark as kernel-created inode */
 			dentry->d_inode->i_private = &dev_mnt;
+		}
 		dput(dentry);
 	} else {
 		err = PTR_ERR(dentry);
 	}
-	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
 
+	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
 	path_put(&nd.path);
 out:
 	kfree(tmp);
@@ -205,16 +201,21 @@
 	mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
 	dentry = lookup_one_len(nd.last.name, nd.path.dentry, nd.last.len);
 	if (!IS_ERR(dentry)) {
-		if (dentry->d_inode)
-			err = vfs_rmdir(nd.path.dentry->d_inode, dentry);
-		else
+		if (dentry->d_inode) {
+			if (dentry->d_inode->i_private == &dev_mnt)
+				err = vfs_rmdir(nd.path.dentry->d_inode,
+						dentry);
+			else
+				err = -EPERM;
+		} else {
 			err = -ENOENT;
+		}
 		dput(dentry);
 	} else {
 		err = PTR_ERR(dentry);
 	}
-	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
 
+	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
 	path_put(&nd.path);
 	return err;
 }
@@ -228,7 +229,8 @@
 	if (!path)
 		return -ENOMEM;
 
-	while (1) {
+	write_lock(&dirlock);
+	for (;;) {
 		char *base;
 
 		base = strrchr(path, '/');
@@ -239,6 +241,7 @@
 		if (err)
 			break;
 	}
+	write_unlock(&dirlock);
 
 	kfree(path);
 	return err;
@@ -322,9 +325,8 @@
  * If configured, or requested by the commandline, devtmpfs will be
  * auto-mounted after the kernel mounted the root filesystem.
  */
-int devtmpfs_mount(const char *mountpoint)
+int devtmpfs_mount(const char *mntdir)
 {
-	struct path path;
 	int err;
 
 	if (!dev_mount)
@@ -333,15 +335,11 @@
 	if (!dev_mnt)
 		return 0;
 
-	err = kern_path(mountpoint, LOOKUP_FOLLOW, &path);
-	if (err)
-		return err;
-	err = do_add_mount(dev_mnt, &path, 0, NULL);
+	err = sys_mount("devtmpfs", (char *)mntdir, "devtmpfs", MS_SILENT, NULL);
 	if (err)
 		printk(KERN_INFO "devtmpfs: error mounting %i\n", err);
 	else
 		printk(KERN_INFO "devtmpfs: mounted\n");
-	path_put(&path);
 	return err;
 }
 
@@ -354,6 +352,8 @@
 	int err;
 	struct vfsmount *mnt;
 
+	rwlock_init(&dirlock);
+
 	err = register_filesystem(&dev_fs_type);
 	if (err) {
 		printk(KERN_ERR "devtmpfs: unable to register devtmpfs "
@@ -361,7 +361,7 @@
 		return err;
 	}
 
-	mnt = kern_mount(&dev_fs_type);
+	mnt = kern_mount_data(&dev_fs_type, "mode=0755");
 	if (IS_ERR(mnt)) {
 		err = PTR_ERR(mnt);
 		printk(KERN_ERR "devtmpfs: unable to create devtmpfs %i\n", err);
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 7376367..a950241 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -601,12 +601,9 @@
 	}
 	ret = _request_firmware(&fw, fw_work->name, fw_work->device,
 		fw_work->uevent);
-	if (ret < 0)
-		fw_work->cont(NULL, fw_work->context);
-	else {
-		fw_work->cont(fw, fw_work->context);
-		release_firmware(fw);
-	}
+
+	fw_work->cont(fw, fw_work->context);
+
 	module_put(fw_work->module);
 	kfree(fw_work);
 	return ret;
@@ -619,6 +616,7 @@
  *	is non-zero else the firmware copy must be done manually.
  * @name: name of firmware file
  * @device: device for which firmware is being loaded
+ * @gfp: allocation flags
  * @context: will be passed over to @cont, and
  *	@fw may be %NULL if firmware request fails.
  * @cont: function will be called asynchronously when the firmware
@@ -631,12 +629,12 @@
 int
 request_firmware_nowait(
 	struct module *module, int uevent,
-	const char *name, struct device *device, void *context,
+	const char *name, struct device *device, gfp_t gfp, void *context,
 	void (*cont)(const struct firmware *fw, void *context))
 {
 	struct task_struct *task;
 	struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work),
-						GFP_ATOMIC);
+						gfp);
 
 	if (!fw_work)
 		return -ENOMEM;
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 4fa954b..9d2ee25 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -1000,7 +1000,7 @@
 int __init early_platform_driver_register(struct early_platform_driver *epdrv,
 					  char *buf)
 {
-	unsigned long index;
+	char *tmp;
 	int n;
 
 	/* Simply add the driver to the end of the global list.
@@ -1019,13 +1019,28 @@
 	if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) {
 		list_move(&epdrv->list, &early_platform_driver_list);
 
-		if (!strcmp(buf, epdrv->pdrv->driver.name))
+		/* Allow passing parameters after device name */
+		if (buf[n] == '\0' || buf[n] == ',')
 			epdrv->requested_id = -1;
-		else if (buf[n] == '.' && strict_strtoul(&buf[n + 1], 10,
-							 &index) == 0)
-			epdrv->requested_id = index;
-		else
-			epdrv->requested_id = EARLY_PLATFORM_ID_ERROR;
+		else {
+			epdrv->requested_id = simple_strtoul(&buf[n + 1],
+							     &tmp, 10);
+
+			if (buf[n] != '.' || (tmp == &buf[n + 1])) {
+				epdrv->requested_id = EARLY_PLATFORM_ID_ERROR;
+				n = 0;
+			} else
+				n += strcspn(&buf[n + 1], ",") + 1;
+		}
+
+		if (buf[n] == ',')
+			n++;
+
+		if (epdrv->bufsize) {
+			memcpy(epdrv->buffer, &buf[n],
+			       min_t(int, epdrv->bufsize, strlen(&buf[n]) + 1));
+			epdrv->buffer[epdrv->bufsize - 1] = '\0';
+		}
 	}
 
 	return 0;
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index 847a9e5..a5af1d6 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -1478,10 +1478,7 @@
 	stdma_lock(floppy_irq, NULL);
 
 	atari_disable_irq( IRQ_MFP_FDC );
-	local_save_flags(flags);	/* The request function is called with ints
-	local_irq_disable();		 * disabled... so must save the IPL for later */ 
 	redo_fd_request();
-	local_irq_restore(flags);
 	atari_enable_irq( IRQ_MFP_FDC );
 }
 
diff --git a/drivers/block/cciss_cmd.h b/drivers/block/cciss_cmd.h
index b50a9b2..6afa700 100644
--- a/drivers/block/cciss_cmd.h
+++ b/drivers/block/cciss_cmd.h
@@ -5,7 +5,7 @@
 //###########################################################################
 #define CISS_VERSION "1.00"
 
-//general boundary defintions
+//general boundary definitions
 #define SENSEINFOBYTES          32//note that this value may vary between host implementations
 #define MAXSGENTRIES            32
 #define CCISS_SG_CHAIN          0x80000000
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index b8578bb..05a31e5 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -42,6 +42,7 @@
 #include <linux/module.h>
 #include <linux/scatterlist.h>
 
+#include <xen/xen.h>
 #include <xen/xenbus.h>
 #include <xen/grant_table.h>
 #include <xen/events.h>
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index 1e6eb1a..f36defa 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -535,7 +535,7 @@
 		break;
 
 	default:
-		BT_ERR("Unknow packet type:%d", type);
+		BT_ERR("Unknown packet type:%d", type);
 		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, payload,
 						blksz * buf_block_len);
 
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 44bc8bb..4d29059 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -1066,7 +1066,7 @@
 		return 0;
 
 	spin_lock_irq(&data->txlock);
-	if (!(interface_to_usbdev(intf)->auto_pm && data->tx_in_flight)) {
+	if (!((message.event & PM_EVENT_AUTO) && data->tx_in_flight)) {
 		set_bit(BTUSB_SUSPENDING, &data->flags);
 		spin_unlock_irq(&data->txlock);
 	} else {
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 4895f0e..aa09193 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -214,7 +214,7 @@
 	struct hci_uart *hu;
 
 	if (!hdev) {
-		BT_ERR("Frame for uknown device (hdev=NULL)");
+		BT_ERR("Frame for unknown device (hdev=NULL)");
 		return -ENODEV;
 	}
 
diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c
index a762283..e789e6c 100644
--- a/drivers/cdrom/gdrom.c
+++ b/drivers/cdrom/gdrom.c
@@ -214,7 +214,7 @@
 		gdrom_getsense(NULL);
 		return;
 	}
-	outsw(PHYSADDR(GDROM_DATA_REG), cmd, 6);
+	outsw(GDROM_DATA_REG, cmd, 6);
 }
 
 
@@ -298,7 +298,7 @@
 		err = -EINVAL;
 		goto cleanup_readtoc;
 	}
-	insw(PHYSADDR(GDROM_DATA_REG), toc, tocsize/2);
+	insw(GDROM_DATA_REG, toc, tocsize/2);
 	if (gd.status & 0x01)
 		err = -EINVAL;
 
@@ -449,7 +449,7 @@
 		GDROM_DEFAULT_TIMEOUT);
 	if (gd.pending)
 		goto cleanup_sense;
-	insw(PHYSADDR(GDROM_DATA_REG), &sense, sense_command->buflen/2);
+	insw(GDROM_DATA_REG, &sense, sense_command->buflen/2);
 	if (sense[1] & 40) {
 		printk(KERN_INFO "GDROM: Drive not ready - command aborted\n");
 		goto cleanup_sense;
@@ -586,7 +586,7 @@
 		spin_unlock(&gdrom_lock);
 		block = blk_rq_pos(req)/GD_TO_BLK + GD_SESSION_OFFSET;
 		block_cnt = blk_rq_sectors(req)/GD_TO_BLK;
-		ctrl_outl(PHYSADDR(req->buffer), GDROM_DMA_STARTADDR_REG);
+		ctrl_outl(virt_to_phys(req->buffer), GDROM_DMA_STARTADDR_REG);
 		ctrl_outl(block_cnt * GDROM_HARD_SECTOR, GDROM_DMA_LENGTH_REG);
 		ctrl_outl(1, GDROM_DMA_DIRECTION_REG);
 		ctrl_outl(1, GDROM_DMA_ENABLE_REG);
@@ -615,7 +615,7 @@
 			cpu_relax();
 		gd.pending = 1;
 		gd.transfer = 1;
-		outsw(PHYSADDR(GDROM_DATA_REG), &read_command->cmd, 6);
+		outsw(GDROM_DATA_REG, &read_command->cmd, 6);
 		timeout = jiffies + HZ / 2;
 		/* Wait for any pending DMA to finish */
 		while (ctrl_inb(GDROM_DMA_STATUS_REG) &&
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 6aad99e..6f31c94 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -201,19 +201,6 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called epca.
 
-config ESPSERIAL
-	tristate "Hayes ESP serial port support"
-	depends on SERIAL_NONSTANDARD && ISA && ISA_DMA_API && BROKEN
-	help
-	  This is a driver which supports Hayes ESP serial ports.  Both single
-	  port cards and multiport cards are supported.  Make sure to read
-	  <file:Documentation/hayes-esp.txt>.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called esp.
-
-	  If unsure, say N.
-
 config MOXA_INTELLIO
 	tristate "Moxa Intellio support"
 	depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI)
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 19a79dd..f957edf 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -18,7 +18,6 @@
 obj-$(CONFIG_HW_CONSOLE)	+= vt.o defkeymap.o
 obj-$(CONFIG_AUDIT)		+= tty_audit.o
 obj-$(CONFIG_MAGIC_SYSRQ)	+= sysrq.o
-obj-$(CONFIG_ESPSERIAL)		+= esp.o
 obj-$(CONFIG_MVME147_SCC)	+= generic_serial.o vme_scc.o
 obj-$(CONFIG_MVME162_SCC)	+= generic_serial.o vme_scc.o
 obj-$(CONFIG_BVME6000_SCC)	+= generic_serial.o vme_scc.o
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
index a96f319..43412c0 100644
--- a/drivers/char/agp/frontend.c
+++ b/drivers/char/agp/frontend.c
@@ -676,25 +676,25 @@
 	int minor = iminor(inode);
 	struct agp_file_private *priv;
 	struct agp_client *client;
-	int rc = -ENXIO;
-
-	lock_kernel();
-	mutex_lock(&(agp_fe.agp_mutex));
 
 	if (minor != AGPGART_MINOR)
-		goto err_out;
+		return -ENXIO;
+
+	mutex_lock(&(agp_fe.agp_mutex));
 
 	priv = kzalloc(sizeof(struct agp_file_private), GFP_KERNEL);
-	if (priv == NULL)
-		goto err_out_nomem;
+	if (priv == NULL) {
+		mutex_unlock(&(agp_fe.agp_mutex));
+		return -ENOMEM;
+	}
 
 	set_bit(AGP_FF_ALLOW_CLIENT, &priv->access_flags);
 	priv->my_pid = current->pid;
 
-	if (capable(CAP_SYS_RAWIO)) {
+	if (capable(CAP_SYS_RAWIO))
 		/* Root priv, can be controller */
 		set_bit(AGP_FF_ALLOW_CONTROLLER, &priv->access_flags);
-	}
+
 	client = agp_find_client_by_pid(current->pid);
 
 	if (client != NULL) {
@@ -704,16 +704,10 @@
 	file->private_data = (void *) priv;
 	agp_insert_file_private(priv);
 	DBG("private=%p, client=%p", priv, client);
-	mutex_unlock(&(agp_fe.agp_mutex));
-	unlock_kernel();
-	return 0;
 
-err_out_nomem:
-	rc = -ENOMEM;
-err_out:
 	mutex_unlock(&(agp_fe.agp_mutex));
-	unlock_kernel();
-	return rc;
+
+	return 0;
 }
 
 
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 3cb56a0..30c36ac 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -36,10 +36,10 @@
 #define PCI_DEVICE_ID_INTEL_82965GME_IG     0x2A12
 #define PCI_DEVICE_ID_INTEL_82945GME_HB     0x27AC
 #define PCI_DEVICE_ID_INTEL_82945GME_IG     0x27AE
-#define PCI_DEVICE_ID_INTEL_IGDGM_HB        0xA010
-#define PCI_DEVICE_ID_INTEL_IGDGM_IG        0xA011
-#define PCI_DEVICE_ID_INTEL_IGDG_HB         0xA000
-#define PCI_DEVICE_ID_INTEL_IGDG_IG         0xA001
+#define PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB        0xA010
+#define PCI_DEVICE_ID_INTEL_PINEVIEW_M_IG        0xA011
+#define PCI_DEVICE_ID_INTEL_PINEVIEW_HB         0xA000
+#define PCI_DEVICE_ID_INTEL_PINEVIEW_IG         0xA001
 #define PCI_DEVICE_ID_INTEL_G33_HB          0x29C0
 #define PCI_DEVICE_ID_INTEL_G33_IG          0x29C2
 #define PCI_DEVICE_ID_INTEL_Q35_HB          0x29B0
@@ -50,20 +50,20 @@
 #define PCI_DEVICE_ID_INTEL_B43_IG          0x2E42
 #define PCI_DEVICE_ID_INTEL_GM45_HB         0x2A40
 #define PCI_DEVICE_ID_INTEL_GM45_IG         0x2A42
-#define PCI_DEVICE_ID_INTEL_IGD_E_HB        0x2E00
-#define PCI_DEVICE_ID_INTEL_IGD_E_IG        0x2E02
+#define PCI_DEVICE_ID_INTEL_EAGLELAKE_HB        0x2E00
+#define PCI_DEVICE_ID_INTEL_EAGLELAKE_IG        0x2E02
 #define PCI_DEVICE_ID_INTEL_Q45_HB          0x2E10
 #define PCI_DEVICE_ID_INTEL_Q45_IG          0x2E12
 #define PCI_DEVICE_ID_INTEL_G45_HB          0x2E20
 #define PCI_DEVICE_ID_INTEL_G45_IG          0x2E22
 #define PCI_DEVICE_ID_INTEL_G41_HB          0x2E30
 #define PCI_DEVICE_ID_INTEL_G41_IG          0x2E32
-#define PCI_DEVICE_ID_INTEL_IGDNG_D_HB	    0x0040
-#define PCI_DEVICE_ID_INTEL_IGDNG_D_IG	    0x0042
-#define PCI_DEVICE_ID_INTEL_IGDNG_M_HB	    0x0044
-#define PCI_DEVICE_ID_INTEL_IGDNG_MA_HB	    0x0062
-#define PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB    0x006a
-#define PCI_DEVICE_ID_INTEL_IGDNG_M_IG	    0x0046
+#define PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB	    0x0040
+#define PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG	    0x0042
+#define PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB	    0x0044
+#define PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB	    0x0062
+#define PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB    0x006a
+#define PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG	    0x0046
 
 /* cover 915 and 945 variants */
 #define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \
@@ -83,22 +83,22 @@
 #define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \
 		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \
 		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q33_HB || \
-		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDGM_HB || \
-		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDG_HB)
+		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB || \
+		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB)
 
-#define IS_IGD (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDGM_HB || \
-		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDG_HB)
+#define IS_PINEVIEW (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB || \
+		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB)
 
-#define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_E_HB || \
+#define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_EAGLELAKE_HB || \
 		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \
 		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \
 		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB || \
 		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G41_HB || \
 		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_B43_HB || \
-		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_D_HB || \
-		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB || \
-		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB || \
-		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB)
+		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB || \
+		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB || \
+		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB || \
+		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB)
 
 extern int agp_memory_reserved;
 
@@ -178,6 +178,7 @@
 	 * popup and for the GTT.
 	 */
 	int gtt_entries;			/* i830+ */
+	int gtt_total_size;
 	union {
 		void __iomem *i9xx_flush_page;
 		void *i8xx_flush_page;
@@ -653,7 +654,7 @@
 			size = 512;
 		}
 		size += 4; /* add in BIOS popup space */
-	} else if (IS_G33 && !IS_IGD) {
+	} else if (IS_G33 && !IS_PINEVIEW) {
 	/* G33's GTT size defined in gmch_ctrl */
 		switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) {
 		case G33_PGETBL_SIZE_1M:
@@ -669,7 +670,7 @@
 			size = 512;
 		}
 		size += 4;
-	} else if (IS_G4X || IS_IGD) {
+	} else if (IS_G4X || IS_PINEVIEW) {
 		/* On 4 series hardware, GTT stolen is separate from graphics
 		 * stolen, ignore it in stolen gtt entries counting.  However,
 		 * 4KB of the stolen memory doesn't get mapped to the GTT.
@@ -1153,7 +1154,7 @@
 	readl(intel_private.registers+I810_PGETBL_CTL);	/* PCI Posting. */
 
 	if (agp_bridge->driver->needs_scratch_page) {
-		for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) {
+		for (i = intel_private.gtt_entries; i < intel_private.gtt_total_size; i++) {
 			writel(agp_bridge->scratch_page, intel_private.gtt+i);
 		}
 		readl(intel_private.gtt+i-1);	/* PCI Posting. */
@@ -1308,6 +1309,8 @@
 	if (!intel_private.gtt)
 		return -ENOMEM;
 
+	intel_private.gtt_total_size = gtt_map_size / 4;
+
 	temp &= 0xfff80000;
 
 	intel_private.registers = ioremap(temp, 128 * 4096);
@@ -1352,15 +1355,15 @@
 {
 	switch (agp_bridge->dev->device) {
 	case PCI_DEVICE_ID_INTEL_GM45_HB:
-	case PCI_DEVICE_ID_INTEL_IGD_E_HB:
+	case PCI_DEVICE_ID_INTEL_EAGLELAKE_HB:
 	case PCI_DEVICE_ID_INTEL_Q45_HB:
 	case PCI_DEVICE_ID_INTEL_G45_HB:
 	case PCI_DEVICE_ID_INTEL_G41_HB:
 	case PCI_DEVICE_ID_INTEL_B43_HB:
-	case PCI_DEVICE_ID_INTEL_IGDNG_D_HB:
-	case PCI_DEVICE_ID_INTEL_IGDNG_M_HB:
-	case PCI_DEVICE_ID_INTEL_IGDNG_MA_HB:
-	case PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB:
+	case PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB:
+	case PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB:
+	case PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB:
+	case PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB:
 		*gtt_offset = *gtt_size = MB(2);
 		break;
 	default:
@@ -1395,6 +1398,8 @@
 	if (!intel_private.gtt)
 		return -ENOMEM;
 
+	intel_private.gtt_total_size = gtt_size / 4;
+
 	intel_private.registers = ioremap(temp, 128 * 4096);
 	if (!intel_private.registers) {
 		iounmap(intel_private.gtt);
@@ -2340,14 +2345,14 @@
 		NULL, &intel_g33_driver },
 	{ PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, 0, "Q33",
 		NULL, &intel_g33_driver },
-	{ PCI_DEVICE_ID_INTEL_IGDGM_HB, PCI_DEVICE_ID_INTEL_IGDGM_IG, 0, "IGD",
+	{ PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB, PCI_DEVICE_ID_INTEL_PINEVIEW_M_IG, 0, "Pineview",
 		NULL, &intel_g33_driver },
-	{ PCI_DEVICE_ID_INTEL_IGDG_HB, PCI_DEVICE_ID_INTEL_IGDG_IG, 0, "IGD",
+	{ PCI_DEVICE_ID_INTEL_PINEVIEW_HB, PCI_DEVICE_ID_INTEL_PINEVIEW_IG, 0, "Pineview",
 		NULL, &intel_g33_driver },
 	{ PCI_DEVICE_ID_INTEL_GM45_HB, PCI_DEVICE_ID_INTEL_GM45_IG, 0,
-	    "Mobile Intel® GM45 Express", NULL, &intel_i965_driver },
-	{ PCI_DEVICE_ID_INTEL_IGD_E_HB, PCI_DEVICE_ID_INTEL_IGD_E_IG, 0,
-	    "Intel Integrated Graphics Device", NULL, &intel_i965_driver },
+	    "GM45", NULL, &intel_i965_driver },
+	{ PCI_DEVICE_ID_INTEL_EAGLELAKE_HB, PCI_DEVICE_ID_INTEL_EAGLELAKE_IG, 0,
+	    "Eaglelake", NULL, &intel_i965_driver },
 	{ PCI_DEVICE_ID_INTEL_Q45_HB, PCI_DEVICE_ID_INTEL_Q45_IG, 0,
 	    "Q45/Q43", NULL, &intel_i965_driver },
 	{ PCI_DEVICE_ID_INTEL_G45_HB, PCI_DEVICE_ID_INTEL_G45_IG, 0,
@@ -2356,14 +2361,14 @@
 	    "B43", NULL, &intel_i965_driver },
 	{ PCI_DEVICE_ID_INTEL_G41_HB, PCI_DEVICE_ID_INTEL_G41_IG, 0,
 	    "G41", NULL, &intel_i965_driver },
-	{ PCI_DEVICE_ID_INTEL_IGDNG_D_HB, PCI_DEVICE_ID_INTEL_IGDNG_D_IG, 0,
-	    "IGDNG/D", NULL, &intel_i965_driver },
-	{ PCI_DEVICE_ID_INTEL_IGDNG_M_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
-	    "IGDNG/M", NULL, &intel_i965_driver },
-	{ PCI_DEVICE_ID_INTEL_IGDNG_MA_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
-	    "IGDNG/MA", NULL, &intel_i965_driver },
-	{ PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
-	    "IGDNG/MC2", NULL, &intel_i965_driver },
+	{ PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG, 0,
+	    "Ironlake/D", NULL, &intel_i965_driver },
+	{ PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0,
+	    "Ironlake/M", NULL, &intel_i965_driver },
+	{ PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0,
+	    "Ironlake/MA", NULL, &intel_i965_driver },
+	{ PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0,
+	    "Ironlake/MC2", NULL, &intel_i965_driver },
 	{ 0, 0, 0, NULL, NULL, NULL }
 };
 
@@ -2545,8 +2550,8 @@
 	ID(PCI_DEVICE_ID_INTEL_82945G_HB),
 	ID(PCI_DEVICE_ID_INTEL_82945GM_HB),
 	ID(PCI_DEVICE_ID_INTEL_82945GME_HB),
-	ID(PCI_DEVICE_ID_INTEL_IGDGM_HB),
-	ID(PCI_DEVICE_ID_INTEL_IGDG_HB),
+	ID(PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB),
+	ID(PCI_DEVICE_ID_INTEL_PINEVIEW_HB),
 	ID(PCI_DEVICE_ID_INTEL_82946GZ_HB),
 	ID(PCI_DEVICE_ID_INTEL_82G35_HB),
 	ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
@@ -2557,15 +2562,15 @@
 	ID(PCI_DEVICE_ID_INTEL_Q35_HB),
 	ID(PCI_DEVICE_ID_INTEL_Q33_HB),
 	ID(PCI_DEVICE_ID_INTEL_GM45_HB),
-	ID(PCI_DEVICE_ID_INTEL_IGD_E_HB),
+	ID(PCI_DEVICE_ID_INTEL_EAGLELAKE_HB),
 	ID(PCI_DEVICE_ID_INTEL_Q45_HB),
 	ID(PCI_DEVICE_ID_INTEL_G45_HB),
 	ID(PCI_DEVICE_ID_INTEL_G41_HB),
 	ID(PCI_DEVICE_ID_INTEL_B43_HB),
-	ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB),
-	ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB),
-	ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB),
-	ID(PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB),
+	ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB),
+	ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB),
+	ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB),
+	ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB),
 	{ }
 };
 
diff --git a/drivers/char/bfin_jtag_comm.c b/drivers/char/bfin_jtag_comm.c
index 1d7c34c..2628c74 100644
--- a/drivers/char/bfin_jtag_comm.c
+++ b/drivers/char/bfin_jtag_comm.c
@@ -226,7 +226,7 @@
 	}
 }
 
-static struct tty_operations bfin_jc_ops = {
+static const struct tty_operations bfin_jc_ops = {
 	.open            = bfin_jc_open,
 	.close           = bfin_jc_close,
 	.write           = bfin_jc_write,
diff --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c
index 04ba906..4d830dc 100644
--- a/drivers/char/cs5535_gpio.c
+++ b/drivers/char/cs5535_gpio.c
@@ -17,7 +17,7 @@
 #include <linux/cdev.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
-#include <linux/smp_lock.h>
+
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
@@ -158,7 +158,6 @@
 {
 	u32 m = iminor(inode);
 
-	cycle_kernel_lock();
 	/* the mask says which pins are usable by this driver */
 	if ((mask & (1 << m)) == 0)
 		return -EINVAL;
diff --git a/drivers/char/efirtc.c b/drivers/char/efirtc.c
index 34d15d5..26a47dc 100644
--- a/drivers/char/efirtc.c
+++ b/drivers/char/efirtc.c
@@ -27,8 +27,6 @@
  * 	- Add module support
  */
 
-
-#include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/miscdevice.h>
@@ -174,13 +172,12 @@
 			return -EINVAL;
 
 		case RTC_RD_TIME:
-			lock_kernel();
 			spin_lock_irqsave(&efi_rtc_lock, flags);
 
 			status = efi.get_time(&eft, &cap);
 
 			spin_unlock_irqrestore(&efi_rtc_lock,flags);
-			unlock_kernel();
+
 			if (status != EFI_SUCCESS) {
 				/* should never happen */
 				printk(KERN_ERR "efitime: can't read time\n");
@@ -202,13 +199,11 @@
 
 			convert_to_efi_time(&wtime, &eft);
 
-			lock_kernel();
 			spin_lock_irqsave(&efi_rtc_lock, flags);
 
 			status = efi.set_time(&eft);
 
 			spin_unlock_irqrestore(&efi_rtc_lock,flags);
-			unlock_kernel();
 
 			return status == EFI_SUCCESS ? 0 : -EINVAL;
 
@@ -224,7 +219,6 @@
 
 			convert_to_efi_time(&wtime, &eft);
 
-			lock_kernel();
 			spin_lock_irqsave(&efi_rtc_lock, flags);
 			/*
 			 * XXX Fixme:
@@ -235,19 +229,16 @@
 			status = efi.set_wakeup_time((efi_bool_t)enabled, &eft);
 
 			spin_unlock_irqrestore(&efi_rtc_lock,flags);
-			unlock_kernel();
 
 			return status == EFI_SUCCESS ? 0 : -EINVAL;
 
 		case RTC_WKALM_RD:
 
-			lock_kernel();
 			spin_lock_irqsave(&efi_rtc_lock, flags);
 
 			status = efi.get_wakeup_time((efi_bool_t *)&enabled, (efi_bool_t *)&pending, &eft);
 
 			spin_unlock_irqrestore(&efi_rtc_lock,flags);
-			unlock_kernel();
 
 			if (status != EFI_SUCCESS) return -EINVAL;
 
@@ -277,7 +268,6 @@
 	 * We do accept multiple open files at the same time as we
 	 * synchronize on the per call operation.
 	 */
-	cycle_kernel_lock();
 	return 0;
 }
 
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index dde5134..17b044a 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -935,7 +935,7 @@
 	return 0;
 }
 
-static struct tty_operations info_ops = {
+static const struct tty_operations info_ops = {
 	.open = info_open,
 	.ioctl = info_ioctl,
 };
diff --git a/drivers/char/esp.c b/drivers/char/esp.c
deleted file mode 100644
index b19d43c..0000000
--- a/drivers/char/esp.c
+++ /dev/null
@@ -1,2533 +0,0 @@
-/*
- *  esp.c - driver for Hayes ESP serial cards
- *
- *  --- Notices from serial.c, upon which this driver is based ---
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- *
- *  Extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92.  Now
- *  much more extensible to support other serial cards based on the
- *  16450/16550A UART's.  Added support for the AST FourPort and the
- *  Accent Async board.
- *
- *  set_serial_info fixed to set the flags, custom divisor, and uart
- * 	type fields.  Fix suggested by Michael K. Johnson 12/12/92.
- *
- *  11/95: TIOCMIWAIT, TIOCGICOUNT by Angelo Haritsis <ah@doc.ic.ac.uk>
- *
- *  03/96: Modularised by Angelo Haritsis <ah@doc.ic.ac.uk>
- *
- *  rs_set_termios fixed to look also for changes of the input
- *      flags INPCK, BRKINT, PARMRK, IGNPAR and IGNBRK.
- *                                            Bernd Anhäupl 05/17/96.
- *
- * --- End of notices from serial.c ---
- *
- * Support for the ESP serial card by Andrew J. Robinson
- *     <arobinso@nyx.net> (Card detection routine taken from a patch
- *     by Dennis J. Boylan).  Patches to allow use with 2.1.x contributed
- *     by Chris Faylor.
- *
- * Most recent changes: (Andrew J. Robinson)
- *   Support for PIO mode.  This allows the driver to work properly with
- *     multiport cards.
- *
- * Arnaldo Carvalho de Melo <acme@conectiva.com.br> -
- * several cleanups, use module_init/module_exit, etc
- *
- * This module exports the following rs232 io functions:
- *
- *	int espserial_init(void);
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/serial.h>
-#include <linux/serialP.h>
-#include <linux/serial_reg.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/fcntl.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-
-#include <asm/system.h>
-#include <linux/io.h>
-
-#include <asm/dma.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-
-#include <linux/hayesesp.h>
-
-#define NR_PORTS 64	/* maximum number of ports */
-#define NR_PRIMARY 8	/* maximum number of primary ports */
-#define REGION_SIZE 8   /* size of io region to request */
-
-/* The following variables can be set by giving module options */
-static int irq[NR_PRIMARY];	/* IRQ for each base port */
-static unsigned int divisor[NR_PRIMARY]; /* custom divisor for each port */
-static unsigned int dma = ESP_DMA_CHANNEL; /* DMA channel */
-static unsigned int rx_trigger = ESP_RX_TRIGGER;
-static unsigned int tx_trigger = ESP_TX_TRIGGER;
-static unsigned int flow_off = ESP_FLOW_OFF;
-static unsigned int flow_on = ESP_FLOW_ON;
-static unsigned int rx_timeout = ESP_RX_TMOUT;
-static unsigned int pio_threshold = ESP_PIO_THRESHOLD;
-
-MODULE_LICENSE("GPL");
-
-module_param_array(irq, int, NULL, 0);
-module_param_array(divisor, uint, NULL, 0);
-module_param(dma, uint, 0);
-module_param(rx_trigger, uint, 0);
-module_param(tx_trigger, uint, 0);
-module_param(flow_off, uint, 0);
-module_param(flow_on, uint, 0);
-module_param(rx_timeout, uint, 0);
-module_param(pio_threshold, uint, 0);
-
-/* END */
-
-static char *dma_buffer;
-static int dma_bytes;
-static struct esp_pio_buffer *free_pio_buf;
-
-#define DMA_BUFFER_SZ 1024
-
-#define WAKEUP_CHARS 1024
-
-static char serial_name[] __initdata = "ESP serial driver";
-static char serial_version[] __initdata = "2.2";
-
-static struct tty_driver *esp_driver;
-
-/*
- * Serial driver configuration section.  Here are the various options:
- *
- * SERIAL_PARANOIA_CHECK
- * 		Check the magic number for the esp_structure where
- * 		ever possible.
- */
-
-#undef SERIAL_PARANOIA_CHECK
-#define SERIAL_DO_RESTART
-
-#undef SERIAL_DEBUG_INTR
-#undef SERIAL_DEBUG_OPEN
-#undef SERIAL_DEBUG_FLOW
-
-#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
-#define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
-				tty->name, info->port.flags, \
-				serial_driver.refcount, \
-				info->port.count, tty->count, s)
-#else
-#define DBG_CNT(s)
-#endif
-
-static struct esp_struct *ports;
-
-static void change_speed(struct esp_struct *info);
-static void rs_wait_until_sent(struct tty_struct *, int);
-
-/*
- * The ESP card has a clock rate of 14.7456 MHz (that is, 2**ESPC_SCALE
- * times the normal 1.8432 Mhz clock of most serial boards).
- */
-#define BASE_BAUD ((1843200 / 16) * (1 << ESPC_SCALE))
-
-/* Standard COM flags (except for COM4, because of the 8514 problem) */
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-
-static inline int serial_paranoia_check(struct esp_struct *info,
-					char *name, const char *routine)
-{
-#ifdef SERIAL_PARANOIA_CHECK
-	static const char badmagic[] = KERN_WARNING
-		"Warning: bad magic number for serial struct (%s) in %s\n";
-	static const char badinfo[] = KERN_WARNING
-		"Warning: null esp_struct for (%s) in %s\n";
-
-	if (!info) {
-		printk(badinfo, name, routine);
-		return 1;
-	}
-	if (info->magic != ESP_MAGIC) {
-		printk(badmagic, name, routine);
-		return 1;
-	}
-#endif
-	return 0;
-}
-
-static inline unsigned int serial_in(struct esp_struct *info, int offset)
-{
-	return inb(info->io_port + offset);
-}
-
-static inline void serial_out(struct esp_struct *info, int offset,
-			      unsigned char value)
-{
-	outb(value, info->io_port+offset);
-}
-
-/*
- * ------------------------------------------------------------
- * rs_stop() and rs_start()
- *
- * This routines are called before setting or resetting tty->stopped.
- * They enable or disable transmitter interrupts, as necessary.
- * ------------------------------------------------------------
- */
-static void rs_stop(struct tty_struct *tty)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, "rs_stop"))
-		return;
-
-	spin_lock_irqsave(&info->lock, flags);
-	if (info->IER & UART_IER_THRI) {
-		info->IER &= ~UART_IER_THRI;
-		serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-		serial_out(info, UART_ESI_CMD2, info->IER);
-	}
-	spin_unlock_irqrestore(&info->lock, flags);
-}
-
-static void rs_start(struct tty_struct *tty)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, "rs_start"))
-		return;
-
-	spin_lock_irqsave(&info->lock, flags);
-	if (info->xmit_cnt && info->xmit_buf && !(info->IER & UART_IER_THRI)) {
-		info->IER |= UART_IER_THRI;
-		serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-		serial_out(info, UART_ESI_CMD2, info->IER);
-	}
-	spin_unlock_irqrestore(&info->lock, flags);
-}
-
-/*
- * ----------------------------------------------------------------------
- *
- * Here starts the interrupt handling routines.  All of the following
- * subroutines are declared as inline and are folded into
- * rs_interrupt().  They were separated out for readability's sake.
- *
- * Note: rs_interrupt() is a "fast" interrupt, which means that it
- * runs with interrupts turned off.  People who may want to modify
- * rs_interrupt() should try to keep the interrupt handler as fast as
- * possible.  After you are done making modifications, it is not a bad
- * idea to do:
- *
- * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
- *
- * and look at the resulting assemble code in serial.s.
- *
- * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
- * -----------------------------------------------------------------------
- */
-
-static DEFINE_SPINLOCK(pio_lock);
-
-static inline struct esp_pio_buffer *get_pio_buffer(void)
-{
-	struct esp_pio_buffer *buf;
-	unsigned long flags;
-
-	spin_lock_irqsave(&pio_lock, flags);
-	if (free_pio_buf) {
-		buf = free_pio_buf;
-		free_pio_buf = buf->next;
-	} else {
-		buf = kmalloc(sizeof(struct esp_pio_buffer), GFP_ATOMIC);
-	}
-	spin_unlock_irqrestore(&pio_lock, flags);
-	return buf;
-}
-
-static inline void release_pio_buffer(struct esp_pio_buffer *buf)
-{
-	unsigned long flags;
-	spin_lock_irqsave(&pio_lock, flags);
-	buf->next = free_pio_buf;
-	free_pio_buf = buf;
-	spin_unlock_irqrestore(&pio_lock, flags);
-}
-
-static inline void receive_chars_pio(struct esp_struct *info, int num_bytes)
-{
-	struct tty_struct *tty = info->port.tty;
-	int i;
-	struct esp_pio_buffer *pio_buf;
-	struct esp_pio_buffer *err_buf;
-	unsigned char status_mask;
-
-	pio_buf = get_pio_buffer();
-
-	if (!pio_buf)
-		return;
-
-	err_buf = get_pio_buffer();
-
-	if (!err_buf) {
-		release_pio_buffer(pio_buf);
-		return;
-	}
-
-	status_mask = (info->read_status_mask >> 2) & 0x07;
-
-	for (i = 0; i < num_bytes - 1; i += 2) {
-		*((unsigned short *)(pio_buf->data + i)) =
-			inw(info->io_port + UART_ESI_RX);
-		err_buf->data[i] = serial_in(info, UART_ESI_RWS);
-		err_buf->data[i + 1] = (err_buf->data[i] >> 3) & status_mask;
-		err_buf->data[i] &= status_mask;
-	}
-
-	if (num_bytes & 0x0001) {
-		pio_buf->data[num_bytes - 1] = serial_in(info, UART_ESI_RX);
-		err_buf->data[num_bytes - 1] =
-			(serial_in(info, UART_ESI_RWS) >> 3) & status_mask;
-	}
-
-	/* make sure everything is still ok since interrupts were enabled */
-	tty = info->port.tty;
-
-	if (!tty) {
-		release_pio_buffer(pio_buf);
-		release_pio_buffer(err_buf);
-		info->stat_flags &= ~ESP_STAT_RX_TIMEOUT;
-		return;
-	}
-
-	status_mask = (info->ignore_status_mask >> 2) & 0x07;
-
-	for (i = 0; i < num_bytes; i++) {
-		if (!(err_buf->data[i] & status_mask)) {
-			int flag = 0;
-
-			if (err_buf->data[i] & 0x04) {
-				flag = TTY_BREAK;
-				if (info->port.flags & ASYNC_SAK)
-					do_SAK(tty);
-			} else if (err_buf->data[i] & 0x02)
-				flag = TTY_FRAME;
-			else if (err_buf->data[i] & 0x01)
-				flag = TTY_PARITY;
-			tty_insert_flip_char(tty, pio_buf->data[i], flag);
-		}
-	}
-
-	tty_schedule_flip(tty);
-
-	info->stat_flags &= ~ESP_STAT_RX_TIMEOUT;
-	release_pio_buffer(pio_buf);
-	release_pio_buffer(err_buf);
-}
-
-static void program_isa_dma(int dma, int dir, unsigned long addr, int len)
-{
-	unsigned long flags;
-
-	flags = claim_dma_lock();
-	disable_dma(dma);
-	clear_dma_ff(dma);
-	set_dma_mode(dma, dir);
-	set_dma_addr(dma, addr);
-	set_dma_count(dma, len);
-	enable_dma(dma);
-	release_dma_lock(flags);
-}
-
-static void receive_chars_dma(struct esp_struct *info, int num_bytes)
-{
-	info->stat_flags &= ~ESP_STAT_RX_TIMEOUT;
-	dma_bytes = num_bytes;
-	info->stat_flags |= ESP_STAT_DMA_RX;
-
-	program_isa_dma(dma, DMA_MODE_READ, isa_virt_to_bus(dma_buffer),
-								dma_bytes);
-	serial_out(info, UART_ESI_CMD1, ESI_START_DMA_RX);
-}
-
-static inline void receive_chars_dma_done(struct esp_struct *info,
-					    int status)
-{
-	struct tty_struct *tty = info->port.tty;
-	int num_bytes;
-	unsigned long flags;
-
-	flags = claim_dma_lock();
-	disable_dma(dma);
-	clear_dma_ff(dma);
-
-	info->stat_flags &= ~ESP_STAT_DMA_RX;
-	num_bytes = dma_bytes - get_dma_residue(dma);
-	release_dma_lock(flags);
-
-	info->icount.rx += num_bytes;
-
-	if (num_bytes > 0) {
-		tty_insert_flip_string(tty, dma_buffer, num_bytes - 1);
-
-		status &= (0x1c & info->read_status_mask);
-
-		/* Is the status significant or do we throw the last byte ? */
-		if (!(status & info->ignore_status_mask)) {
-			int statflag = 0;
-
-			if (status & 0x10) {
-				statflag = TTY_BREAK;
-				(info->icount.brk)++;
-				if (info->port.flags & ASYNC_SAK)
-					do_SAK(tty);
-			} else if (status & 0x08) {
-				statflag = TTY_FRAME;
-				info->icount.frame++;
-			} else if (status & 0x04) {
-				statflag = TTY_PARITY;
-				info->icount.parity++;
-			}
-			tty_insert_flip_char(tty, dma_buffer[num_bytes - 1],
-								statflag);
-		}
-		tty_schedule_flip(tty);
-	}
-
-	if (dma_bytes != num_bytes) {
-		num_bytes = dma_bytes - num_bytes;
-		dma_bytes = 0;
-		receive_chars_dma(info, num_bytes);
-	} else
-		dma_bytes = 0;
-}
-
-/* Caller must hold info->lock */
-
-static inline void transmit_chars_pio(struct esp_struct *info,
-					int space_avail)
-{
-	int i;
-	struct esp_pio_buffer *pio_buf;
-
-	pio_buf = get_pio_buffer();
-
-	if (!pio_buf)
-		return;
-
-	while (space_avail && info->xmit_cnt) {
-		if (info->xmit_tail + space_avail <= ESP_XMIT_SIZE) {
-			memcpy(pio_buf->data,
-			       &(info->xmit_buf[info->xmit_tail]),
-			       space_avail);
-		} else {
-			i = ESP_XMIT_SIZE - info->xmit_tail;
-			memcpy(pio_buf->data,
-			       &(info->xmit_buf[info->xmit_tail]), i);
-			memcpy(&(pio_buf->data[i]), info->xmit_buf,
-			       space_avail - i);
-		}
-
-		info->xmit_cnt -= space_avail;
-		info->xmit_tail = (info->xmit_tail + space_avail) &
-			(ESP_XMIT_SIZE - 1);
-
-		for (i = 0; i < space_avail - 1; i += 2) {
-			outw(*((unsigned short *)(pio_buf->data + i)),
-			     info->io_port + UART_ESI_TX);
-		}
-
-		if (space_avail & 0x0001)
-			serial_out(info, UART_ESI_TX,
-				   pio_buf->data[space_avail - 1]);
-
-		if (info->xmit_cnt) {
-			serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND);
-			serial_out(info, UART_ESI_CMD1, ESI_GET_TX_AVAIL);
-			space_avail = serial_in(info, UART_ESI_STAT1) << 8;
-			space_avail |= serial_in(info, UART_ESI_STAT2);
-
-			if (space_avail > info->xmit_cnt)
-				space_avail = info->xmit_cnt;
-		}
-	}
-
-	if (info->xmit_cnt < WAKEUP_CHARS) {
-		if (info->port.tty)
-			tty_wakeup(info->port.tty);
-
-#ifdef SERIAL_DEBUG_INTR
-		printk("THRE...");
-#endif
-
-		if (info->xmit_cnt <= 0) {
-			info->IER &= ~UART_IER_THRI;
-			serial_out(info, UART_ESI_CMD1,
-				   ESI_SET_SRV_MASK);
-			serial_out(info, UART_ESI_CMD2, info->IER);
-		}
-	}
-
-	release_pio_buffer(pio_buf);
-}
-
-/* Caller must hold info->lock */
-static inline void transmit_chars_dma(struct esp_struct *info, int num_bytes)
-{
-	dma_bytes = num_bytes;
-
-	if (info->xmit_tail + dma_bytes <= ESP_XMIT_SIZE) {
-		memcpy(dma_buffer, &(info->xmit_buf[info->xmit_tail]),
-		       dma_bytes);
-	} else {
-		int i = ESP_XMIT_SIZE - info->xmit_tail;
-		memcpy(dma_buffer, &(info->xmit_buf[info->xmit_tail]),
-			i);
-		memcpy(&(dma_buffer[i]), info->xmit_buf, dma_bytes - i);
-	}
-
-	info->xmit_cnt -= dma_bytes;
-	info->xmit_tail = (info->xmit_tail + dma_bytes) & (ESP_XMIT_SIZE - 1);
-
-	if (info->xmit_cnt < WAKEUP_CHARS) {
-		if (info->port.tty)
-			tty_wakeup(info->port.tty);
-
-#ifdef SERIAL_DEBUG_INTR
-		printk("THRE...");
-#endif
-
-		if (info->xmit_cnt <= 0) {
-			info->IER &= ~UART_IER_THRI;
-			serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-			serial_out(info, UART_ESI_CMD2, info->IER);
-		}
-	}
-
-	info->stat_flags |= ESP_STAT_DMA_TX;
-
-	program_isa_dma(dma, DMA_MODE_WRITE, isa_virt_to_bus(dma_buffer),
-								dma_bytes);
-	serial_out(info, UART_ESI_CMD1, ESI_START_DMA_TX);
-}
-
-static inline void transmit_chars_dma_done(struct esp_struct *info)
-{
-	int num_bytes;
-	unsigned long flags;
-
-	flags = claim_dma_lock();
-	disable_dma(dma);
-	clear_dma_ff(dma);
-
-	num_bytes = dma_bytes - get_dma_residue(dma);
-	info->icount.tx += dma_bytes;
-	release_dma_lock(flags);
-
-	if (dma_bytes != num_bytes) {
-		dma_bytes -= num_bytes;
-		memmove(dma_buffer, dma_buffer + num_bytes, dma_bytes);
-
-		program_isa_dma(dma, DMA_MODE_WRITE,
-				isa_virt_to_bus(dma_buffer), dma_bytes);
-
-		serial_out(info, UART_ESI_CMD1, ESI_START_DMA_TX);
-	} else {
-		dma_bytes = 0;
-		info->stat_flags &= ~ESP_STAT_DMA_TX;
-	}
-}
-
-static void check_modem_status(struct esp_struct *info)
-{
-	int	status;
-
-	serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT);
-	status = serial_in(info, UART_ESI_STAT2);
-
-	if (status & UART_MSR_ANY_DELTA) {
-		/* update input line counters */
-		if (status & UART_MSR_TERI)
-			info->icount.rng++;
-		if (status & UART_MSR_DDSR)
-			info->icount.dsr++;
-		if (status & UART_MSR_DDCD)
-			info->icount.dcd++;
-		if (status & UART_MSR_DCTS)
-			info->icount.cts++;
-		wake_up_interruptible(&info->port.delta_msr_wait);
-	}
-
-	if ((info->port.flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
-#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
-		printk("ttys%d CD now %s...", info->line,
-		       (status & UART_MSR_DCD) ? "on" : "off");
-#endif
-		if (status & UART_MSR_DCD)
-			wake_up_interruptible(&info->port.open_wait);
-		else {
-#ifdef SERIAL_DEBUG_OPEN
-			printk("scheduling hangup...");
-#endif
-			tty_hangup(info->port.tty);
-		}
-	}
-}
-
-/*
- * This is the serial driver's interrupt routine
- */
-static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
-{
-	struct esp_struct *info;
-	unsigned err_status;
-	unsigned int scratch;
-
-#ifdef SERIAL_DEBUG_INTR
-	printk("rs_interrupt_single(%d)...", irq);
-#endif
-	info = (struct esp_struct *)dev_id;
-	err_status = 0;
-	scratch = serial_in(info, UART_ESI_SID);
-
-	spin_lock(&info->lock);
-
-	if (!info->port.tty) {
-		spin_unlock(&info->lock);
-		return IRQ_NONE;
-	}
-
-	if (scratch & 0x04) { /* error */
-		serial_out(info, UART_ESI_CMD1, ESI_GET_ERR_STAT);
-		err_status = serial_in(info, UART_ESI_STAT1);
-		serial_in(info, UART_ESI_STAT2);
-
-		if (err_status & 0x01)
-			info->stat_flags |= ESP_STAT_RX_TIMEOUT;
-
-		if (err_status & 0x20) /* UART status */
-			check_modem_status(info);
-
-		if (err_status & 0x80) /* Start break */
-			wake_up_interruptible(&info->break_wait);
-	}
-
-	if ((scratch & 0x88) || /* DMA completed or timed out */
-	    (err_status & 0x1c) /* receive error */) {
-		if (info->stat_flags & ESP_STAT_DMA_RX)
-			receive_chars_dma_done(info, err_status);
-		else if (info->stat_flags & ESP_STAT_DMA_TX)
-			transmit_chars_dma_done(info);
-	}
-
-	if (!(info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) &&
-	    ((scratch & 0x01) || (info->stat_flags & ESP_STAT_RX_TIMEOUT)) &&
-	    (info->IER & UART_IER_RDI)) {
-		int num_bytes;
-
-		serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND);
-		serial_out(info, UART_ESI_CMD1, ESI_GET_RX_AVAIL);
-		num_bytes = serial_in(info, UART_ESI_STAT1) << 8;
-		num_bytes |= serial_in(info, UART_ESI_STAT2);
-
-		num_bytes = tty_buffer_request_room(info->port.tty, num_bytes);
-
-		if (num_bytes) {
-			if (dma_bytes ||
-			    (info->stat_flags & ESP_STAT_USE_PIO) ||
-			    (num_bytes <= info->config.pio_threshold))
-				receive_chars_pio(info, num_bytes);
-			else
-				receive_chars_dma(info, num_bytes);
-		}
-	}
-
-	if (!(info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) &&
-	    (scratch & 0x02) && (info->IER & UART_IER_THRI)) {
-		if ((info->xmit_cnt <= 0) || info->port.tty->stopped) {
-			info->IER &= ~UART_IER_THRI;
-			serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-			serial_out(info, UART_ESI_CMD2, info->IER);
-		} else {
-			int num_bytes;
-
-			serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND);
-			serial_out(info, UART_ESI_CMD1, ESI_GET_TX_AVAIL);
-			num_bytes = serial_in(info, UART_ESI_STAT1) << 8;
-			num_bytes |= serial_in(info, UART_ESI_STAT2);
-
-			if (num_bytes > info->xmit_cnt)
-				num_bytes = info->xmit_cnt;
-
-			if (num_bytes) {
-				if (dma_bytes ||
-				    (info->stat_flags & ESP_STAT_USE_PIO) ||
-				    (num_bytes <= info->config.pio_threshold))
-					transmit_chars_pio(info, num_bytes);
-				else
-					transmit_chars_dma(info, num_bytes);
-			}
-		}
-	}
-
-	info->last_active = jiffies;
-
-#ifdef SERIAL_DEBUG_INTR
-	printk("end.\n");
-#endif
-	spin_unlock(&info->lock);
-	return IRQ_HANDLED;
-}
-
-/*
- * -------------------------------------------------------------------
- * Here ends the serial interrupt routines.
- * -------------------------------------------------------------------
- */
-
-/*
- * ---------------------------------------------------------------
- * Low level utility subroutines for the serial driver:  routines to
- * figure out the appropriate timeout for an interrupt chain, routines
- * to initialize and startup a serial port, and routines to shutdown a
- * serial port.  Useful stuff like that.
- *
- * Caller should hold lock
- * ---------------------------------------------------------------
- */
-
-static void esp_basic_init(struct esp_struct *info)
-{
-	/* put ESPC in enhanced mode */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_MODE);
-
-	if (info->stat_flags & ESP_STAT_NEVER_DMA)
-		serial_out(info, UART_ESI_CMD2, 0x01);
-	else
-		serial_out(info, UART_ESI_CMD2, 0x31);
-
-	/* disable interrupts for now */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-	serial_out(info, UART_ESI_CMD2, 0x00);
-
-	/* set interrupt and DMA channel */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_IRQ);
-
-	if (info->stat_flags & ESP_STAT_NEVER_DMA)
-		serial_out(info, UART_ESI_CMD2, 0x01);
-	else
-		serial_out(info, UART_ESI_CMD2, (dma << 4) | 0x01);
-
-	serial_out(info, UART_ESI_CMD1, ESI_SET_ENH_IRQ);
-
-	if (info->line % 8)	/* secondary port */
-		serial_out(info, UART_ESI_CMD2, 0x0d);	/* shared */
-	else if (info->irq == 9)
-		serial_out(info, UART_ESI_CMD2, 0x02);
-	else
-		serial_out(info, UART_ESI_CMD2, info->irq);
-
-	/* set error status mask (check this) */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_ERR_MASK);
-
-	if (info->stat_flags & ESP_STAT_NEVER_DMA)
-		serial_out(info, UART_ESI_CMD2, 0xa1);
-	else
-		serial_out(info, UART_ESI_CMD2, 0xbd);
-
-	serial_out(info, UART_ESI_CMD2, 0x00);
-
-	/* set DMA timeout */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_DMA_TMOUT);
-	serial_out(info, UART_ESI_CMD2, 0xff);
-
-	/* set FIFO trigger levels */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_TRIGGER);
-	serial_out(info, UART_ESI_CMD2, info->config.rx_trigger >> 8);
-	serial_out(info, UART_ESI_CMD2, info->config.rx_trigger);
-	serial_out(info, UART_ESI_CMD2, info->config.tx_trigger >> 8);
-	serial_out(info, UART_ESI_CMD2, info->config.tx_trigger);
-
-	/* Set clock scaling and wait states */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_PRESCALAR);
-	serial_out(info, UART_ESI_CMD2, 0x04 | ESPC_SCALE);
-
-	/* set reinterrupt pacing */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_REINTR);
-	serial_out(info, UART_ESI_CMD2, 0xff);
-}
-
-static int startup(struct esp_struct *info)
-{
-	unsigned long flags;
-	int	retval = 0;
-	unsigned int num_chars;
-
-	spin_lock_irqsave(&info->lock, flags);
-
-	if (info->port.flags & ASYNC_INITIALIZED)
-		goto out;
-
-	if (!info->xmit_buf) {
-		info->xmit_buf = (unsigned char *)get_zeroed_page(GFP_ATOMIC);
-		retval = -ENOMEM;
-		if (!info->xmit_buf)
-			goto out;
-	}
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk(KERN_DEBUG "starting up ttys%d (irq %d)...",
-						info->line, info->irq);
-#endif
-
-	/* Flush the RX buffer.  Using the ESI flush command may cause */
-	/* wild interrupts, so read all the data instead. */
-
-	serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND);
-	serial_out(info, UART_ESI_CMD1, ESI_GET_RX_AVAIL);
-	num_chars = serial_in(info, UART_ESI_STAT1) << 8;
-	num_chars |= serial_in(info, UART_ESI_STAT2);
-
-	while (num_chars > 1) {
-		inw(info->io_port + UART_ESI_RX);
-		num_chars -= 2;
-	}
-
-	if (num_chars)
-		serial_in(info, UART_ESI_RX);
-
-	/* set receive character timeout */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_RX_TIMEOUT);
-	serial_out(info, UART_ESI_CMD2, info->config.rx_timeout);
-
-	/* clear all flags except the "never DMA" flag */
-	info->stat_flags &= ESP_STAT_NEVER_DMA;
-
-	if (info->stat_flags & ESP_STAT_NEVER_DMA)
-		info->stat_flags |= ESP_STAT_USE_PIO;
-
-	spin_unlock_irqrestore(&info->lock, flags);
-
-	/*
-	 * Allocate the IRQ
-	 */
-
-	retval = request_irq(info->irq, rs_interrupt_single, IRQF_SHARED,
-			     "esp serial", info);
-
-	if (retval) {
-		if (capable(CAP_SYS_ADMIN)) {
-			if (info->port.tty)
-				set_bit(TTY_IO_ERROR,
-					&info->port.tty->flags);
-			retval = 0;
-		}
-		goto out_unlocked;
-	}
-
-	if (!(info->stat_flags & ESP_STAT_USE_PIO) && !dma_buffer) {
-		dma_buffer = (char *)__get_dma_pages(
-			GFP_KERNEL, get_order(DMA_BUFFER_SZ));
-
-		/* use PIO mode if DMA buf/chan cannot be allocated */
-		if (!dma_buffer)
-			info->stat_flags |= ESP_STAT_USE_PIO;
-		else if (request_dma(dma, "esp serial")) {
-			free_pages((unsigned long)dma_buffer,
-				   get_order(DMA_BUFFER_SZ));
-			dma_buffer = NULL;
-			info->stat_flags |= ESP_STAT_USE_PIO;
-		}
-
-	}
-
-	info->MCR = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
-
-	spin_lock_irqsave(&info->lock, flags);
-	serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
-	serial_out(info, UART_ESI_CMD2, UART_MCR);
-	serial_out(info, UART_ESI_CMD2, info->MCR);
-
-	/*
-	 * Finally, enable interrupts
-	 */
-	/* info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI; */
-	info->IER = UART_IER_RLSI | UART_IER_RDI | UART_IER_DMA_TMOUT |
-			UART_IER_DMA_TC;
-	serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-	serial_out(info, UART_ESI_CMD2, info->IER);
-
-	if (info->port.tty)
-		clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
-	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-	spin_unlock_irqrestore(&info->lock, flags);
-
-	/*
-	 * Set up the tty->alt_speed kludge
-	 */
-	if (info->port.tty) {
-		if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
-			info->port.tty->alt_speed = 57600;
-		if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
-			info->port.tty->alt_speed = 115200;
-		if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
-			info->port.tty->alt_speed = 230400;
-		if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
-			info->port.tty->alt_speed = 460800;
-	}
-
-	/*
-	 * set the speed of the serial port
-	 */
-	change_speed(info);
-	info->port.flags |= ASYNC_INITIALIZED;
-	return 0;
-
-out:
-	spin_unlock_irqrestore(&info->lock, flags);
-out_unlocked:
-	return retval;
-}
-
-/*
- * This routine will shutdown a serial port; interrupts are disabled, and
- * DTR is dropped if the hangup on close termio flag is on.
- */
-static void shutdown(struct esp_struct *info)
-{
-	unsigned long	flags, f;
-
-	if (!(info->port.flags & ASYNC_INITIALIZED))
-		return;
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk("Shutting down serial port %d (irq %d)....", info->line,
-	       info->irq);
-#endif
-
-	spin_lock_irqsave(&info->lock, flags);
-	/*
-	 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
-	 * here so the queue might never be waken up
-	 */
-	wake_up_interruptible(&info->port.delta_msr_wait);
-	wake_up_interruptible(&info->break_wait);
-
-	/* stop a DMA transfer on the port being closed */
-	/* DMA lock is higher priority always */
-	if (info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) {
-		f = claim_dma_lock();
-		disable_dma(dma);
-		clear_dma_ff(dma);
-		release_dma_lock(f);
-
-		dma_bytes = 0;
-	}
-
-	/*
-	 * Free the IRQ
-	 */
-	free_irq(info->irq, info);
-
-	if (dma_buffer) {
-		struct esp_struct *current_port = ports;
-
-		while (current_port) {
-			if ((current_port != info) &&
-			    (current_port->port.flags & ASYNC_INITIALIZED))
-				break;
-
-			current_port = current_port->next_port;
-		}
-
-		if (!current_port) {
-			free_dma(dma);
-			free_pages((unsigned long)dma_buffer,
-				   get_order(DMA_BUFFER_SZ));
-			dma_buffer = NULL;
-		}
-	}
-
-	if (info->xmit_buf) {
-		free_page((unsigned long) info->xmit_buf);
-		info->xmit_buf = NULL;
-	}
-
-	info->IER = 0;
-	serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-	serial_out(info, UART_ESI_CMD2, 0x00);
-
-	if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL))
-		info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
-
-	info->MCR &= ~UART_MCR_OUT2;
-	serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
-	serial_out(info, UART_ESI_CMD2, UART_MCR);
-	serial_out(info, UART_ESI_CMD2, info->MCR);
-
-	if (info->port.tty)
-		set_bit(TTY_IO_ERROR, &info->port.tty->flags);
-
-	info->port.flags &= ~ASYNC_INITIALIZED;
-	spin_unlock_irqrestore(&info->lock, flags);
-}
-
-/*
- * This routine is called to set the UART divisor registers to match
- * the specified baud rate for a serial port.
- */
-static void change_speed(struct esp_struct *info)
-{
-	unsigned short port;
-	int	quot = 0;
-	unsigned cflag, cval;
-	int	baud, bits;
-	unsigned char flow1 = 0, flow2 = 0;
-	unsigned long flags;
-
-	if (!info->port.tty || !info->port.tty->termios)
-		return;
-	cflag = info->port.tty->termios->c_cflag;
-	port = info->io_port;
-
-	/* byte size and parity */
-	switch (cflag & CSIZE) {
-	case CS5: cval = 0x00; bits = 7; break;
-	case CS6: cval = 0x01; bits = 8; break;
-	case CS7: cval = 0x02; bits = 9; break;
-	case CS8: cval = 0x03; bits = 10; break;
-	default:  cval = 0x00; bits = 7; break;
-	}
-	if (cflag & CSTOPB) {
-		cval |= 0x04;
-		bits++;
-	}
-	if (cflag & PARENB) {
-		cval |= UART_LCR_PARITY;
-		bits++;
-	}
-	if (!(cflag & PARODD))
-		cval |= UART_LCR_EPAR;
-#ifdef CMSPAR
-	if (cflag & CMSPAR)
-		cval |= UART_LCR_SPAR;
-#endif
-	baud = tty_get_baud_rate(info->port.tty);
-	if (baud == 38400 &&
-		((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
-		quot = info->custom_divisor;
-	else {
-		if (baud == 134) /* Special case since 134 is really 134.5 */
-			quot = (2*BASE_BAUD / 269);
-		else if (baud)
-			quot = BASE_BAUD / baud;
-	}
-	/* If the quotient is ever zero, default to 9600 bps */
-	if (!quot)
-		quot = BASE_BAUD / 9600;
-
-	if (baud) {
-		/* Actual rate */
-		baud = BASE_BAUD/quot;
-		tty_encode_baud_rate(info->port.tty, baud, baud);
-	}
-	info->timeout = ((1024 * HZ * bits * quot) / BASE_BAUD) + (HZ / 50);
-
-	/* CTS flow control flag and modem status interrupts */
-	/* info->IER &= ~UART_IER_MSI; */
-	if (cflag & CRTSCTS) {
-		info->port.flags |= ASYNC_CTS_FLOW;
-		/* info->IER |= UART_IER_MSI; */
-		flow1 = 0x04;
-		flow2 = 0x10;
-	} else
-		info->port.flags &= ~ASYNC_CTS_FLOW;
-	if (cflag & CLOCAL)
-		info->port.flags &= ~ASYNC_CHECK_CD;
-	else
-		info->port.flags |= ASYNC_CHECK_CD;
-
-	/*
-	 * Set up parity check flag
-	 */
-	info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
-	if (I_INPCK(info->port.tty))
-		info->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
-	if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
-		info->read_status_mask |= UART_LSR_BI;
-
-	info->ignore_status_mask = 0;
-#if 0
-	/* This should be safe, but for some broken bits of hardware... */
-	if (I_IGNPAR(info->port.tty)) {
-		info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
-		info->read_status_mask |= UART_LSR_PE | UART_LSR_FE;
-	}
-#endif
-	if (I_IGNBRK(info->port.tty)) {
-		info->ignore_status_mask |= UART_LSR_BI;
-		info->read_status_mask |= UART_LSR_BI;
-		/*
-		 * If we're ignore parity and break indicators, ignore
-		 * overruns too.  (For real raw support).
-		 */
-		if (I_IGNPAR(info->port.tty)) {
-			info->ignore_status_mask |= UART_LSR_OE | \
-				UART_LSR_PE | UART_LSR_FE;
-			info->read_status_mask |= UART_LSR_OE | \
-				UART_LSR_PE | UART_LSR_FE;
-		}
-	}
-
-	if (I_IXOFF(info->port.tty))
-		flow1 |= 0x81;
-
-	spin_lock_irqsave(&info->lock, flags);
-	/* set baud */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_BAUD);
-	serial_out(info, UART_ESI_CMD2, quot >> 8);
-	serial_out(info, UART_ESI_CMD2, quot & 0xff);
-
-	/* set data bits, parity, etc. */
-	serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
-	serial_out(info, UART_ESI_CMD2, UART_LCR);
-	serial_out(info, UART_ESI_CMD2, cval);
-
-	/* Enable flow control */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_FLOW_CNTL);
-	serial_out(info, UART_ESI_CMD2, flow1);
-	serial_out(info, UART_ESI_CMD2, flow2);
-
-	/* set flow control characters (XON/XOFF only) */
-	if (I_IXOFF(info->port.tty)) {
-		serial_out(info, UART_ESI_CMD1, ESI_SET_FLOW_CHARS);
-		serial_out(info, UART_ESI_CMD2, START_CHAR(info->port.tty));
-		serial_out(info, UART_ESI_CMD2, STOP_CHAR(info->port.tty));
-		serial_out(info, UART_ESI_CMD2, 0x10);
-		serial_out(info, UART_ESI_CMD2, 0x21);
-		switch (cflag & CSIZE) {
-		case CS5:
-			serial_out(info, UART_ESI_CMD2, 0x1f);
-			break;
-		case CS6:
-			serial_out(info, UART_ESI_CMD2, 0x3f);
-			break;
-		case CS7:
-		case CS8:
-			serial_out(info, UART_ESI_CMD2, 0x7f);
-			break;
-		default:
-			serial_out(info, UART_ESI_CMD2, 0xff);
-			break;
-		}
-	}
-
-	/* Set high/low water */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_FLOW_LVL);
-	serial_out(info, UART_ESI_CMD2, info->config.flow_off >> 8);
-	serial_out(info, UART_ESI_CMD2, info->config.flow_off);
-	serial_out(info, UART_ESI_CMD2, info->config.flow_on >> 8);
-	serial_out(info, UART_ESI_CMD2, info->config.flow_on);
-
-	spin_unlock_irqrestore(&info->lock, flags);
-}
-
-static int rs_put_char(struct tty_struct *tty, unsigned char ch)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-	int ret = 0;
-
-	if (serial_paranoia_check(info, tty->name, "rs_put_char"))
-		return 0;
-
-	if (!info->xmit_buf)
-		return 0;
-
-	spin_lock_irqsave(&info->lock, flags);
-	if (info->xmit_cnt < ESP_XMIT_SIZE - 1) {
-		info->xmit_buf[info->xmit_head++] = ch;
-		info->xmit_head &= ESP_XMIT_SIZE-1;
-		info->xmit_cnt++;
-		ret = 1;
-	}
-	spin_unlock_irqrestore(&info->lock, flags);
-	return ret;
-}
-
-static void rs_flush_chars(struct tty_struct *tty)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, "rs_flush_chars"))
-		return;
-
-	spin_lock_irqsave(&info->lock, flags);
-
-	if (info->xmit_cnt <= 0 || tty->stopped || !info->xmit_buf)
-		goto out;
-
-	if (!(info->IER & UART_IER_THRI)) {
-		info->IER |= UART_IER_THRI;
-		serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-		serial_out(info, UART_ESI_CMD2, info->IER);
-	}
-out:
-	spin_unlock_irqrestore(&info->lock, flags);
-}
-
-static int rs_write(struct tty_struct *tty,
-		    const unsigned char *buf, int count)
-{
-	int	c, t, ret = 0;
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, "rs_write"))
-		return 0;
-
-	if (!info->xmit_buf)
-		return 0;
-
-	while (1) {
-		/* Thanks to R. Wolff for suggesting how to do this with */
-		/* interrupts enabled */
-
-		c = count;
-		t = ESP_XMIT_SIZE - info->xmit_cnt - 1;
-
-		if (t < c)
-			c = t;
-
-		t = ESP_XMIT_SIZE - info->xmit_head;
-
-		if (t < c)
-			c = t;
-
-		if (c <= 0)
-			break;
-
-		memcpy(info->xmit_buf + info->xmit_head, buf, c);
-
-		info->xmit_head = (info->xmit_head + c) & (ESP_XMIT_SIZE-1);
-		info->xmit_cnt += c;
-		buf += c;
-		count -= c;
-		ret += c;
-	}
-
-	spin_lock_irqsave(&info->lock, flags);
-
-	if (info->xmit_cnt && !tty->stopped && !(info->IER & UART_IER_THRI)) {
-		info->IER |= UART_IER_THRI;
-		serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-		serial_out(info, UART_ESI_CMD2, info->IER);
-	}
-
-	spin_unlock_irqrestore(&info->lock, flags);
-	return ret;
-}
-
-static int rs_write_room(struct tty_struct *tty)
-{
-	struct esp_struct *info = tty->driver_data;
-	int	ret;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, "rs_write_room"))
-		return 0;
-
-	spin_lock_irqsave(&info->lock, flags);
-
-	ret = ESP_XMIT_SIZE - info->xmit_cnt - 1;
-	if (ret < 0)
-		ret = 0;
-	spin_unlock_irqrestore(&info->lock, flags);
-	return ret;
-}
-
-static int rs_chars_in_buffer(struct tty_struct *tty)
-{
-	struct esp_struct *info = tty->driver_data;
-
-	if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer"))
-		return 0;
-	return info->xmit_cnt;
-}
-
-static void rs_flush_buffer(struct tty_struct *tty)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, "rs_flush_buffer"))
-		return;
-	spin_lock_irqsave(&info->lock, flags);
-	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-	spin_unlock_irqrestore(&info->lock, flags);
-	tty_wakeup(tty);
-}
-
-/*
- * ------------------------------------------------------------
- * rs_throttle()
- *
- * This routine is called by the upper-layer tty layer to signal that
- * incoming characters should be throttled.
- * ------------------------------------------------------------
- */
-static void rs_throttle(struct tty_struct *tty)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-#ifdef SERIAL_DEBUG_THROTTLE
-	char	buf[64];
-
-	printk("throttle %s: %d....\n", tty_name(tty, buf),
-						tty_chars_in_buffer(tty));
-#endif
-
-	if (serial_paranoia_check(info, tty->name, "rs_throttle"))
-		return;
-
-	spin_lock_irqsave(&info->lock, flags);
-	info->IER &= ~UART_IER_RDI;
-	serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-	serial_out(info, UART_ESI_CMD2, info->IER);
-	serial_out(info, UART_ESI_CMD1, ESI_SET_RX_TIMEOUT);
-	serial_out(info, UART_ESI_CMD2, 0x00);
-	spin_unlock_irqrestore(&info->lock, flags);
-}
-
-static void rs_unthrottle(struct tty_struct *tty)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-#ifdef SERIAL_DEBUG_THROTTLE
-	char	buf[64];
-
-	printk(KERN_DEBUG "unthrottle %s: %d....\n", tty_name(tty, buf),
-	       tty_chars_in_buffer(tty));
-#endif
-
-	if (serial_paranoia_check(info, tty->name, "rs_unthrottle"))
-		return;
-
-	spin_lock_irqsave(&info->lock, flags);
-	info->IER |= UART_IER_RDI;
-	serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-	serial_out(info, UART_ESI_CMD2, info->IER);
-	serial_out(info, UART_ESI_CMD1, ESI_SET_RX_TIMEOUT);
-	serial_out(info, UART_ESI_CMD2, info->config.rx_timeout);
-	spin_unlock_irqrestore(&info->lock, flags);
-}
-
-/*
- * ------------------------------------------------------------
- * rs_ioctl() and friends
- * ------------------------------------------------------------
- */
-
-static int get_serial_info(struct esp_struct *info,
-			   struct serial_struct __user *retinfo)
-{
-	struct serial_struct tmp;
-
-	lock_kernel();
-	memset(&tmp, 0, sizeof(tmp));
-	tmp.type = PORT_16550A;
-	tmp.line = info->line;
-	tmp.port = info->io_port;
-	tmp.irq = info->irq;
-	tmp.flags = info->port.flags;
-	tmp.xmit_fifo_size = 1024;
-	tmp.baud_base = BASE_BAUD;
-	tmp.close_delay = info->close_delay;
-	tmp.closing_wait = info->closing_wait;
-	tmp.custom_divisor = info->custom_divisor;
-	tmp.hub6 = 0;
-	unlock_kernel();
-	if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
-		return -EFAULT;
-	return 0;
-}
-
-static int get_esp_config(struct esp_struct *info,
-			  struct hayes_esp_config __user *retinfo)
-{
-	struct hayes_esp_config tmp;
-
-	if (!retinfo)
-		return -EFAULT;
-
-	memset(&tmp, 0, sizeof(tmp));
-	lock_kernel();
-	tmp.rx_timeout = info->config.rx_timeout;
-	tmp.rx_trigger = info->config.rx_trigger;
-	tmp.tx_trigger = info->config.tx_trigger;
-	tmp.flow_off = info->config.flow_off;
-	tmp.flow_on = info->config.flow_on;
-	tmp.pio_threshold = info->config.pio_threshold;
-	tmp.dma_channel = (info->stat_flags & ESP_STAT_NEVER_DMA ? 0 : dma);
-	unlock_kernel();
-
-	return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
-}
-
-static int set_serial_info(struct esp_struct *info,
-			   struct serial_struct __user *new_info)
-{
-	struct serial_struct new_serial;
-	struct esp_struct old_info;
-	unsigned int change_irq;
-	int retval = 0;
-	struct esp_struct *current_async;
-
-	if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
-		return -EFAULT;
-	old_info = *info;
-
-	if ((new_serial.type != PORT_16550A) ||
-	    (new_serial.hub6) ||
-	    (info->io_port != new_serial.port) ||
-	    (new_serial.baud_base != BASE_BAUD) ||
-	    (new_serial.irq > 15) ||
-	    (new_serial.irq < 2) ||
-	    (new_serial.irq == 6) ||
-	    (new_serial.irq == 8) ||
-	    (new_serial.irq == 13))
-		return -EINVAL;
-
-	change_irq = new_serial.irq != info->irq;
-
-	if (change_irq && (info->line % 8))
-		return -EINVAL;
-
-	if (!capable(CAP_SYS_ADMIN)) {
-		if (change_irq ||
-		    (new_serial.close_delay != info->close_delay) ||
-		    ((new_serial.flags & ~ASYNC_USR_MASK) !=
-		     (info->port.flags & ~ASYNC_USR_MASK)))
-			return -EPERM;
-		info->port.flags = ((info->port.flags & ~ASYNC_USR_MASK) |
-			       (new_serial.flags & ASYNC_USR_MASK));
-		info->custom_divisor = new_serial.custom_divisor;
-	} else {
-		if (new_serial.irq == 2)
-			new_serial.irq = 9;
-
-		if (change_irq) {
-			current_async = ports;
-
-			while (current_async) {
-				if ((current_async->line >= info->line) &&
-				    (current_async->line < (info->line + 8))) {
-					if (current_async == info) {
-						if (current_async->port.count > 1)
-							return -EBUSY;
-					} else if (current_async->port.count)
-						return -EBUSY;
-				}
-
-				current_async = current_async->next_port;
-			}
-		}
-
-		/*
-		 * OK, past this point, all the error checking has been done.
-		 * At this point, we start making changes.....
-		 */
-
-		info->port.flags = ((info->port.flags & ~ASYNC_FLAGS) |
-			       (new_serial.flags & ASYNC_FLAGS));
-		info->custom_divisor = new_serial.custom_divisor;
-		info->close_delay = new_serial.close_delay * HZ/100;
-		info->closing_wait = new_serial.closing_wait * HZ/100;
-
-		if (change_irq) {
-			/*
-			 * We need to shutdown the serial port at the old
-			 * port/irq combination.
-			 */
-			shutdown(info);
-
-			current_async = ports;
-
-			while (current_async) {
-				if ((current_async->line >= info->line) &&
-				    (current_async->line < (info->line + 8)))
-					current_async->irq = new_serial.irq;
-
-				current_async = current_async->next_port;
-			}
-
-			serial_out(info, UART_ESI_CMD1, ESI_SET_ENH_IRQ);
-			if (info->irq == 9)
-				serial_out(info, UART_ESI_CMD2, 0x02);
-			else
-				serial_out(info, UART_ESI_CMD2, info->irq);
-		}
-	}
-
-	if (info->port.flags & ASYNC_INITIALIZED) {
-		if (((old_info.port.flags & ASYNC_SPD_MASK) !=
-		     (info->port.flags & ASYNC_SPD_MASK)) ||
-		    (old_info.custom_divisor != info->custom_divisor)) {
-			if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
-				info->port.tty->alt_speed = 57600;
-			if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
-				info->port.tty->alt_speed = 115200;
-			if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
-				info->port.tty->alt_speed = 230400;
-			if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
-				info->port.tty->alt_speed = 460800;
-			change_speed(info);
-		}
-	} else
-		retval = startup(info);
-
-	return retval;
-}
-
-static int set_esp_config(struct esp_struct *info,
-			  struct hayes_esp_config __user *new_info)
-{
-	struct hayes_esp_config new_config;
-	unsigned int change_dma;
-	int retval = 0;
-	struct esp_struct *current_async;
-	unsigned long flags;
-
-	/* Perhaps a non-sysadmin user should be able to do some of these */
-	/* operations.  I haven't decided yet. */
-
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
-	if (copy_from_user(&new_config, new_info, sizeof(new_config)))
-		return -EFAULT;
-
-	if ((new_config.flow_on >= new_config.flow_off) ||
-	    (new_config.rx_trigger < 1) ||
-	    (new_config.tx_trigger < 1) ||
-	    (new_config.flow_off < 1) ||
-	    (new_config.flow_on < 1) ||
-	    (new_config.rx_trigger > 1023) ||
-	    (new_config.tx_trigger > 1023) ||
-	    (new_config.flow_off > 1023) ||
-	    (new_config.flow_on > 1023) ||
-	    (new_config.pio_threshold < 0) ||
-	    (new_config.pio_threshold > 1024))
-		return -EINVAL;
-
-	if ((new_config.dma_channel != 1) && (new_config.dma_channel != 3))
-		new_config.dma_channel = 0;
-
-	if (info->stat_flags & ESP_STAT_NEVER_DMA)
-		change_dma = new_config.dma_channel;
-	else
-		change_dma = (new_config.dma_channel != dma);
-
-	if (change_dma) {
-		if (new_config.dma_channel) {
-			/* PIO mode to DMA mode transition OR */
-			/* change current DMA channel */
-			current_async = ports;
-
-			while (current_async) {
-				if (current_async == info) {
-					if (current_async->port.count > 1)
-						return -EBUSY;
-				} else if (current_async->port.count)
-					return -EBUSY;
-
-				current_async = current_async->next_port;
-			}
-
-			shutdown(info);
-			dma = new_config.dma_channel;
-			info->stat_flags &= ~ESP_STAT_NEVER_DMA;
-
-			/* all ports must use the same DMA channel */
-
-			spin_lock_irqsave(&info->lock, flags);
-			current_async = ports;
-
-			while (current_async) {
-				esp_basic_init(current_async);
-				current_async = current_async->next_port;
-			}
-			spin_unlock_irqrestore(&info->lock, flags);
-		} else {
-			/* DMA mode to PIO mode only */
-			if (info->port.count > 1)
-				return -EBUSY;
-
-			shutdown(info);
-			spin_lock_irqsave(&info->lock, flags);
-			info->stat_flags |= ESP_STAT_NEVER_DMA;
-			esp_basic_init(info);
-			spin_unlock_irqrestore(&info->lock, flags);
-		}
-	}
-
-	info->config.pio_threshold = new_config.pio_threshold;
-
-	if ((new_config.flow_off != info->config.flow_off) ||
-	    (new_config.flow_on != info->config.flow_on)) {
-		info->config.flow_off = new_config.flow_off;
-		info->config.flow_on = new_config.flow_on;
-
-		spin_lock_irqsave(&info->lock, flags);
-		serial_out(info, UART_ESI_CMD1, ESI_SET_FLOW_LVL);
-		serial_out(info, UART_ESI_CMD2, new_config.flow_off >> 8);
-		serial_out(info, UART_ESI_CMD2, new_config.flow_off);
-		serial_out(info, UART_ESI_CMD2, new_config.flow_on >> 8);
-		serial_out(info, UART_ESI_CMD2, new_config.flow_on);
-		spin_unlock_irqrestore(&info->lock, flags);
-	}
-
-	if ((new_config.rx_trigger != info->config.rx_trigger) ||
-	    (new_config.tx_trigger != info->config.tx_trigger)) {
-		info->config.rx_trigger = new_config.rx_trigger;
-		info->config.tx_trigger = new_config.tx_trigger;
-		spin_lock_irqsave(&info->lock, flags);
-		serial_out(info, UART_ESI_CMD1, ESI_SET_TRIGGER);
-		serial_out(info, UART_ESI_CMD2,
-			   new_config.rx_trigger >> 8);
-		serial_out(info, UART_ESI_CMD2, new_config.rx_trigger);
-		serial_out(info, UART_ESI_CMD2,
-			   new_config.tx_trigger >> 8);
-		serial_out(info, UART_ESI_CMD2, new_config.tx_trigger);
-		spin_unlock_irqrestore(&info->lock, flags);
-	}
-
-	if (new_config.rx_timeout != info->config.rx_timeout) {
-		info->config.rx_timeout = new_config.rx_timeout;
-		spin_lock_irqsave(&info->lock, flags);
-
-		if (info->IER & UART_IER_RDI) {
-			serial_out(info, UART_ESI_CMD1,
-				   ESI_SET_RX_TIMEOUT);
-			serial_out(info, UART_ESI_CMD2,
-				   new_config.rx_timeout);
-		}
-
-		spin_unlock_irqrestore(&info->lock, flags);
-	}
-
-	if (!(info->port.flags & ASYNC_INITIALIZED))
-		retval = startup(info);
-
-	return retval;
-}
-
-/*
- * get_lsr_info - get line status register info
- *
- * Purpose: Let user call ioctl() to get info when the UART physically
- * 	    is emptied.  On bus types like RS485, the transmitter must
- * 	    release the bus after transmitting. This must be done when
- * 	    the transmit shift register is empty, not be done when the
- * 	    transmit holding register is empty.  This functionality
- * 	    allows an RS485 driver to be written in user space.
- */
-static int get_lsr_info(struct esp_struct *info, unsigned int __user *value)
-{
-	unsigned char status;
-	unsigned int result;
-	unsigned long flags;
-
-	spin_lock_irqsave(&info->lock, flags);
-	serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT);
-	status = serial_in(info, UART_ESI_STAT1);
-	spin_unlock_irqrestore(&info->lock, flags);
-	result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
-	return put_user(result, value);
-}
-
-
-static int esp_tiocmget(struct tty_struct *tty, struct file *file)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned char control, status;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, __func__))
-		return -ENODEV;
-	if (tty->flags & (1 << TTY_IO_ERROR))
-		return -EIO;
-
-	control = info->MCR;
-
-	spin_lock_irqsave(&info->lock, flags);
-	serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT);
-	status = serial_in(info, UART_ESI_STAT2);
-	spin_unlock_irqrestore(&info->lock, flags);
-
-	return    ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
-		| ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
-		| ((status  & UART_MSR_DCD) ? TIOCM_CAR : 0)
-		| ((status  & UART_MSR_RI) ? TIOCM_RNG : 0)
-		| ((status  & UART_MSR_DSR) ? TIOCM_DSR : 0)
-		| ((status  & UART_MSR_CTS) ? TIOCM_CTS : 0);
-}
-
-static int esp_tiocmset(struct tty_struct *tty, struct file *file,
-			unsigned int set, unsigned int clear)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, __func__))
-		return -ENODEV;
-	if (tty->flags & (1 << TTY_IO_ERROR))
-		return -EIO;
-
-	spin_lock_irqsave(&info->lock, flags);
-
-	if (set & TIOCM_RTS)
-		info->MCR |= UART_MCR_RTS;
-	if (set & TIOCM_DTR)
-		info->MCR |= UART_MCR_DTR;
-
-	if (clear & TIOCM_RTS)
-		info->MCR &= ~UART_MCR_RTS;
-	if (clear & TIOCM_DTR)
-		info->MCR &= ~UART_MCR_DTR;
-
-	serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
-	serial_out(info, UART_ESI_CMD2, UART_MCR);
-	serial_out(info, UART_ESI_CMD2, info->MCR);
-
-	spin_unlock_irqrestore(&info->lock, flags);
-	return 0;
-}
-
-/*
- * rs_break() --- routine which turns the break handling on or off
- */
-static int esp_break(struct tty_struct *tty, int break_state)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, "esp_break"))
-		return -EINVAL;
-
-	if (break_state == -1) {
-		spin_lock_irqsave(&info->lock, flags);
-		serial_out(info, UART_ESI_CMD1, ESI_ISSUE_BREAK);
-		serial_out(info, UART_ESI_CMD2, 0x01);
-		spin_unlock_irqrestore(&info->lock, flags);
-
-		/* FIXME - new style wait needed here */
-		interruptible_sleep_on(&info->break_wait);
-	} else {
-		spin_lock_irqsave(&info->lock, flags);
-		serial_out(info, UART_ESI_CMD1, ESI_ISSUE_BREAK);
-		serial_out(info, UART_ESI_CMD2, 0x00);
-		spin_unlock_irqrestore(&info->lock, flags);
-	}
-	return 0;
-}
-
-static int rs_ioctl(struct tty_struct *tty, struct file *file,
-		    unsigned int cmd, unsigned long arg)
-{
-	struct esp_struct *info = tty->driver_data;
-	struct async_icount cprev, cnow;	/* kernel counter temps */
-	struct serial_icounter_struct __user *p_cuser;	/* user space */
-	void __user *argp = (void __user *)arg;
-	unsigned long flags;
-	int ret;
-
-	if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
-		return -ENODEV;
-
-	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
-	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD)  &&
-	    (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT) &&
-	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT) &&
-	    (cmd != TIOCGHAYESESP) && (cmd != TIOCSHAYESESP)) {
-		if (tty->flags & (1 << TTY_IO_ERROR))
-		    return -EIO;
-	}
-
-	switch (cmd) {
-	case TIOCGSERIAL:
-		return get_serial_info(info, argp);
-	case TIOCSSERIAL:
-		lock_kernel();
-		ret = set_serial_info(info, argp);
-		unlock_kernel();
-		return ret;
-	case TIOCSERGWILD:
-		return put_user(0L, (unsigned long __user *)argp);
-	case TIOCSERGETLSR: /* Get line status register */
-		return get_lsr_info(info, argp);
-	case TIOCSERSWILD:
-		if (!capable(CAP_SYS_ADMIN))
-			return -EPERM;
-		return 0;
-	/*
-	 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
-	 * - mask passed in arg for lines of interest
-	 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
-	 * Caller should use TIOCGICOUNT to see which one it was
-	 */
-	case TIOCMIWAIT:
-		spin_lock_irqsave(&info->lock, flags);
-		cprev = info->icount;	/* note the counters on entry */
-		spin_unlock_irqrestore(&info->lock, flags);
-		while (1) {
-			/* FIXME: convert to new style wakeup */
-			interruptible_sleep_on(&info->port.delta_msr_wait);
-			/* see if a signal did it */
-			if (signal_pending(current))
-				return -ERESTARTSYS;
-			spin_lock_irqsave(&info->lock, flags);
-			cnow = info->icount;	/* atomic copy */
-			spin_unlock_irqrestore(&info->lock, flags);
-			if (cnow.rng == cprev.rng &&
-			    cnow.dsr == cprev.dsr &&
-			    cnow.dcd == cprev.dcd &&
-			    cnow.cts == cprev.cts)
-				return -EIO; /* no change => error */
-			if (((arg & TIOCM_RNG) &&
-			     (cnow.rng != cprev.rng)) ||
-			     ((arg & TIOCM_DSR) &&
-			      (cnow.dsr != cprev.dsr)) ||
-			     ((arg & TIOCM_CD) &&
-			      (cnow.dcd != cprev.dcd)) ||
-			     ((arg & TIOCM_CTS) &&
-			      (cnow.cts != cprev.cts))) {
-				return 0;
-			}
-			cprev = cnow;
-		}
-		/* NOTREACHED */
-	/*
-	 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
-	 * Return: write counters to the user passed counter struct
-	 * NB: both 1->0 and 0->1 transitions are counted except for
-	 *     RI where only 0->1 is counted.
-	 */
-	case TIOCGICOUNT:
-		spin_lock_irqsave(&info->lock, flags);
-		cnow = info->icount;
-		spin_unlock_irqrestore(&info->lock, flags);
-		p_cuser = argp;
-		if (put_user(cnow.cts, &p_cuser->cts) ||
-		    put_user(cnow.dsr, &p_cuser->dsr) ||
-		    put_user(cnow.rng, &p_cuser->rng) ||
-		    put_user(cnow.dcd, &p_cuser->dcd))
-			return -EFAULT;
-			return 0;
-	case TIOCGHAYESESP:
-		return get_esp_config(info, argp);
-	case TIOCSHAYESESP:
-		lock_kernel();
-		ret = set_esp_config(info, argp);
-		unlock_kernel();
-		return ret;
-	default:
-		return -ENOIOCTLCMD;
-	}
-	return 0;
-}
-
-static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-
-	change_speed(info);
-
-	spin_lock_irqsave(&info->lock, flags);
-
-	/* Handle transition to B0 status */
-	if ((old_termios->c_cflag & CBAUD) &&
-		!(tty->termios->c_cflag & CBAUD)) {
-		info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
-		serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
-		serial_out(info, UART_ESI_CMD2, UART_MCR);
-		serial_out(info, UART_ESI_CMD2, info->MCR);
-	}
-
-	/* Handle transition away from B0 status */
-	if (!(old_termios->c_cflag & CBAUD) &&
-		(tty->termios->c_cflag & CBAUD)) {
-		info->MCR |= (UART_MCR_DTR | UART_MCR_RTS);
-		serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
-		serial_out(info, UART_ESI_CMD2, UART_MCR);
-		serial_out(info, UART_ESI_CMD2, info->MCR);
-	}
-
-	spin_unlock_irqrestore(&info->lock, flags);
-
-	/* Handle turning of CRTSCTS */
-	if ((old_termios->c_cflag & CRTSCTS) &&
-	    !(tty->termios->c_cflag & CRTSCTS)) {
-		rs_start(tty);
-	}
-}
-
-/*
- * ------------------------------------------------------------
- * rs_close()
- *
- * This routine is called when the serial port gets closed.  First, we
- * wait for the last remaining data to be sent.  Then, we unlink its
- * async structure from the interrupt chain if necessary, and we free
- * that IRQ if nothing is left in the chain.
- * ------------------------------------------------------------
- */
-static void rs_close(struct tty_struct *tty, struct file *filp)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-
-	if (!info || serial_paranoia_check(info, tty->name, "rs_close"))
-		return;
-
-	spin_lock_irqsave(&info->lock, flags);
-
-	if (tty_hung_up_p(filp)) {
-		DBG_CNT("before DEC-hung");
-		goto out;
-	}
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk(KERN_DEBUG "rs_close ttys%d, count = %d\n",
-						info->line, info->port.count);
-#endif
-	if (tty->count == 1 && info->port.count != 1) {
-		/*
-		 * Uh, oh.  tty->count is 1, which means that the tty
-		 * structure will be freed.  Info->count should always
-		 * be one in these conditions.  If it's greater than
-		 * one, we've got real problems, since it means the
-		 * serial port won't be shutdown.
-		 */
-		printk(KERN_DEBUG "rs_close: bad serial port count; tty->count is 1, info->port.count is %d\n", info->port.count);
-		info->port.count = 1;
-	}
-	if (--info->port.count < 0) {
-		printk(KERN_ERR "rs_close: bad serial port count for ttys%d: %d\n",
-		       info->line, info->port.count);
-		info->port.count = 0;
-	}
-	if (info->port.count) {
-		DBG_CNT("before DEC-2");
-		goto out;
-	}
-	info->port.flags |= ASYNC_CLOSING;
-
-	spin_unlock_irqrestore(&info->lock, flags);
-	/*
-	 * Now we wait for the transmit buffer to clear; and we notify
-	 * the line discipline to only process XON/XOFF characters.
-	 */
-	tty->closing = 1;
-	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-		tty_wait_until_sent(tty, info->closing_wait);
-	/*
-	 * At this point we stop accepting input.  To do this, we
-	 * disable the receive line status interrupts, and tell the
-	 * interrupt driver to stop checking the data ready bit in the
-	 * line status register.
-	 */
-	/* info->IER &= ~UART_IER_RLSI; */
-	info->IER &= ~UART_IER_RDI;
-	info->read_status_mask &= ~UART_LSR_DR;
-	if (info->port.flags & ASYNC_INITIALIZED) {
-
-		spin_lock_irqsave(&info->lock, flags);
-		serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-		serial_out(info, UART_ESI_CMD2, info->IER);
-
-		/* disable receive timeout */
-		serial_out(info, UART_ESI_CMD1, ESI_SET_RX_TIMEOUT);
-		serial_out(info, UART_ESI_CMD2, 0x00);
-
-		spin_unlock_irqrestore(&info->lock, flags);
-
-		/*
-		 * Before we drop DTR, make sure the UART transmitter
-		 * has completely drained; this is especially
-		 * important if there is a transmit FIFO!
-		 */
-		rs_wait_until_sent(tty, info->timeout);
-	}
-	shutdown(info);
-	rs_flush_buffer(tty);
-	tty_ldisc_flush(tty);
-	tty->closing = 0;
-	info->port.tty = NULL;
-
-	if (info->port.blocked_open) {
-		if (info->close_delay)
-			msleep_interruptible(jiffies_to_msecs(info->close_delay));
-		wake_up_interruptible(&info->port.open_wait);
-	}
-	info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
-	wake_up_interruptible(&info->port.close_wait);
-	return;
-
-out:
-	spin_unlock_irqrestore(&info->lock, flags);
-}
-
-static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long orig_jiffies, char_time;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent"))
-		return;
-
-	orig_jiffies = jiffies;
-	char_time = ((info->timeout - HZ / 50) / 1024) / 5;
-
-	if (!char_time)
-		char_time = 1;
-
-	spin_lock_irqsave(&info->lock, flags);
-	serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND);
-	serial_out(info, UART_ESI_CMD1, ESI_GET_TX_AVAIL);
-
-	while ((serial_in(info, UART_ESI_STAT1) != 0x03) ||
-		(serial_in(info, UART_ESI_STAT2) != 0xff)) {
-
-		spin_unlock_irqrestore(&info->lock, flags);
-		msleep_interruptible(jiffies_to_msecs(char_time));
-
-		if (signal_pending(current))
-			return;
-
-		if (timeout && time_after(jiffies, orig_jiffies + timeout))
-			return;
-
-		spin_lock_irqsave(&info->lock, flags);
-		serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND);
-		serial_out(info, UART_ESI_CMD1, ESI_GET_TX_AVAIL);
-	}
-	spin_unlock_irqrestore(&info->lock, flags);
-	set_current_state(TASK_RUNNING);
-}
-
-/*
- * esp_hangup() --- called by tty_hangup() when a hangup is signaled.
- */
-static void esp_hangup(struct tty_struct *tty)
-{
-	struct esp_struct *info = tty->driver_data;
-
-	if (serial_paranoia_check(info, tty->name, "esp_hangup"))
-		return;
-
-	rs_flush_buffer(tty);
-	shutdown(info);
-	info->port.count = 0;
-	info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
-	info->port.tty = NULL;
-	wake_up_interruptible(&info->port.open_wait);
-}
-
-static int esp_carrier_raised(struct tty_port *port)
-{
-	struct esp_struct *info = container_of(port, struct esp_struct, port);
-	serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT);
-	if (serial_in(info, UART_ESI_STAT2) & UART_MSR_DCD)
-		return 1;
-	return 0;
-}
-
-/*
- * ------------------------------------------------------------
- * esp_open() and friends
- * ------------------------------------------------------------
- */
-static int block_til_ready(struct tty_struct *tty, struct file *filp,
-			   struct esp_struct *info)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	int		retval;
-	int		do_clocal = 0;
-	unsigned long	flags;
-	int		cd;
-	struct tty_port *port = &info->port;
-
-	/*
-	 * If the device is in the middle of being closed, then block
-	 * until it's done, and then try again.
-	 */
-	if (tty_hung_up_p(filp) ||
-	    (port->flags & ASYNC_CLOSING)) {
-		if (port->flags & ASYNC_CLOSING)
-			interruptible_sleep_on(&port->close_wait);
-#ifdef SERIAL_DO_RESTART
-		if (port->flags & ASYNC_HUP_NOTIFY)
-			return -EAGAIN;
-		else
-			return -ERESTARTSYS;
-#else
-		return -EAGAIN;
-#endif
-	}
-
-	/*
-	 * If non-blocking mode is set, or the port is not enabled,
-	 * then make the check up front and then exit.
-	 */
-	if ((filp->f_flags & O_NONBLOCK) ||
-	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		port->flags |= ASYNC_NORMAL_ACTIVE;
-		return 0;
-	}
-
-	if (tty->termios->c_cflag & CLOCAL)
-		do_clocal = 1;
-
-	/*
-	 * Block waiting for the carrier detect and the line to become
-	 * free (i.e., not in use by the callout).  While we are in
-	 * this loop, port->count is dropped by one, so that
-	 * rs_close() knows when to free things.  We restore it upon
-	 * exit, either normal or abnormal.
-	 */
-	retval = 0;
-	add_wait_queue(&port->open_wait, &wait);
-#ifdef SERIAL_DEBUG_OPEN
-	printk(KERN_DEBUG "block_til_ready before block: ttys%d, count = %d\n",
-	       info->line, port->count);
-#endif
-	spin_lock_irqsave(&info->lock, flags);
-	if (!tty_hung_up_p(filp))
-		port->count--;
-	port->blocked_open++;
-	while (1) {
-		if ((tty->termios->c_cflag & CBAUD)) {
-			unsigned int scratch;
-
-			serial_out(info, UART_ESI_CMD1, ESI_READ_UART);
-			serial_out(info, UART_ESI_CMD2, UART_MCR);
-			scratch = serial_in(info, UART_ESI_STAT1);
-			serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
-			serial_out(info, UART_ESI_CMD2, UART_MCR);
-			serial_out(info, UART_ESI_CMD2,
-				scratch | UART_MCR_DTR | UART_MCR_RTS);
-		}
-		set_current_state(TASK_INTERRUPTIBLE);
-		if (tty_hung_up_p(filp) ||
-		    !(port->flags & ASYNC_INITIALIZED)) {
-#ifdef SERIAL_DO_RESTART
-			if (port->flags & ASYNC_HUP_NOTIFY)
-				retval = -EAGAIN;
-			else
-				retval = -ERESTARTSYS;
-#else
-			retval = -EAGAIN;
-#endif
-			break;
-		}
-
-		cd = tty_port_carrier_raised(port);
-
-		if (!(port->flags & ASYNC_CLOSING) &&
-		    (do_clocal))
-			break;
-		if (signal_pending(current)) {
-			retval = -ERESTARTSYS;
-			break;
-		}
-#ifdef SERIAL_DEBUG_OPEN
-		printk(KERN_DEBUG "block_til_ready blocking: ttys%d, count = %d\n",
-		       info->line, port->count);
-#endif
-		spin_unlock_irqrestore(&info->lock, flags);
-		schedule();
-		spin_lock_irqsave(&info->lock, flags);
-	}
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&port->open_wait, &wait);
-	if (!tty_hung_up_p(filp))
-		port->count++;
-	port->blocked_open--;
-	spin_unlock_irqrestore(&info->lock, flags);
-#ifdef SERIAL_DEBUG_OPEN
-	printk(KERN_DEBUG "block_til_ready after blocking: ttys%d, count = %d\n",
-	       info->line, port->count);
-#endif
-	if (retval)
-		return retval;
-	port->flags |= ASYNC_NORMAL_ACTIVE;
-	return 0;
-}
-
-/*
- * This routine is called whenever a serial port is opened.  It
- * enables interrupts for a serial port, linking in its async structure into
- * the IRQ chain.   It also performs the serial-specific
- * initialization for the tty structure.
- */
-static int esp_open(struct tty_struct *tty, struct file *filp)
-{
-	struct esp_struct	*info;
-	int 			retval, line;
-	unsigned long		flags;
-
-	line = tty->index;
-	if ((line < 0) || (line >= NR_PORTS))
-		return -ENODEV;
-
-	/* find the port in the chain */
-
-	info = ports;
-
-	while (info && (info->line != line))
-		info = info->next_port;
-
-	if (!info) {
-		serial_paranoia_check(info, tty->name, "esp_open");
-		return -ENODEV;
-	}
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk(KERN_DEBUG "esp_open %s, count = %d\n", tty->name, info->port.count);
-#endif
-	spin_lock_irqsave(&info->lock, flags);
-	info->port.count++;
-	tty->driver_data = info;
-	info->port.tty = tty;
-
-	spin_unlock_irqrestore(&info->lock, flags);
-
-	/*
-	 * Start up serial port
-	 */
-	retval = startup(info);
-	if (retval)
-		return retval;
-
-	retval = block_til_ready(tty, filp, info);
-	if (retval) {
-#ifdef SERIAL_DEBUG_OPEN
-		printk(KERN_DEBUG "esp_open returning after block_til_ready with %d\n",
-		       retval);
-#endif
-		return retval;
-	}
-#ifdef SERIAL_DEBUG_OPEN
-	printk(KERN_DEBUG "esp_open %s successful...", tty->name);
-#endif
-	return 0;
-}
-
-/*
- * ---------------------------------------------------------------------
- * espserial_init() and friends
- *
- * espserial_init() is called at boot-time to initialize the serial driver.
- * ---------------------------------------------------------------------
- */
-
-/*
- * This routine prints out the appropriate serial driver version
- * number, and identifies which options were configured into this
- * driver.
- */
-
-static void __init show_serial_version(void)
-{
-	printk(KERN_INFO "%s version %s (DMA %u)\n",
-		serial_name, serial_version, dma);
-}
-
-/*
- * This routine is called by espserial_init() to initialize a specific serial
- * port.
- */
-static int autoconfig(struct esp_struct *info)
-{
-	int port_detected = 0;
-	unsigned long flags;
-
-	if (!request_region(info->io_port, REGION_SIZE, "esp serial"))
-		return -EIO;
-
-	spin_lock_irqsave(&info->lock, flags);
-	/*
-	 * Check for ESP card
-	 */
-
-	if (serial_in(info, UART_ESI_BASE) == 0xf3) {
-		serial_out(info, UART_ESI_CMD1, 0x00);
-		serial_out(info, UART_ESI_CMD1, 0x01);
-
-		if ((serial_in(info, UART_ESI_STAT2) & 0x70) == 0x20) {
-			port_detected = 1;
-
-			if (!(info->irq)) {
-				serial_out(info, UART_ESI_CMD1, 0x02);
-
-				if (serial_in(info, UART_ESI_STAT1) & 0x01)
-					info->irq = 3;
-				else
-					info->irq = 4;
-			}
-
-
-			/* put card in enhanced mode */
-			/* this prevents access through */
-			/* the "old" IO ports */
-			esp_basic_init(info);
-
-			/* clear out MCR */
-			serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
-			serial_out(info, UART_ESI_CMD2, UART_MCR);
-			serial_out(info, UART_ESI_CMD2, 0x00);
-		}
-	}
-	if (!port_detected)
-		release_region(info->io_port, REGION_SIZE);
-
-	spin_unlock_irqrestore(&info->lock, flags);
-	return (port_detected);
-}
-
-static const struct tty_operations esp_ops = {
-	.open = esp_open,
-	.close = rs_close,
-	.write = rs_write,
-	.put_char = rs_put_char,
-	.flush_chars = rs_flush_chars,
-	.write_room = rs_write_room,
-	.chars_in_buffer = rs_chars_in_buffer,
-	.flush_buffer = rs_flush_buffer,
-	.ioctl = rs_ioctl,
-	.throttle = rs_throttle,
-	.unthrottle = rs_unthrottle,
-	.set_termios = rs_set_termios,
-	.stop = rs_stop,
-	.start = rs_start,
-	.hangup = esp_hangup,
-	.break_ctl = esp_break,
-	.wait_until_sent = rs_wait_until_sent,
-	.tiocmget = esp_tiocmget,
-	.tiocmset = esp_tiocmset,
-};
-
-static const struct tty_port_operations esp_port_ops = {
-	.esp_carrier_raised,
-};
-
-/*
- * The serial driver boot-time initialization code!
- */
-static int __init espserial_init(void)
-{
-	int i, offset;
-	struct esp_struct *info;
-	struct esp_struct *last_primary = NULL;
-	int esp[] = { 0x100, 0x140, 0x180, 0x200, 0x240, 0x280, 0x300, 0x380 };
-
-	esp_driver = alloc_tty_driver(NR_PORTS);
-	if (!esp_driver)
-		return -ENOMEM;
-
-	for (i = 0; i < NR_PRIMARY; i++) {
-		if (irq[i] != 0) {
-			if ((irq[i] < 2) || (irq[i] > 15) || (irq[i] == 6) ||
-			    (irq[i] == 8) || (irq[i] == 13))
-				irq[i] = 0;
-			else if (irq[i] == 2)
-				irq[i] = 9;
-		}
-	}
-
-	if ((dma != 1) && (dma != 3))
-		dma = 0;
-
-	if ((rx_trigger < 1) || (rx_trigger > 1023))
-		rx_trigger = 768;
-
-	if ((tx_trigger < 1) || (tx_trigger > 1023))
-		tx_trigger = 768;
-
-	if ((flow_off < 1) || (flow_off > 1023))
-		flow_off = 1016;
-
-	if ((flow_on < 1) || (flow_on > 1023))
-		flow_on = 944;
-
-	if ((rx_timeout < 0) || (rx_timeout > 255))
-		rx_timeout = 128;
-
-	if (flow_on >= flow_off)
-		flow_on = flow_off - 1;
-
-	show_serial_version();
-
-	/* Initialize the tty_driver structure */
-
-	esp_driver->owner = THIS_MODULE;
-	esp_driver->name = "ttyP";
-	esp_driver->major = ESP_IN_MAJOR;
-	esp_driver->minor_start = 0;
-	esp_driver->type = TTY_DRIVER_TYPE_SERIAL;
-	esp_driver->subtype = SERIAL_TYPE_NORMAL;
-	esp_driver->init_termios = tty_std_termios;
-	esp_driver->init_termios.c_cflag =
-		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-	esp_driver->init_termios.c_ispeed = 9600;
-	esp_driver->init_termios.c_ospeed = 9600;
-	esp_driver->flags = TTY_DRIVER_REAL_RAW;
-	tty_set_operations(esp_driver, &esp_ops);
-	if (tty_register_driver(esp_driver)) {
-		printk(KERN_ERR "Couldn't register esp serial driver");
-		put_tty_driver(esp_driver);
-		return 1;
-	}
-
-	info = kzalloc(sizeof(struct esp_struct), GFP_KERNEL);
-
-	if (!info) {
-		printk(KERN_ERR "Couldn't allocate memory for esp serial device information\n");
-		tty_unregister_driver(esp_driver);
-		put_tty_driver(esp_driver);
-		return 1;
-	}
-
-	spin_lock_init(&info->lock);
-	/* rx_trigger, tx_trigger are needed by autoconfig */
-	info->config.rx_trigger = rx_trigger;
-	info->config.tx_trigger = tx_trigger;
-
-	i = 0;
-	offset = 0;
-
-	do {
-		tty_port_init(&info->port);
-		info->port.ops = &esp_port_ops;
-		info->io_port = esp[i] + offset;
-		info->irq = irq[i];
-		info->line = (i * 8) + (offset / 8);
-
-		if (!autoconfig(info)) {
-			i++;
-			offset = 0;
-			continue;
-		}
-
-		info->custom_divisor = (divisor[i] >> (offset / 2)) & 0xf;
-		info->port.flags = STD_COM_FLAGS;
-		if (info->custom_divisor)
-			info->port.flags |= ASYNC_SPD_CUST;
-		info->magic = ESP_MAGIC;
-		info->close_delay = 5*HZ/10;
-		info->closing_wait = 30*HZ;
-		info->config.rx_timeout = rx_timeout;
-		info->config.flow_on = flow_on;
-		info->config.flow_off = flow_off;
-		info->config.pio_threshold = pio_threshold;
-		info->next_port = ports;
-		init_waitqueue_head(&info->break_wait);
-		ports = info;
-		printk(KERN_INFO "ttyP%d at 0x%04x (irq = %d) is an ESP ",
-			info->line, info->io_port, info->irq);
-
-		if (info->line % 8) {
-			printk("secondary port\n");
-			/* 8 port cards can't do DMA */
-			info->stat_flags |= ESP_STAT_NEVER_DMA;
-
-			if (last_primary)
-				last_primary->stat_flags |= ESP_STAT_NEVER_DMA;
-		} else {
-			printk("primary port\n");
-			last_primary = info;
-			irq[i] = info->irq;
-		}
-
-		if (!dma)
-			info->stat_flags |= ESP_STAT_NEVER_DMA;
-
-		info = kzalloc(sizeof(struct esp_struct), GFP_KERNEL);
-		if (!info) {
-			printk(KERN_ERR "Couldn't allocate memory for esp serial device information\n");
-			/* allow use of the already detected ports */
-			return 0;
-		}
-
-		spin_lock_init(&info->lock);
-		/* rx_trigger, tx_trigger are needed by autoconfig */
-		info->config.rx_trigger = rx_trigger;
-		info->config.tx_trigger = tx_trigger;
-
-		if (offset == 56) {
-			i++;
-			offset = 0;
-		} else {
-			offset += 8;
-		}
-	} while (i < NR_PRIMARY);
-
-	/* free the last port memory allocation */
-	kfree(info);
-
-	return 0;
-}
-
-static void __exit espserial_exit(void)
-{
-	int e1;
-	struct esp_struct *temp_async;
-	struct esp_pio_buffer *pio_buf;
-
-	e1 = tty_unregister_driver(esp_driver);
-	if (e1)
-		printk(KERN_ERR "esp: failed to unregister driver (%d)\n", e1);
-	put_tty_driver(esp_driver);
-
-	while (ports) {
-		if (ports->io_port)
-			release_region(ports->io_port, REGION_SIZE);
-		temp_async = ports->next_port;
-		kfree(ports);
-		ports = temp_async;
-	}
-
-	if (dma_buffer)
-		free_pages((unsigned long)dma_buffer,
-			get_order(DMA_BUFFER_SZ));
-
-	while (free_pio_buf) {
-		pio_buf = free_pio_buf->next;
-		kfree(free_pio_buf);
-		free_pio_buf = pio_buf;
-	}
-}
-
-module_init(espserial_init);
-module_exit(espserial_exit);
diff --git a/drivers/char/generic_nvram.c b/drivers/char/generic_nvram.c
index ef31738..fda4181 100644
--- a/drivers/char/generic_nvram.c
+++ b/drivers/char/generic_nvram.c
@@ -19,7 +19,6 @@
 #include <linux/miscdevice.h>
 #include <linux/fcntl.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include <asm/nvram.h>
 #ifdef CONFIG_PPC_PMAC
@@ -32,7 +31,6 @@
 
 static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
 {
-	lock_kernel();
 	switch (origin) {
 	case 1:
 		offset += file->f_pos;
@@ -41,12 +39,11 @@
 		offset += nvram_len;
 		break;
 	}
-	if (offset < 0) {
-		unlock_kernel();
+	if (offset < 0)
 		return -EINVAL;
-	}
+
 	file->f_pos = offset;
-	unlock_kernel();
+
 	return file->f_pos;
 }
 
diff --git a/drivers/char/hvc_xen.c b/drivers/char/hvc_xen.c
index a6ee32b..b1a7163 100644
--- a/drivers/char/hvc_xen.c
+++ b/drivers/char/hvc_xen.c
@@ -25,6 +25,8 @@
 #include <linux/types.h>
 
 #include <asm/xen/hypervisor.h>
+
+#include <xen/xen.h>
 #include <xen/page.h>
 #include <xen/events.h>
 #include <xen/interface/io/console.h>
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index 1573aeb..e989f67 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -52,7 +52,9 @@
 static struct hwrng *current_rng;
 static LIST_HEAD(rng_list);
 static DEFINE_MUTEX(rng_mutex);
-
+static int data_avail;
+static u8 rng_buffer[SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES]
+	__cacheline_aligned;
 
 static inline int hwrng_init(struct hwrng *rng)
 {
@@ -67,19 +69,6 @@
 		rng->cleanup(rng);
 }
 
-static inline int hwrng_data_present(struct hwrng *rng, int wait)
-{
-	if (!rng->data_present)
-		return 1;
-	return rng->data_present(rng, wait);
-}
-
-static inline int hwrng_data_read(struct hwrng *rng, u32 *data)
-{
-	return rng->data_read(rng, data);
-}
-
-
 static int rng_dev_open(struct inode *inode, struct file *filp)
 {
 	/* enforce read-only access to this chrdev */
@@ -87,58 +76,90 @@
 		return -EINVAL;
 	if (filp->f_mode & FMODE_WRITE)
 		return -EINVAL;
-	cycle_kernel_lock();
+	return 0;
+}
+
+static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size,
+			int wait) {
+	int present;
+
+	if (rng->read)
+		return rng->read(rng, (void *)buffer, size, wait);
+
+	if (rng->data_present)
+		present = rng->data_present(rng, wait);
+	else
+		present = 1;
+
+	if (present)
+		return rng->data_read(rng, (u32 *)buffer);
+
 	return 0;
 }
 
 static ssize_t rng_dev_read(struct file *filp, char __user *buf,
 			    size_t size, loff_t *offp)
 {
-	u32 data;
 	ssize_t ret = 0;
 	int err = 0;
-	int bytes_read;
+	int bytes_read, len;
 
 	while (size) {
-		err = -ERESTARTSYS;
-		if (mutex_lock_interruptible(&rng_mutex))
+		if (mutex_lock_interruptible(&rng_mutex)) {
+			err = -ERESTARTSYS;
 			goto out;
+		}
+
 		if (!current_rng) {
-			mutex_unlock(&rng_mutex);
 			err = -ENODEV;
-			goto out;
+			goto out_unlock;
 		}
 
-		bytes_read = 0;
-		if (hwrng_data_present(current_rng,
-				       !(filp->f_flags & O_NONBLOCK)))
-			bytes_read = hwrng_data_read(current_rng, &data);
+		if (!data_avail) {
+			bytes_read = rng_get_data(current_rng, rng_buffer,
+				sizeof(rng_buffer),
+				!(filp->f_flags & O_NONBLOCK));
+			if (bytes_read < 0) {
+				err = bytes_read;
+				goto out_unlock;
+			}
+			data_avail = bytes_read;
+		}
+
+		if (!data_avail) {
+			if (filp->f_flags & O_NONBLOCK) {
+				err = -EAGAIN;
+				goto out_unlock;
+			}
+		} else {
+			len = data_avail;
+			if (len > size)
+				len = size;
+
+			data_avail -= len;
+
+			if (copy_to_user(buf + ret, rng_buffer + data_avail,
+								len)) {
+				err = -EFAULT;
+				goto out_unlock;
+			}
+
+			size -= len;
+			ret += len;
+		}
+
 		mutex_unlock(&rng_mutex);
 
-		err = -EAGAIN;
-		if (!bytes_read && (filp->f_flags & O_NONBLOCK))
-			goto out;
-		if (bytes_read < 0) {
-			err = bytes_read;
-			goto out;
-		}
-
-		err = -EFAULT;
-		while (bytes_read && size) {
-			if (put_user((u8)data, buf++))
-				goto out;
-			size--;
-			ret++;
-			bytes_read--;
-			data >>= 8;
-		}
-
 		if (need_resched())
 			schedule_timeout_interruptible(1);
-		err = -ERESTARTSYS;
-		if (signal_pending(current))
+
+		if (signal_pending(current)) {
+			err = -ERESTARTSYS;
 			goto out;
+		}
 	}
+out_unlock:
+	mutex_unlock(&rng_mutex);
 out:
 	return ret ? : err;
 }
@@ -280,7 +301,7 @@
 	struct hwrng *old_rng, *tmp;
 
 	if (rng->name == NULL ||
-	    rng->data_read == NULL)
+	    (rng->data_read == NULL && rng->read == NULL))
 		goto out;
 
 	mutex_lock(&rng_mutex);
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
index 915157f..bdaef8e9 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -16,6 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  */
+
 #include <linux/err.h>
 #include <linux/hw_random.h>
 #include <linux/scatterlist.h>
@@ -23,78 +24,64 @@
 #include <linux/virtio.h>
 #include <linux/virtio_rng.h>
 
-/* The host will fill any buffer we give it with sweet, sweet randomness.  We
- * give it 64 bytes at a time, and the hwrng framework takes it 4 bytes at a
- * time. */
-#define RANDOM_DATA_SIZE 64
-
 static struct virtqueue *vq;
-static u32 *random_data;
-static unsigned int data_left;
+static unsigned int data_avail;
 static DECLARE_COMPLETION(have_data);
+static bool busy;
 
 static void random_recv_done(struct virtqueue *vq)
 {
-	unsigned int len;
-
 	/* We can get spurious callbacks, e.g. shared IRQs + virtio_pci. */
-	if (!vq->vq_ops->get_buf(vq, &len))
+	if (!vq->vq_ops->get_buf(vq, &data_avail))
 		return;
 
-	data_left += len;
 	complete(&have_data);
 }
 
-static void register_buffer(void)
+/* The host will fill any buffer we give it with sweet, sweet randomness. */
+static void register_buffer(u8 *buf, size_t size)
 {
 	struct scatterlist sg;
 
-	sg_init_one(&sg, random_data+data_left, RANDOM_DATA_SIZE-data_left);
+	sg_init_one(&sg, buf, size);
+
 	/* There should always be room for one buffer. */
-	if (vq->vq_ops->add_buf(vq, &sg, 0, 1, random_data) < 0)
+	if (vq->vq_ops->add_buf(vq, &sg, 0, 1, buf) < 0)
 		BUG();
+
 	vq->vq_ops->kick(vq);
 }
 
-/* At least we don't udelay() in a loop like some other drivers. */
-static int virtio_data_present(struct hwrng *rng, int wait)
+static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
 {
-	if (data_left >= sizeof(u32))
-		return 1;
 
-again:
+	if (!busy) {
+		busy = true;
+		init_completion(&have_data);
+		register_buffer(buf, size);
+	}
+
 	if (!wait)
 		return 0;
 
 	wait_for_completion(&have_data);
 
-	/* Not enough?  Re-register. */
-	if (unlikely(data_left < sizeof(u32))) {
-		register_buffer();
-		goto again;
-	}
+	busy = false;
 
-	return 1;
+	return data_avail;
 }
 
-/* virtio_data_present() must have succeeded before this is called. */
-static int virtio_data_read(struct hwrng *rng, u32 *data)
+static void virtio_cleanup(struct hwrng *rng)
 {
-	BUG_ON(data_left < sizeof(u32));
-	data_left -= sizeof(u32);
-	*data = random_data[data_left / 4];
-
-	if (data_left < sizeof(u32)) {
-		init_completion(&have_data);
-		register_buffer();
-	}
-	return sizeof(*data);
+	if (busy)
+		wait_for_completion(&have_data);
 }
 
+
 static struct hwrng virtio_hwrng = {
-	.name = "virtio",
-	.data_present = virtio_data_present,
-	.data_read = virtio_data_read,
+	.name		= "virtio",
+	.cleanup	= virtio_cleanup,
+	.read		= virtio_read,
 };
 
 static int virtrng_probe(struct virtio_device *vdev)
@@ -112,7 +99,6 @@
 		return err;
 	}
 
-	register_buffer();
 	return 0;
 }
 
@@ -138,21 +124,11 @@
 
 static int __init init(void)
 {
-	int err;
-
-	random_data = kmalloc(RANDOM_DATA_SIZE, GFP_KERNEL);
-	if (!random_data)
-		return -ENOMEM;
-
-	err = register_virtio_driver(&virtio_rng);
-	if (err)
-		kfree(random_data);
-	return err;
+	return register_virtio_driver(&virtio_rng);
 }
 
 static void __exit fini(void)
 {
-	kfree(random_data);
 	unregister_virtio_driver(&virtio_rng);
 }
 module_init(init);
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 426bfdd..300d5bd 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -793,35 +793,30 @@
 {
 	int channel;
 	struct isi_port *port;
-	unsigned long flags;
 
-	spin_lock_irqsave(&bp->card_lock, flags);
-	if (bp->status & BOARD_ACTIVE) {
-		spin_unlock_irqrestore(&bp->card_lock, flags);
-		return;
+	bp->count++;
+	if (!(bp->status & BOARD_INIT)) {
+		port = bp->ports;
+		for (channel = 0; channel < bp->port_count; channel++, port++)
+			drop_dtr_rts(port);
 	}
-	port = bp->ports;
-	bp->status |= BOARD_ACTIVE;
-	for (channel = 0; channel < bp->port_count; channel++, port++)
-		drop_dtr_rts(port);
-	spin_unlock_irqrestore(&bp->card_lock, flags);
+	bp->status |= BOARD_ACTIVE | BOARD_INIT;
 }
 
-static int isicom_setup_port(struct tty_struct *tty)
+/* Activate and thus setup board are protected from races against shutdown
+   by the tty_port mutex */
+
+static int isicom_activate(struct tty_port *tport, struct tty_struct *tty)
 {
-	struct isi_port *port = tty->driver_data;
+	struct isi_port *port = container_of(tport, struct isi_port, port);
 	struct isi_board *card = port->card;
 	unsigned long flags;
 
-	if (port->port.flags & ASYNC_INITIALIZED)
-		return 0;
-	if (tty_port_alloc_xmit_buf(&port->port) < 0)
+	if (tty_port_alloc_xmit_buf(tport) < 0)
 		return -ENOMEM;
 
 	spin_lock_irqsave(&card->card_lock, flags);
-	clear_bit(TTY_IO_ERROR, &tty->flags);
-	if (port->port.count == 1)
-		card->count++;
+	isicom_setup_board(card);
 
 	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
 
@@ -832,9 +827,7 @@
 		outw(((ISICOM_KILLTX | ISICOM_KILLRX) << 8) | 0x06, card->base);
 		InterruptTheCard(card->base);
 	}
-
 	isicom_config_port(tty);
-	port->port.flags |= ASYNC_INITIALIZED;
 	spin_unlock_irqrestore(&card->card_lock, flags);
 
 	return 0;
@@ -871,85 +864,37 @@
 
 	return &port->port;
 }
-	
+
 static int isicom_open(struct tty_struct *tty, struct file *filp)
 {
 	struct isi_port *port;
 	struct isi_board *card;
 	struct tty_port *tport;
-	int error = 0;
 
 	tport = isicom_find_port(tty);
 	if (tport == NULL)
 		return -ENODEV;
 	port = container_of(tport, struct isi_port, port);
 	card = &isi_card[BOARD(tty->index)];
-	isicom_setup_board(card);
 
-	/* FIXME: locking on port.count etc */
-	port->port.count++;
-	tty->driver_data = port;
-	tty_port_tty_set(&port->port, tty);
-	/* FIXME: Locking on Initialized flag */
-	if (!test_bit(ASYNCB_INITIALIZED, &tport->flags))
-		error = isicom_setup_port(tty);
-	if (error == 0)
-		error = tty_port_block_til_ready(&port->port, tty, filp);
-	return error;
+	return tty_port_open(tport, tty, filp);
 }
 
 /* close et all */
 
-static inline void isicom_shutdown_board(struct isi_board *bp)
-{
-	if (bp->status & BOARD_ACTIVE)
-		bp->status &= ~BOARD_ACTIVE;
-}
-
 /* card->lock HAS to be held */
 static void isicom_shutdown_port(struct isi_port *port)
 {
 	struct isi_board *card = port->card;
-	struct tty_struct *tty;
-
-	tty = tty_port_tty_get(&port->port);
-
-	if (!(port->port.flags & ASYNC_INITIALIZED)) {
-		tty_kref_put(tty);
-		return;
-	}
-
-	tty_port_free_xmit_buf(&port->port);
-	port->port.flags &= ~ASYNC_INITIALIZED;
-	/* 3rd October 2000 : Vinayak P Risbud */
-	tty_port_tty_set(&port->port, NULL);
-
-	/*Fix done by Anil .S on 30-04-2001
-	remote login through isi port has dtr toggle problem
-	due to which the carrier drops before the password prompt
-	appears on the remote end. Now we drop the dtr only if the
-	HUPCL(Hangup on close) flag is set for the tty*/
-
-	if (C_HUPCL(tty))
-		/* drop dtr on this port */
-		drop_dtr(port);
-
-	/* any other port uninits  */
-	if (tty)
-		set_bit(TTY_IO_ERROR, &tty->flags);
 
 	if (--card->count < 0) {
 		pr_dbg("isicom_shutdown_port: bad board(0x%lx) count %d.\n",
 			card->base, card->count);
 		card->count = 0;
 	}
-
-	/* last port was closed, shutdown that boad too */
-	if (C_HUPCL(tty)) {
-		if (!card->count)
-			isicom_shutdown_board(card);
-	}
-	tty_kref_put(tty);
+	/* last port was closed, shutdown that board too */
+	if (!card->count)
+		card->status &= BOARD_ACTIVE;
 }
 
 static void isicom_flush_buffer(struct tty_struct *tty)
@@ -968,7 +913,7 @@
 	tty_wakeup(tty);
 }
 
-static void isicom_close_port(struct tty_port *port)
+static void isicom_shutdown(struct tty_port *port)
 {
 	struct isi_port *ip = container_of(port, struct isi_port, port);
 	struct isi_board *card = ip->card;
@@ -977,12 +922,11 @@
 	/* indicate to the card that no more data can be received
 	   on this port */
 	spin_lock_irqsave(&card->card_lock, flags);
-	if (port->flags & ASYNC_INITIALIZED) {
-		card->port_status &= ~(1 << ip->channel);
-		outw(card->port_status, card->base + 0x02);
-	}
+	card->port_status &= ~(1 << ip->channel);
+	outw(card->port_status, card->base + 0x02);
 	isicom_shutdown_port(ip);
 	spin_unlock_irqrestore(&card->card_lock, flags);
+	tty_port_free_xmit_buf(port);
 }
 
 static void isicom_close(struct tty_struct *tty, struct file *filp)
@@ -991,12 +935,7 @@
 	struct tty_port *port = &ip->port;
 	if (isicom_paranoia_check(ip, tty->name, "isicom_close"))
 		return;
-
-	if (tty_port_close_start(port, tty, filp) == 0)
-		return;
-	isicom_close_port(port);
-	isicom_flush_buffer(tty);
-	tty_port_close_end(port, tty);
+	tty_port_close(port, tty, filp);
 }
 
 /* write et all */
@@ -1326,15 +1265,9 @@
 static void isicom_hangup(struct tty_struct *tty)
 {
 	struct isi_port *port = tty->driver_data;
-	unsigned long flags;
 
 	if (isicom_paranoia_check(port, tty->name, "isicom_hangup"))
 		return;
-
-	spin_lock_irqsave(&port->card->card_lock, flags);
-	isicom_shutdown_port(port);
-	spin_unlock_irqrestore(&port->card->card_lock, flags);
-
 	tty_port_hangup(&port->port);
 }
 
@@ -1367,6 +1300,8 @@
 static const struct tty_port_operations isicom_port_ops = {
 	.carrier_raised		= isicom_carrier_raised,
 	.dtr_rts		= isicom_dtr_rts,
+	.activate		= isicom_activate,
+	.shutdown		= isicom_shutdown,
 };
 
 static int __devinit reset_card(struct pci_dev *pdev,
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 402838f..4cd6c52 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -213,7 +213,6 @@
  *	with the slave. Most of them need to be updated atomically, so always
  *	use the bit setting operations (unless protected by cli/sti).
  */
-#define	ST_INITIALIZING	1
 #define	ST_OPENING	2
 #define	ST_CLOSING	3
 #define	ST_CMDING	4
@@ -621,7 +620,7 @@
 static int	stli_startbrd(struct stlibrd *brdp);
 static ssize_t	stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp);
 static ssize_t	stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp);
-static int	stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
+static long	stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg);
 static void	stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp);
 static void	stli_poll(unsigned long arg);
 static int	stli_hostcmd(struct stlibrd *brdp, struct stliport *portp);
@@ -704,7 +703,7 @@
 	.owner		= THIS_MODULE,
 	.read		= stli_memread,
 	.write		= stli_memwrite,
-	.ioctl		= stli_memioctl,
+	.unlocked_ioctl	= stli_memioctl,
 };
 
 /*****************************************************************************/
@@ -783,13 +782,32 @@
 
 /*****************************************************************************/
 
+/*
+ *	On the first open of the device setup the port hardware, and
+ *	initialize the per port data structure. Since initializing the port
+ *	requires several commands to the board we will need to wait for any
+ *	other open that is already initializing the port.
+ *
+ *	Locking: protected by the port mutex.
+ */
+
+static int stli_activate(struct tty_port *port, struct tty_struct *tty)
+{
+	struct stliport *portp = container_of(port, struct stliport, port);
+	struct stlibrd *brdp = stli_brds[portp->brdnr];
+	int rc;
+
+	if ((rc = stli_initopen(tty, brdp, portp)) >= 0)
+		clear_bit(TTY_IO_ERROR, &tty->flags);
+	wake_up_interruptible(&portp->raw_wait);
+	return rc;
+}
+
 static int stli_open(struct tty_struct *tty, struct file *filp)
 {
 	struct stlibrd *brdp;
 	struct stliport *portp;
-	struct tty_port *port;
 	unsigned int minordev, brdnr, portnr;
-	int rc;
 
 	minordev = tty->index;
 	brdnr = MINOR2BRD(minordev);
@@ -809,95 +827,56 @@
 		return -ENODEV;
 	if (portp->devnr < 1)
 		return -ENODEV;
-	port = &portp->port;
-
-/*
- *	On the first open of the device setup the port hardware, and
- *	initialize the per port data structure. Since initializing the port
- *	requires several commands to the board we will need to wait for any
- *	other open that is already initializing the port.
- *
- *	Review - locking
- */
-	tty_port_tty_set(port, tty);
-	tty->driver_data = portp;
-	port->count++;
-
-	wait_event_interruptible(portp->raw_wait,
-			!test_bit(ST_INITIALIZING, &portp->state));
-	if (signal_pending(current))
-		return -ERESTARTSYS;
-
-	if ((portp->port.flags & ASYNC_INITIALIZED) == 0) {
-		set_bit(ST_INITIALIZING, &portp->state);
-		if ((rc = stli_initopen(tty, brdp, portp)) >= 0) {
-			/* Locking */
-			port->flags |= ASYNC_INITIALIZED;
-			clear_bit(TTY_IO_ERROR, &tty->flags);
-		}
-		clear_bit(ST_INITIALIZING, &portp->state);
-		wake_up_interruptible(&portp->raw_wait);
-		if (rc < 0)
-			return rc;
-	}
-	return tty_port_block_til_ready(&portp->port, tty, filp);
+	return tty_port_open(&portp->port, tty, filp);
 }
 
+
 /*****************************************************************************/
 
-static void stli_close(struct tty_struct *tty, struct file *filp)
+static void stli_shutdown(struct tty_port *port)
 {
 	struct stlibrd *brdp;
-	struct stliport *portp;
-	struct tty_port *port;
+	unsigned long ftype;
 	unsigned long flags;
+	struct stliport *portp = container_of(port, struct stliport, port);
 
-	portp = tty->driver_data;
+	if (portp->brdnr >= stli_nrbrds)
+		return;
+	brdp = stli_brds[portp->brdnr];
+	if (brdp == NULL)
+		return;
+
+	/*
+	 *	May want to wait for data to drain before closing. The BUSY
+	 *	flag keeps track of whether we are still transmitting or not.
+	 *	It is updated by messages from the slave - indicating when all
+	 *	chars really have drained.
+	 */
+
+	if (!test_bit(ST_CLOSING, &portp->state))
+		stli_rawclose(brdp, portp, 0, 0);
+
+ 	spin_lock_irqsave(&stli_lock, flags);
+	clear_bit(ST_TXBUSY, &portp->state);
+	clear_bit(ST_RXSTOP, &portp->state);
+	spin_unlock_irqrestore(&stli_lock, flags);
+
+	ftype = FLUSHTX | FLUSHRX;
+	stli_cmdwait(brdp, portp, A_FLUSH, &ftype, sizeof(u32), 0);
+}
+
+static void stli_close(struct tty_struct *tty, struct file *filp)
+{
+	struct stliport *portp = tty->driver_data;
+	unsigned long flags;
 	if (portp == NULL)
 		return;
-	port = &portp->port;
-
-	if (tty_port_close_start(port, tty, filp) == 0)
-		return;
-
-/*
- *	May want to wait for data to drain before closing. The BUSY flag
- *	keeps track of whether we are still transmitting or not. It is
- *	updated by messages from the slave - indicating when all chars
- *	really have drained.
- */
  	spin_lock_irqsave(&stli_lock, flags);
+	/*	Flush any internal buffering out first */
 	if (tty == stli_txcooktty)
 		stli_flushchars(tty);
 	spin_unlock_irqrestore(&stli_lock, flags);
-
-	/* We end up doing this twice for the moment. This needs looking at
-	   eventually. Note we still use portp->closing_wait as a result */
-	if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-		tty_wait_until_sent(tty, portp->closing_wait);
-
-	/* FIXME: port locking here needs attending to */
-	port->flags &= ~ASYNC_INITIALIZED;
-
-	brdp = stli_brds[portp->brdnr];
-	stli_rawclose(brdp, portp, 0, 0);
-	if (tty->termios->c_cflag & HUPCL) {
-		stli_mkasysigs(&portp->asig, 0, 0);
-		if (test_bit(ST_CMDING, &portp->state))
-			set_bit(ST_DOSIGS, &portp->state);
-		else
-			stli_sendcmd(brdp, portp, A_SETSIGNALS, &portp->asig,
-				sizeof(asysigs_t), 0);
-	}
-	clear_bit(ST_TXBUSY, &portp->state);
-	clear_bit(ST_RXSTOP, &portp->state);
-	set_bit(TTY_IO_ERROR, &tty->flags);
-	tty_ldisc_flush(tty);
-	set_bit(ST_DOFLUSHRX, &portp->state);
-	stli_flushbuffer(tty);
-
-	tty_port_close_end(port, tty);
-	tty_port_tty_set(port, NULL);
+	tty_port_close(&portp->port, tty, filp);
 }
 
 /*****************************************************************************/
@@ -1724,6 +1703,7 @@
 
 /*****************************************************************************/
 
+
 /*
  *	Hangup this port. This is pretty much like closing the port, only
  *	a little more brutal. No waiting for data to drain. Shutdown the
@@ -1733,47 +1713,8 @@
 
 static void stli_hangup(struct tty_struct *tty)
 {
-	struct stliport *portp;
-	struct stlibrd *brdp;
-	struct tty_port *port;
-	unsigned long flags;
-
-	portp = tty->driver_data;
-	if (portp == NULL)
-		return;
-	if (portp->brdnr >= stli_nrbrds)
-		return;
-	brdp = stli_brds[portp->brdnr];
-	if (brdp == NULL)
-		return;
-	port = &portp->port;
-
-	spin_lock_irqsave(&port->lock, flags);
-	port->flags &= ~ASYNC_INITIALIZED;
-	spin_unlock_irqrestore(&port->lock, flags);
-
-	if (!test_bit(ST_CLOSING, &portp->state))
-		stli_rawclose(brdp, portp, 0, 0);
-
-	spin_lock_irqsave(&stli_lock, flags);
-	if (tty->termios->c_cflag & HUPCL) {
-		stli_mkasysigs(&portp->asig, 0, 0);
-		if (test_bit(ST_CMDING, &portp->state)) {
-			set_bit(ST_DOSIGS, &portp->state);
-			set_bit(ST_DOFLUSHTX, &portp->state);
-			set_bit(ST_DOFLUSHRX, &portp->state);
-		} else {
-			stli_sendcmd(brdp, portp, A_SETSIGNALSF,
-				&portp->asig, sizeof(asysigs_t), 0);
-		}
-	}
-
-	clear_bit(ST_TXBUSY, &portp->state);
-	clear_bit(ST_RXSTOP, &portp->state);
-	set_bit(TTY_IO_ERROR, &tty->flags);
-	spin_unlock_irqrestore(&stli_lock, flags);
-
-	tty_port_hangup(port);
+	struct stliport *portp = tty->driver_data;
+	tty_port_hangup(&portp->port);
 }
 
 /*****************************************************************************/
@@ -4311,7 +4252,7 @@
  *	reset it, and start/stop it.
  */
 
-static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
+static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg)
 {
 	struct stlibrd *brdp;
 	int brdnr, rc, done;
@@ -4356,7 +4297,7 @@
  *	Now handle the board specific ioctls. These all depend on the
  *	minor number of the device they were called from.
  */
-	brdnr = iminor(ip);
+	brdnr = iminor(fp->f_dentry->d_inode);
 	if (brdnr >= STL_MAXBRDS)
 		return -ENODEV;
 	brdp = stli_brds[brdnr];
@@ -4420,6 +4361,8 @@
 static const struct tty_port_operations stli_port_ops = {
 	.carrier_raised = stli_carrier_raised,
 	.dtr_rts = stli_dtr_rts,
+	.activate = stli_activate,
+	.shutdown = stli_shutdown,
 };
 
 /*****************************************************************************/
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 950837c..5619007 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -46,8 +46,6 @@
 
 extern void ctrl_alt_del(void);
 
-#define to_handle_h(n) container_of(n, struct input_handle, h_node)
-
 /*
  * Exported functions/variables
  */
@@ -132,6 +130,7 @@
  */
 
 static struct input_handler kbd_handler;
+static DEFINE_SPINLOCK(kbd_event_lock);
 static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)];	/* keyboard key bitmap */
 static unsigned char shift_down[NR_SHIFT];		/* shift state counters.. */
 static int dead_key_next;
@@ -190,78 +189,85 @@
  *  etc.). So this means that scancodes for the extra function keys won't
  *  be valid for the first event device, but will be for the second.
  */
+
+struct getset_keycode_data {
+	unsigned int scancode;
+	unsigned int keycode;
+	int error;
+};
+
+static int getkeycode_helper(struct input_handle *handle, void *data)
+{
+	struct getset_keycode_data *d = data;
+
+	d->error = input_get_keycode(handle->dev, d->scancode, &d->keycode);
+
+	return d->error == 0; /* stop as soon as we successfully get one */
+}
+
 int getkeycode(unsigned int scancode)
 {
-	struct input_handle *handle;
-	int keycode;
-	int error = -ENODEV;
+	struct getset_keycode_data d = { scancode, 0, -ENODEV };
 
-	list_for_each_entry(handle, &kbd_handler.h_list, h_node) {
-		error = input_get_keycode(handle->dev, scancode, &keycode);
-		if (!error)
-			return keycode;
-	}
+	input_handler_for_each_handle(&kbd_handler, &d, getkeycode_helper);
 
-	return error;
+	return d.error ?: d.keycode;
+}
+
+static int setkeycode_helper(struct input_handle *handle, void *data)
+{
+	struct getset_keycode_data *d = data;
+
+	d->error = input_set_keycode(handle->dev, d->scancode, d->keycode);
+
+	return d->error == 0; /* stop as soon as we successfully set one */
 }
 
 int setkeycode(unsigned int scancode, unsigned int keycode)
 {
-	struct input_handle *handle;
-	int error = -ENODEV;
+	struct getset_keycode_data d = { scancode, keycode, -ENODEV };
 
-	list_for_each_entry(handle, &kbd_handler.h_list, h_node) {
-		error = input_set_keycode(handle->dev, scancode, keycode);
-		if (!error)
-			break;
-	}
+	input_handler_for_each_handle(&kbd_handler, &d, setkeycode_helper);
 
-	return error;
+	return d.error;
 }
 
 /*
  * Making beeps and bells.
  */
+
+static int kd_sound_helper(struct input_handle *handle, void *data)
+{
+	unsigned int *hz = data;
+	struct input_dev *dev = handle->dev;
+
+	if (test_bit(EV_SND, dev->evbit)) {
+		if (test_bit(SND_TONE, dev->sndbit))
+			input_inject_event(handle, EV_SND, SND_TONE, *hz);
+		if (test_bit(SND_BELL, handle->dev->sndbit))
+			input_inject_event(handle, EV_SND, SND_BELL, *hz ? 1 : 0);
+	}
+
+	return 0;
+}
+
 static void kd_nosound(unsigned long ignored)
 {
-	struct input_handle *handle;
+	static unsigned int zero;
 
-	list_for_each_entry(handle, &kbd_handler.h_list, h_node) {
-		if (test_bit(EV_SND, handle->dev->evbit)) {
-			if (test_bit(SND_TONE, handle->dev->sndbit))
-				input_inject_event(handle, EV_SND, SND_TONE, 0);
-			if (test_bit(SND_BELL, handle->dev->sndbit))
-				input_inject_event(handle, EV_SND, SND_BELL, 0);
-		}
-	}
+	input_handler_for_each_handle(&kbd_handler, &zero, kd_sound_helper);
 }
 
 static DEFINE_TIMER(kd_mksound_timer, kd_nosound, 0, 0);
 
 void kd_mksound(unsigned int hz, unsigned int ticks)
 {
-	struct list_head *node;
+	del_timer_sync(&kd_mksound_timer);
 
-	del_timer(&kd_mksound_timer);
+	input_handler_for_each_handle(&kbd_handler, &hz, kd_sound_helper);
 
-	if (hz) {
-		list_for_each_prev(node, &kbd_handler.h_list) {
-			struct input_handle *handle = to_handle_h(node);
-			if (test_bit(EV_SND, handle->dev->evbit)) {
-				if (test_bit(SND_TONE, handle->dev->sndbit)) {
-					input_inject_event(handle, EV_SND, SND_TONE, hz);
-					break;
-				}
-				if (test_bit(SND_BELL, handle->dev->sndbit)) {
-					input_inject_event(handle, EV_SND, SND_BELL, 1);
-					break;
-				}
-			}
-		}
-		if (ticks)
-			mod_timer(&kd_mksound_timer, jiffies + ticks);
-	} else
-		kd_nosound(0);
+	if (hz && ticks)
+		mod_timer(&kd_mksound_timer, jiffies + ticks);
 }
 EXPORT_SYMBOL(kd_mksound);
 
@@ -269,27 +275,34 @@
  * Setting the keyboard rate.
  */
 
+static int kbd_rate_helper(struct input_handle *handle, void *data)
+{
+	struct input_dev *dev = handle->dev;
+	struct kbd_repeat *rep = data;
+
+	if (test_bit(EV_REP, dev->evbit)) {
+
+		if (rep[0].delay > 0)
+			input_inject_event(handle,
+					   EV_REP, REP_DELAY, rep[0].delay);
+		if (rep[0].period > 0)
+			input_inject_event(handle,
+					   EV_REP, REP_PERIOD, rep[0].period);
+
+		rep[1].delay = dev->rep[REP_DELAY];
+		rep[1].period = dev->rep[REP_PERIOD];
+	}
+
+	return 0;
+}
+
 int kbd_rate(struct kbd_repeat *rep)
 {
-	struct list_head *node;
-	unsigned int d = 0;
-	unsigned int p = 0;
+	struct kbd_repeat data[2] = { *rep };
 
-	list_for_each(node, &kbd_handler.h_list) {
-		struct input_handle *handle = to_handle_h(node);
-		struct input_dev *dev = handle->dev;
+	input_handler_for_each_handle(&kbd_handler, data, kbd_rate_helper);
+	*rep = data[1];	/* Copy currently used settings */
 
-		if (test_bit(EV_REP, dev->evbit)) {
-			if (rep->delay > 0)
-				input_inject_event(handle, EV_REP, REP_DELAY, rep->delay);
-			if (rep->period > 0)
-				input_inject_event(handle, EV_REP, REP_PERIOD, rep->period);
-			d = dev->rep[REP_DELAY];
-			p = dev->rep[REP_PERIOD];
-		}
-	}
-	rep->delay  = d;
-	rep->period = p;
 	return 0;
 }
 
@@ -997,36 +1010,36 @@
 	return leds;
 }
 
-/*
- * This routine is the bottom half of the keyboard interrupt
- * routine, and runs with all interrupts enabled. It does
- * console changing, led setting and copy_to_cooked, which can
- * take a reasonably long time.
- *
- * Aside from timing (which isn't really that important for
- * keyboard interrupts as they happen often), using the software
- * interrupt routines for this thing allows us to easily mask
- * this when we don't want any of the above to happen.
- * This allows for easy and efficient race-condition prevention
- * for kbd_start => input_inject_event(dev, EV_LED, ...) => ...
- */
+static int kbd_update_leds_helper(struct input_handle *handle, void *data)
+{
+	unsigned char leds = *(unsigned char *)data;
 
+	if (test_bit(EV_LED, handle->dev->evbit)) {
+		input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
+		input_inject_event(handle, EV_LED, LED_NUML,    !!(leds & 0x02));
+		input_inject_event(handle, EV_LED, LED_CAPSL,   !!(leds & 0x04));
+		input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
+	}
+
+	return 0;
+}
+
+/*
+ * This is the tasklet that updates LED state on all keyboards
+ * attached to the box. The reason we use tasklet is that we
+ * need to handle the scenario when keyboard handler is not
+ * registered yet but we already getting updates form VT to
+ * update led state.
+ */
 static void kbd_bh(unsigned long dummy)
 {
-	struct list_head *node;
 	unsigned char leds = getleds();
 
 	if (leds != ledstate) {
-		list_for_each(node, &kbd_handler.h_list) {
-			struct input_handle *handle = to_handle_h(node);
-			input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
-			input_inject_event(handle, EV_LED, LED_NUML,    !!(leds & 0x02));
-			input_inject_event(handle, EV_LED, LED_CAPSL,   !!(leds & 0x04));
-			input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
-		}
+		input_handler_for_each_handle(&kbd_handler, &leds,
+					      kbd_update_leds_helper);
+		ledstate = leds;
 	}
-
-	ledstate = leds;
 }
 
 DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
@@ -1136,7 +1149,7 @@
 static void kbd_rawcode(unsigned char data)
 {
 	struct vc_data *vc = vc_cons[fg_console].d;
-	kbd = kbd_table + fg_console;
+	kbd = kbd_table + vc->vc_num;
 	if (kbd->kbdmode == VC_RAW)
 		put_queue(vc, data);
 }
@@ -1157,7 +1170,7 @@
 		tty->driver_data = vc;
 	}
 
-	kbd = kbd_table + fg_console;
+	kbd = kbd_table + vc->vc_num;
 
 	if (keycode == KEY_LEFTALT || keycode == KEY_RIGHTALT)
 		sysrq_alt = down ? keycode : 0;
@@ -1296,10 +1309,16 @@
 static void kbd_event(struct input_handle *handle, unsigned int event_type,
 		      unsigned int event_code, int value)
 {
+	/* We are called with interrupts disabled, just take the lock */
+	spin_lock(&kbd_event_lock);
+
 	if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev))
 		kbd_rawcode(value);
 	if (event_type == EV_KEY)
 		kbd_keycode(event_code, value, HW_RAW(handle->dev));
+
+	spin_unlock(&kbd_event_lock);
+
 	tasklet_schedule(&keyboard_tasklet);
 	do_poke_blanked_console = 1;
 	schedule_console_callback();
@@ -1363,15 +1382,11 @@
  */
 static void kbd_start(struct input_handle *handle)
 {
-	unsigned char leds = ledstate;
-
 	tasklet_disable(&keyboard_tasklet);
-	if (leds != 0xff) {
-		input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
-		input_inject_event(handle, EV_LED, LED_NUML,    !!(leds & 0x02));
-		input_inject_event(handle, EV_LED, LED_CAPSL,   !!(leds & 0x04));
-		input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
-	}
+
+	if (ledstate != 0xff)
+		kbd_update_leds_helper(handle, &ledstate);
+
 	tasklet_enable(&keyboard_tasklet);
 }
 
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index a074fce..fba76fb 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -5,7 +5,7 @@
  *
  *  Added devfs support. 
  *    Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu>
- *  Shared /dev/zero mmaping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com>
+ *  Shared /dev/zero mmapping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com>
  */
 
 #include <linux/mm.h>
@@ -26,7 +26,6 @@
 #include <linux/bootmem.h>
 #include <linux/splice.h>
 #include <linux/pfn.h>
-#include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -44,7 +43,7 @@
 {
 #if defined(CONFIG_IA64)
 	/*
-	 * On ia64, we ignore O_SYNC because we cannot tolerate memory attribute aliases.
+	 * On ia64, we ignore O_DSYNC because we cannot tolerate memory attribute aliases.
 	 */
 	return !(efi_mem_attributes(addr) & EFI_MEMORY_WB);
 #elif defined(CONFIG_MIPS)
@@ -57,9 +56,9 @@
 #else
 	/*
 	 * Accessing memory above the top the kernel knows about or through a file pointer
-	 * that was marked O_SYNC will be done non-cached.
+	 * that was marked O_DSYNC will be done non-cached.
 	 */
-	if (file->f_flags & O_SYNC)
+	if (file->f_flags & O_DSYNC)
 		return 1;
 	return addr >= __pa(high_memory);
 #endif
@@ -892,29 +891,23 @@
 {
 	int minor;
 	const struct memdev *dev;
-	int ret = -ENXIO;
-
-	lock_kernel();
 
 	minor = iminor(inode);
 	if (minor >= ARRAY_SIZE(devlist))
-		goto out;
+		return -ENXIO;
 
 	dev = &devlist[minor];
 	if (!dev->fops)
-		goto out;
+		return -ENXIO;
 
 	filp->f_op = dev->fops;
 	if (dev->dev_info)
 		filp->f_mapping->backing_dev_info = dev->dev_info;
 
 	if (dev->fops->open)
-		ret = dev->fops->open(inode, filp);
-	else
-		ret = 0;
-out:
-	unlock_kernel();
-	return ret;
+		return dev->fops->open(inode, filp);
+
+	return 0;
 }
 
 static const struct file_operations memory_fops = {
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index 07fa612..96f1cd0 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -49,7 +49,6 @@
 #include <linux/device.h>
 #include <linux/tty.h>
 #include <linux/kmod.h>
-#include <linux/smp_lock.h>
 
 /*
  * Head entry for the doubly linked miscdevice list
@@ -118,8 +117,7 @@
 	struct miscdevice *c;
 	int err = -ENODEV;
 	const struct file_operations *old_fops, *new_fops = NULL;
-	
-	lock_kernel();
+
 	mutex_lock(&misc_mtx);
 	
 	list_for_each_entry(c, &misc_list, list) {
@@ -157,7 +155,6 @@
 	fops_put(old_fops);
 fail:
 	mutex_unlock(&misc_mtx);
-	unlock_kernel();
 	return err;
 }
 
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index dd0083b..63ee3bb 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -34,7 +34,6 @@
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/major.h>
-#include <linux/smp_lock.h>
 #include <linux/string.h>
 #include <linux/fcntl.h>
 #include <linux/ptrace.h>
@@ -139,7 +138,7 @@
 	int cflag;
 	unsigned long statusflags;
 
-	u8 DCDState;
+	u8 DCDState;		/* Protected by the port lock */
 	u8 lineCtrl;
 	u8 lowChkFlag;
 };
@@ -151,10 +150,9 @@
 };
 
 /* statusflags */
-#define TXSTOPPED	0x1
-#define LOWWAIT 	0x2
-#define EMPTYWAIT	0x4
-#define THROTTLE	0x8
+#define TXSTOPPED	1
+#define LOWWAIT 	2
+#define EMPTYWAIT	3
 
 #define SERIAL_DO_RESTART
 
@@ -165,6 +163,7 @@
 static unsigned int moxaFuncTout = HZ / 2;
 static unsigned int moxaLowWaterChk;
 static DEFINE_MUTEX(moxa_openlock);
+static DEFINE_SPINLOCK(moxa_lock);
 /* Variables for insmod */
 #ifdef MODULE
 static unsigned long baseaddr[MAX_BOARDS];
@@ -194,8 +193,6 @@
 static int moxa_write_room(struct tty_struct *);
 static void moxa_flush_buffer(struct tty_struct *);
 static int moxa_chars_in_buffer(struct tty_struct *);
-static void moxa_throttle(struct tty_struct *);
-static void moxa_unthrottle(struct tty_struct *);
 static void moxa_set_termios(struct tty_struct *, struct ktermios *);
 static void moxa_stop(struct tty_struct *);
 static void moxa_start(struct tty_struct *);
@@ -205,9 +202,9 @@
 			 unsigned int set, unsigned int clear);
 static void moxa_poll(unsigned long);
 static void moxa_set_tty_param(struct tty_struct *, struct ktermios *);
-static void moxa_setup_empty_event(struct tty_struct *);
-static void moxa_shut_down(struct tty_struct *);
+static void moxa_shutdown(struct tty_port *);
 static int moxa_carrier_raised(struct tty_port *);
+static void moxa_dtr_rts(struct tty_port *, int);
 /*
  * moxa board interface functions:
  */
@@ -234,6 +231,8 @@
  * I/O functions
  */
 
+static DEFINE_SPINLOCK(moxafunc_lock);
+
 static void moxa_wait_finish(void __iomem *ofsAddr)
 {
 	unsigned long end = jiffies + moxaFuncTout;
@@ -247,9 +246,25 @@
 
 static void moxafunc(void __iomem *ofsAddr, u16 cmd, u16 arg)
 {
+        unsigned long flags;
+        spin_lock_irqsave(&moxafunc_lock, flags);
 	writew(arg, ofsAddr + FuncArg);
 	writew(cmd, ofsAddr + FuncCode);
 	moxa_wait_finish(ofsAddr);
+	spin_unlock_irqrestore(&moxafunc_lock, flags);
+}
+
+static int moxafuncret(void __iomem *ofsAddr, u16 cmd, u16 arg)
+{
+        unsigned long flags;
+        u16 ret;
+        spin_lock_irqsave(&moxafunc_lock, flags);
+	writew(arg, ofsAddr + FuncArg);
+	writew(cmd, ofsAddr + FuncCode);
+	moxa_wait_finish(ofsAddr);
+	ret = readw(ofsAddr + FuncArg);
+	spin_unlock_irqrestore(&moxafunc_lock, flags);
+	return ret;
 }
 
 static void moxa_low_water_check(void __iomem *ofsAddr)
@@ -299,22 +314,20 @@
 		struct moxa_port *p;
 		unsigned int i, j;
 
-		mutex_lock(&moxa_openlock);
 		for (i = 0; i < MAX_BOARDS; i++) {
 			p = moxa_boards[i].ports;
 			for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
 				memset(&tmp, 0, sizeof(tmp));
+				spin_lock_bh(&moxa_lock);
 				if (moxa_boards[i].ready) {
 					tmp.inq = MoxaPortRxQueue(p);
 					tmp.outq = MoxaPortTxQueue(p);
 				}
-				if (copy_to_user(argm, &tmp, sizeof(tmp))) {
-					mutex_unlock(&moxa_openlock);
+				spin_unlock_bh(&moxa_lock);
+				if (copy_to_user(argm, &tmp, sizeof(tmp)))
 					return -EFAULT;
-				}
 			}
 		}
-		mutex_unlock(&moxa_openlock);
 		break;
 	} case MOXA_GET_OQUEUE:
 		status = MoxaPortTxQueue(ch);
@@ -330,16 +343,20 @@
 		struct moxa_port *p;
 		unsigned int i, j;
 
-		mutex_lock(&moxa_openlock);
 		for (i = 0; i < MAX_BOARDS; i++) {
 			p = moxa_boards[i].ports;
 			for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
 				struct tty_struct *ttyp;
 				memset(&tmp, 0, sizeof(tmp));
-				if (!moxa_boards[i].ready)
+				spin_lock_bh(&moxa_lock);
+				if (!moxa_boards[i].ready) {
+				        spin_unlock_bh(&moxa_lock);
 					goto copy;
+                                }
 
 				status = MoxaPortLineStatus(p);
+				spin_unlock_bh(&moxa_lock);
+
 				if (status & 1)
 					tmp.cts = 1;
 				if (status & 2)
@@ -354,24 +371,21 @@
 					tmp.cflag = ttyp->termios->c_cflag;
 				tty_kref_put(tty);
 copy:
-				if (copy_to_user(argm, &tmp, sizeof(tmp))) {
-					mutex_unlock(&moxa_openlock);
+				if (copy_to_user(argm, &tmp, sizeof(tmp)))
 					return -EFAULT;
-				}
 			}
 		}
-		mutex_unlock(&moxa_openlock);
 		break;
 	}
 	case TIOCGSERIAL:
-		mutex_lock(&moxa_openlock);
+	        mutex_lock(&ch->port.mutex);
 		ret = moxa_get_serial_info(ch, argp);
-		mutex_unlock(&moxa_openlock);
+		mutex_unlock(&ch->port.mutex);
 		break;
 	case TIOCSSERIAL:
-		mutex_lock(&moxa_openlock);
+	        mutex_lock(&ch->port.mutex);
 		ret = moxa_set_serial_info(ch, argp);
-		mutex_unlock(&moxa_openlock);
+		mutex_unlock(&ch->port.mutex);
 		break;
 	default:
 		ret = -ENOIOCTLCMD;
@@ -396,8 +410,6 @@
 	.flush_buffer = moxa_flush_buffer,
 	.chars_in_buffer = moxa_chars_in_buffer,
 	.ioctl = moxa_ioctl,
-	.throttle = moxa_throttle,
-	.unthrottle = moxa_unthrottle,
 	.set_termios = moxa_set_termios,
 	.stop = moxa_stop,
 	.start = moxa_start,
@@ -409,11 +421,12 @@
 
 static const struct tty_port_operations moxa_port_ops = {
 	.carrier_raised = moxa_carrier_raised,
+	.dtr_rts = moxa_dtr_rts,
+	.shutdown = moxa_shutdown,
 };
 
 static struct tty_driver *moxaDriver;
 static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0);
-static DEFINE_SPINLOCK(moxa_lock);
 
 /*
  * HW init
@@ -1112,14 +1125,12 @@
 module_init(moxa_init);
 module_exit(moxa_exit);
 
-static void moxa_close_port(struct tty_struct *tty)
+static void moxa_shutdown(struct tty_port *port)
 {
-	struct moxa_port *ch = tty->driver_data;
-	moxa_shut_down(tty);
+	struct moxa_port *ch = container_of(port, struct moxa_port, port);
+        MoxaPortDisable(ch);
 	MoxaPortFlushData(ch, 2);
-	ch->port.flags &= ~ASYNC_NORMAL_ACTIVE;
-	tty->driver_data = NULL;
-	tty_port_tty_set(&ch->port, NULL);
+	clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
 }
 
 static int moxa_carrier_raised(struct tty_port *port)
@@ -1127,45 +1138,19 @@
 	struct moxa_port *ch = container_of(port, struct moxa_port, port);
 	int dcd;
 
-	spin_lock_bh(&moxa_lock);
+	spin_lock_irq(&port->lock);
 	dcd = ch->DCDState;
-	spin_unlock_bh(&moxa_lock);
+	spin_unlock_irq(&port->lock);
 	return dcd;
 }
 
-static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
-			    struct moxa_port *ch)
+static void moxa_dtr_rts(struct tty_port *port, int onoff)
 {
-	struct tty_port *port = &ch->port;
-	DEFINE_WAIT(wait);
-	int retval = 0;
-	u8 dcd;
-
-	while (1) {
-		prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
-		if (tty_hung_up_p(filp)) {
-#ifdef SERIAL_DO_RESTART
-			retval = -ERESTARTSYS;
-#else
-			retval = -EAGAIN;
-#endif
-			break;
-		}
-		dcd = tty_port_carrier_raised(port);
-		if (dcd)
-			break;
-
-		if (signal_pending(current)) {
-			retval = -ERESTARTSYS;
-			break;
-		}
-		schedule();
-	}
-	finish_wait(&port->open_wait, &wait);
-
-	return retval;
+	struct moxa_port *ch = container_of(port, struct moxa_port, port);
+	MoxaPortLineCtrl(ch, onoff, onoff);
 }
 
+
 static int moxa_open(struct tty_struct *tty, struct file *filp)
 {
 	struct moxa_board_conf *brd;
@@ -1194,6 +1179,7 @@
 	ch->port.count++;
 	tty->driver_data = ch;
 	tty_port_tty_set(&ch->port, tty);
+	mutex_lock(&ch->port.mutex);
 	if (!(ch->port.flags & ASYNC_INITIALIZED)) {
 		ch->statusflags = 0;
 		moxa_set_tty_param(tty, tty->termios);
@@ -1202,58 +1188,20 @@
 		MoxaSetFifo(ch, ch->type == PORT_16550A);
 		ch->port.flags |= ASYNC_INITIALIZED;
 	}
+	mutex_unlock(&ch->port.mutex);
 	mutex_unlock(&moxa_openlock);
 
-	retval = 0;
-	if (!(filp->f_flags & O_NONBLOCK) && !C_CLOCAL(tty))
-		retval = moxa_block_till_ready(tty, filp, ch);
-	mutex_lock(&moxa_openlock);
-	if (retval) {
-		if (ch->port.count) /* 0 means already hung up... */
-			if (--ch->port.count == 0)
-				moxa_close_port(tty);
-	} else
-		ch->port.flags |= ASYNC_NORMAL_ACTIVE;
-	mutex_unlock(&moxa_openlock);
-
+	retval = tty_port_block_til_ready(&ch->port, tty, filp);
+	if (retval == 0)
+	        set_bit(ASYNCB_NORMAL_ACTIVE, &ch->port.flags);
 	return retval;
 }
 
 static void moxa_close(struct tty_struct *tty, struct file *filp)
 {
-	struct moxa_port *ch;
-	int port;
-
-	port = tty->index;
-	if (port == MAX_PORTS || tty_hung_up_p(filp))
-		return;
-
-	mutex_lock(&moxa_openlock);
-	ch = tty->driver_data;
-	if (ch == NULL)
-		goto unlock;
-	if (tty->count == 1 && ch->port.count != 1) {
-		printk(KERN_WARNING "moxa_close: bad serial port count; "
-			"tty->count is 1, ch->port.count is %d\n", ch->port.count);
-		ch->port.count = 1;
-	}
-	if (--ch->port.count < 0) {
-		printk(KERN_WARNING "moxa_close: bad serial port count, "
-			"device=%s\n", tty->name);
-		ch->port.count = 0;
-	}
-	if (ch->port.count)
-		goto unlock;
-
+	struct moxa_port *ch = tty->driver_data;
 	ch->cflag = tty->termios->c_cflag;
-	if (ch->port.flags & ASYNC_INITIALIZED) {
-		moxa_setup_empty_event(tty);
-		tty_wait_until_sent(tty, 30 * HZ);	/* 30 seconds timeout */
-	}
-
-	moxa_close_port(tty);
-unlock:
-	mutex_unlock(&moxa_openlock);
+	tty_port_close(&ch->port, tty, filp);
 }
 
 static int moxa_write(struct tty_struct *tty,
@@ -1269,7 +1217,7 @@
 	len = MoxaPortWriteData(tty, buf, count);
 	spin_unlock_bh(&moxa_lock);
 
-	ch->statusflags |= LOWWAIT;
+	set_bit(LOWWAIT, &ch->statusflags);
 	return len;
 }
 
@@ -1300,40 +1248,21 @@
 	struct moxa_port *ch = tty->driver_data;
 	int chars;
 
-	/*
-	 * Sigh...I have to check if driver_data is NULL here, because
-	 * if an open() fails, the TTY subsystem eventually calls
-	 * tty_wait_until_sent(), which calls the driver's chars_in_buffer()
-	 * routine.  And since the open() failed, we return 0 here.  TDJ
-	 */
-	if (ch == NULL)
-		return 0;
-	lock_kernel();
 	chars = MoxaPortTxQueue(ch);
-	if (chars) {
+	if (chars)
 		/*
 		 * Make it possible to wakeup anything waiting for output
 		 * in tty_ioctl.c, etc.
 		 */
-		if (!(ch->statusflags & EMPTYWAIT))
-			moxa_setup_empty_event(tty);
-	}
-	unlock_kernel();
+        	set_bit(EMPTYWAIT, &ch->statusflags);
 	return chars;
 }
 
 static int moxa_tiocmget(struct tty_struct *tty, struct file *file)
 {
-	struct moxa_port *ch;
+	struct moxa_port *ch = tty->driver_data;
 	int flag = 0, dtr, rts;
 
-	mutex_lock(&moxa_openlock);
-	ch = tty->driver_data;
-	if (!ch) {
-		mutex_unlock(&moxa_openlock);
-		return -EINVAL;
-	}
-
 	MoxaPortGetLineOut(ch, &dtr, &rts);
 	if (dtr)
 		flag |= TIOCM_DTR;
@@ -1346,7 +1275,6 @@
 		flag |= TIOCM_DSR;
 	if (dtr & 4)
 		flag |= TIOCM_CD;
-	mutex_unlock(&moxa_openlock);
 	return flag;
 }
 
@@ -1379,20 +1307,6 @@
 	return 0;
 }
 
-static void moxa_throttle(struct tty_struct *tty)
-{
-	struct moxa_port *ch = tty->driver_data;
-
-	ch->statusflags |= THROTTLE;
-}
-
-static void moxa_unthrottle(struct tty_struct *tty)
-{
-	struct moxa_port *ch = tty->driver_data;
-
-	ch->statusflags &= ~THROTTLE;
-}
-
 static void moxa_set_termios(struct tty_struct *tty,
 		struct ktermios *old_termios)
 {
@@ -1412,7 +1326,7 @@
 	if (ch == NULL)
 		return;
 	MoxaPortTxDisable(ch);
-	ch->statusflags |= TXSTOPPED;
+	set_bit(TXSTOPPED, &ch->statusflags);
 }
 
 
@@ -1427,38 +1341,32 @@
 		return;
 
 	MoxaPortTxEnable(ch);
-	ch->statusflags &= ~TXSTOPPED;
+	clear_bit(TXSTOPPED, &ch->statusflags);
 }
 
 static void moxa_hangup(struct tty_struct *tty)
 {
-	struct moxa_port *ch;
-
-	mutex_lock(&moxa_openlock);
-	ch = tty->driver_data;
-	if (ch == NULL) {
-		mutex_unlock(&moxa_openlock);
-		return;
-	}
-	ch->port.count = 0;
-	moxa_close_port(tty);
-	mutex_unlock(&moxa_openlock);
-
-	wake_up_interruptible(&ch->port.open_wait);
+	struct moxa_port *ch = tty->driver_data;
+	tty_port_hangup(&ch->port);
 }
 
 static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
 {
 	struct tty_struct *tty;
+	unsigned long flags;
 	dcd = !!dcd;
 
+	spin_lock_irqsave(&p->port.lock, flags);
 	if (dcd != p->DCDState) {
+        	p->DCDState = dcd;
+        	spin_unlock_irqrestore(&p->port.lock, flags);
 		tty = tty_port_tty_get(&p->port);
 		if (tty && C_CLOCAL(tty) && !dcd)
 			tty_hangup(tty);
 		tty_kref_put(tty);
 	}
-	p->DCDState = dcd;
+	else
+		spin_unlock_irqrestore(&p->port.lock, flags);
 }
 
 static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
@@ -1470,24 +1378,24 @@
 	u16 intr;
 
 	if (tty) {
-		if ((p->statusflags & EMPTYWAIT) &&
+		if (test_bit(EMPTYWAIT, &p->statusflags) &&
 				MoxaPortTxQueue(p) == 0) {
-			p->statusflags &= ~EMPTYWAIT;
+			clear_bit(EMPTYWAIT, &p->statusflags);
 			tty_wakeup(tty);
 		}
-		if ((p->statusflags & LOWWAIT) && !tty->stopped &&
+		if (test_bit(LOWWAIT, &p->statusflags) && !tty->stopped &&
 				MoxaPortTxQueue(p) <= WAKEUP_CHARS) {
-			p->statusflags &= ~LOWWAIT;
+			clear_bit(LOWWAIT, &p->statusflags);
 			tty_wakeup(tty);
 		}
 
-		if (inited && !(p->statusflags & THROTTLE) &&
+		if (inited && !test_bit(TTY_THROTTLED, &tty->flags) &&
 				MoxaPortRxQueue(p) > 0) { /* RX */
 			MoxaPortReadData(p);
 			tty_schedule_flip(tty);
 		}
 	} else {
-		p->statusflags &= ~EMPTYWAIT;
+		clear_bit(EMPTYWAIT, &p->statusflags);
 		MoxaPortFlushData(p, 0); /* flush RX */
 	}
 
@@ -1588,35 +1496,6 @@
 	tty_encode_baud_rate(tty, baud, baud);
 }
 
-static void moxa_setup_empty_event(struct tty_struct *tty)
-{
-	struct moxa_port *ch = tty->driver_data;
-
-	spin_lock_bh(&moxa_lock);
-	ch->statusflags |= EMPTYWAIT;
-	spin_unlock_bh(&moxa_lock);
-}
-
-static void moxa_shut_down(struct tty_struct *tty)
-{
-	struct moxa_port *ch = tty->driver_data;
-
-	if (!(ch->port.flags & ASYNC_INITIALIZED))
-		return;
-
-	MoxaPortDisable(ch);
-
-	/*
-	 * If we're a modem control device and HUPCL is on, drop RTS & DTR.
-	 */
-	if (C_HUPCL(tty))
-		MoxaPortLineCtrl(ch, 0, 0);
-
-	spin_lock_bh(&moxa_lock);
-	ch->port.flags &= ~ASYNC_INITIALIZED;
-	spin_unlock_bh(&moxa_lock);
-}
-
 /*****************************************************************************
  *	Driver level functions: 					     *
  *****************************************************************************/
@@ -1918,10 +1797,12 @@
 	baud = MoxaPortSetBaud(port, baud);
 
 	if (termio->c_iflag & (IXON | IXOFF | IXANY)) {
+	        spin_lock_irq(&moxafunc_lock);
 		writeb(termio->c_cc[VSTART], ofsAddr + FuncArg);
 		writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1);
 		writeb(FC_SetXonXoff, ofsAddr + FuncCode);
 		moxa_wait_finish(ofsAddr);
+		spin_unlock_irq(&moxafunc_lock);
 
 	}
 	return baud;
@@ -1974,18 +1855,14 @@
 	int val;
 
 	ofsAddr = port->tableAddr;
-	if (MOXA_IS_320(port->board)) {
-		moxafunc(ofsAddr, FC_LineStatus, 0);
-		val = readw(ofsAddr + FuncArg);
-	} else {
+	if (MOXA_IS_320(port->board))
+		val = moxafuncret(ofsAddr, FC_LineStatus, 0);
+	else
 		val = readw(ofsAddr + FlagStat) >> 4;
-	}
 	val &= 0x0B;
 	if (val & 8)
 		val |= 4;
-	spin_lock_bh(&moxa_lock);
 	moxa_new_dcdstate(port, val & 8);
-	spin_unlock_bh(&moxa_lock);
 	val &= 7;
 	return val;
 }
diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c
index 1997270..ecb89d7 100644
--- a/drivers/char/mspec.c
+++ b/drivers/char/mspec.c
@@ -248,7 +248,7 @@
 /*
  * mspec_mmap
  *
- * Called when mmaping the device.  Initializes the vma with a fault handler
+ * Called when mmapping the device.  Initializes the vma with a fault handler
  * and private data structure necessary to allocate, track, and free the
  * underlying pages.
  */
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 5e28d39..3d92306 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -23,7 +23,6 @@
 #include <linux/errno.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/timer.h>
 #include <linux/interrupt.h>
 #include <linux/tty.h>
@@ -856,9 +855,9 @@
 	}
 }
 
-static int mxser_startup(struct tty_struct *tty)
+static int mxser_activate(struct tty_port *port, struct tty_struct *tty)
 {
-	struct mxser_port *info = tty->driver_data;
+	struct mxser_port *info = container_of(port, struct mxser_port, port);
 	unsigned long page;
 	unsigned long flags;
 
@@ -868,22 +867,13 @@
 
 	spin_lock_irqsave(&info->slock, flags);
 
-	if (info->port.flags & ASYNC_INITIALIZED) {
-		free_page(page);
-		spin_unlock_irqrestore(&info->slock, flags);
-		return 0;
-	}
-
 	if (!info->ioaddr || !info->type) {
 		set_bit(TTY_IO_ERROR, &tty->flags);
 		free_page(page);
 		spin_unlock_irqrestore(&info->slock, flags);
 		return 0;
 	}
-	if (info->port.xmit_buf)
-		free_page(page);
-	else
-		info->port.xmit_buf = (unsigned char *) page;
+	info->port.xmit_buf = (unsigned char *) page;
 
 	/*
 	 * Clear the FIFO buffers and disable them
@@ -951,24 +941,19 @@
 	 * and set the speed of the serial port
 	 */
 	mxser_change_speed(tty, NULL);
-	info->port.flags |= ASYNC_INITIALIZED;
 	spin_unlock_irqrestore(&info->slock, flags);
 
 	return 0;
 }
 
 /*
- * This routine will shutdown a serial port; interrupts maybe disabled, and
- * DTR is dropped if the hangup on close termio flag is on.
+ * This routine will shutdown a serial port
  */
-static void mxser_shutdown(struct tty_struct *tty)
+static void mxser_shutdown_port(struct tty_port *port)
 {
-	struct mxser_port *info = tty->driver_data;
+	struct mxser_port *info = container_of(port, struct mxser_port, port);
 	unsigned long flags;
 
-	if (!(info->port.flags & ASYNC_INITIALIZED))
-		return;
-
 	spin_lock_irqsave(&info->slock, flags);
 
 	/*
@@ -978,7 +963,7 @@
 	wake_up_interruptible(&info->port.delta_msr_wait);
 
 	/*
-	 * Free the IRQ, if necessary
+	 * Free the xmit buffer, if necessary
 	 */
 	if (info->port.xmit_buf) {
 		free_page((unsigned long) info->port.xmit_buf);
@@ -988,10 +973,6 @@
 	info->IER = 0;
 	outb(0x00, info->ioaddr + UART_IER);
 
-	if (tty->termios->c_cflag & HUPCL)
-		info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS);
-	outb(info->MCR, info->ioaddr + UART_MCR);
-
 	/* clear Rx/Tx FIFO's */
 	if (info->board->chip_flag)
 		outb(UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT |
@@ -1004,9 +985,6 @@
 	/* read data port to reset things */
 	(void) inb(info->ioaddr + UART_RX);
 
-	set_bit(TTY_IO_ERROR, &tty->flags);
-
-	info->port.flags &= ~ASYNC_INITIALIZED;
 
 	if (info->board->chip_flag)
 		SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(info->ioaddr);
@@ -1023,8 +1001,7 @@
 static int mxser_open(struct tty_struct *tty, struct file *filp)
 {
 	struct mxser_port *info;
-	unsigned long flags;
-	int retval, line;
+	int line;
 
 	line = tty->index;
 	if (line == MXSER_PORTS)
@@ -1035,23 +1012,7 @@
 	if (!info->ioaddr)
 		return -ENODEV;
 
-	tty->driver_data = info;
-	tty_port_tty_set(&info->port, tty);
-	/*
-	 * Start up serial port
-	 */
-	spin_lock_irqsave(&info->port.lock, flags);
-	info->port.count++;
-	spin_unlock_irqrestore(&info->port.lock, flags);
-	retval = mxser_startup(tty);
-	if (retval)
-		return retval;
-
-	retval = tty_port_block_til_ready(&info->port, tty, filp);
-	if (retval)
-		return retval;
-
-	return 0;
+	return tty_port_open(&info->port, tty, filp);
 }
 
 static void mxser_flush_buffer(struct tty_struct *tty)
@@ -1075,19 +1036,11 @@
 }
 
 
-static void mxser_close_port(struct tty_struct *tty, struct tty_port *port)
+static void mxser_close_port(struct tty_port *port)
 {
 	struct mxser_port *info = container_of(port, struct mxser_port, port);
 	unsigned long timeout;
 	/*
-	 * Save the termios structure, since this port may have
-	 * separate termios for callout and dialin.
-	 *
-	 * FIXME: Can this go ?
-	 */
-	if (port->flags & ASYNC_NORMAL_ACTIVE)
-		info->normal_termios = *tty->termios;
-	/*
 	 * At this point we stop accepting input.  To do this, we
 	 * disable the receive line status interrupts, and tell the
 	 * interrupt driver to stop checking the data ready bit in the
@@ -1097,22 +1050,18 @@
 	if (info->board->chip_flag)
 		info->IER &= ~MOXA_MUST_RECV_ISR;
 
-	if (port->flags & ASYNC_INITIALIZED) {
-		outb(info->IER, info->ioaddr + UART_IER);
-		/*
-		 * Before we drop DTR, make sure the UART transmitter
-		 * has completely drained; this is especially
-		 * important if there is a transmit FIFO!
-		 */
-		timeout = jiffies + HZ;
-		while (!(inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT)) {
-			schedule_timeout_interruptible(5);
-			if (time_after(jiffies, timeout))
-				break;
-		}
+	outb(info->IER, info->ioaddr + UART_IER);
+	/*
+	 * Before we drop DTR, make sure the UART transmitter
+	 * has completely drained; this is especially
+	 * important if there is a transmit FIFO!
+	 */
+	timeout = jiffies + HZ;
+	while (!(inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT)) {
+		schedule_timeout_interruptible(5);
+		if (time_after(jiffies, timeout))
+			break;
 	}
-	mxser_shutdown(tty);
-
 }
 
 /*
@@ -1130,8 +1079,12 @@
 		return;
 	if (tty_port_close_start(port, tty, filp) == 0)
 		return;
-	mxser_close_port(tty, port);
+	mutex_lock(&port->mutex);
+	mxser_close_port(port);
 	mxser_flush_buffer(tty);
+	mxser_shutdown_port(port);
+	clear_bit(ASYNCB_INITIALIZED, &port->flags);
+	mutex_unlock(&port->mutex);
 	/* Right now the tty_port set is done outside of the close_end helper
 	   as we don't yet have everyone using refcounts */	
 	tty_port_close_end(port, tty);
@@ -1275,6 +1228,7 @@
 		struct serial_struct __user *new_info)
 {
 	struct mxser_port *info = tty->driver_data;
+	struct tty_port *port = &info->port;
 	struct serial_struct new_serial;
 	speed_t baud;
 	unsigned long sl_flags;
@@ -1290,7 +1244,7 @@
 			new_serial.port != info->ioaddr)
 		return -EINVAL;
 
-	flags = info->port.flags & ASYNC_SPD_MASK;
+	flags = port->flags & ASYNC_SPD_MASK;
 
 	if (!capable(CAP_SYS_ADMIN)) {
 		if ((new_serial.baud_base != info->baud_base) ||
@@ -1304,16 +1258,17 @@
 		 * OK, past this point, all the error checking has been done.
 		 * At this point, we start making changes.....
 		 */
-		info->port.flags = ((info->port.flags & ~ASYNC_FLAGS) |
+		port->flags = ((port->flags & ~ASYNC_FLAGS) |
 				(new_serial.flags & ASYNC_FLAGS));
-		info->port.close_delay = new_serial.close_delay * HZ / 100;
-		info->port.closing_wait = new_serial.closing_wait * HZ / 100;
-		tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY)
-								? 1 : 0;
-		if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST &&
+		port->close_delay = new_serial.close_delay * HZ / 100;
+		port->closing_wait = new_serial.closing_wait * HZ / 100;
+		tty->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+		if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST &&
 				(new_serial.baud_base != info->baud_base ||
 				new_serial.custom_divisor !=
 				info->custom_divisor)) {
+			if (new_serial.custom_divisor == 0)
+				return -EINVAL;
 			baud = new_serial.baud_base / new_serial.custom_divisor;
 			tty_encode_baud_rate(tty, baud, baud);
 		}
@@ -1323,15 +1278,17 @@
 
 	process_txrx_fifo(info);
 
-	if (info->port.flags & ASYNC_INITIALIZED) {
-		if (flags != (info->port.flags & ASYNC_SPD_MASK)) {
+	if (test_bit(ASYNCB_INITIALIZED, &port->flags)) {
+		if (flags != (port->flags & ASYNC_SPD_MASK)) {
 			spin_lock_irqsave(&info->slock, sl_flags);
 			mxser_change_speed(tty, NULL);
 			spin_unlock_irqrestore(&info->slock, sl_flags);
 		}
-	} else
-		retval = mxser_startup(tty);
-
+	} else {
+		retval = mxser_activate(port, tty);
+		if (retval == 0)
+			set_bit(ASYNCB_INITIALIZED, &port->flags);
+	}
 	return retval;
 }
 
@@ -1520,7 +1477,8 @@
 
 static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
 {
-	struct mxser_port *port;
+	struct mxser_port *ip;
+	struct tty_port *port;
 	struct tty_struct *tty;
 	int result, status;
 	unsigned int i, j;
@@ -1536,38 +1494,39 @@
 
 	case MOXA_CHKPORTENABLE:
 		result = 0;
-		lock_kernel();
 		for (i = 0; i < MXSER_BOARDS; i++)
 			for (j = 0; j < MXSER_PORTS_PER_BOARD; j++)
 				if (mxser_boards[i].ports[j].ioaddr)
 					result |= (1 << i);
-		unlock_kernel();
 		return put_user(result, (unsigned long __user *)argp);
 	case MOXA_GETDATACOUNT:
-		lock_kernel();
+		/* The receive side is locked by port->slock but it isn't
+		   clear that an exact snapshot is worth copying here */
 		if (copy_to_user(argp, &mxvar_log, sizeof(mxvar_log)))
 			ret = -EFAULT;
-		unlock_kernel();
 		return ret;
 	case MOXA_GETMSTATUS: {
 		struct mxser_mstatus ms, __user *msu = argp;
-		lock_kernel();
 		for (i = 0; i < MXSER_BOARDS; i++)
 			for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) {
-				port = &mxser_boards[i].ports[j];
+				ip = &mxser_boards[i].ports[j];
+				port = &ip->port;
 				memset(&ms, 0, sizeof(ms));
 
-				if (!port->ioaddr)
+				mutex_lock(&port->mutex);
+				if (!ip->ioaddr)
 					goto copy;
 				
-				tty = tty_port_tty_get(&port->port);
+				tty = tty_port_tty_get(port);
 
 				if (!tty || !tty->termios)
-					ms.cflag = port->normal_termios.c_cflag;
+					ms.cflag = ip->normal_termios.c_cflag;
 				else
 					ms.cflag = tty->termios->c_cflag;
 				tty_kref_put(tty);
-				status = inb(port->ioaddr + UART_MSR);
+				spin_lock_irq(&ip->slock);
+				status = inb(ip->ioaddr + UART_MSR);
+				spin_unlock_irq(&ip->slock);
 				if (status & UART_MSR_DCD)
 					ms.dcd = 1;
 				if (status & UART_MSR_DSR)
@@ -1575,13 +1534,11 @@
 				if (status & UART_MSR_CTS)
 					ms.cts = 1;
 			copy:
-				if (copy_to_user(msu, &ms, sizeof(ms))) {
-					unlock_kernel();
+				mutex_unlock(&port->mutex);
+				if (copy_to_user(msu, &ms, sizeof(ms)))
 					return -EFAULT;
-				}
 				msu++;
 			}
-		unlock_kernel();
 		return 0;
 	}
 	case MOXA_ASPP_MON_EXT: {
@@ -1593,41 +1550,48 @@
 		if (!me)
 			return -ENOMEM;
 
-		lock_kernel();
 		for (i = 0, p = 0; i < MXSER_BOARDS; i++) {
 			for (j = 0; j < MXSER_PORTS_PER_BOARD; j++, p++) {
 				if (p >= ARRAY_SIZE(me->rx_cnt)) {
 					i = MXSER_BOARDS;
 					break;
 				}
-				port = &mxser_boards[i].ports[j];
-				if (!port->ioaddr)
-					continue;
+				ip = &mxser_boards[i].ports[j];
+				port = &ip->port;
 
-				status = mxser_get_msr(port->ioaddr, 0, p);
+				mutex_lock(&port->mutex);
+				if (!ip->ioaddr) {
+					mutex_unlock(&port->mutex);
+					continue;
+				}
+
+				spin_lock_irq(&ip->slock);
+				status = mxser_get_msr(ip->ioaddr, 0, p);
 
 				if (status & UART_MSR_TERI)
-					port->icount.rng++;
+					ip->icount.rng++;
 				if (status & UART_MSR_DDSR)
-					port->icount.dsr++;
+					ip->icount.dsr++;
 				if (status & UART_MSR_DDCD)
-					port->icount.dcd++;
+					ip->icount.dcd++;
 				if (status & UART_MSR_DCTS)
-					port->icount.cts++;
+					ip->icount.cts++;
 
-				port->mon_data.modem_status = status;
-				me->rx_cnt[p] = port->mon_data.rxcnt;
-				me->tx_cnt[p] = port->mon_data.txcnt;
-				me->up_rxcnt[p] = port->mon_data.up_rxcnt;
-				me->up_txcnt[p] = port->mon_data.up_txcnt;
+				ip->mon_data.modem_status = status;
+				me->rx_cnt[p] = ip->mon_data.rxcnt;
+				me->tx_cnt[p] = ip->mon_data.txcnt;
+				me->up_rxcnt[p] = ip->mon_data.up_rxcnt;
+				me->up_txcnt[p] = ip->mon_data.up_txcnt;
 				me->modem_status[p] =
-					port->mon_data.modem_status;
-				tty = tty_port_tty_get(&port->port);
+					ip->mon_data.modem_status;
+				spin_unlock_irq(&ip->slock);
+
+				tty = tty_port_tty_get(&ip->port);
 
 				if (!tty || !tty->termios) {
-					cflag = port->normal_termios.c_cflag;
-					iflag = port->normal_termios.c_iflag;
-					me->baudrate[p] = tty_termios_baud_rate(&port->normal_termios);
+					cflag = ip->normal_termios.c_cflag;
+					iflag = ip->normal_termios.c_iflag;
+					me->baudrate[p] = tty_termios_baud_rate(&ip->normal_termios);
 				} else {
 					cflag = tty->termios->c_cflag;
 					iflag = tty->termios->c_iflag;
@@ -1646,16 +1610,15 @@
 				if (iflag & (IXON | IXOFF))
 					me->flowctrl[p] |= 0x0C;
 
-				if (port->type == PORT_16550A)
+				if (ip->type == PORT_16550A)
 					me->fifo[p] = 1;
 
-				opmode = inb(port->opmode_ioaddr) >>
-						((p % 4) * 2);
+				opmode = inb(ip->opmode_ioaddr)>>((p % 4) * 2);
 				opmode &= OP_MODE_MASK;
 				me->iftype[p] = opmode;
+				mutex_unlock(&port->mutex);
 			}
 		}
-		unlock_kernel();
 		if (copy_to_user(argp, me, sizeof(*me)))
 			ret = -EFAULT;
 		kfree(me);
@@ -1692,6 +1655,7 @@
 		unsigned int cmd, unsigned long arg)
 {
 	struct mxser_port *info = tty->driver_data;
+	struct tty_port *port = &info->port;
 	struct async_icount cnow;
 	unsigned long flags;
 	void __user *argp = (void __user *)arg;
@@ -1716,20 +1680,20 @@
 					opmode != RS422_MODE &&
 					opmode != RS485_4WIRE_MODE)
 				return -EFAULT;
-			lock_kernel();
 			mask = ModeMask[p];
 			shiftbit = p * 2;
+			spin_lock_irq(&info->slock);
 			val = inb(info->opmode_ioaddr);
 			val &= mask;
 			val |= (opmode << shiftbit);
 			outb(val, info->opmode_ioaddr);
-			unlock_kernel();
+			spin_unlock_irq(&info->slock);
 		} else {
-			lock_kernel();
 			shiftbit = p * 2;
+			spin_lock_irq(&info->slock);
 			opmode = inb(info->opmode_ioaddr) >> shiftbit;
+			spin_unlock_irq(&info->slock);
 			opmode &= OP_MODE_MASK;
-			unlock_kernel();
 			if (put_user(opmode, (int __user *)argp))
 				return -EFAULT;
 		}
@@ -1742,14 +1706,14 @@
 
 	switch (cmd) {
 	case TIOCGSERIAL:
-		lock_kernel();
+		mutex_lock(&port->mutex);
 		retval = mxser_get_serial_info(tty, argp);
-		unlock_kernel();
+		mutex_unlock(&port->mutex);
 		return retval;
 	case TIOCSSERIAL:
-		lock_kernel();
+		mutex_lock(&port->mutex);
 		retval = mxser_set_serial_info(tty, argp);
-		unlock_kernel();
+		mutex_unlock(&port->mutex);
 		return retval;
 	case TIOCSERGETLSR:	/* Get line status register */
 		return  mxser_get_lsr_info(info, argp);
@@ -1795,31 +1759,33 @@
 	case MOXA_HighSpeedOn:
 		return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp);
 	case MOXA_SDS_RSTICOUNTER:
-		lock_kernel();
+		spin_lock_irq(&info->slock);
 		info->mon_data.rxcnt = 0;
 		info->mon_data.txcnt = 0;
-		unlock_kernel();
+		spin_unlock_irq(&info->slock);
 		return 0;
 
 	case MOXA_ASPP_OQUEUE:{
 		int len, lsr;
 
-		lock_kernel();
 		len = mxser_chars_in_buffer(tty);
+		spin_lock(&info->slock);
 		lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_THRE;
+		spin_unlock_irq(&info->slock);
 		len += (lsr ? 0 : 1);
-		unlock_kernel();
 
 		return put_user(len, (int __user *)argp);
 	}
 	case MOXA_ASPP_MON: {
 		int mcr, status;
 
-		lock_kernel();
+		spin_lock(&info->slock);
 		status = mxser_get_msr(info->ioaddr, 1, tty->index);
 		mxser_check_modem_status(tty, info, status);
 
 		mcr = inb(info->ioaddr + UART_MCR);
+		spin_unlock(&info->slock);
+
 		if (mcr & MOXA_MUST_MCR_XON_FLAG)
 			info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFHOLD;
 		else
@@ -1834,7 +1800,7 @@
 			info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD;
 		else
 			info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD;
-		unlock_kernel();
+
 		if (copy_to_user(argp, &info->mon_data,
 				sizeof(struct mxser_mon)))
 			return -EFAULT;
@@ -1993,6 +1959,7 @@
 {
 	struct mxser_port *info = tty->driver_data;
 	unsigned long orig_jiffies, char_time;
+	unsigned long flags;
 	int lsr;
 
 	if (info->type == PORT_UNKNOWN)
@@ -2032,19 +1999,21 @@
 		timeout, char_time);
 	printk("jiff=%lu...", jiffies);
 #endif
-	lock_kernel();
+	spin_lock_irqsave(&info->slock, flags);
 	while (!((lsr = inb(info->ioaddr + UART_LSR)) & UART_LSR_TEMT)) {
 #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
 		printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
 #endif
+		spin_unlock_irqrestore(&info->slock, flags);
 		schedule_timeout_interruptible(char_time);
+		spin_lock_irqsave(&info->slock, flags);
 		if (signal_pending(current))
 			break;
 		if (timeout && time_after(jiffies, orig_jiffies + timeout))
 			break;
 	}
+	spin_unlock_irqrestore(&info->slock, flags);
 	set_current_state(TASK_RUNNING);
-	unlock_kernel();
 
 #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
 	printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
@@ -2059,7 +2028,6 @@
 	struct mxser_port *info = tty->driver_data;
 
 	mxser_flush_buffer(tty);
-	mxser_shutdown(tty);
 	tty_port_hangup(&info->port);
 }
 
@@ -2363,6 +2331,8 @@
 struct tty_port_operations mxser_port_ops = {
 	.carrier_raised = mxser_carrier_raised,
 	.dtr_rts = mxser_dtr_rts,
+	.activate = mxser_activate,
+	.shutdown = mxser_shutdown_port,
 };
 
 /*
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index 6934025..c1d8b54 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -602,7 +602,7 @@
 		}
 		break;
 	case R3964_WAIT_FOR_RX_REPEAT:
-		/* FALLTROUGH */
+		/* FALLTHROUGH */
 	case R3964_IDLE:
 		if (c == STX) {
 			/* Prevent rx_queue from overflow: */
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index 88cee40..4008e2c 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -38,7 +38,6 @@
 #define NVRAM_VERSION	"1.3"
 
 #include <linux/module.h>
-#include <linux/smp_lock.h>
 #include <linux/nvram.h>
 
 #define PC		1
@@ -111,6 +110,7 @@
 #include <linux/spinlock.h>
 #include <linux/io.h>
 #include <linux/uaccess.h>
+#include <linux/smp_lock.h>
 
 #include <asm/system.h>
 
@@ -214,7 +214,6 @@
 
 static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
 {
-	lock_kernel();
 	switch (origin) {
 	case 0:
 		/* nothing to do */
@@ -226,7 +225,7 @@
 		offset += NVRAM_BYTES;
 		break;
 	}
-	unlock_kernel();
+
 	return (offset >= 0) ? (file->f_pos = offset) : -EINVAL;
 }
 
diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c
index 3f7da8c..8ecbcc1 100644
--- a/drivers/char/pc8736x_gpio.c
+++ b/drivers/char/pc8736x_gpio.c
@@ -20,7 +20,6 @@
 #include <linux/mutex.h>
 #include <linux/nsc_gpio.h>
 #include <linux/platform_device.h>
-#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 
 #define DEVNAME "pc8736x_gpio"
@@ -223,7 +222,6 @@
 	unsigned m = iminor(inode);
 	file->private_data = &pc8736x_gpio_ops;
 
-	cycle_kernel_lock();
 	dev_dbg(&pdev->dev, "open %d\n", m);
 
 	if (m >= PC8736X_GPIO_CT)
diff --git a/drivers/char/pcmcia/ipwireless/tty.c b/drivers/char/pcmcia/ipwireless/tty.c
index 674b3ab..2bb7874 100644
--- a/drivers/char/pcmcia/ipwireless/tty.c
+++ b/drivers/char/pcmcia/ipwireless/tty.c
@@ -603,7 +603,7 @@
 	}
 }
 
-static struct tty_operations tty_ops = {
+static const struct tty_operations tty_ops = {
 	.open = ipw_open,
 	.close = ipw_close,
 	.hangup = ipw_hangup,
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index d86c0bc..385c44b 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -659,7 +659,7 @@
 	if (!retval)
 		return 0;
 out1:
-	tty_release_dev(filp);
+	tty_release(inode, filp);
 	return retval;
 out:
 	devpts_kill_index(inode, index);
diff --git a/drivers/char/rio/route.h b/drivers/char/rio/route.h
index 20ed73f..46e9637 100644
--- a/drivers/char/rio/route.h
+++ b/drivers/char/rio/route.h
@@ -67,7 +67,7 @@
 typedef struct COST_ROUTE COST_ROUTE;
 struct COST_ROUTE {
 	unsigned char cost;	/* Cost down this link */
-	unsigned char route[NODE_BYTES];	/* Nodes thorough this route */
+	unsigned char route[NODE_BYTES];	/* Nodes through this route */
 };
 
 typedef struct ROUTE_STR ROUTE_STR;
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 3cfa22d..0a8d1e5 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -793,26 +793,21 @@
 }
 
 /* Must be called with interrupts enabled */
-static int rc_setup_port(struct tty_struct *tty, struct riscom_board *bp,
-						struct riscom_port *port)
+static int rc_activate_port(struct tty_port *port, struct tty_struct *tty)
 {
+	struct riscom_port *rp = container_of(port, struct riscom_port, port);
+	struct riscom_board *bp = port_Board(rp);
 	unsigned long flags;
 
-	if (port->port.flags & ASYNC_INITIALIZED)
-		return 0;
-
-	if (tty_port_alloc_xmit_buf(&port->port) < 0)
+	if (tty_port_alloc_xmit_buf(port) < 0)
 		return -ENOMEM;
 
 	spin_lock_irqsave(&riscom_lock, flags);
 
 	clear_bit(TTY_IO_ERROR, &tty->flags);
-	if (port->port.count == 1)
-		bp->count++;
-	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
-	rc_change_speed(tty, bp, port);
-	port->port.flags |= ASYNC_INITIALIZED;
-
+	bp->count++;
+	rp->xmit_cnt = rp->xmit_head = rp->xmit_tail = 0;
+	rc_change_speed(tty, bp, rp);
 	spin_unlock_irqrestore(&riscom_lock, flags);
 	return 0;
 }
@@ -821,9 +816,6 @@
 static void rc_shutdown_port(struct tty_struct *tty,
 			struct riscom_board *bp, struct riscom_port *port)
 {
-	if (!(port->port.flags & ASYNC_INITIALIZED))
-		return;
-
 #ifdef RC_REPORT_OVERRUN
 	printk(KERN_INFO "rc%d: port %d: Total %ld overruns were detected.\n",
 	       board_No(bp), port_No(port), port->overrun);
@@ -840,11 +832,6 @@
 	}
 #endif
 	tty_port_free_xmit_buf(&port->port);
-	if (C_HUPCL(tty)) {
-		/* Drop DTR */
-		bp->DTR |= (1u << port_No(port));
-		rc_out(bp, RC_DTR, bp->DTR);
-	}
 
 	/* Select port */
 	rc_out(bp, CD180_CAR, port_No(port));
@@ -856,7 +843,6 @@
 	rc_out(bp, CD180_IER, port->IER);
 
 	set_bit(TTY_IO_ERROR, &tty->flags);
-	port->port.flags &= ~ASYNC_INITIALIZED;
 
 	if (--bp->count < 0)  {
 		printk(KERN_INFO "rc%d: rc_shutdown_port: "
@@ -889,6 +875,20 @@
 	return CD;
 }
 
+static void dtr_rts(struct tty_port *port, int onoff)
+{
+	struct riscom_port *p = container_of(port, struct riscom_port, port);
+	struct riscom_board *bp = port_Board(p);
+	unsigned long flags;
+
+	spin_lock_irqsave(&riscom_lock, flags);
+	bp->DTR &= ~(1u << port_No(p));
+	if (onoff == 0)
+		bp->DTR |= (1u << port_No(p));
+	rc_out(bp, RC_DTR, bp->DTR);
+	spin_unlock_irqrestore(&riscom_lock, flags);
+}
+
 static int rc_open(struct tty_struct *tty, struct file *filp)
 {
 	int board;
@@ -909,14 +909,7 @@
 	if (error)
 		return error;
 
-	port->port.count++;
-	tty->driver_data = port;
-	tty_port_tty_set(&port->port, tty);
-
-	error = rc_setup_port(tty, bp, port);
-	if (error == 0)
-		error = tty_port_block_til_ready(&port->port, tty, filp);
-	return error;
+	return tty_port_open(&port->port, tty, filp);
 }
 
 static void rc_flush_buffer(struct tty_struct *tty)
@@ -950,24 +943,23 @@
 
 	spin_lock_irqsave(&riscom_lock, flags);
 	rp->IER &= ~IER_RXD;
-	if (port->flags & ASYNC_INITIALIZED) {
-		rp->IER &= ~IER_TXRDY;
-		rp->IER |= IER_TXEMPTY;
-		rc_out(bp, CD180_CAR, port_No(rp));
-		rc_out(bp, CD180_IER, rp->IER);
-		/*
-		 * Before we drop DTR, make sure the UART transmitter
-		 * has completely drained; this is especially
-		 * important if there is a transmit FIFO!
-		 */
-		timeout = jiffies + HZ;
-		while (rp->IER & IER_TXEMPTY) {
-			spin_unlock_irqrestore(&riscom_lock, flags);
-			msleep_interruptible(jiffies_to_msecs(rp->timeout));
-			spin_lock_irqsave(&riscom_lock, flags);
-			if (time_after(jiffies, timeout))
-				break;
-		}
+
+	rp->IER &= ~IER_TXRDY;
+	rp->IER |= IER_TXEMPTY;
+	rc_out(bp, CD180_CAR, port_No(rp));
+	rc_out(bp, CD180_IER, rp->IER);
+	/*
+	 * Before we drop DTR, make sure the UART transmitter
+	 * has completely drained; this is especially
+	 * important if there is a transmit FIFO!
+	 */
+	timeout = jiffies + HZ;
+	while (rp->IER & IER_TXEMPTY) {
+		spin_unlock_irqrestore(&riscom_lock, flags);
+		msleep_interruptible(jiffies_to_msecs(rp->timeout));
+		spin_lock_irqsave(&riscom_lock, flags);
+		if (time_after(jiffies, timeout))
+			break;
 	}
 	rc_shutdown_port(port->tty, bp, rp);
 	spin_unlock_irqrestore(&riscom_lock, flags);
@@ -1354,7 +1346,6 @@
 	if (rc_paranoia_check(port, tty->name, "rc_hangup"))
 		return;
 
-	rc_shutdown_port(tty, port_Board(port), port);
 	tty_port_hangup(&port->port);
 }
 
@@ -1401,7 +1392,9 @@
 
 static const struct tty_port_operations riscom_port_ops = {
 	.carrier_raised = carrier_raised,
+	.dtr_rts = dtr_rts,
 	.shutdown = rc_close_port,
+	.activate = rc_activate_port,
 };
 
 
diff --git a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c
index 1d91005..99e5272 100644
--- a/drivers/char/scx200_gpio.c
+++ b/drivers/char/scx200_gpio.c
@@ -12,7 +12,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
@@ -52,7 +51,6 @@
 	unsigned m = iminor(inode);
 	file->private_data = &scx200_gpio_ops;
 
-	cycle_kernel_lock();
 	if (m >= MAX_PINS)
 		return -EINVAL;
 	return nonseekable_open(inode, file);
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index db6dcfa..0e511d6 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -407,7 +407,7 @@
  *	Declare all those functions in this driver!
  */
 
-static int	stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
+static long	stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg);
 static int	stl_brdinit(struct stlbrd *brdp);
 static int	stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp);
 static int	stl_clrportstats(struct stlport *portp, comstats_t __user *cp);
@@ -607,7 +607,7 @@
  */
 static const struct file_operations	stl_fsiomem = {
 	.owner		= THIS_MODULE,
-	.ioctl		= stl_memioctl,
+	.unlocked_ioctl	= stl_memioctl,
 };
 
 static struct class *stallion_class;
@@ -702,6 +702,24 @@
 
 /*****************************************************************************/
 
+static int stl_activate(struct tty_port *port, struct tty_struct *tty)
+{
+	struct stlport *portp = container_of(port, struct stlport, port);
+	if (!portp->tx.buf) {
+		portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL);
+		if (!portp->tx.buf)
+			return -ENOMEM;
+		portp->tx.head = portp->tx.buf;
+		portp->tx.tail = portp->tx.buf;
+	}
+	stl_setport(portp, tty->termios);
+	portp->sigs = stl_getsignals(portp);
+	stl_setsignals(portp, 1, 1);
+	stl_enablerxtx(portp, 1, 1);
+	stl_startrxtx(portp, 1, 0);
+	return 0;
+}
+
 static int stl_open(struct tty_struct *tty, struct file *filp)
 {
 	struct stlport	*portp;
@@ -737,32 +755,8 @@
 	if (portp == NULL)
 		return -ENODEV;
 	port = &portp->port;
+	return tty_port_open(&portp->port, tty, filp);
 
-/*
- *	On the first open of the device setup the port hardware, and
- *	initialize the per port data structure.
- */
-	tty_port_tty_set(port, tty);
-	tty->driver_data = portp;
-	port->count++;
-
-	if ((port->flags & ASYNC_INITIALIZED) == 0) {
-		if (!portp->tx.buf) {
-			portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL);
-			if (!portp->tx.buf)
-				return -ENOMEM;
-			portp->tx.head = portp->tx.buf;
-			portp->tx.tail = portp->tx.buf;
-		}
-		stl_setport(portp, tty->termios);
-		portp->sigs = stl_getsignals(portp);
-		stl_setsignals(portp, 1, 1);
-		stl_enablerxtx(portp, 1, 1);
-		stl_startrxtx(portp, 1, 0);
-		clear_bit(TTY_IO_ERROR, &tty->flags);
-		port->flags |= ASYNC_INITIALIZED;
-	}
-	return tty_port_block_til_ready(port, tty, filp);
 }
 
 /*****************************************************************************/
@@ -826,38 +820,12 @@
 
 /*****************************************************************************/
 
-static void stl_close(struct tty_struct *tty, struct file *filp)
+static void stl_shutdown(struct tty_port *port)
 {
-	struct stlport	*portp;
-	struct tty_port *port;
-	unsigned long	flags;
-
-	pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp);
-
-	portp = tty->driver_data;
-	BUG_ON(portp == NULL);
-
-	port = &portp->port;
-
-	if (tty_port_close_start(port, tty, filp) == 0)
-		return;
-/*
- *	May want to wait for any data to drain before closing. The BUSY
- *	flag keeps track of whether we are still sending or not - it is
- *	very accurate for the cd1400, not quite so for the sc26198.
- *	(The sc26198 has no "end-of-data" interrupt only empty FIFO)
- */
-	stl_waituntilsent(tty, (HZ / 2));
-
-	spin_lock_irqsave(&port->lock, flags);
-	portp->port.flags &= ~ASYNC_INITIALIZED;
-	spin_unlock_irqrestore(&port->lock, flags);
-
+	struct stlport *portp = container_of(port, struct stlport, port);
 	stl_disableintrs(portp);
-	if (tty->termios->c_cflag & HUPCL)
-		stl_setsignals(portp, 0, 0);
 	stl_enablerxtx(portp, 0, 0);
-	stl_flushbuffer(tty);
+	stl_flush(portp);
 	portp->istate = 0;
 	if (portp->tx.buf != NULL) {
 		kfree(portp->tx.buf);
@@ -865,9 +833,16 @@
 		portp->tx.head = NULL;
 		portp->tx.tail = NULL;
 	}
+}
 
-	tty_port_close_end(port, tty);
-	tty_port_tty_set(port, NULL);
+static void stl_close(struct tty_struct *tty, struct file *filp)
+{
+	struct stlport*portp;
+	pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp);
+
+	portp = tty->driver_data;
+	BUG_ON(portp == NULL);
+	tty_port_close(&portp->port, tty, filp);
 }
 
 /*****************************************************************************/
@@ -1314,35 +1289,12 @@
 
 static void stl_hangup(struct tty_struct *tty)
 {
-	struct stlport	*portp;
-	struct tty_port *port;
-	unsigned long flags;
-
+	struct stlport	*portp = tty->driver_data;
 	pr_debug("stl_hangup(tty=%p)\n", tty);
 
-	portp = tty->driver_data;
 	if (portp == NULL)
 		return;
-	port = &portp->port;
-
-	spin_lock_irqsave(&port->lock, flags);
-	port->flags &= ~ASYNC_INITIALIZED;
-	spin_unlock_irqrestore(&port->lock, flags);
-
-	stl_disableintrs(portp);
-	if (tty->termios->c_cflag & HUPCL)
-		stl_setsignals(portp, 0, 0);
-	stl_enablerxtx(portp, 0, 0);
-	stl_flushbuffer(tty);
-	portp->istate = 0;
-	set_bit(TTY_IO_ERROR, &tty->flags);
-	if (portp->tx.buf != NULL) {
-		kfree(portp->tx.buf);
-		portp->tx.buf = NULL;
-		portp->tx.head = NULL;
-		portp->tx.tail = NULL;
-	}
-	tty_port_hangup(port);
+	tty_port_hangup(&portp->port);
 }
 
 /*****************************************************************************/
@@ -2486,18 +2438,19 @@
  *	collection.
  */
 
-static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
+static long stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg)
 {
 	int	brdnr, rc;
 	void __user *argp = (void __user *)arg;
 
-	pr_debug("stl_memioctl(ip=%p,fp=%p,cmd=%x,arg=%lx)\n", ip, fp, cmd,arg);
+	pr_debug("stl_memioctl(fp=%p,cmd=%x,arg=%lx)\n", fp, cmd,arg);
 
-	brdnr = iminor(ip);
+	brdnr = iminor(fp->f_dentry->d_inode);
 	if (brdnr >= STL_MAXBRDS)
 		return -ENODEV;
 	rc = 0;
 
+	lock_kernel();
 	switch (cmd) {
 	case COM_GETPORTSTATS:
 		rc = stl_getportstats(NULL, NULL, argp);
@@ -2518,7 +2471,7 @@
 		rc = -ENOIOCTLCMD;
 		break;
 	}
-
+	unlock_kernel();
 	return rc;
 }
 
@@ -2549,6 +2502,8 @@
 static const struct tty_port_operations stl_port_ops = {
 	.carrier_raised = stl_carrier_raised,
 	.dtr_rts = stl_dtr_rts,
+	.activate = stl_activate,
+	.shutdown = stl_shutdown,
 };
 
 /*****************************************************************************/
diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c
index b3ec9b1..cad4eb6 100644
--- a/drivers/char/tb0219.c
+++ b/drivers/char/tb0219.c
@@ -21,7 +21,6 @@
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/smp_lock.h>
 
 #include <asm/io.h>
 #include <asm/reboot.h>
@@ -38,7 +37,7 @@
 
 static void (*old_machine_restart)(char *command);
 static void __iomem *tb0219_base;
-static spinlock_t tb0219_lock;
+static DEFINE_SPINLOCK(tb0219_lock);
 
 #define tb0219_read(offset)		readw(tb0219_base + (offset))
 #define tb0219_write(offset, value)	writew((value), tb0219_base + (offset))
@@ -237,7 +236,6 @@
 {
 	unsigned int minor;
 
-	cycle_kernel_lock();
 	minor = iminor(inode);
 	switch (minor) {
 	case 0:
@@ -306,8 +304,6 @@
 		return retval;
 	}
 
-	spin_lock_init(&tb0219_lock);
-
 	old_machine_restart = _machine_restart;
 	_machine_restart = tb0219_restart;
 
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 59499ee..684f0e0 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -142,7 +142,6 @@
 							size_t, loff_t *);
 static unsigned int tty_poll(struct file *, poll_table *);
 static int tty_open(struct inode *, struct file *);
-static int tty_release(struct inode *, struct file *);
 long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 #ifdef CONFIG_COMPAT
 static long tty_compat_ioctl(struct file *file, unsigned int cmd,
@@ -506,8 +505,6 @@
 	if (!tty)
 		return;
 
-	/* inuse_filps is protected by the single kernel lock */
-	lock_kernel();
 
 	spin_lock(&redirect_lock);
 	if (redirect && redirect->private_data == tty) {
@@ -516,7 +513,11 @@
 	}
 	spin_unlock(&redirect_lock);
 
+	/* inuse_filps is protected by the single kernel lock */
+	lock_kernel();
 	check_tty_count(tty, "do_tty_hangup");
+	unlock_kernel();
+
 	file_list_lock();
 	/* This breaks for file handles being sent over AF_UNIX sockets ? */
 	list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) {
@@ -530,6 +531,7 @@
 	}
 	file_list_unlock();
 
+	lock_kernel();
 	tty_ldisc_hangup(tty);
 
 	read_lock(&tasklist_lock);
@@ -708,6 +710,8 @@
 	struct tty_struct *tty;
 	struct pid *tty_pgrp = NULL;
 
+	if (!current->signal->leader)
+		return;
 
 	tty = get_current_tty();
 	if (tty) {
@@ -773,8 +777,7 @@
 {
 	struct task_struct *tsk = current;
 	lock_kernel();
-	if (tsk->signal->leader)
-		disassociate_ctty(0);
+	disassociate_ctty(0);
 	unlock_kernel();
 	proc_clear_tty(tsk);
 }
@@ -1017,14 +1020,16 @@
 
 void tty_write_message(struct tty_struct *tty, char *msg)
 {
-	lock_kernel();
 	if (tty) {
 		mutex_lock(&tty->atomic_write_lock);
-		if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags))
+		lock_kernel();
+		if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) {
+			unlock_kernel();
 			tty->ops->write(tty, msg, strlen(msg));
+		} else
+			unlock_kernel();
 		tty_write_unlock(tty);
 	}
-	unlock_kernel();
 	return;
 }
 
@@ -1202,14 +1207,21 @@
 						struct tty_struct *tty)
 {
 	int idx = tty->index;
+	int ret;
 
-	if (driver->ops->install)
-		return driver->ops->install(driver, tty);
+	if (driver->ops->install) {
+		lock_kernel();
+		ret = driver->ops->install(driver, tty);
+		unlock_kernel();
+		return ret;
+	}
 
 	if (tty_init_termios(tty) == 0) {
+		lock_kernel();
 		tty_driver_kref_get(driver);
 		tty->count++;
 		driver->ttys[idx] = tty;
+		unlock_kernel();
 		return 0;
 	}
 	return -ENOMEM;
@@ -1302,10 +1314,14 @@
 	struct tty_struct *tty;
 	int retval;
 
+	lock_kernel();
 	/* Check if pty master is being opened multiple times */
 	if (driver->subtype == PTY_TYPE_MASTER &&
-		(driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok)
+		(driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) {
+		unlock_kernel();
 		return ERR_PTR(-EIO);
+	}
+	unlock_kernel();
 
 	/*
 	 * First time open is complex, especially for PTY devices.
@@ -1335,7 +1351,6 @@
 	 * If we fail here just call release_tty to clean up.  No need
 	 * to decrement the use counts, as release_tty doesn't care.
 	 */
-
 	retval = tty_ldisc_setup(tty, tty->link);
 	if (retval)
 		goto release_mem_out;
@@ -1350,7 +1365,9 @@
 	if (printk_ratelimit())
 		printk(KERN_INFO "tty_init_dev: ldisc open failed, "
 				 "clearing slot %d\n", idx);
+	lock_kernel();
 	release_tty(tty, idx);
+	unlock_kernel();
 	return ERR_PTR(retval);
 }
 
@@ -1464,7 +1481,17 @@
 	tty_kref_put(tty);
 }
 
-/*
+/**
+ *	tty_release		-	vfs callback for close
+ *	@inode: inode of tty
+ *	@filp: file pointer for handle to tty
+ *
+ *	Called the last time each file handle is closed that references
+ *	this tty. There may however be several such references.
+ *
+ *	Locking:
+ *		Takes bkl. See tty_release_dev
+ *
  * Even releasing the tty structures is a tricky business.. We have
  * to be very careful that the structures are all released at the
  * same time, as interrupts might otherwise get the wrong pointers.
@@ -1472,20 +1499,20 @@
  * WSH 09/09/97: rewritten to avoid some nasty race conditions that could
  * lead to double frees or releasing memory still in use.
  */
-void tty_release_dev(struct file *filp)
+
+int tty_release(struct inode *inode, struct file *filp)
 {
 	struct tty_struct *tty, *o_tty;
 	int	pty_master, tty_closing, o_tty_closing, do_sleep;
 	int	devpts;
 	int	idx;
 	char	buf[64];
-	struct 	inode *inode;
 
-	inode = filp->f_path.dentry->d_inode;
 	tty = (struct tty_struct *)filp->private_data;
 	if (tty_paranoia_check(tty, inode, "tty_release_dev"))
-		return;
+		return 0;
 
+	lock_kernel();
 	check_tty_count(tty, "tty_release_dev");
 
 	tty_fasync(-1, filp, 0);
@@ -1500,19 +1527,22 @@
 	if (idx < 0 || idx >= tty->driver->num) {
 		printk(KERN_DEBUG "tty_release_dev: bad idx when trying to "
 				  "free (%s)\n", tty->name);
-		return;
+		unlock_kernel();
+		return 0;
 	}
 	if (!devpts) {
 		if (tty != tty->driver->ttys[idx]) {
+			unlock_kernel();
 			printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty "
 			       "for (%s)\n", idx, tty->name);
-			return;
+			return 0;
 		}
 		if (tty->termios != tty->driver->termios[idx]) {
+			unlock_kernel();
 			printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios "
 			       "for (%s)\n",
 			       idx, tty->name);
-			return;
+			return 0;
 		}
 	}
 #endif
@@ -1526,26 +1556,30 @@
 	if (tty->driver->other &&
 	     !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) {
 		if (o_tty != tty->driver->other->ttys[idx]) {
+			unlock_kernel();
 			printk(KERN_DEBUG "tty_release_dev: other->table[%d] "
 					  "not o_tty for (%s)\n",
 			       idx, tty->name);
-			return;
+			return 0 ;
 		}
 		if (o_tty->termios != tty->driver->other->termios[idx]) {
+			unlock_kernel();
 			printk(KERN_DEBUG "tty_release_dev: other->termios[%d] "
 					  "not o_termios for (%s)\n",
 			       idx, tty->name);
-			return;
+			return 0;
 		}
 		if (o_tty->link != tty) {
+			unlock_kernel();
 			printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n");
-			return;
+			return 0;
 		}
 	}
 #endif
 	if (tty->ops->close)
 		tty->ops->close(tty, filp);
 
+	unlock_kernel();
 	/*
 	 * Sanity check: if tty->count is going to zero, there shouldn't be
 	 * any waiters on tty->read_wait or tty->write_wait.  We test the
@@ -1568,6 +1602,7 @@
 		   opens on /dev/tty */
 
 		mutex_lock(&tty_mutex);
+		lock_kernel();
 		tty_closing = tty->count <= 1;
 		o_tty_closing = o_tty &&
 			(o_tty->count <= (pty_master ? 1 : 0));
@@ -1598,6 +1633,7 @@
 
 		printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue "
 				    "active!\n", tty_name(tty, buf));
+		unlock_kernel();
 		mutex_unlock(&tty_mutex);
 		schedule();
 	}
@@ -1661,8 +1697,10 @@
 	mutex_unlock(&tty_mutex);
 
 	/* check whether both sides are closing ... */
-	if (!tty_closing || (o_tty && !o_tty_closing))
-		return;
+	if (!tty_closing || (o_tty && !o_tty_closing)) {
+		unlock_kernel();
+		return 0;
+	}
 
 #ifdef TTY_DEBUG_HANGUP
 	printk(KERN_DEBUG "freeing tty structure...");
@@ -1680,10 +1718,12 @@
 	/* Make this pty number available for reallocation */
 	if (devpts)
 		devpts_kill_index(inode, idx);
+	unlock_kernel();
+	return 0;
 }
 
 /**
- *	__tty_open		-	open a tty device
+ *	tty_open		-	open a tty device
  *	@inode: inode of device file
  *	@filp: file pointer to tty
  *
@@ -1703,7 +1743,7 @@
  *		 ->siglock protects ->signal/->sighand
  */
 
-static int __tty_open(struct inode *inode, struct file *filp)
+static int tty_open(struct inode *inode, struct file *filp)
 {
 	struct tty_struct *tty = NULL;
 	int noctty, retval;
@@ -1720,10 +1760,12 @@
 	retval = 0;
 
 	mutex_lock(&tty_mutex);
+	lock_kernel();
 
 	if (device == MKDEV(TTYAUX_MAJOR, 0)) {
 		tty = get_current_tty();
 		if (!tty) {
+			unlock_kernel();
 			mutex_unlock(&tty_mutex);
 			return -ENXIO;
 		}
@@ -1755,12 +1797,14 @@
 				goto got_driver;
 			}
 		}
+		unlock_kernel();
 		mutex_unlock(&tty_mutex);
 		return -ENODEV;
 	}
 
 	driver = get_tty_driver(device, &index);
 	if (!driver) {
+		unlock_kernel();
 		mutex_unlock(&tty_mutex);
 		return -ENODEV;
 	}
@@ -1770,6 +1814,7 @@
 		tty = tty_driver_lookup_tty(driver, inode, index);
 
 		if (IS_ERR(tty)) {
+			unlock_kernel();
 			mutex_unlock(&tty_mutex);
 			return PTR_ERR(tty);
 		}
@@ -1784,8 +1829,10 @@
 
 	mutex_unlock(&tty_mutex);
 	tty_driver_kref_put(driver);
-	if (IS_ERR(tty))
+	if (IS_ERR(tty)) {
+		unlock_kernel();
 		return PTR_ERR(tty);
+	}
 
 	filp->private_data = tty;
 	file_move(filp, &tty->tty_files);
@@ -1813,11 +1860,15 @@
 		printk(KERN_DEBUG "error %d in opening %s...", retval,
 		       tty->name);
 #endif
-		tty_release_dev(filp);
-		if (retval != -ERESTARTSYS)
+		tty_release(inode, filp);
+		if (retval != -ERESTARTSYS) {
+			unlock_kernel();
 			return retval;
-		if (signal_pending(current))
+		}
+		if (signal_pending(current)) {
+			unlock_kernel();
 			return retval;
+		}
 		schedule();
 		/*
 		 * Need to reset f_op in case a hangup happened.
@@ -1826,8 +1877,11 @@
 			filp->f_op = &tty_fops;
 		goto retry_open;
 	}
+	unlock_kernel();
+
 
 	mutex_lock(&tty_mutex);
+	lock_kernel();
 	spin_lock_irq(&current->sighand->siglock);
 	if (!noctty &&
 	    current->signal->leader &&
@@ -1835,43 +1889,12 @@
 	    tty->session == NULL)
 		__proc_set_tty(current, tty);
 	spin_unlock_irq(&current->sighand->siglock);
+	unlock_kernel();
 	mutex_unlock(&tty_mutex);
 	return 0;
 }
 
-/* BKL pushdown: scary code avoidance wrapper */
-static int tty_open(struct inode *inode, struct file *filp)
-{
-	int ret;
 
-	lock_kernel();
-	ret = __tty_open(inode, filp);
-	unlock_kernel();
-	return ret;
-}
-
-
-
-
-/**
- *	tty_release		-	vfs callback for close
- *	@inode: inode of tty
- *	@filp: file pointer for handle to tty
- *
- *	Called the last time each file handle is closed that references
- *	this tty. There may however be several such references.
- *
- *	Locking:
- *		Takes bkl. See tty_release_dev
- */
-
-static int tty_release(struct inode *inode, struct file *filp)
-{
-	lock_kernel();
-	tty_release_dev(filp);
-	unlock_kernel();
-	return 0;
-}
 
 /**
  *	tty_poll	-	check tty status
@@ -2317,9 +2340,7 @@
 	if (get_user(ldisc, p))
 		return -EFAULT;
 
-	lock_kernel();
 	ret = tty_set_ldisc(tty, ldisc);
-	unlock_kernel();
 
 	return ret;
 }
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 8e67d5c..6bd5f88 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -315,7 +315,7 @@
  *	For maximal back compatibility with legacy SYS5/POSIX *nix behaviour
  *	we need to carefully set the bits when the user does not get the
  *	desired speed. We allow small margins and preserve as much of possible
- *	of the input intent to keep compatiblity.
+ *	of the input intent to keep compatibility.
  *
  *	Locking: Caller should hold termios lock. This is already held
  *	when calling this function from the driver termios handler.
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c
index feb5507..3f653f7 100644
--- a/drivers/char/tty_ldisc.c
+++ b/drivers/char/tty_ldisc.c
@@ -34,6 +34,8 @@
 #include <linux/vt_kern.h>
 #include <linux/selection.h>
 
+#include <linux/smp_lock.h>	/* For the moment */
+
 #include <linux/kmod.h>
 #include <linux/nsproxy.h>
 
@@ -443,8 +445,14 @@
 static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)
 {
 	WARN_ON(test_and_set_bit(TTY_LDISC_OPEN, &tty->flags));
-	if (ld->ops->open)
-		return ld->ops->open(tty);
+	if (ld->ops->open) {
+		int ret;
+                /* BKL here locks verus a hangup event */
+		lock_kernel();
+		ret = ld->ops->open(tty);
+		unlock_kernel();
+		return ret;
+	}
 	return 0;
 }
 
@@ -545,6 +553,7 @@
 	if (IS_ERR(new_ldisc))
 		return PTR_ERR(new_ldisc);
 
+	lock_kernel();
 	/*
 	 *	We need to look at the tty locking here for pty/tty pairs
 	 *	when both sides try to change in parallel.
@@ -558,10 +567,12 @@
 	 */
 
 	if (tty->ldisc->ops->num == ldisc) {
+		unlock_kernel();
 		tty_ldisc_put(new_ldisc);
 		return 0;
 	}
 
+	unlock_kernel();
 	/*
 	 *	Problem: What do we do if this blocks ?
 	 *	We could deadlock here
@@ -582,6 +593,9 @@
 			test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0);
 		mutex_lock(&tty->ldisc_mutex);
 	}
+
+	lock_kernel();
+
 	set_bit(TTY_LDISC_CHANGING, &tty->flags);
 
 	/*
@@ -592,6 +606,8 @@
 	tty->receive_room = 0;
 
 	o_ldisc = tty->ldisc;
+
+	unlock_kernel();
 	/*
 	 *	Make sure we don't change while someone holds a
 	 *	reference to the line discipline. The TTY_LDISC bit
@@ -617,12 +633,14 @@
 	flush_scheduled_work();
 
 	mutex_lock(&tty->ldisc_mutex);
+	lock_kernel();
 	if (test_bit(TTY_HUPPED, &tty->flags)) {
 		/* We were raced by the hangup method. It will have stomped
 		   the ldisc data and closed the ldisc down */
 		clear_bit(TTY_LDISC_CHANGING, &tty->flags);
 		mutex_unlock(&tty->ldisc_mutex);
 		tty_ldisc_put(new_ldisc);
+		unlock_kernel();
 		return -EIO;
 	}
 
@@ -664,6 +682,7 @@
 	if (o_work)
 		schedule_delayed_work(&o_tty->buf.work, 1);
 	mutex_unlock(&tty->ldisc_mutex);
+	unlock_kernel();
 	return retval;
 }
 
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index c63f3d3..be492dd 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -25,19 +25,21 @@
 	init_waitqueue_head(&port->close_wait);
 	init_waitqueue_head(&port->delta_msr_wait);
 	mutex_init(&port->mutex);
+	mutex_init(&port->buf_mutex);
 	spin_lock_init(&port->lock);
 	port->close_delay = (50 * HZ) / 100;
 	port->closing_wait = (3000 * HZ) / 100;
+	kref_init(&port->kref);
 }
 EXPORT_SYMBOL(tty_port_init);
 
 int tty_port_alloc_xmit_buf(struct tty_port *port)
 {
 	/* We may sleep in get_zeroed_page() */
-	mutex_lock(&port->mutex);
+	mutex_lock(&port->buf_mutex);
 	if (port->xmit_buf == NULL)
 		port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
-	mutex_unlock(&port->mutex);
+	mutex_unlock(&port->buf_mutex);
 	if (port->xmit_buf == NULL)
 		return -ENOMEM;
 	return 0;
@@ -46,15 +48,32 @@
 
 void tty_port_free_xmit_buf(struct tty_port *port)
 {
-	mutex_lock(&port->mutex);
+	mutex_lock(&port->buf_mutex);
 	if (port->xmit_buf != NULL) {
 		free_page((unsigned long)port->xmit_buf);
 		port->xmit_buf = NULL;
 	}
-	mutex_unlock(&port->mutex);
+	mutex_unlock(&port->buf_mutex);
 }
 EXPORT_SYMBOL(tty_port_free_xmit_buf);
 
+static void tty_port_destructor(struct kref *kref)
+{
+	struct tty_port *port = container_of(kref, struct tty_port, kref);
+	if (port->xmit_buf)
+		free_page((unsigned long)port->xmit_buf);
+	if (port->ops->destruct)
+		port->ops->destruct(port);
+	else
+		kfree(port);
+}
+
+void tty_port_put(struct tty_port *port)
+{
+	if (port)
+		kref_put(&port->kref, tty_port_destructor);
+}
+EXPORT_SYMBOL(tty_port_put);
 
 /**
  *	tty_port_tty_get	-	get a tty reference
@@ -99,10 +118,11 @@
 
 static void tty_port_shutdown(struct tty_port *port)
 {
+	mutex_lock(&port->mutex);
 	if (port->ops->shutdown &&
 		test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))
 			port->ops->shutdown(port);
-
+	mutex_unlock(&port->mutex);
 }
 
 /**
@@ -120,8 +140,10 @@
 	spin_lock_irqsave(&port->lock, flags);
 	port->count = 0;
 	port->flags &= ~ASYNC_NORMAL_ACTIVE;
-	if (port->tty)
+	if (port->tty) {
+		set_bit(TTY_IO_ERROR, &port->tty->flags);
 		tty_kref_put(port->tty);
+	}
 	port->tty = NULL;
 	spin_unlock_irqrestore(&port->lock, flags);
 	wake_up_interruptible(&port->open_wait);
@@ -198,7 +220,7 @@
  *	management of these lines. Note that the dtr/rts raise is done each
  *	iteration as a hangup may have previously dropped them while we wait.
  */
- 
+
 int tty_port_block_til_ready(struct tty_port *port,
 				struct tty_struct *tty, struct file *filp)
 {
@@ -253,7 +275,8 @@
 			tty_port_raise_dtr_rts(port);
 
 		prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
-		/* Check for a hangup or uninitialised port. Return accordingly */
+		/* Check for a hangup or uninitialised port.
+							Return accordingly */
 		if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
 			if (port->flags & ASYNC_HUP_NOTIFY)
 				retval = -EAGAIN;
@@ -285,11 +308,11 @@
 		port->flags |= ASYNC_NORMAL_ACTIVE;
 	spin_unlock_irqrestore(&port->lock, flags);
 	return retval;
-	
 }
 EXPORT_SYMBOL(tty_port_block_til_ready);
 
-int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct file *filp)
+int tty_port_close_start(struct tty_port *port,
+				struct tty_struct *tty, struct file *filp)
 {
 	unsigned long flags;
 
@@ -299,7 +322,7 @@
 		return 0;
 	}
 
-	if( tty->count == 1 && port->count != 1) {
+	if (tty->count == 1 && port->count != 1) {
 		printk(KERN_WARNING
 		    "tty_port_close_start: tty->count = 1 port count = %d.\n",
 								port->count);
@@ -331,12 +354,20 @@
 		long timeout;
 
 		if (bps > 1200)
-			timeout = max_t(long, (HZ * 10 * port->drain_delay) / bps,
-								HZ / 10);
+			timeout = max_t(long,
+				(HZ * 10 * port->drain_delay) / bps, HZ / 10);
 		else
 			timeout = 2 * HZ;
 		schedule_timeout_interruptible(timeout);
 	}
+	/* Flush the ldisc buffering */
+	tty_ldisc_flush(tty);
+
+	/* Drop DTR/RTS if HUPCL is set. This causes any attached modem to
+	   hang up the line */
+	if (tty->termios->c_cflag & HUPCL)
+		tty_port_lower_dtr_rts(port);
+
 	/* Don't call port->drop for the last reference. Callers will want
 	   to drop the last active reference in ->shutdown() or the tty
 	   shutdown path */
@@ -348,11 +379,6 @@
 {
 	unsigned long flags;
 
-	tty_ldisc_flush(tty);
-
-	if (tty->termios->c_cflag & HUPCL)
-		tty_port_lower_dtr_rts(port);
-
 	spin_lock_irqsave(&port->lock, flags);
 	tty->closing = 0;
 
@@ -377,7 +403,42 @@
 	if (tty_port_close_start(port, tty, filp) == 0)
 		return;
 	tty_port_shutdown(port);
+	set_bit(TTY_IO_ERROR, &tty->flags);
 	tty_port_close_end(port, tty);
 	tty_port_tty_set(port, NULL);
 }
 EXPORT_SYMBOL(tty_port_close);
+
+int tty_port_open(struct tty_port *port, struct tty_struct *tty,
+							struct file *filp)
+{
+	spin_lock_irq(&port->lock);
+	if (!tty_hung_up_p(filp))
+		++port->count;
+	spin_unlock_irq(&port->lock);
+	tty_port_tty_set(port, tty);
+
+	/*
+	 * Do the device-specific open only if the hardware isn't
+	 * already initialized. Serialize open and shutdown using the
+	 * port mutex.
+	 */
+
+	mutex_lock(&port->mutex);
+
+	if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
+		clear_bit(TTY_IO_ERROR, &tty->flags);
+		if (port->ops->activate) {
+			int retval = port->ops->activate(port, tty);
+			if (retval) {
+				mutex_unlock(&port->mutex);
+				return retval;
+			}
+		}
+		set_bit(ASYNCB_INITIALIZED, &port->flags);
+	}
+	mutex_unlock(&port->mutex);
+	return tty_port_block_til_ready(port, tty, filp);
+}
+
+EXPORT_SYMBOL(tty_port_open);
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 0c80c68..1e3d728 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -161,6 +161,8 @@
 static int printable;		/* Is console ready for printing? */
 int default_utf8 = true;
 module_param(default_utf8, int, S_IRUGO | S_IWUSR);
+int global_cursor_default = -1;
+module_param(global_cursor_default, int, S_IRUGO | S_IWUSR);
 
 /*
  * ignore_poke: don't unblank the screen when things are typed.  This is
@@ -775,6 +777,12 @@
 		vc_cons[currcons].d = NULL;
 		return -ENOMEM;
 	    }
+
+	    /* If no drivers have overridden us and the user didn't pass a
+	       boot option, default to displaying the cursor */
+	    if (global_cursor_default == -1)
+		    global_cursor_default = 1;
+
 	    vc_init(vc, vc->vc_rows, vc->vc_cols, 1);
 	    vcs_make_sysfs(currcons);
 	    atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param);
@@ -1616,7 +1624,7 @@
 	vc->vc_decscnm		= 0;
 	vc->vc_decom		= 0;
 	vc->vc_decawm		= 1;
-	vc->vc_deccm		= 1;
+	vc->vc_deccm		= global_cursor_default;
 	vc->vc_decim		= 0;
 
 	set_kbd(vc, decarm);
@@ -4078,6 +4086,7 @@
 EXPORT_SYMBOL(console_blank_hook);
 EXPORT_SYMBOL(console_blanked);
 EXPORT_SYMBOL(vc_cons);
+EXPORT_SYMBOL(global_cursor_default);
 #ifndef VT_SINGLE_DRIVER
 EXPORT_SYMBOL(take_over_console);
 EXPORT_SYMBOL(give_up_console);
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index ff57c40..f20668c 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -647,6 +647,21 @@
 	return policy->governor->show_setspeed(policy, buf);
 }
 
+/**
+ * show_scaling_driver - show the current cpufreq HW/BIOS limitation
+ */
+static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
+{
+	unsigned int limit;
+	int ret;
+	if (cpufreq_driver->bios_limit) {
+		ret = cpufreq_driver->bios_limit(policy->cpu, &limit);
+		if (!ret)
+			return sprintf(buf, "%u\n", limit);
+	}
+	return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
+}
+
 #define define_one_ro(_name) \
 static struct freq_attr _name = \
 __ATTR(_name, 0444, show_##_name, NULL)
@@ -666,6 +681,7 @@
 define_one_ro(scaling_available_governors);
 define_one_ro(scaling_driver);
 define_one_ro(scaling_cur_freq);
+define_one_ro(bios_limit);
 define_one_ro(related_cpus);
 define_one_ro(affected_cpus);
 define_one_rw(scaling_min_freq);
@@ -767,8 +783,9 @@
  *   0:        Success
  *   Positive: When we have a managed CPU and the sysfs got symlinked
  */
-int cpufreq_add_dev_policy(unsigned int cpu, struct cpufreq_policy *policy,
-		struct sys_device *sys_dev)
+static int cpufreq_add_dev_policy(unsigned int cpu,
+				  struct cpufreq_policy *policy,
+				  struct sys_device *sys_dev)
 {
 	int ret = 0;
 #ifdef CONFIG_SMP
@@ -842,7 +859,8 @@
 
 
 /* symlink affected CPUs */
-int cpufreq_add_dev_symlink(unsigned int cpu, struct cpufreq_policy *policy)
+static int cpufreq_add_dev_symlink(unsigned int cpu,
+				   struct cpufreq_policy *policy)
 {
 	unsigned int j;
 	int ret = 0;
@@ -869,8 +887,9 @@
 	return ret;
 }
 
-int cpufreq_add_dev_interface(unsigned int cpu, struct cpufreq_policy *policy,
-		struct sys_device *sys_dev)
+static int cpufreq_add_dev_interface(unsigned int cpu,
+				     struct cpufreq_policy *policy,
+				     struct sys_device *sys_dev)
 {
 	struct cpufreq_policy new_policy;
 	struct freq_attr **drv_attr;
@@ -902,6 +921,11 @@
 		if (ret)
 			goto err_out_kobj_put;
 	}
+	if (cpufreq_driver->bios_limit) {
+		ret = sysfs_create_file(&policy->kobj, &bios_limit.attr);
+		if (ret)
+			goto err_out_kobj_put;
+	}
 
 	spin_lock_irqsave(&cpufreq_driver_lock, flags);
 	for_each_cpu(j, policy->cpus) {
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index c7b081b..599a40b 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -164,20 +164,22 @@
 };
 
 /************************** sysfs interface ************************/
-static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf)
+static ssize_t show_sampling_rate_max(struct kobject *kobj,
+				      struct attribute *attr, char *buf)
 {
 	printk_once(KERN_INFO "CPUFREQ: conservative sampling_rate_max "
 		    "sysfs file is deprecated - used by: %s\n", current->comm);
 	return sprintf(buf, "%u\n", -1U);
 }
 
-static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf)
+static ssize_t show_sampling_rate_min(struct kobject *kobj,
+				      struct attribute *attr, char *buf)
 {
 	return sprintf(buf, "%u\n", min_sampling_rate);
 }
 
 #define define_one_ro(_name)		\
-static struct freq_attr _name =		\
+static struct global_attr _name =	\
 __ATTR(_name, 0444, show_##_name, NULL)
 
 define_one_ro(sampling_rate_max);
@@ -186,7 +188,7 @@
 /* cpufreq_conservative Governor Tunables */
 #define show_one(file_name, object)					\
 static ssize_t show_##file_name						\
-(struct cpufreq_policy *unused, char *buf)				\
+(struct kobject *kobj, struct attribute *attr, char *buf)		\
 {									\
 	return sprintf(buf, "%u\n", dbs_tuners_ins.object);		\
 }
@@ -197,8 +199,40 @@
 show_one(ignore_nice_load, ignore_nice);
 show_one(freq_step, freq_step);
 
-static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused,
-		const char *buf, size_t count)
+/*** delete after deprecation time ***/
+#define DEPRECATION_MSG(file_name)					\
+	printk_once(KERN_INFO "CPUFREQ: Per core conservative sysfs "	\
+		"interface is deprecated - " #file_name "\n");
+
+#define show_one_old(file_name)						\
+static ssize_t show_##file_name##_old					\
+(struct cpufreq_policy *unused, char *buf)				\
+{									\
+	printk_once(KERN_INFO "CPUFREQ: Per core conservative sysfs "	\
+		"interface is deprecated - " #file_name "\n");		\
+	return show_##file_name(NULL, NULL, buf);			\
+}
+show_one_old(sampling_rate);
+show_one_old(sampling_down_factor);
+show_one_old(up_threshold);
+show_one_old(down_threshold);
+show_one_old(ignore_nice_load);
+show_one_old(freq_step);
+show_one_old(sampling_rate_min);
+show_one_old(sampling_rate_max);
+
+#define define_one_ro_old(object, _name)	\
+static struct freq_attr object =		\
+__ATTR(_name, 0444, show_##_name##_old, NULL)
+
+define_one_ro_old(sampling_rate_min_old, sampling_rate_min);
+define_one_ro_old(sampling_rate_max_old, sampling_rate_max);
+
+/*** delete after deprecation time ***/
+
+static ssize_t store_sampling_down_factor(struct kobject *a,
+					  struct attribute *b,
+					  const char *buf, size_t count)
 {
 	unsigned int input;
 	int ret;
@@ -214,8 +248,8 @@
 	return count;
 }
 
-static ssize_t store_sampling_rate(struct cpufreq_policy *unused,
-		const char *buf, size_t count)
+static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b,
+				   const char *buf, size_t count)
 {
 	unsigned int input;
 	int ret;
@@ -231,8 +265,8 @@
 	return count;
 }
 
-static ssize_t store_up_threshold(struct cpufreq_policy *unused,
-		const char *buf, size_t count)
+static ssize_t store_up_threshold(struct kobject *a, struct attribute *b,
+				  const char *buf, size_t count)
 {
 	unsigned int input;
 	int ret;
@@ -251,8 +285,8 @@
 	return count;
 }
 
-static ssize_t store_down_threshold(struct cpufreq_policy *unused,
-		const char *buf, size_t count)
+static ssize_t store_down_threshold(struct kobject *a, struct attribute *b,
+				    const char *buf, size_t count)
 {
 	unsigned int input;
 	int ret;
@@ -272,8 +306,8 @@
 	return count;
 }
 
-static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
-		const char *buf, size_t count)
+static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b,
+				      const char *buf, size_t count)
 {
 	unsigned int input;
 	int ret;
@@ -308,8 +342,8 @@
 	return count;
 }
 
-static ssize_t store_freq_step(struct cpufreq_policy *policy,
-		const char *buf, size_t count)
+static ssize_t store_freq_step(struct kobject *a, struct attribute *b,
+			       const char *buf, size_t count)
 {
 	unsigned int input;
 	int ret;
@@ -331,7 +365,7 @@
 }
 
 #define define_one_rw(_name) \
-static struct freq_attr _name = \
+static struct global_attr _name = \
 __ATTR(_name, 0644, show_##_name, store_##_name)
 
 define_one_rw(sampling_rate);
@@ -358,6 +392,53 @@
 	.name = "conservative",
 };
 
+/*** delete after deprecation time ***/
+
+#define write_one_old(file_name)					\
+static ssize_t store_##file_name##_old					\
+(struct cpufreq_policy *unused, const char *buf, size_t count)		\
+{									\
+	printk_once(KERN_INFO "CPUFREQ: Per core conservative sysfs "	\
+		"interface is deprecated - " #file_name "\n");	\
+	return store_##file_name(NULL, NULL, buf, count);		\
+}
+write_one_old(sampling_rate);
+write_one_old(sampling_down_factor);
+write_one_old(up_threshold);
+write_one_old(down_threshold);
+write_one_old(ignore_nice_load);
+write_one_old(freq_step);
+
+#define define_one_rw_old(object, _name)	\
+static struct freq_attr object =		\
+__ATTR(_name, 0644, show_##_name##_old, store_##_name##_old)
+
+define_one_rw_old(sampling_rate_old, sampling_rate);
+define_one_rw_old(sampling_down_factor_old, sampling_down_factor);
+define_one_rw_old(up_threshold_old, up_threshold);
+define_one_rw_old(down_threshold_old, down_threshold);
+define_one_rw_old(ignore_nice_load_old, ignore_nice_load);
+define_one_rw_old(freq_step_old, freq_step);
+
+static struct attribute *dbs_attributes_old[] = {
+	&sampling_rate_max_old.attr,
+	&sampling_rate_min_old.attr,
+	&sampling_rate_old.attr,
+	&sampling_down_factor_old.attr,
+	&up_threshold_old.attr,
+	&down_threshold_old.attr,
+	&ignore_nice_load_old.attr,
+	&freq_step_old.attr,
+	NULL
+};
+
+static struct attribute_group dbs_attr_group_old = {
+	.attrs = dbs_attributes_old,
+	.name = "conservative",
+};
+
+/*** delete after deprecation time ***/
+
 /************************** sysfs end ************************/
 
 static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
@@ -530,7 +611,7 @@
 
 		mutex_lock(&dbs_mutex);
 
-		rc = sysfs_create_group(&policy->kobj, &dbs_attr_group);
+		rc = sysfs_create_group(&policy->kobj, &dbs_attr_group_old);
 		if (rc) {
 			mutex_unlock(&dbs_mutex);
 			return rc;
@@ -564,6 +645,13 @@
 			if (latency == 0)
 				latency = 1;
 
+			rc = sysfs_create_group(cpufreq_global_kobject,
+						&dbs_attr_group);
+			if (rc) {
+				mutex_unlock(&dbs_mutex);
+				return rc;
+			}
+
 			/*
 			 * conservative does not implement micro like ondemand
 			 * governor, thus we are bound to jiffes/HZ
@@ -591,7 +679,7 @@
 		dbs_timer_exit(this_dbs_info);
 
 		mutex_lock(&dbs_mutex);
-		sysfs_remove_group(&policy->kobj, &dbs_attr_group);
+		sysfs_remove_group(&policy->kobj, &dbs_attr_group_old);
 		dbs_enable--;
 		mutex_destroy(&this_dbs_info->timer_mutex);
 
@@ -605,6 +693,9 @@
 					CPUFREQ_TRANSITION_NOTIFIER);
 
 		mutex_unlock(&dbs_mutex);
+		if (!dbs_enable)
+			sysfs_remove_group(cpufreq_global_kobject,
+					   &dbs_attr_group);
 
 		break;
 
diff --git a/drivers/cpuidle/governor.c b/drivers/cpuidle/governor.c
index 70b5964..724c164 100644
--- a/drivers/cpuidle/governor.c
+++ b/drivers/cpuidle/governor.c
@@ -21,7 +21,7 @@
  * __cpuidle_find_governor - finds a governor of the specified name
  * @str: the name
  *
- * Must be called with cpuidle_lock aquired.
+ * Must be called with cpuidle_lock acquired.
  */
 static struct cpuidle_governor * __cpuidle_find_governor(const char *str)
 {
@@ -39,7 +39,7 @@
  * @gov: the new target governor
  *
  * NOTE: "gov" can be NULL to specify disabled
- * Must be called with cpuidle_lock aquired.
+ * Must be called with cpuidle_lock acquired.
  */
 int cpuidle_switch_governor(struct cpuidle_governor *gov)
 {
diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c
index 5f753fc..09ad915 100644
--- a/drivers/crypto/hifn_795x.c
+++ b/drivers/crypto/hifn_795x.c
@@ -863,7 +863,7 @@
 		dev->dmareg |= HIFN_DMAIER_PUBDONE;
 		hifn_write_1(dev, HIFN_1_DMA_IER, dev->dmareg);
 
-		dprintk("Chip %s: Public key engine has been sucessfully "
+		dprintk("Chip %s: Public key engine has been successfully "
 				"initialised.\n", dev->name);
 	}
 
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index 7585c41..c52ac9e 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -99,7 +99,7 @@
 }
 
 /**
- * atc_desc_get - get a unsused descriptor from free_list
+ * atc_desc_get - get an unused descriptor from free_list
  * @atchan: channel we want a new descriptor for
  */
 static struct at_desc *atc_desc_get(struct at_dma_chan *atchan)
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index a38831c..5fdd6da 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -19,26 +19,48 @@
 static struct amd64_pvt *pvt_lookup[EDAC_MAX_NUMNODES];
 
 /*
- * See F2x80 for K8 and F2x[1,0]80 for Fam10 and later. The table below is only
- * for DDR2 DRAM mapping.
+ * Address to DRAM bank mapping: see F2x80 for K8 and F2x[1,0]80 for Fam10 and
+ * later.
  */
-u32 revf_quad_ddr2_shift[] = {
-	0,	/* 0000b NULL DIMM (128mb) */
-	28,	/* 0001b 256mb */
-	29,	/* 0010b 512mb */
-	29,	/* 0011b 512mb */
-	29,	/* 0100b 512mb */
-	30,	/* 0101b 1gb */
-	30,	/* 0110b 1gb */
-	31,	/* 0111b 2gb */
-	31,	/* 1000b 2gb */
-	32,	/* 1001b 4gb */
-	32,	/* 1010b 4gb */
-	33,	/* 1011b 8gb */
-	0,	/* 1100b future */
-	0,	/* 1101b future */
-	0,	/* 1110b future */
-	0	/* 1111b future */
+static int ddr2_dbam_revCG[] = {
+			   [0]		= 32,
+			   [1]		= 64,
+			   [2]		= 128,
+			   [3]		= 256,
+			   [4]		= 512,
+			   [5]		= 1024,
+			   [6]		= 2048,
+};
+
+static int ddr2_dbam_revD[] = {
+			   [0]		= 32,
+			   [1]		= 64,
+			   [2 ... 3]	= 128,
+			   [4]		= 256,
+			   [5]		= 512,
+			   [6]		= 256,
+			   [7]		= 512,
+			   [8 ... 9]	= 1024,
+			   [10]		= 2048,
+};
+
+static int ddr2_dbam[] = { [0]		= 128,
+			   [1]		= 256,
+			   [2 ... 4]	= 512,
+			   [5 ... 6]	= 1024,
+			   [7 ... 8]	= 2048,
+			   [9 ... 10]	= 4096,
+			   [11]		= 8192,
+};
+
+static int ddr3_dbam[] = { [0]		= -1,
+			   [1]		= 256,
+			   [2]		= 512,
+			   [3 ... 4]	= -1,
+			   [5 ... 6]	= 1024,
+			   [7 ... 8]	= 2048,
+			   [9 ... 10]	= 4096,
+			   [11]	= 8192,
 };
 
 /*
@@ -164,11 +186,9 @@
 {
 	struct amd64_pvt *pvt = mci->pvt_info;
 	u32 scrubval = 0;
-	int status = -1, i, ret = 0;
+	int status = -1, i;
 
-	ret = pci_read_config_dword(pvt->misc_f3_ctl, K8_SCRCTRL, &scrubval);
-	if (ret)
-		debugf0("Reading K8_SCRCTRL failed\n");
+	amd64_read_pci_cfg(pvt->misc_f3_ctl, K8_SCRCTRL, &scrubval);
 
 	scrubval = scrubval & 0x001F;
 
@@ -189,7 +209,7 @@
 /* Map from a CSROW entry to the mask entry that operates on it */
 static inline u32 amd64_map_to_dcs_mask(struct amd64_pvt *pvt, int csrow)
 {
-	if (boot_cpu_data.x86 == 0xf && pvt->ext_model < OPTERON_CPU_REV_F)
+	if (boot_cpu_data.x86 == 0xf && pvt->ext_model < K8_REV_F)
 		return csrow;
 	else
 		return csrow >> 1;
@@ -437,7 +457,7 @@
 	u64 base;
 
 	/* only revE and later have the DRAM Hole Address Register */
-	if (boot_cpu_data.x86 == 0xf && pvt->ext_model < OPTERON_CPU_REV_E) {
+	if (boot_cpu_data.x86 == 0xf && pvt->ext_model < K8_REV_E) {
 		debugf1("  revision %d for node %d does not support DHAR\n",
 			pvt->ext_model, pvt->mc_node_id);
 		return 1;
@@ -743,21 +763,6 @@
 	*input_addr_max = base | mask | pvt->dcs_mask_notused;
 }
 
-/*
- * Extract error address from MCA NB Address Low (section 3.6.4.5) and MCA NB
- * Address High (section 3.6.4.6) register values and return the result. Address
- * is located in the info structure (nbeah and nbeal), the encoding is device
- * specific.
- */
-static u64 extract_error_address(struct mem_ctl_info *mci,
-				 struct err_regs *info)
-{
-	struct amd64_pvt *pvt = mci->pvt_info;
-
-	return pvt->ops->get_error_address(mci, info);
-}
-
-
 /* Map the Error address to a PAGE and PAGE OFFSET. */
 static inline void error_address_to_page_and_offset(u64 error_address,
 						    u32 *page, u32 *offset)
@@ -787,7 +792,7 @@
 	return csrow;
 }
 
-static int get_channel_from_ecc_syndrome(unsigned short syndrome);
+static int get_channel_from_ecc_syndrome(struct mem_ctl_info *, u16);
 
 static void amd64_cpu_display_info(struct amd64_pvt *pvt)
 {
@@ -797,7 +802,7 @@
 		edac_printk(KERN_DEBUG, EDAC_MC, "F10h CPU detected\n");
 	else if (boot_cpu_data.x86 == 0xf)
 		edac_printk(KERN_DEBUG, EDAC_MC, "%s detected\n",
-			(pvt->ext_model >= OPTERON_CPU_REV_F) ?
+			(pvt->ext_model >= K8_REV_F) ?
 			"Rev F or later" : "Rev E or earlier");
 	else
 		/* we'll hardly ever ever get here */
@@ -813,7 +818,7 @@
 	int bit;
 	enum dev_type edac_cap = EDAC_FLAG_NONE;
 
-	bit = (boot_cpu_data.x86 > 0xf || pvt->ext_model >= OPTERON_CPU_REV_F)
+	bit = (boot_cpu_data.x86 > 0xf || pvt->ext_model >= K8_REV_F)
 		? 19
 		: 17;
 
@@ -824,75 +829,66 @@
 }
 
 
-static void f10_debug_display_dimm_sizes(int ctrl, struct amd64_pvt *pvt,
-					 int ganged);
+static void amd64_debug_display_dimm_sizes(int ctrl, struct amd64_pvt *pvt);
+
+static void amd64_dump_dramcfg_low(u32 dclr, int chan)
+{
+	debugf1("F2x%d90 (DRAM Cfg Low): 0x%08x\n", chan, dclr);
+
+	debugf1("  DIMM type: %sbuffered; all DIMMs support ECC: %s\n",
+		(dclr & BIT(16)) ?  "un" : "",
+		(dclr & BIT(19)) ? "yes" : "no");
+
+	debugf1("  PAR/ERR parity: %s\n",
+		(dclr & BIT(8)) ?  "enabled" : "disabled");
+
+	debugf1("  DCT 128bit mode width: %s\n",
+		(dclr & BIT(11)) ?  "128b" : "64b");
+
+	debugf1("  x4 logical DIMMs present: L0: %s L1: %s L2: %s L3: %s\n",
+		(dclr & BIT(12)) ?  "yes" : "no",
+		(dclr & BIT(13)) ?  "yes" : "no",
+		(dclr & BIT(14)) ?  "yes" : "no",
+		(dclr & BIT(15)) ?  "yes" : "no");
+}
 
 /* Display and decode various NB registers for debug purposes. */
 static void amd64_dump_misc_regs(struct amd64_pvt *pvt)
 {
 	int ganged;
 
-	debugf1("  nbcap:0x%8.08x DctDualCap=%s DualNode=%s 8-Node=%s\n",
-		pvt->nbcap,
-		(pvt->nbcap & K8_NBCAP_DCT_DUAL) ? "True" : "False",
-		(pvt->nbcap & K8_NBCAP_DUAL_NODE) ? "True" : "False",
-		(pvt->nbcap & K8_NBCAP_8_NODE) ? "True" : "False");
-	debugf1("    ECC Capable=%s   ChipKill Capable=%s\n",
-		(pvt->nbcap & K8_NBCAP_SECDED) ? "True" : "False",
-		(pvt->nbcap & K8_NBCAP_CHIPKILL) ? "True" : "False");
-	debugf1("  DramCfg0-low=0x%08x DIMM-ECC=%s Parity=%s Width=%s\n",
-		pvt->dclr0,
-		(pvt->dclr0 & BIT(19)) ?  "Enabled" : "Disabled",
-		(pvt->dclr0 & BIT(8)) ?  "Enabled" : "Disabled",
-		(pvt->dclr0 & BIT(11)) ?  "128b" : "64b");
-	debugf1("    DIMM x4 Present: L0=%s L1=%s L2=%s L3=%s  DIMM Type=%s\n",
-		(pvt->dclr0 & BIT(12)) ?  "Y" : "N",
-		(pvt->dclr0 & BIT(13)) ?  "Y" : "N",
-		(pvt->dclr0 & BIT(14)) ?  "Y" : "N",
-		(pvt->dclr0 & BIT(15)) ?  "Y" : "N",
-		(pvt->dclr0 & BIT(16)) ?  "UN-Buffered" : "Buffered");
+	debugf1("F3xE8 (NB Cap): 0x%08x\n", pvt->nbcap);
 
+	debugf1("  NB two channel DRAM capable: %s\n",
+		(pvt->nbcap & K8_NBCAP_DCT_DUAL) ? "yes" : "no");
 
-	debugf1("  online-spare: 0x%8.08x\n", pvt->online_spare);
+	debugf1("  ECC capable: %s, ChipKill ECC capable: %s\n",
+		(pvt->nbcap & K8_NBCAP_SECDED) ? "yes" : "no",
+		(pvt->nbcap & K8_NBCAP_CHIPKILL) ? "yes" : "no");
 
+	amd64_dump_dramcfg_low(pvt->dclr0, 0);
+
+	debugf1("F3xB0 (Online Spare): 0x%08x\n", pvt->online_spare);
+
+	debugf1("F1xF0 (DRAM Hole Address): 0x%08x, base: 0x%08x, "
+			"offset: 0x%08x\n",
+			pvt->dhar,
+			dhar_base(pvt->dhar),
+			(boot_cpu_data.x86 == 0xf) ? k8_dhar_offset(pvt->dhar)
+						   : f10_dhar_offset(pvt->dhar));
+
+	debugf1("  DramHoleValid: %s\n",
+		(pvt->dhar & DHAR_VALID) ? "yes" : "no");
+
+	/* everything below this point is Fam10h and above */
 	if (boot_cpu_data.x86 == 0xf) {
-		debugf1("  dhar: 0x%8.08x Base=0x%08x Offset=0x%08x\n",
-			pvt->dhar, dhar_base(pvt->dhar),
-			k8_dhar_offset(pvt->dhar));
-		debugf1("      DramHoleValid=%s\n",
-			(pvt->dhar & DHAR_VALID) ?  "True" : "False");
-
-		debugf1("  dbam-dkt: 0x%8.08x\n", pvt->dbam0);
-
-		/* everything below this point is Fam10h and above */
+		amd64_debug_display_dimm_sizes(0, pvt);
 		return;
-
-	} else {
-		debugf1("  dhar: 0x%8.08x Base=0x%08x Offset=0x%08x\n",
-			pvt->dhar, dhar_base(pvt->dhar),
-			f10_dhar_offset(pvt->dhar));
-		debugf1("    DramMemHoistValid=%s DramHoleValid=%s\n",
-			(pvt->dhar & F10_DRAM_MEM_HOIST_VALID) ?
-			"True" : "False",
-			(pvt->dhar & DHAR_VALID) ?
-			"True" : "False");
 	}
 
-	/* Only if NOT ganged does dcl1 have valid info */
-	if (!dct_ganging_enabled(pvt)) {
-		debugf1("  DramCfg1-low=0x%08x DIMM-ECC=%s Parity=%s "
-			"Width=%s\n", pvt->dclr1,
-			(pvt->dclr1 & BIT(19)) ?  "Enabled" : "Disabled",
-			(pvt->dclr1 & BIT(8)) ?  "Enabled" : "Disabled",
-			(pvt->dclr1 & BIT(11)) ?  "128b" : "64b");
-		debugf1("    DIMM x4 Present: L0=%s L1=%s L2=%s L3=%s  "
-			"DIMM Type=%s\n",
-			(pvt->dclr1 & BIT(12)) ?  "Y" : "N",
-			(pvt->dclr1 & BIT(13)) ?  "Y" : "N",
-			(pvt->dclr1 & BIT(14)) ?  "Y" : "N",
-			(pvt->dclr1 & BIT(15)) ?  "Y" : "N",
-			(pvt->dclr1 & BIT(16)) ?  "UN-Buffered" : "Buffered");
-	}
+	/* Only if NOT ganged does dclr1 have valid info */
+	if (!dct_ganging_enabled(pvt))
+		amd64_dump_dramcfg_low(pvt->dclr1, 1);
 
 	/*
 	 * Determine if ganged and then dump memory sizes for first controller,
@@ -900,35 +896,19 @@
 	 */
 	ganged = dct_ganging_enabled(pvt);
 
-	f10_debug_display_dimm_sizes(0, pvt, ganged);
+	amd64_debug_display_dimm_sizes(0, pvt);
 
 	if (!ganged)
-		f10_debug_display_dimm_sizes(1, pvt, ganged);
+		amd64_debug_display_dimm_sizes(1, pvt);
 }
 
 /* Read in both of DBAM registers */
 static void amd64_read_dbam_reg(struct amd64_pvt *pvt)
 {
-	int err = 0;
-	unsigned int reg;
+	amd64_read_pci_cfg(pvt->dram_f2_ctl, DBAM0, &pvt->dbam0);
 
-	reg = DBAM0;
-	err = pci_read_config_dword(pvt->dram_f2_ctl, reg, &pvt->dbam0);
-	if (err)
-		goto err_reg;
-
-	if (boot_cpu_data.x86 >= 0x10) {
-		reg = DBAM1;
-		err = pci_read_config_dword(pvt->dram_f2_ctl, reg, &pvt->dbam1);
-
-		if (err)
-			goto err_reg;
-	}
-
-	return;
-
-err_reg:
-	debugf0("Error reading F2x%03x.\n", reg);
+	if (boot_cpu_data.x86 >= 0x10)
+		amd64_read_pci_cfg(pvt->dram_f2_ctl, DBAM1, &pvt->dbam1);
 }
 
 /*
@@ -963,7 +943,7 @@
 static void amd64_set_dct_base_and_mask(struct amd64_pvt *pvt)
 {
 
-	if (boot_cpu_data.x86 == 0xf && pvt->ext_model < OPTERON_CPU_REV_F) {
+	if (boot_cpu_data.x86 == 0xf && pvt->ext_model < K8_REV_F) {
 		pvt->dcsb_base		= REV_E_DCSB_BASE_BITS;
 		pvt->dcsm_mask		= REV_E_DCSM_MASK_BITS;
 		pvt->dcs_mask_notused	= REV_E_DCS_NOTUSED_BITS;
@@ -991,28 +971,21 @@
  */
 static void amd64_read_dct_base_mask(struct amd64_pvt *pvt)
 {
-	int cs, reg, err = 0;
+	int cs, reg;
 
 	amd64_set_dct_base_and_mask(pvt);
 
 	for (cs = 0; cs < pvt->cs_count; cs++) {
 		reg = K8_DCSB0 + (cs * 4);
-		err = pci_read_config_dword(pvt->dram_f2_ctl, reg,
-						&pvt->dcsb0[cs]);
-		if (unlikely(err))
-			debugf0("Reading K8_DCSB0[%d] failed\n", cs);
-		else
+		if (!amd64_read_pci_cfg(pvt->dram_f2_ctl, reg, &pvt->dcsb0[cs]))
 			debugf0("  DCSB0[%d]=0x%08x reg: F2x%x\n",
 				cs, pvt->dcsb0[cs], reg);
 
 		/* If DCT are NOT ganged, then read in DCT1's base */
 		if (boot_cpu_data.x86 >= 0x10 && !dct_ganging_enabled(pvt)) {
 			reg = F10_DCSB1 + (cs * 4);
-			err = pci_read_config_dword(pvt->dram_f2_ctl, reg,
-							&pvt->dcsb1[cs]);
-			if (unlikely(err))
-				debugf0("Reading F10_DCSB1[%d] failed\n", cs);
-			else
+			if (!amd64_read_pci_cfg(pvt->dram_f2_ctl, reg,
+						&pvt->dcsb1[cs]))
 				debugf0("  DCSB1[%d]=0x%08x reg: F2x%x\n",
 					cs, pvt->dcsb1[cs], reg);
 		} else {
@@ -1022,26 +995,20 @@
 
 	for (cs = 0; cs < pvt->num_dcsm; cs++) {
 		reg = K8_DCSM0 + (cs * 4);
-		err = pci_read_config_dword(pvt->dram_f2_ctl, reg,
-					&pvt->dcsm0[cs]);
-		if (unlikely(err))
-			debugf0("Reading K8_DCSM0 failed\n");
-		else
+		if (!amd64_read_pci_cfg(pvt->dram_f2_ctl, reg, &pvt->dcsm0[cs]))
 			debugf0("    DCSM0[%d]=0x%08x reg: F2x%x\n",
 				cs, pvt->dcsm0[cs], reg);
 
 		/* If DCT are NOT ganged, then read in DCT1's mask */
 		if (boot_cpu_data.x86 >= 0x10 && !dct_ganging_enabled(pvt)) {
 			reg = F10_DCSM1 + (cs * 4);
-			err = pci_read_config_dword(pvt->dram_f2_ctl, reg,
-					&pvt->dcsm1[cs]);
-			if (unlikely(err))
-				debugf0("Reading F10_DCSM1[%d] failed\n", cs);
-			else
+			if (!amd64_read_pci_cfg(pvt->dram_f2_ctl, reg,
+						&pvt->dcsm1[cs]))
 				debugf0("    DCSM1[%d]=0x%08x reg: F2x%x\n",
 					cs, pvt->dcsm1[cs], reg);
-		} else
+		} else {
 			pvt->dcsm1[cs] = 0;
+		}
 	}
 }
 
@@ -1049,18 +1016,16 @@
 {
 	enum mem_type type;
 
-	if (boot_cpu_data.x86 >= 0x10 || pvt->ext_model >= OPTERON_CPU_REV_F) {
-		/* Rev F and later */
-		type = (pvt->dclr0 & BIT(16)) ? MEM_DDR2 : MEM_RDDR2;
+	if (boot_cpu_data.x86 >= 0x10 || pvt->ext_model >= K8_REV_F) {
+		if (pvt->dchr0 & DDR3_MODE)
+			type = (pvt->dclr0 & BIT(16)) ?	MEM_DDR3 : MEM_RDDR3;
+		else
+			type = (pvt->dclr0 & BIT(16)) ? MEM_DDR2 : MEM_RDDR2;
 	} else {
-		/* Rev E and earlier */
 		type = (pvt->dclr0 & BIT(18)) ? MEM_DDR : MEM_RDDR;
 	}
 
-	debugf1("  Memory type is: %s\n",
-		(type == MEM_DDR2) ? "MEM_DDR2" :
-		(type == MEM_RDDR2) ? "MEM_RDDR2" :
-		(type == MEM_DDR) ? "MEM_DDR" : "MEM_RDDR");
+	debugf1("  Memory type is: %s\n", edac_mem_types[type]);
 
 	return type;
 }
@@ -1078,11 +1043,11 @@
 {
 	int flag, err = 0;
 
-	err = pci_read_config_dword(pvt->dram_f2_ctl, F10_DCLR_0, &pvt->dclr0);
+	err = amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCLR_0, &pvt->dclr0);
 	if (err)
 		return err;
 
-	if ((boot_cpu_data.x86_model >> 4) >= OPTERON_CPU_REV_F) {
+	if ((boot_cpu_data.x86_model >> 4) >= K8_REV_F) {
 		/* RevF (NPT) and later */
 		flag = pvt->dclr0 & F10_WIDTH_128;
 	} else {
@@ -1114,22 +1079,15 @@
 {
 	u32 low;
 	u32 off = dram << 3;	/* 8 bytes between DRAM entries */
-	int err;
 
-	err = pci_read_config_dword(pvt->addr_f1_ctl,
-				    K8_DRAM_BASE_LOW + off, &low);
-	if (err)
-		debugf0("Reading K8_DRAM_BASE_LOW failed\n");
+	amd64_read_pci_cfg(pvt->addr_f1_ctl, K8_DRAM_BASE_LOW + off, &low);
 
 	/* Extract parts into separate data entries */
 	pvt->dram_base[dram] = ((u64) low & 0xFFFF0000) << 8;
 	pvt->dram_IntlvEn[dram] = (low >> 8) & 0x7;
 	pvt->dram_rw_en[dram] = (low & 0x3);
 
-	err = pci_read_config_dword(pvt->addr_f1_ctl,
-				    K8_DRAM_LIMIT_LOW + off, &low);
-	if (err)
-		debugf0("Reading K8_DRAM_LIMIT_LOW failed\n");
+	amd64_read_pci_cfg(pvt->addr_f1_ctl, K8_DRAM_LIMIT_LOW + off, &low);
 
 	/*
 	 * Extract parts into separate data entries. Limit is the HIGHEST memory
@@ -1142,7 +1100,7 @@
 
 static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
 					struct err_regs *info,
-					u64 SystemAddress)
+					u64 sys_addr)
 {
 	struct mem_ctl_info *src_mci;
 	unsigned short syndrome;
@@ -1155,7 +1113,7 @@
 
 	/* CHIPKILL enabled */
 	if (info->nbcfg & K8_NBCFG_CHIPKILL) {
-		channel = get_channel_from_ecc_syndrome(syndrome);
+		channel = get_channel_from_ecc_syndrome(mci, syndrome);
 		if (channel < 0) {
 			/*
 			 * Syndrome didn't map, so we don't know which of the
@@ -1177,64 +1135,46 @@
 		 * was obtained from email communication with someone at AMD.
 		 * (Wish the email was placed in this comment - norsk)
 		 */
-		channel = ((SystemAddress & BIT(3)) != 0);
+		channel = ((sys_addr & BIT(3)) != 0);
 	}
 
 	/*
 	 * Find out which node the error address belongs to. This may be
 	 * different from the node that detected the error.
 	 */
-	src_mci = find_mc_by_sys_addr(mci, SystemAddress);
+	src_mci = find_mc_by_sys_addr(mci, sys_addr);
 	if (!src_mci) {
 		amd64_mc_printk(mci, KERN_ERR,
 			     "failed to map error address 0x%lx to a node\n",
-			     (unsigned long)SystemAddress);
+			     (unsigned long)sys_addr);
 		edac_mc_handle_ce_no_info(mci, EDAC_MOD_STR);
 		return;
 	}
 
-	/* Now map the SystemAddress to a CSROW */
-	csrow = sys_addr_to_csrow(src_mci, SystemAddress);
+	/* Now map the sys_addr to a CSROW */
+	csrow = sys_addr_to_csrow(src_mci, sys_addr);
 	if (csrow < 0) {
 		edac_mc_handle_ce_no_info(src_mci, EDAC_MOD_STR);
 	} else {
-		error_address_to_page_and_offset(SystemAddress, &page, &offset);
+		error_address_to_page_and_offset(sys_addr, &page, &offset);
 
 		edac_mc_handle_ce(src_mci, page, offset, syndrome, csrow,
 				  channel, EDAC_MOD_STR);
 	}
 }
 
-/*
- * determrine the number of PAGES in for this DIMM's size based on its DRAM
- * Address Mapping.
- *
- * First step is to calc the number of bits to shift a value of 1 left to
- * indicate show many pages. Start with the DBAM value as the starting bits,
- * then proceed to adjust those shift bits, based on CPU rev and the table.
- * See BKDG on the DBAM
- */
-static int k8_dbam_map_to_pages(struct amd64_pvt *pvt, int dram_map)
+static int k8_dbam_to_chip_select(struct amd64_pvt *pvt, int cs_mode)
 {
-	int nr_pages;
+	int *dbam_map;
 
-	if (pvt->ext_model >= OPTERON_CPU_REV_F) {
-		nr_pages = 1 << (revf_quad_ddr2_shift[dram_map] - PAGE_SHIFT);
-	} else {
-		/*
-		 * RevE and less section; this line is tricky. It collapses the
-		 * table used by RevD and later to one that matches revisions CG
-		 * and earlier.
-		 */
-		dram_map -= (pvt->ext_model >= OPTERON_CPU_REV_D) ?
-				(dram_map > 8 ? 4 : (dram_map > 5 ?
-				3 : (dram_map > 2 ? 1 : 0))) : 0;
+	if (pvt->ext_model >= K8_REV_F)
+		dbam_map = ddr2_dbam;
+	else if (pvt->ext_model >= K8_REV_D)
+		dbam_map = ddr2_dbam_revD;
+	else
+		dbam_map = ddr2_dbam_revCG;
 
-		/* 25 shift is 32MiB minimum DIMM size in RevE and prior */
-		nr_pages = 1 << (dram_map + 25 - PAGE_SHIFT);
-	}
-
-	return nr_pages;
+	return dbam_map[cs_mode];
 }
 
 /*
@@ -1248,34 +1188,24 @@
 static int f10_early_channel_count(struct amd64_pvt *pvt)
 {
 	int dbams[] = { DBAM0, DBAM1 };
-	int err = 0, channels = 0;
-	int i, j;
+	int i, j, channels = 0;
 	u32 dbam;
 
-	err = pci_read_config_dword(pvt->dram_f2_ctl, F10_DCLR_0, &pvt->dclr0);
-	if (err)
-		goto err_reg;
-
-	err = pci_read_config_dword(pvt->dram_f2_ctl, F10_DCLR_1, &pvt->dclr1);
-	if (err)
-		goto err_reg;
-
 	/* If we are in 128 bit mode, then we are using 2 channels */
 	if (pvt->dclr0 & F10_WIDTH_128) {
-		debugf0("Data WIDTH is 128 bits - 2 channels\n");
 		channels = 2;
 		return channels;
 	}
 
 	/*
-	 * Need to check if in UN-ganged mode: In such, there are 2 channels,
-	 * but they are NOT in 128 bit mode and thus the above 'dcl0' status bit
-	 * will be OFF.
+	 * Need to check if in unganged mode: In such, there are 2 channels,
+	 * but they are not in 128 bit mode and thus the above 'dclr0' status
+	 * bit will be OFF.
 	 *
 	 * Need to check DCT0[0] and DCT1[0] to see if only one of them has
 	 * their CSEnable bit on. If so, then SINGLE DIMM case.
 	 */
-	debugf0("Data WIDTH is NOT 128 bits - need more decoding\n");
+	debugf0("Data width is not 128 bits - need more decoding\n");
 
 	/*
 	 * Check DRAM Bank Address Mapping values for each DIMM to see if there
@@ -1283,8 +1213,7 @@
 	 * both controllers since DIMMs can be placed in either one.
 	 */
 	for (i = 0; i < ARRAY_SIZE(dbams); i++) {
-		err = pci_read_config_dword(pvt->dram_f2_ctl, dbams[i], &dbam);
-		if (err)
+		if (amd64_read_pci_cfg(pvt->dram_f2_ctl, dbams[i], &dbam))
 			goto err_reg;
 
 		for (j = 0; j < 4; j++) {
@@ -1295,6 +1224,9 @@
 		}
 	}
 
+	if (channels > 2)
+		channels = 2;
+
 	debugf0("MCT channel count: %d\n", channels);
 
 	return channels;
@@ -1304,9 +1236,16 @@
 
 }
 
-static int f10_dbam_map_to_pages(struct amd64_pvt *pvt, int dram_map)
+static int f10_dbam_to_chip_select(struct amd64_pvt *pvt, int cs_mode)
 {
-	return 1 << (revf_quad_ddr2_shift[dram_map] - PAGE_SHIFT);
+	int *dbam_map;
+
+	if (pvt->dchr0 & DDR3_MODE || pvt->dchr1 & DDR3_MODE)
+		dbam_map = ddr3_dbam;
+	else
+		dbam_map = ddr2_dbam;
+
+	return dbam_map[cs_mode];
 }
 
 /* Enable extended configuration access via 0xCF8 feature */
@@ -1314,7 +1253,7 @@
 {
 	u32 reg;
 
-	pci_read_config_dword(pvt->misc_f3_ctl, F10_NB_CFG_HIGH, &reg);
+	amd64_read_pci_cfg(pvt->misc_f3_ctl, F10_NB_CFG_HIGH, &reg);
 
 	pvt->flags.cf8_extcfg = !!(reg & F10_NB_CFG_LOW_ENABLE_EXT_CFG);
 	reg |= F10_NB_CFG_LOW_ENABLE_EXT_CFG;
@@ -1326,7 +1265,7 @@
 {
 	u32 reg;
 
-	pci_read_config_dword(pvt->misc_f3_ctl, F10_NB_CFG_HIGH, &reg);
+	amd64_read_pci_cfg(pvt->misc_f3_ctl, F10_NB_CFG_HIGH, &reg);
 
 	reg &= ~F10_NB_CFG_LOW_ENABLE_EXT_CFG;
 	if (pvt->flags.cf8_extcfg)
@@ -1355,10 +1294,10 @@
 	high_offset = F10_DRAM_BASE_HIGH + (dram << 3);
 
 	/* read the 'raw' DRAM BASE Address register */
-	pci_read_config_dword(pvt->addr_f1_ctl, low_offset, &low_base);
+	amd64_read_pci_cfg(pvt->addr_f1_ctl, low_offset, &low_base);
 
 	/* Read from the ECS data register */
-	pci_read_config_dword(pvt->addr_f1_ctl, high_offset, &high_base);
+	amd64_read_pci_cfg(pvt->addr_f1_ctl, high_offset, &high_base);
 
 	/* Extract parts into separate data entries */
 	pvt->dram_rw_en[dram] = (low_base & 0x3);
@@ -1375,13 +1314,10 @@
 	high_offset = F10_DRAM_LIMIT_HIGH + (dram << 3);
 
 	/* read the 'raw' LIMIT registers */
-	pci_read_config_dword(pvt->addr_f1_ctl, low_offset, &low_limit);
+	amd64_read_pci_cfg(pvt->addr_f1_ctl, low_offset, &low_limit);
 
 	/* Read from the ECS data register for the HIGH portion */
-	pci_read_config_dword(pvt->addr_f1_ctl, high_offset, &high_limit);
-
-	debugf0("  HW Regs: BASE=0x%08x-%08x      LIMIT=  0x%08x-%08x\n",
-		high_base, low_base, high_limit, low_limit);
+	amd64_read_pci_cfg(pvt->addr_f1_ctl, high_offset, &high_limit);
 
 	pvt->dram_DstNode[dram] = (low_limit & 0x7);
 	pvt->dram_IntlvSel[dram] = (low_limit >> 8) & 0x7;
@@ -1397,32 +1333,35 @@
 
 static void f10_read_dram_ctl_register(struct amd64_pvt *pvt)
 {
-	int err = 0;
 
-	err = pci_read_config_dword(pvt->dram_f2_ctl, F10_DCTL_SEL_LOW,
-				    &pvt->dram_ctl_select_low);
-	if (err) {
-		debugf0("Reading F10_DCTL_SEL_LOW failed\n");
-	} else {
-		debugf0("DRAM_DCTL_SEL_LOW=0x%x  DctSelBaseAddr=0x%x\n",
-			pvt->dram_ctl_select_low, dct_sel_baseaddr(pvt));
+	if (!amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCTL_SEL_LOW,
+				&pvt->dram_ctl_select_low)) {
+		debugf0("F2x110 (DCTL Sel. Low): 0x%08x, "
+			"High range addresses at: 0x%x\n",
+			pvt->dram_ctl_select_low,
+			dct_sel_baseaddr(pvt));
 
-		debugf0("  DRAM DCTs are=%s DRAM Is=%s DRAM-Ctl-"
-				"sel-hi-range=%s\n",
-			(dct_ganging_enabled(pvt) ? "GANGED" : "NOT GANGED"),
-			(dct_dram_enabled(pvt) ? "Enabled"   : "Disabled"),
-			(dct_high_range_enabled(pvt) ? "Enabled" : "Disabled"));
+		debugf0("  DCT mode: %s, All DCTs on: %s\n",
+			(dct_ganging_enabled(pvt) ? "ganged" : "unganged"),
+			(dct_dram_enabled(pvt) ? "yes"   : "no"));
 
-		debugf0("  DctDatIntLv=%s MemCleared=%s DctSelIntLvAddr=0x%x\n",
-			(dct_data_intlv_enabled(pvt) ? "Enabled" : "Disabled"),
-			(dct_memory_cleared(pvt) ? "True " : "False "),
+		if (!dct_ganging_enabled(pvt))
+			debugf0("  Address range split per DCT: %s\n",
+				(dct_high_range_enabled(pvt) ? "yes" : "no"));
+
+		debugf0("  DCT data interleave for ECC: %s, "
+			"DRAM cleared since last warm reset: %s\n",
+			(dct_data_intlv_enabled(pvt) ? "enabled" : "disabled"),
+			(dct_memory_cleared(pvt) ? "yes" : "no"));
+
+		debugf0("  DCT channel interleave: %s, "
+			"DCT interleave bits selector: 0x%x\n",
+			(dct_interleave_enabled(pvt) ? "enabled" : "disabled"),
 			dct_sel_interleave_addr(pvt));
 	}
 
-	err = pci_read_config_dword(pvt->dram_f2_ctl, F10_DCTL_SEL_HIGH,
-				    &pvt->dram_ctl_select_high);
-	if (err)
-		debugf0("Reading F10_DCTL_SEL_HIGH failed\n");
+	amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCTL_SEL_HIGH,
+			   &pvt->dram_ctl_select_high);
 }
 
 /*
@@ -1706,10 +1645,11 @@
 }
 
 /*
- * This the F10h reference code from AMD to map a @sys_addr to NodeID,
- * CSROW, Channel.
+ * For reference see "2.8.5 Routing DRAM Requests" in F10 BKDG. This code maps
+ * a @sys_addr to NodeID, DCT (channel) and chip select (CSROW).
  *
- * The @sys_addr is usually an error address received from the hardware.
+ * The @sys_addr is usually an error address received from the hardware
+ * (MCX_ADDR).
  */
 static void f10_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
 				     struct err_regs *info,
@@ -1722,136 +1662,79 @@
 
 	csrow = f10_translate_sysaddr_to_cs(pvt, sys_addr, &nid, &chan);
 
-	if (csrow >= 0) {
-		error_address_to_page_and_offset(sys_addr, &page, &offset);
-
-		syndrome  = HIGH_SYNDROME(info->nbsl) << 8;
-		syndrome |= LOW_SYNDROME(info->nbsh);
-
-		/*
-		 * Is CHIPKILL on? If so, then we can attempt to use the
-		 * syndrome to isolate which channel the error was on.
-		 */
-		if (pvt->nbcfg & K8_NBCFG_CHIPKILL)
-			chan = get_channel_from_ecc_syndrome(syndrome);
-
-		if (chan >= 0) {
-			edac_mc_handle_ce(mci, page, offset, syndrome,
-					csrow, chan, EDAC_MOD_STR);
-		} else {
-			/*
-			 * Channel unknown, report all channels on this
-			 * CSROW as failed.
-			 */
-			for (chan = 0; chan < mci->csrows[csrow].nr_channels;
-								chan++) {
-					edac_mc_handle_ce(mci, page, offset,
-							syndrome,
-							csrow, chan,
-							EDAC_MOD_STR);
-			}
-		}
-
-	} else {
+	if (csrow < 0) {
 		edac_mc_handle_ce_no_info(mci, EDAC_MOD_STR);
+		return;
 	}
+
+	error_address_to_page_and_offset(sys_addr, &page, &offset);
+
+	syndrome  = HIGH_SYNDROME(info->nbsl) << 8;
+	syndrome |= LOW_SYNDROME(info->nbsh);
+
+	/*
+	 * We need the syndromes for channel detection only when we're
+	 * ganged. Otherwise @chan should already contain the channel at
+	 * this point.
+	 */
+	if (dct_ganging_enabled(pvt) && pvt->nbcfg & K8_NBCFG_CHIPKILL)
+		chan = get_channel_from_ecc_syndrome(mci, syndrome);
+
+	if (chan >= 0)
+		edac_mc_handle_ce(mci, page, offset, syndrome, csrow, chan,
+				  EDAC_MOD_STR);
+	else
+		/*
+		 * Channel unknown, report all channels on this CSROW as failed.
+		 */
+		for (chan = 0; chan < mci->csrows[csrow].nr_channels; chan++)
+			edac_mc_handle_ce(mci, page, offset, syndrome,
+					  csrow, chan, EDAC_MOD_STR);
 }
 
 /*
- * Input (@index) is the DBAM DIMM value (1 of 4) used as an index into a shift
- * table (revf_quad_ddr2_shift) which starts at 128MB DIMM size. Index of 0
- * indicates an empty DIMM slot, as reported by Hardware on empty slots.
- *
- * Normalize to 128MB by subracting 27 bit shift.
- */
-static int map_dbam_to_csrow_size(int index)
-{
-	int mega_bytes = 0;
-
-	if (index > 0 && index <= DBAM_MAX_VALUE)
-		mega_bytes = ((128 << (revf_quad_ddr2_shift[index]-27)));
-
-	return mega_bytes;
-}
-
-/*
- * debug routine to display the memory sizes of a DIMM (ganged or not) and it
+ * debug routine to display the memory sizes of all logical DIMMs and its
  * CSROWs as well
  */
-static void f10_debug_display_dimm_sizes(int ctrl, struct amd64_pvt *pvt,
-					 int ganged)
+static void amd64_debug_display_dimm_sizes(int ctrl, struct amd64_pvt *pvt)
 {
 	int dimm, size0, size1;
 	u32 dbam;
 	u32 *dcsb;
 
-	debugf1("  dbam%d: 0x%8.08x  CSROW is %s\n", ctrl,
-			ctrl ? pvt->dbam1 : pvt->dbam0,
-			ganged ? "GANGED - dbam1 not used" : "NON-GANGED");
+	if (boot_cpu_data.x86 == 0xf) {
+		/* K8 families < revF not supported yet */
+	       if (pvt->ext_model < K8_REV_F)
+			return;
+	       else
+		       WARN_ON(ctrl != 0);
+	}
+
+	debugf1("F2x%d80 (DRAM Bank Address Mapping): 0x%08x\n",
+		ctrl, ctrl ? pvt->dbam1 : pvt->dbam0);
 
 	dbam = ctrl ? pvt->dbam1 : pvt->dbam0;
 	dcsb = ctrl ? pvt->dcsb1 : pvt->dcsb0;
 
+	edac_printk(KERN_DEBUG, EDAC_MC, "DCT%d chip selects:\n", ctrl);
+
 	/* Dump memory sizes for DIMM and its CSROWs */
 	for (dimm = 0; dimm < 4; dimm++) {
 
 		size0 = 0;
 		if (dcsb[dimm*2] & K8_DCSB_CS_ENABLE)
-			size0 = map_dbam_to_csrow_size(DBAM_DIMM(dimm, dbam));
+			size0 = pvt->ops->dbam_to_cs(pvt, DBAM_DIMM(dimm, dbam));
 
 		size1 = 0;
 		if (dcsb[dimm*2 + 1] & K8_DCSB_CS_ENABLE)
-			size1 = map_dbam_to_csrow_size(DBAM_DIMM(dimm, dbam));
+			size1 = pvt->ops->dbam_to_cs(pvt, DBAM_DIMM(dimm, dbam));
 
-		debugf1("     CTRL-%d DIMM-%d=%5dMB   CSROW-%d=%5dMB "
-				"CSROW-%d=%5dMB\n",
-				ctrl,
-				dimm,
-				size0 + size1,
-				dimm * 2,
-				size0,
-				dimm * 2 + 1,
-				size1);
+		edac_printk(KERN_DEBUG, EDAC_MC, " %d: %5dMB %d: %5dMB\n",
+			    dimm * 2, size0, dimm * 2 + 1, size1);
 	}
 }
 
 /*
- * Very early hardware probe on pci_probe thread to determine if this module
- * supports the hardware.
- *
- * Return:
- *      0 for OK
- *      1 for error
- */
-static int f10_probe_valid_hardware(struct amd64_pvt *pvt)
-{
-	int ret = 0;
-
-	/*
-	 * If we are on a DDR3 machine, we don't know yet if
-	 * we support that properly at this time
-	 */
-	if ((pvt->dchr0 & F10_DCHR_Ddr3Mode) ||
-	    (pvt->dchr1 & F10_DCHR_Ddr3Mode)) {
-
-		amd64_printk(KERN_WARNING,
-			"%s() This machine is running with DDR3 memory. "
-			"This is not currently supported. "
-			"DCHR0=0x%x DCHR1=0x%x\n",
-			__func__, pvt->dchr0, pvt->dchr1);
-
-		amd64_printk(KERN_WARNING,
-			"   Contact '%s' module MAINTAINER to help add"
-			" support.\n",
-			EDAC_MOD_STR);
-
-		ret = 1;
-
-	}
-	return ret;
-}
-
-/*
  * There currently are 3 types type of MC devices for AMD Athlon/Opterons
  * (as per PCI DEVICE_IDs):
  *
@@ -1868,11 +1751,11 @@
 		.addr_f1_ctl = PCI_DEVICE_ID_AMD_K8_NB_ADDRMAP,
 		.misc_f3_ctl = PCI_DEVICE_ID_AMD_K8_NB_MISC,
 		.ops = {
-			.early_channel_count = k8_early_channel_count,
-			.get_error_address = k8_get_error_address,
-			.read_dram_base_limit = k8_read_dram_base_limit,
-			.map_sysaddr_to_csrow = k8_map_sysaddr_to_csrow,
-			.dbam_map_to_pages = k8_dbam_map_to_pages,
+			.early_channel_count	= k8_early_channel_count,
+			.get_error_address	= k8_get_error_address,
+			.read_dram_base_limit	= k8_read_dram_base_limit,
+			.map_sysaddr_to_csrow	= k8_map_sysaddr_to_csrow,
+			.dbam_to_cs		= k8_dbam_to_chip_select,
 		}
 	},
 	[F10_CPUS] = {
@@ -1880,13 +1763,12 @@
 		.addr_f1_ctl = PCI_DEVICE_ID_AMD_10H_NB_MAP,
 		.misc_f3_ctl = PCI_DEVICE_ID_AMD_10H_NB_MISC,
 		.ops = {
-			.probe_valid_hardware = f10_probe_valid_hardware,
-			.early_channel_count = f10_early_channel_count,
-			.get_error_address = f10_get_error_address,
-			.read_dram_base_limit = f10_read_dram_base_limit,
-			.read_dram_ctl_register = f10_read_dram_ctl_register,
-			.map_sysaddr_to_csrow = f10_map_sysaddr_to_csrow,
-			.dbam_map_to_pages = f10_dbam_map_to_pages,
+			.early_channel_count	= f10_early_channel_count,
+			.get_error_address	= f10_get_error_address,
+			.read_dram_base_limit	= f10_read_dram_base_limit,
+			.read_dram_ctl_register	= f10_read_dram_ctl_register,
+			.map_sysaddr_to_csrow	= f10_map_sysaddr_to_csrow,
+			.dbam_to_cs		= f10_dbam_to_chip_select,
 		}
 	},
 	[F11_CPUS] = {
@@ -1894,13 +1776,12 @@
 		.addr_f1_ctl = PCI_DEVICE_ID_AMD_11H_NB_MAP,
 		.misc_f3_ctl = PCI_DEVICE_ID_AMD_11H_NB_MISC,
 		.ops = {
-			.probe_valid_hardware = f10_probe_valid_hardware,
-			.early_channel_count = f10_early_channel_count,
-			.get_error_address = f10_get_error_address,
-			.read_dram_base_limit = f10_read_dram_base_limit,
-			.read_dram_ctl_register = f10_read_dram_ctl_register,
-			.map_sysaddr_to_csrow = f10_map_sysaddr_to_csrow,
-			.dbam_map_to_pages = f10_dbam_map_to_pages,
+			.early_channel_count	= f10_early_channel_count,
+			.get_error_address	= f10_get_error_address,
+			.read_dram_base_limit	= f10_read_dram_base_limit,
+			.read_dram_ctl_register	= f10_read_dram_ctl_register,
+			.map_sysaddr_to_csrow	= f10_map_sysaddr_to_csrow,
+			.dbam_to_cs		= f10_dbam_to_chip_select,
 		}
 	},
 };
@@ -1923,142 +1804,170 @@
 }
 
 /*
- * syndrome mapping table for ECC ChipKill devices
+ * These are tables of eigenvectors (one per line) which can be used for the
+ * construction of the syndrome tables. The modified syndrome search algorithm
+ * uses those to find the symbol in error and thus the DIMM.
  *
- * The comment in each row is the token (nibble) number that is in error.
- * The least significant nibble of the syndrome is the mask for the bits
- * that are in error (need to be toggled) for the particular nibble.
- *
- * Each row contains 16 entries.
- * The first entry (0th) is the channel number for that row of syndromes.
- * The remaining 15 entries are the syndromes for the respective Error
- * bit mask index.
- *
- * 1st index entry is 0x0001 mask, indicating that the rightmost bit is the
- * bit in error.
- * The 2nd index entry is 0x0010 that the second bit is damaged.
- * The 3rd index entry is 0x0011 indicating that the rightmost 2 bits
- * are damaged.
- * Thus so on until index 15, 0x1111, whose entry has the syndrome
- * indicating that all 4 bits are damaged.
- *
- * A search is performed on this table looking for a given syndrome.
- *
- * See the AMD documentation for ECC syndromes. This ECC table is valid
- * across all the versions of the AMD64 processors.
- *
- * A fast lookup is to use the LAST four bits of the 16-bit syndrome as a
- * COLUMN index, then search all ROWS of that column, looking for a match
- * with the input syndrome. The ROW value will be the token number.
- *
- * The 0'th entry on that row, can be returned as the CHANNEL (0 or 1) of this
- * error.
+ * Algorithm courtesy of Ross LaFetra from AMD.
  */
-#define NUMBER_ECC_ROWS  36
-static const unsigned short ecc_chipkill_syndromes[NUMBER_ECC_ROWS][16] = {
-	/* Channel 0 syndromes */
-	{/*0*/  0, 0xe821, 0x7c32, 0x9413, 0xbb44, 0x5365, 0xc776, 0x2f57,
-	   0xdd88, 0x35a9, 0xa1ba, 0x499b, 0x66cc, 0x8eed, 0x1afe, 0xf2df },
-	{/*1*/  0, 0x5d31, 0xa612, 0xfb23, 0x9584, 0xc8b5, 0x3396, 0x6ea7,
-	   0xeac8, 0xb7f9, 0x4cda, 0x11eb, 0x7f4c, 0x227d, 0xd95e, 0x846f },
-	{/*2*/  0, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
-	   0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f },
-	{/*3*/  0, 0x2021, 0x3032, 0x1013, 0x4044, 0x6065, 0x7076, 0x5057,
-	   0x8088, 0xa0a9, 0xb0ba, 0x909b, 0xc0cc, 0xe0ed, 0xf0fe, 0xd0df },
-	{/*4*/  0, 0x5041, 0xa082, 0xf0c3, 0x9054, 0xc015, 0x30d6, 0x6097,
-	   0xe0a8, 0xb0e9, 0x402a, 0x106b, 0x70fc, 0x20bd, 0xd07e, 0x803f },
-	{/*5*/  0, 0xbe21, 0xd732, 0x6913, 0x2144, 0x9f65, 0xf676, 0x4857,
-	   0x3288, 0x8ca9, 0xe5ba, 0x5b9b, 0x13cc, 0xaded, 0xc4fe, 0x7adf },
-	{/*6*/  0, 0x4951, 0x8ea2, 0xc7f3, 0x5394, 0x1ac5, 0xdd36, 0x9467,
-	   0xa1e8, 0xe8b9, 0x2f4a, 0x661b, 0xf27c, 0xbb2d, 0x7cde, 0x358f },
-	{/*7*/  0, 0x74e1, 0x9872, 0xec93, 0xd6b4, 0xa255, 0x4ec6, 0x3a27,
-	   0x6bd8, 0x1f39, 0xf3aa, 0x874b, 0xbd6c, 0xc98d, 0x251e, 0x51ff },
-	{/*8*/  0, 0x15c1, 0x2a42, 0x3f83, 0xcef4, 0xdb35, 0xe4b6, 0xf177,
-	   0x4758, 0x5299, 0x6d1a, 0x78db, 0x89ac, 0x9c6d, 0xa3ee, 0xb62f },
-	{/*9*/  0, 0x3d01, 0x1602, 0x2b03, 0x8504, 0xb805, 0x9306, 0xae07,
-	   0xca08, 0xf709, 0xdc0a, 0xe10b, 0x4f0c, 0x720d, 0x590e, 0x640f },
-	{/*a*/  0, 0x9801, 0xec02, 0x7403, 0x6b04, 0xf305, 0x8706, 0x1f07,
-	   0xbd08, 0x2509, 0x510a, 0xc90b, 0xd60c, 0x4e0d, 0x3a0e, 0xa20f },
-	{/*b*/  0, 0xd131, 0x6212, 0xb323, 0x3884, 0xe9b5, 0x5a96, 0x8ba7,
-	   0x1cc8, 0xcdf9, 0x7eda, 0xafeb, 0x244c, 0xf57d, 0x465e, 0x976f },
-	{/*c*/  0, 0xe1d1, 0x7262, 0x93b3, 0xb834, 0x59e5, 0xca56, 0x2b87,
-	   0xdc18, 0x3dc9, 0xae7a, 0x4fab, 0x542c, 0x85fd, 0x164e, 0xf79f },
-	{/*d*/  0, 0x6051, 0xb0a2, 0xd0f3, 0x1094, 0x70c5, 0xa036, 0xc067,
-	   0x20e8, 0x40b9, 0x904a, 0x601b, 0x307c, 0x502d, 0x80de, 0xe08f },
-	{/*e*/  0, 0xa4c1, 0xf842, 0x5c83, 0xe6f4, 0x4235, 0x1eb6, 0xba77,
-	   0x7b58, 0xdf99, 0x831a, 0x27db, 0x9dac, 0x396d, 0x65ee, 0xc12f },
-	{/*f*/  0, 0x11c1, 0x2242, 0x3383, 0xc8f4, 0xd935, 0xeab6, 0xfb77,
-	   0x4c58, 0x5d99, 0x6e1a, 0x7fdb, 0x84ac, 0x956d, 0xa6ee, 0xb72f },
-
-	/* Channel 1 syndromes */
-	{/*10*/ 1, 0x45d1, 0x8a62, 0xcfb3, 0x5e34, 0x1be5, 0xd456, 0x9187,
-	   0xa718, 0xe2c9, 0x2d7a, 0x68ab, 0xf92c, 0xbcfd, 0x734e, 0x369f },
-	{/*11*/ 1, 0x63e1, 0xb172, 0xd293, 0x14b4, 0x7755, 0xa5c6, 0xc627,
-	   0x28d8, 0x4b39, 0x99aa, 0xfa4b, 0x3c6c, 0x5f8d, 0x8d1e, 0xeeff },
-	{/*12*/ 1, 0xb741, 0xd982, 0x6ec3, 0x2254, 0x9515, 0xfbd6, 0x4c97,
-	   0x33a8, 0x84e9, 0xea2a, 0x5d6b, 0x11fc, 0xa6bd, 0xc87e, 0x7f3f },
-	{/*13*/ 1, 0xdd41, 0x6682, 0xbbc3, 0x3554, 0xe815, 0x53d6, 0xce97,
-	   0x1aa8, 0xc7e9, 0x7c2a, 0xa1fb, 0x2ffc, 0xf2bd, 0x497e, 0x943f },
-	{/*14*/ 1, 0x2bd1, 0x3d62, 0x16b3, 0x4f34, 0x64e5, 0x7256, 0x5987,
-	   0x8518, 0xaec9, 0xb87a, 0x93ab, 0xca2c, 0xe1fd, 0xf74e, 0xdc9f },
-	{/*15*/ 1, 0x83c1, 0xc142, 0x4283, 0xa4f4, 0x2735, 0x65b6, 0xe677,
-	   0xf858, 0x7b99, 0x391a, 0xbadb, 0x5cac, 0xdf6d, 0x9dee, 0x1e2f },
-	{/*16*/ 1, 0x8fd1, 0xc562, 0x4ab3, 0xa934, 0x26e5, 0x6c56, 0xe387,
-	   0xfe18, 0x71c9, 0x3b7a, 0xb4ab, 0x572c, 0xd8fd, 0x924e, 0x1d9f },
-	{/*17*/ 1, 0x4791, 0x89e2, 0xce73, 0x5264, 0x15f5, 0xdb86, 0x9c17,
-	   0xa3b8, 0xe429, 0x2a5a, 0x6dcb, 0xf1dc, 0xb64d, 0x783e, 0x3faf },
-	{/*18*/ 1, 0x5781, 0xa9c2, 0xfe43, 0x92a4, 0xc525, 0x3b66, 0x6ce7,
-	   0xe3f8, 0xb479, 0x4a3a, 0x1dbb, 0x715c, 0x26dd, 0xd89e, 0x8f1f },
-	{/*19*/ 1, 0xbf41, 0xd582, 0x6ac3, 0x2954, 0x9615, 0xfcd6, 0x4397,
-	   0x3ea8, 0x81e9, 0xeb2a, 0x546b, 0x17fc, 0xa8bd, 0xc27e, 0x7d3f },
-	{/*1a*/ 1, 0x9891, 0xe1e2, 0x7273, 0x6464, 0xf7f5, 0x8586, 0x1617,
-	   0xb8b8, 0x2b29, 0x595a, 0xcacb, 0xdcdc, 0x4f4d, 0x3d3e, 0xaeaf },
-	{/*1b*/ 1, 0xcce1, 0x4472, 0x8893, 0xfdb4, 0x3f55, 0xb9c6, 0x7527,
-	   0x56d8, 0x9a39, 0x12aa, 0xde4b, 0xab6c, 0x678d, 0xef1e, 0x23ff },
-	{/*1c*/ 1, 0xa761, 0xf9b2, 0x5ed3, 0xe214, 0x4575, 0x1ba6, 0xbcc7,
-	   0x7328, 0xd449, 0x8a9a, 0x2dfb, 0x913c, 0x365d, 0x688e, 0xcfef },
-	{/*1d*/ 1, 0xff61, 0x55b2, 0xaad3, 0x7914, 0x8675, 0x2ca6, 0xd3c7,
-	   0x9e28, 0x6149, 0xcb9a, 0x34fb, 0xe73c, 0x185d, 0xb28e, 0x4def },
-	{/*1e*/ 1, 0x5451, 0xa8a2, 0xfcf3, 0x9694, 0xc2c5, 0x3e36, 0x6a67,
-	   0xebe8, 0xbfb9, 0x434a, 0x171b, 0x7d7c, 0x292d, 0xd5de, 0x818f },
-	{/*1f*/ 1, 0x6fc1, 0xb542, 0xda83, 0x19f4, 0x7635, 0xacb6, 0xc377,
-	   0x2e58, 0x4199, 0x9b1a, 0xf4db, 0x37ac, 0x586d, 0x82ee, 0xed2f },
-
-	/* ECC bits are also in the set of tokens and they too can go bad
-	 * first 2 cover channel 0, while the second 2 cover channel 1
-	 */
-	{/*20*/ 0, 0xbe01, 0xd702, 0x6903, 0x2104, 0x9f05, 0xf606, 0x4807,
-	   0x3208, 0x8c09, 0xe50a, 0x5b0b, 0x130c, 0xad0d, 0xc40e, 0x7a0f },
-	{/*21*/ 0, 0x4101, 0x8202, 0xc303, 0x5804, 0x1905, 0xda06, 0x9b07,
-	   0xac08, 0xed09, 0x2e0a, 0x6f0b, 0x640c, 0xb50d, 0x760e, 0x370f },
-	{/*22*/ 1, 0xc441, 0x4882, 0x8cc3, 0xf654, 0x3215, 0xbed6, 0x7a97,
-	   0x5ba8, 0x9fe9, 0x132a, 0xd76b, 0xadfc, 0x69bd, 0xe57e, 0x213f },
-	{/*23*/ 1, 0x7621, 0x9b32, 0xed13, 0xda44, 0xac65, 0x4176, 0x3757,
-	   0x6f88, 0x19a9, 0xf4ba, 0x829b, 0xb5cc, 0xc3ed, 0x2efe, 0x58df }
+static u16 x4_vectors[] = {
+	0x2f57, 0x1afe, 0x66cc, 0xdd88,
+	0x11eb, 0x3396, 0x7f4c, 0xeac8,
+	0x0001, 0x0002, 0x0004, 0x0008,
+	0x1013, 0x3032, 0x4044, 0x8088,
+	0x106b, 0x30d6, 0x70fc, 0xe0a8,
+	0x4857, 0xc4fe, 0x13cc, 0x3288,
+	0x1ac5, 0x2f4a, 0x5394, 0xa1e8,
+	0x1f39, 0x251e, 0xbd6c, 0x6bd8,
+	0x15c1, 0x2a42, 0x89ac, 0x4758,
+	0x2b03, 0x1602, 0x4f0c, 0xca08,
+	0x1f07, 0x3a0e, 0x6b04, 0xbd08,
+	0x8ba7, 0x465e, 0x244c, 0x1cc8,
+	0x2b87, 0x164e, 0x642c, 0xdc18,
+	0x40b9, 0x80de, 0x1094, 0x20e8,
+	0x27db, 0x1eb6, 0x9dac, 0x7b58,
+	0x11c1, 0x2242, 0x84ac, 0x4c58,
+	0x1be5, 0x2d7a, 0x5e34, 0xa718,
+	0x4b39, 0x8d1e, 0x14b4, 0x28d8,
+	0x4c97, 0xc87e, 0x11fc, 0x33a8,
+	0x8e97, 0x497e, 0x2ffc, 0x1aa8,
+	0x16b3, 0x3d62, 0x4f34, 0x8518,
+	0x1e2f, 0x391a, 0x5cac, 0xf858,
+	0x1d9f, 0x3b7a, 0x572c, 0xfe18,
+	0x15f5, 0x2a5a, 0x5264, 0xa3b8,
+	0x1dbb, 0x3b66, 0x715c, 0xe3f8,
+	0x4397, 0xc27e, 0x17fc, 0x3ea8,
+	0x1617, 0x3d3e, 0x6464, 0xb8b8,
+	0x23ff, 0x12aa, 0xab6c, 0x56d8,
+	0x2dfb, 0x1ba6, 0x913c, 0x7328,
+	0x185d, 0x2ca6, 0x7914, 0x9e28,
+	0x171b, 0x3e36, 0x7d7c, 0xebe8,
+	0x4199, 0x82ee, 0x19f4, 0x2e58,
+	0x4807, 0xc40e, 0x130c, 0x3208,
+	0x1905, 0x2e0a, 0x5804, 0xac08,
+	0x213f, 0x132a, 0xadfc, 0x5ba8,
+	0x19a9, 0x2efe, 0xb5cc, 0x6f88,
 };
 
-/*
- * Given the syndrome argument, scan each of the channel tables for a syndrome
- * match. Depending on which table it is found, return the channel number.
- */
-static int get_channel_from_ecc_syndrome(unsigned short syndrome)
+static u16 x8_vectors[] = {
+	0x0145, 0x028a, 0x2374, 0x43c8, 0xa1f0, 0x0520, 0x0a40, 0x1480,
+	0x0211, 0x0422, 0x0844, 0x1088, 0x01b0, 0x44e0, 0x23c0, 0xed80,
+	0x1011, 0x0116, 0x022c, 0x0458, 0x08b0, 0x8c60, 0x2740, 0x4e80,
+	0x0411, 0x0822, 0x1044, 0x0158, 0x02b0, 0x2360, 0x46c0, 0xab80,
+	0x0811, 0x1022, 0x012c, 0x0258, 0x04b0, 0x4660, 0x8cc0, 0x2780,
+	0x2071, 0x40e2, 0xa0c4, 0x0108, 0x0210, 0x0420, 0x0840, 0x1080,
+	0x4071, 0x80e2, 0x0104, 0x0208, 0x0410, 0x0820, 0x1040, 0x2080,
+	0x8071, 0x0102, 0x0204, 0x0408, 0x0810, 0x1020, 0x2040, 0x4080,
+	0x019d, 0x03d6, 0x136c, 0x2198, 0x50b0, 0xb2e0, 0x0740, 0x0e80,
+	0x0189, 0x03ea, 0x072c, 0x0e58, 0x1cb0, 0x56e0, 0x37c0, 0xf580,
+	0x01fd, 0x0376, 0x06ec, 0x0bb8, 0x1110, 0x2220, 0x4440, 0x8880,
+	0x0163, 0x02c6, 0x1104, 0x0758, 0x0eb0, 0x2be0, 0x6140, 0xc280,
+	0x02fd, 0x01c6, 0x0b5c, 0x1108, 0x07b0, 0x25a0, 0x8840, 0x6180,
+	0x0801, 0x012e, 0x025c, 0x04b8, 0x1370, 0x26e0, 0x57c0, 0xb580,
+	0x0401, 0x0802, 0x015c, 0x02b8, 0x22b0, 0x13e0, 0x7140, 0xe280,
+	0x0201, 0x0402, 0x0804, 0x01b8, 0x11b0, 0x31a0, 0x8040, 0x7180,
+	0x0101, 0x0202, 0x0404, 0x0808, 0x1010, 0x2020, 0x4040, 0x8080,
+	0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
+	0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
+};
+
+static int decode_syndrome(u16 syndrome, u16 *vectors, int num_vecs,
+				 int v_dim)
 {
-	int row;
-	int column;
+	unsigned int i, err_sym;
 
-	/* Determine column to scan */
-	column = syndrome & 0xF;
+	for (err_sym = 0; err_sym < num_vecs / v_dim; err_sym++) {
+		u16 s = syndrome;
+		int v_idx =  err_sym * v_dim;
+		int v_end = (err_sym + 1) * v_dim;
 
-	/* Scan all rows, looking for syndrome, or end of table */
-	for (row = 0; row < NUMBER_ECC_ROWS; row++) {
-		if (ecc_chipkill_syndromes[row][column] == syndrome)
-			return ecc_chipkill_syndromes[row][0];
+		/* walk over all 16 bits of the syndrome */
+		for (i = 1; i < (1U << 16); i <<= 1) {
+
+			/* if bit is set in that eigenvector... */
+			if (v_idx < v_end && vectors[v_idx] & i) {
+				u16 ev_comp = vectors[v_idx++];
+
+				/* ... and bit set in the modified syndrome, */
+				if (s & i) {
+					/* remove it. */
+					s ^= ev_comp;
+
+					if (!s)
+						return err_sym;
+				}
+
+			} else if (s & i)
+				/* can't get to zero, move to next symbol */
+				break;
+		}
 	}
 
 	debugf0("syndrome(%x) not found\n", syndrome);
 	return -1;
 }
 
+static int map_err_sym_to_channel(int err_sym, int sym_size)
+{
+	if (sym_size == 4)
+		switch (err_sym) {
+		case 0x20:
+		case 0x21:
+			return 0;
+			break;
+		case 0x22:
+		case 0x23:
+			return 1;
+			break;
+		default:
+			return err_sym >> 4;
+			break;
+		}
+	/* x8 symbols */
+	else
+		switch (err_sym) {
+		/* imaginary bits not in a DIMM */
+		case 0x10:
+			WARN(1, KERN_ERR "Invalid error symbol: 0x%x\n",
+					  err_sym);
+			return -1;
+			break;
+
+		case 0x11:
+			return 0;
+			break;
+		case 0x12:
+			return 1;
+			break;
+		default:
+			return err_sym >> 3;
+			break;
+		}
+	return -1;
+}
+
+static int get_channel_from_ecc_syndrome(struct mem_ctl_info *mci, u16 syndrome)
+{
+	struct amd64_pvt *pvt = mci->pvt_info;
+	u32 value = 0;
+	int err_sym = 0;
+
+	amd64_read_pci_cfg(pvt->misc_f3_ctl, 0x180, &value);
+
+	/* F3x180[EccSymbolSize]=1, x8 symbols */
+	if (boot_cpu_data.x86 == 0x10 &&
+	    boot_cpu_data.x86_model > 7 &&
+	    value & BIT(25)) {
+		err_sym = decode_syndrome(syndrome, x8_vectors,
+					  ARRAY_SIZE(x8_vectors), 8);
+		return map_err_sym_to_channel(err_sym, 8);
+	} else {
+		err_sym = decode_syndrome(syndrome, x4_vectors,
+					  ARRAY_SIZE(x4_vectors), 4);
+		return map_err_sym_to_channel(err_sym, 4);
+	}
+}
+
 /*
  * Check for valid error in the NB Status High register. If so, proceed to read
  * NB Status Low, NB Address Low and NB Address High registers and store data
@@ -2073,40 +1982,24 @@
 {
 	struct amd64_pvt *pvt;
 	struct pci_dev *misc_f3_ctl;
-	int err = 0;
 
 	pvt = mci->pvt_info;
 	misc_f3_ctl = pvt->misc_f3_ctl;
 
-	err = pci_read_config_dword(misc_f3_ctl, K8_NBSH, &regs->nbsh);
-	if (err)
-		goto err_reg;
+	if (amd64_read_pci_cfg(misc_f3_ctl, K8_NBSH, &regs->nbsh))
+		return 0;
 
 	if (!(regs->nbsh & K8_NBSH_VALID_BIT))
 		return 0;
 
 	/* valid error, read remaining error information registers */
-	err = pci_read_config_dword(misc_f3_ctl, K8_NBSL, &regs->nbsl);
-	if (err)
-		goto err_reg;
-
-	err = pci_read_config_dword(misc_f3_ctl, K8_NBEAL, &regs->nbeal);
-	if (err)
-		goto err_reg;
-
-	err = pci_read_config_dword(misc_f3_ctl, K8_NBEAH, &regs->nbeah);
-	if (err)
-		goto err_reg;
-
-	err = pci_read_config_dword(misc_f3_ctl, K8_NBCFG, &regs->nbcfg);
-	if (err)
-		goto err_reg;
+	if (amd64_read_pci_cfg(misc_f3_ctl, K8_NBSL, &regs->nbsl) ||
+	    amd64_read_pci_cfg(misc_f3_ctl, K8_NBEAL, &regs->nbeal) ||
+	    amd64_read_pci_cfg(misc_f3_ctl, K8_NBEAH, &regs->nbeah) ||
+	    amd64_read_pci_cfg(misc_f3_ctl, K8_NBCFG, &regs->nbcfg))
+		return 0;
 
 	return 1;
-
-err_reg:
-	debugf0("Reading error info register failed\n");
-	return 0;
 }
 
 /*
@@ -2184,7 +2077,7 @@
 			    struct err_regs *info)
 {
 	struct amd64_pvt *pvt = mci->pvt_info;
-	u64 SystemAddress;
+	u64 sys_addr;
 
 	/* Ensure that the Error Address is VALID */
 	if ((info->nbsh & K8_NBSH_VALID_ERROR_ADDR) == 0) {
@@ -2194,22 +2087,23 @@
 		return;
 	}
 
-	SystemAddress = extract_error_address(mci, info);
+	sys_addr = pvt->ops->get_error_address(mci, info);
 
 	amd64_mc_printk(mci, KERN_ERR,
-		"CE ERROR_ADDRESS= 0x%llx\n", SystemAddress);
+		"CE ERROR_ADDRESS= 0x%llx\n", sys_addr);
 
-	pvt->ops->map_sysaddr_to_csrow(mci, info, SystemAddress);
+	pvt->ops->map_sysaddr_to_csrow(mci, info, sys_addr);
 }
 
 /* Handle any Un-correctable Errors (UEs) */
 static void amd64_handle_ue(struct mem_ctl_info *mci,
 			    struct err_regs *info)
 {
-	int csrow;
-	u64 SystemAddress;
-	u32 page, offset;
+	struct amd64_pvt *pvt = mci->pvt_info;
 	struct mem_ctl_info *log_mci, *src_mci = NULL;
+	int csrow;
+	u64 sys_addr;
+	u32 page, offset;
 
 	log_mci = mci;
 
@@ -2220,31 +2114,31 @@
 		return;
 	}
 
-	SystemAddress = extract_error_address(mci, info);
+	sys_addr = pvt->ops->get_error_address(mci, info);
 
 	/*
 	 * Find out which node the error address belongs to. This may be
 	 * different from the node that detected the error.
 	 */
-	src_mci = find_mc_by_sys_addr(mci, SystemAddress);
+	src_mci = find_mc_by_sys_addr(mci, sys_addr);
 	if (!src_mci) {
 		amd64_mc_printk(mci, KERN_CRIT,
 			"ERROR ADDRESS (0x%lx) value NOT mapped to a MC\n",
-			(unsigned long)SystemAddress);
+			(unsigned long)sys_addr);
 		edac_mc_handle_ue_no_info(log_mci, EDAC_MOD_STR);
 		return;
 	}
 
 	log_mci = src_mci;
 
-	csrow = sys_addr_to_csrow(log_mci, SystemAddress);
+	csrow = sys_addr_to_csrow(log_mci, sys_addr);
 	if (csrow < 0) {
 		amd64_mc_printk(mci, KERN_CRIT,
 			"ERROR_ADDRESS (0x%lx) value NOT mapped to 'csrow'\n",
-			(unsigned long)SystemAddress);
+			(unsigned long)sys_addr);
 		edac_mc_handle_ue_no_info(log_mci, EDAC_MOD_STR);
 	} else {
-		error_address_to_page_and_offset(SystemAddress, &page, &offset);
+		error_address_to_page_and_offset(sys_addr, &page, &offset);
 		edac_mc_handle_ue(log_mci, page, offset, csrow, EDAC_MOD_STR);
 	}
 }
@@ -2384,30 +2278,26 @@
 static void amd64_read_mc_registers(struct amd64_pvt *pvt)
 {
 	u64 msr_val;
-	int dram, err = 0;
+	int dram;
 
 	/*
 	 * Retrieve TOP_MEM and TOP_MEM2; no masking off of reserved bits since
 	 * those are Read-As-Zero
 	 */
-	rdmsrl(MSR_K8_TOP_MEM1, msr_val);
-	pvt->top_mem = msr_val >> 23;
-	debugf0("  TOP_MEM=0x%08llx\n", pvt->top_mem);
+	rdmsrl(MSR_K8_TOP_MEM1, pvt->top_mem);
+	debugf0("  TOP_MEM:  0x%016llx\n", pvt->top_mem);
 
 	/* check first whether TOP_MEM2 is enabled */
 	rdmsrl(MSR_K8_SYSCFG, msr_val);
 	if (msr_val & (1U << 21)) {
-		rdmsrl(MSR_K8_TOP_MEM2, msr_val);
-		pvt->top_mem2 = msr_val >> 23;
-		debugf0("  TOP_MEM2=0x%08llx\n", pvt->top_mem2);
+		rdmsrl(MSR_K8_TOP_MEM2, pvt->top_mem2);
+		debugf0("  TOP_MEM2: 0x%016llx\n", pvt->top_mem2);
 	} else
 		debugf0("  TOP_MEM2 disabled.\n");
 
 	amd64_cpu_display_info(pvt);
 
-	err = pci_read_config_dword(pvt->misc_f3_ctl, K8_NBCAP, &pvt->nbcap);
-	if (err)
-		goto err_reg;
+	amd64_read_pci_cfg(pvt->misc_f3_ctl, K8_NBCAP, &pvt->nbcap);
 
 	if (pvt->ops->read_dram_ctl_register)
 		pvt->ops->read_dram_ctl_register(pvt);
@@ -2425,13 +2315,12 @@
 		 * debug output block away.
 		 */
 		if (pvt->dram_rw_en[dram] != 0) {
-			debugf1("  DRAM_BASE[%d]: 0x%8.08x-%8.08x "
-				"DRAM_LIMIT:  0x%8.08x-%8.08x\n",
+			debugf1("  DRAM-BASE[%d]: 0x%016llx "
+				"DRAM-LIMIT:  0x%016llx\n",
 				dram,
-				(u32)(pvt->dram_base[dram] >> 32),
-				(u32)(pvt->dram_base[dram] & 0xFFFFFFFF),
-				(u32)(pvt->dram_limit[dram] >> 32),
-				(u32)(pvt->dram_limit[dram] & 0xFFFFFFFF));
+				pvt->dram_base[dram],
+				pvt->dram_limit[dram]);
+
 			debugf1("        IntlvEn=%s %s %s "
 				"IntlvSel=%d DstNode=%d\n",
 				pvt->dram_IntlvEn[dram] ?
@@ -2445,44 +2334,20 @@
 
 	amd64_read_dct_base_mask(pvt);
 
-	err = pci_read_config_dword(pvt->addr_f1_ctl, K8_DHAR, &pvt->dhar);
-	if (err)
-		goto err_reg;
-
+	amd64_read_pci_cfg(pvt->addr_f1_ctl, K8_DHAR, &pvt->dhar);
 	amd64_read_dbam_reg(pvt);
 
-	err = pci_read_config_dword(pvt->misc_f3_ctl,
-				F10_ONLINE_SPARE, &pvt->online_spare);
-	if (err)
-		goto err_reg;
+	amd64_read_pci_cfg(pvt->misc_f3_ctl,
+			   F10_ONLINE_SPARE, &pvt->online_spare);
 
-	err = pci_read_config_dword(pvt->dram_f2_ctl, F10_DCLR_0, &pvt->dclr0);
-	if (err)
-		goto err_reg;
-
-	err = pci_read_config_dword(pvt->dram_f2_ctl, F10_DCHR_0, &pvt->dchr0);
-	if (err)
-		goto err_reg;
+	amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCLR_0, &pvt->dclr0);
+	amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCHR_0, &pvt->dchr0);
 
 	if (!dct_ganging_enabled(pvt)) {
-		err = pci_read_config_dword(pvt->dram_f2_ctl, F10_DCLR_1,
-						&pvt->dclr1);
-		if (err)
-			goto err_reg;
-
-		err = pci_read_config_dword(pvt->dram_f2_ctl, F10_DCHR_1,
-						&pvt->dchr1);
-		if (err)
-			goto err_reg;
+		amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCLR_1, &pvt->dclr1);
+		amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCHR_1, &pvt->dchr1);
 	}
-
 	amd64_dump_misc_regs(pvt);
-
-	return;
-
-err_reg:
-	debugf0("Reading an MC register failed\n");
-
 }
 
 /*
@@ -2521,7 +2386,7 @@
  */
 static u32 amd64_csrow_nr_pages(int csrow_nr, struct amd64_pvt *pvt)
 {
-	u32 dram_map, nr_pages;
+	u32 cs_mode, nr_pages;
 
 	/*
 	 * The math on this doesn't look right on the surface because x/2*4 can
@@ -2530,9 +2395,9 @@
 	 * number of bits to shift the DBAM register to extract the proper CSROW
 	 * field.
 	 */
-	dram_map = (pvt->dbam0 >> ((csrow_nr / 2) * 4)) & 0xF;
+	cs_mode = (pvt->dbam0 >> ((csrow_nr / 2) * 4)) & 0xF;
 
-	nr_pages = pvt->ops->dbam_map_to_pages(pvt, dram_map);
+	nr_pages = pvt->ops->dbam_to_cs(pvt, cs_mode) << (20 - PAGE_SHIFT);
 
 	/*
 	 * If dual channel then double the memory size of single channel.
@@ -2540,7 +2405,7 @@
 	 */
 	nr_pages <<= (pvt->channel_count - 1);
 
-	debugf0("  (csrow=%d) DBAM map index= %d\n", csrow_nr, dram_map);
+	debugf0("  (csrow=%d) DBAM map index= %d\n", csrow_nr, cs_mode);
 	debugf0("    nr_pages= %u  channel-count = %d\n",
 		nr_pages, pvt->channel_count);
 
@@ -2556,13 +2421,11 @@
 	struct csrow_info *csrow;
 	struct amd64_pvt *pvt;
 	u64 input_addr_min, input_addr_max, sys_addr;
-	int i, err = 0, empty = 1;
+	int i, empty = 1;
 
 	pvt = mci->pvt_info;
 
-	err = pci_read_config_dword(pvt->misc_f3_ctl, K8_NBCFG, &pvt->nbcfg);
-	if (err)
-		debugf0("Reading K8_NBCFG failed\n");
+	amd64_read_pci_cfg(pvt->misc_f3_ctl, K8_NBCFG, &pvt->nbcfg);
 
 	debugf0("NBCFG= 0x%x  CHIPKILL= %s DRAM ECC= %s\n", pvt->nbcfg,
 		(pvt->nbcfg & K8_NBCFG_CHIPKILL) ? "Enabled" : "Disabled",
@@ -2618,6 +2481,109 @@
 	return empty;
 }
 
+/* get all cores on this DCT */
+static void get_cpus_on_this_dct_cpumask(struct cpumask *mask, int nid)
+{
+	int cpu;
+
+	for_each_online_cpu(cpu)
+		if (amd_get_nb_id(cpu) == nid)
+			cpumask_set_cpu(cpu, mask);
+}
+
+/* check MCG_CTL on all the cpus on this node */
+static bool amd64_nb_mce_bank_enabled_on_node(int nid)
+{
+	cpumask_var_t mask;
+	struct msr *msrs;
+	int cpu, nbe, idx = 0;
+	bool ret = false;
+
+	if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) {
+		amd64_printk(KERN_WARNING, "%s: error allocating mask\n",
+			     __func__);
+		return false;
+	}
+
+	get_cpus_on_this_dct_cpumask(mask, nid);
+
+	msrs = kzalloc(sizeof(struct msr) * cpumask_weight(mask), GFP_KERNEL);
+	if (!msrs) {
+		amd64_printk(KERN_WARNING, "%s: error allocating msrs\n",
+			      __func__);
+		free_cpumask_var(mask);
+		 return false;
+	}
+
+	rdmsr_on_cpus(mask, MSR_IA32_MCG_CTL, msrs);
+
+	for_each_cpu(cpu, mask) {
+		nbe = msrs[idx].l & K8_MSR_MCGCTL_NBE;
+
+		debugf0("core: %u, MCG_CTL: 0x%llx, NB MSR is %s\n",
+			cpu, msrs[idx].q,
+			(nbe ? "enabled" : "disabled"));
+
+		if (!nbe)
+			goto out;
+
+		idx++;
+	}
+	ret = true;
+
+out:
+	kfree(msrs);
+	free_cpumask_var(mask);
+	return ret;
+}
+
+static int amd64_toggle_ecc_err_reporting(struct amd64_pvt *pvt, bool on)
+{
+	cpumask_var_t cmask;
+	struct msr *msrs = NULL;
+	int cpu, idx = 0;
+
+	if (!zalloc_cpumask_var(&cmask, GFP_KERNEL)) {
+		amd64_printk(KERN_WARNING, "%s: error allocating mask\n",
+			     __func__);
+		return false;
+	}
+
+	get_cpus_on_this_dct_cpumask(cmask, pvt->mc_node_id);
+
+	msrs = kzalloc(sizeof(struct msr) * cpumask_weight(cmask), GFP_KERNEL);
+	if (!msrs) {
+		amd64_printk(KERN_WARNING, "%s: error allocating msrs\n",
+			     __func__);
+		return -ENOMEM;
+	}
+
+	rdmsr_on_cpus(cmask, MSR_IA32_MCG_CTL, msrs);
+
+	for_each_cpu(cpu, cmask) {
+
+		if (on) {
+			if (msrs[idx].l & K8_MSR_MCGCTL_NBE)
+				pvt->flags.ecc_report = 1;
+
+			msrs[idx].l |= K8_MSR_MCGCTL_NBE;
+		} else {
+			/*
+			 * Turn off ECC reporting only when it was off before
+			 */
+			if (!pvt->flags.ecc_report)
+				msrs[idx].l &= ~K8_MSR_MCGCTL_NBE;
+		}
+		idx++;
+	}
+	wrmsr_on_cpus(cmask, MSR_IA32_MCG_CTL, msrs);
+
+	kfree(msrs);
+	free_cpumask_var(cmask);
+
+	return 0;
+}
+
 /*
  * Only if 'ecc_enable_override' is set AND BIOS had ECC disabled, do "we"
  * enable it.
@@ -2625,24 +2591,16 @@
 static void amd64_enable_ecc_error_reporting(struct mem_ctl_info *mci)
 {
 	struct amd64_pvt *pvt = mci->pvt_info;
-	const cpumask_t *cpumask = cpumask_of_node(pvt->mc_node_id);
-	int cpu, idx = 0, err = 0;
-	struct msr msrs[cpumask_weight(cpumask)];
-	u32 value;
-	u32 mask = K8_NBCTL_CECCEn | K8_NBCTL_UECCEn;
+	u32 value, mask = K8_NBCTL_CECCEn | K8_NBCTL_UECCEn;
 
 	if (!ecc_enable_override)
 		return;
 
-	memset(msrs, 0, sizeof(msrs));
-
 	amd64_printk(KERN_WARNING,
 		"'ecc_enable_override' parameter is active, "
 		"Enabling AMD ECC hardware now: CAUTION\n");
 
-	err = pci_read_config_dword(pvt->misc_f3_ctl, K8_NBCTL, &value);
-	if (err)
-		debugf0("Reading K8_NBCTL failed\n");
+	amd64_read_pci_cfg(pvt->misc_f3_ctl, K8_NBCTL, &value);
 
 	/* turn on UECCn and CECCEn bits */
 	pvt->old_nbctl = value & mask;
@@ -2651,20 +2609,11 @@
 	value |= mask;
 	pci_write_config_dword(pvt->misc_f3_ctl, K8_NBCTL, value);
 
-	rdmsr_on_cpus(cpumask, K8_MSR_MCGCTL, msrs);
+	if (amd64_toggle_ecc_err_reporting(pvt, ON))
+		amd64_printk(KERN_WARNING, "Error enabling ECC reporting over "
+					   "MCGCTL!\n");
 
-	for_each_cpu(cpu, cpumask) {
-		if (msrs[idx].l & K8_MSR_MCGCTL_NBE)
-			set_bit(idx, &pvt->old_mcgctl);
-
-		msrs[idx].l |= K8_MSR_MCGCTL_NBE;
-		idx++;
-	}
-	wrmsr_on_cpus(cpumask, K8_MSR_MCGCTL, msrs);
-
-	err = pci_read_config_dword(pvt->misc_f3_ctl, K8_NBCFG, &value);
-	if (err)
-		debugf0("Reading K8_NBCFG failed\n");
+	amd64_read_pci_cfg(pvt->misc_f3_ctl, K8_NBCFG, &value);
 
 	debugf0("NBCFG(1)= 0x%x  CHIPKILL= %s ECC_ENABLE= %s\n", value,
 		(value & K8_NBCFG_CHIPKILL) ? "Enabled" : "Disabled",
@@ -2679,9 +2628,7 @@
 		value |= K8_NBCFG_ECC_ENABLE;
 		pci_write_config_dword(pvt->misc_f3_ctl, K8_NBCFG, value);
 
-		err = pci_read_config_dword(pvt->misc_f3_ctl, K8_NBCFG, &value);
-		if (err)
-			debugf0("Reading K8_NBCFG failed\n");
+		amd64_read_pci_cfg(pvt->misc_f3_ctl, K8_NBCFG, &value);
 
 		if (!(value & K8_NBCFG_ECC_ENABLE)) {
 			amd64_printk(KERN_WARNING,
@@ -2701,86 +2648,21 @@
 
 static void amd64_restore_ecc_error_reporting(struct amd64_pvt *pvt)
 {
-	const cpumask_t *cpumask = cpumask_of_node(pvt->mc_node_id);
-	int cpu, idx = 0, err = 0;
-	struct msr msrs[cpumask_weight(cpumask)];
-	u32 value;
-	u32 mask = K8_NBCTL_CECCEn | K8_NBCTL_UECCEn;
+	u32 value, mask = K8_NBCTL_CECCEn | K8_NBCTL_UECCEn;
 
 	if (!pvt->nbctl_mcgctl_saved)
 		return;
 
-	memset(msrs, 0, sizeof(msrs));
-
-	err = pci_read_config_dword(pvt->misc_f3_ctl, K8_NBCTL, &value);
-	if (err)
-		debugf0("Reading K8_NBCTL failed\n");
+	amd64_read_pci_cfg(pvt->misc_f3_ctl, K8_NBCTL, &value);
 	value &= ~mask;
 	value |= pvt->old_nbctl;
 
 	/* restore the NB Enable MCGCTL bit */
 	pci_write_config_dword(pvt->misc_f3_ctl, K8_NBCTL, value);
 
-	rdmsr_on_cpus(cpumask, K8_MSR_MCGCTL, msrs);
-
-	for_each_cpu(cpu, cpumask) {
-		msrs[idx].l &= ~K8_MSR_MCGCTL_NBE;
-		msrs[idx].l |=
-			test_bit(idx, &pvt->old_mcgctl) << K8_MSR_MCGCTL_NBE;
-		idx++;
-	}
-
-	wrmsr_on_cpus(cpumask, K8_MSR_MCGCTL, msrs);
-}
-
-/* get all cores on this DCT */
-static void get_cpus_on_this_dct_cpumask(cpumask_t *mask, int nid)
-{
-	int cpu;
-
-	for_each_online_cpu(cpu)
-		if (amd_get_nb_id(cpu) == nid)
-			cpumask_set_cpu(cpu, mask);
-}
-
-/* check MCG_CTL on all the cpus on this node */
-static bool amd64_nb_mce_bank_enabled_on_node(int nid)
-{
-	cpumask_t mask;
-	struct msr *msrs;
-	int cpu, nbe, idx = 0;
-	bool ret = false;
-
-	cpumask_clear(&mask);
-
-	get_cpus_on_this_dct_cpumask(&mask, nid);
-
-	msrs = kzalloc(sizeof(struct msr) * cpumask_weight(&mask), GFP_KERNEL);
-	if (!msrs) {
-		amd64_printk(KERN_WARNING, "%s: error allocating msrs\n",
-			      __func__);
-		 return false;
-	}
-
-	rdmsr_on_cpus(&mask, MSR_IA32_MCG_CTL, msrs);
-
-	for_each_cpu(cpu, &mask) {
-		nbe = msrs[idx].l & K8_MSR_MCGCTL_NBE;
-
-		debugf0("core: %u, MCG_CTL: 0x%llx, NB MSR is %s\n",
-			cpu, msrs[idx].q,
-			(nbe ? "enabled" : "disabled"));
-
-		if (!nbe)
-			goto out;
-
-		idx++;
-	}
-	ret = true;
-
-out:
-	kfree(msrs);
-	return ret;
+	if (amd64_toggle_ecc_err_reporting(pvt, OFF))
+		amd64_printk(KERN_WARNING, "Error restoring ECC reporting over "
+					   "MCGCTL!\n");
 }
 
 /*
@@ -2797,13 +2679,10 @@
 static int amd64_check_ecc_enabled(struct amd64_pvt *pvt)
 {
 	u32 value;
-	int err = 0;
 	u8 ecc_enabled = 0;
 	bool nb_mce_en = false;
 
-	err = pci_read_config_dword(pvt->misc_f3_ctl, K8_NBCFG, &value);
-	if (err)
-		debugf0("Reading K8_NBCTL failed\n");
+	amd64_read_pci_cfg(pvt->misc_f3_ctl, K8_NBCFG, &value);
 
 	ecc_enabled = !!(value & K8_NBCFG_ECC_ENABLE);
 	if (!ecc_enabled)
@@ -2909,7 +2788,6 @@
 	pvt->ext_model		= boot_cpu_data.x86_model >> 4;
 	pvt->mc_type_index	= mc_type_index;
 	pvt->ops		= family_ops(mc_type_index);
-	pvt->old_mcgctl		= 0;
 
 	/*
 	 * We have the dram_f2_ctl device as an argument, now go reserve its
@@ -2959,17 +2837,10 @@
 {
 	int node_id = pvt->mc_node_id;
 	struct mem_ctl_info *mci;
-	int ret, err = 0;
+	int ret = -ENODEV;
 
 	amd64_read_mc_registers(pvt);
 
-	ret = -ENODEV;
-	if (pvt->ops->probe_valid_hardware) {
-		err = pvt->ops->probe_valid_hardware(pvt);
-		if (err)
-			goto err_exit;
-	}
-
 	/*
 	 * We need to determine how many memory channels there are. Then use
 	 * that information for calculating the size of the dynamic instance
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index c6f359a..41bc561 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -129,24 +129,22 @@
  *         sections 3.5.4 and 3.5.5 for more information.
  */
 
-#define EDAC_AMD64_VERSION		" Ver: 3.2.0 " __DATE__
+#define EDAC_AMD64_VERSION		" Ver: 3.3.0 " __DATE__
 #define EDAC_MOD_STR			"amd64_edac"
 
 #define EDAC_MAX_NUMNODES		8
 
 /* Extended Model from CPUID, for CPU Revision numbers */
-#define OPTERON_CPU_LE_REV_C		0
-#define OPTERON_CPU_REV_D		1
-#define OPTERON_CPU_REV_E		2
-
-/* NPT processors have the following Extended Models */
-#define OPTERON_CPU_REV_F		4
-#define OPTERON_CPU_REV_FA		5
+#define K8_REV_D			1
+#define K8_REV_E			2
+#define K8_REV_F			4
 
 /* Hardware limit on ChipSelect rows per MC and processors per system */
 #define MAX_CS_COUNT			8
 #define DRAM_REG_COUNT			8
 
+#define ON true
+#define OFF false
 
 /*
  * PCI-defined configuration space registers
@@ -241,7 +239,7 @@
 #define F10_DCHR_1			0x194
 
 #define F10_DCHR_FOUR_RANK_DIMM		BIT(18)
-#define F10_DCHR_Ddr3Mode		BIT(8)
+#define DDR3_MODE			BIT(8)
 #define F10_DCHR_MblMode		BIT(6)
 
 
@@ -382,14 +380,9 @@
 #define K8_NBCAP_CORES			(BIT(12)|BIT(13))
 #define K8_NBCAP_CHIPKILL		BIT(4)
 #define K8_NBCAP_SECDED			BIT(3)
-#define K8_NBCAP_8_NODE			BIT(2)
-#define K8_NBCAP_DUAL_NODE		BIT(1)
 #define K8_NBCAP_DCT_DUAL		BIT(0)
 
-/*
- * MSR Regs
- */
-#define K8_MSR_MCGCTL			0x017b
+/* MSRs */
 #define K8_MSR_MCGCTL_NBE		BIT(4)
 
 #define K8_MSR_MC4CTL			0x0410
@@ -487,7 +480,6 @@
 	/* Save old hw registers' values before we modified them */
 	u32 nbctl_mcgctl_saved;		/* When true, following 2 are valid */
 	u32 old_nbctl;
-	unsigned long old_mcgctl;	/* per core on this node */
 
 	/* MC Type Index value: socket F vs Family 10h */
 	u32 mc_type_index;
@@ -495,6 +487,7 @@
 	/* misc settings */
 	struct flags {
 		unsigned long cf8_extcfg:1;
+		unsigned long ecc_report:1;
 	} flags;
 };
 
@@ -504,7 +497,6 @@
 };
 
 extern struct scrubrate scrubrates[23];
-extern u32 revf_quad_ddr2_shift[16];
 extern const char *tt_msgs[4];
 extern const char *ll_msgs[4];
 extern const char *rrrr_msgs[16];
@@ -534,17 +526,15 @@
  * functions and per device encoding/decoding logic.
  */
 struct low_ops {
-	int (*probe_valid_hardware)(struct amd64_pvt *pvt);
-	int (*early_channel_count)(struct amd64_pvt *pvt);
+	int (*early_channel_count)	(struct amd64_pvt *pvt);
 
-	u64 (*get_error_address)(struct mem_ctl_info *mci,
-			struct err_regs *info);
-	void (*read_dram_base_limit)(struct amd64_pvt *pvt, int dram);
-	void (*read_dram_ctl_register)(struct amd64_pvt *pvt);
-	void (*map_sysaddr_to_csrow)(struct mem_ctl_info *mci,
-					struct err_regs *info,
-					u64 SystemAddr);
-	int (*dbam_map_to_pages)(struct amd64_pvt *pvt, int dram_map);
+	u64 (*get_error_address)	(struct mem_ctl_info *mci,
+					 struct err_regs *info);
+	void (*read_dram_base_limit)	(struct amd64_pvt *pvt, int dram);
+	void (*read_dram_ctl_register)	(struct amd64_pvt *pvt);
+	void (*map_sysaddr_to_csrow)	(struct mem_ctl_info *mci,
+					 struct err_regs *info, u64 SystemAddr);
+	int (*dbam_to_cs)		(struct amd64_pvt *pvt, int cs_mode);
 };
 
 struct amd64_family_type {
@@ -566,6 +556,22 @@
 	return &amd64_family_types[index].ops;
 }
 
+static inline int amd64_read_pci_cfg_dword(struct pci_dev *pdev, int offset,
+					   u32 *val, const char *func)
+{
+	int err = 0;
+
+	err = pci_read_config_dword(pdev, offset, val);
+	if (err)
+		amd64_printk(KERN_WARNING, "%s: error reading F%dx%x.\n",
+			     func, PCI_FUNC(pdev->devfn), offset);
+
+	return err;
+}
+
+#define amd64_read_pci_cfg(pdev, offset, val)	\
+	amd64_read_pci_cfg_dword(pdev, offset, val, __func__)
+
 /*
  * For future CPU versions, verify the following as new 'slow' rates appear and
  * modify the necessary skip values for the supported CPU.
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index 12f355c..001b2e7 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -74,6 +74,7 @@
 
 #ifdef CONFIG_EDAC_DEBUG
 extern int edac_debug_level;
+extern const char *edac_mem_types[];
 
 #ifndef CONFIG_EDAC_DEBUG_VERBOSE
 #define edac_debug_printk(level, fmt, arg...)                           \
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index b629c41..3630308 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -76,6 +76,30 @@
 	debugf3("\tpvt_info = %p\n\n", mci->pvt_info);
 }
 
+/*
+ * keep those in sync with the enum mem_type
+ */
+const char *edac_mem_types[] = {
+	"Empty csrow",
+	"Reserved csrow type",
+	"Unknown csrow type",
+	"Fast page mode RAM",
+	"Extended data out RAM",
+	"Burst Extended data out RAM",
+	"Single data rate SDRAM",
+	"Registered single data rate SDRAM",
+	"Double data rate SDRAM",
+	"Registered Double data rate SDRAM",
+	"Rambus DRAM",
+	"Unbuffered DDR2 RAM",
+	"Fully buffered DDR2",
+	"Registered DDR2 RAM",
+	"Rambus XDR",
+	"Unbuffered DDR3 RAM",
+	"Registered DDR3 RAM",
+};
+EXPORT_SYMBOL_GPL(edac_mem_types);
+
 #endif				/* CONFIG_EDAC_DEBUG */
 
 /* 'ptr' points to a possibly unaligned item X such that sizeof(X) is 'size'.
diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c
index 689cc6a..c693fcc 100644
--- a/drivers/edac/edac_mce_amd.c
+++ b/drivers/edac/edac_mce_amd.c
@@ -306,7 +306,7 @@
 	 * value encoding has changed so interpret those differently
 	 */
 	if ((boot_cpu_data.x86 == 0x10) &&
-	    (boot_cpu_data.x86_model > 8)) {
+	    (boot_cpu_data.x86_model > 7)) {
 		if (regs->nbsh & K8_NBSH_ERR_CPU_VAL)
 			pr_cont(", core: %u\n", (u8)(regs->nbsh & 0xf));
 	} else {
diff --git a/drivers/firewire/core-topology.c b/drivers/firewire/core-topology.c
index 9a5f38c..93ec64c 100644
--- a/drivers/firewire/core-topology.c
+++ b/drivers/firewire/core-topology.c
@@ -183,7 +183,7 @@
  * This function builds the tree representation of the topology given
  * by the self IDs from the latest bus reset.  During the construction
  * of the tree, the function checks that the self IDs are valid and
- * internally consistent.  On succcess this function returns the
+ * internally consistent.  On success this function returns the
  * fw_node corresponding to the local card otherwise NULL.
  */
 static struct fw_node *build_tree(struct fw_card *card,
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index ae4556f..96768e1 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -2218,6 +2218,13 @@
 	page     = payload >> PAGE_SHIFT;
 	offset   = payload & ~PAGE_MASK;
 	rest     = p->payload_length;
+	/*
+	 * The controllers I've tested have not worked correctly when
+	 * second_req_count is zero.  Rather than do something we know won't
+	 * work, return an error
+	 */
+	if (rest == 0)
+		return -EINVAL;
 
 	/* FIXME: make packet-per-buffer/dual-buffer a context option */
 	while (rest > 0) {
@@ -2271,7 +2278,7 @@
 					unsigned long payload)
 {
 	struct iso_context *ctx = container_of(base, struct iso_context, base);
-	struct descriptor *d = NULL, *pd = NULL;
+	struct descriptor *d, *pd;
 	struct fw_iso_packet *p = packet;
 	dma_addr_t d_bus, page_bus;
 	u32 z, header_z, rest;
@@ -2309,8 +2316,9 @@
 		d->data_address = cpu_to_le32(d_bus + (z * sizeof(*d)));
 
 		rest = payload_per_buffer;
+		pd = d;
 		for (j = 1; j < z; j++) {
-			pd = d + j;
+			pd++;
 			pd->control = cpu_to_le16(DESCRIPTOR_STATUS |
 						  DESCRIPTOR_INPUT_MORE);
 
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c
index b4704e1..b3a0cf5 100644
--- a/drivers/firmware/dell_rbu.c
+++ b/drivers/firmware/dell_rbu.c
@@ -544,9 +544,12 @@
 {
 	rbu_data.entry_created = 0;
 
-	if (!fw || !fw->size)
+	if (!fw)
 		return;
 
+	if (!fw->size)
+		goto out;
+
 	spin_lock(&rbu_data.lock);
 	if (!strcmp(image_type, "mono")) {
 		if (!img_update_realloc(fw->size))
@@ -568,6 +571,8 @@
 	} else
 		pr_debug("invalid image type specified.\n");
 	spin_unlock(&rbu_data.lock);
+ out:
+	release_firmware(fw);
 }
 
 static ssize_t read_rbu_image_type(struct kobject *kobj,
@@ -615,7 +620,7 @@
 			spin_unlock(&rbu_data.lock);
 			req_firm_rc = request_firmware_nowait(THIS_MODULE,
 				FW_ACTION_NOHOTPLUG, "dell_rbu",
-				&rbu_device->dev, &context,
+				&rbu_device->dev, GFP_KERNEL, &context,
 				callbackfn_rbu);
 			if (req_firm_rc) {
 				printk(KERN_ERR
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index 938100f..3a2ccb0 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -429,7 +429,7 @@
 	for (i = 0; i < ARRAY_SIZE(dmi->matches); i++) {
 		int s = dmi->matches[i].slot;
 		if (s == DMI_NONE)
-			continue;
+			break;
 		if (dmi_ident[s]
 		    && strstr(dmi_ident[s], dmi->matches[i].substr))
 			continue;
@@ -440,6 +440,15 @@
 }
 
 /**
+ *	dmi_is_end_of_table - check for end-of-table marker
+ *	@dmi: pointer to the dmi_system_id structure to check
+ */
+static bool dmi_is_end_of_table(const struct dmi_system_id *dmi)
+{
+	return dmi->matches[0].slot == DMI_NONE;
+}
+
+/**
  *	dmi_check_system - check system DMI data
  *	@list: array of dmi_system_id structures to match against
  *		All non-null elements of the list must match
@@ -457,7 +466,7 @@
 	int count = 0;
 	const struct dmi_system_id *d;
 
-	for (d = list; d->ident; d++)
+	for (d = list; !dmi_is_end_of_table(d); d++)
 		if (dmi_matches(d)) {
 			count++;
 			if (d->callback && d->callback(d))
@@ -484,7 +493,7 @@
 {
 	const struct dmi_system_id *d;
 
-	for (d = list; d->ident; d++)
+	for (d = list; !dmi_is_end_of_table(d); d++)
 		if (dmi_matches(d))
 			return d;
 
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 3c8827a..470ef67 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -15,7 +15,7 @@
 
 drm-$(CONFIG_COMPAT) += drm_ioc32.o
 
-drm_kms_helper-y := drm_fb_helper.o drm_crtc_helper.o
+drm_kms_helper-y := drm_fb_helper.o drm_crtc_helper.o drm_dp_i2c_helper.o
 
 obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
 
@@ -31,3 +31,5 @@
 obj-$(CONFIG_DRM_SIS)   += sis/
 obj-$(CONFIG_DRM_SAVAGE)+= savage/
 obj-$(CONFIG_DRM_VIA)	+=via/
+obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/
+obj-y			+= i2c/
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 5cae0b3..5124401 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -125,6 +125,15 @@
 DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
 		 drm_tv_subconnector_enum_list)
 
+static struct drm_prop_enum_list drm_dirty_info_enum_list[] = {
+	{ DRM_MODE_DIRTY_OFF,      "Off"      },
+	{ DRM_MODE_DIRTY_ON,       "On"       },
+	{ DRM_MODE_DIRTY_ANNOTATE, "Annotate" },
+};
+
+DRM_ENUM_NAME_FN(drm_get_dirty_info_name,
+		 drm_dirty_info_enum_list)
+
 struct drm_conn_prop_enum_list {
 	int type;
 	char *name;
@@ -247,7 +256,8 @@
 	mutex_unlock(&dev->mode_config.idr_mutex);
 }
 
-void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type)
+struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
+		uint32_t id, uint32_t type)
 {
 	struct drm_mode_object *obj = NULL;
 
@@ -272,7 +282,7 @@
  * functions & device file and adds it to the master fd list.
  *
  * RETURNS:
- * Zero on success, error code on falure.
+ * Zero on success, error code on failure.
  */
 int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
 			 const struct drm_framebuffer_funcs *funcs)
@@ -802,6 +812,36 @@
 EXPORT_SYMBOL(drm_mode_create_dithering_property);
 
 /**
+ * drm_mode_create_dirty_property - create dirty property
+ * @dev: DRM device
+ *
+ * Called by a driver the first time it's needed, must be attached to desired
+ * connectors.
+ */
+int drm_mode_create_dirty_info_property(struct drm_device *dev)
+{
+	struct drm_property *dirty_info;
+	int i;
+
+	if (dev->mode_config.dirty_info_property)
+		return 0;
+
+	dirty_info =
+		drm_property_create(dev, DRM_MODE_PROP_ENUM |
+				    DRM_MODE_PROP_IMMUTABLE,
+				    "dirty",
+				    ARRAY_SIZE(drm_dirty_info_enum_list));
+	for (i = 0; i < ARRAY_SIZE(drm_dirty_info_enum_list); i++)
+		drm_property_add_enum(dirty_info, i,
+				      drm_dirty_info_enum_list[i].type,
+				      drm_dirty_info_enum_list[i].name);
+	dev->mode_config.dirty_info_property = dirty_info;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_mode_create_dirty_info_property);
+
+/**
  * drm_mode_config_init - initialize DRM mode_configuration structure
  * @dev: DRM device
  *
@@ -1753,6 +1793,71 @@
 	return ret;
 }
 
+int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
+			   void *data, struct drm_file *file_priv)
+{
+	struct drm_clip_rect __user *clips_ptr;
+	struct drm_clip_rect *clips = NULL;
+	struct drm_mode_fb_dirty_cmd *r = data;
+	struct drm_mode_object *obj;
+	struct drm_framebuffer *fb;
+	unsigned flags;
+	int num_clips;
+	int ret = 0;
+
+	mutex_lock(&dev->mode_config.mutex);
+	obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB);
+	if (!obj) {
+		DRM_ERROR("invalid framebuffer id\n");
+		ret = -EINVAL;
+		goto out_err1;
+	}
+	fb = obj_to_fb(obj);
+
+	num_clips = r->num_clips;
+	clips_ptr = (struct drm_clip_rect *)(unsigned long)r->clips_ptr;
+
+	if (!num_clips != !clips_ptr) {
+		ret = -EINVAL;
+		goto out_err1;
+	}
+
+	flags = DRM_MODE_FB_DIRTY_FLAGS & r->flags;
+
+	/* If userspace annotates copy, clips must come in pairs */
+	if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY && (num_clips % 2)) {
+		ret = -EINVAL;
+		goto out_err1;
+	}
+
+	if (num_clips && clips_ptr) {
+		clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL);
+		if (!clips) {
+			ret = -ENOMEM;
+			goto out_err1;
+		}
+
+		ret = copy_from_user(clips, clips_ptr,
+				     num_clips * sizeof(*clips));
+		if (ret)
+			goto out_err2;
+	}
+
+	if (fb->funcs->dirty) {
+		ret = fb->funcs->dirty(fb, flags, r->color, clips, num_clips);
+	} else {
+		ret = -ENOSYS;
+		goto out_err2;
+	}
+
+out_err2:
+	kfree(clips);
+out_err1:
+	mutex_unlock(&dev->mode_config.mutex);
+	return ret;
+}
+
+
 /**
  * drm_fb_release - remove and free the FBs on this file
  * @filp: file * from the ioctl
@@ -2328,7 +2433,7 @@
 	} else if (connector->funcs->set_property)
 		ret = connector->funcs->set_property(connector, property, out_resp->value);
 
-	/* store the property value if succesful */
+	/* store the property value if successful */
 	if (!ret)
 		drm_connector_property_set_value(connector, property, out_resp->value);
 out:
@@ -2478,3 +2583,72 @@
 	mutex_unlock(&dev->mode_config.mutex);
 	return ret;
 }
+
+int drm_mode_page_flip_ioctl(struct drm_device *dev,
+			     void *data, struct drm_file *file_priv)
+{
+	struct drm_mode_crtc_page_flip *page_flip = data;
+	struct drm_mode_object *obj;
+	struct drm_crtc *crtc;
+	struct drm_framebuffer *fb;
+	struct drm_pending_vblank_event *e = NULL;
+	unsigned long flags;
+	int ret = -EINVAL;
+
+	if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS ||
+	    page_flip->reserved != 0)
+		return -EINVAL;
+
+	mutex_lock(&dev->mode_config.mutex);
+	obj = drm_mode_object_find(dev, page_flip->crtc_id, DRM_MODE_OBJECT_CRTC);
+	if (!obj)
+		goto out;
+	crtc = obj_to_crtc(obj);
+
+	if (crtc->funcs->page_flip == NULL)
+		goto out;
+
+	obj = drm_mode_object_find(dev, page_flip->fb_id, DRM_MODE_OBJECT_FB);
+	if (!obj)
+		goto out;
+	fb = obj_to_fb(obj);
+
+	if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
+		ret = -ENOMEM;
+		spin_lock_irqsave(&dev->event_lock, flags);
+		if (file_priv->event_space < sizeof e->event) {
+			spin_unlock_irqrestore(&dev->event_lock, flags);
+			goto out;
+		}
+		file_priv->event_space -= sizeof e->event;
+		spin_unlock_irqrestore(&dev->event_lock, flags);
+
+		e = kzalloc(sizeof *e, GFP_KERNEL);
+		if (e == NULL) {
+			spin_lock_irqsave(&dev->event_lock, flags);
+			file_priv->event_space += sizeof e->event;
+			spin_unlock_irqrestore(&dev->event_lock, flags);
+			goto out;
+		}
+
+		e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
+		e->event.base.length = sizeof e->event;
+		e->event.user_data = page_flip->user_data;
+		e->base.event = &e->event.base;
+		e->base.file_priv = file_priv;
+		e->base.destroy =
+			(void (*) (struct drm_pending_event *)) kfree;
+	}
+
+	ret = crtc->funcs->page_flip(crtc, fb, e);
+	if (ret) {
+		spin_lock_irqsave(&dev->event_lock, flags);
+		file_priv->event_space += sizeof e->event;
+		spin_unlock_irqrestore(&dev->event_lock, flags);
+		kfree(e);
+	}
+
+out:
+	mutex_unlock(&dev->mode_config.mutex);
+	return ret;
+}
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index bbfd110..4231d6d 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -109,7 +109,7 @@
 
 	count = (*connector_funcs->get_modes)(connector);
 	if (!count) {
-		count = drm_add_modes_noedid(connector, 800, 600);
+		count = drm_add_modes_noedid(connector, 1024, 768);
 		if (!count)
 			return 0;
 	}
@@ -1020,6 +1020,9 @@
 {
 	int count = 0;
 
+	/* disable all the possible outputs/crtcs before entering KMS mode */
+	drm_helper_disable_unused_functions(dev);
+
 	drm_fb_helper_parse_command_line(dev);
 
 	count = drm_helper_probe_connector_modes(dev,
diff --git a/drivers/gpu/drm/drm_dp_i2c_helper.c b/drivers/gpu/drm/drm_dp_i2c_helper.c
new file mode 100644
index 0000000..548887c
--- /dev/null
+++ b/drivers/gpu/drm/drm_dp_i2c_helper.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright © 2009 Keith Packard
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/i2c.h>
+#include "drm_dp_helper.h"
+#include "drmP.h"
+
+/* Run a single AUX_CH I2C transaction, writing/reading data as necessary */
+static int
+i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode,
+			    uint8_t write_byte, uint8_t *read_byte)
+{
+	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+	int ret;
+	
+	ret = (*algo_data->aux_ch)(adapter, mode,
+				   write_byte, read_byte);
+	return ret;
+}
+
+/*
+ * I2C over AUX CH
+ */
+
+/*
+ * Send the address. If the I2C link is running, this 'restarts'
+ * the connection with the new address, this is used for doing
+ * a write followed by a read (as needed for DDC)
+ */
+static int
+i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 address, bool reading)
+{
+	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+	int mode = MODE_I2C_START;
+	int ret;
+
+	if (reading)
+		mode |= MODE_I2C_READ;
+	else
+		mode |= MODE_I2C_WRITE;
+	algo_data->address = address;
+	algo_data->running = true;
+	ret = i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
+	return ret;
+}
+
+/*
+ * Stop the I2C transaction. This closes out the link, sending
+ * a bare address packet with the MOT bit turned off
+ */
+static void
+i2c_algo_dp_aux_stop(struct i2c_adapter *adapter, bool reading)
+{
+	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+	int mode = MODE_I2C_STOP;
+
+	if (reading)
+		mode |= MODE_I2C_READ;
+	else
+		mode |= MODE_I2C_WRITE;
+	if (algo_data->running) {
+		(void) i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
+		algo_data->running = false;
+	}
+}
+
+/*
+ * Write a single byte to the current I2C address, the
+ * the I2C link must be running or this returns -EIO
+ */
+static int
+i2c_algo_dp_aux_put_byte(struct i2c_adapter *adapter, u8 byte)
+{
+	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+	int ret;
+
+	if (!algo_data->running)
+		return -EIO;
+
+	ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_WRITE, byte, NULL);
+	return ret;
+}
+
+/*
+ * Read a single byte from the current I2C address, the
+ * I2C link must be running or this returns -EIO
+ */
+static int
+i2c_algo_dp_aux_get_byte(struct i2c_adapter *adapter, u8 *byte_ret)
+{
+	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+	int ret;
+
+	if (!algo_data->running)
+		return -EIO;
+
+	ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_READ, 0, byte_ret);
+	return ret;
+}
+
+static int
+i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter,
+		     struct i2c_msg *msgs,
+		     int num)
+{
+	int ret = 0;
+	bool reading = false;
+	int m;
+	int b;
+
+	for (m = 0; m < num; m++) {
+		u16 len = msgs[m].len;
+		u8 *buf = msgs[m].buf;
+		reading = (msgs[m].flags & I2C_M_RD) != 0;
+		ret = i2c_algo_dp_aux_address(adapter, msgs[m].addr, reading);
+		if (ret < 0)
+			break;
+		if (reading) {
+			for (b = 0; b < len; b++) {
+				ret = i2c_algo_dp_aux_get_byte(adapter, &buf[b]);
+				if (ret < 0)
+					break;
+			}
+		} else {
+			for (b = 0; b < len; b++) {
+				ret = i2c_algo_dp_aux_put_byte(adapter, buf[b]);
+				if (ret < 0)
+					break;
+			}
+		}
+		if (ret < 0)
+			break;
+	}
+	if (ret >= 0)
+		ret = num;
+	i2c_algo_dp_aux_stop(adapter, reading);
+	DRM_DEBUG_KMS("dp_aux_xfer return %d\n", ret);
+	return ret;
+}
+
+static u32
+i2c_algo_dp_aux_functionality(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
+	       I2C_FUNC_SMBUS_READ_BLOCK_DATA |
+	       I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
+	       I2C_FUNC_10BIT_ADDR;
+}
+
+static const struct i2c_algorithm i2c_dp_aux_algo = {
+	.master_xfer	= i2c_algo_dp_aux_xfer,
+	.functionality	= i2c_algo_dp_aux_functionality,
+};
+
+static void
+i2c_dp_aux_reset_bus(struct i2c_adapter *adapter)
+{
+	(void) i2c_algo_dp_aux_address(adapter, 0, false);
+	(void) i2c_algo_dp_aux_stop(adapter, false);
+					   
+}
+
+static int
+i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter)
+{
+	adapter->algo = &i2c_dp_aux_algo;
+	adapter->retries = 3;
+	i2c_dp_aux_reset_bus(adapter);
+	return 0;
+}
+
+int
+i2c_dp_aux_add_bus(struct i2c_adapter *adapter)
+{
+	int error;
+	
+	error = i2c_dp_aux_prepare_bus(adapter);
+	if (error)
+		return error;
+	error = i2c_add_adapter(adapter);
+	return error;
+}
+EXPORT_SYMBOL(i2c_dp_aux_add_bus);
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index a75ca63..ff2f104 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -145,6 +145,8 @@
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW)
 };
 
 #define DRM_CORE_IOCTL_COUNT	ARRAY_SIZE( drm_ioctls )
@@ -366,6 +368,29 @@
 module_exit(drm_core_exit);
 
 /**
+ * Copy and IOCTL return string to user space
+ */
+static int drm_copy_field(char *buf, size_t *buf_len, const char *value)
+{
+	int len;
+
+	/* don't overflow userbuf */
+	len = strlen(value);
+	if (len > *buf_len)
+		len = *buf_len;
+
+	/* let userspace know exact length of driver value (which could be
+	 * larger than the userspace-supplied buffer) */
+	*buf_len = strlen(value);
+
+	/* finally, try filling in the userbuf */
+	if (len && buf)
+		if (copy_to_user(buf, value, len))
+			return -EFAULT;
+	return 0;
+}
+
+/**
  * Get version information
  *
  * \param inode device inode.
@@ -380,16 +405,21 @@
 		       struct drm_file *file_priv)
 {
 	struct drm_version *version = data;
-	int len;
+	int err;
 
 	version->version_major = dev->driver->major;
 	version->version_minor = dev->driver->minor;
 	version->version_patchlevel = dev->driver->patchlevel;
-	DRM_COPY(version->name, dev->driver->name);
-	DRM_COPY(version->date, dev->driver->date);
-	DRM_COPY(version->desc, dev->driver->desc);
+	err = drm_copy_field(version->name, &version->name_len,
+			dev->driver->name);
+	if (!err)
+		err = drm_copy_field(version->date, &version->date_len,
+				dev->driver->date);
+	if (!err)
+		err = drm_copy_field(version->desc, &version->desc_len,
+				dev->driver->desc);
 
-	return 0;
+	return err;
 }
 
 /**
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index b54ba63..c39b26f 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -123,18 +123,20 @@
  */
 static bool edid_is_valid(struct edid *edid)
 {
-	int i;
+	int i, score = 0;
 	u8 csum = 0;
 	u8 *raw_edid = (u8 *)edid;
 
-	if (memcmp(edid->header, edid_header, sizeof(edid_header)))
+	for (i = 0; i < sizeof(edid_header); i++)
+		if (raw_edid[i] == edid_header[i])
+			score++;
+
+	if (score == 8) ;
+	else if (score >= 6) {
+		DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
+		memcpy(raw_edid, edid_header, sizeof(edid_header));
+	} else
 		goto bad;
-	if (edid->version != 1) {
-		DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version);
-		goto bad;
-	}
-	if (edid->revision > 4)
-		DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");
 
 	for (i = 0; i < EDID_LENGTH; i++)
 		csum += raw_edid[i];
@@ -143,6 +145,14 @@
 		goto bad;
 	}
 
+	if (edid->version != 1) {
+		DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version);
+		goto bad;
+	}
+
+	if (edid->revision > 4)
+		DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");
+
 	return 1;
 
 bad:
@@ -481,16 +491,17 @@
 		   3048, 3536, 0, 1600, 1603, 1609, 1682, 0,
 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
 };
+static const int drm_num_dmt_modes =
+	sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode);
 
 static struct drm_display_mode *drm_find_dmt(struct drm_device *dev,
 			int hsize, int vsize, int fresh)
 {
-	int i, count;
+	int i;
 	struct drm_display_mode *ptr, *mode;
 
-	count = sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode);
 	mode = NULL;
-	for (i = 0; i < count; i++) {
+	for (i = 0; i < drm_num_dmt_modes; i++) {
 		ptr = &drm_dmt_modes[i];
 		if (hsize == ptr->hdisplay &&
 			vsize == ptr->vdisplay &&
@@ -834,8 +845,165 @@
 	return modes;
 }
 
+/*
+ * XXX fix this for:
+ * - GTF secondary curve formula
+ * - EDID 1.4 range offsets
+ * - CVT extended bits
+ */
+static bool
+mode_in_range(struct drm_display_mode *mode, struct detailed_timing *timing)
+{
+	struct detailed_data_monitor_range *range;
+	int hsync, vrefresh;
+
+	range = &timing->data.other_data.data.range;
+
+	hsync = drm_mode_hsync(mode);
+	vrefresh = drm_mode_vrefresh(mode);
+
+	if (hsync < range->min_hfreq_khz || hsync > range->max_hfreq_khz)
+		return false;
+
+	if (vrefresh < range->min_vfreq || vrefresh > range->max_vfreq)
+		return false;
+
+	if (range->pixel_clock_mhz && range->pixel_clock_mhz != 0xff) {
+		/* be forgiving since it's in units of 10MHz */
+		int max_clock = range->pixel_clock_mhz * 10 + 9;
+		max_clock *= 1000;
+		if (mode->clock > max_clock)
+			return false;
+	}
+
+	return true;
+}
+
+/*
+ * XXX If drm_dmt_modes ever regrows the CVT-R modes (and it will) this will
+ * need to account for them.
+ */
+static int drm_gtf_modes_for_range(struct drm_connector *connector,
+				   struct detailed_timing *timing)
+{
+	int i, modes = 0;
+	struct drm_display_mode *newmode;
+	struct drm_device *dev = connector->dev;
+
+	for (i = 0; i < drm_num_dmt_modes; i++) {
+		if (mode_in_range(drm_dmt_modes + i, timing)) {
+			newmode = drm_mode_duplicate(dev, &drm_dmt_modes[i]);
+			if (newmode) {
+				drm_mode_probed_add(connector, newmode);
+				modes++;
+			}
+		}
+	}
+
+	return modes;
+}
+
+static int drm_cvt_modes(struct drm_connector *connector,
+			 struct detailed_timing *timing)
+{
+	int i, j, modes = 0;
+	struct drm_display_mode *newmode;
+	struct drm_device *dev = connector->dev;
+	struct cvt_timing *cvt;
+	const int rates[] = { 60, 85, 75, 60, 50 };
+
+	for (i = 0; i < 4; i++) {
+		int width, height;
+		cvt = &(timing->data.other_data.data.cvt[i]);
+
+		height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 8) + 1) * 2;
+		switch (cvt->code[1] & 0xc0) {
+		case 0x00:
+			width = height * 4 / 3;
+			break;
+		case 0x40:
+			width = height * 16 / 9;
+			break;
+		case 0x80:
+			width = height * 16 / 10;
+			break;
+		case 0xc0:
+			width = height * 15 / 9;
+			break;
+		}
+
+		for (j = 1; j < 5; j++) {
+			if (cvt->code[2] & (1 << j)) {
+				newmode = drm_cvt_mode(dev, width, height,
+						       rates[j], j == 0,
+						       false, false);
+				if (newmode) {
+					drm_mode_probed_add(connector, newmode);
+					modes++;
+				}
+			}
+		}
+	}
+
+	return modes;
+}
+
+static int add_detailed_modes(struct drm_connector *connector,
+			      struct detailed_timing *timing,
+			      struct edid *edid, u32 quirks, int preferred)
+{
+	int i, modes = 0;
+	struct detailed_non_pixel *data = &timing->data.other_data;
+	int timing_level = standard_timing_level(edid);
+	int gtf = (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF);
+	struct drm_display_mode *newmode;
+	struct drm_device *dev = connector->dev;
+
+	if (timing->pixel_clock) {
+		newmode = drm_mode_detailed(dev, edid, timing, quirks);
+		if (!newmode)
+			return 0;
+
+		if (preferred)
+			newmode->type |= DRM_MODE_TYPE_PREFERRED;
+
+		drm_mode_probed_add(connector, newmode);
+		return 1;
+	}
+
+	/* other timing types */
+	switch (data->type) {
+	case EDID_DETAIL_MONITOR_RANGE:
+		if (gtf)
+			modes += drm_gtf_modes_for_range(connector, timing);
+		break;
+	case EDID_DETAIL_STD_MODES:
+		/* Six modes per detailed section */
+		for (i = 0; i < 6; i++) {
+			struct std_timing *std;
+			struct drm_display_mode *newmode;
+
+			std = &data->data.timings[i];
+			newmode = drm_mode_std(dev, std, edid->revision,
+					       timing_level);
+			if (newmode) {
+				drm_mode_probed_add(connector, newmode);
+				modes++;
+			}
+		}
+		break;
+	case EDID_DETAIL_CVT_3BYTE:
+		modes += drm_cvt_modes(connector, timing);
+		break;
+	default:
+		break;
+	}
+
+	return modes;
+}
+
 /**
- * add_detailed_modes - get detailed mode info from EDID data
+ * add_detailed_info - get detailed mode info from EDID data
  * @connector: attached connector
  * @edid: EDID block to scan
  * @quirks: quirks to apply
@@ -846,67 +1014,24 @@
 static int add_detailed_info(struct drm_connector *connector,
 			     struct edid *edid, u32 quirks)
 {
-	struct drm_device *dev = connector->dev;
-	int i, j, modes = 0;
-	int timing_level;
-
-	timing_level = standard_timing_level(edid);
+	int i, modes = 0;
 
 	for (i = 0; i < EDID_DETAILED_TIMINGS; i++) {
 		struct detailed_timing *timing = &edid->detailed_timings[i];
-		struct detailed_non_pixel *data = &timing->data.other_data;
-		struct drm_display_mode *newmode;
+		int preferred = (i == 0) && (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING);
 
-		/* X server check is version 1.1 or higher */
-		if (edid->version == 1 && edid->revision >= 1 &&
-		    !timing->pixel_clock) {
-			/* Other timing or info */
-			switch (data->type) {
-			case EDID_DETAIL_MONITOR_SERIAL:
-				break;
-			case EDID_DETAIL_MONITOR_STRING:
-				break;
-			case EDID_DETAIL_MONITOR_RANGE:
-				/* Get monitor range data */
-				break;
-			case EDID_DETAIL_MONITOR_NAME:
-				break;
-			case EDID_DETAIL_MONITOR_CPDATA:
-				break;
-			case EDID_DETAIL_STD_MODES:
-				for (j = 0; j < 6; i++) {
-					struct std_timing *std;
-					struct drm_display_mode *newmode;
+		/* In 1.0, only timings are allowed */
+		if (!timing->pixel_clock && edid->version == 1 &&
+			edid->revision == 0)
+			continue;
 
-					std = &data->data.timings[j];
-					newmode = drm_mode_std(dev, std,
-							       edid->revision,
-							       timing_level);
-					if (newmode) {
-						drm_mode_probed_add(connector, newmode);
-						modes++;
-					}
-				}
-				break;
-			default:
-				break;
-			}
-		} else {
-			newmode = drm_mode_detailed(dev, edid, timing, quirks);
-			if (!newmode)
-				continue;
-
-			/* First detailed mode is preferred */
-			if (i == 0 && (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING))
-				newmode->type |= DRM_MODE_TYPE_PREFERRED;
-			drm_mode_probed_add(connector, newmode);
-
-			modes++;
-		}
+		modes += add_detailed_modes(connector, timing, edid, quirks,
+					    preferred);
 	}
 
 	return modes;
 }
+
 /**
  * add_detailed_mode_eedid - get detailed mode info from addtional timing
  * 			EDID block
@@ -920,12 +1045,9 @@
 static int add_detailed_info_eedid(struct drm_connector *connector,
 			     struct edid *edid, u32 quirks)
 {
-	struct drm_device *dev = connector->dev;
-	int i, j, modes = 0;
+	int i, modes = 0;
 	char *edid_ext = NULL;
 	struct detailed_timing *timing;
-	struct detailed_non_pixel *data;
-	struct drm_display_mode *newmode;
 	int edid_ext_num;
 	int start_offset, end_offset;
 	int timing_level;
@@ -976,51 +1098,7 @@
 	for (i = start_offset; i < end_offset;
 			i += sizeof(struct detailed_timing)) {
 		timing = (struct detailed_timing *)(edid_ext + i);
-		data = &timing->data.other_data;
-		/* Detailed mode timing */
-		if (timing->pixel_clock) {
-			newmode = drm_mode_detailed(dev, edid, timing, quirks);
-			if (!newmode)
-				continue;
-
-			drm_mode_probed_add(connector, newmode);
-
-			modes++;
-			continue;
-		}
-
-		/* Other timing or info */
-		switch (data->type) {
-		case EDID_DETAIL_MONITOR_SERIAL:
-			break;
-		case EDID_DETAIL_MONITOR_STRING:
-			break;
-		case EDID_DETAIL_MONITOR_RANGE:
-			/* Get monitor range data */
-			break;
-		case EDID_DETAIL_MONITOR_NAME:
-			break;
-		case EDID_DETAIL_MONITOR_CPDATA:
-			break;
-		case EDID_DETAIL_STD_MODES:
-			/* Five modes per detailed section */
-			for (j = 0; j < 5; i++) {
-				struct std_timing *std;
-				struct drm_display_mode *newmode;
-
-				std = &data->data.timings[j];
-				newmode = drm_mode_std(dev, std,
-						       edid->revision,
-						       timing_level);
-				if (newmode) {
-					drm_mode_probed_add(connector, newmode);
-					modes++;
-				}
-			}
-			break;
-		default:
-			break;
-		}
+		modes += add_detailed_modes(connector, timing, edid, quirks, 0);
 	}
 
 	return modes;
@@ -1066,19 +1144,19 @@
 			     struct i2c_adapter *adapter,
 			     char *buf, int len)
 {
-	int ret;
+	int i;
 
-	ret = drm_do_probe_ddc_edid(adapter, buf, len);
-	if (ret != 0) {
-		goto end;
+	for (i = 0; i < 4; i++) {
+		if (drm_do_probe_ddc_edid(adapter, buf, len))
+			return -1;
+		if (edid_is_valid((struct edid *)buf))
+			return 0;
 	}
-	if (!edid_is_valid((struct edid *)buf)) {
-		dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n",
-			 drm_get_connector_name(connector));
-		ret = -1;
-	}
-end:
-	return ret;
+
+	/* repeated checksum failures; warn, but carry on */
+	dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n",
+		 drm_get_connector_name(connector));
+	return -1;
 }
 
 /**
@@ -1296,6 +1374,8 @@
 					ptr->vdisplay > vdisplay)
 				continue;
 		}
+		if (drm_mode_vrefresh(ptr) > 61)
+			continue;
 		mode = drm_mode_duplicate(dev, ptr);
 		if (mode) {
 			drm_mode_probed_add(connector, mode);
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 65ef011..1b49fa0 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -373,11 +373,9 @@
 					mutex_unlock(&dev->mode_config.mutex);
 				}
 			}
-			if (dpms_mode == DRM_MODE_DPMS_OFF) {
-				mutex_lock(&dev->mode_config.mutex);
-				crtc_funcs->dpms(crtc, dpms_mode);
-				mutex_unlock(&dev->mode_config.mutex);
-			}
+			mutex_lock(&dev->mode_config.mutex);
+			crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
+			mutex_unlock(&dev->mode_config.mutex);
 		}
 	}
 }
@@ -385,18 +383,23 @@
 int drm_fb_helper_blank(int blank, struct fb_info *info)
 {
 	switch (blank) {
+	/* Display: On; HSync: On, VSync: On */
 	case FB_BLANK_UNBLANK:
 		drm_fb_helper_on(info);
 		break;
+	/* Display: Off; HSync: On, VSync: On */
 	case FB_BLANK_NORMAL:
-		drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
+		drm_fb_helper_off(info, DRM_MODE_DPMS_ON);
 		break;
+	/* Display: Off; HSync: Off, VSync: On */
 	case FB_BLANK_HSYNC_SUSPEND:
 		drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
 		break;
+	/* Display: Off; HSync: On, VSync: Off */
 	case FB_BLANK_VSYNC_SUSPEND:
 		drm_fb_helper_off(info, DRM_MODE_DPMS_SUSPEND);
 		break;
+	/* Display: Off; HSync: Off, VSync: Off */
 	case FB_BLANK_POWERDOWN:
 		drm_fb_helper_off(info, DRM_MODE_DPMS_OFF);
 		break;
@@ -905,8 +908,13 @@
 
 	if (new_fb) {
 		info->var.pixclock = 0;
-		if (register_framebuffer(info) < 0)
+		ret = fb_alloc_cmap(&info->cmap, modeset->crtc->gamma_size, 0);
+		if (ret)
+			return ret;
+		if (register_framebuffer(info) < 0) {
+			fb_dealloc_cmap(&info->cmap);
 			return -EINVAL;
+		}
 	} else {
 		drm_fb_helper_set_par(info);
 	}
@@ -936,6 +944,7 @@
 		unregister_sysrq_key('v', &sysrq_drm_fb_helper_restore_op);
 	}
 	drm_fb_helper_crtc_free(helper);
+	fb_dealloc_cmap(&helper->fb->fbdev->cmap);
 }
 EXPORT_SYMBOL(drm_fb_helper_free);
 
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 251bc0e..08d14df 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -257,6 +257,9 @@
 
 	INIT_LIST_HEAD(&priv->lhead);
 	INIT_LIST_HEAD(&priv->fbs);
+	INIT_LIST_HEAD(&priv->event_list);
+	init_waitqueue_head(&priv->event_wait);
+	priv->event_space = 4096; /* set aside 4k for event buffer */
 
 	if (dev->driver->driver_features & DRIVER_GEM)
 		drm_gem_open(dev, priv);
@@ -297,6 +300,18 @@
 				goto out_free;
 			}
 		}
+		mutex_lock(&dev->struct_mutex);
+		if (dev->driver->master_set) {
+			ret = dev->driver->master_set(dev, priv, true);
+			if (ret) {
+				/* drop both references if this fails */
+				drm_master_put(&priv->minor->master);
+				drm_master_put(&priv->master);
+				mutex_unlock(&dev->struct_mutex);
+				goto out_free;
+			}
+		}
+		mutex_unlock(&dev->struct_mutex);
 	} else {
 		/* get a reference to the master */
 		priv->master = drm_master_get(priv->minor->master);
@@ -413,6 +428,30 @@
 	}
 }
 
+static void drm_events_release(struct drm_file *file_priv)
+{
+	struct drm_device *dev = file_priv->minor->dev;
+	struct drm_pending_event *e, *et;
+	struct drm_pending_vblank_event *v, *vt;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+
+	/* Remove pending flips */
+	list_for_each_entry_safe(v, vt, &dev->vblank_event_list, base.link)
+		if (v->base.file_priv == file_priv) {
+			list_del(&v->base.link);
+			drm_vblank_put(dev, v->pipe);
+			v->base.destroy(&v->base);
+		}
+
+	/* Remove unconsumed events */
+	list_for_each_entry_safe(e, et, &file_priv->event_list, link)
+		e->destroy(e);
+
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
 /**
  * Release file.
  *
@@ -451,6 +490,8 @@
 	if (file_priv->minor->master)
 		drm_master_release(dev, filp);
 
+	drm_events_release(file_priv);
+
 	if (dev->driver->driver_features & DRIVER_GEM)
 		drm_gem_release(dev, file_priv);
 
@@ -504,6 +545,8 @@
 
 		if (file_priv->minor->master == file_priv->master) {
 			/* drop the reference held my the minor */
+			if (dev->driver->master_drop)
+				dev->driver->master_drop(dev, file_priv, true);
 			drm_master_put(&file_priv->minor->master);
 		}
 	}
@@ -544,9 +587,74 @@
 }
 EXPORT_SYMBOL(drm_release);
 
-/** No-op. */
+static bool
+drm_dequeue_event(struct drm_file *file_priv,
+		  size_t total, size_t max, struct drm_pending_event **out)
+{
+	struct drm_device *dev = file_priv->minor->dev;
+	struct drm_pending_event *e;
+	unsigned long flags;
+	bool ret = false;
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+
+	*out = NULL;
+	if (list_empty(&file_priv->event_list))
+		goto out;
+	e = list_first_entry(&file_priv->event_list,
+			     struct drm_pending_event, link);
+	if (e->event->length + total > max)
+		goto out;
+
+	file_priv->event_space += e->event->length;
+	list_del(&e->link);
+	*out = e;
+	ret = true;
+
+out:
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+	return ret;
+}
+
+ssize_t drm_read(struct file *filp, char __user *buffer,
+		 size_t count, loff_t *offset)
+{
+	struct drm_file *file_priv = filp->private_data;
+	struct drm_pending_event *e;
+	size_t total;
+	ssize_t ret;
+
+	ret = wait_event_interruptible(file_priv->event_wait,
+				       !list_empty(&file_priv->event_list));
+	if (ret < 0)
+		return ret;
+
+	total = 0;
+	while (drm_dequeue_event(file_priv, total, count, &e)) {
+		if (copy_to_user(buffer + total,
+				 e->event, e->event->length)) {
+			total = -EFAULT;
+			break;
+		}
+
+		total += e->event->length;
+		e->destroy(e);
+	}
+
+	return total;
+}
+EXPORT_SYMBOL(drm_read);
+
 unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait)
 {
-	return 0;
+	struct drm_file *file_priv = filp->private_data;
+	unsigned int mask = 0;
+
+	poll_wait(filp, &file_priv->event_wait, wait);
+
+	if (!list_empty(&file_priv->event_list))
+		mask |= POLLIN | POLLRDNORM;
+
+	return mask;
 }
 EXPORT_SYMBOL(drm_poll);
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 0a6f0b3..7998ee6 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -429,15 +429,21 @@
 
 	spin_lock_irqsave(&dev->vbl_lock, irqflags);
 	/* Going from 0->1 means we have to enable interrupts again */
-	if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 &&
-	    !dev->vblank_enabled[crtc]) {
-		ret = dev->driver->enable_vblank(dev, crtc);
-		DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret);
-		if (ret)
+	if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) {
+		if (!dev->vblank_enabled[crtc]) {
+			ret = dev->driver->enable_vblank(dev, crtc);
+			DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret);
+			if (ret)
+				atomic_dec(&dev->vblank_refcount[crtc]);
+			else {
+				dev->vblank_enabled[crtc] = 1;
+				drm_update_vblank_count(dev, crtc);
+			}
+		}
+	} else {
+		if (!dev->vblank_enabled[crtc]) {
 			atomic_dec(&dev->vblank_refcount[crtc]);
-		else {
-			dev->vblank_enabled[crtc] = 1;
-			drm_update_vblank_count(dev, crtc);
+			ret = -EINVAL;
 		}
 	}
 	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
@@ -464,6 +470,18 @@
 }
 EXPORT_SYMBOL(drm_vblank_put);
 
+void drm_vblank_off(struct drm_device *dev, int crtc)
+{
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&dev->vbl_lock, irqflags);
+	DRM_WAKEUP(&dev->vbl_queue[crtc]);
+	dev->vblank_enabled[crtc] = 0;
+	dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc);
+	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
+}
+EXPORT_SYMBOL(drm_vblank_off);
+
 /**
  * drm_vblank_pre_modeset - account for vblanks across mode sets
  * @dev: DRM device
@@ -550,6 +568,63 @@
 	return ret;
 }
 
+static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
+				  union drm_wait_vblank *vblwait,
+				  struct drm_file *file_priv)
+{
+	struct drm_pending_vblank_event *e;
+	struct timeval now;
+	unsigned long flags;
+	unsigned int seq;
+
+	e = kzalloc(sizeof *e, GFP_KERNEL);
+	if (e == NULL)
+		return -ENOMEM;
+
+	e->pipe = pipe;
+	e->event.base.type = DRM_EVENT_VBLANK;
+	e->event.base.length = sizeof e->event;
+	e->event.user_data = vblwait->request.signal;
+	e->base.event = &e->event.base;
+	e->base.file_priv = file_priv;
+	e->base.destroy = (void (*) (struct drm_pending_event *)) kfree;
+
+	do_gettimeofday(&now);
+	spin_lock_irqsave(&dev->event_lock, flags);
+
+	if (file_priv->event_space < sizeof e->event) {
+		spin_unlock_irqrestore(&dev->event_lock, flags);
+		kfree(e);
+		return -ENOMEM;
+	}
+
+	file_priv->event_space -= sizeof e->event;
+	seq = drm_vblank_count(dev, pipe);
+	if ((vblwait->request.type & _DRM_VBLANK_NEXTONMISS) &&
+	    (seq - vblwait->request.sequence) <= (1 << 23)) {
+		vblwait->request.sequence = seq + 1;
+		vblwait->reply.sequence = vblwait->request.sequence;
+	}
+
+	DRM_DEBUG("event on vblank count %d, current %d, crtc %d\n",
+		  vblwait->request.sequence, seq, pipe);
+
+	e->event.sequence = vblwait->request.sequence;
+	if ((seq - vblwait->request.sequence) <= (1 << 23)) {
+		e->event.tv_sec = now.tv_sec;
+		e->event.tv_usec = now.tv_usec;
+		drm_vblank_put(dev, e->pipe);
+		list_add_tail(&e->base.link, &e->base.file_priv->event_list);
+		wake_up_interruptible(&e->base.file_priv->event_wait);
+	} else {
+		list_add_tail(&e->base.link, &dev->vblank_event_list);
+	}
+
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+
+	return 0;
+}
+
 /**
  * Wait for VBLANK.
  *
@@ -609,6 +684,9 @@
 		goto done;
 	}
 
+	if (flags & _DRM_VBLANK_EVENT)
+		return drm_queue_vblank_event(dev, crtc, vblwait, file_priv);
+
 	if ((flags & _DRM_VBLANK_NEXTONMISS) &&
 	    (seq - vblwait->request.sequence) <= (1<<23)) {
 		vblwait->request.sequence = seq + 1;
@@ -641,6 +719,38 @@
 	return ret;
 }
 
+void drm_handle_vblank_events(struct drm_device *dev, int crtc)
+{
+	struct drm_pending_vblank_event *e, *t;
+	struct timeval now;
+	unsigned long flags;
+	unsigned int seq;
+
+	do_gettimeofday(&now);
+	seq = drm_vblank_count(dev, crtc);
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+
+	list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) {
+		if (e->pipe != crtc)
+			continue;
+		if ((seq - e->event.sequence) > (1<<23))
+			continue;
+
+		DRM_DEBUG("vblank event on %d, current %d\n",
+			  e->event.sequence, seq);
+
+		e->event.sequence = seq;
+		e->event.tv_sec = now.tv_sec;
+		e->event.tv_usec = now.tv_usec;
+		drm_vblank_put(dev, e->pipe);
+		list_move_tail(&e->base.link, &e->base.file_priv->event_list);
+		wake_up_interruptible(&e->base.file_priv->event_wait);
+	}
+
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
 /**
  * drm_handle_vblank - handle a vblank event
  * @dev: DRM device
@@ -651,7 +761,11 @@
  */
 void drm_handle_vblank(struct drm_device *dev, int crtc)
 {
+	if (!dev->num_crtcs)
+		return;
+
 	atomic_inc(&dev->_vblank_count[crtc]);
 	DRM_WAKEUP(&dev->vbl_queue[crtc]);
+	drm_handle_vblank_events(dev, crtc);
 }
 EXPORT_SYMBOL(drm_handle_vblank);
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 97dc5a4..d7d7eac 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -226,6 +226,44 @@
 }
 EXPORT_SYMBOL(drm_mm_get_block_generic);
 
+struct drm_mm_node *drm_mm_get_block_range_generic(struct drm_mm_node *node,
+						unsigned long size,
+						unsigned alignment,
+						unsigned long start,
+						unsigned long end,
+						int atomic)
+{
+	struct drm_mm_node *align_splitoff = NULL;
+	unsigned tmp = 0;
+	unsigned wasted = 0;
+
+	if (node->start < start)
+		wasted += start - node->start;
+	if (alignment)
+		tmp = ((node->start + wasted) % alignment);
+
+	if (tmp)
+		wasted += alignment - tmp;
+	if (wasted) {
+		align_splitoff = drm_mm_split_at_start(node, wasted, atomic);
+		if (unlikely(align_splitoff == NULL))
+			return NULL;
+	}
+
+	if (node->size == size) {
+		list_del_init(&node->fl_entry);
+		node->free = 0;
+	} else {
+		node = drm_mm_split_at_start(node, size, atomic);
+	}
+
+	if (align_splitoff)
+		drm_mm_put_block(align_splitoff);
+
+	return node;
+}
+EXPORT_SYMBOL(drm_mm_get_block_range_generic);
+
 /*
  * Put a block. Merge with the previous and / or next block if they are free.
  * Otherwise add to the free stack.
@@ -331,6 +369,56 @@
 }
 EXPORT_SYMBOL(drm_mm_search_free);
 
+struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm,
+						unsigned long size,
+						unsigned alignment,
+						unsigned long start,
+						unsigned long end,
+						int best_match)
+{
+	struct list_head *list;
+	const struct list_head *free_stack = &mm->fl_entry;
+	struct drm_mm_node *entry;
+	struct drm_mm_node *best;
+	unsigned long best_size;
+	unsigned wasted;
+
+	best = NULL;
+	best_size = ~0UL;
+
+	list_for_each(list, free_stack) {
+		entry = list_entry(list, struct drm_mm_node, fl_entry);
+		wasted = 0;
+
+		if (entry->size < size)
+			continue;
+
+		if (entry->start > end || (entry->start+entry->size) < start)
+			continue;
+
+		if (entry->start < start)
+			wasted += start - entry->start;
+
+		if (alignment) {
+			register unsigned tmp = (entry->start + wasted) % alignment;
+			if (tmp)
+				wasted += alignment - tmp;
+		}
+
+		if (entry->size >= size + wasted) {
+			if (!best_match)
+				return entry;
+			if (size < best_size) {
+				best = entry;
+				best_size = entry->size;
+			}
+		}
+	}
+
+	return best;
+}
+EXPORT_SYMBOL(drm_mm_search_free_in_range);
+
 int drm_mm_clean(struct drm_mm * mm)
 {
 	struct list_head *head = &mm->ml_entry;
@@ -381,6 +469,26 @@
 }
 EXPORT_SYMBOL(drm_mm_takedown);
 
+void drm_mm_debug_table(struct drm_mm *mm, const char *prefix)
+{
+	struct drm_mm_node *entry;
+	int total_used = 0, total_free = 0, total = 0;
+
+	list_for_each_entry(entry, &mm->ml_entry, ml_entry) {
+		printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8ld: %s\n",
+			prefix, entry->start, entry->start + entry->size,
+			entry->size, entry->free ? "free" : "used");
+		total += entry->size;
+		if (entry->free)
+			total_free += entry->size;
+		else
+			total_used += entry->size;
+	}
+	printk(KERN_DEBUG "%s total: %d, used %d free %d\n", prefix, total,
+		total_used, total_free);
+}
+EXPORT_SYMBOL(drm_mm_debug_table);
+
 #if defined(CONFIG_DEBUG_FS)
 int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm)
 {
@@ -395,7 +503,7 @@
 		else
 			total_used += entry->size;
 	}
-	seq_printf(m, "total: %d, used %d free %d\n", total, total_free, total_used);
+	seq_printf(m, "total: %d, used %d free %d\n", total, total_used, total_free);
 	return 0;
 }
 EXPORT_SYMBOL(drm_mm_dump_table);
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 51f6772..6d81a02 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -553,6 +553,32 @@
 }
 EXPORT_SYMBOL(drm_mode_height);
 
+/** drm_mode_hsync - get the hsync of a mode
+ * @mode: mode
+ *
+ * LOCKING:
+ * None.
+ *
+ * Return @modes's hsync rate in kHz, rounded to the nearest int.
+ */
+int drm_mode_hsync(struct drm_display_mode *mode)
+{
+	unsigned int calc_val;
+
+	if (mode->hsync)
+		return mode->hsync;
+
+	if (mode->htotal < 0)
+		return 0;
+
+	calc_val = (mode->clock * 1000) / mode->htotal; /* hsync in Hz */
+	calc_val += 500;				/* round to 1000Hz */
+	calc_val /= 1000;				/* truncate to kHz */
+
+	return calc_val;
+}
+EXPORT_SYMBOL(drm_mode_hsync);
+
 /**
  * drm_mode_vrefresh - get the vrefresh of a mode
  * @mode: mode
@@ -560,7 +586,7 @@
  * LOCKING:
  * None.
  *
- * Return @mode's vrefresh rate or calculate it if necessary.
+ * Return @mode's vrefresh rate in Hz or calculate it if necessary.
  *
  * FIXME: why is this needed?  shouldn't vrefresh be set already?
  *
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index 55bb8a8..ad73e14 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -128,6 +128,7 @@
 	kref_get(&master->refcount);
 	return master;
 }
+EXPORT_SYMBOL(drm_master_get);
 
 static void drm_master_destroy(struct kref *kref)
 {
@@ -170,10 +171,13 @@
 	kref_put(&(*master)->refcount, drm_master_destroy);
 	*master = NULL;
 }
+EXPORT_SYMBOL(drm_master_put);
 
 int drm_setmaster_ioctl(struct drm_device *dev, void *data,
 			struct drm_file *file_priv)
 {
+	int ret = 0;
+
 	if (file_priv->is_master)
 		return 0;
 
@@ -188,6 +192,13 @@
 		mutex_lock(&dev->struct_mutex);
 		file_priv->minor->master = drm_master_get(file_priv->master);
 		file_priv->is_master = 1;
+		if (dev->driver->master_set) {
+			ret = dev->driver->master_set(dev, file_priv, false);
+			if (unlikely(ret != 0)) {
+				file_priv->is_master = 0;
+				drm_master_put(&file_priv->minor->master);
+			}
+		}
 		mutex_unlock(&dev->struct_mutex);
 	}
 
@@ -204,6 +215,8 @@
 		return -EINVAL;
 
 	mutex_lock(&dev->struct_mutex);
+	if (dev->driver->master_drop)
+		dev->driver->master_drop(dev, file_priv, false);
 	drm_master_put(&file_priv->minor->master);
 	file_priv->is_master = 0;
 	mutex_unlock(&dev->struct_mutex);
@@ -220,9 +233,11 @@
 	INIT_LIST_HEAD(&dev->ctxlist);
 	INIT_LIST_HEAD(&dev->vmalist);
 	INIT_LIST_HEAD(&dev->maplist);
+	INIT_LIST_HEAD(&dev->vblank_event_list);
 
 	spin_lock_init(&dev->count_lock);
 	spin_lock_init(&dev->drw_lock);
+	spin_lock_init(&dev->event_lock);
 	init_timer(&dev->timer);
 	mutex_init(&dev->struct_mutex);
 	mutex_init(&dev->ctxlist_mutex);
diff --git a/drivers/gpu/drm/i2c/Makefile b/drivers/gpu/drm/i2c/Makefile
new file mode 100644
index 0000000..6d2abaf
--- /dev/null
+++ b/drivers/gpu/drm/i2c/Makefile
@@ -0,0 +1,4 @@
+ccflags-y := -Iinclude/drm
+
+ch7006-y := ch7006_drv.o ch7006_mode.o
+obj-$(CONFIG_DRM_I2C_CH7006) += ch7006.o
diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c
new file mode 100644
index 0000000..9422a74
--- /dev/null
+++ b/drivers/gpu/drm/i2c/ch7006_drv.c
@@ -0,0 +1,531 @@
+/*
+ * Copyright (C) 2009 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "ch7006_priv.h"
+
+/* DRM encoder functions */
+
+static void ch7006_encoder_set_config(struct drm_encoder *encoder,
+				      void *params)
+{
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+
+	priv->params = params;
+}
+
+static void ch7006_encoder_destroy(struct drm_encoder *encoder)
+{
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+
+	drm_property_destroy(encoder->dev, priv->scale_property);
+
+	kfree(priv);
+	to_encoder_slave(encoder)->slave_priv = NULL;
+
+	drm_i2c_encoder_destroy(encoder);
+}
+
+static void  ch7006_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	struct ch7006_state *state = &priv->state;
+
+	ch7006_dbg(client, "\n");
+
+	if (mode == priv->last_dpms)
+		return;
+	priv->last_dpms = mode;
+
+	ch7006_setup_power_state(encoder);
+
+	ch7006_load_reg(client, state, CH7006_POWER);
+}
+
+static void ch7006_encoder_save(struct drm_encoder *encoder)
+{
+	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+
+	ch7006_dbg(client, "\n");
+
+	ch7006_state_save(client, &priv->saved_state);
+}
+
+static void ch7006_encoder_restore(struct drm_encoder *encoder)
+{
+	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+
+	ch7006_dbg(client, "\n");
+
+	ch7006_state_load(client, &priv->saved_state);
+}
+
+static bool ch7006_encoder_mode_fixup(struct drm_encoder *encoder,
+				      struct drm_display_mode *mode,
+				      struct drm_display_mode *adjusted_mode)
+{
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+
+	/* The ch7006 is painfully picky with the input timings so no
+	 * custom modes for now... */
+
+	priv->mode = ch7006_lookup_mode(encoder, mode);
+
+	return !!priv->mode;
+}
+
+static int ch7006_encoder_mode_valid(struct drm_encoder *encoder,
+				     struct drm_display_mode *mode)
+{
+	if (ch7006_lookup_mode(encoder, mode))
+		return MODE_OK;
+	else
+		return MODE_BAD;
+}
+
+static void ch7006_encoder_mode_set(struct drm_encoder *encoder,
+				     struct drm_display_mode *drm_mode,
+				     struct drm_display_mode *adjusted_mode)
+{
+	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	struct ch7006_encoder_params *params = priv->params;
+	struct ch7006_state *state = &priv->state;
+	uint8_t *regs = state->regs;
+	struct ch7006_mode *mode = priv->mode;
+	struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm];
+	int start_active;
+
+	ch7006_dbg(client, "\n");
+
+	regs[CH7006_DISPMODE] = norm->dispmode | mode->dispmode;
+	regs[CH7006_BWIDTH] = 0;
+	regs[CH7006_INPUT_FORMAT] = bitf(CH7006_INPUT_FORMAT_FORMAT,
+					 params->input_format);
+
+	regs[CH7006_CLKMODE] = CH7006_CLKMODE_SUBC_LOCK
+		| bitf(CH7006_CLKMODE_XCM, params->xcm)
+		| bitf(CH7006_CLKMODE_PCM, params->pcm);
+	if (params->clock_mode)
+		regs[CH7006_CLKMODE] |= CH7006_CLKMODE_MASTER;
+	if (params->clock_edge)
+		regs[CH7006_CLKMODE] |= CH7006_CLKMODE_POS_EDGE;
+
+	start_active = (drm_mode->htotal & ~0x7) - (drm_mode->hsync_start & ~0x7);
+	regs[CH7006_POV] = bitf(CH7006_POV_START_ACTIVE_8, start_active);
+	regs[CH7006_START_ACTIVE] = bitf(CH7006_START_ACTIVE_0, start_active);
+
+	regs[CH7006_INPUT_SYNC] = 0;
+	if (params->sync_direction)
+		regs[CH7006_INPUT_SYNC] |= CH7006_INPUT_SYNC_OUTPUT;
+	if (params->sync_encoding)
+		regs[CH7006_INPUT_SYNC] |= CH7006_INPUT_SYNC_EMBEDDED;
+	if (drm_mode->flags & DRM_MODE_FLAG_PVSYNC)
+		regs[CH7006_INPUT_SYNC] |= CH7006_INPUT_SYNC_PVSYNC;
+	if (drm_mode->flags & DRM_MODE_FLAG_PHSYNC)
+		regs[CH7006_INPUT_SYNC] |= CH7006_INPUT_SYNC_PHSYNC;
+
+	regs[CH7006_DETECT] = 0;
+	regs[CH7006_BCLKOUT] = 0;
+
+	regs[CH7006_SUBC_INC3] = 0;
+	if (params->pout_level)
+		regs[CH7006_SUBC_INC3] |= CH7006_SUBC_INC3_POUT_3_3V;
+
+	regs[CH7006_SUBC_INC4] = 0;
+	if (params->active_detect)
+		regs[CH7006_SUBC_INC4] |= CH7006_SUBC_INC4_DS_INPUT;
+
+	regs[CH7006_PLL_CONTROL] = priv->saved_state.regs[CH7006_PLL_CONTROL];
+
+	ch7006_setup_levels(encoder);
+	ch7006_setup_subcarrier(encoder);
+	ch7006_setup_pll(encoder);
+	ch7006_setup_power_state(encoder);
+	ch7006_setup_properties(encoder);
+
+	ch7006_state_load(client, state);
+}
+
+static enum drm_connector_status ch7006_encoder_detect(struct drm_encoder *encoder,
+						       struct drm_connector *connector)
+{
+	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	struct ch7006_state *state = &priv->state;
+	int det;
+
+	ch7006_dbg(client, "\n");
+
+	ch7006_save_reg(client, state, CH7006_DETECT);
+	ch7006_save_reg(client, state, CH7006_POWER);
+	ch7006_save_reg(client, state, CH7006_CLKMODE);
+
+	ch7006_write(client, CH7006_POWER, CH7006_POWER_RESET |
+					   bitfs(CH7006_POWER_LEVEL, NORMAL));
+	ch7006_write(client, CH7006_CLKMODE, CH7006_CLKMODE_MASTER);
+
+	ch7006_write(client, CH7006_DETECT, CH7006_DETECT_SENSE);
+
+	ch7006_write(client, CH7006_DETECT, 0);
+
+	det = ch7006_read(client, CH7006_DETECT);
+
+	ch7006_load_reg(client, state, CH7006_CLKMODE);
+	ch7006_load_reg(client, state, CH7006_POWER);
+	ch7006_load_reg(client, state, CH7006_DETECT);
+
+	if ((det & (CH7006_DETECT_SVIDEO_Y_TEST|
+		    CH7006_DETECT_SVIDEO_C_TEST|
+		    CH7006_DETECT_CVBS_TEST)) == 0)
+		priv->subconnector = DRM_MODE_SUBCONNECTOR_SCART;
+	else if ((det & (CH7006_DETECT_SVIDEO_Y_TEST|
+			 CH7006_DETECT_SVIDEO_C_TEST)) == 0)
+		priv->subconnector = DRM_MODE_SUBCONNECTOR_SVIDEO;
+	else if ((det & CH7006_DETECT_CVBS_TEST) == 0)
+		priv->subconnector = DRM_MODE_SUBCONNECTOR_Composite;
+	else
+		priv->subconnector = DRM_MODE_SUBCONNECTOR_Unknown;
+
+	drm_connector_property_set_value(connector,
+			encoder->dev->mode_config.tv_subconnector_property,
+							priv->subconnector);
+
+	return priv->subconnector ? connector_status_connected :
+					connector_status_disconnected;
+}
+
+static int ch7006_encoder_get_modes(struct drm_encoder *encoder,
+				    struct drm_connector *connector)
+{
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	struct ch7006_mode *mode;
+	int n = 0;
+
+	for (mode = ch7006_modes; mode->mode.clock; mode++) {
+		if (~mode->valid_scales & 1<<priv->scale ||
+		    ~mode->valid_norms & 1<<priv->norm)
+			continue;
+
+		drm_mode_probed_add(connector,
+				drm_mode_duplicate(encoder->dev, &mode->mode));
+
+		n++;
+	}
+
+	return n;
+}
+
+static int ch7006_encoder_create_resources(struct drm_encoder *encoder,
+					   struct drm_connector *connector)
+{
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct drm_mode_config *conf = &dev->mode_config;
+
+	drm_mode_create_tv_properties(dev, NUM_TV_NORMS, ch7006_tv_norm_names);
+
+	priv->scale_property = drm_property_create(dev, DRM_MODE_PROP_RANGE,
+						   "scale", 2);
+	priv->scale_property->values[0] = 0;
+	priv->scale_property->values[1] = 2;
+
+	drm_connector_attach_property(connector, conf->tv_select_subconnector_property,
+				      priv->select_subconnector);
+	drm_connector_attach_property(connector, conf->tv_subconnector_property,
+				      priv->subconnector);
+	drm_connector_attach_property(connector, conf->tv_left_margin_property,
+				      priv->hmargin);
+	drm_connector_attach_property(connector, conf->tv_bottom_margin_property,
+				      priv->vmargin);
+	drm_connector_attach_property(connector, conf->tv_mode_property,
+				      priv->norm);
+	drm_connector_attach_property(connector, conf->tv_brightness_property,
+				      priv->brightness);
+	drm_connector_attach_property(connector, conf->tv_contrast_property,
+				      priv->contrast);
+	drm_connector_attach_property(connector, conf->tv_flicker_reduction_property,
+				      priv->flicker);
+	drm_connector_attach_property(connector, priv->scale_property,
+				      priv->scale);
+
+	return 0;
+}
+
+static int ch7006_encoder_set_property(struct drm_encoder *encoder,
+				       struct drm_connector *connector,
+				       struct drm_property *property,
+				       uint64_t val)
+{
+	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	struct ch7006_state *state = &priv->state;
+	struct drm_mode_config *conf = &encoder->dev->mode_config;
+	struct drm_crtc *crtc = encoder->crtc;
+	bool modes_changed = false;
+
+	ch7006_dbg(client, "\n");
+
+	if (property == conf->tv_select_subconnector_property) {
+		priv->select_subconnector = val;
+
+		ch7006_setup_power_state(encoder);
+
+		ch7006_load_reg(client, state, CH7006_POWER);
+
+	} else if (property == conf->tv_left_margin_property) {
+		priv->hmargin = val;
+
+		ch7006_setup_properties(encoder);
+
+		ch7006_load_reg(client, state, CH7006_POV);
+		ch7006_load_reg(client, state, CH7006_HPOS);
+
+	} else if (property == conf->tv_bottom_margin_property) {
+		priv->vmargin = val;
+
+		ch7006_setup_properties(encoder);
+
+		ch7006_load_reg(client, state, CH7006_POV);
+		ch7006_load_reg(client, state, CH7006_VPOS);
+
+	} else if (property == conf->tv_mode_property) {
+		if (connector->dpms != DRM_MODE_DPMS_OFF)
+			return -EINVAL;
+
+		priv->norm = val;
+
+		modes_changed = true;
+
+	} else if (property == conf->tv_brightness_property) {
+		priv->brightness = val;
+
+		ch7006_setup_levels(encoder);
+
+		ch7006_load_reg(client, state, CH7006_BLACK_LEVEL);
+
+	} else if (property == conf->tv_contrast_property) {
+		priv->contrast = val;
+
+		ch7006_setup_properties(encoder);
+
+		ch7006_load_reg(client, state, CH7006_CONTRAST);
+
+	} else if (property == conf->tv_flicker_reduction_property) {
+		priv->flicker = val;
+
+		ch7006_setup_properties(encoder);
+
+		ch7006_load_reg(client, state, CH7006_FFILTER);
+
+	} else if (property == priv->scale_property) {
+		if (connector->dpms != DRM_MODE_DPMS_OFF)
+			return -EINVAL;
+
+		priv->scale = val;
+
+		modes_changed = true;
+
+	} else {
+		return -EINVAL;
+	}
+
+	if (modes_changed) {
+		drm_helper_probe_single_connector_modes(connector, 0, 0);
+
+		/* Disable the crtc to ensure a full modeset is
+		 * performed whenever it's turned on again. */
+		if (crtc) {
+			struct drm_mode_set modeset = {
+				.crtc = crtc,
+			};
+
+			crtc->funcs->set_config(&modeset);
+		}
+	}
+
+	return 0;
+}
+
+static struct drm_encoder_slave_funcs ch7006_encoder_funcs = {
+	.set_config = ch7006_encoder_set_config,
+	.destroy = ch7006_encoder_destroy,
+	.dpms = ch7006_encoder_dpms,
+	.save = ch7006_encoder_save,
+	.restore = ch7006_encoder_restore,
+	.mode_fixup = ch7006_encoder_mode_fixup,
+	.mode_valid = ch7006_encoder_mode_valid,
+	.mode_set = ch7006_encoder_mode_set,
+	.detect = ch7006_encoder_detect,
+	.get_modes = ch7006_encoder_get_modes,
+	.create_resources = ch7006_encoder_create_resources,
+	.set_property = ch7006_encoder_set_property,
+};
+
+
+/* I2C driver functions */
+
+static int ch7006_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+	uint8_t addr = CH7006_VERSION_ID;
+	uint8_t val;
+	int ret;
+
+	ch7006_dbg(client, "\n");
+
+	ret = i2c_master_send(client, &addr, sizeof(addr));
+	if (ret < 0)
+		goto fail;
+
+	ret = i2c_master_recv(client, &val, sizeof(val));
+	if (ret < 0)
+		goto fail;
+
+	ch7006_info(client, "Detected version ID: %x\n", val);
+
+	return 0;
+
+fail:
+	ch7006_err(client, "Error %d reading version ID\n", ret);
+
+	return -ENODEV;
+}
+
+static int ch7006_remove(struct i2c_client *client)
+{
+	ch7006_dbg(client, "\n");
+
+	return 0;
+}
+
+static int ch7006_encoder_init(struct i2c_client *client,
+			       struct drm_device *dev,
+			       struct drm_encoder_slave *encoder)
+{
+	struct ch7006_priv *priv;
+	int i;
+
+	ch7006_dbg(client, "\n");
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	encoder->slave_priv = priv;
+	encoder->slave_funcs = &ch7006_encoder_funcs;
+
+	priv->norm = TV_NORM_PAL;
+	priv->select_subconnector = DRM_MODE_SUBCONNECTOR_Automatic;
+	priv->subconnector = DRM_MODE_SUBCONNECTOR_Unknown;
+	priv->scale = 1;
+	priv->contrast = 50;
+	priv->brightness = 50;
+	priv->flicker = 50;
+	priv->hmargin = 50;
+	priv->vmargin = 50;
+	priv->last_dpms = -1;
+
+	if (ch7006_tv_norm) {
+		for (i = 0; i < NUM_TV_NORMS; i++) {
+			if (!strcmp(ch7006_tv_norm_names[i], ch7006_tv_norm)) {
+				priv->norm = i;
+				break;
+			}
+		}
+
+		if (i == NUM_TV_NORMS)
+			ch7006_err(client, "Invalid TV norm setting \"%s\".\n",
+				   ch7006_tv_norm);
+	}
+
+	if (ch7006_scale >= 0 && ch7006_scale <= 2)
+		priv->scale = ch7006_scale;
+	else
+		ch7006_err(client, "Invalid scale setting \"%d\".\n",
+			   ch7006_scale);
+
+	return 0;
+}
+
+static struct i2c_device_id ch7006_ids[] = {
+	{ "ch7006", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ch7006_ids);
+
+static struct drm_i2c_encoder_driver ch7006_driver = {
+	.i2c_driver = {
+		.probe = ch7006_probe,
+		.remove = ch7006_remove,
+
+		.driver = {
+			.name = "ch7006",
+		},
+
+		.id_table = ch7006_ids,
+	},
+
+	.encoder_init = ch7006_encoder_init,
+};
+
+
+/* Module initialization */
+
+static int __init ch7006_init(void)
+{
+	return drm_i2c_encoder_register(THIS_MODULE, &ch7006_driver);
+}
+
+static void __exit ch7006_exit(void)
+{
+	drm_i2c_encoder_unregister(&ch7006_driver);
+}
+
+int ch7006_debug;
+module_param_named(debug, ch7006_debug, int, 0600);
+MODULE_PARM_DESC(debug, "Enable debug output.");
+
+char *ch7006_tv_norm;
+module_param_named(tv_norm, ch7006_tv_norm, charp, 0600);
+MODULE_PARM_DESC(tv_norm, "Default TV norm.\n"
+		 "\t\tSupported: PAL, PAL-M, PAL-N, PAL-Nc, PAL-60, NTSC-M, NTSC-J.\n"
+		 "\t\tDefault: PAL");
+
+int ch7006_scale = 1;
+module_param_named(scale, ch7006_scale, int, 0600);
+MODULE_PARM_DESC(scale, "Default scale.\n"
+		 "\t\tSupported: 0 -> Select video modes with a higher blanking ratio.\n"
+		 "\t\t\t1 -> Select default video modes.\n"
+		 "\t\t\t2 -> Select video modes with a lower blanking ratio.");
+
+MODULE_AUTHOR("Francisco Jerez <currojerez@riseup.net>");
+MODULE_DESCRIPTION("Chrontel ch7006 TV encoder driver");
+MODULE_LICENSE("GPL and additional rights");
+
+module_init(ch7006_init);
+module_exit(ch7006_exit);
diff --git a/drivers/gpu/drm/i2c/ch7006_mode.c b/drivers/gpu/drm/i2c/ch7006_mode.c
new file mode 100644
index 0000000..87f5445
--- /dev/null
+++ b/drivers/gpu/drm/i2c/ch7006_mode.c
@@ -0,0 +1,473 @@
+/*
+ * Copyright (C) 2009 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "ch7006_priv.h"
+
+char *ch7006_tv_norm_names[] = {
+	[TV_NORM_PAL] = "PAL",
+	[TV_NORM_PAL_M] = "PAL-M",
+	[TV_NORM_PAL_N] = "PAL-N",
+	[TV_NORM_PAL_NC] = "PAL-Nc",
+	[TV_NORM_PAL_60] = "PAL-60",
+	[TV_NORM_NTSC_M] = "NTSC-M",
+	[TV_NORM_NTSC_J] = "NTSC-J",
+};
+
+#define NTSC_LIKE_TIMINGS .vrefresh = 60 * fixed1/1.001,		\
+		.vdisplay = 480,					\
+		.vtotal = 525,						\
+		.hvirtual = 660
+
+#define PAL_LIKE_TIMINGS .vrefresh = 50 * fixed1,		\
+		.vdisplay = 576,				\
+		.vtotal = 625,					\
+		.hvirtual = 810
+
+struct ch7006_tv_norm_info ch7006_tv_norms[] = {
+	[TV_NORM_NTSC_M] = {
+		NTSC_LIKE_TIMINGS,
+		.black_level = 0.339 * fixed1,
+		.subc_freq = 3579545 * fixed1,
+		.dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, NTSC),
+		.voffset = 0,
+	},
+	[TV_NORM_NTSC_J] = {
+		NTSC_LIKE_TIMINGS,
+		.black_level = 0.286 * fixed1,
+		.subc_freq = 3579545 * fixed1,
+		.dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, NTSC_J),
+		.voffset = 0,
+	},
+	[TV_NORM_PAL] = {
+		PAL_LIKE_TIMINGS,
+		.black_level = 0.3 * fixed1,
+		.subc_freq = 4433618.75 * fixed1,
+		.dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, PAL),
+		.voffset = 0,
+	},
+	[TV_NORM_PAL_M] = {
+		NTSC_LIKE_TIMINGS,
+		.black_level = 0.339 * fixed1,
+		.subc_freq = 3575611.433 * fixed1,
+		.dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, PAL_M),
+		.voffset = 16,
+	},
+
+	/* The following modes seem to work right but they're
+	 * undocumented */
+
+	[TV_NORM_PAL_N] = {
+		PAL_LIKE_TIMINGS,
+		.black_level = 0.339 * fixed1,
+		.subc_freq = 4433618.75 * fixed1,
+		.dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, PAL),
+		.voffset = 0,
+	},
+	[TV_NORM_PAL_NC] = {
+		PAL_LIKE_TIMINGS,
+		.black_level = 0.3 * fixed1,
+		.subc_freq = 3582056.25 * fixed1,
+		.dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, PAL),
+		.voffset = 0,
+	},
+	[TV_NORM_PAL_60] = {
+		NTSC_LIKE_TIMINGS,
+		.black_level = 0.3 * fixed1,
+		.subc_freq = 4433618.75 * fixed1,
+		.dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, PAL_M),
+		.voffset = 16,
+	},
+};
+
+#define __MODE(f, hd, vd, ht, vt, hsynp, vsynp,				\
+	       subc, scale, scale_mask, norm_mask, e_hd, e_vd) {	\
+		.mode = {						\
+			.name = #hd "x" #vd,				\
+			.status = 0,					\
+			.type = DRM_MODE_TYPE_DRIVER,			\
+			.clock = f,					\
+			.hdisplay = hd,					\
+			.hsync_start = e_hd + 16,			\
+			.hsync_end = e_hd + 80,				\
+			.htotal = ht,					\
+			.hskew = 0,					\
+			.vdisplay = vd,					\
+			.vsync_start = vd + 10,				\
+			.vsync_end = vd + 26,				\
+			.vtotal = vt,					\
+			.vscan = 0,					\
+			.flags = DRM_MODE_FLAG_##hsynp##HSYNC |		\
+				DRM_MODE_FLAG_##vsynp##VSYNC,		\
+			.vrefresh = 0,					\
+		},							\
+		.enc_hdisp = e_hd,					\
+		.enc_vdisp = e_vd,					\
+		.subc_coeff = subc * fixed1,				\
+		.dispmode = bitfs(CH7006_DISPMODE_SCALING_RATIO, scale) | \
+			    bitfs(CH7006_DISPMODE_INPUT_RES, e_hd##x##e_vd), \
+		.valid_scales = scale_mask,				\
+		.valid_norms = norm_mask				\
+	 }
+
+#define MODE(f, hd, vd, ht, vt, hsynp, vsynp,				\
+	     subc, scale, scale_mask, norm_mask)			\
+	__MODE(f, hd, vd, ht, vt, hsynp, vsynp, subc, scale,		\
+	       scale_mask, norm_mask, hd, vd)
+
+#define NTSC_LIKE (1 << TV_NORM_NTSC_M | 1 << TV_NORM_NTSC_J |		\
+		   1 << TV_NORM_PAL_M | 1 << TV_NORM_PAL_60)
+
+#define PAL_LIKE (1 << TV_NORM_PAL | 1 << TV_NORM_PAL_N | 1 << TV_NORM_PAL_NC)
+
+struct ch7006_mode ch7006_modes[] = {
+	MODE(21000, 512, 384, 840, 500, N, N, 181.797557582, 5_4, 0x6, PAL_LIKE),
+	MODE(26250, 512, 384, 840, 625, N, N, 145.438046066, 1_1, 0x1, PAL_LIKE),
+	MODE(20140, 512, 384, 800, 420, N, N, 213.257083791, 5_4, 0x4, NTSC_LIKE),
+	MODE(24671, 512, 384, 784, 525, N, N, 174.0874153, 1_1, 0x3, NTSC_LIKE),
+	MODE(28125, 720, 400, 1125, 500, N, N, 135.742176298, 5_4, 0x6, PAL_LIKE),
+	MODE(34875, 720, 400, 1116, 625, N, N, 109.469496898, 1_1, 0x1, PAL_LIKE),
+	MODE(23790, 720, 400, 945, 420, N, N, 160.475642016, 5_4, 0x4, NTSC_LIKE),
+	MODE(29455, 720, 400, 936, 525, N, N, 129.614941843, 1_1, 0x3, NTSC_LIKE),
+	MODE(25000, 640, 400, 1000, 500, N, N, 152.709948279, 5_4, 0x6, PAL_LIKE),
+	MODE(31500, 640, 400, 1008, 625, N, N, 121.198371646, 1_1, 0x1, PAL_LIKE),
+	MODE(21147, 640, 400, 840, 420, N, N, 180.535097338, 5_4, 0x4, NTSC_LIKE),
+	MODE(26434, 640, 400, 840, 525, N, N, 144.42807787, 1_1, 0x2, NTSC_LIKE),
+	MODE(30210, 640, 400, 840, 600, N, N, 126.374568276, 7_8, 0x1, NTSC_LIKE),
+	MODE(21000, 640, 480, 840, 500, N, N, 181.797557582, 5_4, 0x4, PAL_LIKE),
+	MODE(26250, 640, 480, 840, 625, N, N, 145.438046066, 1_1, 0x2, PAL_LIKE),
+	MODE(31500, 640, 480, 840, 750, N, N, 121.198371646, 5_6, 0x1, PAL_LIKE),
+	MODE(24671, 640, 480, 784, 525, N, N, 174.0874153, 1_1, 0x4, NTSC_LIKE),
+	MODE(28196, 640, 480, 784, 600, N, N, 152.326488422, 7_8, 0x2, NTSC_LIKE),
+	MODE(30210, 640, 480, 800, 630, N, N, 142.171389101, 5_6, 0x1, NTSC_LIKE),
+	__MODE(29500, 720, 576, 944, 625, P, P, 145.592111636, 1_1, 0x7, PAL_LIKE, 800, 600),
+	MODE(36000, 800, 600, 960, 750, P, P, 119.304647022, 5_6, 0x6, PAL_LIKE),
+	MODE(39000, 800, 600, 936, 836, P, P, 110.127366499, 3_4, 0x1, PAL_LIKE),
+	MODE(39273, 800, 600, 1040, 630, P, P, 145.816809399, 5_6, 0x4, NTSC_LIKE),
+	MODE(43636, 800, 600, 1040, 700, P, P, 131.235128487, 3_4, 0x2, NTSC_LIKE),
+	MODE(47832, 800, 600, 1064, 750, P, P, 119.723275165, 7_10, 0x1, NTSC_LIKE),
+	{}
+};
+
+struct ch7006_mode *ch7006_lookup_mode(struct drm_encoder *encoder,
+				       struct drm_display_mode *drm_mode)
+{
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	struct ch7006_mode *mode;
+
+	for (mode = ch7006_modes; mode->mode.clock; mode++) {
+
+		if (~mode->valid_norms & 1<<priv->norm)
+			continue;
+
+		if (mode->mode.hdisplay != drm_mode->hdisplay ||
+		    mode->mode.vdisplay != drm_mode->vdisplay ||
+		    mode->mode.vtotal != drm_mode->vtotal ||
+		    mode->mode.htotal != drm_mode->htotal ||
+		    mode->mode.clock != drm_mode->clock)
+			continue;
+
+		return mode;
+	}
+
+	return NULL;
+}
+
+/* Some common HW state calculation code */
+
+void ch7006_setup_levels(struct drm_encoder *encoder)
+{
+	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	uint8_t *regs = priv->state.regs;
+	struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm];
+	int gain;
+	int black_level;
+
+	/* Set DAC_GAIN if the voltage drop between white and black is
+	 * high enough. */
+	if (norm->black_level < 339*fixed1/1000) {
+		gain = 76;
+
+		regs[CH7006_INPUT_FORMAT] |= CH7006_INPUT_FORMAT_DAC_GAIN;
+	} else {
+		gain = 71;
+
+		regs[CH7006_INPUT_FORMAT] &= ~CH7006_INPUT_FORMAT_DAC_GAIN;
+	}
+
+	black_level = round_fixed(norm->black_level*26625)/gain;
+
+	/* Correct it with the specified brightness. */
+	black_level = interpolate(90, black_level, 208, priv->brightness);
+
+	regs[CH7006_BLACK_LEVEL] = bitf(CH7006_BLACK_LEVEL_0, black_level);
+
+	ch7006_dbg(client, "black level: %d\n", black_level);
+}
+
+void ch7006_setup_subcarrier(struct drm_encoder *encoder)
+{
+	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	struct ch7006_state *state = &priv->state;
+	struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm];
+	struct ch7006_mode *mode = priv->mode;
+	uint32_t subc_inc;
+
+	subc_inc = round_fixed((mode->subc_coeff >> 8)
+			       * (norm->subc_freq >> 24));
+
+	setbitf(state, CH7006_SUBC_INC0, 28, subc_inc);
+	setbitf(state, CH7006_SUBC_INC1, 24, subc_inc);
+	setbitf(state, CH7006_SUBC_INC2, 20, subc_inc);
+	setbitf(state, CH7006_SUBC_INC3, 16, subc_inc);
+	setbitf(state, CH7006_SUBC_INC4, 12, subc_inc);
+	setbitf(state, CH7006_SUBC_INC5, 8, subc_inc);
+	setbitf(state, CH7006_SUBC_INC6, 4, subc_inc);
+	setbitf(state, CH7006_SUBC_INC7, 0, subc_inc);
+
+	ch7006_dbg(client, "subcarrier inc: %u\n", subc_inc);
+}
+
+void ch7006_setup_pll(struct drm_encoder *encoder)
+{
+	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	uint8_t *regs = priv->state.regs;
+	struct ch7006_mode *mode = priv->mode;
+	int n, best_n = 0;
+	int m, best_m = 0;
+	int freq, best_freq = 0;
+
+	for (n = 0; n < CH7006_MAXN; n++) {
+		for (m = 0; m < CH7006_MAXM; m++) {
+			freq = CH7006_FREQ0*(n+2)/(m+2);
+
+			if (abs(freq - mode->mode.clock) <
+			    abs(best_freq - mode->mode.clock)) {
+				best_freq = freq;
+				best_n = n;
+				best_m = m;
+			}
+		}
+	}
+
+	regs[CH7006_PLLOV] = bitf(CH7006_PLLOV_N_8, best_n) |
+		bitf(CH7006_PLLOV_M_8, best_m);
+
+	regs[CH7006_PLLM] = bitf(CH7006_PLLM_0, best_m);
+	regs[CH7006_PLLN] = bitf(CH7006_PLLN_0, best_n);
+
+	if (best_n < 108)
+		regs[CH7006_PLL_CONTROL] |= CH7006_PLL_CONTROL_CAPACITOR;
+	else
+		regs[CH7006_PLL_CONTROL] &= ~CH7006_PLL_CONTROL_CAPACITOR;
+
+	ch7006_dbg(client, "n=%d m=%d f=%d c=%d\n",
+		   best_n, best_m, best_freq, best_n < 108);
+}
+
+void ch7006_setup_power_state(struct drm_encoder *encoder)
+{
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	uint8_t *power = &priv->state.regs[CH7006_POWER];
+	int subconnector;
+
+	subconnector = priv->select_subconnector ? priv->select_subconnector :
+							priv->subconnector;
+
+	*power = CH7006_POWER_RESET;
+
+	if (priv->last_dpms == DRM_MODE_DPMS_ON) {
+		switch (subconnector) {
+		case DRM_MODE_SUBCONNECTOR_SVIDEO:
+			*power |= bitfs(CH7006_POWER_LEVEL, CVBS_OFF);
+			break;
+		case DRM_MODE_SUBCONNECTOR_Composite:
+			*power |= bitfs(CH7006_POWER_LEVEL, SVIDEO_OFF);
+			break;
+		case DRM_MODE_SUBCONNECTOR_SCART:
+			*power |= bitfs(CH7006_POWER_LEVEL, NORMAL) |
+				CH7006_POWER_SCART;
+			break;
+		}
+
+	} else {
+		*power |= bitfs(CH7006_POWER_LEVEL, FULL_POWER_OFF);
+	}
+}
+
+void ch7006_setup_properties(struct drm_encoder *encoder)
+{
+	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	struct ch7006_state *state = &priv->state;
+	struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm];
+	struct ch7006_mode *ch_mode = priv->mode;
+	struct drm_display_mode *mode = &ch_mode->mode;
+	uint8_t *regs = state->regs;
+	int flicker, contrast, hpos, vpos;
+	uint64_t scale, aspect;
+
+	flicker = interpolate(0, 2, 3, priv->flicker);
+	regs[CH7006_FFILTER] = bitf(CH7006_FFILTER_TEXT, flicker) |
+		bitf(CH7006_FFILTER_LUMA, flicker) |
+		bitf(CH7006_FFILTER_CHROMA, 1);
+
+	contrast = interpolate(0, 5, 7, priv->contrast);
+	regs[CH7006_CONTRAST] = bitf(CH7006_CONTRAST_0, contrast);
+
+	scale = norm->vtotal*fixed1;
+	do_div(scale, mode->vtotal);
+
+	aspect = ch_mode->enc_hdisp*fixed1;
+	do_div(aspect, ch_mode->enc_vdisp);
+
+	hpos = round_fixed((norm->hvirtual * aspect - mode->hdisplay * scale)
+			   * priv->hmargin * mode->vtotal) / norm->vtotal / 100 / 4;
+
+	setbitf(state, CH7006_POV, HPOS_8, hpos);
+	setbitf(state, CH7006_HPOS, 0, hpos);
+
+	vpos = max(0, norm->vdisplay - round_fixed(mode->vdisplay*scale)
+		   + norm->voffset) * priv->vmargin / 100 / 2;
+
+	setbitf(state, CH7006_POV, VPOS_8, vpos);
+	setbitf(state, CH7006_VPOS, 0, vpos);
+
+	ch7006_dbg(client, "hpos: %d, vpos: %d\n", hpos, vpos);
+}
+
+/* HW access functions */
+
+void ch7006_write(struct i2c_client *client, uint8_t addr, uint8_t val)
+{
+	uint8_t buf[] = {addr, val};
+	int ret;
+
+	ret = i2c_master_send(client, buf, ARRAY_SIZE(buf));
+	if (ret < 0)
+		ch7006_err(client, "Error %d writing to subaddress 0x%x\n",
+			   ret, addr);
+}
+
+uint8_t ch7006_read(struct i2c_client *client, uint8_t addr)
+{
+	uint8_t val;
+	int ret;
+
+	ret = i2c_master_send(client, &addr, sizeof(addr));
+	if (ret < 0)
+		goto fail;
+
+	ret = i2c_master_recv(client, &val, sizeof(val));
+	if (ret < 0)
+		goto fail;
+
+	return val;
+
+fail:
+	ch7006_err(client, "Error %d reading from subaddress 0x%x\n",
+		   ret, addr);
+	return 0;
+}
+
+void ch7006_state_load(struct i2c_client *client,
+		       struct ch7006_state *state)
+{
+	ch7006_load_reg(client, state, CH7006_POWER);
+
+	ch7006_load_reg(client, state, CH7006_DISPMODE);
+	ch7006_load_reg(client, state, CH7006_FFILTER);
+	ch7006_load_reg(client, state, CH7006_BWIDTH);
+	ch7006_load_reg(client, state, CH7006_INPUT_FORMAT);
+	ch7006_load_reg(client, state, CH7006_CLKMODE);
+	ch7006_load_reg(client, state, CH7006_START_ACTIVE);
+	ch7006_load_reg(client, state, CH7006_POV);
+	ch7006_load_reg(client, state, CH7006_BLACK_LEVEL);
+	ch7006_load_reg(client, state, CH7006_HPOS);
+	ch7006_load_reg(client, state, CH7006_VPOS);
+	ch7006_load_reg(client, state, CH7006_INPUT_SYNC);
+	ch7006_load_reg(client, state, CH7006_DETECT);
+	ch7006_load_reg(client, state, CH7006_CONTRAST);
+	ch7006_load_reg(client, state, CH7006_PLLOV);
+	ch7006_load_reg(client, state, CH7006_PLLM);
+	ch7006_load_reg(client, state, CH7006_PLLN);
+	ch7006_load_reg(client, state, CH7006_BCLKOUT);
+	ch7006_load_reg(client, state, CH7006_SUBC_INC0);
+	ch7006_load_reg(client, state, CH7006_SUBC_INC1);
+	ch7006_load_reg(client, state, CH7006_SUBC_INC2);
+	ch7006_load_reg(client, state, CH7006_SUBC_INC3);
+	ch7006_load_reg(client, state, CH7006_SUBC_INC4);
+	ch7006_load_reg(client, state, CH7006_SUBC_INC5);
+	ch7006_load_reg(client, state, CH7006_SUBC_INC6);
+	ch7006_load_reg(client, state, CH7006_SUBC_INC7);
+	ch7006_load_reg(client, state, CH7006_PLL_CONTROL);
+	ch7006_load_reg(client, state, CH7006_CALC_SUBC_INC0);
+
+	/* I don't know what this is for, but otherwise I get no
+	 * signal.
+	 */
+	ch7006_write(client, 0x3d, 0x0);
+}
+
+void ch7006_state_save(struct i2c_client *client,
+		       struct ch7006_state *state)
+{
+	ch7006_save_reg(client, state, CH7006_POWER);
+
+	ch7006_save_reg(client, state, CH7006_DISPMODE);
+	ch7006_save_reg(client, state, CH7006_FFILTER);
+	ch7006_save_reg(client, state, CH7006_BWIDTH);
+	ch7006_save_reg(client, state, CH7006_INPUT_FORMAT);
+	ch7006_save_reg(client, state, CH7006_CLKMODE);
+	ch7006_save_reg(client, state, CH7006_START_ACTIVE);
+	ch7006_save_reg(client, state, CH7006_POV);
+	ch7006_save_reg(client, state, CH7006_BLACK_LEVEL);
+	ch7006_save_reg(client, state, CH7006_HPOS);
+	ch7006_save_reg(client, state, CH7006_VPOS);
+	ch7006_save_reg(client, state, CH7006_INPUT_SYNC);
+	ch7006_save_reg(client, state, CH7006_DETECT);
+	ch7006_save_reg(client, state, CH7006_CONTRAST);
+	ch7006_save_reg(client, state, CH7006_PLLOV);
+	ch7006_save_reg(client, state, CH7006_PLLM);
+	ch7006_save_reg(client, state, CH7006_PLLN);
+	ch7006_save_reg(client, state, CH7006_BCLKOUT);
+	ch7006_save_reg(client, state, CH7006_SUBC_INC0);
+	ch7006_save_reg(client, state, CH7006_SUBC_INC1);
+	ch7006_save_reg(client, state, CH7006_SUBC_INC2);
+	ch7006_save_reg(client, state, CH7006_SUBC_INC3);
+	ch7006_save_reg(client, state, CH7006_SUBC_INC4);
+	ch7006_save_reg(client, state, CH7006_SUBC_INC5);
+	ch7006_save_reg(client, state, CH7006_SUBC_INC6);
+	ch7006_save_reg(client, state, CH7006_SUBC_INC7);
+	ch7006_save_reg(client, state, CH7006_PLL_CONTROL);
+	ch7006_save_reg(client, state, CH7006_CALC_SUBC_INC0);
+
+	state->regs[CH7006_FFILTER] = (state->regs[CH7006_FFILTER] & 0xf0) |
+		(state->regs[CH7006_FFILTER] & 0x0c) >> 2 |
+		(state->regs[CH7006_FFILTER] & 0x03) << 2;
+}
diff --git a/drivers/gpu/drm/i2c/ch7006_priv.h b/drivers/gpu/drm/i2c/ch7006_priv.h
new file mode 100644
index 0000000..b06d3d9
--- /dev/null
+++ b/drivers/gpu/drm/i2c/ch7006_priv.h
@@ -0,0 +1,344 @@
+/*
+ * Copyright (C) 2009 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __DRM_I2C_CH7006_PRIV_H__
+#define __DRM_I2C_CH7006_PRIV_H__
+
+#include "drmP.h"
+#include "drm_crtc_helper.h"
+#include "drm_encoder_slave.h"
+#include "i2c/ch7006.h"
+
+typedef int64_t fixed;
+#define fixed1 (1LL << 32)
+
+enum ch7006_tv_norm {
+	TV_NORM_PAL,
+	TV_NORM_PAL_M,
+	TV_NORM_PAL_N,
+	TV_NORM_PAL_NC,
+	TV_NORM_PAL_60,
+	TV_NORM_NTSC_M,
+	TV_NORM_NTSC_J,
+	NUM_TV_NORMS
+};
+
+struct ch7006_tv_norm_info {
+	fixed vrefresh;
+	int vdisplay;
+	int vtotal;
+	int hvirtual;
+
+	fixed subc_freq;
+	fixed black_level;
+
+	uint32_t dispmode;
+	int voffset;
+};
+
+struct ch7006_mode {
+	struct drm_display_mode mode;
+
+	int enc_hdisp;
+	int enc_vdisp;
+
+	fixed subc_coeff;
+	uint32_t dispmode;
+
+	uint32_t valid_scales;
+	uint32_t valid_norms;
+};
+
+struct ch7006_state {
+	uint8_t regs[0x26];
+};
+
+struct ch7006_priv {
+	struct ch7006_encoder_params *params;
+	struct ch7006_mode *mode;
+
+	struct ch7006_state state;
+	struct ch7006_state saved_state;
+
+	struct drm_property *scale_property;
+
+	int select_subconnector;
+	int subconnector;
+	int hmargin;
+	int vmargin;
+	enum ch7006_tv_norm norm;
+	int brightness;
+	int contrast;
+	int flicker;
+	int scale;
+
+	int last_dpms;
+};
+
+#define to_ch7006_priv(x) \
+	((struct ch7006_priv *)to_encoder_slave(x)->slave_priv)
+
+extern int ch7006_debug;
+extern char *ch7006_tv_norm;
+extern int ch7006_scale;
+
+extern char *ch7006_tv_norm_names[];
+extern struct ch7006_tv_norm_info ch7006_tv_norms[];
+extern struct ch7006_mode ch7006_modes[];
+
+struct ch7006_mode *ch7006_lookup_mode(struct drm_encoder *encoder,
+				       struct drm_display_mode *drm_mode);
+
+void ch7006_setup_levels(struct drm_encoder *encoder);
+void ch7006_setup_subcarrier(struct drm_encoder *encoder);
+void ch7006_setup_pll(struct drm_encoder *encoder);
+void ch7006_setup_power_state(struct drm_encoder *encoder);
+void ch7006_setup_properties(struct drm_encoder *encoder);
+
+void ch7006_write(struct i2c_client *client, uint8_t addr, uint8_t val);
+uint8_t ch7006_read(struct i2c_client *client, uint8_t addr);
+
+void ch7006_state_load(struct i2c_client *client,
+		       struct ch7006_state *state);
+void ch7006_state_save(struct i2c_client *client,
+		       struct ch7006_state *state);
+
+/* Some helper macros */
+
+#define ch7006_dbg(client, format, ...) do {				\
+		if (ch7006_debug)					\
+			dev_printk(KERN_DEBUG, &client->dev,		\
+				   "%s: " format, __func__, ## __VA_ARGS__); \
+	} while (0)
+#define ch7006_info(client, format, ...) \
+				dev_info(&client->dev, format, __VA_ARGS__)
+#define ch7006_err(client, format, ...) \
+				dev_err(&client->dev, format, __VA_ARGS__)
+
+#define __mask(src, bitfield) \
+		(((2 << (1 ? bitfield)) - 1) & ~((1 << (0 ? bitfield)) - 1))
+#define mask(bitfield) __mask(bitfield)
+
+#define __bitf(src, bitfield, x) \
+		(((x) >> (src) << (0 ? bitfield)) &  __mask(src, bitfield))
+#define bitf(bitfield, x) __bitf(bitfield, x)
+#define bitfs(bitfield, s) __bitf(bitfield, bitfield##_##s)
+#define setbitf(state, reg, bitfield, x)				\
+	state->regs[reg] = (state->regs[reg] & ~mask(reg##_##bitfield))	\
+		| bitf(reg##_##bitfield, x)
+
+#define __unbitf(src, bitfield, x) \
+		((x & __mask(src, bitfield)) >> (0 ? bitfield) << (src))
+#define unbitf(bitfield, x) __unbitf(bitfield, x)
+
+static inline int interpolate(int y0, int y1, int y2, int x)
+{
+	return y1 + (x < 50 ? y1 - y0 : y2 - y1) * (x - 50) / 50;
+}
+
+static inline int32_t round_fixed(fixed x)
+{
+	return (x + fixed1/2) >> 32;
+}
+
+#define ch7006_load_reg(client, state, reg) ch7006_write(client, reg, state->regs[reg])
+#define ch7006_save_reg(client, state, reg) state->regs[reg] = ch7006_read(client, reg)
+
+/* Fixed hardware specs */
+
+#define CH7006_FREQ0				14318
+#define CH7006_MAXN				650
+#define CH7006_MAXM				315
+
+/* Register definitions */
+
+#define CH7006_DISPMODE				0x00
+#define CH7006_DISPMODE_INPUT_RES		0, 7:5
+#define CH7006_DISPMODE_INPUT_RES_512x384	0x0
+#define CH7006_DISPMODE_INPUT_RES_720x400	0x1
+#define CH7006_DISPMODE_INPUT_RES_640x400	0x2
+#define CH7006_DISPMODE_INPUT_RES_640x480	0x3
+#define CH7006_DISPMODE_INPUT_RES_800x600	0x4
+#define CH7006_DISPMODE_INPUT_RES_NATIVE	0x5
+#define CH7006_DISPMODE_OUTPUT_STD		0, 4:3
+#define CH7006_DISPMODE_OUTPUT_STD_PAL		0x0
+#define CH7006_DISPMODE_OUTPUT_STD_NTSC		0x1
+#define CH7006_DISPMODE_OUTPUT_STD_PAL_M	0x2
+#define CH7006_DISPMODE_OUTPUT_STD_NTSC_J	0x3
+#define CH7006_DISPMODE_SCALING_RATIO		0, 2:0
+#define CH7006_DISPMODE_SCALING_RATIO_5_4	0x0
+#define CH7006_DISPMODE_SCALING_RATIO_1_1	0x1
+#define CH7006_DISPMODE_SCALING_RATIO_7_8	0x2
+#define CH7006_DISPMODE_SCALING_RATIO_5_6	0x3
+#define CH7006_DISPMODE_SCALING_RATIO_3_4	0x4
+#define CH7006_DISPMODE_SCALING_RATIO_7_10	0x5
+
+#define CH7006_FFILTER				0x01
+#define CH7006_FFILTER_TEXT			0, 5:4
+#define CH7006_FFILTER_LUMA			0, 3:2
+#define CH7006_FFILTER_CHROMA			0, 1:0
+#define CH7006_FFILTER_CHROMA_NO_DCRAWL		0x3
+
+#define CH7006_BWIDTH				0x03
+#define CH7006_BWIDTH_5L_FFILER			(1 << 7)
+#define CH7006_BWIDTH_CVBS_NO_CHROMA		(1 << 6)
+#define CH7006_BWIDTH_CHROMA			0, 5:4
+#define CH7006_BWIDTH_SVIDEO_YPEAK		(1 << 3)
+#define CH7006_BWIDTH_SVIDEO_LUMA		0, 2:1
+#define CH7006_BWIDTH_CVBS_LUMA			0, 0:0
+
+#define CH7006_INPUT_FORMAT			0x04
+#define CH7006_INPUT_FORMAT_DAC_GAIN		(1 << 6)
+#define CH7006_INPUT_FORMAT_RGB_PASS_THROUGH	(1 << 5)
+#define CH7006_INPUT_FORMAT_FORMAT		0, 3:0
+#define CH7006_INPUT_FORMAT_FORMAT_RGB16	0x0
+#define CH7006_INPUT_FORMAT_FORMAT_YCrCb24m16	0x1
+#define CH7006_INPUT_FORMAT_FORMAT_RGB24m16	0x2
+#define CH7006_INPUT_FORMAT_FORMAT_RGB15	0x3
+#define CH7006_INPUT_FORMAT_FORMAT_RGB24m12C	0x4
+#define CH7006_INPUT_FORMAT_FORMAT_RGB24m12I	0x5
+#define CH7006_INPUT_FORMAT_FORMAT_RGB24m8	0x6
+#define CH7006_INPUT_FORMAT_FORMAT_RGB16m8	0x7
+#define CH7006_INPUT_FORMAT_FORMAT_RGB15m8	0x8
+#define CH7006_INPUT_FORMAT_FORMAT_YCrCb24m8	0x9
+
+#define CH7006_CLKMODE				0x06
+#define CH7006_CLKMODE_SUBC_LOCK		(1 << 7)
+#define CH7006_CLKMODE_MASTER			(1 << 6)
+#define CH7006_CLKMODE_POS_EDGE			(1 << 4)
+#define CH7006_CLKMODE_XCM			0, 3:2
+#define CH7006_CLKMODE_PCM			0, 1:0
+
+#define CH7006_START_ACTIVE			0x07
+#define CH7006_START_ACTIVE_0			0, 7:0
+
+#define CH7006_POV				0x08
+#define CH7006_POV_START_ACTIVE_8		8, 2:2
+#define CH7006_POV_HPOS_8			8, 1:1
+#define CH7006_POV_VPOS_8			8, 0:0
+
+#define CH7006_BLACK_LEVEL			0x09
+#define CH7006_BLACK_LEVEL_0			0, 7:0
+
+#define CH7006_HPOS				0x0a
+#define CH7006_HPOS_0				0, 7:0
+
+#define CH7006_VPOS				0x0b
+#define CH7006_VPOS_0				0, 7:0
+
+#define CH7006_INPUT_SYNC			0x0d
+#define CH7006_INPUT_SYNC_EMBEDDED		(1 << 3)
+#define CH7006_INPUT_SYNC_OUTPUT		(1 << 2)
+#define CH7006_INPUT_SYNC_PVSYNC		(1 << 1)
+#define CH7006_INPUT_SYNC_PHSYNC		(1 << 0)
+
+#define CH7006_POWER				0x0e
+#define CH7006_POWER_SCART			(1 << 4)
+#define CH7006_POWER_RESET			(1 << 3)
+#define CH7006_POWER_LEVEL			0, 2:0
+#define CH7006_POWER_LEVEL_CVBS_OFF		0x0
+#define CH7006_POWER_LEVEL_POWER_OFF		0x1
+#define CH7006_POWER_LEVEL_SVIDEO_OFF		0x2
+#define CH7006_POWER_LEVEL_NORMAL		0x3
+#define CH7006_POWER_LEVEL_FULL_POWER_OFF	0x4
+
+#define CH7006_DETECT				0x10
+#define CH7006_DETECT_SVIDEO_Y_TEST		(1 << 3)
+#define CH7006_DETECT_SVIDEO_C_TEST		(1 << 2)
+#define CH7006_DETECT_CVBS_TEST			(1 << 1)
+#define CH7006_DETECT_SENSE			(1 << 0)
+
+#define CH7006_CONTRAST				0x11
+#define CH7006_CONTRAST_0			0, 2:0
+
+#define CH7006_PLLOV	 			0x13
+#define CH7006_PLLOV_N_8	 		8, 2:1
+#define CH7006_PLLOV_M_8	 		8, 0:0
+
+#define CH7006_PLLM	 			0x14
+#define CH7006_PLLM_0	 			0, 7:0
+
+#define CH7006_PLLN	 			0x15
+#define CH7006_PLLN_0	 			0, 7:0
+
+#define CH7006_BCLKOUT	 			0x17
+
+#define CH7006_SUBC_INC0			0x18
+#define CH7006_SUBC_INC0_28			28, 3:0
+
+#define CH7006_SUBC_INC1			0x19
+#define CH7006_SUBC_INC1_24			24, 3:0
+
+#define CH7006_SUBC_INC2			0x1a
+#define CH7006_SUBC_INC2_20			20, 3:0
+
+#define CH7006_SUBC_INC3			0x1b
+#define CH7006_SUBC_INC3_GPIO1_VAL		(1 << 7)
+#define CH7006_SUBC_INC3_GPIO0_VAL		(1 << 6)
+#define CH7006_SUBC_INC3_POUT_3_3V		(1 << 5)
+#define CH7006_SUBC_INC3_POUT_INV		(1 << 4)
+#define CH7006_SUBC_INC3_16			16, 3:0
+
+#define CH7006_SUBC_INC4			0x1c
+#define CH7006_SUBC_INC4_GPIO1_IN		(1 << 7)
+#define CH7006_SUBC_INC4_GPIO0_IN		(1 << 6)
+#define CH7006_SUBC_INC4_DS_INPUT		(1 << 4)
+#define CH7006_SUBC_INC4_12			12, 3:0
+
+#define CH7006_SUBC_INC5			0x1d
+#define CH7006_SUBC_INC5_8			8, 3:0
+
+#define CH7006_SUBC_INC6			0x1e
+#define CH7006_SUBC_INC6_4			4, 3:0
+
+#define CH7006_SUBC_INC7			0x1f
+#define CH7006_SUBC_INC7_0			0, 3:0
+
+#define CH7006_PLL_CONTROL			0x20
+#define CH7006_PLL_CONTROL_CPI			(1 << 5)
+#define CH7006_PLL_CONTROL_CAPACITOR		(1 << 4)
+#define CH7006_PLL_CONTROL_7STAGES		(1 << 3)
+#define CH7006_PLL_CONTROL_DIGITAL_5V		(1 << 2)
+#define CH7006_PLL_CONTROL_ANALOG_5V		(1 << 1)
+#define CH7006_PLL_CONTROL_MEMORY_5V		(1 << 0)
+
+#define CH7006_CALC_SUBC_INC0			0x21
+#define CH7006_CALC_SUBC_INC0_24		24, 4:3
+#define CH7006_CALC_SUBC_INC0_HYST		0, 2:1
+#define CH7006_CALC_SUBC_INC0_AUTO		(1 << 0)
+
+#define CH7006_CALC_SUBC_INC1			0x22
+#define CH7006_CALC_SUBC_INC1_16		16, 7:0
+
+#define CH7006_CALC_SUBC_INC2			0x23
+#define CH7006_CALC_SUBC_INC2_8			8, 7:0
+
+#define CH7006_CALC_SUBC_INC3			0x24
+#define CH7006_CALC_SUBC_INC3_0			0, 7:0
+
+#define CH7006_VERSION_ID			0x25
+
+#endif
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index fa7b9be..9929f84 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -15,7 +15,6 @@
 	  intel_lvds.o \
 	  intel_bios.o \
 	  intel_dp.o \
-	  intel_dp_i2c.o \
 	  intel_hdmi.o \
 	  intel_sdvo.o \
 	  intel_modes.o \
@@ -23,6 +22,7 @@
 	  intel_fb.o \
 	  intel_tv.o \
 	  intel_dvo.o \
+	  intel_overlay.o \
 	  dvo_ch7xxx.o \
 	  dvo_ch7017.o \
 	  dvo_ivch.o \
diff --git a/drivers/gpu/drm/i915/dvo_ch7017.c b/drivers/gpu/drm/i915/dvo_ch7017.c
index 621815b..1184c14 100644
--- a/drivers/gpu/drm/i915/dvo_ch7017.c
+++ b/drivers/gpu/drm/i915/dvo_ch7017.c
@@ -249,7 +249,8 @@
 	if (val != CH7017_DEVICE_ID_VALUE &&
 	    val != CH7018_DEVICE_ID_VALUE &&
 	    val != CH7019_DEVICE_ID_VALUE) {
-		DRM_DEBUG("ch701x not detected, got %d: from %s Slave %d.\n",
+		DRM_DEBUG_KMS("ch701x not detected, got %d: from %s "
+				"Slave %d.\n",
 			  val, i2cbus->adapter.name,dvo->slave_addr);
 		goto fail;
 	}
@@ -284,7 +285,7 @@
 	uint8_t horizontal_active_pixel_output, vertical_active_line_output;
 	uint8_t active_input_line_output;
 
-	DRM_DEBUG("Registers before mode setting\n");
+	DRM_DEBUG_KMS("Registers before mode setting\n");
 	ch7017_dump_regs(dvo);
 
 	/* LVDS PLL settings from page 75 of 7017-7017ds.pdf*/
@@ -346,7 +347,7 @@
 	/* Turn the LVDS back on with new settings. */
 	ch7017_write(dvo, CH7017_LVDS_POWER_DOWN, lvds_power_down);
 
-	DRM_DEBUG("Registers after mode setting\n");
+	DRM_DEBUG_KMS("Registers after mode setting\n");
 	ch7017_dump_regs(dvo);
 }
 
@@ -386,7 +387,7 @@
 #define DUMP(reg)					\
 do {							\
 	ch7017_read(dvo, reg, &val);			\
-	DRM_DEBUG(#reg ": %02x\n", val);		\
+	DRM_DEBUG_KMS(#reg ": %02x\n", val);		\
 } while (0)
 
 	DUMP(CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT);
diff --git a/drivers/gpu/drm/i915/dvo_ch7xxx.c b/drivers/gpu/drm/i915/dvo_ch7xxx.c
index a9b8962..d56ff5c 100644
--- a/drivers/gpu/drm/i915/dvo_ch7xxx.c
+++ b/drivers/gpu/drm/i915/dvo_ch7xxx.c
@@ -152,7 +152,7 @@
 	};
 
 	if (!ch7xxx->quiet) {
-		DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n",
+		DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
 			  addr, i2cbus->adapter.name, dvo->slave_addr);
 	}
 	return false;
@@ -179,7 +179,7 @@
 		return true;
 
 	if (!ch7xxx->quiet) {
-		DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n",
+		DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
 			  addr, i2cbus->adapter.name, dvo->slave_addr);
 	}
 
@@ -207,7 +207,8 @@
 
 	name = ch7xxx_get_id(vendor);
 	if (!name) {
-		DRM_DEBUG("ch7xxx not detected; got 0x%02x from %s slave %d.\n",
+		DRM_DEBUG_KMS("ch7xxx not detected; got 0x%02x from %s "
+				"slave %d.\n",
 			  vendor, adapter->name, dvo->slave_addr);
 		goto out;
 	}
@@ -217,13 +218,14 @@
 		goto out;
 
 	if (device != CH7xxx_DID) {
-		DRM_DEBUG("ch7xxx not detected; got 0x%02x from %s slave %d.\n",
+		DRM_DEBUG_KMS("ch7xxx not detected; got 0x%02x from %s "
+				"slave %d.\n",
 			  vendor, adapter->name, dvo->slave_addr);
 		goto out;
 	}
 
 	ch7xxx->quiet = false;
-	DRM_DEBUG("Detected %s chipset, vendor/device ID 0x%02x/0x%02x\n",
+	DRM_DEBUG_KMS("Detected %s chipset, vendor/device ID 0x%02x/0x%02x\n",
 		  name, vendor, device);
 	return true;
 out:
@@ -315,8 +317,8 @@
 
 	for (i = 0; i < CH7xxx_NUM_REGS; i++) {
 		if ((i % 8) == 0 )
-			DRM_DEBUG("\n %02X: ", i);
-		DRM_DEBUG("%02X ", ch7xxx->mode_reg.regs[i]);
+			DRM_LOG_KMS("\n %02X: ", i);
+		DRM_LOG_KMS("%02X ", ch7xxx->mode_reg.regs[i]);
 	}
 }
 
diff --git a/drivers/gpu/drm/i915/dvo_ivch.c b/drivers/gpu/drm/i915/dvo_ivch.c
index aa176f9..24169e5 100644
--- a/drivers/gpu/drm/i915/dvo_ivch.c
+++ b/drivers/gpu/drm/i915/dvo_ivch.c
@@ -202,7 +202,8 @@
 	};
 
 	if (!priv->quiet) {
-		DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n",
+		DRM_DEBUG_KMS("Unable to read register 0x%02x from "
+				"%s:%02x.\n",
 			  addr, i2cbus->adapter.name, dvo->slave_addr);
 	}
 	return false;
@@ -230,7 +231,7 @@
 		return true;
 
 	if (!priv->quiet) {
-		DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n",
+		DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
 			  addr, i2cbus->adapter.name, dvo->slave_addr);
 	}
 
@@ -261,7 +262,7 @@
 	 * the address it's responding on.
 	 */
 	if ((temp & VR00_BASE_ADDRESS_MASK) != dvo->slave_addr) {
-		DRM_DEBUG("ivch detect failed due to address mismatch "
+		DRM_DEBUG_KMS("ivch detect failed due to address mismatch "
 			  "(%d vs %d)\n",
 			  (temp & VR00_BASE_ADDRESS_MASK), dvo->slave_addr);
 		goto out;
@@ -367,41 +368,41 @@
 	uint16_t val;
 
 	ivch_read(dvo, VR00, &val);
-	DRM_DEBUG("VR00: 0x%04x\n", val);
+	DRM_LOG_KMS("VR00: 0x%04x\n", val);
 	ivch_read(dvo, VR01, &val);
-	DRM_DEBUG("VR01: 0x%04x\n", val);
+	DRM_LOG_KMS("VR01: 0x%04x\n", val);
 	ivch_read(dvo, VR30, &val);
-	DRM_DEBUG("VR30: 0x%04x\n", val);
+	DRM_LOG_KMS("VR30: 0x%04x\n", val);
 	ivch_read(dvo, VR40, &val);
-	DRM_DEBUG("VR40: 0x%04x\n", val);
+	DRM_LOG_KMS("VR40: 0x%04x\n", val);
 
 	/* GPIO registers */
 	ivch_read(dvo, VR80, &val);
-	DRM_DEBUG("VR80: 0x%04x\n", val);
+	DRM_LOG_KMS("VR80: 0x%04x\n", val);
 	ivch_read(dvo, VR81, &val);
-	DRM_DEBUG("VR81: 0x%04x\n", val);
+	DRM_LOG_KMS("VR81: 0x%04x\n", val);
 	ivch_read(dvo, VR82, &val);
-	DRM_DEBUG("VR82: 0x%04x\n", val);
+	DRM_LOG_KMS("VR82: 0x%04x\n", val);
 	ivch_read(dvo, VR83, &val);
-	DRM_DEBUG("VR83: 0x%04x\n", val);
+	DRM_LOG_KMS("VR83: 0x%04x\n", val);
 	ivch_read(dvo, VR84, &val);
-	DRM_DEBUG("VR84: 0x%04x\n", val);
+	DRM_LOG_KMS("VR84: 0x%04x\n", val);
 	ivch_read(dvo, VR85, &val);
-	DRM_DEBUG("VR85: 0x%04x\n", val);
+	DRM_LOG_KMS("VR85: 0x%04x\n", val);
 	ivch_read(dvo, VR86, &val);
-	DRM_DEBUG("VR86: 0x%04x\n", val);
+	DRM_LOG_KMS("VR86: 0x%04x\n", val);
 	ivch_read(dvo, VR87, &val);
-	DRM_DEBUG("VR87: 0x%04x\n", val);
+	DRM_LOG_KMS("VR87: 0x%04x\n", val);
 	ivch_read(dvo, VR88, &val);
-	DRM_DEBUG("VR88: 0x%04x\n", val);
+	DRM_LOG_KMS("VR88: 0x%04x\n", val);
 
 	/* Scratch register 0 - AIM Panel type */
 	ivch_read(dvo, VR8E, &val);
-	DRM_DEBUG("VR8E: 0x%04x\n", val);
+	DRM_LOG_KMS("VR8E: 0x%04x\n", val);
 
 	/* Scratch register 1 - Status register */
 	ivch_read(dvo, VR8F, &val);
-	DRM_DEBUG("VR8F: 0x%04x\n", val);
+	DRM_LOG_KMS("VR8F: 0x%04x\n", val);
 }
 
 static void ivch_save(struct intel_dvo_device *dvo)
diff --git a/drivers/gpu/drm/i915/dvo_sil164.c b/drivers/gpu/drm/i915/dvo_sil164.c
index e1c1f73..0001c13 100644
--- a/drivers/gpu/drm/i915/dvo_sil164.c
+++ b/drivers/gpu/drm/i915/dvo_sil164.c
@@ -105,7 +105,7 @@
 	};
 
 	if (!sil->quiet) {
-		DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n",
+		DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
 			  addr, i2cbus->adapter.name, dvo->slave_addr);
 	}
 	return false;
@@ -131,7 +131,7 @@
 		return true;
 
 	if (!sil->quiet) {
-		DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n",
+		DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
 			  addr, i2cbus->adapter.name, dvo->slave_addr);
 	}
 
@@ -158,7 +158,7 @@
 		goto out;
 
 	if (ch != (SIL164_VID & 0xff)) {
-		DRM_DEBUG("sil164 not detected got %d: from %s Slave %d.\n",
+		DRM_DEBUG_KMS("sil164 not detected got %d: from %s Slave %d.\n",
 			  ch, adapter->name, dvo->slave_addr);
 		goto out;
 	}
@@ -167,13 +167,13 @@
 		goto out;
 
 	if (ch != (SIL164_DID & 0xff)) {
-		DRM_DEBUG("sil164 not detected got %d: from %s Slave %d.\n",
+		DRM_DEBUG_KMS("sil164 not detected got %d: from %s Slave %d.\n",
 			  ch, adapter->name, dvo->slave_addr);
 		goto out;
 	}
 	sil->quiet = false;
 
-	DRM_DEBUG("init sil164 dvo controller successfully!\n");
+	DRM_DEBUG_KMS("init sil164 dvo controller successfully!\n");
 	return true;
 
 out:
@@ -241,15 +241,15 @@
 	uint8_t val;
 
 	sil164_readb(dvo, SIL164_FREQ_LO, &val);
-	DRM_DEBUG("SIL164_FREQ_LO: 0x%02x\n", val);
+	DRM_LOG_KMS("SIL164_FREQ_LO: 0x%02x\n", val);
 	sil164_readb(dvo, SIL164_FREQ_HI, &val);
-	DRM_DEBUG("SIL164_FREQ_HI: 0x%02x\n", val);
+	DRM_LOG_KMS("SIL164_FREQ_HI: 0x%02x\n", val);
 	sil164_readb(dvo, SIL164_REG8, &val);
-	DRM_DEBUG("SIL164_REG8: 0x%02x\n", val);
+	DRM_LOG_KMS("SIL164_REG8: 0x%02x\n", val);
 	sil164_readb(dvo, SIL164_REG9, &val);
-	DRM_DEBUG("SIL164_REG9: 0x%02x\n", val);
+	DRM_LOG_KMS("SIL164_REG9: 0x%02x\n", val);
 	sil164_readb(dvo, SIL164_REGC, &val);
-	DRM_DEBUG("SIL164_REGC: 0x%02x\n", val);
+	DRM_LOG_KMS("SIL164_REGC: 0x%02x\n", val);
 }
 
 static void sil164_save(struct intel_dvo_device *dvo)
diff --git a/drivers/gpu/drm/i915/dvo_tfp410.c b/drivers/gpu/drm/i915/dvo_tfp410.c
index 9ecc907..c7c391b 100644
--- a/drivers/gpu/drm/i915/dvo_tfp410.c
+++ b/drivers/gpu/drm/i915/dvo_tfp410.c
@@ -130,7 +130,7 @@
 	};
 
 	if (!tfp->quiet) {
-		DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n",
+		DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
 			  addr, i2cbus->adapter.name, dvo->slave_addr);
 	}
 	return false;
@@ -156,7 +156,7 @@
 		return true;
 
 	if (!tfp->quiet) {
-		DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n",
+		DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
 			  addr, i2cbus->adapter.name, dvo->slave_addr);
 	}
 
@@ -191,13 +191,15 @@
 	tfp->quiet = true;
 
 	if ((id = tfp410_getid(dvo, TFP410_VID_LO)) != TFP410_VID) {
-		DRM_DEBUG("tfp410 not detected got VID %X: from %s Slave %d.\n",
+		DRM_DEBUG_KMS("tfp410 not detected got VID %X: from %s "
+				"Slave %d.\n",
 			  id, adapter->name, dvo->slave_addr);
 		goto out;
 	}
 
 	if ((id = tfp410_getid(dvo, TFP410_DID_LO)) != TFP410_DID) {
-		DRM_DEBUG("tfp410 not detected got DID %X: from %s Slave %d.\n",
+		DRM_DEBUG_KMS("tfp410 not detected got DID %X: from %s "
+				"Slave %d.\n",
 			  id, adapter->name, dvo->slave_addr);
 		goto out;
 	}
@@ -262,33 +264,33 @@
 	uint8_t val, val2;
 
 	tfp410_readb(dvo, TFP410_REV, &val);
-	DRM_DEBUG("TFP410_REV: 0x%02X\n", val);
+	DRM_LOG_KMS("TFP410_REV: 0x%02X\n", val);
 	tfp410_readb(dvo, TFP410_CTL_1, &val);
-	DRM_DEBUG("TFP410_CTL1: 0x%02X\n", val);
+	DRM_LOG_KMS("TFP410_CTL1: 0x%02X\n", val);
 	tfp410_readb(dvo, TFP410_CTL_2, &val);
-	DRM_DEBUG("TFP410_CTL2: 0x%02X\n", val);
+	DRM_LOG_KMS("TFP410_CTL2: 0x%02X\n", val);
 	tfp410_readb(dvo, TFP410_CTL_3, &val);
-	DRM_DEBUG("TFP410_CTL3: 0x%02X\n", val);
+	DRM_LOG_KMS("TFP410_CTL3: 0x%02X\n", val);
 	tfp410_readb(dvo, TFP410_USERCFG, &val);
-	DRM_DEBUG("TFP410_USERCFG: 0x%02X\n", val);
+	DRM_LOG_KMS("TFP410_USERCFG: 0x%02X\n", val);
 	tfp410_readb(dvo, TFP410_DE_DLY, &val);
-	DRM_DEBUG("TFP410_DE_DLY: 0x%02X\n", val);
+	DRM_LOG_KMS("TFP410_DE_DLY: 0x%02X\n", val);
 	tfp410_readb(dvo, TFP410_DE_CTL, &val);
-	DRM_DEBUG("TFP410_DE_CTL: 0x%02X\n", val);
+	DRM_LOG_KMS("TFP410_DE_CTL: 0x%02X\n", val);
 	tfp410_readb(dvo, TFP410_DE_TOP, &val);
-	DRM_DEBUG("TFP410_DE_TOP: 0x%02X\n", val);
+	DRM_LOG_KMS("TFP410_DE_TOP: 0x%02X\n", val);
 	tfp410_readb(dvo, TFP410_DE_CNT_LO, &val);
 	tfp410_readb(dvo, TFP410_DE_CNT_HI, &val2);
-	DRM_DEBUG("TFP410_DE_CNT: 0x%02X%02X\n", val2, val);
+	DRM_LOG_KMS("TFP410_DE_CNT: 0x%02X%02X\n", val2, val);
 	tfp410_readb(dvo, TFP410_DE_LIN_LO, &val);
 	tfp410_readb(dvo, TFP410_DE_LIN_HI, &val2);
-	DRM_DEBUG("TFP410_DE_LIN: 0x%02X%02X\n", val2, val);
+	DRM_LOG_KMS("TFP410_DE_LIN: 0x%02X%02X\n", val2, val);
 	tfp410_readb(dvo, TFP410_H_RES_LO, &val);
 	tfp410_readb(dvo, TFP410_H_RES_HI, &val2);
-	DRM_DEBUG("TFP410_H_RES: 0x%02X%02X\n", val2, val);
+	DRM_LOG_KMS("TFP410_H_RES: 0x%02X%02X\n", val2, val);
 	tfp410_readb(dvo, TFP410_V_RES_LO, &val);
 	tfp410_readb(dvo, TFP410_V_RES_HI, &val2);
-	DRM_DEBUG("TFP410_V_RES: 0x%02X%02X\n", val2, val);
+	DRM_LOG_KMS("TFP410_V_RES: 0x%02X%02X\n", val2, val);
 }
 
 static void tfp410_save(struct intel_dvo_device *dvo)
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 26bf055..18476bf 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -27,6 +27,7 @@
  */
 
 #include <linux/seq_file.h>
+#include <linux/debugfs.h>
 #include "drmP.h"
 #include "drm.h"
 #include "i915_drm.h"
@@ -96,13 +97,14 @@
 	{
 		struct drm_gem_object *obj = obj_priv->obj;
 
-		seq_printf(m, "    %p: %s %8zd %08x %08x %d %s",
+		seq_printf(m, "    %p: %s %8zd %08x %08x %d%s%s",
 			   obj,
 			   get_pin_flag(obj_priv),
 			   obj->size,
 			   obj->read_domains, obj->write_domain,
 			   obj_priv->last_rendering_seqno,
-			   obj_priv->dirty ? "dirty" : "");
+			   obj_priv->dirty ? " dirty" : "",
+			   obj_priv->madv == I915_MADV_DONTNEED ? " purgeable" : "");
 
 		if (obj->name)
 			seq_printf(m, " (name: %d)", obj->name);
@@ -160,7 +162,7 @@
 	struct drm_device *dev = node->minor->dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
 
-	if (!IS_IGDNG(dev)) {
+	if (!IS_IRONLAKE(dev)) {
 		seq_printf(m, "Interrupt enable:    %08x\n",
 			   I915_READ(IER));
 		seq_printf(m, "Interrupt identity:  %08x\n",
@@ -412,6 +414,109 @@
 	return 0;
 }
 
+static int
+i915_wedged_open(struct inode *inode,
+		 struct file *filp)
+{
+	filp->private_data = inode->i_private;
+	return 0;
+}
+
+static ssize_t
+i915_wedged_read(struct file *filp,
+		 char __user *ubuf,
+		 size_t max,
+		 loff_t *ppos)
+{
+	struct drm_device *dev = filp->private_data;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	char buf[80];
+	int len;
+
+	len = snprintf(buf, sizeof (buf),
+		       "wedged :  %d\n",
+		       atomic_read(&dev_priv->mm.wedged));
+
+	return simple_read_from_buffer(ubuf, max, ppos, buf, len);
+}
+
+static ssize_t
+i915_wedged_write(struct file *filp,
+		  const char __user *ubuf,
+		  size_t cnt,
+		  loff_t *ppos)
+{
+	struct drm_device *dev = filp->private_data;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	char buf[20];
+	int val = 1;
+
+	if (cnt > 0) {
+		if (cnt > sizeof (buf) - 1)
+			return -EINVAL;
+
+		if (copy_from_user(buf, ubuf, cnt))
+			return -EFAULT;
+		buf[cnt] = 0;
+
+		val = simple_strtoul(buf, NULL, 0);
+	}
+
+	DRM_INFO("Manually setting wedged to %d\n", val);
+
+	atomic_set(&dev_priv->mm.wedged, val);
+	if (val) {
+		DRM_WAKEUP(&dev_priv->irq_queue);
+		queue_work(dev_priv->wq, &dev_priv->error_work);
+	}
+
+	return cnt;
+}
+
+static const struct file_operations i915_wedged_fops = {
+	.owner = THIS_MODULE,
+	.open = i915_wedged_open,
+	.read = i915_wedged_read,
+	.write = i915_wedged_write,
+};
+
+/* As the drm_debugfs_init() routines are called before dev->dev_private is
+ * allocated we need to hook into the minor for release. */
+static int
+drm_add_fake_info_node(struct drm_minor *minor,
+		       struct dentry *ent,
+		       const void *key)
+{
+	struct drm_info_node *node;
+
+	node = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL);
+	if (node == NULL) {
+		debugfs_remove(ent);
+		return -ENOMEM;
+	}
+
+	node->minor = minor;
+	node->dent = ent;
+	node->info_ent = (void *) key;
+	list_add(&node->list, &minor->debugfs_nodes.list);
+
+	return 0;
+}
+
+static int i915_wedged_create(struct dentry *root, struct drm_minor *minor)
+{
+	struct drm_device *dev = minor->dev;
+	struct dentry *ent;
+
+	ent = debugfs_create_file("i915_wedged",
+				  S_IRUGO | S_IWUSR,
+				  root, dev,
+				  &i915_wedged_fops);
+	if (IS_ERR(ent))
+		return PTR_ERR(ent);
+
+	return drm_add_fake_info_node(minor, ent, &i915_wedged_fops);
+}
 
 static struct drm_info_list i915_debugfs_list[] = {
 	{"i915_regs", i915_registers_info, 0},
@@ -432,6 +537,12 @@
 
 int i915_debugfs_init(struct drm_minor *minor)
 {
+	int ret;
+
+	ret = i915_wedged_create(minor->debugfs_root, minor);
+	if (ret)
+		return ret;
+
 	return drm_debugfs_create_files(i915_debugfs_list,
 					I915_DEBUGFS_ENTRIES,
 					minor->debugfs_root, minor);
@@ -441,7 +552,8 @@
 {
 	drm_debugfs_remove_files(i915_debugfs_list,
 				 I915_DEBUGFS_ENTRIES, minor);
+	drm_debugfs_remove_files((struct drm_info_list *) &i915_wedged_fops,
+				 1, minor);
 }
 
 #endif /* CONFIG_DEBUG_FS */
-
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index e5b138b..701bfea 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -807,6 +807,12 @@
 	case I915_PARAM_NUM_FENCES_AVAIL:
 		value = dev_priv->num_fence_regs - dev_priv->fence_reg_start;
 		break;
+	case I915_PARAM_HAS_OVERLAY:
+		value = dev_priv->overlay ? 1 : 0;
+		break;
+	case I915_PARAM_HAS_PAGEFLIPPING:
+		value = 1;
+		break;
 	default:
 		DRM_DEBUG_DRIVER("Unknown parameter %d\n",
 					param->param);
@@ -962,7 +968,7 @@
 	 * Some of the preallocated space is taken by the GTT
 	 * and popup.  GTT is 1K per MB of aperture size, and popup is 4K.
 	 */
-	if (IS_G4X(dev) || IS_IGD(dev) || IS_IGDNG(dev))
+	if (IS_G4X(dev) || IS_PINEVIEW(dev) || IS_IRONLAKE(dev))
 		overhead = 4096;
 	else
 		overhead = (*aperture_size / 1024) + 4096;
@@ -1048,7 +1054,7 @@
 	int gtt_offset, gtt_size;
 
 	if (IS_I965G(dev)) {
-		if (IS_G4X(dev) || IS_IGDNG(dev)) {
+		if (IS_G4X(dev) || IS_IRONLAKE(dev)) {
 			gtt_offset = 2*1024*1024;
 			gtt_size = 2*1024*1024;
 		} else {
@@ -1070,7 +1076,7 @@
 
 	entry = *(volatile u32 *)(gtt + (gtt_addr / 1024));
 
-	DRM_DEBUG("GTT addr: 0x%08lx, PTE: 0x%08lx\n", gtt_addr, entry);
+	DRM_DEBUG_DRIVER("GTT addr: 0x%08lx, PTE: 0x%08lx\n", gtt_addr, entry);
 
 	/* Mask out these reserved bits on this hardware. */
 	if (!IS_I9XX(dev) || IS_I915G(dev) || IS_I915GM(dev) ||
@@ -1096,7 +1102,7 @@
 	phys =(entry & PTE_ADDRESS_MASK) |
 		((uint64_t)(entry & PTE_ADDRESS_MASK_HIGH) << (32 - 4));
 
-	DRM_DEBUG("GTT addr: 0x%08lx, phys addr: 0x%08lx\n", gtt_addr, phys);
+	DRM_DEBUG_DRIVER("GTT addr: 0x%08lx, phys addr: 0x%08lx\n", gtt_addr, phys);
 
 	return phys;
 }
@@ -1306,7 +1312,7 @@
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	u32 tmp;
 
-	if (!IS_IGD(dev))
+	if (!IS_PINEVIEW(dev))
 		return;
 
 	tmp = I915_READ(CLKCFG);
@@ -1413,7 +1419,7 @@
 	if (ret)
 		goto out_iomapfree;
 
-	dev_priv->wq = create_workqueue("i915");
+	dev_priv->wq = create_singlethread_workqueue("i915");
 	if (dev_priv->wq == NULL) {
 		DRM_ERROR("Failed to create our workqueue.\n");
 		ret = -ENOMEM;
@@ -1434,7 +1440,7 @@
 
 	dev->driver->get_vblank_counter = i915_get_vblank_counter;
 	dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
-	if (IS_G4X(dev) || IS_IGDNG(dev)) {
+	if (IS_G4X(dev) || IS_IRONLAKE(dev)) {
 		dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */
 		dev->driver->get_vblank_counter = gm45_get_vblank_counter;
 	}
@@ -1489,9 +1495,7 @@
 	}
 
 	/* Must be done after probing outputs */
-	/* FIXME: verify on IGDNG */
-	if (!IS_IGDNG(dev))
-		intel_opregion_init(dev, 0);
+	intel_opregion_init(dev, 0);
 
 	setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed,
 		    (unsigned long) dev);
@@ -1525,6 +1529,15 @@
 	}
 
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+		/*
+		 * free the memory space allocated for the child device
+		 * config parsed from VBT
+		 */
+		if (dev_priv->child_dev && dev_priv->child_dev_num) {
+			kfree(dev_priv->child_dev);
+			dev_priv->child_dev = NULL;
+			dev_priv->child_dev_num = 0;
+		}
 		drm_irq_uninstall(dev);
 		vga_client_register(dev->pdev, NULL, NULL, NULL);
 	}
@@ -1535,8 +1548,7 @@
 	if (dev_priv->regs != NULL)
 		iounmap(dev_priv->regs);
 
-	if (!IS_IGDNG(dev))
-		intel_opregion_free(dev, 0);
+	intel_opregion_free(dev, 0);
 
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
 		intel_modeset_cleanup(dev);
@@ -1548,6 +1560,8 @@
 		mutex_unlock(&dev->struct_mutex);
 		drm_mm_takedown(&dev_priv->vram);
 		i915_gem_lastclose(dev);
+
+		intel_cleanup_overlay(dev);
 	}
 
 	pci_dev_put(dev_priv->bridge_dev);
@@ -1656,6 +1670,8 @@
 	DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, 0),
 	DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, 0),
 	DRM_IOCTL_DEF(DRM_I915_GEM_MADVISE, i915_gem_madvise_ioctl, 0),
+	DRM_IOCTL_DEF(DRM_I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW),
+	DRM_IOCTL_DEF(DRM_I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW),
 };
 
 int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 7f436ec..2fa2178 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -333,6 +333,7 @@
 		 .mmap = drm_gem_mmap,
 		 .poll = drm_poll,
 		 .fasync = drm_fasync,
+		 .read = drm_read,
 #ifdef CONFIG_COMPAT
 		 .compat_ioctl = i915_compat_ioctl,
 #endif
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a725f659..fbecac7 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -170,6 +170,8 @@
 	/* clock gating init */
 };
 
+struct intel_overlay;
+
 typedef struct drm_i915_private {
 	struct drm_device *dev;
 
@@ -187,6 +189,7 @@
 	unsigned int status_gfx_addr;
 	drm_local_map_t hws_map;
 	struct drm_gem_object *hws_obj;
+	struct drm_gem_object *pwrctx;
 
 	struct resource mch_res;
 
@@ -206,11 +209,13 @@
 	/** Cached value of IMR to avoid reads in updating the bitfield */
 	u32 irq_mask_reg;
 	u32 pipestat[2];
-	/** splitted irq regs for graphics and display engine on IGDNG,
+	/** splitted irq regs for graphics and display engine on Ironlake,
 	    irq_mask_reg is still used for display irq. */
 	u32 gt_irq_mask_reg;
 	u32 gt_irq_enable_reg;
 	u32 de_irq_enable_reg;
+	u32 pch_irq_mask_reg;
+	u32 pch_irq_enable_reg;
 
 	u32 hotplug_supported_mask;
 	struct work_struct hotplug_work;
@@ -240,6 +245,9 @@
 
 	struct intel_opregion opregion;
 
+	/* overlay */
+	struct intel_overlay *overlay;
+
 	/* LVDS info */
 	int backlight_duty_cycle;  /* restore backlight to this value */
 	bool panel_wants_dither;
@@ -258,7 +266,7 @@
 
 	struct notifier_block lid_notifier;
 
-	int crt_ddc_bus; /* -1 = unknown, else GPIO to use for CRT DDC */
+	int crt_ddc_bus; /* 0 = unknown, else GPIO to use for CRT DDC */
 	struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */
 	int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
 	int num_fence_regs; /* 8 on pre-965, 16 otherwise */
@@ -280,6 +288,7 @@
 	u32 saveDSPBCNTR;
 	u32 saveDSPARB;
 	u32 saveRENDERSTANDBY;
+	u32 savePWRCTXA;
 	u32 saveHWS;
 	u32 savePIPEACONF;
 	u32 savePIPEBCONF;
@@ -374,8 +383,6 @@
 	u32 saveFDI_RXA_IMR;
 	u32 saveFDI_RXB_IMR;
 	u32 saveCACHE_MODE_0;
-	u32 saveD_STATE;
-	u32 saveDSPCLK_GATE_D;
 	u32 saveMI_ARB_STATE;
 	u32 saveSWF0[16];
 	u32 saveSWF1[16];
@@ -539,13 +546,21 @@
 	/* indicate whether the LVDS_BORDER should be enabled or not */
 	unsigned int lvds_border_bits;
 
+	struct drm_crtc *plane_to_crtc_mapping[2];
+	struct drm_crtc *pipe_to_crtc_mapping[2];
+	wait_queue_head_t pending_flip_queue;
+
 	/* Reclocking support */
 	bool render_reclock_avail;
 	bool lvds_downclock_avail;
+	/* indicates the reduced downclock for LVDS*/
+	int lvds_downclock;
 	struct work_struct idle_work;
 	struct timer_list idle_timer;
 	bool busy;
 	u16 orig_clock;
+	int child_dev_num;
+	struct child_device_config *child_dev;
 } drm_i915_private_t;
 
 /** driver private structure attached to each drm_gem_object */
@@ -638,6 +653,13 @@
 	 * Advice: are the backing pages purgeable?
 	 */
 	int madv;
+
+	/**
+	 * Number of crtcs where this object is currently the fb, but
+	 * will be page flipped away on the next vblank.  When it
+	 * reaches 0, dev_priv->pending_flip_queue will be woken up.
+	 */
+	atomic_t pending_flip;
 };
 
 /**
@@ -738,6 +760,8 @@
 void
 i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
 
+void intel_enable_asle (struct drm_device *dev);
+
 
 /* i915_mem.c */
 extern int i915_mem_alloc(struct drm_device *dev, void *data,
@@ -813,6 +837,9 @@
 int i915_gem_do_init(struct drm_device *dev, unsigned long start,
 		     unsigned long end);
 int i915_gem_idle(struct drm_device *dev);
+uint32_t i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
+			  uint32_t flush_domains);
+int i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible);
 int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
 int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj,
 				      int write);
@@ -824,6 +851,7 @@
 int i915_gem_object_get_pages(struct drm_gem_object *obj);
 void i915_gem_object_put_pages(struct drm_gem_object *obj);
 void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv);
+void i915_gem_object_flush_write_domain(struct drm_gem_object *obj);
 
 void i915_gem_shrinker_init(void);
 void i915_gem_shrinker_exit(void);
@@ -863,11 +891,13 @@
 extern int intel_opregion_init(struct drm_device *dev, int resume);
 extern void intel_opregion_free(struct drm_device *dev, int suspend);
 extern void opregion_asle_intr(struct drm_device *dev);
+extern void ironlake_opregion_gse_intr(struct drm_device *dev);
 extern void opregion_enable_asle(struct drm_device *dev);
 #else
 static inline int intel_opregion_init(struct drm_device *dev, int resume) { return 0; }
 static inline void intel_opregion_free(struct drm_device *dev, int suspend) { return; }
 static inline void opregion_asle_intr(struct drm_device *dev) { return; }
+static inline void ironlake_opregion_gse_intr(struct drm_device *dev) { return; }
 static inline void opregion_enable_asle(struct drm_device *dev) { return; }
 #endif
 
@@ -955,8 +985,8 @@
 #define IS_I830(dev) ((dev)->pci_device == 0x3577)
 #define IS_845G(dev) ((dev)->pci_device == 0x2562)
 #define IS_I85X(dev) ((dev)->pci_device == 0x3582)
-#define IS_I855(dev) ((dev)->pci_device == 0x3582)
 #define IS_I865G(dev) ((dev)->pci_device == 0x2572)
+#define IS_I8XX(dev) (IS_I830(dev) || IS_845G(dev) || IS_I85X(dev) || IS_I865G(dev))
 
 #define IS_I915G(dev) ((dev)->pci_device == 0x2582 || (dev)->pci_device == 0x258a)
 #define IS_I915GM(dev) ((dev)->pci_device == 0x2592)
@@ -990,47 +1020,51 @@
 		     (dev)->pci_device == 0x2E42 || \
 		     IS_GM45(dev))
 
-#define IS_IGDG(dev) ((dev)->pci_device == 0xa001)
-#define IS_IGDGM(dev) ((dev)->pci_device == 0xa011)
-#define IS_IGD(dev) (IS_IGDG(dev) || IS_IGDGM(dev))
+#define IS_PINEVIEW_G(dev) ((dev)->pci_device == 0xa001)
+#define IS_PINEVIEW_M(dev) ((dev)->pci_device == 0xa011)
+#define IS_PINEVIEW(dev) (IS_PINEVIEW_G(dev) || IS_PINEVIEW_M(dev))
 
 #define IS_G33(dev)    ((dev)->pci_device == 0x29C2 ||	\
 			(dev)->pci_device == 0x29B2 ||	\
 			(dev)->pci_device == 0x29D2 ||  \
-			(IS_IGD(dev)))
+			(IS_PINEVIEW(dev)))
 
-#define IS_IGDNG_D(dev)	((dev)->pci_device == 0x0042)
-#define IS_IGDNG_M(dev)	((dev)->pci_device == 0x0046)
-#define IS_IGDNG(dev)	(IS_IGDNG_D(dev) || IS_IGDNG_M(dev))
+#define IS_IRONLAKE_D(dev)	((dev)->pci_device == 0x0042)
+#define IS_IRONLAKE_M(dev)	((dev)->pci_device == 0x0046)
+#define IS_IRONLAKE(dev)	(IS_IRONLAKE_D(dev) || IS_IRONLAKE_M(dev))
 
 #define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \
 		      IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev) || \
-		      IS_IGDNG(dev))
+		      IS_IRONLAKE(dev))
 
 #define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \
 			IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev) || \
-			IS_IGD(dev) || IS_IGDNG_M(dev))
+			IS_PINEVIEW(dev) || IS_IRONLAKE_M(dev))
 
 #define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev) || \
-				IS_IGDNG(dev))
+				IS_IRONLAKE(dev))
 /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
  * rows, which changed the alignment requirements and fence programming.
  */
 #define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \
 						      IS_I915GM(dev)))
-#define SUPPORTS_INTEGRATED_HDMI(dev)	(IS_G4X(dev) || IS_IGDNG(dev))
-#define SUPPORTS_INTEGRATED_DP(dev)	(IS_G4X(dev) || IS_IGDNG(dev))
-#define SUPPORTS_EDP(dev)		(IS_IGDNG_M(dev))
+#define SUPPORTS_DIGITAL_OUTPUTS(dev)	(IS_I9XX(dev) && !IS_PINEVIEW(dev))
+#define SUPPORTS_INTEGRATED_HDMI(dev)	(IS_G4X(dev) || IS_IRONLAKE(dev))
+#define SUPPORTS_INTEGRATED_DP(dev)	(IS_G4X(dev) || IS_IRONLAKE(dev))
+#define SUPPORTS_EDP(dev)		(IS_IRONLAKE_M(dev))
+#define SUPPORTS_TV(dev)		(IS_I9XX(dev) && IS_MOBILE(dev) && \
+					!IS_IRONLAKE(dev) && !IS_PINEVIEW(dev))
 #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev) || IS_I965G(dev))
 /* dsparb controlled by hw only */
-#define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev))
+#define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IRONLAKE(dev))
 
-#define HAS_FW_BLC(dev) (IS_I9XX(dev) || IS_G4X(dev) || IS_IGDNG(dev))
-#define HAS_PIPE_CXSR(dev) (IS_G4X(dev) || IS_IGDNG(dev))
+#define HAS_FW_BLC(dev) (IS_I9XX(dev) || IS_G4X(dev) || IS_IRONLAKE(dev))
+#define HAS_PIPE_CXSR(dev) (IS_G4X(dev) || IS_IRONLAKE(dev))
 #define I915_HAS_FBC(dev) (IS_MOBILE(dev) && \
 			   (IS_I9XX(dev) || IS_GM45(dev)) && \
-			   !IS_IGD(dev) && \
-			   !IS_IGDNG(dev))
+			   !IS_PINEVIEW(dev) && \
+			   !IS_IRONLAKE(dev))
+#define I915_HAS_RC6(dev) (IS_I965GM(dev) || IS_GM45(dev) || IS_IRONLAKE_M(dev))
 
 #define PRIMARY_RINGBUFFER_SIZE         (128*1024)
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index abfc27b..8c463cf 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1288,6 +1288,7 @@
 	list->hash.key = list->file_offset_node->start;
 	if (drm_ht_insert_item(&mm->offset_hash, &list->hash)) {
 		DRM_ERROR("failed to add to map hash\n");
+		ret = -ENOMEM;
 		goto out_free_mm;
 	}
 
@@ -1309,7 +1310,7 @@
  * i915_gem_release_mmap - remove physical page mappings
  * @obj: obj in question
  *
- * Preserve the reservation of the mmaping with the DRM core code, but
+ * Preserve the reservation of the mmapping with the DRM core code, but
  * relinquish ownership of the pages back to the system.
  *
  * It is vital that we remove the page mapping if we have mapped a tiled
@@ -1583,7 +1584,7 @@
  *
  * Returned sequence numbers are nonzero on success.
  */
-static uint32_t
+uint32_t
 i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
 		 uint32_t flush_domains)
 {
@@ -1617,7 +1618,7 @@
 	OUT_RING(MI_USER_INTERRUPT);
 	ADVANCE_LP_RING();
 
-	DRM_DEBUG("%d\n", seqno);
+	DRM_DEBUG_DRIVER("%d\n", seqno);
 
 	request->seqno = seqno;
 	request->emitted_jiffies = jiffies;
@@ -1820,12 +1821,8 @@
 	mutex_unlock(&dev->struct_mutex);
 }
 
-/**
- * Waits for a sequence number to be signaled, and cleans up the
- * request and object lists appropriately for that event.
- */
-static int
-i915_wait_request(struct drm_device *dev, uint32_t seqno)
+int
+i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	u32 ier;
@@ -1837,7 +1834,7 @@
 		return -EIO;
 
 	if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) {
-		if (IS_IGDNG(dev))
+		if (IS_IRONLAKE(dev))
 			ier = I915_READ(DEIER) | I915_READ(GTIER);
 		else
 			ier = I915_READ(IER);
@@ -1852,10 +1849,15 @@
 
 		dev_priv->mm.waiting_gem_seqno = seqno;
 		i915_user_irq_get(dev);
-		ret = wait_event_interruptible(dev_priv->irq_queue,
-					       i915_seqno_passed(i915_get_gem_seqno(dev),
-								 seqno) ||
-					       atomic_read(&dev_priv->mm.wedged));
+		if (interruptible)
+			ret = wait_event_interruptible(dev_priv->irq_queue,
+				i915_seqno_passed(i915_get_gem_seqno(dev), seqno) ||
+				atomic_read(&dev_priv->mm.wedged));
+		else
+			wait_event(dev_priv->irq_queue,
+				i915_seqno_passed(i915_get_gem_seqno(dev), seqno) ||
+				atomic_read(&dev_priv->mm.wedged));
+
 		i915_user_irq_put(dev);
 		dev_priv->mm.waiting_gem_seqno = 0;
 
@@ -1879,6 +1881,16 @@
 	return ret;
 }
 
+/**
+ * Waits for a sequence number to be signaled, and cleans up the
+ * request and object lists appropriately for that event.
+ */
+static int
+i915_wait_request(struct drm_device *dev, uint32_t seqno)
+{
+	return i915_do_wait_request(dev, seqno, 1);
+}
+
 static void
 i915_gem_flush(struct drm_device *dev,
 	       uint32_t invalidate_domains,
@@ -1947,7 +1959,7 @@
 #endif
 		BEGIN_LP_RING(2);
 		OUT_RING(cmd);
-		OUT_RING(0); /* noop */
+		OUT_RING(MI_NOOP);
 		ADVANCE_LP_RING();
 	}
 }
@@ -2760,6 +2772,22 @@
 					    old_write_domain);
 }
 
+void
+i915_gem_object_flush_write_domain(struct drm_gem_object *obj)
+{
+	switch (obj->write_domain) {
+	case I915_GEM_DOMAIN_GTT:
+		i915_gem_object_flush_gtt_write_domain(obj);
+		break;
+	case I915_GEM_DOMAIN_CPU:
+		i915_gem_object_flush_cpu_write_domain(obj);
+		break;
+	default:
+		i915_gem_object_flush_gpu_write_domain(obj);
+		break;
+	}
+}
+
 /**
  * Moves a single object to the GTT read, and possibly write domain.
  *
@@ -3525,6 +3553,41 @@
 	return 0;
 }
 
+static int
+i915_gem_wait_for_pending_flip(struct drm_device *dev,
+			       struct drm_gem_object **object_list,
+			       int count)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj_priv;
+	DEFINE_WAIT(wait);
+	int i, ret = 0;
+
+	for (;;) {
+		prepare_to_wait(&dev_priv->pending_flip_queue,
+				&wait, TASK_INTERRUPTIBLE);
+		for (i = 0; i < count; i++) {
+			obj_priv = object_list[i]->driver_private;
+			if (atomic_read(&obj_priv->pending_flip) > 0)
+				break;
+		}
+		if (i == count)
+			break;
+
+		if (!signal_pending(current)) {
+			mutex_unlock(&dev->struct_mutex);
+			schedule();
+			mutex_lock(&dev->struct_mutex);
+			continue;
+		}
+		ret = -ERESTARTSYS;
+		break;
+	}
+	finish_wait(&dev_priv->pending_flip_queue, &wait);
+
+	return ret;
+}
+
 int
 i915_gem_execbuffer(struct drm_device *dev, void *data,
 		    struct drm_file *file_priv)
@@ -3540,7 +3603,7 @@
 	int ret, ret2, i, pinned = 0;
 	uint64_t exec_offset;
 	uint32_t seqno, flush_domains, reloc_index;
-	int pin_tries;
+	int pin_tries, flips;
 
 #if WATCH_EXEC
 	DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
@@ -3552,8 +3615,8 @@
 		return -EINVAL;
 	}
 	/* Copy in the exec list from userland */
-	exec_list = drm_calloc_large(sizeof(*exec_list), args->buffer_count);
-	object_list = drm_calloc_large(sizeof(*object_list), args->buffer_count);
+	exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count);
+	object_list = drm_malloc_ab(sizeof(*object_list), args->buffer_count);
 	if (exec_list == NULL || object_list == NULL) {
 		DRM_ERROR("Failed to allocate exec or object list "
 			  "for %d buffers\n",
@@ -3598,20 +3661,19 @@
 	i915_verify_inactive(dev, __FILE__, __LINE__);
 
 	if (atomic_read(&dev_priv->mm.wedged)) {
-		DRM_ERROR("Execbuf while wedged\n");
 		mutex_unlock(&dev->struct_mutex);
 		ret = -EIO;
 		goto pre_mutex_err;
 	}
 
 	if (dev_priv->mm.suspended) {
-		DRM_ERROR("Execbuf while VT-switched.\n");
 		mutex_unlock(&dev->struct_mutex);
 		ret = -EBUSY;
 		goto pre_mutex_err;
 	}
 
 	/* Look up object handles */
+	flips = 0;
 	for (i = 0; i < args->buffer_count; i++) {
 		object_list[i] = drm_gem_object_lookup(dev, file_priv,
 						       exec_list[i].handle);
@@ -3630,6 +3692,14 @@
 			goto err;
 		}
 		obj_priv->in_execbuffer = true;
+		flips += atomic_read(&obj_priv->pending_flip);
+	}
+
+	if (flips > 0) {
+		ret = i915_gem_wait_for_pending_flip(dev, object_list,
+						     args->buffer_count);
+		if (ret)
+			goto err;
 	}
 
 	/* Pin and relocate */
@@ -4356,7 +4426,7 @@
 	memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
 	I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
 	I915_READ(HWS_PGA); /* posting read */
-	DRM_DEBUG("hws offset: 0x%08x\n", dev_priv->status_gfx_addr);
+	DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr);
 
 	return 0;
 }
@@ -4614,8 +4684,8 @@
 			for (i = 0; i < 8; i++)
 				I915_WRITE(FENCE_REG_945_8 + (i * 4), 0);
 	}
-
 	i915_gem_detect_bit_6_swizzle(dev);
+	init_waitqueue_head(&dev_priv->pending_flip_queue);
 }
 
 /*
@@ -4790,7 +4860,7 @@
 	user_data = (char __user *) (uintptr_t) args->data_ptr;
 	obj_addr = obj_priv->phys_obj->handle->vaddr + args->offset;
 
-	DRM_DEBUG("obj_addr %p, %lld\n", obj_addr, args->size);
+	DRM_DEBUG_DRIVER("obj_addr %p, %lld\n", obj_addr, args->size);
 	ret = copy_from_user(obj_addr, user_data, args->size);
 	if (ret)
 		return -EFAULT;
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index 200e398..30d6af6c 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -121,7 +121,7 @@
 				     0,   pcibios_align_resource,
 				     dev_priv->bridge_dev);
 	if (ret) {
-		DRM_DEBUG("failed bus alloc: %d\n", ret);
+		DRM_DEBUG_DRIVER("failed bus alloc: %d\n", ret);
 		dev_priv->mch_res.start = 0;
 		goto out;
 	}
@@ -209,8 +209,8 @@
 	uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
 	bool need_disable;
 
-	if (IS_IGDNG(dev)) {
-		/* On IGDNG whatever DRAM config, GPU always do
+	if (IS_IRONLAKE(dev)) {
+		/* On Ironlake whatever DRAM config, GPU always do
 		 * same swizzling setup.
 		 */
 		swizzle_x = I915_BIT_6_SWIZZLE_9_10;
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index aa7fd82..85f4c5d 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -43,10 +43,13 @@
  * we leave them always unmasked in IMR and then control enabling them through
  * PIPESTAT alone.
  */
-#define I915_INTERRUPT_ENABLE_FIX (I915_ASLE_INTERRUPT |		 \
-				   I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
-				   I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | \
-				   I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
+#define I915_INTERRUPT_ENABLE_FIX			\
+	(I915_ASLE_INTERRUPT |				\
+	 I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |		\
+	 I915_DISPLAY_PIPE_B_EVENT_INTERRUPT |		\
+	 I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |	\
+	 I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT |	\
+	 I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
 
 /** Interrupts that we mask and unmask at runtime. */
 #define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT)
@@ -61,7 +64,7 @@
 					 DRM_I915_VBLANK_PIPE_B)
 
 void
-igdng_enable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask)
+ironlake_enable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask)
 {
 	if ((dev_priv->gt_irq_mask_reg & mask) != 0) {
 		dev_priv->gt_irq_mask_reg &= ~mask;
@@ -71,7 +74,7 @@
 }
 
 static inline void
-igdng_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask)
+ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask)
 {
 	if ((dev_priv->gt_irq_mask_reg & mask) != mask) {
 		dev_priv->gt_irq_mask_reg |= mask;
@@ -82,7 +85,7 @@
 
 /* For display hotplug interrupt */
 void
-igdng_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
+ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
 {
 	if ((dev_priv->irq_mask_reg & mask) != 0) {
 		dev_priv->irq_mask_reg &= ~mask;
@@ -92,7 +95,7 @@
 }
 
 static inline void
-igdng_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
+ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
 {
 	if ((dev_priv->irq_mask_reg & mask) != mask) {
 		dev_priv->irq_mask_reg |= mask;
@@ -157,6 +160,20 @@
 }
 
 /**
+ * intel_enable_asle - enable ASLE interrupt for OpRegion
+ */
+void intel_enable_asle (struct drm_device *dev)
+{
+	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+
+	if (IS_IRONLAKE(dev))
+		ironlake_enable_display_irq(dev_priv, DE_GSE);
+	else
+		i915_enable_pipestat(dev_priv, 1,
+				     I915_LEGACY_BLC_EVENT_ENABLE);
+}
+
+/**
  * i915_pipe_enabled - check if a pipe is enabled
  * @dev: DRM device
  * @pipe: pipe to check
@@ -191,7 +208,8 @@
 	low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
 
 	if (!i915_pipe_enabled(dev, pipe)) {
-		DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe);
+		DRM_DEBUG_DRIVER("trying to get vblank count for disabled "
+				"pipe %d\n", pipe);
 		return 0;
 	}
 
@@ -220,7 +238,8 @@
 	int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45;
 
 	if (!i915_pipe_enabled(dev, pipe)) {
-		DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe);
+		DRM_DEBUG_DRIVER("trying to get vblank count for disabled "
+					"pipe %d\n", pipe);
 		return 0;
 	}
 
@@ -250,12 +269,12 @@
 	drm_sysfs_hotplug_event(dev);
 }
 
-irqreturn_t igdng_irq_handler(struct drm_device *dev)
+irqreturn_t ironlake_irq_handler(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	int ret = IRQ_NONE;
-	u32 de_iir, gt_iir, de_ier;
-	u32 new_de_iir, new_gt_iir;
+	u32 de_iir, gt_iir, de_ier, pch_iir;
+	u32 new_de_iir, new_gt_iir, new_pch_iir;
 	struct drm_i915_master_private *master_priv;
 
 	/* disable master interrupt before clearing iir  */
@@ -265,13 +284,18 @@
 
 	de_iir = I915_READ(DEIIR);
 	gt_iir = I915_READ(GTIIR);
+	pch_iir = I915_READ(SDEIIR);
 
 	for (;;) {
-		if (de_iir == 0 && gt_iir == 0)
+		if (de_iir == 0 && gt_iir == 0 && pch_iir == 0)
 			break;
 
 		ret = IRQ_HANDLED;
 
+		/* should clear PCH hotplug event before clear CPU irq */
+		I915_WRITE(SDEIIR, pch_iir);
+		new_pch_iir = I915_READ(SDEIIR);
+
 		I915_WRITE(DEIIR, de_iir);
 		new_de_iir = I915_READ(DEIIR);
 		I915_WRITE(GTIIR, gt_iir);
@@ -291,8 +315,18 @@
 			DRM_WAKEUP(&dev_priv->irq_queue);
 		}
 
+		if (de_iir & DE_GSE)
+			ironlake_opregion_gse_intr(dev);
+
+		/* check event from PCH */
+		if ((de_iir & DE_PCH_EVENT) &&
+			(pch_iir & SDE_HOTPLUG_MASK)) {
+			queue_work(dev_priv->wq, &dev_priv->hotplug_work);
+		}
+
 		de_iir = new_de_iir;
 		gt_iir = new_gt_iir;
+		pch_iir = new_pch_iir;
 	}
 
 	I915_WRITE(DEIER, de_ier);
@@ -317,19 +351,19 @@
 	char *reset_event[] = { "RESET=1", NULL };
 	char *reset_done_event[] = { "ERROR=0", NULL };
 
-	DRM_DEBUG("generating error event\n");
+	DRM_DEBUG_DRIVER("generating error event\n");
 	kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, error_event);
 
 	if (atomic_read(&dev_priv->mm.wedged)) {
 		if (IS_I965G(dev)) {
-			DRM_DEBUG("resetting chip\n");
+			DRM_DEBUG_DRIVER("resetting chip\n");
 			kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_event);
 			if (!i965_reset(dev, GDRST_RENDER)) {
 				atomic_set(&dev_priv->mm.wedged, 0);
 				kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_done_event);
 			}
 		} else {
-			printk("reboot required\n");
+			DRM_DEBUG_DRIVER("reboot required\n");
 		}
 	}
 }
@@ -355,7 +389,7 @@
 
 	error = kmalloc(sizeof(*error), GFP_ATOMIC);
 	if (!error) {
-		DRM_DEBUG("out ot memory, not capturing error state\n");
+		DRM_DEBUG_DRIVER("out ot memory, not capturing error state\n");
 		goto out;
 	}
 
@@ -512,7 +546,6 @@
 		/*
 		 * Wakeup waiting processes so they don't hang
 		 */
-		printk("i915: Waking up sleeping processes\n");
 		DRM_WAKEUP(&dev_priv->irq_queue);
 	}
 
@@ -535,8 +568,8 @@
 
 	atomic_inc(&dev_priv->irq_received);
 
-	if (IS_IGDNG(dev))
-		return igdng_irq_handler(dev);
+	if (IS_IRONLAKE(dev))
+		return ironlake_irq_handler(dev);
 
 	iir = I915_READ(IIR);
 
@@ -568,14 +601,14 @@
 		 */
 		if (pipea_stats & 0x8000ffff) {
 			if (pipea_stats &  PIPE_FIFO_UNDERRUN_STATUS)
-				DRM_DEBUG("pipe a underrun\n");
+				DRM_DEBUG_DRIVER("pipe a underrun\n");
 			I915_WRITE(PIPEASTAT, pipea_stats);
 			irq_received = 1;
 		}
 
 		if (pipeb_stats & 0x8000ffff) {
 			if (pipeb_stats &  PIPE_FIFO_UNDERRUN_STATUS)
-				DRM_DEBUG("pipe b underrun\n");
+				DRM_DEBUG_DRIVER("pipe b underrun\n");
 			I915_WRITE(PIPEBSTAT, pipeb_stats);
 			irq_received = 1;
 		}
@@ -591,7 +624,7 @@
 		    (iir & I915_DISPLAY_PORT_INTERRUPT)) {
 			u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT);
 
-			DRM_DEBUG("hotplug event received, stat 0x%08x\n",
+			DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n",
 				  hotplug_status);
 			if (hotplug_status & dev_priv->hotplug_supported_mask)
 				queue_work(dev_priv->wq,
@@ -599,27 +632,6 @@
 
 			I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
 			I915_READ(PORT_HOTPLUG_STAT);
-
-			/* EOS interrupts occurs */
-			if (IS_IGD(dev) &&
-				(hotplug_status & CRT_EOS_INT_STATUS)) {
-				u32 temp;
-
-				DRM_DEBUG("EOS interrupt occurs\n");
-				/* status is already cleared */
-				temp = I915_READ(ADPA);
-				temp &= ~ADPA_DAC_ENABLE;
-				I915_WRITE(ADPA, temp);
-
-				temp = I915_READ(PORT_HOTPLUG_EN);
-				temp &= ~CRT_EOS_INT_EN;
-				I915_WRITE(PORT_HOTPLUG_EN, temp);
-
-				temp = I915_READ(PORT_HOTPLUG_STAT);
-				if (temp & CRT_EOS_INT_STATUS)
-					I915_WRITE(PORT_HOTPLUG_STAT,
-						CRT_EOS_INT_STATUS);
-			}
 		}
 
 		I915_WRITE(IIR, iir);
@@ -641,14 +653,22 @@
 			mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
 		}
 
+		if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT)
+			intel_prepare_page_flip(dev, 0);
+
+		if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT)
+			intel_prepare_page_flip(dev, 1);
+
 		if (pipea_stats & vblank_status) {
 			vblank++;
 			drm_handle_vblank(dev, 0);
+			intel_finish_page_flip(dev, 0);
 		}
 
 		if (pipeb_stats & vblank_status) {
 			vblank++;
 			drm_handle_vblank(dev, 1);
+			intel_finish_page_flip(dev, 1);
 		}
 
 		if ((pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) ||
@@ -684,7 +704,7 @@
 
 	i915_kernel_lost_context(dev);
 
-	DRM_DEBUG("\n");
+	DRM_DEBUG_DRIVER("\n");
 
 	dev_priv->counter++;
 	if (dev_priv->counter > 0x7FFFFFFFUL)
@@ -709,8 +729,8 @@
 
 	spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
 	if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) {
-		if (IS_IGDNG(dev))
-			igdng_enable_graphics_irq(dev_priv, GT_USER_INTERRUPT);
+		if (IS_IRONLAKE(dev))
+			ironlake_enable_graphics_irq(dev_priv, GT_USER_INTERRUPT);
 		else
 			i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
 	}
@@ -725,8 +745,8 @@
 	spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
 	BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0);
 	if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) {
-		if (IS_IGDNG(dev))
-			igdng_disable_graphics_irq(dev_priv, GT_USER_INTERRUPT);
+		if (IS_IRONLAKE(dev))
+			ironlake_disable_graphics_irq(dev_priv, GT_USER_INTERRUPT);
 		else
 			i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
 	}
@@ -749,7 +769,7 @@
 	struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
 	int ret = 0;
 
-	DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr,
+	DRM_DEBUG_DRIVER("irq_nr=%d breadcrumb=%d\n", irq_nr,
 		  READ_BREADCRUMB(dev_priv));
 
 	if (READ_BREADCRUMB(dev_priv) >= irq_nr) {
@@ -832,7 +852,7 @@
 	if (!(pipeconf & PIPEACONF_ENABLE))
 		return -EINVAL;
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		return 0;
 
 	spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
@@ -854,7 +874,7 @@
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	unsigned long irqflags;
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		return;
 
 	spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
@@ -868,7 +888,7 @@
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	if (!IS_IGDNG(dev))
+	if (!IS_IRONLAKE(dev))
 		opregion_enable_asle(dev);
 	dev_priv->irq_enabled = 1;
 }
@@ -976,7 +996,7 @@
 
 /* drm_dma.h hooks
 */
-static void igdng_irq_preinstall(struct drm_device *dev)
+static void ironlake_irq_preinstall(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 
@@ -992,14 +1012,21 @@
 	I915_WRITE(GTIMR, 0xffffffff);
 	I915_WRITE(GTIER, 0x0);
 	(void) I915_READ(GTIER);
+
+	/* south display irq */
+	I915_WRITE(SDEIMR, 0xffffffff);
+	I915_WRITE(SDEIER, 0x0);
+	(void) I915_READ(SDEIER);
 }
 
-static int igdng_irq_postinstall(struct drm_device *dev)
+static int ironlake_irq_postinstall(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	/* enable kind of interrupts always enabled */
-	u32 display_mask = DE_MASTER_IRQ_CONTROL /*| DE_PCH_EVENT */;
+	u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT;
 	u32 render_mask = GT_USER_INTERRUPT;
+	u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG |
+			   SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG;
 
 	dev_priv->irq_mask_reg = ~display_mask;
 	dev_priv->de_irq_enable_reg = display_mask;
@@ -1019,6 +1046,14 @@
 	I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg);
 	(void) I915_READ(GTIER);
 
+	dev_priv->pch_irq_mask_reg = ~hotplug_mask;
+	dev_priv->pch_irq_enable_reg = hotplug_mask;
+
+	I915_WRITE(SDEIIR, I915_READ(SDEIIR));
+	I915_WRITE(SDEIMR, dev_priv->pch_irq_mask_reg);
+	I915_WRITE(SDEIER, dev_priv->pch_irq_enable_reg);
+	(void) I915_READ(SDEIER);
+
 	return 0;
 }
 
@@ -1031,8 +1066,8 @@
 	INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
 	INIT_WORK(&dev_priv->error_work, i915_error_work_func);
 
-	if (IS_IGDNG(dev)) {
-		igdng_irq_preinstall(dev);
+	if (IS_IRONLAKE(dev)) {
+		ironlake_irq_preinstall(dev);
 		return;
 	}
 
@@ -1059,8 +1094,8 @@
 
 	dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
 
-	if (IS_IGDNG(dev))
-		return igdng_irq_postinstall(dev);
+	if (IS_IRONLAKE(dev))
+		return ironlake_irq_postinstall(dev);
 
 	/* Unmask the interrupts that we always want on. */
 	dev_priv->irq_mask_reg = ~I915_INTERRUPT_ENABLE_FIX;
@@ -1120,7 +1155,7 @@
 	return 0;
 }
 
-static void igdng_irq_uninstall(struct drm_device *dev)
+static void ironlake_irq_uninstall(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	I915_WRITE(HWSTAM, 0xffffffff);
@@ -1143,8 +1178,8 @@
 
 	dev_priv->vblank_pipe = 0;
 
-	if (IS_IGDNG(dev)) {
-		igdng_irq_uninstall(dev);
+	if (IS_IRONLAKE(dev)) {
+		ironlake_irq_uninstall(dev);
 		return;
 	}
 
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c
index 2d51935..7cc8410 100644
--- a/drivers/gpu/drm/i915/i915_opregion.c
+++ b/drivers/gpu/drm/i915/i915_opregion.c
@@ -118,6 +118,10 @@
 #define ASLE_BACKLIGHT_FAIL    (2<<12)
 #define ASLE_PFIT_FAIL         (2<<14)
 #define ASLE_PWM_FREQ_FAIL     (2<<16)
+#define ASLE_ALS_ILLUM_FAILED	(1<<10)
+#define ASLE_BACKLIGHT_FAILED	(1<<12)
+#define ASLE_PFIT_FAILED	(1<<14)
+#define ASLE_PWM_FREQ_FAILED	(1<<16)
 
 /* ASLE backlight brightness to set */
 #define ASLE_BCLP_VALID                (1<<31)
@@ -163,7 +167,7 @@
 	if (IS_I965G(dev) && (blc_pwm_ctl2 & BLM_COMBINATION_MODE))
 		pci_write_config_dword(dev->pdev, PCI_LBPC, bclp);
 	else {
-		if (IS_IGD(dev)) {
+		if (IS_PINEVIEW(dev)) {
 			blc_pwm_ctl &= ~(BACKLIGHT_DUTY_CYCLE_MASK - 1);
 			max_backlight = (blc_pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >> 
 					BACKLIGHT_MODULATION_FREQ_SHIFT;
@@ -224,7 +228,7 @@
 	asle_req = asle->aslc & ASLE_REQ_MSK;
 
 	if (!asle_req) {
-		DRM_DEBUG("non asle set request??\n");
+		DRM_DEBUG_DRIVER("non asle set request??\n");
 		return;
 	}
 
@@ -243,6 +247,73 @@
 	asle->aslc = asle_stat;
 }
 
+static u32 asle_set_backlight_ironlake(struct drm_device *dev, u32 bclp)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct opregion_asle *asle = dev_priv->opregion.asle;
+	u32 cpu_pwm_ctl, pch_pwm_ctl2;
+	u32 max_backlight, level;
+
+	if (!(bclp & ASLE_BCLP_VALID))
+		return ASLE_BACKLIGHT_FAILED;
+
+	bclp &= ASLE_BCLP_MSK;
+	if (bclp < 0 || bclp > 255)
+		return ASLE_BACKLIGHT_FAILED;
+
+	cpu_pwm_ctl = I915_READ(BLC_PWM_CPU_CTL);
+	pch_pwm_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
+	/* get the max PWM frequency */
+	max_backlight = (pch_pwm_ctl2 >> 16) & BACKLIGHT_DUTY_CYCLE_MASK;
+	/* calculate the expected PMW frequency */
+	level = (bclp * max_backlight) / 255;
+	/* reserve the high 16 bits */
+	cpu_pwm_ctl &= ~(BACKLIGHT_DUTY_CYCLE_MASK);
+	/* write the updated PWM frequency */
+	I915_WRITE(BLC_PWM_CPU_CTL, cpu_pwm_ctl | level);
+
+	asle->cblv = (bclp*0x64)/0xff | ASLE_CBLV_VALID;
+
+	return 0;
+}
+
+void ironlake_opregion_gse_intr(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct opregion_asle *asle = dev_priv->opregion.asle;
+	u32 asle_stat = 0;
+	u32 asle_req;
+
+	if (!asle)
+		return;
+
+	asle_req = asle->aslc & ASLE_REQ_MSK;
+
+	if (!asle_req) {
+		DRM_DEBUG_DRIVER("non asle set request??\n");
+		return;
+	}
+
+	if (asle_req & ASLE_SET_ALS_ILLUM) {
+		DRM_DEBUG_DRIVER("Illum is not supported\n");
+		asle_stat |= ASLE_ALS_ILLUM_FAILED;
+	}
+
+	if (asle_req & ASLE_SET_BACKLIGHT)
+		asle_stat |= asle_set_backlight_ironlake(dev, asle->bclp);
+
+	if (asle_req & ASLE_SET_PFIT) {
+		DRM_DEBUG_DRIVER("Pfit is not supported\n");
+		asle_stat |= ASLE_PFIT_FAILED;
+	}
+
+	if (asle_req & ASLE_SET_PWM_FREQ) {
+		DRM_DEBUG_DRIVER("PWM freq is not supported\n");
+		asle_stat |= ASLE_PWM_FREQ_FAILED;
+	}
+
+	asle->aslc = asle_stat;
+}
 #define ASLE_ALS_EN    (1<<0)
 #define ASLE_BLC_EN    (1<<1)
 #define ASLE_PFIT_EN   (1<<2)
@@ -258,8 +329,7 @@
 			unsigned long irqflags;
 
 			spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
-			i915_enable_pipestat(dev_priv, 1,
-					     I915_LEGACY_BLC_EVENT_ENABLE);
+			intel_enable_asle(dev);
 			spin_unlock_irqrestore(&dev_priv->user_irq_lock,
 					       irqflags);
 		}
@@ -361,9 +431,9 @@
 	int err = 0;
 
 	pci_read_config_dword(dev->pdev, PCI_ASLS, &asls);
-	DRM_DEBUG("graphic opregion physical addr: 0x%x\n", asls);
+	DRM_DEBUG_DRIVER("graphic opregion physical addr: 0x%x\n", asls);
 	if (asls == 0) {
-		DRM_DEBUG("ACPI OpRegion not supported!\n");
+		DRM_DEBUG_DRIVER("ACPI OpRegion not supported!\n");
 		return -ENOTSUPP;
 	}
 
@@ -373,30 +443,30 @@
 
 	opregion->header = base;
 	if (memcmp(opregion->header->signature, OPREGION_SIGNATURE, 16)) {
-		DRM_DEBUG("opregion signature mismatch\n");
+		DRM_DEBUG_DRIVER("opregion signature mismatch\n");
 		err = -EINVAL;
 		goto err_out;
 	}
 
 	mboxes = opregion->header->mboxes;
 	if (mboxes & MBOX_ACPI) {
-		DRM_DEBUG("Public ACPI methods supported\n");
+		DRM_DEBUG_DRIVER("Public ACPI methods supported\n");
 		opregion->acpi = base + OPREGION_ACPI_OFFSET;
 		if (drm_core_check_feature(dev, DRIVER_MODESET))
 			intel_didl_outputs(dev);
 	} else {
-		DRM_DEBUG("Public ACPI methods not supported\n");
+		DRM_DEBUG_DRIVER("Public ACPI methods not supported\n");
 		err = -ENOTSUPP;
 		goto err_out;
 	}
 	opregion->enabled = 1;
 
 	if (mboxes & MBOX_SWSCI) {
-		DRM_DEBUG("SWSCI supported\n");
+		DRM_DEBUG_DRIVER("SWSCI supported\n");
 		opregion->swsci = base + OPREGION_SWSCI_OFFSET;
 	}
 	if (mboxes & MBOX_ASLE) {
-		DRM_DEBUG("ASLE supported\n");
+		DRM_DEBUG_DRIVER("ASLE supported\n");
 		opregion->asle = base + OPREGION_ASLE_OFFSET;
 		opregion_enable_asle(dev);
 	}
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 1687edf..974b3cf 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -140,6 +140,7 @@
 #define MI_NOOP			MI_INSTR(0, 0)
 #define MI_USER_INTERRUPT	MI_INSTR(0x02, 0)
 #define MI_WAIT_FOR_EVENT       MI_INSTR(0x03, 0)
+#define   MI_WAIT_FOR_OVERLAY_FLIP	(1<<16)
 #define   MI_WAIT_FOR_PLANE_B_FLIP      (1<<6)
 #define   MI_WAIT_FOR_PLANE_A_FLIP      (1<<2)
 #define   MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
@@ -151,7 +152,13 @@
 #define   MI_END_SCENE		(1 << 4) /* flush binner and incr scene count */
 #define MI_BATCH_BUFFER_END	MI_INSTR(0x0a, 0)
 #define MI_REPORT_HEAD		MI_INSTR(0x07, 0)
+#define MI_OVERLAY_FLIP		MI_INSTR(0x11,0)
+#define   MI_OVERLAY_CONTINUE	(0x0<<21)
+#define   MI_OVERLAY_ON		(0x1<<21)
+#define   MI_OVERLAY_OFF	(0x2<<21)
 #define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
+#define MI_DISPLAY_FLIP		MI_INSTR(0x14, 2)
+#define   MI_DISPLAY_FLIP_PLANE(n) ((n) << 20)
 #define MI_STORE_DWORD_IMM	MI_INSTR(0x20, 1)
 #define   MI_MEM_VIRTUAL	(1 << 22) /* 965+ only */
 #define MI_STORE_DWORD_INDEX	MI_INSTR(0x21, 1)
@@ -260,6 +267,8 @@
 #define HWS_PGA		0x02080
 #define HWS_ADDRESS_MASK	0xfffff000
 #define HWS_START_ADDRESS_SHIFT	4
+#define PWRCTXA		0x2088 /* 965GM+ only */
+#define   PWRCTX_EN	(1<<0)
 #define IPEIR		0x02088
 #define IPEHR		0x0208c
 #define INSTDONE	0x02090
@@ -405,6 +414,13 @@
 # define GPIO_DATA_VAL_IN		(1 << 12)
 # define GPIO_DATA_PULLUP_DISABLE	(1 << 13)
 
+#define GMBUS0			0x5100
+#define GMBUS1			0x5104
+#define GMBUS2			0x5108
+#define GMBUS3			0x510c
+#define GMBUS4			0x5110
+#define GMBUS5			0x5120
+
 /*
  * Clock control & power management
  */
@@ -435,7 +451,7 @@
 #define   DPLLB_LVDS_P2_CLOCK_DIV_7	(1 << 24) /* i915 */
 #define   DPLL_P2_CLOCK_DIV_MASK	0x03000000 /* i915 */
 #define   DPLL_FPA01_P1_POST_DIV_MASK	0x00ff0000 /* i915 */
-#define   DPLL_FPA01_P1_POST_DIV_MASK_IGD	0x00ff8000 /* IGD */
+#define   DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW	0x00ff8000 /* Pineview */
 
 #define I915_FIFO_UNDERRUN_STATUS		(1UL<<31)
 #define I915_CRC_ERROR_ENABLE			(1UL<<29)
@@ -512,7 +528,7 @@
  */
 #define   DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS	0x003f0000
 #define   DPLL_FPA01_P1_POST_DIV_SHIFT	16
-#define   DPLL_FPA01_P1_POST_DIV_SHIFT_IGD 15
+#define   DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW 15
 /* i830, required in DVO non-gang */
 #define   PLL_P2_DIVIDE_BY_4		(1 << 23)
 #define   PLL_P1_DIVIDE_BY_TWO		(1 << 21) /* i830 */
@@ -522,7 +538,7 @@
 #define   PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
 #define   PLL_REF_INPUT_MASK		(3 << 13)
 #define   PLL_LOAD_PULSE_PHASE_SHIFT		9
-/* IGDNG */
+/* Ironlake */
 # define PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT     9
 # define PLL_REF_SDVO_HDMI_MULTIPLIER_MASK      (7 << 9)
 # define PLL_REF_SDVO_HDMI_MULTIPLIER(x)	(((x)-1) << 9)
@@ -586,12 +602,12 @@
 #define FPB0	0x06048
 #define FPB1	0x0604c
 #define   FP_N_DIV_MASK		0x003f0000
-#define   FP_N_IGD_DIV_MASK	0x00ff0000
+#define   FP_N_PINEVIEW_DIV_MASK	0x00ff0000
 #define   FP_N_DIV_SHIFT		16
 #define   FP_M1_DIV_MASK	0x00003f00
 #define   FP_M1_DIV_SHIFT		 8
 #define   FP_M2_DIV_MASK	0x0000003f
-#define   FP_M2_IGD_DIV_MASK	0x000000ff
+#define   FP_M2_PINEVIEW_DIV_MASK	0x000000ff
 #define   FP_M2_DIV_SHIFT		 0
 #define DPLL_TEST	0x606c
 #define   DPLLB_TEST_SDVO_DIV_1		(0 << 22)
@@ -769,7 +785,8 @@
 
 /** GM965 GM45 render standby register */
 #define MCHBAR_RENDER_STANDBY	0x111B8
-
+#define   RCX_SW_EXIT		(1<<23)
+#define   RSX_STATUS_MASK	0x00700000
 #define PEG_BAND_GAP_DATA	0x14d68
 
 /*
@@ -844,7 +861,6 @@
 #define   SDVOB_HOTPLUG_INT_EN			(1 << 26)
 #define   SDVOC_HOTPLUG_INT_EN			(1 << 25)
 #define   TV_HOTPLUG_INT_EN			(1 << 18)
-#define   CRT_EOS_INT_EN			(1 << 10)
 #define   CRT_HOTPLUG_INT_EN			(1 << 9)
 #define   CRT_HOTPLUG_FORCE_DETECT		(1 << 3)
 #define CRT_HOTPLUG_ACTIVATION_PERIOD_32	(0 << 8)
@@ -868,7 +884,6 @@
 			 HDMID_HOTPLUG_INT_EN |	  \
 			 SDVOB_HOTPLUG_INT_EN |	  \
 			 SDVOC_HOTPLUG_INT_EN |	  \
-			 TV_HOTPLUG_INT_EN |	  \
 			 CRT_HOTPLUG_INT_EN)
 
 
@@ -879,7 +894,6 @@
 #define   DPC_HOTPLUG_INT_STATUS		(1 << 28)
 #define   HDMID_HOTPLUG_INT_STATUS		(1 << 27)
 #define   DPD_HOTPLUG_INT_STATUS		(1 << 27)
-#define   CRT_EOS_INT_STATUS			(1 << 12)
 #define   CRT_HOTPLUG_INT_STATUS		(1 << 11)
 #define   TV_HOTPLUG_INT_STATUS			(1 << 10)
 #define   CRT_HOTPLUG_MONITOR_MASK		(3 << 8)
@@ -1620,7 +1634,7 @@
 #define   DP_CLOCK_OUTPUT_ENABLE	(1 << 13)
 
 #define   DP_SCRAMBLING_DISABLE		(1 << 12)
-#define   DP_SCRAMBLING_DISABLE_IGDNG	(1 << 7)
+#define   DP_SCRAMBLING_DISABLE_IRONLAKE	(1 << 7)
 
 /** limit RGB values to avoid confusing TVs */
 #define   DP_COLOR_RANGE_16_235		(1 << 8)
@@ -1808,7 +1822,7 @@
 #define DSPFW3			0x7003c
 #define   DSPFW_HPLL_SR_EN	(1<<31)
 #define   DSPFW_CURSOR_SR_SHIFT	24
-#define   IGD_SELF_REFRESH_EN	(1<<30)
+#define   PINEVIEW_SELF_REFRESH_EN	(1<<30)
 
 /* FIFO watermark sizes etc */
 #define G4X_FIFO_LINE_SIZE	64
@@ -1824,16 +1838,16 @@
 #define G4X_MAX_WM		0x3f
 #define I915_MAX_WM		0x3f
 
-#define IGD_DISPLAY_FIFO	512 /* in 64byte unit */
-#define IGD_FIFO_LINE_SIZE	64
-#define IGD_MAX_WM		0x1ff
-#define IGD_DFT_WM		0x3f
-#define IGD_DFT_HPLLOFF_WM	0
-#define IGD_GUARD_WM		10
-#define IGD_CURSOR_FIFO		64
-#define IGD_CURSOR_MAX_WM	0x3f
-#define IGD_CURSOR_DFT_WM	0
-#define IGD_CURSOR_GUARD_WM	5
+#define PINEVIEW_DISPLAY_FIFO	512 /* in 64byte unit */
+#define PINEVIEW_FIFO_LINE_SIZE	64
+#define PINEVIEW_MAX_WM		0x1ff
+#define PINEVIEW_DFT_WM		0x3f
+#define PINEVIEW_DFT_HPLLOFF_WM	0
+#define PINEVIEW_GUARD_WM		10
+#define PINEVIEW_CURSOR_FIFO		64
+#define PINEVIEW_CURSOR_MAX_WM	0x3f
+#define PINEVIEW_CURSOR_DFT_WM	0
+#define PINEVIEW_CURSOR_GUARD_WM	5
 
 /*
  * The two pipe frame counter registers are not synchronized, so
@@ -1907,6 +1921,7 @@
 #define   DISPPLANE_16BPP			(0x5<<26)
 #define   DISPPLANE_32BPP_NO_ALPHA		(0x6<<26)
 #define   DISPPLANE_32BPP			(0x7<<26)
+#define   DISPPLANE_32BPP_30BIT_NO_ALPHA	(0xa<<26)
 #define   DISPPLANE_STEREO_ENABLE		(1<<25)
 #define   DISPPLANE_STEREO_DISABLE		0
 #define   DISPPLANE_SEL_PIPE_MASK		(1<<24)
@@ -1918,7 +1933,7 @@
 #define   DISPPLANE_NO_LINE_DOUBLE		0
 #define   DISPPLANE_STEREO_POLARITY_FIRST	0
 #define   DISPPLANE_STEREO_POLARITY_SECOND	(1<<18)
-#define   DISPPLANE_TRICKLE_FEED_DISABLE	(1<<14) /* IGDNG */
+#define   DISPPLANE_TRICKLE_FEED_DISABLE	(1<<14) /* Ironlake */
 #define   DISPPLANE_TILED			(1<<10)
 #define DSPAADDR		0x70184
 #define DSPASTRIDE		0x70188
@@ -1971,7 +1986,7 @@
 # define VGA_2X_MODE				(1 << 30)
 # define VGA_PIPE_B_SELECT			(1 << 29)
 
-/* IGDNG */
+/* Ironlake */
 
 #define CPU_VGACNTRL	0x41000
 
@@ -2117,6 +2132,7 @@
 #define SDE_PORTC_HOTPLUG       (1 << 9)
 #define SDE_PORTB_HOTPLUG       (1 << 8)
 #define SDE_SDVOB_HOTPLUG       (1 << 6)
+#define SDE_HOTPLUG_MASK	(0xf << 8)
 
 #define SDEISR  0xc4000
 #define SDEIMR  0xc4004
@@ -2157,6 +2173,13 @@
 #define PCH_GPIOE               0xc5020
 #define PCH_GPIOF               0xc5024
 
+#define PCH_GMBUS0		0xc5100
+#define PCH_GMBUS1		0xc5104
+#define PCH_GMBUS2		0xc5108
+#define PCH_GMBUS3		0xc510c
+#define PCH_GMBUS4		0xc5110
+#define PCH_GMBUS5		0xc5120
+
 #define PCH_DPLL_A              0xc6014
 #define PCH_DPLL_B              0xc6018
 
@@ -2292,7 +2315,7 @@
 #define  FDI_DP_PORT_WIDTH_X3           (2<<19)
 #define  FDI_DP_PORT_WIDTH_X4           (3<<19)
 #define  FDI_TX_ENHANCE_FRAME_ENABLE    (1<<18)
-/* IGDNG: hardwired to 1 */
+/* Ironlake: hardwired to 1 */
 #define  FDI_TX_PLL_ENABLE              (1<<14)
 /* both Tx and Rx */
 #define  FDI_SCRAMBLING_ENABLE          (0<<7)
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
index 6eec817..d5ebb00 100644
--- a/drivers/gpu/drm/i915/i915_suspend.c
+++ b/drivers/gpu/drm/i915/i915_suspend.c
@@ -27,14 +27,14 @@
 #include "drmP.h"
 #include "drm.h"
 #include "i915_drm.h"
-#include "i915_drv.h"
+#include "intel_drv.h"
 
 static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32	dpll_reg;
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		dpll_reg = (pipe == PIPE_A) ? PCH_DPLL_A: PCH_DPLL_B;
 	} else {
 		dpll_reg = (pipe == PIPE_A) ? DPLL_A: DPLL_B;
@@ -53,7 +53,7 @@
 	if (!i915_pipe_enabled(dev, pipe))
 		return;
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B;
 
 	if (pipe == PIPE_A)
@@ -75,7 +75,7 @@
 	if (!i915_pipe_enabled(dev, pipe))
 		return;
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B;
 
 	if (pipe == PIPE_A)
@@ -239,7 +239,7 @@
 	if (drm_core_check_feature(dev, DRIVER_MODESET))
 		return;
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL);
 		dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL);
 	}
@@ -247,7 +247,7 @@
 	/* Pipe & plane A info */
 	dev_priv->savePIPEACONF = I915_READ(PIPEACONF);
 	dev_priv->savePIPEASRC = I915_READ(PIPEASRC);
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		dev_priv->saveFPA0 = I915_READ(PCH_FPA0);
 		dev_priv->saveFPA1 = I915_READ(PCH_FPA1);
 		dev_priv->saveDPLL_A = I915_READ(PCH_DPLL_A);
@@ -256,7 +256,7 @@
 		dev_priv->saveFPA1 = I915_READ(FPA1);
 		dev_priv->saveDPLL_A = I915_READ(DPLL_A);
 	}
-	if (IS_I965G(dev) && !IS_IGDNG(dev))
+	if (IS_I965G(dev) && !IS_IRONLAKE(dev))
 		dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD);
 	dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A);
 	dev_priv->saveHBLANK_A = I915_READ(HBLANK_A);
@@ -264,10 +264,10 @@
 	dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A);
 	dev_priv->saveVBLANK_A = I915_READ(VBLANK_A);
 	dev_priv->saveVSYNC_A = I915_READ(VSYNC_A);
-	if (!IS_IGDNG(dev))
+	if (!IS_IRONLAKE(dev))
 		dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		dev_priv->savePIPEA_DATA_M1 = I915_READ(PIPEA_DATA_M1);
 		dev_priv->savePIPEA_DATA_N1 = I915_READ(PIPEA_DATA_N1);
 		dev_priv->savePIPEA_LINK_M1 = I915_READ(PIPEA_LINK_M1);
@@ -304,7 +304,7 @@
 	/* Pipe & plane B info */
 	dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
 	dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC);
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		dev_priv->saveFPB0 = I915_READ(PCH_FPB0);
 		dev_priv->saveFPB1 = I915_READ(PCH_FPB1);
 		dev_priv->saveDPLL_B = I915_READ(PCH_DPLL_B);
@@ -313,7 +313,7 @@
 		dev_priv->saveFPB1 = I915_READ(FPB1);
 		dev_priv->saveDPLL_B = I915_READ(DPLL_B);
 	}
-	if (IS_I965G(dev) && !IS_IGDNG(dev))
+	if (IS_I965G(dev) && !IS_IRONLAKE(dev))
 		dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD);
 	dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B);
 	dev_priv->saveHBLANK_B = I915_READ(HBLANK_B);
@@ -321,10 +321,10 @@
 	dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B);
 	dev_priv->saveVBLANK_B = I915_READ(VBLANK_B);
 	dev_priv->saveVSYNC_B = I915_READ(VSYNC_B);
-	if (!IS_IGDNG(dev))
+	if (!IS_IRONLAKE(dev))
 		dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B);
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		dev_priv->savePIPEB_DATA_M1 = I915_READ(PIPEB_DATA_M1);
 		dev_priv->savePIPEB_DATA_N1 = I915_READ(PIPEB_DATA_N1);
 		dev_priv->savePIPEB_LINK_M1 = I915_READ(PIPEB_LINK_M1);
@@ -369,7 +369,7 @@
 	if (drm_core_check_feature(dev, DRIVER_MODESET))
 		return;
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		dpll_a_reg = PCH_DPLL_A;
 		dpll_b_reg = PCH_DPLL_B;
 		fpa0_reg = PCH_FPA0;
@@ -385,7 +385,7 @@
 		fpb1_reg = FPB1;
 	}
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL);
 		I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL);
 	}
@@ -402,7 +402,7 @@
 	/* Actually enable it */
 	I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A);
 	DRM_UDELAY(150);
-	if (IS_I965G(dev) && !IS_IGDNG(dev))
+	if (IS_I965G(dev) && !IS_IRONLAKE(dev))
 		I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD);
 	DRM_UDELAY(150);
 
@@ -413,10 +413,10 @@
 	I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A);
 	I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A);
 	I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A);
-	if (!IS_IGDNG(dev))
+	if (!IS_IRONLAKE(dev))
 		I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		I915_WRITE(PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1);
 		I915_WRITE(PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1);
 		I915_WRITE(PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1);
@@ -467,7 +467,7 @@
 	/* Actually enable it */
 	I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B);
 	DRM_UDELAY(150);
-	if (IS_I965G(dev) && !IS_IGDNG(dev))
+	if (IS_I965G(dev) && !IS_IRONLAKE(dev))
 		I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
 	DRM_UDELAY(150);
 
@@ -478,10 +478,10 @@
 	I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B);
 	I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B);
 	I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B);
-	if (!IS_IGDNG(dev))
+	if (!IS_IRONLAKE(dev))
 		I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		I915_WRITE(PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1);
 		I915_WRITE(PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1);
 		I915_WRITE(PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1);
@@ -546,14 +546,14 @@
 		dev_priv->saveCURSIZE = I915_READ(CURSIZE);
 
 	/* CRT state */
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		dev_priv->saveADPA = I915_READ(PCH_ADPA);
 	} else {
 		dev_priv->saveADPA = I915_READ(ADPA);
 	}
 
 	/* LVDS state */
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		dev_priv->savePP_CONTROL = I915_READ(PCH_PP_CONTROL);
 		dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1);
 		dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2);
@@ -571,10 +571,10 @@
 			dev_priv->saveLVDS = I915_READ(LVDS);
 	}
 
-	if (!IS_I830(dev) && !IS_845G(dev) && !IS_IGDNG(dev))
+	if (!IS_I830(dev) && !IS_845G(dev) && !IS_IRONLAKE(dev))
 		dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		dev_priv->savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS);
 		dev_priv->savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS);
 		dev_priv->savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR);
@@ -614,7 +614,7 @@
 	dev_priv->saveVGA0 = I915_READ(VGA0);
 	dev_priv->saveVGA1 = I915_READ(VGA1);
 	dev_priv->saveVGA_PD = I915_READ(VGA_PD);
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		dev_priv->saveVGACNTRL = I915_READ(CPU_VGACNTRL);
 	else
 		dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
@@ -656,24 +656,24 @@
 		I915_WRITE(CURSIZE, dev_priv->saveCURSIZE);
 
 	/* CRT state */
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		I915_WRITE(PCH_ADPA, dev_priv->saveADPA);
 	else
 		I915_WRITE(ADPA, dev_priv->saveADPA);
 
 	/* LVDS state */
-	if (IS_I965G(dev) && !IS_IGDNG(dev))
+	if (IS_I965G(dev) && !IS_IRONLAKE(dev))
 		I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2);
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		I915_WRITE(PCH_LVDS, dev_priv->saveLVDS);
 	} else if (IS_MOBILE(dev) && !IS_I830(dev))
 		I915_WRITE(LVDS, dev_priv->saveLVDS);
 
-	if (!IS_I830(dev) && !IS_845G(dev) && !IS_IGDNG(dev))
+	if (!IS_I830(dev) && !IS_845G(dev) && !IS_IRONLAKE(dev))
 		I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL);
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL);
 		I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2);
 		I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL);
@@ -713,7 +713,7 @@
 	}
 
 	/* VGA state */
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL);
 	else
 		I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
@@ -733,8 +733,10 @@
 	pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB);
 
 	/* Render Standby */
-	if (IS_I965G(dev) && IS_MOBILE(dev))
+	if (I915_HAS_RC6(dev)) {
 		dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY);
+		dev_priv->savePWRCTXA = I915_READ(PWRCTXA);
+	}
 
 	/* Hardware status page */
 	dev_priv->saveHWS = I915_READ(HWS_PGA);
@@ -742,7 +744,7 @@
 	i915_save_display(dev);
 
 	/* Interrupt state */
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		dev_priv->saveDEIER = I915_READ(DEIER);
 		dev_priv->saveDEIMR = I915_READ(DEIMR);
 		dev_priv->saveGTIER = I915_READ(GTIER);
@@ -754,10 +756,6 @@
 		dev_priv->saveIMR = I915_READ(IMR);
 	}
 
-	/* Clock gating state */
-	dev_priv->saveD_STATE = I915_READ(D_STATE);
-	dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D); /* Not sure about this */
-
 	/* Cache mode state */
 	dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
 
@@ -796,8 +794,10 @@
 	pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
 
 	/* Render Standby */
-	if (IS_I965G(dev) && IS_MOBILE(dev))
+	if (I915_HAS_RC6(dev)) {
 		I915_WRITE(MCHBAR_RENDER_STANDBY, dev_priv->saveRENDERSTANDBY);
+		I915_WRITE(PWRCTXA, dev_priv->savePWRCTXA);
+	}
 
 	/* Hardware status page */
 	I915_WRITE(HWS_PGA, dev_priv->saveHWS);
@@ -817,7 +817,7 @@
 	i915_restore_display(dev);
 
 	/* Interrupt state */
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		I915_WRITE(DEIER, dev_priv->saveDEIER);
 		I915_WRITE(DEIMR, dev_priv->saveDEIMR);
 		I915_WRITE(GTIER, dev_priv->saveGTIER);
@@ -830,8 +830,7 @@
 	}
 
 	/* Clock gating state */
-	I915_WRITE (D_STATE, dev_priv->saveD_STATE);
-	I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
+	intel_init_clock_gating(dev);
 
 	/* Cache mode state */
 	I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
@@ -846,6 +845,9 @@
 	for (i = 0; i < 3; i++)
 		I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
 
+	/* I2C state */
+	intel_i2c_reset_gmbus(dev);
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 96cd256..f275677 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -114,6 +114,8 @@
 	struct lvds_dvo_timing *dvo_timing;
 	struct drm_display_mode *panel_fixed_mode;
 	int lfp_data_size, dvo_timing_offset;
+	int i, temp_downclock;
+	struct drm_display_mode *temp_mode;
 
 	/* Defaults if we can't find VBT info */
 	dev_priv->lvds_dither = 0;
@@ -159,9 +161,49 @@
 
 	dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;
 
-	DRM_DEBUG("Found panel mode in BIOS VBT tables:\n");
+	DRM_DEBUG_KMS("Found panel mode in BIOS VBT tables:\n");
 	drm_mode_debug_printmodeline(panel_fixed_mode);
 
+	temp_mode = kzalloc(sizeof(*temp_mode), GFP_KERNEL);
+	temp_downclock = panel_fixed_mode->clock;
+	/*
+	 * enumerate the LVDS panel timing info entry in VBT to check whether
+	 * the LVDS downclock is found.
+	 */
+	for (i = 0; i < 16; i++) {
+		entry = (struct bdb_lvds_lfp_data_entry *)
+			((uint8_t *)lvds_lfp_data->data + (lfp_data_size * i));
+		dvo_timing = (struct lvds_dvo_timing *)
+			((unsigned char *)entry + dvo_timing_offset);
+
+		fill_detail_timing_data(temp_mode, dvo_timing);
+
+		if (temp_mode->hdisplay == panel_fixed_mode->hdisplay &&
+		temp_mode->hsync_start == panel_fixed_mode->hsync_start &&
+		temp_mode->hsync_end == panel_fixed_mode->hsync_end &&
+		temp_mode->htotal == panel_fixed_mode->htotal &&
+		temp_mode->vdisplay == panel_fixed_mode->vdisplay &&
+		temp_mode->vsync_start == panel_fixed_mode->vsync_start &&
+		temp_mode->vsync_end == panel_fixed_mode->vsync_end &&
+		temp_mode->vtotal == panel_fixed_mode->vtotal &&
+		temp_mode->clock < temp_downclock) {
+			/*
+			 * downclock is already found. But we expect
+			 * to find the lower downclock.
+			 */
+			temp_downclock = temp_mode->clock;
+		}
+		/* clear it to zero */
+		memset(temp_mode, 0, sizeof(*temp_mode));
+	}
+	kfree(temp_mode);
+	if (temp_downclock < panel_fixed_mode->clock) {
+		dev_priv->lvds_downclock_avail = 1;
+		dev_priv->lvds_downclock = temp_downclock;
+		DRM_DEBUG_KMS("LVDS downclock is found in VBT. ",
+				"Normal Clock %dKHz, downclock %dKHz\n",
+				temp_downclock, panel_fixed_mode->clock);
+	}
 	return;
 }
 
@@ -217,7 +259,7 @@
 			if (IS_I85X(dev_priv->dev))
 				dev_priv->lvds_ssc_freq =
 					general->ssc_freq ? 66 : 48;
-			else if (IS_IGDNG(dev_priv->dev))
+			else if (IS_IRONLAKE(dev_priv->dev))
 				dev_priv->lvds_ssc_freq =
 					general->ssc_freq ? 100 : 120;
 			else
@@ -241,22 +283,18 @@
 		GPIOF,
 	};
 
-	/* Set sensible defaults in case we can't find the general block
-	   or it is the wrong chipset */
-	dev_priv->crt_ddc_bus = -1;
-
 	general = find_section(bdb, BDB_GENERAL_DEFINITIONS);
 	if (general) {
 		u16 block_size = get_blocksize(general);
 		if (block_size >= sizeof(*general)) {
 			int bus_pin = general->crt_ddc_gmbus_pin;
-			DRM_DEBUG("crt_ddc_bus_pin: %d\n", bus_pin);
+			DRM_DEBUG_KMS("crt_ddc_bus_pin: %d\n", bus_pin);
 			if ((bus_pin >= 1) && (bus_pin <= 6)) {
 				dev_priv->crt_ddc_bus =
 					crt_bus_map_table[bus_pin-1];
 			}
 		} else {
-			DRM_DEBUG("BDB_GD too small (%d). Invalid.\n",
+			DRM_DEBUG_KMS("BDB_GD too small (%d). Invalid.\n",
 				  block_size);
 		}
 	}
@@ -274,7 +312,7 @@
 
 	p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
 	if (!p_defs) {
-		DRM_DEBUG("No general definition block is found\n");
+		DRM_DEBUG_KMS("No general definition block is found\n");
 		return;
 	}
 	/* judge whether the size of child device meets the requirements.
@@ -284,7 +322,7 @@
 	 */
 	if (p_defs->child_dev_size != sizeof(*p_child)) {
 		/* different child dev size . Ignore it */
-		DRM_DEBUG("different child size is found. Invalid.\n");
+		DRM_DEBUG_KMS("different child size is found. Invalid.\n");
 		return;
 	}
 	/* get the block size of general definitions */
@@ -310,11 +348,11 @@
 		if (p_child->dvo_port != DEVICE_PORT_DVOB &&
 			p_child->dvo_port != DEVICE_PORT_DVOC) {
 			/* skip the incorrect SDVO port */
-			DRM_DEBUG("Incorrect SDVO port. Skip it \n");
+			DRM_DEBUG_KMS("Incorrect SDVO port. Skip it \n");
 			continue;
 		}
-		DRM_DEBUG("the SDVO device with slave addr %2x is found on "
-				"%s port\n",
+		DRM_DEBUG_KMS("the SDVO device with slave addr %2x is found on"
+				" %s port\n",
 				p_child->slave_addr,
 				(p_child->dvo_port == DEVICE_PORT_DVOB) ?
 					"SDVOB" : "SDVOC");
@@ -325,21 +363,21 @@
 			p_mapping->dvo_wiring = p_child->dvo_wiring;
 			p_mapping->initialized = 1;
 		} else {
-			DRM_DEBUG("Maybe one SDVO port is shared by "
+			DRM_DEBUG_KMS("Maybe one SDVO port is shared by "
 					 "two SDVO device.\n");
 		}
 		if (p_child->slave2_addr) {
 			/* Maybe this is a SDVO device with multiple inputs */
 			/* And the mapping info is not added */
-			DRM_DEBUG("there exists the slave2_addr. Maybe this "
-				"is a SDVO device with multiple inputs.\n");
+			DRM_DEBUG_KMS("there exists the slave2_addr. Maybe this"
+				" is a SDVO device with multiple inputs.\n");
 		}
 		count++;
 	}
 
 	if (!count) {
 		/* No SDVO device info is found */
-		DRM_DEBUG("No SDVO device info is found in VBT\n");
+		DRM_DEBUG_KMS("No SDVO device info is found in VBT\n");
 	}
 	return;
 }
@@ -366,6 +404,70 @@
 		dev_priv->render_reclock_avail = true;
 }
 
+static void
+parse_device_mapping(struct drm_i915_private *dev_priv,
+		       struct bdb_header *bdb)
+{
+	struct bdb_general_definitions *p_defs;
+	struct child_device_config *p_child, *child_dev_ptr;
+	int i, child_device_num, count;
+	u16	block_size;
+
+	p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
+	if (!p_defs) {
+		DRM_DEBUG_KMS("No general definition block is found\n");
+		return;
+	}
+	/* judge whether the size of child device meets the requirements.
+	 * If the child device size obtained from general definition block
+	 * is different with sizeof(struct child_device_config), skip the
+	 * parsing of sdvo device info
+	 */
+	if (p_defs->child_dev_size != sizeof(*p_child)) {
+		/* different child dev size . Ignore it */
+		DRM_DEBUG_KMS("different child size is found. Invalid.\n");
+		return;
+	}
+	/* get the block size of general definitions */
+	block_size = get_blocksize(p_defs);
+	/* get the number of child device */
+	child_device_num = (block_size - sizeof(*p_defs)) /
+				sizeof(*p_child);
+	count = 0;
+	/* get the number of child device that is present */
+	for (i = 0; i < child_device_num; i++) {
+		p_child = &(p_defs->devices[i]);
+		if (!p_child->device_type) {
+			/* skip the device block if device type is invalid */
+			continue;
+		}
+		count++;
+	}
+	if (!count) {
+		DRM_DEBUG_KMS("no child dev is parsed from VBT \n");
+		return;
+	}
+	dev_priv->child_dev = kzalloc(sizeof(*p_child) * count, GFP_KERNEL);
+	if (!dev_priv->child_dev) {
+		DRM_DEBUG_KMS("No memory space for child device\n");
+		return;
+	}
+
+	dev_priv->child_dev_num = count;
+	count = 0;
+	for (i = 0; i < child_device_num; i++) {
+		p_child = &(p_defs->devices[i]);
+		if (!p_child->device_type) {
+			/* skip the device block if device type is invalid */
+			continue;
+		}
+		child_dev_ptr = dev_priv->child_dev + count;
+		count++;
+		memcpy((void *)child_dev_ptr, (void *)p_child,
+					sizeof(*p_child));
+	}
+	return;
+}
 /**
  * intel_init_bios - initialize VBIOS settings & find VBT
  * @dev: DRM device
@@ -417,6 +519,7 @@
 	parse_lfp_panel_data(dev_priv, bdb);
 	parse_sdvo_panel_data(dev_priv, bdb);
 	parse_sdvo_device_mapping(dev_priv, bdb);
+	parse_device_mapping(dev_priv, bdb);
 	parse_driver_features(dev_priv, bdb);
 
 	pci_unmap_rom(pdev, bios);
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index 0f8e5f6..425ac9d 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -549,4 +549,21 @@
 #define   SWF14_APM_STANDBY	0x1
 #define   SWF14_APM_RESTORE	0x0
 
+/* Add the device class for LFP, TV, HDMI */
+#define	 DEVICE_TYPE_INT_LFP	0x1022
+#define	 DEVICE_TYPE_INT_TV	0x1009
+#define	 DEVICE_TYPE_HDMI	0x60D2
+#define	 DEVICE_TYPE_DP		0x68C6
+#define	 DEVICE_TYPE_eDP	0x78C6
+
+/* define the DVO port for HDMI output type */
+#define		DVO_B		1
+#define		DVO_C		2
+#define		DVO_D		3
+
+/* define the PORT for DP output type */
+#define		PORT_IDPB	7
+#define		PORT_IDPC	8
+#define		PORT_IDPD	9
+
 #endif /* _I830_BIOS_H_ */
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index e505144..9f3d3e5 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -39,7 +39,7 @@
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 temp, reg;
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		reg = PCH_ADPA;
 	else
 		reg = ADPA;
@@ -64,34 +64,6 @@
 	}
 
 	I915_WRITE(reg, temp);
-
-	if (IS_IGD(dev)) {
-		if (mode == DRM_MODE_DPMS_OFF) {
-			/* turn off DAC */
-			temp = I915_READ(PORT_HOTPLUG_EN);
-			temp &= ~CRT_EOS_INT_EN;
-			I915_WRITE(PORT_HOTPLUG_EN, temp);
-
-			temp = I915_READ(PORT_HOTPLUG_STAT);
-			if (temp & CRT_EOS_INT_STATUS)
-				I915_WRITE(PORT_HOTPLUG_STAT,
-					CRT_EOS_INT_STATUS);
-		} else {
-			/* turn on DAC. EOS interrupt must be enabled after DAC
-			 * is enabled, so it sounds not good to enable it in
-			 * i915_driver_irq_postinstall()
-			 * wait 12.5ms after DAC is enabled
-			 */
-			msleep(13);
-			temp = I915_READ(PORT_HOTPLUG_STAT);
-			if (temp & CRT_EOS_INT_STATUS)
-				I915_WRITE(PORT_HOTPLUG_STAT,
-					CRT_EOS_INT_STATUS);
-			temp = I915_READ(PORT_HOTPLUG_EN);
-			temp |= CRT_EOS_INT_EN;
-			I915_WRITE(PORT_HOTPLUG_EN, temp);
-		}
-	}
 }
 
 static int intel_crt_mode_valid(struct drm_connector *connector,
@@ -141,7 +113,7 @@
 	else
 		dpll_md_reg = DPLL_B_MD;
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		adpa_reg = PCH_ADPA;
 	else
 		adpa_reg = ADPA;
@@ -150,7 +122,7 @@
 	 * Disable separate mode multiplier used when cloning SDVO to CRT
 	 * XXX this needs to be adjusted when we really are cloning
 	 */
-	if (IS_I965G(dev) && !IS_IGDNG(dev)) {
+	if (IS_I965G(dev) && !IS_IRONLAKE(dev)) {
 		dpll_md = I915_READ(dpll_md_reg);
 		I915_WRITE(dpll_md_reg,
 			   dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
@@ -164,18 +136,18 @@
 
 	if (intel_crtc->pipe == 0) {
 		adpa |= ADPA_PIPE_A_SELECT;
-		if (!IS_IGDNG(dev))
+		if (!IS_IRONLAKE(dev))
 			I915_WRITE(BCLRPAT_A, 0);
 	} else {
 		adpa |= ADPA_PIPE_B_SELECT;
-		if (!IS_IGDNG(dev))
+		if (!IS_IRONLAKE(dev))
 			I915_WRITE(BCLRPAT_B, 0);
 	}
 
 	I915_WRITE(adpa_reg, adpa);
 }
 
-static bool intel_igdng_crt_detect_hotplug(struct drm_connector *connector)
+static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector)
 {
 	struct drm_device *dev = connector->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -194,7 +166,7 @@
 			ADPA_CRT_HOTPLUG_ENABLE |
 			ADPA_CRT_HOTPLUG_FORCE_TRIGGER);
 
-	DRM_DEBUG("pch crt adpa 0x%x", adpa);
+	DRM_DEBUG_KMS("pch crt adpa 0x%x", adpa);
 	I915_WRITE(PCH_ADPA, adpa);
 
 	while ((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) != 0)
@@ -227,8 +199,8 @@
 	u32 hotplug_en;
 	int i, tries = 0;
 
-	if (IS_IGDNG(dev))
-		return intel_igdng_crt_detect_hotplug(connector);
+	if (IS_IRONLAKE(dev))
+		return intel_ironlake_crt_detect_hotplug(connector);
 
 	/*
 	 * On 4 series desktop, CRT detect sequence need to be done twice
@@ -549,12 +521,12 @@
 					  &intel_output->enc);
 
 	/* Set up the DDC bus. */
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		i2c_reg = PCH_GPIOA;
 	else {
 		i2c_reg = GPIOA;
 		/* Use VBT information for CRT DDC if available */
-		if (dev_priv->crt_ddc_bus != -1)
+		if (dev_priv->crt_ddc_bus != 0)
 			i2c_reg = dev_priv->crt_ddc_bus;
 	}
 	intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 099f420..52cd9b0 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -32,7 +32,7 @@
 #include "intel_drv.h"
 #include "i915_drm.h"
 #include "i915_drv.h"
-#include "intel_dp.h"
+#include "drm_dp_helper.h"
 
 #include "drm_crtc_helper.h"
 
@@ -102,32 +102,32 @@
 #define I9XX_DOT_MAX		 400000
 #define I9XX_VCO_MIN		1400000
 #define I9XX_VCO_MAX		2800000
-#define IGD_VCO_MIN		1700000
-#define IGD_VCO_MAX		3500000
+#define PINEVIEW_VCO_MIN		1700000
+#define PINEVIEW_VCO_MAX		3500000
 #define I9XX_N_MIN		      1
 #define I9XX_N_MAX		      6
-/* IGD's Ncounter is a ring counter */
-#define IGD_N_MIN		      3
-#define IGD_N_MAX		      6
+/* Pineview's Ncounter is a ring counter */
+#define PINEVIEW_N_MIN		      3
+#define PINEVIEW_N_MAX		      6
 #define I9XX_M_MIN		     70
 #define I9XX_M_MAX		    120
-#define IGD_M_MIN		      2
-#define IGD_M_MAX		    256
+#define PINEVIEW_M_MIN		      2
+#define PINEVIEW_M_MAX		    256
 #define I9XX_M1_MIN		     10
 #define I9XX_M1_MAX		     22
 #define I9XX_M2_MIN		      5
 #define I9XX_M2_MAX		      9
-/* IGD M1 is reserved, and must be 0 */
-#define IGD_M1_MIN		      0
-#define IGD_M1_MAX		      0
-#define IGD_M2_MIN		      0
-#define IGD_M2_MAX		      254
+/* Pineview M1 is reserved, and must be 0 */
+#define PINEVIEW_M1_MIN		      0
+#define PINEVIEW_M1_MAX		      0
+#define PINEVIEW_M2_MIN		      0
+#define PINEVIEW_M2_MAX		      254
 #define I9XX_P_SDVO_DAC_MIN	      5
 #define I9XX_P_SDVO_DAC_MAX	     80
 #define I9XX_P_LVDS_MIN		      7
 #define I9XX_P_LVDS_MAX		     98
-#define IGD_P_LVDS_MIN		      7
-#define IGD_P_LVDS_MAX		     112
+#define PINEVIEW_P_LVDS_MIN		      7
+#define PINEVIEW_P_LVDS_MAX		     112
 #define I9XX_P1_MIN		      1
 #define I9XX_P1_MAX		      8
 #define I9XX_P2_SDVO_DAC_SLOW		     10
@@ -234,33 +234,33 @@
 #define G4X_P2_DISPLAY_PORT_FAST           10
 #define G4X_P2_DISPLAY_PORT_LIMIT          0
 
-/* IGDNG */
+/* Ironlake */
 /* as we calculate clock using (register_value + 2) for
    N/M1/M2, so here the range value for them is (actual_value-2).
  */
-#define IGDNG_DOT_MIN         25000
-#define IGDNG_DOT_MAX         350000
-#define IGDNG_VCO_MIN         1760000
-#define IGDNG_VCO_MAX         3510000
-#define IGDNG_N_MIN           1
-#define IGDNG_N_MAX           5
-#define IGDNG_M_MIN           79
-#define IGDNG_M_MAX           118
-#define IGDNG_M1_MIN          12
-#define IGDNG_M1_MAX          23
-#define IGDNG_M2_MIN          5
-#define IGDNG_M2_MAX          9
-#define IGDNG_P_SDVO_DAC_MIN  5
-#define IGDNG_P_SDVO_DAC_MAX  80
-#define IGDNG_P_LVDS_MIN      28
-#define IGDNG_P_LVDS_MAX      112
-#define IGDNG_P1_MIN          1
-#define IGDNG_P1_MAX          8
-#define IGDNG_P2_SDVO_DAC_SLOW 10
-#define IGDNG_P2_SDVO_DAC_FAST 5
-#define IGDNG_P2_LVDS_SLOW    14 /* single channel */
-#define IGDNG_P2_LVDS_FAST    7  /* double channel */
-#define IGDNG_P2_DOT_LIMIT    225000 /* 225Mhz */
+#define IRONLAKE_DOT_MIN         25000
+#define IRONLAKE_DOT_MAX         350000
+#define IRONLAKE_VCO_MIN         1760000
+#define IRONLAKE_VCO_MAX         3510000
+#define IRONLAKE_N_MIN           1
+#define IRONLAKE_N_MAX           5
+#define IRONLAKE_M_MIN           79
+#define IRONLAKE_M_MAX           118
+#define IRONLAKE_M1_MIN          12
+#define IRONLAKE_M1_MAX          23
+#define IRONLAKE_M2_MIN          5
+#define IRONLAKE_M2_MAX          9
+#define IRONLAKE_P_SDVO_DAC_MIN  5
+#define IRONLAKE_P_SDVO_DAC_MAX  80
+#define IRONLAKE_P_LVDS_MIN      28
+#define IRONLAKE_P_LVDS_MAX      112
+#define IRONLAKE_P1_MIN          1
+#define IRONLAKE_P1_MAX          8
+#define IRONLAKE_P2_SDVO_DAC_SLOW 10
+#define IRONLAKE_P2_SDVO_DAC_FAST 5
+#define IRONLAKE_P2_LVDS_SLOW    14 /* single channel */
+#define IRONLAKE_P2_LVDS_FAST    7  /* double channel */
+#define IRONLAKE_P2_DOT_LIMIT    225000 /* 225Mhz */
 
 static bool
 intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
@@ -272,15 +272,15 @@
 intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
 			int target, int refclk, intel_clock_t *best_clock);
 static bool
-intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
-			int target, int refclk, intel_clock_t *best_clock);
+intel_ironlake_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
+			     int target, int refclk, intel_clock_t *best_clock);
 
 static bool
 intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc,
 		      int target, int refclk, intel_clock_t *best_clock);
 static bool
-intel_find_pll_igdng_dp(const intel_limit_t *, struct drm_crtc *crtc,
-		      int target, int refclk, intel_clock_t *best_clock);
+intel_find_pll_ironlake_dp(const intel_limit_t *, struct drm_crtc *crtc,
+			   int target, int refclk, intel_clock_t *best_clock);
 
 static const intel_limit_t intel_limits_i8xx_dvo = {
         .dot = { .min = I8XX_DOT_MIN,		.max = I8XX_DOT_MAX },
@@ -453,13 +453,13 @@
         .find_pll = intel_find_pll_g4x_dp,
 };
 
-static const intel_limit_t intel_limits_igd_sdvo = {
+static const intel_limit_t intel_limits_pineview_sdvo = {
         .dot = { .min = I9XX_DOT_MIN,		.max = I9XX_DOT_MAX},
-        .vco = { .min = IGD_VCO_MIN,		.max = IGD_VCO_MAX },
-        .n   = { .min = IGD_N_MIN,		.max = IGD_N_MAX },
-        .m   = { .min = IGD_M_MIN,		.max = IGD_M_MAX },
-        .m1  = { .min = IGD_M1_MIN,		.max = IGD_M1_MAX },
-        .m2  = { .min = IGD_M2_MIN,		.max = IGD_M2_MAX },
+        .vco = { .min = PINEVIEW_VCO_MIN,		.max = PINEVIEW_VCO_MAX },
+        .n   = { .min = PINEVIEW_N_MIN,		.max = PINEVIEW_N_MAX },
+        .m   = { .min = PINEVIEW_M_MIN,		.max = PINEVIEW_M_MAX },
+        .m1  = { .min = PINEVIEW_M1_MIN,		.max = PINEVIEW_M1_MAX },
+        .m2  = { .min = PINEVIEW_M2_MIN,		.max = PINEVIEW_M2_MAX },
         .p   = { .min = I9XX_P_SDVO_DAC_MIN,    .max = I9XX_P_SDVO_DAC_MAX },
         .p1  = { .min = I9XX_P1_MIN,		.max = I9XX_P1_MAX },
 	.p2  = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
@@ -468,59 +468,59 @@
 	.find_reduced_pll = intel_find_best_reduced_PLL,
 };
 
-static const intel_limit_t intel_limits_igd_lvds = {
+static const intel_limit_t intel_limits_pineview_lvds = {
         .dot = { .min = I9XX_DOT_MIN,		.max = I9XX_DOT_MAX },
-        .vco = { .min = IGD_VCO_MIN,		.max = IGD_VCO_MAX },
-        .n   = { .min = IGD_N_MIN,		.max = IGD_N_MAX },
-        .m   = { .min = IGD_M_MIN,		.max = IGD_M_MAX },
-        .m1  = { .min = IGD_M1_MIN,		.max = IGD_M1_MAX },
-        .m2  = { .min = IGD_M2_MIN,		.max = IGD_M2_MAX },
-        .p   = { .min = IGD_P_LVDS_MIN,	.max = IGD_P_LVDS_MAX },
+        .vco = { .min = PINEVIEW_VCO_MIN,		.max = PINEVIEW_VCO_MAX },
+        .n   = { .min = PINEVIEW_N_MIN,		.max = PINEVIEW_N_MAX },
+        .m   = { .min = PINEVIEW_M_MIN,		.max = PINEVIEW_M_MAX },
+        .m1  = { .min = PINEVIEW_M1_MIN,		.max = PINEVIEW_M1_MAX },
+        .m2  = { .min = PINEVIEW_M2_MIN,		.max = PINEVIEW_M2_MAX },
+        .p   = { .min = PINEVIEW_P_LVDS_MIN,	.max = PINEVIEW_P_LVDS_MAX },
         .p1  = { .min = I9XX_P1_MIN,		.max = I9XX_P1_MAX },
-	/* IGD only supports single-channel mode. */
+	/* Pineview only supports single-channel mode. */
 	.p2  = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
 		 .p2_slow = I9XX_P2_LVDS_SLOW,	.p2_fast = I9XX_P2_LVDS_SLOW },
 	.find_pll = intel_find_best_PLL,
 	.find_reduced_pll = intel_find_best_reduced_PLL,
 };
 
-static const intel_limit_t intel_limits_igdng_sdvo = {
-	.dot = { .min = IGDNG_DOT_MIN,          .max = IGDNG_DOT_MAX },
-	.vco = { .min = IGDNG_VCO_MIN,          .max = IGDNG_VCO_MAX },
-	.n   = { .min = IGDNG_N_MIN,            .max = IGDNG_N_MAX },
-	.m   = { .min = IGDNG_M_MIN,            .max = IGDNG_M_MAX },
-	.m1  = { .min = IGDNG_M1_MIN,           .max = IGDNG_M1_MAX },
-	.m2  = { .min = IGDNG_M2_MIN,           .max = IGDNG_M2_MAX },
-	.p   = { .min = IGDNG_P_SDVO_DAC_MIN,   .max = IGDNG_P_SDVO_DAC_MAX },
-	.p1  = { .min = IGDNG_P1_MIN,           .max = IGDNG_P1_MAX },
-	.p2  = { .dot_limit = IGDNG_P2_DOT_LIMIT,
-		 .p2_slow = IGDNG_P2_SDVO_DAC_SLOW,
-		 .p2_fast = IGDNG_P2_SDVO_DAC_FAST },
-	.find_pll = intel_igdng_find_best_PLL,
+static const intel_limit_t intel_limits_ironlake_sdvo = {
+	.dot = { .min = IRONLAKE_DOT_MIN,          .max = IRONLAKE_DOT_MAX },
+	.vco = { .min = IRONLAKE_VCO_MIN,          .max = IRONLAKE_VCO_MAX },
+	.n   = { .min = IRONLAKE_N_MIN,            .max = IRONLAKE_N_MAX },
+	.m   = { .min = IRONLAKE_M_MIN,            .max = IRONLAKE_M_MAX },
+	.m1  = { .min = IRONLAKE_M1_MIN,           .max = IRONLAKE_M1_MAX },
+	.m2  = { .min = IRONLAKE_M2_MIN,           .max = IRONLAKE_M2_MAX },
+	.p   = { .min = IRONLAKE_P_SDVO_DAC_MIN,   .max = IRONLAKE_P_SDVO_DAC_MAX },
+	.p1  = { .min = IRONLAKE_P1_MIN,           .max = IRONLAKE_P1_MAX },
+	.p2  = { .dot_limit = IRONLAKE_P2_DOT_LIMIT,
+		 .p2_slow = IRONLAKE_P2_SDVO_DAC_SLOW,
+		 .p2_fast = IRONLAKE_P2_SDVO_DAC_FAST },
+	.find_pll = intel_ironlake_find_best_PLL,
 };
 
-static const intel_limit_t intel_limits_igdng_lvds = {
-	.dot = { .min = IGDNG_DOT_MIN,          .max = IGDNG_DOT_MAX },
-	.vco = { .min = IGDNG_VCO_MIN,          .max = IGDNG_VCO_MAX },
-	.n   = { .min = IGDNG_N_MIN,            .max = IGDNG_N_MAX },
-	.m   = { .min = IGDNG_M_MIN,            .max = IGDNG_M_MAX },
-	.m1  = { .min = IGDNG_M1_MIN,           .max = IGDNG_M1_MAX },
-	.m2  = { .min = IGDNG_M2_MIN,           .max = IGDNG_M2_MAX },
-	.p   = { .min = IGDNG_P_LVDS_MIN,       .max = IGDNG_P_LVDS_MAX },
-	.p1  = { .min = IGDNG_P1_MIN,           .max = IGDNG_P1_MAX },
-	.p2  = { .dot_limit = IGDNG_P2_DOT_LIMIT,
-		 .p2_slow = IGDNG_P2_LVDS_SLOW,
-		 .p2_fast = IGDNG_P2_LVDS_FAST },
-	.find_pll = intel_igdng_find_best_PLL,
+static const intel_limit_t intel_limits_ironlake_lvds = {
+	.dot = { .min = IRONLAKE_DOT_MIN,          .max = IRONLAKE_DOT_MAX },
+	.vco = { .min = IRONLAKE_VCO_MIN,          .max = IRONLAKE_VCO_MAX },
+	.n   = { .min = IRONLAKE_N_MIN,            .max = IRONLAKE_N_MAX },
+	.m   = { .min = IRONLAKE_M_MIN,            .max = IRONLAKE_M_MAX },
+	.m1  = { .min = IRONLAKE_M1_MIN,           .max = IRONLAKE_M1_MAX },
+	.m2  = { .min = IRONLAKE_M2_MIN,           .max = IRONLAKE_M2_MAX },
+	.p   = { .min = IRONLAKE_P_LVDS_MIN,       .max = IRONLAKE_P_LVDS_MAX },
+	.p1  = { .min = IRONLAKE_P1_MIN,           .max = IRONLAKE_P1_MAX },
+	.p2  = { .dot_limit = IRONLAKE_P2_DOT_LIMIT,
+		 .p2_slow = IRONLAKE_P2_LVDS_SLOW,
+		 .p2_fast = IRONLAKE_P2_LVDS_FAST },
+	.find_pll = intel_ironlake_find_best_PLL,
 };
 
-static const intel_limit_t *intel_igdng_limit(struct drm_crtc *crtc)
+static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc)
 {
 	const intel_limit_t *limit;
 	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
-		limit = &intel_limits_igdng_lvds;
+		limit = &intel_limits_ironlake_lvds;
 	else
-		limit = &intel_limits_igdng_sdvo;
+		limit = &intel_limits_ironlake_sdvo;
 
 	return limit;
 }
@@ -557,20 +557,20 @@
 	struct drm_device *dev = crtc->dev;
 	const intel_limit_t *limit;
 
-	if (IS_IGDNG(dev))
-		limit = intel_igdng_limit(crtc);
+	if (IS_IRONLAKE(dev))
+		limit = intel_ironlake_limit(crtc);
 	else if (IS_G4X(dev)) {
 		limit = intel_g4x_limit(crtc);
-	} else if (IS_I9XX(dev) && !IS_IGD(dev)) {
+	} else if (IS_I9XX(dev) && !IS_PINEVIEW(dev)) {
 		if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
 			limit = &intel_limits_i9xx_lvds;
 		else
 			limit = &intel_limits_i9xx_sdvo;
-	} else if (IS_IGD(dev)) {
+	} else if (IS_PINEVIEW(dev)) {
 		if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
-			limit = &intel_limits_igd_lvds;
+			limit = &intel_limits_pineview_lvds;
 		else
-			limit = &intel_limits_igd_sdvo;
+			limit = &intel_limits_pineview_sdvo;
 	} else {
 		if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
 			limit = &intel_limits_i8xx_lvds;
@@ -580,8 +580,8 @@
 	return limit;
 }
 
-/* m1 is reserved as 0 in IGD, n is a ring counter */
-static void igd_clock(int refclk, intel_clock_t *clock)
+/* m1 is reserved as 0 in Pineview, n is a ring counter */
+static void pineview_clock(int refclk, intel_clock_t *clock)
 {
 	clock->m = clock->m2 + 2;
 	clock->p = clock->p1 * clock->p2;
@@ -591,8 +591,8 @@
 
 static void intel_clock(struct drm_device *dev, int refclk, intel_clock_t *clock)
 {
-	if (IS_IGD(dev)) {
-		igd_clock(refclk, clock);
+	if (IS_PINEVIEW(dev)) {
+		pineview_clock(refclk, clock);
 		return;
 	}
 	clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
@@ -657,7 +657,7 @@
 		INTELPllInvalid ("m2 out of range\n");
 	if (clock->m1  < limit->m1.min  || limit->m1.max  < clock->m1)
 		INTELPllInvalid ("m1 out of range\n");
-	if (clock->m1 <= clock->m2 && !IS_IGD(dev))
+	if (clock->m1 <= clock->m2 && !IS_PINEVIEW(dev))
 		INTELPllInvalid ("m1 <= m2\n");
 	if (clock->m   < limit->m.min   || limit->m.max   < clock->m)
 		INTELPllInvalid ("m out of range\n");
@@ -706,16 +706,17 @@
 
 	memset (best_clock, 0, sizeof (*best_clock));
 
-	for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
-		for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max;
-		     clock.m1++) {
-			for (clock.m2 = limit->m2.min;
-			     clock.m2 <= limit->m2.max; clock.m2++) {
-				/* m1 is always 0 in IGD */
-				if (clock.m2 >= clock.m1 && !IS_IGD(dev))
-					break;
-				for (clock.n = limit->n.min;
-				     clock.n <= limit->n.max; clock.n++) {
+	for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max;
+	     clock.m1++) {
+		for (clock.m2 = limit->m2.min;
+		     clock.m2 <= limit->m2.max; clock.m2++) {
+			/* m1 is always 0 in Pineview */
+			if (clock.m2 >= clock.m1 && !IS_PINEVIEW(dev))
+				break;
+			for (clock.n = limit->n.min;
+			     clock.n <= limit->n.max; clock.n++) {
+				for (clock.p1 = limit->p1.min;
+					clock.p1 <= limit->p1.max; clock.p1++) {
 					int this_err;
 
 					intel_clock(dev, refclk, &clock);
@@ -751,8 +752,8 @@
 
 	for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
 		for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) {
-			/* m1 is always 0 in IGD */
-			if (clock.m2 >= clock.m1 && !IS_IGD(dev))
+			/* m1 is always 0 in Pineview */
+			if (clock.m2 >= clock.m1 && !IS_PINEVIEW(dev))
 				break;
 			for (clock.n = limit->n.min; clock.n <= limit->n.max;
 			     clock.n++) {
@@ -833,8 +834,8 @@
 }
 
 static bool
-intel_find_pll_igdng_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
-		      int target, int refclk, intel_clock_t *best_clock)
+intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
+			   int target, int refclk, intel_clock_t *best_clock)
 {
 	struct drm_device *dev = crtc->dev;
 	intel_clock_t clock;
@@ -857,8 +858,8 @@
 }
 
 static bool
-intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
-			int target, int refclk, intel_clock_t *best_clock)
+intel_ironlake_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
+			     int target, int refclk, intel_clock_t *best_clock)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -871,7 +872,7 @@
 		return true;
 
 	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT))
-		return intel_find_pll_igdng_dp(limit, crtc, target,
+		return intel_find_pll_ironlake_dp(limit, crtc, target,
 					       refclk, best_clock);
 
 	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
@@ -949,7 +950,7 @@
 intel_wait_for_vblank(struct drm_device *dev)
 {
 	/* Wait for 20ms, i.e. one cycle at 50hz. */
-	mdelay(20);
+	msleep(20);
 }
 
 /* Parameters have changed, update FBC info */
@@ -994,7 +995,7 @@
 		fbc_ctl |= dev_priv->cfb_fence;
 	I915_WRITE(FBC_CONTROL, fbc_ctl);
 
-	DRM_DEBUG("enabled FBC, pitch %ld, yoff %d, plane %d, ",
+	DRM_DEBUG_KMS("enabled FBC, pitch %ld, yoff %d, plane %d, ",
 		  dev_priv->cfb_pitch, crtc->y, dev_priv->cfb_plane);
 }
 
@@ -1017,7 +1018,7 @@
 
 	intel_wait_for_vblank(dev);
 
-	DRM_DEBUG("disabled FBC\n");
+	DRM_DEBUG_KMS("disabled FBC\n");
 }
 
 static bool i8xx_fbc_enabled(struct drm_crtc *crtc)
@@ -1062,7 +1063,7 @@
 	/* enable it... */
 	I915_WRITE(DPFC_CONTROL, I915_READ(DPFC_CONTROL) | DPFC_CTL_EN);
 
-	DRM_DEBUG("enabled fbc on plane %d\n", intel_crtc->plane);
+	DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane);
 }
 
 void g4x_disable_fbc(struct drm_device *dev)
@@ -1076,7 +1077,7 @@
 	I915_WRITE(DPFC_CONTROL, dpfc_ctl);
 	intel_wait_for_vblank(dev);
 
-	DRM_DEBUG("disabled FBC\n");
+	DRM_DEBUG_KMS("disabled FBC\n");
 }
 
 static bool g4x_fbc_enabled(struct drm_crtc *crtc)
@@ -1141,25 +1142,27 @@
 	 *   - going to an unsupported config (interlace, pixel multiply, etc.)
 	 */
 	if (intel_fb->obj->size > dev_priv->cfb_size) {
-		DRM_DEBUG("framebuffer too large, disabling compression\n");
+		DRM_DEBUG_KMS("framebuffer too large, disabling "
+				"compression\n");
 		goto out_disable;
 	}
 	if ((mode->flags & DRM_MODE_FLAG_INTERLACE) ||
 	    (mode->flags & DRM_MODE_FLAG_DBLSCAN)) {
-		DRM_DEBUG("mode incompatible with compression, disabling\n");
+		DRM_DEBUG_KMS("mode incompatible with compression, "
+				"disabling\n");
 		goto out_disable;
 	}
 	if ((mode->hdisplay > 2048) ||
 	    (mode->vdisplay > 1536)) {
-		DRM_DEBUG("mode too large for compression, disabling\n");
+		DRM_DEBUG_KMS("mode too large for compression, disabling\n");
 		goto out_disable;
 	}
 	if ((IS_I915GM(dev) || IS_I945GM(dev)) && plane != 0) {
-		DRM_DEBUG("plane not 0, disabling compression\n");
+		DRM_DEBUG_KMS("plane not 0, disabling compression\n");
 		goto out_disable;
 	}
 	if (obj_priv->tiling_mode != I915_TILING_X) {
-		DRM_DEBUG("framebuffer not tiled, disabling compression\n");
+		DRM_DEBUG_KMS("framebuffer not tiled, disabling compression\n");
 		goto out_disable;
 	}
 
@@ -1181,13 +1184,57 @@
 	return;
 
 out_disable:
-	DRM_DEBUG("unsupported config, disabling FBC\n");
+	DRM_DEBUG_KMS("unsupported config, disabling FBC\n");
 	/* Multiple disables should be harmless */
 	if (dev_priv->display.fbc_enabled(crtc))
 		dev_priv->display.disable_fbc(dev);
 }
 
 static int
+intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj)
+{
+	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	u32 alignment;
+	int ret;
+
+	switch (obj_priv->tiling_mode) {
+	case I915_TILING_NONE:
+		alignment = 64 * 1024;
+		break;
+	case I915_TILING_X:
+		/* pin() will align the object as required by fence */
+		alignment = 0;
+		break;
+	case I915_TILING_Y:
+		/* FIXME: Is this true? */
+		DRM_ERROR("Y tiled not allowed for scan out buffers\n");
+		return -EINVAL;
+	default:
+		BUG();
+	}
+
+	ret = i915_gem_object_pin(obj, alignment);
+	if (ret != 0)
+		return ret;
+
+	/* Install a fence for tiled scan-out. Pre-i965 always needs a
+	 * fence, whereas 965+ only requires a fence if using
+	 * framebuffer compression.  For simplicity, we always install
+	 * a fence as the cost is not that onerous.
+	 */
+	if (obj_priv->fence_reg == I915_FENCE_REG_NONE &&
+	    obj_priv->tiling_mode != I915_TILING_NONE) {
+		ret = i915_gem_object_get_fence_reg(obj);
+		if (ret != 0) {
+			i915_gem_object_unpin(obj);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int
 intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 		    struct drm_framebuffer *old_fb)
 {
@@ -1206,12 +1253,12 @@
 	int dspstride = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE;
 	int dsptileoff = (plane == 0 ? DSPATILEOFF : DSPBTILEOFF);
 	int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR;
-	u32 dspcntr, alignment;
+	u32 dspcntr;
 	int ret;
 
 	/* no fb bound */
 	if (!crtc->fb) {
-		DRM_DEBUG("No FB bound\n");
+		DRM_DEBUG_KMS("No FB bound\n");
 		return 0;
 	}
 
@@ -1228,24 +1275,8 @@
 	obj = intel_fb->obj;
 	obj_priv = obj->driver_private;
 
-	switch (obj_priv->tiling_mode) {
-	case I915_TILING_NONE:
-		alignment = 64 * 1024;
-		break;
-	case I915_TILING_X:
-		/* pin() will align the object as required by fence */
-		alignment = 0;
-		break;
-	case I915_TILING_Y:
-		/* FIXME: Is this true? */
-		DRM_ERROR("Y tiled not allowed for scan out buffers\n");
-		return -EINVAL;
-	default:
-		BUG();
-	}
-
 	mutex_lock(&dev->struct_mutex);
-	ret = i915_gem_object_pin(obj, alignment);
+	ret = intel_pin_and_fence_fb_obj(dev, obj);
 	if (ret != 0) {
 		mutex_unlock(&dev->struct_mutex);
 		return ret;
@@ -1258,20 +1289,6 @@
 		return ret;
 	}
 
-	/* Install a fence for tiled scan-out. Pre-i965 always needs a fence,
-	 * whereas 965+ only requires a fence if using framebuffer compression.
-	 * For simplicity, we always install a fence as the cost is not that onerous.
-	 */
-	if (obj_priv->fence_reg == I915_FENCE_REG_NONE &&
-	    obj_priv->tiling_mode != I915_TILING_NONE) {
-		ret = i915_gem_object_get_fence_reg(obj);
-		if (ret != 0) {
-			i915_gem_object_unpin(obj);
-			mutex_unlock(&dev->struct_mutex);
-			return ret;
-		}
-	}
-
 	dspcntr = I915_READ(dspcntr_reg);
 	/* Mask out pixel format bits in case we change it */
 	dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
@@ -1287,7 +1304,10 @@
 		break;
 	case 24:
 	case 32:
-		dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
+		if (crtc->fb->depth == 30)
+			dspcntr |= DISPPLANE_32BPP_30BIT_NO_ALPHA;
+		else
+			dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
 		break;
 	default:
 		DRM_ERROR("Unknown color depth\n");
@@ -1302,7 +1322,7 @@
 			dspcntr &= ~DISPPLANE_TILED;
 	}
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		/* must disable */
 		dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
 
@@ -1311,7 +1331,7 @@
 	Start = obj_priv->gtt_offset;
 	Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
 
-	DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
+	DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
 	I915_WRITE(dspstride, crtc->fb->pitch);
 	if (IS_I965G(dev)) {
 		I915_WRITE(dspbase, Offset);
@@ -1363,7 +1383,7 @@
 	u8 sr1;
 	u32 vga_reg;
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		vga_reg = CPU_VGACNTRL;
 	else
 		vga_reg = VGACNTRL;
@@ -1379,19 +1399,19 @@
 	I915_WRITE(vga_reg, VGA_DISP_DISABLE);
 }
 
-static void igdng_disable_pll_edp (struct drm_crtc *crtc)
+static void ironlake_disable_pll_edp (struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 dpa_ctl;
 
-	DRM_DEBUG("\n");
+	DRM_DEBUG_KMS("\n");
 	dpa_ctl = I915_READ(DP_A);
 	dpa_ctl &= ~DP_PLL_ENABLE;
 	I915_WRITE(DP_A, dpa_ctl);
 }
 
-static void igdng_enable_pll_edp (struct drm_crtc *crtc)
+static void ironlake_enable_pll_edp (struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1404,13 +1424,13 @@
 }
 
 
-static void igdng_set_pll_edp (struct drm_crtc *crtc, int clock)
+static void ironlake_set_pll_edp (struct drm_crtc *crtc, int clock)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 dpa_ctl;
 
-	DRM_DEBUG("eDP PLL enable for clock %d\n", clock);
+	DRM_DEBUG_KMS("eDP PLL enable for clock %d\n", clock);
 	dpa_ctl = I915_READ(DP_A);
 	dpa_ctl &= ~DP_PLL_FREQ_MASK;
 
@@ -1440,7 +1460,7 @@
 	udelay(500);
 }
 
-static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
+static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1481,10 +1501,19 @@
 	case DRM_MODE_DPMS_ON:
 	case DRM_MODE_DPMS_STANDBY:
 	case DRM_MODE_DPMS_SUSPEND:
-		DRM_DEBUG("crtc %d dpms on\n", pipe);
+		DRM_DEBUG_KMS("crtc %d dpms on\n", pipe);
+
+		if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+			temp = I915_READ(PCH_LVDS);
+			if ((temp & LVDS_PORT_EN) == 0) {
+				I915_WRITE(PCH_LVDS, temp | LVDS_PORT_EN);
+				POSTING_READ(PCH_LVDS);
+			}
+		}
+
 		if (HAS_eDP) {
 			/* enable eDP PLL */
-			igdng_enable_pll_edp(crtc);
+			ironlake_enable_pll_edp(crtc);
 		} else {
 			/* enable PCH DPLL */
 			temp = I915_READ(pch_dpll_reg);
@@ -1501,7 +1530,7 @@
 			I915_READ(fdi_rx_reg);
 			udelay(200);
 
-			/* Enable CPU FDI TX PLL, always on for IGDNG */
+			/* Enable CPU FDI TX PLL, always on for Ironlake */
 			temp = I915_READ(fdi_tx_reg);
 			if ((temp & FDI_TX_PLL_ENABLE) == 0) {
 				I915_WRITE(fdi_tx_reg, temp | FDI_TX_PLL_ENABLE);
@@ -1568,12 +1597,13 @@
 			udelay(150);
 
 			temp = I915_READ(fdi_rx_iir_reg);
-			DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp);
+			DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
 
 			if ((temp & FDI_RX_BIT_LOCK) == 0) {
 				for (j = 0; j < tries; j++) {
 					temp = I915_READ(fdi_rx_iir_reg);
-					DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp);
+					DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n",
+								temp);
 					if (temp & FDI_RX_BIT_LOCK)
 						break;
 					udelay(200);
@@ -1582,11 +1612,11 @@
 					I915_WRITE(fdi_rx_iir_reg,
 							temp | FDI_RX_BIT_LOCK);
 				else
-					DRM_DEBUG("train 1 fail\n");
+					DRM_DEBUG_KMS("train 1 fail\n");
 			} else {
 				I915_WRITE(fdi_rx_iir_reg,
 						temp | FDI_RX_BIT_LOCK);
-				DRM_DEBUG("train 1 ok 2!\n");
+				DRM_DEBUG_KMS("train 1 ok 2!\n");
 			}
 			temp = I915_READ(fdi_tx_reg);
 			temp &= ~FDI_LINK_TRAIN_NONE;
@@ -1601,12 +1631,13 @@
 			udelay(150);
 
 			temp = I915_READ(fdi_rx_iir_reg);
-			DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp);
+			DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
 
 			if ((temp & FDI_RX_SYMBOL_LOCK) == 0) {
 				for (j = 0; j < tries; j++) {
 					temp = I915_READ(fdi_rx_iir_reg);
-					DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp);
+					DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n",
+								temp);
 					if (temp & FDI_RX_SYMBOL_LOCK)
 						break;
 					udelay(200);
@@ -1614,15 +1645,15 @@
 				if (j != tries) {
 					I915_WRITE(fdi_rx_iir_reg,
 							temp | FDI_RX_SYMBOL_LOCK);
-					DRM_DEBUG("train 2 ok 1!\n");
+					DRM_DEBUG_KMS("train 2 ok 1!\n");
 				} else
-					DRM_DEBUG("train 2 fail\n");
+					DRM_DEBUG_KMS("train 2 fail\n");
 			} else {
 				I915_WRITE(fdi_rx_iir_reg,
 						temp | FDI_RX_SYMBOL_LOCK);
-				DRM_DEBUG("train 2 ok 2!\n");
+				DRM_DEBUG_KMS("train 2 ok 2!\n");
 			}
-			DRM_DEBUG("train done\n");
+			DRM_DEBUG_KMS("train done\n");
 
 			/* set transcoder timing */
 			I915_WRITE(trans_htot_reg, I915_READ(cpu_htot_reg));
@@ -1664,9 +1695,7 @@
 
 	break;
 	case DRM_MODE_DPMS_OFF:
-		DRM_DEBUG("crtc %d dpms off\n", pipe);
-
-		i915_disable_vga(dev);
+		DRM_DEBUG_KMS("crtc %d dpms off\n", pipe);
 
 		/* Disable display plane */
 		temp = I915_READ(dspcntr_reg);
@@ -1677,6 +1706,8 @@
 			I915_READ(dspbase_reg);
 		}
 
+		i915_disable_vga(dev);
+
 		/* disable cpu pipe, disable after all planes disabled */
 		temp = I915_READ(pipeconf_reg);
 		if ((temp & PIPEACONF_ENABLE) != 0) {
@@ -1690,16 +1721,23 @@
 					udelay(500);
 					continue;
 				} else {
-					DRM_DEBUG("pipe %d off delay\n", pipe);
+					DRM_DEBUG_KMS("pipe %d off delay\n",
+								pipe);
 					break;
 				}
 			}
 		} else
-			DRM_DEBUG("crtc %d is disabled\n", pipe);
+			DRM_DEBUG_KMS("crtc %d is disabled\n", pipe);
 
-		if (HAS_eDP) {
-			igdng_disable_pll_edp(crtc);
+		udelay(100);
+
+		/* Disable PF */
+		temp = I915_READ(pf_ctl_reg);
+		if ((temp & PF_ENABLE) != 0) {
+			I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE);
+			I915_READ(pf_ctl_reg);
 		}
+		I915_WRITE(pf_win_size, 0);
 
 		/* disable CPU FDI tx and PCH FDI rx */
 		temp = I915_READ(fdi_tx_reg);
@@ -1725,6 +1763,13 @@
 
 		udelay(100);
 
+		if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+			temp = I915_READ(PCH_LVDS);
+			I915_WRITE(PCH_LVDS, temp & ~LVDS_PORT_EN);
+			I915_READ(PCH_LVDS);
+			udelay(100);
+		}
+
 		/* disable PCH transcoder */
 		temp = I915_READ(transconf_reg);
 		if ((temp & TRANS_ENABLE) != 0) {
@@ -1738,12 +1783,15 @@
 					udelay(500);
 					continue;
 				} else {
-					DRM_DEBUG("transcoder %d off delay\n", pipe);
+					DRM_DEBUG_KMS("transcoder %d off "
+							"delay\n", pipe);
 					break;
 				}
 			}
 		}
 
+		udelay(100);
+
 		/* disable PCH DPLL */
 		temp = I915_READ(pch_dpll_reg);
 		if ((temp & DPLL_VCO_ENABLE) != 0) {
@@ -1751,14 +1799,20 @@
 			I915_READ(pch_dpll_reg);
 		}
 
-		temp = I915_READ(fdi_rx_reg);
-		if ((temp & FDI_RX_PLL_ENABLE) != 0) {
-			temp &= ~FDI_SEL_PCDCLK;
-			temp &= ~FDI_RX_PLL_ENABLE;
-			I915_WRITE(fdi_rx_reg, temp);
-			I915_READ(fdi_rx_reg);
+		if (HAS_eDP) {
+			ironlake_disable_pll_edp(crtc);
 		}
 
+		temp = I915_READ(fdi_rx_reg);
+		temp &= ~FDI_SEL_PCDCLK;
+		I915_WRITE(fdi_rx_reg, temp);
+		I915_READ(fdi_rx_reg);
+
+		temp = I915_READ(fdi_rx_reg);
+		temp &= ~FDI_RX_PLL_ENABLE;
+		I915_WRITE(fdi_rx_reg, temp);
+		I915_READ(fdi_rx_reg);
+
 		/* Disable CPU FDI TX PLL */
 		temp = I915_READ(fdi_tx_reg);
 		if ((temp & FDI_TX_PLL_ENABLE) != 0) {
@@ -1767,20 +1821,43 @@
 			udelay(100);
 		}
 
-		/* Disable PF */
-		temp = I915_READ(pf_ctl_reg);
-		if ((temp & PF_ENABLE) != 0) {
-			I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE);
-			I915_READ(pf_ctl_reg);
-		}
-		I915_WRITE(pf_win_size, 0);
-
 		/* Wait for the clocks to turn off. */
-		udelay(150);
+		udelay(100);
 		break;
 	}
 }
 
+static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable)
+{
+	struct intel_overlay *overlay;
+	int ret;
+
+	if (!enable && intel_crtc->overlay) {
+		overlay = intel_crtc->overlay;
+		mutex_lock(&overlay->dev->struct_mutex);
+		for (;;) {
+			ret = intel_overlay_switch_off(overlay);
+			if (ret == 0)
+				break;
+
+			ret = intel_overlay_recover_from_interrupt(overlay, 0);
+			if (ret != 0) {
+				/* overlay doesn't react anymore. Usually
+				 * results in a black screen and an unkillable
+				 * X server. */
+				BUG();
+				overlay->hw_wedged = HW_WEDGED;
+				break;
+			}
+		}
+		mutex_unlock(&overlay->dev->struct_mutex);
+	}
+	/* Let userspace switch the overlay on again. In most cases userspace
+	 * has to recompute where to put it anyway. */
+
+	return;
+}
+
 static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
 {
 	struct drm_device *dev = crtc->dev;
@@ -1839,12 +1916,14 @@
 			intel_update_fbc(crtc, &crtc->mode);
 
 		/* Give the overlay scaler a chance to enable if it's on this pipe */
-		//intel_crtc_dpms_video(crtc, true); TODO
+		intel_crtc_dpms_overlay(intel_crtc, true);
 	break;
 	case DRM_MODE_DPMS_OFF:
 		intel_update_watermarks(dev);
+
 		/* Give the overlay scaler a chance to disable if it's on this pipe */
-		//intel_crtc_dpms_video(crtc, FALSE); TODO
+		intel_crtc_dpms_overlay(intel_crtc, false);
+		drm_vblank_off(dev, pipe);
 
 		if (dev_priv->cfb_plane == plane &&
 		    dev_priv->display.disable_fbc)
@@ -1963,7 +2042,7 @@
 				  struct drm_display_mode *adjusted_mode)
 {
 	struct drm_device *dev = crtc->dev;
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		/* FDI link clock is fixed at 2.7G */
 		if (mode->clock * 3 > 27000 * 4)
 			return MODE_CLOCK_HIGH;
@@ -2039,7 +2118,7 @@
  * Return the pipe currently connected to the panel fitter,
  * or -1 if the panel fitter is not present or not in use
  */
-static int intel_panel_fitter_pipe (struct drm_device *dev)
+int intel_panel_fitter_pipe (struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32  pfit_control;
@@ -2083,9 +2162,8 @@
 #define LINK_N 0x80000
 
 static void
-igdng_compute_m_n(int bits_per_pixel, int nlanes,
-		int pixel_clock, int link_clock,
-		struct fdi_m_n *m_n)
+ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock,
+		     int link_clock, struct fdi_m_n *m_n)
 {
 	u64 temp;
 
@@ -2113,34 +2191,34 @@
 	unsigned long cacheline_size;
 };
 
-/* IGD has different values for various configs */
-static struct intel_watermark_params igd_display_wm = {
-	IGD_DISPLAY_FIFO,
-	IGD_MAX_WM,
-	IGD_DFT_WM,
-	IGD_GUARD_WM,
-	IGD_FIFO_LINE_SIZE
+/* Pineview has different values for various configs */
+static struct intel_watermark_params pineview_display_wm = {
+	PINEVIEW_DISPLAY_FIFO,
+	PINEVIEW_MAX_WM,
+	PINEVIEW_DFT_WM,
+	PINEVIEW_GUARD_WM,
+	PINEVIEW_FIFO_LINE_SIZE
 };
-static struct intel_watermark_params igd_display_hplloff_wm = {
-	IGD_DISPLAY_FIFO,
-	IGD_MAX_WM,
-	IGD_DFT_HPLLOFF_WM,
-	IGD_GUARD_WM,
-	IGD_FIFO_LINE_SIZE
+static struct intel_watermark_params pineview_display_hplloff_wm = {
+	PINEVIEW_DISPLAY_FIFO,
+	PINEVIEW_MAX_WM,
+	PINEVIEW_DFT_HPLLOFF_WM,
+	PINEVIEW_GUARD_WM,
+	PINEVIEW_FIFO_LINE_SIZE
 };
-static struct intel_watermark_params igd_cursor_wm = {
-	IGD_CURSOR_FIFO,
-	IGD_CURSOR_MAX_WM,
-	IGD_CURSOR_DFT_WM,
-	IGD_CURSOR_GUARD_WM,
-	IGD_FIFO_LINE_SIZE,
+static struct intel_watermark_params pineview_cursor_wm = {
+	PINEVIEW_CURSOR_FIFO,
+	PINEVIEW_CURSOR_MAX_WM,
+	PINEVIEW_CURSOR_DFT_WM,
+	PINEVIEW_CURSOR_GUARD_WM,
+	PINEVIEW_FIFO_LINE_SIZE,
 };
-static struct intel_watermark_params igd_cursor_hplloff_wm = {
-	IGD_CURSOR_FIFO,
-	IGD_CURSOR_MAX_WM,
-	IGD_CURSOR_DFT_WM,
-	IGD_CURSOR_GUARD_WM,
-	IGD_FIFO_LINE_SIZE
+static struct intel_watermark_params pineview_cursor_hplloff_wm = {
+	PINEVIEW_CURSOR_FIFO,
+	PINEVIEW_CURSOR_MAX_WM,
+	PINEVIEW_CURSOR_DFT_WM,
+	PINEVIEW_CURSOR_GUARD_WM,
+	PINEVIEW_FIFO_LINE_SIZE
 };
 static struct intel_watermark_params g4x_wm_info = {
 	G4X_FIFO_SIZE,
@@ -2213,11 +2291,11 @@
 		1000;
 	entries_required /= wm->cacheline_size;
 
-	DRM_DEBUG("FIFO entries required for mode: %d\n", entries_required);
+	DRM_DEBUG_KMS("FIFO entries required for mode: %d\n", entries_required);
 
 	wm_size = wm->fifo_size - (entries_required + wm->guard_size);
 
-	DRM_DEBUG("FIFO watermark level: %d\n", wm_size);
+	DRM_DEBUG_KMS("FIFO watermark level: %d\n", wm_size);
 
 	/* Don't promote wm_size to unsigned... */
 	if (wm_size > (long)wm->max_wm)
@@ -2279,50 +2357,50 @@
 			return latency;
 	}
 
-	DRM_DEBUG("Unknown FSB/MEM found, disable CxSR\n");
+	DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n");
 
 	return NULL;
 }
 
-static void igd_disable_cxsr(struct drm_device *dev)
+static void pineview_disable_cxsr(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 reg;
 
 	/* deactivate cxsr */
 	reg = I915_READ(DSPFW3);
-	reg &= ~(IGD_SELF_REFRESH_EN);
+	reg &= ~(PINEVIEW_SELF_REFRESH_EN);
 	I915_WRITE(DSPFW3, reg);
 	DRM_INFO("Big FIFO is disabled\n");
 }
 
-static void igd_enable_cxsr(struct drm_device *dev, unsigned long clock,
-			    int pixel_size)
+static void pineview_enable_cxsr(struct drm_device *dev, unsigned long clock,
+				 int pixel_size)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 reg;
 	unsigned long wm;
 	struct cxsr_latency *latency;
 
-	latency = intel_get_cxsr_latency(IS_IGDG(dev), dev_priv->fsb_freq,
+	latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->fsb_freq,
 		dev_priv->mem_freq);
 	if (!latency) {
-		DRM_DEBUG("Unknown FSB/MEM found, disable CxSR\n");
-		igd_disable_cxsr(dev);
+		DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n");
+		pineview_disable_cxsr(dev);
 		return;
 	}
 
 	/* Display SR */
-	wm = intel_calculate_wm(clock, &igd_display_wm, pixel_size,
+	wm = intel_calculate_wm(clock, &pineview_display_wm, pixel_size,
 				latency->display_sr);
 	reg = I915_READ(DSPFW1);
 	reg &= 0x7fffff;
 	reg |= wm << 23;
 	I915_WRITE(DSPFW1, reg);
-	DRM_DEBUG("DSPFW1 register is %x\n", reg);
+	DRM_DEBUG_KMS("DSPFW1 register is %x\n", reg);
 
 	/* cursor SR */
-	wm = intel_calculate_wm(clock, &igd_cursor_wm, pixel_size,
+	wm = intel_calculate_wm(clock, &pineview_cursor_wm, pixel_size,
 				latency->cursor_sr);
 	reg = I915_READ(DSPFW3);
 	reg &= ~(0x3f << 24);
@@ -2330,7 +2408,7 @@
 	I915_WRITE(DSPFW3, reg);
 
 	/* Display HPLL off SR */
-	wm = intel_calculate_wm(clock, &igd_display_hplloff_wm,
+	wm = intel_calculate_wm(clock, &pineview_display_hplloff_wm,
 		latency->display_hpll_disable, I915_FIFO_LINE_SIZE);
 	reg = I915_READ(DSPFW3);
 	reg &= 0xfffffe00;
@@ -2338,17 +2416,17 @@
 	I915_WRITE(DSPFW3, reg);
 
 	/* cursor HPLL off SR */
-	wm = intel_calculate_wm(clock, &igd_cursor_hplloff_wm, pixel_size,
+	wm = intel_calculate_wm(clock, &pineview_cursor_hplloff_wm, pixel_size,
 				latency->cursor_hpll_disable);
 	reg = I915_READ(DSPFW3);
 	reg &= ~(0x3f << 16);
 	reg |= (wm & 0x3f) << 16;
 	I915_WRITE(DSPFW3, reg);
-	DRM_DEBUG("DSPFW3 register is %x\n", reg);
+	DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg);
 
 	/* activate cxsr */
 	reg = I915_READ(DSPFW3);
-	reg |= IGD_SELF_REFRESH_EN;
+	reg |= PINEVIEW_SELF_REFRESH_EN;
 	I915_WRITE(DSPFW3, reg);
 
 	DRM_INFO("Big FIFO is enabled\n");
@@ -2384,8 +2462,8 @@
 		size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) -
 			(dsparb & 0x7f);
 
-	DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A",
-		  size);
+	DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb,
+			plane ? "B" : "A", size);
 
 	return size;
 }
@@ -2403,8 +2481,8 @@
 			(dsparb & 0x1ff);
 	size >>= 1; /* Convert to cachelines */
 
-	DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A",
-		  size);
+	DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb,
+			plane ? "B" : "A", size);
 
 	return size;
 }
@@ -2418,7 +2496,8 @@
 	size = dsparb & 0x7f;
 	size >>= 2; /* Convert to cachelines */
 
-	DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A",
+	DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb,
+			plane ? "B" : "A",
 		  size);
 
 	return size;
@@ -2433,8 +2512,8 @@
 	size = dsparb & 0x7f;
 	size >>= 1; /* Convert to cachelines */
 
-	DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A",
-		  size);
+	DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb,
+			plane ? "B" : "A", size);
 
 	return size;
 }
@@ -2509,15 +2588,39 @@
 		   (cursor_sr << DSPFW_CURSOR_SR_SHIFT));
 }
 
-static void i965_update_wm(struct drm_device *dev, int unused, int unused2,
-			   int unused3, int unused4)
+static void i965_update_wm(struct drm_device *dev, int planea_clock,
+			   int planeb_clock, int sr_hdisplay, int pixel_size)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long line_time_us;
+	int sr_clock, sr_entries, srwm = 1;
 
-	DRM_DEBUG("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR 8\n");
+	/* Calc sr entries for one plane configs */
+	if (sr_hdisplay && (!planea_clock || !planeb_clock)) {
+		/* self-refresh has much higher latency */
+		const static int sr_latency_ns = 12000;
+
+		sr_clock = planea_clock ? planea_clock : planeb_clock;
+		line_time_us = ((sr_hdisplay * 1000) / sr_clock);
+
+		/* Use ns/us then divide to preserve precision */
+		sr_entries = (((sr_latency_ns / line_time_us) + 1) *
+			      pixel_size * sr_hdisplay) / 1000;
+		sr_entries = roundup(sr_entries / I915_FIFO_LINE_SIZE, 1);
+		DRM_DEBUG("self-refresh entries: %d\n", sr_entries);
+		srwm = I945_FIFO_SIZE - sr_entries;
+		if (srwm < 0)
+			srwm = 1;
+		srwm &= 0x3f;
+		I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN);
+	}
+
+	DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n",
+		      srwm);
 
 	/* 965 has limitations... */
-	I915_WRITE(DSPFW1, (8 << 16) | (8 << 8) | (8 << 0));
+	I915_WRITE(DSPFW1, (srwm << DSPFW_SR_SHIFT) | (8 << 16) | (8 << 8) |
+		   (8 << 0));
 	I915_WRITE(DSPFW2, (8 << 8) | (8 << 0));
 }
 
@@ -2553,7 +2656,7 @@
 				       pixel_size, latency_ns);
 	planeb_wm = intel_calculate_wm(planeb_clock, &planeb_params,
 				       pixel_size, latency_ns);
-	DRM_DEBUG("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm);
+	DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm);
 
 	/*
 	 * Overlay gets an aggressive default since video jitter is bad.
@@ -2573,14 +2676,14 @@
 		sr_entries = (((sr_latency_ns / line_time_us) + 1) *
 			      pixel_size * sr_hdisplay) / 1000;
 		sr_entries = roundup(sr_entries / cacheline_size, 1);
-		DRM_DEBUG("self-refresh entries: %d\n", sr_entries);
+		DRM_DEBUG_KMS("self-refresh entries: %d\n", sr_entries);
 		srwm = total_size - sr_entries;
 		if (srwm < 0)
 			srwm = 1;
 		I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (srwm & 0x3f));
 	}
 
-	DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n",
+	DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n",
 		  planea_wm, planeb_wm, cwm, srwm);
 
 	fwater_lo = ((planeb_wm & 0x3f) << 16) | (planea_wm & 0x3f);
@@ -2607,7 +2710,7 @@
 				       pixel_size, latency_ns);
 	fwater_lo |= (3<<8) | planea_wm;
 
-	DRM_DEBUG("Setting FIFO watermarks - A: %d\n", planea_wm);
+	DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d\n", planea_wm);
 
 	I915_WRITE(FW_BLC, fwater_lo);
 }
@@ -2661,11 +2764,11 @@
 		if (crtc->enabled) {
 			enabled++;
 			if (intel_crtc->plane == 0) {
-				DRM_DEBUG("plane A (pipe %d) clock: %d\n",
+				DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n",
 					  intel_crtc->pipe, crtc->mode.clock);
 				planea_clock = crtc->mode.clock;
 			} else {
-				DRM_DEBUG("plane B (pipe %d) clock: %d\n",
+				DRM_DEBUG_KMS("plane B (pipe %d) clock: %d\n",
 					  intel_crtc->pipe, crtc->mode.clock);
 				planeb_clock = crtc->mode.clock;
 			}
@@ -2682,10 +2785,10 @@
 		return;
 
 	/* Single plane configs can enable self refresh */
-	if (enabled == 1 && IS_IGD(dev))
-		igd_enable_cxsr(dev, sr_clock, pixel_size);
-	else if (IS_IGD(dev))
-		igd_disable_cxsr(dev);
+	if (enabled == 1 && IS_PINEVIEW(dev))
+		pineview_enable_cxsr(dev, sr_clock, pixel_size);
+	else if (IS_PINEVIEW(dev))
+		pineview_disable_cxsr(dev);
 
 	dev_priv->display.update_wm(dev, planea_clock, planeb_clock,
 				    sr_hdisplay, pixel_size);
@@ -2779,10 +2882,11 @@
 
 	if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) {
 		refclk = dev_priv->lvds_ssc_freq * 1000;
-		DRM_DEBUG("using SSC reference clock of %d MHz\n", refclk / 1000);
+		DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n",
+					refclk / 1000);
 	} else if (IS_I9XX(dev)) {
 		refclk = 96000;
-		if (IS_IGDNG(dev))
+		if (IS_IRONLAKE(dev))
 			refclk = 120000; /* 120Mhz refclk */
 	} else {
 		refclk = 48000;
@@ -2802,14 +2906,25 @@
 		return -EINVAL;
 	}
 
-	if (limit->find_reduced_pll && dev_priv->lvds_downclock_avail) {
+	if (is_lvds && limit->find_reduced_pll &&
+			dev_priv->lvds_downclock_avail) {
 		memcpy(&reduced_clock, &clock, sizeof(intel_clock_t));
 		has_reduced_clock = limit->find_reduced_pll(limit, crtc,
-							    (adjusted_mode->clock*3/4),
+							    dev_priv->lvds_downclock,
 							    refclk,
 							    &reduced_clock);
+		if (has_reduced_clock && (clock.p != reduced_clock.p)) {
+			/*
+			 * If the different P is found, it means that we can't
+			 * switch the display clock by using the FP0/FP1.
+			 * In such case we will disable the LVDS downclock
+			 * feature.
+			 */
+			DRM_DEBUG_KMS("Different P is found for "
+						"LVDS clock/downclock\n");
+			has_reduced_clock = 0;
+		}
 	}
-
 	/* SDVO TV has fixed PLL values depend on its clock range,
 	   this mirrors vbios setting. */
 	if (is_sdvo && is_tv) {
@@ -2831,7 +2946,7 @@
 	}
 
 	/* FDI link */
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		int lane, link_bw, bpp;
 		/* eDP doesn't require FDI link, so just set DP M/N
 		   according to current link config */
@@ -2873,8 +2988,7 @@
 			bpp = 24;
 		}
 
-		igdng_compute_m_n(bpp, lane, target_clock,
-				  link_bw, &m_n);
+		ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n);
 	}
 
 	/* Ironlake: try to setup display ref clock before DPLL
@@ -2882,7 +2996,7 @@
 	 * PCH B stepping, previous chipset stepping should be
 	 * ignoring this setting.
 	 */
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		temp = I915_READ(PCH_DREF_CONTROL);
 		/* Always enable nonspread source */
 		temp &= ~DREF_NONSPREAD_SOURCE_MASK;
@@ -2917,7 +3031,7 @@
 		}
 	}
 
-	if (IS_IGD(dev)) {
+	if (IS_PINEVIEW(dev)) {
 		fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2;
 		if (has_reduced_clock)
 			fp2 = (1 << reduced_clock.n) << 16 |
@@ -2929,7 +3043,7 @@
 				reduced_clock.m2;
 	}
 
-	if (!IS_IGDNG(dev))
+	if (!IS_IRONLAKE(dev))
 		dpll = DPLL_VGA_MODE_DIS;
 
 	if (IS_I9XX(dev)) {
@@ -2942,19 +3056,19 @@
 			sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
 			if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
 				dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
-			else if (IS_IGDNG(dev))
+			else if (IS_IRONLAKE(dev))
 				dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
 		}
 		if (is_dp)
 			dpll |= DPLL_DVO_HIGH_SPEED;
 
 		/* compute bitmask from p1 value */
-		if (IS_IGD(dev))
-			dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_IGD;
+		if (IS_PINEVIEW(dev))
+			dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW;
 		else {
 			dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
 			/* also FPA1 */
-			if (IS_IGDNG(dev))
+			if (IS_IRONLAKE(dev))
 				dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
 			if (IS_G4X(dev) && has_reduced_clock)
 				dpll |= (1 << (reduced_clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
@@ -2973,7 +3087,7 @@
 			dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
 			break;
 		}
-		if (IS_I965G(dev) && !IS_IGDNG(dev))
+		if (IS_I965G(dev) && !IS_IRONLAKE(dev))
 			dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
 	} else {
 		if (is_lvds) {
@@ -3005,9 +3119,9 @@
 	/* Set up the display plane register */
 	dspcntr = DISPPLANE_GAMMA_ENABLE;
 
-	/* IGDNG's plane is forced to pipe, bit 24 is to
+	/* Ironlake's plane is forced to pipe, bit 24 is to
 	   enable color space conversion */
-	if (!IS_IGDNG(dev)) {
+	if (!IS_IRONLAKE(dev)) {
 		if (pipe == 0)
 			dspcntr &= ~DISPPLANE_SEL_PIPE_MASK;
 		else
@@ -3034,20 +3148,20 @@
 
 
 	/* Disable the panel fitter if it was on our pipe */
-	if (!IS_IGDNG(dev) && intel_panel_fitter_pipe(dev) == pipe)
+	if (!IS_IRONLAKE(dev) && intel_panel_fitter_pipe(dev) == pipe)
 		I915_WRITE(PFIT_CONTROL, 0);
 
-	DRM_DEBUG("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
+	DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
 	drm_mode_debug_printmodeline(mode);
 
-	/* assign to IGDNG registers */
-	if (IS_IGDNG(dev)) {
+	/* assign to Ironlake registers */
+	if (IS_IRONLAKE(dev)) {
 		fp_reg = pch_fp_reg;
 		dpll_reg = pch_dpll_reg;
 	}
 
 	if (is_edp) {
-		igdng_disable_pll_edp(crtc);
+		ironlake_disable_pll_edp(crtc);
 	} else if ((dpll & DPLL_VCO_ENABLE)) {
 		I915_WRITE(fp_reg, fp);
 		I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
@@ -3062,7 +3176,7 @@
 	if (is_lvds) {
 		u32 lvds;
 
-		if (IS_IGDNG(dev))
+		if (IS_IRONLAKE(dev))
 			lvds_reg = PCH_LVDS;
 
 		lvds = I915_READ(lvds_reg);
@@ -3095,7 +3209,7 @@
 		/* Wait for the clocks to stabilize. */
 		udelay(150);
 
-		if (IS_I965G(dev) && !IS_IGDNG(dev)) {
+		if (IS_I965G(dev) && !IS_IRONLAKE(dev)) {
 			if (is_sdvo) {
 				sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
 				I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) |
@@ -3115,14 +3229,14 @@
 		I915_WRITE(fp_reg + 4, fp2);
 		intel_crtc->lowfreq_avail = true;
 		if (HAS_PIPE_CXSR(dev)) {
-			DRM_DEBUG("enabling CxSR downclocking\n");
+			DRM_DEBUG_KMS("enabling CxSR downclocking\n");
 			pipeconf |= PIPECONF_CXSR_DOWNCLOCK;
 		}
 	} else {
 		I915_WRITE(fp_reg + 4, fp);
 		intel_crtc->lowfreq_avail = false;
 		if (HAS_PIPE_CXSR(dev)) {
-			DRM_DEBUG("disabling CxSR downclocking\n");
+			DRM_DEBUG_KMS("disabling CxSR downclocking\n");
 			pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK;
 		}
 	}
@@ -3142,21 +3256,21 @@
 	/* pipesrc and dspsize control the size that is scaled from, which should
 	 * always be the user's requested size.
 	 */
-	if (!IS_IGDNG(dev)) {
+	if (!IS_IRONLAKE(dev)) {
 		I915_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) |
 				(mode->hdisplay - 1));
 		I915_WRITE(dsppos_reg, 0);
 	}
 	I915_WRITE(pipesrc_reg, ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		I915_WRITE(data_m1_reg, TU_SIZE(m_n.tu) | m_n.gmch_m);
 		I915_WRITE(data_n1_reg, TU_SIZE(m_n.tu) | m_n.gmch_n);
 		I915_WRITE(link_m1_reg, m_n.link_m);
 		I915_WRITE(link_n1_reg, m_n.link_n);
 
 		if (is_edp) {
-			igdng_set_pll_edp(crtc, adjusted_mode->clock);
+			ironlake_set_pll_edp(crtc, adjusted_mode->clock);
 		} else {
 			/* enable FDI RX PLL too */
 			temp = I915_READ(fdi_rx_reg);
@@ -3170,7 +3284,7 @@
 
 	intel_wait_for_vblank(dev);
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		/* enable address swizzle for tiling buffer */
 		temp = I915_READ(DISP_ARB_CTL);
 		I915_WRITE(DISP_ARB_CTL, temp | DISP_TILE_SURFACE_SWIZZLING);
@@ -3204,8 +3318,8 @@
 	if (!crtc->enabled)
 		return;
 
-	/* use legacy palette for IGDNG */
-	if (IS_IGDNG(dev))
+	/* use legacy palette for Ironlake */
+	if (IS_IRONLAKE(dev))
 		palreg = (intel_crtc->pipe == 0) ? LGC_PALETTE_A :
 						   LGC_PALETTE_B;
 
@@ -3234,11 +3348,11 @@
 	size_t addr;
 	int ret;
 
-	DRM_DEBUG("\n");
+	DRM_DEBUG_KMS("\n");
 
 	/* if we want to turn off the cursor ignore width and height */
 	if (!handle) {
-		DRM_DEBUG("cursor off\n");
+		DRM_DEBUG_KMS("cursor off\n");
 		if (IS_MOBILE(dev) || IS_I9XX(dev)) {
 			temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
 			temp |= CURSOR_MODE_DISABLE;
@@ -3546,18 +3660,18 @@
 		fp = I915_READ((pipe == 0) ? FPA1 : FPB1);
 
 	clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
-	if (IS_IGD(dev)) {
-		clock.n = ffs((fp & FP_N_IGD_DIV_MASK) >> FP_N_DIV_SHIFT) - 1;
-		clock.m2 = (fp & FP_M2_IGD_DIV_MASK) >> FP_M2_DIV_SHIFT;
+	if (IS_PINEVIEW(dev)) {
+		clock.n = ffs((fp & FP_N_PINEVIEW_DIV_MASK) >> FP_N_DIV_SHIFT) - 1;
+		clock.m2 = (fp & FP_M2_PINEVIEW_DIV_MASK) >> FP_M2_DIV_SHIFT;
 	} else {
 		clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
 		clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
 	}
 
 	if (IS_I9XX(dev)) {
-		if (IS_IGD(dev))
-			clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_IGD) >>
-				DPLL_FPA01_P1_POST_DIV_SHIFT_IGD);
+		if (IS_PINEVIEW(dev))
+			clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW) >>
+				DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW);
 		else
 			clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >>
 			       DPLL_FPA01_P1_POST_DIV_SHIFT);
@@ -3572,7 +3686,7 @@
 				7 : 14;
 			break;
 		default:
-			DRM_DEBUG("Unknown DPLL mode %08x in programmed "
+			DRM_DEBUG_KMS("Unknown DPLL mode %08x in programmed "
 				  "mode\n", (int)(dpll & DPLL_MODE_MASK));
 			return 0;
 		}
@@ -3658,7 +3772,7 @@
 	struct drm_device *dev = (struct drm_device *)arg;
 	drm_i915_private_t *dev_priv = dev->dev_private;
 
-	DRM_DEBUG("idle timer fired, downclocking\n");
+	DRM_DEBUG_DRIVER("idle timer fired, downclocking\n");
 
 	dev_priv->busy = false;
 
@@ -3669,11 +3783,11 @@
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		return;
 
 	if (!dev_priv->render_reclock_avail) {
-		DRM_DEBUG("not reclocking render clock\n");
+		DRM_DEBUG_DRIVER("not reclocking render clock\n");
 		return;
 	}
 
@@ -3682,7 +3796,7 @@
 		pci_write_config_word(dev->pdev, GCFGC, dev_priv->orig_clock);
 	else if (IS_I85X(dev))
 		pci_write_config_word(dev->pdev, HPLLCC, dev_priv->orig_clock);
-	DRM_DEBUG("increasing render clock frequency\n");
+	DRM_DEBUG_DRIVER("increasing render clock frequency\n");
 
 	/* Schedule downclock */
 	if (schedule)
@@ -3694,11 +3808,11 @@
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		return;
 
 	if (!dev_priv->render_reclock_avail) {
-		DRM_DEBUG("not reclocking render clock\n");
+		DRM_DEBUG_DRIVER("not reclocking render clock\n");
 		return;
 	}
 
@@ -3758,7 +3872,7 @@
 
 		pci_write_config_word(dev->pdev, HPLLCC, hpllcc);
 	}
-	DRM_DEBUG("decreasing render clock frequency\n");
+	DRM_DEBUG_DRIVER("decreasing render clock frequency\n");
 }
 
 /* Note that no increase function is needed for this - increase_renderclock()
@@ -3766,7 +3880,7 @@
  */
 void intel_decrease_displayclock(struct drm_device *dev)
 {
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		return;
 
 	if (IS_I945G(dev) || IS_I945GM(dev) || IS_I915G(dev) ||
@@ -3792,7 +3906,7 @@
 	struct drm_crtc *crtc = &intel_crtc->base;
 	drm_i915_private_t *dev_priv = crtc->dev->dev_private;
 
-	DRM_DEBUG("idle timer fired, downclocking\n");
+	DRM_DEBUG_DRIVER("idle timer fired, downclocking\n");
 
 	intel_crtc->busy = false;
 
@@ -3808,14 +3922,14 @@
 	int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
 	int dpll = I915_READ(dpll_reg);
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		return;
 
 	if (!dev_priv->lvds_downclock_avail)
 		return;
 
 	if (!HAS_PIPE_CXSR(dev) && (dpll & DISPLAY_RATE_SELECT_FPA1)) {
-		DRM_DEBUG("upclocking LVDS\n");
+		DRM_DEBUG_DRIVER("upclocking LVDS\n");
 
 		/* Unlock panel regs */
 		I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | (0xabcd << 16));
@@ -3826,7 +3940,7 @@
 		intel_wait_for_vblank(dev);
 		dpll = I915_READ(dpll_reg);
 		if (dpll & DISPLAY_RATE_SELECT_FPA1)
-			DRM_DEBUG("failed to upclock LVDS!\n");
+			DRM_DEBUG_DRIVER("failed to upclock LVDS!\n");
 
 		/* ...and lock them again */
 		I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) & 0x3);
@@ -3847,7 +3961,7 @@
 	int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
 	int dpll = I915_READ(dpll_reg);
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		return;
 
 	if (!dev_priv->lvds_downclock_avail)
@@ -3858,7 +3972,7 @@
 	 * the manual case.
 	 */
 	if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) {
-		DRM_DEBUG("downclocking LVDS\n");
+		DRM_DEBUG_DRIVER("downclocking LVDS\n");
 
 		/* Unlock panel regs */
 		I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | (0xabcd << 16));
@@ -3869,7 +3983,7 @@
 		intel_wait_for_vblank(dev);
 		dpll = I915_READ(dpll_reg);
 		if (!(dpll & DISPLAY_RATE_SELECT_FPA1))
-			DRM_DEBUG("failed to downclock LVDS!\n");
+			DRM_DEBUG_DRIVER("failed to downclock LVDS!\n");
 
 		/* ...and lock them again */
 		I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) & 0x3);
@@ -3936,8 +4050,13 @@
 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
 		return;
 
-	dev_priv->busy = true;
-	intel_increase_renderclock(dev, true);
+	if (!dev_priv->busy) {
+		dev_priv->busy = true;
+		intel_increase_renderclock(dev, true);
+	} else {
+		mod_timer(&dev_priv->idle_timer, jiffies +
+			  msecs_to_jiffies(GPU_IDLE_TIMEOUT));
+	}
 
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 		if (!crtc->fb)
@@ -3967,6 +4086,158 @@
 	kfree(intel_crtc);
 }
 
+struct intel_unpin_work {
+	struct work_struct work;
+	struct drm_device *dev;
+	struct drm_gem_object *obj;
+	struct drm_pending_vblank_event *event;
+	int pending;
+};
+
+static void intel_unpin_work_fn(struct work_struct *__work)
+{
+	struct intel_unpin_work *work =
+		container_of(__work, struct intel_unpin_work, work);
+
+	mutex_lock(&work->dev->struct_mutex);
+	i915_gem_object_unpin(work->obj);
+	drm_gem_object_unreference(work->obj);
+	mutex_unlock(&work->dev->struct_mutex);
+	kfree(work);
+}
+
+void intel_finish_page_flip(struct drm_device *dev, int pipe)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_unpin_work *work;
+	struct drm_i915_gem_object *obj_priv;
+	struct drm_pending_vblank_event *e;
+	struct timeval now;
+	unsigned long flags;
+
+	/* Ignore early vblank irqs */
+	if (intel_crtc == NULL)
+		return;
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+	work = intel_crtc->unpin_work;
+	if (work == NULL || !work->pending) {
+		spin_unlock_irqrestore(&dev->event_lock, flags);
+		return;
+	}
+
+	intel_crtc->unpin_work = NULL;
+	drm_vblank_put(dev, intel_crtc->pipe);
+
+	if (work->event) {
+		e = work->event;
+		do_gettimeofday(&now);
+		e->event.sequence = drm_vblank_count(dev, intel_crtc->pipe);
+		e->event.tv_sec = now.tv_sec;
+		e->event.tv_usec = now.tv_usec;
+		list_add_tail(&e->base.link,
+			      &e->base.file_priv->event_list);
+		wake_up_interruptible(&e->base.file_priv->event_wait);
+	}
+
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+
+	obj_priv = work->obj->driver_private;
+	if (atomic_dec_and_test(&obj_priv->pending_flip))
+		DRM_WAKEUP(&dev_priv->pending_flip_queue);
+	schedule_work(&work->work);
+}
+
+void intel_prepare_page_flip(struct drm_device *dev, int plane)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc =
+		to_intel_crtc(dev_priv->plane_to_crtc_mapping[plane]);
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+	if (intel_crtc->unpin_work)
+		intel_crtc->unpin_work->pending = 1;
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
+static int intel_crtc_page_flip(struct drm_crtc *crtc,
+				struct drm_framebuffer *fb,
+				struct drm_pending_vblank_event *event)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_framebuffer *intel_fb;
+	struct drm_i915_gem_object *obj_priv;
+	struct drm_gem_object *obj;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_unpin_work *work;
+	unsigned long flags;
+	int ret;
+	RING_LOCALS;
+
+	work = kzalloc(sizeof *work, GFP_KERNEL);
+	if (work == NULL)
+		return -ENOMEM;
+
+	mutex_lock(&dev->struct_mutex);
+
+	work->event = event;
+	work->dev = crtc->dev;
+	intel_fb = to_intel_framebuffer(crtc->fb);
+	work->obj = intel_fb->obj;
+	INIT_WORK(&work->work, intel_unpin_work_fn);
+
+	/* We borrow the event spin lock for protecting unpin_work */
+	spin_lock_irqsave(&dev->event_lock, flags);
+	if (intel_crtc->unpin_work) {
+		spin_unlock_irqrestore(&dev->event_lock, flags);
+		kfree(work);
+		mutex_unlock(&dev->struct_mutex);
+		return -EBUSY;
+	}
+	intel_crtc->unpin_work = work;
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+
+	intel_fb = to_intel_framebuffer(fb);
+	obj = intel_fb->obj;
+
+	ret = intel_pin_and_fence_fb_obj(dev, obj);
+	if (ret != 0) {
+		kfree(work);
+		mutex_unlock(&dev->struct_mutex);
+		return ret;
+	}
+
+	/* Reference the old fb object for the scheduled work. */
+	drm_gem_object_reference(work->obj);
+
+	crtc->fb = fb;
+	i915_gem_object_flush_write_domain(obj);
+	drm_vblank_get(dev, intel_crtc->pipe);
+	obj_priv = obj->driver_private;
+	atomic_inc(&obj_priv->pending_flip);
+
+	BEGIN_LP_RING(4);
+	OUT_RING(MI_DISPLAY_FLIP |
+		 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
+	OUT_RING(fb->pitch);
+	if (IS_I965G(dev)) {
+		OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode);
+		OUT_RING((fb->width << 16) | fb->height);
+	} else {
+		OUT_RING(obj_priv->gtt_offset);
+		OUT_RING(MI_NOOP);
+	}
+	ADVANCE_LP_RING();
+
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
 static const struct drm_crtc_helper_funcs intel_helper_funcs = {
 	.dpms = intel_crtc_dpms,
 	.mode_fixup = intel_crtc_mode_fixup,
@@ -3983,11 +4254,13 @@
 	.gamma_set = intel_crtc_gamma_set,
 	.set_config = drm_crtc_helper_set_config,
 	.destroy = intel_crtc_destroy,
+	.page_flip = intel_crtc_page_flip,
 };
 
 
 static void intel_crtc_init(struct drm_device *dev, int pipe)
 {
+	drm_i915_private_t *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc;
 	int i;
 
@@ -4010,10 +4283,15 @@
 	intel_crtc->pipe = pipe;
 	intel_crtc->plane = pipe;
 	if (IS_MOBILE(dev) && (IS_I9XX(dev) && !IS_I965G(dev))) {
-		DRM_DEBUG("swapping pipes & planes for FBC\n");
+		DRM_DEBUG_KMS("swapping pipes & planes for FBC\n");
 		intel_crtc->plane = ((pipe == 0) ? 1 : 0);
 	}
 
+	BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) ||
+	       dev_priv->plane_to_crtc_mapping[intel_crtc->plane] != NULL);
+	dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base;
+	dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base;
+
 	intel_crtc->cursor_addr = 0;
 	intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF;
 	drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
@@ -4090,7 +4368,7 @@
 	if (IS_MOBILE(dev) && !IS_I830(dev))
 		intel_lvds_init(dev);
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		int found;
 
 		if (IS_MOBILE(dev) && (I915_READ(DP_A) & DP_DETECTED))
@@ -4118,7 +4396,7 @@
 		if (I915_READ(PCH_DP_D) & DP_DETECTED)
 			intel_dp_init(dev, PCH_DP_D);
 
-	} else if (IS_I9XX(dev)) {
+	} else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) {
 		bool found = false;
 
 		if (I915_READ(SDVOB) & SDVO_DETECTED) {
@@ -4145,10 +4423,10 @@
 
 		if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED))
 			intel_dp_init(dev, DP_D);
-	} else
+	} else if (IS_I8XX(dev))
 		intel_dvo_init(dev);
 
-	if (IS_I9XX(dev) && IS_MOBILE(dev) && !IS_IGDNG(dev))
+	if (SUPPORTS_TV(dev))
 		intel_tv_init(dev);
 
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
@@ -4257,7 +4535,7 @@
 	 * Disable clock gating reported to work incorrectly according to the
 	 * specs, but enable as much else as we can.
 	 */
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		return;
 	} else if (IS_G4X(dev)) {
 		uint32_t dspclk_gate;
@@ -4291,11 +4569,52 @@
 		dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING |
 			DSTATE_DOT_CLOCK_GATING;
 		I915_WRITE(D_STATE, dstate);
-	} else if (IS_I855(dev) || IS_I865G(dev)) {
+	} else if (IS_I85X(dev) || IS_I865G(dev)) {
 		I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE);
 	} else if (IS_I830(dev)) {
 		I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE);
 	}
+
+	/*
+	 * GPU can automatically power down the render unit if given a page
+	 * to save state.
+	 */
+	if (I915_HAS_RC6(dev)) {
+		struct drm_gem_object *pwrctx;
+		struct drm_i915_gem_object *obj_priv;
+		int ret;
+
+		if (dev_priv->pwrctx) {
+			obj_priv = dev_priv->pwrctx->driver_private;
+		} else {
+			pwrctx = drm_gem_object_alloc(dev, 4096);
+			if (!pwrctx) {
+				DRM_DEBUG("failed to alloc power context, "
+					  "RC6 disabled\n");
+				goto out;
+			}
+
+			ret = i915_gem_object_pin(pwrctx, 4096);
+			if (ret) {
+				DRM_ERROR("failed to pin power context: %d\n",
+					  ret);
+				drm_gem_object_unreference(pwrctx);
+				goto out;
+			}
+
+			i915_gem_object_set_to_gtt_domain(pwrctx, 1);
+
+			dev_priv->pwrctx = pwrctx;
+			obj_priv = pwrctx->driver_private;
+		}
+
+		I915_WRITE(PWRCTXA, obj_priv->gtt_offset | PWRCTX_EN);
+		I915_WRITE(MCHBAR_RENDER_STANDBY,
+			   I915_READ(MCHBAR_RENDER_STANDBY) & ~RCX_SW_EXIT);
+	}
+
+out:
+	return;
 }
 
 /* Set up chip specific display functions */
@@ -4304,8 +4623,8 @@
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
 	/* We always want a DPMS function */
-	if (IS_IGDNG(dev))
-		dev_priv->display.dpms = igdng_crtc_dpms;
+	if (IS_IRONLAKE(dev))
+		dev_priv->display.dpms = ironlake_crtc_dpms;
 	else
 		dev_priv->display.dpms = i9xx_crtc_dpms;
 
@@ -4324,13 +4643,13 @@
 	}
 
 	/* Returns the core display clock speed */
-	if (IS_I945G(dev))
+	if (IS_I945G(dev) || (IS_G33(dev) && ! IS_PINEVIEW_M(dev)))
 		dev_priv->display.get_display_clock_speed =
 			i945_get_display_clock_speed;
 	else if (IS_I915G(dev))
 		dev_priv->display.get_display_clock_speed =
 			i915_get_display_clock_speed;
-	else if (IS_I945GM(dev) || IS_845G(dev) || IS_IGDGM(dev))
+	else if (IS_I945GM(dev) || IS_845G(dev) || IS_PINEVIEW_M(dev))
 		dev_priv->display.get_display_clock_speed =
 			i9xx_misc_get_display_clock_speed;
 	else if (IS_I915GM(dev))
@@ -4339,7 +4658,7 @@
 	else if (IS_I865G(dev))
 		dev_priv->display.get_display_clock_speed =
 			i865_get_display_clock_speed;
-	else if (IS_I855(dev))
+	else if (IS_I85X(dev))
 		dev_priv->display.get_display_clock_speed =
 			i855_get_display_clock_speed;
 	else /* 852, 830 */
@@ -4347,7 +4666,7 @@
 			i830_get_display_clock_speed;
 
 	/* For FIFO watermark updates */
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		dev_priv->display.update_wm = NULL;
 	else if (IS_G4X(dev))
 		dev_priv->display.update_wm = g4x_update_wm;
@@ -4403,7 +4722,7 @@
 		num_pipe = 2;
 	else
 		num_pipe = 1;
-	DRM_DEBUG("%d display pipe%s available.\n",
+	DRM_DEBUG_KMS("%d display pipe%s available.\n",
 		  num_pipe, num_pipe > 1 ? "s" : "");
 
 	if (IS_I85X(dev))
@@ -4422,6 +4741,15 @@
 	INIT_WORK(&dev_priv->idle_work, intel_idle_update);
 	setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer,
 		    (unsigned long)dev);
+
+	intel_setup_overlay(dev);
+
+	if (IS_PINEVIEW(dev) && !intel_get_cxsr_latency(IS_PINEVIEW_G(dev),
+							dev_priv->fsb_freq,
+							dev_priv->mem_freq))
+		DRM_INFO("failed to find known CxSR latency "
+			 "(found fsb freq %d, mem freq %d), disabling CxSR\n",
+			 dev_priv->fsb_freq, dev_priv->mem_freq);
 }
 
 void intel_modeset_cleanup(struct drm_device *dev)
@@ -4445,11 +4773,21 @@
 	intel_increase_renderclock(dev, false);
 	del_timer_sync(&dev_priv->idle_timer);
 
-	mutex_unlock(&dev->struct_mutex);
-
 	if (dev_priv->display.disable_fbc)
 		dev_priv->display.disable_fbc(dev);
 
+	if (dev_priv->pwrctx) {
+		struct drm_i915_gem_object *obj_priv;
+
+		obj_priv = dev_priv->pwrctx->driver_private;
+		I915_WRITE(PWRCTXA, obj_priv->gtt_offset &~ PWRCTX_EN);
+		I915_READ(PWRCTXA);
+		i915_gem_object_unpin(dev_priv->pwrctx);
+		drm_gem_object_unreference(dev_priv->pwrctx);
+	}
+
+	mutex_unlock(&dev->struct_mutex);
+
 	drm_mode_config_cleanup(dev);
 }
 
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index d834475..4e7aa8b 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -33,7 +33,8 @@
 #include "intel_drv.h"
 #include "i915_drm.h"
 #include "i915_drv.h"
-#include "intel_dp.h"
+#include "drm_dp_helper.h"
+
 
 #define DP_LINK_STATUS_SIZE	6
 #define DP_LINK_CHECK_TIMEOUT	(10 * 1000)
@@ -223,8 +224,8 @@
 	 */
 	if (IS_eDP(intel_output))
 		aux_clock_divider = 225; /* eDP input clock at 450Mhz */
-	else if (IS_IGDNG(dev))
-		aux_clock_divider = 62; /* IGDNG: input clock fixed at 125Mhz */
+	else if (IS_IRONLAKE(dev))
+		aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */
 	else
 		aux_clock_divider = intel_hrawclk(dev) / 2;
 
@@ -282,7 +283,7 @@
 	/* Timeouts occur when the device isn't connected, so they're
 	 * "normal" -- don't fill the kernel log with these */
 	if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) {
-		DRM_DEBUG("dp_aux_ch timeout status 0x%08x\n", status);
+		DRM_DEBUG_KMS("dp_aux_ch timeout status 0x%08x\n", status);
 		return -ETIMEDOUT;
 	}
 
@@ -382,17 +383,77 @@
 }
 
 static int
-intel_dp_i2c_aux_ch(struct i2c_adapter *adapter,
-		    uint8_t *send, int send_bytes,
-		    uint8_t *recv, int recv_bytes)
+intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
+		    uint8_t write_byte, uint8_t *read_byte)
 {
+	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
 	struct intel_dp_priv *dp_priv = container_of(adapter,
 						     struct intel_dp_priv,
 						     adapter);
 	struct intel_output *intel_output = dp_priv->intel_output;
+	uint16_t address = algo_data->address;
+	uint8_t msg[5];
+	uint8_t reply[2];
+	int msg_bytes;
+	int reply_bytes;
+	int ret;
 
-	return intel_dp_aux_ch(intel_output,
-			       send, send_bytes, recv, recv_bytes);
+	/* Set up the command byte */
+	if (mode & MODE_I2C_READ)
+		msg[0] = AUX_I2C_READ << 4;
+	else
+		msg[0] = AUX_I2C_WRITE << 4;
+
+	if (!(mode & MODE_I2C_STOP))
+		msg[0] |= AUX_I2C_MOT << 4;
+
+	msg[1] = address >> 8;
+	msg[2] = address;
+
+	switch (mode) {
+	case MODE_I2C_WRITE:
+		msg[3] = 0;
+		msg[4] = write_byte;
+		msg_bytes = 5;
+		reply_bytes = 1;
+		break;
+	case MODE_I2C_READ:
+		msg[3] = 0;
+		msg_bytes = 4;
+		reply_bytes = 2;
+		break;
+	default:
+		msg_bytes = 3;
+		reply_bytes = 1;
+		break;
+	}
+
+	for (;;) {
+	  ret = intel_dp_aux_ch(intel_output,
+				msg, msg_bytes,
+				reply, reply_bytes);
+		if (ret < 0) {
+			DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
+			return ret;
+		}
+		switch (reply[0] & AUX_I2C_REPLY_MASK) {
+		case AUX_I2C_REPLY_ACK:
+			if (mode == MODE_I2C_READ) {
+				*read_byte = reply[1];
+			}
+			return reply_bytes - 1;
+		case AUX_I2C_REPLY_NACK:
+			DRM_DEBUG_KMS("aux_ch nack\n");
+			return -EREMOTEIO;
+		case AUX_I2C_REPLY_DEFER:
+			DRM_DEBUG_KMS("aux_ch defer\n");
+			udelay(100);
+			break;
+		default:
+			DRM_ERROR("aux_ch invalid reply 0x%02x\n", reply[0]);
+			return -EREMOTEIO;
+		}
+	}
 }
 
 static int
@@ -435,7 +496,8 @@
 				dp_priv->link_bw = bws[clock];
 				dp_priv->lane_count = lane_count;
 				adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw);
-				DRM_DEBUG("Display port link bw %02x lane count %d clock %d\n",
+				DRM_DEBUG_KMS("Display port link bw %02x lane "
+						"count %d clock %d\n",
 				       dp_priv->link_bw, dp_priv->lane_count,
 				       adjusted_mode->clock);
 				return true;
@@ -514,7 +576,7 @@
 	intel_dp_compute_m_n(3, lane_count,
 			     mode->clock, adjusted_mode->clock, &m_n);
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		if (intel_crtc->pipe == 0) {
 			I915_WRITE(TRANSA_DATA_M1,
 				   ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) |
@@ -606,23 +668,23 @@
 	}
 }
 
-static void igdng_edp_backlight_on (struct drm_device *dev)
+static void ironlake_edp_backlight_on (struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 pp;
 
-	DRM_DEBUG("\n");
+	DRM_DEBUG_KMS("\n");
 	pp = I915_READ(PCH_PP_CONTROL);
 	pp |= EDP_BLC_ENABLE;
 	I915_WRITE(PCH_PP_CONTROL, pp);
 }
 
-static void igdng_edp_backlight_off (struct drm_device *dev)
+static void ironlake_edp_backlight_off (struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 pp;
 
-	DRM_DEBUG("\n");
+	DRM_DEBUG_KMS("\n");
 	pp = I915_READ(PCH_PP_CONTROL);
 	pp &= ~EDP_BLC_ENABLE;
 	I915_WRITE(PCH_PP_CONTROL, pp);
@@ -641,13 +703,13 @@
 		if (dp_reg & DP_PORT_EN) {
 			intel_dp_link_down(intel_output, dp_priv->DP);
 			if (IS_eDP(intel_output))
-				igdng_edp_backlight_off(dev);
+				ironlake_edp_backlight_off(dev);
 		}
 	} else {
 		if (!(dp_reg & DP_PORT_EN)) {
 			intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration);
 			if (IS_eDP(intel_output))
-				igdng_edp_backlight_on(dev);
+				ironlake_edp_backlight_on(dev);
 		}
 	}
 	dp_priv->dpms_mode = mode;
@@ -1010,7 +1072,7 @@
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_dp_priv *dp_priv = intel_output->dev_priv;
 
-	DRM_DEBUG("\n");
+	DRM_DEBUG_KMS("\n");
 
 	if (IS_eDP(intel_output)) {
 		DP &= ~DP_PLL_ENABLE;
@@ -1071,7 +1133,7 @@
 }
 
 static enum drm_connector_status
-igdng_dp_detect(struct drm_connector *connector)
+ironlake_dp_detect(struct drm_connector *connector)
 {
 	struct intel_output *intel_output = to_intel_output(connector);
 	struct intel_dp_priv *dp_priv = intel_output->dev_priv;
@@ -1106,8 +1168,8 @@
 
 	dp_priv->has_audio = false;
 
-	if (IS_IGDNG(dev))
-		return igdng_dp_detect(connector);
+	if (IS_IRONLAKE(dev))
+		return ironlake_dp_detect(connector);
 
 	temp = I915_READ(PORT_HOTPLUG_EN);
 
@@ -1227,7 +1289,53 @@
 	if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON)
 		intel_dp_check_link_status(intel_output);
 }
+/*
+ * Enumerate the child dev array parsed from VBT to check whether
+ * the given DP is present.
+ * If it is present, return 1.
+ * If it is not present, return false.
+ * If no child dev is parsed from VBT, it is assumed that the given
+ * DP is present.
+ */
+static int dp_is_present_in_vbt(struct drm_device *dev, int dp_reg)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct child_device_config *p_child;
+	int i, dp_port, ret;
 
+	if (!dev_priv->child_dev_num)
+		return 1;
+
+	dp_port = 0;
+	if (dp_reg == DP_B || dp_reg == PCH_DP_B)
+		dp_port = PORT_IDPB;
+	else if (dp_reg == DP_C || dp_reg == PCH_DP_C)
+		dp_port = PORT_IDPC;
+	else if (dp_reg == DP_D || dp_reg == PCH_DP_D)
+		dp_port = PORT_IDPD;
+
+	ret = 0;
+	for (i = 0; i < dev_priv->child_dev_num; i++) {
+		p_child = dev_priv->child_dev + i;
+		/*
+		 * If the device type is not DP, continue.
+		 */
+		if (p_child->device_type != DEVICE_TYPE_DP &&
+			p_child->device_type != DEVICE_TYPE_eDP)
+			continue;
+		/* Find the eDP port */
+		if (dp_reg == DP_A && p_child->device_type == DEVICE_TYPE_eDP) {
+			ret = 1;
+			break;
+		}
+		/* Find the DP port */
+		if (p_child->dvo_port == dp_port) {
+			ret = 1;
+			break;
+		}
+	}
+	return ret;
+}
 void
 intel_dp_init(struct drm_device *dev, int output_reg)
 {
@@ -1237,6 +1345,10 @@
 	struct intel_dp_priv *dp_priv;
 	const char *name = NULL;
 
+	if (!dp_is_present_in_vbt(dev, output_reg)) {
+		DRM_DEBUG_KMS("DP is not present. Ignore it\n");
+		return;
+	}
 	intel_output = kcalloc(sizeof(struct intel_output) + 
 			       sizeof(struct intel_dp_priv), 1, GFP_KERNEL);
 	if (!intel_output)
@@ -1254,11 +1366,11 @@
 	else
 		intel_output->type = INTEL_OUTPUT_DISPLAYPORT;
 
-	if (output_reg == DP_B)
+	if (output_reg == DP_B || output_reg == PCH_DP_B)
 		intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
-	else if (output_reg == DP_C)
+	else if (output_reg == DP_C || output_reg == PCH_DP_C)
 		intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
-	else if (output_reg == DP_D)
+	else if (output_reg == DP_D || output_reg == PCH_DP_D)
 		intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
 
 	if (IS_eDP(intel_output)) {
diff --git a/drivers/gpu/drm/i915/intel_dp.h b/drivers/gpu/drm/i915/intel_dp.h
deleted file mode 100644
index 2b38054..0000000
--- a/drivers/gpu/drm/i915/intel_dp.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright © 2008 Keith Packard
- *
- * 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.
- */
-
-#ifndef _INTEL_DP_H_
-#define _INTEL_DP_H_
-
-/* From the VESA DisplayPort spec */
-
-#define AUX_NATIVE_WRITE	0x8
-#define AUX_NATIVE_READ		0x9
-#define AUX_I2C_WRITE		0x0
-#define AUX_I2C_READ		0x1
-#define AUX_I2C_STATUS		0x2
-#define AUX_I2C_MOT		0x4
-
-#define AUX_NATIVE_REPLY_ACK	(0x0 << 4)
-#define AUX_NATIVE_REPLY_NACK	(0x1 << 4)
-#define AUX_NATIVE_REPLY_DEFER	(0x2 << 4)
-#define AUX_NATIVE_REPLY_MASK	(0x3 << 4)
-
-#define AUX_I2C_REPLY_ACK	(0x0 << 6)
-#define AUX_I2C_REPLY_NACK	(0x1 << 6)
-#define AUX_I2C_REPLY_DEFER	(0x2 << 6)
-#define AUX_I2C_REPLY_MASK	(0x3 << 6)
-
-/* AUX CH addresses */
-#define	DP_LINK_BW_SET		0x100
-# define DP_LINK_BW_1_62		    0x06
-# define DP_LINK_BW_2_7			    0x0a
-
-#define DP_LANE_COUNT_SET	0x101
-# define DP_LANE_COUNT_MASK		    0x0f
-# define DP_LANE_COUNT_ENHANCED_FRAME_EN    (1 << 7)
-
-#define DP_TRAINING_PATTERN_SET	0x102
-
-# define DP_TRAINING_PATTERN_DISABLE	    0
-# define DP_TRAINING_PATTERN_1		    1
-# define DP_TRAINING_PATTERN_2		    2
-# define DP_TRAINING_PATTERN_MASK	    0x3
-
-# define DP_LINK_QUAL_PATTERN_DISABLE	    (0 << 2)
-# define DP_LINK_QUAL_PATTERN_D10_2	    (1 << 2)
-# define DP_LINK_QUAL_PATTERN_ERROR_RATE    (2 << 2)
-# define DP_LINK_QUAL_PATTERN_PRBS7	    (3 << 2)
-# define DP_LINK_QUAL_PATTERN_MASK	    (3 << 2)
-
-# define DP_RECOVERED_CLOCK_OUT_EN	    (1 << 4)
-# define DP_LINK_SCRAMBLING_DISABLE	    (1 << 5)
-
-# define DP_SYMBOL_ERROR_COUNT_BOTH	    (0 << 6)
-# define DP_SYMBOL_ERROR_COUNT_DISPARITY    (1 << 6)
-# define DP_SYMBOL_ERROR_COUNT_SYMBOL	    (2 << 6)
-# define DP_SYMBOL_ERROR_COUNT_MASK	    (3 << 6)
-
-#define DP_TRAINING_LANE0_SET		    0x103
-#define DP_TRAINING_LANE1_SET		    0x104
-#define DP_TRAINING_LANE2_SET		    0x105
-#define DP_TRAINING_LANE3_SET		    0x106
-
-# define DP_TRAIN_VOLTAGE_SWING_MASK	    0x3
-# define DP_TRAIN_VOLTAGE_SWING_SHIFT	    0
-# define DP_TRAIN_MAX_SWING_REACHED	    (1 << 2)
-# define DP_TRAIN_VOLTAGE_SWING_400	    (0 << 0)
-# define DP_TRAIN_VOLTAGE_SWING_600	    (1 << 0)
-# define DP_TRAIN_VOLTAGE_SWING_800	    (2 << 0)
-# define DP_TRAIN_VOLTAGE_SWING_1200	    (3 << 0)
-
-# define DP_TRAIN_PRE_EMPHASIS_MASK	    (3 << 3)
-# define DP_TRAIN_PRE_EMPHASIS_0	    (0 << 3)
-# define DP_TRAIN_PRE_EMPHASIS_3_5	    (1 << 3)
-# define DP_TRAIN_PRE_EMPHASIS_6	    (2 << 3)
-# define DP_TRAIN_PRE_EMPHASIS_9_5	    (3 << 3)
-
-# define DP_TRAIN_PRE_EMPHASIS_SHIFT	    3
-# define DP_TRAIN_MAX_PRE_EMPHASIS_REACHED  (1 << 5)
-
-#define DP_DOWNSPREAD_CTRL		    0x107
-# define DP_SPREAD_AMP_0_5		    (1 << 4)
-
-#define DP_MAIN_LINK_CHANNEL_CODING_SET	    0x108
-# define DP_SET_ANSI_8B10B		    (1 << 0)
-
-#define DP_LANE0_1_STATUS		    0x202
-#define DP_LANE2_3_STATUS		    0x203
-
-# define DP_LANE_CR_DONE		    (1 << 0)
-# define DP_LANE_CHANNEL_EQ_DONE	    (1 << 1)
-# define DP_LANE_SYMBOL_LOCKED		    (1 << 2)
-
-#define DP_LANE_ALIGN_STATUS_UPDATED	    0x204
-
-#define DP_INTERLANE_ALIGN_DONE		    (1 << 0)
-#define DP_DOWNSTREAM_PORT_STATUS_CHANGED   (1 << 6)
-#define DP_LINK_STATUS_UPDATED		    (1 << 7)
-
-#define DP_SINK_STATUS			    0x205
-
-#define DP_RECEIVE_PORT_0_STATUS	    (1 << 0)
-#define DP_RECEIVE_PORT_1_STATUS	    (1 << 1)
-
-#define DP_ADJUST_REQUEST_LANE0_1	    0x206
-#define DP_ADJUST_REQUEST_LANE2_3	    0x207
-
-#define DP_ADJUST_VOLTAGE_SWING_LANE0_MASK  0x03
-#define DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT 0
-#define DP_ADJUST_PRE_EMPHASIS_LANE0_MASK   0x0c
-#define DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT  2
-#define DP_ADJUST_VOLTAGE_SWING_LANE1_MASK  0x30
-#define DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT 4
-#define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK   0xc0
-#define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT  6
-
-struct i2c_algo_dp_aux_data {
-	bool running;
-	u16 address;
-	int (*aux_ch) (struct i2c_adapter *adapter,
-		       uint8_t *send, int send_bytes,
-		       uint8_t *recv, int recv_bytes);
-};
-
-int
-i2c_dp_aux_add_bus(struct i2c_adapter *adapter);
-
-#endif /* _INTEL_DP_H_ */
diff --git a/drivers/gpu/drm/i915/intel_dp_i2c.c b/drivers/gpu/drm/i915/intel_dp_i2c.c
deleted file mode 100644
index a63b6f5..0000000
--- a/drivers/gpu/drm/i915/intel_dp_i2c.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright © 2009 Keith Packard
- *
- * 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.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/i2c.h>
-#include "intel_dp.h"
-#include "drmP.h"
-
-/* Run a single AUX_CH I2C transaction, writing/reading data as necessary */
-
-#define MODE_I2C_START	1
-#define MODE_I2C_WRITE	2
-#define MODE_I2C_READ	4
-#define MODE_I2C_STOP	8
-
-static int
-i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode,
-			    uint8_t write_byte, uint8_t *read_byte)
-{
-	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
-	uint16_t address = algo_data->address;
-	uint8_t msg[5];
-	uint8_t reply[2];
-	int msg_bytes;
-	int reply_bytes;
-	int ret;
-
-	/* Set up the command byte */
-	if (mode & MODE_I2C_READ)
-		msg[0] = AUX_I2C_READ << 4;
-	else
-		msg[0] = AUX_I2C_WRITE << 4;
-
-	if (!(mode & MODE_I2C_STOP))
-		msg[0] |= AUX_I2C_MOT << 4;
-
-	msg[1] = address >> 8;
-	msg[2] = address;
-
-	switch (mode) {
-	case MODE_I2C_WRITE:
-		msg[3] = 0;
-		msg[4] = write_byte;
-		msg_bytes = 5;
-		reply_bytes = 1;
-		break;
-	case MODE_I2C_READ:
-		msg[3] = 0;
-		msg_bytes = 4;
-		reply_bytes = 2;
-		break;
-	default:
-		msg_bytes = 3;
-		reply_bytes = 1;
-		break;
-	}
-
-	for (;;) {
-		ret = (*algo_data->aux_ch)(adapter,
-					   msg, msg_bytes,
-					   reply, reply_bytes);
-		if (ret < 0) {
-			DRM_DEBUG("aux_ch failed %d\n", ret);
-			return ret;
-		}
-		switch (reply[0] & AUX_I2C_REPLY_MASK) {
-		case AUX_I2C_REPLY_ACK:
-			if (mode == MODE_I2C_READ) {
-				*read_byte = reply[1];
-			}
-			return reply_bytes - 1;
-		case AUX_I2C_REPLY_NACK:
-			DRM_DEBUG("aux_ch nack\n");
-			return -EREMOTEIO;
-		case AUX_I2C_REPLY_DEFER:
-			DRM_DEBUG("aux_ch defer\n");
-			udelay(100);
-			break;
-		default:
-			DRM_ERROR("aux_ch invalid reply 0x%02x\n", reply[0]);
-			return -EREMOTEIO;
-		}
-	}
-}
-
-/*
- * I2C over AUX CH
- */
-
-/*
- * Send the address. If the I2C link is running, this 'restarts'
- * the connection with the new address, this is used for doing
- * a write followed by a read (as needed for DDC)
- */
-static int
-i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 address, bool reading)
-{
-	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
-	int mode = MODE_I2C_START;
-	int ret;
-
-	if (reading)
-		mode |= MODE_I2C_READ;
-	else
-		mode |= MODE_I2C_WRITE;
-	algo_data->address = address;
-	algo_data->running = true;
-	ret = i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
-	return ret;
-}
-
-/*
- * Stop the I2C transaction. This closes out the link, sending
- * a bare address packet with the MOT bit turned off
- */
-static void
-i2c_algo_dp_aux_stop(struct i2c_adapter *adapter, bool reading)
-{
-	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
-	int mode = MODE_I2C_STOP;
-
-	if (reading)
-		mode |= MODE_I2C_READ;
-	else
-		mode |= MODE_I2C_WRITE;
-	if (algo_data->running) {
-		(void) i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
-		algo_data->running = false;
-	}
-}
-
-/*
- * Write a single byte to the current I2C address, the
- * the I2C link must be running or this returns -EIO
- */
-static int
-i2c_algo_dp_aux_put_byte(struct i2c_adapter *adapter, u8 byte)
-{
-	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
-	int ret;
-
-	if (!algo_data->running)
-		return -EIO;
-
-	ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_WRITE, byte, NULL);
-	return ret;
-}
-
-/*
- * Read a single byte from the current I2C address, the
- * I2C link must be running or this returns -EIO
- */
-static int
-i2c_algo_dp_aux_get_byte(struct i2c_adapter *adapter, u8 *byte_ret)
-{
-	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
-	int ret;
-
-	if (!algo_data->running)
-		return -EIO;
-
-	ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_READ, 0, byte_ret);
-	return ret;
-}
-
-static int
-i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter,
-		     struct i2c_msg *msgs,
-		     int num)
-{
-	int ret = 0;
-	bool reading = false;
-	int m;
-	int b;
-
-	for (m = 0; m < num; m++) {
-		u16 len = msgs[m].len;
-		u8 *buf = msgs[m].buf;
-		reading = (msgs[m].flags & I2C_M_RD) != 0;
-		ret = i2c_algo_dp_aux_address(adapter, msgs[m].addr, reading);
-		if (ret < 0)
-			break;
-		if (reading) {
-			for (b = 0; b < len; b++) {
-				ret = i2c_algo_dp_aux_get_byte(adapter, &buf[b]);
-				if (ret < 0)
-					break;
-			}
-		} else {
-			for (b = 0; b < len; b++) {
-				ret = i2c_algo_dp_aux_put_byte(adapter, buf[b]);
-				if (ret < 0)
-					break;
-			}
-		}
-		if (ret < 0)
-			break;
-	}
-	if (ret >= 0)
-		ret = num;
-	i2c_algo_dp_aux_stop(adapter, reading);
-	DRM_DEBUG("dp_aux_xfer return %d\n", ret);
-	return ret;
-}
-
-static u32
-i2c_algo_dp_aux_functionality(struct i2c_adapter *adapter)
-{
-	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
-	       I2C_FUNC_SMBUS_READ_BLOCK_DATA |
-	       I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
-	       I2C_FUNC_10BIT_ADDR;
-}
-
-static const struct i2c_algorithm i2c_dp_aux_algo = {
-	.master_xfer	= i2c_algo_dp_aux_xfer,
-	.functionality	= i2c_algo_dp_aux_functionality,
-};
-
-static void
-i2c_dp_aux_reset_bus(struct i2c_adapter *adapter)
-{
-	(void) i2c_algo_dp_aux_address(adapter, 0, false);
-	(void) i2c_algo_dp_aux_stop(adapter, false);
-					   
-}
-
-static int
-i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter)
-{
-	adapter->algo = &i2c_dp_aux_algo;
-	adapter->retries = 3;
-	i2c_dp_aux_reset_bus(adapter);
-	return 0;
-}
-
-int
-i2c_dp_aux_add_bus(struct i2c_adapter *adapter)
-{
-	int error;
-	
-	error = i2c_dp_aux_prepare_bus(adapter);
-	if (error)
-		return error;
-	error = i2c_add_adapter(adapter);
-	return error;
-}
-EXPORT_SYMBOL(i2c_dp_aux_add_bus);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index ef61fe9..a51573d 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -110,6 +110,32 @@
 	int clone_mask;
 };
 
+struct intel_crtc;
+struct intel_overlay {
+	struct drm_device *dev;
+	struct intel_crtc *crtc;
+	struct drm_i915_gem_object *vid_bo;
+	struct drm_i915_gem_object *old_vid_bo;
+	int active;
+	int pfit_active;
+	u32 pfit_vscale_ratio; /* shifted-point number, (1<<12) == 1.0 */
+	u32 color_key;
+	u32 brightness, contrast, saturation;
+	u32 old_xscale, old_yscale;
+	/* register access */
+	u32 flip_addr;
+	struct drm_i915_gem_object *reg_bo;
+	void *virt_addr;
+	/* flip handling */
+	uint32_t last_flip_req;
+	int hw_wedged;
+#define HW_WEDGED		1
+#define NEEDS_WAIT_FOR_FLIP	2
+#define RELEASE_OLD_VID		3
+#define SWITCH_OFF_STAGE_1	4
+#define SWITCH_OFF_STAGE_2	5
+};
+
 struct intel_crtc {
 	struct drm_crtc base;
 	enum pipe pipe;
@@ -121,6 +147,8 @@
 	bool busy; /* is scanout buffer being updated frequently? */
 	struct timer_list idle_timer;
 	bool lowfreq_avail;
+	struct intel_overlay *overlay;
+	struct intel_unpin_work *unpin_work;
 };
 
 #define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
@@ -134,6 +162,8 @@
 int intel_ddc_get_modes(struct intel_output *intel_output);
 extern bool intel_ddc_probe(struct intel_output *intel_output);
 void intel_i2c_quirk_set(struct drm_device *dev, bool enable);
+void intel_i2c_reset_gmbus(struct drm_device *dev);
+
 extern void intel_crt_init(struct drm_device *dev);
 extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg);
 extern bool intel_sdvo_init(struct drm_device *dev, int output_device);
@@ -148,6 +178,7 @@
 extern void intel_edp_link_config (struct intel_output *, int *, int *);
 
 
+extern int intel_panel_fitter_pipe (struct drm_device *dev);
 extern void intel_crtc_load_lut(struct drm_crtc *crtc);
 extern void intel_encoder_prepare (struct drm_encoder *encoder);
 extern void intel_encoder_commit (struct drm_encoder *encoder);
@@ -177,10 +208,23 @@
 				    u16 blue, int regno);
 extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
 				    u16 *blue, int regno);
+extern void intel_init_clock_gating(struct drm_device *dev);
 
 extern int intel_framebuffer_create(struct drm_device *dev,
 				    struct drm_mode_fb_cmd *mode_cmd,
 				    struct drm_framebuffer **fb,
 				    struct drm_gem_object *obj);
 
+extern void intel_prepare_page_flip(struct drm_device *dev, int plane);
+extern void intel_finish_page_flip(struct drm_device *dev, int pipe);
+
+extern void intel_setup_overlay(struct drm_device *dev);
+extern void intel_cleanup_overlay(struct drm_device *dev);
+extern int intel_overlay_switch_off(struct intel_overlay *overlay);
+extern int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
+						int interruptible);
+extern int intel_overlay_put_image(struct drm_device *dev, void *data,
+				   struct drm_file *file_priv);
+extern int intel_overlay_attrs(struct drm_device *dev, void *data,
+			       struct drm_file *file_priv);
 #endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index 2b0fe54..371d753 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -70,7 +70,7 @@
 
 
 /**
- * Curretly it is assumed that the old framebuffer is reused.
+ * Currently it is assumed that the old framebuffer is reused.
  *
  * LOCKING
  * caller should hold the mode config lock.
@@ -230,8 +230,9 @@
 	par->intel_fb = intel_fb;
 
 	/* To allow resizeing without swapping buffers */
-	DRM_DEBUG("allocated %dx%d fb: 0x%08x, bo %p\n", intel_fb->base.width,
-		  intel_fb->base.height, obj_priv->gtt_offset, fbo);
+	DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n",
+			intel_fb->base.width, intel_fb->base.height,
+			obj_priv->gtt_offset, fbo);
 
 	mutex_unlock(&dev->struct_mutex);
 	return 0;
@@ -249,7 +250,7 @@
 {
 	int ret;
 
-	DRM_DEBUG("\n");
+	DRM_DEBUG_KMS("\n");
 	ret = drm_fb_helper_single_fb_probe(dev, 32, intelfb_create);
 	return ret;
 }
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index c33451a..f04dbbe 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -82,7 +82,7 @@
 	/* HW workaround, need to toggle enable bit off and on for 12bpc, but
 	 * we do this anyway which shows more stable in testing.
 	 */
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		I915_WRITE(hdmi_priv->sdvox_reg, temp & ~SDVO_ENABLE);
 		POSTING_READ(hdmi_priv->sdvox_reg);
 	}
@@ -99,7 +99,7 @@
 	/* HW workaround, need to write this twice for issue that may result
 	 * in first write getting masked.
 	 */
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		I915_WRITE(hdmi_priv->sdvox_reg, temp);
 		POSTING_READ(hdmi_priv->sdvox_reg);
 	}
@@ -225,7 +225,52 @@
 	.destroy = intel_hdmi_enc_destroy,
 };
 
+/*
+ * Enumerate the child dev array parsed from VBT to check whether
+ * the given HDMI is present.
+ * If it is present, return 1.
+ * If it is not present, return false.
+ * If no child dev is parsed from VBT, it assumes that the given
+ * HDMI is present.
+ */
+static int hdmi_is_present_in_vbt(struct drm_device *dev, int hdmi_reg)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct child_device_config *p_child;
+	int i, hdmi_port, ret;
 
+	if (!dev_priv->child_dev_num)
+		return 1;
+
+	if (hdmi_reg == SDVOB)
+		hdmi_port = DVO_B;
+	else if (hdmi_reg == SDVOC)
+		hdmi_port = DVO_C;
+	else if (hdmi_reg == HDMIB)
+		hdmi_port = DVO_B;
+	else if (hdmi_reg == HDMIC)
+		hdmi_port = DVO_C;
+	else if (hdmi_reg == HDMID)
+		hdmi_port = DVO_D;
+	else
+		return 0;
+
+	ret = 0;
+	for (i = 0; i < dev_priv->child_dev_num; i++) {
+		p_child = dev_priv->child_dev + i;
+		/*
+		 * If the device type is not HDMI, continue.
+		 */
+		if (p_child->device_type != DEVICE_TYPE_HDMI)
+			continue;
+		/* Find the HDMI port */
+		if (p_child->dvo_port == hdmi_port) {
+			ret = 1;
+			break;
+		}
+	}
+	return ret;
+}
 void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -233,6 +278,10 @@
 	struct intel_output *intel_output;
 	struct intel_hdmi_priv *hdmi_priv;
 
+	if (!hdmi_is_present_in_vbt(dev, sdvox_reg)) {
+		DRM_DEBUG_KMS("HDMI is not present. Ignored it \n");
+		return;
+	}
 	intel_output = kcalloc(sizeof(struct intel_output) +
 			       sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL);
 	if (!intel_output)
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index c7eab72..8673c73 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -39,7 +39,7 @@
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
 	/* When using bit bashing for I2C, this bit needs to be set to 1 */
-	if (!IS_IGD(dev))
+	if (!IS_PINEVIEW(dev))
 		return;
 	if (enable)
 		I915_WRITE(DSPCLK_GATE_D,
@@ -118,6 +118,23 @@
 	udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */
 }
 
+/* Clears the GMBUS setup.  Our driver doesn't make use of the GMBUS I2C
+ * engine, but if the BIOS leaves it enabled, then that can break our use
+ * of the bit-banging I2C interfaces.  This is notably the case with the
+ * Mac Mini in EFI mode.
+ */
+void
+intel_i2c_reset_gmbus(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (IS_IRONLAKE(dev)) {
+		I915_WRITE(PCH_GMBUS0, 0);
+	} else {
+		I915_WRITE(GMBUS0, 0);
+	}
+}
+
 /**
  * intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg
  * @dev: DRM device
@@ -168,6 +185,8 @@
 	if(i2c_bit_add_bus(&chan->adapter))
 		goto out_free;
 
+	intel_i2c_reset_gmbus(dev);
+
 	/* JJJ:  raise SCL and SDA? */
 	intel_i2c_quirk_set(dev, true);
 	set_data(chan, 1);
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 05598ae..3118ce2 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -56,7 +56,7 @@
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 blc_pwm_ctl, reg;
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		reg = BLC_PWM_CPU_CTL;
 	else
 		reg = BLC_PWM_CTL;
@@ -74,7 +74,7 @@
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 reg;
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		reg = BLC_PWM_PCH_CTL2;
 	else
 		reg = BLC_PWM_CTL;
@@ -91,7 +91,7 @@
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 pp_status, ctl_reg, status_reg;
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		ctl_reg = PCH_PP_CONTROL;
 		status_reg = PCH_PP_STATUS;
 	} else {
@@ -137,7 +137,7 @@
 	u32 pp_on_reg, pp_off_reg, pp_ctl_reg, pp_div_reg;
 	u32 pwm_ctl_reg;
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		pp_on_reg = PCH_PP_ON_DELAYS;
 		pp_off_reg = PCH_PP_OFF_DELAYS;
 		pp_ctl_reg = PCH_PP_CONTROL;
@@ -174,7 +174,7 @@
 	u32 pp_on_reg, pp_off_reg, pp_ctl_reg, pp_div_reg;
 	u32 pwm_ctl_reg;
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		pp_on_reg = PCH_PP_ON_DELAYS;
 		pp_off_reg = PCH_PP_OFF_DELAYS;
 		pp_ctl_reg = PCH_PP_CONTROL;
@@ -297,7 +297,7 @@
 	}
 
 	/* full screen scale for now */
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		goto out;
 
 	/* 965+ wants fuzzy fitting */
@@ -327,7 +327,7 @@
 	 * to register description and PRM.
 	 * Change the value here to see the borders for debugging
 	 */
-	if (!IS_IGDNG(dev)) {
+	if (!IS_IRONLAKE(dev)) {
 		I915_WRITE(BCLRPAT_A, 0);
 		I915_WRITE(BCLRPAT_B, 0);
 	}
@@ -548,7 +548,7 @@
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 reg;
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		reg = BLC_PWM_CPU_CTL;
 	else
 		reg = BLC_PWM_CTL;
@@ -587,7 +587,7 @@
 	 * settings.
 	 */
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		return;
 
 	/*
@@ -899,7 +899,7 @@
 
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
 				ACPI_UINT32_MAX,
-				check_lid_device, &lid_present, NULL);
+				check_lid_device, NULL, &lid_present, NULL);
 
 	return lid_present;
 }
@@ -914,6 +914,101 @@
 #endif
 
 /**
+ * intel_find_lvds_downclock - find the reduced downclock for LVDS in EDID
+ * @dev: drm device
+ * @connector: LVDS connector
+ *
+ * Find the reduced downclock for LVDS in EDID.
+ */
+static void intel_find_lvds_downclock(struct drm_device *dev,
+				struct drm_connector *connector)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_display_mode *scan, *panel_fixed_mode;
+	int temp_downclock;
+
+	panel_fixed_mode = dev_priv->panel_fixed_mode;
+	temp_downclock = panel_fixed_mode->clock;
+
+	mutex_lock(&dev->mode_config.mutex);
+	list_for_each_entry(scan, &connector->probed_modes, head) {
+		/*
+		 * If one mode has the same resolution with the fixed_panel
+		 * mode while they have the different refresh rate, it means
+		 * that the reduced downclock is found for the LVDS. In such
+		 * case we can set the different FPx0/1 to dynamically select
+		 * between low and high frequency.
+		 */
+		if (scan->hdisplay == panel_fixed_mode->hdisplay &&
+			scan->hsync_start == panel_fixed_mode->hsync_start &&
+			scan->hsync_end == panel_fixed_mode->hsync_end &&
+			scan->htotal == panel_fixed_mode->htotal &&
+			scan->vdisplay == panel_fixed_mode->vdisplay &&
+			scan->vsync_start == panel_fixed_mode->vsync_start &&
+			scan->vsync_end == panel_fixed_mode->vsync_end &&
+			scan->vtotal == panel_fixed_mode->vtotal) {
+			if (scan->clock < temp_downclock) {
+				/*
+				 * The downclock is already found. But we
+				 * expect to find the lower downclock.
+				 */
+				temp_downclock = scan->clock;
+			}
+		}
+	}
+	mutex_unlock(&dev->mode_config.mutex);
+	if (temp_downclock < panel_fixed_mode->clock) {
+		/* We found the downclock for LVDS. */
+		dev_priv->lvds_downclock_avail = 1;
+		dev_priv->lvds_downclock = temp_downclock;
+		DRM_DEBUG_KMS("LVDS downclock is found in EDID. "
+				"Normal clock %dKhz, downclock %dKhz\n",
+				panel_fixed_mode->clock, temp_downclock);
+	}
+	return;
+}
+
+/*
+ * Enumerate the child dev array parsed from VBT to check whether
+ * the LVDS is present.
+ * If it is present, return 1.
+ * If it is not present, return false.
+ * If no child dev is parsed from VBT, it assumes that the LVDS is present.
+ * Note: The addin_offset should also be checked for LVDS panel.
+ * Only when it is non-zero, it is assumed that it is present.
+ */
+static int lvds_is_present_in_vbt(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct child_device_config *p_child;
+	int i, ret;
+
+	if (!dev_priv->child_dev_num)
+		return 1;
+
+	ret = 0;
+	for (i = 0; i < dev_priv->child_dev_num; i++) {
+		p_child = dev_priv->child_dev + i;
+		/*
+		 * If the device type is not LFP, continue.
+		 * If the device type is 0x22, it is also regarded as LFP.
+		 */
+		if (p_child->device_type != DEVICE_TYPE_INT_LFP &&
+			p_child->device_type != DEVICE_TYPE_LFP)
+			continue;
+
+		/* The addin_offset should be checked. Only when it is
+		 * non-zero, it is regarded as present.
+		 */
+		if (p_child->addin_offset) {
+			ret = 1;
+			break;
+		}
+	}
+	return ret;
+}
+
+/**
  * intel_lvds_init - setup LVDS connectors on this device
  * @dev: drm device
  *
@@ -936,21 +1031,20 @@
 	if (dmi_check_system(intel_no_lvds))
 		return;
 
-	/* Assume that any device without an ACPI LID device also doesn't
-	 * have an integrated LVDS.  We would be better off parsing the BIOS
-	 * to get a reliable indicator, but that code isn't written yet.
-	 *
-	 * In the case of all-in-one desktops using LVDS that we've seen,
-	 * they're using SDVO LVDS.
+	/*
+	 * Assume LVDS is present if there's an ACPI lid device or if the
+	 * device is present in the VBT.
 	 */
-	if (!intel_lid_present())
+	if (!lvds_is_present_in_vbt(dev) && !intel_lid_present()) {
+		DRM_DEBUG_KMS("LVDS is not present in VBT and no lid detected\n");
 		return;
+	}
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0)
 			return;
 		if (dev_priv->edp_support) {
-			DRM_DEBUG("disable LVDS for eDP support\n");
+			DRM_DEBUG_KMS("disable LVDS for eDP support\n");
 			return;
 		}
 		gpio = PCH_GPIOC;
@@ -1023,6 +1117,7 @@
 			dev_priv->panel_fixed_mode =
 				drm_mode_duplicate(dev, scan);
 			mutex_unlock(&dev->mode_config.mutex);
+			intel_find_lvds_downclock(dev, connector);
 			goto out;
 		}
 		mutex_unlock(&dev->mode_config.mutex);
@@ -1047,8 +1142,8 @@
 	 * correct mode.
 	 */
 
-	/* IGDNG: FIXME if still fail, not try pipe mode now */
-	if (IS_IGDNG(dev))
+	/* Ironlake: FIXME if still fail, not try pipe mode now */
+	if (IS_IRONLAKE(dev))
 		goto failed;
 
 	lvds = I915_READ(LVDS);
@@ -1069,7 +1164,7 @@
 		goto failed;
 
 out:
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		u32 pwm;
 		/* make sure PWM is enabled */
 		pwm = I915_READ(BLC_PWM_CPU_CTL2);
@@ -1082,7 +1177,7 @@
 	}
 	dev_priv->lid_notifier.notifier_call = intel_lid_notify;
 	if (acpi_lid_notifier_register(&dev_priv->lid_notifier)) {
-		DRM_DEBUG("lid notifier registration failed\n");
+		DRM_DEBUG_KMS("lid notifier registration failed\n");
 		dev_priv->lid_notifier.notifier_call = NULL;
 	}
 	drm_sysfs_connector_add(connector);
@@ -1093,5 +1188,6 @@
 	if (intel_output->ddc_bus)
 		intel_i2c_destroy(intel_output->ddc_bus);
 	drm_connector_cleanup(connector);
+	drm_encoder_cleanup(encoder);
 	kfree(intel_output);
 }
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
new file mode 100644
index 0000000..2639591
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -0,0 +1,1416 @@
+/*
+ * Copyright © 2009
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Daniel Vetter <daniel@ffwll.ch>
+ *
+ * Derived from Xorg ddx, xf86-video-intel, src/i830_video.c
+ */
+#include "drmP.h"
+#include "drm.h"
+#include "i915_drm.h"
+#include "i915_drv.h"
+#include "i915_reg.h"
+#include "intel_drv.h"
+
+/* Limits for overlay size. According to intel doc, the real limits are:
+ * Y width: 4095, UV width (planar): 2047, Y height: 2047,
+ * UV width (planar): * 1023. But the xorg thinks 2048 for height and width. Use
+ * the mininum of both.  */
+#define IMAGE_MAX_WIDTH		2048
+#define IMAGE_MAX_HEIGHT	2046 /* 2 * 1023 */
+/* on 830 and 845 these large limits result in the card hanging */
+#define IMAGE_MAX_WIDTH_LEGACY	1024
+#define IMAGE_MAX_HEIGHT_LEGACY	1088
+
+/* overlay register definitions */
+/* OCMD register */
+#define OCMD_TILED_SURFACE	(0x1<<19)
+#define OCMD_MIRROR_MASK	(0x3<<17)
+#define OCMD_MIRROR_MODE	(0x3<<17)
+#define OCMD_MIRROR_HORIZONTAL	(0x1<<17)
+#define OCMD_MIRROR_VERTICAL	(0x2<<17)
+#define OCMD_MIRROR_BOTH	(0x3<<17)
+#define OCMD_BYTEORDER_MASK	(0x3<<14) /* zero for YUYV or FOURCC YUY2 */
+#define OCMD_UV_SWAP		(0x1<<14) /* YVYU */
+#define OCMD_Y_SWAP		(0x2<<14) /* UYVY or FOURCC UYVY */
+#define OCMD_Y_AND_UV_SWAP	(0x3<<14) /* VYUY */
+#define OCMD_SOURCE_FORMAT_MASK (0xf<<10)
+#define OCMD_RGB_888		(0x1<<10) /* not in i965 Intel docs */
+#define OCMD_RGB_555		(0x2<<10) /* not in i965 Intel docs */
+#define OCMD_RGB_565		(0x3<<10) /* not in i965 Intel docs */
+#define OCMD_YUV_422_PACKED	(0x8<<10)
+#define OCMD_YUV_411_PACKED	(0x9<<10) /* not in i965 Intel docs */
+#define OCMD_YUV_420_PLANAR	(0xc<<10)
+#define OCMD_YUV_422_PLANAR	(0xd<<10)
+#define OCMD_YUV_410_PLANAR	(0xe<<10) /* also 411 */
+#define OCMD_TVSYNCFLIP_PARITY	(0x1<<9)
+#define OCMD_TVSYNCFLIP_ENABLE	(0x1<<7)
+#define OCMD_BUF_TYPE_MASK	(Ox1<<5)
+#define OCMD_BUF_TYPE_FRAME	(0x0<<5)
+#define OCMD_BUF_TYPE_FIELD	(0x1<<5)
+#define OCMD_TEST_MODE		(0x1<<4)
+#define OCMD_BUFFER_SELECT	(0x3<<2)
+#define OCMD_BUFFER0		(0x0<<2)
+#define OCMD_BUFFER1		(0x1<<2)
+#define OCMD_FIELD_SELECT	(0x1<<2)
+#define OCMD_FIELD0		(0x0<<1)
+#define OCMD_FIELD1		(0x1<<1)
+#define OCMD_ENABLE		(0x1<<0)
+
+/* OCONFIG register */
+#define OCONF_PIPE_MASK		(0x1<<18)
+#define OCONF_PIPE_A		(0x0<<18)
+#define OCONF_PIPE_B		(0x1<<18)
+#define OCONF_GAMMA2_ENABLE	(0x1<<16)
+#define OCONF_CSC_MODE_BT601	(0x0<<5)
+#define OCONF_CSC_MODE_BT709	(0x1<<5)
+#define OCONF_CSC_BYPASS	(0x1<<4)
+#define OCONF_CC_OUT_8BIT	(0x1<<3)
+#define OCONF_TEST_MODE		(0x1<<2)
+#define OCONF_THREE_LINE_BUFFER	(0x1<<0)
+#define OCONF_TWO_LINE_BUFFER	(0x0<<0)
+
+/* DCLRKM (dst-key) register */
+#define DST_KEY_ENABLE		(0x1<<31)
+#define CLK_RGB24_MASK		0x0
+#define CLK_RGB16_MASK		0x070307
+#define CLK_RGB15_MASK		0x070707
+#define CLK_RGB8I_MASK		0xffffff
+
+#define RGB16_TO_COLORKEY(c) \
+	(((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3))
+#define RGB15_TO_COLORKEY(c) \
+	(((c & 0x7c00) << 9) | ((c & 0x03E0) << 6) | ((c & 0x001F) << 3))
+
+/* overlay flip addr flag */
+#define OFC_UPDATE		0x1
+
+/* polyphase filter coefficients */
+#define N_HORIZ_Y_TAPS          5
+#define N_VERT_Y_TAPS           3
+#define N_HORIZ_UV_TAPS         3
+#define N_VERT_UV_TAPS          3
+#define N_PHASES                17
+#define MAX_TAPS                5
+
+/* memory bufferd overlay registers */
+struct overlay_registers {
+    u32 OBUF_0Y;
+    u32 OBUF_1Y;
+    u32 OBUF_0U;
+    u32 OBUF_0V;
+    u32 OBUF_1U;
+    u32 OBUF_1V;
+    u32 OSTRIDE;
+    u32 YRGB_VPH;
+    u32 UV_VPH;
+    u32 HORZ_PH;
+    u32 INIT_PHS;
+    u32 DWINPOS;
+    u32 DWINSZ;
+    u32 SWIDTH;
+    u32 SWIDTHSW;
+    u32 SHEIGHT;
+    u32 YRGBSCALE;
+    u32 UVSCALE;
+    u32 OCLRC0;
+    u32 OCLRC1;
+    u32 DCLRKV;
+    u32 DCLRKM;
+    u32 SCLRKVH;
+    u32 SCLRKVL;
+    u32 SCLRKEN;
+    u32 OCONFIG;
+    u32 OCMD;
+    u32 RESERVED1; /* 0x6C */
+    u32 OSTART_0Y;
+    u32 OSTART_1Y;
+    u32 OSTART_0U;
+    u32 OSTART_0V;
+    u32 OSTART_1U;
+    u32 OSTART_1V;
+    u32 OTILEOFF_0Y;
+    u32 OTILEOFF_1Y;
+    u32 OTILEOFF_0U;
+    u32 OTILEOFF_0V;
+    u32 OTILEOFF_1U;
+    u32 OTILEOFF_1V;
+    u32 FASTHSCALE; /* 0xA0 */
+    u32 UVSCALEV; /* 0xA4 */
+    u32 RESERVEDC[(0x200 - 0xA8) / 4]; /* 0xA8 - 0x1FC */
+    u16 Y_VCOEFS[N_VERT_Y_TAPS * N_PHASES]; /* 0x200 */
+    u16 RESERVEDD[0x100 / 2 - N_VERT_Y_TAPS * N_PHASES];
+    u16 Y_HCOEFS[N_HORIZ_Y_TAPS * N_PHASES]; /* 0x300 */
+    u16 RESERVEDE[0x200 / 2 - N_HORIZ_Y_TAPS * N_PHASES];
+    u16 UV_VCOEFS[N_VERT_UV_TAPS * N_PHASES]; /* 0x500 */
+    u16 RESERVEDF[0x100 / 2 - N_VERT_UV_TAPS * N_PHASES];
+    u16 UV_HCOEFS[N_HORIZ_UV_TAPS * N_PHASES]; /* 0x600 */
+    u16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES];
+};
+
+/* overlay flip addr flag */
+#define OFC_UPDATE		0x1
+
+#define OVERLAY_NONPHYSICAL(dev) (IS_G33(dev) || IS_I965G(dev))
+#define OVERLAY_EXISTS(dev) (!IS_G4X(dev) && !IS_IRONLAKE(dev))
+
+
+static struct overlay_registers *intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
+{
+        drm_i915_private_t *dev_priv = overlay->dev->dev_private;
+	struct overlay_registers *regs;
+
+	/* no recursive mappings */
+	BUG_ON(overlay->virt_addr);
+
+	if (OVERLAY_NONPHYSICAL(overlay->dev)) {
+		regs = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
+				overlay->reg_bo->gtt_offset);
+
+		if (!regs) {
+			DRM_ERROR("failed to map overlay regs in GTT\n");
+			return NULL;
+		}
+	} else
+		regs = overlay->reg_bo->phys_obj->handle->vaddr;
+
+	return overlay->virt_addr = regs;
+}
+
+static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay)
+{
+	struct drm_device *dev = overlay->dev;
+        drm_i915_private_t *dev_priv = dev->dev_private;
+
+	if (OVERLAY_NONPHYSICAL(overlay->dev))
+		io_mapping_unmap_atomic(overlay->virt_addr);
+
+	overlay->virt_addr = NULL;
+
+	I915_READ(OVADD); /* flush wc cashes */
+
+	return;
+}
+
+/* overlay needs to be disable in OCMD reg */
+static int intel_overlay_on(struct intel_overlay *overlay)
+{
+	struct drm_device *dev = overlay->dev;
+        drm_i915_private_t *dev_priv = dev->dev_private;
+	int ret;
+	RING_LOCALS;
+
+	BUG_ON(overlay->active);
+
+	overlay->active = 1;
+	overlay->hw_wedged = NEEDS_WAIT_FOR_FLIP;
+
+	BEGIN_LP_RING(6);
+	OUT_RING(MI_FLUSH);
+	OUT_RING(MI_NOOP);
+	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_ON);
+	OUT_RING(overlay->flip_addr | OFC_UPDATE);
+	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+	OUT_RING(MI_NOOP);
+	ADVANCE_LP_RING();
+
+	overlay->last_flip_req = i915_add_request(dev, NULL, 0);
+	if (overlay->last_flip_req == 0)
+		return -ENOMEM;
+
+	ret = i915_do_wait_request(dev, overlay->last_flip_req, 1);
+	if (ret != 0)
+		return ret;
+
+	overlay->hw_wedged = 0;
+	overlay->last_flip_req = 0;
+	return 0;
+}
+
+/* overlay needs to be enabled in OCMD reg */
+static void intel_overlay_continue(struct intel_overlay *overlay,
+			    bool load_polyphase_filter)
+{
+	struct drm_device *dev = overlay->dev;
+        drm_i915_private_t *dev_priv = dev->dev_private;
+	u32 flip_addr = overlay->flip_addr;
+	u32 tmp;
+	RING_LOCALS;
+
+	BUG_ON(!overlay->active);
+
+	if (load_polyphase_filter)
+		flip_addr |= OFC_UPDATE;
+
+	/* check for underruns */
+	tmp = I915_READ(DOVSTA);
+	if (tmp & (1 << 17))
+		DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
+
+	BEGIN_LP_RING(4);
+	OUT_RING(MI_FLUSH);
+	OUT_RING(MI_NOOP);
+	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
+	OUT_RING(flip_addr);
+        ADVANCE_LP_RING();
+
+	overlay->last_flip_req = i915_add_request(dev, NULL, 0);
+}
+
+static int intel_overlay_wait_flip(struct intel_overlay *overlay)
+{
+	struct drm_device *dev = overlay->dev;
+        drm_i915_private_t *dev_priv = dev->dev_private;
+	int ret;
+	u32 tmp;
+	RING_LOCALS;
+
+	if (overlay->last_flip_req != 0) {
+		ret = i915_do_wait_request(dev, overlay->last_flip_req, 1);
+		if (ret == 0) {
+			overlay->last_flip_req = 0;
+
+			tmp = I915_READ(ISR);
+
+			if (!(tmp & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT))
+				return 0;
+		}
+	}
+
+	/* synchronous slowpath */
+	overlay->hw_wedged = RELEASE_OLD_VID;
+
+	BEGIN_LP_RING(2);
+        OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+        OUT_RING(MI_NOOP);
+        ADVANCE_LP_RING();
+
+	overlay->last_flip_req = i915_add_request(dev, NULL, 0);
+	if (overlay->last_flip_req == 0)
+		return -ENOMEM;
+
+	ret = i915_do_wait_request(dev, overlay->last_flip_req, 1);
+	if (ret != 0)
+		return ret;
+
+	overlay->hw_wedged = 0;
+	overlay->last_flip_req = 0;
+	return 0;
+}
+
+/* overlay needs to be disabled in OCMD reg */
+static int intel_overlay_off(struct intel_overlay *overlay)
+{
+	u32 flip_addr = overlay->flip_addr;
+	struct drm_device *dev = overlay->dev;
+        drm_i915_private_t *dev_priv = dev->dev_private;
+	int ret;
+	RING_LOCALS;
+
+	BUG_ON(!overlay->active);
+
+	/* According to intel docs the overlay hw may hang (when switching
+	 * off) without loading the filter coeffs. It is however unclear whether
+	 * this applies to the disabling of the overlay or to the switching off
+	 * of the hw. Do it in both cases */
+	flip_addr |= OFC_UPDATE;
+
+	/* wait for overlay to go idle */
+	overlay->hw_wedged = SWITCH_OFF_STAGE_1;
+
+	BEGIN_LP_RING(6);
+	OUT_RING(MI_FLUSH);
+	OUT_RING(MI_NOOP);
+	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
+	OUT_RING(flip_addr);
+        OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+        OUT_RING(MI_NOOP);
+        ADVANCE_LP_RING();
+
+	overlay->last_flip_req = i915_add_request(dev, NULL, 0);
+	if (overlay->last_flip_req == 0)
+		return -ENOMEM;
+
+	ret = i915_do_wait_request(dev, overlay->last_flip_req, 1);
+	if (ret != 0)
+		return ret;
+
+	/* turn overlay off */
+	overlay->hw_wedged = SWITCH_OFF_STAGE_2;
+
+	BEGIN_LP_RING(6);
+        OUT_RING(MI_FLUSH);
+        OUT_RING(MI_NOOP);
+        OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
+	OUT_RING(flip_addr);
+        OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+        OUT_RING(MI_NOOP);
+	ADVANCE_LP_RING();
+
+	overlay->last_flip_req = i915_add_request(dev, NULL, 0);
+	if (overlay->last_flip_req == 0)
+		return -ENOMEM;
+
+	ret = i915_do_wait_request(dev, overlay->last_flip_req, 1);
+	if (ret != 0)
+		return ret;
+
+	overlay->hw_wedged = 0;
+	overlay->last_flip_req = 0;
+	return ret;
+}
+
+static void intel_overlay_off_tail(struct intel_overlay *overlay)
+{
+	struct drm_gem_object *obj;
+
+	/* never have the overlay hw on without showing a frame */
+	BUG_ON(!overlay->vid_bo);
+	obj = overlay->vid_bo->obj;
+
+	i915_gem_object_unpin(obj);
+	drm_gem_object_unreference(obj);
+	overlay->vid_bo = NULL;
+
+	overlay->crtc->overlay = NULL;
+	overlay->crtc = NULL;
+	overlay->active = 0;
+}
+
+/* recover from an interruption due to a signal
+ * We have to be careful not to repeat work forever an make forward progess. */
+int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
+					 int interruptible)
+{
+	struct drm_device *dev = overlay->dev;
+        drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_gem_object *obj;
+	u32 flip_addr;
+	int ret;
+	RING_LOCALS;
+
+	if (overlay->hw_wedged == HW_WEDGED)
+		return -EIO;
+
+	if (overlay->last_flip_req == 0) {
+		overlay->last_flip_req = i915_add_request(dev, NULL, 0);
+		if (overlay->last_flip_req == 0)
+			return -ENOMEM;
+	}
+
+	ret = i915_do_wait_request(dev, overlay->last_flip_req, interruptible);
+	if (ret != 0)
+		return ret;
+
+	switch (overlay->hw_wedged) {
+		case RELEASE_OLD_VID:
+			obj = overlay->old_vid_bo->obj;
+			i915_gem_object_unpin(obj);
+			drm_gem_object_unreference(obj);
+			overlay->old_vid_bo = NULL;
+			break;
+		case SWITCH_OFF_STAGE_1:
+			flip_addr = overlay->flip_addr;
+			flip_addr |= OFC_UPDATE;
+
+			overlay->hw_wedged = SWITCH_OFF_STAGE_2;
+
+			BEGIN_LP_RING(6);
+			OUT_RING(MI_FLUSH);
+			OUT_RING(MI_NOOP);
+			OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
+			OUT_RING(flip_addr);
+			OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+			OUT_RING(MI_NOOP);
+			ADVANCE_LP_RING();
+
+			overlay->last_flip_req = i915_add_request(dev, NULL, 0);
+			if (overlay->last_flip_req == 0)
+				return -ENOMEM;
+
+			ret = i915_do_wait_request(dev, overlay->last_flip_req,
+					interruptible);
+			if (ret != 0)
+				return ret;
+
+		case SWITCH_OFF_STAGE_2:
+			intel_overlay_off_tail(overlay);
+			break;
+		default:
+			BUG_ON(overlay->hw_wedged != NEEDS_WAIT_FOR_FLIP);
+	}
+
+	overlay->hw_wedged = 0;
+	overlay->last_flip_req = 0;
+	return 0;
+}
+
+/* Wait for pending overlay flip and release old frame.
+ * Needs to be called before the overlay register are changed
+ * via intel_overlay_(un)map_regs_atomic */
+static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
+{
+	int ret;
+	struct drm_gem_object *obj;
+
+	/* only wait if there is actually an old frame to release to
+	 * guarantee forward progress */
+	if (!overlay->old_vid_bo)
+		return 0;
+
+	ret = intel_overlay_wait_flip(overlay);
+	if (ret != 0)
+		return ret;
+
+	obj = overlay->old_vid_bo->obj;
+	i915_gem_object_unpin(obj);
+	drm_gem_object_unreference(obj);
+	overlay->old_vid_bo = NULL;
+
+	return 0;
+}
+
+struct put_image_params {
+	int format;
+	short dst_x;
+	short dst_y;
+	short dst_w;
+	short dst_h;
+	short src_w;
+	short src_scan_h;
+	short src_scan_w;
+	short src_h;
+	short stride_Y;
+	short stride_UV;
+	int offset_Y;
+	int offset_U;
+	int offset_V;
+};
+
+static int packed_depth_bytes(u32 format)
+{
+	switch (format & I915_OVERLAY_DEPTH_MASK) {
+		case I915_OVERLAY_YUV422:
+			return 4;
+		case I915_OVERLAY_YUV411:
+			/* return 6; not implemented */
+		default:
+			return -EINVAL;
+	}
+}
+
+static int packed_width_bytes(u32 format, short width)
+{
+	switch (format & I915_OVERLAY_DEPTH_MASK) {
+		case I915_OVERLAY_YUV422:
+			return width << 1;
+		default:
+			return -EINVAL;
+	}
+}
+
+static int uv_hsubsampling(u32 format)
+{
+	switch (format & I915_OVERLAY_DEPTH_MASK) {
+		case I915_OVERLAY_YUV422:
+		case I915_OVERLAY_YUV420:
+			return 2;
+		case I915_OVERLAY_YUV411:
+		case I915_OVERLAY_YUV410:
+			return 4;
+		default:
+			return -EINVAL;
+	}
+}
+
+static int uv_vsubsampling(u32 format)
+{
+	switch (format & I915_OVERLAY_DEPTH_MASK) {
+		case I915_OVERLAY_YUV420:
+		case I915_OVERLAY_YUV410:
+			return 2;
+		case I915_OVERLAY_YUV422:
+		case I915_OVERLAY_YUV411:
+			return 1;
+		default:
+			return -EINVAL;
+	}
+}
+
+static u32 calc_swidthsw(struct drm_device *dev, u32 offset, u32 width)
+{
+	u32 mask, shift, ret;
+	if (IS_I9XX(dev)) {
+		mask = 0x3f;
+		shift = 6;
+	} else {
+		mask = 0x1f;
+		shift = 5;
+	}
+	ret = ((offset + width + mask) >> shift) - (offset >> shift);
+	if (IS_I9XX(dev))
+		ret <<= 1;
+	ret -=1;
+	return ret << 2;
+}
+
+static const u16 y_static_hcoeffs[N_HORIZ_Y_TAPS * N_PHASES] = {
+	0x3000, 0xb4a0, 0x1930, 0x1920, 0xb4a0,
+	0x3000, 0xb500, 0x19d0, 0x1880, 0xb440,
+	0x3000, 0xb540, 0x1a88, 0x2f80, 0xb3e0,
+	0x3000, 0xb580, 0x1b30, 0x2e20, 0xb380,
+	0x3000, 0xb5c0, 0x1bd8, 0x2cc0, 0xb320,
+	0x3020, 0xb5e0, 0x1c60, 0x2b80, 0xb2c0,
+	0x3020, 0xb5e0, 0x1cf8, 0x2a20, 0xb260,
+	0x3020, 0xb5e0, 0x1d80, 0x28e0, 0xb200,
+	0x3020, 0xb5c0, 0x1e08, 0x3f40, 0xb1c0,
+	0x3020, 0xb580, 0x1e78, 0x3ce0, 0xb160,
+	0x3040, 0xb520, 0x1ed8, 0x3aa0, 0xb120,
+	0x3040, 0xb4a0, 0x1f30, 0x3880, 0xb0e0,
+	0x3040, 0xb400, 0x1f78, 0x3680, 0xb0a0,
+	0x3020, 0xb340, 0x1fb8, 0x34a0, 0xb060,
+	0x3020, 0xb240, 0x1fe0, 0x32e0, 0xb040,
+	0x3020, 0xb140, 0x1ff8, 0x3160, 0xb020,
+	0xb000, 0x3000, 0x0800, 0x3000, 0xb000};
+static const u16 uv_static_hcoeffs[N_HORIZ_UV_TAPS * N_PHASES] = {
+	0x3000, 0x1800, 0x1800, 0xb000, 0x18d0, 0x2e60,
+	0xb000, 0x1990, 0x2ce0, 0xb020, 0x1a68, 0x2b40,
+	0xb040, 0x1b20, 0x29e0, 0xb060, 0x1bd8, 0x2880,
+	0xb080, 0x1c88, 0x3e60, 0xb0a0, 0x1d28, 0x3c00,
+	0xb0c0, 0x1db8, 0x39e0, 0xb0e0, 0x1e40, 0x37e0,
+	0xb100, 0x1eb8, 0x3620, 0xb100, 0x1f18, 0x34a0,
+	0xb100, 0x1f68, 0x3360, 0xb0e0, 0x1fa8, 0x3240,
+	0xb0c0, 0x1fe0, 0x3140, 0xb060, 0x1ff0, 0x30a0,
+	0x3000, 0x0800, 0x3000};
+
+static void update_polyphase_filter(struct overlay_registers *regs)
+{
+	memcpy(regs->Y_HCOEFS, y_static_hcoeffs, sizeof(y_static_hcoeffs));
+	memcpy(regs->UV_HCOEFS, uv_static_hcoeffs, sizeof(uv_static_hcoeffs));
+}
+
+static bool update_scaling_factors(struct intel_overlay *overlay,
+				   struct overlay_registers *regs,
+				   struct put_image_params *params)
+{
+	/* fixed point with a 12 bit shift */
+	u32 xscale, yscale, xscale_UV, yscale_UV;
+#define FP_SHIFT 12
+#define FRACT_MASK 0xfff
+	bool scale_changed = false;
+	int uv_hscale = uv_hsubsampling(params->format);
+	int uv_vscale = uv_vsubsampling(params->format);
+
+	if (params->dst_w > 1)
+		xscale = ((params->src_scan_w - 1) << FP_SHIFT)
+			/(params->dst_w);
+	else
+		xscale = 1 << FP_SHIFT;
+
+	if (params->dst_h > 1)
+		yscale = ((params->src_scan_h - 1) << FP_SHIFT)
+			/(params->dst_h);
+	else
+		yscale = 1 << FP_SHIFT;
+
+	/*if (params->format & I915_OVERLAY_YUV_PLANAR) {*/
+		xscale_UV = xscale/uv_hscale;
+		yscale_UV = yscale/uv_vscale;
+		/* make the Y scale to UV scale ratio an exact multiply */
+		xscale = xscale_UV * uv_hscale;
+		yscale = yscale_UV * uv_vscale;
+	/*} else {
+		xscale_UV = 0;
+		yscale_UV = 0;
+	}*/
+
+	if (xscale != overlay->old_xscale || yscale != overlay->old_yscale)
+		scale_changed = true;
+	overlay->old_xscale = xscale;
+	overlay->old_yscale = yscale;
+
+	regs->YRGBSCALE = ((yscale & FRACT_MASK) << 20)
+		| ((xscale >> FP_SHIFT) << 16)
+		| ((xscale & FRACT_MASK) << 3);
+	regs->UVSCALE = ((yscale_UV & FRACT_MASK) << 20)
+		| ((xscale_UV >> FP_SHIFT) << 16)
+		| ((xscale_UV & FRACT_MASK) << 3);
+	regs->UVSCALEV = ((yscale >> FP_SHIFT) << 16)
+		| ((yscale_UV >> FP_SHIFT) << 0);
+
+	if (scale_changed)
+		update_polyphase_filter(regs);
+
+	return scale_changed;
+}
+
+static void update_colorkey(struct intel_overlay *overlay,
+			    struct overlay_registers *regs)
+{
+	u32 key = overlay->color_key;
+	switch (overlay->crtc->base.fb->bits_per_pixel) {
+		case 8:
+			regs->DCLRKV = 0;
+			regs->DCLRKM = CLK_RGB8I_MASK | DST_KEY_ENABLE;
+		case 16:
+			if (overlay->crtc->base.fb->depth == 15) {
+				regs->DCLRKV = RGB15_TO_COLORKEY(key);
+				regs->DCLRKM = CLK_RGB15_MASK | DST_KEY_ENABLE;
+			} else {
+				regs->DCLRKV = RGB16_TO_COLORKEY(key);
+				regs->DCLRKM = CLK_RGB16_MASK | DST_KEY_ENABLE;
+			}
+		case 24:
+		case 32:
+			regs->DCLRKV = key;
+			regs->DCLRKM = CLK_RGB24_MASK | DST_KEY_ENABLE;
+	}
+}
+
+static u32 overlay_cmd_reg(struct put_image_params *params)
+{
+	u32 cmd = OCMD_ENABLE | OCMD_BUF_TYPE_FRAME | OCMD_BUFFER0;
+
+	if (params->format & I915_OVERLAY_YUV_PLANAR) {
+		switch (params->format & I915_OVERLAY_DEPTH_MASK) {
+			case I915_OVERLAY_YUV422:
+				cmd |= OCMD_YUV_422_PLANAR;
+				break;
+			case I915_OVERLAY_YUV420:
+				cmd |= OCMD_YUV_420_PLANAR;
+				break;
+			case I915_OVERLAY_YUV411:
+			case I915_OVERLAY_YUV410:
+				cmd |= OCMD_YUV_410_PLANAR;
+				break;
+		}
+	} else { /* YUV packed */
+		switch (params->format & I915_OVERLAY_DEPTH_MASK) {
+			case I915_OVERLAY_YUV422:
+				cmd |= OCMD_YUV_422_PACKED;
+				break;
+			case I915_OVERLAY_YUV411:
+				cmd |= OCMD_YUV_411_PACKED;
+				break;
+		}
+
+		switch (params->format & I915_OVERLAY_SWAP_MASK) {
+			case I915_OVERLAY_NO_SWAP:
+				break;
+			case I915_OVERLAY_UV_SWAP:
+				cmd |= OCMD_UV_SWAP;
+				break;
+			case I915_OVERLAY_Y_SWAP:
+				cmd |= OCMD_Y_SWAP;
+				break;
+			case I915_OVERLAY_Y_AND_UV_SWAP:
+				cmd |= OCMD_Y_AND_UV_SWAP;
+				break;
+		}
+	}
+
+	return cmd;
+}
+
+int intel_overlay_do_put_image(struct intel_overlay *overlay,
+			       struct drm_gem_object *new_bo,
+			       struct put_image_params *params)
+{
+	int ret, tmp_width;
+	struct overlay_registers *regs;
+	bool scale_changed = false;
+	struct drm_i915_gem_object *bo_priv = new_bo->driver_private;
+	struct drm_device *dev = overlay->dev;
+
+	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
+	BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
+	BUG_ON(!overlay);
+
+	ret = intel_overlay_release_old_vid(overlay);
+	if (ret != 0)
+		return ret;
+
+	ret = i915_gem_object_pin(new_bo, PAGE_SIZE);
+	if (ret != 0)
+		return ret;
+
+	ret = i915_gem_object_set_to_gtt_domain(new_bo, 0);
+	if (ret != 0)
+		goto out_unpin;
+
+	if (!overlay->active) {
+		regs = intel_overlay_map_regs_atomic(overlay);
+		if (!regs) {
+			ret = -ENOMEM;
+			goto out_unpin;
+		}
+		regs->OCONFIG = OCONF_CC_OUT_8BIT;
+		if (IS_I965GM(overlay->dev))
+			regs->OCONFIG |= OCONF_CSC_MODE_BT709;
+		regs->OCONFIG |= overlay->crtc->pipe == 0 ?
+			OCONF_PIPE_A : OCONF_PIPE_B;
+		intel_overlay_unmap_regs_atomic(overlay);
+
+		ret = intel_overlay_on(overlay);
+		if (ret != 0)
+			goto out_unpin;
+	}
+
+	regs = intel_overlay_map_regs_atomic(overlay);
+	if (!regs) {
+		ret = -ENOMEM;
+		goto out_unpin;
+	}
+
+	regs->DWINPOS = (params->dst_y << 16) | params->dst_x;
+	regs->DWINSZ = (params->dst_h << 16) | params->dst_w;
+
+	if (params->format & I915_OVERLAY_YUV_PACKED)
+		tmp_width = packed_width_bytes(params->format, params->src_w);
+	else
+		tmp_width = params->src_w;
+
+	regs->SWIDTH = params->src_w;
+	regs->SWIDTHSW = calc_swidthsw(overlay->dev,
+			params->offset_Y, tmp_width);
+	regs->SHEIGHT = params->src_h;
+	regs->OBUF_0Y = bo_priv->gtt_offset + params-> offset_Y;
+	regs->OSTRIDE = params->stride_Y;
+
+	if (params->format & I915_OVERLAY_YUV_PLANAR) {
+		int uv_hscale = uv_hsubsampling(params->format);
+		int uv_vscale = uv_vsubsampling(params->format);
+		u32 tmp_U, tmp_V;
+		regs->SWIDTH |= (params->src_w/uv_hscale) << 16;
+		tmp_U = calc_swidthsw(overlay->dev, params->offset_U,
+				params->src_w/uv_hscale);
+		tmp_V = calc_swidthsw(overlay->dev, params->offset_V,
+				params->src_w/uv_hscale);
+		regs->SWIDTHSW |= max_t(u32, tmp_U, tmp_V) << 16;
+		regs->SHEIGHT |= (params->src_h/uv_vscale) << 16;
+		regs->OBUF_0U = bo_priv->gtt_offset + params->offset_U;
+		regs->OBUF_0V = bo_priv->gtt_offset + params->offset_V;
+		regs->OSTRIDE |= params->stride_UV << 16;
+	}
+
+	scale_changed = update_scaling_factors(overlay, regs, params);
+
+	update_colorkey(overlay, regs);
+
+	regs->OCMD = overlay_cmd_reg(params);
+
+	intel_overlay_unmap_regs_atomic(overlay);
+
+	intel_overlay_continue(overlay, scale_changed);
+
+	overlay->old_vid_bo = overlay->vid_bo;
+	overlay->vid_bo = new_bo->driver_private;
+
+	return 0;
+
+out_unpin:
+	i915_gem_object_unpin(new_bo);
+	return ret;
+}
+
+int intel_overlay_switch_off(struct intel_overlay *overlay)
+{
+	int ret;
+	struct overlay_registers *regs;
+	struct drm_device *dev = overlay->dev;
+
+	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
+	BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
+
+	if (overlay->hw_wedged) {
+		ret = intel_overlay_recover_from_interrupt(overlay, 1);
+		if (ret != 0)
+			return ret;
+	}
+
+	if (!overlay->active)
+		return 0;
+
+	ret = intel_overlay_release_old_vid(overlay);
+	if (ret != 0)
+		return ret;
+
+	regs = intel_overlay_map_regs_atomic(overlay);
+	regs->OCMD = 0;
+	intel_overlay_unmap_regs_atomic(overlay);
+
+	ret = intel_overlay_off(overlay);
+	if (ret != 0)
+		return ret;
+
+	intel_overlay_off_tail(overlay);
+
+	return 0;
+}
+
+static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
+					  struct intel_crtc *crtc)
+{
+        drm_i915_private_t *dev_priv = overlay->dev->dev_private;
+	u32 pipeconf;
+	int pipeconf_reg = (crtc->pipe == 0) ? PIPEACONF : PIPEBCONF;
+
+	if (!crtc->base.enabled || crtc->dpms_mode != DRM_MODE_DPMS_ON)
+		return -EINVAL;
+
+	pipeconf = I915_READ(pipeconf_reg);
+
+	/* can't use the overlay with double wide pipe */
+	if (!IS_I965G(overlay->dev) && pipeconf & PIPEACONF_DOUBLE_WIDE)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
+{
+	struct drm_device *dev = overlay->dev;
+        drm_i915_private_t *dev_priv = dev->dev_private;
+	u32 ratio;
+	u32 pfit_control = I915_READ(PFIT_CONTROL);
+
+	/* XXX: This is not the same logic as in the xorg driver, but more in
+	 * line with the intel documentation for the i965 */
+	if (!IS_I965G(dev) && (pfit_control & VERT_AUTO_SCALE)) {
+		ratio = I915_READ(PFIT_AUTO_RATIOS) >> PFIT_VERT_SCALE_SHIFT;
+	} else { /* on i965 use the PGM reg to read out the autoscaler values */
+		ratio = I915_READ(PFIT_PGM_RATIOS);
+		if (IS_I965G(dev))
+			ratio >>= PFIT_VERT_SCALE_SHIFT_965;
+		else
+			ratio >>= PFIT_VERT_SCALE_SHIFT;
+	}
+
+	overlay->pfit_vscale_ratio = ratio;
+}
+
+static int check_overlay_dst(struct intel_overlay *overlay,
+			     struct drm_intel_overlay_put_image *rec)
+{
+	struct drm_display_mode *mode = &overlay->crtc->base.mode;
+
+	if ((rec->dst_x < mode->crtc_hdisplay)
+	    && (rec->dst_x + rec->dst_width
+		    <= mode->crtc_hdisplay)
+	    && (rec->dst_y < mode->crtc_vdisplay)
+	    && (rec->dst_y + rec->dst_height
+		    <= mode->crtc_vdisplay))
+		return 0;
+	else
+		return -EINVAL;
+}
+
+static int check_overlay_scaling(struct put_image_params *rec)
+{
+	u32 tmp;
+
+	/* downscaling limit is 8.0 */
+	tmp = ((rec->src_scan_h << 16) / rec->dst_h) >> 16;
+	if (tmp > 7)
+		return -EINVAL;
+	tmp = ((rec->src_scan_w << 16) / rec->dst_w) >> 16;
+	if (tmp > 7)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int check_overlay_src(struct drm_device *dev,
+			     struct drm_intel_overlay_put_image *rec,
+			     struct drm_gem_object *new_bo)
+{
+	u32 stride_mask;
+	int depth;
+	int uv_hscale = uv_hsubsampling(rec->flags);
+	int uv_vscale = uv_vsubsampling(rec->flags);
+	size_t tmp;
+
+	/* check src dimensions */
+	if (IS_845G(dev) || IS_I830(dev)) {
+		if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY
+		    || rec->src_width > IMAGE_MAX_WIDTH_LEGACY)
+			return -EINVAL;
+	} else {
+		if (rec->src_height > IMAGE_MAX_HEIGHT
+		    || rec->src_width > IMAGE_MAX_WIDTH)
+			return -EINVAL;
+	}
+	/* better safe than sorry, use 4 as the maximal subsampling ratio */
+	if (rec->src_height < N_VERT_Y_TAPS*4
+	    || rec->src_width < N_HORIZ_Y_TAPS*4)
+		return -EINVAL;
+
+	/* check alingment constrains */
+	switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
+		case I915_OVERLAY_RGB:
+			/* not implemented */
+			return -EINVAL;
+		case I915_OVERLAY_YUV_PACKED:
+			depth = packed_depth_bytes(rec->flags);
+			if (uv_vscale != 1)
+				return -EINVAL;
+			if (depth < 0)
+				return depth;
+			/* ignore UV planes */
+			rec->stride_UV = 0;
+			rec->offset_U = 0;
+			rec->offset_V = 0;
+			/* check pixel alignment */
+			if (rec->offset_Y % depth)
+				return -EINVAL;
+			break;
+		case I915_OVERLAY_YUV_PLANAR:
+			if (uv_vscale < 0 || uv_hscale < 0)
+				return -EINVAL;
+			/* no offset restrictions for planar formats */
+			break;
+		default:
+			return -EINVAL;
+	}
+
+	if (rec->src_width % uv_hscale)
+		return -EINVAL;
+
+	/* stride checking */
+	stride_mask = 63;
+
+	if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask)
+		return -EINVAL;
+	if (IS_I965G(dev) && rec->stride_Y < 512)
+		return -EINVAL;
+
+	tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ?
+		4 : 8;
+	if (rec->stride_Y > tmp*1024 || rec->stride_UV > 2*1024)
+		return -EINVAL;
+
+	/* check buffer dimensions */
+	switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
+		case I915_OVERLAY_RGB:
+		case I915_OVERLAY_YUV_PACKED:
+			/* always 4 Y values per depth pixels */
+			if (packed_width_bytes(rec->flags, rec->src_width)
+					> rec->stride_Y)
+				return -EINVAL;
+
+			tmp = rec->stride_Y*rec->src_height;
+			if (rec->offset_Y + tmp > new_bo->size)
+				return -EINVAL;
+			break;
+		case I915_OVERLAY_YUV_PLANAR:
+			if (rec->src_width > rec->stride_Y)
+				return -EINVAL;
+			if (rec->src_width/uv_hscale > rec->stride_UV)
+				return -EINVAL;
+
+			tmp = rec->stride_Y*rec->src_height;
+			if (rec->offset_Y + tmp > new_bo->size)
+				return -EINVAL;
+			tmp = rec->stride_UV*rec->src_height;
+			tmp /= uv_vscale;
+			if (rec->offset_U + tmp > new_bo->size
+			    || rec->offset_V + tmp > new_bo->size)
+				return -EINVAL;
+			break;
+	}
+
+	return 0;
+}
+
+int intel_overlay_put_image(struct drm_device *dev, void *data,
+                            struct drm_file *file_priv)
+{
+	struct drm_intel_overlay_put_image *put_image_rec = data;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct intel_overlay *overlay;
+	struct drm_mode_object *drmmode_obj;
+	struct intel_crtc *crtc;
+	struct drm_gem_object *new_bo;
+	struct put_image_params *params;
+	int ret;
+
+	if (!dev_priv) {
+		DRM_ERROR("called with no initialization\n");
+		return -EINVAL;
+	}
+
+	overlay = dev_priv->overlay;
+	if (!overlay) {
+		DRM_DEBUG("userspace bug: no overlay\n");
+		return -ENODEV;
+	}
+
+	if (!(put_image_rec->flags & I915_OVERLAY_ENABLE)) {
+		mutex_lock(&dev->mode_config.mutex);
+		mutex_lock(&dev->struct_mutex);
+
+		ret = intel_overlay_switch_off(overlay);
+
+		mutex_unlock(&dev->struct_mutex);
+		mutex_unlock(&dev->mode_config.mutex);
+
+		return ret;
+	}
+
+	params = kmalloc(sizeof(struct put_image_params), GFP_KERNEL);
+	if (!params)
+		return -ENOMEM;
+
+	drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id,
+                        DRM_MODE_OBJECT_CRTC);
+	if (!drmmode_obj)
+		return -ENOENT;
+	crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));
+
+	new_bo = drm_gem_object_lookup(dev, file_priv,
+			put_image_rec->bo_handle);
+	if (!new_bo)
+		return -ENOENT;
+
+	mutex_lock(&dev->mode_config.mutex);
+	mutex_lock(&dev->struct_mutex);
+
+	if (overlay->hw_wedged) {
+		ret = intel_overlay_recover_from_interrupt(overlay, 1);
+		if (ret != 0)
+			goto out_unlock;
+	}
+
+	if (overlay->crtc != crtc) {
+		struct drm_display_mode *mode = &crtc->base.mode;
+		ret = intel_overlay_switch_off(overlay);
+		if (ret != 0)
+			goto out_unlock;
+
+		ret = check_overlay_possible_on_crtc(overlay, crtc);
+		if (ret != 0)
+			goto out_unlock;
+
+		overlay->crtc = crtc;
+		crtc->overlay = overlay;
+
+		if (intel_panel_fitter_pipe(dev) == crtc->pipe
+		    /* and line to wide, i.e. one-line-mode */
+		    && mode->hdisplay > 1024) {
+			overlay->pfit_active = 1;
+			update_pfit_vscale_ratio(overlay);
+		} else
+			overlay->pfit_active = 0;
+	}
+
+	ret = check_overlay_dst(overlay, put_image_rec);
+	if (ret != 0)
+		goto out_unlock;
+
+	if (overlay->pfit_active) {
+		params->dst_y = ((((u32)put_image_rec->dst_y) << 12) /
+			overlay->pfit_vscale_ratio);
+		/* shifting right rounds downwards, so add 1 */
+		params->dst_h = ((((u32)put_image_rec->dst_height) << 12) /
+			overlay->pfit_vscale_ratio) + 1;
+	} else {
+		params->dst_y = put_image_rec->dst_y;
+		params->dst_h = put_image_rec->dst_height;
+	}
+	params->dst_x = put_image_rec->dst_x;
+	params->dst_w = put_image_rec->dst_width;
+
+	params->src_w = put_image_rec->src_width;
+	params->src_h = put_image_rec->src_height;
+	params->src_scan_w = put_image_rec->src_scan_width;
+	params->src_scan_h = put_image_rec->src_scan_height;
+	if (params->src_scan_h > params->src_h
+	    || params->src_scan_w > params->src_w) {
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+	ret = check_overlay_src(dev, put_image_rec, new_bo);
+	if (ret != 0)
+		goto out_unlock;
+	params->format = put_image_rec->flags & ~I915_OVERLAY_FLAGS_MASK;
+	params->stride_Y = put_image_rec->stride_Y;
+	params->stride_UV = put_image_rec->stride_UV;
+	params->offset_Y = put_image_rec->offset_Y;
+	params->offset_U = put_image_rec->offset_U;
+	params->offset_V = put_image_rec->offset_V;
+
+	/* Check scaling after src size to prevent a divide-by-zero. */
+	ret = check_overlay_scaling(params);
+	if (ret != 0)
+		goto out_unlock;
+
+	ret = intel_overlay_do_put_image(overlay, new_bo, params);
+	if (ret != 0)
+		goto out_unlock;
+
+	mutex_unlock(&dev->struct_mutex);
+	mutex_unlock(&dev->mode_config.mutex);
+
+	kfree(params);
+
+	return 0;
+
+out_unlock:
+	mutex_unlock(&dev->struct_mutex);
+	mutex_unlock(&dev->mode_config.mutex);
+	drm_gem_object_unreference(new_bo);
+	kfree(params);
+
+	return ret;
+}
+
+static void update_reg_attrs(struct intel_overlay *overlay,
+			     struct overlay_registers *regs)
+{
+	regs->OCLRC0 = (overlay->contrast << 18) | (overlay->brightness & 0xff);
+	regs->OCLRC1 = overlay->saturation;
+}
+
+static bool check_gamma_bounds(u32 gamma1, u32 gamma2)
+{
+	int i;
+
+	if (gamma1 & 0xff000000 || gamma2 & 0xff000000)
+		return false;
+
+	for (i = 0; i < 3; i++) {
+		if (((gamma1 >> i * 8) & 0xff) >= ((gamma2 >> i*8) & 0xff))
+			return false;
+	}
+
+	return true;
+}
+
+static bool check_gamma5_errata(u32 gamma5)
+{
+	int i;
+
+	for (i = 0; i < 3; i++) {
+		if (((gamma5 >> i*8) & 0xff) == 0x80)
+			return false;
+	}
+
+	return true;
+}
+
+static int check_gamma(struct drm_intel_overlay_attrs *attrs)
+{
+	if (!check_gamma_bounds(0, attrs->gamma0)
+	    || !check_gamma_bounds(attrs->gamma0, attrs->gamma1)
+	    || !check_gamma_bounds(attrs->gamma1, attrs->gamma2)
+	    || !check_gamma_bounds(attrs->gamma2, attrs->gamma3)
+	    || !check_gamma_bounds(attrs->gamma3, attrs->gamma4)
+	    || !check_gamma_bounds(attrs->gamma4, attrs->gamma5)
+	    || !check_gamma_bounds(attrs->gamma5, 0x00ffffff))
+		return -EINVAL;
+	if (!check_gamma5_errata(attrs->gamma5))
+		return -EINVAL;
+	return 0;
+}
+
+int intel_overlay_attrs(struct drm_device *dev, void *data,
+                        struct drm_file *file_priv)
+{
+	struct drm_intel_overlay_attrs *attrs = data;
+        drm_i915_private_t *dev_priv = dev->dev_private;
+	struct intel_overlay *overlay;
+	struct overlay_registers *regs;
+	int ret;
+
+	if (!dev_priv) {
+		DRM_ERROR("called with no initialization\n");
+		return -EINVAL;
+	}
+
+	overlay = dev_priv->overlay;
+	if (!overlay) {
+		DRM_DEBUG("userspace bug: no overlay\n");
+		return -ENODEV;
+	}
+
+	mutex_lock(&dev->mode_config.mutex);
+	mutex_lock(&dev->struct_mutex);
+
+	if (!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS)) {
+		attrs->color_key = overlay->color_key;
+		attrs->brightness = overlay->brightness;
+		attrs->contrast = overlay->contrast;
+		attrs->saturation = overlay->saturation;
+
+		if (IS_I9XX(dev)) {
+			attrs->gamma0 = I915_READ(OGAMC0);
+			attrs->gamma1 = I915_READ(OGAMC1);
+			attrs->gamma2 = I915_READ(OGAMC2);
+			attrs->gamma3 = I915_READ(OGAMC3);
+			attrs->gamma4 = I915_READ(OGAMC4);
+			attrs->gamma5 = I915_READ(OGAMC5);
+		}
+		ret = 0;
+	} else {
+		overlay->color_key = attrs->color_key;
+		if (attrs->brightness >= -128 && attrs->brightness <= 127) {
+			overlay->brightness = attrs->brightness;
+		} else {
+			ret = -EINVAL;
+			goto out_unlock;
+		}
+		if (attrs->contrast <= 255) {
+			overlay->contrast = attrs->contrast;
+		} else {
+			ret = -EINVAL;
+			goto out_unlock;
+		}
+		if (attrs->saturation <= 1023) {
+			overlay->saturation = attrs->saturation;
+		} else {
+			ret = -EINVAL;
+			goto out_unlock;
+		}
+
+		regs = intel_overlay_map_regs_atomic(overlay);
+		if (!regs) {
+			ret = -ENOMEM;
+			goto out_unlock;
+		}
+
+		update_reg_attrs(overlay, regs);
+
+		intel_overlay_unmap_regs_atomic(overlay);
+
+		if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
+			if (!IS_I9XX(dev)) {
+				ret = -EINVAL;
+				goto out_unlock;
+			}
+
+			if (overlay->active) {
+				ret = -EBUSY;
+				goto out_unlock;
+			}
+
+			ret = check_gamma(attrs);
+			if (ret != 0)
+				goto out_unlock;
+
+			I915_WRITE(OGAMC0, attrs->gamma0);
+			I915_WRITE(OGAMC1, attrs->gamma1);
+			I915_WRITE(OGAMC2, attrs->gamma2);
+			I915_WRITE(OGAMC3, attrs->gamma3);
+			I915_WRITE(OGAMC4, attrs->gamma4);
+			I915_WRITE(OGAMC5, attrs->gamma5);
+		}
+		ret = 0;
+	}
+
+out_unlock:
+	mutex_unlock(&dev->struct_mutex);
+	mutex_unlock(&dev->mode_config.mutex);
+
+	return ret;
+}
+
+void intel_setup_overlay(struct drm_device *dev)
+{
+        drm_i915_private_t *dev_priv = dev->dev_private;
+	struct intel_overlay *overlay;
+	struct drm_gem_object *reg_bo;
+	struct overlay_registers *regs;
+	int ret;
+
+	if (!OVERLAY_EXISTS(dev))
+		return;
+
+	overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL);
+	if (!overlay)
+		return;
+	overlay->dev = dev;
+
+	reg_bo = drm_gem_object_alloc(dev, PAGE_SIZE);
+	if (!reg_bo)
+		goto out_free;
+	overlay->reg_bo = reg_bo->driver_private;
+
+	if (OVERLAY_NONPHYSICAL(dev)) {
+		ret = i915_gem_object_pin(reg_bo, PAGE_SIZE);
+		if (ret) {
+                        DRM_ERROR("failed to pin overlay register bo\n");
+                        goto out_free_bo;
+                }
+		overlay->flip_addr = overlay->reg_bo->gtt_offset;
+	} else {
+		ret = i915_gem_attach_phys_object(dev, reg_bo,
+				I915_GEM_PHYS_OVERLAY_REGS);
+                if (ret) {
+                        DRM_ERROR("failed to attach phys overlay regs\n");
+                        goto out_free_bo;
+                }
+		overlay->flip_addr = overlay->reg_bo->phys_obj->handle->busaddr;
+	}
+
+	/* init all values */
+	overlay->color_key = 0x0101fe;
+	overlay->brightness = -19;
+	overlay->contrast = 75;
+	overlay->saturation = 146;
+
+	regs = intel_overlay_map_regs_atomic(overlay);
+	if (!regs)
+		goto out_free_bo;
+
+	memset(regs, 0, sizeof(struct overlay_registers));
+	update_polyphase_filter(regs);
+
+	update_reg_attrs(overlay, regs);
+
+	intel_overlay_unmap_regs_atomic(overlay);
+
+	dev_priv->overlay = overlay;
+	DRM_INFO("initialized overlay support\n");
+	return;
+
+out_free_bo:
+	drm_gem_object_unreference(reg_bo);
+out_free:
+	kfree(overlay);
+	return;
+}
+
+void intel_cleanup_overlay(struct drm_device *dev)
+{
+        drm_i915_private_t *dev_priv = dev->dev_private;
+
+	if (dev_priv->overlay) {
+		/* The bo's should be free'd by the generic code already.
+		 * Furthermore modesetting teardown happens beforehand so the
+		 * hardware should be off already */
+		BUG_ON(dev_priv->overlay->active);
+
+		kfree(dev_priv->overlay);
+	}
+}
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 083bec2..24a3dc9 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -36,8 +36,6 @@
 #include "i915_drv.h"
 #include "intel_sdvo_regs.h"
 
-#undef SDVO_DEBUG
-
 static char *tv_format_names[] = {
 	"NTSC_M"   , "NTSC_J"  , "NTSC_443",
 	"PAL_B"    , "PAL_D"   , "PAL_G"   ,
@@ -356,7 +354,6 @@
 #define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
 #define SDVO_PRIV(output)   ((struct intel_sdvo_priv *) (output)->dev_priv)
 
-#ifdef SDVO_DEBUG
 static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd,
 				   void *args, int args_len)
 {
@@ -379,9 +376,6 @@
 		DRM_LOG_KMS("(%02X)", cmd);
 	DRM_LOG_KMS("\n");
 }
-#else
-#define intel_sdvo_debug_write(o, c, a, l)
-#endif
 
 static void intel_sdvo_write_cmd(struct intel_output *intel_output, u8 cmd,
 				 void *args, int args_len)
@@ -398,7 +392,6 @@
 	intel_sdvo_write_byte(intel_output, SDVO_I2C_OPCODE, cmd);
 }
 
-#ifdef SDVO_DEBUG
 static const char *cmd_status_names[] = {
 	"Power on",
 	"Success",
@@ -427,9 +420,6 @@
 		DRM_LOG_KMS("(??? %d)", status);
 	DRM_LOG_KMS("\n");
 }
-#else
-#define intel_sdvo_debug_response(o, r, l, s)
-#endif
 
 static u8 intel_sdvo_read_response(struct intel_output *intel_output,
 				   void *response, int response_len)
@@ -1627,6 +1617,10 @@
 
 	intel_sdvo_write_cmd(intel_output,
 			     SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
+	if (sdvo_priv->is_tv) {
+		/* add 30ms delay when the output type is SDVO-TV */
+		mdelay(30);
+	}
 	status = intel_sdvo_read_response(intel_output, &response, 2);
 
 	DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8);
@@ -2726,7 +2720,7 @@
 	/* Wrap with our custom algo which switches to DDC mode */
 	intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo;
 
-	/* In defaut case sdvo lvds is false */
+	/* In default case sdvo lvds is false */
 	intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps);
 
 	if (intel_sdvo_output_setup(intel_output,
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 9ca9179..552ec11 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1213,20 +1213,17 @@
 		tv_ctl |= TV_TRILEVEL_SYNC;
 	if (tv_mode->pal_burst)
 		tv_ctl |= TV_PAL_BURST;
-	scctl1 = 0;
-	/* dda1 implies valid video levels */
-	if (tv_mode->dda1_inc) {
-		scctl1 |= TV_SC_DDA1_EN;
-	}
 
+	scctl1 = 0;
+	if (tv_mode->dda1_inc)
+		scctl1 |= TV_SC_DDA1_EN;
 	if (tv_mode->dda2_inc)
 		scctl1 |= TV_SC_DDA2_EN;
-
 	if (tv_mode->dda3_inc)
 		scctl1 |= TV_SC_DDA3_EN;
-
 	scctl1 |= tv_mode->sc_reset;
-	scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
+	if (video_levels)
+		scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
 	scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
 
 	scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
@@ -1416,16 +1413,16 @@
 	 *  0 0 0 Component
 	 */
 	if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
-		DRM_DEBUG("Detected Composite TV connection\n");
+		DRM_DEBUG_KMS("Detected Composite TV connection\n");
 		type = DRM_MODE_CONNECTOR_Composite;
 	} else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
-		DRM_DEBUG("Detected S-Video TV connection\n");
+		DRM_DEBUG_KMS("Detected S-Video TV connection\n");
 		type = DRM_MODE_CONNECTOR_SVIDEO;
 	} else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
-		DRM_DEBUG("Detected Component TV connection\n");
+		DRM_DEBUG_KMS("Detected Component TV connection\n");
 		type = DRM_MODE_CONNECTOR_Component;
 	} else {
-		DRM_DEBUG("No TV connection detected\n");
+		DRM_DEBUG_KMS("No TV connection detected\n");
 		type = -1;
 	}
 
@@ -1702,6 +1699,41 @@
 	.destroy = intel_tv_enc_destroy,
 };
 
+/*
+ * Enumerate the child dev array parsed from VBT to check whether
+ * the integrated TV is present.
+ * If it is present, return 1.
+ * If it is not present, return false.
+ * If no child dev is parsed from VBT, it assumes that the TV is present.
+ */
+static int tv_is_present_in_vbt(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct child_device_config *p_child;
+	int i, ret;
+
+	if (!dev_priv->child_dev_num)
+		return 1;
+
+	ret = 0;
+	for (i = 0; i < dev_priv->child_dev_num; i++) {
+		p_child = dev_priv->child_dev + i;
+		/*
+		 * If the device type is not TV, continue.
+		 */
+		if (p_child->device_type != DEVICE_TYPE_INT_TV &&
+			p_child->device_type != DEVICE_TYPE_TV)
+			continue;
+		/* Only when the addin_offset is non-zero, it is regarded
+		 * as present.
+		 */
+		if (p_child->addin_offset) {
+			ret = 1;
+			break;
+		}
+	}
+	return ret;
+}
 
 void
 intel_tv_init(struct drm_device *dev)
@@ -1717,6 +1749,10 @@
 	if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
 		return;
 
+	if (!tv_is_present_in_vbt(dev)) {
+		DRM_DEBUG_KMS("Integrated TV is not present.\n");
+		return;
+	}
 	/* Even if we have an encoder we may not have a connector */
 	if (!dev_priv->int_tv_support)
 		return;
diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig
new file mode 100644
index 0000000..d823e63
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/Kconfig
@@ -0,0 +1,44 @@
+config DRM_NOUVEAU
+	tristate "Nouveau (nVidia) cards"
+	depends on DRM
+        select FW_LOADER
+	select DRM_KMS_HELPER
+	select DRM_TTM
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB
+	select FRAMEBUFFER_CONSOLE if !EMBEDDED
+	select FB_BACKLIGHT if DRM_NOUVEAU_BACKLIGHT
+	help
+	  Choose this option for open-source nVidia support.
+
+config DRM_NOUVEAU_BACKLIGHT
+	bool "Support for backlight control"
+	depends on DRM_NOUVEAU
+	default y
+	help
+	  Say Y here if you want to control the backlight of your display
+	  (e.g. a laptop panel).
+
+config DRM_NOUVEAU_DEBUG
+	bool "Build in Nouveau's debugfs support"
+	depends on DRM_NOUVEAU && DEBUG_FS
+	default y
+	help
+	  Say Y here if you want Nouveau to output debugging information
+	  via debugfs.
+
+menu "I2C encoder or helper chips"
+     depends on DRM
+
+config DRM_I2C_CH7006
+	tristate "Chrontel ch7006 TV encoder"
+	default m if DRM_NOUVEAU
+	help
+	  Support for Chrontel ch7006 and similar TV encoders, found
+	  on some nVidia video cards.
+
+	  This driver is currently only useful if you're also using
+	  the nouveau driver.
+endmenu
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
new file mode 100644
index 0000000..1d90d4d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/Makefile
@@ -0,0 +1,31 @@
+#
+# Makefile for the drm device driver.  This driver provides support for the
+# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
+
+ccflags-y := -Iinclude/drm
+nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
+             nouveau_object.o nouveau_irq.o nouveau_notifier.o \
+             nouveau_sgdma.o nouveau_dma.o \
+             nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \
+             nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \
+	     nouveau_display.o nouveau_connector.o nouveau_fbcon.o \
+	     nouveau_dp.o \
+             nv04_timer.o \
+             nv04_mc.o nv40_mc.o nv50_mc.o \
+             nv04_fb.o nv10_fb.o nv40_fb.o \
+             nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \
+             nv04_graph.o nv10_graph.o nv20_graph.o \
+             nv40_graph.o nv50_graph.o \
+             nv04_instmem.o nv50_instmem.o \
+             nv50_crtc.o nv50_dac.o nv50_sor.o \
+             nv50_cursor.o nv50_display.o nv50_fbcon.o \
+             nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \
+             nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \
+             nv17_gpio.o
+
+nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o
+nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
+nouveau-$(CONFIG_DRM_NOUVEAU_BACKLIGHT) += nouveau_backlight.o
+nouveau-$(CONFIG_ACPI) += nouveau_acpi.o
+
+obj-$(CONFIG_DRM_NOUVEAU)+= nouveau.o
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c
new file mode 100644
index 0000000..1cf4882
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -0,0 +1,125 @@
+#include <linux/pci.h>
+#include <linux/acpi.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/acpi_bus.h>
+
+#include "drmP.h"
+#include "drm.h"
+#include "drm_sarea.h"
+#include "drm_crtc_helper.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+#include "nv50_display.h"
+
+#define NOUVEAU_DSM_SUPPORTED 0x00
+#define NOUVEAU_DSM_SUPPORTED_FUNCTIONS 0x00
+
+#define NOUVEAU_DSM_ACTIVE 0x01
+#define NOUVEAU_DSM_ACTIVE_QUERY 0x00
+
+#define NOUVEAU_DSM_LED 0x02
+#define NOUVEAU_DSM_LED_STATE 0x00
+#define NOUVEAU_DSM_LED_OFF 0x10
+#define NOUVEAU_DSM_LED_STAMINA 0x11
+#define NOUVEAU_DSM_LED_SPEED 0x12
+
+#define NOUVEAU_DSM_POWER 0x03
+#define NOUVEAU_DSM_POWER_STATE 0x00
+#define NOUVEAU_DSM_POWER_SPEED 0x01
+#define NOUVEAU_DSM_POWER_STAMINA 0x02
+
+static int nouveau_dsm(struct drm_device *dev, int func, int arg, int *result)
+{
+	static char muid[] = {
+		0xA0, 0xA0, 0x95, 0x9D, 0x60, 0x00, 0x48, 0x4D,
+		0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4,
+	};
+
+	struct pci_dev *pdev = dev->pdev;
+	struct acpi_handle *handle;
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+	struct acpi_object_list input;
+	union acpi_object params[4];
+	union acpi_object *obj;
+	int err;
+
+	handle = DEVICE_ACPI_HANDLE(&pdev->dev);
+
+	if (!handle)
+		return -ENODEV;
+
+	input.count = 4;
+	input.pointer = params;
+	params[0].type = ACPI_TYPE_BUFFER;
+	params[0].buffer.length = sizeof(muid);
+	params[0].buffer.pointer = (char *)muid;
+	params[1].type = ACPI_TYPE_INTEGER;
+	params[1].integer.value = 0x00000102;
+	params[2].type = ACPI_TYPE_INTEGER;
+	params[2].integer.value = func;
+	params[3].type = ACPI_TYPE_INTEGER;
+	params[3].integer.value = arg;
+
+	err = acpi_evaluate_object(handle, "_DSM", &input, &output);
+	if (err) {
+		NV_INFO(dev, "failed to evaluate _DSM: %d\n", err);
+		return err;
+	}
+
+	obj = (union acpi_object *)output.pointer;
+
+	if (obj->type == ACPI_TYPE_INTEGER)
+		if (obj->integer.value == 0x80000002)
+			return -ENODEV;
+
+	if (obj->type == ACPI_TYPE_BUFFER) {
+		if (obj->buffer.length == 4 && result) {
+			*result = 0;
+			*result |= obj->buffer.pointer[0];
+			*result |= (obj->buffer.pointer[1] << 8);
+			*result |= (obj->buffer.pointer[2] << 16);
+			*result |= (obj->buffer.pointer[3] << 24);
+		}
+	}
+
+	kfree(output.pointer);
+	return 0;
+}
+
+int nouveau_hybrid_setup(struct drm_device *dev)
+{
+	int result;
+
+	if (nouveau_dsm(dev, NOUVEAU_DSM_ACTIVE, NOUVEAU_DSM_ACTIVE_QUERY,
+								&result))
+		return -ENODEV;
+
+	NV_INFO(dev, "_DSM hardware status gave 0x%x\n", result);
+
+	if (result & 0x1) {	/* Stamina mode - disable the external GPU */
+		nouveau_dsm(dev, NOUVEAU_DSM_LED, NOUVEAU_DSM_LED_STAMINA,
+									NULL);
+		nouveau_dsm(dev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_STAMINA,
+									NULL);
+	} else {		/* Ensure that the external GPU is enabled */
+		nouveau_dsm(dev, NOUVEAU_DSM_LED, NOUVEAU_DSM_LED_SPEED, NULL);
+		nouveau_dsm(dev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_SPEED,
+									NULL);
+	}
+
+	return 0;
+}
+
+bool nouveau_dsm_probe(struct drm_device *dev)
+{
+	int support = 0;
+
+	if (nouveau_dsm(dev, NOUVEAU_DSM_SUPPORTED,
+				NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &support))
+		return false;
+
+	if (!support)
+		return false;
+
+	return true;
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c
new file mode 100644
index 0000000..20564f8
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2009 Red Hat <mjg@redhat.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/*
+ * Authors:
+ *  Matthew Garrett <mjg@redhat.com>
+ *
+ * Register locations derived from NVClock by Roderick Colenbrander
+ */
+
+#include <linux/backlight.h>
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+#include "nouveau_reg.h"
+
+static int nv40_get_intensity(struct backlight_device *bd)
+{
+	struct drm_device *dev = bl_get_data(bd);
+	int val = (nv_rd32(dev, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK)
+									>> 16;
+
+	return val;
+}
+
+static int nv40_set_intensity(struct backlight_device *bd)
+{
+	struct drm_device *dev = bl_get_data(bd);
+	int val = bd->props.brightness;
+	int reg = nv_rd32(dev, NV40_PMC_BACKLIGHT);
+
+	nv_wr32(dev, NV40_PMC_BACKLIGHT,
+		 (val << 16) | (reg & ~NV40_PMC_BACKLIGHT_MASK));
+
+	return 0;
+}
+
+static struct backlight_ops nv40_bl_ops = {
+	.options = BL_CORE_SUSPENDRESUME,
+	.get_brightness = nv40_get_intensity,
+	.update_status = nv40_set_intensity,
+};
+
+static int nv50_get_intensity(struct backlight_device *bd)
+{
+	struct drm_device *dev = bl_get_data(bd);
+
+	return nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT);
+}
+
+static int nv50_set_intensity(struct backlight_device *bd)
+{
+	struct drm_device *dev = bl_get_data(bd);
+	int val = bd->props.brightness;
+
+	nv_wr32(dev, NV50_PDISPLAY_SOR_BACKLIGHT,
+		val | NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE);
+	return 0;
+}
+
+static struct backlight_ops nv50_bl_ops = {
+	.options = BL_CORE_SUSPENDRESUME,
+	.get_brightness = nv50_get_intensity,
+	.update_status = nv50_set_intensity,
+};
+
+static int nouveau_nv40_backlight_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct backlight_device *bd;
+
+	if (!(nv_rd32(dev, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK))
+		return 0;
+
+	bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev,
+				       &nv40_bl_ops);
+	if (IS_ERR(bd))
+		return PTR_ERR(bd);
+
+	dev_priv->backlight = bd;
+	bd->props.max_brightness = 31;
+	bd->props.brightness = nv40_get_intensity(bd);
+	backlight_update_status(bd);
+
+	return 0;
+}
+
+static int nouveau_nv50_backlight_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct backlight_device *bd;
+
+	if (!nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT))
+		return 0;
+
+	bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev,
+				       &nv50_bl_ops);
+	if (IS_ERR(bd))
+		return PTR_ERR(bd);
+
+	dev_priv->backlight = bd;
+	bd->props.max_brightness = 1025;
+	bd->props.brightness = nv50_get_intensity(bd);
+	backlight_update_status(bd);
+	return 0;
+}
+
+int nouveau_backlight_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	switch (dev_priv->card_type) {
+	case NV_40:
+		return nouveau_nv40_backlight_init(dev);
+	case NV_50:
+		return nouveau_nv50_backlight_init(dev);
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+void nouveau_backlight_exit(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->backlight) {
+		backlight_device_unregister(dev_priv->backlight);
+		dev_priv->backlight = NULL;
+	}
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
new file mode 100644
index 0000000..5eec5ed
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -0,0 +1,6095 @@
+/*
+ * Copyright 2005-2006 Erik Waling
+ * Copyright 2006 Stephane Marchesin
+ * Copyright 2007-2009 Stuart Bennett
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "drmP.h"
+#define NV_DEBUG_NOTRACE
+#include "nouveau_drv.h"
+#include "nouveau_hw.h"
+
+/* these defines are made up */
+#define NV_CIO_CRE_44_HEADA 0x0
+#define NV_CIO_CRE_44_HEADB 0x3
+#define FEATURE_MOBILE 0x10	/* also FEATURE_QUADRO for BMP */
+#define LEGACY_I2C_CRT 0x80
+#define LEGACY_I2C_PANEL 0x81
+#define LEGACY_I2C_TV 0x82
+
+#define EDID1_LEN 128
+
+#define BIOSLOG(sip, fmt, arg...) NV_DEBUG(sip->dev, fmt, ##arg)
+#define LOG_OLD_VALUE(x)
+
+#define ROM16(x) le16_to_cpu(*(uint16_t *)&(x))
+#define ROM32(x) le32_to_cpu(*(uint32_t *)&(x))
+
+struct init_exec {
+	bool execute;
+	bool repeat;
+};
+
+static bool nv_cksum(const uint8_t *data, unsigned int length)
+{
+	/*
+	 * There's a few checksums in the BIOS, so here's a generic checking
+	 * function.
+	 */
+	int i;
+	uint8_t sum = 0;
+
+	for (i = 0; i < length; i++)
+		sum += data[i];
+
+	if (sum)
+		return true;
+
+	return false;
+}
+
+static int
+score_vbios(struct drm_device *dev, const uint8_t *data, const bool writeable)
+{
+	if (!(data[0] == 0x55 && data[1] == 0xAA)) {
+		NV_TRACEWARN(dev, "... BIOS signature not found\n");
+		return 0;
+	}
+
+	if (nv_cksum(data, data[2] * 512)) {
+		NV_TRACEWARN(dev, "... BIOS checksum invalid\n");
+		/* if a ro image is somewhat bad, it's probably all rubbish */
+		return writeable ? 2 : 1;
+	} else
+		NV_TRACE(dev, "... appears to be valid\n");
+
+	return 3;
+}
+
+static void load_vbios_prom(struct drm_device *dev, uint8_t *data)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t pci_nv_20, save_pci_nv_20;
+	int pcir_ptr;
+	int i;
+
+	if (dev_priv->card_type >= NV_50)
+		pci_nv_20 = 0x88050;
+	else
+		pci_nv_20 = NV_PBUS_PCI_NV_20;
+
+	/* enable ROM access */
+	save_pci_nv_20 = nvReadMC(dev, pci_nv_20);
+	nvWriteMC(dev, pci_nv_20,
+		  save_pci_nv_20 & ~NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED);
+
+	/* bail if no rom signature */
+	if (nv_rd08(dev, NV_PROM_OFFSET) != 0x55 ||
+	    nv_rd08(dev, NV_PROM_OFFSET + 1) != 0xaa)
+		goto out;
+
+	/* additional check (see note below) - read PCI record header */
+	pcir_ptr = nv_rd08(dev, NV_PROM_OFFSET + 0x18) |
+		   nv_rd08(dev, NV_PROM_OFFSET + 0x19) << 8;
+	if (nv_rd08(dev, NV_PROM_OFFSET + pcir_ptr) != 'P' ||
+	    nv_rd08(dev, NV_PROM_OFFSET + pcir_ptr + 1) != 'C' ||
+	    nv_rd08(dev, NV_PROM_OFFSET + pcir_ptr + 2) != 'I' ||
+	    nv_rd08(dev, NV_PROM_OFFSET + pcir_ptr + 3) != 'R')
+		goto out;
+
+	/* on some 6600GT/6800LE prom reads are messed up.  nvclock alleges a
+	 * a good read may be obtained by waiting or re-reading (cargocult: 5x)
+	 * each byte.  we'll hope pramin has something usable instead
+	 */
+	for (i = 0; i < NV_PROM_SIZE; i++)
+		data[i] = nv_rd08(dev, NV_PROM_OFFSET + i);
+
+out:
+	/* disable ROM access */
+	nvWriteMC(dev, pci_nv_20,
+		  save_pci_nv_20 | NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED);
+}
+
+static void load_vbios_pramin(struct drm_device *dev, uint8_t *data)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t old_bar0_pramin = 0;
+	int i;
+
+	if (dev_priv->card_type >= NV_50) {
+		uint32_t vbios_vram = (nv_rd32(dev, 0x619f04) & ~0xff) << 8;
+
+		if (!vbios_vram)
+			vbios_vram = (nv_rd32(dev, 0x1700) << 16) + 0xf0000;
+
+		old_bar0_pramin = nv_rd32(dev, 0x1700);
+		nv_wr32(dev, 0x1700, vbios_vram >> 16);
+	}
+
+	/* bail if no rom signature */
+	if (nv_rd08(dev, NV_PRAMIN_OFFSET) != 0x55 ||
+	    nv_rd08(dev, NV_PRAMIN_OFFSET + 1) != 0xaa)
+		goto out;
+
+	for (i = 0; i < NV_PROM_SIZE; i++)
+		data[i] = nv_rd08(dev, NV_PRAMIN_OFFSET + i);
+
+out:
+	if (dev_priv->card_type >= NV_50)
+		nv_wr32(dev, 0x1700, old_bar0_pramin);
+}
+
+static void load_vbios_pci(struct drm_device *dev, uint8_t *data)
+{
+	void __iomem *rom = NULL;
+	size_t rom_len;
+	int ret;
+
+	ret = pci_enable_rom(dev->pdev);
+	if (ret)
+		return;
+
+	rom = pci_map_rom(dev->pdev, &rom_len);
+	if (!rom)
+		goto out;
+	memcpy_fromio(data, rom, rom_len);
+	pci_unmap_rom(dev->pdev, rom);
+
+out:
+	pci_disable_rom(dev->pdev);
+}
+
+struct methods {
+	const char desc[8];
+	void (*loadbios)(struct drm_device *, uint8_t *);
+	const bool rw;
+	int score;
+};
+
+static struct methods nv04_methods[] = {
+	{ "PROM", load_vbios_prom, false },
+	{ "PRAMIN", load_vbios_pramin, true },
+	{ "PCIROM", load_vbios_pci, true },
+	{ }
+};
+
+static struct methods nv50_methods[] = {
+	{ "PRAMIN", load_vbios_pramin, true },
+	{ "PROM", load_vbios_prom, false },
+	{ "PCIROM", load_vbios_pci, true },
+	{ }
+};
+
+static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct methods *methods, *method;
+	int testscore = 3;
+
+	if (nouveau_vbios) {
+		method = nv04_methods;
+		while (method->loadbios) {
+			if (!strcasecmp(nouveau_vbios, method->desc))
+				break;
+			method++;
+		}
+
+		if (method->loadbios) {
+			NV_INFO(dev, "Attempting to use BIOS image from %s\n",
+				method->desc);
+
+			method->loadbios(dev, data);
+			if (score_vbios(dev, data, method->rw))
+				return true;
+		}
+
+		NV_ERROR(dev, "VBIOS source \'%s\' invalid\n", nouveau_vbios);
+	}
+
+	if (dev_priv->card_type < NV_50)
+		methods = nv04_methods;
+	else
+		methods = nv50_methods;
+
+	method = methods;
+	while (method->loadbios) {
+		NV_TRACE(dev, "Attempting to load BIOS image from %s\n",
+			 method->desc);
+		data[0] = data[1] = 0;	/* avoid reuse of previous image */
+		method->loadbios(dev, data);
+		method->score = score_vbios(dev, data, method->rw);
+		if (method->score == testscore)
+			return true;
+		method++;
+	}
+
+	while (--testscore > 0) {
+		method = methods;
+		while (method->loadbios) {
+			if (method->score == testscore) {
+				NV_TRACE(dev, "Using BIOS image from %s\n",
+					 method->desc);
+				method->loadbios(dev, data);
+				return true;
+			}
+			method++;
+		}
+	}
+
+	NV_ERROR(dev, "No valid BIOS image found\n");
+	return false;
+}
+
+struct init_tbl_entry {
+	char *name;
+	uint8_t id;
+	int length;
+	int length_offset;
+	int length_multiplier;
+	bool (*handler)(struct nvbios *, uint16_t, struct init_exec *);
+};
+
+struct bit_entry {
+	uint8_t id[2];
+	uint16_t length;
+	uint16_t offset;
+};
+
+static int parse_init_table(struct nvbios *, unsigned int, struct init_exec *);
+
+#define MACRO_INDEX_SIZE	2
+#define MACRO_SIZE		8
+#define CONDITION_SIZE		12
+#define IO_FLAG_CONDITION_SIZE	9
+#define IO_CONDITION_SIZE	5
+#define MEM_INIT_SIZE		66
+
+static void still_alive(void)
+{
+#if 0
+	sync();
+	msleep(2);
+#endif
+}
+
+static uint32_t
+munge_reg(struct nvbios *bios, uint32_t reg)
+{
+	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
+	struct dcb_entry *dcbent = bios->display.output;
+
+	if (dev_priv->card_type < NV_50)
+		return reg;
+
+	if (reg & 0x40000000) {
+		BUG_ON(!dcbent);
+
+		reg += (ffs(dcbent->or) - 1) * 0x800;
+		if ((reg & 0x20000000) && !(dcbent->sorconf.link & 1))
+			reg += 0x00000080;
+	}
+
+	reg &= ~0x60000000;
+	return reg;
+}
+
+static int
+valid_reg(struct nvbios *bios, uint32_t reg)
+{
+	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
+	struct drm_device *dev = bios->dev;
+
+	/* C51 has misaligned regs on purpose. Marvellous */
+	if (reg & 0x2 || (reg & 0x1 && dev_priv->VBIOS.pub.chip_version != 0x51)) {
+		NV_ERROR(dev, "========== misaligned reg 0x%08X ==========\n",
+			 reg);
+		return 0;
+	}
+	/*
+	 * Warn on C51 regs that have not been verified accessible in
+	 * mmiotracing
+	 */
+	if (reg & 0x1 && dev_priv->VBIOS.pub.chip_version == 0x51 &&
+	    reg != 0x130d && reg != 0x1311 && reg != 0x60081d)
+		NV_WARN(dev, "=== C51 misaligned reg 0x%08X not verified ===\n",
+			reg);
+
+	/* Trust the init scripts on G80 */
+	if (dev_priv->card_type >= NV_50)
+		return 1;
+
+	#define WITHIN(x, y, z) ((x >= y) && (x < y + z))
+	if (WITHIN(reg, NV_PMC_OFFSET, NV_PMC_SIZE))
+		return 1;
+	if (WITHIN(reg, NV_PBUS_OFFSET, NV_PBUS_SIZE))
+		return 1;
+	if (WITHIN(reg, NV_PFIFO_OFFSET, NV_PFIFO_SIZE))
+		return 1;
+	if (dev_priv->VBIOS.pub.chip_version >= 0x30 &&
+	    (WITHIN(reg, 0x4000, 0x600) || reg == 0x00004600))
+		return 1;
+	if (dev_priv->VBIOS.pub.chip_version >= 0x40 &&
+						WITHIN(reg, 0xc000, 0x48))
+		return 1;
+	if (dev_priv->VBIOS.pub.chip_version >= 0x17 && reg == 0x0000d204)
+		return 1;
+	if (dev_priv->VBIOS.pub.chip_version >= 0x40) {
+		if (reg == 0x00011014 || reg == 0x00020328)
+			return 1;
+		if (WITHIN(reg, 0x88000, NV_PBUS_SIZE)) /* new PBUS */
+			return 1;
+	}
+	if (WITHIN(reg, NV_PFB_OFFSET, NV_PFB_SIZE))
+		return 1;
+	if (WITHIN(reg, NV_PEXTDEV_OFFSET, NV_PEXTDEV_SIZE))
+		return 1;
+	if (WITHIN(reg, NV_PCRTC0_OFFSET, NV_PCRTC0_SIZE * 2))
+		return 1;
+	if (WITHIN(reg, NV_PRAMDAC0_OFFSET, NV_PRAMDAC0_SIZE * 2))
+		return 1;
+	if (dev_priv->VBIOS.pub.chip_version >= 0x17 && reg == 0x0070fff0)
+		return 1;
+	if (dev_priv->VBIOS.pub.chip_version == 0x51 &&
+				WITHIN(reg, NV_PRAMIN_OFFSET, NV_PRAMIN_SIZE))
+		return 1;
+	#undef WITHIN
+
+	NV_ERROR(dev, "========== unknown reg 0x%08X ==========\n", reg);
+
+	return 0;
+}
+
+static bool
+valid_idx_port(struct nvbios *bios, uint16_t port)
+{
+	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
+	struct drm_device *dev = bios->dev;
+
+	/*
+	 * If adding more ports here, the read/write functions below will need
+	 * updating so that the correct mmio range (PRMCIO, PRMDIO, PRMVIO) is
+	 * used for the port in question
+	 */
+	if (dev_priv->card_type < NV_50) {
+		if (port == NV_CIO_CRX__COLOR)
+			return true;
+		if (port == NV_VIO_SRX)
+			return true;
+	} else {
+		if (port == NV_CIO_CRX__COLOR)
+			return true;
+	}
+
+	NV_ERROR(dev, "========== unknown indexed io port 0x%04X ==========\n",
+		 port);
+
+	return false;
+}
+
+static bool
+valid_port(struct nvbios *bios, uint16_t port)
+{
+	struct drm_device *dev = bios->dev;
+
+	/*
+	 * If adding more ports here, the read/write functions below will need
+	 * updating so that the correct mmio range (PRMCIO, PRMDIO, PRMVIO) is
+	 * used for the port in question
+	 */
+	if (port == NV_VIO_VSE2)
+		return true;
+
+	NV_ERROR(dev, "========== unknown io port 0x%04X ==========\n", port);
+
+	return false;
+}
+
+static uint32_t
+bios_rd32(struct nvbios *bios, uint32_t reg)
+{
+	uint32_t data;
+
+	reg = munge_reg(bios, reg);
+	if (!valid_reg(bios, reg))
+		return 0;
+
+	/*
+	 * C51 sometimes uses regs with bit0 set in the address. For these
+	 * cases there should exist a translation in a BIOS table to an IO
+	 * port address which the BIOS uses for accessing the reg
+	 *
+	 * These only seem to appear for the power control regs to a flat panel,
+	 * and the GPIO regs at 0x60081*.  In C51 mmio traces the normal regs
+	 * for 0x1308 and 0x1310 are used - hence the mask below.  An S3
+	 * suspend-resume mmio trace from a C51 will be required to see if this
+	 * is true for the power microcode in 0x14.., or whether the direct IO
+	 * port access method is needed
+	 */
+	if (reg & 0x1)
+		reg &= ~0x1;
+
+	data = nv_rd32(bios->dev, reg);
+
+	BIOSLOG(bios, "	Read:  Reg: 0x%08X, Data: 0x%08X\n", reg, data);
+
+	return data;
+}
+
+static void
+bios_wr32(struct nvbios *bios, uint32_t reg, uint32_t data)
+{
+	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
+
+	reg = munge_reg(bios, reg);
+	if (!valid_reg(bios, reg))
+		return;
+
+	/* see note in bios_rd32 */
+	if (reg & 0x1)
+		reg &= 0xfffffffe;
+
+	LOG_OLD_VALUE(bios_rd32(bios, reg));
+	BIOSLOG(bios, "	Write: Reg: 0x%08X, Data: 0x%08X\n", reg, data);
+
+	if (dev_priv->VBIOS.execute) {
+		still_alive();
+		nv_wr32(bios->dev, reg, data);
+	}
+}
+
+static uint8_t
+bios_idxprt_rd(struct nvbios *bios, uint16_t port, uint8_t index)
+{
+	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
+	struct drm_device *dev = bios->dev;
+	uint8_t data;
+
+	if (!valid_idx_port(bios, port))
+		return 0;
+
+	if (dev_priv->card_type < NV_50) {
+		if (port == NV_VIO_SRX)
+			data = NVReadVgaSeq(dev, bios->state.crtchead, index);
+		else	/* assume NV_CIO_CRX__COLOR */
+			data = NVReadVgaCrtc(dev, bios->state.crtchead, index);
+	} else {
+		uint32_t data32;
+
+		data32 = bios_rd32(bios, NV50_PDISPLAY_VGACRTC(index & ~3));
+		data = (data32 >> ((index & 3) << 3)) & 0xff;
+	}
+
+	BIOSLOG(bios, "	Indexed IO read:  Port: 0x%04X, Index: 0x%02X, "
+		      "Head: 0x%02X, Data: 0x%02X\n",
+		port, index, bios->state.crtchead, data);
+	return data;
+}
+
+static void
+bios_idxprt_wr(struct nvbios *bios, uint16_t port, uint8_t index, uint8_t data)
+{
+	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
+	struct drm_device *dev = bios->dev;
+
+	if (!valid_idx_port(bios, port))
+		return;
+
+	/*
+	 * The current head is maintained in the nvbios member  state.crtchead.
+	 * We trap changes to CR44 and update the head variable and hence the
+	 * register set written.
+	 * As CR44 only exists on CRTC0, we update crtchead to head0 in advance
+	 * of the write, and to head1 after the write
+	 */
+	if (port == NV_CIO_CRX__COLOR && index == NV_CIO_CRE_44 &&
+	    data != NV_CIO_CRE_44_HEADB)
+		bios->state.crtchead = 0;
+
+	LOG_OLD_VALUE(bios_idxprt_rd(bios, port, index));
+	BIOSLOG(bios, "	Indexed IO write: Port: 0x%04X, Index: 0x%02X, "
+		      "Head: 0x%02X, Data: 0x%02X\n",
+		port, index, bios->state.crtchead, data);
+
+	if (bios->execute && dev_priv->card_type < NV_50) {
+		still_alive();
+		if (port == NV_VIO_SRX)
+			NVWriteVgaSeq(dev, bios->state.crtchead, index, data);
+		else	/* assume NV_CIO_CRX__COLOR */
+			NVWriteVgaCrtc(dev, bios->state.crtchead, index, data);
+	} else
+	if (bios->execute) {
+		uint32_t data32, shift = (index & 3) << 3;
+
+		still_alive();
+
+		data32  = bios_rd32(bios, NV50_PDISPLAY_VGACRTC(index & ~3));
+		data32 &= ~(0xff << shift);
+		data32 |= (data << shift);
+		bios_wr32(bios, NV50_PDISPLAY_VGACRTC(index & ~3), data32);
+	}
+
+	if (port == NV_CIO_CRX__COLOR &&
+	    index == NV_CIO_CRE_44 && data == NV_CIO_CRE_44_HEADB)
+		bios->state.crtchead = 1;
+}
+
+static uint8_t
+bios_port_rd(struct nvbios *bios, uint16_t port)
+{
+	uint8_t data, head = bios->state.crtchead;
+
+	if (!valid_port(bios, port))
+		return 0;
+
+	data = NVReadPRMVIO(bios->dev, head, NV_PRMVIO0_OFFSET + port);
+
+	BIOSLOG(bios, "	IO read:  Port: 0x%04X, Head: 0x%02X, Data: 0x%02X\n",
+		port, head, data);
+
+	return data;
+}
+
+static void
+bios_port_wr(struct nvbios *bios, uint16_t port, uint8_t data)
+{
+	int head = bios->state.crtchead;
+
+	if (!valid_port(bios, port))
+		return;
+
+	LOG_OLD_VALUE(bios_port_rd(bios, port));
+	BIOSLOG(bios, "	IO write: Port: 0x%04X, Head: 0x%02X, Data: 0x%02X\n",
+		port, head, data);
+
+	if (!bios->execute)
+		return;
+
+	still_alive();
+	NVWritePRMVIO(bios->dev, head, NV_PRMVIO0_OFFSET + port, data);
+}
+
+static bool
+io_flag_condition_met(struct nvbios *bios, uint16_t offset, uint8_t cond)
+{
+	/*
+	 * The IO flag condition entry has 2 bytes for the CRTC port; 1 byte
+	 * for the CRTC index; 1 byte for the mask to apply to the value
+	 * retrieved from the CRTC; 1 byte for the shift right to apply to the
+	 * masked CRTC value; 2 bytes for the offset to the flag array, to
+	 * which the shifted value is added; 1 byte for the mask applied to the
+	 * value read from the flag array; and 1 byte for the value to compare
+	 * against the masked byte from the flag table.
+	 */
+
+	uint16_t condptr = bios->io_flag_condition_tbl_ptr + cond * IO_FLAG_CONDITION_SIZE;
+	uint16_t crtcport = ROM16(bios->data[condptr]);
+	uint8_t crtcindex = bios->data[condptr + 2];
+	uint8_t mask = bios->data[condptr + 3];
+	uint8_t shift = bios->data[condptr + 4];
+	uint16_t flagarray = ROM16(bios->data[condptr + 5]);
+	uint8_t flagarraymask = bios->data[condptr + 7];
+	uint8_t cmpval = bios->data[condptr + 8];
+	uint8_t data;
+
+	BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, "
+		      "Shift: 0x%02X, FlagArray: 0x%04X, FAMask: 0x%02X, "
+		      "Cmpval: 0x%02X\n",
+		offset, crtcport, crtcindex, mask, shift, flagarray, flagarraymask, cmpval);
+
+	data = bios_idxprt_rd(bios, crtcport, crtcindex);
+
+	data = bios->data[flagarray + ((data & mask) >> shift)];
+	data &= flagarraymask;
+
+	BIOSLOG(bios, "0x%04X: Checking if 0x%02X equals 0x%02X\n",
+		offset, data, cmpval);
+
+	return (data == cmpval);
+}
+
+static bool
+bios_condition_met(struct nvbios *bios, uint16_t offset, uint8_t cond)
+{
+	/*
+	 * The condition table entry has 4 bytes for the address of the
+	 * register to check, 4 bytes for a mask to apply to the register and
+	 * 4 for a test comparison value
+	 */
+
+	uint16_t condptr = bios->condition_tbl_ptr + cond * CONDITION_SIZE;
+	uint32_t reg = ROM32(bios->data[condptr]);
+	uint32_t mask = ROM32(bios->data[condptr + 4]);
+	uint32_t cmpval = ROM32(bios->data[condptr + 8]);
+	uint32_t data;
+
+	BIOSLOG(bios, "0x%04X: Cond: 0x%02X, Reg: 0x%08X, Mask: 0x%08X\n",
+		offset, cond, reg, mask);
+
+	data = bios_rd32(bios, reg) & mask;
+
+	BIOSLOG(bios, "0x%04X: Checking if 0x%08X equals 0x%08X\n",
+		offset, data, cmpval);
+
+	return (data == cmpval);
+}
+
+static bool
+io_condition_met(struct nvbios *bios, uint16_t offset, uint8_t cond)
+{
+	/*
+	 * The IO condition entry has 2 bytes for the IO port address; 1 byte
+	 * for the index to write to io_port; 1 byte for the mask to apply to
+	 * the byte read from io_port+1; and 1 byte for the value to compare
+	 * against the masked byte.
+	 */
+
+	uint16_t condptr = bios->io_condition_tbl_ptr + cond * IO_CONDITION_SIZE;
+	uint16_t io_port = ROM16(bios->data[condptr]);
+	uint8_t port_index = bios->data[condptr + 2];
+	uint8_t mask = bios->data[condptr + 3];
+	uint8_t cmpval = bios->data[condptr + 4];
+
+	uint8_t data = bios_idxprt_rd(bios, io_port, port_index) & mask;
+
+	BIOSLOG(bios, "0x%04X: Checking if 0x%02X equals 0x%02X\n",
+		offset, data, cmpval);
+
+	return (data == cmpval);
+}
+
+static int
+nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t reg0 = nv_rd32(dev, reg + 0);
+	uint32_t reg1 = nv_rd32(dev, reg + 4);
+	struct nouveau_pll_vals pll;
+	struct pll_lims pll_limits;
+	int ret;
+
+	ret = get_pll_limits(dev, reg, &pll_limits);
+	if (ret)
+		return ret;
+
+	clk = nouveau_calc_pll_mnp(dev, &pll_limits, clk, &pll);
+	if (!clk)
+		return -ERANGE;
+
+	reg0 = (reg0 & 0xfff8ffff) | (pll.log2P << 16);
+	reg1 = (reg1 & 0xffff0000) | (pll.N1 << 8) | pll.M1;
+
+	if (dev_priv->VBIOS.execute) {
+		still_alive();
+		nv_wr32(dev, reg + 4, reg1);
+		nv_wr32(dev, reg + 0, reg0);
+	}
+
+	return 0;
+}
+
+static int
+setPLL(struct nvbios *bios, uint32_t reg, uint32_t clk)
+{
+	struct drm_device *dev = bios->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	/* clk in kHz */
+	struct pll_lims pll_lim;
+	struct nouveau_pll_vals pllvals;
+	int ret;
+
+	if (dev_priv->card_type >= NV_50)
+		return nv50_pll_set(dev, reg, clk);
+
+	/* high regs (such as in the mac g5 table) are not -= 4 */
+	ret = get_pll_limits(dev, reg > 0x405c ? reg : reg - 4, &pll_lim);
+	if (ret)
+		return ret;
+
+	clk = nouveau_calc_pll_mnp(dev, &pll_lim, clk, &pllvals);
+	if (!clk)
+		return -ERANGE;
+
+	if (bios->execute) {
+		still_alive();
+		nouveau_hw_setpll(dev, reg, &pllvals);
+	}
+
+	return 0;
+}
+
+static int dcb_entry_idx_from_crtchead(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+
+	/*
+	 * For the results of this function to be correct, CR44 must have been
+	 * set (using bios_idxprt_wr to set crtchead), CR58 set for CR57 = 0,
+	 * and the DCB table parsed, before the script calling the function is
+	 * run.  run_digital_op_script is example of how to do such setup
+	 */
+
+	uint8_t dcb_entry = NVReadVgaCrtc5758(dev, bios->state.crtchead, 0);
+
+	if (dcb_entry > bios->bdcb.dcb.entries) {
+		NV_ERROR(dev, "CR58 doesn't have a valid DCB entry currently "
+				"(%02X)\n", dcb_entry);
+		dcb_entry = 0x7f;	/* unused / invalid marker */
+	}
+
+	return dcb_entry;
+}
+
+static struct nouveau_i2c_chan *
+init_i2c_device_find(struct drm_device *dev, int i2c_index)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct bios_parsed_dcb *bdcb = &dev_priv->VBIOS.bdcb;
+
+	if (i2c_index == 0xff) {
+		/* note: dcb_entry_idx_from_crtchead needs pre-script set-up */
+		int idx = dcb_entry_idx_from_crtchead(dev), shift = 0;
+		int default_indices = bdcb->i2c_default_indices;
+
+		if (idx != 0x7f && bdcb->dcb.entry[idx].i2c_upper_default)
+			shift = 4;
+
+		i2c_index = (default_indices >> shift) & 0xf;
+	}
+	if (i2c_index == 0x80)	/* g80+ */
+		i2c_index = bdcb->i2c_default_indices & 0xf;
+
+	return nouveau_i2c_find(dev, i2c_index);
+}
+
+static uint32_t get_tmds_index_reg(struct drm_device *dev, uint8_t mlv)
+{
+	/*
+	 * For mlv < 0x80, it is an index into a table of TMDS base addresses.
+	 * For mlv == 0x80 use the "or" value of the dcb_entry indexed by
+	 * CR58 for CR57 = 0 to index a table of offsets to the basic
+	 * 0x6808b0 address.
+	 * For mlv == 0x81 use the "or" value of the dcb_entry indexed by
+	 * CR58 for CR57 = 0 to index a table of offsets to the basic
+	 * 0x6808b0 address, and then flip the offset by 8.
+	 */
+
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	const int pramdac_offset[13] = {
+		0, 0, 0x8, 0, 0x2000, 0, 0, 0, 0x2008, 0, 0, 0, 0x2000 };
+	const uint32_t pramdac_table[4] = {
+		0x6808b0, 0x6808b8, 0x6828b0, 0x6828b8 };
+
+	if (mlv >= 0x80) {
+		int dcb_entry, dacoffset;
+
+		/* note: dcb_entry_idx_from_crtchead needs pre-script set-up */
+		dcb_entry = dcb_entry_idx_from_crtchead(dev);
+		if (dcb_entry == 0x7f)
+			return 0;
+		dacoffset = pramdac_offset[
+				dev_priv->VBIOS.bdcb.dcb.entry[dcb_entry].or];
+		if (mlv == 0x81)
+			dacoffset ^= 8;
+		return 0x6808b0 + dacoffset;
+	} else {
+		if (mlv > ARRAY_SIZE(pramdac_table)) {
+			NV_ERROR(dev, "Magic Lookup Value too big (%02X)\n",
+									mlv);
+			return 0;
+		}
+		return pramdac_table[mlv];
+	}
+}
+
+static bool
+init_io_restrict_prog(struct nvbios *bios, uint16_t offset,
+		      struct init_exec *iexec)
+{
+	/*
+	 * INIT_IO_RESTRICT_PROG   opcode: 0x32 ('2')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (16 bit): CRTC port
+	 * offset + 3  (8  bit): CRTC index
+	 * offset + 4  (8  bit): mask
+	 * offset + 5  (8  bit): shift
+	 * offset + 6  (8  bit): count
+	 * offset + 7  (32 bit): register
+	 * offset + 11 (32 bit): configuration 1
+	 * ...
+	 *
+	 * Starting at offset + 11 there are "count" 32 bit values.
+	 * To find out which value to use read index "CRTC index" on "CRTC
+	 * port", AND this value with "mask" and then bit shift right "shift"
+	 * bits.  Read the appropriate value using this index and write to
+	 * "register"
+	 */
+
+	uint16_t crtcport = ROM16(bios->data[offset + 1]);
+	uint8_t crtcindex = bios->data[offset + 3];
+	uint8_t mask = bios->data[offset + 4];
+	uint8_t shift = bios->data[offset + 5];
+	uint8_t count = bios->data[offset + 6];
+	uint32_t reg = ROM32(bios->data[offset + 7]);
+	uint8_t config;
+	uint32_t configval;
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, "
+		      "Shift: 0x%02X, Count: 0x%02X, Reg: 0x%08X\n",
+		offset, crtcport, crtcindex, mask, shift, count, reg);
+
+	config = (bios_idxprt_rd(bios, crtcport, crtcindex) & mask) >> shift;
+	if (config > count) {
+		NV_ERROR(bios->dev,
+			 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
+			 offset, config, count);
+		return false;
+	}
+
+	configval = ROM32(bios->data[offset + 11 + config * 4]);
+
+	BIOSLOG(bios, "0x%04X: Writing config %02X\n", offset, config);
+
+	bios_wr32(bios, reg, configval);
+
+	return true;
+}
+
+static bool
+init_repeat(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_REPEAT   opcode: 0x33 ('3')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): count
+	 *
+	 * Execute script following this opcode up to INIT_REPEAT_END
+	 * "count" times
+	 */
+
+	uint8_t count = bios->data[offset + 1];
+	uint8_t i;
+
+	/* no iexec->execute check by design */
+
+	BIOSLOG(bios, "0x%04X: Repeating following segment %d times\n",
+		offset, count);
+
+	iexec->repeat = true;
+
+	/*
+	 * count - 1, as the script block will execute once when we leave this
+	 * opcode -- this is compatible with bios behaviour as:
+	 * a) the block is always executed at least once, even if count == 0
+	 * b) the bios interpreter skips to the op following INIT_END_REPEAT,
+	 * while we don't
+	 */
+	for (i = 0; i < count - 1; i++)
+		parse_init_table(bios, offset + 2, iexec);
+
+	iexec->repeat = false;
+
+	return true;
+}
+
+static bool
+init_io_restrict_pll(struct nvbios *bios, uint16_t offset,
+		     struct init_exec *iexec)
+{
+	/*
+	 * INIT_IO_RESTRICT_PLL   opcode: 0x34 ('4')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (16 bit): CRTC port
+	 * offset + 3  (8  bit): CRTC index
+	 * offset + 4  (8  bit): mask
+	 * offset + 5  (8  bit): shift
+	 * offset + 6  (8  bit): IO flag condition index
+	 * offset + 7  (8  bit): count
+	 * offset + 8  (32 bit): register
+	 * offset + 12 (16 bit): frequency 1
+	 * ...
+	 *
+	 * Starting at offset + 12 there are "count" 16 bit frequencies (10kHz).
+	 * Set PLL register "register" to coefficients for frequency n,
+	 * selected by reading index "CRTC index" of "CRTC port" ANDed with
+	 * "mask" and shifted right by "shift".
+	 *
+	 * If "IO flag condition index" > 0, and condition met, double
+	 * frequency before setting it.
+	 */
+
+	uint16_t crtcport = ROM16(bios->data[offset + 1]);
+	uint8_t crtcindex = bios->data[offset + 3];
+	uint8_t mask = bios->data[offset + 4];
+	uint8_t shift = bios->data[offset + 5];
+	int8_t io_flag_condition_idx = bios->data[offset + 6];
+	uint8_t count = bios->data[offset + 7];
+	uint32_t reg = ROM32(bios->data[offset + 8]);
+	uint8_t config;
+	uint16_t freq;
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, "
+		      "Shift: 0x%02X, IO Flag Condition: 0x%02X, "
+		      "Count: 0x%02X, Reg: 0x%08X\n",
+		offset, crtcport, crtcindex, mask, shift,
+		io_flag_condition_idx, count, reg);
+
+	config = (bios_idxprt_rd(bios, crtcport, crtcindex) & mask) >> shift;
+	if (config > count) {
+		NV_ERROR(bios->dev,
+			 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
+			 offset, config, count);
+		return false;
+	}
+
+	freq = ROM16(bios->data[offset + 12 + config * 2]);
+
+	if (io_flag_condition_idx > 0) {
+		if (io_flag_condition_met(bios, offset, io_flag_condition_idx)) {
+			BIOSLOG(bios, "0x%04X: Condition fulfilled -- "
+				      "frequency doubled\n", offset);
+			freq *= 2;
+		} else
+			BIOSLOG(bios, "0x%04X: Condition not fulfilled -- "
+				      "frequency unchanged\n", offset);
+	}
+
+	BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Config: 0x%02X, Freq: %d0kHz\n",
+		offset, reg, config, freq);
+
+	setPLL(bios, reg, freq * 10);
+
+	return true;
+}
+
+static bool
+init_end_repeat(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_END_REPEAT   opcode: 0x36 ('6')
+	 *
+	 * offset      (8 bit): opcode
+	 *
+	 * Marks the end of the block for INIT_REPEAT to repeat
+	 */
+
+	/* no iexec->execute check by design */
+
+	/*
+	 * iexec->repeat flag necessary to go past INIT_END_REPEAT opcode when
+	 * we're not in repeat mode
+	 */
+	if (iexec->repeat)
+		return false;
+
+	return true;
+}
+
+static bool
+init_copy(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_COPY   opcode: 0x37 ('7')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): register
+	 * offset + 5  (8  bit): shift
+	 * offset + 6  (8  bit): srcmask
+	 * offset + 7  (16 bit): CRTC port
+	 * offset + 9  (8 bit): CRTC index
+	 * offset + 10  (8 bit): mask
+	 *
+	 * Read index "CRTC index" on "CRTC port", AND with "mask", OR with
+	 * (REGVAL("register") >> "shift" & "srcmask") and write-back to CRTC
+	 * port
+	 */
+
+	uint32_t reg = ROM32(bios->data[offset + 1]);
+	uint8_t shift = bios->data[offset + 5];
+	uint8_t srcmask = bios->data[offset + 6];
+	uint16_t crtcport = ROM16(bios->data[offset + 7]);
+	uint8_t crtcindex = bios->data[offset + 9];
+	uint8_t mask = bios->data[offset + 10];
+	uint32_t data;
+	uint8_t crtcdata;
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Shift: 0x%02X, SrcMask: 0x%02X, "
+		      "Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X\n",
+		offset, reg, shift, srcmask, crtcport, crtcindex, mask);
+
+	data = bios_rd32(bios, reg);
+
+	if (shift < 0x80)
+		data >>= shift;
+	else
+		data <<= (0x100 - shift);
+
+	data &= srcmask;
+
+	crtcdata  = bios_idxprt_rd(bios, crtcport, crtcindex) & mask;
+	crtcdata |= (uint8_t)data;
+	bios_idxprt_wr(bios, crtcport, crtcindex, crtcdata);
+
+	return true;
+}
+
+static bool
+init_not(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_NOT   opcode: 0x38 ('8')
+	 *
+	 * offset      (8  bit): opcode
+	 *
+	 * Invert the current execute / no-execute condition (i.e. "else")
+	 */
+	if (iexec->execute)
+		BIOSLOG(bios, "0x%04X: ------ Skipping following commands  ------\n", offset);
+	else
+		BIOSLOG(bios, "0x%04X: ------ Executing following commands ------\n", offset);
+
+	iexec->execute = !iexec->execute;
+	return true;
+}
+
+static bool
+init_io_flag_condition(struct nvbios *bios, uint16_t offset,
+		       struct init_exec *iexec)
+{
+	/*
+	 * INIT_IO_FLAG_CONDITION   opcode: 0x39 ('9')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): condition number
+	 *
+	 * Check condition "condition number" in the IO flag condition table.
+	 * If condition not met skip subsequent opcodes until condition is
+	 * inverted (INIT_NOT), or we hit INIT_RESUME
+	 */
+
+	uint8_t cond = bios->data[offset + 1];
+
+	if (!iexec->execute)
+		return true;
+
+	if (io_flag_condition_met(bios, offset, cond))
+		BIOSLOG(bios, "0x%04X: Condition fulfilled -- continuing to execute\n", offset);
+	else {
+		BIOSLOG(bios, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset);
+		iexec->execute = false;
+	}
+
+	return true;
+}
+
+static bool
+init_idx_addr_latched(struct nvbios *bios, uint16_t offset,
+		      struct init_exec *iexec)
+{
+	/*
+	 * INIT_INDEX_ADDRESS_LATCHED   opcode: 0x49 ('I')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): control register
+	 * offset + 5  (32 bit): data register
+	 * offset + 9  (32 bit): mask
+	 * offset + 13 (32 bit): data
+	 * offset + 17 (8  bit): count
+	 * offset + 18 (8  bit): address 1
+	 * offset + 19 (8  bit): data 1
+	 * ...
+	 *
+	 * For each of "count" address and data pairs, write "data n" to
+	 * "data register", read the current value of "control register",
+	 * and write it back once ANDed with "mask", ORed with "data",
+	 * and ORed with "address n"
+	 */
+
+	uint32_t controlreg = ROM32(bios->data[offset + 1]);
+	uint32_t datareg = ROM32(bios->data[offset + 5]);
+	uint32_t mask = ROM32(bios->data[offset + 9]);
+	uint32_t data = ROM32(bios->data[offset + 13]);
+	uint8_t count = bios->data[offset + 17];
+	uint32_t value;
+	int i;
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: ControlReg: 0x%08X, DataReg: 0x%08X, "
+		      "Mask: 0x%08X, Data: 0x%08X, Count: 0x%02X\n",
+		offset, controlreg, datareg, mask, data, count);
+
+	for (i = 0; i < count; i++) {
+		uint8_t instaddress = bios->data[offset + 18 + i * 2];
+		uint8_t instdata = bios->data[offset + 19 + i * 2];
+
+		BIOSLOG(bios, "0x%04X: Address: 0x%02X, Data: 0x%02X\n",
+			offset, instaddress, instdata);
+
+		bios_wr32(bios, datareg, instdata);
+		value  = bios_rd32(bios, controlreg) & mask;
+		value |= data;
+		value |= instaddress;
+		bios_wr32(bios, controlreg, value);
+	}
+
+	return true;
+}
+
+static bool
+init_io_restrict_pll2(struct nvbios *bios, uint16_t offset,
+		      struct init_exec *iexec)
+{
+	/*
+	 * INIT_IO_RESTRICT_PLL2   opcode: 0x4A ('J')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (16 bit): CRTC port
+	 * offset + 3  (8  bit): CRTC index
+	 * offset + 4  (8  bit): mask
+	 * offset + 5  (8  bit): shift
+	 * offset + 6  (8  bit): count
+	 * offset + 7  (32 bit): register
+	 * offset + 11 (32 bit): frequency 1
+	 * ...
+	 *
+	 * Starting at offset + 11 there are "count" 32 bit frequencies (kHz).
+	 * Set PLL register "register" to coefficients for frequency n,
+	 * selected by reading index "CRTC index" of "CRTC port" ANDed with
+	 * "mask" and shifted right by "shift".
+	 */
+
+	uint16_t crtcport = ROM16(bios->data[offset + 1]);
+	uint8_t crtcindex = bios->data[offset + 3];
+	uint8_t mask = bios->data[offset + 4];
+	uint8_t shift = bios->data[offset + 5];
+	uint8_t count = bios->data[offset + 6];
+	uint32_t reg = ROM32(bios->data[offset + 7]);
+	uint8_t config;
+	uint32_t freq;
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, "
+		      "Shift: 0x%02X, Count: 0x%02X, Reg: 0x%08X\n",
+		offset, crtcport, crtcindex, mask, shift, count, reg);
+
+	if (!reg)
+		return true;
+
+	config = (bios_idxprt_rd(bios, crtcport, crtcindex) & mask) >> shift;
+	if (config > count) {
+		NV_ERROR(bios->dev,
+			 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
+			 offset, config, count);
+		return false;
+	}
+
+	freq = ROM32(bios->data[offset + 11 + config * 4]);
+
+	BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Config: 0x%02X, Freq: %dkHz\n",
+		offset, reg, config, freq);
+
+	setPLL(bios, reg, freq);
+
+	return true;
+}
+
+static bool
+init_pll2(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_PLL2   opcode: 0x4B ('K')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): register
+	 * offset + 5  (32 bit): freq
+	 *
+	 * Set PLL register "register" to coefficients for frequency "freq"
+	 */
+
+	uint32_t reg = ROM32(bios->data[offset + 1]);
+	uint32_t freq = ROM32(bios->data[offset + 5]);
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: Reg: 0x%04X, Freq: %dkHz\n",
+		offset, reg, freq);
+
+	setPLL(bios, reg, freq);
+	return true;
+}
+
+static bool
+init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_I2C_BYTE   opcode: 0x4C ('L')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): DCB I2C table entry index
+	 * offset + 2  (8 bit): I2C slave address
+	 * offset + 3  (8 bit): count
+	 * offset + 4  (8 bit): I2C register 1
+	 * offset + 5  (8 bit): mask 1
+	 * offset + 6  (8 bit): data 1
+	 * ...
+	 *
+	 * For each of "count" registers given by "I2C register n" on the device
+	 * addressed by "I2C slave address" on the I2C bus given by
+	 * "DCB I2C table entry index", read the register, AND the result with
+	 * "mask n" and OR it with "data n" before writing it back to the device
+	 */
+
+	uint8_t i2c_index = bios->data[offset + 1];
+	uint8_t i2c_address = bios->data[offset + 2];
+	uint8_t count = bios->data[offset + 3];
+	struct nouveau_i2c_chan *chan;
+	struct i2c_msg msg;
+	int i;
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, "
+		      "Count: 0x%02X\n",
+		offset, i2c_index, i2c_address, count);
+
+	chan = init_i2c_device_find(bios->dev, i2c_index);
+	if (!chan)
+		return false;
+
+	for (i = 0; i < count; i++) {
+		uint8_t i2c_reg = bios->data[offset + 4 + i * 3];
+		uint8_t mask = bios->data[offset + 5 + i * 3];
+		uint8_t data = bios->data[offset + 6 + i * 3];
+		uint8_t value;
+
+		msg.addr = i2c_address;
+		msg.flags = I2C_M_RD;
+		msg.len = 1;
+		msg.buf = &value;
+		if (i2c_transfer(&chan->adapter, &msg, 1) != 1)
+			return false;
+
+		BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, "
+			      "Mask: 0x%02X, Data: 0x%02X\n",
+			offset, i2c_reg, value, mask, data);
+
+		value = (value & mask) | data;
+
+		if (bios->execute) {
+			msg.addr = i2c_address;
+			msg.flags = 0;
+			msg.len = 1;
+			msg.buf = &value;
+			if (i2c_transfer(&chan->adapter, &msg, 1) != 1)
+				return false;
+		}
+	}
+
+	return true;
+}
+
+static bool
+init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_ZM_I2C_BYTE   opcode: 0x4D ('M')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): DCB I2C table entry index
+	 * offset + 2  (8 bit): I2C slave address
+	 * offset + 3  (8 bit): count
+	 * offset + 4  (8 bit): I2C register 1
+	 * offset + 5  (8 bit): data 1
+	 * ...
+	 *
+	 * For each of "count" registers given by "I2C register n" on the device
+	 * addressed by "I2C slave address" on the I2C bus given by
+	 * "DCB I2C table entry index", set the register to "data n"
+	 */
+
+	uint8_t i2c_index = bios->data[offset + 1];
+	uint8_t i2c_address = bios->data[offset + 2];
+	uint8_t count = bios->data[offset + 3];
+	struct nouveau_i2c_chan *chan;
+	struct i2c_msg msg;
+	int i;
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, "
+		      "Count: 0x%02X\n",
+		offset, i2c_index, i2c_address, count);
+
+	chan = init_i2c_device_find(bios->dev, i2c_index);
+	if (!chan)
+		return false;
+
+	for (i = 0; i < count; i++) {
+		uint8_t i2c_reg = bios->data[offset + 4 + i * 2];
+		uint8_t data = bios->data[offset + 5 + i * 2];
+
+		BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Data: 0x%02X\n",
+			offset, i2c_reg, data);
+
+		if (bios->execute) {
+			msg.addr = i2c_address;
+			msg.flags = 0;
+			msg.len = 1;
+			msg.buf = &data;
+			if (i2c_transfer(&chan->adapter, &msg, 1) != 1)
+				return false;
+		}
+	}
+
+	return true;
+}
+
+static bool
+init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_ZM_I2C   opcode: 0x4E ('N')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): DCB I2C table entry index
+	 * offset + 2  (8 bit): I2C slave address
+	 * offset + 3  (8 bit): count
+	 * offset + 4  (8 bit): data 1
+	 * ...
+	 *
+	 * Send "count" bytes ("data n") to the device addressed by "I2C slave
+	 * address" on the I2C bus given by "DCB I2C table entry index"
+	 */
+
+	uint8_t i2c_index = bios->data[offset + 1];
+	uint8_t i2c_address = bios->data[offset + 2];
+	uint8_t count = bios->data[offset + 3];
+	struct nouveau_i2c_chan *chan;
+	struct i2c_msg msg;
+	uint8_t data[256];
+	int i;
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, "
+		      "Count: 0x%02X\n",
+		offset, i2c_index, i2c_address, count);
+
+	chan = init_i2c_device_find(bios->dev, i2c_index);
+	if (!chan)
+		return false;
+
+	for (i = 0; i < count; i++) {
+		data[i] = bios->data[offset + 4 + i];
+
+		BIOSLOG(bios, "0x%04X: Data: 0x%02X\n", offset, data[i]);
+	}
+
+	if (bios->execute) {
+		msg.addr = i2c_address;
+		msg.flags = 0;
+		msg.len = count;
+		msg.buf = data;
+		if (i2c_transfer(&chan->adapter, &msg, 1) != 1)
+			return false;
+	}
+
+	return true;
+}
+
+static bool
+init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_TMDS   opcode: 0x4F ('O')	(non-canon name)
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): magic lookup value
+	 * offset + 2  (8 bit): TMDS address
+	 * offset + 3  (8 bit): mask
+	 * offset + 4  (8 bit): data
+	 *
+	 * Read the data reg for TMDS address "TMDS address", AND it with mask
+	 * and OR it with data, then write it back
+	 * "magic lookup value" determines which TMDS base address register is
+	 * used -- see get_tmds_index_reg()
+	 */
+
+	uint8_t mlv = bios->data[offset + 1];
+	uint32_t tmdsaddr = bios->data[offset + 2];
+	uint8_t mask = bios->data[offset + 3];
+	uint8_t data = bios->data[offset + 4];
+	uint32_t reg, value;
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: MagicLookupValue: 0x%02X, TMDSAddr: 0x%02X, "
+		      "Mask: 0x%02X, Data: 0x%02X\n",
+		offset, mlv, tmdsaddr, mask, data);
+
+	reg = get_tmds_index_reg(bios->dev, mlv);
+	if (!reg)
+		return false;
+
+	bios_wr32(bios, reg,
+		  tmdsaddr | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
+	value = (bios_rd32(bios, reg + 4) & mask) | data;
+	bios_wr32(bios, reg + 4, value);
+	bios_wr32(bios, reg, tmdsaddr);
+
+	return true;
+}
+
+static bool
+init_zm_tmds_group(struct nvbios *bios, uint16_t offset,
+		   struct init_exec *iexec)
+{
+	/*
+	 * INIT_ZM_TMDS_GROUP   opcode: 0x50 ('P')	(non-canon name)
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): magic lookup value
+	 * offset + 2  (8 bit): count
+	 * offset + 3  (8 bit): addr 1
+	 * offset + 4  (8 bit): data 1
+	 * ...
+	 *
+	 * For each of "count" TMDS address and data pairs write "data n" to
+	 * "addr n".  "magic lookup value" determines which TMDS base address
+	 * register is used -- see get_tmds_index_reg()
+	 */
+
+	uint8_t mlv = bios->data[offset + 1];
+	uint8_t count = bios->data[offset + 2];
+	uint32_t reg;
+	int i;
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: MagicLookupValue: 0x%02X, Count: 0x%02X\n",
+		offset, mlv, count);
+
+	reg = get_tmds_index_reg(bios->dev, mlv);
+	if (!reg)
+		return false;
+
+	for (i = 0; i < count; i++) {
+		uint8_t tmdsaddr = bios->data[offset + 3 + i * 2];
+		uint8_t tmdsdata = bios->data[offset + 4 + i * 2];
+
+		bios_wr32(bios, reg + 4, tmdsdata);
+		bios_wr32(bios, reg, tmdsaddr);
+	}
+
+	return true;
+}
+
+static bool
+init_cr_idx_adr_latch(struct nvbios *bios, uint16_t offset,
+		      struct init_exec *iexec)
+{
+	/*
+	 * INIT_CR_INDEX_ADDRESS_LATCHED   opcode: 0x51 ('Q')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): CRTC index1
+	 * offset + 2  (8 bit): CRTC index2
+	 * offset + 3  (8 bit): baseaddr
+	 * offset + 4  (8 bit): count
+	 * offset + 5  (8 bit): data 1
+	 * ...
+	 *
+	 * For each of "count" address and data pairs, write "baseaddr + n" to
+	 * "CRTC index1" and "data n" to "CRTC index2"
+	 * Once complete, restore initial value read from "CRTC index1"
+	 */
+	uint8_t crtcindex1 = bios->data[offset + 1];
+	uint8_t crtcindex2 = bios->data[offset + 2];
+	uint8_t baseaddr = bios->data[offset + 3];
+	uint8_t count = bios->data[offset + 4];
+	uint8_t oldaddr, data;
+	int i;
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: Index1: 0x%02X, Index2: 0x%02X, "
+		      "BaseAddr: 0x%02X, Count: 0x%02X\n",
+		offset, crtcindex1, crtcindex2, baseaddr, count);
+
+	oldaddr = bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, crtcindex1);
+
+	for (i = 0; i < count; i++) {
+		bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex1,
+				     baseaddr + i);
+		data = bios->data[offset + 5 + i];
+		bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex2, data);
+	}
+
+	bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex1, oldaddr);
+
+	return true;
+}
+
+static bool
+init_cr(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_CR   opcode: 0x52 ('R')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (8  bit): CRTC index
+	 * offset + 2  (8  bit): mask
+	 * offset + 3  (8  bit): data
+	 *
+	 * Assign the value of at "CRTC index" ANDed with mask and ORed with
+	 * data back to "CRTC index"
+	 */
+
+	uint8_t crtcindex = bios->data[offset + 1];
+	uint8_t mask = bios->data[offset + 2];
+	uint8_t data = bios->data[offset + 3];
+	uint8_t value;
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: Index: 0x%02X, Mask: 0x%02X, Data: 0x%02X\n",
+		offset, crtcindex, mask, data);
+
+	value  = bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, crtcindex) & mask;
+	value |= data;
+	bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex, value);
+
+	return true;
+}
+
+static bool
+init_zm_cr(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_ZM_CR   opcode: 0x53 ('S')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): CRTC index
+	 * offset + 2  (8 bit): value
+	 *
+	 * Assign "value" to CRTC register with index "CRTC index".
+	 */
+
+	uint8_t crtcindex = ROM32(bios->data[offset + 1]);
+	uint8_t data = bios->data[offset + 2];
+
+	if (!iexec->execute)
+		return true;
+
+	bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex, data);
+
+	return true;
+}
+
+static bool
+init_zm_cr_group(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_ZM_CR_GROUP   opcode: 0x54 ('T')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): count
+	 * offset + 2  (8 bit): CRTC index 1
+	 * offset + 3  (8 bit): value 1
+	 * ...
+	 *
+	 * For "count", assign "value n" to CRTC register with index
+	 * "CRTC index n".
+	 */
+
+	uint8_t count = bios->data[offset + 1];
+	int i;
+
+	if (!iexec->execute)
+		return true;
+
+	for (i = 0; i < count; i++)
+		init_zm_cr(bios, offset + 2 + 2 * i - 1, iexec);
+
+	return true;
+}
+
+static bool
+init_condition_time(struct nvbios *bios, uint16_t offset,
+		    struct init_exec *iexec)
+{
+	/*
+	 * INIT_CONDITION_TIME   opcode: 0x56 ('V')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): condition number
+	 * offset + 2  (8 bit): retries / 50
+	 *
+	 * Check condition "condition number" in the condition table.
+	 * Bios code then sleeps for 2ms if the condition is not met, and
+	 * repeats up to "retries" times, but on one C51 this has proved
+	 * insufficient.  In mmiotraces the driver sleeps for 20ms, so we do
+	 * this, and bail after "retries" times, or 2s, whichever is less.
+	 * If still not met after retries, clear execution flag for this table.
+	 */
+
+	uint8_t cond = bios->data[offset + 1];
+	uint16_t retries = bios->data[offset + 2] * 50;
+	unsigned cnt;
+
+	if (!iexec->execute)
+		return true;
+
+	if (retries > 100)
+		retries = 100;
+
+	BIOSLOG(bios, "0x%04X: Condition: 0x%02X, Retries: 0x%02X\n",
+		offset, cond, retries);
+
+	if (!bios->execute) /* avoid 2s delays when "faking" execution */
+		retries = 1;
+
+	for (cnt = 0; cnt < retries; cnt++) {
+		if (bios_condition_met(bios, offset, cond)) {
+			BIOSLOG(bios, "0x%04X: Condition met, continuing\n",
+								offset);
+			break;
+		} else {
+			BIOSLOG(bios, "0x%04X: "
+				"Condition not met, sleeping for 20ms\n",
+								offset);
+			msleep(20);
+		}
+	}
+
+	if (!bios_condition_met(bios, offset, cond)) {
+		NV_WARN(bios->dev,
+			"0x%04X: Condition still not met after %dms, "
+			"skipping following opcodes\n", offset, 20 * retries);
+		iexec->execute = false;
+	}
+
+	return true;
+}
+
+static bool
+init_zm_reg_sequence(struct nvbios *bios, uint16_t offset,
+		     struct init_exec *iexec)
+{
+	/*
+	 * INIT_ZM_REG_SEQUENCE   opcode: 0x58 ('X')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): base register
+	 * offset + 5  (8  bit): count
+	 * offset + 6  (32 bit): value 1
+	 * ...
+	 *
+	 * Starting at offset + 6 there are "count" 32 bit values.
+	 * For "count" iterations set "base register" + 4 * current_iteration
+	 * to "value current_iteration"
+	 */
+
+	uint32_t basereg = ROM32(bios->data[offset + 1]);
+	uint32_t count = bios->data[offset + 5];
+	int i;
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: BaseReg: 0x%08X, Count: 0x%02X\n",
+		offset, basereg, count);
+
+	for (i = 0; i < count; i++) {
+		uint32_t reg = basereg + i * 4;
+		uint32_t data = ROM32(bios->data[offset + 6 + i * 4]);
+
+		bios_wr32(bios, reg, data);
+	}
+
+	return true;
+}
+
+static bool
+init_sub_direct(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_SUB_DIRECT   opcode: 0x5B ('[')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (16 bit): subroutine offset (in bios)
+	 *
+	 * Calls a subroutine that will execute commands until INIT_DONE
+	 * is found.
+	 */
+
+	uint16_t sub_offset = ROM16(bios->data[offset + 1]);
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: Executing subroutine at 0x%04X\n",
+		offset, sub_offset);
+
+	parse_init_table(bios, sub_offset, iexec);
+
+	BIOSLOG(bios, "0x%04X: End of 0x%04X subroutine\n", offset, sub_offset);
+
+	return true;
+}
+
+static bool
+init_copy_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_COPY_NV_REG   opcode: 0x5F ('_')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): src reg
+	 * offset + 5  (8  bit): shift
+	 * offset + 6  (32 bit): src mask
+	 * offset + 10 (32 bit): xor
+	 * offset + 14 (32 bit): dst reg
+	 * offset + 18 (32 bit): dst mask
+	 *
+	 * Shift REGVAL("src reg") right by (signed) "shift", AND result with
+	 * "src mask", then XOR with "xor". Write this OR'd with
+	 * (REGVAL("dst reg") AND'd with "dst mask") to "dst reg"
+	 */
+
+	uint32_t srcreg = *((uint32_t *)(&bios->data[offset + 1]));
+	uint8_t shift = bios->data[offset + 5];
+	uint32_t srcmask = *((uint32_t *)(&bios->data[offset + 6]));
+	uint32_t xor = *((uint32_t *)(&bios->data[offset + 10]));
+	uint32_t dstreg = *((uint32_t *)(&bios->data[offset + 14]));
+	uint32_t dstmask = *((uint32_t *)(&bios->data[offset + 18]));
+	uint32_t srcvalue, dstvalue;
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: SrcReg: 0x%08X, Shift: 0x%02X, SrcMask: 0x%08X, "
+		      "Xor: 0x%08X, DstReg: 0x%08X, DstMask: 0x%08X\n",
+		offset, srcreg, shift, srcmask, xor, dstreg, dstmask);
+
+	srcvalue = bios_rd32(bios, srcreg);
+
+	if (shift < 0x80)
+		srcvalue >>= shift;
+	else
+		srcvalue <<= (0x100 - shift);
+
+	srcvalue = (srcvalue & srcmask) ^ xor;
+
+	dstvalue = bios_rd32(bios, dstreg) & dstmask;
+
+	bios_wr32(bios, dstreg, dstvalue | srcvalue);
+
+	return true;
+}
+
+static bool
+init_zm_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_ZM_INDEX_IO   opcode: 0x62 ('b')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (16 bit): CRTC port
+	 * offset + 3  (8  bit): CRTC index
+	 * offset + 4  (8  bit): data
+	 *
+	 * Write "data" to index "CRTC index" of "CRTC port"
+	 */
+	uint16_t crtcport = ROM16(bios->data[offset + 1]);
+	uint8_t crtcindex = bios->data[offset + 3];
+	uint8_t data = bios->data[offset + 4];
+
+	if (!iexec->execute)
+		return true;
+
+	bios_idxprt_wr(bios, crtcport, crtcindex, data);
+
+	return true;
+}
+
+static bool
+init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_COMPUTE_MEM   opcode: 0x63 ('c')
+	 *
+	 * offset      (8 bit): opcode
+	 *
+	 * This opcode is meant to set NV_PFB_CFG0 (0x100200) appropriately so
+	 * that the hardware can correctly calculate how much VRAM it has
+	 * (and subsequently report that value in NV_PFB_CSTATUS (0x10020C))
+	 *
+	 * The implementation of this opcode in general consists of two parts:
+	 * 1) determination of the memory bus width
+	 * 2) determination of how many of the card's RAM pads have ICs attached
+	 *
+	 * 1) is done by a cunning combination of writes to offsets 0x1c and
+	 * 0x3c in the framebuffer, and seeing whether the written values are
+	 * read back correctly. This then affects bits 4-7 of NV_PFB_CFG0
+	 *
+	 * 2) is done by a cunning combination of writes to an offset slightly
+	 * less than the maximum memory reported by NV_PFB_CSTATUS, then seeing
+	 * if the test pattern can be read back. This then affects bits 12-15 of
+	 * NV_PFB_CFG0
+	 *
+	 * In this context a "cunning combination" may include multiple reads
+	 * and writes to varying locations, often alternating the test pattern
+	 * and 0, doubtless to make sure buffers are filled, residual charges
+	 * on tracks are removed etc.
+	 *
+	 * Unfortunately, the "cunning combination"s mentioned above, and the
+	 * changes to the bits in NV_PFB_CFG0 differ with nearly every bios
+	 * trace I have.
+	 *
+	 * Therefore, we cheat and assume the value of NV_PFB_CFG0 with which
+	 * we started was correct, and use that instead
+	 */
+
+	/* no iexec->execute check by design */
+
+	/*
+	 * This appears to be a NOP on G8x chipsets, both io logs of the VBIOS
+	 * and kmmio traces of the binary driver POSTing the card show nothing
+	 * being done for this opcode.  why is it still listed in the table?!
+	 */
+
+	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
+
+	if (dev_priv->card_type >= NV_50)
+		return true;
+
+	/*
+	 * On every card I've seen, this step gets done for us earlier in
+	 * the init scripts
+	uint8_t crdata = bios_idxprt_rd(dev, NV_VIO_SRX, 0x01);
+	bios_idxprt_wr(dev, NV_VIO_SRX, 0x01, crdata | 0x20);
+	 */
+
+	/*
+	 * This also has probably been done in the scripts, but an mmio trace of
+	 * s3 resume shows nvidia doing it anyway (unlike the NV_VIO_SRX write)
+	 */
+	bios_wr32(bios, NV_PFB_REFCTRL, NV_PFB_REFCTRL_VALID_1);
+
+	/* write back the saved configuration value */
+	bios_wr32(bios, NV_PFB_CFG0, bios->state.saved_nv_pfb_cfg0);
+
+	return true;
+}
+
+static bool
+init_reset(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_RESET   opcode: 0x65 ('e')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): register
+	 * offset + 5  (32 bit): value1
+	 * offset + 9  (32 bit): value2
+	 *
+	 * Assign "value1" to "register", then assign "value2" to "register"
+	 */
+
+	uint32_t reg = ROM32(bios->data[offset + 1]);
+	uint32_t value1 = ROM32(bios->data[offset + 5]);
+	uint32_t value2 = ROM32(bios->data[offset + 9]);
+	uint32_t pci_nv_19, pci_nv_20;
+
+	/* no iexec->execute check by design */
+
+	pci_nv_19 = bios_rd32(bios, NV_PBUS_PCI_NV_19);
+	bios_wr32(bios, NV_PBUS_PCI_NV_19, 0);
+	bios_wr32(bios, reg, value1);
+
+	udelay(10);
+
+	bios_wr32(bios, reg, value2);
+	bios_wr32(bios, NV_PBUS_PCI_NV_19, pci_nv_19);
+
+	pci_nv_20 = bios_rd32(bios, NV_PBUS_PCI_NV_20);
+	pci_nv_20 &= ~NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED;	/* 0xfffffffe */
+	bios_wr32(bios, NV_PBUS_PCI_NV_20, pci_nv_20);
+
+	return true;
+}
+
+static bool
+init_configure_mem(struct nvbios *bios, uint16_t offset,
+		   struct init_exec *iexec)
+{
+	/*
+	 * INIT_CONFIGURE_MEM   opcode: 0x66 ('f')
+	 *
+	 * offset      (8 bit): opcode
+	 *
+	 * Equivalent to INIT_DONE on bios version 3 or greater.
+	 * For early bios versions, sets up the memory registers, using values
+	 * taken from the memory init table
+	 */
+
+	/* no iexec->execute check by design */
+
+	uint16_t meminitoffs = bios->legacy.mem_init_tbl_ptr + MEM_INIT_SIZE * (bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, NV_CIO_CRE_SCRATCH4__INDEX) >> 4);
+	uint16_t seqtbloffs = bios->legacy.sdr_seq_tbl_ptr, meminitdata = meminitoffs + 6;
+	uint32_t reg, data;
+
+	if (bios->major_version > 2)
+		return false;
+
+	bios_idxprt_wr(bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX, bios_idxprt_rd(
+		       bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX) | 0x20);
+
+	if (bios->data[meminitoffs] & 1)
+		seqtbloffs = bios->legacy.ddr_seq_tbl_ptr;
+
+	for (reg = ROM32(bios->data[seqtbloffs]);
+	     reg != 0xffffffff;
+	     reg = ROM32(bios->data[seqtbloffs += 4])) {
+
+		switch (reg) {
+		case NV_PFB_PRE:
+			data = NV_PFB_PRE_CMD_PRECHARGE;
+			break;
+		case NV_PFB_PAD:
+			data = NV_PFB_PAD_CKE_NORMAL;
+			break;
+		case NV_PFB_REF:
+			data = NV_PFB_REF_CMD_REFRESH;
+			break;
+		default:
+			data = ROM32(bios->data[meminitdata]);
+			meminitdata += 4;
+			if (data == 0xffffffff)
+				continue;
+		}
+
+		bios_wr32(bios, reg, data);
+	}
+
+	return true;
+}
+
+static bool
+init_configure_clk(struct nvbios *bios, uint16_t offset,
+		   struct init_exec *iexec)
+{
+	/*
+	 * INIT_CONFIGURE_CLK   opcode: 0x67 ('g')
+	 *
+	 * offset      (8 bit): opcode
+	 *
+	 * Equivalent to INIT_DONE on bios version 3 or greater.
+	 * For early bios versions, sets up the NVClk and MClk PLLs, using
+	 * values taken from the memory init table
+	 */
+
+	/* no iexec->execute check by design */
+
+	uint16_t meminitoffs = bios->legacy.mem_init_tbl_ptr + MEM_INIT_SIZE * (bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, NV_CIO_CRE_SCRATCH4__INDEX) >> 4);
+	int clock;
+
+	if (bios->major_version > 2)
+		return false;
+
+	clock = ROM16(bios->data[meminitoffs + 4]) * 10;
+	setPLL(bios, NV_PRAMDAC_NVPLL_COEFF, clock);
+
+	clock = ROM16(bios->data[meminitoffs + 2]) * 10;
+	if (bios->data[meminitoffs] & 1) /* DDR */
+		clock *= 2;
+	setPLL(bios, NV_PRAMDAC_MPLL_COEFF, clock);
+
+	return true;
+}
+
+static bool
+init_configure_preinit(struct nvbios *bios, uint16_t offset,
+		       struct init_exec *iexec)
+{
+	/*
+	 * INIT_CONFIGURE_PREINIT   opcode: 0x68 ('h')
+	 *
+	 * offset      (8 bit): opcode
+	 *
+	 * Equivalent to INIT_DONE on bios version 3 or greater.
+	 * For early bios versions, does early init, loading ram and crystal
+	 * configuration from straps into CR3C
+	 */
+
+	/* no iexec->execute check by design */
+
+	uint32_t straps = bios_rd32(bios, NV_PEXTDEV_BOOT_0);
+	uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & (1 << 6));
+
+	if (bios->major_version > 2)
+		return false;
+
+	bios_idxprt_wr(bios, NV_CIO_CRX__COLOR,
+			     NV_CIO_CRE_SCRATCH4__INDEX, cr3c);
+
+	return true;
+}
+
+static bool
+init_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_IO   opcode: 0x69 ('i')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (16 bit): CRTC port
+	 * offset + 3  (8  bit): mask
+	 * offset + 4  (8  bit): data
+	 *
+	 * Assign ((IOVAL("crtc port") & "mask") | "data") to "crtc port"
+	 */
+
+	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
+	uint16_t crtcport = ROM16(bios->data[offset + 1]);
+	uint8_t mask = bios->data[offset + 3];
+	uint8_t data = bios->data[offset + 4];
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: Port: 0x%04X, Mask: 0x%02X, Data: 0x%02X\n",
+		offset, crtcport, mask, data);
+
+	/*
+	 * I have no idea what this does, but NVIDIA do this magic sequence
+	 * in the places where this INIT_IO happens..
+	 */
+	if (dev_priv->card_type >= NV_50 && crtcport == 0x3c3 && data == 1) {
+		int i;
+
+		bios_wr32(bios, 0x614100, (bios_rd32(
+			  bios, 0x614100) & 0x0fffffff) | 0x00800000);
+
+		bios_wr32(bios, 0x00e18c, bios_rd32(
+			  bios, 0x00e18c) | 0x00020000);
+
+		bios_wr32(bios, 0x614900, (bios_rd32(
+			  bios, 0x614900) & 0x0fffffff) | 0x00800000);
+
+		bios_wr32(bios, 0x000200, bios_rd32(
+			  bios, 0x000200) & ~0x40000000);
+
+		mdelay(10);
+
+		bios_wr32(bios, 0x00e18c, bios_rd32(
+			  bios, 0x00e18c) & ~0x00020000);
+
+		bios_wr32(bios, 0x000200, bios_rd32(
+			  bios, 0x000200) | 0x40000000);
+
+		bios_wr32(bios, 0x614100, 0x00800018);
+		bios_wr32(bios, 0x614900, 0x00800018);
+
+		mdelay(10);
+
+		bios_wr32(bios, 0x614100, 0x10000018);
+		bios_wr32(bios, 0x614900, 0x10000018);
+
+		for (i = 0; i < 3; i++)
+			bios_wr32(bios, 0x614280 + (i*0x800), bios_rd32(
+				  bios, 0x614280 + (i*0x800)) & 0xf0f0f0f0);
+
+		for (i = 0; i < 2; i++)
+			bios_wr32(bios, 0x614300 + (i*0x800), bios_rd32(
+				  bios, 0x614300 + (i*0x800)) & 0xfffff0f0);
+
+		for (i = 0; i < 3; i++)
+			bios_wr32(bios, 0x614380 + (i*0x800), bios_rd32(
+				  bios, 0x614380 + (i*0x800)) & 0xfffff0f0);
+
+		for (i = 0; i < 2; i++)
+			bios_wr32(bios, 0x614200 + (i*0x800), bios_rd32(
+				  bios, 0x614200 + (i*0x800)) & 0xfffffff0);
+
+		for (i = 0; i < 2; i++)
+			bios_wr32(bios, 0x614108 + (i*0x800), bios_rd32(
+				  bios, 0x614108 + (i*0x800)) & 0x0fffffff);
+		return true;
+	}
+
+	bios_port_wr(bios, crtcport, (bios_port_rd(bios, crtcport) & mask) |
+									data);
+	return true;
+}
+
+static bool
+init_sub(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_SUB   opcode: 0x6B ('k')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): script number
+	 *
+	 * Execute script number "script number", as a subroutine
+	 */
+
+	uint8_t sub = bios->data[offset + 1];
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: Calling script %d\n", offset, sub);
+
+	parse_init_table(bios,
+			 ROM16(bios->data[bios->init_script_tbls_ptr + sub * 2]),
+			 iexec);
+
+	BIOSLOG(bios, "0x%04X: End of script %d\n", offset, sub);
+
+	return true;
+}
+
+static bool
+init_ram_condition(struct nvbios *bios, uint16_t offset,
+		   struct init_exec *iexec)
+{
+	/*
+	 * INIT_RAM_CONDITION   opcode: 0x6D ('m')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): mask
+	 * offset + 2  (8 bit): cmpval
+	 *
+	 * Test if (NV_PFB_BOOT_0 & "mask") equals "cmpval".
+	 * If condition not met skip subsequent opcodes until condition is
+	 * inverted (INIT_NOT), or we hit INIT_RESUME
+	 */
+
+	uint8_t mask = bios->data[offset + 1];
+	uint8_t cmpval = bios->data[offset + 2];
+	uint8_t data;
+
+	if (!iexec->execute)
+		return true;
+
+	data = bios_rd32(bios, NV_PFB_BOOT_0) & mask;
+
+	BIOSLOG(bios, "0x%04X: Checking if 0x%08X equals 0x%08X\n",
+		offset, data, cmpval);
+
+	if (data == cmpval)
+		BIOSLOG(bios, "0x%04X: Condition fulfilled -- continuing to execute\n", offset);
+	else {
+		BIOSLOG(bios, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset);
+		iexec->execute = false;
+	}
+
+	return true;
+}
+
+static bool
+init_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_NV_REG   opcode: 0x6E ('n')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): register
+	 * offset + 5  (32 bit): mask
+	 * offset + 9  (32 bit): data
+	 *
+	 * Assign ((REGVAL("register") & "mask") | "data") to "register"
+	 */
+
+	uint32_t reg = ROM32(bios->data[offset + 1]);
+	uint32_t mask = ROM32(bios->data[offset + 5]);
+	uint32_t data = ROM32(bios->data[offset + 9]);
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Mask: 0x%08X, Data: 0x%08X\n",
+		offset, reg, mask, data);
+
+	bios_wr32(bios, reg, (bios_rd32(bios, reg) & mask) | data);
+
+	return true;
+}
+
+static bool
+init_macro(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_MACRO   opcode: 0x6F ('o')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): macro number
+	 *
+	 * Look up macro index "macro number" in the macro index table.
+	 * The macro index table entry has 1 byte for the index in the macro
+	 * table, and 1 byte for the number of times to repeat the macro.
+	 * The macro table entry has 4 bytes for the register address and
+	 * 4 bytes for the value to write to that register
+	 */
+
+	uint8_t macro_index_tbl_idx = bios->data[offset + 1];
+	uint16_t tmp = bios->macro_index_tbl_ptr + (macro_index_tbl_idx * MACRO_INDEX_SIZE);
+	uint8_t macro_tbl_idx = bios->data[tmp];
+	uint8_t count = bios->data[tmp + 1];
+	uint32_t reg, data;
+	int i;
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: Macro: 0x%02X, MacroTableIndex: 0x%02X, "
+		      "Count: 0x%02X\n",
+		offset, macro_index_tbl_idx, macro_tbl_idx, count);
+
+	for (i = 0; i < count; i++) {
+		uint16_t macroentryptr = bios->macro_tbl_ptr + (macro_tbl_idx + i) * MACRO_SIZE;
+
+		reg = ROM32(bios->data[macroentryptr]);
+		data = ROM32(bios->data[macroentryptr + 4]);
+
+		bios_wr32(bios, reg, data);
+	}
+
+	return true;
+}
+
+static bool
+init_done(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_DONE   opcode: 0x71 ('q')
+	 *
+	 * offset      (8  bit): opcode
+	 *
+	 * End the current script
+	 */
+
+	/* mild retval abuse to stop parsing this table */
+	return false;
+}
+
+static bool
+init_resume(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_RESUME   opcode: 0x72 ('r')
+	 *
+	 * offset      (8  bit): opcode
+	 *
+	 * End the current execute / no-execute condition
+	 */
+
+	if (iexec->execute)
+		return true;
+
+	iexec->execute = true;
+	BIOSLOG(bios, "0x%04X: ---- Executing following commands ----\n", offset);
+
+	return true;
+}
+
+static bool
+init_time(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_TIME   opcode: 0x74 ('t')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (16 bit): time
+	 *
+	 * Sleep for "time" microseconds.
+	 */
+
+	unsigned time = ROM16(bios->data[offset + 1]);
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: Sleeping for 0x%04X microseconds\n",
+		offset, time);
+
+	if (time < 1000)
+		udelay(time);
+	else
+		msleep((time + 900) / 1000);
+
+	return true;
+}
+
+static bool
+init_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_CONDITION   opcode: 0x75 ('u')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): condition number
+	 *
+	 * Check condition "condition number" in the condition table.
+	 * If condition not met skip subsequent opcodes until condition is
+	 * inverted (INIT_NOT), or we hit INIT_RESUME
+	 */
+
+	uint8_t cond = bios->data[offset + 1];
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: Condition: 0x%02X\n", offset, cond);
+
+	if (bios_condition_met(bios, offset, cond))
+		BIOSLOG(bios, "0x%04X: Condition fulfilled -- continuing to execute\n", offset);
+	else {
+		BIOSLOG(bios, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset);
+		iexec->execute = false;
+	}
+
+	return true;
+}
+
+static bool
+init_io_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_IO_CONDITION  opcode: 0x76
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): condition number
+	 *
+	 * Check condition "condition number" in the io condition table.
+	 * If condition not met skip subsequent opcodes until condition is
+	 * inverted (INIT_NOT), or we hit INIT_RESUME
+	 */
+
+	uint8_t cond = bios->data[offset + 1];
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: IO condition: 0x%02X\n", offset, cond);
+
+	if (io_condition_met(bios, offset, cond))
+		BIOSLOG(bios, "0x%04X: Condition fulfilled -- continuing to execute\n", offset);
+	else {
+		BIOSLOG(bios, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset);
+		iexec->execute = false;
+	}
+
+	return true;
+}
+
+static bool
+init_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_INDEX_IO   opcode: 0x78 ('x')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (16 bit): CRTC port
+	 * offset + 3  (8  bit): CRTC index
+	 * offset + 4  (8  bit): mask
+	 * offset + 5  (8  bit): data
+	 *
+	 * Read value at index "CRTC index" on "CRTC port", AND with "mask",
+	 * OR with "data", write-back
+	 */
+
+	uint16_t crtcport = ROM16(bios->data[offset + 1]);
+	uint8_t crtcindex = bios->data[offset + 3];
+	uint8_t mask = bios->data[offset + 4];
+	uint8_t data = bios->data[offset + 5];
+	uint8_t value;
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, "
+		      "Data: 0x%02X\n",
+		offset, crtcport, crtcindex, mask, data);
+
+	value = (bios_idxprt_rd(bios, crtcport, crtcindex) & mask) | data;
+	bios_idxprt_wr(bios, crtcport, crtcindex, value);
+
+	return true;
+}
+
+static bool
+init_pll(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_PLL   opcode: 0x79 ('y')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): register
+	 * offset + 5  (16 bit): freq
+	 *
+	 * Set PLL register "register" to coefficients for frequency (10kHz)
+	 * "freq"
+	 */
+
+	uint32_t reg = ROM32(bios->data[offset + 1]);
+	uint16_t freq = ROM16(bios->data[offset + 5]);
+
+	if (!iexec->execute)
+		return true;
+
+	BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Freq: %d0kHz\n", offset, reg, freq);
+
+	setPLL(bios, reg, freq * 10);
+
+	return true;
+}
+
+static bool
+init_zm_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_ZM_REG   opcode: 0x7A ('z')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): register
+	 * offset + 5  (32 bit): value
+	 *
+	 * Assign "value" to "register"
+	 */
+
+	uint32_t reg = ROM32(bios->data[offset + 1]);
+	uint32_t value = ROM32(bios->data[offset + 5]);
+
+	if (!iexec->execute)
+		return true;
+
+	if (reg == 0x000200)
+		value |= 1;
+
+	bios_wr32(bios, reg, value);
+
+	return true;
+}
+
+static bool
+init_ram_restrict_pll(struct nvbios *bios, uint16_t offset,
+		      struct init_exec *iexec)
+{
+	/*
+	 * INIT_RAM_RESTRICT_PLL   opcode: 0x87 ('')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): PLL type
+	 * offset + 2 (32 bit): frequency 0
+	 *
+	 * Uses the RAMCFG strap of PEXTDEV_BOOT as an index into the table at
+	 * ram_restrict_table_ptr.  The value read from there is used to select
+	 * a frequency from the table starting at 'frequency 0' to be
+	 * programmed into the PLL corresponding to 'type'.
+	 *
+	 * The PLL limits table on cards using this opcode has a mapping of
+	 * 'type' to the relevant registers.
+	 */
+
+	struct drm_device *dev = bios->dev;
+	uint32_t strap = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) & 0x0000003c) >> 2;
+	uint8_t index = bios->data[bios->ram_restrict_tbl_ptr + strap];
+	uint8_t type = bios->data[offset + 1];
+	uint32_t freq = ROM32(bios->data[offset + 2 + (index * 4)]);
+	uint8_t *pll_limits = &bios->data[bios->pll_limit_tbl_ptr], *entry;
+	int i;
+
+	if (!iexec->execute)
+		return true;
+
+	if (!bios->pll_limit_tbl_ptr || (pll_limits[0] & 0xf0) != 0x30) {
+		NV_ERROR(dev, "PLL limits table not version 3.x\n");
+		return true; /* deliberate, allow default clocks to remain */
+	}
+
+	entry = pll_limits + pll_limits[1];
+	for (i = 0; i < pll_limits[3]; i++, entry += pll_limits[2]) {
+		if (entry[0] == type) {
+			uint32_t reg = ROM32(entry[3]);
+
+			BIOSLOG(bios, "0x%04X: "
+				      "Type %02x Reg 0x%08x Freq %dKHz\n",
+				offset, type, reg, freq);
+
+			setPLL(bios, reg, freq);
+			return true;
+		}
+	}
+
+	NV_ERROR(dev, "PLL type 0x%02x not found in PLL limits table", type);
+	return true;
+}
+
+static bool
+init_8c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_8C   opcode: 0x8C ('')
+	 *
+	 * NOP so far....
+	 *
+	 */
+
+	return true;
+}
+
+static bool
+init_8d(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_8D   opcode: 0x8D ('')
+	 *
+	 * NOP so far....
+	 *
+	 */
+
+	return true;
+}
+
+static bool
+init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_GPIO   opcode: 0x8E ('')
+	 *
+	 * offset      (8 bit): opcode
+	 *
+	 * Loop over all entries in the DCB GPIO table, and initialise
+	 * each GPIO according to various values listed in each entry
+	 */
+
+	const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
+	const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c };
+	const uint8_t *gpio_table = &bios->data[bios->bdcb.gpio_table_ptr];
+	const uint8_t *gpio_entry;
+	int i;
+
+	if (bios->bdcb.version != 0x40) {
+		NV_ERROR(bios->dev, "DCB table not version 4.0\n");
+		return false;
+	}
+
+	if (!bios->bdcb.gpio_table_ptr) {
+		NV_WARN(bios->dev, "Invalid pointer to INIT_8E table\n");
+		return false;
+	}
+
+	gpio_entry = gpio_table + gpio_table[1];
+	for (i = 0; i < gpio_table[2]; i++, gpio_entry += gpio_table[3]) {
+		uint32_t entry = ROM32(gpio_entry[0]), r, s, v;
+		int line = (entry & 0x0000001f);
+
+		BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, entry);
+
+		if ((entry & 0x0000ff00) == 0x0000ff00)
+			continue;
+
+		r = nv50_gpio_reg[line >> 3];
+		s = (line & 0x07) << 2;
+		v = bios_rd32(bios, r) & ~(0x00000003 << s);
+		if (entry & 0x01000000)
+			v |= (((entry & 0x60000000) >> 29) ^ 2) << s;
+		else
+			v |= (((entry & 0x18000000) >> 27) ^ 2) << s;
+		bios_wr32(bios, r, v);
+
+		r = nv50_gpio_ctl[line >> 4];
+		s = (line & 0x0f);
+		v = bios_rd32(bios, r) & ~(0x00010001 << s);
+		switch ((entry & 0x06000000) >> 25) {
+		case 1:
+			v |= (0x00000001 << s);
+			break;
+		case 2:
+			v |= (0x00010000 << s);
+			break;
+		default:
+			break;
+		}
+		bios_wr32(bios, r, v);
+	}
+
+	return true;
+}
+
+/* hack to avoid moving the itbl_entry array before this function */
+int init_ram_restrict_zm_reg_group_blocklen;
+
+static bool
+init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset,
+			       struct init_exec *iexec)
+{
+	/*
+	 * INIT_RAM_RESTRICT_ZM_REG_GROUP   opcode: 0x8F ('')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): reg
+	 * offset + 5  (8  bit): regincrement
+	 * offset + 6  (8  bit): count
+	 * offset + 7  (32 bit): value 1,1
+	 * ...
+	 *
+	 * Use the RAMCFG strap of PEXTDEV_BOOT as an index into the table at
+	 * ram_restrict_table_ptr. The value read from here is 'n', and
+	 * "value 1,n" gets written to "reg". This repeats "count" times and on
+	 * each iteration 'm', "reg" increases by "regincrement" and
+	 * "value m,n" is used. The extent of n is limited by a number read
+	 * from the 'M' BIT table, herein called "blocklen"
+	 */
+
+	uint32_t reg = ROM32(bios->data[offset + 1]);
+	uint8_t regincrement = bios->data[offset + 5];
+	uint8_t count = bios->data[offset + 6];
+	uint32_t strap_ramcfg, data;
+	uint16_t blocklen;
+	uint8_t index;
+	int i;
+
+	/* previously set by 'M' BIT table */
+	blocklen = init_ram_restrict_zm_reg_group_blocklen;
+
+	if (!iexec->execute)
+		return true;
+
+	if (!blocklen) {
+		NV_ERROR(bios->dev,
+			 "0x%04X: Zero block length - has the M table "
+			 "been parsed?\n", offset);
+		return false;
+	}
+
+	strap_ramcfg = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 2) & 0xf;
+	index = bios->data[bios->ram_restrict_tbl_ptr + strap_ramcfg];
+
+	BIOSLOG(bios, "0x%04X: Reg: 0x%08X, RegIncrement: 0x%02X, "
+		      "Count: 0x%02X, StrapRamCfg: 0x%02X, Index: 0x%02X\n",
+		offset, reg, regincrement, count, strap_ramcfg, index);
+
+	for (i = 0; i < count; i++) {
+		data = ROM32(bios->data[offset + 7 + index * 4 + blocklen * i]);
+
+		bios_wr32(bios, reg, data);
+
+		reg += regincrement;
+	}
+
+	return true;
+}
+
+static bool
+init_copy_zm_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_COPY_ZM_REG   opcode: 0x90 ('')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): src reg
+	 * offset + 5  (32 bit): dst reg
+	 *
+	 * Put contents of "src reg" into "dst reg"
+	 */
+
+	uint32_t srcreg = ROM32(bios->data[offset + 1]);
+	uint32_t dstreg = ROM32(bios->data[offset + 5]);
+
+	if (!iexec->execute)
+		return true;
+
+	bios_wr32(bios, dstreg, bios_rd32(bios, srcreg));
+
+	return true;
+}
+
+static bool
+init_zm_reg_group_addr_latched(struct nvbios *bios, uint16_t offset,
+			       struct init_exec *iexec)
+{
+	/*
+	 * INIT_ZM_REG_GROUP_ADDRESS_LATCHED   opcode: 0x91 ('')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): dst reg
+	 * offset + 5  (8  bit): count
+	 * offset + 6  (32 bit): data 1
+	 * ...
+	 *
+	 * For each of "count" values write "data n" to "dst reg"
+	 */
+
+	uint32_t reg = ROM32(bios->data[offset + 1]);
+	uint8_t count = bios->data[offset + 5];
+	int i;
+
+	if (!iexec->execute)
+		return true;
+
+	for (i = 0; i < count; i++) {
+		uint32_t data = ROM32(bios->data[offset + 6 + 4 * i]);
+		bios_wr32(bios, reg, data);
+	}
+
+	return true;
+}
+
+static bool
+init_reserved(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_RESERVED   opcode: 0x92 ('')
+	 *
+	 * offset      (8 bit): opcode
+	 *
+	 * Seemingly does nothing
+	 */
+
+	return true;
+}
+
+static bool
+init_96(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_96   opcode: 0x96 ('')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): sreg
+	 * offset + 5  (8  bit): sshift
+	 * offset + 6  (8  bit): smask
+	 * offset + 7  (8  bit): index
+	 * offset + 8  (32 bit): reg
+	 * offset + 12 (32 bit): mask
+	 * offset + 16 (8  bit): shift
+	 *
+	 */
+
+	uint16_t xlatptr = bios->init96_tbl_ptr + (bios->data[offset + 7] * 2);
+	uint32_t reg = ROM32(bios->data[offset + 8]);
+	uint32_t mask = ROM32(bios->data[offset + 12]);
+	uint32_t val;
+
+	val = bios_rd32(bios, ROM32(bios->data[offset + 1]));
+	if (bios->data[offset + 5] < 0x80)
+		val >>= bios->data[offset + 5];
+	else
+		val <<= (0x100 - bios->data[offset + 5]);
+	val &= bios->data[offset + 6];
+
+	val   = bios->data[ROM16(bios->data[xlatptr]) + val];
+	val <<= bios->data[offset + 16];
+
+	if (!iexec->execute)
+		return true;
+
+	bios_wr32(bios, reg, (bios_rd32(bios, reg) & mask) | val);
+	return true;
+}
+
+static bool
+init_97(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_97   opcode: 0x97 ('')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): register
+	 * offset + 5  (32 bit): mask
+	 * offset + 9  (32 bit): value
+	 *
+	 * Adds "value" to "register" preserving the fields specified
+	 * by "mask"
+	 */
+
+	uint32_t reg = ROM32(bios->data[offset + 1]);
+	uint32_t mask = ROM32(bios->data[offset + 5]);
+	uint32_t add = ROM32(bios->data[offset + 9]);
+	uint32_t val;
+
+	val = bios_rd32(bios, reg);
+	val = (val & mask) | ((val + add) & ~mask);
+
+	if (!iexec->execute)
+		return true;
+
+	bios_wr32(bios, reg, val);
+	return true;
+}
+
+static bool
+init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_AUXCH   opcode: 0x98 ('')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): address
+	 * offset + 5  (8  bit): count
+	 * offset + 6  (8  bit): mask 0
+	 * offset + 7  (8  bit): data 0
+	 *  ...
+	 *
+	 */
+
+	struct drm_device *dev = bios->dev;
+	struct nouveau_i2c_chan *auxch;
+	uint32_t addr = ROM32(bios->data[offset + 1]);
+	uint8_t len = bios->data[offset + 5];
+	int ret, i;
+
+	if (!bios->display.output) {
+		NV_ERROR(dev, "INIT_AUXCH: no active output\n");
+		return false;
+	}
+
+	auxch = init_i2c_device_find(dev, bios->display.output->i2c_index);
+	if (!auxch) {
+		NV_ERROR(dev, "INIT_AUXCH: couldn't get auxch %d\n",
+			 bios->display.output->i2c_index);
+		return false;
+	}
+
+	if (!iexec->execute)
+		return true;
+
+	offset += 6;
+	for (i = 0; i < len; i++, offset += 2) {
+		uint8_t data;
+
+		ret = nouveau_dp_auxch(auxch, 9, addr, &data, 1);
+		if (ret) {
+			NV_ERROR(dev, "INIT_AUXCH: rd auxch fail %d\n", ret);
+			return false;
+		}
+
+		data &= bios->data[offset + 0];
+		data |= bios->data[offset + 1];
+
+		ret = nouveau_dp_auxch(auxch, 8, addr, &data, 1);
+		if (ret) {
+			NV_ERROR(dev, "INIT_AUXCH: wr auxch fail %d\n", ret);
+			return false;
+		}
+	}
+
+	return true;
+}
+
+static bool
+init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_ZM_AUXCH   opcode: 0x99 ('')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): address
+	 * offset + 5  (8  bit): count
+	 * offset + 6  (8  bit): data 0
+	 *  ...
+	 *
+	 */
+
+	struct drm_device *dev = bios->dev;
+	struct nouveau_i2c_chan *auxch;
+	uint32_t addr = ROM32(bios->data[offset + 1]);
+	uint8_t len = bios->data[offset + 5];
+	int ret, i;
+
+	if (!bios->display.output) {
+		NV_ERROR(dev, "INIT_ZM_AUXCH: no active output\n");
+		return false;
+	}
+
+	auxch = init_i2c_device_find(dev, bios->display.output->i2c_index);
+	if (!auxch) {
+		NV_ERROR(dev, "INIT_ZM_AUXCH: couldn't get auxch %d\n",
+			 bios->display.output->i2c_index);
+		return false;
+	}
+
+	if (!iexec->execute)
+		return true;
+
+	offset += 6;
+	for (i = 0; i < len; i++, offset++) {
+		ret = nouveau_dp_auxch(auxch, 8, addr, &bios->data[offset], 1);
+		if (ret) {
+			NV_ERROR(dev, "INIT_ZM_AUXCH: wr auxch fail %d\n", ret);
+			return false;
+		}
+	}
+
+	return true;
+}
+
+static struct init_tbl_entry itbl_entry[] = {
+	/* command name                       , id  , length  , offset  , mult    , command handler                 */
+	/* INIT_PROG (0x31, 15, 10, 4) removed due to no example of use */
+	{ "INIT_IO_RESTRICT_PROG"             , 0x32, 11      , 6       , 4       , init_io_restrict_prog           },
+	{ "INIT_REPEAT"                       , 0x33, 2       , 0       , 0       , init_repeat                     },
+	{ "INIT_IO_RESTRICT_PLL"              , 0x34, 12      , 7       , 2       , init_io_restrict_pll            },
+	{ "INIT_END_REPEAT"                   , 0x36, 1       , 0       , 0       , init_end_repeat                 },
+	{ "INIT_COPY"                         , 0x37, 11      , 0       , 0       , init_copy                       },
+	{ "INIT_NOT"                          , 0x38, 1       , 0       , 0       , init_not                        },
+	{ "INIT_IO_FLAG_CONDITION"            , 0x39, 2       , 0       , 0       , init_io_flag_condition          },
+	{ "INIT_INDEX_ADDRESS_LATCHED"        , 0x49, 18      , 17      , 2       , init_idx_addr_latched           },
+	{ "INIT_IO_RESTRICT_PLL2"             , 0x4A, 11      , 6       , 4       , init_io_restrict_pll2           },
+	{ "INIT_PLL2"                         , 0x4B, 9       , 0       , 0       , init_pll2                       },
+	{ "INIT_I2C_BYTE"                     , 0x4C, 4       , 3       , 3       , init_i2c_byte                   },
+	{ "INIT_ZM_I2C_BYTE"                  , 0x4D, 4       , 3       , 2       , init_zm_i2c_byte                },
+	{ "INIT_ZM_I2C"                       , 0x4E, 4       , 3       , 1       , init_zm_i2c                     },
+	{ "INIT_TMDS"                         , 0x4F, 5       , 0       , 0       , init_tmds                       },
+	{ "INIT_ZM_TMDS_GROUP"                , 0x50, 3       , 2       , 2       , init_zm_tmds_group              },
+	{ "INIT_CR_INDEX_ADDRESS_LATCHED"     , 0x51, 5       , 4       , 1       , init_cr_idx_adr_latch           },
+	{ "INIT_CR"                           , 0x52, 4       , 0       , 0       , init_cr                         },
+	{ "INIT_ZM_CR"                        , 0x53, 3       , 0       , 0       , init_zm_cr                      },
+	{ "INIT_ZM_CR_GROUP"                  , 0x54, 2       , 1       , 2       , init_zm_cr_group                },
+	{ "INIT_CONDITION_TIME"               , 0x56, 3       , 0       , 0       , init_condition_time             },
+	{ "INIT_ZM_REG_SEQUENCE"              , 0x58, 6       , 5       , 4       , init_zm_reg_sequence            },
+	/* INIT_INDIRECT_REG (0x5A, 7, 0, 0) removed due to no example of use */
+	{ "INIT_SUB_DIRECT"                   , 0x5B, 3       , 0       , 0       , init_sub_direct                 },
+	{ "INIT_COPY_NV_REG"                  , 0x5F, 22      , 0       , 0       , init_copy_nv_reg                },
+	{ "INIT_ZM_INDEX_IO"                  , 0x62, 5       , 0       , 0       , init_zm_index_io                },
+	{ "INIT_COMPUTE_MEM"                  , 0x63, 1       , 0       , 0       , init_compute_mem                },
+	{ "INIT_RESET"                        , 0x65, 13      , 0       , 0       , init_reset                      },
+	{ "INIT_CONFIGURE_MEM"                , 0x66, 1       , 0       , 0       , init_configure_mem              },
+	{ "INIT_CONFIGURE_CLK"                , 0x67, 1       , 0       , 0       , init_configure_clk              },
+	{ "INIT_CONFIGURE_PREINIT"            , 0x68, 1       , 0       , 0       , init_configure_preinit          },
+	{ "INIT_IO"                           , 0x69, 5       , 0       , 0       , init_io                         },
+	{ "INIT_SUB"                          , 0x6B, 2       , 0       , 0       , init_sub                        },
+	{ "INIT_RAM_CONDITION"                , 0x6D, 3       , 0       , 0       , init_ram_condition              },
+	{ "INIT_NV_REG"                       , 0x6E, 13      , 0       , 0       , init_nv_reg                     },
+	{ "INIT_MACRO"                        , 0x6F, 2       , 0       , 0       , init_macro                      },
+	{ "INIT_DONE"                         , 0x71, 1       , 0       , 0       , init_done                       },
+	{ "INIT_RESUME"                       , 0x72, 1       , 0       , 0       , init_resume                     },
+	/* INIT_RAM_CONDITION2 (0x73, 9, 0, 0) removed due to no example of use */
+	{ "INIT_TIME"                         , 0x74, 3       , 0       , 0       , init_time                       },
+	{ "INIT_CONDITION"                    , 0x75, 2       , 0       , 0       , init_condition                  },
+	{ "INIT_IO_CONDITION"                 , 0x76, 2       , 0       , 0       , init_io_condition               },
+	{ "INIT_INDEX_IO"                     , 0x78, 6       , 0       , 0       , init_index_io                   },
+	{ "INIT_PLL"                          , 0x79, 7       , 0       , 0       , init_pll                        },
+	{ "INIT_ZM_REG"                       , 0x7A, 9       , 0       , 0       , init_zm_reg                     },
+	/* INIT_RAM_RESTRICT_PLL's length is adjusted by the BIT M table */
+	{ "INIT_RAM_RESTRICT_PLL"             , 0x87, 2       , 0       , 0       , init_ram_restrict_pll           },
+	{ "INIT_8C"                           , 0x8C, 1       , 0       , 0       , init_8c                         },
+	{ "INIT_8D"                           , 0x8D, 1       , 0       , 0       , init_8d                         },
+	{ "INIT_GPIO"                         , 0x8E, 1       , 0       , 0       , init_gpio                       },
+	/* INIT_RAM_RESTRICT_ZM_REG_GROUP's mult is loaded by M table in BIT */
+	{ "INIT_RAM_RESTRICT_ZM_REG_GROUP"    , 0x8F, 7       , 6       , 0       , init_ram_restrict_zm_reg_group  },
+	{ "INIT_COPY_ZM_REG"                  , 0x90, 9       , 0       , 0       , init_copy_zm_reg                },
+	{ "INIT_ZM_REG_GROUP_ADDRESS_LATCHED" , 0x91, 6       , 5       , 4       , init_zm_reg_group_addr_latched  },
+	{ "INIT_RESERVED"                     , 0x92, 1       , 0       , 0       , init_reserved                   },
+	{ "INIT_96"                           , 0x96, 17      , 0       , 0       , init_96                         },
+	{ "INIT_97"                           , 0x97, 13      , 0       , 0       , init_97                         },
+	{ "INIT_AUXCH"                        , 0x98, 6       , 5       , 2       , init_auxch                      },
+	{ "INIT_ZM_AUXCH"                     , 0x99, 6       , 5       , 1       , init_zm_auxch                   },
+	{ NULL                                , 0   , 0       , 0       , 0       , NULL                            }
+};
+
+static unsigned int get_init_table_entry_length(struct nvbios *bios, unsigned int offset, int i)
+{
+	/* Calculates the length of a given init table entry. */
+	return itbl_entry[i].length + bios->data[offset + itbl_entry[i].length_offset]*itbl_entry[i].length_multiplier;
+}
+
+#define MAX_TABLE_OPS 1000
+
+static int
+parse_init_table(struct nvbios *bios, unsigned int offset,
+		 struct init_exec *iexec)
+{
+	/*
+	 * Parses all commands in an init table.
+	 *
+	 * We start out executing all commands found in the init table. Some
+	 * opcodes may change the status of iexec->execute to SKIP, which will
+	 * cause the following opcodes to perform no operation until the value
+	 * is changed back to EXECUTE.
+	 */
+
+	int count = 0, i;
+	uint8_t id;
+
+	/*
+	 * Loop until INIT_DONE causes us to break out of the loop
+	 * (or until offset > bios length just in case... )
+	 * (and no more than MAX_TABLE_OPS iterations, just in case... )
+	 */
+	while ((offset < bios->length) && (count++ < MAX_TABLE_OPS)) {
+		id = bios->data[offset];
+
+		/* Find matching id in itbl_entry */
+		for (i = 0; itbl_entry[i].name && (itbl_entry[i].id != id); i++)
+			;
+
+		if (itbl_entry[i].name) {
+			BIOSLOG(bios, "0x%04X: [ (0x%02X) - %s ]\n",
+				offset, itbl_entry[i].id, itbl_entry[i].name);
+
+			/* execute eventual command handler */
+			if (itbl_entry[i].handler)
+				if (!(*itbl_entry[i].handler)(bios, offset, iexec))
+					break;
+		} else {
+			NV_ERROR(bios->dev,
+				 "0x%04X: Init table command not found: "
+				 "0x%02X\n", offset, id);
+			return -ENOENT;
+		}
+
+		/*
+		 * Add the offset of the current command including all data
+		 * of that command. The offset will then be pointing on the
+		 * next op code.
+		 */
+		offset += get_init_table_entry_length(bios, offset, i);
+	}
+
+	if (offset >= bios->length)
+		NV_WARN(bios->dev,
+			"Offset 0x%04X greater than known bios image length.  "
+			"Corrupt image?\n", offset);
+	if (count >= MAX_TABLE_OPS)
+		NV_WARN(bios->dev,
+			"More than %d opcodes to a table is unlikely, "
+			"is the bios image corrupt?\n", MAX_TABLE_OPS);
+
+	return 0;
+}
+
+static void
+parse_init_tables(struct nvbios *bios)
+{
+	/* Loops and calls parse_init_table() for each present table. */
+
+	int i = 0;
+	uint16_t table;
+	struct init_exec iexec = {true, false};
+
+	if (bios->old_style_init) {
+		if (bios->init_script_tbls_ptr)
+			parse_init_table(bios, bios->init_script_tbls_ptr, &iexec);
+		if (bios->extra_init_script_tbl_ptr)
+			parse_init_table(bios, bios->extra_init_script_tbl_ptr, &iexec);
+
+		return;
+	}
+
+	while ((table = ROM16(bios->data[bios->init_script_tbls_ptr + i]))) {
+		NV_INFO(bios->dev,
+			"Parsing VBIOS init table %d at offset 0x%04X\n",
+			i / 2, table);
+		BIOSLOG(bios, "0x%04X: ------ Executing following commands ------\n", table);
+
+		parse_init_table(bios, table, &iexec);
+		i += 2;
+	}
+}
+
+static uint16_t clkcmptable(struct nvbios *bios, uint16_t clktable, int pxclk)
+{
+	int compare_record_len, i = 0;
+	uint16_t compareclk, scriptptr = 0;
+
+	if (bios->major_version < 5) /* pre BIT */
+		compare_record_len = 3;
+	else
+		compare_record_len = 4;
+
+	do {
+		compareclk = ROM16(bios->data[clktable + compare_record_len * i]);
+		if (pxclk >= compareclk * 10) {
+			if (bios->major_version < 5) {
+				uint8_t tmdssub = bios->data[clktable + 2 + compare_record_len * i];
+				scriptptr = ROM16(bios->data[bios->init_script_tbls_ptr + tmdssub * 2]);
+			} else
+				scriptptr = ROM16(bios->data[clktable + 2 + compare_record_len * i]);
+			break;
+		}
+		i++;
+	} while (compareclk);
+
+	return scriptptr;
+}
+
+static void
+run_digital_op_script(struct drm_device *dev, uint16_t scriptptr,
+		      struct dcb_entry *dcbent, int head, bool dl)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	struct init_exec iexec = {true, false};
+
+	NV_TRACE(dev, "0x%04X: Parsing digital output script table\n",
+		 scriptptr);
+	bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, NV_CIO_CRE_44,
+		       head ? NV_CIO_CRE_44_HEADB : NV_CIO_CRE_44_HEADA);
+	/* note: if dcb entries have been merged, index may be misleading */
+	NVWriteVgaCrtc5758(dev, head, 0, dcbent->index);
+	parse_init_table(bios, scriptptr, &iexec);
+
+	nv04_dfp_bind_head(dev, dcbent, head, dl);
+}
+
+static int call_lvds_manufacturer_script(struct drm_device *dev, struct dcb_entry *dcbent, int head, enum LVDS_script script)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	uint8_t sub = bios->data[bios->fp.xlated_entry + script] + (bios->fp.link_c_increment && dcbent->or & OUTPUT_C ? 1 : 0);
+	uint16_t scriptofs = ROM16(bios->data[bios->init_script_tbls_ptr + sub * 2]);
+
+	if (!bios->fp.xlated_entry || !sub || !scriptofs)
+		return -EINVAL;
+
+	run_digital_op_script(dev, scriptofs, dcbent, head, bios->fp.dual_link);
+
+	if (script == LVDS_PANEL_OFF) {
+		/* off-on delay in ms */
+		msleep(ROM16(bios->data[bios->fp.xlated_entry + 7]));
+	}
+#ifdef __powerpc__
+	/* Powerbook specific quirks */
+	if (script == LVDS_RESET && ((dev->pci_device & 0xffff) == 0x0179 || (dev->pci_device & 0xffff) == 0x0329))
+		nv_write_tmds(dev, dcbent->or, 0, 0x02, 0x72);
+	if ((dev->pci_device & 0xffff) == 0x0179 || (dev->pci_device & 0xffff) == 0x0189 || (dev->pci_device & 0xffff) == 0x0329) {
+		if (script == LVDS_PANEL_ON) {
+			bios_wr32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL, bios_rd32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL) | (1 << 31));
+			bios_wr32(bios, NV_PCRTC_GPIO_EXT, bios_rd32(bios, NV_PCRTC_GPIO_EXT) | 1);
+		}
+		if (script == LVDS_PANEL_OFF) {
+			bios_wr32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL, bios_rd32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL) & ~(1 << 31));
+			bios_wr32(bios, NV_PCRTC_GPIO_EXT, bios_rd32(bios, NV_PCRTC_GPIO_EXT) & ~3);
+		}
+	}
+#endif
+
+	return 0;
+}
+
+static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int head, enum LVDS_script script, int pxclk)
+{
+	/*
+	 * The BIT LVDS table's header has the information to setup the
+	 * necessary registers. Following the standard 4 byte header are:
+	 * A bitmask byte and a dual-link transition pxclk value for use in
+	 * selecting the init script when not using straps; 4 script pointers
+	 * for panel power, selected by output and on/off; and 8 table pointers
+	 * for panel init, the needed one determined by output, and bits in the
+	 * conf byte. These tables are similar to the TMDS tables, consisting
+	 * of a list of pxclks and script pointers.
+	 */
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	unsigned int outputset = (dcbent->or == 4) ? 1 : 0;
+	uint16_t scriptptr = 0, clktable;
+	uint8_t clktableptr = 0;
+
+	/*
+	 * For now we assume version 3.0 table - g80 support will need some
+	 * changes
+	 */
+
+	switch (script) {
+	case LVDS_INIT:
+		return -ENOSYS;
+	case LVDS_BACKLIGHT_ON:
+	case LVDS_PANEL_ON:
+		scriptptr = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 7 + outputset * 2]);
+		break;
+	case LVDS_BACKLIGHT_OFF:
+	case LVDS_PANEL_OFF:
+		scriptptr = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 11 + outputset * 2]);
+		break;
+	case LVDS_RESET:
+		if (dcbent->lvdsconf.use_straps_for_mode) {
+			if (bios->fp.dual_link)
+				clktableptr += 2;
+			if (bios->fp.BITbit1)
+				clktableptr++;
+		} else {
+			/* using EDID */
+			uint8_t fallback = bios->data[bios->fp.lvdsmanufacturerpointer + 4];
+			int fallbackcmpval = (dcbent->or == 4) ? 4 : 1;
+
+			if (bios->fp.dual_link) {
+				clktableptr += 2;
+				fallbackcmpval *= 2;
+			}
+			if (fallbackcmpval & fallback)
+				clktableptr++;
+		}
+
+		/* adding outputset * 8 may not be correct */
+		clktable = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 15 + clktableptr * 2 + outputset * 8]);
+		if (!clktable) {
+			NV_ERROR(dev, "Pixel clock comparison table not found\n");
+			return -ENOENT;
+		}
+		scriptptr = clkcmptable(bios, clktable, pxclk);
+	}
+
+	if (!scriptptr) {
+		NV_ERROR(dev, "LVDS output init script not found\n");
+		return -ENOENT;
+	}
+	run_digital_op_script(dev, scriptptr, dcbent, head, bios->fp.dual_link);
+
+	return 0;
+}
+
+int call_lvds_script(struct drm_device *dev, struct dcb_entry *dcbent, int head, enum LVDS_script script, int pxclk)
+{
+	/*
+	 * LVDS operations are multiplexed in an effort to present a single API
+	 * which works with two vastly differing underlying structures.
+	 * This acts as the demux
+	 */
+
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	uint8_t lvds_ver = bios->data[bios->fp.lvdsmanufacturerpointer];
+	uint32_t sel_clk_binding, sel_clk;
+	int ret;
+
+	if (bios->fp.last_script_invoc == (script << 1 | head) || !lvds_ver ||
+	    (lvds_ver >= 0x30 && script == LVDS_INIT))
+		return 0;
+
+	if (!bios->fp.lvds_init_run) {
+		bios->fp.lvds_init_run = true;
+		call_lvds_script(dev, dcbent, head, LVDS_INIT, pxclk);
+	}
+
+	if (script == LVDS_PANEL_ON && bios->fp.reset_after_pclk_change)
+		call_lvds_script(dev, dcbent, head, LVDS_RESET, pxclk);
+	if (script == LVDS_RESET && bios->fp.power_off_for_reset)
+		call_lvds_script(dev, dcbent, head, LVDS_PANEL_OFF, pxclk);
+
+	NV_TRACE(dev, "Calling LVDS script %d:\n", script);
+
+	/* don't let script change pll->head binding */
+	sel_clk_binding = bios_rd32(bios, NV_PRAMDAC_SEL_CLK) & 0x50000;
+
+	if (lvds_ver < 0x30)
+		ret = call_lvds_manufacturer_script(dev, dcbent, head, script);
+	else
+		ret = run_lvds_table(dev, dcbent, head, script, pxclk);
+
+	bios->fp.last_script_invoc = (script << 1 | head);
+
+	sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK) & ~0x50000;
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, sel_clk | sel_clk_binding);
+	/* some scripts set a value in NV_PBUS_POWERCTRL_2 and break video overlay */
+	nvWriteMC(dev, NV_PBUS_POWERCTRL_2, 0);
+
+	return ret;
+}
+
+struct lvdstableheader {
+	uint8_t lvds_ver, headerlen, recordlen;
+};
+
+static int parse_lvds_manufacturer_table_header(struct drm_device *dev, struct nvbios *bios, struct lvdstableheader *lth)
+{
+	/*
+	 * BMP version (0xa) LVDS table has a simple header of version and
+	 * record length. The BIT LVDS table has the typical BIT table header:
+	 * version byte, header length byte, record length byte, and a byte for
+	 * the maximum number of records that can be held in the table.
+	 */
+
+	uint8_t lvds_ver, headerlen, recordlen;
+
+	memset(lth, 0, sizeof(struct lvdstableheader));
+
+	if (bios->fp.lvdsmanufacturerpointer == 0x0) {
+		NV_ERROR(dev, "Pointer to LVDS manufacturer table invalid\n");
+		return -EINVAL;
+	}
+
+	lvds_ver = bios->data[bios->fp.lvdsmanufacturerpointer];
+
+	switch (lvds_ver) {
+	case 0x0a:	/* pre NV40 */
+		headerlen = 2;
+		recordlen = bios->data[bios->fp.lvdsmanufacturerpointer + 1];
+		break;
+	case 0x30:	/* NV4x */
+		headerlen = bios->data[bios->fp.lvdsmanufacturerpointer + 1];
+		if (headerlen < 0x1f) {
+			NV_ERROR(dev, "LVDS table header not understood\n");
+			return -EINVAL;
+		}
+		recordlen = bios->data[bios->fp.lvdsmanufacturerpointer + 2];
+		break;
+	case 0x40:	/* G80/G90 */
+		headerlen = bios->data[bios->fp.lvdsmanufacturerpointer + 1];
+		if (headerlen < 0x7) {
+			NV_ERROR(dev, "LVDS table header not understood\n");
+			return -EINVAL;
+		}
+		recordlen = bios->data[bios->fp.lvdsmanufacturerpointer + 2];
+		break;
+	default:
+		NV_ERROR(dev,
+			 "LVDS table revision %d.%d not currently supported\n",
+			 lvds_ver >> 4, lvds_ver & 0xf);
+		return -ENOSYS;
+	}
+
+	lth->lvds_ver = lvds_ver;
+	lth->headerlen = headerlen;
+	lth->recordlen = recordlen;
+
+	return 0;
+}
+
+static int
+get_fp_strap(struct drm_device *dev, struct nvbios *bios)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	/*
+	 * The fp strap is normally dictated by the "User Strap" in
+	 * PEXTDEV_BOOT_0[20:16], but on BMP cards when bit 2 of the
+	 * Internal_Flags struct at 0x48 is set, the user strap gets overriden
+	 * by the PCI subsystem ID during POST, but not before the previous user
+	 * strap has been committed to CR58 for CR57=0xf on head A, which may be
+	 * read and used instead
+	 */
+
+	if (bios->major_version < 5 && bios->data[0x48] & 0x4)
+		return NVReadVgaCrtc5758(dev, 0, 0xf) & 0xf;
+
+	if (dev_priv->card_type >= NV_50)
+		return (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 24) & 0xf;
+	else
+		return (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 16) & 0xf;
+}
+
+static int parse_fp_mode_table(struct drm_device *dev, struct nvbios *bios)
+{
+	uint8_t *fptable;
+	uint8_t fptable_ver, headerlen = 0, recordlen, fpentries = 0xf, fpindex;
+	int ret, ofs, fpstrapping;
+	struct lvdstableheader lth;
+
+	if (bios->fp.fptablepointer == 0x0) {
+		/* Apple cards don't have the fp table; the laptops use DDC */
+		/* The table is also missing on some x86 IGPs */
+#ifndef __powerpc__
+		NV_ERROR(dev, "Pointer to flat panel table invalid\n");
+#endif
+		bios->pub.digital_min_front_porch = 0x4b;
+		return 0;
+	}
+
+	fptable = &bios->data[bios->fp.fptablepointer];
+	fptable_ver = fptable[0];
+
+	switch (fptable_ver) {
+	/*
+	 * BMP version 0x5.0x11 BIOSen have version 1 like tables, but no
+	 * version field, and miss one of the spread spectrum/PWM bytes.
+	 * This could affect early GF2Go parts (not seen any appropriate ROMs
+	 * though). Here we assume that a version of 0x05 matches this case
+	 * (combining with a BMP version check would be better), as the
+	 * common case for the panel type field is 0x0005, and that is in
+	 * fact what we are reading the first byte of.
+	 */
+	case 0x05:	/* some NV10, 11, 15, 16 */
+		recordlen = 42;
+		ofs = -1;
+		break;
+	case 0x10:	/* some NV15/16, and NV11+ */
+		recordlen = 44;
+		ofs = 0;
+		break;
+	case 0x20:	/* NV40+ */
+		headerlen = fptable[1];
+		recordlen = fptable[2];
+		fpentries = fptable[3];
+		/*
+		 * fptable[4] is the minimum
+		 * RAMDAC_FP_HCRTC -> RAMDAC_FP_HSYNC_START gap
+		 */
+		bios->pub.digital_min_front_porch = fptable[4];
+		ofs = -7;
+		break;
+	default:
+		NV_ERROR(dev,
+			 "FP table revision %d.%d not currently supported\n",
+			 fptable_ver >> 4, fptable_ver & 0xf);
+		return -ENOSYS;
+	}
+
+	if (!bios->is_mobile) /* !mobile only needs digital_min_front_porch */
+		return 0;
+
+	ret = parse_lvds_manufacturer_table_header(dev, bios, &lth);
+	if (ret)
+		return ret;
+
+	if (lth.lvds_ver == 0x30 || lth.lvds_ver == 0x40) {
+		bios->fp.fpxlatetableptr = bios->fp.lvdsmanufacturerpointer +
+							lth.headerlen + 1;
+		bios->fp.xlatwidth = lth.recordlen;
+	}
+	if (bios->fp.fpxlatetableptr == 0x0) {
+		NV_ERROR(dev, "Pointer to flat panel xlat table invalid\n");
+		return -EINVAL;
+	}
+
+	fpstrapping = get_fp_strap(dev, bios);
+
+	fpindex = bios->data[bios->fp.fpxlatetableptr +
+					fpstrapping * bios->fp.xlatwidth];
+
+	if (fpindex > fpentries) {
+		NV_ERROR(dev, "Bad flat panel table index\n");
+		return -ENOENT;
+	}
+
+	/* nv4x cards need both a strap value and fpindex of 0xf to use DDC */
+	if (lth.lvds_ver > 0x10)
+		bios->pub.fp_no_ddc = fpstrapping != 0xf || fpindex != 0xf;
+
+	/*
+	 * If either the strap or xlated fpindex value are 0xf there is no
+	 * panel using a strap-derived bios mode present.  this condition
+	 * includes, but is different from, the DDC panel indicator above
+	 */
+	if (fpstrapping == 0xf || fpindex == 0xf)
+		return 0;
+
+	bios->fp.mode_ptr = bios->fp.fptablepointer + headerlen +
+			    recordlen * fpindex + ofs;
+
+	NV_TRACE(dev, "BIOS FP mode: %dx%d (%dkHz pixel clock)\n",
+		 ROM16(bios->data[bios->fp.mode_ptr + 11]) + 1,
+		 ROM16(bios->data[bios->fp.mode_ptr + 25]) + 1,
+		 ROM16(bios->data[bios->fp.mode_ptr + 7]) * 10);
+
+	return 0;
+}
+
+bool nouveau_bios_fp_mode(struct drm_device *dev, struct drm_display_mode *mode)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	uint8_t *mode_entry = &bios->data[bios->fp.mode_ptr];
+
+	if (!mode)	/* just checking whether we can produce a mode */
+		return bios->fp.mode_ptr;
+
+	memset(mode, 0, sizeof(struct drm_display_mode));
+	/*
+	 * For version 1.0 (version in byte 0):
+	 * bytes 1-2 are "panel type", including bits on whether Colour/mono,
+	 * single/dual link, and type (TFT etc.)
+	 * bytes 3-6 are bits per colour in RGBX
+	 */
+	mode->clock = ROM16(mode_entry[7]) * 10;
+	/* bytes 9-10 is HActive */
+	mode->hdisplay = ROM16(mode_entry[11]) + 1;
+	/*
+	 * bytes 13-14 is HValid Start
+	 * bytes 15-16 is HValid End
+	 */
+	mode->hsync_start = ROM16(mode_entry[17]) + 1;
+	mode->hsync_end = ROM16(mode_entry[19]) + 1;
+	mode->htotal = ROM16(mode_entry[21]) + 1;
+	/* bytes 23-24, 27-30 similarly, but vertical */
+	mode->vdisplay = ROM16(mode_entry[25]) + 1;
+	mode->vsync_start = ROM16(mode_entry[31]) + 1;
+	mode->vsync_end = ROM16(mode_entry[33]) + 1;
+	mode->vtotal = ROM16(mode_entry[35]) + 1;
+	mode->flags |= (mode_entry[37] & 0x10) ?
+			DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC;
+	mode->flags |= (mode_entry[37] & 0x1) ?
+			DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC;
+	/*
+	 * bytes 38-39 relate to spread spectrum settings
+	 * bytes 40-43 are something to do with PWM
+	 */
+
+	mode->status = MODE_OK;
+	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+	drm_mode_set_name(mode);
+	return bios->fp.mode_ptr;
+}
+
+int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, bool *if_is_24bit)
+{
+	/*
+	 * The LVDS table header is (mostly) described in
+	 * parse_lvds_manufacturer_table_header(): the BIT header additionally
+	 * contains the dual-link transition pxclk (in 10s kHz), at byte 5 - if
+	 * straps are not being used for the panel, this specifies the frequency
+	 * at which modes should be set up in the dual link style.
+	 *
+	 * Following the header, the BMP (ver 0xa) table has several records,
+	 * indexed by a seperate xlat table, indexed in turn by the fp strap in
+	 * EXTDEV_BOOT. Each record had a config byte, followed by 6 script
+	 * numbers for use by INIT_SUB which controlled panel init and power,
+	 * and finally a dword of ms to sleep between power off and on
+	 * operations.
+	 *
+	 * In the BIT versions, the table following the header serves as an
+	 * integrated config and xlat table: the records in the table are
+	 * indexed by the FP strap nibble in EXTDEV_BOOT, and each record has
+	 * two bytes - the first as a config byte, the second for indexing the
+	 * fp mode table pointed to by the BIT 'D' table
+	 *
+	 * DDC is not used until after card init, so selecting the correct table
+	 * entry and setting the dual link flag for EDID equipped panels,
+	 * requiring tests against the native-mode pixel clock, cannot be done
+	 * until later, when this function should be called with non-zero pxclk
+	 */
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	int fpstrapping = get_fp_strap(dev, bios), lvdsmanufacturerindex = 0;
+	struct lvdstableheader lth;
+	uint16_t lvdsofs;
+	int ret, chip_version = bios->pub.chip_version;
+
+	ret = parse_lvds_manufacturer_table_header(dev, bios, &lth);
+	if (ret)
+		return ret;
+
+	switch (lth.lvds_ver) {
+	case 0x0a:	/* pre NV40 */
+		lvdsmanufacturerindex = bios->data[
+					bios->fp.fpxlatemanufacturertableptr +
+					fpstrapping];
+
+		/* we're done if this isn't the EDID panel case */
+		if (!pxclk)
+			break;
+
+		if (chip_version < 0x25) {
+			/* nv17 behaviour
+			 *
+			 * It seems the old style lvds script pointer is reused
+			 * to select 18/24 bit colour depth for EDID panels.
+			 */
+			lvdsmanufacturerindex =
+				(bios->legacy.lvds_single_a_script_ptr & 1) ?
+									2 : 0;
+			if (pxclk >= bios->fp.duallink_transition_clk)
+				lvdsmanufacturerindex++;
+		} else if (chip_version < 0x30) {
+			/* nv28 behaviour (off-chip encoder)
+			 *
+			 * nv28 does a complex dance of first using byte 121 of
+			 * the EDID to choose the lvdsmanufacturerindex, then
+			 * later attempting to match the EDID manufacturer and
+			 * product IDs in a table (signature 'pidt' (panel id
+			 * table?)), setting an lvdsmanufacturerindex of 0 and
+			 * an fp strap of the match index (or 0xf if none)
+			 */
+			lvdsmanufacturerindex = 0;
+		} else {
+			/* nv31, nv34 behaviour */
+			lvdsmanufacturerindex = 0;
+			if (pxclk >= bios->fp.duallink_transition_clk)
+				lvdsmanufacturerindex = 2;
+			if (pxclk >= 140000)
+				lvdsmanufacturerindex = 3;
+		}
+
+		/*
+		 * nvidia set the high nibble of (cr57=f, cr58) to
+		 * lvdsmanufacturerindex in this case; we don't
+		 */
+		break;
+	case 0x30:	/* NV4x */
+	case 0x40:	/* G80/G90 */
+		lvdsmanufacturerindex = fpstrapping;
+		break;
+	default:
+		NV_ERROR(dev, "LVDS table revision not currently supported\n");
+		return -ENOSYS;
+	}
+
+	lvdsofs = bios->fp.xlated_entry = bios->fp.lvdsmanufacturerpointer + lth.headerlen + lth.recordlen * lvdsmanufacturerindex;
+	switch (lth.lvds_ver) {
+	case 0x0a:
+		bios->fp.power_off_for_reset = bios->data[lvdsofs] & 1;
+		bios->fp.reset_after_pclk_change = bios->data[lvdsofs] & 2;
+		bios->fp.dual_link = bios->data[lvdsofs] & 4;
+		bios->fp.link_c_increment = bios->data[lvdsofs] & 8;
+		*if_is_24bit = bios->data[lvdsofs] & 16;
+		break;
+	case 0x30:
+		/*
+		 * My money would be on there being a 24 bit interface bit in
+		 * this table, but I have no example of a laptop bios with a
+		 * 24 bit panel to confirm that. Hence we shout loudly if any
+		 * bit other than bit 0 is set (I've not even seen bit 1)
+		 */
+		if (bios->data[lvdsofs] > 1)
+			NV_ERROR(dev,
+				 "You have a very unusual laptop display; please report it\n");
+		/*
+		 * No sign of the "power off for reset" or "reset for panel
+		 * on" bits, but it's safer to assume we should
+		 */
+		bios->fp.power_off_for_reset = true;
+		bios->fp.reset_after_pclk_change = true;
+		/*
+		 * It's ok lvdsofs is wrong for nv4x edid case; dual_link is
+		 * over-written, and BITbit1 isn't used
+		 */
+		bios->fp.dual_link = bios->data[lvdsofs] & 1;
+		bios->fp.BITbit1 = bios->data[lvdsofs] & 2;
+		bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10;
+		break;
+	case 0x40:
+		bios->fp.dual_link = bios->data[lvdsofs] & 1;
+		bios->fp.if_is_24bit = bios->data[lvdsofs] & 2;
+		bios->fp.strapless_is_24bit = bios->data[bios->fp.lvdsmanufacturerpointer + 4];
+		bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10;
+		break;
+	}
+
+	/* set dual_link flag for EDID case */
+	if (pxclk && (chip_version < 0x25 || chip_version > 0x28))
+		bios->fp.dual_link = (pxclk >= bios->fp.duallink_transition_clk);
+
+	*dl = bios->fp.dual_link;
+
+	return 0;
+}
+
+static uint8_t *
+bios_output_config_match(struct drm_device *dev, struct dcb_entry *dcbent,
+			 uint16_t record, int record_len, int record_nr)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	uint32_t entry;
+	uint16_t table;
+	int i, v;
+
+	for (i = 0; i < record_nr; i++, record += record_len) {
+		table = ROM16(bios->data[record]);
+		if (!table)
+			continue;
+		entry = ROM32(bios->data[table]);
+
+		v = (entry & 0x000f0000) >> 16;
+		if (!(v & dcbent->or))
+			continue;
+
+		v = (entry & 0x000000f0) >> 4;
+		if (v != dcbent->location)
+			continue;
+
+		v = (entry & 0x0000000f);
+		if (v != dcbent->type)
+			continue;
+
+		return &bios->data[table];
+	}
+
+	return NULL;
+}
+
+void *
+nouveau_bios_dp_table(struct drm_device *dev, struct dcb_entry *dcbent,
+		      int *length)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	uint8_t *table;
+
+	if (!bios->display.dp_table_ptr) {
+		NV_ERROR(dev, "No pointer to DisplayPort table\n");
+		return NULL;
+	}
+	table = &bios->data[bios->display.dp_table_ptr];
+
+	if (table[0] != 0x21) {
+		NV_ERROR(dev, "DisplayPort table version 0x%02x unknown\n",
+			 table[0]);
+		return NULL;
+	}
+
+	*length = table[4];
+	return bios_output_config_match(dev, dcbent,
+					bios->display.dp_table_ptr + table[1],
+					table[2], table[3]);
+}
+
+int
+nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
+			       uint32_t sub, int pxclk)
+{
+	/*
+	 * The display script table is located by the BIT 'U' table.
+	 *
+	 * It contains an array of pointers to various tables describing
+	 * a particular output type.  The first 32-bits of the output
+	 * tables contains similar information to a DCB entry, and is
+	 * used to decide whether that particular table is suitable for
+	 * the output you want to access.
+	 *
+	 * The "record header length" field here seems to indicate the
+	 * offset of the first configuration entry in the output tables.
+	 * This is 10 on most cards I've seen, but 12 has been witnessed
+	 * on DP cards, and there's another script pointer within the
+	 * header.
+	 *
+	 * offset + 0   ( 8 bits): version
+	 * offset + 1   ( 8 bits): header length
+	 * offset + 2   ( 8 bits): record length
+	 * offset + 3   ( 8 bits): number of records
+	 * offset + 4   ( 8 bits): record header length
+	 * offset + 5   (16 bits): pointer to first output script table
+	 */
+
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct init_exec iexec = {true, false};
+	struct nvbios *bios = &dev_priv->VBIOS;
+	uint8_t *table = &bios->data[bios->display.script_table_ptr];
+	uint8_t *otable = NULL;
+	uint16_t script;
+	int i = 0;
+
+	if (!bios->display.script_table_ptr) {
+		NV_ERROR(dev, "No pointer to output script table\n");
+		return 1;
+	}
+
+	/*
+	 * Nothing useful has been in any of the pre-2.0 tables I've seen,
+	 * so until they are, we really don't need to care.
+	 */
+	if (table[0] < 0x20)
+		return 1;
+
+	if (table[0] != 0x20 && table[0] != 0x21) {
+		NV_ERROR(dev, "Output script table version 0x%02x unknown\n",
+			 table[0]);
+		return 1;
+	}
+
+	/*
+	 * The output script tables describing a particular output type
+	 * look as follows:
+	 *
+	 * offset + 0   (32 bits): output this table matches (hash of DCB)
+	 * offset + 4   ( 8 bits): unknown
+	 * offset + 5   ( 8 bits): number of configurations
+	 * offset + 6   (16 bits): pointer to some script
+	 * offset + 8   (16 bits): pointer to some script
+	 *
+	 * headerlen == 10
+	 * offset + 10           : configuration 0
+	 *
+	 * headerlen == 12
+	 * offset + 10           : pointer to some script
+	 * offset + 12           : configuration 0
+	 *
+	 * Each config entry is as follows:
+	 *
+	 * offset + 0   (16 bits): unknown, assumed to be a match value
+	 * offset + 2   (16 bits): pointer to script table (clock set?)
+	 * offset + 4   (16 bits): pointer to script table (reset?)
+	 *
+	 * There doesn't appear to be a count value to say how many
+	 * entries exist in each script table, instead, a 0 value in
+	 * the first 16-bit word seems to indicate both the end of the
+	 * list and the default entry.  The second 16-bit word in the
+	 * script tables is a pointer to the script to execute.
+	 */
+
+	NV_DEBUG(dev, "Searching for output entry for %d %d %d\n",
+			dcbent->type, dcbent->location, dcbent->or);
+	otable = bios_output_config_match(dev, dcbent, table[1] +
+					  bios->display.script_table_ptr,
+					  table[2], table[3]);
+	if (!otable) {
+		NV_ERROR(dev, "Couldn't find matching output script table\n");
+		return 1;
+	}
+
+	if (pxclk < -2 || pxclk > 0) {
+		/* Try to find matching script table entry */
+		for (i = 0; i < otable[5]; i++) {
+			if (ROM16(otable[table[4] + i*6]) == sub)
+				break;
+		}
+
+		if (i == otable[5]) {
+			NV_ERROR(dev, "Table 0x%04x not found for %d/%d, "
+				      "using first\n",
+				 sub, dcbent->type, dcbent->or);
+			i = 0;
+		}
+	}
+
+	bios->display.output = dcbent;
+
+	if (pxclk == 0) {
+		script = ROM16(otable[6]);
+		if (!script) {
+			NV_DEBUG(dev, "output script 0 not found\n");
+			return 1;
+		}
+
+		NV_TRACE(dev, "0x%04X: parsing output script 0\n", script);
+		parse_init_table(bios, script, &iexec);
+	} else
+	if (pxclk == -1) {
+		script = ROM16(otable[8]);
+		if (!script) {
+			NV_DEBUG(dev, "output script 1 not found\n");
+			return 1;
+		}
+
+		NV_TRACE(dev, "0x%04X: parsing output script 1\n", script);
+		parse_init_table(bios, script, &iexec);
+	} else
+	if (pxclk == -2) {
+		if (table[4] >= 12)
+			script = ROM16(otable[10]);
+		else
+			script = 0;
+		if (!script) {
+			NV_DEBUG(dev, "output script 2 not found\n");
+			return 1;
+		}
+
+		NV_TRACE(dev, "0x%04X: parsing output script 2\n", script);
+		parse_init_table(bios, script, &iexec);
+	} else
+	if (pxclk > 0) {
+		script = ROM16(otable[table[4] + i*6 + 2]);
+		if (script)
+			script = clkcmptable(bios, script, pxclk);
+		if (!script) {
+			NV_ERROR(dev, "clock script 0 not found\n");
+			return 1;
+		}
+
+		NV_TRACE(dev, "0x%04X: parsing clock script 0\n", script);
+		parse_init_table(bios, script, &iexec);
+	} else
+	if (pxclk < 0) {
+		script = ROM16(otable[table[4] + i*6 + 4]);
+		if (script)
+			script = clkcmptable(bios, script, -pxclk);
+		if (!script) {
+			NV_DEBUG(dev, "clock script 1 not found\n");
+			return 1;
+		}
+
+		NV_TRACE(dev, "0x%04X: parsing clock script 1\n", script);
+		parse_init_table(bios, script, &iexec);
+	}
+
+	return 0;
+}
+
+
+int run_tmds_table(struct drm_device *dev, struct dcb_entry *dcbent, int head, int pxclk)
+{
+	/*
+	 * the pxclk parameter is in kHz
+	 *
+	 * This runs the TMDS regs setting code found on BIT bios cards
+	 *
+	 * For ffs(or) == 1 use the first table, for ffs(or) == 2 and
+	 * ffs(or) == 3, use the second.
+	 */
+
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	int cv = bios->pub.chip_version;
+	uint16_t clktable = 0, scriptptr;
+	uint32_t sel_clk_binding, sel_clk;
+
+	/* pre-nv17 off-chip tmds uses scripts, post nv17 doesn't */
+	if (cv >= 0x17 && cv != 0x1a && cv != 0x20 &&
+	    dcbent->location != DCB_LOC_ON_CHIP)
+		return 0;
+
+	switch (ffs(dcbent->or)) {
+	case 1:
+		clktable = bios->tmds.output0_script_ptr;
+		break;
+	case 2:
+	case 3:
+		clktable = bios->tmds.output1_script_ptr;
+		break;
+	}
+
+	if (!clktable) {
+		NV_ERROR(dev, "Pixel clock comparison table not found\n");
+		return -EINVAL;
+	}
+
+	scriptptr = clkcmptable(bios, clktable, pxclk);
+
+	if (!scriptptr) {
+		NV_ERROR(dev, "TMDS output init script not found\n");
+		return -ENOENT;
+	}
+
+	/* don't let script change pll->head binding */
+	sel_clk_binding = bios_rd32(bios, NV_PRAMDAC_SEL_CLK) & 0x50000;
+	run_digital_op_script(dev, scriptptr, dcbent, head, pxclk >= 165000);
+	sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK) & ~0x50000;
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, sel_clk | sel_clk_binding);
+
+	return 0;
+}
+
+int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims *pll_lim)
+{
+	/*
+	 * PLL limits table
+	 *
+	 * Version 0x10: NV30, NV31
+	 * One byte header (version), one record of 24 bytes
+	 * Version 0x11: NV36 - Not implemented
+	 * Seems to have same record style as 0x10, but 3 records rather than 1
+	 * Version 0x20: Found on Geforce 6 cards
+	 * Trivial 4 byte BIT header. 31 (0x1f) byte record length
+	 * Version 0x21: Found on Geforce 7, 8 and some Geforce 6 cards
+	 * 5 byte header, fifth byte of unknown purpose. 35 (0x23) byte record
+	 * length in general, some (integrated) have an extra configuration byte
+	 * Version 0x30: Found on Geforce 8, separates the register mapping
+	 * from the limits tables.
+	 */
+
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	int cv = bios->pub.chip_version, pllindex = 0;
+	uint8_t pll_lim_ver = 0, headerlen = 0, recordlen = 0, entries = 0;
+	uint32_t crystal_strap_mask, crystal_straps;
+
+	if (!bios->pll_limit_tbl_ptr) {
+		if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 ||
+		    cv >= 0x40) {
+			NV_ERROR(dev, "Pointer to PLL limits table invalid\n");
+			return -EINVAL;
+		}
+	} else
+		pll_lim_ver = bios->data[bios->pll_limit_tbl_ptr];
+
+	crystal_strap_mask = 1 << 6;
+	/* open coded dev->twoHeads test */
+	if (cv > 0x10 && cv != 0x15 && cv != 0x1a && cv != 0x20)
+		crystal_strap_mask |= 1 << 22;
+	crystal_straps = nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) &
+							crystal_strap_mask;
+
+	switch (pll_lim_ver) {
+	/*
+	 * We use version 0 to indicate a pre limit table bios (single stage
+	 * pll) and load the hard coded limits instead.
+	 */
+	case 0:
+		break;
+	case 0x10:
+	case 0x11:
+		/*
+		 * Strictly v0x11 has 3 entries, but the last two don't seem
+		 * to get used.
+		 */
+		headerlen = 1;
+		recordlen = 0x18;
+		entries = 1;
+		pllindex = 0;
+		break;
+	case 0x20:
+	case 0x21:
+	case 0x30:
+	case 0x40:
+		headerlen = bios->data[bios->pll_limit_tbl_ptr + 1];
+		recordlen = bios->data[bios->pll_limit_tbl_ptr + 2];
+		entries = bios->data[bios->pll_limit_tbl_ptr + 3];
+		break;
+	default:
+		NV_ERROR(dev, "PLL limits table revision 0x%X not currently "
+				"supported\n", pll_lim_ver);
+		return -ENOSYS;
+	}
+
+	/* initialize all members to zero */
+	memset(pll_lim, 0, sizeof(struct pll_lims));
+
+	if (pll_lim_ver == 0x10 || pll_lim_ver == 0x11) {
+		uint8_t *pll_rec = &bios->data[bios->pll_limit_tbl_ptr + headerlen + recordlen * pllindex];
+
+		pll_lim->vco1.minfreq = ROM32(pll_rec[0]);
+		pll_lim->vco1.maxfreq = ROM32(pll_rec[4]);
+		pll_lim->vco2.minfreq = ROM32(pll_rec[8]);
+		pll_lim->vco2.maxfreq = ROM32(pll_rec[12]);
+		pll_lim->vco1.min_inputfreq = ROM32(pll_rec[16]);
+		pll_lim->vco2.min_inputfreq = ROM32(pll_rec[20]);
+		pll_lim->vco1.max_inputfreq = pll_lim->vco2.max_inputfreq = INT_MAX;
+
+		/* these values taken from nv30/31/36 */
+		pll_lim->vco1.min_n = 0x1;
+		if (cv == 0x36)
+			pll_lim->vco1.min_n = 0x5;
+		pll_lim->vco1.max_n = 0xff;
+		pll_lim->vco1.min_m = 0x1;
+		pll_lim->vco1.max_m = 0xd;
+		pll_lim->vco2.min_n = 0x4;
+		/*
+		 * On nv30, 31, 36 (i.e. all cards with two stage PLLs with this
+		 * table version (apart from nv35)), N2 is compared to
+		 * maxN2 (0x46) and 10 * maxM2 (0x4), so set maxN2 to 0x28 and
+		 * save a comparison
+		 */
+		pll_lim->vco2.max_n = 0x28;
+		if (cv == 0x30 || cv == 0x35)
+			/* only 5 bits available for N2 on nv30/35 */
+			pll_lim->vco2.max_n = 0x1f;
+		pll_lim->vco2.min_m = 0x1;
+		pll_lim->vco2.max_m = 0x4;
+		pll_lim->max_log2p = 0x7;
+		pll_lim->max_usable_log2p = 0x6;
+	} else if (pll_lim_ver == 0x20 || pll_lim_ver == 0x21) {
+		uint16_t plloffs = bios->pll_limit_tbl_ptr + headerlen;
+		uint32_t reg = 0; /* default match */
+		uint8_t *pll_rec;
+		int i;
+
+		/*
+		 * First entry is default match, if nothing better. warn if
+		 * reg field nonzero
+		 */
+		if (ROM32(bios->data[plloffs]))
+			NV_WARN(dev, "Default PLL limit entry has non-zero "
+				       "register field\n");
+
+		if (limit_match > MAX_PLL_TYPES)
+			/* we've been passed a reg as the match */
+			reg = limit_match;
+		else /* limit match is a pll type */
+			for (i = 1; i < entries && !reg; i++) {
+				uint32_t cmpreg = ROM32(bios->data[plloffs + recordlen * i]);
+
+				if (limit_match == NVPLL &&
+				    (cmpreg == NV_PRAMDAC_NVPLL_COEFF || cmpreg == 0x4000))
+					reg = cmpreg;
+				if (limit_match == MPLL &&
+				    (cmpreg == NV_PRAMDAC_MPLL_COEFF || cmpreg == 0x4020))
+					reg = cmpreg;
+				if (limit_match == VPLL1 &&
+				    (cmpreg == NV_PRAMDAC_VPLL_COEFF || cmpreg == 0x4010))
+					reg = cmpreg;
+				if (limit_match == VPLL2 &&
+				    (cmpreg == NV_RAMDAC_VPLL2 || cmpreg == 0x4018))
+					reg = cmpreg;
+			}
+
+		for (i = 1; i < entries; i++)
+			if (ROM32(bios->data[plloffs + recordlen * i]) == reg) {
+				pllindex = i;
+				break;
+			}
+
+		pll_rec = &bios->data[plloffs + recordlen * pllindex];
+
+		BIOSLOG(bios, "Loading PLL limits for reg 0x%08x\n",
+			pllindex ? reg : 0);
+
+		/*
+		 * Frequencies are stored in tables in MHz, kHz are more
+		 * useful, so we convert.
+		 */
+
+		/* What output frequencies can each VCO generate? */
+		pll_lim->vco1.minfreq = ROM16(pll_rec[4]) * 1000;
+		pll_lim->vco1.maxfreq = ROM16(pll_rec[6]) * 1000;
+		pll_lim->vco2.minfreq = ROM16(pll_rec[8]) * 1000;
+		pll_lim->vco2.maxfreq = ROM16(pll_rec[10]) * 1000;
+
+		/* What input frequencies they accept (past the m-divider)? */
+		pll_lim->vco1.min_inputfreq = ROM16(pll_rec[12]) * 1000;
+		pll_lim->vco2.min_inputfreq = ROM16(pll_rec[14]) * 1000;
+		pll_lim->vco1.max_inputfreq = ROM16(pll_rec[16]) * 1000;
+		pll_lim->vco2.max_inputfreq = ROM16(pll_rec[18]) * 1000;
+
+		/* What values are accepted as multiplier and divider? */
+		pll_lim->vco1.min_n = pll_rec[20];
+		pll_lim->vco1.max_n = pll_rec[21];
+		pll_lim->vco1.min_m = pll_rec[22];
+		pll_lim->vco1.max_m = pll_rec[23];
+		pll_lim->vco2.min_n = pll_rec[24];
+		pll_lim->vco2.max_n = pll_rec[25];
+		pll_lim->vco2.min_m = pll_rec[26];
+		pll_lim->vco2.max_m = pll_rec[27];
+
+		pll_lim->max_usable_log2p = pll_lim->max_log2p = pll_rec[29];
+		if (pll_lim->max_log2p > 0x7)
+			/* pll decoding in nv_hw.c assumes never > 7 */
+			NV_WARN(dev, "Max log2 P value greater than 7 (%d)\n",
+				pll_lim->max_log2p);
+		if (cv < 0x60)
+			pll_lim->max_usable_log2p = 0x6;
+		pll_lim->log2p_bias = pll_rec[30];
+
+		if (recordlen > 0x22)
+			pll_lim->refclk = ROM32(pll_rec[31]);
+
+		if (recordlen > 0x23 && pll_rec[35])
+			NV_WARN(dev,
+				"Bits set in PLL configuration byte (%x)\n",
+				pll_rec[35]);
+
+		/* C51 special not seen elsewhere */
+		if (cv == 0x51 && !pll_lim->refclk) {
+			uint32_t sel_clk = bios_rd32(bios, NV_PRAMDAC_SEL_CLK);
+
+			if (((limit_match == NV_PRAMDAC_VPLL_COEFF || limit_match == VPLL1) && sel_clk & 0x20) ||
+			    ((limit_match == NV_RAMDAC_VPLL2 || limit_match == VPLL2) && sel_clk & 0x80)) {
+				if (bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, NV_CIO_CRE_CHIP_ID_INDEX) < 0xa3)
+					pll_lim->refclk = 200000;
+				else
+					pll_lim->refclk = 25000;
+			}
+		}
+	} else if (pll_lim_ver == 0x30) { /* ver 0x30 */
+		uint8_t *entry = &bios->data[bios->pll_limit_tbl_ptr + headerlen];
+		uint8_t *record = NULL;
+		int i;
+
+		BIOSLOG(bios, "Loading PLL limits for register 0x%08x\n",
+			limit_match);
+
+		for (i = 0; i < entries; i++, entry += recordlen) {
+			if (ROM32(entry[3]) == limit_match) {
+				record = &bios->data[ROM16(entry[1])];
+				break;
+			}
+		}
+
+		if (!record) {
+			NV_ERROR(dev, "Register 0x%08x not found in PLL "
+				 "limits table", limit_match);
+			return -ENOENT;
+		}
+
+		pll_lim->vco1.minfreq = ROM16(record[0]) * 1000;
+		pll_lim->vco1.maxfreq = ROM16(record[2]) * 1000;
+		pll_lim->vco2.minfreq = ROM16(record[4]) * 1000;
+		pll_lim->vco2.maxfreq = ROM16(record[6]) * 1000;
+		pll_lim->vco1.min_inputfreq = ROM16(record[8]) * 1000;
+		pll_lim->vco2.min_inputfreq = ROM16(record[10]) * 1000;
+		pll_lim->vco1.max_inputfreq = ROM16(record[12]) * 1000;
+		pll_lim->vco2.max_inputfreq = ROM16(record[14]) * 1000;
+		pll_lim->vco1.min_n = record[16];
+		pll_lim->vco1.max_n = record[17];
+		pll_lim->vco1.min_m = record[18];
+		pll_lim->vco1.max_m = record[19];
+		pll_lim->vco2.min_n = record[20];
+		pll_lim->vco2.max_n = record[21];
+		pll_lim->vco2.min_m = record[22];
+		pll_lim->vco2.max_m = record[23];
+		pll_lim->max_usable_log2p = pll_lim->max_log2p = record[25];
+		pll_lim->log2p_bias = record[27];
+		pll_lim->refclk = ROM32(record[28]);
+	} else if (pll_lim_ver) { /* ver 0x40 */
+		uint8_t *entry = &bios->data[bios->pll_limit_tbl_ptr + headerlen];
+		uint8_t *record = NULL;
+		int i;
+
+		BIOSLOG(bios, "Loading PLL limits for register 0x%08x\n",
+			limit_match);
+
+		for (i = 0; i < entries; i++, entry += recordlen) {
+			if (ROM32(entry[3]) == limit_match) {
+				record = &bios->data[ROM16(entry[1])];
+				break;
+			}
+		}
+
+		if (!record) {
+			NV_ERROR(dev, "Register 0x%08x not found in PLL "
+				 "limits table", limit_match);
+			return -ENOENT;
+		}
+
+		pll_lim->vco1.minfreq = ROM16(record[0]) * 1000;
+		pll_lim->vco1.maxfreq = ROM16(record[2]) * 1000;
+		pll_lim->vco1.min_inputfreq = ROM16(record[4]) * 1000;
+		pll_lim->vco1.max_inputfreq = ROM16(record[6]) * 1000;
+		pll_lim->vco1.min_m = record[8];
+		pll_lim->vco1.max_m = record[9];
+		pll_lim->vco1.min_n = record[10];
+		pll_lim->vco1.max_n = record[11];
+		pll_lim->min_p = record[12];
+		pll_lim->max_p = record[13];
+		/* where did this go to?? */
+		if (limit_match == 0x00614100 || limit_match == 0x00614900)
+			pll_lim->refclk = 27000;
+		else
+			pll_lim->refclk = 100000;
+	}
+
+	/*
+	 * By now any valid limit table ought to have set a max frequency for
+	 * vco1, so if it's zero it's either a pre limit table bios, or one
+	 * with an empty limit table (seen on nv18)
+	 */
+	if (!pll_lim->vco1.maxfreq) {
+		pll_lim->vco1.minfreq = bios->fminvco;
+		pll_lim->vco1.maxfreq = bios->fmaxvco;
+		pll_lim->vco1.min_inputfreq = 0;
+		pll_lim->vco1.max_inputfreq = INT_MAX;
+		pll_lim->vco1.min_n = 0x1;
+		pll_lim->vco1.max_n = 0xff;
+		pll_lim->vco1.min_m = 0x1;
+		if (crystal_straps == 0) {
+			/* nv05 does this, nv11 doesn't, nv10 unknown */
+			if (cv < 0x11)
+				pll_lim->vco1.min_m = 0x7;
+			pll_lim->vco1.max_m = 0xd;
+		} else {
+			if (cv < 0x11)
+				pll_lim->vco1.min_m = 0x8;
+			pll_lim->vco1.max_m = 0xe;
+		}
+		if (cv < 0x17 || cv == 0x1a || cv == 0x20)
+			pll_lim->max_log2p = 4;
+		else
+			pll_lim->max_log2p = 5;
+		pll_lim->max_usable_log2p = pll_lim->max_log2p;
+	}
+
+	if (!pll_lim->refclk)
+		switch (crystal_straps) {
+		case 0:
+			pll_lim->refclk = 13500;
+			break;
+		case (1 << 6):
+			pll_lim->refclk = 14318;
+			break;
+		case (1 << 22):
+			pll_lim->refclk = 27000;
+			break;
+		case (1 << 22 | 1 << 6):
+			pll_lim->refclk = 25000;
+			break;
+		}
+
+#if 0 /* for easy debugging */
+	ErrorF("pll.vco1.minfreq: %d\n", pll_lim->vco1.minfreq);
+	ErrorF("pll.vco1.maxfreq: %d\n", pll_lim->vco1.maxfreq);
+	ErrorF("pll.vco2.minfreq: %d\n", pll_lim->vco2.minfreq);
+	ErrorF("pll.vco2.maxfreq: %d\n", pll_lim->vco2.maxfreq);
+
+	ErrorF("pll.vco1.min_inputfreq: %d\n", pll_lim->vco1.min_inputfreq);
+	ErrorF("pll.vco1.max_inputfreq: %d\n", pll_lim->vco1.max_inputfreq);
+	ErrorF("pll.vco2.min_inputfreq: %d\n", pll_lim->vco2.min_inputfreq);
+	ErrorF("pll.vco2.max_inputfreq: %d\n", pll_lim->vco2.max_inputfreq);
+
+	ErrorF("pll.vco1.min_n: %d\n", pll_lim->vco1.min_n);
+	ErrorF("pll.vco1.max_n: %d\n", pll_lim->vco1.max_n);
+	ErrorF("pll.vco1.min_m: %d\n", pll_lim->vco1.min_m);
+	ErrorF("pll.vco1.max_m: %d\n", pll_lim->vco1.max_m);
+	ErrorF("pll.vco2.min_n: %d\n", pll_lim->vco2.min_n);
+	ErrorF("pll.vco2.max_n: %d\n", pll_lim->vco2.max_n);
+	ErrorF("pll.vco2.min_m: %d\n", pll_lim->vco2.min_m);
+	ErrorF("pll.vco2.max_m: %d\n", pll_lim->vco2.max_m);
+
+	ErrorF("pll.max_log2p: %d\n", pll_lim->max_log2p);
+	ErrorF("pll.log2p_bias: %d\n", pll_lim->log2p_bias);
+
+	ErrorF("pll.refclk: %d\n", pll_lim->refclk);
+#endif
+
+	return 0;
+}
+
+static void parse_bios_version(struct drm_device *dev, struct nvbios *bios, uint16_t offset)
+{
+	/*
+	 * offset + 0  (8 bits): Micro version
+	 * offset + 1  (8 bits): Minor version
+	 * offset + 2  (8 bits): Chip version
+	 * offset + 3  (8 bits): Major version
+	 */
+
+	bios->major_version = bios->data[offset + 3];
+	bios->pub.chip_version = bios->data[offset + 2];
+	NV_TRACE(dev, "Bios version %02x.%02x.%02x.%02x\n",
+		 bios->data[offset + 3], bios->data[offset + 2],
+		 bios->data[offset + 1], bios->data[offset]);
+}
+
+static void parse_script_table_pointers(struct nvbios *bios, uint16_t offset)
+{
+	/*
+	 * Parses the init table segment for pointers used in script execution.
+	 *
+	 * offset + 0  (16 bits): init script tables pointer
+	 * offset + 2  (16 bits): macro index table pointer
+	 * offset + 4  (16 bits): macro table pointer
+	 * offset + 6  (16 bits): condition table pointer
+	 * offset + 8  (16 bits): io condition table pointer
+	 * offset + 10 (16 bits): io flag condition table pointer
+	 * offset + 12 (16 bits): init function table pointer
+	 */
+
+	bios->init_script_tbls_ptr = ROM16(bios->data[offset]);
+	bios->macro_index_tbl_ptr = ROM16(bios->data[offset + 2]);
+	bios->macro_tbl_ptr = ROM16(bios->data[offset + 4]);
+	bios->condition_tbl_ptr = ROM16(bios->data[offset + 6]);
+	bios->io_condition_tbl_ptr = ROM16(bios->data[offset + 8]);
+	bios->io_flag_condition_tbl_ptr = ROM16(bios->data[offset + 10]);
+	bios->init_function_tbl_ptr = ROM16(bios->data[offset + 12]);
+}
+
+static int parse_bit_A_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry)
+{
+	/*
+	 * Parses the load detect values for g80 cards.
+	 *
+	 * offset + 0 (16 bits): loadval table pointer
+	 */
+
+	uint16_t load_table_ptr;
+	uint8_t version, headerlen, entrylen, num_entries;
+
+	if (bitentry->length != 3) {
+		NV_ERROR(dev, "Do not understand BIT A table\n");
+		return -EINVAL;
+	}
+
+	load_table_ptr = ROM16(bios->data[bitentry->offset]);
+
+	if (load_table_ptr == 0x0) {
+		NV_ERROR(dev, "Pointer to BIT loadval table invalid\n");
+		return -EINVAL;
+	}
+
+	version = bios->data[load_table_ptr];
+
+	if (version != 0x10) {
+		NV_ERROR(dev, "BIT loadval table version %d.%d not supported\n",
+			 version >> 4, version & 0xF);
+		return -ENOSYS;
+	}
+
+	headerlen = bios->data[load_table_ptr + 1];
+	entrylen = bios->data[load_table_ptr + 2];
+	num_entries = bios->data[load_table_ptr + 3];
+
+	if (headerlen != 4 || entrylen != 4 || num_entries != 2) {
+		NV_ERROR(dev, "Do not understand BIT loadval table\n");
+		return -EINVAL;
+	}
+
+	/* First entry is normal dac, 2nd tv-out perhaps? */
+	bios->pub.dactestval = ROM32(bios->data[load_table_ptr + headerlen]) & 0x3ff;
+
+	return 0;
+}
+
+static int parse_bit_C_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry)
+{
+	/*
+	 * offset + 8  (16 bits): PLL limits table pointer
+	 *
+	 * There's more in here, but that's unknown.
+	 */
+
+	if (bitentry->length < 10) {
+		NV_ERROR(dev, "Do not understand BIT C table\n");
+		return -EINVAL;
+	}
+
+	bios->pll_limit_tbl_ptr = ROM16(bios->data[bitentry->offset + 8]);
+
+	return 0;
+}
+
+static int parse_bit_display_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry)
+{
+	/*
+	 * Parses the flat panel table segment that the bit entry points to.
+	 * Starting at bitentry->offset:
+	 *
+	 * offset + 0  (16 bits): ??? table pointer - seems to have 18 byte
+	 * records beginning with a freq.
+	 * offset + 2  (16 bits): mode table pointer
+	 */
+
+	if (bitentry->length != 4) {
+		NV_ERROR(dev, "Do not understand BIT display table\n");
+		return -EINVAL;
+	}
+
+	bios->fp.fptablepointer = ROM16(bios->data[bitentry->offset + 2]);
+
+	return 0;
+}
+
+static int parse_bit_init_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry)
+{
+	/*
+	 * Parses the init table segment that the bit entry points to.
+	 *
+	 * See parse_script_table_pointers for layout
+	 */
+
+	if (bitentry->length < 14) {
+		NV_ERROR(dev, "Do not understand init table\n");
+		return -EINVAL;
+	}
+
+	parse_script_table_pointers(bios, bitentry->offset);
+
+	if (bitentry->length >= 16)
+		bios->some_script_ptr = ROM16(bios->data[bitentry->offset + 14]);
+	if (bitentry->length >= 18)
+		bios->init96_tbl_ptr = ROM16(bios->data[bitentry->offset + 16]);
+
+	return 0;
+}
+
+static int parse_bit_i_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry)
+{
+	/*
+	 * BIT 'i' (info?) table
+	 *
+	 * offset + 0  (32 bits): BIOS version dword (as in B table)
+	 * offset + 5  (8  bits): BIOS feature byte (same as for BMP?)
+	 * offset + 13 (16 bits): pointer to table containing DAC load
+	 * detection comparison values
+	 *
+	 * There's other things in the table, purpose unknown
+	 */
+
+	uint16_t daccmpoffset;
+	uint8_t dacver, dacheaderlen;
+
+	if (bitentry->length < 6) {
+		NV_ERROR(dev, "BIT i table too short for needed information\n");
+		return -EINVAL;
+	}
+
+	parse_bios_version(dev, bios, bitentry->offset);
+
+	/*
+	 * bit 4 seems to indicate a mobile bios (doesn't suffer from BMP's
+	 * Quadro identity crisis), other bits possibly as for BMP feature byte
+	 */
+	bios->feature_byte = bios->data[bitentry->offset + 5];
+	bios->is_mobile = bios->feature_byte & FEATURE_MOBILE;
+
+	if (bitentry->length < 15) {
+		NV_WARN(dev, "BIT i table not long enough for DAC load "
+			       "detection comparison table\n");
+		return -EINVAL;
+	}
+
+	daccmpoffset = ROM16(bios->data[bitentry->offset + 13]);
+
+	/* doesn't exist on g80 */
+	if (!daccmpoffset)
+		return 0;
+
+	/*
+	 * The first value in the table, following the header, is the
+	 * comparison value, the second entry is a comparison value for
+	 * TV load detection.
+	 */
+
+	dacver = bios->data[daccmpoffset];
+	dacheaderlen = bios->data[daccmpoffset + 1];
+
+	if (dacver != 0x00 && dacver != 0x10) {
+		NV_WARN(dev, "DAC load detection comparison table version "
+			       "%d.%d not known\n", dacver >> 4, dacver & 0xf);
+		return -ENOSYS;
+	}
+
+	bios->pub.dactestval = ROM32(bios->data[daccmpoffset + dacheaderlen]);
+	bios->pub.tvdactestval = ROM32(bios->data[daccmpoffset + dacheaderlen + 4]);
+
+	return 0;
+}
+
+static int parse_bit_lvds_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry)
+{
+	/*
+	 * Parses the LVDS table segment that the bit entry points to.
+	 * Starting at bitentry->offset:
+	 *
+	 * offset + 0  (16 bits): LVDS strap xlate table pointer
+	 */
+
+	if (bitentry->length != 2) {
+		NV_ERROR(dev, "Do not understand BIT LVDS table\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * No idea if it's still called the LVDS manufacturer table, but
+	 * the concept's close enough.
+	 */
+	bios->fp.lvdsmanufacturerpointer = ROM16(bios->data[bitentry->offset]);
+
+	return 0;
+}
+
+static int
+parse_bit_M_tbl_entry(struct drm_device *dev, struct nvbios *bios,
+		      struct bit_entry *bitentry)
+{
+	/*
+	 * offset + 2  (8  bits): number of options in an
+	 * 	INIT_RAM_RESTRICT_ZM_REG_GROUP opcode option set
+	 * offset + 3  (16 bits): pointer to strap xlate table for RAM
+	 * 	restrict option selection
+	 *
+	 * There's a bunch of bits in this table other than the RAM restrict
+	 * stuff that we don't use - their use currently unknown
+	 */
+
+	uint16_t rr_strap_xlat;
+	uint8_t rr_group_count;
+	int i;
+
+	/*
+	 * Older bios versions don't have a sufficiently long table for
+	 * what we want
+	 */
+	if (bitentry->length < 0x5)
+		return 0;
+
+	if (bitentry->id[1] < 2) {
+		rr_group_count = bios->data[bitentry->offset + 2];
+		rr_strap_xlat = ROM16(bios->data[bitentry->offset + 3]);
+	} else {
+		rr_group_count = bios->data[bitentry->offset + 0];
+		rr_strap_xlat = ROM16(bios->data[bitentry->offset + 1]);
+	}
+
+	/* adjust length of INIT_87 */
+	for (i = 0; itbl_entry[i].name && (itbl_entry[i].id != 0x87); i++);
+	itbl_entry[i].length += rr_group_count * 4;
+
+	/* set up multiplier for INIT_RAM_RESTRICT_ZM_REG_GROUP */
+	for (; itbl_entry[i].name && (itbl_entry[i].id != 0x8f); i++);
+	itbl_entry[i].length_multiplier = rr_group_count * 4;
+
+	init_ram_restrict_zm_reg_group_blocklen = itbl_entry[i].length_multiplier;
+	bios->ram_restrict_tbl_ptr = rr_strap_xlat;
+
+	return 0;
+}
+
+static int parse_bit_tmds_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry)
+{
+	/*
+	 * Parses the pointer to the TMDS table
+	 *
+	 * Starting at bitentry->offset:
+	 *
+	 * offset + 0  (16 bits): TMDS table pointer
+	 *
+	 * The TMDS table is typically found just before the DCB table, with a
+	 * characteristic signature of 0x11,0x13 (1.1 being version, 0x13 being
+	 * length?)
+	 *
+	 * At offset +7 is a pointer to a script, which I don't know how to
+	 * run yet.
+	 * At offset +9 is a pointer to another script, likewise
+	 * Offset +11 has a pointer to a table where the first word is a pxclk
+	 * frequency and the second word a pointer to a script, which should be
+	 * run if the comparison pxclk frequency is less than the pxclk desired.
+	 * This repeats for decreasing comparison frequencies
+	 * Offset +13 has a pointer to a similar table
+	 * The selection of table (and possibly +7/+9 script) is dictated by
+	 * "or" from the DCB.
+	 */
+
+	uint16_t tmdstableptr, script1, script2;
+
+	if (bitentry->length != 2) {
+		NV_ERROR(dev, "Do not understand BIT TMDS table\n");
+		return -EINVAL;
+	}
+
+	tmdstableptr = ROM16(bios->data[bitentry->offset]);
+
+	if (tmdstableptr == 0x0) {
+		NV_ERROR(dev, "Pointer to TMDS table invalid\n");
+		return -EINVAL;
+	}
+
+	/* nv50+ has v2.0, but we don't parse it atm */
+	if (bios->data[tmdstableptr] != 0x11) {
+		NV_WARN(dev,
+			"TMDS table revision %d.%d not currently supported\n",
+			bios->data[tmdstableptr] >> 4, bios->data[tmdstableptr] & 0xf);
+		return -ENOSYS;
+	}
+
+	/*
+	 * These two scripts are odd: they don't seem to get run even when
+	 * they are not stubbed.
+	 */
+	script1 = ROM16(bios->data[tmdstableptr + 7]);
+	script2 = ROM16(bios->data[tmdstableptr + 9]);
+	if (bios->data[script1] != 'q' || bios->data[script2] != 'q')
+		NV_WARN(dev, "TMDS table script pointers not stubbed\n");
+
+	bios->tmds.output0_script_ptr = ROM16(bios->data[tmdstableptr + 11]);
+	bios->tmds.output1_script_ptr = ROM16(bios->data[tmdstableptr + 13]);
+
+	return 0;
+}
+
+static int
+parse_bit_U_tbl_entry(struct drm_device *dev, struct nvbios *bios,
+		      struct bit_entry *bitentry)
+{
+	/*
+	 * Parses the pointer to the G80 output script tables
+	 *
+	 * Starting at bitentry->offset:
+	 *
+	 * offset + 0  (16 bits): output script table pointer
+	 */
+
+	uint16_t outputscripttableptr;
+
+	if (bitentry->length != 3) {
+		NV_ERROR(dev, "Do not understand BIT U table\n");
+		return -EINVAL;
+	}
+
+	outputscripttableptr = ROM16(bios->data[bitentry->offset]);
+	bios->display.script_table_ptr = outputscripttableptr;
+	return 0;
+}
+
+static int
+parse_bit_displayport_tbl_entry(struct drm_device *dev, struct nvbios *bios,
+				struct bit_entry *bitentry)
+{
+	bios->display.dp_table_ptr = ROM16(bios->data[bitentry->offset]);
+	return 0;
+}
+
+struct bit_table {
+	const char id;
+	int (* const parse_fn)(struct drm_device *, struct nvbios *, struct bit_entry *);
+};
+
+#define BIT_TABLE(id, funcid) ((struct bit_table){ id, parse_bit_##funcid##_tbl_entry })
+
+static int
+parse_bit_table(struct nvbios *bios, const uint16_t bitoffset,
+		struct bit_table *table)
+{
+	struct drm_device *dev = bios->dev;
+	uint8_t maxentries = bios->data[bitoffset + 4];
+	int i, offset;
+	struct bit_entry bitentry;
+
+	for (i = 0, offset = bitoffset + 6; i < maxentries; i++, offset += 6) {
+		bitentry.id[0] = bios->data[offset];
+
+		if (bitentry.id[0] != table->id)
+			continue;
+
+		bitentry.id[1] = bios->data[offset + 1];
+		bitentry.length = ROM16(bios->data[offset + 2]);
+		bitentry.offset = ROM16(bios->data[offset + 4]);
+
+		return table->parse_fn(dev, bios, &bitentry);
+	}
+
+	NV_INFO(dev, "BIT table '%c' not found\n", table->id);
+	return -ENOSYS;
+}
+
+static int
+parse_bit_structure(struct nvbios *bios, const uint16_t bitoffset)
+{
+	int ret;
+
+	/*
+	 * The only restriction on parsing order currently is having 'i' first
+	 * for use of bios->*_version or bios->feature_byte while parsing;
+	 * functions shouldn't be actually *doing* anything apart from pulling
+	 * data from the image into the bios struct, thus no interdependencies
+	 */
+	ret = parse_bit_table(bios, bitoffset, &BIT_TABLE('i', i));
+	if (ret) /* info? */
+		return ret;
+	if (bios->major_version >= 0x60) /* g80+ */
+		parse_bit_table(bios, bitoffset, &BIT_TABLE('A', A));
+	ret = parse_bit_table(bios, bitoffset, &BIT_TABLE('C', C));
+	if (ret)
+		return ret;
+	parse_bit_table(bios, bitoffset, &BIT_TABLE('D', display));
+	ret = parse_bit_table(bios, bitoffset, &BIT_TABLE('I', init));
+	if (ret)
+		return ret;
+	parse_bit_table(bios, bitoffset, &BIT_TABLE('M', M)); /* memory? */
+	parse_bit_table(bios, bitoffset, &BIT_TABLE('L', lvds));
+	parse_bit_table(bios, bitoffset, &BIT_TABLE('T', tmds));
+	parse_bit_table(bios, bitoffset, &BIT_TABLE('U', U));
+	parse_bit_table(bios, bitoffset, &BIT_TABLE('d', displayport));
+
+	return 0;
+}
+
+static int parse_bmp_structure(struct drm_device *dev, struct nvbios *bios, unsigned int offset)
+{
+	/*
+	 * Parses the BMP structure for useful things, but does not act on them
+	 *
+	 * offset +   5: BMP major version
+	 * offset +   6: BMP minor version
+	 * offset +   9: BMP feature byte
+	 * offset +  10: BCD encoded BIOS version
+	 *
+	 * offset +  18: init script table pointer (for bios versions < 5.10h)
+	 * offset +  20: extra init script table pointer (for bios
+	 * versions < 5.10h)
+	 *
+	 * offset +  24: memory init table pointer (used on early bios versions)
+	 * offset +  26: SDR memory sequencing setup data table
+	 * offset +  28: DDR memory sequencing setup data table
+	 *
+	 * offset +  54: index of I2C CRTC pair to use for CRT output
+	 * offset +  55: index of I2C CRTC pair to use for TV output
+	 * offset +  56: index of I2C CRTC pair to use for flat panel output
+	 * offset +  58: write CRTC index for I2C pair 0
+	 * offset +  59: read CRTC index for I2C pair 0
+	 * offset +  60: write CRTC index for I2C pair 1
+	 * offset +  61: read CRTC index for I2C pair 1
+	 *
+	 * offset +  67: maximum internal PLL frequency (single stage PLL)
+	 * offset +  71: minimum internal PLL frequency (single stage PLL)
+	 *
+	 * offset +  75: script table pointers, as described in
+	 * parse_script_table_pointers
+	 *
+	 * offset +  89: TMDS single link output A table pointer
+	 * offset +  91: TMDS single link output B table pointer
+	 * offset +  95: LVDS single link output A table pointer
+	 * offset + 105: flat panel timings table pointer
+	 * offset + 107: flat panel strapping translation table pointer
+	 * offset + 117: LVDS manufacturer panel config table pointer
+	 * offset + 119: LVDS manufacturer strapping translation table pointer
+	 *
+	 * offset + 142: PLL limits table pointer
+	 *
+	 * offset + 156: minimum pixel clock for LVDS dual link
+	 */
+
+	uint8_t *bmp = &bios->data[offset], bmp_version_major, bmp_version_minor;
+	uint16_t bmplength;
+	uint16_t legacy_scripts_offset, legacy_i2c_offset;
+
+	/* load needed defaults in case we can't parse this info */
+	bios->bdcb.dcb.i2c[0].write = NV_CIO_CRE_DDC_WR__INDEX;
+	bios->bdcb.dcb.i2c[0].read = NV_CIO_CRE_DDC_STATUS__INDEX;
+	bios->bdcb.dcb.i2c[1].write = NV_CIO_CRE_DDC0_WR__INDEX;
+	bios->bdcb.dcb.i2c[1].read = NV_CIO_CRE_DDC0_STATUS__INDEX;
+	bios->pub.digital_min_front_porch = 0x4b;
+	bios->fmaxvco = 256000;
+	bios->fminvco = 128000;
+	bios->fp.duallink_transition_clk = 90000;
+
+	bmp_version_major = bmp[5];
+	bmp_version_minor = bmp[6];
+
+	NV_TRACE(dev, "BMP version %d.%d\n",
+		 bmp_version_major, bmp_version_minor);
+
+	/*
+	 * Make sure that 0x36 is blank and can't be mistaken for a DCB
+	 * pointer on early versions
+	 */
+	if (bmp_version_major < 5)
+		*(uint16_t *)&bios->data[0x36] = 0;
+
+	/*
+	 * Seems that the minor version was 1 for all major versions prior
+	 * to 5. Version 6 could theoretically exist, but I suspect BIT
+	 * happened instead.
+	 */
+	if ((bmp_version_major < 5 && bmp_version_minor != 1) || bmp_version_major > 5) {
+		NV_ERROR(dev, "You have an unsupported BMP version. "
+				"Please send in your bios\n");
+		return -ENOSYS;
+	}
+
+	if (bmp_version_major == 0)
+		/* nothing that's currently useful in this version */
+		return 0;
+	else if (bmp_version_major == 1)
+		bmplength = 44; /* exact for 1.01 */
+	else if (bmp_version_major == 2)
+		bmplength = 48; /* exact for 2.01 */
+	else if (bmp_version_major == 3)
+		bmplength = 54;
+		/* guessed - mem init tables added in this version */
+	else if (bmp_version_major == 4 || bmp_version_minor < 0x1)
+		/* don't know if 5.0 exists... */
+		bmplength = 62;
+		/* guessed - BMP I2C indices added in version 4*/
+	else if (bmp_version_minor < 0x6)
+		bmplength = 67; /* exact for 5.01 */
+	else if (bmp_version_minor < 0x10)
+		bmplength = 75; /* exact for 5.06 */
+	else if (bmp_version_minor == 0x10)
+		bmplength = 89; /* exact for 5.10h */
+	else if (bmp_version_minor < 0x14)
+		bmplength = 118; /* exact for 5.11h */
+	else if (bmp_version_minor < 0x24)
+		/*
+		 * Not sure of version where pll limits came in;
+		 * certainly exist by 0x24 though.
+		 */
+		/* length not exact: this is long enough to get lvds members */
+		bmplength = 123;
+	else if (bmp_version_minor < 0x27)
+		/*
+		 * Length not exact: this is long enough to get pll limit
+		 * member
+		 */
+		bmplength = 144;
+	else
+		/*
+		 * Length not exact: this is long enough to get dual link
+		 * transition clock.
+		 */
+		bmplength = 158;
+
+	/* checksum */
+	if (nv_cksum(bmp, 8)) {
+		NV_ERROR(dev, "Bad BMP checksum\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * Bit 4 seems to indicate either a mobile bios or a quadro card --
+	 * mobile behaviour consistent (nv11+), quadro only seen nv18gl-nv36gl
+	 * (not nv10gl), bit 5 that the flat panel tables are present, and
+	 * bit 6 a tv bios.
+	 */
+	bios->feature_byte = bmp[9];
+
+	parse_bios_version(dev, bios, offset + 10);
+
+	if (bmp_version_major < 5 || bmp_version_minor < 0x10)
+		bios->old_style_init = true;
+	legacy_scripts_offset = 18;
+	if (bmp_version_major < 2)
+		legacy_scripts_offset -= 4;
+	bios->init_script_tbls_ptr = ROM16(bmp[legacy_scripts_offset]);
+	bios->extra_init_script_tbl_ptr = ROM16(bmp[legacy_scripts_offset + 2]);
+
+	if (bmp_version_major > 2) {	/* appears in BMP 3 */
+		bios->legacy.mem_init_tbl_ptr = ROM16(bmp[24]);
+		bios->legacy.sdr_seq_tbl_ptr = ROM16(bmp[26]);
+		bios->legacy.ddr_seq_tbl_ptr = ROM16(bmp[28]);
+	}
+
+	legacy_i2c_offset = 0x48;	/* BMP version 2 & 3 */
+	if (bmplength > 61)
+		legacy_i2c_offset = offset + 54;
+	bios->legacy.i2c_indices.crt = bios->data[legacy_i2c_offset];
+	bios->legacy.i2c_indices.tv = bios->data[legacy_i2c_offset + 1];
+	bios->legacy.i2c_indices.panel = bios->data[legacy_i2c_offset + 2];
+	bios->bdcb.dcb.i2c[0].write = bios->data[legacy_i2c_offset + 4];
+	bios->bdcb.dcb.i2c[0].read = bios->data[legacy_i2c_offset + 5];
+	bios->bdcb.dcb.i2c[1].write = bios->data[legacy_i2c_offset + 6];
+	bios->bdcb.dcb.i2c[1].read = bios->data[legacy_i2c_offset + 7];
+
+	if (bmplength > 74) {
+		bios->fmaxvco = ROM32(bmp[67]);
+		bios->fminvco = ROM32(bmp[71]);
+	}
+	if (bmplength > 88)
+		parse_script_table_pointers(bios, offset + 75);
+	if (bmplength > 94) {
+		bios->tmds.output0_script_ptr = ROM16(bmp[89]);
+		bios->tmds.output1_script_ptr = ROM16(bmp[91]);
+		/*
+		 * Never observed in use with lvds scripts, but is reused for
+		 * 18/24 bit panel interface default for EDID equipped panels
+		 * (if_is_24bit not set directly to avoid any oscillation).
+		 */
+		bios->legacy.lvds_single_a_script_ptr = ROM16(bmp[95]);
+	}
+	if (bmplength > 108) {
+		bios->fp.fptablepointer = ROM16(bmp[105]);
+		bios->fp.fpxlatetableptr = ROM16(bmp[107]);
+		bios->fp.xlatwidth = 1;
+	}
+	if (bmplength > 120) {
+		bios->fp.lvdsmanufacturerpointer = ROM16(bmp[117]);
+		bios->fp.fpxlatemanufacturertableptr = ROM16(bmp[119]);
+	}
+	if (bmplength > 143)
+		bios->pll_limit_tbl_ptr = ROM16(bmp[142]);
+
+	if (bmplength > 157)
+		bios->fp.duallink_transition_clk = ROM16(bmp[156]) * 10;
+
+	return 0;
+}
+
+static uint16_t findstr(uint8_t *data, int n, const uint8_t *str, int len)
+{
+	int i, j;
+
+	for (i = 0; i <= (n - len); i++) {
+		for (j = 0; j < len; j++)
+			if (data[i + j] != str[j])
+				break;
+		if (j == len)
+			return i;
+	}
+
+	return 0;
+}
+
+static int
+read_dcb_i2c_entry(struct drm_device *dev, int dcb_version, uint8_t *i2ctable, int index, struct dcb_i2c_entry *i2c)
+{
+	uint8_t dcb_i2c_ver = dcb_version, headerlen = 0, entry_len = 4;
+	int i2c_entries = DCB_MAX_NUM_I2C_ENTRIES;
+	int recordoffset = 0, rdofs = 1, wrofs = 0;
+	uint8_t port_type = 0;
+
+	if (!i2ctable)
+		return -EINVAL;
+
+	if (dcb_version >= 0x30) {
+		if (i2ctable[0] != dcb_version) /* necessary? */
+			NV_WARN(dev,
+				"DCB I2C table version mismatch (%02X vs %02X)\n",
+				i2ctable[0], dcb_version);
+		dcb_i2c_ver = i2ctable[0];
+		headerlen = i2ctable[1];
+		if (i2ctable[2] <= DCB_MAX_NUM_I2C_ENTRIES)
+			i2c_entries = i2ctable[2];
+		else
+			NV_WARN(dev,
+				"DCB I2C table has more entries than indexable "
+				"(%d entries, max index 15)\n", i2ctable[2]);
+		entry_len = i2ctable[3];
+		/* [4] is i2c_default_indices, read in parse_dcb_table() */
+	}
+	/*
+	 * It's your own fault if you call this function on a DCB 1.1 BIOS --
+	 * the test below is for DCB 1.2
+	 */
+	if (dcb_version < 0x14) {
+		recordoffset = 2;
+		rdofs = 0;
+		wrofs = 1;
+	}
+
+	if (index == 0xf)
+		return 0;
+	if (index > i2c_entries) {
+		NV_ERROR(dev, "DCB I2C index too big (%d > %d)\n",
+			 index, i2ctable[2]);
+		return -ENOENT;
+	}
+	if (i2ctable[headerlen + entry_len * index + 3] == 0xff) {
+		NV_ERROR(dev, "DCB I2C entry invalid\n");
+		return -EINVAL;
+	}
+
+	if (dcb_i2c_ver >= 0x30) {
+		port_type = i2ctable[headerlen + recordoffset + 3 + entry_len * index];
+
+		/*
+		 * Fixup for chips using same address offset for read and
+		 * write.
+		 */
+		if (port_type == 4)	/* seen on C51 */
+			rdofs = wrofs = 1;
+		if (port_type >= 5)	/* G80+ */
+			rdofs = wrofs = 0;
+	}
+
+	if (dcb_i2c_ver >= 0x40 && port_type != 5 && port_type != 6)
+		NV_WARN(dev, "DCB I2C table has port type %d\n", port_type);
+
+	i2c->port_type = port_type;
+	i2c->read = i2ctable[headerlen + recordoffset + rdofs + entry_len * index];
+	i2c->write = i2ctable[headerlen + recordoffset + wrofs + entry_len * index];
+
+	return 0;
+}
+
+static struct dcb_gpio_entry *
+new_gpio_entry(struct nvbios *bios)
+{
+	struct parsed_dcb_gpio *gpio = &bios->bdcb.gpio;
+
+	return &gpio->entry[gpio->entries++];
+}
+
+struct dcb_gpio_entry *
+nouveau_bios_gpio_entry(struct drm_device *dev, enum dcb_gpio_tag tag)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	int i;
+
+	for (i = 0; i < bios->bdcb.gpio.entries; i++) {
+		if (bios->bdcb.gpio.entry[i].tag != tag)
+			continue;
+
+		return &bios->bdcb.gpio.entry[i];
+	}
+
+	return NULL;
+}
+
+static void
+parse_dcb30_gpio_entry(struct nvbios *bios, uint16_t offset)
+{
+	struct dcb_gpio_entry *gpio;
+	uint16_t ent = ROM16(bios->data[offset]);
+	uint8_t line = ent & 0x1f,
+		tag = ent >> 5 & 0x3f,
+		flags = ent >> 11 & 0x1f;
+
+	if (tag == 0x3f)
+		return;
+
+	gpio = new_gpio_entry(bios);
+
+	gpio->tag = tag;
+	gpio->line = line;
+	gpio->invert = flags != 4;
+}
+
+static void
+parse_dcb40_gpio_entry(struct nvbios *bios, uint16_t offset)
+{
+	struct dcb_gpio_entry *gpio;
+	uint32_t ent = ROM32(bios->data[offset]);
+	uint8_t line = ent & 0x1f,
+		tag = ent >> 8 & 0xff;
+
+	if (tag == 0xff)
+		return;
+
+	gpio = new_gpio_entry(bios);
+
+	/* Currently unused, we may need more fields parsed at some
+	 * point. */
+	gpio->tag = tag;
+	gpio->line = line;
+}
+
+static void
+parse_dcb_gpio_table(struct nvbios *bios)
+{
+	struct drm_device *dev = bios->dev;
+	uint16_t gpio_table_ptr = bios->bdcb.gpio_table_ptr;
+	uint8_t *gpio_table = &bios->data[gpio_table_ptr];
+	int header_len = gpio_table[1],
+	    entries = gpio_table[2],
+	    entry_len = gpio_table[3];
+	void (*parse_entry)(struct nvbios *, uint16_t) = NULL;
+	int i;
+
+	if (bios->bdcb.version >= 0x40) {
+		if (gpio_table_ptr && entry_len != 4) {
+			NV_WARN(dev, "Invalid DCB GPIO table entry length.\n");
+			return;
+		}
+
+		parse_entry = parse_dcb40_gpio_entry;
+
+	} else if (bios->bdcb.version >= 0x30) {
+		if (gpio_table_ptr && entry_len != 2) {
+			NV_WARN(dev, "Invalid DCB GPIO table entry length.\n");
+			return;
+		}
+
+		parse_entry = parse_dcb30_gpio_entry;
+
+	} else if (bios->bdcb.version >= 0x22) {
+		/*
+		 * DCBs older than v3.0 don't really have a GPIO
+		 * table, instead they keep some GPIO info at fixed
+		 * locations.
+		 */
+		uint16_t dcbptr = ROM16(bios->data[0x36]);
+		uint8_t *tvdac_gpio = &bios->data[dcbptr - 5];
+
+		if (tvdac_gpio[0] & 1) {
+			struct dcb_gpio_entry *gpio = new_gpio_entry(bios);
+
+			gpio->tag = DCB_GPIO_TVDAC0;
+			gpio->line = tvdac_gpio[1] >> 4;
+			gpio->invert = tvdac_gpio[0] & 2;
+		}
+	}
+
+	if (!gpio_table_ptr)
+		return;
+
+	if (entries > DCB_MAX_NUM_GPIO_ENTRIES) {
+		NV_WARN(dev, "Too many entries in the DCB GPIO table.\n");
+		entries = DCB_MAX_NUM_GPIO_ENTRIES;
+	}
+
+	for (i = 0; i < entries; i++)
+		parse_entry(bios, gpio_table_ptr + header_len + entry_len * i);
+}
+
+struct dcb_connector_table_entry *
+nouveau_bios_connector_entry(struct drm_device *dev, int index)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	struct dcb_connector_table_entry *cte;
+
+	if (index >= bios->bdcb.connector.entries)
+		return NULL;
+
+	cte = &bios->bdcb.connector.entry[index];
+	if (cte->type == 0xff)
+		return NULL;
+
+	return cte;
+}
+
+static void
+parse_dcb_connector_table(struct nvbios *bios)
+{
+	struct drm_device *dev = bios->dev;
+	struct dcb_connector_table *ct = &bios->bdcb.connector;
+	struct dcb_connector_table_entry *cte;
+	uint8_t *conntab = &bios->data[bios->bdcb.connector_table_ptr];
+	uint8_t *entry;
+	int i;
+
+	if (!bios->bdcb.connector_table_ptr) {
+		NV_DEBUG(dev, "No DCB connector table present\n");
+		return;
+	}
+
+	NV_INFO(dev, "DCB connector table: VHER 0x%02x %d %d %d\n",
+		conntab[0], conntab[1], conntab[2], conntab[3]);
+	if ((conntab[0] != 0x30 && conntab[0] != 0x40) ||
+	    (conntab[3] != 2 && conntab[3] != 4)) {
+		NV_ERROR(dev, "  Unknown!  Please report.\n");
+		return;
+	}
+
+	ct->entries = conntab[2];
+
+	entry = conntab + conntab[1];
+	cte = &ct->entry[0];
+	for (i = 0; i < conntab[2]; i++, entry += conntab[3], cte++) {
+		if (conntab[3] == 2)
+			cte->entry = ROM16(entry[0]);
+		else
+			cte->entry = ROM32(entry[0]);
+		cte->type  = (cte->entry & 0x000000ff) >> 0;
+		cte->index = (cte->entry & 0x00000f00) >> 8;
+		switch (cte->entry & 0x00033000) {
+		case 0x00001000:
+			cte->gpio_tag = 0x07;
+			break;
+		case 0x00002000:
+			cte->gpio_tag = 0x08;
+			break;
+		case 0x00010000:
+			cte->gpio_tag = 0x51;
+			break;
+		case 0x00020000:
+			cte->gpio_tag = 0x52;
+			break;
+		default:
+			cte->gpio_tag = 0xff;
+			break;
+		}
+
+		if (cte->type == 0xff)
+			continue;
+
+		NV_INFO(dev, "  %d: 0x%08x: type 0x%02x idx %d tag 0x%02x\n",
+			i, cte->entry, cte->type, cte->index, cte->gpio_tag);
+	}
+}
+
+static struct dcb_entry *new_dcb_entry(struct parsed_dcb *dcb)
+{
+	struct dcb_entry *entry = &dcb->entry[dcb->entries];
+
+	memset(entry, 0, sizeof(struct dcb_entry));
+	entry->index = dcb->entries++;
+
+	return entry;
+}
+
+static void fabricate_vga_output(struct parsed_dcb *dcb, int i2c, int heads)
+{
+	struct dcb_entry *entry = new_dcb_entry(dcb);
+
+	entry->type = 0;
+	entry->i2c_index = i2c;
+	entry->heads = heads;
+	entry->location = DCB_LOC_ON_CHIP;
+	/* "or" mostly unused in early gen crt modesetting, 0 is fine */
+}
+
+static void fabricate_dvi_i_output(struct parsed_dcb *dcb, bool twoHeads)
+{
+	struct dcb_entry *entry = new_dcb_entry(dcb);
+
+	entry->type = 2;
+	entry->i2c_index = LEGACY_I2C_PANEL;
+	entry->heads = twoHeads ? 3 : 1;
+	entry->location = !DCB_LOC_ON_CHIP;	/* ie OFF CHIP */
+	entry->or = 1;	/* means |0x10 gets set on CRE_LCD__INDEX */
+	entry->duallink_possible = false; /* SiI164 and co. are single link */
+
+#if 0
+	/*
+	 * For dvi-a either crtc probably works, but my card appears to only
+	 * support dvi-d.  "nvidia" still attempts to program it for dvi-a,
+	 * doing the full fp output setup (program 0x6808.. fp dimension regs,
+	 * setting 0x680848 to 0x10000111 to enable, maybe setting 0x680880);
+	 * the monitor picks up the mode res ok and lights up, but no pixel
+	 * data appears, so the board manufacturer probably connected up the
+	 * sync lines, but missed the video traces / components
+	 *
+	 * with this introduction, dvi-a left as an exercise for the reader.
+	 */
+	fabricate_vga_output(dcb, LEGACY_I2C_PANEL, entry->heads);
+#endif
+}
+
+static void fabricate_tv_output(struct parsed_dcb *dcb, bool twoHeads)
+{
+	struct dcb_entry *entry = new_dcb_entry(dcb);
+
+	entry->type = 1;
+	entry->i2c_index = LEGACY_I2C_TV;
+	entry->heads = twoHeads ? 3 : 1;
+	entry->location = !DCB_LOC_ON_CHIP;	/* ie OFF CHIP */
+}
+
+static bool
+parse_dcb20_entry(struct drm_device *dev, struct bios_parsed_dcb *bdcb,
+		  uint32_t conn, uint32_t conf, struct dcb_entry *entry)
+{
+	entry->type = conn & 0xf;
+	entry->i2c_index = (conn >> 4) & 0xf;
+	entry->heads = (conn >> 8) & 0xf;
+	if (bdcb->version >= 0x40)
+		entry->connector = (conn >> 12) & 0xf;
+	entry->bus = (conn >> 16) & 0xf;
+	entry->location = (conn >> 20) & 0x3;
+	entry->or = (conn >> 24) & 0xf;
+	/*
+	 * Normal entries consist of a single bit, but dual link has the
+	 * next most significant bit set too
+	 */
+	entry->duallink_possible =
+			((1 << (ffs(entry->or) - 1)) * 3 == entry->or);
+
+	switch (entry->type) {
+	case OUTPUT_ANALOG:
+		/*
+		 * Although the rest of a CRT conf dword is usually
+		 * zeros, mac biosen have stuff there so we must mask
+		 */
+		entry->crtconf.maxfreq = (bdcb->version < 0x30) ?
+					 (conf & 0xffff) * 10 :
+					 (conf & 0xff) * 10000;
+		break;
+	case OUTPUT_LVDS:
+		{
+		uint32_t mask;
+		if (conf & 0x1)
+			entry->lvdsconf.use_straps_for_mode = true;
+		if (bdcb->version < 0x22) {
+			mask = ~0xd;
+			/*
+			 * The laptop in bug 14567 lies and claims to not use
+			 * straps when it does, so assume all DCB 2.0 laptops
+			 * use straps, until a broken EDID using one is produced
+			 */
+			entry->lvdsconf.use_straps_for_mode = true;
+			/*
+			 * Both 0x4 and 0x8 show up in v2.0 tables; assume they
+			 * mean the same thing (probably wrong, but might work)
+			 */
+			if (conf & 0x4 || conf & 0x8)
+				entry->lvdsconf.use_power_scripts = true;
+		} else {
+			mask = ~0x5;
+			if (conf & 0x4)
+				entry->lvdsconf.use_power_scripts = true;
+		}
+		if (conf & mask) {
+			/*
+			 * Until we even try to use these on G8x, it's
+			 * useless reporting unknown bits.  They all are.
+			 */
+			if (bdcb->version >= 0x40)
+				break;
+
+			NV_ERROR(dev, "Unknown LVDS configuration bits, "
+				      "please report\n");
+		}
+		break;
+		}
+	case OUTPUT_TV:
+	{
+		if (bdcb->version >= 0x30)
+			entry->tvconf.has_component_output = conf & (0x8 << 4);
+		else
+			entry->tvconf.has_component_output = false;
+
+		break;
+	}
+	case OUTPUT_DP:
+		entry->dpconf.sor.link = (conf & 0x00000030) >> 4;
+		entry->dpconf.link_bw = (conf & 0x00e00000) >> 21;
+		switch ((conf & 0x0f000000) >> 24) {
+		case 0xf:
+			entry->dpconf.link_nr = 4;
+			break;
+		case 0x3:
+			entry->dpconf.link_nr = 2;
+			break;
+		default:
+			entry->dpconf.link_nr = 1;
+			break;
+		}
+		break;
+	case OUTPUT_TMDS:
+		entry->tmdsconf.sor.link = (conf & 0x00000030) >> 4;
+		break;
+	case 0xe:
+		/* weird g80 mobile type that "nv" treats as a terminator */
+		bdcb->dcb.entries--;
+		return false;
+	}
+
+	/* unsure what DCB version introduces this, 3.0? */
+	if (conf & 0x100000)
+		entry->i2c_upper_default = true;
+
+	return true;
+}
+
+static bool
+parse_dcb15_entry(struct drm_device *dev, struct parsed_dcb *dcb,
+		  uint32_t conn, uint32_t conf, struct dcb_entry *entry)
+{
+	if (conn != 0xf0003f00 && conn != 0xf2247f10 && conn != 0xf2204001 &&
+	    conn != 0xf2204301 && conn != 0xf2204311 && conn != 0xf2208001 &&
+	    conn != 0xf2244001 && conn != 0xf2244301 && conn != 0xf2244311 &&
+	    conn != 0xf4204011 && conn != 0xf4208011 && conn != 0xf4248011 &&
+	    conn != 0xf2045ff2 && conn != 0xf2045f14 && conn != 0xf207df14 &&
+	    conn != 0xf2205004 && conn != 0xf2209004) {
+		NV_ERROR(dev, "Unknown DCB 1.5 entry, please report\n");
+
+		/* cause output setting to fail for !TV, so message is seen */
+		if ((conn & 0xf) != 0x1)
+			dcb->entries = 0;
+
+		return false;
+	}
+	/* most of the below is a "best guess" atm */
+	entry->type = conn & 0xf;
+	if (entry->type == 2)
+		/* another way of specifying straps based lvds... */
+		entry->type = OUTPUT_LVDS;
+	if (entry->type == 4) { /* digital */
+		if (conn & 0x10)
+			entry->type = OUTPUT_LVDS;
+		else
+			entry->type = OUTPUT_TMDS;
+	}
+	/* what's in bits 5-13? could be some encoder maker thing, in tv case */
+	entry->i2c_index = (conn >> 14) & 0xf;
+	/* raw heads field is in range 0-1, so move to 1-2 */
+	entry->heads = ((conn >> 18) & 0x7) + 1;
+	entry->location = (conn >> 21) & 0xf;
+	/* unused: entry->bus = (conn >> 25) & 0x7; */
+	/* set or to be same as heads -- hopefully safe enough */
+	entry->or = entry->heads;
+	entry->duallink_possible = false;
+
+	switch (entry->type) {
+	case OUTPUT_ANALOG:
+		entry->crtconf.maxfreq = (conf & 0xffff) * 10;
+		break;
+	case OUTPUT_LVDS:
+		/*
+		 * This is probably buried in conn's unknown bits.
+		 * This will upset EDID-ful models, if they exist
+		 */
+		entry->lvdsconf.use_straps_for_mode = true;
+		entry->lvdsconf.use_power_scripts = true;
+		break;
+	case OUTPUT_TMDS:
+		/*
+		 * Invent a DVI-A output, by copying the fields of the DVI-D
+		 * output; reported to work by math_b on an NV20(!).
+		 */
+		fabricate_vga_output(dcb, entry->i2c_index, entry->heads);
+		break;
+	case OUTPUT_TV:
+		entry->tvconf.has_component_output = false;
+		break;
+	}
+
+	return true;
+}
+
+static bool parse_dcb_entry(struct drm_device *dev, struct bios_parsed_dcb *bdcb,
+			    uint32_t conn, uint32_t conf)
+{
+	struct dcb_entry *entry = new_dcb_entry(&bdcb->dcb);
+	bool ret;
+
+	if (bdcb->version >= 0x20)
+		ret = parse_dcb20_entry(dev, bdcb, conn, conf, entry);
+	else
+		ret = parse_dcb15_entry(dev, &bdcb->dcb, conn, conf, entry);
+	if (!ret)
+		return ret;
+
+	read_dcb_i2c_entry(dev, bdcb->version, bdcb->i2c_table,
+			   entry->i2c_index, &bdcb->dcb.i2c[entry->i2c_index]);
+
+	return true;
+}
+
+static
+void merge_like_dcb_entries(struct drm_device *dev, struct parsed_dcb *dcb)
+{
+	/*
+	 * DCB v2.0 lists each output combination separately.
+	 * Here we merge compatible entries to have fewer outputs, with
+	 * more options
+	 */
+
+	int i, newentries = 0;
+
+	for (i = 0; i < dcb->entries; i++) {
+		struct dcb_entry *ient = &dcb->entry[i];
+		int j;
+
+		for (j = i + 1; j < dcb->entries; j++) {
+			struct dcb_entry *jent = &dcb->entry[j];
+
+			if (jent->type == 100) /* already merged entry */
+				continue;
+
+			/* merge heads field when all other fields the same */
+			if (jent->i2c_index == ient->i2c_index &&
+			    jent->type == ient->type &&
+			    jent->location == ient->location &&
+			    jent->or == ient->or) {
+				NV_TRACE(dev, "Merging DCB entries %d and %d\n",
+					 i, j);
+				ient->heads |= jent->heads;
+				jent->type = 100; /* dummy value */
+			}
+		}
+	}
+
+	/* Compact entries merged into others out of dcb */
+	for (i = 0; i < dcb->entries; i++) {
+		if (dcb->entry[i].type == 100)
+			continue;
+
+		if (newentries != i) {
+			dcb->entry[newentries] = dcb->entry[i];
+			dcb->entry[newentries].index = newentries;
+		}
+		newentries++;
+	}
+
+	dcb->entries = newentries;
+}
+
+static int parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads)
+{
+	struct bios_parsed_dcb *bdcb = &bios->bdcb;
+	struct parsed_dcb *dcb;
+	uint16_t dcbptr, i2ctabptr = 0;
+	uint8_t *dcbtable;
+	uint8_t headerlen = 0x4, entries = DCB_MAX_NUM_ENTRIES;
+	bool configblock = true;
+	int recordlength = 8, confofs = 4;
+	int i;
+
+	dcb = bios->pub.dcb = &bdcb->dcb;
+	dcb->entries = 0;
+
+	/* get the offset from 0x36 */
+	dcbptr = ROM16(bios->data[0x36]);
+
+	if (dcbptr == 0x0) {
+		NV_WARN(dev, "No output data (DCB) found in BIOS, "
+			       "assuming a CRT output exists\n");
+		/* this situation likely means a really old card, pre DCB */
+		fabricate_vga_output(dcb, LEGACY_I2C_CRT, 1);
+
+		if (nv04_tv_identify(dev,
+				     bios->legacy.i2c_indices.tv) >= 0)
+			fabricate_tv_output(dcb, twoHeads);
+
+		return 0;
+	}
+
+	dcbtable = &bios->data[dcbptr];
+
+	/* get DCB version */
+	bdcb->version = dcbtable[0];
+	NV_TRACE(dev, "Found Display Configuration Block version %d.%d\n",
+		 bdcb->version >> 4, bdcb->version & 0xf);
+
+	if (bdcb->version >= 0x20) { /* NV17+ */
+		uint32_t sig;
+
+		if (bdcb->version >= 0x30) { /* NV40+ */
+			headerlen = dcbtable[1];
+			entries = dcbtable[2];
+			recordlength = dcbtable[3];
+			i2ctabptr = ROM16(dcbtable[4]);
+			sig = ROM32(dcbtable[6]);
+			bdcb->gpio_table_ptr = ROM16(dcbtable[10]);
+			bdcb->connector_table_ptr = ROM16(dcbtable[20]);
+		} else {
+			i2ctabptr = ROM16(dcbtable[2]);
+			sig = ROM32(dcbtable[4]);
+			headerlen = 8;
+		}
+
+		if (sig != 0x4edcbdcb) {
+			NV_ERROR(dev, "Bad Display Configuration Block "
+					"signature (%08X)\n", sig);
+			return -EINVAL;
+		}
+	} else if (bdcb->version >= 0x15) { /* some NV11 and NV20 */
+		char sig[8] = { 0 };
+
+		strncpy(sig, (char *)&dcbtable[-7], 7);
+		i2ctabptr = ROM16(dcbtable[2]);
+		recordlength = 10;
+		confofs = 6;
+
+		if (strcmp(sig, "DEV_REC")) {
+			NV_ERROR(dev, "Bad Display Configuration Block "
+					"signature (%s)\n", sig);
+			return -EINVAL;
+		}
+	} else {
+		/*
+		 * v1.4 (some NV15/16, NV11+) seems the same as v1.5, but always
+		 * has the same single (crt) entry, even when tv-out present, so
+		 * the conclusion is this version cannot really be used.
+		 * v1.2 tables (some NV6/10, and NV15+) normally have the same
+		 * 5 entries, which are not specific to the card and so no use.
+		 * v1.2 does have an I2C table that read_dcb_i2c_table can
+		 * handle, but cards exist (nv11 in #14821) with a bad i2c table
+		 * pointer, so use the indices parsed in parse_bmp_structure.
+		 * v1.1 (NV5+, maybe some NV4) is entirely unhelpful
+		 */
+		NV_TRACEWARN(dev, "No useful information in BIOS output table; "
+				  "adding all possible outputs\n");
+		fabricate_vga_output(dcb, LEGACY_I2C_CRT, 1);
+
+		/*
+		 * Attempt to detect TV before DVI because the test
+		 * for the former is more accurate and it rules the
+		 * latter out.
+		 */
+		if (nv04_tv_identify(dev,
+				     bios->legacy.i2c_indices.tv) >= 0)
+			fabricate_tv_output(dcb, twoHeads);
+
+		else if (bios->tmds.output0_script_ptr ||
+			 bios->tmds.output1_script_ptr)
+			fabricate_dvi_i_output(dcb, twoHeads);
+
+		return 0;
+	}
+
+	if (!i2ctabptr)
+		NV_WARN(dev, "No pointer to DCB I2C port table\n");
+	else {
+		bdcb->i2c_table = &bios->data[i2ctabptr];
+		if (bdcb->version >= 0x30)
+			bdcb->i2c_default_indices = bdcb->i2c_table[4];
+	}
+
+	parse_dcb_gpio_table(bios);
+	parse_dcb_connector_table(bios);
+
+	if (entries > DCB_MAX_NUM_ENTRIES)
+		entries = DCB_MAX_NUM_ENTRIES;
+
+	for (i = 0; i < entries; i++) {
+		uint32_t connection, config = 0;
+
+		connection = ROM32(dcbtable[headerlen + recordlength * i]);
+		if (configblock)
+			config = ROM32(dcbtable[headerlen + confofs + recordlength * i]);
+
+		/* seen on an NV11 with DCB v1.5 */
+		if (connection == 0x00000000)
+			break;
+
+		/* seen on an NV17 with DCB v2.0 */
+		if (connection == 0xffffffff)
+			break;
+
+		if ((connection & 0x0000000f) == 0x0000000f)
+			continue;
+
+		NV_TRACEWARN(dev, "Raw DCB entry %d: %08x %08x\n",
+			     dcb->entries, connection, config);
+
+		if (!parse_dcb_entry(dev, bdcb, connection, config))
+			break;
+	}
+
+	/*
+	 * apart for v2.1+ not being known for requiring merging, this
+	 * guarantees dcbent->index is the index of the entry in the rom image
+	 */
+	if (bdcb->version < 0x21)
+		merge_like_dcb_entries(dev, dcb);
+
+	return dcb->entries ? 0 : -ENXIO;
+}
+
+static void
+fixup_legacy_connector(struct nvbios *bios)
+{
+	struct bios_parsed_dcb *bdcb = &bios->bdcb;
+	struct parsed_dcb *dcb = &bdcb->dcb;
+	int high = 0, i;
+
+	/*
+	 * DCB 3.0 also has the table in most cases, but there are some cards
+	 * where the table is filled with stub entries, and the DCB entriy
+	 * indices are all 0.  We don't need the connector indices on pre-G80
+	 * chips (yet?) so limit the use to DCB 4.0 and above.
+	 */
+	if (bdcb->version >= 0x40)
+		return;
+
+	/*
+	 * No known connector info before v3.0, so make it up.  the rule here
+	 * is: anything on the same i2c bus is considered to be on the same
+	 * connector.  any output without an associated i2c bus is assigned
+	 * its own unique connector index.
+	 */
+	for (i = 0; i < dcb->entries; i++) {
+		if (dcb->entry[i].i2c_index == 0xf)
+			continue;
+
+		/*
+		 * Ignore the I2C index for on-chip TV-out, as there
+		 * are cards with bogus values (nv31m in bug 23212),
+		 * and it's otherwise useless.
+		 */
+		if (dcb->entry[i].type == OUTPUT_TV &&
+		    dcb->entry[i].location == DCB_LOC_ON_CHIP) {
+			dcb->entry[i].i2c_index = 0xf;
+			continue;
+		}
+
+		dcb->entry[i].connector = dcb->entry[i].i2c_index;
+		if (dcb->entry[i].connector > high)
+			high = dcb->entry[i].connector;
+	}
+
+	for (i = 0; i < dcb->entries; i++) {
+		if (dcb->entry[i].i2c_index != 0xf)
+			continue;
+
+		dcb->entry[i].connector = ++high;
+	}
+}
+
+static void
+fixup_legacy_i2c(struct nvbios *bios)
+{
+	struct parsed_dcb *dcb = &bios->bdcb.dcb;
+	int i;
+
+	for (i = 0; i < dcb->entries; i++) {
+		if (dcb->entry[i].i2c_index == LEGACY_I2C_CRT)
+			dcb->entry[i].i2c_index = bios->legacy.i2c_indices.crt;
+		if (dcb->entry[i].i2c_index == LEGACY_I2C_PANEL)
+			dcb->entry[i].i2c_index = bios->legacy.i2c_indices.panel;
+		if (dcb->entry[i].i2c_index == LEGACY_I2C_TV)
+			dcb->entry[i].i2c_index = bios->legacy.i2c_indices.tv;
+	}
+}
+
+static int load_nv17_hwsq_ucode_entry(struct drm_device *dev, struct nvbios *bios, uint16_t hwsq_offset, int entry)
+{
+	/*
+	 * The header following the "HWSQ" signature has the number of entries,
+	 * and the entry size
+	 *
+	 * An entry consists of a dword to write to the sequencer control reg
+	 * (0x00001304), followed by the ucode bytes, written sequentially,
+	 * starting at reg 0x00001400
+	 */
+
+	uint8_t bytes_to_write;
+	uint16_t hwsq_entry_offset;
+	int i;
+
+	if (bios->data[hwsq_offset] <= entry) {
+		NV_ERROR(dev, "Too few entries in HW sequencer table for "
+				"requested entry\n");
+		return -ENOENT;
+	}
+
+	bytes_to_write = bios->data[hwsq_offset + 1];
+
+	if (bytes_to_write != 36) {
+		NV_ERROR(dev, "Unknown HW sequencer entry size\n");
+		return -EINVAL;
+	}
+
+	NV_TRACE(dev, "Loading NV17 power sequencing microcode\n");
+
+	hwsq_entry_offset = hwsq_offset + 2 + entry * bytes_to_write;
+
+	/* set sequencer control */
+	bios_wr32(bios, 0x00001304, ROM32(bios->data[hwsq_entry_offset]));
+	bytes_to_write -= 4;
+
+	/* write ucode */
+	for (i = 0; i < bytes_to_write; i += 4)
+		bios_wr32(bios, 0x00001400 + i, ROM32(bios->data[hwsq_entry_offset + i + 4]));
+
+	/* twiddle NV_PBUS_DEBUG_4 */
+	bios_wr32(bios, NV_PBUS_DEBUG_4, bios_rd32(bios, NV_PBUS_DEBUG_4) | 0x18);
+
+	return 0;
+}
+
+static int load_nv17_hw_sequencer_ucode(struct drm_device *dev,
+					struct nvbios *bios)
+{
+	/*
+	 * BMP based cards, from NV17, need a microcode loading to correctly
+	 * control the GPIO etc for LVDS panels
+	 *
+	 * BIT based cards seem to do this directly in the init scripts
+	 *
+	 * The microcode entries are found by the "HWSQ" signature.
+	 */
+
+	const uint8_t hwsq_signature[] = { 'H', 'W', 'S', 'Q' };
+	const int sz = sizeof(hwsq_signature);
+	int hwsq_offset;
+
+	hwsq_offset = findstr(bios->data, bios->length, hwsq_signature, sz);
+	if (!hwsq_offset)
+		return 0;
+
+	/* always use entry 0? */
+	return load_nv17_hwsq_ucode_entry(dev, bios, hwsq_offset + sz, 0);
+}
+
+uint8_t *nouveau_bios_embedded_edid(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	const uint8_t edid_sig[] = {
+			0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
+	uint16_t offset = 0;
+	uint16_t newoffset;
+	int searchlen = NV_PROM_SIZE;
+
+	if (bios->fp.edid)
+		return bios->fp.edid;
+
+	while (searchlen) {
+		newoffset = findstr(&bios->data[offset], searchlen,
+								edid_sig, 8);
+		if (!newoffset)
+			return NULL;
+		offset += newoffset;
+		if (!nv_cksum(&bios->data[offset], EDID1_LEN))
+			break;
+
+		searchlen -= offset;
+		offset++;
+	}
+
+	NV_TRACE(dev, "Found EDID in BIOS\n");
+
+	return bios->fp.edid = &bios->data[offset];
+}
+
+void
+nouveau_bios_run_init_table(struct drm_device *dev, uint16_t table,
+			    struct dcb_entry *dcbent)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	struct init_exec iexec = { true, false };
+
+	bios->display.output = dcbent;
+	parse_init_table(bios, table, &iexec);
+	bios->display.output = NULL;
+}
+
+static bool NVInitVBIOS(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+
+	memset(bios, 0, sizeof(struct nvbios));
+	bios->dev = dev;
+
+	if (!NVShadowVBIOS(dev, bios->data))
+		return false;
+
+	bios->length = NV_PROM_SIZE;
+	return true;
+}
+
+static int nouveau_parse_vbios_struct(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	const uint8_t bit_signature[] = { 0xff, 0xb8, 'B', 'I', 'T' };
+	const uint8_t bmp_signature[] = { 0xff, 0x7f, 'N', 'V', 0x0 };
+	int offset;
+
+	offset = findstr(bios->data, bios->length,
+					bit_signature, sizeof(bit_signature));
+	if (offset) {
+		NV_TRACE(dev, "BIT BIOS found\n");
+		return parse_bit_structure(bios, offset + 6);
+	}
+
+	offset = findstr(bios->data, bios->length,
+					bmp_signature, sizeof(bmp_signature));
+	if (offset) {
+		NV_TRACE(dev, "BMP BIOS found\n");
+		return parse_bmp_structure(dev, bios, offset);
+	}
+
+	NV_ERROR(dev, "No known BIOS signature found\n");
+	return -ENODEV;
+}
+
+int
+nouveau_run_vbios_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	int i, ret = 0;
+
+	NVLockVgaCrtcs(dev, false);
+	if (nv_two_heads(dev))
+		NVSetOwner(dev, bios->state.crtchead);
+
+	if (bios->major_version < 5)	/* BMP only */
+		load_nv17_hw_sequencer_ucode(dev, bios);
+
+	if (bios->execute) {
+		bios->fp.last_script_invoc = 0;
+		bios->fp.lvds_init_run = false;
+	}
+
+	parse_init_tables(bios);
+
+	/*
+	 * Runs some additional script seen on G8x VBIOSen.  The VBIOS'
+	 * parser will run this right after the init tables, the binary
+	 * driver appears to run it at some point later.
+	 */
+	if (bios->some_script_ptr) {
+		struct init_exec iexec = {true, false};
+
+		NV_INFO(dev, "Parsing VBIOS init table at offset 0x%04X\n",
+			bios->some_script_ptr);
+		parse_init_table(bios, bios->some_script_ptr, &iexec);
+	}
+
+	if (dev_priv->card_type >= NV_50) {
+		for (i = 0; i < bios->bdcb.dcb.entries; i++) {
+			nouveau_bios_run_display_table(dev,
+						       &bios->bdcb.dcb.entry[i],
+						       0, 0);
+		}
+	}
+
+	NVLockVgaCrtcs(dev, true);
+
+	return ret;
+}
+
+static void
+nouveau_bios_i2c_devices_takedown(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	struct dcb_i2c_entry *entry;
+	int i;
+
+	entry = &bios->bdcb.dcb.i2c[0];
+	for (i = 0; i < DCB_MAX_NUM_I2C_ENTRIES; i++, entry++)
+		nouveau_i2c_fini(dev, entry);
+}
+
+int
+nouveau_bios_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	uint32_t saved_nv_pextdev_boot_0;
+	bool was_locked;
+	int ret;
+
+	dev_priv->vbios = &bios->pub;
+
+	if (!NVInitVBIOS(dev))
+		return -ENODEV;
+
+	ret = nouveau_parse_vbios_struct(dev);
+	if (ret)
+		return ret;
+
+	ret = parse_dcb_table(dev, bios, nv_two_heads(dev));
+	if (ret)
+		return ret;
+
+	fixup_legacy_i2c(bios);
+	fixup_legacy_connector(bios);
+
+	if (!bios->major_version)	/* we don't run version 0 bios */
+		return 0;
+
+	/* these will need remembering across a suspend */
+	saved_nv_pextdev_boot_0 = bios_rd32(bios, NV_PEXTDEV_BOOT_0);
+	bios->state.saved_nv_pfb_cfg0 = bios_rd32(bios, NV_PFB_CFG0);
+
+	/* init script execution disabled */
+	bios->execute = false;
+
+	/* ... unless card isn't POSTed already */
+	if (dev_priv->card_type >= NV_10 &&
+	    NVReadVgaCrtc(dev, 0, 0x00) == 0 &&
+	    NVReadVgaCrtc(dev, 0, 0x1a) == 0) {
+		NV_INFO(dev, "Adaptor not initialised\n");
+		if (dev_priv->card_type < NV_50) {
+			NV_ERROR(dev, "Unable to POST this chipset\n");
+			return -ENODEV;
+		}
+
+		NV_INFO(dev, "Running VBIOS init tables\n");
+		bios->execute = true;
+	}
+
+	bios_wr32(bios, NV_PEXTDEV_BOOT_0, saved_nv_pextdev_boot_0);
+
+	ret = nouveau_run_vbios_init(dev);
+	if (ret) {
+		dev_priv->vbios = NULL;
+		return ret;
+	}
+
+	/* feature_byte on BMP is poor, but init always sets CR4B */
+	was_locked = NVLockVgaCrtcs(dev, false);
+	if (bios->major_version < 5)
+		bios->is_mobile = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_4B) & 0x40;
+
+	/* all BIT systems need p_f_m_t for digital_min_front_porch */
+	if (bios->is_mobile || bios->major_version >= 5)
+		ret = parse_fp_mode_table(dev, bios);
+	NVLockVgaCrtcs(dev, was_locked);
+
+	/* allow subsequent scripts to execute */
+	bios->execute = true;
+
+	return 0;
+}
+
+void
+nouveau_bios_takedown(struct drm_device *dev)
+{
+	nouveau_bios_i2c_devices_takedown(dev);
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h
new file mode 100644
index 0000000..1d5f10b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.h
@@ -0,0 +1,289 @@
+/*
+ * Copyright 2007-2008 Nouveau Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __NOUVEAU_BIOS_H__
+#define __NOUVEAU_BIOS_H__
+
+#include "nvreg.h"
+#include "nouveau_i2c.h"
+
+#define DCB_MAX_NUM_ENTRIES 16
+#define DCB_MAX_NUM_I2C_ENTRIES 16
+#define DCB_MAX_NUM_GPIO_ENTRIES 32
+#define DCB_MAX_NUM_CONNECTOR_ENTRIES 16
+
+#define DCB_LOC_ON_CHIP 0
+
+struct dcb_entry {
+	int index;	/* may not be raw dcb index if merging has happened */
+	uint8_t type;
+	uint8_t i2c_index;
+	uint8_t heads;
+	uint8_t connector;
+	uint8_t bus;
+	uint8_t location;
+	uint8_t or;
+	bool duallink_possible;
+	union {
+		struct sor_conf {
+			int link;
+		} sorconf;
+		struct {
+			int maxfreq;
+		} crtconf;
+		struct {
+			struct sor_conf sor;
+			bool use_straps_for_mode;
+			bool use_power_scripts;
+		} lvdsconf;
+		struct {
+			bool has_component_output;
+		} tvconf;
+		struct {
+			struct sor_conf sor;
+			int link_nr;
+			int link_bw;
+		} dpconf;
+		struct {
+			struct sor_conf sor;
+		} tmdsconf;
+	};
+	bool i2c_upper_default;
+};
+
+struct dcb_i2c_entry {
+	uint8_t port_type;
+	uint8_t read, write;
+	struct nouveau_i2c_chan *chan;
+};
+
+struct parsed_dcb {
+	int entries;
+	struct dcb_entry entry[DCB_MAX_NUM_ENTRIES];
+	struct dcb_i2c_entry i2c[DCB_MAX_NUM_I2C_ENTRIES];
+};
+
+enum dcb_gpio_tag {
+	DCB_GPIO_TVDAC0 = 0xc,
+	DCB_GPIO_TVDAC1 = 0x2d,
+};
+
+struct dcb_gpio_entry {
+	enum dcb_gpio_tag tag;
+	int line;
+	bool invert;
+};
+
+struct parsed_dcb_gpio {
+	int entries;
+	struct dcb_gpio_entry entry[DCB_MAX_NUM_GPIO_ENTRIES];
+};
+
+struct dcb_connector_table_entry {
+	uint32_t entry;
+	uint8_t type;
+	uint8_t index;
+	uint8_t gpio_tag;
+};
+
+struct dcb_connector_table {
+	int entries;
+	struct dcb_connector_table_entry entry[DCB_MAX_NUM_CONNECTOR_ENTRIES];
+};
+
+struct bios_parsed_dcb {
+	uint8_t version;
+
+	struct parsed_dcb dcb;
+
+	uint8_t *i2c_table;
+	uint8_t i2c_default_indices;
+
+	uint16_t gpio_table_ptr;
+	struct parsed_dcb_gpio gpio;
+	uint16_t connector_table_ptr;
+	struct dcb_connector_table connector;
+};
+
+enum nouveau_encoder_type {
+	OUTPUT_ANALOG = 0,
+	OUTPUT_TV = 1,
+	OUTPUT_TMDS = 2,
+	OUTPUT_LVDS = 3,
+	OUTPUT_DP = 6,
+	OUTPUT_ANY = -1
+};
+
+enum nouveau_or {
+	OUTPUT_A = (1 << 0),
+	OUTPUT_B = (1 << 1),
+	OUTPUT_C = (1 << 2)
+};
+
+enum LVDS_script {
+	/* Order *does* matter here */
+	LVDS_INIT = 1,
+	LVDS_RESET,
+	LVDS_BACKLIGHT_ON,
+	LVDS_BACKLIGHT_OFF,
+	LVDS_PANEL_ON,
+	LVDS_PANEL_OFF
+};
+
+/* changing these requires matching changes to reg tables in nv_get_clock */
+#define MAX_PLL_TYPES	4
+enum pll_types {
+	NVPLL,
+	MPLL,
+	VPLL1,
+	VPLL2
+};
+
+struct pll_lims {
+	struct {
+		int minfreq;
+		int maxfreq;
+		int min_inputfreq;
+		int max_inputfreq;
+
+		uint8_t min_m;
+		uint8_t max_m;
+		uint8_t min_n;
+		uint8_t max_n;
+	} vco1, vco2;
+
+	uint8_t max_log2p;
+	/*
+	 * for most pre nv50 cards setting a log2P of 7 (the common max_log2p
+	 * value) is no different to 6 (at least for vplls) so allowing the MNP
+	 * calc to use 7 causes the generated clock to be out by a factor of 2.
+	 * however, max_log2p cannot be fixed-up during parsing as the
+	 * unmodified max_log2p value is still needed for setting mplls, hence
+	 * an additional max_usable_log2p member
+	 */
+	uint8_t max_usable_log2p;
+	uint8_t log2p_bias;
+
+	uint8_t min_p;
+	uint8_t max_p;
+
+	int refclk;
+};
+
+struct nouveau_bios_info {
+	struct parsed_dcb *dcb;
+
+	uint8_t chip_version;
+
+	uint32_t dactestval;
+	uint32_t tvdactestval;
+	uint8_t digital_min_front_porch;
+	bool fp_no_ddc;
+};
+
+struct nvbios {
+	struct drm_device *dev;
+	struct nouveau_bios_info pub;
+
+	uint8_t data[NV_PROM_SIZE];
+	unsigned int length;
+	bool execute;
+
+	uint8_t major_version;
+	uint8_t feature_byte;
+	bool is_mobile;
+
+	uint32_t fmaxvco, fminvco;
+
+	bool old_style_init;
+	uint16_t init_script_tbls_ptr;
+	uint16_t extra_init_script_tbl_ptr;
+	uint16_t macro_index_tbl_ptr;
+	uint16_t macro_tbl_ptr;
+	uint16_t condition_tbl_ptr;
+	uint16_t io_condition_tbl_ptr;
+	uint16_t io_flag_condition_tbl_ptr;
+	uint16_t init_function_tbl_ptr;
+
+	uint16_t pll_limit_tbl_ptr;
+	uint16_t ram_restrict_tbl_ptr;
+
+	uint16_t some_script_ptr; /* BIT I + 14 */
+	uint16_t init96_tbl_ptr; /* BIT I + 16 */
+
+	struct bios_parsed_dcb bdcb;
+
+	struct {
+		int crtchead;
+		/* these need remembering across suspend */
+		uint32_t saved_nv_pfb_cfg0;
+	} state;
+
+	struct {
+		struct dcb_entry *output;
+		uint16_t script_table_ptr;
+		uint16_t dp_table_ptr;
+	} display;
+
+	struct {
+		uint16_t fptablepointer;	/* also used by tmds */
+		uint16_t fpxlatetableptr;
+		int xlatwidth;
+		uint16_t lvdsmanufacturerpointer;
+		uint16_t fpxlatemanufacturertableptr;
+		uint16_t mode_ptr;
+		uint16_t xlated_entry;
+		bool power_off_for_reset;
+		bool reset_after_pclk_change;
+		bool dual_link;
+		bool link_c_increment;
+		bool BITbit1;
+		bool if_is_24bit;
+		int duallink_transition_clk;
+		uint8_t strapless_is_24bit;
+		uint8_t *edid;
+
+		/* will need resetting after suspend */
+		int last_script_invoc;
+		bool lvds_init_run;
+	} fp;
+
+	struct {
+		uint16_t output0_script_ptr;
+		uint16_t output1_script_ptr;
+	} tmds;
+
+	struct {
+		uint16_t mem_init_tbl_ptr;
+		uint16_t sdr_seq_tbl_ptr;
+		uint16_t ddr_seq_tbl_ptr;
+
+		struct {
+			uint8_t crt, tv, panel;
+		} i2c_indices;
+
+		uint16_t lvds_single_a_script_ptr;
+	} legacy;
+};
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
new file mode 100644
index 0000000..320a14b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -0,0 +1,671 @@
+/*
+ * Copyright 2007 Dave Airlied
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * Authors: Dave Airlied <airlied@linux.ie>
+ *	    Ben Skeggs   <darktama@iinet.net.au>
+ *	    Jeremy Kolb  <jkolb@brandeis.edu>
+ */
+
+#include "drmP.h"
+
+#include "nouveau_drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_dma.h"
+
+static void
+nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
+{
+	struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
+	struct nouveau_bo *nvbo = nouveau_bo(bo);
+
+	ttm_bo_kunmap(&nvbo->kmap);
+
+	if (unlikely(nvbo->gem))
+		DRM_ERROR("bo %p still attached to GEM object\n", bo);
+
+	spin_lock(&dev_priv->ttm.bo_list_lock);
+	list_del(&nvbo->head);
+	spin_unlock(&dev_priv->ttm.bo_list_lock);
+	kfree(nvbo);
+}
+
+int
+nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,
+	       int size, int align, uint32_t flags, uint32_t tile_mode,
+	       uint32_t tile_flags, bool no_vm, bool mappable,
+	       struct nouveau_bo **pnvbo)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_bo *nvbo;
+	int ret, n = 0;
+
+	nvbo = kzalloc(sizeof(struct nouveau_bo), GFP_KERNEL);
+	if (!nvbo)
+		return -ENOMEM;
+	INIT_LIST_HEAD(&nvbo->head);
+	INIT_LIST_HEAD(&nvbo->entry);
+	nvbo->mappable = mappable;
+	nvbo->no_vm = no_vm;
+	nvbo->tile_mode = tile_mode;
+	nvbo->tile_flags = tile_flags;
+
+	/*
+	 * Some of the tile_flags have a periodic structure of N*4096 bytes,
+	 * align to to that as well as the page size. Overallocate memory to
+	 * avoid corruption of other buffer objects.
+	 */
+	switch (tile_flags) {
+	case 0x1800:
+	case 0x2800:
+	case 0x4800:
+	case 0x7a00:
+		if (dev_priv->chipset >= 0xA0) {
+			/* This is based on high end cards with 448 bits
+			 * memory bus, could be different elsewhere.*/
+			size += 6 * 28672;
+			/* 8 * 28672 is the actual alignment requirement,
+			 * but we must also align to page size. */
+			align = 2 * 8 * 28672;
+		} else if (dev_priv->chipset >= 0x90) {
+			size += 3 * 16384;
+			align = 12 * 16834;
+		} else {
+			size += 3 * 8192;
+			/* 12 * 8192 is the actual alignment requirement,
+			 * but we must also align to page size. */
+			align = 2 * 12 * 8192;
+		}
+		break;
+	default:
+		break;
+	}
+
+	align >>= PAGE_SHIFT;
+
+	size = (size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
+	if (dev_priv->card_type == NV_50) {
+		size = (size + 65535) & ~65535;
+		if (align < (65536 / PAGE_SIZE))
+			align = (65536 / PAGE_SIZE);
+	}
+
+	if (flags & TTM_PL_FLAG_VRAM)
+		nvbo->placements[n++] = TTM_PL_FLAG_VRAM | TTM_PL_MASK_CACHING;
+	if (flags & TTM_PL_FLAG_TT)
+		nvbo->placements[n++] = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING;
+	nvbo->placement.fpfn = 0;
+	nvbo->placement.lpfn = mappable ? dev_priv->fb_mappable_pages : 0;
+	nvbo->placement.placement = nvbo->placements;
+	nvbo->placement.busy_placement = nvbo->placements;
+	nvbo->placement.num_placement = n;
+	nvbo->placement.num_busy_placement = n;
+
+	nvbo->channel = chan;
+	nouveau_bo_placement_set(nvbo, flags);
+	ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size,
+			  ttm_bo_type_device, &nvbo->placement, align, 0,
+			  false, NULL, size, nouveau_bo_del_ttm);
+	nvbo->channel = NULL;
+	if (ret) {
+		/* ttm will call nouveau_bo_del_ttm if it fails.. */
+		return ret;
+	}
+
+	spin_lock(&dev_priv->ttm.bo_list_lock);
+	list_add_tail(&nvbo->head, &dev_priv->ttm.bo_list);
+	spin_unlock(&dev_priv->ttm.bo_list_lock);
+	*pnvbo = nvbo;
+	return 0;
+}
+
+void
+nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t memtype)
+{
+	int n = 0;
+
+	if (memtype & TTM_PL_FLAG_VRAM)
+		nvbo->placements[n++] = TTM_PL_FLAG_VRAM | TTM_PL_MASK_CACHING;
+	if (memtype & TTM_PL_FLAG_TT)
+		nvbo->placements[n++] = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING;
+	if (memtype & TTM_PL_FLAG_SYSTEM)
+		nvbo->placements[n++] = TTM_PL_FLAG_SYSTEM | TTM_PL_MASK_CACHING;
+	nvbo->placement.placement = nvbo->placements;
+	nvbo->placement.busy_placement = nvbo->placements;
+	nvbo->placement.num_placement = n;
+	nvbo->placement.num_busy_placement = n;
+}
+
+int
+nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype)
+{
+	struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
+	struct ttm_buffer_object *bo = &nvbo->bo;
+	int ret, i;
+
+	if (nvbo->pin_refcnt && !(memtype & (1 << bo->mem.mem_type))) {
+		NV_ERROR(nouveau_bdev(bo->bdev)->dev,
+			 "bo %p pinned elsewhere: 0x%08x vs 0x%08x\n", bo,
+			 1 << bo->mem.mem_type, memtype);
+		return -EINVAL;
+	}
+
+	if (nvbo->pin_refcnt++)
+		return 0;
+
+	ret = ttm_bo_reserve(bo, false, false, false, 0);
+	if (ret)
+		goto out;
+
+	nouveau_bo_placement_set(nvbo, memtype);
+	for (i = 0; i < nvbo->placement.num_placement; i++)
+		nvbo->placements[i] |= TTM_PL_FLAG_NO_EVICT;
+
+	ret = ttm_bo_validate(bo, &nvbo->placement, false, false);
+	if (ret == 0) {
+		switch (bo->mem.mem_type) {
+		case TTM_PL_VRAM:
+			dev_priv->fb_aper_free -= bo->mem.size;
+			break;
+		case TTM_PL_TT:
+			dev_priv->gart_info.aper_free -= bo->mem.size;
+			break;
+		default:
+			break;
+		}
+	}
+	ttm_bo_unreserve(bo);
+out:
+	if (unlikely(ret))
+		nvbo->pin_refcnt--;
+	return ret;
+}
+
+int
+nouveau_bo_unpin(struct nouveau_bo *nvbo)
+{
+	struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
+	struct ttm_buffer_object *bo = &nvbo->bo;
+	int ret, i;
+
+	if (--nvbo->pin_refcnt)
+		return 0;
+
+	ret = ttm_bo_reserve(bo, false, false, false, 0);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < nvbo->placement.num_placement; i++)
+		nvbo->placements[i] &= ~TTM_PL_FLAG_NO_EVICT;
+
+	ret = ttm_bo_validate(bo, &nvbo->placement, false, false);
+	if (ret == 0) {
+		switch (bo->mem.mem_type) {
+		case TTM_PL_VRAM:
+			dev_priv->fb_aper_free += bo->mem.size;
+			break;
+		case TTM_PL_TT:
+			dev_priv->gart_info.aper_free += bo->mem.size;
+			break;
+		default:
+			break;
+		}
+	}
+
+	ttm_bo_unreserve(bo);
+	return ret;
+}
+
+int
+nouveau_bo_map(struct nouveau_bo *nvbo)
+{
+	int ret;
+
+	ret = ttm_bo_reserve(&nvbo->bo, false, false, false, 0);
+	if (ret)
+		return ret;
+
+	ret = ttm_bo_kmap(&nvbo->bo, 0, nvbo->bo.mem.num_pages, &nvbo->kmap);
+	ttm_bo_unreserve(&nvbo->bo);
+	return ret;
+}
+
+void
+nouveau_bo_unmap(struct nouveau_bo *nvbo)
+{
+	ttm_bo_kunmap(&nvbo->kmap);
+}
+
+u16
+nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index)
+{
+	bool is_iomem;
+	u16 *mem = ttm_kmap_obj_virtual(&nvbo->kmap, &is_iomem);
+	mem = &mem[index];
+	if (is_iomem)
+		return ioread16_native((void __force __iomem *)mem);
+	else
+		return *mem;
+}
+
+void
+nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val)
+{
+	bool is_iomem;
+	u16 *mem = ttm_kmap_obj_virtual(&nvbo->kmap, &is_iomem);
+	mem = &mem[index];
+	if (is_iomem)
+		iowrite16_native(val, (void __force __iomem *)mem);
+	else
+		*mem = val;
+}
+
+u32
+nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index)
+{
+	bool is_iomem;
+	u32 *mem = ttm_kmap_obj_virtual(&nvbo->kmap, &is_iomem);
+	mem = &mem[index];
+	if (is_iomem)
+		return ioread32_native((void __force __iomem *)mem);
+	else
+		return *mem;
+}
+
+void
+nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val)
+{
+	bool is_iomem;
+	u32 *mem = ttm_kmap_obj_virtual(&nvbo->kmap, &is_iomem);
+	mem = &mem[index];
+	if (is_iomem)
+		iowrite32_native(val, (void __force __iomem *)mem);
+	else
+		*mem = val;
+}
+
+static struct ttm_backend *
+nouveau_bo_create_ttm_backend_entry(struct ttm_bo_device *bdev)
+{
+	struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev);
+	struct drm_device *dev = dev_priv->dev;
+
+	switch (dev_priv->gart_info.type) {
+	case NOUVEAU_GART_AGP:
+		return ttm_agp_backend_init(bdev, dev->agp->bridge);
+	case NOUVEAU_GART_SGDMA:
+		return nouveau_sgdma_init_ttm(dev);
+	default:
+		NV_ERROR(dev, "Unknown GART type %d\n",
+			 dev_priv->gart_info.type);
+		break;
+	}
+
+	return NULL;
+}
+
+static int
+nouveau_bo_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags)
+{
+	/* We'll do this from user space. */
+	return 0;
+}
+
+static int
+nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
+			 struct ttm_mem_type_manager *man)
+{
+	struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev);
+	struct drm_device *dev = dev_priv->dev;
+
+	switch (type) {
+	case TTM_PL_SYSTEM:
+		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
+		man->available_caching = TTM_PL_MASK_CACHING;
+		man->default_caching = TTM_PL_FLAG_CACHED;
+		break;
+	case TTM_PL_VRAM:
+		man->flags = TTM_MEMTYPE_FLAG_FIXED |
+			     TTM_MEMTYPE_FLAG_MAPPABLE |
+			     TTM_MEMTYPE_FLAG_NEEDS_IOREMAP;
+		man->available_caching = TTM_PL_FLAG_UNCACHED |
+					 TTM_PL_FLAG_WC;
+		man->default_caching = TTM_PL_FLAG_WC;
+
+		man->io_addr = NULL;
+		man->io_offset = drm_get_resource_start(dev, 1);
+		man->io_size = drm_get_resource_len(dev, 1);
+		if (man->io_size > nouveau_mem_fb_amount(dev))
+			man->io_size = nouveau_mem_fb_amount(dev);
+
+		man->gpu_offset = dev_priv->vm_vram_base;
+		break;
+	case TTM_PL_TT:
+		switch (dev_priv->gart_info.type) {
+		case NOUVEAU_GART_AGP:
+			man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
+				     TTM_MEMTYPE_FLAG_NEEDS_IOREMAP;
+			man->available_caching = TTM_PL_FLAG_UNCACHED;
+			man->default_caching = TTM_PL_FLAG_UNCACHED;
+			break;
+		case NOUVEAU_GART_SGDMA:
+			man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
+				     TTM_MEMTYPE_FLAG_CMA;
+			man->available_caching = TTM_PL_MASK_CACHING;
+			man->default_caching = TTM_PL_FLAG_CACHED;
+			break;
+		default:
+			NV_ERROR(dev, "Unknown GART type: %d\n",
+				 dev_priv->gart_info.type);
+			return -EINVAL;
+		}
+
+		man->io_offset  = dev_priv->gart_info.aper_base;
+		man->io_size    = dev_priv->gart_info.aper_size;
+		man->io_addr   = NULL;
+		man->gpu_offset = dev_priv->vm_gart_base;
+		break;
+	default:
+		NV_ERROR(dev, "Unsupported memory type %u\n", (unsigned)type);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static void
+nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
+{
+	struct nouveau_bo *nvbo = nouveau_bo(bo);
+
+	switch (bo->mem.mem_type) {
+	default:
+		nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM);
+		break;
+	}
+}
+
+
+/* GPU-assisted copy using NV_MEMORY_TO_MEMORY_FORMAT, can access
+ * TTM_PL_{VRAM,TT} directly.
+ */
+static int
+nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan,
+			      struct nouveau_bo *nvbo, bool evict, bool no_wait,
+			      struct ttm_mem_reg *new_mem)
+{
+	struct nouveau_fence *fence = NULL;
+	int ret;
+
+	ret = nouveau_fence_new(chan, &fence, true);
+	if (ret)
+		return ret;
+
+	ret = ttm_bo_move_accel_cleanup(&nvbo->bo, fence, NULL,
+					evict, no_wait, new_mem);
+	nouveau_fence_unref((void *)&fence);
+	return ret;
+}
+
+static inline uint32_t
+nouveau_bo_mem_ctxdma(struct nouveau_bo *nvbo, struct nouveau_channel *chan,
+		      struct ttm_mem_reg *mem)
+{
+	if (chan == nouveau_bdev(nvbo->bo.bdev)->channel) {
+		if (mem->mem_type == TTM_PL_TT)
+			return NvDmaGART;
+		return NvDmaVRAM;
+	}
+
+	if (mem->mem_type == TTM_PL_TT)
+		return chan->gart_handle;
+	return chan->vram_handle;
+}
+
+static int
+nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, int no_wait,
+		     struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
+{
+	struct nouveau_bo *nvbo = nouveau_bo(bo);
+	struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
+	struct nouveau_channel *chan;
+	uint64_t src_offset, dst_offset;
+	uint32_t page_count;
+	int ret;
+
+	chan = nvbo->channel;
+	if (!chan || nvbo->tile_flags || nvbo->no_vm) {
+		chan = dev_priv->channel;
+		if (!chan)
+			return -EINVAL;
+	}
+
+	src_offset = old_mem->mm_node->start << PAGE_SHIFT;
+	dst_offset = new_mem->mm_node->start << PAGE_SHIFT;
+	if (chan != dev_priv->channel) {
+		if (old_mem->mem_type == TTM_PL_TT)
+			src_offset += dev_priv->vm_gart_base;
+		else
+			src_offset += dev_priv->vm_vram_base;
+
+		if (new_mem->mem_type == TTM_PL_TT)
+			dst_offset += dev_priv->vm_gart_base;
+		else
+			dst_offset += dev_priv->vm_vram_base;
+	}
+
+	ret = RING_SPACE(chan, 3);
+	if (ret)
+		return ret;
+	BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_SOURCE, 2);
+	OUT_RING(chan, nouveau_bo_mem_ctxdma(nvbo, chan, old_mem));
+	OUT_RING(chan, nouveau_bo_mem_ctxdma(nvbo, chan, new_mem));
+
+	if (dev_priv->card_type >= NV_50) {
+		ret = RING_SPACE(chan, 4);
+		if (ret)
+			return ret;
+		BEGIN_RING(chan, NvSubM2MF, 0x0200, 1);
+		OUT_RING(chan, 1);
+		BEGIN_RING(chan, NvSubM2MF, 0x021c, 1);
+		OUT_RING(chan, 1);
+	}
+
+	page_count = new_mem->num_pages;
+	while (page_count) {
+		int line_count = (page_count > 2047) ? 2047 : page_count;
+
+		if (dev_priv->card_type >= NV_50) {
+			ret = RING_SPACE(chan, 3);
+			if (ret)
+				return ret;
+			BEGIN_RING(chan, NvSubM2MF, 0x0238, 2);
+			OUT_RING(chan, upper_32_bits(src_offset));
+			OUT_RING(chan, upper_32_bits(dst_offset));
+		}
+		ret = RING_SPACE(chan, 11);
+		if (ret)
+			return ret;
+		BEGIN_RING(chan, NvSubM2MF,
+				 NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
+		OUT_RING(chan, lower_32_bits(src_offset));
+		OUT_RING(chan, lower_32_bits(dst_offset));
+		OUT_RING(chan, PAGE_SIZE); /* src_pitch */
+		OUT_RING(chan, PAGE_SIZE); /* dst_pitch */
+		OUT_RING(chan, PAGE_SIZE); /* line_length */
+		OUT_RING(chan, line_count);
+		OUT_RING(chan, (1<<8)|(1<<0));
+		OUT_RING(chan, 0);
+		BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NOP, 1);
+		OUT_RING(chan, 0);
+
+		page_count -= line_count;
+		src_offset += (PAGE_SIZE * line_count);
+		dst_offset += (PAGE_SIZE * line_count);
+	}
+
+	return nouveau_bo_move_accel_cleanup(chan, nvbo, evict, no_wait, new_mem);
+}
+
+static int
+nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr,
+		      bool no_wait, struct ttm_mem_reg *new_mem)
+{
+	u32 placement_memtype = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING;
+	struct ttm_placement placement;
+	struct ttm_mem_reg tmp_mem;
+	int ret;
+
+	placement.fpfn = placement.lpfn = 0;
+	placement.num_placement = placement.num_busy_placement = 1;
+	placement.placement = &placement_memtype;
+
+	tmp_mem = *new_mem;
+	tmp_mem.mm_node = NULL;
+	ret = ttm_bo_mem_space(bo, &placement, &tmp_mem, intr, no_wait);
+	if (ret)
+		return ret;
+
+	ret = ttm_tt_bind(bo->ttm, &tmp_mem);
+	if (ret)
+		goto out;
+
+	ret = nouveau_bo_move_m2mf(bo, true, no_wait, &bo->mem, &tmp_mem);
+	if (ret)
+		goto out;
+
+	ret = ttm_bo_move_ttm(bo, evict, no_wait, new_mem);
+out:
+	if (tmp_mem.mm_node) {
+		spin_lock(&bo->bdev->glob->lru_lock);
+		drm_mm_put_block(tmp_mem.mm_node);
+		spin_unlock(&bo->bdev->glob->lru_lock);
+	}
+
+	return ret;
+}
+
+static int
+nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr,
+		      bool no_wait, struct ttm_mem_reg *new_mem)
+{
+	u32 placement_memtype = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING;
+	struct ttm_placement placement;
+	struct ttm_mem_reg tmp_mem;
+	int ret;
+
+	placement.fpfn = placement.lpfn = 0;
+	placement.num_placement = placement.num_busy_placement = 1;
+	placement.placement = &placement_memtype;
+
+	tmp_mem = *new_mem;
+	tmp_mem.mm_node = NULL;
+	ret = ttm_bo_mem_space(bo, &placement, &tmp_mem, intr, no_wait);
+	if (ret)
+		return ret;
+
+	ret = ttm_bo_move_ttm(bo, evict, no_wait, &tmp_mem);
+	if (ret)
+		goto out;
+
+	ret = nouveau_bo_move_m2mf(bo, true, no_wait, &bo->mem, new_mem);
+	if (ret)
+		goto out;
+
+out:
+	if (tmp_mem.mm_node) {
+		spin_lock(&bo->bdev->glob->lru_lock);
+		drm_mm_put_block(tmp_mem.mm_node);
+		spin_unlock(&bo->bdev->glob->lru_lock);
+	}
+
+	return ret;
+}
+
+static int
+nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr,
+		bool no_wait, struct ttm_mem_reg *new_mem)
+{
+	struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
+	struct nouveau_bo *nvbo = nouveau_bo(bo);
+	struct drm_device *dev = dev_priv->dev;
+	struct ttm_mem_reg *old_mem = &bo->mem;
+	int ret;
+
+	if (dev_priv->card_type == NV_50 && new_mem->mem_type == TTM_PL_VRAM &&
+	    !nvbo->no_vm) {
+		uint64_t offset = new_mem->mm_node->start << PAGE_SHIFT;
+
+		ret = nv50_mem_vm_bind_linear(dev,
+					      offset + dev_priv->vm_vram_base,
+					      new_mem->size, nvbo->tile_flags,
+					      offset);
+		if (ret)
+			return ret;
+	}
+
+	if (dev_priv->init_state != NOUVEAU_CARD_INIT_DONE)
+		return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem);
+
+	if (old_mem->mem_type == TTM_PL_SYSTEM && !bo->ttm) {
+		BUG_ON(bo->mem.mm_node != NULL);
+		bo->mem = *new_mem;
+		new_mem->mm_node = NULL;
+		return 0;
+	}
+
+	if (new_mem->mem_type == TTM_PL_SYSTEM) {
+		if (old_mem->mem_type == TTM_PL_SYSTEM)
+			return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem);
+		if (nouveau_bo_move_flipd(bo, evict, intr, no_wait, new_mem))
+			return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem);
+	} else if (old_mem->mem_type == TTM_PL_SYSTEM) {
+		if (nouveau_bo_move_flips(bo, evict, intr, no_wait, new_mem))
+			return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem);
+	} else {
+		if (nouveau_bo_move_m2mf(bo, evict, no_wait, old_mem, new_mem))
+			return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem);
+	}
+
+	return 0;
+}
+
+static int
+nouveau_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp)
+{
+	return 0;
+}
+
+struct ttm_bo_driver nouveau_bo_driver = {
+	.create_ttm_backend_entry = nouveau_bo_create_ttm_backend_entry,
+	.invalidate_caches = nouveau_bo_invalidate_caches,
+	.init_mem_type = nouveau_bo_init_mem_type,
+	.evict_flags = nouveau_bo_evict_flags,
+	.move = nouveau_bo_move,
+	.verify_access = nouveau_bo_verify_access,
+	.sync_obj_signaled = nouveau_fence_signalled,
+	.sync_obj_wait = nouveau_fence_wait,
+	.sync_obj_flush = nouveau_fence_flush,
+	.sync_obj_unref = nouveau_fence_unref,
+	.sync_obj_ref = nouveau_fence_ref,
+};
+
diff --git a/drivers/gpu/drm/nouveau/nouveau_calc.c b/drivers/gpu/drm/nouveau/nouveau_calc.c
new file mode 100644
index 0000000..ee2b845
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_calc.c
@@ -0,0 +1,478 @@
+/*
+ * Copyright 1993-2003 NVIDIA, Corporation
+ * Copyright 2007-2009 Stuart Bennett
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_hw.h"
+
+/****************************************************************************\
+*                                                                            *
+* The video arbitration routines calculate some "magic" numbers.  Fixes      *
+* the snow seen when accessing the framebuffer without it.                   *
+* It just works (I hope).                                                    *
+*                                                                            *
+\****************************************************************************/
+
+struct nv_fifo_info {
+	int lwm;
+	int burst;
+};
+
+struct nv_sim_state {
+	int pclk_khz;
+	int mclk_khz;
+	int nvclk_khz;
+	int bpp;
+	int mem_page_miss;
+	int mem_latency;
+	int memory_type;
+	int memory_width;
+	int two_heads;
+};
+
+static void
+nv04_calc_arb(struct nv_fifo_info *fifo, struct nv_sim_state *arb)
+{
+	int pagemiss, cas, width, bpp;
+	int nvclks, mclks, pclks, crtpagemiss;
+	int found, mclk_extra, mclk_loop, cbs, m1, p1;
+	int mclk_freq, pclk_freq, nvclk_freq;
+	int us_m, us_n, us_p, crtc_drain_rate;
+	int cpm_us, us_crt, clwm;
+
+	pclk_freq = arb->pclk_khz;
+	mclk_freq = arb->mclk_khz;
+	nvclk_freq = arb->nvclk_khz;
+	pagemiss = arb->mem_page_miss;
+	cas = arb->mem_latency;
+	width = arb->memory_width >> 6;
+	bpp = arb->bpp;
+	cbs = 128;
+
+	pclks = 2;
+	nvclks = 10;
+	mclks = 13 + cas;
+	mclk_extra = 3;
+	found = 0;
+
+	while (!found) {
+		found = 1;
+
+		mclk_loop = mclks + mclk_extra;
+		us_m = mclk_loop * 1000 * 1000 / mclk_freq;
+		us_n = nvclks * 1000 * 1000 / nvclk_freq;
+		us_p = nvclks * 1000 * 1000 / pclk_freq;
+
+		crtc_drain_rate = pclk_freq * bpp / 8;
+		crtpagemiss = 2;
+		crtpagemiss += 1;
+		cpm_us = crtpagemiss * pagemiss * 1000 * 1000 / mclk_freq;
+		us_crt = cpm_us + us_m + us_n + us_p;
+		clwm = us_crt * crtc_drain_rate / (1000 * 1000);
+		clwm++;
+
+		m1 = clwm + cbs - 512;
+		p1 = m1 * pclk_freq / mclk_freq;
+		p1 = p1 * bpp / 8;
+		if ((p1 < m1 && m1 > 0) || clwm > 519) {
+			found = !mclk_extra;
+			mclk_extra--;
+		}
+		if (clwm < 384)
+			clwm = 384;
+
+		fifo->lwm = clwm;
+		fifo->burst = cbs;
+	}
+}
+
+static void
+nv10_calc_arb(struct nv_fifo_info *fifo, struct nv_sim_state *arb)
+{
+	int fill_rate, drain_rate;
+	int pclks, nvclks, mclks, xclks;
+	int pclk_freq, nvclk_freq, mclk_freq;
+	int fill_lat, extra_lat;
+	int max_burst_o, max_burst_l;
+	int fifo_len, min_lwm, max_lwm;
+	const int burst_lat = 80; /* Maximum allowable latency due
+				   * to the CRTC FIFO burst. (ns) */
+
+	pclk_freq = arb->pclk_khz;
+	nvclk_freq = arb->nvclk_khz;
+	mclk_freq = arb->mclk_khz;
+
+	fill_rate = mclk_freq * arb->memory_width / 8; /* kB/s */
+	drain_rate = pclk_freq * arb->bpp / 8; /* kB/s */
+
+	fifo_len = arb->two_heads ? 1536 : 1024; /* B */
+
+	/* Fixed FIFO refill latency. */
+
+	pclks = 4;	/* lwm detect. */
+
+	nvclks = 3	/* lwm -> sync. */
+		+ 2	/* fbi bus cycles (1 req + 1 busy) */
+		+ 1	/* 2 edge sync.  may be very close to edge so
+			 * just put one. */
+		+ 1	/* fbi_d_rdv_n */
+		+ 1	/* Fbi_d_rdata */
+		+ 1;	/* crtfifo load */
+
+	mclks = 1	/* 2 edge sync.  may be very close to edge so
+			 * just put one. */
+		+ 1	/* arb_hp_req */
+		+ 5	/* tiling pipeline */
+		+ 2	/* latency fifo */
+		+ 2	/* memory request to fbio block */
+		+ 7;	/* data returned from fbio block */
+
+	/* Need to accumulate 256 bits for read */
+	mclks += (arb->memory_type == 0 ? 2 : 1)
+		* arb->memory_width / 32;
+
+	fill_lat = mclks * 1000 * 1000 / mclk_freq   /* minimum mclk latency */
+		+ nvclks * 1000 * 1000 / nvclk_freq  /* nvclk latency */
+		+ pclks * 1000 * 1000 / pclk_freq;   /* pclk latency */
+
+	/* Conditional FIFO refill latency. */
+
+	xclks = 2 * arb->mem_page_miss + mclks /* Extra latency due to
+						* the overlay. */
+		+ 2 * arb->mem_page_miss       /* Extra pagemiss latency. */
+		+ (arb->bpp == 32 ? 8 : 4);    /* Margin of error. */
+
+	extra_lat = xclks * 1000 * 1000 / mclk_freq;
+
+	if (arb->two_heads)
+		/* Account for another CRTC. */
+		extra_lat += fill_lat + extra_lat + burst_lat;
+
+	/* FIFO burst */
+
+	/* Max burst not leading to overflows. */
+	max_burst_o = (1 + fifo_len - extra_lat * drain_rate / (1000 * 1000))
+		* (fill_rate / 1000) / ((fill_rate - drain_rate) / 1000);
+	fifo->burst = min(max_burst_o, 1024);
+
+	/* Max burst value with an acceptable latency. */
+	max_burst_l = burst_lat * fill_rate / (1000 * 1000);
+	fifo->burst = min(max_burst_l, fifo->burst);
+
+	fifo->burst = rounddown_pow_of_two(fifo->burst);
+
+	/* FIFO low watermark */
+
+	min_lwm = (fill_lat + extra_lat) * drain_rate / (1000 * 1000) + 1;
+	max_lwm = fifo_len - fifo->burst
+		+ fill_lat * drain_rate / (1000 * 1000)
+		+ fifo->burst * drain_rate / fill_rate;
+
+	fifo->lwm = min_lwm + 10 * (max_lwm - min_lwm) / 100; /* Empirical. */
+}
+
+static void
+nv04_update_arb(struct drm_device *dev, int VClk, int bpp,
+		int *burst, int *lwm)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv_fifo_info fifo_data;
+	struct nv_sim_state sim_data;
+	int MClk = nouveau_hw_get_clock(dev, MPLL);
+	int NVClk = nouveau_hw_get_clock(dev, NVPLL);
+	uint32_t cfg1 = nvReadFB(dev, NV_PFB_CFG1);
+
+	sim_data.pclk_khz = VClk;
+	sim_data.mclk_khz = MClk;
+	sim_data.nvclk_khz = NVClk;
+	sim_data.bpp = bpp;
+	sim_data.two_heads = nv_two_heads(dev);
+	if ((dev->pci_device & 0xffff) == 0x01a0 /*CHIPSET_NFORCE*/ ||
+	    (dev->pci_device & 0xffff) == 0x01f0 /*CHIPSET_NFORCE2*/) {
+		uint32_t type;
+
+		pci_read_config_dword(pci_get_bus_and_slot(0, 1), 0x7c, &type);
+
+		sim_data.memory_type = (type >> 12) & 1;
+		sim_data.memory_width = 64;
+		sim_data.mem_latency = 3;
+		sim_data.mem_page_miss = 10;
+	} else {
+		sim_data.memory_type = nvReadFB(dev, NV_PFB_CFG0) & 0x1;
+		sim_data.memory_width = (nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) & 0x10) ? 128 : 64;
+		sim_data.mem_latency = cfg1 & 0xf;
+		sim_data.mem_page_miss = ((cfg1 >> 4) & 0xf) + ((cfg1 >> 31) & 0x1);
+	}
+
+	if (dev_priv->card_type == NV_04)
+		nv04_calc_arb(&fifo_data, &sim_data);
+	else
+		nv10_calc_arb(&fifo_data, &sim_data);
+
+	*burst = ilog2(fifo_data.burst >> 4);
+	*lwm = fifo_data.lwm >> 3;
+}
+
+static void
+nv30_update_arb(int *burst, int *lwm)
+{
+	unsigned int fifo_size, burst_size, graphics_lwm;
+
+	fifo_size = 2048;
+	burst_size = 512;
+	graphics_lwm = fifo_size - burst_size;
+
+	*burst = ilog2(burst_size >> 5);
+	*lwm = graphics_lwm >> 3;
+}
+
+void
+nouveau_calc_arb(struct drm_device *dev, int vclk, int bpp, int *burst, int *lwm)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->card_type < NV_30)
+		nv04_update_arb(dev, vclk, bpp, burst, lwm);
+	else if ((dev->pci_device & 0xfff0) == 0x0240 /*CHIPSET_C51*/ ||
+		 (dev->pci_device & 0xfff0) == 0x03d0 /*CHIPSET_C512*/) {
+		*burst = 128;
+		*lwm = 0x0480;
+	} else
+		nv30_update_arb(burst, lwm);
+}
+
+static int
+getMNP_single(struct drm_device *dev, struct pll_lims *pll_lim, int clk,
+	      struct nouveau_pll_vals *bestpv)
+{
+	/* Find M, N and P for a single stage PLL
+	 *
+	 * Note that some bioses (NV3x) have lookup tables of precomputed MNP
+	 * values, but we're too lazy to use those atm
+	 *
+	 * "clk" parameter in kHz
+	 * returns calculated clock
+	 */
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int cv = dev_priv->vbios->chip_version;
+	int minvco = pll_lim->vco1.minfreq, maxvco = pll_lim->vco1.maxfreq;
+	int minM = pll_lim->vco1.min_m, maxM = pll_lim->vco1.max_m;
+	int minN = pll_lim->vco1.min_n, maxN = pll_lim->vco1.max_n;
+	int minU = pll_lim->vco1.min_inputfreq;
+	int maxU = pll_lim->vco1.max_inputfreq;
+	int minP = pll_lim->max_p ? pll_lim->min_p : 0;
+	int maxP = pll_lim->max_p ? pll_lim->max_p : pll_lim->max_usable_log2p;
+	int crystal = pll_lim->refclk;
+	int M, N, thisP, P;
+	int clkP, calcclk;
+	int delta, bestdelta = INT_MAX;
+	int bestclk = 0;
+
+	/* this division verified for nv20, nv18, nv28 (Haiku), and nv34 */
+	/* possibly correlated with introduction of 27MHz crystal */
+	if (dev_priv->card_type < NV_50) {
+		if (cv < 0x17 || cv == 0x1a || cv == 0x20) {
+			if (clk > 250000)
+				maxM = 6;
+			if (clk > 340000)
+				maxM = 2;
+		} else if (cv < 0x40) {
+			if (clk > 150000)
+				maxM = 6;
+			if (clk > 200000)
+				maxM = 4;
+			if (clk > 340000)
+				maxM = 2;
+		}
+	}
+
+	P = pll_lim->max_p ? maxP : (1 << maxP);
+	if ((clk * P) < minvco) {
+		minvco = clk * maxP;
+		maxvco = minvco * 2;
+	}
+
+	if (clk + clk/200 > maxvco)	/* +0.5% */
+		maxvco = clk + clk/200;
+
+	/* NV34 goes maxlog2P->0, NV20 goes 0->maxlog2P */
+	for (thisP = minP; thisP <= maxP; thisP++) {
+		P = pll_lim->max_p ? thisP : (1 << thisP);
+		clkP = clk * P;
+
+		if (clkP < minvco)
+			continue;
+		if (clkP > maxvco)
+			return bestclk;
+
+		for (M = minM; M <= maxM; M++) {
+			if (crystal/M < minU)
+				return bestclk;
+			if (crystal/M > maxU)
+				continue;
+
+			/* add crystal/2 to round better */
+			N = (clkP * M + crystal/2) / crystal;
+
+			if (N < minN)
+				continue;
+			if (N > maxN)
+				break;
+
+			/* more rounding additions */
+			calcclk = ((N * crystal + P/2) / P + M/2) / M;
+			delta = abs(calcclk - clk);
+			/* we do an exhaustive search rather than terminating
+			 * on an optimality condition...
+			 */
+			if (delta < bestdelta) {
+				bestdelta = delta;
+				bestclk = calcclk;
+				bestpv->N1 = N;
+				bestpv->M1 = M;
+				bestpv->log2P = thisP;
+				if (delta == 0)	/* except this one */
+					return bestclk;
+			}
+		}
+	}
+
+	return bestclk;
+}
+
+static int
+getMNP_double(struct drm_device *dev, struct pll_lims *pll_lim, int clk,
+	      struct nouveau_pll_vals *bestpv)
+{
+	/* Find M, N and P for a two stage PLL
+	 *
+	 * Note that some bioses (NV30+) have lookup tables of precomputed MNP
+	 * values, but we're too lazy to use those atm
+	 *
+	 * "clk" parameter in kHz
+	 * returns calculated clock
+	 */
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int chip_version = dev_priv->vbios->chip_version;
+	int minvco1 = pll_lim->vco1.minfreq, maxvco1 = pll_lim->vco1.maxfreq;
+	int minvco2 = pll_lim->vco2.minfreq, maxvco2 = pll_lim->vco2.maxfreq;
+	int minU1 = pll_lim->vco1.min_inputfreq, minU2 = pll_lim->vco2.min_inputfreq;
+	int maxU1 = pll_lim->vco1.max_inputfreq, maxU2 = pll_lim->vco2.max_inputfreq;
+	int minM1 = pll_lim->vco1.min_m, maxM1 = pll_lim->vco1.max_m;
+	int minN1 = pll_lim->vco1.min_n, maxN1 = pll_lim->vco1.max_n;
+	int minM2 = pll_lim->vco2.min_m, maxM2 = pll_lim->vco2.max_m;
+	int minN2 = pll_lim->vco2.min_n, maxN2 = pll_lim->vco2.max_n;
+	int maxlog2P = pll_lim->max_usable_log2p;
+	int crystal = pll_lim->refclk;
+	bool fixedgain2 = (minM2 == maxM2 && minN2 == maxN2);
+	int M1, N1, M2, N2, log2P;
+	int clkP, calcclk1, calcclk2, calcclkout;
+	int delta, bestdelta = INT_MAX;
+	int bestclk = 0;
+
+	int vco2 = (maxvco2 - maxvco2/200) / 2;
+	for (log2P = 0; clk && log2P < maxlog2P && clk <= (vco2 >> log2P); log2P++)
+		;
+	clkP = clk << log2P;
+
+	if (maxvco2 < clk + clk/200)	/* +0.5% */
+		maxvco2 = clk + clk/200;
+
+	for (M1 = minM1; M1 <= maxM1; M1++) {
+		if (crystal/M1 < minU1)
+			return bestclk;
+		if (crystal/M1 > maxU1)
+			continue;
+
+		for (N1 = minN1; N1 <= maxN1; N1++) {
+			calcclk1 = crystal * N1 / M1;
+			if (calcclk1 < minvco1)
+				continue;
+			if (calcclk1 > maxvco1)
+				break;
+
+			for (M2 = minM2; M2 <= maxM2; M2++) {
+				if (calcclk1/M2 < minU2)
+					break;
+				if (calcclk1/M2 > maxU2)
+					continue;
+
+				/* add calcclk1/2 to round better */
+				N2 = (clkP * M2 + calcclk1/2) / calcclk1;
+				if (N2 < minN2)
+					continue;
+				if (N2 > maxN2)
+					break;
+
+				if (!fixedgain2) {
+					if (chip_version < 0x60)
+						if (N2/M2 < 4 || N2/M2 > 10)
+							continue;
+
+					calcclk2 = calcclk1 * N2 / M2;
+					if (calcclk2 < minvco2)
+						break;
+					if (calcclk2 > maxvco2)
+						continue;
+				} else
+					calcclk2 = calcclk1;
+
+				calcclkout = calcclk2 >> log2P;
+				delta = abs(calcclkout - clk);
+				/* we do an exhaustive search rather than terminating
+				 * on an optimality condition...
+				 */
+				if (delta < bestdelta) {
+					bestdelta = delta;
+					bestclk = calcclkout;
+					bestpv->N1 = N1;
+					bestpv->M1 = M1;
+					bestpv->N2 = N2;
+					bestpv->M2 = M2;
+					bestpv->log2P = log2P;
+					if (delta == 0)	/* except this one */
+						return bestclk;
+				}
+			}
+		}
+	}
+
+	return bestclk;
+}
+
+int
+nouveau_calc_pll_mnp(struct drm_device *dev, struct pll_lims *pll_lim, int clk,
+		     struct nouveau_pll_vals *pv)
+{
+	int outclk;
+
+	if (!pll_lim->vco2.maxfreq)
+		outclk = getMNP_single(dev, pll_lim, clk, pv);
+	else
+		outclk = getMNP_double(dev, pll_lim, clk, pv);
+
+	if (!outclk)
+		NV_ERROR(dev, "Could not find a compatible set of PLL values\n");
+
+	return outclk;
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c
new file mode 100644
index 0000000..9aaa972
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_channel.c
@@ -0,0 +1,468 @@
+/*
+ * Copyright 2005-2006 Stephane Marchesin
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+#include "nouveau_dma.h"
+
+static int
+nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_bo *pb = chan->pushbuf_bo;
+	struct nouveau_gpuobj *pushbuf = NULL;
+	uint32_t start = pb->bo.mem.mm_node->start << PAGE_SHIFT;
+	int ret;
+
+	if (pb->bo.mem.mem_type == TTM_PL_TT) {
+		ret = nouveau_gpuobj_gart_dma_new(chan, 0,
+						  dev_priv->gart_info.aper_size,
+						  NV_DMA_ACCESS_RO, &pushbuf,
+						  NULL);
+		chan->pushbuf_base = start;
+	} else
+	if (dev_priv->card_type != NV_04) {
+		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0,
+					     dev_priv->fb_available_size,
+					     NV_DMA_ACCESS_RO,
+					     NV_DMA_TARGET_VIDMEM, &pushbuf);
+		chan->pushbuf_base = start;
+	} else {
+		/* NV04 cmdbuf hack, from original ddx.. not sure of it's
+		 * exact reason for existing :)  PCI access to cmdbuf in
+		 * VRAM.
+		 */
+		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
+					     drm_get_resource_start(dev, 1),
+					     dev_priv->fb_available_size,
+					     NV_DMA_ACCESS_RO,
+					     NV_DMA_TARGET_PCI, &pushbuf);
+		chan->pushbuf_base = start;
+	}
+
+	ret = nouveau_gpuobj_ref_add(dev, chan, 0, pushbuf, &chan->pushbuf);
+	if (ret) {
+		NV_ERROR(dev, "Error referencing pushbuf ctxdma: %d\n", ret);
+		if (pushbuf != dev_priv->gart_info.sg_ctxdma)
+			nouveau_gpuobj_del(dev, &pushbuf);
+		return ret;
+	}
+
+	return 0;
+}
+
+static struct nouveau_bo *
+nouveau_channel_user_pushbuf_alloc(struct drm_device *dev)
+{
+	struct nouveau_bo *pushbuf = NULL;
+	int location, ret;
+
+	if (nouveau_vram_pushbuf)
+		location = TTM_PL_FLAG_VRAM;
+	else
+		location = TTM_PL_FLAG_TT;
+
+	ret = nouveau_bo_new(dev, NULL, 65536, 0, location, 0, 0x0000, false,
+			     true, &pushbuf);
+	if (ret) {
+		NV_ERROR(dev, "error allocating DMA push buffer: %d\n", ret);
+		return NULL;
+	}
+
+	ret = nouveau_bo_pin(pushbuf, location);
+	if (ret) {
+		NV_ERROR(dev, "error pinning DMA push buffer: %d\n", ret);
+		nouveau_bo_ref(NULL, &pushbuf);
+		return NULL;
+	}
+
+	return pushbuf;
+}
+
+/* allocates and initializes a fifo for user space consumption */
+int
+nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
+		      struct drm_file *file_priv,
+		      uint32_t vram_handle, uint32_t tt_handle)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	struct nouveau_channel *chan;
+	int channel, user;
+	int ret;
+
+	/*
+	 * Alright, here is the full story
+	 * Nvidia cards have multiple hw fifo contexts (praise them for that,
+	 * no complicated crash-prone context switches)
+	 * We allocate a new context for each app and let it write to it
+	 * directly (woo, full userspace command submission !)
+	 * When there are no more contexts, you lost
+	 */
+	for (channel = 0; channel < pfifo->channels; channel++) {
+		if (dev_priv->fifos[channel] == NULL)
+			break;
+	}
+
+	/* no more fifos. you lost. */
+	if (channel == pfifo->channels)
+		return -EINVAL;
+
+	dev_priv->fifos[channel] = kzalloc(sizeof(struct nouveau_channel),
+					   GFP_KERNEL);
+	if (!dev_priv->fifos[channel])
+		return -ENOMEM;
+	dev_priv->fifo_alloc_count++;
+	chan = dev_priv->fifos[channel];
+	INIT_LIST_HEAD(&chan->nvsw.vbl_wait);
+	INIT_LIST_HEAD(&chan->fence.pending);
+	chan->dev = dev;
+	chan->id = channel;
+	chan->file_priv = file_priv;
+	chan->vram_handle = vram_handle;
+	chan->gart_handle = tt_handle;
+
+	NV_INFO(dev, "Allocating FIFO number %d\n", channel);
+
+	/* Allocate DMA push buffer */
+	chan->pushbuf_bo = nouveau_channel_user_pushbuf_alloc(dev);
+	if (!chan->pushbuf_bo) {
+		ret = -ENOMEM;
+		NV_ERROR(dev, "pushbuf %d\n", ret);
+		nouveau_channel_free(chan);
+		return ret;
+	}
+
+	/* Locate channel's user control regs */
+	if (dev_priv->card_type < NV_40)
+		user = NV03_USER(channel);
+	else
+	if (dev_priv->card_type < NV_50)
+		user = NV40_USER(channel);
+	else
+		user = NV50_USER(channel);
+
+	chan->user = ioremap(pci_resource_start(dev->pdev, 0) + user,
+								PAGE_SIZE);
+	if (!chan->user) {
+		NV_ERROR(dev, "ioremap of regs failed.\n");
+		nouveau_channel_free(chan);
+		return -ENOMEM;
+	}
+	chan->user_put = 0x40;
+	chan->user_get = 0x44;
+
+	/* Allocate space for per-channel fixed notifier memory */
+	ret = nouveau_notifier_init_channel(chan);
+	if (ret) {
+		NV_ERROR(dev, "ntfy %d\n", ret);
+		nouveau_channel_free(chan);
+		return ret;
+	}
+
+	/* Setup channel's default objects */
+	ret = nouveau_gpuobj_channel_init(chan, vram_handle, tt_handle);
+	if (ret) {
+		NV_ERROR(dev, "gpuobj %d\n", ret);
+		nouveau_channel_free(chan);
+		return ret;
+	}
+
+	/* Create a dma object for the push buffer */
+	ret = nouveau_channel_pushbuf_ctxdma_init(chan);
+	if (ret) {
+		NV_ERROR(dev, "pbctxdma %d\n", ret);
+		nouveau_channel_free(chan);
+		return ret;
+	}
+
+	/* disable the fifo caches */
+	pfifo->reassign(dev, false);
+
+	/* Create a graphics context for new channel */
+	ret = pgraph->create_context(chan);
+	if (ret) {
+		nouveau_channel_free(chan);
+		return ret;
+	}
+
+	/* Construct inital RAMFC for new channel */
+	ret = pfifo->create_context(chan);
+	if (ret) {
+		nouveau_channel_free(chan);
+		return ret;
+	}
+
+	pfifo->reassign(dev, true);
+
+	ret = nouveau_dma_init(chan);
+	if (!ret)
+		ret = nouveau_fence_init(chan);
+	if (ret) {
+		nouveau_channel_free(chan);
+		return ret;
+	}
+
+	nouveau_debugfs_channel_init(chan);
+
+	NV_INFO(dev, "%s: initialised FIFO %d\n", __func__, channel);
+	*chan_ret = chan;
+	return 0;
+}
+
+int
+nouveau_channel_idle(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
+	uint32_t caches;
+	int idle;
+
+	if (!chan) {
+		NV_ERROR(dev, "no channel...\n");
+		return 1;
+	}
+
+	caches = nv_rd32(dev, NV03_PFIFO_CACHES);
+	nv_wr32(dev, NV03_PFIFO_CACHES, caches & ~1);
+
+	if (engine->fifo.channel_id(dev) != chan->id) {
+		struct nouveau_gpuobj *ramfc =
+			chan->ramfc ? chan->ramfc->gpuobj : NULL;
+
+		if (!ramfc) {
+			NV_ERROR(dev, "No RAMFC for channel %d\n", chan->id);
+			return 1;
+		}
+
+		engine->instmem.prepare_access(dev, false);
+		if (nv_ro32(dev, ramfc, 0) != nv_ro32(dev, ramfc, 1))
+			idle = 0;
+		else
+			idle = 1;
+		engine->instmem.finish_access(dev);
+	} else {
+		idle = (nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET) ==
+			nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT));
+	}
+
+	nv_wr32(dev, NV03_PFIFO_CACHES, caches);
+	return idle;
+}
+
+/* stops a fifo */
+void
+nouveau_channel_free(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	unsigned long flags;
+	int ret;
+
+	NV_INFO(dev, "%s: freeing fifo %d\n", __func__, chan->id);
+
+	nouveau_debugfs_channel_fini(chan);
+
+	/* Give outstanding push buffers a chance to complete */
+	spin_lock_irqsave(&chan->fence.lock, flags);
+	nouveau_fence_update(chan);
+	spin_unlock_irqrestore(&chan->fence.lock, flags);
+	if (chan->fence.sequence != chan->fence.sequence_ack) {
+		struct nouveau_fence *fence = NULL;
+
+		ret = nouveau_fence_new(chan, &fence, true);
+		if (ret == 0) {
+			ret = nouveau_fence_wait(fence, NULL, false, false);
+			nouveau_fence_unref((void *)&fence);
+		}
+
+		if (ret)
+			NV_ERROR(dev, "Failed to idle channel %d.\n", chan->id);
+	}
+
+	/* Ensure all outstanding fences are signaled.  They should be if the
+	 * above attempts at idling were OK, but if we failed this'll tell TTM
+	 * we're done with the buffers.
+	 */
+	nouveau_fence_fini(chan);
+
+	/* Ensure the channel is no longer active on the GPU */
+	pfifo->reassign(dev, false);
+
+	if (pgraph->channel(dev) == chan) {
+		pgraph->fifo_access(dev, false);
+		pgraph->unload_context(dev);
+		pgraph->fifo_access(dev, true);
+	}
+	pgraph->destroy_context(chan);
+
+	if (pfifo->channel_id(dev) == chan->id) {
+		pfifo->disable(dev);
+		pfifo->unload_context(dev);
+		pfifo->enable(dev);
+	}
+	pfifo->destroy_context(chan);
+
+	pfifo->reassign(dev, true);
+
+	/* Release the channel's resources */
+	nouveau_gpuobj_ref_del(dev, &chan->pushbuf);
+	if (chan->pushbuf_bo) {
+		nouveau_bo_unpin(chan->pushbuf_bo);
+		nouveau_bo_ref(NULL, &chan->pushbuf_bo);
+	}
+	nouveau_gpuobj_channel_takedown(chan);
+	nouveau_notifier_takedown_channel(chan);
+	if (chan->user)
+		iounmap(chan->user);
+
+	dev_priv->fifos[chan->id] = NULL;
+	dev_priv->fifo_alloc_count--;
+	kfree(chan);
+}
+
+/* cleans up all the fifos from file_priv */
+void
+nouveau_channel_cleanup(struct drm_device *dev, struct drm_file *file_priv)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
+	int i;
+
+	NV_DEBUG(dev, "clearing FIFO enables from file_priv\n");
+	for (i = 0; i < engine->fifo.channels; i++) {
+		struct nouveau_channel *chan = dev_priv->fifos[i];
+
+		if (chan && chan->file_priv == file_priv)
+			nouveau_channel_free(chan);
+	}
+}
+
+int
+nouveau_channel_owner(struct drm_device *dev, struct drm_file *file_priv,
+		      int channel)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
+
+	if (channel >= engine->fifo.channels)
+		return 0;
+	if (dev_priv->fifos[channel] == NULL)
+		return 0;
+
+	return (dev_priv->fifos[channel]->file_priv == file_priv);
+}
+
+/***********************************
+ * ioctls wrapping the functions
+ ***********************************/
+
+static int
+nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data,
+			 struct drm_file *file_priv)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_nouveau_channel_alloc *init = data;
+	struct nouveau_channel *chan;
+	int ret;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
+	if (dev_priv->engine.graph.accel_blocked)
+		return -ENODEV;
+
+	if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0)
+		return -EINVAL;
+
+	ret = nouveau_channel_alloc(dev, &chan, file_priv,
+				    init->fb_ctxdma_handle,
+				    init->tt_ctxdma_handle);
+	if (ret)
+		return ret;
+	init->channel  = chan->id;
+
+	init->subchan[0].handle = NvM2MF;
+	if (dev_priv->card_type < NV_50)
+		init->subchan[0].grclass = 0x0039;
+	else
+		init->subchan[0].grclass = 0x5039;
+	init->nr_subchan = 1;
+
+	/* Named memory object area */
+	ret = drm_gem_handle_create(file_priv, chan->notifier_bo->gem,
+				    &init->notifier_handle);
+	if (ret) {
+		nouveau_channel_free(chan);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int
+nouveau_ioctl_fifo_free(struct drm_device *dev, void *data,
+			struct drm_file *file_priv)
+{
+	struct drm_nouveau_channel_free *cfree = data;
+	struct nouveau_channel *chan;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+	NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(cfree->channel, file_priv, chan);
+
+	nouveau_channel_free(chan);
+	return 0;
+}
+
+/***********************************
+ * finally, the ioctl table
+ ***********************************/
+
+struct drm_ioctl_desc nouveau_ioctls[] = {
+	DRM_IOCTL_DEF(DRM_NOUVEAU_CARD_INIT, nouveau_ioctl_card_init, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF_CALL, nouveau_gem_ioctl_pushbuf_call, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PIN, nouveau_gem_ioctl_pin, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_UNPIN, nouveau_gem_ioctl_unpin, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF_CALL2, nouveau_gem_ioctl_pushbuf_call2, DRM_AUTH),
+};
+
+int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls);
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
new file mode 100644
index 0000000..032cf09
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -0,0 +1,824 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "drm_edid.h"
+#include "drm_crtc_helper.h"
+#include "nouveau_reg.h"
+#include "nouveau_drv.h"
+#include "nouveau_encoder.h"
+#include "nouveau_crtc.h"
+#include "nouveau_connector.h"
+#include "nouveau_hw.h"
+
+static inline struct drm_encoder_slave_funcs *
+get_slave_funcs(struct nouveau_encoder *enc)
+{
+	return to_encoder_slave(to_drm_encoder(enc))->slave_funcs;
+}
+
+static struct nouveau_encoder *
+find_encoder_by_type(struct drm_connector *connector, int type)
+{
+	struct drm_device *dev = connector->dev;
+	struct nouveau_encoder *nv_encoder;
+	struct drm_mode_object *obj;
+	int i, id;
+
+	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
+		id = connector->encoder_ids[i];
+		if (!id)
+			break;
+
+		obj = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER);
+		if (!obj)
+			continue;
+		nv_encoder = nouveau_encoder(obj_to_encoder(obj));
+
+		if (type == OUTPUT_ANY || nv_encoder->dcb->type == type)
+			return nv_encoder;
+	}
+
+	return NULL;
+}
+
+struct nouveau_connector *
+nouveau_encoder_connector_get(struct nouveau_encoder *encoder)
+{
+	struct drm_device *dev = to_drm_encoder(encoder)->dev;
+	struct drm_connector *drm_connector;
+
+	list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) {
+		if (drm_connector->encoder == to_drm_encoder(encoder))
+			return nouveau_connector(drm_connector);
+	}
+
+	return NULL;
+}
+
+
+static void
+nouveau_connector_destroy(struct drm_connector *drm_connector)
+{
+	struct nouveau_connector *connector = nouveau_connector(drm_connector);
+	struct drm_device *dev = connector->base.dev;
+
+	NV_DEBUG(dev, "\n");
+
+	if (!connector)
+		return;
+
+	drm_sysfs_connector_remove(drm_connector);
+	drm_connector_cleanup(drm_connector);
+	kfree(drm_connector);
+}
+
+static void
+nouveau_connector_ddc_prepare(struct drm_connector *connector, int *flags)
+{
+	struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
+
+	if (dev_priv->card_type >= NV_50)
+		return;
+
+	*flags = 0;
+	if (NVLockVgaCrtcs(dev_priv->dev, false))
+		*flags |= 1;
+	if (nv_heads_tied(dev_priv->dev))
+		*flags |= 2;
+
+	if (*flags & 2)
+		NVSetOwner(dev_priv->dev, 0); /* necessary? */
+}
+
+static void
+nouveau_connector_ddc_finish(struct drm_connector *connector, int flags)
+{
+	struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
+
+	if (dev_priv->card_type >= NV_50)
+		return;
+
+	if (flags & 2)
+		NVSetOwner(dev_priv->dev, 4);
+	if (flags & 1)
+		NVLockVgaCrtcs(dev_priv->dev, true);
+}
+
+static struct nouveau_i2c_chan *
+nouveau_connector_ddc_detect(struct drm_connector *connector,
+			     struct nouveau_encoder **pnv_encoder)
+{
+	struct drm_device *dev = connector->dev;
+	uint8_t out_buf[] = { 0x0, 0x0}, buf[2];
+	int ret, flags, i;
+
+	struct i2c_msg msgs[] = {
+		{
+			.addr = 0x50,
+			.flags = 0,
+			.len = 1,
+			.buf = out_buf,
+		},
+		{
+			.addr = 0x50,
+			.flags = I2C_M_RD,
+			.len = 1,
+			.buf = buf,
+		}
+	};
+
+	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
+		struct nouveau_i2c_chan *i2c = NULL;
+		struct nouveau_encoder *nv_encoder;
+		struct drm_mode_object *obj;
+		int id;
+
+		id = connector->encoder_ids[i];
+		if (!id)
+			break;
+
+		obj = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER);
+		if (!obj)
+			continue;
+		nv_encoder = nouveau_encoder(obj_to_encoder(obj));
+
+		if (nv_encoder->dcb->i2c_index < 0xf)
+			i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
+		if (!i2c)
+			continue;
+
+		nouveau_connector_ddc_prepare(connector, &flags);
+		ret = i2c_transfer(&i2c->adapter, msgs, 2);
+		nouveau_connector_ddc_finish(connector, flags);
+
+		if (ret == 2) {
+			*pnv_encoder = nv_encoder;
+			return i2c;
+		}
+	}
+
+	return NULL;
+}
+
+static void
+nouveau_connector_set_encoder(struct drm_connector *connector,
+			      struct nouveau_encoder *nv_encoder)
+{
+	struct nouveau_connector *nv_connector = nouveau_connector(connector);
+	struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
+	struct drm_device *dev = connector->dev;
+
+	if (nv_connector->detected_encoder == nv_encoder)
+		return;
+	nv_connector->detected_encoder = nv_encoder;
+
+	if (nv_encoder->dcb->type == OUTPUT_LVDS ||
+	    nv_encoder->dcb->type == OUTPUT_TMDS) {
+		connector->doublescan_allowed = false;
+		connector->interlace_allowed = false;
+	} else {
+		connector->doublescan_allowed = true;
+		if (dev_priv->card_type == NV_20 ||
+		   (dev_priv->card_type == NV_10 &&
+		    (dev->pci_device & 0x0ff0) != 0x0100 &&
+		    (dev->pci_device & 0x0ff0) != 0x0150))
+			/* HW is broken */
+			connector->interlace_allowed = false;
+		else
+			connector->interlace_allowed = true;
+	}
+
+	if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) {
+		drm_connector_property_set_value(connector,
+			dev->mode_config.dvi_i_subconnector_property,
+			nv_encoder->dcb->type == OUTPUT_TMDS ?
+			DRM_MODE_SUBCONNECTOR_DVID :
+			DRM_MODE_SUBCONNECTOR_DVIA);
+	}
+}
+
+static enum drm_connector_status
+nouveau_connector_detect(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct nouveau_connector *nv_connector = nouveau_connector(connector);
+	struct nouveau_encoder *nv_encoder = NULL;
+	struct nouveau_i2c_chan *i2c;
+	int type, flags;
+
+	if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
+		nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS);
+	if (nv_encoder && nv_connector->native_mode) {
+		nouveau_connector_set_encoder(connector, nv_encoder);
+		return connector_status_connected;
+	}
+
+	i2c = nouveau_connector_ddc_detect(connector, &nv_encoder);
+	if (i2c) {
+		nouveau_connector_ddc_prepare(connector, &flags);
+		nv_connector->edid = drm_get_edid(connector, &i2c->adapter);
+		nouveau_connector_ddc_finish(connector, flags);
+		drm_mode_connector_update_edid_property(connector,
+							nv_connector->edid);
+		if (!nv_connector->edid) {
+			NV_ERROR(dev, "DDC responded, but no EDID for %s\n",
+				 drm_get_connector_name(connector));
+			return connector_status_disconnected;
+		}
+
+		if (nv_encoder->dcb->type == OUTPUT_DP &&
+		    !nouveau_dp_detect(to_drm_encoder(nv_encoder))) {
+			NV_ERROR(dev, "Detected %s, but failed init\n",
+				 drm_get_connector_name(connector));
+			return connector_status_disconnected;
+		}
+
+		/* Override encoder type for DVI-I based on whether EDID
+		 * says the display is digital or analog, both use the
+		 * same i2c channel so the value returned from ddc_detect
+		 * isn't necessarily correct.
+		 */
+		if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) {
+			if (nv_connector->edid->input & DRM_EDID_INPUT_DIGITAL)
+				type = OUTPUT_TMDS;
+			else
+				type = OUTPUT_ANALOG;
+
+			nv_encoder = find_encoder_by_type(connector, type);
+			if (!nv_encoder) {
+				NV_ERROR(dev, "Detected %d encoder on %s, "
+					      "but no object!\n", type,
+					 drm_get_connector_name(connector));
+				return connector_status_disconnected;
+			}
+		}
+
+		nouveau_connector_set_encoder(connector, nv_encoder);
+		return connector_status_connected;
+	}
+
+	nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG);
+	if (!nv_encoder)
+		nv_encoder = find_encoder_by_type(connector, OUTPUT_TV);
+	if (nv_encoder) {
+		struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
+		struct drm_encoder_helper_funcs *helper =
+						encoder->helper_private;
+
+		if (helper->detect(encoder, connector) ==
+						connector_status_connected) {
+			nouveau_connector_set_encoder(connector, nv_encoder);
+			return connector_status_connected;
+		}
+
+	}
+
+	return connector_status_disconnected;
+}
+
+static void
+nouveau_connector_force(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct nouveau_encoder *nv_encoder;
+	int type;
+
+	if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) {
+		if (connector->force == DRM_FORCE_ON_DIGITAL)
+			type = OUTPUT_TMDS;
+		else
+			type = OUTPUT_ANALOG;
+	} else
+		type = OUTPUT_ANY;
+
+	nv_encoder = find_encoder_by_type(connector, type);
+	if (!nv_encoder) {
+		NV_ERROR(dev, "can't find encoder to force %s on!\n",
+			 drm_get_connector_name(connector));
+		connector->status = connector_status_disconnected;
+		return;
+	}
+
+	nouveau_connector_set_encoder(connector, nv_encoder);
+}
+
+static int
+nouveau_connector_set_property(struct drm_connector *connector,
+			       struct drm_property *property, uint64_t value)
+{
+	struct nouveau_connector *nv_connector = nouveau_connector(connector);
+	struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
+	struct drm_device *dev = connector->dev;
+	int ret;
+
+	/* Scaling mode */
+	if (property == dev->mode_config.scaling_mode_property) {
+		struct nouveau_crtc *nv_crtc = NULL;
+		bool modeset = false;
+
+		switch (value) {
+		case DRM_MODE_SCALE_NONE:
+		case DRM_MODE_SCALE_FULLSCREEN:
+		case DRM_MODE_SCALE_CENTER:
+		case DRM_MODE_SCALE_ASPECT:
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		/* LVDS always needs gpu scaling */
+		if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS &&
+		    value == DRM_MODE_SCALE_NONE)
+			return -EINVAL;
+
+		/* Changing between GPU and panel scaling requires a full
+		 * modeset
+		 */
+		if ((nv_connector->scaling_mode == DRM_MODE_SCALE_NONE) ||
+		    (value == DRM_MODE_SCALE_NONE))
+			modeset = true;
+		nv_connector->scaling_mode = value;
+
+		if (connector->encoder && connector->encoder->crtc)
+			nv_crtc = nouveau_crtc(connector->encoder->crtc);
+		if (!nv_crtc)
+			return 0;
+
+		if (modeset || !nv_crtc->set_scale) {
+			ret = drm_crtc_helper_set_mode(&nv_crtc->base,
+							&nv_crtc->base.mode,
+							nv_crtc->base.x,
+							nv_crtc->base.y, NULL);
+			if (!ret)
+				return -EINVAL;
+		} else {
+			ret = nv_crtc->set_scale(nv_crtc, value, true);
+			if (ret)
+				return ret;
+		}
+
+		return 0;
+	}
+
+	/* Dithering */
+	if (property == dev->mode_config.dithering_mode_property) {
+		struct nouveau_crtc *nv_crtc = NULL;
+
+		if (value == DRM_MODE_DITHERING_ON)
+			nv_connector->use_dithering = true;
+		else
+			nv_connector->use_dithering = false;
+
+		if (connector->encoder && connector->encoder->crtc)
+			nv_crtc = nouveau_crtc(connector->encoder->crtc);
+
+		if (!nv_crtc || !nv_crtc->set_dither)
+			return 0;
+
+		return nv_crtc->set_dither(nv_crtc, nv_connector->use_dithering,
+					   true);
+	}
+
+	if (nv_encoder && nv_encoder->dcb->type == OUTPUT_TV)
+		return get_slave_funcs(nv_encoder)->
+			set_property(to_drm_encoder(nv_encoder), connector, property, value);
+
+	return -EINVAL;
+}
+
+static struct drm_display_mode *
+nouveau_connector_native_mode(struct nouveau_connector *connector)
+{
+	struct drm_device *dev = connector->base.dev;
+	struct drm_display_mode *mode, *largest = NULL;
+	int high_w = 0, high_h = 0, high_v = 0;
+
+	/* Use preferred mode if there is one.. */
+	list_for_each_entry(mode, &connector->base.probed_modes, head) {
+		if (mode->type & DRM_MODE_TYPE_PREFERRED) {
+			NV_DEBUG(dev, "native mode from preferred\n");
+			return drm_mode_duplicate(dev, mode);
+		}
+	}
+
+	/* Otherwise, take the resolution with the largest width, then height,
+	 * then vertical refresh
+	 */
+	list_for_each_entry(mode, &connector->base.probed_modes, head) {
+		if (mode->hdisplay < high_w)
+			continue;
+
+		if (mode->hdisplay == high_w && mode->vdisplay < high_h)
+			continue;
+
+		if (mode->hdisplay == high_w && mode->vdisplay == high_h &&
+		    mode->vrefresh < high_v)
+			continue;
+
+		high_w = mode->hdisplay;
+		high_h = mode->vdisplay;
+		high_v = mode->vrefresh;
+		largest = mode;
+	}
+
+	NV_DEBUG(dev, "native mode from largest: %dx%d@%d\n",
+		      high_w, high_h, high_v);
+	return largest ? drm_mode_duplicate(dev, largest) : NULL;
+}
+
+struct moderec {
+	int hdisplay;
+	int vdisplay;
+};
+
+static struct moderec scaler_modes[] = {
+	{ 1920, 1200 },
+	{ 1920, 1080 },
+	{ 1680, 1050 },
+	{ 1600, 1200 },
+	{ 1400, 1050 },
+	{ 1280, 1024 },
+	{ 1280, 960 },
+	{ 1152, 864 },
+	{ 1024, 768 },
+	{ 800, 600 },
+	{ 720, 400 },
+	{ 640, 480 },
+	{ 640, 400 },
+	{ 640, 350 },
+	{}
+};
+
+static int
+nouveau_connector_scaler_modes_add(struct drm_connector *connector)
+{
+	struct nouveau_connector *nv_connector = nouveau_connector(connector);
+	struct drm_display_mode *native = nv_connector->native_mode, *m;
+	struct drm_device *dev = connector->dev;
+	struct moderec *mode = &scaler_modes[0];
+	int modes = 0;
+
+	if (!native)
+		return 0;
+
+	while (mode->hdisplay) {
+		if (mode->hdisplay <= native->hdisplay &&
+		    mode->vdisplay <= native->vdisplay) {
+			m = drm_cvt_mode(dev, mode->hdisplay, mode->vdisplay,
+					 drm_mode_vrefresh(native), false,
+					 false, false);
+			if (!m)
+				continue;
+
+			m->type |= DRM_MODE_TYPE_DRIVER;
+
+			drm_mode_probed_add(connector, m);
+			modes++;
+		}
+
+		mode++;
+	}
+
+	return modes;
+}
+
+static int
+nouveau_connector_get_modes(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct nouveau_connector *nv_connector = nouveau_connector(connector);
+	struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
+	int ret = 0;
+
+	/* If we're not LVDS, destroy the previous native mode, the attached
+	 * monitor could have changed.
+	 */
+	if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS &&
+	    nv_connector->native_mode) {
+		drm_mode_destroy(dev, nv_connector->native_mode);
+		nv_connector->native_mode = NULL;
+	}
+
+	if (nv_connector->edid)
+		ret = drm_add_edid_modes(connector, nv_connector->edid);
+
+	/* Find the native mode if this is a digital panel, if we didn't
+	 * find any modes through DDC previously add the native mode to
+	 * the list of modes.
+	 */
+	if (!nv_connector->native_mode)
+		nv_connector->native_mode =
+			nouveau_connector_native_mode(nv_connector);
+	if (ret == 0 && nv_connector->native_mode) {
+		struct drm_display_mode *mode;
+
+		mode = drm_mode_duplicate(dev, nv_connector->native_mode);
+		drm_mode_probed_add(connector, mode);
+		ret = 1;
+	}
+
+	if (nv_encoder->dcb->type == OUTPUT_TV)
+		ret = get_slave_funcs(nv_encoder)->
+			get_modes(to_drm_encoder(nv_encoder), connector);
+
+	if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
+		ret += nouveau_connector_scaler_modes_add(connector);
+
+	return ret;
+}
+
+static int
+nouveau_connector_mode_valid(struct drm_connector *connector,
+			     struct drm_display_mode *mode)
+{
+	struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
+	struct nouveau_connector *nv_connector = nouveau_connector(connector);
+	struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
+	unsigned min_clock = 25000, max_clock = min_clock;
+	unsigned clock = mode->clock;
+
+	switch (nv_encoder->dcb->type) {
+	case OUTPUT_LVDS:
+		BUG_ON(!nv_connector->native_mode);
+		if (mode->hdisplay > nv_connector->native_mode->hdisplay ||
+		    mode->vdisplay > nv_connector->native_mode->vdisplay)
+			return MODE_PANEL;
+
+		min_clock = 0;
+		max_clock = 400000;
+		break;
+	case OUTPUT_TMDS:
+		if ((dev_priv->card_type >= NV_50 && !nouveau_duallink) ||
+		    (dev_priv->card_type < NV_50 &&
+		     !nv_encoder->dcb->duallink_possible))
+			max_clock = 165000;
+		else
+			max_clock = 330000;
+		break;
+	case OUTPUT_ANALOG:
+		max_clock = nv_encoder->dcb->crtconf.maxfreq;
+		if (!max_clock)
+			max_clock = 350000;
+		break;
+	case OUTPUT_TV:
+		return get_slave_funcs(nv_encoder)->
+			mode_valid(to_drm_encoder(nv_encoder), mode);
+	case OUTPUT_DP:
+		if (nv_encoder->dp.link_bw == DP_LINK_BW_2_7)
+			max_clock = nv_encoder->dp.link_nr * 270000;
+		else
+			max_clock = nv_encoder->dp.link_nr * 162000;
+
+		clock *= 3;
+		break;
+	}
+
+	if (clock < min_clock)
+		return MODE_CLOCK_LOW;
+
+	if (clock > max_clock)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
+static struct drm_encoder *
+nouveau_connector_best_encoder(struct drm_connector *connector)
+{
+	struct nouveau_connector *nv_connector = nouveau_connector(connector);
+
+	if (nv_connector->detected_encoder)
+		return to_drm_encoder(nv_connector->detected_encoder);
+
+	return NULL;
+}
+
+static const struct drm_connector_helper_funcs
+nouveau_connector_helper_funcs = {
+	.get_modes = nouveau_connector_get_modes,
+	.mode_valid = nouveau_connector_mode_valid,
+	.best_encoder = nouveau_connector_best_encoder,
+};
+
+static const struct drm_connector_funcs
+nouveau_connector_funcs = {
+	.dpms = drm_helper_connector_dpms,
+	.save = NULL,
+	.restore = NULL,
+	.detect = nouveau_connector_detect,
+	.destroy = nouveau_connector_destroy,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.set_property = nouveau_connector_set_property,
+	.force = nouveau_connector_force
+};
+
+static int
+nouveau_connector_create_lvds(struct drm_device *dev,
+			      struct drm_connector *connector)
+{
+	struct nouveau_connector *nv_connector = nouveau_connector(connector);
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_i2c_chan *i2c = NULL;
+	struct nouveau_encoder *nv_encoder;
+	struct drm_display_mode native, *mode, *temp;
+	bool dummy, if_is_24bit = false;
+	int ret, flags;
+
+	nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS);
+	if (!nv_encoder)
+		return -ENODEV;
+
+	ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &if_is_24bit);
+	if (ret) {
+		NV_ERROR(dev, "Error parsing LVDS table, disabling LVDS\n");
+		return ret;
+	}
+	nv_connector->use_dithering = !if_is_24bit;
+
+	/* Firstly try getting EDID over DDC, if allowed and I2C channel
+	 * is available.
+	 */
+	if (!dev_priv->VBIOS.pub.fp_no_ddc && nv_encoder->dcb->i2c_index < 0xf)
+		i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
+
+	if (i2c) {
+		nouveau_connector_ddc_prepare(connector, &flags);
+		nv_connector->edid = drm_get_edid(connector, &i2c->adapter);
+		nouveau_connector_ddc_finish(connector, flags);
+	}
+
+	/* If no EDID found above, and the VBIOS indicates a hardcoded
+	 * modeline is avalilable for the panel, set it as the panel's
+	 * native mode and exit.
+	 */
+	if (!nv_connector->edid && nouveau_bios_fp_mode(dev, &native) &&
+	     (nv_encoder->dcb->lvdsconf.use_straps_for_mode ||
+	      dev_priv->VBIOS.pub.fp_no_ddc)) {
+		nv_connector->native_mode = drm_mode_duplicate(dev, &native);
+		goto out;
+	}
+
+	/* Still nothing, some VBIOS images have a hardcoded EDID block
+	 * stored for the panel stored in them.
+	 */
+	if (!nv_connector->edid && !nv_connector->native_mode &&
+	    !dev_priv->VBIOS.pub.fp_no_ddc) {
+		nv_connector->edid =
+			(struct edid *)nouveau_bios_embedded_edid(dev);
+	}
+
+	if (!nv_connector->edid)
+		goto out;
+
+	/* We didn't find/use a panel mode from the VBIOS, so parse the EDID
+	 * block and look for the preferred mode there.
+	 */
+	ret = drm_add_edid_modes(connector, nv_connector->edid);
+	if (ret == 0)
+		goto out;
+	nv_connector->detected_encoder = nv_encoder;
+	nv_connector->native_mode = nouveau_connector_native_mode(nv_connector);
+	list_for_each_entry_safe(mode, temp, &connector->probed_modes, head)
+		drm_mode_remove(connector, mode);
+
+out:
+	if (!nv_connector->native_mode) {
+		NV_ERROR(dev, "LVDS present in DCB table, but couldn't "
+			      "determine its native mode.  Disabling.\n");
+		return -ENODEV;
+	}
+
+	drm_mode_connector_update_edid_property(connector, nv_connector->edid);
+	return 0;
+}
+
+int
+nouveau_connector_create(struct drm_device *dev, int index, int type)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_connector *nv_connector = NULL;
+	struct drm_connector *connector;
+	struct drm_encoder *encoder;
+	int ret;
+
+	NV_DEBUG(dev, "\n");
+
+	nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL);
+	if (!nv_connector)
+		return -ENOMEM;
+	nv_connector->dcb = nouveau_bios_connector_entry(dev, index);
+	connector = &nv_connector->base;
+
+	switch (type) {
+	case DRM_MODE_CONNECTOR_VGA:
+		NV_INFO(dev, "Detected a VGA connector\n");
+		break;
+	case DRM_MODE_CONNECTOR_DVID:
+		NV_INFO(dev, "Detected a DVI-D connector\n");
+		break;
+	case DRM_MODE_CONNECTOR_DVII:
+		NV_INFO(dev, "Detected a DVI-I connector\n");
+		break;
+	case DRM_MODE_CONNECTOR_LVDS:
+		NV_INFO(dev, "Detected a LVDS connector\n");
+		break;
+	case DRM_MODE_CONNECTOR_TV:
+		NV_INFO(dev, "Detected a TV connector\n");
+		break;
+	case DRM_MODE_CONNECTOR_DisplayPort:
+		NV_INFO(dev, "Detected a DisplayPort connector\n");
+		break;
+	default:
+		NV_ERROR(dev, "Unknown connector, this is not good.\n");
+		break;
+	}
+
+	/* defaults, will get overridden in detect() */
+	connector->interlace_allowed = false;
+	connector->doublescan_allowed = false;
+
+	drm_connector_init(dev, connector, &nouveau_connector_funcs, type);
+	drm_connector_helper_add(connector, &nouveau_connector_helper_funcs);
+
+	/* Init DVI-I specific properties */
+	if (type == DRM_MODE_CONNECTOR_DVII) {
+		drm_mode_create_dvi_i_properties(dev);
+		drm_connector_attach_property(connector, dev->mode_config.dvi_i_subconnector_property, 0);
+		drm_connector_attach_property(connector, dev->mode_config.dvi_i_select_subconnector_property, 0);
+	}
+
+	if (type != DRM_MODE_CONNECTOR_LVDS)
+		nv_connector->use_dithering = false;
+
+	if (type == DRM_MODE_CONNECTOR_DVID ||
+	    type == DRM_MODE_CONNECTOR_DVII ||
+	    type == DRM_MODE_CONNECTOR_LVDS ||
+	    type == DRM_MODE_CONNECTOR_DisplayPort) {
+		nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN;
+
+		drm_connector_attach_property(connector, dev->mode_config.scaling_mode_property,
+					      nv_connector->scaling_mode);
+		drm_connector_attach_property(connector, dev->mode_config.dithering_mode_property,
+					      nv_connector->use_dithering ? DRM_MODE_DITHERING_ON
+					      : DRM_MODE_DITHERING_OFF);
+
+	} else {
+		nv_connector->scaling_mode = DRM_MODE_SCALE_NONE;
+
+		if (type == DRM_MODE_CONNECTOR_VGA  &&
+				dev_priv->card_type >= NV_50) {
+			drm_connector_attach_property(connector,
+					dev->mode_config.scaling_mode_property,
+					nv_connector->scaling_mode);
+		}
+	}
+
+	/* attach encoders */
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+		if (nv_encoder->dcb->connector != index)
+			continue;
+
+		if (get_slave_funcs(nv_encoder))
+			get_slave_funcs(nv_encoder)->create_resources(encoder, connector);
+
+		drm_mode_connector_attach_encoder(connector, encoder);
+	}
+
+	drm_sysfs_connector_add(connector);
+
+	if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
+		ret = nouveau_connector_create_lvds(dev, connector);
+		if (ret) {
+			connector->funcs->destroy(connector);
+			return ret;
+		}
+	}
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h
new file mode 100644
index 0000000..728b809
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __NOUVEAU_CONNECTOR_H__
+#define __NOUVEAU_CONNECTOR_H__
+
+#include "drm_edid.h"
+#include "nouveau_i2c.h"
+
+struct nouveau_connector {
+	struct drm_connector base;
+
+	struct dcb_connector_table_entry *dcb;
+
+	int scaling_mode;
+	bool use_dithering;
+
+	struct nouveau_encoder *detected_encoder;
+	struct edid *edid;
+	struct drm_display_mode *native_mode;
+};
+
+static inline struct nouveau_connector *nouveau_connector(
+						struct drm_connector *con)
+{
+	return container_of(con, struct nouveau_connector, base);
+}
+
+int nouveau_connector_create(struct drm_device *dev, int i2c_index, int type);
+
+#endif /* __NOUVEAU_CONNECTOR_H__ */
diff --git a/drivers/gpu/drm/nouveau/nouveau_crtc.h b/drivers/gpu/drm/nouveau/nouveau_crtc.h
new file mode 100644
index 0000000..49fa7b2
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_crtc.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __NOUVEAU_CRTC_H__
+#define __NOUVEAU_CRTC_H__
+
+struct nouveau_crtc {
+	struct drm_crtc base;
+
+	int index;
+
+	struct drm_display_mode *mode;
+
+	uint32_t dpms_saved_fp_control;
+	uint32_t fp_users;
+	int saturation;
+	int sharpness;
+	int last_dpms;
+
+	struct {
+		int cpp;
+		bool blanked;
+		uint32_t offset;
+		uint32_t tile_flags;
+	} fb;
+
+	struct {
+		struct nouveau_bo *nvbo;
+		bool visible;
+		uint32_t offset;
+		void (*set_offset)(struct nouveau_crtc *, uint32_t offset);
+		void (*set_pos)(struct nouveau_crtc *, int x, int y);
+		void (*hide)(struct nouveau_crtc *, bool update);
+		void (*show)(struct nouveau_crtc *, bool update);
+	} cursor;
+
+	struct {
+		struct nouveau_bo *nvbo;
+		uint16_t r[256];
+		uint16_t g[256];
+		uint16_t b[256];
+		int depth;
+	} lut;
+
+	int (*set_dither)(struct nouveau_crtc *crtc, bool on, bool update);
+	int (*set_scale)(struct nouveau_crtc *crtc, int mode, bool update);
+};
+
+static inline struct nouveau_crtc *nouveau_crtc(struct drm_crtc *crtc)
+{
+	return container_of(crtc, struct nouveau_crtc, base);
+}
+
+static inline struct drm_crtc *to_drm_crtc(struct nouveau_crtc *crtc)
+{
+	return &crtc->base;
+}
+
+int nv50_crtc_create(struct drm_device *dev, int index);
+int nv50_cursor_init(struct nouveau_crtc *);
+void nv50_cursor_fini(struct nouveau_crtc *);
+int nv50_crtc_cursor_set(struct drm_crtc *drm_crtc, struct drm_file *file_priv,
+			 uint32_t buffer_handle, uint32_t width,
+			 uint32_t height);
+int nv50_crtc_cursor_move(struct drm_crtc *drm_crtc, int x, int y);
+
+int nv04_cursor_init(struct nouveau_crtc *);
+
+struct nouveau_connector *
+nouveau_crtc_connector_get(struct nouveau_crtc *crtc);
+
+#endif /* __NOUVEAU_CRTC_H__ */
diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c
new file mode 100644
index 0000000..d79db36
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2009 Red Hat <bskeggs@redhat.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/*
+ * Authors:
+ *  Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#include <linux/debugfs.h>
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+
+static int
+nouveau_debugfs_channel_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct nouveau_channel *chan = node->info_ent->data;
+
+	seq_printf(m, "channel id    : %d\n", chan->id);
+
+	seq_printf(m, "cpu fifo state:\n");
+	seq_printf(m, "          base: 0x%08x\n", chan->pushbuf_base);
+	seq_printf(m, "           max: 0x%08x\n", chan->dma.max << 2);
+	seq_printf(m, "           cur: 0x%08x\n", chan->dma.cur << 2);
+	seq_printf(m, "           put: 0x%08x\n", chan->dma.put << 2);
+	seq_printf(m, "          free: 0x%08x\n", chan->dma.free << 2);
+
+	seq_printf(m, "gpu fifo state:\n");
+	seq_printf(m, "           get: 0x%08x\n",
+					nvchan_rd32(chan, chan->user_get));
+	seq_printf(m, "           put: 0x%08x\n",
+					nvchan_rd32(chan, chan->user_put));
+
+	seq_printf(m, "last fence    : %d\n", chan->fence.sequence);
+	seq_printf(m, "last signalled: %d\n", chan->fence.sequence_ack);
+	return 0;
+}
+
+int
+nouveau_debugfs_channel_init(struct nouveau_channel *chan)
+{
+	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
+	struct drm_minor *minor = chan->dev->primary;
+	int ret;
+
+	if (!dev_priv->debugfs.channel_root) {
+		dev_priv->debugfs.channel_root =
+			debugfs_create_dir("channel", minor->debugfs_root);
+		if (!dev_priv->debugfs.channel_root)
+			return -ENOENT;
+	}
+
+	snprintf(chan->debugfs.name, 32, "%d", chan->id);
+	chan->debugfs.info.name = chan->debugfs.name;
+	chan->debugfs.info.show = nouveau_debugfs_channel_info;
+	chan->debugfs.info.driver_features = 0;
+	chan->debugfs.info.data = chan;
+
+	ret = drm_debugfs_create_files(&chan->debugfs.info, 1,
+				       dev_priv->debugfs.channel_root,
+				       chan->dev->primary);
+	if (ret == 0)
+		chan->debugfs.active = true;
+	return ret;
+}
+
+void
+nouveau_debugfs_channel_fini(struct nouveau_channel *chan)
+{
+	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
+
+	if (!chan->debugfs.active)
+		return;
+
+	drm_debugfs_remove_files(&chan->debugfs.info, 1, chan->dev->primary);
+	chan->debugfs.active = false;
+
+	if (chan == dev_priv->channel) {
+		debugfs_remove(dev_priv->debugfs.channel_root);
+		dev_priv->debugfs.channel_root = NULL;
+	}
+}
+
+static int
+nouveau_debugfs_chipset_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_minor *minor = node->minor;
+	struct drm_device *dev = minor->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t ppci_0;
+
+	ppci_0 = nv_rd32(dev, dev_priv->chipset >= 0x40 ? 0x88000 : 0x1800);
+
+	seq_printf(m, "PMC_BOOT_0: 0x%08x\n", nv_rd32(dev, NV03_PMC_BOOT_0));
+	seq_printf(m, "PCI ID    : 0x%04x:0x%04x\n",
+		   ppci_0 & 0xffff, ppci_0 >> 16);
+	return 0;
+}
+
+static int
+nouveau_debugfs_memory_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_minor *minor = node->minor;
+	struct drm_device *dev = minor->dev;
+
+	seq_printf(m, "VRAM total: %dKiB\n",
+		   (int)(nouveau_mem_fb_amount(dev) >> 10));
+	return 0;
+}
+
+static struct drm_info_list nouveau_debugfs_list[] = {
+	{ "chipset", nouveau_debugfs_chipset_info, 0, NULL },
+	{ "memory", nouveau_debugfs_memory_info, 0, NULL },
+};
+#define NOUVEAU_DEBUGFS_ENTRIES ARRAY_SIZE(nouveau_debugfs_list)
+
+int
+nouveau_debugfs_init(struct drm_minor *minor)
+{
+	drm_debugfs_create_files(nouveau_debugfs_list, NOUVEAU_DEBUGFS_ENTRIES,
+				 minor->debugfs_root, minor);
+	return 0;
+}
+
+void
+nouveau_debugfs_takedown(struct drm_minor *minor)
+{
+	drm_debugfs_remove_files(nouveau_debugfs_list, NOUVEAU_DEBUGFS_ENTRIES,
+				 minor);
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
new file mode 100644
index 0000000..dfc9439
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "drm_crtc_helper.h"
+#include "nouveau_drv.h"
+#include "nouveau_fb.h"
+#include "nouveau_fbcon.h"
+
+static void
+nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb)
+{
+	struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
+	struct drm_device *dev = drm_fb->dev;
+
+	if (drm_fb->fbdev)
+		nouveau_fbcon_remove(dev, drm_fb);
+
+	if (fb->nvbo) {
+		mutex_lock(&dev->struct_mutex);
+		drm_gem_object_unreference(fb->nvbo->gem);
+		mutex_unlock(&dev->struct_mutex);
+	}
+
+	drm_framebuffer_cleanup(drm_fb);
+	kfree(fb);
+}
+
+static int
+nouveau_user_framebuffer_create_handle(struct drm_framebuffer *drm_fb,
+				       struct drm_file *file_priv,
+				       unsigned int *handle)
+{
+	struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
+
+	return drm_gem_handle_create(file_priv, fb->nvbo->gem, handle);
+}
+
+static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = {
+	.destroy = nouveau_user_framebuffer_destroy,
+	.create_handle = nouveau_user_framebuffer_create_handle,
+};
+
+struct drm_framebuffer *
+nouveau_framebuffer_create(struct drm_device *dev, struct nouveau_bo *nvbo,
+			   struct drm_mode_fb_cmd *mode_cmd)
+{
+	struct nouveau_framebuffer *fb;
+	int ret;
+
+	fb = kzalloc(sizeof(struct nouveau_framebuffer), GFP_KERNEL);
+	if (!fb)
+		return NULL;
+
+	ret = drm_framebuffer_init(dev, &fb->base, &nouveau_framebuffer_funcs);
+	if (ret) {
+		kfree(fb);
+		return NULL;
+	}
+
+	drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd);
+
+	fb->nvbo = nvbo;
+	return &fb->base;
+}
+
+static struct drm_framebuffer *
+nouveau_user_framebuffer_create(struct drm_device *dev,
+				struct drm_file *file_priv,
+				struct drm_mode_fb_cmd *mode_cmd)
+{
+	struct drm_framebuffer *fb;
+	struct drm_gem_object *gem;
+
+	gem = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle);
+	if (!gem)
+		return NULL;
+
+	fb = nouveau_framebuffer_create(dev, nouveau_gem_object(gem), mode_cmd);
+	if (!fb) {
+		drm_gem_object_unreference(gem);
+		return NULL;
+	}
+
+	return fb;
+}
+
+const struct drm_mode_config_funcs nouveau_mode_config_funcs = {
+	.fb_create = nouveau_user_framebuffer_create,
+	.fb_changed = nouveau_fbcon_probe,
+};
+
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c
new file mode 100644
index 0000000..7035536
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_dma.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_dma.h"
+
+int
+nouveau_dma_init(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *m2mf = NULL;
+	int ret, i;
+
+	/* Create NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */
+	ret = nouveau_gpuobj_gr_new(chan, dev_priv->card_type < NV_50 ?
+				    0x0039 : 0x5039, &m2mf);
+	if (ret)
+		return ret;
+
+	ret = nouveau_gpuobj_ref_add(dev, chan, NvM2MF, m2mf, NULL);
+	if (ret)
+		return ret;
+
+	/* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */
+	ret = nouveau_notifier_alloc(chan, NvNotify0, 32, &chan->m2mf_ntfy);
+	if (ret)
+		return ret;
+
+	/* Map push buffer */
+	ret = nouveau_bo_map(chan->pushbuf_bo);
+	if (ret)
+		return ret;
+
+	/* Map M2MF notifier object - fbcon. */
+	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+		ret = nouveau_bo_map(chan->notifier_bo);
+		if (ret)
+			return ret;
+	}
+
+	/* Initialise DMA vars */
+	chan->dma.max  = (chan->pushbuf_bo->bo.mem.size >> 2) - 2;
+	chan->dma.put  = 0;
+	chan->dma.cur  = chan->dma.put;
+	chan->dma.free = chan->dma.max - chan->dma.cur;
+
+	/* Insert NOPS for NOUVEAU_DMA_SKIPS */
+	ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < NOUVEAU_DMA_SKIPS; i++)
+		OUT_RING(chan, 0);
+
+	/* Initialise NV_MEMORY_TO_MEMORY_FORMAT */
+	ret = RING_SPACE(chan, 4);
+	if (ret)
+		return ret;
+	BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NAME, 1);
+	OUT_RING(chan, NvM2MF);
+	BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
+	OUT_RING(chan, NvNotify0);
+
+	/* Sit back and pray the channel works.. */
+	FIRE_RING(chan);
+
+	return 0;
+}
+
+void
+OUT_RINGp(struct nouveau_channel *chan, const void *data, unsigned nr_dwords)
+{
+	bool is_iomem;
+	u32 *mem = ttm_kmap_obj_virtual(&chan->pushbuf_bo->kmap, &is_iomem);
+	mem = &mem[chan->dma.cur];
+	if (is_iomem)
+		memcpy_toio((void __force __iomem *)mem, data, nr_dwords * 4);
+	else
+		memcpy(mem, data, nr_dwords * 4);
+	chan->dma.cur += nr_dwords;
+}
+
+static inline bool
+READ_GET(struct nouveau_channel *chan, uint32_t *get)
+{
+	uint32_t val;
+
+	val = nvchan_rd32(chan, chan->user_get);
+	if (val < chan->pushbuf_base ||
+	    val >= chan->pushbuf_base + chan->pushbuf_bo->bo.mem.size) {
+		/* meaningless to dma_wait() except to know whether the
+		 * GPU has stalled or not
+		 */
+		*get = val;
+		return false;
+	}
+
+	*get = (val - chan->pushbuf_base) >> 2;
+	return true;
+}
+
+int
+nouveau_dma_wait(struct nouveau_channel *chan, int size)
+{
+	uint32_t get, prev_get = 0, cnt = 0;
+	bool get_valid;
+
+	while (chan->dma.free < size) {
+		/* reset counter as long as GET is still advancing, this is
+		 * to avoid misdetecting a GPU lockup if the GPU happens to
+		 * just be processing an operation that takes a long time
+		 */
+		get_valid = READ_GET(chan, &get);
+		if (get != prev_get) {
+			prev_get = get;
+			cnt = 0;
+		}
+
+		if ((++cnt & 0xff) == 0) {
+			DRM_UDELAY(1);
+			if (cnt > 100000)
+				return -EBUSY;
+		}
+
+		/* loop until we have a usable GET pointer.  the value
+		 * we read from the GPU may be outside the main ring if
+		 * PFIFO is processing a buffer called from the main ring,
+		 * discard these values until something sensible is seen.
+		 *
+		 * the other case we discard GET is while the GPU is fetching
+		 * from the SKIPS area, so the code below doesn't have to deal
+		 * with some fun corner cases.
+		 */
+		if (!get_valid || get < NOUVEAU_DMA_SKIPS)
+			continue;
+
+		if (get <= chan->dma.cur) {
+			/* engine is fetching behind us, or is completely
+			 * idle (GET == PUT) so we have free space up until
+			 * the end of the push buffer
+			 *
+			 * we can only hit that path once per call due to
+			 * looping back to the beginning of the push buffer,
+			 * we'll hit the fetching-ahead-of-us path from that
+			 * point on.
+			 *
+			 * the *one* exception to that rule is if we read
+			 * GET==PUT, in which case the below conditional will
+			 * always succeed and break us out of the wait loop.
+			 */
+			chan->dma.free = chan->dma.max - chan->dma.cur;
+			if (chan->dma.free >= size)
+				break;
+
+			/* not enough space left at the end of the push buffer,
+			 * instruct the GPU to jump back to the start right
+			 * after processing the currently pending commands.
+			 */
+			OUT_RING(chan, chan->pushbuf_base | 0x20000000);
+			WRITE_PUT(NOUVEAU_DMA_SKIPS);
+
+			/* we're now submitting commands at the start of
+			 * the push buffer.
+			 */
+			chan->dma.cur  =
+			chan->dma.put  = NOUVEAU_DMA_SKIPS;
+		}
+
+		/* engine fetching ahead of us, we have space up until the
+		 * current GET pointer.  the "- 1" is to ensure there's
+		 * space left to emit a jump back to the beginning of the
+		 * push buffer if we require it.  we can never get GET == PUT
+		 * here, so this is safe.
+		 */
+		chan->dma.free = get - chan->dma.cur - 1;
+	}
+
+	return 0;
+}
+
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h
new file mode 100644
index 0000000..04e85d8
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_dma.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __NOUVEAU_DMA_H__
+#define __NOUVEAU_DMA_H__
+
+#ifndef NOUVEAU_DMA_DEBUG
+#define NOUVEAU_DMA_DEBUG 0
+#endif
+
+/*
+ * There's a hw race condition where you can't jump to your PUT offset,
+ * to avoid this we jump to offset + SKIPS and fill the difference with
+ * NOPs.
+ *
+ * xf86-video-nv configures the DMA fetch size to 32 bytes, and uses
+ * a SKIPS value of 8.  Lets assume that the race condition is to do
+ * with writing into the fetch area, we configure a fetch size of 128
+ * bytes so we need a larger SKIPS value.
+ */
+#define NOUVEAU_DMA_SKIPS (128 / 4)
+
+/* Hardcoded object assignments to subchannels (subchannel id). */
+enum {
+	NvSubM2MF	= 0,
+	NvSub2D		= 1,
+	NvSubCtxSurf2D  = 1,
+	NvSubGdiRect    = 2,
+	NvSubImageBlit  = 3
+};
+
+/* Object handles. */
+enum {
+	NvM2MF		= 0x80000001,
+	NvDmaFB		= 0x80000002,
+	NvDmaTT		= 0x80000003,
+	NvDmaVRAM	= 0x80000004,
+	NvDmaGART	= 0x80000005,
+	NvNotify0       = 0x80000006,
+	Nv2D		= 0x80000007,
+	NvCtxSurf2D	= 0x80000008,
+	NvRop		= 0x80000009,
+	NvImagePatt	= 0x8000000a,
+	NvClipRect	= 0x8000000b,
+	NvGdiRect	= 0x8000000c,
+	NvImageBlit	= 0x8000000d,
+
+	/* G80+ display objects */
+	NvEvoVRAM	= 0x01000000,
+	NvEvoFB16	= 0x01000001,
+	NvEvoFB32	= 0x01000002
+};
+
+#define NV_MEMORY_TO_MEMORY_FORMAT                                    0x00000039
+#define NV_MEMORY_TO_MEMORY_FORMAT_NAME                               0x00000000
+#define NV_MEMORY_TO_MEMORY_FORMAT_SET_REF                            0x00000050
+#define NV_MEMORY_TO_MEMORY_FORMAT_NOP                                0x00000100
+#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY                             0x00000104
+#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY_STYLE_WRITE                 0x00000000
+#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY_STYLE_WRITE_LE_AWAKEN       0x00000001
+#define NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY                         0x00000180
+#define NV_MEMORY_TO_MEMORY_FORMAT_DMA_SOURCE                         0x00000184
+#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN                          0x0000030c
+
+#define NV50_MEMORY_TO_MEMORY_FORMAT                                  0x00005039
+#define NV50_MEMORY_TO_MEMORY_FORMAT_UNK200                           0x00000200
+#define NV50_MEMORY_TO_MEMORY_FORMAT_UNK21C                           0x0000021c
+#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH                   0x00000238
+#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_OUT_HIGH                  0x0000023c
+
+static __must_check inline int
+RING_SPACE(struct nouveau_channel *chan, int size)
+{
+	if (chan->dma.free < size) {
+		int ret;
+
+		ret = nouveau_dma_wait(chan, size);
+		if (ret)
+			return ret;
+	}
+
+	chan->dma.free -= size;
+	return 0;
+}
+
+static inline void
+OUT_RING(struct nouveau_channel *chan, int data)
+{
+	if (NOUVEAU_DMA_DEBUG) {
+		NV_INFO(chan->dev, "Ch%d/0x%08x: 0x%08x\n",
+			chan->id, chan->dma.cur << 2, data);
+	}
+
+	nouveau_bo_wr32(chan->pushbuf_bo, chan->dma.cur++, data);
+}
+
+extern void
+OUT_RINGp(struct nouveau_channel *chan, const void *data, unsigned nr_dwords);
+
+static inline void
+BEGIN_RING(struct nouveau_channel *chan, int subc, int mthd, int size)
+{
+	OUT_RING(chan, (subc << 13) | (size << 18) | mthd);
+}
+
+#define WRITE_PUT(val) do {                                                    \
+	DRM_MEMORYBARRIER();                                                   \
+	nouveau_bo_rd32(chan->pushbuf_bo, 0);                                  \
+	nvchan_wr32(chan, chan->user_put, ((val) << 2) + chan->pushbuf_base);  \
+} while (0)
+
+static inline void
+FIRE_RING(struct nouveau_channel *chan)
+{
+	if (NOUVEAU_DMA_DEBUG) {
+		NV_INFO(chan->dev, "Ch%d/0x%08x: PUSH!\n",
+			chan->id, chan->dma.cur << 2);
+	}
+
+	if (chan->dma.cur == chan->dma.put)
+		return;
+	chan->accel_done = true;
+
+	WRITE_PUT(chan->dma.cur);
+	chan->dma.put = chan->dma.cur;
+}
+
+static inline void
+WIND_RING(struct nouveau_channel *chan)
+{
+	chan->dma.cur = chan->dma.put;
+}
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c
new file mode 100644
index 0000000..de61f46
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c
@@ -0,0 +1,569 @@
+/*
+ * Copyright 2009 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_i2c.h"
+#include "nouveau_encoder.h"
+
+static int
+auxch_rd(struct drm_encoder *encoder, int address, uint8_t *buf, int size)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct nouveau_i2c_chan *auxch;
+	int ret;
+
+	auxch = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
+	if (!auxch)
+		return -ENODEV;
+
+	ret = nouveau_dp_auxch(auxch, 9, address, buf, size);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int
+auxch_wr(struct drm_encoder *encoder, int address, uint8_t *buf, int size)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct nouveau_i2c_chan *auxch;
+	int ret;
+
+	auxch = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
+	if (!auxch)
+		return -ENODEV;
+
+	ret = nouveau_dp_auxch(auxch, 8, address, buf, size);
+	return ret;
+}
+
+static int
+nouveau_dp_lane_count_set(struct drm_encoder *encoder, uint8_t cmd)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	uint32_t tmp;
+	int or = nv_encoder->or, link = !(nv_encoder->dcb->sorconf.link & 1);
+
+	tmp  = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link));
+	tmp &= ~(NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED |
+		 NV50_SOR_DP_CTRL_LANE_MASK);
+	tmp |= ((1 << (cmd & DP_LANE_COUNT_MASK)) - 1) << 16;
+	if (cmd & DP_LANE_COUNT_ENHANCED_FRAME_EN)
+		tmp |= NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED;
+	nv_wr32(dev, NV50_SOR_DP_CTRL(or, link), tmp);
+
+	return auxch_wr(encoder, DP_LANE_COUNT_SET, &cmd, 1);
+}
+
+static int
+nouveau_dp_link_bw_set(struct drm_encoder *encoder, uint8_t cmd)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	uint32_t tmp;
+	int reg = 0x614300 + (nv_encoder->or * 0x800);
+
+	tmp  = nv_rd32(dev, reg);
+	tmp &= 0xfff3ffff;
+	if (cmd == DP_LINK_BW_2_7)
+		tmp |= 0x00040000;
+	nv_wr32(dev, reg, tmp);
+
+	return auxch_wr(encoder, DP_LINK_BW_SET, &cmd, 1);
+}
+
+static int
+nouveau_dp_link_train_set(struct drm_encoder *encoder, int pattern)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	uint32_t tmp;
+	uint8_t cmd;
+	int or = nv_encoder->or, link = !(nv_encoder->dcb->sorconf.link & 1);
+	int ret;
+
+	tmp  = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link));
+	tmp &= ~NV50_SOR_DP_CTRL_TRAINING_PATTERN;
+	tmp |= (pattern << 24);
+	nv_wr32(dev, NV50_SOR_DP_CTRL(or, link), tmp);
+
+	ret = auxch_rd(encoder, DP_TRAINING_PATTERN_SET, &cmd, 1);
+	if (ret)
+		return ret;
+	cmd &= ~DP_TRAINING_PATTERN_MASK;
+	cmd |= (pattern & DP_TRAINING_PATTERN_MASK);
+	return auxch_wr(encoder, DP_TRAINING_PATTERN_SET, &cmd, 1);
+}
+
+static int
+nouveau_dp_max_voltage_swing(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct bit_displayport_encoder_table_entry *dpse;
+	struct bit_displayport_encoder_table *dpe;
+	int i, dpe_headerlen, max_vs = 0;
+
+	dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen);
+	if (!dpe)
+		return false;
+	dpse = (void *)((char *)dpe + dpe_headerlen);
+
+	for (i = 0; i < dpe_headerlen; i++, dpse++) {
+		if (dpse->vs_level > max_vs)
+			max_vs = dpse->vs_level;
+	}
+
+	return max_vs;
+}
+
+static int
+nouveau_dp_max_pre_emphasis(struct drm_encoder *encoder, int vs)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct bit_displayport_encoder_table_entry *dpse;
+	struct bit_displayport_encoder_table *dpe;
+	int i, dpe_headerlen, max_pre = 0;
+
+	dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen);
+	if (!dpe)
+		return false;
+	dpse = (void *)((char *)dpe + dpe_headerlen);
+
+	for (i = 0; i < dpe_headerlen; i++, dpse++) {
+		if (dpse->vs_level != vs)
+			continue;
+
+		if (dpse->pre_level > max_pre)
+			max_pre = dpse->pre_level;
+	}
+
+	return max_pre;
+}
+
+static bool
+nouveau_dp_link_train_adjust(struct drm_encoder *encoder, uint8_t *config)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct bit_displayport_encoder_table_entry *dpse;
+	struct bit_displayport_encoder_table *dpe;
+	int ret, i, dpe_headerlen, vs = 0, pre = 0;
+	uint8_t request[2];
+
+	dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen);
+	if (!dpe)
+		return false;
+	dpse = (void *)((char *)dpe + dpe_headerlen);
+
+	ret = auxch_rd(encoder, DP_ADJUST_REQUEST_LANE0_1, request, 2);
+	if (ret)
+		return false;
+
+	NV_DEBUG(dev, "\t\tadjust 0x%02x 0x%02x\n", request[0], request[1]);
+
+	/* Keep all lanes at the same level.. */
+	for (i = 0; i < nv_encoder->dp.link_nr; i++) {
+		int lane_req = (request[i >> 1] >> ((i & 1) << 2)) & 0xf;
+		int lane_vs = lane_req & 3;
+		int lane_pre = (lane_req >> 2) & 3;
+
+		if (lane_vs > vs)
+			vs = lane_vs;
+		if (lane_pre > pre)
+			pre = lane_pre;
+	}
+
+	if (vs >= nouveau_dp_max_voltage_swing(encoder)) {
+		vs  = nouveau_dp_max_voltage_swing(encoder);
+		vs |= 4;
+	}
+
+	if (pre >= nouveau_dp_max_pre_emphasis(encoder, vs & 3)) {
+		pre  = nouveau_dp_max_pre_emphasis(encoder, vs & 3);
+		pre |= 4;
+	}
+
+	/* Update the configuration for all lanes.. */
+	for (i = 0; i < nv_encoder->dp.link_nr; i++)
+		config[i] = (pre << 3) | vs;
+
+	return true;
+}
+
+static bool
+nouveau_dp_link_train_commit(struct drm_encoder *encoder, uint8_t *config)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct bit_displayport_encoder_table_entry *dpse;
+	struct bit_displayport_encoder_table *dpe;
+	int or = nv_encoder->or, link = !(nv_encoder->dcb->sorconf.link & 1);
+	int dpe_headerlen, ret, i;
+
+	NV_DEBUG(dev, "\t\tconfig 0x%02x 0x%02x 0x%02x 0x%02x\n",
+		 config[0], config[1], config[2], config[3]);
+
+	dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen);
+	if (!dpe)
+		return false;
+	dpse = (void *)((char *)dpe + dpe_headerlen);
+
+	for (i = 0; i < dpe->record_nr; i++, dpse++) {
+		if (dpse->vs_level == (config[0] & 3) &&
+		    dpse->pre_level == ((config[0] >> 3) & 3))
+			break;
+	}
+	BUG_ON(i == dpe->record_nr);
+
+	for (i = 0; i < nv_encoder->dp.link_nr; i++) {
+		const int shift[4] = { 16, 8, 0, 24 };
+		uint32_t mask = 0xff << shift[i];
+		uint32_t reg0, reg1, reg2;
+
+		reg0  = nv_rd32(dev, NV50_SOR_DP_UNK118(or, link)) & ~mask;
+		reg0 |= (dpse->reg0 << shift[i]);
+		reg1  = nv_rd32(dev, NV50_SOR_DP_UNK120(or, link)) & ~mask;
+		reg1 |= (dpse->reg1 << shift[i]);
+		reg2  = nv_rd32(dev, NV50_SOR_DP_UNK130(or, link)) & 0xffff00ff;
+		reg2 |= (dpse->reg2 << 8);
+		nv_wr32(dev, NV50_SOR_DP_UNK118(or, link), reg0);
+		nv_wr32(dev, NV50_SOR_DP_UNK120(or, link), reg1);
+		nv_wr32(dev, NV50_SOR_DP_UNK130(or, link), reg2);
+	}
+
+	ret = auxch_wr(encoder, DP_TRAINING_LANE0_SET, config, 4);
+	if (ret)
+		return false;
+
+	return true;
+}
+
+bool
+nouveau_dp_link_train(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	uint8_t config[4];
+	uint8_t status[3];
+	bool cr_done, cr_max_vs, eq_done;
+	int ret = 0, i, tries, voltage;
+
+	NV_DEBUG(dev, "link training!!\n");
+train:
+	cr_done = eq_done = false;
+
+	/* set link configuration */
+	NV_DEBUG(dev, "\tbegin train: bw %d, lanes %d\n",
+		 nv_encoder->dp.link_bw, nv_encoder->dp.link_nr);
+
+	ret = nouveau_dp_link_bw_set(encoder, nv_encoder->dp.link_bw);
+	if (ret)
+		return false;
+
+	config[0] = nv_encoder->dp.link_nr;
+	if (nv_encoder->dp.dpcd_version >= 0x11)
+		config[0] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
+
+	ret = nouveau_dp_lane_count_set(encoder, config[0]);
+	if (ret)
+		return false;
+
+	/* clock recovery */
+	NV_DEBUG(dev, "\tbegin cr\n");
+	ret = nouveau_dp_link_train_set(encoder, DP_TRAINING_PATTERN_1);
+	if (ret)
+		goto stop;
+
+	tries = 0;
+	voltage = -1;
+	memset(config, 0x00, sizeof(config));
+	for (;;) {
+		if (!nouveau_dp_link_train_commit(encoder, config))
+			break;
+
+		udelay(100);
+
+		ret = auxch_rd(encoder, DP_LANE0_1_STATUS, status, 2);
+		if (ret)
+			break;
+		NV_DEBUG(dev, "\t\tstatus: 0x%02x 0x%02x\n",
+			 status[0], status[1]);
+
+		cr_done = true;
+		cr_max_vs = false;
+		for (i = 0; i < nv_encoder->dp.link_nr; i++) {
+			int lane = (status[i >> 1] >> ((i & 1) * 4)) & 0xf;
+
+			if (!(lane & DP_LANE_CR_DONE)) {
+				cr_done = false;
+				if (config[i] & DP_TRAIN_MAX_PRE_EMPHASIS_REACHED)
+					cr_max_vs = true;
+				break;
+			}
+		}
+
+		if ((config[0] & DP_TRAIN_VOLTAGE_SWING_MASK) != voltage) {
+			voltage = config[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
+			tries = 0;
+		}
+
+		if (cr_done || cr_max_vs || (++tries == 5))
+			break;
+
+		if (!nouveau_dp_link_train_adjust(encoder, config))
+			break;
+	}
+
+	if (!cr_done)
+		goto stop;
+
+	/* channel equalisation */
+	NV_DEBUG(dev, "\tbegin eq\n");
+	ret = nouveau_dp_link_train_set(encoder, DP_TRAINING_PATTERN_2);
+	if (ret)
+		goto stop;
+
+	for (tries = 0; tries <= 5; tries++) {
+		udelay(400);
+
+		ret = auxch_rd(encoder, DP_LANE0_1_STATUS, status, 3);
+		if (ret)
+			break;
+		NV_DEBUG(dev, "\t\tstatus: 0x%02x 0x%02x\n",
+			 status[0], status[1]);
+
+		eq_done = true;
+		if (!(status[2] & DP_INTERLANE_ALIGN_DONE))
+			eq_done = false;
+
+		for (i = 0; eq_done && i < nv_encoder->dp.link_nr; i++) {
+			int lane = (status[i >> 1] >> ((i & 1) * 4)) & 0xf;
+
+			if (!(lane & DP_LANE_CR_DONE)) {
+				cr_done = false;
+				break;
+			}
+
+			if (!(lane & DP_LANE_CHANNEL_EQ_DONE) ||
+			    !(lane & DP_LANE_SYMBOL_LOCKED)) {
+				eq_done = false;
+				break;
+			}
+		}
+
+		if (eq_done || !cr_done)
+			break;
+
+		if (!nouveau_dp_link_train_adjust(encoder, config) ||
+		    !nouveau_dp_link_train_commit(encoder, config))
+			break;
+	}
+
+stop:
+	/* end link training */
+	ret = nouveau_dp_link_train_set(encoder, DP_TRAINING_PATTERN_DISABLE);
+	if (ret)
+		return false;
+
+	/* retry at a lower setting, if possible */
+	if (!ret && !(eq_done && cr_done)) {
+		NV_DEBUG(dev, "\twe failed\n");
+		if (nv_encoder->dp.link_bw != DP_LINK_BW_1_62) {
+			NV_DEBUG(dev, "retry link training at low rate\n");
+			nv_encoder->dp.link_bw = DP_LINK_BW_1_62;
+			goto train;
+		}
+	}
+
+	return eq_done;
+}
+
+bool
+nouveau_dp_detect(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	uint8_t dpcd[4];
+	int ret;
+
+	ret = auxch_rd(encoder, 0x0000, dpcd, 4);
+	if (ret)
+		return false;
+
+	NV_DEBUG(dev, "encoder: link_bw %d, link_nr %d\n"
+		      "display: link_bw %d, link_nr %d version 0x%02x\n",
+		 nv_encoder->dcb->dpconf.link_bw,
+		 nv_encoder->dcb->dpconf.link_nr,
+		 dpcd[1], dpcd[2] & 0x0f, dpcd[0]);
+
+	nv_encoder->dp.dpcd_version = dpcd[0];
+
+	nv_encoder->dp.link_bw = dpcd[1];
+	if (nv_encoder->dp.link_bw != DP_LINK_BW_1_62 &&
+	    !nv_encoder->dcb->dpconf.link_bw)
+		nv_encoder->dp.link_bw = DP_LINK_BW_1_62;
+
+	nv_encoder->dp.link_nr = dpcd[2] & 0xf;
+	if (nv_encoder->dp.link_nr > nv_encoder->dcb->dpconf.link_nr)
+		nv_encoder->dp.link_nr = nv_encoder->dcb->dpconf.link_nr;
+
+	return true;
+}
+
+int
+nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr,
+		 uint8_t *data, int data_nr)
+{
+	struct drm_device *dev = auxch->dev;
+	uint32_t tmp, ctrl, stat = 0, data32[4] = {};
+	int ret = 0, i, index = auxch->rd;
+
+	NV_DEBUG(dev, "ch %d cmd %d addr 0x%x len %d\n", index, cmd, addr, data_nr);
+
+	tmp = nv_rd32(dev, NV50_AUXCH_CTRL(auxch->rd));
+	nv_wr32(dev, NV50_AUXCH_CTRL(auxch->rd), tmp | 0x00100000);
+	tmp = nv_rd32(dev, NV50_AUXCH_CTRL(auxch->rd));
+	if (!(tmp & 0x01000000)) {
+		NV_ERROR(dev, "expected bit 24 == 1, got 0x%08x\n", tmp);
+		ret = -EIO;
+		goto out;
+	}
+
+	for (i = 0; i < 3; i++) {
+		tmp = nv_rd32(dev, NV50_AUXCH_STAT(auxch->rd));
+		if (tmp & NV50_AUXCH_STAT_STATE_READY)
+			break;
+		udelay(100);
+	}
+
+	if (i == 3) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	if (!(cmd & 1)) {
+		memcpy(data32, data, data_nr);
+		for (i = 0; i < 4; i++) {
+			NV_DEBUG(dev, "wr %d: 0x%08x\n", i, data32[i]);
+			nv_wr32(dev, NV50_AUXCH_DATA_OUT(index, i), data32[i]);
+		}
+	}
+
+	nv_wr32(dev, NV50_AUXCH_ADDR(index), addr);
+	ctrl  = nv_rd32(dev, NV50_AUXCH_CTRL(index));
+	ctrl &= ~(NV50_AUXCH_CTRL_CMD | NV50_AUXCH_CTRL_LEN);
+	ctrl |= (cmd << NV50_AUXCH_CTRL_CMD_SHIFT);
+	ctrl |= ((data_nr - 1) << NV50_AUXCH_CTRL_LEN_SHIFT);
+
+	for (;;) {
+		nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl | 0x80000000);
+		nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl);
+		nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl | 0x00010000);
+		if (!nv_wait(NV50_AUXCH_CTRL(index), 0x00010000, 0x00000000)) {
+			NV_ERROR(dev, "expected bit 16 == 0, got 0x%08x\n",
+				 nv_rd32(dev, NV50_AUXCH_CTRL(index)));
+			return -EBUSY;
+		}
+
+		udelay(400);
+
+		stat = nv_rd32(dev, NV50_AUXCH_STAT(index));
+		if ((stat & NV50_AUXCH_STAT_REPLY_AUX) !=
+			    NV50_AUXCH_STAT_REPLY_AUX_DEFER)
+			break;
+	}
+
+	if (cmd & 1) {
+		for (i = 0; i < 4; i++) {
+			data32[i] = nv_rd32(dev, NV50_AUXCH_DATA_IN(index, i));
+			NV_DEBUG(dev, "rd %d: 0x%08x\n", i, data32[i]);
+		}
+		memcpy(data, data32, data_nr);
+	}
+
+out:
+	tmp = nv_rd32(dev, NV50_AUXCH_CTRL(auxch->rd));
+	nv_wr32(dev, NV50_AUXCH_CTRL(auxch->rd), tmp & ~0x00100000);
+	tmp = nv_rd32(dev, NV50_AUXCH_CTRL(auxch->rd));
+	if (tmp & 0x01000000) {
+		NV_ERROR(dev, "expected bit 24 == 0, got 0x%08x\n", tmp);
+		ret = -EIO;
+	}
+
+	udelay(400);
+
+	return ret ? ret : (stat & NV50_AUXCH_STAT_REPLY);
+}
+
+int
+nouveau_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
+		      uint8_t write_byte, uint8_t *read_byte)
+{
+	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+	struct nouveau_i2c_chan *auxch = (struct nouveau_i2c_chan *)adapter;
+	struct drm_device *dev = auxch->dev;
+	int ret = 0, cmd, addr = algo_data->address;
+	uint8_t *buf;
+
+	if (mode == MODE_I2C_READ) {
+		cmd = AUX_I2C_READ;
+		buf = read_byte;
+	} else {
+		cmd = (mode & MODE_I2C_READ) ? AUX_I2C_READ : AUX_I2C_WRITE;
+		buf = &write_byte;
+	}
+
+	if (!(mode & MODE_I2C_STOP))
+		cmd |= AUX_I2C_MOT;
+
+	if (mode & MODE_I2C_START)
+		return 1;
+
+	for (;;) {
+		ret = nouveau_dp_auxch(auxch, cmd, addr, buf, 1);
+		if (ret < 0)
+			return ret;
+
+		switch (ret & NV50_AUXCH_STAT_REPLY_I2C) {
+		case NV50_AUXCH_STAT_REPLY_I2C_ACK:
+			return 1;
+		case NV50_AUXCH_STAT_REPLY_I2C_NACK:
+			return -EREMOTEIO;
+		case NV50_AUXCH_STAT_REPLY_I2C_DEFER:
+			udelay(100);
+			break;
+		default:
+			NV_ERROR(dev, "invalid auxch status: 0x%08x\n", ret);
+			return -EREMOTEIO;
+		}
+	}
+}
+
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c
new file mode 100644
index 0000000..35249c3
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.c
@@ -0,0 +1,405 @@
+/*
+ * Copyright 2005 Stephane Marchesin.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/console.h>
+
+#include "drmP.h"
+#include "drm.h"
+#include "drm_crtc_helper.h"
+#include "nouveau_drv.h"
+#include "nouveau_hw.h"
+#include "nouveau_fb.h"
+#include "nouveau_fbcon.h"
+#include "nv50_display.h"
+
+#include "drm_pciids.h"
+
+MODULE_PARM_DESC(noagp, "Disable AGP");
+int nouveau_noagp;
+module_param_named(noagp, nouveau_noagp, int, 0400);
+
+MODULE_PARM_DESC(modeset, "Enable kernel modesetting");
+static int nouveau_modeset = -1; /* kms */
+module_param_named(modeset, nouveau_modeset, int, 0400);
+
+MODULE_PARM_DESC(vbios, "Override default VBIOS location");
+char *nouveau_vbios;
+module_param_named(vbios, nouveau_vbios, charp, 0400);
+
+MODULE_PARM_DESC(vram_pushbuf, "Force DMA push buffers to be in VRAM");
+int nouveau_vram_pushbuf;
+module_param_named(vram_pushbuf, nouveau_vram_pushbuf, int, 0400);
+
+MODULE_PARM_DESC(vram_notify, "Force DMA notifiers to be in VRAM");
+int nouveau_vram_notify;
+module_param_named(vram_notify, nouveau_vram_notify, int, 0400);
+
+MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (>=GeForce 8)");
+int nouveau_duallink = 1;
+module_param_named(duallink, nouveau_duallink, int, 0400);
+
+MODULE_PARM_DESC(uscript_lvds, "LVDS output script table ID (>=GeForce 8)");
+int nouveau_uscript_lvds = -1;
+module_param_named(uscript_lvds, nouveau_uscript_lvds, int, 0400);
+
+MODULE_PARM_DESC(uscript_tmds, "TMDS output script table ID (>=GeForce 8)");
+int nouveau_uscript_tmds = -1;
+module_param_named(uscript_tmds, nouveau_uscript_tmds, int, 0400);
+
+MODULE_PARM_DESC(tv_norm, "Default TV norm.\n"
+		 "\t\tSupported: PAL, PAL-M, PAL-N, PAL-Nc, NTSC-M, NTSC-J,\n"
+		 "\t\t\thd480i, hd480p, hd576i, hd576p, hd720p, hd1080i.\n"
+		 "\t\tDefault: PAL\n"
+		 "\t\t*NOTE* Ignored for cards with external TV encoders.");
+char *nouveau_tv_norm;
+module_param_named(tv_norm, nouveau_tv_norm, charp, 0400);
+
+MODULE_PARM_DESC(reg_debug, "Register access debug bitmask:\n"
+		"\t\t0x1 mc, 0x2 video, 0x4 fb, 0x8 extdev,\n"
+		"\t\t0x10 crtc, 0x20 ramdac, 0x40 vgacrtc, 0x80 rmvio,\n"
+		"\t\t0x100 vgaattr, 0x200 EVO (G80+). ");
+int nouveau_reg_debug;
+module_param_named(reg_debug, nouveau_reg_debug, int, 0600);
+
+int nouveau_fbpercrtc;
+#if 0
+module_param_named(fbpercrtc, nouveau_fbpercrtc, int, 0400);
+#endif
+
+static struct pci_device_id pciidlist[] = {
+	{
+		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
+		.class = PCI_BASE_CLASS_DISPLAY << 16,
+		.class_mask  = 0xff << 16,
+	},
+	{
+		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA_SGS, PCI_ANY_ID),
+		.class = PCI_BASE_CLASS_DISPLAY << 16,
+		.class_mask  = 0xff << 16,
+	},
+	{}
+};
+
+MODULE_DEVICE_TABLE(pci, pciidlist);
+
+static struct drm_driver driver;
+
+static int __devinit
+nouveau_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	return drm_get_dev(pdev, ent, &driver);
+}
+
+static void
+nouveau_pci_remove(struct pci_dev *pdev)
+{
+	struct drm_device *dev = pci_get_drvdata(pdev);
+
+	drm_put_dev(dev);
+}
+
+static int
+nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
+{
+	struct drm_device *dev = pci_get_drvdata(pdev);
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	struct nouveau_channel *chan;
+	struct drm_crtc *crtc;
+	uint32_t fbdev_flags;
+	int ret, i;
+
+	if (!drm_core_check_feature(dev, DRIVER_MODESET))
+		return -ENODEV;
+
+	if (pm_state.event == PM_EVENT_PRETHAW)
+		return 0;
+
+	fbdev_flags = dev_priv->fbdev_info->flags;
+	dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED;
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		struct nouveau_framebuffer *nouveau_fb;
+
+		nouveau_fb = nouveau_framebuffer(crtc->fb);
+		if (!nouveau_fb || !nouveau_fb->nvbo)
+			continue;
+
+		nouveau_bo_unpin(nouveau_fb->nvbo);
+	}
+
+	NV_INFO(dev, "Evicting buffers...\n");
+	ttm_bo_evict_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);
+
+	NV_INFO(dev, "Idling channels...\n");
+	for (i = 0; i < pfifo->channels; i++) {
+		struct nouveau_fence *fence = NULL;
+
+		chan = dev_priv->fifos[i];
+		if (!chan || (dev_priv->card_type >= NV_50 &&
+			      chan == dev_priv->fifos[0]))
+			continue;
+
+		ret = nouveau_fence_new(chan, &fence, true);
+		if (ret == 0) {
+			ret = nouveau_fence_wait(fence, NULL, false, false);
+			nouveau_fence_unref((void *)&fence);
+		}
+
+		if (ret) {
+			NV_ERROR(dev, "Failed to idle channel %d for suspend\n",
+				 chan->id);
+		}
+	}
+
+	pgraph->fifo_access(dev, false);
+	nouveau_wait_for_idle(dev);
+	pfifo->reassign(dev, false);
+	pfifo->disable(dev);
+	pfifo->unload_context(dev);
+	pgraph->unload_context(dev);
+
+	NV_INFO(dev, "Suspending GPU objects...\n");
+	ret = nouveau_gpuobj_suspend(dev);
+	if (ret) {
+		NV_ERROR(dev, "... failed: %d\n", ret);
+		goto out_abort;
+	}
+
+	ret = pinstmem->suspend(dev);
+	if (ret) {
+		NV_ERROR(dev, "... failed: %d\n", ret);
+		nouveau_gpuobj_suspend_cleanup(dev);
+		goto out_abort;
+	}
+
+	NV_INFO(dev, "And we're gone!\n");
+	pci_save_state(pdev);
+	if (pm_state.event == PM_EVENT_SUSPEND) {
+		pci_disable_device(pdev);
+		pci_set_power_state(pdev, PCI_D3hot);
+	}
+
+	acquire_console_sem();
+	fb_set_suspend(dev_priv->fbdev_info, 1);
+	release_console_sem();
+	dev_priv->fbdev_info->flags = fbdev_flags;
+	return 0;
+
+out_abort:
+	NV_INFO(dev, "Re-enabling acceleration..\n");
+	pfifo->enable(dev);
+	pfifo->reassign(dev, true);
+	pgraph->fifo_access(dev, true);
+	return ret;
+}
+
+static int
+nouveau_pci_resume(struct pci_dev *pdev)
+{
+	struct drm_device *dev = pci_get_drvdata(pdev);
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
+	struct drm_crtc *crtc;
+	uint32_t fbdev_flags;
+	int ret, i;
+
+	if (!drm_core_check_feature(dev, DRIVER_MODESET))
+		return -ENODEV;
+
+	fbdev_flags = dev_priv->fbdev_info->flags;
+	dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED;
+
+	NV_INFO(dev, "We're back, enabling device...\n");
+	pci_set_power_state(pdev, PCI_D0);
+	pci_restore_state(pdev);
+	if (pci_enable_device(pdev))
+		return -1;
+	pci_set_master(dev->pdev);
+
+	NV_INFO(dev, "POSTing device...\n");
+	ret = nouveau_run_vbios_init(dev);
+	if (ret)
+		return ret;
+
+	if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) {
+		ret = nouveau_mem_init_agp(dev);
+		if (ret) {
+			NV_ERROR(dev, "error reinitialising AGP: %d\n", ret);
+			return ret;
+		}
+	}
+
+	NV_INFO(dev, "Reinitialising engines...\n");
+	engine->instmem.resume(dev);
+	engine->mc.init(dev);
+	engine->timer.init(dev);
+	engine->fb.init(dev);
+	engine->graph.init(dev);
+	engine->fifo.init(dev);
+
+	NV_INFO(dev, "Restoring GPU objects...\n");
+	nouveau_gpuobj_resume(dev);
+
+	nouveau_irq_postinstall(dev);
+
+	/* Re-write SKIPS, they'll have been lost over the suspend */
+	if (nouveau_vram_pushbuf) {
+		struct nouveau_channel *chan;
+		int j;
+
+		for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
+			chan = dev_priv->fifos[i];
+			if (!chan)
+				continue;
+
+			for (j = 0; j < NOUVEAU_DMA_SKIPS; j++)
+				nouveau_bo_wr32(chan->pushbuf_bo, i, 0);
+		}
+	}
+
+	NV_INFO(dev, "Restoring mode...\n");
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		struct nouveau_framebuffer *nouveau_fb;
+
+		nouveau_fb = nouveau_framebuffer(crtc->fb);
+		if (!nouveau_fb || !nouveau_fb->nvbo)
+			continue;
+
+		nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM);
+	}
+
+	if (dev_priv->card_type < NV_50) {
+		nv04_display_restore(dev);
+		NVLockVgaCrtcs(dev, false);
+	} else
+		nv50_display_init(dev);
+
+	/* Force CLUT to get re-loaded during modeset */
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+
+		nv_crtc->lut.depth = 0;
+	}
+
+	acquire_console_sem();
+	fb_set_suspend(dev_priv->fbdev_info, 0);
+	release_console_sem();
+
+	nouveau_fbcon_zfill(dev);
+
+	drm_helper_resume_force_mode(dev);
+	dev_priv->fbdev_info->flags = fbdev_flags;
+	return 0;
+}
+
+static struct drm_driver driver = {
+	.driver_features =
+		DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG |
+		DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM,
+	.load = nouveau_load,
+	.firstopen = nouveau_firstopen,
+	.lastclose = nouveau_lastclose,
+	.unload = nouveau_unload,
+	.preclose = nouveau_preclose,
+#if defined(CONFIG_DRM_NOUVEAU_DEBUG)
+	.debugfs_init = nouveau_debugfs_init,
+	.debugfs_cleanup = nouveau_debugfs_takedown,
+#endif
+	.irq_preinstall = nouveau_irq_preinstall,
+	.irq_postinstall = nouveau_irq_postinstall,
+	.irq_uninstall = nouveau_irq_uninstall,
+	.irq_handler = nouveau_irq_handler,
+	.reclaim_buffers = drm_core_reclaim_buffers,
+	.get_map_ofs = drm_core_get_map_ofs,
+	.get_reg_ofs = drm_core_get_reg_ofs,
+	.ioctls = nouveau_ioctls,
+	.fops = {
+		.owner = THIS_MODULE,
+		.open = drm_open,
+		.release = drm_release,
+		.ioctl = drm_ioctl,
+		.mmap = nouveau_ttm_mmap,
+		.poll = drm_poll,
+		.fasync = drm_fasync,
+#if defined(CONFIG_COMPAT)
+		.compat_ioctl = nouveau_compat_ioctl,
+#endif
+	},
+	.pci_driver = {
+		.name = DRIVER_NAME,
+		.id_table = pciidlist,
+		.probe = nouveau_pci_probe,
+		.remove = nouveau_pci_remove,
+		.suspend = nouveau_pci_suspend,
+		.resume = nouveau_pci_resume
+	},
+
+	.gem_init_object = nouveau_gem_object_new,
+	.gem_free_object = nouveau_gem_object_del,
+
+	.name = DRIVER_NAME,
+	.desc = DRIVER_DESC,
+#ifdef GIT_REVISION
+	.date = GIT_REVISION,
+#else
+	.date = DRIVER_DATE,
+#endif
+	.major = DRIVER_MAJOR,
+	.minor = DRIVER_MINOR,
+	.patchlevel = DRIVER_PATCHLEVEL,
+};
+
+static int __init nouveau_init(void)
+{
+	driver.num_ioctls = nouveau_max_ioctl;
+
+	if (nouveau_modeset == -1) {
+#ifdef CONFIG_VGA_CONSOLE
+		if (vgacon_text_force())
+			nouveau_modeset = 0;
+		else
+#endif
+			nouveau_modeset = 1;
+	}
+
+	if (nouveau_modeset == 1)
+		driver.driver_features |= DRIVER_MODESET;
+
+	return drm_init(&driver);
+}
+
+static void __exit nouveau_exit(void)
+{
+	drm_exit(&driver);
+}
+
+module_init(nouveau_init);
+module_exit(nouveau_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
new file mode 100644
index 0000000..88b4c7b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -0,0 +1,1286 @@
+/*
+ * Copyright 2005 Stephane Marchesin.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __NOUVEAU_DRV_H__
+#define __NOUVEAU_DRV_H__
+
+#define DRIVER_AUTHOR		"Stephane Marchesin"
+#define DRIVER_EMAIL		"dri-devel@lists.sourceforge.net"
+
+#define DRIVER_NAME		"nouveau"
+#define DRIVER_DESC		"nVidia Riva/TNT/GeForce"
+#define DRIVER_DATE		"20090420"
+
+#define DRIVER_MAJOR		0
+#define DRIVER_MINOR		0
+#define DRIVER_PATCHLEVEL	15
+
+#define NOUVEAU_FAMILY   0x0000FFFF
+#define NOUVEAU_FLAGS    0xFFFF0000
+
+#include "ttm/ttm_bo_api.h"
+#include "ttm/ttm_bo_driver.h"
+#include "ttm/ttm_placement.h"
+#include "ttm/ttm_memory.h"
+#include "ttm/ttm_module.h"
+
+struct nouveau_fpriv {
+	struct ttm_object_file *tfile;
+};
+
+#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
+
+#include "nouveau_drm.h"
+#include "nouveau_reg.h"
+#include "nouveau_bios.h"
+
+#define MAX_NUM_DCB_ENTRIES 16
+
+#define NOUVEAU_MAX_CHANNEL_NR 128
+
+#define NV50_VM_MAX_VRAM (2*1024*1024*1024ULL)
+#define NV50_VM_BLOCK    (512*1024*1024ULL)
+#define NV50_VM_VRAM_NR  (NV50_VM_MAX_VRAM / NV50_VM_BLOCK)
+
+struct nouveau_bo {
+	struct ttm_buffer_object bo;
+	struct ttm_placement placement;
+	u32 placements[3];
+	struct ttm_bo_kmap_obj kmap;
+	struct list_head head;
+
+	/* protected by ttm_bo_reserve() */
+	struct drm_file *reserved_by;
+	struct list_head entry;
+	int pbbo_index;
+
+	struct nouveau_channel *channel;
+
+	bool mappable;
+	bool no_vm;
+
+	uint32_t tile_mode;
+	uint32_t tile_flags;
+
+	struct drm_gem_object *gem;
+	struct drm_file *cpu_filp;
+	int pin_refcnt;
+};
+
+static inline struct nouveau_bo *
+nouveau_bo(struct ttm_buffer_object *bo)
+{
+	return container_of(bo, struct nouveau_bo, bo);
+}
+
+static inline struct nouveau_bo *
+nouveau_gem_object(struct drm_gem_object *gem)
+{
+	return gem ? gem->driver_private : NULL;
+}
+
+/* TODO: submit equivalent to TTM generic API upstream? */
+static inline void __iomem *
+nvbo_kmap_obj_iovirtual(struct nouveau_bo *nvbo)
+{
+	bool is_iomem;
+	void __iomem *ioptr = (void __force __iomem *)ttm_kmap_obj_virtual(
+						&nvbo->kmap, &is_iomem);
+	WARN_ON_ONCE(ioptr && !is_iomem);
+	return ioptr;
+}
+
+struct mem_block {
+	struct mem_block *next;
+	struct mem_block *prev;
+	uint64_t start;
+	uint64_t size;
+	struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */
+};
+
+enum nouveau_flags {
+	NV_NFORCE   = 0x10000000,
+	NV_NFORCE2  = 0x20000000
+};
+
+#define NVOBJ_ENGINE_SW		0
+#define NVOBJ_ENGINE_GR		1
+#define NVOBJ_ENGINE_DISPLAY	2
+#define NVOBJ_ENGINE_INT	0xdeadbeef
+
+#define NVOBJ_FLAG_ALLOW_NO_REFS	(1 << 0)
+#define NVOBJ_FLAG_ZERO_ALLOC		(1 << 1)
+#define NVOBJ_FLAG_ZERO_FREE		(1 << 2)
+#define NVOBJ_FLAG_FAKE			(1 << 3)
+struct nouveau_gpuobj {
+	struct list_head list;
+
+	struct nouveau_channel *im_channel;
+	struct mem_block *im_pramin;
+	struct nouveau_bo *im_backing;
+	uint32_t im_backing_start;
+	uint32_t *im_backing_suspend;
+	int im_bound;
+
+	uint32_t flags;
+	int refcount;
+
+	uint32_t engine;
+	uint32_t class;
+
+	void (*dtor)(struct drm_device *, struct nouveau_gpuobj *);
+	void *priv;
+};
+
+struct nouveau_gpuobj_ref {
+	struct list_head list;
+
+	struct nouveau_gpuobj *gpuobj;
+	uint32_t instance;
+
+	struct nouveau_channel *channel;
+	int handle;
+};
+
+struct nouveau_channel {
+	struct drm_device *dev;
+	int id;
+
+	/* owner of this fifo */
+	struct drm_file *file_priv;
+	/* mapping of the fifo itself */
+	struct drm_local_map *map;
+
+	/* mapping of the regs controling the fifo */
+	void __iomem *user;
+	uint32_t user_get;
+	uint32_t user_put;
+
+	/* Fencing */
+	struct {
+		/* lock protects the pending list only */
+		spinlock_t lock;
+		struct list_head pending;
+		uint32_t sequence;
+		uint32_t sequence_ack;
+		uint32_t last_sequence_irq;
+	} fence;
+
+	/* DMA push buffer */
+	struct nouveau_gpuobj_ref *pushbuf;
+	struct nouveau_bo         *pushbuf_bo;
+	uint32_t                   pushbuf_base;
+
+	/* Notifier memory */
+	struct nouveau_bo *notifier_bo;
+	struct mem_block *notifier_heap;
+
+	/* PFIFO context */
+	struct nouveau_gpuobj_ref *ramfc;
+	struct nouveau_gpuobj_ref *cache;
+
+	/* PGRAPH context */
+	/* XXX may be merge 2 pointers as private data ??? */
+	struct nouveau_gpuobj_ref *ramin_grctx;
+	void *pgraph_ctx;
+
+	/* NV50 VM */
+	struct nouveau_gpuobj     *vm_pd;
+	struct nouveau_gpuobj_ref *vm_gart_pt;
+	struct nouveau_gpuobj_ref *vm_vram_pt[NV50_VM_VRAM_NR];
+
+	/* Objects */
+	struct nouveau_gpuobj_ref *ramin; /* Private instmem */
+	struct mem_block          *ramin_heap; /* Private PRAMIN heap */
+	struct nouveau_gpuobj_ref *ramht; /* Hash table */
+	struct list_head           ramht_refs; /* Objects referenced by RAMHT */
+
+	/* GPU object info for stuff used in-kernel (mm_enabled) */
+	uint32_t m2mf_ntfy;
+	uint32_t vram_handle;
+	uint32_t gart_handle;
+	bool accel_done;
+
+	/* Push buffer state (only for drm's channel on !mm_enabled) */
+	struct {
+		int max;
+		int free;
+		int cur;
+		int put;
+		/* access via pushbuf_bo */
+	} dma;
+
+	uint32_t sw_subchannel[8];
+
+	struct {
+		struct nouveau_gpuobj *vblsem;
+		uint32_t vblsem_offset;
+		uint32_t vblsem_rval;
+		struct list_head vbl_wait;
+	} nvsw;
+
+	struct {
+		bool active;
+		char name[32];
+		struct drm_info_list info;
+	} debugfs;
+};
+
+struct nouveau_instmem_engine {
+	void	*priv;
+
+	int	(*init)(struct drm_device *dev);
+	void	(*takedown)(struct drm_device *dev);
+	int	(*suspend)(struct drm_device *dev);
+	void	(*resume)(struct drm_device *dev);
+
+	int	(*populate)(struct drm_device *, struct nouveau_gpuobj *,
+			    uint32_t *size);
+	void	(*clear)(struct drm_device *, struct nouveau_gpuobj *);
+	int	(*bind)(struct drm_device *, struct nouveau_gpuobj *);
+	int	(*unbind)(struct drm_device *, struct nouveau_gpuobj *);
+	void	(*prepare_access)(struct drm_device *, bool write);
+	void	(*finish_access)(struct drm_device *);
+};
+
+struct nouveau_mc_engine {
+	int  (*init)(struct drm_device *dev);
+	void (*takedown)(struct drm_device *dev);
+};
+
+struct nouveau_timer_engine {
+	int      (*init)(struct drm_device *dev);
+	void     (*takedown)(struct drm_device *dev);
+	uint64_t (*read)(struct drm_device *dev);
+};
+
+struct nouveau_fb_engine {
+	int  (*init)(struct drm_device *dev);
+	void (*takedown)(struct drm_device *dev);
+};
+
+struct nouveau_fifo_engine {
+	void *priv;
+
+	int  channels;
+
+	int  (*init)(struct drm_device *);
+	void (*takedown)(struct drm_device *);
+
+	void (*disable)(struct drm_device *);
+	void (*enable)(struct drm_device *);
+	bool (*reassign)(struct drm_device *, bool enable);
+
+	int  (*channel_id)(struct drm_device *);
+
+	int  (*create_context)(struct nouveau_channel *);
+	void (*destroy_context)(struct nouveau_channel *);
+	int  (*load_context)(struct nouveau_channel *);
+	int  (*unload_context)(struct drm_device *);
+};
+
+struct nouveau_pgraph_object_method {
+	int id;
+	int (*exec)(struct nouveau_channel *chan, int grclass, int mthd,
+		      uint32_t data);
+};
+
+struct nouveau_pgraph_object_class {
+	int id;
+	bool software;
+	struct nouveau_pgraph_object_method *methods;
+};
+
+struct nouveau_pgraph_engine {
+	struct nouveau_pgraph_object_class *grclass;
+	bool accel_blocked;
+	void *ctxprog;
+	void *ctxvals;
+
+	int  (*init)(struct drm_device *);
+	void (*takedown)(struct drm_device *);
+
+	void (*fifo_access)(struct drm_device *, bool);
+
+	struct nouveau_channel *(*channel)(struct drm_device *);
+	int  (*create_context)(struct nouveau_channel *);
+	void (*destroy_context)(struct nouveau_channel *);
+	int  (*load_context)(struct nouveau_channel *);
+	int  (*unload_context)(struct drm_device *);
+};
+
+struct nouveau_engine {
+	struct nouveau_instmem_engine instmem;
+	struct nouveau_mc_engine      mc;
+	struct nouveau_timer_engine   timer;
+	struct nouveau_fb_engine      fb;
+	struct nouveau_pgraph_engine  graph;
+	struct nouveau_fifo_engine    fifo;
+};
+
+struct nouveau_pll_vals {
+	union {
+		struct {
+#ifdef __BIG_ENDIAN
+			uint8_t N1, M1, N2, M2;
+#else
+			uint8_t M1, N1, M2, N2;
+#endif
+		};
+		struct {
+			uint16_t NM1, NM2;
+		} __attribute__((packed));
+	};
+	int log2P;
+
+	int refclk;
+};
+
+enum nv04_fp_display_regs {
+	FP_DISPLAY_END,
+	FP_TOTAL,
+	FP_CRTC,
+	FP_SYNC_START,
+	FP_SYNC_END,
+	FP_VALID_START,
+	FP_VALID_END
+};
+
+struct nv04_crtc_reg {
+	unsigned char MiscOutReg;     /* */
+	uint8_t CRTC[0x9f];
+	uint8_t CR58[0x10];
+	uint8_t Sequencer[5];
+	uint8_t Graphics[9];
+	uint8_t Attribute[21];
+	unsigned char DAC[768];       /* Internal Colorlookuptable */
+
+	/* PCRTC regs */
+	uint32_t fb_start;
+	uint32_t crtc_cfg;
+	uint32_t cursor_cfg;
+	uint32_t gpio_ext;
+	uint32_t crtc_830;
+	uint32_t crtc_834;
+	uint32_t crtc_850;
+	uint32_t crtc_eng_ctrl;
+
+	/* PRAMDAC regs */
+	uint32_t nv10_cursync;
+	struct nouveau_pll_vals pllvals;
+	uint32_t ramdac_gen_ctrl;
+	uint32_t ramdac_630;
+	uint32_t ramdac_634;
+	uint32_t tv_setup;
+	uint32_t tv_vtotal;
+	uint32_t tv_vskew;
+	uint32_t tv_vsync_delay;
+	uint32_t tv_htotal;
+	uint32_t tv_hskew;
+	uint32_t tv_hsync_delay;
+	uint32_t tv_hsync_delay2;
+	uint32_t fp_horiz_regs[7];
+	uint32_t fp_vert_regs[7];
+	uint32_t dither;
+	uint32_t fp_control;
+	uint32_t dither_regs[6];
+	uint32_t fp_debug_0;
+	uint32_t fp_debug_1;
+	uint32_t fp_debug_2;
+	uint32_t fp_margin_color;
+	uint32_t ramdac_8c0;
+	uint32_t ramdac_a20;
+	uint32_t ramdac_a24;
+	uint32_t ramdac_a34;
+	uint32_t ctv_regs[38];
+};
+
+struct nv04_output_reg {
+	uint32_t output;
+	int head;
+};
+
+struct nv04_mode_state {
+	uint32_t bpp;
+	uint32_t width;
+	uint32_t height;
+	uint32_t interlace;
+	uint32_t repaint0;
+	uint32_t repaint1;
+	uint32_t screen;
+	uint32_t scale;
+	uint32_t dither;
+	uint32_t extra;
+	uint32_t fifo;
+	uint32_t pixel;
+	uint32_t horiz;
+	int arbitration0;
+	int arbitration1;
+	uint32_t pll;
+	uint32_t pllB;
+	uint32_t vpll;
+	uint32_t vpll2;
+	uint32_t vpllB;
+	uint32_t vpll2B;
+	uint32_t pllsel;
+	uint32_t sel_clk;
+	uint32_t general;
+	uint32_t crtcOwner;
+	uint32_t head;
+	uint32_t head2;
+	uint32_t cursorConfig;
+	uint32_t cursor0;
+	uint32_t cursor1;
+	uint32_t cursor2;
+	uint32_t timingH;
+	uint32_t timingV;
+	uint32_t displayV;
+	uint32_t crtcSync;
+
+	struct nv04_crtc_reg crtc_reg[2];
+};
+
+enum nouveau_card_type {
+	NV_04      = 0x00,
+	NV_10      = 0x10,
+	NV_20      = 0x20,
+	NV_30      = 0x30,
+	NV_40      = 0x40,
+	NV_50      = 0x50,
+};
+
+struct drm_nouveau_private {
+	struct drm_device *dev;
+	enum {
+		NOUVEAU_CARD_INIT_DOWN,
+		NOUVEAU_CARD_INIT_DONE,
+		NOUVEAU_CARD_INIT_FAILED
+	} init_state;
+
+	/* the card type, takes NV_* as values */
+	enum nouveau_card_type card_type;
+	/* exact chipset, derived from NV_PMC_BOOT_0 */
+	int chipset;
+	int flags;
+
+	void __iomem *mmio;
+	void __iomem *ramin;
+	uint32_t ramin_size;
+
+	struct workqueue_struct *wq;
+	struct work_struct irq_work;
+
+	struct list_head vbl_waiting;
+
+	struct {
+		struct ttm_global_reference mem_global_ref;
+		struct ttm_bo_global_ref bo_global_ref;
+		struct ttm_bo_device bdev;
+		spinlock_t bo_list_lock;
+		struct list_head bo_list;
+		atomic_t validate_sequence;
+	} ttm;
+
+	struct fb_info *fbdev_info;
+
+	int fifo_alloc_count;
+	struct nouveau_channel *fifos[NOUVEAU_MAX_CHANNEL_NR];
+
+	struct nouveau_engine engine;
+	struct nouveau_channel *channel;
+
+	/* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */
+	struct nouveau_gpuobj *ramht;
+	uint32_t ramin_rsvd_vram;
+	uint32_t ramht_offset;
+	uint32_t ramht_size;
+	uint32_t ramht_bits;
+	uint32_t ramfc_offset;
+	uint32_t ramfc_size;
+	uint32_t ramro_offset;
+	uint32_t ramro_size;
+
+	/* base physical adresses */
+	uint64_t fb_phys;
+	uint64_t fb_available_size;
+	uint64_t fb_mappable_pages;
+	uint64_t fb_aper_free;
+
+	struct {
+		enum {
+			NOUVEAU_GART_NONE = 0,
+			NOUVEAU_GART_AGP,
+			NOUVEAU_GART_SGDMA
+		} type;
+		uint64_t aper_base;
+		uint64_t aper_size;
+		uint64_t aper_free;
+
+		struct nouveau_gpuobj *sg_ctxdma;
+		struct page *sg_dummy_page;
+		dma_addr_t sg_dummy_bus;
+
+		/* nottm hack */
+		struct drm_ttm_backend *sg_be;
+		unsigned long sg_handle;
+	} gart_info;
+
+	/* G8x/G9x virtual address space */
+	uint64_t vm_gart_base;
+	uint64_t vm_gart_size;
+	uint64_t vm_vram_base;
+	uint64_t vm_vram_size;
+	uint64_t vm_end;
+	struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR];
+	int vm_vram_pt_nr;
+
+	/* the mtrr covering the FB */
+	int fb_mtrr;
+
+	struct mem_block *ramin_heap;
+
+	/* context table pointed to be NV_PGRAPH_CHANNEL_CTX_TABLE (0x400780) */
+	uint32_t ctx_table_size;
+	struct nouveau_gpuobj_ref *ctx_table;
+
+	struct list_head gpuobj_list;
+
+	struct nvbios VBIOS;
+	struct nouveau_bios_info *vbios;
+
+	struct nv04_mode_state mode_reg;
+	struct nv04_mode_state saved_reg;
+	uint32_t saved_vga_font[4][16384];
+	uint32_t crtc_owner;
+	uint32_t dac_users[4];
+
+	struct nouveau_suspend_resume {
+		uint32_t fifo_mode;
+		uint32_t graph_ctx_control;
+		uint32_t graph_state;
+		uint32_t *ramin_copy;
+		uint64_t ramin_size;
+	} susres;
+
+	struct backlight_device *backlight;
+	bool acpi_dsm;
+
+	struct nouveau_channel *evo;
+
+	struct {
+		struct dentry *channel_root;
+	} debugfs;
+};
+
+static inline struct drm_nouveau_private *
+nouveau_bdev(struct ttm_bo_device *bd)
+{
+	return container_of(bd, struct drm_nouveau_private, ttm.bdev);
+}
+
+static inline int
+nouveau_bo_ref(struct nouveau_bo *ref, struct nouveau_bo **pnvbo)
+{
+	struct nouveau_bo *prev;
+
+	if (!pnvbo)
+		return -EINVAL;
+	prev = *pnvbo;
+
+	*pnvbo = ref ? nouveau_bo(ttm_bo_reference(&ref->bo)) : NULL;
+	if (prev) {
+		struct ttm_buffer_object *bo = &prev->bo;
+
+		ttm_bo_unref(&bo);
+	}
+
+	return 0;
+}
+
+#define NOUVEAU_CHECK_INITIALISED_WITH_RETURN do {            \
+	struct drm_nouveau_private *nv = dev->dev_private;    \
+	if (nv->init_state != NOUVEAU_CARD_INIT_DONE) {       \
+		NV_ERROR(dev, "called without init\n");       \
+		return -EINVAL;                               \
+	}                                                     \
+} while (0)
+
+#define NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(id, cl, ch) do {    \
+	struct drm_nouveau_private *nv = dev->dev_private;       \
+	if (!nouveau_channel_owner(dev, (cl), (id))) {           \
+		NV_ERROR(dev, "pid %d doesn't own channel %d\n", \
+			 DRM_CURRENTPID, (id));                  \
+		return -EPERM;                                   \
+	}                                                        \
+	(ch) = nv->fifos[(id)];                                  \
+} while (0)
+
+/* nouveau_drv.c */
+extern int nouveau_noagp;
+extern int nouveau_duallink;
+extern int nouveau_uscript_lvds;
+extern int nouveau_uscript_tmds;
+extern int nouveau_vram_pushbuf;
+extern int nouveau_vram_notify;
+extern int nouveau_fbpercrtc;
+extern char *nouveau_tv_norm;
+extern int nouveau_reg_debug;
+extern char *nouveau_vbios;
+
+/* nouveau_state.c */
+extern void nouveau_preclose(struct drm_device *dev, struct drm_file *);
+extern int  nouveau_load(struct drm_device *, unsigned long flags);
+extern int  nouveau_firstopen(struct drm_device *);
+extern void nouveau_lastclose(struct drm_device *);
+extern int  nouveau_unload(struct drm_device *);
+extern int  nouveau_ioctl_getparam(struct drm_device *, void *data,
+				   struct drm_file *);
+extern int  nouveau_ioctl_setparam(struct drm_device *, void *data,
+				   struct drm_file *);
+extern bool nouveau_wait_until(struct drm_device *, uint64_t timeout,
+			       uint32_t reg, uint32_t mask, uint32_t val);
+extern bool nouveau_wait_for_idle(struct drm_device *);
+extern int  nouveau_card_init(struct drm_device *);
+extern int  nouveau_ioctl_card_init(struct drm_device *, void *data,
+				    struct drm_file *);
+extern int  nouveau_ioctl_suspend(struct drm_device *, void *data,
+				  struct drm_file *);
+extern int  nouveau_ioctl_resume(struct drm_device *, void *data,
+				 struct drm_file *);
+
+/* nouveau_mem.c */
+extern int  nouveau_mem_init_heap(struct mem_block **, uint64_t start,
+				 uint64_t size);
+extern struct mem_block *nouveau_mem_alloc_block(struct mem_block *,
+						 uint64_t size, int align2,
+						 struct drm_file *, int tail);
+extern void nouveau_mem_takedown(struct mem_block **heap);
+extern void nouveau_mem_free_block(struct mem_block *);
+extern uint64_t nouveau_mem_fb_amount(struct drm_device *);
+extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap);
+extern int  nouveau_mem_init(struct drm_device *);
+extern int  nouveau_mem_init_agp(struct drm_device *);
+extern void nouveau_mem_close(struct drm_device *);
+extern int  nv50_mem_vm_bind_linear(struct drm_device *, uint64_t virt,
+				    uint32_t size, uint32_t flags,
+				    uint64_t phys);
+extern void nv50_mem_vm_unbind(struct drm_device *, uint64_t virt,
+			       uint32_t size);
+
+/* nouveau_notifier.c */
+extern int  nouveau_notifier_init_channel(struct nouveau_channel *);
+extern void nouveau_notifier_takedown_channel(struct nouveau_channel *);
+extern int  nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle,
+				   int cout, uint32_t *offset);
+extern int  nouveau_notifier_offset(struct nouveau_gpuobj *, uint32_t *);
+extern int  nouveau_ioctl_notifier_alloc(struct drm_device *, void *data,
+					 struct drm_file *);
+extern int  nouveau_ioctl_notifier_free(struct drm_device *, void *data,
+					struct drm_file *);
+
+/* nouveau_channel.c */
+extern struct drm_ioctl_desc nouveau_ioctls[];
+extern int nouveau_max_ioctl;
+extern void nouveau_channel_cleanup(struct drm_device *, struct drm_file *);
+extern int  nouveau_channel_owner(struct drm_device *, struct drm_file *,
+				  int channel);
+extern int  nouveau_channel_alloc(struct drm_device *dev,
+				  struct nouveau_channel **chan,
+				  struct drm_file *file_priv,
+				  uint32_t fb_ctxdma, uint32_t tt_ctxdma);
+extern void nouveau_channel_free(struct nouveau_channel *);
+extern int  nouveau_channel_idle(struct nouveau_channel *chan);
+
+/* nouveau_object.c */
+extern int  nouveau_gpuobj_early_init(struct drm_device *);
+extern int  nouveau_gpuobj_init(struct drm_device *);
+extern void nouveau_gpuobj_takedown(struct drm_device *);
+extern void nouveau_gpuobj_late_takedown(struct drm_device *);
+extern int  nouveau_gpuobj_suspend(struct drm_device *dev);
+extern void nouveau_gpuobj_suspend_cleanup(struct drm_device *dev);
+extern void nouveau_gpuobj_resume(struct drm_device *dev);
+extern int nouveau_gpuobj_channel_init(struct nouveau_channel *,
+				       uint32_t vram_h, uint32_t tt_h);
+extern void nouveau_gpuobj_channel_takedown(struct nouveau_channel *);
+extern int nouveau_gpuobj_new(struct drm_device *, struct nouveau_channel *,
+			      uint32_t size, int align, uint32_t flags,
+			      struct nouveau_gpuobj **);
+extern int nouveau_gpuobj_del(struct drm_device *, struct nouveau_gpuobj **);
+extern int nouveau_gpuobj_ref_add(struct drm_device *, struct nouveau_channel *,
+				  uint32_t handle, struct nouveau_gpuobj *,
+				  struct nouveau_gpuobj_ref **);
+extern int nouveau_gpuobj_ref_del(struct drm_device *,
+				  struct nouveau_gpuobj_ref **);
+extern int nouveau_gpuobj_ref_find(struct nouveau_channel *, uint32_t handle,
+				   struct nouveau_gpuobj_ref **ref_ret);
+extern int nouveau_gpuobj_new_ref(struct drm_device *,
+				  struct nouveau_channel *alloc_chan,
+				  struct nouveau_channel *ref_chan,
+				  uint32_t handle, uint32_t size, int align,
+				  uint32_t flags, struct nouveau_gpuobj_ref **);
+extern int nouveau_gpuobj_new_fake(struct drm_device *,
+				   uint32_t p_offset, uint32_t b_offset,
+				   uint32_t size, uint32_t flags,
+				   struct nouveau_gpuobj **,
+				   struct nouveau_gpuobj_ref**);
+extern int nouveau_gpuobj_dma_new(struct nouveau_channel *, int class,
+				  uint64_t offset, uint64_t size, int access,
+				  int target, struct nouveau_gpuobj **);
+extern int nouveau_gpuobj_gart_dma_new(struct nouveau_channel *,
+				       uint64_t offset, uint64_t size,
+				       int access, struct nouveau_gpuobj **,
+				       uint32_t *o_ret);
+extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, int class,
+				 struct nouveau_gpuobj **);
+extern int nouveau_ioctl_grobj_alloc(struct drm_device *, void *data,
+				     struct drm_file *);
+extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data,
+				     struct drm_file *);
+
+/* nouveau_irq.c */
+extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS);
+extern void        nouveau_irq_preinstall(struct drm_device *);
+extern int         nouveau_irq_postinstall(struct drm_device *);
+extern void        nouveau_irq_uninstall(struct drm_device *);
+
+/* nouveau_sgdma.c */
+extern int nouveau_sgdma_init(struct drm_device *);
+extern void nouveau_sgdma_takedown(struct drm_device *);
+extern int nouveau_sgdma_get_page(struct drm_device *, uint32_t offset,
+				  uint32_t *page);
+extern struct ttm_backend *nouveau_sgdma_init_ttm(struct drm_device *);
+
+/* nouveau_debugfs.c */
+#if defined(CONFIG_DRM_NOUVEAU_DEBUG)
+extern int  nouveau_debugfs_init(struct drm_minor *);
+extern void nouveau_debugfs_takedown(struct drm_minor *);
+extern int  nouveau_debugfs_channel_init(struct nouveau_channel *);
+extern void nouveau_debugfs_channel_fini(struct nouveau_channel *);
+#else
+static inline int
+nouveau_debugfs_init(struct drm_minor *minor)
+{
+	return 0;
+}
+
+static inline void nouveau_debugfs_takedown(struct drm_minor *minor)
+{
+}
+
+static inline int
+nouveau_debugfs_channel_init(struct nouveau_channel *chan)
+{
+	return 0;
+}
+
+static inline void
+nouveau_debugfs_channel_fini(struct nouveau_channel *chan)
+{
+}
+#endif
+
+/* nouveau_dma.c */
+extern int  nouveau_dma_init(struct nouveau_channel *);
+extern int  nouveau_dma_wait(struct nouveau_channel *, int size);
+
+/* nouveau_acpi.c */
+#ifdef CONFIG_ACPI
+extern int nouveau_hybrid_setup(struct drm_device *dev);
+extern bool nouveau_dsm_probe(struct drm_device *dev);
+#else
+static inline int nouveau_hybrid_setup(struct drm_device *dev)
+{
+	return 0;
+}
+static inline bool nouveau_dsm_probe(struct drm_device *dev)
+{
+	return false;
+}
+#endif
+
+/* nouveau_backlight.c */
+#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
+extern int nouveau_backlight_init(struct drm_device *);
+extern void nouveau_backlight_exit(struct drm_device *);
+#else
+static inline int nouveau_backlight_init(struct drm_device *dev)
+{
+	return 0;
+}
+
+static inline void nouveau_backlight_exit(struct drm_device *dev) { }
+#endif
+
+/* nouveau_bios.c */
+extern int nouveau_bios_init(struct drm_device *);
+extern void nouveau_bios_takedown(struct drm_device *dev);
+extern int nouveau_run_vbios_init(struct drm_device *);
+extern void nouveau_bios_run_init_table(struct drm_device *, uint16_t table,
+					struct dcb_entry *);
+extern struct dcb_gpio_entry *nouveau_bios_gpio_entry(struct drm_device *,
+						      enum dcb_gpio_tag);
+extern struct dcb_connector_table_entry *
+nouveau_bios_connector_entry(struct drm_device *, int index);
+extern int get_pll_limits(struct drm_device *, uint32_t limit_match,
+			  struct pll_lims *);
+extern int nouveau_bios_run_display_table(struct drm_device *,
+					  struct dcb_entry *,
+					  uint32_t script, int pxclk);
+extern void *nouveau_bios_dp_table(struct drm_device *, struct dcb_entry *,
+				   int *length);
+extern bool nouveau_bios_fp_mode(struct drm_device *, struct drm_display_mode *);
+extern uint8_t *nouveau_bios_embedded_edid(struct drm_device *);
+extern int nouveau_bios_parse_lvds_table(struct drm_device *, int pxclk,
+					 bool *dl, bool *if_is_24bit);
+extern int run_tmds_table(struct drm_device *, struct dcb_entry *,
+			  int head, int pxclk);
+extern int call_lvds_script(struct drm_device *, struct dcb_entry *, int head,
+			    enum LVDS_script, int pxclk);
+
+/* nouveau_ttm.c */
+int nouveau_ttm_global_init(struct drm_nouveau_private *);
+void nouveau_ttm_global_release(struct drm_nouveau_private *);
+int nouveau_ttm_mmap(struct file *, struct vm_area_struct *);
+
+/* nouveau_dp.c */
+int nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr,
+		     uint8_t *data, int data_nr);
+bool nouveau_dp_detect(struct drm_encoder *);
+bool nouveau_dp_link_train(struct drm_encoder *);
+
+/* nv04_fb.c */
+extern int  nv04_fb_init(struct drm_device *);
+extern void nv04_fb_takedown(struct drm_device *);
+
+/* nv10_fb.c */
+extern int  nv10_fb_init(struct drm_device *);
+extern void nv10_fb_takedown(struct drm_device *);
+
+/* nv40_fb.c */
+extern int  nv40_fb_init(struct drm_device *);
+extern void nv40_fb_takedown(struct drm_device *);
+
+/* nv04_fifo.c */
+extern int  nv04_fifo_init(struct drm_device *);
+extern void nv04_fifo_disable(struct drm_device *);
+extern void nv04_fifo_enable(struct drm_device *);
+extern bool nv04_fifo_reassign(struct drm_device *, bool);
+extern int  nv04_fifo_channel_id(struct drm_device *);
+extern int  nv04_fifo_create_context(struct nouveau_channel *);
+extern void nv04_fifo_destroy_context(struct nouveau_channel *);
+extern int  nv04_fifo_load_context(struct nouveau_channel *);
+extern int  nv04_fifo_unload_context(struct drm_device *);
+
+/* nv10_fifo.c */
+extern int  nv10_fifo_init(struct drm_device *);
+extern int  nv10_fifo_channel_id(struct drm_device *);
+extern int  nv10_fifo_create_context(struct nouveau_channel *);
+extern void nv10_fifo_destroy_context(struct nouveau_channel *);
+extern int  nv10_fifo_load_context(struct nouveau_channel *);
+extern int  nv10_fifo_unload_context(struct drm_device *);
+
+/* nv40_fifo.c */
+extern int  nv40_fifo_init(struct drm_device *);
+extern int  nv40_fifo_create_context(struct nouveau_channel *);
+extern void nv40_fifo_destroy_context(struct nouveau_channel *);
+extern int  nv40_fifo_load_context(struct nouveau_channel *);
+extern int  nv40_fifo_unload_context(struct drm_device *);
+
+/* nv50_fifo.c */
+extern int  nv50_fifo_init(struct drm_device *);
+extern void nv50_fifo_takedown(struct drm_device *);
+extern int  nv50_fifo_channel_id(struct drm_device *);
+extern int  nv50_fifo_create_context(struct nouveau_channel *);
+extern void nv50_fifo_destroy_context(struct nouveau_channel *);
+extern int  nv50_fifo_load_context(struct nouveau_channel *);
+extern int  nv50_fifo_unload_context(struct drm_device *);
+
+/* nv04_graph.c */
+extern struct nouveau_pgraph_object_class nv04_graph_grclass[];
+extern int  nv04_graph_init(struct drm_device *);
+extern void nv04_graph_takedown(struct drm_device *);
+extern void nv04_graph_fifo_access(struct drm_device *, bool);
+extern struct nouveau_channel *nv04_graph_channel(struct drm_device *);
+extern int  nv04_graph_create_context(struct nouveau_channel *);
+extern void nv04_graph_destroy_context(struct nouveau_channel *);
+extern int  nv04_graph_load_context(struct nouveau_channel *);
+extern int  nv04_graph_unload_context(struct drm_device *);
+extern void nv04_graph_context_switch(struct drm_device *);
+
+/* nv10_graph.c */
+extern struct nouveau_pgraph_object_class nv10_graph_grclass[];
+extern int  nv10_graph_init(struct drm_device *);
+extern void nv10_graph_takedown(struct drm_device *);
+extern struct nouveau_channel *nv10_graph_channel(struct drm_device *);
+extern int  nv10_graph_create_context(struct nouveau_channel *);
+extern void nv10_graph_destroy_context(struct nouveau_channel *);
+extern int  nv10_graph_load_context(struct nouveau_channel *);
+extern int  nv10_graph_unload_context(struct drm_device *);
+extern void nv10_graph_context_switch(struct drm_device *);
+
+/* nv20_graph.c */
+extern struct nouveau_pgraph_object_class nv20_graph_grclass[];
+extern struct nouveau_pgraph_object_class nv30_graph_grclass[];
+extern int  nv20_graph_create_context(struct nouveau_channel *);
+extern void nv20_graph_destroy_context(struct nouveau_channel *);
+extern int  nv20_graph_load_context(struct nouveau_channel *);
+extern int  nv20_graph_unload_context(struct drm_device *);
+extern int  nv20_graph_init(struct drm_device *);
+extern void nv20_graph_takedown(struct drm_device *);
+extern int  nv30_graph_init(struct drm_device *);
+
+/* nv40_graph.c */
+extern struct nouveau_pgraph_object_class nv40_graph_grclass[];
+extern int  nv40_graph_init(struct drm_device *);
+extern void nv40_graph_takedown(struct drm_device *);
+extern struct nouveau_channel *nv40_graph_channel(struct drm_device *);
+extern int  nv40_graph_create_context(struct nouveau_channel *);
+extern void nv40_graph_destroy_context(struct nouveau_channel *);
+extern int  nv40_graph_load_context(struct nouveau_channel *);
+extern int  nv40_graph_unload_context(struct drm_device *);
+extern int  nv40_grctx_init(struct drm_device *);
+extern void nv40_grctx_fini(struct drm_device *);
+extern void nv40_grctx_vals_load(struct drm_device *, struct nouveau_gpuobj *);
+
+/* nv50_graph.c */
+extern struct nouveau_pgraph_object_class nv50_graph_grclass[];
+extern int  nv50_graph_init(struct drm_device *);
+extern void nv50_graph_takedown(struct drm_device *);
+extern void nv50_graph_fifo_access(struct drm_device *, bool);
+extern struct nouveau_channel *nv50_graph_channel(struct drm_device *);
+extern int  nv50_graph_create_context(struct nouveau_channel *);
+extern void nv50_graph_destroy_context(struct nouveau_channel *);
+extern int  nv50_graph_load_context(struct nouveau_channel *);
+extern int  nv50_graph_unload_context(struct drm_device *);
+extern void nv50_graph_context_switch(struct drm_device *);
+
+/* nv04_instmem.c */
+extern int  nv04_instmem_init(struct drm_device *);
+extern void nv04_instmem_takedown(struct drm_device *);
+extern int  nv04_instmem_suspend(struct drm_device *);
+extern void nv04_instmem_resume(struct drm_device *);
+extern int  nv04_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
+				  uint32_t *size);
+extern void nv04_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
+extern int  nv04_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
+extern int  nv04_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
+extern void nv04_instmem_prepare_access(struct drm_device *, bool write);
+extern void nv04_instmem_finish_access(struct drm_device *);
+
+/* nv50_instmem.c */
+extern int  nv50_instmem_init(struct drm_device *);
+extern void nv50_instmem_takedown(struct drm_device *);
+extern int  nv50_instmem_suspend(struct drm_device *);
+extern void nv50_instmem_resume(struct drm_device *);
+extern int  nv50_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
+				  uint32_t *size);
+extern void nv50_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
+extern int  nv50_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
+extern int  nv50_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
+extern void nv50_instmem_prepare_access(struct drm_device *, bool write);
+extern void nv50_instmem_finish_access(struct drm_device *);
+
+/* nv04_mc.c */
+extern int  nv04_mc_init(struct drm_device *);
+extern void nv04_mc_takedown(struct drm_device *);
+
+/* nv40_mc.c */
+extern int  nv40_mc_init(struct drm_device *);
+extern void nv40_mc_takedown(struct drm_device *);
+
+/* nv50_mc.c */
+extern int  nv50_mc_init(struct drm_device *);
+extern void nv50_mc_takedown(struct drm_device *);
+
+/* nv04_timer.c */
+extern int  nv04_timer_init(struct drm_device *);
+extern uint64_t nv04_timer_read(struct drm_device *);
+extern void nv04_timer_takedown(struct drm_device *);
+
+extern long nouveau_compat_ioctl(struct file *file, unsigned int cmd,
+				 unsigned long arg);
+
+/* nv04_dac.c */
+extern int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry);
+extern enum drm_connector_status nv17_dac_detect(struct drm_encoder *encoder,
+						 struct drm_connector *connector);
+extern int nv04_dac_output_offset(struct drm_encoder *encoder);
+extern void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable);
+
+/* nv04_dfp.c */
+extern int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry);
+extern int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_entry *dcbent);
+extern void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_entry *dcbent,
+			       int head, bool dl);
+extern void nv04_dfp_disable(struct drm_device *dev, int head);
+extern void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode);
+
+/* nv04_tv.c */
+extern int nv04_tv_identify(struct drm_device *dev, int i2c_index);
+extern int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry);
+
+/* nv17_tv.c */
+extern int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry);
+extern enum drm_connector_status nv17_tv_detect(struct drm_encoder *encoder,
+						struct drm_connector *connector,
+						uint32_t pin_mask);
+
+/* nv04_display.c */
+extern int nv04_display_create(struct drm_device *);
+extern void nv04_display_destroy(struct drm_device *);
+extern void nv04_display_restore(struct drm_device *);
+
+/* nv04_crtc.c */
+extern int nv04_crtc_create(struct drm_device *, int index);
+
+/* nouveau_bo.c */
+extern struct ttm_bo_driver nouveau_bo_driver;
+extern int nouveau_bo_new(struct drm_device *, struct nouveau_channel *,
+			  int size, int align, uint32_t flags,
+			  uint32_t tile_mode, uint32_t tile_flags,
+			  bool no_vm, bool mappable, struct nouveau_bo **);
+extern int nouveau_bo_pin(struct nouveau_bo *, uint32_t flags);
+extern int nouveau_bo_unpin(struct nouveau_bo *);
+extern int nouveau_bo_map(struct nouveau_bo *);
+extern void nouveau_bo_unmap(struct nouveau_bo *);
+extern void nouveau_bo_placement_set(struct nouveau_bo *, uint32_t memtype);
+extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index);
+extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val);
+extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index);
+extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val);
+
+/* nouveau_fence.c */
+struct nouveau_fence;
+extern int nouveau_fence_init(struct nouveau_channel *);
+extern void nouveau_fence_fini(struct nouveau_channel *);
+extern void nouveau_fence_update(struct nouveau_channel *);
+extern int nouveau_fence_new(struct nouveau_channel *, struct nouveau_fence **,
+			     bool emit);
+extern int nouveau_fence_emit(struct nouveau_fence *);
+struct nouveau_channel *nouveau_fence_channel(struct nouveau_fence *);
+extern bool nouveau_fence_signalled(void *obj, void *arg);
+extern int nouveau_fence_wait(void *obj, void *arg, bool lazy, bool intr);
+extern int nouveau_fence_flush(void *obj, void *arg);
+extern void nouveau_fence_unref(void **obj);
+extern void *nouveau_fence_ref(void *obj);
+extern void nouveau_fence_handler(struct drm_device *dev, int channel);
+
+/* nouveau_gem.c */
+extern int nouveau_gem_new(struct drm_device *, struct nouveau_channel *,
+			   int size, int align, uint32_t flags,
+			   uint32_t tile_mode, uint32_t tile_flags,
+			   bool no_vm, bool mappable, struct nouveau_bo **);
+extern int nouveau_gem_object_new(struct drm_gem_object *);
+extern void nouveau_gem_object_del(struct drm_gem_object *);
+extern int nouveau_gem_ioctl_new(struct drm_device *, void *,
+				 struct drm_file *);
+extern int nouveau_gem_ioctl_pushbuf(struct drm_device *, void *,
+				     struct drm_file *);
+extern int nouveau_gem_ioctl_pushbuf_call(struct drm_device *, void *,
+					  struct drm_file *);
+extern int nouveau_gem_ioctl_pushbuf_call2(struct drm_device *, void *,
+					   struct drm_file *);
+extern int nouveau_gem_ioctl_pin(struct drm_device *, void *,
+				 struct drm_file *);
+extern int nouveau_gem_ioctl_unpin(struct drm_device *, void *,
+				   struct drm_file *);
+extern int nouveau_gem_ioctl_tile(struct drm_device *, void *,
+				  struct drm_file *);
+extern int nouveau_gem_ioctl_cpu_prep(struct drm_device *, void *,
+				      struct drm_file *);
+extern int nouveau_gem_ioctl_cpu_fini(struct drm_device *, void *,
+				      struct drm_file *);
+extern int nouveau_gem_ioctl_info(struct drm_device *, void *,
+				  struct drm_file *);
+
+/* nv17_gpio.c */
+int nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
+int nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);
+
+#ifndef ioread32_native
+#ifdef __BIG_ENDIAN
+#define ioread16_native ioread16be
+#define iowrite16_native iowrite16be
+#define ioread32_native  ioread32be
+#define iowrite32_native iowrite32be
+#else /* def __BIG_ENDIAN */
+#define ioread16_native ioread16
+#define iowrite16_native iowrite16
+#define ioread32_native  ioread32
+#define iowrite32_native iowrite32
+#endif /* def __BIG_ENDIAN else */
+#endif /* !ioread32_native */
+
+/* channel control reg access */
+static inline u32 nvchan_rd32(struct nouveau_channel *chan, unsigned reg)
+{
+	return ioread32_native(chan->user + reg);
+}
+
+static inline void nvchan_wr32(struct nouveau_channel *chan,
+							unsigned reg, u32 val)
+{
+	iowrite32_native(val, chan->user + reg);
+}
+
+/* register access */
+static inline u32 nv_rd32(struct drm_device *dev, unsigned reg)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	return ioread32_native(dev_priv->mmio + reg);
+}
+
+static inline void nv_wr32(struct drm_device *dev, unsigned reg, u32 val)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	iowrite32_native(val, dev_priv->mmio + reg);
+}
+
+static inline u8 nv_rd08(struct drm_device *dev, unsigned reg)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	return ioread8(dev_priv->mmio + reg);
+}
+
+static inline void nv_wr08(struct drm_device *dev, unsigned reg, u8 val)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	iowrite8(val, dev_priv->mmio + reg);
+}
+
+#define nv_wait(reg, mask, val) \
+	nouveau_wait_until(dev, 2000000000ULL, (reg), (mask), (val))
+
+/* PRAMIN access */
+static inline u32 nv_ri32(struct drm_device *dev, unsigned offset)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	return ioread32_native(dev_priv->ramin + offset);
+}
+
+static inline void nv_wi32(struct drm_device *dev, unsigned offset, u32 val)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	iowrite32_native(val, dev_priv->ramin + offset);
+}
+
+/* object access */
+static inline u32 nv_ro32(struct drm_device *dev, struct nouveau_gpuobj *obj,
+				unsigned index)
+{
+	return nv_ri32(dev, obj->im_pramin->start + index * 4);
+}
+
+static inline void nv_wo32(struct drm_device *dev, struct nouveau_gpuobj *obj,
+				unsigned index, u32 val)
+{
+	nv_wi32(dev, obj->im_pramin->start + index * 4, val);
+}
+
+/*
+ * Logging
+ * Argument d is (struct drm_device *).
+ */
+#define NV_PRINTK(level, d, fmt, arg...) \
+	printk(level "[" DRM_NAME "] " DRIVER_NAME " %s: " fmt, \
+					pci_name(d->pdev), ##arg)
+#ifndef NV_DEBUG_NOTRACE
+#define NV_DEBUG(d, fmt, arg...) do {                                          \
+	if (drm_debug) {                                                       \
+		NV_PRINTK(KERN_DEBUG, d, "%s:%d - " fmt, __func__,             \
+			  __LINE__, ##arg);                                    \
+	}                                                                      \
+} while (0)
+#else
+#define NV_DEBUG(d, fmt, arg...) do {                                          \
+	if (drm_debug)                                                         \
+		NV_PRINTK(KERN_DEBUG, d, fmt, ##arg);                          \
+} while (0)
+#endif
+#define NV_ERROR(d, fmt, arg...) NV_PRINTK(KERN_ERR, d, fmt, ##arg)
+#define NV_INFO(d, fmt, arg...) NV_PRINTK(KERN_INFO, d, fmt, ##arg)
+#define NV_TRACEWARN(d, fmt, arg...) NV_PRINTK(KERN_NOTICE, d, fmt, ##arg)
+#define NV_TRACE(d, fmt, arg...) NV_PRINTK(KERN_INFO, d, fmt, ##arg)
+#define NV_WARN(d, fmt, arg...) NV_PRINTK(KERN_WARNING, d, fmt, ##arg)
+
+/* nouveau_reg_debug bitmask */
+enum {
+	NOUVEAU_REG_DEBUG_MC             = 0x1,
+	NOUVEAU_REG_DEBUG_VIDEO          = 0x2,
+	NOUVEAU_REG_DEBUG_FB             = 0x4,
+	NOUVEAU_REG_DEBUG_EXTDEV         = 0x8,
+	NOUVEAU_REG_DEBUG_CRTC           = 0x10,
+	NOUVEAU_REG_DEBUG_RAMDAC         = 0x20,
+	NOUVEAU_REG_DEBUG_VGACRTC        = 0x40,
+	NOUVEAU_REG_DEBUG_RMVIO          = 0x80,
+	NOUVEAU_REG_DEBUG_VGAATTR        = 0x100,
+	NOUVEAU_REG_DEBUG_EVO            = 0x200,
+};
+
+#define NV_REG_DEBUG(type, dev, fmt, arg...) do { \
+	if (nouveau_reg_debug & NOUVEAU_REG_DEBUG_##type) \
+		NV_PRINTK(KERN_DEBUG, dev, "%s: " fmt, __func__, ##arg); \
+} while (0)
+
+static inline bool
+nv_two_heads(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	const int impl = dev->pci_device & 0x0ff0;
+
+	if (dev_priv->card_type >= NV_10 && impl != 0x0100 &&
+	    impl != 0x0150 && impl != 0x01a0 && impl != 0x0200)
+		return true;
+
+	return false;
+}
+
+static inline bool
+nv_gf4_disp_arch(struct drm_device *dev)
+{
+	return nv_two_heads(dev) && (dev->pci_device & 0x0ff0) != 0x0110;
+}
+
+static inline bool
+nv_two_reg_pll(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	const int impl = dev->pci_device & 0x0ff0;
+
+	if (impl == 0x0310 || impl == 0x0340 || dev_priv->card_type >= NV_40)
+		return true;
+	return false;
+}
+
+#define NV50_NVSW                                                    0x0000506e
+#define NV50_NVSW_DMA_SEMAPHORE                                      0x00000060
+#define NV50_NVSW_SEMAPHORE_OFFSET                                   0x00000064
+#define NV50_NVSW_SEMAPHORE_ACQUIRE                                  0x00000068
+#define NV50_NVSW_SEMAPHORE_RELEASE                                  0x0000006c
+#define NV50_NVSW_DMA_VBLSEM                                         0x0000018c
+#define NV50_NVSW_VBLSEM_OFFSET                                      0x00000400
+#define NV50_NVSW_VBLSEM_RELEASE_VALUE                               0x00000404
+#define NV50_NVSW_VBLSEM_RELEASE                                     0x00000408
+
+#endif /* __NOUVEAU_DRV_H__ */
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h
new file mode 100644
index 0000000..bc4a240
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __NOUVEAU_ENCODER_H__
+#define __NOUVEAU_ENCODER_H__
+
+#include "drm_encoder_slave.h"
+#include "nouveau_drv.h"
+
+#define NV_DPMS_CLEARED 0x80
+
+struct nouveau_encoder {
+	struct drm_encoder_slave base;
+
+	struct dcb_entry *dcb;
+	int or;
+
+	struct drm_display_mode mode;
+	int last_dpms;
+
+	struct nv04_output_reg restore;
+
+	void (*disconnect)(struct nouveau_encoder *encoder);
+
+	union {
+		struct {
+			int dpcd_version;
+			int link_nr;
+			int link_bw;
+		} dp;
+	};
+};
+
+static inline struct nouveau_encoder *nouveau_encoder(struct drm_encoder *enc)
+{
+	struct drm_encoder_slave *slave = to_encoder_slave(enc);
+
+	return container_of(slave, struct nouveau_encoder, base);
+}
+
+static inline struct drm_encoder *to_drm_encoder(struct nouveau_encoder *enc)
+{
+	return &enc->base.base;
+}
+
+struct nouveau_connector *
+nouveau_encoder_connector_get(struct nouveau_encoder *encoder);
+int nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry);
+int nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry);
+
+struct bit_displayport_encoder_table {
+	uint32_t match;
+	uint8_t  record_nr;
+	uint8_t  unknown;
+	uint16_t script0;
+	uint16_t script1;
+	uint16_t unknown_table;
+} __attribute__ ((packed));
+
+struct bit_displayport_encoder_table_entry {
+	uint8_t vs_level;
+	uint8_t pre_level;
+	uint8_t reg0;
+	uint8_t reg1;
+	uint8_t reg2;
+} __attribute__ ((packed));
+
+#endif /* __NOUVEAU_ENCODER_H__ */
diff --git a/drivers/gpu/drm/nouveau/nouveau_fb.h b/drivers/gpu/drm/nouveau/nouveau_fb.h
new file mode 100644
index 0000000..4a3f31a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_fb.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __NOUVEAU_FB_H__
+#define __NOUVEAU_FB_H__
+
+struct nouveau_framebuffer {
+	struct drm_framebuffer base;
+	struct nouveau_bo *nvbo;
+};
+
+static inline struct nouveau_framebuffer *
+nouveau_framebuffer(struct drm_framebuffer *fb)
+{
+	return container_of(fb, struct nouveau_framebuffer, base);
+}
+
+extern const struct drm_mode_config_funcs nouveau_mode_config_funcs;
+
+struct drm_framebuffer *
+nouveau_framebuffer_create(struct drm_device *, struct nouveau_bo *,
+			   struct drm_mode_fb_cmd *);
+
+#endif /* __NOUVEAU_FB_H__ */
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
new file mode 100644
index 0000000..36e8c5e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -0,0 +1,380 @@
+/*
+ * Copyright © 2007 David Airlie
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *     David Airlie
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/sysrq.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/screen_info.h>
+
+#include "drmP.h"
+#include "drm.h"
+#include "drm_crtc.h"
+#include "drm_crtc_helper.h"
+#include "drm_fb_helper.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+#include "nouveau_crtc.h"
+#include "nouveau_fb.h"
+#include "nouveau_fbcon.h"
+#include "nouveau_dma.h"
+
+static int
+nouveau_fbcon_sync(struct fb_info *info)
+{
+	struct nouveau_fbcon_par *par = info->par;
+	struct drm_device *dev = par->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = dev_priv->channel;
+	int ret, i;
+
+	if (!chan->accel_done ||
+	    info->state != FBINFO_STATE_RUNNING ||
+	    info->flags & FBINFO_HWACCEL_DISABLED)
+		return 0;
+
+	if (RING_SPACE(chan, 4)) {
+		NV_ERROR(dev, "GPU lockup - switching to software fbcon\n");
+		info->flags |= FBINFO_HWACCEL_DISABLED;
+		return 0;
+	}
+
+	BEGIN_RING(chan, 0, 0x0104, 1);
+	OUT_RING(chan, 0);
+	BEGIN_RING(chan, 0, 0x0100, 1);
+	OUT_RING(chan, 0);
+	nouveau_bo_wr32(chan->notifier_bo, chan->m2mf_ntfy + 3, 0xffffffff);
+	FIRE_RING(chan);
+
+	ret = -EBUSY;
+	for (i = 0; i < 100000; i++) {
+		if (!nouveau_bo_rd32(chan->notifier_bo, chan->m2mf_ntfy + 3)) {
+			ret = 0;
+			break;
+		}
+		DRM_UDELAY(1);
+	}
+
+	if (ret) {
+		NV_ERROR(dev, "GPU lockup - switching to software fbcon\n");
+		info->flags |= FBINFO_HWACCEL_DISABLED;
+		return 0;
+	}
+
+	chan->accel_done = false;
+	return 0;
+}
+
+static struct fb_ops nouveau_fbcon_ops = {
+	.owner = THIS_MODULE,
+	.fb_check_var = drm_fb_helper_check_var,
+	.fb_set_par = drm_fb_helper_set_par,
+	.fb_setcolreg = drm_fb_helper_setcolreg,
+	.fb_fillrect = cfb_fillrect,
+	.fb_copyarea = cfb_copyarea,
+	.fb_imageblit = cfb_imageblit,
+	.fb_sync = nouveau_fbcon_sync,
+	.fb_pan_display = drm_fb_helper_pan_display,
+	.fb_blank = drm_fb_helper_blank,
+	.fb_setcmap = drm_fb_helper_setcmap,
+};
+
+static void nouveau_fbcon_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
+				    u16 blue, int regno)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+
+	nv_crtc->lut.r[regno] = red;
+	nv_crtc->lut.g[regno] = green;
+	nv_crtc->lut.b[regno] = blue;
+}
+
+static void nouveau_fbcon_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
+				    u16 *blue, int regno)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+
+	*red = nv_crtc->lut.r[regno];
+	*green = nv_crtc->lut.g[regno];
+	*blue = nv_crtc->lut.b[regno];
+}
+
+static struct drm_fb_helper_funcs nouveau_fbcon_helper_funcs = {
+	.gamma_set = nouveau_fbcon_gamma_set,
+	.gamma_get = nouveau_fbcon_gamma_get
+};
+
+#if defined(__i386__) || defined(__x86_64__)
+static bool
+nouveau_fbcon_has_vesafb_or_efifb(struct drm_device *dev)
+{
+	struct pci_dev *pdev = dev->pdev;
+	int ramin;
+
+	if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB &&
+	    screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
+		return false;
+
+	if (screen_info.lfb_base < pci_resource_start(pdev, 1))
+		goto not_fb;
+
+	if (screen_info.lfb_base + screen_info.lfb_size >=
+	    pci_resource_start(pdev, 1) + pci_resource_len(pdev, 1))
+		goto not_fb;
+
+	return true;
+not_fb:
+	ramin = 2;
+	if (pci_resource_len(pdev, ramin) == 0) {
+		ramin = 3;
+		if (pci_resource_len(pdev, ramin) == 0)
+			return false;
+	}
+
+	if (screen_info.lfb_base < pci_resource_start(pdev, ramin))
+		return false;
+
+	if (screen_info.lfb_base + screen_info.lfb_size >=
+	    pci_resource_start(pdev, ramin) + pci_resource_len(pdev, ramin))
+		return false;
+
+	return true;
+}
+#endif
+
+void
+nouveau_fbcon_zfill(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct fb_info *info = dev_priv->fbdev_info;
+	struct fb_fillrect rect;
+
+	/* Clear the entire fbcon.  The drm will program every connector
+	 * with it's preferred mode.  If the sizes differ, one display will
+	 * quite likely have garbage around the console.
+	 */
+	rect.dx = rect.dy = 0;
+	rect.width = info->var.xres_virtual;
+	rect.height = info->var.yres_virtual;
+	rect.color = 0;
+	rect.rop = ROP_COPY;
+	info->fbops->fb_fillrect(info, &rect);
+}
+
+static int
+nouveau_fbcon_create(struct drm_device *dev, uint32_t fb_width,
+		     uint32_t fb_height, uint32_t surface_width,
+		     uint32_t surface_height, uint32_t surface_depth,
+		     uint32_t surface_bpp, struct drm_framebuffer **pfb)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct fb_info *info;
+	struct nouveau_fbcon_par *par;
+	struct drm_framebuffer *fb;
+	struct nouveau_framebuffer *nouveau_fb;
+	struct nouveau_bo *nvbo;
+	struct drm_mode_fb_cmd mode_cmd;
+	struct device *device = &dev->pdev->dev;
+	int size, ret;
+
+	mode_cmd.width = surface_width;
+	mode_cmd.height = surface_height;
+
+	mode_cmd.bpp = surface_bpp;
+	mode_cmd.pitch = mode_cmd.width * (mode_cmd.bpp >> 3);
+	mode_cmd.pitch = ALIGN(mode_cmd.pitch, 256);
+	mode_cmd.depth = surface_depth;
+
+	size = mode_cmd.pitch * mode_cmd.height;
+	size = ALIGN(size, PAGE_SIZE);
+
+	ret = nouveau_gem_new(dev, dev_priv->channel, size, 0, TTM_PL_FLAG_VRAM,
+			      0, 0x0000, false, true, &nvbo);
+	if (ret) {
+		NV_ERROR(dev, "failed to allocate framebuffer\n");
+		goto out;
+	}
+
+	ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM);
+	if (ret) {
+		NV_ERROR(dev, "failed to pin fb: %d\n", ret);
+		nouveau_bo_ref(NULL, &nvbo);
+		goto out;
+	}
+
+	ret = nouveau_bo_map(nvbo);
+	if (ret) {
+		NV_ERROR(dev, "failed to map fb: %d\n", ret);
+		nouveau_bo_unpin(nvbo);
+		nouveau_bo_ref(NULL, &nvbo);
+		goto out;
+	}
+
+	mutex_lock(&dev->struct_mutex);
+
+	fb = nouveau_framebuffer_create(dev, nvbo, &mode_cmd);
+	if (!fb) {
+		ret = -ENOMEM;
+		NV_ERROR(dev, "failed to allocate fb.\n");
+		goto out_unref;
+	}
+
+	list_add(&fb->filp_head, &dev->mode_config.fb_kernel_list);
+
+	nouveau_fb = nouveau_framebuffer(fb);
+	*pfb = fb;
+
+	info = framebuffer_alloc(sizeof(struct nouveau_fbcon_par), device);
+	if (!info) {
+		ret = -ENOMEM;
+		goto out_unref;
+	}
+
+	par = info->par;
+	par->helper.funcs = &nouveau_fbcon_helper_funcs;
+	par->helper.dev = dev;
+	ret = drm_fb_helper_init_crtc_count(&par->helper, 2, 4);
+	if (ret)
+		goto out_unref;
+	dev_priv->fbdev_info = info;
+
+	strcpy(info->fix.id, "nouveaufb");
+	info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA |
+		      FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_IMAGEBLIT;
+	info->fbops = &nouveau_fbcon_ops;
+	info->fix.smem_start = dev->mode_config.fb_base + nvbo->bo.offset -
+			       dev_priv->vm_vram_base;
+	info->fix.smem_len = size;
+
+	info->screen_base = nvbo_kmap_obj_iovirtual(nouveau_fb->nvbo);
+	info->screen_size = size;
+
+	drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
+	drm_fb_helper_fill_var(info, fb, fb_width, fb_height);
+
+	/* FIXME: we really shouldn't expose mmio space at all */
+	info->fix.mmio_start = pci_resource_start(dev->pdev, 1);
+	info->fix.mmio_len = pci_resource_len(dev->pdev, 1);
+
+	/* Set aperture base/size for vesafb takeover */
+#if defined(__i386__) || defined(__x86_64__)
+	if (nouveau_fbcon_has_vesafb_or_efifb(dev)) {
+		/* Some NVIDIA VBIOS' are stupid and decide to put the
+		 * framebuffer in the middle of the PRAMIN BAR for
+		 * whatever reason.  We need to know the exact lfb_base
+		 * to get vesafb kicked off, and the only reliable way
+		 * we have left is to find out lfb_base the same way
+		 * vesafb did.
+		 */
+		info->aperture_base = screen_info.lfb_base;
+		info->aperture_size = screen_info.lfb_size;
+		if (screen_info.orig_video_isVGA == VIDEO_TYPE_VLFB)
+			info->aperture_size *= 65536;
+	} else
+#endif
+	{
+		info->aperture_base = info->fix.mmio_start;
+		info->aperture_size = info->fix.mmio_len;
+	}
+
+	info->pixmap.size = 64*1024;
+	info->pixmap.buf_align = 8;
+	info->pixmap.access_align = 32;
+	info->pixmap.flags = FB_PIXMAP_SYSTEM;
+	info->pixmap.scan_align = 1;
+
+	fb->fbdev = info;
+
+	par->nouveau_fb = nouveau_fb;
+	par->dev = dev;
+
+	switch (dev_priv->card_type) {
+	case NV_50:
+		nv50_fbcon_accel_init(info);
+		break;
+	default:
+		nv04_fbcon_accel_init(info);
+		break;
+	};
+
+	nouveau_fbcon_zfill(dev);
+
+	/* To allow resizeing without swapping buffers */
+	NV_INFO(dev, "allocated %dx%d fb: 0x%lx, bo %p\n",
+						nouveau_fb->base.width,
+						nouveau_fb->base.height,
+						nvbo->bo.offset, nvbo);
+
+	mutex_unlock(&dev->struct_mutex);
+	return 0;
+
+out_unref:
+	mutex_unlock(&dev->struct_mutex);
+out:
+	return ret;
+}
+
+int
+nouveau_fbcon_probe(struct drm_device *dev)
+{
+	NV_DEBUG(dev, "\n");
+
+	return drm_fb_helper_single_fb_probe(dev, 32, nouveau_fbcon_create);
+}
+
+int
+nouveau_fbcon_remove(struct drm_device *dev, struct drm_framebuffer *fb)
+{
+	struct nouveau_framebuffer *nouveau_fb = nouveau_framebuffer(fb);
+	struct fb_info *info;
+
+	if (!fb)
+		return -EINVAL;
+
+	info = fb->fbdev;
+	if (info) {
+		struct nouveau_fbcon_par *par = info->par;
+
+		unregister_framebuffer(info);
+		nouveau_bo_unmap(nouveau_fb->nvbo);
+		mutex_lock(&dev->struct_mutex);
+		drm_gem_object_unreference(nouveau_fb->nvbo->gem);
+		nouveau_fb->nvbo = NULL;
+		mutex_unlock(&dev->struct_mutex);
+		if (par)
+			drm_fb_helper_free(&par->helper);
+		framebuffer_release(info);
+	}
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/drivers/gpu/drm/nouveau/nouveau_fbcon.h
new file mode 100644
index 0000000..8531140
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __NOUVEAU_FBCON_H__
+#define __NOUVEAU_FBCON_H__
+
+#include "drm_fb_helper.h"
+
+struct nouveau_fbcon_par {
+	struct drm_fb_helper helper;
+	struct drm_device *dev;
+	struct nouveau_framebuffer *nouveau_fb;
+};
+
+int nouveau_fbcon_probe(struct drm_device *dev);
+int nouveau_fbcon_remove(struct drm_device *dev, struct drm_framebuffer *fb);
+void nouveau_fbcon_restore(void);
+void nouveau_fbcon_zfill(struct drm_device *dev);
+
+int nv04_fbcon_accel_init(struct fb_info *info);
+int nv50_fbcon_accel_init(struct fb_info *info);
+
+#endif /* __NV50_FBCON_H__ */
+
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
new file mode 100644
index 0000000..0cff7eb
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+
+#include "nouveau_drv.h"
+#include "nouveau_dma.h"
+
+#define USE_REFCNT (dev_priv->card_type >= NV_10)
+
+struct nouveau_fence {
+	struct nouveau_channel *channel;
+	struct kref refcount;
+	struct list_head entry;
+
+	uint32_t sequence;
+	bool signalled;
+};
+
+static inline struct nouveau_fence *
+nouveau_fence(void *sync_obj)
+{
+	return (struct nouveau_fence *)sync_obj;
+}
+
+static void
+nouveau_fence_del(struct kref *ref)
+{
+	struct nouveau_fence *fence =
+		container_of(ref, struct nouveau_fence, refcount);
+
+	kfree(fence);
+}
+
+void
+nouveau_fence_update(struct nouveau_channel *chan)
+{
+	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
+	struct list_head *entry, *tmp;
+	struct nouveau_fence *fence;
+	uint32_t sequence;
+
+	if (USE_REFCNT)
+		sequence = nvchan_rd32(chan, 0x48);
+	else
+		sequence = chan->fence.last_sequence_irq;
+
+	if (chan->fence.sequence_ack == sequence)
+		return;
+	chan->fence.sequence_ack = sequence;
+
+	list_for_each_safe(entry, tmp, &chan->fence.pending) {
+		fence = list_entry(entry, struct nouveau_fence, entry);
+
+		sequence = fence->sequence;
+		fence->signalled = true;
+		list_del(&fence->entry);
+		kref_put(&fence->refcount, nouveau_fence_del);
+
+		if (sequence == chan->fence.sequence_ack)
+			break;
+	}
+}
+
+int
+nouveau_fence_new(struct nouveau_channel *chan, struct nouveau_fence **pfence,
+		  bool emit)
+{
+	struct nouveau_fence *fence;
+	int ret = 0;
+
+	fence = kzalloc(sizeof(*fence), GFP_KERNEL);
+	if (!fence)
+		return -ENOMEM;
+	kref_init(&fence->refcount);
+	fence->channel = chan;
+
+	if (emit)
+		ret = nouveau_fence_emit(fence);
+
+	if (ret)
+		nouveau_fence_unref((void *)&fence);
+	*pfence = fence;
+	return ret;
+}
+
+struct nouveau_channel *
+nouveau_fence_channel(struct nouveau_fence *fence)
+{
+	return fence ? fence->channel : NULL;
+}
+
+int
+nouveau_fence_emit(struct nouveau_fence *fence)
+{
+	struct drm_nouveau_private *dev_priv = fence->channel->dev->dev_private;
+	struct nouveau_channel *chan = fence->channel;
+	unsigned long flags;
+	int ret;
+
+	ret = RING_SPACE(chan, 2);
+	if (ret)
+		return ret;
+
+	if (unlikely(chan->fence.sequence == chan->fence.sequence_ack - 1)) {
+		spin_lock_irqsave(&chan->fence.lock, flags);
+		nouveau_fence_update(chan);
+		spin_unlock_irqrestore(&chan->fence.lock, flags);
+
+		BUG_ON(chan->fence.sequence ==
+		       chan->fence.sequence_ack - 1);
+	}
+
+	fence->sequence = ++chan->fence.sequence;
+
+	kref_get(&fence->refcount);
+	spin_lock_irqsave(&chan->fence.lock, flags);
+	list_add_tail(&fence->entry, &chan->fence.pending);
+	spin_unlock_irqrestore(&chan->fence.lock, flags);
+
+	BEGIN_RING(chan, NvSubM2MF, USE_REFCNT ? 0x0050 : 0x0150, 1);
+	OUT_RING(chan, fence->sequence);
+	FIRE_RING(chan);
+
+	return 0;
+}
+
+void
+nouveau_fence_unref(void **sync_obj)
+{
+	struct nouveau_fence *fence = nouveau_fence(*sync_obj);
+
+	if (fence)
+		kref_put(&fence->refcount, nouveau_fence_del);
+	*sync_obj = NULL;
+}
+
+void *
+nouveau_fence_ref(void *sync_obj)
+{
+	struct nouveau_fence *fence = nouveau_fence(sync_obj);
+
+	kref_get(&fence->refcount);
+	return sync_obj;
+}
+
+bool
+nouveau_fence_signalled(void *sync_obj, void *sync_arg)
+{
+	struct nouveau_fence *fence = nouveau_fence(sync_obj);
+	struct nouveau_channel *chan = fence->channel;
+	unsigned long flags;
+
+	if (fence->signalled)
+		return true;
+
+	spin_lock_irqsave(&chan->fence.lock, flags);
+	nouveau_fence_update(chan);
+	spin_unlock_irqrestore(&chan->fence.lock, flags);
+	return fence->signalled;
+}
+
+int
+nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr)
+{
+	unsigned long timeout = jiffies + (3 * DRM_HZ);
+	int ret = 0;
+
+	__set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
+
+	while (1) {
+		if (nouveau_fence_signalled(sync_obj, sync_arg))
+			break;
+
+		if (time_after_eq(jiffies, timeout)) {
+			ret = -EBUSY;
+			break;
+		}
+
+		if (lazy)
+			schedule_timeout(1);
+
+		if (intr && signal_pending(current)) {
+			ret = -ERESTART;
+			break;
+		}
+	}
+
+	__set_current_state(TASK_RUNNING);
+
+	return ret;
+}
+
+int
+nouveau_fence_flush(void *sync_obj, void *sync_arg)
+{
+	return 0;
+}
+
+void
+nouveau_fence_handler(struct drm_device *dev, int channel)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = NULL;
+
+	if (channel >= 0 && channel < dev_priv->engine.fifo.channels)
+		chan = dev_priv->fifos[channel];
+
+	if (chan) {
+		spin_lock_irq(&chan->fence.lock);
+		nouveau_fence_update(chan);
+		spin_unlock_irq(&chan->fence.lock);
+	}
+}
+
+int
+nouveau_fence_init(struct nouveau_channel *chan)
+{
+	INIT_LIST_HEAD(&chan->fence.pending);
+	spin_lock_init(&chan->fence.lock);
+	return 0;
+}
+
+void
+nouveau_fence_fini(struct nouveau_channel *chan)
+{
+	struct list_head *entry, *tmp;
+	struct nouveau_fence *fence;
+
+	list_for_each_safe(entry, tmp, &chan->fence.pending) {
+		fence = list_entry(entry, struct nouveau_fence, entry);
+
+		fence->signalled = true;
+		list_del(&fence->entry);
+		kref_put(&fence->refcount, nouveau_fence_del);
+	}
+}
+
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
new file mode 100644
index 0000000..11f831f
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -0,0 +1,992 @@
+/*
+ * Copyright (C) 2008 Ben Skeggs.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include "drmP.h"
+#include "drm.h"
+
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+#include "nouveau_dma.h"
+
+#define nouveau_gem_pushbuf_sync(chan) 0
+
+int
+nouveau_gem_object_new(struct drm_gem_object *gem)
+{
+	return 0;
+}
+
+void
+nouveau_gem_object_del(struct drm_gem_object *gem)
+{
+	struct nouveau_bo *nvbo = gem->driver_private;
+	struct ttm_buffer_object *bo = &nvbo->bo;
+
+	if (!nvbo)
+		return;
+	nvbo->gem = NULL;
+
+	if (unlikely(nvbo->cpu_filp))
+		ttm_bo_synccpu_write_release(bo);
+
+	if (unlikely(nvbo->pin_refcnt)) {
+		nvbo->pin_refcnt = 1;
+		nouveau_bo_unpin(nvbo);
+	}
+
+	ttm_bo_unref(&bo);
+}
+
+int
+nouveau_gem_new(struct drm_device *dev, struct nouveau_channel *chan,
+		int size, int align, uint32_t flags, uint32_t tile_mode,
+		uint32_t tile_flags, bool no_vm, bool mappable,
+		struct nouveau_bo **pnvbo)
+{
+	struct nouveau_bo *nvbo;
+	int ret;
+
+	ret = nouveau_bo_new(dev, chan, size, align, flags, tile_mode,
+			     tile_flags, no_vm, mappable, pnvbo);
+	if (ret)
+		return ret;
+	nvbo = *pnvbo;
+
+	nvbo->gem = drm_gem_object_alloc(dev, nvbo->bo.mem.size);
+	if (!nvbo->gem) {
+		nouveau_bo_ref(NULL, pnvbo);
+		return -ENOMEM;
+	}
+
+	nvbo->bo.persistant_swap_storage = nvbo->gem->filp;
+	nvbo->gem->driver_private = nvbo;
+	return 0;
+}
+
+static int
+nouveau_gem_info(struct drm_gem_object *gem, struct drm_nouveau_gem_info *rep)
+{
+	struct nouveau_bo *nvbo = nouveau_gem_object(gem);
+
+	if (nvbo->bo.mem.mem_type == TTM_PL_TT)
+		rep->domain = NOUVEAU_GEM_DOMAIN_GART;
+	else
+		rep->domain = NOUVEAU_GEM_DOMAIN_VRAM;
+
+	rep->size = nvbo->bo.mem.num_pages << PAGE_SHIFT;
+	rep->offset = nvbo->bo.offset;
+	rep->map_handle = nvbo->mappable ? nvbo->bo.addr_space_offset : 0;
+	rep->tile_mode = nvbo->tile_mode;
+	rep->tile_flags = nvbo->tile_flags;
+	return 0;
+}
+
+static bool
+nouveau_gem_tile_flags_valid(struct drm_device *dev, uint32_t tile_flags) {
+	switch (tile_flags) {
+	case 0x0000:
+	case 0x1800:
+	case 0x2800:
+	case 0x4800:
+	case 0x7000:
+	case 0x7400:
+	case 0x7a00:
+	case 0xe000:
+		break;
+	default:
+		NV_ERROR(dev, "bad page flags: 0x%08x\n", tile_flags);
+		return false;
+	}
+
+	return true;
+}
+
+int
+nouveau_gem_ioctl_new(struct drm_device *dev, void *data,
+		      struct drm_file *file_priv)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_nouveau_gem_new *req = data;
+	struct nouveau_bo *nvbo = NULL;
+	struct nouveau_channel *chan = NULL;
+	uint32_t flags = 0;
+	int ret = 0;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
+	if (unlikely(dev_priv->ttm.bdev.dev_mapping == NULL))
+		dev_priv->ttm.bdev.dev_mapping = dev_priv->dev->dev_mapping;
+
+	if (req->channel_hint) {
+		NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel_hint,
+						     file_priv, chan);
+	}
+
+	if (req->info.domain & NOUVEAU_GEM_DOMAIN_VRAM)
+		flags |= TTM_PL_FLAG_VRAM;
+	if (req->info.domain & NOUVEAU_GEM_DOMAIN_GART)
+		flags |= TTM_PL_FLAG_TT;
+	if (!flags || req->info.domain & NOUVEAU_GEM_DOMAIN_CPU)
+		flags |= TTM_PL_FLAG_SYSTEM;
+
+	if (!nouveau_gem_tile_flags_valid(dev, req->info.tile_flags))
+		return -EINVAL;
+
+	ret = nouveau_gem_new(dev, chan, req->info.size, req->align, flags,
+			      req->info.tile_mode, req->info.tile_flags, false,
+			      (req->info.domain & NOUVEAU_GEM_DOMAIN_MAPPABLE),
+			      &nvbo);
+	if (ret)
+		return ret;
+
+	ret = nouveau_gem_info(nvbo->gem, &req->info);
+	if (ret)
+		goto out;
+
+	ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle);
+out:
+	mutex_lock(&dev->struct_mutex);
+	drm_gem_object_handle_unreference(nvbo->gem);
+	mutex_unlock(&dev->struct_mutex);
+
+	if (ret)
+		drm_gem_object_unreference(nvbo->gem);
+	return ret;
+}
+
+static int
+nouveau_gem_set_domain(struct drm_gem_object *gem, uint32_t read_domains,
+		       uint32_t write_domains, uint32_t valid_domains)
+{
+	struct nouveau_bo *nvbo = gem->driver_private;
+	struct ttm_buffer_object *bo = &nvbo->bo;
+	uint64_t flags;
+
+	if (!valid_domains || (!read_domains && !write_domains))
+		return -EINVAL;
+
+	if (write_domains) {
+		if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
+		    (write_domains & NOUVEAU_GEM_DOMAIN_VRAM))
+			flags = TTM_PL_FLAG_VRAM;
+		else
+		if ((valid_domains & NOUVEAU_GEM_DOMAIN_GART) &&
+		    (write_domains & NOUVEAU_GEM_DOMAIN_GART))
+			flags = TTM_PL_FLAG_TT;
+		else
+			return -EINVAL;
+	} else {
+		if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
+		    (read_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
+		    bo->mem.mem_type == TTM_PL_VRAM)
+			flags = TTM_PL_FLAG_VRAM;
+		else
+		if ((valid_domains & NOUVEAU_GEM_DOMAIN_GART) &&
+		    (read_domains & NOUVEAU_GEM_DOMAIN_GART) &&
+		    bo->mem.mem_type == TTM_PL_TT)
+			flags = TTM_PL_FLAG_TT;
+		else
+		if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
+		    (read_domains & NOUVEAU_GEM_DOMAIN_VRAM))
+			flags = TTM_PL_FLAG_VRAM;
+		else
+			flags = TTM_PL_FLAG_TT;
+	}
+
+	nouveau_bo_placement_set(nvbo, flags);
+	return 0;
+}
+
+struct validate_op {
+	struct nouveau_fence *fence;
+	struct list_head vram_list;
+	struct list_head gart_list;
+	struct list_head both_list;
+};
+
+static void
+validate_fini_list(struct list_head *list, struct nouveau_fence *fence)
+{
+	struct list_head *entry, *tmp;
+	struct nouveau_bo *nvbo;
+
+	list_for_each_safe(entry, tmp, list) {
+		nvbo = list_entry(entry, struct nouveau_bo, entry);
+		if (likely(fence)) {
+			struct nouveau_fence *prev_fence;
+
+			spin_lock(&nvbo->bo.lock);
+			prev_fence = nvbo->bo.sync_obj;
+			nvbo->bo.sync_obj = nouveau_fence_ref(fence);
+			spin_unlock(&nvbo->bo.lock);
+			nouveau_fence_unref((void *)&prev_fence);
+		}
+
+		list_del(&nvbo->entry);
+		nvbo->reserved_by = NULL;
+		ttm_bo_unreserve(&nvbo->bo);
+		drm_gem_object_unreference(nvbo->gem);
+	}
+}
+
+static void
+validate_fini(struct validate_op *op, bool success)
+{
+	struct nouveau_fence *fence = op->fence;
+
+	if (unlikely(!success))
+		op->fence = NULL;
+
+	validate_fini_list(&op->vram_list, op->fence);
+	validate_fini_list(&op->gart_list, op->fence);
+	validate_fini_list(&op->both_list, op->fence);
+	nouveau_fence_unref((void *)&fence);
+}
+
+static int
+validate_init(struct nouveau_channel *chan, struct drm_file *file_priv,
+	      struct drm_nouveau_gem_pushbuf_bo *pbbo,
+	      int nr_buffers, struct validate_op *op)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t sequence;
+	int trycnt = 0;
+	int ret, i;
+
+	sequence = atomic_add_return(1, &dev_priv->ttm.validate_sequence);
+retry:
+	if (++trycnt > 100000) {
+		NV_ERROR(dev, "%s failed and gave up.\n", __func__);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < nr_buffers; i++) {
+		struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[i];
+		struct drm_gem_object *gem;
+		struct nouveau_bo *nvbo;
+
+		gem = drm_gem_object_lookup(dev, file_priv, b->handle);
+		if (!gem) {
+			NV_ERROR(dev, "Unknown handle 0x%08x\n", b->handle);
+			validate_fini(op, NULL);
+			return -EINVAL;
+		}
+		nvbo = gem->driver_private;
+
+		if (nvbo->reserved_by && nvbo->reserved_by == file_priv) {
+			NV_ERROR(dev, "multiple instances of buffer %d on "
+				      "validation list\n", b->handle);
+			validate_fini(op, NULL);
+			return -EINVAL;
+		}
+
+		ret = ttm_bo_reserve(&nvbo->bo, false, false, true, sequence);
+		if (ret) {
+			validate_fini(op, NULL);
+			if (ret == -EAGAIN)
+				ret = ttm_bo_wait_unreserved(&nvbo->bo, false);
+			drm_gem_object_unreference(gem);
+			if (ret)
+				return ret;
+			goto retry;
+		}
+
+		nvbo->reserved_by = file_priv;
+		nvbo->pbbo_index = i;
+		if ((b->valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
+		    (b->valid_domains & NOUVEAU_GEM_DOMAIN_GART))
+			list_add_tail(&nvbo->entry, &op->both_list);
+		else
+		if (b->valid_domains & NOUVEAU_GEM_DOMAIN_VRAM)
+			list_add_tail(&nvbo->entry, &op->vram_list);
+		else
+		if (b->valid_domains & NOUVEAU_GEM_DOMAIN_GART)
+			list_add_tail(&nvbo->entry, &op->gart_list);
+		else {
+			NV_ERROR(dev, "invalid valid domains: 0x%08x\n",
+				 b->valid_domains);
+			validate_fini(op, NULL);
+			return -EINVAL;
+		}
+
+		if (unlikely(atomic_read(&nvbo->bo.cpu_writers) > 0)) {
+			validate_fini(op, NULL);
+
+			if (nvbo->cpu_filp == file_priv) {
+				NV_ERROR(dev, "bo %p mapped by process trying "
+					      "to validate it!\n", nvbo);
+				return -EINVAL;
+			}
+
+			ret = ttm_bo_wait_cpu(&nvbo->bo, false);
+			if (ret == -ERESTART)
+				ret = -EAGAIN;
+			if (ret)
+				return ret;
+			goto retry;
+		}
+	}
+
+	return 0;
+}
+
+static int
+validate_list(struct nouveau_channel *chan, struct list_head *list,
+	      struct drm_nouveau_gem_pushbuf_bo *pbbo, uint64_t user_pbbo_ptr)
+{
+	struct drm_nouveau_gem_pushbuf_bo __user *upbbo =
+				(void __force __user *)(uintptr_t)user_pbbo_ptr;
+	struct nouveau_bo *nvbo;
+	int ret, relocs = 0;
+
+	list_for_each_entry(nvbo, list, entry) {
+		struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index];
+		struct nouveau_fence *prev_fence = nvbo->bo.sync_obj;
+
+		if (prev_fence && nouveau_fence_channel(prev_fence) != chan) {
+			spin_lock(&nvbo->bo.lock);
+			ret = ttm_bo_wait(&nvbo->bo, false, false, false);
+			spin_unlock(&nvbo->bo.lock);
+			if (unlikely(ret))
+				return ret;
+		}
+
+		ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains,
+					     b->write_domains,
+					     b->valid_domains);
+		if (unlikely(ret))
+			return ret;
+
+		nvbo->channel = chan;
+		ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement,
+				      false, false);
+		nvbo->channel = NULL;
+		if (unlikely(ret))
+			return ret;
+
+		if (nvbo->bo.offset == b->presumed_offset &&
+		    ((nvbo->bo.mem.mem_type == TTM_PL_VRAM &&
+		      b->presumed_domain & NOUVEAU_GEM_DOMAIN_VRAM) ||
+		     (nvbo->bo.mem.mem_type == TTM_PL_TT &&
+		      b->presumed_domain & NOUVEAU_GEM_DOMAIN_GART)))
+			continue;
+
+		if (nvbo->bo.mem.mem_type == TTM_PL_TT)
+			b->presumed_domain = NOUVEAU_GEM_DOMAIN_GART;
+		else
+			b->presumed_domain = NOUVEAU_GEM_DOMAIN_VRAM;
+		b->presumed_offset = nvbo->bo.offset;
+		b->presumed_ok = 0;
+		relocs++;
+
+		if (DRM_COPY_TO_USER(&upbbo[nvbo->pbbo_index], b, sizeof(*b)))
+			return -EFAULT;
+	}
+
+	return relocs;
+}
+
+static int
+nouveau_gem_pushbuf_validate(struct nouveau_channel *chan,
+			     struct drm_file *file_priv,
+			     struct drm_nouveau_gem_pushbuf_bo *pbbo,
+			     uint64_t user_buffers, int nr_buffers,
+			     struct validate_op *op, int *apply_relocs)
+{
+	int ret, relocs = 0;
+
+	INIT_LIST_HEAD(&op->vram_list);
+	INIT_LIST_HEAD(&op->gart_list);
+	INIT_LIST_HEAD(&op->both_list);
+
+	ret = nouveau_fence_new(chan, &op->fence, false);
+	if (ret)
+		return ret;
+
+	if (nr_buffers == 0)
+		return 0;
+
+	ret = validate_init(chan, file_priv, pbbo, nr_buffers, op);
+	if (unlikely(ret))
+		return ret;
+
+	ret = validate_list(chan, &op->vram_list, pbbo, user_buffers);
+	if (unlikely(ret < 0)) {
+		validate_fini(op, NULL);
+		return ret;
+	}
+	relocs += ret;
+
+	ret = validate_list(chan, &op->gart_list, pbbo, user_buffers);
+	if (unlikely(ret < 0)) {
+		validate_fini(op, NULL);
+		return ret;
+	}
+	relocs += ret;
+
+	ret = validate_list(chan, &op->both_list, pbbo, user_buffers);
+	if (unlikely(ret < 0)) {
+		validate_fini(op, NULL);
+		return ret;
+	}
+	relocs += ret;
+
+	*apply_relocs = relocs;
+	return 0;
+}
+
+static inline void *
+u_memcpya(uint64_t user, unsigned nmemb, unsigned size)
+{
+	void *mem;
+	void __user *userptr = (void __force __user *)(uintptr_t)user;
+
+	mem = kmalloc(nmemb * size, GFP_KERNEL);
+	if (!mem)
+		return ERR_PTR(-ENOMEM);
+
+	if (DRM_COPY_FROM_USER(mem, userptr, nmemb * size)) {
+		kfree(mem);
+		return ERR_PTR(-EFAULT);
+	}
+
+	return mem;
+}
+
+static int
+nouveau_gem_pushbuf_reloc_apply(struct nouveau_channel *chan, int nr_bo,
+				struct drm_nouveau_gem_pushbuf_bo *bo,
+				int nr_relocs, uint64_t ptr_relocs,
+				int nr_dwords, int first_dword,
+				uint32_t *pushbuf, bool is_iomem)
+{
+	struct drm_nouveau_gem_pushbuf_reloc *reloc = NULL;
+	struct drm_device *dev = chan->dev;
+	int ret = 0, i;
+
+	reloc = u_memcpya(ptr_relocs, nr_relocs, sizeof(*reloc));
+	if (IS_ERR(reloc))
+		return PTR_ERR(reloc);
+
+	for (i = 0; i < nr_relocs; i++) {
+		struct drm_nouveau_gem_pushbuf_reloc *r = &reloc[i];
+		struct drm_nouveau_gem_pushbuf_bo *b;
+		uint32_t data;
+
+		if (r->bo_index >= nr_bo || r->reloc_index < first_dword ||
+		    r->reloc_index >= first_dword + nr_dwords) {
+			NV_ERROR(dev, "Bad relocation %d\n", i);
+			NV_ERROR(dev, "  bo: %d max %d\n", r->bo_index, nr_bo);
+			NV_ERROR(dev, "  id: %d max %d\n", r->reloc_index, nr_dwords);
+			ret = -EINVAL;
+			break;
+		}
+
+		b = &bo[r->bo_index];
+		if (b->presumed_ok)
+			continue;
+
+		if (r->flags & NOUVEAU_GEM_RELOC_LOW)
+			data = b->presumed_offset + r->data;
+		else
+		if (r->flags & NOUVEAU_GEM_RELOC_HIGH)
+			data = (b->presumed_offset + r->data) >> 32;
+		else
+			data = r->data;
+
+		if (r->flags & NOUVEAU_GEM_RELOC_OR) {
+			if (b->presumed_domain == NOUVEAU_GEM_DOMAIN_GART)
+				data |= r->tor;
+			else
+				data |= r->vor;
+		}
+
+		if (is_iomem)
+			iowrite32_native(data, (void __force __iomem *)
+						&pushbuf[r->reloc_index]);
+		else
+			pushbuf[r->reloc_index] = data;
+	}
+
+	kfree(reloc);
+	return ret;
+}
+
+int
+nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
+			  struct drm_file *file_priv)
+{
+	struct drm_nouveau_gem_pushbuf *req = data;
+	struct drm_nouveau_gem_pushbuf_bo *bo = NULL;
+	struct nouveau_channel *chan;
+	struct validate_op op;
+	uint32_t *pushbuf = NULL;
+	int ret = 0, do_reloc = 0, i;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+	NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel, file_priv, chan);
+
+	if (req->nr_dwords >= chan->dma.max ||
+	    req->nr_buffers > NOUVEAU_GEM_MAX_BUFFERS ||
+	    req->nr_relocs > NOUVEAU_GEM_MAX_RELOCS) {
+		NV_ERROR(dev, "Pushbuf config exceeds limits:\n");
+		NV_ERROR(dev, "  dwords : %d max %d\n", req->nr_dwords,
+			 chan->dma.max - 1);
+		NV_ERROR(dev, "  buffers: %d max %d\n", req->nr_buffers,
+			 NOUVEAU_GEM_MAX_BUFFERS);
+		NV_ERROR(dev, "  relocs : %d max %d\n", req->nr_relocs,
+			 NOUVEAU_GEM_MAX_RELOCS);
+		return -EINVAL;
+	}
+
+	pushbuf = u_memcpya(req->dwords, req->nr_dwords, sizeof(uint32_t));
+	if (IS_ERR(pushbuf))
+		return PTR_ERR(pushbuf);
+
+	bo = u_memcpya(req->buffers, req->nr_buffers, sizeof(*bo));
+	if (IS_ERR(bo)) {
+		kfree(pushbuf);
+		return PTR_ERR(bo);
+	}
+
+	mutex_lock(&dev->struct_mutex);
+
+	/* Validate buffer list */
+	ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers,
+					   req->nr_buffers, &op, &do_reloc);
+	if (ret)
+		goto out;
+
+	/* Apply any relocations that are required */
+	if (do_reloc) {
+		ret = nouveau_gem_pushbuf_reloc_apply(chan, req->nr_buffers,
+						      bo, req->nr_relocs,
+						      req->relocs,
+						      req->nr_dwords, 0,
+						      pushbuf, false);
+		if (ret)
+			goto out;
+	}
+
+	/* Emit push buffer to the hw
+	 */
+	ret = RING_SPACE(chan, req->nr_dwords);
+	if (ret)
+		goto out;
+
+	OUT_RINGp(chan, pushbuf, req->nr_dwords);
+
+	ret = nouveau_fence_emit(op.fence);
+	if (ret) {
+		NV_ERROR(dev, "error fencing pushbuf: %d\n", ret);
+		WIND_RING(chan);
+		goto out;
+	}
+
+	if (nouveau_gem_pushbuf_sync(chan)) {
+		ret = nouveau_fence_wait(op.fence, NULL, false, false);
+		if (ret) {
+			for (i = 0; i < req->nr_dwords; i++)
+				NV_ERROR(dev, "0x%08x\n", pushbuf[i]);
+			NV_ERROR(dev, "^^ above push buffer is fail :(\n");
+		}
+	}
+
+out:
+	validate_fini(&op, ret == 0);
+	mutex_unlock(&dev->struct_mutex);
+	kfree(pushbuf);
+	kfree(bo);
+	return ret;
+}
+
+#define PUSHBUF_CAL (dev_priv->card_type >= NV_20)
+
+int
+nouveau_gem_ioctl_pushbuf_call(struct drm_device *dev, void *data,
+			       struct drm_file *file_priv)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_nouveau_gem_pushbuf_call *req = data;
+	struct drm_nouveau_gem_pushbuf_bo *bo = NULL;
+	struct nouveau_channel *chan;
+	struct drm_gem_object *gem;
+	struct nouveau_bo *pbbo;
+	struct validate_op op;
+	int i, ret = 0, do_reloc = 0;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+	NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel, file_priv, chan);
+
+	if (unlikely(req->handle == 0))
+		goto out_next;
+
+	if (req->nr_buffers > NOUVEAU_GEM_MAX_BUFFERS ||
+	    req->nr_relocs > NOUVEAU_GEM_MAX_RELOCS) {
+		NV_ERROR(dev, "Pushbuf config exceeds limits:\n");
+		NV_ERROR(dev, "  buffers: %d max %d\n", req->nr_buffers,
+			 NOUVEAU_GEM_MAX_BUFFERS);
+		NV_ERROR(dev, "  relocs : %d max %d\n", req->nr_relocs,
+			 NOUVEAU_GEM_MAX_RELOCS);
+		return -EINVAL;
+	}
+
+	bo = u_memcpya(req->buffers, req->nr_buffers, sizeof(*bo));
+	if (IS_ERR(bo))
+		return PTR_ERR(bo);
+
+	mutex_lock(&dev->struct_mutex);
+
+	/* Validate buffer list */
+	ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers,
+					   req->nr_buffers, &op, &do_reloc);
+	if (ret) {
+		NV_ERROR(dev, "validate: %d\n", ret);
+		goto out;
+	}
+
+	/* Validate DMA push buffer */
+	gem = drm_gem_object_lookup(dev, file_priv, req->handle);
+	if (!gem) {
+		NV_ERROR(dev, "Unknown pb handle 0x%08x\n", req->handle);
+		ret = -EINVAL;
+		goto out;
+	}
+	pbbo = nouveau_gem_object(gem);
+
+	ret = ttm_bo_reserve(&pbbo->bo, false, false, true,
+			     chan->fence.sequence);
+	if (ret) {
+		NV_ERROR(dev, "resv pb: %d\n", ret);
+		drm_gem_object_unreference(gem);
+		goto out;
+	}
+
+	nouveau_bo_placement_set(pbbo, 1 << chan->pushbuf_bo->bo.mem.mem_type);
+	ret = ttm_bo_validate(&pbbo->bo, &pbbo->placement, false, false);
+	if (ret) {
+		NV_ERROR(dev, "validate pb: %d\n", ret);
+		ttm_bo_unreserve(&pbbo->bo);
+		drm_gem_object_unreference(gem);
+		goto out;
+	}
+
+	list_add_tail(&pbbo->entry, &op.both_list);
+
+	/* If presumed return address doesn't match, we need to map the
+	 * push buffer and fix it..
+	 */
+	if (!PUSHBUF_CAL) {
+		uint32_t retaddy;
+
+		if (chan->dma.free < 4 + NOUVEAU_DMA_SKIPS) {
+			ret = nouveau_dma_wait(chan, 4 + NOUVEAU_DMA_SKIPS);
+			if (ret) {
+				NV_ERROR(dev, "jmp_space: %d\n", ret);
+				goto out;
+			}
+		}
+
+		retaddy  = chan->pushbuf_base + ((chan->dma.cur + 2) << 2);
+		retaddy |= 0x20000000;
+		if (retaddy != req->suffix0) {
+			req->suffix0 = retaddy;
+			do_reloc = 1;
+		}
+	}
+
+	/* Apply any relocations that are required */
+	if (do_reloc) {
+		void *pbvirt;
+		bool is_iomem;
+		ret = ttm_bo_kmap(&pbbo->bo, 0, pbbo->bo.mem.num_pages,
+				  &pbbo->kmap);
+		if (ret) {
+			NV_ERROR(dev, "kmap pb: %d\n", ret);
+			goto out;
+		}
+
+		pbvirt = ttm_kmap_obj_virtual(&pbbo->kmap, &is_iomem);
+		ret = nouveau_gem_pushbuf_reloc_apply(chan, req->nr_buffers, bo,
+						      req->nr_relocs,
+						      req->relocs,
+						      req->nr_dwords,
+						      req->offset / 4,
+						      pbvirt, is_iomem);
+
+		if (!PUSHBUF_CAL) {
+			nouveau_bo_wr32(pbbo,
+					req->offset / 4 + req->nr_dwords - 2,
+					req->suffix0);
+		}
+
+		ttm_bo_kunmap(&pbbo->kmap);
+		if (ret) {
+			NV_ERROR(dev, "reloc apply: %d\n", ret);
+			goto out;
+		}
+	}
+
+	if (PUSHBUF_CAL) {
+		ret = RING_SPACE(chan, 2);
+		if (ret) {
+			NV_ERROR(dev, "cal_space: %d\n", ret);
+			goto out;
+		}
+		OUT_RING(chan, ((pbbo->bo.mem.mm_node->start << PAGE_SHIFT) +
+				  req->offset) | 2);
+		OUT_RING(chan, 0);
+	} else {
+		ret = RING_SPACE(chan, 2 + NOUVEAU_DMA_SKIPS);
+		if (ret) {
+			NV_ERROR(dev, "jmp_space: %d\n", ret);
+			goto out;
+		}
+		OUT_RING(chan, ((pbbo->bo.mem.mm_node->start << PAGE_SHIFT) +
+				  req->offset) | 0x20000000);
+		OUT_RING(chan, 0);
+
+		/* Space the jumps apart with NOPs. */
+		for (i = 0; i < NOUVEAU_DMA_SKIPS; i++)
+			OUT_RING(chan, 0);
+	}
+
+	ret = nouveau_fence_emit(op.fence);
+	if (ret) {
+		NV_ERROR(dev, "error fencing pushbuf: %d\n", ret);
+		WIND_RING(chan);
+		goto out;
+	}
+
+out:
+	validate_fini(&op, ret == 0);
+	mutex_unlock(&dev->struct_mutex);
+	kfree(bo);
+
+out_next:
+	if (PUSHBUF_CAL) {
+		req->suffix0 = 0x00020000;
+		req->suffix1 = 0x00000000;
+	} else {
+		req->suffix0 = 0x20000000 |
+			      (chan->pushbuf_base + ((chan->dma.cur + 2) << 2));
+		req->suffix1 = 0x00000000;
+	}
+
+	return ret;
+}
+
+int
+nouveau_gem_ioctl_pushbuf_call2(struct drm_device *dev, void *data,
+				struct drm_file *file_priv)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_nouveau_gem_pushbuf_call *req = data;
+
+	req->vram_available = dev_priv->fb_aper_free;
+	req->gart_available = dev_priv->gart_info.aper_free;
+
+	return nouveau_gem_ioctl_pushbuf_call(dev, data, file_priv);
+}
+
+static inline uint32_t
+domain_to_ttm(struct nouveau_bo *nvbo, uint32_t domain)
+{
+	uint32_t flags = 0;
+
+	if (domain & NOUVEAU_GEM_DOMAIN_VRAM)
+		flags |= TTM_PL_FLAG_VRAM;
+	if (domain & NOUVEAU_GEM_DOMAIN_GART)
+		flags |= TTM_PL_FLAG_TT;
+
+	return flags;
+}
+
+int
+nouveau_gem_ioctl_pin(struct drm_device *dev, void *data,
+		      struct drm_file *file_priv)
+{
+	struct drm_nouveau_gem_pin *req = data;
+	struct drm_gem_object *gem;
+	struct nouveau_bo *nvbo;
+	int ret = 0;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
+	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+		NV_ERROR(dev, "pin only allowed without kernel modesetting\n");
+		return -EINVAL;
+	}
+
+	if (!DRM_SUSER(DRM_CURPROC))
+		return -EPERM;
+
+	gem = drm_gem_object_lookup(dev, file_priv, req->handle);
+	if (!gem)
+		return -EINVAL;
+	nvbo = nouveau_gem_object(gem);
+
+	ret = nouveau_bo_pin(nvbo, domain_to_ttm(nvbo, req->domain));
+	if (ret)
+		goto out;
+
+	req->offset = nvbo->bo.offset;
+	if (nvbo->bo.mem.mem_type == TTM_PL_TT)
+		req->domain = NOUVEAU_GEM_DOMAIN_GART;
+	else
+		req->domain = NOUVEAU_GEM_DOMAIN_VRAM;
+
+out:
+	mutex_lock(&dev->struct_mutex);
+	drm_gem_object_unreference(gem);
+	mutex_unlock(&dev->struct_mutex);
+
+	return ret;
+}
+
+int
+nouveau_gem_ioctl_unpin(struct drm_device *dev, void *data,
+			struct drm_file *file_priv)
+{
+	struct drm_nouveau_gem_pin *req = data;
+	struct drm_gem_object *gem;
+	int ret;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
+	if (drm_core_check_feature(dev, DRIVER_MODESET))
+		return -EINVAL;
+
+	gem = drm_gem_object_lookup(dev, file_priv, req->handle);
+	if (!gem)
+		return -EINVAL;
+
+	ret = nouveau_bo_unpin(nouveau_gem_object(gem));
+
+	mutex_lock(&dev->struct_mutex);
+	drm_gem_object_unreference(gem);
+	mutex_unlock(&dev->struct_mutex);
+
+	return ret;
+}
+
+int
+nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data,
+			   struct drm_file *file_priv)
+{
+	struct drm_nouveau_gem_cpu_prep *req = data;
+	struct drm_gem_object *gem;
+	struct nouveau_bo *nvbo;
+	bool no_wait = !!(req->flags & NOUVEAU_GEM_CPU_PREP_NOWAIT);
+	int ret = -EINVAL;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
+	gem = drm_gem_object_lookup(dev, file_priv, req->handle);
+	if (!gem)
+		return ret;
+	nvbo = nouveau_gem_object(gem);
+
+	if (nvbo->cpu_filp) {
+		if (nvbo->cpu_filp == file_priv)
+			goto out;
+
+		ret = ttm_bo_wait_cpu(&nvbo->bo, no_wait);
+		if (ret == -ERESTART)
+			ret = -EAGAIN;
+		if (ret)
+			goto out;
+	}
+
+	if (req->flags & NOUVEAU_GEM_CPU_PREP_NOBLOCK) {
+		ret = ttm_bo_wait(&nvbo->bo, false, false, no_wait);
+	} else {
+		ret = ttm_bo_synccpu_write_grab(&nvbo->bo, no_wait);
+		if (ret == -ERESTART)
+			ret = -EAGAIN;
+		else
+		if (ret == 0)
+			nvbo->cpu_filp = file_priv;
+	}
+
+out:
+	mutex_lock(&dev->struct_mutex);
+	drm_gem_object_unreference(gem);
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
+int
+nouveau_gem_ioctl_cpu_fini(struct drm_device *dev, void *data,
+			   struct drm_file *file_priv)
+{
+	struct drm_nouveau_gem_cpu_prep *req = data;
+	struct drm_gem_object *gem;
+	struct nouveau_bo *nvbo;
+	int ret = -EINVAL;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
+	gem = drm_gem_object_lookup(dev, file_priv, req->handle);
+	if (!gem)
+		return ret;
+	nvbo = nouveau_gem_object(gem);
+
+	if (nvbo->cpu_filp != file_priv)
+		goto out;
+	nvbo->cpu_filp = NULL;
+
+	ttm_bo_synccpu_write_release(&nvbo->bo);
+	ret = 0;
+
+out:
+	mutex_lock(&dev->struct_mutex);
+	drm_gem_object_unreference(gem);
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
+int
+nouveau_gem_ioctl_info(struct drm_device *dev, void *data,
+		       struct drm_file *file_priv)
+{
+	struct drm_nouveau_gem_info *req = data;
+	struct drm_gem_object *gem;
+	int ret;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
+	gem = drm_gem_object_lookup(dev, file_priv, req->handle);
+	if (!gem)
+		return -EINVAL;
+
+	ret = nouveau_gem_info(gem, req);
+	mutex_lock(&dev->struct_mutex);
+	drm_gem_object_unreference(gem);
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.c b/drivers/gpu/drm/nouveau/nouveau_hw.c
new file mode 100644
index 0000000..dc46792
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_hw.c
@@ -0,0 +1,1080 @@
+/*
+ * Copyright 2006 Dave Airlie
+ * Copyright 2007 Maarten Maathuis
+ * Copyright 2007-2009 Stuart Bennett
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_hw.h"
+
+#define CHIPSET_NFORCE 0x01a0
+#define CHIPSET_NFORCE2 0x01f0
+
+/*
+ * misc hw access wrappers/control functions
+ */
+
+void
+NVWriteVgaSeq(struct drm_device *dev, int head, uint8_t index, uint8_t value)
+{
+	NVWritePRMVIO(dev, head, NV_PRMVIO_SRX, index);
+	NVWritePRMVIO(dev, head, NV_PRMVIO_SR, value);
+}
+
+uint8_t
+NVReadVgaSeq(struct drm_device *dev, int head, uint8_t index)
+{
+	NVWritePRMVIO(dev, head, NV_PRMVIO_SRX, index);
+	return NVReadPRMVIO(dev, head, NV_PRMVIO_SR);
+}
+
+void
+NVWriteVgaGr(struct drm_device *dev, int head, uint8_t index, uint8_t value)
+{
+	NVWritePRMVIO(dev, head, NV_PRMVIO_GRX, index);
+	NVWritePRMVIO(dev, head, NV_PRMVIO_GX, value);
+}
+
+uint8_t
+NVReadVgaGr(struct drm_device *dev, int head, uint8_t index)
+{
+	NVWritePRMVIO(dev, head, NV_PRMVIO_GRX, index);
+	return NVReadPRMVIO(dev, head, NV_PRMVIO_GX);
+}
+
+/* CR44 takes values 0 (head A), 3 (head B) and 4 (heads tied)
+ * it affects only the 8 bit vga io regs, which we access using mmio at
+ * 0xc{0,2}3c*, 0x60{1,3}3*, and 0x68{1,3}3d*
+ * in general, the set value of cr44 does not matter: reg access works as
+ * expected and values can be set for the appropriate head by using a 0x2000
+ * offset as required
+ * however:
+ * a) pre nv40, the head B range of PRMVIO regs at 0xc23c* was not exposed and
+ *    cr44 must be set to 0 or 3 for accessing values on the correct head
+ *    through the common 0xc03c* addresses
+ * b) in tied mode (4) head B is programmed to the values set on head A, and
+ *    access using the head B addresses can have strange results, ergo we leave
+ *    tied mode in init once we know to what cr44 should be restored on exit
+ *
+ * the owner parameter is slightly abused:
+ * 0 and 1 are treated as head values and so the set value is (owner * 3)
+ * other values are treated as literal values to set
+ */
+void
+NVSetOwner(struct drm_device *dev, int owner)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (owner == 1)
+		owner *= 3;
+
+	if (dev_priv->chipset == 0x11) {
+		/* This might seem stupid, but the blob does it and
+		 * omitting it often locks the system up.
+		 */
+		NVReadVgaCrtc(dev, 0, NV_CIO_SR_LOCK_INDEX);
+		NVReadVgaCrtc(dev, 1, NV_CIO_SR_LOCK_INDEX);
+	}
+
+	/* CR44 is always changed on CRTC0 */
+	NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_44, owner);
+
+	if (dev_priv->chipset == 0x11) {	/* set me harder */
+		NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_2E, owner);
+		NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_2E, owner);
+	}
+}
+
+void
+NVBlankScreen(struct drm_device *dev, int head, bool blank)
+{
+	unsigned char seq1;
+
+	if (nv_two_heads(dev))
+		NVSetOwner(dev, head);
+
+	seq1 = NVReadVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX);
+
+	NVVgaSeqReset(dev, head, true);
+	if (blank)
+		NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 | 0x20);
+	else
+		NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 & ~0x20);
+	NVVgaSeqReset(dev, head, false);
+}
+
+/*
+ * PLL setting
+ */
+
+static int
+powerctrl_1_shift(int chip_version, int reg)
+{
+	int shift = -4;
+
+	if (chip_version < 0x17 || chip_version == 0x1a || chip_version == 0x20)
+		return shift;
+
+	switch (reg) {
+	case NV_RAMDAC_VPLL2:
+		shift += 4;
+	case NV_PRAMDAC_VPLL_COEFF:
+		shift += 4;
+	case NV_PRAMDAC_MPLL_COEFF:
+		shift += 4;
+	case NV_PRAMDAC_NVPLL_COEFF:
+		shift += 4;
+	}
+
+	/*
+	 * the shift for vpll regs is only used for nv3x chips with a single
+	 * stage pll
+	 */
+	if (shift > 4 && (chip_version < 0x32 || chip_version == 0x35 ||
+			  chip_version == 0x36 || chip_version >= 0x40))
+		shift = -4;
+
+	return shift;
+}
+
+static void
+setPLL_single(struct drm_device *dev, uint32_t reg, struct nouveau_pll_vals *pv)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int chip_version = dev_priv->vbios->chip_version;
+	uint32_t oldpll = NVReadRAMDAC(dev, 0, reg);
+	int oldN = (oldpll >> 8) & 0xff, oldM = oldpll & 0xff;
+	uint32_t pll = (oldpll & 0xfff80000) | pv->log2P << 16 | pv->NM1;
+	uint32_t saved_powerctrl_1 = 0;
+	int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg);
+
+	if (oldpll == pll)
+		return;	/* already set */
+
+	if (shift_powerctrl_1 >= 0) {
+		saved_powerctrl_1 = nvReadMC(dev, NV_PBUS_POWERCTRL_1);
+		nvWriteMC(dev, NV_PBUS_POWERCTRL_1,
+			(saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) |
+			1 << shift_powerctrl_1);
+	}
+
+	if (oldM && pv->M1 && (oldN / oldM < pv->N1 / pv->M1))
+		/* upclock -- write new post divider first */
+		NVWriteRAMDAC(dev, 0, reg, pv->log2P << 16 | (oldpll & 0xffff));
+	else
+		/* downclock -- write new NM first */
+		NVWriteRAMDAC(dev, 0, reg, (oldpll & 0xffff0000) | pv->NM1);
+
+	if (chip_version < 0x17 && chip_version != 0x11)
+		/* wait a bit on older chips */
+		msleep(64);
+	NVReadRAMDAC(dev, 0, reg);
+
+	/* then write the other half as well */
+	NVWriteRAMDAC(dev, 0, reg, pll);
+
+	if (shift_powerctrl_1 >= 0)
+		nvWriteMC(dev, NV_PBUS_POWERCTRL_1, saved_powerctrl_1);
+}
+
+static uint32_t
+new_ramdac580(uint32_t reg1, bool ss, uint32_t ramdac580)
+{
+	bool head_a = (reg1 == NV_PRAMDAC_VPLL_COEFF);
+
+	if (ss)	/* single stage pll mode */
+		ramdac580 |= head_a ? NV_RAMDAC_580_VPLL1_ACTIVE :
+				      NV_RAMDAC_580_VPLL2_ACTIVE;
+	else
+		ramdac580 &= head_a ? ~NV_RAMDAC_580_VPLL1_ACTIVE :
+				      ~NV_RAMDAC_580_VPLL2_ACTIVE;
+
+	return ramdac580;
+}
+
+static void
+setPLL_double_highregs(struct drm_device *dev, uint32_t reg1,
+		       struct nouveau_pll_vals *pv)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int chip_version = dev_priv->vbios->chip_version;
+	bool nv3035 = chip_version == 0x30 || chip_version == 0x35;
+	uint32_t reg2 = reg1 + ((reg1 == NV_RAMDAC_VPLL2) ? 0x5c : 0x70);
+	uint32_t oldpll1 = NVReadRAMDAC(dev, 0, reg1);
+	uint32_t oldpll2 = !nv3035 ? NVReadRAMDAC(dev, 0, reg2) : 0;
+	uint32_t pll1 = (oldpll1 & 0xfff80000) | pv->log2P << 16 | pv->NM1;
+	uint32_t pll2 = (oldpll2 & 0x7fff0000) | 1 << 31 | pv->NM2;
+	uint32_t oldramdac580 = 0, ramdac580 = 0;
+	bool single_stage = !pv->NM2 || pv->N2 == pv->M2;	/* nv41+ only */
+	uint32_t saved_powerctrl_1 = 0, savedc040 = 0;
+	int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg1);
+
+	/* model specific additions to generic pll1 and pll2 set up above */
+	if (nv3035) {
+		pll1 = (pll1 & 0xfcc7ffff) | (pv->N2 & 0x18) << 21 |
+		       (pv->N2 & 0x7) << 19 | 8 << 4 | (pv->M2 & 7) << 4;
+		pll2 = 0;
+	}
+	if (chip_version > 0x40 && reg1 >= NV_PRAMDAC_VPLL_COEFF) { /* !nv40 */
+		oldramdac580 = NVReadRAMDAC(dev, 0, NV_PRAMDAC_580);
+		ramdac580 = new_ramdac580(reg1, single_stage, oldramdac580);
+		if (oldramdac580 != ramdac580)
+			oldpll1 = ~0;	/* force mismatch */
+		if (single_stage)
+			/* magic value used by nvidia in single stage mode */
+			pll2 |= 0x011f;
+	}
+	if (chip_version > 0x70)
+		/* magic bits set by the blob (but not the bios) on g71-73 */
+		pll1 = (pll1 & 0x7fffffff) | (single_stage ? 0x4 : 0xc) << 28;
+
+	if (oldpll1 == pll1 && oldpll2 == pll2)
+		return;	/* already set */
+
+	if (shift_powerctrl_1 >= 0) {
+		saved_powerctrl_1 = nvReadMC(dev, NV_PBUS_POWERCTRL_1);
+		nvWriteMC(dev, NV_PBUS_POWERCTRL_1,
+			(saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) |
+			1 << shift_powerctrl_1);
+	}
+
+	if (chip_version >= 0x40) {
+		int shift_c040 = 14;
+
+		switch (reg1) {
+		case NV_PRAMDAC_MPLL_COEFF:
+			shift_c040 += 2;
+		case NV_PRAMDAC_NVPLL_COEFF:
+			shift_c040 += 2;
+		case NV_RAMDAC_VPLL2:
+			shift_c040 += 2;
+		case NV_PRAMDAC_VPLL_COEFF:
+			shift_c040 += 2;
+		}
+
+		savedc040 = nvReadMC(dev, 0xc040);
+		if (shift_c040 != 14)
+			nvWriteMC(dev, 0xc040, savedc040 & ~(3 << shift_c040));
+	}
+
+	if (oldramdac580 != ramdac580)
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_580, ramdac580);
+
+	if (!nv3035)
+		NVWriteRAMDAC(dev, 0, reg2, pll2);
+	NVWriteRAMDAC(dev, 0, reg1, pll1);
+
+	if (shift_powerctrl_1 >= 0)
+		nvWriteMC(dev, NV_PBUS_POWERCTRL_1, saved_powerctrl_1);
+	if (chip_version >= 0x40)
+		nvWriteMC(dev, 0xc040, savedc040);
+}
+
+static void
+setPLL_double_lowregs(struct drm_device *dev, uint32_t NMNMreg,
+		      struct nouveau_pll_vals *pv)
+{
+	/* When setting PLLs, there is a merry game of disabling and enabling
+	 * various bits of hardware during the process. This function is a
+	 * synthesis of six nv4x traces, nearly each card doing a subtly
+	 * different thing. With luck all the necessary bits for each card are
+	 * combined herein. Without luck it deviates from each card's formula
+	 * so as to not work on any :)
+	 */
+
+	uint32_t Preg = NMNMreg - 4;
+	bool mpll = Preg == 0x4020;
+	uint32_t oldPval = nvReadMC(dev, Preg);
+	uint32_t NMNM = pv->NM2 << 16 | pv->NM1;
+	uint32_t Pval = (oldPval & (mpll ? ~(0x11 << 16) : ~(1 << 16))) |
+			0xc << 28 | pv->log2P << 16;
+	uint32_t saved4600 = 0;
+	/* some cards have different maskc040s */
+	uint32_t maskc040 = ~(3 << 14), savedc040;
+	bool single_stage = !pv->NM2 || pv->N2 == pv->M2;
+
+	if (nvReadMC(dev, NMNMreg) == NMNM && (oldPval & 0xc0070000) == Pval)
+		return;
+
+	if (Preg == 0x4000)
+		maskc040 = ~0x333;
+	if (Preg == 0x4058)
+		maskc040 = ~(0xc << 24);
+
+	if (mpll) {
+		struct pll_lims pll_lim;
+		uint8_t Pval2;
+
+		if (get_pll_limits(dev, Preg, &pll_lim))
+			return;
+
+		Pval2 = pv->log2P + pll_lim.log2p_bias;
+		if (Pval2 > pll_lim.max_log2p)
+			Pval2 = pll_lim.max_log2p;
+		Pval |= 1 << 28 | Pval2 << 20;
+
+		saved4600 = nvReadMC(dev, 0x4600);
+		nvWriteMC(dev, 0x4600, saved4600 | 8 << 28);
+	}
+	if (single_stage)
+		Pval |= mpll ? 1 << 12 : 1 << 8;
+
+	nvWriteMC(dev, Preg, oldPval | 1 << 28);
+	nvWriteMC(dev, Preg, Pval & ~(4 << 28));
+	if (mpll) {
+		Pval |= 8 << 20;
+		nvWriteMC(dev, 0x4020, Pval & ~(0xc << 28));
+		nvWriteMC(dev, 0x4038, Pval & ~(0xc << 28));
+	}
+
+	savedc040 = nvReadMC(dev, 0xc040);
+	nvWriteMC(dev, 0xc040, savedc040 & maskc040);
+
+	nvWriteMC(dev, NMNMreg, NMNM);
+	if (NMNMreg == 0x4024)
+		nvWriteMC(dev, 0x403c, NMNM);
+
+	nvWriteMC(dev, Preg, Pval);
+	if (mpll) {
+		Pval &= ~(8 << 20);
+		nvWriteMC(dev, 0x4020, Pval);
+		nvWriteMC(dev, 0x4038, Pval);
+		nvWriteMC(dev, 0x4600, saved4600);
+	}
+
+	nvWriteMC(dev, 0xc040, savedc040);
+
+	if (mpll) {
+		nvWriteMC(dev, 0x4020, Pval & ~(1 << 28));
+		nvWriteMC(dev, 0x4038, Pval & ~(1 << 28));
+	}
+}
+
+void
+nouveau_hw_setpll(struct drm_device *dev, uint32_t reg1,
+		  struct nouveau_pll_vals *pv)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int cv = dev_priv->vbios->chip_version;
+
+	if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 ||
+	    cv >= 0x40) {
+		if (reg1 > 0x405c)
+			setPLL_double_highregs(dev, reg1, pv);
+		else
+			setPLL_double_lowregs(dev, reg1, pv);
+	} else
+		setPLL_single(dev, reg1, pv);
+}
+
+/*
+ * PLL getting
+ */
+
+static void
+nouveau_hw_decode_pll(struct drm_device *dev, uint32_t reg1, uint32_t pll1,
+		      uint32_t pll2, struct nouveau_pll_vals *pllvals)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	/* to force parsing as single stage (i.e. nv40 vplls) pass pll2 as 0 */
+
+	/* log2P is & 0x7 as never more than 7, and nv30/35 only uses 3 bits */
+	pllvals->log2P = (pll1 >> 16) & 0x7;
+	pllvals->N2 = pllvals->M2 = 1;
+
+	if (reg1 <= 0x405c) {
+		pllvals->NM1 = pll2 & 0xffff;
+		/* single stage NVPLL and VPLLs use 1 << 8, MPLL uses 1 << 12 */
+		if (!(pll1 & 0x1100))
+			pllvals->NM2 = pll2 >> 16;
+	} else {
+		pllvals->NM1 = pll1 & 0xffff;
+		if (nv_two_reg_pll(dev) && pll2 & NV31_RAMDAC_ENABLE_VCO2)
+			pllvals->NM2 = pll2 & 0xffff;
+		else if (dev_priv->chipset == 0x30 || dev_priv->chipset == 0x35) {
+			pllvals->M1 &= 0xf; /* only 4 bits */
+			if (pll1 & NV30_RAMDAC_ENABLE_VCO2) {
+				pllvals->M2 = (pll1 >> 4) & 0x7;
+				pllvals->N2 = ((pll1 >> 21) & 0x18) |
+					      ((pll1 >> 19) & 0x7);
+			}
+		}
+	}
+}
+
+int
+nouveau_hw_get_pllvals(struct drm_device *dev, enum pll_types plltype,
+		       struct nouveau_pll_vals *pllvals)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	const uint32_t nv04_regs[MAX_PLL_TYPES] = { NV_PRAMDAC_NVPLL_COEFF,
+						    NV_PRAMDAC_MPLL_COEFF,
+						    NV_PRAMDAC_VPLL_COEFF,
+						    NV_RAMDAC_VPLL2 };
+	const uint32_t nv40_regs[MAX_PLL_TYPES] = { 0x4000,
+						    0x4020,
+						    NV_PRAMDAC_VPLL_COEFF,
+						    NV_RAMDAC_VPLL2 };
+	uint32_t reg1, pll1, pll2 = 0;
+	struct pll_lims pll_lim;
+	int ret;
+
+	if (dev_priv->card_type < NV_40)
+		reg1 = nv04_regs[plltype];
+	else
+		reg1 = nv40_regs[plltype];
+
+	pll1 = nvReadMC(dev, reg1);
+
+	if (reg1 <= 0x405c)
+		pll2 = nvReadMC(dev, reg1 + 4);
+	else if (nv_two_reg_pll(dev)) {
+		uint32_t reg2 = reg1 + (reg1 == NV_RAMDAC_VPLL2 ? 0x5c : 0x70);
+
+		pll2 = nvReadMC(dev, reg2);
+	}
+
+	if (dev_priv->card_type == 0x40 && reg1 >= NV_PRAMDAC_VPLL_COEFF) {
+		uint32_t ramdac580 = NVReadRAMDAC(dev, 0, NV_PRAMDAC_580);
+
+		/* check whether vpll has been forced into single stage mode */
+		if (reg1 == NV_PRAMDAC_VPLL_COEFF) {
+			if (ramdac580 & NV_RAMDAC_580_VPLL1_ACTIVE)
+				pll2 = 0;
+		} else
+			if (ramdac580 & NV_RAMDAC_580_VPLL2_ACTIVE)
+				pll2 = 0;
+	}
+
+	nouveau_hw_decode_pll(dev, reg1, pll1, pll2, pllvals);
+
+	ret = get_pll_limits(dev, plltype, &pll_lim);
+	if (ret)
+		return ret;
+
+	pllvals->refclk = pll_lim.refclk;
+
+	return 0;
+}
+
+int
+nouveau_hw_pllvals_to_clk(struct nouveau_pll_vals *pv)
+{
+	/* Avoid divide by zero if called at an inappropriate time */
+	if (!pv->M1 || !pv->M2)
+		return 0;
+
+	return pv->N1 * pv->N2 * pv->refclk / (pv->M1 * pv->M2) >> pv->log2P;
+}
+
+int
+nouveau_hw_get_clock(struct drm_device *dev, enum pll_types plltype)
+{
+	struct nouveau_pll_vals pllvals;
+
+	if (plltype == MPLL && (dev->pci_device & 0x0ff0) == CHIPSET_NFORCE) {
+		uint32_t mpllP;
+
+		pci_read_config_dword(pci_get_bus_and_slot(0, 3), 0x6c, &mpllP);
+		if (!mpllP)
+			mpllP = 4;
+
+		return 400000 / mpllP;
+	} else
+	if (plltype == MPLL && (dev->pci_device & 0xff0) == CHIPSET_NFORCE2) {
+		uint32_t clock;
+
+		pci_read_config_dword(pci_get_bus_and_slot(0, 5), 0x4c, &clock);
+		return clock;
+	}
+
+	nouveau_hw_get_pllvals(dev, plltype, &pllvals);
+
+	return nouveau_hw_pllvals_to_clk(&pllvals);
+}
+
+static void
+nouveau_hw_fix_bad_vpll(struct drm_device *dev, int head)
+{
+	/* the vpll on an unused head can come up with a random value, way
+	 * beyond the pll limits.  for some reason this causes the chip to
+	 * lock up when reading the dac palette regs, so set a valid pll here
+	 * when such a condition detected.  only seen on nv11 to date
+	 */
+
+	struct pll_lims pll_lim;
+	struct nouveau_pll_vals pv;
+	uint32_t pllreg = head ? NV_RAMDAC_VPLL2 : NV_PRAMDAC_VPLL_COEFF;
+
+	if (get_pll_limits(dev, head ? VPLL2 : VPLL1, &pll_lim))
+		return;
+	nouveau_hw_get_pllvals(dev, head ? VPLL2 : VPLL1, &pv);
+
+	if (pv.M1 >= pll_lim.vco1.min_m && pv.M1 <= pll_lim.vco1.max_m &&
+	    pv.N1 >= pll_lim.vco1.min_n && pv.N1 <= pll_lim.vco1.max_n &&
+	    pv.log2P <= pll_lim.max_log2p)
+		return;
+
+	NV_WARN(dev, "VPLL %d outwith limits, attempting to fix\n", head + 1);
+
+	/* set lowest clock within static limits */
+	pv.M1 = pll_lim.vco1.max_m;
+	pv.N1 = pll_lim.vco1.min_n;
+	pv.log2P = pll_lim.max_usable_log2p;
+	nouveau_hw_setpll(dev, pllreg, &pv);
+}
+
+/*
+ * vga font save/restore
+ */
+
+static void nouveau_vga_font_io(struct drm_device *dev,
+				void __iomem *iovram,
+				bool save, unsigned plane)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	unsigned i;
+
+	NVWriteVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX, 1 << plane);
+	NVWriteVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX, plane);
+	for (i = 0; i < 16384; i++) {
+		if (save) {
+			dev_priv->saved_vga_font[plane][i] =
+					ioread32_native(iovram + i * 4);
+		} else {
+			iowrite32_native(dev_priv->saved_vga_font[plane][i],
+							iovram + i * 4);
+		}
+	}
+}
+
+void
+nouveau_hw_save_vga_fonts(struct drm_device *dev, bool save)
+{
+	uint8_t misc, gr4, gr5, gr6, seq2, seq4;
+	bool graphicsmode;
+	unsigned plane;
+	void __iomem *iovram;
+
+	if (nv_two_heads(dev))
+		NVSetOwner(dev, 0);
+
+	NVSetEnablePalette(dev, 0, true);
+	graphicsmode = NVReadVgaAttr(dev, 0, NV_CIO_AR_MODE_INDEX) & 1;
+	NVSetEnablePalette(dev, 0, false);
+
+	if (graphicsmode) /* graphics mode => framebuffer => no need to save */
+		return;
+
+	NV_INFO(dev, "%sing VGA fonts\n", save ? "Sav" : "Restor");
+
+	/* map first 64KiB of VRAM, holds VGA fonts etc */
+	iovram = ioremap(pci_resource_start(dev->pdev, 1), 65536);
+	if (!iovram) {
+		NV_ERROR(dev, "Failed to map VRAM, "
+					"cannot save/restore VGA fonts.\n");
+		return;
+	}
+
+	if (nv_two_heads(dev))
+		NVBlankScreen(dev, 1, true);
+	NVBlankScreen(dev, 0, true);
+
+	/* save control regs */
+	misc = NVReadPRMVIO(dev, 0, NV_PRMVIO_MISC__READ);
+	seq2 = NVReadVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX);
+	seq4 = NVReadVgaSeq(dev, 0, NV_VIO_SR_MEM_MODE_INDEX);
+	gr4 = NVReadVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX);
+	gr5 = NVReadVgaGr(dev, 0, NV_VIO_GX_MODE_INDEX);
+	gr6 = NVReadVgaGr(dev, 0, NV_VIO_GX_MISC_INDEX);
+
+	NVWritePRMVIO(dev, 0, NV_PRMVIO_MISC__WRITE, 0x67);
+	NVWriteVgaSeq(dev, 0, NV_VIO_SR_MEM_MODE_INDEX, 0x6);
+	NVWriteVgaGr(dev, 0, NV_VIO_GX_MODE_INDEX, 0x0);
+	NVWriteVgaGr(dev, 0, NV_VIO_GX_MISC_INDEX, 0x5);
+
+	/* store font in planes 0..3 */
+	for (plane = 0; plane < 4; plane++)
+		nouveau_vga_font_io(dev, iovram, save, plane);
+
+	/* restore control regs */
+	NVWritePRMVIO(dev, 0, NV_PRMVIO_MISC__WRITE, misc);
+	NVWriteVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX, gr4);
+	NVWriteVgaGr(dev, 0, NV_VIO_GX_MODE_INDEX, gr5);
+	NVWriteVgaGr(dev, 0, NV_VIO_GX_MISC_INDEX, gr6);
+	NVWriteVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX, seq2);
+	NVWriteVgaSeq(dev, 0, NV_VIO_SR_MEM_MODE_INDEX, seq4);
+
+	if (nv_two_heads(dev))
+		NVBlankScreen(dev, 1, false);
+	NVBlankScreen(dev, 0, false);
+
+	iounmap(iovram);
+}
+
+/*
+ * mode state save/load
+ */
+
+static void
+rd_cio_state(struct drm_device *dev, int head,
+	     struct nv04_crtc_reg *crtcstate, int index)
+{
+	crtcstate->CRTC[index] = NVReadVgaCrtc(dev, head, index);
+}
+
+static void
+wr_cio_state(struct drm_device *dev, int head,
+	     struct nv04_crtc_reg *crtcstate, int index)
+{
+	NVWriteVgaCrtc(dev, head, index, crtcstate->CRTC[index]);
+}
+
+static void
+nv_save_state_ramdac(struct drm_device *dev, int head,
+		     struct nv04_mode_state *state)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv04_crtc_reg *regp = &state->crtc_reg[head];
+	int i;
+
+	if (dev_priv->card_type >= NV_10)
+		regp->nv10_cursync = NVReadRAMDAC(dev, head, NV_RAMDAC_NV10_CURSYNC);
+
+	nouveau_hw_get_pllvals(dev, head ? VPLL2 : VPLL1, &regp->pllvals);
+	state->pllsel = NVReadRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT);
+	if (nv_two_heads(dev))
+		state->sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK);
+	if (dev_priv->chipset == 0x11)
+		regp->dither = NVReadRAMDAC(dev, head, NV_RAMDAC_DITHER_NV11);
+
+	regp->ramdac_gen_ctrl = NVReadRAMDAC(dev, head, NV_PRAMDAC_GENERAL_CONTROL);
+
+	if (nv_gf4_disp_arch(dev))
+		regp->ramdac_630 = NVReadRAMDAC(dev, head, NV_PRAMDAC_630);
+	if (dev_priv->chipset >= 0x30)
+		regp->ramdac_634 = NVReadRAMDAC(dev, head, NV_PRAMDAC_634);
+
+	regp->tv_setup = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_SETUP);
+	regp->tv_vtotal = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_VTOTAL);
+	regp->tv_vskew = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_VSKEW);
+	regp->tv_vsync_delay = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_VSYNC_DELAY);
+	regp->tv_htotal = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_HTOTAL);
+	regp->tv_hskew = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_HSKEW);
+	regp->tv_hsync_delay = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_HSYNC_DELAY);
+	regp->tv_hsync_delay2 = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_HSYNC_DELAY2);
+
+	for (i = 0; i < 7; i++) {
+		uint32_t ramdac_reg = NV_PRAMDAC_FP_VDISPLAY_END + (i * 4);
+		regp->fp_vert_regs[i] = NVReadRAMDAC(dev, head, ramdac_reg);
+		regp->fp_horiz_regs[i] = NVReadRAMDAC(dev, head, ramdac_reg + 0x20);
+	}
+
+	if (nv_gf4_disp_arch(dev)) {
+		regp->dither = NVReadRAMDAC(dev, head, NV_RAMDAC_FP_DITHER);
+		for (i = 0; i < 3; i++) {
+			regp->dither_regs[i] = NVReadRAMDAC(dev, head, NV_PRAMDAC_850 + i * 4);
+			regp->dither_regs[i + 3] = NVReadRAMDAC(dev, head, NV_PRAMDAC_85C + i * 4);
+		}
+	}
+
+	regp->fp_control = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL);
+	regp->fp_debug_0 = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_0);
+	if (!nv_gf4_disp_arch(dev) && head == 0) {
+		/* early chips don't allow access to PRAMDAC_TMDS_* without
+		 * the head A FPCLK on (nv11 even locks up) */
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_FP_DEBUG_0, regp->fp_debug_0 &
+			      ~NV_PRAMDAC_FP_DEBUG_0_PWRDOWN_FPCLK);
+	}
+	regp->fp_debug_1 = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_1);
+	regp->fp_debug_2 = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_2);
+
+	regp->fp_margin_color = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_MARGIN_COLOR);
+
+	if (nv_gf4_disp_arch(dev))
+		regp->ramdac_8c0 = NVReadRAMDAC(dev, head, NV_PRAMDAC_8C0);
+
+	if (dev_priv->card_type == NV_40) {
+		regp->ramdac_a20 = NVReadRAMDAC(dev, head, NV_PRAMDAC_A20);
+		regp->ramdac_a24 = NVReadRAMDAC(dev, head, NV_PRAMDAC_A24);
+		regp->ramdac_a34 = NVReadRAMDAC(dev, head, NV_PRAMDAC_A34);
+
+		for (i = 0; i < 38; i++)
+			regp->ctv_regs[i] = NVReadRAMDAC(dev, head,
+							 NV_PRAMDAC_CTV + 4*i);
+	}
+}
+
+static void
+nv_load_state_ramdac(struct drm_device *dev, int head,
+		     struct nv04_mode_state *state)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv04_crtc_reg *regp = &state->crtc_reg[head];
+	uint32_t pllreg = head ? NV_RAMDAC_VPLL2 : NV_PRAMDAC_VPLL_COEFF;
+	int i;
+
+	if (dev_priv->card_type >= NV_10)
+		NVWriteRAMDAC(dev, head, NV_RAMDAC_NV10_CURSYNC, regp->nv10_cursync);
+
+	nouveau_hw_setpll(dev, pllreg, &regp->pllvals);
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT, state->pllsel);
+	if (nv_two_heads(dev))
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, state->sel_clk);
+	if (dev_priv->chipset == 0x11)
+		NVWriteRAMDAC(dev, head, NV_RAMDAC_DITHER_NV11, regp->dither);
+
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_GENERAL_CONTROL, regp->ramdac_gen_ctrl);
+
+	if (nv_gf4_disp_arch(dev))
+		NVWriteRAMDAC(dev, head, NV_PRAMDAC_630, regp->ramdac_630);
+	if (dev_priv->chipset >= 0x30)
+		NVWriteRAMDAC(dev, head, NV_PRAMDAC_634, regp->ramdac_634);
+
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_SETUP, regp->tv_setup);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_VTOTAL, regp->tv_vtotal);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_VSKEW, regp->tv_vskew);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_VSYNC_DELAY, regp->tv_vsync_delay);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_HTOTAL, regp->tv_htotal);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_HSKEW, regp->tv_hskew);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_HSYNC_DELAY, regp->tv_hsync_delay);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_HSYNC_DELAY2, regp->tv_hsync_delay2);
+
+	for (i = 0; i < 7; i++) {
+		uint32_t ramdac_reg = NV_PRAMDAC_FP_VDISPLAY_END + (i * 4);
+
+		NVWriteRAMDAC(dev, head, ramdac_reg, regp->fp_vert_regs[i]);
+		NVWriteRAMDAC(dev, head, ramdac_reg + 0x20, regp->fp_horiz_regs[i]);
+	}
+
+	if (nv_gf4_disp_arch(dev)) {
+		NVWriteRAMDAC(dev, head, NV_RAMDAC_FP_DITHER, regp->dither);
+		for (i = 0; i < 3; i++) {
+			NVWriteRAMDAC(dev, head, NV_PRAMDAC_850 + i * 4, regp->dither_regs[i]);
+			NVWriteRAMDAC(dev, head, NV_PRAMDAC_85C + i * 4, regp->dither_regs[i + 3]);
+		}
+	}
+
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL, regp->fp_control);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_0, regp->fp_debug_0);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_1, regp->fp_debug_1);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_2, regp->fp_debug_2);
+
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_MARGIN_COLOR, regp->fp_margin_color);
+
+	if (nv_gf4_disp_arch(dev))
+		NVWriteRAMDAC(dev, head, NV_PRAMDAC_8C0, regp->ramdac_8c0);
+
+	if (dev_priv->card_type == NV_40) {
+		NVWriteRAMDAC(dev, head, NV_PRAMDAC_A20, regp->ramdac_a20);
+		NVWriteRAMDAC(dev, head, NV_PRAMDAC_A24, regp->ramdac_a24);
+		NVWriteRAMDAC(dev, head, NV_PRAMDAC_A34, regp->ramdac_a34);
+
+		for (i = 0; i < 38; i++)
+			NVWriteRAMDAC(dev, head,
+				      NV_PRAMDAC_CTV + 4*i, regp->ctv_regs[i]);
+	}
+}
+
+static void
+nv_save_state_vga(struct drm_device *dev, int head,
+		  struct nv04_mode_state *state)
+{
+	struct nv04_crtc_reg *regp = &state->crtc_reg[head];
+	int i;
+
+	regp->MiscOutReg = NVReadPRMVIO(dev, head, NV_PRMVIO_MISC__READ);
+
+	for (i = 0; i < 25; i++)
+		rd_cio_state(dev, head, regp, i);
+
+	NVSetEnablePalette(dev, head, true);
+	for (i = 0; i < 21; i++)
+		regp->Attribute[i] = NVReadVgaAttr(dev, head, i);
+	NVSetEnablePalette(dev, head, false);
+
+	for (i = 0; i < 9; i++)
+		regp->Graphics[i] = NVReadVgaGr(dev, head, i);
+
+	for (i = 0; i < 5; i++)
+		regp->Sequencer[i] = NVReadVgaSeq(dev, head, i);
+}
+
+static void
+nv_load_state_vga(struct drm_device *dev, int head,
+		  struct nv04_mode_state *state)
+{
+	struct nv04_crtc_reg *regp = &state->crtc_reg[head];
+	int i;
+
+	NVWritePRMVIO(dev, head, NV_PRMVIO_MISC__WRITE, regp->MiscOutReg);
+
+	for (i = 0; i < 5; i++)
+		NVWriteVgaSeq(dev, head, i, regp->Sequencer[i]);
+
+	nv_lock_vga_crtc_base(dev, head, false);
+	for (i = 0; i < 25; i++)
+		wr_cio_state(dev, head, regp, i);
+	nv_lock_vga_crtc_base(dev, head, true);
+
+	for (i = 0; i < 9; i++)
+		NVWriteVgaGr(dev, head, i, regp->Graphics[i]);
+
+	NVSetEnablePalette(dev, head, true);
+	for (i = 0; i < 21; i++)
+		NVWriteVgaAttr(dev, head, i, regp->Attribute[i]);
+	NVSetEnablePalette(dev, head, false);
+}
+
+static void
+nv_save_state_ext(struct drm_device *dev, int head,
+		  struct nv04_mode_state *state)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv04_crtc_reg *regp = &state->crtc_reg[head];
+	int i;
+
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_LCD__INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_RPC0_INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_RPC1_INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_LSR_INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_PIXEL_INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_HEB__INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_ENH_INDEX);
+
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_FF_INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_FFLWM__INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_21);
+	if (dev_priv->card_type >= NV_30)
+		rd_cio_state(dev, head, regp, NV_CIO_CRE_47);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_49);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR2_INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_ILACE__INDEX);
+
+	if (dev_priv->card_type >= NV_10) {
+		regp->crtc_830 = NVReadCRTC(dev, head, NV_PCRTC_830);
+		regp->crtc_834 = NVReadCRTC(dev, head, NV_PCRTC_834);
+
+		if (dev_priv->card_type >= NV_30)
+			regp->gpio_ext = NVReadCRTC(dev, head, NV_PCRTC_GPIO_EXT);
+
+		if (dev_priv->card_type == NV_40)
+			regp->crtc_850 = NVReadCRTC(dev, head, NV_PCRTC_850);
+
+		if (nv_two_heads(dev))
+			regp->crtc_eng_ctrl = NVReadCRTC(dev, head, NV_PCRTC_ENGINE_CTRL);
+		regp->cursor_cfg = NVReadCRTC(dev, head, NV_PCRTC_CURSOR_CONFIG);
+	}
+
+	regp->crtc_cfg = NVReadCRTC(dev, head, NV_PCRTC_CONFIG);
+
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH3__INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH4__INDEX);
+	if (dev_priv->card_type >= NV_10) {
+		rd_cio_state(dev, head, regp, NV_CIO_CRE_EBR_INDEX);
+		rd_cio_state(dev, head, regp, NV_CIO_CRE_CSB);
+		rd_cio_state(dev, head, regp, NV_CIO_CRE_4B);
+		rd_cio_state(dev, head, regp, NV_CIO_CRE_TVOUT_LATENCY);
+	}
+	/* NV11 and NV20 don't have this, they stop at 0x52. */
+	if (nv_gf4_disp_arch(dev)) {
+		rd_cio_state(dev, head, regp, NV_CIO_CRE_53);
+		rd_cio_state(dev, head, regp, NV_CIO_CRE_54);
+
+		for (i = 0; i < 0x10; i++)
+			regp->CR58[i] = NVReadVgaCrtc5758(dev, head, i);
+		rd_cio_state(dev, head, regp, NV_CIO_CRE_59);
+		rd_cio_state(dev, head, regp, NV_CIO_CRE_5B);
+
+		rd_cio_state(dev, head, regp, NV_CIO_CRE_85);
+		rd_cio_state(dev, head, regp, NV_CIO_CRE_86);
+	}
+
+	regp->fb_start = NVReadCRTC(dev, head, NV_PCRTC_START);
+}
+
+static void
+nv_load_state_ext(struct drm_device *dev, int head,
+		  struct nv04_mode_state *state)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv04_crtc_reg *regp = &state->crtc_reg[head];
+	uint32_t reg900;
+	int i;
+
+	if (dev_priv->card_type >= NV_10) {
+		if (nv_two_heads(dev))
+			/* setting ENGINE_CTRL (EC) *must* come before
+			 * CIO_CRE_LCD, as writing CRE_LCD sets bits 16 & 17 in
+			 * EC that should not be overwritten by writing stale EC
+			 */
+			NVWriteCRTC(dev, head, NV_PCRTC_ENGINE_CTRL, regp->crtc_eng_ctrl);
+
+		nvWriteVIDEO(dev, NV_PVIDEO_STOP, 1);
+		nvWriteVIDEO(dev, NV_PVIDEO_INTR_EN, 0);
+		nvWriteVIDEO(dev, NV_PVIDEO_OFFSET_BUFF(0), 0);
+		nvWriteVIDEO(dev, NV_PVIDEO_OFFSET_BUFF(1), 0);
+		nvWriteVIDEO(dev, NV_PVIDEO_LIMIT(0), dev_priv->fb_available_size - 1);
+		nvWriteVIDEO(dev, NV_PVIDEO_LIMIT(1), dev_priv->fb_available_size - 1);
+		nvWriteVIDEO(dev, NV_PVIDEO_UVPLANE_LIMIT(0), dev_priv->fb_available_size - 1);
+		nvWriteVIDEO(dev, NV_PVIDEO_UVPLANE_LIMIT(1), dev_priv->fb_available_size - 1);
+		nvWriteMC(dev, NV_PBUS_POWERCTRL_2, 0);
+
+		NVWriteCRTC(dev, head, NV_PCRTC_CURSOR_CONFIG, regp->cursor_cfg);
+		NVWriteCRTC(dev, head, NV_PCRTC_830, regp->crtc_830);
+		NVWriteCRTC(dev, head, NV_PCRTC_834, regp->crtc_834);
+
+		if (dev_priv->card_type >= NV_30)
+			NVWriteCRTC(dev, head, NV_PCRTC_GPIO_EXT, regp->gpio_ext);
+
+		if (dev_priv->card_type == NV_40) {
+			NVWriteCRTC(dev, head, NV_PCRTC_850, regp->crtc_850);
+
+			reg900 = NVReadRAMDAC(dev, head, NV_PRAMDAC_900);
+			if (regp->crtc_cfg == NV_PCRTC_CONFIG_START_ADDRESS_HSYNC)
+				NVWriteRAMDAC(dev, head, NV_PRAMDAC_900, reg900 | 0x10000);
+			else
+				NVWriteRAMDAC(dev, head, NV_PRAMDAC_900, reg900 & ~0x10000);
+		}
+	}
+
+	NVWriteCRTC(dev, head, NV_PCRTC_CONFIG, regp->crtc_cfg);
+
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_RPC0_INDEX);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_RPC1_INDEX);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_LSR_INDEX);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_PIXEL_INDEX);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_LCD__INDEX);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_HEB__INDEX);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_ENH_INDEX);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_FF_INDEX);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_FFLWM__INDEX);
+	if (dev_priv->card_type >= NV_30)
+		wr_cio_state(dev, head, regp, NV_CIO_CRE_47);
+
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_49);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR2_INDEX);
+	if (dev_priv->card_type == NV_40)
+		nv_fix_nv40_hw_cursor(dev, head);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_ILACE__INDEX);
+
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH3__INDEX);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH4__INDEX);
+	if (dev_priv->card_type >= NV_10) {
+		wr_cio_state(dev, head, regp, NV_CIO_CRE_EBR_INDEX);
+		wr_cio_state(dev, head, regp, NV_CIO_CRE_CSB);
+		wr_cio_state(dev, head, regp, NV_CIO_CRE_4B);
+		wr_cio_state(dev, head, regp, NV_CIO_CRE_TVOUT_LATENCY);
+	}
+	/* NV11 and NV20 stop at 0x52. */
+	if (nv_gf4_disp_arch(dev)) {
+		if (dev_priv->card_type == NV_10) {
+			/* Not waiting for vertical retrace before modifying
+			   CRE_53/CRE_54 causes lockups. */
+			nouveau_wait_until(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x8);
+			nouveau_wait_until(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x0);
+		}
+
+		wr_cio_state(dev, head, regp, NV_CIO_CRE_53);
+		wr_cio_state(dev, head, regp, NV_CIO_CRE_54);
+
+		for (i = 0; i < 0x10; i++)
+			NVWriteVgaCrtc5758(dev, head, i, regp->CR58[i]);
+		wr_cio_state(dev, head, regp, NV_CIO_CRE_59);
+		wr_cio_state(dev, head, regp, NV_CIO_CRE_5B);
+
+		wr_cio_state(dev, head, regp, NV_CIO_CRE_85);
+		wr_cio_state(dev, head, regp, NV_CIO_CRE_86);
+	}
+
+	NVWriteCRTC(dev, head, NV_PCRTC_START, regp->fb_start);
+
+	/* Setting 1 on this value gives you interrupts for every vblank period. */
+	NVWriteCRTC(dev, head, NV_PCRTC_INTR_EN_0, 0);
+	NVWriteCRTC(dev, head, NV_PCRTC_INTR_0, NV_PCRTC_INTR_0_VBLANK);
+}
+
+static void
+nv_save_state_palette(struct drm_device *dev, int head,
+		      struct nv04_mode_state *state)
+{
+	int head_offset = head * NV_PRMDIO_SIZE, i;
+
+	nv_wr08(dev, NV_PRMDIO_PIXEL_MASK + head_offset,
+				NV_PRMDIO_PIXEL_MASK_MASK);
+	nv_wr08(dev, NV_PRMDIO_READ_MODE_ADDRESS + head_offset, 0x0);
+
+	for (i = 0; i < 768; i++) {
+		state->crtc_reg[head].DAC[i] = nv_rd08(dev,
+				NV_PRMDIO_PALETTE_DATA + head_offset);
+	}
+
+	NVSetEnablePalette(dev, head, false);
+}
+
+void
+nouveau_hw_load_state_palette(struct drm_device *dev, int head,
+			      struct nv04_mode_state *state)
+{
+	int head_offset = head * NV_PRMDIO_SIZE, i;
+
+	nv_wr08(dev, NV_PRMDIO_PIXEL_MASK + head_offset,
+				NV_PRMDIO_PIXEL_MASK_MASK);
+	nv_wr08(dev, NV_PRMDIO_WRITE_MODE_ADDRESS + head_offset, 0x0);
+
+	for (i = 0; i < 768; i++) {
+		nv_wr08(dev, NV_PRMDIO_PALETTE_DATA + head_offset,
+				state->crtc_reg[head].DAC[i]);
+	}
+
+	NVSetEnablePalette(dev, head, false);
+}
+
+void nouveau_hw_save_state(struct drm_device *dev, int head,
+			   struct nv04_mode_state *state)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->chipset == 0x11)
+		/* NB: no attempt is made to restore the bad pll later on */
+		nouveau_hw_fix_bad_vpll(dev, head);
+	nv_save_state_ramdac(dev, head, state);
+	nv_save_state_vga(dev, head, state);
+	nv_save_state_palette(dev, head, state);
+	nv_save_state_ext(dev, head, state);
+}
+
+void nouveau_hw_load_state(struct drm_device *dev, int head,
+			   struct nv04_mode_state *state)
+{
+	NVVgaProtect(dev, head, true);
+	nv_load_state_ramdac(dev, head, state);
+	nv_load_state_ext(dev, head, state);
+	nouveau_hw_load_state_palette(dev, head, state);
+	nv_load_state_vga(dev, head, state);
+	NVVgaProtect(dev, head, false);
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.h b/drivers/gpu/drm/nouveau/nouveau_hw.h
new file mode 100644
index 0000000..869130f
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_hw.h
@@ -0,0 +1,455 @@
+/*
+ * Copyright 2008 Stuart Bennett
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __NOUVEAU_HW_H__
+#define __NOUVEAU_HW_H__
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+
+#define MASK(field) ( \
+	(0xffffffff >> (31 - ((1 ? field) - (0 ? field)))) << (0 ? field))
+
+#define XLATE(src, srclowbit, outfield) ( \
+	(((src) >> (srclowbit)) << (0 ? outfield)) & MASK(outfield))
+
+void NVWriteVgaSeq(struct drm_device *, int head, uint8_t index, uint8_t value);
+uint8_t NVReadVgaSeq(struct drm_device *, int head, uint8_t index);
+void NVWriteVgaGr(struct drm_device *, int head, uint8_t index, uint8_t value);
+uint8_t NVReadVgaGr(struct drm_device *, int head, uint8_t index);
+void NVSetOwner(struct drm_device *, int owner);
+void NVBlankScreen(struct drm_device *, int head, bool blank);
+void nouveau_hw_setpll(struct drm_device *, uint32_t reg1,
+		       struct nouveau_pll_vals *pv);
+int nouveau_hw_get_pllvals(struct drm_device *, enum pll_types plltype,
+			   struct nouveau_pll_vals *pllvals);
+int nouveau_hw_pllvals_to_clk(struct nouveau_pll_vals *pllvals);
+int nouveau_hw_get_clock(struct drm_device *, enum pll_types plltype);
+void nouveau_hw_save_vga_fonts(struct drm_device *, bool save);
+void nouveau_hw_save_state(struct drm_device *, int head,
+			   struct nv04_mode_state *state);
+void nouveau_hw_load_state(struct drm_device *, int head,
+			   struct nv04_mode_state *state);
+void nouveau_hw_load_state_palette(struct drm_device *, int head,
+				   struct nv04_mode_state *state);
+
+/* nouveau_calc.c */
+extern void nouveau_calc_arb(struct drm_device *, int vclk, int bpp,
+			     int *burst, int *lwm);
+extern int nouveau_calc_pll_mnp(struct drm_device *, struct pll_lims *pll_lim,
+				int clk, struct nouveau_pll_vals *pv);
+
+static inline uint32_t
+nvReadMC(struct drm_device *dev, uint32_t reg)
+{
+	uint32_t val = nv_rd32(dev, reg);
+	NV_REG_DEBUG(MC, dev, "reg %08x val %08x\n", reg, val);
+	return val;
+}
+
+static inline void
+nvWriteMC(struct drm_device *dev, uint32_t reg, uint32_t val)
+{
+	NV_REG_DEBUG(MC, dev, "reg %08x val %08x\n", reg, val);
+	nv_wr32(dev, reg, val);
+}
+
+static inline uint32_t
+nvReadVIDEO(struct drm_device *dev, uint32_t reg)
+{
+	uint32_t val = nv_rd32(dev, reg);
+	NV_REG_DEBUG(VIDEO, dev, "reg %08x val %08x\n", reg, val);
+	return val;
+}
+
+static inline void
+nvWriteVIDEO(struct drm_device *dev, uint32_t reg, uint32_t val)
+{
+	NV_REG_DEBUG(VIDEO, dev, "reg %08x val %08x\n", reg, val);
+	nv_wr32(dev, reg, val);
+}
+
+static inline uint32_t
+nvReadFB(struct drm_device *dev, uint32_t reg)
+{
+	uint32_t val = nv_rd32(dev, reg);
+	NV_REG_DEBUG(FB, dev, "reg %08x val %08x\n", reg, val);
+	return val;
+}
+
+static inline void
+nvWriteFB(struct drm_device *dev, uint32_t reg, uint32_t val)
+{
+	NV_REG_DEBUG(FB, dev, "reg %08x val %08x\n", reg, val);
+	nv_wr32(dev, reg, val);
+}
+
+static inline uint32_t
+nvReadEXTDEV(struct drm_device *dev, uint32_t reg)
+{
+	uint32_t val = nv_rd32(dev, reg);
+	NV_REG_DEBUG(EXTDEV, dev, "reg %08x val %08x\n", reg, val);
+	return val;
+}
+
+static inline void
+nvWriteEXTDEV(struct drm_device *dev, uint32_t reg, uint32_t val)
+{
+	NV_REG_DEBUG(EXTDEV, dev, "reg %08x val %08x\n", reg, val);
+	nv_wr32(dev, reg, val);
+}
+
+static inline uint32_t NVReadCRTC(struct drm_device *dev,
+					int head, uint32_t reg)
+{
+	uint32_t val;
+	if (head)
+		reg += NV_PCRTC0_SIZE;
+	val = nv_rd32(dev, reg);
+	NV_REG_DEBUG(CRTC, dev, "head %d reg %08x val %08x\n", head, reg, val);
+	return val;
+}
+
+static inline void NVWriteCRTC(struct drm_device *dev,
+					int head, uint32_t reg, uint32_t val)
+{
+	if (head)
+		reg += NV_PCRTC0_SIZE;
+	NV_REG_DEBUG(CRTC, dev, "head %d reg %08x val %08x\n", head, reg, val);
+	nv_wr32(dev, reg, val);
+}
+
+static inline uint32_t NVReadRAMDAC(struct drm_device *dev,
+					int head, uint32_t reg)
+{
+	uint32_t val;
+	if (head)
+		reg += NV_PRAMDAC0_SIZE;
+	val = nv_rd32(dev, reg);
+	NV_REG_DEBUG(RAMDAC, dev, "head %d reg %08x val %08x\n",
+							head, reg, val);
+	return val;
+}
+
+static inline void NVWriteRAMDAC(struct drm_device *dev,
+					int head, uint32_t reg, uint32_t val)
+{
+	if (head)
+		reg += NV_PRAMDAC0_SIZE;
+	NV_REG_DEBUG(RAMDAC, dev, "head %d reg %08x val %08x\n",
+							head, reg, val);
+	nv_wr32(dev, reg, val);
+}
+
+static inline uint8_t nv_read_tmds(struct drm_device *dev,
+					int or, int dl, uint8_t address)
+{
+	int ramdac = (or & OUTPUT_C) >> 2;
+
+	NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL + dl * 8,
+	NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE | address);
+	return NVReadRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_DATA + dl * 8);
+}
+
+static inline void nv_write_tmds(struct drm_device *dev,
+					int or, int dl, uint8_t address,
+					uint8_t data)
+{
+	int ramdac = (or & OUTPUT_C) >> 2;
+
+	NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_DATA + dl * 8, data);
+	NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL + dl * 8, address);
+}
+
+static inline void NVWriteVgaCrtc(struct drm_device *dev,
+					int head, uint8_t index, uint8_t value)
+{
+	NV_REG_DEBUG(VGACRTC, dev, "head %d index 0x%02x data 0x%02x\n",
+							head, index, value);
+	nv_wr08(dev, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index);
+	nv_wr08(dev, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE, value);
+}
+
+static inline uint8_t NVReadVgaCrtc(struct drm_device *dev,
+					int head, uint8_t index)
+{
+	uint8_t val;
+	nv_wr08(dev, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index);
+	val = nv_rd08(dev, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE);
+	NV_REG_DEBUG(VGACRTC, dev, "head %d index 0x%02x data 0x%02x\n",
+							head, index, val);
+	return val;
+}
+
+/* CR57 and CR58 are a fun pair of regs. CR57 provides an index (0-0xf) for CR58
+ * I suspect they in fact do nothing, but are merely a way to carry useful
+ * per-head variables around
+ *
+ * Known uses:
+ * CR57		CR58
+ * 0x00		index to the appropriate dcb entry (or 7f for inactive)
+ * 0x02		dcb entry's "or" value (or 00 for inactive)
+ * 0x03		bit0 set for dual link (LVDS, possibly elsewhere too)
+ * 0x08 or 0x09	pxclk in MHz
+ * 0x0f		laptop panel info -	low nibble for PEXTDEV_BOOT_0 strap
+ * 					high nibble for xlat strap value
+ */
+
+static inline void
+NVWriteVgaCrtc5758(struct drm_device *dev, int head, uint8_t index, uint8_t value)
+{
+	NVWriteVgaCrtc(dev, head, NV_CIO_CRE_57, index);
+	NVWriteVgaCrtc(dev, head, NV_CIO_CRE_58, value);
+}
+
+static inline uint8_t NVReadVgaCrtc5758(struct drm_device *dev, int head, uint8_t index)
+{
+	NVWriteVgaCrtc(dev, head, NV_CIO_CRE_57, index);
+	return NVReadVgaCrtc(dev, head, NV_CIO_CRE_58);
+}
+
+static inline uint8_t NVReadPRMVIO(struct drm_device *dev,
+					int head, uint32_t reg)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint8_t val;
+
+	/* Only NV4x have two pvio ranges; other twoHeads cards MUST call
+	 * NVSetOwner for the relevant head to be programmed */
+	if (head && dev_priv->card_type == NV_40)
+		reg += NV_PRMVIO_SIZE;
+
+	val = nv_rd08(dev, reg);
+	NV_REG_DEBUG(RMVIO, dev, "head %d reg %08x val %02x\n", head, reg, val);
+	return val;
+}
+
+static inline void NVWritePRMVIO(struct drm_device *dev,
+					int head, uint32_t reg, uint8_t value)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	/* Only NV4x have two pvio ranges; other twoHeads cards MUST call
+	 * NVSetOwner for the relevant head to be programmed */
+	if (head && dev_priv->card_type == NV_40)
+		reg += NV_PRMVIO_SIZE;
+
+	NV_REG_DEBUG(RMVIO, dev, "head %d reg %08x val %02x\n",
+						head, reg, value);
+	nv_wr08(dev, reg, value);
+}
+
+static inline void NVSetEnablePalette(struct drm_device *dev, int head, bool enable)
+{
+	nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
+	nv_wr08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, enable ? 0 : 0x20);
+}
+
+static inline bool NVGetEnablePalette(struct drm_device *dev, int head)
+{
+	nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
+	return !(nv_rd08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE) & 0x20);
+}
+
+static inline void NVWriteVgaAttr(struct drm_device *dev,
+					int head, uint8_t index, uint8_t value)
+{
+	if (NVGetEnablePalette(dev, head))
+		index &= ~0x20;
+	else
+		index |= 0x20;
+
+	nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
+	NV_REG_DEBUG(VGAATTR, dev, "head %d index 0x%02x data 0x%02x\n",
+							head, index, value);
+	nv_wr08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index);
+	nv_wr08(dev, NV_PRMCIO_AR__WRITE + head * NV_PRMCIO_SIZE, value);
+}
+
+static inline uint8_t NVReadVgaAttr(struct drm_device *dev,
+					int head, uint8_t index)
+{
+	uint8_t val;
+	if (NVGetEnablePalette(dev, head))
+		index &= ~0x20;
+	else
+		index |= 0x20;
+
+	nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
+	nv_wr08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index);
+	val = nv_rd08(dev, NV_PRMCIO_AR__READ + head * NV_PRMCIO_SIZE);
+	NV_REG_DEBUG(VGAATTR, dev, "head %d index 0x%02x data 0x%02x\n",
+							head, index, val);
+	return val;
+}
+
+static inline void NVVgaSeqReset(struct drm_device *dev, int head, bool start)
+{
+	NVWriteVgaSeq(dev, head, NV_VIO_SR_RESET_INDEX, start ? 0x1 : 0x3);
+}
+
+static inline void NVVgaProtect(struct drm_device *dev, int head, bool protect)
+{
+	uint8_t seq1 = NVReadVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX);
+
+	if (protect) {
+		NVVgaSeqReset(dev, head, true);
+		NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 | 0x20);
+	} else {
+		/* Reenable sequencer, then turn on screen */
+		NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 & ~0x20);   /* reenable display */
+		NVVgaSeqReset(dev, head, false);
+	}
+	NVSetEnablePalette(dev, head, protect);
+}
+
+static inline bool
+nv_heads_tied(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->chipset == 0x11)
+		return !!(nvReadMC(dev, NV_PBUS_DEBUG_1) & (1 << 28));
+
+	return NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44) & 0x4;
+}
+
+/* makes cr0-7 on the specified head read-only */
+static inline bool
+nv_lock_vga_crtc_base(struct drm_device *dev, int head, bool lock)
+{
+	uint8_t cr11 = NVReadVgaCrtc(dev, head, NV_CIO_CR_VRE_INDEX);
+	bool waslocked = cr11 & 0x80;
+
+	if (lock)
+		cr11 |= 0x80;
+	else
+		cr11 &= ~0x80;
+	NVWriteVgaCrtc(dev, head, NV_CIO_CR_VRE_INDEX, cr11);
+
+	return waslocked;
+}
+
+static inline void
+nv_lock_vga_crtc_shadow(struct drm_device *dev, int head, int lock)
+{
+	/* shadow lock: connects 0x60?3d? regs to "real" 0x3d? regs
+	 * bit7: unlocks HDT, HBS, HBE, HRS, HRE, HEB
+	 * bit6: seems to have some effect on CR09 (double scan, VBS_9)
+	 * bit5: unlocks HDE
+	 * bit4: unlocks VDE
+	 * bit3: unlocks VDT, OVL, VRS, ?VRE?, VBS, VBE, LSR, EBR
+	 * bit2: same as bit 1 of 0x60?804
+	 * bit0: same as bit 0 of 0x60?804
+	 */
+
+	uint8_t cr21 = lock;
+
+	if (lock < 0)
+		/* 0xfa is generic "unlock all" mask */
+		cr21 = NVReadVgaCrtc(dev, head, NV_CIO_CRE_21) | 0xfa;
+
+	NVWriteVgaCrtc(dev, head, NV_CIO_CRE_21, cr21);
+}
+
+/* renders the extended crtc regs (cr19+) on all crtcs impervious:
+ * immutable and unreadable
+ */
+static inline bool
+NVLockVgaCrtcs(struct drm_device *dev, bool lock)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	bool waslocked = !NVReadVgaCrtc(dev, 0, NV_CIO_SR_LOCK_INDEX);
+
+	NVWriteVgaCrtc(dev, 0, NV_CIO_SR_LOCK_INDEX,
+		       lock ? NV_CIO_SR_LOCK_VALUE : NV_CIO_SR_UNLOCK_RW_VALUE);
+	/* NV11 has independently lockable extended crtcs, except when tied */
+	if (dev_priv->chipset == 0x11 && !nv_heads_tied(dev))
+		NVWriteVgaCrtc(dev, 1, NV_CIO_SR_LOCK_INDEX,
+			       lock ? NV_CIO_SR_LOCK_VALUE :
+				      NV_CIO_SR_UNLOCK_RW_VALUE);
+
+	return waslocked;
+}
+
+/* nv04 cursor max dimensions of 32x32 (A1R5G5B5) */
+#define NV04_CURSOR_SIZE 32
+/* limit nv10 cursors to 64x64 (ARGB8) (we could go to 64x255) */
+#define NV10_CURSOR_SIZE 64
+
+static inline int nv_cursor_width(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	return dev_priv->card_type >= NV_10 ? NV10_CURSOR_SIZE : NV04_CURSOR_SIZE;
+}
+
+static inline void
+nv_fix_nv40_hw_cursor(struct drm_device *dev, int head)
+{
+	/* on some nv40 (such as the "true" (in the NV_PFB_BOOT_0 sense) nv40,
+	 * the gf6800gt) a hardware bug requires a write to PRAMDAC_CURSOR_POS
+	 * for changes to the CRTC CURCTL regs to take effect, whether changing
+	 * the pixmap location, or just showing/hiding the cursor
+	 */
+	uint32_t curpos = NVReadRAMDAC(dev, head, NV_PRAMDAC_CU_START_POS);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_CU_START_POS, curpos);
+}
+
+static inline void
+nv_show_cursor(struct drm_device *dev, int head, bool show)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint8_t *curctl1 =
+		&dev_priv->mode_reg.crtc_reg[head].CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX];
+
+	if (show)
+		*curctl1 |= MASK(NV_CIO_CRE_HCUR_ADDR1_ENABLE);
+	else
+		*curctl1 &= ~MASK(NV_CIO_CRE_HCUR_ADDR1_ENABLE);
+	NVWriteVgaCrtc(dev, head, NV_CIO_CRE_HCUR_ADDR1_INDEX, *curctl1);
+
+	if (dev_priv->card_type == NV_40)
+		nv_fix_nv40_hw_cursor(dev, head);
+}
+
+static inline uint32_t
+nv_pitch_align(struct drm_device *dev, uint32_t width, int bpp)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int mask;
+
+	if (bpp == 15)
+		bpp = 16;
+	if (bpp == 24)
+		bpp = 8;
+
+	/* Alignment requirements taken from the Haiku driver */
+	if (dev_priv->card_type == NV_04)
+		mask = 128 / bpp - 1;
+	else
+		mask = 512 / bpp - 1;
+
+	return (width + mask) & ~mask;
+}
+
+#endif	/* __NOUVEAU_HW_H__ */
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c
new file mode 100644
index 0000000..70e994d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright 2009 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_i2c.h"
+#include "nouveau_hw.h"
+
+static void
+nv04_i2c_setscl(void *data, int state)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+	uint8_t val;
+
+	val = (NVReadVgaCrtc(dev, 0, i2c->wr) & 0xd0) | (state ? 0x20 : 0);
+	NVWriteVgaCrtc(dev, 0, i2c->wr, val | 0x01);
+}
+
+static void
+nv04_i2c_setsda(void *data, int state)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+	uint8_t val;
+
+	val = (NVReadVgaCrtc(dev, 0, i2c->wr) & 0xe0) | (state ? 0x10 : 0);
+	NVWriteVgaCrtc(dev, 0, i2c->wr, val | 0x01);
+}
+
+static int
+nv04_i2c_getscl(void *data)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+
+	return !!(NVReadVgaCrtc(dev, 0, i2c->rd) & 4);
+}
+
+static int
+nv04_i2c_getsda(void *data)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+
+	return !!(NVReadVgaCrtc(dev, 0, i2c->rd) & 8);
+}
+
+static void
+nv4e_i2c_setscl(void *data, int state)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+	uint8_t val;
+
+	val = (nv_rd32(dev, i2c->wr) & 0xd0) | (state ? 0x20 : 0);
+	nv_wr32(dev, i2c->wr, val | 0x01);
+}
+
+static void
+nv4e_i2c_setsda(void *data, int state)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+	uint8_t val;
+
+	val = (nv_rd32(dev, i2c->wr) & 0xe0) | (state ? 0x10 : 0);
+	nv_wr32(dev, i2c->wr, val | 0x01);
+}
+
+static int
+nv4e_i2c_getscl(void *data)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+
+	return !!((nv_rd32(dev, i2c->rd) >> 16) & 4);
+}
+
+static int
+nv4e_i2c_getsda(void *data)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+
+	return !!((nv_rd32(dev, i2c->rd) >> 16) & 8);
+}
+
+static int
+nv50_i2c_getscl(void *data)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+
+	return !!(nv_rd32(dev, i2c->rd) & 1);
+}
+
+
+static int
+nv50_i2c_getsda(void *data)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+
+	return !!(nv_rd32(dev, i2c->rd) & 2);
+}
+
+static void
+nv50_i2c_setscl(void *data, int state)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+
+	nv_wr32(dev, i2c->wr, 4 | (i2c->data ? 2 : 0) | (state ? 1 : 0));
+}
+
+static void
+nv50_i2c_setsda(void *data, int state)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+
+	nv_wr32(dev, i2c->wr,
+			(nv_rd32(dev, i2c->rd) & 1) | 4 | (state ? 2 : 0));
+	i2c->data = state;
+}
+
+static const uint32_t nv50_i2c_port[] = {
+	0x00e138, 0x00e150, 0x00e168, 0x00e180,
+	0x00e254, 0x00e274, 0x00e764, 0x00e780,
+	0x00e79c, 0x00e7b8
+};
+#define NV50_I2C_PORTS ARRAY_SIZE(nv50_i2c_port)
+
+int
+nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_i2c_chan *i2c;
+	int ret;
+
+	if (entry->chan)
+		return -EEXIST;
+
+	if (dev_priv->card_type == NV_50 && entry->read >= NV50_I2C_PORTS) {
+		NV_ERROR(dev, "unknown i2c port %d\n", entry->read);
+		return -EINVAL;
+	}
+
+	i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
+	if (i2c == NULL)
+		return -ENOMEM;
+
+	switch (entry->port_type) {
+	case 0:
+		i2c->algo.bit.setsda = nv04_i2c_setsda;
+		i2c->algo.bit.setscl = nv04_i2c_setscl;
+		i2c->algo.bit.getsda = nv04_i2c_getsda;
+		i2c->algo.bit.getscl = nv04_i2c_getscl;
+		i2c->rd = entry->read;
+		i2c->wr = entry->write;
+		break;
+	case 4:
+		i2c->algo.bit.setsda = nv4e_i2c_setsda;
+		i2c->algo.bit.setscl = nv4e_i2c_setscl;
+		i2c->algo.bit.getsda = nv4e_i2c_getsda;
+		i2c->algo.bit.getscl = nv4e_i2c_getscl;
+		i2c->rd = 0x600800 + entry->read;
+		i2c->wr = 0x600800 + entry->write;
+		break;
+	case 5:
+		i2c->algo.bit.setsda = nv50_i2c_setsda;
+		i2c->algo.bit.setscl = nv50_i2c_setscl;
+		i2c->algo.bit.getsda = nv50_i2c_getsda;
+		i2c->algo.bit.getscl = nv50_i2c_getscl;
+		i2c->rd = nv50_i2c_port[entry->read];
+		i2c->wr = i2c->rd;
+		break;
+	case 6:
+		i2c->rd = entry->read;
+		i2c->wr = entry->write;
+		break;
+	default:
+		NV_ERROR(dev, "DCB I2C port type %d unknown\n",
+			 entry->port_type);
+		kfree(i2c);
+		return -EINVAL;
+	}
+
+	snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
+		 "nouveau-%s-%d", pci_name(dev->pdev), index);
+	i2c->adapter.owner = THIS_MODULE;
+	i2c->adapter.dev.parent = &dev->pdev->dev;
+	i2c->dev = dev;
+	i2c_set_adapdata(&i2c->adapter, i2c);
+
+	if (entry->port_type < 6) {
+		i2c->adapter.algo_data = &i2c->algo.bit;
+		i2c->algo.bit.udelay = 40;
+		i2c->algo.bit.timeout = usecs_to_jiffies(5000);
+		i2c->algo.bit.data = i2c;
+		ret = i2c_bit_add_bus(&i2c->adapter);
+	} else {
+		i2c->adapter.algo_data = &i2c->algo.dp;
+		i2c->algo.dp.running = false;
+		i2c->algo.dp.address = 0;
+		i2c->algo.dp.aux_ch = nouveau_dp_i2c_aux_ch;
+		ret = i2c_dp_aux_add_bus(&i2c->adapter);
+	}
+
+	if (ret) {
+		NV_ERROR(dev, "Failed to register i2c %d\n", index);
+		kfree(i2c);
+		return ret;
+	}
+
+	entry->chan = i2c;
+	return 0;
+}
+
+void
+nouveau_i2c_fini(struct drm_device *dev, struct dcb_i2c_entry *entry)
+{
+	if (!entry->chan)
+		return;
+
+	i2c_del_adapter(&entry->chan->adapter);
+	kfree(entry->chan);
+	entry->chan = NULL;
+}
+
+struct nouveau_i2c_chan *
+nouveau_i2c_find(struct drm_device *dev, int index)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+
+	if (index > DCB_MAX_NUM_I2C_ENTRIES)
+		return NULL;
+
+	if (!bios->bdcb.dcb.i2c[index].chan) {
+		if (nouveau_i2c_init(dev, &bios->bdcb.dcb.i2c[index], index))
+			return NULL;
+	}
+
+	return bios->bdcb.dcb.i2c[index].chan;
+}
+
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.h b/drivers/gpu/drm/nouveau/nouveau_i2c.h
new file mode 100644
index 0000000..c8eaf7a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_i2c.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2009 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __NOUVEAU_I2C_H__
+#define __NOUVEAU_I2C_H__
+
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <linux/i2c-algo-bit.h>
+#include "drm_dp_helper.h"
+
+struct dcb_i2c_entry;
+
+struct nouveau_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;
+	unsigned rd;
+	unsigned wr;
+	unsigned data;
+};
+
+int nouveau_i2c_init(struct drm_device *, struct dcb_i2c_entry *, int index);
+void nouveau_i2c_fini(struct drm_device *, struct dcb_i2c_entry *);
+struct nouveau_i2c_chan *nouveau_i2c_find(struct drm_device *, int index);
+
+int nouveau_dp_i2c_aux_ch(struct i2c_adapter *, int mode, uint8_t write_byte,
+			  uint8_t *read_byte);
+
+#endif /* __NOUVEAU_I2C_H__ */
diff --git a/drivers/gpu/drm/nouveau/nouveau_ioc32.c b/drivers/gpu/drm/nouveau/nouveau_ioc32.c
new file mode 100644
index 0000000..a2c30f4
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_ioc32.c
@@ -0,0 +1,72 @@
+/**
+ * \file mga_ioc32.c
+ *
+ * 32-bit ioctl compatibility routines for the MGA DRM.
+ *
+ * \author Dave Airlie <airlied@linux.ie> with code from patches by Egbert Eich
+ *
+ *
+ * Copyright (C) Paul Mackerras 2005
+ * Copyright (C) Egbert Eich 2003,2004
+ * Copyright (C) Dave Airlie 2005
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <linux/compat.h>
+
+#include "drmP.h"
+#include "drm.h"
+
+#include "nouveau_drv.h"
+
+/**
+ * Called whenever a 32-bit process running under a 64-bit kernel
+ * performs an ioctl on /dev/dri/card<n>.
+ *
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or negative number on failure.
+ */
+long nouveau_compat_ioctl(struct file *filp, unsigned int cmd,
+			 unsigned long arg)
+{
+	unsigned int nr = DRM_IOCTL_NR(cmd);
+	drm_ioctl_compat_t *fn = NULL;
+	int ret;
+
+	if (nr < DRM_COMMAND_BASE)
+		return drm_compat_ioctl(filp, cmd, arg);
+
+#if 0
+	if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls))
+		fn = nouveau_compat_ioctls[nr - DRM_COMMAND_BASE];
+#endif
+	lock_kernel();	  /* XXX for now */
+	if (fn != NULL)
+		ret = (*fn)(filp, cmd, arg);
+	else
+		ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+	unlock_kernel();
+
+	return ret;
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c
new file mode 100644
index 0000000..370c72c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_irq.c
@@ -0,0 +1,702 @@
+/*
+ * Copyright (C) 2006 Ben Skeggs.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/*
+ * Authors:
+ *   Ben Skeggs <darktama@iinet.net.au>
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_reg.h"
+#include <linux/ratelimit.h>
+
+/* needed for hotplug irq */
+#include "nouveau_connector.h"
+#include "nv50_display.h"
+
+void
+nouveau_irq_preinstall(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	/* Master disable */
+	nv_wr32(dev, NV03_PMC_INTR_EN_0, 0);
+
+	if (dev_priv->card_type == NV_50) {
+		INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh);
+		INIT_LIST_HEAD(&dev_priv->vbl_waiting);
+	}
+}
+
+int
+nouveau_irq_postinstall(struct drm_device *dev)
+{
+	/* Master enable */
+	nv_wr32(dev, NV03_PMC_INTR_EN_0, NV_PMC_INTR_EN_0_MASTER_ENABLE);
+	return 0;
+}
+
+void
+nouveau_irq_uninstall(struct drm_device *dev)
+{
+	/* Master disable */
+	nv_wr32(dev, NV03_PMC_INTR_EN_0, 0);
+}
+
+static int
+nouveau_call_method(struct nouveau_channel *chan, int class, int mthd, int data)
+{
+	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
+	struct nouveau_pgraph_object_method *grm;
+	struct nouveau_pgraph_object_class *grc;
+
+	grc = dev_priv->engine.graph.grclass;
+	while (grc->id) {
+		if (grc->id == class)
+			break;
+		grc++;
+	}
+
+	if (grc->id != class || !grc->methods)
+		return -ENOENT;
+
+	grm = grc->methods;
+	while (grm->id) {
+		if (grm->id == mthd)
+			return grm->exec(chan, class, mthd, data);
+		grm++;
+	}
+
+	return -ENOENT;
+}
+
+static bool
+nouveau_fifo_swmthd(struct nouveau_channel *chan, uint32_t addr, uint32_t data)
+{
+	struct drm_device *dev = chan->dev;
+	const int subc = (addr >> 13) & 0x7;
+	const int mthd = addr & 0x1ffc;
+
+	if (mthd == 0x0000) {
+		struct nouveau_gpuobj_ref *ref = NULL;
+
+		if (nouveau_gpuobj_ref_find(chan, data, &ref))
+			return false;
+
+		if (ref->gpuobj->engine != NVOBJ_ENGINE_SW)
+			return false;
+
+		chan->sw_subchannel[subc] = ref->gpuobj->class;
+		nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_rd32(dev,
+			NV04_PFIFO_CACHE1_ENGINE) & ~(0xf << subc * 4));
+		return true;
+	}
+
+	/* hw object */
+	if (nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE) & (1 << (subc*4)))
+		return false;
+
+	if (nouveau_call_method(chan, chan->sw_subchannel[subc], mthd, data))
+		return false;
+
+	return true;
+}
+
+static void
+nouveau_fifo_irq_handler(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
+	uint32_t status, reassign;
+	int cnt = 0;
+
+	reassign = nv_rd32(dev, NV03_PFIFO_CACHES) & 1;
+	while ((status = nv_rd32(dev, NV03_PFIFO_INTR_0)) && (cnt++ < 100)) {
+		struct nouveau_channel *chan = NULL;
+		uint32_t chid, get;
+
+		nv_wr32(dev, NV03_PFIFO_CACHES, 0);
+
+		chid = engine->fifo.channel_id(dev);
+		if (chid >= 0 && chid < engine->fifo.channels)
+			chan = dev_priv->fifos[chid];
+		get  = nv_rd32(dev, NV03_PFIFO_CACHE1_GET);
+
+		if (status & NV_PFIFO_INTR_CACHE_ERROR) {
+			uint32_t mthd, data;
+			int ptr;
+
+			/* NV_PFIFO_CACHE1_GET actually goes to 0xffc before
+			 * wrapping on my G80 chips, but CACHE1 isn't big
+			 * enough for this much data.. Tests show that it
+			 * wraps around to the start at GET=0x800.. No clue
+			 * as to why..
+			 */
+			ptr = (get & 0x7ff) >> 2;
+
+			if (dev_priv->card_type < NV_40) {
+				mthd = nv_rd32(dev,
+					NV04_PFIFO_CACHE1_METHOD(ptr));
+				data = nv_rd32(dev,
+					NV04_PFIFO_CACHE1_DATA(ptr));
+			} else {
+				mthd = nv_rd32(dev,
+					NV40_PFIFO_CACHE1_METHOD(ptr));
+				data = nv_rd32(dev,
+					NV40_PFIFO_CACHE1_DATA(ptr));
+			}
+
+			if (!chan || !nouveau_fifo_swmthd(chan, mthd, data)) {
+				NV_INFO(dev, "PFIFO_CACHE_ERROR - Ch %d/%d "
+					     "Mthd 0x%04x Data 0x%08x\n",
+					chid, (mthd >> 13) & 7, mthd & 0x1ffc,
+					data);
+			}
+
+			nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, 0);
+			nv_wr32(dev, NV03_PFIFO_INTR_0,
+						NV_PFIFO_INTR_CACHE_ERROR);
+
+			nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0,
+				nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH0) & ~1);
+			nv_wr32(dev, NV03_PFIFO_CACHE1_GET, get + 4);
+			nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0,
+				nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH0) | 1);
+			nv_wr32(dev, NV04_PFIFO_CACHE1_HASH, 0);
+
+			nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH,
+				nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUSH) | 1);
+			nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1);
+
+			status &= ~NV_PFIFO_INTR_CACHE_ERROR;
+		}
+
+		if (status & NV_PFIFO_INTR_DMA_PUSHER) {
+			NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d\n", chid);
+
+			status &= ~NV_PFIFO_INTR_DMA_PUSHER;
+			nv_wr32(dev, NV03_PFIFO_INTR_0,
+						NV_PFIFO_INTR_DMA_PUSHER);
+
+			nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_STATE, 0x00000000);
+			if (nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT) != get)
+				nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET,
+								get + 4);
+		}
+
+		if (status) {
+			NV_INFO(dev, "PFIFO_INTR 0x%08x - Ch %d\n",
+				status, chid);
+			nv_wr32(dev, NV03_PFIFO_INTR_0, status);
+			status = 0;
+		}
+
+		nv_wr32(dev, NV03_PFIFO_CACHES, reassign);
+	}
+
+	if (status) {
+		NV_INFO(dev, "PFIFO still angry after %d spins, halt\n", cnt);
+		nv_wr32(dev, 0x2140, 0);
+		nv_wr32(dev, 0x140, 0);
+	}
+
+	nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PFIFO_PENDING);
+}
+
+struct nouveau_bitfield_names {
+	uint32_t mask;
+	const char *name;
+};
+
+static struct nouveau_bitfield_names nstatus_names[] =
+{
+	{ NV04_PGRAPH_NSTATUS_STATE_IN_USE,       "STATE_IN_USE" },
+	{ NV04_PGRAPH_NSTATUS_INVALID_STATE,      "INVALID_STATE" },
+	{ NV04_PGRAPH_NSTATUS_BAD_ARGUMENT,       "BAD_ARGUMENT" },
+	{ NV04_PGRAPH_NSTATUS_PROTECTION_FAULT,   "PROTECTION_FAULT" }
+};
+
+static struct nouveau_bitfield_names nstatus_names_nv10[] =
+{
+	{ NV10_PGRAPH_NSTATUS_STATE_IN_USE,       "STATE_IN_USE" },
+	{ NV10_PGRAPH_NSTATUS_INVALID_STATE,      "INVALID_STATE" },
+	{ NV10_PGRAPH_NSTATUS_BAD_ARGUMENT,       "BAD_ARGUMENT" },
+	{ NV10_PGRAPH_NSTATUS_PROTECTION_FAULT,   "PROTECTION_FAULT" }
+};
+
+static struct nouveau_bitfield_names nsource_names[] =
+{
+	{ NV03_PGRAPH_NSOURCE_NOTIFICATION,       "NOTIFICATION" },
+	{ NV03_PGRAPH_NSOURCE_DATA_ERROR,         "DATA_ERROR" },
+	{ NV03_PGRAPH_NSOURCE_PROTECTION_ERROR,   "PROTECTION_ERROR" },
+	{ NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION,    "RANGE_EXCEPTION" },
+	{ NV03_PGRAPH_NSOURCE_LIMIT_COLOR,        "LIMIT_COLOR" },
+	{ NV03_PGRAPH_NSOURCE_LIMIT_ZETA,         "LIMIT_ZETA" },
+	{ NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD,       "ILLEGAL_MTHD" },
+	{ NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION,   "DMA_R_PROTECTION" },
+	{ NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION,   "DMA_W_PROTECTION" },
+	{ NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION,   "FORMAT_EXCEPTION" },
+	{ NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION,    "PATCH_EXCEPTION" },
+	{ NV03_PGRAPH_NSOURCE_STATE_INVALID,      "STATE_INVALID" },
+	{ NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY,      "DOUBLE_NOTIFY" },
+	{ NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE,      "NOTIFY_IN_USE" },
+	{ NV03_PGRAPH_NSOURCE_METHOD_CNT,         "METHOD_CNT" },
+	{ NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION,   "BFR_NOTIFICATION" },
+	{ NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION, "DMA_VTX_PROTECTION" },
+	{ NV03_PGRAPH_NSOURCE_DMA_WIDTH_A,        "DMA_WIDTH_A" },
+	{ NV03_PGRAPH_NSOURCE_DMA_WIDTH_B,        "DMA_WIDTH_B" },
+};
+
+static void
+nouveau_print_bitfield_names_(uint32_t value,
+				const struct nouveau_bitfield_names *namelist,
+				const int namelist_len)
+{
+	/*
+	 * Caller must have already printed the KERN_* log level for us.
+	 * Also the caller is responsible for adding the newline.
+	 */
+	int i;
+	for (i = 0; i < namelist_len; ++i) {
+		uint32_t mask = namelist[i].mask;
+		if (value & mask) {
+			printk(" %s", namelist[i].name);
+			value &= ~mask;
+		}
+	}
+	if (value)
+		printk(" (unknown bits 0x%08x)", value);
+}
+#define nouveau_print_bitfield_names(val, namelist) \
+	nouveau_print_bitfield_names_((val), (namelist), ARRAY_SIZE(namelist))
+
+
+static int
+nouveau_graph_chid_from_grctx(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t inst;
+	int i;
+
+	if (dev_priv->card_type < NV_40)
+		return dev_priv->engine.fifo.channels;
+	else
+	if (dev_priv->card_type < NV_50) {
+		inst = (nv_rd32(dev, 0x40032c) & 0xfffff) << 4;
+
+		for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
+			struct nouveau_channel *chan = dev_priv->fifos[i];
+
+			if (!chan || !chan->ramin_grctx)
+				continue;
+
+			if (inst == chan->ramin_grctx->instance)
+				break;
+		}
+	} else {
+		inst = (nv_rd32(dev, 0x40032c) & 0xfffff) << 12;
+
+		for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
+			struct nouveau_channel *chan = dev_priv->fifos[i];
+
+			if (!chan || !chan->ramin)
+				continue;
+
+			if (inst == chan->ramin->instance)
+				break;
+		}
+	}
+
+
+	return i;
+}
+
+static int
+nouveau_graph_trapped_channel(struct drm_device *dev, int *channel_ret)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
+	int channel;
+
+	if (dev_priv->card_type < NV_10)
+		channel = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 24) & 0xf;
+	else
+	if (dev_priv->card_type < NV_40)
+		channel = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f;
+	else
+		channel = nouveau_graph_chid_from_grctx(dev);
+
+	if (channel >= engine->fifo.channels || !dev_priv->fifos[channel]) {
+		NV_ERROR(dev, "AIII, invalid/inactive channel id %d\n", channel);
+		return -EINVAL;
+	}
+
+	*channel_ret = channel;
+	return 0;
+}
+
+struct nouveau_pgraph_trap {
+	int channel;
+	int class;
+	int subc, mthd, size;
+	uint32_t data, data2;
+	uint32_t nsource, nstatus;
+};
+
+static void
+nouveau_graph_trap_info(struct drm_device *dev,
+			struct nouveau_pgraph_trap *trap)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t address;
+
+	trap->nsource = trap->nstatus = 0;
+	if (dev_priv->card_type < NV_50) {
+		trap->nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
+		trap->nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS);
+	}
+
+	if (nouveau_graph_trapped_channel(dev, &trap->channel))
+		trap->channel = -1;
+	address = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR);
+
+	trap->mthd = address & 0x1FFC;
+	trap->data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA);
+	if (dev_priv->card_type < NV_10) {
+		trap->subc  = (address >> 13) & 0x7;
+	} else {
+		trap->subc  = (address >> 16) & 0x7;
+		trap->data2 = nv_rd32(dev, NV10_PGRAPH_TRAPPED_DATA_HIGH);
+	}
+
+	if (dev_priv->card_type < NV_10)
+		trap->class = nv_rd32(dev, 0x400180 + trap->subc*4) & 0xFF;
+	else if (dev_priv->card_type < NV_40)
+		trap->class = nv_rd32(dev, 0x400160 + trap->subc*4) & 0xFFF;
+	else if (dev_priv->card_type < NV_50)
+		trap->class = nv_rd32(dev, 0x400160 + trap->subc*4) & 0xFFFF;
+	else
+		trap->class = nv_rd32(dev, 0x400814);
+}
+
+static void
+nouveau_graph_dump_trap_info(struct drm_device *dev, const char *id,
+			     struct nouveau_pgraph_trap *trap)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t nsource = trap->nsource, nstatus = trap->nstatus;
+
+	NV_INFO(dev, "%s - nSource:", id);
+	nouveau_print_bitfield_names(nsource, nsource_names);
+	printk(", nStatus:");
+	if (dev_priv->card_type < NV_10)
+		nouveau_print_bitfield_names(nstatus, nstatus_names);
+	else
+		nouveau_print_bitfield_names(nstatus, nstatus_names_nv10);
+	printk("\n");
+
+	NV_INFO(dev, "%s - Ch %d/%d Class 0x%04x Mthd 0x%04x "
+					"Data 0x%08x:0x%08x\n",
+					id, trap->channel, trap->subc,
+					trap->class, trap->mthd,
+					trap->data2, trap->data);
+}
+
+static int
+nouveau_pgraph_intr_swmthd(struct drm_device *dev,
+			   struct nouveau_pgraph_trap *trap)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (trap->channel < 0 ||
+	    trap->channel >= dev_priv->engine.fifo.channels ||
+	    !dev_priv->fifos[trap->channel])
+		return -ENODEV;
+
+	return nouveau_call_method(dev_priv->fifos[trap->channel],
+				   trap->class, trap->mthd, trap->data);
+}
+
+static inline void
+nouveau_pgraph_intr_notify(struct drm_device *dev, uint32_t nsource)
+{
+	struct nouveau_pgraph_trap trap;
+	int unhandled = 0;
+
+	nouveau_graph_trap_info(dev, &trap);
+
+	if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) {
+		if (nouveau_pgraph_intr_swmthd(dev, &trap))
+			unhandled = 1;
+	} else {
+		unhandled = 1;
+	}
+
+	if (unhandled)
+		nouveau_graph_dump_trap_info(dev, "PGRAPH_NOTIFY", &trap);
+}
+
+static DEFINE_RATELIMIT_STATE(nouveau_ratelimit_state, 3 * HZ, 20);
+
+static int nouveau_ratelimit(void)
+{
+	return __ratelimit(&nouveau_ratelimit_state);
+}
+
+
+static inline void
+nouveau_pgraph_intr_error(struct drm_device *dev, uint32_t nsource)
+{
+	struct nouveau_pgraph_trap trap;
+	int unhandled = 0;
+
+	nouveau_graph_trap_info(dev, &trap);
+	trap.nsource = nsource;
+
+	if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) {
+		if (nouveau_pgraph_intr_swmthd(dev, &trap))
+			unhandled = 1;
+	} else {
+		unhandled = 1;
+	}
+
+	if (unhandled && nouveau_ratelimit())
+		nouveau_graph_dump_trap_info(dev, "PGRAPH_ERROR", &trap);
+}
+
+static inline void
+nouveau_pgraph_intr_context_switch(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
+	uint32_t chid;
+
+	chid = engine->fifo.channel_id(dev);
+	NV_DEBUG(dev, "PGRAPH context switch interrupt channel %x\n", chid);
+
+	switch (dev_priv->card_type) {
+	case NV_04:
+		nv04_graph_context_switch(dev);
+		break;
+	case NV_10:
+		nv10_graph_context_switch(dev);
+		break;
+	default:
+		NV_ERROR(dev, "Context switch not implemented\n");
+		break;
+	}
+}
+
+static void
+nouveau_pgraph_irq_handler(struct drm_device *dev)
+{
+	uint32_t status;
+
+	while ((status = nv_rd32(dev, NV03_PGRAPH_INTR))) {
+		uint32_t nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
+
+		if (status & NV_PGRAPH_INTR_NOTIFY) {
+			nouveau_pgraph_intr_notify(dev, nsource);
+
+			status &= ~NV_PGRAPH_INTR_NOTIFY;
+			nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_NOTIFY);
+		}
+
+		if (status & NV_PGRAPH_INTR_ERROR) {
+			nouveau_pgraph_intr_error(dev, nsource);
+
+			status &= ~NV_PGRAPH_INTR_ERROR;
+			nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_ERROR);
+		}
+
+		if (status & NV_PGRAPH_INTR_CONTEXT_SWITCH) {
+			nouveau_pgraph_intr_context_switch(dev);
+
+			status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
+			nv_wr32(dev, NV03_PGRAPH_INTR,
+				 NV_PGRAPH_INTR_CONTEXT_SWITCH);
+		}
+
+		if (status) {
+			NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n", status);
+			nv_wr32(dev, NV03_PGRAPH_INTR, status);
+		}
+
+		if ((nv_rd32(dev, NV04_PGRAPH_FIFO) & (1 << 0)) == 0)
+			nv_wr32(dev, NV04_PGRAPH_FIFO, 1);
+	}
+
+	nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING);
+}
+
+static void
+nv50_pgraph_irq_handler(struct drm_device *dev)
+{
+	uint32_t status, nsource;
+
+	status = nv_rd32(dev, NV03_PGRAPH_INTR);
+	nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
+
+	if (status & 0x00000001) {
+		nouveau_pgraph_intr_notify(dev, nsource);
+		status &= ~0x00000001;
+		nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000001);
+	}
+
+	if (status & 0x00000010) {
+		nouveau_pgraph_intr_error(dev, nsource |
+					  NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD);
+
+		status &= ~0x00000010;
+		nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000010);
+	}
+
+	if (status & 0x00001000) {
+		nv_wr32(dev, 0x400500, 0x00000000);
+		nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
+		nv_wr32(dev, NV40_PGRAPH_INTR_EN, nv_rd32(dev,
+			NV40_PGRAPH_INTR_EN) & ~NV_PGRAPH_INTR_CONTEXT_SWITCH);
+		nv_wr32(dev, 0x400500, 0x00010001);
+
+		nv50_graph_context_switch(dev);
+
+		status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
+	}
+
+	if (status & 0x00100000) {
+		nouveau_pgraph_intr_error(dev, nsource |
+					  NV03_PGRAPH_NSOURCE_DATA_ERROR);
+
+		status &= ~0x00100000;
+		nv_wr32(dev, NV03_PGRAPH_INTR, 0x00100000);
+	}
+
+	if (status & 0x00200000) {
+		int r;
+
+		nouveau_pgraph_intr_error(dev, nsource |
+					  NV03_PGRAPH_NSOURCE_PROTECTION_ERROR);
+
+		NV_ERROR(dev, "magic set 1:\n");
+		for (r = 0x408900; r <= 0x408910; r += 4)
+			NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r));
+		nv_wr32(dev, 0x408900, nv_rd32(dev, 0x408904) | 0xc0000000);
+		for (r = 0x408e08; r <= 0x408e24; r += 4)
+			NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r));
+		nv_wr32(dev, 0x408e08, nv_rd32(dev, 0x408e08) | 0xc0000000);
+
+		NV_ERROR(dev, "magic set 2:\n");
+		for (r = 0x409900; r <= 0x409910; r += 4)
+			NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r));
+		nv_wr32(dev, 0x409900, nv_rd32(dev, 0x409904) | 0xc0000000);
+		for (r = 0x409e08; r <= 0x409e24; r += 4)
+			NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r));
+		nv_wr32(dev, 0x409e08, nv_rd32(dev, 0x409e08) | 0xc0000000);
+
+		status &= ~0x00200000;
+		nv_wr32(dev, NV03_PGRAPH_NSOURCE, nsource);
+		nv_wr32(dev, NV03_PGRAPH_INTR, 0x00200000);
+	}
+
+	if (status) {
+		NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n", status);
+		nv_wr32(dev, NV03_PGRAPH_INTR, status);
+	}
+
+	{
+		const int isb = (1 << 16) | (1 << 0);
+
+		if ((nv_rd32(dev, 0x400500) & isb) != isb)
+			nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) | isb);
+	}
+
+	nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING);
+}
+
+static void
+nouveau_crtc_irq_handler(struct drm_device *dev, int crtc)
+{
+	if (crtc & 1)
+		nv_wr32(dev, NV_CRTC0_INTSTAT, NV_CRTC_INTR_VBLANK);
+
+	if (crtc & 2)
+		nv_wr32(dev, NV_CRTC1_INTSTAT, NV_CRTC_INTR_VBLANK);
+}
+
+irqreturn_t
+nouveau_irq_handler(DRM_IRQ_ARGS)
+{
+	struct drm_device *dev = (struct drm_device *)arg;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t status, fbdev_flags = 0;
+
+	status = nv_rd32(dev, NV03_PMC_INTR_0);
+	if (!status)
+		return IRQ_NONE;
+
+	if (dev_priv->fbdev_info) {
+		fbdev_flags = dev_priv->fbdev_info->flags;
+		dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED;
+	}
+
+	if (status & NV_PMC_INTR_0_PFIFO_PENDING) {
+		nouveau_fifo_irq_handler(dev);
+		status &= ~NV_PMC_INTR_0_PFIFO_PENDING;
+	}
+
+	if (status & NV_PMC_INTR_0_PGRAPH_PENDING) {
+		if (dev_priv->card_type >= NV_50)
+			nv50_pgraph_irq_handler(dev);
+		else
+			nouveau_pgraph_irq_handler(dev);
+
+		status &= ~NV_PMC_INTR_0_PGRAPH_PENDING;
+	}
+
+	if (status & NV_PMC_INTR_0_CRTCn_PENDING) {
+		nouveau_crtc_irq_handler(dev, (status>>24)&3);
+		status &= ~NV_PMC_INTR_0_CRTCn_PENDING;
+	}
+
+	if (status & (NV_PMC_INTR_0_NV50_DISPLAY_PENDING |
+		      NV_PMC_INTR_0_NV50_I2C_PENDING)) {
+		nv50_display_irq_handler(dev);
+		status &= ~(NV_PMC_INTR_0_NV50_DISPLAY_PENDING |
+			    NV_PMC_INTR_0_NV50_I2C_PENDING);
+	}
+
+	if (status)
+		NV_ERROR(dev, "Unhandled PMC INTR status bits 0x%08x\n", status);
+
+	if (dev_priv->fbdev_info)
+		dev_priv->fbdev_info->flags = fbdev_flags;
+
+	return IRQ_HANDLED;
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
new file mode 100644
index 0000000..0275571
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -0,0 +1,568 @@
+/*
+ * Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+ * Copyright 2005 Stephane Marchesin
+ *
+ * The Weather Channel (TM) funded Tungsten Graphics to develop the
+ * initial release of the Radeon 8500 driver under the XFree86 license.
+ * This notice must be preserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+
+#include "drmP.h"
+#include "drm.h"
+#include "drm_sarea.h"
+#include "nouveau_drv.h"
+
+static struct mem_block *
+split_block(struct mem_block *p, uint64_t start, uint64_t size,
+	    struct drm_file *file_priv)
+{
+	/* Maybe cut off the start of an existing block */
+	if (start > p->start) {
+		struct mem_block *newblock =
+			kmalloc(sizeof(*newblock), GFP_KERNEL);
+		if (!newblock)
+			goto out;
+		newblock->start = start;
+		newblock->size = p->size - (start - p->start);
+		newblock->file_priv = NULL;
+		newblock->next = p->next;
+		newblock->prev = p;
+		p->next->prev = newblock;
+		p->next = newblock;
+		p->size -= newblock->size;
+		p = newblock;
+	}
+
+	/* Maybe cut off the end of an existing block */
+	if (size < p->size) {
+		struct mem_block *newblock =
+			kmalloc(sizeof(*newblock), GFP_KERNEL);
+		if (!newblock)
+			goto out;
+		newblock->start = start + size;
+		newblock->size = p->size - size;
+		newblock->file_priv = NULL;
+		newblock->next = p->next;
+		newblock->prev = p;
+		p->next->prev = newblock;
+		p->next = newblock;
+		p->size = size;
+	}
+
+out:
+	/* Our block is in the middle */
+	p->file_priv = file_priv;
+	return p;
+}
+
+struct mem_block *
+nouveau_mem_alloc_block(struct mem_block *heap, uint64_t size,
+			int align2, struct drm_file *file_priv, int tail)
+{
+	struct mem_block *p;
+	uint64_t mask = (1 << align2) - 1;
+
+	if (!heap)
+		return NULL;
+
+	if (tail) {
+		list_for_each_prev(p, heap) {
+			uint64_t start = ((p->start + p->size) - size) & ~mask;
+
+			if (p->file_priv == NULL && start >= p->start &&
+			    start + size <= p->start + p->size)
+				return split_block(p, start, size, file_priv);
+		}
+	} else {
+		list_for_each(p, heap) {
+			uint64_t start = (p->start + mask) & ~mask;
+
+			if (p->file_priv == NULL &&
+			    start + size <= p->start + p->size)
+				return split_block(p, start, size, file_priv);
+		}
+	}
+
+	return NULL;
+}
+
+void nouveau_mem_free_block(struct mem_block *p)
+{
+	p->file_priv = NULL;
+
+	/* Assumes a single contiguous range.  Needs a special file_priv in
+	 * 'heap' to stop it being subsumed.
+	 */
+	if (p->next->file_priv == NULL) {
+		struct mem_block *q = p->next;
+		p->size += q->size;
+		p->next = q->next;
+		p->next->prev = p;
+		kfree(q);
+	}
+
+	if (p->prev->file_priv == NULL) {
+		struct mem_block *q = p->prev;
+		q->size += p->size;
+		q->next = p->next;
+		q->next->prev = q;
+		kfree(p);
+	}
+}
+
+/* Initialize.  How to check for an uninitialized heap?
+ */
+int nouveau_mem_init_heap(struct mem_block **heap, uint64_t start,
+			  uint64_t size)
+{
+	struct mem_block *blocks = kmalloc(sizeof(*blocks), GFP_KERNEL);
+
+	if (!blocks)
+		return -ENOMEM;
+
+	*heap = kmalloc(sizeof(**heap), GFP_KERNEL);
+	if (!*heap) {
+		kfree(blocks);
+		return -ENOMEM;
+	}
+
+	blocks->start = start;
+	blocks->size = size;
+	blocks->file_priv = NULL;
+	blocks->next = blocks->prev = *heap;
+
+	memset(*heap, 0, sizeof(**heap));
+	(*heap)->file_priv = (struct drm_file *) -1;
+	(*heap)->next = (*heap)->prev = blocks;
+	return 0;
+}
+
+/*
+ * Free all blocks associated with the releasing file_priv
+ */
+void nouveau_mem_release(struct drm_file *file_priv, struct mem_block *heap)
+{
+	struct mem_block *p;
+
+	if (!heap || !heap->next)
+		return;
+
+	list_for_each(p, heap) {
+		if (p->file_priv == file_priv)
+			p->file_priv = NULL;
+	}
+
+	/* Assumes a single contiguous range.  Needs a special file_priv in
+	 * 'heap' to stop it being subsumed.
+	 */
+	list_for_each(p, heap) {
+		while ((p->file_priv == NULL) &&
+					(p->next->file_priv == NULL) &&
+					(p->next != heap)) {
+			struct mem_block *q = p->next;
+			p->size += q->size;
+			p->next = q->next;
+			p->next->prev = p;
+			kfree(q);
+		}
+	}
+}
+
+/*
+ * NV50 VM helpers
+ */
+int
+nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size,
+			uint32_t flags, uint64_t phys)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj **pgt;
+	unsigned psz, pfl, pages;
+
+	if (virt >= dev_priv->vm_gart_base &&
+	    (virt + size) < (dev_priv->vm_gart_base + dev_priv->vm_gart_size)) {
+		psz = 12;
+		pgt = &dev_priv->gart_info.sg_ctxdma;
+		pfl = 0x21;
+		virt -= dev_priv->vm_gart_base;
+	} else
+	if (virt >= dev_priv->vm_vram_base &&
+	    (virt + size) < (dev_priv->vm_vram_base + dev_priv->vm_vram_size)) {
+		psz = 16;
+		pgt = dev_priv->vm_vram_pt;
+		pfl = 0x01;
+		virt -= dev_priv->vm_vram_base;
+	} else {
+		NV_ERROR(dev, "Invalid address: 0x%16llx-0x%16llx\n",
+			 virt, virt + size - 1);
+		return -EINVAL;
+	}
+
+	pages = size >> psz;
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	if (flags & 0x80000000) {
+		while (pages--) {
+			struct nouveau_gpuobj *pt = pgt[virt >> 29];
+			unsigned pte = ((virt & 0x1fffffffULL) >> psz) << 1;
+
+			nv_wo32(dev, pt, pte++, 0x00000000);
+			nv_wo32(dev, pt, pte++, 0x00000000);
+
+			virt += (1 << psz);
+		}
+	} else {
+		while (pages--) {
+			struct nouveau_gpuobj *pt = pgt[virt >> 29];
+			unsigned pte = ((virt & 0x1fffffffULL) >> psz) << 1;
+			unsigned offset_h = upper_32_bits(phys) & 0xff;
+			unsigned offset_l = lower_32_bits(phys);
+
+			nv_wo32(dev, pt, pte++, offset_l | pfl);
+			nv_wo32(dev, pt, pte++, offset_h | flags);
+
+			phys += (1 << psz);
+			virt += (1 << psz);
+		}
+	}
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nv_wr32(dev, 0x100c80, 0x00050001);
+	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+		return -EBUSY;
+	}
+
+	nv_wr32(dev, 0x100c80, 0x00000001);
+	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
+void
+nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size)
+{
+	nv50_mem_vm_bind_linear(dev, virt, size, 0x80000000, 0);
+}
+
+/*
+ * Cleanup everything
+ */
+void nouveau_mem_takedown(struct mem_block **heap)
+{
+	struct mem_block *p;
+
+	if (!*heap)
+		return;
+
+	for (p = (*heap)->next; p != *heap;) {
+		struct mem_block *q = p;
+		p = p->next;
+		kfree(q);
+	}
+
+	kfree(*heap);
+	*heap = NULL;
+}
+
+void nouveau_mem_close(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->ttm.bdev.man[TTM_PL_PRIV0].has_type)
+		ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_PRIV0);
+	ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);
+
+	ttm_bo_device_release(&dev_priv->ttm.bdev);
+
+	nouveau_ttm_global_release(dev_priv);
+
+	if (drm_core_has_AGP(dev) && dev->agp &&
+	    drm_core_check_feature(dev, DRIVER_MODESET)) {
+		struct drm_agp_mem *entry, *tempe;
+
+		/* Remove AGP resources, but leave dev->agp
+		   intact until drv_cleanup is called. */
+		list_for_each_entry_safe(entry, tempe, &dev->agp->memory, head) {
+			if (entry->bound)
+				drm_unbind_agp(entry->memory);
+			drm_free_agp(entry->memory, entry->pages);
+			kfree(entry);
+		}
+		INIT_LIST_HEAD(&dev->agp->memory);
+
+		if (dev->agp->acquired)
+			drm_agp_release(dev);
+
+		dev->agp->acquired = 0;
+		dev->agp->enabled = 0;
+	}
+
+	if (dev_priv->fb_mtrr) {
+		drm_mtrr_del(dev_priv->fb_mtrr, drm_get_resource_start(dev, 1),
+			     drm_get_resource_len(dev, 1), DRM_MTRR_WC);
+		dev_priv->fb_mtrr = 0;
+	}
+}
+
+/*XXX won't work on BSD because of pci_read_config_dword */
+static uint32_t
+nouveau_mem_fb_amount_igp(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct pci_dev *bridge;
+	uint32_t mem;
+
+	bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 1));
+	if (!bridge) {
+		NV_ERROR(dev, "no bridge device\n");
+		return 0;
+	}
+
+	if (dev_priv->flags&NV_NFORCE) {
+		pci_read_config_dword(bridge, 0x7C, &mem);
+		return (uint64_t)(((mem >> 6) & 31) + 1)*1024*1024;
+	} else
+	if (dev_priv->flags&NV_NFORCE2) {
+		pci_read_config_dword(bridge, 0x84, &mem);
+		return (uint64_t)(((mem >> 4) & 127) + 1)*1024*1024;
+	}
+
+	NV_ERROR(dev, "impossible!\n");
+	return 0;
+}
+
+/* returns the amount of FB ram in bytes */
+uint64_t nouveau_mem_fb_amount(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t boot0;
+
+	switch (dev_priv->card_type) {
+	case NV_04:
+		boot0 = nv_rd32(dev, NV03_BOOT_0);
+		if (boot0 & 0x00000100)
+			return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024;
+
+		switch (boot0 & NV03_BOOT_0_RAM_AMOUNT) {
+		case NV04_BOOT_0_RAM_AMOUNT_32MB:
+			return 32 * 1024 * 1024;
+		case NV04_BOOT_0_RAM_AMOUNT_16MB:
+			return 16 * 1024 * 1024;
+		case NV04_BOOT_0_RAM_AMOUNT_8MB:
+			return 8 * 1024 * 1024;
+		case NV04_BOOT_0_RAM_AMOUNT_4MB:
+			return 4 * 1024 * 1024;
+		}
+		break;
+	case NV_10:
+	case NV_20:
+	case NV_30:
+	case NV_40:
+	case NV_50:
+	default:
+		if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) {
+			return nouveau_mem_fb_amount_igp(dev);
+		} else {
+			uint64_t mem;
+			mem = (nv_rd32(dev, NV04_FIFO_DATA) &
+					NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK) >>
+					NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT;
+			return mem * 1024 * 1024;
+		}
+		break;
+	}
+
+	NV_ERROR(dev,
+		"Unable to detect video ram size. Please report your setup to "
+							DRIVER_EMAIL "\n");
+	return 0;
+}
+
+static void nouveau_mem_reset_agp(struct drm_device *dev)
+{
+	uint32_t saved_pci_nv_1, saved_pci_nv_19, pmc_enable;
+
+	saved_pci_nv_1 = nv_rd32(dev, NV04_PBUS_PCI_NV_1);
+	saved_pci_nv_19 = nv_rd32(dev, NV04_PBUS_PCI_NV_19);
+
+	/* clear busmaster bit */
+	nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1 & ~0x4);
+	/* clear SBA and AGP bits */
+	nv_wr32(dev, NV04_PBUS_PCI_NV_19, saved_pci_nv_19 & 0xfffff0ff);
+
+	/* power cycle pgraph, if enabled */
+	pmc_enable = nv_rd32(dev, NV03_PMC_ENABLE);
+	if (pmc_enable & NV_PMC_ENABLE_PGRAPH) {
+		nv_wr32(dev, NV03_PMC_ENABLE,
+				pmc_enable & ~NV_PMC_ENABLE_PGRAPH);
+		nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
+				NV_PMC_ENABLE_PGRAPH);
+	}
+
+	/* and restore (gives effect of resetting AGP) */
+	nv_wr32(dev, NV04_PBUS_PCI_NV_19, saved_pci_nv_19);
+	nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1);
+}
+
+int
+nouveau_mem_init_agp(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_agp_info info;
+	struct drm_agp_mode mode;
+	int ret;
+
+	if (nouveau_noagp)
+		return 0;
+
+	nouveau_mem_reset_agp(dev);
+
+	if (!dev->agp->acquired) {
+		ret = drm_agp_acquire(dev);
+		if (ret) {
+			NV_ERROR(dev, "Unable to acquire AGP: %d\n", ret);
+			return ret;
+		}
+	}
+
+	ret = drm_agp_info(dev, &info);
+	if (ret) {
+		NV_ERROR(dev, "Unable to get AGP info: %d\n", ret);
+		return ret;
+	}
+
+	/* see agp.h for the AGPSTAT_* modes available */
+	mode.mode = info.mode;
+	ret = drm_agp_enable(dev, mode);
+	if (ret) {
+		NV_ERROR(dev, "Unable to enable AGP: %d\n", ret);
+		return ret;
+	}
+
+	dev_priv->gart_info.type	= NOUVEAU_GART_AGP;
+	dev_priv->gart_info.aper_base	= info.aperture_base;
+	dev_priv->gart_info.aper_size	= info.aperture_size;
+	return 0;
+}
+
+int
+nouveau_mem_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct ttm_bo_device *bdev = &dev_priv->ttm.bdev;
+	int ret, dma_bits = 32;
+
+	dev_priv->fb_phys = drm_get_resource_start(dev, 1);
+	dev_priv->gart_info.type = NOUVEAU_GART_NONE;
+
+	if (dev_priv->card_type >= NV_50 &&
+	    pci_dma_supported(dev->pdev, DMA_BIT_MASK(40)))
+		dma_bits = 40;
+
+	ret = pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(dma_bits));
+	if (ret) {
+		NV_ERROR(dev, "Error setting DMA mask: %d\n", ret);
+		return ret;
+	}
+
+	ret = nouveau_ttm_global_init(dev_priv);
+	if (ret)
+		return ret;
+
+	ret = ttm_bo_device_init(&dev_priv->ttm.bdev,
+				 dev_priv->ttm.bo_global_ref.ref.object,
+				 &nouveau_bo_driver, DRM_FILE_PAGE_OFFSET,
+				 dma_bits <= 32 ? true : false);
+	if (ret) {
+		NV_ERROR(dev, "Error initialising bo driver: %d\n", ret);
+		return ret;
+	}
+
+	INIT_LIST_HEAD(&dev_priv->ttm.bo_list);
+	spin_lock_init(&dev_priv->ttm.bo_list_lock);
+
+	dev_priv->fb_available_size = nouveau_mem_fb_amount(dev);
+
+	dev_priv->fb_mappable_pages = dev_priv->fb_available_size;
+	if (dev_priv->fb_mappable_pages > drm_get_resource_len(dev, 1))
+		dev_priv->fb_mappable_pages = drm_get_resource_len(dev, 1);
+	dev_priv->fb_mappable_pages >>= PAGE_SHIFT;
+
+	NV_INFO(dev, "%d MiB VRAM\n", (int)(dev_priv->fb_available_size >> 20));
+
+	/* remove reserved space at end of vram from available amount */
+	dev_priv->fb_available_size -= dev_priv->ramin_rsvd_vram;
+	dev_priv->fb_aper_free = dev_priv->fb_available_size;
+
+	/* mappable vram */
+	ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM,
+			     dev_priv->fb_available_size >> PAGE_SHIFT);
+	if (ret) {
+		NV_ERROR(dev, "Failed VRAM mm init: %d\n", ret);
+		return ret;
+	}
+
+	/* GART */
+#if !defined(__powerpc__) && !defined(__ia64__)
+	if (drm_device_is_agp(dev) && dev->agp) {
+		ret = nouveau_mem_init_agp(dev);
+		if (ret)
+			NV_ERROR(dev, "Error initialising AGP: %d\n", ret);
+	}
+#endif
+
+	if (dev_priv->gart_info.type == NOUVEAU_GART_NONE) {
+		ret = nouveau_sgdma_init(dev);
+		if (ret) {
+			NV_ERROR(dev, "Error initialising PCI(E): %d\n", ret);
+			return ret;
+		}
+	}
+
+	NV_INFO(dev, "%d MiB GART (aperture)\n",
+		(int)(dev_priv->gart_info.aper_size >> 20));
+	dev_priv->gart_info.aper_free = dev_priv->gart_info.aper_size;
+
+	ret = ttm_bo_init_mm(bdev, TTM_PL_TT,
+			     dev_priv->gart_info.aper_size >> PAGE_SHIFT);
+	if (ret) {
+		NV_ERROR(dev, "Failed TT mm init: %d\n", ret);
+		return ret;
+	}
+
+	dev_priv->fb_mtrr = drm_mtrr_add(drm_get_resource_start(dev, 1),
+					 drm_get_resource_len(dev, 1),
+					 DRM_MTRR_WC);
+	return 0;
+}
+
+
diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c
new file mode 100644
index 0000000..6c66a34
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+
+int
+nouveau_notifier_init_channel(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct nouveau_bo *ntfy = NULL;
+	int ret;
+
+	ret = nouveau_gem_new(dev, NULL, PAGE_SIZE, 0, nouveau_vram_notify ?
+			      TTM_PL_FLAG_VRAM : TTM_PL_FLAG_TT,
+			      0, 0x0000, false, true, &ntfy);
+	if (ret)
+		return ret;
+
+	ret = nouveau_bo_pin(ntfy, TTM_PL_FLAG_VRAM);
+	if (ret)
+		goto out_err;
+
+	ret = nouveau_bo_map(ntfy);
+	if (ret)
+		goto out_err;
+
+	ret = nouveau_mem_init_heap(&chan->notifier_heap, 0, ntfy->bo.mem.size);
+	if (ret)
+		goto out_err;
+
+	chan->notifier_bo = ntfy;
+out_err:
+	if (ret) {
+		mutex_lock(&dev->struct_mutex);
+		drm_gem_object_unreference(ntfy->gem);
+		mutex_unlock(&dev->struct_mutex);
+	}
+
+	return ret;
+}
+
+void
+nouveau_notifier_takedown_channel(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+
+	if (!chan->notifier_bo)
+		return;
+
+	nouveau_bo_unmap(chan->notifier_bo);
+	mutex_lock(&dev->struct_mutex);
+	nouveau_bo_unpin(chan->notifier_bo);
+	drm_gem_object_unreference(chan->notifier_bo->gem);
+	mutex_unlock(&dev->struct_mutex);
+	nouveau_mem_takedown(&chan->notifier_heap);
+}
+
+static void
+nouveau_notifier_gpuobj_dtor(struct drm_device *dev,
+			     struct nouveau_gpuobj *gpuobj)
+{
+	NV_DEBUG(dev, "\n");
+
+	if (gpuobj->priv)
+		nouveau_mem_free_block(gpuobj->priv);
+}
+
+int
+nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle,
+		       int size, uint32_t *b_offset)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *nobj = NULL;
+	struct mem_block *mem;
+	uint32_t offset;
+	int target, ret;
+
+	if (!chan->notifier_heap) {
+		NV_ERROR(dev, "Channel %d doesn't have a notifier heap!\n",
+			 chan->id);
+		return -EINVAL;
+	}
+
+	mem = nouveau_mem_alloc_block(chan->notifier_heap, size, 0,
+				      (struct drm_file *)-2, 0);
+	if (!mem) {
+		NV_ERROR(dev, "Channel %d notifier block full\n", chan->id);
+		return -ENOMEM;
+	}
+
+	offset = chan->notifier_bo->bo.mem.mm_node->start << PAGE_SHIFT;
+	if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_VRAM) {
+		target = NV_DMA_TARGET_VIDMEM;
+	} else
+	if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_TT) {
+		if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA &&
+		    dev_priv->card_type < NV_50) {
+			ret = nouveau_sgdma_get_page(dev, offset, &offset);
+			if (ret)
+				return ret;
+			target = NV_DMA_TARGET_PCI;
+		} else {
+			target = NV_DMA_TARGET_AGP;
+		}
+	} else {
+		NV_ERROR(dev, "Bad DMA target, mem_type %d!\n",
+			 chan->notifier_bo->bo.mem.mem_type);
+		return -EINVAL;
+	}
+	offset += mem->start;
+
+	ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, offset,
+				     mem->size, NV_DMA_ACCESS_RW, target,
+				     &nobj);
+	if (ret) {
+		nouveau_mem_free_block(mem);
+		NV_ERROR(dev, "Error creating notifier ctxdma: %d\n", ret);
+		return ret;
+	}
+	nobj->dtor   = nouveau_notifier_gpuobj_dtor;
+	nobj->priv   = mem;
+
+	ret = nouveau_gpuobj_ref_add(dev, chan, handle, nobj, NULL);
+	if (ret) {
+		nouveau_gpuobj_del(dev, &nobj);
+		nouveau_mem_free_block(mem);
+		NV_ERROR(dev, "Error referencing notifier ctxdma: %d\n", ret);
+		return ret;
+	}
+
+	*b_offset = mem->start;
+	return 0;
+}
+
+int
+nouveau_notifier_offset(struct nouveau_gpuobj *nobj, uint32_t *poffset)
+{
+	if (!nobj || nobj->dtor != nouveau_notifier_gpuobj_dtor)
+		return -EINVAL;
+
+	if (poffset) {
+		struct mem_block *mem = nobj->priv;
+
+		if (*poffset >= mem->size)
+			return false;
+
+		*poffset += mem->start;
+	}
+
+	return 0;
+}
+
+int
+nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data,
+			     struct drm_file *file_priv)
+{
+	struct drm_nouveau_notifierobj_alloc *na = data;
+	struct nouveau_channel *chan;
+	int ret;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+	NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(na->channel, file_priv, chan);
+
+	ret = nouveau_notifier_alloc(chan, na->handle, na->size, &na->offset);
+	if (ret)
+		return ret;
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c
new file mode 100644
index 0000000..93379bb
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_object.c
@@ -0,0 +1,1294 @@
+/*
+ * Copyright (C) 2006 Ben Skeggs.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/*
+ * Authors:
+ *   Ben Skeggs <darktama@iinet.net.au>
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+/* NVidia uses context objects to drive drawing operations.
+
+   Context objects can be selected into 8 subchannels in the FIFO,
+   and then used via DMA command buffers.
+
+   A context object is referenced by a user defined handle (CARD32). The HW
+   looks up graphics objects in a hash table in the instance RAM.
+
+   An entry in the hash table consists of 2 CARD32. The first CARD32 contains
+   the handle, the second one a bitfield, that contains the address of the
+   object in instance RAM.
+
+   The format of the second CARD32 seems to be:
+
+   NV4 to NV30:
+
+   15: 0  instance_addr >> 4
+   17:16  engine (here uses 1 = graphics)
+   28:24  channel id (here uses 0)
+   31	  valid (use 1)
+
+   NV40:
+
+   15: 0  instance_addr >> 4   (maybe 19-0)
+   21:20  engine (here uses 1 = graphics)
+   I'm unsure about the other bits, but using 0 seems to work.
+
+   The key into the hash table depends on the object handle and channel id and
+   is given as:
+*/
+static uint32_t
+nouveau_ramht_hash_handle(struct drm_device *dev, int channel, uint32_t handle)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t hash = 0;
+	int i;
+
+	NV_DEBUG(dev, "ch%d handle=0x%08x\n", channel, handle);
+
+	for (i = 32; i > 0; i -= dev_priv->ramht_bits) {
+		hash ^= (handle & ((1 << dev_priv->ramht_bits) - 1));
+		handle >>= dev_priv->ramht_bits;
+	}
+
+	if (dev_priv->card_type < NV_50)
+		hash ^= channel << (dev_priv->ramht_bits - 4);
+	hash <<= 3;
+
+	NV_DEBUG(dev, "hash=0x%08x\n", hash);
+	return hash;
+}
+
+static int
+nouveau_ramht_entry_valid(struct drm_device *dev, struct nouveau_gpuobj *ramht,
+			  uint32_t offset)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t ctx = nv_ro32(dev, ramht, (offset + 4)/4);
+
+	if (dev_priv->card_type < NV_40)
+		return ((ctx & NV_RAMHT_CONTEXT_VALID) != 0);
+	return (ctx != 0);
+}
+
+static int
+nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
+	struct nouveau_channel *chan = ref->channel;
+	struct nouveau_gpuobj *ramht = chan->ramht ? chan->ramht->gpuobj : NULL;
+	uint32_t ctx, co, ho;
+
+	if (!ramht) {
+		NV_ERROR(dev, "No hash table!\n");
+		return -EINVAL;
+	}
+
+	if (dev_priv->card_type < NV_40) {
+		ctx = NV_RAMHT_CONTEXT_VALID | (ref->instance >> 4) |
+		      (chan->id << NV_RAMHT_CONTEXT_CHANNEL_SHIFT) |
+		      (ref->gpuobj->engine << NV_RAMHT_CONTEXT_ENGINE_SHIFT);
+	} else
+	if (dev_priv->card_type < NV_50) {
+		ctx = (ref->instance >> 4) |
+		      (chan->id << NV40_RAMHT_CONTEXT_CHANNEL_SHIFT) |
+		      (ref->gpuobj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT);
+	} else {
+		if (ref->gpuobj->engine == NVOBJ_ENGINE_DISPLAY) {
+			ctx = (ref->instance << 10) | 2;
+		} else {
+			ctx = (ref->instance >> 4) |
+			      ((ref->gpuobj->engine <<
+				NV40_RAMHT_CONTEXT_ENGINE_SHIFT));
+		}
+	}
+
+	instmem->prepare_access(dev, true);
+	co = ho = nouveau_ramht_hash_handle(dev, chan->id, ref->handle);
+	do {
+		if (!nouveau_ramht_entry_valid(dev, ramht, co)) {
+			NV_DEBUG(dev,
+				 "insert ch%d 0x%08x: h=0x%08x, c=0x%08x\n",
+				 chan->id, co, ref->handle, ctx);
+			nv_wo32(dev, ramht, (co + 0)/4, ref->handle);
+			nv_wo32(dev, ramht, (co + 4)/4, ctx);
+
+			list_add_tail(&ref->list, &chan->ramht_refs);
+			instmem->finish_access(dev);
+			return 0;
+		}
+		NV_DEBUG(dev, "collision ch%d 0x%08x: h=0x%08x\n",
+			 chan->id, co, nv_ro32(dev, ramht, co/4));
+
+		co += 8;
+		if (co >= dev_priv->ramht_size)
+			co = 0;
+	} while (co != ho);
+	instmem->finish_access(dev);
+
+	NV_ERROR(dev, "RAMHT space exhausted. ch=%d\n", chan->id);
+	return -ENOMEM;
+}
+
+static void
+nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
+	struct nouveau_channel *chan = ref->channel;
+	struct nouveau_gpuobj *ramht = chan->ramht ? chan->ramht->gpuobj : NULL;
+	uint32_t co, ho;
+
+	if (!ramht) {
+		NV_ERROR(dev, "No hash table!\n");
+		return;
+	}
+
+	instmem->prepare_access(dev, true);
+	co = ho = nouveau_ramht_hash_handle(dev, chan->id, ref->handle);
+	do {
+		if (nouveau_ramht_entry_valid(dev, ramht, co) &&
+		    (ref->handle == nv_ro32(dev, ramht, (co/4)))) {
+			NV_DEBUG(dev,
+				 "remove ch%d 0x%08x: h=0x%08x, c=0x%08x\n",
+				 chan->id, co, ref->handle,
+				 nv_ro32(dev, ramht, (co + 4)));
+			nv_wo32(dev, ramht, (co + 0)/4, 0x00000000);
+			nv_wo32(dev, ramht, (co + 4)/4, 0x00000000);
+
+			list_del(&ref->list);
+			instmem->finish_access(dev);
+			return;
+		}
+
+		co += 8;
+		if (co >= dev_priv->ramht_size)
+			co = 0;
+	} while (co != ho);
+	list_del(&ref->list);
+	instmem->finish_access(dev);
+
+	NV_ERROR(dev, "RAMHT entry not found. ch=%d, handle=0x%08x\n",
+		 chan->id, ref->handle);
+}
+
+int
+nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
+		   uint32_t size, int align, uint32_t flags,
+		   struct nouveau_gpuobj **gpuobj_ret)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
+	struct nouveau_gpuobj *gpuobj;
+	struct mem_block *pramin = NULL;
+	int ret;
+
+	NV_DEBUG(dev, "ch%d size=%u align=%d flags=0x%08x\n",
+		 chan ? chan->id : -1, size, align, flags);
+
+	if (!dev_priv || !gpuobj_ret || *gpuobj_ret != NULL)
+		return -EINVAL;
+
+	gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL);
+	if (!gpuobj)
+		return -ENOMEM;
+	NV_DEBUG(dev, "gpuobj %p\n", gpuobj);
+	gpuobj->flags = flags;
+	gpuobj->im_channel = chan;
+
+	list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
+
+	/* Choose between global instmem heap, and per-channel private
+	 * instmem heap.  On <NV50 allow requests for private instmem
+	 * to be satisfied from global heap if no per-channel area
+	 * available.
+	 */
+	if (chan) {
+		if (chan->ramin_heap) {
+			NV_DEBUG(dev, "private heap\n");
+			pramin = chan->ramin_heap;
+		} else
+		if (dev_priv->card_type < NV_50) {
+			NV_DEBUG(dev, "global heap fallback\n");
+			pramin = dev_priv->ramin_heap;
+		}
+	} else {
+		NV_DEBUG(dev, "global heap\n");
+		pramin = dev_priv->ramin_heap;
+	}
+
+	if (!pramin) {
+		NV_ERROR(dev, "No PRAMIN heap!\n");
+		return -EINVAL;
+	}
+
+	if (!chan) {
+		ret = engine->instmem.populate(dev, gpuobj, &size);
+		if (ret) {
+			nouveau_gpuobj_del(dev, &gpuobj);
+			return ret;
+		}
+	}
+
+	/* Allocate a chunk of the PRAMIN aperture */
+	gpuobj->im_pramin = nouveau_mem_alloc_block(pramin, size,
+						    drm_order(align),
+						    (struct drm_file *)-2, 0);
+	if (!gpuobj->im_pramin) {
+		nouveau_gpuobj_del(dev, &gpuobj);
+		return -ENOMEM;
+	}
+
+	if (!chan) {
+		ret = engine->instmem.bind(dev, gpuobj);
+		if (ret) {
+			nouveau_gpuobj_del(dev, &gpuobj);
+			return ret;
+		}
+	}
+
+	if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
+		int i;
+
+		engine->instmem.prepare_access(dev, true);
+		for (i = 0; i < gpuobj->im_pramin->size; i += 4)
+			nv_wo32(dev, gpuobj, i/4, 0);
+		engine->instmem.finish_access(dev);
+	}
+
+	*gpuobj_ret = gpuobj;
+	return 0;
+}
+
+int
+nouveau_gpuobj_early_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	NV_DEBUG(dev, "\n");
+
+	INIT_LIST_HEAD(&dev_priv->gpuobj_list);
+
+	return 0;
+}
+
+int
+nouveau_gpuobj_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int ret;
+
+	NV_DEBUG(dev, "\n");
+
+	if (dev_priv->card_type < NV_50) {
+		ret = nouveau_gpuobj_new_fake(dev,
+			dev_priv->ramht_offset, ~0, dev_priv->ramht_size,
+			NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ALLOW_NO_REFS,
+						&dev_priv->ramht, NULL);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+void
+nouveau_gpuobj_takedown(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	NV_DEBUG(dev, "\n");
+
+	nouveau_gpuobj_del(dev, &dev_priv->ramht);
+}
+
+void
+nouveau_gpuobj_late_takedown(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *gpuobj = NULL;
+	struct list_head *entry, *tmp;
+
+	NV_DEBUG(dev, "\n");
+
+	list_for_each_safe(entry, tmp, &dev_priv->gpuobj_list) {
+		gpuobj = list_entry(entry, struct nouveau_gpuobj, list);
+
+		NV_ERROR(dev, "gpuobj %p still exists at takedown, refs=%d\n",
+			 gpuobj, gpuobj->refcount);
+		gpuobj->refcount = 0;
+		nouveau_gpuobj_del(dev, &gpuobj);
+	}
+}
+
+int
+nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
+	struct nouveau_gpuobj *gpuobj;
+	int i;
+
+	NV_DEBUG(dev, "gpuobj %p\n", pgpuobj ? *pgpuobj : NULL);
+
+	if (!dev_priv || !pgpuobj || !(*pgpuobj))
+		return -EINVAL;
+	gpuobj = *pgpuobj;
+
+	if (gpuobj->refcount != 0) {
+		NV_ERROR(dev, "gpuobj refcount is %d\n", gpuobj->refcount);
+		return -EINVAL;
+	}
+
+	if (gpuobj->im_pramin && (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE)) {
+		engine->instmem.prepare_access(dev, true);
+		for (i = 0; i < gpuobj->im_pramin->size; i += 4)
+			nv_wo32(dev, gpuobj, i/4, 0);
+		engine->instmem.finish_access(dev);
+	}
+
+	if (gpuobj->dtor)
+		gpuobj->dtor(dev, gpuobj);
+
+	if (gpuobj->im_backing && !(gpuobj->flags & NVOBJ_FLAG_FAKE))
+		engine->instmem.clear(dev, gpuobj);
+
+	if (gpuobj->im_pramin) {
+		if (gpuobj->flags & NVOBJ_FLAG_FAKE)
+			kfree(gpuobj->im_pramin);
+		else
+			nouveau_mem_free_block(gpuobj->im_pramin);
+	}
+
+	list_del(&gpuobj->list);
+
+	*pgpuobj = NULL;
+	kfree(gpuobj);
+	return 0;
+}
+
+static int
+nouveau_gpuobj_instance_get(struct drm_device *dev,
+			    struct nouveau_channel *chan,
+			    struct nouveau_gpuobj *gpuobj, uint32_t *inst)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *cpramin;
+
+	/* <NV50 use PRAMIN address everywhere */
+	if (dev_priv->card_type < NV_50) {
+		*inst = gpuobj->im_pramin->start;
+		return 0;
+	}
+
+	if (chan && gpuobj->im_channel != chan) {
+		NV_ERROR(dev, "Channel mismatch: obj %d, ref %d\n",
+			 gpuobj->im_channel->id, chan->id);
+		return -EINVAL;
+	}
+
+	/* NV50 channel-local instance */
+	if (chan) {
+		cpramin = chan->ramin->gpuobj;
+		*inst = gpuobj->im_pramin->start - cpramin->im_pramin->start;
+		return 0;
+	}
+
+	/* NV50 global (VRAM) instance */
+	if (!gpuobj->im_channel) {
+		/* ...from global heap */
+		if (!gpuobj->im_backing) {
+			NV_ERROR(dev, "AII, no VRAM backing gpuobj\n");
+			return -EINVAL;
+		}
+		*inst = gpuobj->im_backing_start;
+		return 0;
+	} else {
+		/* ...from local heap */
+		cpramin = gpuobj->im_channel->ramin->gpuobj;
+		*inst = cpramin->im_backing_start +
+			(gpuobj->im_pramin->start - cpramin->im_pramin->start);
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+int
+nouveau_gpuobj_ref_add(struct drm_device *dev, struct nouveau_channel *chan,
+		       uint32_t handle, struct nouveau_gpuobj *gpuobj,
+		       struct nouveau_gpuobj_ref **ref_ret)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj_ref *ref;
+	uint32_t instance;
+	int ret;
+
+	NV_DEBUG(dev, "ch%d h=0x%08x gpuobj=%p\n",
+		 chan ? chan->id : -1, handle, gpuobj);
+
+	if (!dev_priv || !gpuobj || (ref_ret && *ref_ret != NULL))
+		return -EINVAL;
+
+	if (!chan && !ref_ret)
+		return -EINVAL;
+
+	if (gpuobj->engine == NVOBJ_ENGINE_SW && !gpuobj->im_pramin) {
+		/* sw object */
+		instance = 0x40;
+	} else {
+		ret = nouveau_gpuobj_instance_get(dev, chan, gpuobj, &instance);
+		if (ret)
+			return ret;
+	}
+
+	ref = kzalloc(sizeof(*ref), GFP_KERNEL);
+	if (!ref)
+		return -ENOMEM;
+	INIT_LIST_HEAD(&ref->list);
+	ref->gpuobj   = gpuobj;
+	ref->channel  = chan;
+	ref->instance = instance;
+
+	if (!ref_ret) {
+		ref->handle = handle;
+
+		ret = nouveau_ramht_insert(dev, ref);
+		if (ret) {
+			kfree(ref);
+			return ret;
+		}
+	} else {
+		ref->handle = ~0;
+		*ref_ret = ref;
+	}
+
+	ref->gpuobj->refcount++;
+	return 0;
+}
+
+int nouveau_gpuobj_ref_del(struct drm_device *dev, struct nouveau_gpuobj_ref **pref)
+{
+	struct nouveau_gpuobj_ref *ref;
+
+	NV_DEBUG(dev, "ref %p\n", pref ? *pref : NULL);
+
+	if (!dev || !pref || *pref == NULL)
+		return -EINVAL;
+	ref = *pref;
+
+	if (ref->handle != ~0)
+		nouveau_ramht_remove(dev, ref);
+
+	if (ref->gpuobj) {
+		ref->gpuobj->refcount--;
+
+		if (ref->gpuobj->refcount == 0) {
+			if (!(ref->gpuobj->flags & NVOBJ_FLAG_ALLOW_NO_REFS))
+				nouveau_gpuobj_del(dev, &ref->gpuobj);
+		}
+	}
+
+	*pref = NULL;
+	kfree(ref);
+	return 0;
+}
+
+int
+nouveau_gpuobj_new_ref(struct drm_device *dev,
+		       struct nouveau_channel *oc, struct nouveau_channel *rc,
+		       uint32_t handle, uint32_t size, int align,
+		       uint32_t flags, struct nouveau_gpuobj_ref **ref)
+{
+	struct nouveau_gpuobj *gpuobj = NULL;
+	int ret;
+
+	ret = nouveau_gpuobj_new(dev, oc, size, align, flags, &gpuobj);
+	if (ret)
+		return ret;
+
+	ret = nouveau_gpuobj_ref_add(dev, rc, handle, gpuobj, ref);
+	if (ret) {
+		nouveau_gpuobj_del(dev, &gpuobj);
+		return ret;
+	}
+
+	return 0;
+}
+
+int
+nouveau_gpuobj_ref_find(struct nouveau_channel *chan, uint32_t handle,
+			struct nouveau_gpuobj_ref **ref_ret)
+{
+	struct nouveau_gpuobj_ref *ref;
+	struct list_head *entry, *tmp;
+
+	list_for_each_safe(entry, tmp, &chan->ramht_refs) {
+		ref = list_entry(entry, struct nouveau_gpuobj_ref, list);
+
+		if (ref->handle == handle) {
+			if (ref_ret)
+				*ref_ret = ref;
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+int
+nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t p_offset,
+			uint32_t b_offset, uint32_t size,
+			uint32_t flags, struct nouveau_gpuobj **pgpuobj,
+			struct nouveau_gpuobj_ref **pref)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *gpuobj = NULL;
+	int i;
+
+	NV_DEBUG(dev,
+		 "p_offset=0x%08x b_offset=0x%08x size=0x%08x flags=0x%08x\n",
+		 p_offset, b_offset, size, flags);
+
+	gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL);
+	if (!gpuobj)
+		return -ENOMEM;
+	NV_DEBUG(dev, "gpuobj %p\n", gpuobj);
+	gpuobj->im_channel = NULL;
+	gpuobj->flags      = flags | NVOBJ_FLAG_FAKE;
+
+	list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
+
+	if (p_offset != ~0) {
+		gpuobj->im_pramin = kzalloc(sizeof(struct mem_block),
+					    GFP_KERNEL);
+		if (!gpuobj->im_pramin) {
+			nouveau_gpuobj_del(dev, &gpuobj);
+			return -ENOMEM;
+		}
+		gpuobj->im_pramin->start = p_offset;
+		gpuobj->im_pramin->size  = size;
+	}
+
+	if (b_offset != ~0) {
+		gpuobj->im_backing = (struct nouveau_bo *)-1;
+		gpuobj->im_backing_start = b_offset;
+	}
+
+	if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
+		dev_priv->engine.instmem.prepare_access(dev, true);
+		for (i = 0; i < gpuobj->im_pramin->size; i += 4)
+			nv_wo32(dev, gpuobj, i/4, 0);
+		dev_priv->engine.instmem.finish_access(dev);
+	}
+
+	if (pref) {
+		i = nouveau_gpuobj_ref_add(dev, NULL, 0, gpuobj, pref);
+		if (i) {
+			nouveau_gpuobj_del(dev, &gpuobj);
+			return i;
+		}
+	}
+
+	if (pgpuobj)
+		*pgpuobj = gpuobj;
+	return 0;
+}
+
+
+static uint32_t
+nouveau_gpuobj_class_instmem_size(struct drm_device *dev, int class)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	/*XXX: dodgy hack for now */
+	if (dev_priv->card_type >= NV_50)
+		return 24;
+	if (dev_priv->card_type >= NV_40)
+		return 32;
+	return 16;
+}
+
+/*
+   DMA objects are used to reference a piece of memory in the
+   framebuffer, PCI or AGP address space. Each object is 16 bytes big
+   and looks as follows:
+
+   entry[0]
+   11:0  class (seems like I can always use 0 here)
+   12    page table present?
+   13    page entry linear?
+   15:14 access: 0 rw, 1 ro, 2 wo
+   17:16 target: 0 NV memory, 1 NV memory tiled, 2 PCI, 3 AGP
+   31:20 dma adjust (bits 0-11 of the address)
+   entry[1]
+   dma limit (size of transfer)
+   entry[X]
+   1     0 readonly, 1 readwrite
+   31:12 dma frame address of the page (bits 12-31 of the address)
+   entry[N]
+   page table terminator, same value as the first pte, as does nvidia
+   rivatv uses 0xffffffff
+
+   Non linear page tables need a list of frame addresses afterwards,
+   the rivatv project has some info on this.
+
+   The method below creates a DMA object in instance RAM and returns a handle
+   to it that can be used to set up context objects.
+*/
+int
+nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class,
+		       uint64_t offset, uint64_t size, int access,
+		       int target, struct nouveau_gpuobj **gpuobj)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
+	int ret;
+
+	NV_DEBUG(dev, "ch%d class=0x%04x offset=0x%llx size=0x%llx\n",
+		 chan->id, class, offset, size);
+	NV_DEBUG(dev, "access=%d target=%d\n", access, target);
+
+	switch (target) {
+	case NV_DMA_TARGET_AGP:
+		offset += dev_priv->gart_info.aper_base;
+		break;
+	default:
+		break;
+	}
+
+	ret = nouveau_gpuobj_new(dev, chan,
+				 nouveau_gpuobj_class_instmem_size(dev, class),
+				 16, NVOBJ_FLAG_ZERO_ALLOC |
+				 NVOBJ_FLAG_ZERO_FREE, gpuobj);
+	if (ret) {
+		NV_ERROR(dev, "Error creating gpuobj: %d\n", ret);
+		return ret;
+	}
+
+	instmem->prepare_access(dev, true);
+
+	if (dev_priv->card_type < NV_50) {
+		uint32_t frame, adjust, pte_flags = 0;
+
+		if (access != NV_DMA_ACCESS_RO)
+			pte_flags |= (1<<1);
+		adjust = offset &  0x00000fff;
+		frame  = offset & ~0x00000fff;
+
+		nv_wo32(dev, *gpuobj, 0, ((1<<12) | (1<<13) |
+				(adjust << 20) |
+				 (access << 14) |
+				 (target << 16) |
+				  class));
+		nv_wo32(dev, *gpuobj, 1, size - 1);
+		nv_wo32(dev, *gpuobj, 2, frame | pte_flags);
+		nv_wo32(dev, *gpuobj, 3, frame | pte_flags);
+	} else {
+		uint64_t limit = offset + size - 1;
+		uint32_t flags0, flags5;
+
+		if (target == NV_DMA_TARGET_VIDMEM) {
+			flags0 = 0x00190000;
+			flags5 = 0x00010000;
+		} else {
+			flags0 = 0x7fc00000;
+			flags5 = 0x00080000;
+		}
+
+		nv_wo32(dev, *gpuobj, 0, flags0 | class);
+		nv_wo32(dev, *gpuobj, 1, lower_32_bits(limit));
+		nv_wo32(dev, *gpuobj, 2, lower_32_bits(offset));
+		nv_wo32(dev, *gpuobj, 3, ((upper_32_bits(limit) & 0xff) << 24) |
+					(upper_32_bits(offset) & 0xff));
+		nv_wo32(dev, *gpuobj, 5, flags5);
+	}
+
+	instmem->finish_access(dev);
+
+	(*gpuobj)->engine = NVOBJ_ENGINE_SW;
+	(*gpuobj)->class  = class;
+	return 0;
+}
+
+int
+nouveau_gpuobj_gart_dma_new(struct nouveau_channel *chan,
+			    uint64_t offset, uint64_t size, int access,
+			    struct nouveau_gpuobj **gpuobj,
+			    uint32_t *o_ret)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int ret;
+
+	if (dev_priv->gart_info.type == NOUVEAU_GART_AGP ||
+	    (dev_priv->card_type >= NV_50 &&
+	     dev_priv->gart_info.type == NOUVEAU_GART_SGDMA)) {
+		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
+					     offset + dev_priv->vm_gart_base,
+					     size, access, NV_DMA_TARGET_AGP,
+					     gpuobj);
+		if (o_ret)
+			*o_ret = 0;
+	} else
+	if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA) {
+		*gpuobj = dev_priv->gart_info.sg_ctxdma;
+		if (offset & ~0xffffffffULL) {
+			NV_ERROR(dev, "obj offset exceeds 32-bits\n");
+			return -EINVAL;
+		}
+		if (o_ret)
+			*o_ret = (uint32_t)offset;
+		ret = (*gpuobj != NULL) ? 0 : -EINVAL;
+	} else {
+		NV_ERROR(dev, "Invalid GART type %d\n", dev_priv->gart_info.type);
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+/* Context objects in the instance RAM have the following structure.
+ * On NV40 they are 32 byte long, on NV30 and smaller 16 bytes.
+
+   NV4 - NV30:
+
+   entry[0]
+   11:0 class
+   12   chroma key enable
+   13   user clip enable
+   14   swizzle enable
+   17:15 patch config:
+       scrcopy_and, rop_and, blend_and, scrcopy, srccopy_pre, blend_pre
+   18   synchronize enable
+   19   endian: 1 big, 0 little
+   21:20 dither mode
+   23    single step enable
+   24    patch status: 0 invalid, 1 valid
+   25    context_surface 0: 1 valid
+   26    context surface 1: 1 valid
+   27    context pattern: 1 valid
+   28    context rop: 1 valid
+   29,30 context beta, beta4
+   entry[1]
+   7:0   mono format
+   15:8  color format
+   31:16 notify instance address
+   entry[2]
+   15:0  dma 0 instance address
+   31:16 dma 1 instance address
+   entry[3]
+   dma method traps
+
+   NV40:
+   No idea what the exact format is. Here's what can be deducted:
+
+   entry[0]:
+   11:0  class  (maybe uses more bits here?)
+   17    user clip enable
+   21:19 patch config
+   25    patch status valid ?
+   entry[1]:
+   15:0  DMA notifier  (maybe 20:0)
+   entry[2]:
+   15:0  DMA 0 instance (maybe 20:0)
+   24    big endian
+   entry[3]:
+   15:0  DMA 1 instance (maybe 20:0)
+   entry[4]:
+   entry[5]:
+   set to 0?
+*/
+int
+nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class,
+		      struct nouveau_gpuobj **gpuobj)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int ret;
+
+	NV_DEBUG(dev, "ch%d class=0x%04x\n", chan->id, class);
+
+	ret = nouveau_gpuobj_new(dev, chan,
+				 nouveau_gpuobj_class_instmem_size(dev, class),
+				 16,
+				 NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE,
+				 gpuobj);
+	if (ret) {
+		NV_ERROR(dev, "Error creating gpuobj: %d\n", ret);
+		return ret;
+	}
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	if (dev_priv->card_type >= NV_50) {
+		nv_wo32(dev, *gpuobj, 0, class);
+		nv_wo32(dev, *gpuobj, 5, 0x00010000);
+	} else {
+		switch (class) {
+		case NV_CLASS_NULL:
+			nv_wo32(dev, *gpuobj, 0, 0x00001030);
+			nv_wo32(dev, *gpuobj, 1, 0xFFFFFFFF);
+			break;
+		default:
+			if (dev_priv->card_type >= NV_40) {
+				nv_wo32(dev, *gpuobj, 0, class);
+#ifdef __BIG_ENDIAN
+				nv_wo32(dev, *gpuobj, 2, 0x01000000);
+#endif
+			} else {
+#ifdef __BIG_ENDIAN
+				nv_wo32(dev, *gpuobj, 0, class | 0x00080000);
+#else
+				nv_wo32(dev, *gpuobj, 0, class);
+#endif
+			}
+		}
+	}
+	dev_priv->engine.instmem.finish_access(dev);
+
+	(*gpuobj)->engine = NVOBJ_ENGINE_GR;
+	(*gpuobj)->class  = class;
+	return 0;
+}
+
+static int
+nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class,
+		      struct nouveau_gpuobj **gpuobj_ret)
+{
+	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
+	struct nouveau_gpuobj *gpuobj;
+
+	if (!chan || !gpuobj_ret || *gpuobj_ret != NULL)
+		return -EINVAL;
+
+	gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL);
+	if (!gpuobj)
+		return -ENOMEM;
+	gpuobj->engine = NVOBJ_ENGINE_SW;
+	gpuobj->class = class;
+
+	list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
+	*gpuobj_ret = gpuobj;
+	return 0;
+}
+
+static int
+nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *pramin = NULL;
+	uint32_t size;
+	uint32_t base;
+	int ret;
+
+	NV_DEBUG(dev, "ch%d\n", chan->id);
+
+	/* Base amount for object storage (4KiB enough?) */
+	size = 0x1000;
+	base = 0;
+
+	/* PGRAPH context */
+
+	if (dev_priv->card_type == NV_50) {
+		/* Various fixed table thingos */
+		size += 0x1400; /* mostly unknown stuff */
+		size += 0x4000; /* vm pd */
+		base  = 0x6000;
+		/* RAMHT, not sure about setting size yet, 32KiB to be safe */
+		size += 0x8000;
+		/* RAMFC */
+		size += 0x1000;
+		/* PGRAPH context */
+		size += 0x70000;
+	}
+
+	NV_DEBUG(dev, "ch%d PRAMIN size: 0x%08x bytes, base alloc=0x%08x\n",
+		 chan->id, size, base);
+	ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, size, 0x1000, 0,
+				     &chan->ramin);
+	if (ret) {
+		NV_ERROR(dev, "Error allocating channel PRAMIN: %d\n", ret);
+		return ret;
+	}
+	pramin = chan->ramin->gpuobj;
+
+	ret = nouveau_mem_init_heap(&chan->ramin_heap,
+				    pramin->im_pramin->start + base, size);
+	if (ret) {
+		NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret);
+		nouveau_gpuobj_ref_del(dev, &chan->ramin);
+		return ret;
+	}
+
+	return 0;
+}
+
+int
+nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
+			    uint32_t vram_h, uint32_t tt_h)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
+	struct nouveau_gpuobj *vram = NULL, *tt = NULL;
+	int ret, i;
+
+	INIT_LIST_HEAD(&chan->ramht_refs);
+
+	NV_DEBUG(dev, "ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h);
+
+	/* Reserve a block of PRAMIN for the channel
+	 *XXX: maybe on <NV50 too at some point
+	 */
+	if (0 || dev_priv->card_type == NV_50) {
+		ret = nouveau_gpuobj_channel_init_pramin(chan);
+		if (ret) {
+			NV_ERROR(dev, "init pramin\n");
+			return ret;
+		}
+	}
+
+	/* NV50 VM
+	 *  - Allocate per-channel page-directory
+	 *  - Map GART and VRAM into the channel's address space at the
+	 *    locations determined during init.
+	 */
+	if (dev_priv->card_type >= NV_50) {
+		uint32_t vm_offset, pde;
+
+		instmem->prepare_access(dev, true);
+
+		vm_offset = (dev_priv->chipset & 0xf0) == 0x50 ? 0x1400 : 0x200;
+		vm_offset += chan->ramin->gpuobj->im_pramin->start;
+
+		ret = nouveau_gpuobj_new_fake(dev, vm_offset, ~0, 0x4000,
+							0, &chan->vm_pd, NULL);
+		if (ret) {
+			instmem->finish_access(dev);
+			return ret;
+		}
+		for (i = 0; i < 0x4000; i += 8) {
+			nv_wo32(dev, chan->vm_pd, (i+0)/4, 0x00000000);
+			nv_wo32(dev, chan->vm_pd, (i+4)/4, 0xdeadcafe);
+		}
+
+		pde = (dev_priv->vm_gart_base / (512*1024*1024)) * 2;
+		ret = nouveau_gpuobj_ref_add(dev, NULL, 0,
+					     dev_priv->gart_info.sg_ctxdma,
+					     &chan->vm_gart_pt);
+		if (ret) {
+			instmem->finish_access(dev);
+			return ret;
+		}
+		nv_wo32(dev, chan->vm_pd, pde++,
+			    chan->vm_gart_pt->instance | 0x03);
+		nv_wo32(dev, chan->vm_pd, pde++, 0x00000000);
+
+		pde = (dev_priv->vm_vram_base / (512*1024*1024)) * 2;
+		for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) {
+			ret = nouveau_gpuobj_ref_add(dev, NULL, 0,
+						     dev_priv->vm_vram_pt[i],
+						     &chan->vm_vram_pt[i]);
+			if (ret) {
+				instmem->finish_access(dev);
+				return ret;
+			}
+
+			nv_wo32(dev, chan->vm_pd, pde++,
+				    chan->vm_vram_pt[i]->instance | 0x61);
+			nv_wo32(dev, chan->vm_pd, pde++, 0x00000000);
+		}
+
+		instmem->finish_access(dev);
+	}
+
+	/* RAMHT */
+	if (dev_priv->card_type < NV_50) {
+		ret = nouveau_gpuobj_ref_add(dev, NULL, 0, dev_priv->ramht,
+					     &chan->ramht);
+		if (ret)
+			return ret;
+	} else {
+		ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0,
+					     0x8000, 16,
+					     NVOBJ_FLAG_ZERO_ALLOC,
+					     &chan->ramht);
+		if (ret)
+			return ret;
+	}
+
+	/* VRAM ctxdma */
+	if (dev_priv->card_type >= NV_50) {
+		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
+					     0, dev_priv->vm_end,
+					     NV_DMA_ACCESS_RW,
+					     NV_DMA_TARGET_AGP, &vram);
+		if (ret) {
+			NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret);
+			return ret;
+		}
+	} else {
+		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
+						0, dev_priv->fb_available_size,
+						NV_DMA_ACCESS_RW,
+						NV_DMA_TARGET_VIDMEM, &vram);
+		if (ret) {
+			NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret);
+			return ret;
+		}
+	}
+
+	ret = nouveau_gpuobj_ref_add(dev, chan, vram_h, vram, NULL);
+	if (ret) {
+		NV_ERROR(dev, "Error referencing VRAM ctxdma: %d\n", ret);
+		return ret;
+	}
+
+	/* TT memory ctxdma */
+	if (dev_priv->card_type >= NV_50) {
+		tt = vram;
+	} else
+	if (dev_priv->gart_info.type != NOUVEAU_GART_NONE) {
+		ret = nouveau_gpuobj_gart_dma_new(chan, 0,
+						  dev_priv->gart_info.aper_size,
+						  NV_DMA_ACCESS_RW, &tt, NULL);
+	} else {
+		NV_ERROR(dev, "Invalid GART type %d\n", dev_priv->gart_info.type);
+		ret = -EINVAL;
+	}
+
+	if (ret) {
+		NV_ERROR(dev, "Error creating TT ctxdma: %d\n", ret);
+		return ret;
+	}
+
+	ret = nouveau_gpuobj_ref_add(dev, chan, tt_h, tt, NULL);
+	if (ret) {
+		NV_ERROR(dev, "Error referencing TT ctxdma: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+void
+nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan)
+{
+	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
+	struct drm_device *dev = chan->dev;
+	struct list_head *entry, *tmp;
+	struct nouveau_gpuobj_ref *ref;
+	int i;
+
+	NV_DEBUG(dev, "ch%d\n", chan->id);
+
+	if (!chan->ramht_refs.next)
+		return;
+
+	list_for_each_safe(entry, tmp, &chan->ramht_refs) {
+		ref = list_entry(entry, struct nouveau_gpuobj_ref, list);
+
+		nouveau_gpuobj_ref_del(dev, &ref);
+	}
+
+	nouveau_gpuobj_ref_del(dev, &chan->ramht);
+
+	nouveau_gpuobj_del(dev, &chan->vm_pd);
+	nouveau_gpuobj_ref_del(dev, &chan->vm_gart_pt);
+	for (i = 0; i < dev_priv->vm_vram_pt_nr; i++)
+		nouveau_gpuobj_ref_del(dev, &chan->vm_vram_pt[i]);
+
+	if (chan->ramin_heap)
+		nouveau_mem_takedown(&chan->ramin_heap);
+	if (chan->ramin)
+		nouveau_gpuobj_ref_del(dev, &chan->ramin);
+
+}
+
+int
+nouveau_gpuobj_suspend(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *gpuobj;
+	int i;
+
+	if (dev_priv->card_type < NV_50) {
+		dev_priv->susres.ramin_copy = vmalloc(dev_priv->ramin_rsvd_vram);
+		if (!dev_priv->susres.ramin_copy)
+			return -ENOMEM;
+
+		for (i = 0; i < dev_priv->ramin_rsvd_vram; i += 4)
+			dev_priv->susres.ramin_copy[i/4] = nv_ri32(dev, i);
+		return 0;
+	}
+
+	list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) {
+		if (!gpuobj->im_backing || (gpuobj->flags & NVOBJ_FLAG_FAKE))
+			continue;
+
+		gpuobj->im_backing_suspend = vmalloc(gpuobj->im_pramin->size);
+		if (!gpuobj->im_backing_suspend) {
+			nouveau_gpuobj_resume(dev);
+			return -ENOMEM;
+		}
+
+		dev_priv->engine.instmem.prepare_access(dev, false);
+		for (i = 0; i < gpuobj->im_pramin->size / 4; i++)
+			gpuobj->im_backing_suspend[i] = nv_ro32(dev, gpuobj, i);
+		dev_priv->engine.instmem.finish_access(dev);
+	}
+
+	return 0;
+}
+
+void
+nouveau_gpuobj_suspend_cleanup(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *gpuobj;
+
+	if (dev_priv->card_type < NV_50) {
+		vfree(dev_priv->susres.ramin_copy);
+		dev_priv->susres.ramin_copy = NULL;
+		return;
+	}
+
+	list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) {
+		if (!gpuobj->im_backing_suspend)
+			continue;
+
+		vfree(gpuobj->im_backing_suspend);
+		gpuobj->im_backing_suspend = NULL;
+	}
+}
+
+void
+nouveau_gpuobj_resume(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *gpuobj;
+	int i;
+
+	if (dev_priv->card_type < NV_50) {
+		for (i = 0; i < dev_priv->ramin_rsvd_vram; i += 4)
+			nv_wi32(dev, i, dev_priv->susres.ramin_copy[i/4]);
+		nouveau_gpuobj_suspend_cleanup(dev);
+		return;
+	}
+
+	list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) {
+		if (!gpuobj->im_backing_suspend)
+			continue;
+
+		dev_priv->engine.instmem.prepare_access(dev, true);
+		for (i = 0; i < gpuobj->im_pramin->size / 4; i++)
+			nv_wo32(dev, gpuobj, i, gpuobj->im_backing_suspend[i]);
+		dev_priv->engine.instmem.finish_access(dev);
+	}
+
+	nouveau_gpuobj_suspend_cleanup(dev);
+}
+
+int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data,
+			      struct drm_file *file_priv)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_nouveau_grobj_alloc *init = data;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	struct nouveau_pgraph_object_class *grc;
+	struct nouveau_gpuobj *gr = NULL;
+	struct nouveau_channel *chan;
+	int ret;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+	NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(init->channel, file_priv, chan);
+
+	if (init->handle == ~0)
+		return -EINVAL;
+
+	grc = pgraph->grclass;
+	while (grc->id) {
+		if (grc->id == init->class)
+			break;
+		grc++;
+	}
+
+	if (!grc->id) {
+		NV_ERROR(dev, "Illegal object class: 0x%x\n", init->class);
+		return -EPERM;
+	}
+
+	if (nouveau_gpuobj_ref_find(chan, init->handle, NULL) == 0)
+		return -EEXIST;
+
+	if (!grc->software)
+		ret = nouveau_gpuobj_gr_new(chan, grc->id, &gr);
+	else
+		ret = nouveau_gpuobj_sw_new(chan, grc->id, &gr);
+
+	if (ret) {
+		NV_ERROR(dev, "Error creating object: %d (%d/0x%08x)\n",
+			 ret, init->channel, init->handle);
+		return ret;
+	}
+
+	ret = nouveau_gpuobj_ref_add(dev, chan, init->handle, gr, NULL);
+	if (ret) {
+		NV_ERROR(dev, "Error referencing object: %d (%d/0x%08x)\n",
+			 ret, init->channel, init->handle);
+		nouveau_gpuobj_del(dev, &gr);
+		return ret;
+	}
+
+	return 0;
+}
+
+int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data,
+			      struct drm_file *file_priv)
+{
+	struct drm_nouveau_gpuobj_free *objfree = data;
+	struct nouveau_gpuobj_ref *ref;
+	struct nouveau_channel *chan;
+	int ret;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+	NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(objfree->channel, file_priv, chan);
+
+	ret = nouveau_gpuobj_ref_find(chan, objfree->handle, &ref);
+	if (ret)
+		return ret;
+	nouveau_gpuobj_ref_del(dev, &ref);
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h
new file mode 100644
index 0000000..fa1b0e7
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_reg.h
@@ -0,0 +1,836 @@
+
+
+#define NV03_BOOT_0                                        0x00100000
+#    define NV03_BOOT_0_RAM_AMOUNT                         0x00000003
+#    define NV03_BOOT_0_RAM_AMOUNT_8MB                     0x00000000
+#    define NV03_BOOT_0_RAM_AMOUNT_2MB                     0x00000001
+#    define NV03_BOOT_0_RAM_AMOUNT_4MB                     0x00000002
+#    define NV03_BOOT_0_RAM_AMOUNT_8MB_SDRAM               0x00000003
+#    define NV04_BOOT_0_RAM_AMOUNT_32MB                    0x00000000
+#    define NV04_BOOT_0_RAM_AMOUNT_4MB                     0x00000001
+#    define NV04_BOOT_0_RAM_AMOUNT_8MB                     0x00000002
+#    define NV04_BOOT_0_RAM_AMOUNT_16MB                    0x00000003
+
+#define NV04_FIFO_DATA                                     0x0010020c
+#    define NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK              0xfff00000
+#    define NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT             20
+
+#define NV_RAMIN                                           0x00700000
+
+#define NV_RAMHT_HANDLE_OFFSET                             0
+#define NV_RAMHT_CONTEXT_OFFSET                            4
+#    define NV_RAMHT_CONTEXT_VALID                         (1<<31)
+#    define NV_RAMHT_CONTEXT_CHANNEL_SHIFT                 24
+#    define NV_RAMHT_CONTEXT_ENGINE_SHIFT                  16
+#        define NV_RAMHT_CONTEXT_ENGINE_SOFTWARE           0
+#        define NV_RAMHT_CONTEXT_ENGINE_GRAPHICS           1
+#    define NV_RAMHT_CONTEXT_INSTANCE_SHIFT                0
+#    define NV40_RAMHT_CONTEXT_CHANNEL_SHIFT               23
+#    define NV40_RAMHT_CONTEXT_ENGINE_SHIFT                20
+#    define NV40_RAMHT_CONTEXT_INSTANCE_SHIFT              0
+
+/* DMA object defines */
+#define NV_DMA_ACCESS_RW 0
+#define NV_DMA_ACCESS_RO 1
+#define NV_DMA_ACCESS_WO 2
+#define NV_DMA_TARGET_VIDMEM 0
+#define NV_DMA_TARGET_PCI    2
+#define NV_DMA_TARGET_AGP    3
+/* The following is not a real value used by the card, it's changed by
+ * nouveau_object_dma_create */
+#define NV_DMA_TARGET_PCI_NONLINEAR 8
+
+/* Some object classes we care about in the drm */
+#define NV_CLASS_DMA_FROM_MEMORY                           0x00000002
+#define NV_CLASS_DMA_TO_MEMORY                             0x00000003
+#define NV_CLASS_NULL                                      0x00000030
+#define NV_CLASS_DMA_IN_MEMORY                             0x0000003D
+
+#define NV03_USER(i)                             (0x00800000+(i*NV03_USER_SIZE))
+#define NV03_USER__SIZE                                                       16
+#define NV10_USER__SIZE                                                       32
+#define NV03_USER_SIZE                                                0x00010000
+#define NV03_USER_DMA_PUT(i)                     (0x00800040+(i*NV03_USER_SIZE))
+#define NV03_USER_DMA_PUT__SIZE                                               16
+#define NV10_USER_DMA_PUT__SIZE                                               32
+#define NV03_USER_DMA_GET(i)                     (0x00800044+(i*NV03_USER_SIZE))
+#define NV03_USER_DMA_GET__SIZE                                               16
+#define NV10_USER_DMA_GET__SIZE                                               32
+#define NV03_USER_REF_CNT(i)                     (0x00800048+(i*NV03_USER_SIZE))
+#define NV03_USER_REF_CNT__SIZE                                               16
+#define NV10_USER_REF_CNT__SIZE                                               32
+
+#define NV40_USER(i)                             (0x00c00000+(i*NV40_USER_SIZE))
+#define NV40_USER_SIZE                                                0x00001000
+#define NV40_USER_DMA_PUT(i)                     (0x00c00040+(i*NV40_USER_SIZE))
+#define NV40_USER_DMA_PUT__SIZE                                               32
+#define NV40_USER_DMA_GET(i)                     (0x00c00044+(i*NV40_USER_SIZE))
+#define NV40_USER_DMA_GET__SIZE                                               32
+#define NV40_USER_REF_CNT(i)                     (0x00c00048+(i*NV40_USER_SIZE))
+#define NV40_USER_REF_CNT__SIZE                                               32
+
+#define NV50_USER(i)                             (0x00c00000+(i*NV50_USER_SIZE))
+#define NV50_USER_SIZE                                                0x00002000
+#define NV50_USER_DMA_PUT(i)                     (0x00c00040+(i*NV50_USER_SIZE))
+#define NV50_USER_DMA_PUT__SIZE                                              128
+#define NV50_USER_DMA_GET(i)                     (0x00c00044+(i*NV50_USER_SIZE))
+#define NV50_USER_DMA_GET__SIZE                                              128
+#define NV50_USER_REF_CNT(i)                     (0x00c00048+(i*NV50_USER_SIZE))
+#define NV50_USER_REF_CNT__SIZE                                              128
+
+#define NV03_FIFO_SIZE                                     0x8000UL
+
+#define NV03_PMC_BOOT_0                                    0x00000000
+#define NV03_PMC_BOOT_1                                    0x00000004
+#define NV03_PMC_INTR_0                                    0x00000100
+#    define NV_PMC_INTR_0_PFIFO_PENDING                        (1<<8)
+#    define NV_PMC_INTR_0_PGRAPH_PENDING                      (1<<12)
+#    define NV_PMC_INTR_0_NV50_I2C_PENDING                    (1<<21)
+#    define NV_PMC_INTR_0_CRTC0_PENDING                       (1<<24)
+#    define NV_PMC_INTR_0_CRTC1_PENDING                       (1<<25)
+#    define NV_PMC_INTR_0_NV50_DISPLAY_PENDING                (1<<26)
+#    define NV_PMC_INTR_0_CRTCn_PENDING                       (3<<24)
+#define NV03_PMC_INTR_EN_0                                 0x00000140
+#    define NV_PMC_INTR_EN_0_MASTER_ENABLE                     (1<<0)
+#define NV03_PMC_ENABLE                                    0x00000200
+#    define NV_PMC_ENABLE_PFIFO                                (1<<8)
+#    define NV_PMC_ENABLE_PGRAPH                              (1<<12)
+/* Disabling the below bit breaks newer (G7X only?) mobile chipsets,
+ * the card will hang early on in the X init process.
+ */
+#    define NV_PMC_ENABLE_UNK13                               (1<<13)
+#define NV40_PMC_BACKLIGHT				   0x000015f0
+#	define NV40_PMC_BACKLIGHT_MASK			   0x001f0000
+#define NV40_PMC_1700                                      0x00001700
+#define NV40_PMC_1704                                      0x00001704
+#define NV40_PMC_1708                                      0x00001708
+#define NV40_PMC_170C                                      0x0000170C
+
+/* probably PMC ? */
+#define NV50_PUNK_BAR0_PRAMIN                              0x00001700
+#define NV50_PUNK_BAR_CFG_BASE                             0x00001704
+#define NV50_PUNK_BAR_CFG_BASE_VALID                          (1<<30)
+#define NV50_PUNK_BAR1_CTXDMA                              0x00001708
+#define NV50_PUNK_BAR1_CTXDMA_VALID                           (1<<31)
+#define NV50_PUNK_BAR3_CTXDMA                              0x0000170C
+#define NV50_PUNK_BAR3_CTXDMA_VALID                           (1<<31)
+#define NV50_PUNK_UNK1710                                  0x00001710
+
+#define NV04_PBUS_PCI_NV_1                                 0x00001804
+#define NV04_PBUS_PCI_NV_19                                0x0000184C
+#define NV04_PBUS_PCI_NV_20				0x00001850
+#	define NV04_PBUS_PCI_NV_20_ROM_SHADOW_DISABLED		(0 << 0)
+#	define NV04_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED		(1 << 0)
+
+#define NV04_PTIMER_INTR_0                                 0x00009100
+#define NV04_PTIMER_INTR_EN_0                              0x00009140
+#define NV04_PTIMER_NUMERATOR                              0x00009200
+#define NV04_PTIMER_DENOMINATOR                            0x00009210
+#define NV04_PTIMER_TIME_0                                 0x00009400
+#define NV04_PTIMER_TIME_1                                 0x00009410
+#define NV04_PTIMER_ALARM_0                                0x00009420
+
+#define NV04_PFB_CFG0                                      0x00100200
+#define NV04_PFB_CFG1                                      0x00100204
+#define NV40_PFB_020C                                      0x0010020C
+#define NV10_PFB_TILE(i)                                   (0x00100240 + (i*16))
+#define NV10_PFB_TILE__SIZE                                8
+#define NV10_PFB_TLIMIT(i)                                 (0x00100244 + (i*16))
+#define NV10_PFB_TSIZE(i)                                  (0x00100248 + (i*16))
+#define NV10_PFB_TSTATUS(i)                                (0x0010024C + (i*16))
+#define NV10_PFB_CLOSE_PAGE2                               0x0010033C
+#define NV40_PFB_TILE(i)                                   (0x00100600 + (i*16))
+#define NV40_PFB_TILE__SIZE_0                              12
+#define NV40_PFB_TILE__SIZE_1                              15
+#define NV40_PFB_TLIMIT(i)                                 (0x00100604 + (i*16))
+#define NV40_PFB_TSIZE(i)                                  (0x00100608 + (i*16))
+#define NV40_PFB_TSTATUS(i)                                (0x0010060C + (i*16))
+#define NV40_PFB_UNK_800					0x00100800
+
+#define NV04_PGRAPH_DEBUG_0                                0x00400080
+#define NV04_PGRAPH_DEBUG_1                                0x00400084
+#define NV04_PGRAPH_DEBUG_2                                0x00400088
+#define NV04_PGRAPH_DEBUG_3                                0x0040008c
+#define NV10_PGRAPH_DEBUG_4                                0x00400090
+#define NV03_PGRAPH_INTR                                   0x00400100
+#define NV03_PGRAPH_NSTATUS                                0x00400104
+#    define NV04_PGRAPH_NSTATUS_STATE_IN_USE                  (1<<11)
+#    define NV04_PGRAPH_NSTATUS_INVALID_STATE                 (1<<12)
+#    define NV04_PGRAPH_NSTATUS_BAD_ARGUMENT                  (1<<13)
+#    define NV04_PGRAPH_NSTATUS_PROTECTION_FAULT              (1<<14)
+#    define NV10_PGRAPH_NSTATUS_STATE_IN_USE                  (1<<23)
+#    define NV10_PGRAPH_NSTATUS_INVALID_STATE                 (1<<24)
+#    define NV10_PGRAPH_NSTATUS_BAD_ARGUMENT                  (1<<25)
+#    define NV10_PGRAPH_NSTATUS_PROTECTION_FAULT              (1<<26)
+#define NV03_PGRAPH_NSOURCE                                0x00400108
+#    define NV03_PGRAPH_NSOURCE_NOTIFICATION                   (1<<0)
+#    define NV03_PGRAPH_NSOURCE_DATA_ERROR                     (1<<1)
+#    define NV03_PGRAPH_NSOURCE_PROTECTION_ERROR               (1<<2)
+#    define NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION                (1<<3)
+#    define NV03_PGRAPH_NSOURCE_LIMIT_COLOR                    (1<<4)
+#    define NV03_PGRAPH_NSOURCE_LIMIT_ZETA                     (1<<5)
+#    define NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD                   (1<<6)
+#    define NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION               (1<<7)
+#    define NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION               (1<<8)
+#    define NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION               (1<<9)
+#    define NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION               (1<<10)
+#    define NV03_PGRAPH_NSOURCE_STATE_INVALID                 (1<<11)
+#    define NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY                 (1<<12)
+#    define NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE                 (1<<13)
+#    define NV03_PGRAPH_NSOURCE_METHOD_CNT                    (1<<14)
+#    define NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION              (1<<15)
+#    define NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION            (1<<16)
+#    define NV03_PGRAPH_NSOURCE_DMA_WIDTH_A                   (1<<17)
+#    define NV03_PGRAPH_NSOURCE_DMA_WIDTH_B                   (1<<18)
+#define NV03_PGRAPH_INTR_EN                                0x00400140
+#define NV40_PGRAPH_INTR_EN                                0x0040013C
+#    define NV_PGRAPH_INTR_NOTIFY                              (1<<0)
+#    define NV_PGRAPH_INTR_MISSING_HW                          (1<<4)
+#    define NV_PGRAPH_INTR_CONTEXT_SWITCH                     (1<<12)
+#    define NV_PGRAPH_INTR_BUFFER_NOTIFY                      (1<<16)
+#    define NV_PGRAPH_INTR_ERROR                              (1<<20)
+#define NV10_PGRAPH_CTX_CONTROL                            0x00400144
+#define NV10_PGRAPH_CTX_USER                               0x00400148
+#define NV10_PGRAPH_CTX_SWITCH1                            0x0040014C
+#define NV10_PGRAPH_CTX_SWITCH2                            0x00400150
+#define NV10_PGRAPH_CTX_SWITCH3                            0x00400154
+#define NV10_PGRAPH_CTX_SWITCH4                            0x00400158
+#define NV10_PGRAPH_CTX_SWITCH5                            0x0040015C
+#define NV04_PGRAPH_CTX_SWITCH1                            0x00400160
+#define NV10_PGRAPH_CTX_CACHE1                             0x00400160
+#define NV04_PGRAPH_CTX_SWITCH2                            0x00400164
+#define NV04_PGRAPH_CTX_SWITCH3                            0x00400168
+#define NV04_PGRAPH_CTX_SWITCH4                            0x0040016C
+#define NV04_PGRAPH_CTX_CONTROL                            0x00400170
+#define NV04_PGRAPH_CTX_USER                               0x00400174
+#define NV04_PGRAPH_CTX_CACHE1                             0x00400180
+#define NV10_PGRAPH_CTX_CACHE2                             0x00400180
+#define NV03_PGRAPH_CTX_CONTROL                            0x00400190
+#define NV03_PGRAPH_CTX_USER                               0x00400194
+#define NV04_PGRAPH_CTX_CACHE2                             0x004001A0
+#define NV10_PGRAPH_CTX_CACHE3                             0x004001A0
+#define NV04_PGRAPH_CTX_CACHE3                             0x004001C0
+#define NV10_PGRAPH_CTX_CACHE4                             0x004001C0
+#define NV04_PGRAPH_CTX_CACHE4                             0x004001E0
+#define NV10_PGRAPH_CTX_CACHE5                             0x004001E0
+#define NV40_PGRAPH_CTXCTL_0304                            0x00400304
+#define NV40_PGRAPH_CTXCTL_0304_XFER_CTX                   0x00000001
+#define NV40_PGRAPH_CTXCTL_UCODE_STAT                      0x00400308
+#define NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_MASK              0xff000000
+#define NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_SHIFT                     24
+#define NV40_PGRAPH_CTXCTL_UCODE_STAT_OP_MASK              0x00ffffff
+#define NV40_PGRAPH_CTXCTL_0310                            0x00400310
+#define NV40_PGRAPH_CTXCTL_0310_XFER_SAVE                  0x00000020
+#define NV40_PGRAPH_CTXCTL_0310_XFER_LOAD                  0x00000040
+#define NV40_PGRAPH_CTXCTL_030C                            0x0040030c
+#define NV40_PGRAPH_CTXCTL_UCODE_INDEX                     0x00400324
+#define NV40_PGRAPH_CTXCTL_UCODE_DATA                      0x00400328
+#define NV40_PGRAPH_CTXCTL_CUR                             0x0040032c
+#define NV40_PGRAPH_CTXCTL_CUR_LOADED                      0x01000000
+#define NV40_PGRAPH_CTXCTL_CUR_INSTANCE                    0x000FFFFF
+#define NV40_PGRAPH_CTXCTL_NEXT                            0x00400330
+#define NV40_PGRAPH_CTXCTL_NEXT_INSTANCE                   0x000fffff
+#define NV50_PGRAPH_CTXCTL_CUR                             0x0040032c
+#define NV50_PGRAPH_CTXCTL_CUR_LOADED                      0x80000000
+#define NV50_PGRAPH_CTXCTL_CUR_INSTANCE                    0x00ffffff
+#define NV50_PGRAPH_CTXCTL_NEXT                            0x00400330
+#define NV50_PGRAPH_CTXCTL_NEXT_INSTANCE                   0x00ffffff
+#define NV03_PGRAPH_ABS_X_RAM                              0x00400400
+#define NV03_PGRAPH_ABS_Y_RAM                              0x00400480
+#define NV03_PGRAPH_X_MISC                                 0x00400500
+#define NV03_PGRAPH_Y_MISC                                 0x00400504
+#define NV04_PGRAPH_VALID1                                 0x00400508
+#define NV04_PGRAPH_SOURCE_COLOR                           0x0040050C
+#define NV04_PGRAPH_MISC24_0                               0x00400510
+#define NV03_PGRAPH_XY_LOGIC_MISC0                         0x00400514
+#define NV03_PGRAPH_XY_LOGIC_MISC1                         0x00400518
+#define NV03_PGRAPH_XY_LOGIC_MISC2                         0x0040051C
+#define NV03_PGRAPH_XY_LOGIC_MISC3                         0x00400520
+#define NV03_PGRAPH_CLIPX_0                                0x00400524
+#define NV03_PGRAPH_CLIPX_1                                0x00400528
+#define NV03_PGRAPH_CLIPY_0                                0x0040052C
+#define NV03_PGRAPH_CLIPY_1                                0x00400530
+#define NV03_PGRAPH_ABS_ICLIP_XMAX                         0x00400534
+#define NV03_PGRAPH_ABS_ICLIP_YMAX                         0x00400538
+#define NV03_PGRAPH_ABS_UCLIP_XMIN                         0x0040053C
+#define NV03_PGRAPH_ABS_UCLIP_YMIN                         0x00400540
+#define NV03_PGRAPH_ABS_UCLIP_XMAX                         0x00400544
+#define NV03_PGRAPH_ABS_UCLIP_YMAX                         0x00400548
+#define NV03_PGRAPH_ABS_UCLIPA_XMIN                        0x00400560
+#define NV03_PGRAPH_ABS_UCLIPA_YMIN                        0x00400564
+#define NV03_PGRAPH_ABS_UCLIPA_XMAX                        0x00400568
+#define NV03_PGRAPH_ABS_UCLIPA_YMAX                        0x0040056C
+#define NV04_PGRAPH_MISC24_1                               0x00400570
+#define NV04_PGRAPH_MISC24_2                               0x00400574
+#define NV04_PGRAPH_VALID2                                 0x00400578
+#define NV04_PGRAPH_PASSTHRU_0                             0x0040057C
+#define NV04_PGRAPH_PASSTHRU_1                             0x00400580
+#define NV04_PGRAPH_PASSTHRU_2                             0x00400584
+#define NV10_PGRAPH_DIMX_TEXTURE                           0x00400588
+#define NV10_PGRAPH_WDIMX_TEXTURE                          0x0040058C
+#define NV04_PGRAPH_COMBINE_0_ALPHA                        0x00400590
+#define NV04_PGRAPH_COMBINE_0_COLOR                        0x00400594
+#define NV04_PGRAPH_COMBINE_1_ALPHA                        0x00400598
+#define NV04_PGRAPH_COMBINE_1_COLOR                        0x0040059C
+#define NV04_PGRAPH_FORMAT_0                               0x004005A8
+#define NV04_PGRAPH_FORMAT_1                               0x004005AC
+#define NV04_PGRAPH_FILTER_0                               0x004005B0
+#define NV04_PGRAPH_FILTER_1                               0x004005B4
+#define NV03_PGRAPH_MONO_COLOR0                            0x00400600
+#define NV04_PGRAPH_ROP3                                   0x00400604
+#define NV04_PGRAPH_BETA_AND                               0x00400608
+#define NV04_PGRAPH_BETA_PREMULT                           0x0040060C
+#define NV04_PGRAPH_LIMIT_VIOL_PIX                         0x00400610
+#define NV04_PGRAPH_FORMATS                                0x00400618
+#define NV10_PGRAPH_DEBUG_2                                0x00400620
+#define NV04_PGRAPH_BOFFSET0                               0x00400640
+#define NV04_PGRAPH_BOFFSET1                               0x00400644
+#define NV04_PGRAPH_BOFFSET2                               0x00400648
+#define NV04_PGRAPH_BOFFSET3                               0x0040064C
+#define NV04_PGRAPH_BOFFSET4                               0x00400650
+#define NV04_PGRAPH_BOFFSET5                               0x00400654
+#define NV04_PGRAPH_BBASE0                                 0x00400658
+#define NV04_PGRAPH_BBASE1                                 0x0040065C
+#define NV04_PGRAPH_BBASE2                                 0x00400660
+#define NV04_PGRAPH_BBASE3                                 0x00400664
+#define NV04_PGRAPH_BBASE4                                 0x00400668
+#define NV04_PGRAPH_BBASE5                                 0x0040066C
+#define NV04_PGRAPH_BPITCH0                                0x00400670
+#define NV04_PGRAPH_BPITCH1                                0x00400674
+#define NV04_PGRAPH_BPITCH2                                0x00400678
+#define NV04_PGRAPH_BPITCH3                                0x0040067C
+#define NV04_PGRAPH_BPITCH4                                0x00400680
+#define NV04_PGRAPH_BLIMIT0                                0x00400684
+#define NV04_PGRAPH_BLIMIT1                                0x00400688
+#define NV04_PGRAPH_BLIMIT2                                0x0040068C
+#define NV04_PGRAPH_BLIMIT3                                0x00400690
+#define NV04_PGRAPH_BLIMIT4                                0x00400694
+#define NV04_PGRAPH_BLIMIT5                                0x00400698
+#define NV04_PGRAPH_BSWIZZLE2                              0x0040069C
+#define NV04_PGRAPH_BSWIZZLE5                              0x004006A0
+#define NV03_PGRAPH_STATUS                                 0x004006B0
+#define NV04_PGRAPH_STATUS                                 0x00400700
+#define NV04_PGRAPH_TRAPPED_ADDR                           0x00400704
+#define NV04_PGRAPH_TRAPPED_DATA                           0x00400708
+#define NV04_PGRAPH_SURFACE                                0x0040070C
+#define NV10_PGRAPH_TRAPPED_DATA_HIGH                      0x0040070C
+#define NV04_PGRAPH_STATE                                  0x00400710
+#define NV10_PGRAPH_SURFACE                                0x00400710
+#define NV04_PGRAPH_NOTIFY                                 0x00400714
+#define NV10_PGRAPH_STATE                                  0x00400714
+#define NV10_PGRAPH_NOTIFY                                 0x00400718
+
+#define NV04_PGRAPH_FIFO                                   0x00400720
+
+#define NV04_PGRAPH_BPIXEL                                 0x00400724
+#define NV10_PGRAPH_RDI_INDEX                              0x00400750
+#define NV04_PGRAPH_FFINTFC_ST2                            0x00400754
+#define NV10_PGRAPH_RDI_DATA                               0x00400754
+#define NV04_PGRAPH_DMA_PITCH                              0x00400760
+#define NV10_PGRAPH_FFINTFC_ST2                            0x00400764
+#define NV04_PGRAPH_DVD_COLORFMT                           0x00400764
+#define NV04_PGRAPH_SCALED_FORMAT                          0x00400768
+#define NV10_PGRAPH_DMA_PITCH                              0x00400770
+#define NV10_PGRAPH_DVD_COLORFMT                           0x00400774
+#define NV10_PGRAPH_SCALED_FORMAT                          0x00400778
+#define NV20_PGRAPH_CHANNEL_CTX_TABLE                      0x00400780
+#define NV20_PGRAPH_CHANNEL_CTX_POINTER                    0x00400784
+#define NV20_PGRAPH_CHANNEL_CTX_XFER                       0x00400788
+#define NV20_PGRAPH_CHANNEL_CTX_XFER_LOAD                  0x00000001
+#define NV20_PGRAPH_CHANNEL_CTX_XFER_SAVE                  0x00000002
+#define NV04_PGRAPH_PATT_COLOR0                            0x00400800
+#define NV04_PGRAPH_PATT_COLOR1                            0x00400804
+#define NV04_PGRAPH_PATTERN                                0x00400808
+#define NV04_PGRAPH_PATTERN_SHAPE                          0x00400810
+#define NV04_PGRAPH_CHROMA                                 0x00400814
+#define NV04_PGRAPH_CONTROL0                               0x00400818
+#define NV04_PGRAPH_CONTROL1                               0x0040081C
+#define NV04_PGRAPH_CONTROL2                               0x00400820
+#define NV04_PGRAPH_BLEND                                  0x00400824
+#define NV04_PGRAPH_STORED_FMT                             0x00400830
+#define NV04_PGRAPH_PATT_COLORRAM                          0x00400900
+#define NV40_PGRAPH_TILE0(i)                               (0x00400900 + (i*16))
+#define NV40_PGRAPH_TLIMIT0(i)                             (0x00400904 + (i*16))
+#define NV40_PGRAPH_TSIZE0(i)                              (0x00400908 + (i*16))
+#define NV40_PGRAPH_TSTATUS0(i)                            (0x0040090C + (i*16))
+#define NV10_PGRAPH_TILE(i)                                (0x00400B00 + (i*16))
+#define NV10_PGRAPH_TLIMIT(i)                              (0x00400B04 + (i*16))
+#define NV10_PGRAPH_TSIZE(i)                               (0x00400B08 + (i*16))
+#define NV10_PGRAPH_TSTATUS(i)                             (0x00400B0C + (i*16))
+#define NV04_PGRAPH_U_RAM                                  0x00400D00
+#define NV47_PGRAPH_TILE0(i)                               (0x00400D00 + (i*16))
+#define NV47_PGRAPH_TLIMIT0(i)                             (0x00400D04 + (i*16))
+#define NV47_PGRAPH_TSIZE0(i)                              (0x00400D08 + (i*16))
+#define NV47_PGRAPH_TSTATUS0(i)                            (0x00400D0C + (i*16))
+#define NV04_PGRAPH_V_RAM                                  0x00400D40
+#define NV04_PGRAPH_W_RAM                                  0x00400D80
+#define NV10_PGRAPH_COMBINER0_IN_ALPHA                     0x00400E40
+#define NV10_PGRAPH_COMBINER1_IN_ALPHA                     0x00400E44
+#define NV10_PGRAPH_COMBINER0_IN_RGB                       0x00400E48
+#define NV10_PGRAPH_COMBINER1_IN_RGB                       0x00400E4C
+#define NV10_PGRAPH_COMBINER_COLOR0                        0x00400E50
+#define NV10_PGRAPH_COMBINER_COLOR1                        0x00400E54
+#define NV10_PGRAPH_COMBINER0_OUT_ALPHA                    0x00400E58
+#define NV10_PGRAPH_COMBINER1_OUT_ALPHA                    0x00400E5C
+#define NV10_PGRAPH_COMBINER0_OUT_RGB                      0x00400E60
+#define NV10_PGRAPH_COMBINER1_OUT_RGB                      0x00400E64
+#define NV10_PGRAPH_COMBINER_FINAL0                        0x00400E68
+#define NV10_PGRAPH_COMBINER_FINAL1                        0x00400E6C
+#define NV10_PGRAPH_WINDOWCLIP_HORIZONTAL                  0x00400F00
+#define NV10_PGRAPH_WINDOWCLIP_VERTICAL                    0x00400F20
+#define NV10_PGRAPH_XFMODE0                                0x00400F40
+#define NV10_PGRAPH_XFMODE1                                0x00400F44
+#define NV10_PGRAPH_GLOBALSTATE0                           0x00400F48
+#define NV10_PGRAPH_GLOBALSTATE1                           0x00400F4C
+#define NV10_PGRAPH_PIPE_ADDRESS                           0x00400F50
+#define NV10_PGRAPH_PIPE_DATA                              0x00400F54
+#define NV04_PGRAPH_DMA_START_0                            0x00401000
+#define NV04_PGRAPH_DMA_START_1                            0x00401004
+#define NV04_PGRAPH_DMA_LENGTH                             0x00401008
+#define NV04_PGRAPH_DMA_MISC                               0x0040100C
+#define NV04_PGRAPH_DMA_DATA_0                             0x00401020
+#define NV04_PGRAPH_DMA_DATA_1                             0x00401024
+#define NV04_PGRAPH_DMA_RM                                 0x00401030
+#define NV04_PGRAPH_DMA_A_XLATE_INST                       0x00401040
+#define NV04_PGRAPH_DMA_A_CONTROL                          0x00401044
+#define NV04_PGRAPH_DMA_A_LIMIT                            0x00401048
+#define NV04_PGRAPH_DMA_A_TLB_PTE                          0x0040104C
+#define NV04_PGRAPH_DMA_A_TLB_TAG                          0x00401050
+#define NV04_PGRAPH_DMA_A_ADJ_OFFSET                       0x00401054
+#define NV04_PGRAPH_DMA_A_OFFSET                           0x00401058
+#define NV04_PGRAPH_DMA_A_SIZE                             0x0040105C
+#define NV04_PGRAPH_DMA_A_Y_SIZE                           0x00401060
+#define NV04_PGRAPH_DMA_B_XLATE_INST                       0x00401080
+#define NV04_PGRAPH_DMA_B_CONTROL                          0x00401084
+#define NV04_PGRAPH_DMA_B_LIMIT                            0x00401088
+#define NV04_PGRAPH_DMA_B_TLB_PTE                          0x0040108C
+#define NV04_PGRAPH_DMA_B_TLB_TAG                          0x00401090
+#define NV04_PGRAPH_DMA_B_ADJ_OFFSET                       0x00401094
+#define NV04_PGRAPH_DMA_B_OFFSET                           0x00401098
+#define NV04_PGRAPH_DMA_B_SIZE                             0x0040109C
+#define NV04_PGRAPH_DMA_B_Y_SIZE                           0x004010A0
+#define NV40_PGRAPH_TILE1(i)                               (0x00406900 + (i*16))
+#define NV40_PGRAPH_TLIMIT1(i)                             (0x00406904 + (i*16))
+#define NV40_PGRAPH_TSIZE1(i)                              (0x00406908 + (i*16))
+#define NV40_PGRAPH_TSTATUS1(i)                            (0x0040690C + (i*16))
+
+
+/* It's a guess that this works on NV03. Confirmed on NV04, though */
+#define NV04_PFIFO_DELAY_0                                 0x00002040
+#define NV04_PFIFO_DMA_TIMESLICE                           0x00002044
+#define NV04_PFIFO_NEXT_CHANNEL                            0x00002050
+#define NV03_PFIFO_INTR_0                                  0x00002100
+#define NV03_PFIFO_INTR_EN_0                               0x00002140
+#    define NV_PFIFO_INTR_CACHE_ERROR                          (1<<0)
+#    define NV_PFIFO_INTR_RUNOUT                               (1<<4)
+#    define NV_PFIFO_INTR_RUNOUT_OVERFLOW                      (1<<8)
+#    define NV_PFIFO_INTR_DMA_PUSHER                          (1<<12)
+#    define NV_PFIFO_INTR_DMA_PT                              (1<<16)
+#    define NV_PFIFO_INTR_SEMAPHORE                           (1<<20)
+#    define NV_PFIFO_INTR_ACQUIRE_TIMEOUT                     (1<<24)
+#define NV03_PFIFO_RAMHT                                   0x00002210
+#define NV03_PFIFO_RAMFC                                   0x00002214
+#define NV03_PFIFO_RAMRO                                   0x00002218
+#define NV40_PFIFO_RAMFC                                   0x00002220
+#define NV03_PFIFO_CACHES                                  0x00002500
+#define NV04_PFIFO_MODE                                    0x00002504
+#define NV04_PFIFO_DMA                                     0x00002508
+#define NV04_PFIFO_SIZE                                    0x0000250c
+#define NV50_PFIFO_CTX_TABLE(c)                        (0x2600+(c)*4)
+#define NV50_PFIFO_CTX_TABLE__SIZE                                128
+#define NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED                  (1<<31)
+#define NV50_PFIFO_CTX_TABLE_UNK30_BAD                        (1<<30)
+#define NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80             0x0FFFFFFF
+#define NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84             0x00FFFFFF
+#define NV03_PFIFO_CACHE0_PUSH0                            0x00003000
+#define NV03_PFIFO_CACHE0_PULL0                            0x00003040
+#define NV04_PFIFO_CACHE0_PULL0                            0x00003050
+#define NV04_PFIFO_CACHE0_PULL1                            0x00003054
+#define NV03_PFIFO_CACHE1_PUSH0                            0x00003200
+#define NV03_PFIFO_CACHE1_PUSH1                            0x00003204
+#define NV03_PFIFO_CACHE1_PUSH1_DMA                            (1<<8)
+#define NV40_PFIFO_CACHE1_PUSH1_DMA                           (1<<16)
+#define NV03_PFIFO_CACHE1_PUSH1_CHID_MASK                  0x0000000f
+#define NV10_PFIFO_CACHE1_PUSH1_CHID_MASK                  0x0000001f
+#define NV50_PFIFO_CACHE1_PUSH1_CHID_MASK                  0x0000007f
+#define NV03_PFIFO_CACHE1_PUT                              0x00003210
+#define NV04_PFIFO_CACHE1_DMA_PUSH                         0x00003220
+#define NV04_PFIFO_CACHE1_DMA_FETCH                        0x00003224
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_8_BYTES         0x00000000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_16_BYTES        0x00000008
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_24_BYTES        0x00000010
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_32_BYTES        0x00000018
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_40_BYTES        0x00000020
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_48_BYTES        0x00000028
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_56_BYTES        0x00000030
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_64_BYTES        0x00000038
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_72_BYTES        0x00000040
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_80_BYTES        0x00000048
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_88_BYTES        0x00000050
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_96_BYTES        0x00000058
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_104_BYTES       0x00000060
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_112_BYTES       0x00000068
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_120_BYTES       0x00000070
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES       0x00000078
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_136_BYTES       0x00000080
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_144_BYTES       0x00000088
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_152_BYTES       0x00000090
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_160_BYTES       0x00000098
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_168_BYTES       0x000000A0
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_176_BYTES       0x000000A8
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_184_BYTES       0x000000B0
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_192_BYTES       0x000000B8
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_200_BYTES       0x000000C0
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_208_BYTES       0x000000C8
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_216_BYTES       0x000000D0
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_224_BYTES       0x000000D8
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_232_BYTES       0x000000E0
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_240_BYTES       0x000000E8
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_248_BYTES       0x000000F0
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_256_BYTES       0x000000F8
+#    define NV_PFIFO_CACHE1_DMA_FETCH_SIZE                 0x0000E000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_32_BYTES        0x00000000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_64_BYTES        0x00002000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_96_BYTES        0x00004000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES       0x00006000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_160_BYTES       0x00008000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_192_BYTES       0x0000A000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_224_BYTES       0x0000C000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_256_BYTES       0x0000E000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS             0x001F0000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_0           0x00000000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_1           0x00010000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_2           0x00020000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_3           0x00030000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_4           0x00040000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_5           0x00050000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_6           0x00060000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_7           0x00070000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8           0x00080000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_9           0x00090000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_10          0x000A0000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_11          0x000B0000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_12          0x000C0000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_13          0x000D0000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_14          0x000E0000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_15          0x000F0000
+#    define NV_PFIFO_CACHE1_ENDIAN                         0x80000000
+#    define NV_PFIFO_CACHE1_LITTLE_ENDIAN                  0x7FFFFFFF
+#    define NV_PFIFO_CACHE1_BIG_ENDIAN                     0x80000000
+#define NV04_PFIFO_CACHE1_DMA_STATE                        0x00003228
+#define NV04_PFIFO_CACHE1_DMA_INSTANCE                     0x0000322c
+#define NV04_PFIFO_CACHE1_DMA_CTL                          0x00003230
+#define NV04_PFIFO_CACHE1_DMA_PUT                          0x00003240
+#define NV04_PFIFO_CACHE1_DMA_GET                          0x00003244
+#define NV10_PFIFO_CACHE1_REF_CNT                          0x00003248
+#define NV10_PFIFO_CACHE1_DMA_SUBROUTINE                   0x0000324C
+#define NV03_PFIFO_CACHE1_PULL0                            0x00003240
+#define NV04_PFIFO_CACHE1_PULL0                            0x00003250
+#define NV03_PFIFO_CACHE1_PULL1                            0x00003250
+#define NV04_PFIFO_CACHE1_PULL1                            0x00003254
+#define NV04_PFIFO_CACHE1_HASH                             0x00003258
+#define NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT                  0x00003260
+#define NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP                0x00003264
+#define NV10_PFIFO_CACHE1_ACQUIRE_VALUE                    0x00003268
+#define NV10_PFIFO_CACHE1_SEMAPHORE                        0x0000326C
+#define NV03_PFIFO_CACHE1_GET                              0x00003270
+#define NV04_PFIFO_CACHE1_ENGINE                           0x00003280
+#define NV04_PFIFO_CACHE1_DMA_DCOUNT                       0x000032A0
+#define NV40_PFIFO_GRCTX_INSTANCE                          0x000032E0
+#define NV40_PFIFO_UNK32E4                                 0x000032E4
+#define NV04_PFIFO_CACHE1_METHOD(i)                (0x00003800+(i*8))
+#define NV04_PFIFO_CACHE1_DATA(i)                  (0x00003804+(i*8))
+#define NV40_PFIFO_CACHE1_METHOD(i)                (0x00090000+(i*8))
+#define NV40_PFIFO_CACHE1_DATA(i)                  (0x00090004+(i*8))
+
+#define NV_CRTC0_INTSTAT                                   0x00600100
+#define NV_CRTC0_INTEN                                     0x00600140
+#define NV_CRTC1_INTSTAT                                   0x00602100
+#define NV_CRTC1_INTEN                                     0x00602140
+#    define NV_CRTC_INTR_VBLANK                                (1<<0)
+
+#define NV04_PRAMIN						0x00700000
+
+/* Fifo commands. These are not regs, neither masks */
+#define NV03_FIFO_CMD_JUMP                                 0x20000000
+#define NV03_FIFO_CMD_JUMP_OFFSET_MASK                     0x1ffffffc
+#define NV03_FIFO_CMD_REWIND                               (NV03_FIFO_CMD_JUMP | (0 & NV03_FIFO_CMD_JUMP_OFFSET_MASK))
+
+/* This is a partial import from rules-ng, a few things may be duplicated.
+ * Eventually we should completely import everything from rules-ng.
+ * For the moment check rules-ng for docs.
+  */
+
+#define NV50_PMC                                            0x00000000
+#define NV50_PMC__LEN                                              0x1
+#define NV50_PMC__ESIZE                                         0x2000
+#    define NV50_PMC_BOOT_0                                 0x00000000
+#        define NV50_PMC_BOOT_0_REVISION                    0x000000ff
+#        define NV50_PMC_BOOT_0_REVISION__SHIFT                      0
+#        define NV50_PMC_BOOT_0_ARCH                        0x0ff00000
+#        define NV50_PMC_BOOT_0_ARCH__SHIFT                         20
+#    define NV50_PMC_INTR_0                                 0x00000100
+#        define NV50_PMC_INTR_0_PFIFO                           (1<<8)
+#        define NV50_PMC_INTR_0_PGRAPH                         (1<<12)
+#        define NV50_PMC_INTR_0_PTIMER                         (1<<20)
+#        define NV50_PMC_INTR_0_HOTPLUG                        (1<<21)
+#        define NV50_PMC_INTR_0_DISPLAY                        (1<<26)
+#    define NV50_PMC_INTR_EN_0                              0x00000140
+#        define NV50_PMC_INTR_EN_0_MASTER                       (1<<0)
+#            define NV50_PMC_INTR_EN_0_MASTER_DISABLED          (0<<0)
+#            define NV50_PMC_INTR_EN_0_MASTER_ENABLED           (1<<0)
+#    define NV50_PMC_ENABLE                                 0x00000200
+#        define NV50_PMC_ENABLE_PFIFO                           (1<<8)
+#        define NV50_PMC_ENABLE_PGRAPH                         (1<<12)
+
+#define NV50_PCONNECTOR                                     0x0000e000
+#define NV50_PCONNECTOR__LEN                                       0x1
+#define NV50_PCONNECTOR__ESIZE                                  0x1000
+#    define NV50_PCONNECTOR_HOTPLUG_INTR                    0x0000e050
+#        define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C0          (1<<0)
+#        define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C1          (1<<1)
+#        define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C2          (1<<2)
+#        define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C3          (1<<3)
+#        define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C0       (1<<16)
+#        define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C1       (1<<17)
+#        define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C2       (1<<18)
+#        define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C3       (1<<19)
+#    define NV50_PCONNECTOR_HOTPLUG_CTRL                    0x0000e054
+#        define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C0          (1<<0)
+#        define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C1          (1<<1)
+#        define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C2          (1<<2)
+#        define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C3          (1<<3)
+#        define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C0       (1<<16)
+#        define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C1       (1<<17)
+#        define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C2       (1<<18)
+#        define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C3       (1<<19)
+#    define NV50_PCONNECTOR_HOTPLUG_STATE                   0x0000e104
+#        define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C0 (1<<2)
+#        define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C1 (1<<6)
+#        define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C2 (1<<10)
+#        define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C3 (1<<14)
+#    define NV50_PCONNECTOR_I2C_PORT_0                      0x0000e138
+#    define NV50_PCONNECTOR_I2C_PORT_1                      0x0000e150
+#    define NV50_PCONNECTOR_I2C_PORT_2                      0x0000e168
+#    define NV50_PCONNECTOR_I2C_PORT_3                      0x0000e180
+#    define NV50_PCONNECTOR_I2C_PORT_4                      0x0000e240
+#    define NV50_PCONNECTOR_I2C_PORT_5                      0x0000e258
+
+#define NV50_AUXCH_DATA_OUT(i,n)             ((n) * 4 + (i) * 0x50 + 0x0000e4c0)
+#define NV50_AUXCH_DATA_OUT__SIZE                                             4
+#define NV50_AUXCH_DATA_IN(i,n)              ((n) * 4 + (i) * 0x50 + 0x0000e4d0)
+#define NV50_AUXCH_DATA_IN__SIZE                                              4
+#define NV50_AUXCH_ADDR(i)                             ((i) * 0x50 + 0x0000e4e0)
+#define NV50_AUXCH_CTRL(i)                             ((i) * 0x50 + 0x0000e4e4)
+#define NV50_AUXCH_CTRL_LINKSTAT                                     0x01000000
+#define NV50_AUXCH_CTRL_LINKSTAT_NOT_READY                           0x00000000
+#define NV50_AUXCH_CTRL_LINKSTAT_READY                               0x01000000
+#define NV50_AUXCH_CTRL_LINKEN                                       0x00100000
+#define NV50_AUXCH_CTRL_LINKEN_DISABLED                              0x00000000
+#define NV50_AUXCH_CTRL_LINKEN_ENABLED                               0x00100000
+#define NV50_AUXCH_CTRL_EXEC                                         0x00010000
+#define NV50_AUXCH_CTRL_EXEC_COMPLETE                                0x00000000
+#define NV50_AUXCH_CTRL_EXEC_IN_PROCESS                              0x00010000
+#define NV50_AUXCH_CTRL_CMD                                          0x0000f000
+#define NV50_AUXCH_CTRL_CMD_SHIFT                                            12
+#define NV50_AUXCH_CTRL_LEN                                          0x0000000f
+#define NV50_AUXCH_CTRL_LEN_SHIFT                                             0
+#define NV50_AUXCH_STAT(i)                             ((i) * 0x50 + 0x0000e4e8)
+#define NV50_AUXCH_STAT_STATE                                        0x10000000
+#define NV50_AUXCH_STAT_STATE_NOT_READY                              0x00000000
+#define NV50_AUXCH_STAT_STATE_READY                                  0x10000000
+#define NV50_AUXCH_STAT_REPLY                                        0x000f0000
+#define NV50_AUXCH_STAT_REPLY_AUX                                    0x00030000
+#define NV50_AUXCH_STAT_REPLY_AUX_ACK                                0x00000000
+#define NV50_AUXCH_STAT_REPLY_AUX_NACK                               0x00010000
+#define NV50_AUXCH_STAT_REPLY_AUX_DEFER                              0x00020000
+#define NV50_AUXCH_STAT_REPLY_I2C                                    0x000c0000
+#define NV50_AUXCH_STAT_REPLY_I2C_ACK                                0x00000000
+#define NV50_AUXCH_STAT_REPLY_I2C_NACK                               0x00040000
+#define NV50_AUXCH_STAT_REPLY_I2C_DEFER                              0x00080000
+#define NV50_AUXCH_STAT_COUNT                                        0x0000001f
+
+#define NV50_PBUS                                           0x00088000
+#define NV50_PBUS__LEN                                             0x1
+#define NV50_PBUS__ESIZE                                        0x1000
+#    define NV50_PBUS_PCI_ID                                0x00088000
+#        define NV50_PBUS_PCI_ID_VENDOR_ID                  0x0000ffff
+#        define NV50_PBUS_PCI_ID_VENDOR_ID__SHIFT                    0
+#        define NV50_PBUS_PCI_ID_DEVICE_ID                  0xffff0000
+#        define NV50_PBUS_PCI_ID_DEVICE_ID__SHIFT                   16
+
+#define NV50_PFB                                            0x00100000
+#define NV50_PFB__LEN                                              0x1
+#define NV50_PFB__ESIZE                                         0x1000
+
+#define NV50_PEXTDEV                                        0x00101000
+#define NV50_PEXTDEV__LEN                                          0x1
+#define NV50_PEXTDEV__ESIZE                                     0x1000
+
+#define NV50_PROM                                           0x00300000
+#define NV50_PROM__LEN                                             0x1
+#define NV50_PROM__ESIZE                                       0x10000
+
+#define NV50_PGRAPH                                         0x00400000
+#define NV50_PGRAPH__LEN                                           0x1
+#define NV50_PGRAPH__ESIZE                                     0x10000
+
+#define NV50_PDISPLAY                                                0x00610000
+#define NV50_PDISPLAY_OBJECTS                                        0x00610010
+#define NV50_PDISPLAY_INTR_0                                         0x00610020
+#define NV50_PDISPLAY_INTR_1                                         0x00610024
+#define NV50_PDISPLAY_INTR_1_VBLANK_CRTC                             0x0000000c
+#define NV50_PDISPLAY_INTR_1_VBLANK_CRTC_SHIFT                                2
+#define NV50_PDISPLAY_INTR_1_VBLANK_CRTC_(n)                   (1 << ((n) + 2))
+#define NV50_PDISPLAY_INTR_1_VBLANK_CRTC_0                           0x00000004
+#define NV50_PDISPLAY_INTR_1_VBLANK_CRTC_1                           0x00000008
+#define NV50_PDISPLAY_INTR_1_CLK_UNK10                               0x00000010
+#define NV50_PDISPLAY_INTR_1_CLK_UNK20                               0x00000020
+#define NV50_PDISPLAY_INTR_1_CLK_UNK40                               0x00000040
+#define NV50_PDISPLAY_INTR_EN                                        0x0061002c
+#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC                            0x0000000c
+#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_(n)                   (1 << ((n) + 2))
+#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_0                          0x00000004
+#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_1                          0x00000008
+#define NV50_PDISPLAY_INTR_EN_CLK_UNK10                              0x00000010
+#define NV50_PDISPLAY_INTR_EN_CLK_UNK20                              0x00000020
+#define NV50_PDISPLAY_INTR_EN_CLK_UNK40                              0x00000040
+#define NV50_PDISPLAY_UNK30_CTRL                                     0x00610030
+#define NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK0                        0x00000200
+#define NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK1                        0x00000400
+#define NV50_PDISPLAY_UNK30_CTRL_PENDING                             0x80000000
+#define NV50_PDISPLAY_TRAPPED_ADDR                                   0x00610080
+#define NV50_PDISPLAY_TRAPPED_DATA                                   0x00610084
+#define NV50_PDISPLAY_CHANNEL_STAT(i)                  ((i) * 0x10 + 0x00610200)
+#define NV50_PDISPLAY_CHANNEL_STAT_DMA                               0x00000010
+#define NV50_PDISPLAY_CHANNEL_STAT_DMA_DISABLED                      0x00000000
+#define NV50_PDISPLAY_CHANNEL_STAT_DMA_ENABLED                       0x00000010
+#define NV50_PDISPLAY_CHANNEL_DMA_CB(i)                ((i) * 0x10 + 0x00610204)
+#define NV50_PDISPLAY_CHANNEL_DMA_CB_LOCATION                        0x00000002
+#define NV50_PDISPLAY_CHANNEL_DMA_CB_LOCATION_VRAM                   0x00000000
+#define NV50_PDISPLAY_CHANNEL_DMA_CB_LOCATION_SYSTEM                 0x00000002
+#define NV50_PDISPLAY_CHANNEL_DMA_CB_VALID                           0x00000001
+#define NV50_PDISPLAY_CHANNEL_UNK2(i)                  ((i) * 0x10 + 0x00610208)
+#define NV50_PDISPLAY_CHANNEL_UNK3(i)                  ((i) * 0x10 + 0x0061020c)
+
+#define NV50_PDISPLAY_CURSOR                                         0x00610270
+#define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i)           ((i) * 0x10 + 0x00610270)
+#define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_ON                         0x00000001
+#define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS                     0x00030000
+#define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE              0x00010000
+
+#define NV50_PDISPLAY_CTRL_STATE                                     0x00610300
+#define NV50_PDISPLAY_CTRL_STATE_PENDING                             0x80000000
+#define NV50_PDISPLAY_CTRL_STATE_METHOD                              0x00001ffc
+#define NV50_PDISPLAY_CTRL_STATE_ENABLE                              0x00000001
+#define NV50_PDISPLAY_CTRL_VAL                                       0x00610304
+#define NV50_PDISPLAY_UNK_380                                        0x00610380
+#define NV50_PDISPLAY_RAM_AMOUNT                                     0x00610384
+#define NV50_PDISPLAY_UNK_388                                        0x00610388
+#define NV50_PDISPLAY_UNK_38C                                        0x0061038c
+
+#define NV50_PDISPLAY_CRTC_P(i, r)        ((i) * 0x540 + NV50_PDISPLAY_CRTC_##r)
+#define NV50_PDISPLAY_CRTC_C(i, r)    (4 + (i) * 0x540 + NV50_PDISPLAY_CRTC_##r)
+#define NV50_PDISPLAY_CRTC_UNK_0A18 /* mthd 0x0900 */                0x00610a18
+#define NV50_PDISPLAY_CRTC_CLUT_MODE                                 0x00610a24
+#define NV50_PDISPLAY_CRTC_INTERLACE                                 0x00610a48
+#define NV50_PDISPLAY_CRTC_SCALE_CTRL                                0x00610a50
+#define NV50_PDISPLAY_CRTC_CURSOR_CTRL                               0x00610a58
+#define NV50_PDISPLAY_CRTC_UNK0A78 /* mthd 0x0904 */                 0x00610a78
+#define NV50_PDISPLAY_CRTC_UNK0AB8                                   0x00610ab8
+#define NV50_PDISPLAY_CRTC_DEPTH                                     0x00610ac8
+#define NV50_PDISPLAY_CRTC_CLOCK                                     0x00610ad0
+#define NV50_PDISPLAY_CRTC_COLOR_CTRL                                0x00610ae0
+#define NV50_PDISPLAY_CRTC_SYNC_START_TO_BLANK_END                   0x00610ae8
+#define NV50_PDISPLAY_CRTC_MODE_UNK1                                 0x00610af0
+#define NV50_PDISPLAY_CRTC_DISPLAY_TOTAL                             0x00610af8
+#define NV50_PDISPLAY_CRTC_SYNC_DURATION                             0x00610b00
+#define NV50_PDISPLAY_CRTC_MODE_UNK2                                 0x00610b08
+#define NV50_PDISPLAY_CRTC_UNK_0B10 /* mthd 0x0828 */                0x00610b10
+#define NV50_PDISPLAY_CRTC_FB_SIZE                                   0x00610b18
+#define NV50_PDISPLAY_CRTC_FB_PITCH                                  0x00610b20
+#define NV50_PDISPLAY_CRTC_FB_PITCH_LINEAR                           0x00100000
+#define NV50_PDISPLAY_CRTC_FB_POS                                    0x00610b28
+#define NV50_PDISPLAY_CRTC_SCALE_CENTER_OFFSET                       0x00610b38
+#define NV50_PDISPLAY_CRTC_REAL_RES                                  0x00610b40
+#define NV50_PDISPLAY_CRTC_SCALE_RES1                                0x00610b48
+#define NV50_PDISPLAY_CRTC_SCALE_RES2                                0x00610b50
+
+#define NV50_PDISPLAY_DAC_MODE_CTRL_P(i)                (0x00610b58 + (i) * 0x8)
+#define NV50_PDISPLAY_DAC_MODE_CTRL_C(i)                (0x00610b5c + (i) * 0x8)
+#define NV50_PDISPLAY_SOR_MODE_CTRL_P(i)                (0x00610b70 + (i) * 0x8)
+#define NV50_PDISPLAY_SOR_MODE_CTRL_C(i)                (0x00610b74 + (i) * 0x8)
+#define NV50_PDISPLAY_DAC_MODE_CTRL2_P(i)               (0x00610bdc + (i) * 0x8)
+#define NV50_PDISPLAY_DAC_MODE_CTRL2_C(i)               (0x00610be0 + (i) * 0x8)
+
+#define NV90_PDISPLAY_SOR_MODE_CTRL_P(i)                (0x00610794 + (i) * 0x8)
+#define NV90_PDISPLAY_SOR_MODE_CTRL_C(i)                (0x00610798 + (i) * 0x8)
+#define NV90_PDISPLAY_DAC_MODE_CTRL_P(i)                (0x00610b58 + (i) * 0x8)
+#define NV90_PDISPLAY_DAC_MODE_CTRL_C(i)                (0x00610b5c + (i) * 0x8)
+#define NV90_PDISPLAY_DAC_MODE_CTRL2_P(i)               (0x00610b80 + (i) * 0x8)
+#define NV90_PDISPLAY_DAC_MODE_CTRL2_C(i)               (0x00610b84 + (i) * 0x8)
+
+#define NV50_PDISPLAY_CRTC_CLK                                       0x00614000
+#define NV50_PDISPLAY_CRTC_CLK_CTRL1(i)                 ((i) * 0x800 + 0x614100)
+#define NV50_PDISPLAY_CRTC_CLK_CTRL1_CONNECTED                       0x00000600
+#define NV50_PDISPLAY_CRTC_CLK_VPLL_A(i)                ((i) * 0x800 + 0x614104)
+#define NV50_PDISPLAY_CRTC_CLK_VPLL_B(i)                ((i) * 0x800 + 0x614108)
+#define NV50_PDISPLAY_CRTC_CLK_CTRL2(i)                 ((i) * 0x800 + 0x614200)
+
+#define NV50_PDISPLAY_DAC_CLK                                        0x00614000
+#define NV50_PDISPLAY_DAC_CLK_CTRL2(i)                  ((i) * 0x800 + 0x614280)
+
+#define NV50_PDISPLAY_SOR_CLK                                        0x00614000
+#define NV50_PDISPLAY_SOR_CLK_CTRL2(i)                  ((i) * 0x800 + 0x614300)
+
+#define NV50_PDISPLAY_VGACRTC(r)                                ((r) + 0x619400)
+
+#define NV50_PDISPLAY_DAC                                            0x0061a000
+#define NV50_PDISPLAY_DAC_DPMS_CTRL(i)                (0x0061a004 + (i) * 0x800)
+#define NV50_PDISPLAY_DAC_DPMS_CTRL_HSYNC_OFF                        0x00000001
+#define NV50_PDISPLAY_DAC_DPMS_CTRL_VSYNC_OFF                        0x00000004
+#define NV50_PDISPLAY_DAC_DPMS_CTRL_BLANKED                          0x00000010
+#define NV50_PDISPLAY_DAC_DPMS_CTRL_OFF                              0x00000040
+#define NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING                          0x80000000
+#define NV50_PDISPLAY_DAC_LOAD_CTRL(i)                (0x0061a00c + (i) * 0x800)
+#define NV50_PDISPLAY_DAC_LOAD_CTRL_ACTIVE                           0x00100000
+#define NV50_PDISPLAY_DAC_LOAD_CTRL_PRESENT                          0x38000000
+#define NV50_PDISPLAY_DAC_LOAD_CTRL_DONE                             0x80000000
+#define NV50_PDISPLAY_DAC_CLK_CTRL1(i)                (0x0061a010 + (i) * 0x800)
+#define NV50_PDISPLAY_DAC_CLK_CTRL1_CONNECTED                        0x00000600
+
+#define NV50_PDISPLAY_SOR                                            0x0061c000
+#define NV50_PDISPLAY_SOR_DPMS_CTRL(i)                (0x0061c004 + (i) * 0x800)
+#define NV50_PDISPLAY_SOR_DPMS_CTRL_PENDING                          0x80000000
+#define NV50_PDISPLAY_SOR_DPMS_CTRL_ON                               0x00000001
+#define NV50_PDISPLAY_SOR_CLK_CTRL1(i)                (0x0061c008 + (i) * 0x800)
+#define NV50_PDISPLAY_SOR_CLK_CTRL1_CONNECTED                        0x00000600
+#define NV50_PDISPLAY_SOR_DPMS_STATE(i)               (0x0061c030 + (i) * 0x800)
+#define NV50_PDISPLAY_SOR_DPMS_STATE_ACTIVE                          0x00030000
+#define NV50_PDISPLAY_SOR_DPMS_STATE_BLANKED                         0x00080000
+#define NV50_PDISPLAY_SOR_DPMS_STATE_WAIT                            0x10000000
+#define NV50_PDISPLAY_SOR_BACKLIGHT                                  0x0061c084
+#define NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE                           0x80000000
+#define NV50_PDISPLAY_SOR_BACKLIGHT_LEVEL                            0x00000fff
+#define NV50_SOR_DP_CTRL(i,l)            (0x0061c10c + (i) * 0x800 + (l) * 0x80)
+#define NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED                      0x00004000
+#define NV50_SOR_DP_CTRL_LANE_MASK                                   0x001f0000
+#define NV50_SOR_DP_CTRL_LANE_0_ENABLED                              0x00010000
+#define NV50_SOR_DP_CTRL_LANE_1_ENABLED                              0x00020000
+#define NV50_SOR_DP_CTRL_LANE_2_ENABLED                              0x00040000
+#define NV50_SOR_DP_CTRL_LANE_3_ENABLED                              0x00080000
+#define NV50_SOR_DP_CTRL_TRAINING_PATTERN                            0x0f000000
+#define NV50_SOR_DP_CTRL_TRAINING_PATTERN_DISABLED                   0x00000000
+#define NV50_SOR_DP_CTRL_TRAINING_PATTERN_1                          0x01000000
+#define NV50_SOR_DP_CTRL_TRAINING_PATTERN_2                          0x02000000
+#define NV50_SOR_DP_UNK118(i,l)          (0x0061c118 + (i) * 0x800 + (l) * 0x80)
+#define NV50_SOR_DP_UNK120(i,l)          (0x0061c120 + (i) * 0x800 + (l) * 0x80)
+#define NV50_SOR_DP_UNK130(i,l)          (0x0061c130 + (i) * 0x800 + (l) * 0x80)
+
+#define NV50_PDISPLAY_USER(i)                        ((i) * 0x1000 + 0x00640000)
+#define NV50_PDISPLAY_USER_PUT(i)                    ((i) * 0x1000 + 0x00640000)
+#define NV50_PDISPLAY_USER_GET(i)                    ((i) * 0x1000 + 0x00640004)
+
+#define NV50_PDISPLAY_CURSOR_USER                                    0x00647000
+#define NV50_PDISPLAY_CURSOR_USER_POS_CTRL(i)        ((i) * 0x1000 + 0x00647080)
+#define NV50_PDISPLAY_CURSOR_USER_POS(i)             ((i) * 0x1000 + 0x00647084)
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
new file mode 100644
index 0000000..4c7f1e4
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
@@ -0,0 +1,321 @@
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include <linux/pagemap.h>
+
+#define NV_CTXDMA_PAGE_SHIFT 12
+#define NV_CTXDMA_PAGE_SIZE  (1 << NV_CTXDMA_PAGE_SHIFT)
+#define NV_CTXDMA_PAGE_MASK  (NV_CTXDMA_PAGE_SIZE - 1)
+
+struct nouveau_sgdma_be {
+	struct ttm_backend backend;
+	struct drm_device *dev;
+
+	dma_addr_t *pages;
+	unsigned nr_pages;
+
+	unsigned pte_start;
+	bool bound;
+};
+
+static int
+nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages,
+		       struct page **pages, struct page *dummy_read_page)
+{
+	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+	struct drm_device *dev = nvbe->dev;
+
+	NV_DEBUG(nvbe->dev, "num_pages = %ld\n", num_pages);
+
+	if (nvbe->pages)
+		return -EINVAL;
+
+	nvbe->pages = kmalloc(sizeof(dma_addr_t) * num_pages, GFP_KERNEL);
+	if (!nvbe->pages)
+		return -ENOMEM;
+
+	nvbe->nr_pages = 0;
+	while (num_pages--) {
+		nvbe->pages[nvbe->nr_pages] =
+			pci_map_page(dev->pdev, pages[nvbe->nr_pages], 0,
+				     PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+		if (pci_dma_mapping_error(dev->pdev,
+					  nvbe->pages[nvbe->nr_pages])) {
+			be->func->clear(be);
+			return -EFAULT;
+		}
+
+		nvbe->nr_pages++;
+	}
+
+	return 0;
+}
+
+static void
+nouveau_sgdma_clear(struct ttm_backend *be)
+{
+	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+	struct drm_device *dev = nvbe->dev;
+
+	NV_DEBUG(nvbe->dev, "\n");
+
+	if (nvbe && nvbe->pages) {
+		if (nvbe->bound)
+			be->func->unbind(be);
+
+		while (nvbe->nr_pages--) {
+			pci_unmap_page(dev->pdev, nvbe->pages[nvbe->nr_pages],
+				       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+		}
+		kfree(nvbe->pages);
+		nvbe->pages = NULL;
+		nvbe->nr_pages = 0;
+	}
+}
+
+static inline unsigned
+nouveau_sgdma_pte(struct drm_device *dev, uint64_t offset)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	unsigned pte = (offset >> NV_CTXDMA_PAGE_SHIFT);
+
+	if (dev_priv->card_type < NV_50)
+		return pte + 2;
+
+	return pte << 1;
+}
+
+static int
+nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
+{
+	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+	struct drm_device *dev = nvbe->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma;
+	unsigned i, j, pte;
+
+	NV_DEBUG(dev, "pg=0x%lx\n", mem->mm_node->start);
+
+	dev_priv->engine.instmem.prepare_access(nvbe->dev, true);
+	pte = nouveau_sgdma_pte(nvbe->dev, mem->mm_node->start << PAGE_SHIFT);
+	nvbe->pte_start = pte;
+	for (i = 0; i < nvbe->nr_pages; i++) {
+		dma_addr_t dma_offset = nvbe->pages[i];
+		uint32_t offset_l = lower_32_bits(dma_offset);
+		uint32_t offset_h = upper_32_bits(dma_offset);
+
+		for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++) {
+			if (dev_priv->card_type < NV_50)
+				nv_wo32(dev, gpuobj, pte++, offset_l | 3);
+			else {
+				nv_wo32(dev, gpuobj, pte++, offset_l | 0x21);
+				nv_wo32(dev, gpuobj, pte++, offset_h & 0xff);
+			}
+
+			dma_offset += NV_CTXDMA_PAGE_SIZE;
+		}
+	}
+	dev_priv->engine.instmem.finish_access(nvbe->dev);
+
+	if (dev_priv->card_type == NV_50) {
+		nv_wr32(dev, 0x100c80, 0x00050001);
+		if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+			NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+			NV_ERROR(dev, "0x100c80 = 0x%08x\n",
+						nv_rd32(dev, 0x100c80));
+			return -EBUSY;
+		}
+
+		nv_wr32(dev, 0x100c80, 0x00000001);
+		if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+			NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+			NV_ERROR(dev, "0x100c80 = 0x%08x\n",
+						nv_rd32(dev, 0x100c80));
+			return -EBUSY;
+		}
+	}
+
+	nvbe->bound = true;
+	return 0;
+}
+
+static int
+nouveau_sgdma_unbind(struct ttm_backend *be)
+{
+	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+	struct drm_device *dev = nvbe->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma;
+	unsigned i, j, pte;
+
+	NV_DEBUG(dev, "\n");
+
+	if (!nvbe->bound)
+		return 0;
+
+	dev_priv->engine.instmem.prepare_access(nvbe->dev, true);
+	pte = nvbe->pte_start;
+	for (i = 0; i < nvbe->nr_pages; i++) {
+		dma_addr_t dma_offset = dev_priv->gart_info.sg_dummy_bus;
+
+		for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++) {
+			if (dev_priv->card_type < NV_50)
+				nv_wo32(dev, gpuobj, pte++, dma_offset | 3);
+			else {
+				nv_wo32(dev, gpuobj, pte++, dma_offset | 0x21);
+				nv_wo32(dev, gpuobj, pte++, 0x00000000);
+			}
+
+			dma_offset += NV_CTXDMA_PAGE_SIZE;
+		}
+	}
+	dev_priv->engine.instmem.finish_access(nvbe->dev);
+
+	nvbe->bound = false;
+	return 0;
+}
+
+static void
+nouveau_sgdma_destroy(struct ttm_backend *be)
+{
+	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+
+	if (be) {
+		NV_DEBUG(nvbe->dev, "\n");
+
+		if (nvbe) {
+			if (nvbe->pages)
+				be->func->clear(be);
+			kfree(nvbe);
+		}
+	}
+}
+
+static struct ttm_backend_func nouveau_sgdma_backend = {
+	.populate		= nouveau_sgdma_populate,
+	.clear			= nouveau_sgdma_clear,
+	.bind			= nouveau_sgdma_bind,
+	.unbind			= nouveau_sgdma_unbind,
+	.destroy		= nouveau_sgdma_destroy
+};
+
+struct ttm_backend *
+nouveau_sgdma_init_ttm(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_sgdma_be *nvbe;
+
+	if (!dev_priv->gart_info.sg_ctxdma)
+		return NULL;
+
+	nvbe = kzalloc(sizeof(*nvbe), GFP_KERNEL);
+	if (!nvbe)
+		return NULL;
+
+	nvbe->dev = dev;
+
+	nvbe->backend.func	= &nouveau_sgdma_backend;
+
+	return &nvbe->backend;
+}
+
+int
+nouveau_sgdma_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *gpuobj = NULL;
+	uint32_t aper_size, obj_size;
+	int i, ret;
+
+	if (dev_priv->card_type < NV_50) {
+		aper_size = (64 * 1024 * 1024);
+		obj_size  = (aper_size >> NV_CTXDMA_PAGE_SHIFT) * 4;
+		obj_size += 8; /* ctxdma header */
+	} else {
+		/* 1 entire VM page table */
+		aper_size = (512 * 1024 * 1024);
+		obj_size  = (aper_size >> NV_CTXDMA_PAGE_SHIFT) * 8;
+	}
+
+	ret = nouveau_gpuobj_new(dev, NULL, obj_size, 16,
+				      NVOBJ_FLAG_ALLOW_NO_REFS |
+				      NVOBJ_FLAG_ZERO_ALLOC |
+				      NVOBJ_FLAG_ZERO_FREE, &gpuobj);
+	if (ret) {
+		NV_ERROR(dev, "Error creating sgdma object: %d\n", ret);
+		return ret;
+	}
+
+	dev_priv->gart_info.sg_dummy_page =
+		alloc_page(GFP_KERNEL|__GFP_DMA32);
+	set_bit(PG_locked, &dev_priv->gart_info.sg_dummy_page->flags);
+	dev_priv->gart_info.sg_dummy_bus =
+		pci_map_page(dev->pdev, dev_priv->gart_info.sg_dummy_page, 0,
+			     PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	if (dev_priv->card_type < NV_50) {
+		/* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and
+		 * confirmed to work on c51.  Perhaps means NV_DMA_TARGET_PCIE
+		 * on those cards? */
+		nv_wo32(dev, gpuobj, 0, NV_CLASS_DMA_IN_MEMORY |
+				       (1 << 12) /* PT present */ |
+				       (0 << 13) /* PT *not* linear */ |
+				       (NV_DMA_ACCESS_RW  << 14) |
+				       (NV_DMA_TARGET_PCI << 16));
+		nv_wo32(dev, gpuobj, 1, aper_size - 1);
+		for (i = 2; i < 2 + (aper_size >> 12); i++) {
+			nv_wo32(dev, gpuobj, i,
+				    dev_priv->gart_info.sg_dummy_bus | 3);
+		}
+	} else {
+		for (i = 0; i < obj_size; i += 8) {
+			nv_wo32(dev, gpuobj, (i+0)/4,
+				    dev_priv->gart_info.sg_dummy_bus | 0x21);
+			nv_wo32(dev, gpuobj, (i+4)/4, 0);
+		}
+	}
+	dev_priv->engine.instmem.finish_access(dev);
+
+	dev_priv->gart_info.type      = NOUVEAU_GART_SGDMA;
+	dev_priv->gart_info.aper_base = 0;
+	dev_priv->gart_info.aper_size = aper_size;
+	dev_priv->gart_info.sg_ctxdma = gpuobj;
+	return 0;
+}
+
+void
+nouveau_sgdma_takedown(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->gart_info.sg_dummy_page) {
+		pci_unmap_page(dev->pdev, dev_priv->gart_info.sg_dummy_bus,
+			       NV_CTXDMA_PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+		unlock_page(dev_priv->gart_info.sg_dummy_page);
+		__free_page(dev_priv->gart_info.sg_dummy_page);
+		dev_priv->gart_info.sg_dummy_page = NULL;
+		dev_priv->gart_info.sg_dummy_bus = 0;
+	}
+
+	nouveau_gpuobj_del(dev, &dev_priv->gart_info.sg_ctxdma);
+}
+
+int
+nouveau_sgdma_get_page(struct drm_device *dev, uint32_t offset, uint32_t *page)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma;
+	struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
+	int pte;
+
+	pte = (offset >> NV_CTXDMA_PAGE_SHIFT);
+	if (dev_priv->card_type < NV_50) {
+		instmem->prepare_access(dev, false);
+		*page = nv_ro32(dev, gpuobj, (pte + 2)) & ~NV_CTXDMA_PAGE_MASK;
+		instmem->finish_access(dev);
+		return 0;
+	}
+
+	NV_ERROR(dev, "Unimplemented on NV50\n");
+	return -EINVAL;
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
new file mode 100644
index 0000000..2ed41d3
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -0,0 +1,811 @@
+/*
+ * Copyright 2005 Stephane Marchesin
+ * Copyright 2008 Stuart Bennett
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/swab.h>
+#include "drmP.h"
+#include "drm.h"
+#include "drm_sarea.h"
+#include "drm_crtc_helper.h"
+#include <linux/vgaarb.h>
+
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+#include "nv50_display.h"
+
+static int nouveau_stub_init(struct drm_device *dev) { return 0; }
+static void nouveau_stub_takedown(struct drm_device *dev) {}
+
+static int nouveau_init_engine_ptrs(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
+
+	switch (dev_priv->chipset & 0xf0) {
+	case 0x00:
+		engine->instmem.init		= nv04_instmem_init;
+		engine->instmem.takedown	= nv04_instmem_takedown;
+		engine->instmem.suspend		= nv04_instmem_suspend;
+		engine->instmem.resume		= nv04_instmem_resume;
+		engine->instmem.populate	= nv04_instmem_populate;
+		engine->instmem.clear		= nv04_instmem_clear;
+		engine->instmem.bind		= nv04_instmem_bind;
+		engine->instmem.unbind		= nv04_instmem_unbind;
+		engine->instmem.prepare_access	= nv04_instmem_prepare_access;
+		engine->instmem.finish_access	= nv04_instmem_finish_access;
+		engine->mc.init			= nv04_mc_init;
+		engine->mc.takedown		= nv04_mc_takedown;
+		engine->timer.init		= nv04_timer_init;
+		engine->timer.read		= nv04_timer_read;
+		engine->timer.takedown		= nv04_timer_takedown;
+		engine->fb.init			= nv04_fb_init;
+		engine->fb.takedown		= nv04_fb_takedown;
+		engine->graph.grclass		= nv04_graph_grclass;
+		engine->graph.init		= nv04_graph_init;
+		engine->graph.takedown		= nv04_graph_takedown;
+		engine->graph.fifo_access	= nv04_graph_fifo_access;
+		engine->graph.channel		= nv04_graph_channel;
+		engine->graph.create_context	= nv04_graph_create_context;
+		engine->graph.destroy_context	= nv04_graph_destroy_context;
+		engine->graph.load_context	= nv04_graph_load_context;
+		engine->graph.unload_context	= nv04_graph_unload_context;
+		engine->fifo.channels		= 16;
+		engine->fifo.init		= nv04_fifo_init;
+		engine->fifo.takedown		= nouveau_stub_takedown;
+		engine->fifo.disable		= nv04_fifo_disable;
+		engine->fifo.enable		= nv04_fifo_enable;
+		engine->fifo.reassign		= nv04_fifo_reassign;
+		engine->fifo.channel_id		= nv04_fifo_channel_id;
+		engine->fifo.create_context	= nv04_fifo_create_context;
+		engine->fifo.destroy_context	= nv04_fifo_destroy_context;
+		engine->fifo.load_context	= nv04_fifo_load_context;
+		engine->fifo.unload_context	= nv04_fifo_unload_context;
+		break;
+	case 0x10:
+		engine->instmem.init		= nv04_instmem_init;
+		engine->instmem.takedown	= nv04_instmem_takedown;
+		engine->instmem.suspend		= nv04_instmem_suspend;
+		engine->instmem.resume		= nv04_instmem_resume;
+		engine->instmem.populate	= nv04_instmem_populate;
+		engine->instmem.clear		= nv04_instmem_clear;
+		engine->instmem.bind		= nv04_instmem_bind;
+		engine->instmem.unbind		= nv04_instmem_unbind;
+		engine->instmem.prepare_access	= nv04_instmem_prepare_access;
+		engine->instmem.finish_access	= nv04_instmem_finish_access;
+		engine->mc.init			= nv04_mc_init;
+		engine->mc.takedown		= nv04_mc_takedown;
+		engine->timer.init		= nv04_timer_init;
+		engine->timer.read		= nv04_timer_read;
+		engine->timer.takedown		= nv04_timer_takedown;
+		engine->fb.init			= nv10_fb_init;
+		engine->fb.takedown		= nv10_fb_takedown;
+		engine->graph.grclass		= nv10_graph_grclass;
+		engine->graph.init		= nv10_graph_init;
+		engine->graph.takedown		= nv10_graph_takedown;
+		engine->graph.channel		= nv10_graph_channel;
+		engine->graph.create_context	= nv10_graph_create_context;
+		engine->graph.destroy_context	= nv10_graph_destroy_context;
+		engine->graph.fifo_access	= nv04_graph_fifo_access;
+		engine->graph.load_context	= nv10_graph_load_context;
+		engine->graph.unload_context	= nv10_graph_unload_context;
+		engine->fifo.channels		= 32;
+		engine->fifo.init		= nv10_fifo_init;
+		engine->fifo.takedown		= nouveau_stub_takedown;
+		engine->fifo.disable		= nv04_fifo_disable;
+		engine->fifo.enable		= nv04_fifo_enable;
+		engine->fifo.reassign		= nv04_fifo_reassign;
+		engine->fifo.channel_id		= nv10_fifo_channel_id;
+		engine->fifo.create_context	= nv10_fifo_create_context;
+		engine->fifo.destroy_context	= nv10_fifo_destroy_context;
+		engine->fifo.load_context	= nv10_fifo_load_context;
+		engine->fifo.unload_context	= nv10_fifo_unload_context;
+		break;
+	case 0x20:
+		engine->instmem.init		= nv04_instmem_init;
+		engine->instmem.takedown	= nv04_instmem_takedown;
+		engine->instmem.suspend		= nv04_instmem_suspend;
+		engine->instmem.resume		= nv04_instmem_resume;
+		engine->instmem.populate	= nv04_instmem_populate;
+		engine->instmem.clear		= nv04_instmem_clear;
+		engine->instmem.bind		= nv04_instmem_bind;
+		engine->instmem.unbind		= nv04_instmem_unbind;
+		engine->instmem.prepare_access	= nv04_instmem_prepare_access;
+		engine->instmem.finish_access	= nv04_instmem_finish_access;
+		engine->mc.init			= nv04_mc_init;
+		engine->mc.takedown		= nv04_mc_takedown;
+		engine->timer.init		= nv04_timer_init;
+		engine->timer.read		= nv04_timer_read;
+		engine->timer.takedown		= nv04_timer_takedown;
+		engine->fb.init			= nv10_fb_init;
+		engine->fb.takedown		= nv10_fb_takedown;
+		engine->graph.grclass		= nv20_graph_grclass;
+		engine->graph.init		= nv20_graph_init;
+		engine->graph.takedown		= nv20_graph_takedown;
+		engine->graph.channel		= nv10_graph_channel;
+		engine->graph.create_context	= nv20_graph_create_context;
+		engine->graph.destroy_context	= nv20_graph_destroy_context;
+		engine->graph.fifo_access	= nv04_graph_fifo_access;
+		engine->graph.load_context	= nv20_graph_load_context;
+		engine->graph.unload_context	= nv20_graph_unload_context;
+		engine->fifo.channels		= 32;
+		engine->fifo.init		= nv10_fifo_init;
+		engine->fifo.takedown		= nouveau_stub_takedown;
+		engine->fifo.disable		= nv04_fifo_disable;
+		engine->fifo.enable		= nv04_fifo_enable;
+		engine->fifo.reassign		= nv04_fifo_reassign;
+		engine->fifo.channel_id		= nv10_fifo_channel_id;
+		engine->fifo.create_context	= nv10_fifo_create_context;
+		engine->fifo.destroy_context	= nv10_fifo_destroy_context;
+		engine->fifo.load_context	= nv10_fifo_load_context;
+		engine->fifo.unload_context	= nv10_fifo_unload_context;
+		break;
+	case 0x30:
+		engine->instmem.init		= nv04_instmem_init;
+		engine->instmem.takedown	= nv04_instmem_takedown;
+		engine->instmem.suspend		= nv04_instmem_suspend;
+		engine->instmem.resume		= nv04_instmem_resume;
+		engine->instmem.populate	= nv04_instmem_populate;
+		engine->instmem.clear		= nv04_instmem_clear;
+		engine->instmem.bind		= nv04_instmem_bind;
+		engine->instmem.unbind		= nv04_instmem_unbind;
+		engine->instmem.prepare_access	= nv04_instmem_prepare_access;
+		engine->instmem.finish_access	= nv04_instmem_finish_access;
+		engine->mc.init			= nv04_mc_init;
+		engine->mc.takedown		= nv04_mc_takedown;
+		engine->timer.init		= nv04_timer_init;
+		engine->timer.read		= nv04_timer_read;
+		engine->timer.takedown		= nv04_timer_takedown;
+		engine->fb.init			= nv10_fb_init;
+		engine->fb.takedown		= nv10_fb_takedown;
+		engine->graph.grclass		= nv30_graph_grclass;
+		engine->graph.init		= nv30_graph_init;
+		engine->graph.takedown		= nv20_graph_takedown;
+		engine->graph.fifo_access	= nv04_graph_fifo_access;
+		engine->graph.channel		= nv10_graph_channel;
+		engine->graph.create_context	= nv20_graph_create_context;
+		engine->graph.destroy_context	= nv20_graph_destroy_context;
+		engine->graph.load_context	= nv20_graph_load_context;
+		engine->graph.unload_context	= nv20_graph_unload_context;
+		engine->fifo.channels		= 32;
+		engine->fifo.init		= nv10_fifo_init;
+		engine->fifo.takedown		= nouveau_stub_takedown;
+		engine->fifo.disable		= nv04_fifo_disable;
+		engine->fifo.enable		= nv04_fifo_enable;
+		engine->fifo.reassign		= nv04_fifo_reassign;
+		engine->fifo.channel_id		= nv10_fifo_channel_id;
+		engine->fifo.create_context	= nv10_fifo_create_context;
+		engine->fifo.destroy_context	= nv10_fifo_destroy_context;
+		engine->fifo.load_context	= nv10_fifo_load_context;
+		engine->fifo.unload_context	= nv10_fifo_unload_context;
+		break;
+	case 0x40:
+	case 0x60:
+		engine->instmem.init		= nv04_instmem_init;
+		engine->instmem.takedown	= nv04_instmem_takedown;
+		engine->instmem.suspend		= nv04_instmem_suspend;
+		engine->instmem.resume		= nv04_instmem_resume;
+		engine->instmem.populate	= nv04_instmem_populate;
+		engine->instmem.clear		= nv04_instmem_clear;
+		engine->instmem.bind		= nv04_instmem_bind;
+		engine->instmem.unbind		= nv04_instmem_unbind;
+		engine->instmem.prepare_access	= nv04_instmem_prepare_access;
+		engine->instmem.finish_access	= nv04_instmem_finish_access;
+		engine->mc.init			= nv40_mc_init;
+		engine->mc.takedown		= nv40_mc_takedown;
+		engine->timer.init		= nv04_timer_init;
+		engine->timer.read		= nv04_timer_read;
+		engine->timer.takedown		= nv04_timer_takedown;
+		engine->fb.init			= nv40_fb_init;
+		engine->fb.takedown		= nv40_fb_takedown;
+		engine->graph.grclass		= nv40_graph_grclass;
+		engine->graph.init		= nv40_graph_init;
+		engine->graph.takedown		= nv40_graph_takedown;
+		engine->graph.fifo_access	= nv04_graph_fifo_access;
+		engine->graph.channel		= nv40_graph_channel;
+		engine->graph.create_context	= nv40_graph_create_context;
+		engine->graph.destroy_context	= nv40_graph_destroy_context;
+		engine->graph.load_context	= nv40_graph_load_context;
+		engine->graph.unload_context	= nv40_graph_unload_context;
+		engine->fifo.channels		= 32;
+		engine->fifo.init		= nv40_fifo_init;
+		engine->fifo.takedown		= nouveau_stub_takedown;
+		engine->fifo.disable		= nv04_fifo_disable;
+		engine->fifo.enable		= nv04_fifo_enable;
+		engine->fifo.reassign		= nv04_fifo_reassign;
+		engine->fifo.channel_id		= nv10_fifo_channel_id;
+		engine->fifo.create_context	= nv40_fifo_create_context;
+		engine->fifo.destroy_context	= nv40_fifo_destroy_context;
+		engine->fifo.load_context	= nv40_fifo_load_context;
+		engine->fifo.unload_context	= nv40_fifo_unload_context;
+		break;
+	case 0x50:
+	case 0x80: /* gotta love NVIDIA's consistency.. */
+	case 0x90:
+	case 0xA0:
+		engine->instmem.init		= nv50_instmem_init;
+		engine->instmem.takedown	= nv50_instmem_takedown;
+		engine->instmem.suspend		= nv50_instmem_suspend;
+		engine->instmem.resume		= nv50_instmem_resume;
+		engine->instmem.populate	= nv50_instmem_populate;
+		engine->instmem.clear		= nv50_instmem_clear;
+		engine->instmem.bind		= nv50_instmem_bind;
+		engine->instmem.unbind		= nv50_instmem_unbind;
+		engine->instmem.prepare_access	= nv50_instmem_prepare_access;
+		engine->instmem.finish_access	= nv50_instmem_finish_access;
+		engine->mc.init			= nv50_mc_init;
+		engine->mc.takedown		= nv50_mc_takedown;
+		engine->timer.init		= nv04_timer_init;
+		engine->timer.read		= nv04_timer_read;
+		engine->timer.takedown		= nv04_timer_takedown;
+		engine->fb.init			= nouveau_stub_init;
+		engine->fb.takedown		= nouveau_stub_takedown;
+		engine->graph.grclass		= nv50_graph_grclass;
+		engine->graph.init		= nv50_graph_init;
+		engine->graph.takedown		= nv50_graph_takedown;
+		engine->graph.fifo_access	= nv50_graph_fifo_access;
+		engine->graph.channel		= nv50_graph_channel;
+		engine->graph.create_context	= nv50_graph_create_context;
+		engine->graph.destroy_context	= nv50_graph_destroy_context;
+		engine->graph.load_context	= nv50_graph_load_context;
+		engine->graph.unload_context	= nv50_graph_unload_context;
+		engine->fifo.channels		= 128;
+		engine->fifo.init		= nv50_fifo_init;
+		engine->fifo.takedown		= nv50_fifo_takedown;
+		engine->fifo.disable		= nv04_fifo_disable;
+		engine->fifo.enable		= nv04_fifo_enable;
+		engine->fifo.reassign		= nv04_fifo_reassign;
+		engine->fifo.channel_id		= nv50_fifo_channel_id;
+		engine->fifo.create_context	= nv50_fifo_create_context;
+		engine->fifo.destroy_context	= nv50_fifo_destroy_context;
+		engine->fifo.load_context	= nv50_fifo_load_context;
+		engine->fifo.unload_context	= nv50_fifo_unload_context;
+		break;
+	default:
+		NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
+		return 1;
+	}
+
+	return 0;
+}
+
+static unsigned int
+nouveau_vga_set_decode(void *priv, bool state)
+{
+	if (state)
+		return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
+		       VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
+	else
+		return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
+}
+
+int
+nouveau_card_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine;
+	struct nouveau_gpuobj *gpuobj;
+	int ret;
+
+	NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state);
+
+	if (dev_priv->init_state == NOUVEAU_CARD_INIT_DONE)
+		return 0;
+
+	vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode);
+
+	/* Initialise internal driver API hooks */
+	ret = nouveau_init_engine_ptrs(dev);
+	if (ret)
+		return ret;
+	engine = &dev_priv->engine;
+	dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED;
+
+	/* Parse BIOS tables / Run init tables if card not POSTed */
+	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+		ret = nouveau_bios_init(dev);
+		if (ret)
+			return ret;
+	}
+
+	ret = nouveau_gpuobj_early_init(dev);
+	if (ret)
+		return ret;
+
+	/* Initialise instance memory, must happen before mem_init so we
+	 * know exactly how much VRAM we're able to use for "normal"
+	 * purposes.
+	 */
+	ret = engine->instmem.init(dev);
+	if (ret)
+		return ret;
+
+	/* Setup the memory manager */
+	ret = nouveau_mem_init(dev);
+	if (ret)
+		return ret;
+
+	ret = nouveau_gpuobj_init(dev);
+	if (ret)
+		return ret;
+
+	/* PMC */
+	ret = engine->mc.init(dev);
+	if (ret)
+		return ret;
+
+	/* PTIMER */
+	ret = engine->timer.init(dev);
+	if (ret)
+		return ret;
+
+	/* PFB */
+	ret = engine->fb.init(dev);
+	if (ret)
+		return ret;
+
+	/* PGRAPH */
+	ret = engine->graph.init(dev);
+	if (ret)
+		return ret;
+
+	/* PFIFO */
+	ret = engine->fifo.init(dev);
+	if (ret)
+		return ret;
+
+	/* this call irq_preinstall, register irq handler and
+	 * call irq_postinstall
+	 */
+	ret = drm_irq_install(dev);
+	if (ret)
+		return ret;
+
+	ret = drm_vblank_init(dev, 0);
+	if (ret)
+		return ret;
+
+	/* what about PVIDEO/PCRTC/PRAMDAC etc? */
+
+	ret = nouveau_channel_alloc(dev, &dev_priv->channel,
+				    (struct drm_file *)-2,
+				    NvDmaFB, NvDmaTT);
+	if (ret)
+		return ret;
+
+	gpuobj = NULL;
+	ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY,
+				     0, nouveau_mem_fb_amount(dev),
+				     NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM,
+				     &gpuobj);
+	if (ret)
+		return ret;
+
+	ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaVRAM,
+				     gpuobj, NULL);
+	if (ret) {
+		nouveau_gpuobj_del(dev, &gpuobj);
+		return ret;
+	}
+
+	gpuobj = NULL;
+	ret = nouveau_gpuobj_gart_dma_new(dev_priv->channel, 0,
+					  dev_priv->gart_info.aper_size,
+					  NV_DMA_ACCESS_RW, &gpuobj, NULL);
+	if (ret)
+		return ret;
+
+	ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaGART,
+				     gpuobj, NULL);
+	if (ret) {
+		nouveau_gpuobj_del(dev, &gpuobj);
+		return ret;
+	}
+
+	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+		if (dev_priv->card_type >= NV_50) {
+			ret = nv50_display_create(dev);
+			if (ret)
+				return ret;
+		} else {
+			ret = nv04_display_create(dev);
+			if (ret)
+				return ret;
+		}
+	}
+
+	ret = nouveau_backlight_init(dev);
+	if (ret)
+		NV_ERROR(dev, "Error %d registering backlight\n", ret);
+
+	dev_priv->init_state = NOUVEAU_CARD_INIT_DONE;
+
+	if (drm_core_check_feature(dev, DRIVER_MODESET))
+		drm_helper_initial_config(dev);
+
+	return 0;
+}
+
+static void nouveau_card_takedown(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
+
+	NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state);
+
+	if (dev_priv->init_state != NOUVEAU_CARD_INIT_DOWN) {
+		nouveau_backlight_exit(dev);
+
+		if (dev_priv->channel) {
+			nouveau_channel_free(dev_priv->channel);
+			dev_priv->channel = NULL;
+		}
+
+		engine->fifo.takedown(dev);
+		engine->graph.takedown(dev);
+		engine->fb.takedown(dev);
+		engine->timer.takedown(dev);
+		engine->mc.takedown(dev);
+
+		mutex_lock(&dev->struct_mutex);
+		ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT);
+		mutex_unlock(&dev->struct_mutex);
+		nouveau_sgdma_takedown(dev);
+
+		nouveau_gpuobj_takedown(dev);
+		nouveau_mem_close(dev);
+		engine->instmem.takedown(dev);
+
+		if (drm_core_check_feature(dev, DRIVER_MODESET))
+			drm_irq_uninstall(dev);
+
+		nouveau_gpuobj_late_takedown(dev);
+		nouveau_bios_takedown(dev);
+
+		vga_client_register(dev->pdev, NULL, NULL, NULL);
+
+		dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN;
+	}
+}
+
+/* here a client dies, release the stuff that was allocated for its
+ * file_priv */
+void nouveau_preclose(struct drm_device *dev, struct drm_file *file_priv)
+{
+	nouveau_channel_cleanup(dev, file_priv);
+}
+
+/* first module load, setup the mmio/fb mapping */
+/* KMS: we need mmio at load time, not when the first drm client opens. */
+int nouveau_firstopen(struct drm_device *dev)
+{
+	return 0;
+}
+
+/* if we have an OF card, copy vbios to RAMIN */
+static void nouveau_OF_copy_vbios_to_ramin(struct drm_device *dev)
+{
+#if defined(__powerpc__)
+	int size, i;
+	const uint32_t *bios;
+	struct device_node *dn = pci_device_to_OF_node(dev->pdev);
+	if (!dn) {
+		NV_INFO(dev, "Unable to get the OF node\n");
+		return;
+	}
+
+	bios = of_get_property(dn, "NVDA,BMP", &size);
+	if (bios) {
+		for (i = 0; i < size; i += 4)
+			nv_wi32(dev, i, bios[i/4]);
+		NV_INFO(dev, "OF bios successfully copied (%d bytes)\n", size);
+	} else {
+		NV_INFO(dev, "Unable to get the OF bios\n");
+	}
+#endif
+}
+
+int nouveau_load(struct drm_device *dev, unsigned long flags)
+{
+	struct drm_nouveau_private *dev_priv;
+	uint32_t reg0;
+	resource_size_t mmio_start_offs;
+
+	dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
+	if (!dev_priv)
+		return -ENOMEM;
+	dev->dev_private = dev_priv;
+	dev_priv->dev = dev;
+
+	dev_priv->flags = flags & NOUVEAU_FLAGS;
+	dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN;
+
+	NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n",
+		 dev->pci_vendor, dev->pci_device, dev->pdev->class);
+
+	dev_priv->acpi_dsm = nouveau_dsm_probe(dev);
+
+	if (dev_priv->acpi_dsm)
+		nouveau_hybrid_setup(dev);
+
+	dev_priv->wq = create_workqueue("nouveau");
+	if (!dev_priv->wq)
+		return -EINVAL;
+
+	/* resource 0 is mmio regs */
+	/* resource 1 is linear FB */
+	/* resource 2 is RAMIN (mmio regs + 0x1000000) */
+	/* resource 6 is bios */
+
+	/* map the mmio regs */
+	mmio_start_offs = pci_resource_start(dev->pdev, 0);
+	dev_priv->mmio = ioremap(mmio_start_offs, 0x00800000);
+	if (!dev_priv->mmio) {
+		NV_ERROR(dev, "Unable to initialize the mmio mapping. "
+			 "Please report your setup to " DRIVER_EMAIL "\n");
+		return -EINVAL;
+	}
+	NV_DEBUG(dev, "regs mapped ok at 0x%llx\n",
+					(unsigned long long)mmio_start_offs);
+
+#ifdef __BIG_ENDIAN
+	/* Put the card in BE mode if it's not */
+	if (nv_rd32(dev, NV03_PMC_BOOT_1))
+		nv_wr32(dev, NV03_PMC_BOOT_1, 0x00000001);
+
+	DRM_MEMORYBARRIER();
+#endif
+
+	/* Time to determine the card architecture */
+	reg0 = nv_rd32(dev, NV03_PMC_BOOT_0);
+
+	/* We're dealing with >=NV10 */
+	if ((reg0 & 0x0f000000) > 0) {
+		/* Bit 27-20 contain the architecture in hex */
+		dev_priv->chipset = (reg0 & 0xff00000) >> 20;
+	/* NV04 or NV05 */
+	} else if ((reg0 & 0xff00fff0) == 0x20004000) {
+		dev_priv->chipset = 0x04;
+	} else
+		dev_priv->chipset = 0xff;
+
+	switch (dev_priv->chipset & 0xf0) {
+	case 0x00:
+	case 0x10:
+	case 0x20:
+	case 0x30:
+		dev_priv->card_type = dev_priv->chipset & 0xf0;
+		break;
+	case 0x40:
+	case 0x60:
+		dev_priv->card_type = NV_40;
+		break;
+	case 0x50:
+	case 0x80:
+	case 0x90:
+	case 0xa0:
+		dev_priv->card_type = NV_50;
+		break;
+	default:
+		NV_INFO(dev, "Unsupported chipset 0x%08x\n", reg0);
+		return -EINVAL;
+	}
+
+	NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n",
+		dev_priv->card_type, reg0);
+
+	/* map larger RAMIN aperture on NV40 cards */
+	dev_priv->ramin  = NULL;
+	if (dev_priv->card_type >= NV_40) {
+		int ramin_bar = 2;
+		if (pci_resource_len(dev->pdev, ramin_bar) == 0)
+			ramin_bar = 3;
+
+		dev_priv->ramin_size = pci_resource_len(dev->pdev, ramin_bar);
+		dev_priv->ramin = ioremap(
+				pci_resource_start(dev->pdev, ramin_bar),
+				dev_priv->ramin_size);
+		if (!dev_priv->ramin) {
+			NV_ERROR(dev, "Failed to init RAMIN mapping, "
+				      "limited instance memory available\n");
+		}
+	}
+
+	/* On older cards (or if the above failed), create a map covering
+	 * the BAR0 PRAMIN aperture */
+	if (!dev_priv->ramin) {
+		dev_priv->ramin_size = 1 * 1024 * 1024;
+		dev_priv->ramin = ioremap(mmio_start_offs + NV_RAMIN,
+							dev_priv->ramin_size);
+		if (!dev_priv->ramin) {
+			NV_ERROR(dev, "Failed to map BAR0 PRAMIN.\n");
+			return -ENOMEM;
+		}
+	}
+
+	nouveau_OF_copy_vbios_to_ramin(dev);
+
+	/* Special flags */
+	if (dev->pci_device == 0x01a0)
+		dev_priv->flags |= NV_NFORCE;
+	else if (dev->pci_device == 0x01f0)
+		dev_priv->flags |= NV_NFORCE2;
+
+	/* For kernel modesetting, init card now and bring up fbcon */
+	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+		int ret = nouveau_card_init(dev);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static void nouveau_close(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	/* In the case of an error dev_priv may not be be allocated yet */
+	if (dev_priv && dev_priv->card_type)
+		nouveau_card_takedown(dev);
+}
+
+/* KMS: we need mmio at load time, not when the first drm client opens. */
+void nouveau_lastclose(struct drm_device *dev)
+{
+	if (drm_core_check_feature(dev, DRIVER_MODESET))
+		return;
+
+	nouveau_close(dev);
+}
+
+int nouveau_unload(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+		if (dev_priv->card_type >= NV_50)
+			nv50_display_destroy(dev);
+		else
+			nv04_display_destroy(dev);
+		nouveau_close(dev);
+	}
+
+	iounmap(dev_priv->mmio);
+	iounmap(dev_priv->ramin);
+
+	kfree(dev_priv);
+	dev->dev_private = NULL;
+	return 0;
+}
+
+int
+nouveau_ioctl_card_init(struct drm_device *dev, void *data,
+			struct drm_file *file_priv)
+{
+	return nouveau_card_init(dev);
+}
+
+int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
+						struct drm_file *file_priv)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_nouveau_getparam *getparam = data;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
+	switch (getparam->param) {
+	case NOUVEAU_GETPARAM_CHIPSET_ID:
+		getparam->value = dev_priv->chipset;
+		break;
+	case NOUVEAU_GETPARAM_PCI_VENDOR:
+		getparam->value = dev->pci_vendor;
+		break;
+	case NOUVEAU_GETPARAM_PCI_DEVICE:
+		getparam->value = dev->pci_device;
+		break;
+	case NOUVEAU_GETPARAM_BUS_TYPE:
+		if (drm_device_is_agp(dev))
+			getparam->value = NV_AGP;
+		else if (drm_device_is_pcie(dev))
+			getparam->value = NV_PCIE;
+		else
+			getparam->value = NV_PCI;
+		break;
+	case NOUVEAU_GETPARAM_FB_PHYSICAL:
+		getparam->value = dev_priv->fb_phys;
+		break;
+	case NOUVEAU_GETPARAM_AGP_PHYSICAL:
+		getparam->value = dev_priv->gart_info.aper_base;
+		break;
+	case NOUVEAU_GETPARAM_PCI_PHYSICAL:
+		if (dev->sg) {
+			getparam->value = (unsigned long)dev->sg->virtual;
+		} else {
+			NV_ERROR(dev, "Requested PCIGART address, "
+					"while no PCIGART was created\n");
+			return -EINVAL;
+		}
+		break;
+	case NOUVEAU_GETPARAM_FB_SIZE:
+		getparam->value = dev_priv->fb_available_size;
+		break;
+	case NOUVEAU_GETPARAM_AGP_SIZE:
+		getparam->value = dev_priv->gart_info.aper_size;
+		break;
+	case NOUVEAU_GETPARAM_VM_VRAM_BASE:
+		getparam->value = dev_priv->vm_vram_base;
+		break;
+	default:
+		NV_ERROR(dev, "unknown parameter %lld\n", getparam->param);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int
+nouveau_ioctl_setparam(struct drm_device *dev, void *data,
+		       struct drm_file *file_priv)
+{
+	struct drm_nouveau_setparam *setparam = data;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
+	switch (setparam->param) {
+	default:
+		NV_ERROR(dev, "unknown parameter %lld\n", setparam->param);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* Wait until (value(reg) & mask) == val, up until timeout has hit */
+bool nouveau_wait_until(struct drm_device *dev, uint64_t timeout,
+			uint32_t reg, uint32_t mask, uint32_t val)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
+	uint64_t start = ptimer->read(dev);
+
+	do {
+		if ((nv_rd32(dev, reg) & mask) == val)
+			return true;
+	} while (ptimer->read(dev) - start < timeout);
+
+	return false;
+}
+
+/* Waits for PGRAPH to go completely idle */
+bool nouveau_wait_for_idle(struct drm_device *dev)
+{
+	if (!nv_wait(NV04_PGRAPH_STATUS, 0xffffffff, 0x00000000)) {
+		NV_ERROR(dev, "PGRAPH idle timed out with status 0x%08x\n",
+			 nv_rd32(dev, NV04_PGRAPH_STATUS));
+		return false;
+	}
+
+	return true;
+}
+
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c
new file mode 100644
index 0000000..187eb84
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA,
+ * All Rights Reserved.
+ * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA,
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+
+#include "nouveau_drv.h"
+
+static struct vm_operations_struct nouveau_ttm_vm_ops;
+static const struct vm_operations_struct *ttm_vm_ops;
+
+static int
+nouveau_ttm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+	struct ttm_buffer_object *bo = vma->vm_private_data;
+	int ret;
+
+	if (unlikely(bo == NULL))
+		return VM_FAULT_NOPAGE;
+
+	ret = ttm_vm_ops->fault(vma, vmf);
+	return ret;
+}
+
+int
+nouveau_ttm_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	struct drm_file *file_priv = filp->private_data;
+	struct drm_nouveau_private *dev_priv =
+		file_priv->minor->dev->dev_private;
+	int ret;
+
+	if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET))
+		return drm_mmap(filp, vma);
+
+	ret = ttm_bo_mmap(filp, vma, &dev_priv->ttm.bdev);
+	if (unlikely(ret != 0))
+		return ret;
+
+	if (unlikely(ttm_vm_ops == NULL)) {
+		ttm_vm_ops = vma->vm_ops;
+		nouveau_ttm_vm_ops = *ttm_vm_ops;
+		nouveau_ttm_vm_ops.fault = &nouveau_ttm_fault;
+	}
+
+	vma->vm_ops = &nouveau_ttm_vm_ops;
+	return 0;
+}
+
+static int
+nouveau_ttm_mem_global_init(struct ttm_global_reference *ref)
+{
+	return ttm_mem_global_init(ref->object);
+}
+
+static void
+nouveau_ttm_mem_global_release(struct ttm_global_reference *ref)
+{
+	ttm_mem_global_release(ref->object);
+}
+
+int
+nouveau_ttm_global_init(struct drm_nouveau_private *dev_priv)
+{
+	struct ttm_global_reference *global_ref;
+	int ret;
+
+	global_ref = &dev_priv->ttm.mem_global_ref;
+	global_ref->global_type = TTM_GLOBAL_TTM_MEM;
+	global_ref->size = sizeof(struct ttm_mem_global);
+	global_ref->init = &nouveau_ttm_mem_global_init;
+	global_ref->release = &nouveau_ttm_mem_global_release;
+
+	ret = ttm_global_item_ref(global_ref);
+	if (unlikely(ret != 0)) {
+		DRM_ERROR("Failed setting up TTM memory accounting\n");
+		dev_priv->ttm.mem_global_ref.release = NULL;
+		return ret;
+	}
+
+	dev_priv->ttm.bo_global_ref.mem_glob = global_ref->object;
+	global_ref = &dev_priv->ttm.bo_global_ref.ref;
+	global_ref->global_type = TTM_GLOBAL_TTM_BO;
+	global_ref->size = sizeof(struct ttm_bo_global);
+	global_ref->init = &ttm_bo_global_init;
+	global_ref->release = &ttm_bo_global_release;
+
+	ret = ttm_global_item_ref(global_ref);
+	if (unlikely(ret != 0)) {
+		DRM_ERROR("Failed setting up TTM BO subsystem\n");
+		ttm_global_item_unref(&dev_priv->ttm.mem_global_ref);
+		dev_priv->ttm.mem_global_ref.release = NULL;
+		return ret;
+	}
+
+	return 0;
+}
+
+void
+nouveau_ttm_global_release(struct drm_nouveau_private *dev_priv)
+{
+	if (dev_priv->ttm.mem_global_ref.release == NULL)
+		return;
+
+	ttm_global_item_unref(&dev_priv->ttm.bo_global_ref.ref);
+	ttm_global_item_unref(&dev_priv->ttm.mem_global_ref);
+	dev_priv->ttm.mem_global_ref.release = NULL;
+}
+
diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c
new file mode 100644
index 0000000..b913636
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv04_crtc.c
@@ -0,0 +1,1002 @@
+/*
+ * Copyright 1993-2003 NVIDIA, Corporation
+ * Copyright 2006 Dave Airlie
+ * Copyright 2007 Maarten Maathuis
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+#include "drm_crtc_helper.h"
+
+#include "nouveau_drv.h"
+#include "nouveau_encoder.h"
+#include "nouveau_connector.h"
+#include "nouveau_crtc.h"
+#include "nouveau_fb.h"
+#include "nouveau_hw.h"
+#include "nvreg.h"
+
+static int
+nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+			struct drm_framebuffer *old_fb);
+
+static void
+crtc_wr_cio_state(struct drm_crtc *crtc, struct nv04_crtc_reg *crtcstate, int index)
+{
+	NVWriteVgaCrtc(crtc->dev, nouveau_crtc(crtc)->index, index,
+		       crtcstate->CRTC[index]);
+}
+
+static void nv_crtc_set_digital_vibrance(struct drm_crtc *crtc, int level)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct drm_nouveau_private *dev_priv = crtc->dev->dev_private;
+	struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
+
+	regp->CRTC[NV_CIO_CRE_CSB] = nv_crtc->saturation = level;
+	if (nv_crtc->saturation && nv_gf4_disp_arch(crtc->dev)) {
+		regp->CRTC[NV_CIO_CRE_CSB] = 0x80;
+		regp->CRTC[NV_CIO_CRE_5B] = nv_crtc->saturation << 2;
+		crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_5B);
+	}
+	crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_CSB);
+}
+
+static void nv_crtc_set_image_sharpening(struct drm_crtc *crtc, int level)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct drm_nouveau_private *dev_priv = crtc->dev->dev_private;
+	struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
+
+	nv_crtc->sharpness = level;
+	if (level < 0)	/* blur is in hw range 0x3f -> 0x20 */
+		level += 0x40;
+	regp->ramdac_634 = level;
+	NVWriteRAMDAC(crtc->dev, nv_crtc->index, NV_PRAMDAC_634, regp->ramdac_634);
+}
+
+#define PLLSEL_VPLL1_MASK				\
+	(NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_VPLL	\
+	 | NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO_DB2)
+#define PLLSEL_VPLL2_MASK				\
+	(NV_PRAMDAC_PLL_COEFF_SELECT_PLL_SOURCE_VPLL2		\
+	 | NV_PRAMDAC_PLL_COEFF_SELECT_VCLK2_RATIO_DB2)
+#define PLLSEL_TV_MASK					\
+	(NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK1		\
+	 | NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK1		\
+	 | NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK2	\
+	 | NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK2)
+
+/* NV4x 0x40.. pll notes:
+ * gpu pll: 0x4000 + 0x4004
+ * ?gpu? pll: 0x4008 + 0x400c
+ * vpll1: 0x4010 + 0x4014
+ * vpll2: 0x4018 + 0x401c
+ * mpll: 0x4020 + 0x4024
+ * mpll: 0x4038 + 0x403c
+ *
+ * the first register of each pair has some unknown details:
+ * bits 0-7: redirected values from elsewhere? (similar to PLL_SETUP_CONTROL?)
+ * bits 20-23: (mpll) something to do with post divider?
+ * bits 28-31: related to single stage mode? (bit 8/12)
+ */
+
+static void nv_crtc_calc_state_ext(struct drm_crtc *crtc, struct drm_display_mode * mode, int dot_clock)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct nv04_mode_state *state = &dev_priv->mode_reg;
+	struct nv04_crtc_reg *regp = &state->crtc_reg[nv_crtc->index];
+	struct nouveau_pll_vals *pv = &regp->pllvals;
+	struct pll_lims pll_lim;
+
+	if (get_pll_limits(dev, nv_crtc->index ? VPLL2 : VPLL1, &pll_lim))
+		return;
+
+	/* NM2 == 0 is used to determine single stage mode on two stage plls */
+	pv->NM2 = 0;
+
+	/* for newer nv4x the blob uses only the first stage of the vpll below a
+	 * certain clock.  for a certain nv4b this is 150MHz.  since the max
+	 * output frequency of the first stage for this card is 300MHz, it is
+	 * assumed the threshold is given by vco1 maxfreq/2
+	 */
+	/* for early nv4x, specifically nv40 and *some* nv43 (devids 0 and 6,
+	 * not 8, others unknown), the blob always uses both plls.  no problem
+	 * has yet been observed in allowing the use a single stage pll on all
+	 * nv43 however.  the behaviour of single stage use is untested on nv40
+	 */
+	if (dev_priv->chipset > 0x40 && dot_clock <= (pll_lim.vco1.maxfreq / 2))
+		memset(&pll_lim.vco2, 0, sizeof(pll_lim.vco2));
+
+	if (!nouveau_calc_pll_mnp(dev, &pll_lim, dot_clock, pv))
+		return;
+
+	state->pllsel &= PLLSEL_VPLL1_MASK | PLLSEL_VPLL2_MASK | PLLSEL_TV_MASK;
+
+	/* The blob uses this always, so let's do the same */
+	if (dev_priv->card_type == NV_40)
+		state->pllsel |= NV_PRAMDAC_PLL_COEFF_SELECT_USE_VPLL2_TRUE;
+	/* again nv40 and some nv43 act more like nv3x as described above */
+	if (dev_priv->chipset < 0x41)
+		state->pllsel |= NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_MPLL |
+				 NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_NVPLL;
+	state->pllsel |= nv_crtc->index ? PLLSEL_VPLL2_MASK : PLLSEL_VPLL1_MASK;
+
+	if (pv->NM2)
+		NV_TRACE(dev, "vpll: n1 %d n2 %d m1 %d m2 %d log2p %d\n",
+			 pv->N1, pv->N2, pv->M1, pv->M2, pv->log2P);
+	else
+		NV_TRACE(dev, "vpll: n %d m %d log2p %d\n",
+			 pv->N1, pv->M1, pv->log2P);
+
+	nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.offset);
+}
+
+static void
+nv_crtc_dpms(struct drm_crtc *crtc, int mode)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	unsigned char seq1 = 0, crtc17 = 0;
+	unsigned char crtc1A;
+
+	NV_TRACE(dev, "Setting dpms mode %d on CRTC %d\n", mode,
+							nv_crtc->index);
+
+	if (nv_crtc->last_dpms == mode) /* Don't do unnecesary mode changes. */
+		return;
+
+	nv_crtc->last_dpms = mode;
+
+	if (nv_two_heads(dev))
+		NVSetOwner(dev, nv_crtc->index);
+
+	/* nv4ref indicates these two RPC1 bits inhibit h/v sync */
+	crtc1A = NVReadVgaCrtc(dev, nv_crtc->index,
+					NV_CIO_CRE_RPC1_INDEX) & ~0xC0;
+	switch (mode) {
+	case DRM_MODE_DPMS_STANDBY:
+		/* Screen: Off; HSync: Off, VSync: On -- Not Supported */
+		seq1 = 0x20;
+		crtc17 = 0x80;
+		crtc1A |= 0x80;
+		break;
+	case DRM_MODE_DPMS_SUSPEND:
+		/* Screen: Off; HSync: On, VSync: Off -- Not Supported */
+		seq1 = 0x20;
+		crtc17 = 0x80;
+		crtc1A |= 0x40;
+		break;
+	case DRM_MODE_DPMS_OFF:
+		/* Screen: Off; HSync: Off, VSync: Off */
+		seq1 = 0x20;
+		crtc17 = 0x00;
+		crtc1A |= 0xC0;
+		break;
+	case DRM_MODE_DPMS_ON:
+	default:
+		/* Screen: On; HSync: On, VSync: On */
+		seq1 = 0x00;
+		crtc17 = 0x80;
+		break;
+	}
+
+	NVVgaSeqReset(dev, nv_crtc->index, true);
+	/* Each head has it's own sequencer, so we can turn it off when we want */
+	seq1 |= (NVReadVgaSeq(dev, nv_crtc->index, NV_VIO_SR_CLOCK_INDEX) & ~0x20);
+	NVWriteVgaSeq(dev, nv_crtc->index, NV_VIO_SR_CLOCK_INDEX, seq1);
+	crtc17 |= (NVReadVgaCrtc(dev, nv_crtc->index, NV_CIO_CR_MODE_INDEX) & ~0x80);
+	mdelay(10);
+	NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CR_MODE_INDEX, crtc17);
+	NVVgaSeqReset(dev, nv_crtc->index, false);
+
+	NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RPC1_INDEX, crtc1A);
+}
+
+static bool
+nv_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *mode,
+		   struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static void
+nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode *mode)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
+	struct drm_framebuffer *fb = crtc->fb;
+
+	/* Calculate our timings */
+	int horizDisplay	= (mode->crtc_hdisplay >> 3) 	- 1;
+	int horizStart		= (mode->crtc_hsync_start >> 3) 	- 1;
+	int horizEnd		= (mode->crtc_hsync_end >> 3) 	- 1;
+	int horizTotal		= (mode->crtc_htotal >> 3)		- 5;
+	int horizBlankStart	= (mode->crtc_hdisplay >> 3)		- 1;
+	int horizBlankEnd	= (mode->crtc_htotal >> 3)		- 1;
+	int vertDisplay		= mode->crtc_vdisplay			- 1;
+	int vertStart		= mode->crtc_vsync_start 		- 1;
+	int vertEnd		= mode->crtc_vsync_end			- 1;
+	int vertTotal		= mode->crtc_vtotal 			- 2;
+	int vertBlankStart	= mode->crtc_vdisplay 			- 1;
+	int vertBlankEnd	= mode->crtc_vtotal			- 1;
+
+	struct drm_encoder *encoder;
+	bool fp_output = false;
+
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+		if (encoder->crtc == crtc &&
+		    (nv_encoder->dcb->type == OUTPUT_LVDS ||
+		     nv_encoder->dcb->type == OUTPUT_TMDS))
+			fp_output = true;
+	}
+
+	if (fp_output) {
+		vertStart = vertTotal - 3;
+		vertEnd = vertTotal - 2;
+		vertBlankStart = vertStart;
+		horizStart = horizTotal - 5;
+		horizEnd = horizTotal - 2;
+		horizBlankEnd = horizTotal + 4;
+#if 0
+		if (dev->overlayAdaptor && dev_priv->card_type >= NV_10)
+			/* This reportedly works around some video overlay bandwidth problems */
+			horizTotal += 2;
+#endif
+	}
+
+	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+		vertTotal |= 1;
+
+#if 0
+	ErrorF("horizDisplay: 0x%X \n", horizDisplay);
+	ErrorF("horizStart: 0x%X \n", horizStart);
+	ErrorF("horizEnd: 0x%X \n", horizEnd);
+	ErrorF("horizTotal: 0x%X \n", horizTotal);
+	ErrorF("horizBlankStart: 0x%X \n", horizBlankStart);
+	ErrorF("horizBlankEnd: 0x%X \n", horizBlankEnd);
+	ErrorF("vertDisplay: 0x%X \n", vertDisplay);
+	ErrorF("vertStart: 0x%X \n", vertStart);
+	ErrorF("vertEnd: 0x%X \n", vertEnd);
+	ErrorF("vertTotal: 0x%X \n", vertTotal);
+	ErrorF("vertBlankStart: 0x%X \n", vertBlankStart);
+	ErrorF("vertBlankEnd: 0x%X \n", vertBlankEnd);
+#endif
+
+	/*
+	* compute correct Hsync & Vsync polarity
+	*/
+	if ((mode->flags & (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC))
+		&& (mode->flags & (DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC))) {
+
+		regp->MiscOutReg = 0x23;
+		if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+			regp->MiscOutReg |= 0x40;
+		if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+			regp->MiscOutReg |= 0x80;
+	} else {
+		int vdisplay = mode->vdisplay;
+		if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+			vdisplay *= 2;
+		if (mode->vscan > 1)
+			vdisplay *= mode->vscan;
+		if (vdisplay < 400)
+			regp->MiscOutReg = 0xA3;	/* +hsync -vsync */
+		else if (vdisplay < 480)
+			regp->MiscOutReg = 0x63;	/* -hsync +vsync */
+		else if (vdisplay < 768)
+			regp->MiscOutReg = 0xE3;	/* -hsync -vsync */
+		else
+			regp->MiscOutReg = 0x23;	/* +hsync +vsync */
+	}
+
+	regp->MiscOutReg |= (mode->clock_index & 0x03) << 2;
+
+	/*
+	 * Time Sequencer
+	 */
+	regp->Sequencer[NV_VIO_SR_RESET_INDEX] = 0x00;
+	/* 0x20 disables the sequencer */
+	if (mode->flags & DRM_MODE_FLAG_CLKDIV2)
+		regp->Sequencer[NV_VIO_SR_CLOCK_INDEX] = 0x29;
+	else
+		regp->Sequencer[NV_VIO_SR_CLOCK_INDEX] = 0x21;
+	regp->Sequencer[NV_VIO_SR_PLANE_MASK_INDEX] = 0x0F;
+	regp->Sequencer[NV_VIO_SR_CHAR_MAP_INDEX] = 0x00;
+	regp->Sequencer[NV_VIO_SR_MEM_MODE_INDEX] = 0x0E;
+
+	/*
+	 * CRTC
+	 */
+	regp->CRTC[NV_CIO_CR_HDT_INDEX] = horizTotal;
+	regp->CRTC[NV_CIO_CR_HDE_INDEX] = horizDisplay;
+	regp->CRTC[NV_CIO_CR_HBS_INDEX] = horizBlankStart;
+	regp->CRTC[NV_CIO_CR_HBE_INDEX] = (1 << 7) |
+					  XLATE(horizBlankEnd, 0, NV_CIO_CR_HBE_4_0);
+	regp->CRTC[NV_CIO_CR_HRS_INDEX] = horizStart;
+	regp->CRTC[NV_CIO_CR_HRE_INDEX] = XLATE(horizBlankEnd, 5, NV_CIO_CR_HRE_HBE_5) |
+					  XLATE(horizEnd, 0, NV_CIO_CR_HRE_4_0);
+	regp->CRTC[NV_CIO_CR_VDT_INDEX] = vertTotal;
+	regp->CRTC[NV_CIO_CR_OVL_INDEX] = XLATE(vertStart, 9, NV_CIO_CR_OVL_VRS_9) |
+					  XLATE(vertDisplay, 9, NV_CIO_CR_OVL_VDE_9) |
+					  XLATE(vertTotal, 9, NV_CIO_CR_OVL_VDT_9) |
+					  (1 << 4) |
+					  XLATE(vertBlankStart, 8, NV_CIO_CR_OVL_VBS_8) |
+					  XLATE(vertStart, 8, NV_CIO_CR_OVL_VRS_8) |
+					  XLATE(vertDisplay, 8, NV_CIO_CR_OVL_VDE_8) |
+					  XLATE(vertTotal, 8, NV_CIO_CR_OVL_VDT_8);
+	regp->CRTC[NV_CIO_CR_RSAL_INDEX] = 0x00;
+	regp->CRTC[NV_CIO_CR_CELL_HT_INDEX] = ((mode->flags & DRM_MODE_FLAG_DBLSCAN) ? MASK(NV_CIO_CR_CELL_HT_SCANDBL) : 0) |
+					      1 << 6 |
+					      XLATE(vertBlankStart, 9, NV_CIO_CR_CELL_HT_VBS_9);
+	regp->CRTC[NV_CIO_CR_CURS_ST_INDEX] = 0x00;
+	regp->CRTC[NV_CIO_CR_CURS_END_INDEX] = 0x00;
+	regp->CRTC[NV_CIO_CR_SA_HI_INDEX] = 0x00;
+	regp->CRTC[NV_CIO_CR_SA_LO_INDEX] = 0x00;
+	regp->CRTC[NV_CIO_CR_TCOFF_HI_INDEX] = 0x00;
+	regp->CRTC[NV_CIO_CR_TCOFF_LO_INDEX] = 0x00;
+	regp->CRTC[NV_CIO_CR_VRS_INDEX] = vertStart;
+	regp->CRTC[NV_CIO_CR_VRE_INDEX] = 1 << 5 | XLATE(vertEnd, 0, NV_CIO_CR_VRE_3_0);
+	regp->CRTC[NV_CIO_CR_VDE_INDEX] = vertDisplay;
+	/* framebuffer can be larger than crtc scanout area. */
+	regp->CRTC[NV_CIO_CR_OFFSET_INDEX] = fb->pitch / 8;
+	regp->CRTC[NV_CIO_CR_ULINE_INDEX] = 0x00;
+	regp->CRTC[NV_CIO_CR_VBS_INDEX] = vertBlankStart;
+	regp->CRTC[NV_CIO_CR_VBE_INDEX] = vertBlankEnd;
+	regp->CRTC[NV_CIO_CR_MODE_INDEX] = 0x43;
+	regp->CRTC[NV_CIO_CR_LCOMP_INDEX] = 0xff;
+
+	/*
+	 * Some extended CRTC registers (they are not saved with the rest of the vga regs).
+	 */
+
+	/* framebuffer can be larger than crtc scanout area. */
+	regp->CRTC[NV_CIO_CRE_RPC0_INDEX] = XLATE(fb->pitch / 8, 8, NV_CIO_CRE_RPC0_OFFSET_10_8);
+	regp->CRTC[NV_CIO_CRE_RPC1_INDEX] = mode->crtc_hdisplay < 1280 ?
+					    MASK(NV_CIO_CRE_RPC1_LARGE) : 0x00;
+	regp->CRTC[NV_CIO_CRE_LSR_INDEX] = XLATE(horizBlankEnd, 6, NV_CIO_CRE_LSR_HBE_6) |
+					   XLATE(vertBlankStart, 10, NV_CIO_CRE_LSR_VBS_10) |
+					   XLATE(vertStart, 10, NV_CIO_CRE_LSR_VRS_10) |
+					   XLATE(vertDisplay, 10, NV_CIO_CRE_LSR_VDE_10) |
+					   XLATE(vertTotal, 10, NV_CIO_CRE_LSR_VDT_10);
+	regp->CRTC[NV_CIO_CRE_HEB__INDEX] = XLATE(horizStart, 8, NV_CIO_CRE_HEB_HRS_8) |
+					    XLATE(horizBlankStart, 8, NV_CIO_CRE_HEB_HBS_8) |
+					    XLATE(horizDisplay, 8, NV_CIO_CRE_HEB_HDE_8) |
+					    XLATE(horizTotal, 8, NV_CIO_CRE_HEB_HDT_8);
+	regp->CRTC[NV_CIO_CRE_EBR_INDEX] = XLATE(vertBlankStart, 11, NV_CIO_CRE_EBR_VBS_11) |
+					   XLATE(vertStart, 11, NV_CIO_CRE_EBR_VRS_11) |
+					   XLATE(vertDisplay, 11, NV_CIO_CRE_EBR_VDE_11) |
+					   XLATE(vertTotal, 11, NV_CIO_CRE_EBR_VDT_11);
+
+	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
+		horizTotal = (horizTotal >> 1) & ~1;
+		regp->CRTC[NV_CIO_CRE_ILACE__INDEX] = horizTotal;
+		regp->CRTC[NV_CIO_CRE_HEB__INDEX] |= XLATE(horizTotal, 8, NV_CIO_CRE_HEB_ILC_8);
+	} else
+		regp->CRTC[NV_CIO_CRE_ILACE__INDEX] = 0xff;  /* interlace off */
+
+	/*
+	* Graphics Display Controller
+	*/
+	regp->Graphics[NV_VIO_GX_SR_INDEX] = 0x00;
+	regp->Graphics[NV_VIO_GX_SREN_INDEX] = 0x00;
+	regp->Graphics[NV_VIO_GX_CCOMP_INDEX] = 0x00;
+	regp->Graphics[NV_VIO_GX_ROP_INDEX] = 0x00;
+	regp->Graphics[NV_VIO_GX_READ_MAP_INDEX] = 0x00;
+	regp->Graphics[NV_VIO_GX_MODE_INDEX] = 0x40; /* 256 color mode */
+	regp->Graphics[NV_VIO_GX_MISC_INDEX] = 0x05; /* map 64k mem + graphic mode */
+	regp->Graphics[NV_VIO_GX_DONT_CARE_INDEX] = 0x0F;
+	regp->Graphics[NV_VIO_GX_BIT_MASK_INDEX] = 0xFF;
+
+	regp->Attribute[0]  = 0x00; /* standard colormap translation */
+	regp->Attribute[1]  = 0x01;
+	regp->Attribute[2]  = 0x02;
+	regp->Attribute[3]  = 0x03;
+	regp->Attribute[4]  = 0x04;
+	regp->Attribute[5]  = 0x05;
+	regp->Attribute[6]  = 0x06;
+	regp->Attribute[7]  = 0x07;
+	regp->Attribute[8]  = 0x08;
+	regp->Attribute[9]  = 0x09;
+	regp->Attribute[10] = 0x0A;
+	regp->Attribute[11] = 0x0B;
+	regp->Attribute[12] = 0x0C;
+	regp->Attribute[13] = 0x0D;
+	regp->Attribute[14] = 0x0E;
+	regp->Attribute[15] = 0x0F;
+	regp->Attribute[NV_CIO_AR_MODE_INDEX] = 0x01; /* Enable graphic mode */
+	/* Non-vga */
+	regp->Attribute[NV_CIO_AR_OSCAN_INDEX] = 0x00;
+	regp->Attribute[NV_CIO_AR_PLANE_INDEX] = 0x0F; /* enable all color planes */
+	regp->Attribute[NV_CIO_AR_HPP_INDEX] = 0x00;
+	regp->Attribute[NV_CIO_AR_CSEL_INDEX] = 0x00;
+}
+
+/**
+ * Sets up registers for the given mode/adjusted_mode pair.
+ *
+ * The clocks, CRTCs and outputs attached to this CRTC must be off.
+ *
+ * This shouldn't enable any clocks, CRTCs, or outputs, but they should
+ * be easily turned on/off after this.
+ */
+static void
+nv_crtc_mode_set_regs(struct drm_crtc *crtc, struct drm_display_mode * mode)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
+	struct nv04_crtc_reg *savep = &dev_priv->saved_reg.crtc_reg[nv_crtc->index];
+	struct drm_encoder *encoder;
+	bool lvds_output = false, tmds_output = false, tv_output = false,
+		off_chip_digital = false;
+
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+		bool digital = false;
+
+		if (encoder->crtc != crtc)
+			continue;
+
+		if (nv_encoder->dcb->type == OUTPUT_LVDS)
+			digital = lvds_output = true;
+		if (nv_encoder->dcb->type == OUTPUT_TV)
+			tv_output = true;
+		if (nv_encoder->dcb->type == OUTPUT_TMDS)
+			digital = tmds_output = true;
+		if (nv_encoder->dcb->location != DCB_LOC_ON_CHIP && digital)
+			off_chip_digital = true;
+	}
+
+	/* Registers not directly related to the (s)vga mode */
+
+	/* What is the meaning of this register? */
+	/* A few popular values are 0x18, 0x1c, 0x38, 0x3c */
+	regp->CRTC[NV_CIO_CRE_ENH_INDEX] = savep->CRTC[NV_CIO_CRE_ENH_INDEX] & ~(1<<5);
+
+	regp->crtc_eng_ctrl = 0;
+	/* Except for rare conditions I2C is enabled on the primary crtc */
+	if (nv_crtc->index == 0)
+		regp->crtc_eng_ctrl |= NV_CRTC_FSEL_I2C;
+#if 0
+	/* Set overlay to desired crtc. */
+	if (dev->overlayAdaptor) {
+		NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(dev);
+		if (pPriv->overlayCRTC == nv_crtc->index)
+			regp->crtc_eng_ctrl |= NV_CRTC_FSEL_OVERLAY;
+	}
+#endif
+
+	/* ADDRESS_SPACE_PNVM is the same as setting HCUR_ASI */
+	regp->cursor_cfg = NV_PCRTC_CURSOR_CONFIG_CUR_LINES_64 |
+			     NV_PCRTC_CURSOR_CONFIG_CUR_PIXELS_64 |
+			     NV_PCRTC_CURSOR_CONFIG_ADDRESS_SPACE_PNVM;
+	if (dev_priv->chipset >= 0x11)
+		regp->cursor_cfg |= NV_PCRTC_CURSOR_CONFIG_CUR_BPP_32;
+	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+		regp->cursor_cfg |= NV_PCRTC_CURSOR_CONFIG_DOUBLE_SCAN_ENABLE;
+
+	/* Unblock some timings */
+	regp->CRTC[NV_CIO_CRE_53] = 0;
+	regp->CRTC[NV_CIO_CRE_54] = 0;
+
+	/* 0x00 is disabled, 0x11 is lvds, 0x22 crt and 0x88 tmds */
+	if (lvds_output)
+		regp->CRTC[NV_CIO_CRE_SCRATCH3__INDEX] = 0x11;
+	else if (tmds_output)
+		regp->CRTC[NV_CIO_CRE_SCRATCH3__INDEX] = 0x88;
+	else
+		regp->CRTC[NV_CIO_CRE_SCRATCH3__INDEX] = 0x22;
+
+	/* These values seem to vary */
+	/* This register seems to be used by the bios to make certain decisions on some G70 cards? */
+	regp->CRTC[NV_CIO_CRE_SCRATCH4__INDEX] = savep->CRTC[NV_CIO_CRE_SCRATCH4__INDEX];
+
+	nv_crtc_set_digital_vibrance(crtc, nv_crtc->saturation);
+
+	/* probably a scratch reg, but kept for cargo-cult purposes:
+	 * bit0: crtc0?, head A
+	 * bit6: lvds, head A
+	 * bit7: (only in X), head A
+	 */
+	if (nv_crtc->index == 0)
+		regp->CRTC[NV_CIO_CRE_4B] = savep->CRTC[NV_CIO_CRE_4B] | 0x80;
+
+	/* The blob seems to take the current value from crtc 0, add 4 to that
+	 * and reuse the old value for crtc 1 */
+	regp->CRTC[NV_CIO_CRE_TVOUT_LATENCY] = dev_priv->saved_reg.crtc_reg[0].CRTC[NV_CIO_CRE_TVOUT_LATENCY];
+	if (!nv_crtc->index)
+		regp->CRTC[NV_CIO_CRE_TVOUT_LATENCY] += 4;
+
+	/* the blob sometimes sets |= 0x10 (which is the same as setting |=
+	 * 1 << 30 on 0x60.830), for no apparent reason */
+	regp->CRTC[NV_CIO_CRE_59] = off_chip_digital;
+
+	regp->crtc_830 = mode->crtc_vdisplay - 3;
+	regp->crtc_834 = mode->crtc_vdisplay - 1;
+
+	if (dev_priv->card_type == NV_40)
+		/* This is what the blob does */
+		regp->crtc_850 = NVReadCRTC(dev, 0, NV_PCRTC_850);
+
+	if (dev_priv->card_type >= NV_30)
+		regp->gpio_ext = NVReadCRTC(dev, 0, NV_PCRTC_GPIO_EXT);
+
+	regp->crtc_cfg = NV_PCRTC_CONFIG_START_ADDRESS_HSYNC;
+
+	/* Some misc regs */
+	if (dev_priv->card_type == NV_40) {
+		regp->CRTC[NV_CIO_CRE_85] = 0xFF;
+		regp->CRTC[NV_CIO_CRE_86] = 0x1;
+	}
+
+	regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] = (crtc->fb->depth + 1) / 8;
+	/* Enable slaved mode (called MODE_TV in nv4ref.h) */
+	if (lvds_output || tmds_output || tv_output)
+		regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] |= (1 << 7);
+
+	/* Generic PRAMDAC regs */
+
+	if (dev_priv->card_type >= NV_10)
+		/* Only bit that bios and blob set. */
+		regp->nv10_cursync = (1 << 25);
+
+	regp->ramdac_gen_ctrl = NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS |
+				NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE_SEL |
+				NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON;
+	if (crtc->fb->depth == 16)
+		regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL;
+	if (dev_priv->chipset >= 0x11)
+		regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_PIPE_LONG;
+
+	regp->ramdac_630 = 0; /* turn off green mode (tv test pattern?) */
+	regp->tv_setup = 0;
+
+	nv_crtc_set_image_sharpening(crtc, nv_crtc->sharpness);
+
+	/* Some values the blob sets */
+	regp->ramdac_8c0 = 0x100;
+	regp->ramdac_a20 = 0x0;
+	regp->ramdac_a24 = 0xfffff;
+	regp->ramdac_a34 = 0x1;
+}
+
+/**
+ * Sets up registers for the given mode/adjusted_mode pair.
+ *
+ * The clocks, CRTCs and outputs attached to this CRTC must be off.
+ *
+ * This shouldn't enable any clocks, CRTCs, or outputs, but they should
+ * be easily turned on/off after this.
+ */
+static int
+nv_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
+		 struct drm_display_mode *adjusted_mode,
+		 int x, int y, struct drm_framebuffer *old_fb)
+{
+	struct drm_device *dev = crtc->dev;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	NV_DEBUG(dev, "CTRC mode on CRTC %d:\n", nv_crtc->index);
+	drm_mode_debug_printmodeline(adjusted_mode);
+
+	/* unlock must come after turning off FP_TG_CONTROL in output_prepare */
+	nv_lock_vga_crtc_shadow(dev, nv_crtc->index, -1);
+
+	nv_crtc_mode_set_vga(crtc, adjusted_mode);
+	/* calculated in nv04_dfp_prepare, nv40 needs it written before calculating PLLs */
+	if (dev_priv->card_type == NV_40)
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, dev_priv->mode_reg.sel_clk);
+	nv_crtc_mode_set_regs(crtc, adjusted_mode);
+	nv_crtc_calc_state_ext(crtc, mode, adjusted_mode->clock);
+	return 0;
+}
+
+static void nv_crtc_save(struct drm_crtc *crtc)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct drm_nouveau_private *dev_priv = crtc->dev->dev_private;
+	struct nv04_mode_state *state = &dev_priv->mode_reg;
+	struct nv04_crtc_reg *crtc_state = &state->crtc_reg[nv_crtc->index];
+	struct nv04_mode_state *saved = &dev_priv->saved_reg;
+	struct nv04_crtc_reg *crtc_saved = &saved->crtc_reg[nv_crtc->index];
+
+	if (nv_two_heads(crtc->dev))
+		NVSetOwner(crtc->dev, nv_crtc->index);
+
+	nouveau_hw_save_state(crtc->dev, nv_crtc->index, saved);
+
+	/* init some state to saved value */
+	state->sel_clk = saved->sel_clk & ~(0x5 << 16);
+	crtc_state->CRTC[NV_CIO_CRE_LCD__INDEX] = crtc_saved->CRTC[NV_CIO_CRE_LCD__INDEX];
+	state->pllsel = saved->pllsel & ~(PLLSEL_VPLL1_MASK | PLLSEL_VPLL2_MASK | PLLSEL_TV_MASK);
+	crtc_state->gpio_ext = crtc_saved->gpio_ext;
+}
+
+static void nv_crtc_restore(struct drm_crtc *crtc)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct drm_nouveau_private *dev_priv = crtc->dev->dev_private;
+	int head = nv_crtc->index;
+	uint8_t saved_cr21 = dev_priv->saved_reg.crtc_reg[head].CRTC[NV_CIO_CRE_21];
+
+	if (nv_two_heads(crtc->dev))
+		NVSetOwner(crtc->dev, head);
+
+	nouveau_hw_load_state(crtc->dev, head, &dev_priv->saved_reg);
+	nv_lock_vga_crtc_shadow(crtc->dev, head, saved_cr21);
+
+	nv_crtc->last_dpms = NV_DPMS_CLEARED;
+}
+
+static void nv_crtc_prepare(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct drm_crtc_helper_funcs *funcs = crtc->helper_private;
+
+	if (nv_two_heads(dev))
+		NVSetOwner(dev, nv_crtc->index);
+
+	funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
+
+	NVBlankScreen(dev, nv_crtc->index, true);
+
+	/* Some more preperation. */
+	NVWriteCRTC(dev, nv_crtc->index, NV_PCRTC_CONFIG, NV_PCRTC_CONFIG_START_ADDRESS_NON_VGA);
+	if (dev_priv->card_type == NV_40) {
+		uint32_t reg900 = NVReadRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_900);
+		NVWriteRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_900, reg900 & ~0x10000);
+	}
+}
+
+static void nv_crtc_commit(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_crtc_helper_funcs *funcs = crtc->helper_private;
+	struct drm_nouveau_private *dev_priv = crtc->dev->dev_private;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+
+	nouveau_hw_load_state(dev, nv_crtc->index, &dev_priv->mode_reg);
+	nv04_crtc_mode_set_base(crtc, crtc->x, crtc->y, NULL);
+
+#ifdef __BIG_ENDIAN
+	/* turn on LFB swapping */
+	{
+		uint8_t tmp = NVReadVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RCR);
+		tmp |= MASK(NV_CIO_CRE_RCR_ENDIAN_BIG);
+		NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RCR, tmp);
+	}
+#endif
+
+	funcs->dpms(crtc, DRM_MODE_DPMS_ON);
+}
+
+static void nv_crtc_destroy(struct drm_crtc *crtc)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+
+	NV_DEBUG(crtc->dev, "\n");
+
+	if (!nv_crtc)
+		return;
+
+	drm_crtc_cleanup(crtc);
+
+	nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
+	kfree(nv_crtc);
+}
+
+static void
+nv_crtc_gamma_load(struct drm_crtc *crtc)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct drm_device *dev = nv_crtc->base.dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct rgb { uint8_t r, g, b; } __attribute__((packed)) *rgbs;
+	int i;
+
+	rgbs = (struct rgb *)dev_priv->mode_reg.crtc_reg[nv_crtc->index].DAC;
+	for (i = 0; i < 256; i++) {
+		rgbs[i].r = nv_crtc->lut.r[i] >> 8;
+		rgbs[i].g = nv_crtc->lut.g[i] >> 8;
+		rgbs[i].b = nv_crtc->lut.b[i] >> 8;
+	}
+
+	nouveau_hw_load_state_palette(dev, nv_crtc->index, &dev_priv->mode_reg);
+}
+
+static void
+nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, uint32_t size)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	int i;
+
+	if (size != 256)
+		return;
+
+	for (i = 0; i < 256; i++) {
+		nv_crtc->lut.r[i] = r[i];
+		nv_crtc->lut.g[i] = g[i];
+		nv_crtc->lut.b[i] = b[i];
+	}
+
+	/* We need to know the depth before we upload, but it's possible to
+	 * get called before a framebuffer is bound.  If this is the case,
+	 * mark the lut values as dirty by setting depth==0, and it'll be
+	 * uploaded on the first mode_set_base()
+	 */
+	if (!nv_crtc->base.fb) {
+		nv_crtc->lut.depth = 0;
+		return;
+	}
+
+	nv_crtc_gamma_load(crtc);
+}
+
+static int
+nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+			struct drm_framebuffer *old_fb)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
+	struct drm_framebuffer *drm_fb = nv_crtc->base.fb;
+	struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
+	int arb_burst, arb_lwm;
+	int ret;
+
+	ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM);
+	if (ret)
+		return ret;
+
+	if (old_fb) {
+		struct nouveau_framebuffer *ofb = nouveau_framebuffer(old_fb);
+		nouveau_bo_unpin(ofb->nvbo);
+	}
+
+	nv_crtc->fb.offset = fb->nvbo->bo.offset;
+
+	if (nv_crtc->lut.depth != drm_fb->depth) {
+		nv_crtc->lut.depth = drm_fb->depth;
+		nv_crtc_gamma_load(crtc);
+	}
+
+	/* Update the framebuffer format. */
+	regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] &= ~3;
+	regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] |= (crtc->fb->depth + 1) / 8;
+	regp->ramdac_gen_ctrl &= ~NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL;
+	if (crtc->fb->depth == 16)
+		regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL;
+	crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_PIXEL_INDEX);
+	NVWriteRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_GENERAL_CONTROL,
+		      regp->ramdac_gen_ctrl);
+
+	regp->CRTC[NV_CIO_CR_OFFSET_INDEX] = drm_fb->pitch >> 3;
+	regp->CRTC[NV_CIO_CRE_RPC0_INDEX] =
+		XLATE(drm_fb->pitch >> 3, 8, NV_CIO_CRE_RPC0_OFFSET_10_8);
+	crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_RPC0_INDEX);
+	crtc_wr_cio_state(crtc, regp, NV_CIO_CR_OFFSET_INDEX);
+
+	/* Update the framebuffer location. */
+	regp->fb_start = nv_crtc->fb.offset & ~3;
+	regp->fb_start += (y * drm_fb->pitch) + (x * drm_fb->bits_per_pixel / 8);
+	NVWriteCRTC(dev, nv_crtc->index, NV_PCRTC_START, regp->fb_start);
+
+	/* Update the arbitration parameters. */
+	nouveau_calc_arb(dev, crtc->mode.clock, drm_fb->bits_per_pixel,
+			 &arb_burst, &arb_lwm);
+
+	regp->CRTC[NV_CIO_CRE_FF_INDEX] = arb_burst;
+	regp->CRTC[NV_CIO_CRE_FFLWM__INDEX] = arb_lwm & 0xff;
+	crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_FF_INDEX);
+	crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_FFLWM__INDEX);
+
+	if (dev_priv->card_type >= NV_30) {
+		regp->CRTC[NV_CIO_CRE_47] = arb_lwm >> 8;
+		crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_47);
+	}
+
+	return 0;
+}
+
+static void nv04_cursor_upload(struct drm_device *dev, struct nouveau_bo *src,
+			       struct nouveau_bo *dst)
+{
+	int width = nv_cursor_width(dev);
+	uint32_t pixel;
+	int i, j;
+
+	for (i = 0; i < width; i++) {
+		for (j = 0; j < width; j++) {
+			pixel = nouveau_bo_rd32(src, i*64 + j);
+
+			nouveau_bo_wr16(dst, i*width + j, (pixel & 0x80000000) >> 16
+				     | (pixel & 0xf80000) >> 9
+				     | (pixel & 0xf800) >> 6
+				     | (pixel & 0xf8) >> 3);
+		}
+	}
+}
+
+static void nv11_cursor_upload(struct drm_device *dev, struct nouveau_bo *src,
+			       struct nouveau_bo *dst)
+{
+	uint32_t pixel;
+	int alpha, i;
+
+	/* nv11+ supports premultiplied (PM), or non-premultiplied (NPM) alpha
+	 * cursors (though NPM in combination with fp dithering may not work on
+	 * nv11, from "nv" driver history)
+	 * NPM mode needs NV_PCRTC_CURSOR_CONFIG_ALPHA_BLEND set and is what the
+	 * blob uses, however we get given PM cursors so we use PM mode
+	 */
+	for (i = 0; i < 64 * 64; i++) {
+		pixel = nouveau_bo_rd32(src, i);
+
+		/* hw gets unhappy if alpha <= rgb values.  for a PM image "less
+		 * than" shouldn't happen; fix "equal to" case by adding one to
+		 * alpha channel (slightly inaccurate, but so is attempting to
+		 * get back to NPM images, due to limits of integer precision)
+		 */
+		alpha = pixel >> 24;
+		if (alpha > 0 && alpha < 255)
+			pixel = (pixel & 0x00ffffff) | ((alpha + 1) << 24);
+
+#ifdef __BIG_ENDIAN
+		{
+			struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+			if (dev_priv->chipset == 0x11) {
+				pixel = ((pixel & 0x000000ff) << 24) |
+					((pixel & 0x0000ff00) << 8) |
+					((pixel & 0x00ff0000) >> 8) |
+					((pixel & 0xff000000) >> 24);
+			}
+		}
+#endif
+
+		nouveau_bo_wr32(dst, i, pixel);
+	}
+}
+
+static int
+nv04_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
+		     uint32_t buffer_handle, uint32_t width, uint32_t height)
+{
+	struct drm_nouveau_private *dev_priv = crtc->dev->dev_private;
+	struct drm_device *dev = dev_priv->dev;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct nouveau_bo *cursor = NULL;
+	struct drm_gem_object *gem;
+	int ret = 0;
+
+	if (width != 64 || height != 64)
+		return -EINVAL;
+
+	if (!buffer_handle) {
+		nv_crtc->cursor.hide(nv_crtc, true);
+		return 0;
+	}
+
+	gem = drm_gem_object_lookup(dev, file_priv, buffer_handle);
+	if (!gem)
+		return -EINVAL;
+	cursor = nouveau_gem_object(gem);
+
+	ret = nouveau_bo_map(cursor);
+	if (ret)
+		goto out;
+
+	if (dev_priv->chipset >= 0x11)
+		nv11_cursor_upload(dev, cursor, nv_crtc->cursor.nvbo);
+	else
+		nv04_cursor_upload(dev, cursor, nv_crtc->cursor.nvbo);
+
+	nouveau_bo_unmap(cursor);
+	nv_crtc->cursor.offset = nv_crtc->cursor.nvbo->bo.offset;
+	nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.offset);
+	nv_crtc->cursor.show(nv_crtc, true);
+out:
+	mutex_lock(&dev->struct_mutex);
+	drm_gem_object_unreference(gem);
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
+static int
+nv04_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+
+	nv_crtc->cursor.set_pos(nv_crtc, x, y);
+	return 0;
+}
+
+static const struct drm_crtc_funcs nv04_crtc_funcs = {
+	.save = nv_crtc_save,
+	.restore = nv_crtc_restore,
+	.cursor_set = nv04_crtc_cursor_set,
+	.cursor_move = nv04_crtc_cursor_move,
+	.gamma_set = nv_crtc_gamma_set,
+	.set_config = drm_crtc_helper_set_config,
+	.destroy = nv_crtc_destroy,
+};
+
+static const struct drm_crtc_helper_funcs nv04_crtc_helper_funcs = {
+	.dpms = nv_crtc_dpms,
+	.prepare = nv_crtc_prepare,
+	.commit = nv_crtc_commit,
+	.mode_fixup = nv_crtc_mode_fixup,
+	.mode_set = nv_crtc_mode_set,
+	.mode_set_base = nv04_crtc_mode_set_base,
+	.load_lut = nv_crtc_gamma_load,
+};
+
+int
+nv04_crtc_create(struct drm_device *dev, int crtc_num)
+{
+	struct nouveau_crtc *nv_crtc;
+	int ret, i;
+
+	nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL);
+	if (!nv_crtc)
+		return -ENOMEM;
+
+	for (i = 0; i < 256; i++) {
+		nv_crtc->lut.r[i] = i << 8;
+		nv_crtc->lut.g[i] = i << 8;
+		nv_crtc->lut.b[i] = i << 8;
+	}
+	nv_crtc->lut.depth = 0;
+
+	nv_crtc->index = crtc_num;
+	nv_crtc->last_dpms = NV_DPMS_CLEARED;
+
+	drm_crtc_init(dev, &nv_crtc->base, &nv04_crtc_funcs);
+	drm_crtc_helper_add(&nv_crtc->base, &nv04_crtc_helper_funcs);
+	drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256);
+
+	ret = nouveau_bo_new(dev, NULL, 64*64*4, 0x100, TTM_PL_FLAG_VRAM,
+			     0, 0x0000, false, true, &nv_crtc->cursor.nvbo);
+	if (!ret) {
+		ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM);
+		if (!ret)
+			ret = nouveau_bo_map(nv_crtc->cursor.nvbo);
+		if (ret)
+			nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
+	}
+
+	nv04_cursor_init(nv_crtc);
+
+	return 0;
+}
+
diff --git a/drivers/gpu/drm/nouveau/nv04_cursor.c b/drivers/gpu/drm/nouveau/nv04_cursor.c
new file mode 100644
index 0000000..89a91b9
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv04_cursor.c
@@ -0,0 +1,70 @@
+#include "drmP.h"
+#include "drm_mode.h"
+#include "nouveau_reg.h"
+#include "nouveau_drv.h"
+#include "nouveau_crtc.h"
+#include "nouveau_hw.h"
+
+static void
+nv04_cursor_show(struct nouveau_crtc *nv_crtc, bool update)
+{
+	nv_show_cursor(nv_crtc->base.dev, nv_crtc->index, true);
+}
+
+static void
+nv04_cursor_hide(struct nouveau_crtc *nv_crtc, bool update)
+{
+	nv_show_cursor(nv_crtc->base.dev, nv_crtc->index, false);
+}
+
+static void
+nv04_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y)
+{
+	NVWriteRAMDAC(nv_crtc->base.dev, nv_crtc->index,
+		      NV_PRAMDAC_CU_START_POS,
+		      XLATE(y, 0, NV_PRAMDAC_CU_START_POS_Y) |
+		      XLATE(x, 0, NV_PRAMDAC_CU_START_POS_X));
+}
+
+static void
+crtc_wr_cio_state(struct drm_crtc *crtc, struct nv04_crtc_reg *crtcstate, int index)
+{
+	NVWriteVgaCrtc(crtc->dev, nouveau_crtc(crtc)->index, index,
+		       crtcstate->CRTC[index]);
+}
+
+static void
+nv04_cursor_set_offset(struct nouveau_crtc *nv_crtc, uint32_t offset)
+{
+	struct drm_device *dev = nv_crtc->base.dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
+	struct drm_crtc *crtc = &nv_crtc->base;
+
+	regp->CRTC[NV_CIO_CRE_HCUR_ADDR0_INDEX] =
+		MASK(NV_CIO_CRE_HCUR_ASI) |
+		XLATE(offset, 17, NV_CIO_CRE_HCUR_ADDR0_ADR);
+	regp->CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX] =
+		XLATE(offset, 11, NV_CIO_CRE_HCUR_ADDR1_ADR);
+	if (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)
+		regp->CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX] |=
+			MASK(NV_CIO_CRE_HCUR_ADDR1_CUR_DBL);
+	regp->CRTC[NV_CIO_CRE_HCUR_ADDR2_INDEX] = offset >> 24;
+
+	crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX);
+	crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX);
+	crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_HCUR_ADDR2_INDEX);
+	if (dev_priv->card_type == NV_40)
+		nv_fix_nv40_hw_cursor(dev, nv_crtc->index);
+}
+
+int
+nv04_cursor_init(struct nouveau_crtc *crtc)
+{
+	crtc->cursor.set_offset = nv04_cursor_set_offset;
+	crtc->cursor.set_pos = nv04_cursor_set_pos;
+	crtc->cursor.hide = nv04_cursor_hide;
+	crtc->cursor.show = nv04_cursor_show;
+	return 0;
+}
+
diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c
new file mode 100644
index 0000000..a5fa517
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv04_dac.c
@@ -0,0 +1,528 @@
+/*
+ * Copyright 2003 NVIDIA, Corporation
+ * Copyright 2006 Dave Airlie
+ * Copyright 2007 Maarten Maathuis
+ * Copyright 2007-2009 Stuart Bennett
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+#include "drm_crtc_helper.h"
+
+#include "nouveau_drv.h"
+#include "nouveau_encoder.h"
+#include "nouveau_connector.h"
+#include "nouveau_crtc.h"
+#include "nouveau_hw.h"
+#include "nvreg.h"
+
+int nv04_dac_output_offset(struct drm_encoder *encoder)
+{
+	struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
+	int offset = 0;
+
+	if (dcb->or & (8 | OUTPUT_C))
+		offset += 0x68;
+	if (dcb->or & (8 | OUTPUT_B))
+		offset += 0x2000;
+
+	return offset;
+}
+
+/*
+ * arbitrary limit to number of sense oscillations tolerated in one sample
+ * period (observed to be at least 13 in "nvidia")
+ */
+#define MAX_HBLANK_OSC 20
+
+/*
+ * arbitrary limit to number of conflicting sample pairs to tolerate at a
+ * voltage step (observed to be at least 5 in "nvidia")
+ */
+#define MAX_SAMPLE_PAIRS 10
+
+static int sample_load_twice(struct drm_device *dev, bool sense[2])
+{
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		bool sense_a, sense_b, sense_b_prime;
+		int j = 0;
+
+		/*
+		 * wait for bit 0 clear -- out of hblank -- (say reg value 0x4),
+		 * then wait for transition 0x4->0x5->0x4: enter hblank, leave
+		 * hblank again
+		 * use a 10ms timeout (guards against crtc being inactive, in
+		 * which case blank state would never change)
+		 */
+		if (!nouveau_wait_until(dev, 10000000, NV_PRMCIO_INP0__COLOR,
+					0x00000001, 0x00000000))
+			return -EBUSY;
+		if (!nouveau_wait_until(dev, 10000000, NV_PRMCIO_INP0__COLOR,
+					0x00000001, 0x00000001))
+			return -EBUSY;
+		if (!nouveau_wait_until(dev, 10000000, NV_PRMCIO_INP0__COLOR,
+					0x00000001, 0x00000000))
+			return -EBUSY;
+
+		udelay(100);
+		/* when level triggers, sense is _LO_ */
+		sense_a = nv_rd08(dev, NV_PRMCIO_INP0) & 0x10;
+
+		/* take another reading until it agrees with sense_a... */
+		do {
+			udelay(100);
+			sense_b = nv_rd08(dev, NV_PRMCIO_INP0) & 0x10;
+			if (sense_a != sense_b) {
+				sense_b_prime =
+					nv_rd08(dev, NV_PRMCIO_INP0) & 0x10;
+				if (sense_b == sense_b_prime) {
+					/* ... unless two consecutive subsequent
+					 * samples agree; sense_a is replaced */
+					sense_a = sense_b;
+					/* force mis-match so we loop */
+					sense_b = !sense_a;
+				}
+			}
+		} while ((sense_a != sense_b) && ++j < MAX_HBLANK_OSC);
+
+		if (j == MAX_HBLANK_OSC)
+			/* with so much oscillation, default to sense:LO */
+			sense[i] = false;
+		else
+			sense[i] = sense_a;
+	}
+
+	return 0;
+}
+
+static enum drm_connector_status nv04_dac_detect(struct drm_encoder *encoder,
+						 struct drm_connector *connector)
+{
+	struct drm_device *dev = encoder->dev;
+	uint8_t saved_seq1, saved_pi, saved_rpc1;
+	uint8_t saved_palette0[3], saved_palette_mask;
+	uint32_t saved_rtest_ctrl, saved_rgen_ctrl;
+	int i;
+	uint8_t blue;
+	bool sense = true;
+
+	/*
+	 * for this detection to work, there needs to be a mode set up on the
+	 * CRTC.  this is presumed to be the case
+	 */
+
+	if (nv_two_heads(dev))
+		/* only implemented for head A for now */
+		NVSetOwner(dev, 0);
+
+	saved_seq1 = NVReadVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX);
+	NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1 & ~0x20);
+
+	saved_rtest_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL);
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL,
+		      saved_rtest_ctrl & ~NV_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_OFF);
+
+	msleep(10);
+
+	saved_pi = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX);
+	NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX,
+		       saved_pi & ~(0x80 | MASK(NV_CIO_CRE_PIXEL_FORMAT)));
+	saved_rpc1 = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX);
+	NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX, saved_rpc1 & ~0xc0);
+
+	nv_wr08(dev, NV_PRMDIO_READ_MODE_ADDRESS, 0x0);
+	for (i = 0; i < 3; i++)
+		saved_palette0[i] = nv_rd08(dev, NV_PRMDIO_PALETTE_DATA);
+	saved_palette_mask = nv_rd08(dev, NV_PRMDIO_PIXEL_MASK);
+	nv_wr08(dev, NV_PRMDIO_PIXEL_MASK, 0);
+
+	saved_rgen_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_GENERAL_CONTROL);
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_GENERAL_CONTROL,
+		      (saved_rgen_ctrl & ~(NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS |
+					   NV_PRAMDAC_GENERAL_CONTROL_TERMINATION_75OHM)) |
+		      NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON);
+
+	blue = 8;	/* start of test range */
+
+	do {
+		bool sense_pair[2];
+
+		nv_wr08(dev, NV_PRMDIO_WRITE_MODE_ADDRESS, 0);
+		nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, 0);
+		nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, 0);
+		/* testing blue won't find monochrome monitors.  I don't care */
+		nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, blue);
+
+		i = 0;
+		/* take sample pairs until both samples in the pair agree */
+		do {
+			if (sample_load_twice(dev, sense_pair))
+				goto out;
+		} while ((sense_pair[0] != sense_pair[1]) &&
+							++i < MAX_SAMPLE_PAIRS);
+
+		if (i == MAX_SAMPLE_PAIRS)
+			/* too much oscillation defaults to LO */
+			sense = false;
+		else
+			sense = sense_pair[0];
+
+	/*
+	 * if sense goes LO before blue ramps to 0x18, monitor is not connected.
+	 * ergo, if blue gets to 0x18, monitor must be connected
+	 */
+	} while (++blue < 0x18 && sense);
+
+out:
+	nv_wr08(dev, NV_PRMDIO_PIXEL_MASK, saved_palette_mask);
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_GENERAL_CONTROL, saved_rgen_ctrl);
+	nv_wr08(dev, NV_PRMDIO_WRITE_MODE_ADDRESS, 0);
+	for (i = 0; i < 3; i++)
+		nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, saved_palette0[i]);
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL, saved_rtest_ctrl);
+	NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX, saved_pi);
+	NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX, saved_rpc1);
+	NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1);
+
+	if (blue == 0x18) {
+		NV_TRACE(dev, "Load detected on head A\n");
+		return connector_status_connected;
+	}
+
+	return connector_status_disconnected;
+}
+
+enum drm_connector_status nv17_dac_detect(struct drm_encoder *encoder,
+					  struct drm_connector *connector)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
+	uint32_t testval, regoffset = nv04_dac_output_offset(encoder);
+	uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput,
+		saved_rtest_ctrl, saved_gpio0, saved_gpio1, temp, routput;
+	int head, present = 0;
+
+#define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20)
+	if (dcb->type == OUTPUT_TV) {
+		testval = RGB_TEST_DATA(0xa0, 0xa0, 0xa0);
+
+		if (dev_priv->vbios->tvdactestval)
+			testval = dev_priv->vbios->tvdactestval;
+	} else {
+		testval = RGB_TEST_DATA(0x140, 0x140, 0x140); /* 0x94050140 */
+
+		if (dev_priv->vbios->dactestval)
+			testval = dev_priv->vbios->dactestval;
+	}
+
+	saved_rtest_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset);
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset,
+		      saved_rtest_ctrl & ~NV_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_OFF);
+
+	saved_powerctrl_2 = nvReadMC(dev, NV_PBUS_POWERCTRL_2);
+
+	nvWriteMC(dev, NV_PBUS_POWERCTRL_2, saved_powerctrl_2 & 0xd7ffffff);
+	if (regoffset == 0x68) {
+		saved_powerctrl_4 = nvReadMC(dev, NV_PBUS_POWERCTRL_4);
+		nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4 & 0xffffffcf);
+	}
+
+	saved_gpio1 = nv17_gpio_get(dev, DCB_GPIO_TVDAC1);
+	saved_gpio0 = nv17_gpio_get(dev, DCB_GPIO_TVDAC0);
+
+	nv17_gpio_set(dev, DCB_GPIO_TVDAC1, dcb->type == OUTPUT_TV);
+	nv17_gpio_set(dev, DCB_GPIO_TVDAC0, dcb->type == OUTPUT_TV);
+
+	msleep(4);
+
+	saved_routput = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset);
+	head = (saved_routput & 0x100) >> 8;
+#if 0
+	/* if there's a spare crtc, using it will minimise flicker for the case
+	 * where the in-use crtc is in use by an off-chip tmds encoder */
+	if (xf86_config->crtc[head]->enabled && !xf86_config->crtc[head ^ 1]->enabled)
+		head ^= 1;
+#endif
+	/* nv driver and nv31 use 0xfffffeee, nv34 and 6600 use 0xfffffece */
+	routput = (saved_routput & 0xfffffece) | head << 8;
+
+	if (dev_priv->card_type >= NV_40) {
+		if (dcb->type == OUTPUT_TV)
+			routput |= 0x1a << 16;
+		else
+			routput &= ~(0x1a << 16);
+	}
+
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, routput);
+	msleep(1);
+
+	temp = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset);
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, temp | 1);
+
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TESTPOINT_DATA,
+		      NV_PRAMDAC_TESTPOINT_DATA_NOTBLANK | testval);
+	temp = NVReadRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL,
+		      temp | NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED);
+	msleep(5);
+
+	temp = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset);
+
+	if (dcb->type == OUTPUT_TV)
+		present = (nv17_tv_detect(encoder, connector, temp)
+			   == connector_status_connected);
+	else
+		present = temp & NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI;
+
+	temp = NVReadRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL,
+		      temp & ~NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TESTPOINT_DATA, 0);
+
+	/* bios does something more complex for restoring, but I think this is good enough */
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, saved_routput);
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, saved_rtest_ctrl);
+	if (regoffset == 0x68)
+		nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4);
+	nvWriteMC(dev, NV_PBUS_POWERCTRL_2, saved_powerctrl_2);
+
+	nv17_gpio_set(dev, DCB_GPIO_TVDAC1, saved_gpio1);
+	nv17_gpio_set(dev, DCB_GPIO_TVDAC0, saved_gpio0);
+
+	if (present) {
+		NV_INFO(dev, "Load detected on output %c\n", '@' + ffs(dcb->or));
+		return connector_status_connected;
+	}
+
+	return connector_status_disconnected;
+}
+
+
+static bool nv04_dac_mode_fixup(struct drm_encoder *encoder,
+				struct drm_display_mode *mode,
+				struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static void nv04_dac_prepare(struct drm_encoder *encoder)
+{
+	struct drm_encoder_helper_funcs *helper = encoder->helper_private;
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int head = nouveau_crtc(encoder->crtc)->index;
+	struct nv04_crtc_reg *crtcstate = dev_priv->mode_reg.crtc_reg;
+
+	helper->dpms(encoder, DRM_MODE_DPMS_OFF);
+
+	nv04_dfp_disable(dev, head);
+
+	/* Some NV4x have unknown values (0x3f, 0x50, 0x54, 0x6b, 0x79, 0x7f)
+	 * at LCD__INDEX which we don't alter
+	 */
+	if (!(crtcstate[head].CRTC[NV_CIO_CRE_LCD__INDEX] & 0x44))
+		crtcstate[head].CRTC[NV_CIO_CRE_LCD__INDEX] = 0;
+}
+
+
+static void nv04_dac_mode_set(struct drm_encoder *encoder,
+			      struct drm_display_mode *mode,
+			      struct drm_display_mode *adjusted_mode)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int head = nouveau_crtc(encoder->crtc)->index;
+
+	NV_TRACE(dev, "%s called for encoder %d\n", __func__,
+		      nv_encoder->dcb->index);
+
+	if (nv_gf4_disp_arch(dev)) {
+		struct drm_encoder *rebind;
+		uint32_t dac_offset = nv04_dac_output_offset(encoder);
+		uint32_t otherdac;
+
+		/* bit 16-19 are bits that are set on some G70 cards,
+		 * but don't seem to have much effect */
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + dac_offset,
+			      head << 8 | NV_PRAMDAC_DACCLK_SEL_DACCLK);
+		/* force any other vga encoders to bind to the other crtc */
+		list_for_each_entry(rebind, &dev->mode_config.encoder_list, head) {
+			if (rebind == encoder
+			    || nouveau_encoder(rebind)->dcb->type != OUTPUT_ANALOG)
+				continue;
+
+			dac_offset = nv04_dac_output_offset(rebind);
+			otherdac = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + dac_offset);
+			NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + dac_offset,
+				      (otherdac & ~0x0100) | (head ^ 1) << 8);
+		}
+	}
+
+	/* This could use refinement for flatpanels, but it should work this way */
+	if (dev_priv->chipset < 0x44)
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0xf0000000);
+	else
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000);
+}
+
+static void nv04_dac_commit(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
+	struct drm_encoder_helper_funcs *helper = encoder->helper_private;
+
+	helper->dpms(encoder, DRM_MODE_DPMS_ON);
+
+	NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n",
+		drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base),
+		nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
+}
+
+void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
+
+	if (nv_gf4_disp_arch(dev)) {
+		uint32_t *dac_users = &dev_priv->dac_users[ffs(dcb->or) - 1];
+		int dacclk_off = NV_PRAMDAC_DACCLK + nv04_dac_output_offset(encoder);
+		uint32_t dacclk = NVReadRAMDAC(dev, 0, dacclk_off);
+
+		if (enable) {
+			*dac_users |= 1 << dcb->index;
+			NVWriteRAMDAC(dev, 0, dacclk_off, dacclk | NV_PRAMDAC_DACCLK_SEL_DACCLK);
+
+		} else {
+			*dac_users &= ~(1 << dcb->index);
+			if (!*dac_users)
+				NVWriteRAMDAC(dev, 0, dacclk_off,
+					dacclk & ~NV_PRAMDAC_DACCLK_SEL_DACCLK);
+		}
+	}
+}
+
+static void nv04_dac_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+	if (nv_encoder->last_dpms == mode)
+		return;
+	nv_encoder->last_dpms = mode;
+
+	NV_INFO(dev, "Setting dpms mode %d on vga encoder (output %d)\n",
+		     mode, nv_encoder->dcb->index);
+
+	nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON);
+}
+
+static void nv04_dac_save(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+
+	if (nv_gf4_disp_arch(dev))
+		nv_encoder->restore.output = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK +
+							  nv04_dac_output_offset(encoder));
+}
+
+static void nv04_dac_restore(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+
+	if (nv_gf4_disp_arch(dev))
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + nv04_dac_output_offset(encoder),
+			      nv_encoder->restore.output);
+
+	nv_encoder->last_dpms = NV_DPMS_CLEARED;
+}
+
+static void nv04_dac_destroy(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+	NV_DEBUG(encoder->dev, "\n");
+
+	drm_encoder_cleanup(encoder);
+	kfree(nv_encoder);
+}
+
+static const struct drm_encoder_helper_funcs nv04_dac_helper_funcs = {
+	.dpms = nv04_dac_dpms,
+	.save = nv04_dac_save,
+	.restore = nv04_dac_restore,
+	.mode_fixup = nv04_dac_mode_fixup,
+	.prepare = nv04_dac_prepare,
+	.commit = nv04_dac_commit,
+	.mode_set = nv04_dac_mode_set,
+	.detect = nv04_dac_detect
+};
+
+static const struct drm_encoder_helper_funcs nv17_dac_helper_funcs = {
+	.dpms = nv04_dac_dpms,
+	.save = nv04_dac_save,
+	.restore = nv04_dac_restore,
+	.mode_fixup = nv04_dac_mode_fixup,
+	.prepare = nv04_dac_prepare,
+	.commit = nv04_dac_commit,
+	.mode_set = nv04_dac_mode_set,
+	.detect = nv17_dac_detect
+};
+
+static const struct drm_encoder_funcs nv04_dac_funcs = {
+	.destroy = nv04_dac_destroy,
+};
+
+int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry)
+{
+	const struct drm_encoder_helper_funcs *helper;
+	struct drm_encoder *encoder;
+	struct nouveau_encoder *nv_encoder = NULL;
+
+	nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
+	if (!nv_encoder)
+		return -ENOMEM;
+
+	encoder = to_drm_encoder(nv_encoder);
+
+	nv_encoder->dcb = entry;
+	nv_encoder->or = ffs(entry->or) - 1;
+
+	if (nv_gf4_disp_arch(dev))
+		helper = &nv17_dac_helper_funcs;
+	else
+		helper = &nv04_dac_helper_funcs;
+
+	drm_encoder_init(dev, encoder, &nv04_dac_funcs, DRM_MODE_ENCODER_DAC);
+	drm_encoder_helper_add(encoder, helper);
+
+	encoder->possible_crtcs = entry->heads;
+	encoder->possible_clones = 0;
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c
new file mode 100644
index 0000000..e5b3333
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv04_dfp.c
@@ -0,0 +1,621 @@
+/*
+ * Copyright 2003 NVIDIA, Corporation
+ * Copyright 2006 Dave Airlie
+ * Copyright 2007 Maarten Maathuis
+ * Copyright 2007-2009 Stuart Bennett
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+#include "drm_crtc_helper.h"
+
+#include "nouveau_drv.h"
+#include "nouveau_encoder.h"
+#include "nouveau_connector.h"
+#include "nouveau_crtc.h"
+#include "nouveau_hw.h"
+#include "nvreg.h"
+
+#define FP_TG_CONTROL_ON  (NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS |	\
+			   NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS |		\
+			   NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS)
+#define FP_TG_CONTROL_OFF (NV_PRAMDAC_FP_TG_CONTROL_DISPEN_DISABLE |	\
+			   NV_PRAMDAC_FP_TG_CONTROL_HSYNC_DISABLE |	\
+			   NV_PRAMDAC_FP_TG_CONTROL_VSYNC_DISABLE)
+
+static inline bool is_fpc_off(uint32_t fpc)
+{
+	return ((fpc & (FP_TG_CONTROL_ON | FP_TG_CONTROL_OFF)) ==
+			FP_TG_CONTROL_OFF);
+}
+
+int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_entry *dcbent)
+{
+	/* special case of nv_read_tmds to find crtc associated with an output.
+	 * this does not give a correct answer for off-chip dvi, but there's no
+	 * use for such an answer anyway
+	 */
+	int ramdac = (dcbent->or & OUTPUT_C) >> 2;
+
+	NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL,
+	NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE | 0x4);
+	return ((NVReadRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_DATA) & 0x8) >> 3) ^ ramdac;
+}
+
+void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_entry *dcbent,
+			int head, bool dl)
+{
+	/* The BIOS scripts don't do this for us, sadly
+	 * Luckily we do know the values ;-)
+	 *
+	 * head < 0 indicates we wish to force a setting with the overrideval
+	 * (for VT restore etc.)
+	 */
+
+	int ramdac = (dcbent->or & OUTPUT_C) >> 2;
+	uint8_t tmds04 = 0x80;
+
+	if (head != ramdac)
+		tmds04 = 0x88;
+
+	if (dcbent->type == OUTPUT_LVDS)
+		tmds04 |= 0x01;
+
+	nv_write_tmds(dev, dcbent->or, 0, 0x04, tmds04);
+
+	if (dl)	/* dual link */
+		nv_write_tmds(dev, dcbent->or, 1, 0x04, tmds04 ^ 0x08);
+}
+
+void nv04_dfp_disable(struct drm_device *dev, int head)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv04_crtc_reg *crtcstate = dev_priv->mode_reg.crtc_reg;
+
+	if (NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL) &
+	    FP_TG_CONTROL_ON) {
+		/* digital remnants must be cleaned before new crtc
+		 * values programmed.  delay is time for the vga stuff
+		 * to realise it's in control again
+		 */
+		NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL,
+			      FP_TG_CONTROL_OFF);
+		msleep(50);
+	}
+	/* don't inadvertently turn it on when state written later */
+	crtcstate[head].fp_control = FP_TG_CONTROL_OFF;
+}
+
+void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc;
+	struct nouveau_crtc *nv_crtc;
+	uint32_t *fpc;
+
+	if (mode == DRM_MODE_DPMS_ON) {
+		nv_crtc = nouveau_crtc(encoder->crtc);
+		fpc = &dev_priv->mode_reg.crtc_reg[nv_crtc->index].fp_control;
+
+		if (is_fpc_off(*fpc)) {
+			/* using saved value is ok, as (is_digital && dpms_on &&
+			 * fp_control==OFF) is (at present) *only* true when
+			 * fpc's most recent change was by below "off" code
+			 */
+			*fpc = nv_crtc->dpms_saved_fp_control;
+		}
+
+		nv_crtc->fp_users |= 1 << nouveau_encoder(encoder)->dcb->index;
+		NVWriteRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_FP_TG_CONTROL, *fpc);
+	} else {
+		list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+			nv_crtc = nouveau_crtc(crtc);
+			fpc = &dev_priv->mode_reg.crtc_reg[nv_crtc->index].fp_control;
+
+			nv_crtc->fp_users &= ~(1 << nouveau_encoder(encoder)->dcb->index);
+			if (!is_fpc_off(*fpc) && !nv_crtc->fp_users) {
+				nv_crtc->dpms_saved_fp_control = *fpc;
+				/* cut the FP output */
+				*fpc &= ~FP_TG_CONTROL_ON;
+				*fpc |= FP_TG_CONTROL_OFF;
+				NVWriteRAMDAC(dev, nv_crtc->index,
+					      NV_PRAMDAC_FP_TG_CONTROL, *fpc);
+			}
+		}
+	}
+}
+
+static bool nv04_dfp_mode_fixup(struct drm_encoder *encoder,
+				struct drm_display_mode *mode,
+				struct drm_display_mode *adjusted_mode)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct nouveau_connector *nv_connector = nouveau_encoder_connector_get(nv_encoder);
+
+	/* For internal panels and gpu scaling on DVI we need the native mode */
+	if (nv_connector->scaling_mode != DRM_MODE_SCALE_NONE) {
+		if (!nv_connector->native_mode)
+			return false;
+		nv_encoder->mode = *nv_connector->native_mode;
+		adjusted_mode->clock = nv_connector->native_mode->clock;
+	} else {
+		nv_encoder->mode = *adjusted_mode;
+	}
+
+	return true;
+}
+
+static void nv04_dfp_prepare_sel_clk(struct drm_device *dev,
+				     struct nouveau_encoder *nv_encoder, int head)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv04_mode_state *state = &dev_priv->mode_reg;
+	uint32_t bits1618 = nv_encoder->dcb->or & OUTPUT_A ? 0x10000 : 0x40000;
+
+	if (nv_encoder->dcb->location != DCB_LOC_ON_CHIP)
+		return;
+
+	/* SEL_CLK is only used on the primary ramdac
+	 * It toggles spread spectrum PLL output and sets the bindings of PLLs
+	 * to heads on digital outputs
+	 */
+	if (head)
+		state->sel_clk |= bits1618;
+	else
+		state->sel_clk &= ~bits1618;
+
+	/* nv30:
+	 *	bit 0		NVClk spread spectrum on/off
+	 *	bit 2		MemClk spread spectrum on/off
+	 * 	bit 4		PixClk1 spread spectrum on/off toggle
+	 * 	bit 6		PixClk2 spread spectrum on/off toggle
+	 *
+	 * nv40 (observations from bios behaviour and mmio traces):
+	 * 	bits 4&6	as for nv30
+	 * 	bits 5&7	head dependent as for bits 4&6, but do not appear with 4&6;
+	 * 			maybe a different spread mode
+	 * 	bits 8&10	seen on dual-link dvi outputs, purpose unknown (set by POST scripts)
+	 * 	The logic behind turning spread spectrum on/off in the first place,
+	 * 	and which bit-pair to use, is unclear on nv40 (for earlier cards, the fp table
+	 * 	entry has the necessary info)
+	 */
+	if (nv_encoder->dcb->type == OUTPUT_LVDS && dev_priv->saved_reg.sel_clk & 0xf0) {
+		int shift = (dev_priv->saved_reg.sel_clk & 0x50) ? 0 : 1;
+
+		state->sel_clk &= ~0xf0;
+		state->sel_clk |= (head ? 0x40 : 0x10) << shift;
+	}
+}
+
+static void nv04_dfp_prepare(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_encoder_helper_funcs *helper = encoder->helper_private;
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int head = nouveau_crtc(encoder->crtc)->index;
+	struct nv04_crtc_reg *crtcstate = dev_priv->mode_reg.crtc_reg;
+	uint8_t *cr_lcd = &crtcstate[head].CRTC[NV_CIO_CRE_LCD__INDEX];
+	uint8_t *cr_lcd_oth = &crtcstate[head ^ 1].CRTC[NV_CIO_CRE_LCD__INDEX];
+
+	helper->dpms(encoder, DRM_MODE_DPMS_OFF);
+
+	nv04_dfp_prepare_sel_clk(dev, nv_encoder, head);
+
+	/* Some NV4x have unknown values (0x3f, 0x50, 0x54, 0x6b, 0x79, 0x7f)
+	 * at LCD__INDEX which we don't alter
+	 */
+	if (!(*cr_lcd & 0x44)) {
+		*cr_lcd = 0x3;
+
+		if (nv_two_heads(dev)) {
+			if (nv_encoder->dcb->location == DCB_LOC_ON_CHIP)
+				*cr_lcd |= head ? 0x0 : 0x8;
+			else {
+				*cr_lcd |= (nv_encoder->dcb->or << 4) & 0x30;
+				if (nv_encoder->dcb->type == OUTPUT_LVDS)
+					*cr_lcd |= 0x30;
+				if ((*cr_lcd & 0x30) == (*cr_lcd_oth & 0x30)) {
+					/* avoid being connected to both crtcs */
+					*cr_lcd_oth &= ~0x30;
+					NVWriteVgaCrtc(dev, head ^ 1,
+						       NV_CIO_CRE_LCD__INDEX,
+						       *cr_lcd_oth);
+				}
+			}
+		}
+	}
+}
+
+
+static void nv04_dfp_mode_set(struct drm_encoder *encoder,
+			      struct drm_display_mode *mode,
+			      struct drm_display_mode *adjusted_mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
+	struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
+	struct nv04_crtc_reg *savep = &dev_priv->saved_reg.crtc_reg[nv_crtc->index];
+	struct nouveau_connector *nv_connector = nouveau_crtc_connector_get(nv_crtc);
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_display_mode *output_mode = &nv_encoder->mode;
+	uint32_t mode_ratio, panel_ratio;
+
+	NV_DEBUG(dev, "Output mode on CRTC %d:\n", nv_crtc->index);
+	drm_mode_debug_printmodeline(output_mode);
+
+	/* Initialize the FP registers in this CRTC. */
+	regp->fp_horiz_regs[FP_DISPLAY_END] = output_mode->hdisplay - 1;
+	regp->fp_horiz_regs[FP_TOTAL] = output_mode->htotal - 1;
+	if (!nv_gf4_disp_arch(dev) ||
+	    (output_mode->hsync_start - output_mode->hdisplay) >=
+					dev_priv->vbios->digital_min_front_porch)
+		regp->fp_horiz_regs[FP_CRTC] = output_mode->hdisplay;
+	else
+		regp->fp_horiz_regs[FP_CRTC] = output_mode->hsync_start - dev_priv->vbios->digital_min_front_porch - 1;
+	regp->fp_horiz_regs[FP_SYNC_START] = output_mode->hsync_start - 1;
+	regp->fp_horiz_regs[FP_SYNC_END] = output_mode->hsync_end - 1;
+	regp->fp_horiz_regs[FP_VALID_START] = output_mode->hskew;
+	regp->fp_horiz_regs[FP_VALID_END] = output_mode->hdisplay - 1;
+
+	regp->fp_vert_regs[FP_DISPLAY_END] = output_mode->vdisplay - 1;
+	regp->fp_vert_regs[FP_TOTAL] = output_mode->vtotal - 1;
+	regp->fp_vert_regs[FP_CRTC] = output_mode->vtotal - 5 - 1;
+	regp->fp_vert_regs[FP_SYNC_START] = output_mode->vsync_start - 1;
+	regp->fp_vert_regs[FP_SYNC_END] = output_mode->vsync_end - 1;
+	regp->fp_vert_regs[FP_VALID_START] = 0;
+	regp->fp_vert_regs[FP_VALID_END] = output_mode->vdisplay - 1;
+
+	/* bit26: a bit seen on some g7x, no as yet discernable purpose */
+	regp->fp_control = NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS |
+			   (savep->fp_control & (1 << 26 | NV_PRAMDAC_FP_TG_CONTROL_READ_PROG));
+	/* Deal with vsync/hsync polarity */
+	/* LVDS screens do set this, but modes with +ve syncs are very rare */
+	if (output_mode->flags & DRM_MODE_FLAG_PVSYNC)
+		regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS;
+	if (output_mode->flags & DRM_MODE_FLAG_PHSYNC)
+		regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS;
+	/* panel scaling first, as native would get set otherwise */
+	if (nv_connector->scaling_mode == DRM_MODE_SCALE_NONE ||
+	    nv_connector->scaling_mode == DRM_MODE_SCALE_CENTER)	/* panel handles it */
+		regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_MODE_CENTER;
+	else if (adjusted_mode->hdisplay == output_mode->hdisplay &&
+		 adjusted_mode->vdisplay == output_mode->vdisplay) /* native mode */
+		regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_MODE_NATIVE;
+	else /* gpu needs to scale */
+		regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_MODE_SCALE;
+	if (nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) & NV_PEXTDEV_BOOT_0_STRAP_FP_IFACE_12BIT)
+		regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12;
+	if (nv_encoder->dcb->location != DCB_LOC_ON_CHIP &&
+	    output_mode->clock > 165000)
+		regp->fp_control |= (2 << 24);
+	if (nv_encoder->dcb->type == OUTPUT_LVDS) {
+		bool duallink, dummy;
+
+		nouveau_bios_parse_lvds_table(dev, nv_connector->native_mode->
+					      clock, &duallink, &dummy);
+		if (duallink)
+			regp->fp_control |= (8 << 28);
+	} else
+	if (output_mode->clock > 165000)
+		regp->fp_control |= (8 << 28);
+
+	regp->fp_debug_0 = NV_PRAMDAC_FP_DEBUG_0_YWEIGHT_ROUND |
+			   NV_PRAMDAC_FP_DEBUG_0_XWEIGHT_ROUND |
+			   NV_PRAMDAC_FP_DEBUG_0_YINTERP_BILINEAR |
+			   NV_PRAMDAC_FP_DEBUG_0_XINTERP_BILINEAR |
+			   NV_RAMDAC_FP_DEBUG_0_TMDS_ENABLED |
+			   NV_PRAMDAC_FP_DEBUG_0_YSCALE_ENABLE |
+			   NV_PRAMDAC_FP_DEBUG_0_XSCALE_ENABLE;
+
+	/* We want automatic scaling */
+	regp->fp_debug_1 = 0;
+	/* This can override HTOTAL and VTOTAL */
+	regp->fp_debug_2 = 0;
+
+	/* Use 20.12 fixed point format to avoid floats */
+	mode_ratio = (1 << 12) * adjusted_mode->hdisplay / adjusted_mode->vdisplay;
+	panel_ratio = (1 << 12) * output_mode->hdisplay / output_mode->vdisplay;
+	/* if ratios are equal, SCALE_ASPECT will automatically (and correctly)
+	 * get treated the same as SCALE_FULLSCREEN */
+	if (nv_connector->scaling_mode == DRM_MODE_SCALE_ASPECT &&
+	    mode_ratio != panel_ratio) {
+		uint32_t diff, scale;
+		bool divide_by_2 = nv_gf4_disp_arch(dev);
+
+		if (mode_ratio < panel_ratio) {
+			/* vertical needs to expand to glass size (automatic)
+			 * horizontal needs to be scaled at vertical scale factor
+			 * to maintain aspect */
+
+			scale = (1 << 12) * adjusted_mode->vdisplay / output_mode->vdisplay;
+			regp->fp_debug_1 = NV_PRAMDAC_FP_DEBUG_1_XSCALE_TESTMODE_ENABLE |
+					   XLATE(scale, divide_by_2, NV_PRAMDAC_FP_DEBUG_1_XSCALE_VALUE);
+
+			/* restrict area of screen used, horizontally */
+			diff = output_mode->hdisplay -
+			       output_mode->vdisplay * mode_ratio / (1 << 12);
+			regp->fp_horiz_regs[FP_VALID_START] += diff / 2;
+			regp->fp_horiz_regs[FP_VALID_END] -= diff / 2;
+		}
+
+		if (mode_ratio > panel_ratio) {
+			/* horizontal needs to expand to glass size (automatic)
+			 * vertical needs to be scaled at horizontal scale factor
+			 * to maintain aspect */
+
+			scale = (1 << 12) * adjusted_mode->hdisplay / output_mode->hdisplay;
+			regp->fp_debug_1 = NV_PRAMDAC_FP_DEBUG_1_YSCALE_TESTMODE_ENABLE |
+					   XLATE(scale, divide_by_2, NV_PRAMDAC_FP_DEBUG_1_YSCALE_VALUE);
+
+			/* restrict area of screen used, vertically */
+			diff = output_mode->vdisplay -
+			       (1 << 12) * output_mode->hdisplay / mode_ratio;
+			regp->fp_vert_regs[FP_VALID_START] += diff / 2;
+			regp->fp_vert_regs[FP_VALID_END] -= diff / 2;
+		}
+	}
+
+	/* Output property. */
+	if (nv_connector->use_dithering) {
+		if (dev_priv->chipset == 0x11)
+			regp->dither = savep->dither | 0x00010000;
+		else {
+			int i;
+			regp->dither = savep->dither | 0x00000001;
+			for (i = 0; i < 3; i++) {
+				regp->dither_regs[i] = 0xe4e4e4e4;
+				regp->dither_regs[i + 3] = 0x44444444;
+			}
+		}
+	} else {
+		if (dev_priv->chipset != 0x11) {
+			/* reset them */
+			int i;
+			for (i = 0; i < 3; i++) {
+				regp->dither_regs[i] = savep->dither_regs[i];
+				regp->dither_regs[i + 3] = savep->dither_regs[i + 3];
+			}
+		}
+		regp->dither = savep->dither;
+	}
+
+	regp->fp_margin_color = 0;
+}
+
+static void nv04_dfp_commit(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_encoder_helper_funcs *helper = encoder->helper_private;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct dcb_entry *dcbe = nv_encoder->dcb;
+	int head = nouveau_crtc(encoder->crtc)->index;
+
+	NV_TRACE(dev, "%s called for encoder %d\n", __func__, nv_encoder->dcb->index);
+
+	if (dcbe->type == OUTPUT_TMDS)
+		run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock);
+	else if (dcbe->type == OUTPUT_LVDS)
+		call_lvds_script(dev, dcbe, head, LVDS_RESET, nv_encoder->mode.clock);
+
+	/* update fp_control state for any changes made by scripts,
+	 * so correct value is written at DPMS on */
+	dev_priv->mode_reg.crtc_reg[head].fp_control =
+		NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL);
+
+	/* This could use refinement for flatpanels, but it should work this way */
+	if (dev_priv->chipset < 0x44)
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0xf0000000);
+	else
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000);
+
+	helper->dpms(encoder, DRM_MODE_DPMS_ON);
+
+	NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n",
+		drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base),
+		nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
+}
+
+static inline bool is_powersaving_dpms(int mode)
+{
+	return (mode != DRM_MODE_DPMS_ON);
+}
+
+static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_crtc *crtc = encoder->crtc;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	bool was_powersaving = is_powersaving_dpms(nv_encoder->last_dpms);
+
+	if (nv_encoder->last_dpms == mode)
+		return;
+	nv_encoder->last_dpms = mode;
+
+	NV_INFO(dev, "Setting dpms mode %d on lvds encoder (output %d)\n",
+		     mode, nv_encoder->dcb->index);
+
+	if (was_powersaving && is_powersaving_dpms(mode))
+		return;
+
+	if (nv_encoder->dcb->lvdsconf.use_power_scripts) {
+		struct nouveau_connector *nv_connector = nouveau_encoder_connector_get(nv_encoder);
+
+		/* when removing an output, crtc may not be set, but PANEL_OFF
+		 * must still be run
+		 */
+		int head = crtc ? nouveau_crtc(crtc)->index :
+			   nv04_dfp_get_bound_head(dev, nv_encoder->dcb);
+
+		if (mode == DRM_MODE_DPMS_ON) {
+			if (!nv_connector->native_mode) {
+				NV_ERROR(dev, "Not turning on LVDS without native mode\n");
+				return;
+			}
+			call_lvds_script(dev, nv_encoder->dcb, head,
+					 LVDS_PANEL_ON, nv_connector->native_mode->clock);
+		} else
+			/* pxclk of 0 is fine for PANEL_OFF, and for a
+			 * disconnected LVDS encoder there is no native_mode
+			 */
+			call_lvds_script(dev, nv_encoder->dcb, head,
+					 LVDS_PANEL_OFF, 0);
+	}
+
+	nv04_dfp_update_fp_control(encoder, mode);
+
+	if (mode == DRM_MODE_DPMS_ON)
+		nv04_dfp_prepare_sel_clk(dev, nv_encoder, nouveau_crtc(crtc)->index);
+	else {
+		dev_priv->mode_reg.sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK);
+		dev_priv->mode_reg.sel_clk &= ~0xf0;
+	}
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, dev_priv->mode_reg.sel_clk);
+}
+
+static void nv04_tmds_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+	if (nv_encoder->last_dpms == mode)
+		return;
+	nv_encoder->last_dpms = mode;
+
+	NV_INFO(dev, "Setting dpms mode %d on tmds encoder (output %d)\n",
+		     mode, nv_encoder->dcb->index);
+
+	nv04_dfp_update_fp_control(encoder, mode);
+}
+
+static void nv04_dfp_save(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+
+	if (nv_two_heads(dev))
+		nv_encoder->restore.head =
+			nv04_dfp_get_bound_head(dev, nv_encoder->dcb);
+}
+
+static void nv04_dfp_restore(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int head = nv_encoder->restore.head;
+
+	if (nv_encoder->dcb->type == OUTPUT_LVDS) {
+		struct drm_display_mode *native_mode = nouveau_encoder_connector_get(nv_encoder)->native_mode;
+		if (native_mode)
+			call_lvds_script(dev, nv_encoder->dcb, head, LVDS_PANEL_ON,
+					 native_mode->clock);
+		else
+			NV_ERROR(dev, "Not restoring LVDS without native mode\n");
+
+	} else if (nv_encoder->dcb->type == OUTPUT_TMDS) {
+		int clock = nouveau_hw_pllvals_to_clk
+					(&dev_priv->saved_reg.crtc_reg[head].pllvals);
+
+		run_tmds_table(dev, nv_encoder->dcb, head, clock);
+	}
+
+	nv_encoder->last_dpms = NV_DPMS_CLEARED;
+}
+
+static void nv04_dfp_destroy(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+	NV_DEBUG(encoder->dev, "\n");
+
+	drm_encoder_cleanup(encoder);
+	kfree(nv_encoder);
+}
+
+static const struct drm_encoder_helper_funcs nv04_lvds_helper_funcs = {
+	.dpms = nv04_lvds_dpms,
+	.save = nv04_dfp_save,
+	.restore = nv04_dfp_restore,
+	.mode_fixup = nv04_dfp_mode_fixup,
+	.prepare = nv04_dfp_prepare,
+	.commit = nv04_dfp_commit,
+	.mode_set = nv04_dfp_mode_set,
+	.detect = NULL,
+};
+
+static const struct drm_encoder_helper_funcs nv04_tmds_helper_funcs = {
+	.dpms = nv04_tmds_dpms,
+	.save = nv04_dfp_save,
+	.restore = nv04_dfp_restore,
+	.mode_fixup = nv04_dfp_mode_fixup,
+	.prepare = nv04_dfp_prepare,
+	.commit = nv04_dfp_commit,
+	.mode_set = nv04_dfp_mode_set,
+	.detect = NULL,
+};
+
+static const struct drm_encoder_funcs nv04_dfp_funcs = {
+	.destroy = nv04_dfp_destroy,
+};
+
+int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry)
+{
+	const struct drm_encoder_helper_funcs *helper;
+	struct drm_encoder *encoder;
+	struct nouveau_encoder *nv_encoder = NULL;
+	int type;
+
+	switch (entry->type) {
+	case OUTPUT_TMDS:
+		type = DRM_MODE_ENCODER_TMDS;
+		helper = &nv04_tmds_helper_funcs;
+		break;
+	case OUTPUT_LVDS:
+		type = DRM_MODE_ENCODER_LVDS;
+		helper = &nv04_lvds_helper_funcs;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
+	if (!nv_encoder)
+		return -ENOMEM;
+
+	encoder = to_drm_encoder(nv_encoder);
+
+	nv_encoder->dcb = entry;
+	nv_encoder->or = ffs(entry->or) - 1;
+
+	drm_encoder_init(dev, encoder, &nv04_dfp_funcs, type);
+	drm_encoder_helper_add(encoder, helper);
+
+	encoder->possible_crtcs = entry->heads;
+	encoder->possible_clones = 0;
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/nv04_display.c
new file mode 100644
index 0000000..b47c757
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv04_display.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright 2009 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Ben Skeggs
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "drm_crtc_helper.h"
+
+#include "nouveau_drv.h"
+#include "nouveau_fb.h"
+#include "nouveau_hw.h"
+#include "nouveau_encoder.h"
+#include "nouveau_connector.h"
+
+#define MULTIPLE_ENCODERS(e) (e & (e - 1))
+
+static void
+nv04_display_store_initial_head_owner(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->chipset != 0x11) {
+		dev_priv->crtc_owner = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44);
+		goto ownerknown;
+	}
+
+	/* reading CR44 is broken on nv11, so we attempt to infer it */
+	if (nvReadMC(dev, NV_PBUS_DEBUG_1) & (1 << 28))	/* heads tied, restore both */
+		dev_priv->crtc_owner = 0x4;
+	else {
+		uint8_t slaved_on_A, slaved_on_B;
+		bool tvA = false;
+		bool tvB = false;
+
+		NVLockVgaCrtcs(dev, false);
+
+		slaved_on_B = NVReadVgaCrtc(dev, 1, NV_CIO_CRE_PIXEL_INDEX) &
+									0x80;
+		if (slaved_on_B)
+			tvB = !(NVReadVgaCrtc(dev, 1, NV_CIO_CRE_LCD__INDEX) &
+					MASK(NV_CIO_CRE_LCD_LCD_SELECT));
+
+		slaved_on_A = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX) &
+									0x80;
+		if (slaved_on_A)
+			tvA = !(NVReadVgaCrtc(dev, 0, NV_CIO_CRE_LCD__INDEX) &
+					MASK(NV_CIO_CRE_LCD_LCD_SELECT));
+
+		NVLockVgaCrtcs(dev, true);
+
+		if (slaved_on_A && !tvA)
+			dev_priv->crtc_owner = 0x0;
+		else if (slaved_on_B && !tvB)
+			dev_priv->crtc_owner = 0x3;
+		else if (slaved_on_A)
+			dev_priv->crtc_owner = 0x0;
+		else if (slaved_on_B)
+			dev_priv->crtc_owner = 0x3;
+		else
+			dev_priv->crtc_owner = 0x0;
+	}
+
+ownerknown:
+	NV_INFO(dev, "Initial CRTC_OWNER is %d\n", dev_priv->crtc_owner);
+
+	/* we need to ensure the heads are not tied henceforth, or reading any
+	 * 8 bit reg on head B will fail
+	 * setting a single arbitrary head solves that */
+	NVSetOwner(dev, 0);
+}
+
+int
+nv04_display_create(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct parsed_dcb *dcb = dev_priv->vbios->dcb;
+	struct drm_encoder *encoder;
+	struct drm_crtc *crtc;
+	uint16_t connector[16] = { 0 };
+	int i, ret;
+
+	NV_DEBUG(dev, "\n");
+
+	if (nv_two_heads(dev))
+		nv04_display_store_initial_head_owner(dev);
+
+	drm_mode_config_init(dev);
+	drm_mode_create_scaling_mode_property(dev);
+	drm_mode_create_dithering_property(dev);
+
+	dev->mode_config.funcs = (void *)&nouveau_mode_config_funcs;
+
+	dev->mode_config.min_width = 0;
+	dev->mode_config.min_height = 0;
+	switch (dev_priv->card_type) {
+	case NV_04:
+		dev->mode_config.max_width = 2048;
+		dev->mode_config.max_height = 2048;
+		break;
+	default:
+		dev->mode_config.max_width = 4096;
+		dev->mode_config.max_height = 4096;
+		break;
+	}
+
+	dev->mode_config.fb_base = dev_priv->fb_phys;
+
+	nv04_crtc_create(dev, 0);
+	if (nv_two_heads(dev))
+		nv04_crtc_create(dev, 1);
+
+	for (i = 0; i < dcb->entries; i++) {
+		struct dcb_entry *dcbent = &dcb->entry[i];
+
+		switch (dcbent->type) {
+		case OUTPUT_ANALOG:
+			ret = nv04_dac_create(dev, dcbent);
+			break;
+		case OUTPUT_LVDS:
+		case OUTPUT_TMDS:
+			ret = nv04_dfp_create(dev, dcbent);
+			break;
+		case OUTPUT_TV:
+			if (dcbent->location == DCB_LOC_ON_CHIP)
+				ret = nv17_tv_create(dev, dcbent);
+			else
+				ret = nv04_tv_create(dev, dcbent);
+			break;
+		default:
+			NV_WARN(dev, "DCB type %d not known\n", dcbent->type);
+			continue;
+		}
+
+		if (ret)
+			continue;
+
+		connector[dcbent->connector] |= (1 << dcbent->type);
+	}
+
+	for (i = 0; i < dcb->entries; i++) {
+		struct dcb_entry *dcbent = &dcb->entry[i];
+		uint16_t encoders;
+		int type;
+
+		encoders = connector[dcbent->connector];
+		if (!(encoders & (1 << dcbent->type)))
+			continue;
+		connector[dcbent->connector] = 0;
+
+		switch (dcbent->type) {
+		case OUTPUT_ANALOG:
+			if (!MULTIPLE_ENCODERS(encoders))
+				type = DRM_MODE_CONNECTOR_VGA;
+			else
+				type = DRM_MODE_CONNECTOR_DVII;
+			break;
+		case OUTPUT_TMDS:
+			if (!MULTIPLE_ENCODERS(encoders))
+				type = DRM_MODE_CONNECTOR_DVID;
+			else
+				type = DRM_MODE_CONNECTOR_DVII;
+			break;
+		case OUTPUT_LVDS:
+			type = DRM_MODE_CONNECTOR_LVDS;
+#if 0
+			/* don't create i2c adapter when lvds ddc not allowed */
+			if (dcbent->lvdsconf.use_straps_for_mode ||
+			    dev_priv->vbios->fp_no_ddc)
+				i2c_index = 0xf;
+#endif
+			break;
+		case OUTPUT_TV:
+			type = DRM_MODE_CONNECTOR_TV;
+			break;
+		default:
+			type = DRM_MODE_CONNECTOR_Unknown;
+			continue;
+		}
+
+		nouveau_connector_create(dev, dcbent->connector, type);
+	}
+
+	/* Save previous state */
+	NVLockVgaCrtcs(dev, false);
+
+	nouveau_hw_save_vga_fonts(dev, 1);
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+		crtc->funcs->save(crtc);
+
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		struct drm_encoder_helper_funcs *func = encoder->helper_private;
+
+		func->save(encoder);
+	}
+
+	return 0;
+}
+
+void
+nv04_display_destroy(struct drm_device *dev)
+{
+	struct drm_encoder *encoder;
+	struct drm_crtc *crtc;
+
+	NV_DEBUG(dev, "\n");
+
+	/* Turn every CRTC off. */
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		struct drm_mode_set modeset = {
+			.crtc = crtc,
+		};
+
+		crtc->funcs->set_config(&modeset);
+	}
+
+	/* Restore state */
+	NVLockVgaCrtcs(dev, false);
+
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		struct drm_encoder_helper_funcs *func = encoder->helper_private;
+
+		func->restore(encoder);
+	}
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+		crtc->funcs->restore(crtc);
+
+	nouveau_hw_save_vga_fonts(dev, 0);
+
+	drm_mode_config_cleanup(dev);
+}
+
+void
+nv04_display_restore(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_encoder *encoder;
+	struct drm_crtc *crtc;
+
+	NVLockVgaCrtcs(dev, false);
+
+	/* meh.. modeset apparently doesn't setup all the regs and depends
+	 * on pre-existing state, for now load the state of the card *before*
+	 * nouveau was loaded, and then do a modeset.
+	 *
+	 * best thing to do probably is to make save/restore routines not
+	 * save/restore "pre-load" state, but more general so we can save
+	 * on suspend too.
+	 */
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		struct drm_encoder_helper_funcs *func = encoder->helper_private;
+
+		func->restore(encoder);
+	}
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+		crtc->funcs->restore(crtc);
+
+	if (nv_two_heads(dev)) {
+		NV_INFO(dev, "Restoring CRTC_OWNER to %d.\n",
+			dev_priv->crtc_owner);
+		NVSetOwner(dev, dev_priv->crtc_owner);
+	}
+
+	NVLockVgaCrtcs(dev, true);
+}
+
diff --git a/drivers/gpu/drm/nouveau/nv04_fb.c b/drivers/gpu/drm/nouveau/nv04_fb.c
new file mode 100644
index 0000000..638cf60
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv04_fb.c
@@ -0,0 +1,21 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+int
+nv04_fb_init(struct drm_device *dev)
+{
+	/* This is what the DDX did for NV_ARCH_04, but a mmio-trace shows
+	 * nvidia reading PFB_CFG_0, then writing back its original value.
+	 * (which was 0x701114 in this case)
+	 */
+
+	nv_wr32(dev, NV04_PFB_CFG0, 0x1114);
+	return 0;
+}
+
+void
+nv04_fb_takedown(struct drm_device *dev)
+{
+}
diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c
new file mode 100644
index 0000000..09a3107
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright 2009 Ben Skeggs
+ * Copyright 2008 Stuart Bennett
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_dma.h"
+#include "nouveau_fbcon.h"
+
+static void
+nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region)
+{
+	struct nouveau_fbcon_par *par = info->par;
+	struct drm_device *dev = par->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = dev_priv->channel;
+
+	if (info->state != FBINFO_STATE_RUNNING)
+		return;
+
+	if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 4)) {
+		NV_ERROR(dev, "GPU lockup - switching to software fbcon\n");
+		info->flags |= FBINFO_HWACCEL_DISABLED;
+	}
+
+	if (info->flags & FBINFO_HWACCEL_DISABLED) {
+		cfb_copyarea(info, region);
+		return;
+	}
+
+	BEGIN_RING(chan, NvSubImageBlit, 0x0300, 3);
+	OUT_RING(chan, (region->sy << 16) | region->sx);
+	OUT_RING(chan, (region->dy << 16) | region->dx);
+	OUT_RING(chan, (region->height << 16) | region->width);
+	FIRE_RING(chan);
+}
+
+static void
+nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
+{
+	struct nouveau_fbcon_par *par = info->par;
+	struct drm_device *dev = par->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = dev_priv->channel;
+	uint32_t color = ((uint32_t *) info->pseudo_palette)[rect->color];
+
+	if (info->state != FBINFO_STATE_RUNNING)
+		return;
+
+	if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 7)) {
+		NV_ERROR(dev, "GPU lockup - switching to software fbcon\n");
+		info->flags |= FBINFO_HWACCEL_DISABLED;
+	}
+
+	if (info->flags & FBINFO_HWACCEL_DISABLED) {
+		cfb_fillrect(info, rect);
+		return;
+	}
+
+	BEGIN_RING(chan, NvSubGdiRect, 0x02fc, 1);
+	OUT_RING(chan, (rect->rop != ROP_COPY) ? 1 : 3);
+	BEGIN_RING(chan, NvSubGdiRect, 0x03fc, 1);
+	OUT_RING(chan, color);
+	BEGIN_RING(chan, NvSubGdiRect, 0x0400, 2);
+	OUT_RING(chan, (rect->dx << 16) | rect->dy);
+	OUT_RING(chan, (rect->width << 16) | rect->height);
+	FIRE_RING(chan);
+}
+
+static void
+nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
+{
+	struct nouveau_fbcon_par *par = info->par;
+	struct drm_device *dev = par->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = dev_priv->channel;
+	uint32_t fg;
+	uint32_t bg;
+	uint32_t dsize;
+	uint32_t width;
+	uint32_t *data = (uint32_t *)image->data;
+
+	if (info->state != FBINFO_STATE_RUNNING)
+		return;
+
+	if (image->depth != 1) {
+		cfb_imageblit(info, image);
+		return;
+	}
+
+	if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 8)) {
+		NV_ERROR(dev, "GPU lockup - switching to software fbcon\n");
+		info->flags |= FBINFO_HWACCEL_DISABLED;
+	}
+
+	if (info->flags & FBINFO_HWACCEL_DISABLED) {
+		cfb_imageblit(info, image);
+		return;
+	}
+
+	width = (image->width + 31) & ~31;
+	dsize = (width * image->height) >> 5;
+
+	if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
+	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+		fg = ((uint32_t *) info->pseudo_palette)[image->fg_color];
+		bg = ((uint32_t *) info->pseudo_palette)[image->bg_color];
+	} else {
+		fg = image->fg_color;
+		bg = image->bg_color;
+	}
+
+	BEGIN_RING(chan, NvSubGdiRect, 0x0be4, 7);
+	OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff));
+	OUT_RING(chan, ((image->dy + image->height) << 16) |
+			 ((image->dx + image->width) & 0xffff));
+	OUT_RING(chan, bg);
+	OUT_RING(chan, fg);
+	OUT_RING(chan, (image->height << 16) | image->width);
+	OUT_RING(chan, (image->height << 16) | width);
+	OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff));
+
+	while (dsize) {
+		int iter_len = dsize > 128 ? 128 : dsize;
+
+		if (RING_SPACE(chan, iter_len + 1)) {
+			NV_ERROR(dev, "GPU lockup - switching to software fbcon\n");
+			info->flags |= FBINFO_HWACCEL_DISABLED;
+			cfb_imageblit(info, image);
+			return;
+		}
+
+		BEGIN_RING(chan, NvSubGdiRect, 0x0c00, iter_len);
+		OUT_RINGp(chan, data, iter_len);
+		data += iter_len;
+		dsize -= iter_len;
+	}
+
+	FIRE_RING(chan);
+}
+
+static int
+nv04_fbcon_grobj_new(struct drm_device *dev, int class, uint32_t handle)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *obj = NULL;
+	int ret;
+
+	ret = nouveau_gpuobj_gr_new(dev_priv->channel, class, &obj);
+	if (ret)
+		return ret;
+
+	ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, handle, obj, NULL);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+int
+nv04_fbcon_accel_init(struct fb_info *info)
+{
+	struct nouveau_fbcon_par *par = info->par;
+	struct drm_device *dev = par->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = dev_priv->channel;
+	int surface_fmt, pattern_fmt, rect_fmt;
+	int ret;
+
+	switch (info->var.bits_per_pixel) {
+	case 8:
+		surface_fmt = 1;
+		pattern_fmt = 3;
+		rect_fmt = 3;
+		break;
+	case 16:
+		surface_fmt = 4;
+		pattern_fmt = 1;
+		rect_fmt = 1;
+		break;
+	case 32:
+		switch (info->var.transp.length) {
+		case 0: /* depth 24 */
+		case 8: /* depth 32 */
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		surface_fmt = 6;
+		pattern_fmt = 3;
+		rect_fmt = 3;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	ret = nv04_fbcon_grobj_new(dev, dev_priv->card_type >= NV_10 ?
+				   0x0062 : 0x0042, NvCtxSurf2D);
+	if (ret)
+		return ret;
+
+	ret = nv04_fbcon_grobj_new(dev, 0x0019, NvClipRect);
+	if (ret)
+		return ret;
+
+	ret = nv04_fbcon_grobj_new(dev, 0x0043, NvRop);
+	if (ret)
+		return ret;
+
+	ret = nv04_fbcon_grobj_new(dev, 0x0044, NvImagePatt);
+	if (ret)
+		return ret;
+
+	ret = nv04_fbcon_grobj_new(dev, 0x004a, NvGdiRect);
+	if (ret)
+		return ret;
+
+	ret = nv04_fbcon_grobj_new(dev, dev_priv->card_type >= NV_10 ?
+				   0x009f : 0x005f, NvImageBlit);
+	if (ret)
+		return ret;
+
+	if (RING_SPACE(chan, 49)) {
+		NV_ERROR(dev, "GPU lockup - switching to software fbcon\n");
+		info->flags |= FBINFO_HWACCEL_DISABLED;
+		return 0;
+	}
+
+	BEGIN_RING(chan, 1, 0x0000, 1);
+	OUT_RING(chan, NvCtxSurf2D);
+	BEGIN_RING(chan, 1, 0x0184, 2);
+	OUT_RING(chan, NvDmaFB);
+	OUT_RING(chan, NvDmaFB);
+	BEGIN_RING(chan, 1, 0x0300, 4);
+	OUT_RING(chan, surface_fmt);
+	OUT_RING(chan, info->fix.line_length | (info->fix.line_length << 16));
+	OUT_RING(chan, info->fix.smem_start - dev->mode_config.fb_base);
+	OUT_RING(chan, info->fix.smem_start - dev->mode_config.fb_base);
+
+	BEGIN_RING(chan, 1, 0x0000, 1);
+	OUT_RING(chan, NvRop);
+	BEGIN_RING(chan, 1, 0x0300, 1);
+	OUT_RING(chan, 0x55);
+
+	BEGIN_RING(chan, 1, 0x0000, 1);
+	OUT_RING(chan, NvImagePatt);
+	BEGIN_RING(chan, 1, 0x0300, 8);
+	OUT_RING(chan, pattern_fmt);
+#ifdef __BIG_ENDIAN
+	OUT_RING(chan, 2);
+#else
+	OUT_RING(chan, 1);
+#endif
+	OUT_RING(chan, 0);
+	OUT_RING(chan, 1);
+	OUT_RING(chan, ~0);
+	OUT_RING(chan, ~0);
+	OUT_RING(chan, ~0);
+	OUT_RING(chan, ~0);
+
+	BEGIN_RING(chan, 1, 0x0000, 1);
+	OUT_RING(chan, NvClipRect);
+	BEGIN_RING(chan, 1, 0x0300, 2);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, (info->var.yres_virtual << 16) | info->var.xres_virtual);
+
+	BEGIN_RING(chan, NvSubImageBlit, 0x0000, 1);
+	OUT_RING(chan, NvImageBlit);
+	BEGIN_RING(chan, NvSubImageBlit, 0x019c, 1);
+	OUT_RING(chan, NvCtxSurf2D);
+	BEGIN_RING(chan, NvSubImageBlit, 0x02fc, 1);
+	OUT_RING(chan, 3);
+
+	BEGIN_RING(chan, NvSubGdiRect, 0x0000, 1);
+	OUT_RING(chan, NvGdiRect);
+	BEGIN_RING(chan, NvSubGdiRect, 0x0198, 1);
+	OUT_RING(chan, NvCtxSurf2D);
+	BEGIN_RING(chan, NvSubGdiRect, 0x0188, 2);
+	OUT_RING(chan, NvImagePatt);
+	OUT_RING(chan, NvRop);
+	BEGIN_RING(chan, NvSubGdiRect, 0x0304, 1);
+	OUT_RING(chan, 1);
+	BEGIN_RING(chan, NvSubGdiRect, 0x0300, 1);
+	OUT_RING(chan, rect_fmt);
+	BEGIN_RING(chan, NvSubGdiRect, 0x02fc, 1);
+	OUT_RING(chan, 3);
+
+	FIRE_RING(chan);
+
+	info->fbops->fb_fillrect = nv04_fbcon_fillrect;
+	info->fbops->fb_copyarea = nv04_fbcon_copyarea;
+	info->fbops->fb_imageblit = nv04_fbcon_imageblit;
+	return 0;
+}
+
diff --git a/drivers/gpu/drm/nouveau/nv04_fifo.c b/drivers/gpu/drm/nouveau/nv04_fifo.c
new file mode 100644
index 0000000..0c3cd53
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv04_fifo.c
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+
+#define NV04_RAMFC(c) (dev_priv->ramfc_offset + ((c) * NV04_RAMFC__SIZE))
+#define NV04_RAMFC__SIZE 32
+#define NV04_RAMFC_DMA_PUT                                       0x00
+#define NV04_RAMFC_DMA_GET                                       0x04
+#define NV04_RAMFC_DMA_INSTANCE                                  0x08
+#define NV04_RAMFC_DMA_STATE                                     0x0C
+#define NV04_RAMFC_DMA_FETCH                                     0x10
+#define NV04_RAMFC_ENGINE                                        0x14
+#define NV04_RAMFC_PULL1_ENGINE                                  0x18
+
+#define RAMFC_WR(offset, val) nv_wo32(dev, chan->ramfc->gpuobj, \
+					 NV04_RAMFC_##offset/4, (val))
+#define RAMFC_RD(offset)      nv_ro32(dev, chan->ramfc->gpuobj, \
+					 NV04_RAMFC_##offset/4)
+
+void
+nv04_fifo_disable(struct drm_device *dev)
+{
+	uint32_t tmp;
+
+	tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUSH);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, tmp & ~1);
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 0);
+	tmp = nv_rd32(dev, NV03_PFIFO_CACHE1_PULL1);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, tmp & ~1);
+}
+
+void
+nv04_fifo_enable(struct drm_device *dev)
+{
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 1);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1);
+}
+
+bool
+nv04_fifo_reassign(struct drm_device *dev, bool enable)
+{
+	uint32_t reassign = nv_rd32(dev, NV03_PFIFO_CACHES);
+
+	nv_wr32(dev, NV03_PFIFO_CACHES, enable ? 1 : 0);
+	return (reassign == 1);
+}
+
+int
+nv04_fifo_channel_id(struct drm_device *dev)
+{
+	return nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) &
+			NV03_PFIFO_CACHE1_PUSH1_CHID_MASK;
+}
+
+int
+nv04_fifo_create_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int ret;
+
+	ret = nouveau_gpuobj_new_fake(dev, NV04_RAMFC(chan->id), ~0,
+						NV04_RAMFC__SIZE,
+						NVOBJ_FLAG_ZERO_ALLOC |
+						NVOBJ_FLAG_ZERO_FREE,
+						NULL, &chan->ramfc);
+	if (ret)
+		return ret;
+
+	/* Setup initial state */
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	RAMFC_WR(DMA_PUT, chan->pushbuf_base);
+	RAMFC_WR(DMA_GET, chan->pushbuf_base);
+	RAMFC_WR(DMA_INSTANCE, chan->pushbuf->instance >> 4);
+	RAMFC_WR(DMA_FETCH, (NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
+			     NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
+			     NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 |
+#ifdef __BIG_ENDIAN
+			     NV_PFIFO_CACHE1_BIG_ENDIAN |
+#endif
+			     0));
+	dev_priv->engine.instmem.finish_access(dev);
+
+	/* enable the fifo dma operation */
+	nv_wr32(dev, NV04_PFIFO_MODE,
+		nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id));
+	return 0;
+}
+
+void
+nv04_fifo_destroy_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+
+	nv_wr32(dev, NV04_PFIFO_MODE,
+		nv_rd32(dev, NV04_PFIFO_MODE) & ~(1 << chan->id));
+
+	nouveau_gpuobj_ref_del(dev, &chan->ramfc);
+}
+
+static void
+nv04_fifo_do_load_context(struct drm_device *dev, int chid)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t fc = NV04_RAMFC(chid), tmp;
+
+	dev_priv->engine.instmem.prepare_access(dev, false);
+
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4));
+	tmp = nv_ri32(dev, fc + 8);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE, tmp & 0xFFFF);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT, tmp >> 16);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_STATE, nv_ri32(dev, fc + 12));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_FETCH, nv_ri32(dev, fc + 16));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_ri32(dev, fc + 20));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_PULL1, nv_ri32(dev, fc + 24));
+
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0);
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0);
+}
+
+int
+nv04_fifo_load_context(struct nouveau_channel *chan)
+{
+	uint32_t tmp;
+
+	nv_wr32(chan->dev, NV03_PFIFO_CACHE1_PUSH1,
+			   NV03_PFIFO_CACHE1_PUSH1_DMA | chan->id);
+	nv04_fifo_do_load_context(chan->dev, chan->id);
+	nv_wr32(chan->dev, NV04_PFIFO_CACHE1_DMA_PUSH, 1);
+
+	/* Reset NV04_PFIFO_CACHE1_DMA_CTL_AT_INFO to INVALID */
+	tmp = nv_rd32(chan->dev, NV04_PFIFO_CACHE1_DMA_CTL) & ~(1 << 31);
+	nv_wr32(chan->dev, NV04_PFIFO_CACHE1_DMA_CTL, tmp);
+
+	return 0;
+}
+
+int
+nv04_fifo_unload_context(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	struct nouveau_channel *chan = NULL;
+	uint32_t tmp;
+	int chid;
+
+	chid = pfifo->channel_id(dev);
+	if (chid < 0 || chid >= dev_priv->engine.fifo.channels)
+		return 0;
+
+	chan = dev_priv->fifos[chid];
+	if (!chan) {
+		NV_ERROR(dev, "Inactive channel on PFIFO: %d\n", chid);
+		return -EINVAL;
+	}
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	RAMFC_WR(DMA_PUT, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT));
+	RAMFC_WR(DMA_GET, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET));
+	tmp  = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT) << 16;
+	tmp |= nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE);
+	RAMFC_WR(DMA_INSTANCE, tmp);
+	RAMFC_WR(DMA_STATE, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_STATE));
+	RAMFC_WR(DMA_FETCH, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_FETCH));
+	RAMFC_WR(ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE));
+	RAMFC_WR(PULL1_ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_PULL1));
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nv04_fifo_do_load_context(dev, pfifo->channels - 1);
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1);
+	return 0;
+}
+
+static void
+nv04_fifo_init_reset(struct drm_device *dev)
+{
+	nv_wr32(dev, NV03_PMC_ENABLE,
+		nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PFIFO);
+	nv_wr32(dev, NV03_PMC_ENABLE,
+		nv_rd32(dev, NV03_PMC_ENABLE) |  NV_PMC_ENABLE_PFIFO);
+
+	nv_wr32(dev, 0x003224, 0x000f0078);
+	nv_wr32(dev, 0x002044, 0x0101ffff);
+	nv_wr32(dev, 0x002040, 0x000000ff);
+	nv_wr32(dev, 0x002500, 0x00000000);
+	nv_wr32(dev, 0x003000, 0x00000000);
+	nv_wr32(dev, 0x003050, 0x00000000);
+	nv_wr32(dev, 0x003200, 0x00000000);
+	nv_wr32(dev, 0x003250, 0x00000000);
+	nv_wr32(dev, 0x003220, 0x00000000);
+
+	nv_wr32(dev, 0x003250, 0x00000000);
+	nv_wr32(dev, 0x003270, 0x00000000);
+	nv_wr32(dev, 0x003210, 0x00000000);
+}
+
+static void
+nv04_fifo_init_ramxx(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ |
+				       ((dev_priv->ramht_bits - 9) << 16) |
+				       (dev_priv->ramht_offset >> 8));
+	nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro_offset>>8);
+	nv_wr32(dev, NV03_PFIFO_RAMFC, dev_priv->ramfc_offset >> 8);
+}
+
+static void
+nv04_fifo_init_intr(struct drm_device *dev)
+{
+	nv_wr32(dev, 0x002100, 0xffffffff);
+	nv_wr32(dev, 0x002140, 0xffffffff);
+}
+
+int
+nv04_fifo_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	int i;
+
+	nv04_fifo_init_reset(dev);
+	nv04_fifo_init_ramxx(dev);
+
+	nv04_fifo_do_load_context(dev, pfifo->channels - 1);
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1);
+
+	nv04_fifo_init_intr(dev);
+	pfifo->enable(dev);
+
+	for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
+		if (dev_priv->fifos[i]) {
+			uint32_t mode = nv_rd32(dev, NV04_PFIFO_MODE);
+			nv_wr32(dev, NV04_PFIFO_MODE, mode | (1 << i));
+		}
+	}
+
+	return 0;
+}
+
diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c
new file mode 100644
index 0000000..396ee92
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv04_graph.c
@@ -0,0 +1,579 @@
+/*
+ * Copyright 2007 Stephane Marchesin
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drm.h"
+#include "nouveau_drv.h"
+
+static uint32_t nv04_graph_ctx_regs[] = {
+	NV04_PGRAPH_CTX_SWITCH1,
+	NV04_PGRAPH_CTX_SWITCH2,
+	NV04_PGRAPH_CTX_SWITCH3,
+	NV04_PGRAPH_CTX_SWITCH4,
+	NV04_PGRAPH_CTX_CACHE1,
+	NV04_PGRAPH_CTX_CACHE2,
+	NV04_PGRAPH_CTX_CACHE3,
+	NV04_PGRAPH_CTX_CACHE4,
+	0x00400184,
+	0x004001a4,
+	0x004001c4,
+	0x004001e4,
+	0x00400188,
+	0x004001a8,
+	0x004001c8,
+	0x004001e8,
+	0x0040018c,
+	0x004001ac,
+	0x004001cc,
+	0x004001ec,
+	0x00400190,
+	0x004001b0,
+	0x004001d0,
+	0x004001f0,
+	0x00400194,
+	0x004001b4,
+	0x004001d4,
+	0x004001f4,
+	0x00400198,
+	0x004001b8,
+	0x004001d8,
+	0x004001f8,
+	0x0040019c,
+	0x004001bc,
+	0x004001dc,
+	0x004001fc,
+	0x00400174,
+	NV04_PGRAPH_DMA_START_0,
+	NV04_PGRAPH_DMA_START_1,
+	NV04_PGRAPH_DMA_LENGTH,
+	NV04_PGRAPH_DMA_MISC,
+	NV04_PGRAPH_DMA_PITCH,
+	NV04_PGRAPH_BOFFSET0,
+	NV04_PGRAPH_BBASE0,
+	NV04_PGRAPH_BLIMIT0,
+	NV04_PGRAPH_BOFFSET1,
+	NV04_PGRAPH_BBASE1,
+	NV04_PGRAPH_BLIMIT1,
+	NV04_PGRAPH_BOFFSET2,
+	NV04_PGRAPH_BBASE2,
+	NV04_PGRAPH_BLIMIT2,
+	NV04_PGRAPH_BOFFSET3,
+	NV04_PGRAPH_BBASE3,
+	NV04_PGRAPH_BLIMIT3,
+	NV04_PGRAPH_BOFFSET4,
+	NV04_PGRAPH_BBASE4,
+	NV04_PGRAPH_BLIMIT4,
+	NV04_PGRAPH_BOFFSET5,
+	NV04_PGRAPH_BBASE5,
+	NV04_PGRAPH_BLIMIT5,
+	NV04_PGRAPH_BPITCH0,
+	NV04_PGRAPH_BPITCH1,
+	NV04_PGRAPH_BPITCH2,
+	NV04_PGRAPH_BPITCH3,
+	NV04_PGRAPH_BPITCH4,
+	NV04_PGRAPH_SURFACE,
+	NV04_PGRAPH_STATE,
+	NV04_PGRAPH_BSWIZZLE2,
+	NV04_PGRAPH_BSWIZZLE5,
+	NV04_PGRAPH_BPIXEL,
+	NV04_PGRAPH_NOTIFY,
+	NV04_PGRAPH_PATT_COLOR0,
+	NV04_PGRAPH_PATT_COLOR1,
+	NV04_PGRAPH_PATT_COLORRAM+0x00,
+	NV04_PGRAPH_PATT_COLORRAM+0x01,
+	NV04_PGRAPH_PATT_COLORRAM+0x02,
+	NV04_PGRAPH_PATT_COLORRAM+0x03,
+	NV04_PGRAPH_PATT_COLORRAM+0x04,
+	NV04_PGRAPH_PATT_COLORRAM+0x05,
+	NV04_PGRAPH_PATT_COLORRAM+0x06,
+	NV04_PGRAPH_PATT_COLORRAM+0x07,
+	NV04_PGRAPH_PATT_COLORRAM+0x08,
+	NV04_PGRAPH_PATT_COLORRAM+0x09,
+	NV04_PGRAPH_PATT_COLORRAM+0x0A,
+	NV04_PGRAPH_PATT_COLORRAM+0x0B,
+	NV04_PGRAPH_PATT_COLORRAM+0x0C,
+	NV04_PGRAPH_PATT_COLORRAM+0x0D,
+	NV04_PGRAPH_PATT_COLORRAM+0x0E,
+	NV04_PGRAPH_PATT_COLORRAM+0x0F,
+	NV04_PGRAPH_PATT_COLORRAM+0x10,
+	NV04_PGRAPH_PATT_COLORRAM+0x11,
+	NV04_PGRAPH_PATT_COLORRAM+0x12,
+	NV04_PGRAPH_PATT_COLORRAM+0x13,
+	NV04_PGRAPH_PATT_COLORRAM+0x14,
+	NV04_PGRAPH_PATT_COLORRAM+0x15,
+	NV04_PGRAPH_PATT_COLORRAM+0x16,
+	NV04_PGRAPH_PATT_COLORRAM+0x17,
+	NV04_PGRAPH_PATT_COLORRAM+0x18,
+	NV04_PGRAPH_PATT_COLORRAM+0x19,
+	NV04_PGRAPH_PATT_COLORRAM+0x1A,
+	NV04_PGRAPH_PATT_COLORRAM+0x1B,
+	NV04_PGRAPH_PATT_COLORRAM+0x1C,
+	NV04_PGRAPH_PATT_COLORRAM+0x1D,
+	NV04_PGRAPH_PATT_COLORRAM+0x1E,
+	NV04_PGRAPH_PATT_COLORRAM+0x1F,
+	NV04_PGRAPH_PATT_COLORRAM+0x20,
+	NV04_PGRAPH_PATT_COLORRAM+0x21,
+	NV04_PGRAPH_PATT_COLORRAM+0x22,
+	NV04_PGRAPH_PATT_COLORRAM+0x23,
+	NV04_PGRAPH_PATT_COLORRAM+0x24,
+	NV04_PGRAPH_PATT_COLORRAM+0x25,
+	NV04_PGRAPH_PATT_COLORRAM+0x26,
+	NV04_PGRAPH_PATT_COLORRAM+0x27,
+	NV04_PGRAPH_PATT_COLORRAM+0x28,
+	NV04_PGRAPH_PATT_COLORRAM+0x29,
+	NV04_PGRAPH_PATT_COLORRAM+0x2A,
+	NV04_PGRAPH_PATT_COLORRAM+0x2B,
+	NV04_PGRAPH_PATT_COLORRAM+0x2C,
+	NV04_PGRAPH_PATT_COLORRAM+0x2D,
+	NV04_PGRAPH_PATT_COLORRAM+0x2E,
+	NV04_PGRAPH_PATT_COLORRAM+0x2F,
+	NV04_PGRAPH_PATT_COLORRAM+0x30,
+	NV04_PGRAPH_PATT_COLORRAM+0x31,
+	NV04_PGRAPH_PATT_COLORRAM+0x32,
+	NV04_PGRAPH_PATT_COLORRAM+0x33,
+	NV04_PGRAPH_PATT_COLORRAM+0x34,
+	NV04_PGRAPH_PATT_COLORRAM+0x35,
+	NV04_PGRAPH_PATT_COLORRAM+0x36,
+	NV04_PGRAPH_PATT_COLORRAM+0x37,
+	NV04_PGRAPH_PATT_COLORRAM+0x38,
+	NV04_PGRAPH_PATT_COLORRAM+0x39,
+	NV04_PGRAPH_PATT_COLORRAM+0x3A,
+	NV04_PGRAPH_PATT_COLORRAM+0x3B,
+	NV04_PGRAPH_PATT_COLORRAM+0x3C,
+	NV04_PGRAPH_PATT_COLORRAM+0x3D,
+	NV04_PGRAPH_PATT_COLORRAM+0x3E,
+	NV04_PGRAPH_PATT_COLORRAM+0x3F,
+	NV04_PGRAPH_PATTERN,
+	0x0040080c,
+	NV04_PGRAPH_PATTERN_SHAPE,
+	0x00400600,
+	NV04_PGRAPH_ROP3,
+	NV04_PGRAPH_CHROMA,
+	NV04_PGRAPH_BETA_AND,
+	NV04_PGRAPH_BETA_PREMULT,
+	NV04_PGRAPH_CONTROL0,
+	NV04_PGRAPH_CONTROL1,
+	NV04_PGRAPH_CONTROL2,
+	NV04_PGRAPH_BLEND,
+	NV04_PGRAPH_STORED_FMT,
+	NV04_PGRAPH_SOURCE_COLOR,
+	0x00400560,
+	0x00400568,
+	0x00400564,
+	0x0040056c,
+	0x00400400,
+	0x00400480,
+	0x00400404,
+	0x00400484,
+	0x00400408,
+	0x00400488,
+	0x0040040c,
+	0x0040048c,
+	0x00400410,
+	0x00400490,
+	0x00400414,
+	0x00400494,
+	0x00400418,
+	0x00400498,
+	0x0040041c,
+	0x0040049c,
+	0x00400420,
+	0x004004a0,
+	0x00400424,
+	0x004004a4,
+	0x00400428,
+	0x004004a8,
+	0x0040042c,
+	0x004004ac,
+	0x00400430,
+	0x004004b0,
+	0x00400434,
+	0x004004b4,
+	0x00400438,
+	0x004004b8,
+	0x0040043c,
+	0x004004bc,
+	0x00400440,
+	0x004004c0,
+	0x00400444,
+	0x004004c4,
+	0x00400448,
+	0x004004c8,
+	0x0040044c,
+	0x004004cc,
+	0x00400450,
+	0x004004d0,
+	0x00400454,
+	0x004004d4,
+	0x00400458,
+	0x004004d8,
+	0x0040045c,
+	0x004004dc,
+	0x00400460,
+	0x004004e0,
+	0x00400464,
+	0x004004e4,
+	0x00400468,
+	0x004004e8,
+	0x0040046c,
+	0x004004ec,
+	0x00400470,
+	0x004004f0,
+	0x00400474,
+	0x004004f4,
+	0x00400478,
+	0x004004f8,
+	0x0040047c,
+	0x004004fc,
+	0x0040053c,
+	0x00400544,
+	0x00400540,
+	0x00400548,
+	0x00400560,
+	0x00400568,
+	0x00400564,
+	0x0040056c,
+	0x00400534,
+	0x00400538,
+	0x00400514,
+	0x00400518,
+	0x0040051c,
+	0x00400520,
+	0x00400524,
+	0x00400528,
+	0x0040052c,
+	0x00400530,
+	0x00400d00,
+	0x00400d40,
+	0x00400d80,
+	0x00400d04,
+	0x00400d44,
+	0x00400d84,
+	0x00400d08,
+	0x00400d48,
+	0x00400d88,
+	0x00400d0c,
+	0x00400d4c,
+	0x00400d8c,
+	0x00400d10,
+	0x00400d50,
+	0x00400d90,
+	0x00400d14,
+	0x00400d54,
+	0x00400d94,
+	0x00400d18,
+	0x00400d58,
+	0x00400d98,
+	0x00400d1c,
+	0x00400d5c,
+	0x00400d9c,
+	0x00400d20,
+	0x00400d60,
+	0x00400da0,
+	0x00400d24,
+	0x00400d64,
+	0x00400da4,
+	0x00400d28,
+	0x00400d68,
+	0x00400da8,
+	0x00400d2c,
+	0x00400d6c,
+	0x00400dac,
+	0x00400d30,
+	0x00400d70,
+	0x00400db0,
+	0x00400d34,
+	0x00400d74,
+	0x00400db4,
+	0x00400d38,
+	0x00400d78,
+	0x00400db8,
+	0x00400d3c,
+	0x00400d7c,
+	0x00400dbc,
+	0x00400590,
+	0x00400594,
+	0x00400598,
+	0x0040059c,
+	0x004005a8,
+	0x004005ac,
+	0x004005b0,
+	0x004005b4,
+	0x004005c0,
+	0x004005c4,
+	0x004005c8,
+	0x004005cc,
+	0x004005d0,
+	0x004005d4,
+	0x004005d8,
+	0x004005dc,
+	0x004005e0,
+	NV04_PGRAPH_PASSTHRU_0,
+	NV04_PGRAPH_PASSTHRU_1,
+	NV04_PGRAPH_PASSTHRU_2,
+	NV04_PGRAPH_DVD_COLORFMT,
+	NV04_PGRAPH_SCALED_FORMAT,
+	NV04_PGRAPH_MISC24_0,
+	NV04_PGRAPH_MISC24_1,
+	NV04_PGRAPH_MISC24_2,
+	0x00400500,
+	0x00400504,
+	NV04_PGRAPH_VALID1,
+	NV04_PGRAPH_VALID2
+
+
+};
+
+struct graph_state {
+	int nv04[ARRAY_SIZE(nv04_graph_ctx_regs)];
+};
+
+struct nouveau_channel *
+nv04_graph_channel(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int chid = dev_priv->engine.fifo.channels;
+
+	if (nv_rd32(dev, NV04_PGRAPH_CTX_CONTROL) & 0x00010000)
+		chid = nv_rd32(dev, NV04_PGRAPH_CTX_USER) >> 24;
+
+	if (chid >= dev_priv->engine.fifo.channels)
+		return NULL;
+
+	return dev_priv->fifos[chid];
+}
+
+void
+nv04_graph_context_switch(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	struct nouveau_channel *chan = NULL;
+	int chid;
+
+	pgraph->fifo_access(dev, false);
+	nouveau_wait_for_idle(dev);
+
+	/* If previous context is valid, we need to save it */
+	pgraph->unload_context(dev);
+
+	/* Load context for next channel */
+	chid = dev_priv->engine.fifo.channel_id(dev);
+	chan = dev_priv->fifos[chid];
+	if (chan)
+		nv04_graph_load_context(chan);
+
+	pgraph->fifo_access(dev, true);
+}
+
+int nv04_graph_create_context(struct nouveau_channel *chan)
+{
+	struct graph_state *pgraph_ctx;
+	NV_DEBUG(chan->dev, "nv04_graph_context_create %d\n", chan->id);
+
+	chan->pgraph_ctx = pgraph_ctx = kzalloc(sizeof(*pgraph_ctx),
+						GFP_KERNEL);
+	if (pgraph_ctx == NULL)
+		return -ENOMEM;
+
+	/* dev_priv->fifos[channel].pgraph_ctx_user = channel << 24; */
+	pgraph_ctx->nv04[0] = 0x0001ffff;
+	/* is it really needed ??? */
+#if 0
+	dev_priv->fifos[channel].pgraph_ctx[1] =
+					nv_rd32(dev, NV_PGRAPH_DEBUG_4);
+	dev_priv->fifos[channel].pgraph_ctx[2] =
+					nv_rd32(dev, 0x004006b0);
+#endif
+	return 0;
+}
+
+void nv04_graph_destroy_context(struct nouveau_channel *chan)
+{
+	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
+
+	kfree(pgraph_ctx);
+	chan->pgraph_ctx = NULL;
+}
+
+int nv04_graph_load_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
+	uint32_t tmp;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++)
+		nv_wr32(dev, nv04_graph_ctx_regs[i], pgraph_ctx->nv04[i]);
+
+	nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL, 0x10010100);
+	nv_wr32(dev, NV04_PGRAPH_CTX_USER, chan->id << 24);
+	tmp = nv_rd32(dev, NV04_PGRAPH_FFINTFC_ST2);
+	nv_wr32(dev, NV04_PGRAPH_FFINTFC_ST2, tmp & 0x000fffff);
+	return 0;
+}
+
+int
+nv04_graph_unload_context(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	struct nouveau_channel *chan = NULL;
+	struct graph_state *ctx;
+	uint32_t tmp;
+	int i;
+
+	chan = pgraph->channel(dev);
+	if (!chan)
+		return 0;
+	ctx = chan->pgraph_ctx;
+
+	for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++)
+		ctx->nv04[i] = nv_rd32(dev, nv04_graph_ctx_regs[i]);
+
+	nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL, 0x10000000);
+	tmp  = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff;
+	tmp |= (dev_priv->engine.fifo.channels - 1) << 24;
+	nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp);
+	return 0;
+}
+
+int nv04_graph_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t tmp;
+
+	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
+			~NV_PMC_ENABLE_PGRAPH);
+	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
+			 NV_PMC_ENABLE_PGRAPH);
+
+	/* Enable PGRAPH interrupts */
+	nv_wr32(dev, NV03_PGRAPH_INTR, 0xFFFFFFFF);
+	nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
+
+	nv_wr32(dev, NV04_PGRAPH_VALID1, 0);
+	nv_wr32(dev, NV04_PGRAPH_VALID2, 0);
+	/*nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x000001FF);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x001FFFFF);*/
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x1231c000);
+	/*1231C000 blob, 001 haiku*/
+	//*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x72111100);
+	/*0x72111100 blob , 01 haiku*/
+	/*nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x11d5f870);*/
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x11d5f071);
+	/*haiku same*/
+
+	/*nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xfad4ff31);*/
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xf0d4ff31);
+	/*haiku and blob 10d4*/
+
+	nv_wr32(dev, NV04_PGRAPH_STATE        , 0xFFFFFFFF);
+	nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL  , 0x10000100);
+	tmp  = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff;
+	tmp |= dev_priv->engine.fifo.channels << 24;
+	nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp);
+
+	/* These don't belong here, they're part of a per-channel context */
+	nv_wr32(dev, NV04_PGRAPH_PATTERN_SHAPE, 0x00000000);
+	nv_wr32(dev, NV04_PGRAPH_BETA_AND     , 0xFFFFFFFF);
+
+	return 0;
+}
+
+void nv04_graph_takedown(struct drm_device *dev)
+{
+}
+
+void
+nv04_graph_fifo_access(struct drm_device *dev, bool enabled)
+{
+	if (enabled)
+		nv_wr32(dev, NV04_PGRAPH_FIFO,
+					nv_rd32(dev, NV04_PGRAPH_FIFO) | 1);
+	else
+		nv_wr32(dev, NV04_PGRAPH_FIFO,
+					nv_rd32(dev, NV04_PGRAPH_FIFO) & ~1);
+}
+
+static int
+nv04_graph_mthd_set_ref(struct nouveau_channel *chan, int grclass,
+			int mthd, uint32_t data)
+{
+	chan->fence.last_sequence_irq = data;
+	nouveau_fence_handler(chan->dev, chan->id);
+	return 0;
+}
+
+static int
+nv04_graph_mthd_set_operation(struct nouveau_channel *chan, int grclass,
+			      int mthd, uint32_t data)
+{
+	struct drm_device *dev = chan->dev;
+	uint32_t instance = nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff;
+	int subc = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7;
+	uint32_t tmp;
+
+	tmp  = nv_ri32(dev, instance);
+	tmp &= ~0x00038000;
+	tmp |= ((data & 7) << 15);
+
+	nv_wi32(dev, instance, tmp);
+	nv_wr32(dev, NV04_PGRAPH_CTX_SWITCH1, tmp);
+	nv_wr32(dev, NV04_PGRAPH_CTX_CACHE1 + subc, tmp);
+	return 0;
+}
+
+static struct nouveau_pgraph_object_method nv04_graph_mthds_m2mf[] = {
+	{ 0x0150, nv04_graph_mthd_set_ref },
+	{}
+};
+
+static struct nouveau_pgraph_object_method nv04_graph_mthds_set_operation[] = {
+	{ 0x02fc, nv04_graph_mthd_set_operation },
+	{},
+};
+
+struct nouveau_pgraph_object_class nv04_graph_grclass[] = {
+	{ 0x0039, false, nv04_graph_mthds_m2mf },
+	{ 0x004a, false, nv04_graph_mthds_set_operation }, /* gdirect */
+	{ 0x005f, false, nv04_graph_mthds_set_operation }, /* imageblit */
+	{ 0x0061, false, nv04_graph_mthds_set_operation }, /* ifc */
+	{ 0x0077, false, nv04_graph_mthds_set_operation }, /* sifm */
+	{ 0x0030, false, NULL }, /* null */
+	{ 0x0042, false, NULL }, /* surf2d */
+	{ 0x0043, false, NULL }, /* rop */
+	{ 0x0012, false, NULL }, /* beta1 */
+	{ 0x0072, false, NULL }, /* beta4 */
+	{ 0x0019, false, NULL }, /* cliprect */
+	{ 0x0044, false, NULL }, /* pattern */
+	{ 0x0052, false, NULL }, /* swzsurf */
+	{ 0x0053, false, NULL }, /* surf3d */
+	{ 0x0054, false, NULL }, /* tex_tri */
+	{ 0x0055, false, NULL }, /* multitex_tri */
+	{}
+};
+
diff --git a/drivers/gpu/drm/nouveau/nv04_instmem.c b/drivers/gpu/drm/nouveau/nv04_instmem.c
new file mode 100644
index 0000000..a20c206
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv04_instmem.c
@@ -0,0 +1,208 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+
+/* returns the size of fifo context */
+static int
+nouveau_fifo_ctx_size(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->chipset >= 0x40)
+		return 128;
+	else
+	if (dev_priv->chipset >= 0x17)
+		return 64;
+
+	return 32;
+}
+
+static void
+nv04_instmem_determine_amount(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int i;
+
+	/* Figure out how much instance memory we need */
+	if (dev_priv->card_type >= NV_40) {
+		/* We'll want more instance memory than this on some NV4x cards.
+		 * There's a 16MB aperture to play with that maps onto the end
+		 * of vram.  For now, only reserve a small piece until we know
+		 * more about what each chipset requires.
+		 */
+		switch (dev_priv->chipset & 0xf0) {
+		case 0x40:
+		case 0x47:
+		case 0x49:
+		case 0x4b:
+			dev_priv->ramin_rsvd_vram = (2 * 1024 * 1024);
+			break;
+		default:
+			dev_priv->ramin_rsvd_vram = (1 * 1024 * 1024);
+			break;
+		}
+	} else {
+		/*XXX: what *are* the limits on <NV40 cards?
+		 */
+		dev_priv->ramin_rsvd_vram = (512 * 1024);
+	}
+	NV_DEBUG(dev, "RAMIN size: %dKiB\n", dev_priv->ramin_rsvd_vram >> 10);
+
+	/* Clear all of it, except the BIOS image that's in the first 64KiB */
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	for (i = 64 * 1024; i < dev_priv->ramin_rsvd_vram; i += 4)
+		nv_wi32(dev, i, 0x00000000);
+	dev_priv->engine.instmem.finish_access(dev);
+}
+
+static void
+nv04_instmem_configure_fixed_tables(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
+
+	/* FIFO hash table (RAMHT)
+	 *   use 4k hash table at RAMIN+0x10000
+	 *   TODO: extend the hash table
+	 */
+	dev_priv->ramht_offset = 0x10000;
+	dev_priv->ramht_bits   = 9;
+	dev_priv->ramht_size   = (1 << dev_priv->ramht_bits); /* nr entries */
+	dev_priv->ramht_size  *= 8; /* 2 32-bit values per entry in RAMHT */
+	NV_DEBUG(dev, "RAMHT offset=0x%x, size=%d\n", dev_priv->ramht_offset,
+						      dev_priv->ramht_size);
+
+	/* FIFO runout table (RAMRO) - 512k at 0x11200 */
+	dev_priv->ramro_offset = 0x11200;
+	dev_priv->ramro_size   = 512;
+	NV_DEBUG(dev, "RAMRO offset=0x%x, size=%d\n", dev_priv->ramro_offset,
+						      dev_priv->ramro_size);
+
+	/* FIFO context table (RAMFC)
+	 *   NV40  : Not sure exactly how to position RAMFC on some cards,
+	 *           0x30002 seems to position it at RAMIN+0x20000 on these
+	 *           cards.  RAMFC is 4kb (32 fifos, 128byte entries).
+	 *   Others: Position RAMFC at RAMIN+0x11400
+	 */
+	dev_priv->ramfc_size = engine->fifo.channels *
+						nouveau_fifo_ctx_size(dev);
+	switch (dev_priv->card_type) {
+	case NV_40:
+		dev_priv->ramfc_offset = 0x20000;
+		break;
+	case NV_30:
+	case NV_20:
+	case NV_10:
+	case NV_04:
+	default:
+		dev_priv->ramfc_offset = 0x11400;
+		break;
+	}
+	NV_DEBUG(dev, "RAMFC offset=0x%x, size=%d\n", dev_priv->ramfc_offset,
+						      dev_priv->ramfc_size);
+}
+
+int nv04_instmem_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t offset;
+	int ret = 0;
+
+	nv04_instmem_determine_amount(dev);
+	nv04_instmem_configure_fixed_tables(dev);
+
+	/* Create a heap to manage RAMIN allocations, we don't allocate
+	 * the space that was reserved for RAMHT/FC/RO.
+	 */
+	offset = dev_priv->ramfc_offset + dev_priv->ramfc_size;
+
+	/* It appears RAMRO (or something?) is controlled by 0x2220/0x2230
+	 * on certain NV4x chipsets as well as RAMFC.  When 0x2230 == 0
+	 * ("new style" control) the upper 16-bits of 0x2220 points at this
+	 * other mysterious table that's clobbering important things.
+	 *
+	 * We're now pointing this at RAMIN+0x30000 to avoid RAMFC getting
+	 * smashed to pieces on us, so reserve 0x30000-0x40000 too..
+	 */
+	if (dev_priv->card_type >= NV_40) {
+		if (offset < 0x40000)
+			offset = 0x40000;
+	}
+
+	ret = nouveau_mem_init_heap(&dev_priv->ramin_heap,
+				    offset, dev_priv->ramin_rsvd_vram - offset);
+	if (ret) {
+		dev_priv->ramin_heap = NULL;
+		NV_ERROR(dev, "Failed to init RAMIN heap\n");
+	}
+
+	return ret;
+}
+
+void
+nv04_instmem_takedown(struct drm_device *dev)
+{
+}
+
+int
+nv04_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, uint32_t *sz)
+{
+	if (gpuobj->im_backing)
+		return -EINVAL;
+
+	return 0;
+}
+
+void
+nv04_instmem_clear(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (gpuobj && gpuobj->im_backing) {
+		if (gpuobj->im_bound)
+			dev_priv->engine.instmem.unbind(dev, gpuobj);
+		gpuobj->im_backing = NULL;
+	}
+}
+
+int
+nv04_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
+{
+	if (!gpuobj->im_pramin || gpuobj->im_bound)
+		return -EINVAL;
+
+	gpuobj->im_bound = 1;
+	return 0;
+}
+
+int
+nv04_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
+{
+	if (gpuobj->im_bound == 0)
+		return -EINVAL;
+
+	gpuobj->im_bound = 0;
+	return 0;
+}
+
+void
+nv04_instmem_prepare_access(struct drm_device *dev, bool write)
+{
+}
+
+void
+nv04_instmem_finish_access(struct drm_device *dev)
+{
+}
+
+int
+nv04_instmem_suspend(struct drm_device *dev)
+{
+	return 0;
+}
+
+void
+nv04_instmem_resume(struct drm_device *dev)
+{
+}
+
diff --git a/drivers/gpu/drm/nouveau/nv04_mc.c b/drivers/gpu/drm/nouveau/nv04_mc.c
new file mode 100644
index 0000000..617ed1e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv04_mc.c
@@ -0,0 +1,20 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+int
+nv04_mc_init(struct drm_device *dev)
+{
+	/* Power up everything, resetting each individual unit will
+	 * be done later if needed.
+	 */
+
+	nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF);
+	return 0;
+}
+
+void
+nv04_mc_takedown(struct drm_device *dev)
+{
+}
diff --git a/drivers/gpu/drm/nouveau/nv04_timer.c b/drivers/gpu/drm/nouveau/nv04_timer.c
new file mode 100644
index 0000000..1d09ddd
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv04_timer.c
@@ -0,0 +1,51 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+int
+nv04_timer_init(struct drm_device *dev)
+{
+	nv_wr32(dev, NV04_PTIMER_INTR_EN_0, 0x00000000);
+	nv_wr32(dev, NV04_PTIMER_INTR_0, 0xFFFFFFFF);
+
+	/* Just use the pre-existing values when possible for now; these regs
+	 * are not written in nv (driver writer missed a /4 on the address), and
+	 * writing 8 and 3 to the correct regs breaks the timings on the LVDS
+	 * hardware sequencing microcode.
+	 * A correct solution (involving calculations with the GPU PLL) can
+	 * be done when kernel modesetting lands
+	 */
+	if (!nv_rd32(dev, NV04_PTIMER_NUMERATOR) ||
+				!nv_rd32(dev, NV04_PTIMER_DENOMINATOR)) {
+		nv_wr32(dev, NV04_PTIMER_NUMERATOR, 0x00000008);
+		nv_wr32(dev, NV04_PTIMER_DENOMINATOR, 0x00000003);
+	}
+
+	return 0;
+}
+
+uint64_t
+nv04_timer_read(struct drm_device *dev)
+{
+	uint32_t low;
+	/* From kmmio dumps on nv28 this looks like how the blob does this.
+	 * It reads the high dword twice, before and after.
+	 * The only explanation seems to be that the 64-bit timer counter
+	 * advances between high and low dword reads and may corrupt the
+	 * result. Not confirmed.
+	 */
+	uint32_t high2 = nv_rd32(dev, NV04_PTIMER_TIME_1);
+	uint32_t high1;
+	do {
+		high1 = high2;
+		low = nv_rd32(dev, NV04_PTIMER_TIME_0);
+		high2 = nv_rd32(dev, NV04_PTIMER_TIME_1);
+	} while (high1 != high2);
+	return (((uint64_t)high2) << 32) | (uint64_t)low;
+}
+
+void
+nv04_timer_takedown(struct drm_device *dev)
+{
+}
diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c b/drivers/gpu/drm/nouveau/nv04_tv.c
new file mode 100644
index 0000000..9c63099
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv04_tv.c
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2009 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_encoder.h"
+#include "nouveau_connector.h"
+#include "nouveau_crtc.h"
+#include "nouveau_hw.h"
+#include "drm_crtc_helper.h"
+
+#include "i2c/ch7006.h"
+
+static struct {
+	struct i2c_board_info board_info;
+	struct drm_encoder_funcs funcs;
+	struct drm_encoder_helper_funcs hfuncs;
+	void *params;
+
+} nv04_tv_encoder_info[] = {
+	{
+		.board_info = { I2C_BOARD_INFO("ch7006", 0x75) },
+		.params = &(struct ch7006_encoder_params) {
+			CH7006_FORMAT_RGB24m12I, CH7006_CLOCK_MASTER,
+			0, 0, 0,
+			CH7006_SYNC_SLAVE, CH7006_SYNC_SEPARATED,
+			CH7006_POUT_3_3V, CH7006_ACTIVE_HSYNC
+		},
+	},
+};
+
+static bool probe_i2c_addr(struct i2c_adapter *adapter, int addr)
+{
+	struct i2c_msg msg = {
+		.addr = addr,
+		.len = 0,
+	};
+
+	return i2c_transfer(adapter, &msg, 1) == 1;
+}
+
+int nv04_tv_identify(struct drm_device *dev, int i2c_index)
+{
+	struct nouveau_i2c_chan *i2c;
+	bool was_locked;
+	int i, ret;
+
+	NV_TRACE(dev, "Probing TV encoders on I2C bus: %d\n", i2c_index);
+
+	i2c = nouveau_i2c_find(dev, i2c_index);
+	if (!i2c)
+		return -ENODEV;
+
+	was_locked = NVLockVgaCrtcs(dev, false);
+
+	for (i = 0; i < ARRAY_SIZE(nv04_tv_encoder_info); i++) {
+		if (probe_i2c_addr(&i2c->adapter,
+				   nv04_tv_encoder_info[i].board_info.addr)) {
+			ret = i;
+			break;
+		}
+	}
+
+	if (i < ARRAY_SIZE(nv04_tv_encoder_info)) {
+		NV_TRACE(dev, "Detected TV encoder: %s\n",
+			 nv04_tv_encoder_info[i].board_info.type);
+
+	} else {
+		NV_TRACE(dev, "No TV encoders found.\n");
+		i = -ENODEV;
+	}
+
+	NVLockVgaCrtcs(dev, was_locked);
+	return i;
+}
+
+#define PLLSEL_TV_CRTC1_MASK				\
+	(NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK1		\
+	 | NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK1)
+#define PLLSEL_TV_CRTC2_MASK				\
+	(NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK2		\
+	 | NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK2)
+
+static void nv04_tv_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv04_mode_state *state = &dev_priv->mode_reg;
+	uint8_t crtc1A;
+
+	NV_INFO(dev, "Setting dpms mode %d on TV encoder (output %d)\n",
+		mode, nv_encoder->dcb->index);
+
+	state->pllsel &= ~(PLLSEL_TV_CRTC1_MASK | PLLSEL_TV_CRTC2_MASK);
+
+	if (mode == DRM_MODE_DPMS_ON) {
+		int head = nouveau_crtc(encoder->crtc)->index;
+		crtc1A = NVReadVgaCrtc(dev, head, NV_CIO_CRE_RPC1_INDEX);
+
+		state->pllsel |= head ? PLLSEL_TV_CRTC2_MASK :
+					PLLSEL_TV_CRTC1_MASK;
+
+		/* Inhibit hsync */
+		crtc1A |= 0x80;
+
+		NVWriteVgaCrtc(dev, head, NV_CIO_CRE_RPC1_INDEX, crtc1A);
+	}
+
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT, state->pllsel);
+
+	to_encoder_slave(encoder)->slave_funcs->dpms(encoder, mode);
+}
+
+static void nv04_tv_bind(struct drm_device *dev, int head, bool bind)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv04_crtc_reg *state = &dev_priv->mode_reg.crtc_reg[head];
+
+	state->tv_setup = 0;
+
+	if (bind) {
+		state->CRTC[NV_CIO_CRE_LCD__INDEX] = 0;
+		state->CRTC[NV_CIO_CRE_49] |= 0x10;
+	} else {
+		state->CRTC[NV_CIO_CRE_49] &= ~0x10;
+	}
+
+	NVWriteVgaCrtc(dev, head, NV_CIO_CRE_LCD__INDEX,
+		       state->CRTC[NV_CIO_CRE_LCD__INDEX]);
+	NVWriteVgaCrtc(dev, head, NV_CIO_CRE_49,
+		       state->CRTC[NV_CIO_CRE_49]);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_SETUP,
+		      state->tv_setup);
+}
+
+static void nv04_tv_prepare(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	int head = nouveau_crtc(encoder->crtc)->index;
+	struct drm_encoder_helper_funcs *helper = encoder->helper_private;
+
+	helper->dpms(encoder, DRM_MODE_DPMS_OFF);
+
+	nv04_dfp_disable(dev, head);
+
+	if (nv_two_heads(dev))
+		nv04_tv_bind(dev, head ^ 1, false);
+
+	nv04_tv_bind(dev, head, true);
+}
+
+static void nv04_tv_mode_set(struct drm_encoder *encoder,
+			     struct drm_display_mode *mode,
+			     struct drm_display_mode *adjusted_mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
+	struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
+
+	regp->tv_htotal = adjusted_mode->htotal;
+	regp->tv_vtotal = adjusted_mode->vtotal;
+
+	/* These delay the TV signals with respect to the VGA port,
+	 * they might be useful if we ever allow a CRTC to drive
+	 * multiple outputs.
+	 */
+	regp->tv_hskew = 1;
+	regp->tv_hsync_delay = 1;
+	regp->tv_hsync_delay2 = 64;
+	regp->tv_vskew = 1;
+	regp->tv_vsync_delay = 1;
+
+	to_encoder_slave(encoder)->slave_funcs->mode_set(encoder, mode, adjusted_mode);
+}
+
+static void nv04_tv_commit(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
+	struct drm_encoder_helper_funcs *helper = encoder->helper_private;
+
+	helper->dpms(encoder, DRM_MODE_DPMS_ON);
+
+	NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n",
+		      drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index,
+		      '@' + ffs(nv_encoder->dcb->or));
+}
+
+static void nv04_tv_destroy(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+	to_encoder_slave(encoder)->slave_funcs->destroy(encoder);
+
+	drm_encoder_cleanup(encoder);
+
+	kfree(nv_encoder);
+}
+
+int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry)
+{
+	struct nouveau_encoder *nv_encoder;
+	struct drm_encoder *encoder;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct i2c_adapter *adap;
+	struct drm_encoder_funcs *funcs = NULL;
+	struct drm_encoder_helper_funcs *hfuncs = NULL;
+	struct drm_encoder_slave_funcs *sfuncs = NULL;
+	int i2c_index = entry->i2c_index;
+	int type, ret;
+	bool was_locked;
+
+	/* Ensure that we can talk to this encoder */
+	type = nv04_tv_identify(dev, i2c_index);
+	if (type < 0)
+		return type;
+
+	/* Allocate the necessary memory */
+	nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
+	if (!nv_encoder)
+		return -ENOMEM;
+
+	/* Initialize the common members */
+	encoder = to_drm_encoder(nv_encoder);
+
+	funcs = &nv04_tv_encoder_info[type].funcs;
+	hfuncs = &nv04_tv_encoder_info[type].hfuncs;
+
+	drm_encoder_init(dev, encoder, funcs, DRM_MODE_ENCODER_TVDAC);
+	drm_encoder_helper_add(encoder, hfuncs);
+
+	encoder->possible_crtcs = entry->heads;
+	encoder->possible_clones = 0;
+
+	nv_encoder->dcb = entry;
+	nv_encoder->or = ffs(entry->or) - 1;
+
+	/* Run the slave-specific initialization */
+	adap = &dev_priv->vbios->dcb->i2c[i2c_index].chan->adapter;
+
+	was_locked = NVLockVgaCrtcs(dev, false);
+
+	ret = drm_i2c_encoder_init(encoder->dev, to_encoder_slave(encoder), adap,
+				   &nv04_tv_encoder_info[type].board_info);
+
+	NVLockVgaCrtcs(dev, was_locked);
+
+	if (ret < 0)
+		goto fail;
+
+	/* Fill the function pointers */
+	sfuncs = to_encoder_slave(encoder)->slave_funcs;
+
+	*funcs = (struct drm_encoder_funcs) {
+		.destroy = nv04_tv_destroy,
+	};
+
+	*hfuncs = (struct drm_encoder_helper_funcs) {
+		.dpms = nv04_tv_dpms,
+		.save = sfuncs->save,
+		.restore = sfuncs->restore,
+		.mode_fixup = sfuncs->mode_fixup,
+		.prepare = nv04_tv_prepare,
+		.commit = nv04_tv_commit,
+		.mode_set = nv04_tv_mode_set,
+		.detect = sfuncs->detect,
+	};
+
+	/* Set the slave encoder configuration */
+	sfuncs->set_config(encoder, nv04_tv_encoder_info[type].params);
+
+	return 0;
+
+fail:
+	drm_encoder_cleanup(encoder);
+
+	kfree(nv_encoder);
+	return ret;
+}
diff --git a/drivers/gpu/drm/nouveau/nv10_fb.c b/drivers/gpu/drm/nouveau/nv10_fb.c
new file mode 100644
index 0000000..79e2d10
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv10_fb.c
@@ -0,0 +1,24 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+int
+nv10_fb_init(struct drm_device *dev)
+{
+	uint32_t fb_bar_size;
+	int i;
+
+	fb_bar_size = drm_get_resource_len(dev, 0) - 1;
+	for (i = 0; i < NV10_PFB_TILE__SIZE; i++) {
+		nv_wr32(dev, NV10_PFB_TILE(i), 0);
+		nv_wr32(dev, NV10_PFB_TLIMIT(i), fb_bar_size);
+	}
+
+	return 0;
+}
+
+void
+nv10_fb_takedown(struct drm_device *dev)
+{
+}
diff --git a/drivers/gpu/drm/nouveau/nv10_fifo.c b/drivers/gpu/drm/nouveau/nv10_fifo.c
new file mode 100644
index 0000000..7aeabf2
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv10_fifo.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+
+#define NV10_RAMFC(c) (dev_priv->ramfc_offset + ((c) * NV10_RAMFC__SIZE))
+#define NV10_RAMFC__SIZE ((dev_priv->chipset) >= 0x17 ? 64 : 32)
+
+int
+nv10_fifo_channel_id(struct drm_device *dev)
+{
+	return nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) &
+			NV10_PFIFO_CACHE1_PUSH1_CHID_MASK;
+}
+
+int
+nv10_fifo_create_context(struct nouveau_channel *chan)
+{
+	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
+	struct drm_device *dev = chan->dev;
+	uint32_t fc = NV10_RAMFC(chan->id);
+	int ret;
+
+	ret = nouveau_gpuobj_new_fake(dev, NV10_RAMFC(chan->id), ~0,
+				      NV10_RAMFC__SIZE, NVOBJ_FLAG_ZERO_ALLOC |
+				      NVOBJ_FLAG_ZERO_FREE, NULL, &chan->ramfc);
+	if (ret)
+		return ret;
+
+	/* Fill entries that are seen filled in dumps of nvidia driver just
+	 * after channel's is put into DMA mode
+	 */
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	nv_wi32(dev, fc +  0, chan->pushbuf_base);
+	nv_wi32(dev, fc +  4, chan->pushbuf_base);
+	nv_wi32(dev, fc + 12, chan->pushbuf->instance >> 4);
+	nv_wi32(dev, fc + 20, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
+			      NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
+			      NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 |
+#ifdef __BIG_ENDIAN
+			      NV_PFIFO_CACHE1_BIG_ENDIAN |
+#endif
+			      0);
+	dev_priv->engine.instmem.finish_access(dev);
+
+	/* enable the fifo dma operation */
+	nv_wr32(dev, NV04_PFIFO_MODE,
+		nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id));
+	return 0;
+}
+
+void
+nv10_fifo_destroy_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+
+	nv_wr32(dev, NV04_PFIFO_MODE,
+			nv_rd32(dev, NV04_PFIFO_MODE) & ~(1 << chan->id));
+
+	nouveau_gpuobj_ref_del(dev, &chan->ramfc);
+}
+
+static void
+nv10_fifo_do_load_context(struct drm_device *dev, int chid)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t fc = NV10_RAMFC(chid), tmp;
+
+	dev_priv->engine.instmem.prepare_access(dev, false);
+
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4));
+	nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8));
+
+	tmp = nv_ri32(dev, fc + 12);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE, tmp & 0xFFFF);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT, tmp >> 16);
+
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_STATE, nv_ri32(dev, fc + 16));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_FETCH, nv_ri32(dev, fc + 20));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_ri32(dev, fc + 24));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_PULL1, nv_ri32(dev, fc + 28));
+
+	if (dev_priv->chipset < 0x17)
+		goto out;
+
+	nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_VALUE, nv_ri32(dev, fc + 32));
+	tmp = nv_ri32(dev, fc + 36);
+	nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP, tmp);
+	nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT, nv_ri32(dev, fc + 40));
+	nv_wr32(dev, NV10_PFIFO_CACHE1_SEMAPHORE, nv_ri32(dev, fc + 44));
+	nv_wr32(dev, NV10_PFIFO_CACHE1_DMA_SUBROUTINE, nv_ri32(dev, fc + 48));
+
+out:
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0);
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0);
+}
+
+int
+nv10_fifo_load_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	uint32_t tmp;
+
+	nv10_fifo_do_load_context(dev, chan->id);
+
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1,
+		     NV03_PFIFO_CACHE1_PUSH1_DMA | chan->id);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, 1);
+
+	/* Reset NV04_PFIFO_CACHE1_DMA_CTL_AT_INFO to INVALID */
+	tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_CTL) & ~(1 << 31);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_CTL, tmp);
+
+	return 0;
+}
+
+int
+nv10_fifo_unload_context(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	uint32_t fc, tmp;
+	int chid;
+
+	chid = pfifo->channel_id(dev);
+	if (chid < 0 || chid >= dev_priv->engine.fifo.channels)
+		return 0;
+	fc = NV10_RAMFC(chid);
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+
+	nv_wi32(dev, fc +  0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT));
+	nv_wi32(dev, fc +  4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET));
+	nv_wi32(dev, fc +  8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT));
+	tmp  = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE) & 0xFFFF;
+	tmp |= (nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT) << 16);
+	nv_wi32(dev, fc + 12, tmp);
+	nv_wi32(dev, fc + 16, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_STATE));
+	nv_wi32(dev, fc + 20, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_FETCH));
+	nv_wi32(dev, fc + 24, nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE));
+	nv_wi32(dev, fc + 28, nv_rd32(dev, NV04_PFIFO_CACHE1_PULL1));
+
+	if (dev_priv->chipset < 0x17)
+		goto out;
+
+	nv_wi32(dev, fc + 32, nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_VALUE));
+	tmp = nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP);
+	nv_wi32(dev, fc + 36, tmp);
+	nv_wi32(dev, fc + 40, nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT));
+	nv_wi32(dev, fc + 44, nv_rd32(dev, NV10_PFIFO_CACHE1_SEMAPHORE));
+	nv_wi32(dev, fc + 48, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET));
+
+out:
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nv10_fifo_do_load_context(dev, pfifo->channels - 1);
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1);
+	return 0;
+}
+
+static void
+nv10_fifo_init_reset(struct drm_device *dev)
+{
+	nv_wr32(dev, NV03_PMC_ENABLE,
+		nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PFIFO);
+	nv_wr32(dev, NV03_PMC_ENABLE,
+		nv_rd32(dev, NV03_PMC_ENABLE) |  NV_PMC_ENABLE_PFIFO);
+
+	nv_wr32(dev, 0x003224, 0x000f0078);
+	nv_wr32(dev, 0x002044, 0x0101ffff);
+	nv_wr32(dev, 0x002040, 0x000000ff);
+	nv_wr32(dev, 0x002500, 0x00000000);
+	nv_wr32(dev, 0x003000, 0x00000000);
+	nv_wr32(dev, 0x003050, 0x00000000);
+
+	nv_wr32(dev, 0x003258, 0x00000000);
+	nv_wr32(dev, 0x003210, 0x00000000);
+	nv_wr32(dev, 0x003270, 0x00000000);
+}
+
+static void
+nv10_fifo_init_ramxx(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ |
+				       ((dev_priv->ramht_bits - 9) << 16) |
+				       (dev_priv->ramht_offset >> 8));
+	nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro_offset>>8);
+
+	if (dev_priv->chipset < 0x17) {
+		nv_wr32(dev, NV03_PFIFO_RAMFC, dev_priv->ramfc_offset >> 8);
+	} else {
+		nv_wr32(dev, NV03_PFIFO_RAMFC, (dev_priv->ramfc_offset >> 8) |
+					       (1 << 16) /* 64 Bytes entry*/);
+		/* XXX nvidia blob set bit 18, 21,23 for nv20 & nv30 */
+	}
+}
+
+static void
+nv10_fifo_init_intr(struct drm_device *dev)
+{
+	nv_wr32(dev, 0x002100, 0xffffffff);
+	nv_wr32(dev, 0x002140, 0xffffffff);
+}
+
+int
+nv10_fifo_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	int i;
+
+	nv10_fifo_init_reset(dev);
+	nv10_fifo_init_ramxx(dev);
+
+	nv10_fifo_do_load_context(dev, pfifo->channels - 1);
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1);
+
+	nv10_fifo_init_intr(dev);
+	pfifo->enable(dev);
+	pfifo->reassign(dev, true);
+
+	for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
+		if (dev_priv->fifos[i]) {
+			uint32_t mode = nv_rd32(dev, NV04_PFIFO_MODE);
+			nv_wr32(dev, NV04_PFIFO_MODE, mode | (1 << i));
+		}
+	}
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c
new file mode 100644
index 0000000..6bf6804
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv10_graph.c
@@ -0,0 +1,892 @@
+/*
+ * Copyright 2007 Matthieu CASTET <castet.matthieu@free.fr>
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drm.h"
+#include "nouveau_drv.h"
+
+#define NV10_FIFO_NUMBER 32
+
+struct pipe_state {
+	uint32_t pipe_0x0000[0x040/4];
+	uint32_t pipe_0x0040[0x010/4];
+	uint32_t pipe_0x0200[0x0c0/4];
+	uint32_t pipe_0x4400[0x080/4];
+	uint32_t pipe_0x6400[0x3b0/4];
+	uint32_t pipe_0x6800[0x2f0/4];
+	uint32_t pipe_0x6c00[0x030/4];
+	uint32_t pipe_0x7000[0x130/4];
+	uint32_t pipe_0x7400[0x0c0/4];
+	uint32_t pipe_0x7800[0x0c0/4];
+};
+
+static int nv10_graph_ctx_regs[] = {
+	NV10_PGRAPH_CTX_SWITCH1,
+	NV10_PGRAPH_CTX_SWITCH2,
+	NV10_PGRAPH_CTX_SWITCH3,
+	NV10_PGRAPH_CTX_SWITCH4,
+	NV10_PGRAPH_CTX_SWITCH5,
+	NV10_PGRAPH_CTX_CACHE1,	/* 8 values from 0x400160 to 0x40017c */
+	NV10_PGRAPH_CTX_CACHE2,	/* 8 values from 0x400180 to 0x40019c */
+	NV10_PGRAPH_CTX_CACHE3,	/* 8 values from 0x4001a0 to 0x4001bc */
+	NV10_PGRAPH_CTX_CACHE4,	/* 8 values from 0x4001c0 to 0x4001dc */
+	NV10_PGRAPH_CTX_CACHE5,	/* 8 values from 0x4001e0 to 0x4001fc */
+	0x00400164,
+	0x00400184,
+	0x004001a4,
+	0x004001c4,
+	0x004001e4,
+	0x00400168,
+	0x00400188,
+	0x004001a8,
+	0x004001c8,
+	0x004001e8,
+	0x0040016c,
+	0x0040018c,
+	0x004001ac,
+	0x004001cc,
+	0x004001ec,
+	0x00400170,
+	0x00400190,
+	0x004001b0,
+	0x004001d0,
+	0x004001f0,
+	0x00400174,
+	0x00400194,
+	0x004001b4,
+	0x004001d4,
+	0x004001f4,
+	0x00400178,
+	0x00400198,
+	0x004001b8,
+	0x004001d8,
+	0x004001f8,
+	0x0040017c,
+	0x0040019c,
+	0x004001bc,
+	0x004001dc,
+	0x004001fc,
+	NV10_PGRAPH_CTX_USER,
+	NV04_PGRAPH_DMA_START_0,
+	NV04_PGRAPH_DMA_START_1,
+	NV04_PGRAPH_DMA_LENGTH,
+	NV04_PGRAPH_DMA_MISC,
+	NV10_PGRAPH_DMA_PITCH,
+	NV04_PGRAPH_BOFFSET0,
+	NV04_PGRAPH_BBASE0,
+	NV04_PGRAPH_BLIMIT0,
+	NV04_PGRAPH_BOFFSET1,
+	NV04_PGRAPH_BBASE1,
+	NV04_PGRAPH_BLIMIT1,
+	NV04_PGRAPH_BOFFSET2,
+	NV04_PGRAPH_BBASE2,
+	NV04_PGRAPH_BLIMIT2,
+	NV04_PGRAPH_BOFFSET3,
+	NV04_PGRAPH_BBASE3,
+	NV04_PGRAPH_BLIMIT3,
+	NV04_PGRAPH_BOFFSET4,
+	NV04_PGRAPH_BBASE4,
+	NV04_PGRAPH_BLIMIT4,
+	NV04_PGRAPH_BOFFSET5,
+	NV04_PGRAPH_BBASE5,
+	NV04_PGRAPH_BLIMIT5,
+	NV04_PGRAPH_BPITCH0,
+	NV04_PGRAPH_BPITCH1,
+	NV04_PGRAPH_BPITCH2,
+	NV04_PGRAPH_BPITCH3,
+	NV04_PGRAPH_BPITCH4,
+	NV10_PGRAPH_SURFACE,
+	NV10_PGRAPH_STATE,
+	NV04_PGRAPH_BSWIZZLE2,
+	NV04_PGRAPH_BSWIZZLE5,
+	NV04_PGRAPH_BPIXEL,
+	NV10_PGRAPH_NOTIFY,
+	NV04_PGRAPH_PATT_COLOR0,
+	NV04_PGRAPH_PATT_COLOR1,
+	NV04_PGRAPH_PATT_COLORRAM, /* 64 values from 0x400900 to 0x4009fc */
+	0x00400904,
+	0x00400908,
+	0x0040090c,
+	0x00400910,
+	0x00400914,
+	0x00400918,
+	0x0040091c,
+	0x00400920,
+	0x00400924,
+	0x00400928,
+	0x0040092c,
+	0x00400930,
+	0x00400934,
+	0x00400938,
+	0x0040093c,
+	0x00400940,
+	0x00400944,
+	0x00400948,
+	0x0040094c,
+	0x00400950,
+	0x00400954,
+	0x00400958,
+	0x0040095c,
+	0x00400960,
+	0x00400964,
+	0x00400968,
+	0x0040096c,
+	0x00400970,
+	0x00400974,
+	0x00400978,
+	0x0040097c,
+	0x00400980,
+	0x00400984,
+	0x00400988,
+	0x0040098c,
+	0x00400990,
+	0x00400994,
+	0x00400998,
+	0x0040099c,
+	0x004009a0,
+	0x004009a4,
+	0x004009a8,
+	0x004009ac,
+	0x004009b0,
+	0x004009b4,
+	0x004009b8,
+	0x004009bc,
+	0x004009c0,
+	0x004009c4,
+	0x004009c8,
+	0x004009cc,
+	0x004009d0,
+	0x004009d4,
+	0x004009d8,
+	0x004009dc,
+	0x004009e0,
+	0x004009e4,
+	0x004009e8,
+	0x004009ec,
+	0x004009f0,
+	0x004009f4,
+	0x004009f8,
+	0x004009fc,
+	NV04_PGRAPH_PATTERN,	/* 2 values from 0x400808 to 0x40080c */
+	0x0040080c,
+	NV04_PGRAPH_PATTERN_SHAPE,
+	NV03_PGRAPH_MONO_COLOR0,
+	NV04_PGRAPH_ROP3,
+	NV04_PGRAPH_CHROMA,
+	NV04_PGRAPH_BETA_AND,
+	NV04_PGRAPH_BETA_PREMULT,
+	0x00400e70,
+	0x00400e74,
+	0x00400e78,
+	0x00400e7c,
+	0x00400e80,
+	0x00400e84,
+	0x00400e88,
+	0x00400e8c,
+	0x00400ea0,
+	0x00400ea4,
+	0x00400ea8,
+	0x00400e90,
+	0x00400e94,
+	0x00400e98,
+	0x00400e9c,
+	NV10_PGRAPH_WINDOWCLIP_HORIZONTAL, /* 8 values from 0x400f00-0x400f1c */
+	NV10_PGRAPH_WINDOWCLIP_VERTICAL,   /* 8 values from 0x400f20-0x400f3c */
+	0x00400f04,
+	0x00400f24,
+	0x00400f08,
+	0x00400f28,
+	0x00400f0c,
+	0x00400f2c,
+	0x00400f10,
+	0x00400f30,
+	0x00400f14,
+	0x00400f34,
+	0x00400f18,
+	0x00400f38,
+	0x00400f1c,
+	0x00400f3c,
+	NV10_PGRAPH_XFMODE0,
+	NV10_PGRAPH_XFMODE1,
+	NV10_PGRAPH_GLOBALSTATE0,
+	NV10_PGRAPH_GLOBALSTATE1,
+	NV04_PGRAPH_STORED_FMT,
+	NV04_PGRAPH_SOURCE_COLOR,
+	NV03_PGRAPH_ABS_X_RAM,	/* 32 values from 0x400400 to 0x40047c */
+	NV03_PGRAPH_ABS_Y_RAM,	/* 32 values from 0x400480 to 0x4004fc */
+	0x00400404,
+	0x00400484,
+	0x00400408,
+	0x00400488,
+	0x0040040c,
+	0x0040048c,
+	0x00400410,
+	0x00400490,
+	0x00400414,
+	0x00400494,
+	0x00400418,
+	0x00400498,
+	0x0040041c,
+	0x0040049c,
+	0x00400420,
+	0x004004a0,
+	0x00400424,
+	0x004004a4,
+	0x00400428,
+	0x004004a8,
+	0x0040042c,
+	0x004004ac,
+	0x00400430,
+	0x004004b0,
+	0x00400434,
+	0x004004b4,
+	0x00400438,
+	0x004004b8,
+	0x0040043c,
+	0x004004bc,
+	0x00400440,
+	0x004004c0,
+	0x00400444,
+	0x004004c4,
+	0x00400448,
+	0x004004c8,
+	0x0040044c,
+	0x004004cc,
+	0x00400450,
+	0x004004d0,
+	0x00400454,
+	0x004004d4,
+	0x00400458,
+	0x004004d8,
+	0x0040045c,
+	0x004004dc,
+	0x00400460,
+	0x004004e0,
+	0x00400464,
+	0x004004e4,
+	0x00400468,
+	0x004004e8,
+	0x0040046c,
+	0x004004ec,
+	0x00400470,
+	0x004004f0,
+	0x00400474,
+	0x004004f4,
+	0x00400478,
+	0x004004f8,
+	0x0040047c,
+	0x004004fc,
+	NV03_PGRAPH_ABS_UCLIP_XMIN,
+	NV03_PGRAPH_ABS_UCLIP_XMAX,
+	NV03_PGRAPH_ABS_UCLIP_YMIN,
+	NV03_PGRAPH_ABS_UCLIP_YMAX,
+	0x00400550,
+	0x00400558,
+	0x00400554,
+	0x0040055c,
+	NV03_PGRAPH_ABS_UCLIPA_XMIN,
+	NV03_PGRAPH_ABS_UCLIPA_XMAX,
+	NV03_PGRAPH_ABS_UCLIPA_YMIN,
+	NV03_PGRAPH_ABS_UCLIPA_YMAX,
+	NV03_PGRAPH_ABS_ICLIP_XMAX,
+	NV03_PGRAPH_ABS_ICLIP_YMAX,
+	NV03_PGRAPH_XY_LOGIC_MISC0,
+	NV03_PGRAPH_XY_LOGIC_MISC1,
+	NV03_PGRAPH_XY_LOGIC_MISC2,
+	NV03_PGRAPH_XY_LOGIC_MISC3,
+	NV03_PGRAPH_CLIPX_0,
+	NV03_PGRAPH_CLIPX_1,
+	NV03_PGRAPH_CLIPY_0,
+	NV03_PGRAPH_CLIPY_1,
+	NV10_PGRAPH_COMBINER0_IN_ALPHA,
+	NV10_PGRAPH_COMBINER1_IN_ALPHA,
+	NV10_PGRAPH_COMBINER0_IN_RGB,
+	NV10_PGRAPH_COMBINER1_IN_RGB,
+	NV10_PGRAPH_COMBINER_COLOR0,
+	NV10_PGRAPH_COMBINER_COLOR1,
+	NV10_PGRAPH_COMBINER0_OUT_ALPHA,
+	NV10_PGRAPH_COMBINER1_OUT_ALPHA,
+	NV10_PGRAPH_COMBINER0_OUT_RGB,
+	NV10_PGRAPH_COMBINER1_OUT_RGB,
+	NV10_PGRAPH_COMBINER_FINAL0,
+	NV10_PGRAPH_COMBINER_FINAL1,
+	0x00400e00,
+	0x00400e04,
+	0x00400e08,
+	0x00400e0c,
+	0x00400e10,
+	0x00400e14,
+	0x00400e18,
+	0x00400e1c,
+	0x00400e20,
+	0x00400e24,
+	0x00400e28,
+	0x00400e2c,
+	0x00400e30,
+	0x00400e34,
+	0x00400e38,
+	0x00400e3c,
+	NV04_PGRAPH_PASSTHRU_0,
+	NV04_PGRAPH_PASSTHRU_1,
+	NV04_PGRAPH_PASSTHRU_2,
+	NV10_PGRAPH_DIMX_TEXTURE,
+	NV10_PGRAPH_WDIMX_TEXTURE,
+	NV10_PGRAPH_DVD_COLORFMT,
+	NV10_PGRAPH_SCALED_FORMAT,
+	NV04_PGRAPH_MISC24_0,
+	NV04_PGRAPH_MISC24_1,
+	NV04_PGRAPH_MISC24_2,
+	NV03_PGRAPH_X_MISC,
+	NV03_PGRAPH_Y_MISC,
+	NV04_PGRAPH_VALID1,
+	NV04_PGRAPH_VALID2,
+};
+
+static int nv17_graph_ctx_regs[] = {
+	NV10_PGRAPH_DEBUG_4,
+	0x004006b0,
+	0x00400eac,
+	0x00400eb0,
+	0x00400eb4,
+	0x00400eb8,
+	0x00400ebc,
+	0x00400ec0,
+	0x00400ec4,
+	0x00400ec8,
+	0x00400ecc,
+	0x00400ed0,
+	0x00400ed4,
+	0x00400ed8,
+	0x00400edc,
+	0x00400ee0,
+	0x00400a00,
+	0x00400a04,
+};
+
+struct graph_state {
+	int nv10[ARRAY_SIZE(nv10_graph_ctx_regs)];
+	int nv17[ARRAY_SIZE(nv17_graph_ctx_regs)];
+	struct pipe_state pipe_state;
+};
+
+static void nv10_graph_save_pipe(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
+	struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state;
+	int i;
+#define PIPE_SAVE(addr) \
+	do { \
+		nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr); \
+		for (i = 0; i < ARRAY_SIZE(fifo_pipe_state->pipe_##addr); i++) \
+			fifo_pipe_state->pipe_##addr[i] = nv_rd32(dev, NV10_PGRAPH_PIPE_DATA); \
+	} while (0)
+
+	PIPE_SAVE(0x4400);
+	PIPE_SAVE(0x0200);
+	PIPE_SAVE(0x6400);
+	PIPE_SAVE(0x6800);
+	PIPE_SAVE(0x6c00);
+	PIPE_SAVE(0x7000);
+	PIPE_SAVE(0x7400);
+	PIPE_SAVE(0x7800);
+	PIPE_SAVE(0x0040);
+	PIPE_SAVE(0x0000);
+
+#undef PIPE_SAVE
+}
+
+static void nv10_graph_load_pipe(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
+	struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state;
+	int i;
+	uint32_t xfmode0, xfmode1;
+#define PIPE_RESTORE(addr) \
+	do { \
+		nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr); \
+		for (i = 0; i < ARRAY_SIZE(fifo_pipe_state->pipe_##addr); i++) \
+			nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, fifo_pipe_state->pipe_##addr[i]); \
+	} while (0)
+
+
+	nouveau_wait_for_idle(dev);
+	/* XXX check haiku comments */
+	xfmode0 = nv_rd32(dev, NV10_PGRAPH_XFMODE0);
+	xfmode1 = nv_rd32(dev, NV10_PGRAPH_XFMODE1);
+	nv_wr32(dev, NV10_PGRAPH_XFMODE0, 0x10000000);
+	nv_wr32(dev, NV10_PGRAPH_XFMODE1, 0x00000000);
+	nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0);
+	for (i = 0; i < 4; i++)
+		nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
+	for (i = 0; i < 4; i++)
+		nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
+
+	nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0);
+	for (i = 0; i < 3; i++)
+		nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
+
+	nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80);
+	for (i = 0; i < 3; i++)
+		nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
+
+	nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
+	nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000008);
+
+
+	PIPE_RESTORE(0x0200);
+	nouveau_wait_for_idle(dev);
+
+	/* restore XFMODE */
+	nv_wr32(dev, NV10_PGRAPH_XFMODE0, xfmode0);
+	nv_wr32(dev, NV10_PGRAPH_XFMODE1, xfmode1);
+	PIPE_RESTORE(0x6400);
+	PIPE_RESTORE(0x6800);
+	PIPE_RESTORE(0x6c00);
+	PIPE_RESTORE(0x7000);
+	PIPE_RESTORE(0x7400);
+	PIPE_RESTORE(0x7800);
+	PIPE_RESTORE(0x4400);
+	PIPE_RESTORE(0x0000);
+	PIPE_RESTORE(0x0040);
+	nouveau_wait_for_idle(dev);
+
+#undef PIPE_RESTORE
+}
+
+static void nv10_graph_create_pipe(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
+	struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state;
+	uint32_t *fifo_pipe_state_addr;
+	int i;
+#define PIPE_INIT(addr) \
+	do { \
+		fifo_pipe_state_addr = fifo_pipe_state->pipe_##addr; \
+	} while (0)
+#define PIPE_INIT_END(addr) \
+	do { \
+		uint32_t *__end_addr = fifo_pipe_state->pipe_##addr + \
+				ARRAY_SIZE(fifo_pipe_state->pipe_##addr); \
+		if (fifo_pipe_state_addr != __end_addr) \
+			NV_ERROR(dev, "incomplete pipe init for 0x%x :  %p/%p\n", \
+				addr, fifo_pipe_state_addr, __end_addr); \
+	} while (0)
+#define NV_WRITE_PIPE_INIT(value) *(fifo_pipe_state_addr++) = value
+
+	PIPE_INIT(0x0200);
+	for (i = 0; i < 48; i++)
+		NV_WRITE_PIPE_INIT(0x00000000);
+	PIPE_INIT_END(0x0200);
+
+	PIPE_INIT(0x6400);
+	for (i = 0; i < 211; i++)
+		NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x3f800000);
+	NV_WRITE_PIPE_INIT(0x40000000);
+	NV_WRITE_PIPE_INIT(0x40000000);
+	NV_WRITE_PIPE_INIT(0x40000000);
+	NV_WRITE_PIPE_INIT(0x40000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x3f800000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x3f000000);
+	NV_WRITE_PIPE_INIT(0x3f000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x3f800000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x3f800000);
+	NV_WRITE_PIPE_INIT(0x3f800000);
+	NV_WRITE_PIPE_INIT(0x3f800000);
+	NV_WRITE_PIPE_INIT(0x3f800000);
+	PIPE_INIT_END(0x6400);
+
+	PIPE_INIT(0x6800);
+	for (i = 0; i < 162; i++)
+		NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x3f800000);
+	for (i = 0; i < 25; i++)
+		NV_WRITE_PIPE_INIT(0x00000000);
+	PIPE_INIT_END(0x6800);
+
+	PIPE_INIT(0x6c00);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0xbf800000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	PIPE_INIT_END(0x6c00);
+
+	PIPE_INIT(0x7000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x7149f2ca);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x7149f2ca);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x7149f2ca);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x7149f2ca);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x7149f2ca);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x7149f2ca);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x7149f2ca);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x7149f2ca);
+	for (i = 0; i < 35; i++)
+		NV_WRITE_PIPE_INIT(0x00000000);
+	PIPE_INIT_END(0x7000);
+
+	PIPE_INIT(0x7400);
+	for (i = 0; i < 48; i++)
+		NV_WRITE_PIPE_INIT(0x00000000);
+	PIPE_INIT_END(0x7400);
+
+	PIPE_INIT(0x7800);
+	for (i = 0; i < 48; i++)
+		NV_WRITE_PIPE_INIT(0x00000000);
+	PIPE_INIT_END(0x7800);
+
+	PIPE_INIT(0x4400);
+	for (i = 0; i < 32; i++)
+		NV_WRITE_PIPE_INIT(0x00000000);
+	PIPE_INIT_END(0x4400);
+
+	PIPE_INIT(0x0000);
+	for (i = 0; i < 16; i++)
+		NV_WRITE_PIPE_INIT(0x00000000);
+	PIPE_INIT_END(0x0000);
+
+	PIPE_INIT(0x0040);
+	for (i = 0; i < 4; i++)
+		NV_WRITE_PIPE_INIT(0x00000000);
+	PIPE_INIT_END(0x0040);
+
+#undef PIPE_INIT
+#undef PIPE_INIT_END
+#undef NV_WRITE_PIPE_INIT
+}
+
+static int nv10_graph_ctx_regs_find_offset(struct drm_device *dev, int reg)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++) {
+		if (nv10_graph_ctx_regs[i] == reg)
+			return i;
+	}
+	NV_ERROR(dev, "unknow offset nv10_ctx_regs %d\n", reg);
+	return -1;
+}
+
+static int nv17_graph_ctx_regs_find_offset(struct drm_device *dev, int reg)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++) {
+		if (nv17_graph_ctx_regs[i] == reg)
+			return i;
+	}
+	NV_ERROR(dev, "unknow offset nv17_ctx_regs %d\n", reg);
+	return -1;
+}
+
+int nv10_graph_load_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
+	uint32_t tmp;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++)
+		nv_wr32(dev, nv10_graph_ctx_regs[i], pgraph_ctx->nv10[i]);
+	if (dev_priv->chipset >= 0x17) {
+		for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++)
+			nv_wr32(dev, nv17_graph_ctx_regs[i],
+						pgraph_ctx->nv17[i]);
+	}
+
+	nv10_graph_load_pipe(chan);
+
+	nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100);
+	tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER);
+	nv_wr32(dev, NV10_PGRAPH_CTX_USER, (tmp & 0xffffff) | chan->id << 24);
+	tmp = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2);
+	nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, tmp & 0xcfffffff);
+	return 0;
+}
+
+int
+nv10_graph_unload_context(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	struct nouveau_channel *chan;
+	struct graph_state *ctx;
+	uint32_t tmp;
+	int i;
+
+	chan = pgraph->channel(dev);
+	if (!chan)
+		return 0;
+	ctx = chan->pgraph_ctx;
+
+	for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++)
+		ctx->nv10[i] = nv_rd32(dev, nv10_graph_ctx_regs[i]);
+
+	if (dev_priv->chipset >= 0x17) {
+		for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++)
+			ctx->nv17[i] = nv_rd32(dev, nv17_graph_ctx_regs[i]);
+	}
+
+	nv10_graph_save_pipe(chan);
+
+	nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000000);
+	tmp  = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
+	tmp |= (pfifo->channels - 1) << 24;
+	nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp);
+	return 0;
+}
+
+void
+nv10_graph_context_switch(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	struct nouveau_channel *chan = NULL;
+	int chid;
+
+	pgraph->fifo_access(dev, false);
+	nouveau_wait_for_idle(dev);
+
+	/* If previous context is valid, we need to save it */
+	nv10_graph_unload_context(dev);
+
+	/* Load context for next channel */
+	chid = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f;
+	chan = dev_priv->fifos[chid];
+	if (chan)
+		nv10_graph_load_context(chan);
+
+	pgraph->fifo_access(dev, true);
+}
+
+#define NV_WRITE_CTX(reg, val) do { \
+	int offset = nv10_graph_ctx_regs_find_offset(dev, reg); \
+	if (offset > 0) \
+		pgraph_ctx->nv10[offset] = val; \
+	} while (0)
+
+#define NV17_WRITE_CTX(reg, val) do { \
+	int offset = nv17_graph_ctx_regs_find_offset(dev, reg); \
+	if (offset > 0) \
+		pgraph_ctx->nv17[offset] = val; \
+	} while (0)
+
+struct nouveau_channel *
+nv10_graph_channel(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int chid = dev_priv->engine.fifo.channels;
+
+	if (nv_rd32(dev, NV10_PGRAPH_CTX_CONTROL) & 0x00010000)
+		chid = nv_rd32(dev, NV10_PGRAPH_CTX_USER) >> 24;
+
+	if (chid >= dev_priv->engine.fifo.channels)
+		return NULL;
+
+	return dev_priv->fifos[chid];
+}
+
+int nv10_graph_create_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct graph_state *pgraph_ctx;
+
+	NV_DEBUG(dev, "nv10_graph_context_create %d\n", chan->id);
+
+	chan->pgraph_ctx = pgraph_ctx = kzalloc(sizeof(*pgraph_ctx),
+						GFP_KERNEL);
+	if (pgraph_ctx == NULL)
+		return -ENOMEM;
+
+
+	NV_WRITE_CTX(0x00400e88, 0x08000000);
+	NV_WRITE_CTX(0x00400e9c, 0x4b7fffff);
+	NV_WRITE_CTX(NV03_PGRAPH_XY_LOGIC_MISC0, 0x0001ffff);
+	NV_WRITE_CTX(0x00400e10, 0x00001000);
+	NV_WRITE_CTX(0x00400e14, 0x00001000);
+	NV_WRITE_CTX(0x00400e30, 0x00080008);
+	NV_WRITE_CTX(0x00400e34, 0x00080008);
+	if (dev_priv->chipset >= 0x17) {
+		/* is it really needed ??? */
+		NV17_WRITE_CTX(NV10_PGRAPH_DEBUG_4,
+					nv_rd32(dev, NV10_PGRAPH_DEBUG_4));
+		NV17_WRITE_CTX(0x004006b0, nv_rd32(dev, 0x004006b0));
+		NV17_WRITE_CTX(0x00400eac, 0x0fff0000);
+		NV17_WRITE_CTX(0x00400eb0, 0x0fff0000);
+		NV17_WRITE_CTX(0x00400ec0, 0x00000080);
+		NV17_WRITE_CTX(0x00400ed0, 0x00000080);
+	}
+	NV_WRITE_CTX(NV10_PGRAPH_CTX_USER, chan->id << 24);
+
+	nv10_graph_create_pipe(chan);
+	return 0;
+}
+
+void nv10_graph_destroy_context(struct nouveau_channel *chan)
+{
+	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
+
+	kfree(pgraph_ctx);
+	chan->pgraph_ctx = NULL;
+}
+
+int nv10_graph_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t tmp;
+	int i;
+
+	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
+			~NV_PMC_ENABLE_PGRAPH);
+	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
+			 NV_PMC_ENABLE_PGRAPH);
+
+	nv_wr32(dev, NV03_PGRAPH_INTR   , 0xFFFFFFFF);
+	nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
+
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x00118700);
+	/* nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x24E00810); */ /* 0x25f92ad9 */
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x25f92ad9);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0x55DE0830 |
+				      (1<<29) |
+				      (1<<31));
+	if (dev_priv->chipset >= 0x17) {
+		nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x1f000000);
+		nv_wr32(dev, 0x004006b0, 0x40000020);
+	} else
+		nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000);
+
+	/* copy tile info from PFB */
+	for (i = 0; i < NV10_PFB_TILE__SIZE; i++) {
+		nv_wr32(dev, NV10_PGRAPH_TILE(i),
+					nv_rd32(dev, NV10_PFB_TILE(i)));
+		nv_wr32(dev, NV10_PGRAPH_TLIMIT(i),
+					nv_rd32(dev, NV10_PFB_TLIMIT(i)));
+		nv_wr32(dev, NV10_PGRAPH_TSIZE(i),
+					nv_rd32(dev, NV10_PFB_TSIZE(i)));
+		nv_wr32(dev, NV10_PGRAPH_TSTATUS(i),
+					nv_rd32(dev, NV10_PFB_TSTATUS(i)));
+	}
+
+	nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH1, 0x00000000);
+	nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH2, 0x00000000);
+	nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH3, 0x00000000);
+	nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH4, 0x00000000);
+	nv_wr32(dev, NV10_PGRAPH_STATE      , 0xFFFFFFFF);
+
+	tmp  = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
+	tmp |= (dev_priv->engine.fifo.channels - 1) << 24;
+	nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp);
+	nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
+	nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, 0x08000000);
+
+	return 0;
+}
+
+void nv10_graph_takedown(struct drm_device *dev)
+{
+}
+
+struct nouveau_pgraph_object_class nv10_graph_grclass[] = {
+	{ 0x0030, false, NULL }, /* null */
+	{ 0x0039, false, NULL }, /* m2mf */
+	{ 0x004a, false, NULL }, /* gdirect */
+	{ 0x005f, false, NULL }, /* imageblit */
+	{ 0x009f, false, NULL }, /* imageblit (nv12) */
+	{ 0x008a, false, NULL }, /* ifc */
+	{ 0x0089, false, NULL }, /* sifm */
+	{ 0x0062, false, NULL }, /* surf2d */
+	{ 0x0043, false, NULL }, /* rop */
+	{ 0x0012, false, NULL }, /* beta1 */
+	{ 0x0072, false, NULL }, /* beta4 */
+	{ 0x0019, false, NULL }, /* cliprect */
+	{ 0x0044, false, NULL }, /* pattern */
+	{ 0x0052, false, NULL }, /* swzsurf */
+	{ 0x0093, false, NULL }, /* surf3d */
+	{ 0x0094, false, NULL }, /* tex_tri */
+	{ 0x0095, false, NULL }, /* multitex_tri */
+	{ 0x0056, false, NULL }, /* celcius (nv10) */
+	{ 0x0096, false, NULL }, /* celcius (nv11) */
+	{ 0x0099, false, NULL }, /* celcius (nv17) */
+	{}
+};
diff --git a/drivers/gpu/drm/nouveau/nv17_gpio.c b/drivers/gpu/drm/nouveau/nv17_gpio.c
new file mode 100644
index 0000000..2e58c33
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv17_gpio.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2009 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_hw.h"
+
+static bool
+get_gpio_location(struct dcb_gpio_entry *ent, uint32_t *reg, uint32_t *shift,
+		  uint32_t *mask)
+{
+	if (ent->line < 2) {
+		*reg = NV_PCRTC_GPIO;
+		*shift = ent->line * 16;
+		*mask = 0x11;
+
+	} else if (ent->line < 10) {
+		*reg = NV_PCRTC_GPIO_EXT;
+		*shift = (ent->line - 2) * 4;
+		*mask = 0x3;
+
+	} else if (ent->line < 14) {
+		*reg = NV_PCRTC_850;
+		*shift = (ent->line - 10) * 4;
+		*mask = 0x3;
+
+	} else {
+		return false;
+	}
+
+	return true;
+}
+
+int
+nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag)
+{
+	struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag);
+	uint32_t reg, shift, mask, value;
+
+	if (!ent)
+		return -ENODEV;
+
+	if (!get_gpio_location(ent, &reg, &shift, &mask))
+		return -ENODEV;
+
+	value = NVReadCRTC(dev, 0, reg) >> shift;
+
+	return (ent->invert ? 1 : 0) ^ (value & 1);
+}
+
+int
+nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state)
+{
+	struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag);
+	uint32_t reg, shift, mask, value;
+
+	if (!ent)
+		return -ENODEV;
+
+	if (!get_gpio_location(ent, &reg, &shift, &mask))
+		return -ENODEV;
+
+	value = ((ent->invert ? 1 : 0) ^ (state ? 1 : 0)) << shift;
+	mask = ~(mask << shift);
+
+	NVWriteCRTC(dev, 0, reg, value | (NVReadCRTC(dev, 0, reg) & mask));
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c
new file mode 100644
index 0000000..46cfd9c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv17_tv.c
@@ -0,0 +1,681 @@
+/*
+ * Copyright (C) 2009 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "drm_crtc_helper.h"
+#include "nouveau_drv.h"
+#include "nouveau_encoder.h"
+#include "nouveau_connector.h"
+#include "nouveau_crtc.h"
+#include "nouveau_hw.h"
+#include "nv17_tv.h"
+
+enum drm_connector_status nv17_tv_detect(struct drm_encoder *encoder,
+					 struct drm_connector *connector,
+					 uint32_t pin_mask)
+{
+	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
+
+	tv_enc->pin_mask = pin_mask >> 28 & 0xe;
+
+	switch (tv_enc->pin_mask) {
+	case 0x2:
+	case 0x4:
+		tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Composite;
+		break;
+	case 0xc:
+		tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_SVIDEO;
+		break;
+	case 0xe:
+		if (nouveau_encoder(encoder)->dcb->tvconf.has_component_output)
+			tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Component;
+		else
+			tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_SCART;
+		break;
+	default:
+		tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Unknown;
+		break;
+	}
+
+	drm_connector_property_set_value(connector,
+			encoder->dev->mode_config.tv_subconnector_property,
+							tv_enc->subconnector);
+
+	return tv_enc->subconnector ? connector_status_connected :
+					connector_status_disconnected;
+}
+
+static const struct {
+	int hdisplay;
+	int vdisplay;
+} modes[] = {
+	{ 640, 400 },
+	{ 640, 480 },
+	{ 720, 480 },
+	{ 720, 576 },
+	{ 800, 600 },
+	{ 1024, 768 },
+	{ 1280, 720 },
+	{ 1280, 1024 },
+	{ 1920, 1080 }
+};
+
+static int nv17_tv_get_modes(struct drm_encoder *encoder,
+			     struct drm_connector *connector)
+{
+	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
+	struct drm_display_mode *mode;
+	struct drm_display_mode *output_mode;
+	int n = 0;
+	int i;
+
+	if (tv_norm->kind != CTV_ENC_MODE) {
+		struct drm_display_mode *tv_mode;
+
+		for (tv_mode = nv17_tv_modes; tv_mode->hdisplay; tv_mode++) {
+			mode = drm_mode_duplicate(encoder->dev, tv_mode);
+
+			mode->clock = tv_norm->tv_enc_mode.vrefresh *
+						mode->htotal / 1000 *
+						mode->vtotal / 1000;
+
+			if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+				mode->clock *= 2;
+
+			if (mode->hdisplay == tv_norm->tv_enc_mode.hdisplay &&
+			    mode->vdisplay == tv_norm->tv_enc_mode.vdisplay)
+				mode->type |= DRM_MODE_TYPE_PREFERRED;
+
+			drm_mode_probed_add(connector, mode);
+			n++;
+		}
+		return n;
+	}
+
+	/* tv_norm->kind == CTV_ENC_MODE */
+	output_mode = &tv_norm->ctv_enc_mode.mode;
+	for (i = 0; i < ARRAY_SIZE(modes); i++) {
+		if (modes[i].hdisplay > output_mode->hdisplay ||
+		    modes[i].vdisplay > output_mode->vdisplay)
+			continue;
+
+		if (modes[i].hdisplay == output_mode->hdisplay &&
+		    modes[i].vdisplay == output_mode->vdisplay) {
+			mode = drm_mode_duplicate(encoder->dev, output_mode);
+			mode->type |= DRM_MODE_TYPE_PREFERRED;
+		} else {
+			mode = drm_cvt_mode(encoder->dev, modes[i].hdisplay,
+				modes[i].vdisplay, 60, false,
+				output_mode->flags & DRM_MODE_FLAG_INTERLACE,
+				false);
+		}
+
+		/* CVT modes are sometimes unsuitable... */
+		if (output_mode->hdisplay <= 720
+		    || output_mode->hdisplay >= 1920) {
+			mode->htotal = output_mode->htotal;
+			mode->hsync_start = (mode->hdisplay + (mode->htotal
+					     - mode->hdisplay) * 9 / 10) & ~7;
+			mode->hsync_end = mode->hsync_start + 8;
+		}
+		if (output_mode->vdisplay >= 1024) {
+			mode->vtotal = output_mode->vtotal;
+			mode->vsync_start = output_mode->vsync_start;
+			mode->vsync_end = output_mode->vsync_end;
+		}
+
+		mode->type |= DRM_MODE_TYPE_DRIVER;
+		drm_mode_probed_add(connector, mode);
+		n++;
+	}
+	return n;
+}
+
+static int nv17_tv_mode_valid(struct drm_encoder *encoder,
+			      struct drm_display_mode *mode)
+{
+	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
+
+	if (tv_norm->kind == CTV_ENC_MODE) {
+		struct drm_display_mode *output_mode =
+						&tv_norm->ctv_enc_mode.mode;
+
+		if (mode->clock > 400000)
+			return MODE_CLOCK_HIGH;
+
+		if (mode->hdisplay > output_mode->hdisplay ||
+		    mode->vdisplay > output_mode->vdisplay)
+			return MODE_BAD;
+
+		if ((mode->flags & DRM_MODE_FLAG_INTERLACE) !=
+		    (output_mode->flags & DRM_MODE_FLAG_INTERLACE))
+			return MODE_NO_INTERLACE;
+
+		if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+			return MODE_NO_DBLESCAN;
+
+	} else {
+		const int vsync_tolerance = 600;
+
+		if (mode->clock > 70000)
+			return MODE_CLOCK_HIGH;
+
+		if (abs(drm_mode_vrefresh(mode) * 1000 -
+			tv_norm->tv_enc_mode.vrefresh) > vsync_tolerance)
+			return MODE_VSYNC;
+
+		/* The encoder takes care of the actual interlacing */
+		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+			return MODE_NO_INTERLACE;
+	}
+
+	return MODE_OK;
+}
+
+static bool nv17_tv_mode_fixup(struct drm_encoder *encoder,
+			       struct drm_display_mode *mode,
+			       struct drm_display_mode *adjusted_mode)
+{
+	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
+
+	if (tv_norm->kind == CTV_ENC_MODE)
+		adjusted_mode->clock = tv_norm->ctv_enc_mode.mode.clock;
+	else
+		adjusted_mode->clock = 90000;
+
+	return true;
+}
+
+static void  nv17_tv_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nv17_tv_state *regs = &to_tv_enc(encoder)->state;
+	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
+
+	if (nouveau_encoder(encoder)->last_dpms == mode)
+		return;
+	nouveau_encoder(encoder)->last_dpms = mode;
+
+	NV_TRACE(dev, "Setting dpms mode %d on TV encoder (output %d)\n",
+		 mode, nouveau_encoder(encoder)->dcb->index);
+
+	regs->ptv_200 &= ~1;
+
+	if (tv_norm->kind == CTV_ENC_MODE) {
+		nv04_dfp_update_fp_control(encoder, mode);
+
+	} else {
+		nv04_dfp_update_fp_control(encoder, DRM_MODE_DPMS_OFF);
+
+		if (mode == DRM_MODE_DPMS_ON)
+			regs->ptv_200 |= 1;
+	}
+
+	nv_load_ptv(dev, regs, 200);
+
+	nv17_gpio_set(dev, DCB_GPIO_TVDAC1, mode == DRM_MODE_DPMS_ON);
+	nv17_gpio_set(dev, DCB_GPIO_TVDAC0, mode == DRM_MODE_DPMS_ON);
+
+	nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON);
+}
+
+static void nv17_tv_prepare(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_encoder_helper_funcs *helper = encoder->helper_private;
+	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
+	int head = nouveau_crtc(encoder->crtc)->index;
+	uint8_t *cr_lcd = &dev_priv->mode_reg.crtc_reg[head].CRTC[
+							NV_CIO_CRE_LCD__INDEX];
+	uint32_t dacclk_off = NV_PRAMDAC_DACCLK +
+					nv04_dac_output_offset(encoder);
+	uint32_t dacclk;
+
+	helper->dpms(encoder, DRM_MODE_DPMS_OFF);
+
+	nv04_dfp_disable(dev, head);
+
+	/* Unbind any FP encoders from this head if we need the FP
+	 * stuff enabled. */
+	if (tv_norm->kind == CTV_ENC_MODE) {
+		struct drm_encoder *enc;
+
+		list_for_each_entry(enc, &dev->mode_config.encoder_list, head) {
+			struct dcb_entry *dcb = nouveau_encoder(enc)->dcb;
+
+			if ((dcb->type == OUTPUT_TMDS ||
+			     dcb->type == OUTPUT_LVDS) &&
+			     !enc->crtc &&
+			     nv04_dfp_get_bound_head(dev, dcb) == head) {
+				nv04_dfp_bind_head(dev, dcb, head ^ 1,
+						dev_priv->VBIOS.fp.dual_link);
+			}
+		}
+
+	}
+
+	/* Some NV4x have unknown values (0x3f, 0x50, 0x54, 0x6b, 0x79, 0x7f)
+	 * at LCD__INDEX which we don't alter
+	 */
+	if (!(*cr_lcd & 0x44)) {
+		if (tv_norm->kind == CTV_ENC_MODE)
+			*cr_lcd = 0x1 | (head ? 0x0 : 0x8);
+		else
+			*cr_lcd = 0;
+	}
+
+	/* Set the DACCLK register */
+	dacclk = (NVReadRAMDAC(dev, 0, dacclk_off) & ~0x30) | 0x1;
+
+	if (dev_priv->card_type == NV_40)
+		dacclk |= 0x1a << 16;
+
+	if (tv_norm->kind == CTV_ENC_MODE) {
+		dacclk |=  0x20;
+
+		if (head)
+			dacclk |= 0x100;
+		else
+			dacclk &= ~0x100;
+
+	} else {
+		dacclk |= 0x10;
+
+	}
+
+	NVWriteRAMDAC(dev, 0, dacclk_off, dacclk);
+}
+
+static void nv17_tv_mode_set(struct drm_encoder *encoder,
+			     struct drm_display_mode *drm_mode,
+			     struct drm_display_mode *adjusted_mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int head = nouveau_crtc(encoder->crtc)->index;
+	struct nv04_crtc_reg *regs = &dev_priv->mode_reg.crtc_reg[head];
+	struct nv17_tv_state *tv_regs = &to_tv_enc(encoder)->state;
+	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
+	int i;
+
+	regs->CRTC[NV_CIO_CRE_53] = 0x40; /* FP_HTIMING */
+	regs->CRTC[NV_CIO_CRE_54] = 0; /* FP_VTIMING */
+	regs->ramdac_630 = 0x2; /* turn off green mode (tv test pattern?) */
+	regs->tv_setup = 1;
+	regs->ramdac_8c0 = 0x0;
+
+	if (tv_norm->kind == TV_ENC_MODE) {
+		tv_regs->ptv_200 = 0x13111100;
+		if (head)
+			tv_regs->ptv_200 |= 0x10;
+
+		tv_regs->ptv_20c = 0x808010;
+		tv_regs->ptv_304 = 0x2d00000;
+		tv_regs->ptv_600 = 0x0;
+		tv_regs->ptv_60c = 0x0;
+		tv_regs->ptv_610 = 0x1e00000;
+
+		if (tv_norm->tv_enc_mode.vdisplay == 576) {
+			tv_regs->ptv_508 = 0x1200000;
+			tv_regs->ptv_614 = 0x33;
+
+		} else if (tv_norm->tv_enc_mode.vdisplay == 480) {
+			tv_regs->ptv_508 = 0xf00000;
+			tv_regs->ptv_614 = 0x13;
+		}
+
+		if (dev_priv->card_type >= NV_30) {
+			tv_regs->ptv_500 = 0xe8e0;
+			tv_regs->ptv_504 = 0x1710;
+			tv_regs->ptv_604 = 0x0;
+			tv_regs->ptv_608 = 0x0;
+		} else {
+			if (tv_norm->tv_enc_mode.vdisplay == 576) {
+				tv_regs->ptv_604 = 0x20;
+				tv_regs->ptv_608 = 0x10;
+				tv_regs->ptv_500 = 0x19710;
+				tv_regs->ptv_504 = 0x68f0;
+
+			} else if (tv_norm->tv_enc_mode.vdisplay == 480) {
+				tv_regs->ptv_604 = 0x10;
+				tv_regs->ptv_608 = 0x20;
+				tv_regs->ptv_500 = 0x4b90;
+				tv_regs->ptv_504 = 0x1b480;
+			}
+		}
+
+		for (i = 0; i < 0x40; i++)
+			tv_regs->tv_enc[i] = tv_norm->tv_enc_mode.tv_enc[i];
+
+	} else {
+		struct drm_display_mode *output_mode =
+						&tv_norm->ctv_enc_mode.mode;
+
+		/* The registers in PRAMDAC+0xc00 control some timings and CSC
+		 * parameters for the CTV encoder (It's only used for "HD" TV
+		 * modes, I don't think I have enough working to guess what
+		 * they exactly mean...), it's probably connected at the
+		 * output of the FP encoder, but it also needs the analog
+		 * encoder in its OR enabled and routed to the head it's
+		 * using. It's enabled with the DACCLK register, bits [5:4].
+		 */
+		for (i = 0; i < 38; i++)
+			regs->ctv_regs[i] = tv_norm->ctv_enc_mode.ctv_regs[i];
+
+		regs->fp_horiz_regs[FP_DISPLAY_END] = output_mode->hdisplay - 1;
+		regs->fp_horiz_regs[FP_TOTAL] = output_mode->htotal - 1;
+		regs->fp_horiz_regs[FP_SYNC_START] =
+						output_mode->hsync_start - 1;
+		regs->fp_horiz_regs[FP_SYNC_END] = output_mode->hsync_end - 1;
+		regs->fp_horiz_regs[FP_CRTC] = output_mode->hdisplay +
+			max((output_mode->hdisplay-600)/40 - 1, 1);
+
+		regs->fp_vert_regs[FP_DISPLAY_END] = output_mode->vdisplay - 1;
+		regs->fp_vert_regs[FP_TOTAL] = output_mode->vtotal - 1;
+		regs->fp_vert_regs[FP_SYNC_START] =
+						output_mode->vsync_start - 1;
+		regs->fp_vert_regs[FP_SYNC_END] = output_mode->vsync_end - 1;
+		regs->fp_vert_regs[FP_CRTC] = output_mode->vdisplay - 1;
+
+		regs->fp_control = NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS |
+			NV_PRAMDAC_FP_TG_CONTROL_READ_PROG |
+			NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12;
+
+		if (output_mode->flags & DRM_MODE_FLAG_PVSYNC)
+			regs->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS;
+		if (output_mode->flags & DRM_MODE_FLAG_PHSYNC)
+			regs->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS;
+
+		regs->fp_debug_0 = NV_PRAMDAC_FP_DEBUG_0_YWEIGHT_ROUND |
+			NV_PRAMDAC_FP_DEBUG_0_XWEIGHT_ROUND |
+			NV_PRAMDAC_FP_DEBUG_0_YINTERP_BILINEAR |
+			NV_PRAMDAC_FP_DEBUG_0_XINTERP_BILINEAR |
+			NV_RAMDAC_FP_DEBUG_0_TMDS_ENABLED |
+			NV_PRAMDAC_FP_DEBUG_0_YSCALE_ENABLE |
+			NV_PRAMDAC_FP_DEBUG_0_XSCALE_ENABLE;
+
+		regs->fp_debug_2 = 0;
+
+		regs->fp_margin_color = 0x801080;
+
+	}
+}
+
+static void nv17_tv_commit(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_encoder_helper_funcs *helper = encoder->helper_private;
+
+	if (get_tv_norm(encoder)->kind == TV_ENC_MODE) {
+		nv17_tv_update_rescaler(encoder);
+		nv17_tv_update_properties(encoder);
+	} else {
+		nv17_ctv_update_rescaler(encoder);
+	}
+
+	nv17_tv_state_load(dev, &to_tv_enc(encoder)->state);
+
+	/* This could use refinement for flatpanels, but it should work */
+	if (dev_priv->chipset < 0x44)
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL +
+					nv04_dac_output_offset(encoder),
+					0xf0000000);
+	else
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL +
+					nv04_dac_output_offset(encoder),
+					0x00100000);
+
+	helper->dpms(encoder, DRM_MODE_DPMS_ON);
+
+	NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n",
+		drm_get_connector_name(
+			&nouveau_encoder_connector_get(nv_encoder)->base),
+		nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
+}
+
+static void nv17_tv_save(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
+
+	nouveau_encoder(encoder)->restore.output =
+					NVReadRAMDAC(dev, 0,
+					NV_PRAMDAC_DACCLK +
+					nv04_dac_output_offset(encoder));
+
+	nv17_tv_state_save(dev, &tv_enc->saved_state);
+
+	tv_enc->state.ptv_200 = tv_enc->saved_state.ptv_200;
+}
+
+static void nv17_tv_restore(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK +
+				nv04_dac_output_offset(encoder),
+				nouveau_encoder(encoder)->restore.output);
+
+	nv17_tv_state_load(dev, &to_tv_enc(encoder)->saved_state);
+}
+
+static int nv17_tv_create_resources(struct drm_encoder *encoder,
+				    struct drm_connector *connector)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_mode_config *conf = &dev->mode_config;
+	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
+	struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
+	int num_tv_norms = dcb->tvconf.has_component_output ? NUM_TV_NORMS :
+							NUM_LD_TV_NORMS;
+	int i;
+
+	if (nouveau_tv_norm) {
+		for (i = 0; i < num_tv_norms; i++) {
+			if (!strcmp(nv17_tv_norm_names[i], nouveau_tv_norm)) {
+				tv_enc->tv_norm = i;
+				break;
+			}
+		}
+
+		if (i == num_tv_norms)
+			NV_WARN(dev, "Invalid TV norm setting \"%s\"\n",
+				nouveau_tv_norm);
+	}
+
+	drm_mode_create_tv_properties(dev, num_tv_norms, nv17_tv_norm_names);
+
+	drm_connector_attach_property(connector,
+					conf->tv_select_subconnector_property,
+					tv_enc->select_subconnector);
+	drm_connector_attach_property(connector,
+					conf->tv_subconnector_property,
+					tv_enc->subconnector);
+	drm_connector_attach_property(connector,
+					conf->tv_mode_property,
+					tv_enc->tv_norm);
+	drm_connector_attach_property(connector,
+					conf->tv_flicker_reduction_property,
+					tv_enc->flicker);
+	drm_connector_attach_property(connector,
+					conf->tv_saturation_property,
+					tv_enc->saturation);
+	drm_connector_attach_property(connector,
+					conf->tv_hue_property,
+					tv_enc->hue);
+	drm_connector_attach_property(connector,
+					conf->tv_overscan_property,
+					tv_enc->overscan);
+
+	return 0;
+}
+
+static int nv17_tv_set_property(struct drm_encoder *encoder,
+				struct drm_connector *connector,
+				struct drm_property *property,
+				uint64_t val)
+{
+	struct drm_mode_config *conf = &encoder->dev->mode_config;
+	struct drm_crtc *crtc = encoder->crtc;
+	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
+	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
+	bool modes_changed = false;
+
+	if (property == conf->tv_overscan_property) {
+		tv_enc->overscan = val;
+		if (encoder->crtc) {
+			if (tv_norm->kind == CTV_ENC_MODE)
+				nv17_ctv_update_rescaler(encoder);
+			else
+				nv17_tv_update_rescaler(encoder);
+		}
+
+	} else if (property == conf->tv_saturation_property) {
+		if (tv_norm->kind != TV_ENC_MODE)
+			return -EINVAL;
+
+		tv_enc->saturation = val;
+		nv17_tv_update_properties(encoder);
+
+	} else if (property == conf->tv_hue_property) {
+		if (tv_norm->kind != TV_ENC_MODE)
+			return -EINVAL;
+
+		tv_enc->hue = val;
+		nv17_tv_update_properties(encoder);
+
+	} else if (property == conf->tv_flicker_reduction_property) {
+		if (tv_norm->kind != TV_ENC_MODE)
+			return -EINVAL;
+
+		tv_enc->flicker = val;
+		if (encoder->crtc)
+			nv17_tv_update_rescaler(encoder);
+
+	} else if (property == conf->tv_mode_property) {
+		if (connector->dpms != DRM_MODE_DPMS_OFF)
+			return -EINVAL;
+
+		tv_enc->tv_norm = val;
+
+		modes_changed = true;
+
+	} else if (property == conf->tv_select_subconnector_property) {
+		if (tv_norm->kind != TV_ENC_MODE)
+			return -EINVAL;
+
+		tv_enc->select_subconnector = val;
+		nv17_tv_update_properties(encoder);
+
+	} else {
+		return -EINVAL;
+	}
+
+	if (modes_changed) {
+		drm_helper_probe_single_connector_modes(connector, 0, 0);
+
+		/* Disable the crtc to ensure a full modeset is
+		 * performed whenever it's turned on again. */
+		if (crtc) {
+			struct drm_mode_set modeset = {
+				.crtc = crtc,
+			};
+
+			crtc->funcs->set_config(&modeset);
+		}
+	}
+
+	return 0;
+}
+
+static void nv17_tv_destroy(struct drm_encoder *encoder)
+{
+	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
+
+	NV_DEBUG(encoder->dev, "\n");
+
+	drm_encoder_cleanup(encoder);
+	kfree(tv_enc);
+}
+
+static struct drm_encoder_helper_funcs nv17_tv_helper_funcs = {
+	.dpms = nv17_tv_dpms,
+	.save = nv17_tv_save,
+	.restore = nv17_tv_restore,
+	.mode_fixup = nv17_tv_mode_fixup,
+	.prepare = nv17_tv_prepare,
+	.commit = nv17_tv_commit,
+	.mode_set = nv17_tv_mode_set,
+	.detect = nv17_dac_detect,
+};
+
+static struct drm_encoder_slave_funcs nv17_tv_slave_funcs = {
+	.get_modes = nv17_tv_get_modes,
+	.mode_valid = nv17_tv_mode_valid,
+	.create_resources = nv17_tv_create_resources,
+	.set_property = nv17_tv_set_property,
+};
+
+static struct drm_encoder_funcs nv17_tv_funcs = {
+	.destroy = nv17_tv_destroy,
+};
+
+int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry)
+{
+	struct drm_encoder *encoder;
+	struct nv17_tv_encoder *tv_enc = NULL;
+
+	tv_enc = kzalloc(sizeof(*tv_enc), GFP_KERNEL);
+	if (!tv_enc)
+		return -ENOMEM;
+
+	tv_enc->overscan = 50;
+	tv_enc->flicker = 50;
+	tv_enc->saturation = 50;
+	tv_enc->hue = 0;
+	tv_enc->tv_norm = TV_NORM_PAL;
+	tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Unknown;
+	tv_enc->select_subconnector = DRM_MODE_SUBCONNECTOR_Automatic;
+	tv_enc->pin_mask = 0;
+
+	encoder = to_drm_encoder(&tv_enc->base);
+
+	tv_enc->base.dcb = entry;
+	tv_enc->base.or = ffs(entry->or) - 1;
+
+	drm_encoder_init(dev, encoder, &nv17_tv_funcs, DRM_MODE_ENCODER_TVDAC);
+	drm_encoder_helper_add(encoder, &nv17_tv_helper_funcs);
+	to_encoder_slave(encoder)->slave_funcs = &nv17_tv_slave_funcs;
+
+	encoder->possible_crtcs = entry->heads;
+	encoder->possible_clones = 0;
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nv17_tv.h b/drivers/gpu/drm/nouveau/nv17_tv.h
new file mode 100644
index 0000000..c00977c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv17_tv.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2009 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __NV17_TV_H__
+#define __NV17_TV_H__
+
+struct nv17_tv_state {
+	uint8_t tv_enc[0x40];
+
+	uint32_t hfilter[4][7];
+	uint32_t hfilter2[4][7];
+	uint32_t vfilter[4][7];
+
+	uint32_t ptv_200;
+	uint32_t ptv_204;
+	uint32_t ptv_208;
+	uint32_t ptv_20c;
+	uint32_t ptv_304;
+	uint32_t ptv_500;
+	uint32_t ptv_504;
+	uint32_t ptv_508;
+	uint32_t ptv_600;
+	uint32_t ptv_604;
+	uint32_t ptv_608;
+	uint32_t ptv_60c;
+	uint32_t ptv_610;
+	uint32_t ptv_614;
+};
+
+enum nv17_tv_norm{
+	TV_NORM_PAL,
+	TV_NORM_PAL_M,
+	TV_NORM_PAL_N,
+	TV_NORM_PAL_NC,
+	TV_NORM_NTSC_M,
+	TV_NORM_NTSC_J,
+	NUM_LD_TV_NORMS,
+	TV_NORM_HD480I = NUM_LD_TV_NORMS,
+	TV_NORM_HD480P,
+	TV_NORM_HD576I,
+	TV_NORM_HD576P,
+	TV_NORM_HD720P,
+	TV_NORM_HD1080I,
+	NUM_TV_NORMS
+};
+
+struct nv17_tv_encoder {
+	struct nouveau_encoder base;
+
+	struct nv17_tv_state state;
+	struct nv17_tv_state saved_state;
+
+	int overscan;
+	int flicker;
+	int saturation;
+	int hue;
+	enum nv17_tv_norm tv_norm;
+	int subconnector;
+	int select_subconnector;
+	uint32_t pin_mask;
+};
+#define to_tv_enc(x) container_of(nouveau_encoder(x),		\
+				  struct nv17_tv_encoder, base)
+
+extern char *nv17_tv_norm_names[NUM_TV_NORMS];
+
+extern struct nv17_tv_norm_params {
+	enum {
+		TV_ENC_MODE,
+		CTV_ENC_MODE,
+	} kind;
+
+	union {
+		struct {
+			int hdisplay;
+			int vdisplay;
+			int vrefresh; /* mHz */
+
+			uint8_t tv_enc[0x40];
+		} tv_enc_mode;
+
+		struct {
+			struct drm_display_mode mode;
+
+			uint32_t ctv_regs[38];
+		} ctv_enc_mode;
+	};
+
+} nv17_tv_norms[NUM_TV_NORMS];
+#define get_tv_norm(enc) (&nv17_tv_norms[to_tv_enc(enc)->tv_norm])
+
+extern struct drm_display_mode nv17_tv_modes[];
+
+static inline int interpolate(int y0, int y1, int y2, int x)
+{
+	return y1 + (x < 50 ? y1 - y0 : y2 - y1) * (x - 50) / 50;
+}
+
+void nv17_tv_state_save(struct drm_device *dev, struct nv17_tv_state *state);
+void nv17_tv_state_load(struct drm_device *dev, struct nv17_tv_state *state);
+void nv17_tv_update_properties(struct drm_encoder *encoder);
+void nv17_tv_update_rescaler(struct drm_encoder *encoder);
+void nv17_ctv_update_rescaler(struct drm_encoder *encoder);
+
+/* TV hardware access functions */
+
+static inline void nv_write_ptv(struct drm_device *dev, uint32_t reg, uint32_t val)
+{
+	nv_wr32(dev, reg, val);
+}
+
+static inline uint32_t nv_read_ptv(struct drm_device *dev, uint32_t reg)
+{
+	return nv_rd32(dev, reg);
+}
+
+static inline void nv_write_tv_enc(struct drm_device *dev, uint8_t reg, uint8_t val)
+{
+	nv_write_ptv(dev, NV_PTV_TV_INDEX, reg);
+	nv_write_ptv(dev, NV_PTV_TV_DATA, val);
+}
+
+static inline uint8_t nv_read_tv_enc(struct drm_device *dev, uint8_t reg)
+{
+	nv_write_ptv(dev, NV_PTV_TV_INDEX, reg);
+	return nv_read_ptv(dev, NV_PTV_TV_DATA);
+}
+
+#define nv_load_ptv(dev, state, reg) nv_write_ptv(dev, NV_PTV_OFFSET + 0x##reg, state->ptv_##reg)
+#define nv_save_ptv(dev, state, reg) state->ptv_##reg = nv_read_ptv(dev, NV_PTV_OFFSET + 0x##reg)
+#define nv_load_tv_enc(dev, state, reg) nv_write_tv_enc(dev, 0x##reg, state->tv_enc[0x##reg])
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nv17_tv_modes.c b/drivers/gpu/drm/nouveau/nv17_tv_modes.c
new file mode 100644
index 0000000..d64683d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv17_tv_modes.c
@@ -0,0 +1,583 @@
+/*
+ * Copyright (C) 2009 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "drm_crtc_helper.h"
+#include "nouveau_drv.h"
+#include "nouveau_encoder.h"
+#include "nouveau_crtc.h"
+#include "nouveau_hw.h"
+#include "nv17_tv.h"
+
+char *nv17_tv_norm_names[NUM_TV_NORMS] = {
+	[TV_NORM_PAL] = "PAL",
+	[TV_NORM_PAL_M] = "PAL-M",
+	[TV_NORM_PAL_N] = "PAL-N",
+	[TV_NORM_PAL_NC] = "PAL-Nc",
+	[TV_NORM_NTSC_M] = "NTSC-M",
+	[TV_NORM_NTSC_J] = "NTSC-J",
+	[TV_NORM_HD480I] = "hd480i",
+	[TV_NORM_HD480P] = "hd480p",
+	[TV_NORM_HD576I] = "hd576i",
+	[TV_NORM_HD576P] = "hd576p",
+	[TV_NORM_HD720P] = "hd720p",
+	[TV_NORM_HD1080I] = "hd1080i"
+};
+
+/* TV standard specific parameters */
+
+struct nv17_tv_norm_params nv17_tv_norms[NUM_TV_NORMS] = {
+	[TV_NORM_PAL] = { TV_ENC_MODE, {
+			.tv_enc_mode = { 720, 576, 50000, {
+					0x2a, 0x9, 0x8a, 0xcb, 0x0, 0x0, 0xb, 0x18,
+					0x7e, 0x40, 0x8a, 0x35, 0x27, 0x0, 0x34, 0x3,
+					0x3e, 0x3, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c,
+					0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x3,
+					0xd3, 0x4, 0xd4, 0x1, 0x2, 0x0, 0xa, 0x5,
+					0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0,
+					0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b,
+					0xbd, 0x15, 0x5, 0x15, 0x3e, 0x3, 0x0, 0x0
+				} } } },
+
+	[TV_NORM_PAL_M] = { TV_ENC_MODE, {
+			.tv_enc_mode = { 720, 480, 59940, {
+					0x21, 0xe6, 0xef, 0xe3, 0x0, 0x0, 0xb, 0x18,
+					0x7e, 0x44, 0x76, 0x32, 0x25, 0x0, 0x3c, 0x0,
+					0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83,
+					0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1,
+					0xc5, 0x4, 0xc5, 0x1, 0x2, 0x0, 0xa, 0x5,
+					0x0, 0x18, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0,
+					0x0, 0xb4, 0x0, 0x15, 0x40, 0x10, 0x0, 0x9c,
+					0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0
+				} } } },
+
+	[TV_NORM_PAL_N] = { TV_ENC_MODE, {
+			.tv_enc_mode = { 720, 576, 50000, {
+					0x2a, 0x9, 0x8a, 0xcb, 0x0, 0x0, 0xb, 0x18,
+					0x7e, 0x40, 0x8a, 0x32, 0x25, 0x0, 0x3c, 0x0,
+					0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c,
+					0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1,
+					0xc5, 0x4, 0xc5, 0x1, 0x2, 0x0, 0xa, 0x5,
+					0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0,
+					0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b,
+					0xbd, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0
+				} } } },
+
+	[TV_NORM_PAL_NC] = { TV_ENC_MODE, {
+			.tv_enc_mode = { 720, 576, 50000, {
+					0x21, 0xf6, 0x94, 0x46, 0x0, 0x0, 0xb, 0x18,
+					0x7e, 0x44, 0x8a, 0x35, 0x27, 0x0, 0x34, 0x3,
+					0x3e, 0x3, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c,
+					0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x3,
+					0xd3, 0x4, 0xd4, 0x1, 0x2, 0x0, 0xa, 0x5,
+					0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0,
+					0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b,
+					0xbd, 0x15, 0x5, 0x15, 0x3e, 0x3, 0x0, 0x0
+				} } } },
+
+	[TV_NORM_NTSC_M] = { TV_ENC_MODE, {
+			.tv_enc_mode = { 720, 480, 59940, {
+					0x21, 0xf0, 0x7c, 0x1f, 0x0, 0x0, 0xb, 0x18,
+					0x7e, 0x44, 0x76, 0x48, 0x0, 0x0, 0x3c, 0x0,
+					0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83,
+					0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1,
+					0xc5, 0x4, 0xc5, 0x1, 0x2, 0x0, 0xa, 0x5,
+					0x0, 0x16, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0,
+					0x0, 0xb4, 0x0, 0x15, 0x4, 0x10, 0x0, 0x9c,
+					0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0
+				} } } },
+
+	[TV_NORM_NTSC_J] = { TV_ENC_MODE, {
+			.tv_enc_mode = { 720, 480, 59940, {
+					0x21, 0xf0, 0x7c, 0x1f, 0x0, 0x0, 0xb, 0x18,
+					0x7e, 0x44, 0x76, 0x48, 0x0, 0x0, 0x32, 0x0,
+					0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83,
+					0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1,
+					0xcf, 0x4, 0xcf, 0x1, 0x2, 0x0, 0xa, 0x5,
+					0x0, 0x16, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0,
+					0x0, 0xb4, 0x0, 0x15, 0x4, 0x10, 0x0, 0xa4,
+					0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0
+				} } } },
+
+	[TV_NORM_HD480I] = { TV_ENC_MODE, {
+			.tv_enc_mode = { 720, 480, 59940, {
+					0x21, 0xf0, 0x7c, 0x1f, 0x0, 0x0, 0xb, 0x18,
+					0x7e, 0x44, 0x76, 0x48, 0x0, 0x0, 0x32, 0x0,
+					0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83,
+					0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1,
+					0xcf, 0x4, 0xcf, 0x1, 0x2, 0x0, 0xa, 0x5,
+					0x0, 0x16, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0,
+					0x0, 0xb4, 0x0, 0x15, 0x4, 0x10, 0x0, 0xa4,
+					0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0
+				} } } },
+
+	[TV_NORM_HD576I] = { TV_ENC_MODE, {
+			.tv_enc_mode = { 720, 576, 50000, {
+					0x2a, 0x9, 0x8a, 0xcb, 0x0, 0x0, 0xb, 0x18,
+					0x7e, 0x40, 0x8a, 0x35, 0x27, 0x0, 0x34, 0x3,
+					0x3e, 0x3, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c,
+					0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x3,
+					0xd3, 0x4, 0xd4, 0x1, 0x2, 0x0, 0xa, 0x5,
+					0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0,
+					0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b,
+					0xbd, 0x15, 0x5, 0x15, 0x3e, 0x3, 0x0, 0x0
+				} } } },
+
+
+	[TV_NORM_HD480P] = { CTV_ENC_MODE, {
+			.ctv_enc_mode = {
+				.mode = { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000,
+						   720, 735, 743, 858, 0, 480, 490, 494, 525, 0,
+						   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+				.ctv_regs = { 0x3540000, 0x0, 0x0, 0x314,
+					      0x354003a, 0x40000, 0x6f0344, 0x18100000,
+					      0x10160004, 0x10060005, 0x1006000c, 0x10060020,
+					      0x10060021, 0x140e0022, 0x10060202, 0x1802020a,
+					      0x1810020b, 0x10000fff, 0x10000fff, 0x10000fff,
+					      0x10000fff, 0x10000fff, 0x10000fff, 0x70,
+					      0x3ff0000, 0x57, 0x2e001e, 0x258012c,
+					      0xa0aa04ec, 0x30, 0x80960019, 0x12c0300,
+					      0x2019, 0x600, 0x32060019, 0x0, 0x0, 0x400
+				} } } },
+
+	[TV_NORM_HD576P] = { CTV_ENC_MODE, {
+			.ctv_enc_mode = {
+				.mode = { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000,
+						   720, 730, 738, 864, 0, 576, 581, 585, 625, 0,
+						   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+				.ctv_regs = { 0x3540000, 0x0, 0x0, 0x314,
+					      0x354003a, 0x40000, 0x6f0344, 0x18100000,
+					      0x10060001, 0x10060009, 0x10060026, 0x10060027,
+					      0x140e0028, 0x10060268, 0x1810026d, 0x10000fff,
+					      0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff,
+					      0x10000fff, 0x10000fff, 0x10000fff, 0x69,
+					      0x3ff0000, 0x57, 0x2e001e, 0x258012c,
+					      0xa0aa04ec, 0x30, 0x80960019, 0x12c0300,
+					      0x2019, 0x600, 0x32060019, 0x0, 0x0, 0x400
+				} } } },
+
+	[TV_NORM_HD720P] = { CTV_ENC_MODE, {
+			.ctv_enc_mode = {
+				.mode = { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250,
+						   1280, 1349, 1357, 1650, 0, 720, 725, 730, 750, 0,
+						   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+				.ctv_regs = { 0x1260394, 0x0, 0x0, 0x622,
+					      0x66b0021, 0x6004a, 0x1210626, 0x8170000,
+					      0x70004, 0x70016, 0x70017, 0x40f0018,
+					      0x702e8, 0x81702ed, 0xfff, 0xfff,
+					      0xfff, 0xfff, 0xfff, 0xfff,
+					      0xfff, 0xfff, 0xfff, 0x0,
+					      0x2e40001, 0x58, 0x2e001e, 0x258012c,
+					      0xa0aa04ec, 0x30, 0x810c0039, 0x12c0300,
+					      0xc0002039, 0x600, 0x32060039, 0x0, 0x0, 0x0
+				} } } },
+
+	[TV_NORM_HD1080I] = { CTV_ENC_MODE, {
+			.ctv_enc_mode = {
+				.mode = { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250,
+						   1920, 1961, 2049, 2200, 0, 1080, 1084, 1088, 1125, 0,
+						   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC
+						   | DRM_MODE_FLAG_INTERLACE) },
+				.ctv_regs = { 0xac0420, 0x44c0478, 0x4a4, 0x4fc0868,
+					      0x8940028, 0x60054, 0xe80870, 0xbf70000,
+					      0xbc70004, 0x70005, 0x70012, 0x70013,
+					      0x40f0014, 0x70230, 0xbf70232, 0xbf70233,
+					      0x1c70237, 0x70238, 0x70244, 0x70245,
+					      0x40f0246, 0x70462, 0x1f70464, 0x0,
+					      0x2e40001, 0x58, 0x2e001e, 0x258012c,
+					      0xa0aa04ec, 0x30, 0x815f004c, 0x12c0300,
+					      0xc000204c, 0x600, 0x3206004c, 0x0, 0x0, 0x0
+				} } } }
+};
+
+/*
+ * The following is some guesswork on how the TV encoder flicker
+ * filter/rescaler works:
+ *
+ * It seems to use some sort of resampling filter, it is controlled
+ * through the registers at NV_PTV_HFILTER and NV_PTV_VFILTER, they
+ * control the horizontal and vertical stage respectively, there is
+ * also NV_PTV_HFILTER2 the blob fills identically to NV_PTV_HFILTER,
+ * but they seem to do nothing. A rough guess might be that they could
+ * be used to independently control the filtering of each interlaced
+ * field, but I don't know how they are enabled. The whole filtering
+ * process seems to be disabled with bits 26:27 of PTV_200, but we
+ * aren't doing that.
+ *
+ * The layout of both register sets is the same:
+ *
+ * A: [BASE+0x18]...[BASE+0x0] [BASE+0x58]..[BASE+0x40]
+ * B: [BASE+0x34]...[BASE+0x1c] [BASE+0x74]..[BASE+0x5c]
+ *
+ * Each coefficient is stored in bits [31],[15:9] in two's complement
+ * format. They seem to be some kind of weights used in a low-pass
+ * filter. Both A and B coefficients are applied to the 14 nearest
+ * samples on each side (Listed from nearest to furthermost.  They
+ * roughly cover 2 framebuffer pixels on each side).  They are
+ * probably multiplied with some more hardwired weights before being
+ * used: B-coefficients are applied the same on both sides,
+ * A-coefficients are inverted before being applied to the opposite
+ * side.
+ *
+ * After all the hassle, I got the following formula by empirical
+ * means...
+ */
+
+#define calc_overscan(o) interpolate(0x100, 0xe1, 0xc1, o)
+
+#define id1 (1LL << 8)
+#define id2 (1LL << 16)
+#define id3 (1LL << 24)
+#define id4 (1LL << 32)
+#define id5 (1LL << 48)
+
+static struct filter_params{
+	int64_t k1;
+	int64_t ki;
+	int64_t ki2;
+	int64_t ki3;
+	int64_t kr;
+	int64_t kir;
+	int64_t ki2r;
+	int64_t ki3r;
+	int64_t kf;
+	int64_t kif;
+	int64_t ki2f;
+	int64_t ki3f;
+	int64_t krf;
+	int64_t kirf;
+	int64_t ki2rf;
+	int64_t ki3rf;
+} fparams[2][4] = {
+	/* Horizontal filter parameters */
+	{
+		{64.311690 * id5, -39.516924 * id5, 6.586143 * id5, 0.000002 * id5,
+		 0.051285 * id4, 26.168746 * id4, -4.361449 * id4, -0.000001 * id4,
+		 9.308169 * id3, 78.180965 * id3, -13.030158 * id3, -0.000001 * id3,
+		 -8.801540 * id1, -46.572890 * id1, 7.762145 * id1, -0.000000 * id1},
+		{-44.565569 * id5, -68.081246 * id5, 39.812074 * id5, -4.009316 * id5,
+		 29.832207 * id4, 50.047322 * id4, -25.380017 * id4, 2.546422 * id4,
+		 104.605622 * id3, 141.908641 * id3, -74.322319 * id3, 7.484316 * id3,
+		 -37.081621 * id1, -90.397510 * id1, 42.784229 * id1, -4.289952 * id1},
+		{-56.793244 * id5, 31.153584 * id5, -5.192247 * id5, -0.000003 * id5,
+		 33.541131 * id4, -34.149302 * id4, 5.691537 * id4, 0.000002 * id4,
+		 87.196610 * id3, -88.995169 * id3, 14.832456 * id3, 0.000012 * id3,
+		 17.288138 * id1, 71.864786 * id1, -11.977408 * id1, -0.000009 * id1},
+		{51.787796 * id5, 21.211771 * id5, -18.993730 * id5, 1.853310 * id5,
+		 -41.470726 * id4, -17.775823 * id4, 13.057821 * id4, -1.15823 * id4,
+		 -154.235673 * id3, -44.878641 * id3, 40.656077 * id3, -3.695595 * id3,
+		 112.201065 * id1, 39.992155 * id1, -25.155714 * id1, 2.113984 * id1},
+	},
+
+	/* Vertical filter parameters */
+	{
+		{67.601979 * id5, 0.428319 * id5, -0.071318 * id5, -0.000012 * id5,
+		 -3.402339 * id4, 0.000209 * id4, -0.000092 * id4, 0.000010 * id4,
+		 -9.180996 * id3, 6.111270 * id3, -1.024457 * id3, 0.001043 * id3,
+		 6.060315 * id1, -0.017425 * id1, 0.007830 * id1, -0.000869 * id1},
+		{6.755647 * id5, 5.841348 * id5, 1.469734 * id5, -0.149656 * id5,
+		 8.293120 * id4, -1.192888 * id4, -0.947652 * id4, 0.094507 * id4,
+		 37.526655 * id3, 10.257875 * id3, -10.823275 * id3, 1.081497 * id3,
+		 -2.361928 * id1, -2.059432 * id1, 1.840671 * id1, -0.168100 * id1},
+		{-14.780391 * id5, -16.042148 * id5, 2.673692 * id5, -0.000000 * id5,
+		 39.541978 * id4, 5.680053 * id4, -0.946676 * id4, 0.000000 * id4,
+		 152.994486 * id3, 12.625439 * id3, -2.119579 * id3, 0.002708 * id3,
+		 -38.125089 * id1, -0.855880 * id1, 0.155359 * id1, -0.002245 * id1},
+		{-27.476193 * id5, -1.454976 * id5, 1.286557 * id5, 0.025346 * id5,
+		 20.687300 * id4, 3.014003 * id4, -0.557786 * id4, -0.01311 * id4,
+		 60.008737 * id3, -0.738273 * id3, 5.408217 * id3, -0.796798 * id3,
+		 -17.296835 * id1, 4.438577 * id1, -2.809420 * id1, 0.385491 * id1},
+	}
+};
+
+static void tv_setup_filter(struct drm_encoder *encoder)
+{
+	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
+	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
+	struct drm_display_mode *mode = &encoder->crtc->mode;
+	uint32_t (*filters[])[4][7] = {&tv_enc->state.hfilter,
+				       &tv_enc->state.vfilter};
+	int i, j, k;
+	int32_t overscan = calc_overscan(tv_enc->overscan);
+	int64_t flicker = (tv_enc->flicker - 50) * (id3 / 100);
+	uint64_t rs[] = {mode->hdisplay * id3,
+			 mode->vdisplay * id3};
+
+	do_div(rs[0], overscan * tv_norm->tv_enc_mode.hdisplay);
+	do_div(rs[1], overscan * tv_norm->tv_enc_mode.vdisplay);
+
+	for (k = 0; k < 2; k++) {
+		rs[k] = max((int64_t)rs[k], id2);
+
+		for (j = 0; j < 4; j++) {
+			struct filter_params *p = &fparams[k][j];
+
+			for (i = 0; i < 7; i++) {
+				int64_t c = (p->k1 + p->ki*i + p->ki2*i*i + p->ki3*i*i*i)
+					+ (p->kr + p->kir*i + p->ki2r*i*i + p->ki3r*i*i*i)*rs[k]
+					+ (p->kf + p->kif*i + p->ki2f*i*i + p->ki3f*i*i*i)*flicker
+					+ (p->krf + p->kirf*i + p->ki2rf*i*i + p->ki3rf*i*i*i)*flicker*rs[k];
+
+				(*filters[k])[j][i] = (c + id5/2) >> 39 & (0x1 << 31 | 0x7f << 9);
+			}
+		}
+	}
+}
+
+/* Hardware state saving/restoring */
+
+static void tv_save_filter(struct drm_device *dev, uint32_t base, uint32_t regs[4][7])
+{
+	int i, j;
+	uint32_t offsets[] = { base, base + 0x1c, base + 0x40, base + 0x5c };
+
+	for (i = 0; i < 4; i++) {
+		for (j = 0; j < 7; j++)
+			regs[i][j] = nv_read_ptv(dev, offsets[i]+4*j);
+	}
+}
+
+static void tv_load_filter(struct drm_device *dev, uint32_t base, uint32_t regs[4][7])
+{
+	int i, j;
+	uint32_t offsets[] = { base, base + 0x1c, base + 0x40, base + 0x5c };
+
+	for (i = 0; i < 4; i++) {
+		for (j = 0; j < 7; j++)
+			nv_write_ptv(dev, offsets[i]+4*j, regs[i][j]);
+	}
+}
+
+void nv17_tv_state_save(struct drm_device *dev, struct nv17_tv_state *state)
+{
+	int i;
+
+	for (i = 0; i < 0x40; i++)
+		state->tv_enc[i] = nv_read_tv_enc(dev, i);
+
+	tv_save_filter(dev, NV_PTV_HFILTER, state->hfilter);
+	tv_save_filter(dev, NV_PTV_HFILTER2, state->hfilter2);
+	tv_save_filter(dev, NV_PTV_VFILTER, state->vfilter);
+
+	nv_save_ptv(dev, state, 200);
+	nv_save_ptv(dev, state, 204);
+	nv_save_ptv(dev, state, 208);
+	nv_save_ptv(dev, state, 20c);
+	nv_save_ptv(dev, state, 304);
+	nv_save_ptv(dev, state, 500);
+	nv_save_ptv(dev, state, 504);
+	nv_save_ptv(dev, state, 508);
+	nv_save_ptv(dev, state, 600);
+	nv_save_ptv(dev, state, 604);
+	nv_save_ptv(dev, state, 608);
+	nv_save_ptv(dev, state, 60c);
+	nv_save_ptv(dev, state, 610);
+	nv_save_ptv(dev, state, 614);
+}
+
+void nv17_tv_state_load(struct drm_device *dev, struct nv17_tv_state *state)
+{
+	int i;
+
+	for (i = 0; i < 0x40; i++)
+		nv_write_tv_enc(dev, i, state->tv_enc[i]);
+
+	tv_load_filter(dev, NV_PTV_HFILTER, state->hfilter);
+	tv_load_filter(dev, NV_PTV_HFILTER2, state->hfilter2);
+	tv_load_filter(dev, NV_PTV_VFILTER, state->vfilter);
+
+	nv_load_ptv(dev, state, 200);
+	nv_load_ptv(dev, state, 204);
+	nv_load_ptv(dev, state, 208);
+	nv_load_ptv(dev, state, 20c);
+	nv_load_ptv(dev, state, 304);
+	nv_load_ptv(dev, state, 500);
+	nv_load_ptv(dev, state, 504);
+	nv_load_ptv(dev, state, 508);
+	nv_load_ptv(dev, state, 600);
+	nv_load_ptv(dev, state, 604);
+	nv_load_ptv(dev, state, 608);
+	nv_load_ptv(dev, state, 60c);
+	nv_load_ptv(dev, state, 610);
+	nv_load_ptv(dev, state, 614);
+
+	/* This is required for some settings to kick in. */
+	nv_write_tv_enc(dev, 0x3e, 1);
+	nv_write_tv_enc(dev, 0x3e, 0);
+}
+
+/* Timings similar to the ones the blob sets */
+
+struct drm_display_mode nv17_tv_modes[] = {
+	{ DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 0,
+		   320, 344, 392, 560, 0, 200, 200, 202, 220, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC
+		   | DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_CLKDIV2) },
+	{ DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 0,
+		   320, 344, 392, 560, 0, 240, 240, 246, 263, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC
+		   | DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_CLKDIV2) },
+	{ DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 0,
+		   400, 432, 496, 640, 0, 300, 300, 303, 314, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC
+		   | DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_CLKDIV2) },
+	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 0,
+		   640, 672, 768, 880, 0, 480, 480, 492, 525, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	{ DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 0,
+		   720, 752, 872, 960, 0, 480, 480, 493, 525, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	{ DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 0,
+		   720, 776, 856, 960, 0, 576, 576, 588, 597, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 0,
+		   800, 840, 920, 1040, 0, 600, 600, 604, 618, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 0,
+		   1024, 1064, 1200, 1344, 0, 768, 768, 777, 806, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	{}
+};
+
+void nv17_tv_update_properties(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
+	struct nv17_tv_state *regs = &tv_enc->state;
+	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
+	int subconnector = tv_enc->select_subconnector ?
+						tv_enc->select_subconnector :
+						tv_enc->subconnector;
+
+	switch (subconnector) {
+	case DRM_MODE_SUBCONNECTOR_Composite:
+	{
+		regs->ptv_204 = 0x2;
+
+		/* The composite connector may be found on either pin. */
+		if (tv_enc->pin_mask & 0x4)
+			regs->ptv_204 |= 0x010000;
+		else if (tv_enc->pin_mask & 0x2)
+			regs->ptv_204 |= 0x100000;
+		else
+			regs->ptv_204 |= 0x110000;
+
+		regs->tv_enc[0x7] = 0x10;
+		break;
+	}
+	case DRM_MODE_SUBCONNECTOR_SVIDEO:
+		regs->ptv_204 = 0x11012;
+		regs->tv_enc[0x7] = 0x18;
+		break;
+
+	case DRM_MODE_SUBCONNECTOR_Component:
+		regs->ptv_204 = 0x111333;
+		regs->tv_enc[0x7] = 0x14;
+		break;
+
+	case DRM_MODE_SUBCONNECTOR_SCART:
+		regs->ptv_204 = 0x111012;
+		regs->tv_enc[0x7] = 0x18;
+		break;
+	}
+
+	regs->tv_enc[0x20] = interpolate(0, tv_norm->tv_enc_mode.tv_enc[0x20], 255,
+					 tv_enc->saturation);
+	regs->tv_enc[0x22] = interpolate(0, tv_norm->tv_enc_mode.tv_enc[0x22], 255,
+					 tv_enc->saturation);
+	regs->tv_enc[0x25] = tv_enc->hue * 255 / 100;
+
+	nv_load_ptv(dev, regs, 204);
+	nv_load_tv_enc(dev, regs, 7);
+	nv_load_tv_enc(dev, regs, 20);
+	nv_load_tv_enc(dev, regs, 22);
+	nv_load_tv_enc(dev, regs, 25);
+}
+
+void nv17_tv_update_rescaler(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
+	struct nv17_tv_state *regs = &tv_enc->state;
+
+	regs->ptv_208 = 0x40 | (calc_overscan(tv_enc->overscan) << 8);
+
+	tv_setup_filter(encoder);
+
+	nv_load_ptv(dev, regs, 208);
+	tv_load_filter(dev, NV_PTV_HFILTER, regs->hfilter);
+	tv_load_filter(dev, NV_PTV_HFILTER2, regs->hfilter2);
+	tv_load_filter(dev, NV_PTV_VFILTER, regs->vfilter);
+}
+
+void nv17_ctv_update_rescaler(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
+	int head = nouveau_crtc(encoder->crtc)->index;
+	struct nv04_crtc_reg *regs = &dev_priv->mode_reg.crtc_reg[head];
+	struct drm_display_mode *crtc_mode = &encoder->crtc->mode;
+	struct drm_display_mode *output_mode = &get_tv_norm(encoder)->ctv_enc_mode.mode;
+	int overscan, hmargin, vmargin, hratio, vratio;
+
+	/* The rescaler doesn't do the right thing for interlaced modes. */
+	if (output_mode->flags & DRM_MODE_FLAG_INTERLACE)
+		overscan = 100;
+	else
+		overscan = tv_enc->overscan;
+
+	hmargin = (output_mode->hdisplay - crtc_mode->hdisplay) / 2;
+	vmargin = (output_mode->vdisplay - crtc_mode->vdisplay) / 2;
+
+	hmargin = interpolate(0, min(hmargin, output_mode->hdisplay/20), hmargin,
+			      overscan);
+	vmargin = interpolate(0, min(vmargin, output_mode->vdisplay/20), vmargin,
+			      overscan);
+
+	hratio = crtc_mode->hdisplay * 0x800 / (output_mode->hdisplay - 2*hmargin);
+	vratio = crtc_mode->vdisplay * 0x800 / (output_mode->vdisplay - 2*vmargin) & ~3;
+
+	regs->fp_horiz_regs[FP_VALID_START] = hmargin;
+	regs->fp_horiz_regs[FP_VALID_END] = output_mode->hdisplay - hmargin - 1;
+	regs->fp_vert_regs[FP_VALID_START] = vmargin;
+	regs->fp_vert_regs[FP_VALID_END] = output_mode->vdisplay - vmargin - 1;
+
+	regs->fp_debug_1 = NV_PRAMDAC_FP_DEBUG_1_YSCALE_TESTMODE_ENABLE |
+		XLATE(vratio, 0, NV_PRAMDAC_FP_DEBUG_1_YSCALE_VALUE) |
+		NV_PRAMDAC_FP_DEBUG_1_XSCALE_TESTMODE_ENABLE |
+		XLATE(hratio, 0, NV_PRAMDAC_FP_DEBUG_1_XSCALE_VALUE);
+
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HVALID_START,
+		      regs->fp_horiz_regs[FP_VALID_START]);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HVALID_END,
+		      regs->fp_horiz_regs[FP_VALID_END]);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_VVALID_START,
+		      regs->fp_vert_regs[FP_VALID_START]);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_VVALID_END,
+		      regs->fp_vert_regs[FP_VALID_END]);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_1, regs->fp_debug_1);
+}
diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c b/drivers/gpu/drm/nouveau/nv20_graph.c
new file mode 100644
index 0000000..18ba74f
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv20_graph.c
@@ -0,0 +1,780 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+/*
+ * NV20
+ * -----
+ * There are 3 families :
+ * NV20 is 0x10de:0x020*
+ * NV25/28 is 0x10de:0x025* / 0x10de:0x028*
+ * NV2A is 0x10de:0x02A0
+ *
+ * NV30
+ * -----
+ * There are 3 families :
+ * NV30/31 is 0x10de:0x030* / 0x10de:0x031*
+ * NV34 is 0x10de:0x032*
+ * NV35/36 is 0x10de:0x033* / 0x10de:0x034*
+ *
+ * Not seen in the wild, no dumps (probably NV35) :
+ * NV37 is 0x10de:0x00fc, 0x10de:0x00fd
+ * NV38 is 0x10de:0x0333, 0x10de:0x00fe
+ *
+ */
+
+#define NV20_GRCTX_SIZE (3580*4)
+#define NV25_GRCTX_SIZE (3529*4)
+#define NV2A_GRCTX_SIZE (3500*4)
+
+#define NV30_31_GRCTX_SIZE (24392)
+#define NV34_GRCTX_SIZE    (18140)
+#define NV35_36_GRCTX_SIZE (22396)
+
+static void
+nv20_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
+{
+	int i;
+
+	nv_wo32(dev, ctx, 0x033c/4, 0xffff0000);
+	nv_wo32(dev, ctx, 0x03a0/4, 0x0fff0000);
+	nv_wo32(dev, ctx, 0x03a4/4, 0x0fff0000);
+	nv_wo32(dev, ctx, 0x047c/4, 0x00000101);
+	nv_wo32(dev, ctx, 0x0490/4, 0x00000111);
+	nv_wo32(dev, ctx, 0x04a8/4, 0x44400000);
+	for (i = 0x04d4; i <= 0x04e0; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00030303);
+	for (i = 0x04f4; i <= 0x0500; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00080000);
+	for (i = 0x050c; i <= 0x0518; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x01012000);
+	for (i = 0x051c; i <= 0x0528; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x000105b8);
+	for (i = 0x052c; i <= 0x0538; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00080008);
+	for (i = 0x055c; i <= 0x0598; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x07ff0000);
+	nv_wo32(dev, ctx, 0x05a4/4, 0x4b7fffff);
+	nv_wo32(dev, ctx, 0x05fc/4, 0x00000001);
+	nv_wo32(dev, ctx, 0x0604/4, 0x00004000);
+	nv_wo32(dev, ctx, 0x0610/4, 0x00000001);
+	nv_wo32(dev, ctx, 0x0618/4, 0x00040000);
+	nv_wo32(dev, ctx, 0x061c/4, 0x00010000);
+	for (i = 0x1c1c; i <= 0x248c; i += 16) {
+		nv_wo32(dev, ctx, (i + 0)/4, 0x10700ff9);
+		nv_wo32(dev, ctx, (i + 4)/4, 0x0436086c);
+		nv_wo32(dev, ctx, (i + 8)/4, 0x000c001b);
+	}
+	nv_wo32(dev, ctx, 0x281c/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x2830/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x285c/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x2860/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x2864/4, 0x3f000000);
+	nv_wo32(dev, ctx, 0x286c/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x2870/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x2878/4, 0xbf800000);
+	nv_wo32(dev, ctx, 0x2880/4, 0xbf800000);
+	nv_wo32(dev, ctx, 0x34a4/4, 0x000fe000);
+	nv_wo32(dev, ctx, 0x3530/4, 0x000003f8);
+	nv_wo32(dev, ctx, 0x3540/4, 0x002fe000);
+	for (i = 0x355c; i <= 0x3578; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x001c527c);
+}
+
+static void
+nv25_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
+{
+	int i;
+
+	nv_wo32(dev, ctx, 0x035c/4, 0xffff0000);
+	nv_wo32(dev, ctx, 0x03c0/4, 0x0fff0000);
+	nv_wo32(dev, ctx, 0x03c4/4, 0x0fff0000);
+	nv_wo32(dev, ctx, 0x049c/4, 0x00000101);
+	nv_wo32(dev, ctx, 0x04b0/4, 0x00000111);
+	nv_wo32(dev, ctx, 0x04c8/4, 0x00000080);
+	nv_wo32(dev, ctx, 0x04cc/4, 0xffff0000);
+	nv_wo32(dev, ctx, 0x04d0/4, 0x00000001);
+	nv_wo32(dev, ctx, 0x04e4/4, 0x44400000);
+	nv_wo32(dev, ctx, 0x04fc/4, 0x4b800000);
+	for (i = 0x0510; i <= 0x051c; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00030303);
+	for (i = 0x0530; i <= 0x053c; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00080000);
+	for (i = 0x0548; i <= 0x0554; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x01012000);
+	for (i = 0x0558; i <= 0x0564; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x000105b8);
+	for (i = 0x0568; i <= 0x0574; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00080008);
+	for (i = 0x0598; i <= 0x05d4; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x07ff0000);
+	nv_wo32(dev, ctx, 0x05e0/4, 0x4b7fffff);
+	nv_wo32(dev, ctx, 0x0620/4, 0x00000080);
+	nv_wo32(dev, ctx, 0x0624/4, 0x30201000);
+	nv_wo32(dev, ctx, 0x0628/4, 0x70605040);
+	nv_wo32(dev, ctx, 0x062c/4, 0xb0a09080);
+	nv_wo32(dev, ctx, 0x0630/4, 0xf0e0d0c0);
+	nv_wo32(dev, ctx, 0x0664/4, 0x00000001);
+	nv_wo32(dev, ctx, 0x066c/4, 0x00004000);
+	nv_wo32(dev, ctx, 0x0678/4, 0x00000001);
+	nv_wo32(dev, ctx, 0x0680/4, 0x00040000);
+	nv_wo32(dev, ctx, 0x0684/4, 0x00010000);
+	for (i = 0x1b04; i <= 0x2374; i += 16) {
+		nv_wo32(dev, ctx, (i + 0)/4, 0x10700ff9);
+		nv_wo32(dev, ctx, (i + 4)/4, 0x0436086c);
+		nv_wo32(dev, ctx, (i + 8)/4, 0x000c001b);
+	}
+	nv_wo32(dev, ctx, 0x2704/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x2718/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x2744/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x2748/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x274c/4, 0x3f000000);
+	nv_wo32(dev, ctx, 0x2754/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x2758/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x2760/4, 0xbf800000);
+	nv_wo32(dev, ctx, 0x2768/4, 0xbf800000);
+	nv_wo32(dev, ctx, 0x308c/4, 0x000fe000);
+	nv_wo32(dev, ctx, 0x3108/4, 0x000003f8);
+	nv_wo32(dev, ctx, 0x3468/4, 0x002fe000);
+	for (i = 0x3484; i <= 0x34a0; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x001c527c);
+}
+
+static void
+nv2a_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
+{
+	int i;
+
+	nv_wo32(dev, ctx, 0x033c/4, 0xffff0000);
+	nv_wo32(dev, ctx, 0x03a0/4, 0x0fff0000);
+	nv_wo32(dev, ctx, 0x03a4/4, 0x0fff0000);
+	nv_wo32(dev, ctx, 0x047c/4, 0x00000101);
+	nv_wo32(dev, ctx, 0x0490/4, 0x00000111);
+	nv_wo32(dev, ctx, 0x04a8/4, 0x44400000);
+	for (i = 0x04d4; i <= 0x04e0; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00030303);
+	for (i = 0x04f4; i <= 0x0500; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00080000);
+	for (i = 0x050c; i <= 0x0518; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x01012000);
+	for (i = 0x051c; i <= 0x0528; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x000105b8);
+	for (i = 0x052c; i <= 0x0538; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00080008);
+	for (i = 0x055c; i <= 0x0598; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x07ff0000);
+	nv_wo32(dev, ctx, 0x05a4/4, 0x4b7fffff);
+	nv_wo32(dev, ctx, 0x05fc/4, 0x00000001);
+	nv_wo32(dev, ctx, 0x0604/4, 0x00004000);
+	nv_wo32(dev, ctx, 0x0610/4, 0x00000001);
+	nv_wo32(dev, ctx, 0x0618/4, 0x00040000);
+	nv_wo32(dev, ctx, 0x061c/4, 0x00010000);
+	for (i = 0x1a9c; i <= 0x22fc; i += 16) { /*XXX: check!! */
+		nv_wo32(dev, ctx, (i + 0)/4, 0x10700ff9);
+		nv_wo32(dev, ctx, (i + 4)/4, 0x0436086c);
+		nv_wo32(dev, ctx, (i + 8)/4, 0x000c001b);
+	}
+	nv_wo32(dev, ctx, 0x269c/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x26b0/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x26dc/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x26e0/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x26e4/4, 0x3f000000);
+	nv_wo32(dev, ctx, 0x26ec/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x26f0/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x26f8/4, 0xbf800000);
+	nv_wo32(dev, ctx, 0x2700/4, 0xbf800000);
+	nv_wo32(dev, ctx, 0x3024/4, 0x000fe000);
+	nv_wo32(dev, ctx, 0x30a0/4, 0x000003f8);
+	nv_wo32(dev, ctx, 0x33fc/4, 0x002fe000);
+	for (i = 0x341c; i <= 0x3438; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x001c527c);
+}
+
+static void
+nv30_31_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
+{
+	int i;
+
+	nv_wo32(dev, ctx, 0x0410/4, 0x00000101);
+	nv_wo32(dev, ctx, 0x0424/4, 0x00000111);
+	nv_wo32(dev, ctx, 0x0428/4, 0x00000060);
+	nv_wo32(dev, ctx, 0x0444/4, 0x00000080);
+	nv_wo32(dev, ctx, 0x0448/4, 0xffff0000);
+	nv_wo32(dev, ctx, 0x044c/4, 0x00000001);
+	nv_wo32(dev, ctx, 0x0460/4, 0x44400000);
+	nv_wo32(dev, ctx, 0x048c/4, 0xffff0000);
+	for (i = 0x04e0; i < 0x04e8; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x0fff0000);
+	nv_wo32(dev, ctx, 0x04ec/4, 0x00011100);
+	for (i = 0x0508; i < 0x0548; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x07ff0000);
+	nv_wo32(dev, ctx, 0x0550/4, 0x4b7fffff);
+	nv_wo32(dev, ctx, 0x058c/4, 0x00000080);
+	nv_wo32(dev, ctx, 0x0590/4, 0x30201000);
+	nv_wo32(dev, ctx, 0x0594/4, 0x70605040);
+	nv_wo32(dev, ctx, 0x0598/4, 0xb8a89888);
+	nv_wo32(dev, ctx, 0x059c/4, 0xf8e8d8c8);
+	nv_wo32(dev, ctx, 0x05b0/4, 0xb0000000);
+	for (i = 0x0600; i < 0x0640; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00010588);
+	for (i = 0x0640; i < 0x0680; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00030303);
+	for (i = 0x06c0; i < 0x0700; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x0008aae4);
+	for (i = 0x0700; i < 0x0740; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x01012000);
+	for (i = 0x0740; i < 0x0780; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00080008);
+	nv_wo32(dev, ctx, 0x085c/4, 0x00040000);
+	nv_wo32(dev, ctx, 0x0860/4, 0x00010000);
+	for (i = 0x0864; i < 0x0874; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00040004);
+	for (i = 0x1f18; i <= 0x3088 ; i += 16) {
+		nv_wo32(dev, ctx, i/4 + 0, 0x10700ff9);
+		nv_wo32(dev, ctx, i/4 + 1, 0x0436086c);
+		nv_wo32(dev, ctx, i/4 + 2, 0x000c001b);
+	}
+	for (i = 0x30b8; i < 0x30c8; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x0000ffff);
+	nv_wo32(dev, ctx, 0x344c/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x3808/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x381c/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x3848/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x384c/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x3850/4, 0x3f000000);
+	nv_wo32(dev, ctx, 0x3858/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x385c/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x3864/4, 0xbf800000);
+	nv_wo32(dev, ctx, 0x386c/4, 0xbf800000);
+}
+
+static void
+nv34_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
+{
+	int i;
+
+	nv_wo32(dev, ctx, 0x040c/4, 0x01000101);
+	nv_wo32(dev, ctx, 0x0420/4, 0x00000111);
+	nv_wo32(dev, ctx, 0x0424/4, 0x00000060);
+	nv_wo32(dev, ctx, 0x0440/4, 0x00000080);
+	nv_wo32(dev, ctx, 0x0444/4, 0xffff0000);
+	nv_wo32(dev, ctx, 0x0448/4, 0x00000001);
+	nv_wo32(dev, ctx, 0x045c/4, 0x44400000);
+	nv_wo32(dev, ctx, 0x0480/4, 0xffff0000);
+	for (i = 0x04d4; i < 0x04dc; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x0fff0000);
+	nv_wo32(dev, ctx, 0x04e0/4, 0x00011100);
+	for (i = 0x04fc; i < 0x053c; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x07ff0000);
+	nv_wo32(dev, ctx, 0x0544/4, 0x4b7fffff);
+	nv_wo32(dev, ctx, 0x057c/4, 0x00000080);
+	nv_wo32(dev, ctx, 0x0580/4, 0x30201000);
+	nv_wo32(dev, ctx, 0x0584/4, 0x70605040);
+	nv_wo32(dev, ctx, 0x0588/4, 0xb8a89888);
+	nv_wo32(dev, ctx, 0x058c/4, 0xf8e8d8c8);
+	nv_wo32(dev, ctx, 0x05a0/4, 0xb0000000);
+	for (i = 0x05f0; i < 0x0630; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00010588);
+	for (i = 0x0630; i < 0x0670; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00030303);
+	for (i = 0x06b0; i < 0x06f0; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x0008aae4);
+	for (i = 0x06f0; i < 0x0730; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x01012000);
+	for (i = 0x0730; i < 0x0770; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00080008);
+	nv_wo32(dev, ctx, 0x0850/4, 0x00040000);
+	nv_wo32(dev, ctx, 0x0854/4, 0x00010000);
+	for (i = 0x0858; i < 0x0868; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00040004);
+	for (i = 0x15ac; i <= 0x271c ; i += 16) {
+		nv_wo32(dev, ctx, i/4 + 0, 0x10700ff9);
+		nv_wo32(dev, ctx, i/4 + 1, 0x0436086c);
+		nv_wo32(dev, ctx, i/4 + 2, 0x000c001b);
+	}
+	for (i = 0x274c; i < 0x275c; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x0000ffff);
+	nv_wo32(dev, ctx, 0x2ae0/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x2e9c/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x2eb0/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x2edc/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x2ee0/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x2ee4/4, 0x3f000000);
+	nv_wo32(dev, ctx, 0x2eec/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x2ef0/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x2ef8/4, 0xbf800000);
+	nv_wo32(dev, ctx, 0x2f00/4, 0xbf800000);
+}
+
+static void
+nv35_36_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
+{
+	int i;
+
+	nv_wo32(dev, ctx, 0x040c/4, 0x00000101);
+	nv_wo32(dev, ctx, 0x0420/4, 0x00000111);
+	nv_wo32(dev, ctx, 0x0424/4, 0x00000060);
+	nv_wo32(dev, ctx, 0x0440/4, 0x00000080);
+	nv_wo32(dev, ctx, 0x0444/4, 0xffff0000);
+	nv_wo32(dev, ctx, 0x0448/4, 0x00000001);
+	nv_wo32(dev, ctx, 0x045c/4, 0x44400000);
+	nv_wo32(dev, ctx, 0x0488/4, 0xffff0000);
+	for (i = 0x04dc; i < 0x04e4; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x0fff0000);
+	nv_wo32(dev, ctx, 0x04e8/4, 0x00011100);
+	for (i = 0x0504; i < 0x0544; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x07ff0000);
+	nv_wo32(dev, ctx, 0x054c/4, 0x4b7fffff);
+	nv_wo32(dev, ctx, 0x0588/4, 0x00000080);
+	nv_wo32(dev, ctx, 0x058c/4, 0x30201000);
+	nv_wo32(dev, ctx, 0x0590/4, 0x70605040);
+	nv_wo32(dev, ctx, 0x0594/4, 0xb8a89888);
+	nv_wo32(dev, ctx, 0x0598/4, 0xf8e8d8c8);
+	nv_wo32(dev, ctx, 0x05ac/4, 0xb0000000);
+	for (i = 0x0604; i < 0x0644; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00010588);
+	for (i = 0x0644; i < 0x0684; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00030303);
+	for (i = 0x06c4; i < 0x0704; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x0008aae4);
+	for (i = 0x0704; i < 0x0744; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x01012000);
+	for (i = 0x0744; i < 0x0784; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00080008);
+	nv_wo32(dev, ctx, 0x0860/4, 0x00040000);
+	nv_wo32(dev, ctx, 0x0864/4, 0x00010000);
+	for (i = 0x0868; i < 0x0878; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00040004);
+	for (i = 0x1f1c; i <= 0x308c ; i += 16) {
+		nv_wo32(dev, ctx, i/4 + 0, 0x10700ff9);
+		nv_wo32(dev, ctx, i/4 + 1, 0x0436086c);
+		nv_wo32(dev, ctx, i/4 + 2, 0x000c001b);
+	}
+	for (i = 0x30bc; i < 0x30cc; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x0000ffff);
+	nv_wo32(dev, ctx, 0x3450/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x380c/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x3820/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x384c/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x3850/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x3854/4, 0x3f000000);
+	nv_wo32(dev, ctx, 0x385c/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x3860/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x3868/4, 0xbf800000);
+	nv_wo32(dev, ctx, 0x3870/4, 0xbf800000);
+}
+
+int
+nv20_graph_create_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	void (*ctx_init)(struct drm_device *, struct nouveau_gpuobj *);
+	unsigned int ctx_size;
+	unsigned int idoffs = 0x28/4;
+	int ret;
+
+	switch (dev_priv->chipset) {
+	case 0x20:
+		ctx_size = NV20_GRCTX_SIZE;
+		ctx_init = nv20_graph_context_init;
+		idoffs = 0;
+		break;
+	case 0x25:
+	case 0x28:
+		ctx_size = NV25_GRCTX_SIZE;
+		ctx_init = nv25_graph_context_init;
+		break;
+	case 0x2a:
+		ctx_size = NV2A_GRCTX_SIZE;
+		ctx_init = nv2a_graph_context_init;
+		idoffs = 0;
+		break;
+	case 0x30:
+	case 0x31:
+		ctx_size = NV30_31_GRCTX_SIZE;
+		ctx_init = nv30_31_graph_context_init;
+		break;
+	case 0x34:
+		ctx_size = NV34_GRCTX_SIZE;
+		ctx_init = nv34_graph_context_init;
+		break;
+	case 0x35:
+	case 0x36:
+		ctx_size = NV35_36_GRCTX_SIZE;
+		ctx_init = nv35_36_graph_context_init;
+		break;
+	default:
+		ctx_size = 0;
+		ctx_init = nv35_36_graph_context_init;
+		NV_ERROR(dev, "Please contact the devs if you want your NV%x"
+			      " card to work\n", dev_priv->chipset);
+		return -ENOSYS;
+		break;
+	}
+
+	ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, ctx_size, 16,
+					  NVOBJ_FLAG_ZERO_ALLOC,
+					  &chan->ramin_grctx);
+	if (ret)
+		return ret;
+
+	/* Initialise default context values */
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	ctx_init(dev, chan->ramin_grctx->gpuobj);
+
+	/* nv20: nv_wo32(dev, chan->ramin_grctx->gpuobj, 10, chan->id<<24); */
+	nv_wo32(dev, chan->ramin_grctx->gpuobj, idoffs,
+					(chan->id << 24) | 0x1); /* CTX_USER */
+
+	nv_wo32(dev, dev_priv->ctx_table->gpuobj, chan->id,
+			chan->ramin_grctx->instance >> 4);
+
+	dev_priv->engine.instmem.finish_access(dev);
+	return 0;
+}
+
+void
+nv20_graph_destroy_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (chan->ramin_grctx)
+		nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx);
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	nv_wo32(dev, dev_priv->ctx_table->gpuobj, chan->id, 0);
+	dev_priv->engine.instmem.finish_access(dev);
+}
+
+int
+nv20_graph_load_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	uint32_t inst;
+
+	if (!chan->ramin_grctx)
+		return -EINVAL;
+	inst = chan->ramin_grctx->instance >> 4;
+
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, inst);
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_XFER,
+		     NV20_PGRAPH_CHANNEL_CTX_XFER_LOAD);
+	nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100);
+
+	nouveau_wait_for_idle(dev);
+	return 0;
+}
+
+int
+nv20_graph_unload_context(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	struct nouveau_channel *chan;
+	uint32_t inst, tmp;
+
+	chan = pgraph->channel(dev);
+	if (!chan)
+		return 0;
+	inst = chan->ramin_grctx->instance >> 4;
+
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, inst);
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_XFER,
+		     NV20_PGRAPH_CHANNEL_CTX_XFER_SAVE);
+
+	nouveau_wait_for_idle(dev);
+
+	nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000000);
+	tmp  = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
+	tmp |= (pfifo->channels - 1) << 24;
+	nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp);
+	return 0;
+}
+
+static void
+nv20_graph_rdi(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int i, writecount = 32;
+	uint32_t rdi_index = 0x2c80000;
+
+	if (dev_priv->chipset == 0x20) {
+		rdi_index = 0x3d0000;
+		writecount = 15;
+	}
+
+	nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, rdi_index);
+	for (i = 0; i < writecount; i++)
+		nv_wr32(dev, NV10_PGRAPH_RDI_DATA, 0);
+
+	nouveau_wait_for_idle(dev);
+}
+
+int
+nv20_graph_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv =
+		(struct drm_nouveau_private *)dev->dev_private;
+	uint32_t tmp, vramsz;
+	int ret, i;
+
+	nv_wr32(dev, NV03_PMC_ENABLE,
+		nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH);
+	nv_wr32(dev, NV03_PMC_ENABLE,
+		nv_rd32(dev, NV03_PMC_ENABLE) |  NV_PMC_ENABLE_PGRAPH);
+
+	if (!dev_priv->ctx_table) {
+		/* Create Context Pointer Table */
+		dev_priv->ctx_table_size = 32 * 4;
+		ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0,
+						  dev_priv->ctx_table_size, 16,
+						  NVOBJ_FLAG_ZERO_ALLOC,
+						  &dev_priv->ctx_table);
+		if (ret)
+			return ret;
+	}
+
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE,
+		 dev_priv->ctx_table->instance >> 4);
+
+	nv20_graph_rdi(dev);
+
+	nv_wr32(dev, NV03_PGRAPH_INTR   , 0xFFFFFFFF);
+	nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
+
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x00118700);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xF3CE0475); /* 0x4 = auto ctx switch */
+	nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000);
+	nv_wr32(dev, 0x40009C           , 0x00000040);
+
+	if (dev_priv->chipset >= 0x25) {
+		nv_wr32(dev, 0x400890, 0x00080000);
+		nv_wr32(dev, 0x400610, 0x304B1FB6);
+		nv_wr32(dev, 0x400B80, 0x18B82880);
+		nv_wr32(dev, 0x400B84, 0x44000000);
+		nv_wr32(dev, 0x400098, 0x40000080);
+		nv_wr32(dev, 0x400B88, 0x000000ff);
+	} else {
+		nv_wr32(dev, 0x400880, 0x00080000); /* 0x0008c7df */
+		nv_wr32(dev, 0x400094, 0x00000005);
+		nv_wr32(dev, 0x400B80, 0x45CAA208); /* 0x45eae20e */
+		nv_wr32(dev, 0x400B84, 0x24000000);
+		nv_wr32(dev, 0x400098, 0x00000040);
+		nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00E00038);
+		nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000030);
+		nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00E10038);
+		nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000030);
+	}
+
+	/* copy tile info from PFB */
+	for (i = 0; i < NV10_PFB_TILE__SIZE; i++) {
+		nv_wr32(dev, 0x00400904 + i * 0x10,
+					nv_rd32(dev, NV10_PFB_TLIMIT(i)));
+			/* which is NV40_PGRAPH_TLIMIT0(i) ?? */
+		nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0030 + i * 4);
+		nv_wr32(dev, NV10_PGRAPH_RDI_DATA,
+					nv_rd32(dev, NV10_PFB_TLIMIT(i)));
+		nv_wr32(dev, 0x00400908 + i * 0x10,
+					nv_rd32(dev, NV10_PFB_TSIZE(i)));
+			/* which is NV40_PGRAPH_TSIZE0(i) ?? */
+		nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0050 + i * 4);
+		nv_wr32(dev, NV10_PGRAPH_RDI_DATA,
+					nv_rd32(dev, NV10_PFB_TSIZE(i)));
+		nv_wr32(dev, 0x00400900 + i * 0x10,
+					nv_rd32(dev, NV10_PFB_TILE(i)));
+			/* which is NV40_PGRAPH_TILE0(i) ?? */
+		nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0010 + i * 4);
+		nv_wr32(dev, NV10_PGRAPH_RDI_DATA,
+					nv_rd32(dev, NV10_PFB_TILE(i)));
+	}
+	for (i = 0; i < 8; i++) {
+		nv_wr32(dev, 0x400980 + i * 4, nv_rd32(dev, 0x100300 + i * 4));
+		nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0090 + i * 4);
+		nv_wr32(dev, NV10_PGRAPH_RDI_DATA,
+					nv_rd32(dev, 0x100300 + i * 4));
+	}
+	nv_wr32(dev, 0x4009a0, nv_rd32(dev, 0x100324));
+	nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA000C);
+	nv_wr32(dev, NV10_PGRAPH_RDI_DATA, nv_rd32(dev, 0x100324));
+
+	nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
+	nv_wr32(dev, NV10_PGRAPH_STATE      , 0xFFFFFFFF);
+
+	tmp = nv_rd32(dev, NV10_PGRAPH_SURFACE) & 0x0007ff00;
+	nv_wr32(dev, NV10_PGRAPH_SURFACE, tmp);
+	tmp = nv_rd32(dev, NV10_PGRAPH_SURFACE) | 0x00020100;
+	nv_wr32(dev, NV10_PGRAPH_SURFACE, tmp);
+
+	/* begin RAM config */
+	vramsz = drm_get_resource_len(dev, 0) - 1;
+	nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0));
+	nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1));
+	nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0000);
+	nv_wr32(dev, NV10_PGRAPH_RDI_DATA , nv_rd32(dev, NV04_PFB_CFG0));
+	nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0004);
+	nv_wr32(dev, NV10_PGRAPH_RDI_DATA , nv_rd32(dev, NV04_PFB_CFG1));
+	nv_wr32(dev, 0x400820, 0);
+	nv_wr32(dev, 0x400824, 0);
+	nv_wr32(dev, 0x400864, vramsz - 1);
+	nv_wr32(dev, 0x400868, vramsz - 1);
+
+	/* interesting.. the below overwrites some of the tile setup above.. */
+	nv_wr32(dev, 0x400B20, 0x00000000);
+	nv_wr32(dev, 0x400B04, 0xFFFFFFFF);
+
+	nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_XMIN, 0);
+	nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_YMIN, 0);
+	nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_XMAX, 0x7fff);
+	nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_YMAX, 0x7fff);
+
+	return 0;
+}
+
+void
+nv20_graph_takedown(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	nouveau_gpuobj_ref_del(dev, &dev_priv->ctx_table);
+}
+
+int
+nv30_graph_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int ret, i;
+
+	nv_wr32(dev, NV03_PMC_ENABLE,
+		nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH);
+	nv_wr32(dev, NV03_PMC_ENABLE,
+		nv_rd32(dev, NV03_PMC_ENABLE) |  NV_PMC_ENABLE_PGRAPH);
+
+	if (!dev_priv->ctx_table) {
+		/* Create Context Pointer Table */
+		dev_priv->ctx_table_size = 32 * 4;
+		ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0,
+						  dev_priv->ctx_table_size, 16,
+						  NVOBJ_FLAG_ZERO_ALLOC,
+						  &dev_priv->ctx_table);
+		if (ret)
+			return ret;
+	}
+
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE,
+			dev_priv->ctx_table->instance >> 4);
+
+	nv_wr32(dev, NV03_PGRAPH_INTR   , 0xFFFFFFFF);
+	nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
+
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x401287c0);
+	nv_wr32(dev, 0x400890, 0x01b463ff);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xf2de0475);
+	nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00008000);
+	nv_wr32(dev, NV04_PGRAPH_LIMIT_VIOL_PIX, 0xf04bdff6);
+	nv_wr32(dev, 0x400B80, 0x1003d888);
+	nv_wr32(dev, 0x400B84, 0x0c000000);
+	nv_wr32(dev, 0x400098, 0x00000000);
+	nv_wr32(dev, 0x40009C, 0x0005ad00);
+	nv_wr32(dev, 0x400B88, 0x62ff00ff); /* suspiciously like PGRAPH_DEBUG_2 */
+	nv_wr32(dev, 0x4000a0, 0x00000000);
+	nv_wr32(dev, 0x4000a4, 0x00000008);
+	nv_wr32(dev, 0x4008a8, 0xb784a400);
+	nv_wr32(dev, 0x400ba0, 0x002f8685);
+	nv_wr32(dev, 0x400ba4, 0x00231f3f);
+	nv_wr32(dev, 0x4008a4, 0x40000020);
+
+	if (dev_priv->chipset == 0x34) {
+		nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0004);
+		nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00200201);
+		nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0008);
+		nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000008);
+		nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0000);
+		nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000032);
+		nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00E00004);
+		nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000002);
+	}
+
+	nv_wr32(dev, 0x4000c0, 0x00000016);
+
+	/* copy tile info from PFB */
+	for (i = 0; i < NV10_PFB_TILE__SIZE; i++) {
+		nv_wr32(dev, 0x00400904 + i * 0x10,
+					nv_rd32(dev, NV10_PFB_TLIMIT(i)));
+			/* which is NV40_PGRAPH_TLIMIT0(i) ?? */
+		nv_wr32(dev, 0x00400908 + i * 0x10,
+					nv_rd32(dev, NV10_PFB_TSIZE(i)));
+			/* which is NV40_PGRAPH_TSIZE0(i) ?? */
+		nv_wr32(dev, 0x00400900 + i * 0x10,
+					nv_rd32(dev, NV10_PFB_TILE(i)));
+			/* which is NV40_PGRAPH_TILE0(i) ?? */
+	}
+
+	nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
+	nv_wr32(dev, NV10_PGRAPH_STATE      , 0xFFFFFFFF);
+	nv_wr32(dev, 0x0040075c             , 0x00000001);
+
+	/* begin RAM config */
+	/* vramsz = drm_get_resource_len(dev, 0) - 1; */
+	nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0));
+	nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1));
+	if (dev_priv->chipset != 0x34) {
+		nv_wr32(dev, 0x400750, 0x00EA0000);
+		nv_wr32(dev, 0x400754, nv_rd32(dev, NV04_PFB_CFG0));
+		nv_wr32(dev, 0x400750, 0x00EA0004);
+		nv_wr32(dev, 0x400754, nv_rd32(dev, NV04_PFB_CFG1));
+	}
+
+	return 0;
+}
+
+struct nouveau_pgraph_object_class nv20_graph_grclass[] = {
+	{ 0x0030, false, NULL }, /* null */
+	{ 0x0039, false, NULL }, /* m2mf */
+	{ 0x004a, false, NULL }, /* gdirect */
+	{ 0x009f, false, NULL }, /* imageblit (nv12) */
+	{ 0x008a, false, NULL }, /* ifc */
+	{ 0x0089, false, NULL }, /* sifm */
+	{ 0x0062, false, NULL }, /* surf2d */
+	{ 0x0043, false, NULL }, /* rop */
+	{ 0x0012, false, NULL }, /* beta1 */
+	{ 0x0072, false, NULL }, /* beta4 */
+	{ 0x0019, false, NULL }, /* cliprect */
+	{ 0x0044, false, NULL }, /* pattern */
+	{ 0x009e, false, NULL }, /* swzsurf */
+	{ 0x0096, false, NULL }, /* celcius */
+	{ 0x0097, false, NULL }, /* kelvin (nv20) */
+	{ 0x0597, false, NULL }, /* kelvin (nv25) */
+	{}
+};
+
+struct nouveau_pgraph_object_class nv30_graph_grclass[] = {
+	{ 0x0030, false, NULL }, /* null */
+	{ 0x0039, false, NULL }, /* m2mf */
+	{ 0x004a, false, NULL }, /* gdirect */
+	{ 0x009f, false, NULL }, /* imageblit (nv12) */
+	{ 0x008a, false, NULL }, /* ifc */
+	{ 0x038a, false, NULL }, /* ifc (nv30) */
+	{ 0x0089, false, NULL }, /* sifm */
+	{ 0x0389, false, NULL }, /* sifm (nv30) */
+	{ 0x0062, false, NULL }, /* surf2d */
+	{ 0x0362, false, NULL }, /* surf2d (nv30) */
+	{ 0x0043, false, NULL }, /* rop */
+	{ 0x0012, false, NULL }, /* beta1 */
+	{ 0x0072, false, NULL }, /* beta4 */
+	{ 0x0019, false, NULL }, /* cliprect */
+	{ 0x0044, false, NULL }, /* pattern */
+	{ 0x039e, false, NULL }, /* swzsurf */
+	{ 0x0397, false, NULL }, /* rankine (nv30) */
+	{ 0x0497, false, NULL }, /* rankine (nv35) */
+	{ 0x0697, false, NULL }, /* rankine (nv34) */
+	{}
+};
+
diff --git a/drivers/gpu/drm/nouveau/nv40_fb.c b/drivers/gpu/drm/nouveau/nv40_fb.c
new file mode 100644
index 0000000..ca1d271
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv40_fb.c
@@ -0,0 +1,62 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+int
+nv40_fb_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t fb_bar_size, tmp;
+	int num_tiles;
+	int i;
+
+	/* This is strictly a NV4x register (don't know about NV5x). */
+	/* The blob sets these to all kinds of values, and they mess up our setup. */
+	/* I got value 0x52802 instead. For some cards the blob even sets it back to 0x1. */
+	/* Note: the blob doesn't read this value, so i'm pretty sure this is safe for all cards. */
+	/* Any idea what this is? */
+	nv_wr32(dev, NV40_PFB_UNK_800, 0x1);
+
+	switch (dev_priv->chipset) {
+	case 0x40:
+	case 0x45:
+		tmp = nv_rd32(dev, NV10_PFB_CLOSE_PAGE2);
+		nv_wr32(dev, NV10_PFB_CLOSE_PAGE2, tmp & ~(1 << 15));
+		num_tiles = NV10_PFB_TILE__SIZE;
+		break;
+	case 0x46: /* G72 */
+	case 0x47: /* G70 */
+	case 0x49: /* G71 */
+	case 0x4b: /* G73 */
+	case 0x4c: /* C51 (G7X version) */
+		num_tiles = NV40_PFB_TILE__SIZE_1;
+		break;
+	default:
+		num_tiles = NV40_PFB_TILE__SIZE_0;
+		break;
+	}
+
+	fb_bar_size = drm_get_resource_len(dev, 0) - 1;
+	switch (dev_priv->chipset) {
+	case 0x40:
+		for (i = 0; i < num_tiles; i++) {
+			nv_wr32(dev, NV10_PFB_TILE(i), 0);
+			nv_wr32(dev, NV10_PFB_TLIMIT(i), fb_bar_size);
+		}
+		break;
+	default:
+		for (i = 0; i < num_tiles; i++) {
+			nv_wr32(dev, NV40_PFB_TILE(i), 0);
+			nv_wr32(dev, NV40_PFB_TLIMIT(i), fb_bar_size);
+		}
+		break;
+	}
+
+	return 0;
+}
+
+void
+nv40_fb_takedown(struct drm_device *dev)
+{
+}
diff --git a/drivers/gpu/drm/nouveau/nv40_fifo.c b/drivers/gpu/drm/nouveau/nv40_fifo.c
new file mode 100644
index 0000000..b4f19cc
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv40_fifo.c
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+#define NV40_RAMFC(c) (dev_priv->ramfc_offset + ((c) * NV40_RAMFC__SIZE))
+#define NV40_RAMFC__SIZE 128
+
+int
+nv40_fifo_create_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t fc = NV40_RAMFC(chan->id);
+	int ret;
+
+	ret = nouveau_gpuobj_new_fake(dev, NV40_RAMFC(chan->id), ~0,
+				      NV40_RAMFC__SIZE, NVOBJ_FLAG_ZERO_ALLOC |
+				      NVOBJ_FLAG_ZERO_FREE, NULL, &chan->ramfc);
+	if (ret)
+		return ret;
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	nv_wi32(dev, fc +  0, chan->pushbuf_base);
+	nv_wi32(dev, fc +  4, chan->pushbuf_base);
+	nv_wi32(dev, fc + 12, chan->pushbuf->instance >> 4);
+	nv_wi32(dev, fc + 24, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
+			      NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
+			      NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 |
+#ifdef __BIG_ENDIAN
+			      NV_PFIFO_CACHE1_BIG_ENDIAN |
+#endif
+			      0x30000000 /* no idea.. */);
+	nv_wi32(dev, fc + 56, chan->ramin_grctx->instance >> 4);
+	nv_wi32(dev, fc + 60, 0x0001FFFF);
+	dev_priv->engine.instmem.finish_access(dev);
+
+	/* enable the fifo dma operation */
+	nv_wr32(dev, NV04_PFIFO_MODE,
+		nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id));
+	return 0;
+}
+
+void
+nv40_fifo_destroy_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+
+	nv_wr32(dev, NV04_PFIFO_MODE,
+		nv_rd32(dev, NV04_PFIFO_MODE) & ~(1 << chan->id));
+
+	if (chan->ramfc)
+		nouveau_gpuobj_ref_del(dev, &chan->ramfc);
+}
+
+static void
+nv40_fifo_do_load_context(struct drm_device *dev, int chid)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t fc = NV40_RAMFC(chid), tmp, tmp2;
+
+	dev_priv->engine.instmem.prepare_access(dev, false);
+
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4));
+	nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE, nv_ri32(dev, fc + 12));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT, nv_ri32(dev, fc + 16));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_STATE, nv_ri32(dev, fc + 20));
+
+	/* No idea what 0x2058 is.. */
+	tmp   = nv_ri32(dev, fc + 24);
+	tmp2  = nv_rd32(dev, 0x2058) & 0xFFF;
+	tmp2 |= (tmp & 0x30000000);
+	nv_wr32(dev, 0x2058, tmp2);
+	tmp  &= ~0x30000000;
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_FETCH, tmp);
+
+	nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_ri32(dev, fc + 28));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_PULL1, nv_ri32(dev, fc + 32));
+	nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_VALUE, nv_ri32(dev, fc + 36));
+	tmp = nv_ri32(dev, fc + 40);
+	nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP, tmp);
+	nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT, nv_ri32(dev, fc + 44));
+	nv_wr32(dev, NV10_PFIFO_CACHE1_SEMAPHORE, nv_ri32(dev, fc + 48));
+	nv_wr32(dev, NV10_PFIFO_CACHE1_DMA_SUBROUTINE, nv_ri32(dev, fc + 52));
+	nv_wr32(dev, NV40_PFIFO_GRCTX_INSTANCE, nv_ri32(dev, fc + 56));
+
+	/* Don't clobber the TIMEOUT_ENABLED flag when restoring from RAMFC */
+	tmp  = nv_rd32(dev, NV04_PFIFO_DMA_TIMESLICE) & ~0x1FFFF;
+	tmp |= nv_ri32(dev, fc + 60) & 0x1FFFF;
+	nv_wr32(dev, NV04_PFIFO_DMA_TIMESLICE, tmp);
+
+	nv_wr32(dev, 0x32e4, nv_ri32(dev, fc + 64));
+	/* NVIDIA does this next line twice... */
+	nv_wr32(dev, 0x32e8, nv_ri32(dev, fc + 68));
+	nv_wr32(dev, 0x2088, nv_ri32(dev, fc + 76));
+	nv_wr32(dev, 0x3300, nv_ri32(dev, fc + 80));
+
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0);
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0);
+}
+
+int
+nv40_fifo_load_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	uint32_t tmp;
+
+	nv40_fifo_do_load_context(dev, chan->id);
+
+	/* Set channel active, and in DMA mode */
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1,
+		     NV40_PFIFO_CACHE1_PUSH1_DMA | chan->id);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, 1);
+
+	/* Reset DMA_CTL_AT_INFO to INVALID */
+	tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_CTL) & ~(1 << 31);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_CTL, tmp);
+
+	return 0;
+}
+
+int
+nv40_fifo_unload_context(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	uint32_t fc, tmp;
+	int chid;
+
+	chid = pfifo->channel_id(dev);
+	if (chid < 0 || chid >= dev_priv->engine.fifo.channels)
+		return 0;
+	fc = NV40_RAMFC(chid);
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	nv_wi32(dev, fc + 0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT));
+	nv_wi32(dev, fc + 4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET));
+	nv_wi32(dev, fc + 8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT));
+	nv_wi32(dev, fc + 12, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE));
+	nv_wi32(dev, fc + 16, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT));
+	nv_wi32(dev, fc + 20, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_STATE));
+	tmp  = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_FETCH);
+	tmp |= nv_rd32(dev, 0x2058) & 0x30000000;
+	nv_wi32(dev, fc + 24, tmp);
+	nv_wi32(dev, fc + 28, nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE));
+	nv_wi32(dev, fc + 32, nv_rd32(dev, NV04_PFIFO_CACHE1_PULL1));
+	nv_wi32(dev, fc + 36, nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_VALUE));
+	tmp = nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP);
+	nv_wi32(dev, fc + 40, tmp);
+	nv_wi32(dev, fc + 44, nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT));
+	nv_wi32(dev, fc + 48, nv_rd32(dev, NV10_PFIFO_CACHE1_SEMAPHORE));
+	/* NVIDIA read 0x3228 first, then write DMA_GET here.. maybe something
+	 * more involved depending on the value of 0x3228?
+	 */
+	nv_wi32(dev, fc + 52, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET));
+	nv_wi32(dev, fc + 56, nv_rd32(dev, NV40_PFIFO_GRCTX_INSTANCE));
+	nv_wi32(dev, fc + 60, nv_rd32(dev, NV04_PFIFO_DMA_TIMESLICE) & 0x1ffff);
+	/* No idea what the below is for exactly, ripped from a mmio-trace */
+	nv_wi32(dev, fc + 64, nv_rd32(dev, NV40_PFIFO_UNK32E4));
+	/* NVIDIA do this next line twice.. bug? */
+	nv_wi32(dev, fc + 68, nv_rd32(dev, 0x32e8));
+	nv_wi32(dev, fc + 76, nv_rd32(dev, 0x2088));
+	nv_wi32(dev, fc + 80, nv_rd32(dev, 0x3300));
+#if 0 /* no real idea which is PUT/GET in UNK_48.. */
+	tmp  = nv_rd32(dev, NV04_PFIFO_CACHE1_GET);
+	tmp |= (nv_rd32(dev, NV04_PFIFO_CACHE1_PUT) << 16);
+	nv_wi32(dev, fc + 72, tmp);
+#endif
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nv40_fifo_do_load_context(dev, pfifo->channels - 1);
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1,
+		     NV40_PFIFO_CACHE1_PUSH1_DMA | (pfifo->channels - 1));
+	return 0;
+}
+
+static void
+nv40_fifo_init_reset(struct drm_device *dev)
+{
+	int i;
+
+	nv_wr32(dev, NV03_PMC_ENABLE,
+		nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PFIFO);
+	nv_wr32(dev, NV03_PMC_ENABLE,
+		nv_rd32(dev, NV03_PMC_ENABLE) |  NV_PMC_ENABLE_PFIFO);
+
+	nv_wr32(dev, 0x003224, 0x000f0078);
+	nv_wr32(dev, 0x003210, 0x00000000);
+	nv_wr32(dev, 0x003270, 0x00000000);
+	nv_wr32(dev, 0x003240, 0x00000000);
+	nv_wr32(dev, 0x003244, 0x00000000);
+	nv_wr32(dev, 0x003258, 0x00000000);
+	nv_wr32(dev, 0x002504, 0x00000000);
+	for (i = 0; i < 16; i++)
+		nv_wr32(dev, 0x002510 + (i * 4), 0x00000000);
+	nv_wr32(dev, 0x00250c, 0x0000ffff);
+	nv_wr32(dev, 0x002048, 0x00000000);
+	nv_wr32(dev, 0x003228, 0x00000000);
+	nv_wr32(dev, 0x0032e8, 0x00000000);
+	nv_wr32(dev, 0x002410, 0x00000000);
+	nv_wr32(dev, 0x002420, 0x00000000);
+	nv_wr32(dev, 0x002058, 0x00000001);
+	nv_wr32(dev, 0x00221c, 0x00000000);
+	/* something with 0x2084, read/modify/write, no change */
+	nv_wr32(dev, 0x002040, 0x000000ff);
+	nv_wr32(dev, 0x002500, 0x00000000);
+	nv_wr32(dev, 0x003200, 0x00000000);
+
+	nv_wr32(dev, NV04_PFIFO_DMA_TIMESLICE, 0x2101ffff);
+}
+
+static void
+nv40_fifo_init_ramxx(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ |
+				       ((dev_priv->ramht_bits - 9) << 16) |
+				       (dev_priv->ramht_offset >> 8));
+	nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro_offset>>8);
+
+	switch (dev_priv->chipset) {
+	case 0x47:
+	case 0x49:
+	case 0x4b:
+		nv_wr32(dev, 0x2230, 1);
+		break;
+	default:
+		break;
+	}
+
+	switch (dev_priv->chipset) {
+	case 0x40:
+	case 0x41:
+	case 0x42:
+	case 0x43:
+	case 0x45:
+	case 0x47:
+	case 0x48:
+	case 0x49:
+	case 0x4b:
+		nv_wr32(dev, NV40_PFIFO_RAMFC, 0x30002);
+		break;
+	default:
+		nv_wr32(dev, 0x2230, 0);
+		nv_wr32(dev, NV40_PFIFO_RAMFC,
+			((nouveau_mem_fb_amount(dev) - 512 * 1024 +
+			  dev_priv->ramfc_offset) >> 16) | (3 << 16));
+		break;
+	}
+}
+
+static void
+nv40_fifo_init_intr(struct drm_device *dev)
+{
+	nv_wr32(dev, 0x002100, 0xffffffff);
+	nv_wr32(dev, 0x002140, 0xffffffff);
+}
+
+int
+nv40_fifo_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	int i;
+
+	nv40_fifo_init_reset(dev);
+	nv40_fifo_init_ramxx(dev);
+
+	nv40_fifo_do_load_context(dev, pfifo->channels - 1);
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1);
+
+	nv40_fifo_init_intr(dev);
+	pfifo->enable(dev);
+	pfifo->reassign(dev, true);
+
+	for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
+		if (dev_priv->fifos[i]) {
+			uint32_t mode = nv_rd32(dev, NV04_PFIFO_MODE);
+			nv_wr32(dev, NV04_PFIFO_MODE, mode | (1 << i));
+		}
+	}
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c
new file mode 100644
index 0000000..d3e0a2a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv40_graph.c
@@ -0,0 +1,560 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <linux/firmware.h>
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+
+MODULE_FIRMWARE("nouveau/nv40.ctxprog");
+MODULE_FIRMWARE("nouveau/nv40.ctxvals");
+MODULE_FIRMWARE("nouveau/nv41.ctxprog");
+MODULE_FIRMWARE("nouveau/nv41.ctxvals");
+MODULE_FIRMWARE("nouveau/nv42.ctxprog");
+MODULE_FIRMWARE("nouveau/nv42.ctxvals");
+MODULE_FIRMWARE("nouveau/nv43.ctxprog");
+MODULE_FIRMWARE("nouveau/nv43.ctxvals");
+MODULE_FIRMWARE("nouveau/nv44.ctxprog");
+MODULE_FIRMWARE("nouveau/nv44.ctxvals");
+MODULE_FIRMWARE("nouveau/nv46.ctxprog");
+MODULE_FIRMWARE("nouveau/nv46.ctxvals");
+MODULE_FIRMWARE("nouveau/nv47.ctxprog");
+MODULE_FIRMWARE("nouveau/nv47.ctxvals");
+MODULE_FIRMWARE("nouveau/nv49.ctxprog");
+MODULE_FIRMWARE("nouveau/nv49.ctxvals");
+MODULE_FIRMWARE("nouveau/nv4a.ctxprog");
+MODULE_FIRMWARE("nouveau/nv4a.ctxvals");
+MODULE_FIRMWARE("nouveau/nv4b.ctxprog");
+MODULE_FIRMWARE("nouveau/nv4b.ctxvals");
+MODULE_FIRMWARE("nouveau/nv4c.ctxprog");
+MODULE_FIRMWARE("nouveau/nv4c.ctxvals");
+MODULE_FIRMWARE("nouveau/nv4e.ctxprog");
+MODULE_FIRMWARE("nouveau/nv4e.ctxvals");
+
+struct nouveau_channel *
+nv40_graph_channel(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t inst;
+	int i;
+
+	inst = nv_rd32(dev, NV40_PGRAPH_CTXCTL_CUR);
+	if (!(inst & NV40_PGRAPH_CTXCTL_CUR_LOADED))
+		return NULL;
+	inst = (inst & NV40_PGRAPH_CTXCTL_CUR_INSTANCE) << 4;
+
+	for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
+		struct nouveau_channel *chan = dev_priv->fifos[i];
+
+		if (chan && chan->ramin_grctx &&
+		    chan->ramin_grctx->instance == inst)
+			return chan;
+	}
+
+	return NULL;
+}
+
+int
+nv40_graph_create_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *ctx;
+	int ret;
+
+	/* Allocate a 175KiB block of PRAMIN to store the context.  This
+	 * is massive overkill for a lot of chipsets, but it should be safe
+	 * until we're able to implement this properly (will happen at more
+	 * or less the same time we're able to write our own context programs.
+	 */
+	ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, 175*1024, 16,
+					  NVOBJ_FLAG_ZERO_ALLOC,
+					  &chan->ramin_grctx);
+	if (ret)
+		return ret;
+	ctx = chan->ramin_grctx->gpuobj;
+
+	/* Initialise default context values */
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	nv40_grctx_vals_load(dev, ctx);
+	nv_wo32(dev, ctx, 0, ctx->im_pramin->start);
+	dev_priv->engine.instmem.finish_access(dev);
+
+	return 0;
+}
+
+void
+nv40_graph_destroy_context(struct nouveau_channel *chan)
+{
+	nouveau_gpuobj_ref_del(chan->dev, &chan->ramin_grctx);
+}
+
+static int
+nv40_graph_transfer_context(struct drm_device *dev, uint32_t inst, int save)
+{
+	uint32_t old_cp, tv = 1000, tmp;
+	int i;
+
+	old_cp = nv_rd32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER);
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, inst);
+
+	tmp  = nv_rd32(dev, NV40_PGRAPH_CTXCTL_0310);
+	tmp |= save ? NV40_PGRAPH_CTXCTL_0310_XFER_SAVE :
+		      NV40_PGRAPH_CTXCTL_0310_XFER_LOAD;
+	nv_wr32(dev, NV40_PGRAPH_CTXCTL_0310, tmp);
+
+	tmp  = nv_rd32(dev, NV40_PGRAPH_CTXCTL_0304);
+	tmp |= NV40_PGRAPH_CTXCTL_0304_XFER_CTX;
+	nv_wr32(dev, NV40_PGRAPH_CTXCTL_0304, tmp);
+
+	nouveau_wait_for_idle(dev);
+
+	for (i = 0; i < tv; i++) {
+		if (nv_rd32(dev, NV40_PGRAPH_CTXCTL_030C) == 0)
+			break;
+	}
+
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, old_cp);
+
+	if (i == tv) {
+		uint32_t ucstat = nv_rd32(dev, NV40_PGRAPH_CTXCTL_UCODE_STAT);
+		NV_ERROR(dev, "Failed: Instance=0x%08x Save=%d\n", inst, save);
+		NV_ERROR(dev, "IP: 0x%02x, Opcode: 0x%08x\n",
+			 ucstat >> NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_SHIFT,
+			 ucstat  & NV40_PGRAPH_CTXCTL_UCODE_STAT_OP_MASK);
+		NV_ERROR(dev, "0x40030C = 0x%08x\n",
+			 nv_rd32(dev, NV40_PGRAPH_CTXCTL_030C));
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
+/* Restore the context for a specific channel into PGRAPH */
+int
+nv40_graph_load_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	uint32_t inst;
+	int ret;
+
+	if (!chan->ramin_grctx)
+		return -EINVAL;
+	inst = chan->ramin_grctx->instance >> 4;
+
+	ret = nv40_graph_transfer_context(dev, inst, 0);
+	if (ret)
+		return ret;
+
+	/* 0x40032C, no idea of it's exact function.  Could simply be a
+	 * record of the currently active PGRAPH context.  It's currently
+	 * unknown as to what bit 24 does.  The nv ddx has it set, so we will
+	 * set it here too.
+	 */
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, inst);
+	nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR,
+		 (inst & NV40_PGRAPH_CTXCTL_CUR_INSTANCE) |
+		  NV40_PGRAPH_CTXCTL_CUR_LOADED);
+	/* 0x32E0 records the instance address of the active FIFO's PGRAPH
+	 * context.  If at any time this doesn't match 0x40032C, you will
+	 * recieve PGRAPH_INTR_CONTEXT_SWITCH
+	 */
+	nv_wr32(dev, NV40_PFIFO_GRCTX_INSTANCE, inst);
+	return 0;
+}
+
+int
+nv40_graph_unload_context(struct drm_device *dev)
+{
+	uint32_t inst;
+	int ret;
+
+	inst = nv_rd32(dev, NV40_PGRAPH_CTXCTL_CUR);
+	if (!(inst & NV40_PGRAPH_CTXCTL_CUR_LOADED))
+		return 0;
+	inst &= NV40_PGRAPH_CTXCTL_CUR_INSTANCE;
+
+	ret = nv40_graph_transfer_context(dev, inst, 1);
+
+	nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, inst);
+	return ret;
+}
+
+struct nouveau_ctxprog {
+	uint32_t signature;
+	uint8_t  version;
+	uint16_t length;
+	uint32_t data[];
+} __attribute__ ((packed));
+
+struct nouveau_ctxvals {
+	uint32_t signature;
+	uint8_t  version;
+	uint32_t length;
+	struct {
+		uint32_t offset;
+		uint32_t value;
+	} data[];
+} __attribute__ ((packed));
+
+int
+nv40_grctx_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	const int chipset = dev_priv->chipset;
+	const struct firmware *fw;
+	const struct nouveau_ctxprog *cp;
+	const struct nouveau_ctxvals *cv;
+	char name[32];
+	int ret, i;
+
+	pgraph->accel_blocked = true;
+
+	if (!pgraph->ctxprog) {
+		sprintf(name, "nouveau/nv%02x.ctxprog", chipset);
+		ret = request_firmware(&fw, name, &dev->pdev->dev);
+		if (ret) {
+			NV_ERROR(dev, "No ctxprog for NV%02x\n", chipset);
+			return ret;
+		}
+
+		pgraph->ctxprog = kmalloc(fw->size, GFP_KERNEL);
+		if (!pgraph->ctxprog) {
+			NV_ERROR(dev, "OOM copying ctxprog\n");
+			release_firmware(fw);
+			return -ENOMEM;
+		}
+		memcpy(pgraph->ctxprog, fw->data, fw->size);
+
+		cp = pgraph->ctxprog;
+		if (cp->signature != 0x5043564e || cp->version != 0 ||
+		    cp->length != ((fw->size - 7) / 4)) {
+			NV_ERROR(dev, "ctxprog invalid\n");
+			release_firmware(fw);
+			nv40_grctx_fini(dev);
+			return -EINVAL;
+		}
+		release_firmware(fw);
+	}
+
+	if (!pgraph->ctxvals) {
+		sprintf(name, "nouveau/nv%02x.ctxvals", chipset);
+		ret = request_firmware(&fw, name, &dev->pdev->dev);
+		if (ret) {
+			NV_ERROR(dev, "No ctxvals for NV%02x\n", chipset);
+			nv40_grctx_fini(dev);
+			return ret;
+		}
+
+		pgraph->ctxvals = kmalloc(fw->size, GFP_KERNEL);
+		if (!pgraph->ctxprog) {
+			NV_ERROR(dev, "OOM copying ctxprog\n");
+			release_firmware(fw);
+			nv40_grctx_fini(dev);
+			return -ENOMEM;
+		}
+		memcpy(pgraph->ctxvals, fw->data, fw->size);
+
+		cv = (void *)pgraph->ctxvals;
+		if (cv->signature != 0x5643564e || cv->version != 0 ||
+		    cv->length != ((fw->size - 9) / 8)) {
+			NV_ERROR(dev, "ctxvals invalid\n");
+			release_firmware(fw);
+			nv40_grctx_fini(dev);
+			return -EINVAL;
+		}
+		release_firmware(fw);
+	}
+
+	cp = pgraph->ctxprog;
+
+	nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
+	for (i = 0; i < cp->length; i++)
+		nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp->data[i]);
+
+	pgraph->accel_blocked = false;
+	return 0;
+}
+
+void
+nv40_grctx_fini(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+
+	if (pgraph->ctxprog) {
+		kfree(pgraph->ctxprog);
+		pgraph->ctxprog = NULL;
+	}
+
+	if (pgraph->ctxvals) {
+		kfree(pgraph->ctxprog);
+		pgraph->ctxvals = NULL;
+	}
+}
+
+void
+nv40_grctx_vals_load(struct drm_device *dev, struct nouveau_gpuobj *ctx)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	struct nouveau_ctxvals *cv = pgraph->ctxvals;
+	int i;
+
+	if (!cv)
+		return;
+
+	for (i = 0; i < cv->length; i++)
+		nv_wo32(dev, ctx, cv->data[i].offset, cv->data[i].value);
+}
+
+/*
+ * G70		0x47
+ * G71		0x49
+ * NV45		0x48
+ * G72[M]	0x46
+ * G73		0x4b
+ * C51_G7X	0x4c
+ * C51		0x4e
+ */
+int
+nv40_graph_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv =
+		(struct drm_nouveau_private *)dev->dev_private;
+	uint32_t vramsz, tmp;
+	int i, j;
+
+	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
+			~NV_PMC_ENABLE_PGRAPH);
+	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
+			 NV_PMC_ENABLE_PGRAPH);
+
+	nv40_grctx_init(dev);
+
+	/* No context present currently */
+	nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0x00000000);
+
+	nv_wr32(dev, NV03_PGRAPH_INTR   , 0xFFFFFFFF);
+	nv_wr32(dev, NV40_PGRAPH_INTR_EN, 0xFFFFFFFF);
+
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x401287c0);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xe0de8055);
+	nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00008000);
+	nv_wr32(dev, NV04_PGRAPH_LIMIT_VIOL_PIX, 0x00be3c5f);
+
+	nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100);
+	nv_wr32(dev, NV10_PGRAPH_STATE      , 0xFFFFFFFF);
+
+	j = nv_rd32(dev, 0x1540) & 0xff;
+	if (j) {
+		for (i = 0; !(j & 1); j >>= 1, i++)
+			;
+		nv_wr32(dev, 0x405000, i);
+	}
+
+	if (dev_priv->chipset == 0x40) {
+		nv_wr32(dev, 0x4009b0, 0x83280fff);
+		nv_wr32(dev, 0x4009b4, 0x000000a0);
+	} else {
+		nv_wr32(dev, 0x400820, 0x83280eff);
+		nv_wr32(dev, 0x400824, 0x000000a0);
+	}
+
+	switch (dev_priv->chipset) {
+	case 0x40:
+	case 0x45:
+		nv_wr32(dev, 0x4009b8, 0x0078e366);
+		nv_wr32(dev, 0x4009bc, 0x0000014c);
+		break;
+	case 0x41:
+	case 0x42: /* pciid also 0x00Cx */
+	/* case 0x0120: XXX (pciid) */
+		nv_wr32(dev, 0x400828, 0x007596ff);
+		nv_wr32(dev, 0x40082c, 0x00000108);
+		break;
+	case 0x43:
+		nv_wr32(dev, 0x400828, 0x0072cb77);
+		nv_wr32(dev, 0x40082c, 0x00000108);
+		break;
+	case 0x44:
+	case 0x46: /* G72 */
+	case 0x4a:
+	case 0x4c: /* G7x-based C51 */
+	case 0x4e:
+		nv_wr32(dev, 0x400860, 0);
+		nv_wr32(dev, 0x400864, 0);
+		break;
+	case 0x47: /* G70 */
+	case 0x49: /* G71 */
+	case 0x4b: /* G73 */
+		nv_wr32(dev, 0x400828, 0x07830610);
+		nv_wr32(dev, 0x40082c, 0x0000016A);
+		break;
+	default:
+		break;
+	}
+
+	nv_wr32(dev, 0x400b38, 0x2ffff800);
+	nv_wr32(dev, 0x400b3c, 0x00006000);
+
+	/* copy tile info from PFB */
+	switch (dev_priv->chipset) {
+	case 0x40: /* vanilla NV40 */
+		for (i = 0; i < NV10_PFB_TILE__SIZE; i++) {
+			tmp = nv_rd32(dev, NV10_PFB_TILE(i));
+			nv_wr32(dev, NV40_PGRAPH_TILE0(i), tmp);
+			nv_wr32(dev, NV40_PGRAPH_TILE1(i), tmp);
+			tmp = nv_rd32(dev, NV10_PFB_TLIMIT(i));
+			nv_wr32(dev, NV40_PGRAPH_TLIMIT0(i), tmp);
+			nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tmp);
+			tmp = nv_rd32(dev, NV10_PFB_TSIZE(i));
+			nv_wr32(dev, NV40_PGRAPH_TSIZE0(i), tmp);
+			nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tmp);
+			tmp = nv_rd32(dev, NV10_PFB_TSTATUS(i));
+			nv_wr32(dev, NV40_PGRAPH_TSTATUS0(i), tmp);
+			nv_wr32(dev, NV40_PGRAPH_TSTATUS1(i), tmp);
+		}
+		break;
+	case 0x44:
+	case 0x4a:
+	case 0x4e: /* NV44-based cores don't have 0x406900? */
+		for (i = 0; i < NV40_PFB_TILE__SIZE_0; i++) {
+			tmp = nv_rd32(dev, NV40_PFB_TILE(i));
+			nv_wr32(dev, NV40_PGRAPH_TILE0(i), tmp);
+			tmp = nv_rd32(dev, NV40_PFB_TLIMIT(i));
+			nv_wr32(dev, NV40_PGRAPH_TLIMIT0(i), tmp);
+			tmp = nv_rd32(dev, NV40_PFB_TSIZE(i));
+			nv_wr32(dev, NV40_PGRAPH_TSIZE0(i), tmp);
+			tmp = nv_rd32(dev, NV40_PFB_TSTATUS(i));
+			nv_wr32(dev, NV40_PGRAPH_TSTATUS0(i), tmp);
+		}
+		break;
+	case 0x46:
+	case 0x47:
+	case 0x49:
+	case 0x4b: /* G7X-based cores */
+		for (i = 0; i < NV40_PFB_TILE__SIZE_1; i++) {
+			tmp = nv_rd32(dev, NV40_PFB_TILE(i));
+			nv_wr32(dev, NV47_PGRAPH_TILE0(i), tmp);
+			nv_wr32(dev, NV40_PGRAPH_TILE1(i), tmp);
+			tmp = nv_rd32(dev, NV40_PFB_TLIMIT(i));
+			nv_wr32(dev, NV47_PGRAPH_TLIMIT0(i), tmp);
+			nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tmp);
+			tmp = nv_rd32(dev, NV40_PFB_TSIZE(i));
+			nv_wr32(dev, NV47_PGRAPH_TSIZE0(i), tmp);
+			nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tmp);
+			tmp = nv_rd32(dev, NV40_PFB_TSTATUS(i));
+			nv_wr32(dev, NV47_PGRAPH_TSTATUS0(i), tmp);
+			nv_wr32(dev, NV40_PGRAPH_TSTATUS1(i), tmp);
+		}
+		break;
+	default: /* everything else */
+		for (i = 0; i < NV40_PFB_TILE__SIZE_0; i++) {
+			tmp = nv_rd32(dev, NV40_PFB_TILE(i));
+			nv_wr32(dev, NV40_PGRAPH_TILE0(i), tmp);
+			nv_wr32(dev, NV40_PGRAPH_TILE1(i), tmp);
+			tmp = nv_rd32(dev, NV40_PFB_TLIMIT(i));
+			nv_wr32(dev, NV40_PGRAPH_TLIMIT0(i), tmp);
+			nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tmp);
+			tmp = nv_rd32(dev, NV40_PFB_TSIZE(i));
+			nv_wr32(dev, NV40_PGRAPH_TSIZE0(i), tmp);
+			nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tmp);
+			tmp = nv_rd32(dev, NV40_PFB_TSTATUS(i));
+			nv_wr32(dev, NV40_PGRAPH_TSTATUS0(i), tmp);
+			nv_wr32(dev, NV40_PGRAPH_TSTATUS1(i), tmp);
+		}
+		break;
+	}
+
+	/* begin RAM config */
+	vramsz = drm_get_resource_len(dev, 0) - 1;
+	switch (dev_priv->chipset) {
+	case 0x40:
+		nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0));
+		nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1));
+		nv_wr32(dev, 0x4069A4, nv_rd32(dev, NV04_PFB_CFG0));
+		nv_wr32(dev, 0x4069A8, nv_rd32(dev, NV04_PFB_CFG1));
+		nv_wr32(dev, 0x400820, 0);
+		nv_wr32(dev, 0x400824, 0);
+		nv_wr32(dev, 0x400864, vramsz);
+		nv_wr32(dev, 0x400868, vramsz);
+		break;
+	default:
+		switch (dev_priv->chipset) {
+		case 0x46:
+		case 0x47:
+		case 0x49:
+		case 0x4b:
+			nv_wr32(dev, 0x400DF0, nv_rd32(dev, NV04_PFB_CFG0));
+			nv_wr32(dev, 0x400DF4, nv_rd32(dev, NV04_PFB_CFG1));
+			break;
+		default:
+			nv_wr32(dev, 0x4009F0, nv_rd32(dev, NV04_PFB_CFG0));
+			nv_wr32(dev, 0x4009F4, nv_rd32(dev, NV04_PFB_CFG1));
+			break;
+		}
+		nv_wr32(dev, 0x4069F0, nv_rd32(dev, NV04_PFB_CFG0));
+		nv_wr32(dev, 0x4069F4, nv_rd32(dev, NV04_PFB_CFG1));
+		nv_wr32(dev, 0x400840, 0);
+		nv_wr32(dev, 0x400844, 0);
+		nv_wr32(dev, 0x4008A0, vramsz);
+		nv_wr32(dev, 0x4008A4, vramsz);
+		break;
+	}
+
+	return 0;
+}
+
+void nv40_graph_takedown(struct drm_device *dev)
+{
+}
+
+struct nouveau_pgraph_object_class nv40_graph_grclass[] = {
+	{ 0x0030, false, NULL }, /* null */
+	{ 0x0039, false, NULL }, /* m2mf */
+	{ 0x004a, false, NULL }, /* gdirect */
+	{ 0x009f, false, NULL }, /* imageblit (nv12) */
+	{ 0x008a, false, NULL }, /* ifc */
+	{ 0x0089, false, NULL }, /* sifm */
+	{ 0x3089, false, NULL }, /* sifm (nv40) */
+	{ 0x0062, false, NULL }, /* surf2d */
+	{ 0x3062, false, NULL }, /* surf2d (nv40) */
+	{ 0x0043, false, NULL }, /* rop */
+	{ 0x0012, false, NULL }, /* beta1 */
+	{ 0x0072, false, NULL }, /* beta4 */
+	{ 0x0019, false, NULL }, /* cliprect */
+	{ 0x0044, false, NULL }, /* pattern */
+	{ 0x309e, false, NULL }, /* swzsurf */
+	{ 0x4097, false, NULL }, /* curie (nv40) */
+	{ 0x4497, false, NULL }, /* curie (nv44) */
+	{}
+};
+
diff --git a/drivers/gpu/drm/nouveau/nv40_mc.c b/drivers/gpu/drm/nouveau/nv40_mc.c
new file mode 100644
index 0000000..2a3495e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv40_mc.c
@@ -0,0 +1,38 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+int
+nv40_mc_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t tmp;
+
+	/* Power up everything, resetting each individual unit will
+	 * be done later if needed.
+	 */
+	nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF);
+
+	switch (dev_priv->chipset) {
+	case 0x44:
+	case 0x46: /* G72 */
+	case 0x4e:
+	case 0x4c: /* C51_G7X */
+		tmp = nv_rd32(dev, NV40_PFB_020C);
+		nv_wr32(dev, NV40_PMC_1700, tmp);
+		nv_wr32(dev, NV40_PMC_1704, 0);
+		nv_wr32(dev, NV40_PMC_1708, 0);
+		nv_wr32(dev, NV40_PMC_170C, tmp);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+void
+nv40_mc_takedown(struct drm_device *dev)
+{
+}
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c
new file mode 100644
index 0000000..f8e28a1
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv50_crtc.c
@@ -0,0 +1,769 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "drm_mode.h"
+#include "drm_crtc_helper.h"
+
+#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO)
+#include "nouveau_reg.h"
+#include "nouveau_drv.h"
+#include "nouveau_hw.h"
+#include "nouveau_encoder.h"
+#include "nouveau_crtc.h"
+#include "nouveau_fb.h"
+#include "nouveau_connector.h"
+#include "nv50_display.h"
+
+static void
+nv50_crtc_lut_load(struct drm_crtc *crtc)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	void __iomem *lut = nvbo_kmap_obj_iovirtual(nv_crtc->lut.nvbo);
+	int i;
+
+	NV_DEBUG(crtc->dev, "\n");
+
+	for (i = 0; i < 256; i++) {
+		writew(nv_crtc->lut.r[i] >> 2, lut + 8*i + 0);
+		writew(nv_crtc->lut.g[i] >> 2, lut + 8*i + 2);
+		writew(nv_crtc->lut.b[i] >> 2, lut + 8*i + 4);
+	}
+
+	if (nv_crtc->lut.depth == 30) {
+		writew(nv_crtc->lut.r[i - 1] >> 2, lut + 8*i + 0);
+		writew(nv_crtc->lut.g[i - 1] >> 2, lut + 8*i + 2);
+		writew(nv_crtc->lut.b[i - 1] >> 2, lut + 8*i + 4);
+	}
+}
+
+int
+nv50_crtc_blank(struct nouveau_crtc *nv_crtc, bool blanked)
+{
+	struct drm_device *dev = nv_crtc->base.dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	int index = nv_crtc->index, ret;
+
+	NV_DEBUG(dev, "index %d\n", nv_crtc->index);
+	NV_DEBUG(dev, "%s\n", blanked ? "blanked" : "unblanked");
+
+	if (blanked) {
+		nv_crtc->cursor.hide(nv_crtc, false);
+
+		ret = RING_SPACE(evo, dev_priv->chipset != 0x50 ? 7 : 5);
+		if (ret) {
+			NV_ERROR(dev, "no space while blanking crtc\n");
+			return ret;
+		}
+		BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, CLUT_MODE), 2);
+		OUT_RING(evo, NV50_EVO_CRTC_CLUT_MODE_BLANK);
+		OUT_RING(evo, 0);
+		if (dev_priv->chipset != 0x50) {
+			BEGIN_RING(evo, 0, NV84_EVO_CRTC(index, CLUT_DMA), 1);
+			OUT_RING(evo, NV84_EVO_CRTC_CLUT_DMA_HANDLE_NONE);
+		}
+
+		BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, FB_DMA), 1);
+		OUT_RING(evo, NV50_EVO_CRTC_FB_DMA_HANDLE_NONE);
+	} else {
+		if (nv_crtc->cursor.visible)
+			nv_crtc->cursor.show(nv_crtc, false);
+		else
+			nv_crtc->cursor.hide(nv_crtc, false);
+
+		ret = RING_SPACE(evo, dev_priv->chipset != 0x50 ? 10 : 8);
+		if (ret) {
+			NV_ERROR(dev, "no space while unblanking crtc\n");
+			return ret;
+		}
+		BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, CLUT_MODE), 2);
+		OUT_RING(evo, nv_crtc->lut.depth == 8 ?
+				NV50_EVO_CRTC_CLUT_MODE_OFF :
+				NV50_EVO_CRTC_CLUT_MODE_ON);
+		OUT_RING(evo, (nv_crtc->lut.nvbo->bo.mem.mm_node->start <<
+				 PAGE_SHIFT) >> 8);
+		if (dev_priv->chipset != 0x50) {
+			BEGIN_RING(evo, 0, NV84_EVO_CRTC(index, CLUT_DMA), 1);
+			OUT_RING(evo, NvEvoVRAM);
+		}
+
+		BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, FB_OFFSET), 2);
+		OUT_RING(evo, nv_crtc->fb.offset >> 8);
+		OUT_RING(evo, 0);
+		BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, FB_DMA), 1);
+		if (dev_priv->chipset != 0x50)
+			if (nv_crtc->fb.tile_flags == 0x7a00)
+				OUT_RING(evo, NvEvoFB32);
+			else
+			if (nv_crtc->fb.tile_flags == 0x7000)
+				OUT_RING(evo, NvEvoFB16);
+			else
+				OUT_RING(evo, NvEvoVRAM);
+		else
+			OUT_RING(evo, NvEvoVRAM);
+	}
+
+	nv_crtc->fb.blanked = blanked;
+	return 0;
+}
+
+static int
+nv50_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool on, bool update)
+{
+	struct drm_device *dev = nv_crtc->base.dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	int ret;
+
+	NV_DEBUG(dev, "\n");
+
+	ret = RING_SPACE(evo, 2 + (update ? 2 : 0));
+	if (ret) {
+		NV_ERROR(dev, "no space while setting dither\n");
+		return ret;
+	}
+
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, DITHER_CTRL), 1);
+	if (on)
+		OUT_RING(evo, NV50_EVO_CRTC_DITHER_CTRL_ON);
+	else
+		OUT_RING(evo, NV50_EVO_CRTC_DITHER_CTRL_OFF);
+
+	if (update) {
+		BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
+		OUT_RING(evo, 0);
+		FIRE_RING(evo);
+	}
+
+	return 0;
+}
+
+struct nouveau_connector *
+nouveau_crtc_connector_get(struct nouveau_crtc *nv_crtc)
+{
+	struct drm_device *dev = nv_crtc->base.dev;
+	struct drm_connector *connector;
+	struct drm_crtc *crtc = to_drm_crtc(nv_crtc);
+
+	/* The safest approach is to find an encoder with the right crtc, that
+	 * is also linked to a connector. */
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		if (connector->encoder)
+			if (connector->encoder->crtc == crtc)
+				return nouveau_connector(connector);
+	}
+
+	return NULL;
+}
+
+static int
+nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, int scaling_mode, bool update)
+{
+	struct nouveau_connector *nv_connector =
+		nouveau_crtc_connector_get(nv_crtc);
+	struct drm_device *dev = nv_crtc->base.dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	struct drm_display_mode *native_mode = NULL;
+	struct drm_display_mode *mode = &nv_crtc->base.mode;
+	uint32_t outX, outY, horiz, vert;
+	int ret;
+
+	NV_DEBUG(dev, "\n");
+
+	switch (scaling_mode) {
+	case DRM_MODE_SCALE_NONE:
+		break;
+	default:
+		if (!nv_connector || !nv_connector->native_mode) {
+			NV_ERROR(dev, "No native mode, forcing panel scaling\n");
+			scaling_mode = DRM_MODE_SCALE_NONE;
+		} else {
+			native_mode = nv_connector->native_mode;
+		}
+		break;
+	}
+
+	switch (scaling_mode) {
+	case DRM_MODE_SCALE_ASPECT:
+		horiz = (native_mode->hdisplay << 19) / mode->hdisplay;
+		vert = (native_mode->vdisplay << 19) / mode->vdisplay;
+
+		if (vert > horiz) {
+			outX = (mode->hdisplay * horiz) >> 19;
+			outY = (mode->vdisplay * horiz) >> 19;
+		} else {
+			outX = (mode->hdisplay * vert) >> 19;
+			outY = (mode->vdisplay * vert) >> 19;
+		}
+		break;
+	case DRM_MODE_SCALE_FULLSCREEN:
+		outX = native_mode->hdisplay;
+		outY = native_mode->vdisplay;
+		break;
+	case DRM_MODE_SCALE_CENTER:
+	case DRM_MODE_SCALE_NONE:
+	default:
+		outX = mode->hdisplay;
+		outY = mode->vdisplay;
+		break;
+	}
+
+	ret = RING_SPACE(evo, update ? 7 : 5);
+	if (ret)
+		return ret;
+
+	/* Got a better name for SCALER_ACTIVE? */
+	/* One day i've got to really figure out why this is needed. */
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, SCALE_CTRL), 1);
+	if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) ||
+	    (mode->flags & DRM_MODE_FLAG_INTERLACE) ||
+	    mode->hdisplay != outX || mode->vdisplay != outY) {
+		OUT_RING(evo, NV50_EVO_CRTC_SCALE_CTRL_ACTIVE);
+	} else {
+		OUT_RING(evo, NV50_EVO_CRTC_SCALE_CTRL_INACTIVE);
+	}
+
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, SCALE_RES1), 2);
+	OUT_RING(evo, outY << 16 | outX);
+	OUT_RING(evo, outY << 16 | outX);
+
+	if (update) {
+		BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
+		OUT_RING(evo, 0);
+		FIRE_RING(evo);
+	}
+
+	return 0;
+}
+
+int
+nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk)
+{
+	uint32_t pll_reg = NV50_PDISPLAY_CRTC_CLK_CTRL1(head);
+	struct nouveau_pll_vals pll;
+	struct pll_lims limits;
+	uint32_t reg1, reg2;
+	int ret;
+
+	ret = get_pll_limits(dev, pll_reg, &limits);
+	if (ret)
+		return ret;
+
+	ret = nouveau_calc_pll_mnp(dev, &limits, pclk, &pll);
+	if (ret <= 0)
+		return ret;
+
+	if (limits.vco2.maxfreq) {
+		reg1 = nv_rd32(dev, pll_reg + 4) & 0xff00ff00;
+		reg2 = nv_rd32(dev, pll_reg + 8) & 0x8000ff00;
+		nv_wr32(dev, pll_reg, 0x10000611);
+		nv_wr32(dev, pll_reg + 4, reg1 | (pll.M1 << 16) | pll.N1);
+		nv_wr32(dev, pll_reg + 8,
+			reg2 | (pll.log2P << 28) | (pll.M2 << 16) | pll.N2);
+	} else {
+		reg1 = nv_rd32(dev, pll_reg + 4) & 0xffc00000;
+		nv_wr32(dev, pll_reg, 0x50000610);
+		nv_wr32(dev, pll_reg + 4, reg1 |
+			(pll.log2P << 16) | (pll.M1 << 8) | pll.N1);
+	}
+
+	return 0;
+}
+
+static void
+nv50_crtc_destroy(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+
+	NV_DEBUG(dev, "\n");
+
+	if (!crtc)
+		return;
+
+	drm_crtc_cleanup(&nv_crtc->base);
+
+	nv50_cursor_fini(nv_crtc);
+
+	nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo);
+	nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
+	kfree(nv_crtc->mode);
+	kfree(nv_crtc);
+}
+
+int
+nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
+		     uint32_t buffer_handle, uint32_t width, uint32_t height)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct nouveau_bo *cursor = NULL;
+	struct drm_gem_object *gem;
+	int ret = 0, i;
+
+	if (width != 64 || height != 64)
+		return -EINVAL;
+
+	if (!buffer_handle) {
+		nv_crtc->cursor.hide(nv_crtc, true);
+		return 0;
+	}
+
+	gem = drm_gem_object_lookup(dev, file_priv, buffer_handle);
+	if (!gem)
+		return -EINVAL;
+	cursor = nouveau_gem_object(gem);
+
+	ret = nouveau_bo_map(cursor);
+	if (ret)
+		goto out;
+
+	/* The simple will do for now. */
+	for (i = 0; i < 64 * 64; i++)
+		nouveau_bo_wr32(nv_crtc->cursor.nvbo, i, nouveau_bo_rd32(cursor, i));
+
+	nouveau_bo_unmap(cursor);
+
+	nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.nvbo->bo.offset -
+					    dev_priv->vm_vram_base);
+	nv_crtc->cursor.show(nv_crtc, true);
+
+out:
+	mutex_lock(&dev->struct_mutex);
+	drm_gem_object_unreference(gem);
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
+int
+nv50_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+
+	nv_crtc->cursor.set_pos(nv_crtc, x, y);
+	return 0;
+}
+
+static void
+nv50_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
+		    uint32_t size)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	int i;
+
+	if (size != 256)
+		return;
+
+	for (i = 0; i < 256; i++) {
+		nv_crtc->lut.r[i] = r[i];
+		nv_crtc->lut.g[i] = g[i];
+		nv_crtc->lut.b[i] = b[i];
+	}
+
+	/* We need to know the depth before we upload, but it's possible to
+	 * get called before a framebuffer is bound.  If this is the case,
+	 * mark the lut values as dirty by setting depth==0, and it'll be
+	 * uploaded on the first mode_set_base()
+	 */
+	if (!nv_crtc->base.fb) {
+		nv_crtc->lut.depth = 0;
+		return;
+	}
+
+	nv50_crtc_lut_load(crtc);
+}
+
+static void
+nv50_crtc_save(struct drm_crtc *crtc)
+{
+	NV_ERROR(crtc->dev, "!!\n");
+}
+
+static void
+nv50_crtc_restore(struct drm_crtc *crtc)
+{
+	NV_ERROR(crtc->dev, "!!\n");
+}
+
+static const struct drm_crtc_funcs nv50_crtc_funcs = {
+	.save = nv50_crtc_save,
+	.restore = nv50_crtc_restore,
+	.cursor_set = nv50_crtc_cursor_set,
+	.cursor_move = nv50_crtc_cursor_move,
+	.gamma_set = nv50_crtc_gamma_set,
+	.set_config = drm_crtc_helper_set_config,
+	.destroy = nv50_crtc_destroy,
+};
+
+static void
+nv50_crtc_dpms(struct drm_crtc *crtc, int mode)
+{
+}
+
+static void
+nv50_crtc_prepare(struct drm_crtc *crtc)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	struct drm_encoder *encoder;
+
+	NV_DEBUG(dev, "index %d\n", nv_crtc->index);
+
+	/* Disconnect all unused encoders. */
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+		if (drm_helper_encoder_in_use(encoder))
+			continue;
+
+		nv_encoder->disconnect(nv_encoder);
+	}
+
+	nv50_crtc_blank(nv_crtc, true);
+}
+
+static void
+nv50_crtc_commit(struct drm_crtc *crtc)
+{
+	struct drm_crtc *crtc2;
+	struct drm_device *dev = crtc->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	int ret;
+
+	NV_DEBUG(dev, "index %d\n", nv_crtc->index);
+
+	nv50_crtc_blank(nv_crtc, false);
+
+	/* Explicitly blank all unused crtc's. */
+	list_for_each_entry(crtc2, &dev->mode_config.crtc_list, head) {
+		if (!drm_helper_crtc_in_use(crtc2))
+			nv50_crtc_blank(nouveau_crtc(crtc2), true);
+	}
+
+	ret = RING_SPACE(evo, 2);
+	if (ret) {
+		NV_ERROR(dev, "no space while committing crtc\n");
+		return;
+	}
+	BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
+	OUT_RING(evo, 0);
+	FIRE_RING(evo);
+}
+
+static bool
+nv50_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *mode,
+		     struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static int
+nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, int x, int y,
+			   struct drm_framebuffer *old_fb, bool update)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct drm_device *dev = nv_crtc->base.dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	struct drm_framebuffer *drm_fb = nv_crtc->base.fb;
+	struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
+	int ret, format;
+
+	NV_DEBUG(dev, "index %d\n", nv_crtc->index);
+
+	switch (drm_fb->depth) {
+	case  8:
+		format = NV50_EVO_CRTC_FB_DEPTH_8;
+		break;
+	case 15:
+		format = NV50_EVO_CRTC_FB_DEPTH_15;
+		break;
+	case 16:
+		format = NV50_EVO_CRTC_FB_DEPTH_16;
+		break;
+	case 24:
+	case 32:
+		format = NV50_EVO_CRTC_FB_DEPTH_24;
+		break;
+	case 30:
+		format = NV50_EVO_CRTC_FB_DEPTH_30;
+		break;
+	default:
+		 NV_ERROR(dev, "unknown depth %d\n", drm_fb->depth);
+		 return -EINVAL;
+	}
+
+	ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM);
+	if (ret)
+		return ret;
+
+	if (old_fb) {
+		struct nouveau_framebuffer *ofb = nouveau_framebuffer(old_fb);
+		nouveau_bo_unpin(ofb->nvbo);
+	}
+
+	nv_crtc->fb.offset = fb->nvbo->bo.offset - dev_priv->vm_vram_base;
+	nv_crtc->fb.tile_flags = fb->nvbo->tile_flags;
+	nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8;
+	if (!nv_crtc->fb.blanked && dev_priv->chipset != 0x50) {
+		ret = RING_SPACE(evo, 2);
+		if (ret)
+			return ret;
+
+		BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_DMA), 1);
+		if (nv_crtc->fb.tile_flags == 0x7a00)
+			OUT_RING(evo, NvEvoFB32);
+		else
+		if (nv_crtc->fb.tile_flags == 0x7000)
+			OUT_RING(evo, NvEvoFB16);
+		else
+			OUT_RING(evo, NvEvoVRAM);
+	}
+
+	ret = RING_SPACE(evo, 12);
+	if (ret)
+		return ret;
+
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_OFFSET), 5);
+	OUT_RING(evo, nv_crtc->fb.offset >> 8);
+	OUT_RING(evo, 0);
+	OUT_RING(evo, (drm_fb->height << 16) | drm_fb->width);
+	if (!nv_crtc->fb.tile_flags) {
+		OUT_RING(evo, drm_fb->pitch | (1 << 20));
+	} else {
+		OUT_RING(evo, ((drm_fb->pitch / 4) << 4) |
+				  fb->nvbo->tile_mode);
+	}
+	if (dev_priv->chipset == 0x50)
+		OUT_RING(evo, (fb->nvbo->tile_flags << 8) | format);
+	else
+		OUT_RING(evo, format);
+
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CLUT_MODE), 1);
+	OUT_RING(evo, fb->base.depth == 8 ?
+		 NV50_EVO_CRTC_CLUT_MODE_OFF : NV50_EVO_CRTC_CLUT_MODE_ON);
+
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, COLOR_CTRL), 1);
+	OUT_RING(evo, NV50_EVO_CRTC_COLOR_CTRL_COLOR);
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_POS), 1);
+	OUT_RING(evo, (y << 16) | x);
+
+	if (nv_crtc->lut.depth != fb->base.depth) {
+		nv_crtc->lut.depth = fb->base.depth;
+		nv50_crtc_lut_load(crtc);
+	}
+
+	if (update) {
+		ret = RING_SPACE(evo, 2);
+		if (ret)
+			return ret;
+		BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
+		OUT_RING(evo, 0);
+		FIRE_RING(evo);
+	}
+
+	return 0;
+}
+
+static int
+nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
+		   struct drm_display_mode *adjusted_mode, int x, int y,
+		   struct drm_framebuffer *old_fb)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct nouveau_connector *nv_connector = NULL;
+	uint32_t hsync_dur,  vsync_dur, hsync_start_to_end, vsync_start_to_end;
+	uint32_t hunk1, vunk1, vunk2a, vunk2b;
+	int ret;
+
+	/* Find the connector attached to this CRTC */
+	nv_connector = nouveau_crtc_connector_get(nv_crtc);
+
+	*nv_crtc->mode = *adjusted_mode;
+
+	NV_DEBUG(dev, "index %d\n", nv_crtc->index);
+
+	hsync_dur = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
+	vsync_dur = adjusted_mode->vsync_end - adjusted_mode->vsync_start;
+	hsync_start_to_end = adjusted_mode->htotal - adjusted_mode->hsync_start;
+	vsync_start_to_end = adjusted_mode->vtotal - adjusted_mode->vsync_start;
+	/* I can't give this a proper name, anyone else can? */
+	hunk1 = adjusted_mode->htotal -
+		adjusted_mode->hsync_start + adjusted_mode->hdisplay;
+	vunk1 = adjusted_mode->vtotal -
+		adjusted_mode->vsync_start + adjusted_mode->vdisplay;
+	/* Another strange value, this time only for interlaced adjusted_modes. */
+	vunk2a = 2 * adjusted_mode->vtotal -
+		 adjusted_mode->vsync_start + adjusted_mode->vdisplay;
+	vunk2b = adjusted_mode->vtotal -
+		 adjusted_mode->vsync_start + adjusted_mode->vtotal;
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
+		vsync_dur /= 2;
+		vsync_start_to_end  /= 2;
+		vunk1 /= 2;
+		vunk2a /= 2;
+		vunk2b /= 2;
+		/* magic */
+		if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) {
+			vsync_start_to_end -= 1;
+			vunk1 -= 1;
+			vunk2a -= 1;
+			vunk2b -= 1;
+		}
+	}
+
+	ret = RING_SPACE(evo, 17);
+	if (ret)
+		return ret;
+
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CLOCK), 2);
+	OUT_RING(evo, adjusted_mode->clock | 0x800000);
+	OUT_RING(evo, (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) ? 2 : 0);
+
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, DISPLAY_START), 5);
+	OUT_RING(evo, 0);
+	OUT_RING(evo, (adjusted_mode->vtotal << 16) | adjusted_mode->htotal);
+	OUT_RING(evo, (vsync_dur - 1) << 16 | (hsync_dur - 1));
+	OUT_RING(evo, (vsync_start_to_end - 1) << 16 |
+			(hsync_start_to_end - 1));
+	OUT_RING(evo, (vunk1 - 1) << 16 | (hunk1 - 1));
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
+		BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, UNK0824), 1);
+		OUT_RING(evo, (vunk2b - 1) << 16 | (vunk2a - 1));
+	} else {
+		OUT_RING(evo, 0);
+		OUT_RING(evo, 0);
+	}
+
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, UNK082C), 1);
+	OUT_RING(evo, 0);
+
+	/* This is the actual resolution of the mode. */
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, REAL_RES), 1);
+	OUT_RING(evo, (mode->vdisplay << 16) | mode->hdisplay);
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, SCALE_CENTER_OFFSET), 1);
+	OUT_RING(evo, NV50_EVO_CRTC_SCALE_CENTER_OFFSET_VAL(0, 0));
+
+	nv_crtc->set_dither(nv_crtc, nv_connector->use_dithering, false);
+	nv_crtc->set_scale(nv_crtc, nv_connector->scaling_mode, false);
+
+	return nv50_crtc_do_mode_set_base(crtc, x, y, old_fb, false);
+}
+
+static int
+nv50_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+			struct drm_framebuffer *old_fb)
+{
+	return nv50_crtc_do_mode_set_base(crtc, x, y, old_fb, true);
+}
+
+static const struct drm_crtc_helper_funcs nv50_crtc_helper_funcs = {
+	.dpms = nv50_crtc_dpms,
+	.prepare = nv50_crtc_prepare,
+	.commit = nv50_crtc_commit,
+	.mode_fixup = nv50_crtc_mode_fixup,
+	.mode_set = nv50_crtc_mode_set,
+	.mode_set_base = nv50_crtc_mode_set_base,
+	.load_lut = nv50_crtc_lut_load,
+};
+
+int
+nv50_crtc_create(struct drm_device *dev, int index)
+{
+	struct nouveau_crtc *nv_crtc = NULL;
+	int ret, i;
+
+	NV_DEBUG(dev, "\n");
+
+	nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL);
+	if (!nv_crtc)
+		return -ENOMEM;
+
+	nv_crtc->mode = kzalloc(sizeof(*nv_crtc->mode), GFP_KERNEL);
+	if (!nv_crtc->mode) {
+		kfree(nv_crtc);
+		return -ENOMEM;
+	}
+
+	/* Default CLUT parameters, will be activated on the hw upon
+	 * first mode set.
+	 */
+	for (i = 0; i < 256; i++) {
+		nv_crtc->lut.r[i] = i << 8;
+		nv_crtc->lut.g[i] = i << 8;
+		nv_crtc->lut.b[i] = i << 8;
+	}
+	nv_crtc->lut.depth = 0;
+
+	ret = nouveau_bo_new(dev, NULL, 4096, 0x100, TTM_PL_FLAG_VRAM,
+			     0, 0x0000, false, true, &nv_crtc->lut.nvbo);
+	if (!ret) {
+		ret = nouveau_bo_pin(nv_crtc->lut.nvbo, TTM_PL_FLAG_VRAM);
+		if (!ret)
+			ret = nouveau_bo_map(nv_crtc->lut.nvbo);
+		if (ret)
+			nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo);
+	}
+
+	if (ret) {
+		kfree(nv_crtc->mode);
+		kfree(nv_crtc);
+		return ret;
+	}
+
+	nv_crtc->index = index;
+
+	/* set function pointers */
+	nv_crtc->set_dither = nv50_crtc_set_dither;
+	nv_crtc->set_scale = nv50_crtc_set_scale;
+
+	drm_crtc_init(dev, &nv_crtc->base, &nv50_crtc_funcs);
+	drm_crtc_helper_add(&nv_crtc->base, &nv50_crtc_helper_funcs);
+	drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256);
+
+	ret = nouveau_bo_new(dev, NULL, 64*64*4, 0x100, TTM_PL_FLAG_VRAM,
+			     0, 0x0000, false, true, &nv_crtc->cursor.nvbo);
+	if (!ret) {
+		ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM);
+		if (!ret)
+			ret = nouveau_bo_map(nv_crtc->cursor.nvbo);
+		if (ret)
+			nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
+	}
+
+	nv50_cursor_init(nv_crtc);
+	return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nv50_cursor.c b/drivers/gpu/drm/nouveau/nv50_cursor.c
new file mode 100644
index 0000000..e2e79a8
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv50_cursor.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "drm_mode.h"
+
+#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO)
+#include "nouveau_reg.h"
+#include "nouveau_drv.h"
+#include "nouveau_crtc.h"
+#include "nv50_display.h"
+
+static void
+nv50_cursor_show(struct nouveau_crtc *nv_crtc, bool update)
+{
+	struct drm_nouveau_private *dev_priv = nv_crtc->base.dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	struct drm_device *dev = nv_crtc->base.dev;
+	int ret;
+
+	NV_DEBUG(dev, "\n");
+
+	if (update && nv_crtc->cursor.visible)
+		return;
+
+	ret = RING_SPACE(evo, (dev_priv->chipset != 0x50 ? 5 : 3) + update * 2);
+	if (ret) {
+		NV_ERROR(dev, "no space while unhiding cursor\n");
+		return;
+	}
+
+	if (dev_priv->chipset != 0x50) {
+		BEGIN_RING(evo, 0, NV84_EVO_CRTC(nv_crtc->index, CURSOR_DMA), 1);
+		OUT_RING(evo, NvEvoVRAM);
+	}
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CURSOR_CTRL), 2);
+	OUT_RING(evo, NV50_EVO_CRTC_CURSOR_CTRL_SHOW);
+	OUT_RING(evo, nv_crtc->cursor.offset >> 8);
+
+	if (update) {
+		BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
+		OUT_RING(evo, 0);
+		FIRE_RING(evo);
+		nv_crtc->cursor.visible = true;
+	}
+}
+
+static void
+nv50_cursor_hide(struct nouveau_crtc *nv_crtc, bool update)
+{
+	struct drm_nouveau_private *dev_priv = nv_crtc->base.dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	struct drm_device *dev = nv_crtc->base.dev;
+	int ret;
+
+	NV_DEBUG(dev, "\n");
+
+	if (update && !nv_crtc->cursor.visible)
+		return;
+
+	ret = RING_SPACE(evo, (dev_priv->chipset != 0x50 ? 5 : 3) + update * 2);
+	if (ret) {
+		NV_ERROR(dev, "no space while hiding cursor\n");
+		return;
+	}
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CURSOR_CTRL), 2);
+	OUT_RING(evo, NV50_EVO_CRTC_CURSOR_CTRL_HIDE);
+	OUT_RING(evo, 0);
+	if (dev_priv->chipset != 0x50) {
+		BEGIN_RING(evo, 0, NV84_EVO_CRTC(nv_crtc->index, CURSOR_DMA), 1);
+		OUT_RING(evo, NV84_EVO_CRTC_CURSOR_DMA_HANDLE_NONE);
+	}
+
+	if (update) {
+		BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
+		OUT_RING(evo, 0);
+		FIRE_RING(evo);
+		nv_crtc->cursor.visible = false;
+	}
+}
+
+static void
+nv50_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y)
+{
+	struct drm_device *dev = nv_crtc->base.dev;
+
+	nv_wr32(dev, NV50_PDISPLAY_CURSOR_USER_POS(nv_crtc->index),
+		((y & 0xFFFF) << 16) | (x & 0xFFFF));
+	/* Needed to make the cursor move. */
+	nv_wr32(dev, NV50_PDISPLAY_CURSOR_USER_POS_CTRL(nv_crtc->index), 0);
+}
+
+static void
+nv50_cursor_set_offset(struct nouveau_crtc *nv_crtc, uint32_t offset)
+{
+	NV_DEBUG(nv_crtc->base.dev, "\n");
+	if (offset == nv_crtc->cursor.offset)
+		return;
+
+	nv_crtc->cursor.offset = offset;
+	if (nv_crtc->cursor.visible) {
+		nv_crtc->cursor.visible = false;
+		nv_crtc->cursor.show(nv_crtc, true);
+	}
+}
+
+int
+nv50_cursor_init(struct nouveau_crtc *nv_crtc)
+{
+	nv_crtc->cursor.set_offset = nv50_cursor_set_offset;
+	nv_crtc->cursor.set_pos = nv50_cursor_set_pos;
+	nv_crtc->cursor.hide = nv50_cursor_hide;
+	nv_crtc->cursor.show = nv50_cursor_show;
+	return 0;
+}
+
+void
+nv50_cursor_fini(struct nouveau_crtc *nv_crtc)
+{
+	struct drm_device *dev = nv_crtc->base.dev;
+	int idx = nv_crtc->index;
+
+	NV_DEBUG(dev, "\n");
+
+	nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), 0);
+	if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx),
+		     NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, 0)) {
+		NV_ERROR(dev, "timeout: CURSOR_CTRL2_STATUS == 0\n");
+		NV_ERROR(dev, "CURSOR_CTRL2 = 0x%08x\n",
+			 nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx)));
+	}
+}
+
diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c
new file mode 100644
index 0000000..fb5838e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv50_dac.c
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "drm_crtc_helper.h"
+
+#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO)
+#include "nouveau_reg.h"
+#include "nouveau_drv.h"
+#include "nouveau_dma.h"
+#include "nouveau_encoder.h"
+#include "nouveau_connector.h"
+#include "nouveau_crtc.h"
+#include "nv50_display.h"
+
+static void
+nv50_dac_disconnect(struct nouveau_encoder *nv_encoder)
+{
+	struct drm_device *dev = to_drm_encoder(nv_encoder)->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	int ret;
+
+	NV_DEBUG(dev, "Disconnecting DAC %d\n", nv_encoder->or);
+
+	ret = RING_SPACE(evo, 2);
+	if (ret) {
+		NV_ERROR(dev, "no space while disconnecting DAC\n");
+		return;
+	}
+	BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 1);
+	OUT_RING(evo, 0);
+}
+
+static enum drm_connector_status
+nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	enum drm_connector_status status = connector_status_disconnected;
+	uint32_t dpms_state, load_pattern, load_state;
+	int or = nv_encoder->or;
+
+	nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL1(or), 0x00000001);
+	dpms_state = nv_rd32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or));
+
+	nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or),
+		0x00150000 | NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING);
+	if (!nv_wait(NV50_PDISPLAY_DAC_DPMS_CTRL(or),
+		     NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING, 0)) {
+		NV_ERROR(dev, "timeout: DAC_DPMS_CTRL_PENDING(%d) == 0\n", or);
+		NV_ERROR(dev, "DAC_DPMS_CTRL(%d) = 0x%08x\n", or,
+			  nv_rd32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or)));
+		return status;
+	}
+
+	/* Use bios provided value if possible. */
+	if (dev_priv->vbios->dactestval) {
+		load_pattern = dev_priv->vbios->dactestval;
+		NV_DEBUG(dev, "Using bios provided load_pattern of %d\n",
+			  load_pattern);
+	} else {
+		load_pattern = 340;
+		NV_DEBUG(dev, "Using default load_pattern of %d\n",
+			 load_pattern);
+	}
+
+	nv_wr32(dev, NV50_PDISPLAY_DAC_LOAD_CTRL(or),
+		NV50_PDISPLAY_DAC_LOAD_CTRL_ACTIVE | load_pattern);
+	mdelay(45); /* give it some time to process */
+	load_state = nv_rd32(dev, NV50_PDISPLAY_DAC_LOAD_CTRL(or));
+
+	nv_wr32(dev, NV50_PDISPLAY_DAC_LOAD_CTRL(or), 0);
+	nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or), dpms_state |
+		NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING);
+
+	if ((load_state & NV50_PDISPLAY_DAC_LOAD_CTRL_PRESENT) ==
+			  NV50_PDISPLAY_DAC_LOAD_CTRL_PRESENT)
+		status = connector_status_connected;
+
+	if (status == connector_status_connected)
+		NV_DEBUG(dev, "Load was detected on output with or %d\n", or);
+	else
+		NV_DEBUG(dev, "Load was not detected on output with or %d\n", or);
+
+	return status;
+}
+
+static void
+nv50_dac_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	uint32_t val;
+	int or = nv_encoder->or;
+
+	NV_DEBUG(dev, "or %d mode %d\n", or, mode);
+
+	/* wait for it to be done */
+	if (!nv_wait(NV50_PDISPLAY_DAC_DPMS_CTRL(or),
+		     NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING, 0)) {
+		NV_ERROR(dev, "timeout: DAC_DPMS_CTRL_PENDING(%d) == 0\n", or);
+		NV_ERROR(dev, "DAC_DPMS_CTRL(%d) = 0x%08x\n", or,
+			 nv_rd32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or)));
+		return;
+	}
+
+	val = nv_rd32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or)) & ~0x7F;
+
+	if (mode != DRM_MODE_DPMS_ON)
+		val |= NV50_PDISPLAY_DAC_DPMS_CTRL_BLANKED;
+
+	switch (mode) {
+	case DRM_MODE_DPMS_STANDBY:
+		val |= NV50_PDISPLAY_DAC_DPMS_CTRL_HSYNC_OFF;
+		break;
+	case DRM_MODE_DPMS_SUSPEND:
+		val |= NV50_PDISPLAY_DAC_DPMS_CTRL_VSYNC_OFF;
+		break;
+	case DRM_MODE_DPMS_OFF:
+		val |= NV50_PDISPLAY_DAC_DPMS_CTRL_OFF;
+		val |= NV50_PDISPLAY_DAC_DPMS_CTRL_HSYNC_OFF;
+		val |= NV50_PDISPLAY_DAC_DPMS_CTRL_VSYNC_OFF;
+		break;
+	default:
+		break;
+	}
+
+	nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or), val |
+		NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING);
+}
+
+static void
+nv50_dac_save(struct drm_encoder *encoder)
+{
+	NV_ERROR(encoder->dev, "!!\n");
+}
+
+static void
+nv50_dac_restore(struct drm_encoder *encoder)
+{
+	NV_ERROR(encoder->dev, "!!\n");
+}
+
+static bool
+nv50_dac_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
+		    struct drm_display_mode *adjusted_mode)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct nouveau_connector *connector;
+
+	NV_DEBUG(encoder->dev, "or %d\n", nv_encoder->or);
+
+	connector = nouveau_encoder_connector_get(nv_encoder);
+	if (!connector) {
+		NV_ERROR(encoder->dev, "Encoder has no connector\n");
+		return false;
+	}
+
+	if (connector->scaling_mode != DRM_MODE_SCALE_NONE &&
+	     connector->native_mode) {
+		int id = adjusted_mode->base.id;
+		*adjusted_mode = *connector->native_mode;
+		adjusted_mode->base.id = id;
+	}
+
+	return true;
+}
+
+static void
+nv50_dac_prepare(struct drm_encoder *encoder)
+{
+}
+
+static void
+nv50_dac_commit(struct drm_encoder *encoder)
+{
+}
+
+static void
+nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
+		  struct drm_display_mode *adjusted_mode)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	struct nouveau_crtc *crtc = nouveau_crtc(encoder->crtc);
+	uint32_t mode_ctl = 0, mode_ctl2 = 0;
+	int ret;
+
+	NV_DEBUG(dev, "or %d\n", nv_encoder->or);
+
+	nv50_dac_dpms(encoder, DRM_MODE_DPMS_ON);
+
+	if (crtc->index == 1)
+		mode_ctl |= NV50_EVO_DAC_MODE_CTRL_CRTC1;
+	else
+		mode_ctl |= NV50_EVO_DAC_MODE_CTRL_CRTC0;
+
+	/* Lacking a working tv-out, this is not a 100% sure. */
+	if (nv_encoder->dcb->type == OUTPUT_ANALOG)
+		mode_ctl |= 0x40;
+	else
+	if (nv_encoder->dcb->type == OUTPUT_TV)
+		mode_ctl |= 0x100;
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
+		mode_ctl2 |= NV50_EVO_DAC_MODE_CTRL2_NHSYNC;
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
+		mode_ctl2 |= NV50_EVO_DAC_MODE_CTRL2_NVSYNC;
+
+	ret = RING_SPACE(evo, 3);
+	if (ret) {
+		NV_ERROR(dev, "no space while connecting DAC\n");
+		return;
+	}
+	BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 2);
+	OUT_RING(evo, mode_ctl);
+	OUT_RING(evo, mode_ctl2);
+}
+
+static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = {
+	.dpms = nv50_dac_dpms,
+	.save = nv50_dac_save,
+	.restore = nv50_dac_restore,
+	.mode_fixup = nv50_dac_mode_fixup,
+	.prepare = nv50_dac_prepare,
+	.commit = nv50_dac_commit,
+	.mode_set = nv50_dac_mode_set,
+	.detect = nv50_dac_detect
+};
+
+static void
+nv50_dac_destroy(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+	if (!encoder)
+		return;
+
+	NV_DEBUG(encoder->dev, "\n");
+
+	drm_encoder_cleanup(encoder);
+	kfree(nv_encoder);
+}
+
+static const struct drm_encoder_funcs nv50_dac_encoder_funcs = {
+	.destroy = nv50_dac_destroy,
+};
+
+int
+nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry)
+{
+	struct nouveau_encoder *nv_encoder;
+	struct drm_encoder *encoder;
+
+	NV_DEBUG(dev, "\n");
+	NV_INFO(dev, "Detected a DAC output\n");
+
+	nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
+	if (!nv_encoder)
+		return -ENOMEM;
+	encoder = to_drm_encoder(nv_encoder);
+
+	nv_encoder->dcb = entry;
+	nv_encoder->or = ffs(entry->or) - 1;
+
+	nv_encoder->disconnect = nv50_dac_disconnect;
+
+	drm_encoder_init(dev, encoder, &nv50_dac_encoder_funcs,
+			 DRM_MODE_ENCODER_DAC);
+	drm_encoder_helper_add(encoder, &nv50_dac_helper_funcs);
+
+	encoder->possible_crtcs = entry->heads;
+	encoder->possible_clones = 0;
+	return 0;
+}
+
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
new file mode 100644
index 0000000..12c5ee6
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -0,0 +1,1015 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "nv50_display.h"
+#include "nouveau_crtc.h"
+#include "nouveau_encoder.h"
+#include "nouveau_connector.h"
+#include "nouveau_fb.h"
+#include "drm_crtc_helper.h"
+
+static void
+nv50_evo_channel_del(struct nouveau_channel **pchan)
+{
+	struct nouveau_channel *chan = *pchan;
+
+	if (!chan)
+		return;
+	*pchan = NULL;
+
+	nouveau_gpuobj_channel_takedown(chan);
+	nouveau_bo_ref(NULL, &chan->pushbuf_bo);
+
+	if (chan->user)
+		iounmap(chan->user);
+
+	kfree(chan);
+}
+
+static int
+nv50_evo_dmaobj_new(struct nouveau_channel *evo, uint32_t class, uint32_t name,
+		    uint32_t tile_flags, uint32_t magic_flags,
+		    uint32_t offset, uint32_t limit)
+{
+	struct drm_nouveau_private *dev_priv = evo->dev->dev_private;
+	struct drm_device *dev = evo->dev;
+	struct nouveau_gpuobj *obj = NULL;
+	int ret;
+
+	ret = nouveau_gpuobj_new(dev, evo, 6*4, 32, 0, &obj);
+	if (ret)
+		return ret;
+	obj->engine = NVOBJ_ENGINE_DISPLAY;
+
+	ret = nouveau_gpuobj_ref_add(dev, evo, name, obj, NULL);
+	if (ret) {
+		nouveau_gpuobj_del(dev, &obj);
+		return ret;
+	}
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	nv_wo32(dev, obj, 0, (tile_flags << 22) | (magic_flags << 16) | class);
+	nv_wo32(dev, obj, 1, limit);
+	nv_wo32(dev, obj, 2, offset);
+	nv_wo32(dev, obj, 3, 0x00000000);
+	nv_wo32(dev, obj, 4, 0x00000000);
+	nv_wo32(dev, obj, 5, 0x00010000);
+	dev_priv->engine.instmem.finish_access(dev);
+
+	return 0;
+}
+
+static int
+nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan;
+	int ret;
+
+	chan = kzalloc(sizeof(struct nouveau_channel), GFP_KERNEL);
+	if (!chan)
+		return -ENOMEM;
+	*pchan = chan;
+
+	chan->id = -1;
+	chan->dev = dev;
+	chan->user_get = 4;
+	chan->user_put = 0;
+
+	INIT_LIST_HEAD(&chan->ramht_refs);
+
+	ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 32768, 0x1000,
+				     NVOBJ_FLAG_ZERO_ALLOC, &chan->ramin);
+	if (ret) {
+		NV_ERROR(dev, "Error allocating EVO channel memory: %d\n", ret);
+		nv50_evo_channel_del(pchan);
+		return ret;
+	}
+
+	ret = nouveau_mem_init_heap(&chan->ramin_heap, chan->ramin->gpuobj->
+				    im_pramin->start, 32768);
+	if (ret) {
+		NV_ERROR(dev, "Error initialising EVO PRAMIN heap: %d\n", ret);
+		nv50_evo_channel_del(pchan);
+		return ret;
+	}
+
+	ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0, 4096, 16,
+				     0, &chan->ramht);
+	if (ret) {
+		NV_ERROR(dev, "Unable to allocate EVO RAMHT: %d\n", ret);
+		nv50_evo_channel_del(pchan);
+		return ret;
+	}
+
+	if (dev_priv->chipset != 0x50) {
+		ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoFB16, 0x70, 0x19,
+					  0, 0xffffffff);
+		if (ret) {
+			nv50_evo_channel_del(pchan);
+			return ret;
+		}
+
+
+		ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoFB32, 0x7a, 0x19,
+					  0, 0xffffffff);
+		if (ret) {
+			nv50_evo_channel_del(pchan);
+			return ret;
+		}
+	}
+
+	ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoVRAM, 0, 0x19,
+				  0, nouveau_mem_fb_amount(dev));
+	if (ret) {
+		nv50_evo_channel_del(pchan);
+		return ret;
+	}
+
+	ret = nouveau_bo_new(dev, NULL, 4096, 0, TTM_PL_FLAG_VRAM, 0, 0,
+			     false, true, &chan->pushbuf_bo);
+	if (ret == 0)
+		ret = nouveau_bo_pin(chan->pushbuf_bo, TTM_PL_FLAG_VRAM);
+	if (ret) {
+		NV_ERROR(dev, "Error creating EVO DMA push buffer: %d\n", ret);
+		nv50_evo_channel_del(pchan);
+		return ret;
+	}
+
+	ret = nouveau_bo_map(chan->pushbuf_bo);
+	if (ret) {
+		NV_ERROR(dev, "Error mapping EVO DMA push buffer: %d\n", ret);
+		nv50_evo_channel_del(pchan);
+		return ret;
+	}
+
+	chan->user = ioremap(pci_resource_start(dev->pdev, 0) +
+					NV50_PDISPLAY_USER(0), PAGE_SIZE);
+	if (!chan->user) {
+		NV_ERROR(dev, "Error mapping EVO control regs.\n");
+		nv50_evo_channel_del(pchan);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+int
+nv50_display_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
+	struct nouveau_channel *evo = dev_priv->evo;
+	struct drm_connector *connector;
+	uint32_t val, ram_amount, hpd_en[2];
+	uint64_t start;
+	int ret, i;
+
+	NV_DEBUG(dev, "\n");
+
+	nv_wr32(dev, 0x00610184, nv_rd32(dev, 0x00614004));
+	/*
+	 * I think the 0x006101XX range is some kind of main control area
+	 * that enables things.
+	 */
+	/* CRTC? */
+	for (i = 0; i < 2; i++) {
+		val = nv_rd32(dev, 0x00616100 + (i * 0x800));
+		nv_wr32(dev, 0x00610190 + (i * 0x10), val);
+		val = nv_rd32(dev, 0x00616104 + (i * 0x800));
+		nv_wr32(dev, 0x00610194 + (i * 0x10), val);
+		val = nv_rd32(dev, 0x00616108 + (i * 0x800));
+		nv_wr32(dev, 0x00610198 + (i * 0x10), val);
+		val = nv_rd32(dev, 0x0061610c + (i * 0x800));
+		nv_wr32(dev, 0x0061019c + (i * 0x10), val);
+	}
+	/* DAC */
+	for (i = 0; i < 3; i++) {
+		val = nv_rd32(dev, 0x0061a000 + (i * 0x800));
+		nv_wr32(dev, 0x006101d0 + (i * 0x04), val);
+	}
+	/* SOR */
+	for (i = 0; i < 4; i++) {
+		val = nv_rd32(dev, 0x0061c000 + (i * 0x800));
+		nv_wr32(dev, 0x006101e0 + (i * 0x04), val);
+	}
+	/* Something not yet in use, tv-out maybe. */
+	for (i = 0; i < 3; i++) {
+		val = nv_rd32(dev, 0x0061e000 + (i * 0x800));
+		nv_wr32(dev, 0x006101f0 + (i * 0x04), val);
+	}
+
+	for (i = 0; i < 3; i++) {
+		nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(i), 0x00550000 |
+			NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING);
+		nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL1(i), 0x00000001);
+	}
+
+	/* This used to be in crtc unblank, but seems out of place there. */
+	nv_wr32(dev, NV50_PDISPLAY_UNK_380, 0);
+	/* RAM is clamped to 256 MiB. */
+	ram_amount = nouveau_mem_fb_amount(dev);
+	NV_DEBUG(dev, "ram_amount %d\n", ram_amount);
+	if (ram_amount > 256*1024*1024)
+		ram_amount = 256*1024*1024;
+	nv_wr32(dev, NV50_PDISPLAY_RAM_AMOUNT, ram_amount - 1);
+	nv_wr32(dev, NV50_PDISPLAY_UNK_388, 0x150000);
+	nv_wr32(dev, NV50_PDISPLAY_UNK_38C, 0);
+
+	/* The precise purpose is unknown, i suspect it has something to do
+	 * with text mode.
+	 */
+	if (nv_rd32(dev, NV50_PDISPLAY_INTR_1) & 0x100) {
+		nv_wr32(dev, NV50_PDISPLAY_INTR_1, 0x100);
+		nv_wr32(dev, 0x006194e8, nv_rd32(dev, 0x006194e8) & ~1);
+		if (!nv_wait(0x006194e8, 2, 0)) {
+			NV_ERROR(dev, "timeout: (0x6194e8 & 2) != 0\n");
+			NV_ERROR(dev, "0x6194e8 = 0x%08x\n",
+						nv_rd32(dev, 0x6194e8));
+			return -EBUSY;
+		}
+	}
+
+	/* taken from nv bug #12637, attempts to un-wedge the hw if it's
+	 * stuck in some unspecified state
+	 */
+	start = ptimer->read(dev);
+	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x2b00);
+	while ((val = nv_rd32(dev, NV50_PDISPLAY_CHANNEL_STAT(0))) & 0x1e0000) {
+		if ((val & 0x9f0000) == 0x20000)
+			nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0),
+							val | 0x800000);
+
+		if ((val & 0x3f0000) == 0x30000)
+			nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0),
+							val | 0x200000);
+
+		if (ptimer->read(dev) - start > 1000000000ULL) {
+			NV_ERROR(dev, "timeout: (0x610200 & 0x1e0000) != 0\n");
+			NV_ERROR(dev, "0x610200 = 0x%08x\n", val);
+			return -EBUSY;
+		}
+	}
+
+	nv_wr32(dev, NV50_PDISPLAY_CTRL_STATE, NV50_PDISPLAY_CTRL_STATE_ENABLE);
+	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x1000b03);
+	if (!nv_wait(NV50_PDISPLAY_CHANNEL_STAT(0), 0x40000000, 0x40000000)) {
+		NV_ERROR(dev, "timeout: (0x610200 & 0x40000000) == 0x40000000\n");
+		NV_ERROR(dev, "0x610200 = 0x%08x\n",
+			  nv_rd32(dev, NV50_PDISPLAY_CHANNEL_STAT(0)));
+		return -EBUSY;
+	}
+
+	for (i = 0; i < 2; i++) {
+		nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), 0x2000);
+		if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
+			     NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, 0)) {
+			NV_ERROR(dev, "timeout: CURSOR_CTRL2_STATUS == 0\n");
+			NV_ERROR(dev, "CURSOR_CTRL2 = 0x%08x\n",
+				 nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i)));
+			return -EBUSY;
+		}
+
+		nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
+			NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_ON);
+		if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
+			     NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS,
+			     NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE)) {
+			NV_ERROR(dev, "timeout: "
+				      "CURSOR_CTRL2_STATUS_ACTIVE(%d)\n", i);
+			NV_ERROR(dev, "CURSOR_CTRL2(%d) = 0x%08x\n", i,
+				 nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i)));
+			return -EBUSY;
+		}
+	}
+
+	nv_wr32(dev, NV50_PDISPLAY_OBJECTS, (evo->ramin->instance >> 8) | 9);
+
+	/* initialise fifo */
+	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_DMA_CB(0),
+		((evo->pushbuf_bo->bo.mem.mm_node->start << PAGE_SHIFT) >> 8) |
+		NV50_PDISPLAY_CHANNEL_DMA_CB_LOCATION_VRAM |
+		NV50_PDISPLAY_CHANNEL_DMA_CB_VALID);
+	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_UNK2(0), 0x00010000);
+	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_UNK3(0), 0x00000002);
+	if (!nv_wait(0x610200, 0x80000000, 0x00000000)) {
+		NV_ERROR(dev, "timeout: (0x610200 & 0x80000000) == 0\n");
+		NV_ERROR(dev, "0x610200 = 0x%08x\n", nv_rd32(dev, 0x610200));
+		return -EBUSY;
+	}
+	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0),
+		(nv_rd32(dev, NV50_PDISPLAY_CHANNEL_STAT(0)) & ~0x00000003) |
+		 NV50_PDISPLAY_CHANNEL_STAT_DMA_ENABLED);
+	nv_wr32(dev, NV50_PDISPLAY_USER_PUT(0), 0);
+	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x01000003 |
+		NV50_PDISPLAY_CHANNEL_STAT_DMA_ENABLED);
+	nv_wr32(dev, 0x610300, nv_rd32(dev, 0x610300) & ~1);
+
+	evo->dma.max = (4096/4) - 2;
+	evo->dma.put = 0;
+	evo->dma.cur = evo->dma.put;
+	evo->dma.free = evo->dma.max - evo->dma.cur;
+
+	ret = RING_SPACE(evo, NOUVEAU_DMA_SKIPS);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < NOUVEAU_DMA_SKIPS; i++)
+		OUT_RING(evo, 0);
+
+	ret = RING_SPACE(evo, 11);
+	if (ret)
+		return ret;
+	BEGIN_RING(evo, 0, NV50_EVO_UNK84, 2);
+	OUT_RING(evo, NV50_EVO_UNK84_NOTIFY_DISABLED);
+	OUT_RING(evo, NV50_EVO_DMA_NOTIFY_HANDLE_NONE);
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, FB_DMA), 1);
+	OUT_RING(evo, NV50_EVO_CRTC_FB_DMA_HANDLE_NONE);
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, UNK0800), 1);
+	OUT_RING(evo, 0);
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, DISPLAY_START), 1);
+	OUT_RING(evo, 0);
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, UNK082C), 1);
+	OUT_RING(evo, 0);
+	FIRE_RING(evo);
+	if (!nv_wait(0x640004, 0xffffffff, evo->dma.put << 2))
+		NV_ERROR(dev, "evo pushbuf stalled\n");
+
+	/* enable clock change interrupts. */
+	nv_wr32(dev, 0x610028, 0x00010001);
+	nv_wr32(dev, NV50_PDISPLAY_INTR_EN, (NV50_PDISPLAY_INTR_EN_CLK_UNK10 |
+					     NV50_PDISPLAY_INTR_EN_CLK_UNK20 |
+					     NV50_PDISPLAY_INTR_EN_CLK_UNK40));
+
+	/* enable hotplug interrupts */
+	hpd_en[0] = hpd_en[1] = 0;
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		struct nouveau_connector *conn = nouveau_connector(connector);
+		struct dcb_gpio_entry *gpio;
+
+		if (connector->connector_type != DRM_MODE_CONNECTOR_DVII &&
+		    connector->connector_type != DRM_MODE_CONNECTOR_DVID &&
+		    connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
+			continue;
+
+		gpio = nouveau_bios_gpio_entry(dev, conn->dcb->gpio_tag);
+		if (!gpio)
+			continue;
+
+		hpd_en[gpio->line >> 4] |= (0x00010001 << (gpio->line & 0xf));
+	}
+
+	nv_wr32(dev, 0xe054, 0xffffffff);
+	nv_wr32(dev, 0xe050, hpd_en[0]);
+	if (dev_priv->chipset >= 0x90) {
+		nv_wr32(dev, 0xe074, 0xffffffff);
+		nv_wr32(dev, 0xe070, hpd_en[1]);
+	}
+
+	return 0;
+}
+
+static int nv50_display_disable(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_crtc *drm_crtc;
+	int ret, i;
+
+	NV_DEBUG(dev, "\n");
+
+	list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) {
+		struct nouveau_crtc *crtc = nouveau_crtc(drm_crtc);
+
+		nv50_crtc_blank(crtc, true);
+	}
+
+	ret = RING_SPACE(dev_priv->evo, 2);
+	if (ret == 0) {
+		BEGIN_RING(dev_priv->evo, 0, NV50_EVO_UPDATE, 1);
+		OUT_RING(dev_priv->evo, 0);
+	}
+	FIRE_RING(dev_priv->evo);
+
+	/* Almost like ack'ing a vblank interrupt, maybe in the spirit of
+	 * cleaning up?
+	 */
+	list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) {
+		struct nouveau_crtc *crtc = nouveau_crtc(drm_crtc);
+		uint32_t mask = NV50_PDISPLAY_INTR_1_VBLANK_CRTC_(crtc->index);
+
+		if (!crtc->base.enabled)
+			continue;
+
+		nv_wr32(dev, NV50_PDISPLAY_INTR_1, mask);
+		if (!nv_wait(NV50_PDISPLAY_INTR_1, mask, mask)) {
+			NV_ERROR(dev, "timeout: (0x610024 & 0x%08x) == "
+				      "0x%08x\n", mask, mask);
+			NV_ERROR(dev, "0x610024 = 0x%08x\n",
+				 nv_rd32(dev, NV50_PDISPLAY_INTR_1));
+		}
+	}
+
+	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0);
+	nv_wr32(dev, NV50_PDISPLAY_CTRL_STATE, 0);
+	if (!nv_wait(NV50_PDISPLAY_CHANNEL_STAT(0), 0x1e0000, 0)) {
+		NV_ERROR(dev, "timeout: (0x610200 & 0x1e0000) == 0\n");
+		NV_ERROR(dev, "0x610200 = 0x%08x\n",
+			  nv_rd32(dev, NV50_PDISPLAY_CHANNEL_STAT(0)));
+	}
+
+	for (i = 0; i < 3; i++) {
+		if (!nv_wait(NV50_PDISPLAY_SOR_DPMS_STATE(i),
+			     NV50_PDISPLAY_SOR_DPMS_STATE_WAIT, 0)) {
+			NV_ERROR(dev, "timeout: SOR_DPMS_STATE_WAIT(%d) == 0\n", i);
+			NV_ERROR(dev, "SOR_DPMS_STATE(%d) = 0x%08x\n", i,
+				  nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_STATE(i)));
+		}
+	}
+
+	/* disable interrupts. */
+	nv_wr32(dev, NV50_PDISPLAY_INTR_EN, 0x00000000);
+
+	/* disable hotplug interrupts */
+	nv_wr32(dev, 0xe054, 0xffffffff);
+	nv_wr32(dev, 0xe050, 0x00000000);
+	if (dev_priv->chipset >= 0x90) {
+		nv_wr32(dev, 0xe074, 0xffffffff);
+		nv_wr32(dev, 0xe070, 0x00000000);
+	}
+	return 0;
+}
+
+int nv50_display_create(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct parsed_dcb *dcb = dev_priv->vbios->dcb;
+	uint32_t connector[16] = {};
+	int ret, i;
+
+	NV_DEBUG(dev, "\n");
+
+	/* init basic kernel modesetting */
+	drm_mode_config_init(dev);
+
+	/* Initialise some optional connector properties. */
+	drm_mode_create_scaling_mode_property(dev);
+	drm_mode_create_dithering_property(dev);
+
+	dev->mode_config.min_width = 0;
+	dev->mode_config.min_height = 0;
+
+	dev->mode_config.funcs = (void *)&nouveau_mode_config_funcs;
+
+	dev->mode_config.max_width = 8192;
+	dev->mode_config.max_height = 8192;
+
+	dev->mode_config.fb_base = dev_priv->fb_phys;
+
+	/* Create EVO channel */
+	ret = nv50_evo_channel_new(dev, &dev_priv->evo);
+	if (ret) {
+		NV_ERROR(dev, "Error creating EVO channel: %d\n", ret);
+		return ret;
+	}
+
+	/* Create CRTC objects */
+	for (i = 0; i < 2; i++)
+		nv50_crtc_create(dev, i);
+
+	/* We setup the encoders from the BIOS table */
+	for (i = 0 ; i < dcb->entries; i++) {
+		struct dcb_entry *entry = &dcb->entry[i];
+
+		if (entry->location != DCB_LOC_ON_CHIP) {
+			NV_WARN(dev, "Off-chip encoder %d/%d unsupported\n",
+				entry->type, ffs(entry->or) - 1);
+			continue;
+		}
+
+		switch (entry->type) {
+		case OUTPUT_TMDS:
+		case OUTPUT_LVDS:
+		case OUTPUT_DP:
+			nv50_sor_create(dev, entry);
+			break;
+		case OUTPUT_ANALOG:
+			nv50_dac_create(dev, entry);
+			break;
+		default:
+			NV_WARN(dev, "DCB encoder %d unknown\n", entry->type);
+			continue;
+		}
+
+		connector[entry->connector] |= (1 << entry->type);
+	}
+
+	/* It appears that DCB 3.0+ VBIOS has a connector table, however,
+	 * I'm not 100% certain how to decode it correctly yet so just
+	 * look at what encoders are present on each connector index and
+	 * attempt to derive the connector type from that.
+	 */
+	for (i = 0 ; i < dcb->entries; i++) {
+		struct dcb_entry *entry = &dcb->entry[i];
+		uint16_t encoders;
+		int type;
+
+		encoders = connector[entry->connector];
+		if (!(encoders & (1 << entry->type)))
+			continue;
+		connector[entry->connector] = 0;
+
+		if (encoders & (1 << OUTPUT_DP)) {
+			type = DRM_MODE_CONNECTOR_DisplayPort;
+		} else if (encoders & (1 << OUTPUT_TMDS)) {
+			if (encoders & (1 << OUTPUT_ANALOG))
+				type = DRM_MODE_CONNECTOR_DVII;
+			else
+				type = DRM_MODE_CONNECTOR_DVID;
+		} else if (encoders & (1 << OUTPUT_ANALOG)) {
+			type = DRM_MODE_CONNECTOR_VGA;
+		} else if (encoders & (1 << OUTPUT_LVDS)) {
+			type = DRM_MODE_CONNECTOR_LVDS;
+		} else {
+			type = DRM_MODE_CONNECTOR_Unknown;
+		}
+
+		if (type == DRM_MODE_CONNECTOR_Unknown)
+			continue;
+
+		nouveau_connector_create(dev, entry->connector, type);
+	}
+
+	ret = nv50_display_init(dev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+int nv50_display_destroy(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	NV_DEBUG(dev, "\n");
+
+	drm_mode_config_cleanup(dev);
+
+	nv50_display_disable(dev);
+	nv50_evo_channel_del(&dev_priv->evo);
+
+	return 0;
+}
+
+static inline uint32_t
+nv50_display_mode_ctrl(struct drm_device *dev, bool sor, int or)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t mc;
+
+	if (sor) {
+		if (dev_priv->chipset < 0x90 ||
+		    dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0)
+			mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_P(or));
+		else
+			mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_P(or));
+	} else {
+		mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_P(or));
+	}
+
+	return mc;
+}
+
+static int
+nv50_display_irq_head(struct drm_device *dev, int *phead,
+		      struct dcb_entry **pdcbent)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t unk30 = nv_rd32(dev, NV50_PDISPLAY_UNK30_CTRL);
+	uint32_t dac = 0, sor = 0;
+	int head, i, or = 0, type = OUTPUT_ANY;
+
+	/* We're assuming that head 0 *or* head 1 will be active here,
+	 * and not both.  I'm not sure if the hw will even signal both
+	 * ever, but it definitely shouldn't for us as we commit each
+	 * CRTC separately, and submission will be blocked by the GPU
+	 * until we handle each in turn.
+	 */
+	NV_DEBUG(dev, "0x610030: 0x%08x\n", unk30);
+	head = ffs((unk30 >> 9) & 3) - 1;
+	if (head < 0)
+		return -EINVAL;
+
+	/* This assumes CRTCs are never bound to multiple encoders, which
+	 * should be the case.
+	 */
+	for (i = 0; i < 3 && type == OUTPUT_ANY; i++) {
+		uint32_t mc = nv50_display_mode_ctrl(dev, false, i);
+		if (!(mc & (1 << head)))
+			continue;
+
+		switch ((mc >> 8) & 0xf) {
+		case 0: type = OUTPUT_ANALOG; break;
+		case 1: type = OUTPUT_TV; break;
+		default:
+			NV_ERROR(dev, "unknown dac mode_ctrl: 0x%08x\n", dac);
+			return -1;
+		}
+
+		or = i;
+	}
+
+	for (i = 0; i < 4 && type == OUTPUT_ANY; i++) {
+		uint32_t mc = nv50_display_mode_ctrl(dev, true, i);
+		if (!(mc & (1 << head)))
+			continue;
+
+		switch ((mc >> 8) & 0xf) {
+		case 0: type = OUTPUT_LVDS; break;
+		case 1: type = OUTPUT_TMDS; break;
+		case 2: type = OUTPUT_TMDS; break;
+		case 5: type = OUTPUT_TMDS; break;
+		case 8: type = OUTPUT_DP; break;
+		case 9: type = OUTPUT_DP; break;
+		default:
+			NV_ERROR(dev, "unknown sor mode_ctrl: 0x%08x\n", sor);
+			return -1;
+		}
+
+		or = i;
+	}
+
+	NV_DEBUG(dev, "type %d, or %d\n", type, or);
+	if (type == OUTPUT_ANY) {
+		NV_ERROR(dev, "unknown encoder!!\n");
+		return -1;
+	}
+
+	for (i = 0; i < dev_priv->vbios->dcb->entries; i++) {
+		struct dcb_entry *dcbent = &dev_priv->vbios->dcb->entry[i];
+
+		if (dcbent->type != type)
+			continue;
+
+		if (!(dcbent->or & (1 << or)))
+			continue;
+
+		*phead = head;
+		*pdcbent = dcbent;
+		return 0;
+	}
+
+	NV_ERROR(dev, "no DCB entry for %d %d\n", dac != 0, or);
+	return 0;
+}
+
+static uint32_t
+nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcbent,
+			   int pxclk)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	uint32_t mc, script = 0, or;
+
+	or = ffs(dcbent->or) - 1;
+	mc = nv50_display_mode_ctrl(dev, dcbent->type != OUTPUT_ANALOG, or);
+	switch (dcbent->type) {
+	case OUTPUT_LVDS:
+		script = (mc >> 8) & 0xf;
+		if (bios->pub.fp_no_ddc) {
+			if (bios->fp.dual_link)
+				script |= 0x0100;
+			if (bios->fp.if_is_24bit)
+				script |= 0x0200;
+		} else {
+			if (pxclk >= bios->fp.duallink_transition_clk) {
+				script |= 0x0100;
+				if (bios->fp.strapless_is_24bit & 2)
+					script |= 0x0200;
+			} else
+			if (bios->fp.strapless_is_24bit & 1)
+				script |= 0x0200;
+		}
+
+		if (nouveau_uscript_lvds >= 0) {
+			NV_INFO(dev, "override script 0x%04x with 0x%04x "
+				     "for output LVDS-%d\n", script,
+				     nouveau_uscript_lvds, or);
+			script = nouveau_uscript_lvds;
+		}
+		break;
+	case OUTPUT_TMDS:
+		script = (mc >> 8) & 0xf;
+		if (pxclk >= 165000)
+			script |= 0x0100;
+
+		if (nouveau_uscript_tmds >= 0) {
+			NV_INFO(dev, "override script 0x%04x with 0x%04x "
+				     "for output TMDS-%d\n", script,
+				     nouveau_uscript_tmds, or);
+			script = nouveau_uscript_tmds;
+		}
+		break;
+	case OUTPUT_DP:
+		script = (mc >> 8) & 0xf;
+		break;
+	case OUTPUT_ANALOG:
+		script = 0xff;
+		break;
+	default:
+		NV_ERROR(dev, "modeset on unsupported output type!\n");
+		break;
+	}
+
+	return script;
+}
+
+static void
+nv50_display_vblank_crtc_handler(struct drm_device *dev, int crtc)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan;
+	struct list_head *entry, *tmp;
+
+	list_for_each_safe(entry, tmp, &dev_priv->vbl_waiting) {
+		chan = list_entry(entry, struct nouveau_channel, nvsw.vbl_wait);
+
+		nouveau_bo_wr32(chan->notifier_bo, chan->nvsw.vblsem_offset,
+						chan->nvsw.vblsem_rval);
+		list_del(&chan->nvsw.vbl_wait);
+	}
+}
+
+static void
+nv50_display_vblank_handler(struct drm_device *dev, uint32_t intr)
+{
+	intr &= NV50_PDISPLAY_INTR_1_VBLANK_CRTC;
+
+	if (intr & NV50_PDISPLAY_INTR_1_VBLANK_CRTC_0)
+		nv50_display_vblank_crtc_handler(dev, 0);
+
+	if (intr & NV50_PDISPLAY_INTR_1_VBLANK_CRTC_1)
+		nv50_display_vblank_crtc_handler(dev, 1);
+
+	nv_wr32(dev, NV50_PDISPLAY_INTR_EN, nv_rd32(dev,
+		     NV50_PDISPLAY_INTR_EN) & ~intr);
+	nv_wr32(dev, NV50_PDISPLAY_INTR_1, intr);
+}
+
+static void
+nv50_display_unk10_handler(struct drm_device *dev)
+{
+	struct dcb_entry *dcbent;
+	int head, ret;
+
+	ret = nv50_display_irq_head(dev, &head, &dcbent);
+	if (ret)
+		goto ack;
+
+	nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) & ~8);
+
+	nouveau_bios_run_display_table(dev, dcbent, 0, -1);
+
+ack:
+	nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK10);
+	nv_wr32(dev, 0x610030, 0x80000000);
+}
+
+static void
+nv50_display_unk20_handler(struct drm_device *dev)
+{
+	struct dcb_entry *dcbent;
+	uint32_t tmp, pclk, script;
+	int head, or, ret;
+
+	ret = nv50_display_irq_head(dev, &head, &dcbent);
+	if (ret)
+		goto ack;
+	or = ffs(dcbent->or) - 1;
+	pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff;
+	script = nv50_display_script_select(dev, dcbent, pclk);
+
+	NV_DEBUG(dev, "head %d pxclk: %dKHz\n", head, pclk);
+
+	if (dcbent->type != OUTPUT_DP)
+		nouveau_bios_run_display_table(dev, dcbent, 0, -2);
+
+	nv50_crtc_set_clock(dev, head, pclk);
+
+	nouveau_bios_run_display_table(dev, dcbent, script, pclk);
+
+	tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head));
+	tmp &= ~0x000000f;
+	nv_wr32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head), tmp);
+
+	if (dcbent->type != OUTPUT_ANALOG) {
+		tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_CLK_CTRL2(or));
+		tmp &= ~0x00000f0f;
+		if (script & 0x0100)
+			tmp |= 0x00000101;
+		nv_wr32(dev, NV50_PDISPLAY_SOR_CLK_CTRL2(or), tmp);
+	} else {
+		nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL2(or), 0);
+	}
+
+ack:
+	nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK20);
+	nv_wr32(dev, 0x610030, 0x80000000);
+}
+
+static void
+nv50_display_unk40_handler(struct drm_device *dev)
+{
+	struct dcb_entry *dcbent;
+	int head, pclk, script, ret;
+
+	ret = nv50_display_irq_head(dev, &head, &dcbent);
+	if (ret)
+		goto ack;
+	pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff;
+	script = nv50_display_script_select(dev, dcbent, pclk);
+
+	nouveau_bios_run_display_table(dev, dcbent, script, -pclk);
+
+ack:
+	nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK40);
+	nv_wr32(dev, 0x610030, 0x80000000);
+	nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) | 8);
+}
+
+void
+nv50_display_irq_handler_bh(struct work_struct *work)
+{
+	struct drm_nouveau_private *dev_priv =
+		container_of(work, struct drm_nouveau_private, irq_work);
+	struct drm_device *dev = dev_priv->dev;
+
+	for (;;) {
+		uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0);
+		uint32_t intr1 = nv_rd32(dev, NV50_PDISPLAY_INTR_1);
+
+		NV_DEBUG(dev, "PDISPLAY_INTR_BH 0x%08x 0x%08x\n", intr0, intr1);
+
+		if (intr1 & NV50_PDISPLAY_INTR_1_CLK_UNK10)
+			nv50_display_unk10_handler(dev);
+		else
+		if (intr1 & NV50_PDISPLAY_INTR_1_CLK_UNK20)
+			nv50_display_unk20_handler(dev);
+		else
+		if (intr1 & NV50_PDISPLAY_INTR_1_CLK_UNK40)
+			nv50_display_unk40_handler(dev);
+		else
+			break;
+	}
+
+	nv_wr32(dev, NV03_PMC_INTR_EN_0, 1);
+}
+
+static void
+nv50_display_error_handler(struct drm_device *dev)
+{
+	uint32_t addr, data;
+
+	nv_wr32(dev, NV50_PDISPLAY_INTR_0, 0x00010000);
+	addr = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_ADDR);
+	data = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_DATA);
+
+	NV_ERROR(dev, "EvoCh %d Mthd 0x%04x Data 0x%08x (0x%04x 0x%02x)\n",
+		 0, addr & 0xffc, data, addr >> 16, (addr >> 12) & 0xf);
+
+	nv_wr32(dev, NV50_PDISPLAY_TRAPPED_ADDR, 0x90000000);
+}
+
+static void
+nv50_display_irq_hotplug(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_connector *connector;
+	const uint32_t gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
+	uint32_t unplug_mask, plug_mask, change_mask;
+	uint32_t hpd0, hpd1 = 0;
+
+	hpd0 = nv_rd32(dev, 0xe054) & nv_rd32(dev, 0xe050);
+	if (dev_priv->chipset >= 0x90)
+		hpd1 = nv_rd32(dev, 0xe074) & nv_rd32(dev, 0xe070);
+
+	plug_mask   = (hpd0 & 0x0000ffff) | (hpd1 << 16);
+	unplug_mask = (hpd0 >> 16) | (hpd1 & 0xffff0000);
+	change_mask = plug_mask | unplug_mask;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		struct drm_encoder_helper_funcs *helper;
+		struct nouveau_connector *nv_connector =
+			nouveau_connector(connector);
+		struct nouveau_encoder *nv_encoder;
+		struct dcb_gpio_entry *gpio;
+		uint32_t reg;
+		bool plugged;
+
+		if (!nv_connector->dcb)
+			continue;
+
+		gpio = nouveau_bios_gpio_entry(dev, nv_connector->dcb->gpio_tag);
+		if (!gpio || !(change_mask & (1 << gpio->line)))
+			continue;
+
+		reg = nv_rd32(dev, gpio_reg[gpio->line >> 3]);
+		plugged = !!(reg & (4 << ((gpio->line & 7) << 2)));
+		NV_INFO(dev, "%splugged %s\n", plugged ? "" : "un",
+			drm_get_connector_name(connector)) ;
+
+		if (!connector->encoder || !connector->encoder->crtc ||
+		    !connector->encoder->crtc->enabled)
+			continue;
+		nv_encoder = nouveau_encoder(connector->encoder);
+		helper = connector->encoder->helper_private;
+
+		if (nv_encoder->dcb->type != OUTPUT_DP)
+			continue;
+
+		if (plugged)
+			helper->dpms(connector->encoder, DRM_MODE_DPMS_ON);
+		else
+			helper->dpms(connector->encoder, DRM_MODE_DPMS_OFF);
+	}
+
+	nv_wr32(dev, 0xe054, nv_rd32(dev, 0xe054));
+	if (dev_priv->chipset >= 0x90)
+		nv_wr32(dev, 0xe074, nv_rd32(dev, 0xe074));
+}
+
+void
+nv50_display_irq_handler(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t delayed = 0;
+
+	while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG)
+		nv50_display_irq_hotplug(dev);
+
+	while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) {
+		uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0);
+		uint32_t intr1 = nv_rd32(dev, NV50_PDISPLAY_INTR_1);
+		uint32_t clock;
+
+		NV_DEBUG(dev, "PDISPLAY_INTR 0x%08x 0x%08x\n", intr0, intr1);
+
+		if (!intr0 && !(intr1 & ~delayed))
+			break;
+
+		if (intr0 & 0x00010000) {
+			nv50_display_error_handler(dev);
+			intr0 &= ~0x00010000;
+		}
+
+		if (intr1 & NV50_PDISPLAY_INTR_1_VBLANK_CRTC) {
+			nv50_display_vblank_handler(dev, intr1);
+			intr1 &= ~NV50_PDISPLAY_INTR_1_VBLANK_CRTC;
+		}
+
+		clock = (intr1 & (NV50_PDISPLAY_INTR_1_CLK_UNK10 |
+				  NV50_PDISPLAY_INTR_1_CLK_UNK20 |
+				  NV50_PDISPLAY_INTR_1_CLK_UNK40));
+		if (clock) {
+			nv_wr32(dev, NV03_PMC_INTR_EN_0, 0);
+			if (!work_pending(&dev_priv->irq_work))
+				queue_work(dev_priv->wq, &dev_priv->irq_work);
+			delayed |= clock;
+			intr1 &= ~clock;
+		}
+
+		if (intr0) {
+			NV_ERROR(dev, "unknown PDISPLAY_INTR_0: 0x%08x\n", intr0);
+			nv_wr32(dev, NV50_PDISPLAY_INTR_0, intr0);
+		}
+
+		if (intr1) {
+			NV_ERROR(dev,
+				 "unknown PDISPLAY_INTR_1: 0x%08x\n", intr1);
+			nv_wr32(dev, NV50_PDISPLAY_INTR_1, intr1);
+		}
+	}
+}
+
diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h
new file mode 100644
index 0000000..3ae8d07
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv50_display.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __NV50_DISPLAY_H__
+#define __NV50_DISPLAY_H__
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_dma.h"
+#include "nouveau_reg.h"
+#include "nouveau_crtc.h"
+#include "nv50_evo.h"
+
+void nv50_display_irq_handler(struct drm_device *dev);
+void nv50_display_irq_handler_bh(struct work_struct *work);
+int nv50_display_init(struct drm_device *dev);
+int nv50_display_create(struct drm_device *dev);
+int nv50_display_destroy(struct drm_device *dev);
+int nv50_crtc_blank(struct nouveau_crtc *, bool blank);
+int nv50_crtc_set_clock(struct drm_device *, int head, int pclk);
+
+#endif /* __NV50_DISPLAY_H__ */
diff --git a/drivers/gpu/drm/nouveau/nv50_evo.h b/drivers/gpu/drm/nouveau/nv50_evo.h
new file mode 100644
index 0000000..aae1334
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv50_evo.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#define NV50_EVO_UPDATE                                              0x00000080
+#define NV50_EVO_UNK84                                               0x00000084
+#define NV50_EVO_UNK84_NOTIFY                                        0x40000000
+#define NV50_EVO_UNK84_NOTIFY_DISABLED                               0x00000000
+#define NV50_EVO_UNK84_NOTIFY_ENABLED                                0x40000000
+#define NV50_EVO_DMA_NOTIFY                                          0x00000088
+#define NV50_EVO_DMA_NOTIFY_HANDLE                                   0xffffffff
+#define NV50_EVO_DMA_NOTIFY_HANDLE_NONE                              0x00000000
+#define NV50_EVO_UNK8C                                               0x0000008C
+
+#define NV50_EVO_DAC(n, r)                       ((n) * 0x80 + NV50_EVO_DAC_##r)
+#define NV50_EVO_DAC_MODE_CTRL                                       0x00000400
+#define NV50_EVO_DAC_MODE_CTRL_CRTC0                                 0x00000001
+#define NV50_EVO_DAC_MODE_CTRL_CRTC1                                 0x00000002
+#define NV50_EVO_DAC_MODE_CTRL2                                      0x00000404
+#define NV50_EVO_DAC_MODE_CTRL2_NHSYNC                               0x00000001
+#define NV50_EVO_DAC_MODE_CTRL2_NVSYNC                               0x00000002
+
+#define NV50_EVO_SOR(n, r)                       ((n) * 0x40 + NV50_EVO_SOR_##r)
+#define NV50_EVO_SOR_MODE_CTRL                                       0x00000600
+#define NV50_EVO_SOR_MODE_CTRL_CRTC0                                 0x00000001
+#define NV50_EVO_SOR_MODE_CTRL_CRTC1                                 0x00000002
+#define NV50_EVO_SOR_MODE_CTRL_TMDS                                  0x00000100
+#define NV50_EVO_SOR_MODE_CTRL_TMDS_DUAL_LINK                        0x00000400
+#define NV50_EVO_SOR_MODE_CTRL_NHSYNC                                0x00001000
+#define NV50_EVO_SOR_MODE_CTRL_NVSYNC                                0x00002000
+
+#define NV50_EVO_CRTC(n, r)                    ((n) * 0x400 + NV50_EVO_CRTC_##r)
+#define NV84_EVO_CRTC(n, r)                    ((n) * 0x400 + NV84_EVO_CRTC_##r)
+#define NV50_EVO_CRTC_UNK0800                                        0x00000800
+#define NV50_EVO_CRTC_CLOCK                                          0x00000804
+#define NV50_EVO_CRTC_INTERLACE                                      0x00000808
+#define NV50_EVO_CRTC_DISPLAY_START                                  0x00000810
+#define NV50_EVO_CRTC_DISPLAY_TOTAL                                  0x00000814
+#define NV50_EVO_CRTC_SYNC_DURATION                                  0x00000818
+#define NV50_EVO_CRTC_SYNC_START_TO_BLANK_END                        0x0000081c
+#define NV50_EVO_CRTC_UNK0820                                        0x00000820
+#define NV50_EVO_CRTC_UNK0824                                        0x00000824
+#define NV50_EVO_CRTC_UNK082C                                        0x0000082c
+#define NV50_EVO_CRTC_CLUT_MODE                                      0x00000840
+/* You can't have a palette in 8 bit mode (=OFF) */
+#define NV50_EVO_CRTC_CLUT_MODE_BLANK                                0x00000000
+#define NV50_EVO_CRTC_CLUT_MODE_OFF                                  0x80000000
+#define NV50_EVO_CRTC_CLUT_MODE_ON                                   0xC0000000
+#define NV50_EVO_CRTC_CLUT_OFFSET                                    0x00000844
+#define NV84_EVO_CRTC_CLUT_DMA                                       0x0000085C
+#define NV84_EVO_CRTC_CLUT_DMA_HANDLE                                0xffffffff
+#define NV84_EVO_CRTC_CLUT_DMA_HANDLE_NONE                           0x00000000
+#define NV50_EVO_CRTC_FB_OFFSET                                      0x00000860
+#define NV50_EVO_CRTC_FB_SIZE                                        0x00000868
+#define NV50_EVO_CRTC_FB_CONFIG                                      0x0000086c
+#define NV50_EVO_CRTC_FB_CONFIG_MODE                                 0x00100000
+#define NV50_EVO_CRTC_FB_CONFIG_MODE_TILE                            0x00000000
+#define NV50_EVO_CRTC_FB_CONFIG_MODE_PITCH                           0x00100000
+#define NV50_EVO_CRTC_FB_DEPTH                                       0x00000870
+#define NV50_EVO_CRTC_FB_DEPTH_8                                     0x00001e00
+#define NV50_EVO_CRTC_FB_DEPTH_15                                    0x0000e900
+#define NV50_EVO_CRTC_FB_DEPTH_16                                    0x0000e800
+#define NV50_EVO_CRTC_FB_DEPTH_24                                    0x0000cf00
+#define NV50_EVO_CRTC_FB_DEPTH_30                                    0x0000d100
+#define NV50_EVO_CRTC_FB_DMA                                         0x00000874
+#define NV50_EVO_CRTC_FB_DMA_HANDLE                                  0xffffffff
+#define NV50_EVO_CRTC_FB_DMA_HANDLE_NONE                             0x00000000
+#define NV50_EVO_CRTC_CURSOR_CTRL                                    0x00000880
+#define NV50_EVO_CRTC_CURSOR_CTRL_HIDE                               0x05000000
+#define NV50_EVO_CRTC_CURSOR_CTRL_SHOW                               0x85000000
+#define NV50_EVO_CRTC_CURSOR_OFFSET                                  0x00000884
+#define NV84_EVO_CRTC_CURSOR_DMA                                     0x0000089c
+#define NV84_EVO_CRTC_CURSOR_DMA_HANDLE                              0xffffffff
+#define NV84_EVO_CRTC_CURSOR_DMA_HANDLE_NONE                         0x00000000
+#define NV50_EVO_CRTC_DITHER_CTRL                                    0x000008a0
+#define NV50_EVO_CRTC_DITHER_CTRL_OFF                                0x00000000
+#define NV50_EVO_CRTC_DITHER_CTRL_ON                                 0x00000011
+#define NV50_EVO_CRTC_SCALE_CTRL                                     0x000008a4
+#define NV50_EVO_CRTC_SCALE_CTRL_INACTIVE                            0x00000000
+#define NV50_EVO_CRTC_SCALE_CTRL_ACTIVE                              0x00000009
+#define NV50_EVO_CRTC_COLOR_CTRL                                     0x000008a8
+#define NV50_EVO_CRTC_COLOR_CTRL_COLOR                               0x00040000
+#define NV50_EVO_CRTC_FB_POS                                         0x000008c0
+#define NV50_EVO_CRTC_REAL_RES                                       0x000008c8
+#define NV50_EVO_CRTC_SCALE_CENTER_OFFSET                            0x000008d4
+#define NV50_EVO_CRTC_SCALE_CENTER_OFFSET_VAL(x, y) \
+	((((unsigned)y << 16) & 0xFFFF0000) | (((unsigned)x) & 0x0000FFFF))
+/* Both of these are needed, otherwise nothing happens. */
+#define NV50_EVO_CRTC_SCALE_RES1                                     0x000008d8
+#define NV50_EVO_CRTC_SCALE_RES2                                     0x000008dc
+
diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c
new file mode 100644
index 0000000..6bcc6d3
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c
@@ -0,0 +1,273 @@
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_dma.h"
+#include "nouveau_fbcon.h"
+
+static void
+nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
+{
+	struct nouveau_fbcon_par *par = info->par;
+	struct drm_device *dev = par->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = dev_priv->channel;
+
+	if (info->state != FBINFO_STATE_RUNNING)
+		return;
+
+	if (!(info->flags & FBINFO_HWACCEL_DISABLED) &&
+	     RING_SPACE(chan, rect->rop == ROP_COPY ? 7 : 11)) {
+		NV_ERROR(dev, "GPU lockup - switching to software fbcon\n");
+
+		info->flags |= FBINFO_HWACCEL_DISABLED;
+	}
+
+	if (info->flags & FBINFO_HWACCEL_DISABLED) {
+		cfb_fillrect(info, rect);
+		return;
+	}
+
+	if (rect->rop != ROP_COPY) {
+		BEGIN_RING(chan, NvSub2D, 0x02ac, 1);
+		OUT_RING(chan, 1);
+	}
+	BEGIN_RING(chan, NvSub2D, 0x0588, 1);
+	OUT_RING(chan, rect->color);
+	BEGIN_RING(chan, NvSub2D, 0x0600, 4);
+	OUT_RING(chan, rect->dx);
+	OUT_RING(chan, rect->dy);
+	OUT_RING(chan, rect->dx + rect->width);
+	OUT_RING(chan, rect->dy + rect->height);
+	if (rect->rop != ROP_COPY) {
+		BEGIN_RING(chan, NvSub2D, 0x02ac, 1);
+		OUT_RING(chan, 3);
+	}
+	FIRE_RING(chan);
+}
+
+static void
+nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region)
+{
+	struct nouveau_fbcon_par *par = info->par;
+	struct drm_device *dev = par->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = dev_priv->channel;
+
+	if (info->state != FBINFO_STATE_RUNNING)
+		return;
+
+	if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 12)) {
+		NV_ERROR(dev, "GPU lockup - switching to software fbcon\n");
+
+		info->flags |= FBINFO_HWACCEL_DISABLED;
+	}
+
+	if (info->flags & FBINFO_HWACCEL_DISABLED) {
+		cfb_copyarea(info, region);
+		return;
+	}
+
+	BEGIN_RING(chan, NvSub2D, 0x0110, 1);
+	OUT_RING(chan, 0);
+	BEGIN_RING(chan, NvSub2D, 0x08b0, 4);
+	OUT_RING(chan, region->dx);
+	OUT_RING(chan, region->dy);
+	OUT_RING(chan, region->width);
+	OUT_RING(chan, region->height);
+	BEGIN_RING(chan, NvSub2D, 0x08d0, 4);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, region->sx);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, region->sy);
+	FIRE_RING(chan);
+}
+
+static void
+nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
+{
+	struct nouveau_fbcon_par *par = info->par;
+	struct drm_device *dev = par->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = dev_priv->channel;
+	uint32_t width, dwords, *data = (uint32_t *)image->data;
+	uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel));
+	uint32_t *palette = info->pseudo_palette;
+
+	if (info->state != FBINFO_STATE_RUNNING)
+		return;
+
+	if (image->depth != 1) {
+		cfb_imageblit(info, image);
+		return;
+	}
+
+	if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 11)) {
+		NV_ERROR(dev, "GPU lockup - switching to software fbcon\n");
+		info->flags |= FBINFO_HWACCEL_DISABLED;
+	}
+
+	if (info->flags & FBINFO_HWACCEL_DISABLED) {
+		cfb_imageblit(info, image);
+		return;
+	}
+
+	width = (image->width + 31) & ~31;
+	dwords = (width * image->height) >> 5;
+
+	BEGIN_RING(chan, NvSub2D, 0x0814, 2);
+	if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
+	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+		OUT_RING(chan, palette[image->bg_color] | mask);
+		OUT_RING(chan, palette[image->fg_color] | mask);
+	} else {
+		OUT_RING(chan, image->bg_color);
+		OUT_RING(chan, image->fg_color);
+	}
+	BEGIN_RING(chan, NvSub2D, 0x0838, 2);
+	OUT_RING(chan, image->width);
+	OUT_RING(chan, image->height);
+	BEGIN_RING(chan, NvSub2D, 0x0850, 4);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, image->dx);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, image->dy);
+
+	while (dwords) {
+		int push = dwords > 2047 ? 2047 : dwords;
+
+		if (RING_SPACE(chan, push + 1)) {
+			NV_ERROR(dev,
+				 "GPU lockup - switching to software fbcon\n");
+			info->flags |= FBINFO_HWACCEL_DISABLED;
+			cfb_imageblit(info, image);
+			return;
+		}
+
+		dwords -= push;
+
+		BEGIN_RING(chan, NvSub2D, 0x40000860, push);
+		OUT_RINGp(chan, data, push);
+		data += push;
+	}
+
+	FIRE_RING(chan);
+}
+
+int
+nv50_fbcon_accel_init(struct fb_info *info)
+{
+	struct nouveau_fbcon_par *par = info->par;
+	struct drm_device *dev = par->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = dev_priv->channel;
+	struct nouveau_gpuobj *eng2d = NULL;
+	int ret, format;
+
+	switch (info->var.bits_per_pixel) {
+	case 8:
+		format = 0xf3;
+		break;
+	case 15:
+		format = 0xf8;
+		break;
+	case 16:
+		format = 0xe8;
+		break;
+	case 32:
+		switch (info->var.transp.length) {
+		case 0: /* depth 24 */
+		case 8: /* depth 32, just use 24.. */
+			format = 0xe6;
+			break;
+		case 2: /* depth 30 */
+			format = 0xd1;
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	ret = nouveau_gpuobj_gr_new(dev_priv->channel, 0x502d, &eng2d);
+	if (ret)
+		return ret;
+
+	ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, Nv2D, eng2d, NULL);
+	if (ret)
+		return ret;
+
+	ret = RING_SPACE(chan, 59);
+	if (ret) {
+		NV_ERROR(dev, "GPU lockup - switching to software fbcon\n");
+		return ret;
+	}
+
+	BEGIN_RING(chan, NvSub2D, 0x0000, 1);
+	OUT_RING(chan, Nv2D);
+	BEGIN_RING(chan, NvSub2D, 0x0180, 4);
+	OUT_RING(chan, NvNotify0);
+	OUT_RING(chan, chan->vram_handle);
+	OUT_RING(chan, chan->vram_handle);
+	OUT_RING(chan, chan->vram_handle);
+	BEGIN_RING(chan, NvSub2D, 0x0290, 1);
+	OUT_RING(chan, 0);
+	BEGIN_RING(chan, NvSub2D, 0x0888, 1);
+	OUT_RING(chan, 1);
+	BEGIN_RING(chan, NvSub2D, 0x02ac, 1);
+	OUT_RING(chan, 3);
+	BEGIN_RING(chan, NvSub2D, 0x02a0, 1);
+	OUT_RING(chan, 0x55);
+	BEGIN_RING(chan, NvSub2D, 0x08c0, 4);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, 1);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, 1);
+	BEGIN_RING(chan, NvSub2D, 0x0580, 2);
+	OUT_RING(chan, 4);
+	OUT_RING(chan, format);
+	BEGIN_RING(chan, NvSub2D, 0x02e8, 2);
+	OUT_RING(chan, 2);
+	OUT_RING(chan, 1);
+	BEGIN_RING(chan, NvSub2D, 0x0804, 1);
+	OUT_RING(chan, format);
+	BEGIN_RING(chan, NvSub2D, 0x0800, 1);
+	OUT_RING(chan, 1);
+	BEGIN_RING(chan, NvSub2D, 0x0808, 3);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, 0);
+	BEGIN_RING(chan, NvSub2D, 0x081c, 1);
+	OUT_RING(chan, 1);
+	BEGIN_RING(chan, NvSub2D, 0x0840, 4);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, 1);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, 1);
+	BEGIN_RING(chan, NvSub2D, 0x0200, 2);
+	OUT_RING(chan, format);
+	OUT_RING(chan, 1);
+	BEGIN_RING(chan, NvSub2D, 0x0214, 5);
+	OUT_RING(chan, info->fix.line_length);
+	OUT_RING(chan, info->var.xres_virtual);
+	OUT_RING(chan, info->var.yres_virtual);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, info->fix.smem_start - dev_priv->fb_phys +
+			 dev_priv->vm_vram_base);
+	BEGIN_RING(chan, NvSub2D, 0x0230, 2);
+	OUT_RING(chan, format);
+	OUT_RING(chan, 1);
+	BEGIN_RING(chan, NvSub2D, 0x0244, 5);
+	OUT_RING(chan, info->fix.line_length);
+	OUT_RING(chan, info->var.xres_virtual);
+	OUT_RING(chan, info->var.yres_virtual);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, info->fix.smem_start - dev_priv->fb_phys +
+			 dev_priv->vm_vram_base);
+
+	info->fbops->fb_fillrect = nv50_fbcon_fillrect;
+	info->fbops->fb_copyarea = nv50_fbcon_copyarea;
+	info->fbops->fb_imageblit = nv50_fbcon_imageblit;
+	return 0;
+}
+
diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c
new file mode 100644
index 0000000..77ae1aa
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv50_fifo.c
@@ -0,0 +1,494 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+
+struct nv50_fifo_priv {
+	struct nouveau_gpuobj_ref *thingo[2];
+	int cur_thingo;
+};
+
+#define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50)
+
+static void
+nv50_fifo_init_thingo(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv50_fifo_priv *priv = dev_priv->engine.fifo.priv;
+	struct nouveau_gpuobj_ref *cur;
+	int i, nr;
+
+	NV_DEBUG(dev, "\n");
+
+	cur = priv->thingo[priv->cur_thingo];
+	priv->cur_thingo = !priv->cur_thingo;
+
+	/* We never schedule channel 0 or 127 */
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	for (i = 1, nr = 0; i < 127; i++) {
+		if (dev_priv->fifos[i] && dev_priv->fifos[i]->ramfc)
+			nv_wo32(dev, cur->gpuobj, nr++, i);
+	}
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nv_wr32(dev, 0x32f4, cur->instance >> 12);
+	nv_wr32(dev, 0x32ec, nr);
+	nv_wr32(dev, 0x2500, 0x101);
+}
+
+static int
+nv50_fifo_channel_enable(struct drm_device *dev, int channel, bool nt)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = dev_priv->fifos[channel];
+	uint32_t inst;
+
+	NV_DEBUG(dev, "ch%d\n", channel);
+
+	if (!chan->ramfc)
+		return -EINVAL;
+
+	if (IS_G80)
+		inst = chan->ramfc->instance >> 12;
+	else
+		inst = chan->ramfc->instance >> 8;
+	nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel),
+		 inst | NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED);
+
+	if (!nt)
+		nv50_fifo_init_thingo(dev);
+	return 0;
+}
+
+static void
+nv50_fifo_channel_disable(struct drm_device *dev, int channel, bool nt)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t inst;
+
+	NV_DEBUG(dev, "ch%d, nt=%d\n", channel, nt);
+
+	if (IS_G80)
+		inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80;
+	else
+		inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84;
+	nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), inst);
+
+	if (!nt)
+		nv50_fifo_init_thingo(dev);
+}
+
+static void
+nv50_fifo_init_reset(struct drm_device *dev)
+{
+	uint32_t pmc_e = NV_PMC_ENABLE_PFIFO;
+
+	NV_DEBUG(dev, "\n");
+
+	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & ~pmc_e);
+	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |  pmc_e);
+}
+
+static void
+nv50_fifo_init_intr(struct drm_device *dev)
+{
+	NV_DEBUG(dev, "\n");
+
+	nv_wr32(dev, NV03_PFIFO_INTR_0, 0xFFFFFFFF);
+	nv_wr32(dev, NV03_PFIFO_INTR_EN_0, 0xFFFFFFFF);
+}
+
+static void
+nv50_fifo_init_context_table(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int i;
+
+	NV_DEBUG(dev, "\n");
+
+	for (i = 0; i < NV50_PFIFO_CTX_TABLE__SIZE; i++) {
+		if (dev_priv->fifos[i])
+			nv50_fifo_channel_enable(dev, i, true);
+		else
+			nv50_fifo_channel_disable(dev, i, true);
+	}
+
+	nv50_fifo_init_thingo(dev);
+}
+
+static void
+nv50_fifo_init_regs__nv(struct drm_device *dev)
+{
+	NV_DEBUG(dev, "\n");
+
+	nv_wr32(dev, 0x250c, 0x6f3cfc34);
+}
+
+static void
+nv50_fifo_init_regs(struct drm_device *dev)
+{
+	NV_DEBUG(dev, "\n");
+
+	nv_wr32(dev, 0x2500, 0);
+	nv_wr32(dev, 0x3250, 0);
+	nv_wr32(dev, 0x3220, 0);
+	nv_wr32(dev, 0x3204, 0);
+	nv_wr32(dev, 0x3210, 0);
+	nv_wr32(dev, 0x3270, 0);
+
+	/* Enable dummy channels setup by nv50_instmem.c */
+	nv50_fifo_channel_enable(dev, 0, true);
+	nv50_fifo_channel_enable(dev, 127, true);
+}
+
+int
+nv50_fifo_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv50_fifo_priv *priv;
+	int ret;
+
+	NV_DEBUG(dev, "\n");
+
+	priv = dev_priv->engine.fifo.priv;
+	if (priv) {
+		priv->cur_thingo = !priv->cur_thingo;
+		goto just_reset;
+	}
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	dev_priv->engine.fifo.priv = priv;
+
+	ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000,
+				     NVOBJ_FLAG_ZERO_ALLOC, &priv->thingo[0]);
+	if (ret) {
+		NV_ERROR(dev, "error creating thingo0: %d\n", ret);
+		return ret;
+	}
+
+	ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000,
+				     NVOBJ_FLAG_ZERO_ALLOC, &priv->thingo[1]);
+	if (ret) {
+		NV_ERROR(dev, "error creating thingo1: %d\n", ret);
+		return ret;
+	}
+
+just_reset:
+	nv50_fifo_init_reset(dev);
+	nv50_fifo_init_intr(dev);
+	nv50_fifo_init_context_table(dev);
+	nv50_fifo_init_regs__nv(dev);
+	nv50_fifo_init_regs(dev);
+	dev_priv->engine.fifo.enable(dev);
+	dev_priv->engine.fifo.reassign(dev, true);
+
+	return 0;
+}
+
+void
+nv50_fifo_takedown(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv50_fifo_priv *priv = dev_priv->engine.fifo.priv;
+
+	NV_DEBUG(dev, "\n");
+
+	if (!priv)
+		return;
+
+	nouveau_gpuobj_ref_del(dev, &priv->thingo[0]);
+	nouveau_gpuobj_ref_del(dev, &priv->thingo[1]);
+
+	dev_priv->engine.fifo.priv = NULL;
+	kfree(priv);
+}
+
+int
+nv50_fifo_channel_id(struct drm_device *dev)
+{
+	return nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) &
+			NV50_PFIFO_CACHE1_PUSH1_CHID_MASK;
+}
+
+int
+nv50_fifo_create_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *ramfc = NULL;
+	int ret;
+
+	NV_DEBUG(dev, "ch%d\n", chan->id);
+
+	if (IS_G80) {
+		uint32_t ramin_poffset = chan->ramin->gpuobj->im_pramin->start;
+		uint32_t ramin_voffset = chan->ramin->gpuobj->im_backing_start;
+
+		ret = nouveau_gpuobj_new_fake(dev, ramin_poffset, ramin_voffset,
+					      0x100, NVOBJ_FLAG_ZERO_ALLOC |
+					      NVOBJ_FLAG_ZERO_FREE, &ramfc,
+					      &chan->ramfc);
+		if (ret)
+			return ret;
+
+		ret = nouveau_gpuobj_new_fake(dev, ramin_poffset + 0x0400,
+					      ramin_voffset + 0x0400, 4096,
+					      0, NULL, &chan->cache);
+		if (ret)
+			return ret;
+	} else {
+		ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, 0x100, 256,
+					     NVOBJ_FLAG_ZERO_ALLOC |
+					     NVOBJ_FLAG_ZERO_FREE,
+					     &chan->ramfc);
+		if (ret)
+			return ret;
+		ramfc = chan->ramfc->gpuobj;
+
+		ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, 4096, 256,
+					     0, &chan->cache);
+		if (ret)
+			return ret;
+	}
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+
+	nv_wo32(dev, ramfc, 0x08/4, chan->pushbuf_base);
+	nv_wo32(dev, ramfc, 0x10/4, chan->pushbuf_base);
+	nv_wo32(dev, ramfc, 0x48/4, chan->pushbuf->instance >> 4);
+	nv_wo32(dev, ramfc, 0x80/4, (0xc << 24) | (chan->ramht->instance >> 4));
+	nv_wo32(dev, ramfc, 0x3c/4, 0x00086078);
+	nv_wo32(dev, ramfc, 0x44/4, 0x2101ffff);
+	nv_wo32(dev, ramfc, 0x60/4, 0x7fffffff);
+	nv_wo32(dev, ramfc, 0x40/4, 0x00000000);
+	nv_wo32(dev, ramfc, 0x7c/4, 0x30000001);
+	nv_wo32(dev, ramfc, 0x78/4, 0x00000000);
+	nv_wo32(dev, ramfc, 0x4c/4, 0xffffffff);
+
+	if (!IS_G80) {
+		nv_wo32(dev, chan->ramin->gpuobj, 0, chan->id);
+		nv_wo32(dev, chan->ramin->gpuobj, 1,
+						chan->ramfc->instance >> 8);
+
+		nv_wo32(dev, ramfc, 0x88/4, chan->cache->instance >> 10);
+		nv_wo32(dev, ramfc, 0x98/4, chan->ramin->instance >> 12);
+	}
+
+	dev_priv->engine.instmem.finish_access(dev);
+
+	ret = nv50_fifo_channel_enable(dev, chan->id, false);
+	if (ret) {
+		NV_ERROR(dev, "error enabling ch%d: %d\n", chan->id, ret);
+		nouveau_gpuobj_ref_del(dev, &chan->ramfc);
+		return ret;
+	}
+
+	return 0;
+}
+
+void
+nv50_fifo_destroy_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+
+	NV_DEBUG(dev, "ch%d\n", chan->id);
+
+	nouveau_gpuobj_ref_del(dev, &chan->ramfc);
+	nouveau_gpuobj_ref_del(dev, &chan->cache);
+
+	nv50_fifo_channel_disable(dev, chan->id, false);
+
+	/* Dummy channel, also used on ch 127 */
+	if (chan->id == 0)
+		nv50_fifo_channel_disable(dev, 127, false);
+}
+
+int
+nv50_fifo_load_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *ramfc = chan->ramfc->gpuobj;
+	struct nouveau_gpuobj *cache = chan->cache->gpuobj;
+	int ptr, cnt;
+
+	NV_DEBUG(dev, "ch%d\n", chan->id);
+
+	dev_priv->engine.instmem.prepare_access(dev, false);
+
+	nv_wr32(dev, 0x3330, nv_ro32(dev, ramfc, 0x00/4));
+	nv_wr32(dev, 0x3334, nv_ro32(dev, ramfc, 0x04/4));
+	nv_wr32(dev, 0x3240, nv_ro32(dev, ramfc, 0x08/4));
+	nv_wr32(dev, 0x3320, nv_ro32(dev, ramfc, 0x0c/4));
+	nv_wr32(dev, 0x3244, nv_ro32(dev, ramfc, 0x10/4));
+	nv_wr32(dev, 0x3328, nv_ro32(dev, ramfc, 0x14/4));
+	nv_wr32(dev, 0x3368, nv_ro32(dev, ramfc, 0x18/4));
+	nv_wr32(dev, 0x336c, nv_ro32(dev, ramfc, 0x1c/4));
+	nv_wr32(dev, 0x3370, nv_ro32(dev, ramfc, 0x20/4));
+	nv_wr32(dev, 0x3374, nv_ro32(dev, ramfc, 0x24/4));
+	nv_wr32(dev, 0x3378, nv_ro32(dev, ramfc, 0x28/4));
+	nv_wr32(dev, 0x337c, nv_ro32(dev, ramfc, 0x2c/4));
+	nv_wr32(dev, 0x3228, nv_ro32(dev, ramfc, 0x30/4));
+	nv_wr32(dev, 0x3364, nv_ro32(dev, ramfc, 0x34/4));
+	nv_wr32(dev, 0x32a0, nv_ro32(dev, ramfc, 0x38/4));
+	nv_wr32(dev, 0x3224, nv_ro32(dev, ramfc, 0x3c/4));
+	nv_wr32(dev, 0x324c, nv_ro32(dev, ramfc, 0x40/4));
+	nv_wr32(dev, 0x2044, nv_ro32(dev, ramfc, 0x44/4));
+	nv_wr32(dev, 0x322c, nv_ro32(dev, ramfc, 0x48/4));
+	nv_wr32(dev, 0x3234, nv_ro32(dev, ramfc, 0x4c/4));
+	nv_wr32(dev, 0x3340, nv_ro32(dev, ramfc, 0x50/4));
+	nv_wr32(dev, 0x3344, nv_ro32(dev, ramfc, 0x54/4));
+	nv_wr32(dev, 0x3280, nv_ro32(dev, ramfc, 0x58/4));
+	nv_wr32(dev, 0x3254, nv_ro32(dev, ramfc, 0x5c/4));
+	nv_wr32(dev, 0x3260, nv_ro32(dev, ramfc, 0x60/4));
+	nv_wr32(dev, 0x3264, nv_ro32(dev, ramfc, 0x64/4));
+	nv_wr32(dev, 0x3268, nv_ro32(dev, ramfc, 0x68/4));
+	nv_wr32(dev, 0x326c, nv_ro32(dev, ramfc, 0x6c/4));
+	nv_wr32(dev, 0x32e4, nv_ro32(dev, ramfc, 0x70/4));
+	nv_wr32(dev, 0x3248, nv_ro32(dev, ramfc, 0x74/4));
+	nv_wr32(dev, 0x2088, nv_ro32(dev, ramfc, 0x78/4));
+	nv_wr32(dev, 0x2058, nv_ro32(dev, ramfc, 0x7c/4));
+	nv_wr32(dev, 0x2210, nv_ro32(dev, ramfc, 0x80/4));
+
+	cnt = nv_ro32(dev, ramfc, 0x84/4);
+	for (ptr = 0; ptr < cnt; ptr++) {
+		nv_wr32(dev, NV40_PFIFO_CACHE1_METHOD(ptr),
+			nv_ro32(dev, cache, (ptr * 2) + 0));
+		nv_wr32(dev, NV40_PFIFO_CACHE1_DATA(ptr),
+			nv_ro32(dev, cache, (ptr * 2) + 1));
+	}
+	nv_wr32(dev, 0x3210, cnt << 2);
+	nv_wr32(dev, 0x3270, 0);
+
+	/* guessing that all the 0x34xx regs aren't on NV50 */
+	if (!IS_G80) {
+		nv_wr32(dev, 0x340c, nv_ro32(dev, ramfc, 0x88/4));
+		nv_wr32(dev, 0x3400, nv_ro32(dev, ramfc, 0x8c/4));
+		nv_wr32(dev, 0x3404, nv_ro32(dev, ramfc, 0x90/4));
+		nv_wr32(dev, 0x3408, nv_ro32(dev, ramfc, 0x94/4));
+		nv_wr32(dev, 0x3410, nv_ro32(dev, ramfc, 0x98/4));
+	}
+
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0);
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0);
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, chan->id | (1<<16));
+	return 0;
+}
+
+int
+nv50_fifo_unload_context(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	struct nouveau_gpuobj *ramfc, *cache;
+	struct nouveau_channel *chan = NULL;
+	int chid, get, put, ptr;
+
+	NV_DEBUG(dev, "\n");
+
+	chid = pfifo->channel_id(dev);
+	if (chid < 0 || chid >= dev_priv->engine.fifo.channels)
+		return 0;
+
+	chan = dev_priv->fifos[chid];
+	if (!chan) {
+		NV_ERROR(dev, "Inactive channel on PFIFO: %d\n", chid);
+		return -EINVAL;
+	}
+	NV_DEBUG(dev, "ch%d\n", chan->id);
+	ramfc = chan->ramfc->gpuobj;
+	cache = chan->cache->gpuobj;
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+
+	nv_wo32(dev, ramfc, 0x00/4, nv_rd32(dev, 0x3330));
+	nv_wo32(dev, ramfc, 0x04/4, nv_rd32(dev, 0x3334));
+	nv_wo32(dev, ramfc, 0x08/4, nv_rd32(dev, 0x3240));
+	nv_wo32(dev, ramfc, 0x0c/4, nv_rd32(dev, 0x3320));
+	nv_wo32(dev, ramfc, 0x10/4, nv_rd32(dev, 0x3244));
+	nv_wo32(dev, ramfc, 0x14/4, nv_rd32(dev, 0x3328));
+	nv_wo32(dev, ramfc, 0x18/4, nv_rd32(dev, 0x3368));
+	nv_wo32(dev, ramfc, 0x1c/4, nv_rd32(dev, 0x336c));
+	nv_wo32(dev, ramfc, 0x20/4, nv_rd32(dev, 0x3370));
+	nv_wo32(dev, ramfc, 0x24/4, nv_rd32(dev, 0x3374));
+	nv_wo32(dev, ramfc, 0x28/4, nv_rd32(dev, 0x3378));
+	nv_wo32(dev, ramfc, 0x2c/4, nv_rd32(dev, 0x337c));
+	nv_wo32(dev, ramfc, 0x30/4, nv_rd32(dev, 0x3228));
+	nv_wo32(dev, ramfc, 0x34/4, nv_rd32(dev, 0x3364));
+	nv_wo32(dev, ramfc, 0x38/4, nv_rd32(dev, 0x32a0));
+	nv_wo32(dev, ramfc, 0x3c/4, nv_rd32(dev, 0x3224));
+	nv_wo32(dev, ramfc, 0x40/4, nv_rd32(dev, 0x324c));
+	nv_wo32(dev, ramfc, 0x44/4, nv_rd32(dev, 0x2044));
+	nv_wo32(dev, ramfc, 0x48/4, nv_rd32(dev, 0x322c));
+	nv_wo32(dev, ramfc, 0x4c/4, nv_rd32(dev, 0x3234));
+	nv_wo32(dev, ramfc, 0x50/4, nv_rd32(dev, 0x3340));
+	nv_wo32(dev, ramfc, 0x54/4, nv_rd32(dev, 0x3344));
+	nv_wo32(dev, ramfc, 0x58/4, nv_rd32(dev, 0x3280));
+	nv_wo32(dev, ramfc, 0x5c/4, nv_rd32(dev, 0x3254));
+	nv_wo32(dev, ramfc, 0x60/4, nv_rd32(dev, 0x3260));
+	nv_wo32(dev, ramfc, 0x64/4, nv_rd32(dev, 0x3264));
+	nv_wo32(dev, ramfc, 0x68/4, nv_rd32(dev, 0x3268));
+	nv_wo32(dev, ramfc, 0x6c/4, nv_rd32(dev, 0x326c));
+	nv_wo32(dev, ramfc, 0x70/4, nv_rd32(dev, 0x32e4));
+	nv_wo32(dev, ramfc, 0x74/4, nv_rd32(dev, 0x3248));
+	nv_wo32(dev, ramfc, 0x78/4, nv_rd32(dev, 0x2088));
+	nv_wo32(dev, ramfc, 0x7c/4, nv_rd32(dev, 0x2058));
+	nv_wo32(dev, ramfc, 0x80/4, nv_rd32(dev, 0x2210));
+
+	put = (nv_rd32(dev, NV03_PFIFO_CACHE1_PUT) & 0x7ff) >> 2;
+	get = (nv_rd32(dev, NV03_PFIFO_CACHE1_GET) & 0x7ff) >> 2;
+	ptr = 0;
+	while (put != get) {
+		nv_wo32(dev, cache, ptr++,
+			    nv_rd32(dev, NV40_PFIFO_CACHE1_METHOD(get)));
+		nv_wo32(dev, cache, ptr++,
+			    nv_rd32(dev, NV40_PFIFO_CACHE1_DATA(get)));
+		get = (get + 1) & 0x1ff;
+	}
+
+	/* guessing that all the 0x34xx regs aren't on NV50 */
+	if (!IS_G80) {
+		nv_wo32(dev, ramfc, 0x84/4, ptr >> 1);
+		nv_wo32(dev, ramfc, 0x88/4, nv_rd32(dev, 0x340c));
+		nv_wo32(dev, ramfc, 0x8c/4, nv_rd32(dev, 0x3400));
+		nv_wo32(dev, ramfc, 0x90/4, nv_rd32(dev, 0x3404));
+		nv_wo32(dev, ramfc, 0x94/4, nv_rd32(dev, 0x3408));
+		nv_wo32(dev, ramfc, 0x98/4, nv_rd32(dev, 0x3410));
+	}
+
+	dev_priv->engine.instmem.finish_access(dev);
+
+	/*XXX: probably reload ch127 (NULL) state back too */
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, 127);
+	return 0;
+}
+
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c
new file mode 100644
index 0000000..177d822
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv50_graph.c
@@ -0,0 +1,385 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+
+MODULE_FIRMWARE("nouveau/nv50.ctxprog");
+MODULE_FIRMWARE("nouveau/nv50.ctxvals");
+MODULE_FIRMWARE("nouveau/nv84.ctxprog");
+MODULE_FIRMWARE("nouveau/nv84.ctxvals");
+MODULE_FIRMWARE("nouveau/nv86.ctxprog");
+MODULE_FIRMWARE("nouveau/nv86.ctxvals");
+MODULE_FIRMWARE("nouveau/nv92.ctxprog");
+MODULE_FIRMWARE("nouveau/nv92.ctxvals");
+MODULE_FIRMWARE("nouveau/nv94.ctxprog");
+MODULE_FIRMWARE("nouveau/nv94.ctxvals");
+MODULE_FIRMWARE("nouveau/nv96.ctxprog");
+MODULE_FIRMWARE("nouveau/nv96.ctxvals");
+MODULE_FIRMWARE("nouveau/nv98.ctxprog");
+MODULE_FIRMWARE("nouveau/nv98.ctxvals");
+MODULE_FIRMWARE("nouveau/nva0.ctxprog");
+MODULE_FIRMWARE("nouveau/nva0.ctxvals");
+MODULE_FIRMWARE("nouveau/nva5.ctxprog");
+MODULE_FIRMWARE("nouveau/nva5.ctxvals");
+MODULE_FIRMWARE("nouveau/nva8.ctxprog");
+MODULE_FIRMWARE("nouveau/nva8.ctxvals");
+MODULE_FIRMWARE("nouveau/nvaa.ctxprog");
+MODULE_FIRMWARE("nouveau/nvaa.ctxvals");
+MODULE_FIRMWARE("nouveau/nvac.ctxprog");
+MODULE_FIRMWARE("nouveau/nvac.ctxvals");
+
+#define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50)
+
+static void
+nv50_graph_init_reset(struct drm_device *dev)
+{
+	uint32_t pmc_e = NV_PMC_ENABLE_PGRAPH | (1 << 21);
+
+	NV_DEBUG(dev, "\n");
+
+	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & ~pmc_e);
+	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |  pmc_e);
+}
+
+static void
+nv50_graph_init_intr(struct drm_device *dev)
+{
+	NV_DEBUG(dev, "\n");
+
+	nv_wr32(dev, NV03_PGRAPH_INTR, 0xffffffff);
+	nv_wr32(dev, 0x400138, 0xffffffff);
+	nv_wr32(dev, NV40_PGRAPH_INTR_EN, 0xffffffff);
+}
+
+static void
+nv50_graph_init_regs__nv(struct drm_device *dev)
+{
+	NV_DEBUG(dev, "\n");
+
+	nv_wr32(dev, 0x400804, 0xc0000000);
+	nv_wr32(dev, 0x406800, 0xc0000000);
+	nv_wr32(dev, 0x400c04, 0xc0000000);
+	nv_wr32(dev, 0x401804, 0xc0000000);
+	nv_wr32(dev, 0x405018, 0xc0000000);
+	nv_wr32(dev, 0x402000, 0xc0000000);
+
+	nv_wr32(dev, 0x400108, 0xffffffff);
+
+	nv_wr32(dev, 0x400824, 0x00004000);
+	nv_wr32(dev, 0x400500, 0x00010001);
+}
+
+static void
+nv50_graph_init_regs(struct drm_device *dev)
+{
+	NV_DEBUG(dev, "\n");
+
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_3,
+				(1 << 2) /* HW_CONTEXT_SWITCH_ENABLED */);
+	nv_wr32(dev, 0x402ca8, 0x800);
+}
+
+static int
+nv50_graph_init_ctxctl(struct drm_device *dev)
+{
+	NV_DEBUG(dev, "\n");
+
+	nv40_grctx_init(dev);
+
+	nv_wr32(dev, 0x400320, 4);
+	nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0);
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, 0);
+	return 0;
+}
+
+int
+nv50_graph_init(struct drm_device *dev)
+{
+	int ret;
+
+	NV_DEBUG(dev, "\n");
+
+	nv50_graph_init_reset(dev);
+	nv50_graph_init_regs__nv(dev);
+	nv50_graph_init_regs(dev);
+	nv50_graph_init_intr(dev);
+
+	ret = nv50_graph_init_ctxctl(dev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+void
+nv50_graph_takedown(struct drm_device *dev)
+{
+	NV_DEBUG(dev, "\n");
+	nv40_grctx_fini(dev);
+}
+
+void
+nv50_graph_fifo_access(struct drm_device *dev, bool enabled)
+{
+	const uint32_t mask = 0x00010001;
+
+	if (enabled)
+		nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) | mask);
+	else
+		nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) & ~mask);
+}
+
+struct nouveau_channel *
+nv50_graph_channel(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t inst;
+	int i;
+
+	inst = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR);
+	if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED))
+		return NULL;
+	inst = (inst & NV50_PGRAPH_CTXCTL_CUR_INSTANCE) << 12;
+
+	for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
+		struct nouveau_channel *chan = dev_priv->fifos[i];
+
+		if (chan && chan->ramin && chan->ramin->instance == inst)
+			return chan;
+	}
+
+	return NULL;
+}
+
+int
+nv50_graph_create_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *ramin = chan->ramin->gpuobj;
+	struct nouveau_gpuobj *ctx;
+	uint32_t grctx_size = 0x70000;
+	int hdr, ret;
+
+	NV_DEBUG(dev, "ch%d\n", chan->id);
+
+	ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, grctx_size, 0x1000,
+				     NVOBJ_FLAG_ZERO_ALLOC |
+				     NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx);
+	if (ret)
+		return ret;
+	ctx = chan->ramin_grctx->gpuobj;
+
+	hdr = IS_G80 ? 0x200 : 0x20;
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	nv_wo32(dev, ramin, (hdr + 0x00)/4, 0x00190002);
+	nv_wo32(dev, ramin, (hdr + 0x04)/4, chan->ramin_grctx->instance +
+					   grctx_size - 1);
+	nv_wo32(dev, ramin, (hdr + 0x08)/4, chan->ramin_grctx->instance);
+	nv_wo32(dev, ramin, (hdr + 0x0c)/4, 0);
+	nv_wo32(dev, ramin, (hdr + 0x10)/4, 0);
+	nv_wo32(dev, ramin, (hdr + 0x14)/4, 0x00010000);
+	dev_priv->engine.instmem.finish_access(dev);
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	nv40_grctx_vals_load(dev, ctx);
+	nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12);
+	if ((dev_priv->chipset & 0xf0) == 0xa0)
+		nv_wo32(dev, ctx, 0x00004/4, 0x00000000);
+	else
+		nv_wo32(dev, ctx, 0x0011c/4, 0x00000000);
+	dev_priv->engine.instmem.finish_access(dev);
+
+	return 0;
+}
+
+void
+nv50_graph_destroy_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int i, hdr = IS_G80 ? 0x200 : 0x20;
+
+	NV_DEBUG(dev, "ch%d\n", chan->id);
+
+	if (!chan->ramin || !chan->ramin->gpuobj)
+		return;
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	for (i = hdr; i < hdr + 24; i += 4)
+		nv_wo32(dev, chan->ramin->gpuobj, i/4, 0);
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx);
+}
+
+static int
+nv50_graph_do_load_context(struct drm_device *dev, uint32_t inst)
+{
+	uint32_t fifo = nv_rd32(dev, 0x400500);
+
+	nv_wr32(dev, 0x400500, fifo & ~1);
+	nv_wr32(dev, 0x400784, inst);
+	nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) | 0x40);
+	nv_wr32(dev, 0x400320, nv_rd32(dev, 0x400320) | 0x11);
+	nv_wr32(dev, 0x400040, 0xffffffff);
+	(void)nv_rd32(dev, 0x400040);
+	nv_wr32(dev, 0x400040, 0x00000000);
+	nv_wr32(dev, 0x400304, nv_rd32(dev, 0x400304) | 1);
+
+	if (nouveau_wait_for_idle(dev))
+		nv_wr32(dev, 0x40032c, inst | (1<<31));
+	nv_wr32(dev, 0x400500, fifo);
+
+	return 0;
+}
+
+int
+nv50_graph_load_context(struct nouveau_channel *chan)
+{
+	uint32_t inst = chan->ramin->instance >> 12;
+
+	NV_DEBUG(chan->dev, "ch%d\n", chan->id);
+	return nv50_graph_do_load_context(chan->dev, inst);
+}
+
+int
+nv50_graph_unload_context(struct drm_device *dev)
+{
+	uint32_t inst, fifo = nv_rd32(dev, 0x400500);
+
+	inst  = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR);
+	if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED))
+		return 0;
+	inst &= NV50_PGRAPH_CTXCTL_CUR_INSTANCE;
+
+	nv_wr32(dev, 0x400500, fifo & ~1);
+	nv_wr32(dev, 0x400784, inst);
+	nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) | 0x20);
+	nv_wr32(dev, 0x400304, nv_rd32(dev, 0x400304) | 0x01);
+	nouveau_wait_for_idle(dev);
+	nv_wr32(dev, 0x400500, fifo);
+
+	nv_wr32(dev, NV50_PGRAPH_CTXCTL_CUR, inst);
+	return 0;
+}
+
+void
+nv50_graph_context_switch(struct drm_device *dev)
+{
+	uint32_t inst;
+
+	nv50_graph_unload_context(dev);
+
+	inst  = nv_rd32(dev, NV50_PGRAPH_CTXCTL_NEXT);
+	inst &= NV50_PGRAPH_CTXCTL_NEXT_INSTANCE;
+	nv50_graph_do_load_context(dev, inst);
+
+	nv_wr32(dev, NV40_PGRAPH_INTR_EN, nv_rd32(dev,
+		NV40_PGRAPH_INTR_EN) | NV_PGRAPH_INTR_CONTEXT_SWITCH);
+}
+
+static int
+nv50_graph_nvsw_dma_vblsem(struct nouveau_channel *chan, int grclass,
+			   int mthd, uint32_t data)
+{
+	struct nouveau_gpuobj_ref *ref = NULL;
+
+	if (nouveau_gpuobj_ref_find(chan, data, &ref))
+		return -ENOENT;
+
+	if (nouveau_notifier_offset(ref->gpuobj, NULL))
+		return -EINVAL;
+
+	chan->nvsw.vblsem = ref->gpuobj;
+	chan->nvsw.vblsem_offset = ~0;
+	return 0;
+}
+
+static int
+nv50_graph_nvsw_vblsem_offset(struct nouveau_channel *chan, int grclass,
+			      int mthd, uint32_t data)
+{
+	if (nouveau_notifier_offset(chan->nvsw.vblsem, &data))
+		return -ERANGE;
+
+	chan->nvsw.vblsem_offset = data >> 2;
+	return 0;
+}
+
+static int
+nv50_graph_nvsw_vblsem_release_val(struct nouveau_channel *chan, int grclass,
+				   int mthd, uint32_t data)
+{
+	chan->nvsw.vblsem_rval = data;
+	return 0;
+}
+
+static int
+nv50_graph_nvsw_vblsem_release(struct nouveau_channel *chan, int grclass,
+			       int mthd, uint32_t data)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (!chan->nvsw.vblsem || chan->nvsw.vblsem_offset == ~0 || data > 1)
+		return -EINVAL;
+
+	if (!(nv_rd32(dev, NV50_PDISPLAY_INTR_EN) &
+		      NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_(data))) {
+		nv_wr32(dev, NV50_PDISPLAY_INTR_1,
+			NV50_PDISPLAY_INTR_1_VBLANK_CRTC_(data));
+		nv_wr32(dev, NV50_PDISPLAY_INTR_EN, nv_rd32(dev,
+			NV50_PDISPLAY_INTR_EN) |
+			NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_(data));
+	}
+
+	list_add(&chan->nvsw.vbl_wait, &dev_priv->vbl_waiting);
+	return 0;
+}
+
+static struct nouveau_pgraph_object_method nv50_graph_nvsw_methods[] = {
+	{ 0x018c, nv50_graph_nvsw_dma_vblsem },
+	{ 0x0400, nv50_graph_nvsw_vblsem_offset },
+	{ 0x0404, nv50_graph_nvsw_vblsem_release_val },
+	{ 0x0408, nv50_graph_nvsw_vblsem_release },
+	{}
+};
+
+struct nouveau_pgraph_object_class nv50_graph_grclass[] = {
+	{ 0x506e, true, nv50_graph_nvsw_methods }, /* nvsw */
+	{ 0x0030, false, NULL }, /* null */
+	{ 0x5039, false, NULL }, /* m2mf */
+	{ 0x502d, false, NULL }, /* 2d */
+	{ 0x50c0, false, NULL }, /* compute */
+	{ 0x5097, false, NULL }, /* tesla (nv50) */
+	{ 0x8297, false, NULL }, /* tesla (nv80/nv90) */
+	{ 0x8397, false, NULL }, /* tesla (nva0) */
+	{ 0x8597, false, NULL }, /* tesla (nva8) */
+	{}
+};
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c
new file mode 100644
index 0000000..94400f7
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv50_instmem.c
@@ -0,0 +1,509 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+
+struct nv50_instmem_priv {
+	uint32_t save1700[5]; /* 0x1700->0x1710 */
+
+	struct nouveau_gpuobj_ref *pramin_pt;
+	struct nouveau_gpuobj_ref *pramin_bar;
+	struct nouveau_gpuobj_ref *fb_bar;
+
+	bool last_access_wr;
+};
+
+#define NV50_INSTMEM_PAGE_SHIFT 12
+#define NV50_INSTMEM_PAGE_SIZE  (1 << NV50_INSTMEM_PAGE_SHIFT)
+#define NV50_INSTMEM_PT_SIZE(a)	(((a) >> 12) << 3)
+
+/*NOTE: - Assumes 0x1700 already covers the correct MiB of PRAMIN
+ */
+#define BAR0_WI32(g, o, v) do {                                   \
+	uint32_t offset;                                          \
+	if ((g)->im_backing) {                                    \
+		offset = (g)->im_backing_start;                   \
+	} else {                                                  \
+		offset  = chan->ramin->gpuobj->im_backing_start;  \
+		offset += (g)->im_pramin->start;                  \
+	}                                                         \
+	offset += (o);                                            \
+	nv_wr32(dev, NV_RAMIN + (offset & 0xfffff), (v));              \
+} while (0)
+
+int
+nv50_instmem_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan;
+	uint32_t c_offset, c_size, c_ramfc, c_vmpd, c_base, pt_size;
+	struct nv50_instmem_priv *priv;
+	int ret, i;
+	uint32_t v, save_nv001700;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	dev_priv->engine.instmem.priv = priv;
+
+	/* Save state, will restore at takedown. */
+	for (i = 0x1700; i <= 0x1710; i += 4)
+		priv->save1700[(i-0x1700)/4] = nv_rd32(dev, i);
+
+	/* Reserve the last MiB of VRAM, we should probably try to avoid
+	 * setting up the below tables over the top of the VBIOS image at
+	 * some point.
+	 */
+	dev_priv->ramin_rsvd_vram = 1 << 20;
+	c_offset = nouveau_mem_fb_amount(dev) - dev_priv->ramin_rsvd_vram;
+	c_size   = 128 << 10;
+	c_vmpd   = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x1400 : 0x200;
+	c_ramfc  = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x0 : 0x20;
+	c_base   = c_vmpd + 0x4000;
+	pt_size  = NV50_INSTMEM_PT_SIZE(dev_priv->ramin_size);
+
+	NV_DEBUG(dev, " Rsvd VRAM base: 0x%08x\n", c_offset);
+	NV_DEBUG(dev, "    VBIOS image: 0x%08x\n",
+				(nv_rd32(dev, 0x619f04) & ~0xff) << 8);
+	NV_DEBUG(dev, "  Aperture size: %d MiB\n", dev_priv->ramin_size >> 20);
+	NV_DEBUG(dev, "        PT size: %d KiB\n", pt_size >> 10);
+
+	/* Determine VM layout, we need to do this first to make sure
+	 * we allocate enough memory for all the page tables.
+	 */
+	dev_priv->vm_gart_base = roundup(NV50_VM_BLOCK, NV50_VM_BLOCK);
+	dev_priv->vm_gart_size = NV50_VM_BLOCK;
+
+	dev_priv->vm_vram_base = dev_priv->vm_gart_base + dev_priv->vm_gart_size;
+	dev_priv->vm_vram_size = nouveau_mem_fb_amount(dev);
+	if (dev_priv->vm_vram_size > NV50_VM_MAX_VRAM)
+		dev_priv->vm_vram_size = NV50_VM_MAX_VRAM;
+	dev_priv->vm_vram_size = roundup(dev_priv->vm_vram_size, NV50_VM_BLOCK);
+	dev_priv->vm_vram_pt_nr = dev_priv->vm_vram_size / NV50_VM_BLOCK;
+
+	dev_priv->vm_end = dev_priv->vm_vram_base + dev_priv->vm_vram_size;
+
+	NV_DEBUG(dev, "NV50VM: GART 0x%016llx-0x%016llx\n",
+		 dev_priv->vm_gart_base,
+		 dev_priv->vm_gart_base + dev_priv->vm_gart_size - 1);
+	NV_DEBUG(dev, "NV50VM: VRAM 0x%016llx-0x%016llx\n",
+		 dev_priv->vm_vram_base,
+		 dev_priv->vm_vram_base + dev_priv->vm_vram_size - 1);
+
+	c_size += dev_priv->vm_vram_pt_nr * (NV50_VM_BLOCK / 65536 * 8);
+
+	/* Map BAR0 PRAMIN aperture over the memory we want to use */
+	save_nv001700 = nv_rd32(dev, NV50_PUNK_BAR0_PRAMIN);
+	nv_wr32(dev, NV50_PUNK_BAR0_PRAMIN, (c_offset >> 16));
+
+	/* Create a fake channel, and use it as our "dummy" channels 0/127.
+	 * The main reason for creating a channel is so we can use the gpuobj
+	 * code.  However, it's probably worth noting that NVIDIA also setup
+	 * their channels 0/127 with the same values they configure here.
+	 * So, there may be some other reason for doing this.
+	 *
+	 * Have to create the entire channel manually, as the real channel
+	 * creation code assumes we have PRAMIN access, and we don't until
+	 * we're done here.
+	 */
+	chan = kzalloc(sizeof(*chan), GFP_KERNEL);
+	if (!chan)
+		return -ENOMEM;
+	chan->id = 0;
+	chan->dev = dev;
+	chan->file_priv = (struct drm_file *)-2;
+	dev_priv->fifos[0] = dev_priv->fifos[127] = chan;
+
+	/* Channel's PRAMIN object + heap */
+	ret = nouveau_gpuobj_new_fake(dev, 0, c_offset, c_size, 0,
+							NULL, &chan->ramin);
+	if (ret)
+		return ret;
+
+	if (nouveau_mem_init_heap(&chan->ramin_heap, c_base, c_size - c_base))
+		return -ENOMEM;
+
+	/* RAMFC + zero channel's PRAMIN up to start of VM pagedir */
+	ret = nouveau_gpuobj_new_fake(dev, c_ramfc, c_offset + c_ramfc,
+						0x4000, 0, NULL, &chan->ramfc);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < c_vmpd; i += 4)
+		BAR0_WI32(chan->ramin->gpuobj, i, 0);
+
+	/* VM page directory */
+	ret = nouveau_gpuobj_new_fake(dev, c_vmpd, c_offset + c_vmpd,
+					   0x4000, 0, &chan->vm_pd, NULL);
+	if (ret)
+		return ret;
+	for (i = 0; i < 0x4000; i += 8) {
+		BAR0_WI32(chan->vm_pd, i + 0x00, 0x00000000);
+		BAR0_WI32(chan->vm_pd, i + 0x04, 0x00000000);
+	}
+
+	/* PRAMIN page table, cheat and map into VM at 0x0000000000.
+	 * We map the entire fake channel into the start of the PRAMIN BAR
+	 */
+	ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pt_size, 0x1000,
+							0, &priv->pramin_pt);
+	if (ret)
+		return ret;
+
+	for (i = 0, v = c_offset; i < pt_size; i += 8, v += 0x1000) {
+		if (v < (c_offset + c_size))
+			BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, v | 1);
+		else
+			BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, 0x00000009);
+		BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, 0x00000000);
+	}
+
+	BAR0_WI32(chan->vm_pd, 0x00, priv->pramin_pt->instance | 0x63);
+	BAR0_WI32(chan->vm_pd, 0x04, 0x00000000);
+
+	/* VRAM page table(s), mapped into VM at +1GiB  */
+	for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) {
+		ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0,
+					     NV50_VM_BLOCK/65536*8, 0, 0,
+					     &chan->vm_vram_pt[i]);
+		if (ret) {
+			NV_ERROR(dev, "Error creating VRAM page tables: %d\n",
+									ret);
+			dev_priv->vm_vram_pt_nr = i;
+			return ret;
+		}
+		dev_priv->vm_vram_pt[i] = chan->vm_vram_pt[i]->gpuobj;
+
+		for (v = 0; v < dev_priv->vm_vram_pt[i]->im_pramin->size;
+								v += 4)
+			BAR0_WI32(dev_priv->vm_vram_pt[i], v, 0);
+
+		BAR0_WI32(chan->vm_pd, 0x10 + (i*8),
+			  chan->vm_vram_pt[i]->instance | 0x61);
+		BAR0_WI32(chan->vm_pd, 0x14 + (i*8), 0);
+	}
+
+	/* DMA object for PRAMIN BAR */
+	ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0, 6*4, 16, 0,
+							&priv->pramin_bar);
+	if (ret)
+		return ret;
+	BAR0_WI32(priv->pramin_bar->gpuobj, 0x00, 0x7fc00000);
+	BAR0_WI32(priv->pramin_bar->gpuobj, 0x04, dev_priv->ramin_size - 1);
+	BAR0_WI32(priv->pramin_bar->gpuobj, 0x08, 0x00000000);
+	BAR0_WI32(priv->pramin_bar->gpuobj, 0x0c, 0x00000000);
+	BAR0_WI32(priv->pramin_bar->gpuobj, 0x10, 0x00000000);
+	BAR0_WI32(priv->pramin_bar->gpuobj, 0x14, 0x00000000);
+
+	/* DMA object for FB BAR */
+	ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0, 6*4, 16, 0,
+							&priv->fb_bar);
+	if (ret)
+		return ret;
+	BAR0_WI32(priv->fb_bar->gpuobj, 0x00, 0x7fc00000);
+	BAR0_WI32(priv->fb_bar->gpuobj, 0x04, 0x40000000 +
+					      drm_get_resource_len(dev, 1) - 1);
+	BAR0_WI32(priv->fb_bar->gpuobj, 0x08, 0x40000000);
+	BAR0_WI32(priv->fb_bar->gpuobj, 0x0c, 0x00000000);
+	BAR0_WI32(priv->fb_bar->gpuobj, 0x10, 0x00000000);
+	BAR0_WI32(priv->fb_bar->gpuobj, 0x14, 0x00000000);
+
+	/* Poke the relevant regs, and pray it works :) */
+	nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->instance >> 12));
+	nv_wr32(dev, NV50_PUNK_UNK1710, 0);
+	nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->instance >> 12) |
+					 NV50_PUNK_BAR_CFG_BASE_VALID);
+	nv_wr32(dev, NV50_PUNK_BAR1_CTXDMA, (priv->fb_bar->instance >> 4) |
+					NV50_PUNK_BAR1_CTXDMA_VALID);
+	nv_wr32(dev, NV50_PUNK_BAR3_CTXDMA, (priv->pramin_bar->instance >> 4) |
+					NV50_PUNK_BAR3_CTXDMA_VALID);
+
+	for (i = 0; i < 8; i++)
+		nv_wr32(dev, 0x1900 + (i*4), 0);
+
+	/* Assume that praying isn't enough, check that we can re-read the
+	 * entire fake channel back from the PRAMIN BAR */
+	dev_priv->engine.instmem.prepare_access(dev, false);
+	for (i = 0; i < c_size; i += 4) {
+		if (nv_rd32(dev, NV_RAMIN + i) != nv_ri32(dev, i)) {
+			NV_ERROR(dev, "Error reading back PRAMIN at 0x%08x\n",
+									i);
+			dev_priv->engine.instmem.finish_access(dev);
+			return -EINVAL;
+		}
+	}
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nv_wr32(dev, NV50_PUNK_BAR0_PRAMIN, save_nv001700);
+
+	/* Global PRAMIN heap */
+	if (nouveau_mem_init_heap(&dev_priv->ramin_heap,
+				  c_size, dev_priv->ramin_size - c_size)) {
+		dev_priv->ramin_heap = NULL;
+		NV_ERROR(dev, "Failed to init RAMIN heap\n");
+	}
+
+	/*XXX: incorrect, but needed to make hash func "work" */
+	dev_priv->ramht_offset = 0x10000;
+	dev_priv->ramht_bits   = 9;
+	dev_priv->ramht_size   = (1 << dev_priv->ramht_bits);
+	return 0;
+}
+
+void
+nv50_instmem_takedown(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
+	struct nouveau_channel *chan = dev_priv->fifos[0];
+	int i;
+
+	NV_DEBUG(dev, "\n");
+
+	if (!priv)
+		return;
+
+	/* Restore state from before init */
+	for (i = 0x1700; i <= 0x1710; i += 4)
+		nv_wr32(dev, i, priv->save1700[(i - 0x1700) / 4]);
+
+	nouveau_gpuobj_ref_del(dev, &priv->fb_bar);
+	nouveau_gpuobj_ref_del(dev, &priv->pramin_bar);
+	nouveau_gpuobj_ref_del(dev, &priv->pramin_pt);
+
+	/* Destroy dummy channel */
+	if (chan) {
+		for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) {
+			nouveau_gpuobj_ref_del(dev, &chan->vm_vram_pt[i]);
+			dev_priv->vm_vram_pt[i] = NULL;
+		}
+		dev_priv->vm_vram_pt_nr = 0;
+
+		nouveau_gpuobj_del(dev, &chan->vm_pd);
+		nouveau_gpuobj_ref_del(dev, &chan->ramfc);
+		nouveau_gpuobj_ref_del(dev, &chan->ramin);
+		nouveau_mem_takedown(&chan->ramin_heap);
+
+		dev_priv->fifos[0] = dev_priv->fifos[127] = NULL;
+		kfree(chan);
+	}
+
+	dev_priv->engine.instmem.priv = NULL;
+	kfree(priv);
+}
+
+int
+nv50_instmem_suspend(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = dev_priv->fifos[0];
+	struct nouveau_gpuobj *ramin = chan->ramin->gpuobj;
+	int i;
+
+	ramin->im_backing_suspend = vmalloc(ramin->im_pramin->size);
+	if (!ramin->im_backing_suspend)
+		return -ENOMEM;
+
+	for (i = 0; i < ramin->im_pramin->size; i += 4)
+		ramin->im_backing_suspend[i/4] = nv_ri32(dev, i);
+	return 0;
+}
+
+void
+nv50_instmem_resume(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
+	struct nouveau_channel *chan = dev_priv->fifos[0];
+	struct nouveau_gpuobj *ramin = chan->ramin->gpuobj;
+	int i;
+
+	nv_wr32(dev, NV50_PUNK_BAR0_PRAMIN, (ramin->im_backing_start >> 16));
+	for (i = 0; i < ramin->im_pramin->size; i += 4)
+		BAR0_WI32(ramin, i, ramin->im_backing_suspend[i/4]);
+	vfree(ramin->im_backing_suspend);
+	ramin->im_backing_suspend = NULL;
+
+	/* Poke the relevant regs, and pray it works :) */
+	nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->instance >> 12));
+	nv_wr32(dev, NV50_PUNK_UNK1710, 0);
+	nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->instance >> 12) |
+					 NV50_PUNK_BAR_CFG_BASE_VALID);
+	nv_wr32(dev, NV50_PUNK_BAR1_CTXDMA, (priv->fb_bar->instance >> 4) |
+					NV50_PUNK_BAR1_CTXDMA_VALID);
+	nv_wr32(dev, NV50_PUNK_BAR3_CTXDMA, (priv->pramin_bar->instance >> 4) |
+					NV50_PUNK_BAR3_CTXDMA_VALID);
+
+	for (i = 0; i < 8; i++)
+		nv_wr32(dev, 0x1900 + (i*4), 0);
+}
+
+int
+nv50_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj,
+		      uint32_t *sz)
+{
+	int ret;
+
+	if (gpuobj->im_backing)
+		return -EINVAL;
+
+	*sz = (*sz + (NV50_INSTMEM_PAGE_SIZE-1)) & ~(NV50_INSTMEM_PAGE_SIZE-1);
+	if (*sz == 0)
+		return -EINVAL;
+
+	ret = nouveau_bo_new(dev, NULL, *sz, 0, TTM_PL_FLAG_VRAM, 0, 0x0000,
+			     true, false, &gpuobj->im_backing);
+	if (ret) {
+		NV_ERROR(dev, "error getting PRAMIN backing pages: %d\n", ret);
+		return ret;
+	}
+
+	ret = nouveau_bo_pin(gpuobj->im_backing, TTM_PL_FLAG_VRAM);
+	if (ret) {
+		NV_ERROR(dev, "error pinning PRAMIN backing VRAM: %d\n", ret);
+		nouveau_bo_ref(NULL, &gpuobj->im_backing);
+		return ret;
+	}
+
+	gpuobj->im_backing_start = gpuobj->im_backing->bo.mem.mm_node->start;
+	gpuobj->im_backing_start <<= PAGE_SHIFT;
+
+	return 0;
+}
+
+void
+nv50_instmem_clear(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (gpuobj && gpuobj->im_backing) {
+		if (gpuobj->im_bound)
+			dev_priv->engine.instmem.unbind(dev, gpuobj);
+		nouveau_bo_unpin(gpuobj->im_backing);
+		nouveau_bo_ref(NULL, &gpuobj->im_backing);
+		gpuobj->im_backing = NULL;
+	}
+}
+
+int
+nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
+	uint32_t pte, pte_end, vram;
+
+	if (!gpuobj->im_backing || !gpuobj->im_pramin || gpuobj->im_bound)
+		return -EINVAL;
+
+	NV_DEBUG(dev, "st=0x%0llx sz=0x%0llx\n",
+		 gpuobj->im_pramin->start, gpuobj->im_pramin->size);
+
+	pte     = (gpuobj->im_pramin->start >> 12) << 3;
+	pte_end = ((gpuobj->im_pramin->size >> 12) << 3) + pte;
+	vram    = gpuobj->im_backing_start;
+
+	NV_DEBUG(dev, "pramin=0x%llx, pte=%d, pte_end=%d\n",
+		 gpuobj->im_pramin->start, pte, pte_end);
+	NV_DEBUG(dev, "first vram page: 0x%08x\n", gpuobj->im_backing_start);
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	while (pte < pte_end) {
+		nv_wo32(dev, priv->pramin_pt->gpuobj, (pte + 0)/4, vram | 1);
+		nv_wo32(dev, priv->pramin_pt->gpuobj, (pte + 4)/4, 0x00000000);
+
+		pte += 8;
+		vram += NV50_INSTMEM_PAGE_SIZE;
+	}
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nv_wr32(dev, 0x100c80, 0x00040001);
+	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (1)\n");
+		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+		return -EBUSY;
+	}
+
+	nv_wr32(dev, 0x100c80, 0x00060001);
+	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+		return -EBUSY;
+	}
+
+	gpuobj->im_bound = 1;
+	return 0;
+}
+
+int
+nv50_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
+	uint32_t pte, pte_end;
+
+	if (gpuobj->im_bound == 0)
+		return -EINVAL;
+
+	pte     = (gpuobj->im_pramin->start >> 12) << 3;
+	pte_end = ((gpuobj->im_pramin->size >> 12) << 3) + pte;
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	while (pte < pte_end) {
+		nv_wo32(dev, priv->pramin_pt->gpuobj, (pte + 0)/4, 0x00000009);
+		nv_wo32(dev, priv->pramin_pt->gpuobj, (pte + 4)/4, 0x00000000);
+		pte += 8;
+	}
+	dev_priv->engine.instmem.finish_access(dev);
+
+	gpuobj->im_bound = 0;
+	return 0;
+}
+
+void
+nv50_instmem_prepare_access(struct drm_device *dev, bool write)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
+
+	priv->last_access_wr = write;
+}
+
+void
+nv50_instmem_finish_access(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
+
+	if (priv->last_access_wr) {
+		nv_wr32(dev, 0x070000, 0x00000001);
+		if (!nv_wait(0x070000, 0x00000001, 0x00000000))
+			NV_ERROR(dev, "PRAMIN flush timeout\n");
+	}
+}
+
diff --git a/drivers/gpu/drm/nouveau/nv50_mc.c b/drivers/gpu/drm/nouveau/nv50_mc.c
new file mode 100644
index 0000000..e0a9c3f
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv50_mc.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+
+int
+nv50_mc_init(struct drm_device *dev)
+{
+	nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF);
+	return 0;
+}
+
+void nv50_mc_takedown(struct drm_device *dev)
+{
+}
diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c
new file mode 100644
index 0000000..8c28046
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv50_sor.c
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "drm_crtc_helper.h"
+
+#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO)
+#include "nouveau_reg.h"
+#include "nouveau_drv.h"
+#include "nouveau_dma.h"
+#include "nouveau_encoder.h"
+#include "nouveau_connector.h"
+#include "nouveau_crtc.h"
+#include "nv50_display.h"
+
+static void
+nv50_sor_disconnect(struct nouveau_encoder *nv_encoder)
+{
+	struct drm_device *dev = to_drm_encoder(nv_encoder)->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	int ret;
+
+	NV_DEBUG(dev, "Disconnecting SOR %d\n", nv_encoder->or);
+
+	ret = RING_SPACE(evo, 2);
+	if (ret) {
+		NV_ERROR(dev, "no space while disconnecting SOR\n");
+		return;
+	}
+	BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1);
+	OUT_RING(evo, 0);
+}
+
+static void
+nv50_sor_dp_link_train(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct bit_displayport_encoder_table *dpe;
+	int dpe_headerlen;
+
+	dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen);
+	if (!dpe) {
+		NV_ERROR(dev, "SOR-%d: no DP encoder table!\n", nv_encoder->or);
+		return;
+	}
+
+	if (dpe->script0) {
+		NV_DEBUG(dev, "SOR-%d: running DP script 0\n", nv_encoder->or);
+		nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script0),
+					    nv_encoder->dcb);
+	}
+
+	if (!nouveau_dp_link_train(encoder))
+		NV_ERROR(dev, "SOR-%d: link training failed\n", nv_encoder->or);
+
+	if (dpe->script1) {
+		NV_DEBUG(dev, "SOR-%d: running DP script 1\n", nv_encoder->or);
+		nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script1),
+					    nv_encoder->dcb);
+	}
+}
+
+static void
+nv50_sor_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	uint32_t val;
+	int or = nv_encoder->or;
+
+	NV_DEBUG(dev, "or %d mode %d\n", or, mode);
+
+	/* wait for it to be done */
+	if (!nv_wait(NV50_PDISPLAY_SOR_DPMS_CTRL(or),
+		     NV50_PDISPLAY_SOR_DPMS_CTRL_PENDING, 0)) {
+		NV_ERROR(dev, "timeout: SOR_DPMS_CTRL_PENDING(%d) == 0\n", or);
+		NV_ERROR(dev, "SOR_DPMS_CTRL(%d) = 0x%08x\n", or,
+			 nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_CTRL(or)));
+	}
+
+	val = nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_CTRL(or));
+
+	if (mode == DRM_MODE_DPMS_ON)
+		val |= NV50_PDISPLAY_SOR_DPMS_CTRL_ON;
+	else
+		val &= ~NV50_PDISPLAY_SOR_DPMS_CTRL_ON;
+
+	nv_wr32(dev, NV50_PDISPLAY_SOR_DPMS_CTRL(or), val |
+		NV50_PDISPLAY_SOR_DPMS_CTRL_PENDING);
+	if (!nv_wait(NV50_PDISPLAY_SOR_DPMS_STATE(or),
+		     NV50_PDISPLAY_SOR_DPMS_STATE_WAIT, 0)) {
+		NV_ERROR(dev, "timeout: SOR_DPMS_STATE_WAIT(%d) == 0\n", or);
+		NV_ERROR(dev, "SOR_DPMS_STATE(%d) = 0x%08x\n", or,
+			 nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_STATE(or)));
+	}
+
+	if (nv_encoder->dcb->type == OUTPUT_DP && mode == DRM_MODE_DPMS_ON)
+		nv50_sor_dp_link_train(encoder);
+}
+
+static void
+nv50_sor_save(struct drm_encoder *encoder)
+{
+	NV_ERROR(encoder->dev, "!!\n");
+}
+
+static void
+nv50_sor_restore(struct drm_encoder *encoder)
+{
+	NV_ERROR(encoder->dev, "!!\n");
+}
+
+static bool
+nv50_sor_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
+		    struct drm_display_mode *adjusted_mode)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct nouveau_connector *connector;
+
+	NV_DEBUG(encoder->dev, "or %d\n", nv_encoder->or);
+
+	connector = nouveau_encoder_connector_get(nv_encoder);
+	if (!connector) {
+		NV_ERROR(encoder->dev, "Encoder has no connector\n");
+		return false;
+	}
+
+	if (connector->scaling_mode != DRM_MODE_SCALE_NONE &&
+	     connector->native_mode) {
+		int id = adjusted_mode->base.id;
+		*adjusted_mode = *connector->native_mode;
+		adjusted_mode->base.id = id;
+	}
+
+	return true;
+}
+
+static void
+nv50_sor_prepare(struct drm_encoder *encoder)
+{
+}
+
+static void
+nv50_sor_commit(struct drm_encoder *encoder)
+{
+}
+
+static void
+nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
+		  struct drm_display_mode *adjusted_mode)
+{
+	struct drm_nouveau_private *dev_priv = encoder->dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_crtc *crtc = nouveau_crtc(encoder->crtc);
+	uint32_t mode_ctl = 0;
+	int ret;
+
+	NV_DEBUG(dev, "or %d\n", nv_encoder->or);
+
+	nv50_sor_dpms(encoder, DRM_MODE_DPMS_ON);
+
+	switch (nv_encoder->dcb->type) {
+	case OUTPUT_TMDS:
+		if (nv_encoder->dcb->sorconf.link & 1) {
+			if (adjusted_mode->clock < 165000)
+				mode_ctl = 0x0100;
+			else
+				mode_ctl = 0x0500;
+		} else
+			mode_ctl = 0x0200;
+		break;
+	case OUTPUT_DP:
+		mode_ctl |= 0x00050000;
+		if (nv_encoder->dcb->sorconf.link & 1)
+			mode_ctl |= 0x00000800;
+		else
+			mode_ctl |= 0x00000900;
+		break;
+	default:
+		break;
+	}
+
+	if (crtc->index == 1)
+		mode_ctl |= NV50_EVO_SOR_MODE_CTRL_CRTC1;
+	else
+		mode_ctl |= NV50_EVO_SOR_MODE_CTRL_CRTC0;
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
+		mode_ctl |= NV50_EVO_SOR_MODE_CTRL_NHSYNC;
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
+		mode_ctl |= NV50_EVO_SOR_MODE_CTRL_NVSYNC;
+
+	ret = RING_SPACE(evo, 2);
+	if (ret) {
+		NV_ERROR(dev, "no space while connecting SOR\n");
+		return;
+	}
+	BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1);
+	OUT_RING(evo, mode_ctl);
+}
+
+static const struct drm_encoder_helper_funcs nv50_sor_helper_funcs = {
+	.dpms = nv50_sor_dpms,
+	.save = nv50_sor_save,
+	.restore = nv50_sor_restore,
+	.mode_fixup = nv50_sor_mode_fixup,
+	.prepare = nv50_sor_prepare,
+	.commit = nv50_sor_commit,
+	.mode_set = nv50_sor_mode_set,
+	.detect = NULL
+};
+
+static void
+nv50_sor_destroy(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+	if (!encoder)
+		return;
+
+	NV_DEBUG(encoder->dev, "\n");
+
+	drm_encoder_cleanup(encoder);
+
+	kfree(nv_encoder);
+}
+
+static const struct drm_encoder_funcs nv50_sor_encoder_funcs = {
+	.destroy = nv50_sor_destroy,
+};
+
+int
+nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
+{
+	struct nouveau_encoder *nv_encoder = NULL;
+	struct drm_encoder *encoder;
+	bool dum;
+	int type;
+
+	NV_DEBUG(dev, "\n");
+
+	switch (entry->type) {
+	case OUTPUT_TMDS:
+		NV_INFO(dev, "Detected a TMDS output\n");
+		type = DRM_MODE_ENCODER_TMDS;
+		break;
+	case OUTPUT_LVDS:
+		NV_INFO(dev, "Detected a LVDS output\n");
+		type = DRM_MODE_ENCODER_LVDS;
+
+		if (nouveau_bios_parse_lvds_table(dev, 0, &dum, &dum)) {
+			NV_ERROR(dev, "Failed parsing LVDS table\n");
+			return -EINVAL;
+		}
+		break;
+	case OUTPUT_DP:
+		NV_INFO(dev, "Detected a DP output\n");
+		type = DRM_MODE_ENCODER_TMDS;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
+	if (!nv_encoder)
+		return -ENOMEM;
+	encoder = to_drm_encoder(nv_encoder);
+
+	nv_encoder->dcb = entry;
+	nv_encoder->or = ffs(entry->or) - 1;
+
+	nv_encoder->disconnect = nv50_sor_disconnect;
+
+	drm_encoder_init(dev, encoder, &nv50_sor_encoder_funcs, type);
+	drm_encoder_helper_add(encoder, &nv50_sor_helper_funcs);
+
+	encoder->possible_crtcs = entry->heads;
+	encoder->possible_clones = 0;
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nvreg.h b/drivers/gpu/drm/nouveau/nvreg.h
new file mode 100644
index 0000000..5998c35
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvreg.h
@@ -0,0 +1,535 @@
+/* $XConsortium: nvreg.h /main/2 1996/10/28 05:13:41 kaleb $ */
+/*
+ * Copyright 1996-1997  David J. McKay
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nvreg.h,v 1.6 2002/01/25 21:56:06 tsi Exp $ */
+
+#ifndef __NVREG_H_
+#define __NVREG_H_
+
+#define NV_PMC_OFFSET               0x00000000
+#define NV_PMC_SIZE                 0x00001000
+
+#define NV_PBUS_OFFSET              0x00001000
+#define NV_PBUS_SIZE                0x00001000
+
+#define NV_PFIFO_OFFSET             0x00002000
+#define NV_PFIFO_SIZE               0x00002000
+
+#define NV_HDIAG_OFFSET             0x00005000
+#define NV_HDIAG_SIZE               0x00001000
+
+#define NV_PRAM_OFFSET              0x00006000
+#define NV_PRAM_SIZE                0x00001000
+
+#define NV_PVIDEO_OFFSET            0x00008000
+#define NV_PVIDEO_SIZE              0x00001000
+
+#define NV_PTIMER_OFFSET            0x00009000
+#define NV_PTIMER_SIZE              0x00001000
+
+#define NV_PPM_OFFSET               0x0000A000
+#define NV_PPM_SIZE                 0x00001000
+
+#define NV_PTV_OFFSET               0x0000D000
+#define NV_PTV_SIZE                 0x00001000
+
+#define NV_PRMVGA_OFFSET            0x000A0000
+#define NV_PRMVGA_SIZE              0x00020000
+
+#define NV_PRMVIO0_OFFSET           0x000C0000
+#define NV_PRMVIO_SIZE              0x00002000
+#define NV_PRMVIO1_OFFSET           0x000C2000
+
+#define NV_PFB_OFFSET               0x00100000
+#define NV_PFB_SIZE                 0x00001000
+
+#define NV_PEXTDEV_OFFSET           0x00101000
+#define NV_PEXTDEV_SIZE             0x00001000
+
+#define NV_PME_OFFSET               0x00200000
+#define NV_PME_SIZE                 0x00001000
+
+#define NV_PROM_OFFSET              0x00300000
+#define NV_PROM_SIZE                0x00010000
+
+#define NV_PGRAPH_OFFSET            0x00400000
+#define NV_PGRAPH_SIZE              0x00010000
+
+#define NV_PCRTC0_OFFSET            0x00600000
+#define NV_PCRTC0_SIZE              0x00002000 /* empirical */
+
+#define NV_PRMCIO0_OFFSET           0x00601000
+#define NV_PRMCIO_SIZE              0x00002000
+#define NV_PRMCIO1_OFFSET           0x00603000
+
+#define NV50_DISPLAY_OFFSET           0x00610000
+#define NV50_DISPLAY_SIZE             0x0000FFFF
+
+#define NV_PRAMDAC0_OFFSET          0x00680000
+#define NV_PRAMDAC0_SIZE            0x00002000
+
+#define NV_PRMDIO0_OFFSET           0x00681000
+#define NV_PRMDIO_SIZE              0x00002000
+#define NV_PRMDIO1_OFFSET           0x00683000
+
+#define NV_PRAMIN_OFFSET            0x00700000
+#define NV_PRAMIN_SIZE              0x00100000
+
+#define NV_FIFO_OFFSET              0x00800000
+#define NV_FIFO_SIZE                0x00800000
+
+#define NV_PMC_BOOT_0			0x00000000
+#define NV_PMC_ENABLE			0x00000200
+
+#define NV_VIO_VSE2			0x000003c3
+#define NV_VIO_SRX			0x000003c4
+
+#define NV_CIO_CRX__COLOR		0x000003d4
+#define NV_CIO_CR__COLOR		0x000003d5
+
+#define NV_PBUS_DEBUG_1			0x00001084
+#define NV_PBUS_DEBUG_4			0x00001098
+#define NV_PBUS_DEBUG_DUALHEAD_CTL	0x000010f0
+#define NV_PBUS_POWERCTRL_1		0x00001584
+#define NV_PBUS_POWERCTRL_2		0x00001588
+#define NV_PBUS_POWERCTRL_4		0x00001590
+#define NV_PBUS_PCI_NV_19		0x0000184C
+#define NV_PBUS_PCI_NV_20		0x00001850
+#	define NV_PBUS_PCI_NV_20_ROM_SHADOW_DISABLED	(0 << 0)
+#	define NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED	(1 << 0)
+
+#define NV_PFIFO_RAMHT			0x00002210
+
+#define NV_PTV_TV_INDEX			0x0000d220
+#define NV_PTV_TV_DATA			0x0000d224
+#define NV_PTV_HFILTER			0x0000d310
+#define NV_PTV_HFILTER2			0x0000d390
+#define NV_PTV_VFILTER			0x0000d510
+
+#define NV_PRMVIO_MISC__WRITE		0x000c03c2
+#define NV_PRMVIO_SRX			0x000c03c4
+#define NV_PRMVIO_SR			0x000c03c5
+#	define NV_VIO_SR_RESET_INDEX		0x00
+#	define NV_VIO_SR_CLOCK_INDEX		0x01
+#	define NV_VIO_SR_PLANE_MASK_INDEX	0x02
+#	define NV_VIO_SR_CHAR_MAP_INDEX		0x03
+#	define NV_VIO_SR_MEM_MODE_INDEX		0x04
+#define NV_PRMVIO_MISC__READ		0x000c03cc
+#define NV_PRMVIO_GRX			0x000c03ce
+#define NV_PRMVIO_GX			0x000c03cf
+#	define NV_VIO_GX_SR_INDEX		0x00
+#	define NV_VIO_GX_SREN_INDEX		0x01
+#	define NV_VIO_GX_CCOMP_INDEX		0x02
+#	define NV_VIO_GX_ROP_INDEX		0x03
+#	define NV_VIO_GX_READ_MAP_INDEX		0x04
+#	define NV_VIO_GX_MODE_INDEX		0x05
+#	define NV_VIO_GX_MISC_INDEX		0x06
+#	define NV_VIO_GX_DONT_CARE_INDEX	0x07
+#	define NV_VIO_GX_BIT_MASK_INDEX		0x08
+
+#define NV_PFB_BOOT_0			0x00100000
+#define NV_PFB_CFG0			0x00100200
+#define NV_PFB_CFG1			0x00100204
+#define NV_PFB_CSTATUS			0x0010020C
+#define NV_PFB_REFCTRL			0x00100210
+#	define NV_PFB_REFCTRL_VALID_1			(1 << 31)
+#define NV_PFB_PAD			0x0010021C
+#	define NV_PFB_PAD_CKE_NORMAL			(1 << 0)
+#define NV_PFB_TILE_NV10		0x00100240
+#define NV_PFB_TILE_SIZE_NV10		0x00100244
+#define NV_PFB_REF			0x001002D0
+#	define NV_PFB_REF_CMD_REFRESH			(1 << 0)
+#define NV_PFB_PRE			0x001002D4
+#	define NV_PFB_PRE_CMD_PRECHARGE			(1 << 0)
+#define NV_PFB_CLOSE_PAGE2		0x0010033C
+#define NV_PFB_TILE_NV40		0x00100600
+#define NV_PFB_TILE_SIZE_NV40		0x00100604
+
+#define NV_PEXTDEV_BOOT_0		0x00101000
+#	define NV_PEXTDEV_BOOT_0_STRAP_FP_IFACE_12BIT	(8 << 12)
+#define NV_PEXTDEV_BOOT_3		0x0010100c
+
+#define NV_PCRTC_INTR_0					0x00600100
+#	define NV_PCRTC_INTR_0_VBLANK				(1 << 0)
+#define NV_PCRTC_INTR_EN_0				0x00600140
+#define NV_PCRTC_START					0x00600800
+#define NV_PCRTC_CONFIG					0x00600804
+#	define NV_PCRTC_CONFIG_START_ADDRESS_NON_VGA		(1 << 0)
+#	define NV_PCRTC_CONFIG_START_ADDRESS_HSYNC		(2 << 0)
+#define NV_PCRTC_CURSOR_CONFIG				0x00600810
+#	define NV_PCRTC_CURSOR_CONFIG_ENABLE_ENABLE		(1 << 0)
+#	define NV_PCRTC_CURSOR_CONFIG_DOUBLE_SCAN_ENABLE	(1 << 4)
+#	define NV_PCRTC_CURSOR_CONFIG_ADDRESS_SPACE_PNVM	(1 << 8)
+#	define NV_PCRTC_CURSOR_CONFIG_CUR_BPP_32		(1 << 12)
+#	define NV_PCRTC_CURSOR_CONFIG_CUR_PIXELS_64		(1 << 16)
+#	define NV_PCRTC_CURSOR_CONFIG_CUR_LINES_32		(2 << 24)
+#	define NV_PCRTC_CURSOR_CONFIG_CUR_LINES_64		(4 << 24)
+#	define NV_PCRTC_CURSOR_CONFIG_CUR_BLEND_ALPHA		(1 << 28)
+
+/* note: PCRTC_GPIO is not available on nv10, and in fact aliases 0x600810 */
+#define NV_PCRTC_GPIO					0x00600818
+#define NV_PCRTC_GPIO_EXT				0x0060081c
+#define NV_PCRTC_830					0x00600830
+#define NV_PCRTC_834					0x00600834
+#define NV_PCRTC_850					0x00600850
+#define NV_PCRTC_ENGINE_CTRL				0x00600860
+#	define NV_CRTC_FSEL_I2C					(1 << 4)
+#	define NV_CRTC_FSEL_OVERLAY				(1 << 12)
+
+#define NV_PRMCIO_ARX			0x006013c0
+#define NV_PRMCIO_AR__WRITE		0x006013c0
+#define NV_PRMCIO_AR__READ		0x006013c1
+#	define NV_CIO_AR_MODE_INDEX		0x10
+#	define NV_CIO_AR_OSCAN_INDEX		0x11
+#	define NV_CIO_AR_PLANE_INDEX		0x12
+#	define NV_CIO_AR_HPP_INDEX		0x13
+#	define NV_CIO_AR_CSEL_INDEX		0x14
+#define NV_PRMCIO_INP0			0x006013c2
+#define NV_PRMCIO_CRX__COLOR		0x006013d4
+#define NV_PRMCIO_CR__COLOR		0x006013d5
+	/* Standard VGA CRTC registers */
+#	define NV_CIO_CR_HDT_INDEX		0x00	/* horizontal display total */
+#	define NV_CIO_CR_HDE_INDEX		0x01	/* horizontal display end */
+#	define NV_CIO_CR_HBS_INDEX		0x02	/* horizontal blanking start */
+#	define NV_CIO_CR_HBE_INDEX		0x03	/* horizontal blanking end */
+#		define NV_CIO_CR_HBE_4_0		4:0
+#	define NV_CIO_CR_HRS_INDEX		0x04	/* horizontal retrace start */
+#	define NV_CIO_CR_HRE_INDEX		0x05	/* horizontal retrace end */
+#		define NV_CIO_CR_HRE_4_0		4:0
+#		define NV_CIO_CR_HRE_HBE_5		7:7
+#	define NV_CIO_CR_VDT_INDEX		0x06	/* vertical display total */
+#	define NV_CIO_CR_OVL_INDEX		0x07	/* overflow bits */
+#		define NV_CIO_CR_OVL_VDT_8		0:0
+#		define NV_CIO_CR_OVL_VDE_8		1:1
+#		define NV_CIO_CR_OVL_VRS_8		2:2
+#		define NV_CIO_CR_OVL_VBS_8		3:3
+#		define NV_CIO_CR_OVL_VDT_9		5:5
+#		define NV_CIO_CR_OVL_VDE_9		6:6
+#		define NV_CIO_CR_OVL_VRS_9		7:7
+#	define NV_CIO_CR_RSAL_INDEX		0x08	/* normally "preset row scan" */
+#	define NV_CIO_CR_CELL_HT_INDEX		0x09	/* cell height?! normally "max scan line" */
+#		define NV_CIO_CR_CELL_HT_VBS_9		5:5
+#		define NV_CIO_CR_CELL_HT_SCANDBL	7:7
+#	define NV_CIO_CR_CURS_ST_INDEX		0x0a	/* cursor start */
+#	define NV_CIO_CR_CURS_END_INDEX		0x0b	/* cursor end */
+#	define NV_CIO_CR_SA_HI_INDEX		0x0c	/* screen start address high */
+#	define NV_CIO_CR_SA_LO_INDEX		0x0d	/* screen start address low */
+#	define NV_CIO_CR_TCOFF_HI_INDEX		0x0e	/* cursor offset high */
+#	define NV_CIO_CR_TCOFF_LO_INDEX		0x0f	/* cursor offset low */
+#	define NV_CIO_CR_VRS_INDEX		0x10	/* vertical retrace start */
+#	define NV_CIO_CR_VRE_INDEX		0x11	/* vertical retrace end */
+#		define NV_CIO_CR_VRE_3_0		3:0
+#	define NV_CIO_CR_VDE_INDEX		0x12	/* vertical display end */
+#	define NV_CIO_CR_OFFSET_INDEX		0x13	/* sets screen pitch */
+#	define NV_CIO_CR_ULINE_INDEX		0x14	/* underline location */
+#	define NV_CIO_CR_VBS_INDEX		0x15	/* vertical blank start */
+#	define NV_CIO_CR_VBE_INDEX		0x16	/* vertical blank end */
+#	define NV_CIO_CR_MODE_INDEX		0x17	/* crtc mode control */
+#	define NV_CIO_CR_LCOMP_INDEX		0x18	/* line compare */
+	/* Extended VGA CRTC registers */
+#	define NV_CIO_CRE_RPC0_INDEX		0x19	/* repaint control 0 */
+#		define NV_CIO_CRE_RPC0_OFFSET_10_8	7:5
+#	define NV_CIO_CRE_RPC1_INDEX		0x1a	/* repaint control 1 */
+#		define NV_CIO_CRE_RPC1_LARGE		2:2
+#	define NV_CIO_CRE_FF_INDEX		0x1b	/* fifo control */
+#	define NV_CIO_CRE_ENH_INDEX		0x1c	/* enhanced? */
+#	define NV_CIO_SR_LOCK_INDEX		0x1f	/* crtc lock */
+#		define NV_CIO_SR_UNLOCK_RW_VALUE	0x57
+#		define NV_CIO_SR_LOCK_VALUE		0x99
+#	define NV_CIO_CRE_FFLWM__INDEX		0x20	/* fifo low water mark */
+#	define NV_CIO_CRE_21			0x21	/* vga shadow crtc lock */
+#	define NV_CIO_CRE_LSR_INDEX		0x25	/* ? */
+#		define NV_CIO_CRE_LSR_VDT_10		0:0
+#		define NV_CIO_CRE_LSR_VDE_10		1:1
+#		define NV_CIO_CRE_LSR_VRS_10		2:2
+#		define NV_CIO_CRE_LSR_VBS_10		3:3
+#		define NV_CIO_CRE_LSR_HBE_6		4:4
+#	define NV_CIO_CR_ARX_INDEX		0x26	/* attribute index -- ro copy of 0x60.3c0 */
+#	define NV_CIO_CRE_CHIP_ID_INDEX		0x27	/* chip revision */
+#	define NV_CIO_CRE_PIXEL_INDEX		0x28
+#		define NV_CIO_CRE_PIXEL_FORMAT		1:0
+#	define NV_CIO_CRE_HEB__INDEX		0x2d	/* horizontal extra bits? */
+#		define NV_CIO_CRE_HEB_HDT_8		0:0
+#		define NV_CIO_CRE_HEB_HDE_8		1:1
+#		define NV_CIO_CRE_HEB_HBS_8		2:2
+#		define NV_CIO_CRE_HEB_HRS_8		3:3
+#		define NV_CIO_CRE_HEB_ILC_8		4:4
+#	define NV_CIO_CRE_2E			0x2e	/* some scratch or dummy reg to force writes to sink in */
+#	define NV_CIO_CRE_HCUR_ADDR2_INDEX	0x2f	/* cursor */
+#	define NV_CIO_CRE_HCUR_ADDR0_INDEX	0x30		/* pixmap */
+#		define NV_CIO_CRE_HCUR_ADDR0_ADR	6:0
+#		define NV_CIO_CRE_HCUR_ASI		7:7
+#	define NV_CIO_CRE_HCUR_ADDR1_INDEX	0x31			/* address */
+#		define NV_CIO_CRE_HCUR_ADDR1_ENABLE	0:0
+#		define NV_CIO_CRE_HCUR_ADDR1_CUR_DBL	1:1
+#		define NV_CIO_CRE_HCUR_ADDR1_ADR	7:2
+#	define NV_CIO_CRE_LCD__INDEX		0x33
+#		define NV_CIO_CRE_LCD_LCD_SELECT	0:0
+#	define NV_CIO_CRE_DDC0_STATUS__INDEX	0x36
+#	define NV_CIO_CRE_DDC0_WR__INDEX	0x37
+#	define NV_CIO_CRE_ILACE__INDEX		0x39	/* interlace */
+#	define NV_CIO_CRE_SCRATCH3__INDEX	0x3b
+#	define NV_CIO_CRE_SCRATCH4__INDEX	0x3c
+#	define NV_CIO_CRE_DDC_STATUS__INDEX	0x3e
+#	define NV_CIO_CRE_DDC_WR__INDEX		0x3f
+#	define NV_CIO_CRE_EBR_INDEX		0x41	/* extra bits ? (vertical) */
+#		define NV_CIO_CRE_EBR_VDT_11		0:0
+#		define NV_CIO_CRE_EBR_VDE_11		2:2
+#		define NV_CIO_CRE_EBR_VRS_11		4:4
+#		define NV_CIO_CRE_EBR_VBS_11		6:6
+#	define NV_CIO_CRE_43			0x43
+#	define NV_CIO_CRE_44			0x44	/* head control */
+#	define NV_CIO_CRE_CSB			0x45	/* colour saturation boost */
+#	define NV_CIO_CRE_RCR			0x46
+#		define NV_CIO_CRE_RCR_ENDIAN_BIG	7:7
+#	define NV_CIO_CRE_47			0x47	/* extended fifo lwm, used on nv30+ */
+#	define NV_CIO_CRE_49			0x49
+#	define NV_CIO_CRE_4B			0x4b	/* given patterns in 0x[2-3][a-c] regs, probably scratch 6 */
+#	define NV_CIO_CRE_TVOUT_LATENCY		0x52
+#	define NV_CIO_CRE_53			0x53	/* `fp_htiming' according to Haiku */
+#	define NV_CIO_CRE_54			0x54	/* `fp_vtiming' according to Haiku */
+#	define NV_CIO_CRE_57			0x57	/* index reg for cr58 */
+#	define NV_CIO_CRE_58			0x58	/* data reg for cr57 */
+#	define NV_CIO_CRE_59			0x59	/* related to on/off-chip-ness of digital outputs */
+#	define NV_CIO_CRE_5B			0x5B	/* newer colour saturation reg */
+#	define NV_CIO_CRE_85			0x85
+#	define NV_CIO_CRE_86			0x86
+#define NV_PRMCIO_INP0__COLOR		0x006013da
+
+#define NV_PRAMDAC_CU_START_POS				0x00680300
+#	define NV_PRAMDAC_CU_START_POS_X			15:0
+#	define NV_PRAMDAC_CU_START_POS_Y			31:16
+#define NV_RAMDAC_NV10_CURSYNC				0x00680404
+
+#define NV_PRAMDAC_NVPLL_COEFF				0x00680500
+#define NV_PRAMDAC_MPLL_COEFF				0x00680504
+#define NV_PRAMDAC_VPLL_COEFF				0x00680508
+#	define NV30_RAMDAC_ENABLE_VCO2				(8 << 4)
+
+#define NV_PRAMDAC_PLL_COEFF_SELECT			0x0068050c
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_USE_VPLL2_TRUE	(4 << 0)
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_MPLL	(1 << 8)
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_VPLL	(2 << 8)
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_NVPLL	(4 << 8)
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_PLL_SOURCE_VPLL2	(8 << 8)
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK1		(1 << 16)
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK1		(2 << 16)
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK2		(4 << 16)
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK2		(8 << 16)
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_TV_CLK_SOURCE_VIP	(1 << 20)
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO_DB2	(1 << 28)
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK2_RATIO_DB2	(2 << 28)
+
+#define NV_PRAMDAC_PLL_SETUP_CONTROL			0x00680510
+#define NV_RAMDAC_VPLL2					0x00680520
+#define NV_PRAMDAC_SEL_CLK				0x00680524
+#define NV_RAMDAC_DITHER_NV11				0x00680528
+#define NV_PRAMDAC_DACCLK				0x0068052c
+#	define NV_PRAMDAC_DACCLK_SEL_DACCLK			(1 << 0)
+
+#define NV_RAMDAC_NVPLL_B				0x00680570
+#define NV_RAMDAC_MPLL_B				0x00680574
+#define NV_RAMDAC_VPLL_B				0x00680578
+#define NV_RAMDAC_VPLL2_B				0x0068057c
+#	define NV31_RAMDAC_ENABLE_VCO2				(8 << 28)
+#define NV_PRAMDAC_580					0x00680580
+#	define NV_RAMDAC_580_VPLL1_ACTIVE			(1 << 8)
+#	define NV_RAMDAC_580_VPLL2_ACTIVE			(1 << 28)
+
+#define NV_PRAMDAC_GENERAL_CONTROL			0x00680600
+#	define NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON		(3 << 4)
+#	define NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE_SEL		(1 << 8)
+#	define NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL		(1 << 12)
+#	define NV_PRAMDAC_GENERAL_CONTROL_TERMINATION_75OHM	(2 << 16)
+#	define NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS		(1 << 20)
+#	define NV_PRAMDAC_GENERAL_CONTROL_PIPE_LONG		(2 << 28)
+#define NV_PRAMDAC_TEST_CONTROL				0x00680608
+#	define NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED	(1 << 12)
+#	define NV_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_OFF		(1 << 16)
+#	define NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI		(1 << 28)
+#define NV_PRAMDAC_TESTPOINT_DATA			0x00680610
+#	define NV_PRAMDAC_TESTPOINT_DATA_NOTBLANK		(8 << 28)
+#define NV_PRAMDAC_630					0x00680630
+#define NV_PRAMDAC_634					0x00680634
+
+#define NV_PRAMDAC_TV_SETUP				0x00680700
+#define NV_PRAMDAC_TV_VTOTAL				0x00680720
+#define NV_PRAMDAC_TV_VSKEW				0x00680724
+#define NV_PRAMDAC_TV_VSYNC_DELAY			0x00680728
+#define NV_PRAMDAC_TV_HTOTAL				0x0068072c
+#define NV_PRAMDAC_TV_HSKEW				0x00680730
+#define NV_PRAMDAC_TV_HSYNC_DELAY			0x00680734
+#define NV_PRAMDAC_TV_HSYNC_DELAY2			0x00680738
+
+#define NV_PRAMDAC_TV_SETUP                             0x00680700
+
+#define NV_PRAMDAC_FP_VDISPLAY_END			0x00680800
+#define NV_PRAMDAC_FP_VTOTAL				0x00680804
+#define NV_PRAMDAC_FP_VCRTC				0x00680808
+#define NV_PRAMDAC_FP_VSYNC_START			0x0068080c
+#define NV_PRAMDAC_FP_VSYNC_END				0x00680810
+#define NV_PRAMDAC_FP_VVALID_START			0x00680814
+#define NV_PRAMDAC_FP_VVALID_END			0x00680818
+#define NV_PRAMDAC_FP_HDISPLAY_END			0x00680820
+#define NV_PRAMDAC_FP_HTOTAL				0x00680824
+#define NV_PRAMDAC_FP_HCRTC				0x00680828
+#define NV_PRAMDAC_FP_HSYNC_START			0x0068082c
+#define NV_PRAMDAC_FP_HSYNC_END				0x00680830
+#define NV_PRAMDAC_FP_HVALID_START			0x00680834
+#define NV_PRAMDAC_FP_HVALID_END			0x00680838
+
+#define NV_RAMDAC_FP_DITHER				0x0068083c
+#define NV_PRAMDAC_FP_TG_CONTROL			0x00680848
+#	define NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS		(1 << 0)
+#	define NV_PRAMDAC_FP_TG_CONTROL_VSYNC_DISABLE		(2 << 0)
+#	define NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS		(1 << 4)
+#	define NV_PRAMDAC_FP_TG_CONTROL_HSYNC_DISABLE		(2 << 4)
+#	define NV_PRAMDAC_FP_TG_CONTROL_MODE_SCALE		(0 << 8)
+#	define NV_PRAMDAC_FP_TG_CONTROL_MODE_CENTER		(1 << 8)
+#	define NV_PRAMDAC_FP_TG_CONTROL_MODE_NATIVE		(2 << 8)
+#	define NV_PRAMDAC_FP_TG_CONTROL_READ_PROG		(1 << 20)
+#	define NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12		(1 << 24)
+#	define NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS		(1 << 28)
+#	define NV_PRAMDAC_FP_TG_CONTROL_DISPEN_DISABLE		(2 << 28)
+#define NV_PRAMDAC_FP_MARGIN_COLOR			0x0068084c
+#define NV_PRAMDAC_850					0x00680850
+#define NV_PRAMDAC_85C					0x0068085c
+#define NV_PRAMDAC_FP_DEBUG_0				0x00680880
+#	define NV_PRAMDAC_FP_DEBUG_0_XSCALE_ENABLE		(1 << 0)
+#	define NV_PRAMDAC_FP_DEBUG_0_YSCALE_ENABLE		(1 << 4)
+/* This doesn't seem to be essential for tmds, but still often set */
+#	define NV_RAMDAC_FP_DEBUG_0_TMDS_ENABLED		(8 << 4)
+#	define NV_PRAMDAC_FP_DEBUG_0_XINTERP_BILINEAR		(1 << 8)
+#	define NV_PRAMDAC_FP_DEBUG_0_YINTERP_BILINEAR		(1 << 12)
+#	define NV_PRAMDAC_FP_DEBUG_0_XWEIGHT_ROUND		(1 << 20)
+#	define NV_PRAMDAC_FP_DEBUG_0_YWEIGHT_ROUND		(1 << 24)
+#       define NV_PRAMDAC_FP_DEBUG_0_PWRDOWN_FPCLK              (1 << 28)
+#define NV_PRAMDAC_FP_DEBUG_1				0x00680884
+#	define NV_PRAMDAC_FP_DEBUG_1_XSCALE_VALUE		11:0
+#	define NV_PRAMDAC_FP_DEBUG_1_XSCALE_TESTMODE_ENABLE	(1 << 12)
+#	define NV_PRAMDAC_FP_DEBUG_1_YSCALE_VALUE		27:16
+#	define NV_PRAMDAC_FP_DEBUG_1_YSCALE_TESTMODE_ENABLE	(1 << 28)
+#define NV_PRAMDAC_FP_DEBUG_2				0x00680888
+#define NV_PRAMDAC_FP_DEBUG_3				0x0068088C
+
+/* see NV_PRAMDAC_INDIR_TMDS in rules.xml */
+#define NV_PRAMDAC_FP_TMDS_CONTROL			0x006808b0
+#	define NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE		(1 << 16)
+#define NV_PRAMDAC_FP_TMDS_DATA				0x006808b4
+
+#define NV_PRAMDAC_8C0                                  0x006808c0
+
+/* Some kind of switch */
+#define NV_PRAMDAC_900					0x00680900
+#define NV_PRAMDAC_A20					0x00680A20
+#define NV_PRAMDAC_A24					0x00680A24
+#define NV_PRAMDAC_A34					0x00680A34
+
+#define NV_PRAMDAC_CTV					0x00680c00
+
+/* names fabricated from NV_USER_DAC info */
+#define NV_PRMDIO_PIXEL_MASK		0x006813c6
+#	define NV_PRMDIO_PIXEL_MASK_MASK	0xff
+#define NV_PRMDIO_READ_MODE_ADDRESS	0x006813c7
+#define NV_PRMDIO_WRITE_MODE_ADDRESS	0x006813c8
+#define NV_PRMDIO_PALETTE_DATA		0x006813c9
+
+#define NV_PGRAPH_DEBUG_0		0x00400080
+#define NV_PGRAPH_DEBUG_1		0x00400084
+#define NV_PGRAPH_DEBUG_2_NV04		0x00400088
+#define NV_PGRAPH_DEBUG_2		0x00400620
+#define NV_PGRAPH_DEBUG_3		0x0040008c
+#define NV_PGRAPH_DEBUG_4		0x00400090
+#define NV_PGRAPH_INTR			0x00400100
+#define NV_PGRAPH_INTR_EN		0x00400140
+#define NV_PGRAPH_CTX_CONTROL		0x00400144
+#define NV_PGRAPH_CTX_CONTROL_NV04	0x00400170
+#define NV_PGRAPH_ABS_UCLIP_XMIN	0x0040053C
+#define NV_PGRAPH_ABS_UCLIP_YMIN	0x00400540
+#define NV_PGRAPH_ABS_UCLIP_XMAX	0x00400544
+#define NV_PGRAPH_ABS_UCLIP_YMAX	0x00400548
+#define NV_PGRAPH_BETA_AND		0x00400608
+#define NV_PGRAPH_LIMIT_VIOL_PIX	0x00400610
+#define NV_PGRAPH_BOFFSET0		0x00400640
+#define NV_PGRAPH_BOFFSET1		0x00400644
+#define NV_PGRAPH_BOFFSET2		0x00400648
+#define NV_PGRAPH_BLIMIT0		0x00400684
+#define NV_PGRAPH_BLIMIT1		0x00400688
+#define NV_PGRAPH_BLIMIT2		0x0040068c
+#define NV_PGRAPH_STATUS		0x00400700
+#define NV_PGRAPH_SURFACE		0x00400710
+#define NV_PGRAPH_STATE			0x00400714
+#define NV_PGRAPH_FIFO			0x00400720
+#define NV_PGRAPH_PATTERN_SHAPE		0x00400810
+#define NV_PGRAPH_TILE			0x00400b00
+
+#define NV_PVIDEO_INTR_EN		0x00008140
+#define NV_PVIDEO_BUFFER		0x00008700
+#define NV_PVIDEO_STOP			0x00008704
+#define NV_PVIDEO_UVPLANE_BASE(buff)	(0x00008800+(buff)*4)
+#define NV_PVIDEO_UVPLANE_LIMIT(buff)	(0x00008808+(buff)*4)
+#define NV_PVIDEO_UVPLANE_OFFSET_BUFF(buff)	(0x00008820+(buff)*4)
+#define NV_PVIDEO_BASE(buff)		(0x00008900+(buff)*4)
+#define NV_PVIDEO_LIMIT(buff)		(0x00008908+(buff)*4)
+#define NV_PVIDEO_LUMINANCE(buff)	(0x00008910+(buff)*4)
+#define NV_PVIDEO_CHROMINANCE(buff)	(0x00008918+(buff)*4)
+#define NV_PVIDEO_OFFSET_BUFF(buff)	(0x00008920+(buff)*4)
+#define NV_PVIDEO_SIZE_IN(buff)		(0x00008928+(buff)*4)
+#define NV_PVIDEO_POINT_IN(buff)	(0x00008930+(buff)*4)
+#define NV_PVIDEO_DS_DX(buff)		(0x00008938+(buff)*4)
+#define NV_PVIDEO_DT_DY(buff)		(0x00008940+(buff)*4)
+#define NV_PVIDEO_POINT_OUT(buff)	(0x00008948+(buff)*4)
+#define NV_PVIDEO_SIZE_OUT(buff)	(0x00008950+(buff)*4)
+#define NV_PVIDEO_FORMAT(buff)		(0x00008958+(buff)*4)
+#	define NV_PVIDEO_FORMAT_PLANAR			(1 << 0)
+#	define NV_PVIDEO_FORMAT_COLOR_LE_CR8YB8CB8YA8	(1 << 16)
+#	define NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY	(1 << 20)
+#	define NV_PVIDEO_FORMAT_MATRIX_ITURBT709	(1 << 24)
+#define NV_PVIDEO_COLOR_KEY		0x00008B00
+
+/* NV04 overlay defines from VIDIX & Haiku */
+#define NV_PVIDEO_INTR_EN_0		0x00680140
+#define NV_PVIDEO_STEP_SIZE		0x00680200
+#define NV_PVIDEO_CONTROL_Y		0x00680204
+#define NV_PVIDEO_CONTROL_X		0x00680208
+#define NV_PVIDEO_BUFF0_START_ADDRESS	0x0068020c
+#define NV_PVIDEO_BUFF0_PITCH_LENGTH	0x00680214
+#define NV_PVIDEO_BUFF0_OFFSET		0x0068021c
+#define NV_PVIDEO_BUFF1_START_ADDRESS	0x00680210
+#define NV_PVIDEO_BUFF1_PITCH_LENGTH	0x00680218
+#define NV_PVIDEO_BUFF1_OFFSET		0x00680220
+#define NV_PVIDEO_OE_STATE		0x00680224
+#define NV_PVIDEO_SU_STATE		0x00680228
+#define NV_PVIDEO_RM_STATE		0x0068022c
+#define NV_PVIDEO_WINDOW_START		0x00680230
+#define NV_PVIDEO_WINDOW_SIZE		0x00680234
+#define NV_PVIDEO_FIFO_THRES_SIZE	0x00680238
+#define NV_PVIDEO_FIFO_BURST_LENGTH	0x0068023c
+#define NV_PVIDEO_KEY			0x00680240
+#define NV_PVIDEO_OVERLAY		0x00680244
+#define NV_PVIDEO_RED_CSC_OFFSET	0x00680280
+#define NV_PVIDEO_GREEN_CSC_OFFSET	0x00680284
+#define NV_PVIDEO_BLUE_CSC_OFFSET	0x00680288
+#define NV_PVIDEO_CSC_ADJUST		0x0068028c
+
+#endif
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index b5713ee..feb52ee 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -49,7 +49,7 @@
 	radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \
 	rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \
 	r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \
-	r600_blit_kms.o radeon_pm.o
+	r600_blit_kms.o radeon_pm.o atombios_dp.o
 
 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
 
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c
index d67c425..6578d19 100644
--- a/drivers/gpu/drm/radeon/atom.c
+++ b/drivers/gpu/drm/radeon/atom.c
@@ -263,10 +263,10 @@
 	case ATOM_ARG_FB:
 		idx = U8(*ptr);
 		(*ptr)++;
+		val = gctx->scratch[((gctx->fb_base + idx) / 4)];
 		if (print)
 			DEBUG("FB[0x%02X]", idx);
-		printk(KERN_INFO "FB access is not implemented.\n");
-		return 0;
+		break;
 	case ATOM_ARG_IMM:
 		switch (align) {
 		case ATOM_SRC_DWORD:
@@ -488,9 +488,9 @@
 	case ATOM_ARG_FB:
 		idx = U8(*ptr);
 		(*ptr)++;
+		gctx->scratch[((gctx->fb_base + idx) / 4)] = val;
 		DEBUG("FB[0x%02X]", idx);
-		printk(KERN_INFO "FB access is not implemented.\n");
-		return;
+		break;
 	case ATOM_ARG_PLL:
 		idx = U8(*ptr);
 		(*ptr)++;
@@ -1214,3 +1214,28 @@
 		*crev = CU8(idx + 3);
 	return;
 }
+
+int atom_allocate_fb_scratch(struct atom_context *ctx)
+{
+	int index = GetIndexIntoMasterTable(DATA, VRAM_UsageByFirmware);
+	uint16_t data_offset;
+	int usage_bytes;
+	struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage;
+
+	atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset);
+
+	firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset);
+
+	DRM_DEBUG("atom firmware requested %08x %dkb\n",
+		  firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware,
+		  firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb);
+
+	usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
+	if (usage_bytes == 0)
+		usage_bytes = 20 * 1024;
+	/* allocate some scratch memory */
+	ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL);
+	if (!ctx->scratch)
+		return -ENOMEM;
+	return 0;
+}
diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h
index e6eb38f..6671848 100644
--- a/drivers/gpu/drm/radeon/atom.h
+++ b/drivers/gpu/drm/radeon/atom.h
@@ -132,6 +132,7 @@
 	uint8_t shift;
 	int cs_equal, cs_above;
 	int io_mode;
+	uint32_t *scratch;
 };
 
 extern int atom_debug;
@@ -142,6 +143,7 @@
 void atom_destroy(struct atom_context *);
 void atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start);
 void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *frev, uint8_t *crev);
+int atom_allocate_fb_scratch(struct atom_context *ctx);
 #include "atom-types.h"
 #include "atombios.h"
 #include "ObjectID.h"
diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h
index c11dddd..5f48515 100644
--- a/drivers/gpu/drm/radeon/atombios.h
+++ b/drivers/gpu/drm/radeon/atombios.h
@@ -1141,7 +1141,7 @@
 /* ucTableFormatRevision=1,ucTableContentRevision=2 */
 typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS_V2 {
 	USHORT usPixelClock;	/*  in 10KHz; for bios convenient */
-	UCHAR ucMisc;		/*  see PANEL_ENCODER_MISC_xx defintions below */
+	UCHAR ucMisc;		/*  see PANEL_ENCODER_MISC_xx definitions below */
 	UCHAR ucAction;		/*  0: turn off encoder */
 	/*  1: setup and turn on encoder */
 	UCHAR ucTruncate;	/*  bit0=0: Disable truncate */
@@ -1424,7 +1424,7 @@
 /*  Structures used in FirmwareInfoTable */
 /****************************************************************************/
 
-/*  usBIOSCapability Defintion: */
+/*  usBIOSCapability Definition: */
 /*  Bit 0 = 0: Bios image is not Posted, =1:Bios image is Posted; */
 /*  Bit 1 = 0: Dual CRTC is not supported, =1: Dual CRTC is supported; */
 /*  Bit 2 = 0: Extended Desktop is not supported, =1: Extended Desktop is supported; */
@@ -2386,7 +2386,7 @@
 } ATOM_ANALOG_TV_INFO_V1_2;
 
 /**************************************************************************/
-/*  VRAM usage and their defintions */
+/*  VRAM usage and their definitions */
 
 /*  One chunk of VRAM used by Bios are for HWICON surfaces,EDID data. */
 /*  Current Mode timing and Dail Timing and/or STD timing data EACH device. They can be broken down as below. */
@@ -2680,7 +2680,7 @@
 typedef struct _ATOM_HPD_INT_RECORD {
 	ATOM_COMMON_RECORD_HEADER sheader;
 	UCHAR ucHPDIntGPIOID;	/* Corresponding block in GPIO_PIN_INFO table gives the pin info */
-	UCHAR ucPluggged_PinState;
+	UCHAR ucPlugged_PinState;
 } ATOM_HPD_INT_RECORD;
 
 typedef struct _ATOM_OUTPUT_PROTECTION_RECORD {
@@ -3046,7 +3046,7 @@
 #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_DC     2
 #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_LITEAC 3
 
-/* Byte aligned defintion for BIOS usage */
+/* Byte aligned definition for BIOS usage */
 #define ATOM_S0_CRT1_MONOb0             0x01
 #define ATOM_S0_CRT1_COLORb0            0x02
 #define ATOM_S0_CRT1_MASKb0             (ATOM_S0_CRT1_MONOb0+ATOM_S0_CRT1_COLORb0)
@@ -3131,7 +3131,7 @@
 #define ATOM_S2_DISPLAY_ROTATION_DEGREE_SHIFT 30
 #define ATOM_S2_DISPLAY_ROTATION_ANGLE_MASK   0xC0000000L
 
-/* Byte aligned defintion for BIOS usage */
+/* Byte aligned definition for BIOS usage */
 #define ATOM_S2_TV1_STANDARD_MASKb0     0x0F
 #define ATOM_S2_CURRENT_BL_LEVEL_MASKb1 0xFF
 #define ATOM_S2_CRT1_DPMS_STATEb2       0x01
@@ -3190,7 +3190,7 @@
 #define ATOM_S3_ALLOW_FAST_PWR_SWITCH   0x40000000L
 #define ATOM_S3_RQST_GPU_USE_MIN_PWR    0x80000000L
 
-/* Byte aligned defintion for BIOS usage */
+/* Byte aligned definition for BIOS usage */
 #define ATOM_S3_CRT1_ACTIVEb0           0x01
 #define ATOM_S3_LCD1_ACTIVEb0           0x02
 #define ATOM_S3_TV1_ACTIVEb0            0x04
@@ -3230,7 +3230,7 @@
 #define ATOM_S4_LCD1_REFRESH_MASK       0x0000FF00L
 #define ATOM_S4_LCD1_REFRESH_SHIFT      8
 
-/* Byte aligned defintion for BIOS usage */
+/* Byte aligned definition for BIOS usage */
 #define ATOM_S4_LCD1_PANEL_ID_MASKb0	  0x0FF
 #define ATOM_S4_LCD1_REFRESH_MASKb1		  ATOM_S4_LCD1_PANEL_ID_MASKb0
 #define ATOM_S4_VRAM_INFO_MASKb2        ATOM_S4_LCD1_PANEL_ID_MASKb0
@@ -3310,7 +3310,7 @@
 #define ATOM_S6_VRI_BRIGHTNESS_CHANGE       0x40000000L
 #define ATOM_S6_CONFIG_DISPLAY_CHANGE_MASK  0x80000000L
 
-/* Byte aligned defintion for BIOS usage */
+/* Byte aligned definition for BIOS usage */
 #define ATOM_S6_DEVICE_CHANGEb0         0x01
 #define ATOM_S6_SCALER_CHANGEb0         0x02
 #define ATOM_S6_LID_CHANGEb0            0x04
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index c15287a..260fcf5 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -241,6 +241,7 @@
 {
 	struct drm_device *dev = crtc->dev;
 	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 
 	switch (mode) {
 	case DRM_MODE_DPMS_ON:
@@ -248,20 +249,19 @@
 		if (ASIC_IS_DCE3(rdev))
 			atombios_enable_crtc_memreq(crtc, 1);
 		atombios_blank_crtc(crtc, 0);
+		drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
+		radeon_crtc_load_lut(crtc);
 		break;
 	case DRM_MODE_DPMS_STANDBY:
 	case DRM_MODE_DPMS_SUSPEND:
 	case DRM_MODE_DPMS_OFF:
+		drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
 		atombios_blank_crtc(crtc, 1);
 		if (ASIC_IS_DCE3(rdev))
 			atombios_enable_crtc_memreq(crtc, 0);
 		atombios_enable_crtc(crtc, 0);
 		break;
 	}
-
-	if (mode != DRM_MODE_DPMS_OFF) {
-		radeon_crtc_load_lut(crtc);
-	}
 }
 
 static void
@@ -457,9 +457,8 @@
 				if (encoder->encoder_type !=
 				    DRM_MODE_ENCODER_DAC)
 					pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
-				if (!ASIC_IS_AVIVO(rdev)
-				    && (encoder->encoder_type ==
-					DRM_MODE_ENCODER_LVDS))
+				if (encoder->encoder_type ==
+					DRM_MODE_ENCODER_LVDS)
 					pll_flags |= RADEON_PLL_USE_REF_DIV;
 			}
 			radeon_encoder = to_radeon_encoder(encoder);
@@ -500,8 +499,18 @@
 	else
 		pll = &rdev->clock.p2pll;
 
-	radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
-			   &ref_div, &post_div, pll_flags);
+	if (ASIC_IS_AVIVO(rdev)) {
+		if (radeon_new_pll)
+			radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock,
+						 &fb_div, &frac_fb_div,
+						 &ref_div, &post_div, pll_flags);
+		else
+			radeon_compute_pll(pll, adjusted_clock, &pll_clock,
+					   &fb_div, &frac_fb_div,
+					   &ref_div, &post_div, pll_flags);
+	} else
+		radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
+				   &ref_div, &post_div, pll_flags);
 
 	index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
 	atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
@@ -574,21 +583,32 @@
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_framebuffer *radeon_fb;
 	struct drm_gem_object *obj;
-	struct drm_radeon_gem_object *obj_priv;
+	struct radeon_bo *rbo;
 	uint64_t fb_location;
 	uint32_t fb_format, fb_pitch_pixels, tiling_flags;
+	int r;
 
-	if (!crtc->fb)
-		return -EINVAL;
+	/* no fb bound */
+	if (!crtc->fb) {
+		DRM_DEBUG("No FB bound\n");
+		return 0;
+	}
 
 	radeon_fb = to_radeon_framebuffer(crtc->fb);
 
+	/* Pin framebuffer & get tilling informations */
 	obj = radeon_fb->obj;
-	obj_priv = obj->driver_private;
-
-	if (radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &fb_location)) {
+	rbo = obj->driver_private;
+	r = radeon_bo_reserve(rbo, false);
+	if (unlikely(r != 0))
+		return r;
+	r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
+	if (unlikely(r != 0)) {
+		radeon_bo_unreserve(rbo);
 		return -EINVAL;
 	}
+	radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
+	radeon_bo_unreserve(rbo);
 
 	switch (crtc->fb->bits_per_pixel) {
 	case 8:
@@ -618,8 +638,6 @@
 		return -EINVAL;
 	}
 
-	radeon_object_get_tiling_flags(obj->driver_private,
-				       &tiling_flags, NULL);
 	if (tiling_flags & RADEON_TILING_MACRO)
 		fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE;
 
@@ -674,7 +692,12 @@
 
 	if (old_fb && old_fb != crtc->fb) {
 		radeon_fb = to_radeon_framebuffer(old_fb);
-		radeon_gem_object_unpin(radeon_fb->obj);
+		rbo = radeon_fb->obj->driver_private;
+		r = radeon_bo_reserve(rbo, false);
+		if (unlikely(r != 0))
+			return r;
+		radeon_bo_unpin(rbo);
+		radeon_bo_unreserve(rbo);
 	}
 
 	/* Bytes per pixel may have changed */
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
new file mode 100644
index 0000000..0d63c44
--- /dev/null
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -0,0 +1,790 @@
+/*
+ * Copyright 2007-8 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ *          Alex Deucher
+ */
+#include "drmP.h"
+#include "radeon_drm.h"
+#include "radeon.h"
+
+#include "atom.h"
+#include "atom-bits.h"
+#include "drm_dp_helper.h"
+
+/* move these to drm_dp_helper.c/h */
+#define DP_LINK_CONFIGURATION_SIZE 9
+#define DP_LINK_STATUS_SIZE	   6
+#define DP_DPCD_SIZE	           8
+
+static char *voltage_names[] = {
+        "0.4V", "0.6V", "0.8V", "1.2V"
+};
+static char *pre_emph_names[] = {
+        "0dB", "3.5dB", "6dB", "9.5dB"
+};
+
+static const int dp_clocks[] = {
+	54000,  /* 1 lane, 1.62 Ghz */
+	90000,  /* 1 lane, 2.70 Ghz */
+	108000, /* 2 lane, 1.62 Ghz */
+	180000, /* 2 lane, 2.70 Ghz */
+	216000, /* 4 lane, 1.62 Ghz */
+	360000, /* 4 lane, 2.70 Ghz */
+};
+
+static const int num_dp_clocks = sizeof(dp_clocks) / sizeof(int);
+
+/* common helper functions */
+static int dp_lanes_for_mode_clock(u8 dpcd[DP_DPCD_SIZE], int mode_clock)
+{
+	int i;
+	u8 max_link_bw;
+	u8 max_lane_count;
+
+	if (!dpcd)
+		return 0;
+
+	max_link_bw = dpcd[DP_MAX_LINK_RATE];
+	max_lane_count = dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK;
+
+	switch (max_link_bw) {
+	case DP_LINK_BW_1_62:
+	default:
+		for (i = 0; i < num_dp_clocks; i++) {
+			if (i % 2)
+				continue;
+			switch (max_lane_count) {
+			case 1:
+				if (i > 1)
+					return 0;
+				break;
+			case 2:
+				if (i > 3)
+					return 0;
+				break;
+			case 4:
+			default:
+				break;
+			}
+			if (dp_clocks[i] > mode_clock) {
+				if (i < 2)
+					return 1;
+				else if (i < 4)
+					return 2;
+				else
+					return 4;
+			}
+		}
+		break;
+	case DP_LINK_BW_2_7:
+		for (i = 0; i < num_dp_clocks; i++) {
+			switch (max_lane_count) {
+			case 1:
+				if (i > 1)
+					return 0;
+				break;
+			case 2:
+				if (i > 3)
+					return 0;
+				break;
+			case 4:
+			default:
+				break;
+			}
+			if (dp_clocks[i] > mode_clock) {
+				if (i < 2)
+					return 1;
+				else if (i < 4)
+					return 2;
+				else
+					return 4;
+			}
+		}
+		break;
+	}
+
+	return 0;
+}
+
+static int dp_link_clock_for_mode_clock(u8 dpcd[DP_DPCD_SIZE], int mode_clock)
+{
+	int i;
+	u8 max_link_bw;
+	u8 max_lane_count;
+
+	if (!dpcd)
+		return 0;
+
+	max_link_bw = dpcd[DP_MAX_LINK_RATE];
+	max_lane_count = dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK;
+
+	switch (max_link_bw) {
+	case DP_LINK_BW_1_62:
+	default:
+		for (i = 0; i < num_dp_clocks; i++) {
+			if (i % 2)
+				continue;
+			switch (max_lane_count) {
+			case 1:
+				if (i > 1)
+					return 0;
+				break;
+			case 2:
+				if (i > 3)
+					return 0;
+				break;
+			case 4:
+			default:
+				break;
+			}
+			if (dp_clocks[i] > mode_clock)
+				return 162000;
+		}
+		break;
+	case DP_LINK_BW_2_7:
+		for (i = 0; i < num_dp_clocks; i++) {
+			switch (max_lane_count) {
+			case 1:
+				if (i > 1)
+					return 0;
+				break;
+			case 2:
+				if (i > 3)
+					return 0;
+				break;
+			case 4:
+			default:
+				break;
+			}
+			if (dp_clocks[i] > mode_clock)
+				return (i % 2) ? 270000 : 162000;
+		}
+	}
+
+	return 0;
+}
+
+int dp_mode_valid(u8 dpcd[DP_DPCD_SIZE], int mode_clock)
+{
+	int lanes = dp_lanes_for_mode_clock(dpcd, mode_clock);
+	int bw = dp_lanes_for_mode_clock(dpcd, mode_clock);
+
+	if ((lanes == 0) || (bw == 0))
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
+static u8 dp_link_status(u8 link_status[DP_LINK_STATUS_SIZE], int r)
+{
+	return link_status[r - DP_LANE0_1_STATUS];
+}
+
+static u8 dp_get_lane_status(u8 link_status[DP_LINK_STATUS_SIZE],
+			     int lane)
+{
+	int i = DP_LANE0_1_STATUS + (lane >> 1);
+	int s = (lane & 1) * 4;
+	u8 l = dp_link_status(link_status, i);
+	return (l >> s) & 0xf;
+}
+
+static bool dp_clock_recovery_ok(u8 link_status[DP_LINK_STATUS_SIZE],
+				 int lane_count)
+{
+	int lane;
+	u8 lane_status;
+
+	for (lane = 0; lane < lane_count; lane++) {
+		lane_status = dp_get_lane_status(link_status, lane);
+		if ((lane_status & DP_LANE_CR_DONE) == 0)
+			return false;
+	}
+	return true;
+}
+
+static bool dp_channel_eq_ok(u8 link_status[DP_LINK_STATUS_SIZE],
+			     int lane_count)
+{
+	u8 lane_align;
+	u8 lane_status;
+	int lane;
+
+	lane_align = dp_link_status(link_status,
+				    DP_LANE_ALIGN_STATUS_UPDATED);
+	if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0)
+		return false;
+	for (lane = 0; lane < lane_count; lane++) {
+		lane_status = dp_get_lane_status(link_status, lane);
+		if ((lane_status & DP_CHANNEL_EQ_BITS) != DP_CHANNEL_EQ_BITS)
+			return false;
+	}
+	return true;
+}
+
+static u8 dp_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE],
+					int lane)
+
+{
+	int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
+	int s = ((lane & 1) ?
+		 DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT :
+		 DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT);
+	u8 l = dp_link_status(link_status, i);
+
+	return ((l >> s) & 0x3) << DP_TRAIN_VOLTAGE_SWING_SHIFT;
+}
+
+static u8 dp_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE],
+					     int lane)
+{
+	int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
+	int s = ((lane & 1) ?
+		 DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT :
+		 DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT);
+	u8 l = dp_link_status(link_status, i);
+
+	return ((l >> s) & 0x3) << DP_TRAIN_PRE_EMPHASIS_SHIFT;
+}
+
+/* XXX fix me -- chip specific */
+#define DP_VOLTAGE_MAX         DP_TRAIN_VOLTAGE_SWING_1200
+static u8 dp_pre_emphasis_max(u8 voltage_swing)
+{
+	switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
+	case DP_TRAIN_VOLTAGE_SWING_400:
+		return DP_TRAIN_PRE_EMPHASIS_6;
+	case DP_TRAIN_VOLTAGE_SWING_600:
+		return DP_TRAIN_PRE_EMPHASIS_6;
+	case DP_TRAIN_VOLTAGE_SWING_800:
+		return DP_TRAIN_PRE_EMPHASIS_3_5;
+	case DP_TRAIN_VOLTAGE_SWING_1200:
+	default:
+		return DP_TRAIN_PRE_EMPHASIS_0;
+	}
+}
+
+static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE],
+				int lane_count,
+				u8 train_set[4])
+{
+	u8 v = 0;
+	u8 p = 0;
+	int lane;
+
+	for (lane = 0; lane < lane_count; lane++) {
+		u8 this_v = dp_get_adjust_request_voltage(link_status, lane);
+		u8 this_p = dp_get_adjust_request_pre_emphasis(link_status, lane);
+
+		DRM_DEBUG("requested signal parameters: lane %d voltage %s pre_emph %s\n",
+			  lane,
+			  voltage_names[this_v >> DP_TRAIN_VOLTAGE_SWING_SHIFT],
+			  pre_emph_names[this_p >> DP_TRAIN_PRE_EMPHASIS_SHIFT]);
+
+		if (this_v > v)
+			v = this_v;
+		if (this_p > p)
+			p = this_p;
+	}
+
+	if (v >= DP_VOLTAGE_MAX)
+		v = DP_VOLTAGE_MAX | DP_TRAIN_MAX_SWING_REACHED;
+
+	if (p >= dp_pre_emphasis_max(v))
+		p = dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
+
+	DRM_DEBUG("using signal parameters: voltage %s pre_emph %s\n",
+		  voltage_names[(v & DP_TRAIN_VOLTAGE_SWING_MASK) >> DP_TRAIN_VOLTAGE_SWING_SHIFT],
+		  pre_emph_names[(p & DP_TRAIN_PRE_EMPHASIS_MASK) >> DP_TRAIN_PRE_EMPHASIS_SHIFT]);
+
+	for (lane = 0; lane < 4; lane++)
+		train_set[lane] = v | p;
+}
+
+
+/* radeon aux chan functions */
+bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes,
+			   int num_bytes, u8 *read_byte,
+			   u8 read_buf_len, u8 delay)
+{
+	struct drm_device *dev = chan->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION args;
+	int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction);
+	unsigned char *base;
+
+	memset(&args, 0, sizeof(args));
+
+	base = (unsigned char *)rdev->mode_info.atom_context->scratch;
+
+	memcpy(base, req_bytes, num_bytes);
+
+	args.lpAuxRequest = 0;
+	args.lpDataOut = 16;
+	args.ucDataOutLen = 0;
+	args.ucChannelID = chan->rec.i2c_id;
+	args.ucDelay = delay / 10;
+
+	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+
+	if (args.ucReplyStatus) {
+		DRM_DEBUG("failed to get auxch %02x%02x %02x %02x 0x%02x %02x\n",
+			  req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3],
+			  chan->rec.i2c_id, args.ucReplyStatus);
+		return false;
+	}
+
+	if (args.ucDataOutLen && read_byte && read_buf_len) {
+		if (read_buf_len < args.ucDataOutLen) {
+			DRM_ERROR("Buffer to small for return answer %d %d\n",
+				  read_buf_len, args.ucDataOutLen);
+			return false;
+		}
+		{
+			int len = min(read_buf_len, args.ucDataOutLen);
+			memcpy(read_byte, base + 16, len);
+		}
+	}
+	return true;
+}
+
+bool radeon_dp_aux_native_write(struct radeon_connector *radeon_connector, uint16_t address,
+				uint8_t send_bytes, uint8_t *send)
+{
+	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
+	u8 msg[20];
+	u8 msg_len, dp_msg_len;
+	bool ret;
+
+	dp_msg_len = 4;
+	msg[0] = address;
+	msg[1] = address >> 8;
+	msg[2] = AUX_NATIVE_WRITE << 4;
+	dp_msg_len += send_bytes;
+	msg[3] = (dp_msg_len << 4) | (send_bytes - 1);
+
+	if (send_bytes > 16)
+		return false;
+
+	memcpy(&msg[4], send, send_bytes);
+	msg_len = 4 + send_bytes;
+	ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_len, NULL, 0, 0);
+	return ret;
+}
+
+bool radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, uint16_t address,
+			       uint8_t delay, uint8_t expected_bytes,
+			       uint8_t *read_p)
+{
+	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
+	u8 msg[20];
+	u8 msg_len, dp_msg_len;
+	bool ret = false;
+	msg_len = 4;
+	dp_msg_len = 4;
+	msg[0] = address;
+	msg[1] = address >> 8;
+	msg[2] = AUX_NATIVE_READ << 4;
+	msg[3] = (dp_msg_len) << 4;
+	msg[3] |= expected_bytes - 1;
+
+	ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_len, read_p, expected_bytes, delay);
+	return ret;
+}
+
+/* radeon dp functions */
+static u8 radeon_dp_encoder_service(struct radeon_device *rdev, int action, int dp_clock,
+				    uint8_t ucconfig, uint8_t lane_num)
+{
+	DP_ENCODER_SERVICE_PARAMETERS args;
+	int index = GetIndexIntoMasterTable(COMMAND, DPEncoderService);
+
+	memset(&args, 0, sizeof(args));
+	args.ucLinkClock = dp_clock / 10;
+	args.ucConfig = ucconfig;
+	args.ucAction = action;
+	args.ucLaneNum = lane_num;
+	args.ucStatus = 0;
+
+	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+	return args.ucStatus;
+}
+
+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);
+}
+
+bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector)
+{
+	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
+	u8 msg[25];
+	int ret;
+
+	ret = radeon_dp_aux_native_read(radeon_connector, DP_DPCD_REV, 0, 8, msg);
+	if (ret) {
+		memcpy(dig_connector->dpcd, msg, 8);
+		{
+			int i;
+			DRM_DEBUG("DPCD: ");
+			for (i = 0; i < 8; i++)
+				DRM_DEBUG("%02x ", msg[i]);
+			DRM_DEBUG("\n");
+		}
+		return true;
+	}
+	dig_connector->dpcd[0] = 0;
+	return false;
+}
+
+void radeon_dp_set_link_config(struct drm_connector *connector,
+			       struct drm_display_mode *mode)
+{
+	struct radeon_connector *radeon_connector;
+	struct radeon_connector_atom_dig *dig_connector;
+
+	if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
+		return;
+
+	radeon_connector = to_radeon_connector(connector);
+	if (!radeon_connector->con_priv)
+		return;
+	dig_connector = radeon_connector->con_priv;
+
+	dig_connector->dp_clock =
+		dp_link_clock_for_mode_clock(dig_connector->dpcd, mode->clock);
+	dig_connector->dp_lane_count =
+		dp_lanes_for_mode_clock(dig_connector->dpcd, mode->clock);
+}
+
+int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector,
+				struct drm_display_mode *mode)
+{
+	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
+
+	return dp_mode_valid(dig_connector->dpcd, mode->clock);
+}
+
+static bool atom_dp_get_link_status(struct radeon_connector *radeon_connector,
+				    u8 link_status[DP_LINK_STATUS_SIZE])
+{
+	int ret;
+	ret = radeon_dp_aux_native_read(radeon_connector, DP_LANE0_1_STATUS, 100,
+					DP_LINK_STATUS_SIZE, link_status);
+	if (!ret) {
+		DRM_ERROR("displayport link status failed\n");
+		return false;
+	}
+
+	DRM_DEBUG("link status %02x %02x %02x %02x %02x %02x\n",
+		  link_status[0], link_status[1], link_status[2],
+		  link_status[3], link_status[4], link_status[5]);
+	return true;
+}
+
+bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector)
+{
+	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
+	u8 link_status[DP_LINK_STATUS_SIZE];
+
+	if (!atom_dp_get_link_status(radeon_connector, link_status))
+		return false;
+	if (dp_channel_eq_ok(link_status, dig_connector->dp_lane_count))
+		return false;
+	return true;
+}
+
+static void dp_set_power(struct radeon_connector *radeon_connector, u8 power_state)
+{
+	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
+
+	if (dig_connector->dpcd[0] >= 0x11) {
+		radeon_dp_aux_native_write(radeon_connector, DP_SET_POWER, 1,
+					   &power_state);
+	}
+}
+
+static void dp_set_downspread(struct radeon_connector *radeon_connector, u8 downspread)
+{
+	radeon_dp_aux_native_write(radeon_connector, DP_DOWNSPREAD_CTRL, 1,
+				   &downspread);
+}
+
+static void dp_set_link_bw_lanes(struct radeon_connector *radeon_connector,
+				 u8 link_configuration[DP_LINK_CONFIGURATION_SIZE])
+{
+	radeon_dp_aux_native_write(radeon_connector, DP_LINK_BW_SET, 2,
+				   link_configuration);
+}
+
+static void dp_update_dpvs_emph(struct radeon_connector *radeon_connector,
+				struct drm_encoder *encoder,
+				u8 train_set[4])
+{
+	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
+	int i;
+
+	for (i = 0; i < dig_connector->dp_lane_count; i++)
+		atombios_dig_transmitter_setup(encoder,
+					       ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH,
+					       i, train_set[i]);
+
+	radeon_dp_aux_native_write(radeon_connector, DP_TRAINING_LANE0_SET,
+				   dig_connector->dp_lane_count, train_set);
+}
+
+static void dp_set_training(struct radeon_connector *radeon_connector,
+			    u8 training)
+{
+	radeon_dp_aux_native_write(radeon_connector, DP_TRAINING_PATTERN_SET,
+				   1, &training);
+}
+
+void dp_link_train(struct drm_encoder *encoder,
+		   struct drm_connector *connector)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct radeon_encoder_atom_dig *dig;
+	struct radeon_connector *radeon_connector;
+	struct radeon_connector_atom_dig *dig_connector;
+	int enc_id = 0;
+	bool clock_recovery, channel_eq;
+	u8 link_status[DP_LINK_STATUS_SIZE];
+	u8 link_configuration[DP_LINK_CONFIGURATION_SIZE];
+	u8 tries, voltage;
+	u8 train_set[4];
+	int i;
+
+	if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
+		return;
+
+	if (!radeon_encoder->enc_priv)
+		return;
+	dig = radeon_encoder->enc_priv;
+
+	radeon_connector = to_radeon_connector(connector);
+	if (!radeon_connector->con_priv)
+		return;
+	dig_connector = radeon_connector->con_priv;
+
+	if (ASIC_IS_DCE32(rdev)) {
+		if (dig->dig_block)
+			enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER;
+		else
+			enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER;
+		if (dig_connector->linkb)
+			enc_id |= ATOM_DP_CONFIG_LINK_B;
+		else
+			enc_id |= ATOM_DP_CONFIG_LINK_A;
+	} else {
+		if (dig_connector->linkb)
+			enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER | ATOM_DP_CONFIG_LINK_B;
+		else
+			enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER | ATOM_DP_CONFIG_LINK_A;
+	}
+
+	memset(link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);
+	if (dig_connector->dp_clock == 270000)
+		link_configuration[0] = DP_LINK_BW_2_7;
+	else
+		link_configuration[0] = DP_LINK_BW_1_62;
+	link_configuration[1] = dig_connector->dp_lane_count;
+	if (dig_connector->dpcd[0] >= 0x11)
+		link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
+
+	/* power up the sink */
+	dp_set_power(radeon_connector, DP_SET_POWER_D0);
+	/* disable the training pattern on the sink */
+	dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE);
+	/* set link bw and lanes on the sink */
+	dp_set_link_bw_lanes(radeon_connector, link_configuration);
+	/* disable downspread on the sink */
+	dp_set_downspread(radeon_connector, 0);
+	/* start training on the source */
+	radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_START,
+				  dig_connector->dp_clock, enc_id, 0);
+	/* set training pattern 1 on the source */
+	radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL,
+				  dig_connector->dp_clock, enc_id, 0);
+
+	/* set initial vs/emph */
+	memset(train_set, 0, 4);
+	udelay(400);
+	/* set training pattern 1 on the sink */
+	dp_set_training(radeon_connector, DP_TRAINING_PATTERN_1);
+
+	dp_update_dpvs_emph(radeon_connector, encoder, train_set);
+
+	/* clock recovery loop */
+	clock_recovery = false;
+	tries = 0;
+	voltage = 0xff;
+	for (;;) {
+		udelay(100);
+		if (!atom_dp_get_link_status(radeon_connector, link_status))
+			break;
+
+		if (dp_clock_recovery_ok(link_status, dig_connector->dp_lane_count)) {
+			clock_recovery = true;
+			break;
+		}
+
+		for (i = 0; i < dig_connector->dp_lane_count; i++) {
+			if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
+				break;
+		}
+		if (i == dig_connector->dp_lane_count) {
+			DRM_ERROR("clock recovery reached max voltage\n");
+			break;
+		}
+
+		if ((train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
+			++tries;
+			if (tries == 5) {
+				DRM_ERROR("clock recovery tried 5 times\n");
+				break;
+			}
+		} else
+			tries = 0;
+
+		voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
+
+		/* Compute new train_set as requested by sink */
+		dp_get_adjust_train(link_status, dig_connector->dp_lane_count, train_set);
+		dp_update_dpvs_emph(radeon_connector, encoder, train_set);
+	}
+	if (!clock_recovery)
+		DRM_ERROR("clock recovery failed\n");
+	else
+		DRM_DEBUG("clock recovery at voltage %d pre-emphasis %d\n",
+			  train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK,
+			  (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) >>
+			  DP_TRAIN_PRE_EMPHASIS_SHIFT);
+
+
+	/* set training pattern 2 on the sink */
+	dp_set_training(radeon_connector, DP_TRAINING_PATTERN_2);
+	/* set training pattern 2 on the source */
+	radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL,
+				  dig_connector->dp_clock, enc_id, 1);
+
+	/* channel equalization loop */
+	tries = 0;
+	channel_eq = false;
+	for (;;) {
+		udelay(400);
+		if (!atom_dp_get_link_status(radeon_connector, link_status))
+			break;
+
+		if (dp_channel_eq_ok(link_status, dig_connector->dp_lane_count)) {
+			channel_eq = true;
+			break;
+		}
+
+		/* Try 5 times */
+		if (tries > 5) {
+			DRM_ERROR("channel eq failed: 5 tries\n");
+			break;
+		}
+
+		/* Compute new train_set as requested by sink */
+		dp_get_adjust_train(link_status, dig_connector->dp_lane_count, train_set);
+		dp_update_dpvs_emph(radeon_connector, encoder, train_set);
+
+		tries++;
+	}
+
+	if (!channel_eq)
+		DRM_ERROR("channel eq failed\n");
+	else
+		DRM_DEBUG("channel eq at voltage %d pre-emphasis %d\n",
+			  train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK,
+			  (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK)
+			  >> DP_TRAIN_PRE_EMPHASIS_SHIFT);
+
+	/* disable the training pattern on the sink */
+	dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE);
+
+	radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE,
+				  dig_connector->dp_clock, enc_id, 0);
+}
+
+int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
+			 uint8_t write_byte, uint8_t *read_byte)
+{
+	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+	struct radeon_i2c_chan *auxch = (struct radeon_i2c_chan *)adapter;
+	int ret = 0;
+	uint16_t address = algo_data->address;
+	uint8_t msg[5];
+	uint8_t reply[2];
+	int msg_len, dp_msg_len;
+	int reply_bytes;
+
+	/* Set up the command byte */
+	if (mode & MODE_I2C_READ)
+		msg[2] = AUX_I2C_READ << 4;
+	else
+		msg[2] = AUX_I2C_WRITE << 4;
+
+	if (!(mode & MODE_I2C_STOP))
+		msg[2] |= AUX_I2C_MOT << 4;
+
+	msg[0] = address;
+	msg[1] = address >> 8;
+
+	reply_bytes = 1;
+
+	msg_len = 4;
+	dp_msg_len = 3;
+	switch (mode) {
+	case MODE_I2C_WRITE:
+		msg[4] = write_byte;
+		msg_len++;
+		dp_msg_len += 2;
+		break;
+	case MODE_I2C_READ:
+		dp_msg_len += 1;
+		break;
+	default:
+		break;
+	}
+
+	msg[3] = (dp_msg_len) << 4;
+	ret = radeon_process_aux_ch(auxch, msg, msg_len, reply, reply_bytes, 0);
+
+	if (ret) {
+		if (read_byte)
+			*read_byte = reply[0];
+		return reply_bytes;
+	}
+	return -EREMOTEIO;
+}
+
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index c9e93ea..824cc64 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -65,6 +65,95 @@
  * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
  */
 
+/* hpd for digital panel detect/disconnect */
+bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
+{
+	bool connected = false;
+
+	switch (hpd) {
+	case RADEON_HPD_1:
+		if (RREG32(RADEON_FP_GEN_CNTL) & RADEON_FP_DETECT_SENSE)
+			connected = true;
+		break;
+	case RADEON_HPD_2:
+		if (RREG32(RADEON_FP2_GEN_CNTL) & RADEON_FP2_DETECT_SENSE)
+			connected = true;
+		break;
+	default:
+		break;
+	}
+	return connected;
+}
+
+void r100_hpd_set_polarity(struct radeon_device *rdev,
+			   enum radeon_hpd_id hpd)
+{
+	u32 tmp;
+	bool connected = r100_hpd_sense(rdev, hpd);
+
+	switch (hpd) {
+	case RADEON_HPD_1:
+		tmp = RREG32(RADEON_FP_GEN_CNTL);
+		if (connected)
+			tmp &= ~RADEON_FP_DETECT_INT_POL;
+		else
+			tmp |= RADEON_FP_DETECT_INT_POL;
+		WREG32(RADEON_FP_GEN_CNTL, tmp);
+		break;
+	case RADEON_HPD_2:
+		tmp = RREG32(RADEON_FP2_GEN_CNTL);
+		if (connected)
+			tmp &= ~RADEON_FP2_DETECT_INT_POL;
+		else
+			tmp |= RADEON_FP2_DETECT_INT_POL;
+		WREG32(RADEON_FP2_GEN_CNTL, tmp);
+		break;
+	default:
+		break;
+	}
+}
+
+void r100_hpd_init(struct radeon_device *rdev)
+{
+	struct drm_device *dev = rdev->ddev;
+	struct drm_connector *connector;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+		switch (radeon_connector->hpd.hpd) {
+		case RADEON_HPD_1:
+			rdev->irq.hpd[0] = true;
+			break;
+		case RADEON_HPD_2:
+			rdev->irq.hpd[1] = true;
+			break;
+		default:
+			break;
+		}
+	}
+	r100_irq_set(rdev);
+}
+
+void r100_hpd_fini(struct radeon_device *rdev)
+{
+	struct drm_device *dev = rdev->ddev;
+	struct drm_connector *connector;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+		switch (radeon_connector->hpd.hpd) {
+		case RADEON_HPD_1:
+			rdev->irq.hpd[0] = false;
+			break;
+		case RADEON_HPD_2:
+			rdev->irq.hpd[1] = false;
+			break;
+		default:
+			break;
+		}
+	}
+}
+
 /*
  * PCI GART
  */
@@ -94,6 +183,15 @@
 	return radeon_gart_table_ram_alloc(rdev);
 }
 
+/* required on r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */
+void r100_enable_bm(struct radeon_device *rdev)
+{
+	uint32_t tmp;
+	/* Enable bus mastering */
+	tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
+	WREG32(RADEON_BUS_CNTL, tmp);
+}
+
 int r100_pci_gart_enable(struct radeon_device *rdev)
 {
 	uint32_t tmp;
@@ -105,9 +203,6 @@
 	WREG32(RADEON_AIC_LO_ADDR, rdev->mc.gtt_location);
 	tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
 	WREG32(RADEON_AIC_HI_ADDR, tmp);
-	/* Enable bus mastering */
-	tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
-	WREG32(RADEON_BUS_CNTL, tmp);
 	/* set PCI GART page-table base address */
 	WREG32(RADEON_AIC_PT_BASE, rdev->gart.table_addr);
 	tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN;
@@ -157,6 +252,12 @@
 	if (rdev->irq.crtc_vblank_int[1]) {
 		tmp |= RADEON_CRTC2_VBLANK_MASK;
 	}
+	if (rdev->irq.hpd[0]) {
+		tmp |= RADEON_FP_DETECT_MASK;
+	}
+	if (rdev->irq.hpd[1]) {
+		tmp |= RADEON_FP2_DETECT_MASK;
+	}
 	WREG32(RADEON_GEN_INT_CNTL, tmp);
 	return 0;
 }
@@ -175,8 +276,9 @@
 static inline uint32_t r100_irq_ack(struct radeon_device *rdev)
 {
 	uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS);
-	uint32_t irq_mask = RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT |
-		RADEON_CRTC2_VBLANK_STAT;
+	uint32_t irq_mask = RADEON_SW_INT_TEST |
+		RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT |
+		RADEON_FP_DETECT_STAT | RADEON_FP2_DETECT_STAT;
 
 	if (irqs) {
 		WREG32(RADEON_GEN_INT_STATUS, irqs);
@@ -187,6 +289,7 @@
 int r100_irq_process(struct radeon_device *rdev)
 {
 	uint32_t status, msi_rearm;
+	bool queue_hotplug = false;
 
 	status = r100_irq_ack(rdev);
 	if (!status) {
@@ -207,8 +310,18 @@
 		if (status & RADEON_CRTC2_VBLANK_STAT) {
 			drm_handle_vblank(rdev->ddev, 1);
 		}
+		if (status & RADEON_FP_DETECT_STAT) {
+			queue_hotplug = true;
+			DRM_DEBUG("HPD1\n");
+		}
+		if (status & RADEON_FP2_DETECT_STAT) {
+			queue_hotplug = true;
+			DRM_DEBUG("HPD2\n");
+		}
 		status = r100_irq_ack(rdev);
 	}
+	if (queue_hotplug)
+		queue_work(rdev->wq, &rdev->hotplug_work);
 	if (rdev->msi_enabled) {
 		switch (rdev->family) {
 		case CHIP_RS400:
@@ -255,24 +368,27 @@
 	int r;
 
 	if (rdev->wb.wb_obj == NULL) {
-		r = radeon_object_create(rdev, NULL, RADEON_GPU_PAGE_SIZE,
-					 true,
-					 RADEON_GEM_DOMAIN_GTT,
-					 false, &rdev->wb.wb_obj);
+		r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true,
+					RADEON_GEM_DOMAIN_GTT,
+					&rdev->wb.wb_obj);
 		if (r) {
-			DRM_ERROR("radeon: failed to create WB buffer (%d).\n", r);
+			dev_err(rdev->dev, "(%d) create WB buffer failed\n", r);
 			return r;
 		}
-		r = radeon_object_pin(rdev->wb.wb_obj,
-				      RADEON_GEM_DOMAIN_GTT,
-				      &rdev->wb.gpu_addr);
+		r = radeon_bo_reserve(rdev->wb.wb_obj, false);
+		if (unlikely(r != 0))
+			return r;
+		r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT,
+					&rdev->wb.gpu_addr);
 		if (r) {
-			DRM_ERROR("radeon: failed to pin WB buffer (%d).\n", r);
+			dev_err(rdev->dev, "(%d) pin WB buffer failed\n", r);
+			radeon_bo_unreserve(rdev->wb.wb_obj);
 			return r;
 		}
-		r = radeon_object_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
+		r = radeon_bo_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
+		radeon_bo_unreserve(rdev->wb.wb_obj);
 		if (r) {
-			DRM_ERROR("radeon: failed to map WB buffer (%d).\n", r);
+			dev_err(rdev->dev, "(%d) map WB buffer failed\n", r);
 			return r;
 		}
 	}
@@ -290,11 +406,19 @@
 
 void r100_wb_fini(struct radeon_device *rdev)
 {
+	int r;
+
 	r100_wb_disable(rdev);
 	if (rdev->wb.wb_obj) {
-		radeon_object_kunmap(rdev->wb.wb_obj);
-		radeon_object_unpin(rdev->wb.wb_obj);
-		radeon_object_unref(&rdev->wb.wb_obj);
+		r = radeon_bo_reserve(rdev->wb.wb_obj, false);
+		if (unlikely(r != 0)) {
+			dev_err(rdev->dev, "(%d) can't finish WB\n", r);
+			return;
+		}
+		radeon_bo_kunmap(rdev->wb.wb_obj);
+		radeon_bo_unpin(rdev->wb.wb_obj);
+		radeon_bo_unreserve(rdev->wb.wb_obj);
+		radeon_bo_unref(&rdev->wb.wb_obj);
 		rdev->wb.wb = NULL;
 		rdev->wb.wb_obj = NULL;
 	}
@@ -1288,17 +1412,17 @@
 
 int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
 					 struct radeon_cs_packet *pkt,
-					 struct radeon_object *robj)
+					 struct radeon_bo *robj)
 {
 	unsigned idx;
 	u32 value;
 	idx = pkt->idx + 1;
 	value = radeon_get_ib_value(p, idx + 2);
-	if ((value + 1) > radeon_object_size(robj)) {
+	if ((value + 1) > radeon_bo_size(robj)) {
 		DRM_ERROR("[drm] Buffer too small for PACKET3 INDX_BUFFER "
 			  "(need %u have %lu) !\n",
 			  value + 1,
-			  radeon_object_size(robj));
+			  radeon_bo_size(robj));
 		return -EINVAL;
 	}
 	return 0;
@@ -1583,6 +1707,14 @@
 	r100_hdp_reset(rdev);
 }
 
+void r100_hdp_flush(struct radeon_device *rdev)
+{
+	u32 tmp;
+	tmp = RREG32(RADEON_HOST_PATH_CNTL);
+	tmp |= RADEON_HDP_READ_BUFFER_INVALIDATE;
+	WREG32(RADEON_HOST_PATH_CNTL, tmp);
+}
+
 void r100_hdp_reset(struct radeon_device *rdev)
 {
 	uint32_t tmp;
@@ -1650,6 +1782,17 @@
 	return 0;
 }
 
+void r100_set_common_regs(struct radeon_device *rdev)
+{
+	/* set these so they don't interfere with anything */
+	WREG32(RADEON_OV0_SCALE_CNTL, 0);
+	WREG32(RADEON_SUBPIC_CNTL, 0);
+	WREG32(RADEON_VIPH_CONTROL, 0);
+	WREG32(RADEON_I2C_CNTL_1, 0);
+	WREG32(RADEON_DVI_I2C_CNTL_1, 0);
+	WREG32(RADEON_CAP0_TRIG_CNTL, 0);
+	WREG32(RADEON_CAP1_TRIG_CNTL, 0);
+}
 
 /*
  * VRAM info
@@ -2594,7 +2737,7 @@
 			      struct r100_cs_track *track, unsigned idx)
 {
 	unsigned face, w, h;
-	struct radeon_object *cube_robj;
+	struct radeon_bo *cube_robj;
 	unsigned long size;
 
 	for (face = 0; face < 5; face++) {
@@ -2607,9 +2750,9 @@
 
 		size += track->textures[idx].cube_info[face].offset;
 
-		if (size > radeon_object_size(cube_robj)) {
+		if (size > radeon_bo_size(cube_robj)) {
 			DRM_ERROR("Cube texture offset greater than object size %lu %lu\n",
-				  size, radeon_object_size(cube_robj));
+				  size, radeon_bo_size(cube_robj));
 			r100_cs_track_texture_print(&track->textures[idx]);
 			return -1;
 		}
@@ -2620,7 +2763,7 @@
 static int r100_cs_track_texture_check(struct radeon_device *rdev,
 				       struct r100_cs_track *track)
 {
-	struct radeon_object *robj;
+	struct radeon_bo *robj;
 	unsigned long size;
 	unsigned u, i, w, h;
 	int ret;
@@ -2676,9 +2819,9 @@
 				  "%u\n", track->textures[u].tex_coord_type, u);
 			return -EINVAL;
 		}
-		if (size > radeon_object_size(robj)) {
+		if (size > radeon_bo_size(robj)) {
 			DRM_ERROR("Texture of unit %u needs %lu bytes but is "
-				  "%lu\n", u, size, radeon_object_size(robj));
+				  "%lu\n", u, size, radeon_bo_size(robj));
 			r100_cs_track_texture_print(&track->textures[u]);
 			return -EINVAL;
 		}
@@ -2700,10 +2843,10 @@
 		}
 		size = track->cb[i].pitch * track->cb[i].cpp * track->maxy;
 		size += track->cb[i].offset;
-		if (size > radeon_object_size(track->cb[i].robj)) {
+		if (size > radeon_bo_size(track->cb[i].robj)) {
 			DRM_ERROR("[drm] Buffer too small for color buffer %d "
 				  "(need %lu have %lu) !\n", i, size,
-				  radeon_object_size(track->cb[i].robj));
+				  radeon_bo_size(track->cb[i].robj));
 			DRM_ERROR("[drm] color buffer %d (%u %u %u %u)\n",
 				  i, track->cb[i].pitch, track->cb[i].cpp,
 				  track->cb[i].offset, track->maxy);
@@ -2717,10 +2860,10 @@
 		}
 		size = track->zb.pitch * track->zb.cpp * track->maxy;
 		size += track->zb.offset;
-		if (size > radeon_object_size(track->zb.robj)) {
+		if (size > radeon_bo_size(track->zb.robj)) {
 			DRM_ERROR("[drm] Buffer too small for z buffer "
 				  "(need %lu have %lu) !\n", size,
-				  radeon_object_size(track->zb.robj));
+				  radeon_bo_size(track->zb.robj));
 			DRM_ERROR("[drm] zbuffer (%u %u %u %u)\n",
 				  track->zb.pitch, track->zb.cpp,
 				  track->zb.offset, track->maxy);
@@ -2738,11 +2881,12 @@
 					  "bound\n", prim_walk, i);
 				return -EINVAL;
 			}
-			if (size > radeon_object_size(track->arrays[i].robj)) {
-				DRM_ERROR("(PW %u) Vertex array %u need %lu dwords "
-					   "have %lu dwords\n", prim_walk, i,
-					   size >> 2,
-					   radeon_object_size(track->arrays[i].robj) >> 2);
+			if (size > radeon_bo_size(track->arrays[i].robj)) {
+				dev_err(rdev->dev, "(PW %u) Vertex array %u "
+					"need %lu dwords have %lu dwords\n",
+					prim_walk, i, size >> 2,
+					radeon_bo_size(track->arrays[i].robj)
+					>> 2);
 				DRM_ERROR("Max indices %u\n", track->max_indx);
 				return -EINVAL;
 			}
@@ -2756,10 +2900,12 @@
 					  "bound\n", prim_walk, i);
 				return -EINVAL;
 			}
-			if (size > radeon_object_size(track->arrays[i].robj)) {
-				DRM_ERROR("(PW %u) Vertex array %u need %lu dwords "
-					   "have %lu dwords\n", prim_walk, i, size >> 2,
-					   radeon_object_size(track->arrays[i].robj) >> 2);
+			if (size > radeon_bo_size(track->arrays[i].robj)) {
+				dev_err(rdev->dev, "(PW %u) Vertex array %u "
+					"need %lu dwords have %lu dwords\n",
+					prim_walk, i, size >> 2,
+					radeon_bo_size(track->arrays[i].robj)
+					>> 2);
 				return -EINVAL;
 			}
 		}
@@ -3101,6 +3247,9 @@
 {
 	int r;
 
+	/* set common regs */
+	r100_set_common_regs(rdev);
+	/* program mc */
 	r100_mc_program(rdev);
 	/* Resume clock */
 	r100_clock_startup(rdev);
@@ -3108,13 +3257,13 @@
 	r100_gpu_init(rdev);
 	/* Initialize GART (initialize after TTM so we can allocate
 	 * memory through TTM but finalize after TTM) */
+	r100_enable_bm(rdev);
 	if (rdev->flags & RADEON_IS_PCI) {
 		r = r100_pci_gart_enable(rdev);
 		if (r)
 			return r;
 	}
 	/* Enable IRQ */
-	rdev->irq.sw_int = true;
 	r100_irq_set(rdev);
 	/* 1M ring buffer */
 	r = r100_cp_init(rdev, 1024 * 1024);
@@ -3150,6 +3299,8 @@
 	radeon_combios_asic_init(rdev->ddev);
 	/* Resume clock after posting */
 	r100_clock_startup(rdev);
+	/* Initialize surface registers */
+	radeon_surface_init(rdev);
 	return r100_startup(rdev);
 }
 
@@ -3174,7 +3325,7 @@
 		r100_pci_gart_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	radeon_fence_driver_fini(rdev);
-	radeon_object_fini(rdev);
+	radeon_bo_fini(rdev);
 	radeon_atombios_fini(rdev);
 	kfree(rdev->bios);
 	rdev->bios = NULL;
@@ -3242,10 +3393,8 @@
 			RREG32(R_0007C0_CP_STAT));
 	}
 	/* check if cards are posted or not */
-	if (!radeon_card_posted(rdev) && rdev->bios) {
-		DRM_INFO("GPU not posted. posting now...\n");
-		radeon_combios_asic_init(rdev->ddev);
-	}
+	if (radeon_boot_test_post_card(rdev) == false)
+		return -EINVAL;
 	/* Set asic errata */
 	r100_errata(rdev);
 	/* Initialize clocks */
@@ -3264,7 +3413,7 @@
 	if (r)
 		return r;
 	/* Memory manager */
-	r = radeon_object_init(rdev);
+	r = radeon_bo_init(rdev);
 	if (r)
 		return r;
 	if (rdev->flags & RADEON_IS_PCI) {
diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h
index 0daf0d7..ca50903 100644
--- a/drivers/gpu/drm/radeon/r100_track.h
+++ b/drivers/gpu/drm/radeon/r100_track.h
@@ -10,26 +10,26 @@
  * CS functions
  */
 struct r100_cs_track_cb {
-	struct radeon_object	*robj;
+	struct radeon_bo	*robj;
 	unsigned		pitch;
 	unsigned		cpp;
 	unsigned		offset;
 };
 
 struct r100_cs_track_array {
-	struct radeon_object	*robj;
+	struct radeon_bo	*robj;
 	unsigned		esize;
 };
 
 struct r100_cs_cube_info {
-	struct radeon_object	*robj;
-	unsigned                offset;
+	struct radeon_bo	*robj;
+	unsigned		offset;
 	unsigned		width;
 	unsigned		height;
 };
 
 struct r100_cs_track_texture {
-	struct radeon_object	*robj;
+	struct radeon_bo	*robj;
 	struct r100_cs_cube_info cube_info[5]; /* info for 5 non-primary faces */
 	unsigned		pitch;
 	unsigned		width;
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 2f43ee8..83378c3 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -137,14 +137,19 @@
 
 void rv370_pcie_gart_disable(struct radeon_device *rdev)
 {
-	uint32_t tmp;
+	u32 tmp;
+	int r;
 
 	tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL);
 	tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD;
 	WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN);
 	if (rdev->gart.table.vram.robj) {
-		radeon_object_kunmap(rdev->gart.table.vram.robj);
-		radeon_object_unpin(rdev->gart.table.vram.robj);
+		r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
+		if (likely(r == 0)) {
+			radeon_bo_kunmap(rdev->gart.table.vram.robj);
+			radeon_bo_unpin(rdev->gart.table.vram.robj);
+			radeon_bo_unreserve(rdev->gart.table.vram.robj);
+		}
 	}
 }
 
@@ -1181,6 +1186,9 @@
 {
 	int r;
 
+	/* set common regs */
+	r100_set_common_regs(rdev);
+	/* program mc */
 	r300_mc_program(rdev);
 	/* Resume clock */
 	r300_clock_startup(rdev);
@@ -1193,13 +1201,18 @@
 		if (r)
 			return r;
 	}
+
+	if (rdev->family == CHIP_R300 ||
+	    rdev->family == CHIP_R350 ||
+	    rdev->family == CHIP_RV350)
+		r100_enable_bm(rdev);
+
 	if (rdev->flags & RADEON_IS_PCI) {
 		r = r100_pci_gart_enable(rdev);
 		if (r)
 			return r;
 	}
 	/* Enable IRQ */
-	rdev->irq.sw_int = true;
 	r100_irq_set(rdev);
 	/* 1M ring buffer */
 	r = r100_cp_init(rdev, 1024 * 1024);
@@ -1237,6 +1250,8 @@
 	radeon_combios_asic_init(rdev->ddev);
 	/* Resume clock after posting */
 	r300_clock_startup(rdev);
+	/* Initialize surface registers */
+	radeon_surface_init(rdev);
 	return r300_startup(rdev);
 }
 
@@ -1265,7 +1280,7 @@
 		r100_pci_gart_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	radeon_fence_driver_fini(rdev);
-	radeon_object_fini(rdev);
+	radeon_bo_fini(rdev);
 	radeon_atombios_fini(rdev);
 	kfree(rdev->bios);
 	rdev->bios = NULL;
@@ -1303,10 +1318,8 @@
 			RREG32(R_0007C0_CP_STAT));
 	}
 	/* check if cards are posted or not */
-	if (!radeon_card_posted(rdev) && rdev->bios) {
-		DRM_INFO("GPU not posted. posting now...\n");
-		radeon_combios_asic_init(rdev->ddev);
-	}
+	if (radeon_boot_test_post_card(rdev) == false)
+		return -EINVAL;
 	/* Set asic errata */
 	r300_errata(rdev);
 	/* Initialize clocks */
@@ -1325,7 +1338,7 @@
 	if (r)
 		return r;
 	/* Memory manager */
-	r = radeon_object_init(rdev);
+	r = radeon_bo_init(rdev);
 	if (r)
 		return r;
 	if (rdev->flags & RADEON_IS_PCIE) {
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c
index 1cefdbc..c05a727 100644
--- a/drivers/gpu/drm/radeon/r420.c
+++ b/drivers/gpu/drm/radeon/r420.c
@@ -169,6 +169,9 @@
 {
 	int r;
 
+	/* set common regs */
+	r100_set_common_regs(rdev);
+	/* program mc */
 	r300_mc_program(rdev);
 	/* Resume clock */
 	r420_clock_resume(rdev);
@@ -186,7 +189,6 @@
 	}
 	r420_pipes_init(rdev);
 	/* Enable IRQ */
-	rdev->irq.sw_int = true;
 	r100_irq_set(rdev);
 	/* 1M ring buffer */
 	r = r100_cp_init(rdev, 1024 * 1024);
@@ -229,7 +231,8 @@
 	}
 	/* Resume clock after posting */
 	r420_clock_resume(rdev);
-
+	/* Initialize surface registers */
+	radeon_surface_init(rdev);
 	return r420_startup(rdev);
 }
 
@@ -258,7 +261,7 @@
 	radeon_agp_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	radeon_fence_driver_fini(rdev);
-	radeon_object_fini(rdev);
+	radeon_bo_fini(rdev);
 	if (rdev->is_atom_bios) {
 		radeon_atombios_fini(rdev);
 	} else {
@@ -301,14 +304,9 @@
 			RREG32(R_0007C0_CP_STAT));
 	}
 	/* check if cards are posted or not */
-	if (!radeon_card_posted(rdev) && rdev->bios) {
-		DRM_INFO("GPU not posted. posting now...\n");
-		if (rdev->is_atom_bios) {
-			atom_asic_init(rdev->mode_info.atom_context);
-		} else {
-			radeon_combios_asic_init(rdev->ddev);
-		}
-	}
+	if (radeon_boot_test_post_card(rdev) == false)
+		return -EINVAL;
+
 	/* Initialize clocks */
 	radeon_get_clock_info(rdev->ddev);
 	/* Initialize power management */
@@ -331,10 +329,13 @@
 		return r;
 	}
 	/* Memory manager */
-	r = radeon_object_init(rdev);
+	r = radeon_bo_init(rdev);
 	if (r) {
 		return r;
 	}
+	if (rdev->family == CHIP_R420)
+		r100_enable_bm(rdev);
+
 	if (rdev->flags & RADEON_IS_PCIE) {
 		r = rv370_pcie_gart_init(rdev);
 		if (r)
diff --git a/drivers/gpu/drm/radeon/r500_reg.h b/drivers/gpu/drm/radeon/r500_reg.h
index 7baa739..74ad89b 100644
--- a/drivers/gpu/drm/radeon/r500_reg.h
+++ b/drivers/gpu/drm/radeon/r500_reg.h
@@ -716,6 +716,8 @@
 
 #define AVIVO_DVOA_BIT_DEPTH_CONTROL			0x7988
 
+#define AVIVO_DC_GPIO_HPD_A                 0x7e94
+
 #define AVIVO_GPIO_0                        0x7e30
 #define AVIVO_GPIO_1                        0x7e40
 #define AVIVO_GPIO_2                        0x7e50
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c
index f743518..0f3843b 100644
--- a/drivers/gpu/drm/radeon/r520.c
+++ b/drivers/gpu/drm/radeon/r520.c
@@ -185,7 +185,6 @@
 			return r;
 	}
 	/* Enable IRQ */
-	rdev->irq.sw_int = true;
 	rs600_irq_set(rdev);
 	/* 1M ring buffer */
 	r = r100_cp_init(rdev, 1024 * 1024);
@@ -221,6 +220,8 @@
 	atom_asic_init(rdev->mode_info.atom_context);
 	/* Resume clock after posting */
 	rv515_clock_startup(rdev);
+	/* Initialize surface registers */
+	radeon_surface_init(rdev);
 	return r520_startup(rdev);
 }
 
@@ -254,6 +255,9 @@
 			RREG32(R_0007C0_CP_STAT));
 	}
 	/* check if cards are posted or not */
+	if (radeon_boot_test_post_card(rdev) == false)
+		return -EINVAL;
+
 	if (!radeon_card_posted(rdev) && rdev->bios) {
 		DRM_INFO("GPU not posted. posting now...\n");
 		atom_asic_init(rdev->mode_info.atom_context);
@@ -277,7 +281,7 @@
 	if (r)
 		return r;
 	/* Memory manager */
-	r = radeon_object_init(rdev);
+	r = radeon_bo_init(rdev);
 	if (r)
 		return r;
 	r = rv370_pcie_gart_init(rdev);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 278f646..36656bd 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -38,8 +38,10 @@
 
 #define PFP_UCODE_SIZE 576
 #define PM4_UCODE_SIZE 1792
+#define RLC_UCODE_SIZE 768
 #define R700_PFP_UCODE_SIZE 848
 #define R700_PM4_UCODE_SIZE 1360
+#define R700_RLC_UCODE_SIZE 1024
 
 /* Firmware Names */
 MODULE_FIRMWARE("radeon/R600_pfp.bin");
@@ -62,6 +64,8 @@
 MODULE_FIRMWARE("radeon/RV730_me.bin");
 MODULE_FIRMWARE("radeon/RV710_pfp.bin");
 MODULE_FIRMWARE("radeon/RV710_me.bin");
+MODULE_FIRMWARE("radeon/R600_rlc.bin");
+MODULE_FIRMWARE("radeon/R700_rlc.bin");
 
 int r600_debugfs_mc_info_init(struct radeon_device *rdev);
 
@@ -70,6 +74,281 @@
 void r600_gpu_init(struct radeon_device *rdev);
 void r600_fini(struct radeon_device *rdev);
 
+/* hpd for digital panel detect/disconnect */
+bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
+{
+	bool connected = false;
+
+	if (ASIC_IS_DCE3(rdev)) {
+		switch (hpd) {
+		case RADEON_HPD_1:
+			if (RREG32(DC_HPD1_INT_STATUS) & DC_HPDx_SENSE)
+				connected = true;
+			break;
+		case RADEON_HPD_2:
+			if (RREG32(DC_HPD2_INT_STATUS) & DC_HPDx_SENSE)
+				connected = true;
+			break;
+		case RADEON_HPD_3:
+			if (RREG32(DC_HPD3_INT_STATUS) & DC_HPDx_SENSE)
+				connected = true;
+			break;
+		case RADEON_HPD_4:
+			if (RREG32(DC_HPD4_INT_STATUS) & DC_HPDx_SENSE)
+				connected = true;
+			break;
+			/* DCE 3.2 */
+		case RADEON_HPD_5:
+			if (RREG32(DC_HPD5_INT_STATUS) & DC_HPDx_SENSE)
+				connected = true;
+			break;
+		case RADEON_HPD_6:
+			if (RREG32(DC_HPD6_INT_STATUS) & DC_HPDx_SENSE)
+				connected = true;
+			break;
+		default:
+			break;
+		}
+	} else {
+		switch (hpd) {
+		case RADEON_HPD_1:
+			if (RREG32(DC_HOT_PLUG_DETECT1_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE)
+				connected = true;
+			break;
+		case RADEON_HPD_2:
+			if (RREG32(DC_HOT_PLUG_DETECT2_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE)
+				connected = true;
+			break;
+		case RADEON_HPD_3:
+			if (RREG32(DC_HOT_PLUG_DETECT3_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE)
+				connected = true;
+			break;
+		default:
+			break;
+		}
+	}
+	return connected;
+}
+
+void r600_hpd_set_polarity(struct radeon_device *rdev,
+			   enum radeon_hpd_id hpd)
+{
+	u32 tmp;
+	bool connected = r600_hpd_sense(rdev, hpd);
+
+	if (ASIC_IS_DCE3(rdev)) {
+		switch (hpd) {
+		case RADEON_HPD_1:
+			tmp = RREG32(DC_HPD1_INT_CONTROL);
+			if (connected)
+				tmp &= ~DC_HPDx_INT_POLARITY;
+			else
+				tmp |= DC_HPDx_INT_POLARITY;
+			WREG32(DC_HPD1_INT_CONTROL, tmp);
+			break;
+		case RADEON_HPD_2:
+			tmp = RREG32(DC_HPD2_INT_CONTROL);
+			if (connected)
+				tmp &= ~DC_HPDx_INT_POLARITY;
+			else
+				tmp |= DC_HPDx_INT_POLARITY;
+			WREG32(DC_HPD2_INT_CONTROL, tmp);
+			break;
+		case RADEON_HPD_3:
+			tmp = RREG32(DC_HPD3_INT_CONTROL);
+			if (connected)
+				tmp &= ~DC_HPDx_INT_POLARITY;
+			else
+				tmp |= DC_HPDx_INT_POLARITY;
+			WREG32(DC_HPD3_INT_CONTROL, tmp);
+			break;
+		case RADEON_HPD_4:
+			tmp = RREG32(DC_HPD4_INT_CONTROL);
+			if (connected)
+				tmp &= ~DC_HPDx_INT_POLARITY;
+			else
+				tmp |= DC_HPDx_INT_POLARITY;
+			WREG32(DC_HPD4_INT_CONTROL, tmp);
+			break;
+		case RADEON_HPD_5:
+			tmp = RREG32(DC_HPD5_INT_CONTROL);
+			if (connected)
+				tmp &= ~DC_HPDx_INT_POLARITY;
+			else
+				tmp |= DC_HPDx_INT_POLARITY;
+			WREG32(DC_HPD5_INT_CONTROL, tmp);
+			break;
+			/* DCE 3.2 */
+		case RADEON_HPD_6:
+			tmp = RREG32(DC_HPD6_INT_CONTROL);
+			if (connected)
+				tmp &= ~DC_HPDx_INT_POLARITY;
+			else
+				tmp |= DC_HPDx_INT_POLARITY;
+			WREG32(DC_HPD6_INT_CONTROL, tmp);
+			break;
+		default:
+			break;
+		}
+	} else {
+		switch (hpd) {
+		case RADEON_HPD_1:
+			tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL);
+			if (connected)
+				tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY;
+			else
+				tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY;
+			WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);
+			break;
+		case RADEON_HPD_2:
+			tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL);
+			if (connected)
+				tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY;
+			else
+				tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY;
+			WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);
+			break;
+		case RADEON_HPD_3:
+			tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL);
+			if (connected)
+				tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY;
+			else
+				tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY;
+			WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp);
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+void r600_hpd_init(struct radeon_device *rdev)
+{
+	struct drm_device *dev = rdev->ddev;
+	struct drm_connector *connector;
+
+	if (ASIC_IS_DCE3(rdev)) {
+		u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | DC_HPDx_RX_INT_TIMER(0xfa);
+		if (ASIC_IS_DCE32(rdev))
+			tmp |= DC_HPDx_EN;
+
+		list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+			struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+			switch (radeon_connector->hpd.hpd) {
+			case RADEON_HPD_1:
+				WREG32(DC_HPD1_CONTROL, tmp);
+				rdev->irq.hpd[0] = true;
+				break;
+			case RADEON_HPD_2:
+				WREG32(DC_HPD2_CONTROL, tmp);
+				rdev->irq.hpd[1] = true;
+				break;
+			case RADEON_HPD_3:
+				WREG32(DC_HPD3_CONTROL, tmp);
+				rdev->irq.hpd[2] = true;
+				break;
+			case RADEON_HPD_4:
+				WREG32(DC_HPD4_CONTROL, tmp);
+				rdev->irq.hpd[3] = true;
+				break;
+				/* DCE 3.2 */
+			case RADEON_HPD_5:
+				WREG32(DC_HPD5_CONTROL, tmp);
+				rdev->irq.hpd[4] = true;
+				break;
+			case RADEON_HPD_6:
+				WREG32(DC_HPD6_CONTROL, tmp);
+				rdev->irq.hpd[5] = true;
+				break;
+			default:
+				break;
+			}
+		}
+	} else {
+		list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+			struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+			switch (radeon_connector->hpd.hpd) {
+			case RADEON_HPD_1:
+				WREG32(DC_HOT_PLUG_DETECT1_CONTROL, DC_HOT_PLUG_DETECTx_EN);
+				rdev->irq.hpd[0] = true;
+				break;
+			case RADEON_HPD_2:
+				WREG32(DC_HOT_PLUG_DETECT2_CONTROL, DC_HOT_PLUG_DETECTx_EN);
+				rdev->irq.hpd[1] = true;
+				break;
+			case RADEON_HPD_3:
+				WREG32(DC_HOT_PLUG_DETECT3_CONTROL, DC_HOT_PLUG_DETECTx_EN);
+				rdev->irq.hpd[2] = true;
+				break;
+			default:
+				break;
+			}
+		}
+	}
+	r600_irq_set(rdev);
+}
+
+void r600_hpd_fini(struct radeon_device *rdev)
+{
+	struct drm_device *dev = rdev->ddev;
+	struct drm_connector *connector;
+
+	if (ASIC_IS_DCE3(rdev)) {
+		list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+			struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+			switch (radeon_connector->hpd.hpd) {
+			case RADEON_HPD_1:
+				WREG32(DC_HPD1_CONTROL, 0);
+				rdev->irq.hpd[0] = false;
+				break;
+			case RADEON_HPD_2:
+				WREG32(DC_HPD2_CONTROL, 0);
+				rdev->irq.hpd[1] = false;
+				break;
+			case RADEON_HPD_3:
+				WREG32(DC_HPD3_CONTROL, 0);
+				rdev->irq.hpd[2] = false;
+				break;
+			case RADEON_HPD_4:
+				WREG32(DC_HPD4_CONTROL, 0);
+				rdev->irq.hpd[3] = false;
+				break;
+				/* DCE 3.2 */
+			case RADEON_HPD_5:
+				WREG32(DC_HPD5_CONTROL, 0);
+				rdev->irq.hpd[4] = false;
+				break;
+			case RADEON_HPD_6:
+				WREG32(DC_HPD6_CONTROL, 0);
+				rdev->irq.hpd[5] = false;
+				break;
+			default:
+				break;
+			}
+		}
+	} else {
+		list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+			struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+			switch (radeon_connector->hpd.hpd) {
+			case RADEON_HPD_1:
+				WREG32(DC_HOT_PLUG_DETECT1_CONTROL, 0);
+				rdev->irq.hpd[0] = false;
+				break;
+			case RADEON_HPD_2:
+				WREG32(DC_HOT_PLUG_DETECT2_CONTROL, 0);
+				rdev->irq.hpd[1] = false;
+				break;
+			case RADEON_HPD_3:
+				WREG32(DC_HOT_PLUG_DETECT3_CONTROL, 0);
+				rdev->irq.hpd[2] = false;
+				break;
+			default:
+				break;
+			}
+		}
+	}
+}
+
 /*
  * R600 PCIE GART
  */
@@ -180,7 +459,7 @@
 void r600_pcie_gart_disable(struct radeon_device *rdev)
 {
 	u32 tmp;
-	int i;
+	int i, r;
 
 	/* Disable all tables */
 	for (i = 0; i < 7; i++)
@@ -208,8 +487,12 @@
 	WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp);
 	WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp);
 	if (rdev->gart.table.vram.robj) {
-		radeon_object_kunmap(rdev->gart.table.vram.robj);
-		radeon_object_unpin(rdev->gart.table.vram.robj);
+		r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
+		if (likely(r == 0)) {
+			radeon_bo_kunmap(rdev->gart.table.vram.robj);
+			radeon_bo_unpin(rdev->gart.table.vram.robj);
+			radeon_bo_unreserve(rdev->gart.table.vram.robj);
+		}
 	}
 }
 
@@ -394,11 +677,11 @@
 		 * AGP so that GPU can catch out of VRAM/AGP access
 		 */
 		if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) {
-			/* Enought place before */
+			/* Enough place before */
 			rdev->mc.vram_location = rdev->mc.gtt_location -
 							rdev->mc.mc_vram_size;
 		} else if (tmp > rdev->mc.mc_vram_size) {
-			/* Enought place after */
+			/* Enough place after */
 			rdev->mc.vram_location = rdev->mc.gtt_location +
 							rdev->mc.gtt_size;
 		} else {
@@ -1101,6 +1384,10 @@
 	(void)RREG32(PCIE_PORT_DATA);
 }
 
+void r600_hdp_flush(struct radeon_device *rdev)
+{
+	WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
+}
 
 /*
  * CP & Ring
@@ -1110,11 +1397,12 @@
 	WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1));
 }
 
-int r600_cp_init_microcode(struct radeon_device *rdev)
+int r600_init_microcode(struct radeon_device *rdev)
 {
 	struct platform_device *pdev;
 	const char *chip_name;
-	size_t pfp_req_size, me_req_size;
+	const char *rlc_chip_name;
+	size_t pfp_req_size, me_req_size, rlc_req_size;
 	char fw_name[30];
 	int err;
 
@@ -1128,30 +1416,62 @@
 	}
 
 	switch (rdev->family) {
-	case CHIP_R600: chip_name = "R600"; break;
-	case CHIP_RV610: chip_name = "RV610"; break;
-	case CHIP_RV630: chip_name = "RV630"; break;
-	case CHIP_RV620: chip_name = "RV620"; break;
-	case CHIP_RV635: chip_name = "RV635"; break;
-	case CHIP_RV670: chip_name = "RV670"; break;
+	case CHIP_R600:
+		chip_name = "R600";
+		rlc_chip_name = "R600";
+		break;
+	case CHIP_RV610:
+		chip_name = "RV610";
+		rlc_chip_name = "R600";
+		break;
+	case CHIP_RV630:
+		chip_name = "RV630";
+		rlc_chip_name = "R600";
+		break;
+	case CHIP_RV620:
+		chip_name = "RV620";
+		rlc_chip_name = "R600";
+		break;
+	case CHIP_RV635:
+		chip_name = "RV635";
+		rlc_chip_name = "R600";
+		break;
+	case CHIP_RV670:
+		chip_name = "RV670";
+		rlc_chip_name = "R600";
+		break;
 	case CHIP_RS780:
-	case CHIP_RS880: chip_name = "RS780"; break;
-	case CHIP_RV770: chip_name = "RV770"; break;
+	case CHIP_RS880:
+		chip_name = "RS780";
+		rlc_chip_name = "R600";
+		break;
+	case CHIP_RV770:
+		chip_name = "RV770";
+		rlc_chip_name = "R700";
+		break;
 	case CHIP_RV730:
-	case CHIP_RV740: chip_name = "RV730"; break;
-	case CHIP_RV710: chip_name = "RV710"; break;
+	case CHIP_RV740:
+		chip_name = "RV730";
+		rlc_chip_name = "R700";
+		break;
+	case CHIP_RV710:
+		chip_name = "RV710";
+		rlc_chip_name = "R700";
+		break;
 	default: BUG();
 	}
 
 	if (rdev->family >= CHIP_RV770) {
 		pfp_req_size = R700_PFP_UCODE_SIZE * 4;
 		me_req_size = R700_PM4_UCODE_SIZE * 4;
+		rlc_req_size = R700_RLC_UCODE_SIZE * 4;
 	} else {
 		pfp_req_size = PFP_UCODE_SIZE * 4;
 		me_req_size = PM4_UCODE_SIZE * 12;
+		rlc_req_size = RLC_UCODE_SIZE * 4;
 	}
 
-	DRM_INFO("Loading %s CP Microcode\n", chip_name);
+	DRM_INFO("Loading %s Microcode\n", chip_name);
 
 	snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
 	err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev);
@@ -1175,6 +1495,18 @@
 		       rdev->me_fw->size, fw_name);
 		err = -EINVAL;
 	}
+
+	snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name);
+	err = request_firmware(&rdev->rlc_fw, fw_name, &pdev->dev);
+	if (err)
+		goto out;
+	if (rdev->rlc_fw->size != rlc_req_size) {
+		printk(KERN_ERR
+		       "r600_rlc: Bogus length %zu in firmware \"%s\"\n",
+		       rdev->rlc_fw->size, fw_name);
+		err = -EINVAL;
+	}
+
 out:
 	platform_device_unregister(pdev);
 
@@ -1187,6 +1519,8 @@
 		rdev->pfp_fw = NULL;
 		release_firmware(rdev->me_fw);
 		rdev->me_fw = NULL;
+		release_firmware(rdev->rlc_fw);
+		rdev->rlc_fw = NULL;
 	}
 	return err;
 }
@@ -1381,10 +1715,16 @@
 
 void r600_wb_disable(struct radeon_device *rdev)
 {
+	int r;
+
 	WREG32(SCRATCH_UMSK, 0);
 	if (rdev->wb.wb_obj) {
-		radeon_object_kunmap(rdev->wb.wb_obj);
-		radeon_object_unpin(rdev->wb.wb_obj);
+		r = radeon_bo_reserve(rdev->wb.wb_obj, false);
+		if (unlikely(r != 0))
+			return;
+		radeon_bo_kunmap(rdev->wb.wb_obj);
+		radeon_bo_unpin(rdev->wb.wb_obj);
+		radeon_bo_unreserve(rdev->wb.wb_obj);
 	}
 }
 
@@ -1392,7 +1732,7 @@
 {
 	r600_wb_disable(rdev);
 	if (rdev->wb.wb_obj) {
-		radeon_object_unref(&rdev->wb.wb_obj);
+		radeon_bo_unref(&rdev->wb.wb_obj);
 		rdev->wb.wb = NULL;
 		rdev->wb.wb_obj = NULL;
 	}
@@ -1403,22 +1743,29 @@
 	int r;
 
 	if (rdev->wb.wb_obj == NULL) {
-		r = radeon_object_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true,
-				RADEON_GEM_DOMAIN_GTT, false, &rdev->wb.wb_obj);
+		r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true,
+				RADEON_GEM_DOMAIN_GTT, &rdev->wb.wb_obj);
 		if (r) {
-			dev_warn(rdev->dev, "failed to create WB buffer (%d).\n", r);
+			dev_warn(rdev->dev, "(%d) create WB bo failed\n", r);
 			return r;
 		}
-		r = radeon_object_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT,
-				&rdev->wb.gpu_addr);
-		if (r) {
-			dev_warn(rdev->dev, "failed to pin WB buffer (%d).\n", r);
+		r = radeon_bo_reserve(rdev->wb.wb_obj, false);
+		if (unlikely(r != 0)) {
 			r600_wb_fini(rdev);
 			return r;
 		}
-		r = radeon_object_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
+		r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT,
+				&rdev->wb.gpu_addr);
 		if (r) {
-			dev_warn(rdev->dev, "failed to map WB buffer (%d).\n", r);
+			radeon_bo_unreserve(rdev->wb.wb_obj);
+			dev_warn(rdev->dev, "(%d) pin WB bo failed\n", r);
+			r600_wb_fini(rdev);
+			return r;
+		}
+		r = radeon_bo_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
+		radeon_bo_unreserve(rdev->wb.wb_obj);
+		if (r) {
+			dev_warn(rdev->dev, "(%d) map WB bo failed\n", r);
 			r600_wb_fini(rdev);
 			return r;
 		}
@@ -1433,10 +1780,14 @@
 void r600_fence_ring_emit(struct radeon_device *rdev,
 			  struct radeon_fence *fence)
 {
+	/* Also consider EVENT_WRITE_EOP.  it handles the interrupts + timestamps + events */
 	/* Emit fence sequence & fire IRQ */
 	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
 	radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2));
 	radeon_ring_write(rdev, fence->seq);
+	/* CP_INTERRUPT packet 3 no longer exists, use packet 0 */
+	radeon_ring_write(rdev, PACKET0(CP_INT_STATUS, 0));
+	radeon_ring_write(rdev, RB_INT_STAT);
 }
 
 int r600_copy_dma(struct radeon_device *rdev,
@@ -1459,18 +1810,6 @@
 	return 0;
 }
 
-int r600_irq_process(struct radeon_device *rdev)
-{
-	/* FIXME: implement */
-	return 0;
-}
-
-int r600_irq_set(struct radeon_device *rdev)
-{
-	/* FIXME: implement */
-	return 0;
-}
-
 int r600_set_surface_reg(struct radeon_device *rdev, int reg,
 			 uint32_t tiling_flags, uint32_t pitch,
 			 uint32_t offset, uint32_t obj_size)
@@ -1506,6 +1845,14 @@
 {
 	int r;
 
+	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
+		r = r600_init_microcode(rdev);
+		if (r) {
+			DRM_ERROR("Failed to load firmware!\n");
+			return r;
+		}
+	}
+
 	r600_mc_program(rdev);
 	if (rdev->flags & RADEON_IS_AGP) {
 		r600_agp_enable(rdev);
@@ -1516,13 +1863,26 @@
 	}
 	r600_gpu_init(rdev);
 
-	r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
-			      &rdev->r600_blit.shader_gpu_addr);
+	r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
+	if (unlikely(r != 0))
+		return r;
+	r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
+			&rdev->r600_blit.shader_gpu_addr);
+	radeon_bo_unreserve(rdev->r600_blit.shader_obj);
 	if (r) {
-		DRM_ERROR("failed to pin blit object %d\n", r);
+		dev_err(rdev->dev, "(%d) pin blit object failed\n", r);
 		return r;
 	}
 
+	/* Enable IRQ */
+	r = r600_irq_init(rdev);
+	if (r) {
+		DRM_ERROR("radeon: IH init failed (%d).\n", r);
+		radeon_irq_kms_fini(rdev);
+		return r;
+	}
+	r600_irq_set(rdev);
+
 	r = radeon_ring_init(rdev, rdev->cp.ring_size);
 	if (r)
 		return r;
@@ -1583,13 +1943,19 @@
 
 int r600_suspend(struct radeon_device *rdev)
 {
+	int r;
+
 	/* FIXME: we should wait for ring to be empty */
 	r600_cp_stop(rdev);
 	rdev->cp.ready = false;
 	r600_wb_disable(rdev);
 	r600_pcie_gart_disable(rdev);
 	/* unpin shaders bo */
-	radeon_object_unpin(rdev->r600_blit.shader_obj);
+	r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
+	if (unlikely(r != 0))
+		return r;
+	radeon_bo_unpin(rdev->r600_blit.shader_obj);
+	radeon_bo_unreserve(rdev->r600_blit.shader_obj);
 	return 0;
 }
 
@@ -1627,7 +1993,11 @@
 	if (r)
 		return r;
 	/* Post card if necessary */
-	if (!r600_card_posted(rdev) && rdev->bios) {
+	if (!r600_card_posted(rdev)) {
+		if (!rdev->bios) {
+			dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
+			return -EINVAL;
+		}
 		DRM_INFO("GPU not posted. posting now...\n");
 		atom_asic_init(rdev->mode_info.atom_context);
 	}
@@ -1650,31 +2020,31 @@
 	if (r)
 		return r;
 	/* Memory manager */
-	r = radeon_object_init(rdev);
+	r = radeon_bo_init(rdev);
 	if (r)
 		return r;
+
+	r = radeon_irq_kms_init(rdev);
+	if (r)
+		return r;
+
 	rdev->cp.ring_obj = NULL;
 	r600_ring_init(rdev, 1024 * 1024);
 
-	if (!rdev->me_fw || !rdev->pfp_fw) {
-		r = r600_cp_init_microcode(rdev);
-		if (r) {
-			DRM_ERROR("Failed to load firmware!\n");
-			return r;
-		}
-	}
+	rdev->ih.ring_obj = NULL;
+	r600_ih_ring_init(rdev, 64 * 1024);
 
 	r = r600_pcie_gart_init(rdev);
 	if (r)
 		return r;
 
-	rdev->accel_working = true;
 	r = r600_blit_init(rdev);
 	if (r) {
-		DRM_ERROR("radeon: failled blitter (%d).\n", r);
+		DRM_ERROR("radeon: failed blitter (%d).\n", r);
 		return r;
 	}
 
+	rdev->accel_working = true;
 	r = r600_startup(rdev);
 	if (r) {
 		r600_suspend(rdev);
@@ -1686,12 +2056,12 @@
 	if (rdev->accel_working) {
 		r = radeon_ib_pool_init(rdev);
 		if (r) {
-			DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r);
+			DRM_ERROR("radeon: failed initializing IB pool (%d).\n", r);
 			rdev->accel_working = false;
 		}
 		r = r600_ib_test(rdev);
 		if (r) {
-			DRM_ERROR("radeon: failled testing IB (%d).\n", r);
+			DRM_ERROR("radeon: failed testing IB (%d).\n", r);
 			rdev->accel_working = false;
 		}
 	}
@@ -1704,6 +2074,8 @@
 	r600_suspend(rdev);
 
 	r600_blit_fini(rdev);
+	r600_irq_fini(rdev);
+	radeon_irq_kms_fini(rdev);
 	radeon_ring_fini(rdev);
 	r600_wb_fini(rdev);
 	r600_pcie_gart_fini(rdev);
@@ -1712,7 +2084,7 @@
 	radeon_clocks_fini(rdev);
 	if (rdev->flags & RADEON_IS_AGP)
 		radeon_agp_fini(rdev);
-	radeon_object_fini(rdev);
+	radeon_bo_fini(rdev);
 	radeon_atombios_fini(rdev);
 	kfree(rdev->bios);
 	rdev->bios = NULL;
@@ -1798,8 +2170,657 @@
 	return r;
 }
 
+/*
+ * Interrupts
+ *
+ * Interrupts use a ring buffer on r6xx/r7xx hardware.  It works pretty
+ * the same as the CP ring buffer, but in reverse.  Rather than the CPU
+ * writing to the ring and the GPU consuming, the GPU writes to the ring
+ * and host consumes.  As the host irq handler processes interrupts, it
+ * increments the rptr.  When the rptr catches up with the wptr, all the
+ * current interrupts have been processed.
+ */
 
+void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size)
+{
+	u32 rb_bufsz;
 
+	/* Align ring size */
+	rb_bufsz = drm_order(ring_size / 4);
+	ring_size = (1 << rb_bufsz) * 4;
+	rdev->ih.ring_size = ring_size;
+	rdev->ih.align_mask = 4 - 1;
+}
+
+static int r600_ih_ring_alloc(struct radeon_device *rdev, unsigned ring_size)
+{
+	int r;
+
+	rdev->ih.ring_size = ring_size;
+	/* Allocate ring buffer */
+	if (rdev->ih.ring_obj == NULL) {
+		r = radeon_bo_create(rdev, NULL, rdev->ih.ring_size,
+				     true,
+				     RADEON_GEM_DOMAIN_GTT,
+				     &rdev->ih.ring_obj);
+		if (r) {
+			DRM_ERROR("radeon: failed to create ih ring buffer (%d).\n", r);
+			return r;
+		}
+		r = radeon_bo_reserve(rdev->ih.ring_obj, false);
+		if (unlikely(r != 0))
+			return r;
+		r = radeon_bo_pin(rdev->ih.ring_obj,
+				  RADEON_GEM_DOMAIN_GTT,
+				  &rdev->ih.gpu_addr);
+		if (r) {
+			radeon_bo_unreserve(rdev->ih.ring_obj);
+			DRM_ERROR("radeon: failed to pin ih ring buffer (%d).\n", r);
+			return r;
+		}
+		r = radeon_bo_kmap(rdev->ih.ring_obj,
+				   (void **)&rdev->ih.ring);
+		radeon_bo_unreserve(rdev->ih.ring_obj);
+		if (r) {
+			DRM_ERROR("radeon: failed to map ih ring buffer (%d).\n", r);
+			return r;
+		}
+	}
+	rdev->ih.ptr_mask = (rdev->cp.ring_size / 4) - 1;
+	rdev->ih.rptr = 0;
+
+	return 0;
+}
+
+static void r600_ih_ring_fini(struct radeon_device *rdev)
+{
+	int r;
+	if (rdev->ih.ring_obj) {
+		r = radeon_bo_reserve(rdev->ih.ring_obj, false);
+		if (likely(r == 0)) {
+			radeon_bo_kunmap(rdev->ih.ring_obj);
+			radeon_bo_unpin(rdev->ih.ring_obj);
+			radeon_bo_unreserve(rdev->ih.ring_obj);
+		}
+		radeon_bo_unref(&rdev->ih.ring_obj);
+		rdev->ih.ring = NULL;
+		rdev->ih.ring_obj = NULL;
+	}
+}
+
+static void r600_rlc_stop(struct radeon_device *rdev)
+{
+
+	if (rdev->family >= CHIP_RV770) {
+		/* r7xx asics need to soft reset RLC before halting */
+		WREG32(SRBM_SOFT_RESET, SOFT_RESET_RLC);
+		RREG32(SRBM_SOFT_RESET);
+		udelay(15000);
+		WREG32(SRBM_SOFT_RESET, 0);
+		RREG32(SRBM_SOFT_RESET);
+	}
+
+	WREG32(RLC_CNTL, 0);
+}
+
+static void r600_rlc_start(struct radeon_device *rdev)
+{
+	WREG32(RLC_CNTL, RLC_ENABLE);
+}
+
+static int r600_rlc_init(struct radeon_device *rdev)
+{
+	u32 i;
+	const __be32 *fw_data;
+
+	if (!rdev->rlc_fw)
+		return -EINVAL;
+
+	r600_rlc_stop(rdev);
+
+	WREG32(RLC_HB_BASE, 0);
+	WREG32(RLC_HB_CNTL, 0);
+	WREG32(RLC_HB_RPTR, 0);
+	WREG32(RLC_HB_WPTR, 0);
+	WREG32(RLC_HB_WPTR_LSB_ADDR, 0);
+	WREG32(RLC_HB_WPTR_MSB_ADDR, 0);
+	WREG32(RLC_MC_CNTL, 0);
+	WREG32(RLC_UCODE_CNTL, 0);
+
+	fw_data = (const __be32 *)rdev->rlc_fw->data;
+	if (rdev->family >= CHIP_RV770) {
+		for (i = 0; i < R700_RLC_UCODE_SIZE; i++) {
+			WREG32(RLC_UCODE_ADDR, i);
+			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
+		}
+	} else {
+		for (i = 0; i < RLC_UCODE_SIZE; i++) {
+			WREG32(RLC_UCODE_ADDR, i);
+			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
+		}
+	}
+	WREG32(RLC_UCODE_ADDR, 0);
+
+	r600_rlc_start(rdev);
+
+	return 0;
+}
+
+static void r600_enable_interrupts(struct radeon_device *rdev)
+{
+	u32 ih_cntl = RREG32(IH_CNTL);
+	u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
+
+	ih_cntl |= ENABLE_INTR;
+	ih_rb_cntl |= IH_RB_ENABLE;
+	WREG32(IH_CNTL, ih_cntl);
+	WREG32(IH_RB_CNTL, ih_rb_cntl);
+	rdev->ih.enabled = true;
+}
+
+static void r600_disable_interrupts(struct radeon_device *rdev)
+{
+	u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
+	u32 ih_cntl = RREG32(IH_CNTL);
+
+	ih_rb_cntl &= ~IH_RB_ENABLE;
+	ih_cntl &= ~ENABLE_INTR;
+	WREG32(IH_RB_CNTL, ih_rb_cntl);
+	WREG32(IH_CNTL, ih_cntl);
+	/* set rptr, wptr to 0 */
+	WREG32(IH_RB_RPTR, 0);
+	WREG32(IH_RB_WPTR, 0);
+	rdev->ih.enabled = false;
+	rdev->ih.wptr = 0;
+	rdev->ih.rptr = 0;
+}
+
+static void r600_disable_interrupt_state(struct radeon_device *rdev)
+{
+	u32 tmp;
+
+	WREG32(CP_INT_CNTL, 0);
+	WREG32(GRBM_INT_CNTL, 0);
+	WREG32(DxMODE_INT_MASK, 0);
+	if (ASIC_IS_DCE3(rdev)) {
+		WREG32(DCE3_DACA_AUTODETECT_INT_CONTROL, 0);
+		WREG32(DCE3_DACB_AUTODETECT_INT_CONTROL, 0);
+		tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY;
+		WREG32(DC_HPD1_INT_CONTROL, tmp);
+		tmp = RREG32(DC_HPD2_INT_CONTROL) & DC_HPDx_INT_POLARITY;
+		WREG32(DC_HPD2_INT_CONTROL, tmp);
+		tmp = RREG32(DC_HPD3_INT_CONTROL) & DC_HPDx_INT_POLARITY;
+		WREG32(DC_HPD3_INT_CONTROL, tmp);
+		tmp = RREG32(DC_HPD4_INT_CONTROL) & DC_HPDx_INT_POLARITY;
+		WREG32(DC_HPD4_INT_CONTROL, tmp);
+		if (ASIC_IS_DCE32(rdev)) {
+			tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY;
+			WREG32(DC_HPD5_INT_CONTROL, 0);
+			tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY;
+			WREG32(DC_HPD6_INT_CONTROL, 0);
+		}
+	} else {
+		WREG32(DACA_AUTODETECT_INT_CONTROL, 0);
+		WREG32(DACB_AUTODETECT_INT_CONTROL, 0);
+		tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
+		WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, 0);
+		tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
+		WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, 0);
+		tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
+		WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, 0);
+	}
+}
+
+int r600_irq_init(struct radeon_device *rdev)
+{
+	int ret = 0;
+	int rb_bufsz;
+	u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
+
+	/* allocate ring */
+	ret = r600_ih_ring_alloc(rdev, rdev->ih.ring_size);
+	if (ret)
+		return ret;
+
+	/* disable irqs */
+	r600_disable_interrupts(rdev);
+
+	/* init rlc */
+	ret = r600_rlc_init(rdev);
+	if (ret) {
+		r600_ih_ring_fini(rdev);
+		return ret;
+	}
+
+	/* setup interrupt control */
+	/* set dummy read address to ring address */
+	WREG32(INTERRUPT_CNTL2, rdev->ih.gpu_addr >> 8);
+	interrupt_cntl = RREG32(INTERRUPT_CNTL);
+	/* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled without msi
+	 * IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_EN
+	 */
+	interrupt_cntl &= ~IH_DUMMY_RD_OVERRIDE;
+	/* IH_REQ_NONSNOOP_EN=1 if ring is in non-cacheable memory, e.g., vram */
+	interrupt_cntl &= ~IH_REQ_NONSNOOP_EN;
+	WREG32(INTERRUPT_CNTL, interrupt_cntl);
+
+	WREG32(IH_RB_BASE, rdev->ih.gpu_addr >> 8);
+	rb_bufsz = drm_order(rdev->ih.ring_size / 4);
+
+	ih_rb_cntl = (IH_WPTR_OVERFLOW_ENABLE |
+		      IH_WPTR_OVERFLOW_CLEAR |
+		      (rb_bufsz << 1));
+	/* WPTR writeback, not yet */
+	/*ih_rb_cntl |= IH_WPTR_WRITEBACK_ENABLE;*/
+	WREG32(IH_RB_WPTR_ADDR_LO, 0);
+	WREG32(IH_RB_WPTR_ADDR_HI, 0);
+
+	WREG32(IH_RB_CNTL, ih_rb_cntl);
+
+	/* set rptr, wptr to 0 */
+	WREG32(IH_RB_RPTR, 0);
+	WREG32(IH_RB_WPTR, 0);
+
+	/* Default settings for IH_CNTL (disabled at first) */
+	ih_cntl = MC_WRREQ_CREDIT(0x10) | MC_WR_CLEAN_CNT(0x10);
+	/* RPTR_REARM only works if msi's are enabled */
+	if (rdev->msi_enabled)
+		ih_cntl |= RPTR_REARM;
+
+#ifdef __BIG_ENDIAN
+	ih_cntl |= IH_MC_SWAP(IH_MC_SWAP_32BIT);
+#endif
+	WREG32(IH_CNTL, ih_cntl);
+
+	/* force the active interrupt state to all disabled */
+	r600_disable_interrupt_state(rdev);
+
+	/* enable irqs */
+	r600_enable_interrupts(rdev);
+
+	return ret;
+}
+
+void r600_irq_fini(struct radeon_device *rdev)
+{
+	r600_disable_interrupts(rdev);
+	r600_rlc_stop(rdev);
+	r600_ih_ring_fini(rdev);
+}
+
+int r600_irq_set(struct radeon_device *rdev)
+{
+	u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE;
+	u32 mode_int = 0;
+	u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0;
+
+	/* don't enable anything if the ih is disabled */
+	if (!rdev->ih.enabled)
+		return 0;
+
+	if (ASIC_IS_DCE3(rdev)) {
+		hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN;
+		hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN;
+		hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN;
+		hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN;
+		if (ASIC_IS_DCE32(rdev)) {
+			hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN;
+			hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN;
+		}
+	} else {
+		hpd1 = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & ~DC_HPDx_INT_EN;
+		hpd2 = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & ~DC_HPDx_INT_EN;
+		hpd3 = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & ~DC_HPDx_INT_EN;
+	}
+
+	if (rdev->irq.sw_int) {
+		DRM_DEBUG("r600_irq_set: sw int\n");
+		cp_int_cntl |= RB_INT_ENABLE;
+	}
+	if (rdev->irq.crtc_vblank_int[0]) {
+		DRM_DEBUG("r600_irq_set: vblank 0\n");
+		mode_int |= D1MODE_VBLANK_INT_MASK;
+	}
+	if (rdev->irq.crtc_vblank_int[1]) {
+		DRM_DEBUG("r600_irq_set: vblank 1\n");
+		mode_int |= D2MODE_VBLANK_INT_MASK;
+	}
+	if (rdev->irq.hpd[0]) {
+		DRM_DEBUG("r600_irq_set: hpd 1\n");
+		hpd1 |= DC_HPDx_INT_EN;
+	}
+	if (rdev->irq.hpd[1]) {
+		DRM_DEBUG("r600_irq_set: hpd 2\n");
+		hpd2 |= DC_HPDx_INT_EN;
+	}
+	if (rdev->irq.hpd[2]) {
+		DRM_DEBUG("r600_irq_set: hpd 3\n");
+		hpd3 |= DC_HPDx_INT_EN;
+	}
+	if (rdev->irq.hpd[3]) {
+		DRM_DEBUG("r600_irq_set: hpd 4\n");
+		hpd4 |= DC_HPDx_INT_EN;
+	}
+	if (rdev->irq.hpd[4]) {
+		DRM_DEBUG("r600_irq_set: hpd 5\n");
+		hpd5 |= DC_HPDx_INT_EN;
+	}
+	if (rdev->irq.hpd[5]) {
+		DRM_DEBUG("r600_irq_set: hpd 6\n");
+		hpd6 |= DC_HPDx_INT_EN;
+	}
+
+	WREG32(CP_INT_CNTL, cp_int_cntl);
+	WREG32(DxMODE_INT_MASK, mode_int);
+	if (ASIC_IS_DCE3(rdev)) {
+		WREG32(DC_HPD1_INT_CONTROL, hpd1);
+		WREG32(DC_HPD2_INT_CONTROL, hpd2);
+		WREG32(DC_HPD3_INT_CONTROL, hpd3);
+		WREG32(DC_HPD4_INT_CONTROL, hpd4);
+		if (ASIC_IS_DCE32(rdev)) {
+			WREG32(DC_HPD5_INT_CONTROL, hpd5);
+			WREG32(DC_HPD6_INT_CONTROL, hpd6);
+		}
+	} else {
+		WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1);
+		WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2);
+		WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, hpd3);
+	}
+
+	return 0;
+}
+
+static inline void r600_irq_ack(struct radeon_device *rdev,
+				u32 *disp_int,
+				u32 *disp_int_cont,
+				u32 *disp_int_cont2)
+{
+	u32 tmp;
+
+	if (ASIC_IS_DCE3(rdev)) {
+		*disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS);
+		*disp_int_cont = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE);
+		*disp_int_cont2 = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE2);
+	} else {
+		*disp_int = RREG32(DISP_INTERRUPT_STATUS);
+		*disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE);
+		*disp_int_cont2 = 0;
+	}
+
+	if (*disp_int & LB_D1_VBLANK_INTERRUPT)
+		WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK);
+	if (*disp_int & LB_D1_VLINE_INTERRUPT)
+		WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK);
+	if (*disp_int & LB_D2_VBLANK_INTERRUPT)
+		WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK);
+	if (*disp_int & LB_D2_VLINE_INTERRUPT)
+		WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK);
+	if (*disp_int & DC_HPD1_INTERRUPT) {
+		if (ASIC_IS_DCE3(rdev)) {
+			tmp = RREG32(DC_HPD1_INT_CONTROL);
+			tmp |= DC_HPDx_INT_ACK;
+			WREG32(DC_HPD1_INT_CONTROL, tmp);
+		} else {
+			tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL);
+			tmp |= DC_HPDx_INT_ACK;
+			WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);
+		}
+	}
+	if (*disp_int & DC_HPD2_INTERRUPT) {
+		if (ASIC_IS_DCE3(rdev)) {
+			tmp = RREG32(DC_HPD2_INT_CONTROL);
+			tmp |= DC_HPDx_INT_ACK;
+			WREG32(DC_HPD2_INT_CONTROL, tmp);
+		} else {
+			tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL);
+			tmp |= DC_HPDx_INT_ACK;
+			WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);
+		}
+	}
+	if (*disp_int_cont & DC_HPD3_INTERRUPT) {
+		if (ASIC_IS_DCE3(rdev)) {
+			tmp = RREG32(DC_HPD3_INT_CONTROL);
+			tmp |= DC_HPDx_INT_ACK;
+			WREG32(DC_HPD3_INT_CONTROL, tmp);
+		} else {
+			tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL);
+			tmp |= DC_HPDx_INT_ACK;
+			WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp);
+		}
+	}
+	if (*disp_int_cont & DC_HPD4_INTERRUPT) {
+		tmp = RREG32(DC_HPD4_INT_CONTROL);
+		tmp |= DC_HPDx_INT_ACK;
+		WREG32(DC_HPD4_INT_CONTROL, tmp);
+	}
+	if (ASIC_IS_DCE32(rdev)) {
+		if (*disp_int_cont2 & DC_HPD5_INTERRUPT) {
+			tmp = RREG32(DC_HPD5_INT_CONTROL);
+			tmp |= DC_HPDx_INT_ACK;
+			WREG32(DC_HPD5_INT_CONTROL, tmp);
+		}
+		if (*disp_int_cont2 & DC_HPD6_INTERRUPT) {
+			tmp = RREG32(DC_HPD5_INT_CONTROL);
+			tmp |= DC_HPDx_INT_ACK;
+			WREG32(DC_HPD6_INT_CONTROL, tmp);
+		}
+	}
+}
+
+void r600_irq_disable(struct radeon_device *rdev)
+{
+	u32 disp_int, disp_int_cont, disp_int_cont2;
+
+	r600_disable_interrupts(rdev);
+	/* Wait and acknowledge irq */
+	mdelay(1);
+	r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2);
+	r600_disable_interrupt_state(rdev);
+}
+
+static inline u32 r600_get_ih_wptr(struct radeon_device *rdev)
+{
+	u32 wptr, tmp;
+
+	/* XXX use writeback */
+	wptr = RREG32(IH_RB_WPTR);
+
+	if (wptr & RB_OVERFLOW) {
+		WARN_ON(1);
+		/* XXX deal with overflow */
+		DRM_ERROR("IH RB overflow\n");
+		tmp = RREG32(IH_RB_CNTL);
+		tmp |= IH_WPTR_OVERFLOW_CLEAR;
+		WREG32(IH_RB_CNTL, tmp);
+	}
+	wptr = wptr & WPTR_OFFSET_MASK;
+
+	return wptr;
+}
+
+/*        r600 IV Ring
+ * Each IV ring entry is 128 bits:
+ * [7:0]    - interrupt source id
+ * [31:8]   - reserved
+ * [59:32]  - interrupt source data
+ * [127:60]  - reserved
+ *
+ * The basic interrupt vector entries
+ * are decoded as follows:
+ * src_id  src_data  description
+ *      1         0  D1 Vblank
+ *      1         1  D1 Vline
+ *      5         0  D2 Vblank
+ *      5         1  D2 Vline
+ *     19         0  FP Hot plug detection A
+ *     19         1  FP Hot plug detection B
+ *     19         2  DAC A auto-detection
+ *     19         3  DAC B auto-detection
+ *    176         -  CP_INT RB
+ *    177         -  CP_INT IB1
+ *    178         -  CP_INT IB2
+ *    181         -  EOP Interrupt
+ *    233         -  GUI Idle
+ *
+ * Note, these are based on r600 and may need to be
+ * adjusted or added to on newer asics
+ */
+
+int r600_irq_process(struct radeon_device *rdev)
+{
+	u32 wptr = r600_get_ih_wptr(rdev);
+	u32 rptr = rdev->ih.rptr;
+	u32 src_id, src_data;
+	u32 last_entry = rdev->ih.ring_size - 16;
+	u32 ring_index, disp_int, disp_int_cont, disp_int_cont2;
+	unsigned long flags;
+	bool queue_hotplug = false;
+
+	DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
+
+	spin_lock_irqsave(&rdev->ih.lock, flags);
+
+	if (rptr == wptr) {
+		spin_unlock_irqrestore(&rdev->ih.lock, flags);
+		return IRQ_NONE;
+	}
+	if (rdev->shutdown) {
+		spin_unlock_irqrestore(&rdev->ih.lock, flags);
+		return IRQ_NONE;
+	}
+
+restart_ih:
+	/* display interrupts */
+	r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2);
+
+	rdev->ih.wptr = wptr;
+	while (rptr != wptr) {
+		/* wptr/rptr are in bytes! */
+		ring_index = rptr / 4;
+		src_id =  rdev->ih.ring[ring_index] & 0xff;
+		src_data = rdev->ih.ring[ring_index + 1] & 0xfffffff;
+
+		switch (src_id) {
+		case 1: /* D1 vblank/vline */
+			switch (src_data) {
+			case 0: /* D1 vblank */
+				if (disp_int & LB_D1_VBLANK_INTERRUPT) {
+					drm_handle_vblank(rdev->ddev, 0);
+					disp_int &= ~LB_D1_VBLANK_INTERRUPT;
+					DRM_DEBUG("IH: D1 vblank\n");
+				}
+				break;
+			case 1: /* D1 vline */
+				if (disp_int & LB_D1_VLINE_INTERRUPT) {
+					disp_int &= ~LB_D1_VLINE_INTERRUPT;
+					DRM_DEBUG("IH: D1 vline\n");
+				}
+				break;
+			default:
+				DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
+				break;
+			}
+			break;
+		case 5: /* D2 vblank/vline */
+			switch (src_data) {
+			case 0: /* D2 vblank */
+				if (disp_int & LB_D2_VBLANK_INTERRUPT) {
+					drm_handle_vblank(rdev->ddev, 1);
+					disp_int &= ~LB_D2_VBLANK_INTERRUPT;
+					DRM_DEBUG("IH: D2 vblank\n");
+				}
+				break;
+			case 1: /* D1 vline */
+				if (disp_int & LB_D2_VLINE_INTERRUPT) {
+					disp_int &= ~LB_D2_VLINE_INTERRUPT;
+					DRM_DEBUG("IH: D2 vline\n");
+				}
+				break;
+			default:
+				DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
+				break;
+			}
+			break;
+		case 19: /* HPD/DAC hotplug */
+			switch (src_data) {
+			case 0:
+				if (disp_int & DC_HPD1_INTERRUPT) {
+					disp_int &= ~DC_HPD1_INTERRUPT;
+					queue_hotplug = true;
+					DRM_DEBUG("IH: HPD1\n");
+				}
+				break;
+			case 1:
+				if (disp_int & DC_HPD2_INTERRUPT) {
+					disp_int &= ~DC_HPD2_INTERRUPT;
+					queue_hotplug = true;
+					DRM_DEBUG("IH: HPD2\n");
+				}
+				break;
+			case 4:
+				if (disp_int_cont & DC_HPD3_INTERRUPT) {
+					disp_int_cont &= ~DC_HPD3_INTERRUPT;
+					queue_hotplug = true;
+					DRM_DEBUG("IH: HPD3\n");
+				}
+				break;
+			case 5:
+				if (disp_int_cont & DC_HPD4_INTERRUPT) {
+					disp_int_cont &= ~DC_HPD4_INTERRUPT;
+					queue_hotplug = true;
+					DRM_DEBUG("IH: HPD4\n");
+				}
+				break;
+			case 10:
+				if (disp_int_cont2 & DC_HPD5_INTERRUPT) {
+					disp_int_cont &= ~DC_HPD5_INTERRUPT;
+					queue_hotplug = true;
+					DRM_DEBUG("IH: HPD5\n");
+				}
+				break;
+			case 12:
+				if (disp_int_cont2 & DC_HPD6_INTERRUPT) {
+					disp_int_cont &= ~DC_HPD6_INTERRUPT;
+					queue_hotplug = true;
+					DRM_DEBUG("IH: HPD6\n");
+				}
+				break;
+			default:
+				DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
+				break;
+			}
+			break;
+		case 176: /* CP_INT in ring buffer */
+		case 177: /* CP_INT in IB1 */
+		case 178: /* CP_INT in IB2 */
+			DRM_DEBUG("IH: CP int: 0x%08x\n", src_data);
+			radeon_fence_process(rdev);
+			break;
+		case 181: /* CP EOP event */
+			DRM_DEBUG("IH: CP EOP\n");
+			break;
+		default:
+			DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
+			break;
+		}
+
+		/* wptr/rptr are in bytes! */
+		if (rptr == last_entry)
+			rptr = 0;
+		else
+			rptr += 16;
+	}
+	/* make sure wptr hasn't changed while processing */
+	wptr = r600_get_ih_wptr(rdev);
+	if (wptr != rdev->ih.wptr)
+		goto restart_ih;
+	if (queue_hotplug)
+		queue_work(rdev->wq, &rdev->hotplug_work);
+	rdev->ih.rptr = rptr;
+	WREG32(IH_RB_RPTR, rdev->ih.rptr);
+	spin_unlock_irqrestore(&rdev->ih.lock, flags);
+	return IRQ_HANDLED;
+}
 
 /*
  * Debugfs info
@@ -1811,21 +2832,21 @@
 	struct drm_info_node *node = (struct drm_info_node *) m->private;
 	struct drm_device *dev = node->minor->dev;
 	struct radeon_device *rdev = dev->dev_private;
-	uint32_t rdp, wdp;
 	unsigned count, i, j;
 
 	radeon_ring_free_size(rdev);
-	rdp = RREG32(CP_RB_RPTR);
-	wdp = RREG32(CP_RB_WPTR);
-	count = (rdp + rdev->cp.ring_size - wdp) & rdev->cp.ptr_mask;
+	count = (rdev->cp.ring_size / 4) - rdev->cp.ring_free_dw;
 	seq_printf(m, "CP_STAT 0x%08x\n", RREG32(CP_STAT));
-	seq_printf(m, "CP_RB_WPTR 0x%08x\n", wdp);
-	seq_printf(m, "CP_RB_RPTR 0x%08x\n", rdp);
+	seq_printf(m, "CP_RB_WPTR 0x%08x\n", RREG32(CP_RB_WPTR));
+	seq_printf(m, "CP_RB_RPTR 0x%08x\n", RREG32(CP_RB_RPTR));
+	seq_printf(m, "driver's copy of the CP_RB_WPTR 0x%08x\n", rdev->cp.wptr);
+	seq_printf(m, "driver's copy of the CP_RB_RPTR 0x%08x\n", rdev->cp.rptr);
 	seq_printf(m, "%u free dwords in ring\n", rdev->cp.ring_free_dw);
 	seq_printf(m, "%u dwords in ring\n", count);
+	i = rdev->cp.rptr;
 	for (j = 0; j <= count; j++) {
-		i = (rdp + j) & rdev->cp.ptr_mask;
 		seq_printf(m, "r[%04d]=0x%08x\n", i, rdev->cp.ring[i]);
+		i = (i + 1) & rdev->cp.ptr_mask;
 	}
 	return 0;
 }
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c
index dbf716e..9aecafb 100644
--- a/drivers/gpu/drm/radeon/r600_blit_kms.c
+++ b/drivers/gpu/drm/radeon/r600_blit_kms.c
@@ -473,9 +473,8 @@
 	obj_size += r6xx_ps_size * 4;
 	obj_size = ALIGN(obj_size, 256);
 
-	r = radeon_object_create(rdev, NULL, obj_size,
-				 true, RADEON_GEM_DOMAIN_VRAM,
-				 false, &rdev->r600_blit.shader_obj);
+	r = radeon_bo_create(rdev, NULL, obj_size, true, RADEON_GEM_DOMAIN_VRAM,
+				&rdev->r600_blit.shader_obj);
 	if (r) {
 		DRM_ERROR("r600 failed to allocate shader\n");
 		return r;
@@ -485,12 +484,14 @@
 		  obj_size,
 		  rdev->r600_blit.vs_offset, rdev->r600_blit.ps_offset);
 
-	r = radeon_object_kmap(rdev->r600_blit.shader_obj, &ptr);
+	r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
+	if (unlikely(r != 0))
+		return r;
+	r = radeon_bo_kmap(rdev->r600_blit.shader_obj, &ptr);
 	if (r) {
 		DRM_ERROR("failed to map blit object %d\n", r);
 		return r;
 	}
-
 	if (rdev->family >= CHIP_RV770)
 		memcpy_toio(ptr + rdev->r600_blit.state_offset,
 			    r7xx_default_state, rdev->r600_blit.state_len * 4);
@@ -500,19 +501,26 @@
 	if (num_packet2s)
 		memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4),
 			    packet2s, num_packet2s * 4);
-
-
 	memcpy(ptr + rdev->r600_blit.vs_offset, r6xx_vs, r6xx_vs_size * 4);
 	memcpy(ptr + rdev->r600_blit.ps_offset, r6xx_ps, r6xx_ps_size * 4);
-
-	radeon_object_kunmap(rdev->r600_blit.shader_obj);
+	radeon_bo_kunmap(rdev->r600_blit.shader_obj);
+	radeon_bo_unreserve(rdev->r600_blit.shader_obj);
 	return 0;
 }
 
 void r600_blit_fini(struct radeon_device *rdev)
 {
-	radeon_object_unpin(rdev->r600_blit.shader_obj);
-	radeon_object_unref(&rdev->r600_blit.shader_obj);
+	int r;
+
+	r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
+	if (unlikely(r != 0)) {
+		dev_err(rdev->dev, "(%d) can't finish r600 blit\n", r);
+		goto out_unref;
+	}
+	radeon_bo_unpin(rdev->r600_blit.shader_obj);
+	radeon_bo_unreserve(rdev->r600_blit.shader_obj);
+out_unref:
+	radeon_bo_unref(&rdev->r600_blit.shader_obj);
 }
 
 int r600_vb_ib_get(struct radeon_device *rdev)
@@ -569,9 +577,9 @@
 	ring_size = num_loops * dwords_per_loop;
 	/* set default  + shaders */
 	ring_size += 40; /* shaders + def state */
-	ring_size += 3; /* fence emit for VB IB */
+	ring_size += 5; /* fence emit for VB IB */
 	ring_size += 5; /* done copy */
-	ring_size += 3; /* fence emit for done copy */
+	ring_size += 5; /* fence emit for done copy */
 	r = radeon_ring_lock(rdev, ring_size);
 	WARN_ON(r);
 
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
index 27ab428..05894ed 100644
--- a/drivers/gpu/drm/radeon/r600d.h
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -456,7 +456,215 @@
 #define         WAIT_2D_IDLECLEAN_bit                           (1 << 16)
 #define         WAIT_3D_IDLECLEAN_bit                           (1 << 17)
 
+#define IH_RB_CNTL                                        0x3e00
+#       define IH_RB_ENABLE                               (1 << 0)
+#       define IH_IB_SIZE(x)                              ((x) << 1) /* log2 */
+#       define IH_RB_FULL_DRAIN_ENABLE                    (1 << 6)
+#       define IH_WPTR_WRITEBACK_ENABLE                   (1 << 8)
+#       define IH_WPTR_WRITEBACK_TIMER(x)                 ((x) << 9) /* log2 */
+#       define IH_WPTR_OVERFLOW_ENABLE                    (1 << 16)
+#       define IH_WPTR_OVERFLOW_CLEAR                     (1 << 31)
+#define IH_RB_BASE                                        0x3e04
+#define IH_RB_RPTR                                        0x3e08
+#define IH_RB_WPTR                                        0x3e0c
+#       define RB_OVERFLOW                                (1 << 0)
+#       define WPTR_OFFSET_MASK                           0x3fffc
+#define IH_RB_WPTR_ADDR_HI                                0x3e10
+#define IH_RB_WPTR_ADDR_LO                                0x3e14
+#define IH_CNTL                                           0x3e18
+#       define ENABLE_INTR                                (1 << 0)
+#       define IH_MC_SWAP(x)                              ((x) << 2)
+#       define IH_MC_SWAP_NONE                            0
+#       define IH_MC_SWAP_16BIT                           1
+#       define IH_MC_SWAP_32BIT                           2
+#       define IH_MC_SWAP_64BIT                           3
+#       define RPTR_REARM                                 (1 << 4)
+#       define MC_WRREQ_CREDIT(x)                         ((x) << 15)
+#       define MC_WR_CLEAN_CNT(x)                         ((x) << 20)
 
+#define RLC_CNTL                                          0x3f00
+#       define RLC_ENABLE                                 (1 << 0)
+#define RLC_HB_BASE                                       0x3f10
+#define RLC_HB_CNTL                                       0x3f0c
+#define RLC_HB_RPTR                                       0x3f20
+#define RLC_HB_WPTR                                       0x3f1c
+#define RLC_HB_WPTR_LSB_ADDR                              0x3f14
+#define RLC_HB_WPTR_MSB_ADDR                              0x3f18
+#define RLC_MC_CNTL                                       0x3f44
+#define RLC_UCODE_CNTL                                    0x3f48
+#define RLC_UCODE_ADDR                                    0x3f2c
+#define RLC_UCODE_DATA                                    0x3f30
+
+#define SRBM_SOFT_RESET                                   0xe60
+#       define SOFT_RESET_RLC                             (1 << 13)
+
+#define CP_INT_CNTL                                       0xc124
+#       define CNTX_BUSY_INT_ENABLE                       (1 << 19)
+#       define CNTX_EMPTY_INT_ENABLE                      (1 << 20)
+#       define SCRATCH_INT_ENABLE                         (1 << 25)
+#       define TIME_STAMP_INT_ENABLE                      (1 << 26)
+#       define IB2_INT_ENABLE                             (1 << 29)
+#       define IB1_INT_ENABLE                             (1 << 30)
+#       define RB_INT_ENABLE                              (1 << 31)
+#define CP_INT_STATUS                                     0xc128
+#       define SCRATCH_INT_STAT                           (1 << 25)
+#       define TIME_STAMP_INT_STAT                        (1 << 26)
+#       define IB2_INT_STAT                               (1 << 29)
+#       define IB1_INT_STAT                               (1 << 30)
+#       define RB_INT_STAT                                (1 << 31)
+
+#define GRBM_INT_CNTL                                     0x8060
+#       define RDERR_INT_ENABLE                           (1 << 0)
+#       define WAIT_COUNT_TIMEOUT_INT_ENABLE              (1 << 1)
+#       define GUI_IDLE_INT_ENABLE                        (1 << 19)
+
+#define INTERRUPT_CNTL                                    0x5468
+#       define IH_DUMMY_RD_OVERRIDE                       (1 << 0)
+#       define IH_DUMMY_RD_EN                             (1 << 1)
+#       define IH_REQ_NONSNOOP_EN                         (1 << 3)
+#       define GEN_IH_INT_EN                              (1 << 8)
+#define INTERRUPT_CNTL2                                   0x546c
+
+#define D1MODE_VBLANK_STATUS                              0x6534
+#define D2MODE_VBLANK_STATUS                              0x6d34
+#       define DxMODE_VBLANK_OCCURRED                     (1 << 0)
+#       define DxMODE_VBLANK_ACK                          (1 << 4)
+#       define DxMODE_VBLANK_STAT                         (1 << 12)
+#       define DxMODE_VBLANK_INTERRUPT                    (1 << 16)
+#       define DxMODE_VBLANK_INTERRUPT_TYPE               (1 << 17)
+#define D1MODE_VLINE_STATUS                               0x653c
+#define D2MODE_VLINE_STATUS                               0x6d3c
+#       define DxMODE_VLINE_OCCURRED                      (1 << 0)
+#       define DxMODE_VLINE_ACK                           (1 << 4)
+#       define DxMODE_VLINE_STAT                          (1 << 12)
+#       define DxMODE_VLINE_INTERRUPT                     (1 << 16)
+#       define DxMODE_VLINE_INTERRUPT_TYPE                (1 << 17)
+#define DxMODE_INT_MASK                                   0x6540
+#       define D1MODE_VBLANK_INT_MASK                     (1 << 0)
+#       define D1MODE_VLINE_INT_MASK                      (1 << 4)
+#       define D2MODE_VBLANK_INT_MASK                     (1 << 8)
+#       define D2MODE_VLINE_INT_MASK                      (1 << 12)
+#define DCE3_DISP_INTERRUPT_STATUS                        0x7ddc
+#       define DC_HPD1_INTERRUPT                          (1 << 18)
+#       define DC_HPD2_INTERRUPT                          (1 << 19)
+#define DISP_INTERRUPT_STATUS                             0x7edc
+#       define LB_D1_VLINE_INTERRUPT                      (1 << 2)
+#       define LB_D2_VLINE_INTERRUPT                      (1 << 3)
+#       define LB_D1_VBLANK_INTERRUPT                     (1 << 4)
+#       define LB_D2_VBLANK_INTERRUPT                     (1 << 5)
+#       define DACA_AUTODETECT_INTERRUPT                  (1 << 16)
+#       define DACB_AUTODETECT_INTERRUPT                  (1 << 17)
+#       define DC_HOT_PLUG_DETECT1_INTERRUPT              (1 << 18)
+#       define DC_HOT_PLUG_DETECT2_INTERRUPT              (1 << 19)
+#       define DC_I2C_SW_DONE_INTERRUPT                   (1 << 20)
+#       define DC_I2C_HW_DONE_INTERRUPT                   (1 << 21)
+#define DISP_INTERRUPT_STATUS_CONTINUE                    0x7ee8
+#define DCE3_DISP_INTERRUPT_STATUS_CONTINUE               0x7de8
+#       define DC_HPD4_INTERRUPT                          (1 << 14)
+#       define DC_HPD4_RX_INTERRUPT                       (1 << 15)
+#       define DC_HPD3_INTERRUPT                          (1 << 28)
+#       define DC_HPD1_RX_INTERRUPT                       (1 << 29)
+#       define DC_HPD2_RX_INTERRUPT                       (1 << 30)
+#define DCE3_DISP_INTERRUPT_STATUS_CONTINUE2              0x7dec
+#       define DC_HPD3_RX_INTERRUPT                       (1 << 0)
+#       define DIGA_DP_VID_STREAM_DISABLE_INTERRUPT       (1 << 1)
+#       define DIGA_DP_STEER_FIFO_OVERFLOW_INTERRUPT      (1 << 2)
+#       define DIGB_DP_VID_STREAM_DISABLE_INTERRUPT       (1 << 3)
+#       define DIGB_DP_STEER_FIFO_OVERFLOW_INTERRUPT      (1 << 4)
+#       define AUX1_SW_DONE_INTERRUPT                     (1 << 5)
+#       define AUX1_LS_DONE_INTERRUPT                     (1 << 6)
+#       define AUX2_SW_DONE_INTERRUPT                     (1 << 7)
+#       define AUX2_LS_DONE_INTERRUPT                     (1 << 8)
+#       define AUX3_SW_DONE_INTERRUPT                     (1 << 9)
+#       define AUX3_LS_DONE_INTERRUPT                     (1 << 10)
+#       define AUX4_SW_DONE_INTERRUPT                     (1 << 11)
+#       define AUX4_LS_DONE_INTERRUPT                     (1 << 12)
+#       define DIGA_DP_FAST_TRAINING_COMPLETE_INTERRUPT   (1 << 13)
+#       define DIGB_DP_FAST_TRAINING_COMPLETE_INTERRUPT   (1 << 14)
+/* DCE 3.2 */
+#       define AUX5_SW_DONE_INTERRUPT                     (1 << 15)
+#       define AUX5_LS_DONE_INTERRUPT                     (1 << 16)
+#       define AUX6_SW_DONE_INTERRUPT                     (1 << 17)
+#       define AUX6_LS_DONE_INTERRUPT                     (1 << 18)
+#       define DC_HPD5_INTERRUPT                          (1 << 19)
+#       define DC_HPD5_RX_INTERRUPT                       (1 << 20)
+#       define DC_HPD6_INTERRUPT                          (1 << 21)
+#       define DC_HPD6_RX_INTERRUPT                       (1 << 22)
+
+#define DACA_AUTO_DETECT_CONTROL                          0x7828
+#define DACB_AUTO_DETECT_CONTROL                          0x7a28
+#define DCE3_DACA_AUTO_DETECT_CONTROL                     0x7028
+#define DCE3_DACB_AUTO_DETECT_CONTROL                     0x7128
+#       define DACx_AUTODETECT_MODE(x)                    ((x) << 0)
+#       define DACx_AUTODETECT_MODE_NONE                  0
+#       define DACx_AUTODETECT_MODE_CONNECT               1
+#       define DACx_AUTODETECT_MODE_DISCONNECT            2
+#       define DACx_AUTODETECT_FRAME_TIME_COUNTER(x)      ((x) << 8)
+/* bit 18 = R/C, 17 = G/Y, 16 = B/Comp */
+#       define DACx_AUTODETECT_CHECK_MASK(x)              ((x) << 16)
+
+#define DCE3_DACA_AUTODETECT_INT_CONTROL                  0x7038
+#define DCE3_DACB_AUTODETECT_INT_CONTROL                  0x7138
+#define DACA_AUTODETECT_INT_CONTROL                       0x7838
+#define DACB_AUTODETECT_INT_CONTROL                       0x7a38
+#       define DACx_AUTODETECT_ACK                        (1 << 0)
+#       define DACx_AUTODETECT_INT_ENABLE                 (1 << 16)
+
+#define DC_HOT_PLUG_DETECT1_CONTROL                       0x7d00
+#define DC_HOT_PLUG_DETECT2_CONTROL                       0x7d10
+#define DC_HOT_PLUG_DETECT3_CONTROL                       0x7d24
+#       define DC_HOT_PLUG_DETECTx_EN                     (1 << 0)
+
+#define DC_HOT_PLUG_DETECT1_INT_STATUS                    0x7d04
+#define DC_HOT_PLUG_DETECT2_INT_STATUS                    0x7d14
+#define DC_HOT_PLUG_DETECT3_INT_STATUS                    0x7d28
+#       define DC_HOT_PLUG_DETECTx_INT_STATUS             (1 << 0)
+#       define DC_HOT_PLUG_DETECTx_SENSE                  (1 << 1)
+
+/* DCE 3.0 */
+#define DC_HPD1_INT_STATUS                                0x7d00
+#define DC_HPD2_INT_STATUS                                0x7d0c
+#define DC_HPD3_INT_STATUS                                0x7d18
+#define DC_HPD4_INT_STATUS                                0x7d24
+/* DCE 3.2 */
+#define DC_HPD5_INT_STATUS                                0x7dc0
+#define DC_HPD6_INT_STATUS                                0x7df4
+#       define DC_HPDx_INT_STATUS                         (1 << 0)
+#       define DC_HPDx_SENSE                              (1 << 1)
+#       define DC_HPDx_RX_INT_STATUS                      (1 << 8)
+
+#define DC_HOT_PLUG_DETECT1_INT_CONTROL                   0x7d08
+#define DC_HOT_PLUG_DETECT2_INT_CONTROL                   0x7d18
+#define DC_HOT_PLUG_DETECT3_INT_CONTROL                   0x7d2c
+#       define DC_HOT_PLUG_DETECTx_INT_ACK                (1 << 0)
+#       define DC_HOT_PLUG_DETECTx_INT_POLARITY           (1 << 8)
+#       define DC_HOT_PLUG_DETECTx_INT_EN                 (1 << 16)
+/* DCE 3.0 */
+#define DC_HPD1_INT_CONTROL                               0x7d04
+#define DC_HPD2_INT_CONTROL                               0x7d10
+#define DC_HPD3_INT_CONTROL                               0x7d1c
+#define DC_HPD4_INT_CONTROL                               0x7d28
+/* DCE 3.2 */
+#define DC_HPD5_INT_CONTROL                               0x7dc4
+#define DC_HPD6_INT_CONTROL                               0x7df8
+#       define DC_HPDx_INT_ACK                            (1 << 0)
+#       define DC_HPDx_INT_POLARITY                       (1 << 8)
+#       define DC_HPDx_INT_EN                             (1 << 16)
+#       define DC_HPDx_RX_INT_ACK                         (1 << 20)
+#       define DC_HPDx_RX_INT_EN                          (1 << 24)
+
+/* DCE 3.0 */
+#define DC_HPD1_CONTROL                                   0x7d08
+#define DC_HPD2_CONTROL                                   0x7d14
+#define DC_HPD3_CONTROL                                   0x7d20
+#define DC_HPD4_CONTROL                                   0x7d2c
+/* DCE 3.2 */
+#define DC_HPD5_CONTROL                                   0x7dc8
+#define DC_HPD6_CONTROL                                   0x7dfc
+#       define DC_HPDx_CONNECTION_TIMER(x)                ((x) << 0)
+#       define DC_HPDx_RX_INT_TIMER(x)                    ((x) << 16)
+/* DCE 3.2 */
+#       define DC_HPDx_EN                                 (1 << 28)
 
 /*
  * PM4
@@ -500,7 +708,6 @@
 #define	PACKET3_WAIT_REG_MEM				0x3C
 #define	PACKET3_MEM_WRITE				0x3D
 #define	PACKET3_INDIRECT_BUFFER				0x32
-#define	PACKET3_CP_INTERRUPT				0x40
 #define	PACKET3_SURFACE_SYNC				0x43
 #              define PACKET3_CB0_DEST_BASE_ENA    (1 << 6)
 #              define PACKET3_TC_ACTION_ENA        (1 << 23)
@@ -674,4 +881,5 @@
 #define		S_000E60_SOFT_RESET_TSC(x)		(((x) & 1) << 16)
 #define		S_000E60_SOFT_RESET_VMC(x)		(((x) & 1) << 17)
 
+#define R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL		0x5480
 #endif
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 224506a2..c938bb5 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -28,8 +28,6 @@
 #ifndef __RADEON_H__
 #define __RADEON_H__
 
-#include "radeon_object.h"
-
 /* TODO: Here are things that needs to be done :
  *	- surface allocator & initializer : (bit like scratch reg) should
  *	  initialize HDP_ stuff on RS600, R600, R700 hw, well anythings
@@ -67,6 +65,11 @@
 #include <linux/list.h>
 #include <linux/kref.h>
 
+#include <ttm/ttm_bo_api.h>
+#include <ttm/ttm_bo_driver.h>
+#include <ttm/ttm_placement.h>
+#include <ttm/ttm_module.h>
+
 #include "radeon_family.h"
 #include "radeon_mode.h"
 #include "radeon_reg.h"
@@ -85,6 +88,7 @@
 extern int radeon_testing;
 extern int radeon_connector_table;
 extern int radeon_tv;
+extern int radeon_new_pll;
 
 /*
  * Copy from radeon_drv.h so we don't have to include both and have conflicting
@@ -186,76 +190,62 @@
  * Tiling registers
  */
 struct radeon_surface_reg {
-	struct radeon_object *robj;
+	struct radeon_bo *bo;
 };
 
 #define RADEON_GEM_MAX_SURFACES 8
 
 /*
- * Radeon buffer.
+ * TTM.
  */
-struct radeon_object;
+struct radeon_mman {
+	struct ttm_bo_global_ref        bo_global_ref;
+	struct ttm_global_reference	mem_global_ref;
+	bool				mem_global_referenced;
+	struct ttm_bo_device		bdev;
+};
 
-struct radeon_object_list {
+struct radeon_bo {
+	/* Protected by gem.mutex */
+	struct list_head		list;
+	/* Protected by tbo.reserved */
+	u32				placements[3];
+	struct ttm_placement		placement;
+	struct ttm_buffer_object	tbo;
+	struct ttm_bo_kmap_obj		kmap;
+	unsigned			pin_count;
+	void				*kptr;
+	u32				tiling_flags;
+	u32				pitch;
+	int				surface_reg;
+	/* Constant after initialization */
+	struct radeon_device		*rdev;
+	struct drm_gem_object		*gobj;
+};
+
+struct radeon_bo_list {
 	struct list_head	list;
-	struct radeon_object	*robj;
+	struct radeon_bo	*bo;
 	uint64_t		gpu_offset;
 	unsigned		rdomain;
 	unsigned		wdomain;
-	uint32_t                tiling_flags;
+	u32			tiling_flags;
 };
 
-int radeon_object_init(struct radeon_device *rdev);
-void radeon_object_fini(struct radeon_device *rdev);
-int radeon_object_create(struct radeon_device *rdev,
-			 struct drm_gem_object *gobj,
-			 unsigned long size,
-			 bool kernel,
-			 uint32_t domain,
-			 bool interruptible,
-			 struct radeon_object **robj_ptr);
-int radeon_object_kmap(struct radeon_object *robj, void **ptr);
-void radeon_object_kunmap(struct radeon_object *robj);
-void radeon_object_unref(struct radeon_object **robj);
-int radeon_object_pin(struct radeon_object *robj, uint32_t domain,
-		      uint64_t *gpu_addr);
-void radeon_object_unpin(struct radeon_object *robj);
-int radeon_object_wait(struct radeon_object *robj);
-int radeon_object_busy_domain(struct radeon_object *robj, uint32_t *cur_placement);
-int radeon_object_evict_vram(struct radeon_device *rdev);
-int radeon_object_mmap(struct radeon_object *robj, uint64_t *offset);
-void radeon_object_force_delete(struct radeon_device *rdev);
-void radeon_object_list_add_object(struct radeon_object_list *lobj,
-				   struct list_head *head);
-int radeon_object_list_validate(struct list_head *head, void *fence);
-void radeon_object_list_unvalidate(struct list_head *head);
-void radeon_object_list_clean(struct list_head *head);
-int radeon_object_fbdev_mmap(struct radeon_object *robj,
-			     struct vm_area_struct *vma);
-unsigned long radeon_object_size(struct radeon_object *robj);
-void radeon_object_clear_surface_reg(struct radeon_object *robj);
-int radeon_object_check_tiling(struct radeon_object *robj, bool has_moved,
-			       bool force_drop);
-void radeon_object_set_tiling_flags(struct radeon_object *robj,
-				    uint32_t tiling_flags, uint32_t pitch);
-void radeon_object_get_tiling_flags(struct radeon_object *robj, uint32_t *tiling_flags, uint32_t *pitch);
-void radeon_bo_move_notify(struct ttm_buffer_object *bo,
-			   struct ttm_mem_reg *mem);
-void radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo);
 /*
  * GEM objects.
  */
 struct radeon_gem {
+	struct mutex		mutex;
 	struct list_head	objects;
 };
 
 int radeon_gem_init(struct radeon_device *rdev);
 void radeon_gem_fini(struct radeon_device *rdev);
 int radeon_gem_object_create(struct radeon_device *rdev, int size,
-			     int alignment, int initial_domain,
-			     bool discardable, bool kernel,
-			     bool interruptible,
-			     struct drm_gem_object **obj);
+				int alignment, int initial_domain,
+				bool discardable, bool kernel,
+				struct drm_gem_object **obj);
 int radeon_gem_object_pin(struct drm_gem_object *obj, uint32_t pin_domain,
 			  uint64_t *gpu_addr);
 void radeon_gem_object_unpin(struct drm_gem_object *obj);
@@ -271,7 +261,7 @@
 };
 
 struct radeon_gart_table_vram {
-	struct radeon_object		*robj;
+	struct radeon_bo		*robj;
 	volatile uint32_t		*ptr;
 };
 
@@ -352,11 +342,16 @@
 	bool		sw_int;
 	/* FIXME: use a define max crtc rather than hardcode it */
 	bool		crtc_vblank_int[2];
+	/* FIXME: use defines for max hpd/dacs */
+	bool            hpd[6];
+	spinlock_t sw_lock;
+	int sw_refcount;
 };
 
 int radeon_irq_kms_init(struct radeon_device *rdev);
 void radeon_irq_kms_fini(struct radeon_device *rdev);
-
+void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev);
+void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev);
 
 /*
  * CP & ring.
@@ -376,7 +371,7 @@
  */
 struct radeon_ib_pool {
 	struct mutex		mutex;
-	struct radeon_object	*robj;
+	struct radeon_bo	*robj;
 	struct list_head	scheduled_ibs;
 	struct radeon_ib	ibs[RADEON_IB_POOL_SIZE];
 	bool			ready;
@@ -384,7 +379,7 @@
 };
 
 struct radeon_cp {
-	struct radeon_object	*ring_obj;
+	struct radeon_bo	*ring_obj;
 	volatile uint32_t	*ring;
 	unsigned		rptr;
 	unsigned		wptr;
@@ -399,8 +394,25 @@
 	bool			ready;
 };
 
+/*
+ * R6xx+ IH ring
+ */
+struct r600_ih {
+	struct radeon_bo	*ring_obj;
+	volatile uint32_t	*ring;
+	unsigned		rptr;
+	unsigned		wptr;
+	unsigned		wptr_old;
+	unsigned		ring_size;
+	uint64_t		gpu_addr;
+	uint32_t		align_mask;
+	uint32_t		ptr_mask;
+	spinlock_t              lock;
+	bool                    enabled;
+};
+
 struct r600_blit {
-	struct radeon_object	*shader_obj;
+	struct radeon_bo	*shader_obj;
 	u64 shader_gpu_addr;
 	u32 vs_offset, ps_offset;
 	u32 state_offset;
@@ -430,8 +442,8 @@
  */
 struct radeon_cs_reloc {
 	struct drm_gem_object		*gobj;
-	struct radeon_object		*robj;
-	struct radeon_object_list	lobj;
+	struct radeon_bo		*robj;
+	struct radeon_bo_list		lobj;
 	uint32_t			handle;
 	uint32_t			flags;
 };
@@ -527,7 +539,7 @@
  * Writeback
  */
 struct radeon_wb {
-	struct radeon_object	*wb_obj;
+	struct radeon_bo	*wb_obj;
 	volatile uint32_t	*wb;
 	uint64_t		gpu_addr;
 };
@@ -639,6 +651,11 @@
 			       uint32_t offset, uint32_t obj_size);
 	int (*clear_surface_reg)(struct radeon_device *rdev, int reg);
 	void (*bandwidth_update)(struct radeon_device *rdev);
+	void (*hdp_flush)(struct radeon_device *rdev);
+	void (*hpd_init)(struct radeon_device *rdev);
+	void (*hpd_fini)(struct radeon_device *rdev);
+	bool (*hpd_sense)(struct radeon_device *rdev, enum radeon_hpd_id hpd);
+	void (*hpd_set_polarity)(struct radeon_device *rdev, enum radeon_hpd_id hpd);
 };
 
 /*
@@ -751,9 +768,9 @@
 	uint8_t				*bios;
 	bool				is_atom_bios;
 	uint16_t			bios_header_start;
-	struct radeon_object		*stollen_vga_memory;
+	struct radeon_bo		*stollen_vga_memory;
 	struct fb_info			*fbdev_info;
-	struct radeon_object		*fbdev_robj;
+	struct radeon_bo		*fbdev_rbo;
 	struct radeon_framebuffer	*fbdev_rfb;
 	/* Register mmio */
 	resource_size_t			rmmio_base;
@@ -791,8 +808,12 @@
 	struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES];
 	const struct firmware *me_fw;	/* all family ME firmware */
 	const struct firmware *pfp_fw;	/* r6/700 PFP firmware */
+	const struct firmware *rlc_fw;	/* r6/700 RLC firmware */
 	struct r600_blit r600_blit;
 	int msi_enabled; /* msi enabled */
+	struct r600_ih ih; /* r6/700 interrupt ring */
+	struct workqueue_struct *wq;
+	struct work_struct hotplug_work;
 };
 
 int radeon_device_init(struct radeon_device *rdev,
@@ -829,6 +850,10 @@
 	}
 }
 
+/*
+ * Cast helper
+ */
+#define to_radeon_fence(p) ((struct radeon_fence *)(p))
 
 /*
  * Registers read & write functions.
@@ -965,18 +990,24 @@
 #define radeon_get_engine_clock(rdev) (rdev)->asic->get_engine_clock((rdev))
 #define radeon_set_engine_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e))
 #define radeon_get_memory_clock(rdev) (rdev)->asic->get_memory_clock((rdev))
-#define radeon_set_memory_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e))
+#define radeon_set_memory_clock(rdev, e) (rdev)->asic->set_memory_clock((rdev), (e))
 #define radeon_set_pcie_lanes(rdev, l) (rdev)->asic->set_pcie_lanes((rdev), (l))
 #define radeon_set_clock_gating(rdev, e) (rdev)->asic->set_clock_gating((rdev), (e))
 #define radeon_set_surface_reg(rdev, r, f, p, o, s) ((rdev)->asic->set_surface_reg((rdev), (r), (f), (p), (o), (s)))
 #define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->clear_surface_reg((rdev), (r)))
 #define radeon_bandwidth_update(rdev) (rdev)->asic->bandwidth_update((rdev))
+#define radeon_hdp_flush(rdev) (rdev)->asic->hdp_flush((rdev))
+#define radeon_hpd_init(rdev) (rdev)->asic->hpd_init((rdev))
+#define radeon_hpd_fini(rdev) (rdev)->asic->hpd_fini((rdev))
+#define radeon_hpd_sense(rdev, hpd) (rdev)->asic->hpd_sense((rdev), (hpd))
+#define radeon_hpd_set_polarity(rdev, hpd) (rdev)->asic->hpd_set_polarity((rdev), (hpd))
 
 /* Common functions */
 extern int radeon_gart_table_vram_pin(struct radeon_device *rdev);
 extern int radeon_modeset_init(struct radeon_device *rdev);
 extern void radeon_modeset_fini(struct radeon_device *rdev);
 extern bool radeon_card_posted(struct radeon_device *rdev);
+extern bool radeon_boot_test_post_card(struct radeon_device *rdev);
 extern int radeon_clocks_init(struct radeon_device *rdev);
 extern void radeon_clocks_fini(struct radeon_device *rdev);
 extern void radeon_scratch_init(struct radeon_device *rdev);
@@ -984,6 +1015,7 @@
 extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data);
 extern void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable);
 extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
+extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain);
 
 /* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */
 struct r100_mc_save {
@@ -1021,7 +1053,7 @@
 extern void r100_vga_render_disable(struct radeon_device *rdev);
 extern int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
 						struct radeon_cs_packet *pkt,
-						struct radeon_object *robj);
+						struct radeon_bo *robj);
 extern int r100_cs_parse_packet0(struct radeon_cs_parser *p,
 				struct radeon_cs_packet *pkt,
 				const unsigned *auth, unsigned n,
@@ -1029,6 +1061,8 @@
 extern int r100_cs_packet_parse(struct radeon_cs_parser *p,
 				struct radeon_cs_packet *pkt,
 				unsigned idx);
+extern void r100_enable_bm(struct radeon_device *rdev);
+extern void r100_set_common_regs(struct radeon_device *rdev);
 
 /* rv200,rv250,rv280 */
 extern void r200_set_safe_registers(struct radeon_device *rdev);
@@ -1104,7 +1138,14 @@
 extern void r600_scratch_init(struct radeon_device *rdev);
 extern int r600_blit_init(struct radeon_device *rdev);
 extern void r600_blit_fini(struct radeon_device *rdev);
-extern int r600_cp_init_microcode(struct radeon_device *rdev);
+extern int r600_init_microcode(struct radeon_device *rdev);
 extern int r600_gpu_reset(struct radeon_device *rdev);
+/* r600 irq */
+extern int r600_irq_init(struct radeon_device *rdev);
+extern void r600_irq_fini(struct radeon_device *rdev);
+extern void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size);
+extern int r600_irq_set(struct radeon_device *rdev);
+
+#include "radeon_object.h"
 
 #endif
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index c18fbee..636116b 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -76,6 +76,12 @@
 void r100_bandwidth_update(struct radeon_device *rdev);
 void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
 int r100_ring_test(struct radeon_device *rdev);
+void r100_hdp_flush(struct radeon_device *rdev);
+void r100_hpd_init(struct radeon_device *rdev);
+void r100_hpd_fini(struct radeon_device *rdev);
+bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
+void r100_hpd_set_polarity(struct radeon_device *rdev,
+			   enum radeon_hpd_id hpd);
 
 static struct radeon_asic r100_asic = {
 	.init = &r100_init,
@@ -107,6 +113,11 @@
 	.set_surface_reg = r100_set_surface_reg,
 	.clear_surface_reg = r100_clear_surface_reg,
 	.bandwidth_update = &r100_bandwidth_update,
+	.hdp_flush = &r100_hdp_flush,
+	.hpd_init = &r100_hpd_init,
+	.hpd_fini = &r100_hpd_fini,
+	.hpd_sense = &r100_hpd_sense,
+	.hpd_set_polarity = &r100_hpd_set_polarity,
 };
 
 
@@ -162,6 +173,11 @@
 	.set_surface_reg = r100_set_surface_reg,
 	.clear_surface_reg = r100_clear_surface_reg,
 	.bandwidth_update = &r100_bandwidth_update,
+	.hdp_flush = &r100_hdp_flush,
+	.hpd_init = &r100_hpd_init,
+	.hpd_fini = &r100_hpd_fini,
+	.hpd_sense = &r100_hpd_sense,
+	.hpd_set_polarity = &r100_hpd_set_polarity,
 };
 
 /*
@@ -201,6 +217,11 @@
 	.set_surface_reg = r100_set_surface_reg,
 	.clear_surface_reg = r100_clear_surface_reg,
 	.bandwidth_update = &r100_bandwidth_update,
+	.hdp_flush = &r100_hdp_flush,
+	.hpd_init = &r100_hpd_init,
+	.hpd_fini = &r100_hpd_fini,
+	.hpd_sense = &r100_hpd_sense,
+	.hpd_set_polarity = &r100_hpd_set_polarity,
 };
 
 
@@ -245,6 +266,11 @@
 	.set_surface_reg = r100_set_surface_reg,
 	.clear_surface_reg = r100_clear_surface_reg,
 	.bandwidth_update = &r100_bandwidth_update,
+	.hdp_flush = &r100_hdp_flush,
+	.hpd_init = &r100_hpd_init,
+	.hpd_fini = &r100_hpd_fini,
+	.hpd_sense = &r100_hpd_sense,
+	.hpd_set_polarity = &r100_hpd_set_polarity,
 };
 
 
@@ -263,6 +289,12 @@
 uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg);
 void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
 void rs600_bandwidth_update(struct radeon_device *rdev);
+void rs600_hpd_init(struct radeon_device *rdev);
+void rs600_hpd_fini(struct radeon_device *rdev);
+bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
+void rs600_hpd_set_polarity(struct radeon_device *rdev,
+			    enum radeon_hpd_id hpd);
+
 static struct radeon_asic rs600_asic = {
 	.init = &rs600_init,
 	.fini = &rs600_fini,
@@ -291,6 +323,11 @@
 	.set_pcie_lanes = NULL,
 	.set_clock_gating = &radeon_atom_set_clock_gating,
 	.bandwidth_update = &rs600_bandwidth_update,
+	.hdp_flush = &r100_hdp_flush,
+	.hpd_init = &rs600_hpd_init,
+	.hpd_fini = &rs600_hpd_fini,
+	.hpd_sense = &rs600_hpd_sense,
+	.hpd_set_polarity = &rs600_hpd_set_polarity,
 };
 
 
@@ -334,6 +371,11 @@
 	.set_surface_reg = r100_set_surface_reg,
 	.clear_surface_reg = r100_clear_surface_reg,
 	.bandwidth_update = &rs690_bandwidth_update,
+	.hdp_flush = &r100_hdp_flush,
+	.hpd_init = &rs600_hpd_init,
+	.hpd_fini = &rs600_hpd_fini,
+	.hpd_sense = &rs600_hpd_sense,
+	.hpd_set_polarity = &rs600_hpd_set_polarity,
 };
 
 
@@ -381,6 +423,11 @@
 	.set_surface_reg = r100_set_surface_reg,
 	.clear_surface_reg = r100_clear_surface_reg,
 	.bandwidth_update = &rv515_bandwidth_update,
+	.hdp_flush = &r100_hdp_flush,
+	.hpd_init = &rs600_hpd_init,
+	.hpd_fini = &rs600_hpd_fini,
+	.hpd_sense = &rs600_hpd_sense,
+	.hpd_set_polarity = &rs600_hpd_set_polarity,
 };
 
 
@@ -419,6 +466,11 @@
 	.set_surface_reg = r100_set_surface_reg,
 	.clear_surface_reg = r100_clear_surface_reg,
 	.bandwidth_update = &rv515_bandwidth_update,
+	.hdp_flush = &r100_hdp_flush,
+	.hpd_init = &rs600_hpd_init,
+	.hpd_fini = &rs600_hpd_fini,
+	.hpd_sense = &rs600_hpd_sense,
+	.hpd_set_polarity = &rs600_hpd_set_polarity,
 };
 
 /*
@@ -455,6 +507,12 @@
 int r600_copy_blit(struct radeon_device *rdev,
 		   uint64_t src_offset, uint64_t dst_offset,
 		   unsigned num_pages, struct radeon_fence *fence);
+void r600_hdp_flush(struct radeon_device *rdev);
+void r600_hpd_init(struct radeon_device *rdev);
+void r600_hpd_fini(struct radeon_device *rdev);
+bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
+void r600_hpd_set_polarity(struct radeon_device *rdev,
+			   enum radeon_hpd_id hpd);
 
 static struct radeon_asic r600_asic = {
 	.init = &r600_init,
@@ -470,6 +528,7 @@
 	.ring_ib_execute = &r600_ring_ib_execute,
 	.irq_set = &r600_irq_set,
 	.irq_process = &r600_irq_process,
+	.get_vblank_counter = &rs600_get_vblank_counter,
 	.fence_ring_emit = &r600_fence_ring_emit,
 	.cs_parse = &r600_cs_parse,
 	.copy_blit = &r600_copy_blit,
@@ -484,6 +543,11 @@
 	.set_surface_reg = r600_set_surface_reg,
 	.clear_surface_reg = r600_clear_surface_reg,
 	.bandwidth_update = &rv515_bandwidth_update,
+	.hdp_flush = &r600_hdp_flush,
+	.hpd_init = &r600_hpd_init,
+	.hpd_fini = &r600_hpd_fini,
+	.hpd_sense = &r600_hpd_sense,
+	.hpd_set_polarity = &r600_hpd_set_polarity,
 };
 
 /*
@@ -509,6 +573,7 @@
 	.ring_ib_execute = &r600_ring_ib_execute,
 	.irq_set = &r600_irq_set,
 	.irq_process = &r600_irq_process,
+	.get_vblank_counter = &rs600_get_vblank_counter,
 	.fence_ring_emit = &r600_fence_ring_emit,
 	.cs_parse = &r600_cs_parse,
 	.copy_blit = &r600_copy_blit,
@@ -523,6 +588,11 @@
 	.set_surface_reg = r600_set_surface_reg,
 	.clear_surface_reg = r600_clear_surface_reg,
 	.bandwidth_update = &rv515_bandwidth_update,
+	.hdp_flush = &r600_hdp_flush,
+	.hpd_init = &r600_hpd_init,
+	.hpd_fini = &r600_hpd_fini,
+	.hpd_sense = &r600_hpd_sense,
+	.hpd_set_polarity = &r600_hpd_set_polarity,
 };
 
 #endif
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 2ed88a8..12a0c76 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -47,7 +47,8 @@
 			  int connector_type,
 			  struct radeon_i2c_bus_rec *i2c_bus,
 			  bool linkb, uint32_t igp_lane_info,
-			  uint16_t connector_object_id);
+			  uint16_t connector_object_id,
+			  struct radeon_hpd *hpd);
 
 /* from radeon_legacy_encoder.c */
 extern void
@@ -60,16 +61,16 @@
 	struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1;
 };
 
-static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device
-							   *dev, uint8_t id)
+static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev,
+							       uint8_t id)
 {
-	struct radeon_device *rdev = dev->dev_private;
 	struct atom_context *ctx = rdev->mode_info.atom_context;
-	ATOM_GPIO_I2C_ASSIGMENT gpio;
+	ATOM_GPIO_I2C_ASSIGMENT *gpio;
 	struct radeon_i2c_bus_rec i2c;
 	int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info);
 	struct _ATOM_GPIO_I2C_INFO *i2c_info;
 	uint16_t data_offset;
+	int i;
 
 	memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec));
 	i2c.valid = false;
@@ -78,34 +79,121 @@
 
 	i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
 
-	gpio = i2c_info->asGPIO_Info[id];
 
-	i2c.mask_clk_reg = le16_to_cpu(gpio.usClkMaskRegisterIndex) * 4;
-	i2c.mask_data_reg = le16_to_cpu(gpio.usDataMaskRegisterIndex) * 4;
-	i2c.put_clk_reg = le16_to_cpu(gpio.usClkEnRegisterIndex) * 4;
-	i2c.put_data_reg = le16_to_cpu(gpio.usDataEnRegisterIndex) * 4;
-	i2c.get_clk_reg = le16_to_cpu(gpio.usClkY_RegisterIndex) * 4;
-	i2c.get_data_reg = le16_to_cpu(gpio.usDataY_RegisterIndex) * 4;
-	i2c.a_clk_reg = le16_to_cpu(gpio.usClkA_RegisterIndex) * 4;
-	i2c.a_data_reg = le16_to_cpu(gpio.usDataA_RegisterIndex) * 4;
-	i2c.mask_clk_mask = (1 << gpio.ucClkMaskShift);
-	i2c.mask_data_mask = (1 << gpio.ucDataMaskShift);
-	i2c.put_clk_mask = (1 << gpio.ucClkEnShift);
-	i2c.put_data_mask = (1 << gpio.ucDataEnShift);
-	i2c.get_clk_mask = (1 << gpio.ucClkY_Shift);
-	i2c.get_data_mask = (1 << gpio.ucDataY_Shift);
-	i2c.a_clk_mask = (1 << gpio.ucClkA_Shift);
-	i2c.a_data_mask = (1 << gpio.ucDataA_Shift);
-	i2c.valid = true;
+	for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
+		gpio = &i2c_info->asGPIO_Info[i];
+
+		if (gpio->sucI2cId.ucAccess == id) {
+			i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
+			i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
+			i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
+			i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4;
+			i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4;
+			i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4;
+			i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4;
+			i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4;
+			i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
+			i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
+			i2c.en_clk_mask = (1 << gpio->ucClkEnShift);
+			i2c.en_data_mask = (1 << gpio->ucDataEnShift);
+			i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);
+			i2c.y_data_mask = (1 << gpio->ucDataY_Shift);
+			i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);
+			i2c.a_data_mask = (1 << gpio->ucDataA_Shift);
+
+			if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
+				i2c.hw_capable = true;
+			else
+				i2c.hw_capable = false;
+
+			if (gpio->sucI2cId.ucAccess == 0xa0)
+				i2c.mm_i2c = true;
+			else
+				i2c.mm_i2c = false;
+
+			i2c.i2c_id = gpio->sucI2cId.ucAccess;
+
+			i2c.valid = true;
+		}
+	}
 
 	return i2c;
 }
 
+static inline struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rdev,
+							u8 id)
+{
+	struct atom_context *ctx = rdev->mode_info.atom_context;
+	struct radeon_gpio_rec gpio;
+	int index = GetIndexIntoMasterTable(DATA, GPIO_Pin_LUT);
+	struct _ATOM_GPIO_PIN_LUT *gpio_info;
+	ATOM_GPIO_PIN_ASSIGNMENT *pin;
+	u16 data_offset, size;
+	int i, num_indices;
+
+	memset(&gpio, 0, sizeof(struct radeon_gpio_rec));
+	gpio.valid = false;
+
+	atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset);
+
+	gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset);
+
+	num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / sizeof(ATOM_GPIO_PIN_ASSIGNMENT);
+
+	for (i = 0; i < num_indices; i++) {
+		pin = &gpio_info->asGPIO_Pin[i];
+		if (id == pin->ucGPIO_ID) {
+			gpio.id = pin->ucGPIO_ID;
+			gpio.reg = pin->usGpioPin_AIndex * 4;
+			gpio.mask = (1 << pin->ucGpioPinBitShift);
+			gpio.valid = true;
+			break;
+		}
+	}
+
+	return gpio;
+}
+
+static struct radeon_hpd radeon_atom_get_hpd_info_from_gpio(struct radeon_device *rdev,
+							    struct radeon_gpio_rec *gpio)
+{
+	struct radeon_hpd hpd;
+	hpd.gpio = *gpio;
+	if (gpio->reg == AVIVO_DC_GPIO_HPD_A) {
+		switch(gpio->mask) {
+		case (1 << 0):
+			hpd.hpd = RADEON_HPD_1;
+			break;
+		case (1 << 8):
+			hpd.hpd = RADEON_HPD_2;
+			break;
+		case (1 << 16):
+			hpd.hpd = RADEON_HPD_3;
+			break;
+		case (1 << 24):
+			hpd.hpd = RADEON_HPD_4;
+			break;
+		case (1 << 26):
+			hpd.hpd = RADEON_HPD_5;
+			break;
+		case (1 << 28):
+			hpd.hpd = RADEON_HPD_6;
+			break;
+		default:
+			hpd.hpd = RADEON_HPD_NONE;
+			break;
+		}
+	} else
+		hpd.hpd = RADEON_HPD_NONE;
+	return hpd;
+}
+
 static bool radeon_atom_apply_quirks(struct drm_device *dev,
 				     uint32_t supported_device,
 				     int *connector_type,
 				     struct radeon_i2c_bus_rec *i2c_bus,
-				     uint16_t *line_mux)
+				     uint16_t *line_mux,
+				     struct radeon_hpd *hpd)
 {
 
 	/* Asus M2A-VM HDMI board lists the DVI port as HDMI */
@@ -135,6 +223,23 @@
 		}
 	}
 
+	/* HIS X1300 is DVI+VGA, not DVI+DVI */
+	if ((dev->pdev->device == 0x7146) &&
+	    (dev->pdev->subsystem_vendor == 0x17af) &&
+	    (dev->pdev->subsystem_device == 0x2058)) {
+		if (supported_device == ATOM_DEVICE_DFP1_SUPPORT)
+			return false;
+	}
+
+	/* Gigabyte X1300 is DVI+VGA, not DVI+DVI */
+	if ((dev->pdev->device == 0x7142) &&
+	    (dev->pdev->subsystem_vendor == 0x1458) &&
+	    (dev->pdev->subsystem_device == 0x2134)) {
+		if (supported_device == ATOM_DEVICE_DFP1_SUPPORT)
+			return false;
+	}
+
+
 	/* Funky macbooks */
 	if ((dev->pdev->device == 0x71C5) &&
 	    (dev->pdev->subsystem_vendor == 0x106b) &&
@@ -172,6 +277,15 @@
 		}
 	}
 
+	/* Acer laptop reports DVI-D as DVI-I */
+	if ((dev->pdev->device == 0x95c4) &&
+	    (dev->pdev->subsystem_vendor == 0x1025) &&
+	    (dev->pdev->subsystem_device == 0x013c)) {
+		if ((*connector_type == DRM_MODE_CONNECTOR_DVII) &&
+		    (supported_device == ATOM_DEVICE_DFP1_SUPPORT))
+			*connector_type = DRM_MODE_CONNECTOR_DVID;
+	}
+
 	return true;
 }
 
@@ -240,16 +354,18 @@
 	struct radeon_mode_info *mode_info = &rdev->mode_info;
 	struct atom_context *ctx = mode_info->atom_context;
 	int index = GetIndexIntoMasterTable(DATA, Object_Header);
-	uint16_t size, data_offset;
-	uint8_t frev, crev, line_mux = 0;
+	u16 size, data_offset;
+	u8 frev, crev;
 	ATOM_CONNECTOR_OBJECT_TABLE *con_obj;
 	ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj;
 	ATOM_OBJECT_HEADER *obj_header;
 	int i, j, path_size, device_support;
 	int connector_type;
-	uint16_t igp_lane_info, conn_id, connector_object_id;
+	u16 igp_lane_info, conn_id, connector_object_id;
 	bool linkb;
 	struct radeon_i2c_bus_rec ddc_bus;
+	struct radeon_gpio_rec gpio;
+	struct radeon_hpd hpd;
 
 	atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
 
@@ -276,7 +392,6 @@
 		path = (ATOM_DISPLAY_OBJECT_PATH *) addr;
 		path_size += le16_to_cpu(path->usSize);
 		linkb = false;
-
 		if (device_support & le16_to_cpu(path->usDeviceTag)) {
 			uint8_t con_obj_id, con_obj_num, con_obj_type;
 
@@ -377,10 +492,9 @@
 				}
 			}
 
-			/* look up gpio for ddc */
+			/* look up gpio for ddc, hpd */
 			if ((le16_to_cpu(path->usDeviceTag) &
-			     (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
-			    == 0) {
+			     (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) == 0) {
 				for (j = 0; j < con_obj->ucNumberOfObjects; j++) {
 					if (le16_to_cpu(path->usConnObjectId) ==
 					    le16_to_cpu(con_obj->asObjects[j].
@@ -394,21 +508,34 @@
 								 asObjects[j].
 								 usRecordOffset));
 						ATOM_I2C_RECORD *i2c_record;
+						ATOM_HPD_INT_RECORD *hpd_record;
+						ATOM_I2C_ID_CONFIG_ACCESS *i2c_config;
+						hpd.hpd = RADEON_HPD_NONE;
 
 						while (record->ucRecordType > 0
 						       && record->
 						       ucRecordType <=
 						       ATOM_MAX_OBJECT_RECORD_NUMBER) {
-							switch (record->
-								ucRecordType) {
+							switch (record->ucRecordType) {
 							case ATOM_I2C_RECORD_TYPE:
 								i2c_record =
-								    (ATOM_I2C_RECORD
-								     *) record;
-								line_mux =
-								    i2c_record->
-								    sucI2cId.
-								    bfI2C_LineMux;
+								    (ATOM_I2C_RECORD *)
+									record;
+								i2c_config =
+									(ATOM_I2C_ID_CONFIG_ACCESS *)
+									&i2c_record->sucI2cId;
+								ddc_bus = radeon_lookup_i2c_gpio(rdev,
+												 i2c_config->
+												 ucAccess);
+								break;
+							case ATOM_HPD_INT_RECORD_TYPE:
+								hpd_record =
+									(ATOM_HPD_INT_RECORD *)
+									record;
+								gpio = radeon_lookup_gpio(rdev,
+											  hpd_record->ucHPDIntGPIOID);
+								hpd = radeon_atom_get_hpd_info_from_gpio(rdev, &gpio);
+								hpd.plugged_state = hpd_record->ucPlugged_PinState;
 								break;
 							}
 							record =
@@ -421,24 +548,16 @@
 						break;
 					}
 				}
-			} else
-				line_mux = 0;
-
-			if ((le16_to_cpu(path->usDeviceTag) ==
-			     ATOM_DEVICE_TV1_SUPPORT)
-			    || (le16_to_cpu(path->usDeviceTag) ==
-				ATOM_DEVICE_TV2_SUPPORT)
-			    || (le16_to_cpu(path->usDeviceTag) ==
-				ATOM_DEVICE_CV_SUPPORT))
+			} else {
+				hpd.hpd = RADEON_HPD_NONE;
 				ddc_bus.valid = false;
-			else
-				ddc_bus = radeon_lookup_gpio(dev, line_mux);
+			}
 
 			conn_id = le16_to_cpu(path->usConnObjectId);
 
 			if (!radeon_atom_apply_quirks
 			    (dev, le16_to_cpu(path->usDeviceTag), &connector_type,
-			     &ddc_bus, &conn_id))
+			     &ddc_bus, &conn_id, &hpd))
 				continue;
 
 			radeon_add_atom_connector(dev,
@@ -447,7 +566,8 @@
 							      usDeviceTag),
 						  connector_type, &ddc_bus,
 						  linkb, igp_lane_info,
-						  connector_object_id);
+						  connector_object_id,
+						  &hpd);
 
 		}
 	}
@@ -502,6 +622,7 @@
 	uint16_t devices;
 	int connector_type;
 	struct radeon_i2c_bus_rec ddc_bus;
+	struct radeon_hpd hpd;
 };
 
 bool radeon_get_atom_connector_info_from_supported_devices_table(struct
@@ -517,7 +638,7 @@
 	uint16_t device_support;
 	uint8_t dac;
 	union atom_supported_devices *supported_devices;
-	int i, j;
+	int i, j, max_device;
 	struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE];
 
 	atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
@@ -527,7 +648,12 @@
 
 	device_support = le16_to_cpu(supported_devices->info.usDeviceSupport);
 
-	for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
+	if (frev > 1)
+		max_device = ATOM_MAX_SUPPORTED_DEVICE;
+	else
+		max_device = ATOM_MAX_SUPPORTED_DEVICE_INFO;
+
+	for (i = 0; i < max_device; i++) {
 		ATOM_CONNECTOR_INFO_I2C ci =
 		    supported_devices->info.asConnInfo[i];
 
@@ -553,22 +679,8 @@
 
 		dac = ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC;
 
-		if ((rdev->family == CHIP_RS690) ||
-		    (rdev->family == CHIP_RS740)) {
-			if ((i == ATOM_DEVICE_DFP2_INDEX)
-			    && (ci.sucI2cId.sbfAccess.bfI2C_LineMux == 2))
-				bios_connectors[i].line_mux =
-				    ci.sucI2cId.sbfAccess.bfI2C_LineMux + 1;
-			else if ((i == ATOM_DEVICE_DFP3_INDEX)
-				 && (ci.sucI2cId.sbfAccess.bfI2C_LineMux == 1))
-				bios_connectors[i].line_mux =
-				    ci.sucI2cId.sbfAccess.bfI2C_LineMux + 1;
-			else
-				bios_connectors[i].line_mux =
-				    ci.sucI2cId.sbfAccess.bfI2C_LineMux;
-		} else
-			bios_connectors[i].line_mux =
-			    ci.sucI2cId.sbfAccess.bfI2C_LineMux;
+		bios_connectors[i].line_mux =
+			ci.sucI2cId.ucAccess;
 
 		/* give tv unique connector ids */
 		if (i == ATOM_DEVICE_TV1_INDEX) {
@@ -582,8 +694,30 @@
 			bios_connectors[i].line_mux = 52;
 		} else
 			bios_connectors[i].ddc_bus =
-			    radeon_lookup_gpio(dev,
-					       bios_connectors[i].line_mux);
+			    radeon_lookup_i2c_gpio(rdev,
+						   bios_connectors[i].line_mux);
+
+		if ((crev > 1) && (frev > 1)) {
+			u8 isb = supported_devices->info_2d1.asIntSrcInfo[i].ucIntSrcBitmap;
+			switch (isb) {
+			case 0x4:
+				bios_connectors[i].hpd.hpd = RADEON_HPD_1;
+				break;
+			case 0xa:
+				bios_connectors[i].hpd.hpd = RADEON_HPD_2;
+				break;
+			default:
+				bios_connectors[i].hpd.hpd = RADEON_HPD_NONE;
+				break;
+			}
+		} else {
+			if (i == ATOM_DEVICE_DFP1_INDEX)
+				bios_connectors[i].hpd.hpd = RADEON_HPD_1;
+			else if (i == ATOM_DEVICE_DFP2_INDEX)
+				bios_connectors[i].hpd.hpd = RADEON_HPD_2;
+			else
+				bios_connectors[i].hpd.hpd = RADEON_HPD_NONE;
+		}
 
 		/* Always set the connector type to VGA for CRT1/CRT2. if they are
 		 * shared with a DVI port, we'll pick up the DVI connector when we
@@ -595,7 +729,8 @@
 
 		if (!radeon_atom_apply_quirks
 		    (dev, (1 << i), &bios_connectors[i].connector_type,
-		     &bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux))
+		     &bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux,
+		     &bios_connectors[i].hpd))
 			continue;
 
 		bios_connectors[i].valid = true;
@@ -617,9 +752,9 @@
 	}
 
 	/* combine shared connectors */
-	for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
+	for (i = 0; i < max_device; i++) {
 		if (bios_connectors[i].valid) {
-			for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) {
+			for (j = 0; j < max_device; j++) {
 				if (bios_connectors[j].valid && (i != j)) {
 					if (bios_connectors[i].line_mux ==
 					    bios_connectors[j].line_mux) {
@@ -643,6 +778,10 @@
 							bios_connectors[i].
 							    connector_type =
 							    DRM_MODE_CONNECTOR_DVII;
+							if (bios_connectors[j].devices &
+							    (ATOM_DEVICE_DFP_SUPPORT))
+								bios_connectors[i].hpd =
+									bios_connectors[j].hpd;
 							bios_connectors[j].
 							    valid = false;
 						}
@@ -653,7 +792,7 @@
 	}
 
 	/* add the connectors */
-	for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
+	for (i = 0; i < max_device; i++) {
 		if (bios_connectors[i].valid) {
 			uint16_t connector_object_id =
 				atombios_get_connector_object_id(dev,
@@ -666,7 +805,8 @@
 						  connector_type,
 						  &bios_connectors[i].ddc_bus,
 						  false, 0,
-						  connector_object_id);
+						  connector_object_id,
+						  &bios_connectors[i].hpd);
 		}
 	}
 
@@ -731,7 +871,8 @@
 			 * pre-DCE 3.0 r6xx hardware.  This might need to be adjusted per
 			 * family.
 			 */
-			p1pll->pll_out_min = 64800;
+			if (!radeon_new_pll)
+				p1pll->pll_out_min = 64800;
 		}
 
 		p1pll->pll_in_min =
@@ -861,6 +1002,7 @@
 	struct _ATOM_SPREAD_SPECTRUM_INFO *ss_info;
 	uint8_t frev, crev;
 	struct radeon_atom_ss *ss = NULL;
+	int i;
 
 	if (id > ATOM_MAX_SS_ENTRY)
 		return NULL;
@@ -878,12 +1020,17 @@
 		if (!ss)
 			return NULL;
 
-		ss->percentage = le16_to_cpu(ss_info->asSS_Info[id].usSpreadSpectrumPercentage);
-		ss->type = ss_info->asSS_Info[id].ucSpreadSpectrumType;
-		ss->step = ss_info->asSS_Info[id].ucSS_Step;
-		ss->delay = ss_info->asSS_Info[id].ucSS_Delay;
-		ss->range = ss_info->asSS_Info[id].ucSS_Range;
-		ss->refdiv = ss_info->asSS_Info[id].ucRecommendedRef_Div;
+		for (i = 0; i < ATOM_MAX_SS_ENTRY; i++) {
+			if (ss_info->asSS_Info[i].ucSS_Id == id) {
+				ss->percentage =
+					le16_to_cpu(ss_info->asSS_Info[i].usSpreadSpectrumPercentage);
+				ss->type = ss_info->asSS_Info[i].ucSpreadSpectrumType;
+				ss->step = ss_info->asSS_Info[i].ucSS_Step;
+				ss->delay = ss_info->asSS_Info[i].ucSS_Delay;
+				ss->range = ss_info->asSS_Info[i].ucSS_Range;
+				ss->refdiv = ss_info->asSS_Info[i].ucRecommendedRef_Div;
+			}
+		}
 	}
 	return ss;
 }
@@ -901,7 +1048,7 @@
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_mode_info *mode_info = &rdev->mode_info;
 	int index = GetIndexIntoMasterTable(DATA, LVDS_Info);
-	uint16_t data_offset;
+	uint16_t data_offset, misc;
 	union lvds_info *lvds_info;
 	uint8_t frev, crev;
 	struct radeon_encoder_atom_dig *lvds = NULL;
@@ -940,6 +1087,19 @@
 		lvds->panel_pwr_delay =
 		    le16_to_cpu(lvds_info->info.usOffDelayInMs);
 		lvds->lvds_misc = lvds_info->info.ucLVDS_Misc;
+
+		misc = le16_to_cpu(lvds_info->info.sLCDTiming.susModeMiscInfo.usAccess);
+		if (misc & ATOM_VSYNC_POLARITY)
+			lvds->native_mode.flags |= DRM_MODE_FLAG_NVSYNC;
+		if (misc & ATOM_HSYNC_POLARITY)
+			lvds->native_mode.flags |= DRM_MODE_FLAG_NHSYNC;
+		if (misc & ATOM_COMPOSITESYNC)
+			lvds->native_mode.flags |= DRM_MODE_FLAG_CSYNC;
+		if (misc & ATOM_INTERLACE)
+			lvds->native_mode.flags |= DRM_MODE_FLAG_INTERLACE;
+		if (misc & ATOM_DOUBLE_CLOCK_MODE)
+			lvds->native_mode.flags |= DRM_MODE_FLAG_DBLSCAN;
+
 		/* set crtc values */
 		drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V);
 
diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c
index 10bd50a..4ddfd4b 100644
--- a/drivers/gpu/drm/radeon/radeon_benchmark.c
+++ b/drivers/gpu/drm/radeon/radeon_benchmark.c
@@ -29,8 +29,8 @@
 void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize,
 			   unsigned sdomain, unsigned ddomain)
 {
-	struct radeon_object *dobj = NULL;
-	struct radeon_object *sobj = NULL;
+	struct radeon_bo *dobj = NULL;
+	struct radeon_bo *sobj = NULL;
 	struct radeon_fence *fence = NULL;
 	uint64_t saddr, daddr;
 	unsigned long start_jiffies;
@@ -41,19 +41,27 @@
 
 	size = bsize;
 	n = 1024;
-	r = radeon_object_create(rdev, NULL, size, true, sdomain, false, &sobj);
+	r = radeon_bo_create(rdev, NULL, size, true, sdomain, &sobj);
 	if (r) {
 		goto out_cleanup;
 	}
-	r = radeon_object_pin(sobj, sdomain, &saddr);
+	r = radeon_bo_reserve(sobj, false);
+	if (unlikely(r != 0))
+		goto out_cleanup;
+	r = radeon_bo_pin(sobj, sdomain, &saddr);
+	radeon_bo_unreserve(sobj);
 	if (r) {
 		goto out_cleanup;
 	}
-	r = radeon_object_create(rdev, NULL, size, true, ddomain, false, &dobj);
+	r = radeon_bo_create(rdev, NULL, size, true, ddomain, &dobj);
 	if (r) {
 		goto out_cleanup;
 	}
-	r = radeon_object_pin(dobj, ddomain, &daddr);
+	r = radeon_bo_reserve(dobj, false);
+	if (unlikely(r != 0))
+		goto out_cleanup;
+	r = radeon_bo_pin(dobj, ddomain, &daddr);
+	radeon_bo_unreserve(dobj);
 	if (r) {
 		goto out_cleanup;
 	}
@@ -109,12 +117,20 @@
 	}
 out_cleanup:
 	if (sobj) {
-		radeon_object_unpin(sobj);
-		radeon_object_unref(&sobj);
+		r = radeon_bo_reserve(sobj, false);
+		if (likely(r == 0)) {
+			radeon_bo_unpin(sobj);
+			radeon_bo_unreserve(sobj);
+		}
+		radeon_bo_unref(&sobj);
 	}
 	if (dobj) {
-		radeon_object_unpin(dobj);
-		radeon_object_unref(&dobj);
+		r = radeon_bo_reserve(dobj, false);
+		if (likely(r == 0)) {
+			radeon_bo_unpin(dobj);
+			radeon_bo_unreserve(dobj);
+		}
+		radeon_bo_unref(&dobj);
 	}
 	if (fence) {
 		radeon_fence_unref(&fence);
diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c
index a813541..b062109 100644
--- a/drivers/gpu/drm/radeon/radeon_clocks.c
+++ b/drivers/gpu/drm/radeon/radeon_clocks.c
@@ -44,6 +44,10 @@
 
 	ref_div =
 	    RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK;
+
+	if (ref_div == 0)
+		return 0;
+
 	sclk = fb_div / ref_div;
 
 	post_div = RREG32_PLL(RADEON_SCLK_CNTL) & RADEON_SCLK_SRC_SEL_MASK;
@@ -70,6 +74,10 @@
 
 	ref_div =
 	    RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK;
+
+	if (ref_div == 0)
+		return 0;
+
 	mclk = fb_div / ref_div;
 
 	post_div = RREG32_PLL(RADEON_MCLK_CNTL) & 0x7;
@@ -98,8 +106,19 @@
 		ret = radeon_combios_get_clock_info(dev);
 
 	if (ret) {
-		if (p1pll->reference_div < 2)
-			p1pll->reference_div = 12;
+		if (p1pll->reference_div < 2) {
+			if (!ASIC_IS_AVIVO(rdev)) {
+				u32 tmp = RREG32_PLL(RADEON_PPLL_REF_DIV);
+				if (ASIC_IS_R300(rdev))
+					p1pll->reference_div =
+						(tmp & R300_PPLL_REF_DIV_ACC_MASK) >> R300_PPLL_REF_DIV_ACC_SHIFT;
+				else
+					p1pll->reference_div = tmp & RADEON_PPLL_REF_DIV_MASK;
+				if (p1pll->reference_div < 2)
+					p1pll->reference_div = 12;
+			} else
+				p1pll->reference_div = 12;
+		}
 		if (p2pll->reference_div < 2)
 			p2pll->reference_div = 12;
 		if (rdev->family < CHIP_RS600) {
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
index 5253cbf..c5021a3 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -50,7 +50,8 @@
 			    uint32_t supported_device,
 			    int connector_type,
 			    struct radeon_i2c_bus_rec *i2c_bus,
-			    uint16_t connector_object_id);
+			    uint16_t connector_object_id,
+			    struct radeon_hpd *hpd);
 
 /* from radeon_legacy_encoder.c */
 extern void
@@ -442,39 +443,71 @@
 
 }
 
-struct radeon_i2c_bus_rec combios_setup_i2c_bus(int ddc_line)
+static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rdev,
+						       int ddc_line)
 {
 	struct radeon_i2c_bus_rec i2c;
 
-	i2c.mask_clk_mask = RADEON_GPIO_EN_1;
-	i2c.mask_data_mask = RADEON_GPIO_EN_0;
-	i2c.a_clk_mask = RADEON_GPIO_A_1;
-	i2c.a_data_mask = RADEON_GPIO_A_0;
-	i2c.put_clk_mask = RADEON_GPIO_EN_1;
-	i2c.put_data_mask = RADEON_GPIO_EN_0;
-	i2c.get_clk_mask = RADEON_GPIO_Y_1;
-	i2c.get_data_mask = RADEON_GPIO_Y_0;
-	if ((ddc_line == RADEON_LCD_GPIO_MASK) ||
-	    (ddc_line == RADEON_MDGPIO_EN_REG)) {
-		i2c.mask_clk_reg = ddc_line;
-		i2c.mask_data_reg = ddc_line;
-		i2c.a_clk_reg = ddc_line;
-		i2c.a_data_reg = ddc_line;
-		i2c.put_clk_reg = ddc_line;
-		i2c.put_data_reg = ddc_line;
-		i2c.get_clk_reg = ddc_line + 4;
-		i2c.get_data_reg = ddc_line + 4;
+	if (ddc_line == RADEON_GPIOPAD_MASK) {
+		i2c.mask_clk_reg = RADEON_GPIOPAD_MASK;
+		i2c.mask_data_reg = RADEON_GPIOPAD_MASK;
+		i2c.a_clk_reg = RADEON_GPIOPAD_A;
+		i2c.a_data_reg = RADEON_GPIOPAD_A;
+		i2c.en_clk_reg = RADEON_GPIOPAD_EN;
+		i2c.en_data_reg = RADEON_GPIOPAD_EN;
+		i2c.y_clk_reg = RADEON_GPIOPAD_Y;
+		i2c.y_data_reg = RADEON_GPIOPAD_Y;
+	} else if (ddc_line == RADEON_MDGPIO_MASK) {
+		i2c.mask_clk_reg = RADEON_MDGPIO_MASK;
+		i2c.mask_data_reg = RADEON_MDGPIO_MASK;
+		i2c.a_clk_reg = RADEON_MDGPIO_A;
+		i2c.a_data_reg = RADEON_MDGPIO_A;
+		i2c.en_clk_reg = RADEON_MDGPIO_EN;
+		i2c.en_data_reg = RADEON_MDGPIO_EN;
+		i2c.y_clk_reg = RADEON_MDGPIO_Y;
+		i2c.y_data_reg = RADEON_MDGPIO_Y;
 	} else {
+		i2c.mask_clk_mask = RADEON_GPIO_EN_1;
+		i2c.mask_data_mask = RADEON_GPIO_EN_0;
+		i2c.a_clk_mask = RADEON_GPIO_A_1;
+		i2c.a_data_mask = RADEON_GPIO_A_0;
+		i2c.en_clk_mask = RADEON_GPIO_EN_1;
+		i2c.en_data_mask = RADEON_GPIO_EN_0;
+		i2c.y_clk_mask = RADEON_GPIO_Y_1;
+		i2c.y_data_mask = RADEON_GPIO_Y_0;
+
 		i2c.mask_clk_reg = ddc_line;
 		i2c.mask_data_reg = ddc_line;
 		i2c.a_clk_reg = ddc_line;
 		i2c.a_data_reg = ddc_line;
-		i2c.put_clk_reg = ddc_line;
-		i2c.put_data_reg = ddc_line;
-		i2c.get_clk_reg = ddc_line;
-		i2c.get_data_reg = ddc_line;
+		i2c.en_clk_reg = ddc_line;
+		i2c.en_data_reg = ddc_line;
+		i2c.y_clk_reg = ddc_line;
+		i2c.y_data_reg = ddc_line;
 	}
 
+	if (rdev->family < CHIP_R200)
+		i2c.hw_capable = false;
+	else {
+		switch (ddc_line) {
+		case RADEON_GPIO_VGA_DDC:
+		case RADEON_GPIO_DVI_DDC:
+			i2c.hw_capable = true;
+			break;
+		case RADEON_GPIO_MONID:
+			/* hw i2c on RADEON_GPIO_MONID doesn't seem to work
+			 * reliably on some pre-r4xx hardware; not sure why.
+			 */
+			i2c.hw_capable = false;
+			break;
+		default:
+			i2c.hw_capable = false;
+			break;
+		}
+	}
+	i2c.mm_i2c = false;
+	i2c.i2c_id = 0;
+
 	if (ddc_line)
 		i2c.valid = true;
 	else
@@ -495,7 +528,7 @@
 	uint16_t sclk, mclk;
 
 	if (rdev->bios == NULL)
-		return NULL;
+		return false;
 
 	pll_info = combios_get_table_offset(dev, COMBIOS_PLL_INFO_TABLE);
 	if (pll_info) {
@@ -993,8 +1026,8 @@
 	{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},	/* CHIP_R420  */
 	{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},	/* CHIP_R423  */
 	{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},	/* CHIP_RV410 */
-	{{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},	/* CHIP_RS400 */
-	{{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},	/* CHIP_RS480 */
+	{ {0, 0}, {0, 0}, {0, 0}, {0, 0} },	/* CHIP_RS400 */
+	{ {0, 0}, {0, 0}, {0, 0}, {0, 0} },	/* CHIP_RS480 */
 };
 
 bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
@@ -1028,7 +1061,6 @@
 	tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
 
 	if (tmds_info) {
-
 		ver = RBIOS8(tmds_info);
 		DRM_INFO("DFP table revision: %d\n", ver);
 		if (ver == 3) {
@@ -1063,51 +1095,139 @@
 					  tmds->tmds_pll[i].value);
 			}
 		}
-	} else
+	} else {
 		DRM_INFO("No TMDS info found in BIOS\n");
+		return false;
+	}
 	return true;
 }
 
-struct radeon_encoder_int_tmds *radeon_combios_get_tmds_info(struct radeon_encoder *encoder)
-{
-	struct radeon_encoder_int_tmds *tmds = NULL;
-	bool ret;
-
-	tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
-
-	if (!tmds)
-		return NULL;
-
-	ret = radeon_legacy_get_tmds_info_from_combios(encoder, tmds);
-	if (ret == false)
-		radeon_legacy_get_tmds_info_from_table(encoder, tmds);
-
-	return tmds;
-}
-
-void radeon_combios_get_ext_tmds_info(struct radeon_encoder *encoder)
+bool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder,
+						struct radeon_encoder_ext_tmds *tmds)
 {
 	struct drm_device *dev = encoder->base.dev;
 	struct radeon_device *rdev = dev->dev_private;
-	uint16_t ext_tmds_info;
-	uint8_t ver;
+	struct radeon_i2c_bus_rec i2c_bus;
+
+	/* default for macs */
+	i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
+	tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
+
+	/* XXX some macs have duallink chips */
+	switch (rdev->mode_info.connector_table) {
+	case CT_POWERBOOK_EXTERNAL:
+	case CT_MINI_EXTERNAL:
+	default:
+		tmds->dvo_chip = DVO_SIL164;
+		tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */
+		break;
+	}
+
+	return true;
+}
+
+bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder,
+						  struct radeon_encoder_ext_tmds *tmds)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct radeon_device *rdev = dev->dev_private;
+	uint16_t offset;
+	uint8_t ver, id, blocks, clk, data;
+	int i;
+	enum radeon_combios_ddc gpio;
+	struct radeon_i2c_bus_rec i2c_bus;
 
 	if (rdev->bios == NULL)
-		return;
+		return false;
 
-	ext_tmds_info =
-	    combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
-	if (ext_tmds_info) {
-		ver = RBIOS8(ext_tmds_info);
-		DRM_INFO("External TMDS Table revision: %d\n", ver);
-		// TODO
+	tmds->i2c_bus = NULL;
+	if (rdev->flags & RADEON_IS_IGP) {
+		offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE);
+		if (offset) {
+			ver = RBIOS8(offset);
+			DRM_INFO("GPIO Table revision: %d\n", ver);
+			blocks = RBIOS8(offset + 2);
+			for (i = 0; i < blocks; i++) {
+				id = RBIOS8(offset + 3 + (i * 5) + 0);
+				if (id == 136) {
+					clk = RBIOS8(offset + 3 + (i * 5) + 3);
+					data = RBIOS8(offset + 3 + (i * 5) + 4);
+					i2c_bus.valid = true;
+					i2c_bus.mask_clk_mask = (1 << clk);
+					i2c_bus.mask_data_mask = (1 << data);
+					i2c_bus.a_clk_mask = (1 << clk);
+					i2c_bus.a_data_mask = (1 << data);
+					i2c_bus.en_clk_mask = (1 << clk);
+					i2c_bus.en_data_mask = (1 << data);
+					i2c_bus.y_clk_mask = (1 << clk);
+					i2c_bus.y_data_mask = (1 << data);
+					i2c_bus.mask_clk_reg = RADEON_GPIOPAD_MASK;
+					i2c_bus.mask_data_reg = RADEON_GPIOPAD_MASK;
+					i2c_bus.a_clk_reg = RADEON_GPIOPAD_A;
+					i2c_bus.a_data_reg = RADEON_GPIOPAD_A;
+					i2c_bus.en_clk_reg = RADEON_GPIOPAD_EN;
+					i2c_bus.en_data_reg = RADEON_GPIOPAD_EN;
+					i2c_bus.y_clk_reg = RADEON_GPIOPAD_Y;
+					i2c_bus.y_data_reg = RADEON_GPIOPAD_Y;
+					tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
+					tmds->dvo_chip = DVO_SIL164;
+					tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */
+					break;
+				}
+			}
+		}
+	} else {
+		offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
+		if (offset) {
+			ver = RBIOS8(offset);
+			DRM_INFO("External TMDS Table revision: %d\n", ver);
+			tmds->slave_addr = RBIOS8(offset + 4 + 2);
+			tmds->slave_addr >>= 1; /* 7 bit addressing */
+			gpio = RBIOS8(offset + 4 + 3);
+			switch (gpio) {
+			case DDC_MONID:
+				i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
+				tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
+				break;
+			case DDC_DVI:
+				i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+				tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
+				break;
+			case DDC_VGA:
+				i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+				tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
+				break;
+			case DDC_CRT2:
+				/* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */
+				if (rdev->family >= CHIP_R300)
+					i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
+				else
+					i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
+				tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
+				break;
+			case DDC_LCD: /* MM i2c */
+				DRM_ERROR("MM i2c requires hw i2c engine\n");
+				break;
+			default:
+				DRM_ERROR("Unsupported gpio %d\n", gpio);
+				break;
+			}
+		}
 	}
+
+	if (!tmds->i2c_bus) {
+		DRM_INFO("No valid Ext TMDS info found in BIOS\n");
+		return false;
+	}
+
+	return true;
 }
 
 bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
 {
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_i2c_bus_rec ddc_i2c;
+	struct radeon_hpd hpd;
 
 	rdev->mode_info.connector_table = radeon_connector_table;
 	if (rdev->mode_info.connector_table == CT_NONE) {
@@ -1168,7 +1288,8 @@
 		/* these are the most common settings */
 		if (rdev->flags & RADEON_SINGLE_CRTC) {
 			/* VGA - primary dac */
-			ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+			ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+			hpd.hpd = RADEON_HPD_NONE;
 			radeon_add_legacy_encoder(dev,
 						  radeon_get_encoder_id(dev,
 									ATOM_DEVICE_CRT1_SUPPORT,
@@ -1178,10 +1299,12 @@
 						    ATOM_DEVICE_CRT1_SUPPORT,
 						    DRM_MODE_CONNECTOR_VGA,
 						    &ddc_i2c,
-						    CONNECTOR_OBJECT_ID_VGA);
+						    CONNECTOR_OBJECT_ID_VGA,
+						    &hpd);
 		} else if (rdev->flags & RADEON_IS_MOBILITY) {
 			/* LVDS */
-			ddc_i2c = combios_setup_i2c_bus(RADEON_LCD_GPIO_MASK);
+			ddc_i2c = combios_setup_i2c_bus(rdev, 0);
+			hpd.hpd = RADEON_HPD_NONE;
 			radeon_add_legacy_encoder(dev,
 						  radeon_get_encoder_id(dev,
 									ATOM_DEVICE_LCD1_SUPPORT,
@@ -1191,10 +1314,12 @@
 						    ATOM_DEVICE_LCD1_SUPPORT,
 						    DRM_MODE_CONNECTOR_LVDS,
 						    &ddc_i2c,
-						    CONNECTOR_OBJECT_ID_LVDS);
+						    CONNECTOR_OBJECT_ID_LVDS,
+						    &hpd);
 
 			/* VGA - primary dac */
-			ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+			ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+			hpd.hpd = RADEON_HPD_NONE;
 			radeon_add_legacy_encoder(dev,
 						  radeon_get_encoder_id(dev,
 									ATOM_DEVICE_CRT1_SUPPORT,
@@ -1204,10 +1329,12 @@
 						    ATOM_DEVICE_CRT1_SUPPORT,
 						    DRM_MODE_CONNECTOR_VGA,
 						    &ddc_i2c,
-						    CONNECTOR_OBJECT_ID_VGA);
+						    CONNECTOR_OBJECT_ID_VGA,
+						    &hpd);
 		} else {
 			/* DVI-I - tv dac, int tmds */
-			ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+			ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+			hpd.hpd = RADEON_HPD_1;
 			radeon_add_legacy_encoder(dev,
 						  radeon_get_encoder_id(dev,
 									ATOM_DEVICE_DFP1_SUPPORT,
@@ -1223,10 +1350,12 @@
 						    ATOM_DEVICE_CRT2_SUPPORT,
 						    DRM_MODE_CONNECTOR_DVII,
 						    &ddc_i2c,
-						    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
+						    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
+						    &hpd);
 
 			/* VGA - primary dac */
-			ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+			ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+			hpd.hpd = RADEON_HPD_NONE;
 			radeon_add_legacy_encoder(dev,
 						  radeon_get_encoder_id(dev,
 									ATOM_DEVICE_CRT1_SUPPORT,
@@ -1236,11 +1365,14 @@
 						    ATOM_DEVICE_CRT1_SUPPORT,
 						    DRM_MODE_CONNECTOR_VGA,
 						    &ddc_i2c,
-						    CONNECTOR_OBJECT_ID_VGA);
+						    CONNECTOR_OBJECT_ID_VGA,
+						    &hpd);
 		}
 
 		if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) {
 			/* TV - tv dac */
+			ddc_i2c.valid = false;
+			hpd.hpd = RADEON_HPD_NONE;
 			radeon_add_legacy_encoder(dev,
 						  radeon_get_encoder_id(dev,
 									ATOM_DEVICE_TV1_SUPPORT,
@@ -1250,14 +1382,16 @@
 						    ATOM_DEVICE_TV1_SUPPORT,
 						    DRM_MODE_CONNECTOR_SVIDEO,
 						    &ddc_i2c,
-						    CONNECTOR_OBJECT_ID_SVIDEO);
+						    CONNECTOR_OBJECT_ID_SVIDEO,
+						    &hpd);
 		}
 		break;
 	case CT_IBOOK:
 		DRM_INFO("Connector Table: %d (ibook)\n",
 			 rdev->mode_info.connector_table);
 		/* LVDS */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_LCD1_SUPPORT,
@@ -1265,9 +1399,11 @@
 					  ATOM_DEVICE_LCD1_SUPPORT);
 		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
 					    DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_LVDS);
+					    CONNECTOR_OBJECT_ID_LVDS,
+					    &hpd);
 		/* VGA - TV DAC */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_CRT2_SUPPORT,
@@ -1275,8 +1411,11 @@
 					  ATOM_DEVICE_CRT2_SUPPORT);
 		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
 					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_VGA);
+					    CONNECTOR_OBJECT_ID_VGA,
+					    &hpd);
 		/* TV - TV DAC */
+		ddc_i2c.valid = false;
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_TV1_SUPPORT,
@@ -1285,13 +1424,15 @@
 		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
 					    DRM_MODE_CONNECTOR_SVIDEO,
 					    &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SVIDEO);
+					    CONNECTOR_OBJECT_ID_SVIDEO,
+					    &hpd);
 		break;
 	case CT_POWERBOOK_EXTERNAL:
 		DRM_INFO("Connector Table: %d (powerbook external tmds)\n",
 			 rdev->mode_info.connector_table);
 		/* LVDS */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_LCD1_SUPPORT,
@@ -1299,9 +1440,11 @@
 					  ATOM_DEVICE_LCD1_SUPPORT);
 		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
 					    DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_LVDS);
+					    CONNECTOR_OBJECT_ID_LVDS,
+					    &hpd);
 		/* DVI-I - primary dac, ext tmds */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+		hpd.hpd = RADEON_HPD_2; /* ??? */
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_DFP2_SUPPORT,
@@ -1317,8 +1460,11 @@
 					    ATOM_DEVICE_DFP2_SUPPORT |
 					    ATOM_DEVICE_CRT1_SUPPORT,
 					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I);
+					    CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I,
+					    &hpd);
 		/* TV - TV DAC */
+		ddc_i2c.valid = false;
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_TV1_SUPPORT,
@@ -1327,13 +1473,15 @@
 		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
 					    DRM_MODE_CONNECTOR_SVIDEO,
 					    &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SVIDEO);
+					    CONNECTOR_OBJECT_ID_SVIDEO,
+					    &hpd);
 		break;
 	case CT_POWERBOOK_INTERNAL:
 		DRM_INFO("Connector Table: %d (powerbook internal tmds)\n",
 			 rdev->mode_info.connector_table);
 		/* LVDS */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_LCD1_SUPPORT,
@@ -1341,9 +1489,11 @@
 					  ATOM_DEVICE_LCD1_SUPPORT);
 		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
 					    DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_LVDS);
+					    CONNECTOR_OBJECT_ID_LVDS,
+					    &hpd);
 		/* DVI-I - primary dac, int tmds */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+		hpd.hpd = RADEON_HPD_1; /* ??? */
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_DFP1_SUPPORT,
@@ -1358,8 +1508,11 @@
 					    ATOM_DEVICE_DFP1_SUPPORT |
 					    ATOM_DEVICE_CRT1_SUPPORT,
 					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
+					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
+					    &hpd);
 		/* TV - TV DAC */
+		ddc_i2c.valid = false;
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_TV1_SUPPORT,
@@ -1368,13 +1521,15 @@
 		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
 					    DRM_MODE_CONNECTOR_SVIDEO,
 					    &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SVIDEO);
+					    CONNECTOR_OBJECT_ID_SVIDEO,
+					    &hpd);
 		break;
 	case CT_POWERBOOK_VGA:
 		DRM_INFO("Connector Table: %d (powerbook vga)\n",
 			 rdev->mode_info.connector_table);
 		/* LVDS */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_LCD1_SUPPORT,
@@ -1382,9 +1537,11 @@
 					  ATOM_DEVICE_LCD1_SUPPORT);
 		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
 					    DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_LVDS);
+					    CONNECTOR_OBJECT_ID_LVDS,
+					    &hpd);
 		/* VGA - primary dac */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_CRT1_SUPPORT,
@@ -1392,8 +1549,11 @@
 					  ATOM_DEVICE_CRT1_SUPPORT);
 		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT,
 					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_VGA);
+					    CONNECTOR_OBJECT_ID_VGA,
+					    &hpd);
 		/* TV - TV DAC */
+		ddc_i2c.valid = false;
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_TV1_SUPPORT,
@@ -1402,13 +1562,15 @@
 		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
 					    DRM_MODE_CONNECTOR_SVIDEO,
 					    &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SVIDEO);
+					    CONNECTOR_OBJECT_ID_SVIDEO,
+					    &hpd);
 		break;
 	case CT_MINI_EXTERNAL:
 		DRM_INFO("Connector Table: %d (mini external tmds)\n",
 			 rdev->mode_info.connector_table);
 		/* DVI-I - tv dac, ext tmds */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
+		hpd.hpd = RADEON_HPD_2; /* ??? */
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_DFP2_SUPPORT,
@@ -1424,8 +1586,11 @@
 					    ATOM_DEVICE_DFP2_SUPPORT |
 					    ATOM_DEVICE_CRT2_SUPPORT,
 					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
+					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
+					    &hpd);
 		/* TV - TV DAC */
+		ddc_i2c.valid = false;
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_TV1_SUPPORT,
@@ -1434,13 +1599,15 @@
 		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT,
 					    DRM_MODE_CONNECTOR_SVIDEO,
 					    &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SVIDEO);
+					    CONNECTOR_OBJECT_ID_SVIDEO,
+					    &hpd);
 		break;
 	case CT_MINI_INTERNAL:
 		DRM_INFO("Connector Table: %d (mini internal tmds)\n",
 			 rdev->mode_info.connector_table);
 		/* DVI-I - tv dac, int tmds */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
+		hpd.hpd = RADEON_HPD_1; /* ??? */
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_DFP1_SUPPORT,
@@ -1455,8 +1622,11 @@
 					    ATOM_DEVICE_DFP1_SUPPORT |
 					    ATOM_DEVICE_CRT2_SUPPORT,
 					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
+					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
+					    &hpd);
 		/* TV - TV DAC */
+		ddc_i2c.valid = false;
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_TV1_SUPPORT,
@@ -1465,13 +1635,15 @@
 		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT,
 					    DRM_MODE_CONNECTOR_SVIDEO,
 					    &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SVIDEO);
+					    CONNECTOR_OBJECT_ID_SVIDEO,
+					    &hpd);
 		break;
 	case CT_IMAC_G5_ISIGHT:
 		DRM_INFO("Connector Table: %d (imac g5 isight)\n",
 			 rdev->mode_info.connector_table);
 		/* DVI-D - int tmds */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_MONID);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
+		hpd.hpd = RADEON_HPD_1; /* ??? */
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_DFP1_SUPPORT,
@@ -1479,9 +1651,11 @@
 					  ATOM_DEVICE_DFP1_SUPPORT);
 		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_DFP1_SUPPORT,
 					    DRM_MODE_CONNECTOR_DVID, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D);
+					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D,
+					    &hpd);
 		/* VGA - tv dac */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_CRT2_SUPPORT,
@@ -1489,8 +1663,11 @@
 					  ATOM_DEVICE_CRT2_SUPPORT);
 		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
 					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_VGA);
+					    CONNECTOR_OBJECT_ID_VGA,
+					    &hpd);
 		/* TV - TV DAC */
+		ddc_i2c.valid = false;
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_TV1_SUPPORT,
@@ -1499,13 +1676,15 @@
 		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
 					    DRM_MODE_CONNECTOR_SVIDEO,
 					    &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SVIDEO);
+					    CONNECTOR_OBJECT_ID_SVIDEO,
+					    &hpd);
 		break;
 	case CT_EMAC:
 		DRM_INFO("Connector Table: %d (emac)\n",
 			 rdev->mode_info.connector_table);
 		/* VGA - primary dac */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_CRT1_SUPPORT,
@@ -1513,9 +1692,11 @@
 					  ATOM_DEVICE_CRT1_SUPPORT);
 		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT,
 					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_VGA);
+					    CONNECTOR_OBJECT_ID_VGA,
+					    &hpd);
 		/* VGA - tv dac */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_CRT2_SUPPORT,
@@ -1523,8 +1704,11 @@
 					  ATOM_DEVICE_CRT2_SUPPORT);
 		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
 					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_VGA);
+					    CONNECTOR_OBJECT_ID_VGA,
+					    &hpd);
 		/* TV - TV DAC */
+		ddc_i2c.valid = false;
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_TV1_SUPPORT,
@@ -1533,7 +1717,8 @@
 		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
 					    DRM_MODE_CONNECTOR_SVIDEO,
 					    &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SVIDEO);
+					    CONNECTOR_OBJECT_ID_SVIDEO,
+					    &hpd);
 		break;
 	default:
 		DRM_INFO("Connector table: %d (invalid)\n",
@@ -1550,7 +1735,8 @@
 				       int bios_index,
 				       enum radeon_combios_connector
 				       *legacy_connector,
-				       struct radeon_i2c_bus_rec *ddc_i2c)
+				       struct radeon_i2c_bus_rec *ddc_i2c,
+				       struct radeon_hpd *hpd)
 {
 	struct radeon_device *rdev = dev->dev_private;
 
@@ -1558,29 +1744,26 @@
 	if ((rdev->family == CHIP_RS400 ||
 	     rdev->family == CHIP_RS480) &&
 	    ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC)
-		*ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_MONID);
+		*ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
 	else if ((rdev->family == CHIP_RS400 ||
 		  rdev->family == CHIP_RS480) &&
 		 ddc_i2c->mask_clk_reg == RADEON_GPIO_MONID) {
-		ddc_i2c->valid = true;
+		*ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIOPAD_MASK);
 		ddc_i2c->mask_clk_mask = (0x20 << 8);
 		ddc_i2c->mask_data_mask = 0x80;
 		ddc_i2c->a_clk_mask = (0x20 << 8);
 		ddc_i2c->a_data_mask = 0x80;
-		ddc_i2c->put_clk_mask = (0x20 << 8);
-		ddc_i2c->put_data_mask = 0x80;
-		ddc_i2c->get_clk_mask = (0x20 << 8);
-		ddc_i2c->get_data_mask = 0x80;
-		ddc_i2c->mask_clk_reg = RADEON_GPIOPAD_MASK;
-		ddc_i2c->mask_data_reg = RADEON_GPIOPAD_MASK;
-		ddc_i2c->a_clk_reg = RADEON_GPIOPAD_A;
-		ddc_i2c->a_data_reg = RADEON_GPIOPAD_A;
-		ddc_i2c->put_clk_reg = RADEON_GPIOPAD_EN;
-		ddc_i2c->put_data_reg = RADEON_GPIOPAD_EN;
-		ddc_i2c->get_clk_reg = RADEON_LCD_GPIO_Y_REG;
-		ddc_i2c->get_data_reg = RADEON_LCD_GPIO_Y_REG;
+		ddc_i2c->en_clk_mask = (0x20 << 8);
+		ddc_i2c->en_data_mask = 0x80;
+		ddc_i2c->y_clk_mask = (0x20 << 8);
+		ddc_i2c->y_data_mask = 0x80;
 	}
 
+	/* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */
+	if ((rdev->family >= CHIP_R300) &&
+	    ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC)
+		*ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+
 	/* Certain IBM chipset RN50s have a BIOS reporting two VGAs,
 	   one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */
 	if (dev->pdev->device == 0x515e &&
@@ -1624,6 +1807,12 @@
 	    dev->pdev->subsystem_device == 0x280a)
 		return false;
 
+	/* MSI S270 has non-existent TV port */
+	if (dev->pdev->device == 0x5955 &&
+	    dev->pdev->subsystem_vendor == 0x1462 &&
+	    dev->pdev->subsystem_device == 0x0131)
+		return false;
+
 	return true;
 }
 
@@ -1671,6 +1860,7 @@
 	enum radeon_combios_connector connector;
 	int i = 0;
 	struct radeon_i2c_bus_rec ddc_i2c;
+	struct radeon_hpd hpd;
 
 	if (rdev->bios == NULL)
 		return false;
@@ -1691,26 +1881,40 @@
 			switch (ddc_type) {
 			case DDC_MONID:
 				ddc_i2c =
-				    combios_setup_i2c_bus(RADEON_GPIO_MONID);
+					combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
 				break;
 			case DDC_DVI:
 				ddc_i2c =
-				    combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+					combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
 				break;
 			case DDC_VGA:
 				ddc_i2c =
-				    combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+					combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
 				break;
 			case DDC_CRT2:
 				ddc_i2c =
-				    combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
+					combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
 				break;
 			default:
 				break;
 			}
 
+			switch (connector) {
+			case CONNECTOR_PROPRIETARY_LEGACY:
+			case CONNECTOR_DVI_I_LEGACY:
+			case CONNECTOR_DVI_D_LEGACY:
+				if ((tmp >> 4) & 0x1)
+					hpd.hpd = RADEON_HPD_2;
+				else
+					hpd.hpd = RADEON_HPD_1;
+				break;
+			default:
+				hpd.hpd = RADEON_HPD_NONE;
+				break;
+			}
+
 			if (!radeon_apply_legacy_quirks(dev, i, &connector,
-						       &ddc_i2c))
+							&ddc_i2c, &hpd))
 				continue;
 
 			switch (connector) {
@@ -1727,7 +1931,8 @@
 							    legacy_connector_convert
 							    [connector],
 							    &ddc_i2c,
-							    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D);
+							    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D,
+							    &hpd);
 				break;
 			case CONNECTOR_CRT_LEGACY:
 				if (tmp & 0x1) {
@@ -1753,7 +1958,8 @@
 							    legacy_connector_convert
 							    [connector],
 							    &ddc_i2c,
-							    CONNECTOR_OBJECT_ID_VGA);
+							    CONNECTOR_OBJECT_ID_VGA,
+							    &hpd);
 				break;
 			case CONNECTOR_DVI_I_LEGACY:
 				devices = 0;
@@ -1799,7 +2005,8 @@
 							    legacy_connector_convert
 							    [connector],
 							    &ddc_i2c,
-							    connector_object_id);
+							    connector_object_id,
+							    &hpd);
 				break;
 			case CONNECTOR_DVI_D_LEGACY:
 				if ((tmp >> 4) & 0x1) {
@@ -1817,7 +2024,8 @@
 							    legacy_connector_convert
 							    [connector],
 							    &ddc_i2c,
-							    connector_object_id);
+							    connector_object_id,
+							    &hpd);
 				break;
 			case CONNECTOR_CTV_LEGACY:
 			case CONNECTOR_STV_LEGACY:
@@ -1832,7 +2040,8 @@
 							    legacy_connector_convert
 							    [connector],
 							    &ddc_i2c,
-							    CONNECTOR_OBJECT_ID_SVIDEO);
+							    CONNECTOR_OBJECT_ID_SVIDEO,
+							    &hpd);
 				break;
 			default:
 				DRM_ERROR("Unknown connector type: %d\n",
@@ -1858,14 +2067,16 @@
 									0),
 						  ATOM_DEVICE_DFP1_SUPPORT);
 
-			ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+			ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+			hpd.hpd = RADEON_HPD_NONE;
 			radeon_add_legacy_connector(dev,
 						    0,
 						    ATOM_DEVICE_CRT1_SUPPORT |
 						    ATOM_DEVICE_DFP1_SUPPORT,
 						    DRM_MODE_CONNECTOR_DVII,
 						    &ddc_i2c,
-						    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
+						    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
+						    &hpd);
 		} else {
 			uint16_t crt_info =
 				combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE);
@@ -1876,13 +2087,15 @@
 										ATOM_DEVICE_CRT1_SUPPORT,
 										1),
 							  ATOM_DEVICE_CRT1_SUPPORT);
-				ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+				ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+				hpd.hpd = RADEON_HPD_NONE;
 				radeon_add_legacy_connector(dev,
 							    0,
 							    ATOM_DEVICE_CRT1_SUPPORT,
 							    DRM_MODE_CONNECTOR_VGA,
 							    &ddc_i2c,
-							    CONNECTOR_OBJECT_ID_VGA);
+							    CONNECTOR_OBJECT_ID_VGA,
+							    &hpd);
 			} else {
 				DRM_DEBUG("No connector info found\n");
 				return false;
@@ -1910,27 +2123,27 @@
 				case DDC_MONID:
 					ddc_i2c =
 					    combios_setup_i2c_bus
-					    (RADEON_GPIO_MONID);
+						(rdev, RADEON_GPIO_MONID);
 					break;
 				case DDC_DVI:
 					ddc_i2c =
 					    combios_setup_i2c_bus
-					    (RADEON_GPIO_DVI_DDC);
+						(rdev, RADEON_GPIO_DVI_DDC);
 					break;
 				case DDC_VGA:
 					ddc_i2c =
 					    combios_setup_i2c_bus
-					    (RADEON_GPIO_VGA_DDC);
+						(rdev, RADEON_GPIO_VGA_DDC);
 					break;
 				case DDC_CRT2:
 					ddc_i2c =
 					    combios_setup_i2c_bus
-					    (RADEON_GPIO_CRT2_DDC);
+						(rdev, RADEON_GPIO_CRT2_DDC);
 					break;
 				case DDC_LCD:
 					ddc_i2c =
 					    combios_setup_i2c_bus
-					    (RADEON_LCD_GPIO_MASK);
+						(rdev, RADEON_GPIOPAD_MASK);
 					ddc_i2c.mask_clk_mask =
 					    RBIOS32(lcd_ddc_info + 3);
 					ddc_i2c.mask_data_mask =
@@ -1939,19 +2152,19 @@
 					    RBIOS32(lcd_ddc_info + 3);
 					ddc_i2c.a_data_mask =
 					    RBIOS32(lcd_ddc_info + 7);
-					ddc_i2c.put_clk_mask =
+					ddc_i2c.en_clk_mask =
 					    RBIOS32(lcd_ddc_info + 3);
-					ddc_i2c.put_data_mask =
+					ddc_i2c.en_data_mask =
 					    RBIOS32(lcd_ddc_info + 7);
-					ddc_i2c.get_clk_mask =
+					ddc_i2c.y_clk_mask =
 					    RBIOS32(lcd_ddc_info + 3);
-					ddc_i2c.get_data_mask =
+					ddc_i2c.y_data_mask =
 					    RBIOS32(lcd_ddc_info + 7);
 					break;
 				case DDC_GPIO:
 					ddc_i2c =
 					    combios_setup_i2c_bus
-					    (RADEON_MDGPIO_EN_REG);
+						(rdev, RADEON_MDGPIO_MASK);
 					ddc_i2c.mask_clk_mask =
 					    RBIOS32(lcd_ddc_info + 3);
 					ddc_i2c.mask_data_mask =
@@ -1960,13 +2173,13 @@
 					    RBIOS32(lcd_ddc_info + 3);
 					ddc_i2c.a_data_mask =
 					    RBIOS32(lcd_ddc_info + 7);
-					ddc_i2c.put_clk_mask =
+					ddc_i2c.en_clk_mask =
 					    RBIOS32(lcd_ddc_info + 3);
-					ddc_i2c.put_data_mask =
+					ddc_i2c.en_data_mask =
 					    RBIOS32(lcd_ddc_info + 7);
-					ddc_i2c.get_clk_mask =
+					ddc_i2c.y_clk_mask =
 					    RBIOS32(lcd_ddc_info + 3);
-					ddc_i2c.get_data_mask =
+					ddc_i2c.y_data_mask =
 					    RBIOS32(lcd_ddc_info + 7);
 					break;
 				default:
@@ -1977,12 +2190,14 @@
 			} else
 				ddc_i2c.valid = false;
 
+			hpd.hpd = RADEON_HPD_NONE;
 			radeon_add_legacy_connector(dev,
 						    5,
 						    ATOM_DEVICE_LCD1_SUPPORT,
 						    DRM_MODE_CONNECTOR_LVDS,
 						    &ddc_i2c,
-						    CONNECTOR_OBJECT_ID_LVDS);
+						    CONNECTOR_OBJECT_ID_LVDS,
+						    &hpd);
 		}
 	}
 
@@ -1993,6 +2208,7 @@
 		if (tv_info) {
 			if (RBIOS8(tv_info + 6) == 'T') {
 				if (radeon_apply_legacy_tv_quirks(dev)) {
+					hpd.hpd = RADEON_HPD_NONE;
 					radeon_add_legacy_encoder(dev,
 								  radeon_get_encoder_id
 								  (dev,
@@ -2003,7 +2219,8 @@
 								    ATOM_DEVICE_TV1_SUPPORT,
 								    DRM_MODE_CONNECTOR_SVIDEO,
 								    &ddc_i2c,
-								    CONNECTOR_OBJECT_ID_SVIDEO);
+								    CONNECTOR_OBJECT_ID_SVIDEO,
+								    &hpd);
 				}
 			}
 		}
@@ -2014,6 +2231,193 @@
 	return true;
 }
 
+void radeon_external_tmds_setup(struct drm_encoder *encoder)
+{
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
+
+	if (!tmds)
+		return;
+
+	switch (tmds->dvo_chip) {
+	case DVO_SIL164:
+		/* sil 164 */
+		radeon_i2c_do_lock(tmds->i2c_bus, 1);
+		radeon_i2c_sw_put_byte(tmds->i2c_bus,
+				       tmds->slave_addr,
+				       0x08, 0x30);
+		radeon_i2c_sw_put_byte(tmds->i2c_bus,
+				       tmds->slave_addr,
+				       0x09, 0x00);
+		radeon_i2c_sw_put_byte(tmds->i2c_bus,
+				       tmds->slave_addr,
+				       0x0a, 0x90);
+		radeon_i2c_sw_put_byte(tmds->i2c_bus,
+				       tmds->slave_addr,
+				       0x0c, 0x89);
+		radeon_i2c_sw_put_byte(tmds->i2c_bus,
+				       tmds->slave_addr,
+				       0x08, 0x3b);
+		radeon_i2c_do_lock(tmds->i2c_bus, 0);
+		break;
+	case DVO_SIL1178:
+		/* sil 1178 - untested */
+		/*
+		 * 0x0f, 0x44
+		 * 0x0f, 0x4c
+		 * 0x0e, 0x01
+		 * 0x0a, 0x80
+		 * 0x09, 0x30
+		 * 0x0c, 0xc9
+		 * 0x0d, 0x70
+		 * 0x08, 0x32
+		 * 0x08, 0x33
+		 */
+		break;
+	default:
+		break;
+	}
+
+}
+
+bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	uint16_t offset;
+	uint8_t blocks, slave_addr, rev;
+	uint32_t index, id;
+	uint32_t reg, val, and_mask, or_mask;
+	struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
+
+	if (rdev->bios == NULL)
+		return false;
+
+	if (!tmds)
+		return false;
+
+	if (rdev->flags & RADEON_IS_IGP) {
+		offset = combios_get_table_offset(dev, COMBIOS_TMDS_POWER_ON_TABLE);
+		rev = RBIOS8(offset);
+		if (offset) {
+			rev = RBIOS8(offset);
+			if (rev > 1) {
+				blocks = RBIOS8(offset + 3);
+				index = offset + 4;
+				while (blocks > 0) {
+					id = RBIOS16(index);
+					index += 2;
+					switch (id >> 13) {
+					case 0:
+						reg = (id & 0x1fff) * 4;
+						val = RBIOS32(index);
+						index += 4;
+						WREG32(reg, val);
+						break;
+					case 2:
+						reg = (id & 0x1fff) * 4;
+						and_mask = RBIOS32(index);
+						index += 4;
+						or_mask = RBIOS32(index);
+						index += 4;
+						val = RREG32(reg);
+						val = (val & and_mask) | or_mask;
+						WREG32(reg, val);
+						break;
+					case 3:
+						val = RBIOS16(index);
+						index += 2;
+						udelay(val);
+						break;
+					case 4:
+						val = RBIOS16(index);
+						index += 2;
+						udelay(val * 1000);
+						break;
+					case 6:
+						slave_addr = id & 0xff;
+						slave_addr >>= 1; /* 7 bit addressing */
+						index++;
+						reg = RBIOS8(index);
+						index++;
+						val = RBIOS8(index);
+						index++;
+						radeon_i2c_do_lock(tmds->i2c_bus, 1);
+						radeon_i2c_sw_put_byte(tmds->i2c_bus,
+								       slave_addr,
+								       reg, val);
+						radeon_i2c_do_lock(tmds->i2c_bus, 0);
+						break;
+					default:
+						DRM_ERROR("Unknown id %d\n", id >> 13);
+						break;
+					}
+					blocks--;
+				}
+				return true;
+			}
+		}
+	} else {
+		offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
+		if (offset) {
+			index = offset + 10;
+			id = RBIOS16(index);
+			while (id != 0xffff) {
+				index += 2;
+				switch (id >> 13) {
+				case 0:
+					reg = (id & 0x1fff) * 4;
+					val = RBIOS32(index);
+					WREG32(reg, val);
+					break;
+				case 2:
+					reg = (id & 0x1fff) * 4;
+					and_mask = RBIOS32(index);
+					index += 4;
+					or_mask = RBIOS32(index);
+					index += 4;
+					val = RREG32(reg);
+					val = (val & and_mask) | or_mask;
+					WREG32(reg, val);
+					break;
+				case 4:
+					val = RBIOS16(index);
+					index += 2;
+					udelay(val);
+					break;
+				case 5:
+					reg = id & 0x1fff;
+					and_mask = RBIOS32(index);
+					index += 4;
+					or_mask = RBIOS32(index);
+					index += 4;
+					val = RREG32_PLL(reg);
+					val = (val & and_mask) | or_mask;
+					WREG32_PLL(reg, val);
+					break;
+				case 6:
+					reg = id & 0x1fff;
+					val = RBIOS8(index);
+					index += 1;
+					radeon_i2c_do_lock(tmds->i2c_bus, 1);
+					radeon_i2c_sw_put_byte(tmds->i2c_bus,
+							       tmds->slave_addr,
+							       reg, val);
+					radeon_i2c_do_lock(tmds->i2c_bus, 0);
+					break;
+				default:
+					DRM_ERROR("Unknown id %d\n", id >> 13);
+					break;
+				}
+				id = RBIOS16(index);
+			}
+			return true;
+		}
+	}
+	return false;
+}
+
 static void combios_parse_mmio_table(struct drm_device *dev, uint16_t offset)
 {
 	struct radeon_device *rdev = dev->dev_private;
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 29763ce..5eece18 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -40,6 +40,26 @@
 				       struct drm_encoder *encoder,
 				       bool connected);
 
+void radeon_connector_hotplug(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+
+	if (radeon_connector->hpd.hpd != RADEON_HPD_NONE)
+		radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd);
+
+	if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
+		if (radeon_dp_getsinktype(radeon_connector) == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
+			if (radeon_dp_needs_link_train(radeon_connector)) {
+				if (connector->encoder)
+					dp_link_train(connector->encoder, connector);
+			}
+		}
+	}
+
+}
+
 static void radeon_property_change_mode(struct drm_encoder *encoder)
 {
 	struct drm_crtc *crtc = encoder->crtc;
@@ -445,10 +465,10 @@
 		ret = connector_status_connected;
 	else {
 		if (radeon_connector->ddc_bus) {
-			radeon_i2c_do_lock(radeon_connector, 1);
+			radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
 			radeon_connector->edid = drm_get_edid(&radeon_connector->base,
 							      &radeon_connector->ddc_bus->adapter);
-			radeon_i2c_do_lock(radeon_connector, 0);
+			radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
 			if (radeon_connector->edid)
 				ret = connector_status_connected;
 		}
@@ -553,17 +573,17 @@
 	if (!encoder)
 		ret = connector_status_disconnected;
 
-	radeon_i2c_do_lock(radeon_connector, 1);
+	radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
 	dret = radeon_ddc_probe(radeon_connector);
-	radeon_i2c_do_lock(radeon_connector, 0);
+	radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
 	if (dret) {
 		if (radeon_connector->edid) {
 			kfree(radeon_connector->edid);
 			radeon_connector->edid = NULL;
 		}
-		radeon_i2c_do_lock(radeon_connector, 1);
+		radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
 		radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
-		radeon_i2c_do_lock(radeon_connector, 0);
+		radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
 
 		if (!radeon_connector->edid) {
 			DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
@@ -708,17 +728,17 @@
 	enum drm_connector_status ret = connector_status_disconnected;
 	bool dret;
 
-	radeon_i2c_do_lock(radeon_connector, 1);
+	radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
 	dret = radeon_ddc_probe(radeon_connector);
-	radeon_i2c_do_lock(radeon_connector, 0);
+	radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
 	if (dret) {
 		if (radeon_connector->edid) {
 			kfree(radeon_connector->edid);
 			radeon_connector->edid = NULL;
 		}
-		radeon_i2c_do_lock(radeon_connector, 1);
+		radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
 		radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
-		radeon_i2c_do_lock(radeon_connector, 0);
+		radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
 
 		if (!radeon_connector->edid) {
 			DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
@@ -735,6 +755,39 @@
 				ret = connector_status_disconnected;
 			} else
 				ret = connector_status_connected;
+
+			/* multiple connectors on the same encoder with the same ddc line
+			 * This tends to be HDMI and DVI on the same encoder with the
+			 * same ddc line.  If the edid says HDMI, consider the HDMI port
+			 * connected and the DVI port disconnected.  If the edid doesn't
+			 * say HDMI, vice versa.
+			 */
+			if (radeon_connector->shared_ddc && connector_status_connected) {
+				struct drm_device *dev = connector->dev;
+				struct drm_connector *list_connector;
+				struct radeon_connector *list_radeon_connector;
+				list_for_each_entry(list_connector, &dev->mode_config.connector_list, head) {
+					if (connector == list_connector)
+						continue;
+					list_radeon_connector = to_radeon_connector(list_connector);
+					if (radeon_connector->devices == list_radeon_connector->devices) {
+						if (drm_detect_hdmi_monitor(radeon_connector->edid)) {
+							if (connector->connector_type == DRM_MODE_CONNECTOR_DVID) {
+								kfree(radeon_connector->edid);
+								radeon_connector->edid = NULL;
+								ret = connector_status_disconnected;
+							}
+						} else {
+							if ((connector->connector_type == DRM_MODE_CONNECTOR_HDMIA) ||
+							    (connector->connector_type == DRM_MODE_CONNECTOR_HDMIB)) {
+								kfree(radeon_connector->edid);
+								radeon_connector->edid = NULL;
+								ret = connector_status_disconnected;
+							}
+						}
+					}
+				}
+			}
 		}
 	}
 
@@ -863,6 +916,91 @@
 	.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->ddc_bus)
+		radeon_i2c_destroy(radeon_connector->ddc_bus);
+	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);
+	int ret;
+
+	ret = radeon_ddc_get_modes(radeon_connector);
+	return ret;
+}
+
+static enum drm_connector_status radeon_dp_detect(struct drm_connector *connector)
+{
+	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+	enum drm_connector_status ret = connector_status_disconnected;
+	struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
+	u8 sink_type;
+
+	if (radeon_connector->edid) {
+		kfree(radeon_connector->edid);
+		radeon_connector->edid = NULL;
+	}
+
+	sink_type = radeon_dp_getsinktype(radeon_connector);
+	if (sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
+		if (radeon_dp_getdpcd(radeon_connector)) {
+			radeon_dig_connector->dp_sink_type = sink_type;
+			ret = connector_status_connected;
+		}
+	} else {
+		radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
+		if (radeon_ddc_probe(radeon_connector)) {
+			radeon_dig_connector->dp_sink_type = sink_type;
+			ret = connector_status_connected;
+		}
+		radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
+	}
+
+	return ret;
+}
+
+static int radeon_dp_mode_valid(struct drm_connector *connector,
+				  struct drm_display_mode *mode)
+{
+	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+	struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
+
+	/* XXX check mode bandwidth */
+
+	if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT)
+		return radeon_dp_mode_valid_helper(radeon_connector, mode);
+	else
+		return MODE_OK;
+}
+
+struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = {
+	.get_modes = radeon_dp_get_modes,
+	.mode_valid = radeon_dp_mode_valid,
+	.best_encoder = radeon_dvi_encoder,
+};
+
+struct drm_connector_funcs radeon_dp_connector_funcs = {
+	.dpms = drm_helper_connector_dpms,
+	.detect = radeon_dp_detect,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.set_property = radeon_connector_set_property,
+	.destroy = radeon_dp_connector_destroy,
+	.force = radeon_dvi_force,
+};
+
 void
 radeon_add_atom_connector(struct drm_device *dev,
 			  uint32_t connector_id,
@@ -871,7 +1009,8 @@
 			  struct radeon_i2c_bus_rec *i2c_bus,
 			  bool linkb,
 			  uint32_t igp_lane_info,
-			  uint16_t connector_object_id)
+			  uint16_t connector_object_id,
+			  struct radeon_hpd *hpd)
 {
 	struct radeon_device *rdev = dev->dev_private;
 	struct drm_connector *connector;
@@ -911,6 +1050,7 @@
 	radeon_connector->devices = supported_device;
 	radeon_connector->shared_ddc = shared_ddc;
 	radeon_connector->connector_object_id = connector_object_id;
+	radeon_connector->hpd = *hpd;
 	switch (connector_type) {
 	case DRM_MODE_CONNECTOR_VGA:
 		drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
@@ -963,10 +1103,12 @@
 		drm_connector_attach_property(&radeon_connector->base,
 					      rdev->mode_info.coherent_mode_property,
 					      1);
-		radeon_connector->dac_load_detect = true;
-		drm_connector_attach_property(&radeon_connector->base,
-					      rdev->mode_info.load_detect_property,
-					      1);
+		if (connector_type == DRM_MODE_CONNECTOR_DVII) {
+			radeon_connector->dac_load_detect = true;
+			drm_connector_attach_property(&radeon_connector->base,
+						      rdev->mode_info.load_detect_property,
+						      1);
+		}
 		break;
 	case DRM_MODE_CONNECTOR_HDMIA:
 	case DRM_MODE_CONNECTOR_HDMIB:
@@ -997,16 +1139,23 @@
 		radeon_dig_connector->linkb = linkb;
 		radeon_dig_connector->igp_lane_info = igp_lane_info;
 		radeon_connector->con_priv = radeon_dig_connector;
-		drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
-		ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
+		drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type);
+		ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs);
 		if (ret)
 			goto failed;
 		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)
+				goto failed;
 			radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP");
 			if (!radeon_connector->ddc_bus)
 				goto failed;
 		}
 		subpixel_order = SubPixelHorizontalRGB;
+		drm_connector_attach_property(&radeon_connector->base,
+					      rdev->mode_info.coherent_mode_property,
+					      1);
 		break;
 	case DRM_MODE_CONNECTOR_SVIDEO:
 	case DRM_MODE_CONNECTOR_Composite:
@@ -1020,6 +1169,9 @@
 			drm_connector_attach_property(&radeon_connector->base,
 						      rdev->mode_info.load_detect_property,
 						      1);
+			drm_connector_attach_property(&radeon_connector->base,
+						      rdev->mode_info.tv_std_property,
+						      1);
 		}
 		break;
 	case DRM_MODE_CONNECTOR_LVDS:
@@ -1038,7 +1190,6 @@
 			if (!radeon_connector->ddc_bus)
 				goto failed;
 		}
-		drm_mode_create_scaling_mode_property(dev);
 		drm_connector_attach_property(&radeon_connector->base,
 					      dev->mode_config.scaling_mode_property,
 					      DRM_MODE_SCALE_FULLSCREEN);
@@ -1063,7 +1214,8 @@
 			    uint32_t supported_device,
 			    int connector_type,
 			    struct radeon_i2c_bus_rec *i2c_bus,
-			    uint16_t connector_object_id)
+			    uint16_t connector_object_id,
+			    struct radeon_hpd *hpd)
 {
 	struct radeon_device *rdev = dev->dev_private;
 	struct drm_connector *connector;
@@ -1093,6 +1245,7 @@
 	radeon_connector->connector_id = connector_id;
 	radeon_connector->devices = supported_device;
 	radeon_connector->connector_object_id = connector_object_id;
+	radeon_connector->hpd = *hpd;
 	switch (connector_type) {
 	case DRM_MODE_CONNECTOR_VGA:
 		drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
@@ -1160,6 +1313,9 @@
 			drm_connector_attach_property(&radeon_connector->base,
 						      rdev->mode_info.load_detect_property,
 						      1);
+			drm_connector_attach_property(&radeon_connector->base,
+						      rdev->mode_info.tv_std_property,
+						      1);
 		}
 		break;
 	case DRM_MODE_CONNECTOR_LVDS:
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c
index 4f7afc7..0b2f9c2 100644
--- a/drivers/gpu/drm/radeon/radeon_cp.c
+++ b/drivers/gpu/drm/radeon/radeon_cp.c
@@ -1941,8 +1941,8 @@
 	for (t = 0; t < dev_priv->usec_timeout; t++) {
 		u32 done_age = GET_SCRATCH(dev_priv, 1);
 		DRM_DEBUG("done_age = %d\n", done_age);
-		for (i = start; i < dma->buf_count; i++) {
-			buf = dma->buflist[i];
+		for (i = 0; i < dma->buf_count; i++) {
+			buf = dma->buflist[start];
 			buf_priv = buf->dev_private;
 			if (buf->file_priv == NULL || (buf->pending &&
 						       buf_priv->age <=
@@ -1951,7 +1951,8 @@
 				buf->pending = 0;
 				return buf;
 			}
-			start = 0;
+			if (++start >= dma->buf_count)
+				start = 0;
 		}
 
 		if (t) {
@@ -1960,47 +1961,9 @@
 		}
 	}
 
-	DRM_DEBUG("returning NULL!\n");
 	return NULL;
 }
 
-#if 0
-struct drm_buf *radeon_freelist_get(struct drm_device * dev)
-{
-	struct drm_device_dma *dma = dev->dma;
-	drm_radeon_private_t *dev_priv = dev->dev_private;
-	drm_radeon_buf_priv_t *buf_priv;
-	struct drm_buf *buf;
-	int i, t;
-	int start;
-	u32 done_age;
-
-	done_age = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1));
-	if (++dev_priv->last_buf >= dma->buf_count)
-		dev_priv->last_buf = 0;
-
-	start = dev_priv->last_buf;
-	dev_priv->stats.freelist_loops++;
-
-	for (t = 0; t < 2; t++) {
-		for (i = start; i < dma->buf_count; i++) {
-			buf = dma->buflist[i];
-			buf_priv = buf->dev_private;
-			if (buf->file_priv == 0 || (buf->pending &&
-						    buf_priv->age <=
-						    done_age)) {
-				dev_priv->stats.requested_bufs++;
-				buf->pending = 0;
-				return buf;
-			}
-		}
-		start = 0;
-	}
-
-	return NULL;
-}
-#endif
-
 void radeon_freelist_reset(struct drm_device * dev)
 {
 	struct drm_device_dma *dma = dev->dma;
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index 5ab2cf9..65590a0 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -76,17 +76,17 @@
 			}
 			p->relocs_ptr[i] = &p->relocs[i];
 			p->relocs[i].robj = p->relocs[i].gobj->driver_private;
-			p->relocs[i].lobj.robj = p->relocs[i].robj;
+			p->relocs[i].lobj.bo = p->relocs[i].robj;
 			p->relocs[i].lobj.rdomain = r->read_domains;
 			p->relocs[i].lobj.wdomain = r->write_domain;
 			p->relocs[i].handle = r->handle;
 			p->relocs[i].flags = r->flags;
 			INIT_LIST_HEAD(&p->relocs[i].lobj.list);
-			radeon_object_list_add_object(&p->relocs[i].lobj,
-						      &p->validated);
+			radeon_bo_list_add_object(&p->relocs[i].lobj,
+						&p->validated);
 		}
 	}
-	return radeon_object_list_validate(&p->validated, p->ib->fence);
+	return radeon_bo_list_validate(&p->validated, p->ib->fence);
 }
 
 int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
@@ -190,9 +190,10 @@
 	unsigned i;
 
 	if (error) {
-		radeon_object_list_unvalidate(&parser->validated);
+		radeon_bo_list_unvalidate(&parser->validated,
+						parser->ib->fence);
 	} else {
-		radeon_object_list_clean(&parser->validated);
+		radeon_bo_list_unreserve(&parser->validated);
 	}
 	for (i = 0; i < parser->nrelocs; i++) {
 		if (parser->relocs[i].gobj) {
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 41bb76f..02bcdb1 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -44,10 +44,11 @@
 	if (rdev->family < CHIP_R600) {
 		int i;
 
-		for (i = 0; i < 8; i++) {
-			WREG32(RADEON_SURFACE0_INFO +
-			       i * (RADEON_SURFACE1_INFO - RADEON_SURFACE0_INFO),
-			       0);
+		for (i = 0; i < RADEON_GEM_MAX_SURFACES; i++) {
+			if (rdev->surface_regs[i].bo)
+				radeon_bo_get_surface_reg(rdev->surface_regs[i].bo);
+			else
+				radeon_clear_surface_reg(rdev, i);
 		}
 		/* enable surfaces */
 		WREG32(RADEON_SURFACE_CNTL, 0);
@@ -208,6 +209,24 @@
 
 }
 
+bool radeon_boot_test_post_card(struct radeon_device *rdev)
+{
+	if (radeon_card_posted(rdev))
+		return true;
+
+	if (rdev->bios) {
+		DRM_INFO("GPU not posted. posting now...\n");
+		if (rdev->is_atom_bios)
+			atom_asic_init(rdev->mode_info.atom_context);
+		else
+			radeon_combios_asic_init(rdev->ddev);
+		return true;
+	} else {
+		dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
+		return false;
+	}
+}
+
 int radeon_dummy_page_init(struct radeon_device *rdev)
 {
 	rdev->dummy_page.page = alloc_page(GFP_DMA32 | GFP_KERNEL | __GFP_ZERO);
@@ -463,12 +482,16 @@
 
 	rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios);
 	radeon_atom_initialize_bios_scratch_regs(rdev->ddev);
+	atom_allocate_fb_scratch(rdev->mode_info.atom_context);
 	return 0;
 }
 
 void radeon_atombios_fini(struct radeon_device *rdev)
 {
-	kfree(rdev->mode_info.atom_context);
+	if (rdev->mode_info.atom_context) {
+		kfree(rdev->mode_info.atom_context->scratch);
+		kfree(rdev->mode_info.atom_context);
+	}
 	kfree(rdev->mode_info.atom_card_info);
 }
 
@@ -544,16 +567,24 @@
 	mutex_init(&rdev->cs_mutex);
 	mutex_init(&rdev->ib_pool.mutex);
 	mutex_init(&rdev->cp.mutex);
+	if (rdev->family >= CHIP_R600)
+		spin_lock_init(&rdev->ih.lock);
+	mutex_init(&rdev->gem.mutex);
 	rwlock_init(&rdev->fence_drv.lock);
 	INIT_LIST_HEAD(&rdev->gem.objects);
 
+	/* setup workqueue */
+	rdev->wq = create_workqueue("radeon");
+	if (rdev->wq == NULL)
+		return -ENOMEM;
+
 	/* Set asic functions */
 	r = radeon_asic_init(rdev);
 	if (r) {
 		return r;
 	}
 
-	if (radeon_agpmode == -1) {
+	if (rdev->flags & RADEON_IS_AGP && radeon_agpmode == -1) {
 		radeon_agp_disable(rdev);
 	}
 
@@ -620,6 +651,7 @@
 	DRM_INFO("radeon: finishing device.\n");
 	rdev->shutdown = true;
 	radeon_fini(rdev);
+	destroy_workqueue(rdev->wq);
 	vga_client_register(rdev->pdev, NULL, NULL, NULL);
 	iounmap(rdev->rmmio);
 	rdev->rmmio = NULL;
@@ -633,6 +665,7 @@
 {
 	struct radeon_device *rdev = dev->dev_private;
 	struct drm_crtc *crtc;
+	int r;
 
 	if (dev == NULL || rdev == NULL) {
 		return -ENODEV;
@@ -643,26 +676,31 @@
 	/* unpin the front buffers */
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 		struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb);
-		struct radeon_object *robj;
+		struct radeon_bo *robj;
 
 		if (rfb == NULL || rfb->obj == NULL) {
 			continue;
 		}
 		robj = rfb->obj->driver_private;
-		if (robj != rdev->fbdev_robj) {
-			radeon_object_unpin(robj);
+		if (robj != rdev->fbdev_rbo) {
+			r = radeon_bo_reserve(robj, false);
+			if (unlikely(r == 0)) {
+				radeon_bo_unpin(robj);
+				radeon_bo_unreserve(robj);
+			}
 		}
 	}
 	/* evict vram memory */
-	radeon_object_evict_vram(rdev);
+	radeon_bo_evict_vram(rdev);
 	/* wait for gpu to finish processing current batch */
 	radeon_fence_wait_last(rdev);
 
 	radeon_save_bios_scratch_regs(rdev);
 
 	radeon_suspend(rdev);
+	radeon_hpd_fini(rdev);
 	/* evict remaining vram memory */
-	radeon_object_evict_vram(rdev);
+	radeon_bo_evict_vram(rdev);
 
 	pci_save_state(dev->pdev);
 	if (state.event == PM_EVENT_SUSPEND) {
@@ -695,6 +733,8 @@
 	fb_set_suspend(rdev->fbdev_info, 0);
 	release_console_sem();
 
+	/* reset hpd state */
+	radeon_hpd_init(rdev);
 	/* blat the mode back in */
 	drm_helper_resume_force_mode(dev);
 	return 0;
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index c85df4a..a133b83 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -250,6 +250,16 @@
 	"HDMI-B",
 };
 
+static const char *hpd_names[7] = {
+	"NONE",
+	"HPD1",
+	"HPD2",
+	"HPD3",
+	"HPD4",
+	"HPD5",
+	"HPD6",
+};
+
 static void radeon_print_display_setup(struct drm_device *dev)
 {
 	struct drm_connector *connector;
@@ -264,16 +274,18 @@
 		radeon_connector = to_radeon_connector(connector);
 		DRM_INFO("Connector %d:\n", i);
 		DRM_INFO("  %s\n", connector_names[connector->connector_type]);
+		if (radeon_connector->hpd.hpd != RADEON_HPD_NONE)
+			DRM_INFO("  %s\n", hpd_names[radeon_connector->hpd.hpd]);
 		if (radeon_connector->ddc_bus)
 			DRM_INFO("  DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
 				 radeon_connector->ddc_bus->rec.mask_clk_reg,
 				 radeon_connector->ddc_bus->rec.mask_data_reg,
 				 radeon_connector->ddc_bus->rec.a_clk_reg,
 				 radeon_connector->ddc_bus->rec.a_data_reg,
-				 radeon_connector->ddc_bus->rec.put_clk_reg,
-				 radeon_connector->ddc_bus->rec.put_data_reg,
-				 radeon_connector->ddc_bus->rec.get_clk_reg,
-				 radeon_connector->ddc_bus->rec.get_data_reg);
+				 radeon_connector->ddc_bus->rec.en_clk_reg,
+				 radeon_connector->ddc_bus->rec.en_data_reg,
+				 radeon_connector->ddc_bus->rec.y_clk_reg,
+				 radeon_connector->ddc_bus->rec.y_data_reg);
 		DRM_INFO("  Encoders:\n");
 		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 			radeon_encoder = to_radeon_encoder(encoder);
@@ -324,6 +336,7 @@
 			ret = radeon_get_legacy_connector_info_from_table(dev);
 	}
 	if (ret) {
+		radeon_setup_encoder_clones(dev);
 		radeon_print_display_setup(dev);
 		list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head)
 			radeon_ddc_dump(drm_connector);
@@ -336,12 +349,17 @@
 {
 	int ret = 0;
 
+	if (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
+		struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
+		if (dig->dp_i2c_bus)
+			radeon_connector->edid = drm_get_edid(&radeon_connector->base, &dig->dp_i2c_bus->adapter);
+	}
 	if (!radeon_connector->ddc_bus)
 		return -1;
 	if (!radeon_connector->edid) {
-		radeon_i2c_do_lock(radeon_connector, 1);
+		radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
 		radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
-		radeon_i2c_do_lock(radeon_connector, 0);
+		radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
 	}
 
 	if (radeon_connector->edid) {
@@ -361,9 +379,9 @@
 
 	if (!radeon_connector->ddc_bus)
 		return -1;
-	radeon_i2c_do_lock(radeon_connector, 1);
+	radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
 	edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter);
-	radeon_i2c_do_lock(radeon_connector, 0);
+	radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
 	if (edid) {
 		kfree(edid);
 	}
@@ -542,6 +560,98 @@
 	*post_div_p = best_post_div;
 }
 
+void radeon_compute_pll_avivo(struct radeon_pll *pll,
+			      uint64_t freq,
+			      uint32_t *dot_clock_p,
+			      uint32_t *fb_div_p,
+			      uint32_t *frac_fb_div_p,
+			      uint32_t *ref_div_p,
+			      uint32_t *post_div_p,
+			      int flags)
+{
+	fixed20_12 m, n, frac_n, p, f_vco, f_pclk, best_freq;
+	fixed20_12 pll_out_max, pll_out_min;
+	fixed20_12 pll_in_max, pll_in_min;
+	fixed20_12 reference_freq;
+	fixed20_12 error, ffreq, a, b;
+
+	pll_out_max.full = rfixed_const(pll->pll_out_max);
+	pll_out_min.full = rfixed_const(pll->pll_out_min);
+	pll_in_max.full = rfixed_const(pll->pll_in_max);
+	pll_in_min.full = rfixed_const(pll->pll_in_min);
+	reference_freq.full = rfixed_const(pll->reference_freq);
+	do_div(freq, 10);
+	ffreq.full = rfixed_const(freq);
+	error.full = rfixed_const(100 * 100);
+
+	/* max p */
+	p.full = rfixed_div(pll_out_max, ffreq);
+	p.full = rfixed_floor(p);
+
+	/* min m */
+	m.full = rfixed_div(reference_freq, pll_in_max);
+	m.full = rfixed_ceil(m);
+
+	while (1) {
+		n.full = rfixed_div(ffreq, reference_freq);
+		n.full = rfixed_mul(n, m);
+		n.full = rfixed_mul(n, p);
+
+		f_vco.full = rfixed_div(n, m);
+		f_vco.full = rfixed_mul(f_vco, reference_freq);
+
+		f_pclk.full = rfixed_div(f_vco, p);
+
+		if (f_pclk.full > ffreq.full)
+			error.full = f_pclk.full - ffreq.full;
+		else
+			error.full = ffreq.full - f_pclk.full;
+		error.full = rfixed_div(error, f_pclk);
+		a.full = rfixed_const(100 * 100);
+		error.full = rfixed_mul(error, a);
+
+		a.full = rfixed_mul(m, p);
+		a.full = rfixed_div(n, a);
+		best_freq.full = rfixed_mul(reference_freq, a);
+
+		if (rfixed_trunc(error) < 25)
+			break;
+
+		a.full = rfixed_const(1);
+		m.full = m.full + a.full;
+		a.full = rfixed_div(reference_freq, m);
+		if (a.full >= pll_in_min.full)
+			continue;
+
+		m.full = rfixed_div(reference_freq, pll_in_max);
+		m.full = rfixed_ceil(m);
+		a.full= rfixed_const(1);
+		p.full = p.full - a.full;
+		a.full = rfixed_mul(p, ffreq);
+		if (a.full >= pll_out_min.full)
+			continue;
+		else {
+			DRM_ERROR("Unable to find pll dividers\n");
+			break;
+		}
+	}
+
+	a.full = rfixed_const(10);
+	b.full = rfixed_mul(n, a);
+
+	frac_n.full = rfixed_floor(n);
+	frac_n.full = rfixed_mul(frac_n, a);
+	frac_n.full = b.full - frac_n.full;
+
+	*dot_clock_p = rfixed_trunc(best_freq);
+	*fb_div_p = rfixed_trunc(n);
+	*frac_fb_div_p = rfixed_trunc(frac_n);
+	*ref_div_p = rfixed_trunc(m);
+	*post_div_p = rfixed_trunc(p);
+
+	DRM_DEBUG("%u %d.%d, %d, %d\n", *dot_clock_p * 10, *fb_div_p, *frac_fb_div_p, *ref_div_p, *post_div_p);
+}
+
 static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb)
 {
 	struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
@@ -642,7 +752,7 @@
 			return -ENOMEM;
 
 		rdev->mode_info.coherent_mode_property->values[0] = 0;
-		rdev->mode_info.coherent_mode_property->values[0] = 1;
+		rdev->mode_info.coherent_mode_property->values[1] = 1;
 	}
 
 	if (!ASIC_IS_AVIVO(rdev)) {
@@ -666,7 +776,7 @@
 	if (!rdev->mode_info.load_detect_property)
 		return -ENOMEM;
 	rdev->mode_info.load_detect_property->values[0] = 0;
-	rdev->mode_info.load_detect_property->values[0] = 1;
+	rdev->mode_info.load_detect_property->values[1] = 1;
 
 	drm_mode_create_scaling_mode_property(rdev->ddev);
 
@@ -723,6 +833,8 @@
 	if (!ret) {
 		return ret;
 	}
+	/* initialize hpd */
+	radeon_hpd_init(rdev);
 	drm_helper_initial_config(rdev->ddev);
 	return 0;
 }
@@ -730,6 +842,7 @@
 void radeon_modeset_fini(struct radeon_device *rdev)
 {
 	if (rdev->mode_info.mode_config_initialized) {
+		radeon_hpd_fini(rdev);
 		drm_mode_config_cleanup(rdev->ddev);
 		rdev->mode_info.mode_config_initialized = false;
 	}
@@ -750,9 +863,17 @@
 		if (encoder->crtc != crtc)
 			continue;
 		if (first) {
-			radeon_crtc->rmx_type = radeon_encoder->rmx_type;
+			/* set scaling */
+			if (radeon_encoder->rmx_type == RMX_OFF)
+				radeon_crtc->rmx_type = RMX_OFF;
+			else if (mode->hdisplay < radeon_encoder->native_mode.hdisplay ||
+				 mode->vdisplay < radeon_encoder->native_mode.vdisplay)
+				radeon_crtc->rmx_type = radeon_encoder->rmx_type;
+			else
+				radeon_crtc->rmx_type = RMX_OFF;
+			/* copy native mode */
 			memcpy(&radeon_crtc->native_mode,
-				&radeon_encoder->native_mode,
+			       &radeon_encoder->native_mode,
 				sizeof(struct drm_display_mode));
 			first = false;
 		} else {
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 7f50fb8..c5c45e6 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -86,6 +86,7 @@
 int radeon_testing = 0;
 int radeon_connector_table = 0;
 int radeon_tv = 1;
+int radeon_new_pll = 1;
 
 MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
 module_param_named(no_wb, radeon_no_wb, int, 0444);
@@ -120,6 +121,9 @@
 MODULE_PARM_DESC(tv, "TV enable (0 = disable)");
 module_param_named(tv, radeon_tv, int, 0444);
 
+MODULE_PARM_DESC(new_pll, "Select new PLL code for AVIVO chips");
+module_param_named(new_pll, radeon_new_pll, int, 0444);
+
 static int radeon_suspend(struct drm_device *dev, pm_message_t state)
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h
index 350962e..e137852 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.h
+++ b/drivers/gpu/drm/radeon/radeon_drv.h
@@ -1104,7 +1104,6 @@
 #       define R600_IT_WAIT_REG_MEM             0x00003C00
 #       define R600_IT_MEM_WRITE                0x00003D00
 #       define R600_IT_INDIRECT_BUFFER          0x00003200
-#       define R600_IT_CP_INTERRUPT             0x00004000
 #       define R600_IT_SURFACE_SYNC             0x00004300
 #              define R600_CB0_DEST_BASE_ENA    (1 << 6)
 #              define R600_TC_ACTION_ENA        (1 << 23)
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index d42bc51..b4f23ec 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -35,6 +35,51 @@
 bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
 				struct drm_display_mode *mode);
 
+static uint32_t radeon_encoder_clones(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct drm_encoder *clone_encoder;
+	uint32_t index_mask = 0;
+	int count;
+
+	/* DIG routing gets problematic */
+	if (rdev->family >= CHIP_R600)
+		return index_mask;
+	/* LVDS/TV are too wacky */
+	if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
+		return index_mask;
+	/* DVO requires 2x ppll clocks depending on tmds chip */
+	if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT)
+		return index_mask;
+	
+	count = -1;
+	list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) {
+		struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder);
+		count++;
+
+		if (clone_encoder == encoder)
+			continue;
+		if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT))
+			continue;
+		if (radeon_clone->devices & ATOM_DEVICE_DFP2_SUPPORT)
+			continue;
+		else
+			index_mask |= (1 << count);
+	}
+	return index_mask;
+}
+
+void radeon_setup_encoder_clones(struct drm_device *dev)
+{
+	struct drm_encoder *encoder;
+
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		encoder->possible_clones = radeon_encoder_clones(encoder);
+	}
+}
+
 uint32_t
 radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac)
 {
@@ -163,29 +208,6 @@
 	return NULL;
 }
 
-/* used for both atom and legacy */
-void radeon_rmx_mode_fixup(struct drm_encoder *encoder,
-			   struct drm_display_mode *mode,
-			   struct drm_display_mode *adjusted_mode)
-{
-	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-	struct drm_device *dev = encoder->dev;
-	struct radeon_device *rdev = dev->dev_private;
-	struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
-
-	if (mode->hdisplay < native_mode->hdisplay ||
-	    mode->vdisplay < native_mode->vdisplay) {
-		int mode_id = adjusted_mode->base.id;
-		*adjusted_mode = *native_mode;
-		if (!ASIC_IS_AVIVO(rdev)) {
-			adjusted_mode->hdisplay = mode->hdisplay;
-			adjusted_mode->vdisplay = mode->vdisplay;
-		}
-		adjusted_mode->base.id = mode_id;
-	}
-}
-
-
 static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
 				   struct drm_display_mode *mode,
 				   struct drm_display_mode *adjusted_mode)
@@ -198,14 +220,24 @@
 	radeon_encoder_set_active_device(encoder);
 	drm_mode_set_crtcinfo(adjusted_mode, 0);
 
-	if (radeon_encoder->rmx_type != RMX_OFF)
-		radeon_rmx_mode_fixup(encoder, mode, adjusted_mode);
-
 	/* hw bug */
 	if ((mode->flags & DRM_MODE_FLAG_INTERLACE)
 	    && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2)))
 		adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;
 
+	/* get the native mode for LVDS */
+	if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
+		struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
+		int mode_id = adjusted_mode->base.id;
+		*adjusted_mode = *native_mode;
+		if (!ASIC_IS_AVIVO(rdev)) {
+			adjusted_mode->hdisplay = mode->hdisplay;
+			adjusted_mode->vdisplay = mode->vdisplay;
+		}
+		adjusted_mode->base.id = mode_id;
+	}
+
+	/* get the native mode for TV */
 	if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
 		struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
 		if (tv_dac) {
@@ -218,6 +250,12 @@
 		}
 	}
 
+	if (ASIC_IS_DCE3(rdev) &&
+	    (radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT))) {
+		struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+		radeon_dp_set_link_config(connector, mode);
+	}
+
 	return true;
 }
 
@@ -392,7 +430,7 @@
 	LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 v2;
 };
 
-static void
+void
 atombios_digital_setup(struct drm_encoder *encoder, int action)
 {
 	struct drm_device *dev = encoder->dev;
@@ -522,6 +560,7 @@
 {
 	struct drm_connector *connector;
 	struct radeon_connector *radeon_connector;
+	struct radeon_connector_atom_dig *radeon_dig_connector;
 
 	connector = radeon_get_connector_for_encoder(encoder);
 	if (!connector)
@@ -551,10 +590,10 @@
 		return ATOM_ENCODER_MODE_LVDS;
 		break;
 	case DRM_MODE_CONNECTOR_DisplayPort:
-		/*if (radeon_output->MonType == MT_DP)
-		  return ATOM_ENCODER_MODE_DP;
-		  else*/
-		if (drm_detect_hdmi_monitor(radeon_connector->edid))
+		radeon_dig_connector = radeon_connector->con_priv;
+		if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT)
+			return ATOM_ENCODER_MODE_DP;
+		else if (drm_detect_hdmi_monitor(radeon_connector->edid))
 			return ATOM_ENCODER_MODE_HDMI;
 		else
 			return ATOM_ENCODER_MODE_DVI;
@@ -573,6 +612,30 @@
 	}
 }
 
+/*
+ * DIG Encoder/Transmitter Setup
+ *
+ * DCE 3.0/3.1
+ * - 2 DIG transmitter blocks. UNIPHY (links A and B) and LVTMA.
+ * Supports up to 3 digital outputs
+ * - 2 DIG encoder blocks.
+ * DIG1 can drive UNIPHY link A or link B
+ * DIG2 can drive UNIPHY link B or LVTMA
+ *
+ * DCE 3.2
+ * - 3 DIG transmitter blocks. UNIPHY0/1/2 (links A and B).
+ * Supports up to 5 digital outputs
+ * - 2 DIG encoder blocks.
+ * DIG1/2 can drive UNIPHY0/1/2 link A or link B
+ *
+ * Routing
+ * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links)
+ * Examples:
+ * crtc0 -> dig2 -> LVTMA   links A+B -> TMDS/HDMI
+ * crtc1 -> dig1 -> UNIPHY0 link  B   -> DP
+ * crtc0 -> dig1 -> UNIPHY2 link  A   -> LVDS
+ * crtc1 -> dig2 -> UNIPHY1 link  B+A -> TMDS/HDMI
+ */
 static void
 atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
 {
@@ -614,10 +677,17 @@
 	} else {
 		switch (radeon_encoder->encoder_id) {
 		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-			index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
+			/* XXX doesn't really matter which dig encoder we pick as long as it's
+			 * not already in use
+			 */
+			if (dig_connector->linkb)
+				index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
+			else
+				index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
 			num = 1;
 			break;
 		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+			/* Only dig2 encoder can drive LVTMA */
 			index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
 			num = 2;
 			break;
@@ -652,19 +722,22 @@
 		}
 	}
 
-	if (radeon_encoder->pixel_clock > 165000) {
-		args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA_B;
-		args.ucLaneNum = 8;
-	} else {
-		if (dig_connector->linkb)
-			args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
-		else
-			args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
-		args.ucLaneNum = 4;
-	}
-
 	args.ucEncoderMode = atombios_get_encoder_mode(encoder);
 
+	if (args.ucEncoderMode == ATOM_ENCODER_MODE_DP) {
+		if (dig_connector->dp_clock == 270000)
+			args.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
+		args.ucLaneNum = dig_connector->dp_lane_count;
+	} else if (radeon_encoder->pixel_clock > 165000)
+		args.ucLaneNum = 8;
+	else
+		args.ucLaneNum = 4;
+
+	if (dig_connector->linkb)
+		args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
+	else
+		args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
+
 	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 
 }
@@ -674,8 +747,8 @@
 	DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2;
 };
 
-static void
-atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action)
+void
+atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set)
 {
 	struct drm_device *dev = encoder->dev;
 	struct radeon_device *rdev = dev->dev_private;
@@ -687,6 +760,7 @@
 	struct drm_connector *connector;
 	struct radeon_connector *radeon_connector;
 	struct radeon_connector_atom_dig *dig_connector;
+	bool is_dp = false;
 
 	connector = radeon_get_connector_for_encoder(encoder);
 	if (!connector)
@@ -704,6 +778,9 @@
 
 	dig_connector = radeon_connector->con_priv;
 
+	if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP)
+		is_dp = true;
+
 	memset(&args, 0, sizeof(args));
 
 	if (ASIC_IS_DCE32(rdev))
@@ -724,17 +801,23 @@
 	args.v1.ucAction = action;
 	if (action == ATOM_TRANSMITTER_ACTION_INIT) {
 		args.v1.usInitInfo = radeon_connector->connector_object_id;
+	} else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {
+		args.v1.asMode.ucLaneSel = lane_num;
+		args.v1.asMode.ucLaneSet = lane_set;
 	} else {
-		if (radeon_encoder->pixel_clock > 165000)
+		if (is_dp)
+			args.v1.usPixelClock =
+				cpu_to_le16(dig_connector->dp_clock / 10);
+		else if (radeon_encoder->pixel_clock > 165000)
 			args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
 		else
 			args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
 	}
 	if (ASIC_IS_DCE32(rdev)) {
-		if (radeon_encoder->pixel_clock > 165000)
-			args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
 		if (dig->dig_block)
 			args.v2.acConfig.ucEncoderSel = 1;
+		if (dig_connector->linkb)
+			args.v2.acConfig.ucLinkSel = 1;
 
 		switch (radeon_encoder->encoder_id) {
 		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
@@ -751,7 +834,9 @@
 			break;
 		}
 
-		if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
+		if (is_dp)
+			args.v2.acConfig.fCoherentMode = 1;
+		else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
 			if (dig->coherent_mode)
 				args.v2.acConfig.fCoherentMode = 1;
 		}
@@ -760,17 +845,20 @@
 
 		switch (radeon_encoder->encoder_id) {
 		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
+			/* XXX doesn't really matter which dig encoder we pick as long as it's
+			 * not already in use
+			 */
+			if (dig_connector->linkb)
+				args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
+			else
+				args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
 			if (rdev->flags & RADEON_IS_IGP) {
 				if (radeon_encoder->pixel_clock > 165000) {
-					args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
-							     ATOM_TRANSMITTER_CONFIG_LINKA_B);
 					if (dig_connector->igp_lane_info & 0x3)
 						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
 					else if (dig_connector->igp_lane_info & 0xc)
 						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
 				} else {
-					args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;
 					if (dig_connector->igp_lane_info & 0x1)
 						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
 					else if (dig_connector->igp_lane_info & 0x2)
@@ -780,35 +868,25 @@
 					else if (dig_connector->igp_lane_info & 0x8)
 						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
 				}
-			} else {
-				if (radeon_encoder->pixel_clock > 165000)
-					args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
-							     ATOM_TRANSMITTER_CONFIG_LINKA_B |
-							     ATOM_TRANSMITTER_CONFIG_LANE_0_7);
-				else {
-					if (dig_connector->linkb)
-						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
-					else
-						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
-				}
 			}
 			break;
 		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+			/* Only dig2 encoder can drive LVTMA */
 			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
-			if (radeon_encoder->pixel_clock > 165000)
-				args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
-						     ATOM_TRANSMITTER_CONFIG_LINKA_B |
-						     ATOM_TRANSMITTER_CONFIG_LANE_0_7);
-			else {
-				if (dig_connector->linkb)
-					args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
-				else
-					args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
-			}
 			break;
 		}
 
-		if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
+		if (radeon_encoder->pixel_clock > 165000)
+			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK;
+
+		if (dig_connector->linkb)
+			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB;
+		else
+			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;
+
+		if (is_dp)
+			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
+		else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
 			if (dig->coherent_mode)
 				args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
 		}
@@ -918,12 +996,16 @@
 	if (is_dig) {
 		switch (mode) {
 		case DRM_MODE_DPMS_ON:
-			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE);
+			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
+			{
+				struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+				dp_link_train(encoder, connector);
+			}
 			break;
 		case DRM_MODE_DPMS_STANDBY:
 		case DRM_MODE_DPMS_SUSPEND:
 		case DRM_MODE_DPMS_OFF:
-			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE);
+			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
 			break;
 		}
 	} else {
@@ -1025,13 +1107,33 @@
 						args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
 					else
 						args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
-				} else
-					args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
+				} else {
+					struct drm_connector *connector;
+					struct radeon_connector *radeon_connector;
+					struct radeon_connector_atom_dig *dig_connector;
+
+					connector = radeon_get_connector_for_encoder(encoder);
+					if (!connector)
+						return;
+					radeon_connector = to_radeon_connector(connector);
+					if (!radeon_connector->con_priv)
+						return;
+					dig_connector = radeon_connector->con_priv;
+
+					/* XXX doesn't really matter which dig encoder we pick as long as it's
+					 * not already in use
+					 */
+					if (dig_connector->linkb)
+						args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
+					else
+						args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
+				}
 				break;
 			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
 				args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID;
 				break;
 			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+				/* Only dig2 encoder can drive LVTMA */
 				args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
 				break;
 			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
@@ -1104,11 +1206,14 @@
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
 
-	if (radeon_encoder->enc_priv) {
-		struct radeon_encoder_atom_dig *dig;
+	if (radeon_encoder->active_device &
+	    (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) {
+		if (radeon_encoder->enc_priv) {
+			struct radeon_encoder_atom_dig *dig;
 
-		dig = radeon_encoder->enc_priv;
-		dig->dig_block = radeon_crtc->crtc_id;
+			dig = radeon_encoder->enc_priv;
+			dig->dig_block = radeon_crtc->crtc_id;
+		}
 	}
 	radeon_encoder->pixel_clock = adjusted_mode->clock;
 
@@ -1134,14 +1239,14 @@
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
 		/* disable the encoder and transmitter */
-		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE);
+		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
 		atombios_dig_encoder_setup(encoder, ATOM_DISABLE);
 
 		/* setup and enable the encoder and transmitter */
 		atombios_dig_encoder_setup(encoder, ATOM_ENABLE);
-		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT);
-		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP);
-		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE);
+		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);
+		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
+		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
 		break;
 	case ENCODER_OBJECT_ID_INTERNAL_DDI:
 		atombios_ddia_setup(encoder, ATOM_ENABLE);
@@ -1354,7 +1459,6 @@
 		encoder->possible_crtcs = 0x1;
 	else
 		encoder->possible_crtcs = 0x3;
-	encoder->possible_clones = 0;
 
 	radeon_encoder->enc_priv = NULL;
 
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index b38c4c8..3ba213d 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -59,7 +59,7 @@
 };
 
 /**
- * Curretly it is assumed that the old framebuffer is reused.
+ * Currently it is assumed that the old framebuffer is reused.
  *
  * LOCKING
  * caller should hold the mode config lock.
@@ -140,7 +140,7 @@
 	struct radeon_framebuffer *rfb;
 	struct drm_mode_fb_cmd mode_cmd;
 	struct drm_gem_object *gobj = NULL;
-	struct radeon_object *robj = NULL;
+	struct radeon_bo *rbo = NULL;
 	struct device *device = &rdev->pdev->dev;
 	int size, aligned_size, ret;
 	u64 fb_gpuaddr;
@@ -168,14 +168,14 @@
 	ret = radeon_gem_object_create(rdev, aligned_size, 0,
 			RADEON_GEM_DOMAIN_VRAM,
 			false, ttm_bo_type_kernel,
-			false, &gobj);
+			&gobj);
 	if (ret) {
 		printk(KERN_ERR "failed to allocate framebuffer (%d %d)\n",
 		       surface_width, surface_height);
 		ret = -ENOMEM;
 		goto out;
 	}
-	robj = gobj->driver_private;
+	rbo = gobj->driver_private;
 
 	if (fb_tiled)
 		tiling_flags = RADEON_TILING_MACRO;
@@ -192,8 +192,13 @@
 	}
 #endif
 
-	if (tiling_flags)
-		radeon_object_set_tiling_flags(robj, tiling_flags | RADEON_TILING_SURFACE, mode_cmd.pitch);
+	if (tiling_flags) {
+		ret = radeon_bo_set_tiling_flags(rbo,
+					tiling_flags | RADEON_TILING_SURFACE,
+					mode_cmd.pitch);
+		if (ret)
+			dev_err(rdev->dev, "FB failed to set tiling flags\n");
+	}
 	mutex_lock(&rdev->ddev->struct_mutex);
 	fb = radeon_framebuffer_create(rdev->ddev, &mode_cmd, gobj);
 	if (fb == NULL) {
@@ -201,10 +206,19 @@
 		ret = -ENOMEM;
 		goto out_unref;
 	}
-	ret = radeon_object_pin(robj, RADEON_GEM_DOMAIN_VRAM, &fb_gpuaddr);
+	ret = radeon_bo_reserve(rbo, false);
+	if (unlikely(ret != 0))
+		goto out_unref;
+	ret = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_gpuaddr);
 	if (ret) {
-		printk(KERN_ERR "failed to pin framebuffer\n");
-		ret = -ENOMEM;
+		radeon_bo_unreserve(rbo);
+		goto out_unref;
+	}
+	if (fb_tiled)
+		radeon_bo_check_tiling(rbo, 0, 0);
+	ret = radeon_bo_kmap(rbo, &fbptr);
+	radeon_bo_unreserve(rbo);
+	if (ret) {
 		goto out_unref;
 	}
 
@@ -213,7 +227,7 @@
 	*fb_p = fb;
 	rfb = to_radeon_framebuffer(fb);
 	rdev->fbdev_rfb = rfb;
-	rdev->fbdev_robj = robj;
+	rdev->fbdev_rbo = rbo;
 
 	info = framebuffer_alloc(sizeof(struct radeon_fb_device), device);
 	if (info == NULL) {
@@ -234,15 +248,7 @@
 	if (ret)
 		goto out_unref;
 
-	if (fb_tiled)
-		radeon_object_check_tiling(robj, 0, 0);
-
-	ret = radeon_object_kmap(robj, &fbptr);
-	if (ret) {
-		goto out_unref;
-	}
-
-	memset_io(fbptr, 0, aligned_size);
+	memset_io(fbptr, 0xff, aligned_size);
 
 	strcpy(info->fix.id, "radeondrmfb");
 
@@ -288,8 +294,12 @@
 	return 0;
 
 out_unref:
-	if (robj) {
-		radeon_object_kunmap(robj);
+	if (rbo) {
+		ret = radeon_bo_reserve(rbo, false);
+		if (likely(ret == 0)) {
+			radeon_bo_kunmap(rbo);
+			radeon_bo_unreserve(rbo);
+		}
 	}
 	if (fb && ret) {
 		list_del(&fb->filp_head);
@@ -321,14 +331,22 @@
 
 int radeonfb_probe(struct drm_device *dev)
 {
-	return drm_fb_helper_single_fb_probe(dev, 32, &radeonfb_create);
+	struct radeon_device *rdev = dev->dev_private;
+	int bpp_sel = 32;
+
+	/* select 8 bpp console on RN50 or 16MB cards */
+	if (ASIC_IS_RN50(rdev) || rdev->mc.real_vram_size <= (32*1024*1024))
+		bpp_sel = 8;
+
+	return drm_fb_helper_single_fb_probe(dev, bpp_sel, &radeonfb_create);
 }
 
 int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
 {
 	struct fb_info *info;
 	struct radeon_framebuffer *rfb = to_radeon_framebuffer(fb);
-	struct radeon_object *robj;
+	struct radeon_bo *rbo;
+	int r;
 
 	if (!fb) {
 		return -EINVAL;
@@ -336,10 +354,14 @@
 	info = fb->fbdev;
 	if (info) {
 		struct radeon_fb_device *rfbdev = info->par;
-		robj = rfb->obj->driver_private;
+		rbo = rfb->obj->driver_private;
 		unregister_framebuffer(info);
-		radeon_object_kunmap(robj);
-		radeon_object_unpin(robj);
+		r = radeon_bo_reserve(rbo, false);
+		if (likely(r == 0)) {
+			radeon_bo_kunmap(rbo);
+			radeon_bo_unpin(rbo);
+			radeon_bo_unreserve(rbo);
+		}
 		drm_fb_helper_free(&rfbdev->helper);
 		framebuffer_release(info);
 	}
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c
index 3beb26d..cb4cd97 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -168,37 +168,6 @@
 	return signaled;
 }
 
-int r600_fence_wait(struct radeon_fence *fence,  bool intr, bool lazy)
-{
-	struct radeon_device *rdev;
-	int ret = 0;
-
-	rdev = fence->rdev;
-
-	__set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
-
-	while (1) {
-		if (radeon_fence_signaled(fence))
-			break;
-
-		if (time_after_eq(jiffies, fence->timeout)) {
-			ret = -EBUSY;
-			break;
-		}
-
-		if (lazy)
-			schedule_timeout(1);
-
-		if (intr && signal_pending(current)) {
-			ret = -ERESTARTSYS;
-			break;
-		}
-	}
-	__set_current_state(TASK_RUNNING);
-	return ret;
-}
-
-
 int radeon_fence_wait(struct radeon_fence *fence, bool intr)
 {
 	struct radeon_device *rdev;
@@ -216,13 +185,6 @@
 		return 0;
 	}
 
-	if (rdev->family >= CHIP_R600) {
-		r = r600_fence_wait(fence, intr, 0);
-		if (r == -ERESTARTSYS)
-			return -EBUSY;
-		return r;
-	}
-
 retry:
 	cur_jiffies = jiffies;
 	timeout = HZ / 100;
@@ -231,14 +193,17 @@
 	}
 
 	if (intr) {
+		radeon_irq_kms_sw_irq_get(rdev);
 		r = wait_event_interruptible_timeout(rdev->fence_drv.queue,
 				radeon_fence_signaled(fence), timeout);
-		if (unlikely(r == -ERESTARTSYS)) {
-			return -EBUSY;
-		}
+		radeon_irq_kms_sw_irq_put(rdev);
+		if (unlikely(r < 0))
+			return r;
 	} else {
+		radeon_irq_kms_sw_irq_get(rdev);
 		r = wait_event_timeout(rdev->fence_drv.queue,
 			 radeon_fence_signaled(fence), timeout);
+		radeon_irq_kms_sw_irq_put(rdev);
 	}
 	if (unlikely(!radeon_fence_signaled(fence))) {
 		if (unlikely(r == 0)) {
diff --git a/drivers/gpu/drm/radeon/radeon_fixed.h b/drivers/gpu/drm/radeon/radeon_fixed.h
index 90187d1..3d4d84e 100644
--- a/drivers/gpu/drm/radeon/radeon_fixed.h
+++ b/drivers/gpu/drm/radeon/radeon_fixed.h
@@ -38,6 +38,23 @@
 #define fixed_init_half(A) { .full = rfixed_const_half((A)) }
 #define rfixed_trunc(A) ((A).full >> 12)
 
+static inline u32 rfixed_floor(fixed20_12 A)
+{
+	u32 non_frac = rfixed_trunc(A);
+
+	return rfixed_const(non_frac);
+}
+
+static inline u32 rfixed_ceil(fixed20_12 A)
+{
+	u32 non_frac = rfixed_trunc(A);
+
+	if (A.full > rfixed_const(non_frac))
+		return rfixed_const(non_frac + 1);
+	else
+		return rfixed_const(non_frac);
+}
+
 static inline u32 rfixed_div(fixed20_12 A, fixed20_12 B)
 {
 	u64 tmp = ((u64)A.full << 13);
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c
index a68d756..e73d56e 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -78,11 +78,9 @@
 	int r;
 
 	if (rdev->gart.table.vram.robj == NULL) {
-		r = radeon_object_create(rdev, NULL,
-					 rdev->gart.table_size,
-					 true,
-					 RADEON_GEM_DOMAIN_VRAM,
-					 false, &rdev->gart.table.vram.robj);
+		r = radeon_bo_create(rdev, NULL, rdev->gart.table_size,
+					true, RADEON_GEM_DOMAIN_VRAM,
+					&rdev->gart.table.vram.robj);
 		if (r) {
 			return r;
 		}
@@ -95,32 +93,38 @@
 	uint64_t gpu_addr;
 	int r;
 
-	r = radeon_object_pin(rdev->gart.table.vram.robj,
-			      RADEON_GEM_DOMAIN_VRAM, &gpu_addr);
+	r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
+	if (unlikely(r != 0))
+		return r;
+	r = radeon_bo_pin(rdev->gart.table.vram.robj,
+				RADEON_GEM_DOMAIN_VRAM, &gpu_addr);
 	if (r) {
-		radeon_object_unref(&rdev->gart.table.vram.robj);
+		radeon_bo_unreserve(rdev->gart.table.vram.robj);
 		return r;
 	}
-	r = radeon_object_kmap(rdev->gart.table.vram.robj,
-			       (void **)&rdev->gart.table.vram.ptr);
-	if (r) {
-		radeon_object_unpin(rdev->gart.table.vram.robj);
-		radeon_object_unref(&rdev->gart.table.vram.robj);
-		DRM_ERROR("radeon: failed to map gart vram table.\n");
-		return r;
-	}
+	r = radeon_bo_kmap(rdev->gart.table.vram.robj,
+				(void **)&rdev->gart.table.vram.ptr);
+	if (r)
+		radeon_bo_unpin(rdev->gart.table.vram.robj);
+	radeon_bo_unreserve(rdev->gart.table.vram.robj);
 	rdev->gart.table_addr = gpu_addr;
-	return 0;
+	return r;
 }
 
 void radeon_gart_table_vram_free(struct radeon_device *rdev)
 {
+	int r;
+
 	if (rdev->gart.table.vram.robj == NULL) {
 		return;
 	}
-	radeon_object_kunmap(rdev->gart.table.vram.robj);
-	radeon_object_unpin(rdev->gart.table.vram.robj);
-	radeon_object_unref(&rdev->gart.table.vram.robj);
+	r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
+	if (likely(r == 0)) {
+		radeon_bo_kunmap(rdev->gart.table.vram.robj);
+		radeon_bo_unpin(rdev->gart.table.vram.robj);
+		radeon_bo_unreserve(rdev->gart.table.vram.robj);
+	}
+	radeon_bo_unref(&rdev->gart.table.vram.robj);
 }
 
 
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
index d880edf..2944486 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -38,22 +38,21 @@
 
 void radeon_gem_object_free(struct drm_gem_object *gobj)
 {
-	struct radeon_object *robj = gobj->driver_private;
+	struct radeon_bo *robj = gobj->driver_private;
 
 	gobj->driver_private = NULL;
 	if (robj) {
-		radeon_object_unref(&robj);
+		radeon_bo_unref(&robj);
 	}
 }
 
 int radeon_gem_object_create(struct radeon_device *rdev, int size,
-			     int alignment, int initial_domain,
-			     bool discardable, bool kernel,
-			     bool interruptible,
-			     struct drm_gem_object **obj)
+				int alignment, int initial_domain,
+				bool discardable, bool kernel,
+				struct drm_gem_object **obj)
 {
 	struct drm_gem_object *gobj;
-	struct radeon_object *robj;
+	struct radeon_bo *robj;
 	int r;
 
 	*obj = NULL;
@@ -65,8 +64,7 @@
 	if (alignment < PAGE_SIZE) {
 		alignment = PAGE_SIZE;
 	}
-	r = radeon_object_create(rdev, gobj, size, kernel, initial_domain,
-				 interruptible, &robj);
+	r = radeon_bo_create(rdev, gobj, size, kernel, initial_domain, &robj);
 	if (r) {
 		DRM_ERROR("Failed to allocate GEM object (%d, %d, %u)\n",
 			  size, initial_domain, alignment);
@@ -83,33 +81,33 @@
 int radeon_gem_object_pin(struct drm_gem_object *obj, uint32_t pin_domain,
 			  uint64_t *gpu_addr)
 {
-	struct radeon_object *robj = obj->driver_private;
-	uint32_t flags;
+	struct radeon_bo *robj = obj->driver_private;
+	int r;
 
-	switch (pin_domain) {
-	case RADEON_GEM_DOMAIN_VRAM:
-		flags = TTM_PL_FLAG_VRAM;
-		break;
-	case RADEON_GEM_DOMAIN_GTT:
-		flags = TTM_PL_FLAG_TT;
-		break;
-	default:
-		flags = TTM_PL_FLAG_SYSTEM;
-		break;
-	}
-	return radeon_object_pin(robj, flags, gpu_addr);
+	r = radeon_bo_reserve(robj, false);
+	if (unlikely(r != 0))
+		return r;
+	r = radeon_bo_pin(robj, pin_domain, gpu_addr);
+	radeon_bo_unreserve(robj);
+	return r;
 }
 
 void radeon_gem_object_unpin(struct drm_gem_object *obj)
 {
-	struct radeon_object *robj = obj->driver_private;
-	radeon_object_unpin(robj);
+	struct radeon_bo *robj = obj->driver_private;
+	int r;
+
+	r = radeon_bo_reserve(robj, false);
+	if (likely(r == 0)) {
+		radeon_bo_unpin(robj);
+		radeon_bo_unreserve(robj);
+	}
 }
 
 int radeon_gem_set_domain(struct drm_gem_object *gobj,
 			  uint32_t rdomain, uint32_t wdomain)
 {
-	struct radeon_object *robj;
+	struct radeon_bo *robj;
 	uint32_t domain;
 	int r;
 
@@ -127,11 +125,12 @@
 	}
 	if (domain == RADEON_GEM_DOMAIN_CPU) {
 		/* Asking for cpu access wait for object idle */
-		r = radeon_object_wait(robj);
+		r = radeon_bo_wait(robj, NULL, false);
 		if (r) {
 			printk(KERN_ERR "Failed to wait for object !\n");
 			return r;
 		}
+		radeon_hdp_flush(robj->rdev);
 	}
 	return 0;
 }
@@ -144,7 +143,7 @@
 
 void radeon_gem_fini(struct radeon_device *rdev)
 {
-	radeon_object_force_delete(rdev);
+	radeon_bo_force_delete(rdev);
 }
 
 
@@ -158,9 +157,13 @@
 	struct drm_radeon_gem_info *args = data;
 
 	args->vram_size = rdev->mc.real_vram_size;
-	/* FIXME: report somethings that makes sense */
-	args->vram_visible = rdev->mc.real_vram_size - (4 * 1024 * 1024);
-	args->gart_size = rdev->mc.gtt_size;
+	args->vram_visible = rdev->mc.real_vram_size;
+	if (rdev->stollen_vga_memory)
+		args->vram_visible -= radeon_bo_size(rdev->stollen_vga_memory);
+	if (rdev->fbdev_rbo)
+		args->vram_visible -= radeon_bo_size(rdev->fbdev_rbo);
+	args->gart_size = rdev->mc.gtt_size - rdev->cp.ring_size - 4096 -
+		RADEON_IB_POOL_SIZE*64*1024;
 	return 0;
 }
 
@@ -192,8 +195,8 @@
 	/* create a gem object to contain this object in */
 	args->size = roundup(args->size, PAGE_SIZE);
 	r = radeon_gem_object_create(rdev, args->size, args->alignment,
-				     args->initial_domain, false,
-				     false, true, &gobj);
+					args->initial_domain, false,
+					false, &gobj);
 	if (r) {
 		return r;
 	}
@@ -218,7 +221,7 @@
 	 * just validate the BO into a certain domain */
 	struct drm_radeon_gem_set_domain *args = data;
 	struct drm_gem_object *gobj;
-	struct radeon_object *robj;
+	struct radeon_bo *robj;
 	int r;
 
 	/* for now if someone requests domain CPU -
@@ -244,19 +247,18 @@
 {
 	struct drm_radeon_gem_mmap *args = data;
 	struct drm_gem_object *gobj;
-	struct radeon_object *robj;
-	int r;
+	struct radeon_bo *robj;
 
 	gobj = drm_gem_object_lookup(dev, filp, args->handle);
 	if (gobj == NULL) {
 		return -EINVAL;
 	}
 	robj = gobj->driver_private;
-	r = radeon_object_mmap(robj, &args->addr_ptr);
+	args->addr_ptr = radeon_bo_mmap_offset(robj);
 	mutex_lock(&dev->struct_mutex);
 	drm_gem_object_unreference(gobj);
 	mutex_unlock(&dev->struct_mutex);
-	return r;
+	return 0;
 }
 
 int radeon_gem_busy_ioctl(struct drm_device *dev, void *data,
@@ -264,16 +266,16 @@
 {
 	struct drm_radeon_gem_busy *args = data;
 	struct drm_gem_object *gobj;
-	struct radeon_object *robj;
+	struct radeon_bo *robj;
 	int r;
-	uint32_t cur_placement;
+	uint32_t cur_placement = 0;
 
 	gobj = drm_gem_object_lookup(dev, filp, args->handle);
 	if (gobj == NULL) {
 		return -EINVAL;
 	}
 	robj = gobj->driver_private;
-	r = radeon_object_busy_domain(robj, &cur_placement);
+	r = radeon_bo_wait(robj, &cur_placement, true);
 	switch (cur_placement) {
 	case TTM_PL_VRAM:
 		args->domain = RADEON_GEM_DOMAIN_VRAM;
@@ -297,7 +299,7 @@
 {
 	struct drm_radeon_gem_wait_idle *args = data;
 	struct drm_gem_object *gobj;
-	struct radeon_object *robj;
+	struct radeon_bo *robj;
 	int r;
 
 	gobj = drm_gem_object_lookup(dev, filp, args->handle);
@@ -305,10 +307,11 @@
 		return -EINVAL;
 	}
 	robj = gobj->driver_private;
-	r = radeon_object_wait(robj);
+	r = radeon_bo_wait(robj, NULL, false);
 	mutex_lock(&dev->struct_mutex);
 	drm_gem_object_unreference(gobj);
 	mutex_unlock(&dev->struct_mutex);
+	radeon_hdp_flush(robj->rdev);
 	return r;
 }
 
@@ -317,7 +320,7 @@
 {
 	struct drm_radeon_gem_set_tiling *args = data;
 	struct drm_gem_object *gobj;
-	struct radeon_object *robj;
+	struct radeon_bo *robj;
 	int r = 0;
 
 	DRM_DEBUG("%d \n", args->handle);
@@ -325,7 +328,7 @@
 	if (gobj == NULL)
 		return -EINVAL;
 	robj = gobj->driver_private;
-	radeon_object_set_tiling_flags(robj, args->tiling_flags, args->pitch);
+	r = radeon_bo_set_tiling_flags(robj, args->tiling_flags, args->pitch);
 	mutex_lock(&dev->struct_mutex);
 	drm_gem_object_unreference(gobj);
 	mutex_unlock(&dev->struct_mutex);
@@ -337,16 +340,19 @@
 {
 	struct drm_radeon_gem_get_tiling *args = data;
 	struct drm_gem_object *gobj;
-	struct radeon_object *robj;
+	struct radeon_bo *rbo;
 	int r = 0;
 
 	DRM_DEBUG("\n");
 	gobj = drm_gem_object_lookup(dev, filp, args->handle);
 	if (gobj == NULL)
 		return -EINVAL;
-	robj = gobj->driver_private;
-	radeon_object_get_tiling_flags(robj, &args->tiling_flags,
-				       &args->pitch);
+	rbo = gobj->driver_private;
+	r = radeon_bo_reserve(rbo, false);
+	if (unlikely(r != 0))
+		return r;
+	radeon_bo_get_tiling_flags(rbo, &args->tiling_flags, &args->pitch);
+	radeon_bo_unreserve(rbo);
 	mutex_lock(&dev->struct_mutex);
 	drm_gem_object_unreference(gobj);
 	mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c
index dd438d3..da3da1e 100644
--- a/drivers/gpu/drm/radeon/radeon_i2c.c
+++ b/drivers/gpu/drm/radeon/radeon_i2c.c
@@ -59,35 +59,43 @@
 }
 
 
-void radeon_i2c_do_lock(struct radeon_connector *radeon_connector, int lock_state)
+void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state)
 {
-	struct radeon_device *rdev = radeon_connector->base.dev->dev_private;
+	struct radeon_device *rdev = i2c->dev->dev_private;
+	struct radeon_i2c_bus_rec *rec = &i2c->rec;
 	uint32_t temp;
-	struct radeon_i2c_bus_rec *rec = &radeon_connector->ddc_bus->rec;
 
 	/* RV410 appears to have a bug where the hw i2c in reset
 	 * holds the i2c port in a bad state - switch hw i2c away before
 	 * doing DDC - do this for all r200s/r300s/r400s for safety sake
 	 */
-	if ((rdev->family >= CHIP_R200) && !ASIC_IS_AVIVO(rdev)) {
-		if (rec->a_clk_reg == RADEON_GPIO_MONID) {
-			WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST |
-						R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1)));
-		} else {
-			WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST |
-						R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3)));
+	if (rec->hw_capable) {
+		if ((rdev->family >= CHIP_R200) && !ASIC_IS_AVIVO(rdev)) {
+			if (rec->a_clk_reg == RADEON_GPIO_MONID) {
+				WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST |
+							       R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1)));
+			} else {
+				WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST |
+							       R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3)));
+			}
 		}
 	}
-	if (lock_state) {
-		temp = RREG32(rec->a_clk_reg);
-		temp &= ~(rec->a_clk_mask);
-		WREG32(rec->a_clk_reg, temp);
 
-		temp = RREG32(rec->a_data_reg);
-		temp &= ~(rec->a_data_mask);
-		WREG32(rec->a_data_reg, temp);
-	}
+	/* clear the output pin values */
+	temp = RREG32(rec->a_clk_reg) & ~rec->a_clk_mask;
+	WREG32(rec->a_clk_reg, temp);
 
+	temp = RREG32(rec->a_data_reg) & ~rec->a_data_mask;
+	WREG32(rec->a_data_reg, temp);
+
+	/* set the pins to input */
+	temp = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask;
+	WREG32(rec->en_clk_reg, temp);
+
+	temp = RREG32(rec->en_data_reg) & ~rec->en_data_mask;
+	WREG32(rec->en_data_reg, temp);
+
+	/* mask the gpio pins for software use */
 	temp = RREG32(rec->mask_clk_reg);
 	if (lock_state)
 		temp |= rec->mask_clk_mask;
@@ -112,8 +120,9 @@
 	struct radeon_i2c_bus_rec *rec = &i2c->rec;
 	uint32_t val;
 
-	val = RREG32(rec->get_clk_reg);
-	val &= rec->get_clk_mask;
+	/* read the value off the pin */
+	val = RREG32(rec->y_clk_reg);
+	val &= rec->y_clk_mask;
 
 	return (val != 0);
 }
@@ -126,8 +135,10 @@
 	struct radeon_i2c_bus_rec *rec = &i2c->rec;
 	uint32_t val;
 
-	val = RREG32(rec->get_data_reg);
-	val &= rec->get_data_mask;
+	/* read the value off the pin */
+	val = RREG32(rec->y_data_reg);
+	val &= rec->y_data_mask;
+
 	return (val != 0);
 }
 
@@ -138,9 +149,10 @@
 	struct radeon_i2c_bus_rec *rec = &i2c->rec;
 	uint32_t val;
 
-	val = RREG32(rec->put_clk_reg) & (uint32_t)~(rec->put_clk_mask);
-	val |= clock ? 0 : rec->put_clk_mask;
-	WREG32(rec->put_clk_reg, val);
+	/* set pin direction */
+	val = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask;
+	val |= clock ? 0 : rec->en_clk_mask;
+	WREG32(rec->en_clk_reg, val);
 }
 
 static void set_data(void *i2c_priv, int data)
@@ -150,14 +162,15 @@
 	struct radeon_i2c_bus_rec *rec = &i2c->rec;
 	uint32_t val;
 
-	val = RREG32(rec->put_data_reg) & (uint32_t)~(rec->put_data_mask);
-	val |= data ? 0 : rec->put_data_mask;
-	WREG32(rec->put_data_reg, val);
+	/* set pin direction */
+	val = RREG32(rec->en_data_reg) & ~rec->en_data_mask;
+	val |= data ? 0 : rec->en_data_mask;
+	WREG32(rec->en_data_reg, val);
 }
 
 struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
-		struct radeon_i2c_bus_rec *rec,
-		const char *name)
+					  struct radeon_i2c_bus_rec *rec,
+					  const char *name)
 {
 	struct radeon_i2c_chan *i2c;
 	int ret;
@@ -167,20 +180,19 @@
 		return NULL;
 
 	i2c->adapter.owner = THIS_MODULE;
-	i2c->adapter.algo_data = &i2c->algo;
 	i2c->dev = dev;
-	i2c->algo.setsda = set_data;
-	i2c->algo.setscl = set_clock;
-	i2c->algo.getsda = get_data;
-	i2c->algo.getscl = get_clock;
-	i2c->algo.udelay = 20;
+	i2c_set_adapdata(&i2c->adapter, i2c);
+	i2c->adapter.algo_data = &i2c->algo.bit;
+	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 = 20;
 	/* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always
 	 * make this, 2 jiffies is a lot more reliable */
-	i2c->algo.timeout = 2;
-	i2c->algo.data = i2c;
+	i2c->algo.bit.timeout = 2;
+	i2c->algo.bit.data = i2c;
 	i2c->rec = *rec;
-	i2c_set_adapdata(&i2c->adapter, i2c);
-
 	ret = i2c_bit_add_bus(&i2c->adapter);
 	if (ret) {
 		DRM_INFO("Failed to register i2c %s\n", name);
@@ -194,6 +206,38 @@
 
 }
 
+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->dev = dev;
+	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)
@@ -207,3 +251,59 @@
 {
 	return NULL;
 }
+
+void radeon_i2c_sw_get_byte(struct radeon_i2c_chan *i2c_bus,
+			    u8 slave_addr,
+			    u8 addr,
+			    u8 *val)
+{
+	u8 out_buf[2];
+	u8 in_buf[2];
+	struct i2c_msg msgs[] = {
+		{
+			.addr = slave_addr,
+			.flags = 0,
+			.len = 1,
+			.buf = out_buf,
+		},
+		{
+			.addr = slave_addr,
+			.flags = I2C_M_RD,
+			.len = 1,
+			.buf = in_buf,
+		}
+	};
+
+	out_buf[0] = addr;
+	out_buf[1] = 0;
+
+	if (i2c_transfer(&i2c_bus->adapter, msgs, 2) == 2) {
+		*val = in_buf[0];
+		DRM_DEBUG("val = 0x%02x\n", *val);
+	} else {
+		DRM_ERROR("i2c 0x%02x 0x%02x read failed\n",
+			  addr, *val);
+	}
+}
+
+void radeon_i2c_sw_put_byte(struct radeon_i2c_chan *i2c_bus,
+			    u8 slave_addr,
+			    u8 addr,
+			    u8 val)
+{
+	uint8_t out_buf[2];
+	struct i2c_msg msg = {
+		.addr = slave_addr,
+		.flags = 0,
+		.len = 2,
+		.buf = out_buf,
+	};
+
+	out_buf[0] = addr;
+	out_buf[1] = val;
+
+	if (i2c_transfer(&i2c_bus->adapter, &msg, 1) != 1)
+		DRM_ERROR("i2c 0x%02x 0x%02x write failed\n",
+			  addr, val);
+}
+
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index a0fe623..9223296 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -39,11 +39,32 @@
 	return radeon_irq_process(rdev);
 }
 
+/*
+ * Handle hotplug events outside the interrupt handler proper.
+ */
+static void radeon_hotplug_work_func(struct work_struct *work)
+{
+	struct radeon_device *rdev = container_of(work, struct radeon_device,
+						  hotplug_work);
+	struct drm_device *dev = rdev->ddev;
+	struct drm_mode_config *mode_config = &dev->mode_config;
+	struct drm_connector *connector;
+
+	if (mode_config->num_connector) {
+		list_for_each_entry(connector, &mode_config->connector_list, head)
+			radeon_connector_hotplug(connector);
+	}
+	/* Just fire off a uevent and let userspace tell us what to do */
+	drm_sysfs_hotplug_event(dev);
+}
+
 void radeon_driver_irq_preinstall_kms(struct drm_device *dev)
 {
 	struct radeon_device *rdev = dev->dev_private;
 	unsigned i;
 
+	INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func);
+
 	/* Disable *all* interrupts */
 	rdev->irq.sw_int = false;
 	for (i = 0; i < 2; i++) {
@@ -87,17 +108,25 @@
 
 	if (rdev->flags & RADEON_SINGLE_CRTC)
 		num_crtc = 1;
-
+	spin_lock_init(&rdev->irq.sw_lock);
 	r = drm_vblank_init(rdev->ddev, num_crtc);
 	if (r) {
 		return r;
 	}
 	/* enable msi */
 	rdev->msi_enabled = 0;
-	if (rdev->family >= CHIP_RV380) {
+	/* MSIs don't seem to work on my rs780;
+	 * not sure about rs880 or other rs780s.
+	 * Needs more investigation.
+	 */
+	if ((rdev->family >= CHIP_RV380) &&
+	    (rdev->family != CHIP_RS780) &&
+	    (rdev->family != CHIP_RS880)) {
 		int ret = pci_enable_msi(rdev->pdev);
-		if (!ret)
+		if (!ret) {
 			rdev->msi_enabled = 1;
+			DRM_INFO("radeon: using MSI.\n");
+		}
 	}
 	drm_irq_install(rdev->ddev);
 	rdev->irq.installed = true;
@@ -114,3 +143,29 @@
 			pci_disable_msi(rdev->pdev);
 	}
 }
+
+void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev)
+{
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&rdev->irq.sw_lock, irqflags);
+	if (rdev->ddev->irq_enabled && (++rdev->irq.sw_refcount == 1)) {
+		rdev->irq.sw_int = true;
+		radeon_irq_set(rdev);
+	}
+	spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags);
+}
+
+void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev)
+{
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&rdev->irq.sw_lock, irqflags);
+	BUG_ON(rdev->ddev->irq_enabled && rdev->irq.sw_refcount <= 0);
+	if (rdev->ddev->irq_enabled && (--rdev->irq.sw_refcount == 0)) {
+		rdev->irq.sw_int = false;
+		radeon_irq_set(rdev);
+	}
+	spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags);
+}
+
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index ba12862..f23b056 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -30,10 +30,19 @@
 #include "radeon.h"
 #include "radeon_drm.h"
 
+int radeon_driver_unload_kms(struct drm_device *dev)
+{
+	struct radeon_device *rdev = dev->dev_private;
 
-/*
- * Driver load/unload
- */
+	if (rdev == NULL)
+		return 0;
+	radeon_modeset_fini(rdev);
+	radeon_device_fini(rdev);
+	kfree(rdev);
+	dev->dev_private = NULL;
+	return 0;
+}
+
 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
 {
 	struct radeon_device *rdev;
@@ -62,31 +71,20 @@
 	 */
 	r = radeon_device_init(rdev, dev, dev->pdev, flags);
 	if (r) {
-		DRM_ERROR("Fatal error while trying to initialize radeon.\n");
-		return r;
+		dev_err(&dev->pdev->dev, "Fatal error during GPU init\n");
+		goto out;
 	}
 	/* Again modeset_init should fail only on fatal error
 	 * otherwise it should provide enough functionalities
 	 * for shadowfb to run
 	 */
 	r = radeon_modeset_init(rdev);
-	if (r) {
-		return r;
-	}
-	return 0;
-}
-
-int radeon_driver_unload_kms(struct drm_device *dev)
-{
-	struct radeon_device *rdev = dev->dev_private;
-
-	if (rdev == NULL)
-		return 0;
-	radeon_modeset_fini(rdev);
-	radeon_device_fini(rdev);
-	kfree(rdev);
-	dev->dev_private = NULL;
-	return 0;
+	if (r)
+		dev_err(&dev->pdev->dev, "Fatal error during modeset init\n");
+out:
+	if (r)
+		radeon_driver_unload_kms(dev);
+	return r;
 }
 
 
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
index 8d0b7aa..b82ede9 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
@@ -30,6 +30,18 @@
 #include "radeon.h"
 #include "atom.h"
 
+static void radeon_overscan_setup(struct drm_crtc *crtc,
+				  struct drm_display_mode *mode)
+{
+	struct drm_device *dev = crtc->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+
+	WREG32(RADEON_OVR_CLR + radeon_crtc->crtc_offset, 0);
+	WREG32(RADEON_OVR_WID_LEFT_RIGHT + radeon_crtc->crtc_offset, 0);
+	WREG32(RADEON_OVR_WID_TOP_BOTTOM + radeon_crtc->crtc_offset, 0);
+}
+
 static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc,
 				       struct drm_display_mode *mode,
 				       struct drm_display_mode *adjusted_mode)
@@ -292,8 +304,7 @@
 	uint32_t mask;
 
 	if (radeon_crtc->crtc_id)
-		mask = (RADEON_CRTC2_EN |
-			RADEON_CRTC2_DISP_DIS |
+		mask = (RADEON_CRTC2_DISP_DIS |
 			RADEON_CRTC2_VSYNC_DIS |
 			RADEON_CRTC2_HSYNC_DIS |
 			RADEON_CRTC2_DISP_REQ_EN_B);
@@ -305,7 +316,7 @@
 	switch (mode) {
 	case DRM_MODE_DPMS_ON:
 		if (radeon_crtc->crtc_id)
-			WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~mask);
+			WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~(RADEON_CRTC2_EN | mask));
 		else {
 			WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN |
 									 RADEON_CRTC_DISP_REQ_EN_B));
@@ -319,7 +330,7 @@
 	case DRM_MODE_DPMS_OFF:
 		drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
 		if (radeon_crtc->crtc_id)
-			WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~mask);
+			WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~(RADEON_CRTC2_EN | mask));
 		else {
 			WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN |
 										    RADEON_CRTC_DISP_REQ_EN_B));
@@ -400,14 +411,21 @@
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 	struct radeon_framebuffer *radeon_fb;
 	struct drm_gem_object *obj;
+	struct radeon_bo *rbo;
 	uint64_t base;
 	uint32_t crtc_offset, crtc_offset_cntl, crtc_tile_x0_y0 = 0;
 	uint32_t crtc_pitch, pitch_pixels;
 	uint32_t tiling_flags;
 	int format;
 	uint32_t gen_cntl_reg, gen_cntl_val;
+	int r;
 
 	DRM_DEBUG("\n");
+	/* no fb bound */
+	if (!crtc->fb) {
+		DRM_DEBUG("No FB bound\n");
+		return 0;
+	}
 
 	radeon_fb = to_radeon_framebuffer(crtc->fb);
 
@@ -431,10 +449,22 @@
 		return false;
 	}
 
+	/* Pin framebuffer & get tilling informations */
 	obj = radeon_fb->obj;
-	if (radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &base)) {
+	rbo = obj->driver_private;
+	r = radeon_bo_reserve(rbo, false);
+	if (unlikely(r != 0))
+		return r;
+	r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &base);
+	if (unlikely(r != 0)) {
+		radeon_bo_unreserve(rbo);
 		return -EINVAL;
 	}
+	radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
+	radeon_bo_unreserve(rbo);
+	if (tiling_flags & RADEON_TILING_MICRO)
+		DRM_ERROR("trying to scanout microtiled buffer\n");
+
 	/* if scanout was in GTT this really wouldn't work */
 	/* crtc offset is from display base addr not FB location */
 	radeon_crtc->legacy_display_base_addr = rdev->mc.vram_location;
@@ -449,10 +479,6 @@
 		       (crtc->fb->bits_per_pixel * 8));
 	crtc_pitch |= crtc_pitch << 16;
 
-	radeon_object_get_tiling_flags(obj->driver_private,
-				       &tiling_flags, NULL);
-	if (tiling_flags & RADEON_TILING_MICRO)
-		DRM_ERROR("trying to scanout microtiled buffer\n");
 
 	if (tiling_flags & RADEON_TILING_MACRO) {
 		if (ASIC_IS_R300(rdev))
@@ -530,7 +556,12 @@
 
 	if (old_fb && old_fb != crtc->fb) {
 		radeon_fb = to_radeon_framebuffer(old_fb);
-		radeon_gem_object_unpin(radeon_fb->obj);
+		rbo = radeon_fb->obj->driver_private;
+		r = radeon_bo_reserve(rbo, false);
+		if (unlikely(r != 0))
+			return r;
+		radeon_bo_unpin(rbo);
+		radeon_bo_unreserve(rbo);
 	}
 
 	/* Bytes per pixel may have changed */
@@ -642,12 +673,8 @@
 		uint32_t crtc2_gen_cntl;
 		uint32_t disp2_merge_cntl;
 
-		/* check to see if TV DAC is enabled for another crtc and keep it enabled */
-		if (RREG32(RADEON_CRTC2_GEN_CNTL) & RADEON_CRTC2_CRT2_ON)
-			crtc2_gen_cntl = RADEON_CRTC2_CRT2_ON;
-		else
-			crtc2_gen_cntl = 0;
-
+		/* if TV DAC is enabled for another crtc and keep it enabled */
+		crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL) & 0x00718080;
 		crtc2_gen_cntl |= ((format << 8)
 				   | RADEON_CRTC2_VSYNC_DIS
 				   | RADEON_CRTC2_HSYNC_DIS
@@ -676,7 +703,8 @@
 		uint32_t crtc_ext_cntl;
 		uint32_t disp_merge_cntl;
 
-		crtc_gen_cntl = (RADEON_CRTC_EXT_DISP_EN
+		crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL) & 0x00718000;
+		crtc_gen_cntl |= (RADEON_CRTC_EXT_DISP_EN
 				 | (format << 8)
 				 | RADEON_CRTC_DISP_REQ_EN_B
 				 | ((mode->flags & DRM_MODE_FLAG_DBLSCAN)
@@ -779,15 +807,17 @@
 			if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
 				pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
 			if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) {
-				struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-				struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv;
-				if (lvds) {
-					if (lvds->use_bios_dividers) {
-						pll_ref_div = lvds->panel_ref_divider;
-						pll_fb_post_div   = (lvds->panel_fb_divider |
-								     (lvds->panel_post_divider << 16));
-						htotal_cntl  = 0;
-						use_bios_divs = true;
+				if (!rdev->is_atom_bios) {
+					struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+					struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv;
+					if (lvds) {
+						if (lvds->use_bios_dividers) {
+							pll_ref_div = lvds->panel_ref_divider;
+							pll_fb_post_div   = (lvds->panel_fb_divider |
+									     (lvds->panel_post_divider << 16));
+							htotal_cntl  = 0;
+							use_bios_divs = true;
+						}
 					}
 				}
 				pll_flags |= RADEON_PLL_USE_REF_DIV;
@@ -1027,6 +1057,7 @@
 	radeon_crtc_set_base(crtc, x, y, old_fb);
 	radeon_set_crtc_timing(crtc, adjusted_mode);
 	radeon_set_pll(crtc, adjusted_mode);
+	radeon_overscan_setup(crtc, adjusted_mode);
 	if (radeon_crtc->crtc_id == 0) {
 		radeon_legacy_rmx_mode_set(crtc, mode, adjusted_mode);
 	} else {
@@ -1042,12 +1073,29 @@
 
 static void radeon_crtc_prepare(struct drm_crtc *crtc)
 {
-	radeon_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+	struct drm_device *dev = crtc->dev;
+	struct drm_crtc *crtci;
+
+	/*
+	* The hardware wedges sometimes if you reconfigure one CRTC
+	* whilst another is running (see fdo bug #24611).
+	*/
+	list_for_each_entry(crtci, &dev->mode_config.crtc_list, head)
+		radeon_crtc_dpms(crtci, DRM_MODE_DPMS_OFF);
 }
 
 static void radeon_crtc_commit(struct drm_crtc *crtc)
 {
-	radeon_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
+	struct drm_device *dev = crtc->dev;
+	struct drm_crtc *crtci;
+
+	/*
+	* Reenable the CRTCs that should be running.
+	*/
+	list_for_each_entry(crtci, &dev->mode_config.crtc_list, head) {
+		if (crtci->enabled)
+			radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON);
+	}
 }
 
 static const struct drm_crtc_helper_funcs legacy_helper_funcs = {
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
index 0038212..df00515 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
@@ -136,7 +136,14 @@
 	lvds_pll_cntl &= ~RADEON_LVDS_PLL_EN;
 
 	lvds_ss_gen_cntl = RREG32(RADEON_LVDS_SS_GEN_CNTL);
-	if ((!rdev->is_atom_bios)) {
+	if (rdev->is_atom_bios) {
+		/* LVDS_GEN_CNTL parameters are computed in LVDSEncoderControl
+		 * need to call that on resume to set up the reg properly.
+		 */
+		radeon_encoder->pixel_clock = adjusted_mode->clock;
+		atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_ENABLE);
+		lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL);
+	} else {
 		struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv;
 		if (lvds) {
 			DRM_DEBUG("bios LVDS_GEN_CNTL: 0x%x\n", lvds->lvds_gen_cntl);
@@ -147,8 +154,7 @@
 					     (lvds->panel_blon_delay << RADEON_LVDS_PWRSEQ_DELAY2_SHIFT));
 		} else
 			lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL);
-	} else
-		lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL);
+	}
 	lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
 	lvds_gen_cntl &= ~(RADEON_LVDS_ON |
 			   RADEON_LVDS_BLON |
@@ -184,9 +190,9 @@
 		radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
 }
 
-static bool radeon_legacy_lvds_mode_fixup(struct drm_encoder *encoder,
-					  struct drm_display_mode *mode,
-					  struct drm_display_mode *adjusted_mode)
+static bool radeon_legacy_mode_fixup(struct drm_encoder *encoder,
+				     struct drm_display_mode *mode,
+				     struct drm_display_mode *adjusted_mode)
 {
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 
@@ -194,15 +200,22 @@
 	radeon_encoder_set_active_device(encoder);
 	drm_mode_set_crtcinfo(adjusted_mode, 0);
 
-	if (radeon_encoder->rmx_type != RMX_OFF)
-		radeon_rmx_mode_fixup(encoder, mode, adjusted_mode);
+	/* get the native mode for LVDS */
+	if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
+		struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
+		int mode_id = adjusted_mode->base.id;
+		*adjusted_mode = *native_mode;
+		adjusted_mode->hdisplay = mode->hdisplay;
+		adjusted_mode->vdisplay = mode->vdisplay;
+		adjusted_mode->base.id = mode_id;
+	}
 
 	return true;
 }
 
 static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = {
 	.dpms = radeon_legacy_lvds_dpms,
-	.mode_fixup = radeon_legacy_lvds_mode_fixup,
+	.mode_fixup = radeon_legacy_mode_fixup,
 	.prepare = radeon_legacy_lvds_prepare,
 	.mode_set = radeon_legacy_lvds_mode_set,
 	.commit = radeon_legacy_lvds_commit,
@@ -214,17 +227,6 @@
 	.destroy = radeon_enc_destroy,
 };
 
-static bool radeon_legacy_primary_dac_mode_fixup(struct drm_encoder *encoder,
-						 struct drm_display_mode *mode,
-						 struct drm_display_mode *adjusted_mode)
-{
-	/* set the active encoder to connector routing */
-	radeon_encoder_set_active_device(encoder);
-	drm_mode_set_crtcinfo(adjusted_mode, 0);
-
-	return true;
-}
-
 static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode)
 {
 	struct drm_device *dev = encoder->dev;
@@ -410,7 +412,7 @@
 
 static const struct drm_encoder_helper_funcs radeon_legacy_primary_dac_helper_funcs = {
 	.dpms = radeon_legacy_primary_dac_dpms,
-	.mode_fixup = radeon_legacy_primary_dac_mode_fixup,
+	.mode_fixup = radeon_legacy_mode_fixup,
 	.prepare = radeon_legacy_primary_dac_prepare,
 	.mode_set = radeon_legacy_primary_dac_mode_set,
 	.commit = radeon_legacy_primary_dac_commit,
@@ -423,16 +425,6 @@
 	.destroy = radeon_enc_destroy,
 };
 
-static bool radeon_legacy_tmds_int_mode_fixup(struct drm_encoder *encoder,
-					      struct drm_display_mode *mode,
-					      struct drm_display_mode *adjusted_mode)
-{
-
-	drm_mode_set_crtcinfo(adjusted_mode, 0);
-
-	return true;
-}
-
 static void radeon_legacy_tmds_int_dpms(struct drm_encoder *encoder, int mode)
 {
 	struct drm_device *dev = encoder->dev;
@@ -584,7 +576,7 @@
 
 static const struct drm_encoder_helper_funcs radeon_legacy_tmds_int_helper_funcs = {
 	.dpms = radeon_legacy_tmds_int_dpms,
-	.mode_fixup = radeon_legacy_tmds_int_mode_fixup,
+	.mode_fixup = radeon_legacy_mode_fixup,
 	.prepare = radeon_legacy_tmds_int_prepare,
 	.mode_set = radeon_legacy_tmds_int_mode_set,
 	.commit = radeon_legacy_tmds_int_commit,
@@ -596,17 +588,6 @@
 	.destroy = radeon_enc_destroy,
 };
 
-static bool radeon_legacy_tmds_ext_mode_fixup(struct drm_encoder *encoder,
-					      struct drm_display_mode *mode,
-					      struct drm_display_mode *adjusted_mode)
-{
-	/* set the active encoder to connector routing */
-	radeon_encoder_set_active_device(encoder);
-	drm_mode_set_crtcinfo(adjusted_mode, 0);
-
-	return true;
-}
-
 static void radeon_legacy_tmds_ext_dpms(struct drm_encoder *encoder, int mode)
 {
 	struct drm_device *dev = encoder->dev;
@@ -697,6 +678,8 @@
 			/*if (mode->clock > 165000)
 			  fp2_gen_cntl |= R300_FP2_DVO_DUAL_CHANNEL_EN;*/
 		}
+		if (!radeon_combios_external_tmds_setup(encoder))
+			radeon_external_tmds_setup(encoder);
 	}
 
 	if (radeon_crtc->crtc_id == 0) {
@@ -724,9 +707,22 @@
 		radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
 }
 
+static void radeon_ext_tmds_enc_destroy(struct drm_encoder *encoder)
+{
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
+	if (tmds) {
+		if (tmds->i2c_bus)
+			radeon_i2c_destroy(tmds->i2c_bus);
+	}
+	kfree(radeon_encoder->enc_priv);
+	drm_encoder_cleanup(encoder);
+	kfree(radeon_encoder);
+}
+
 static const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs = {
 	.dpms = radeon_legacy_tmds_ext_dpms,
-	.mode_fixup = radeon_legacy_tmds_ext_mode_fixup,
+	.mode_fixup = radeon_legacy_mode_fixup,
 	.prepare = radeon_legacy_tmds_ext_prepare,
 	.mode_set = radeon_legacy_tmds_ext_mode_set,
 	.commit = radeon_legacy_tmds_ext_commit,
@@ -735,20 +731,9 @@
 
 
 static const struct drm_encoder_funcs radeon_legacy_tmds_ext_enc_funcs = {
-	.destroy = radeon_enc_destroy,
+	.destroy = radeon_ext_tmds_enc_destroy,
 };
 
-static bool radeon_legacy_tv_dac_mode_fixup(struct drm_encoder *encoder,
-					    struct drm_display_mode *mode,
-					    struct drm_display_mode *adjusted_mode)
-{
-	/* set the active encoder to connector routing */
-	radeon_encoder_set_active_device(encoder);
-	drm_mode_set_crtcinfo(adjusted_mode, 0);
-
-	return true;
-}
-
 static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
 {
 	struct drm_device *dev = encoder->dev;
@@ -1265,7 +1250,7 @@
 
 static const struct drm_encoder_helper_funcs radeon_legacy_tv_dac_helper_funcs = {
 	.dpms = radeon_legacy_tv_dac_dpms,
-	.mode_fixup = radeon_legacy_tv_dac_mode_fixup,
+	.mode_fixup = radeon_legacy_mode_fixup,
 	.prepare = radeon_legacy_tv_dac_prepare,
 	.mode_set = radeon_legacy_tv_dac_mode_set,
 	.commit = radeon_legacy_tv_dac_commit,
@@ -1302,6 +1287,29 @@
 	return tmds;
 }
 
+static struct radeon_encoder_ext_tmds *radeon_legacy_get_ext_tmds_info(struct radeon_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_encoder_ext_tmds *tmds = NULL;
+	bool ret;
+
+	if (rdev->is_atom_bios)
+		return NULL;
+
+	tmds = kzalloc(sizeof(struct radeon_encoder_ext_tmds), GFP_KERNEL);
+
+	if (!tmds)
+		return NULL;
+
+	ret = radeon_legacy_get_ext_tmds_info_from_combios(encoder, tmds);
+
+	if (ret == false)
+		radeon_legacy_get_ext_tmds_info_from_table(encoder, tmds);
+
+	return tmds;
+}
+
 void
 radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device)
 {
@@ -1329,7 +1337,6 @@
 		encoder->possible_crtcs = 0x1;
 	else
 		encoder->possible_crtcs = 0x3;
-	encoder->possible_clones = 0;
 
 	radeon_encoder->enc_priv = NULL;
 
@@ -1373,7 +1380,7 @@
 		drm_encoder_init(dev, encoder, &radeon_legacy_tmds_ext_enc_funcs, DRM_MODE_ENCODER_TMDS);
 		drm_encoder_helper_add(encoder, &radeon_legacy_tmds_ext_helper_funcs);
 		if (!rdev->is_atom_bios)
-			radeon_combios_get_ext_tmds_info(radeon_encoder);
+			radeon_encoder->enc_priv = radeon_legacy_get_ext_tmds_info(radeon_encoder);
 		break;
 	}
 }
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index ace726a..44d4b65 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -33,6 +33,7 @@
 #include <drm_crtc.h>
 #include <drm_mode.h>
 #include <drm_edid.h>
+#include <drm_dp_helper.h>
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
 #include <linux/i2c-algo-bit.h>
@@ -89,24 +90,45 @@
 	TV_STD_PAL_CN,
 };
 
+/* radeon gpio-based i2c
+ * 1. "mask" reg and bits
+ *    grabs the gpio pins for software use
+ *    0=not held  1=held
+ * 2. "a" reg and bits
+ *    output pin value
+ *    0=low 1=high
+ * 3. "en" reg and bits
+ *    sets the pin direction
+ *    0=input 1=output
+ * 4. "y" reg and bits
+ *    input pin value
+ *    0=low 1=high
+ */
 struct radeon_i2c_bus_rec {
 	bool valid;
+	/* id used by atom */
+	uint8_t i2c_id;
+	/* can be used with hw i2c engine */
+	bool hw_capable;
+	/* uses multi-media i2c engine */
+	bool mm_i2c;
+	/* regs and bits */
 	uint32_t mask_clk_reg;
 	uint32_t mask_data_reg;
 	uint32_t a_clk_reg;
 	uint32_t a_data_reg;
-	uint32_t put_clk_reg;
-	uint32_t put_data_reg;
-	uint32_t get_clk_reg;
-	uint32_t get_data_reg;
+	uint32_t en_clk_reg;
+	uint32_t en_data_reg;
+	uint32_t y_clk_reg;
+	uint32_t y_data_reg;
 	uint32_t mask_clk_mask;
 	uint32_t mask_data_mask;
-	uint32_t put_clk_mask;
-	uint32_t put_data_mask;
-	uint32_t get_clk_mask;
-	uint32_t get_data_mask;
 	uint32_t a_clk_mask;
 	uint32_t a_data_mask;
+	uint32_t en_clk_mask;
+	uint32_t en_data_mask;
+	uint32_t y_clk_mask;
+	uint32_t y_data_mask;
 };
 
 struct radeon_tmds_pll {
@@ -150,9 +172,12 @@
 };
 
 struct radeon_i2c_chan {
-	struct drm_device *dev;
 	struct i2c_adapter adapter;
-	struct i2c_algo_bit_data algo;
+	struct drm_device *dev;
+	union {
+		struct i2c_algo_dp_aux_data dp;
+		struct i2c_algo_bit_data bit;
+	} algo;
 	struct radeon_i2c_bus_rec rec;
 };
 
@@ -170,6 +195,11 @@
 	CT_EMAC,
 };
 
+enum radeon_dvo_chip {
+	DVO_SIL164,
+	DVO_SIL1178,
+};
+
 struct radeon_mode_info {
 	struct atom_context *atom_context;
 	struct card_info *atom_card_info;
@@ -261,6 +291,13 @@
 	struct radeon_tmds_pll tmds_pll[4];
 };
 
+struct radeon_encoder_ext_tmds {
+	/* tmds over dvo */
+	struct radeon_i2c_chan *i2c_bus;
+	uint8_t slave_addr;
+	enum radeon_dvo_chip dvo_chip;
+};
+
 /* spread spectrum */
 struct radeon_atom_ss {
 	uint16_t percentage;
@@ -302,6 +339,35 @@
 struct radeon_connector_atom_dig {
 	uint32_t igp_lane_info;
 	bool linkb;
+	/* displayport */
+	struct radeon_i2c_chan *dp_i2c_bus;
+	u8 dpcd[8];
+	u8 dp_sink_type;
+	int dp_clock;
+	int dp_lane_count;
+};
+
+struct radeon_gpio_rec {
+	bool valid;
+	u8 id;
+	u32 reg;
+	u32 mask;
+};
+
+enum radeon_hpd_id {
+	RADEON_HPD_NONE = 0,
+	RADEON_HPD_1,
+	RADEON_HPD_2,
+	RADEON_HPD_3,
+	RADEON_HPD_4,
+	RADEON_HPD_5,
+	RADEON_HPD_6,
+};
+
+struct radeon_hpd {
+	enum radeon_hpd_id hpd;
+	u8 plugged_state;
+	struct radeon_gpio_rec gpio;
 };
 
 struct radeon_connector {
@@ -318,6 +384,7 @@
 	void *con_priv;
 	bool dac_load_detect;
 	uint16_t connector_object_id;
+	struct radeon_hpd hpd;
 };
 
 struct radeon_framebuffer {
@@ -325,10 +392,37 @@
 	struct drm_gem_object *obj;
 };
 
+extern void radeon_connector_hotplug(struct drm_connector *connector);
+extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector);
+extern int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector,
+				       struct drm_display_mode *mode);
+extern void radeon_dp_set_link_config(struct drm_connector *connector,
+				      struct drm_display_mode *mode);
+extern void dp_link_train(struct drm_encoder *encoder,
+			  struct drm_connector *connector);
+extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector);
+extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector);
+extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder,
+					   int action, uint8_t lane_num,
+					   uint8_t lane_set);
+extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
+				uint8_t write_byte, uint8_t *read_byte);
+
+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);
 extern void radeon_i2c_destroy(struct radeon_i2c_chan *i2c);
+extern void radeon_i2c_sw_get_byte(struct radeon_i2c_chan *i2c_bus,
+				   u8 slave_addr,
+				   u8 addr,
+				   u8 *val);
+extern void radeon_i2c_sw_put_byte(struct radeon_i2c_chan *i2c,
+				   u8 slave_addr,
+				   u8 addr,
+				   u8 val);
 extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector);
 extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector);
 
@@ -343,12 +437,24 @@
 			       uint32_t *post_div_p,
 			       int flags);
 
+extern void radeon_compute_pll_avivo(struct radeon_pll *pll,
+				     uint64_t freq,
+				     uint32_t *dot_clock_p,
+				     uint32_t *fb_div_p,
+				     uint32_t *frac_fb_div_p,
+				     uint32_t *ref_div_p,
+				     uint32_t *post_div_p,
+				     int flags);
+
+extern void radeon_setup_encoder_clones(struct drm_device *dev);
+
 struct drm_encoder *radeon_encoder_legacy_lvds_add(struct drm_device *dev, int bios_index);
 struct drm_encoder *radeon_encoder_legacy_primary_dac_add(struct drm_device *dev, int bios_index, int with_tv);
 struct drm_encoder *radeon_encoder_legacy_tv_dac_add(struct drm_device *dev, int bios_index, int with_tv);
 struct drm_encoder *radeon_encoder_legacy_tmds_int_add(struct drm_device *dev, int bios_index);
 struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index);
 extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action);
+extern void atombios_digital_setup(struct drm_encoder *encoder, int action);
 extern int atombios_get_encoder_mode(struct drm_encoder *encoder);
 extern void radeon_encoder_set_active_device(struct drm_encoder *encoder);
 
@@ -378,12 +484,16 @@
 extern bool radeon_combios_get_clock_info(struct drm_device *dev);
 extern struct radeon_encoder_atom_dig *
 radeon_atombios_get_lvds_info(struct radeon_encoder *encoder);
-bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
-				   struct radeon_encoder_int_tmds *tmds);
-bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
-					   struct radeon_encoder_int_tmds *tmds);
-bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
-					    struct radeon_encoder_int_tmds *tmds);
+extern bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
+					  struct radeon_encoder_int_tmds *tmds);
+extern bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
+						     struct radeon_encoder_int_tmds *tmds);
+extern bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
+						   struct radeon_encoder_int_tmds *tmds);
+extern bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder,
+							 struct radeon_encoder_ext_tmds *tmds);
+extern bool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder,
+						       struct radeon_encoder_ext_tmds *tmds);
 extern struct radeon_encoder_primary_dac *
 radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder);
 extern struct radeon_encoder_tv_dac *
@@ -395,6 +505,8 @@
 radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder);
 extern struct radeon_encoder_primary_dac *
 radeon_combios_get_primary_dac_info(struct radeon_encoder *encoder);
+extern bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder);
+extern void radeon_external_tmds_setup(struct drm_encoder *encoder);
 extern void radeon_combios_output_lock(struct drm_encoder *encoder, bool lock);
 extern void radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev);
 extern void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock);
@@ -426,16 +538,13 @@
 			       struct radeon_crtc *radeon_crtc);
 void radeon_legacy_init_crtc(struct drm_device *dev,
 			     struct radeon_crtc *radeon_crtc);
-void radeon_i2c_do_lock(struct radeon_connector *radeon_connector, int lock_state);
+extern void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state);
 
 void radeon_get_clock_info(struct drm_device *dev);
 
 extern bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev);
 extern bool radeon_get_atom_connector_info_from_supported_devices_table(struct drm_device *dev);
 
-void radeon_rmx_mode_fixup(struct drm_encoder *encoder,
-			   struct drm_display_mode *mode,
-			   struct drm_display_mode *adjusted_mode);
 void radeon_enc_destroy(struct drm_encoder *encoder);
 void radeon_copy_fb(struct drm_device *dev, struct drm_gem_object *dst_obj);
 void radeon_combios_asic_init(struct drm_device *dev);
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index 1f056da..544e18f 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -34,100 +34,53 @@
 #include "radeon_drm.h"
 #include "radeon.h"
 
-struct radeon_object {
-	struct ttm_buffer_object	tobj;
-	struct list_head		list;
-	struct radeon_device		*rdev;
-	struct drm_gem_object		*gobj;
-	struct ttm_bo_kmap_obj		kmap;
-	unsigned			pin_count;
-	uint64_t			gpu_addr;
-	void				*kptr;
-	bool				is_iomem;
-	uint32_t			tiling_flags;
-	uint32_t			pitch;
-	int				surface_reg;
-};
 
 int radeon_ttm_init(struct radeon_device *rdev);
 void radeon_ttm_fini(struct radeon_device *rdev);
+static void radeon_bo_clear_surface_reg(struct radeon_bo *bo);
 
 /*
  * To exclude mutual BO access we rely on bo_reserve exclusion, as all
  * function are calling it.
  */
 
-static int radeon_object_reserve(struct radeon_object *robj, bool interruptible)
+static void radeon_ttm_bo_destroy(struct ttm_buffer_object *tbo)
 {
-	return ttm_bo_reserve(&robj->tobj, interruptible, false, false, 0);
+	struct radeon_bo *bo;
+
+	bo = container_of(tbo, struct radeon_bo, tbo);
+	mutex_lock(&bo->rdev->gem.mutex);
+	list_del_init(&bo->list);
+	mutex_unlock(&bo->rdev->gem.mutex);
+	radeon_bo_clear_surface_reg(bo);
+	kfree(bo);
 }
 
-static void radeon_object_unreserve(struct radeon_object *robj)
+void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
 {
-	ttm_bo_unreserve(&robj->tobj);
+	u32 c = 0;
+
+	rbo->placement.fpfn = 0;
+	rbo->placement.lpfn = 0;
+	rbo->placement.placement = rbo->placements;
+	rbo->placement.busy_placement = rbo->placements;
+	if (domain & RADEON_GEM_DOMAIN_VRAM)
+		rbo->placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED |
+					TTM_PL_FLAG_VRAM;
+	if (domain & RADEON_GEM_DOMAIN_GTT)
+		rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;
+	if (domain & RADEON_GEM_DOMAIN_CPU)
+		rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
+	rbo->placement.num_placement = c;
+	rbo->placement.num_busy_placement = c;
 }
 
-static void radeon_ttm_object_object_destroy(struct ttm_buffer_object *tobj)
+int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
+			unsigned long size, bool kernel, u32 domain,
+			struct radeon_bo **bo_ptr)
 {
-	struct radeon_object *robj;
-
-	robj = container_of(tobj, struct radeon_object, tobj);
-	list_del_init(&robj->list);
-	radeon_object_clear_surface_reg(robj);
-	kfree(robj);
-}
-
-static inline void radeon_object_gpu_addr(struct radeon_object *robj)
-{
-	/* Default gpu address */
-	robj->gpu_addr = 0xFFFFFFFFFFFFFFFFULL;
-	if (robj->tobj.mem.mm_node == NULL) {
-		return;
-	}
-	robj->gpu_addr = ((u64)robj->tobj.mem.mm_node->start) << PAGE_SHIFT;
-	switch (robj->tobj.mem.mem_type) {
-	case TTM_PL_VRAM:
-		robj->gpu_addr += (u64)robj->rdev->mc.vram_location;
-		break;
-	case TTM_PL_TT:
-		robj->gpu_addr += (u64)robj->rdev->mc.gtt_location;
-		break;
-	default:
-		DRM_ERROR("Unknown placement %d\n", robj->tobj.mem.mem_type);
-		robj->gpu_addr = 0xFFFFFFFFFFFFFFFFULL;
-		return;
-	}
-}
-
-static inline uint32_t radeon_object_flags_from_domain(uint32_t domain)
-{
-	uint32_t flags = 0;
-	if (domain & RADEON_GEM_DOMAIN_VRAM) {
-		flags |= TTM_PL_FLAG_VRAM | TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED;
-	}
-	if (domain & RADEON_GEM_DOMAIN_GTT) {
-		flags |= TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING;
-	}
-	if (domain & RADEON_GEM_DOMAIN_CPU) {
-		flags |= TTM_PL_FLAG_SYSTEM | TTM_PL_MASK_CACHING;
-	}
-	if (!flags) {
-		flags |= TTM_PL_FLAG_SYSTEM | TTM_PL_MASK_CACHING;
-	}
-	return flags;
-}
-
-int radeon_object_create(struct radeon_device *rdev,
-			 struct drm_gem_object *gobj,
-			 unsigned long size,
-			 bool kernel,
-			 uint32_t domain,
-			 bool interruptible,
-			 struct radeon_object **robj_ptr)
-{
-	struct radeon_object *robj;
+	struct radeon_bo *bo;
 	enum ttm_bo_type type;
-	uint32_t flags;
 	int r;
 
 	if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) {
@@ -138,206 +91,125 @@
 	} else {
 		type = ttm_bo_type_device;
 	}
-	*robj_ptr = NULL;
-	robj = kzalloc(sizeof(struct radeon_object), GFP_KERNEL);
-	if (robj == NULL) {
+	*bo_ptr = NULL;
+	bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL);
+	if (bo == NULL)
 		return -ENOMEM;
-	}
-	robj->rdev = rdev;
-	robj->gobj = gobj;
-	robj->surface_reg = -1;
-	INIT_LIST_HEAD(&robj->list);
+	bo->rdev = rdev;
+	bo->gobj = gobj;
+	bo->surface_reg = -1;
+	INIT_LIST_HEAD(&bo->list);
 
-	flags = radeon_object_flags_from_domain(domain);
-	r = ttm_buffer_object_init(&rdev->mman.bdev, &robj->tobj, size, type, flags,
-				   0, 0, false, NULL, size,
-				   &radeon_ttm_object_object_destroy);
+	radeon_ttm_placement_from_domain(bo, domain);
+	/* Kernel allocation are uninterruptible */
+	r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type,
+			&bo->placement, 0, 0, !kernel, NULL, size,
+			&radeon_ttm_bo_destroy);
 	if (unlikely(r != 0)) {
-		/* ttm call radeon_ttm_object_object_destroy if error happen */
-		DRM_ERROR("Failed to allocate TTM object (%ld, 0x%08X, %u)\n",
-			  size, flags, 0);
+		if (r != -ERESTARTSYS)
+			dev_err(rdev->dev,
+				"object_init failed for (%lu, 0x%08X)\n",
+				size, domain);
 		return r;
 	}
-	*robj_ptr = robj;
+	*bo_ptr = bo;
 	if (gobj) {
-		list_add_tail(&robj->list, &rdev->gem.objects);
+		mutex_lock(&bo->rdev->gem.mutex);
+		list_add_tail(&bo->list, &rdev->gem.objects);
+		mutex_unlock(&bo->rdev->gem.mutex);
 	}
 	return 0;
 }
 
-int radeon_object_kmap(struct radeon_object *robj, void **ptr)
+int radeon_bo_kmap(struct radeon_bo *bo, void **ptr)
 {
+	bool is_iomem;
 	int r;
 
-	spin_lock(&robj->tobj.lock);
-	if (robj->kptr) {
+	if (bo->kptr) {
 		if (ptr) {
-			*ptr = robj->kptr;
+			*ptr = bo->kptr;
 		}
-		spin_unlock(&robj->tobj.lock);
 		return 0;
 	}
-	spin_unlock(&robj->tobj.lock);
-	r = ttm_bo_kmap(&robj->tobj, 0, robj->tobj.num_pages, &robj->kmap);
+	r = ttm_bo_kmap(&bo->tbo, 0, bo->tbo.num_pages, &bo->kmap);
 	if (r) {
 		return r;
 	}
-	spin_lock(&robj->tobj.lock);
-	robj->kptr = ttm_kmap_obj_virtual(&robj->kmap, &robj->is_iomem);
-	spin_unlock(&robj->tobj.lock);
+	bo->kptr = ttm_kmap_obj_virtual(&bo->kmap, &is_iomem);
 	if (ptr) {
-		*ptr = robj->kptr;
+		*ptr = bo->kptr;
 	}
-	radeon_object_check_tiling(robj, 0, 0);
+	radeon_bo_check_tiling(bo, 0, 0);
 	return 0;
 }
 
-void radeon_object_kunmap(struct radeon_object *robj)
+void radeon_bo_kunmap(struct radeon_bo *bo)
 {
-	spin_lock(&robj->tobj.lock);
-	if (robj->kptr == NULL) {
-		spin_unlock(&robj->tobj.lock);
+	if (bo->kptr == NULL)
 		return;
-	}
-	robj->kptr = NULL;
-	spin_unlock(&robj->tobj.lock);
-	radeon_object_check_tiling(robj, 0, 0);
-	ttm_bo_kunmap(&robj->kmap);
+	bo->kptr = NULL;
+	radeon_bo_check_tiling(bo, 0, 0);
+	ttm_bo_kunmap(&bo->kmap);
 }
 
-void radeon_object_unref(struct radeon_object **robj)
+void radeon_bo_unref(struct radeon_bo **bo)
 {
-	struct ttm_buffer_object *tobj;
+	struct ttm_buffer_object *tbo;
 
-	if ((*robj) == NULL) {
+	if ((*bo) == NULL)
 		return;
-	}
-	tobj = &((*robj)->tobj);
-	ttm_bo_unref(&tobj);
-	if (tobj == NULL) {
-		*robj = NULL;
-	}
+	tbo = &((*bo)->tbo);
+	ttm_bo_unref(&tbo);
+	if (tbo == NULL)
+		*bo = NULL;
 }
 
-int radeon_object_mmap(struct radeon_object *robj, uint64_t *offset)
+int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr)
 {
-	*offset = robj->tobj.addr_space_offset;
-	return 0;
-}
+	int r, i;
 
-int radeon_object_pin(struct radeon_object *robj, uint32_t domain,
-		      uint64_t *gpu_addr)
-{
-	uint32_t flags;
-	uint32_t tmp;
-	int r;
-
-	flags = radeon_object_flags_from_domain(domain);
-	spin_lock(&robj->tobj.lock);
-	if (robj->pin_count) {
-		robj->pin_count++;
-		if (gpu_addr != NULL) {
-			*gpu_addr = robj->gpu_addr;
-		}
-		spin_unlock(&robj->tobj.lock);
+	radeon_ttm_placement_from_domain(bo, domain);
+	if (bo->pin_count) {
+		bo->pin_count++;
+		if (gpu_addr)
+			*gpu_addr = radeon_bo_gpu_offset(bo);
 		return 0;
 	}
-	spin_unlock(&robj->tobj.lock);
-	r = radeon_object_reserve(robj, false);
-	if (unlikely(r != 0)) {
-		DRM_ERROR("radeon: failed to reserve object for pinning it.\n");
-		return r;
+	radeon_ttm_placement_from_domain(bo, domain);
+	for (i = 0; i < bo->placement.num_placement; i++)
+		bo->placements[i] |= TTM_PL_FLAG_NO_EVICT;
+	r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
+	if (likely(r == 0)) {
+		bo->pin_count = 1;
+		if (gpu_addr != NULL)
+			*gpu_addr = radeon_bo_gpu_offset(bo);
 	}
-	tmp = robj->tobj.mem.placement;
-	ttm_flag_masked(&tmp, flags, TTM_PL_MASK_MEM);
-	robj->tobj.proposed_placement = tmp | TTM_PL_FLAG_NO_EVICT | TTM_PL_MASK_CACHING;
-	r = ttm_buffer_object_validate(&robj->tobj,
-				       robj->tobj.proposed_placement,
-				       false, false);
-	radeon_object_gpu_addr(robj);
-	if (gpu_addr != NULL) {
-		*gpu_addr = robj->gpu_addr;
-	}
-	robj->pin_count = 1;
-	if (unlikely(r != 0)) {
-		DRM_ERROR("radeon: failed to pin object.\n");
-	}
-	radeon_object_unreserve(robj);
+	if (unlikely(r != 0))
+		dev_err(bo->rdev->dev, "%p pin failed\n", bo);
 	return r;
 }
 
-void radeon_object_unpin(struct radeon_object *robj)
+int radeon_bo_unpin(struct radeon_bo *bo)
 {
-	uint32_t flags;
-	int r;
+	int r, i;
 
-	spin_lock(&robj->tobj.lock);
-	if (!robj->pin_count) {
-		spin_unlock(&robj->tobj.lock);
-		printk(KERN_WARNING "Unpin not necessary for %p !\n", robj);
-		return;
+	if (!bo->pin_count) {
+		dev_warn(bo->rdev->dev, "%p unpin not necessary\n", bo);
+		return 0;
 	}
-	robj->pin_count--;
-	if (robj->pin_count) {
-		spin_unlock(&robj->tobj.lock);
-		return;
-	}
-	spin_unlock(&robj->tobj.lock);
-	r = radeon_object_reserve(robj, false);
-	if (unlikely(r != 0)) {
-		DRM_ERROR("radeon: failed to reserve object for unpinning it.\n");
-		return;
-	}
-	flags = robj->tobj.mem.placement;
-	robj->tobj.proposed_placement = flags & ~TTM_PL_FLAG_NO_EVICT;
-	r = ttm_buffer_object_validate(&robj->tobj,
-				       robj->tobj.proposed_placement,
-				       false, false);
-	if (unlikely(r != 0)) {
-		DRM_ERROR("radeon: failed to unpin buffer.\n");
-	}
-	radeon_object_unreserve(robj);
-}
-
-int radeon_object_wait(struct radeon_object *robj)
-{
-	int r = 0;
-
-	/* FIXME: should use block reservation instead */
-	r = radeon_object_reserve(robj, true);
-	if (unlikely(r != 0)) {
-		DRM_ERROR("radeon: failed to reserve object for waiting.\n");
-		return r;
-	}
-	spin_lock(&robj->tobj.lock);
-	if (robj->tobj.sync_obj) {
-		r = ttm_bo_wait(&robj->tobj, true, true, false);
-	}
-	spin_unlock(&robj->tobj.lock);
-	radeon_object_unreserve(robj);
+	bo->pin_count--;
+	if (bo->pin_count)
+		return 0;
+	for (i = 0; i < bo->placement.num_placement; i++)
+		bo->placements[i] &= ~TTM_PL_FLAG_NO_EVICT;
+	r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
+	if (unlikely(r != 0))
+		dev_err(bo->rdev->dev, "%p validate failed for unpin\n", bo);
 	return r;
 }
 
-int radeon_object_busy_domain(struct radeon_object *robj, uint32_t *cur_placement)
-{
-	int r = 0;
-
-	r = radeon_object_reserve(robj, true);
-	if (unlikely(r != 0)) {
-		DRM_ERROR("radeon: failed to reserve object for waiting.\n");
-		return r;
-	}
-	spin_lock(&robj->tobj.lock);
-	*cur_placement = robj->tobj.mem.mem_type;
-	if (robj->tobj.sync_obj) {
-		r = ttm_bo_wait(&robj->tobj, true, true, true);
-	}
-	spin_unlock(&robj->tobj.lock);
-	radeon_object_unreserve(robj);
-	return r;
-}
-
-int radeon_object_evict_vram(struct radeon_device *rdev)
+int radeon_bo_evict_vram(struct radeon_device *rdev)
 {
 	if (rdev->flags & RADEON_IS_IGP) {
 		/* Useless to evict on IGP chips */
@@ -346,30 +218,32 @@
 	return ttm_bo_evict_mm(&rdev->mman.bdev, TTM_PL_VRAM);
 }
 
-void radeon_object_force_delete(struct radeon_device *rdev)
+void radeon_bo_force_delete(struct radeon_device *rdev)
 {
-	struct radeon_object *robj, *n;
+	struct radeon_bo *bo, *n;
 	struct drm_gem_object *gobj;
 
 	if (list_empty(&rdev->gem.objects)) {
 		return;
 	}
-	DRM_ERROR("Userspace still has active objects !\n");
-	list_for_each_entry_safe(robj, n, &rdev->gem.objects, list) {
+	dev_err(rdev->dev, "Userspace still has active objects !\n");
+	list_for_each_entry_safe(bo, n, &rdev->gem.objects, list) {
 		mutex_lock(&rdev->ddev->struct_mutex);
-		gobj = robj->gobj;
-		DRM_ERROR("Force free for (%p,%p,%lu,%lu)\n",
-			  gobj, robj, (unsigned long)gobj->size,
-			  *((unsigned long *)&gobj->refcount));
-		list_del_init(&robj->list);
-		radeon_object_unref(&robj);
+		gobj = bo->gobj;
+		dev_err(rdev->dev, "%p %p %lu %lu force free\n",
+			gobj, bo, (unsigned long)gobj->size,
+			*((unsigned long *)&gobj->refcount));
+		mutex_lock(&bo->rdev->gem.mutex);
+		list_del_init(&bo->list);
+		mutex_unlock(&bo->rdev->gem.mutex);
+		radeon_bo_unref(&bo);
 		gobj->driver_private = NULL;
 		drm_gem_object_unreference(gobj);
 		mutex_unlock(&rdev->ddev->struct_mutex);
 	}
 }
 
-int radeon_object_init(struct radeon_device *rdev)
+int radeon_bo_init(struct radeon_device *rdev)
 {
 	/* Add an MTRR for the VRAM */
 	rdev->mc.vram_mtrr = mtrr_add(rdev->mc.aper_base, rdev->mc.aper_size,
@@ -382,13 +256,13 @@
 	return radeon_ttm_init(rdev);
 }
 
-void radeon_object_fini(struct radeon_device *rdev)
+void radeon_bo_fini(struct radeon_device *rdev)
 {
 	radeon_ttm_fini(rdev);
 }
 
-void radeon_object_list_add_object(struct radeon_object_list *lobj,
-				   struct list_head *head)
+void radeon_bo_list_add_object(struct radeon_bo_list *lobj,
+				struct list_head *head)
 {
 	if (lobj->wdomain) {
 		list_add(&lobj->list, head);
@@ -397,72 +271,62 @@
 	}
 }
 
-int radeon_object_list_reserve(struct list_head *head)
+int radeon_bo_list_reserve(struct list_head *head)
 {
-	struct radeon_object_list *lobj;
+	struct radeon_bo_list *lobj;
 	int r;
 
 	list_for_each_entry(lobj, head, list){
-		if (!lobj->robj->pin_count) {
-			r = radeon_object_reserve(lobj->robj, true);
-			if (unlikely(r != 0)) {
-				DRM_ERROR("radeon: failed to reserve object.\n");
-				return r;
-			}
-		} else {
-		}
+		r = radeon_bo_reserve(lobj->bo, false);
+		if (unlikely(r != 0))
+			return r;
 	}
 	return 0;
 }
 
-void radeon_object_list_unreserve(struct list_head *head)
+void radeon_bo_list_unreserve(struct list_head *head)
 {
-	struct radeon_object_list *lobj;
+	struct radeon_bo_list *lobj;
 
 	list_for_each_entry(lobj, head, list) {
-		if (!lobj->robj->pin_count) {
-			radeon_object_unreserve(lobj->robj);
-		}
+		/* only unreserve object we successfully reserved */
+		if (radeon_bo_is_reserved(lobj->bo))
+			radeon_bo_unreserve(lobj->bo);
 	}
 }
 
-int radeon_object_list_validate(struct list_head *head, void *fence)
+int radeon_bo_list_validate(struct list_head *head, void *fence)
 {
-	struct radeon_object_list *lobj;
-	struct radeon_object *robj;
+	struct radeon_bo_list *lobj;
+	struct radeon_bo *bo;
 	struct radeon_fence *old_fence = NULL;
 	int r;
 
-	r = radeon_object_list_reserve(head);
+	r = radeon_bo_list_reserve(head);
 	if (unlikely(r != 0)) {
-		radeon_object_list_unreserve(head);
 		return r;
 	}
 	list_for_each_entry(lobj, head, list) {
-		robj = lobj->robj;
-		if (!robj->pin_count) {
+		bo = lobj->bo;
+		if (!bo->pin_count) {
 			if (lobj->wdomain) {
-				robj->tobj.proposed_placement =
-					radeon_object_flags_from_domain(lobj->wdomain);
+				radeon_ttm_placement_from_domain(bo,
+								lobj->wdomain);
 			} else {
-				robj->tobj.proposed_placement =
-					radeon_object_flags_from_domain(lobj->rdomain);
+				radeon_ttm_placement_from_domain(bo,
+								lobj->rdomain);
 			}
-			r = ttm_buffer_object_validate(&robj->tobj,
-						       robj->tobj.proposed_placement,
-						       true, false);
-			if (unlikely(r)) {
-				DRM_ERROR("radeon: failed to validate.\n");
+			r = ttm_bo_validate(&bo->tbo, &bo->placement,
+						true, false);
+			if (unlikely(r))
 				return r;
-			}
-			radeon_object_gpu_addr(robj);
 		}
-		lobj->gpu_offset = robj->gpu_addr;
-		lobj->tiling_flags = robj->tiling_flags;
+		lobj->gpu_offset = radeon_bo_gpu_offset(bo);
+		lobj->tiling_flags = bo->tiling_flags;
 		if (fence) {
-			old_fence = (struct radeon_fence *)robj->tobj.sync_obj;
-			robj->tobj.sync_obj = radeon_fence_ref(fence);
-			robj->tobj.sync_obj_arg = NULL;
+			old_fence = (struct radeon_fence *)bo->tbo.sync_obj;
+			bo->tbo.sync_obj = radeon_fence_ref(fence);
+			bo->tbo.sync_obj_arg = NULL;
 		}
 		if (old_fence) {
 			radeon_fence_unref(&old_fence);
@@ -471,51 +335,44 @@
 	return 0;
 }
 
-void radeon_object_list_unvalidate(struct list_head *head)
+void radeon_bo_list_unvalidate(struct list_head *head, void *fence)
 {
-	struct radeon_object_list *lobj;
-	struct radeon_fence *old_fence = NULL;
+	struct radeon_bo_list *lobj;
+	struct radeon_fence *old_fence;
 
-	list_for_each_entry(lobj, head, list) {
-		old_fence = (struct radeon_fence *)lobj->robj->tobj.sync_obj;
-		lobj->robj->tobj.sync_obj = NULL;
-		if (old_fence) {
-			radeon_fence_unref(&old_fence);
+	if (fence)
+		list_for_each_entry(lobj, head, list) {
+			old_fence = to_radeon_fence(lobj->bo->tbo.sync_obj);
+			if (old_fence == fence) {
+				lobj->bo->tbo.sync_obj = NULL;
+				radeon_fence_unref(&old_fence);
+			}
 		}
-	}
-	radeon_object_list_unreserve(head);
+	radeon_bo_list_unreserve(head);
 }
 
-void radeon_object_list_clean(struct list_head *head)
-{
-	radeon_object_list_unreserve(head);
-}
-
-int radeon_object_fbdev_mmap(struct radeon_object *robj,
+int radeon_bo_fbdev_mmap(struct radeon_bo *bo,
 			     struct vm_area_struct *vma)
 {
-	return ttm_fbdev_mmap(vma, &robj->tobj);
+	return ttm_fbdev_mmap(vma, &bo->tbo);
 }
 
-unsigned long radeon_object_size(struct radeon_object *robj)
+int radeon_bo_get_surface_reg(struct radeon_bo *bo)
 {
-	return robj->tobj.num_pages << PAGE_SHIFT;
-}
-
-int radeon_object_get_surface_reg(struct radeon_object *robj)
-{
-	struct radeon_device *rdev = robj->rdev;
+	struct radeon_device *rdev = bo->rdev;
 	struct radeon_surface_reg *reg;
-	struct radeon_object *old_object;
+	struct radeon_bo *old_object;
 	int steal;
 	int i;
 
-	if (!robj->tiling_flags)
+	BUG_ON(!atomic_read(&bo->tbo.reserved));
+
+	if (!bo->tiling_flags)
 		return 0;
 
-	if (robj->surface_reg >= 0) {
-		reg = &rdev->surface_regs[robj->surface_reg];
-		i = robj->surface_reg;
+	if (bo->surface_reg >= 0) {
+		reg = &rdev->surface_regs[bo->surface_reg];
+		i = bo->surface_reg;
 		goto out;
 	}
 
@@ -523,10 +380,10 @@
 	for (i = 0; i < RADEON_GEM_MAX_SURFACES; i++) {
 
 		reg = &rdev->surface_regs[i];
-		if (!reg->robj)
+		if (!reg->bo)
 			break;
 
-		old_object = reg->robj;
+		old_object = reg->bo;
 		if (old_object->pin_count == 0)
 			steal = i;
 	}
@@ -537,91 +394,101 @@
 			return -ENOMEM;
 		/* find someone with a surface reg and nuke their BO */
 		reg = &rdev->surface_regs[steal];
-		old_object = reg->robj;
+		old_object = reg->bo;
 		/* blow away the mapping */
 		DRM_DEBUG("stealing surface reg %d from %p\n", steal, old_object);
-		ttm_bo_unmap_virtual(&old_object->tobj);
+		ttm_bo_unmap_virtual(&old_object->tbo);
 		old_object->surface_reg = -1;
 		i = steal;
 	}
 
-	robj->surface_reg = i;
-	reg->robj = robj;
+	bo->surface_reg = i;
+	reg->bo = bo;
 
 out:
-	radeon_set_surface_reg(rdev, i, robj->tiling_flags, robj->pitch,
-			       robj->tobj.mem.mm_node->start << PAGE_SHIFT,
-			       robj->tobj.num_pages << PAGE_SHIFT);
+	radeon_set_surface_reg(rdev, i, bo->tiling_flags, bo->pitch,
+			       bo->tbo.mem.mm_node->start << PAGE_SHIFT,
+			       bo->tbo.num_pages << PAGE_SHIFT);
 	return 0;
 }
 
-void radeon_object_clear_surface_reg(struct radeon_object *robj)
+static void radeon_bo_clear_surface_reg(struct radeon_bo *bo)
 {
-	struct radeon_device *rdev = robj->rdev;
+	struct radeon_device *rdev = bo->rdev;
 	struct radeon_surface_reg *reg;
 
-	if (robj->surface_reg == -1)
+	if (bo->surface_reg == -1)
 		return;
 
-	reg = &rdev->surface_regs[robj->surface_reg];
-	radeon_clear_surface_reg(rdev, robj->surface_reg);
+	reg = &rdev->surface_regs[bo->surface_reg];
+	radeon_clear_surface_reg(rdev, bo->surface_reg);
 
-	reg->robj = NULL;
-	robj->surface_reg = -1;
+	reg->bo = NULL;
+	bo->surface_reg = -1;
 }
 
-void radeon_object_set_tiling_flags(struct radeon_object *robj,
-				    uint32_t tiling_flags, uint32_t pitch)
+int radeon_bo_set_tiling_flags(struct radeon_bo *bo,
+				uint32_t tiling_flags, uint32_t pitch)
 {
-	robj->tiling_flags = tiling_flags;
-	robj->pitch = pitch;
+	int r;
+
+	r = radeon_bo_reserve(bo, false);
+	if (unlikely(r != 0))
+		return r;
+	bo->tiling_flags = tiling_flags;
+	bo->pitch = pitch;
+	radeon_bo_unreserve(bo);
+	return 0;
 }
 
-void radeon_object_get_tiling_flags(struct radeon_object *robj,
-				    uint32_t *tiling_flags,
-				    uint32_t *pitch)
+void radeon_bo_get_tiling_flags(struct radeon_bo *bo,
+				uint32_t *tiling_flags,
+				uint32_t *pitch)
 {
+	BUG_ON(!atomic_read(&bo->tbo.reserved));
 	if (tiling_flags)
-		*tiling_flags = robj->tiling_flags;
+		*tiling_flags = bo->tiling_flags;
 	if (pitch)
-		*pitch = robj->pitch;
+		*pitch = bo->pitch;
 }
 
-int radeon_object_check_tiling(struct radeon_object *robj, bool has_moved,
-			       bool force_drop)
+int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved,
+				bool force_drop)
 {
-	if (!(robj->tiling_flags & RADEON_TILING_SURFACE))
+	BUG_ON(!atomic_read(&bo->tbo.reserved));
+
+	if (!(bo->tiling_flags & RADEON_TILING_SURFACE))
 		return 0;
 
 	if (force_drop) {
-		radeon_object_clear_surface_reg(robj);
+		radeon_bo_clear_surface_reg(bo);
 		return 0;
 	}
 
-	if (robj->tobj.mem.mem_type != TTM_PL_VRAM) {
+	if (bo->tbo.mem.mem_type != TTM_PL_VRAM) {
 		if (!has_moved)
 			return 0;
 
-		if (robj->surface_reg >= 0)
-			radeon_object_clear_surface_reg(robj);
+		if (bo->surface_reg >= 0)
+			radeon_bo_clear_surface_reg(bo);
 		return 0;
 	}
 
-	if ((robj->surface_reg >= 0) && !has_moved)
+	if ((bo->surface_reg >= 0) && !has_moved)
 		return 0;
 
-	return radeon_object_get_surface_reg(robj);
+	return radeon_bo_get_surface_reg(bo);
 }
 
 void radeon_bo_move_notify(struct ttm_buffer_object *bo,
-			  struct ttm_mem_reg *mem)
+				struct ttm_mem_reg *mem)
 {
-	struct radeon_object *robj = container_of(bo, struct radeon_object, tobj);
-	radeon_object_check_tiling(robj, 0, 1);
+	struct radeon_bo *rbo = container_of(bo, struct radeon_bo, tbo);
+	radeon_bo_check_tiling(rbo, 0, 1);
 }
 
 void radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
 {
-	struct radeon_object *robj = container_of(bo, struct radeon_object, tobj);
-	radeon_object_check_tiling(robj, 0, 0);
+	struct radeon_bo *rbo = container_of(bo, struct radeon_bo, tbo);
+	radeon_bo_check_tiling(rbo, 0, 0);
 }
diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h
index 10e8af6..f6b69c2 100644
--- a/drivers/gpu/drm/radeon/radeon_object.h
+++ b/drivers/gpu/drm/radeon/radeon_object.h
@@ -28,19 +28,152 @@
 #ifndef __RADEON_OBJECT_H__
 #define __RADEON_OBJECT_H__
 
-#include <ttm/ttm_bo_api.h>
-#include <ttm/ttm_bo_driver.h>
-#include <ttm/ttm_placement.h>
-#include <ttm/ttm_module.h>
+#include <drm/radeon_drm.h>
+#include "radeon.h"
 
-/*
- * TTM.
+/**
+ * radeon_mem_type_to_domain - return domain corresponding to mem_type
+ * @mem_type:	ttm memory type
+ *
+ * Returns corresponding domain of the ttm mem_type
  */
-struct radeon_mman {
-	struct ttm_bo_global_ref        bo_global_ref;
-	struct ttm_global_reference	mem_global_ref;
-	bool				mem_global_referenced;
-	struct ttm_bo_device		bdev;
-};
+static inline unsigned radeon_mem_type_to_domain(u32 mem_type)
+{
+	switch (mem_type) {
+	case TTM_PL_VRAM:
+		return RADEON_GEM_DOMAIN_VRAM;
+	case TTM_PL_TT:
+		return RADEON_GEM_DOMAIN_GTT;
+	case TTM_PL_SYSTEM:
+		return RADEON_GEM_DOMAIN_CPU;
+	default:
+		break;
+	}
+	return 0;
+}
 
+/**
+ * radeon_bo_reserve - reserve bo
+ * @bo:		bo structure
+ * @no_wait:		don't sleep while trying to reserve (return -EBUSY)
+ *
+ * Returns:
+ * -EBUSY: buffer is busy and @no_wait is true
+ * -ERESTART: A wait for the buffer to become unreserved was interrupted by
+ * a signal. Release all buffer reservations and return to user-space.
+ */
+static inline int radeon_bo_reserve(struct radeon_bo *bo, bool no_wait)
+{
+	int r;
+
+retry:
+	r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0);
+	if (unlikely(r != 0)) {
+		if (r == -ERESTART)
+			goto retry;
+		dev_err(bo->rdev->dev, "%p reserve failed\n", bo);
+		return r;
+	}
+	return 0;
+}
+
+static inline void radeon_bo_unreserve(struct radeon_bo *bo)
+{
+	ttm_bo_unreserve(&bo->tbo);
+}
+
+/**
+ * radeon_bo_gpu_offset - return GPU offset of bo
+ * @bo:	radeon object for which we query the offset
+ *
+ * Returns current GPU offset of the object.
+ *
+ * Note: object should either be pinned or reserved when calling this
+ * function, it might be usefull to add check for this for debugging.
+ */
+static inline u64 radeon_bo_gpu_offset(struct radeon_bo *bo)
+{
+	return bo->tbo.offset;
+}
+
+static inline unsigned long radeon_bo_size(struct radeon_bo *bo)
+{
+	return bo->tbo.num_pages << PAGE_SHIFT;
+}
+
+static inline bool radeon_bo_is_reserved(struct radeon_bo *bo)
+{
+	return !!atomic_read(&bo->tbo.reserved);
+}
+
+/**
+ * radeon_bo_mmap_offset - return mmap offset of bo
+ * @bo:	radeon object for which we query the offset
+ *
+ * Returns mmap offset of the object.
+ *
+ * Note: addr_space_offset is constant after ttm bo init thus isn't protected
+ * by any lock.
+ */
+static inline u64 radeon_bo_mmap_offset(struct radeon_bo *bo)
+{
+	return bo->tbo.addr_space_offset;
+}
+
+static inline int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type,
+					bool no_wait)
+{
+	int r;
+
+retry:
+	r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0);
+	if (unlikely(r != 0)) {
+		if (r == -ERESTART)
+			goto retry;
+		dev_err(bo->rdev->dev, "%p reserve failed for wait\n", bo);
+		return r;
+	}
+	spin_lock(&bo->tbo.lock);
+	if (mem_type)
+		*mem_type = bo->tbo.mem.mem_type;
+	if (bo->tbo.sync_obj)
+		r = ttm_bo_wait(&bo->tbo, true, true, no_wait);
+	spin_unlock(&bo->tbo.lock);
+	ttm_bo_unreserve(&bo->tbo);
+	if (unlikely(r == -ERESTART))
+		goto retry;
+	return r;
+}
+
+extern int radeon_bo_create(struct radeon_device *rdev,
+				struct drm_gem_object *gobj, unsigned long size,
+				bool kernel, u32 domain,
+				struct radeon_bo **bo_ptr);
+extern int radeon_bo_kmap(struct radeon_bo *bo, void **ptr);
+extern void radeon_bo_kunmap(struct radeon_bo *bo);
+extern void radeon_bo_unref(struct radeon_bo **bo);
+extern int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr);
+extern int radeon_bo_unpin(struct radeon_bo *bo);
+extern int radeon_bo_evict_vram(struct radeon_device *rdev);
+extern void radeon_bo_force_delete(struct radeon_device *rdev);
+extern int radeon_bo_init(struct radeon_device *rdev);
+extern void radeon_bo_fini(struct radeon_device *rdev);
+extern void radeon_bo_list_add_object(struct radeon_bo_list *lobj,
+				struct list_head *head);
+extern int radeon_bo_list_reserve(struct list_head *head);
+extern void radeon_bo_list_unreserve(struct list_head *head);
+extern int radeon_bo_list_validate(struct list_head *head, void *fence);
+extern void radeon_bo_list_unvalidate(struct list_head *head, void *fence);
+extern int radeon_bo_fbdev_mmap(struct radeon_bo *bo,
+				struct vm_area_struct *vma);
+extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo,
+				u32 tiling_flags, u32 pitch);
+extern void radeon_bo_get_tiling_flags(struct radeon_bo *bo,
+				u32 *tiling_flags, u32 *pitch);
+extern int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved,
+				bool force_drop);
+extern void radeon_bo_move_notify(struct ttm_buffer_object *bo,
+					struct ttm_mem_reg *mem);
+extern void radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo);
+extern int radeon_bo_get_surface_reg(struct radeon_bo *bo);
 #endif
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index 46146c6..34b08d3 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -27,7 +27,7 @@
 int radeon_pm_init(struct radeon_device *rdev)
 {
 	if (radeon_debugfs_pm_init(rdev)) {
-		DRM_ERROR("Failed to register debugfs file for CP !\n");
+		DRM_ERROR("Failed to register debugfs file for PM!\n");
 	}
 
 	return 0;
@@ -44,8 +44,8 @@
 	struct drm_device *dev = node->minor->dev;
 	struct radeon_device *rdev = dev->dev_private;
 
-	seq_printf(m, "engine clock: %u0 Hz\n", radeon_get_engine_clock(rdev));
-	seq_printf(m, "memory clock: %u0 Hz\n", radeon_get_memory_clock(rdev));
+	seq_printf(m, "engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev));
+	seq_printf(m, "memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev));
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h
index 29ab759..6d0a009 100644
--- a/drivers/gpu/drm/radeon/radeon_reg.h
+++ b/drivers/gpu/drm/radeon/radeon_reg.h
@@ -887,6 +887,7 @@
 #       define RADEON_FP_PANEL_FORMAT          (1 <<  3)
 #       define RADEON_FP_EN_TMDS               (1 <<  7)
 #       define RADEON_FP_DETECT_SENSE          (1 <<  8)
+#       define RADEON_FP_DETECT_INT_POL        (1 <<  9)
 #       define R200_FP_SOURCE_SEL_MASK         (3 <<  10)
 #       define R200_FP_SOURCE_SEL_CRTC1        (0 <<  10)
 #       define R200_FP_SOURCE_SEL_CRTC2        (1 <<  10)
@@ -894,6 +895,7 @@
 #       define R200_FP_SOURCE_SEL_TRANS        (3 <<  10)
 #       define RADEON_FP_SEL_CRTC1             (0 << 13)
 #       define RADEON_FP_SEL_CRTC2             (1 << 13)
+#       define R300_HPD_SEL(x)                 ((x) << 13)
 #       define RADEON_FP_CRTC_DONT_SHADOW_HPAR (1 << 15)
 #       define RADEON_FP_CRTC_DONT_SHADOW_VPAR (1 << 16)
 #       define RADEON_FP_CRTC_DONT_SHADOW_HEND (1 << 17)
@@ -909,6 +911,7 @@
 #       define RADEON_FP2_ON                   (1 <<  2)
 #       define RADEON_FP2_PANEL_FORMAT         (1 <<  3)
 #       define RADEON_FP2_DETECT_SENSE         (1 <<  8)
+#       define RADEON_FP2_DETECT_INT_POL       (1 <<  9)
 #       define R200_FP2_SOURCE_SEL_MASK        (3 << 10)
 #       define R200_FP2_SOURCE_SEL_CRTC1       (0 << 10)
 #       define R200_FP2_SOURCE_SEL_CRTC2       (1 << 10)
@@ -988,14 +991,20 @@
 
 #define RADEON_GEN_INT_CNTL                 0x0040
 #	define RADEON_CRTC_VBLANK_MASK		(1 << 0)
+#	define RADEON_FP_DETECT_MASK		(1 << 4)
 #	define RADEON_CRTC2_VBLANK_MASK		(1 << 9)
+#	define RADEON_FP2_DETECT_MASK		(1 << 10)
 #	define RADEON_SW_INT_ENABLE		(1 << 25)
 #define RADEON_GEN_INT_STATUS               0x0044
 #	define AVIVO_DISPLAY_INT_STATUS		(1 << 0)
 #	define RADEON_CRTC_VBLANK_STAT		(1 << 0)
 #	define RADEON_CRTC_VBLANK_STAT_ACK	(1 << 0)
+#	define RADEON_FP_DETECT_STAT		(1 << 4)
+#	define RADEON_FP_DETECT_STAT_ACK	(1 << 4)
 #	define RADEON_CRTC2_VBLANK_STAT		(1 << 9)
 #	define RADEON_CRTC2_VBLANK_STAT_ACK	(1 << 9)
+#	define RADEON_FP2_DETECT_STAT		(1 << 10)
+#	define RADEON_FP2_DETECT_STAT_ACK	(1 << 10)
 #	define RADEON_SW_INT_FIRE		(1 << 26)
 #	define RADEON_SW_INT_TEST		(1 << 25)
 #	define RADEON_SW_INT_TEST_ACK		(1 << 25)
@@ -1051,20 +1060,25 @@
 
        /* Multimedia I2C bus */
 #define RADEON_I2C_CNTL_0		    0x0090
-#define RADEON_I2C_DONE (1<<0)
-#define RADEON_I2C_NACK (1<<1)
-#define RADEON_I2C_HALT (1<<2)
-#define RADEON_I2C_SOFT_RST (1<<5)
-#define RADEON_I2C_DRIVE_EN (1<<6)
-#define RADEON_I2C_DRIVE_SEL (1<<7)
-#define RADEON_I2C_START (1<<8)
-#define RADEON_I2C_STOP (1<<9)
-#define RADEON_I2C_RECEIVE (1<<10)
-#define RADEON_I2C_ABORT (1<<11)
-#define RADEON_I2C_GO (1<<12)
+#define RADEON_I2C_DONE                     (1 << 0)
+#define RADEON_I2C_NACK                     (1 << 1)
+#define RADEON_I2C_HALT                     (1 << 2)
+#define RADEON_I2C_SOFT_RST                 (1 << 5)
+#define RADEON_I2C_DRIVE_EN                 (1 << 6)
+#define RADEON_I2C_DRIVE_SEL                (1 << 7)
+#define RADEON_I2C_START                    (1 << 8)
+#define RADEON_I2C_STOP                     (1 << 9)
+#define RADEON_I2C_RECEIVE                  (1 << 10)
+#define RADEON_I2C_ABORT                    (1 << 11)
+#define RADEON_I2C_GO                       (1 << 12)
+#define RADEON_I2C_PRESCALE_SHIFT           16
 #define RADEON_I2C_CNTL_1                   0x0094
-#define RADEON_I2C_SEL         (1<<16)
-#define RADEON_I2C_EN          (1<<17)
+#define RADEON_I2C_DATA_COUNT_SHIFT         0
+#define RADEON_I2C_ADDR_COUNT_SHIFT         4
+#define RADEON_I2C_INTRA_BYTE_DELAY_SHIFT   8
+#define RADEON_I2C_SEL                      (1 << 16)
+#define RADEON_I2C_EN                       (1 << 17)
+#define RADEON_I2C_TIME_LIMIT_SHIFT         24
 #define RADEON_I2C_DATA			    0x0098
 
 #define RADEON_DVI_I2C_CNTL_0		    0x02e0
@@ -1072,7 +1086,7 @@
 #       define R200_SEL_DDC1                0 /* 0x60 - VGA_DDC */
 #       define R200_SEL_DDC2                1 /* 0x64 - DVI_DDC */
 #       define R200_SEL_DDC3                2 /* 0x68 - MONID_DDC */
-#define RADEON_DVI_I2C_CNTL_1               0x02e4 /* ? */
+#define RADEON_DVI_I2C_CNTL_1               0x02e4
 #define RADEON_DVI_I2C_DATA		    0x02e8
 
 #define RADEON_INTERRUPT_LINE               0x0f3c /* PCI */
@@ -1143,15 +1157,16 @@
 #       define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1 << 13)
 #       define RADEON_MC_MCLK_DYN_ENABLE    (1 << 14)
 #       define RADEON_IO_MCLK_DYN_ENABLE    (1 << 15)
-#define RADEON_LCD_GPIO_MASK                0x01a0
-#define RADEON_GPIOPAD_EN                   0x01a0
-#define RADEON_LCD_GPIO_Y_REG               0x01a4
-#define RADEON_MDGPIO_A_REG                 0x01ac
-#define RADEON_MDGPIO_EN_REG                0x01b0
-#define RADEON_MDGPIO_MASK                  0x0198
+
 #define RADEON_GPIOPAD_MASK                 0x0198
 #define RADEON_GPIOPAD_A		    0x019c
-#define RADEON_MDGPIO_Y_REG                 0x01b4
+#define RADEON_GPIOPAD_EN                   0x01a0
+#define RADEON_GPIOPAD_Y                    0x01a4
+#define RADEON_MDGPIO_MASK                  0x01a8
+#define RADEON_MDGPIO_A                     0x01ac
+#define RADEON_MDGPIO_EN                    0x01b0
+#define RADEON_MDGPIO_Y                     0x01b4
+
 #define RADEON_MEM_ADDR_CONFIG              0x0148
 #define RADEON_MEM_BASE                     0x0f10 /* PCI */
 #define RADEON_MEM_CNTL                     0x0140
@@ -1360,6 +1375,9 @@
 #define RADEON_OVR_CLR                      0x0230
 #define RADEON_OVR_WID_LEFT_RIGHT           0x0234
 #define RADEON_OVR_WID_TOP_BOTTOM           0x0238
+#define RADEON_OVR2_CLR                     0x0330
+#define RADEON_OVR2_WID_LEFT_RIGHT          0x0334
+#define RADEON_OVR2_WID_TOP_BOTTOM          0x0338
 
 /* first capture unit */
 
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index 747b4bf..4d12b2d 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -165,19 +165,24 @@
 		return 0;
 	/* Allocate 1M object buffer */
 	INIT_LIST_HEAD(&rdev->ib_pool.scheduled_ibs);
-	r = radeon_object_create(rdev, NULL,  RADEON_IB_POOL_SIZE*64*1024,
-				 true, RADEON_GEM_DOMAIN_GTT,
-				 false, &rdev->ib_pool.robj);
+	r = radeon_bo_create(rdev, NULL,  RADEON_IB_POOL_SIZE*64*1024,
+				true, RADEON_GEM_DOMAIN_GTT,
+				&rdev->ib_pool.robj);
 	if (r) {
 		DRM_ERROR("radeon: failed to ib pool (%d).\n", r);
 		return r;
 	}
-	r = radeon_object_pin(rdev->ib_pool.robj, RADEON_GEM_DOMAIN_GTT, &gpu_addr);
+	r = radeon_bo_reserve(rdev->ib_pool.robj, false);
+	if (unlikely(r != 0))
+		return r;
+	r = radeon_bo_pin(rdev->ib_pool.robj, RADEON_GEM_DOMAIN_GTT, &gpu_addr);
 	if (r) {
+		radeon_bo_unreserve(rdev->ib_pool.robj);
 		DRM_ERROR("radeon: failed to pin ib pool (%d).\n", r);
 		return r;
 	}
-	r = radeon_object_kmap(rdev->ib_pool.robj, &ptr);
+	r = radeon_bo_kmap(rdev->ib_pool.robj, &ptr);
+	radeon_bo_unreserve(rdev->ib_pool.robj);
 	if (r) {
 		DRM_ERROR("radeon: failed to map ib poll (%d).\n", r);
 		return r;
@@ -203,14 +208,21 @@
 
 void radeon_ib_pool_fini(struct radeon_device *rdev)
 {
+	int r;
+
 	if (!rdev->ib_pool.ready) {
 		return;
 	}
 	mutex_lock(&rdev->ib_pool.mutex);
 	bitmap_zero(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE);
 	if (rdev->ib_pool.robj) {
-		radeon_object_kunmap(rdev->ib_pool.robj);
-		radeon_object_unref(&rdev->ib_pool.robj);
+		r = radeon_bo_reserve(rdev->ib_pool.robj, false);
+		if (likely(r == 0)) {
+			radeon_bo_kunmap(rdev->ib_pool.robj);
+			radeon_bo_unpin(rdev->ib_pool.robj);
+			radeon_bo_unreserve(rdev->ib_pool.robj);
+		}
+		radeon_bo_unref(&rdev->ib_pool.robj);
 		rdev->ib_pool.robj = NULL;
 	}
 	mutex_unlock(&rdev->ib_pool.mutex);
@@ -288,29 +300,28 @@
 	rdev->cp.ring_size = ring_size;
 	/* Allocate ring buffer */
 	if (rdev->cp.ring_obj == NULL) {
-		r = radeon_object_create(rdev, NULL, rdev->cp.ring_size,
-					 true,
-					 RADEON_GEM_DOMAIN_GTT,
-					 false,
-					 &rdev->cp.ring_obj);
+		r = radeon_bo_create(rdev, NULL, rdev->cp.ring_size, true,
+					RADEON_GEM_DOMAIN_GTT,
+					&rdev->cp.ring_obj);
 		if (r) {
-			DRM_ERROR("radeon: failed to create ring buffer (%d).\n", r);
-			mutex_unlock(&rdev->cp.mutex);
+			dev_err(rdev->dev, "(%d) ring create failed\n", r);
 			return r;
 		}
-		r = radeon_object_pin(rdev->cp.ring_obj,
-				      RADEON_GEM_DOMAIN_GTT,
-				      &rdev->cp.gpu_addr);
+		r = radeon_bo_reserve(rdev->cp.ring_obj, false);
+		if (unlikely(r != 0))
+			return r;
+		r = radeon_bo_pin(rdev->cp.ring_obj, RADEON_GEM_DOMAIN_GTT,
+					&rdev->cp.gpu_addr);
 		if (r) {
-			DRM_ERROR("radeon: failed to pin ring buffer (%d).\n", r);
-			mutex_unlock(&rdev->cp.mutex);
+			radeon_bo_unreserve(rdev->cp.ring_obj);
+			dev_err(rdev->dev, "(%d) ring pin failed\n", r);
 			return r;
 		}
-		r = radeon_object_kmap(rdev->cp.ring_obj,
+		r = radeon_bo_kmap(rdev->cp.ring_obj,
 				       (void **)&rdev->cp.ring);
+		radeon_bo_unreserve(rdev->cp.ring_obj);
 		if (r) {
-			DRM_ERROR("radeon: failed to map ring buffer (%d).\n", r);
-			mutex_unlock(&rdev->cp.mutex);
+			dev_err(rdev->dev, "(%d) ring map failed\n", r);
 			return r;
 		}
 	}
@@ -321,11 +332,17 @@
 
 void radeon_ring_fini(struct radeon_device *rdev)
 {
+	int r;
+
 	mutex_lock(&rdev->cp.mutex);
 	if (rdev->cp.ring_obj) {
-		radeon_object_kunmap(rdev->cp.ring_obj);
-		radeon_object_unpin(rdev->cp.ring_obj);
-		radeon_object_unref(&rdev->cp.ring_obj);
+		r = radeon_bo_reserve(rdev->cp.ring_obj, false);
+		if (likely(r == 0)) {
+			radeon_bo_kunmap(rdev->cp.ring_obj);
+			radeon_bo_unpin(rdev->cp.ring_obj);
+			radeon_bo_unreserve(rdev->cp.ring_obj);
+		}
+		radeon_bo_unref(&rdev->cp.ring_obj);
 		rdev->cp.ring = NULL;
 		rdev->cp.ring_obj = NULL;
 	}
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c
index 38537d9..067167c 100644
--- a/drivers/gpu/drm/radeon/radeon_state.c
+++ b/drivers/gpu/drm/radeon/radeon_state.c
@@ -1950,7 +1950,7 @@
  * Note that refcount can be at most 2, since during a free refcount=3
  * might mean we have to allocate a new surface which might not always
  * be available.
- * For example : we allocate three contigous surfaces ABC. If B is
+ * For example : we allocate three contiguous surfaces ABC. If B is
  * freed, we suddenly need two surfaces to store A and C, which might
  * not always be available.
  */
diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c
index f8a465d..391c973 100644
--- a/drivers/gpu/drm/radeon/radeon_test.c
+++ b/drivers/gpu/drm/radeon/radeon_test.c
@@ -30,8 +30,8 @@
 /* Test BO GTT->VRAM and VRAM->GTT GPU copies across the whole GTT aperture */
 void radeon_test_moves(struct radeon_device *rdev)
 {
-	struct radeon_object *vram_obj = NULL;
-	struct radeon_object **gtt_obj = NULL;
+	struct radeon_bo *vram_obj = NULL;
+	struct radeon_bo **gtt_obj = NULL;
 	struct radeon_fence *fence = NULL;
 	uint64_t gtt_addr, vram_addr;
 	unsigned i, n, size;
@@ -52,38 +52,42 @@
 		goto out_cleanup;
 	}
 
-	r = radeon_object_create(rdev, NULL, size, true, RADEON_GEM_DOMAIN_VRAM,
-				 false, &vram_obj);
+	r = radeon_bo_create(rdev, NULL, size, true, RADEON_GEM_DOMAIN_VRAM,
+				&vram_obj);
 	if (r) {
 		DRM_ERROR("Failed to create VRAM object\n");
 		goto out_cleanup;
 	}
-
-	r = radeon_object_pin(vram_obj, RADEON_GEM_DOMAIN_VRAM, &vram_addr);
+	r = radeon_bo_reserve(vram_obj, false);
+	if (unlikely(r != 0))
+		goto out_cleanup;
+	r = radeon_bo_pin(vram_obj, RADEON_GEM_DOMAIN_VRAM, &vram_addr);
 	if (r) {
 		DRM_ERROR("Failed to pin VRAM object\n");
 		goto out_cleanup;
 	}
-
 	for (i = 0; i < n; i++) {
 		void *gtt_map, *vram_map;
 		void **gtt_start, **gtt_end;
 		void **vram_start, **vram_end;
 
-		r = radeon_object_create(rdev, NULL, size, true,
-					 RADEON_GEM_DOMAIN_GTT, false, gtt_obj + i);
+		r = radeon_bo_create(rdev, NULL, size, true,
+					 RADEON_GEM_DOMAIN_GTT, gtt_obj + i);
 		if (r) {
 			DRM_ERROR("Failed to create GTT object %d\n", i);
 			goto out_cleanup;
 		}
 
-		r = radeon_object_pin(gtt_obj[i], RADEON_GEM_DOMAIN_GTT, &gtt_addr);
+		r = radeon_bo_reserve(gtt_obj[i], false);
+		if (unlikely(r != 0))
+			goto out_cleanup;
+		r = radeon_bo_pin(gtt_obj[i], RADEON_GEM_DOMAIN_GTT, &gtt_addr);
 		if (r) {
 			DRM_ERROR("Failed to pin GTT object %d\n", i);
 			goto out_cleanup;
 		}
 
-		r = radeon_object_kmap(gtt_obj[i], &gtt_map);
+		r = radeon_bo_kmap(gtt_obj[i], &gtt_map);
 		if (r) {
 			DRM_ERROR("Failed to map GTT object %d\n", i);
 			goto out_cleanup;
@@ -94,7 +98,7 @@
 		     gtt_start++)
 			*gtt_start = gtt_start;
 
-		radeon_object_kunmap(gtt_obj[i]);
+		radeon_bo_kunmap(gtt_obj[i]);
 
 		r = radeon_fence_create(rdev, &fence);
 		if (r) {
@@ -116,7 +120,7 @@
 
 		radeon_fence_unref(&fence);
 
-		r = radeon_object_kmap(vram_obj, &vram_map);
+		r = radeon_bo_kmap(vram_obj, &vram_map);
 		if (r) {
 			DRM_ERROR("Failed to map VRAM object after copy %d\n", i);
 			goto out_cleanup;
@@ -131,13 +135,13 @@
 					  "expected 0x%p (GTT map 0x%p-0x%p)\n",
 					  i, *vram_start, gtt_start, gtt_map,
 					  gtt_end);
-				radeon_object_kunmap(vram_obj);
+				radeon_bo_kunmap(vram_obj);
 				goto out_cleanup;
 			}
 			*vram_start = vram_start;
 		}
 
-		radeon_object_kunmap(vram_obj);
+		radeon_bo_kunmap(vram_obj);
 
 		r = radeon_fence_create(rdev, &fence);
 		if (r) {
@@ -159,7 +163,7 @@
 
 		radeon_fence_unref(&fence);
 
-		r = radeon_object_kmap(gtt_obj[i], &gtt_map);
+		r = radeon_bo_kmap(gtt_obj[i], &gtt_map);
 		if (r) {
 			DRM_ERROR("Failed to map GTT object after copy %d\n", i);
 			goto out_cleanup;
@@ -174,12 +178,12 @@
 					  "expected 0x%p (VRAM map 0x%p-0x%p)\n",
 					  i, *gtt_start, vram_start, vram_map,
 					  vram_end);
-				radeon_object_kunmap(gtt_obj[i]);
+				radeon_bo_kunmap(gtt_obj[i]);
 				goto out_cleanup;
 			}
 		}
 
-		radeon_object_kunmap(gtt_obj[i]);
+		radeon_bo_kunmap(gtt_obj[i]);
 
 		DRM_INFO("Tested GTT->VRAM and VRAM->GTT copy for GTT offset 0x%llx\n",
 			 gtt_addr - rdev->mc.gtt_location);
@@ -187,14 +191,20 @@
 
 out_cleanup:
 	if (vram_obj) {
-		radeon_object_unpin(vram_obj);
-		radeon_object_unref(&vram_obj);
+		if (radeon_bo_is_reserved(vram_obj)) {
+			radeon_bo_unpin(vram_obj);
+			radeon_bo_unreserve(vram_obj);
+		}
+		radeon_bo_unref(&vram_obj);
 	}
 	if (gtt_obj) {
 		for (i = 0; i < n; i++) {
 			if (gtt_obj[i]) {
-				radeon_object_unpin(gtt_obj[i]);
-				radeon_object_unref(&gtt_obj[i]);
+				if (radeon_bo_is_reserved(gtt_obj[i])) {
+					radeon_bo_unpin(gtt_obj[i]);
+					radeon_bo_unreserve(gtt_obj[i]);
+				}
+				radeon_bo_unref(&gtt_obj[i]);
 			}
 		}
 		kfree(gtt_obj);
@@ -206,4 +216,3 @@
 		printk(KERN_WARNING "Error while testing BO move.\n");
 	}
 }
-
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index 1381e06..5a19d52 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -150,7 +150,7 @@
 		man->default_caching = TTM_PL_FLAG_CACHED;
 		break;
 	case TTM_PL_TT:
-		man->gpu_offset = 0;
+		man->gpu_offset = rdev->mc.gtt_location;
 		man->available_caching = TTM_PL_MASK_CACHING;
 		man->default_caching = TTM_PL_FLAG_CACHED;
 		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | TTM_MEMTYPE_FLAG_CMA;
@@ -180,7 +180,7 @@
 		break;
 	case TTM_PL_VRAM:
 		/* "On-card" video ram */
-		man->gpu_offset = 0;
+		man->gpu_offset = rdev->mc.vram_location;
 		man->flags = TTM_MEMTYPE_FLAG_FIXED |
 			     TTM_MEMTYPE_FLAG_NEEDS_IOREMAP |
 			     TTM_MEMTYPE_FLAG_MAPPABLE;
@@ -197,16 +197,19 @@
 	return 0;
 }
 
-static uint32_t radeon_evict_flags(struct ttm_buffer_object *bo)
+static void radeon_evict_flags(struct ttm_buffer_object *bo,
+				struct ttm_placement *placement)
 {
-	uint32_t cur_placement = bo->mem.placement & ~TTM_PL_MASK_MEMTYPE;
-
+	struct radeon_bo *rbo = container_of(bo, struct radeon_bo, tbo);
 	switch (bo->mem.mem_type) {
+	case TTM_PL_VRAM:
+		radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT);
+		break;
+	case TTM_PL_TT:
 	default:
-		return (cur_placement & ~TTM_PL_MASK_CACHING) |
-			TTM_PL_FLAG_SYSTEM |
-			TTM_PL_FLAG_CACHED;
+		radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU);
 	}
+	*placement = rbo->placement;
 }
 
 static int radeon_verify_access(struct ttm_buffer_object *bo, struct file *filp)
@@ -283,14 +286,21 @@
 	struct radeon_device *rdev;
 	struct ttm_mem_reg *old_mem = &bo->mem;
 	struct ttm_mem_reg tmp_mem;
-	uint32_t proposed_placement;
+	u32 placements;
+	struct ttm_placement placement;
 	int r;
 
 	rdev = radeon_get_rdev(bo->bdev);
 	tmp_mem = *new_mem;
 	tmp_mem.mm_node = NULL;
-	proposed_placement = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING;
-	r = ttm_bo_mem_space(bo, proposed_placement, &tmp_mem,
+	placement.fpfn = 0;
+	placement.lpfn = 0;
+	placement.num_placement = 1;
+	placement.placement = &placements;
+	placement.num_busy_placement = 1;
+	placement.busy_placement = &placements;
+	placements = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;
+	r = ttm_bo_mem_space(bo, &placement, &tmp_mem,
 			     interruptible, no_wait);
 	if (unlikely(r)) {
 		return r;
@@ -329,15 +339,21 @@
 	struct radeon_device *rdev;
 	struct ttm_mem_reg *old_mem = &bo->mem;
 	struct ttm_mem_reg tmp_mem;
-	uint32_t proposed_flags;
+	struct ttm_placement placement;
+	u32 placements;
 	int r;
 
 	rdev = radeon_get_rdev(bo->bdev);
 	tmp_mem = *new_mem;
 	tmp_mem.mm_node = NULL;
-	proposed_flags = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING;
-	r = ttm_bo_mem_space(bo, proposed_flags, &tmp_mem,
-			     interruptible, no_wait);
+	placement.fpfn = 0;
+	placement.lpfn = 0;
+	placement.num_placement = 1;
+	placement.placement = &placements;
+	placement.num_busy_placement = 1;
+	placement.busy_placement = &placements;
+	placements = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;
+	r = ttm_bo_mem_space(bo, &placement, &tmp_mem, interruptible, no_wait);
 	if (unlikely(r)) {
 		return r;
 	}
@@ -378,7 +394,7 @@
 	     new_mem->mem_type == TTM_PL_SYSTEM) ||
 	    (old_mem->mem_type == TTM_PL_SYSTEM &&
 	     new_mem->mem_type == TTM_PL_TT)) {
-		/* bind is enought */
+		/* bind is enough */
 		radeon_move_null(bo, new_mem);
 		return 0;
 	}
@@ -407,18 +423,6 @@
 	return r;
 }
 
-const uint32_t radeon_mem_prios[] = {
-	TTM_PL_VRAM,
-	TTM_PL_TT,
-	TTM_PL_SYSTEM,
-};
-
-const uint32_t radeon_busy_prios[] = {
-	TTM_PL_TT,
-	TTM_PL_VRAM,
-	TTM_PL_SYSTEM,
-};
-
 static int radeon_sync_obj_wait(void *sync_obj, void *sync_arg,
 				bool lazy, bool interruptible)
 {
@@ -446,10 +450,6 @@
 }
 
 static struct ttm_bo_driver radeon_bo_driver = {
-	.mem_type_prio = radeon_mem_prios,
-	.mem_busy_prio = radeon_busy_prios,
-	.num_mem_type_prio = ARRAY_SIZE(radeon_mem_prios),
-	.num_mem_busy_prio = ARRAY_SIZE(radeon_busy_prios),
 	.create_ttm_backend_entry = &radeon_create_ttm_backend_entry,
 	.invalidate_caches = &radeon_invalidate_caches,
 	.init_mem_type = &radeon_init_mem_type,
@@ -482,27 +482,31 @@
 		DRM_ERROR("failed initializing buffer object driver(%d).\n", r);
 		return r;
 	}
-	r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_VRAM, 0,
-			   ((rdev->mc.real_vram_size) >> PAGE_SHIFT));
+	r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_VRAM,
+				rdev->mc.real_vram_size >> PAGE_SHIFT);
 	if (r) {
 		DRM_ERROR("Failed initializing VRAM heap.\n");
 		return r;
 	}
-	r = radeon_object_create(rdev, NULL, 256 * 1024, true,
-				 RADEON_GEM_DOMAIN_VRAM, false,
-				 &rdev->stollen_vga_memory);
+	r = radeon_bo_create(rdev, NULL, 256 * 1024, true,
+				RADEON_GEM_DOMAIN_VRAM,
+				&rdev->stollen_vga_memory);
 	if (r) {
 		return r;
 	}
-	r = radeon_object_pin(rdev->stollen_vga_memory, RADEON_GEM_DOMAIN_VRAM, NULL);
+	r = radeon_bo_reserve(rdev->stollen_vga_memory, false);
+	if (r)
+		return r;
+	r = radeon_bo_pin(rdev->stollen_vga_memory, RADEON_GEM_DOMAIN_VRAM, NULL);
+	radeon_bo_unreserve(rdev->stollen_vga_memory);
 	if (r) {
-		radeon_object_unref(&rdev->stollen_vga_memory);
+		radeon_bo_unref(&rdev->stollen_vga_memory);
 		return r;
 	}
 	DRM_INFO("radeon: %uM of VRAM memory ready\n",
 		 (unsigned)rdev->mc.real_vram_size / (1024 * 1024));
-	r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT, 0,
-			   ((rdev->mc.gtt_size) >> PAGE_SHIFT));
+	r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT,
+				rdev->mc.gtt_size >> PAGE_SHIFT);
 	if (r) {
 		DRM_ERROR("Failed initializing GTT heap.\n");
 		return r;
@@ -523,9 +527,15 @@
 
 void radeon_ttm_fini(struct radeon_device *rdev)
 {
+	int r;
+
 	if (rdev->stollen_vga_memory) {
-		radeon_object_unpin(rdev->stollen_vga_memory);
-		radeon_object_unref(&rdev->stollen_vga_memory);
+		r = radeon_bo_reserve(rdev->stollen_vga_memory, false);
+		if (r == 0) {
+			radeon_bo_unpin(rdev->stollen_vga_memory);
+			radeon_bo_unreserve(rdev->stollen_vga_memory);
+		}
+		radeon_bo_unref(&rdev->stollen_vga_memory);
 	}
 	ttm_bo_clean_mm(&rdev->mman.bdev, TTM_PL_VRAM);
 	ttm_bo_clean_mm(&rdev->mman.bdev, TTM_PL_TT);
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c
index ca03716..c1fcddd 100644
--- a/drivers/gpu/drm/radeon/rs400.c
+++ b/drivers/gpu/drm/radeon/rs400.c
@@ -352,7 +352,7 @@
 	u32 tmp;
 
 	/* Setup GPU memory space */
-	tmp = G_00015C_MC_FB_START(RREG32(R_00015C_NB_TOM));
+	tmp = RREG32(R_00015C_NB_TOM);
 	rdev->mc.vram_location = G_00015C_MC_FB_START(tmp) << 16;
 	rdev->mc.gtt_location = 0xFFFFFFFFUL;
 	r = radeon_mc_setup(rdev);
@@ -387,13 +387,13 @@
 	r300_clock_startup(rdev);
 	/* Initialize GPU configuration (# pipes, ...) */
 	rs400_gpu_init(rdev);
+	r100_enable_bm(rdev);
 	/* Initialize GART (initialize after TTM so we can allocate
 	 * memory through TTM but finalize after TTM) */
 	r = rs400_gart_enable(rdev);
 	if (r)
 		return r;
 	/* Enable IRQ */
-	rdev->irq.sw_int = true;
 	r100_irq_set(rdev);
 	/* 1M ring buffer */
 	r = r100_cp_init(rdev, 1024 * 1024);
@@ -430,6 +430,8 @@
 	radeon_combios_asic_init(rdev->ddev);
 	/* Resume clock after posting */
 	r300_clock_startup(rdev);
+	/* Initialize surface registers */
+	radeon_surface_init(rdev);
 	return rs400_startup(rdev);
 }
 
@@ -452,7 +454,7 @@
 	rs400_gart_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	radeon_fence_driver_fini(rdev);
-	radeon_object_fini(rdev);
+	radeon_bo_fini(rdev);
 	radeon_atombios_fini(rdev);
 	kfree(rdev->bios);
 	rdev->bios = NULL;
@@ -490,10 +492,9 @@
 			RREG32(R_0007C0_CP_STAT));
 	}
 	/* check if cards are posted or not */
-	if (!radeon_card_posted(rdev) && rdev->bios) {
-		DRM_INFO("GPU not posted. posting now...\n");
-		radeon_combios_asic_init(rdev->ddev);
-	}
+	if (radeon_boot_test_post_card(rdev) == false)
+		return -EINVAL;
+
 	/* Initialize clocks */
 	radeon_get_clock_info(rdev->ddev);
 	/* Get vram informations */
@@ -510,7 +511,7 @@
 	if (r)
 		return r;
 	/* Memory manager */
-	r = radeon_object_init(rdev);
+	r = radeon_bo_init(rdev);
 	if (r)
 		return r;
 	r = rs400_gart_init(rdev);
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 5f117cd..4f8ea42 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -45,6 +45,122 @@
 void rs600_gpu_init(struct radeon_device *rdev);
 int rs600_mc_wait_for_idle(struct radeon_device *rdev);
 
+int rs600_mc_init(struct radeon_device *rdev)
+{
+	/* read back the MC value from the hw */
+	int r;
+	u32 tmp;
+
+	/* Setup GPU memory space */
+	tmp = RREG32_MC(R_000004_MC_FB_LOCATION);
+	rdev->mc.vram_location = G_000004_MC_FB_START(tmp) << 16;
+	rdev->mc.gtt_location = 0xffffffffUL;
+	r = radeon_mc_setup(rdev);
+	if (r)
+		return r;
+	return 0;
+}
+
+/* hpd for digital panel detect/disconnect */
+bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
+{
+	u32 tmp;
+	bool connected = false;
+
+	switch (hpd) {
+	case RADEON_HPD_1:
+		tmp = RREG32(R_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS);
+		if (G_007D04_DC_HOT_PLUG_DETECT1_SENSE(tmp))
+			connected = true;
+		break;
+	case RADEON_HPD_2:
+		tmp = RREG32(R_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS);
+		if (G_007D14_DC_HOT_PLUG_DETECT2_SENSE(tmp))
+			connected = true;
+		break;
+	default:
+		break;
+	}
+	return connected;
+}
+
+void rs600_hpd_set_polarity(struct radeon_device *rdev,
+			    enum radeon_hpd_id hpd)
+{
+	u32 tmp;
+	bool connected = rs600_hpd_sense(rdev, hpd);
+
+	switch (hpd) {
+	case RADEON_HPD_1:
+		tmp = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL);
+		if (connected)
+			tmp &= ~S_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(1);
+		else
+			tmp |= S_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(1);
+		WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);
+		break;
+	case RADEON_HPD_2:
+		tmp = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL);
+		if (connected)
+			tmp &= ~S_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(1);
+		else
+			tmp |= S_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(1);
+		WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);
+		break;
+	default:
+		break;
+	}
+}
+
+void rs600_hpd_init(struct radeon_device *rdev)
+{
+	struct drm_device *dev = rdev->ddev;
+	struct drm_connector *connector;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+		switch (radeon_connector->hpd.hpd) {
+		case RADEON_HPD_1:
+			WREG32(R_007D00_DC_HOT_PLUG_DETECT1_CONTROL,
+			       S_007D00_DC_HOT_PLUG_DETECT1_EN(1));
+			rdev->irq.hpd[0] = true;
+			break;
+		case RADEON_HPD_2:
+			WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL,
+			       S_007D10_DC_HOT_PLUG_DETECT2_EN(1));
+			rdev->irq.hpd[1] = true;
+			break;
+		default:
+			break;
+		}
+	}
+	rs600_irq_set(rdev);
+}
+
+void rs600_hpd_fini(struct radeon_device *rdev)
+{
+	struct drm_device *dev = rdev->ddev;
+	struct drm_connector *connector;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+		switch (radeon_connector->hpd.hpd) {
+		case RADEON_HPD_1:
+			WREG32(R_007D00_DC_HOT_PLUG_DETECT1_CONTROL,
+			       S_007D00_DC_HOT_PLUG_DETECT1_EN(0));
+			rdev->irq.hpd[0] = false;
+			break;
+		case RADEON_HPD_2:
+			WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL,
+			       S_007D10_DC_HOT_PLUG_DETECT2_EN(0));
+			rdev->irq.hpd[1] = false;
+			break;
+		default:
+			break;
+		}
+	}
+}
+
 /*
  * GART.
  */
@@ -100,40 +216,40 @@
 	WREG32(R_00004C_BUS_CNTL, tmp);
 	/* FIXME: setup default page */
 	WREG32_MC(R_000100_MC_PT0_CNTL,
-		 (S_000100_EFFECTIVE_L2_CACHE_SIZE(6) |
-		  S_000100_EFFECTIVE_L2_QUEUE_SIZE(6)));
+		  (S_000100_EFFECTIVE_L2_CACHE_SIZE(6) |
+		   S_000100_EFFECTIVE_L2_QUEUE_SIZE(6)));
+
 	for (i = 0; i < 19; i++) {
 		WREG32_MC(R_00016C_MC_PT0_CLIENT0_CNTL + i,
-			S_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE(1) |
-			S_00016C_SYSTEM_ACCESS_MODE_MASK(
-				V_00016C_SYSTEM_ACCESS_MODE_IN_SYS) |
-			S_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS(
-				V_00016C_SYSTEM_APERTURE_UNMAPPED_DEFAULT_PAGE) |
-			S_00016C_EFFECTIVE_L1_CACHE_SIZE(1) |
-			S_00016C_ENABLE_FRAGMENT_PROCESSING(1) |
-			S_00016C_EFFECTIVE_L1_QUEUE_SIZE(1));
+			  S_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE(1) |
+			  S_00016C_SYSTEM_ACCESS_MODE_MASK(
+				  V_00016C_SYSTEM_ACCESS_MODE_NOT_IN_SYS) |
+			  S_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS(
+				  V_00016C_SYSTEM_APERTURE_UNMAPPED_PASSTHROUGH) |
+			  S_00016C_EFFECTIVE_L1_CACHE_SIZE(3) |
+			  S_00016C_ENABLE_FRAGMENT_PROCESSING(1) |
+			  S_00016C_EFFECTIVE_L1_QUEUE_SIZE(3));
 	}
-
-	/* System context map to GART space */
-	WREG32_MC(R_000112_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.gtt_start);
-	WREG32_MC(R_000114_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.gtt_end);
-
 	/* enable first context */
-	WREG32_MC(R_00013C_MC_PT0_CONTEXT0_FLAT_START_ADDR, rdev->mc.gtt_start);
-	WREG32_MC(R_00014C_MC_PT0_CONTEXT0_FLAT_END_ADDR, rdev->mc.gtt_end);
 	WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL,
-			S_000102_ENABLE_PAGE_TABLE(1) |
-			S_000102_PAGE_TABLE_DEPTH(V_000102_PAGE_TABLE_FLAT));
+		  S_000102_ENABLE_PAGE_TABLE(1) |
+		  S_000102_PAGE_TABLE_DEPTH(V_000102_PAGE_TABLE_FLAT));
+
 	/* disable all other contexts */
-	for (i = 1; i < 8; i++) {
+	for (i = 1; i < 8; i++)
 		WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL + i, 0);
-	}
 
 	/* setup the page table */
 	WREG32_MC(R_00012C_MC_PT0_CONTEXT0_FLAT_BASE_ADDR,
-			rdev->gart.table_addr);
+		  rdev->gart.table_addr);
+	WREG32_MC(R_00013C_MC_PT0_CONTEXT0_FLAT_START_ADDR, rdev->mc.gtt_start);
+	WREG32_MC(R_00014C_MC_PT0_CONTEXT0_FLAT_END_ADDR, rdev->mc.gtt_end);
 	WREG32_MC(R_00011C_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0);
 
+	/* System context maps to VRAM space */
+	WREG32_MC(R_000112_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start);
+	WREG32_MC(R_000114_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end);
+
 	/* enable page tables */
 	tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
 	WREG32_MC(R_000100_MC_PT0_CNTL, (tmp | S_000100_ENABLE_PT(1)));
@@ -146,15 +262,20 @@
 
 void rs600_gart_disable(struct radeon_device *rdev)
 {
-	uint32_t tmp;
+	u32 tmp;
+	int r;
 
 	/* FIXME: disable out of gart access */
 	WREG32_MC(R_000100_MC_PT0_CNTL, 0);
 	tmp = RREG32_MC(R_000009_MC_CNTL1);
 	WREG32_MC(R_000009_MC_CNTL1, tmp & C_000009_ENABLE_PAGE_TABLES);
 	if (rdev->gart.table.vram.robj) {
-		radeon_object_kunmap(rdev->gart.table.vram.robj);
-		radeon_object_unpin(rdev->gart.table.vram.robj);
+		r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
+		if (r == 0) {
+			radeon_bo_kunmap(rdev->gart.table.vram.robj);
+			radeon_bo_unpin(rdev->gart.table.vram.robj);
+			radeon_bo_unreserve(rdev->gart.table.vram.robj);
+		}
 	}
 }
 
@@ -189,6 +310,10 @@
 {
 	uint32_t tmp = 0;
 	uint32_t mode_int = 0;
+	u32 hpd1 = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL) &
+		~S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(1);
+	u32 hpd2 = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL) &
+		~S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1);
 
 	if (rdev->irq.sw_int) {
 		tmp |= S_000040_SW_INT_EN(1);
@@ -199,8 +324,16 @@
 	if (rdev->irq.crtc_vblank_int[1]) {
 		mode_int |= S_006540_D2MODE_VBLANK_INT_MASK(1);
 	}
+	if (rdev->irq.hpd[0]) {
+		hpd1 |= S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(1);
+	}
+	if (rdev->irq.hpd[1]) {
+		hpd2 |= S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1);
+	}
 	WREG32(R_000040_GEN_INT_CNTL, tmp);
 	WREG32(R_006540_DxMODE_INT_MASK, mode_int);
+	WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1);
+	WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2);
 	return 0;
 }
 
@@ -208,6 +341,7 @@
 {
 	uint32_t irqs = RREG32(R_000044_GEN_INT_STATUS);
 	uint32_t irq_mask = ~C_000044_SW_INT;
+	u32 tmp;
 
 	if (G_000044_DISPLAY_INT_STAT(irqs)) {
 		*r500_disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS);
@@ -219,6 +353,16 @@
 			WREG32(R_006D34_D2MODE_VBLANK_STATUS,
 				S_006D34_D2MODE_VBLANK_ACK(1));
 		}
+		if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(*r500_disp_int)) {
+			tmp = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL);
+			tmp |= S_007D08_DC_HOT_PLUG_DETECT1_INT_ACK(1);
+			WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);
+		}
+		if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(*r500_disp_int)) {
+			tmp = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL);
+			tmp |= S_007D18_DC_HOT_PLUG_DETECT2_INT_ACK(1);
+			WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);
+		}
 	} else {
 		*r500_disp_int = 0;
 	}
@@ -244,6 +388,7 @@
 {
 	uint32_t status, msi_rearm;
 	uint32_t r500_disp_int;
+	bool queue_hotplug = false;
 
 	status = rs600_irq_ack(rdev, &r500_disp_int);
 	if (!status && !r500_disp_int) {
@@ -258,8 +403,18 @@
 			drm_handle_vblank(rdev->ddev, 0);
 		if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int))
 			drm_handle_vblank(rdev->ddev, 1);
+		if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(r500_disp_int)) {
+			queue_hotplug = true;
+			DRM_DEBUG("HPD1\n");
+		}
+		if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(r500_disp_int)) {
+			queue_hotplug = true;
+			DRM_DEBUG("HPD2\n");
+		}
 		status = rs600_irq_ack(rdev, &r500_disp_int);
 	}
+	if (queue_hotplug)
+		queue_work(rdev->wq, &rdev->hotplug_work);
 	if (rdev->msi_enabled) {
 		switch (rdev->family) {
 		case CHIP_RS600:
@@ -301,9 +456,7 @@
 
 void rs600_gpu_init(struct radeon_device *rdev)
 {
-	/* FIXME: HDP same place on rs600 ? */
 	r100_hdp_reset(rdev);
-	/* FIXME: is this correct ? */
 	r420_pipes_init(rdev);
 	/* Wait for mc idle */
 	if (rs600_mc_wait_for_idle(rdev))
@@ -312,9 +465,20 @@
 
 void rs600_vram_info(struct radeon_device *rdev)
 {
-	/* FIXME: to do or is these values sane ? */
 	rdev->mc.vram_is_ddr = true;
 	rdev->mc.vram_width = 128;
+
+	rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
+	rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
+
+	rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
+	rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+
+	if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
+		rdev->mc.mc_vram_size = rdev->mc.aper_size;
+
+	if (rdev->mc.real_vram_size > rdev->mc.aper_size)
+		rdev->mc.real_vram_size = rdev->mc.aper_size;
 }
 
 void rs600_bandwidth_update(struct radeon_device *rdev)
@@ -388,7 +552,6 @@
 	if (r)
 		return r;
 	/* Enable IRQ */
-	rdev->irq.sw_int = true;
 	rs600_irq_set(rdev);
 	/* 1M ring buffer */
 	r = r100_cp_init(rdev, 1024 * 1024);
@@ -423,6 +586,8 @@
 	atom_asic_init(rdev->mode_info.atom_context);
 	/* Resume clock after posting */
 	rv515_clock_startup(rdev);
+	/* Initialize surface registers */
+	radeon_surface_init(rdev);
 	return rs600_startup(rdev);
 }
 
@@ -445,7 +610,7 @@
 	rs600_gart_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	radeon_fence_driver_fini(rdev);
-	radeon_object_fini(rdev);
+	radeon_bo_fini(rdev);
 	radeon_atombios_fini(rdev);
 	kfree(rdev->bios);
 	rdev->bios = NULL;
@@ -482,10 +647,9 @@
 			RREG32(R_0007C0_CP_STAT));
 	}
 	/* check if cards are posted or not */
-	if (!radeon_card_posted(rdev) && rdev->bios) {
-		DRM_INFO("GPU not posted. posting now...\n");
-		atom_asic_init(rdev->mode_info.atom_context);
-	}
+	if (radeon_boot_test_post_card(rdev) == false)
+		return -EINVAL;
+
 	/* Initialize clocks */
 	radeon_get_clock_info(rdev->ddev);
 	/* Initialize power management */
@@ -493,7 +657,7 @@
 	/* Get vram informations */
 	rs600_vram_info(rdev);
 	/* Initialize memory controller (also test AGP) */
-	r = r420_mc_init(rdev);
+	r = rs600_mc_init(rdev);
 	if (r)
 		return r;
 	rs600_debugfs(rdev);
@@ -505,7 +669,7 @@
 	if (r)
 		return r;
 	/* Memory manager */
-	r = radeon_object_init(rdev);
+	r = radeon_bo_init(rdev);
 	if (r)
 		return r;
 	r = rs600_gart_init(rdev);
diff --git a/drivers/gpu/drm/radeon/rs600d.h b/drivers/gpu/drm/radeon/rs600d.h
index 8130892..c1c8f58 100644
--- a/drivers/gpu/drm/radeon/rs600d.h
+++ b/drivers/gpu/drm/radeon/rs600d.h
@@ -30,27 +30,12 @@
 
 /* Registers */
 #define R_000040_GEN_INT_CNTL                        0x000040
-#define   S_000040_DISPLAY_INT_STATUS(x)               (((x) & 0x1) << 0)
-#define   G_000040_DISPLAY_INT_STATUS(x)               (((x) >> 0) & 0x1)
-#define   C_000040_DISPLAY_INT_STATUS                  0xFFFFFFFE
-#define   S_000040_DMA_VIPH0_INT_EN(x)                 (((x) & 0x1) << 12)
-#define   G_000040_DMA_VIPH0_INT_EN(x)                 (((x) >> 12) & 0x1)
-#define   C_000040_DMA_VIPH0_INT_EN                    0xFFFFEFFF
-#define   S_000040_CRTC2_VSYNC(x)                      (((x) & 0x1) << 6)
-#define   G_000040_CRTC2_VSYNC(x)                      (((x) >> 6) & 0x1)
-#define   C_000040_CRTC2_VSYNC                         0xFFFFFFBF
-#define   S_000040_SNAPSHOT2(x)                        (((x) & 0x1) << 7)
-#define   G_000040_SNAPSHOT2(x)                        (((x) >> 7) & 0x1)
-#define   C_000040_SNAPSHOT2                           0xFFFFFF7F
-#define   S_000040_CRTC2_VBLANK(x)                     (((x) & 0x1) << 9)
-#define   G_000040_CRTC2_VBLANK(x)                     (((x) >> 9) & 0x1)
-#define   C_000040_CRTC2_VBLANK                        0xFFFFFDFF
-#define   S_000040_FP2_DETECT(x)                       (((x) & 0x1) << 10)
-#define   G_000040_FP2_DETECT(x)                       (((x) >> 10) & 0x1)
-#define   C_000040_FP2_DETECT                          0xFFFFFBFF
-#define   S_000040_VSYNC_DIFF_OVER_LIMIT(x)            (((x) & 0x1) << 11)
-#define   G_000040_VSYNC_DIFF_OVER_LIMIT(x)            (((x) >> 11) & 0x1)
-#define   C_000040_VSYNC_DIFF_OVER_LIMIT               0xFFFFF7FF
+#define   S_000040_SCRATCH_INT_MASK(x)                 (((x) & 0x1) << 18)
+#define   G_000040_SCRATCH_INT_MASK(x)                 (((x) >> 18) & 0x1)
+#define   C_000040_SCRATCH_INT_MASK                    0xFFFBFFFF
+#define   S_000040_GUI_IDLE_MASK(x)                    (((x) & 0x1) << 19)
+#define   G_000040_GUI_IDLE_MASK(x)                    (((x) >> 19) & 0x1)
+#define   C_000040_GUI_IDLE_MASK                       0xFFF7FFFF
 #define   S_000040_DMA_VIPH1_INT_EN(x)                 (((x) & 0x1) << 13)
 #define   G_000040_DMA_VIPH1_INT_EN(x)                 (((x) >> 13) & 0x1)
 #define   C_000040_DMA_VIPH1_INT_EN                    0xFFFFDFFF
@@ -370,7 +355,90 @@
 #define   S_007EDC_LB_D2_VBLANK_INTERRUPT(x)           (((x) & 0x1) << 5)
 #define   G_007EDC_LB_D2_VBLANK_INTERRUPT(x)           (((x) >> 5) & 0x1)
 #define   C_007EDC_LB_D2_VBLANK_INTERRUPT              0xFFFFFFDF
-
+#define   S_007EDC_DACA_AUTODETECT_INTERRUPT(x)        (((x) & 0x1) << 16)
+#define   G_007EDC_DACA_AUTODETECT_INTERRUPT(x)        (((x) >> 16) & 0x1)
+#define   C_007EDC_DACA_AUTODETECT_INTERRUPT           0xFFFEFFFF
+#define   S_007EDC_DACB_AUTODETECT_INTERRUPT(x)        (((x) & 0x1) << 17)
+#define   G_007EDC_DACB_AUTODETECT_INTERRUPT(x)        (((x) >> 17) & 0x1)
+#define   C_007EDC_DACB_AUTODETECT_INTERRUPT           0xFFFDFFFF
+#define   S_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(x)    (((x) & 0x1) << 18)
+#define   G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(x)    (((x) >> 18) & 0x1)
+#define   C_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT       0xFFFBFFFF
+#define   S_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(x)    (((x) & 0x1) << 19)
+#define   G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(x)    (((x) >> 19) & 0x1)
+#define   C_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT       0xFFF7FFFF
+#define R_007828_DACA_AUTODETECT_CONTROL               0x007828
+#define   S_007828_DACA_AUTODETECT_MODE(x)             (((x) & 0x3) << 0)
+#define   G_007828_DACA_AUTODETECT_MODE(x)             (((x) >> 0) & 0x3)
+#define   C_007828_DACA_AUTODETECT_MODE                0xFFFFFFFC
+#define   S_007828_DACA_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) & 0xff) << 8)
+#define   G_007828_DACA_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) >> 8) & 0xff)
+#define   C_007828_DACA_AUTODETECT_FRAME_TIME_COUNTER  0xFFFF00FF
+#define   S_007828_DACA_AUTODETECT_CHECK_MASK(x)       (((x) & 0x3) << 16)
+#define   G_007828_DACA_AUTODETECT_CHECK_MASK(x)       (((x) >> 16) & 0x3)
+#define   C_007828_DACA_AUTODETECT_CHECK_MASK          0xFFFCFFFF
+#define R_007838_DACA_AUTODETECT_INT_CONTROL           0x007838
+#define   S_007838_DACA_AUTODETECT_ACK(x)              (((x) & 0x1) << 0)
+#define   C_007838_DACA_DACA_AUTODETECT_ACK            0xFFFFFFFE
+#define   S_007838_DACA_AUTODETECT_INT_ENABLE(x)       (((x) & 0x1) << 16)
+#define   G_007838_DACA_AUTODETECT_INT_ENABLE(x)       (((x) >> 16) & 0x1)
+#define   C_007838_DACA_AUTODETECT_INT_ENABLE          0xFFFCFFFF
+#define R_007A28_DACB_AUTODETECT_CONTROL               0x007A28
+#define   S_007A28_DACB_AUTODETECT_MODE(x)             (((x) & 0x3) << 0)
+#define   G_007A28_DACB_AUTODETECT_MODE(x)             (((x) >> 0) & 0x3)
+#define   C_007A28_DACB_AUTODETECT_MODE                0xFFFFFFFC
+#define   S_007A28_DACB_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) & 0xff) << 8)
+#define   G_007A28_DACB_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) >> 8) & 0xff)
+#define   C_007A28_DACB_AUTODETECT_FRAME_TIME_COUNTER  0xFFFF00FF
+#define   S_007A28_DACB_AUTODETECT_CHECK_MASK(x)       (((x) & 0x3) << 16)
+#define   G_007A28_DACB_AUTODETECT_CHECK_MASK(x)       (((x) >> 16) & 0x3)
+#define   C_007A28_DACB_AUTODETECT_CHECK_MASK          0xFFFCFFFF
+#define R_007A38_DACB_AUTODETECT_INT_CONTROL           0x007A38
+#define   S_007A38_DACB_AUTODETECT_ACK(x)              (((x) & 0x1) << 0)
+#define   C_007A38_DACB_DACA_AUTODETECT_ACK            0xFFFFFFFE
+#define   S_007A38_DACB_AUTODETECT_INT_ENABLE(x)       (((x) & 0x1) << 16)
+#define   G_007A38_DACB_AUTODETECT_INT_ENABLE(x)       (((x) >> 16) & 0x1)
+#define   C_007A38_DACB_AUTODETECT_INT_ENABLE          0xFFFCFFFF
+#define R_007D00_DC_HOT_PLUG_DETECT1_CONTROL           0x007D00
+#define   S_007D00_DC_HOT_PLUG_DETECT1_EN(x)           (((x) & 0x1) << 0)
+#define   G_007D00_DC_HOT_PLUG_DETECT1_EN(x)           (((x) >> 0) & 0x1)
+#define   C_007D00_DC_HOT_PLUG_DETECT1_EN              0xFFFFFFFE
+#define R_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS        0x007D04
+#define   S_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS(x)   (((x) & 0x1) << 0)
+#define   G_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS(x)   (((x) >> 0) & 0x1)
+#define   C_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS      0xFFFFFFFE
+#define   S_007D04_DC_HOT_PLUG_DETECT1_SENSE(x)        (((x) & 0x1) << 1)
+#define   G_007D04_DC_HOT_PLUG_DETECT1_SENSE(x)        (((x) >> 1) & 0x1)
+#define   C_007D04_DC_HOT_PLUG_DETECT1_SENSE           0xFFFFFFFD
+#define R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL       0x007D08
+#define   S_007D08_DC_HOT_PLUG_DETECT1_INT_ACK(x)      (((x) & 0x1) << 0)
+#define   C_007D08_DC_HOT_PLUG_DETECT1_INT_ACK         0xFFFFFFFE
+#define   S_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(x) (((x) & 0x1) << 8)
+#define   G_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(x) (((x) >> 8) & 0x1)
+#define   C_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY    0xFFFFFEFF
+#define   S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(x)       (((x) & 0x1) << 16)
+#define   G_007D08_DC_HOT_PLUG_DETECT1_INT_EN(x)       (((x) >> 16) & 0x1)
+#define   C_007D08_DC_HOT_PLUG_DETECT1_INT_EN          0xFFFEFFFF
+#define R_007D10_DC_HOT_PLUG_DETECT2_CONTROL           0x007D10
+#define   S_007D10_DC_HOT_PLUG_DETECT2_EN(x)           (((x) & 0x1) << 0)
+#define   G_007D10_DC_HOT_PLUG_DETECT2_EN(x)           (((x) >> 0) & 0x1)
+#define   C_007D10_DC_HOT_PLUG_DETECT2_EN              0xFFFFFFFE
+#define R_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS        0x007D14
+#define   S_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS(x)   (((x) & 0x1) << 0)
+#define   G_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS(x)   (((x) >> 0) & 0x1)
+#define   C_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS      0xFFFFFFFE
+#define   S_007D14_DC_HOT_PLUG_DETECT2_SENSE(x)        (((x) & 0x1) << 1)
+#define   G_007D14_DC_HOT_PLUG_DETECT2_SENSE(x)        (((x) >> 1) & 0x1)
+#define   C_007D14_DC_HOT_PLUG_DETECT2_SENSE           0xFFFFFFFD
+#define R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL       0x007D18
+#define   S_007D18_DC_HOT_PLUG_DETECT2_INT_ACK(x)      (((x) & 0x1) << 0)
+#define   C_007D18_DC_HOT_PLUG_DETECT2_INT_ACK         0xFFFFFFFE
+#define   S_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(x) (((x) & 0x1) << 8)
+#define   G_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(x) (((x) >> 8) & 0x1)
+#define   C_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY    0xFFFFFEFF
+#define   S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(x)       (((x) & 0x1) << 16)
+#define   G_007D18_DC_HOT_PLUG_DETECT2_INT_EN(x)       (((x) >> 16) & 0x1)
+#define   C_007D18_DC_HOT_PLUG_DETECT2_INT_EN          0xFFFEFFFF
 
 /* MC registers */
 #define R_000000_MC_STATUS                           0x000000
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c
index 2754717..1e22f52 100644
--- a/drivers/gpu/drm/radeon/rs690.c
+++ b/drivers/gpu/drm/radeon/rs690.c
@@ -131,24 +131,25 @@
 
 void rs690_vram_info(struct radeon_device *rdev)
 {
-	uint32_t tmp;
 	fixed20_12 a;
 
 	rs400_gart_adjust_size(rdev);
-	/* DDR for all card after R300 & IGP */
+
 	rdev->mc.vram_is_ddr = true;
-	/* FIXME: is this correct for RS690/RS740 ? */
-	tmp = RREG32(RADEON_MEM_CNTL);
-	if (tmp & R300_MEM_NUM_CHANNELS_MASK) {
-		rdev->mc.vram_width = 128;
-	} else {
-		rdev->mc.vram_width = 64;
-	}
+	rdev->mc.vram_width = 128;
+
 	rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
 	rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
 
 	rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
 	rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+
+	if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
+		rdev->mc.mc_vram_size = rdev->mc.aper_size;
+
+	if (rdev->mc.real_vram_size > rdev->mc.aper_size)
+		rdev->mc.real_vram_size = rdev->mc.aper_size;
+
 	rs690_pm_info(rdev);
 	/* FIXME: we should enforce default clock in case GPU is not in
 	 * default setup
@@ -161,6 +162,21 @@
 	rdev->pm.core_bandwidth.full = rfixed_div(rdev->pm.sclk, a);
 }
 
+static int rs690_mc_init(struct radeon_device *rdev)
+{
+	int r;
+	u32 tmp;
+
+	/* Setup GPU memory space */
+	tmp = RREG32_MC(R_000100_MCCFG_FB_LOCATION);
+	rdev->mc.vram_location = G_000100_MC_FB_START(tmp) << 16;
+	rdev->mc.gtt_location = 0xFFFFFFFFUL;
+	r = radeon_mc_setup(rdev);
+	if (r)
+		return r;
+	return 0;
+}
+
 void rs690_line_buffer_adjust(struct radeon_device *rdev,
 			      struct drm_display_mode *mode1,
 			      struct drm_display_mode *mode2)
@@ -244,8 +260,9 @@
 
 	b.full = rfixed_const(mode->crtc_hdisplay);
 	c.full = rfixed_const(256);
-	a.full = rfixed_mul(wm->num_line_pair, b);
-	request_fifo_depth.full = rfixed_div(a, c);
+	a.full = rfixed_div(b, c);
+	request_fifo_depth.full = rfixed_mul(a, wm->num_line_pair);
+	request_fifo_depth.full = rfixed_ceil(request_fifo_depth);
 	if (a.full < rfixed_const(4)) {
 		wm->lb_request_fifo_depth = 4;
 	} else {
@@ -374,6 +391,7 @@
 	a.full = rfixed_const(16);
 	wm->priority_mark_max.full = rfixed_const(crtc->base.mode.crtc_hdisplay);
 	wm->priority_mark_max.full = rfixed_div(wm->priority_mark_max, a);
+	wm->priority_mark_max.full = rfixed_ceil(wm->priority_mark_max);
 
 	/* Determine estimated width */
 	estimated_width.full = tolerable_latency.full - wm->worst_case_latency.full;
@@ -383,6 +401,7 @@
 	} else {
 		a.full = rfixed_const(16);
 		wm->priority_mark.full = rfixed_div(estimated_width, a);
+		wm->priority_mark.full = rfixed_ceil(wm->priority_mark);
 		wm->priority_mark.full = wm->priority_mark_max.full - wm->priority_mark.full;
 	}
 }
@@ -605,7 +624,6 @@
 	if (r)
 		return r;
 	/* Enable IRQ */
-	rdev->irq.sw_int = true;
 	rs600_irq_set(rdev);
 	/* 1M ring buffer */
 	r = r100_cp_init(rdev, 1024 * 1024);
@@ -640,6 +658,8 @@
 	atom_asic_init(rdev->mode_info.atom_context);
 	/* Resume clock after posting */
 	rv515_clock_startup(rdev);
+	/* Initialize surface registers */
+	radeon_surface_init(rdev);
 	return rs690_startup(rdev);
 }
 
@@ -662,7 +682,7 @@
 	rs400_gart_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	radeon_fence_driver_fini(rdev);
-	radeon_object_fini(rdev);
+	radeon_bo_fini(rdev);
 	radeon_atombios_fini(rdev);
 	kfree(rdev->bios);
 	rdev->bios = NULL;
@@ -700,10 +720,9 @@
 			RREG32(R_0007C0_CP_STAT));
 	}
 	/* check if cards are posted or not */
-	if (!radeon_card_posted(rdev) && rdev->bios) {
-		DRM_INFO("GPU not posted. posting now...\n");
-		atom_asic_init(rdev->mode_info.atom_context);
-	}
+	if (radeon_boot_test_post_card(rdev) == false)
+		return -EINVAL;
+
 	/* Initialize clocks */
 	radeon_get_clock_info(rdev->ddev);
 	/* Initialize power management */
@@ -711,7 +730,7 @@
 	/* Get vram informations */
 	rs690_vram_info(rdev);
 	/* Initialize memory controller (also test AGP) */
-	r = r420_mc_init(rdev);
+	r = rs690_mc_init(rdev);
 	if (r)
 		return r;
 	rv515_debugfs(rdev);
@@ -723,7 +742,7 @@
 	if (r)
 		return r;
 	/* Memory manager */
-	r = radeon_object_init(rdev);
+	r = radeon_bo_init(rdev);
 	if (r)
 		return r;
 	r = rs400_gart_init(rdev);
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c
index ba68c9f..59632a5 100644
--- a/drivers/gpu/drm/radeon/rv515.c
+++ b/drivers/gpu/drm/radeon/rv515.c
@@ -478,7 +478,6 @@
 			return r;
 	}
 	/* Enable IRQ */
-	rdev->irq.sw_int = true;
 	rs600_irq_set(rdev);
 	/* 1M ring buffer */
 	r = r100_cp_init(rdev, 1024 * 1024);
@@ -514,6 +513,8 @@
 	atom_asic_init(rdev->mode_info.atom_context);
 	/* Resume clock after posting */
 	rv515_clock_startup(rdev);
+	/* Initialize surface registers */
+	radeon_surface_init(rdev);
 	return rv515_startup(rdev);
 }
 
@@ -540,11 +541,11 @@
 	r100_wb_fini(rdev);
 	r100_ib_fini(rdev);
 	radeon_gem_fini(rdev);
-    rv370_pcie_gart_fini(rdev);
+	rv370_pcie_gart_fini(rdev);
 	radeon_agp_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	radeon_fence_driver_fini(rdev);
-	radeon_object_fini(rdev);
+	radeon_bo_fini(rdev);
 	radeon_atombios_fini(rdev);
 	kfree(rdev->bios);
 	rdev->bios = NULL;
@@ -580,10 +581,8 @@
 			RREG32(R_0007C0_CP_STAT));
 	}
 	/* check if cards are posted or not */
-	if (!radeon_card_posted(rdev) && rdev->bios) {
-		DRM_INFO("GPU not posted. posting now...\n");
-		atom_asic_init(rdev->mode_info.atom_context);
-	}
+	if (radeon_boot_test_post_card(rdev) == false)
+		return -EINVAL;
 	/* Initialize clocks */
 	radeon_get_clock_info(rdev->ddev);
 	/* Initialize power management */
@@ -603,7 +602,7 @@
 	if (r)
 		return r;
 	/* Memory manager */
-	r = radeon_object_init(rdev);
+	r = radeon_bo_init(rdev);
 	if (r)
 		return r;
 	r = rv370_pcie_gart_init(rdev);
@@ -892,8 +891,9 @@
 
 	b.full = rfixed_const(mode->crtc_hdisplay);
 	c.full = rfixed_const(256);
-	a.full = rfixed_mul(wm->num_line_pair, b);
-	request_fifo_depth.full = rfixed_div(a, c);
+	a.full = rfixed_div(b, c);
+	request_fifo_depth.full = rfixed_mul(a, wm->num_line_pair);
+	request_fifo_depth.full = rfixed_ceil(request_fifo_depth);
 	if (a.full < rfixed_const(4)) {
 		wm->lb_request_fifo_depth = 4;
 	} else {
@@ -995,15 +995,17 @@
 	a.full = rfixed_const(16);
 	wm->priority_mark_max.full = rfixed_const(crtc->base.mode.crtc_hdisplay);
 	wm->priority_mark_max.full = rfixed_div(wm->priority_mark_max, a);
+	wm->priority_mark_max.full = rfixed_ceil(wm->priority_mark_max);
 
 	/* Determine estimated width */
 	estimated_width.full = tolerable_latency.full - wm->worst_case_latency.full;
 	estimated_width.full = rfixed_div(estimated_width, consumption_time);
 	if (rfixed_trunc(estimated_width) > crtc->base.mode.crtc_hdisplay) {
-		wm->priority_mark.full = rfixed_const(10);
+		wm->priority_mark.full = wm->priority_mark_max.full;
 	} else {
 		a.full = rfixed_const(16);
 		wm->priority_mark.full = rfixed_div(estimated_width, a);
+		wm->priority_mark.full = rfixed_ceil(wm->priority_mark);
 		wm->priority_mark.full = wm->priority_mark_max.full - wm->priority_mark.full;
 	}
 }
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index b0efd0d..fbb0357 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -92,7 +92,7 @@
 void rv770_pcie_gart_disable(struct radeon_device *rdev)
 {
 	u32 tmp;
-	int i;
+	int i, r;
 
 	/* Disable all tables */
 	for (i = 0; i < 7; i++)
@@ -113,8 +113,12 @@
 	WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
 	WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
 	if (rdev->gart.table.vram.robj) {
-		radeon_object_kunmap(rdev->gart.table.vram.robj);
-		radeon_object_unpin(rdev->gart.table.vram.robj);
+		r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
+		if (likely(r == 0)) {
+			radeon_bo_kunmap(rdev->gart.table.vram.robj);
+			radeon_bo_unpin(rdev->gart.table.vram.robj);
+			radeon_bo_unreserve(rdev->gart.table.vram.robj);
+		}
 	}
 }
 
@@ -829,11 +833,11 @@
 		 * AGP so that GPU can catch out of VRAM/AGP access
 		 */
 		if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) {
-			/* Enought place before */
+			/* Enough place before */
 			rdev->mc.vram_location = rdev->mc.gtt_location -
 							rdev->mc.mc_vram_size;
 		} else if (tmp > rdev->mc.mc_vram_size) {
-			/* Enought place after */
+			/* Enough place after */
 			rdev->mc.vram_location = rdev->mc.gtt_location +
 							rdev->mc.gtt_size;
 		} else {
@@ -870,6 +874,14 @@
 {
 	int r;
 
+	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
+		r = r600_init_microcode(rdev);
+		if (r) {
+			DRM_ERROR("Failed to load firmware!\n");
+			return r;
+		}
+	}
+
 	rv770_mc_program(rdev);
 	if (rdev->flags & RADEON_IS_AGP) {
 		rv770_agp_enable(rdev);
@@ -880,13 +892,26 @@
 	}
 	rv770_gpu_init(rdev);
 
-	r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
-			      &rdev->r600_blit.shader_gpu_addr);
+	r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
+	if (unlikely(r != 0))
+		return r;
+	r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
+			&rdev->r600_blit.shader_gpu_addr);
+	radeon_bo_unreserve(rdev->r600_blit.shader_obj);
 	if (r) {
 		DRM_ERROR("failed to pin blit object %d\n", r);
 		return r;
 	}
 
+	/* Enable IRQ */
+	r = r600_irq_init(rdev);
+	if (r) {
+		DRM_ERROR("radeon: IH init failed (%d).\n", r);
+		radeon_irq_kms_fini(rdev);
+		return r;
+	}
+	r600_irq_set(rdev);
+
 	r = radeon_ring_init(rdev, rdev->cp.ring_size);
 	if (r)
 		return r;
@@ -934,13 +959,19 @@
 
 int rv770_suspend(struct radeon_device *rdev)
 {
+	int r;
+
 	/* FIXME: we should wait for ring to be empty */
 	r700_cp_stop(rdev);
 	rdev->cp.ready = false;
 	r600_wb_disable(rdev);
 	rv770_pcie_gart_disable(rdev);
 	/* unpin shaders bo */
-        radeon_object_unpin(rdev->r600_blit.shader_obj);
+	r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
+	if (likely(r == 0)) {
+		radeon_bo_unpin(rdev->r600_blit.shader_obj);
+		radeon_bo_unreserve(rdev->r600_blit.shader_obj);
+	}
 	return 0;
 }
 
@@ -975,7 +1006,11 @@
 	if (r)
 		return r;
 	/* Post card if necessary */
-	if (!r600_card_posted(rdev) && rdev->bios) {
+	if (!r600_card_posted(rdev)) {
+		if (!rdev->bios) {
+			dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
+			return -EINVAL;
+		}
 		DRM_INFO("GPU not posted. posting now...\n");
 		atom_asic_init(rdev->mode_info.atom_context);
 	}
@@ -998,31 +1033,31 @@
 	if (r)
 		return r;
 	/* Memory manager */
-	r = radeon_object_init(rdev);
+	r = radeon_bo_init(rdev);
 	if (r)
 		return r;
+
+	r = radeon_irq_kms_init(rdev);
+	if (r)
+		return r;
+
 	rdev->cp.ring_obj = NULL;
 	r600_ring_init(rdev, 1024 * 1024);
 
-	if (!rdev->me_fw || !rdev->pfp_fw) {
-		r = r600_cp_init_microcode(rdev);
-		if (r) {
-			DRM_ERROR("Failed to load firmware!\n");
-			return r;
-		}
-	}
+	rdev->ih.ring_obj = NULL;
+	r600_ih_ring_init(rdev, 64 * 1024);
 
 	r = r600_pcie_gart_init(rdev);
 	if (r)
 		return r;
 
-	rdev->accel_working = true;
 	r = r600_blit_init(rdev);
 	if (r) {
-		DRM_ERROR("radeon: failled blitter (%d).\n", r);
-		rdev->accel_working = false;
+		DRM_ERROR("radeon: failed blitter (%d).\n", r);
+		return r;
 	}
 
+	rdev->accel_working = true;
 	r = rv770_startup(rdev);
 	if (r) {
 		rv770_suspend(rdev);
@@ -1034,12 +1069,12 @@
 	if (rdev->accel_working) {
 		r = radeon_ib_pool_init(rdev);
 		if (r) {
-			DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r);
+			DRM_ERROR("radeon: failed initializing IB pool (%d).\n", r);
 			rdev->accel_working = false;
 		}
 		r = r600_ib_test(rdev);
 		if (r) {
-			DRM_ERROR("radeon: failled testing IB (%d).\n", r);
+			DRM_ERROR("radeon: failed testing IB (%d).\n", r);
 			rdev->accel_working = false;
 		}
 	}
@@ -1051,6 +1086,8 @@
 	rv770_suspend(rdev);
 
 	r600_blit_fini(rdev);
+	r600_irq_fini(rdev);
+	radeon_irq_kms_fini(rdev);
 	radeon_ring_fini(rdev);
 	r600_wb_fini(rdev);
 	rv770_pcie_gart_fini(rdev);
@@ -1059,7 +1096,7 @@
 	radeon_clocks_fini(rdev);
 	if (rdev->flags & RADEON_IS_AGP)
 		radeon_agp_fini(rdev);
-	radeon_object_fini(rdev);
+	radeon_bo_fini(rdev);
 	radeon_atombios_fini(rdev);
 	kfree(rdev->bios);
 	rdev->bios = NULL;
diff --git a/drivers/gpu/drm/ttm/Makefile b/drivers/gpu/drm/ttm/Makefile
index b0a9de7..1e138f5 100644
--- a/drivers/gpu/drm/ttm/Makefile
+++ b/drivers/gpu/drm/ttm/Makefile
@@ -3,6 +3,7 @@
 
 ccflags-y := -Iinclude/drm
 ttm-y := ttm_agp_backend.o ttm_memory.o ttm_tt.o ttm_bo.o \
-	ttm_bo_util.o ttm_bo_vm.o ttm_module.o ttm_global.o
+	ttm_bo_util.o ttm_bo_vm.o ttm_module.o ttm_global.o \
+	ttm_object.o ttm_lock.o ttm_execbuf_util.o
 
 obj-$(CONFIG_DRM_TTM) += ttm.o
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 87c0625..1fbb2ee 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -27,6 +27,14 @@
 /*
  * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
  */
+/* Notes:
+ *
+ * We store bo pointer in drm_mm_node struct so we know which bo own a
+ * specific node. There is no protection on the pointer, thus to make
+ * sure things don't go berserk you have to access this pointer while
+ * holding the global lru lock and make sure anytime you free a node you
+ * reset the pointer to NULL.
+ */
 
 #include "ttm/ttm_module.h"
 #include "ttm/ttm_bo_driver.h"
@@ -51,6 +59,60 @@
 	.mode = S_IRUGO
 };
 
+static inline int ttm_mem_type_from_flags(uint32_t flags, uint32_t *mem_type)
+{
+	int i;
+
+	for (i = 0; i <= TTM_PL_PRIV5; i++)
+		if (flags & (1 << i)) {
+			*mem_type = i;
+			return 0;
+		}
+	return -EINVAL;
+}
+
+static void ttm_mem_type_manager_debug(struct ttm_bo_global *glob,
+					struct ttm_mem_type_manager *man)
+{
+	printk(KERN_ERR TTM_PFX "    has_type: %d\n", man->has_type);
+	printk(KERN_ERR TTM_PFX "    use_type: %d\n", man->use_type);
+	printk(KERN_ERR TTM_PFX "    flags: 0x%08X\n", man->flags);
+	printk(KERN_ERR TTM_PFX "    gpu_offset: 0x%08lX\n", man->gpu_offset);
+	printk(KERN_ERR TTM_PFX "    io_offset: 0x%08lX\n", man->io_offset);
+	printk(KERN_ERR TTM_PFX "    io_size: %ld\n", man->io_size);
+	printk(KERN_ERR TTM_PFX "    size: %ld\n", (unsigned long)man->size);
+	printk(KERN_ERR TTM_PFX "    available_caching: 0x%08X\n",
+		man->available_caching);
+	printk(KERN_ERR TTM_PFX "    default_caching: 0x%08X\n",
+		man->default_caching);
+	spin_lock(&glob->lru_lock);
+	drm_mm_debug_table(&man->manager, TTM_PFX);
+	spin_unlock(&glob->lru_lock);
+}
+
+static void ttm_bo_mem_space_debug(struct ttm_buffer_object *bo,
+					struct ttm_placement *placement)
+{
+	struct ttm_bo_device *bdev = bo->bdev;
+	struct ttm_bo_global *glob = bo->glob;
+	struct ttm_mem_type_manager *man;
+	int i, ret, mem_type;
+
+	printk(KERN_ERR TTM_PFX "No space for %p (%ld pages, %ldK, %ldM)\n",
+		bo, bo->mem.num_pages, bo->mem.size >> 10,
+		bo->mem.size >> 20);
+	for (i = 0; i < placement->num_placement; i++) {
+		ret = ttm_mem_type_from_flags(placement->placement[i],
+						&mem_type);
+		if (ret)
+			return;
+		man = &bdev->man[mem_type];
+		printk(KERN_ERR TTM_PFX "  placement[%d]=0x%08X (%d)\n",
+			i, placement->placement[i], mem_type);
+		ttm_mem_type_manager_debug(glob, man);
+	}
+}
+
 static ssize_t ttm_bo_global_show(struct kobject *kobj,
 				  struct attribute *attr,
 				  char *buffer)
@@ -117,12 +179,13 @@
 		ret = wait_event_interruptible(bo->event_queue,
 					       atomic_read(&bo->reserved) == 0);
 		if (unlikely(ret != 0))
-			return -ERESTART;
+			return ret;
 	} else {
 		wait_event(bo->event_queue, atomic_read(&bo->reserved) == 0);
 	}
 	return 0;
 }
+EXPORT_SYMBOL(ttm_bo_wait_unreserved);
 
 static void ttm_bo_add_to_lru(struct ttm_buffer_object *bo)
 {
@@ -247,7 +310,6 @@
 /*
  * Call bo->mutex locked.
  */
-
 static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, bool zero_alloc)
 {
 	struct ttm_bo_device *bdev = bo->bdev;
@@ -275,9 +337,10 @@
 		bo->ttm = ttm_tt_create(bdev, bo->num_pages << PAGE_SHIFT,
 					page_flags | TTM_PAGE_FLAG_USER,
 					glob->dummy_read_page);
-		if (unlikely(bo->ttm == NULL))
+		if (unlikely(bo->ttm == NULL)) {
 			ret = -ENOMEM;
-		break;
+			break;
+		}
 
 		ret = ttm_tt_set_user(bo->ttm, current,
 				      bo->buffer_start, bo->num_pages);
@@ -328,14 +391,8 @@
 		}
 
 		if (bo->mem.mem_type == TTM_PL_SYSTEM) {
-
-			struct ttm_mem_reg *old_mem = &bo->mem;
-			uint32_t save_flags = old_mem->placement;
-
-			*old_mem = *mem;
+			bo->mem = *mem;
 			mem->mm_node = NULL;
-			ttm_flag_masked(&save_flags, mem->placement,
-					TTM_PL_MASK_MEMTYPE);
 			goto moved;
 		}
 
@@ -418,6 +475,7 @@
 			kref_put(&bo->list_kref, ttm_bo_ref_bug);
 		}
 		if (bo->mem.mm_node) {
+			bo->mem.mm_node->private = NULL;
 			drm_mm_put_block(bo->mem.mm_node);
 			bo->mem.mm_node = NULL;
 		}
@@ -554,24 +612,21 @@
 }
 EXPORT_SYMBOL(ttm_bo_unref);
 
-static int ttm_bo_evict(struct ttm_buffer_object *bo, unsigned mem_type,
-			bool interruptible, bool no_wait)
+static int ttm_bo_evict(struct ttm_buffer_object *bo, bool interruptible,
+			bool no_wait)
 {
-	int ret = 0;
 	struct ttm_bo_device *bdev = bo->bdev;
 	struct ttm_bo_global *glob = bo->glob;
 	struct ttm_mem_reg evict_mem;
-	uint32_t proposed_placement;
-
-	if (bo->mem.mem_type != mem_type)
-		goto out;
+	struct ttm_placement placement;
+	int ret = 0;
 
 	spin_lock(&bo->lock);
 	ret = ttm_bo_wait(bo, false, interruptible, no_wait);
 	spin_unlock(&bo->lock);
 
 	if (unlikely(ret != 0)) {
-		if (ret != -ERESTART) {
+		if (ret != -ERESTARTSYS) {
 			printk(KERN_ERR TTM_PFX
 			       "Failed to expire sync object before "
 			       "buffer eviction.\n");
@@ -584,116 +639,139 @@
 	evict_mem = bo->mem;
 	evict_mem.mm_node = NULL;
 
-	proposed_placement = bdev->driver->evict_flags(bo);
-
-	ret = ttm_bo_mem_space(bo, proposed_placement,
-			       &evict_mem, interruptible, no_wait);
-	if (unlikely(ret != 0 && ret != -ERESTART))
-		ret = ttm_bo_mem_space(bo, TTM_PL_FLAG_SYSTEM,
-				       &evict_mem, interruptible, no_wait);
-
+	placement.fpfn = 0;
+	placement.lpfn = 0;
+	placement.num_placement = 0;
+	placement.num_busy_placement = 0;
+	bdev->driver->evict_flags(bo, &placement);
+	ret = ttm_bo_mem_space(bo, &placement, &evict_mem, interruptible,
+				no_wait);
 	if (ret) {
-		if (ret != -ERESTART)
+		if (ret != -ERESTARTSYS) {
 			printk(KERN_ERR TTM_PFX
 			       "Failed to find memory space for "
 			       "buffer 0x%p eviction.\n", bo);
+			ttm_bo_mem_space_debug(bo, &placement);
+		}
 		goto out;
 	}
 
 	ret = ttm_bo_handle_move_mem(bo, &evict_mem, true, interruptible,
 				     no_wait);
 	if (ret) {
-		if (ret != -ERESTART)
+		if (ret != -ERESTARTSYS)
 			printk(KERN_ERR TTM_PFX "Buffer eviction failed\n");
+		spin_lock(&glob->lru_lock);
+		if (evict_mem.mm_node) {
+			evict_mem.mm_node->private = NULL;
+			drm_mm_put_block(evict_mem.mm_node);
+			evict_mem.mm_node = NULL;
+		}
+		spin_unlock(&glob->lru_lock);
 		goto out;
 	}
-
-	spin_lock(&glob->lru_lock);
-	if (evict_mem.mm_node) {
-		drm_mm_put_block(evict_mem.mm_node);
-		evict_mem.mm_node = NULL;
-	}
-	spin_unlock(&glob->lru_lock);
 	bo->evicted = true;
 out:
 	return ret;
 }
 
+static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
+				uint32_t mem_type,
+				bool interruptible, bool no_wait)
+{
+	struct ttm_bo_global *glob = bdev->glob;
+	struct ttm_mem_type_manager *man = &bdev->man[mem_type];
+	struct ttm_buffer_object *bo;
+	int ret, put_count = 0;
+
+	spin_lock(&glob->lru_lock);
+	bo = list_first_entry(&man->lru, struct ttm_buffer_object, lru);
+	kref_get(&bo->list_kref);
+	ret = ttm_bo_reserve_locked(bo, interruptible, no_wait, false, 0);
+	if (likely(ret == 0))
+		put_count = ttm_bo_del_from_lru(bo);
+	spin_unlock(&glob->lru_lock);
+	if (unlikely(ret != 0))
+		return ret;
+	while (put_count--)
+		kref_put(&bo->list_kref, ttm_bo_ref_bug);
+	ret = ttm_bo_evict(bo, interruptible, no_wait);
+	ttm_bo_unreserve(bo);
+	kref_put(&bo->list_kref, ttm_bo_release_list);
+	return ret;
+}
+
+static int ttm_bo_man_get_node(struct ttm_buffer_object *bo,
+				struct ttm_mem_type_manager *man,
+				struct ttm_placement *placement,
+				struct ttm_mem_reg *mem,
+				struct drm_mm_node **node)
+{
+	struct ttm_bo_global *glob = bo->glob;
+	unsigned long lpfn;
+	int ret;
+
+	lpfn = placement->lpfn;
+	if (!lpfn)
+		lpfn = man->size;
+	*node = NULL;
+	do {
+		ret = drm_mm_pre_get(&man->manager);
+		if (unlikely(ret))
+			return ret;
+
+		spin_lock(&glob->lru_lock);
+		*node = drm_mm_search_free_in_range(&man->manager,
+					mem->num_pages, mem->page_alignment,
+					placement->fpfn, lpfn, 1);
+		if (unlikely(*node == NULL)) {
+			spin_unlock(&glob->lru_lock);
+			return 0;
+		}
+		*node = drm_mm_get_block_atomic_range(*node, mem->num_pages,
+							mem->page_alignment,
+							placement->fpfn,
+							lpfn);
+		spin_unlock(&glob->lru_lock);
+	} while (*node == NULL);
+	return 0;
+}
+
 /**
  * Repeatedly evict memory from the LRU for @mem_type until we create enough
  * space, or we've evicted everything and there isn't enough space.
  */
-static int ttm_bo_mem_force_space(struct ttm_bo_device *bdev,
-				  struct ttm_mem_reg *mem,
-				  uint32_t mem_type,
-				  bool interruptible, bool no_wait)
+static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo,
+					uint32_t mem_type,
+					struct ttm_placement *placement,
+					struct ttm_mem_reg *mem,
+					bool interruptible, bool no_wait)
 {
+	struct ttm_bo_device *bdev = bo->bdev;
 	struct ttm_bo_global *glob = bdev->glob;
-	struct drm_mm_node *node;
-	struct ttm_buffer_object *entry;
 	struct ttm_mem_type_manager *man = &bdev->man[mem_type];
-	struct list_head *lru;
-	unsigned long num_pages = mem->num_pages;
-	int put_count = 0;
+	struct drm_mm_node *node;
 	int ret;
 
-retry_pre_get:
-	ret = drm_mm_pre_get(&man->manager);
-	if (unlikely(ret != 0))
-		return ret;
-
-	spin_lock(&glob->lru_lock);
 	do {
-		node = drm_mm_search_free(&man->manager, num_pages,
-					  mem->page_alignment, 1);
-		if (node)
-			break;
-
-		lru = &man->lru;
-		if (list_empty(lru))
-			break;
-
-		entry = list_first_entry(lru, struct ttm_buffer_object, lru);
-		kref_get(&entry->list_kref);
-
-		ret =
-		    ttm_bo_reserve_locked(entry, interruptible, no_wait,
-					  false, 0);
-
-		if (likely(ret == 0))
-			put_count = ttm_bo_del_from_lru(entry);
-
-		spin_unlock(&glob->lru_lock);
-
+		ret = ttm_bo_man_get_node(bo, man, placement, mem, &node);
 		if (unlikely(ret != 0))
 			return ret;
-
-		while (put_count--)
-			kref_put(&entry->list_kref, ttm_bo_ref_bug);
-
-		ret = ttm_bo_evict(entry, mem_type, interruptible, no_wait);
-
-		ttm_bo_unreserve(entry);
-
-		kref_put(&entry->list_kref, ttm_bo_release_list);
-		if (ret)
-			return ret;
-
+		if (node)
+			break;
 		spin_lock(&glob->lru_lock);
+		if (list_empty(&man->lru)) {
+			spin_unlock(&glob->lru_lock);
+			break;
+		}
+		spin_unlock(&glob->lru_lock);
+		ret = ttm_mem_evict_first(bdev, mem_type, interruptible,
+						no_wait);
+		if (unlikely(ret != 0))
+			return ret;
 	} while (1);
-
-	if (!node) {
-		spin_unlock(&glob->lru_lock);
+	if (node == NULL)
 		return -ENOMEM;
-	}
-
-	node = drm_mm_get_block_atomic(node, num_pages, mem->page_alignment);
-	if (unlikely(!node)) {
-		spin_unlock(&glob->lru_lock);
-		goto retry_pre_get;
-	}
-
-	spin_unlock(&glob->lru_lock);
 	mem->mm_node = node;
 	mem->mem_type = mem_type;
 	return 0;
@@ -724,7 +802,6 @@
 	return result;
 }
 
-
 static bool ttm_bo_mt_compatible(struct ttm_mem_type_manager *man,
 				 bool disallow_fixed,
 				 uint32_t mem_type,
@@ -757,66 +834,55 @@
  * space.
  */
 int ttm_bo_mem_space(struct ttm_buffer_object *bo,
-		     uint32_t proposed_placement,
-		     struct ttm_mem_reg *mem,
-		     bool interruptible, bool no_wait)
+			struct ttm_placement *placement,
+			struct ttm_mem_reg *mem,
+			bool interruptible, bool no_wait)
 {
 	struct ttm_bo_device *bdev = bo->bdev;
-	struct ttm_bo_global *glob = bo->glob;
 	struct ttm_mem_type_manager *man;
-
-	uint32_t num_prios = bdev->driver->num_mem_type_prio;
-	const uint32_t *prios = bdev->driver->mem_type_prio;
-	uint32_t i;
 	uint32_t mem_type = TTM_PL_SYSTEM;
 	uint32_t cur_flags = 0;
 	bool type_found = false;
 	bool type_ok = false;
-	bool has_eagain = false;
+	bool has_erestartsys = false;
 	struct drm_mm_node *node = NULL;
-	int ret;
+	int i, ret;
 
 	mem->mm_node = NULL;
-	for (i = 0; i < num_prios; ++i) {
-		mem_type = prios[i];
+	for (i = 0; i <= placement->num_placement; ++i) {
+		ret = ttm_mem_type_from_flags(placement->placement[i],
+						&mem_type);
+		if (ret)
+			return ret;
 		man = &bdev->man[mem_type];
 
 		type_ok = ttm_bo_mt_compatible(man,
-					       bo->type == ttm_bo_type_user,
-					       mem_type, proposed_placement,
-					       &cur_flags);
+						bo->type == ttm_bo_type_user,
+						mem_type,
+						placement->placement[i],
+						&cur_flags);
 
 		if (!type_ok)
 			continue;
 
 		cur_flags = ttm_bo_select_caching(man, bo->mem.placement,
 						  cur_flags);
+		/*
+		 * Use the access and other non-mapping-related flag bits from
+		 * the memory placement flags to the current flags
+		 */
+		ttm_flag_masked(&cur_flags, placement->placement[i],
+				~TTM_PL_MASK_MEMTYPE);
 
 		if (mem_type == TTM_PL_SYSTEM)
 			break;
 
 		if (man->has_type && man->use_type) {
 			type_found = true;
-			do {
-				ret = drm_mm_pre_get(&man->manager);
-				if (unlikely(ret))
-					return ret;
-
-				spin_lock(&glob->lru_lock);
-				node = drm_mm_search_free(&man->manager,
-							  mem->num_pages,
-							  mem->page_alignment,
-							  1);
-				if (unlikely(!node)) {
-					spin_unlock(&glob->lru_lock);
-					break;
-				}
-				node = drm_mm_get_block_atomic(node,
-							       mem->num_pages,
-							       mem->
-							       page_alignment);
-				spin_unlock(&glob->lru_lock);
-			} while (!node);
+			ret = ttm_bo_man_get_node(bo, man, placement, mem,
+							&node);
+			if (unlikely(ret))
+				return ret;
 		}
 		if (node)
 			break;
@@ -826,67 +892,66 @@
 		mem->mm_node = node;
 		mem->mem_type = mem_type;
 		mem->placement = cur_flags;
+		if (node)
+			node->private = bo;
 		return 0;
 	}
 
 	if (!type_found)
 		return -EINVAL;
 
-	num_prios = bdev->driver->num_mem_busy_prio;
-	prios = bdev->driver->mem_busy_prio;
-
-	for (i = 0; i < num_prios; ++i) {
-		mem_type = prios[i];
+	for (i = 0; i <= placement->num_busy_placement; ++i) {
+		ret = ttm_mem_type_from_flags(placement->placement[i],
+						&mem_type);
+		if (ret)
+			return ret;
 		man = &bdev->man[mem_type];
-
 		if (!man->has_type)
 			continue;
-
 		if (!ttm_bo_mt_compatible(man,
-					  bo->type == ttm_bo_type_user,
-					  mem_type,
-					  proposed_placement, &cur_flags))
+						bo->type == ttm_bo_type_user,
+						mem_type,
+						placement->placement[i],
+						&cur_flags))
 			continue;
 
 		cur_flags = ttm_bo_select_caching(man, bo->mem.placement,
 						  cur_flags);
+		/*
+		 * Use the access and other non-mapping-related flag bits from
+		 * the memory placement flags to the current flags
+		 */
+		ttm_flag_masked(&cur_flags, placement->placement[i],
+				~TTM_PL_MASK_MEMTYPE);
 
-		ret = ttm_bo_mem_force_space(bdev, mem, mem_type,
-					     interruptible, no_wait);
-
+		ret = ttm_bo_mem_force_space(bo, mem_type, placement, mem,
+						interruptible, no_wait);
 		if (ret == 0 && mem->mm_node) {
 			mem->placement = cur_flags;
+			mem->mm_node->private = bo;
 			return 0;
 		}
-
-		if (ret == -ERESTART)
-			has_eagain = true;
+		if (ret == -ERESTARTSYS)
+			has_erestartsys = true;
 	}
-
-	ret = (has_eagain) ? -ERESTART : -ENOMEM;
+	ret = (has_erestartsys) ? -ERESTARTSYS : -ENOMEM;
 	return ret;
 }
 EXPORT_SYMBOL(ttm_bo_mem_space);
 
 int ttm_bo_wait_cpu(struct ttm_buffer_object *bo, bool no_wait)
 {
-	int ret = 0;
-
 	if ((atomic_read(&bo->cpu_writers) > 0) && no_wait)
 		return -EBUSY;
 
-	ret = wait_event_interruptible(bo->event_queue,
-				       atomic_read(&bo->cpu_writers) == 0);
-
-	if (ret == -ERESTARTSYS)
-		ret = -ERESTART;
-
-	return ret;
+	return wait_event_interruptible(bo->event_queue,
+					atomic_read(&bo->cpu_writers) == 0);
 }
+EXPORT_SYMBOL(ttm_bo_wait_cpu);
 
 int ttm_bo_move_buffer(struct ttm_buffer_object *bo,
-		       uint32_t proposed_placement,
-		       bool interruptible, bool no_wait)
+			struct ttm_placement *placement,
+			bool interruptible, bool no_wait)
 {
 	struct ttm_bo_global *glob = bo->glob;
 	int ret = 0;
@@ -899,147 +964,132 @@
 	 * Have the driver move function wait for idle when necessary,
 	 * instead of doing it here.
 	 */
-
 	spin_lock(&bo->lock);
 	ret = ttm_bo_wait(bo, false, interruptible, no_wait);
 	spin_unlock(&bo->lock);
-
 	if (ret)
 		return ret;
-
 	mem.num_pages = bo->num_pages;
 	mem.size = mem.num_pages << PAGE_SHIFT;
 	mem.page_alignment = bo->mem.page_alignment;
-
 	/*
 	 * Determine where to move the buffer.
 	 */
-
-	ret = ttm_bo_mem_space(bo, proposed_placement, &mem,
-			       interruptible, no_wait);
+	ret = ttm_bo_mem_space(bo, placement, &mem, interruptible, no_wait);
 	if (ret)
 		goto out_unlock;
-
 	ret = ttm_bo_handle_move_mem(bo, &mem, false, interruptible, no_wait);
-
 out_unlock:
 	if (ret && mem.mm_node) {
 		spin_lock(&glob->lru_lock);
+		mem.mm_node->private = NULL;
 		drm_mm_put_block(mem.mm_node);
 		spin_unlock(&glob->lru_lock);
 	}
 	return ret;
 }
 
-static int ttm_bo_mem_compat(uint32_t proposed_placement,
+static int ttm_bo_mem_compat(struct ttm_placement *placement,
 			     struct ttm_mem_reg *mem)
 {
-	if ((proposed_placement & mem->placement & TTM_PL_MASK_MEM) == 0)
-		return 0;
-	if ((proposed_placement & mem->placement & TTM_PL_MASK_CACHING) == 0)
-		return 0;
+	int i;
 
-	return 1;
+	for (i = 0; i < placement->num_placement; i++) {
+		if ((placement->placement[i] & mem->placement &
+			TTM_PL_MASK_CACHING) &&
+			(placement->placement[i] & mem->placement &
+			TTM_PL_MASK_MEM))
+			return i;
+	}
+	return -1;
 }
 
-int ttm_buffer_object_validate(struct ttm_buffer_object *bo,
-			       uint32_t proposed_placement,
-			       bool interruptible, bool no_wait)
+int ttm_bo_validate(struct ttm_buffer_object *bo,
+			struct ttm_placement *placement,
+			bool interruptible, bool no_wait)
 {
 	int ret;
 
 	BUG_ON(!atomic_read(&bo->reserved));
-	bo->proposed_placement = proposed_placement;
-
-	TTM_DEBUG("Proposed placement 0x%08lx, Old flags 0x%08lx\n",
-		  (unsigned long)proposed_placement,
-		  (unsigned long)bo->mem.placement);
-
+	/* Check that range is valid */
+	if (placement->lpfn || placement->fpfn)
+		if (placement->fpfn > placement->lpfn ||
+			(placement->lpfn - placement->fpfn) < bo->num_pages)
+			return -EINVAL;
 	/*
 	 * Check whether we need to move buffer.
 	 */
-
-	if (!ttm_bo_mem_compat(bo->proposed_placement, &bo->mem)) {
-		ret = ttm_bo_move_buffer(bo, bo->proposed_placement,
-					 interruptible, no_wait);
-		if (ret) {
-			if (ret != -ERESTART)
-				printk(KERN_ERR TTM_PFX
-				       "Failed moving buffer. "
-				       "Proposed placement 0x%08x\n",
-				       bo->proposed_placement);
-			if (ret == -ENOMEM)
-				printk(KERN_ERR TTM_PFX
-				       "Out of aperture space or "
-				       "DRM memory quota.\n");
+	ret = ttm_bo_mem_compat(placement, &bo->mem);
+	if (ret < 0) {
+		ret = ttm_bo_move_buffer(bo, placement, interruptible, no_wait);
+		if (ret)
 			return ret;
-		}
+	} else {
+		/*
+		 * Use the access and other non-mapping-related flag bits from
+		 * the compatible memory placement flags to the active flags
+		 */
+		ttm_flag_masked(&bo->mem.placement, placement->placement[ret],
+				~TTM_PL_MASK_MEMTYPE);
 	}
-
 	/*
 	 * We might need to add a TTM.
 	 */
-
 	if (bo->mem.mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) {
 		ret = ttm_bo_add_ttm(bo, true);
 		if (ret)
 			return ret;
 	}
-	/*
-	 * Validation has succeeded, move the access and other
-	 * non-mapping-related flag bits from the proposed flags to
-	 * the active flags
-	 */
-
-	ttm_flag_masked(&bo->mem.placement, bo->proposed_placement,
-			~TTM_PL_MASK_MEMTYPE);
-
 	return 0;
 }
-EXPORT_SYMBOL(ttm_buffer_object_validate);
+EXPORT_SYMBOL(ttm_bo_validate);
 
-int
-ttm_bo_check_placement(struct ttm_buffer_object *bo,
-		       uint32_t set_flags, uint32_t clr_flags)
+int ttm_bo_check_placement(struct ttm_buffer_object *bo,
+				struct ttm_placement *placement)
 {
-	uint32_t new_mask = set_flags | clr_flags;
+	int i;
 
-	if ((bo->type == ttm_bo_type_user) &&
-	    (clr_flags & TTM_PL_FLAG_CACHED)) {
-		printk(KERN_ERR TTM_PFX
-		       "User buffers require cache-coherent memory.\n");
-		return -EINVAL;
-	}
-
-	if (!capable(CAP_SYS_ADMIN)) {
-		if (new_mask & TTM_PL_FLAG_NO_EVICT) {
-			printk(KERN_ERR TTM_PFX "Need to be root to modify"
-			       " NO_EVICT status.\n");
+	if (placement->fpfn || placement->lpfn) {
+		if (bo->mem.num_pages > (placement->lpfn - placement->fpfn)) {
+			printk(KERN_ERR TTM_PFX "Page number range to small "
+				"Need %lu pages, range is [%u, %u]\n",
+				bo->mem.num_pages, placement->fpfn,
+				placement->lpfn);
 			return -EINVAL;
 		}
-
-		if ((clr_flags & bo->mem.placement & TTM_PL_MASK_MEMTYPE) &&
-		    (bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) {
-			printk(KERN_ERR TTM_PFX
-			       "Incompatible memory specification"
-			       " for NO_EVICT buffer.\n");
-			return -EINVAL;
+	}
+	for (i = 0; i < placement->num_placement; i++) {
+		if (!capable(CAP_SYS_ADMIN)) {
+			if (placement->placement[i] & TTM_PL_FLAG_NO_EVICT) {
+				printk(KERN_ERR TTM_PFX "Need to be root to "
+					"modify NO_EVICT status.\n");
+				return -EINVAL;
+			}
+		}
+	}
+	for (i = 0; i < placement->num_busy_placement; i++) {
+		if (!capable(CAP_SYS_ADMIN)) {
+			if (placement->busy_placement[i] & TTM_PL_FLAG_NO_EVICT) {
+				printk(KERN_ERR TTM_PFX "Need to be root to "
+					"modify NO_EVICT status.\n");
+				return -EINVAL;
+			}
 		}
 	}
 	return 0;
 }
 
-int ttm_buffer_object_init(struct ttm_bo_device *bdev,
-			   struct ttm_buffer_object *bo,
-			   unsigned long size,
-			   enum ttm_bo_type type,
-			   uint32_t flags,
-			   uint32_t page_alignment,
-			   unsigned long buffer_start,
-			   bool interruptible,
-			   struct file *persistant_swap_storage,
-			   size_t acc_size,
-			   void (*destroy) (struct ttm_buffer_object *))
+int ttm_bo_init(struct ttm_bo_device *bdev,
+		struct ttm_buffer_object *bo,
+		unsigned long size,
+		enum ttm_bo_type type,
+		struct ttm_placement *placement,
+		uint32_t page_alignment,
+		unsigned long buffer_start,
+		bool interruptible,
+		struct file *persistant_swap_storage,
+		size_t acc_size,
+		void (*destroy) (struct ttm_buffer_object *))
 {
 	int ret = 0;
 	unsigned long num_pages;
@@ -1077,29 +1127,21 @@
 	bo->acc_size = acc_size;
 	atomic_inc(&bo->glob->bo_count);
 
-	ret = ttm_bo_check_placement(bo, flags, 0ULL);
+	ret = ttm_bo_check_placement(bo, placement);
 	if (unlikely(ret != 0))
 		goto out_err;
 
 	/*
-	 * If no caching attributes are set, accept any form of caching.
-	 */
-
-	if ((flags & TTM_PL_MASK_CACHING) == 0)
-		flags |= TTM_PL_MASK_CACHING;
-
-	/*
 	 * For ttm_bo_type_device buffers, allocate
 	 * address space from the device.
 	 */
-
 	if (bo->type == ttm_bo_type_device) {
 		ret = ttm_bo_setup_vm(bo);
 		if (ret)
 			goto out_err;
 	}
 
-	ret = ttm_buffer_object_validate(bo, flags, interruptible, false);
+	ret = ttm_bo_validate(bo, placement, interruptible, false);
 	if (ret)
 		goto out_err;
 
@@ -1112,7 +1154,7 @@
 
 	return ret;
 }
-EXPORT_SYMBOL(ttm_buffer_object_init);
+EXPORT_SYMBOL(ttm_bo_init);
 
 static inline size_t ttm_bo_size(struct ttm_bo_global *glob,
 				 unsigned long num_pages)
@@ -1123,19 +1165,19 @@
 	return glob->ttm_bo_size + 2 * page_array_size;
 }
 
-int ttm_buffer_object_create(struct ttm_bo_device *bdev,
-			     unsigned long size,
-			     enum ttm_bo_type type,
-			     uint32_t flags,
-			     uint32_t page_alignment,
-			     unsigned long buffer_start,
-			     bool interruptible,
-			     struct file *persistant_swap_storage,
-			     struct ttm_buffer_object **p_bo)
+int ttm_bo_create(struct ttm_bo_device *bdev,
+			unsigned long size,
+			enum ttm_bo_type type,
+			struct ttm_placement *placement,
+			uint32_t page_alignment,
+			unsigned long buffer_start,
+			bool interruptible,
+			struct file *persistant_swap_storage,
+			struct ttm_buffer_object **p_bo)
 {
 	struct ttm_buffer_object *bo;
-	int ret;
 	struct ttm_mem_global *mem_glob = bdev->glob->mem_glob;
+	int ret;
 
 	size_t acc_size =
 	    ttm_bo_size(bdev->glob, (size + PAGE_SIZE - 1) >> PAGE_SHIFT);
@@ -1150,76 +1192,41 @@
 		return -ENOMEM;
 	}
 
-	ret = ttm_buffer_object_init(bdev, bo, size, type, flags,
-				     page_alignment, buffer_start,
-				     interruptible,
-				     persistant_swap_storage, acc_size, NULL);
+	ret = ttm_bo_init(bdev, bo, size, type, placement, page_alignment,
+				buffer_start, interruptible,
+				persistant_swap_storage, acc_size, NULL);
 	if (likely(ret == 0))
 		*p_bo = bo;
 
 	return ret;
 }
 
-static int ttm_bo_leave_list(struct ttm_buffer_object *bo,
-			     uint32_t mem_type, bool allow_errors)
-{
-	int ret;
-
-	spin_lock(&bo->lock);
-	ret = ttm_bo_wait(bo, false, false, false);
-	spin_unlock(&bo->lock);
-
-	if (ret && allow_errors)
-		goto out;
-
-	if (bo->mem.mem_type == mem_type)
-		ret = ttm_bo_evict(bo, mem_type, false, false);
-
-	if (ret) {
-		if (allow_errors) {
-			goto out;
-		} else {
-			ret = 0;
-			printk(KERN_ERR TTM_PFX "Cleanup eviction failed\n");
-		}
-	}
-
-out:
-	return ret;
-}
-
 static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev,
-				   struct list_head *head,
-				   unsigned mem_type, bool allow_errors)
+					unsigned mem_type, bool allow_errors)
 {
+	struct ttm_mem_type_manager *man = &bdev->man[mem_type];
 	struct ttm_bo_global *glob = bdev->glob;
-	struct ttm_buffer_object *entry;
 	int ret;
-	int put_count;
 
 	/*
 	 * Can't use standard list traversal since we're unlocking.
 	 */
 
 	spin_lock(&glob->lru_lock);
-
-	while (!list_empty(head)) {
-		entry = list_first_entry(head, struct ttm_buffer_object, lru);
-		kref_get(&entry->list_kref);
-		ret = ttm_bo_reserve_locked(entry, false, false, false, 0);
-		put_count = ttm_bo_del_from_lru(entry);
+	while (!list_empty(&man->lru)) {
 		spin_unlock(&glob->lru_lock);
-		while (put_count--)
-			kref_put(&entry->list_kref, ttm_bo_ref_bug);
-		BUG_ON(ret);
-		ret = ttm_bo_leave_list(entry, mem_type, allow_errors);
-		ttm_bo_unreserve(entry);
-		kref_put(&entry->list_kref, ttm_bo_release_list);
+		ret = ttm_mem_evict_first(bdev, mem_type, false, false);
+		if (ret) {
+			if (allow_errors) {
+				return ret;
+			} else {
+				printk(KERN_ERR TTM_PFX
+					"Cleanup eviction failed\n");
+			}
+		}
 		spin_lock(&glob->lru_lock);
 	}
-
 	spin_unlock(&glob->lru_lock);
-
 	return 0;
 }
 
@@ -1246,7 +1253,7 @@
 
 	ret = 0;
 	if (mem_type > 0) {
-		ttm_bo_force_list_clean(bdev, &man->lru, mem_type, false);
+		ttm_bo_force_list_clean(bdev, mem_type, false);
 
 		spin_lock(&glob->lru_lock);
 		if (drm_mm_clean(&man->manager))
@@ -1279,12 +1286,12 @@
 		return 0;
 	}
 
-	return ttm_bo_force_list_clean(bdev, &man->lru, mem_type, true);
+	return ttm_bo_force_list_clean(bdev, mem_type, true);
 }
 EXPORT_SYMBOL(ttm_bo_evict_mm);
 
 int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type,
-		   unsigned long p_offset, unsigned long p_size)
+			unsigned long p_size)
 {
 	int ret = -EINVAL;
 	struct ttm_mem_type_manager *man;
@@ -1314,7 +1321,7 @@
 			       type);
 			return ret;
 		}
-		ret = drm_mm_init(&man->manager, p_offset, p_size);
+		ret = drm_mm_init(&man->manager, 0, p_size);
 		if (ret)
 			return ret;
 	}
@@ -1463,7 +1470,7 @@
 	 * Initialize the system memory buffer type.
 	 * Other types need to be driver / IOCTL initialized.
 	 */
-	ret = ttm_bo_init_mm(bdev, TTM_PL_SYSTEM, 0, 0);
+	ret = ttm_bo_init_mm(bdev, TTM_PL_SYSTEM, 0);
 	if (unlikely(ret != 0))
 		goto out_no_sys;
 
@@ -1693,7 +1700,7 @@
 			ret = wait_event_interruptible
 			    (bo->event_queue, atomic_read(&bo->reserved) == 0);
 			if (unlikely(ret != 0))
-				return -ERESTART;
+				return ret;
 		} else {
 			wait_event(bo->event_queue,
 				   atomic_read(&bo->reserved) == 0);
@@ -1722,12 +1729,14 @@
 	ttm_bo_unreserve(bo);
 	return ret;
 }
+EXPORT_SYMBOL(ttm_bo_synccpu_write_grab);
 
 void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo)
 {
 	if (atomic_dec_and_test(&bo->cpu_writers))
 		wake_up_all(&bo->event_queue);
 }
+EXPORT_SYMBOL(ttm_bo_synccpu_write_release);
 
 /**
  * A buffer object shrink method that tries to swap out the first
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c
index c70927e..2ecf7d0 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_util.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
@@ -369,6 +369,7 @@
 #endif
 	return tmp;
 }
+EXPORT_SYMBOL(ttm_io_prot);
 
 static int ttm_bo_ioremap(struct ttm_buffer_object *bo,
 			  unsigned long bus_base,
@@ -427,7 +428,7 @@
 
 		/*
 		 * We need to use vmap to get the desired page protection
-		 * or to make the buffer object look contigous.
+		 * or to make the buffer object look contiguous.
 		 */
 		prot = (mem->placement & TTM_PL_FLAG_CACHED) ?
 			PAGE_KERNEL :
diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c
index 1c040d0..609a85a 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_vm.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c
@@ -114,7 +114,7 @@
 		ret = ttm_bo_wait(bo, false, true, false);
 		spin_unlock(&bo->lock);
 		if (unlikely(ret != 0)) {
-			retval = (ret != -ERESTART) ?
+			retval = (ret != -ERESTARTSYS) ?
 			    VM_FAULT_SIGBUS : VM_FAULT_NOPAGE;
 			goto out_unlock;
 		}
@@ -349,9 +349,6 @@
 	switch (ret) {
 	case 0:
 		break;
-	case -ERESTART:
-		ret = -EINTR;
-		goto out_unref;
 	case -EBUSY:
 		ret = -EAGAIN;
 		goto out_unref;
@@ -421,8 +418,6 @@
 	switch (ret) {
 	case 0:
 		break;
-	case -ERESTART:
-		return -EINTR;
 	case -EBUSY:
 		return -EAGAIN;
 	default:
diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
new file mode 100644
index 0000000..c285c29
--- /dev/null
+++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
@@ -0,0 +1,117 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "ttm/ttm_execbuf_util.h"
+#include "ttm/ttm_bo_driver.h"
+#include "ttm/ttm_placement.h"
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+
+void ttm_eu_backoff_reservation(struct list_head *list)
+{
+	struct ttm_validate_buffer *entry;
+
+	list_for_each_entry(entry, list, head) {
+		struct ttm_buffer_object *bo = entry->bo;
+		if (!entry->reserved)
+			continue;
+
+		entry->reserved = false;
+		ttm_bo_unreserve(bo);
+	}
+}
+EXPORT_SYMBOL(ttm_eu_backoff_reservation);
+
+/*
+ * Reserve buffers for validation.
+ *
+ * If a buffer in the list is marked for CPU access, we back off and
+ * wait for that buffer to become free for GPU access.
+ *
+ * If a buffer is reserved for another validation, the validator with
+ * the highest validation sequence backs off and waits for that buffer
+ * to become unreserved. This prevents deadlocks when validating multiple
+ * buffers in different orders.
+ */
+
+int ttm_eu_reserve_buffers(struct list_head *list, uint32_t val_seq)
+{
+	struct ttm_validate_buffer *entry;
+	int ret;
+
+retry:
+	list_for_each_entry(entry, list, head) {
+		struct ttm_buffer_object *bo = entry->bo;
+
+		entry->reserved = false;
+		ret = ttm_bo_reserve(bo, true, false, true, val_seq);
+		if (ret != 0) {
+			ttm_eu_backoff_reservation(list);
+			if (ret == -EAGAIN) {
+				ret = ttm_bo_wait_unreserved(bo, true);
+				if (unlikely(ret != 0))
+					return ret;
+				goto retry;
+			} else
+				return ret;
+		}
+
+		entry->reserved = true;
+		if (unlikely(atomic_read(&bo->cpu_writers) > 0)) {
+			ttm_eu_backoff_reservation(list);
+			ret = ttm_bo_wait_cpu(bo, false);
+			if (ret)
+				return ret;
+			goto retry;
+		}
+	}
+	return 0;
+}
+EXPORT_SYMBOL(ttm_eu_reserve_buffers);
+
+void ttm_eu_fence_buffer_objects(struct list_head *list, void *sync_obj)
+{
+	struct ttm_validate_buffer *entry;
+
+	list_for_each_entry(entry, list, head) {
+		struct ttm_buffer_object *bo = entry->bo;
+		struct ttm_bo_driver *driver = bo->bdev->driver;
+		void *old_sync_obj;
+
+		spin_lock(&bo->lock);
+		old_sync_obj = bo->sync_obj;
+		bo->sync_obj = driver->sync_obj_ref(sync_obj);
+		bo->sync_obj_arg = entry->new_sync_obj_arg;
+		spin_unlock(&bo->lock);
+		ttm_bo_unreserve(bo);
+		entry->reserved = false;
+		if (old_sync_obj)
+			driver->sync_obj_unref(&old_sync_obj);
+	}
+}
+EXPORT_SYMBOL(ttm_eu_fence_buffer_objects);
diff --git a/drivers/gpu/drm/ttm/ttm_lock.c b/drivers/gpu/drm/ttm/ttm_lock.c
new file mode 100644
index 0000000..f619ebc
--- /dev/null
+++ b/drivers/gpu/drm/ttm/ttm_lock.c
@@ -0,0 +1,311 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2007-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+
+#include "ttm/ttm_lock.h"
+#include "ttm/ttm_module.h"
+#include <asm/atomic.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+
+#define TTM_WRITE_LOCK_PENDING    (1 << 0)
+#define TTM_VT_LOCK_PENDING       (1 << 1)
+#define TTM_SUSPEND_LOCK_PENDING  (1 << 2)
+#define TTM_VT_LOCK               (1 << 3)
+#define TTM_SUSPEND_LOCK          (1 << 4)
+
+void ttm_lock_init(struct ttm_lock *lock)
+{
+	spin_lock_init(&lock->lock);
+	init_waitqueue_head(&lock->queue);
+	lock->rw = 0;
+	lock->flags = 0;
+	lock->kill_takers = false;
+	lock->signal = SIGKILL;
+}
+EXPORT_SYMBOL(ttm_lock_init);
+
+void ttm_read_unlock(struct ttm_lock *lock)
+{
+	spin_lock(&lock->lock);
+	if (--lock->rw == 0)
+		wake_up_all(&lock->queue);
+	spin_unlock(&lock->lock);
+}
+EXPORT_SYMBOL(ttm_read_unlock);
+
+static bool __ttm_read_lock(struct ttm_lock *lock)
+{
+	bool locked = false;
+
+	spin_lock(&lock->lock);
+	if (unlikely(lock->kill_takers)) {
+		send_sig(lock->signal, current, 0);
+		spin_unlock(&lock->lock);
+		return false;
+	}
+	if (lock->rw >= 0 && lock->flags == 0) {
+		++lock->rw;
+		locked = true;
+	}
+	spin_unlock(&lock->lock);
+	return locked;
+}
+
+int ttm_read_lock(struct ttm_lock *lock, bool interruptible)
+{
+	int ret = 0;
+
+	if (interruptible)
+		ret = wait_event_interruptible(lock->queue,
+					       __ttm_read_lock(lock));
+	else
+		wait_event(lock->queue, __ttm_read_lock(lock));
+	return ret;
+}
+EXPORT_SYMBOL(ttm_read_lock);
+
+static bool __ttm_read_trylock(struct ttm_lock *lock, bool *locked)
+{
+	bool block = true;
+
+	*locked = false;
+
+	spin_lock(&lock->lock);
+	if (unlikely(lock->kill_takers)) {
+		send_sig(lock->signal, current, 0);
+		spin_unlock(&lock->lock);
+		return false;
+	}
+	if (lock->rw >= 0 && lock->flags == 0) {
+		++lock->rw;
+		block = false;
+		*locked = true;
+	} else if (lock->flags == 0) {
+		block = false;
+	}
+	spin_unlock(&lock->lock);
+
+	return !block;
+}
+
+int ttm_read_trylock(struct ttm_lock *lock, bool interruptible)
+{
+	int ret = 0;
+	bool locked;
+
+	if (interruptible)
+		ret = wait_event_interruptible
+			(lock->queue, __ttm_read_trylock(lock, &locked));
+	else
+		wait_event(lock->queue, __ttm_read_trylock(lock, &locked));
+
+	if (unlikely(ret != 0)) {
+		BUG_ON(locked);
+		return ret;
+	}
+
+	return (locked) ? 0 : -EBUSY;
+}
+
+void ttm_write_unlock(struct ttm_lock *lock)
+{
+	spin_lock(&lock->lock);
+	lock->rw = 0;
+	wake_up_all(&lock->queue);
+	spin_unlock(&lock->lock);
+}
+EXPORT_SYMBOL(ttm_write_unlock);
+
+static bool __ttm_write_lock(struct ttm_lock *lock)
+{
+	bool locked = false;
+
+	spin_lock(&lock->lock);
+	if (unlikely(lock->kill_takers)) {
+		send_sig(lock->signal, current, 0);
+		spin_unlock(&lock->lock);
+		return false;
+	}
+	if (lock->rw == 0 && ((lock->flags & ~TTM_WRITE_LOCK_PENDING) == 0)) {
+		lock->rw = -1;
+		lock->flags &= ~TTM_WRITE_LOCK_PENDING;
+		locked = true;
+	} else {
+		lock->flags |= TTM_WRITE_LOCK_PENDING;
+	}
+	spin_unlock(&lock->lock);
+	return locked;
+}
+
+int ttm_write_lock(struct ttm_lock *lock, bool interruptible)
+{
+	int ret = 0;
+
+	if (interruptible) {
+		ret = wait_event_interruptible(lock->queue,
+					       __ttm_write_lock(lock));
+		if (unlikely(ret != 0)) {
+			spin_lock(&lock->lock);
+			lock->flags &= ~TTM_WRITE_LOCK_PENDING;
+			wake_up_all(&lock->queue);
+			spin_unlock(&lock->lock);
+		}
+	} else
+		wait_event(lock->queue, __ttm_read_lock(lock));
+
+	return ret;
+}
+EXPORT_SYMBOL(ttm_write_lock);
+
+void ttm_write_lock_downgrade(struct ttm_lock *lock)
+{
+	spin_lock(&lock->lock);
+	lock->rw = 1;
+	wake_up_all(&lock->queue);
+	spin_unlock(&lock->lock);
+}
+
+static int __ttm_vt_unlock(struct ttm_lock *lock)
+{
+	int ret = 0;
+
+	spin_lock(&lock->lock);
+	if (unlikely(!(lock->flags & TTM_VT_LOCK)))
+		ret = -EINVAL;
+	lock->flags &= ~TTM_VT_LOCK;
+	wake_up_all(&lock->queue);
+	spin_unlock(&lock->lock);
+	printk(KERN_INFO TTM_PFX "vt unlock.\n");
+
+	return ret;
+}
+
+static void ttm_vt_lock_remove(struct ttm_base_object **p_base)
+{
+	struct ttm_base_object *base = *p_base;
+	struct ttm_lock *lock = container_of(base, struct ttm_lock, base);
+	int ret;
+
+	*p_base = NULL;
+	ret = __ttm_vt_unlock(lock);
+	BUG_ON(ret != 0);
+}
+
+static bool __ttm_vt_lock(struct ttm_lock *lock)
+{
+	bool locked = false;
+
+	spin_lock(&lock->lock);
+	if (lock->rw == 0) {
+		lock->flags &= ~TTM_VT_LOCK_PENDING;
+		lock->flags |= TTM_VT_LOCK;
+		locked = true;
+	} else {
+		lock->flags |= TTM_VT_LOCK_PENDING;
+	}
+	spin_unlock(&lock->lock);
+	return locked;
+}
+
+int ttm_vt_lock(struct ttm_lock *lock,
+		bool interruptible,
+		struct ttm_object_file *tfile)
+{
+	int ret = 0;
+
+	if (interruptible) {
+		ret = wait_event_interruptible(lock->queue,
+					       __ttm_vt_lock(lock));
+		if (unlikely(ret != 0)) {
+			spin_lock(&lock->lock);
+			lock->flags &= ~TTM_VT_LOCK_PENDING;
+			wake_up_all(&lock->queue);
+			spin_unlock(&lock->lock);
+			return ret;
+		}
+	} else
+		wait_event(lock->queue, __ttm_vt_lock(lock));
+
+	/*
+	 * Add a base-object, the destructor of which will
+	 * make sure the lock is released if the client dies
+	 * while holding it.
+	 */
+
+	ret = ttm_base_object_init(tfile, &lock->base, false,
+				   ttm_lock_type, &ttm_vt_lock_remove, NULL);
+	if (ret)
+		(void)__ttm_vt_unlock(lock);
+	else {
+		lock->vt_holder = tfile;
+		printk(KERN_INFO TTM_PFX "vt lock.\n");
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(ttm_vt_lock);
+
+int ttm_vt_unlock(struct ttm_lock *lock)
+{
+	return ttm_ref_object_base_unref(lock->vt_holder,
+					 lock->base.hash.key, TTM_REF_USAGE);
+}
+EXPORT_SYMBOL(ttm_vt_unlock);
+
+void ttm_suspend_unlock(struct ttm_lock *lock)
+{
+	spin_lock(&lock->lock);
+	lock->flags &= ~TTM_SUSPEND_LOCK;
+	wake_up_all(&lock->queue);
+	spin_unlock(&lock->lock);
+}
+
+static bool __ttm_suspend_lock(struct ttm_lock *lock)
+{
+	bool locked = false;
+
+	spin_lock(&lock->lock);
+	if (lock->rw == 0) {
+		lock->flags &= ~TTM_SUSPEND_LOCK_PENDING;
+		lock->flags |= TTM_SUSPEND_LOCK;
+		locked = true;
+	} else {
+		lock->flags |= TTM_SUSPEND_LOCK_PENDING;
+	}
+	spin_unlock(&lock->lock);
+	return locked;
+}
+
+void ttm_suspend_lock(struct ttm_lock *lock)
+{
+	wait_event(lock->queue, __ttm_suspend_lock(lock));
+}
diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c
index 072c281a..f5245c0 100644
--- a/drivers/gpu/drm/ttm/ttm_memory.c
+++ b/drivers/gpu/drm/ttm/ttm_memory.c
@@ -274,16 +274,17 @@
 static int ttm_mem_init_highmem_zone(struct ttm_mem_global *glob,
 				     const struct sysinfo *si)
 {
-	struct ttm_mem_zone *zone = kzalloc(sizeof(*zone), GFP_KERNEL);
+	struct ttm_mem_zone *zone;
 	uint64_t mem;
 	int ret;
 
-	if (unlikely(!zone))
-		return -ENOMEM;
-
 	if (si->totalhigh == 0)
 		return 0;
 
+	zone = kzalloc(sizeof(*zone), GFP_KERNEL);
+	if (unlikely(!zone))
+		return -ENOMEM;
+
 	mem = si->totalram;
 	mem *= si->mem_unit;
 
@@ -322,8 +323,10 @@
 	 * No special dma32 zone needed.
 	 */
 
-	if (mem <= ((uint64_t) 1ULL << 32))
+	if (mem <= ((uint64_t) 1ULL << 32)) {
+		kfree(zone);
 		return 0;
+	}
 
 	/*
 	 * Limit max dma32 memory to 4GB for now
@@ -460,6 +463,7 @@
 {
 	return ttm_mem_global_free_zone(glob, NULL, amount);
 }
+EXPORT_SYMBOL(ttm_mem_global_free);
 
 static int ttm_mem_global_reserve(struct ttm_mem_global *glob,
 				  struct ttm_mem_zone *single_zone,
@@ -533,6 +537,7 @@
 	return ttm_mem_global_alloc_zone(glob, NULL, memory, no_wait,
 					 interruptible);
 }
+EXPORT_SYMBOL(ttm_mem_global_alloc);
 
 int ttm_mem_global_alloc_page(struct ttm_mem_global *glob,
 			      struct page *page,
@@ -588,3 +593,4 @@
 	}
 	return 0;
 }
+EXPORT_SYMBOL(ttm_round_pot);
diff --git a/drivers/gpu/drm/ttm/ttm_object.c b/drivers/gpu/drm/ttm/ttm_object.c
new file mode 100644
index 0000000..1099aba
--- /dev/null
+++ b/drivers/gpu/drm/ttm/ttm_object.c
@@ -0,0 +1,452 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+/** @file ttm_ref_object.c
+ *
+ * Base- and reference object implementation for the various
+ * ttm objects. Implements reference counting, minimal security checks
+ * and release on file close.
+ */
+
+/**
+ * struct ttm_object_file
+ *
+ * @tdev: Pointer to the ttm_object_device.
+ *
+ * @lock: Lock that protects the ref_list list and the
+ * ref_hash hash tables.
+ *
+ * @ref_list: List of ttm_ref_objects to be destroyed at
+ * file release.
+ *
+ * @ref_hash: Hash tables of ref objects, one per ttm_ref_type,
+ * for fast lookup of ref objects given a base object.
+ */
+
+#include "ttm/ttm_object.h"
+#include "ttm/ttm_module.h"
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <asm/atomic.h>
+
+struct ttm_object_file {
+	struct ttm_object_device *tdev;
+	rwlock_t lock;
+	struct list_head ref_list;
+	struct drm_open_hash ref_hash[TTM_REF_NUM];
+	struct kref refcount;
+};
+
+/**
+ * struct ttm_object_device
+ *
+ * @object_lock: lock that protects the object_hash hash table.
+ *
+ * @object_hash: hash table for fast lookup of object global names.
+ *
+ * @object_count: Per device object count.
+ *
+ * This is the per-device data structure needed for ttm object management.
+ */
+
+struct ttm_object_device {
+	rwlock_t object_lock;
+	struct drm_open_hash object_hash;
+	atomic_t object_count;
+	struct ttm_mem_global *mem_glob;
+};
+
+/**
+ * struct ttm_ref_object
+ *
+ * @hash: Hash entry for the per-file object reference hash.
+ *
+ * @head: List entry for the per-file list of ref-objects.
+ *
+ * @kref: Ref count.
+ *
+ * @obj: Base object this ref object is referencing.
+ *
+ * @ref_type: Type of ref object.
+ *
+ * This is similar to an idr object, but it also has a hash table entry
+ * that allows lookup with a pointer to the referenced object as a key. In
+ * that way, one can easily detect whether a base object is referenced by
+ * a particular ttm_object_file. It also carries a ref count to avoid creating
+ * multiple ref objects if a ttm_object_file references the same base
+ * object more than once.
+ */
+
+struct ttm_ref_object {
+	struct drm_hash_item hash;
+	struct list_head head;
+	struct kref kref;
+	struct ttm_base_object *obj;
+	enum ttm_ref_type ref_type;
+	struct ttm_object_file *tfile;
+};
+
+static inline struct ttm_object_file *
+ttm_object_file_ref(struct ttm_object_file *tfile)
+{
+	kref_get(&tfile->refcount);
+	return tfile;
+}
+
+static void ttm_object_file_destroy(struct kref *kref)
+{
+	struct ttm_object_file *tfile =
+		container_of(kref, struct ttm_object_file, refcount);
+
+	kfree(tfile);
+}
+
+
+static inline void ttm_object_file_unref(struct ttm_object_file **p_tfile)
+{
+	struct ttm_object_file *tfile = *p_tfile;
+
+	*p_tfile = NULL;
+	kref_put(&tfile->refcount, ttm_object_file_destroy);
+}
+
+
+int ttm_base_object_init(struct ttm_object_file *tfile,
+			 struct ttm_base_object *base,
+			 bool shareable,
+			 enum ttm_object_type object_type,
+			 void (*refcount_release) (struct ttm_base_object **),
+			 void (*ref_obj_release) (struct ttm_base_object *,
+						  enum ttm_ref_type ref_type))
+{
+	struct ttm_object_device *tdev = tfile->tdev;
+	int ret;
+
+	base->shareable = shareable;
+	base->tfile = ttm_object_file_ref(tfile);
+	base->refcount_release = refcount_release;
+	base->ref_obj_release = ref_obj_release;
+	base->object_type = object_type;
+	write_lock(&tdev->object_lock);
+	kref_init(&base->refcount);
+	ret = drm_ht_just_insert_please(&tdev->object_hash,
+					&base->hash,
+					(unsigned long)base, 31, 0, 0);
+	write_unlock(&tdev->object_lock);
+	if (unlikely(ret != 0))
+		goto out_err0;
+
+	ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL);
+	if (unlikely(ret != 0))
+		goto out_err1;
+
+	ttm_base_object_unref(&base);
+
+	return 0;
+out_err1:
+	(void)drm_ht_remove_item(&tdev->object_hash, &base->hash);
+out_err0:
+	return ret;
+}
+EXPORT_SYMBOL(ttm_base_object_init);
+
+static void ttm_release_base(struct kref *kref)
+{
+	struct ttm_base_object *base =
+	    container_of(kref, struct ttm_base_object, refcount);
+	struct ttm_object_device *tdev = base->tfile->tdev;
+
+	(void)drm_ht_remove_item(&tdev->object_hash, &base->hash);
+	write_unlock(&tdev->object_lock);
+	if (base->refcount_release) {
+		ttm_object_file_unref(&base->tfile);
+		base->refcount_release(&base);
+	}
+	write_lock(&tdev->object_lock);
+}
+
+void ttm_base_object_unref(struct ttm_base_object **p_base)
+{
+	struct ttm_base_object *base = *p_base;
+	struct ttm_object_device *tdev = base->tfile->tdev;
+
+	*p_base = NULL;
+
+	/*
+	 * Need to take the lock here to avoid racing with
+	 * users trying to look up the object.
+	 */
+
+	write_lock(&tdev->object_lock);
+	(void)kref_put(&base->refcount, &ttm_release_base);
+	write_unlock(&tdev->object_lock);
+}
+EXPORT_SYMBOL(ttm_base_object_unref);
+
+struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file *tfile,
+					       uint32_t key)
+{
+	struct ttm_object_device *tdev = tfile->tdev;
+	struct ttm_base_object *base;
+	struct drm_hash_item *hash;
+	int ret;
+
+	read_lock(&tdev->object_lock);
+	ret = drm_ht_find_item(&tdev->object_hash, key, &hash);
+
+	if (likely(ret == 0)) {
+		base = drm_hash_entry(hash, struct ttm_base_object, hash);
+		kref_get(&base->refcount);
+	}
+	read_unlock(&tdev->object_lock);
+
+	if (unlikely(ret != 0))
+		return NULL;
+
+	if (tfile != base->tfile && !base->shareable) {
+		printk(KERN_ERR TTM_PFX
+		       "Attempted access of non-shareable object.\n");
+		ttm_base_object_unref(&base);
+		return NULL;
+	}
+
+	return base;
+}
+EXPORT_SYMBOL(ttm_base_object_lookup);
+
+int ttm_ref_object_add(struct ttm_object_file *tfile,
+		       struct ttm_base_object *base,
+		       enum ttm_ref_type ref_type, bool *existed)
+{
+	struct drm_open_hash *ht = &tfile->ref_hash[ref_type];
+	struct ttm_ref_object *ref;
+	struct drm_hash_item *hash;
+	struct ttm_mem_global *mem_glob = tfile->tdev->mem_glob;
+	int ret = -EINVAL;
+
+	if (existed != NULL)
+		*existed = true;
+
+	while (ret == -EINVAL) {
+		read_lock(&tfile->lock);
+		ret = drm_ht_find_item(ht, base->hash.key, &hash);
+
+		if (ret == 0) {
+			ref = drm_hash_entry(hash, struct ttm_ref_object, hash);
+			kref_get(&ref->kref);
+			read_unlock(&tfile->lock);
+			break;
+		}
+
+		read_unlock(&tfile->lock);
+		ret = ttm_mem_global_alloc(mem_glob, sizeof(*ref),
+					   false, false);
+		if (unlikely(ret != 0))
+			return ret;
+		ref = kmalloc(sizeof(*ref), GFP_KERNEL);
+		if (unlikely(ref == NULL)) {
+			ttm_mem_global_free(mem_glob, sizeof(*ref));
+			return -ENOMEM;
+		}
+
+		ref->hash.key = base->hash.key;
+		ref->obj = base;
+		ref->tfile = tfile;
+		ref->ref_type = ref_type;
+		kref_init(&ref->kref);
+
+		write_lock(&tfile->lock);
+		ret = drm_ht_insert_item(ht, &ref->hash);
+
+		if (likely(ret == 0)) {
+			list_add_tail(&ref->head, &tfile->ref_list);
+			kref_get(&base->refcount);
+			write_unlock(&tfile->lock);
+			if (existed != NULL)
+				*existed = false;
+			break;
+		}
+
+		write_unlock(&tfile->lock);
+		BUG_ON(ret != -EINVAL);
+
+		ttm_mem_global_free(mem_glob, sizeof(*ref));
+		kfree(ref);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(ttm_ref_object_add);
+
+static void ttm_ref_object_release(struct kref *kref)
+{
+	struct ttm_ref_object *ref =
+	    container_of(kref, struct ttm_ref_object, kref);
+	struct ttm_base_object *base = ref->obj;
+	struct ttm_object_file *tfile = ref->tfile;
+	struct drm_open_hash *ht;
+	struct ttm_mem_global *mem_glob = tfile->tdev->mem_glob;
+
+	ht = &tfile->ref_hash[ref->ref_type];
+	(void)drm_ht_remove_item(ht, &ref->hash);
+	list_del(&ref->head);
+	write_unlock(&tfile->lock);
+
+	if (ref->ref_type != TTM_REF_USAGE && base->ref_obj_release)
+		base->ref_obj_release(base, ref->ref_type);
+
+	ttm_base_object_unref(&ref->obj);
+	ttm_mem_global_free(mem_glob, sizeof(*ref));
+	kfree(ref);
+	write_lock(&tfile->lock);
+}
+
+int ttm_ref_object_base_unref(struct ttm_object_file *tfile,
+			      unsigned long key, enum ttm_ref_type ref_type)
+{
+	struct drm_open_hash *ht = &tfile->ref_hash[ref_type];
+	struct ttm_ref_object *ref;
+	struct drm_hash_item *hash;
+	int ret;
+
+	write_lock(&tfile->lock);
+	ret = drm_ht_find_item(ht, key, &hash);
+	if (unlikely(ret != 0)) {
+		write_unlock(&tfile->lock);
+		return -EINVAL;
+	}
+	ref = drm_hash_entry(hash, struct ttm_ref_object, hash);
+	kref_put(&ref->kref, ttm_ref_object_release);
+	write_unlock(&tfile->lock);
+	return 0;
+}
+EXPORT_SYMBOL(ttm_ref_object_base_unref);
+
+void ttm_object_file_release(struct ttm_object_file **p_tfile)
+{
+	struct ttm_ref_object *ref;
+	struct list_head *list;
+	unsigned int i;
+	struct ttm_object_file *tfile = *p_tfile;
+
+	*p_tfile = NULL;
+	write_lock(&tfile->lock);
+
+	/*
+	 * Since we release the lock within the loop, we have to
+	 * restart it from the beginning each time.
+	 */
+
+	while (!list_empty(&tfile->ref_list)) {
+		list = tfile->ref_list.next;
+		ref = list_entry(list, struct ttm_ref_object, head);
+		ttm_ref_object_release(&ref->kref);
+	}
+
+	for (i = 0; i < TTM_REF_NUM; ++i)
+		drm_ht_remove(&tfile->ref_hash[i]);
+
+	write_unlock(&tfile->lock);
+	ttm_object_file_unref(&tfile);
+}
+EXPORT_SYMBOL(ttm_object_file_release);
+
+struct ttm_object_file *ttm_object_file_init(struct ttm_object_device *tdev,
+					     unsigned int hash_order)
+{
+	struct ttm_object_file *tfile = kmalloc(sizeof(*tfile), GFP_KERNEL);
+	unsigned int i;
+	unsigned int j = 0;
+	int ret;
+
+	if (unlikely(tfile == NULL))
+		return NULL;
+
+	rwlock_init(&tfile->lock);
+	tfile->tdev = tdev;
+	kref_init(&tfile->refcount);
+	INIT_LIST_HEAD(&tfile->ref_list);
+
+	for (i = 0; i < TTM_REF_NUM; ++i) {
+		ret = drm_ht_create(&tfile->ref_hash[i], hash_order);
+		if (ret) {
+			j = i;
+			goto out_err;
+		}
+	}
+
+	return tfile;
+out_err:
+	for (i = 0; i < j; ++i)
+		drm_ht_remove(&tfile->ref_hash[i]);
+
+	kfree(tfile);
+
+	return NULL;
+}
+EXPORT_SYMBOL(ttm_object_file_init);
+
+struct ttm_object_device *ttm_object_device_init(struct ttm_mem_global
+						 *mem_glob,
+						 unsigned int hash_order)
+{
+	struct ttm_object_device *tdev = kmalloc(sizeof(*tdev), GFP_KERNEL);
+	int ret;
+
+	if (unlikely(tdev == NULL))
+		return NULL;
+
+	tdev->mem_glob = mem_glob;
+	rwlock_init(&tdev->object_lock);
+	atomic_set(&tdev->object_count, 0);
+	ret = drm_ht_create(&tdev->object_hash, hash_order);
+
+	if (likely(ret == 0))
+		return tdev;
+
+	kfree(tdev);
+	return NULL;
+}
+EXPORT_SYMBOL(ttm_object_device_init);
+
+void ttm_object_device_release(struct ttm_object_device **p_tdev)
+{
+	struct ttm_object_device *tdev = *p_tdev;
+
+	*p_tdev = NULL;
+
+	write_lock(&tdev->object_lock);
+	drm_ht_remove(&tdev->object_hash);
+	write_unlock(&tdev->object_lock);
+
+	kfree(tdev);
+}
+EXPORT_SYMBOL(ttm_object_device_release);
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index 7bcb89f..9c2b1cc 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -192,6 +192,7 @@
 	ttm->state = tt_unbound;
 	return 0;
 }
+EXPORT_SYMBOL(ttm_tt_populate);
 
 #ifdef CONFIG_X86
 static inline int ttm_tt_set_page_caching(struct page *p,
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 7d05c4b..80792d3 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -39,8 +39,6 @@
  * Version Information
  */
 
-#define DRIVER_VERSION "v2.6"
-#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik, Jiri Kosina"
 #define DRIVER_DESC "HID core driver"
 #define DRIVER_LICENSE "GPL"
 
@@ -1294,6 +1292,7 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
@@ -1326,6 +1325,8 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) },
@@ -1620,6 +1621,7 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) },
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_KYE, 0x0058) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY) },
@@ -1918,5 +1920,8 @@
 module_init(hid_init);
 module_exit(hid_exit);
 
+MODULE_AUTHOR("Andreas Gal");
+MODULE_AUTHOR("Vojtech Pavlik");
+MODULE_AUTHOR("Jiri Kosina");
 MODULE_LICENSE(DRIVER_LICENSE);
 
diff --git a/drivers/hid/hid-cypress.c b/drivers/hid/hid-cypress.c
index 62e9cb1..998b6f4 100644
--- a/drivers/hid/hid-cypress.c
+++ b/drivers/hid/hid-cypress.c
@@ -126,6 +126,8 @@
 		.driver_data = CP_RDESC_SWAPPED_MIN_MAX },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2),
 		.driver_data = CP_RDESC_SWAPPED_MIN_MAX },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3),
+		.driver_data = CP_RDESC_SWAPPED_MIN_MAX },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE),
 		.driver_data = CP_2WHEEL_MOUSE_HACK },
 	{ }
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index adbef5d..3839340e 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -117,6 +117,7 @@
 #define USB_DEVICE_ID_CH_PRO_PEDALS	0x00f2
 #define USB_DEVICE_ID_CH_COMBATSTICK	0x00f4
 #define USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE	0x00ff
+#define USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK	0x00d3
 
 #define USB_VENDOR_ID_CHERRY		0x046a
 #define USB_DEVICE_ID_CHERRY_CYMOTION	0x0023
@@ -145,6 +146,7 @@
 #define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE	0x7417
 #define USB_DEVICE_ID_CYPRESS_BARCODE_1	0xde61
 #define USB_DEVICE_ID_CYPRESS_BARCODE_2	0xde64
+#define USB_DEVICE_ID_CYPRESS_BARCODE_3	0xbca1
 
 #define USB_VENDOR_ID_DEALEXTREAME	0x10c5
 #define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701	0x819a
@@ -304,6 +306,8 @@
 #define USB_DEVICE_ID_S510_RECEIVER_2	0xc517
 #define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500	0xc512
 #define USB_DEVICE_ID_MX3000_RECEIVER	0xc513
+#define USB_DEVICE_ID_SPACETRAVELLER	0xc623
+#define USB_DEVICE_ID_SPACENAVIGATOR	0xc626
 #define USB_DEVICE_ID_DINOVO_DESKTOP	0xc704
 #define USB_DEVICE_ID_DINOVO_EDGE	0xc714
 #define USB_DEVICE_ID_DINOVO_MINI	0xc71f
@@ -346,6 +350,9 @@
 #define USB_VENDOR_ID_NEC		0x073e
 #define USB_DEVICE_ID_NEC_USB_GAME_PAD	0x0301
 
+#define USB_VENDOR_ID_NEXTWINDOW	0x1926
+#define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN	0x0003
+
 #define USB_VENDOR_ID_NTRIG                0x1b96
 #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN   0x0001
 
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index 0f870a3..9fcd3d0 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -33,6 +33,7 @@
 #define LG_NOGET		0x100
 #define LG_FF			0x200
 #define LG_FF2			0x400
+#define LG_RDESC_REL_ABS	0x800
 
 /*
  * Certain Logitech keyboards send in report #3 keys which are far
@@ -51,6 +52,13 @@
 		rdesc[84] = rdesc[89] = 0x4d;
 		rdesc[85] = rdesc[90] = 0x10;
 	}
+	if ((quirks & LG_RDESC_REL_ABS) && rsize >= 50 &&
+			rdesc[32] == 0x81 && rdesc[33] == 0x06 &&
+			rdesc[49] == 0x81 && rdesc[50] == 0x06) {
+		dev_info(&hdev->dev, "fixing up rel/abs in Logitech "
+				"report descriptor\n");
+		rdesc[33] = rdesc[50] = 0x02;
+	}
 }
 
 #define lg_map_key_clear(c)	hid_map_usage_clear(hi, usage, bit, max, \
@@ -89,6 +97,22 @@
 	return 1;
 }
 
+static int lg_dinovo_mapping(struct hid_input *hi, struct hid_usage *usage,
+		unsigned long **bit, int *max)
+{
+	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
+		return 0;
+
+	switch (usage->hid & HID_USAGE) {
+
+	case 0x00d: lg_map_key_clear(KEY_MEDIA);	break;
+	default:
+		return 0;
+
+	}
+	return 1;
+}
+
 static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage,
 		unsigned long **bit, int *max)
 {
@@ -164,6 +188,10 @@
 			lg_ultrax_remote_mapping(hi, usage, bit, max))
 		return 1;
 
+	if (hdev->product == USB_DEVICE_ID_DINOVO_MINI &&
+			lg_dinovo_mapping(hi, usage, bit, max))
+		return 1;
+
 	if ((quirks & LG_WIRELESS) && lg_wireless_mapping(hi, usage, bit, max))
 		return 1;
 
@@ -303,8 +331,13 @@
 		.driver_data = LG_FF },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2),
 		.driver_data = LG_FF2 },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR),
+		.driver_data = LG_RDESC_REL_ABS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER),
+		.driver_data = LG_RDESC_REL_ABS },
 	{ }
 };
+
 MODULE_DEVICE_TABLE(hid, lg_devices);
 
 static struct hid_driver lg_driver = {
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 03bd703..e2997a8 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -41,8 +41,6 @@
  * Version Information
  */
 
-#define DRIVER_VERSION "v2.6"
-#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik, Jiri Kosina"
 #define DRIVER_DESC "USB HID core driver"
 #define DRIVER_LICENSE "GPL"
 
@@ -998,7 +996,8 @@
 	usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma;
 	usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
 
-	usbhid_init_reports(hid);
+	if (!(hid->quirks & HID_QUIRK_NO_INIT_REPORTS))
+		usbhid_init_reports(hid);
 
 	set_bit(HID_STARTED, &usbhid->iofl);
 
@@ -1254,10 +1253,9 @@
 {
 	struct hid_device *hid = usb_get_intfdata(intf);
 	struct usbhid_device *usbhid = hid->driver_data;
-	struct usb_device *udev = interface_to_usbdev(intf);
 	int status;
 
-	if (udev->auto_pm) {
+	if (message.event & PM_EVENT_AUTO) {
 		spin_lock_irq(&usbhid->lock);	/* Sync with error handler */
 		if (!test_bit(HID_RESET_PENDING, &usbhid->iofl)
 		    && !test_bit(HID_CLEAR_HALT, &usbhid->iofl)
@@ -1282,7 +1280,7 @@
 			return -EIO;
 	}
 
-	if (!ignoreled && udev->auto_pm) {
+	if (!ignoreled && (message.event & PM_EVENT_AUTO)) {
 		spin_lock_irq(&usbhid->lock);
 		if (test_bit(HID_LED_ON, &usbhid->iofl)) {
 			spin_unlock_irq(&usbhid->lock);
@@ -1295,7 +1293,8 @@
 	hid_cancel_delayed_stuff(usbhid);
 	hid_cease_io(usbhid);
 
-	if (udev->auto_pm && test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) {
+	if ((message.event & PM_EVENT_AUTO) &&
+			test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) {
 		/* lost race against keypresses */
 		status = hid_start_in(hid);
 		if (status < 0)
@@ -1395,8 +1394,7 @@
 	retval = usb_register(&hid_driver);
 	if (retval)
 		goto usb_register_fail;
-	printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
-			DRIVER_DESC "\n");
+	printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n");
 
 	return 0;
 usb_register_fail:
@@ -1423,6 +1421,8 @@
 module_init(hid_init);
 module_exit(hid_exit);
 
-MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_AUTHOR("Andreas Gal");
+MODULE_AUTHOR("Vojtech Pavlik");
+MODULE_AUTHOR("Jiri Kosina");
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE(DRIVER_LICENSE);
diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c
index 484e3ee..e565dbe 100644
--- a/drivers/hid/usbhid/hid-pidff.c
+++ b/drivers/hid/usbhid/hid-pidff.c
@@ -1181,12 +1181,11 @@
 	usbhid_wait_io(hid);
 
 	if (pidff->pool[PID_SIMULTANEOUS_MAX].value) {
-		int sim_effects = pidff->pool[PID_SIMULTANEOUS_MAX].value[0];
-		while (sim_effects < 2) {
+		while (pidff->pool[PID_SIMULTANEOUS_MAX].value[0] < 2) {
 			if (i++ > 20) {
 				printk(KERN_WARNING "hid-pidff: device reports "
 				       "%d simultaneous effects\n",
-				       sim_effects);
+				       pidff->pool[PID_SIMULTANEOUS_MAX].value[0]);
 				break;
 			}
 			debug("pid_pool requested again");
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 0d9045aa..38773dc 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -37,6 +37,7 @@
 	{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_NATSU, USB_DEVICE_ID_NATSU_GAMEPAD, HID_QUIRK_BADPAD },
 	{ USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD },
+	{ USB_VENDOR_ID_NEXTWINDOW, USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN, HID_QUIRK_MULTI_INPUT},
 	{ USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD },
 	{ USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
 
@@ -53,6 +54,7 @@
 	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS, HID_QUIRK_NOGET },
+	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
@@ -280,7 +282,7 @@
 	if (idVendor == USB_VENDOR_ID_NCR &&
 			idProduct >= USB_DEVICE_ID_NCR_FIRST &&
 			idProduct <= USB_DEVICE_ID_NCR_LAST)
-			return HID_QUIRK_NOGET;
+			return HID_QUIRK_NO_INIT_REPORTS;
 
 	down_read(&dquirks_rwsem);
 	bl_entry = usbhid_exists_dquirk(idVendor, idProduct);
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 8b6ee24..867e084 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -450,7 +450,6 @@
 	uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL);
 	if (!uref_multi)
 		return -ENOMEM;
-	lock_kernel();
 	uref = &uref_multi->uref;
 	if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
 		if (copy_from_user(uref_multi, user_arg,
@@ -528,7 +527,6 @@
 
 		case HIDIOCGCOLLECTIONINDEX:
 			i = field->usage[uref->usage_index].collection_index;
-			unlock_kernel();
 			kfree(uref_multi);
 			return i;
 		case HIDIOCGUSAGES:
@@ -547,15 +545,12 @@
 		}
 
 goodreturn:
-		unlock_kernel();
 		kfree(uref_multi);
 		return 0;
 fault:
-		unlock_kernel();
 		kfree(uref_multi);
 		return -EFAULT;
 inval:
-		unlock_kernel();
 		kfree(uref_multi);
 		return -EINVAL;
 	}
diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c
index b342926..f843443 100644
--- a/drivers/hid/usbhid/usbkbd.c
+++ b/drivers/hid/usbhid/usbkbd.c
@@ -266,7 +266,7 @@
 			 le16_to_cpu(dev->descriptor.idProduct));
 
 	usb_make_path(dev, kbd->phys, sizeof(kbd->phys));
-	strlcpy(kbd->phys, "/input0", sizeof(kbd->phys));
+	strlcat(kbd->phys, "/input0", sizeof(kbd->phys));
 
 	input_dev->name = kbd->name;
 	input_dev->phys = kbd->phys;
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 700e93a..9e640c6 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -191,21 +191,27 @@
 	  will be called adt7470.
 
 config SENSORS_ADT7473
-	tristate "Analog Devices ADT7473"
+	tristate "Analog Devices ADT7473 (DEPRECATED)"
 	depends on I2C && EXPERIMENTAL
+	select SENSORS_ADT7475
 	help
 	  If you say yes here you get support for the Analog Devices
 	  ADT7473 temperature monitoring chips.
 
+	  This driver is deprecated, you should use the adt7475 driver
+	  instead.
+
 	  This driver can also be built as a module. If so, the module
 	  will be called adt7473.
 
 config SENSORS_ADT7475
-	tristate "Analog Devices ADT7475"
+	tristate "Analog Devices ADT7473, ADT7475, ADT7476 and ADT7490"
 	depends on I2C && EXPERIMENTAL
+	select HWMON_VID
 	help
 	  If you say yes here you get support for the Analog Devices
-	  ADT7475 hardware monitoring chips.
+	  ADT7473, ADT7475, ADT7476 and ADT7490 hardware monitoring
+	  chips.
 
 	  This driver can also be build as a module.  If so, the module
 	  will be called adt7475.
@@ -305,12 +311,12 @@
 	  will be called f71805f.
 
 config SENSORS_F71882FG
-	tristate "Fintek F71858FG, F71862FG, F71882FG and F8000"
+	tristate "Fintek F71858FG, F71862FG, F71882FG, F71889FG and F8000"
 	depends on EXPERIMENTAL
 	help
 	  If you say yes here you get support for hardware monitoring
-	  features of the Fintek F71858FG, F71862FG/71863FG, F71882FG/F71883FG
-	  and F8000 Super-I/O chips.
+	  features of the Fintek F71858FG, F71862FG/71863FG, F71882FG/F71883FG,
+	  F71889FG and F8000 Super-I/O chips.
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called f71882fg.
@@ -442,6 +448,15 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called lm70.
 
+config SENSORS_LM73
+	tristate "National Semiconductor LM73"
+	depends on I2C
+	help
+	  If you say yes here you get support for National Semiconductor LM73
+	  sensor chips.
+	  This driver can also be built as a module.  If so, the module
+	  will be called lm73.
+
 config SENSORS_LM75
 	tristate "National Semiconductor LM75 and compatibles"
 	depends on I2C
@@ -841,7 +856,7 @@
 
 config SENSORS_W83791D
 	tristate "Winbond W83791D"
-	depends on I2C && EXPERIMENTAL
+	depends on I2C
 	select HWMON_VID
 	help
 	  If you say yes here you get support for the Winbond W83791D chip.
@@ -1008,6 +1023,12 @@
 	  Say Y here if you have an applicable laptop and want to experience
 	  the awesome power of applesmc.
 
+config SENSORS_MC13783_ADC
+        tristate "Freescale MC13783 ADC"
+        depends on MFD_MC13783
+        help
+          Support for the A/D converter on MC13783 PMIC.
+
 if ACPI
 
 comment "ACPI drivers"
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 9f46cb0..33c2ee1 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -57,6 +57,7 @@
 obj-$(CONFIG_SENSORS_LIS3_SPI)	+= lis3lv02d.o lis3lv02d_spi.o
 obj-$(CONFIG_SENSORS_LM63)	+= lm63.o
 obj-$(CONFIG_SENSORS_LM70)	+= lm70.o
+obj-$(CONFIG_SENSORS_LM73)	+= lm73.o
 obj-$(CONFIG_SENSORS_LM75)	+= lm75.o
 obj-$(CONFIG_SENSORS_LM77)	+= lm77.o
 obj-$(CONFIG_SENSORS_LM78)	+= lm78.o
@@ -73,6 +74,7 @@
 obj-$(CONFIG_SENSORS_MAX1111)	+= max1111.o
 obj-$(CONFIG_SENSORS_MAX1619)	+= max1619.o
 obj-$(CONFIG_SENSORS_MAX6650)	+= max6650.o
+obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o
 obj-$(CONFIG_SENSORS_PC87360)	+= pc87360.o
 obj-$(CONFIG_SENSORS_PC87427)	+= pc87427.o
 obj-$(CONFIG_SENSORS_PCF8591)	+= pcf8591.o
diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c
index afc5943..33acf29 100644
--- a/drivers/hwmon/adm1021.c
+++ b/drivers/hwmon/adm1021.c
@@ -288,9 +288,8 @@
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
-	int i;
-	const char *type_name = "";
-	int conv_rate, status, config;
+	const char *type_name;
+	int conv_rate, status, config, man_id, dev_id;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
 		pr_debug("adm1021: detect failed, "
@@ -303,62 +302,37 @@
 					     ADM1021_REG_CONV_RATE_R);
 	config = i2c_smbus_read_byte_data(client, ADM1021_REG_CONFIG_R);
 
-	/* Now, we do the remaining detection. */
-	if (kind < 0) {
-		if ((status & 0x03) != 0x00 || (config & 0x3F) != 0x00
-		    || (conv_rate & 0xF8) != 0x00) {
-			pr_debug("adm1021: detect failed, "
-				 "chip not detected!\n");
-			return -ENODEV;
-		}
+	/* Check unused bits */
+	if ((status & 0x03) || (config & 0x3F) || (conv_rate & 0xF8)) {
+		pr_debug("adm1021: detect failed, chip not detected!\n");
+		return -ENODEV;
 	}
 
 	/* Determine the chip type. */
-	if (kind <= 0) {
-		i = i2c_smbus_read_byte_data(client, ADM1021_REG_MAN_ID);
-		if (i == 0x41)
-			if ((i2c_smbus_read_byte_data(client,
-					ADM1021_REG_DEV_ID) & 0xF0) == 0x30)
-				kind = adm1023;
-			else
-				kind = adm1021;
-		else if (i == 0x49)
-			kind = thmc10;
-		else if (i == 0x23)
-			kind = gl523sm;
-		else if ((i == 0x4d) &&
-			 (i2c_smbus_read_byte_data(client,
-						   ADM1021_REG_DEV_ID) == 0x01))
-			kind = max1617a;
-		else if (i == 0x54)
-			kind = mc1066;
-		/* LM84 Mfr ID in a different place, and it has more unused bits */
-		else if (conv_rate == 0x00
-			 && (kind == 0 /* skip extra detection */
-			     || ((config & 0x7F) == 0x00
-				 && (status & 0xAB) == 0x00)))
-			kind = lm84;
-		else
-			kind = max1617;
-	}
+	man_id = i2c_smbus_read_byte_data(client, ADM1021_REG_MAN_ID);
+	dev_id = i2c_smbus_read_byte_data(client, ADM1021_REG_DEV_ID);
 
-	if (kind == max1617) {
-		type_name = "max1617";
-	} else if (kind == max1617a) {
+	if (man_id == 0x4d && dev_id == 0x01)
 		type_name = "max1617a";
-	} else if (kind == adm1021) {
-		type_name = "adm1021";
-	} else if (kind == adm1023) {
-		type_name = "adm1023";
-	} else if (kind == thmc10) {
+	else if (man_id == 0x41) {
+		if ((dev_id & 0xF0) == 0x30)
+			type_name = "adm1023";
+		else
+			type_name = "adm1021";
+	} else if (man_id == 0x49)
 		type_name = "thmc10";
-	} else if (kind == lm84) {
-		type_name = "lm84";
-	} else if (kind == gl523sm) {
+	else if (man_id == 0x23)
 		type_name = "gl523sm";
-	} else if (kind == mc1066) {
+	else if (man_id == 0x54)
 		type_name = "mc1066";
-	}
+	/* LM84 Mfr ID in a different place, and it has more unused bits */
+	else if (conv_rate == 0x00
+		 && (config & 0x7F) == 0x00
+		 && (status & 0xAB) == 0x00)
+		type_name = "lm84";
+	else
+		type_name = "max1617";
+
 	pr_debug("adm1021: Detected chip %s at adapter %d, address 0x%02x.\n",
 		 type_name, i2c_adapter_id(adapter), client->addr);
 	strlcpy(info->type, type_name, I2C_NAME_SIZE);
diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c
index 4db04d6..db6ac2b 100644
--- a/drivers/hwmon/adm1025.c
+++ b/drivers/hwmon/adm1025.c
@@ -2,7 +2,7 @@
  * adm1025.c
  *
  * Copyright (C) 2000       Chen-Yuan Wu <gwu@esoft.com>
- * Copyright (C) 2003-2008  Jean Delvare <khali@linux-fr.org>
+ * Copyright (C) 2003-2009  Jean Delvare <khali@linux-fr.org>
  *
  * The ADM1025 is a sensor chip made by Analog Devices. It reports up to 6
  * voltages (including its own power source) and up to two temperatures
@@ -413,67 +413,34 @@
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
-	const char *name = "";
-	u8 config;
+	const char *name;
+	u8 man_id, chip_id;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	/*
-	 * Now we do the remaining detection. A negative kind means that
-	 * the driver was loaded with no force parameter (default), so we
-	 * must both detect and identify the chip. A zero kind means that
-	 * the driver was loaded with the force parameter, the detection
-	 * step shall be skipped. A positive kind means that the driver
-	 * was loaded with the force parameter and a given kind of chip is
-	 * requested, so both the detection and the identification steps
-	 * are skipped.
-	 */
-	config = i2c_smbus_read_byte_data(client, ADM1025_REG_CONFIG);
-	if (kind < 0) { /* detection */
-		if ((config & 0x80) != 0x00
-		 || (i2c_smbus_read_byte_data(client,
-		     ADM1025_REG_STATUS1) & 0xC0) != 0x00
-		 || (i2c_smbus_read_byte_data(client,
-		     ADM1025_REG_STATUS2) & 0xBC) != 0x00) {
-			dev_dbg(&adapter->dev,
-				"ADM1025 detection failed at 0x%02x.\n",
-				client->addr);
-			return -ENODEV;
-		}
+	/* Check for unused bits */
+	if ((i2c_smbus_read_byte_data(client, ADM1025_REG_CONFIG) & 0x80)
+	 || (i2c_smbus_read_byte_data(client, ADM1025_REG_STATUS1) & 0xC0)
+	 || (i2c_smbus_read_byte_data(client, ADM1025_REG_STATUS2) & 0xBC)) {
+		dev_dbg(&adapter->dev, "ADM1025 detection failed at 0x%02x\n",
+			client->addr);
+		return -ENODEV;
 	}
 
-	if (kind <= 0) { /* identification */
-		u8 man_id, chip_id;
+	/* Identification */
+	chip_id = i2c_smbus_read_byte_data(client, ADM1025_REG_CHIP_ID);
+	if ((chip_id & 0xF0) != 0x20)
+		return -ENODEV;
 
-		man_id = i2c_smbus_read_byte_data(client, ADM1025_REG_MAN_ID);
-		chip_id = i2c_smbus_read_byte_data(client, ADM1025_REG_CHIP_ID);
-
-		if (man_id == 0x41) { /* Analog Devices */
-			if ((chip_id & 0xF0) == 0x20) { /* ADM1025/ADM1025A */
-				kind = adm1025;
-			}
-		} else
-		if (man_id == 0xA1) { /* Philips */
-			if (client->addr != 0x2E
-			 && (chip_id & 0xF0) == 0x20) { /* NE1619 */
-				kind = ne1619;
-			}
-		}
-
-		if (kind <= 0) { /* identification failed */
-			dev_info(&adapter->dev,
-			    "Unsupported chip (man_id=0x%02X, "
-			    "chip_id=0x%02X).\n", man_id, chip_id);
-			return -ENODEV;
-		}
-	}
-
-	if (kind == adm1025) {
+	man_id = i2c_smbus_read_byte_data(client, ADM1025_REG_MAN_ID);
+	if (man_id == 0x41)
 		name = "adm1025";
-	} else if (kind == ne1619) {
+	else if (man_id == 0xA1 && client->addr != 0x2E)
 		name = "ne1619";
-	}
+	else
+		return -ENODEV;
+
 	strlcpy(info->type, name, I2C_NAME_SIZE);
 
 	return 0;
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c
index ff7de40..fb53639 100644
--- a/drivers/hwmon/adm1026.c
+++ b/drivers/hwmon/adm1026.c
@@ -1672,35 +1672,26 @@
 		i2c_adapter_id(client->adapter), client->addr,
 		company, verstep);
 
-	/* If auto-detecting, Determine the chip type. */
-	if (kind <= 0) {
-		dev_dbg(&adapter->dev, "Autodetecting device at %d,0x%02x "
-			"...\n", i2c_adapter_id(adapter), address);
-		if (company == ADM1026_COMPANY_ANALOG_DEV
-		    && verstep == ADM1026_VERSTEP_ADM1026) {
-			kind = adm1026;
-		} else if (company == ADM1026_COMPANY_ANALOG_DEV
-			&& (verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) {
-			dev_err(&adapter->dev, "Unrecognized stepping "
-				"0x%02x. Defaulting to ADM1026.\n", verstep);
-			kind = adm1026;
-		} else if ((verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) {
-			dev_err(&adapter->dev, "Found version/stepping "
-				"0x%02x. Assuming generic ADM1026.\n",
-				verstep);
-			kind = any_chip;
-		} else {
-			dev_dbg(&adapter->dev, "Autodetection failed\n");
-			/* Not an ADM1026 ... */
-			if (kind == 0) { /* User used force=x,y */
-				dev_err(&adapter->dev, "Generic ADM1026 not "
-					"found at %d,0x%02x.  Try "
-					"force_adm1026.\n",
-					i2c_adapter_id(adapter), address);
-			}
-			return -ENODEV;
-		}
+	/* Determine the chip type. */
+	dev_dbg(&adapter->dev, "Autodetecting device at %d,0x%02x...\n",
+		i2c_adapter_id(adapter), address);
+	if (company == ADM1026_COMPANY_ANALOG_DEV
+	    && verstep == ADM1026_VERSTEP_ADM1026) {
+		/* Analog Devices ADM1026 */
+	} else if (company == ADM1026_COMPANY_ANALOG_DEV
+		&& (verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) {
+		dev_err(&adapter->dev, "Unrecognized stepping "
+			"0x%02x. Defaulting to ADM1026.\n", verstep);
+	} else if ((verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) {
+		dev_err(&adapter->dev, "Found version/stepping "
+			"0x%02x. Assuming generic ADM1026.\n",
+			verstep);
+	} else {
+		dev_dbg(&adapter->dev, "Autodetection failed\n");
+		/* Not an ADM1026... */
+		return -ENODEV;
 	}
+
 	strlcpy(info->type, "adm1026", I2C_NAME_SIZE);
 
 	return 0;
diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c
index 3671815..ef91e2a4 100644
--- a/drivers/hwmon/adm1029.c
+++ b/drivers/hwmon/adm1029.c
@@ -301,59 +301,36 @@
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
+	u8 man_id, chip_id, temp_devices_installed, nb_fan_support;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	/* Now we do the detection and identification. A negative kind
-	 * means that the driver was loaded with no force parameter
-	 * (default), so we must both detect and identify the chip
-	 * (actually there is only one possible kind of chip for now, adm1029).
-	 * A zero kind means that the driver was loaded with the force
-	 * parameter, the detection step shall be skipped. A positive kind
-	 * means that the driver was loaded with the force parameter and a
-	 * given kind of chip is requested, so both the detection and the
-	 * identification steps are skipped. */
-
-	/* Default to an adm1029 if forced */
-	if (kind == 0)
-		kind = adm1029;
-
 	/* ADM1029 doesn't have CHIP ID, check just MAN ID
 	 * For better detection we check also ADM1029_TEMP_DEVICES_INSTALLED,
 	 * ADM1029_REG_NB_FAN_SUPPORT and compare it with possible values
 	 * documented
 	 */
 
-	if (kind <= 0) {	/* identification */
-		u8 man_id, chip_id, temp_devices_installed, nb_fan_support;
-
-		man_id = i2c_smbus_read_byte_data(client, ADM1029_REG_MAN_ID);
-		chip_id = i2c_smbus_read_byte_data(client, ADM1029_REG_CHIP_ID);
-		temp_devices_installed = i2c_smbus_read_byte_data(client,
+	man_id = i2c_smbus_read_byte_data(client, ADM1029_REG_MAN_ID);
+	chip_id = i2c_smbus_read_byte_data(client, ADM1029_REG_CHIP_ID);
+	temp_devices_installed = i2c_smbus_read_byte_data(client,
 					ADM1029_REG_TEMP_DEVICES_INSTALLED);
-		nb_fan_support = i2c_smbus_read_byte_data(client,
+	nb_fan_support = i2c_smbus_read_byte_data(client,
 						ADM1029_REG_NB_FAN_SUPPORT);
-		/* 0x41 is Analog Devices */
-		if (man_id == 0x41 && (temp_devices_installed & 0xf9) == 0x01
-		    && nb_fan_support == 0x03) {
-			if ((chip_id & 0xF0) == 0x00) {
-				kind = adm1029;
-			} else {
-				/* There are no "official" CHIP ID, so actually
-				 * we use Major/Minor revision for that */
-				printk(KERN_INFO
-				       "adm1029: Unknown major revision %x, "
-				       "please let us know\n", chip_id);
-			}
-		}
+	/* 0x41 is Analog Devices */
+	if (man_id != 0x41 || (temp_devices_installed & 0xf9) != 0x01
+	    || nb_fan_support != 0x03)
+		return -ENODEV;
 
-		if (kind <= 0) {	/* identification failed */
-			pr_debug("adm1029: Unsupported chip (man_id=0x%02X, "
-				 "chip_id=0x%02X)\n", man_id, chip_id);
-			return -ENODEV;
-		}
+	if ((chip_id & 0xF0) != 0x00) {
+		/* There are no "official" CHIP ID, so actually
+		 * we use Major/Minor revision for that */
+		pr_info("adm1029: Unknown major revision %x, "
+			"please let us know\n", chip_id);
+		return -ENODEV;
 	}
+
 	strlcpy(info->type, "adm1029", I2C_NAME_SIZE);
 
 	return 0;
@@ -432,7 +409,7 @@
 }
 
 /*
-function that update the status of the chips (temperature for exemple)
+function that update the status of the chips (temperature for example)
 */
 static struct adm1029_data *adm1029_update_device(struct device *dev)
 {
diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c
index 5690595..0e72217 100644
--- a/drivers/hwmon/adm1031.c
+++ b/drivers/hwmon/adm1031.c
@@ -817,31 +817,19 @@
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
-	const char *name = "";
+	const char *name;
+	int id, co;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	if (kind < 0) {
-		int id, co;
-		id = i2c_smbus_read_byte_data(client, 0x3d);
-		co = i2c_smbus_read_byte_data(client, 0x3e);
+	id = i2c_smbus_read_byte_data(client, 0x3d);
+	co = i2c_smbus_read_byte_data(client, 0x3e);
 
-		if (!((id == 0x31 || id == 0x30) && co == 0x41))
-			return -ENODEV;
-		kind = (id == 0x30) ? adm1030 : adm1031;
-	}
+	if (!((id == 0x31 || id == 0x30) && co == 0x41))
+		return -ENODEV;
+	name = (id == 0x30) ? "adm1030" : "adm1031";
 
-	if (kind <= 0)
-		kind = adm1031;
-
-	/* Given the detected chip type, set the chip name and the
-	 * auto fan control helper table. */
-	if (kind == adm1030) {
-		name = "adm1030";
-	} else if (kind == adm1031) {
-		name = "adm1031";
-	}
 	strlcpy(info->type, name, I2C_NAME_SIZE);
 
 	return 0;
diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c
index 2444b15..20e0481 100644
--- a/drivers/hwmon/adm9240.c
+++ b/drivers/hwmon/adm9240.c
@@ -556,51 +556,34 @@
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	if (kind == 0) {
-		kind = adm9240;
+	/* verify chip: reg address should match i2c address */
+	if (i2c_smbus_read_byte_data(new_client, ADM9240_REG_I2C_ADDR)
+			!= address) {
+		dev_err(&adapter->dev, "detect fail: address match, 0x%02x\n",
+			address);
+		return -ENODEV;
 	}
 
-	if (kind < 0) {
-
-		/* verify chip: reg address should match i2c address */
-		if (i2c_smbus_read_byte_data(new_client, ADM9240_REG_I2C_ADDR)
-				!= address) {
-			dev_err(&adapter->dev, "detect fail: address match, "
-					"0x%02x\n", address);
-			return -ENODEV;
-		}
-
-		/* check known chip manufacturer */
-		man_id = i2c_smbus_read_byte_data(new_client,
-				ADM9240_REG_MAN_ID);
-		if (man_id == 0x23) {
-			kind = adm9240;
-		} else if (man_id == 0xda) {
-			kind = ds1780;
-		} else if (man_id == 0x01) {
-			kind = lm81;
-		} else {
-			dev_err(&adapter->dev, "detect fail: unknown manuf, "
-					"0x%02x\n", man_id);
-			return -ENODEV;
-		}
-
-		/* successful detect, print chip info */
-		die_rev = i2c_smbus_read_byte_data(new_client,
-				ADM9240_REG_DIE_REV);
-		dev_info(&adapter->dev, "found %s revision %u\n",
-				man_id == 0x23 ? "ADM9240" :
-				man_id == 0xda ? "DS1780" : "LM81", die_rev);
-	}
-
-	/* either forced or detected chip kind */
-	if (kind == adm9240) {
+	/* check known chip manufacturer */
+	man_id = i2c_smbus_read_byte_data(new_client, ADM9240_REG_MAN_ID);
+	if (man_id == 0x23) {
 		name = "adm9240";
-	} else if (kind == ds1780) {
+	} else if (man_id == 0xda) {
 		name = "ds1780";
-	} else if (kind == lm81) {
+	} else if (man_id == 0x01) {
 		name = "lm81";
+	} else {
+		dev_err(&adapter->dev, "detect fail: unknown manuf, 0x%02x\n",
+			man_id);
+		return -ENODEV;
 	}
+
+	/* successful detect, print chip info */
+	die_rev = i2c_smbus_read_byte_data(new_client, ADM9240_REG_DIE_REV);
+	dev_info(&adapter->dev, "found %s revision %u\n",
+		 man_id == 0x23 ? "ADM9240" :
+		 man_id == 0xda ? "DS1780" : "LM81", die_rev);
+
 	strlcpy(info->type, name, I2C_NAME_SIZE);
 
 	return 0;
diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c
index 5c39b4a..451977b 100644
--- a/drivers/hwmon/ads7828.c
+++ b/drivers/hwmon/ads7828.c
@@ -191,6 +191,7 @@
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
+	int ch;
 
 	/* Check we have a valid client */
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_WORD_DATA))
@@ -202,20 +203,17 @@
 	- Read from the 8 channel addresses
 	- Check the top 4 bits of each result are not set (12 data bits)
 	*/
-	if (kind < 0) {
-		int ch;
-		for (ch = 0; ch < ADS7828_NCH; ch++) {
-			u16 in_data;
-			u8 cmd = channel_cmd_byte(ch);
-			in_data = ads7828_read_value(client, cmd);
-			if (in_data & 0xF000) {
-				printk(KERN_DEBUG
-				"%s : Doesn't look like an ads7828 device\n",
-				__func__);
-				return -ENODEV;
-			}
+	for (ch = 0; ch < ADS7828_NCH; ch++) {
+		u16 in_data;
+		u8 cmd = channel_cmd_byte(ch);
+		in_data = ads7828_read_value(client, cmd);
+		if (in_data & 0xF000) {
+			pr_debug("%s : Doesn't look like an ads7828 device\n",
+				 __func__);
+			return -ENODEV;
 		}
 	}
+
 	strlcpy(info->type, "ads7828", I2C_NAME_SIZE);
 
 	return 0;
diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c
index 1852f27..f9c9562 100644
--- a/drivers/hwmon/adt7462.c
+++ b/drivers/hwmon/adt7462.c
@@ -1906,27 +1906,22 @@
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
+	int vendor, device, revision;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	if (kind <= 0) {
-		int vendor, device, revision;
+	vendor = i2c_smbus_read_byte_data(client, ADT7462_REG_VENDOR);
+	if (vendor != ADT7462_VENDOR)
+		return -ENODEV;
 
-		vendor = i2c_smbus_read_byte_data(client, ADT7462_REG_VENDOR);
-		if (vendor != ADT7462_VENDOR)
-			return -ENODEV;
+	device = i2c_smbus_read_byte_data(client, ADT7462_REG_DEVICE);
+	if (device != ADT7462_DEVICE)
+		return -ENODEV;
 
-		device = i2c_smbus_read_byte_data(client, ADT7462_REG_DEVICE);
-		if (device != ADT7462_DEVICE)
-			return -ENODEV;
-
-		revision = i2c_smbus_read_byte_data(client,
-						    ADT7462_REG_REVISION);
-		if (revision != ADT7462_REVISION)
-			return -ENODEV;
-	} else
-		dev_dbg(&adapter->dev, "detection forced\n");
+	revision = i2c_smbus_read_byte_data(client, ADT7462_REG_REVISION);
+	if (revision != ADT7462_REVISION)
+		return -ENODEV;
 
 	strlcpy(info->type, "adt7462", I2C_NAME_SIZE);
 
diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c
index 633e1a1..32b1750 100644
--- a/drivers/hwmon/adt7470.c
+++ b/drivers/hwmon/adt7470.c
@@ -1229,27 +1229,22 @@
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
+	int vendor, device, revision;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	if (kind <= 0) {
-		int vendor, device, revision;
+	vendor = i2c_smbus_read_byte_data(client, ADT7470_REG_VENDOR);
+	if (vendor != ADT7470_VENDOR)
+		return -ENODEV;
 
-		vendor = i2c_smbus_read_byte_data(client, ADT7470_REG_VENDOR);
-		if (vendor != ADT7470_VENDOR)
-			return -ENODEV;
+	device = i2c_smbus_read_byte_data(client, ADT7470_REG_DEVICE);
+	if (device != ADT7470_DEVICE)
+		return -ENODEV;
 
-		device = i2c_smbus_read_byte_data(client, ADT7470_REG_DEVICE);
-		if (device != ADT7470_DEVICE)
-			return -ENODEV;
-
-		revision = i2c_smbus_read_byte_data(client,
-						    ADT7470_REG_REVISION);
-		if (revision != ADT7470_REVISION)
-			return -ENODEV;
-	} else
-		dev_dbg(&adapter->dev, "detection forced\n");
+	revision = i2c_smbus_read_byte_data(client, ADT7470_REG_REVISION);
+	if (revision != ADT7470_REVISION)
+		return -ENODEV;
 
 	strlcpy(info->type, "adt7470", I2C_NAME_SIZE);
 
diff --git a/drivers/hwmon/adt7473.c b/drivers/hwmon/adt7473.c
index 0a6ce23..aea244d 100644
--- a/drivers/hwmon/adt7473.c
+++ b/drivers/hwmon/adt7473.c
@@ -174,7 +174,6 @@
 	{ "adt7473", adt7473 },
 	{ }
 };
-MODULE_DEVICE_TABLE(i2c, adt7473_id);
 
 static struct i2c_driver adt7473_driver = {
 	.class		= I2C_CLASS_HWMON,
@@ -1090,27 +1089,22 @@
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
+	int vendor, device, revision;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	if (kind <= 0) {
-		int vendor, device, revision;
+	vendor = i2c_smbus_read_byte_data(client, ADT7473_REG_VENDOR);
+	if (vendor != ADT7473_VENDOR)
+		return -ENODEV;
 
-		vendor = i2c_smbus_read_byte_data(client, ADT7473_REG_VENDOR);
-		if (vendor != ADT7473_VENDOR)
-			return -ENODEV;
+	device = i2c_smbus_read_byte_data(client, ADT7473_REG_DEVICE);
+	if (device != ADT7473_DEVICE)
+		return -ENODEV;
 
-		device = i2c_smbus_read_byte_data(client, ADT7473_REG_DEVICE);
-		if (device != ADT7473_DEVICE)
-			return -ENODEV;
-
-		revision = i2c_smbus_read_byte_data(client,
-						    ADT7473_REG_REVISION);
-		if (revision != ADT7473_REV_68 && revision != ADT7473_REV_69)
-			return -ENODEV;
-	} else
-		dev_dbg(&adapter->dev, "detection forced\n");
+	revision = i2c_smbus_read_byte_data(client, ADT7473_REG_REVISION);
+	if (revision != ADT7473_REV_68 && revision != ADT7473_REV_69)
+		return -ENODEV;
 
 	strlcpy(info->type, "adt7473", I2C_NAME_SIZE);
 
@@ -1171,6 +1165,8 @@
 
 static int __init adt7473_init(void)
 {
+	pr_notice("The adt7473 driver is deprecated, please use the adt7475 "
+		  "driver instead\n");
 	return i2c_add_driver(&adt7473_driver);
 }
 
diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c
index b5a9519..99abfdd 100644
--- a/drivers/hwmon/adt7475.c
+++ b/drivers/hwmon/adt7475.c
@@ -3,7 +3,8 @@
  * Copyright (C) 2007-2008, Advanced Micro Devices, Inc.
  * Copyright (C) 2008 Jordan Crouse <jordan@cosmicpenguin.net>
  * Copyright (C) 2008 Hans de Goede <hdegoede@redhat.com>
-
+ * Copyright (C) 2009 Jean Delvare <khali@linux-fr.org>
+ *
  * Derived from the lm83 driver by Jean Delvare
  *
  * This program is free software; you can redistribute it and/or modify
@@ -17,6 +18,7 @@
 #include <linux/i2c.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
+#include <linux/hwmon-vid.h>
 #include <linux/err.h>
 
 /* Indexes for the sysfs hooks */
@@ -39,7 +41,12 @@
 
 /* 7475 Common Registers */
 
-#define REG_VOLTAGE_BASE	0x21
+#define REG_DEVREV2		0x12	/* ADT7490 only */
+
+#define REG_VTT			0x1E	/* ADT7490 only */
+#define REG_EXTEND3		0x1F	/* ADT7490 only */
+
+#define REG_VOLTAGE_BASE	0x20
 #define REG_TEMP_BASE		0x25
 #define REG_TACH_BASE		0x28
 #define REG_PWM_BASE		0x30
@@ -47,12 +54,15 @@
 
 #define REG_DEVID		0x3D
 #define REG_VENDID		0x3E
+#define REG_DEVID2		0x3F
 
 #define REG_STATUS1		0x41
 #define REG_STATUS2		0x42
 
-#define REG_VOLTAGE_MIN_BASE	0x46
-#define REG_VOLTAGE_MAX_BASE	0x47
+#define REG_VID			0x43	/* ADT7476 only */
+
+#define REG_VOLTAGE_MIN_BASE	0x44
+#define REG_VOLTAGE_MAX_BASE	0x45
 
 #define REG_TEMP_MIN_BASE	0x4E
 #define REG_TEMP_MAX_BASE	0x4F
@@ -73,16 +83,39 @@
 
 #define REG_TEMP_OFFSET_BASE	0x70
 
+#define REG_CONFIG2		0x73
+
 #define REG_EXTEND1		0x76
 #define REG_EXTEND2		0x77
+
+#define REG_CONFIG3		0x78
 #define REG_CONFIG5		0x7C
+#define REG_CONFIG4		0x7D
+
+#define REG_STATUS4		0x81	/* ADT7490 only */
+
+#define REG_VTT_MIN		0x84	/* ADT7490 only */
+#define REG_VTT_MAX		0x86	/* ADT7490 only */
+
+#define VID_VIDSEL		0x80	/* ADT7476 only */
+
+#define CONFIG2_ATTN		0x20
+
+#define CONFIG3_SMBALERT	0x01
+#define CONFIG3_THERM		0x02
+
+#define CONFIG4_PINFUNC		0x03
+#define CONFIG4_MAXDUTY		0x08
+#define CONFIG4_ATTN_IN10	0x30
+#define CONFIG4_ATTN_IN43	0xC0
 
 #define CONFIG5_TWOSCOMP	0x01
 #define CONFIG5_TEMPOFFSET	0x02
+#define CONFIG5_VIDGPIO		0x10	/* ADT7476 only */
 
 /* ADT7475 Settings */
 
-#define ADT7475_VOLTAGE_COUNT	2
+#define ADT7475_VOLTAGE_COUNT	5	/* Not counting Vtt */
 #define ADT7475_TEMP_COUNT	3
 #define ADT7475_TACH_COUNT	4
 #define ADT7475_PWM_COUNT	3
@@ -113,12 +146,15 @@
 #define TEMP_OFFSET_REG(idx) (REG_TEMP_OFFSET_BASE + (idx))
 #define TEMP_TRANGE_REG(idx) (REG_TEMP_TRANGE_BASE + (idx))
 
-static unsigned short normal_i2c[] = { 0x2e, I2C_CLIENT_END };
+static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
 
-I2C_CLIENT_INSMOD_1(adt7475);
+I2C_CLIENT_INSMOD_4(adt7473, adt7475, adt7476, adt7490);
 
 static const struct i2c_device_id adt7475_id[] = {
+	{ "adt7473", adt7473 },
 	{ "adt7475", adt7475 },
+	{ "adt7476", adt7476 },
+	{ "adt7490", adt7490 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, adt7475_id);
@@ -131,15 +167,24 @@
 	unsigned long limits_updated;
 	char valid;
 
+	u8 config4;
 	u8 config5;
-	u16 alarms;
-	u16 voltage[3][3];
+	u8 has_voltage;
+	u8 bypass_attn;		/* Bypass voltage attenuator */
+	u8 has_pwm2:1;
+	u8 has_fan4:1;
+	u8 has_vid:1;
+	u32 alarms;
+	u16 voltage[3][6];
 	u16 temp[7][3];
 	u16 tach[2][4];
 	u8 pwm[4][3];
 	u8 range[3];
 	u8 pwmctl[3];
 	u8 pwmchan[3];
+
+	u8 vid;
+	u8 vrm;
 };
 
 static struct i2c_driver adt7475_driver;
@@ -196,26 +241,35 @@
 	return SENSORS_LIMIT((90000 * 60) / rpm, 1, 0xFFFF);
 }
 
-static inline int reg2vcc(u16 reg)
+/* Scaling factors for voltage inputs, taken from the ADT7490 datasheet */
+static const int adt7473_in_scaling[ADT7475_VOLTAGE_COUNT + 1][2] = {
+	{ 45, 94 },	/* +2.5V */
+	{ 175, 525 },	/* Vccp */
+	{ 68, 71 },	/* Vcc */
+	{ 93, 47 },	/* +5V */
+	{ 120, 20 },	/* +12V */
+	{ 45, 45 },	/* Vtt */
+};
+
+static inline int reg2volt(int channel, u16 reg, u8 bypass_attn)
 {
-	return (4296 * reg) / 1000;
+	const int *r = adt7473_in_scaling[channel];
+
+	if (bypass_attn & (1 << channel))
+		return DIV_ROUND_CLOSEST(reg * 2250, 1024);
+	return DIV_ROUND_CLOSEST(reg * (r[0] + r[1]) * 2250, r[1] * 1024);
 }
 
-static inline int reg2vccp(u16 reg)
+static inline u16 volt2reg(int channel, long volt, u8 bypass_attn)
 {
-	return (2929 * reg) / 1000;
-}
+	const int *r = adt7473_in_scaling[channel];
+	long reg;
 
-static inline u16 vcc2reg(long vcc)
-{
-	vcc = SENSORS_LIMIT(vcc, 0, 4396);
-	return (vcc * 1000) / 4296;
-}
-
-static inline u16 vccp2reg(long vcc)
-{
-	vcc = SENSORS_LIMIT(vcc, 0, 2998);
-	return (vcc * 1000) / 2929;
+	if (bypass_attn & (1 << channel))
+		reg = (volt * 1024) / 2250;
+	else
+		reg = (volt * r[1] * 1024) / ((r[0] + r[1]) * 2250);
+	return SENSORS_LIMIT(reg, 0, 1023) & (0xff << 2);
 }
 
 static u16 adt7475_read_word(struct i2c_client *client, int reg)
@@ -271,12 +325,11 @@
 	switch (sattr->nr) {
 	case ALARM:
 		return sprintf(buf, "%d\n",
-			       (data->alarms >> (sattr->index + 1)) & 1);
+			       (data->alarms >> sattr->index) & 1);
 	default:
 		val = data->voltage[sattr->nr][sattr->index];
 		return sprintf(buf, "%d\n",
-			       sattr->index ==
-			       0 ? reg2vccp(val) : reg2vcc(val));
+			       reg2volt(sattr->index, val, data->bypass_attn));
 	}
 }
 
@@ -296,12 +349,19 @@
 	mutex_lock(&data->lock);
 
 	data->voltage[sattr->nr][sattr->index] =
-		sattr->index ? vcc2reg(val) : vccp2reg(val);
+				volt2reg(sattr->index, val, data->bypass_attn);
 
-	if (sattr->nr == MIN)
-		reg = VOLTAGE_MIN_REG(sattr->index);
-	else
-		reg = VOLTAGE_MAX_REG(sattr->index);
+	if (sattr->index < ADT7475_VOLTAGE_COUNT) {
+		if (sattr->nr == MIN)
+			reg = VOLTAGE_MIN_REG(sattr->index);
+		else
+			reg = VOLTAGE_MAX_REG(sattr->index);
+	} else {
+		if (sattr->nr == MIN)
+			reg = REG_VTT_MIN;
+		else
+			reg = REG_VTT_MAX;
+	}
 
 	i2c_smbus_write_byte_data(client, reg,
 				  data->voltage[sattr->nr][sattr->index] >> 2);
@@ -778,18 +838,103 @@
 	return count;
 }
 
-static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_voltage, NULL, INPUT, 0);
-static SENSOR_DEVICE_ATTR_2(in1_max, S_IRUGO | S_IWUSR, show_voltage,
+static ssize_t show_pwm_at_crit(struct device *dev,
+				struct device_attribute *devattr, char *buf)
+{
+	struct adt7475_data *data = adt7475_update_device(dev);
+	return sprintf(buf, "%d\n", !!(data->config4 & CONFIG4_MAXDUTY));
+}
+
+static ssize_t set_pwm_at_crit(struct device *dev,
+			       struct device_attribute *devattr,
+			       const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adt7475_data *data = i2c_get_clientdata(client);
+	long val;
+
+	if (strict_strtol(buf, 10, &val))
+		return -EINVAL;
+	if (val != 0 && val != 1)
+		return -EINVAL;
+
+	mutex_lock(&data->lock);
+	data->config4 = i2c_smbus_read_byte_data(client, REG_CONFIG4);
+	if (val)
+		data->config4 |= CONFIG4_MAXDUTY;
+	else
+		data->config4 &= ~CONFIG4_MAXDUTY;
+	i2c_smbus_write_byte_data(client, REG_CONFIG4, data->config4);
+	mutex_unlock(&data->lock);
+
+	return count;
+}
+
+static ssize_t show_vrm(struct device *dev, struct device_attribute *devattr,
+			char *buf)
+{
+	struct adt7475_data *data = dev_get_drvdata(dev);
+	return sprintf(buf, "%d\n", (int)data->vrm);
+}
+
+static ssize_t set_vrm(struct device *dev, struct device_attribute *devattr,
+		       const char *buf, size_t count)
+{
+	struct adt7475_data *data = dev_get_drvdata(dev);
+	long val;
+
+	if (strict_strtol(buf, 10, &val))
+		return -EINVAL;
+	if (val < 0 || val > 255)
+		return -EINVAL;
+	data->vrm = val;
+
+	return count;
+}
+
+static ssize_t show_vid(struct device *dev, struct device_attribute *devattr,
+			char *buf)
+{
+	struct adt7475_data *data = adt7475_update_device(dev);
+	return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
+}
+
+static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_voltage, NULL, INPUT, 0);
+static SENSOR_DEVICE_ATTR_2(in0_max, S_IRUGO | S_IWUSR, show_voltage,
 			    set_voltage, MAX, 0);
-static SENSOR_DEVICE_ATTR_2(in1_min, S_IRUGO | S_IWUSR, show_voltage,
+static SENSOR_DEVICE_ATTR_2(in0_min, S_IRUGO | S_IWUSR, show_voltage,
 			    set_voltage, MIN, 0);
-static SENSOR_DEVICE_ATTR_2(in1_alarm, S_IRUGO, show_voltage, NULL, ALARM, 0);
-static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_voltage, NULL, INPUT, 1);
-static SENSOR_DEVICE_ATTR_2(in2_max, S_IRUGO | S_IWUSR, show_voltage,
+static SENSOR_DEVICE_ATTR_2(in0_alarm, S_IRUGO, show_voltage, NULL, ALARM, 0);
+static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_voltage, NULL, INPUT, 1);
+static SENSOR_DEVICE_ATTR_2(in1_max, S_IRUGO | S_IWUSR, show_voltage,
 			    set_voltage, MAX, 1);
-static SENSOR_DEVICE_ATTR_2(in2_min, S_IRUGO | S_IWUSR, show_voltage,
+static SENSOR_DEVICE_ATTR_2(in1_min, S_IRUGO | S_IWUSR, show_voltage,
 			    set_voltage, MIN, 1);
-static SENSOR_DEVICE_ATTR_2(in2_alarm, S_IRUGO, show_voltage, NULL, ALARM, 1);
+static SENSOR_DEVICE_ATTR_2(in1_alarm, S_IRUGO, show_voltage, NULL, ALARM, 1);
+static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_voltage, NULL, INPUT, 2);
+static SENSOR_DEVICE_ATTR_2(in2_max, S_IRUGO | S_IWUSR, show_voltage,
+			    set_voltage, MAX, 2);
+static SENSOR_DEVICE_ATTR_2(in2_min, S_IRUGO | S_IWUSR, show_voltage,
+			    set_voltage, MIN, 2);
+static SENSOR_DEVICE_ATTR_2(in2_alarm, S_IRUGO, show_voltage, NULL, ALARM, 2);
+static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, show_voltage, NULL, INPUT, 3);
+static SENSOR_DEVICE_ATTR_2(in3_max, S_IRUGO | S_IWUSR, show_voltage,
+			    set_voltage, MAX, 3);
+static SENSOR_DEVICE_ATTR_2(in3_min, S_IRUGO | S_IWUSR, show_voltage,
+			    set_voltage, MIN, 3);
+static SENSOR_DEVICE_ATTR_2(in3_alarm, S_IRUGO, show_voltage, NULL, ALARM, 3);
+static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, show_voltage, NULL, INPUT, 4);
+static SENSOR_DEVICE_ATTR_2(in4_max, S_IRUGO | S_IWUSR, show_voltage,
+			    set_voltage, MAX, 4);
+static SENSOR_DEVICE_ATTR_2(in4_min, S_IRUGO | S_IWUSR, show_voltage,
+			    set_voltage, MIN, 4);
+static SENSOR_DEVICE_ATTR_2(in4_alarm, S_IRUGO, show_voltage, NULL, ALARM, 8);
+static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO, show_voltage, NULL, INPUT, 5);
+static SENSOR_DEVICE_ATTR_2(in5_max, S_IRUGO | S_IWUSR, show_voltage,
+			    set_voltage, MAX, 5);
+static SENSOR_DEVICE_ATTR_2(in5_min, S_IRUGO | S_IWUSR, show_voltage,
+			    set_voltage, MIN, 5);
+static SENSOR_DEVICE_ATTR_2(in5_alarm, S_IRUGO, show_voltage, NULL, ALARM, 31);
 static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, INPUT, 0);
 static SENSOR_DEVICE_ATTR_2(temp1_alarm, S_IRUGO, show_temp, NULL, ALARM, 0);
 static SENSOR_DEVICE_ATTR_2(temp1_fault, S_IRUGO, show_temp, NULL, FAULT, 0);
@@ -893,6 +1038,13 @@
 static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO | S_IWUSR, show_pwm,
 			    set_pwm, MAX, 2);
 
+/* Non-standard name, might need revisiting */
+static DEVICE_ATTR(pwm_use_point2_pwm_at_crit, S_IWUSR | S_IRUGO,
+		   show_pwm_at_crit, set_pwm_at_crit);
+
+static DEVICE_ATTR(vrm, S_IWUSR | S_IRUGO, show_vrm, set_vrm);
+static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
+
 static struct attribute *adt7475_attrs[] = {
 	&sensor_dev_attr_in1_input.dev_attr.attr,
 	&sensor_dev_attr_in1_max.dev_attr.attr,
@@ -940,60 +1092,156 @@
 	&sensor_dev_attr_fan3_input.dev_attr.attr,
 	&sensor_dev_attr_fan3_min.dev_attr.attr,
 	&sensor_dev_attr_fan3_alarm.dev_attr.attr,
-	&sensor_dev_attr_fan4_input.dev_attr.attr,
-	&sensor_dev_attr_fan4_min.dev_attr.attr,
-	&sensor_dev_attr_fan4_alarm.dev_attr.attr,
 	&sensor_dev_attr_pwm1.dev_attr.attr,
 	&sensor_dev_attr_pwm1_freq.dev_attr.attr,
 	&sensor_dev_attr_pwm1_enable.dev_attr.attr,
 	&sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr,
 	&sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
 	&sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
-	&sensor_dev_attr_pwm2.dev_attr.attr,
-	&sensor_dev_attr_pwm2_freq.dev_attr.attr,
-	&sensor_dev_attr_pwm2_enable.dev_attr.attr,
-	&sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr,
-	&sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
-	&sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
 	&sensor_dev_attr_pwm3.dev_attr.attr,
 	&sensor_dev_attr_pwm3_freq.dev_attr.attr,
 	&sensor_dev_attr_pwm3_enable.dev_attr.attr,
 	&sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr,
 	&sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
 	&sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr,
+	&dev_attr_pwm_use_point2_pwm_at_crit.attr,
 	NULL,
 };
 
-struct attribute_group adt7475_attr_group = { .attrs = adt7475_attrs };
+static struct attribute *fan4_attrs[] = {
+	&sensor_dev_attr_fan4_input.dev_attr.attr,
+	&sensor_dev_attr_fan4_min.dev_attr.attr,
+	&sensor_dev_attr_fan4_alarm.dev_attr.attr,
+	NULL
+};
+
+static struct attribute *pwm2_attrs[] = {
+	&sensor_dev_attr_pwm2.dev_attr.attr,
+	&sensor_dev_attr_pwm2_freq.dev_attr.attr,
+	&sensor_dev_attr_pwm2_enable.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
+	NULL
+};
+
+static struct attribute *in0_attrs[] = {
+	&sensor_dev_attr_in0_input.dev_attr.attr,
+	&sensor_dev_attr_in0_max.dev_attr.attr,
+	&sensor_dev_attr_in0_min.dev_attr.attr,
+	&sensor_dev_attr_in0_alarm.dev_attr.attr,
+	NULL
+};
+
+static struct attribute *in3_attrs[] = {
+	&sensor_dev_attr_in3_input.dev_attr.attr,
+	&sensor_dev_attr_in3_max.dev_attr.attr,
+	&sensor_dev_attr_in3_min.dev_attr.attr,
+	&sensor_dev_attr_in3_alarm.dev_attr.attr,
+	NULL
+};
+
+static struct attribute *in4_attrs[] = {
+	&sensor_dev_attr_in4_input.dev_attr.attr,
+	&sensor_dev_attr_in4_max.dev_attr.attr,
+	&sensor_dev_attr_in4_min.dev_attr.attr,
+	&sensor_dev_attr_in4_alarm.dev_attr.attr,
+	NULL
+};
+
+static struct attribute *in5_attrs[] = {
+	&sensor_dev_attr_in5_input.dev_attr.attr,
+	&sensor_dev_attr_in5_max.dev_attr.attr,
+	&sensor_dev_attr_in5_min.dev_attr.attr,
+	&sensor_dev_attr_in5_alarm.dev_attr.attr,
+	NULL
+};
+
+static struct attribute *vid_attrs[] = {
+	&dev_attr_cpu0_vid.attr,
+	&dev_attr_vrm.attr,
+	NULL
+};
+
+static struct attribute_group adt7475_attr_group = { .attrs = adt7475_attrs };
+static struct attribute_group fan4_attr_group = { .attrs = fan4_attrs };
+static struct attribute_group pwm2_attr_group = { .attrs = pwm2_attrs };
+static struct attribute_group in0_attr_group = { .attrs = in0_attrs };
+static struct attribute_group in3_attr_group = { .attrs = in3_attrs };
+static struct attribute_group in4_attr_group = { .attrs = in4_attrs };
+static struct attribute_group in5_attr_group = { .attrs = in5_attrs };
+static struct attribute_group vid_attr_group = { .attrs = vid_attrs };
 
 static int adt7475_detect(struct i2c_client *client, int kind,
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
+	int vendid, devid, devid2;
+	const char *name;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	if (kind <= 0) {
-		if (adt7475_read(REG_VENDID) != 0x41 ||
-		    adt7475_read(REG_DEVID) != 0x75) {
-			dev_err(&adapter->dev,
-				"Couldn't detect a adt7475 part at 0x%02x\n",
-				(unsigned int)client->addr);
-			return -ENODEV;
-		}
+	vendid = adt7475_read(REG_VENDID);
+	devid2 = adt7475_read(REG_DEVID2);
+	if (vendid != 0x41 ||		/* Analog Devices */
+	    (devid2 & 0xf8) != 0x68)
+		return -ENODEV;
+
+	devid = adt7475_read(REG_DEVID);
+	if (devid == 0x73)
+		name = "adt7473";
+	else if (devid == 0x75 && client->addr == 0x2e)
+		name = "adt7475";
+	else if (devid == 0x76)
+		name = "adt7476";
+	else if ((devid2 & 0xfc) == 0x6c)
+		name = "adt7490";
+	else {
+		dev_dbg(&adapter->dev,
+			"Couldn't detect an ADT7473/75/76/90 part at "
+			"0x%02x\n", (unsigned int)client->addr);
+		return -ENODEV;
 	}
 
-	strlcpy(info->type, adt7475_id[0].name, I2C_NAME_SIZE);
+	strlcpy(info->type, name, I2C_NAME_SIZE);
 
 	return 0;
 }
 
+static void adt7475_remove_files(struct i2c_client *client,
+				 struct adt7475_data *data)
+{
+	sysfs_remove_group(&client->dev.kobj, &adt7475_attr_group);
+	if (data->has_fan4)
+		sysfs_remove_group(&client->dev.kobj, &fan4_attr_group);
+	if (data->has_pwm2)
+		sysfs_remove_group(&client->dev.kobj, &pwm2_attr_group);
+	if (data->has_voltage & (1 << 0))
+		sysfs_remove_group(&client->dev.kobj, &in0_attr_group);
+	if (data->has_voltage & (1 << 3))
+		sysfs_remove_group(&client->dev.kobj, &in3_attr_group);
+	if (data->has_voltage & (1 << 4))
+		sysfs_remove_group(&client->dev.kobj, &in4_attr_group);
+	if (data->has_voltage & (1 << 5))
+		sysfs_remove_group(&client->dev.kobj, &in5_attr_group);
+	if (data->has_vid)
+		sysfs_remove_group(&client->dev.kobj, &vid_attr_group);
+}
+
 static int adt7475_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 {
+	static const char *names[] = {
+		[adt7473] = "ADT7473",
+		[adt7475] = "ADT7475",
+		[adt7476] = "ADT7476",
+		[adt7490] = "ADT7490",
+	};
+
 	struct adt7475_data *data;
-	int i, ret = 0;
+	int i, ret = 0, revision;
+	u8 config2, config3;
 
 	data = kzalloc(sizeof(*data), GFP_KERNEL);
 	if (data == NULL)
@@ -1002,6 +1250,70 @@
 	mutex_init(&data->lock);
 	i2c_set_clientdata(client, data);
 
+	/* Initialize device-specific values */
+	switch (id->driver_data) {
+	case adt7476:
+		data->has_voltage = 0x0e;	/* in1 to in3 */
+		revision = adt7475_read(REG_DEVID2) & 0x07;
+		break;
+	case adt7490:
+		data->has_voltage = 0x3e;	/* in1 to in5 */
+		revision = adt7475_read(REG_DEVID2) & 0x03;
+		if (revision == 0x03)
+			revision += adt7475_read(REG_DEVREV2);
+		break;
+	default:
+		data->has_voltage = 0x06;	/* in1, in2 */
+		revision = adt7475_read(REG_DEVID2) & 0x07;
+	}
+
+	config3 = adt7475_read(REG_CONFIG3);
+	/* Pin PWM2 may alternatively be used for ALERT output */
+	if (!(config3 & CONFIG3_SMBALERT))
+		data->has_pwm2 = 1;
+	/* Meaning of this bit is inverted for the ADT7473-1 */
+	if (id->driver_data == adt7473 && revision >= 1)
+		data->has_pwm2 = !data->has_pwm2;
+
+	data->config4 = adt7475_read(REG_CONFIG4);
+	/* Pin TACH4 may alternatively be used for THERM */
+	if ((data->config4 & CONFIG4_PINFUNC) == 0x0)
+		data->has_fan4 = 1;
+
+	/* THERM configuration is more complex on the ADT7476 and ADT7490,
+	   because 2 different pins (TACH4 and +2.5 Vin) can be used for
+	   this function */
+	if (id->driver_data == adt7490) {
+		if ((data->config4 & CONFIG4_PINFUNC) == 0x1 &&
+		    !(config3 & CONFIG3_THERM))
+			data->has_fan4 = 1;
+	}
+	if (id->driver_data == adt7476 || id->driver_data == adt7490) {
+		if (!(config3 & CONFIG3_THERM) ||
+		    (data->config4 & CONFIG4_PINFUNC) == 0x1)
+			data->has_voltage |= (1 << 0);		/* in0 */
+	}
+
+	/* On the ADT7476, the +12V input pin may instead be used as VID5,
+	   and VID pins may alternatively be used as GPIO */
+	if (id->driver_data == adt7476) {
+		u8 vid = adt7475_read(REG_VID);
+		if (!(vid & VID_VIDSEL))
+			data->has_voltage |= (1 << 4);		/* in4 */
+
+		data->has_vid = !(adt7475_read(REG_CONFIG5) & CONFIG5_VIDGPIO);
+	}
+
+	/* Voltage attenuators can be bypassed, globally or individually */
+	config2 = adt7475_read(REG_CONFIG2);
+	if (config2 & CONFIG2_ATTN) {
+		data->bypass_attn = (0x3 << 3) | 0x3;
+	} else {
+		data->bypass_attn = ((data->config4 & CONFIG4_ATTN_IN10) >> 4) |
+				    ((data->config4 & CONFIG4_ATTN_IN43) >> 3);
+	}
+	data->bypass_attn &= data->has_voltage;
+
 	/* Call adt7475_read_pwm for all pwm's as this will reprogram any
 	   pwm's which are disabled to manual mode with 0% duty cycle */
 	for (i = 0; i < ADT7475_PWM_COUNT; i++)
@@ -1011,16 +1323,70 @@
 	if (ret)
 		goto efree;
 
+	/* Features that can be disabled individually */
+	if (data->has_fan4) {
+		ret = sysfs_create_group(&client->dev.kobj, &fan4_attr_group);
+		if (ret)
+			goto eremove;
+	}
+	if (data->has_pwm2) {
+		ret = sysfs_create_group(&client->dev.kobj, &pwm2_attr_group);
+		if (ret)
+			goto eremove;
+	}
+	if (data->has_voltage & (1 << 0)) {
+		ret = sysfs_create_group(&client->dev.kobj, &in0_attr_group);
+		if (ret)
+			goto eremove;
+	}
+	if (data->has_voltage & (1 << 3)) {
+		ret = sysfs_create_group(&client->dev.kobj, &in3_attr_group);
+		if (ret)
+			goto eremove;
+	}
+	if (data->has_voltage & (1 << 4)) {
+		ret = sysfs_create_group(&client->dev.kobj, &in4_attr_group);
+		if (ret)
+			goto eremove;
+	}
+	if (data->has_voltage & (1 << 5)) {
+		ret = sysfs_create_group(&client->dev.kobj, &in5_attr_group);
+		if (ret)
+			goto eremove;
+	}
+	if (data->has_vid) {
+		data->vrm = vid_which_vrm();
+		ret = sysfs_create_group(&client->dev.kobj, &vid_attr_group);
+		if (ret)
+			goto eremove;
+	}
+
 	data->hwmon_dev = hwmon_device_register(&client->dev);
 	if (IS_ERR(data->hwmon_dev)) {
 		ret = PTR_ERR(data->hwmon_dev);
 		goto eremove;
 	}
 
+	dev_info(&client->dev, "%s device, revision %d\n",
+		 names[id->driver_data], revision);
+	if ((data->has_voltage & 0x11) || data->has_fan4 || data->has_pwm2)
+		dev_info(&client->dev, "Optional features:%s%s%s%s%s\n",
+			 (data->has_voltage & (1 << 0)) ? " in0" : "",
+			 (data->has_voltage & (1 << 4)) ? " in4" : "",
+			 data->has_fan4 ? " fan4" : "",
+			 data->has_pwm2 ? " pwm2" : "",
+			 data->has_vid ? " vid" : "");
+	if (data->bypass_attn)
+		dev_info(&client->dev, "Bypassing attenuators on:%s%s%s%s\n",
+			 (data->bypass_attn & (1 << 0)) ? " in0" : "",
+			 (data->bypass_attn & (1 << 1)) ? " in1" : "",
+			 (data->bypass_attn & (1 << 3)) ? " in3" : "",
+			 (data->bypass_attn & (1 << 4)) ? " in4" : "");
+
 	return 0;
 
 eremove:
-	sysfs_remove_group(&client->dev.kobj, &adt7475_attr_group);
+	adt7475_remove_files(client, data);
 efree:
 	kfree(data);
 	return ret;
@@ -1031,7 +1397,7 @@
 	struct adt7475_data *data = i2c_get_clientdata(client);
 
 	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &adt7475_attr_group);
+	adt7475_remove_files(client, data);
 	kfree(data);
 
 	return 0;
@@ -1116,7 +1482,7 @@
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adt7475_data *data = i2c_get_clientdata(client);
-	u8 ext;
+	u16 ext;
 	int i;
 
 	mutex_lock(&data->lock);
@@ -1127,25 +1493,44 @@
 		data->alarms = adt7475_read(REG_STATUS2) << 8;
 		data->alarms |= adt7475_read(REG_STATUS1);
 
-		ext = adt7475_read(REG_EXTEND1);
-		for (i = 0; i < ADT7475_VOLTAGE_COUNT; i++)
+		ext = (adt7475_read(REG_EXTEND2) << 8) |
+			adt7475_read(REG_EXTEND1);
+		for (i = 0; i < ADT7475_VOLTAGE_COUNT; i++) {
+			if (!(data->has_voltage & (1 << i)))
+				continue;
 			data->voltage[INPUT][i] =
 				(adt7475_read(VOLTAGE_REG(i)) << 2) |
-				((ext >> ((i + 1) * 2)) & 3);
+				((ext >> (i * 2)) & 3);
+		}
 
-		ext = adt7475_read(REG_EXTEND2);
 		for (i = 0; i < ADT7475_TEMP_COUNT; i++)
 			data->temp[INPUT][i] =
 				(adt7475_read(TEMP_REG(i)) << 2) |
-				((ext >> ((i + 1) * 2)) & 3);
+				((ext >> ((i + 5) * 2)) & 3);
 
-		for (i = 0; i < ADT7475_TACH_COUNT; i++)
+		if (data->has_voltage & (1 << 5)) {
+			data->alarms |= adt7475_read(REG_STATUS4) << 24;
+			ext = adt7475_read(REG_EXTEND3);
+			data->voltage[INPUT][5] = adt7475_read(REG_VTT) << 2 |
+				((ext >> 4) & 3);
+		}
+
+		for (i = 0; i < ADT7475_TACH_COUNT; i++) {
+			if (i == 3 && !data->has_fan4)
+				continue;
 			data->tach[INPUT][i] =
 				adt7475_read_word(client, TACH_REG(i));
+		}
 
 		/* Updated by hw when in auto mode */
-		for (i = 0; i < ADT7475_PWM_COUNT; i++)
+		for (i = 0; i < ADT7475_PWM_COUNT; i++) {
+			if (i == 1 && !data->has_pwm2)
+				continue;
 			data->pwm[INPUT][i] = adt7475_read(PWM_REG(i));
+		}
+
+		if (data->has_vid)
+			data->vid = adt7475_read(REG_VID) & 0x3f;
 
 		data->measure_updated = jiffies;
 	}
@@ -1153,9 +1538,12 @@
 	/* Limits and settings, should never change update every 60 seconds */
 	if (time_after(jiffies, data->limits_updated + HZ * 60) ||
 	    !data->valid) {
+		data->config4 = adt7475_read(REG_CONFIG4);
 		data->config5 = adt7475_read(REG_CONFIG5);
 
 		for (i = 0; i < ADT7475_VOLTAGE_COUNT; i++) {
+			if (!(data->has_voltage & (1 << i)))
+				continue;
 			/* Adjust values so they match the input precision */
 			data->voltage[MIN][i] =
 				adt7475_read(VOLTAGE_MIN_REG(i)) << 2;
@@ -1163,6 +1551,11 @@
 				adt7475_read(VOLTAGE_MAX_REG(i)) << 2;
 		}
 
+		if (data->has_voltage & (1 << 5)) {
+			data->voltage[MIN][5] = adt7475_read(REG_VTT_MIN) << 2;
+			data->voltage[MAX][5] = adt7475_read(REG_VTT_MAX) << 2;
+		}
+
 		for (i = 0; i < ADT7475_TEMP_COUNT; i++) {
 			/* Adjust values so they match the input precision */
 			data->temp[MIN][i] =
@@ -1178,11 +1571,16 @@
 		}
 		adt7475_read_hystersis(client);
 
-		for (i = 0; i < ADT7475_TACH_COUNT; i++)
+		for (i = 0; i < ADT7475_TACH_COUNT; i++) {
+			if (i == 3 && !data->has_fan4)
+				continue;
 			data->tach[MIN][i] =
 				adt7475_read_word(client, TACH_MIN_REG(i));
+		}
 
 		for (i = 0; i < ADT7475_PWM_COUNT; i++) {
+			if (i == 1 && !data->has_pwm2)
+				continue;
 			data->pwm[MAX][i] = adt7475_read(PWM_MAX_REG(i));
 			data->pwm[MIN][i] = adt7475_read(PWM_MIN_REG(i));
 			/* Set the channel and control information */
diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c
index 8acf829..480f80e 100644
--- a/drivers/hwmon/asb100.c
+++ b/drivers/hwmon/asb100.c
@@ -701,6 +701,7 @@
 			 struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
+	int val1, val2;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
 		pr_debug("asb100.o: detect failed, "
@@ -708,50 +709,30 @@
 		return -ENODEV;
 	}
 
-	/* The chip may be stuck in some other bank than bank 0. This may
-	   make reading other information impossible. Specify a force=... or
-	   force_*=... parameter, and the chip will be reset to the right
-	   bank. */
-	if (kind < 0) {
+	val1 = i2c_smbus_read_byte_data(client, ASB100_REG_BANK);
+	val2 = i2c_smbus_read_byte_data(client, ASB100_REG_CHIPMAN);
 
-		int val1 = i2c_smbus_read_byte_data(client, ASB100_REG_BANK);
-		int val2 = i2c_smbus_read_byte_data(client, ASB100_REG_CHIPMAN);
+	/* If we're in bank 0 */
+	if ((!(val1 & 0x07)) &&
+			/* Check for ASB100 ID (low byte) */
+			(((!(val1 & 0x80)) && (val2 != 0x94)) ||
+			/* Check for ASB100 ID (high byte ) */
+			((val1 & 0x80) && (val2 != 0x06)))) {
+		pr_debug("asb100: detect failed, bad chip id 0x%02x!\n", val2);
+		return -ENODEV;
+	}
 
-		/* If we're in bank 0 */
-		if ((!(val1 & 0x07)) &&
-				/* Check for ASB100 ID (low byte) */
-				(((!(val1 & 0x80)) && (val2 != 0x94)) ||
-				/* Check for ASB100 ID (high byte ) */
-				((val1 & 0x80) && (val2 != 0x06)))) {
-			pr_debug("asb100.o: detect failed, "
-					"bad chip id 0x%02x!\n", val2);
-			return -ENODEV;
-		}
-
-	} /* kind < 0 */
-
-	/* We have either had a force parameter, or we have already detected
-	   Winbond. Put it now into bank 0 and Vendor ID High Byte */
+	/* Put it now into bank 0 and Vendor ID High Byte */
 	i2c_smbus_write_byte_data(client, ASB100_REG_BANK,
 		(i2c_smbus_read_byte_data(client, ASB100_REG_BANK) & 0x78)
 		| 0x80);
 
 	/* Determine the chip type. */
-	if (kind <= 0) {
-		int val1 = i2c_smbus_read_byte_data(client, ASB100_REG_WCHIPID);
-		int val2 = i2c_smbus_read_byte_data(client, ASB100_REG_CHIPMAN);
+	val1 = i2c_smbus_read_byte_data(client, ASB100_REG_WCHIPID);
+	val2 = i2c_smbus_read_byte_data(client, ASB100_REG_CHIPMAN);
 
-		if ((val1 == 0x31) && (val2 == 0x06))
-			kind = asb100;
-		else {
-			if (kind == 0)
-				dev_warn(&adapter->dev, "ignoring "
-					"'force' parameter for unknown chip "
-					"at adapter %d, address 0x%02x.\n",
-					i2c_adapter_id(adapter), client->addr);
-			return -ENODEV;
-		}
-	}
+	if (val1 != 0x31 || val2 != 0x06)
+		return -ENODEV;
 
 	strlcpy(info->type, "asb100", I2C_NAME_SIZE);
 
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c
index 27d6257..4377bb0 100644
--- a/drivers/hwmon/dme1737.c
+++ b/drivers/hwmon/dme1737.c
@@ -2220,33 +2220,23 @@
 		return -ENODEV;
 	}
 
-	/* A negative kind means that the driver was loaded with no force
-	 * parameter (default), so we must identify the chip. */
-	if (kind < 0) {
-		company = i2c_smbus_read_byte_data(client, DME1737_REG_COMPANY);
-		verstep = i2c_smbus_read_byte_data(client, DME1737_REG_VERSTEP);
+	company = i2c_smbus_read_byte_data(client, DME1737_REG_COMPANY);
+	verstep = i2c_smbus_read_byte_data(client, DME1737_REG_VERSTEP);
 
-		if (company == DME1737_COMPANY_SMSC &&
-		    (verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP) {
-			kind = dme1737;
-		} else if (company == DME1737_COMPANY_SMSC &&
-			   verstep == SCH5027_VERSTEP) {
-			kind = sch5027;
-		} else {
-			return -ENODEV;
-		}
-	}
-
-	if (kind == sch5027) {
+	if (company == DME1737_COMPANY_SMSC &&
+	    verstep == SCH5027_VERSTEP) {
 		name = "sch5027";
-	} else {
-		kind = dme1737;
+
+	} else if (company == DME1737_COMPANY_SMSC &&
+		   (verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP) {
 		name = "dme1737";
+	} else {
+		return -ENODEV;
 	}
 
 	dev_info(dev, "Found a %s chip at 0x%02x (rev 0x%02x).\n",
-		 kind == sch5027 ? "SCH5027" : "DME1737", client->addr,
-		 verstep);
+		 verstep == SCH5027_VERSTEP ? "SCH5027" : "DME1737",
+		 client->addr, verstep);
 	strlcpy(info->type, name, I2C_NAME_SIZE);
 
 	return 0;
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c
index 53f88f5..2a4c6a0 100644
--- a/drivers/hwmon/ds1621.c
+++ b/drivers/hwmon/ds1621.c
@@ -237,20 +237,16 @@
 		return -ENODEV;
 
 	/* Now, we do the remaining detection. It is lousy. */
-	if (kind < 0) {
-		/* The NVB bit should be low if no EEPROM write has been 
-		   requested during the latest 10ms, which is highly 
-		   improbable in our case. */
-		conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF);
-		if (conf < 0 || conf & DS1621_REG_CONFIG_NVB)
+	/* The NVB bit should be low if no EEPROM write has been  requested
+	   during the latest 10ms, which is highly improbable in our case. */
+	conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF);
+	if (conf < 0 || conf & DS1621_REG_CONFIG_NVB)
+		return -ENODEV;
+	/* The 7 lowest bits of a temperature should always be 0. */
+	for (i = 0; i < ARRAY_SIZE(DS1621_REG_TEMP); i++) {
+		temp = i2c_smbus_read_word_data(client, DS1621_REG_TEMP[i]);
+		if (temp < 0 || (temp & 0x7f00))
 			return -ENODEV;
-		/* The 7 lowest bits of a temperature should always be 0. */
-		for (i = 0; i < ARRAY_SIZE(DS1621_REG_TEMP); i++) {
-			temp = i2c_smbus_read_word_data(client,
-							DS1621_REG_TEMP[i]);
-			if (temp < 0 || (temp & 0x7f00))
-				return -ENODEV;
-		}
 	}
 
 	strlcpy(info->type, "ds1621", I2C_NAME_SIZE);
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 4146105..a95fa42 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -48,6 +48,7 @@
 #define SIO_F71858_ID		0x0507  /* Chipset ID */
 #define SIO_F71862_ID		0x0601	/* Chipset ID */
 #define SIO_F71882_ID		0x0541	/* Chipset ID */
+#define SIO_F71889_ID		0x0723	/* Chipset ID */
 #define SIO_F8000_ID		0x0581	/* Chipset ID */
 
 #define REGION_LENGTH		8
@@ -95,12 +96,13 @@
 module_param(force_id, ushort, 0);
 MODULE_PARM_DESC(force_id, "Override the detected device ID");
 
-enum chips { f71858fg, f71862fg, f71882fg, f8000 };
+enum chips { f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
 
 static const char *f71882fg_names[] = {
 	"f71858fg",
 	"f71862fg",
 	"f71882fg",
+	"f71889fg",
 	"f8000",
 };
 
@@ -155,7 +157,7 @@
 	u8	pwm_auto_point_hyst[2];
 	u8	pwm_auto_point_mapping[4];
 	u8	pwm_auto_point_pwm[4][5];
-	u8	pwm_auto_point_temp[4][4];
+	s8	pwm_auto_point_temp[4][4];
 };
 
 /* Sysfs in */
@@ -258,7 +260,9 @@
 
 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
 
-/* Temp and in attr for the f71858fg */
+/* Temp and in attr for the f71858fg, the f71858fg is special as it
+   has its temperature indexes start at 0 (the others start at 1) and
+   it only has 3 voltage inputs */
 static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = {
 	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
 	SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
@@ -302,8 +306,8 @@
 	SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
 };
 
-/* Temp and in attr common to both the f71862fg and f71882fg */
-static struct sensor_device_attribute_2 f718x2fg_in_temp_attr[] = {
+/* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
 	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
 	SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
 	SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
@@ -371,8 +375,8 @@
 	SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3),
 };
 
-/* Temp and in attr found only on the f71882fg */
-static struct sensor_device_attribute_2 f71882fg_in_temp_attr[] = {
+/* For models with in1 alarm capability */
+static struct sensor_device_attribute_2 fxxxx_in1_alarm_attr[] = {
 	SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max,
 		0, 1),
 	SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep,
@@ -383,6 +387,7 @@
 /* Temp and in attr for the f8000
    Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max)
    is used as hysteresis value to clear alarms
+   Also like the f71858fg its temperature indexes start at 0
  */
 static struct sensor_device_attribute_2 f8000_in_temp_attr[] = {
 	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
@@ -413,61 +418,70 @@
 };
 
 /* Fan / PWM attr common to all models */
-static struct sensor_device_attribute_2 fxxxx_fan_attr[] = {
+static struct sensor_device_attribute_2 fxxxx_fan_attr[4][6] = { {
 	SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0),
 	SENSOR_ATTR_2(fan1_full_speed, S_IRUGO|S_IWUSR,
 		      show_fan_full_speed,
 		      store_fan_full_speed, 0, 0),
 	SENSOR_ATTR_2(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 0),
-	SENSOR_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 0, 1),
-	SENSOR_ATTR_2(fan2_full_speed, S_IRUGO|S_IWUSR,
-		      show_fan_full_speed,
-		      store_fan_full_speed, 0, 1),
-	SENSOR_ATTR_2(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 1),
-	SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
-	SENSOR_ATTR_2(fan3_full_speed, S_IRUGO|S_IWUSR,
-		      show_fan_full_speed,
-		      store_fan_full_speed, 0, 2),
-	SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
-
 	SENSOR_ATTR_2(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 0),
 	SENSOR_ATTR_2(pwm1_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
 		      store_pwm_enable, 0, 0),
 	SENSOR_ATTR_2(pwm1_interpolate, S_IRUGO|S_IWUSR,
 		      show_pwm_interpolate, store_pwm_interpolate, 0, 0),
-	SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
-		      show_pwm_auto_point_channel,
-		      store_pwm_auto_point_channel, 0, 0),
-
+}, {
+	SENSOR_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 0, 1),
+	SENSOR_ATTR_2(fan2_full_speed, S_IRUGO|S_IWUSR,
+		      show_fan_full_speed,
+		      store_fan_full_speed, 0, 1),
+	SENSOR_ATTR_2(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 1),
 	SENSOR_ATTR_2(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 1),
 	SENSOR_ATTR_2(pwm2_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
 		      store_pwm_enable, 0, 1),
 	SENSOR_ATTR_2(pwm2_interpolate, S_IRUGO|S_IWUSR,
 		      show_pwm_interpolate, store_pwm_interpolate, 0, 1),
-	SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
-		      show_pwm_auto_point_channel,
-		      store_pwm_auto_point_channel, 0, 1),
-
+}, {
+	SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
+	SENSOR_ATTR_2(fan3_full_speed, S_IRUGO|S_IWUSR,
+		      show_fan_full_speed,
+		      store_fan_full_speed, 0, 2),
+	SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
 	SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
 	SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
 		      store_pwm_enable, 0, 2),
 	SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR,
 		      show_pwm_interpolate, store_pwm_interpolate, 0, 2),
-	SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
-		      show_pwm_auto_point_channel,
-		      store_pwm_auto_point_channel, 0, 2),
-};
+}, {
+	SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
+	SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,
+		      show_fan_full_speed,
+		      store_fan_full_speed, 0, 3),
+	SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3),
+	SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3),
+	SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
+		      store_pwm_enable, 0, 3),
+	SENSOR_ATTR_2(pwm4_interpolate, S_IRUGO|S_IWUSR,
+		      show_pwm_interpolate, store_pwm_interpolate, 0, 3),
+} };
 
-/* Fan / PWM attr for the f71862fg, less pwms and less zones per pwm than the
-   f71882fg */
-static struct sensor_device_attribute_2 f71862fg_fan_attr[] = {
+/* Attr for models which can beep on Fan alarm */
+static struct sensor_device_attribute_2 fxxxx_fan_beep_attr[] = {
 	SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
 		store_fan_beep, 0, 0),
 	SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
 		store_fan_beep, 0, 1),
 	SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
 		store_fan_beep, 0, 2),
+	SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
+		store_fan_beep, 0, 3),
+};
 
+/* PWM attr for the f71862fg, fewer pwms and fewer zones per pwm than the
+   f71858fg / f71882fg / f71889fg */
+static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[] = {
+	SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_channel,
+		      store_pwm_auto_point_channel, 0, 0),
 	SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
 		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 		      1, 0),
@@ -487,6 +501,9 @@
 	SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
 		      show_pwm_auto_point_temp_hyst, NULL, 3, 0),
 
+	SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_channel,
+		      store_pwm_auto_point_channel, 0, 1),
 	SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
 		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 		      1, 1),
@@ -506,6 +523,9 @@
 	SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
 		      show_pwm_auto_point_temp_hyst, NULL, 3, 1),
 
+	SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_channel,
+		      store_pwm_auto_point_channel, 0, 2),
 	SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
 		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 		      1, 2),
@@ -526,8 +546,11 @@
 		      show_pwm_auto_point_temp_hyst, NULL, 3, 2),
 };
 
-/* Fan / PWM attr common to both the f71882fg and f71858fg */
-static struct sensor_device_attribute_2 f71882fg_f71858fg_fan_attr[] = {
+/* PWM attr common to the f71858fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 fxxxx_auto_pwm_attr[4][14] = { {
+	SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_channel,
+		      store_pwm_auto_point_channel, 0, 0),
 	SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
 		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 		      0, 0),
@@ -565,7 +588,10 @@
 		      show_pwm_auto_point_temp_hyst, NULL, 2, 0),
 	SENSOR_ATTR_2(pwm1_auto_point4_temp_hyst, S_IRUGO,
 		      show_pwm_auto_point_temp_hyst, NULL, 3, 0),
-
+}, {
+	SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_channel,
+		      store_pwm_auto_point_channel, 0, 1),
 	SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
 		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 		      0, 1),
@@ -603,7 +629,10 @@
 		      show_pwm_auto_point_temp_hyst, NULL, 2, 1),
 	SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO,
 		      show_pwm_auto_point_temp_hyst, NULL, 3, 1),
-
+}, {
+	SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_channel,
+		      store_pwm_auto_point_channel, 0, 2),
 	SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
 		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 		      0, 2),
@@ -641,30 +670,7 @@
 		      show_pwm_auto_point_temp_hyst, NULL, 2, 2),
 	SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO,
 		      show_pwm_auto_point_temp_hyst, NULL, 3, 2),
-};
-
-/* Fan / PWM attr found on the f71882fg but not on the f71858fg */
-static struct sensor_device_attribute_2 f71882fg_fan_attr[] = {
-	SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
-		store_fan_beep, 0, 0),
-	SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
-		store_fan_beep, 0, 1),
-	SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
-		store_fan_beep, 0, 2),
-
-	SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
-	SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,
-		      show_fan_full_speed,
-		      store_fan_full_speed, 0, 3),
-	SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
-		store_fan_beep, 0, 3),
-	SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3),
-
-	SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3),
-	SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
-		      store_pwm_enable, 0, 3),
-	SENSOR_ATTR_2(pwm4_interpolate, S_IRUGO|S_IWUSR,
-		      show_pwm_interpolate, store_pwm_interpolate, 0, 3),
+}, {
 	SENSOR_ATTR_2(pwm4_auto_channels_temp, S_IRUGO|S_IWUSR,
 		      show_pwm_auto_point_channel,
 		      store_pwm_auto_point_channel, 0, 3),
@@ -705,14 +711,20 @@
 		      show_pwm_auto_point_temp_hyst, NULL, 2, 3),
 	SENSOR_ATTR_2(pwm4_auto_point4_temp_hyst, S_IRUGO,
 		      show_pwm_auto_point_temp_hyst, NULL, 3, 3),
-};
+} };
 
-/* Fan / PWM attr for the f8000, zones mapped to temp instead of to pwm!
-   Also the register block at offset A0 maps to TEMP1 (so our temp2, as the
-   F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0 */
+/* Fan attr specific to the f8000 (4th fan input can only measure speed) */
 static struct sensor_device_attribute_2 f8000_fan_attr[] = {
 	SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
+};
 
+/* PWM attr for the f8000, zones mapped to temp instead of to pwm!
+   Also the register block at offset A0 maps to TEMP1 (so our temp2, as the
+   F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0 */
+static struct sensor_device_attribute_2 f8000_auto_pwm_attr[] = {
+	SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_channel,
+		      store_pwm_auto_point_channel, 0, 0),
 	SENSOR_ATTR_2(temp1_auto_point1_pwm, S_IRUGO|S_IWUSR,
 		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 		      0, 2),
@@ -751,6 +763,9 @@
 	SENSOR_ATTR_2(temp1_auto_point4_temp_hyst, S_IRUGO,
 		      show_pwm_auto_point_temp_hyst, NULL, 3, 2),
 
+	SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_channel,
+		      store_pwm_auto_point_channel, 0, 1),
 	SENSOR_ATTR_2(temp2_auto_point1_pwm, S_IRUGO|S_IWUSR,
 		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 		      0, 0),
@@ -789,6 +804,9 @@
 	SENSOR_ATTR_2(temp2_auto_point4_temp_hyst, S_IRUGO,
 		      show_pwm_auto_point_temp_hyst, NULL, 3, 0),
 
+	SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_channel,
+		      store_pwm_auto_point_channel, 0, 2),
 	SENSOR_ATTR_2(temp3_auto_point1_pwm, S_IRUGO|S_IWUSR,
 		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 		      0, 1),
@@ -929,7 +947,7 @@
 	/* Update once every 60 seconds */
 	if ( time_after(jiffies, data->last_limits + 60 * HZ ) ||
 			!data->valid) {
-		if (data->type == f71882fg) {
+		if (data->type == f71882fg || data->type == f71889fg) {
 			data->in1_max =
 				f71882fg_read8(data, F71882FG_REG_IN1_HIGH);
 			data->in_beep =
@@ -951,7 +969,8 @@
 						F71882FG_REG_TEMP_HYST(1));
 		}
 
-		if (data->type == f71862fg || data->type == f71882fg) {
+		if (data->type == f71862fg || data->type == f71882fg ||
+		    data->type == f71889fg) {
 			data->fan_beep = f71882fg_read8(data,
 						F71882FG_REG_FAN_BEEP);
 			data->temp_beep = f71882fg_read8(data,
@@ -961,15 +980,33 @@
 			data->temp_type[2] = (reg & 0x04) ? 2 : 4;
 			data->temp_type[3] = (reg & 0x08) ? 2 : 4;
 		}
-		reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
-		if ((reg2 & 0x03) == 0x01)
-			data->temp_type[1] = 6 /* PECI */;
-		else if ((reg2 & 0x03) == 0x02)
-			data->temp_type[1] = 5 /* AMDSI */;
-		else if (data->type == f71862fg || data->type == f71882fg)
-			data->temp_type[1] = (reg & 0x02) ? 2 : 4;
-		else
-			data->temp_type[1] = 2; /* Only supports BJT */
+		/* Determine temp index 1 sensor type */
+		if (data->type == f71889fg) {
+			reg2 = f71882fg_read8(data, F71882FG_REG_START);
+			switch ((reg2 & 0x60) >> 5) {
+			case 0x00: /* BJT / Thermistor */
+				data->temp_type[1] = (reg & 0x02) ? 2 : 4;
+				break;
+			case 0x01: /* AMDSI */
+				data->temp_type[1] = 5;
+				break;
+			case 0x02: /* PECI */
+			case 0x03: /* Ibex Peak ?? Report as PECI for now */
+				data->temp_type[1] = 6;
+				break;
+			}
+		} else {
+			reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
+			if ((reg2 & 0x03) == 0x01)
+				data->temp_type[1] = 6; /* PECI */
+			else if ((reg2 & 0x03) == 0x02)
+				data->temp_type[1] = 5; /* AMDSI */
+			else if (data->type == f71862fg ||
+				 data->type == f71882fg)
+				data->temp_type[1] = (reg & 0x02) ? 2 : 4;
+			else /* f71858fg and f8000 only support BJT */
+				data->temp_type[1] = 2;
+		}
 
 		data->pwm_enable = f71882fg_read8(data,
 						  F71882FG_REG_PWM_ENABLE);
@@ -1046,7 +1083,7 @@
 		if (data->type == f8000)
 			data->fan[3] = f71882fg_read16(data,
 						F71882FG_REG_FAN(3));
-		if (data->type == f71882fg)
+		if (data->type == f71882fg || data->type == f71889fg)
 			data->in_status = f71882fg_read8(data,
 						F71882FG_REG_IN_STATUS);
 		for (nr = 0; nr < nr_ins; nr++)
@@ -1764,7 +1801,11 @@
 	int pwm = to_sensor_dev_attr_2(devattr)->index;
 	int point = to_sensor_dev_attr_2(devattr)->nr;
 	long val = simple_strtol(buf, NULL, 10) / 1000;
-	val = SENSORS_LIMIT(val, 0, 255);
+
+	if (data->type == f71889fg)
+		val = SENSORS_LIMIT(val, -128, 127);
+	else
+		val = SENSORS_LIMIT(val, 0, 127);
 
 	mutex_lock(&data->update_lock);
 	f71882fg_write8(data, F71882FG_REG_POINT_TEMP(pwm, point), val);
@@ -1794,6 +1835,15 @@
 	return 0;
 }
 
+static void f71882fg_remove_sysfs_files(struct platform_device *pdev,
+	struct sensor_device_attribute_2 *attr, int count)
+{
+	int i;
+
+	for (i = 0; i < count; i++)
+		device_remove_file(&pdev->dev, &attr[i].dev_attr);
+}
+
 static int __devinit f71882fg_probe(struct platform_device *pdev)
 {
 	struct f71882fg_data *data;
@@ -1846,16 +1896,17 @@
 					ARRAY_SIZE(f71858fg_in_temp_attr));
 			break;
 		case f71882fg:
+		case f71889fg:
 			err = f71882fg_create_sysfs_files(pdev,
-					f71882fg_in_temp_attr,
-					ARRAY_SIZE(f71882fg_in_temp_attr));
+					fxxxx_in1_alarm_attr,
+					ARRAY_SIZE(fxxxx_in1_alarm_attr));
 			if (err)
 				goto exit_unregister_sysfs;
 			/* fall through! */
 		case f71862fg:
 			err = f71882fg_create_sysfs_files(pdev,
-					f718x2fg_in_temp_attr,
-					ARRAY_SIZE(f718x2fg_in_temp_attr));
+					fxxxx_in_temp_attr,
+					ARRAY_SIZE(fxxxx_in_temp_attr));
 			break;
 		case f8000:
 			err = f71882fg_create_sysfs_files(pdev,
@@ -1883,6 +1934,7 @@
 			err = (data->pwm_enable & 0x15) != 0x15;
 			break;
 		case f71882fg:
+		case f71889fg:
 			err = 0;
 			break;
 		case f8000:
@@ -1897,34 +1949,55 @@
 			goto exit_unregister_sysfs;
 		}
 
-		err = f71882fg_create_sysfs_files(pdev, fxxxx_fan_attr,
-					ARRAY_SIZE(fxxxx_fan_attr));
+		err = f71882fg_create_sysfs_files(pdev, &fxxxx_fan_attr[0][0],
+				ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans);
 		if (err)
 			goto exit_unregister_sysfs;
 
+		if (data->type == f71862fg || data->type == f71882fg ||
+		    data->type == f71889fg) {
+			err = f71882fg_create_sysfs_files(pdev,
+					fxxxx_fan_beep_attr, nr_fans);
+			if (err)
+				goto exit_unregister_sysfs;
+		}
+
 		switch (data->type) {
 		case f71862fg:
 			err = f71882fg_create_sysfs_files(pdev,
-					f71862fg_fan_attr,
-					ARRAY_SIZE(f71862fg_fan_attr));
-			break;
-		case f71882fg:
-			err = f71882fg_create_sysfs_files(pdev,
-					f71882fg_fan_attr,
-					ARRAY_SIZE(f71882fg_fan_attr));
-			if (err)
-				goto exit_unregister_sysfs;
-			/* fall through! */
-		case f71858fg:
-			err = f71882fg_create_sysfs_files(pdev,
-					f71882fg_f71858fg_fan_attr,
-					ARRAY_SIZE(f71882fg_f71858fg_fan_attr));
+					f71862fg_auto_pwm_attr,
+					ARRAY_SIZE(f71862fg_auto_pwm_attr));
 			break;
 		case f8000:
 			err = f71882fg_create_sysfs_files(pdev,
 					f8000_fan_attr,
 					ARRAY_SIZE(f8000_fan_attr));
+			if (err)
+				goto exit_unregister_sysfs;
+			err = f71882fg_create_sysfs_files(pdev,
+					f8000_auto_pwm_attr,
+					ARRAY_SIZE(f8000_auto_pwm_attr));
 			break;
+		case f71889fg:
+			for (i = 0; i < nr_fans; i++) {
+				data->pwm_auto_point_mapping[i] =
+					f71882fg_read8(data,
+						F71882FG_REG_POINT_MAPPING(i));
+				if (data->pwm_auto_point_mapping[i] & 0x80)
+					break;
+			}
+			if (i != nr_fans) {
+				dev_warn(&pdev->dev,
+					 "Auto pwm controlled by raw digital "
+					 "data, disabling pwm auto_point "
+					 "sysfs attributes\n");
+				break;
+			}
+			/* fall through */
+		default: /* f71858fg / f71882fg */
+			err = f71882fg_create_sysfs_files(pdev,
+				&fxxxx_auto_pwm_attr[0][0],
+				ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
 		}
 		if (err)
 			goto exit_unregister_sysfs;
@@ -1954,33 +2027,76 @@
 
 static int f71882fg_remove(struct platform_device *pdev)
 {
-	int i;
 	struct f71882fg_data *data = platform_get_drvdata(pdev);
+	int nr_fans = (data->type == f71882fg) ? 4 : 3;
+	u8 start_reg = f71882fg_read8(data, F71882FG_REG_START);
 
 	platform_set_drvdata(pdev, NULL);
 	if (data->hwmon_dev)
 		hwmon_device_unregister(data->hwmon_dev);
 
-	/* Note we are not looping over all attr arrays we have as the ones
-	   below are supersets of the ones skipped. */
 	device_remove_file(&pdev->dev, &dev_attr_name);
 
-	for (i = 0; i < ARRAY_SIZE(f718x2fg_in_temp_attr); i++)
-		device_remove_file(&pdev->dev,
-					&f718x2fg_in_temp_attr[i].dev_attr);
+	if (start_reg & 0x01) {
+		switch (data->type) {
+		case f71858fg:
+			if (data->temp_config & 0x10)
+				f71882fg_remove_sysfs_files(pdev,
+					f8000_in_temp_attr,
+					ARRAY_SIZE(f8000_in_temp_attr));
+			else
+				f71882fg_remove_sysfs_files(pdev,
+					f71858fg_in_temp_attr,
+					ARRAY_SIZE(f71858fg_in_temp_attr));
+			break;
+		case f71882fg:
+		case f71889fg:
+			f71882fg_remove_sysfs_files(pdev,
+					fxxxx_in1_alarm_attr,
+					ARRAY_SIZE(fxxxx_in1_alarm_attr));
+			/* fall through! */
+		case f71862fg:
+			f71882fg_remove_sysfs_files(pdev,
+					fxxxx_in_temp_attr,
+					ARRAY_SIZE(fxxxx_in_temp_attr));
+			break;
+		case f8000:
+			f71882fg_remove_sysfs_files(pdev,
+					f8000_in_temp_attr,
+					ARRAY_SIZE(f8000_in_temp_attr));
+			break;
+		}
+	}
 
-	for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++)
-		device_remove_file(&pdev->dev,
-					&f71882fg_in_temp_attr[i].dev_attr);
+	if (start_reg & 0x02) {
+		f71882fg_remove_sysfs_files(pdev, &fxxxx_fan_attr[0][0],
+				ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans);
 
-	for (i = 0; i < ARRAY_SIZE(fxxxx_fan_attr); i++)
-		device_remove_file(&pdev->dev, &fxxxx_fan_attr[i].dev_attr);
+		if (data->type == f71862fg || data->type == f71882fg ||
+		    data->type == f71889fg)
+			f71882fg_remove_sysfs_files(pdev,
+					fxxxx_fan_beep_attr, nr_fans);
 
-	for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++)
-		device_remove_file(&pdev->dev, &f71882fg_fan_attr[i].dev_attr);
-
-	for (i = 0; i < ARRAY_SIZE(f8000_fan_attr); i++)
-		device_remove_file(&pdev->dev, &f8000_fan_attr[i].dev_attr);
+		switch (data->type) {
+		case f71862fg:
+			f71882fg_remove_sysfs_files(pdev,
+					f71862fg_auto_pwm_attr,
+					ARRAY_SIZE(f71862fg_auto_pwm_attr));
+			break;
+		case f8000:
+			f71882fg_remove_sysfs_files(pdev,
+					f8000_fan_attr,
+					ARRAY_SIZE(f8000_fan_attr));
+			f71882fg_remove_sysfs_files(pdev,
+					f8000_auto_pwm_attr,
+					ARRAY_SIZE(f8000_auto_pwm_attr));
+			break;
+		default: /* f71858fg / f71882fg / f71889fg */
+			f71882fg_remove_sysfs_files(pdev,
+				&fxxxx_auto_pwm_attr[0][0],
+				ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
+		}
+	}
 
 	kfree(data);
 
@@ -2012,11 +2128,15 @@
 	case SIO_F71882_ID:
 		sio_data->type = f71882fg;
 		break;
+	case SIO_F71889_ID:
+		sio_data->type = f71889fg;
+		break;
 	case SIO_F8000_ID:
 		sio_data->type = f8000;
 		break;
 	default:
-		printk(KERN_INFO DRVNAME ": Unsupported Fintek device\n");
+		printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n",
+		       (unsigned int)devid);
 		goto exit;
 	}
 
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index e2107e5..40dfbcd 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -681,30 +681,20 @@
 			 struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
-	u8 version = 0;
-	const char *name = "";
+	u16 vendid, chipid;
+	u8 version;
+	const char *name;
 
-	if (kind < 0) {
-		u16 vendid = f75375_read16(client, F75375_REG_VENDOR);
-		u16 chipid = f75375_read16(client, F75375_CHIP_ID);
-		version = f75375_read8(client, F75375_REG_VERSION);
-		if (chipid == 0x0306 && vendid == 0x1934) {
-			kind = f75375;
-		} else if (chipid == 0x0204 && vendid == 0x1934) {
-			kind = f75373;
-		} else {
-			dev_err(&adapter->dev,
-				"failed,%02X,%02X,%02X\n",
-				chipid, version, vendid);
-			return -ENODEV;
-		}
-	}
-
-	if (kind == f75375) {
+	vendid = f75375_read16(client, F75375_REG_VENDOR);
+	chipid = f75375_read16(client, F75375_CHIP_ID);
+	if (chipid == 0x0306 && vendid == 0x1934)
 		name = "f75375";
-	} else if (kind == f75373) {
+	else if (chipid == 0x0204 && vendid == 0x1934)
 		name = "f75373";
-	}
+	else
+		return -ENODEV;
+
+	version = f75375_read8(client, F75375_REG_VERSION);
 	dev_info(&adapter->dev, "found %s version: %02X\n", name, version);
 	strlcpy(info->type, name, I2C_NAME_SIZE);
 
diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c
index da1b1f9..281829c 100644
--- a/drivers/hwmon/fschmd.c
+++ b/drivers/hwmon/fschmd.c
@@ -1000,43 +1000,38 @@
 	}
 }
 
-static int fschmd_detect(struct i2c_client *client, int kind,
+static int fschmd_detect(struct i2c_client *client, int _kind,
 			 struct i2c_board_info *info)
 {
+	enum chips kind;
 	struct i2c_adapter *adapter = client->adapter;
+	char id[4];
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
 	/* Detect & Identify the chip */
-	if (kind <= 0) {
-		char id[4];
+	id[0] = i2c_smbus_read_byte_data(client, FSCHMD_REG_IDENT_0);
+	id[1] = i2c_smbus_read_byte_data(client, FSCHMD_REG_IDENT_1);
+	id[2] = i2c_smbus_read_byte_data(client, FSCHMD_REG_IDENT_2);
+	id[3] = '\0';
 
-		id[0] = i2c_smbus_read_byte_data(client,
-				FSCHMD_REG_IDENT_0);
-		id[1] = i2c_smbus_read_byte_data(client,
-				FSCHMD_REG_IDENT_1);
-		id[2] = i2c_smbus_read_byte_data(client,
-				FSCHMD_REG_IDENT_2);
-		id[3] = '\0';
-
-		if (!strcmp(id, "PEG"))
-			kind = fscpos;
-		else if (!strcmp(id, "HER"))
-			kind = fscher;
-		else if (!strcmp(id, "SCY"))
-			kind = fscscy;
-		else if (!strcmp(id, "HRC"))
-			kind = fschrc;
-		else if (!strcmp(id, "HMD"))
-			kind = fschmd;
-		else if (!strcmp(id, "HDS"))
-			kind = fschds;
-		else if (!strcmp(id, "SYL"))
-			kind = fscsyl;
-		else
-			return -ENODEV;
-	}
+	if (!strcmp(id, "PEG"))
+		kind = fscpos;
+	else if (!strcmp(id, "HER"))
+		kind = fscher;
+	else if (!strcmp(id, "SCY"))
+		kind = fscscy;
+	else if (!strcmp(id, "HRC"))
+		kind = fschrc;
+	else if (!strcmp(id, "HMD"))
+		kind = fschmd;
+	else if (!strcmp(id, "HDS"))
+		kind = fschds;
+	else if (!strcmp(id, "SYL"))
+		kind = fscsyl;
+	else
+		return -ENODEV;
 
 	strlcpy(info->type, fschmd_id[kind - 1].name, I2C_NAME_SIZE);
 
diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c
index 7820df4..1d69458a 100644
--- a/drivers/hwmon/gl518sm.c
+++ b/drivers/hwmon/gl518sm.c
@@ -488,36 +488,21 @@
 			struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
-	int i;
+	int rev;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
 				     I2C_FUNC_SMBUS_WORD_DATA))
 		return -ENODEV;
 
 	/* Now, we do the remaining detection. */
-
-	if (kind < 0) {
-		if ((gl518_read_value(client, GL518_REG_CHIP_ID) != 0x80)
-		 || (gl518_read_value(client, GL518_REG_CONF) & 0x80))
-			return -ENODEV;
-	}
+	if ((gl518_read_value(client, GL518_REG_CHIP_ID) != 0x80)
+	 || (gl518_read_value(client, GL518_REG_CONF) & 0x80))
+		return -ENODEV;
 
 	/* Determine the chip type. */
-	if (kind <= 0) {
-		i = gl518_read_value(client, GL518_REG_REVISION);
-		if (i == 0x00) {
-			kind = gl518sm_r00;
-		} else if (i == 0x80) {
-			kind = gl518sm_r80;
-		} else {
-			if (kind <= 0)
-				dev_info(&adapter->dev,
-				    "Ignoring 'force' parameter for unknown "
-				    "chip at adapter %d, address 0x%02x\n",
-				    i2c_adapter_id(adapter), client->addr);
-			return -ENODEV;
-		}
-	}
+	rev = gl518_read_value(client, GL518_REG_REVISION);
+	if (rev != 0x00 && rev != 0x80)
+		return -ENODEV;
 
 	strlcpy(info->type, "gl518sm", I2C_NAME_SIZE);
 
diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c
index 19616f2..92b5720 100644
--- a/drivers/hwmon/gl520sm.c
+++ b/drivers/hwmon/gl520sm.c
@@ -691,13 +691,11 @@
 		return -ENODEV;
 
 	/* Determine the chip type. */
-	if (kind < 0) {
-		if ((gl520_read_value(client, GL520_REG_CHIP_ID) != 0x20) ||
-		    ((gl520_read_value(client, GL520_REG_REVISION) & 0x7f) != 0x00) ||
-		    ((gl520_read_value(client, GL520_REG_CONF) & 0x80) != 0x00)) {
-			dev_dbg(&client->dev, "Unknown chip type, skipping\n");
-			return -ENODEV;
-		}
+	if ((gl520_read_value(client, GL520_REG_CHIP_ID) != 0x20) ||
+	    ((gl520_read_value(client, GL520_REG_REVISION) & 0x7f) != 0x00) ||
+	    ((gl520_read_value(client, GL520_REG_CONF) & 0x80) != 0x00)) {
+		dev_dbg(&client->dev, "Unknown chip type, skipping\n");
+		return -ENODEV;
 	}
 
 	strlcpy(info->type, "gl520sm", I2C_NAME_SIZE);
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index a3749cb..0ffe84d 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -124,6 +124,8 @@
 #define IT87_BASE_REG 0x60
 
 /* Logical device 7 registers (IT8712F and later) */
+#define IT87_SIO_GPIO3_REG	0x27
+#define IT87_SIO_GPIO5_REG	0x29
 #define IT87_SIO_PINX2_REG	0x2c	/* Pin selection */
 #define IT87_SIO_VID_REG	0xfc	/* VID value */
 
@@ -244,7 +246,9 @@
 	/* Values read from Super-I/O config space */
 	u8 revision;
 	u8 vid_value;
-	/* Values set based on DMI strings */
+	/* Features skipped based on config or DMI */
+	u8 skip_vid;
+	u8 skip_fan;
 	u8 skip_pwm;
 };
 
@@ -1028,11 +1032,35 @@
 		chip_type, *address, sio_data->revision);
 
 	/* Read GPIO config and VID value from LDN 7 (GPIO) */
-	if (sio_data->type != it87) {
+	if (sio_data->type == it87) {
+		/* The IT8705F doesn't have VID pins at all */
+		sio_data->skip_vid = 1;
+	} else {
 		int reg;
 
 		superio_select(GPIO);
-		if (sio_data->type == it8718 || sio_data->type == it8720)
+		/* We need at least 4 VID pins */
+		reg = superio_inb(IT87_SIO_GPIO3_REG);
+		if (reg & 0x0f) {
+			pr_info("it87: VID is disabled (pins used for GPIO)\n");
+			sio_data->skip_vid = 1;
+		}
+
+		/* Check if fan3 is there or not */
+		if (reg & (1 << 6))
+			sio_data->skip_pwm |= (1 << 2);
+		if (reg & (1 << 7))
+			sio_data->skip_fan |= (1 << 2);
+
+		/* Check if fan2 is there or not */
+		reg = superio_inb(IT87_SIO_GPIO5_REG);
+		if (reg & (1 << 1))
+			sio_data->skip_pwm |= (1 << 1);
+		if (reg & (1 << 2))
+			sio_data->skip_fan |= (1 << 1);
+
+		if ((sio_data->type == it8718 || sio_data->type == it8720)
+		 && !(sio_data->skip_vid))
 			sio_data->vid_value = superio_inb(IT87_SIO_VID_REG);
 
 		reg = superio_inb(IT87_SIO_PINX2_REG);
@@ -1236,8 +1264,7 @@
 		}
 	}
 
-	if (data->type == it8712 || data->type == it8716
-	 || data->type == it8718 || data->type == it8720) {
+	if (!sio_data->skip_vid) {
 		data->vrm = vid_which_vrm();
 		/* VID reading from Super-I/O config space if available */
 		data->vid = sio_data->vid_value;
@@ -1355,8 +1382,10 @@
 /* Called when we have found a new IT87. */
 static void __devinit it87_init_device(struct platform_device *pdev)
 {
+	struct it87_sio_data *sio_data = pdev->dev.platform_data;
 	struct it87_data *data = platform_get_drvdata(pdev);
 	int tmp, i;
+	u8 mask;
 
 	/* initialize to sane defaults:
 	 * - if the chip is in manual pwm mode, this will be overwritten with
@@ -1402,10 +1431,11 @@
 	}
 
 	/* Check if tachometers are reset manually or by some reason */
+	mask = 0x70 & ~(sio_data->skip_fan << 4);
 	data->fan_main_ctrl = it87_read_value(data, IT87_REG_FAN_MAIN_CTRL);
-	if ((data->fan_main_ctrl & 0x70) == 0) {
+	if ((data->fan_main_ctrl & mask) == 0) {
 		/* Enable all fan tachometers */
-		data->fan_main_ctrl |= 0x70;
+		data->fan_main_ctrl |= mask;
 		it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
 	}
 	data->has_fan = (data->fan_main_ctrl >> 4) & 0x07;
@@ -1428,6 +1458,9 @@
 		}
 	}
 
+	/* Fan input pins may be used for alternative functions */
+	data->has_fan &= ~sio_data->skip_fan;
+
 	/* Set current fan mode registers and the default settings for the
 	 * other mode registers */
 	for (i = 0; i < 3; i++) {
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c
index 3195a26..5da66ab 100644
--- a/drivers/hwmon/lm63.c
+++ b/drivers/hwmon/lm63.c
@@ -427,40 +427,34 @@
 		       struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = new_client->adapter;
+	u8 man_id, chip_id, reg_config1, reg_config2;
+	u8 reg_alert_status, reg_alert_mask;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	if (kind < 0) { /* must identify */
-		u8 man_id, chip_id, reg_config1, reg_config2;
-		u8 reg_alert_status, reg_alert_mask;
+	man_id = i2c_smbus_read_byte_data(new_client, LM63_REG_MAN_ID);
+	chip_id = i2c_smbus_read_byte_data(new_client, LM63_REG_CHIP_ID);
 
-		man_id = i2c_smbus_read_byte_data(new_client,
-			 LM63_REG_MAN_ID);
-		chip_id = i2c_smbus_read_byte_data(new_client,
-			  LM63_REG_CHIP_ID);
-		reg_config1 = i2c_smbus_read_byte_data(new_client,
-			      LM63_REG_CONFIG1);
-		reg_config2 = i2c_smbus_read_byte_data(new_client,
-			      LM63_REG_CONFIG2);
-		reg_alert_status = i2c_smbus_read_byte_data(new_client,
-				   LM63_REG_ALERT_STATUS);
-		reg_alert_mask = i2c_smbus_read_byte_data(new_client,
-				 LM63_REG_ALERT_MASK);
+	reg_config1 = i2c_smbus_read_byte_data(new_client,
+		      LM63_REG_CONFIG1);
+	reg_config2 = i2c_smbus_read_byte_data(new_client,
+		      LM63_REG_CONFIG2);
+	reg_alert_status = i2c_smbus_read_byte_data(new_client,
+			   LM63_REG_ALERT_STATUS);
+	reg_alert_mask = i2c_smbus_read_byte_data(new_client,
+			 LM63_REG_ALERT_MASK);
 
-		if (man_id == 0x01 /* National Semiconductor */
-		 && chip_id == 0x41 /* LM63 */
-		 && (reg_config1 & 0x18) == 0x00
-		 && (reg_config2 & 0xF8) == 0x00
-		 && (reg_alert_status & 0x20) == 0x00
-		 && (reg_alert_mask & 0xA4) == 0xA4) {
-			kind = lm63;
-		} else { /* failed */
-			dev_dbg(&adapter->dev, "Unsupported chip "
-				"(man_id=0x%02X, chip_id=0x%02X).\n",
-				man_id, chip_id);
-			return -ENODEV;
-		}
+	if (man_id != 0x01 /* National Semiconductor */
+	 || chip_id != 0x41 /* LM63 */
+	 || (reg_config1 & 0x18) != 0x00
+	 || (reg_config2 & 0xF8) != 0x00
+	 || (reg_alert_status & 0x20) != 0x00
+	 || (reg_alert_mask & 0xA4) != 0xA4) {
+		dev_dbg(&adapter->dev,
+			"Unsupported chip (man_id=0x%02X, chip_id=0x%02X)\n",
+			man_id, chip_id);
+		return -ENODEV;
 	}
 
 	strlcpy(info->type, "lm63", I2C_NAME_SIZE);
diff --git a/drivers/hwmon/lm73.c b/drivers/hwmon/lm73.c
new file mode 100644
index 0000000..0bf8b2a
--- /dev/null
+++ b/drivers/hwmon/lm73.c
@@ -0,0 +1,205 @@
+/*
+ * LM73 Sensor driver
+ * Based on LM75
+ *
+ * Copyright (C) 2007, CenoSYS (www.cenosys.com).
+ * Copyright (C) 2009, Bollore telecom (www.bolloretelecom.eu).
+ *
+ * Guillaume Ligneul <guillaume.ligneul@gmail.com>
+ * Adrien Demarez <adrien.demarez@bolloretelecom.eu>
+ * Jeremy Laine <jeremy.laine@bolloretelecom.eu>
+ *
+ * This software program is licensed subject to the GNU General Public License
+ * (GPL).Version 2,June 1991, available at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+
+
+/* Addresses scanned */
+static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4c,
+					0x4d, 0x4e, I2C_CLIENT_END };
+
+/* Insmod parameters */
+I2C_CLIENT_INSMOD_1(lm73);
+
+/* LM73 registers */
+#define LM73_REG_INPUT		0x00
+#define LM73_REG_CONF		0x01
+#define LM73_REG_MAX		0x02
+#define LM73_REG_MIN		0x03
+#define LM73_REG_CTRL		0x04
+#define LM73_REG_ID		0x07
+
+#define LM73_ID			0x9001 /* or 0x190 after a swab16() */
+#define DRVNAME			"lm73"
+#define LM73_TEMP_MIN		(-40)
+#define LM73_TEMP_MAX		150
+
+/*-----------------------------------------------------------------------*/
+
+
+static ssize_t set_temp(struct device *dev, struct device_attribute *da,
+			const char *buf, size_t count)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+	struct i2c_client *client = to_i2c_client(dev);
+	long temp;
+	short value;
+
+	int status = strict_strtol(buf, 10, &temp);
+	if (status < 0)
+		return status;
+
+	/* Write value */
+	value = (short) SENSORS_LIMIT(temp/250, (LM73_TEMP_MIN*4),
+		(LM73_TEMP_MAX*4)) << 5;
+	i2c_smbus_write_word_data(client, attr->index, swab16(value));
+	return count;
+}
+
+static ssize_t show_temp(struct device *dev, struct device_attribute *da,
+			 char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+	struct i2c_client *client = to_i2c_client(dev);
+	/* use integer division instead of equivalent right shift to
+	   guarantee arithmetic shift and preserve the sign */
+	int temp = ((s16) (swab16(i2c_smbus_read_word_data(client,
+		attr->index)))*250) / 32;
+	return sprintf(buf, "%d\n", temp);
+}
+
+
+/*-----------------------------------------------------------------------*/
+
+/* sysfs attributes for hwmon */
+
+static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
+			show_temp, set_temp, LM73_REG_MAX);
+static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO,
+			show_temp, set_temp, LM73_REG_MIN);
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
+			show_temp, NULL, LM73_REG_INPUT);
+
+
+static struct attribute *lm73_attributes[] = {
+	&sensor_dev_attr_temp1_input.dev_attr.attr,
+	&sensor_dev_attr_temp1_max.dev_attr.attr,
+	&sensor_dev_attr_temp1_min.dev_attr.attr,
+
+	NULL
+};
+
+static const struct attribute_group lm73_group = {
+	.attrs = lm73_attributes,
+};
+
+/*-----------------------------------------------------------------------*/
+
+/* device probe and removal */
+
+static int
+lm73_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+	struct device *hwmon_dev;
+	int status;
+
+	/* Register sysfs hooks */
+	status = sysfs_create_group(&client->dev.kobj, &lm73_group);
+	if (status)
+		return status;
+
+	hwmon_dev = hwmon_device_register(&client->dev);
+	if (IS_ERR(hwmon_dev)) {
+		status = PTR_ERR(hwmon_dev);
+		goto exit_remove;
+	}
+	i2c_set_clientdata(client, hwmon_dev);
+
+	dev_info(&client->dev, "%s: sensor '%s'\n",
+		 dev_name(hwmon_dev), client->name);
+
+	return 0;
+
+exit_remove:
+	sysfs_remove_group(&client->dev.kobj, &lm73_group);
+	return status;
+}
+
+static int lm73_remove(struct i2c_client *client)
+{
+	struct device *hwmon_dev = i2c_get_clientdata(client);
+
+	hwmon_device_unregister(hwmon_dev);
+	sysfs_remove_group(&client->dev.kobj, &lm73_group);
+	i2c_set_clientdata(client, NULL);
+	return 0;
+}
+
+static const struct i2c_device_id lm73_ids[] = {
+	{ "lm73", lm73 },
+	{ /* LIST END */ }
+};
+MODULE_DEVICE_TABLE(i2c, lm73_ids);
+
+/* Return 0 if detection is successful, -ENODEV otherwise */
+static int lm73_detect(struct i2c_client *new_client, int kind,
+			struct i2c_board_info *info)
+{
+	struct i2c_adapter *adapter = new_client->adapter;
+	u16 id;
+	u8 ctrl;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
+					I2C_FUNC_SMBUS_WORD_DATA))
+		return -ENODEV;
+
+	/* Check device ID */
+	id = i2c_smbus_read_word_data(new_client, LM73_REG_ID);
+	ctrl = i2c_smbus_read_byte_data(new_client, LM73_REG_CTRL);
+	if ((id != LM73_ID) || (ctrl & 0x10))
+		return -ENODEV;
+
+	strlcpy(info->type, "lm73", I2C_NAME_SIZE);
+
+	return 0;
+}
+
+static struct i2c_driver lm73_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "lm73",
+	},
+	.probe		= lm73_probe,
+	.remove		= lm73_remove,
+	.id_table	= lm73_ids,
+	.detect		= lm73_detect,
+	.address_data	= &addr_data,
+};
+
+/* module glue */
+
+static int __init sensors_lm73_init(void)
+{
+	return i2c_add_driver(&lm73_driver);
+}
+
+static void __exit sensors_lm73_exit(void)
+{
+	i2c_del_driver(&lm73_driver);
+}
+
+MODULE_AUTHOR("Guillaume Ligneul <guillaume.ligneul@gmail.com>");
+MODULE_DESCRIPTION("LM73 driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_lm73_init);
+module_exit(sensors_lm73_exit);
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
index 55bd87c..e392548 100644
--- a/drivers/hwmon/lm75.c
+++ b/drivers/hwmon/lm75.c
@@ -239,6 +239,7 @@
 {
 	struct i2c_adapter *adapter = new_client->adapter;
 	int i;
+	int cur, conf, hyst, os;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
 				     I2C_FUNC_SMBUS_WORD_DATA))
@@ -251,40 +252,35 @@
 	   The cycling+unused addresses combination is not tested,
 	   since it would significantly slow the detection down and would
 	   hardly add any value. */
-	if (kind < 0) {
-		int cur, conf, hyst, os;
 
-		/* Unused addresses */
-		cur = i2c_smbus_read_word_data(new_client, 0);
-		conf = i2c_smbus_read_byte_data(new_client, 1);
-		hyst = i2c_smbus_read_word_data(new_client, 2);
-		if (i2c_smbus_read_word_data(new_client, 4) != hyst
-		 || i2c_smbus_read_word_data(new_client, 5) != hyst
-		 || i2c_smbus_read_word_data(new_client, 6) != hyst
-		 || i2c_smbus_read_word_data(new_client, 7) != hyst)
-			return -ENODEV;
-		os = i2c_smbus_read_word_data(new_client, 3);
-		if (i2c_smbus_read_word_data(new_client, 4) != os
-		 || i2c_smbus_read_word_data(new_client, 5) != os
-		 || i2c_smbus_read_word_data(new_client, 6) != os
-		 || i2c_smbus_read_word_data(new_client, 7) != os)
-			return -ENODEV;
+	/* Unused addresses */
+	cur = i2c_smbus_read_word_data(new_client, 0);
+	conf = i2c_smbus_read_byte_data(new_client, 1);
+	hyst = i2c_smbus_read_word_data(new_client, 2);
+	if (i2c_smbus_read_word_data(new_client, 4) != hyst
+	 || i2c_smbus_read_word_data(new_client, 5) != hyst
+	 || i2c_smbus_read_word_data(new_client, 6) != hyst
+	 || i2c_smbus_read_word_data(new_client, 7) != hyst)
+		return -ENODEV;
+	os = i2c_smbus_read_word_data(new_client, 3);
+	if (i2c_smbus_read_word_data(new_client, 4) != os
+	 || i2c_smbus_read_word_data(new_client, 5) != os
+	 || i2c_smbus_read_word_data(new_client, 6) != os
+	 || i2c_smbus_read_word_data(new_client, 7) != os)
+		return -ENODEV;
 
-		/* Unused bits */
-		if (conf & 0xe0)
-			return -ENODEV;
+	/* Unused bits */
+	if (conf & 0xe0)
+		return -ENODEV;
 
-		/* Addresses cycling */
-		for (i = 8; i < 0xff; i += 8)
-			if (i2c_smbus_read_byte_data(new_client, i + 1) != conf
-			 || i2c_smbus_read_word_data(new_client, i + 2) != hyst
-			 || i2c_smbus_read_word_data(new_client, i + 3) != os)
-				return -ENODEV;
+	/* Addresses cycling */
+	for (i = 8; i < 0xff; i += 8) {
+		if (i2c_smbus_read_byte_data(new_client, i + 1) != conf
+		 || i2c_smbus_read_word_data(new_client, i + 2) != hyst
+		 || i2c_smbus_read_word_data(new_client, i + 3) != os)
+			return -ENODEV;
 	}
 
-	/* NOTE: we treat "force=..." and "force_lm75=..." the same.
-	 * Only new-style driver binding distinguishes chip types.
-	 */
 	strlcpy(info->type, "lm75", I2C_NAME_SIZE);
 
 	return 0;
diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c
index 866b401..ac067fd 100644
--- a/drivers/hwmon/lm77.c
+++ b/drivers/hwmon/lm77.c
@@ -249,6 +249,7 @@
 		       struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = new_client->adapter;
+	int i, cur, conf, hyst, crit, min, max;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
 				     I2C_FUNC_SMBUS_WORD_DATA))
@@ -265,52 +266,49 @@
 	   4. registers cycling over 8-address boundaries
 
 	   Word-sized registers are high-byte first. */
-	if (kind < 0) {
-		int i, cur, conf, hyst, crit, min, max;
 
-		/* addresses cycling */
-		cur = i2c_smbus_read_word_data(new_client, 0);
-		conf = i2c_smbus_read_byte_data(new_client, 1);
-		hyst = i2c_smbus_read_word_data(new_client, 2);
-		crit = i2c_smbus_read_word_data(new_client, 3);
-		min = i2c_smbus_read_word_data(new_client, 4);
-		max = i2c_smbus_read_word_data(new_client, 5);
-		for (i = 8; i <= 0xff; i += 8)
-			if (i2c_smbus_read_byte_data(new_client, i + 1) != conf
-			    || i2c_smbus_read_word_data(new_client, i + 2) != hyst
-			    || i2c_smbus_read_word_data(new_client, i + 3) != crit
-			    || i2c_smbus_read_word_data(new_client, i + 4) != min
-			    || i2c_smbus_read_word_data(new_client, i + 5) != max)
-				return -ENODEV;
-
-		/* sign bits */
-		if (((cur & 0x00f0) != 0xf0 && (cur & 0x00f0) != 0x0)
-		    || ((hyst & 0x00f0) != 0xf0 && (hyst & 0x00f0) != 0x0)
-		    || ((crit & 0x00f0) != 0xf0 && (crit & 0x00f0) != 0x0)
-		    || ((min & 0x00f0) != 0xf0 && (min & 0x00f0) != 0x0)
-		    || ((max & 0x00f0) != 0xf0 && (max & 0x00f0) != 0x0))
+	/* addresses cycling */
+	cur = i2c_smbus_read_word_data(new_client, 0);
+	conf = i2c_smbus_read_byte_data(new_client, 1);
+	hyst = i2c_smbus_read_word_data(new_client, 2);
+	crit = i2c_smbus_read_word_data(new_client, 3);
+	min = i2c_smbus_read_word_data(new_client, 4);
+	max = i2c_smbus_read_word_data(new_client, 5);
+	for (i = 8; i <= 0xff; i += 8) {
+		if (i2c_smbus_read_byte_data(new_client, i + 1) != conf
+		 || i2c_smbus_read_word_data(new_client, i + 2) != hyst
+		 || i2c_smbus_read_word_data(new_client, i + 3) != crit
+		 || i2c_smbus_read_word_data(new_client, i + 4) != min
+		 || i2c_smbus_read_word_data(new_client, i + 5) != max)
 			return -ENODEV;
-
-		/* unused bits */
-		if (conf & 0xe0)
-			return -ENODEV;
-
-		/* 0x06 and 0x07 return the last read value */
-		cur = i2c_smbus_read_word_data(new_client, 0);
-		if (i2c_smbus_read_word_data(new_client, 6) != cur
-		    || i2c_smbus_read_word_data(new_client, 7) != cur)
-			return -ENODEV;
-		hyst = i2c_smbus_read_word_data(new_client, 2);
-		if (i2c_smbus_read_word_data(new_client, 6) != hyst
-		    || i2c_smbus_read_word_data(new_client, 7) != hyst)
-			return -ENODEV;
-		min = i2c_smbus_read_word_data(new_client, 4);
-		if (i2c_smbus_read_word_data(new_client, 6) != min
-		    || i2c_smbus_read_word_data(new_client, 7) != min)
-			return -ENODEV;
-
 	}
 
+	/* sign bits */
+	if (((cur & 0x00f0) != 0xf0 && (cur & 0x00f0) != 0x0)
+	 || ((hyst & 0x00f0) != 0xf0 && (hyst & 0x00f0) != 0x0)
+	 || ((crit & 0x00f0) != 0xf0 && (crit & 0x00f0) != 0x0)
+	 || ((min & 0x00f0) != 0xf0 && (min & 0x00f0) != 0x0)
+	 || ((max & 0x00f0) != 0xf0 && (max & 0x00f0) != 0x0))
+		return -ENODEV;
+
+	/* unused bits */
+	if (conf & 0xe0)
+		return -ENODEV;
+
+	/* 0x06 and 0x07 return the last read value */
+	cur = i2c_smbus_read_word_data(new_client, 0);
+	if (i2c_smbus_read_word_data(new_client, 6) != cur
+	 || i2c_smbus_read_word_data(new_client, 7) != cur)
+		return -ENODEV;
+	hyst = i2c_smbus_read_word_data(new_client, 2);
+	if (i2c_smbus_read_word_data(new_client, 6) != hyst
+	 || i2c_smbus_read_word_data(new_client, 7) != hyst)
+		return -ENODEV;
+	min = i2c_smbus_read_word_data(new_client, 4);
+	if (i2c_smbus_read_word_data(new_client, 6) != min
+	 || i2c_smbus_read_word_data(new_client, 7) != min)
+		return -ENODEV;
+
 	strlcpy(info->type, "lm77", I2C_NAME_SIZE);
 
 	return 0;
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c
index f7e7016..5978291 100644
--- a/drivers/hwmon/lm78.c
+++ b/drivers/hwmon/lm78.c
@@ -576,52 +576,34 @@
 	if (isa)
 		mutex_lock(&isa->update_lock);
 
-	if (kind < 0) {
-		if ((i2c_smbus_read_byte_data(client, LM78_REG_CONFIG) & 0x80)
-		 || i2c_smbus_read_byte_data(client, LM78_REG_I2C_ADDR)
-		    != address)
-			goto err_nodev;
+	if ((i2c_smbus_read_byte_data(client, LM78_REG_CONFIG) & 0x80)
+	 || i2c_smbus_read_byte_data(client, LM78_REG_I2C_ADDR) != address)
+		goto err_nodev;
 
-		/* Explicitly prevent the misdetection of Winbond chips */
-		i = i2c_smbus_read_byte_data(client, 0x4f);
-		if (i == 0xa3 || i == 0x5c)
-			goto err_nodev;
-	}
+	/* Explicitly prevent the misdetection of Winbond chips */
+	i = i2c_smbus_read_byte_data(client, 0x4f);
+	if (i == 0xa3 || i == 0x5c)
+		goto err_nodev;
 
 	/* Determine the chip type. */
-	if (kind <= 0) {
-		i = i2c_smbus_read_byte_data(client, LM78_REG_CHIPID);
-		if (i == 0x00 || i == 0x20	/* LM78 */
-		 || i == 0x40)			/* LM78-J */
-			kind = lm78;
-		else if ((i & 0xfe) == 0xc0)
-			kind = lm79;
-		else {
-			if (kind == 0)
-				dev_warn(&adapter->dev, "Ignoring 'force' "
-					"parameter for unknown chip at "
-					"adapter %d, address 0x%02x\n",
-					i2c_adapter_id(adapter), address);
-			goto err_nodev;
-		}
+	i = i2c_smbus_read_byte_data(client, LM78_REG_CHIPID);
+	if (i == 0x00 || i == 0x20	/* LM78 */
+	 || i == 0x40)			/* LM78-J */
+		client_name = "lm78";
+	else if ((i & 0xfe) == 0xc0)
+		client_name = "lm79";
+	else
+		goto err_nodev;
 
-		if (lm78_alias_detect(client, i)) {
-			dev_dbg(&adapter->dev, "Device at 0x%02x appears to "
-				"be the same as ISA device\n", address);
-			goto err_nodev;
-		}
+	if (lm78_alias_detect(client, i)) {
+		dev_dbg(&adapter->dev, "Device at 0x%02x appears to "
+			"be the same as ISA device\n", address);
+		goto err_nodev;
 	}
 
 	if (isa)
 		mutex_unlock(&isa->update_lock);
 
-	switch (kind) {
-	case lm79:
-		client_name = "lm79";
-		break;
-	default:
-		client_name = "lm78";
-	}
 	strlcpy(info->type, client_name, I2C_NAME_SIZE);
 
 	return 0;
diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c
index e59e2d1..08b03e6 100644
--- a/drivers/hwmon/lm83.c
+++ b/drivers/hwmon/lm83.c
@@ -1,7 +1,7 @@
 /*
  * lm83.c - Part of lm_sensors, Linux kernel modules for hardware
  *          monitoring
- * Copyright (C) 2003-2008  Jean Delvare <khali@linux-fr.org>
+ * Copyright (C) 2003-2009  Jean Delvare <khali@linux-fr.org>
  *
  * Heavily inspired from the lm78, lm75 and adm1021 drivers. The LM83 is
  * a sensor chip made by National Semiconductor. It reports up to four
@@ -295,69 +295,40 @@
 		       struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = new_client->adapter;
-	const char *name = "";
+	const char *name;
+	u8 man_id, chip_id;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	/* Now we do the detection and identification. A negative kind
-	 * means that the driver was loaded with no force parameter
-	 * (default), so we must both detect and identify the chip
-	 * (actually there is only one possible kind of chip for now, LM83).
-	 * A zero kind means that the driver was loaded with the force
-	 * parameter, the detection step shall be skipped. A positive kind
-	 * means that the driver was loaded with the force parameter and a
-	 * given kind of chip is requested, so both the detection and the
-	 * identification steps are skipped. */
-
-	/* Default to an LM83 if forced */
-	if (kind == 0)
-		kind = lm83;
-
-	if (kind < 0) { /* detection */
-		if (((i2c_smbus_read_byte_data(new_client, LM83_REG_R_STATUS1)
-		    & 0xA8) != 0x00) ||
-		    ((i2c_smbus_read_byte_data(new_client, LM83_REG_R_STATUS2)
-		    & 0x48) != 0x00) ||
-		    ((i2c_smbus_read_byte_data(new_client, LM83_REG_R_CONFIG)
-		    & 0x41) != 0x00)) {
-			dev_dbg(&adapter->dev,
-				"LM83 detection failed at 0x%02x.\n",
-				new_client->addr);
-			return -ENODEV;
-		}
+	/* Detection */
+	if ((i2c_smbus_read_byte_data(new_client, LM83_REG_R_STATUS1) & 0xA8) ||
+	    (i2c_smbus_read_byte_data(new_client, LM83_REG_R_STATUS2) & 0x48) ||
+	    (i2c_smbus_read_byte_data(new_client, LM83_REG_R_CONFIG) & 0x41)) {
+		dev_dbg(&adapter->dev, "LM83 detection failed at 0x%02x\n",
+			new_client->addr);
+		return -ENODEV;
 	}
 
-	if (kind <= 0) { /* identification */
-		u8 man_id, chip_id;
+	/* Identification */
+	man_id = i2c_smbus_read_byte_data(new_client, LM83_REG_R_MAN_ID);
+	if (man_id != 0x01)	/* National Semiconductor */
+		return -ENODEV;
 
-		man_id = i2c_smbus_read_byte_data(new_client,
-		    LM83_REG_R_MAN_ID);
-		chip_id = i2c_smbus_read_byte_data(new_client,
-		    LM83_REG_R_CHIP_ID);
-
-		if (man_id == 0x01) { /* National Semiconductor */
-			if (chip_id == 0x03) {
-				kind = lm83;
-			} else
-			if (chip_id == 0x01) {
-				kind = lm82;
-			}
-		}
-
-		if (kind <= 0) { /* identification failed */
-			dev_info(&adapter->dev,
-			    "Unsupported chip (man_id=0x%02X, "
-			    "chip_id=0x%02X).\n", man_id, chip_id);
-			return -ENODEV;
-		}
-	}
-
-	if (kind == lm83) {
+	chip_id = i2c_smbus_read_byte_data(new_client, LM83_REG_R_CHIP_ID);
+	switch (chip_id) {
+	case 0x03:
 		name = "lm83";
-	} else
-	if (kind == lm82) {
+		break;
+	case 0x01:
 		name = "lm82";
+		break;
+	default:
+		/* identification failed */
+		dev_info(&adapter->dev,
+			 "Unsupported chip (man_id=0x%02X, chip_id=0x%02X)\n",
+			 man_id, chip_id);
+		return -ENODEV;
 	}
 
 	strlcpy(info->type, name, I2C_NAME_SIZE);
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c
index 6c53d98..d56da2e 100644
--- a/drivers/hwmon/lm85.c
+++ b/drivers/hwmon/lm85.c
@@ -5,7 +5,7 @@
     Copyright (c) 2002, 2003  Philip Pokorny <ppokorny@penguincomputing.com>
     Copyright (c) 2003        Margit Schubert-While <margitsw@t-online.de>
     Copyright (c) 2004        Justin Thiessen <jthiessen@penguincomputing.com>
-    Copyright (C) 2007, 2008  Jean Delvare <khali@linux-fr.org>
+    Copyright (C) 2007--2009  Jean Delvare <khali@linux-fr.org>
 
     Chip details at	      <http://www.national.com/ds/LM/LM85.pdf>
 
@@ -1162,107 +1162,80 @@
 	struct i2c_adapter *adapter = client->adapter;
 	int address = client->addr;
 	const char *type_name;
+	int company, verstep;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
 		/* We need to be able to do byte I/O */
 		return -ENODEV;
 	}
 
-	/* If auto-detecting, determine the chip type */
-	if (kind < 0) {
-		int company = lm85_read_value(client, LM85_REG_COMPANY);
-		int verstep = lm85_read_value(client, LM85_REG_VERSTEP);
+	/* Determine the chip type */
+	company = lm85_read_value(client, LM85_REG_COMPANY);
+	verstep = lm85_read_value(client, LM85_REG_VERSTEP);
 
-		dev_dbg(&adapter->dev, "Detecting device at 0x%02x with "
-			"COMPANY: 0x%02x and VERSTEP: 0x%02x\n",
-			address, company, verstep);
+	dev_dbg(&adapter->dev, "Detecting device at 0x%02x with "
+		"COMPANY: 0x%02x and VERSTEP: 0x%02x\n",
+		address, company, verstep);
 
-		/* All supported chips have the version in common */
-		if ((verstep & LM85_VERSTEP_VMASK) != LM85_VERSTEP_GENERIC &&
-		    (verstep & LM85_VERSTEP_VMASK) != LM85_VERSTEP_GENERIC2) {
-			dev_dbg(&adapter->dev, "Autodetection failed: "
-				"unsupported version\n");
-			return -ENODEV;
+	/* All supported chips have the version in common */
+	if ((verstep & LM85_VERSTEP_VMASK) != LM85_VERSTEP_GENERIC &&
+	    (verstep & LM85_VERSTEP_VMASK) != LM85_VERSTEP_GENERIC2) {
+		dev_dbg(&adapter->dev,
+			"Autodetection failed: unsupported version\n");
+		return -ENODEV;
+	}
+	type_name = "lm85";
+
+	/* Now, refine the detection */
+	if (company == LM85_COMPANY_NATIONAL) {
+		switch (verstep) {
+		case LM85_VERSTEP_LM85C:
+			type_name = "lm85c";
+			break;
+		case LM85_VERSTEP_LM85B:
+			type_name = "lm85b";
+			break;
+		case LM85_VERSTEP_LM96000_1:
+		case LM85_VERSTEP_LM96000_2:
+			/* Check for Winbond WPCD377I */
+			if (lm85_is_fake(client)) {
+				dev_dbg(&adapter->dev,
+					"Found Winbond WPCD377I, ignoring\n");
+				return -ENODEV;
+			}
+			break;
 		}
-		kind = any_chip;
-
-		/* Now, refine the detection */
-		if (company == LM85_COMPANY_NATIONAL) {
-			switch (verstep) {
-			case LM85_VERSTEP_LM85C:
-				kind = lm85c;
-				break;
-			case LM85_VERSTEP_LM85B:
-				kind = lm85b;
-				break;
-			case LM85_VERSTEP_LM96000_1:
-			case LM85_VERSTEP_LM96000_2:
-				/* Check for Winbond WPCD377I */
-				if (lm85_is_fake(client)) {
-					dev_dbg(&adapter->dev,
-						"Found Winbond WPCD377I, "
-						"ignoring\n");
-					return -ENODEV;
-				}
-				break;
-			}
-		} else if (company == LM85_COMPANY_ANALOG_DEV) {
-			switch (verstep) {
-			case LM85_VERSTEP_ADM1027:
-				kind = adm1027;
-				break;
-			case LM85_VERSTEP_ADT7463:
-			case LM85_VERSTEP_ADT7463C:
-				kind = adt7463;
-				break;
-			case LM85_VERSTEP_ADT7468_1:
-			case LM85_VERSTEP_ADT7468_2:
-				kind = adt7468;
-				break;
-			}
-		} else if (company == LM85_COMPANY_SMSC) {
-			switch (verstep) {
-			case LM85_VERSTEP_EMC6D100_A0:
-			case LM85_VERSTEP_EMC6D100_A1:
-				/* Note: we can't tell a '100 from a '101 */
-				kind = emc6d100;
-				break;
-			case LM85_VERSTEP_EMC6D102:
-				kind = emc6d102;
-				break;
-			}
-		} else {
-			dev_dbg(&adapter->dev, "Autodetection failed: "
-				"unknown vendor\n");
-			return -ENODEV;
+	} else if (company == LM85_COMPANY_ANALOG_DEV) {
+		switch (verstep) {
+		case LM85_VERSTEP_ADM1027:
+			type_name = "adm1027";
+			break;
+		case LM85_VERSTEP_ADT7463:
+		case LM85_VERSTEP_ADT7463C:
+			type_name = "adt7463";
+			break;
+		case LM85_VERSTEP_ADT7468_1:
+		case LM85_VERSTEP_ADT7468_2:
+			type_name = "adt7468";
+			break;
 		}
+	} else if (company == LM85_COMPANY_SMSC) {
+		switch (verstep) {
+		case LM85_VERSTEP_EMC6D100_A0:
+		case LM85_VERSTEP_EMC6D100_A1:
+			/* Note: we can't tell a '100 from a '101 */
+			type_name = "emc6d100";
+			break;
+		case LM85_VERSTEP_EMC6D102:
+			type_name = "emc6d102";
+			break;
+		}
+	} else {
+		dev_dbg(&adapter->dev,
+			"Autodetection failed: unknown vendor\n");
+		return -ENODEV;
 	}
 
-	switch (kind) {
-	case lm85b:
-		type_name = "lm85b";
-		break;
-	case lm85c:
-		type_name = "lm85c";
-		break;
-	case adm1027:
-		type_name = "adm1027";
-		break;
-	case adt7463:
-		type_name = "adt7463";
-		break;
-	case adt7468:
-		type_name = "adt7468";
-		break;
-	case emc6d100:
-		type_name = "emc6d100";
-		break;
-	case emc6d102:
-		type_name = "emc6d102";
-		break;
-	default:
-		type_name = "lm85";
-	}
 	strlcpy(info->type, type_name, I2C_NAME_SIZE);
 
 	return 0;
diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c
index 2e4a3ce..4929b18 100644
--- a/drivers/hwmon/lm87.c
+++ b/drivers/hwmon/lm87.c
@@ -666,37 +666,32 @@
 		       struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = new_client->adapter;
-	static const char *names[] = { "lm87", "adm1024" };
+	const char *name;
+	u8 cid, rev;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	/* Default to an LM87 if forced */
-	if (kind == 0)
-		kind = lm87;
+	if (lm87_read_value(new_client, LM87_REG_CONFIG) & 0x80)
+		return -ENODEV;
 
 	/* Now, we do the remaining detection. */
-	if (kind < 0) {
-		u8 cid = lm87_read_value(new_client, LM87_REG_COMPANY_ID);
-		u8 rev = lm87_read_value(new_client, LM87_REG_REVISION);
+	cid = lm87_read_value(new_client, LM87_REG_COMPANY_ID);
+	rev = lm87_read_value(new_client, LM87_REG_REVISION);
 
-		if (cid == 0x02			/* National Semiconductor */
-		 && (rev >= 0x01 && rev <= 0x08))
-			kind = lm87;
-		else if (cid == 0x41		/* Analog Devices */
-		      && (rev & 0xf0) == 0x10)
-			kind = adm1024;
-
-		if (kind < 0
-		 || (lm87_read_value(new_client, LM87_REG_CONFIG) & 0x80)) {
-			dev_dbg(&adapter->dev,
-				"LM87 detection failed at 0x%02x.\n",
-				new_client->addr);
-			return -ENODEV;
-		}
+	if (cid == 0x02			/* National Semiconductor */
+	 && (rev >= 0x01 && rev <= 0x08))
+		name = "lm87";
+	else if (cid == 0x41		/* Analog Devices */
+	      && (rev & 0xf0) == 0x10)
+		name = "adm1024";
+	else {
+		dev_dbg(&adapter->dev, "LM87 detection failed at 0x%02x\n",
+			new_client->addr);
+		return -ENODEV;
 	}
 
-	strlcpy(info->type, names[kind - 1], I2C_NAME_SIZE);
+	strlcpy(info->type, name, I2C_NAME_SIZE);
 
 	return 0;
 }
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
index 1aff757..b7c905f 100644
--- a/drivers/hwmon/lm90.c
+++ b/drivers/hwmon/lm90.c
@@ -1,7 +1,7 @@
 /*
  * lm90.c - Part of lm_sensors, Linux kernel modules for hardware
  *          monitoring
- * Copyright (C) 2003-2008  Jean Delvare <khali@linux-fr.org>
+ * Copyright (C) 2003-2009  Jean Delvare <khali@linux-fr.org>
  *
  * Based on the lm83 driver. The LM90 is a sensor chip made by National
  * Semiconductor. It reports up to two temperatures (its own plus up to
@@ -661,154 +661,118 @@
 {
 	struct i2c_adapter *adapter = new_client->adapter;
 	int address = new_client->addr;
-	const char *name = "";
+	const char *name = NULL;
+	int man_id, chip_id, reg_config1, reg_convrate;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	/*
-	 * Now we do the remaining detection. A negative kind means that
-	 * the driver was loaded with no force parameter (default), so we
-	 * must both detect and identify the chip. A zero kind means that
-	 * the driver was loaded with the force parameter, the detection
-	 * step shall be skipped. A positive kind means that the driver
-	 * was loaded with the force parameter and a given kind of chip is
-	 * requested, so both the detection and the identification steps
-	 * are skipped.
-	 */
-
-	/* Default to an LM90 if forced */
-	if (kind == 0)
-		kind = lm90;
-
-	if (kind < 0) { /* detection and identification */
-		int man_id, chip_id, reg_config1, reg_convrate;
-
-		if ((man_id = i2c_smbus_read_byte_data(new_client,
+	/* detection and identification */
+	if ((man_id = i2c_smbus_read_byte_data(new_client,
 						LM90_REG_R_MAN_ID)) < 0
-		 || (chip_id = i2c_smbus_read_byte_data(new_client,
+	 || (chip_id = i2c_smbus_read_byte_data(new_client,
 						LM90_REG_R_CHIP_ID)) < 0
-		 || (reg_config1 = i2c_smbus_read_byte_data(new_client,
+	 || (reg_config1 = i2c_smbus_read_byte_data(new_client,
 						LM90_REG_R_CONFIG1)) < 0
-		 || (reg_convrate = i2c_smbus_read_byte_data(new_client,
+	 || (reg_convrate = i2c_smbus_read_byte_data(new_client,
 						LM90_REG_R_CONVRATE)) < 0)
+		return -ENODEV;
+
+	if ((address == 0x4C || address == 0x4D)
+	 && man_id == 0x01) { /* National Semiconductor */
+		int reg_config2;
+
+		reg_config2 = i2c_smbus_read_byte_data(new_client,
+						LM90_REG_R_CONFIG2);
+		if (reg_config2 < 0)
 			return -ENODEV;
-		
-		if ((address == 0x4C || address == 0x4D)
-		 && man_id == 0x01) { /* National Semiconductor */
-			int reg_config2;
 
-			if ((reg_config2 = i2c_smbus_read_byte_data(new_client,
-						LM90_REG_R_CONFIG2)) < 0)
-				return -ENODEV;
-
-			if ((reg_config1 & 0x2A) == 0x00
-			 && (reg_config2 & 0xF8) == 0x00
-			 && reg_convrate <= 0x09) {
-				if (address == 0x4C
-				 && (chip_id & 0xF0) == 0x20) { /* LM90 */
-					kind = lm90;
-				} else
-				if ((chip_id & 0xF0) == 0x30) { /* LM89/LM99 */
-					kind = lm99;
-					dev_info(&adapter->dev,
-						 "Assuming LM99 chip at "
-						 "0x%02x\n", address);
-					dev_info(&adapter->dev,
-						 "If it is an LM89, pass "
-						 "force_lm86=%d,0x%02x when "
-						 "loading the lm90 driver\n",
-						 i2c_adapter_id(adapter),
-						 address);
-				} else
-				if (address == 0x4C
-				 && (chip_id & 0xF0) == 0x10) { /* LM86 */
-					kind = lm86;
-				}
-			}
-		} else
-		if ((address == 0x4C || address == 0x4D)
-		 && man_id == 0x41) { /* Analog Devices */
-			if ((chip_id & 0xF0) == 0x40 /* ADM1032 */
-			 && (reg_config1 & 0x3F) == 0x00
-			 && reg_convrate <= 0x0A) {
-				kind = adm1032;
+		if ((reg_config1 & 0x2A) == 0x00
+		 && (reg_config2 & 0xF8) == 0x00
+		 && reg_convrate <= 0x09) {
+			if (address == 0x4C
+			 && (chip_id & 0xF0) == 0x20) { /* LM90 */
+				name = "lm90";
 			} else
-			if (chip_id == 0x51 /* ADT7461 */
-			 && (reg_config1 & 0x1B) == 0x00
-			 && reg_convrate <= 0x0A) {
-				kind = adt7461;
-			}
-		} else
-		if (man_id == 0x4D) { /* Maxim */
-			/*
-			 * The MAX6657, MAX6658 and MAX6659 do NOT have a
-			 * chip_id register. Reading from that address will
-			 * return the last read value, which in our case is
-			 * those of the man_id register. Likewise, the config1
-			 * register seems to lack a low nibble, so the value
-			 * will be those of the previous read, so in our case
-			 * those of the man_id register.
-			 */
-			if (chip_id == man_id
-			 && (address == 0x4C || address == 0x4D)
-			 && (reg_config1 & 0x1F) == (man_id & 0x0F)
-			 && reg_convrate <= 0x09) {
-			 	kind = max6657;
+			if ((chip_id & 0xF0) == 0x30) { /* LM89/LM99 */
+				name = "lm99";
+				dev_info(&adapter->dev,
+					 "Assuming LM99 chip at 0x%02x\n",
+					 address);
+				dev_info(&adapter->dev,
+					 "If it is an LM89, instantiate it "
+					 "with the new_device sysfs "
+					 "interface\n");
 			} else
-			/* The chip_id register of the MAX6680 and MAX6681
-			 * holds the revision of the chip.
-			 * the lowest bit of the config1 register is unused
-			 * and should return zero when read, so should the
-			 * second to last bit of config1 (software reset)
-			 */
-			if (chip_id == 0x01
-			 && (reg_config1 & 0x03) == 0x00
-			 && reg_convrate <= 0x07) {
-			 	kind = max6680;
-			} else
-			/* The chip_id register of the MAX6646/6647/6649
-			 * holds the revision of the chip.
-			 * The lowest 6 bits of the config1 register are
-			 * unused and should return zero when read.
-			 */
-			if (chip_id == 0x59
-			 && (reg_config1 & 0x3f) == 0x00
-			 && reg_convrate <= 0x07) {
-				kind = max6646;
+			if (address == 0x4C
+			 && (chip_id & 0xF0) == 0x10) { /* LM86 */
+				name = "lm86";
 			}
 		}
-
-		if (kind <= 0) { /* identification failed */
-			dev_dbg(&adapter->dev,
-				"Unsupported chip at 0x%02x (man_id=0x%02X, "
-				"chip_id=0x%02X)\n", address, man_id, chip_id);
-			return -ENODEV;
+	} else
+	if ((address == 0x4C || address == 0x4D)
+	 && man_id == 0x41) { /* Analog Devices */
+		if ((chip_id & 0xF0) == 0x40 /* ADM1032 */
+		 && (reg_config1 & 0x3F) == 0x00
+		 && reg_convrate <= 0x0A) {
+			name = "adm1032";
+			/* The ADM1032 supports PEC, but only if combined
+			   transactions are not used. */
+			if (i2c_check_functionality(adapter,
+						    I2C_FUNC_SMBUS_BYTE))
+				info->flags |= I2C_CLIENT_PEC;
+		} else
+		if (chip_id == 0x51 /* ADT7461 */
+		 && (reg_config1 & 0x1B) == 0x00
+		 && reg_convrate <= 0x0A) {
+			name = "adt7461";
+		}
+	} else
+	if (man_id == 0x4D) { /* Maxim */
+		/*
+		 * The MAX6657, MAX6658 and MAX6659 do NOT have a chip_id
+		 * register. Reading from that address will return the last
+		 * read value, which in our case is those of the man_id
+		 * register. Likewise, the config1 register seems to lack a
+		 * low nibble, so the value will be those of the previous
+		 * read, so in our case those of the man_id register.
+		 */
+		if (chip_id == man_id
+		 && (address == 0x4C || address == 0x4D)
+		 && (reg_config1 & 0x1F) == (man_id & 0x0F)
+		 && reg_convrate <= 0x09) {
+			name = "max6657";
+		} else
+		/*
+		 * The chip_id register of the MAX6680 and MAX6681 holds the
+		 * revision of the chip. The lowest bit of the config1 register
+		 * is unused and should return zero when read, so should the
+		 * second to last bit of config1 (software reset).
+		 */
+		if (chip_id == 0x01
+		 && (reg_config1 & 0x03) == 0x00
+		 && reg_convrate <= 0x07) {
+			name = "max6680";
+		} else
+		/*
+		 * The chip_id register of the MAX6646/6647/6649 holds the
+		 * revision of the chip. The lowest 6 bits of the config1
+		 * register are unused and should return zero when read.
+		 */
+		if (chip_id == 0x59
+		 && (reg_config1 & 0x3f) == 0x00
+		 && reg_convrate <= 0x07) {
+			name = "max6646";
 		}
 	}
 
-	/* Fill the i2c board info */
-	if (kind == lm90) {
-		name = "lm90";
-	} else if (kind == adm1032) {
-		name = "adm1032";
-		/* The ADM1032 supports PEC, but only if combined
-		   transactions are not used. */
-		if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
-			info->flags |= I2C_CLIENT_PEC;
-	} else if (kind == lm99) {
-		name = "lm99";
-	} else if (kind == lm86) {
-		name = "lm86";
-	} else if (kind == max6657) {
-		name = "max6657";
-	} else if (kind == max6680) {
-		name = "max6680";
-	} else if (kind == adt7461) {
-		name = "adt7461";
-	} else if (kind == max6646) {
-		name = "max6646";
+	if (!name) { /* identification failed */
+		dev_dbg(&adapter->dev,
+			"Unsupported chip at 0x%02x (man_id=0x%02X, "
+			"chip_id=0x%02X)\n", address, man_id, chip_id);
+		return -ENODEV;
 	}
+
 	strlcpy(info->type, name, I2C_NAME_SIZE);
 
 	return 0;
diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c
index b2e00c5..47ac698 100644
--- a/drivers/hwmon/lm92.c
+++ b/drivers/hwmon/lm92.c
@@ -323,31 +323,22 @@
 		       struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = new_client->adapter;
+	u8 config;
+	u16 man_id;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
 					    | I2C_FUNC_SMBUS_WORD_DATA))
 		return -ENODEV;
 
-	/* A negative kind means that the driver was loaded with no force
-	   parameter (default), so we must identify the chip. */
-	if (kind < 0) {
-		u8 config = i2c_smbus_read_byte_data(new_client,
-			     LM92_REG_CONFIG);
-		u16 man_id = i2c_smbus_read_word_data(new_client,
-			     LM92_REG_MAN_ID);
+	config = i2c_smbus_read_byte_data(new_client, LM92_REG_CONFIG);
+	man_id = i2c_smbus_read_word_data(new_client, LM92_REG_MAN_ID);
 
-		if ((config & 0xe0) == 0x00
-		 && man_id == 0x0180) {
-			pr_info("lm92: Found National Semiconductor LM92 chip\n");
-	 		kind = lm92;
-		} else
-		if (max6635_check(new_client)) {
-			pr_info("lm92: Found Maxim MAX6635 chip\n");
-			kind = lm92; /* No separate prefix */
-		}
-		else
-			return -ENODEV;
-	}
+	if ((config & 0xe0) == 0x00 && man_id == 0x0180)
+		pr_info("lm92: Found National Semiconductor LM92 chip\n");
+	else if (max6635_check(new_client))
+		pr_info("lm92: Found Maxim MAX6635 chip\n");
+	else
+		return -ENODEV;
 
 	strlcpy(info->type, "lm92", I2C_NAME_SIZE);
 
diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c
index fc36cad..124dd7c 100644
--- a/drivers/hwmon/lm93.c
+++ b/drivers/hwmon/lm93.c
@@ -928,7 +928,7 @@
 	data->prochot_interval = lm93_read_byte(client,
 			LM93_REG_PROCHOT_INTERVAL);
 
-	/* Fan Boost Termperature registers */
+	/* Fan Boost Temperature registers */
 	for (i = 0; i < 4; i++)
 		data->boost[i] = lm93_read_byte(client, LM93_REG_BOOST(i));
 
@@ -2505,34 +2505,24 @@
 		       struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
+	int mfr, ver;
 
 	if (!i2c_check_functionality(adapter, LM93_SMBUS_FUNC_MIN))
 		return -ENODEV;
 
 	/* detection */
-	if (kind < 0) {
-		int mfr = lm93_read_byte(client, LM93_REG_MFR_ID);
-
-		if (mfr != 0x01) {
-			dev_dbg(&adapter->dev,"detect failed, "
-				"bad manufacturer id 0x%02x!\n", mfr);
-			return -ENODEV;
-		}
+	mfr = lm93_read_byte(client, LM93_REG_MFR_ID);
+	if (mfr != 0x01) {
+		dev_dbg(&adapter->dev,
+			"detect failed, bad manufacturer id 0x%02x!\n", mfr);
+		return -ENODEV;
 	}
 
-	if (kind <= 0) {
-		int ver = lm93_read_byte(client, LM93_REG_VER);
-
-		if ((ver == LM93_MFR_ID) || (ver == LM93_MFR_ID_PROTOTYPE)) {
-			kind = lm93;
-		} else {
-			dev_dbg(&adapter->dev,"detect failed, "
-				"bad version id 0x%02x!\n", ver);
-			if (kind == 0)
-				dev_dbg(&adapter->dev,
-					"(ignored 'force' parameter)\n");
-			return -ENODEV;
-		}
+	ver = lm93_read_byte(client, LM93_REG_VER);
+	if (ver != LM93_MFR_ID && ver != LM93_MFR_ID_PROTOTYPE) {
+		dev_dbg(&adapter->dev,
+			"detect failed, bad version id 0x%02x!\n", ver);
+		return -ENODEV;
 	}
 
 	strlcpy(info->type, "lm93", I2C_NAME_SIZE);
diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c
index e34f9e4..906b896 100644
--- a/drivers/hwmon/lm95241.c
+++ b/drivers/hwmon/lm95241.c
@@ -315,51 +315,23 @@
 {
 	struct i2c_adapter *adapter = new_client->adapter;
 	int address = new_client->addr;
-	const char *name = "";
+	const char *name;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	/*
-	 * Now we do the remaining detection. A negative kind means that
-	 * the driver was loaded with no force parameter (default), so we
-	 * must both detect and identify the chip. A zero kind means that
-	 * the driver was loaded with the force parameter, the detection
-	 * step shall be skipped. A positive kind means that the driver
-	 * was loaded with the force parameter and a given kind of chip is
-	 * requested, so both the detection and the identification steps
-	 * are skipped.
-	 */
-	if (kind < 0) {	/* detection */
-		if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID)
-		     != MANUFACTURER_ID)
-		|| (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID)
-		    < DEFAULT_REVISION)) {
-			dev_dbg(&adapter->dev,
-				"LM95241 detection failed at 0x%02x.\n",
-				address);
-			return -ENODEV;
-		}
-	}
-
-	if (kind <= 0) { /* identification */
-		if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID)
-		     == MANUFACTURER_ID)
-		&& (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID)
-		    >= DEFAULT_REVISION)) {
-
-			kind = lm95241;
-
-			if (kind <= 0) { /* identification failed */
-				dev_info(&adapter->dev, "Unsupported chip\n");
-				return -ENODEV;
-			}
-		}
+	if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID)
+	     == MANUFACTURER_ID)
+	 && (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID)
+	     >= DEFAULT_REVISION)) {
+		name = "lm95241";
+	} else {
+		dev_dbg(&adapter->dev, "LM95241 detection failed at 0x%02x\n",
+			address);
+		return -ENODEV;
 	}
 
 	/* Fill the i2c board info */
-	if (kind == lm95241)
-		name = "lm95241";
 	strlcpy(info->type, name, I2C_NAME_SIZE);
 	return 0;
 }
diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c
index 7897754..7fcf5ff 100644
--- a/drivers/hwmon/max1619.c
+++ b/drivers/hwmon/max1619.c
@@ -226,58 +226,34 @@
  */
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int max1619_detect(struct i2c_client *new_client, int kind,
+static int max1619_detect(struct i2c_client *client, int kind,
 			  struct i2c_board_info *info)
 {
-	struct i2c_adapter *adapter = new_client->adapter;
-	u8 reg_config=0, reg_convrate=0, reg_status=0;
+	struct i2c_adapter *adapter = client->adapter;
+	u8 reg_config, reg_convrate, reg_status, man_id, chip_id;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	/*
-	 * Now we do the remaining detection. A negative kind means that
-	 * the driver was loaded with no force parameter (default), so we
-	 * must both detect and identify the chip. A zero kind means that
-	 * the driver was loaded with the force parameter, the detection
-	 * step shall be skipped. A positive kind means that the driver
-	 * was loaded with the force parameter and a given kind of chip is
-	 * requested, so both the detection and the identification steps
-	 * are skipped.
-	 */
-	if (kind < 0) { /* detection */
-		reg_config = i2c_smbus_read_byte_data(new_client,
-			      MAX1619_REG_R_CONFIG);
-		reg_convrate = i2c_smbus_read_byte_data(new_client,
-			       MAX1619_REG_R_CONVRATE);
-		reg_status = i2c_smbus_read_byte_data(new_client,
-				MAX1619_REG_R_STATUS);
-		if ((reg_config & 0x03) != 0x00
-		 || reg_convrate > 0x07 || (reg_status & 0x61 ) !=0x00) {
-			dev_dbg(&adapter->dev,
-				"MAX1619 detection failed at 0x%02x.\n",
-				new_client->addr);
-			return -ENODEV;
-		}
+	/* detection */
+	reg_config = i2c_smbus_read_byte_data(client, MAX1619_REG_R_CONFIG);
+	reg_convrate = i2c_smbus_read_byte_data(client, MAX1619_REG_R_CONVRATE);
+	reg_status = i2c_smbus_read_byte_data(client, MAX1619_REG_R_STATUS);
+	if ((reg_config & 0x03) != 0x00
+	 || reg_convrate > 0x07 || (reg_status & 0x61) != 0x00) {
+		dev_dbg(&adapter->dev, "MAX1619 detection failed at 0x%02x\n",
+			client->addr);
+		return -ENODEV;
 	}
 
-	if (kind <= 0) { /* identification */
-		u8 man_id, chip_id;
-	
-		man_id = i2c_smbus_read_byte_data(new_client,
-			 MAX1619_REG_R_MAN_ID);
-		chip_id = i2c_smbus_read_byte_data(new_client,
-			  MAX1619_REG_R_CHIP_ID);
-		
-		if ((man_id == 0x4D) && (chip_id == 0x04))
-			kind = max1619;
-
-		if (kind <= 0) { /* identification failed */
-			dev_info(&adapter->dev,
-			    "Unsupported chip (man_id=0x%02X, "
-			    "chip_id=0x%02X).\n", man_id, chip_id);
-			return -ENODEV;
-		}
+	/* identification */
+	man_id = i2c_smbus_read_byte_data(client, MAX1619_REG_R_MAN_ID);
+	chip_id = i2c_smbus_read_byte_data(client, MAX1619_REG_R_CHIP_ID);
+	if (man_id != 0x4D || chip_id != 0x04) {
+		dev_info(&adapter->dev,
+			 "Unsupported chip (man_id=0x%02X, chip_id=0x%02X).\n",
+			 man_id, chip_id);
+		return -ENODEV;
 	}
 
 	strlcpy(info->type, "max1619", I2C_NAME_SIZE);
diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c
index 58f66be..1da561e 100644
--- a/drivers/hwmon/max6650.c
+++ b/drivers/hwmon/max6650.c
@@ -534,7 +534,7 @@
 	struct i2c_adapter *adapter = client->adapter;
 	int address = client->addr;
 
-	dev_dbg(&adapter->dev, "max6650_detect called, kind = %d\n", kind);
+	dev_dbg(&adapter->dev, "max6650_detect called\n");
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
 		dev_dbg(&adapter->dev, "max6650: I2C bus doesn't support "
@@ -542,23 +542,7 @@
 		return -ENODEV;
 	}
 
-	/*
-	 * Now we do the remaining detection. A negative kind means that
-	 * the driver was loaded with no force parameter (default), so we
-	 * must both detect and identify the chip (actually there is only
-	 * one possible kind of chip for now, max6650). A zero kind means that
-	 * the driver was loaded with the force parameter, the detection
-	 * step shall be skipped. A positive kind means that the driver
-	 * was loaded with the force parameter and a given kind of chip is
-	 * requested, so both the detection and the identification steps
-	 * are skipped.
-	 *
-	 * Currently I can find no way to distinguish between a MAX6650 and
-	 * a MAX6651. This driver has only been tried on the former.
-	 */
-
-	if ((kind < 0) &&
-	   (  (i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG) & 0xC0)
+	if (((i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG) & 0xC0)
 	    ||(i2c_smbus_read_byte_data(client, MAX6650_REG_GPIO_STAT) & 0xE0)
 	    ||(i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM_EN) & 0xE0)
 	    ||(i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM) & 0xE0)
diff --git a/drivers/hwmon/mc13783-adc.c b/drivers/hwmon/mc13783-adc.c
new file mode 100644
index 0000000..883fa81
--- /dev/null
+++ b/drivers/hwmon/mc13783-adc.c
@@ -0,0 +1,236 @@
+/*
+ * Driver for the Freescale Semiconductor MC13783 adc.
+ *
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009 Sascha Hauer, Pengutronix
+ *
+ * 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., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/mfd/mc13783-private.h>
+#include <linux/platform_device.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/hwmon.h>
+#include <linux/init.h>
+#include <linux/err.h>
+
+#define MC13783_ADC_NAME	"mc13783-adc"
+
+struct mc13783_adc_priv {
+	struct mc13783 *mc13783;
+	struct device *hwmon_dev;
+};
+
+static ssize_t mc13783_adc_show_name(struct device *dev, struct device_attribute
+			      *devattr, char *buf)
+{
+	return sprintf(buf, "mc13783_adc\n");
+}
+
+static int mc13783_adc_read(struct device *dev,
+		struct device_attribute *devattr, unsigned int *val)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct mc13783_adc_priv *priv = platform_get_drvdata(pdev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	unsigned int channel = attr->index;
+	unsigned int sample[4];
+	int ret;
+
+	ret = mc13783_adc_do_conversion(priv->mc13783,
+			MC13783_ADC_MODE_MULT_CHAN,
+			channel, sample);
+	if (ret)
+		return ret;
+
+	channel &= 0x7;
+
+	*val = (sample[channel % 4] >> (channel > 3 ? 14 : 2)) & 0x3ff;
+
+	return 0;
+}
+
+static ssize_t mc13783_adc_read_bp(struct device *dev,
+		struct device_attribute *devattr, char *buf)
+{
+	unsigned val;
+	int ret = mc13783_adc_read(dev, devattr, &val);
+
+	if (ret)
+		return ret;
+
+	/*
+	 * BP (channel 2) reports with offset 2.4V to the actual value to fit
+	 * the input range of the ADC.  unit = 2.25mV = 9/4 mV.
+	 */
+	val = DIV_ROUND_CLOSEST(val * 9, 4) + 2400;
+
+	return sprintf(buf, "%u\n", val);
+}
+
+static ssize_t mc13783_adc_read_gp(struct device *dev,
+		struct device_attribute *devattr, char *buf)
+{
+	unsigned val;
+	int ret = mc13783_adc_read(dev, devattr, &val);
+
+	if (ret)
+		return ret;
+
+	/*
+	 * input range is [0, 2.3V], val has 10 bits, so each bit
+	 * is worth 9/4 mV.
+	 */
+	val = DIV_ROUND_CLOSEST(val * 9, 4);
+
+	return sprintf(buf, "%u\n", val);
+}
+
+static DEVICE_ATTR(name, S_IRUGO, mc13783_adc_show_name, NULL);
+static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, mc13783_adc_read_bp, NULL, 2);
+static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, mc13783_adc_read_gp, NULL, 5);
+static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, mc13783_adc_read_gp, NULL, 6);
+static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, mc13783_adc_read_gp, NULL, 7);
+static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, mc13783_adc_read_gp, NULL, 8);
+static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, mc13783_adc_read_gp, NULL, 9);
+static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, mc13783_adc_read_gp, NULL, 10);
+static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, mc13783_adc_read_gp, NULL, 11);
+static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, mc13783_adc_read_gp, NULL, 12);
+static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, mc13783_adc_read_gp, NULL, 13);
+static SENSOR_DEVICE_ATTR(in14_input, S_IRUGO, mc13783_adc_read_gp, NULL, 14);
+static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, mc13783_adc_read_gp, NULL, 15);
+
+static struct attribute *mc13783_attr[] = {
+	&dev_attr_name.attr,
+	&sensor_dev_attr_in2_input.dev_attr.attr,
+	&sensor_dev_attr_in5_input.dev_attr.attr,
+	&sensor_dev_attr_in6_input.dev_attr.attr,
+	&sensor_dev_attr_in7_input.dev_attr.attr,
+	&sensor_dev_attr_in8_input.dev_attr.attr,
+	&sensor_dev_attr_in9_input.dev_attr.attr,
+	&sensor_dev_attr_in10_input.dev_attr.attr,
+	&sensor_dev_attr_in11_input.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group mc13783_group = {
+	.attrs = mc13783_attr,
+};
+
+/* last four channels may be occupied by the touchscreen */
+static struct attribute *mc13783_attr_ts[] = {
+	&sensor_dev_attr_in12_input.dev_attr.attr,
+	&sensor_dev_attr_in13_input.dev_attr.attr,
+	&sensor_dev_attr_in14_input.dev_attr.attr,
+	&sensor_dev_attr_in15_input.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group mc13783_group_ts = {
+	.attrs = mc13783_attr_ts,
+};
+
+static int __init mc13783_adc_probe(struct platform_device *pdev)
+{
+	struct mc13783_adc_priv *priv;
+	int ret;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->mc13783 = dev_get_drvdata(pdev->dev.parent);
+
+	platform_set_drvdata(pdev, priv);
+
+	/* Register sysfs hooks */
+	ret = sysfs_create_group(&pdev->dev.kobj, &mc13783_group);
+	if (ret)
+		goto out_err_create1;
+
+	if (!(priv->mc13783->flags & MC13783_USE_TOUCHSCREEN))
+		ret = sysfs_create_group(&pdev->dev.kobj, &mc13783_group_ts);
+		if (ret)
+			goto out_err_create2;
+
+	priv->hwmon_dev = hwmon_device_register(&pdev->dev);
+	if (IS_ERR(priv->hwmon_dev)) {
+		ret = PTR_ERR(priv->hwmon_dev);
+		dev_err(&pdev->dev,
+				"hwmon_device_register failed with %d.\n", ret);
+		goto out_err_register;
+	}
+
+
+	return 0;
+
+out_err_register:
+
+	if (!(priv->mc13783->flags & MC13783_USE_TOUCHSCREEN))
+		sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_ts);
+out_err_create2:
+
+	sysfs_remove_group(&pdev->dev.kobj, &mc13783_group);
+out_err_create1:
+
+	platform_set_drvdata(pdev, NULL);
+	kfree(priv);
+
+	return ret;
+}
+
+static int __devexit mc13783_adc_remove(struct platform_device *pdev)
+{
+	struct mc13783_adc_priv *priv = platform_get_drvdata(pdev);
+
+	hwmon_device_unregister(priv->hwmon_dev);
+
+	if (!(priv->mc13783->flags & MC13783_USE_TOUCHSCREEN))
+		sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_ts);
+
+	sysfs_remove_group(&pdev->dev.kobj, &mc13783_group);
+
+	platform_set_drvdata(pdev, NULL);
+	kfree(priv);
+
+	return 0;
+}
+
+static struct platform_driver mc13783_adc_driver = {
+	.remove 	= __devexit_p(mc13783_adc_remove),
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= MC13783_ADC_NAME,
+	},
+};
+
+static int __init mc13783_adc_init(void)
+{
+	return platform_driver_probe(&mc13783_adc_driver, mc13783_adc_probe);
+}
+
+static void __exit mc13783_adc_exit(void)
+{
+	platform_driver_unregister(&mc13783_adc_driver);
+}
+
+module_init(mc13783_adc_init);
+module_exit(mc13783_adc_exit);
+
+MODULE_DESCRIPTION("MC13783 ADC driver");
+MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" MC13783_ADC_NAME);
diff --git a/drivers/hwmon/s3c-hwmon.c b/drivers/hwmon/s3c-hwmon.c
index 7183541..3f3f9a4 100644
--- a/drivers/hwmon/s3c-hwmon.c
+++ b/drivers/hwmon/s3c-hwmon.c
@@ -323,7 +323,7 @@
 	}
 
 	for (i = 0; i < ARRAY_SIZE(pdata->in); i++) {
-		struct s3c24xx_adc_hwmon_incfg *cfg = pdata->in[i];
+		struct s3c_hwmon_chcfg *cfg = pdata->in[i];
 
 		if (!cfg)
 			continue;
@@ -333,7 +333,7 @@
 				 "channel %d multiplier too large\n",
 				 i);
 
-		if (cfg->divider == 0) {
+		if (cfg->div == 0) {
 			dev_err(&dev->dev, "channel %d divider zero\n", i);
 			continue;
 		}
diff --git a/drivers/hwmon/smsc47m192.c b/drivers/hwmon/smsc47m192.c
index 8bb5cb5..4d88c04 100644
--- a/drivers/hwmon/smsc47m192.c
+++ b/drivers/hwmon/smsc47m192.c
@@ -491,24 +491,22 @@
 		return -ENODEV;
 
 	/* Detection criteria from sensors_detect script */
-	if (kind < 0) {
-		if (i2c_smbus_read_byte_data(client,
+	version = i2c_smbus_read_byte_data(client, SMSC47M192_REG_VERSION);
+	if (i2c_smbus_read_byte_data(client,
 				SMSC47M192_REG_COMPANY_ID) == 0x55
-		 && ((version = i2c_smbus_read_byte_data(client,
-				SMSC47M192_REG_VERSION)) & 0xf0) == 0x20
-		 && (i2c_smbus_read_byte_data(client,
+	 && (version & 0xf0) == 0x20
+	 && (i2c_smbus_read_byte_data(client,
 				SMSC47M192_REG_VID) & 0x70) == 0x00
-		 && (i2c_smbus_read_byte_data(client,
+	 && (i2c_smbus_read_byte_data(client,
 				SMSC47M192_REG_VID4) & 0xfe) == 0x80) {
-			dev_info(&adapter->dev,
-				 "found SMSC47M192 or compatible, "
-				 "version 2, stepping A%d\n", version & 0x0f);
-		} else {
-			dev_dbg(&adapter->dev,
-				"SMSC47M192 detection failed at 0x%02x\n",
-				client->addr);
-			return -ENODEV;
-		}
+		dev_info(&adapter->dev,
+			 "found SMSC47M192 or compatible, "
+			 "version 2, stepping A%d\n", version & 0x0f);
+	} else {
+		dev_dbg(&adapter->dev,
+			"SMSC47M192 detection failed at 0x%02x\n",
+			client->addr);
+		return -ENODEV;
 	}
 
 	strlcpy(info->type, "smsc47m192", I2C_NAME_SIZE);
diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c
index 7d97431..4b79384 100644
--- a/drivers/hwmon/thmc50.c
+++ b/drivers/hwmon/thmc50.c
@@ -36,7 +36,11 @@
 
 /* Insmod parameters */
 I2C_CLIENT_INSMOD_2(thmc50, adm1022);
-I2C_CLIENT_MODULE_PARM(adm1022_temp3, "List of adapter,address pairs "
+
+static unsigned short adm1022_temp3[16];
+static unsigned int adm1022_temp3_num;
+module_param_array(adm1022_temp3, ushort, &adm1022_temp3_num, 0);
+MODULE_PARM_DESC(adm1022_temp3, "List of adapter,address pairs "
 			"to enable 3rd temperature (ADM1022 only)");
 
 /* Many THMC50 constants specified below */
@@ -289,7 +293,6 @@
 	unsigned revision;
 	unsigned config;
 	struct i2c_adapter *adapter = client->adapter;
-	int err = 0;
 	const char *type_name;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
@@ -301,31 +304,13 @@
 	pr_debug("thmc50: Probing for THMC50 at 0x%2X on bus %d\n",
 		 client->addr, i2c_adapter_id(client->adapter));
 
-	/* Now, we do the remaining detection. */
 	company = i2c_smbus_read_byte_data(client, THMC50_REG_COMPANY_ID);
 	revision = i2c_smbus_read_byte_data(client, THMC50_REG_DIE_CODE);
 	config = i2c_smbus_read_byte_data(client, THMC50_REG_CONF);
+	if (revision < 0xc0 || (config & 0x10))
+		return -ENODEV;
 
-	if (kind == 0)
-		kind = thmc50;
-	else if (kind < 0) {
-		err = -ENODEV;
-		if (revision >= 0xc0 && ((config & 0x10) == 0)) {
-			if (company == 0x49) {
-				kind = thmc50;
-				err = 0;
-			} else if (company == 0x41) {
-				kind = adm1022;
-				err = 0;
-			}
-		}
-	}
-	if (err == -ENODEV) {
-		pr_debug("thmc50: Detection of THMC50/ADM1022 failed\n");
-		return err;
-	}
-
-	if (kind == adm1022) {
+	if (company == 0x41) {
 		int id = i2c_adapter_id(client->adapter);
 		int i;
 
@@ -340,9 +325,13 @@
 							  config);
 				break;
 			}
-	} else {
+	} else if (company == 0x49) {
 		type_name = "thmc50";
+	} else {
+		pr_debug("thmc50: Detection of THMC50/ADM1022 failed\n");
+		return -ENODEV;
 	}
+
 	pr_debug("thmc50: Detected %s (version %x, revision %x)\n",
 		 type_name, (revision >> 4) - 0xc, revision & 0xf);
 
diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c
index 7b34f2c..ee96734 100644
--- a/drivers/hwmon/tmp401.c
+++ b/drivers/hwmon/tmp401.c
@@ -488,46 +488,43 @@
 		i2c_smbus_write_byte_data(client, TMP401_CONFIG_WRITE, config);
 }
 
-static int tmp401_detect(struct i2c_client *client, int kind,
+static int tmp401_detect(struct i2c_client *client, int _kind,
 			 struct i2c_board_info *info)
 {
+	enum chips kind;
 	struct i2c_adapter *adapter = client->adapter;
+	u8 reg;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
 	/* Detect and identify the chip */
-	if (kind <= 0) {
-		u8 reg;
+	reg = i2c_smbus_read_byte_data(client, TMP401_MANUFACTURER_ID_REG);
+	if (reg != TMP401_MANUFACTURER_ID)
+		return -ENODEV;
 
-		reg = i2c_smbus_read_byte_data(client,
-					       TMP401_MANUFACTURER_ID_REG);
-		if (reg != TMP401_MANUFACTURER_ID)
-			return -ENODEV;
+	reg = i2c_smbus_read_byte_data(client, TMP401_DEVICE_ID_REG);
 
-		reg = i2c_smbus_read_byte_data(client, TMP401_DEVICE_ID_REG);
-
-		switch (reg) {
-		case TMP401_DEVICE_ID:
-			kind = tmp401;
-			break;
-		case TMP411_DEVICE_ID:
-			kind = tmp411;
-			break;
-		default:
-			return -ENODEV;
-		}
-
-		reg = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ);
-		if (reg & 0x1b)
-			return -ENODEV;
-
-		reg = i2c_smbus_read_byte_data(client,
-					       TMP401_CONVERSION_RATE_READ);
-		/* Datasheet says: 0x1-0x6 */
-		if (reg > 15)
-			return -ENODEV;
+	switch (reg) {
+	case TMP401_DEVICE_ID:
+		kind = tmp401;
+		break;
+	case TMP411_DEVICE_ID:
+		kind = tmp411;
+		break;
+	default:
+		return -ENODEV;
 	}
+
+	reg = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ);
+	if (reg & 0x1b)
+		return -ENODEV;
+
+	reg = i2c_smbus_read_byte_data(client, TMP401_CONVERSION_RATE_READ);
+	/* Datasheet says: 0x1-0x6 */
+	if (reg > 15)
+		return -ENODEV;
+
 	strlcpy(info->type, tmp401_id[kind - 1].name, I2C_NAME_SIZE);
 
 	return 0;
diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c
index 2092434..bb5464a 100644
--- a/drivers/hwmon/tmp421.c
+++ b/drivers/hwmon/tmp421.c
@@ -223,39 +223,36 @@
 	return 0;
 }
 
-static int tmp421_detect(struct i2c_client *client, int kind,
+static int tmp421_detect(struct i2c_client *client, int _kind,
 			 struct i2c_board_info *info)
 {
+	enum chips kind;
 	struct i2c_adapter *adapter = client->adapter;
 	const char *names[] = { "TMP421", "TMP422", "TMP423" };
+	u8 reg;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	if (kind <= 0) {
-		u8 reg;
+	reg = i2c_smbus_read_byte_data(client, TMP421_MANUFACTURER_ID_REG);
+	if (reg != TMP421_MANUFACTURER_ID)
+		return -ENODEV;
 
-		reg = i2c_smbus_read_byte_data(client,
-					       TMP421_MANUFACTURER_ID_REG);
-		if (reg != TMP421_MANUFACTURER_ID)
-			return -ENODEV;
-
-		reg = i2c_smbus_read_byte_data(client,
-					       TMP421_DEVICE_ID_REG);
-		switch (reg) {
-		case TMP421_DEVICE_ID:
-			kind = tmp421;
-			break;
-		case TMP422_DEVICE_ID:
-			kind = tmp422;
-			break;
-		case TMP423_DEVICE_ID:
-			kind = tmp423;
-			break;
-		default:
-			return -ENODEV;
-		}
+	reg = i2c_smbus_read_byte_data(client, TMP421_DEVICE_ID_REG);
+	switch (reg) {
+	case TMP421_DEVICE_ID:
+		kind = tmp421;
+		break;
+	case TMP422_DEVICE_ID:
+		kind = tmp422;
+		break;
+	case TMP423_DEVICE_ID:
+		kind = tmp423;
+		break;
+	default:
+		return -ENODEV;
 	}
+
 	strlcpy(info->type, tmp421_id[kind - 1].name, I2C_NAME_SIZE);
 	dev_info(&adapter->dev, "Detected TI %s chip at 0x%02x\n",
 		 names[kind - 1], client->addr);
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index 2be28ac..b257c72 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -59,10 +59,11 @@
 #define DRVNAME "w83627hf"
 enum chips { w83627hf, w83627thf, w83697hf, w83637hf, w83687thf };
 
-static u16 force_addr;
-module_param(force_addr, ushort, 0);
-MODULE_PARM_DESC(force_addr,
-		 "Initialize the base address of the sensors");
+struct w83627hf_sio_data {
+	enum chips type;
+	int sioaddr;
+};
+
 static u8 force_i2c = 0x1f;
 module_param(force_i2c, byte, 0);
 MODULE_PARM_DESC(force_i2c,
@@ -77,9 +78,7 @@
 MODULE_PARM_DESC(force_id, "Override the detected device ID");
 
 /* modified from kernel/include/traps.c */
-static int REG;		/* The register to read/write */
 #define	DEV	0x07	/* Register: Logical device select */
-static int VAL;		/* The value to read/write */
 
 /* logical device numbers for superio_select (below) */
 #define W83627HF_LD_FDC		0x00
@@ -109,37 +108,37 @@
 #define W83687THF_VID_DATA	0xF1 /* w83687thf only */
 
 static inline void
-superio_outb(int reg, int val)
+superio_outb(struct w83627hf_sio_data *sio, int reg, int val)
 {
-	outb(reg, REG);
-	outb(val, VAL);
+	outb(reg, sio->sioaddr);
+	outb(val, sio->sioaddr + 1);
 }
 
 static inline int
-superio_inb(int reg)
+superio_inb(struct w83627hf_sio_data *sio, int reg)
 {
-	outb(reg, REG);
-	return inb(VAL);
+	outb(reg, sio->sioaddr);
+	return inb(sio->sioaddr + 1);
 }
 
 static inline void
-superio_select(int ld)
+superio_select(struct w83627hf_sio_data *sio, int ld)
 {
-	outb(DEV, REG);
-	outb(ld, VAL);
+	outb(DEV, sio->sioaddr);
+	outb(ld,  sio->sioaddr + 1);
 }
 
 static inline void
-superio_enter(void)
+superio_enter(struct w83627hf_sio_data *sio)
 {
-	outb(0x87, REG);
-	outb(0x87, REG);
+	outb(0x87, sio->sioaddr);
+	outb(0x87, sio->sioaddr);
 }
 
 static inline void
-superio_exit(void)
+superio_exit(struct w83627hf_sio_data *sio)
 {
-	outb(0xAA, REG);
+	outb(0xAA, sio->sioaddr);
 }
 
 #define W627_DEVID 0x52
@@ -380,10 +379,6 @@
 	u8 vrm_ovt;		/* Register value, 627THF/637HF/687THF only */
 };
 
-struct w83627hf_sio_data {
-	enum chips type;
-};
-
 
 static int w83627hf_probe(struct platform_device *pdev);
 static int __devexit w83627hf_remove(struct platform_device *pdev);
@@ -1140,11 +1135,8 @@
 		"W83687THF",
 	};
 
-	REG = sioaddr;
-	VAL = sioaddr + 1;
-
-	superio_enter();
-	val = force_id ? force_id : superio_inb(DEVID);
+	superio_enter(sio_data);
+	val = force_id ? force_id : superio_inb(sio_data, DEVID);
 	switch (val) {
 	case W627_DEVID:
 		sio_data->type = w83627hf;
@@ -1168,16 +1160,9 @@
 		goto exit;
 	}
 
-	superio_select(W83627HF_LD_HWM);
-	force_addr &= WINB_ALIGNMENT;
-	if (force_addr) {
-		printk(KERN_WARNING DRVNAME ": Forcing address 0x%x\n",
-		       force_addr);
-		superio_outb(WINB_BASE_REG, force_addr >> 8);
-		superio_outb(WINB_BASE_REG + 1, force_addr & 0xff);
-	}
-	val = (superio_inb(WINB_BASE_REG) << 8) |
-	       superio_inb(WINB_BASE_REG + 1);
+	superio_select(sio_data, W83627HF_LD_HWM);
+	val = (superio_inb(sio_data, WINB_BASE_REG) << 8) |
+	       superio_inb(sio_data, WINB_BASE_REG + 1);
 	*addr = val & WINB_ALIGNMENT;
 	if (*addr == 0) {
 		printk(KERN_WARNING DRVNAME ": Base address not set, "
@@ -1185,18 +1170,19 @@
 		goto exit;
 	}
 
-	val = superio_inb(WINB_ACT_REG);
+	val = superio_inb(sio_data, WINB_ACT_REG);
 	if (!(val & 0x01)) {
 		printk(KERN_WARNING DRVNAME ": Enabling HWM logical device\n");
-		superio_outb(WINB_ACT_REG, val | 0x01);
+		superio_outb(sio_data, WINB_ACT_REG, val | 0x01);
 	}
 
 	err = 0;
+	sio_data->sioaddr = sioaddr;
 	pr_info(DRVNAME ": Found %s chip at %#x\n",
 		names[sio_data->type], *addr);
 
  exit:
-	superio_exit();
+	superio_exit(sio_data);
 	return err;
 }
 
@@ -1511,20 +1497,21 @@
 
 static int __devinit w83627thf_read_gpio5(struct platform_device *pdev)
 {
+	struct w83627hf_sio_data *sio_data = pdev->dev.platform_data;
 	int res = 0xff, sel;
 
-	superio_enter();
-	superio_select(W83627HF_LD_GPIO5);
+	superio_enter(sio_data);
+	superio_select(sio_data, W83627HF_LD_GPIO5);
 
 	/* Make sure these GPIO pins are enabled */
-	if (!(superio_inb(W83627THF_GPIO5_EN) & (1<<3))) {
+	if (!(superio_inb(sio_data, W83627THF_GPIO5_EN) & (1<<3))) {
 		dev_dbg(&pdev->dev, "GPIO5 disabled, no VID function\n");
 		goto exit;
 	}
 
 	/* Make sure the pins are configured for input
 	   There must be at least five (VRM 9), and possibly 6 (VRM 10) */
-	sel = superio_inb(W83627THF_GPIO5_IOSR) & 0x3f;
+	sel = superio_inb(sio_data, W83627THF_GPIO5_IOSR) & 0x3f;
 	if ((sel & 0x1f) != 0x1f) {
 		dev_dbg(&pdev->dev, "GPIO5 not configured for VID "
 			"function\n");
@@ -1532,37 +1519,38 @@
 	}
 
 	dev_info(&pdev->dev, "Reading VID from GPIO5\n");
-	res = superio_inb(W83627THF_GPIO5_DR) & sel;
+	res = superio_inb(sio_data, W83627THF_GPIO5_DR) & sel;
 
 exit:
-	superio_exit();
+	superio_exit(sio_data);
 	return res;
 }
 
 static int __devinit w83687thf_read_vid(struct platform_device *pdev)
 {
+	struct w83627hf_sio_data *sio_data = pdev->dev.platform_data;
 	int res = 0xff;
 
-	superio_enter();
-	superio_select(W83627HF_LD_HWM);
+	superio_enter(sio_data);
+	superio_select(sio_data, W83627HF_LD_HWM);
 
 	/* Make sure these GPIO pins are enabled */
-	if (!(superio_inb(W83687THF_VID_EN) & (1 << 2))) {
+	if (!(superio_inb(sio_data, W83687THF_VID_EN) & (1 << 2))) {
 		dev_dbg(&pdev->dev, "VID disabled, no VID function\n");
 		goto exit;
 	}
 
 	/* Make sure the pins are configured for input */
-	if (!(superio_inb(W83687THF_VID_CFG) & (1 << 4))) {
+	if (!(superio_inb(sio_data, W83687THF_VID_CFG) & (1 << 4))) {
 		dev_dbg(&pdev->dev, "VID configured as output, "
 			"no VID function\n");
 		goto exit;
 	}
 
-	res = superio_inb(W83687THF_VID_DATA) & 0x3f;
+	res = superio_inb(sio_data, W83687THF_VID_DATA) & 0x3f;
 
 exit:
-	superio_exit();
+	superio_exit(sio_data);
 	return res;
 }
 
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index d27ed1b..7ab7967 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -1054,11 +1054,11 @@
 w83781d_detect(struct i2c_client *client, int kind,
 	       struct i2c_board_info *info)
 {
-	int val1 = 0, val2;
+	int val1, val2;
 	struct w83781d_data *isa = w83781d_data_if_isa();
 	struct i2c_adapter *adapter = client->adapter;
 	int address = client->addr;
-	const char *client_name = "";
+	const char *client_name;
 	enum vendor { winbond, asus } vendid;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -1070,98 +1070,73 @@
 	if (isa)
 		mutex_lock(&isa->update_lock);
 
-	/* The w8378?d may be stuck in some other bank than bank 0. This may
-	   make reading other information impossible. Specify a force=... or
-	   force_*=... parameter, and the Winbond will be reset to the right
-	   bank. */
-	if (kind < 0) {
-		if (i2c_smbus_read_byte_data
-		    (client, W83781D_REG_CONFIG) & 0x80) {
-			dev_dbg(&adapter->dev, "Detection of w83781d chip "
-				"failed at step 3\n");
+	if (i2c_smbus_read_byte_data(client, W83781D_REG_CONFIG) & 0x80) {
+		dev_dbg(&adapter->dev,
+			"Detection of w83781d chip failed at step 3\n");
+		goto err_nodev;
+	}
+
+	val1 = i2c_smbus_read_byte_data(client, W83781D_REG_BANK);
+	val2 = i2c_smbus_read_byte_data(client, W83781D_REG_CHIPMAN);
+	/* Check for Winbond or Asus ID if in bank 0 */
+	if (!(val1 & 0x07) &&
+	    ((!(val1 & 0x80) && val2 != 0xa3 && val2 != 0xc3) ||
+	     ( (val1 & 0x80) && val2 != 0x5c && val2 != 0x12))) {
+		dev_dbg(&adapter->dev,
+			"Detection of w83781d chip failed at step 4\n");
+		goto err_nodev;
+	}
+	/* If Winbond SMBus, check address at 0x48.
+	   Asus doesn't support, except for as99127f rev.2 */
+	if ((!(val1 & 0x80) && val2 == 0xa3) ||
+	    ( (val1 & 0x80) && val2 == 0x5c)) {
+		if (i2c_smbus_read_byte_data(client, W83781D_REG_I2C_ADDR)
+		    != address) {
+			dev_dbg(&adapter->dev,
+				"Detection of w83781d chip failed at step 5\n");
 			goto err_nodev;
 		}
-		val1 = i2c_smbus_read_byte_data(client, W83781D_REG_BANK);
-		val2 = i2c_smbus_read_byte_data(client, W83781D_REG_CHIPMAN);
-		/* Check for Winbond or Asus ID if in bank 0 */
-		if ((!(val1 & 0x07)) &&
-		    (((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3))
-		     || ((val1 & 0x80) && (val2 != 0x5c) && (val2 != 0x12)))) {
-			dev_dbg(&adapter->dev, "Detection of w83781d chip "
-				"failed at step 4\n");
-			goto err_nodev;
-		}
-		/* If Winbond SMBus, check address at 0x48.
-		   Asus doesn't support, except for as99127f rev.2 */
-		if ((!(val1 & 0x80) && (val2 == 0xa3)) ||
-		    ((val1 & 0x80) && (val2 == 0x5c))) {
-			if (i2c_smbus_read_byte_data
-			    (client, W83781D_REG_I2C_ADDR) != address) {
-				dev_dbg(&adapter->dev, "Detection of w83781d "
-					"chip failed at step 5\n");
-				goto err_nodev;
-			}
-		}
 	}
 
-	/* We have either had a force parameter, or we have already detected the
-	   Winbond. Put it now into bank 0 and Vendor ID High Byte */
+	/* Put it now into bank 0 and Vendor ID High Byte */
 	i2c_smbus_write_byte_data(client, W83781D_REG_BANK,
 		(i2c_smbus_read_byte_data(client, W83781D_REG_BANK)
 		 & 0x78) | 0x80);
 
+	/* Get the vendor ID */
+	val2 = i2c_smbus_read_byte_data(client, W83781D_REG_CHIPMAN);
+	if (val2 == 0x5c)
+		vendid = winbond;
+	else if (val2 == 0x12)
+		vendid = asus;
+	else {
+		dev_dbg(&adapter->dev,
+			"w83781d chip vendor is neither Winbond nor Asus\n");
+		goto err_nodev;
+	}
+
 	/* Determine the chip type. */
-	if (kind <= 0) {
-		/* get vendor ID */
-		val2 = i2c_smbus_read_byte_data(client, W83781D_REG_CHIPMAN);
-		if (val2 == 0x5c)
-			vendid = winbond;
-		else if (val2 == 0x12)
-			vendid = asus;
-		else {
-			dev_dbg(&adapter->dev, "w83781d chip vendor is "
-				"neither Winbond nor Asus\n");
-			goto err_nodev;
-		}
+	val1 = i2c_smbus_read_byte_data(client, W83781D_REG_WCHIPID);
+	if ((val1 == 0x10 || val1 == 0x11) && vendid == winbond)
+		client_name = "w83781d";
+	else if (val1 == 0x30 && vendid == winbond)
+		client_name = "w83782d";
+	else if (val1 == 0x40 && vendid == winbond && address == 0x2d)
+		client_name = "w83783s";
+	else if (val1 == 0x31)
+		client_name = "as99127f";
+	else
+		goto err_nodev;
 
-		val1 = i2c_smbus_read_byte_data(client, W83781D_REG_WCHIPID);
-		if ((val1 == 0x10 || val1 == 0x11) && vendid == winbond)
-			kind = w83781d;
-		else if (val1 == 0x30 && vendid == winbond)
-			kind = w83782d;
-		else if (val1 == 0x40 && vendid == winbond && address == 0x2d)
-			kind = w83783s;
-		else if (val1 == 0x31)
-			kind = as99127f;
-		else {
-			if (kind == 0)
-				dev_warn(&adapter->dev, "Ignoring 'force' "
-					 "parameter for unknown chip at "
-					 "address 0x%02x\n", address);
-			goto err_nodev;
-		}
-
-		if ((kind == w83781d || kind == w83782d)
-		 && w83781d_alias_detect(client, val1)) {
-			dev_dbg(&adapter->dev, "Device at 0x%02x appears to "
-				"be the same as ISA device\n", address);
-			goto err_nodev;
-		}
+	if (val1 <= 0x30 && w83781d_alias_detect(client, val1)) {
+		dev_dbg(&adapter->dev, "Device at 0x%02x appears to "
+			"be the same as ISA device\n", address);
+		goto err_nodev;
 	}
 
 	if (isa)
 		mutex_unlock(&isa->update_lock);
 
-	if (kind == w83781d) {
-		client_name = "w83781d";
-	} else if (kind == w83782d) {
-		client_name = "w83782d";
-	} else if (kind == w83783s) {
-		client_name = "w83783s";
-	} else if (kind == as99127f) {
-		client_name = "as99127f";
-	}
-
 	strlcpy(info->type, client_name, I2C_NAME_SIZE);
 
 	return 0;
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c
index 97851c5..0410bf1 100644
--- a/drivers/hwmon/w83791d.c
+++ b/drivers/hwmon/w83791d.c
@@ -1270,56 +1270,32 @@
 		return -ENODEV;
 	}
 
-	/* The w83791d may be stuck in some other bank than bank 0. This may
-	   make reading other information impossible. Specify a force=...
-	   parameter, and the Winbond will be reset to the right bank. */
-	if (kind < 0) {
-		if (w83791d_read(client, W83791D_REG_CONFIG) & 0x80) {
-			return -ENODEV;
-		}
-		val1 = w83791d_read(client, W83791D_REG_BANK);
-		val2 = w83791d_read(client, W83791D_REG_CHIPMAN);
-		/* Check for Winbond ID if in bank 0 */
-		if (!(val1 & 0x07)) {
-			/* yes it is Bank0 */
-			if (((!(val1 & 0x80)) && (val2 != 0xa3)) ||
-			    ((val1 & 0x80) && (val2 != 0x5c))) {
-				return -ENODEV;
-			}
-		}
-		/* If Winbond chip, address of chip and W83791D_REG_I2C_ADDR
-		   should match */
-		if (w83791d_read(client, W83791D_REG_I2C_ADDR) != address) {
+	if (w83791d_read(client, W83791D_REG_CONFIG) & 0x80)
+		return -ENODEV;
+
+	val1 = w83791d_read(client, W83791D_REG_BANK);
+	val2 = w83791d_read(client, W83791D_REG_CHIPMAN);
+	/* Check for Winbond ID if in bank 0 */
+	if (!(val1 & 0x07)) {
+		if ((!(val1 & 0x80) && val2 != 0xa3) ||
+		    ( (val1 & 0x80) && val2 != 0x5c)) {
 			return -ENODEV;
 		}
 	}
+	/* If Winbond chip, address of chip and W83791D_REG_I2C_ADDR
+	   should match */
+	if (w83791d_read(client, W83791D_REG_I2C_ADDR) != address)
+		return -ENODEV;
 
-	/* We either have a force parameter or we have reason to
-	   believe it is a Winbond chip. Either way, we want bank 0 and
-	   Vendor ID high byte */
+	/* We want bank 0 and Vendor ID high byte */
 	val1 = w83791d_read(client, W83791D_REG_BANK) & 0x78;
 	w83791d_write(client, W83791D_REG_BANK, val1 | 0x80);
 
 	/* Verify it is a Winbond w83791d */
-	if (kind <= 0) {
-		/* get vendor ID */
-		val2 = w83791d_read(client, W83791D_REG_CHIPMAN);
-		if (val2 != 0x5c) {	/* the vendor is NOT Winbond */
-			return -ENODEV;
-		}
-		val1 = w83791d_read(client, W83791D_REG_WCHIPID);
-		if (val1 == 0x71) {
-			kind = w83791d;
-		} else {
-			if (kind == 0)
-				dev_warn(&adapter->dev,
-					"w83791d: Ignoring 'force' parameter "
-					"for unknown chip at adapter %d, "
-					"address 0x%02x\n",
-					i2c_adapter_id(adapter), address);
-			return -ENODEV;
-		}
-	}
+	val1 = w83791d_read(client, W83791D_REG_WCHIPID);
+	val2 = w83791d_read(client, W83791D_REG_CHIPMAN);
+	if (val1 != 0x71 || val2 != 0x5c)
+		return -ENODEV;
 
 	strlcpy(info->type, "w83791d", I2C_NAME_SIZE);
 
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c
index 2be1619..3897885 100644
--- a/drivers/hwmon/w83792d.c
+++ b/drivers/hwmon/w83792d.c
@@ -1273,58 +1273,33 @@
 		return -ENODEV;
 	}
 
-	/* The w83792d may be stuck in some other bank than bank 0. This may
-	   make reading other information impossible. Specify a force=... or
-	   force_*=... parameter, and the Winbond will be reset to the right
-	   bank. */
-	if (kind < 0) {
-		if (w83792d_read_value(client, W83792D_REG_CONFIG) & 0x80) {
-			return -ENODEV;
-		}
-		val1 = w83792d_read_value(client, W83792D_REG_BANK);
-		val2 = w83792d_read_value(client, W83792D_REG_CHIPMAN);
-		/* Check for Winbond ID if in bank 0 */
-		if (!(val1 & 0x07)) {  /* is Bank0 */
-			if (((!(val1 & 0x80)) && (val2 != 0xa3)) ||
-			     ((val1 & 0x80) && (val2 != 0x5c))) {
-				return -ENODEV;
-			}
-		}
-		/* If Winbond chip, address of chip and W83792D_REG_I2C_ADDR
-		   should match */
-		if (w83792d_read_value(client,
-					W83792D_REG_I2C_ADDR) != address) {
-			return -ENODEV;
-		}
-	}
+	if (w83792d_read_value(client, W83792D_REG_CONFIG) & 0x80)
+		return -ENODEV;
 
-	/* We have either had a force parameter, or we have already detected the
-	   Winbond. Put it now into bank 0 and Vendor ID High Byte */
+	val1 = w83792d_read_value(client, W83792D_REG_BANK);
+	val2 = w83792d_read_value(client, W83792D_REG_CHIPMAN);
+	/* Check for Winbond ID if in bank 0 */
+	if (!(val1 & 0x07)) {  /* is Bank0 */
+		if ((!(val1 & 0x80) && val2 != 0xa3) ||
+		    ( (val1 & 0x80) && val2 != 0x5c))
+			return -ENODEV;
+	}
+	/* If Winbond chip, address of chip and W83792D_REG_I2C_ADDR
+	   should match */
+	if (w83792d_read_value(client, W83792D_REG_I2C_ADDR) != address)
+		return -ENODEV;
+
+	/*  Put it now into bank 0 and Vendor ID High Byte */
 	w83792d_write_value(client,
 			    W83792D_REG_BANK,
 			    (w83792d_read_value(client,
 				W83792D_REG_BANK) & 0x78) | 0x80);
 
 	/* Determine the chip type. */
-	if (kind <= 0) {
-		/* get vendor ID */
-		val2 = w83792d_read_value(client, W83792D_REG_CHIPMAN);
-		if (val2 != 0x5c) {  /* the vendor is NOT Winbond */
-			return -ENODEV;
-		}
-		val1 = w83792d_read_value(client, W83792D_REG_WCHIPID);
-		if (val1 == 0x7a) {
-			kind = w83792d;
-		} else {
-			if (kind == 0)
-				dev_warn(&adapter->dev,
-					"w83792d: Ignoring 'force' parameter for"
-					" unknown chip at adapter %d, address"
-					" 0x%02x\n", i2c_adapter_id(adapter),
-					address);
-			return -ENODEV;
-		}
-	}
+	val1 = w83792d_read_value(client, W83792D_REG_WCHIPID);
+	val2 = w83792d_read_value(client, W83792D_REG_CHIPMAN);
+	if (val1 != 0x7a || val2 != 0x5c)
+		return -ENODEV;
 
 	strlcpy(info->type, "w83792d", I2C_NAME_SIZE);
 
diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c
index 47dd398..80a2191 100644
--- a/drivers/hwmon/w83793.c
+++ b/drivers/hwmon/w83793.c
@@ -1164,7 +1164,7 @@
 static int w83793_detect(struct i2c_client *client, int kind,
 			 struct i2c_board_info *info)
 {
-	u8 tmp, bank;
+	u8 tmp, bank, chip_id;
 	struct i2c_adapter *adapter = client->adapter;
 	unsigned short address = client->addr;
 
@@ -1174,44 +1174,27 @@
 
 	bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL);
 
-	if (kind < 0) {
-		tmp = bank & 0x80 ? 0x5c : 0xa3;
-		/* Check Winbond vendor ID */
-		if (tmp != i2c_smbus_read_byte_data(client,
-							W83793_REG_VENDORID)) {
-			pr_debug("w83793: Detection failed at check "
-				 "vendor id\n");
-			return -ENODEV;
-		}
-
-		/* If Winbond chip, address of chip and W83793_REG_I2C_ADDR
-		   should match */
-		if ((bank & 0x07) == 0
-		 && i2c_smbus_read_byte_data(client, W83793_REG_I2C_ADDR) !=
-		    (address << 1)) {
-			pr_debug("w83793: Detection failed at check "
-				 "i2c addr\n");
-			return -ENODEV;
-		}
-
+	tmp = bank & 0x80 ? 0x5c : 0xa3;
+	/* Check Winbond vendor ID */
+	if (tmp != i2c_smbus_read_byte_data(client, W83793_REG_VENDORID)) {
+		pr_debug("w83793: Detection failed at check vendor id\n");
+		return -ENODEV;
 	}
 
-	/* We have either had a force parameter, or we have already detected the
-	   Winbond. Determine the chip type now */
-
-	if (kind <= 0) {
-		if (0x7b == i2c_smbus_read_byte_data(client,
-						     W83793_REG_CHIPID)) {
-			kind = w83793;
-		} else {
-			if (kind == 0)
-				dev_warn(&adapter->dev, "w83793: Ignoring "
-					 "'force' parameter for unknown chip "
-					 "at address 0x%02x\n", address);
-			return -ENODEV;
-		}
+	/* If Winbond chip, address of chip and W83793_REG_I2C_ADDR
+	   should match */
+	if ((bank & 0x07) == 0
+	 && i2c_smbus_read_byte_data(client, W83793_REG_I2C_ADDR) !=
+	    (address << 1)) {
+		pr_debug("w83793: Detection failed at check i2c addr\n");
+		return -ENODEV;
 	}
 
+	/* Determine the chip type now */
+	chip_id = i2c_smbus_read_byte_data(client, W83793_REG_CHIPID);
+	if (chip_id != 0x7b)
+		return -ENODEV;
+
 	strlcpy(info->type, "w83793", I2C_NAME_SIZE);
 
 	return 0;
diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c
index ea295b9..9b6c4c1 100644
--- a/drivers/hwmon/w83l785ts.c
+++ b/drivers/hwmon/w83l785ts.c
@@ -1,7 +1,7 @@
 /*
  * w83l785ts.c - Part of lm_sensors, Linux kernel modules for hardware
  *               monitoring
- * Copyright (C) 2003-2004  Jean Delvare <khali@linux-fr.org>
+ * Copyright (C) 2003-2009  Jean Delvare <khali@linux-fr.org>
  *
  * Inspired from the lm83 driver. The W83L785TS-S is a sensor chip made
  * by Winbond. It reports a single external temperature with a 1 deg
@@ -146,60 +146,36 @@
  */
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int w83l785ts_detect(struct i2c_client *new_client, int kind,
+static int w83l785ts_detect(struct i2c_client *client, int kind,
 			    struct i2c_board_info *info)
 {
-	struct i2c_adapter *adapter = new_client->adapter;
+	struct i2c_adapter *adapter = client->adapter;
+	u16 man_id;
+	u8 chip_id;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	/*
-	 * Now we do the remaining detection. A negative kind means that
-	 * the driver was loaded with no force parameter (default), so we
-	 * must both detect and identify the chip (actually there is only
-	 * one possible kind of chip for now, W83L785TS-S). A zero kind means
-	 * that the driver was loaded with the force parameter, the detection
-	 * step shall be skipped. A positive kind means that the driver
-	 * was loaded with the force parameter and a given kind of chip is
-	 * requested, so both the detection and the identification steps
-	 * are skipped.
-	 */
-	if (kind < 0) { /* detection */
-		if (((w83l785ts_read_value(new_client,
-		      W83L785TS_REG_CONFIG, 0) & 0x80) != 0x00)
-		 || ((w83l785ts_read_value(new_client,
-		      W83L785TS_REG_TYPE, 0) & 0xFC) != 0x00)) {
-			dev_dbg(&adapter->dev,
-				"W83L785TS-S detection failed at 0x%02x.\n",
-				new_client->addr);
-			return -ENODEV;
-		}
+	/* detection */
+	if ((w83l785ts_read_value(client, W83L785TS_REG_CONFIG, 0) & 0x80)
+	 || (w83l785ts_read_value(client, W83L785TS_REG_TYPE, 0) & 0xFC)) {
+		dev_dbg(&adapter->dev,
+			"W83L785TS-S detection failed at 0x%02x\n",
+			client->addr);
+		return -ENODEV;
 	}
 
-	if (kind <= 0) { /* identification */
-		u16 man_id;
-		u8 chip_id;
+	/* Identification */
+	man_id = (w83l785ts_read_value(client, W83L785TS_REG_MAN_ID1, 0) << 8)
+	       + w83l785ts_read_value(client, W83L785TS_REG_MAN_ID2, 0);
+	chip_id = w83l785ts_read_value(client, W83L785TS_REG_CHIP_ID, 0);
 
-		man_id = (w83l785ts_read_value(new_client,
-			 W83L785TS_REG_MAN_ID1, 0) << 8) +
-			 w83l785ts_read_value(new_client,
-			 W83L785TS_REG_MAN_ID2, 0);
-		chip_id = w83l785ts_read_value(new_client,
-			  W83L785TS_REG_CHIP_ID, 0);
-
-		if (man_id == 0x5CA3) { /* Winbond */
-			if (chip_id == 0x70) { /* W83L785TS-S */
-				kind = w83l785ts;			
-			}
-		}
-	
-		if (kind <= 0) { /* identification failed */
-			dev_info(&adapter->dev,
-				 "Unsupported chip (man_id=0x%04X, "
-				 "chip_id=0x%02X).\n", man_id, chip_id);
-			return -ENODEV;
-		}
+	if (man_id != 0x5CA3		/* Winbond */
+	 || chip_id != 0x70) {		/* W83L785TS-S */
+		dev_dbg(&adapter->dev,
+			"Unsupported chip (man_id=0x%04X, chip_id=0x%02X)\n",
+			man_id, chip_id);
+		return -ENODEV;
 	}
 
 	strlcpy(info->type, "w83l785ts", I2C_NAME_SIZE);
diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c
index badca76..27da7d2 100644
--- a/drivers/hwmon/w83l786ng.c
+++ b/drivers/hwmon/w83l786ng.c
@@ -590,53 +590,31 @@
 		 struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
+	u16 man_id;
+	u8 chip_id;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
 		return -ENODEV;
 	}
 
-	/*
-	 * Now we do the remaining detection. A negative kind means that
-	 * the driver was loaded with no force parameter (default), so we
-	 * must both detect and identify the chip (actually there is only
-	 * one possible kind of chip for now, W83L786NG). A zero kind means
-	 * that the driver was loaded with the force parameter, the detection
-	 * step shall be skipped. A positive kind means that the driver
-	 * was loaded with the force parameter and a given kind of chip is
-	 * requested, so both the detection and the identification steps
-	 * are skipped.
-	 */
-	if (kind < 0) { /* detection */
-		if (((w83l786ng_read_value(client,
-		    W83L786NG_REG_CONFIG) & 0x80) != 0x00)) {
-			dev_dbg(&adapter->dev,
-				"W83L786NG detection failed at 0x%02x.\n",
-				client->addr);
-			return -ENODEV;
-		}
+	/* Detection */
+	if ((w83l786ng_read_value(client, W83L786NG_REG_CONFIG) & 0x80)) {
+		dev_dbg(&adapter->dev, "W83L786NG detection failed at 0x%02x\n",
+			client->addr);
+		return -ENODEV;
 	}
 
-	if (kind <= 0) { /* identification */
-		u16 man_id;
-		u8 chip_id;
+	/* Identification */
+	man_id = (w83l786ng_read_value(client, W83L786NG_REG_MAN_ID1) << 8) +
+		 w83l786ng_read_value(client, W83L786NG_REG_MAN_ID2);
+	chip_id = w83l786ng_read_value(client, W83L786NG_REG_CHIP_ID);
 
-		man_id = (w83l786ng_read_value(client,
-		    W83L786NG_REG_MAN_ID1) << 8) +
-		    w83l786ng_read_value(client, W83L786NG_REG_MAN_ID2);
-		chip_id = w83l786ng_read_value(client, W83L786NG_REG_CHIP_ID);
-
-		if (man_id == 0x5CA3) { /* Winbond */
-			if (chip_id == 0x80) { /* W83L786NG */
-				kind = w83l786ng;
-			}
-		}
-
-		if (kind <= 0) { /* identification failed */
-			dev_info(&adapter->dev,
-			    "Unsupported chip (man_id=0x%04X, "
-			    "chip_id=0x%02X).\n", man_id, chip_id);
-			return -ENODEV;
-		}
+	if (man_id != 0x5CA3 ||		/* Winbond */
+	    chip_id != 0x80) {		/* W83L786NG */
+		dev_dbg(&adapter->dev,
+			"Unsupported chip (man_id=0x%04X, chip_id=0x%02X)\n",
+			man_id, chip_id);
+		return -ENODEV;
 	}
 
 	strlcpy(info->type, "w83l786ng", I2C_NAME_SIZE);
diff --git a/drivers/i2c/busses/i2c-designware.c b/drivers/i2c/busses/i2c-designware.c
index b444762..9e18ef9 100644
--- a/drivers/i2c/busses/i2c-designware.c
+++ b/drivers/i2c/busses/i2c-designware.c
@@ -1,5 +1,5 @@
 /*
- * Synopsys Designware I2C adapter driver (master only).
+ * Synopsys DesignWare I2C adapter driver (master only).
  *
  * Based on the TI DAVINCI I2C adapter driver.
  *
@@ -49,7 +49,20 @@
 #define DW_IC_FS_SCL_LCNT	0x20
 #define DW_IC_INTR_STAT		0x2c
 #define DW_IC_INTR_MASK		0x30
+#define DW_IC_RAW_INTR_STAT	0x34
+#define DW_IC_RX_TL		0x38
+#define DW_IC_TX_TL		0x3c
 #define DW_IC_CLR_INTR		0x40
+#define DW_IC_CLR_RX_UNDER	0x44
+#define DW_IC_CLR_RX_OVER	0x48
+#define DW_IC_CLR_TX_OVER	0x4c
+#define DW_IC_CLR_RD_REQ	0x50
+#define DW_IC_CLR_TX_ABRT	0x54
+#define DW_IC_CLR_RX_DONE	0x58
+#define DW_IC_CLR_ACTIVITY	0x5c
+#define DW_IC_CLR_STOP_DET	0x60
+#define DW_IC_CLR_START_DET	0x64
+#define DW_IC_CLR_GEN_CALL	0x68
 #define DW_IC_ENABLE		0x6c
 #define DW_IC_STATUS		0x70
 #define DW_IC_TXFLR		0x74
@@ -64,9 +77,23 @@
 #define DW_IC_CON_RESTART_EN		0x20
 #define DW_IC_CON_SLAVE_DISABLE		0x40
 
-#define DW_IC_INTR_TX_EMPTY	0x10
-#define DW_IC_INTR_TX_ABRT	0x40
+#define DW_IC_INTR_RX_UNDER	0x001
+#define DW_IC_INTR_RX_OVER	0x002
+#define DW_IC_INTR_RX_FULL	0x004
+#define DW_IC_INTR_TX_OVER	0x008
+#define DW_IC_INTR_TX_EMPTY	0x010
+#define DW_IC_INTR_RD_REQ	0x020
+#define DW_IC_INTR_TX_ABRT	0x040
+#define DW_IC_INTR_RX_DONE	0x080
+#define DW_IC_INTR_ACTIVITY	0x100
 #define DW_IC_INTR_STOP_DET	0x200
+#define DW_IC_INTR_START_DET	0x400
+#define DW_IC_INTR_GEN_CALL	0x800
+
+#define DW_IC_INTR_DEFAULT_MASK		(DW_IC_INTR_RX_FULL | \
+					 DW_IC_INTR_TX_EMPTY | \
+					 DW_IC_INTR_TX_ABRT | \
+					 DW_IC_INTR_STOP_DET)
 
 #define DW_IC_STATUS_ACTIVITY	0x1
 
@@ -96,31 +123,49 @@
 #define ABRT_SBYTE_ACKDET	7
 #define ABRT_SBYTE_NORSTRT	9
 #define ABRT_10B_RD_NORSTRT	10
-#define ARB_MASTER_DIS		11
+#define ABRT_MASTER_DIS		11
 #define ARB_LOST		12
 
+#define DW_IC_TX_ABRT_7B_ADDR_NOACK	(1UL << ABRT_7B_ADDR_NOACK)
+#define DW_IC_TX_ABRT_10ADDR1_NOACK	(1UL << ABRT_10ADDR1_NOACK)
+#define DW_IC_TX_ABRT_10ADDR2_NOACK	(1UL << ABRT_10ADDR2_NOACK)
+#define DW_IC_TX_ABRT_TXDATA_NOACK	(1UL << ABRT_TXDATA_NOACK)
+#define DW_IC_TX_ABRT_GCALL_NOACK	(1UL << ABRT_GCALL_NOACK)
+#define DW_IC_TX_ABRT_GCALL_READ	(1UL << ABRT_GCALL_READ)
+#define DW_IC_TX_ABRT_SBYTE_ACKDET	(1UL << ABRT_SBYTE_ACKDET)
+#define DW_IC_TX_ABRT_SBYTE_NORSTRT	(1UL << ABRT_SBYTE_NORSTRT)
+#define DW_IC_TX_ABRT_10B_RD_NORSTRT	(1UL << ABRT_10B_RD_NORSTRT)
+#define DW_IC_TX_ABRT_MASTER_DIS	(1UL << ABRT_MASTER_DIS)
+#define DW_IC_TX_ARB_LOST		(1UL << ARB_LOST)
+
+#define DW_IC_TX_ABRT_NOACK		(DW_IC_TX_ABRT_7B_ADDR_NOACK | \
+					 DW_IC_TX_ABRT_10ADDR1_NOACK | \
+					 DW_IC_TX_ABRT_10ADDR2_NOACK | \
+					 DW_IC_TX_ABRT_TXDATA_NOACK | \
+					 DW_IC_TX_ABRT_GCALL_NOACK)
+
 static char *abort_sources[] = {
-	[ABRT_7B_ADDR_NOACK]	=
+	[ABRT_7B_ADDR_NOACK] =
 		"slave address not acknowledged (7bit mode)",
-	[ABRT_10ADDR1_NOACK]	=
+	[ABRT_10ADDR1_NOACK] =
 		"first address byte not acknowledged (10bit mode)",
-	[ABRT_10ADDR2_NOACK]	=
+	[ABRT_10ADDR2_NOACK] =
 		"second address byte not acknowledged (10bit mode)",
-	[ABRT_TXDATA_NOACK]		=
+	[ABRT_TXDATA_NOACK] =
 		"data not acknowledged",
-	[ABRT_GCALL_NOACK]		=
+	[ABRT_GCALL_NOACK] =
 		"no acknowledgement for a general call",
-	[ABRT_GCALL_READ]		=
+	[ABRT_GCALL_READ] =
 		"read after general call",
-	[ABRT_SBYTE_ACKDET]		=
+	[ABRT_SBYTE_ACKDET] =
 		"start byte acknowledged",
-	[ABRT_SBYTE_NORSTRT]	=
+	[ABRT_SBYTE_NORSTRT] =
 		"trying to send start byte when restart is disabled",
-	[ABRT_10B_RD_NORSTRT]	=
+	[ABRT_10B_RD_NORSTRT] =
 		"trying to read when restart is disabled (10bit mode)",
-	[ARB_MASTER_DIS]		=
+	[ABRT_MASTER_DIS] =
 		"trying to use disabled adapter",
-	[ARB_LOST]			=
+	[ARB_LOST] =
 		"lost arbitration",
 };
 
@@ -129,7 +174,6 @@
  * @dev: driver model device node
  * @base: IO registers pointer
  * @cmd_complete: tx completion indicator
- * @pump_msg: continue in progress transfers
  * @lock: protect this struct and IO registers
  * @clk: input reference clock
  * @cmd_err: run time hadware error code
@@ -155,27 +199,81 @@
 	struct device		*dev;
 	void __iomem		*base;
 	struct completion	cmd_complete;
-	struct tasklet_struct	pump_msg;
 	struct mutex		lock;
 	struct clk		*clk;
 	int			cmd_err;
 	struct i2c_msg		*msgs;
 	int			msgs_num;
 	int			msg_write_idx;
-	u16			tx_buf_len;
+	u32			tx_buf_len;
 	u8			*tx_buf;
 	int			msg_read_idx;
-	u16			rx_buf_len;
+	u32			rx_buf_len;
 	u8			*rx_buf;
 	int			msg_err;
 	unsigned int		status;
-	u16			abort_source;
+	u32			abort_source;
 	int			irq;
 	struct i2c_adapter	adapter;
 	unsigned int		tx_fifo_depth;
 	unsigned int		rx_fifo_depth;
 };
 
+static u32
+i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset)
+{
+	/*
+	 * DesignWare I2C core doesn't seem to have solid strategy to meet
+	 * the tHD;STA timing spec.  Configuring _HCNT based on tHIGH spec
+	 * will result in violation of the tHD;STA spec.
+	 */
+	if (cond)
+		/*
+		 * Conditional expression:
+		 *
+		 *   IC_[FS]S_SCL_HCNT + (1+4+3) >= IC_CLK * tHIGH
+		 *
+		 * This is based on the DW manuals, and represents an ideal
+		 * configuration.  The resulting I2C bus speed will be
+		 * faster than any of the others.
+		 *
+		 * If your hardware is free from tHD;STA issue, try this one.
+		 */
+		return (ic_clk * tSYMBOL + 5000) / 10000 - 8 + offset;
+	else
+		/*
+		 * Conditional expression:
+		 *
+		 *   IC_[FS]S_SCL_HCNT + 3 >= IC_CLK * (tHD;STA + tf)
+		 *
+		 * This is just experimental rule; the tHD;STA period turned
+		 * out to be proportinal to (_HCNT + 3).  With this setting,
+		 * we could meet both tHIGH and tHD;STA timing specs.
+		 *
+		 * If unsure, you'd better to take this alternative.
+		 *
+		 * The reason why we need to take into account "tf" here,
+		 * is the same as described in i2c_dw_scl_lcnt().
+		 */
+		return (ic_clk * (tSYMBOL + tf) + 5000) / 10000 - 3 + offset;
+}
+
+static u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset)
+{
+	/*
+	 * Conditional expression:
+	 *
+	 *   IC_[FS]S_SCL_LCNT + 1 >= IC_CLK * (tLOW + tf)
+	 *
+	 * DW I2C core starts counting the SCL CNTs for the LOW period
+	 * of the SCL clock (tLOW) as soon as it pulls the SCL line.
+	 * In order to meet the tLOW timing spec, we need to take into
+	 * account the fall time of SCL signal (tf).  Default tf value
+	 * should be 0.3 us, for safety.
+	 */
+	return ((ic_clk * (tLOW + tf) + 5000) / 10000) - 1 + offset;
+}
+
 /**
  * i2c_dw_init() - initialize the designware i2c master hardware
  * @dev: device private data
@@ -187,25 +285,49 @@
 static void i2c_dw_init(struct dw_i2c_dev *dev)
 {
 	u32 input_clock_khz = clk_get_rate(dev->clk) / 1000;
-	u16 ic_con;
+	u32 ic_con, hcnt, lcnt;
 
 	/* Disable the adapter */
-	writeb(0, dev->base + DW_IC_ENABLE);
+	writel(0, dev->base + DW_IC_ENABLE);
 
 	/* set standard and fast speed deviders for high/low periods */
-	writew((input_clock_khz * 40 / 10000)+1, /* std speed high, 4us */
-			dev->base + DW_IC_SS_SCL_HCNT);
-	writew((input_clock_khz * 47 / 10000)+1, /* std speed low, 4.7us */
-			dev->base + DW_IC_SS_SCL_LCNT);
-	writew((input_clock_khz *  6 / 10000)+1, /* fast speed high, 0.6us */
-			dev->base + DW_IC_FS_SCL_HCNT);
-	writew((input_clock_khz * 13 / 10000)+1, /* fast speed low, 1.3us */
-			dev->base + DW_IC_FS_SCL_LCNT);
+
+	/* Standard-mode */
+	hcnt = i2c_dw_scl_hcnt(input_clock_khz,
+				40,	/* tHD;STA = tHIGH = 4.0 us */
+				3,	/* tf = 0.3 us */
+				0,	/* 0: DW default, 1: Ideal */
+				0);	/* No offset */
+	lcnt = i2c_dw_scl_lcnt(input_clock_khz,
+				47,	/* tLOW = 4.7 us */
+				3,	/* tf = 0.3 us */
+				0);	/* No offset */
+	writel(hcnt, dev->base + DW_IC_SS_SCL_HCNT);
+	writel(lcnt, dev->base + DW_IC_SS_SCL_LCNT);
+	dev_dbg(dev->dev, "Standard-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt);
+
+	/* Fast-mode */
+	hcnt = i2c_dw_scl_hcnt(input_clock_khz,
+				6,	/* tHD;STA = tHIGH = 0.6 us */
+				3,	/* tf = 0.3 us */
+				0,	/* 0: DW default, 1: Ideal */
+				0);	/* No offset */
+	lcnt = i2c_dw_scl_lcnt(input_clock_khz,
+				13,	/* tLOW = 1.3 us */
+				3,	/* tf = 0.3 us */
+				0);	/* No offset */
+	writel(hcnt, dev->base + DW_IC_FS_SCL_HCNT);
+	writel(lcnt, dev->base + DW_IC_FS_SCL_LCNT);
+	dev_dbg(dev->dev, "Fast-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt);
+
+	/* Configure Tx/Rx FIFO threshold levels */
+	writel(dev->tx_fifo_depth - 1, dev->base + DW_IC_TX_TL);
+	writel(0, dev->base + DW_IC_RX_TL);
 
 	/* configure the i2c master */
 	ic_con = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
 		DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST;
-	writew(ic_con, dev->base + DW_IC_CON);
+	writel(ic_con, dev->base + DW_IC_CON);
 }
 
 /*
@@ -215,7 +337,7 @@
 {
 	int timeout = TIMEOUT;
 
-	while (readb(dev->base + DW_IC_STATUS) & DW_IC_STATUS_ACTIVITY) {
+	while (readl(dev->base + DW_IC_STATUS) & DW_IC_STATUS_ACTIVITY) {
 		if (timeout <= 0) {
 			dev_warn(dev->dev, "timeout waiting for bus ready\n");
 			return -ETIMEDOUT;
@@ -227,106 +349,125 @@
 	return 0;
 }
 
+static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
+{
+	struct i2c_msg *msgs = dev->msgs;
+	u32 ic_con;
+
+	/* Disable the adapter */
+	writel(0, dev->base + DW_IC_ENABLE);
+
+	/* set the slave (target) address */
+	writel(msgs[dev->msg_write_idx].addr, dev->base + DW_IC_TAR);
+
+	/* if the slave address is ten bit address, enable 10BITADDR */
+	ic_con = readl(dev->base + DW_IC_CON);
+	if (msgs[dev->msg_write_idx].flags & I2C_M_TEN)
+		ic_con |= DW_IC_CON_10BITADDR_MASTER;
+	else
+		ic_con &= ~DW_IC_CON_10BITADDR_MASTER;
+	writel(ic_con, dev->base + DW_IC_CON);
+
+	/* Enable the adapter */
+	writel(1, dev->base + DW_IC_ENABLE);
+
+	/* Enable interrupts */
+	writel(DW_IC_INTR_DEFAULT_MASK, dev->base + DW_IC_INTR_MASK);
+}
+
 /*
- * Initiate low level master read/write transaction.
- * This function is called from i2c_dw_xfer when starting a transfer.
- * This function is also called from dw_i2c_pump_msg to continue a transfer
- * that is longer than the size of the TX FIFO.
+ * Initiate (and continue) low level master read/write transaction.
+ * This function is only called from i2c_dw_isr, and pumping i2c_msg
+ * messages into the tx buffer.  Even if the size of i2c_msg data is
+ * longer than the size of the tx buffer, it handles everything.
  */
 static void
-i2c_dw_xfer_msg(struct i2c_adapter *adap)
+i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
 {
-	struct dw_i2c_dev *dev = i2c_get_adapdata(adap);
 	struct i2c_msg *msgs = dev->msgs;
-	int num = dev->msgs_num;
-	u16 ic_con, intr_mask;
-	int tx_limit = dev->tx_fifo_depth - readb(dev->base + DW_IC_TXFLR);
-	int rx_limit = dev->rx_fifo_depth - readb(dev->base + DW_IC_RXFLR);
-	u16 addr = msgs[dev->msg_write_idx].addr;
-	u16 buf_len = dev->tx_buf_len;
+	u32 intr_mask;
+	int tx_limit, rx_limit;
+	u32 addr = msgs[dev->msg_write_idx].addr;
+	u32 buf_len = dev->tx_buf_len;
+	u8 *buf = dev->tx_buf;;
 
-	if (!(dev->status & STATUS_WRITE_IN_PROGRESS)) {
-		/* Disable the adapter */
-		writeb(0, dev->base + DW_IC_ENABLE);
+	intr_mask = DW_IC_INTR_DEFAULT_MASK;
 
-		/* set the slave (target) address */
-		writew(msgs[dev->msg_write_idx].addr, dev->base + DW_IC_TAR);
-
-		/* if the slave address is ten bit address, enable 10BITADDR */
-		ic_con = readw(dev->base + DW_IC_CON);
-		if (msgs[dev->msg_write_idx].flags & I2C_M_TEN)
-			ic_con |= DW_IC_CON_10BITADDR_MASTER;
-		else
-			ic_con &= ~DW_IC_CON_10BITADDR_MASTER;
-		writew(ic_con, dev->base + DW_IC_CON);
-
-		/* Enable the adapter */
-		writeb(1, dev->base + DW_IC_ENABLE);
-	}
-
-	for (; dev->msg_write_idx < num; dev->msg_write_idx++) {
-		/* if target address has changed, we need to
+	for (; dev->msg_write_idx < dev->msgs_num; dev->msg_write_idx++) {
+		/*
+		 * if target address has changed, we need to
 		 * reprogram the target address in the i2c
 		 * adapter when we are done with this transfer
 		 */
-		if (msgs[dev->msg_write_idx].addr != addr)
-			return;
+		if (msgs[dev->msg_write_idx].addr != addr) {
+			dev_err(dev->dev,
+				"%s: invalid target address\n", __func__);
+			dev->msg_err = -EINVAL;
+			break;
+		}
 
 		if (msgs[dev->msg_write_idx].len == 0) {
 			dev_err(dev->dev,
 				"%s: invalid message length\n", __func__);
 			dev->msg_err = -EINVAL;
-			return;
+			break;
 		}
 
 		if (!(dev->status & STATUS_WRITE_IN_PROGRESS)) {
 			/* new i2c_msg */
-			dev->tx_buf = msgs[dev->msg_write_idx].buf;
+			buf = msgs[dev->msg_write_idx].buf;
 			buf_len = msgs[dev->msg_write_idx].len;
 		}
 
+		tx_limit = dev->tx_fifo_depth - readl(dev->base + DW_IC_TXFLR);
+		rx_limit = dev->rx_fifo_depth - readl(dev->base + DW_IC_RXFLR);
+
 		while (buf_len > 0 && tx_limit > 0 && rx_limit > 0) {
 			if (msgs[dev->msg_write_idx].flags & I2C_M_RD) {
-				writew(0x100, dev->base + DW_IC_DATA_CMD);
+				writel(0x100, dev->base + DW_IC_DATA_CMD);
 				rx_limit--;
 			} else
-				writew(*(dev->tx_buf++),
-						dev->base + DW_IC_DATA_CMD);
+				writel(*buf++, dev->base + DW_IC_DATA_CMD);
 			tx_limit--; buf_len--;
 		}
+
+		dev->tx_buf = buf;
+		dev->tx_buf_len = buf_len;
+
+		if (buf_len > 0) {
+			/* more bytes to be written */
+			dev->status |= STATUS_WRITE_IN_PROGRESS;
+			break;
+		} else
+			dev->status &= ~STATUS_WRITE_IN_PROGRESS;
 	}
 
-	intr_mask = DW_IC_INTR_STOP_DET | DW_IC_INTR_TX_ABRT;
-	if (buf_len > 0) { /* more bytes to be written */
-		intr_mask |= DW_IC_INTR_TX_EMPTY;
-		dev->status |= STATUS_WRITE_IN_PROGRESS;
-	} else
-		dev->status &= ~STATUS_WRITE_IN_PROGRESS;
-	writew(intr_mask, dev->base + DW_IC_INTR_MASK);
+	/*
+	 * If i2c_msg index search is completed, we don't need TX_EMPTY
+	 * interrupt any more.
+	 */
+	if (dev->msg_write_idx == dev->msgs_num)
+		intr_mask &= ~DW_IC_INTR_TX_EMPTY;
 
-	dev->tx_buf_len = buf_len;
+	if (dev->msg_err)
+		intr_mask = 0;
+
+	writel(intr_mask, dev->base + DW_IC_INTR_MASK);
 }
 
 static void
-i2c_dw_read(struct i2c_adapter *adap)
+i2c_dw_read(struct dw_i2c_dev *dev)
 {
-	struct dw_i2c_dev *dev = i2c_get_adapdata(adap);
 	struct i2c_msg *msgs = dev->msgs;
-	int num = dev->msgs_num;
-	u16 addr = msgs[dev->msg_read_idx].addr;
-	int rx_valid = readw(dev->base + DW_IC_RXFLR);
+	int rx_valid;
 
-	for (; dev->msg_read_idx < num; dev->msg_read_idx++) {
-		u16 len;
+	for (; dev->msg_read_idx < dev->msgs_num; dev->msg_read_idx++) {
+		u32 len;
 		u8 *buf;
 
 		if (!(msgs[dev->msg_read_idx].flags & I2C_M_RD))
 			continue;
 
-		/* different i2c client, reprogram the i2c adapter */
-		if (msgs[dev->msg_read_idx].addr != addr)
-			return;
-
 		if (!(dev->status & STATUS_READ_IN_PROGRESS)) {
 			len = msgs[dev->msg_read_idx].len;
 			buf = msgs[dev->msg_read_idx].buf;
@@ -335,8 +476,10 @@
 			buf = dev->rx_buf;
 		}
 
+		rx_valid = readl(dev->base + DW_IC_RXFLR);
+
 		for (; len > 0 && rx_valid > 0; len--, rx_valid--)
-			*buf++ = readb(dev->base + DW_IC_DATA_CMD);
+			*buf++ = readl(dev->base + DW_IC_DATA_CMD);
 
 		if (len > 0) {
 			dev->status |= STATUS_READ_IN_PROGRESS;
@@ -348,6 +491,29 @@
 	}
 }
 
+static int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev)
+{
+	unsigned long abort_source = dev->abort_source;
+	int i;
+
+	if (abort_source & DW_IC_TX_ABRT_NOACK) {
+		for_each_bit(i, &abort_source, ARRAY_SIZE(abort_sources))
+			dev_dbg(dev->dev,
+				"%s: %s\n", __func__, abort_sources[i]);
+		return -EREMOTEIO;
+	}
+
+	for_each_bit(i, &abort_source, ARRAY_SIZE(abort_sources))
+		dev_err(dev->dev, "%s: %s\n", __func__, abort_sources[i]);
+
+	if (abort_source & DW_IC_TX_ARB_LOST)
+		return -EAGAIN;
+	else if (abort_source & DW_IC_TX_ABRT_GCALL_READ)
+		return -EINVAL; /* wrong msgs[] data */
+	else
+		return -EIO;
+}
+
 /*
  * Prepare controller for a transaction and call i2c_dw_xfer_msg
  */
@@ -369,13 +535,14 @@
 	dev->msg_read_idx = 0;
 	dev->msg_err = 0;
 	dev->status = STATUS_IDLE;
+	dev->abort_source = 0;
 
 	ret = i2c_dw_wait_bus_not_busy(dev);
 	if (ret < 0)
 		goto done;
 
 	/* start the transfers */
-	i2c_dw_xfer_msg(adap);
+	i2c_dw_xfer_init(dev);
 
 	/* wait for tx to complete */
 	ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, HZ);
@@ -394,23 +561,16 @@
 
 	/* no error */
 	if (likely(!dev->cmd_err)) {
-		/* read rx fifo, and disable the adapter */
-		do {
-			i2c_dw_read(adap);
-		} while (dev->status & STATUS_READ_IN_PROGRESS);
-		writeb(0, dev->base + DW_IC_ENABLE);
+		/* Disable the adapter */
+		writel(0, dev->base + DW_IC_ENABLE);
 		ret = num;
 		goto done;
 	}
 
 	/* We have an error */
 	if (dev->cmd_err == DW_IC_ERR_TX_ABRT) {
-		unsigned long abort_source = dev->abort_source;
-		int i;
-
-		for_each_bit(i, &abort_source, ARRAY_SIZE(abort_sources)) {
-		    dev_err(dev->dev, "%s: %s\n", __func__, abort_sources[i]);
-		}
+		ret = i2c_dw_handle_tx_abort(dev);
+		goto done;
 	}
 	ret = -EIO;
 
@@ -422,21 +582,67 @@
 
 static u32 i2c_dw_func(struct i2c_adapter *adap)
 {
-	return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR;
+	return	I2C_FUNC_I2C |
+		I2C_FUNC_10BIT_ADDR |
+		I2C_FUNC_SMBUS_BYTE |
+		I2C_FUNC_SMBUS_BYTE_DATA |
+		I2C_FUNC_SMBUS_WORD_DATA |
+		I2C_FUNC_SMBUS_I2C_BLOCK;
 }
 
-static void dw_i2c_pump_msg(unsigned long data)
+static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev)
 {
-	struct dw_i2c_dev *dev = (struct dw_i2c_dev *) data;
-	u16 intr_mask;
+	u32 stat;
 
-	i2c_dw_read(&dev->adapter);
-	i2c_dw_xfer_msg(&dev->adapter);
+	/*
+	 * The IC_INTR_STAT register just indicates "enabled" interrupts.
+	 * Ths unmasked raw version of interrupt status bits are available
+	 * in the IC_RAW_INTR_STAT register.
+	 *
+	 * That is,
+	 *   stat = readl(IC_INTR_STAT);
+	 * equals to,
+	 *   stat = readl(IC_RAW_INTR_STAT) & readl(IC_INTR_MASK);
+	 *
+	 * The raw version might be useful for debugging purposes.
+	 */
+	stat = readl(dev->base + DW_IC_INTR_STAT);
 
-	intr_mask = DW_IC_INTR_STOP_DET | DW_IC_INTR_TX_ABRT;
-	if (dev->status & STATUS_WRITE_IN_PROGRESS)
-		intr_mask |= DW_IC_INTR_TX_EMPTY;
-	writew(intr_mask, dev->base + DW_IC_INTR_MASK);
+	/*
+	 * Do not use the IC_CLR_INTR register to clear interrupts, or
+	 * you'll miss some interrupts, triggered during the period from
+	 * readl(IC_INTR_STAT) to readl(IC_CLR_INTR).
+	 *
+	 * Instead, use the separately-prepared IC_CLR_* registers.
+	 */
+	if (stat & DW_IC_INTR_RX_UNDER)
+		readl(dev->base + DW_IC_CLR_RX_UNDER);
+	if (stat & DW_IC_INTR_RX_OVER)
+		readl(dev->base + DW_IC_CLR_RX_OVER);
+	if (stat & DW_IC_INTR_TX_OVER)
+		readl(dev->base + DW_IC_CLR_TX_OVER);
+	if (stat & DW_IC_INTR_RD_REQ)
+		readl(dev->base + DW_IC_CLR_RD_REQ);
+	if (stat & DW_IC_INTR_TX_ABRT) {
+		/*
+		 * The IC_TX_ABRT_SOURCE register is cleared whenever
+		 * the IC_CLR_TX_ABRT is read.  Preserve it beforehand.
+		 */
+		dev->abort_source = readl(dev->base + DW_IC_TX_ABRT_SOURCE);
+		readl(dev->base + DW_IC_CLR_TX_ABRT);
+	}
+	if (stat & DW_IC_INTR_RX_DONE)
+		readl(dev->base + DW_IC_CLR_RX_DONE);
+	if (stat & DW_IC_INTR_ACTIVITY)
+		readl(dev->base + DW_IC_CLR_ACTIVITY);
+	if (stat & DW_IC_INTR_STOP_DET)
+		readl(dev->base + DW_IC_CLR_STOP_DET);
+	if (stat & DW_IC_INTR_START_DET)
+		readl(dev->base + DW_IC_CLR_START_DET);
+	if (stat & DW_IC_INTR_GEN_CALL)
+		readl(dev->base + DW_IC_CLR_GEN_CALL);
+
+	return stat;
 }
 
 /*
@@ -446,20 +652,37 @@
 static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
 {
 	struct dw_i2c_dev *dev = dev_id;
-	u16 stat;
+	u32 stat;
 
-	stat = readw(dev->base + DW_IC_INTR_STAT);
+	stat = i2c_dw_read_clear_intrbits(dev);
 	dev_dbg(dev->dev, "%s: stat=0x%x\n", __func__, stat);
+
 	if (stat & DW_IC_INTR_TX_ABRT) {
-		dev->abort_source = readw(dev->base + DW_IC_TX_ABRT_SOURCE);
 		dev->cmd_err |= DW_IC_ERR_TX_ABRT;
 		dev->status = STATUS_IDLE;
-	} else if (stat & DW_IC_INTR_TX_EMPTY)
-		tasklet_schedule(&dev->pump_msg);
 
-	readb(dev->base + DW_IC_CLR_INTR);	/* clear interrupts */
-	writew(0, dev->base + DW_IC_INTR_MASK);	/* disable interrupts */
-	if (stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET))
+		/*
+		 * Anytime TX_ABRT is set, the contents of the tx/rx
+		 * buffers are flushed.  Make sure to skip them.
+		 */
+		writel(0, dev->base + DW_IC_INTR_MASK);
+		goto tx_aborted;
+	}
+
+	if (stat & DW_IC_INTR_RX_FULL)
+		i2c_dw_read(dev);
+
+	if (stat & DW_IC_INTR_TX_EMPTY)
+		i2c_dw_xfer_msg(dev);
+
+	/*
+	 * No need to modify or disable the interrupt mask here.
+	 * i2c_dw_xfer_msg() will take care of it according to
+	 * the current transmit status.
+	 */
+
+tx_aborted:
+	if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err)
 		complete(&dev->cmd_complete);
 
 	return IRQ_HANDLED;
@@ -474,8 +697,8 @@
 {
 	struct dw_i2c_dev *dev;
 	struct i2c_adapter *adap;
-	struct resource *mem, *irq, *ioarea;
-	int r;
+	struct resource *mem, *ioarea;
+	int irq, r;
 
 	/* NOTE: driver uses the static register mapping */
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -484,10 +707,10 @@
 		return -EINVAL;
 	}
 
-	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!irq) {
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
 		dev_err(&pdev->dev, "no irq resource?\n");
-		return -EINVAL;
+		return irq; /* -ENXIO */
 	}
 
 	ioarea = request_mem_region(mem->start, resource_size(mem),
@@ -504,10 +727,9 @@
 	}
 
 	init_completion(&dev->cmd_complete);
-	tasklet_init(&dev->pump_msg, dw_i2c_pump_msg, (unsigned long) dev);
 	mutex_init(&dev->lock);
 	dev->dev = get_device(&pdev->dev);
-	dev->irq = irq->start;
+	dev->irq = irq;
 	platform_set_drvdata(pdev, dev);
 
 	dev->clk = clk_get(&pdev->dev, NULL);
@@ -531,8 +753,8 @@
 	}
 	i2c_dw_init(dev);
 
-	writew(0, dev->base + DW_IC_INTR_MASK); /* disable IRQ */
-	r = request_irq(dev->irq, i2c_dw_isr, 0, pdev->name, dev);
+	writel(0, dev->base + DW_IC_INTR_MASK); /* disable IRQ */
+	r = request_irq(dev->irq, i2c_dw_isr, IRQF_DISABLED, pdev->name, dev);
 	if (r) {
 		dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq);
 		goto err_iounmap;
@@ -587,7 +809,7 @@
 	clk_put(dev->clk);
 	dev->clk = NULL;
 
-	writeb(0, dev->base + DW_IC_ENABLE);
+	writel(0, dev->base + DW_IC_ENABLE);
 	free_irq(dev->irq, dev);
 	kfree(dev);
 
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 827da08..75bf3ad 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -178,6 +178,12 @@
 	unsigned		b_hw:1;		/* bad h/w fixes */
 	unsigned		idle:1;
 	u16			iestate;	/* Saved interrupt register */
+	u16			pscstate;
+	u16			scllstate;
+	u16			sclhstate;
+	u16			bufstate;
+	u16			syscstate;
+	u16			westate;
 };
 
 static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev,
@@ -230,9 +236,18 @@
 
 	clk_enable(dev->iclk);
 	clk_enable(dev->fclk);
+	if (cpu_is_omap34xx()) {
+		omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
+		omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
+		omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
+		omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
+		omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, dev->bufstate);
+		omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, dev->syscstate);
+		omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
+		omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+	}
 	dev->idle = 0;
-	if (dev->iestate)
-		omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
+	omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
 }
 
 static void omap_i2c_idle(struct omap_i2c_dev *dev)
@@ -258,7 +273,7 @@
 
 static int omap_i2c_init(struct omap_i2c_dev *dev)
 {
-	u16 psc = 0, scll = 0, sclh = 0;
+	u16 psc = 0, scll = 0, sclh = 0, buf = 0;
 	u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
 	unsigned long fclk_rate = 12000000;
 	unsigned long timeout;
@@ -287,24 +302,22 @@
 					   SYSC_AUTOIDLE_MASK);
 
 		} else if (dev->rev >= OMAP_I2C_REV_ON_3430) {
-			u32 v;
-
-			v = SYSC_AUTOIDLE_MASK;
-			v |= SYSC_ENAWAKEUP_MASK;
-			v |= (SYSC_IDLEMODE_SMART <<
+			dev->syscstate = SYSC_AUTOIDLE_MASK;
+			dev->syscstate |= SYSC_ENAWAKEUP_MASK;
+			dev->syscstate |= (SYSC_IDLEMODE_SMART <<
 			      __ffs(SYSC_SIDLEMODE_MASK));
-			v |= (SYSC_CLOCKACTIVITY_FCLK <<
+			dev->syscstate |= (SYSC_CLOCKACTIVITY_FCLK <<
 			      __ffs(SYSC_CLOCKACTIVITY_MASK));
 
-			omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, v);
+			omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG,
+							dev->syscstate);
 			/*
 			 * Enabling all wakup sources to stop I2C freezing on
 			 * WFI instruction.
 			 * REVISIT: Some wkup sources might not be needed.
 			 */
-			omap_i2c_write_reg(dev, OMAP_I2C_WE_REG,
-							OMAP_I2C_WE_ALL);
-
+			dev->westate = OMAP_I2C_WE_ALL;
+			omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
 		}
 	}
 	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
@@ -394,23 +407,28 @@
 	omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);
 	omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh);
 
-	if (dev->fifo_size)
-		/* Note: setup required fifo size - 1 */
-		omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG,
-					(dev->fifo_size - 1) << 8 | /* RTRSH */
-					OMAP_I2C_BUF_RXFIF_CLR |
-					(dev->fifo_size - 1) | /* XTRSH */
-					OMAP_I2C_BUF_TXFIF_CLR);
+	if (dev->fifo_size) {
+		/* Note: setup required fifo size - 1. RTRSH and XTRSH */
+		buf = (dev->fifo_size - 1) << 8 | OMAP_I2C_BUF_RXFIF_CLR |
+			(dev->fifo_size - 1) | OMAP_I2C_BUF_TXFIF_CLR;
+		omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf);
+	}
 
 	/* Take the I2C module out of reset: */
 	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
 
 	/* Enable interrupts */
-	omap_i2c_write_reg(dev, OMAP_I2C_IE_REG,
-			(OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
+	dev->iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
 			OMAP_I2C_IE_ARDY | OMAP_I2C_IE_NACK |
 			OMAP_I2C_IE_AL)  | ((dev->fifo_size) ?
-				(OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0));
+				(OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0);
+	omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
+	if (cpu_is_omap34xx()) {
+		dev->pscstate = psc;
+		dev->scllstate = scll;
+		dev->sclhstate = sclh;
+		dev->bufstate = buf;
+	}
 	return 0;
 }
 
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c
index fbab684..5d1c260 100644
--- a/drivers/i2c/busses/i2c-pnx.c
+++ b/drivers/i2c/busses/i2c-pnx.c
@@ -638,7 +638,8 @@
 
 	/* Register this adapter with the I2C subsystem */
 	i2c_pnx->adapter->dev.parent = &pdev->dev;
-	ret = i2c_add_adapter(i2c_pnx->adapter);
+	i2c_pnx->adapter->nr = pdev->id;
+	ret = i2c_add_numbered_adapter(i2c_pnx->adapter);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "I2C: Failed to add bus\n");
 		goto out_irq;
diff --git a/drivers/i2c/busses/i2c-scmi.c b/drivers/i2c/busses/i2c-scmi.c
index b4a55d4..365e0be 100644
--- a/drivers/i2c/busses/i2c-scmi.c
+++ b/drivers/i2c/busses/i2c-scmi.c
@@ -363,7 +363,7 @@
 	smbus_cmi->cap_write = 0;
 
 	acpi_walk_namespace(ACPI_TYPE_METHOD, smbus_cmi->handle, 1,
-			    acpi_smbus_cmi_query_methods, smbus_cmi, NULL);
+			    acpi_smbus_cmi_query_methods, NULL, smbus_cmi, NULL);
 
 	if (smbus_cmi->cap_info == 0)
 		goto err;
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 9a5d0aa..98ccfeb 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -7,50 +7,25 @@
 	bool
 
 menuconfig IDE
-	tristate "ATA/ATAPI/MFM/RLL support"
+	tristate "ATA/ATAPI/MFM/RLL support (DEPRECATED)"
 	depends on HAVE_IDE
 	depends on BLOCK
 	---help---
-	  If you say Y here, your kernel will be able to manage low cost mass
-	  storage units such as ATA/(E)IDE and ATAPI units. The most common
-	  cases are IDE hard drives and ATAPI CD-ROM drives.
+	  If you say Y here, your kernel will be able to manage ATA/(E)IDE and
+	  ATAPI units. The most common cases are IDE hard drives and ATAPI
+	  CD-ROM drives.
 
-	  If your system is pure SCSI and doesn't use these interfaces, you
-	  can say N here.
-
-	  Integrated Disk Electronics (IDE aka ATA-1) is a connecting standard
-	  for mass storage units such as hard disks. It was designed by
-	  Western Digital and Compaq Computer in 1984. It was then named
-	  ST506. Quite a number of disks use the IDE interface.
-
-	  AT Attachment (ATA) is the superset of the IDE specifications.
-	  ST506 was also called ATA-1.
-
-	  Fast-IDE is ATA-2 (also named Fast ATA), Enhanced IDE (EIDE) is
-	  ATA-3. It provides support for larger disks (up to 8.4GB by means of
-	  the LBA standard), more disks (4 instead of 2) and for other mass
-	  storage units such as tapes and cdrom. UDMA/33 (aka UltraDMA/33) is
-	  ATA-4 and provides faster (and more CPU friendly) transfer modes
-	  than previous PIO (Programmed processor Input/Output) from previous
-	  ATA/IDE standards by means of fast DMA controllers.
-
-	  ATA Packet Interface (ATAPI) is a protocol used by EIDE tape and
-	  CD-ROM drives, similar in many respects to the SCSI protocol.
-
-	  SMART IDE (Self Monitoring, Analysis and Reporting Technology) was
-	  designed in order to prevent data corruption and disk crash by
-	  detecting pre hardware failure conditions (heat, access time, and
-	  the like...). Disks built since June 1995 may follow this standard.
-	  The kernel itself doesn't manage this; however there are quite a
-	  number of user programs such as smart that can query the status of
-	  SMART parameters from disk drives.
+	  This subsystem is currently in maintenance mode with only bug fix
+	  changes applied. Users of ATA hardware are encouraged to migrate to
+	  the newer ATA subsystem ("Serial ATA (prod) and Parallel ATA
+	  (experimental) drivers") which is more actively maintained.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called ide-core.
 
 	  For further information, please read <file:Documentation/ide/ide.txt>.
 
-	  If unsure, say Y.
+	  If unsure, say N.
 
 if IDE
 
diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c
index e59b6de..0abc43f 100644
--- a/drivers/ide/alim15x3.c
+++ b/drivers/ide/alim15x3.c
@@ -40,16 +40,6 @@
 #define DRV_NAME "alim15x3"
 
 /*
- * Allow UDMA on M1543C-E chipset for WDC disks that ignore CRC checking
- * (this is DANGEROUS and could result in data corruption).
- */
-static int wdc_udma;
-
-module_param(wdc_udma, bool, 0);
-MODULE_PARM_DESC(wdc_udma,
-		 "allow UDMA on M1543C-E chipset for WDC disks (DANGEROUS)");
-
-/*
  *	ALi devices are not plug in. Otherwise these static values would
  *	need to go. They ought to go away anyway
  */
@@ -132,7 +122,7 @@
 	if (m5229_revision > 0x20 && m5229_revision < 0xC2) {
 		if (drive->media != ide_disk)
 			return 0;
-		if (wdc_udma == 0 && chip_is_1543c_e &&
+		if (chip_is_1543c_e &&
 		    strstr((char *)&drive->id[ATA_ID_PROD], "WDC "))
 			return 0;
 	}
diff --git a/drivers/ide/au1xxx-ide.c b/drivers/ide/au1xxx-ide.c
index 58121bd..87cef0c 100644
--- a/drivers/ide/au1xxx-ide.c
+++ b/drivers/ide/au1xxx-ide.c
@@ -532,14 +532,13 @@
 		goto out;
 	}
 
-	if (!request_mem_region(res->start, res->end - res->start + 1,
-				dev->name)) {
+	if (!request_mem_region(res->start, resource_size(res), dev->name)) {
 		pr_debug("%s: request_mem_region failed\n", DRV_NAME);
 		ret =  -EBUSY;
 		goto out;
 	}
 
-	ahwif->regbase = (u32)ioremap(res->start, res->end - res->start + 1);
+	ahwif->regbase = (u32)ioremap(res->start, resource_size(res));
 	if (ahwif->regbase == 0) {
 		ret = -ENOMEM;
 		goto out;
@@ -575,7 +574,7 @@
 	iounmap((void *)ahwif->regbase);
 
 	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
-	release_mem_region(res->start, res->end - res->start + 1);
+	release_mem_region(res->start, resource_size(res));
 
 	return 0;
 }
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c
index ca0c46f..f2500c8 100644
--- a/drivers/ide/cmd64x.c
+++ b/drivers/ide/cmd64x.c
@@ -20,14 +20,6 @@
 
 #define DRV_NAME "cmd64x"
 
-#define CMD_DEBUG 0
-
-#if CMD_DEBUG
-#define cmdprintk(x...)	printk(x)
-#else
-#define cmdprintk(x...)
-#endif
-
 /*
  * CMD64x specific registers definition.
  */
@@ -76,9 +68,6 @@
 		{15, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0};
 	static const u8 drwtim_regs[4] = {DRWTIM0, DRWTIM1, DRWTIM2, DRWTIM3};
 
-	cmdprintk("program_cycle_times parameters: total=%d, active=%d\n",
-		  cycle_time, active_time);
-
 	cycle_count	= quantize_timing( cycle_time, clock_time);
 	active_count	= quantize_timing(active_time, clock_time);
 	recovery_count	= cycle_count - active_count;
@@ -94,9 +83,6 @@
 	if (active_count > 16)		/* shouldn't actually happen... */
 	 	active_count = 16;
 
-	cmdprintk("Final counts: total=%d, active=%d, recovery=%d\n",
-		  cycle_count, active_count, recovery_count);
-
 	/*
 	 * Convert values to internal chipset representation
 	 */
@@ -106,7 +92,6 @@
 	/* Program the active/recovery counts into the DRWTIM register */
 	drwtim = (active_count << 4) | recovery_count;
 	(void) pci_write_config_byte(dev, drwtim_regs[drive->dn], drwtim);
-	cmdprintk("Write 0x%02x to reg 0x%x\n", drwtim, drwtim_regs[drive->dn]);
 }
 
 /*
@@ -150,7 +135,6 @@
 
 	if (setup_count > 5)		/* shouldn't actually happen... */
 		setup_count = 5;
-	cmdprintk("Final address setup count: %d\n", setup_count);
 
 	/*
 	 * Program the address setup clocks into the ARTTIM registers.
@@ -162,7 +146,6 @@
 	arttim &= ~0xc0;
 	arttim |= setup_values[setup_count];
 	(void) pci_write_config_byte(dev, arttim_regs[drive->dn], arttim);
-	cmdprintk("Write 0x%02x to reg 0x%x\n", arttim, arttim_regs[drive->dn]);
 }
 
 /*
diff --git a/drivers/ide/cs5535.c b/drivers/ide/cs5535.c
index 983d957..b883838 100644
--- a/drivers/ide/cs5535.c
+++ b/drivers/ide/cs5535.c
@@ -187,6 +187,7 @@
 
 static const struct pci_device_id cs5535_pci_tbl[] = {
 	{ PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_CS5535_IDE), 0 },
+	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5535_IDE), },
 	{ 0, },
 };
 
diff --git a/drivers/ide/cy82c693.c b/drivers/ide/cy82c693.c
index 74fc540..d6e2cbb 100644
--- a/drivers/ide/cy82c693.c
+++ b/drivers/ide/cy82c693.c
@@ -51,11 +51,6 @@
 #define DRV_NAME "cy82c693"
 
 /*
- *	The following are used to debug the driver.
- */
-#define CY82C693_DEBUG_INFO	0
-
-/*
  *	NOTE: the value for busmaster timeout is tricky and I got it by
  *	trial and error!  By using a to low value will cause DMA timeouts
  *	and drop IDE performance, and by using a to high value will cause
@@ -176,11 +171,6 @@
 	outb(index, CY82_INDEX_PORT);
 	outb(data, CY82_DATA_PORT);
 
-#if CY82C693_DEBUG_INFO
-	printk(KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n",
-		drive->name, hwif->channel, drive->dn & 1, mode & 3, single);
-#endif /* CY82C693_DEBUG_INFO */
-
 	/*
 	 * note: below we set the value for Bus Master IDE TimeOut Register
 	 * I'm not absolutly sure what this does, but it solved my problem
@@ -194,11 +184,6 @@
 	data = BUSMASTER_TIMEOUT;
 	outb(CY82_INDEX_TIMEOUT, CY82_INDEX_PORT);
 	outb(data, CY82_DATA_PORT);
-
-#if CY82C693_DEBUG_INFO
-	printk(KERN_INFO "%s: Set IDE Bus Master TimeOut Register to 0x%X\n",
-		drive->name, data);
-#endif /* CY82C693_DEBUG_INFO */
 }
 
 static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
@@ -239,8 +224,6 @@
 		pci_write_config_byte(dev, CY82_IDE_MASTER_IOR, pclk.time_16r);
 		pci_write_config_byte(dev, CY82_IDE_MASTER_IOW, pclk.time_16w);
 		pci_write_config_byte(dev, CY82_IDE_MASTER_8BIT, pclk.time_8);
-
-		addrCtrl &= 0xF;
 	} else {
 		/*
 		 * set slave drive
@@ -257,17 +240,7 @@
 		pci_write_config_byte(dev, CY82_IDE_SLAVE_IOR, pclk.time_16r);
 		pci_write_config_byte(dev, CY82_IDE_SLAVE_IOW, pclk.time_16w);
 		pci_write_config_byte(dev, CY82_IDE_SLAVE_8BIT, pclk.time_8);
-
-		addrCtrl >>= 4;
-		addrCtrl &= 0xF;
 	}
-
-#if CY82C693_DEBUG_INFO
-	printk(KERN_INFO "%s (ch=%d, dev=%d): set PIO timing to "
-		"(addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n",
-		drive->name, hwif->channel, drive->dn & 1,
-		addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8);
-#endif /* CY82C693_DEBUG_INFO */
 }
 
 static void __devinit init_iops_cy82c693(ide_hwif_t *hwif)
diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c
index 7ce68ef..4d90ac2 100644
--- a/drivers/ide/hpt366.c
+++ b/drivers/ide/hpt366.c
@@ -297,68 +297,6 @@
 	/* XFER_PIO_0 */	0xc0d08585
 };
 
-#if 0
-/* These are the timing tables from the HighPoint open source drivers... */
-static u32 thirty_three_base_hpt37x[] = {
-	/* XFER_UDMA_6 */	0x12446231,	/* 0x12646231 ?? */
-	/* XFER_UDMA_5 */	0x12446231,
-	/* XFER_UDMA_4 */	0x12446231,
-	/* XFER_UDMA_3 */	0x126c6231,
-	/* XFER_UDMA_2 */	0x12486231,
-	/* XFER_UDMA_1 */	0x124c6233,
-	/* XFER_UDMA_0 */	0x12506297,
-
-	/* XFER_MW_DMA_2 */	0x22406c31,
-	/* XFER_MW_DMA_1 */	0x22406c33,
-	/* XFER_MW_DMA_0 */	0x22406c97,
-
-	/* XFER_PIO_4 */	0x06414e31,
-	/* XFER_PIO_3 */	0x06414e42,
-	/* XFER_PIO_2 */	0x06414e53,
-	/* XFER_PIO_1 */	0x06814e93,
-	/* XFER_PIO_0 */	0x06814ea7
-};
-
-static u32 fifty_base_hpt37x[] = {
-	/* XFER_UDMA_6 */	0x12848242,
-	/* XFER_UDMA_5 */	0x12848242,
-	/* XFER_UDMA_4 */	0x12ac8242,
-	/* XFER_UDMA_3 */	0x128c8242,
-	/* XFER_UDMA_2 */	0x120c8242,
-	/* XFER_UDMA_1 */	0x12148254,
-	/* XFER_UDMA_0 */	0x121882ea,
-
-	/* XFER_MW_DMA_2 */	0x22808242,
-	/* XFER_MW_DMA_1 */	0x22808254,
-	/* XFER_MW_DMA_0 */	0x228082ea,
-
-	/* XFER_PIO_4 */	0x0a81f442,
-	/* XFER_PIO_3 */	0x0a81f443,
-	/* XFER_PIO_2 */	0x0a81f454,
-	/* XFER_PIO_1 */	0x0ac1f465,
-	/* XFER_PIO_0 */	0x0ac1f48a
-};
-
-static u32 sixty_six_base_hpt37x[] = {
-	/* XFER_UDMA_6 */	0x1c869c62,
-	/* XFER_UDMA_5 */	0x1cae9c62,	/* 0x1c8a9c62 */
-	/* XFER_UDMA_4 */	0x1c8a9c62,
-	/* XFER_UDMA_3 */	0x1c8e9c62,
-	/* XFER_UDMA_2 */	0x1c929c62,
-	/* XFER_UDMA_1 */	0x1c9a9c62,
-	/* XFER_UDMA_0 */	0x1c829c62,
-
-	/* XFER_MW_DMA_2 */	0x2c829c62,
-	/* XFER_MW_DMA_1 */	0x2c829c66,
-	/* XFER_MW_DMA_0 */	0x2c829d2e,
-
-	/* XFER_PIO_4 */	0x0c829c62,
-	/* XFER_PIO_3 */	0x0c829c84,
-	/* XFER_PIO_2 */	0x0c829ca6,
-	/* XFER_PIO_1 */	0x0d029d26,
-	/* XFER_PIO_0 */	0x0d029d5e
-};
-#else
 /*
  * The following are the new timing tables with PIO mode data/taskfile transfer
  * overclocking fixed...
@@ -424,16 +362,13 @@
 	/* XFER_PIO_1 */	0x0d02ff26,
 	/* XFER_PIO_0 */	0x0d42ff7f
 };
-#endif
 
-#define HPT366_DEBUG_DRIVE_INFO		0
 #define HPT371_ALLOW_ATA133_6		1
 #define HPT302_ALLOW_ATA133_6		1
 #define HPT372_ALLOW_ATA133_6		1
 #define HPT370_ALLOW_ATA100_5		0
 #define HPT366_ALLOW_ATA66_4		1
 #define HPT366_ALLOW_ATA66_3		1
-#define HPT366_MAX_DEVS			8
 
 /* Supported ATA clock frequencies */
 enum ata_clock {
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 58fc920..6a0e625 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -221,6 +221,8 @@
 
 static DEFINE_MUTEX(idetape_ref_mutex);
 
+static DEFINE_MUTEX(idetape_chrdev_mutex);
+
 static struct class *idetape_sysfs_class;
 
 static void ide_tape_release(struct device *);
@@ -1457,10 +1459,11 @@
 	if (i >= MAX_HWIFS * MAX_DRIVES)
 		return -ENXIO;
 
-	lock_kernel();
+	mutex_lock(&idetape_chrdev_mutex);
+
 	tape = ide_tape_get(NULL, true, i);
 	if (!tape) {
-		unlock_kernel();
+		mutex_unlock(&idetape_chrdev_mutex);
 		return -ENXIO;
 	}
 
@@ -1519,12 +1522,15 @@
 				tape->door_locked = DOOR_LOCKED;
 		}
 	}
-	unlock_kernel();
+	mutex_unlock(&idetape_chrdev_mutex);
+
 	return 0;
 
 out_put_tape:
 	ide_tape_put(tape);
-	unlock_kernel();
+
+	mutex_unlock(&idetape_chrdev_mutex);
+
 	return retval;
 }
 
@@ -1551,7 +1557,8 @@
 	ide_drive_t *drive = tape->drive;
 	unsigned int minor = iminor(inode);
 
-	lock_kernel();
+	mutex_lock(&idetape_chrdev_mutex);
+
 	tape = drive->driver_data;
 
 	ide_debug_log(IDE_DBG_FUNC, "enter");
@@ -1575,7 +1582,9 @@
 	}
 	clear_bit(ilog2(IDE_AFLAG_BUSY), &drive->atapi_flags);
 	ide_tape_put(tape);
-	unlock_kernel();
+
+	mutex_unlock(&idetape_chrdev_mutex);
+
 	return 0;
 }
 
diff --git a/drivers/ide/ide_platform.c b/drivers/ide/ide_platform.c
index b579fbe..42965b3 100644
--- a/drivers/ide/ide_platform.c
+++ b/drivers/ide/ide_platform.c
@@ -81,14 +81,14 @@
 
 	if (mmio) {
 		base = devm_ioremap(&pdev->dev,
-			res_base->start, res_base->end - res_base->start + 1);
+			res_base->start, resource_size(res_base));
 		alt_base = devm_ioremap(&pdev->dev,
-			res_alt->start, res_alt->end - res_alt->start + 1);
+			res_alt->start, resource_size(res_alt));
 	} else {
 		base = devm_ioport_map(&pdev->dev,
-			res_base->start, res_base->end - res_base->start + 1);
+			res_base->start, resource_size(res_base));
 		alt_base = devm_ioport_map(&pdev->dev,
-			res_alt->start, res_alt->end - res_alt->start + 1);
+			res_alt->start, resource_size(res_alt));
 	}
 
 	memset(&hw, 0, sizeof(hw));
diff --git a/drivers/ide/pdc202xx_old.c b/drivers/ide/pdc202xx_old.c
index cb812f3..35161dd 100644
--- a/drivers/ide/pdc202xx_old.c
+++ b/drivers/ide/pdc202xx_old.c
@@ -21,8 +21,6 @@
 
 #define DRV_NAME "pdc202xx_old"
 
-#define PDC202XX_DEBUG_DRIVE_INFO	0
-
 static void pdc_old_disable_66MHz_clock(ide_hwif_t *);
 
 static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed)
@@ -34,11 +32,6 @@
 	u8			AP = 0, BP = 0, CP = 0;
 	u8			TA = 0, TB = 0, TC = 0;
 
-#if PDC202XX_DEBUG_DRIVE_INFO
-	u32			drive_conf = 0;
-	pci_read_config_dword(dev, drive_pci, &drive_conf);
-#endif
-
 	/*
 	 * TODO: do this once per channel
 	 */
@@ -89,14 +82,6 @@
 		pci_write_config_byte(dev, drive_pci + 1, BP | TB);
 		pci_write_config_byte(dev, drive_pci + 2, CP | TC);
 	}
-
-#if PDC202XX_DEBUG_DRIVE_INFO
-	printk(KERN_DEBUG "%s: %s drive%d 0x%08x ",
-		drive->name, ide_xfer_verbose(speed),
-		drive->dn, drive_conf);
-	pci_read_config_dword(dev, drive_pci, &drive_conf);
-	printk("0x%08x\n", drive_conf);
-#endif
 }
 
 static void pdc202xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
diff --git a/drivers/ide/sis5513.c b/drivers/ide/sis5513.c
index 3b88eba..4687060 100644
--- a/drivers/ide/sis5513.c
+++ b/drivers/ide/sis5513.c
@@ -632,12 +632,3 @@
 MODULE_AUTHOR("Lionel Bouton, L C Chang, Andre Hedrick, Vojtech Pavlik");
 MODULE_DESCRIPTION("PCI driver module for SIS IDE");
 MODULE_LICENSE("GPL");
-
-/*
- * TODO:
- *	- CLEANUP
- *	- More checks in the config registers (force values instead of
- *	  relying on the BIOS setting them correctly).
- *	- Further optimisations ?
- *	  . for example ATA66+ regs 0x48 & 0x4A
- */
diff --git a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c
index d698da4..3c2bbf0 100644
--- a/drivers/ide/sl82c105.c
+++ b/drivers/ide/sl82c105.c
@@ -24,13 +24,6 @@
 
 #define DRV_NAME "sl82c105"
 
-#undef DEBUG
-
-#ifdef DEBUG
-#define DBG(arg) printk arg
-#else
-#define DBG(fmt,...)
-#endif
 /*
  * SL82C105 PCI config register 0x40 bits.
  */
@@ -104,9 +97,6 @@
 	unsigned long timings = (unsigned long)ide_get_drivedata(drive);
 	u16 drv_ctrl;
 
- 	DBG(("sl82c105_tune_chipset(drive:%s, speed:%s)\n",
-	     drive->name, ide_xfer_verbose(speed)));
-
 	drv_ctrl = mwdma_timings[speed - XFER_MW_DMA_0];
 
 	/*
@@ -196,8 +186,6 @@
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
 	int reg 		= 0x44 + drive->dn * 4;
 
-	DBG(("%s(drive:%s)\n", __func__, drive->name));
-
 	pci_write_config_word(dev, reg,
 			      (unsigned long)ide_get_drivedata(drive) >> 16);
 
@@ -209,8 +197,6 @@
 {
 	struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
 
-	DBG(("sl82c105_dma_clear(drive:%s)\n", drive->name));
-
 	sl82c105_reset_host(dev);
 }
 
@@ -218,11 +204,7 @@
 {
 	struct pci_dev *dev	= to_pci_dev(drive->hwif->dev);
 	int reg 		= 0x44 + drive->dn * 4;
-	int ret;
-
-	DBG(("%s(drive:%s)\n", __func__, drive->name));
-
-	ret = ide_dma_end(drive);
+	int ret			= ide_dma_end(drive);
 
 	pci_write_config_word(dev, reg,
 			      (unsigned long)ide_get_drivedata(drive));
@@ -239,8 +221,6 @@
 	struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
 	u32 val;
 
-	DBG(("sl82c105_resetproc(drive:%s)\n", drive->name));
-
 	pci_read_config_dword(dev, 0x40, &val);
 	val |= (CTRL_P1F16 | CTRL_P0F16);
 	pci_write_config_dword(dev, 0x40, val);
@@ -291,8 +271,6 @@
 {
 	u32 val;
 
-	DBG(("init_chipset_sl82c105()\n"));
-
 	pci_read_config_dword(dev, 0x40, &val);
 	val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16;
 	pci_write_config_dword(dev, 0x40, val);
diff --git a/drivers/ide/slc90e66.c b/drivers/ide/slc90e66.c
index 9aec78d..1ccfb40 100644
--- a/drivers/ide/slc90e66.c
+++ b/drivers/ide/slc90e66.c
@@ -91,8 +91,7 @@
 
 		if (!(reg48 & u_flag))
 			pci_write_config_word(dev, 0x48, reg48|u_flag);
-		/* FIXME: (reg4a & a_speed) ? */
-		if ((reg4a & u_speed) != u_speed) {
+		if ((reg4a & a_speed) != u_speed) {
 			pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
 			pci_read_config_word(dev, 0x4a, &reg4a);
 			pci_write_config_word(dev, 0x4a, reg4a|u_speed);
diff --git a/drivers/ide/tx4938ide.c b/drivers/ide/tx4938ide.c
index ea89fdd..fd59c0d 100644
--- a/drivers/ide/tx4938ide.c
+++ b/drivers/ide/tx4938ide.c
@@ -146,7 +146,7 @@
 		return -ENODEV;
 
 	if (!devm_request_mem_region(&pdev->dev, res->start,
-				     res->end - res->start + 1, "tx4938ide"))
+				     resource_size(res), "tx4938ide"))
 		return -EBUSY;
 	mapbase = (unsigned long)devm_ioremap(&pdev->dev, res->start,
 					      8 << pdata->ioport_shift);
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index 2cd00b5..9fd4a0d 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -125,7 +125,7 @@
    0 - no debugging messages
    1 - some debugging messages, but none during DMA frame transmission
    2 - lots of messages, including during DMA frame transmission
-       (will cause undeflows if your machine is too slow!)
+       (will cause underflows if your machine is too slow!)
 */
 
 #define DV1394_DEBUG_LEVEL 0
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c
index 72ed339..0677fc7 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c
@@ -589,7 +589,7 @@
 
 /* write len bytes of data into addr (32B aligned address)
  * If data is NULL, clear len byte of memory to zero.
- * caller aquires the ctrl_qp lock before the call
+ * caller acquires the ctrl_qp lock before the call
  */
 static int cxio_hal_ctrl_qp_write_mem(struct cxio_rdev *rdev_p, u32 addr,
 				      u32 len, void *data)
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c
index 40dbe54..73933a4 100644
--- a/drivers/infiniband/hw/ipath/ipath_file_ops.c
+++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c
@@ -1821,7 +1821,6 @@
 static int ipath_open(struct inode *in, struct file *fp)
 {
 	/* The real work is performed later in ipath_assign_port() */
-	cycle_kernel_lock();
 	fp->private_data = kzalloc(sizeof(struct ipath_filedata), GFP_KERNEL);
 	return fp->private_data ? 0 : -ENOMEM;
 }
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6110.c b/drivers/infiniband/hw/ipath/ipath_iba6110.c
index 4bd39c8..37d12e5 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba6110.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba6110.c
@@ -381,7 +381,7 @@
 #define IPATH_GPIO_SCL \
 	(1ULL << (_IPATH_GPIO_SCL_NUM+INFINIPATH_EXTC_GPIOOE_SHIFT))
 
-/* keep the code below somewhat more readonable; not used elsewhere */
+/* keep the code below somewhat more readable; not used elsewhere */
 #define _IPATH_HTLINK0_CRCBITS (infinipath_hwe_htclnkabyte0crcerr |	\
 				infinipath_hwe_htclnkabyte1crcerr)
 #define _IPATH_HTLINK1_CRCBITS (infinipath_hwe_htclnkbbyte0crcerr |	\
diff --git a/drivers/infiniband/hw/ipath/ipath_sd7220.c b/drivers/infiniband/hw/ipath/ipath_sd7220.c
index aa47eb5..2a68d9f 100644
--- a/drivers/infiniband/hw/ipath/ipath_sd7220.c
+++ b/drivers/infiniband/hw/ipath/ipath_sd7220.c
@@ -614,7 +614,7 @@
  * @wd: Write Data - value to set in register
  * @mask: ones where data should be spliced into reg.
  *
- * Basic register read/modify/write, with un-needed acesses elided. That is,
+ * Basic register read/modify/write, with un-needed accesses elided. That is,
  * a mask of zero will prevent write, while a mask of 0xFF will prevent read.
  * returns current (presumed, if a write was done) contents of selected
  * register, or <0 if errors.
@@ -989,7 +989,7 @@
 	/* Set DFELTHFDR/HDR thresholds */
 	RXEQ_VAL(7, 8,    0, 0, 0, 0), /* FDR */
 	RXEQ_VAL(7, 0x21, 0, 0, 0, 0), /* HDR */
-	/* Set TLTHFDR/HDR theshold */
+	/* Set TLTHFDR/HDR threshold */
 	RXEQ_VAL(7, 9,    2, 2, 2, 2), /* FDR */
 	RXEQ_VAL(7, 0x23, 2, 2, 2, 2), /* HDR */
 	/* Set Preamp setting 2 (ZFR/ZCNT) */
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 219b103..256a00c 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -352,7 +352,7 @@
 	 * anymore, so we do this only if selective signaling is off.
 	 *
 	 * Further, on 32-bit platforms, we can't use vmap() to make
-	 * the QP buffer virtually contigious.  Thus we have to use
+	 * the QP buffer virtually contiguous.  Thus we have to use
 	 * constant-sized WRs to make sure a WR is always fully within
 	 * a single page-sized chunk.
 	 *
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index add9188..5f7a6fc 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -625,6 +625,7 @@
 				  ISCSI_USERNAME | ISCSI_PASSWORD |
 				  ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
 				  ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
+				  ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO |
 				  ISCSI_PING_TMO | ISCSI_RECV_TMO |
 				  ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
 	.host_param_mask	= ISCSI_HOST_HWADDRESS |
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index ea9e155..8579f32 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -499,7 +499,7 @@
 
  /**
  * starts the process of connecting to the target
- * sleeps untill the connection is established or rejected
+ * sleeps until the connection is established or rejected
  */
 int iser_connect(struct iser_conn   *ib_conn,
 		 struct sockaddr_in *src_addr,
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index cd50c00..07c2cd4 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -8,7 +8,7 @@
 config INPUT
 	tristate "Generic input layer (needed for keyboard, mouse, ...)" if EMBEDDED
 	default y
-	---help---
+	help
 	  Say Y here if you have any input device (mouse, keyboard, tablet,
 	  joystick, steering wheel ...) connected to your system and want
 	  it to be available to applications. This includes standard PS/2
@@ -27,8 +27,7 @@
 
 config INPUT_FF_MEMLESS
 	tristate "Support for memoryless force-feedback devices"
-	default n
-	---help---
+	help
 	  Say Y here if you have memoryless force-feedback input device
 	  such as Logitech WingMan Force 3D, ThrustMaster FireStorm Dual
 	  Power 2, or similar. You will also need to enable hardware-specific
@@ -52,12 +51,25 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called input-polldev.
 
+config INPUT_SPARSEKMAP
+	tristate "Sparse keymap support library"
+	help
+	  Say Y here if you are using a driver for an input
+	  device that uses sparse keymap. This option is only
+	  useful for out-of-tree drivers since in-tree drivers
+	  select it automatically.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called sparse-keymap.
+
 comment "Userland interfaces"
 
 config INPUT_MOUSEDEV
 	tristate "Mouse interface" if EMBEDDED
 	default y
-	---help---
+	help
 	  Say Y here if you want your mouse to be accessible as char devices
 	  13:32+ - /dev/input/mouseX and 13:63 - /dev/input/mice as an
 	  emulated IntelliMouse Explorer PS/2 mouse. That way, all user space
@@ -73,7 +85,7 @@
 	bool "Provide legacy /dev/psaux device"
 	default y
 	depends on INPUT_MOUSEDEV
-	---help---
+	help
 	  Say Y here if you want your mouse also be accessible as char device
 	  10:1 - /dev/psaux. The data available through /dev/psaux is exactly
 	  the same as the data from /dev/input/mice.
@@ -103,7 +115,7 @@
 
 config INPUT_JOYDEV
 	tristate "Joystick interface"
-	---help---
+	help
 	  Say Y here if you want your joystick or gamepad to be
 	  accessible as char device 13:0+ - /dev/input/jsX device.
 
@@ -125,7 +137,7 @@
 
 config INPUT_EVBUG
 	tristate "Event debugging"
-	---help---
+	help
 	  Say Y here if you have a problem with the input subsystem and
 	  want all events (keypresses, mouse movements), to be output to
 	  the system log. While this is useful for debugging, it's also
@@ -140,7 +152,7 @@
 config INPUT_APMPOWER
 	tristate "Input Power Event -> APM Bridge" if EMBEDDED
 	depends on INPUT && APM_EMULATION
-	---help---
+	help
 	  Say Y here if you want suspend key events to trigger a user
 	  requested suspend through APM. This is useful on embedded
 	  systems where such behaviour is desired without userspace
@@ -153,6 +165,7 @@
 	tristate "Xen virtual keyboard and mouse support"
 	depends on XEN_FBDEV_FRONTEND
 	default y
+	select XEN_XENBUS_FRONTEND
 	help
 	  This driver implements the front-end of the Xen virtual
 	  keyboard and mouse device driver.  It communicates with a back-end
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index 4c9c745..7ad212d 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -9,6 +9,7 @@
 
 obj-$(CONFIG_INPUT_FF_MEMLESS)	+= ff-memless.o
 obj-$(CONFIG_INPUT_POLLDEV)	+= input-polldev.o
+obj-$(CONFIG_INPUT_SPARSEKMAP)	+= sparse-keymap.o
 
 obj-$(CONFIG_INPUT_MOUSEDEV)	+= mousedev.o
 obj-$(CONFIG_INPUT_JOYDEV)	+= joydev.o
diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c
index 38df81f..b2f07aa 100644
--- a/drivers/input/ff-core.c
+++ b/drivers/input/ff-core.c
@@ -353,7 +353,7 @@
 EXPORT_SYMBOL_GPL(input_ff_create);
 
 /**
- * input_ff_free() - frees force feedback portion of input device
+ * input_ff_destroy() - frees force feedback portion of input device
  * @dev: input device supporting force feedback
  *
  * This function is only needed in error path as input core will
@@ -369,6 +369,7 @@
 		if (ff->destroy)
 			ff->destroy(ff);
 		kfree(ff->private);
+		kfree(ff->effects);
 		kfree(ff);
 		dev->ff = NULL;
 	}
diff --git a/drivers/input/input-polldev.c b/drivers/input/input-polldev.c
index 0d3ce7a..aa6713b 100644
--- a/drivers/input/input-polldev.c
+++ b/drivers/input/input-polldev.c
@@ -56,14 +56,10 @@
 	mutex_unlock(&polldev_mutex);
 }
 
-static void input_polled_device_work(struct work_struct *work)
+static void input_polldev_queue_work(struct input_polled_dev *dev)
 {
-	struct input_polled_dev *dev =
-		container_of(work, struct input_polled_dev, work.work);
 	unsigned long delay;
 
-	dev->poll(dev);
-
 	delay = msecs_to_jiffies(dev->poll_interval);
 	if (delay >= HZ)
 		delay = round_jiffies_relative(delay);
@@ -71,6 +67,15 @@
 	queue_delayed_work(polldev_wq, &dev->work, delay);
 }
 
+static void input_polled_device_work(struct work_struct *work)
+{
+	struct input_polled_dev *dev =
+		container_of(work, struct input_polled_dev, work.work);
+
+	dev->poll(dev);
+	input_polldev_queue_work(dev);
+}
+
 static int input_open_polled_device(struct input_dev *input)
 {
 	struct input_polled_dev *dev = input_get_drvdata(input);
@@ -80,11 +85,12 @@
 	if (error)
 		return error;
 
-	if (dev->flush)
-		dev->flush(dev);
+	if (dev->open)
+		dev->open(dev);
 
-	queue_delayed_work(polldev_wq, &dev->work,
-			   msecs_to_jiffies(dev->poll_interval));
+	/* Only start polling if polling is enabled */
+	if (dev->poll_interval > 0)
+		queue_delayed_work(polldev_wq, &dev->work, 0);
 
 	return 0;
 }
@@ -95,8 +101,88 @@
 
 	cancel_delayed_work_sync(&dev->work);
 	input_polldev_stop_workqueue();
+
+	if (dev->close)
+		dev->close(dev);
 }
 
+/* SYSFS interface */
+
+static ssize_t input_polldev_get_poll(struct device *dev,
+				      struct device_attribute *attr, char *buf)
+{
+	struct input_polled_dev *polldev = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", polldev->poll_interval);
+}
+
+static ssize_t input_polldev_set_poll(struct device *dev,
+				struct device_attribute *attr, const char *buf,
+				size_t count)
+{
+	struct input_polled_dev *polldev = dev_get_drvdata(dev);
+	struct input_dev *input = polldev->input;
+	unsigned long interval;
+
+	if (strict_strtoul(buf, 0, &interval))
+		return -EINVAL;
+
+	if (interval < polldev->poll_interval_min)
+		return -EINVAL;
+
+	if (interval > polldev->poll_interval_max)
+		return -EINVAL;
+
+	mutex_lock(&input->mutex);
+
+	polldev->poll_interval = interval;
+
+	if (input->users) {
+		cancel_delayed_work_sync(&polldev->work);
+		if (polldev->poll_interval > 0)
+			input_polldev_queue_work(polldev);
+	}
+
+	mutex_unlock(&input->mutex);
+
+	return count;
+}
+
+static DEVICE_ATTR(poll, S_IRUGO | S_IWUSR, input_polldev_get_poll,
+					    input_polldev_set_poll);
+
+
+static ssize_t input_polldev_get_max(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct input_polled_dev *polldev = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", polldev->poll_interval_max);
+}
+
+static DEVICE_ATTR(max, S_IRUGO, input_polldev_get_max, NULL);
+
+static ssize_t input_polldev_get_min(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct input_polled_dev *polldev = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", polldev->poll_interval_min);
+}
+
+static DEVICE_ATTR(min, S_IRUGO, input_polldev_get_min, NULL);
+
+static struct attribute *sysfs_attrs[] = {
+	&dev_attr_poll.attr,
+	&dev_attr_max.attr,
+	&dev_attr_min.attr,
+	NULL
+};
+
+static struct attribute_group input_polldev_attribute_group = {
+	.attrs = sysfs_attrs
+};
+
 /**
  * input_allocate_polled_device - allocated memory polled device
  *
@@ -126,7 +212,7 @@
  * @dev: device to free
  *
  * The function frees memory allocated for polling device and drops
- * reference to the associated input device (if present).
+ * reference to the associated input device.
  */
 void input_free_polled_device(struct input_polled_dev *dev)
 {
@@ -150,15 +236,38 @@
 int input_register_polled_device(struct input_polled_dev *dev)
 {
 	struct input_dev *input = dev->input;
+	int error;
 
 	input_set_drvdata(input, dev);
 	INIT_DELAYED_WORK(&dev->work, input_polled_device_work);
 	if (!dev->poll_interval)
 		dev->poll_interval = 500;
+	if (!dev->poll_interval_max)
+		dev->poll_interval_max = dev->poll_interval;
 	input->open = input_open_polled_device;
 	input->close = input_close_polled_device;
 
-	return input_register_device(input);
+	error = input_register_device(input);
+	if (error)
+		return error;
+
+	error = sysfs_create_group(&input->dev.kobj,
+				   &input_polldev_attribute_group);
+	if (error) {
+		input_unregister_device(input);
+		return error;
+	}
+
+	/*
+	 * Take extra reference to the underlying input device so
+	 * that it survives call to input_unregister_polled_device()
+	 * and is deleted only after input_free_polled_device()
+	 * has been invoked. This is needed to ease task of freeing
+	 * sparse keymaps.
+	 */
+	input_get_device(input);
+
+	return 0;
 }
 EXPORT_SYMBOL(input_register_polled_device);
 
@@ -169,13 +278,13 @@
  * The function unregisters previously registered polled input
  * device from input layer. Polling is stopped and device is
  * ready to be freed with call to input_free_polled_device().
- * Callers should not attempt to access dev->input pointer
- * after calling this function.
  */
 void input_unregister_polled_device(struct input_polled_dev *dev)
 {
+	sysfs_remove_group(&dev->input->dev.kobj,
+			   &input_polldev_attribute_group);
+
 	input_unregister_device(dev->input);
-	dev->input = NULL;
 }
 EXPORT_SYMBOL(input_unregister_polled_device);
 
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 2266ecb..5c16001 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -1658,6 +1658,38 @@
 EXPORT_SYMBOL(input_unregister_handler);
 
 /**
+ * input_handler_for_each_handle - handle iterator
+ * @handler: input handler to iterate
+ * @data: data for the callback
+ * @fn: function to be called for each handle
+ *
+ * Iterate over @bus's list of devices, and call @fn for each, passing
+ * it @data and stop when @fn returns a non-zero value. The function is
+ * using RCU to traverse the list and therefore may be usind in atonic
+ * contexts. The @fn callback is invoked from RCU critical section and
+ * thus must not sleep.
+ */
+int input_handler_for_each_handle(struct input_handler *handler, void *data,
+				  int (*fn)(struct input_handle *, void *))
+{
+	struct input_handle *handle;
+	int retval = 0;
+
+	rcu_read_lock();
+
+	list_for_each_entry_rcu(handle, &handler->h_list, h_node) {
+		retval = fn(handle, data);
+		if (retval)
+			break;
+	}
+
+	rcu_read_unlock();
+
+	return retval;
+}
+EXPORT_SYMBOL(input_handler_for_each_handle);
+
+/**
  * input_register_handle - register a new input handle
  * @handle: handle to register
  *
@@ -1690,7 +1722,7 @@
 	 * we can't be racing with input_unregister_handle()
 	 * and so separate lock is not needed here.
 	 */
-	list_add_tail(&handle->h_node, &handler->h_list);
+	list_add_tail_rcu(&handle->h_node, &handler->h_list);
 
 	if (handler->start)
 		handler->start(handle);
@@ -1713,7 +1745,7 @@
 {
 	struct input_dev *dev = handle->dev;
 
-	list_del_init(&handle->h_node);
+	list_del_rcu(&handle->h_node);
 
 	/*
 	 * Take dev->mutex to prevent race with input_release_device().
@@ -1721,6 +1753,7 @@
 	mutex_lock(&dev->mutex);
 	list_del_rcu(&handle->d_node);
 	mutex_unlock(&dev->mutex);
+
 	synchronize_rcu();
 }
 EXPORT_SYMBOL(input_unregister_handle);
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 79e3edc..482cb12 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -125,6 +125,7 @@
 	{ 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
 	{ 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
 	{ 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
+	{ 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
 	{ 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
 	{ 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
 	{ 0x0c12, 0x880a, "Pelican Eclipse PL-2023", MAP_DPAD_TO_AXES, XTYPE_XBOX },
@@ -146,6 +147,7 @@
 	{ 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
 	{ 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
 	{ 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
+	{ 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
 	{ 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
 	{ 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_UNKNOWN }
 };
@@ -212,6 +214,7 @@
 	XPAD_XBOX360_VENDOR(0x1430),		/* RedOctane X-Box 360 controllers */
 	XPAD_XBOX360_VENDOR(0x146b),		/* BigBen Interactive Controllers */
 	XPAD_XBOX360_VENDOR(0x1bad),		/* Rock Band Drums */
+	XPAD_XBOX360_VENDOR(0x0f0d),            /* Hori Controllers */
 	{ }
 };
 
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index ee98b1b..203b88a 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -361,6 +361,16 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called sh_keysc.
 
+config KEYBOARD_DAVINCI
+	tristate "TI DaVinci Key Scan"
+	depends on ARCH_DAVINCI_DM365
+	help
+	  Say Y to enable keypad module support for the TI DaVinci
+	  platforms (DM365).
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called davinci_keyscan.
+
 config KEYBOARD_OMAP
 	tristate "TI OMAP keypad support"
 	depends on (ARCH_OMAP1 || ARCH_OMAP2)
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index babad5e..68c0172 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -11,6 +11,7 @@
 obj-$(CONFIG_KEYBOARD_ATKBD)		+= atkbd.o
 obj-$(CONFIG_KEYBOARD_BFIN)		+= bf54x-keys.o
 obj-$(CONFIG_KEYBOARD_CORGI)		+= corgikbd.o
+obj-$(CONFIG_KEYBOARD_DAVINCI)		+= davinci_keyscan.o
 obj-$(CONFIG_KEYBOARD_EP93XX)		+= ep93xx_keypad.o
 obj-$(CONFIG_KEYBOARD_GPIO)		+= gpio_keys.o
 obj-$(CONFIG_KEYBOARD_HIL)		+= hil_kbd.o
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 28e6110..a357357 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -1567,9 +1567,8 @@
 	return 0;
 }
 
-static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
+static const struct dmi_system_id atkbd_dmi_quirk_table[] __initconst = {
 	{
-		.ident = "Dell Laptop",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
@@ -1578,7 +1577,6 @@
 		.driver_data = atkbd_dell_laptop_forced_release_keys,
 	},
 	{
-		.ident = "Dell Laptop",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
 			DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
@@ -1587,7 +1585,6 @@
 		.driver_data = atkbd_dell_laptop_forced_release_keys,
 	},
 	{
-		.ident = "HP 2133",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"),
@@ -1596,7 +1593,6 @@
 		.driver_data = atkbd_hp_forced_release_keys,
 	},
 	{
-		.ident = "HP Pavilion ZV6100",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"),
@@ -1605,7 +1601,6 @@
 		.driver_data = atkbd_volume_forced_release_keys,
 	},
 	{
-		.ident = "HP Presario R4000",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4000"),
@@ -1614,7 +1609,6 @@
 		.driver_data = atkbd_volume_forced_release_keys,
 	},
 	{
-		.ident = "HP Presario R4100",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4100"),
@@ -1623,7 +1617,6 @@
 		.driver_data = atkbd_volume_forced_release_keys,
 	},
 	{
-		.ident = "HP Presario R4200",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4200"),
@@ -1632,7 +1625,7 @@
 		.driver_data = atkbd_volume_forced_release_keys,
 	},
 	{
-		.ident = "Inventec Symphony",
+		/* Inventec Symphony */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"),
@@ -1641,7 +1634,7 @@
 		.driver_data = atkbd_volume_forced_release_keys,
 	},
 	{
-		.ident = "Samsung NC10",
+		/* Samsung NC10 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "NC10"),
@@ -1650,7 +1643,7 @@
 		.driver_data = atkbd_samsung_forced_release_keys,
 	},
 	{
-		.ident = "Samsung NC20",
+		/* Samsung NC20 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "NC20"),
@@ -1659,7 +1652,7 @@
 		.driver_data = atkbd_samsung_forced_release_keys,
 	},
 	{
-		.ident = "Samsung SQ45S70S",
+		/* Samsung SQ45S70S */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"),
@@ -1668,7 +1661,7 @@
 		.driver_data = atkbd_samsung_forced_release_keys,
 	},
 	{
-		.ident = "Fujitsu Amilo PA 1510",
+		/* Fujitsu Amilo PA 1510 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"),
@@ -1677,7 +1670,7 @@
 		.driver_data = atkbd_volume_forced_release_keys,
 	},
 	{
-		.ident = "Fujitsu Amilo Pi 3525",
+		/* Fujitsu Amilo Pi 3525 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 3525"),
@@ -1686,7 +1679,7 @@
 		.driver_data = atkbd_amilo_pi3525_forced_release_keys,
 	},
 	{
-		.ident = "Fujitsu Amilo Xi 3650",
+		/* Fujitsu Amilo Xi 3650 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 3650"),
@@ -1695,7 +1688,6 @@
 		.driver_data = atkbd_amilo_xi3650_forced_release_keys,
 	},
 	{
-		.ident = "Soltech Corporation TA12",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Soltech Corporation"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TA12"),
@@ -1704,7 +1696,7 @@
 		.driver_data = atkdb_soltech_ta12_forced_release_keys,
 	},
 	{
-		.ident = "OQO Model 01+",
+		/* OQO Model 01+ */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "OQO"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"),
diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c
new file mode 100644
index 0000000..6e52d85
--- /dev/null
+++ b/drivers/input/keyboard/davinci_keyscan.c
@@ -0,0 +1,337 @@
+/*
+ * DaVinci Key Scan Driver for TI platforms
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc
+ *
+ * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com>
+ *
+ * Intial Code: Sandeep Paulraj <s-paulraj@ti.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+
+#include <asm/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/keyscan.h>
+
+/* Key scan registers */
+#define DAVINCI_KEYSCAN_KEYCTRL		0x0000
+#define DAVINCI_KEYSCAN_INTENA		0x0004
+#define DAVINCI_KEYSCAN_INTFLAG		0x0008
+#define DAVINCI_KEYSCAN_INTCLR		0x000c
+#define DAVINCI_KEYSCAN_STRBWIDTH	0x0010
+#define DAVINCI_KEYSCAN_INTERVAL	0x0014
+#define DAVINCI_KEYSCAN_CONTTIME	0x0018
+#define DAVINCI_KEYSCAN_CURRENTST	0x001c
+#define DAVINCI_KEYSCAN_PREVSTATE	0x0020
+#define DAVINCI_KEYSCAN_EMUCTRL		0x0024
+#define DAVINCI_KEYSCAN_IODFTCTRL	0x002c
+
+/* Key Control Register (KEYCTRL) */
+#define DAVINCI_KEYSCAN_KEYEN		0x00000001
+#define DAVINCI_KEYSCAN_PREVMODE	0x00000002
+#define DAVINCI_KEYSCAN_CHATOFF		0x00000004
+#define DAVINCI_KEYSCAN_AUTODET		0x00000008
+#define DAVINCI_KEYSCAN_SCANMODE	0x00000010
+#define DAVINCI_KEYSCAN_OUTTYPE		0x00000020
+
+/* Masks for the interrupts */
+#define DAVINCI_KEYSCAN_INT_CONT	0x00000008
+#define DAVINCI_KEYSCAN_INT_OFF		0x00000004
+#define DAVINCI_KEYSCAN_INT_ON		0x00000002
+#define DAVINCI_KEYSCAN_INT_CHANGE	0x00000001
+#define DAVINCI_KEYSCAN_INT_ALL		0x0000000f
+
+struct davinci_ks {
+	struct input_dev		*input;
+	struct davinci_ks_platform_data	*pdata;
+	int				irq;
+	void __iomem			*base;
+	resource_size_t			pbase;
+	size_t				base_size;
+	unsigned short			keymap[];
+};
+
+/* Initializing the kp Module */
+static int __init davinci_ks_initialize(struct davinci_ks *davinci_ks)
+{
+	struct device *dev = &davinci_ks->input->dev;
+	struct davinci_ks_platform_data *pdata = davinci_ks->pdata;
+	u32 matrix_ctrl;
+
+	/* Enable all interrupts */
+	__raw_writel(DAVINCI_KEYSCAN_INT_ALL,
+		     davinci_ks->base + DAVINCI_KEYSCAN_INTENA);
+
+	/* Clear interrupts if any */
+	__raw_writel(DAVINCI_KEYSCAN_INT_ALL,
+		     davinci_ks->base + DAVINCI_KEYSCAN_INTCLR);
+
+	/* Setup the scan period = strobe + interval */
+	__raw_writel(pdata->strobe,
+		     davinci_ks->base + DAVINCI_KEYSCAN_STRBWIDTH);
+	__raw_writel(pdata->interval,
+		     davinci_ks->base + DAVINCI_KEYSCAN_INTERVAL);
+	__raw_writel(0x01,
+		     davinci_ks->base + DAVINCI_KEYSCAN_CONTTIME);
+
+	/* Define matrix type */
+	switch (pdata->matrix_type) {
+	case DAVINCI_KEYSCAN_MATRIX_4X4:
+		matrix_ctrl = 0;
+		break;
+	case DAVINCI_KEYSCAN_MATRIX_5X3:
+		matrix_ctrl = (1 << 6);
+		break;
+	default:
+		dev_err(dev->parent, "wrong matrix type\n");
+		return -EINVAL;
+	}
+
+	/* Enable key scan module and set matrix type */
+	__raw_writel(DAVINCI_KEYSCAN_AUTODET | DAVINCI_KEYSCAN_KEYEN |
+		     matrix_ctrl, davinci_ks->base + DAVINCI_KEYSCAN_KEYCTRL);
+
+	return 0;
+}
+
+static irqreturn_t davinci_ks_interrupt(int irq, void *dev_id)
+{
+	struct davinci_ks *davinci_ks = dev_id;
+	struct device *dev = &davinci_ks->input->dev;
+	unsigned short *keymap = davinci_ks->keymap;
+	int keymapsize = davinci_ks->pdata->keymapsize;
+	u32 prev_status, new_status, changed;
+	bool release;
+	int keycode = KEY_UNKNOWN;
+	int i;
+
+	/* Disable interrupt */
+	__raw_writel(0x0, davinci_ks->base + DAVINCI_KEYSCAN_INTENA);
+
+	/* Reading previous and new status of the key scan */
+	prev_status = __raw_readl(davinci_ks->base + DAVINCI_KEYSCAN_PREVSTATE);
+	new_status = __raw_readl(davinci_ks->base + DAVINCI_KEYSCAN_CURRENTST);
+
+	changed = prev_status ^ new_status;
+
+	if (changed) {
+		/*
+		 * It goes through all bits in 'changed' to ensure
+		 * that no key changes are being missed
+		 */
+		for (i = 0 ; i < keymapsize; i++) {
+			if ((changed>>i) & 0x1) {
+				keycode = keymap[i];
+				release = (new_status >> i) & 0x1;
+				dev_dbg(dev->parent, "key %d %s\n", keycode,
+					release ? "released" : "pressed");
+				input_report_key(davinci_ks->input, keycode,
+						 !release);
+				input_sync(davinci_ks->input);
+			}
+		}
+		/* Clearing interrupt */
+		__raw_writel(DAVINCI_KEYSCAN_INT_ALL,
+			     davinci_ks->base + DAVINCI_KEYSCAN_INTCLR);
+	}
+
+	/* Enable interrupts */
+	__raw_writel(0x1, davinci_ks->base + DAVINCI_KEYSCAN_INTENA);
+
+	return IRQ_HANDLED;
+}
+
+static int __init davinci_ks_probe(struct platform_device *pdev)
+{
+	struct davinci_ks *davinci_ks;
+	struct input_dev *key_dev;
+	struct resource *res, *mem;
+	struct device *dev = &pdev->dev;
+	struct davinci_ks_platform_data *pdata = pdev->dev.platform_data;
+	int error, i;
+
+	if (!pdata->keymap) {
+		dev_dbg(dev, "no keymap from pdata\n");
+		return -EINVAL;
+	}
+
+	davinci_ks = kzalloc(sizeof(struct davinci_ks) +
+		sizeof(unsigned short) * pdata->keymapsize, GFP_KERNEL);
+	if (!davinci_ks) {
+		dev_dbg(dev, "could not allocate memory for private data\n");
+		return -ENOMEM;
+	}
+
+	memcpy(davinci_ks->keymap, pdata->keymap,
+		sizeof(unsigned short) * pdata->keymapsize);
+
+	key_dev = input_allocate_device();
+	if (!key_dev) {
+		dev_dbg(dev, "could not allocate input device\n");
+		error = -ENOMEM;
+		goto fail1;
+	}
+
+	davinci_ks->input = key_dev;
+
+	davinci_ks->irq = platform_get_irq(pdev, 0);
+	if (davinci_ks->irq < 0) {
+		dev_err(dev, "no key scan irq\n");
+		error = davinci_ks->irq;
+		goto fail2;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "no mem resource\n");
+		error = -EINVAL;
+		goto fail2;
+	}
+
+	davinci_ks->pbase = res->start;
+	davinci_ks->base_size = resource_size(res);
+
+	mem = request_mem_region(davinci_ks->pbase, davinci_ks->base_size,
+				 pdev->name);
+	if (!mem) {
+		dev_err(dev, "key scan registers at %08x are not free\n",
+			davinci_ks->pbase);
+		error = -EBUSY;
+		goto fail2;
+	}
+
+	davinci_ks->base = ioremap(davinci_ks->pbase, davinci_ks->base_size);
+	if (!davinci_ks->base) {
+		dev_err(dev, "can't ioremap MEM resource.\n");
+		error = -ENOMEM;
+		goto fail3;
+	}
+
+	/* Enable auto repeat feature of Linux input subsystem */
+	if (pdata->rep)
+		__set_bit(EV_REP, key_dev->evbit);
+
+	/* Setup input device */
+	__set_bit(EV_KEY, key_dev->evbit);
+
+	/* Setup the platform data */
+	davinci_ks->pdata = pdata;
+
+	for (i = 0; i < davinci_ks->pdata->keymapsize; i++)
+		__set_bit(davinci_ks->pdata->keymap[i], key_dev->keybit);
+
+	key_dev->name = "davinci_keyscan";
+	key_dev->phys = "davinci_keyscan/input0";
+	key_dev->dev.parent = &pdev->dev;
+	key_dev->id.bustype = BUS_HOST;
+	key_dev->id.vendor = 0x0001;
+	key_dev->id.product = 0x0001;
+	key_dev->id.version = 0x0001;
+	key_dev->keycode = davinci_ks->keymap;
+	key_dev->keycodesize = sizeof(davinci_ks->keymap[0]);
+	key_dev->keycodemax = davinci_ks->pdata->keymapsize;
+
+	error = input_register_device(davinci_ks->input);
+	if (error < 0) {
+		dev_err(dev, "unable to register davinci key scan device\n");
+		goto fail4;
+	}
+
+	error = request_irq(davinci_ks->irq, davinci_ks_interrupt,
+			  IRQF_DISABLED, pdev->name, davinci_ks);
+	if (error < 0) {
+		dev_err(dev, "unable to register davinci key scan interrupt\n");
+		goto fail5;
+	}
+
+	error = davinci_ks_initialize(davinci_ks);
+	if (error < 0) {
+		dev_err(dev, "unable to initialize davinci key scan device\n");
+		goto fail6;
+	}
+
+	platform_set_drvdata(pdev, davinci_ks);
+	return 0;
+
+fail6:
+	free_irq(davinci_ks->irq, davinci_ks);
+fail5:
+	input_unregister_device(davinci_ks->input);
+	key_dev = NULL;
+fail4:
+	iounmap(davinci_ks->base);
+fail3:
+	release_mem_region(davinci_ks->pbase, davinci_ks->base_size);
+fail2:
+	input_free_device(key_dev);
+fail1:
+	kfree(davinci_ks);
+
+	return error;
+}
+
+static int __devexit davinci_ks_remove(struct platform_device *pdev)
+{
+	struct davinci_ks *davinci_ks = platform_get_drvdata(pdev);
+
+	free_irq(davinci_ks->irq, davinci_ks);
+
+	input_unregister_device(davinci_ks->input);
+
+	iounmap(davinci_ks->base);
+	release_mem_region(davinci_ks->pbase, davinci_ks->base_size);
+
+	platform_set_drvdata(pdev, NULL);
+
+	kfree(davinci_ks);
+
+	return 0;
+}
+
+static struct platform_driver davinci_ks_driver = {
+	.driver	= {
+		.name = "davinci_keyscan",
+		.owner = THIS_MODULE,
+	},
+	.remove	= __devexit_p(davinci_ks_remove),
+};
+
+static int __init davinci_ks_init(void)
+{
+	return platform_driver_probe(&davinci_ks_driver, davinci_ks_probe);
+}
+module_init(davinci_ks_init);
+
+static void __exit davinci_ks_exit(void)
+{
+	platform_driver_unregister(&davinci_ks_driver);
+}
+module_exit(davinci_ks_exit);
+
+MODULE_AUTHOR("Miguel Aguilar");
+MODULE_DESCRIPTION("Texas Instruments DaVinci Key Scan Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index 77d1309..1aff3b7 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -23,8 +23,7 @@
 #include <linux/input.h>
 #include <linux/gpio_keys.h>
 #include <linux/workqueue.h>
-
-#include <asm/gpio.h>
+#include <linux/gpio.h>
 
 struct gpio_button_data {
 	struct gpio_keys_button *button;
@@ -38,10 +37,8 @@
 	struct gpio_button_data data[0];
 };
 
-static void gpio_keys_report_event(struct work_struct *work)
+static void gpio_keys_report_event(struct gpio_button_data *bdata)
 {
-	struct gpio_button_data *bdata =
-		container_of(work, struct gpio_button_data, work);
 	struct gpio_keys_button *button = bdata->button;
 	struct input_dev *input = bdata->input;
 	unsigned int type = button->type ?: EV_KEY;
@@ -51,6 +48,14 @@
 	input_sync(input);
 }
 
+static void gpio_keys_work_func(struct work_struct *work)
+{
+	struct gpio_button_data *bdata =
+		container_of(work, struct gpio_button_data, work);
+
+	gpio_keys_report_event(bdata);
+}
+
 static void gpio_keys_timer(unsigned long _data)
 {
 	struct gpio_button_data *data = (struct gpio_button_data *)_data;
@@ -74,10 +79,62 @@
 	return IRQ_HANDLED;
 }
 
+static int __devinit gpio_keys_setup_key(struct device *dev,
+					 struct gpio_button_data *bdata,
+					 struct gpio_keys_button *button)
+{
+	char *desc = button->desc ? button->desc : "gpio_keys";
+	int irq, error;
+
+	setup_timer(&bdata->timer, gpio_keys_timer, (unsigned long)bdata);
+	INIT_WORK(&bdata->work, gpio_keys_work_func);
+
+	error = gpio_request(button->gpio, desc);
+	if (error < 0) {
+		dev_err(dev, "failed to request GPIO %d, error %d\n",
+			button->gpio, error);
+		goto fail2;
+	}
+
+	error = gpio_direction_input(button->gpio);
+	if (error < 0) {
+		dev_err(dev, "failed to configure"
+			" direction for GPIO %d, error %d\n",
+			button->gpio, error);
+		goto fail3;
+	}
+
+	irq = gpio_to_irq(button->gpio);
+	if (irq < 0) {
+		error = irq;
+		dev_err(dev, "Unable to get irq number for GPIO %d, error %d\n",
+			button->gpio, error);
+		goto fail3;
+	}
+
+	error = request_irq(irq, gpio_keys_isr,
+			    IRQF_SHARED |
+			    IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+			    desc, bdata);
+	if (error) {
+		dev_err(dev, "Unable to claim irq %d; error %d\n",
+			irq, error);
+		goto fail3;
+	}
+
+	return 0;
+
+fail3:
+	gpio_free(button->gpio);
+fail2:
+	return error;
+}
+
 static int __devinit gpio_keys_probe(struct platform_device *pdev)
 {
 	struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
 	struct gpio_keys_drvdata *ddata;
+	struct device *dev = &pdev->dev;
 	struct input_dev *input;
 	int i, error;
 	int wakeup = 0;
@@ -87,6 +144,7 @@
 			GFP_KERNEL);
 	input = input_allocate_device();
 	if (!ddata || !input) {
+		dev_err(dev, "failed to allocate state\n");
 		error = -ENOMEM;
 		goto fail1;
 	}
@@ -111,52 +169,14 @@
 	for (i = 0; i < pdata->nbuttons; i++) {
 		struct gpio_keys_button *button = &pdata->buttons[i];
 		struct gpio_button_data *bdata = &ddata->data[i];
-		int irq;
 		unsigned int type = button->type ?: EV_KEY;
 
 		bdata->input = input;
 		bdata->button = button;
-		setup_timer(&bdata->timer,
-			    gpio_keys_timer, (unsigned long)bdata);
-		INIT_WORK(&bdata->work, gpio_keys_report_event);
 
-		error = gpio_request(button->gpio, button->desc ?: "gpio_keys");
-		if (error < 0) {
-			pr_err("gpio-keys: failed to request GPIO %d,"
-				" error %d\n", button->gpio, error);
+		error = gpio_keys_setup_key(dev, bdata, button);
+		if (error)
 			goto fail2;
-		}
-
-		error = gpio_direction_input(button->gpio);
-		if (error < 0) {
-			pr_err("gpio-keys: failed to configure input"
-				" direction for GPIO %d, error %d\n",
-				button->gpio, error);
-			gpio_free(button->gpio);
-			goto fail2;
-		}
-
-		irq = gpio_to_irq(button->gpio);
-		if (irq < 0) {
-			error = irq;
-			pr_err("gpio-keys: Unable to get irq number"
-				" for GPIO %d, error %d\n",
-				button->gpio, error);
-			gpio_free(button->gpio);
-			goto fail2;
-		}
-
-		error = request_irq(irq, gpio_keys_isr,
-				    IRQF_SHARED |
-				    IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-				    button->desc ? button->desc : "gpio_keys",
-				    bdata);
-		if (error) {
-			pr_err("gpio-keys: Unable to claim irq %d; error %d\n",
-				irq, error);
-			gpio_free(button->gpio);
-			goto fail2;
-		}
 
 		if (button->wakeup)
 			wakeup = 1;
@@ -166,11 +186,16 @@
 
 	error = input_register_device(input);
 	if (error) {
-		pr_err("gpio-keys: Unable to register input device, "
+		dev_err(dev, "Unable to register input device, "
 			"error: %d\n", error);
 		goto fail2;
 	}
 
+	/* get current state of buttons */
+	for (i = 0; i < pdata->nbuttons; i++)
+		gpio_keys_report_event(&ddata->data[i]);
+	input_sync(input);
+
 	device_init_wakeup(&pdev->dev, wakeup);
 
 	return 0;
@@ -239,18 +264,21 @@
 static int gpio_keys_resume(struct device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev);
+	struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev);
 	struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
 	int i;
 
-	if (device_may_wakeup(&pdev->dev)) {
-		for (i = 0; i < pdata->nbuttons; i++) {
-			struct gpio_keys_button *button = &pdata->buttons[i];
-			if (button->wakeup) {
-				int irq = gpio_to_irq(button->gpio);
-				disable_irq_wake(irq);
-			}
+	for (i = 0; i < pdata->nbuttons; i++) {
+
+		struct gpio_keys_button *button = &pdata->buttons[i];
+		if (button->wakeup && device_may_wakeup(&pdev->dev)) {
+			int irq = gpio_to_irq(button->gpio);
+			disable_irq_wake(irq);
 		}
+
+		gpio_keys_report_event(&ddata->data[i]);
 	}
+	input_sync(ddata->input);
 
 	return 0;
 }
diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c
index f9847e0..fa9bb6d 100644
--- a/drivers/input/keyboard/lkkbd.c
+++ b/drivers/input/keyboard/lkkbd.c
@@ -72,9 +72,9 @@
 
 #define DRIVER_DESC	"LK keyboard driver"
 
-MODULE_AUTHOR ("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
-MODULE_DESCRIPTION (DRIVER_DESC);
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
 
 /*
  * Known parameters:
@@ -85,27 +85,27 @@
  * Please notice that there's not yet an API to set these at runtime.
  */
 static int bell_volume = 100; /* % */
-module_param (bell_volume, int, 0);
-MODULE_PARM_DESC (bell_volume, "Bell volume (in %). default is 100%");
+module_param(bell_volume, int, 0);
+MODULE_PARM_DESC(bell_volume, "Bell volume (in %). default is 100%");
 
 static int keyclick_volume = 100; /* % */
-module_param (keyclick_volume, int, 0);
-MODULE_PARM_DESC (keyclick_volume, "Keyclick volume (in %), default is 100%");
+module_param(keyclick_volume, int, 0);
+MODULE_PARM_DESC(keyclick_volume, "Keyclick volume (in %), default is 100%");
 
 static int ctrlclick_volume = 100; /* % */
-module_param (ctrlclick_volume, int, 0);
-MODULE_PARM_DESC (ctrlclick_volume, "Ctrlclick volume (in %), default is 100%");
+module_param(ctrlclick_volume, int, 0);
+MODULE_PARM_DESC(ctrlclick_volume, "Ctrlclick volume (in %), default is 100%");
 
 static int lk201_compose_is_alt;
-module_param (lk201_compose_is_alt, int, 0);
-MODULE_PARM_DESC (lk201_compose_is_alt, "If set non-zero, LK201' Compose key "
-		"will act as an Alt key");
+module_param(lk201_compose_is_alt, int, 0);
+MODULE_PARM_DESC(lk201_compose_is_alt,
+		 "If set non-zero, LK201' Compose key will act as an Alt key");
 
 
 
 #undef LKKBD_DEBUG
 #ifdef LKKBD_DEBUG
-#define DBG(x...) printk (x)
+#define DBG(x...) printk(x)
 #else
 #define DBG(x...) do {} while (0)
 #endif
@@ -122,7 +122,7 @@
 #define LK_MODE_DOWN		0x80
 #define LK_MODE_AUTODOWN	0x82
 #define LK_MODE_UPDOWN		0x86
-#define LK_CMD_SET_MODE(mode,div)	((mode) | ((div) << 3))
+#define LK_CMD_SET_MODE(mode, div)	((mode) | ((div) << 3))
 
 /* Misc commands */
 #define LK_CMD_ENABLE_KEYCLICK	0x1b
@@ -152,11 +152,8 @@
 
 #define LK_NUM_KEYCODES		256
 #define LK_NUM_IGNORE_BYTES	6
-typedef u_int16_t lk_keycode_t;
 
-
-
-static lk_keycode_t lkkbd_keycode[LK_NUM_KEYCODES] = {
+static unsigned short lkkbd_keycode[LK_NUM_KEYCODES] = {
 	[0x56] = KEY_F1,
 	[0x57] = KEY_F2,
 	[0x58] = KEY_F3,
@@ -268,7 +265,7 @@
 };
 
 #define CHECK_LED(LK, VAR_ON, VAR_OFF, LED, BITS) do {		\
-	if (test_bit (LED, (LK)->dev->led))			\
+	if (test_bit(LED, (LK)->dev->led))			\
 		VAR_ON |= BITS;					\
 	else							\
 		VAR_OFF |= BITS;				\
@@ -278,7 +275,7 @@
  * Per-keyboard data
  */
 struct lkkbd {
-	lk_keycode_t keycode[LK_NUM_KEYCODES];
+	unsigned short keycode[LK_NUM_KEYCODES];
 	int ignore_bytes;
 	unsigned char id[LK_NUM_IGNORE_BYTES];
 	struct input_dev *dev;
@@ -301,26 +298,25 @@
 	unsigned char *name;
 } lk_response[] = {
 #define RESPONSE(x) { .value = (x), .name = #x, }
-	RESPONSE (LK_STUCK_KEY),
-	RESPONSE (LK_SELFTEST_FAILED),
-	RESPONSE (LK_ALL_KEYS_UP),
-	RESPONSE (LK_METRONOME),
-	RESPONSE (LK_OUTPUT_ERROR),
-	RESPONSE (LK_INPUT_ERROR),
-	RESPONSE (LK_KBD_LOCKED),
-	RESPONSE (LK_KBD_TEST_MODE_ACK),
-	RESPONSE (LK_PREFIX_KEY_DOWN),
-	RESPONSE (LK_MODE_CHANGE_ACK),
-	RESPONSE (LK_RESPONSE_RESERVED),
+	RESPONSE(LK_STUCK_KEY),
+	RESPONSE(LK_SELFTEST_FAILED),
+	RESPONSE(LK_ALL_KEYS_UP),
+	RESPONSE(LK_METRONOME),
+	RESPONSE(LK_OUTPUT_ERROR),
+	RESPONSE(LK_INPUT_ERROR),
+	RESPONSE(LK_KBD_LOCKED),
+	RESPONSE(LK_KBD_TEST_MODE_ACK),
+	RESPONSE(LK_PREFIX_KEY_DOWN),
+	RESPONSE(LK_MODE_CHANGE_ACK),
+	RESPONSE(LK_RESPONSE_RESERVED),
 #undef RESPONSE
 };
 
-static unsigned char *
-response_name (unsigned char value)
+static unsigned char *response_name(unsigned char value)
 {
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE (lk_response); i++)
+	for (i = 0; i < ARRAY_SIZE(lk_response); i++)
 		if (lk_response[i].value == value)
 			return lk_response[i].name;
 
@@ -331,8 +327,7 @@
 /*
  * Calculate volume parameter byte for a given volume.
  */
-static unsigned char
-volume_to_hw (int volume_percent)
+static unsigned char volume_to_hw(int volume_percent)
 {
 	unsigned char ret = 0;
 
@@ -363,8 +358,7 @@
 	return ret;
 }
 
-static void
-lkkbd_detection_done (struct lkkbd *lk)
+static void lkkbd_detection_done(struct lkkbd *lk)
 {
 	int i;
 
@@ -377,190 +371,202 @@
 	 * Print keyboard name and modify Compose=Alt on user's request.
 	 */
 	switch (lk->id[4]) {
-		case 1:
-			strlcpy (lk->name, "DEC LK201 keyboard",
-				 sizeof (lk->name));
+	case 1:
+		strlcpy(lk->name, "DEC LK201 keyboard", sizeof(lk->name));
 
-			if (lk201_compose_is_alt)
-				lk->keycode[0xb1] = KEY_LEFTALT;
-			break;
+		if (lk201_compose_is_alt)
+			lk->keycode[0xb1] = KEY_LEFTALT;
+		break;
 
-		case 2:
-			strlcpy (lk->name, "DEC LK401 keyboard",
-				 sizeof (lk->name));
-			break;
+	case 2:
+		strlcpy(lk->name, "DEC LK401 keyboard", sizeof(lk->name));
+		break;
 
-		default:
-			strlcpy (lk->name, "Unknown DEC keyboard",
-				 sizeof (lk->name));
-			printk (KERN_ERR "lkkbd: keyboard on %s is unknown, "
-					"please report to Jan-Benedict Glaw "
-					"<jbglaw@lug-owl.de>\n", lk->phys);
-			printk (KERN_ERR "lkkbd: keyboard ID'ed as:");
-			for (i = 0; i < LK_NUM_IGNORE_BYTES; i++)
-				printk (" 0x%02x", lk->id[i]);
-			printk ("\n");
-			break;
+	default:
+		strlcpy(lk->name, "Unknown DEC keyboard", sizeof(lk->name));
+		printk(KERN_ERR
+			"lkkbd: keyboard on %s is unknown, please report to "
+			"Jan-Benedict Glaw <jbglaw@lug-owl.de>\n", lk->phys);
+		printk(KERN_ERR "lkkbd: keyboard ID'ed as:");
+		for (i = 0; i < LK_NUM_IGNORE_BYTES; i++)
+			printk(" 0x%02x", lk->id[i]);
+		printk("\n");
+		break;
 	}
-	printk (KERN_INFO "lkkbd: keyboard on %s identified as: %s\n",
-			lk->phys, lk->name);
+
+	printk(KERN_INFO "lkkbd: keyboard on %s identified as: %s\n",
+		lk->phys, lk->name);
 
 	/*
 	 * Report errors during keyboard boot-up.
 	 */
 	switch (lk->id[2]) {
-		case 0x00:
-			/* All okay */
-			break;
+	case 0x00:
+		/* All okay */
+		break;
 
-		case LK_STUCK_KEY:
-			printk (KERN_ERR "lkkbd: Stuck key on keyboard at "
-					"%s\n", lk->phys);
-			break;
+	case LK_STUCK_KEY:
+		printk(KERN_ERR "lkkbd: Stuck key on keyboard at %s\n",
+			lk->phys);
+		break;
 
-		case LK_SELFTEST_FAILED:
-			printk (KERN_ERR "lkkbd: Selftest failed on keyboard "
-					"at %s, keyboard may not work "
-					"properly\n", lk->phys);
-			break;
+	case LK_SELFTEST_FAILED:
+		printk(KERN_ERR
+			"lkkbd: Selftest failed on keyboard at %s, "
+			"keyboard may not work properly\n", lk->phys);
+		break;
 
-		default:
-			printk (KERN_ERR "lkkbd: Unknown error %02x on "
-					"keyboard at %s\n", lk->id[2],
-					lk->phys);
-			break;
+	default:
+		printk(KERN_ERR
+			"lkkbd: Unknown error %02x on keyboard at %s\n",
+			lk->id[2], lk->phys);
+		break;
 	}
 
 	/*
 	 * Try to hint user if there's a stuck key.
 	 */
 	if (lk->id[2] == LK_STUCK_KEY && lk->id[3] != 0)
-		printk (KERN_ERR "Scancode of stuck key is 0x%02x, keycode "
-				"is 0x%04x\n", lk->id[3],
-				lk->keycode[lk->id[3]]);
-
-	return;
+		printk(KERN_ERR
+			"Scancode of stuck key is 0x%02x, keycode is 0x%04x\n",
+			lk->id[3], lk->keycode[lk->id[3]]);
 }
 
 /*
  * lkkbd_interrupt() is called by the low level driver when a character
  * is received.
  */
-static irqreturn_t
-lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags)
+static irqreturn_t lkkbd_interrupt(struct serio *serio,
+				   unsigned char data, unsigned int flags)
 {
-	struct lkkbd *lk = serio_get_drvdata (serio);
+	struct lkkbd *lk = serio_get_drvdata(serio);
+	struct input_dev *input_dev = lk->dev;
+	unsigned int keycode;
 	int i;
 
-	DBG (KERN_INFO "Got byte 0x%02x\n", data);
+	DBG(KERN_INFO "Got byte 0x%02x\n", data);
 
 	if (lk->ignore_bytes > 0) {
-		DBG (KERN_INFO "Ignoring a byte on %s\n", lk->name);
+		DBG(KERN_INFO "Ignoring a byte on %s\n", lk->name);
 		lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data;
 
 		if (lk->ignore_bytes == 0)
-			lkkbd_detection_done (lk);
+			lkkbd_detection_done(lk);
 
 		return IRQ_HANDLED;
 	}
 
 	switch (data) {
-		case LK_ALL_KEYS_UP:
-			for (i = 0; i < ARRAY_SIZE (lkkbd_keycode); i++)
-				if (lk->keycode[i] != KEY_RESERVED)
-					input_report_key (lk->dev, lk->keycode[i], 0);
-			input_sync (lk->dev);
-			break;
+	case LK_ALL_KEYS_UP:
+		for (i = 0; i < ARRAY_SIZE(lkkbd_keycode); i++)
+			input_report_key(input_dev, lk->keycode[i], 0);
+		input_sync(input_dev);
+		break;
 
-		case 0x01:
-			DBG (KERN_INFO "Got 0x01, scheduling re-initialization\n");
-			lk->ignore_bytes = LK_NUM_IGNORE_BYTES;
-			lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data;
-			schedule_work (&lk->tq);
-			break;
+	case 0x01:
+		DBG(KERN_INFO "Got 0x01, scheduling re-initialization\n");
+		lk->ignore_bytes = LK_NUM_IGNORE_BYTES;
+		lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data;
+		schedule_work(&lk->tq);
+		break;
 
-		case LK_METRONOME:
-		case LK_OUTPUT_ERROR:
-		case LK_INPUT_ERROR:
-		case LK_KBD_LOCKED:
-		case LK_KBD_TEST_MODE_ACK:
-		case LK_PREFIX_KEY_DOWN:
-		case LK_MODE_CHANGE_ACK:
-		case LK_RESPONSE_RESERVED:
-			DBG (KERN_INFO "Got %s and don't know how to handle...\n",
-					response_name (data));
-			break;
+	case LK_METRONOME:
+	case LK_OUTPUT_ERROR:
+	case LK_INPUT_ERROR:
+	case LK_KBD_LOCKED:
+	case LK_KBD_TEST_MODE_ACK:
+	case LK_PREFIX_KEY_DOWN:
+	case LK_MODE_CHANGE_ACK:
+	case LK_RESPONSE_RESERVED:
+		DBG(KERN_INFO "Got %s and don't know how to handle...\n",
+			response_name(data));
+		break;
 
-		default:
-			if (lk->keycode[data] != KEY_RESERVED) {
-				if (!test_bit (lk->keycode[data], lk->dev->key))
-					input_report_key (lk->dev, lk->keycode[data], 1);
-				else
-					input_report_key (lk->dev, lk->keycode[data], 0);
-				input_sync (lk->dev);
-                        } else
-                                printk (KERN_WARNING "%s: Unknown key with "
-						"scancode 0x%02x on %s.\n",
-						__FILE__, data, lk->name);
+	default:
+		keycode = lk->keycode[data];
+		if (keycode != KEY_RESERVED) {
+			input_report_key(input_dev, keycode,
+					 !test_bit(keycode, input_dev->key));
+			input_sync(input_dev);
+		} else {
+			printk(KERN_WARNING
+				"%s: Unknown key with scancode 0x%02x on %s.\n",
+				__FILE__, data, lk->name);
+		}
 	}
 
 	return IRQ_HANDLED;
 }
 
-/*
- * lkkbd_event() handles events from the input module.
- */
-static int
-lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code,
-		int value)
+static void lkkbd_toggle_leds(struct lkkbd *lk)
 {
-	struct lkkbd *lk = input_get_drvdata (dev);
+	struct serio *serio = lk->serio;
 	unsigned char leds_on = 0;
 	unsigned char leds_off = 0;
 
+	CHECK_LED(lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK);
+	CHECK_LED(lk, leds_on, leds_off, LED_COMPOSE, LK_LED_COMPOSE);
+	CHECK_LED(lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK);
+	CHECK_LED(lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT);
+	if (leds_on != 0) {
+		serio_write(serio, LK_CMD_LED_ON);
+		serio_write(serio, leds_on);
+	}
+	if (leds_off != 0) {
+		serio_write(serio, LK_CMD_LED_OFF);
+		serio_write(serio, leds_off);
+	}
+}
+
+static void lkkbd_toggle_keyclick(struct lkkbd *lk, bool on)
+{
+	struct serio *serio = lk->serio;
+
+	if (on) {
+		DBG("%s: Activating key clicks\n", __func__);
+		serio_write(serio, LK_CMD_ENABLE_KEYCLICK);
+		serio_write(serio, volume_to_hw(lk->keyclick_volume));
+		serio_write(serio, LK_CMD_ENABLE_CTRCLICK);
+		serio_write(serio, volume_to_hw(lk->ctrlclick_volume));
+	} else {
+		DBG("%s: Deactivating key clicks\n", __func__);
+		serio_write(serio, LK_CMD_DISABLE_KEYCLICK);
+		serio_write(serio, LK_CMD_DISABLE_CTRCLICK);
+	}
+
+}
+
+/*
+ * lkkbd_event() handles events from the input module.
+ */
+static int lkkbd_event(struct input_dev *dev,
+			unsigned int type, unsigned int code, int value)
+{
+	struct lkkbd *lk = input_get_drvdata(dev);
+
 	switch (type) {
-		case EV_LED:
-			CHECK_LED (lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK);
-			CHECK_LED (lk, leds_on, leds_off, LED_COMPOSE, LK_LED_COMPOSE);
-			CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK);
-			CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT);
-			if (leds_on != 0) {
-				serio_write (lk->serio, LK_CMD_LED_ON);
-				serio_write (lk->serio, leds_on);
-			}
-			if (leds_off != 0) {
-				serio_write (lk->serio, LK_CMD_LED_OFF);
-				serio_write (lk->serio, leds_off);
-			}
+	case EV_LED:
+		lkkbd_toggle_leds(lk);
+		return 0;
+
+	case EV_SND:
+		switch (code) {
+		case SND_CLICK:
+			lkkbd_toggle_keyclick(lk, value);
 			return 0;
 
-		case EV_SND:
-			switch (code) {
-				case SND_CLICK:
-					if (value == 0) {
-						DBG ("%s: Deactivating key clicks\n", __func__);
-						serio_write (lk->serio, LK_CMD_DISABLE_KEYCLICK);
-						serio_write (lk->serio, LK_CMD_DISABLE_CTRCLICK);
-					} else {
-						DBG ("%s: Activating key clicks\n", __func__);
-						serio_write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
-						serio_write (lk->serio, volume_to_hw (lk->keyclick_volume));
-						serio_write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
-						serio_write (lk->serio, volume_to_hw (lk->ctrlclick_volume));
-					}
-					return 0;
+		case SND_BELL:
+			if (value != 0)
+				serio_write(lk->serio, LK_CMD_SOUND_BELL);
 
-				case SND_BELL:
-					if (value != 0)
-						serio_write (lk->serio, LK_CMD_SOUND_BELL);
+			return 0;
+		}
 
-					return 0;
-			}
-			break;
+		break;
 
-		default:
-			printk (KERN_ERR "%s (): Got unknown type %d, code %d, value %d\n",
-					__func__, type, code, value);
+	default:
+		printk(KERN_ERR "%s(): Got unknown type %d, code %d, value %d\n",
+			__func__, type, code, value);
 	}
 
 	return -1;
@@ -570,79 +576,56 @@
  * lkkbd_reinit() sets leds and beeps to a state the computer remembers they
  * were in.
  */
-static void
-lkkbd_reinit (struct work_struct *work)
+static void lkkbd_reinit(struct work_struct *work)
 {
 	struct lkkbd *lk = container_of(work, struct lkkbd, tq);
 	int division;
-	unsigned char leds_on = 0;
-	unsigned char leds_off = 0;
 
 	/* Ask for ID */
-	serio_write (lk->serio, LK_CMD_REQUEST_ID);
+	serio_write(lk->serio, LK_CMD_REQUEST_ID);
 
 	/* Reset parameters */
-	serio_write (lk->serio, LK_CMD_SET_DEFAULTS);
+	serio_write(lk->serio, LK_CMD_SET_DEFAULTS);
 
 	/* Set LEDs */
-	CHECK_LED (lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK);
-	CHECK_LED (lk, leds_on, leds_off, LED_COMPOSE, LK_LED_COMPOSE);
-	CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK);
-	CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT);
-	if (leds_on != 0) {
-		serio_write (lk->serio, LK_CMD_LED_ON);
-		serio_write (lk->serio, leds_on);
-	}
-	if (leds_off != 0) {
-		serio_write (lk->serio, LK_CMD_LED_OFF);
-		serio_write (lk->serio, leds_off);
-	}
+	lkkbd_toggle_leds(lk);
 
 	/*
 	 * Try to activate extended LK401 mode. This command will
 	 * only work with a LK401 keyboard and grants access to
 	 * LAlt, RAlt, RCompose and RShift.
 	 */
-	serio_write (lk->serio, LK_CMD_ENABLE_LK401);
+	serio_write(lk->serio, LK_CMD_ENABLE_LK401);
 
 	/* Set all keys to UPDOWN mode */
 	for (division = 1; division <= 14; division++)
-		serio_write (lk->serio, LK_CMD_SET_MODE (LK_MODE_UPDOWN,
-					division));
+		serio_write(lk->serio,
+			    LK_CMD_SET_MODE(LK_MODE_UPDOWN, division));
 
 	/* Enable bell and set volume */
-	serio_write (lk->serio, LK_CMD_ENABLE_BELL);
-	serio_write (lk->serio, volume_to_hw (lk->bell_volume));
+	serio_write(lk->serio, LK_CMD_ENABLE_BELL);
+	serio_write(lk->serio, volume_to_hw(lk->bell_volume));
 
 	/* Enable/disable keyclick (and possibly set volume) */
-	if (test_bit (SND_CLICK, lk->dev->snd)) {
-		serio_write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
-		serio_write (lk->serio, volume_to_hw (lk->keyclick_volume));
-		serio_write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
-		serio_write (lk->serio, volume_to_hw (lk->ctrlclick_volume));
-	} else {
-		serio_write (lk->serio, LK_CMD_DISABLE_KEYCLICK);
-		serio_write (lk->serio, LK_CMD_DISABLE_CTRCLICK);
-	}
+	lkkbd_toggle_keyclick(lk, test_bit(SND_CLICK, lk->dev->snd));
 
 	/* Sound the bell if needed */
-	if (test_bit (SND_BELL, lk->dev->snd))
-		serio_write (lk->serio, LK_CMD_SOUND_BELL);
+	if (test_bit(SND_BELL, lk->dev->snd))
+		serio_write(lk->serio, LK_CMD_SOUND_BELL);
 }
 
 /*
  * lkkbd_connect() probes for a LK keyboard and fills the necessary structures.
  */
-static int
-lkkbd_connect (struct serio *serio, struct serio_driver *drv)
+static int lkkbd_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct lkkbd *lk;
 	struct input_dev *input_dev;
 	int i;
 	int err;
 
-	lk = kzalloc (sizeof (struct lkkbd), GFP_KERNEL);
-	input_dev = input_allocate_device ();
+	lk = kzalloc(sizeof(struct lkkbd), GFP_KERNEL);
+	input_dev = input_allocate_device();
 	if (!lk || !input_dev) {
 		err = -ENOMEM;
 		goto fail1;
@@ -650,14 +633,14 @@
 
 	lk->serio = serio;
 	lk->dev = input_dev;
-	INIT_WORK (&lk->tq, lkkbd_reinit);
+	INIT_WORK(&lk->tq, lkkbd_reinit);
 	lk->bell_volume = bell_volume;
 	lk->keyclick_volume = keyclick_volume;
 	lk->ctrlclick_volume = ctrlclick_volume;
-	memcpy (lk->keycode, lkkbd_keycode, sizeof (lk_keycode_t) * LK_NUM_KEYCODES);
+	memcpy(lk->keycode, lkkbd_keycode, sizeof(lk->keycode));
 
-	strlcpy (lk->name, "DEC LK keyboard", sizeof(lk->name));
-	snprintf (lk->phys, sizeof(lk->phys), "%s/input0", serio->phys);
+	strlcpy(lk->name, "DEC LK keyboard", sizeof(lk->name));
+	snprintf(lk->phys, sizeof(lk->phys), "%s/input0", serio->phys);
 
 	input_dev->name = lk->name;
 	input_dev->phys = lk->phys;
@@ -668,62 +651,61 @@
 	input_dev->dev.parent = &serio->dev;
 	input_dev->event = lkkbd_event;
 
-	input_set_drvdata (input_dev, lk);
+	input_set_drvdata(input_dev, lk);
 
-	set_bit (EV_KEY, input_dev->evbit);
-	set_bit (EV_LED, input_dev->evbit);
-	set_bit (EV_SND, input_dev->evbit);
-	set_bit (EV_REP, input_dev->evbit);
-	set_bit (LED_CAPSL, input_dev->ledbit);
-	set_bit (LED_SLEEP, input_dev->ledbit);
-	set_bit (LED_COMPOSE, input_dev->ledbit);
-	set_bit (LED_SCROLLL, input_dev->ledbit);
-	set_bit (SND_BELL, input_dev->sndbit);
-	set_bit (SND_CLICK, input_dev->sndbit);
+	__set_bit(EV_KEY, input_dev->evbit);
+	__set_bit(EV_LED, input_dev->evbit);
+	__set_bit(EV_SND, input_dev->evbit);
+	__set_bit(EV_REP, input_dev->evbit);
+	__set_bit(LED_CAPSL, input_dev->ledbit);
+	__set_bit(LED_SLEEP, input_dev->ledbit);
+	__set_bit(LED_COMPOSE, input_dev->ledbit);
+	__set_bit(LED_SCROLLL, input_dev->ledbit);
+	__set_bit(SND_BELL, input_dev->sndbit);
+	__set_bit(SND_CLICK, input_dev->sndbit);
 
 	input_dev->keycode = lk->keycode;
-	input_dev->keycodesize = sizeof (lk_keycode_t);
-	input_dev->keycodemax = LK_NUM_KEYCODES;
+	input_dev->keycodesize = sizeof(lk->keycode[0]);
+	input_dev->keycodemax = ARRAY_SIZE(lk->keycode);
 
 	for (i = 0; i < LK_NUM_KEYCODES; i++)
-		__set_bit (lk->keycode[i], input_dev->keybit);
+		__set_bit(lk->keycode[i], input_dev->keybit);
 	__clear_bit(KEY_RESERVED, input_dev->keybit);
 
-	serio_set_drvdata (serio, lk);
+	serio_set_drvdata(serio, lk);
 
-	err = serio_open (serio, drv);
+	err = serio_open(serio, drv);
 	if (err)
 		goto fail2;
 
-	err = input_register_device (lk->dev);
+	err = input_register_device(lk->dev);
 	if (err)
 		goto fail3;
 
-	serio_write (lk->serio, LK_CMD_POWERCYCLE_RESET);
+	serio_write(lk->serio, LK_CMD_POWERCYCLE_RESET);
 
 	return 0;
 
- fail3:	serio_close (serio);
- fail2:	serio_set_drvdata (serio, NULL);
- fail1:	input_free_device (input_dev);
-	kfree (lk);
+ fail3:	serio_close(serio);
+ fail2:	serio_set_drvdata(serio, NULL);
+ fail1:	input_free_device(input_dev);
+	kfree(lk);
 	return err;
 }
 
 /*
  * lkkbd_disconnect() unregisters and closes behind us.
  */
-static void
-lkkbd_disconnect (struct serio *serio)
+static void lkkbd_disconnect(struct serio *serio)
 {
-	struct lkkbd *lk = serio_get_drvdata (serio);
+	struct lkkbd *lk = serio_get_drvdata(serio);
 
-	input_get_device (lk->dev);
-	input_unregister_device (lk->dev);
-	serio_close (serio);
-	serio_set_drvdata (serio, NULL);
-	input_put_device (lk->dev);
-	kfree (lk);
+	input_get_device(lk->dev);
+	input_unregister_device(lk->dev);
+	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
+	input_put_device(lk->dev);
+	kfree(lk);
 }
 
 static struct serio_device_id lkkbd_serio_ids[] = {
@@ -752,18 +734,16 @@
 /*
  * The functions for insering/removing us as a module.
  */
-static int __init
-lkkbd_init (void)
+static int __init lkkbd_init(void)
 {
 	return serio_register_driver(&lkkbd_drv);
 }
 
-static void __exit
-lkkbd_exit (void)
+static void __exit lkkbd_exit(void)
 {
 	serio_unregister_driver(&lkkbd_drv);
 }
 
-module_init (lkkbd_init);
-module_exit (lkkbd_exit);
+module_init(lkkbd_init);
+module_exit(lkkbd_exit);
 
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index 91cfe51..34f4a29 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -213,8 +213,9 @@
 }
 
 #ifdef CONFIG_PM
-static int matrix_keypad_suspend(struct platform_device *pdev, pm_message_t state)
+static int matrix_keypad_suspend(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
 	struct matrix_keypad *keypad = platform_get_drvdata(pdev);
 	const struct matrix_keypad_platform_data *pdata = keypad->pdata;
 	int i;
@@ -228,8 +229,9 @@
 	return 0;
 }
 
-static int matrix_keypad_resume(struct platform_device *pdev)
+static int matrix_keypad_resume(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
 	struct matrix_keypad *keypad = platform_get_drvdata(pdev);
 	const struct matrix_keypad_platform_data *pdata = keypad->pdata;
 	int i;
@@ -242,9 +244,9 @@
 
 	return 0;
 }
-#else
-#define matrix_keypad_suspend	NULL
-#define matrix_keypad_resume	NULL
+
+static const SIMPLE_DEV_PM_OPS(matrix_keypad_pm_ops,
+				matrix_keypad_suspend, matrix_keypad_resume);
 #endif
 
 static int __devinit init_matrix_gpio(struct platform_device *pdev,
@@ -417,11 +419,12 @@
 static struct platform_driver matrix_keypad_driver = {
 	.probe		= matrix_keypad_probe,
 	.remove		= __devexit_p(matrix_keypad_remove),
-	.suspend	= matrix_keypad_suspend,
-	.resume		= matrix_keypad_resume,
 	.driver		= {
 		.name	= "matrix-keypad",
 		.owner	= THIS_MODULE,
+#ifdef CONFIG_PM
+		.pm	= &matrix_keypad_pm_ops,
+#endif
 	},
 };
 
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c
index 887af79..076111f 100644
--- a/drivers/input/keyboard/sh_keysc.c
+++ b/drivers/input/keyboard/sh_keysc.c
@@ -18,9 +18,9 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/input.h>
+#include <linux/input/sh_keysc.h>
 #include <linux/clk.h>
 #include <linux/io.h>
-#include <asm/sh_keysc.h>
 
 #define KYCR1_OFFS   0x00
 #define KYCR2_OFFS   0x04
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index a9bb254..16ec523 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -80,6 +80,7 @@
 	tristate "x86 Wistron laptop button interface"
 	depends on X86 && !X86_64
 	select INPUT_POLLDEV
+	select INPUT_SPARSEKMAP
 	select NEW_LEDS
 	select LEDS_CLASS
 	select CHECK_SIGNATURE
@@ -281,6 +282,7 @@
 config INPUT_DM355EVM
 	tristate "TI DaVinci DM355 EVM Keypad and IR Remote"
 	depends on MFD_DM355EVM_MSP
+	select INPUT_SPARSEKMAP
 	help
 	  Supports the pushbuttons and IR remote used with
 	  the DM355 EVM board.
diff --git a/drivers/input/misc/ati_remote.c b/drivers/input/misc/ati_remote.c
index e290fde..614b65d 100644
--- a/drivers/input/misc/ati_remote.c
+++ b/drivers/input/misc/ati_remote.c
@@ -766,7 +766,7 @@
 	ati_remote->interface = interface;
 
 	usb_make_path(udev, ati_remote->phys, sizeof(ati_remote->phys));
-	strlcpy(ati_remote->phys, "/input0", sizeof(ati_remote->phys));
+	strlcat(ati_remote->phys, "/input0", sizeof(ati_remote->phys));
 
 	if (udev->manufacturer)
 		strlcpy(ati_remote->name, udev->manufacturer, sizeof(ati_remote->name));
diff --git a/drivers/input/misc/dm355evm_keys.c b/drivers/input/misc/dm355evm_keys.c
index f2b67dc..766c069 100644
--- a/drivers/input/misc/dm355evm_keys.c
+++ b/drivers/input/misc/dm355evm_keys.c
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 
@@ -33,12 +34,8 @@
 	int			irq;
 };
 
-/* These initial keycodes can be remapped by dm355evm_setkeycode(). */
-static struct {
-	u16	event;
-	u16	keycode;
-} dm355evm_keys[] = {
-
+/* These initial keycodes can be remapped */
+static const struct key_entry dm355evm_keys[] = {
 	/*
 	 * Pushbuttons on the EVM board ... note that the labels for these
 	 * are SW10/SW11/etc on the PC board.  The left/right orientation
@@ -47,11 +44,11 @@
 	 * is to the right.  (That is, rotate the board counter-clockwise
 	 * by 90 degrees from the SW10/etc and "DM355 EVM" labels.)
 	 */
-	{ 0x00d8, KEY_OK, },		/* SW12 */
-	{ 0x00b8, KEY_UP, },		/* SW13 */
-	{ 0x00e8, KEY_DOWN, },		/* SW11 */
-	{ 0x0078, KEY_LEFT, },		/* SW14 */
-	{ 0x00f0, KEY_RIGHT, },		/* SW10 */
+	{ KE_KEY, 0x00d8, { KEY_OK } },		/* SW12 */
+	{ KE_KEY, 0x00b8, { KEY_UP } },		/* SW13 */
+	{ KE_KEY, 0x00e8, { KEY_DOWN } },	/* SW11 */
+	{ KE_KEY, 0x0078, { KEY_LEFT } },	/* SW14 */
+	{ KE_KEY, 0x00f0, { KEY_RIGHT } },	/* SW10 */
 
 	/*
 	 * IR buttons ... codes assigned to match the universal remote
@@ -65,35 +62,35 @@
 	 * RC5 codes are 14 bits, with two start bits (0x3 prefix)
 	 * and a toggle bit (masked out below).
 	 */
-	{ 0x300c, KEY_POWER, },		/* NOTE: docs omit this */
-	{ 0x3000, KEY_NUMERIC_0, },
-	{ 0x3001, KEY_NUMERIC_1, },
-	{ 0x3002, KEY_NUMERIC_2, },
-	{ 0x3003, KEY_NUMERIC_3, },
-	{ 0x3004, KEY_NUMERIC_4, },
-	{ 0x3005, KEY_NUMERIC_5, },
-	{ 0x3006, KEY_NUMERIC_6, },
-	{ 0x3007, KEY_NUMERIC_7, },
-	{ 0x3008, KEY_NUMERIC_8, },
-	{ 0x3009, KEY_NUMERIC_9, },
-	{ 0x3022, KEY_ENTER, },
-	{ 0x30ec, KEY_MODE, },		/* "tv/vcr/..." */
-	{ 0x300f, KEY_SELECT, },	/* "info" */
-	{ 0x3020, KEY_CHANNELUP, },	/* "up" */
-	{ 0x302e, KEY_MENU, },		/* "in/out" */
-	{ 0x3011, KEY_VOLUMEDOWN, },	/* "left" */
-	{ 0x300d, KEY_MUTE, },		/* "ok" */
-	{ 0x3010, KEY_VOLUMEUP, },	/* "right" */
-	{ 0x301e, KEY_SUBTITLE, },	/* "cc" */
-	{ 0x3021, KEY_CHANNELDOWN, },	/* "down" */
-	{ 0x3022, KEY_PREVIOUS, },
-	{ 0x3026, KEY_SLEEP, },
-	{ 0x3172, KEY_REWIND, },	/* NOTE: docs wrongly say 0x30ca */
-	{ 0x3175, KEY_PLAY, },
-	{ 0x3174, KEY_FASTFORWARD, },
-	{ 0x3177, KEY_RECORD, },
-	{ 0x3176, KEY_STOP, },
-	{ 0x3169, KEY_PAUSE, },
+	{ KE_KEY, 0x300c, { KEY_POWER } },	/* NOTE: docs omit this */
+	{ KE_KEY, 0x3000, { KEY_NUMERIC_0 } },
+	{ KE_KEY, 0x3001, { KEY_NUMERIC_1 } },
+	{ KE_KEY, 0x3002, { KEY_NUMERIC_2 } },
+	{ KE_KEY, 0x3003, { KEY_NUMERIC_3 } },
+	{ KE_KEY, 0x3004, { KEY_NUMERIC_4 } },
+	{ KE_KEY, 0x3005, { KEY_NUMERIC_5 } },
+	{ KE_KEY, 0x3006, { KEY_NUMERIC_6 } },
+	{ KE_KEY, 0x3007, { KEY_NUMERIC_7 } },
+	{ KE_KEY, 0x3008, { KEY_NUMERIC_8 } },
+	{ KE_KEY, 0x3009, { KEY_NUMERIC_9 } },
+	{ KE_KEY, 0x3022, { KEY_ENTER } },
+	{ KE_KEY, 0x30ec, { KEY_MODE } },	/* "tv/vcr/..." */
+	{ KE_KEY, 0x300f, { KEY_SELECT } },	/* "info" */
+	{ KE_KEY, 0x3020, { KEY_CHANNELUP } },	/* "up" */
+	{ KE_KEY, 0x302e, { KEY_MENU } },	/* "in/out" */
+	{ KE_KEY, 0x3011, { KEY_VOLUMEDOWN } },	/* "left" */
+	{ KE_KEY, 0x300d, { KEY_MUTE } },	/* "ok" */
+	{ KE_KEY, 0x3010, { KEY_VOLUMEUP } },	/* "right" */
+	{ KE_KEY, 0x301e, { KEY_SUBTITLE } },	/* "cc" */
+	{ KE_KEY, 0x3021, { KEY_CHANNELDOWN } },/* "down" */
+	{ KE_KEY, 0x3022, { KEY_PREVIOUS } },
+	{ KE_KEY, 0x3026, { KEY_SLEEP } },
+	{ KE_KEY, 0x3172, { KEY_REWIND } },	/* NOTE: docs wrongly say 0x30ca */
+	{ KE_KEY, 0x3175, { KEY_PLAY } },
+	{ KE_KEY, 0x3174, { KEY_FASTFORWARD } },
+	{ KE_KEY, 0x3177, { KEY_RECORD } },
+	{ KE_KEY, 0x3176, { KEY_STOP } },
+	{ KE_KEY, 0x3169, { KEY_PAUSE } },
 };
 
 /*
@@ -105,19 +102,18 @@
  */
 static irqreturn_t dm355evm_keys_irq(int irq, void *_keys)
 {
-	struct dm355evm_keys	*keys = _keys;
-	int			status;
+	static u16 last_event;
+	struct dm355evm_keys *keys = _keys;
+	const struct key_entry *ke;
+	unsigned int keycode;
+	int status;
+	u16 event;
 
 	/* For simplicity we ignore INPUT_COUNT and just read
 	 * events until we get the "queue empty" indicator.
 	 * Reading INPUT_LOW decrements the count.
 	 */
 	for (;;) {
-		static u16	last_event;
-		u16		event;
-		int		keycode;
-		int		i;
-
 		status = dm355evm_msp_read(DM355EVM_MSP_INPUT_HIGH);
 		if (status < 0) {
 			dev_dbg(keys->dev, "input high err %d\n",
@@ -156,14 +152,9 @@
 		/* ignore the RC5 toggle bit */
 		event &= ~0x0800;
 
-		/* find the key, or leave it as unknown */
-		keycode = KEY_UNKNOWN;
-		for (i = 0; i < ARRAY_SIZE(dm355evm_keys); i++) {
-			if (dm355evm_keys[i].event != event)
-				continue;
-			keycode = dm355evm_keys[i].keycode;
-			break;
-		}
+		/* find the key, or report it as unknown */
+		ke = sparse_keymap_entry_from_scancode(keys->input, event);
+		keycode = ke ? ke->keycode : KEY_UNKNOWN;
 		dev_dbg(keys->dev,
 			"input event 0x%04x--> keycode %d\n",
 			event, keycode);
@@ -174,38 +165,10 @@
 		input_report_key(keys->input, keycode, 0);
 		input_sync(keys->input);
 	}
+
 	return IRQ_HANDLED;
 }
 
-static int dm355evm_setkeycode(struct input_dev *dev, int index, int keycode)
-{
-	u16		old_keycode;
-	unsigned	i;
-
-	if (((unsigned)index) >= ARRAY_SIZE(dm355evm_keys))
-		return -EINVAL;
-
-	old_keycode = dm355evm_keys[index].keycode;
-	dm355evm_keys[index].keycode = keycode;
-	set_bit(keycode, dev->keybit);
-
-	for (i = 0; i < ARRAY_SIZE(dm355evm_keys); i++) {
-		if (dm355evm_keys[index].keycode == old_keycode)
-			goto done;
-	}
-	clear_bit(old_keycode, dev->keybit);
-done:
-	return 0;
-}
-
-static int dm355evm_getkeycode(struct input_dev *dev, int index, int *keycode)
-{
-	if (((unsigned)index) >= ARRAY_SIZE(dm355evm_keys))
-		return -EINVAL;
-
-	return dm355evm_keys[index].keycode;
-}
-
 /*----------------------------------------------------------------------*/
 
 static int __devinit dm355evm_keys_probe(struct platform_device *pdev)
@@ -213,7 +176,6 @@
 	struct dm355evm_keys	*keys;
 	struct input_dev	*input;
 	int			status;
-	int			i;
 
 	/* allocate instance struct and input dev */
 	keys = kzalloc(sizeof *keys, GFP_KERNEL);
@@ -242,31 +204,30 @@
 	input->id.product = 0x0355;
 	input->id.version = dm355evm_msp_read(DM355EVM_MSP_FIRMREV);
 
-	input->evbit[0] = BIT(EV_KEY);
-	for (i = 0; i < ARRAY_SIZE(dm355evm_keys); i++)
-		__set_bit(dm355evm_keys[i].keycode, input->keybit);
-
-	input->setkeycode = dm355evm_setkeycode;
-	input->getkeycode = dm355evm_getkeycode;
+	status = sparse_keymap_setup(input, dm355evm_keys, NULL);
+	if (status)
+		goto fail1;
 
 	/* REVISIT:  flush the event queue? */
 
 	status = request_threaded_irq(keys->irq, NULL, dm355evm_keys_irq,
 			IRQF_TRIGGER_FALLING, dev_name(&pdev->dev), keys);
 	if (status < 0)
-		goto fail1;
+		goto fail2;
 
 	/* register */
 	status = input_register_device(input);
 	if (status < 0)
-		goto fail2;
+		goto fail3;
 
 	platform_set_drvdata(pdev, keys);
 
 	return 0;
 
-fail2:
+fail3:
 	free_irq(keys->irq, keys);
+fail2:
+	sparse_keymap_free(input);
 fail1:
 	input_free_device(input);
 	kfree(keys);
@@ -280,6 +241,7 @@
 	struct dm355evm_keys	*keys = platform_get_drvdata(pdev);
 
 	free_irq(keys->irq, keys);
+	sparse_keymap_free(keys->input);
 	input_unregister_device(keys->input);
 	kfree(keys);
 
diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c
index ea821b5..ad730e1 100644
--- a/drivers/input/misc/hp_sdc_rtc.c
+++ b/drivers/input/misc/hp_sdc_rtc.c
@@ -35,7 +35,6 @@
 
 #include <linux/hp_sdc.h>
 #include <linux/errno.h>
-#include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -409,7 +408,6 @@
 
 static int hp_sdc_rtc_open(struct inode *inode, struct file *file)
 {
-	cycle_kernel_lock();
         return 0;
 }
 
diff --git a/drivers/input/misc/powermate.c b/drivers/input/misc/powermate.c
index a53c488..668913d 100644
--- a/drivers/input/misc/powermate.c
+++ b/drivers/input/misc/powermate.c
@@ -338,7 +338,7 @@
 	pm->input = input_dev;
 
 	usb_make_path(udev, pm->phys, sizeof(pm->phys));
-	strlcpy(pm->phys, "/input0", sizeof(pm->phys));
+	strlcat(pm->phys, "/input0", sizeof(pm->phys));
 
 	spin_lock_init(&pm->lock);
 
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index a932179..38da6ab 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -21,6 +21,7 @@
 #include <linux/dmi.h>
 #include <linux/init.h>
 #include <linux/input-polldev.h>
+#include <linux/input/sparse-keymap.h>
 #include <linux/interrupt.h>
 #include <linux/jiffies.h>
 #include <linux/kernel.h>
@@ -224,19 +225,8 @@
 
 /* Hardware database */
 
-struct key_entry {
-	char type;		/* See KE_* below */
-	u8 code;
-	union {
-		u16 keycode;		/* For KE_KEY */
-		struct {		/* For KE_SW */
-			u8 code;
-			u8 value;
-		} sw;
-	};
-};
-
-enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH };
+#define KE_WIFI		(KE_LAST + 1)
+#define KE_BLUETOOTH	(KE_LAST + 2)
 
 #define FE_MAIL_LED 0x01
 #define FE_WIFI_LED 0x02
@@ -644,10 +634,10 @@
  * a list of buttons and their key codes (reported when loading this module
  * with force=1) and the output of dmidecode to $MODULE_AUTHOR.
  */
-static struct dmi_system_id dmi_ids[] __initdata = {
+static const struct dmi_system_id __initconst dmi_ids[] = {
 	{
+		/* Fujitsu-Siemens Amilo Pro V2000 */
 		.callback = dmi_matched,
-		.ident = "Fujitsu-Siemens Amilo Pro V2000",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2000"),
@@ -655,8 +645,8 @@
 		.driver_data = keymap_fs_amilo_pro_v2000
 	},
 	{
+		/* Fujitsu-Siemens Amilo Pro Edition V3505 */
 		.callback = dmi_matched,
-		.ident = "Fujitsu-Siemens Amilo Pro Edition V3505",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro Edition V3505"),
@@ -664,8 +654,8 @@
 		.driver_data = keymap_fs_amilo_pro_v3505
 	},
 	{
+		/* Fujitsu-Siemens Amilo M7400 */
 		.callback = dmi_matched,
-		.ident = "Fujitsu-Siemens Amilo M7400",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO M        "),
@@ -673,8 +663,8 @@
 		.driver_data = keymap_fs_amilo_pro_v2000
 	},
 	{
+		/* Maxdata Pro 7000 DX */
 		.callback = dmi_matched,
-		.ident = "Maxdata Pro 7000 DX",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "MAXDATA"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Pro 7000"),
@@ -682,8 +672,8 @@
 		.driver_data = keymap_fs_amilo_pro_v2000
 	},
 	{
+		/* Fujitsu N3510 */
 		.callback = dmi_matched,
-		.ident = "Fujitsu N3510",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "N3510"),
@@ -691,8 +681,8 @@
 		.driver_data = keymap_fujitsu_n3510
 	},
 	{
+		/* Acer Aspire 1500 */
 		.callback = dmi_matched,
-		.ident = "Acer Aspire 1500",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1500"),
@@ -700,8 +690,8 @@
 		.driver_data = keymap_acer_aspire_1500
 	},
 	{
+		/* Acer Aspire 1600 */
 		.callback = dmi_matched,
-		.ident = "Acer Aspire 1600",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1600"),
@@ -709,8 +699,8 @@
 		.driver_data = keymap_acer_aspire_1600
 	},
 	{
+		/* Acer Aspire 3020 */
 		.callback = dmi_matched,
-		.ident = "Acer Aspire 3020",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3020"),
@@ -718,8 +708,8 @@
 		.driver_data = keymap_acer_aspire_5020
 	},
 	{
+		/* Acer Aspire 5020 */
 		.callback = dmi_matched,
-		.ident = "Acer Aspire 5020",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5020"),
@@ -727,8 +717,8 @@
 		.driver_data = keymap_acer_aspire_5020
 	},
 	{
+		/* Acer TravelMate 2100 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 2100",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2100"),
@@ -736,8 +726,8 @@
 		.driver_data = keymap_acer_aspire_5020
 	},
 	{
+		/* Acer TravelMate 2410 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 2410",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2410"),
@@ -745,8 +735,8 @@
 		.driver_data = keymap_acer_travelmate_2410
 	},
 	{
+		/* Acer TravelMate C300 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate C300",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C300"),
@@ -754,8 +744,8 @@
 		.driver_data = keymap_acer_travelmate_300
 	},
 	{
+		/* Acer TravelMate C100 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate C100",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C100"),
@@ -763,8 +753,8 @@
 		.driver_data = keymap_acer_travelmate_300
 	},
 	{
+		/* Acer TravelMate C110 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate C110",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C110"),
@@ -772,8 +762,8 @@
 		.driver_data = keymap_acer_travelmate_110
 	},
 	{
+		/* Acer TravelMate 380 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 380",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 380"),
@@ -781,8 +771,8 @@
 		.driver_data = keymap_acer_travelmate_380
 	},
 	{
+		/* Acer TravelMate 370 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 370",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 370"),
@@ -790,8 +780,8 @@
 		.driver_data = keymap_acer_travelmate_380 /* keyboard minus 1 key */
 	},
 	{
+		/* Acer TravelMate 220 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 220",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 220"),
@@ -799,8 +789,8 @@
 		.driver_data = keymap_acer_travelmate_220
 	},
 	{
+		/* Acer TravelMate 260 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 260",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 260"),
@@ -808,8 +798,8 @@
 		.driver_data = keymap_acer_travelmate_220
 	},
 	{
+		/* Acer TravelMate 230 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 230",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 230"),
@@ -818,8 +808,8 @@
 		.driver_data = keymap_acer_travelmate_230
 	},
 	{
+		/* Acer TravelMate 280 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 280",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 280"),
@@ -827,8 +817,8 @@
 		.driver_data = keymap_acer_travelmate_230
 	},
 	{
+		/* Acer TravelMate 240 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 240",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 240"),
@@ -836,8 +826,8 @@
 		.driver_data = keymap_acer_travelmate_240
 	},
 	{
+		/* Acer TravelMate 250 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 250",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 250"),
@@ -845,8 +835,8 @@
 		.driver_data = keymap_acer_travelmate_240
 	},
 	{
+		/* Acer TravelMate 2424NWXCi */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 2424NWXCi",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2420"),
@@ -854,8 +844,8 @@
 		.driver_data = keymap_acer_travelmate_240
 	},
 	{
+		/* Acer TravelMate 350 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 350",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 350"),
@@ -863,8 +853,8 @@
 		.driver_data = keymap_acer_travelmate_350
 	},
 	{
+		/* Acer TravelMate 360 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 360",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
@@ -872,8 +862,8 @@
 		.driver_data = keymap_acer_travelmate_360
 	},
 	{
+		/* Acer TravelMate 610 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 610",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ACER"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 610"),
@@ -881,8 +871,8 @@
 		.driver_data = keymap_acer_travelmate_610
 	},
 	{
+		/* Acer TravelMate 620 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 620",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 620"),
@@ -890,8 +880,8 @@
 		.driver_data = keymap_acer_travelmate_630
 	},
 	{
+		/* Acer TravelMate 630 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 630",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 630"),
@@ -899,8 +889,8 @@
 		.driver_data = keymap_acer_travelmate_630
 	},
 	{
+		/* AOpen 1559AS */
 		.callback = dmi_matched,
-		.ident = "AOpen 1559AS",
 		.matches = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "E2U"),
 			DMI_MATCH(DMI_BOARD_NAME, "E2U"),
@@ -908,8 +898,8 @@
 		.driver_data = keymap_aopen_1559as
 	},
 	{
+		/* Medion MD 9783 */
 		.callback = dmi_matched,
-		.ident = "Medion MD 9783",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "MD 9783"),
@@ -917,8 +907,8 @@
 		.driver_data = keymap_wistron_ms2111
 	},
 	{
+		/* Medion MD 40100 */
 		.callback = dmi_matched,
-		.ident = "Medion MD 40100",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "WID2000"),
@@ -926,8 +916,8 @@
 		.driver_data = keymap_wistron_md40100
 	},
 	{
+		/* Medion MD 2900 */
 		.callback = dmi_matched,
-		.ident = "Medion MD 2900",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2000"),
@@ -935,8 +925,8 @@
 		.driver_data = keymap_wistron_md2900
 	},
 	{
+		/* Medion MD 42200 */
 		.callback = dmi_matched,
-		.ident = "Medion MD 42200",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Medion"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2030"),
@@ -944,8 +934,8 @@
 		.driver_data = keymap_fs_amilo_pro_v2000
 	},
 	{
+		/* Medion MD 96500 */
 		.callback = dmi_matched,
-		.ident = "Medion MD 96500",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2040"),
@@ -953,8 +943,8 @@
 		.driver_data = keymap_wistron_md96500
 	},
 	{
+		/* Medion MD 95400 */
 		.callback = dmi_matched,
-		.ident = "Medion MD 95400",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2050"),
@@ -962,8 +952,8 @@
 		.driver_data = keymap_wistron_md96500
 	},
 	{
+		/* Fujitsu Siemens Amilo D7820 */
 		.callback = dmi_matched,
-		.ident = "Fujitsu Siemens Amilo D7820",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), /* not sure */
 			DMI_MATCH(DMI_PRODUCT_NAME, "Amilo D"),
@@ -971,8 +961,8 @@
 		.driver_data = keymap_fs_amilo_d88x0
 	},
 	{
+		/* Fujitsu Siemens Amilo D88x0 */
 		.callback = dmi_matched,
-		.ident = "Fujitsu Siemens Amilo D88x0",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO D"),
@@ -1037,21 +1027,6 @@
 static bool wifi_enabled;
 static bool bluetooth_enabled;
 
-static void report_key(struct input_dev *dev, unsigned int keycode)
-{
-	input_report_key(dev, keycode, 1);
-	input_sync(dev);
-	input_report_key(dev, keycode, 0);
-	input_sync(dev);
-}
-
-static void report_switch(struct input_dev *dev, unsigned int code, int value)
-{
-	input_report_switch(dev, code, value);
-	input_sync(dev);
-}
-
-
  /* led management */
 static void wistron_mail_led_set(struct led_classdev *led_cdev,
 				enum led_brightness value)
@@ -1128,43 +1103,13 @@
 		led_classdev_resume(&wistron_wifi_led);
 }
 
-static struct key_entry *wistron_get_entry_by_scancode(int code)
-{
-	struct key_entry *key;
-
-	for (key = keymap; key->type != KE_END; key++)
-		if (code == key->code)
-			return key;
-
-	return NULL;
-}
-
-static struct key_entry *wistron_get_entry_by_keycode(int keycode)
-{
-	struct key_entry *key;
-
-	for (key = keymap; key->type != KE_END; key++)
-		if (key->type == KE_KEY && keycode == key->keycode)
-			return key;
-
-	return NULL;
-}
-
 static void handle_key(u8 code)
 {
-	const struct key_entry *key = wistron_get_entry_by_scancode(code);
+	const struct key_entry *key =
+		sparse_keymap_entry_from_scancode(wistron_idev->input, code);
 
 	if (key) {
 		switch (key->type) {
-		case KE_KEY:
-			report_key(wistron_idev->input, key->keycode);
-			break;
-
-		case KE_SW:
-			report_switch(wistron_idev->input,
-				      key->sw.code, key->sw.value);
-			break;
-
 		case KE_WIFI:
 			if (have_wifi) {
 				wifi_enabled = !wifi_enabled;
@@ -1180,7 +1125,9 @@
 			break;
 
 		default:
-			BUG();
+			sparse_keymap_report_entry(wistron_idev->input,
+						   key, 1, true);
+			break;
 		}
 		jiffies_last_press = jiffies;
 	} else
@@ -1220,42 +1167,39 @@
 		dev->poll_interval = POLL_INTERVAL_DEFAULT;
 }
 
-static int wistron_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+static int __devinit wistron_setup_keymap(struct input_dev *dev,
+					  struct key_entry *entry)
 {
-	const struct key_entry *key = wistron_get_entry_by_scancode(scancode);
+	switch (entry->type) {
 
-	if (key && key->type == KE_KEY) {
-		*keycode = key->keycode;
-		return 0;
+	/* if wifi or bluetooth are not available, create normal keys */
+	case KE_WIFI:
+		if (!have_wifi) {
+			entry->type = KE_KEY;
+			entry->keycode = KEY_WLAN;
+		}
+		break;
+
+	case KE_BLUETOOTH:
+		if (!have_bluetooth) {
+			entry->type = KE_KEY;
+			entry->keycode = KEY_BLUETOOTH;
+		}
+		break;
+
+	case KE_END:
+		if (entry->code & FE_UNTESTED)
+			printk(KERN_WARNING "Untested laptop multimedia keys, "
+				"please report success or failure to "
+				"eric.piel@tremplin-utc.net\n");
+		break;
 	}
 
-	return -EINVAL;
-}
-
-static int wistron_setkeycode(struct input_dev *dev, int scancode, int keycode)
-{
-	struct key_entry *key;
-	int old_keycode;
-
-	if (keycode < 0 || keycode > KEY_MAX)
-		return -EINVAL;
-
-	key = wistron_get_entry_by_scancode(scancode);
-	if (key && key->type == KE_KEY) {
-		old_keycode = key->keycode;
-		key->keycode = keycode;
-		set_bit(keycode, dev->keybit);
-		if (!wistron_get_entry_by_keycode(old_keycode))
-			clear_bit(old_keycode, dev->keybit);
-		return 0;
-	}
-
-	return -EINVAL;
+	return 0;
 }
 
 static int __devinit setup_input_dev(void)
 {
-	struct key_entry *key;
 	struct input_dev *input_dev;
 	int error;
 
@@ -1263,7 +1207,7 @@
 	if (!wistron_idev)
 		return -ENOMEM;
 
-	wistron_idev->flush = wistron_flush;
+	wistron_idev->open = wistron_flush;
 	wistron_idev->poll = wistron_poll;
 	wistron_idev->poll_interval = POLL_INTERVAL_DEFAULT;
 
@@ -1273,56 +1217,21 @@
 	input_dev->id.bustype = BUS_HOST;
 	input_dev->dev.parent = &wistron_device->dev;
 
-	input_dev->getkeycode = wistron_getkeycode;
-	input_dev->setkeycode = wistron_setkeycode;
-
-	for (key = keymap; key->type != KE_END; key++) {
-		switch (key->type) {
-			case KE_KEY:
-				set_bit(EV_KEY, input_dev->evbit);
-				set_bit(key->keycode, input_dev->keybit);
-				break;
-
-			case KE_SW:
-				set_bit(EV_SW, input_dev->evbit);
-				set_bit(key->sw.code, input_dev->swbit);
-				break;
-
-			/* if wifi or bluetooth are not available, create normal keys */
-			case KE_WIFI:
-				if (!have_wifi) {
-					key->type = KE_KEY;
-					key->keycode = KEY_WLAN;
-					key--;
-				}
-				break;
-
-			case KE_BLUETOOTH:
-				if (!have_bluetooth) {
-					key->type = KE_KEY;
-					key->keycode = KEY_BLUETOOTH;
-					key--;
-				}
-				break;
-
-			default:
-				break;
-		}
-	}
-
-	/* reads information flags on KE_END */
-	if (key->code & FE_UNTESTED)
-		printk(KERN_WARNING "Untested laptop multimedia keys, "
-			"please report success or failure to eric.piel"
-			"@tremplin-utc.net\n");
+	error = sparse_keymap_setup(input_dev, keymap, wistron_setup_keymap);
+	if (error)
+		goto err_free_dev;
 
 	error = input_register_polled_device(wistron_idev);
-	if (error) {
-		input_free_polled_device(wistron_idev);
-		return error;
-	}
+	if (error)
+		goto err_free_keymap;
 
 	return 0;
+
+ err_free_keymap:
+	sparse_keymap_free(input_dev);
+ err_free_dev:
+	input_free_polled_device(wistron_idev);
+	return error;
 }
 
 /* Driver core */
@@ -1371,6 +1280,7 @@
 {
 	wistron_led_remove();
 	input_unregister_polled_device(wistron_idev);
+	sparse_keymap_free(wistron_idev->input);
 	input_free_polled_device(wistron_idev);
 	bios_detach();
 
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index f361106..a3f492a 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -28,13 +28,16 @@
 #define dbg(format, arg...) do {} while (0)
 #endif
 
-#define ALPS_DUALPOINT	0x01
-#define ALPS_WHEEL	0x02
-#define ALPS_FW_BK_1	0x04
-#define ALPS_4BTN	0x08
-#define ALPS_OLDPROTO	0x10
-#define ALPS_PASS	0x20
-#define ALPS_FW_BK_2	0x40
+
+#define ALPS_OLDPROTO		0x01	/* old style input */
+#define ALPS_DUALPOINT		0x02	/* touchpad has trackstick */
+#define ALPS_PASS		0x04	/* device has a pass-through port */
+
+#define ALPS_WHEEL		0x08	/* hardware wheel present */
+#define ALPS_FW_BK_1		0x10	/* front & back buttons present */
+#define ALPS_FW_BK_2		0x20	/* front & back buttons present */
+#define ALPS_FOUR_BUTTONS	0x40	/* 4 direction button present */
+
 
 static const struct alps_model_info alps_model_data[] = {
 	{ { 0x32, 0x02, 0x14 },	0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */
@@ -56,7 +59,7 @@
 	{ { 0x22, 0x02, 0x0a },	0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
 	{ { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */
 	{ { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude E6500 */
-	{ { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 },		  /* Dell Vostro 1400 */
+	{ { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS },	  /* Dell Vostro 1400 */
 };
 
 /*
@@ -83,6 +86,7 @@
 static void alps_process_packet(struct psmouse *psmouse)
 {
 	struct alps_data *priv = psmouse->private;
+	const struct alps_model_info *model = priv->i;
 	unsigned char *packet = psmouse->packet;
 	struct input_dev *dev = psmouse->dev;
 	struct input_dev *dev2 = priv->dev2;
@@ -101,7 +105,7 @@
 		return;
 	}
 
-	if (priv->i->flags & ALPS_OLDPROTO) {
+	if (model->flags & ALPS_OLDPROTO) {
 		left = packet[2] & 0x10;
 		right = packet[2] & 0x08;
 		middle = 0;
@@ -117,12 +121,12 @@
 		z = packet[5];
 	}
 
-	if (priv->i->flags & ALPS_FW_BK_1) {
+	if (model->flags & ALPS_FW_BK_1) {
 		back = packet[0] & 0x10;
 		forward = packet[2] & 4;
 	}
 
-	if (priv->i->flags & ALPS_FW_BK_2) {
+	if (model->flags & ALPS_FW_BK_2) {
 		back = packet[3] & 4;
 		forward = packet[2] & 4;
 		if ((middle = forward && back))
@@ -132,7 +136,7 @@
 	ges = packet[2] & 1;
 	fin = packet[2] & 2;
 
-	if ((priv->i->flags & ALPS_DUALPOINT) && z == 127) {
+	if ((model->flags & ALPS_DUALPOINT) && z == 127) {
 		input_report_rel(dev2, REL_X,  (x > 383 ? (x - 768) : x));
 		input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y));
 
@@ -150,7 +154,8 @@
 	input_report_key(dev, BTN_MIDDLE, middle);
 
 	/* Convert hardware tap to a reasonable Z value */
-	if (ges && !fin) z = 40;
+	if (ges && !fin)
+		z = 40;
 
 	/*
 	 * A "tap and drag" operation is reported by the hardware as a transition
@@ -166,8 +171,10 @@
 	}
 	priv->prev_fin = fin;
 
-	if (z > 30) input_report_key(dev, BTN_TOUCH, 1);
-	if (z < 25) input_report_key(dev, BTN_TOUCH, 0);
+	if (z > 30)
+		input_report_key(dev, BTN_TOUCH, 1);
+	if (z < 25)
+		input_report_key(dev, BTN_TOUCH, 0);
 
 	if (z > 0) {
 		input_report_abs(dev, ABS_X, x);
@@ -177,14 +184,21 @@
 	input_report_abs(dev, ABS_PRESSURE, z);
 	input_report_key(dev, BTN_TOOL_FINGER, z > 0);
 
-	if (priv->i->flags & ALPS_WHEEL)
+	if (model->flags & ALPS_WHEEL)
 		input_report_rel(dev, REL_WHEEL, ((packet[2] << 1) & 0x08) - ((packet[0] >> 4) & 0x07));
 
-	if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
+	if (model->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
 		input_report_key(dev, BTN_FORWARD, forward);
 		input_report_key(dev, BTN_BACK, back);
 	}
 
+	if (model->flags & ALPS_FOUR_BUTTONS) {
+		input_report_key(dev, BTN_0, packet[2] & 4);
+		input_report_key(dev, BTN_1, packet[0] & 0x10);
+		input_report_key(dev, BTN_2, packet[3] & 4);
+		input_report_key(dev, BTN_3, packet[0] & 0x20);
+	}
+
 	input_sync(dev);
 }
 
@@ -393,15 +407,12 @@
 	return 0;
 }
 
-static int alps_hw_init(struct psmouse *psmouse, int *version)
+static int alps_hw_init(struct psmouse *psmouse)
 {
 	struct alps_data *priv = psmouse->private;
+	const struct alps_model_info *model = priv->i;
 
-	priv->i = alps_get_model(psmouse, version);
-	if (!priv->i)
-		return -1;
-
-	if ((priv->i->flags & ALPS_PASS) &&
+	if ((model->flags & ALPS_PASS) &&
 	    alps_passthrough_mode(psmouse, true)) {
 		return -1;
 	}
@@ -416,7 +427,7 @@
 		return -1;
 	}
 
-	if ((priv->i->flags & ALPS_PASS) &&
+	if ((model->flags & ALPS_PASS) &&
 	    alps_passthrough_mode(psmouse, false)) {
 		return -1;
 	}
@@ -432,12 +443,15 @@
 
 static int alps_reconnect(struct psmouse *psmouse)
 {
+	const struct alps_model_info *model;
+
 	psmouse_reset(psmouse);
 
-	if (alps_hw_init(psmouse, NULL))
+	model = alps_get_model(psmouse, NULL);
+	if (!model)
 		return -1;
 
-	return 0;
+	return alps_hw_init(psmouse);
 }
 
 static void alps_disconnect(struct psmouse *psmouse)
@@ -452,6 +466,7 @@
 int alps_init(struct psmouse *psmouse)
 {
 	struct alps_data *priv;
+	const struct alps_model_info *model;
 	struct input_dev *dev1 = psmouse->dev, *dev2;
 	int version;
 
@@ -463,33 +478,48 @@
 	priv->dev2 = dev2;
 	psmouse->private = priv;
 
-	if (alps_hw_init(psmouse, &version))
+	model = alps_get_model(psmouse, &version);
+	if (!model)
+		goto init_fail;
+
+	priv->i = model;
+
+	if (alps_hw_init(psmouse))
 		goto init_fail;
 
 	dev1->evbit[BIT_WORD(EV_KEY)] |= BIT_MASK(EV_KEY);
 	dev1->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH);
 	dev1->keybit[BIT_WORD(BTN_TOOL_FINGER)] |= BIT_MASK(BTN_TOOL_FINGER);
-	dev1->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
-		BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+	dev1->keybit[BIT_WORD(BTN_LEFT)] |=
+		BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
 
 	dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS);
 	input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0);
 	input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0);
 	input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
 
-	if (priv->i->flags & ALPS_WHEEL) {
+	if (model->flags & ALPS_WHEEL) {
 		dev1->evbit[BIT_WORD(EV_REL)] |= BIT_MASK(EV_REL);
 		dev1->relbit[BIT_WORD(REL_WHEEL)] |= BIT_MASK(REL_WHEEL);
 	}
 
-	if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
+	if (model->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
 		dev1->keybit[BIT_WORD(BTN_FORWARD)] |= BIT_MASK(BTN_FORWARD);
 		dev1->keybit[BIT_WORD(BTN_BACK)] |= BIT_MASK(BTN_BACK);
 	}
 
+	if (model->flags & ALPS_FOUR_BUTTONS) {
+		dev1->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_0);
+		dev1->keybit[BIT_WORD(BTN_1)] |= BIT_MASK(BTN_1);
+		dev1->keybit[BIT_WORD(BTN_2)] |= BIT_MASK(BTN_2);
+		dev1->keybit[BIT_WORD(BTN_3)] |= BIT_MASK(BTN_3);
+	} else {
+		dev1->keybit[BIT_WORD(BTN_MIDDLE)] |= BIT_MASK(BTN_MIDDLE);
+	}
+
 	snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys);
 	dev2->phys = priv->phys;
-	dev2->name = (priv->i->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse";
+	dev2->name = (model->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse";
 	dev2->id.bustype = BUS_I8042;
 	dev2->id.vendor  = 0x0002;
 	dev2->id.product = PSMOUSE_ALPS;
@@ -497,9 +527,9 @@
 	dev2->dev.parent = &psmouse->ps2dev.serio->dev;
 
 	dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
-	dev2->relbit[BIT_WORD(REL_X)] |= BIT_MASK(REL_X) | BIT_MASK(REL_Y);
-	dev2->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
-		BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+	dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+	dev2->keybit[BIT_WORD(BTN_LEFT)] =
+		BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
 
 	if (input_register_device(priv->dev2))
 		goto init_fail;
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index fda35e6..b27684f 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -420,6 +420,7 @@
 
 	__set_bit(EV_KEY, dev->evbit);
 	__set_bit(EV_ABS, dev->evbit);
+	__clear_bit(EV_REL, dev->evbit);
 
 	__set_bit(BTN_LEFT, dev->keybit);
 	__set_bit(BTN_RIGHT, dev->keybit);
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c
index de1e553..b146237 100644
--- a/drivers/input/mouse/hgpk.c
+++ b/drivers/input/mouse/hgpk.c
@@ -430,19 +430,6 @@
 	struct input_dev *dev = psmouse->dev;
 	int err;
 
-	/* unset the things that psmouse-base sets which we don't have */
-	__clear_bit(BTN_MIDDLE, dev->keybit);
-
-	/* set the things we do have */
-	__set_bit(EV_KEY, dev->evbit);
-	__set_bit(EV_REL, dev->evbit);
-
-	__set_bit(REL_X, dev->relbit);
-	__set_bit(REL_Y, dev->relbit);
-
-	__set_bit(BTN_LEFT, dev->keybit);
-	__set_bit(BTN_RIGHT, dev->keybit);
-
 	/* register handlers */
 	psmouse->protocol_handler = hgpk_process_byte;
 	psmouse->poll = hgpk_poll;
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
index 8281155..2e6bdfe 100644
--- a/drivers/input/mouse/lifebook.c
+++ b/drivers/input/mouse/lifebook.c
@@ -25,11 +25,13 @@
 	char phys[32];
 };
 
+static bool lifebook_present;
+
 static const char *desired_serio_phys;
 
-static int lifebook_set_serio_phys(const struct dmi_system_id *d)
+static int lifebook_limit_serio3(const struct dmi_system_id *d)
 {
-	desired_serio_phys = d->driver_data;
+	desired_serio_phys = "isa0060/serio3";
 	return 0;
 }
 
@@ -41,53 +43,53 @@
 	return 0;
 }
 
-static const struct dmi_system_id lifebook_dmi_table[] = {
+static const struct dmi_system_id __initconst lifebook_dmi_table[] = {
+#if defined(CONFIG_DMI) && defined(CONFIG_X86)
 	{
-		.ident = "FLORA-ie 55mi",
+		/* FLORA-ie 55mi */
 		.matches = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "FLORA-ie 55mi"),
 		},
 	},
 	{
-		.ident = "LifeBook B",
+		/* LifeBook B */
 		.matches = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B Series"),
 		},
 	},
 	{
-		.ident = "Lifebook B",
+		/* Lifebook B */
 		.matches = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK B Series"),
 		},
 	},
 	{
-		.ident = "Lifebook B-2130",
+		/* Lifebook B-2130 */
 		.matches = {
 			DMI_MATCH(DMI_BOARD_NAME, "ZEPHYR"),
 		},
 	},
 	{
-		.ident = "Lifebook B213x/B2150",
+		/* Lifebook B213x/B2150 */
 		.matches = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B2131/B2133/B2150"),
 		},
 	},
 	{
-		.ident = "Zephyr",
+		/* Zephyr */
 		.matches = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "ZEPHYR"),
 		},
 	},
 	{
-		.ident = "CF-18",
+		/* Panasonic CF-18 */
 		.matches = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"),
 		},
-		.callback = lifebook_set_serio_phys,
-		.driver_data = "isa0060/serio3",
+		.callback = lifebook_limit_serio3,
 	},
 	{
-		.ident = "Panasonic CF-28",
+		/* Panasonic CF-28 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "CF-28"),
@@ -95,7 +97,7 @@
 		.callback = lifebook_set_6byte_proto,
 	},
 	{
-		.ident = "Panasonic CF-29",
+		/* Panasonic CF-29 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"),
@@ -103,21 +105,27 @@
 		.callback = lifebook_set_6byte_proto,
 	},
 	{
-		.ident = "CF-72",
+		/* Panasonic CF-72 */
 		.matches = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "CF-72"),
 		},
 		.callback = lifebook_set_6byte_proto,
 	},
 	{
-		.ident = "Lifebook B142",
+		/* Lifebook B142 */
 		.matches = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
 		},
 	},
 	{ }
+#endif
 };
 
+void __init lifebook_module_init(void)
+{
+	lifebook_present = dmi_check_system(lifebook_dmi_table);
+}
+
 static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
 {
 	struct lifebook_data *priv = psmouse->private;
@@ -198,10 +206,10 @@
 		return -1;
 
 	/*
-	   Enable absolute output -- ps2_command fails always but if
-	   you leave this call out the touchsreen will never send
-	   absolute coordinates
-	*/
+	 * Enable absolute output -- ps2_command fails always but if
+	 * you leave this call out the touchsreen will never send
+	 * absolute coordinates
+	 */
 	param = lifebook_use_6byte_proto ? 0x08 : 0x07;
 	ps2_command(ps2dev, &param, PSMOUSE_CMD_SETRES);
 
@@ -243,7 +251,7 @@
 
 int lifebook_detect(struct psmouse *psmouse, bool set_properties)
 {
-        if (!dmi_check_system(lifebook_dmi_table))
+        if (!lifebook_present)
                 return -1;
 
 	if (desired_serio_phys &&
@@ -283,8 +291,8 @@
 
 	dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
 	dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
-	dev2->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
-		BIT_MASK(BTN_RIGHT);
+	dev2->keybit[BIT_WORD(BTN_LEFT)] =
+				BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
 
 	error = input_register_device(priv->dev2);
 	if (error)
@@ -309,6 +317,7 @@
 
 	dev1->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
 	dev1->relbit[0] = 0;
+	dev1->keybit[BIT_WORD(BTN_MOUSE)] = 0;
 	dev1->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 	input_set_abs_params(dev1, ABS_X, 0, max_coord, 0, 0);
 	input_set_abs_params(dev1, ABS_Y, 0, max_coord, 0, 0);
diff --git a/drivers/input/mouse/lifebook.h b/drivers/input/mouse/lifebook.h
index 407cb22..4c4326c 100644
--- a/drivers/input/mouse/lifebook.h
+++ b/drivers/input/mouse/lifebook.h
@@ -12,9 +12,13 @@
 #define _LIFEBOOK_H
 
 #ifdef CONFIG_MOUSE_PS2_LIFEBOOK
+void lifebook_module_init(void);
 int lifebook_detect(struct psmouse *psmouse, bool set_properties);
 int lifebook_init(struct psmouse *psmouse);
 #else
+inline void lifebook_module_init(void)
+{
+}
 inline int lifebook_detect(struct psmouse *psmouse, bool set_properties)
 {
 	return -ENOSYS;
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index ab5dc5f..543c240 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -404,8 +404,8 @@
 			}
 		}
 
-		if (buttons < 3)
-			__clear_bit(BTN_MIDDLE, psmouse->dev->keybit);
+		if (buttons >= 3)
+			__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
 
 		if (model_info)
 			ps2pp_set_model_properties(psmouse, model_info, use_ps2pp);
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 07c5379..fd0bc09 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -425,6 +425,7 @@
 		return -1;
 
 	if (set_properties) {
+		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
 		__set_bit(BTN_EXTRA, psmouse->dev->keybit);
 		__set_bit(BTN_SIDE, psmouse->dev->keybit);
 		__set_bit(REL_WHEEL, psmouse->dev->relbit);
@@ -460,8 +461,10 @@
 		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
 		__set_bit(REL_WHEEL, psmouse->dev->relbit);
 
-		if (!psmouse->vendor) psmouse->vendor = "Generic";
-		if (!psmouse->name) psmouse->name = "Wheel Mouse";
+		if (!psmouse->vendor)
+			psmouse->vendor = "Generic";
+		if (!psmouse->name)
+			psmouse->name = "Wheel Mouse";
 		psmouse->pktsize = 4;
 	}
 
@@ -504,8 +507,10 @@
 		__set_bit(BTN_SIDE, psmouse->dev->keybit);
 		__set_bit(BTN_EXTRA, psmouse->dev->keybit);
 
-		if (!psmouse->vendor) psmouse->vendor = "Generic";
-		if (!psmouse->name) psmouse->name = "Explorer Mouse";
+		if (!psmouse->vendor)
+			psmouse->vendor = "Generic";
+		if (!psmouse->name)
+			psmouse->name = "Explorer Mouse";
 		psmouse->pktsize = 4;
 	}
 
@@ -536,6 +541,7 @@
 		return -1;
 
 	if (set_properties) {
+		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
 		__set_bit(BTN_EXTRA, psmouse->dev->keybit);
 
 		psmouse->vendor = "Kensington";
@@ -551,8 +557,16 @@
 static int ps2bare_detect(struct psmouse *psmouse, bool set_properties)
 {
 	if (set_properties) {
-		if (!psmouse->vendor) psmouse->vendor = "Generic";
-		if (!psmouse->name) psmouse->name = "Mouse";
+		if (!psmouse->vendor)
+			psmouse->vendor = "Generic";
+		if (!psmouse->name)
+			psmouse->name = "Mouse";
+
+/*
+ * We have no way of figuring true number of buttons so let's
+ * assume that the device has 3.
+ */
+		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
 	}
 
 	return 0;
@@ -567,6 +581,8 @@
 	if (set_properties) {
 		psmouse->vendor = "Cortron";
 		psmouse->name = "PS/2 Trackball";
+
+		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
 		__set_bit(BTN_SIDE, psmouse->dev->keybit);
 	}
 
@@ -1184,15 +1200,16 @@
 	mutex_unlock(&psmouse_mutex);
 }
 
-static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse_protocol *proto)
+static int psmouse_switch_protocol(struct psmouse *psmouse,
+				   const struct psmouse_protocol *proto)
 {
 	struct input_dev *input_dev = psmouse->dev;
 
 	input_dev->dev.parent = &psmouse->ps2dev.serio->dev;
 
 	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
-	input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
-		BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+	input_dev->keybit[BIT_WORD(BTN_MOUSE)] =
+				BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
 	input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
 
 	psmouse->set_rate = psmouse_set_rate;
@@ -1209,8 +1226,7 @@
 			return -1;
 
 		psmouse->type = proto->type;
-	}
-	else
+	} else
 		psmouse->type = psmouse_extensions(psmouse,
 						   psmouse_max_proto, true);
 
@@ -1680,6 +1696,9 @@
 {
 	int err;
 
+	lifebook_module_init();
+	synaptics_module_init();
+
 	kpsmoused_wq = create_singlethread_workqueue("kpsmoused");
 	if (!kpsmoused_wq) {
 		printk(KERN_ERR "psmouse: failed to create kpsmoused workqueue\n");
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c
index f84cbd9..77b9fd0 100644
--- a/drivers/input/mouse/sentelic.c
+++ b/drivers/input/mouse/sentelic.c
@@ -836,6 +836,7 @@
 	priv->flags |= FSPDRV_FLAG_EN_OPC;
 
 	/* Set up various supported input event bits */
+	__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
 	__set_bit(BTN_BACK, psmouse->dev->keybit);
 	__set_bit(BTN_FORWARD, psmouse->dev->keybit);
 	__set_bit(REL_WHEEL, psmouse->dev->relbit);
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index f4a6125..05689e7 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -24,6 +24,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/dmi.h>
 #include <linux/input.h>
 #include <linux/serio.h>
 #include <linux/libps2.h>
@@ -629,25 +630,26 @@
 	return 0;
 }
 
-#if defined(__i386__)
-#include <linux/dmi.h>
-static const struct dmi_system_id toshiba_dmi_table[] = {
+static bool impaired_toshiba_kbc;
+
+static const struct dmi_system_id __initconst toshiba_dmi_table[] = {
+#if defined(CONFIG_DMI) && defined(CONFIG_X86)
 	{
-		.ident = "Toshiba Satellite",
+		/* Toshiba Satellite */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Satellite"),
 		},
 	},
 	{
-		.ident = "Toshiba Dynabook",
+		/* Toshiba Dynabook */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "dynabook"),
 		},
 	},
 	{
-		.ident = "Toshiba Portege M300",
+		/* Toshiba Portege M300 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
@@ -655,7 +657,7 @@
 
 	},
 	{
-		.ident = "Toshiba Portege M300",
+		/* Toshiba Portege M300 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Portable PC"),
@@ -664,8 +666,13 @@
 
 	},
 	{ }
-};
 #endif
+};
+
+void __init synaptics_module_init(void)
+{
+	impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table);
+}
 
 int synaptics_init(struct psmouse *psmouse)
 {
@@ -718,18 +725,16 @@
 	if (SYN_CAP_PASS_THROUGH(priv->capabilities))
 		synaptics_pt_create(psmouse);
 
-#if defined(__i386__)
 	/*
 	 * Toshiba's KBC seems to have trouble handling data from
 	 * Synaptics as full rate, switch to lower rate which is roughly
 	 * thye same as rate of standard PS/2 mouse.
 	 */
-	if (psmouse->rate >= 80 && dmi_check_system(toshiba_dmi_table)) {
+	if (psmouse->rate >= 80 && impaired_toshiba_kbc) {
 		printk(KERN_INFO "synaptics: Toshiba %s detected, limiting rate to 40pps.\n",
 			dmi_get_system_info(DMI_PRODUCT_NAME));
 		psmouse->rate = 40;
 	}
-#endif
 
 	return 0;
 
@@ -740,6 +745,10 @@
 
 #else /* CONFIG_MOUSE_PS2_SYNAPTICS */
 
+void __init synaptics_module_init(void)
+{
+}
+
 int synaptics_init(struct psmouse *psmouse)
 {
 	return -ENOSYS;
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
index 871f6fe..838e7f2 100644
--- a/drivers/input/mouse/synaptics.h
+++ b/drivers/input/mouse/synaptics.h
@@ -105,6 +105,7 @@
 	int scroll;
 };
 
+void synaptics_module_init(void);
 int synaptics_detect(struct psmouse *psmouse, bool set_properties);
 int synaptics_init(struct psmouse *psmouse);
 void synaptics_reset(struct psmouse *psmouse);
diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c
index 7283c78..9867dfe 100644
--- a/drivers/input/mouse/synaptics_i2c.c
+++ b/drivers/input/mouse/synaptics_i2c.c
@@ -420,8 +420,8 @@
 }
 
 /* Control the Device polling rate / Work Handler sleep time */
-unsigned long synaptics_i2c_adjust_delay(struct synaptics_i2c *touch,
-					 bool have_data)
+static unsigned long synaptics_i2c_adjust_delay(struct synaptics_i2c *touch,
+						bool have_data)
 {
 	unsigned long delay, nodata_count_thres;
 
@@ -520,7 +520,7 @@
 	__set_bit(BTN_LEFT, input->keybit);
 }
 
-struct synaptics_i2c *synaptics_i2c_touch_create(struct i2c_client *client)
+static struct synaptics_i2c *synaptics_i2c_touch_create(struct i2c_client *client)
 {
 	struct synaptics_i2c *touch;
 
diff --git a/drivers/input/mouse/touchkit_ps2.c b/drivers/input/mouse/touchkit_ps2.c
index 0308a0f..909431c 100644
--- a/drivers/input/mouse/touchkit_ps2.c
+++ b/drivers/input/mouse/touchkit_ps2.c
@@ -86,7 +86,8 @@
 
 	if (set_properties) {
 		dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
-		__set_bit(BTN_TOUCH, dev->keybit);
+		dev->keybit[BIT_WORD(BTN_MOUSE)] = 0;
+		dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 		input_set_abs_params(dev, ABS_X, 0, TOUCHKIT_MAX_XC, 0, 0);
 		input_set_abs_params(dev, ABS_Y, 0, TOUCHKIT_MAX_YC, 0, 0);
 
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c
index e354362..63d4a67 100644
--- a/drivers/input/mouse/trackpoint.c
+++ b/drivers/input/mouse/trackpoint.c
@@ -284,7 +284,6 @@
 
 int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
 {
-	struct trackpoint_data *priv;
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
 	unsigned char firmware_id;
 	unsigned char button_info;
@@ -301,8 +300,8 @@
 		button_info = 0;
 	}
 
-	psmouse->private = priv = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL);
-	if (!priv)
+	psmouse->private = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL);
+	if (!psmouse->private)
 		return -1;
 
 	psmouse->vendor = "IBM";
@@ -311,7 +310,10 @@
 	psmouse->reconnect = trackpoint_reconnect;
 	psmouse->disconnect = trackpoint_disconnect;
 
-	trackpoint_defaults(priv);
+	if ((button_info & 0x0f) >= 3)
+		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
+
+	trackpoint_defaults(psmouse->private);
 	trackpoint_sync(psmouse);
 
 	error = sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group);
@@ -319,7 +321,8 @@
 		printk(KERN_ERR
 			"trackpoint.c: failed to create sysfs attributes, error: %d\n",
 			error);
-		kfree(priv);
+		kfree(psmouse->private);
+		psmouse->private = NULL;
 		return -1;
 	}
 
diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c
index 7011144..bf2c0c8 100644
--- a/drivers/input/mouse/vsxxxaa.c
+++ b/drivers/input/mouse/vsxxxaa.c
@@ -86,27 +86,28 @@
 
 #define DRIVER_DESC "Driver for DEC VSXXX-AA and -GA mice and VSXXX-AB tablet"
 
-MODULE_AUTHOR ("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
-MODULE_DESCRIPTION (DRIVER_DESC);
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
 
 #undef VSXXXAA_DEBUG
 #ifdef VSXXXAA_DEBUG
-#define DBG(x...) printk (x)
+#define DBG(x...) printk(x)
 #else
 #define DBG(x...) do {} while (0)
 #endif
 
 #define VSXXXAA_INTRO_MASK	0x80
 #define VSXXXAA_INTRO_HEAD	0x80
-#define IS_HDR_BYTE(x)		(((x) & VSXXXAA_INTRO_MASK)	\
-					== VSXXXAA_INTRO_HEAD)
+#define IS_HDR_BYTE(x)			\
+	(((x) & VSXXXAA_INTRO_MASK) == VSXXXAA_INTRO_HEAD)
 
 #define VSXXXAA_PACKET_MASK	0xe0
 #define VSXXXAA_PACKET_REL	0x80
 #define VSXXXAA_PACKET_ABS	0xc0
 #define VSXXXAA_PACKET_POR	0xa0
-#define MATCH_PACKET_TYPE(data, type)	(((data) & VSXXXAA_PACKET_MASK) == (type))
+#define MATCH_PACKET_TYPE(data, type)	\
+	(((data) & VSXXXAA_PACKET_MASK) == (type))
 
 
 
@@ -123,52 +124,50 @@
 	char phys[32];
 };
 
-static void
-vsxxxaa_drop_bytes (struct vsxxxaa *mouse, int num)
+static void vsxxxaa_drop_bytes(struct vsxxxaa *mouse, int num)
 {
-	if (num >= mouse->count)
+	if (num >= mouse->count) {
 		mouse->count = 0;
-	else {
-		memmove (mouse->buf, mouse->buf + num - 1, BUFLEN - num);
+	} else {
+		memmove(mouse->buf, mouse->buf + num - 1, BUFLEN - num);
 		mouse->count -= num;
 	}
 }
 
-static void
-vsxxxaa_queue_byte (struct vsxxxaa *mouse, unsigned char byte)
+static void vsxxxaa_queue_byte(struct vsxxxaa *mouse, unsigned char byte)
 {
 	if (mouse->count == BUFLEN) {
-		printk (KERN_ERR "%s on %s: Dropping a byte of full buffer.\n",
-				mouse->name, mouse->phys);
-		vsxxxaa_drop_bytes (mouse, 1);
+		printk(KERN_ERR "%s on %s: Dropping a byte of full buffer.\n",
+			mouse->name, mouse->phys);
+		vsxxxaa_drop_bytes(mouse, 1);
 	}
-	DBG (KERN_INFO "Queueing byte 0x%02x\n", byte);
+
+	DBG(KERN_INFO "Queueing byte 0x%02x\n", byte);
 
 	mouse->buf[mouse->count++] = byte;
 }
 
-static void
-vsxxxaa_detection_done (struct vsxxxaa *mouse)
+static void vsxxxaa_detection_done(struct vsxxxaa *mouse)
 {
 	switch (mouse->type) {
-		case 0x02:
-			strlcpy (mouse->name, "DEC VSXXX-AA/-GA mouse",
-				 sizeof (mouse->name));
-			break;
+	case 0x02:
+		strlcpy(mouse->name, "DEC VSXXX-AA/-GA mouse",
+			sizeof(mouse->name));
+		break;
 
-		case 0x04:
-			strlcpy (mouse->name, "DEC VSXXX-AB digitizer",
-				 sizeof (mouse->name));
-			break;
+	case 0x04:
+		strlcpy(mouse->name, "DEC VSXXX-AB digitizer",
+			sizeof(mouse->name));
+		break;
 
-		default:
-			snprintf (mouse->name, sizeof (mouse->name),
-				  "unknown DEC pointer device (type = 0x%02x)",
-				  mouse->type);
-			break;
+	default:
+		snprintf(mouse->name, sizeof(mouse->name),
+			 "unknown DEC pointer device (type = 0x%02x)",
+			 mouse->type);
+		break;
 	}
 
-	printk (KERN_INFO
+	printk(KERN_INFO
 		"Found %s version 0x%02x from country 0x%02x on port %s\n",
 		mouse->name, mouse->version, mouse->country, mouse->phys);
 }
@@ -176,42 +175,38 @@
 /*
  * Returns number of bytes to be dropped, 0 if packet is okay.
  */
-static int
-vsxxxaa_check_packet (struct vsxxxaa *mouse, int packet_len)
+static int vsxxxaa_check_packet(struct vsxxxaa *mouse, int packet_len)
 {
 	int i;
 
 	/* First byte must be a header byte */
-	if (!IS_HDR_BYTE (mouse->buf[0])) {
-		DBG ("vsck: len=%d, 1st=0x%02x\n", packet_len, mouse->buf[0]);
+	if (!IS_HDR_BYTE(mouse->buf[0])) {
+		DBG("vsck: len=%d, 1st=0x%02x\n", packet_len, mouse->buf[0]);
 		return 1;
 	}
 
 	/* Check all following bytes */
-	if (packet_len > 1) {
-		for (i = 1; i < packet_len; i++) {
-			if (IS_HDR_BYTE (mouse->buf[i])) {
-				printk (KERN_ERR "Need to drop %d bytes "
-						"of a broken packet.\n",
-						i - 1);
-				DBG (KERN_INFO "check: len=%d, b[%d]=0x%02x\n",
-						packet_len, i, mouse->buf[i]);
-				return i - 1;
-			}
+	for (i = 1; i < packet_len; i++) {
+		if (IS_HDR_BYTE(mouse->buf[i])) {
+			printk(KERN_ERR
+				"Need to drop %d bytes of a broken packet.\n",
+				i - 1);
+			DBG(KERN_INFO "check: len=%d, b[%d]=0x%02x\n",
+			    packet_len, i, mouse->buf[i]);
+			return i - 1;
 		}
 	}
 
 	return 0;
 }
 
-static __inline__ int
-vsxxxaa_smells_like_packet (struct vsxxxaa *mouse, unsigned char type, size_t len)
+static inline int vsxxxaa_smells_like_packet(struct vsxxxaa *mouse,
+					     unsigned char type, size_t len)
 {
-	return (mouse->count >= len) && MATCH_PACKET_TYPE (mouse->buf[0], type);
+	return mouse->count >= len && MATCH_PACKET_TYPE(mouse->buf[0], type);
 }
 
-static void
-vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse)
+static void vsxxxaa_handle_REL_packet(struct vsxxxaa *mouse)
 {
 	struct input_dev *dev = mouse->dev;
 	unsigned char *buf = mouse->buf;
@@ -232,43 +227,42 @@
 	 * 0, bit 4 of byte 0 is direction.
 	 */
 	dx = buf[1] & 0x7f;
-	dx *= ((buf[0] >> 4) & 0x01)? 1: -1;
+	dx *= ((buf[0] >> 4) & 0x01) ? 1 : -1;
 
 	/*
 	 * Low 7 bit of byte 2 are abs(dy), bit 7 is
 	 * 0, bit 3 of byte 0 is direction.
 	 */
 	dy = buf[2] & 0x7f;
-	dy *= ((buf[0] >> 3) & 0x01)? -1: 1;
+	dy *= ((buf[0] >> 3) & 0x01) ? -1 : 1;
 
 	/*
 	 * Get button state. It's the low three bits
 	 * (for three buttons) of byte 0.
 	 */
-	left	= (buf[0] & 0x04)? 1: 0;
-	middle	= (buf[0] & 0x02)? 1: 0;
-	right	= (buf[0] & 0x01)? 1: 0;
+	left	= buf[0] & 0x04;
+	middle	= buf[0] & 0x02;
+	right	= buf[0] & 0x01;
 
-	vsxxxaa_drop_bytes (mouse, 3);
+	vsxxxaa_drop_bytes(mouse, 3);
 
-	DBG (KERN_INFO "%s on %s: dx=%d, dy=%d, buttons=%s%s%s\n",
-			mouse->name, mouse->phys, dx, dy,
-			left? "L": "l", middle? "M": "m", right? "R": "r");
+	DBG(KERN_INFO "%s on %s: dx=%d, dy=%d, buttons=%s%s%s\n",
+	    mouse->name, mouse->phys, dx, dy,
+	    left ? "L" : "l", middle ? "M" : "m", right ? "R" : "r");
 
 	/*
 	 * Report what we've found so far...
 	 */
-	input_report_key (dev, BTN_LEFT, left);
-	input_report_key (dev, BTN_MIDDLE, middle);
-	input_report_key (dev, BTN_RIGHT, right);
-	input_report_key (dev, BTN_TOUCH, 0);
-	input_report_rel (dev, REL_X, dx);
-	input_report_rel (dev, REL_Y, dy);
-	input_sync (dev);
+	input_report_key(dev, BTN_LEFT, left);
+	input_report_key(dev, BTN_MIDDLE, middle);
+	input_report_key(dev, BTN_RIGHT, right);
+	input_report_key(dev, BTN_TOUCH, 0);
+	input_report_rel(dev, REL_X, dx);
+	input_report_rel(dev, REL_Y, dy);
+	input_sync(dev);
 }
 
-static void
-vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse)
+static void vsxxxaa_handle_ABS_packet(struct vsxxxaa *mouse)
 {
 	struct input_dev *dev = mouse->dev;
 	unsigned char *buf = mouse->buf;
@@ -296,32 +290,31 @@
 	/*
 	 * Get button state. It's bits <4..1> of byte 0.
 	 */
-	left	= (buf[0] & 0x02)? 1: 0;
-	middle	= (buf[0] & 0x04)? 1: 0;
-	right	= (buf[0] & 0x08)? 1: 0;
-	touch	= (buf[0] & 0x10)? 1: 0;
+	left	= buf[0] & 0x02;
+	middle	= buf[0] & 0x04;
+	right	= buf[0] & 0x08;
+	touch	= buf[0] & 0x10;
 
-	vsxxxaa_drop_bytes (mouse, 5);
+	vsxxxaa_drop_bytes(mouse, 5);
 
-	DBG (KERN_INFO "%s on %s: x=%d, y=%d, buttons=%s%s%s%s\n",
-			mouse->name, mouse->phys, x, y,
-			left? "L": "l", middle? "M": "m",
-			right? "R": "r", touch? "T": "t");
+	DBG(KERN_INFO "%s on %s: x=%d, y=%d, buttons=%s%s%s%s\n",
+	    mouse->name, mouse->phys, x, y,
+	    left ? "L" : "l", middle ? "M" : "m",
+	    right ? "R" : "r", touch ? "T" : "t");
 
 	/*
 	 * Report what we've found so far...
 	 */
-	input_report_key (dev, BTN_LEFT, left);
-	input_report_key (dev, BTN_MIDDLE, middle);
-	input_report_key (dev, BTN_RIGHT, right);
-	input_report_key (dev, BTN_TOUCH, touch);
-	input_report_abs (dev, ABS_X, x);
-	input_report_abs (dev, ABS_Y, y);
-	input_sync (dev);
+	input_report_key(dev, BTN_LEFT, left);
+	input_report_key(dev, BTN_MIDDLE, middle);
+	input_report_key(dev, BTN_RIGHT, right);
+	input_report_key(dev, BTN_TOUCH, touch);
+	input_report_abs(dev, ABS_X, x);
+	input_report_abs(dev, ABS_Y, y);
+	input_sync(dev);
 }
 
-static void
-vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse)
+static void vsxxxaa_handle_POR_packet(struct vsxxxaa *mouse)
 {
 	struct input_dev *dev = mouse->dev;
 	unsigned char *buf = mouse->buf;
@@ -356,24 +349,24 @@
 	 * (for three buttons) of byte 0. Maybe even the bit <3>
 	 * has some meaning if a tablet is attached.
 	 */
-	left	= (buf[0] & 0x04)? 1: 0;
-	middle	= (buf[0] & 0x02)? 1: 0;
-	right	= (buf[0] & 0x01)? 1: 0;
+	left	= buf[0] & 0x04;
+	middle	= buf[0] & 0x02;
+	right	= buf[0] & 0x01;
 
-	vsxxxaa_drop_bytes (mouse, 4);
-	vsxxxaa_detection_done (mouse);
+	vsxxxaa_drop_bytes(mouse, 4);
+	vsxxxaa_detection_done(mouse);
 
 	if (error <= 0x1f) {
 		/* No (serious) error. Report buttons */
-		input_report_key (dev, BTN_LEFT, left);
-		input_report_key (dev, BTN_MIDDLE, middle);
-		input_report_key (dev, BTN_RIGHT, right);
-		input_report_key (dev, BTN_TOUCH, 0);
-		input_sync (dev);
+		input_report_key(dev, BTN_LEFT, left);
+		input_report_key(dev, BTN_MIDDLE, middle);
+		input_report_key(dev, BTN_RIGHT, right);
+		input_report_key(dev, BTN_TOUCH, 0);
+		input_sync(dev);
 
 		if (error != 0)
-			printk (KERN_INFO "Your %s on %s reports error=0x%02x\n",
-					mouse->name, mouse->phys, error);
+			printk(KERN_INFO "Your %s on %s reports error=0x%02x\n",
+				mouse->name, mouse->phys, error);
 
 	}
 
@@ -381,18 +374,18 @@
 	 * If the mouse was hot-plugged, we need to force differential mode
 	 * now... However, give it a second to recover from it's reset.
 	 */
-	printk (KERN_NOTICE "%s on %s: Forceing standard packet format, "
-			"incremental streaming mode and 72 samples/sec\n",
-			mouse->name, mouse->phys);
-	serio_write (mouse->serio, 'S');	/* Standard format */
-	mdelay (50);
-	serio_write (mouse->serio, 'R');	/* Incremental */
-	mdelay (50);
-	serio_write (mouse->serio, 'L');	/* 72 samples/sec */
+	printk(KERN_NOTICE
+		"%s on %s: Forcing standard packet format, "
+		"incremental streaming mode and 72 samples/sec\n",
+		mouse->name, mouse->phys);
+	serio_write(mouse->serio, 'S');	/* Standard format */
+	mdelay(50);
+	serio_write(mouse->serio, 'R');	/* Incremental */
+	mdelay(50);
+	serio_write(mouse->serio, 'L');	/* 72 samples/sec */
 }
 
-static void
-vsxxxaa_parse_buffer (struct vsxxxaa *mouse)
+static void vsxxxaa_parse_buffer(struct vsxxxaa *mouse)
 {
 	unsigned char *buf = mouse->buf;
 	int stray_bytes;
@@ -409,122 +402,107 @@
 		 * activity on the mouse.
 		 */
 		while (mouse->count > 0 && !IS_HDR_BYTE(buf[0])) {
-			printk (KERN_ERR "%s on %s: Dropping a byte to regain "
-					"sync with mouse data stream...\n",
-					mouse->name, mouse->phys);
-			vsxxxaa_drop_bytes (mouse, 1);
+			printk(KERN_ERR "%s on %s: Dropping a byte to regain "
+				"sync with mouse data stream...\n",
+				mouse->name, mouse->phys);
+			vsxxxaa_drop_bytes(mouse, 1);
 		}
 
 		/*
 		 * Check for packets we know about.
 		 */
 
-		if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_REL, 3)) {
+		if (vsxxxaa_smells_like_packet(mouse, VSXXXAA_PACKET_REL, 3)) {
 			/* Check for broken packet */
-			stray_bytes = vsxxxaa_check_packet (mouse, 3);
-			if (stray_bytes > 0) {
-				printk (KERN_ERR "Dropping %d bytes now...\n",
-						stray_bytes);
-				vsxxxaa_drop_bytes (mouse, stray_bytes);
-				continue;
-			}
+			stray_bytes = vsxxxaa_check_packet(mouse, 3);
+			if (!stray_bytes)
+				vsxxxaa_handle_REL_packet(mouse);
 
-			vsxxxaa_handle_REL_packet (mouse);
-			continue; /* More to parse? */
+		} else if (vsxxxaa_smells_like_packet(mouse,
+						      VSXXXAA_PACKET_ABS, 5)) {
+			/* Check for broken packet */
+			stray_bytes = vsxxxaa_check_packet(mouse, 5);
+			if (!stray_bytes)
+				vsxxxaa_handle_ABS_packet(mouse);
+
+		} else if (vsxxxaa_smells_like_packet(mouse,
+						      VSXXXAA_PACKET_POR, 4)) {
+			/* Check for broken packet */
+			stray_bytes = vsxxxaa_check_packet(mouse, 4);
+			if (!stray_bytes)
+				vsxxxaa_handle_POR_packet(mouse);
+
+		} else {
+			break; /* No REL, ABS or POR packet found */
 		}
 
-		if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_ABS, 5)) {
-			/* Check for broken packet */
-			stray_bytes = vsxxxaa_check_packet (mouse, 5);
-			if (stray_bytes > 0) {
-				printk (KERN_ERR "Dropping %d bytes now...\n",
-						stray_bytes);
-				vsxxxaa_drop_bytes (mouse, stray_bytes);
-				continue;
-			}
-
-			vsxxxaa_handle_ABS_packet (mouse);
-			continue; /* More to parse? */
+		if (stray_bytes > 0) {
+			printk(KERN_ERR "Dropping %d bytes now...\n",
+				stray_bytes);
+			vsxxxaa_drop_bytes(mouse, stray_bytes);
 		}
 
-		if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_POR, 4)) {
-			/* Check for broken packet */
-			stray_bytes = vsxxxaa_check_packet (mouse, 4);
-			if (stray_bytes > 0) {
-				printk (KERN_ERR "Dropping %d bytes now...\n",
-						stray_bytes);
-				vsxxxaa_drop_bytes (mouse, stray_bytes);
-				continue;
-			}
-
-			vsxxxaa_handle_POR_packet (mouse);
-			continue; /* More to parse? */
-		}
-
-		break; /* No REL, ABS or POR packet found */
 	} while (1);
 }
 
-static irqreturn_t
-vsxxxaa_interrupt (struct serio *serio, unsigned char data, unsigned int flags)
+static irqreturn_t vsxxxaa_interrupt(struct serio *serio,
+				     unsigned char data, unsigned int flags)
 {
-	struct vsxxxaa *mouse = serio_get_drvdata (serio);
+	struct vsxxxaa *mouse = serio_get_drvdata(serio);
 
-	vsxxxaa_queue_byte (mouse, data);
-	vsxxxaa_parse_buffer (mouse);
+	vsxxxaa_queue_byte(mouse, data);
+	vsxxxaa_parse_buffer(mouse);
 
 	return IRQ_HANDLED;
 }
 
-static void
-vsxxxaa_disconnect (struct serio *serio)
+static void vsxxxaa_disconnect(struct serio *serio)
 {
-	struct vsxxxaa *mouse = serio_get_drvdata (serio);
+	struct vsxxxaa *mouse = serio_get_drvdata(serio);
 
-	serio_close (serio);
-	serio_set_drvdata (serio, NULL);
-	input_unregister_device (mouse->dev);
-	kfree (mouse);
+	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
+	input_unregister_device(mouse->dev);
+	kfree(mouse);
 }
 
-static int
-vsxxxaa_connect (struct serio *serio, struct serio_driver *drv)
+static int vsxxxaa_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct vsxxxaa *mouse;
 	struct input_dev *input_dev;
 	int err = -ENOMEM;
 
-	mouse = kzalloc (sizeof (struct vsxxxaa), GFP_KERNEL);
-	input_dev = input_allocate_device ();
+	mouse = kzalloc(sizeof(struct vsxxxaa), GFP_KERNEL);
+	input_dev = input_allocate_device();
 	if (!mouse || !input_dev)
 		goto fail1;
 
 	mouse->dev = input_dev;
 	mouse->serio = serio;
-	strlcat (mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer",
-		 sizeof (mouse->name));
-	snprintf (mouse->phys, sizeof (mouse->phys), "%s/input0", serio->phys);
+	strlcat(mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer",
+		 sizeof(mouse->name));
+	snprintf(mouse->phys, sizeof(mouse->phys), "%s/input0", serio->phys);
 
 	input_dev->name = mouse->name;
 	input_dev->phys = mouse->phys;
 	input_dev->id.bustype = BUS_RS232;
 	input_dev->dev.parent = &serio->dev;
 
-	set_bit (EV_KEY, input_dev->evbit);		/* We have buttons */
-	set_bit (EV_REL, input_dev->evbit);
-	set_bit (EV_ABS, input_dev->evbit);
-	set_bit (BTN_LEFT, input_dev->keybit);		/* We have 3 buttons */
-	set_bit (BTN_MIDDLE, input_dev->keybit);
-	set_bit (BTN_RIGHT, input_dev->keybit);
-	set_bit (BTN_TOUCH, input_dev->keybit);		/* ...and Tablet */
-	set_bit (REL_X, input_dev->relbit);
-	set_bit (REL_Y, input_dev->relbit);
-	input_set_abs_params (input_dev, ABS_X, 0, 1023, 0, 0);
-	input_set_abs_params (input_dev, ABS_Y, 0, 1023, 0, 0);
+	__set_bit(EV_KEY, input_dev->evbit);		/* We have buttons */
+	__set_bit(EV_REL, input_dev->evbit);
+	__set_bit(EV_ABS, input_dev->evbit);
+	__set_bit(BTN_LEFT, input_dev->keybit);		/* We have 3 buttons */
+	__set_bit(BTN_MIDDLE, input_dev->keybit);
+	__set_bit(BTN_RIGHT, input_dev->keybit);
+	__set_bit(BTN_TOUCH, input_dev->keybit);	/* ...and Tablet */
+	__set_bit(REL_X, input_dev->relbit);
+	__set_bit(REL_Y, input_dev->relbit);
+	input_set_abs_params(input_dev, ABS_X, 0, 1023, 0, 0);
+	input_set_abs_params(input_dev, ABS_Y, 0, 1023, 0, 0);
 
-	serio_set_drvdata (serio, mouse);
+	serio_set_drvdata(serio, mouse);
 
-	err = serio_open (serio, drv);
+	err = serio_open(serio, drv);
 	if (err)
 		goto fail2;
 
@@ -532,18 +510,18 @@
 	 * Request selftest. Standard packet format and differential
 	 * mode will be requested after the device ID'ed successfully.
 	 */
-	serio_write (serio, 'T'); /* Test */
+	serio_write(serio, 'T'); /* Test */
 
-	err = input_register_device (input_dev);
+	err = input_register_device(input_dev);
 	if (err)
 		goto fail3;
 
 	return 0;
 
- fail3:	serio_close (serio);
- fail2:	serio_set_drvdata (serio, NULL);
- fail1:	input_free_device (input_dev);
-	kfree (mouse);
+ fail3:	serio_close(serio);
+ fail2:	serio_set_drvdata(serio, NULL);
+ fail1:	input_free_device(input_dev);
+	kfree(mouse);
 	return err;
 }
 
@@ -570,18 +548,16 @@
 	.disconnect	= vsxxxaa_disconnect,
 };
 
-static int __init
-vsxxxaa_init (void)
+static int __init vsxxxaa_init(void)
 {
 	return serio_register_driver(&vsxxxaa_drv);
 }
 
-static void __exit
-vsxxxaa_exit (void)
+static void __exit vsxxxaa_exit(void)
 {
 	serio_unregister_driver(&vsxxxaa_drv);
 }
 
-module_init (vsxxxaa_init);
-module_exit (vsxxxaa_exit);
+module_init(vsxxxaa_init);
+module_exit(vsxxxaa_exit);
 
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
index aa533ce..7e319d6 100644
--- a/drivers/input/serio/Kconfig
+++ b/drivers/input/serio/Kconfig
@@ -201,4 +201,12 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called xilinx_ps2.
 
+config SERIO_ALTERA_PS2
+	tristate "Altera UP PS/2 controller"
+	help
+	  Say Y here if you have Altera University Program PS/2 ports.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called altera_ps2.
+
 endif
diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile
index 9b6c813..bf945f7 100644
--- a/drivers/input/serio/Makefile
+++ b/drivers/input/serio/Makefile
@@ -22,3 +22,4 @@
 obj-$(CONFIG_SERIO_LIBPS2)	+= libps2.o
 obj-$(CONFIG_SERIO_RAW)		+= serio_raw.o
 obj-$(CONFIG_SERIO_XILINX_XPS_PS2)	+= xilinx_ps2.o
+obj-$(CONFIG_SERIO_ALTERA_PS2)	+= altera_ps2.o
diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c
new file mode 100644
index 0000000..f479ea5
--- /dev/null
+++ b/drivers/input/serio/altera_ps2.c
@@ -0,0 +1,200 @@
+/*
+ * Altera University Program PS2 controller driver
+ *
+ * Copyright (C) 2008 Thomas Chou <thomas@wytron.com.tw>
+ *
+ * Based on sa1111ps2.c, which is:
+ * Copyright (C) 2002 Russell King
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#define DRV_NAME "altera_ps2"
+
+struct ps2if {
+	struct serio *io;
+	struct resource *iomem_res;
+	void __iomem *base;
+	unsigned irq;
+};
+
+/*
+ * Read all bytes waiting in the PS2 port.  There should be
+ * at the most one, but we loop for safety.
+ */
+static irqreturn_t altera_ps2_rxint(int irq, void *dev_id)
+{
+	struct ps2if *ps2if = dev_id;
+	unsigned int status;
+	int handled = IRQ_NONE;
+
+	while ((status = readl(ps2if->base)) & 0xffff0000) {
+		serio_interrupt(ps2if->io, status & 0xff, 0);
+		handled = IRQ_HANDLED;
+	}
+
+	return handled;
+}
+
+/*
+ * Write a byte to the PS2 port.
+ */
+static int altera_ps2_write(struct serio *io, unsigned char val)
+{
+	struct ps2if *ps2if = io->port_data;
+
+	writel(val, ps2if->base);
+	return 0;
+}
+
+static int altera_ps2_open(struct serio *io)
+{
+	struct ps2if *ps2if = io->port_data;
+
+	/* clear fifo */
+	while (readl(ps2if->base) & 0xffff0000)
+		/* empty */;
+
+	writel(1, ps2if->base + 4); /* enable rx irq */
+	return 0;
+}
+
+static void altera_ps2_close(struct serio *io)
+{
+	struct ps2if *ps2if = io->port_data;
+
+	writel(0, ps2if->base); /* disable rx irq */
+}
+
+/*
+ * Add one device to this driver.
+ */
+static int altera_ps2_probe(struct platform_device *pdev)
+{
+	struct ps2if *ps2if;
+	struct serio *serio;
+	int error;
+
+	ps2if = kzalloc(sizeof(struct ps2if), GFP_KERNEL);
+	serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+	if (!ps2if || !serio) {
+		error = -ENOMEM;
+		goto err_free_mem;
+	}
+
+	serio->id.type		= SERIO_8042;
+	serio->write		= altera_ps2_write;
+	serio->open		= altera_ps2_open;
+	serio->close		= altera_ps2_close;
+	strlcpy(serio->name, dev_name(&pdev->dev), sizeof(serio->name));
+	strlcpy(serio->phys, dev_name(&pdev->dev), sizeof(serio->phys));
+	serio->port_data	= ps2if;
+	serio->dev.parent	= &pdev->dev;
+	ps2if->io		= serio;
+
+	ps2if->iomem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (ps2if->iomem_res == NULL) {
+		error = -ENOENT;
+		goto err_free_mem;
+	}
+
+	ps2if->irq  = platform_get_irq(pdev, 0);
+	if (ps2if->irq < 0) {
+		error = -ENXIO;
+		goto err_free_mem;
+	}
+
+	if (!request_mem_region(ps2if->iomem_res->start,
+				resource_size(ps2if->iomem_res), pdev->name)) {
+		error = -EBUSY;
+		goto err_free_mem;
+	}
+
+	ps2if->base = ioremap(ps2if->iomem_res->start,
+			      resource_size(ps2if->iomem_res));
+	if (!ps2if->base) {
+		error = -ENOMEM;
+		goto err_free_res;
+	}
+
+	error = request_irq(ps2if->irq, altera_ps2_rxint, 0, pdev->name, ps2if);
+	if (error) {
+		dev_err(&pdev->dev, "could not allocate IRQ %d: %d\n",
+			ps2if->irq, error);
+		goto err_unmap;
+	}
+
+	dev_info(&pdev->dev, "base %p, irq %d\n", ps2if->base, ps2if->irq);
+
+	serio_register_port(ps2if->io);
+	platform_set_drvdata(pdev, ps2if);
+
+	return 0;
+
+ err_unmap:
+	iounmap(ps2if->base);
+ err_free_res:
+	release_mem_region(ps2if->iomem_res->start,
+			   resource_size(ps2if->iomem_res));
+ err_free_mem:
+	kfree(ps2if);
+	kfree(serio);
+	return error;
+}
+
+/*
+ * Remove one device from this driver.
+ */
+static int altera_ps2_remove(struct platform_device *pdev)
+{
+	struct ps2if *ps2if = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+	serio_unregister_port(ps2if->io);
+	free_irq(ps2if->irq, ps2if);
+	iounmap(ps2if->base);
+	release_mem_region(ps2if->iomem_res->start,
+			   resource_size(ps2if->iomem_res));
+	kfree(ps2if);
+
+	return 0;
+}
+
+/*
+ * Our device driver structure
+ */
+static struct platform_driver altera_ps2_driver = {
+	.probe		= altera_ps2_probe,
+	.remove		= altera_ps2_remove,
+	.driver	= {
+		.name	= DRV_NAME,
+	},
+};
+
+static int __init altera_ps2_init(void)
+{
+	return platform_driver_register(&altera_ps2_driver);
+}
+
+static void __exit altera_ps2_exit(void)
+{
+	platform_driver_unregister(&altera_ps2_driver);
+}
+
+module_init(altera_ps2_init);
+module_exit(altera_ps2_exit);
+
+MODULE_DESCRIPTION("Altera University Program PS2 controller driver");
+MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c
index 1c9410d..bcc2d30 100644
--- a/drivers/input/serio/hp_sdc.c
+++ b/drivers/input/serio/hp_sdc.c
@@ -955,7 +955,7 @@
 	INIT_DELAYED_WORK(&moduleloader_work, request_module_delayed);
 
 	ret = hp_sdc_init();
-	/* after sucessfull initialization give SDC some time to settle
+	/* after successfull initialization give SDC some time to settle
 	 * and then load the hp_sdc_mlc upper layer driver */
 	if (!ret)
 		schedule_delayed_work(&moduleloader_work,
diff --git a/drivers/input/serio/hp_sdc_mlc.c b/drivers/input/serio/hp_sdc_mlc.c
index 820e516..7d2b820 100644
--- a/drivers/input/serio/hp_sdc_mlc.c
+++ b/drivers/input/serio/hp_sdc_mlc.c
@@ -125,7 +125,7 @@
 		break;
 
 	default:
-		printk(KERN_WARNING PREFIX "Unkown HIL Error status (%x)!\n", data);
+		printk(KERN_WARNING PREFIX "Unknown HIL Error status (%x)!\n", data);
 		break;
 	}
 
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 2bcf1ac..7fbffe4 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -67,10 +67,12 @@
 
 #include <linux/dmi.h>
 
-static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = {
+static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
 	{
-		/* AUX LOOP command does not raise AUX IRQ */
-		.ident = "Arima-Rioworks HDAMB",
+		/*
+		 * Arima-Rioworks HDAMB -
+		 * AUX LOOP command does not raise AUX IRQ
+		 */
 		.matches = {
 			DMI_MATCH(DMI_BOARD_VENDOR, "RIOWORKS"),
 			DMI_MATCH(DMI_BOARD_NAME, "HDAMB"),
@@ -78,7 +80,7 @@
 		},
 	},
 	{
-		.ident = "ASUS G1S",
+		/* ASUS G1S */
 		.matches = {
 			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
 			DMI_MATCH(DMI_BOARD_NAME, "G1S"),
@@ -86,8 +88,7 @@
 		},
 	},
 	{
-		/* AUX LOOP command does not raise AUX IRQ */
-		.ident = "ASUS P65UP5",
+		/* ASUS P65UP5 - AUX LOOP command does not raise AUX IRQ */
 		.matches = {
 			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
 			DMI_MATCH(DMI_BOARD_NAME, "P/I-P65UP5"),
@@ -95,7 +96,6 @@
 		},
 	},
 	{
-		.ident = "Compaq Proliant 8500",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
 			DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
@@ -103,7 +103,6 @@
 		},
 	},
 	{
-		.ident = "Compaq Proliant DL760",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
 			DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
@@ -111,7 +110,7 @@
 		},
 	},
 	{
-		.ident = "OQO Model 01",
+		/* OQO Model 01 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "OQO"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"),
@@ -119,8 +118,7 @@
 		},
 	},
 	{
-		/* AUX LOOP does not work properly */
-		.ident = "ULI EV4873",
+		/* ULI EV4873 - AUX LOOP does not work properly */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ULI"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "EV4873"),
@@ -128,7 +126,7 @@
 		},
 	},
 	{
-		.ident = "Microsoft Virtual Machine",
+		/* Microsoft Virtual Machine */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
@@ -136,7 +134,7 @@
 		},
 	},
 	{
-		.ident = "Medion MAM 2070",
+		/* Medion MAM 2070 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070"),
@@ -144,7 +142,7 @@
 		},
 	},
 	{
-		.ident = "Blue FB5601",
+		/* Blue FB5601 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "blue"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "FB5601"),
@@ -152,7 +150,7 @@
 		},
 	},
 	{
-		.ident = "Gigabyte M912",
+		/* Gigabyte M912 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "M912"),
@@ -160,7 +158,6 @@
 		},
 	},
 	{
-		.ident = "HP DV9700",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"),
@@ -177,72 +174,72 @@
  * ... apparently some Toshibas don't like MUX mode either and
  * die horrible death on reboot.
  */
-static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
+static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
 	{
-		.ident = "Fujitsu Lifebook P7010/P7010D",
+		/* Fujitsu Lifebook P7010/P7010D */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "P7010"),
 		},
 	},
 	{
-		.ident = "Fujitsu Lifebook P7010",
+		/* Fujitsu Lifebook P7010 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"),
 		},
 	},
 	{
-		.ident = "Fujitsu Lifebook P5020D",
+		/* Fujitsu Lifebook P5020D */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series"),
 		},
 	},
 	{
-		.ident = "Fujitsu Lifebook S2000",
+		/* Fujitsu Lifebook S2000 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"),
 		},
 	},
 	{
-		.ident = "Fujitsu Lifebook S6230",
+		/* Fujitsu Lifebook S6230 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"),
 		},
 	},
 	{
-		.ident = "Fujitsu T70H",
+		/* Fujitsu T70H */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"),
 		},
 	},
 	{
-		.ident = "Fujitsu-Siemens Lifebook T3010",
+		/* Fujitsu-Siemens Lifebook T3010 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"),
 		},
 	},
 	{
-		.ident = "Fujitsu-Siemens Lifebook E4010",
+		/* Fujitsu-Siemens Lifebook E4010 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"),
 		},
 	},
 	{
-		.ident = "Fujitsu-Siemens Amilo Pro 2010",
+		/* Fujitsu-Siemens Amilo Pro 2010 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2010"),
 		},
 	},
 	{
-		.ident = "Fujitsu-Siemens Amilo Pro 2030",
+		/* Fujitsu-Siemens Amilo Pro 2030 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"),
@@ -253,7 +250,7 @@
 		 * No data is coming from the touchscreen unless KBC
 		 * is in legacy mode.
 		 */
-		.ident = "Panasonic CF-29",
+		/* Panasonic CF-29 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"),
@@ -261,10 +258,10 @@
 	},
 	{
 		/*
-		 * Errors on MUX ports are reported without raising AUXDATA
+		 * HP Pavilion DV4017EA -
+		 * errors on MUX ports are reported without raising AUXDATA
 		 * causing "spurious NAK" messages.
 		 */
-		.ident = "HP Pavilion DV4017EA",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"),
@@ -272,9 +269,9 @@
 	},
 	{
 		/*
-		 * Like DV4017EA does not raise AUXERR for errors on MUX ports.
+		 * HP Pavilion ZT1000 -
+		 * like DV4017EA does not raise AUXERR for errors on MUX ports.
 		 */
-		.ident = "HP Pavilion ZT1000",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"),
@@ -283,44 +280,41 @@
 	},
 	{
 		/*
-		 * Like DV4017EA does not raise AUXERR for errors on MUX ports.
+		 * HP Pavilion DV4270ca -
+		 * like DV4017EA does not raise AUXERR for errors on MUX ports.
 		 */
-		.ident = "HP Pavilion DV4270ca",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)"),
 		},
 	},
 	{
-		.ident = "Toshiba P10",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"),
 		},
 	},
 	{
-		.ident = "Toshiba Equium A110",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"),
 		},
 	},
 	{
-		.ident = "Alienware Sentia",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"),
 		},
 	},
 	{
-		.ident = "Sharp Actius MM20",
+		/* Sharp Actius MM20 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "SHARP"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"),
 		},
 	},
 	{
-		.ident = "Sony Vaio FS-115b",
+		/* Sony Vaio FS-115b */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"),
@@ -328,73 +322,72 @@
 	},
 	{
 		/*
-		 * Reset and GET ID commands issued via KBD port are
+		 * Sony Vaio FZ-240E -
+		 * reset and GET ID commands issued via KBD port are
 		 * sometimes being delivered to AUX3.
 		 */
-		.ident = "Sony Vaio FZ-240E",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"),
 		},
 	},
 	{
-		.ident = "Amoi M636/A737",
+		/* Amoi M636/A737 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
 		},
 	},
 	{
-		.ident = "Lenovo 3000 n100",
+		/* Lenovo 3000 n100 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "076804U"),
 		},
 	},
 	{
-		.ident = "Acer Aspire 1360",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"),
 		},
 	},
 	{
-		.ident = "Gericom Bellagio",
+		/* Gericom Bellagio */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Gericom"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"),
 		},
 	},
 	{
-		.ident = "IBM 2656",
+		/* IBM 2656 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "2656"),
 		},
 	},
 	{
-		.ident = "Dell XPS M1530",
+		/* Dell XPS M1530 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"),
 		},
 	},
 	{
-		.ident = "Compal HEL80I",
+		/* Compal HEL80I */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"),
 		},
 	},
 	{
-		.ident = "Dell Vostro 1510",
+		/* Dell Vostro 1510 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"),
 		},
 	},
 	{
-		.ident = "Acer Aspire 5536",
+		/* Acer Aspire 5536 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"),
@@ -404,65 +397,65 @@
 	{ }
 };
 
-static struct dmi_system_id __initdata i8042_dmi_reset_table[] = {
+static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
 	{
-		.ident = "MSI Wind U-100",
+		/* MSI Wind U-100 */
 		.matches = {
 			DMI_MATCH(DMI_BOARD_NAME, "U-100"),
 			DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
 		},
 	},
 	{
-		.ident = "LG Electronics X110",
+		/* LG Electronics X110 */
 		.matches = {
 			DMI_MATCH(DMI_BOARD_NAME, "X110"),
 			DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."),
 		},
 	},
 	{
-		.ident = "Acer Aspire One 150",
+		/* Acer Aspire One 150 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"),
 		},
 	},
 	{
-		.ident = "Advent 4211",
+		/* Advent 4211 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211"),
 		},
 	},
 	{
-		.ident = "Medion Akoya Mini E1210",
+		/* Medion Akoya Mini E1210 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "E1210"),
 		},
 	},
 	{
-		.ident = "Mivvy M310",
+		/* Mivvy M310 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "N10"),
 		},
 	},
 	{
-		.ident = "Dell Vostro 1320",
+		/* Dell Vostro 1320 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"),
 		},
 	},
 	{
-		.ident = "Dell Vostro 1520",
+		/* Dell Vostro 1520 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"),
 		},
 	},
 	{
-		.ident = "Dell Vostro 1720",
+		/* Dell Vostro 1720 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"),
@@ -472,16 +465,16 @@
 };
 
 #ifdef CONFIG_PNP
-static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = {
+static const struct dmi_system_id __initconst i8042_dmi_nopnp_table[] = {
 	{
-		.ident = "Intel MBO Desktop D845PESV",
+		/* Intel MBO Desktop D845PESV */
 		.matches = {
 			DMI_MATCH(DMI_BOARD_NAME, "D845PESV"),
 			DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
 		},
 	},
 	{
-		.ident = "MSI Wind U-100",
+		/* MSI Wind U-100 */
 		.matches = {
 			DMI_MATCH(DMI_BOARD_NAME, "U-100"),
 			DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
@@ -490,27 +483,23 @@
 	{ }
 };
 
-static struct dmi_system_id __initdata i8042_dmi_laptop_table[] = {
+static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = {
 	{
-		.ident = "Portable",
 		.matches = {
 			DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
 		},
 	},
 	{
-		.ident = "Laptop",
 		.matches = {
 			DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /* Laptop */
 		},
 	},
 	{
-		.ident = "Notebook",
 		.matches = {
 			DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */
 		},
 	},
 	{
-		.ident = "Sub-Notebook",
 		.matches = {
 			DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */
 		},
@@ -525,58 +514,58 @@
  * Originally, this was just confined to older laptops, but a few Acer laptops
  * have turned up in 2007 that also need this again.
  */
-static struct dmi_system_id __initdata i8042_dmi_dritek_table[] = {
+static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = {
 	{
-		.ident = "Acer Aspire 5630",
+		/* Acer Aspire 5630 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"),
 		},
 	},
 	{
-		.ident = "Acer Aspire 5650",
+		/* Acer Aspire 5650 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"),
 		},
 	},
 	{
-		.ident = "Acer Aspire 5680",
+		/* Acer Aspire 5680 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"),
 		},
 	},
 	{
-		.ident = "Acer Aspire 5720",
+		/* Acer Aspire 5720 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"),
 		},
 	},
 	{
-		.ident = "Acer Aspire 9110",
+		/* Acer Aspire 9110 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"),
 		},
 	},
 	{
-		.ident = "Acer TravelMate 660",
+		/* Acer TravelMate 660 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"),
 		},
 	},
 	{
-		.ident = "Acer TravelMate 2490",
+		/* Acer TravelMate 2490 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"),
 		},
 	},
 	{
-		.ident = "Acer TravelMate 4280",
+		/* Acer TravelMate 4280 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"),
diff --git a/drivers/input/sparse-keymap.c b/drivers/input/sparse-keymap.c
new file mode 100644
index 0000000..fbd3987
--- /dev/null
+++ b/drivers/input/sparse-keymap.c
@@ -0,0 +1,250 @@
+/*
+ * Generic support for sparse keymaps
+ *
+ * Copyright (c) 2009 Dmitry Torokhov
+ *
+ * Derived from wistron button driver:
+ * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
+ * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
+ * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
+ *
+ * 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.
+ */
+
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
+
+MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
+MODULE_DESCRIPTION("Generic support for sparse keymaps");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("0.1");
+
+/**
+ * sparse_keymap_entry_from_scancode - perform sparse keymap lookup
+ * @dev: Input device using sparse keymap
+ * @code: Scan code
+ *
+ * This function is used to perform &struct key_entry lookup in an
+ * input device using sparse keymap.
+ */
+struct key_entry *sparse_keymap_entry_from_scancode(struct input_dev *dev,
+						    unsigned int code)
+{
+	struct key_entry *key;
+
+	for (key = dev->keycode; key->type != KE_END; key++)
+		if (code == key->code)
+			return key;
+
+	return NULL;
+}
+EXPORT_SYMBOL(sparse_keymap_entry_from_scancode);
+
+/**
+ * sparse_keymap_entry_from_keycode - perform sparse keymap lookup
+ * @dev: Input device using sparse keymap
+ * @keycode: Key code
+ *
+ * This function is used to perform &struct key_entry lookup in an
+ * input device using sparse keymap.
+ */
+struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev,
+						   unsigned int keycode)
+{
+	struct key_entry *key;
+
+	for (key = dev->keycode; key->type != KE_END; key++)
+		if (key->type == KE_KEY && keycode == key->keycode)
+			return key;
+
+	return NULL;
+}
+EXPORT_SYMBOL(sparse_keymap_entry_from_keycode);
+
+static int sparse_keymap_getkeycode(struct input_dev *dev,
+				    int scancode, int *keycode)
+{
+	const struct key_entry *key =
+			sparse_keymap_entry_from_scancode(dev, scancode);
+
+	if (key && key->type == KE_KEY) {
+		*keycode = key->keycode;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int sparse_keymap_setkeycode(struct input_dev *dev,
+				    int scancode, int keycode)
+{
+	struct key_entry *key;
+	int old_keycode;
+
+	if (keycode < 0 || keycode > KEY_MAX)
+		return -EINVAL;
+
+	key = sparse_keymap_entry_from_scancode(dev, scancode);
+	if (key && key->type == KE_KEY) {
+		old_keycode = key->keycode;
+		key->keycode = keycode;
+		set_bit(keycode, dev->keybit);
+		if (!sparse_keymap_entry_from_keycode(dev, old_keycode))
+			clear_bit(old_keycode, dev->keybit);
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+/**
+ * sparse_keymap_setup - set up sparse keymap for an input device
+ * @dev: Input device
+ * @keymap: Keymap in form of array of &key_entry structures ending
+ *	with %KE_END type entry
+ * @setup: Function that can be used to adjust keymap entries
+ *	depending on device's deeds, may be %NULL
+ *
+ * The function calculates size and allocates copy of the original
+ * keymap after which sets up input device event bits appropriately.
+ * Before destroying input device allocated keymap should be freed
+ * with a call to sparse_keymap_free().
+ */
+int sparse_keymap_setup(struct input_dev *dev,
+			const struct key_entry *keymap,
+			int (*setup)(struct input_dev *, struct key_entry *))
+{
+	size_t map_size = 1; /* to account for the last KE_END entry */
+	const struct key_entry *e;
+	struct key_entry *map, *entry;
+	int i;
+	int error;
+
+	for (e = keymap; e->type != KE_END; e++)
+		map_size++;
+
+	map = kcalloc(map_size, sizeof (struct key_entry), GFP_KERNEL);
+	if (!map)
+		return -ENOMEM;
+
+	memcpy(map, keymap, map_size * sizeof (struct key_entry));
+
+	for (i = 0; i < map_size; i++) {
+		entry = &map[i];
+
+		if (setup) {
+			error = setup(dev, entry);
+			if (error)
+				goto err_out;
+		}
+
+		switch (entry->type) {
+		case KE_KEY:
+			__set_bit(EV_KEY, dev->evbit);
+			__set_bit(entry->keycode, dev->keybit);
+			break;
+
+		case KE_SW:
+			__set_bit(EV_SW, dev->evbit);
+			__set_bit(entry->sw.code, dev->swbit);
+			break;
+		}
+	}
+
+	dev->keycode = map;
+	dev->keycodemax = map_size;
+	dev->getkeycode = sparse_keymap_getkeycode;
+	dev->setkeycode = sparse_keymap_setkeycode;
+
+	return 0;
+
+ err_out:
+	kfree(keymap);
+	return error;
+
+}
+EXPORT_SYMBOL(sparse_keymap_setup);
+
+/**
+ * sparse_keymap_free - free memory allocated for sparse keymap
+ * @dev: Input device using sparse keymap
+ *
+ * This function is used to free memory allocated by sparse keymap
+ * in an input device that was set up by sparse_keymap_setup().
+ */
+void sparse_keymap_free(struct input_dev *dev)
+{
+	kfree(dev->keycode);
+	dev->keycode = NULL;
+	dev->keycodemax = 0;
+	dev->getkeycode = NULL;
+	dev->setkeycode = NULL;
+}
+EXPORT_SYMBOL(sparse_keymap_free);
+
+/**
+ * sparse_keymap_report_entry - report event corresponding to given key entry
+ * @dev: Input device for which event should be reported
+ * @ke: key entry describing event
+ * @value: Value that should be reported (ignored by %KE_SW entries)
+ * @autorelease: Signals whether release event should be emitted for %KE_KEY
+ *	entries right after reporting press event, ignored by all other
+ *	entries
+ *
+ * This function is used to report input event described by given
+ * &struct key_entry.
+ */
+void sparse_keymap_report_entry(struct input_dev *dev, const struct key_entry *ke,
+				unsigned int value, bool autorelease)
+{
+	switch (ke->type) {
+	case KE_KEY:
+		input_report_key(dev, ke->keycode, value);
+		input_sync(dev);
+		if (value && autorelease) {
+			input_report_key(dev, ke->keycode, 0);
+			input_sync(dev);
+		}
+		break;
+
+	case KE_SW:
+		value = ke->sw.value;
+		/* fall through */
+
+	case KE_VSW:
+		input_report_switch(dev, ke->sw.code, value);
+		break;
+	}
+}
+EXPORT_SYMBOL(sparse_keymap_report_entry);
+
+/**
+ * sparse_keymap_report_event - report event corresponding to given scancode
+ * @dev: Input device using sparse keymap
+ * @code: Scan code
+ * @value: Value that should be reported (ignored by %KE_SW entries)
+ * @autorelease: Signals whether release event should be emitted for %KE_KEY
+ *	entries right after reporting press event, ignored by all other
+ *	entries
+ *
+ * This function is used to perform lookup in an input device using sparse
+ * keymap and report corresponding event. Returns %true if lookup was
+ * successful and %false otherwise.
+ */
+bool sparse_keymap_report_event(struct input_dev *dev, unsigned int code,
+				unsigned int value, bool autorelease)
+{
+	const struct key_entry *ke =
+		sparse_keymap_entry_from_scancode(dev, code);
+
+	if (ke) {
+		sparse_keymap_report_entry(dev, ke, value, autorelease);
+		return true;
+	}
+
+	return false;
+}
+EXPORT_SYMBOL(sparse_keymap_report_event);
+
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 8cc453c..32fc8ba 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -111,6 +111,18 @@
 	  Say Y here to enable the support for the touchscreen found
 	  on Dialog Semiconductor DA9034 PMIC.
 
+config TOUCHSCREEN_DYNAPRO
+	tristate "Dynapro serial touchscreen"
+	select SERIO
+	help
+	  Say Y here if you have a Dynapro serial touchscreen connected to
+	  your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called dynapro.
+
 config TOUCHSCREEN_EETI
 	tristate "EETI touchscreen panel support"
 	depends on I2C
@@ -133,6 +145,18 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called fujitsu-ts.
 
+config TOUCHSCREEN_S3C2410
+	tristate "Samsung S3C2410 touchscreen input driver"
+	depends on ARCH_S3C2410
+	select S3C24XX_ADC
+	help
+	  Say Y here if you have the s3c2410 touchscreen.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called s3c2410_ts.
+
 config TOUCHSCREEN_GUNZE
 	tristate "Gunze AHL-51S touchscreen"
 	select SERIO
@@ -297,7 +321,7 @@
 
 config TOUCHSCREEN_ATMEL_TSADCC
 	tristate "Atmel Touchscreen Interface"
-	depends on ARCH_AT91SAM9RL
+	depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
 	help
 	  Say Y here if you have a 4-wire touchscreen connected to the
           ADC Controller on your Atmel SoC (such as the AT91SAM9RL).
@@ -418,6 +442,7 @@
 	  - IdealTEK URTC1000
 	  - GoTop Super_Q2/GogoPen/PenPower tablets
 	  - JASTEC USB Touch Controller/DigiTech DTR-02U
+	  - Zytronic controllers
 
 	  Have a look at <http://linux.chapter7.ch/touchkit/> for
 	  a usage description and the required user-space stuff.
@@ -490,6 +515,16 @@
 	bool "e2i Touchscreen controller (e.g. from Mimo 740)"
 	depends on TOUCHSCREEN_USB_COMPOSITE
 
+config TOUCHSCREEN_USB_ZYTRONIC
+	default y
+	bool "Zytronic controller" if EMBEDDED
+	depends on TOUCHSCREEN_USB_COMPOSITE
+
+config TOUCHSCREEN_USB_ETT_TC5UH
+	default y
+	bool "ET&T TC5UH touchscreen controler support" if EMBEDDED
+	depends on TOUCHSCREEN_USB_COMPOSITE
+
 config TOUCHSCREEN_TOUCHIT213
 	tristate "Sahara TouchIT-213 touchscreen"
 	select SERIO
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 15fa62c..f1f59c9 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -12,6 +12,7 @@
 obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC)	+= atmel_tsadcc.o
 obj-$(CONFIG_TOUCHSCREEN_BITSY)		+= h3600_ts_input.o
 obj-$(CONFIG_TOUCHSCREEN_CORGI)		+= corgi_ts.o
+obj-$(CONFIG_TOUCHSCREEN_DYNAPRO)	+= dynapro.o
 obj-$(CONFIG_TOUCHSCREEN_GUNZE)		+= gunze.o
 obj-$(CONFIG_TOUCHSCREEN_EETI)		+= eeti_ts.o
 obj-$(CONFIG_TOUCHSCREEN_ELO)		+= elo.o
@@ -25,7 +26,9 @@
 obj-$(CONFIG_TOUCHSCREEN_HP7XX)		+= jornada720_ts.o
 obj-$(CONFIG_TOUCHSCREEN_HTCPEN)	+= htcpen.o
 obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE)	+= usbtouchscreen.o
+obj-$(CONFIG_TOUCHSCREEN_PCAP)		+= pcap_ts.o
 obj-$(CONFIG_TOUCHSCREEN_PENMOUNT)	+= penmount.o
+obj-$(CONFIG_TOUCHSCREEN_S3C2410)	+= s3c2410_ts.o
 obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213)	+= touchit213.o
 obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT)	+= touchright.o
 obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN)	+= touchwin.o
@@ -41,4 +44,3 @@
 obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE)	+= mainstone-wm97xx.o
 obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE)	+= zylonite-wm97xx.o
 obj-$(CONFIG_TOUCHSCREEN_W90X900)	+= w90p910_ts.o
-obj-$(CONFIG_TOUCHSCREEN_PCAP)		+= pcap_ts.o
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 09c8109..52d2ca1 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -29,10 +29,9 @@
 #include <linux/spi/ads7846.h>
 #include <asm/irq.h>
 
-
 /*
  * This code has been heavily tested on a Nokia 770, and lightly
- * tested on other ads7846 devices (OSK/Mistral, Lubbock).
+ * tested on other ads7846 devices (OSK/Mistral, Lubbock, Spitz).
  * TSC2046 is just newer ads7846 silicon.
  * Support for ads7843 tested on Atmel at91sam926x-EK.
  * Support for ads7845 has only been stubbed in.
@@ -43,7 +42,7 @@
  * have to maintain our own SW IRQ disabled status. This should be
  * removed as soon as the affected platform's IRQ handling is fixed.
  *
- * app note sbaa036 talks in more detail about accurate sampling...
+ * App note sbaa036 talks in more detail about accurate sampling...
  * that ought to help in situations like LCDs inducing noise (which
  * can also be helped by using synch signals) and more generally.
  * This driver tries to utilize the measures described in the app
@@ -566,10 +565,8 @@
 	 * once more the measurement
 	 */
 	if (packet->tc.ignore || Rt > ts->pressure_max) {
-#ifdef VERBOSE
-		pr_debug("%s: ignored %d pressure %d\n",
-			dev_name(&ts->spi->dev), packet->tc.ignore, Rt);
-#endif
+		dev_vdbg(&ts->spi->dev, "ignored %d pressure %d\n",
+			 packet->tc.ignore, Rt);
 		hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
 			      HRTIMER_MODE_REL);
 		return;
@@ -598,9 +595,7 @@
 		if (!ts->pendown) {
 			input_report_key(input, BTN_TOUCH, 1);
 			ts->pendown = 1;
-#ifdef VERBOSE
-			dev_dbg(&ts->spi->dev, "DOWN\n");
-#endif
+			dev_vdbg(&ts->spi->dev, "DOWN\n");
 		}
 
 		if (ts->swap_xy)
@@ -608,12 +603,10 @@
 
 		input_report_abs(input, ABS_X, x);
 		input_report_abs(input, ABS_Y, y);
-		input_report_abs(input, ABS_PRESSURE, Rt);
+		input_report_abs(input, ABS_PRESSURE, ts->pressure_max - Rt);
 
 		input_sync(input);
-#ifdef VERBOSE
-		dev_dbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt);
-#endif
+		dev_vdbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt);
 	}
 
 	hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
@@ -723,9 +716,7 @@
 			input_sync(input);
 
 			ts->pendown = 0;
-#ifdef VERBOSE
-			dev_dbg(&ts->spi->dev, "UP\n");
-#endif
+			dev_vdbg(&ts->spi->dev, "UP\n");
 		}
 
 		/* measurement cycle ended */
diff --git a/drivers/input/touchscreen/atmel-wm97xx.c b/drivers/input/touchscreen/atmel-wm97xx.c
index 35377f5..a12242f 100644
--- a/drivers/input/touchscreen/atmel-wm97xx.c
+++ b/drivers/input/touchscreen/atmel-wm97xx.c
@@ -59,7 +59,7 @@
 #define ATMEL_WM97XX_AC97C_IRQ		(29)
 #define ATMEL_WM97XX_GPIO_DEFAULT	(32+16) /* Pin 16 on port B. */
 #else
-#error Unkown CPU, this driver only supports AT32AP700X CPUs.
+#error Unknown CPU, this driver only supports AT32AP700X CPUs.
 #endif
 
 struct continuous {
diff --git a/drivers/input/touchscreen/atmel_tsadcc.c b/drivers/input/touchscreen/atmel_tsadcc.c
index 9c7fce4..3d9b516 100644
--- a/drivers/input/touchscreen/atmel_tsadcc.c
+++ b/drivers/input/touchscreen/atmel_tsadcc.c
@@ -22,6 +22,8 @@
 #include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <mach/board.h>
+#include <mach/cpu.h>
 
 /* Register definitions based on AT91SAM9RL64 preliminary draft datasheet */
 
@@ -36,7 +38,9 @@
 #define	  ATMEL_TSADCC_LOWRES	(1    <<  4)	/* Resolution selection */
 #define	  ATMEL_TSADCC_SLEEP	(1    <<  5)	/* Sleep mode */
 #define	  ATMEL_TSADCC_PENDET	(1    <<  6)	/* Pen Detect selection */
+#define	  ATMEL_TSADCC_PRES	(1    <<  7)	/* Pressure Measurement Selection */
 #define	  ATMEL_TSADCC_PRESCAL	(0x3f <<  8)	/* Prescalar Rate Selection */
+#define	  ATMEL_TSADCC_EPRESCAL	(0xff <<  8)	/* Prescalar Rate Selection (Extended) */
 #define	  ATMEL_TSADCC_STARTUP	(0x7f << 16)	/* Start Up time */
 #define	  ATMEL_TSADCC_SHTIM	(0xf  << 24)	/* Sample & Hold time */
 #define	  ATMEL_TSADCC_PENDBC	(0xf  << 28)	/* Pen Detect debouncing time */
@@ -84,7 +88,13 @@
 #define ATMEL_TSADCC_CDR4	0x40	/* Channel Data 4 */
 #define ATMEL_TSADCC_CDR5	0x44	/* Channel Data 5 */
 
-#define ADC_CLOCK	1000000
+#define ATMEL_TSADCC_XPOS	0x50
+#define ATMEL_TSADCC_Z1DAT	0x54
+#define ATMEL_TSADCC_Z2DAT	0x58
+
+#define PRESCALER_VAL(x)	((x) >> 8)
+
+#define ADC_DEFAULT_CLOCK	100000
 
 struct atmel_tsadcc {
 	struct input_dev	*input;
@@ -172,6 +182,7 @@
 	struct atmel_tsadcc	*ts_dev;
 	struct input_dev	*input_dev;
 	struct resource		*res;
+	struct at91_tsadcc_data *pdata = pdev->dev.platform_data;
 	int		err = 0;
 	unsigned int	prsc;
 	unsigned int	reg;
@@ -242,31 +253,49 @@
 	input_dev->phys = ts_dev->phys;
 	input_dev->dev.parent = &pdev->dev;
 
-	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
-	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
-
+	__set_bit(EV_ABS, input_dev->evbit);
 	input_set_abs_params(input_dev, ABS_X, 0, 0x3FF, 0, 0);
 	input_set_abs_params(input_dev, ABS_Y, 0, 0x3FF, 0, 0);
 
+	input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
+
 	/* clk_enable() always returns 0, no need to check it */
 	clk_enable(ts_dev->clk);
 
 	prsc = clk_get_rate(ts_dev->clk);
 	dev_info(&pdev->dev, "Master clock is set at: %d Hz\n", prsc);
 
-	prsc = prsc / ADC_CLOCK / 2 - 1;
+	if (!pdata)
+		goto err_fail;
+
+	if (!pdata->adc_clock)
+		pdata->adc_clock = ADC_DEFAULT_CLOCK;
+
+	prsc = (prsc / (2 * pdata->adc_clock)) - 1;
+
+	/* saturate if this value is too high */
+	if (cpu_is_at91sam9rl()) {
+		if (prsc > PRESCALER_VAL(ATMEL_TSADCC_PRESCAL))
+			prsc = PRESCALER_VAL(ATMEL_TSADCC_PRESCAL);
+	} else {
+		if (prsc > PRESCALER_VAL(ATMEL_TSADCC_EPRESCAL))
+			prsc = PRESCALER_VAL(ATMEL_TSADCC_EPRESCAL);
+	}
+
+	dev_info(&pdev->dev, "Prescaler is set at: %d\n", prsc);
 
 	reg = ATMEL_TSADCC_TSAMOD_TS_ONLY_MODE		|
 		((0x00 << 5) & ATMEL_TSADCC_SLEEP)	|	/* Normal Mode */
 		((0x01 << 6) & ATMEL_TSADCC_PENDET)	|	/* Enable Pen Detect */
-		((prsc << 8) & ATMEL_TSADCC_PRESCAL)	|	/* PRESCAL */
-		((0x13 << 16) & ATMEL_TSADCC_STARTUP)	|	/* STARTUP */
-		((0x0F << 28) & ATMEL_TSADCC_PENDBC);		/* PENDBC */
+		(prsc << 8)				|
+		((0x26 << 16) & ATMEL_TSADCC_STARTUP)	|
+		((pdata->pendet_debounce << 28) & ATMEL_TSADCC_PENDBC);
 
 	atmel_tsadcc_write(ATMEL_TSADCC_CR, ATMEL_TSADCC_SWRST);
 	atmel_tsadcc_write(ATMEL_TSADCC_MR, reg);
 	atmel_tsadcc_write(ATMEL_TSADCC_TRGR, ATMEL_TSADCC_TRGMOD_NONE);
-	atmel_tsadcc_write(ATMEL_TSADCC_TSR, (0x3 << 24) & ATMEL_TSADCC_TSSHTIM);
+	atmel_tsadcc_write(ATMEL_TSADCC_TSR,
+		(pdata->ts_sample_hold_time << 24) & ATMEL_TSADCC_TSSHTIM);
 
 	atmel_tsadcc_read(ATMEL_TSADCC_SR);
 	atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT);
diff --git a/drivers/input/touchscreen/dynapro.c b/drivers/input/touchscreen/dynapro.c
new file mode 100644
index 0000000..4553539
--- /dev/null
+++ b/drivers/input/touchscreen/dynapro.c
@@ -0,0 +1,206 @@
+/*
+ * Dynapro serial touchscreen driver
+ *
+ * Copyright (c) 2009 Tias Guns
+ * Based on the inexio driver (c) Vojtech Pavlik and Dan Streetman and
+ * Richard Lemon
+ *
+ */
+
+/*
+ * 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.
+ */
+
+/*
+ * 2009/09/19 Tias Guns <tias@ulyssis.org>
+ *   Copied inexio.c and edited for Dynapro protocol (from retired Xorg module)
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/init.h>
+
+#define DRIVER_DESC	"Dynapro serial touchscreen driver"
+
+MODULE_AUTHOR("Tias Guns <tias@ulyssis.org>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+/*
+ * Definitions & global arrays.
+ */
+
+#define DYNAPRO_FORMAT_TOUCH_BIT 0x40
+#define DYNAPRO_FORMAT_LENGTH 3
+#define DYNAPRO_RESPONSE_BEGIN_BYTE 0x80
+
+#define DYNAPRO_MIN_XC 0
+#define DYNAPRO_MAX_XC 0x3ff
+#define DYNAPRO_MIN_YC 0
+#define DYNAPRO_MAX_YC 0x3ff
+
+#define DYNAPRO_GET_XC(data) (data[1] | ((data[0] & 0x38) << 4))
+#define DYNAPRO_GET_YC(data) (data[2] | ((data[0] & 0x07) << 7))
+#define DYNAPRO_GET_TOUCHED(data) (DYNAPRO_FORMAT_TOUCH_BIT & data[0])
+
+/*
+ * Per-touchscreen data.
+ */
+
+struct dynapro {
+	struct input_dev *dev;
+	struct serio *serio;
+	int idx;
+	unsigned char data[DYNAPRO_FORMAT_LENGTH];
+	char phys[32];
+};
+
+static void dynapro_process_data(struct dynapro *pdynapro)
+{
+	struct input_dev *dev = pdynapro->dev;
+
+	if (DYNAPRO_FORMAT_LENGTH == ++pdynapro->idx) {
+		input_report_abs(dev, ABS_X, DYNAPRO_GET_XC(pdynapro->data));
+		input_report_abs(dev, ABS_Y, DYNAPRO_GET_YC(pdynapro->data));
+		input_report_key(dev, BTN_TOUCH,
+				 DYNAPRO_GET_TOUCHED(pdynapro->data));
+		input_sync(dev);
+
+		pdynapro->idx = 0;
+	}
+}
+
+static irqreturn_t dynapro_interrupt(struct serio *serio,
+		unsigned char data, unsigned int flags)
+{
+	struct dynapro *pdynapro = serio_get_drvdata(serio);
+
+	pdynapro->data[pdynapro->idx] = data;
+
+	if (DYNAPRO_RESPONSE_BEGIN_BYTE & pdynapro->data[0])
+		dynapro_process_data(pdynapro);
+	else
+		dev_dbg(&serio->dev, "unknown/unsynchronized data: %x\n",
+			pdynapro->data[0]);
+
+	return IRQ_HANDLED;
+}
+
+static void dynapro_disconnect(struct serio *serio)
+{
+	struct dynapro *pdynapro = serio_get_drvdata(serio);
+
+	input_get_device(pdynapro->dev);
+	input_unregister_device(pdynapro->dev);
+	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
+	input_put_device(pdynapro->dev);
+	kfree(pdynapro);
+}
+
+/*
+ * dynapro_connect() is the routine that is called when someone adds a
+ * new serio device that supports dynapro protocol and registers it as
+ * an input device. This is usually accomplished using inputattach.
+ */
+
+static int dynapro_connect(struct serio *serio, struct serio_driver *drv)
+{
+	struct dynapro *pdynapro;
+	struct input_dev *input_dev;
+	int err;
+
+	pdynapro = kzalloc(sizeof(struct dynapro), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!pdynapro || !input_dev) {
+		err = -ENOMEM;
+		goto fail1;
+	}
+
+	pdynapro->serio = serio;
+	pdynapro->dev = input_dev;
+	snprintf(pdynapro->phys, sizeof(pdynapro->phys),
+		 "%s/input0", serio->phys);
+
+	input_dev->name = "Dynapro Serial TouchScreen";
+	input_dev->phys = pdynapro->phys;
+	input_dev->id.bustype = BUS_RS232;
+	input_dev->id.vendor = SERIO_DYNAPRO;
+	input_dev->id.product = 0;
+	input_dev->id.version = 0x0001;
+	input_dev->dev.parent = &serio->dev;
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+	input_set_abs_params(pdynapro->dev, ABS_X,
+			     DYNAPRO_MIN_XC, DYNAPRO_MAX_XC, 0, 0);
+	input_set_abs_params(pdynapro->dev, ABS_Y,
+			     DYNAPRO_MIN_YC, DYNAPRO_MAX_YC, 0, 0);
+
+	serio_set_drvdata(serio, pdynapro);
+
+	err = serio_open(serio, drv);
+	if (err)
+		goto fail2;
+
+	err = input_register_device(pdynapro->dev);
+	if (err)
+		goto fail3;
+
+	return 0;
+
+ fail3:	serio_close(serio);
+ fail2:	serio_set_drvdata(serio, NULL);
+ fail1:	input_free_device(input_dev);
+	kfree(pdynapro);
+	return err;
+}
+
+/*
+ * The serio driver structure.
+ */
+
+static struct serio_device_id dynapro_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_DYNAPRO,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(serio, dynapro_serio_ids);
+
+static struct serio_driver dynapro_drv = {
+	.driver		= {
+		.name	= "dynapro",
+	},
+	.description	= DRIVER_DESC,
+	.id_table	= dynapro_serio_ids,
+	.interrupt	= dynapro_interrupt,
+	.connect	= dynapro_connect,
+	.disconnect	= dynapro_disconnect,
+};
+
+/*
+ * The functions for inserting/removing us as a module.
+ */
+
+static int __init dynapro_init(void)
+{
+	return serio_register_driver(&dynapro_drv);
+}
+
+static void __exit dynapro_exit(void)
+{
+	serio_unregister_driver(&dynapro_drv);
+}
+
+module_init(dynapro_init);
+module_exit(dynapro_exit);
diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c
index 8fc3b08..6cdcf2a 100644
--- a/drivers/input/touchscreen/mainstone-wm97xx.c
+++ b/drivers/input/touchscreen/mainstone-wm97xx.c
@@ -14,7 +14,7 @@
  *
  * Notes:
  *     This is a wm97xx extended touch driver to capture touch
- *     data in a continuous manner on the Intel XScale archictecture
+ *     data in a continuous manner on the Intel XScale architecture
  *
  *  Features:
  *       - codecs supported:- WM9705, WM9712, WM9713
@@ -131,7 +131,7 @@
 	/* When the AC97 queue has been drained we need to allow time
 	 * to buffer up samples otherwise we end up spinning polling
 	 * for samples.  The controller can't have a suitably low
-	 * threashold set to use the notifications it gives.
+	 * threshold set to use the notifications it gives.
 	 */
 	schedule_timeout_uninterruptible(1);
 
diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c
new file mode 100644
index 0000000..6386b44
--- /dev/null
+++ b/drivers/input/touchscreen/s3c2410_ts.c
@@ -0,0 +1,457 @@
+/*
+ * Samsung S3C24XX touchscreen driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the term 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Copyright 2004 Arnaud Patard <arnaud.patard@rtp-net.org>
+ * Copyright 2008 Ben Dooks <ben-linux@fluff.org>
+ * Copyright 2009 Simtec Electronics <linux@simtec.co.uk>
+ *
+ * Additional work by Herbert Pötzl <herbert@13thfloor.at> and
+ * Harald Welte <laforge@openmoko.org>
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/adc.h>
+#include <plat/regs-adc.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/ts.h>
+
+#define TSC_SLEEP  (S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_XY_PST(0))
+
+#define INT_DOWN	(0)
+#define INT_UP		(1 << 8)
+
+#define WAIT4INT	(S3C2410_ADCTSC_YM_SEN | \
+			 S3C2410_ADCTSC_YP_SEN | \
+			 S3C2410_ADCTSC_XP_SEN | \
+			 S3C2410_ADCTSC_XY_PST(3))
+
+#define AUTOPST		(S3C2410_ADCTSC_YM_SEN | \
+			 S3C2410_ADCTSC_YP_SEN | \
+			 S3C2410_ADCTSC_XP_SEN | \
+			 S3C2410_ADCTSC_AUTO_PST | \
+			 S3C2410_ADCTSC_XY_PST(0))
+
+/* Per-touchscreen data. */
+
+/**
+ * struct s3c2410ts - driver touchscreen state.
+ * @client: The ADC client we registered with the core driver.
+ * @dev: The device we are bound to.
+ * @input: The input device we registered with the input subsystem.
+ * @clock: The clock for the adc.
+ * @io: Pointer to the IO base.
+ * @xp: The accumulated X position data.
+ * @yp: The accumulated Y position data.
+ * @irq_tc: The interrupt number for pen up/down interrupt
+ * @count: The number of samples collected.
+ * @shift: The log2 of the maximum count to read in one go.
+ */
+struct s3c2410ts {
+	struct s3c_adc_client *client;
+	struct device *dev;
+	struct input_dev *input;
+	struct clk *clock;
+	void __iomem *io;
+	unsigned long xp;
+	unsigned long yp;
+	int irq_tc;
+	int count;
+	int shift;
+};
+
+static struct s3c2410ts ts;
+
+/**
+ * s3c2410_ts_connect - configure gpio for s3c2410 systems
+ *
+ * Configure the GPIO for the S3C2410 system, where we have external FETs
+ * connected to the device (later systems such as the S3C2440 integrate
+ * these into the device).
+*/
+static inline void s3c2410_ts_connect(void)
+{
+	s3c2410_gpio_cfgpin(S3C2410_GPG(12), S3C2410_GPG12_XMON);
+	s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPG13_nXPON);
+	s3c2410_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPG14_YMON);
+	s3c2410_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPG15_nYPON);
+}
+
+/**
+ * get_down - return the down state of the pen
+ * @data0: The data read from ADCDAT0 register.
+ * @data1: The data read from ADCDAT1 register.
+ *
+ * Return non-zero if both readings show that the pen is down.
+ */
+static inline bool get_down(unsigned long data0, unsigned long data1)
+{
+	/* returns true if both data values show stylus down */
+	return (!(data0 & S3C2410_ADCDAT0_UPDOWN) &&
+		!(data1 & S3C2410_ADCDAT0_UPDOWN));
+}
+
+static void touch_timer_fire(unsigned long data)
+{
+	unsigned long data0;
+	unsigned long data1;
+	bool down;
+
+	data0 = readl(ts.io + S3C2410_ADCDAT0);
+	data1 = readl(ts.io + S3C2410_ADCDAT1);
+
+	down = get_down(data0, data1);
+
+	if (ts.count == (1 << ts.shift)) {
+		ts.xp >>= ts.shift;
+		ts.yp >>= ts.shift;
+
+		dev_dbg(ts.dev, "%s: X=%lu, Y=%lu, count=%d\n",
+			__func__, ts.xp, ts.yp, ts.count);
+
+		input_report_abs(ts.input, ABS_X, ts.xp);
+		input_report_abs(ts.input, ABS_Y, ts.yp);
+
+		input_report_key(ts.input, BTN_TOUCH, 1);
+		input_sync(ts.input);
+
+		ts.xp = 0;
+		ts.yp = 0;
+		ts.count = 0;
+	}
+
+	if (down) {
+		s3c_adc_start(ts.client, 0, 1 << ts.shift);
+	} else {
+		ts.count = 0;
+
+		input_report_key(ts.input, BTN_TOUCH, 0);
+		input_sync(ts.input);
+
+		writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC);
+	}
+}
+
+static DEFINE_TIMER(touch_timer, touch_timer_fire, 0, 0);
+
+/**
+ * stylus_irq - touchscreen stylus event interrupt
+ * @irq: The interrupt number
+ * @dev_id: The device ID.
+ *
+ * Called when the IRQ_TC is fired for a pen up or down event.
+ */
+static irqreturn_t stylus_irq(int irq, void *dev_id)
+{
+	unsigned long data0;
+	unsigned long data1;
+	bool down;
+
+	data0 = readl(ts.io + S3C2410_ADCDAT0);
+	data1 = readl(ts.io + S3C2410_ADCDAT1);
+
+	down = get_down(data0, data1);
+
+	/* TODO we should never get an interrupt with down set while
+	 * the timer is running, but maybe we ought to verify that the
+	 * timer isn't running anyways. */
+
+	if (down)
+		s3c_adc_start(ts.client, 0, 1 << ts.shift);
+	else
+		dev_info(ts.dev, "%s: count=%d\n", __func__, ts.count);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * s3c24xx_ts_conversion - ADC conversion callback
+ * @client: The client that was registered with the ADC core.
+ * @data0: The reading from ADCDAT0.
+ * @data1: The reading from ADCDAT1.
+ * @left: The number of samples left.
+ *
+ * Called when a conversion has finished.
+ */
+static void s3c24xx_ts_conversion(struct s3c_adc_client *client,
+				  unsigned data0, unsigned data1,
+				  unsigned *left)
+{
+	dev_dbg(ts.dev, "%s: %d,%d\n", __func__, data0, data1);
+
+	ts.xp += data0;
+	ts.yp += data1;
+
+	ts.count++;
+
+	/* From tests, it seems that it is unlikely to get a pen-up
+	 * event during the conversion process which means we can
+	 * ignore any pen-up events with less than the requisite
+	 * count done.
+	 *
+	 * In several thousand conversions, no pen-ups where detected
+	 * before count completed.
+	 */
+}
+
+/**
+ * s3c24xx_ts_select - ADC selection callback.
+ * @client: The client that was registered with the ADC core.
+ * @select: The reason for select.
+ *
+ * Called when the ADC core selects (or deslects) us as a client.
+ */
+static void s3c24xx_ts_select(struct s3c_adc_client *client, unsigned select)
+{
+	if (select) {
+		writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST,
+		       ts.io + S3C2410_ADCTSC);
+	} else {
+		mod_timer(&touch_timer, jiffies+1);
+		writel(WAIT4INT | INT_UP, ts.io + S3C2410_ADCTSC);
+	}
+}
+
+/**
+ * s3c2410ts_probe - device core probe entry point
+ * @pdev: The device we are being bound to.
+ *
+ * Initialise, find and allocate any resources we need to run and then
+ * register with the ADC and input systems.
+ */
+static int __devinit s3c2410ts_probe(struct platform_device *pdev)
+{
+	struct s3c2410_ts_mach_info *info;
+	struct device *dev = &pdev->dev;
+	struct input_dev *input_dev;
+	struct resource *res;
+	int ret = -EINVAL;
+
+	/* Initialise input stuff */
+	memset(&ts, 0, sizeof(struct s3c2410ts));
+
+	ts.dev = dev;
+
+	info = pdev->dev.platform_data;
+	if (!info) {
+		dev_err(dev, "no platform data, cannot attach\n");
+		return -EINVAL;
+	}
+
+	dev_dbg(dev, "initialising touchscreen\n");
+
+	ts.clock = clk_get(dev, "adc");
+	if (IS_ERR(ts.clock)) {
+		dev_err(dev, "cannot get adc clock source\n");
+		return -ENOENT;
+	}
+
+	clk_enable(ts.clock);
+	dev_dbg(dev, "got and enabled clocks\n");
+
+	ts.irq_tc = ret = platform_get_irq(pdev, 0);
+	if (ret < 0) {
+		dev_err(dev, "no resource for interrupt\n");
+		goto err_clk;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "no resource for registers\n");
+		ret = -ENOENT;
+		goto err_clk;
+	}
+
+	ts.io = ioremap(res->start, resource_size(res));
+	if (ts.io == NULL) {
+		dev_err(dev, "cannot map registers\n");
+		ret = -ENOMEM;
+		goto err_clk;
+	}
+
+	/* Configure the touchscreen external FETs on the S3C2410 */
+	if (!platform_get_device_id(pdev)->driver_data)
+		s3c2410_ts_connect();
+
+	ts.client = s3c_adc_register(pdev, s3c24xx_ts_select,
+				     s3c24xx_ts_conversion, 1);
+	if (IS_ERR(ts.client)) {
+		dev_err(dev, "failed to register adc client\n");
+		ret = PTR_ERR(ts.client);
+		goto err_iomap;
+	}
+
+	/* Initialise registers */
+	if ((info->delay & 0xffff) > 0)
+		writel(info->delay & 0xffff, ts.io + S3C2410_ADCDLY);
+
+	writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC);
+
+	input_dev = input_allocate_device();
+	if (!input_dev) {
+		dev_err(dev, "Unable to allocate the input device !!\n");
+		ret = -ENOMEM;
+		goto err_iomap;
+	}
+
+	ts.input = input_dev;
+	ts.input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	ts.input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+	input_set_abs_params(ts.input, ABS_X, 0, 0x3FF, 0, 0);
+	input_set_abs_params(ts.input, ABS_Y, 0, 0x3FF, 0, 0);
+
+	ts.input->name = "S3C24XX TouchScreen";
+	ts.input->id.bustype = BUS_HOST;
+	ts.input->id.vendor = 0xDEAD;
+	ts.input->id.product = 0xBEEF;
+	ts.input->id.version = 0x0102;
+
+	ts.shift = info->oversampling_shift;
+
+	ret = request_irq(ts.irq_tc, stylus_irq, IRQF_DISABLED,
+			  "s3c2410_ts_pen", ts.input);
+	if (ret) {
+		dev_err(dev, "cannot get TC interrupt\n");
+		goto err_inputdev;
+	}
+
+	dev_info(dev, "driver attached, registering input device\n");
+
+	/* All went ok, so register to the input system */
+	ret = input_register_device(ts.input);
+	if (ret < 0) {
+		dev_err(dev, "failed to register input device\n");
+		ret = -EIO;
+		goto err_tcirq;
+	}
+
+	return 0;
+
+ err_tcirq:
+	free_irq(ts.irq_tc, ts.input);
+ err_inputdev:
+	input_unregister_device(ts.input);
+ err_iomap:
+	iounmap(ts.io);
+ err_clk:
+	del_timer_sync(&touch_timer);
+	clk_put(ts.clock);
+	return ret;
+}
+
+/**
+ * s3c2410ts_remove - device core removal entry point
+ * @pdev: The device we are being removed from.
+ *
+ * Free up our state ready to be removed.
+ */
+static int __devexit s3c2410ts_remove(struct platform_device *pdev)
+{
+	free_irq(ts.irq_tc, ts.input);
+	del_timer_sync(&touch_timer);
+
+	clk_disable(ts.clock);
+	clk_put(ts.clock);
+
+	input_unregister_device(ts.input);
+	iounmap(ts.io);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int s3c2410ts_suspend(struct device *dev)
+{
+	writel(TSC_SLEEP, ts.io + S3C2410_ADCTSC);
+	disable_irq(ts.irq_tc);
+	clk_disable(ts.clock);
+
+	return 0;
+}
+
+static int s3c2410ts_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct s3c2410_ts_mach_info *info = pdev->dev.platform_data;
+
+	clk_enable(ts.clock);
+
+	/* Initialise registers */
+	if ((info->delay & 0xffff) > 0)
+		writel(info->delay & 0xffff, ts.io + S3C2410_ADCDLY);
+
+	writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC);
+
+	return 0;
+}
+
+static struct dev_pm_ops s3c_ts_pmops = {
+	.suspend	= s3c2410ts_suspend,
+	.resume		= s3c2410ts_resume,
+};
+#endif
+
+static struct platform_device_id s3cts_driver_ids[] = {
+	{ "s3c2410-ts", 0 },
+	{ "s3c2440-ts", 1 },
+	{ }
+};
+MODULE_DEVICE_TABLE(platform, s3cts_driver_ids);
+
+static struct platform_driver s3c_ts_driver = {
+	.driver         = {
+		.name   = "s3c24xx-ts",
+		.owner  = THIS_MODULE,
+#ifdef CONFIG_PM
+		.pm	= &s3c_ts_pmops,
+#endif
+	},
+	.id_table	= s3cts_driver_ids,
+	.probe		= s3c2410ts_probe,
+	.remove		= __devexit_p(s3c2410ts_remove),
+};
+
+static int __init s3c2410ts_init(void)
+{
+	return platform_driver_register(&s3c_ts_driver);
+}
+
+static void __exit s3c2410ts_exit(void)
+{
+	platform_driver_unregister(&s3c_ts_driver);
+}
+
+module_init(s3c2410ts_init);
+module_exit(s3c2410ts_exit);
+
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>, "
+	      "Ben Dooks <ben@simtec.co.uk>, "
+	      "Simtec Electronics <linux@simtec.co.uk>");
+MODULE_DESCRIPTION("S3C24XX Touchscreen driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c
index 095f84b..89dcbe7 100644
--- a/drivers/input/touchscreen/ucb1400_ts.c
+++ b/drivers/input/touchscreen/ucb1400_ts.c
@@ -355,10 +355,13 @@
 		goto err;
 	}
 
-	error = ucb1400_ts_detect_irq(ucb);
-	if (error) {
-		printk(KERN_ERR "UCB1400: IRQ probe failed\n");
-		goto err_free_devs;
+	/* Only in case the IRQ line wasn't supplied, try detecting it */
+	if (ucb->irq < 0) {
+		error = ucb1400_ts_detect_irq(ucb);
+		if (error) {
+			printk(KERN_ERR "UCB1400: IRQ probe failed\n");
+			goto err_free_devs;
+		}
 	}
 
 	init_waitqueue_head(&ucb->ts_wait);
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index 68ece58..09a5e73 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -14,6 +14,7 @@
  *  - General Touch
  *  - GoTop Super_Q2/GogoPen/PenPower tablets
  *  - JASTEC USB touch controller/DigiTech DTR-02U
+ *  - Zytronic capacitive touchscreen
  *
  * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch>
  * Copyright (C) by Todd E. Johnson (mtouchusb.c)
@@ -73,6 +74,15 @@
 	int min_press, max_press;
 	int rept_size;
 
+	/*
+	 * Always service the USB devices irq not just when the input device is
+	 * open. This is useful when devices have a watchdog which prevents us
+	 * from periodically polling the device. Leave this unset unless your
+	 * touchscreen device requires it, as it does consume more of the USB
+	 * bandwidth.
+	 */
+	bool irq_always;
+
 	void (*process_pkt) (struct usbtouch_usb *usbtouch, unsigned char *pkt, int len);
 
 	/*
@@ -121,6 +131,8 @@
 	DEVTYPE_GOTOP,
 	DEVTYPE_JASTEC,
 	DEVTYPE_E2I,
+	DEVTYPE_ZYTRONIC,
+	DEVTYPE_TC5UH,
 };
 
 #define USB_DEVICE_HID_CLASS(vend, prod) \
@@ -201,6 +213,15 @@
 #ifdef CONFIG_TOUCHSCREEN_USB_E2I
 	{USB_DEVICE(0x1ac7, 0x0001), .driver_info = DEVTYPE_E2I},
 #endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC
+	{USB_DEVICE(0x14c8, 0x0003), .driver_info = DEVTYPE_ZYTRONIC},
+#endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH
+	{USB_DEVICE(0x0664, 0x0309), .driver_info = DEVTYPE_TC5UH},
+#endif
+
 	{}
 };
 
@@ -538,6 +559,19 @@
 }
 #endif
 
+/*****************************************************************************
+ * ET&T TC5UH part
+ */
+#ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH
+static int tc5uh_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+{
+	dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1];
+	dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3];
+	dev->touch = pkt[0] & 0x01;
+
+	return 1;
+}
+#endif
 
 /*****************************************************************************
  * IdealTEK URTC1000 Part
@@ -621,6 +655,39 @@
 }
 #endif
 
+/*****************************************************************************
+ * Zytronic Part
+ */
+#ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC
+static int zytronic_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+{
+	switch (pkt[0]) {
+	case 0x3A: /* command response */
+		dbg("%s: Command response %d", __func__, pkt[1]);
+		break;
+
+	case 0xC0: /* down */
+		dev->x = (pkt[1] & 0x7f) | ((pkt[2] & 0x07) << 7);
+		dev->y = (pkt[3] & 0x7f) | ((pkt[4] & 0x07) << 7);
+		dev->touch = 1;
+		dbg("%s: down %d,%d", __func__, dev->x, dev->y);
+		return 1;
+
+	case 0x80: /* up */
+		dev->x = (pkt[1] & 0x7f) | ((pkt[2] & 0x07) << 7);
+		dev->y = (pkt[3] & 0x7f) | ((pkt[4] & 0x07) << 7);
+		dev->touch = 0;
+		dbg("%s: up %d,%d", __func__, dev->x, dev->y);
+		return 1;
+
+	default:
+		dbg("%s: Unknown return %d", __func__, pkt[0]);
+		break;
+	}
+
+	return 0;
+}
+#endif
 
 /*****************************************************************************
  * the different device descriptors
@@ -783,6 +850,29 @@
 		.read_data	= e2i_read_data,
 	},
 #endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC
+	[DEVTYPE_ZYTRONIC] = {
+		.min_xc		= 0x0,
+		.max_xc		= 0x03ff,
+		.min_yc		= 0x0,
+		.max_yc		= 0x03ff,
+		.rept_size	= 5,
+		.read_data	= zytronic_read_data,
+		.irq_always     = true,
+	},
+#endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH
+	[DEVTYPE_TC5UH] = {
+		.min_xc		= 0x0,
+		.max_xc		= 0x0fff,
+		.min_yc		= 0x0,
+		.max_yc		= 0x0fff,
+		.rept_size	= 5,
+		.read_data	= tc5uh_read_data,
+	},
+#endif
 };
 
 
@@ -933,8 +1023,10 @@
 
 	usbtouch->irq->dev = usbtouch->udev;
 
-	if (usb_submit_urb(usbtouch->irq, GFP_KERNEL))
-		return -EIO;
+	if (!usbtouch->type->irq_always) {
+		if (usb_submit_urb(usbtouch->irq, GFP_KERNEL))
+		  return -EIO;
+	}
 
 	return 0;
 }
@@ -943,7 +1035,8 @@
 {
 	struct usbtouch_usb *usbtouch = input_get_drvdata(input);
 
-	usb_kill_urb(usbtouch->irq);
+	if (!usbtouch->type->irq_always)
+		usb_kill_urb(usbtouch->irq);
 }
 
 
@@ -1066,6 +1159,9 @@
 
 	usb_set_intfdata(intf, usbtouch);
 
+	if (usbtouch->type->irq_always)
+		usb_submit_urb(usbtouch->irq, GFP_KERNEL);
+
 	return 0;
 
 out_free_buffers:
@@ -1087,7 +1183,7 @@
 
 	dbg("%s - usbtouch is initialized, cleaning up", __func__);
 	usb_set_intfdata(intf, NULL);
-	usb_kill_urb(usbtouch->irq);
+	/* this will stop IO via close */
 	input_unregister_device(usbtouch->input);
 	usb_free_urb(usbtouch->irq);
 	usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch);
diff --git a/drivers/input/touchscreen/zylonite-wm97xx.c b/drivers/input/touchscreen/zylonite-wm97xx.c
index 41e4359..eca54db 100644
--- a/drivers/input/touchscreen/zylonite-wm97xx.c
+++ b/drivers/input/touchscreen/zylonite-wm97xx.c
@@ -96,7 +96,7 @@
 	/* When the AC97 queue has been drained we need to allow time
 	 * to buffer up samples otherwise we end up spinning polling
 	 * for samples.  The controller can't have a suitably low
-	 * threashold set to use the notifications it gives.
+	 * threshold set to use the notifications it gives.
 	 */
 	msleep(1);
 
diff --git a/drivers/input/xen-kbdfront.c b/drivers/input/xen-kbdfront.c
index b115726..c721c0a 100644
--- a/drivers/input/xen-kbdfront.c
+++ b/drivers/input/xen-kbdfront.c
@@ -21,7 +21,10 @@
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/input.h>
+
 #include <asm/xen/hypervisor.h>
+
+#include <xen/xen.h>
 #include <xen/events.h>
 #include <xen/page.h>
 #include <xen/interface/io/fbif.h>
diff --git a/drivers/isdn/act2000/Kconfig b/drivers/isdn/act2000/Kconfig
index 3fc1a54..fa2673f 100644
--- a/drivers/isdn/act2000/Kconfig
+++ b/drivers/isdn/act2000/Kconfig
@@ -1,6 +1,3 @@
-#
-# Config.in for IBM Active 2000 ISDN driver
-#
 config ISDN_DRV_ACT2000
 	tristate "IBM Active 2000 support"
 	depends on ISA
@@ -10,4 +7,3 @@
 	  into the card using a utility which is part of the latest
 	  isdn4k-utils package. Please read the file
 	  <file:Documentation/isdn/README.act2000> for more information.
-
diff --git a/drivers/isdn/capi/Kconfig b/drivers/isdn/capi/Kconfig
index e1afd60..b2a0475 100644
--- a/drivers/isdn/capi/Kconfig
+++ b/drivers/isdn/capi/Kconfig
@@ -1,6 +1,3 @@
-#
-# Config.in for the CAPI subsystem
-#
 config ISDN_DRV_AVMB1_VERBOSE_REASON
 	bool "Verbose reason code reporting"
 	default y
@@ -59,4 +56,3 @@
 	  the legacy isdn4linux link layer.  If you have a card which is
 	  supported by a CAPI driver, but still want to use old features like
 	  ippp interfaces or ttyI emulation, say Y/M here.
-
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c
index 3e6d17f..66b7d7a 100644
--- a/drivers/isdn/capi/capidrv.c
+++ b/drivers/isdn/capi/capidrv.c
@@ -830,7 +830,7 @@
 		      case 0: break;
 		      case 1: s = "unknown class"; break;
 		      case 2: s = "unknown function"; break;
-		      default: s = "unkown error"; break;
+		      default: s = "unknown error"; break;
 		   }
 		   if (s)
 	           printk(KERN_INFO "capidrv-%d: %s from controller 0x%x function %d: %s\n",
diff --git a/drivers/isdn/hardware/eicon/di.c b/drivers/isdn/hardware/eicon/di.c
index b029d13..cb14ae3 100644
--- a/drivers/isdn/hardware/eicon/di.c
+++ b/drivers/isdn/hardware/eicon/di.c
@@ -806,7 +806,7 @@
           DELIVERY - indication entered isdn_rc function
           RNR=...  - application had returned RNR=... after the
                      look ahead callback
-          RNum=0   - aplication had not returned any buffer to copy
+          RNum=0   - application had not returned any buffer to copy
                      this indication and will copy it self
           COMPLETE - XDI had copied the data to the buffers provided
                      bu the application and is about to issue the
diff --git a/drivers/isdn/hardware/eicon/maintidi.c b/drivers/isdn/hardware/eicon/maintidi.c
index 41c26e7..534978b 100644
--- a/drivers/isdn/hardware/eicon/maintidi.c
+++ b/drivers/isdn/hardware/eicon/maintidi.c
@@ -385,7 +385,7 @@
                   }
                   break;
                 default:
-                  diva_mnt_internal_dprintf (0, DLI_ERR, "Unknon IDI Ind (DMA mode): %02x", Ind);
+                  diva_mnt_internal_dprintf (0, DLI_ERR, "Unknown IDI Ind (DMA mode): %02x", Ind);
               }
               p += (this_ind_length+1);
               total_length -= (4 + this_ind_length);
@@ -420,7 +420,7 @@
             }
             break;
           default:
-            diva_mnt_internal_dprintf (0, DLI_ERR, "Unknon IDI Ind: %02x", Ind);
+            diva_mnt_internal_dprintf (0, DLI_ERR, "Unknown IDI Ind: %02x", Ind);
         }
       }
     }
diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c
index fc46a26..a64bb6c 100644
--- a/drivers/isdn/hardware/mISDN/hfcsusb.c
+++ b/drivers/isdn/hardware/mISDN/hfcsusb.c
@@ -721,7 +721,7 @@
 	switch (protocol) {
 	case (-1):	/* used for init */
 		bch->state = -1;
-		/* fall trough */
+		/* fall through */
 	case (ISDN_P_NONE):
 		if (bch->state == ISDN_P_NONE)
 			return 0; /* already in idle state */
diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.h b/drivers/isdn/hardware/mISDN/hfcsusb.h
index 43efe73..369196a 100644
--- a/drivers/isdn/hardware/mISDN/hfcsusb.h
+++ b/drivers/isdn/hardware/mISDN/hfcsusb.h
@@ -150,7 +150,7 @@
 	for (i = 0; list[i].name != NULL; i++)
 		if (list[i].num == num)
 			return list[i].name;
-	return "<unkown USB Error>";
+	return "<unknown USB Error>";
 }
 
 /* USB descriptor need to contain one of the following EndPoint combination: */
diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c
index de352a1..09095c7 100644
--- a/drivers/isdn/hardware/mISDN/mISDNisar.c
+++ b/drivers/isdn/hardware/mISDN/mISDNisar.c
@@ -860,7 +860,7 @@
 		pr_debug("%s: pump stev GSTN CLEAR\n", ch->is->name);
 		break;
 	default:
-		pr_info("u%s: nknown pump stev %x\n", ch->is->name, devt);
+		pr_info("u%s: unknown pump stev %x\n", ch->is->name, devt);
 		break;
 	}
 }
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index a420b64..aaaeaaf 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -1086,7 +1086,7 @@
 			break;
 		default:
 			DBG(HFCUSB_DBG_STATES,
-			       "HFC_USB: hfc_usb_d_l2l1: unkown state : %#x", pr);
+			       "HFC_USB: hfc_usb_d_l2l1: unknown state : %#x", pr);
 			break;
 	}
 }
diff --git a/drivers/isdn/hysdn/Kconfig b/drivers/isdn/hysdn/Kconfig
index c9e4231..e86bc65 100644
--- a/drivers/isdn/hysdn/Kconfig
+++ b/drivers/isdn/hysdn/Kconfig
@@ -1,6 +1,3 @@
-#
-# Config.in for HYSDN ISDN driver
-#
 config HYSDN
 	tristate "Hypercope HYSDN cards (Champ, Ergo, Metro) support (module only)"
 	depends on m && PROC_FS && PCI
@@ -15,4 +12,3 @@
 	depends on HYSDN && ISDN_CAPI
 	help
 	  Say Y here if you like to use Hypercope's CAPI 2.0 interface.
-
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index 90b56ed..507e13d 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -1563,7 +1563,7 @@
 	*(__be32 *)(p +  4) = cpu_to_be32(CISCO_SLARP_KEEPALIVE);
 	*(__be32 *)(p +  8) = cpu_to_be32(lp->cisco_myseq);
 	*(__be32 *)(p + 12) = cpu_to_be32(lp->cisco_yourseq);
-	*(__be16 *)(p + 16) = cpu_to_be16(0xffff); // reliablity, always 0xffff
+	*(__be16 *)(p + 16) = cpu_to_be16(0xffff); // reliability, always 0xffff
 	p += 18;
 
 	isdn_net_write_super(lp, skb);
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index 642d5aa..45df667 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -836,7 +836,7 @@
 			unsigned short hl;
 			struct sk_buff *skb;
 			/*
-			 * we need to reserve enought space in front of
+			 * we need to reserve enough space in front of
 			 * sk_buff. old call to dev_alloc_skb only reserved
 			 * 16 bytes, now we are looking what the driver want
 			 */
@@ -1326,7 +1326,7 @@
 		struct sk_buff *new_skb;
 	        unsigned short hl;
 		/*
-		 * we need to reserve enought space in front of
+		 * we need to reserve enough space in front of
 		 * sk_buff. old call to dev_alloc_skb only reserved
 		 * 16 bytes, now we are looking what the driver want.
 		 */
@@ -1674,7 +1674,7 @@
 	 * - insert new fragment into the proper sequence slot (once that's done
 	 *   newfrag will be set to NULL)
 	 * - reassemble any complete fragment sequence (non-null 'start'
-	 *   indicates there is a continguous sequence present)
+	 *   indicates there is a contiguous sequence present)
 	 * - discard any incomplete sequences that are below minseq -- due
 	 *   to the fact that sender always increment sequence number, if there
 	 *   is an incomplete sequence below minseq, no new fragments would
diff --git a/drivers/isdn/i4l/isdn_ttyfax.c b/drivers/isdn/i4l/isdn_ttyfax.c
index 78f7660..4c41f19 100644
--- a/drivers/isdn/i4l/isdn_ttyfax.c
+++ b/drivers/isdn/i4l/isdn_ttyfax.c
@@ -470,7 +470,7 @@
 		}
 		return 0;
 	}
-	/* BADMUL=value - dummy 0=disable errorchk disabled (treshold multiplier) */
+	/* BADMUL=value - dummy 0=disable errorchk disabled (threshold multiplier) */
 	if (!strncmp(p[0], "BADMUL", 6)) {
 		p[0] += 6;
 		switch (*p[0]) {
diff --git a/drivers/isdn/icn/Kconfig b/drivers/isdn/icn/Kconfig
index 89d15ee..4534f21 100644
--- a/drivers/isdn/icn/Kconfig
+++ b/drivers/isdn/icn/Kconfig
@@ -1,6 +1,3 @@
-#
-# Config.in for ICN ISDN driver
-#
 config ISDN_DRV_ICN
 	tristate "ICN 2B and 4B support"
 	depends on ISA
@@ -13,4 +10,3 @@
 	  separately.  See <file:Documentation/isdn/README> and
 	  <file:Documentation/isdn/README.icn> for more
 	  information.
-
diff --git a/drivers/isdn/mISDN/dsp_core.c b/drivers/isdn/mISDN/dsp_core.c
index 77ee286..43ff4d3 100644
--- a/drivers/isdn/mISDN/dsp_core.c
+++ b/drivers/isdn/mISDN/dsp_core.c
@@ -110,7 +110,7 @@
  * crossconnections and conferences via software if not possible through
  * hardware. If hardware capability is available, hardware is used.
  *
- * Echo: Is generated by CMX and is used to check performane of hard and
+ * Echo: Is generated by CMX and is used to check performance of hard and
  * software CMX.
  *
  * The CMX has special functions for conferences with one, two and more
diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c
index e04bad6..6d4da60 100644
--- a/drivers/isdn/mISDN/tei.c
+++ b/drivers/isdn/mISDN/tei.c
@@ -725,7 +725,7 @@
 	if (tm->rcnt == 1) {
 		if (*debug & DEBUG_L2_TEI)
 			tm->tei_m.printdebug(fi,
-			    "check req for tei %d sucessful\n", tm->l2->tei);
+			    "check req for tei %d successful\n", tm->l2->tei);
 		mISDN_FsmChangeState(fi, ST_TEI_NOP);
 	} else if (tm->rcnt > 1) {
 		/* duplicate assignment; remove */
diff --git a/drivers/isdn/pcbit/Kconfig b/drivers/isdn/pcbit/Kconfig
index ffba6ec..e9b2dd8 100644
--- a/drivers/isdn/pcbit/Kconfig
+++ b/drivers/isdn/pcbit/Kconfig
@@ -1,6 +1,3 @@
-#
-# Config.in for PCBIT ISDN driver
-#
 config ISDN_DRV_PCBIT
 	tristate "PCBIT-D support"
 	depends on ISA && (BROKEN || X86)
@@ -11,4 +8,3 @@
 	  the card using a utility which is distributed separately.  See
 	  <file:Documentation/isdn/README> and
 	  <file:Documentation/isdn/README.pcbit> for more information.
-
diff --git a/drivers/isdn/sc/Kconfig b/drivers/isdn/sc/Kconfig
index e6510ca..7469863 100644
--- a/drivers/isdn/sc/Kconfig
+++ b/drivers/isdn/sc/Kconfig
@@ -1,6 +1,3 @@
-#
-# Config.in for Spellcaster ISDN driver
-#
 config ISDN_DRV_SC
 	tristate "Spellcaster support"
 	depends on ISA
@@ -9,4 +6,3 @@
 	  driver currently builds only in a modularized version.
 	  To build it, choose M here: the module will be called sc.
 	  See <file:Documentation/isdn/README.sc> for more information.
-
diff --git a/drivers/macintosh/ans-lcd.c b/drivers/macintosh/ans-lcd.c
index 6a82218..a3d25da 100644
--- a/drivers/macintosh/ans-lcd.c
+++ b/drivers/macintosh/ans-lcd.c
@@ -3,7 +3,6 @@
  */
 
 #include <linux/types.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/miscdevice.h>
@@ -26,6 +25,7 @@
 static unsigned long anslcd_short_delay = 80;
 static unsigned long anslcd_long_delay = 3280;
 static volatile unsigned char __iomem *anslcd_ptr;
+static DEFINE_MUTEX(anslcd_mutex);
 
 #undef DEBUG
 
@@ -65,26 +65,31 @@
 
 	if (!access_ok(VERIFY_READ, buf, count))
 		return -EFAULT;
+
+	mutex_lock(&anslcd_mutex);
 	for ( i = *ppos; count > 0; ++i, ++p, --count ) 
 	{
 		char c;
 		__get_user(c, p);
 		anslcd_write_byte_data( c );
 	}
+	mutex_unlock(&anslcd_mutex);
 	*ppos = i;
 	return p - buf;
 }
 
-static int
-anslcd_ioctl( struct inode * inode, struct file * file,
-				unsigned int cmd, unsigned long arg )
+static long
+anslcd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	char ch, __user *temp;
+	long ret = 0;
 
 #ifdef DEBUG
 	printk(KERN_DEBUG "LCD: ioctl(%d,%d)\n",cmd,arg);
 #endif
 
+	mutex_lock(&anslcd_mutex);
+
 	switch ( cmd )
 	{
 	case ANSLCD_CLEAR:
@@ -93,7 +98,7 @@
 		anslcd_write_byte_ctrl ( 0x06 );
 		anslcd_write_byte_ctrl ( 0x01 );
 		anslcd_write_byte_ctrl ( 0x02 );
-		return 0;
+		break;
 	case ANSLCD_SENDCTRL:
 		temp = (char __user *) arg;
 		__get_user(ch, temp);
@@ -101,33 +106,37 @@
 			anslcd_write_byte_ctrl ( ch );
 			__get_user(ch, temp);
 		}
-		return 0;
+		break;
 	case ANSLCD_SETSHORTDELAY:
 		if (!capable(CAP_SYS_ADMIN))
-			return -EACCES;
-		anslcd_short_delay=arg;
-		return 0;
+			ret =-EACCES;
+		else
+			anslcd_short_delay=arg;
+		break;
 	case ANSLCD_SETLONGDELAY:
 		if (!capable(CAP_SYS_ADMIN))
-			return -EACCES;
-		anslcd_long_delay=arg;
-		return 0;
+			ret = -EACCES;
+		else
+			anslcd_long_delay=arg;
+		break;
 	default:
-		return -EINVAL;
+		ret = -EINVAL;
 	}
+
+	mutex_unlock(&anslcd_mutex);
+	return ret;
 }
 
 static int
 anslcd_open( struct inode * inode, struct file * file )
 {
-	cycle_kernel_lock();
 	return 0;
 }
 
 const struct file_operations anslcd_fops = {
-	.write	= anslcd_write,
-	.ioctl	= anslcd_ioctl,
-	.open	= anslcd_open,
+	.write		= anslcd_write,
+	.unlocked_ioctl	= anslcd_ioctl,
+	.open		= anslcd_open,
 };
 
 static struct miscdevice anslcd_dev = {
@@ -168,6 +177,7 @@
 	printk(KERN_DEBUG "LCD: init\n");
 #endif
 
+	mutex_lock(&anslcd_mutex);
 	anslcd_write_byte_ctrl ( 0x38 );
 	anslcd_write_byte_ctrl ( 0x0c );
 	anslcd_write_byte_ctrl ( 0x06 );
@@ -176,6 +186,7 @@
 	for(a=0;a<80;a++) {
 		anslcd_write_byte_data(anslcd_logo[a]);
 	}
+	mutex_unlock(&anslcd_mutex);
 	return 0;
 }
 
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
index 8b93644..3fbe41b 100644
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -15,7 +15,7 @@
  *
  *	WARNING: This driver has only been testen on Apple's
  *	1.25 MHz Dual G4 (March 03). It is tuned for a CPU
- *	temperatur around 57 C.
+ *	temperature around 57 C.
  *
  *   Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se)
  *
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index ed10381..e412980 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -988,7 +988,7 @@
 		goto bad_cipher;
 	}
 
-	/* Compatiblity mode for old dm-crypt cipher strings */
+	/* Compatibility mode for old dm-crypt cipher strings */
 	if (!chainmode || (strcmp(chainmode, "plain") == 0 && !ivmode)) {
 		chainmode = "cbc";
 		ivmode = "plain";
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 32d0b87..dce971d 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -1116,8 +1116,9 @@
 	return limit_reached;
 }
 
-static void pg_init_done(struct dm_path *path, int errors)
+static void pg_init_done(void *data, int errors)
 {
+	struct dm_path *path = data;
 	struct pgpath *pgpath = path_to_pgpath(path);
 	struct priority_group *pg = pgpath->pg;
 	struct multipath *m = pg->m;
@@ -1183,12 +1184,11 @@
 
 static void activate_path(struct work_struct *work)
 {
-	int ret;
 	struct pgpath *pgpath =
 		container_of(work, struct pgpath, activate_path);
 
-	ret = scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev));
-	pg_init_done(&pgpath->path, ret);
+	scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev),
+				pg_init_done, &pgpath->path);
 }
 
 /*
diff --git a/drivers/media/common/Makefile b/drivers/media/common/Makefile
index 351b98b..169b337 100644
--- a/drivers/media/common/Makefile
+++ b/drivers/media/common/Makefile
@@ -1,6 +1,6 @@
 saa7146-objs    := saa7146_i2c.o saa7146_core.o
 saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o
-ir-common-objs  := ir-functions.o ir-keymaps.o
+ir-common-objs  := ir-functions.o ir-keymaps.o ir-keytable.o
 
 obj-y += tuners/
 obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o
diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c
index abd4791..e616f62 100644
--- a/drivers/media/common/ir-functions.c
+++ b/drivers/media/common/ir-functions.c
@@ -34,22 +34,19 @@
 module_param(repeat, int, 0444);
 MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)");
 
-static int debug;    /* debug level (0,1,2) */
-module_param(debug, int, 0644);
-
-#define dprintk(level, fmt, arg...)	if (debug >= level) \
-	printk(KERN_DEBUG fmt , ## arg)
+int media_ir_debug;    /* media_ir_debug level (0,1,2) */
+module_param_named(debug, media_ir_debug, int, 0644);
 
 /* -------------------------------------------------------------------------- */
 
 static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
 {
 	if (KEY_RESERVED == ir->keycode) {
-		printk(KERN_INFO "%s: unknown key: key=0x%02x raw=0x%02x down=%d\n",
-		       dev->name,ir->ir_key,ir->ir_raw,ir->keypressed);
+		printk(KERN_INFO "%s: unknown key: key=0x%02x down=%d\n",
+		       dev->name, ir->ir_key, ir->keypressed);
 		return;
 	}
-	dprintk(1,"%s: key event code=%d down=%d\n",
+	IR_dprintk(1,"%s: key event code=%d down=%d\n",
 		dev->name,ir->keycode,ir->keypressed);
 	input_report_key(dev,ir->keycode,ir->keypressed);
 	input_sync(dev);
@@ -57,39 +54,34 @@
 
 /* -------------------------------------------------------------------------- */
 
-void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
+int ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
 		   int ir_type, struct ir_scancode_table *ir_codes)
 {
-	int i;
-
 	ir->ir_type = ir_type;
 
-	memset(ir->ir_codes, 0, sizeof(ir->ir_codes));
+	ir->keytable.size = ir_roundup_tablesize(ir_codes->size);
+	ir->keytable.scan = kzalloc(ir->keytable.size *
+				    sizeof(struct ir_scancode), GFP_KERNEL);
+	if (!ir->keytable.scan)
+		return -ENOMEM;
 
-	/*
-	 * FIXME: This is a temporary workaround to use the new IR tables
-	 * with the old approach. Later patches will replace this to a
-	 * proper method
-	 */
+	IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n",
+		ir->keytable.size,
+		ir->keytable.size * sizeof(ir->keytable.scan));
 
-	if (ir_codes)
-		for (i = 0; i < ir_codes->size; i++)
-			if (ir_codes->scan[i].scancode < IR_KEYTAB_SIZE)
-				ir->ir_codes[ir_codes->scan[i].scancode] = ir_codes->scan[i].keycode;
+	ir_copy_table(&ir->keytable, ir_codes);
+	ir_set_keycode_table(dev, &ir->keytable);
 
-	dev->keycode     = ir->ir_codes;
-	dev->keycodesize = sizeof(IR_KEYTAB_TYPE);
-	dev->keycodemax  = IR_KEYTAB_SIZE;
-	for (i = 0; i < IR_KEYTAB_SIZE; i++)
-		set_bit(ir->ir_codes[i], dev->keybit);
 	clear_bit(0, dev->keybit);
-
 	set_bit(EV_KEY, dev->evbit);
 	if (repeat)
 		set_bit(EV_REP, dev->evbit);
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(ir_input_init);
 
+
 void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir)
 {
 	if (ir->keypressed) {
@@ -100,9 +92,9 @@
 EXPORT_SYMBOL_GPL(ir_input_nokey);
 
 void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
-		      u32 ir_key, u32 ir_raw)
+		      u32 ir_key)
 {
-	u32 keycode = IR_KEYCODE(ir->ir_codes, ir_key);
+	u32 keycode = ir_g_keycode_from_table(dev, ir_key);
 
 	if (ir->keypressed && ir->keycode != keycode) {
 		ir->keypressed = 0;
@@ -110,7 +102,6 @@
 	}
 	if (!ir->keypressed) {
 		ir->ir_key  = ir_key;
-		ir->ir_raw  = ir_raw;
 		ir->keycode = keycode;
 		ir->keypressed = 1;
 		ir_input_key_event(dev,ir);
@@ -275,7 +266,7 @@
  * saa7134 */
 
 /* decode raw bit pattern to RC5 code */
-static u32 ir_rc5_decode(unsigned int code)
+u32 ir_rc5_decode(unsigned int code)
 {
 	unsigned int org_code = code;
 	unsigned int pair;
@@ -295,15 +286,16 @@
 			rc5 |= 1;
 			break;
 		case 3:
-			dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code);
+			IR_dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code);
 			return 0;
 		}
 	}
-	dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
+	IR_dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
 		"instr=%x\n", rc5, org_code, RC5_START(rc5),
 		RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
 	return rc5;
 }
+EXPORT_SYMBOL_GPL(ir_rc5_decode);
 
 void ir_rc5_timer_end(unsigned long data)
 {
@@ -330,20 +322,20 @@
 
 	/* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */
 	if (gap < 28000) {
-		dprintk(1, "ir-common: spurious timer_end\n");
+		IR_dprintk(1, "ir-common: spurious timer_end\n");
 		return;
 	}
 
 	if (ir->last_bit < 20) {
 		/* ignore spurious codes (caused by light/other remotes) */
-		dprintk(1, "ir-common: short code: %x\n", ir->code);
+		IR_dprintk(1, "ir-common: short code: %x\n", ir->code);
 	} else {
 		ir->code = (ir->code << ir->shift_by) | 1;
 		rc5 = ir_rc5_decode(ir->code);
 
 		/* two start bits? */
 		if (RC5_START(rc5) != ir->start) {
-			dprintk(1, "ir-common: rc5 start bits invalid: %u\n", RC5_START(rc5));
+			IR_dprintk(1, "ir-common: rc5 start bits invalid: %u\n", RC5_START(rc5));
 
 			/* right address? */
 		} else if (RC5_ADDR(rc5) == ir->addr) {
@@ -353,11 +345,10 @@
 			/* Good code, decide if repeat/repress */
 			if (toggle != RC5_TOGGLE(ir->last_rc5) ||
 			    instr != RC5_INSTR(ir->last_rc5)) {
-				dprintk(1, "ir-common: instruction %x, toggle %x\n", instr,
+				IR_dprintk(1, "ir-common: instruction %x, toggle %x\n", instr,
 					toggle);
 				ir_input_nokey(ir->dev, &ir->ir);
-				ir_input_keydown(ir->dev, &ir->ir, instr,
-						 instr);
+				ir_input_keydown(ir->dev, &ir->ir, instr);
 			}
 
 			/* Set/reset key-up timer */
@@ -376,7 +367,7 @@
 {
 	struct card_ir *ir = (struct card_ir *)data;
 
-	dprintk(1, "ir-common: key released\n");
+	IR_dprintk(1, "ir-common: key released\n");
 	ir_input_nokey(ir->dev, &ir->ir);
 }
 EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup);
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c
index f679017..328c973 100644
--- a/drivers/media/common/ir-keymaps.c
+++ b/drivers/media/common/ir-keymaps.c
@@ -1705,6 +1705,7 @@
 	{ 0x37, KEY_RADIO },		/* FM */
 	{ 0x38, KEY_DVD },
 
+	{ 0x1a, KEY_MODE},		/* change to MCE mode on Y04G0051 */
 	{ 0x3e, KEY_F21 },		/* MCE +VOL, on Y04G0033 */
 	{ 0x3a, KEY_F22 },		/* MCE -VOL, on Y04G0033 */
 	{ 0x3b, KEY_F23 },		/* MCE +CH,  on Y04G0033 */
@@ -1846,6 +1847,76 @@
 };
 EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new_table);
 
+/*
+ * Hauppauge:the newer, gray remotes (seems there are multiple
+ * slightly different versions), shipped with cx88+ivtv cards.
+ *
+ * This table contains the complete RC5 code, instead of just the data part
+ */
+static struct ir_scancode ir_codes_rc5_hauppauge_new[] = {
+	/* Keys 0 to 9 */
+	{ 0x1e00, KEY_0 },
+	{ 0x1e01, KEY_1 },
+	{ 0x1e02, KEY_2 },
+	{ 0x1e03, KEY_3 },
+	{ 0x1e04, KEY_4 },
+	{ 0x1e05, KEY_5 },
+	{ 0x1e06, KEY_6 },
+	{ 0x1e07, KEY_7 },
+	{ 0x1e08, KEY_8 },
+	{ 0x1e09, KEY_9 },
+
+	{ 0x1e0a, KEY_TEXT },		/* keypad asterisk as well */
+	{ 0x1e0b, KEY_RED },		/* red button */
+	{ 0x1e0c, KEY_RADIO },
+	{ 0x1e0d, KEY_MENU },
+	{ 0x1e0e, KEY_SUBTITLE },		/* also the # key */
+	{ 0x1e0f, KEY_MUTE },
+	{ 0x1e10, KEY_VOLUMEUP },
+	{ 0x1e11, KEY_VOLUMEDOWN },
+	{ 0x1e12, KEY_PREVIOUS },		/* previous channel */
+	{ 0x1e14, KEY_UP },
+	{ 0x1e15, KEY_DOWN },
+	{ 0x1e16, KEY_LEFT },
+	{ 0x1e17, KEY_RIGHT },
+	{ 0x1e18, KEY_VIDEO },		/* Videos */
+	{ 0x1e19, KEY_AUDIO },		/* Music */
+	/* 0x1e1a: Pictures - presume this means
+	   "Multimedia Home Platform" -
+	   no "PICTURES" key in input.h
+	 */
+	{ 0x1e1a, KEY_MHP },
+
+	{ 0x1e1b, KEY_EPG },		/* Guide */
+	{ 0x1e1c, KEY_TV },
+	{ 0x1e1e, KEY_NEXTSONG },		/* skip >| */
+	{ 0x1e1f, KEY_EXIT },		/* back/exit */
+	{ 0x1e20, KEY_CHANNELUP },	/* channel / program + */
+	{ 0x1e21, KEY_CHANNELDOWN },	/* channel / program - */
+	{ 0x1e22, KEY_CHANNEL },		/* source (old black remote) */
+	{ 0x1e24, KEY_PREVIOUSSONG },	/* replay |< */
+	{ 0x1e25, KEY_ENTER },		/* OK */
+	{ 0x1e26, KEY_SLEEP },		/* minimize (old black remote) */
+	{ 0x1e29, KEY_BLUE },		/* blue key */
+	{ 0x1e2e, KEY_GREEN },		/* green button */
+	{ 0x1e30, KEY_PAUSE },		/* pause */
+	{ 0x1e32, KEY_REWIND },		/* backward << */
+	{ 0x1e34, KEY_FASTFORWARD },	/* forward >> */
+	{ 0x1e35, KEY_PLAY },
+	{ 0x1e36, KEY_STOP },
+	{ 0x1e37, KEY_RECORD },		/* recording */
+	{ 0x1e38, KEY_YELLOW },		/* yellow key */
+	{ 0x1e3b, KEY_SELECT },		/* top right button */
+	{ 0x1e3c, KEY_ZOOM },		/* full */
+	{ 0x1e3d, KEY_POWER },		/* system power (green button) */
+};
+
+struct ir_scancode_table ir_codes_rc5_hauppauge_new_table = {
+	.scan = ir_codes_rc5_hauppauge_new,
+	.size = ARRAY_SIZE(ir_codes_rc5_hauppauge_new),
+};
+EXPORT_SYMBOL_GPL(ir_codes_rc5_hauppauge_new_table);
+
 static struct ir_scancode ir_codes_npgtech[] = {
 	{ 0x1d, KEY_SWITCHVIDEOMODE },	/* switch inputs */
 	{ 0x2a, KEY_FRONT },
@@ -2964,6 +3035,101 @@
 };
 EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec_table);
 
+static struct ir_scancode ir_codes_tevii_nec[] = {
+	{ 0x0a, KEY_POWER2},
+	{ 0x0c, KEY_MUTE},
+	{ 0x11, KEY_1},
+	{ 0x12, KEY_2},
+	{ 0x13, KEY_3},
+	{ 0x14, KEY_4},
+	{ 0x15, KEY_5},
+	{ 0x16, KEY_6},
+	{ 0x17, KEY_7},
+	{ 0x18, KEY_8},
+	{ 0x19, KEY_9},
+	{ 0x10, KEY_0},
+	{ 0x1c, KEY_MENU},
+	{ 0x0f, KEY_VOLUMEDOWN},
+	{ 0x1a, KEY_LAST},
+	{ 0x0e, KEY_OPEN},
+	{ 0x04, KEY_RECORD},
+	{ 0x09, KEY_VOLUMEUP},
+	{ 0x08, KEY_CHANNELUP},
+	{ 0x07, KEY_PVR},
+	{ 0x0b, KEY_TIME},
+	{ 0x02, KEY_RIGHT},
+	{ 0x03, KEY_LEFT},
+	{ 0x00, KEY_UP},
+	{ 0x1f, KEY_OK},
+	{ 0x01, KEY_DOWN},
+	{ 0x05, KEY_TUNER},
+	{ 0x06, KEY_CHANNELDOWN},
+	{ 0x40, KEY_PLAYPAUSE},
+	{ 0x1e, KEY_REWIND},
+	{ 0x1b, KEY_FAVORITES},
+	{ 0x1d, KEY_BACK},
+	{ 0x4d, KEY_FASTFORWARD},
+	{ 0x44, KEY_EPG},
+	{ 0x4c, KEY_INFO},
+	{ 0x41, KEY_AB},
+	{ 0x43, KEY_AUDIO},
+	{ 0x45, KEY_SUBTITLE},
+	{ 0x4a, KEY_LIST},
+	{ 0x46, KEY_F1},
+	{ 0x47, KEY_F2},
+	{ 0x5e, KEY_F3},
+	{ 0x5c, KEY_F4},
+	{ 0x52, KEY_F5},
+	{ 0x5a, KEY_F6},
+	{ 0x56, KEY_MODE},
+	{ 0x58, KEY_SWITCHVIDEOMODE},
+};
+struct ir_scancode_table ir_codes_tevii_nec_table = {
+	.scan = ir_codes_tevii_nec,
+	.size = ARRAY_SIZE(ir_codes_tevii_nec),
+};
+EXPORT_SYMBOL_GPL(ir_codes_tevii_nec_table);
+
+static struct ir_scancode ir_codes_tbs_nec[] = {
+	{ 0x04, KEY_POWER2},	/*power*/
+	{ 0x14, KEY_MUTE},	/*mute*/
+	{ 0x07, KEY_1},
+	{ 0x06, KEY_2},
+	{ 0x05, KEY_3},
+	{ 0x0b, KEY_4},
+	{ 0x0a, KEY_5},
+	{ 0x09, KEY_6},
+	{ 0x0f, KEY_7},
+	{ 0x0e, KEY_8},
+	{ 0x0d, KEY_9},
+	{ 0x12, KEY_0},
+	{ 0x16, KEY_CHANNELUP},	/*ch+*/
+	{ 0x11, KEY_CHANNELDOWN},/*ch-*/
+	{ 0x13, KEY_VOLUMEUP},	/*vol+*/
+	{ 0x0c, KEY_VOLUMEDOWN},/*vol-*/
+	{ 0x03, KEY_RECORD},	/*rec*/
+	{ 0x18, KEY_PAUSE},	/*pause*/
+	{ 0x19, KEY_OK},	/*ok*/
+	{ 0x1a, KEY_CAMERA},	/* snapshot */
+	{ 0x01, KEY_UP},
+	{ 0x10, KEY_LEFT},
+	{ 0x02, KEY_RIGHT},
+	{ 0x08, KEY_DOWN},
+	{ 0x15, KEY_FAVORITES},
+	{ 0x17, KEY_SUBTITLE},
+	{ 0x1d, KEY_ZOOM},
+	{ 0x1f, KEY_EXIT},
+	{ 0x1e, KEY_MENU},
+	{ 0x1c, KEY_EPG},
+	{ 0x00, KEY_PREVIOUS},
+	{ 0x1b, KEY_MODE},
+};
+struct ir_scancode_table ir_codes_tbs_nec_table = {
+	.scan = ir_codes_tbs_nec,
+	.size = ARRAY_SIZE(ir_codes_tbs_nec),
+};
+EXPORT_SYMBOL_GPL(ir_codes_tbs_nec_table);
+
 /* Terratec Cinergy Hybrid T USB XS
    Devin Heitmueller <dheitmueller@linuxtv.org>
  */
@@ -3147,3 +3313,4 @@
 	.size = ARRAY_SIZE(ir_codes_gadmei_rm008z),
 };
 EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table);
+
diff --git a/drivers/media/common/ir-keytable.c b/drivers/media/common/ir-keytable.c
new file mode 100644
index 0000000..26ce5bc
--- /dev/null
+++ b/drivers/media/common/ir-keytable.c
@@ -0,0 +1,429 @@
+/* ir-register.c - handle IR scancode->keycode tables
+ *
+ * Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ */
+
+#include <linux/usb/input.h>
+
+#include <media/ir-common.h>
+
+#define IR_TAB_MIN_SIZE	32
+#define IR_TAB_MAX_SIZE	1024
+
+/**
+ * ir_seek_table() - returns the element order on the table
+ * @rc_tab:	the ir_scancode_table with the keymap to be used
+ * @scancode:	the scancode that we're seeking
+ *
+ * This routine is used by the input routines when a key is pressed at the
+ * IR. The scancode is received and needs to be converted into a keycode.
+ * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the
+ * corresponding keycode from the table.
+ */
+static int ir_seek_table(struct ir_scancode_table *rc_tab, u32 scancode)
+{
+	int rc;
+	unsigned long flags;
+	struct ir_scancode *keymap = rc_tab->scan;
+
+	spin_lock_irqsave(&rc_tab->lock, flags);
+
+	/* FIXME: replace it by a binary search */
+
+	for (rc = 0; rc < rc_tab->size; rc++)
+		if (keymap[rc].scancode == scancode)
+			goto exit;
+
+	/* Not found */
+	rc = -EINVAL;
+
+exit:
+	spin_unlock_irqrestore(&rc_tab->lock, flags);
+	return rc;
+}
+
+/**
+ * ir_roundup_tablesize() - gets an optimum value for the table size
+ * @n_elems:		minimum number of entries to store keycodes
+ *
+ * This routine is used to choose the keycode table size.
+ *
+ * In order to have some empty space for new keycodes,
+ * and knowing in advance that kmalloc allocates only power of two
+ * segments, it optimizes the allocated space to have some spare space
+ * for those new keycodes by using the maximum number of entries that
+ * will be effectively be allocated by kmalloc.
+ * In order to reduce the quantity of table resizes, it has a minimum
+ * table size of IR_TAB_MIN_SIZE.
+ */
+int ir_roundup_tablesize(int n_elems)
+{
+	size_t size;
+
+	if (n_elems < IR_TAB_MIN_SIZE)
+		n_elems = IR_TAB_MIN_SIZE;
+
+	/*
+	 * As kmalloc only allocates sizes of power of two, get as
+	 * much entries as possible for the allocated memory segment
+	 */
+	size = roundup_pow_of_two(n_elems * sizeof(struct ir_scancode));
+	n_elems = size / sizeof(struct ir_scancode);
+
+	return n_elems;
+}
+
+/**
+ * ir_copy_table() - copies a keytable, discarding the unused entries
+ * @destin:	destin table
+ * @origin:	origin table
+ *
+ * Copies all entries where the keycode is not KEY_UNKNOWN/KEY_RESERVED
+ */
+
+int ir_copy_table(struct ir_scancode_table *destin,
+		 const struct ir_scancode_table *origin)
+{
+	int i, j = 0;
+
+	for (i = 0; i < origin->size; i++) {
+		if (origin->scan[i].keycode == KEY_UNKNOWN ||
+		   origin->scan[i].keycode == KEY_RESERVED)
+			continue;
+
+		memcpy(&destin->scan[j], &origin->scan[i], sizeof(struct ir_scancode));
+		j++;
+	}
+	destin->size = j;
+
+	IR_dprintk(1, "Copied %d scancodes to the new keycode table\n", destin->size);
+
+	return 0;
+}
+
+/**
+ * ir_getkeycode() - get a keycode at the evdev scancode ->keycode table
+ * @dev:	the struct input_dev device descriptor
+ * @scancode:	the desired scancode
+ * @keycode:	the keycode to be retorned.
+ *
+ * This routine is used to handle evdev EVIOCGKEY ioctl.
+ * If the key is not found, returns -EINVAL, otherwise, returns 0.
+ */
+static int ir_getkeycode(struct input_dev *dev,
+			 int scancode, int *keycode)
+{
+	int elem;
+	struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
+
+	elem = ir_seek_table(rc_tab, scancode);
+	if (elem >= 0) {
+		*keycode = rc_tab->scan[elem].keycode;
+		return 0;
+	}
+
+	/*
+	 * Scancode not found and table can't be expanded
+	 */
+	if (elem < 0 && rc_tab->size == IR_TAB_MAX_SIZE)
+		return -EINVAL;
+
+	/*
+	 * If is there extra space, returns KEY_RESERVED,
+	 * otherwise, input core won't let ir_setkeycode to work
+	 */
+	*keycode = KEY_RESERVED;
+	return 0;
+}
+
+
+/**
+ * ir_is_resize_needed() - Check if the table needs rezise
+ * @table:		keycode table that may need to resize
+ * @n_elems:		minimum number of entries to store keycodes
+ *
+ * Considering that kmalloc uses power of two storage areas, this
+ * routine detects if the real alloced size will change. If not, it
+ * just returns without doing nothing. Otherwise, it will extend or
+ * reduce the table size to meet the new needs.
+ *
+ * It returns 0 if no resize is needed, 1 otherwise.
+ */
+static int ir_is_resize_needed(struct ir_scancode_table *table, int n_elems)
+{
+	int cur_size = ir_roundup_tablesize(table->size);
+	int new_size = ir_roundup_tablesize(n_elems);
+
+	if (cur_size == new_size)
+		return 0;
+
+	/* Resize is needed */
+	return 1;
+}
+
+/**
+ * ir_delete_key() - remove a keycode from the table
+ * @rc_tab:		keycode table
+ * @elem:		element to be removed
+ *
+ */
+static void ir_delete_key(struct ir_scancode_table *rc_tab, int elem)
+{
+	unsigned long flags = 0;
+	int newsize = rc_tab->size - 1;
+	int resize = ir_is_resize_needed(rc_tab, newsize);
+	struct ir_scancode *oldkeymap = rc_tab->scan;
+	struct ir_scancode *newkeymap;
+
+	if (resize) {
+		newkeymap = kzalloc(ir_roundup_tablesize(newsize) *
+				    sizeof(*newkeymap), GFP_ATOMIC);
+
+		/* There's no memory for resize. Keep the old table */
+		if (!newkeymap)
+			resize = 0;
+	}
+
+	if (!resize) {
+		newkeymap = oldkeymap;
+
+		/* We'll modify the live table. Lock it */
+		spin_lock_irqsave(&rc_tab->lock, flags);
+	}
+
+	/*
+	 * Copy the elements before the one that will be deleted
+	 * if (!resize), both oldkeymap and newkeymap points
+	 * to the same place, so, there's no need to copy
+	 */
+	if (resize && elem > 0)
+		memcpy(newkeymap, oldkeymap,
+		       elem * sizeof(*newkeymap));
+
+	/*
+	 * Copy the other elements overwriting the element to be removed
+	 * This operation applies to both resize and non-resize case
+	 */
+	if (elem < newsize)
+		memcpy(&newkeymap[elem], &oldkeymap[elem + 1],
+		       (newsize - elem) * sizeof(*newkeymap));
+
+	if (resize) {
+		/*
+		 * As the copy happened to a temporary table, only here
+		 * it needs to lock while replacing the table pointers
+		 * to use the new table
+		 */
+		spin_lock_irqsave(&rc_tab->lock, flags);
+		rc_tab->size = newsize;
+		rc_tab->scan = newkeymap;
+		spin_unlock_irqrestore(&rc_tab->lock, flags);
+
+		/* Frees the old keytable */
+		kfree(oldkeymap);
+	} else {
+		rc_tab->size = newsize;
+		spin_unlock_irqrestore(&rc_tab->lock, flags);
+	}
+}
+
+/**
+ * ir_insert_key() - insert a keycode at the table
+ * @rc_tab:		keycode table
+ * @scancode:	the desired scancode
+ * @keycode:	the keycode to be retorned.
+ *
+ */
+static int ir_insert_key(struct ir_scancode_table *rc_tab,
+			  int scancode, int keycode)
+{
+	unsigned long flags;
+	int elem = rc_tab->size;
+	int newsize = rc_tab->size + 1;
+	int resize = ir_is_resize_needed(rc_tab, newsize);
+	struct ir_scancode *oldkeymap = rc_tab->scan;
+	struct ir_scancode *newkeymap;
+
+	if (resize) {
+		newkeymap = kzalloc(ir_roundup_tablesize(newsize) *
+				    sizeof(*newkeymap), GFP_ATOMIC);
+		if (!newkeymap)
+			return -ENOMEM;
+
+		memcpy(newkeymap, oldkeymap,
+		       rc_tab->size * sizeof(*newkeymap));
+	} else
+		newkeymap  = oldkeymap;
+
+	/* Stores the new code at the table */
+	IR_dprintk(1, "#%d: New scan 0x%04x with key 0x%04x\n",
+		   rc_tab->size, scancode, keycode);
+
+	spin_lock_irqsave(&rc_tab->lock, flags);
+	rc_tab->size = newsize;
+	if (resize) {
+		rc_tab->scan = newkeymap;
+		kfree(oldkeymap);
+	}
+	newkeymap[elem].scancode = scancode;
+	newkeymap[elem].keycode  = keycode;
+	spin_unlock_irqrestore(&rc_tab->lock, flags);
+
+	return 0;
+}
+
+/**
+ * ir_setkeycode() - set a keycode at the evdev scancode ->keycode table
+ * @dev:	the struct input_dev device descriptor
+ * @scancode:	the desired scancode
+ * @keycode:	the keycode to be retorned.
+ *
+ * This routine is used to handle evdev EVIOCSKEY ioctl.
+ * There's one caveat here: how can we increase the size of the table?
+ * If the key is not found, returns -EINVAL, otherwise, returns 0.
+ */
+static int ir_setkeycode(struct input_dev *dev,
+			 int scancode, int keycode)
+{
+	int rc = 0;
+	struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
+	struct ir_scancode *keymap = rc_tab->scan;
+	unsigned long flags;
+
+	/*
+	 * Handle keycode table deletions
+	 *
+	 * If userspace is adding a KEY_UNKNOWN or KEY_RESERVED,
+	 * deal as a trial to remove an existing scancode attribution
+	 * if table become too big, reduce it to save space
+	 */
+	if (keycode == KEY_UNKNOWN || keycode == KEY_RESERVED) {
+		rc = ir_seek_table(rc_tab, scancode);
+		if (rc < 0)
+			return 0;
+
+		IR_dprintk(1, "#%d: Deleting scan 0x%04x\n", rc, scancode);
+		clear_bit(keymap[rc].keycode, dev->keybit);
+		ir_delete_key(rc_tab, rc);
+
+		return 0;
+	}
+
+	/*
+	 * Handle keycode replacements
+	 *
+	 * If the scancode exists, just replace by the new value
+	 */
+	rc = ir_seek_table(rc_tab, scancode);
+	if (rc >= 0) {
+		IR_dprintk(1, "#%d: Replacing scan 0x%04x with key 0x%04x\n",
+			rc, scancode, keycode);
+
+		clear_bit(keymap[rc].keycode, dev->keybit);
+
+		spin_lock_irqsave(&rc_tab->lock, flags);
+		keymap[rc].keycode = keycode;
+		spin_unlock_irqrestore(&rc_tab->lock, flags);
+
+		set_bit(keycode, dev->keybit);
+
+		return 0;
+	}
+
+	/*
+	 * Handle new scancode inserts
+	 *
+	 * reallocate table if needed and insert a new keycode
+	 */
+
+	/* Avoid growing the table indefinitely */
+	if (rc_tab->size + 1 > IR_TAB_MAX_SIZE)
+		return -EINVAL;
+
+	rc = ir_insert_key(rc_tab, scancode, keycode);
+	if (rc < 0)
+		return rc;
+	set_bit(keycode, dev->keybit);
+
+	return 0;
+}
+
+/**
+ * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode
+ * @input_dev:	the struct input_dev descriptor of the device
+ * @scancode:	the scancode that we're seeking
+ *
+ * This routine is used by the input routines when a key is pressed at the
+ * IR. The scancode is received and needs to be converted into a keycode.
+ * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the
+ * corresponding keycode from the table.
+ */
+u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
+{
+	struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
+	struct ir_scancode *keymap = rc_tab->scan;
+	int elem;
+
+	elem = ir_seek_table(rc_tab, scancode);
+	if (elem >= 0) {
+		IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n",
+			   dev->name, scancode, keymap[elem].keycode);
+
+		return rc_tab->scan[elem].keycode;
+	}
+
+	printk(KERN_INFO "%s: unknown key for scancode 0x%04x\n",
+	       dev->name, scancode);
+
+	/* Reports userspace that an unknown keycode were got */
+	return KEY_RESERVED;
+}
+
+/**
+ * ir_set_keycode_table() - sets the IR keycode table and add the handlers
+ *			    for keymap table get/set
+ * @input_dev:	the struct input_dev descriptor of the device
+ * @rc_tab:	the struct ir_scancode_table table of scancode/keymap
+ *
+ * This routine is used to initialize the input infrastructure to work with
+ * an IR.
+ * It should be called before registering the IR device.
+ */
+int ir_set_keycode_table(struct input_dev *input_dev,
+			 struct ir_scancode_table *rc_tab)
+{
+	struct ir_scancode *keymap = rc_tab->scan;
+	int i;
+
+	spin_lock_init(&rc_tab->lock);
+
+	if (rc_tab->scan == NULL || !rc_tab->size)
+		return -EINVAL;
+
+	/* set the bits for the keys */
+	IR_dprintk(1, "key map size: %d\n", rc_tab->size);
+	for (i = 0; i < rc_tab->size; i++) {
+		IR_dprintk(1, "#%d: setting bit for keycode 0x%04x\n",
+			i, keymap[i].keycode);
+		set_bit(keymap[i].keycode, input_dev->keybit);
+	}
+
+	input_dev->getkeycode = ir_getkeycode;
+	input_dev->setkeycode = ir_setkeycode;
+	input_set_drvdata(input_dev, rc_tab);
+
+	return 0;
+}
+
+void ir_input_free(struct input_dev *dev)
+{
+	struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
+
+	IR_dprintk(1, "Freed keycode table\n");
+
+	rc_tab->size = 0;
+	kfree(rc_tab->scan);
+	rc_tab->scan = NULL;
+}
+EXPORT_SYMBOL_GPL(ir_input_free);
+
diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c
index 7e8f568..48cb154 100644
--- a/drivers/media/common/saa7146_i2c.c
+++ b/drivers/media/common/saa7146_i2c.c
@@ -98,7 +98,7 @@
 
 		op_count++;
 
-		/* loop throgh all bytes of message i */
+		/* loop through all bytes of message i */
 		for(j = 0; j < m[i].len; j++) {
 			/* write back all bytes that could have been read */
 			m[i].buf[j] = (le32_to_cpu(op[op_count/3]) >> ((3-(op_count%3))*8));
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index 552dab4..becbaad 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -1205,6 +1205,13 @@
 	return 0;
 }
 
+static void release_all_pagetables(struct saa7146_dev *dev, struct saa7146_buf *buf)
+{
+	saa7146_pgtable_free(dev->pci, &buf->pt[0]);
+	saa7146_pgtable_free(dev->pci, &buf->pt[1]);
+	saa7146_pgtable_free(dev->pci, &buf->pt[2]);
+}
+
 static int buffer_prepare(struct videobuf_queue *q,
 			  struct videobuf_buffer *vb, enum v4l2_field field)
 {
@@ -1257,16 +1264,12 @@
 
 		sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
 
+		release_all_pagetables(dev, buf);
 		if( 0 != IS_PLANAR(sfmt->trans)) {
-			saa7146_pgtable_free(dev->pci, &buf->pt[0]);
-			saa7146_pgtable_free(dev->pci, &buf->pt[1]);
-			saa7146_pgtable_free(dev->pci, &buf->pt[2]);
-
 			saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
 			saa7146_pgtable_alloc(dev->pci, &buf->pt[1]);
 			saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
 		} else {
-			saa7146_pgtable_free(dev->pci, &buf->pt[0]);
 			saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
 		}
 
@@ -1329,6 +1332,9 @@
 	struct saa7146_buf *buf = (struct saa7146_buf *)vb;
 
 	DEB_CAP(("vbuf:%p\n",vb));
+
+	release_all_pagetables(dev, buf);
+
 	saa7146_dma_free(dev,q,buf);
 }
 
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
index 607d319..409a426 100644
--- a/drivers/media/common/tuners/Kconfig
+++ b/drivers/media/common/tuners/Kconfig
@@ -172,4 +172,11 @@
 	help
 	  Say Y here to support the Freescale MC44S803 based tuners
 
+config MEDIA_TUNER_MAX2165
+	tristate "Maxim MAX2165 silicon tuner"
+	depends on VIDEO_MEDIA && I2C
+	default m if MEDIA_TUNER_CUSTOMISE
+	help
+	  A driver for the silicon tuner MAX2165 from Maxim.
+
 endif # MEDIA_TUNER_CUSTOMISE
diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile
index 4132b2b..a543852 100644
--- a/drivers/media/common/tuners/Makefile
+++ b/drivers/media/common/tuners/Makefile
@@ -23,6 +23,7 @@
 obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o
 obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o
 obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o
+obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o
 
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
 EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/common/tuners/max2165.c b/drivers/media/common/tuners/max2165.c
new file mode 100644
index 0000000..3d03640
--- /dev/null
+++ b/drivers/media/common/tuners/max2165.c
@@ -0,0 +1,442 @@
+/*
+ *  Driver for Maxim MAX2165 silicon tuner
+ *
+ *  Copyright (c) 2009 David T. L. Wong <davidtlwong@gmail.com>
+ *
+ *  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.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/videodev2.h>
+#include <linux/delay.h>
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+
+#include "dvb_frontend.h"
+
+#include "max2165.h"
+#include "max2165_priv.h"
+#include "tuner-i2c.h"
+
+#define dprintk(args...) \
+	do { \
+		if (debug) \
+			printk(KERN_DEBUG "max2165: " args); \
+	} while (0)
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+static int max2165_write_reg(struct max2165_priv *priv, u8 reg, u8 data)
+{
+	int ret;
+	u8 buf[] = { reg, data };
+	struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 };
+
+	msg.addr = priv->config->i2c_address;
+
+	if (debug >= 2)
+		printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
+			__func__, reg, data);
+
+	ret = i2c_transfer(priv->i2c, &msg, 1);
+
+	if (ret != 1)
+		dprintk(KERN_DEBUG "%s: error reg=0x%x, data=0x%x, ret=%i\n",
+			__func__, reg, data, ret);
+
+	return (ret != 1) ? -EIO : 0;
+}
+
+static int max2165_read_reg(struct max2165_priv *priv, u8 reg, u8 *p_data)
+{
+	int ret;
+	u8 dev_addr = priv->config->i2c_address;
+
+	u8 b0[] = { reg };
+	u8 b1[] = { 0 };
+	struct i2c_msg msg[] = {
+		{ .addr = dev_addr, .flags = 0, .buf = b0, .len = 1 },
+		{ .addr = dev_addr, .flags = I2C_M_RD, .buf = b1, .len = 1 },
+	};
+
+	ret = i2c_transfer(priv->i2c, msg, 2);
+	if (ret != 2) {
+		dprintk(KERN_DEBUG "%s: error reg=0x%x, ret=%i\n",
+			__func__, reg, ret);
+		return -EIO;
+	}
+
+	*p_data = b1[0];
+	if (debug >= 2)
+		printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
+			__func__, reg, b1[0]);
+	return 0;
+}
+
+static int max2165_mask_write_reg(struct max2165_priv *priv, u8 reg,
+	u8 mask, u8 data)
+{
+	int ret;
+	u8 v;
+
+	data &= mask;
+	ret = max2165_read_reg(priv, reg, &v);
+	if (ret != 0)
+		return ret;
+	v &= ~mask;
+	v |= data;
+	ret = max2165_write_reg(priv, reg, v);
+
+	return ret;
+}
+
+static int max2165_read_rom_table(struct max2165_priv *priv)
+{
+	u8 dat[3];
+	int i;
+
+	for (i = 0; i < 3; i++) {
+		max2165_write_reg(priv, REG_ROM_TABLE_ADDR, i + 1);
+		max2165_read_reg(priv, REG_ROM_TABLE_DATA, &dat[i]);
+	}
+
+	priv->tf_ntch_low_cfg = dat[0] >> 4;
+	priv->tf_ntch_hi_cfg = dat[0] & 0x0F;
+	priv->tf_balun_low_ref = dat[1] & 0x0F;
+	priv->tf_balun_hi_ref = dat[1] >> 4;
+	priv->bb_filter_7mhz_cfg = dat[2] & 0x0F;
+	priv->bb_filter_8mhz_cfg = dat[2] >> 4;
+
+	dprintk("tf_ntch_low_cfg = 0x%X\n", priv->tf_ntch_low_cfg);
+	dprintk("tf_ntch_hi_cfg = 0x%X\n", priv->tf_ntch_hi_cfg);
+	dprintk("tf_balun_low_ref = 0x%X\n", priv->tf_balun_low_ref);
+	dprintk("tf_balun_hi_ref = 0x%X\n", priv->tf_balun_hi_ref);
+	dprintk("bb_filter_7mhz_cfg = 0x%X\n", priv->bb_filter_7mhz_cfg);
+	dprintk("bb_filter_8mhz_cfg = 0x%X\n", priv->bb_filter_8mhz_cfg);
+
+	return 0;
+}
+
+static int max2165_set_osc(struct max2165_priv *priv, u8 osc /*MHz*/)
+{
+	u8 v;
+
+	v = (osc / 2);
+	if (v == 2)
+		v = 0x7;
+	else
+		v -= 8;
+
+	max2165_mask_write_reg(priv, REG_PLL_CFG, 0x07, v);
+
+	return 0;
+}
+
+static int max2165_set_bandwidth(struct max2165_priv *priv, u32 bw)
+{
+	u8 val;
+
+	if (bw == BANDWIDTH_8_MHZ)
+		val = priv->bb_filter_8mhz_cfg;
+	else
+		val = priv->bb_filter_7mhz_cfg;
+
+	max2165_mask_write_reg(priv, REG_BASEBAND_CTRL, 0xF0, val << 4);
+
+	return 0;
+}
+
+int fixpt_div32(u32 dividend, u32 divisor, u32 *quotient, u32 *fraction)
+{
+	u32 remainder;
+	u32 q, f = 0;
+	int i;
+
+	if (0 == divisor)
+		return -1;
+
+	q = dividend / divisor;
+	remainder = dividend - q * divisor;
+
+	for (i = 0; i < 31; i++) {
+		remainder <<= 1;
+		if (remainder >= divisor) {
+			f += 1;
+			remainder -= divisor;
+		}
+		f <<= 1;
+	}
+
+	*quotient = q;
+	*fraction = f;
+
+	return 0;
+}
+
+static int max2165_set_rf(struct max2165_priv *priv, u32 freq)
+{
+	u8 tf;
+	u8 tf_ntch;
+	u32 t;
+	u32 quotient, fraction;
+
+	/* Set PLL divider according to RF frequency */
+	fixpt_div32(freq / 1000, priv->config->osc_clk * 1000,
+		&quotient, &fraction);
+
+	/* 20-bit fraction */
+	fraction >>= 12;
+
+	max2165_write_reg(priv, REG_NDIV_INT, quotient);
+	max2165_mask_write_reg(priv, REG_NDIV_FRAC2, 0x0F, fraction >> 16);
+	max2165_write_reg(priv, REG_NDIV_FRAC1, fraction >> 8);
+	max2165_write_reg(priv, REG_NDIV_FRAC0, fraction);
+
+	/* Norch Filter */
+	tf_ntch = (freq < 725000000) ?
+		priv->tf_ntch_low_cfg : priv->tf_ntch_hi_cfg;
+
+	/* Tracking filter balun */
+	t = priv->tf_balun_low_ref;
+	t += (priv->tf_balun_hi_ref - priv->tf_balun_low_ref)
+		* (freq / 1000 - 470000) / (780000 - 470000);
+
+	tf = t;
+	dprintk("tf = %X\n", tf);
+	tf |= tf_ntch << 4;
+
+	max2165_write_reg(priv, REG_TRACK_FILTER, tf);
+
+	return 0;
+}
+
+static void max2165_debug_status(struct max2165_priv *priv)
+{
+	u8 status, autotune;
+	u8 auto_vco_success, auto_vco_active;
+	u8 pll_locked;
+	u8 dc_offset_low, dc_offset_hi;
+	u8 signal_lv_over_threshold;
+	u8 vco, vco_sub_band, adc;
+
+	max2165_read_reg(priv, REG_STATUS, &status);
+	max2165_read_reg(priv, REG_AUTOTUNE, &autotune);
+
+	auto_vco_success = (status >> 6) & 0x01;
+	auto_vco_active = (status >> 5) & 0x01;
+	pll_locked = (status >> 4) & 0x01;
+	dc_offset_low = (status >> 3) & 0x01;
+	dc_offset_hi = (status >> 2) & 0x01;
+	signal_lv_over_threshold = status & 0x01;
+
+	vco = autotune >> 6;
+	vco_sub_band = (autotune >> 3) & 0x7;
+	adc = autotune & 0x7;
+
+	dprintk("auto VCO active: %d, auto VCO success: %d\n",
+		auto_vco_active, auto_vco_success);
+	dprintk("PLL locked: %d\n", pll_locked);
+	dprintk("DC offset low: %d, DC offset high: %d\n",
+		dc_offset_low, dc_offset_hi);
+	dprintk("Signal lvl over threshold: %d\n", signal_lv_over_threshold);
+	dprintk("VCO: %d, VCO Sub-band: %d, ADC: %d\n", vco, vco_sub_band, adc);
+}
+
+static int max2165_set_params(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *params)
+{
+	struct max2165_priv *priv = fe->tuner_priv;
+	int ret;
+
+	dprintk("%s() frequency=%d (Hz)\n", __func__, params->frequency);
+	if (fe->ops.info.type == FE_ATSC) {
+			return -EINVAL;
+	} else if (fe->ops.info.type == FE_OFDM) {
+		dprintk("%s() OFDM\n", __func__);
+		switch (params->u.ofdm.bandwidth) {
+		case BANDWIDTH_6_MHZ:
+			return -EINVAL;
+		case BANDWIDTH_7_MHZ:
+		case BANDWIDTH_8_MHZ:
+			priv->frequency = params->frequency;
+			priv->bandwidth = params->u.ofdm.bandwidth;
+			break;
+		default:
+			printk(KERN_ERR "MAX2165 bandwidth not set!\n");
+			return -EINVAL;
+		}
+	} else {
+		printk(KERN_ERR "MAX2165 modulation type not supported!\n");
+		return -EINVAL;
+	}
+
+	dprintk("%s() frequency=%d\n", __func__, priv->frequency);
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+	max2165_set_bandwidth(priv, priv->bandwidth);
+	ret = max2165_set_rf(priv, priv->frequency);
+	mdelay(50);
+	max2165_debug_status(priv);
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	if (ret != 0)
+		return -EREMOTEIO;
+
+	return 0;
+}
+
+static int max2165_get_frequency(struct dvb_frontend *fe, u32 *freq)
+{
+	struct max2165_priv *priv = fe->tuner_priv;
+	dprintk("%s()\n", __func__);
+	*freq = priv->frequency;
+	return 0;
+}
+
+static int max2165_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
+{
+	struct max2165_priv *priv = fe->tuner_priv;
+	dprintk("%s()\n", __func__);
+
+	*bw = priv->bandwidth;
+	return 0;
+}
+
+static int max2165_get_status(struct dvb_frontend *fe, u32 *status)
+{
+	struct max2165_priv *priv = fe->tuner_priv;
+	u16 lock_status = 0;
+
+	dprintk("%s()\n", __func__);
+
+	if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 1);
+
+	max2165_debug_status(priv);
+	*status = lock_status;
+
+	if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 0);
+
+	return 0;
+}
+
+static int max2165_sleep(struct dvb_frontend *fe)
+{
+	dprintk("%s()\n", __func__);
+	return 0;
+}
+
+static int max2165_init(struct dvb_frontend *fe)
+{
+	struct max2165_priv *priv = fe->tuner_priv;
+	dprintk("%s()\n", __func__);
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
+	/* Setup initial values */
+	/* Fractional Mode on */
+	max2165_write_reg(priv, REG_NDIV_FRAC2, 0x18);
+	/* LNA on */
+	max2165_write_reg(priv, REG_LNA, 0x01);
+	max2165_write_reg(priv, REG_PLL_CFG, 0x7A);
+	max2165_write_reg(priv, REG_TEST, 0x08);
+	max2165_write_reg(priv, REG_SHUTDOWN, 0x40);
+	max2165_write_reg(priv, REG_VCO_CTRL, 0x84);
+	max2165_write_reg(priv, REG_BASEBAND_CTRL, 0xC3);
+	max2165_write_reg(priv, REG_DC_OFFSET_CTRL, 0x75);
+	max2165_write_reg(priv, REG_DC_OFFSET_DAC, 0x00);
+	max2165_write_reg(priv, REG_ROM_TABLE_ADDR, 0x00);
+
+	max2165_set_osc(priv, priv->config->osc_clk);
+
+	max2165_read_rom_table(priv);
+
+	max2165_set_bandwidth(priv, BANDWIDTH_8_MHZ);
+
+	if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 0);
+
+	return 0;
+}
+
+static int max2165_release(struct dvb_frontend *fe)
+{
+	struct max2165_priv *priv = fe->tuner_priv;
+	dprintk("%s()\n", __func__);
+
+	kfree(priv);
+	fe->tuner_priv = NULL;
+
+	return 0;
+}
+
+static const struct dvb_tuner_ops max2165_tuner_ops = {
+	.info = {
+		.name           = "Maxim MAX2165",
+		.frequency_min  = 470000000,
+		.frequency_max  = 780000000,
+		.frequency_step =     50000,
+	},
+
+	.release	   = max2165_release,
+	.init		   = max2165_init,
+	.sleep		   = max2165_sleep,
+
+	.set_params	   = max2165_set_params,
+	.set_analog_params = NULL,
+	.get_frequency	   = max2165_get_frequency,
+	.get_bandwidth	   = max2165_get_bandwidth,
+	.get_status	   = max2165_get_status
+};
+
+struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
+				   struct i2c_adapter *i2c,
+				   struct max2165_config *cfg)
+{
+	struct max2165_priv *priv = NULL;
+
+	dprintk("%s(%d-%04x)\n", __func__,
+		i2c ? i2c_adapter_id(i2c) : -1,
+		cfg ? cfg->i2c_address : -1);
+
+	priv = kzalloc(sizeof(struct max2165_priv), GFP_KERNEL);
+	if (priv == NULL)
+		return NULL;
+
+	memcpy(&fe->ops.tuner_ops, &max2165_tuner_ops,
+		sizeof(struct dvb_tuner_ops));
+
+	priv->config = cfg;
+	priv->i2c = i2c;
+	fe->tuner_priv = priv;
+
+	max2165_init(fe);
+	max2165_debug_status(priv);
+
+	return fe;
+}
+EXPORT_SYMBOL(max2165_attach);
+
+MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
+MODULE_DESCRIPTION("Maxim MAX2165 silicon tuner driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/max2165.h b/drivers/media/common/tuners/max2165.h
new file mode 100644
index 0000000..c063c36
--- /dev/null
+++ b/drivers/media/common/tuners/max2165.h
@@ -0,0 +1,48 @@
+/*
+ *  Driver for Maxim MAX2165 silicon tuner
+ *
+ *  Copyright (c) 2009 David T. L. Wong <davidtlwong@gmail.com>
+ *
+ *  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.
+ */
+
+#ifndef __MAX2165_H__
+#define __MAX2165_H__
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+struct max2165_config {
+	u8 i2c_address;
+	u8 osc_clk; /* in MHz, selectable values: 4,16,18,20,22,24,26,28 */
+};
+
+#if defined(CONFIG_MEDIA_TUNER_MAX2165) || \
+    (defined(CONFIG_MEDIA_TUNER_MAX2165_MODULE) && defined(MODULE))
+extern struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
+	struct i2c_adapter *i2c,
+	struct max2165_config *cfg);
+#else
+static inline struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
+	struct i2c_adapter *i2c,
+	struct max2165_config *cfg)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/common/tuners/max2165_priv.h b/drivers/media/common/tuners/max2165_priv.h
new file mode 100644
index 0000000..91bbe02
--- /dev/null
+++ b/drivers/media/common/tuners/max2165_priv.h
@@ -0,0 +1,60 @@
+/*
+ *  Driver for Maxim MAX2165 silicon tuner
+ *
+ *  Copyright (c) 2009 David T. L. Wong <davidtlwong@gmail.com>
+ *
+ *  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.
+ */
+
+#ifndef __MAX2165_PRIV_H__
+#define __MAX2165_PRIV_H__
+
+#define REG_NDIV_INT 0x00
+#define REG_NDIV_FRAC2 0x01
+#define REG_NDIV_FRAC1 0x02
+#define REG_NDIV_FRAC0 0x03
+#define REG_TRACK_FILTER 0x04
+#define REG_LNA 0x05
+#define REG_PLL_CFG 0x06
+#define REG_TEST 0x07
+#define REG_SHUTDOWN 0x08
+#define REG_VCO_CTRL 0x09
+#define REG_BASEBAND_CTRL 0x0A
+#define REG_DC_OFFSET_CTRL 0x0B
+#define REG_DC_OFFSET_DAC 0x0C
+#define REG_ROM_TABLE_ADDR 0x0D
+
+/* Read Only Registers */
+#define REG_ROM_TABLE_DATA 0x10
+#define REG_STATUS 0x11
+#define REG_AUTOTUNE 0x12
+
+struct max2165_priv {
+	struct max2165_config *config;
+	struct i2c_adapter *i2c;
+
+	u32 frequency;
+	u32 bandwidth;
+
+	u8 tf_ntch_low_cfg;
+	u8 tf_ntch_hi_cfg;
+	u8 tf_balun_low_ref;
+	u8 tf_balun_hi_ref;
+	u8 bb_filter_7mhz_cfg;
+	u8 bb_filter_8mhz_cfg;
+};
+
+#endif
diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c
index 0803dab..605e28b 100644
--- a/drivers/media/common/tuners/mxl5005s.c
+++ b/drivers/media/common/tuners/mxl5005s.c
@@ -2789,7 +2789,10 @@
 
 	/* add for 2.6.5 Special setting for QAM */
 	if (state->Mod_Type == MXL_QAM) {
-		if (state->RF_IN < 680000000)
+		if (state->config->qam_gain != 0)
+			status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN,
+						   state->config->qam_gain);
+		else if (state->RF_IN < 680000000)
 			status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
 		else
 			status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 2);
diff --git a/drivers/media/common/tuners/mxl5005s.h b/drivers/media/common/tuners/mxl5005s.h
index 7ac6815..fc8a1ff 100644
--- a/drivers/media/common/tuners/mxl5005s.h
+++ b/drivers/media/common/tuners/mxl5005s.h
@@ -108,6 +108,10 @@
 #define MXL_LOW_IF  1
 	u8 if_mode;
 
+	/* Some boards need to override the built-in logic for determining
+	   the gain when in QAM mode (the HVR-1600 is one such case) */
+	u8 qam_gain;
+
 	/* Stuff I don't know what to do with */
 	u8 AgcMasterByte;
 };
diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c
index 2d02698..7eb1bf7 100644
--- a/drivers/media/common/tuners/mxl5007t.c
+++ b/drivers/media/common/tuners/mxl5007t.c
@@ -196,7 +196,7 @@
 	i = j = 0;
 
 	while (reg_pair1[i].reg || reg_pair1[i].val) {
-		while (reg_pair2[j].reg || reg_pair2[j].reg) {
+		while (reg_pair2[j].reg || reg_pair2[j].val) {
 			if (reg_pair1[i].reg != reg_pair2[j].reg) {
 				j++;
 				continue;
diff --git a/drivers/media/common/tuners/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c
index 155c93e..e1f6782 100644
--- a/drivers/media/common/tuners/tda18271-common.c
+++ b/drivers/media/common/tuners/tda18271-common.c
@@ -326,12 +326,24 @@
 	regs[R_EB22] = 0x48;
 	regs[R_EB23] = 0xb0;
 
-	if (priv->small_i2c) {
+	switch (priv->small_i2c) {
+	case TDA18271_08_BYTE_CHUNK_INIT:
+		tda18271_write_regs(fe, 0x00, 0x08);
+		tda18271_write_regs(fe, 0x08, 0x08);
+		tda18271_write_regs(fe, 0x10, 0x08);
+		tda18271_write_regs(fe, 0x18, 0x08);
+		tda18271_write_regs(fe, 0x20, 0x07);
+		break;
+	case TDA18271_16_BYTE_CHUNK_INIT:
 		tda18271_write_regs(fe, 0x00, 0x10);
 		tda18271_write_regs(fe, 0x10, 0x10);
 		tda18271_write_regs(fe, 0x20, 0x07);
-	} else
+		break;
+	case TDA18271_39_BYTE_CHUNK_INIT:
+	default:
 		tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS);
+		break;
+	}
 
 	/* setup agc1 gain */
 	regs[R_EB17] = 0x00;
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c
index 3a50ce9..b2e1545 100644
--- a/drivers/media/common/tuners/tda18271-fe.c
+++ b/drivers/media/common/tuners/tda18271-fe.c
@@ -256,8 +256,9 @@
 	struct tda18271_priv *priv = fe->tuner_priv;
 	struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
 	unsigned char *regs = priv->tda18271_regs;
-	int tm_current, rfcal_comp, approx, i, ret;
-	u8 dc_over_dt, rf_tab;
+	int i, ret;
+	u8 tm_current, dc_over_dt, rf_tab;
+	s32 rfcal_comp, approx;
 
 	/* power up */
 	ret = tda18271_set_standby_mode(fe, 0, 0, 0);
@@ -277,11 +278,11 @@
 		return i;
 
 	if ((0 == map[i].rf3) || (freq / 1000 < map[i].rf2)) {
-		approx = map[i].rf_a1 *
-			(freq / 1000 - map[i].rf1) + map[i].rf_b1 + rf_tab;
+		approx = map[i].rf_a1 * (s32)(freq / 1000 - map[i].rf1) +
+			map[i].rf_b1 + rf_tab;
 	} else {
-		approx = map[i].rf_a2 *
-			(freq / 1000 - map[i].rf2) + map[i].rf_b2 + rf_tab;
+		approx = map[i].rf_a2 * (s32)(freq / 1000 - map[i].rf2) +
+			map[i].rf_b2 + rf_tab;
 	}
 
 	if (approx < 0)
@@ -292,9 +293,9 @@
 	tda18271_lookup_map(fe, RF_CAL_DC_OVER_DT, &freq, &dc_over_dt);
 
 	/* calculate temperature compensation */
-	rfcal_comp = dc_over_dt * (tm_current - priv->tm_rfcal) / 1000;
+	rfcal_comp = dc_over_dt * (s32)(tm_current - priv->tm_rfcal) / 1000;
 
-	regs[R_EB14] = approx + rfcal_comp;
+	regs[R_EB14] = (unsigned char)(approx + rfcal_comp);
 	ret = tda18271_write_regs(fe, R_EB14, 1);
 fail:
 	return ret;
@@ -572,6 +573,7 @@
 	struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
 	unsigned char *regs = priv->tda18271_regs;
 	int bcal, rf, i;
+	s32 divisor, dividend;
 #define RF1 0
 #define RF2 1
 #define RF3 2
@@ -610,20 +612,22 @@
 		switch (rf) {
 		case RF1:
 			map[i].rf_a1 = 0;
-			map[i].rf_b1 = prog_cal[RF1] - prog_tab[RF1];
+			map[i].rf_b1 = (s32)(prog_cal[RF1] - prog_tab[RF1]);
 			map[i].rf1   = rf_freq[RF1] / 1000;
 			break;
 		case RF2:
-			map[i].rf_a1 = (prog_cal[RF2] - prog_tab[RF2] -
-					prog_cal[RF1] + prog_tab[RF1]) /
-				(s32)((rf_freq[RF2] - rf_freq[RF1]) / 1000);
+			dividend = (s32)(prog_cal[RF2] - prog_tab[RF2]) -
+				   (s32)(prog_cal[RF1] + prog_tab[RF1]);
+			divisor = (s32)(rf_freq[RF2] - rf_freq[RF1]) / 1000;
+			map[i].rf_a1 = (dividend / divisor);
 			map[i].rf2   = rf_freq[RF2] / 1000;
 			break;
 		case RF3:
-			map[i].rf_a2 = (prog_cal[RF3] - prog_tab[RF3] -
-					prog_cal[RF2] + prog_tab[RF2]) /
-				(s32)((rf_freq[RF3] - rf_freq[RF2]) / 1000);
-			map[i].rf_b2 = prog_cal[RF2] - prog_tab[RF2];
+			dividend = (s32)(prog_cal[RF3] - prog_tab[RF3]) -
+				   (s32)(prog_cal[RF2] + prog_tab[RF2]);
+			divisor = (s32)(rf_freq[RF3] - rf_freq[RF2]) / 1000;
+			map[i].rf_a2 = (dividend / divisor);
+			map[i].rf_b2 = (s32)(prog_cal[RF2] - prog_tab[RF2]);
 			map[i].rf3   = rf_freq[RF3] / 1000;
 			break;
 		default:
@@ -1181,6 +1185,48 @@
 	return ret;
 }
 
+static int tda18271_setup_configuration(struct dvb_frontend *fe,
+					struct tda18271_config *cfg)
+{
+	struct tda18271_priv *priv = fe->tuner_priv;
+
+	priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
+	priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
+	priv->config = (cfg) ? cfg->config : 0;
+	priv->small_i2c = (cfg) ?
+		cfg->small_i2c : TDA18271_39_BYTE_CHUNK_INIT;
+	priv->output_opt = (cfg) ?
+		cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON;
+
+	return 0;
+}
+
+static inline int tda18271_need_cal_on_startup(struct tda18271_config *cfg)
+{
+	/* tda18271_cal_on_startup == -1 when cal module option is unset */
+	return ((tda18271_cal_on_startup == -1) ?
+		/* honor configuration setting */
+		((cfg) && (cfg->rf_cal_on_startup)) :
+		/* module option overrides configuration setting */
+		(tda18271_cal_on_startup)) ? 1 : 0;
+}
+
+static int tda18271_set_config(struct dvb_frontend *fe, void *priv_cfg)
+{
+	struct tda18271_config *cfg = (struct tda18271_config *) priv_cfg;
+
+	tda18271_setup_configuration(fe, cfg);
+
+	if (tda18271_need_cal_on_startup(cfg))
+		tda18271_init(fe);
+
+	/* override default std map with values in config struct */
+	if ((cfg) && (cfg->std_map))
+		tda18271_update_std_map(fe, cfg->std_map);
+
+	return 0;
+}
+
 static struct dvb_tuner_ops tda18271_tuner_ops = {
 	.info = {
 		.name = "NXP TDA18271HD",
@@ -1193,6 +1239,7 @@
 	.set_params        = tda18271_set_params,
 	.set_analog_params = tda18271_set_analog_params,
 	.release           = tda18271_release,
+	.set_config        = tda18271_set_config,
 	.get_frequency     = tda18271_get_frequency,
 	.get_bandwidth     = tda18271_get_bandwidth,
 };
@@ -1213,33 +1260,14 @@
 	case 0:
 		goto fail;
 	case 1:
-	{
 		/* new tuner instance */
-		int rf_cal_on_startup;
+		fe->tuner_priv = priv;
 
-		priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
-		priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
-		priv->config = (cfg) ? cfg->config : 0;
-		priv->small_i2c = (cfg) ? cfg->small_i2c : 0;
-		priv->output_opt = (cfg) ?
-			cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON;
-
-		/* tda18271_cal_on_startup == -1 when cal
-		 * module option is unset */
-		if (tda18271_cal_on_startup == -1) {
-			/* honor attach-time configuration */
-			rf_cal_on_startup =
-				((cfg) && (cfg->rf_cal_on_startup)) ? 1 : 0;
-		} else {
-			/* module option overrides attach configuration */
-			rf_cal_on_startup = tda18271_cal_on_startup;
-		}
+		tda18271_setup_configuration(fe, cfg);
 
 		priv->cal_initialized = false;
 		mutex_init(&priv->lock);
 
-		fe->tuner_priv = priv;
-
 		if (tda_fail(tda18271_get_id(fe)))
 			goto fail;
 
@@ -1249,12 +1277,12 @@
 		mutex_lock(&priv->lock);
 		tda18271_init_regs(fe);
 
-		if ((rf_cal_on_startup) && (priv->id == TDA18271HDC2))
+		if ((tda18271_need_cal_on_startup(cfg)) &&
+		    (priv->id == TDA18271HDC2))
 			tda18271c2_rf_cal_init(fe);
 
 		mutex_unlock(&priv->lock);
 		break;
-	}
 	default:
 		/* existing tuner instance */
 		fe->tuner_priv = priv;
@@ -1271,7 +1299,11 @@
 				priv->small_i2c = cfg->small_i2c;
 			if (cfg->output_opt)
 				priv->output_opt = cfg->output_opt;
+			if (cfg->std_map)
+				tda18271_update_std_map(fe, cfg->std_map);
 		}
+		if (tda18271_need_cal_on_startup(cfg))
+			tda18271_init(fe);
 		break;
 	}
 
@@ -1298,7 +1330,7 @@
 MODULE_DESCRIPTION("NXP TDA18271HD analog / digital tuner driver");
 MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
 MODULE_LICENSE("GPL");
-MODULE_VERSION("0.3");
+MODULE_VERSION("0.4");
 
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/drivers/media/common/tuners/tda18271-maps.c b/drivers/media/common/tuners/tda18271-maps.c
index e21fdef..e7f84c7 100644
--- a/drivers/media/common/tuners/tda18271-maps.c
+++ b/drivers/media/common/tuners/tda18271-maps.c
@@ -978,6 +978,7 @@
 int tda18271_lookup_cid_target(struct dvb_frontend *fe,
 			       u32 *freq, u8 *cid_target, u16 *count_limit)
 {
+	struct tda18271_priv *priv = fe->tuner_priv;
 	int i = 0;
 
 	while ((tda18271_cid_target[i].rfmax * 1000) < *freq) {
diff --git a/drivers/media/common/tuners/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h
index 2bee229..9589ab0 100644
--- a/drivers/media/common/tuners/tda18271-priv.h
+++ b/drivers/media/common/tuners/tda18271-priv.h
@@ -80,10 +80,10 @@
 	u32 rf1;
 	u32 rf2;
 	u32 rf3;
-	int rf_a1;
-	int rf_b1;
-	int rf_a2;
-	int rf_b2;
+	s32 rf_a1;
+	s32 rf_b1;
+	s32 rf_a2;
+	s32 rf_b2;
 };
 
 enum tda18271_pll {
@@ -109,11 +109,12 @@
 	enum tda18271_i2c_gate gate;
 	enum tda18271_ver id;
 	enum tda18271_output_options output_opt;
+	enum tda18271_small_i2c small_i2c;
 
 	unsigned int config; /* interface to saa713x / tda829x */
-	unsigned int tm_rfcal;
 	unsigned int cal_initialized:1;
-	unsigned int small_i2c:1;
+
+	u8 tm_rfcal;
 
 	struct tda18271_map_layout *maps;
 	struct tda18271_std_map std;
@@ -135,27 +136,37 @@
 #define DBG_ADV  8
 #define DBG_CAL  16
 
-#define tda_printk(kern, fmt, arg...) \
-	printk(kern "%s: " fmt, __func__, ##arg)
+#define tda_printk(st, kern, fmt, arg...) do {\
+	if (st) { \
+		struct tda18271_priv *state = st; \
+		printk(kern "%s: [%d-%04x|%s] " fmt, __func__, \
+			i2c_adapter_id(state->i2c_props.adap), \
+			state->i2c_props.addr, \
+			(state->role == TDA18271_MASTER) \
+			? "M" : "S", ##arg); \
+	} else \
+		printk(kern "%s: " fmt, __func__, ##arg); \
+} while (0)
 
-#define tda_dprintk(lvl, fmt, arg...) do {\
+#define tda_dprintk(st, lvl, fmt, arg...) do {\
 	if (tda18271_debug & lvl) \
-		tda_printk(KERN_DEBUG, fmt, ##arg); } while (0)
+		tda_printk(st, KERN_DEBUG, fmt, ##arg); } while (0)
 
 #define tda_info(fmt, arg...)     printk(KERN_INFO     fmt, ##arg)
-#define tda_warn(fmt, arg...) tda_printk(KERN_WARNING, fmt, ##arg)
-#define tda_err(fmt, arg...)  tda_printk(KERN_ERR,     fmt, ##arg)
-#define tda_dbg(fmt, arg...)  tda_dprintk(DBG_INFO,    fmt, ##arg)
-#define tda_map(fmt, arg...)  tda_dprintk(DBG_MAP,     fmt, ##arg)
-#define tda_reg(fmt, arg...)  tda_dprintk(DBG_REG,     fmt, ##arg)
-#define tda_cal(fmt, arg...)  tda_dprintk(DBG_CAL,     fmt, ##arg)
+#define tda_warn(fmt, arg...) tda_printk(priv, KERN_WARNING, fmt, ##arg)
+#define tda_err(fmt, arg...)  tda_printk(priv, KERN_ERR,     fmt, ##arg)
+#define tda_dbg(fmt, arg...)  tda_dprintk(priv, DBG_INFO,    fmt, ##arg)
+#define tda_map(fmt, arg...)  tda_dprintk(priv, DBG_MAP,     fmt, ##arg)
+#define tda_reg(fmt, arg...)  tda_dprintk(priv, DBG_REG,     fmt, ##arg)
+#define tda_cal(fmt, arg...)  tda_dprintk(priv, DBG_CAL,     fmt, ##arg)
 
 #define tda_fail(ret)							     \
 ({									     \
 	int __ret;							     \
 	__ret = (ret < 0);						     \
 	if (__ret)							     \
-		tda_printk(KERN_ERR, "error %d on line %d\n", ret, __LINE__);\
+		tda_printk(priv, KERN_ERR,				     \
+			   "error %d on line %d\n", ret, __LINE__);	     \
 	__ret;								     \
 })
 
diff --git a/drivers/media/common/tuners/tda18271.h b/drivers/media/common/tuners/tda18271.h
index 323f291..d7fcc36 100644
--- a/drivers/media/common/tuners/tda18271.h
+++ b/drivers/media/common/tuners/tda18271.h
@@ -78,6 +78,12 @@
 	TDA18271_OUTPUT_XT_OFF = 2,
 };
 
+enum tda18271_small_i2c {
+	TDA18271_39_BYTE_CHUNK_INIT = 0,
+	TDA18271_16_BYTE_CHUNK_INIT = 1,
+	TDA18271_08_BYTE_CHUNK_INIT = 2,
+};
+
 struct tda18271_config {
 	/* override default if freq / std settings (optional) */
 	struct tda18271_std_map *std_map;
@@ -91,12 +97,12 @@
 	/* output options that can be disabled */
 	enum tda18271_output_options output_opt;
 
+	/* some i2c providers cant write all 39 registers at once */
+	enum tda18271_small_i2c small_i2c;
+
 	/* force rf tracking filter calibration on startup */
 	unsigned int rf_cal_on_startup:1;
 
-	/* some i2c providers cant write all 39 registers at once */
-	unsigned int small_i2c:1;
-
 	/* interface to saa713x / tda829x */
 	unsigned int config;
 };
diff --git a/drivers/media/common/tuners/tda8290.c b/drivers/media/common/tuners/tda8290.c
index 064d14c..c190b0d 100644
--- a/drivers/media/common/tuners/tda8290.c
+++ b/drivers/media/common/tuners/tda8290.c
@@ -33,6 +33,7 @@
 MODULE_PARM_DESC(debug, "enable verbose debug messages");
 
 static int deemphasis_50;
+module_param(deemphasis_50, int, 0644);
 MODULE_PARM_DESC(deemphasis_50, "0 - 75us deemphasis; 1 - 50us deemphasis");
 
 /* ---------------------------------------------------------------------- */
diff --git a/drivers/media/common/tuners/tda9887.c b/drivers/media/common/tuners/tda9887.c
index 544cdbe..a71c100 100644
--- a/drivers/media/common/tuners/tda9887.c
+++ b/drivers/media/common/tuners/tda9887.c
@@ -463,7 +463,7 @@
 			buf[1] &= ~cQSS;
 	}
 
-	if (adjust >= 0x00 && adjust < 0x20) {
+	if (adjust < 0x20) {
 		buf[2] &= ~cTopMask;
 		buf[2] |= adjust;
 	}
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index f4ffcdc..432003d 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -61,6 +61,7 @@
 	u32 bandwidth;
 	u8  video_standard;
 	u8  rf_mode;
+	u8  radio_input;
 };
 
 /* Misc Defines */
@@ -632,8 +633,12 @@
 	struct xc5000_priv *priv = fe->tuner_priv;
 	int ret;
 
-	if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS)
-		xc_load_fw_and_init_tuner(fe);
+	if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
+		if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
+			dprintk(1, "Unable to load firmware and init tuner\n");
+			return -EINVAL;
+		}
+	}
 
 	dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
 
@@ -739,15 +744,12 @@
 	return ret;
 }
 
-static int xc5000_set_analog_params(struct dvb_frontend *fe,
+static int xc5000_set_tv_freq(struct dvb_frontend *fe,
 	struct analog_parameters *params)
 {
 	struct xc5000_priv *priv = fe->tuner_priv;
 	int ret;
 
-	if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS)
-		xc_load_fw_and_init_tuner(fe);
-
 	dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
 		__func__, params->frequency);
 
@@ -827,6 +829,86 @@
 	return 0;
 }
 
+static int xc5000_set_radio_freq(struct dvb_frontend *fe,
+	struct analog_parameters *params)
+{
+	struct xc5000_priv *priv = fe->tuner_priv;
+	int ret = -EINVAL;
+	u8 radio_input;
+
+	dprintk(1, "%s() frequency=%d (in units of khz)\n",
+		__func__, params->frequency);
+
+	if (priv->radio_input == XC5000_RADIO_NOT_CONFIGURED) {
+		dprintk(1, "%s() radio input not configured\n", __func__);
+		return -EINVAL;
+	}
+
+	if (priv->radio_input == XC5000_RADIO_FM1)
+		radio_input = FM_Radio_INPUT1;
+	else if  (priv->radio_input == XC5000_RADIO_FM2)
+		radio_input = FM_Radio_INPUT2;
+	else {
+		dprintk(1, "%s() unknown radio input %d\n", __func__,
+			priv->radio_input);
+		return -EINVAL;
+	}
+
+	priv->freq_hz = params->frequency * 125 / 2;
+
+	priv->rf_mode = XC_RF_MODE_AIR;
+
+	ret = xc_SetTVStandard(priv, XC5000_Standard[radio_input].VideoMode,
+			       XC5000_Standard[radio_input].AudioMode);
+
+	if (ret != XC_RESULT_SUCCESS) {
+		printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
+		return -EREMOTEIO;
+	}
+
+	ret = xc_SetSignalSource(priv, priv->rf_mode);
+	if (ret != XC_RESULT_SUCCESS) {
+		printk(KERN_ERR
+			"xc5000: xc_SetSignalSource(%d) failed\n",
+			priv->rf_mode);
+		return -EREMOTEIO;
+	}
+
+	xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
+
+	return 0;
+}
+
+static int xc5000_set_analog_params(struct dvb_frontend *fe,
+			     struct analog_parameters *params)
+{
+	struct xc5000_priv *priv = fe->tuner_priv;
+	int ret = -EINVAL;
+
+	if (priv->i2c_props.adap == NULL)
+		return -EINVAL;
+
+	if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
+		if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
+			dprintk(1, "Unable to load firmware and init tuner\n");
+			return -EINVAL;
+		}
+	}
+
+	switch (params->mode) {
+	case V4L2_TUNER_RADIO:
+		ret = xc5000_set_radio_freq(fe, params);
+		break;
+	case V4L2_TUNER_ANALOG_TV:
+	case V4L2_TUNER_DIGITAL_TV:
+		ret = xc5000_set_tv_freq(fe, params);
+		break;
+	}
+
+	return ret;
+}
+
+
 static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq)
 {
 	struct xc5000_priv *priv = fe->tuner_priv;
@@ -1000,6 +1082,9 @@
 		priv->if_khz = cfg->if_khz;
 	}
 
+	if (priv->radio_input == 0)
+		priv->radio_input = cfg->radio_input;
+
 	/* Check if firmware has been loaded. It is possible that another
 	   instance of the driver has loaded the firmware.
 	 */
diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h
index f4c1466..e6d7236 100644
--- a/drivers/media/common/tuners/xc5000.h
+++ b/drivers/media/common/tuners/xc5000.h
@@ -30,11 +30,17 @@
 struct xc5000_config {
 	u8   i2c_address;
 	u32  if_khz;
+	u8   radio_input;
 };
 
 /* xc5000 callback command */
 #define XC5000_TUNER_RESET		0
 
+/* Possible Radio inputs */
+#define XC5000_RADIO_NOT_CONFIGURED		0
+#define XC5000_RADIO_FM1			1
+#define XC5000_RADIO_FM2			2
+
 /* For each bridge framework, when it attaches either analog or digital,
  * it has to store a reference back to its _core equivalent structure,
  * so that it can service the hardware by steering gpio's etc.
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index b1857c1..78fc469 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -215,7 +215,7 @@
 		freq = 2150000; /* satellite IF is 950..2150MHz */
 
 	/* decide which VCO to use for the input frequency */
-	for(i = 1; (i < ARRAY_SIZE(osci)) && (osci[i] < freq); i++);
+	for(i = 1; (i < ARRAY_SIZE(osci) - 1) && (osci[i] < freq); i++);
 	printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq);
 	band=bandsel[i];
 	/* the gain values must be set by SetSymbolrate */
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c
index 2d099e2..53e3f2a 100644
--- a/drivers/media/dvb/dm1105/dm1105.c
+++ b/drivers/media/dvb/dm1105/dm1105.c
@@ -510,7 +510,7 @@
 
 	data = (ircom >> 8) & 0x7f;
 
-	ir_input_keydown(ir->input_dev, &ir->ir, data, data);
+	ir_input_keydown(ir->input_dev, &ir->ir, data);
 	ir_input_nokey(ir->input_dev, &ir->ir);
 }
 
@@ -589,7 +589,12 @@
 	snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys),
 		"pci-%s/ir0", pci_name(dm1105->pdev));
 
-	ir_input_init(input_dev, &dm1105->ir.ir, ir_type, ir_codes);
+	err = ir_input_init(input_dev, &dm1105->ir.ir, ir_type, ir_codes);
+	if (err < 0) {
+		input_free_device(input_dev);
+		return err;
+	}
+
 	input_dev->name = "DVB on-card IR receiver";
 	input_dev->phys = dm1105->ir.input_phys;
 	input_dev->id.bustype = BUS_PCI;
@@ -608,6 +613,7 @@
 
 	err = input_register_device(input_dev);
 	if (err) {
+		ir_input_free(input_dev);
 		input_free_device(input_dev);
 		return err;
 	}
@@ -617,8 +623,8 @@
 
 void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105)
 {
+	ir_input_free(dm1105->ir.input_dev);
 	input_unregister_device(dm1105->ir.input_dev);
-
 }
 
 static int __devinit dm1105dvb_hw_init(struct dm1105dvb *dm1105dvb)
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index 91c537b..b78cfb7 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -30,6 +30,7 @@
 #include <linux/string.h>
 #include <linux/crc32.h>
 #include <asm/uaccess.h>
+#include <asm/div64.h>
 
 #include "dvb_demux.h"
 
@@ -44,6 +45,11 @@
 MODULE_PARM_DESC(dvb_demux_tscheck,
 		"enable transport stream continuity and TEI check");
 
+static int dvb_demux_speedcheck;
+module_param(dvb_demux_speedcheck, int, 0644);
+MODULE_PARM_DESC(dvb_demux_speedcheck,
+		"enable transport stream speed check");
+
 #define dprintk_tscheck(x...) do {                              \
 		if (dvb_demux_tscheck && printk_ratelimit())    \
 			printk(x);                              \
@@ -387,6 +393,39 @@
 	u16 pid = ts_pid(buf);
 	int dvr_done = 0;
 
+	if (dvb_demux_speedcheck) {
+		struct timespec cur_time, delta_time;
+		u64 speed_bytes, speed_timedelta;
+
+		demux->speed_pkts_cnt++;
+
+		/* show speed every SPEED_PKTS_INTERVAL packets */
+		if (!(demux->speed_pkts_cnt % SPEED_PKTS_INTERVAL)) {
+			cur_time = current_kernel_time();
+
+			if (demux->speed_last_time.tv_sec != 0 &&
+					demux->speed_last_time.tv_nsec != 0) {
+				delta_time = timespec_sub(cur_time,
+						demux->speed_last_time);
+				speed_bytes = (u64)demux->speed_pkts_cnt
+					* 188 * 8;
+				/* convert to 1024 basis */
+				speed_bytes = 1000 * div64_u64(speed_bytes,
+						1024);
+				speed_timedelta =
+					(u64)timespec_to_ns(&delta_time);
+				speed_timedelta = div64_u64(speed_timedelta,
+						1000000); /* nsec -> usec */
+				printk(KERN_INFO "TS speed %llu Kbits/sec \n",
+						div64_u64(speed_bytes,
+							speed_timedelta));
+			};
+
+			demux->speed_last_time = cur_time;
+			demux->speed_pkts_cnt = 0;
+		};
+	};
+
 	if (dvb_demux_tscheck) {
 		if (!demux->cnt_storage)
 			demux->cnt_storage = vmalloc(MAX_PID + 1);
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h
index 2fe05d0..a7d876f 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.h
+++ b/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -44,6 +44,8 @@
 
 #define MAX_PID 0x1fff
 
+#define SPEED_PKTS_INTERVAL 50000
+
 struct dvb_demux_filter {
 	struct dmx_section_filter filter;
 	u8 maskandmode[DMX_MAX_FILTER_SIZE];
@@ -131,6 +133,9 @@
 	spinlock_t lock;
 
 	uint8_t *cnt_storage; /* for TS continuity check */
+
+	struct timespec speed_last_time; /* for TS speed check */
+	uint32_t speed_pkts_cnt; /* for TS speed check */
 };
 
 int dvb_dmx_init(struct dvb_demux *dvbdemux);
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 9808241..0746122 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -895,104 +895,27 @@
 }
 
 static struct dtv_cmds_h dtv_cmds[] = {
-	[DTV_TUNE] = {
-		.name	= "DTV_TUNE",
-		.cmd	= DTV_TUNE,
-		.set	= 1,
-	},
-	[DTV_CLEAR] = {
-		.name	= "DTV_CLEAR",
-		.cmd	= DTV_CLEAR,
-		.set	= 1,
-	},
+	_DTV_CMD(DTV_TUNE, 1, 0),
+	_DTV_CMD(DTV_CLEAR, 1, 0),
 
 	/* Set */
-	[DTV_FREQUENCY] = {
-		.name	= "DTV_FREQUENCY",
-		.cmd	= DTV_FREQUENCY,
-		.set	= 1,
-	},
-	[DTV_BANDWIDTH_HZ] = {
-		.name	= "DTV_BANDWIDTH_HZ",
-		.cmd	= DTV_BANDWIDTH_HZ,
-		.set	= 1,
-	},
-	[DTV_MODULATION] = {
-		.name	= "DTV_MODULATION",
-		.cmd	= DTV_MODULATION,
-		.set	= 1,
-	},
-	[DTV_INVERSION] = {
-		.name	= "DTV_INVERSION",
-		.cmd	= DTV_INVERSION,
-		.set	= 1,
-	},
-	[DTV_DISEQC_MASTER] = {
-		.name	= "DTV_DISEQC_MASTER",
-		.cmd	= DTV_DISEQC_MASTER,
-		.set	= 1,
-		.buffer	= 1,
-	},
-	[DTV_SYMBOL_RATE] = {
-		.name	= "DTV_SYMBOL_RATE",
-		.cmd	= DTV_SYMBOL_RATE,
-		.set	= 1,
-	},
-	[DTV_INNER_FEC] = {
-		.name	= "DTV_INNER_FEC",
-		.cmd	= DTV_INNER_FEC,
-		.set	= 1,
-	},
-	[DTV_VOLTAGE] = {
-		.name	= "DTV_VOLTAGE",
-		.cmd	= DTV_VOLTAGE,
-		.set	= 1,
-	},
-	[DTV_TONE] = {
-		.name	= "DTV_TONE",
-		.cmd	= DTV_TONE,
-		.set	= 1,
-	},
-	[DTV_PILOT] = {
-		.name	= "DTV_PILOT",
-		.cmd	= DTV_PILOT,
-		.set	= 1,
-	},
-	[DTV_ROLLOFF] = {
-		.name	= "DTV_ROLLOFF",
-		.cmd	= DTV_ROLLOFF,
-		.set	= 1,
-	},
-	[DTV_DELIVERY_SYSTEM] = {
-		.name	= "DTV_DELIVERY_SYSTEM",
-		.cmd	= DTV_DELIVERY_SYSTEM,
-		.set	= 1,
-	},
-	[DTV_HIERARCHY] = {
-		.name	= "DTV_HIERARCHY",
-		.cmd	= DTV_HIERARCHY,
-		.set	= 1,
-	},
-	[DTV_CODE_RATE_HP] = {
-		.name	= "DTV_CODE_RATE_HP",
-		.cmd	= DTV_CODE_RATE_HP,
-		.set	= 1,
-	},
-	[DTV_CODE_RATE_LP] = {
-		.name	= "DTV_CODE_RATE_LP",
-		.cmd	= DTV_CODE_RATE_LP,
-		.set	= 1,
-	},
-	[DTV_GUARD_INTERVAL] = {
-		.name	= "DTV_GUARD_INTERVAL",
-		.cmd	= DTV_GUARD_INTERVAL,
-		.set	= 1,
-	},
-	[DTV_TRANSMISSION_MODE] = {
-		.name	= "DTV_TRANSMISSION_MODE",
-		.cmd	= DTV_TRANSMISSION_MODE,
-		.set	= 1,
-	},
+	_DTV_CMD(DTV_FREQUENCY, 1, 0),
+	_DTV_CMD(DTV_BANDWIDTH_HZ, 1, 0),
+	_DTV_CMD(DTV_MODULATION, 1, 0),
+	_DTV_CMD(DTV_INVERSION, 1, 0),
+	_DTV_CMD(DTV_DISEQC_MASTER, 1, 1),
+	_DTV_CMD(DTV_SYMBOL_RATE, 1, 0),
+	_DTV_CMD(DTV_INNER_FEC, 1, 0),
+	_DTV_CMD(DTV_VOLTAGE, 1, 0),
+	_DTV_CMD(DTV_TONE, 1, 0),
+	_DTV_CMD(DTV_PILOT, 1, 0),
+	_DTV_CMD(DTV_ROLLOFF, 1, 0),
+	_DTV_CMD(DTV_DELIVERY_SYSTEM, 1, 0),
+	_DTV_CMD(DTV_HIERARCHY, 1, 0),
+	_DTV_CMD(DTV_CODE_RATE_HP, 1, 0),
+	_DTV_CMD(DTV_CODE_RATE_LP, 1, 0),
+	_DTV_CMD(DTV_GUARD_INTERVAL, 1, 0),
+	_DTV_CMD(DTV_TRANSMISSION_MODE, 1, 0),
 
 	_DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 1, 0),
 	_DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 1, 0),
@@ -1035,43 +958,13 @@
 	_DTV_CMD(DTV_ISDBS_TS_ID, 1, 0),
 
 	/* Get */
-	[DTV_DISEQC_SLAVE_REPLY] = {
-		.name	= "DTV_DISEQC_SLAVE_REPLY",
-		.cmd	= DTV_DISEQC_SLAVE_REPLY,
-		.set	= 0,
-		.buffer	= 1,
-	},
-
-	[DTV_API_VERSION] = {
-		.name	= "DTV_API_VERSION",
-		.cmd	= DTV_API_VERSION,
-		.set	= 0,
-	},
-	[DTV_CODE_RATE_HP] = {
-		.name	= "DTV_CODE_RATE_HP",
-		.cmd	= DTV_CODE_RATE_HP,
-		.set	= 0,
-	},
-	[DTV_CODE_RATE_LP] = {
-		.name	= "DTV_CODE_RATE_LP",
-		.cmd	= DTV_CODE_RATE_LP,
-		.set	= 0,
-	},
-	[DTV_GUARD_INTERVAL] = {
-		.name	= "DTV_GUARD_INTERVAL",
-		.cmd	= DTV_GUARD_INTERVAL,
-		.set	= 0,
-	},
-	[DTV_TRANSMISSION_MODE] = {
-		.name	= "DTV_TRANSMISSION_MODE",
-		.cmd	= DTV_TRANSMISSION_MODE,
-		.set	= 0,
-	},
-	[DTV_HIERARCHY] = {
-		.name	= "DTV_HIERARCHY",
-		.cmd	= DTV_HIERARCHY,
-		.set	= 0,
-	},
+	_DTV_CMD(DTV_DISEQC_SLAVE_REPLY, 0, 1),
+	_DTV_CMD(DTV_API_VERSION, 0, 0),
+	_DTV_CMD(DTV_CODE_RATE_HP, 0, 0),
+	_DTV_CMD(DTV_CODE_RATE_LP, 0, 0),
+	_DTV_CMD(DTV_GUARD_INTERVAL, 0, 0),
+	_DTV_CMD(DTV_TRANSMISSION_MODE, 0, 0),
+	_DTV_CMD(DTV_HIERARCHY, 0, 0),
 };
 
 static void dtv_property_dump(struct dtv_property *tvp)
@@ -1712,7 +1605,18 @@
 	struct dvb_device *dvbdev = file->private_data;
 	struct dvb_frontend *fe = dvbdev->priv;
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
-	int err = -EOPNOTSUPP;
+	int cb_err, err = -EOPNOTSUPP;
+
+	if (fe->dvb->fe_ioctl_override) {
+		cb_err = fe->dvb->fe_ioctl_override(fe, cmd, parg,
+						    DVB_FE_IOCTL_PRE);
+		if (cb_err < 0)
+			return cb_err;
+		if (cb_err > 0)
+			return 0;
+		/* fe_ioctl_override returning 0 allows
+		 * dvb-core to continue handling the ioctl */
+	}
 
 	switch (cmd) {
 	case FE_GET_INFO: {
@@ -1978,6 +1882,13 @@
 		break;
 	};
 
+	if (fe->dvb->fe_ioctl_override) {
+		cb_err = fe->dvb->fe_ioctl_override(fe, cmd, parg,
+						    DVB_FE_IOCTL_POST);
+		if (cb_err < 0)
+			return cb_err;
+	}
+
 	return err;
 }
 
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index 810f07d..52e4ce4 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -160,7 +160,7 @@
  * search callback possible return status
  *
  * DVBFE_ALGO_SEARCH_SUCCESS
- * The frontend search algorithm completed and returned succesfully
+ * The frontend search algorithm completed and returned successfully
  *
  * DVBFE_ALGO_SEARCH_ASLEEP
  * The frontend search algorithm is sleeping
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index 0241a7c..8b8558f 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -1396,7 +1396,7 @@
 		return ret;
 	}
 
-	/* binary compatiblity cruft */
+	/* binary compatibility cruft */
 	case __NET_ADD_IF_OLD:
 	{
 		struct __dvb_net_if_old *dvbnetif = parg;
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
index 01fc704..f7b499d 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -54,6 +54,8 @@
 	module_param_array(adapter_nr, short, NULL, 0444); \
 	MODULE_PARM_DESC(adapter_nr, "DVB adapter numbers")
 
+struct dvb_frontend;
+
 struct dvb_adapter {
 	int num;
 	struct list_head list_head;
@@ -69,6 +71,32 @@
 	int mfe_shared;			/* indicates mutually exclusive frontends */
 	struct dvb_device *mfe_dvbdev;	/* frontend device in use */
 	struct mutex mfe_lock;		/* access lock for thread creation */
+
+	/* Allow the adapter/bridge driver to perform an action before and/or
+	 * after the core handles an ioctl:
+	 *
+	 * DVB_FE_IOCTL_PRE indicates that the ioctl has not yet been handled.
+	 * DVB_FE_IOCTL_POST indicates that the ioctl has been handled.
+	 *
+	 * When DVB_FE_IOCTL_PRE is passed to the callback as the stage arg:
+	 *
+	 * return 0 to allow dvb-core to handle the ioctl.
+	 * return a positive int to prevent dvb-core from handling the ioctl,
+	 * 	and exit without error.
+	 * return a negative int to prevent dvb-core from handling the ioctl,
+	 * 	and return that value as an error.
+	 *
+	 * When DVB_FE_IOCTL_POST is passed to the callback as the stage arg:
+	 *
+	 * return 0 to allow the dvb_frontend ioctl handler to exit normally.
+	 * return a negative int to cause the dvb_frontend ioctl handler to
+	 * 	return that value as an error.
+	 */
+#define DVB_FE_IOCTL_PRE 0
+#define DVB_FE_IOCTL_POST 1
+	int (*fe_ioctl_override)(struct dvb_frontend *fe,
+				 unsigned int cmd, void *parg,
+				 unsigned int stage);
 };
 
 
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 0e4b97f..2dee1bf 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -322,3 +322,11 @@
 	depends on DVB_USB
 	help
 	  Say Y here to support the Japanese DTV receiver Friio.
+
+config DVB_USB_EC168
+	tristate "E3C EC168 DVB-T USB2.0 support"
+	depends on DVB_USB && EXPERIMENTAL
+	select DVB_EC100
+	select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
+	help
+	  Say Y here to support the E3C EC168 DVB-T USB2.0 receiver.
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 85b83a4..72c92cb 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -82,6 +82,9 @@
 dvb-usb-friio-objs = friio.o friio-fe.o
 obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o
 
+dvb-usb-ec168-objs = ec168.o
+obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o
+
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
 # due to tuner-xc3028
 EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index cf042b3..8b60a60 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -730,7 +730,7 @@
 		goto error;
 	deb_info("%s: IR mode:%d\n", __func__, val);
 	for (i = 0; i < af9015_properties_count; i++) {
-		if (val == AF9015_IR_MODE_DISABLED || val == 0x04) {
+		if (val == AF9015_IR_MODE_DISABLED) {
 			af9015_properties[i].rc_key_map = NULL;
 			af9015_properties[i].rc_key_map_size  = 0;
 		} else if (dvb_usb_af9015_remote) {
@@ -868,6 +868,16 @@
 				af9015_config.ir_table_size =
 				  ARRAY_SIZE(af9015_ir_table_avermedia);
 				break;
+			case USB_VID_MSI_2:
+				af9015_properties[i].rc_key_map =
+				  af9015_rc_keys_msi_digivox_iii;
+				af9015_properties[i].rc_key_map_size =
+				  ARRAY_SIZE(af9015_rc_keys_msi_digivox_iii);
+				af9015_config.ir_table =
+				  af9015_ir_table_msi_digivox_iii;
+				af9015_config.ir_table_size =
+				  ARRAY_SIZE(af9015_ir_table_msi_digivox_iii);
+				break;
 			}
 		}
 	}
@@ -1283,6 +1293,8 @@
 	{USB_DEVICE(USB_VID_KWORLD_2,  USB_PID_KWORLD_MC810)},
 	{USB_DEVICE(USB_VID_KYE,       USB_PID_GENIUS_TVGO_DVB_T03)},
 /* 25 */{USB_DEVICE(USB_VID_KWORLD_2,  USB_PID_KWORLD_399U_2)},
+	{USB_DEVICE(USB_VID_KWORLD_2,  USB_PID_KWORLD_PC160_T)},
+	{USB_DEVICE(USB_VID_KWORLD_2,  USB_PID_SVEON_STV20)},
 	{0},
 };
 MODULE_DEVICE_TABLE(usb, af9015_usb_table);
@@ -1296,7 +1308,7 @@
 		.firmware = "dvb-usb-af9015.fw",
 		.no_reconnect = 1,
 
-		.size_of_priv = sizeof(struct af9015_state), \
+		.size_of_priv = sizeof(struct af9015_state),
 
 		.num_adapters = 2,
 		.adapter = {
@@ -1402,7 +1414,7 @@
 		.firmware = "dvb-usb-af9015.fw",
 		.no_reconnect = 1,
 
-		.size_of_priv = sizeof(struct af9015_state), \
+		.size_of_priv = sizeof(struct af9015_state),
 
 		.num_adapters = 2,
 		.adapter = {
@@ -1508,7 +1520,7 @@
 		.firmware = "dvb-usb-af9015.fw",
 		.no_reconnect = 1,
 
-		.size_of_priv = sizeof(struct af9015_state), \
+		.size_of_priv = sizeof(struct af9015_state),
 
 		.num_adapters = 2,
 		.adapter = {
@@ -1554,7 +1566,7 @@
 
 		.i2c_algo = &af9015_i2c_algo,
 
-		.num_device_descs = 4, /* max 9 */
+		.num_device_descs = 6, /* max 9 */
 		.devices = {
 			{
 				.name = "AverMedia AVerTV Volar GPS 805 (A805)",
@@ -1577,6 +1589,17 @@
 				.cold_ids = {&af9015_usb_table[24], NULL},
 				.warm_ids = {NULL},
 			},
+			{
+				.name = "KWorld PlusTV DVB-T PCI Pro Card " \
+					"(DVB-T PC160-T)",
+				.cold_ids = {&af9015_usb_table[26], NULL},
+				.warm_ids = {NULL},
+			},
+			{
+				.name = "Sveon STV20 Tuner USB DVB-T HDTV",
+				.cold_ids = {&af9015_usb_table[27], NULL},
+				.warm_ids = {NULL},
+			},
 		}
 	},
 };
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h
index c41f30e..931c851 100644
--- a/drivers/media/dvb/dvb-usb/af9015.h
+++ b/drivers/media/dvb/dvb-usb/af9015.h
@@ -95,6 +95,7 @@
 	AF9015_IR_MODE_HID,
 	AF9015_IR_MODE_RLC,
 	AF9015_IR_MODE_RC6,
+	AF9015_IR_MODE_POLLING, /* just guess */
 };
 
 struct af9015_state {
@@ -119,6 +120,7 @@
 /* 5 */	AF9015_REMOTE_AVERMEDIA_KS,
 };
 
+/* LeadTek - Y04G0051 */
 /* Leadtek WinFast DTV Dongle Gold */
 static struct dvb_usb_rc_key af9015_rc_keys_leadtek[] = {
 	{ 0x001e, KEY_1 },
@@ -131,64 +133,96 @@
 	{ 0x0025, KEY_8 },
 	{ 0x0026, KEY_9 },
 	{ 0x0027, KEY_0 },
-	{ 0x0028, KEY_ENTER },
-	{ 0x004f, KEY_VOLUMEUP },
-	{ 0x0050, KEY_VOLUMEDOWN },
-	{ 0x0051, KEY_CHANNELDOWN },
-	{ 0x0052, KEY_CHANNELUP },
+	{ 0x0028, KEY_OK },
+	{ 0x004f, KEY_RIGHT },
+	{ 0x0050, KEY_LEFT },
+	{ 0x0051, KEY_DOWN },
+	{ 0x0052, KEY_UP },
+	{ 0x011a, KEY_POWER2 },
+	{ 0x04b4, KEY_TV },
+	{ 0x04b3, KEY_RED },
+	{ 0x04b2, KEY_GREEN },
+	{ 0x04b1, KEY_YELLOW },
+	{ 0x04b0, KEY_BLUE },
+	{ 0x003d, KEY_TEXT },
+	{ 0x0113, KEY_SLEEP },
+	{ 0x0010, KEY_MUTE },
+	{ 0x0105, KEY_ESC },
+	{ 0x0009, KEY_SCREEN },
+	{ 0x010f, KEY_MENU },
+	{ 0x003f, KEY_CHANNEL },
+	{ 0x0013, KEY_REWIND },
+	{ 0x0012, KEY_PLAY },
+	{ 0x0011, KEY_FASTFORWARD },
+	{ 0x0005, KEY_PREVIOUS },
+	{ 0x0029, KEY_STOP },
+	{ 0x002b, KEY_NEXT },
+	{ 0x0041, KEY_EPG },
+	{ 0x0019, KEY_VIDEO },
+	{ 0x0016, KEY_AUDIO },
+	{ 0x0037, KEY_DOT },
+	{ 0x002a, KEY_AGAIN },
+	{ 0x002c, KEY_CAMERA },
+	{ 0x003c, KEY_NEW },
+	{ 0x0115, KEY_RECORD },
+	{ 0x010b, KEY_TIME },
+	{ 0x0043, KEY_VOLUMEUP },
+	{ 0x0042, KEY_VOLUMEDOWN },
+	{ 0x004b, KEY_CHANNELUP },
+	{ 0x004e, KEY_CHANNELDOWN },
 };
 
 static u8 af9015_ir_table_leadtek[] = {
-	0x03, 0xfc, 0x00, 0xff, 0x1a, 0x01, 0x00,
-	0x03, 0xfc, 0x56, 0xa9, 0x00, 0x00, 0x00,
-	0x03, 0xfc, 0x4b, 0xb4, 0x00, 0x00, 0x00,
-	0x03, 0xfc, 0x4c, 0xb3, 0xb2, 0x04, 0x00,
-	0x03, 0xfc, 0x4d, 0xb2, 0x00, 0x00, 0x00,
-	0x03, 0xfc, 0x4e, 0xb1, 0x00, 0x00, 0x00,
-	0x03, 0xfc, 0x1f, 0xe0, 0x3d, 0x00, 0x00,
-	0x03, 0xfc, 0x40, 0xbf, 0x13, 0x01, 0x00,
-	0x03, 0xfc, 0x14, 0xeb, 0x10, 0x00, 0x00,
-	0x03, 0xfc, 0x49, 0xb6, 0x05, 0x01, 0x00,
-	0x03, 0xfc, 0x50, 0xaf, 0x29, 0x00, 0x00,
-	0x03, 0xfc, 0x0c, 0xf3, 0x52, 0x00, 0x00,
-	0x03, 0xfc, 0x03, 0xfc, 0x09, 0x00, 0x00,
-	0x03, 0xfc, 0x08, 0xf7, 0x50, 0x00, 0x00,
-	0x03, 0xfc, 0x13, 0xec, 0x28, 0x00, 0x00,
-	0x03, 0xfc, 0x04, 0xfb, 0x4f, 0x00, 0x00,
-	0x03, 0xfc, 0x4f, 0xb0, 0x0f, 0x01, 0x00,
-	0x03, 0xfc, 0x10, 0xef, 0x51, 0x00, 0x00,
-	0x03, 0xfc, 0x51, 0xae, 0x3f, 0x00, 0x00,
-	0x03, 0xfc, 0x42, 0xbd, 0x13, 0x00, 0x00,
-	0x03, 0xfc, 0x43, 0xbc, 0x00, 0x00, 0x00,
-	0x03, 0xfc, 0x44, 0xbb, 0x11, 0x00, 0x00,
-	0x03, 0xfc, 0x52, 0xad, 0x19, 0x00, 0x00,
-	0x03, 0xfc, 0x54, 0xab, 0x05, 0x00, 0x00,
-	0x03, 0xfc, 0x46, 0xb9, 0x29, 0x00, 0x00,
-	0x03, 0xfc, 0x55, 0xaa, 0x2b, 0x00, 0x00,
-	0x03, 0xfc, 0x53, 0xac, 0x41, 0x00, 0x00,
-	0x03, 0xfc, 0x05, 0xfa, 0x1e, 0x00, 0x00,
-	0x03, 0xfc, 0x06, 0xf9, 0x1f, 0x00, 0x00,
-	0x03, 0xfc, 0x07, 0xf8, 0x20, 0x00, 0x00,
-	0x03, 0xfc, 0x1e, 0xe1, 0x19, 0x00, 0x00,
-	0x03, 0xfc, 0x09, 0xf6, 0x21, 0x00, 0x00,
-	0x03, 0xfc, 0x0a, 0xf5, 0x22, 0x00, 0x00,
-	0x03, 0xfc, 0x0b, 0xf4, 0x23, 0x00, 0x00,
-	0x03, 0xfc, 0x1b, 0xe4, 0x16, 0x00, 0x00,
-	0x03, 0xfc, 0x0d, 0xf2, 0x24, 0x00, 0x00,
-	0x03, 0xfc, 0x0e, 0xf1, 0x25, 0x00, 0x00,
-	0x03, 0xfc, 0x0f, 0xf0, 0x26, 0x00, 0x00,
-	0x03, 0xfc, 0x16, 0xe9, 0x28, 0x00, 0x00,
-	0x03, 0xfc, 0x41, 0xbe, 0x37, 0x00, 0x00,
-	0x03, 0xfc, 0x12, 0xed, 0x27, 0x00, 0x00,
-	0x03, 0xfc, 0x11, 0xee, 0x2a, 0x00, 0x00,
-	0x03, 0xfc, 0x48, 0xb7, 0x2c, 0x00, 0x00,
-	0x03, 0xfc, 0x4a, 0xb5, 0x3c, 0x00, 0x00,
-	0x03, 0xfc, 0x47, 0xb8, 0x15, 0x01, 0x00,
-	0x03, 0xfc, 0x45, 0xba, 0x0b, 0x01, 0x00,
-	0x03, 0xfc, 0x5e, 0xa1, 0x43, 0x00, 0x00,
-	0x03, 0xfc, 0x5a, 0xa5, 0x42, 0x00, 0x00,
-	0x03, 0xfc, 0x5b, 0xa4, 0x4b, 0x00, 0x00,
-	0x03, 0xfc, 0x5f, 0xa0, 0x4e, 0x00, 0x00,
+	0x03, 0xfc, 0x00, 0xff, 0x1a, 0x01, 0x00, /* KEY_POWER2 */
+	0x03, 0xfc, 0x56, 0xa9, 0xb4, 0x04, 0x00, /* KEY_TV */
+	0x03, 0xfc, 0x4b, 0xb4, 0xb3, 0x04, 0x00, /* KEY_RED */
+	0x03, 0xfc, 0x4c, 0xb3, 0xb2, 0x04, 0x00, /* KEY_GREEN */
+	0x03, 0xfc, 0x4d, 0xb2, 0xb1, 0x04, 0x00, /* KEY_YELLOW */
+	0x03, 0xfc, 0x4e, 0xb1, 0xb0, 0x04, 0x00, /* KEY_BLUE */
+	0x03, 0xfc, 0x1f, 0xe0, 0x3d, 0x00, 0x00, /* KEY_TEXT */
+	0x03, 0xfc, 0x40, 0xbf, 0x13, 0x01, 0x00, /* KEY_SLEEP */
+	0x03, 0xfc, 0x14, 0xeb, 0x10, 0x00, 0x00, /* KEY_MUTE */
+	0x03, 0xfc, 0x49, 0xb6, 0x05, 0x01, 0x00, /* KEY_ESC */
+	0x03, 0xfc, 0x50, 0xaf, 0x29, 0x00, 0x00, /* KEY_STOP (1)*/
+	0x03, 0xfc, 0x0c, 0xf3, 0x52, 0x00, 0x00, /* KEY_UP */
+	0x03, 0xfc, 0x03, 0xfc, 0x09, 0x00, 0x00, /* KEY_SCREEN */
+	0x03, 0xfc, 0x08, 0xf7, 0x50, 0x00, 0x00, /* KEY_LEFT */
+	0x03, 0xfc, 0x13, 0xec, 0x28, 0x00, 0x00, /* KEY_OK (1) */
+	0x03, 0xfc, 0x04, 0xfb, 0x4f, 0x00, 0x00, /* KEY_RIGHT */
+	0x03, 0xfc, 0x4f, 0xb0, 0x0f, 0x01, 0x00, /* KEY_MENU */
+	0x03, 0xfc, 0x10, 0xef, 0x51, 0x00, 0x00, /* KEY_DOWN */
+	0x03, 0xfc, 0x51, 0xae, 0x3f, 0x00, 0x00, /* KEY_CHANNEL */
+	0x03, 0xfc, 0x42, 0xbd, 0x13, 0x00, 0x00, /* KEY_REWIND */
+	0x03, 0xfc, 0x43, 0xbc, 0x12, 0x00, 0x00, /* KEY_PLAY */
+	0x03, 0xfc, 0x44, 0xbb, 0x11, 0x00, 0x00, /* KEY_FASTFORWARD */
+	0x03, 0xfc, 0x52, 0xad, 0x19, 0x00, 0x00, /* KEY_VIDEO (1) */
+	0x03, 0xfc, 0x54, 0xab, 0x05, 0x00, 0x00, /* KEY_PREVIOUS */
+	0x03, 0xfc, 0x46, 0xb9, 0x29, 0x00, 0x00, /* KEY_STOP (2) */
+	0x03, 0xfc, 0x55, 0xaa, 0x2b, 0x00, 0x00, /* KEY_NEXT */
+	0x03, 0xfc, 0x53, 0xac, 0x41, 0x00, 0x00, /* KEY_EPG */
+	0x03, 0xfc, 0x05, 0xfa, 0x1e, 0x00, 0x00, /* KEY_1 */
+	0x03, 0xfc, 0x06, 0xf9, 0x1f, 0x00, 0x00, /* KEY_2 */
+	0x03, 0xfc, 0x07, 0xf8, 0x20, 0x00, 0x00, /* KEY_3 */
+	0x03, 0xfc, 0x1e, 0xe1, 0x19, 0x00, 0x00, /* KEY_VIDEO (2) */
+	0x03, 0xfc, 0x09, 0xf6, 0x21, 0x00, 0x00, /* KEY_4 */
+	0x03, 0xfc, 0x0a, 0xf5, 0x22, 0x00, 0x00, /* KEY_5 */
+	0x03, 0xfc, 0x0b, 0xf4, 0x23, 0x00, 0x00, /* KEY_6 */
+	0x03, 0xfc, 0x1b, 0xe4, 0x16, 0x00, 0x00, /* KEY_AUDIO */
+	0x03, 0xfc, 0x0d, 0xf2, 0x24, 0x00, 0x00, /* KEY_7 */
+	0x03, 0xfc, 0x0e, 0xf1, 0x25, 0x00, 0x00, /* KEY_8 */
+	0x03, 0xfc, 0x0f, 0xf0, 0x26, 0x00, 0x00, /* KEY_9 */
+	0x03, 0xfc, 0x16, 0xe9, 0x28, 0x00, 0x00, /* KEY_OK (2) */
+	0x03, 0xfc, 0x41, 0xbe, 0x37, 0x00, 0x00, /* KEY_DOT */
+	0x03, 0xfc, 0x12, 0xed, 0x27, 0x00, 0x00, /* KEY_0 */
+	0x03, 0xfc, 0x11, 0xee, 0x2a, 0x00, 0x00, /* KEY_AGAIN */
+	0x03, 0xfc, 0x48, 0xb7, 0x2c, 0x00, 0x00, /* KEY_CAMERA */
+	0x03, 0xfc, 0x4a, 0xb5, 0x3c, 0x00, 0x00, /* KEY_NEW */
+	0x03, 0xfc, 0x47, 0xb8, 0x15, 0x01, 0x00, /* KEY_RECORD */
+	0x03, 0xfc, 0x45, 0xba, 0x0b, 0x01, 0x00, /* KEY_TIME */
+	0x03, 0xfc, 0x5e, 0xa1, 0x43, 0x00, 0x00, /* KEY_VOLUMEUP */
+	0x03, 0xfc, 0x5a, 0xa5, 0x42, 0x00, 0x00, /* KEY_VOLUMEDOWN */
+	0x03, 0xfc, 0x5b, 0xa4, 0x4b, 0x00, 0x00, /* KEY_CHANNELUP */
+	0x03, 0xfc, 0x5f, 0xa0, 0x4e, 0x00, 0x00, /* KEY_CHANNELDOWN */
 };
 
 /* TwinHan AzureWave AD-TU700(704J) */
@@ -746,4 +780,75 @@
 	0x00, 0xff, 0x84, 0x7b, 0x27, 0x07, 0x00,
 };
 
+/* MSI DIGIVOX mini III */
+static struct dvb_usb_rc_key af9015_rc_keys_msi_digivox_iii[] = {
+	{ 0x0713, KEY_POWER },       /* [red power button] */
+	{ 0x073b, KEY_VIDEO },       /* Source */
+	{ 0x073e, KEY_ZOOM },        /* Zoom */
+	{ 0x070b, KEY_POWER2 },      /* ShutDown */
+	{ 0x071e, KEY_1 },
+	{ 0x071f, KEY_2 },
+	{ 0x0720, KEY_3 },
+	{ 0x0721, KEY_4 },
+	{ 0x0722, KEY_5 },
+	{ 0x0723, KEY_6 },
+	{ 0x0724, KEY_7 },
+	{ 0x0725, KEY_8 },
+	{ 0x0726, KEY_9 },
+	{ 0x0727, KEY_0 },
+	{ 0x0752, KEY_CHANNELUP },   /* CH+ */
+	{ 0x0751, KEY_CHANNELDOWN }, /* CH- */
+	{ 0x0750, KEY_VOLUMEUP },    /* Vol+ */
+	{ 0x074f, KEY_VOLUMEDOWN },  /* Vol- */
+	{ 0x0705, KEY_ESC },         /* [back up arrow] */
+	{ 0x0708, KEY_OK },          /* [enter arrow] */
+	{ 0x073f, KEY_RECORD },      /* Rec */
+	{ 0x0716, KEY_STOP },        /* Stop */
+	{ 0x072a, KEY_PLAY },        /* Play */
+	{ 0x073c, KEY_MUTE },        /* Mute */
+	{ 0x0718, KEY_UP },
+	{ 0x0707, KEY_DOWN },
+	{ 0x070f, KEY_LEFT },
+	{ 0x0715, KEY_RIGHT },
+	{ 0x0736, KEY_RED },
+	{ 0x0737, KEY_GREEN },
+	{ 0x072d, KEY_YELLOW },
+	{ 0x072e, KEY_BLUE },
+};
+
+static u8 af9015_ir_table_msi_digivox_iii[] = {
+	0x61, 0xd6, 0x43, 0xbc, 0x13, 0x07, 0x00, /* KEY_POWER */
+	0x61, 0xd6, 0x01, 0xfe, 0x3b, 0x07, 0x00, /* KEY_VIDEO */
+	0x61, 0xd6, 0x0b, 0xf4, 0x3e, 0x07, 0x00, /* KEY_ZOOM */
+	0x61, 0xd6, 0x03, 0xfc, 0x0b, 0x07, 0x00, /* KEY_POWER2 */
+	0x61, 0xd6, 0x04, 0xfb, 0x1e, 0x07, 0x00, /* KEY_1 */
+	0x61, 0xd6, 0x08, 0xf7, 0x1f, 0x07, 0x00, /* KEY_2 */
+	0x61, 0xd6, 0x02, 0xfd, 0x20, 0x07, 0x00, /* KEY_3 */
+	0x61, 0xd6, 0x0f, 0xf0, 0x21, 0x07, 0x00, /* KEY_4 */
+	0x61, 0xd6, 0x05, 0xfa, 0x22, 0x07, 0x00, /* KEY_5 */
+	0x61, 0xd6, 0x06, 0xf9, 0x23, 0x07, 0x00, /* KEY_6 */
+	0x61, 0xd6, 0x0c, 0xf3, 0x24, 0x07, 0x00, /* KEY_7 */
+	0x61, 0xd6, 0x0d, 0xf2, 0x25, 0x07, 0x00, /* KEY_8 */
+	0x61, 0xd6, 0x0a, 0xf5, 0x26, 0x07, 0x00, /* KEY_9 */
+	0x61, 0xd6, 0x11, 0xee, 0x27, 0x07, 0x00, /* KEY_0 */
+	0x61, 0xd6, 0x09, 0xf6, 0x52, 0x07, 0x00, /* KEY_CHANNELUP */
+	0x61, 0xd6, 0x07, 0xf8, 0x51, 0x07, 0x00, /* KEY_CHANNELDOWN */
+	0x61, 0xd6, 0x0e, 0xf1, 0x50, 0x07, 0x00, /* KEY_VOLUMEUP */
+	0x61, 0xd6, 0x13, 0xec, 0x4f, 0x07, 0x00, /* KEY_VOLUMEDOWN */
+	0x61, 0xd6, 0x10, 0xef, 0x05, 0x07, 0x00, /* KEY_ESC */
+	0x61, 0xd6, 0x12, 0xed, 0x08, 0x07, 0x00, /* KEY_OK */
+	0x61, 0xd6, 0x14, 0xeb, 0x3f, 0x07, 0x00, /* KEY_RECORD */
+	0x61, 0xd6, 0x15, 0xea, 0x16, 0x07, 0x00, /* KEY_STOP */
+	0x61, 0xd6, 0x16, 0xe9, 0x2a, 0x07, 0x00, /* KEY_PLAY */
+	0x61, 0xd6, 0x17, 0xe8, 0x3c, 0x07, 0x00, /* KEY_MUTE */
+	0x61, 0xd6, 0x18, 0xe7, 0x18, 0x07, 0x00, /* KEY_UP */
+	0x61, 0xd6, 0x19, 0xe6, 0x07, 0x07, 0x00, /* KEY_DOWN */
+	0x61, 0xd6, 0x1a, 0xe5, 0x0f, 0x07, 0x00, /* KEY_LEFT */
+	0x61, 0xd6, 0x1b, 0xe4, 0x15, 0x07, 0x00, /* KEY_RIGHT */
+	0x61, 0xd6, 0x1c, 0xe3, 0x36, 0x07, 0x00, /* KEY_RED */
+	0x61, 0xd6, 0x1d, 0xe2, 0x37, 0x07, 0x00, /* KEY_GREEN */
+	0x61, 0xd6, 0x1e, 0xe1, 0x2d, 0x07, 0x00, /* KEY_YELLOW */
+	0x61, 0xd6, 0x1f, 0xe0, 0x2e, 0x07, 0x00, /* KEY_BLUE */
+};
+
 #endif
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
index 2ae7f64..bb69f37 100644
--- a/drivers/media/dvb/dvb-usb/anysee.c
+++ b/drivers/media/dvb/dvb-usb/anysee.c
@@ -344,7 +344,7 @@
 	if (ret)
 		return ret;
 
-	err("Unkown Anysee version: %02x %02x %02x. "\
+	err("Unknown Anysee version: %02x %02x %02x. "\
 	    "Please report the <linux-dvb@linuxtv.org>.",
 	    hw_info[0], hw_info[1], hw_info[2]);
 
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index 2a53dd0..05fb28e9 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -36,9 +36,11 @@
 #include "tuner-xc2028.h"
 #include "tuner-simple.h"
 #include "mxl5005s.h"
+#include "max2165.h"
 #include "dib7000p.h"
 #include "dib0070.h"
 #include "lgs8gxx.h"
+#include "atbm8830.h"
 
 /* debug */
 static int dvb_usb_cxusb_debug;
@@ -714,6 +716,11 @@
 	.AgcMasterByte   = 0x00,
 };
 
+static struct max2165_config mygica_d689_max2165_cfg = {
+	.i2c_address = 0x60,
+	.osc_clk = 20
+};
+
 /* Callbacks for DVB USB */
 static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
 {
@@ -813,6 +820,14 @@
 	return (fe == NULL) ? -EIO : 0;
 }
 
+static int cxusb_mygica_d689_tuner_attach(struct dvb_usb_adapter *adap)
+{
+	struct dvb_frontend *fe;
+	fe = dvb_attach(max2165_attach, adap->fe,
+			&adap->dev->i2c_adap, &mygica_d689_max2165_cfg);
+	return (fe == NULL) ? -EIO : 0;
+}
+
 static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
 {
 	u8 b;
@@ -1160,6 +1175,55 @@
 	return 0;
 }
 
+static struct atbm8830_config mygica_d689_atbm8830_cfg = {
+	.prod = ATBM8830_PROD_8830,
+	.demod_address = 0x40,
+	.serial_ts = 0,
+	.ts_sampling_edge = 1,
+	.ts_clk_gated = 0,
+	.osc_clk_freq = 30400, /* in kHz */
+	.if_freq = 0, /* zero IF */
+	.zif_swap_iq = 1,
+};
+
+static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap)
+{
+	struct dvb_usb_device *d = adap->dev;
+
+	/* Select required USB configuration */
+	if (usb_set_interface(d->udev, 0, 0) < 0)
+		err("set interface failed");
+
+	/* Unblock all USB pipes */
+	usb_clear_halt(d->udev,
+		usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
+	usb_clear_halt(d->udev,
+		usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
+	usb_clear_halt(d->udev,
+		usb_rcvbulkpipe(d->udev, d->props.adapter[0].stream.endpoint));
+
+
+	/* Reset the tuner */
+	if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) {
+		err("clear tuner gpio failed");
+		return -EIO;
+	}
+	msleep(100);
+	if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) {
+		err("set tuner gpio failed");
+		return -EIO;
+	}
+	msleep(100);
+
+	/* Attach frontend */
+	adap->fe = dvb_attach(atbm8830_attach, &mygica_d689_atbm8830_cfg,
+		&d->i2c_adap);
+	if (adap->fe == NULL)
+		return -EIO;
+
+	return 0;
+}
+
 /*
  * DViCO has shipped two devices with the same USB ID, but only one of them
  * needs a firmware download.  Check the device class details to see if they
@@ -1240,6 +1304,7 @@
 static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
 static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
 static struct dvb_usb_device_properties cxusb_d680_dmb_properties;
+static struct dvb_usb_device_properties cxusb_mygica_d689_properties;
 
 static int cxusb_probe(struct usb_interface *intf,
 		       const struct usb_device_id *id)
@@ -1268,6 +1333,8 @@
 				     THIS_MODULE, NULL, adapter_nr) ||
 	    0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties,
 				     THIS_MODULE, NULL, adapter_nr) ||
+	    0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties,
+				     THIS_MODULE, NULL, adapter_nr) ||
 	    0)
 		return 0;
 
@@ -1294,6 +1361,7 @@
 	{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) },
 	{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) },
 	{ USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) },
+	{ USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) },
 	{}		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE (usb, cxusb_table);
@@ -1837,6 +1905,55 @@
 	}
 };
 
+static struct dvb_usb_device_properties cxusb_mygica_d689_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+	.usb_ctrl         = CYPRESS_FX2,
+
+	.size_of_priv     = sizeof(struct cxusb_state),
+
+	.num_adapters = 1,
+	.adapter = {
+		{
+			.streaming_ctrl   = cxusb_d680_dmb_streaming_ctrl,
+			.frontend_attach  = cxusb_mygica_d689_frontend_attach,
+			.tuner_attach     = cxusb_mygica_d689_tuner_attach,
+
+			/* parameter for the MPEG2-data transfer */
+			.stream = {
+				.type = USB_BULK,
+				.count = 5,
+				.endpoint = 0x02,
+				.u = {
+					.bulk = {
+						.buffersize = 8192,
+					}
+				}
+			},
+		},
+	},
+
+	.power_ctrl       = cxusb_d680_dmb_power_ctrl,
+
+	.i2c_algo         = &cxusb_i2c_algo,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
+
+	.rc_interval      = 100,
+	.rc_key_map       = d680_dmb_rc_keys,
+	.rc_key_map_size  = ARRAY_SIZE(d680_dmb_rc_keys),
+	.rc_query         = cxusb_d680_dmb_rc_query,
+
+	.num_device_descs = 1,
+	.devices = {
+		{
+			"Mygica D689 DMB-TH",
+			{ NULL },
+			{ &cxusb_table[19], NULL },
+		},
+	}
+};
+
 static struct usb_driver cxusb_driver = {
 	.name		= "dvb_usb_cxusb",
 	.probe		= cxusb_probe,
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 6bd8951..684146f 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -558,8 +558,7 @@
 struct dib0700_rc_response {
 	u8 report_id;
 	u8 data_state;
-	u8 system_msb;
-	u8 system_lsb;
+	u16 system;
 	u8 data;
 	u8 not_data;
 };
@@ -589,37 +588,50 @@
 		return 0;
 	}
 
-	if (actlen != sizeof(buf)) {
-		/* We didn't get back the 6 byte message we expected */
-		err("Unexpected RC response size [%d]", actlen);
-		return -1;
+
+	switch (dvb_usb_dib0700_ir_proto) {
+	case 0:
+		poll_reply.report_id  = 0;
+		poll_reply.data_state = 1;
+		poll_reply.system     = buf[2];
+		poll_reply.data       = buf[4];
+		poll_reply.not_data   = buf[5];
+
+		/* NEC protocol sends repeat code as 0 0 0 FF */
+		if ((poll_reply.system == 0x00) && (poll_reply.data == 0x00)
+		    && (poll_reply.not_data == 0xff)) {
+			poll_reply.data_state = 2;
+			break;
+		}
+		break;
+	default:
+		if (actlen != sizeof(buf)) {
+			/* We didn't get back the 6 byte message we expected */
+			err("Unexpected RC response size [%d]", actlen);
+			return -1;
+		}
+
+		poll_reply.report_id  = buf[0];
+		poll_reply.data_state = buf[1];
+		poll_reply.system     = (buf[2] << 8) | buf[3];
+		poll_reply.data       = buf[4];
+		poll_reply.not_data   = buf[5];
+
+		break;
 	}
 
-	poll_reply.report_id  = buf[0];
-	poll_reply.data_state = buf[1];
-	poll_reply.system_msb = buf[2];
-	poll_reply.system_lsb = buf[3];
-	poll_reply.data       = buf[4];
-	poll_reply.not_data   = buf[5];
-
-	/*
-	info("rid=%02x ds=%02x sm=%02x sl=%02x d=%02x nd=%02x\n",
-	     poll_reply.report_id, poll_reply.data_state,
-	     poll_reply.system_msb, poll_reply.system_lsb,
-	     poll_reply.data, poll_reply.not_data);
-	*/
-
 	if ((poll_reply.data + poll_reply.not_data) != 0xff) {
 		/* Key failed integrity check */
-		err("key failed integrity check: %02x %02x %02x %02x",
-		    poll_reply.system_msb, poll_reply.system_lsb,
+		err("key failed integrity check: %04x %02x %02x",
+		    poll_reply.system,
 		    poll_reply.data, poll_reply.not_data);
 		return -1;
 	}
 
+
 	/* Find the key in the map */
 	for (i = 0; i < d->props.rc_key_map_size; i++) {
-		if (rc5_custom(&keymap[i]) == poll_reply.system_lsb &&
+		if (rc5_custom(&keymap[i]) == (poll_reply.system & 0xff) &&
 		    rc5_data(&keymap[i]) == poll_reply.data) {
 			*event = keymap[i].event;
 			found = 1;
@@ -628,8 +640,8 @@
 	}
 
 	if (found == 0) {
-		err("Unknown remote controller key: %02x %02x %02x %02x",
-		    poll_reply.system_msb, poll_reply.system_lsb,
+		err("Unknown remote controller key: %04x %02x %02x",
+		    poll_reply.system,
 		    poll_reply.data, poll_reply.not_data);
 		d->last_event = 0;
 		return 0;
@@ -874,6 +886,49 @@
 	{ 0x1d37, KEY_RECORD },
 	{ 0x1d3b, KEY_GOTO },
 	{ 0x1d3d, KEY_POWER },
+
+	/* Key codes for the Pixelview SBTVD remote (proto NEC) */
+	{ 0x8613, KEY_MUTE },
+	{ 0x8612, KEY_POWER },
+	{ 0x8601, KEY_1 },
+	{ 0x8602, KEY_2 },
+	{ 0x8603, KEY_3 },
+	{ 0x8604, KEY_4 },
+	{ 0x8605, KEY_5 },
+	{ 0x8606, KEY_6 },
+	{ 0x8607, KEY_7 },
+	{ 0x8608, KEY_8 },
+	{ 0x8609, KEY_9 },
+	{ 0x8600, KEY_0 },
+	{ 0x860d, KEY_CHANNELUP },
+	{ 0x8619, KEY_CHANNELDOWN },
+	{ 0x8610, KEY_VOLUMEUP },
+	{ 0x860c, KEY_VOLUMEDOWN },
+
+	{ 0x860a, KEY_CAMERA },
+	{ 0x860b, KEY_ZOOM },
+	{ 0x861b, KEY_BACKSPACE },
+	{ 0x8615, KEY_ENTER },
+
+	{ 0x861d, KEY_UP },
+	{ 0x861e, KEY_DOWN },
+	{ 0x860e, KEY_LEFT },
+	{ 0x860f, KEY_RIGHT },
+
+	{ 0x8618, KEY_RECORD },
+	{ 0x861a, KEY_STOP },
+
+	/* Key codes for the EvolutePC TVWay+ remote (proto NEC) */
+	{ 0x7a00, KEY_MENU },
+	{ 0x7a01, KEY_RECORD },
+	{ 0x7a02, KEY_PLAY },
+	{ 0x7a03, KEY_STOP },
+	{ 0x7a10, KEY_CHANNELUP },
+	{ 0x7a11, KEY_CHANNELDOWN },
+	{ 0x7a12, KEY_VOLUMEUP },
+	{ 0x7a13, KEY_VOLUMEDOWN },
+	{ 0x7a40, KEY_POWER },
+	{ 0x7a41, KEY_MUTE },
 };
 
 /* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
@@ -1133,6 +1188,7 @@
 	 .clock_khz = 12000,
 	 .clock_pad_drive = 0,
 	 .flip_chip = 1,
+	 .charge_pump = 2,
 };
 
 static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
@@ -1209,6 +1265,16 @@
 	return 0;
 }
 
+static int stk70x0p_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
+{
+    return dib7000p_pid_filter(adapter->fe, index, pid, onoff);
+}
+
+static int stk70x0p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
+{
+    return dib7000p_pid_filter_ctrl(adapter->fe, onoff);
+}
+
 static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
 	60000, 15000, // internal, sampling
 	1, 20, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
@@ -1500,6 +1566,15 @@
 	return 0;
 }
 
+static int stk807x_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
+{
+    return dib8000_pid_filter(adapter->fe, index, pid, onoff);
+}
+
+static int stk807x_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
+{
+    return dib8000_pid_filter_ctrl(adapter->fe, onoff);
+}
 
 /* STK807x */
 static int stk807x_frontend_attach(struct dvb_usb_adapter *adap)
@@ -1861,6 +1936,7 @@
 	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK807XPVR) },
 	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK807XP) },
 	{ USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) },
+	{ USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) },
 	{ 0 }		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1895,6 +1971,10 @@
 		.num_adapters = 1,
 		.adapter = {
 			{
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter       = stk70x0p_pid_filter,
+				.pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
 				.frontend_attach  = stk7700p_frontend_attach,
 				.tuner_attach     = stk7700p_tuner_attach,
 
@@ -1976,11 +2056,19 @@
 		.num_adapters = 2,
 		.adapter = {
 			{
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter       = stk70x0p_pid_filter,
+				.pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
 				.frontend_attach  = stk7700d_frontend_attach,
 				.tuner_attach     = stk7700d_tuner_attach,
 
 				DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
 			}, {
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter       = stk70x0p_pid_filter,
+				.pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
 				.frontend_attach  = stk7700d_frontend_attach,
 				.tuner_attach     = stk7700d_tuner_attach,
 
@@ -2023,6 +2111,10 @@
 		.num_adapters = 1,
 		.adapter = {
 			{
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter       = stk70x0p_pid_filter,
+				.pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
 				.frontend_attach  = stk7700P2_frontend_attach,
 				.tuner_attach     = stk7700d_tuner_attach,
 
@@ -2055,6 +2147,10 @@
 		.num_adapters = 1,
 		.adapter = {
 			{
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter       = stk70x0p_pid_filter,
+				.pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
 				.frontend_attach  = stk7070p_frontend_attach,
 				.tuner_attach     = dib7070p_tuner_attach,
 
@@ -2122,6 +2218,10 @@
 		.num_adapters = 1,
 		.adapter = {
 			{
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter       = stk70x0p_pid_filter,
+				.pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
 				.frontend_attach  = stk7070p_frontend_attach,
 				.tuner_attach     = dib7070p_tuner_attach,
 
@@ -2157,6 +2257,10 @@
 		.num_adapters = 2,
 		.adapter = {
 			{
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter       = stk70x0p_pid_filter,
+				.pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
 				.frontend_attach  = stk7070pd_frontend_attach0,
 				.tuner_attach     = dib7070p_tuner_attach,
 
@@ -2164,6 +2268,10 @@
 
 				.size_of_priv     = sizeof(struct dib0700_adapter_state),
 			}, {
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter       = stk70x0p_pid_filter,
+				.pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
 				.frontend_attach  = stk7070pd_frontend_attach1,
 				.tuner_attach     = dib7070p_tuner_attach,
 
@@ -2210,6 +2318,10 @@
 		.num_adapters = 1,
 		.adapter = {
 			{
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter       = stk70x0p_pid_filter,
+				.pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
 				.frontend_attach  = stk7700ph_frontend_attach,
 				.tuner_attach     = stk7700ph_tuner_attach,
 
@@ -2322,6 +2434,10 @@
 		.num_adapters = 1,
 		.adapter = {
 			{
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter       = stk70x0p_pid_filter,
+				.pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
 				.frontend_attach  = stk7070p_frontend_attach,
 				.tuner_attach     = dib7770p_tuner_attach,
 
@@ -2353,6 +2469,10 @@
 		.num_adapters = 1,
 		.adapter = {
 			{
+				.caps  = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter = stk807x_pid_filter,
+				.pid_filter_ctrl = stk807x_pid_filter_ctrl,
 				.frontend_attach  = stk807x_frontend_attach,
 				.tuner_attach     = dib807x_tuner_attach,
 
@@ -2363,7 +2483,7 @@
 			},
 		},
 
-		.num_device_descs = 2,
+		.num_device_descs = 3,
 		.devices = {
 			{   "DiBcom STK807xP reference design",
 				{ &dib0700_usb_id_table[62], NULL },
@@ -2373,6 +2493,10 @@
 				{ &dib0700_usb_id_table[63], NULL },
 				{ NULL },
 			},
+			{   "EvolutePC TVWay+",
+				{ &dib0700_usb_id_table[64], NULL },
+				{ NULL },
+			},
 		},
 
 		.rc_interval      = DEFAULT_RC_INTERVAL,
@@ -2384,6 +2508,10 @@
 		.num_adapters = 2,
 		.adapter = {
 			{
+				.caps  = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter = stk807x_pid_filter,
+				.pid_filter_ctrl = stk807x_pid_filter_ctrl,
 				.frontend_attach  = stk807xpvr_frontend_attach0,
 				.tuner_attach     = dib807x_tuner_attach,
 
@@ -2393,6 +2521,10 @@
 					sizeof(struct dib0700_adapter_state),
 			},
 			{
+				.caps  = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter = stk807x_pid_filter,
+				.pid_filter_ctrl = stk807x_pid_filter_ctrl,
 				.frontend_attach  = stk807xpvr_frontend_attach1,
 				.tuner_attach     = dib807x_tuner_attach,
 
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
index eeef50b..5c0126d 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -242,7 +242,7 @@
 			{ &dibusb_dib3000mb_table[9],  &dibusb_dib3000mb_table[11], NULL },
 			{ &dibusb_dib3000mb_table[10], &dibusb_dib3000mb_table[12], NULL },
 		},
-		{	"Unkown USB1.1 DVB-T device ???? please report the name to the author",
+		{	"Unknown USB1.1 DVB-T device ???? please report the name to the author",
 			{ &dibusb_dib3000mb_table[13], NULL },
 			{ &dibusb_dib3000mb_table[14], NULL },
 		},
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
index 8a7d87b..df1ec3e 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
@@ -88,6 +88,7 @@
 		goto err;
 	}
 	adap->dvb_adap.priv = adap;
+	adap->dvb_adap.fe_ioctl_override = adap->props.fe_ioctl_override;
 
 	if (adap->dev->props.read_mac_address) {
 		if (adap->dev->props.read_mac_address(adap->dev,adap->dvb_adap.proposed_mac) == 0)
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index a548c14..f1602d4 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -27,6 +27,7 @@
 #define USB_VID_DIBCOM				0x10b8
 #define USB_VID_DPOSH				0x1498
 #define USB_VID_DVICO				0x0fe9
+#define USB_VID_E3C				0x18b4
 #define USB_VID_ELGATO				0x0fd9
 #define USB_VID_EMPIA				0xeb1a
 #define USB_VID_GENPIX				0x09c0
@@ -61,6 +62,7 @@
 #define USB_VID_XTENSIONS			0x1ae7
 #define USB_VID_HUMAX_COEX			0x10b9
 #define USB_VID_774				0x7a69
+#define USB_VID_EVOLUTEPC			0x1e59
 
 /* Product IDs */
 #define USB_PID_ADSTECH_USB2_COLD			0xa333
@@ -103,6 +105,11 @@
 #define USB_PID_DIBCOM_STK7770P				0x1e80
 #define USB_PID_DPOSH_M9206_COLD			0x9206
 #define USB_PID_DPOSH_M9206_WARM			0xa090
+#define USB_PID_E3C_EC168				0x1689
+#define USB_PID_E3C_EC168_2				0xfffa
+#define USB_PID_E3C_EC168_3				0xfffb
+#define USB_PID_E3C_EC168_4				0x1001
+#define USB_PID_E3C_EC168_5				0x1002
 #define USB_PID_UNIWILL_STK7700P			0x6003
 #define USB_PID_GENIUS_TVGO_DVB_T03			0x4012
 #define USB_PID_GRANDTEC_DVBT_USB_COLD			0x0fa0
@@ -115,6 +122,7 @@
 #define USB_PID_KWORLD_395U_3				0xe395
 #define USB_PID_KWORLD_MC810				0xc810
 #define USB_PID_KWORLD_PC160_2T				0xc160
+#define USB_PID_KWORLD_PC160_T				0xc161
 #define USB_PID_KWORLD_VSTREAM_COLD			0x17de
 #define USB_PID_KWORLD_VSTREAM_WARM			0x17df
 #define USB_PID_TERRATEC_CINERGY_T_USB_XE		0x0055
@@ -271,10 +279,13 @@
 #define USB_PID_TELESTAR_STARSTICK_2			0x8000
 #define USB_PID_MSI_DIGI_VOX_MINI_III                   0x8807
 #define USB_PID_SONY_PLAYTV				0x0003
+#define USB_PID_MYGICA_D689				0xd811
 #define USB_PID_ELGATO_EYETV_DTT			0x0021
 #define USB_PID_ELGATO_EYETV_DTT_Dlx			0x0020
 #define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD		0x5000
 #define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM		0x5001
 #define USB_PID_FRIIO_WHITE				0x0001
+#define USB_PID_TVWAY_PLUS				0x0002
+#define USB_PID_SVEON_STV20				0xe39d
 
 #endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index edde87c..6b5ded9 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -259,7 +259,7 @@
 			*state = REMOTE_KEY_REPEAT;
 			break;
 		default:
-			deb_err("unkown type of remote status: %d\n",keybuf[0]);
+			deb_err("unknown type of remote status: %d\n",keybuf[0]);
 			break;
 	}
 	return 0;
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index fe2b87e..0143aef 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -162,6 +162,9 @@
 	struct usb_data_stream_properties stream;
 
 	int size_of_priv;
+
+	int (*fe_ioctl_override) (struct dvb_frontend *,
+				  unsigned int, void *, unsigned int);
 };
 
 /**
diff --git a/drivers/media/dvb/dvb-usb/ec168.c b/drivers/media/dvb/dvb-usb/ec168.c
new file mode 100644
index 0000000..52f5d4f
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/ec168.c
@@ -0,0 +1,440 @@
+/*
+ * E3C EC168 DVB USB driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ *
+ *    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.
+ *
+ */
+
+#include "ec168.h"
+#include "ec100.h"
+#include "mxl5005s.h"
+
+/* debug */
+static int dvb_usb_ec168_debug;
+module_param_named(debug, dvb_usb_ec168_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static struct ec100_config ec168_ec100_config;
+
+static int ec168_rw_udev(struct usb_device *udev, struct ec168_req *req)
+{
+	int ret;
+	unsigned int pipe;
+	u8 request, requesttype;
+	u8 buf[req->size];
+
+	switch (req->cmd) {
+	case DOWNLOAD_FIRMWARE:
+	case GPIO:
+	case WRITE_I2C:
+	case STREAMING_CTRL:
+		requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
+		request = req->cmd;
+		break;
+	case READ_I2C:
+		requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
+		request = req->cmd;
+		break;
+	case GET_CONFIG:
+		requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
+		request = CONFIG;
+		break;
+	case SET_CONFIG:
+		requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
+		request = CONFIG;
+		break;
+	case WRITE_DEMOD:
+		requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
+		request = DEMOD_RW;
+		break;
+	case READ_DEMOD:
+		requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
+		request = DEMOD_RW;
+		break;
+	default:
+		err("unknown command:%02x", req->cmd);
+		ret = -EPERM;
+		goto error;
+	}
+
+	if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
+		/* write */
+		memcpy(buf, req->data, req->size);
+		pipe = usb_sndctrlpipe(udev, 0);
+	} else {
+		/* read */
+		pipe = usb_rcvctrlpipe(udev, 0);
+	}
+
+	msleep(1); /* avoid I2C errors */
+
+	ret = usb_control_msg(udev, pipe, request, requesttype, req->value,
+		req->index, buf, sizeof(buf), EC168_USB_TIMEOUT);
+
+	ec168_debug_dump(request, requesttype, req->value, req->index, buf,
+		req->size, deb_xfer);
+
+	if (ret < 0)
+		goto error;
+	else
+		ret = 0;
+
+	/* read request, copy returned data to return buf */
+	if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
+		memcpy(req->data, buf, req->size);
+
+	return ret;
+error:
+	deb_info("%s: failed:%d\n", __func__, ret);
+	return ret;
+}
+
+static int ec168_ctrl_msg(struct dvb_usb_device *d, struct ec168_req *req)
+{
+	return ec168_rw_udev(d->udev, req);
+}
+
+/* I2C */
+static int ec168_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+	int num)
+{
+	struct dvb_usb_device *d = i2c_get_adapdata(adap);
+	struct ec168_req req;
+	int i = 0;
+	int ret;
+
+	if (num > 2)
+		return -EINVAL;
+
+	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+		return -EAGAIN;
+
+	while (i < num) {
+		if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
+			if (msg[i].addr == ec168_ec100_config.demod_address) {
+				req.cmd = READ_DEMOD;
+				req.value = 0;
+				req.index = 0xff00 + msg[i].buf[0]; /* reg */
+				req.size = msg[i+1].len; /* bytes to read */
+				req.data = &msg[i+1].buf[0];
+				ret = ec168_ctrl_msg(d, &req);
+				i += 2;
+			} else {
+				err("I2C read not implemented");
+				ret = -ENOSYS;
+				i += 2;
+			}
+		} else {
+			if (msg[i].addr == ec168_ec100_config.demod_address) {
+				req.cmd = WRITE_DEMOD;
+				req.value = msg[i].buf[1]; /* val */
+				req.index = 0xff00 + msg[i].buf[0]; /* reg */
+				req.size = 0;
+				req.data = NULL;
+				ret = ec168_ctrl_msg(d, &req);
+				i += 1;
+			} else {
+				req.cmd = WRITE_I2C;
+				req.value = msg[i].buf[0]; /* val */
+				req.index = 0x0100 + msg[i].addr; /* I2C addr */
+				req.size = msg[i].len-1;
+				req.data = &msg[i].buf[1];
+				ret = ec168_ctrl_msg(d, &req);
+				i += 1;
+			}
+		}
+		if (ret)
+			goto error;
+
+	}
+	ret = i;
+
+error:
+	mutex_unlock(&d->i2c_mutex);
+	return i;
+}
+
+
+static u32 ec168_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm ec168_i2c_algo = {
+	.master_xfer   = ec168_i2c_xfer,
+	.functionality = ec168_i2c_func,
+};
+
+/* Callbacks for DVB USB */
+static struct ec100_config ec168_ec100_config = {
+	.demod_address = 0xff, /* not real address, demod is integrated */
+};
+
+static int ec168_ec100_frontend_attach(struct dvb_usb_adapter *adap)
+{
+	deb_info("%s:\n", __func__);
+	adap->fe = dvb_attach(ec100_attach, &ec168_ec100_config,
+		&adap->dev->i2c_adap);
+	if (adap->fe == NULL)
+		return -ENODEV;
+
+	return 0;
+}
+
+static struct mxl5005s_config ec168_mxl5003s_config = {
+	.i2c_address     = 0xc6,
+	.if_freq         = IF_FREQ_4570000HZ,
+	.xtal_freq       = CRYSTAL_FREQ_16000000HZ,
+	.agc_mode        = MXL_SINGLE_AGC,
+	.tracking_filter = MXL_TF_OFF,
+	.rssi_enable     = MXL_RSSI_ENABLE,
+	.cap_select      = MXL_CAP_SEL_ENABLE,
+	.div_out         = MXL_DIV_OUT_4,
+	.clock_out       = MXL_CLOCK_OUT_DISABLE,
+	.output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
+	.top		 = MXL5005S_TOP_25P2,
+	.mod_mode        = MXL_DIGITAL_MODE,
+	.if_mode         = MXL_ZERO_IF,
+	.AgcMasterByte   = 0x00,
+};
+
+static int ec168_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
+{
+	deb_info("%s:\n", __func__);
+	return dvb_attach(mxl5005s_attach, adap->fe, &adap->dev->i2c_adap,
+		&ec168_mxl5003s_config) == NULL ? -ENODEV : 0;
+}
+
+static int ec168_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+	struct ec168_req req = {STREAMING_CTRL, 0x7f01, 0x0202, 0, NULL};
+	deb_info("%s: onoff:%d\n", __func__, onoff);
+	if (onoff)
+		req.index = 0x0102;
+	return ec168_ctrl_msg(adap->dev, &req);
+}
+
+static int ec168_download_firmware(struct usb_device *udev,
+	const struct firmware *fw)
+{
+	int i, len, packets, remainder, ret;
+	u16 addr = 0x0000; /* firmware start address */
+	struct ec168_req req = {DOWNLOAD_FIRMWARE, 0, 0, 0, NULL};
+	deb_info("%s:\n", __func__);
+
+	#define FW_PACKET_MAX_DATA  2048
+	packets = fw->size / FW_PACKET_MAX_DATA;
+	remainder = fw->size % FW_PACKET_MAX_DATA;
+	len = FW_PACKET_MAX_DATA;
+	for (i = 0; i <= packets; i++) {
+		if (i == packets)  /* set size of the last packet */
+			len = remainder;
+
+		req.size = len;
+		req.data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA);
+		req.index = addr;
+		addr += FW_PACKET_MAX_DATA;
+
+		ret = ec168_rw_udev(udev, &req);
+		if (ret) {
+			err("firmware download failed:%d packet:%d", ret, i);
+			goto error;
+		}
+	}
+	req.size = 0;
+
+	/* set "warm"? */
+	req.cmd = SET_CONFIG;
+	req.value = 0;
+	req.index = 0x0001;
+	ret = ec168_rw_udev(udev, &req);
+	if (ret)
+		goto error;
+
+	/* really needed - no idea what does */
+	req.cmd = GPIO;
+	req.value = 0;
+	req.index = 0x0206;
+	ret = ec168_rw_udev(udev, &req);
+	if (ret)
+		goto error;
+
+	/* activate tuner I2C? */
+	req.cmd = WRITE_I2C;
+	req.value = 0;
+	req.index = 0x00c6;
+	ret = ec168_rw_udev(udev, &req);
+	if (ret)
+		goto error;
+
+	return ret;
+error:
+	deb_info("%s: failed:%d\n", __func__, ret);
+	return ret;
+}
+
+static int ec168_identify_state(struct usb_device *udev,
+	struct dvb_usb_device_properties *props,
+	struct dvb_usb_device_description **desc, int *cold)
+{
+	int ret;
+	u8 reply;
+	struct ec168_req req = {GET_CONFIG, 0, 1, sizeof(reply), &reply};
+	deb_info("%s:\n", __func__);
+
+	ret = ec168_rw_udev(udev, &req);
+	if (ret)
+		goto error;
+
+	deb_info("%s: reply:%02x\n", __func__, reply);
+
+	if (reply == 0x01)
+		*cold = 0;
+	else
+		*cold = 1;
+
+	return ret;
+error:
+	deb_info("%s: failed:%d\n", __func__, ret);
+	return ret;
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties ec168_properties;
+
+static int ec168_probe(struct usb_interface *intf,
+	const struct usb_device_id *id)
+{
+	int ret;
+	deb_info("%s: interface:%d\n", __func__,
+		intf->cur_altsetting->desc.bInterfaceNumber);
+
+	ret = dvb_usb_device_init(intf, &ec168_properties, THIS_MODULE, NULL,
+		adapter_nr);
+	if (ret)
+		goto error;
+
+	return ret;
+error:
+	deb_info("%s: failed:%d\n", __func__, ret);
+	return ret;
+}
+
+#define E3C_EC168_1689                          0
+#define E3C_EC168_FFFA                          1
+#define E3C_EC168_FFFB                          2
+#define E3C_EC168_1001                          3
+#define E3C_EC168_1002                          4
+
+static struct usb_device_id ec168_id[] = {
+	[E3C_EC168_1689] =
+		{USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168)},
+	[E3C_EC168_FFFA] =
+		{USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_2)},
+	[E3C_EC168_FFFB] =
+		{USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_3)},
+	[E3C_EC168_1001] =
+		{USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_4)},
+	[E3C_EC168_1002] =
+		{USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_5)},
+	{} /* terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, ec168_id);
+
+static struct dvb_usb_device_properties ec168_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+	.usb_ctrl = DEVICE_SPECIFIC,
+	.download_firmware = ec168_download_firmware,
+	.firmware = "dvb-usb-ec168.fw",
+	.no_reconnect = 1,
+
+	.size_of_priv = 0,
+
+	.num_adapters = 1,
+	.adapter = {
+		{
+			.streaming_ctrl   = ec168_streaming_ctrl,
+			.frontend_attach  = ec168_ec100_frontend_attach,
+			.tuner_attach     = ec168_mxl5003s_tuner_attach,
+			.stream = {
+				.type = USB_BULK,
+				.count = 6,
+				.endpoint = 0x82,
+				.u = {
+					.bulk = {
+						.buffersize = (32*512),
+					}
+				}
+			},
+		}
+	},
+
+	.identify_state = ec168_identify_state,
+
+	.i2c_algo = &ec168_i2c_algo,
+
+	.num_device_descs = 1,
+	.devices = {
+		{
+			.name = "E3C EC168 DVB-T USB2.0 reference design",
+			.cold_ids = {
+				&ec168_id[E3C_EC168_1689],
+				&ec168_id[E3C_EC168_FFFA],
+				&ec168_id[E3C_EC168_FFFB],
+				&ec168_id[E3C_EC168_1001],
+				&ec168_id[E3C_EC168_1002],
+				NULL},
+			.warm_ids = {NULL},
+		},
+	}
+};
+
+static struct usb_driver ec168_driver = {
+	.name       = "dvb_usb_ec168",
+	.probe      = ec168_probe,
+	.disconnect = dvb_usb_device_exit,
+	.id_table   = ec168_id,
+};
+
+/* module stuff */
+static int __init ec168_module_init(void)
+{
+	int ret;
+	deb_info("%s:\n", __func__);
+	ret = usb_register(&ec168_driver);
+	if (ret)
+		err("module init failed:%d", ret);
+
+	return ret;
+}
+
+static void __exit ec168_module_exit(void)
+{
+	deb_info("%s:\n", __func__);
+	/* deregister this driver from the USB subsystem */
+	usb_deregister(&ec168_driver);
+}
+
+module_init(ec168_module_init);
+module_exit(ec168_module_exit);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("E3C EC168 DVB-T USB2.0 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/ec168.h b/drivers/media/dvb/dvb-usb/ec168.h
new file mode 100644
index 0000000..e7e0b83
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/ec168.h
@@ -0,0 +1,73 @@
+/*
+ * E3C EC168 DVB USB driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ *
+ *    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.
+ *
+ */
+
+#ifndef EC168_H
+#define EC168_H
+
+#define DVB_USB_LOG_PREFIX "ec168"
+#include "dvb-usb.h"
+
+#define deb_info(args...) dprintk(dvb_usb_ec168_debug, 0x01, args)
+#define deb_rc(args...)   dprintk(dvb_usb_ec168_debug, 0x02, args)
+#define deb_xfer(args...) dprintk(dvb_usb_ec168_debug, 0x04, args)
+#define deb_reg(args...)  dprintk(dvb_usb_ec168_debug, 0x08, args)
+#define deb_i2c(args...)  dprintk(dvb_usb_ec168_debug, 0x10, args)
+#define deb_fw(args...)   dprintk(dvb_usb_ec168_debug, 0x20, args)
+
+#define ec168_debug_dump(r, t, v, i, b, l, func) { \
+	int loop_; \
+	func("%02x %02x %02x %02x %02x %02x %02x %02x", \
+		t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, l & 0xff, l >> 8); \
+	if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
+		func(" >>> "); \
+	else \
+		func(" <<< "); \
+	for (loop_ = 0; loop_ < l; loop_++) \
+		func("%02x ", b[loop_]); \
+	func("\n");\
+}
+
+#define EC168_USB_TIMEOUT 1000
+
+struct ec168_req {
+	u8  cmd;       /* [1] */
+	u16 value;     /* [2|3] */
+	u16 index;     /* [4|5] */
+	u16 size;      /* [6|7] */
+	u8  *data;
+};
+
+enum ec168_cmd {
+	DOWNLOAD_FIRMWARE    = 0x00,
+	CONFIG               = 0x01,
+	DEMOD_RW             = 0x03,
+	GPIO                 = 0x04,
+	STREAMING_CTRL       = 0x10,
+	READ_I2C             = 0x20,
+	WRITE_I2C            = 0x21,
+	HID_DOWNLOAD         = 0x30,
+	GET_CONFIG,
+	SET_CONFIG,
+	READ_DEMOD,
+	WRITE_DEMOD,
+};
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/friio-fe.c b/drivers/media/dvb/dvb-usb/friio-fe.c
index c4dfe25..9cbbe42 100644
--- a/drivers/media/dvb/dvb-usb/friio-fe.c
+++ b/drivers/media/dvb/dvb-usb/friio-fe.c
@@ -232,12 +232,6 @@
 	return 0;
 }
 
-static int jdvbt90502_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-	*ber = 0;
-	return 0;
-}
-
 static int jdvbt90502_read_signal_strength(struct dvb_frontend *fe,
 					   u16 *strength)
 {
@@ -264,26 +258,26 @@
 	return 0;
 }
 
-static int jdvbt90502_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-	*snr = 0x0101;
-	return 0;
-}
 
-static int jdvbt90502_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+/* filter out un-supported properties to notify users */
+static int jdvbt90502_set_property(struct dvb_frontend *fe,
+				   struct dtv_property *tvp)
 {
-	*ucblocks = 0;
-	return 0;
-}
+	int r = 0;
 
-static int jdvbt90502_get_tune_settings(struct dvb_frontend *fe,
-					struct dvb_frontend_tune_settings *fs)
-{
-	fs->min_delay_ms = 500;
-	fs->step_size = 0;
-	fs->max_drift = 0;
-
-	return 0;
+	switch (tvp->cmd) {
+	case DTV_DELIVERY_SYSTEM:
+		if (tvp->u.data != SYS_ISDBT)
+			r = -EINVAL;
+		break;
+	case DTV_CLEAR:
+	case DTV_TUNE:
+	case DTV_FREQUENCY:
+		break;
+	default:
+		r = -EINVAL;
+	}
+	return r;
 }
 
 static int jdvbt90502_get_frontend(struct dvb_frontend *fe,
@@ -314,6 +308,9 @@
 
 	deb_fe("%s: Freq:%d\n", __func__, p->frequency);
 
+	/* for recovery from DTV_CLEAN */
+	fe->dtv_property_cache.delivery_system = SYS_ISDBT;
+
 	ret = jdvbt90502_pll_set_freq(state, p->frequency);
 	if (ret) {
 		deb_fe("%s:ret == %d\n", __func__, ret);
@@ -323,12 +320,6 @@
 	return 0;
 }
 
-static int jdvbt90502_sleep(struct dvb_frontend *fe)
-{
-	deb_fe("%s called.\n", __func__);
-	return 0;
-}
-
 
 /**
  * (reg, val) commad list to initialize this module.
@@ -394,6 +385,7 @@
 		if (ret != 1)
 			goto error;
 	}
+	fe->dtv_property_cache.delivery_system = SYS_ISDBT;
 	msleep(100);
 
 	return 0;
@@ -468,16 +460,13 @@
 	.release = jdvbt90502_release,
 
 	.init = jdvbt90502_init,
-	.sleep = jdvbt90502_sleep,
 	.write = _jdvbt90502_write,
 
+	.set_property = jdvbt90502_set_property,
+
 	.set_frontend = jdvbt90502_set_frontend,
 	.get_frontend = jdvbt90502_get_frontend,
-	.get_tune_settings = jdvbt90502_get_tune_settings,
 
 	.read_status = jdvbt90502_read_status,
-	.read_ber = jdvbt90502_read_ber,
 	.read_signal_strength = jdvbt90502_read_signal_strength,
-	.read_snr = jdvbt90502_read_snr,
-	.read_ucblocks = jdvbt90502_read_ucblocks,
 };
diff --git a/drivers/media/dvb/dvb-usb/usb-urb.c b/drivers/media/dvb/dvb-usb/usb-urb.c
index 9da2cc9..f9702e3 100644
--- a/drivers/media/dvb/dvb-usb/usb-urb.c
+++ b/drivers/media/dvb/dvb-usb/usb-urb.c
@@ -56,7 +56,7 @@
 				stream->complete(stream, b, urb->actual_length);
 			break;
 		default:
-			err("unkown endpoint type in completition handler.");
+			err("unknown endpoint type in completition handler.");
 			return;
 	}
 	usb_submit_urb(urb,GFP_ATOMIC);
@@ -228,7 +228,7 @@
 		case USB_ISOC:
 			return usb_isoc_urb_init(stream);
 		default:
-			err("unkown URB-type for data transfer.");
+			err("unknown URB-type for data transfer.");
 			return -EINVAL;
 	}
 }
diff --git a/drivers/media/dvb/firewire/Kconfig b/drivers/media/dvb/firewire/Kconfig
index 6902825..4afa292 100644
--- a/drivers/media/dvb/firewire/Kconfig
+++ b/drivers/media/dvb/firewire/Kconfig
@@ -1,6 +1,6 @@
 config DVB_FIREDTV
 	tristate "FireDTV and FloppyDTV"
-	depends on DVB_CORE && IEEE1394
+	depends on DVB_CORE && (FIREWIRE || IEEE1394)
 	help
 	  Support for DVB receivers from Digital Everywhere
 	  which are connected via IEEE 1394 (FireWire).
@@ -13,8 +13,11 @@
 
 if DVB_FIREDTV
 
+config DVB_FIREDTV_FIREWIRE
+	def_bool FIREWIRE = y || (FIREWIRE = m && DVB_FIREDTV = m)
+
 config DVB_FIREDTV_IEEE1394
-	def_bool IEEE1394
+	def_bool IEEE1394 = y || (IEEE1394 = m && DVB_FIREDTV = m)
 
 config DVB_FIREDTV_INPUT
 	def_bool INPUT = y || (INPUT = m && DVB_FIREDTV = m)
diff --git a/drivers/media/dvb/firewire/Makefile b/drivers/media/dvb/firewire/Makefile
index 2034695..da84203 100644
--- a/drivers/media/dvb/firewire/Makefile
+++ b/drivers/media/dvb/firewire/Makefile
@@ -1,6 +1,7 @@
 obj-$(CONFIG_DVB_FIREDTV) += firedtv.o
 
 firedtv-y := firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o
+firedtv-$(CONFIG_DVB_FIREDTV_FIREWIRE) += firedtv-fw.o
 firedtv-$(CONFIG_DVB_FIREDTV_IEEE1394) += firedtv-1394.o
 firedtv-$(CONFIG_DVB_FIREDTV_INPUT)    += firedtv-rc.o
 
diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c
index 2b6eeea..7c5459c2 100644
--- a/drivers/media/dvb/firewire/firedtv-1394.c
+++ b/drivers/media/dvb/firewire/firedtv-1394.c
@@ -1,5 +1,5 @@
 /*
- * FireDTV driver (formerly known as FireSAT)
+ * FireDTV driver -- ieee1394 I/O backend
  *
  * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
  * Copyright (C) 2007-2008 Ben Backx <ben@bbackx.com>
@@ -26,13 +26,16 @@
 #include <iso.h>
 #include <nodemgr.h>
 
+#include <dvb_demux.h>
+
 #include "firedtv.h"
 
 static LIST_HEAD(node_list);
 static DEFINE_SPINLOCK(node_list_lock);
 
-#define FIREWIRE_HEADER_SIZE	4
-#define CIP_HEADER_SIZE		8
+#define CIP_HEADER_SIZE			8
+#define MPEG2_TS_HEADER_SIZE		4
+#define MPEG2_TS_SOURCE_PACKET_SIZE	(4 + 188)
 
 static void rawiso_activity_cb(struct hpsb_iso *iso)
 {
@@ -62,20 +65,20 @@
 		buf = dma_region_i(&iso->data_buf, unsigned char,
 			iso->infos[packet].offset + CIP_HEADER_SIZE);
 		count = (iso->infos[packet].len - CIP_HEADER_SIZE) /
-			(188 + FIREWIRE_HEADER_SIZE);
+			MPEG2_TS_SOURCE_PACKET_SIZE;
 
 		/* ignore empty packet */
 		if (iso->infos[packet].len <= CIP_HEADER_SIZE)
 			continue;
 
 		while (count--) {
-			if (buf[FIREWIRE_HEADER_SIZE] == 0x47)
+			if (buf[MPEG2_TS_HEADER_SIZE] == 0x47)
 				dvb_dmx_swfilter_packets(&fdtv->demux,
-						&buf[FIREWIRE_HEADER_SIZE], 1);
+						&buf[MPEG2_TS_HEADER_SIZE], 1);
 			else
 				dev_err(fdtv->device,
 					"skipping invalid packet\n");
-			buf += 188 + FIREWIRE_HEADER_SIZE;
+			buf += MPEG2_TS_SOURCE_PACKET_SIZE;
 		}
 	}
 out:
@@ -87,15 +90,20 @@
 	return container_of(fdtv->device, struct unit_directory, device)->ne;
 }
 
-static int node_lock(struct firedtv *fdtv, u64 addr, void *data, __be32 arg)
+static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
 {
-	return hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP, data,
-			      (__force quadlet_t)arg);
+	int ret;
+
+	ret = hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP,
+		(__force quadlet_t *)&data[1], (__force quadlet_t)data[0]);
+	data[0] = data[1];
+
+	return ret;
 }
 
-static int node_read(struct firedtv *fdtv, u64 addr, void *data, size_t len)
+static int node_read(struct firedtv *fdtv, u64 addr, void *data)
 {
-	return hpsb_node_read(node_of(fdtv), addr, data, len);
+	return hpsb_node_read(node_of(fdtv), addr, data, 4);
 }
 
 static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
@@ -212,6 +220,7 @@
 		goto fail;
 
 	avc_register_remote_control(fdtv);
+
 	return 0;
 fail:
 	spin_lock_irq(&node_list_lock);
@@ -220,6 +229,7 @@
 	fdtv_unregister_rc(fdtv);
 fail_free:
 	kfree(fdtv);
+
 	return err;
 }
 
@@ -233,10 +243,9 @@
 	list_del(&fdtv->list);
 	spin_unlock_irq(&node_list_lock);
 
-	cancel_work_sync(&fdtv->remote_ctrl_work);
 	fdtv_unregister_rc(fdtv);
-
 	kfree(fdtv);
+
 	return 0;
 }
 
@@ -252,6 +261,7 @@
 
 static struct hpsb_protocol_driver fdtv_driver = {
 	.name		= "firedtv",
+	.id_table	= fdtv_id_table,
 	.update		= node_update,
 	.driver         = {
 		.probe  = node_probe,
@@ -264,12 +274,11 @@
 	.fcp_request	= fcp_request,
 };
 
-int __init fdtv_1394_init(struct ieee1394_device_id id_table[])
+int __init fdtv_1394_init(void)
 {
 	int ret;
 
 	hpsb_register_highlevel(&fdtv_highlevel);
-	fdtv_driver.id_table = id_table;
 	ret = hpsb_register_protocol(&fdtv_driver);
 	if (ret) {
 		printk(KERN_ERR "firedtv: failed to register protocol\n");
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c
index 485d061..50c42a4 100644
--- a/drivers/media/dvb/firewire/firedtv-avc.c
+++ b/drivers/media/dvb/firewire/firedtv-avc.c
@@ -1236,14 +1236,14 @@
 
 #define CMP_OUTPUT_PLUG_CONTROL_REG_0	0xfffff0000904ULL
 
-static int cmp_read(struct firedtv *fdtv, void *buf, u64 addr, size_t len)
+static int cmp_read(struct firedtv *fdtv, u64 addr, __be32 *data)
 {
 	int ret;
 
 	if (mutex_lock_interruptible(&fdtv->avc_mutex))
 		return -EINTR;
 
-	ret = fdtv->backend->read(fdtv, addr, buf, len);
+	ret = fdtv->backend->read(fdtv, addr, data);
 	if (ret < 0)
 		dev_err(fdtv->device, "CMP: read I/O error\n");
 
@@ -1251,14 +1251,14 @@
 	return ret;
 }
 
-static int cmp_lock(struct firedtv *fdtv, void *data, u64 addr, __be32 arg)
+static int cmp_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
 {
 	int ret;
 
 	if (mutex_lock_interruptible(&fdtv->avc_mutex))
 		return -EINTR;
 
-	ret = fdtv->backend->lock(fdtv, addr, data, arg);
+	ret = fdtv->backend->lock(fdtv, addr, data);
 	if (ret < 0)
 		dev_err(fdtv->device, "CMP: lock I/O error\n");
 
@@ -1288,25 +1288,25 @@
 
 int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel)
 {
-	__be32 old_opcr, opcr;
+	__be32 old_opcr, opcr[2];
 	u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
 	int attempts = 0;
 	int ret;
 
-	ret = cmp_read(fdtv, &opcr, opcr_address, 4);
+	ret = cmp_read(fdtv, opcr_address, opcr);
 	if (ret < 0)
 		return ret;
 
 repeat:
-	if (!get_opcr_online(opcr)) {
+	if (!get_opcr_online(*opcr)) {
 		dev_err(fdtv->device, "CMP: output offline\n");
 		return -EBUSY;
 	}
 
-	old_opcr = opcr;
+	old_opcr = *opcr;
 
-	if (get_opcr_p2p_connections(opcr)) {
-		if (get_opcr_channel(opcr) != channel) {
+	if (get_opcr_p2p_connections(*opcr)) {
+		if (get_opcr_channel(*opcr) != channel) {
 			dev_err(fdtv->device, "CMP: cannot change channel\n");
 			return -EBUSY;
 		}
@@ -1314,11 +1314,11 @@
 
 		/* We don't allocate isochronous resources. */
 	} else {
-		set_opcr_channel(&opcr, channel);
-		set_opcr_data_rate(&opcr, 2); /* S400 */
+		set_opcr_channel(opcr, channel);
+		set_opcr_data_rate(opcr, 2); /* S400 */
 
 		/* FIXME: this is for the worst case - optimize */
-		set_opcr_overhead_id(&opcr, 0);
+		set_opcr_overhead_id(opcr, 0);
 
 		/*
 		 * FIXME: allocate isochronous channel and bandwidth at IRM
@@ -1326,13 +1326,16 @@
 		 */
 	}
 
-	set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) + 1);
+	set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) + 1);
 
-	ret = cmp_lock(fdtv, &opcr, opcr_address, old_opcr);
+	opcr[1] = *opcr;
+	opcr[0] = old_opcr;
+
+	ret = cmp_lock(fdtv, opcr_address, opcr);
 	if (ret < 0)
 		return ret;
 
-	if (old_opcr != opcr) {
+	if (old_opcr != *opcr) {
 		/*
 		 * FIXME: if old_opcr.P2P_Connections > 0,
 		 * deallocate isochronous channel and bandwidth at IRM
@@ -1350,27 +1353,30 @@
 
 void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel)
 {
-	__be32 old_opcr, opcr;
+	__be32 old_opcr, opcr[2];
 	u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
 	int attempts = 0;
 
-	if (cmp_read(fdtv, &opcr, opcr_address, 4) < 0)
+	if (cmp_read(fdtv, opcr_address, opcr) < 0)
 		return;
 
 repeat:
-	if (!get_opcr_online(opcr) || !get_opcr_p2p_connections(opcr) ||
-	    get_opcr_channel(opcr) != channel) {
+	if (!get_opcr_online(*opcr) || !get_opcr_p2p_connections(*opcr) ||
+	    get_opcr_channel(*opcr) != channel) {
 		dev_err(fdtv->device, "CMP: no connection to break\n");
 		return;
 	}
 
-	old_opcr = opcr;
-	set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) - 1);
+	old_opcr = *opcr;
+	set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) - 1);
 
-	if (cmp_lock(fdtv, &opcr, opcr_address, old_opcr) < 0)
+	opcr[1] = *opcr;
+	opcr[0] = old_opcr;
+
+	if (cmp_lock(fdtv, opcr_address, opcr) < 0)
 		return;
 
-	if (old_opcr != opcr) {
+	if (old_opcr != *opcr) {
 		/*
 		 * FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last
 		 * owner, deallocate isochronous channel and bandwidth at IRM
diff --git a/drivers/media/dvb/firewire/firedtv-dvb.c b/drivers/media/dvb/firewire/firedtv-dvb.c
index 5742fde..fc9996c 100644
--- a/drivers/media/dvb/firewire/firedtv-dvb.c
+++ b/drivers/media/dvb/firewire/firedtv-dvb.c
@@ -297,7 +297,7 @@
 #define AVC_UNIT_SPEC_ID_ENTRY	0x00a02d
 #define AVC_SW_VERSION_ENTRY	0x010001
 
-static struct ieee1394_device_id fdtv_id_table[] = {
+const struct ieee1394_device_id fdtv_id_table[] = {
 	{
 		/* FloppyDTV S/CI and FloppyDTV S2 */
 		.match_flags	= MATCH_FLAGS,
@@ -346,12 +346,23 @@
 
 static int __init fdtv_init(void)
 {
-	return fdtv_1394_init(fdtv_id_table);
+	int ret;
+
+	ret = fdtv_fw_init();
+	if (ret < 0)
+		return ret;
+
+	ret = fdtv_1394_init();
+	if (ret < 0)
+		fdtv_fw_exit();
+
+	return ret;
 }
 
 static void __exit fdtv_exit(void)
 {
 	fdtv_1394_exit();
+	fdtv_fw_exit();
 }
 
 module_init(fdtv_init);
diff --git a/drivers/media/dvb/firewire/firedtv-fw.c b/drivers/media/dvb/firewire/firedtv-fw.c
new file mode 100644
index 0000000..fe44789
--- /dev/null
+++ b/drivers/media/dvb/firewire/firedtv-fw.c
@@ -0,0 +1,376 @@
+/*
+ * FireDTV driver -- firewire I/O backend
+ */
+
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/firewire.h>
+#include <linux/firewire-constants.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/page.h>
+
+#include <dvb_demux.h>
+
+#include "firedtv.h"
+
+static LIST_HEAD(node_list);
+static DEFINE_SPINLOCK(node_list_lock);
+
+static inline struct fw_device *device_of(struct firedtv *fdtv)
+{
+	return fw_device(fdtv->device->parent);
+}
+
+static int node_req(struct firedtv *fdtv, u64 addr, void *data, size_t len,
+		    int tcode)
+{
+	struct fw_device *device = device_of(fdtv);
+	int rcode, generation = device->generation;
+
+	smp_rmb(); /* node_id vs. generation */
+
+	rcode = fw_run_transaction(device->card, tcode, device->node_id,
+			generation, device->max_speed, addr, data, len);
+
+	return rcode != RCODE_COMPLETE ? -EIO : 0;
+}
+
+static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
+{
+	return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP);
+}
+
+static int node_read(struct firedtv *fdtv, u64 addr, void *data)
+{
+	return node_req(fdtv, addr, data, 4, TCODE_READ_QUADLET_REQUEST);
+}
+
+static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
+{
+	return node_req(fdtv, addr, data, len, TCODE_WRITE_BLOCK_REQUEST);
+}
+
+#define ISO_HEADER_SIZE			4
+#define CIP_HEADER_SIZE			8
+#define MPEG2_TS_HEADER_SIZE		4
+#define MPEG2_TS_SOURCE_PACKET_SIZE	(4 + 188)
+
+#define MAX_PACKET_SIZE		1024  /* 776, rounded up to 2^n */
+#define PACKETS_PER_PAGE	(PAGE_SIZE / MAX_PACKET_SIZE)
+#define N_PACKETS		64    /* buffer size */
+#define N_PAGES			DIV_ROUND_UP(N_PACKETS, PACKETS_PER_PAGE)
+#define IRQ_INTERVAL		16
+
+struct firedtv_receive_context {
+	struct fw_iso_context *context;
+	struct fw_iso_buffer buffer;
+	int interrupt_packet;
+	int current_packet;
+	char *pages[N_PAGES];
+};
+
+static int queue_iso(struct firedtv_receive_context *ctx, int index)
+{
+	struct fw_iso_packet p;
+
+	p.payload_length = MAX_PACKET_SIZE;
+	p.interrupt = !(++ctx->interrupt_packet & (IRQ_INTERVAL - 1));
+	p.skip = 0;
+	p.header_length = ISO_HEADER_SIZE;
+
+	return fw_iso_context_queue(ctx->context, &p, &ctx->buffer,
+				    index * MAX_PACKET_SIZE);
+}
+
+static void handle_iso(struct fw_iso_context *context, u32 cycle,
+		       size_t header_length, void *header, void *data)
+{
+	struct firedtv *fdtv = data;
+	struct firedtv_receive_context *ctx = fdtv->backend_data;
+	__be32 *h, *h_end;
+	int length, err, i = ctx->current_packet;
+	char *p, *p_end;
+
+	for (h = header, h_end = h + header_length / 4; h < h_end; h++) {
+		length = be32_to_cpup(h) >> 16;
+		if (unlikely(length > MAX_PACKET_SIZE)) {
+			dev_err(fdtv->device, "length = %d\n", length);
+			length = MAX_PACKET_SIZE;
+		}
+
+		p = ctx->pages[i / PACKETS_PER_PAGE]
+				+ (i % PACKETS_PER_PAGE) * MAX_PACKET_SIZE;
+		p_end = p + length;
+
+		for (p += CIP_HEADER_SIZE + MPEG2_TS_HEADER_SIZE; p < p_end;
+		     p += MPEG2_TS_SOURCE_PACKET_SIZE)
+			dvb_dmx_swfilter_packets(&fdtv->demux, p, 1);
+
+		err = queue_iso(ctx, i);
+		if (unlikely(err))
+			dev_err(fdtv->device, "requeue failed\n");
+
+		i = (i + 1) & (N_PACKETS - 1);
+	}
+	ctx->current_packet = i;
+}
+
+static int start_iso(struct firedtv *fdtv)
+{
+	struct firedtv_receive_context *ctx;
+	struct fw_device *device = device_of(fdtv);
+	int i, err;
+
+	ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+
+	ctx->context = fw_iso_context_create(device->card,
+			FW_ISO_CONTEXT_RECEIVE, fdtv->isochannel,
+			device->max_speed, ISO_HEADER_SIZE, handle_iso, fdtv);
+	if (IS_ERR(ctx->context)) {
+		err = PTR_ERR(ctx->context);
+		goto fail_free;
+	}
+
+	err = fw_iso_buffer_init(&ctx->buffer, device->card,
+				 N_PAGES, DMA_FROM_DEVICE);
+	if (err)
+		goto fail_context_destroy;
+
+	ctx->interrupt_packet = 0;
+	ctx->current_packet = 0;
+
+	for (i = 0; i < N_PAGES; i++)
+		ctx->pages[i] = page_address(ctx->buffer.pages[i]);
+
+	for (i = 0; i < N_PACKETS; i++) {
+		err = queue_iso(ctx, i);
+		if (err)
+			goto fail;
+	}
+
+	err = fw_iso_context_start(ctx->context, -1, 0,
+				   FW_ISO_CONTEXT_MATCH_ALL_TAGS);
+	if (err)
+		goto fail;
+
+	fdtv->backend_data = ctx;
+
+	return 0;
+fail:
+	fw_iso_buffer_destroy(&ctx->buffer, device->card);
+fail_context_destroy:
+	fw_iso_context_destroy(ctx->context);
+fail_free:
+	kfree(ctx);
+
+	return err;
+}
+
+static void stop_iso(struct firedtv *fdtv)
+{
+	struct firedtv_receive_context *ctx = fdtv->backend_data;
+
+	fw_iso_context_stop(ctx->context);
+	fw_iso_buffer_destroy(&ctx->buffer, device_of(fdtv)->card);
+	fw_iso_context_destroy(ctx->context);
+	kfree(ctx);
+}
+
+static const struct firedtv_backend backend = {
+	.lock		= node_lock,
+	.read		= node_read,
+	.write		= node_write,
+	.start_iso	= start_iso,
+	.stop_iso	= stop_iso,
+};
+
+static void handle_fcp(struct fw_card *card, struct fw_request *request,
+		       int tcode, int destination, int source, int generation,
+		       int speed, unsigned long long offset,
+		       void *payload, size_t length, void *callback_data)
+{
+	struct firedtv *f, *fdtv = NULL;
+	struct fw_device *device;
+	unsigned long flags;
+	int su;
+
+	if ((tcode != TCODE_WRITE_QUADLET_REQUEST &&
+	     tcode != TCODE_WRITE_BLOCK_REQUEST) ||
+	    offset != CSR_REGISTER_BASE + CSR_FCP_RESPONSE ||
+	    length == 0 ||
+	    (((u8 *)payload)[0] & 0xf0) != 0) {
+		fw_send_response(card, request, RCODE_TYPE_ERROR);
+		return;
+	}
+
+	su = ((u8 *)payload)[1] & 0x7;
+
+	spin_lock_irqsave(&node_list_lock, flags);
+	list_for_each_entry(f, &node_list, list) {
+		device = device_of(f);
+		if (device->generation != generation)
+			continue;
+
+		smp_rmb(); /* node_id vs. generation */
+
+		if (device->card == card &&
+		    device->node_id == source &&
+		    (f->subunit == su || (f->subunit == 0 && su == 0x7))) {
+			fdtv = f;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&node_list_lock, flags);
+
+	if (fdtv) {
+		avc_recv(fdtv, payload, length);
+		fw_send_response(card, request, RCODE_COMPLETE);
+	}
+}
+
+static struct fw_address_handler fcp_handler = {
+	.length           = CSR_FCP_END - CSR_FCP_RESPONSE,
+	.address_callback = handle_fcp,
+};
+
+static const struct fw_address_region fcp_region = {
+	.start	= CSR_REGISTER_BASE + CSR_FCP_RESPONSE,
+	.end	= CSR_REGISTER_BASE + CSR_FCP_END,
+};
+
+/* Adjust the template string if models with longer names appear. */
+#define MAX_MODEL_NAME_LEN ((int)DIV_ROUND_UP(sizeof("FireDTV ????"), 4))
+
+static size_t model_name(u32 *directory, __be32 *buffer)
+{
+	struct fw_csr_iterator ci;
+	int i, length, key, value, last_key = 0;
+	u32 *block = NULL;
+
+	fw_csr_iterator_init(&ci, directory);
+	while (fw_csr_iterator_next(&ci, &key, &value)) {
+		if (last_key == CSR_MODEL &&
+		    key == (CSR_DESCRIPTOR | CSR_LEAF))
+			block = ci.p - 1 + value;
+		last_key = key;
+	}
+
+	if (block == NULL)
+		return 0;
+
+	length = min((int)(block[0] >> 16) - 2, MAX_MODEL_NAME_LEN);
+	if (length <= 0)
+		return 0;
+
+	/* fast-forward to text string */
+	block += 3;
+
+	for (i = 0; i < length; i++)
+		buffer[i] = cpu_to_be32(block[i]);
+
+	return length * 4;
+}
+
+static int node_probe(struct device *dev)
+{
+	struct firedtv *fdtv;
+	__be32 name[MAX_MODEL_NAME_LEN];
+	int name_len, err;
+
+	name_len = model_name(fw_unit(dev)->directory, name);
+
+	fdtv = fdtv_alloc(dev, &backend, (char *)name, name_len);
+	if (!fdtv)
+		return -ENOMEM;
+
+	err = fdtv_register_rc(fdtv, dev);
+	if (err)
+		goto fail_free;
+
+	spin_lock_irq(&node_list_lock);
+	list_add_tail(&fdtv->list, &node_list);
+	spin_unlock_irq(&node_list_lock);
+
+	err = avc_identify_subunit(fdtv);
+	if (err)
+		goto fail;
+
+	err = fdtv_dvb_register(fdtv);
+	if (err)
+		goto fail;
+
+	avc_register_remote_control(fdtv);
+
+	return 0;
+fail:
+	spin_lock_irq(&node_list_lock);
+	list_del(&fdtv->list);
+	spin_unlock_irq(&node_list_lock);
+	fdtv_unregister_rc(fdtv);
+fail_free:
+	kfree(fdtv);
+
+	return err;
+}
+
+static int node_remove(struct device *dev)
+{
+	struct firedtv *fdtv = dev_get_drvdata(dev);
+
+	fdtv_dvb_unregister(fdtv);
+
+	spin_lock_irq(&node_list_lock);
+	list_del(&fdtv->list);
+	spin_unlock_irq(&node_list_lock);
+
+	fdtv_unregister_rc(fdtv);
+
+	kfree(fdtv);
+	return 0;
+}
+
+static void node_update(struct fw_unit *unit)
+{
+	struct firedtv *fdtv = dev_get_drvdata(&unit->device);
+
+	if (fdtv->isochannel >= 0)
+		cmp_establish_pp_connection(fdtv, fdtv->subunit,
+					    fdtv->isochannel);
+}
+
+static struct fw_driver fdtv_driver = {
+	.driver   = {
+		.owner  = THIS_MODULE,
+		.name   = "firedtv",
+		.bus    = &fw_bus_type,
+		.probe  = node_probe,
+		.remove = node_remove,
+	},
+	.update   = node_update,
+	.id_table = fdtv_id_table,
+};
+
+int __init fdtv_fw_init(void)
+{
+	int ret;
+
+	ret = fw_core_add_address_handler(&fcp_handler, &fcp_region);
+	if (ret < 0)
+		return ret;
+
+	return driver_register(&fdtv_driver.driver);
+}
+
+void fdtv_fw_exit(void)
+{
+	driver_unregister(&fdtv_driver.driver);
+	fw_core_remove_address_handler(&fcp_handler);
+}
diff --git a/drivers/media/dvb/firewire/firedtv-rc.c b/drivers/media/dvb/firewire/firedtv-rc.c
index 27bca2e..599d66e 100644
--- a/drivers/media/dvb/firewire/firedtv-rc.c
+++ b/drivers/media/dvb/firewire/firedtv-rc.c
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/types.h>
+#include <linux/workqueue.h>
 
 #include "firedtv.h"
 
@@ -163,6 +164,7 @@
 
 void fdtv_unregister_rc(struct firedtv *fdtv)
 {
+	cancel_work_sync(&fdtv->remote_ctrl_work);
 	kfree(fdtv->remote_ctrl_dev->keycode);
 	input_unregister_device(fdtv->remote_ctrl_dev);
 }
diff --git a/drivers/media/dvb/firewire/firedtv.h b/drivers/media/dvb/firewire/firedtv.h
index d48530b..35080db 100644
--- a/drivers/media/dvb/firewire/firedtv.h
+++ b/drivers/media/dvb/firewire/firedtv.h
@@ -16,6 +16,7 @@
 #include <linux/dvb/dmx.h>
 #include <linux/dvb/frontend.h>
 #include <linux/list.h>
+#include <linux/mod_devicetable.h>
 #include <linux/mutex.h>
 #include <linux/spinlock_types.h>
 #include <linux/types.h>
@@ -72,8 +73,8 @@
 struct firedtv;
 
 struct firedtv_backend {
-	int (*lock)(struct firedtv *fdtv, u64 addr, void *data, __be32 arg);
-	int (*read)(struct firedtv *fdtv, u64 addr, void *data, size_t len);
+	int (*lock)(struct firedtv *fdtv, u64 addr, __be32 data[]);
+	int (*read)(struct firedtv *fdtv, u64 addr, void *data);
 	int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len);
 	int (*start_iso)(struct firedtv *fdtv);
 	void (*stop_iso)(struct firedtv *fdtv);
@@ -119,10 +120,10 @@
 
 /* firedtv-1394.c */
 #ifdef CONFIG_DVB_FIREDTV_IEEE1394
-int fdtv_1394_init(struct ieee1394_device_id id_table[]);
+int fdtv_1394_init(void);
 void fdtv_1394_exit(void);
 #else
-static inline int fdtv_1394_init(struct ieee1394_device_id it[]) { return 0; }
+static inline int fdtv_1394_init(void) { return 0; }
 static inline void fdtv_1394_exit(void) {}
 #endif
 
@@ -163,10 +164,20 @@
 			   const struct firedtv_backend *backend,
 			   const char *name, size_t name_len);
 extern const char *fdtv_model_names[];
+extern const struct ieee1394_device_id fdtv_id_table[];
 
 /* firedtv-fe.c */
 void fdtv_frontend_init(struct firedtv *fdtv);
 
+/* firedtv-fw.c */
+#ifdef CONFIG_DVB_FIREDTV_FIREWIRE
+int fdtv_fw_init(void);
+void fdtv_fw_exit(void);
+#else
+static inline int fdtv_fw_init(void) { return 0; }
+static inline void fdtv_fw_exit(void) {}
+#endif
+
 /* firedtv-rc.c */
 #ifdef CONFIG_DVB_FIREDTV_INPUT
 int fdtv_register_rc(struct firedtv *fdtv, struct device *dev);
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index d7c4837..58aac01 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -201,6 +201,13 @@
 	help
 	  A DVB-S tuner module. Say Y when you want to support this frontend.
 
+config DVB_DS3000
+	tristate "Montage Tehnology DS3000 based"
+	depends on DVB_CORE && I2C
+	default m if DVB_FE_CUSTOMISE
+	help
+	  A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
+
 comment "DVB-T (terrestrial) frontends"
 	depends on DVB_CORE
 
@@ -342,6 +349,13 @@
 	help
 	  Say Y when you want to support this frontend.
 
+config DVB_EC100
+	tristate "E3C EC100"
+	depends on DVB_CORE && I2C
+	default m if DVB_FE_CUSTOMISE
+	help
+	  Say Y when you want to support this frontend.
+
 comment "DVB-C (cable) frontends"
 	depends on DVB_CORE
 
@@ -557,6 +571,13 @@
 	help
 	  A DMB-TH tuner module. Say Y when you want to support this frontend.
 
+config DVB_ATBM8830
+	tristate "AltoBeam ATBM8830/8831 DMB-TH demodulator"
+	depends on DVB_CORE && I2C
+	default m if DVB_FE_CUSTOMISE
+	help
+	  A DMB-TH tuner module. Say Y when you want to support this frontend.
+
 comment "Tools to develop new frontends"
 
 config DVB_DUMMY_FE
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 3523767..8234825 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -64,6 +64,7 @@
 obj-$(CONFIG_DVB_S5H1411) += s5h1411.o
 obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o
 obj-$(CONFIG_DVB_LGS8GXX) += lgs8gxx.o
+obj-$(CONFIG_DVB_ATBM8830) += atbm8830.o
 obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o
 obj-$(CONFIG_DVB_AF9013) += af9013.o
 obj-$(CONFIG_DVB_CX24116) += cx24116.o
@@ -76,3 +77,5 @@
 obj-$(CONFIG_DVB_STV090x) += stv090x.o
 obj-$(CONFIG_DVB_STV6110x) += stv6110x.o
 obj-$(CONFIG_DVB_ISL6423) += isl6423.o
+obj-$(CONFIG_DVB_EC100) += ec100.o
+obj-$(CONFIG_DVB_DS3000) += ds3000.o
diff --git a/drivers/media/dvb/frontends/atbm8830.c b/drivers/media/dvb/frontends/atbm8830.c
new file mode 100644
index 0000000..59881a5
--- /dev/null
+++ b/drivers/media/dvb/frontends/atbm8830.c
@@ -0,0 +1,495 @@
+/*
+ *    Support for AltoBeam GB20600 (a.k.a DMB-TH) demodulator
+ *    ATBM8830, ATBM8831
+ *
+ *    Copyright (C) 2009 David T.L. Wong <davidtlwong@gmail.com>
+ *
+ *    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.
+ */
+
+#include <asm/div64.h>
+#include "dvb_frontend.h"
+
+#include "atbm8830.h"
+#include "atbm8830_priv.h"
+
+#define dprintk(args...) \
+	do { \
+		if (debug) \
+			printk(KERN_DEBUG "atbm8830: " args); \
+	} while (0)
+
+static int debug;
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+static int atbm8830_write_reg(struct atbm_state *priv, u16 reg, u8 data)
+{
+	int ret = 0;
+	u8 dev_addr;
+	u8 buf1[] = { reg >> 8, reg & 0xFF };
+	u8 buf2[] = { data };
+	struct i2c_msg msg1 = { .flags = 0, .buf = buf1, .len = 2 };
+	struct i2c_msg msg2 = { .flags = 0, .buf = buf2, .len = 1 };
+
+	dev_addr = priv->config->demod_address;
+	msg1.addr = dev_addr;
+	msg2.addr = dev_addr;
+
+	if (debug >= 2)
+		printk(KERN_DEBUG "%s: reg=0x%04X, data=0x%02X\n",
+			__func__, reg, data);
+
+	ret = i2c_transfer(priv->i2c, &msg1, 1);
+	if (ret != 1)
+		return -EIO;
+
+	ret = i2c_transfer(priv->i2c, &msg2, 1);
+	return (ret != 1) ? -EIO : 0;
+}
+
+static int atbm8830_read_reg(struct atbm_state *priv, u16 reg, u8 *p_data)
+{
+	int ret;
+	u8 dev_addr;
+
+	u8 buf1[] = { reg >> 8, reg & 0xFF };
+	u8 buf2[] = { 0 };
+	struct i2c_msg msg1 = { .flags = 0, .buf = buf1, .len = 2 };
+	struct i2c_msg msg2 = { .flags = I2C_M_RD, .buf = buf2, .len = 1 };
+
+	dev_addr = priv->config->demod_address;
+	msg1.addr = dev_addr;
+	msg2.addr = dev_addr;
+
+	ret = i2c_transfer(priv->i2c, &msg1, 1);
+	if (ret != 1) {
+		dprintk(KERN_DEBUG "%s: error reg=0x%04x, ret=%i\n",
+			__func__, reg, ret);
+		return -EIO;
+	}
+
+	ret = i2c_transfer(priv->i2c, &msg2, 1);
+	if (ret != 1)
+		return -EIO;
+
+	*p_data = buf2[0];
+	if (debug >= 2)
+		printk(KERN_DEBUG "%s: reg=0x%04X, data=0x%02X\n",
+			__func__, reg, buf2[0]);
+
+	return 0;
+}
+
+/* Lock register latch so that multi-register read is atomic */
+static inline int atbm8830_reglatch_lock(struct atbm_state *priv, int lock)
+{
+	return atbm8830_write_reg(priv, REG_READ_LATCH, lock ? 1 : 0);
+}
+
+static int set_osc_freq(struct atbm_state *priv, u32 freq /*in kHz*/)
+{
+	u32 val;
+	u64 t;
+
+	/* 0x100000 * freq / 30.4MHz */
+	t = (u64)0x100000 * freq;
+	do_div(t, 30400);
+	val = t;
+
+	atbm8830_write_reg(priv, REG_OSC_CLK, val);
+	atbm8830_write_reg(priv, REG_OSC_CLK + 1, val >> 8);
+	atbm8830_write_reg(priv, REG_OSC_CLK + 2, val >> 16);
+
+	return 0;
+}
+
+static int set_if_freq(struct atbm_state *priv, u32 freq /*in kHz*/)
+{
+
+	u32 fs = priv->config->osc_clk_freq;
+	u64 t;
+	u32 val;
+	u8 dat;
+
+	if (freq != 0) {
+		/* 2 * PI * (freq - fs) / fs * (2 ^ 22) */
+		t = (u64) 2 * 31416 * (freq - fs);
+		t <<= 22;
+		do_div(t, fs);
+		do_div(t, 1000);
+		val = t;
+
+		atbm8830_write_reg(priv, REG_TUNER_BASEBAND, 1);
+		atbm8830_write_reg(priv, REG_IF_FREQ, val);
+		atbm8830_write_reg(priv, REG_IF_FREQ+1, val >> 8);
+		atbm8830_write_reg(priv, REG_IF_FREQ+2, val >> 16);
+
+		atbm8830_read_reg(priv, REG_ADC_CONFIG, &dat);
+		dat &= 0xFC;
+		atbm8830_write_reg(priv, REG_ADC_CONFIG, dat);
+	} else {
+		/* Zero IF */
+		atbm8830_write_reg(priv, REG_TUNER_BASEBAND, 0);
+
+		atbm8830_read_reg(priv, REG_ADC_CONFIG, &dat);
+		dat &= 0xFC;
+		dat |= 0x02;
+		atbm8830_write_reg(priv, REG_ADC_CONFIG, dat);
+
+		if (priv->config->zif_swap_iq)
+			atbm8830_write_reg(priv, REG_SWAP_I_Q, 0x03);
+		else
+			atbm8830_write_reg(priv, REG_SWAP_I_Q, 0x01);
+	}
+
+	return 0;
+}
+
+static int is_locked(struct atbm_state *priv, u8 *locked)
+{
+	u8 status;
+
+	atbm8830_read_reg(priv, REG_LOCK_STATUS, &status);
+
+	if (locked != NULL)
+		*locked = (status == 1);
+	return 0;
+}
+
+
+static int set_static_channel_mode(struct atbm_state *priv)
+{
+	int i;
+
+	for (i = 0; i < 5; i++)
+		atbm8830_write_reg(priv, 0x099B + i, 0x08);
+
+	atbm8830_write_reg(priv, 0x095B, 0x7F);
+	atbm8830_write_reg(priv, 0x09CB, 0x01);
+	atbm8830_write_reg(priv, 0x09CC, 0x7F);
+	atbm8830_write_reg(priv, 0x09CD, 0x7F);
+	atbm8830_write_reg(priv, 0x0E01, 0x20);
+
+	/* For single carrier */
+	atbm8830_write_reg(priv, 0x0B03, 0x0A);
+	atbm8830_write_reg(priv, 0x0935, 0x10);
+	atbm8830_write_reg(priv, 0x0936, 0x08);
+	atbm8830_write_reg(priv, 0x093E, 0x08);
+	atbm8830_write_reg(priv, 0x096E, 0x06);
+
+	/* frame_count_max0 */
+	atbm8830_write_reg(priv, 0x0B09, 0x00);
+	/* frame_count_max1 */
+	atbm8830_write_reg(priv, 0x0B0A, 0x08);
+
+	return 0;
+}
+
+static int set_ts_config(struct atbm_state *priv)
+{
+	const struct atbm8830_config *cfg = priv->config;
+
+	/*Set parallel/serial ts mode*/
+	atbm8830_write_reg(priv, REG_TS_SERIAL, cfg->serial_ts ? 1 : 0);
+	atbm8830_write_reg(priv, REG_TS_CLK_MODE, cfg->serial_ts ? 1 : 0);
+	/*Set ts sampling edge*/
+	atbm8830_write_reg(priv, REG_TS_SAMPLE_EDGE,
+		cfg->ts_sampling_edge ? 1 : 0);
+	/*Set ts clock freerun*/
+	atbm8830_write_reg(priv, REG_TS_CLK_FREERUN,
+		cfg->ts_clk_gated ? 0 : 1);
+
+	return 0;
+}
+
+static int atbm8830_init(struct dvb_frontend *fe)
+{
+	struct atbm_state *priv = fe->demodulator_priv;
+	const struct atbm8830_config *cfg = priv->config;
+
+	/*Set oscillator frequency*/
+	set_osc_freq(priv, cfg->osc_clk_freq);
+
+	/*Set IF frequency*/
+	set_if_freq(priv, cfg->if_freq);
+
+
+	/*Set static channel mode*/
+	set_static_channel_mode(priv);
+
+	set_ts_config(priv);
+	/*Turn off DSP reset*/
+	atbm8830_write_reg(priv, 0x000A, 0);
+
+	/*SW version test*/
+	atbm8830_write_reg(priv, 0x020C, 11);
+
+	/* Run */
+	atbm8830_write_reg(priv, REG_DEMOD_RUN, 1);
+
+	return 0;
+}
+
+
+static void atbm8830_release(struct dvb_frontend *fe)
+{
+	struct atbm_state *state = fe->demodulator_priv;
+	dprintk("%s\n", __func__);
+
+	kfree(state);
+}
+
+static int atbm8830_set_fe(struct dvb_frontend *fe,
+			  struct dvb_frontend_parameters *fe_params)
+{
+	struct atbm_state *priv = fe->demodulator_priv;
+	int i;
+	u8 locked = 0;
+	dprintk("%s\n", __func__);
+
+	/* set frequency */
+	if (fe->ops.tuner_ops.set_params) {
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 1);
+		fe->ops.tuner_ops.set_params(fe, fe_params);
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 0);
+	}
+
+	/* start auto lock */
+	for (i = 0; i < 10; i++) {
+		mdelay(100);
+		dprintk("Try %d\n", i);
+		is_locked(priv, &locked);
+		if (locked != 0) {
+			dprintk("ATBM8830 locked!\n");
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static int atbm8830_get_fe(struct dvb_frontend *fe,
+			  struct dvb_frontend_parameters *fe_params)
+{
+	dprintk("%s\n", __func__);
+
+	/* TODO: get real readings from device */
+	/* inversion status */
+	fe_params->inversion = INVERSION_OFF;
+
+	/* bandwidth */
+	fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
+
+	fe_params->u.ofdm.code_rate_HP = FEC_AUTO;
+	fe_params->u.ofdm.code_rate_LP = FEC_AUTO;
+
+	fe_params->u.ofdm.constellation = QAM_AUTO;
+
+	/* transmission mode */
+	fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
+
+	/* guard interval */
+	fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
+
+	/* hierarchy */
+	fe_params->u.ofdm.hierarchy_information = HIERARCHY_NONE;
+
+	return 0;
+}
+
+static int atbm8830_get_tune_settings(struct dvb_frontend *fe,
+	struct dvb_frontend_tune_settings *fesettings)
+{
+	fesettings->min_delay_ms = 0;
+	fesettings->step_size = 0;
+	fesettings->max_drift = 0;
+	return 0;
+}
+
+static int atbm8830_read_status(struct dvb_frontend *fe, fe_status_t *fe_status)
+{
+	struct atbm_state *priv = fe->demodulator_priv;
+	u8 locked = 0;
+	u8 agc_locked = 0;
+
+	dprintk("%s\n", __func__);
+	*fe_status = 0;
+
+	is_locked(priv, &locked);
+	if (locked) {
+		*fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+			FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+	}
+	dprintk("%s: fe_status=0x%x\n", __func__, *fe_status);
+
+	atbm8830_read_reg(priv, REG_AGC_LOCK, &agc_locked);
+	dprintk("AGC Lock: %d\n", agc_locked);
+
+	return 0;
+}
+
+static int atbm8830_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+	struct atbm_state *priv = fe->demodulator_priv;
+	u32 frame_err;
+	u8 t;
+
+	dprintk("%s\n", __func__);
+
+	atbm8830_reglatch_lock(priv, 1);
+
+	atbm8830_read_reg(priv, REG_FRAME_ERR_CNT + 1, &t);
+	frame_err = t & 0x7F;
+	frame_err <<= 8;
+	atbm8830_read_reg(priv, REG_FRAME_ERR_CNT, &t);
+	frame_err |= t;
+
+	atbm8830_reglatch_lock(priv, 0);
+
+	*ber = frame_err * 100 / 32767;
+
+	dprintk("%s: ber=0x%x\n", __func__, *ber);
+	return 0;
+}
+
+static int atbm8830_read_signal_strength(struct dvb_frontend *fe, u16 *signal)
+{
+	struct atbm_state *priv = fe->demodulator_priv;
+	u32 pwm;
+	u8 t;
+
+	dprintk("%s\n", __func__);
+	atbm8830_reglatch_lock(priv, 1);
+
+	atbm8830_read_reg(priv, REG_AGC_PWM_VAL + 1, &t);
+	pwm = t & 0x03;
+	pwm <<= 8;
+	atbm8830_read_reg(priv, REG_AGC_PWM_VAL, &t);
+	pwm |= t;
+
+	atbm8830_reglatch_lock(priv, 0);
+
+	dprintk("AGC PWM = 0x%02X\n", pwm);
+	pwm = 0x400 - pwm;
+
+	*signal = pwm * 0x10000 / 0x400;
+
+	return 0;
+}
+
+static int atbm8830_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	dprintk("%s\n", __func__);
+	*snr = 0;
+	return 0;
+}
+
+static int atbm8830_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+	dprintk("%s\n", __func__);
+	*ucblocks = 0;
+	return 0;
+}
+
+static int atbm8830_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+	struct atbm_state *priv = fe->demodulator_priv;
+
+	return atbm8830_write_reg(priv, REG_I2C_GATE, enable ? 1 : 0);
+}
+
+static struct dvb_frontend_ops atbm8830_ops = {
+	.info = {
+		.name = "AltoBeam ATBM8830/8831 DMB-TH",
+		.type = FE_OFDM,
+		.frequency_min = 474000000,
+		.frequency_max = 858000000,
+		.frequency_stepsize = 10000,
+		.caps =
+			FE_CAN_FEC_AUTO |
+			FE_CAN_QAM_AUTO |
+			FE_CAN_TRANSMISSION_MODE_AUTO |
+			FE_CAN_GUARD_INTERVAL_AUTO
+	},
+
+	.release = atbm8830_release,
+
+	.init = atbm8830_init,
+	.sleep = NULL,
+	.write = NULL,
+	.i2c_gate_ctrl = atbm8830_i2c_gate_ctrl,
+
+	.set_frontend = atbm8830_set_fe,
+	.get_frontend = atbm8830_get_fe,
+	.get_tune_settings = atbm8830_get_tune_settings,
+
+	.read_status = atbm8830_read_status,
+	.read_ber = atbm8830_read_ber,
+	.read_signal_strength = atbm8830_read_signal_strength,
+	.read_snr = atbm8830_read_snr,
+	.read_ucblocks = atbm8830_read_ucblocks,
+};
+
+struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
+	struct i2c_adapter *i2c)
+{
+	struct atbm_state *priv = NULL;
+	u8 data = 0;
+
+	dprintk("%s()\n", __func__);
+
+	if (config == NULL || i2c == NULL)
+		return NULL;
+
+	priv = kzalloc(sizeof(struct atbm_state), GFP_KERNEL);
+	if (priv == NULL)
+		goto error_out;
+
+	priv->config = config;
+	priv->i2c = i2c;
+
+	/* check if the demod is there */
+	if (atbm8830_read_reg(priv, REG_CHIP_ID, &data) != 0) {
+		dprintk("%s atbm8830/8831 not found at i2c addr 0x%02X\n",
+			__func__, priv->config->demod_address);
+		goto error_out;
+	}
+	dprintk("atbm8830 chip id: 0x%02X\n", data);
+
+	memcpy(&priv->frontend.ops, &atbm8830_ops,
+	       sizeof(struct dvb_frontend_ops));
+	priv->frontend.demodulator_priv = priv;
+
+	atbm8830_init(&priv->frontend);
+
+	atbm8830_i2c_gate_ctrl(&priv->frontend, 1);
+
+	return &priv->frontend;
+
+error_out:
+	dprintk("%s() error_out\n", __func__);
+	kfree(priv);
+	return NULL;
+
+}
+EXPORT_SYMBOL(atbm8830_attach);
+
+MODULE_DESCRIPTION("AltoBeam ATBM8830/8831 GB20600 demodulator driver");
+MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/atbm8830.h b/drivers/media/dvb/frontends/atbm8830.h
new file mode 100644
index 0000000..e8149f3
--- /dev/null
+++ b/drivers/media/dvb/frontends/atbm8830.h
@@ -0,0 +1,76 @@
+/*
+ *    Support for AltoBeam GB20600 (a.k.a DMB-TH) demodulator
+ *    ATBM8830, ATBM8831
+ *
+ *    Copyright (C) 2009 David T.L. Wong <davidtlwong@gmail.com>
+ *
+ *    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.
+ */
+
+#ifndef __ATBM8830_H__
+#define __ATBM8830_H__
+
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+
+#define ATBM8830_PROD_8830 0
+#define ATBM8830_PROD_8831 1
+
+struct atbm8830_config {
+
+	/* product type */
+	u8 prod;
+
+	/* the demodulator's i2c address */
+	u8 demod_address;
+
+	/* parallel or serial transport stream */
+	u8 serial_ts;
+
+	/* transport stream clock output only when receving valid stream */
+	u8 ts_clk_gated;
+
+	/* Decoder sample TS data at rising edge of clock */
+	u8 ts_sampling_edge;
+
+	/* Oscillator clock frequency */
+	u32 osc_clk_freq; /* in kHz */
+
+	/* IF frequency */
+	u32 if_freq; /* in kHz */
+
+	/* Swap I/Q for zero IF */
+	u8 zif_swap_iq;
+
+	/* Tuner AGC settings */
+	u8 agc_min;
+	u8 agc_max;
+	u8 agc_hold_loop;
+};
+
+#if defined(CONFIG_DVB_ATBM8830) || \
+	(defined(CONFIG_DVB_ATBM8830_MODULE) && defined(MODULE))
+extern struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
+		struct i2c_adapter *i2c);
+#else
+static inline
+struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
+		struct i2c_adapter *i2c) {
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif /* CONFIG_DVB_ATBM8830 */
+
+#endif /* __ATBM8830_H__ */
diff --git a/drivers/media/dvb/frontends/atbm8830_priv.h b/drivers/media/dvb/frontends/atbm8830_priv.h
new file mode 100644
index 0000000..ce960f7
--- /dev/null
+++ b/drivers/media/dvb/frontends/atbm8830_priv.h
@@ -0,0 +1,75 @@
+/*
+ *    Support for AltoBeam GB20600 (a.k.a DMB-TH) demodulator
+ *    ATBM8830, ATBM8831
+ *
+ *    Copyright (C) 2009 David T.L. Wong <davidtlwong@gmail.com>
+ *
+ *    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.
+ */
+ 
+#ifndef __ATBM8830_PRIV_H
+#define __ATBM8830_PRIV_H
+
+struct atbm_state {
+	struct i2c_adapter *i2c;
+	/* configuration settings */
+	const struct atbm8830_config *config;
+	struct dvb_frontend frontend;
+};
+
+#define REG_CHIP_ID	0x0000
+#define REG_TUNER_BASEBAND	0x0001
+#define REG_DEMOD_RUN	0x0004
+#define REG_DSP_RESET	0x0005
+#define REG_RAM_RESET	0x0006
+#define REG_ADC_RESET	0x0007
+#define REG_TSPORT_RESET	0x0008
+#define REG_BLKERR_POL	0x000C
+#define REG_I2C_GATE	0x0103
+#define REG_TS_SAMPLE_EDGE	0x0301
+#define REG_TS_PKT_LEN_204	0x0302
+#define REG_TS_PKT_LEN_AUTO	0x0303
+#define REG_TS_SERIAL	0x0305
+#define REG_TS_CLK_FREERUN	0x0306
+#define REG_TS_VALID_MODE	0x0307
+#define REG_TS_CLK_MODE	0x030B /* 1 for serial, 0 for parallel */
+
+#define REG_TS_ERRBIT_USE	0x030C
+#define REG_LOCK_STATUS	0x030D
+#define REG_ADC_CONFIG	0x0602
+#define REG_CARRIER_OFFSET	0x0827 /* 0x0827-0x0829 little endian */
+#define REG_DETECTED_PN_MODE	0x082D
+#define REG_READ_LATCH	0x084D
+#define REG_IF_FREQ	0x0A00 /* 0x0A00-0x0A02 little endian */
+#define REG_OSC_CLK	0x0A03 /* 0x0A03-0x0A05 little endian */
+#define REG_BYPASS_CCI	0x0A06
+#define REG_ANALOG_LUMA_DETECTED	0x0A25
+#define REG_ANALOG_AUDIO_DETECTED	0x0A26
+#define REG_ANALOG_CHROMA_DETECTED	0x0A39
+#define REG_FRAME_ERR_CNT	0x0B04
+#define REG_USE_EXT_ADC	0x0C00
+#define REG_SWAP_I_Q	0x0C01
+#define REG_TPS_MANUAL	0x0D01
+#define REG_TPS_CONFIG	0x0D02
+#define REG_BYPASS_DEINTERLEAVER	0x0E00
+#define REG_AGC_TARGET	0x1003 /* 0x1003-0x1005 little endian */
+#define REG_AGC_MIN	0x1020
+#define REG_AGC_MAX	0x1023
+#define REG_AGC_LOCK	0x1027
+#define REG_AGC_PWM_VAL	0x1028 /* 0x1028-0x1029 little endian */
+#define REG_AGC_HOLD_LOOP	0x1031
+
+#endif
+
diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c
index 74981ee..2dc2723 100644
--- a/drivers/media/dvb/frontends/au8522_decoder.c
+++ b/drivers/media/dvb/frontends/au8522_decoder.c
@@ -23,7 +23,6 @@
 /* Developer notes:
  *
  * VBI support is not yet working
- * Saturation and hue setting are not yet working
  * Enough is implemented here for CVBS and S-Video inputs, but the actual
  *  analog demodulator code isn't implemented (not needed for xc5000 since it
  *  has its own demodulator and outputs CVBS)
@@ -236,8 +235,10 @@
 	state->contrast = 0x79;
 	au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH, 0x80);
 	au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH, 0x80);
+	state->saturation = 0x80;
 	au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH, 0x00);
 	au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH, 0x00);
+	state->hue = 0x00;
 
 	/* Other decoder registers */
 	au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00);
@@ -315,7 +316,7 @@
 	if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 ||
 	    input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
 		/* Despite what the table says, for the HVR-950q we still need
-		   to be in CVBS mode for the S-Video input (reason uknown). */
+		   to be in CVBS mode for the S-Video input (reason unknown). */
 		/* filter_coef_type = 3; */
 		filter_coef_type = 5;
 	} else {
@@ -504,7 +505,19 @@
 				ctrl->value);
 		break;
 	case V4L2_CID_SATURATION:
+		state->saturation = ctrl->value;
+		au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH,
+				ctrl->value);
+		au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH,
+				ctrl->value);
+		break;
 	case V4L2_CID_HUE:
+		state->hue = ctrl->value;
+		au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH,
+				ctrl->value >> 8);
+		au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH,
+				ctrl->value & 0xFF);
+		break;
 	case V4L2_CID_AUDIO_VOLUME:
 	case V4L2_CID_AUDIO_BASS:
 	case V4L2_CID_AUDIO_TREBLE:
@@ -534,7 +547,11 @@
 		ctrl->value = state->contrast;
 		break;
 	case V4L2_CID_SATURATION:
+		ctrl->value = state->saturation;
+		break;
 	case V4L2_CID_HUE:
+		ctrl->value = state->hue;
+		break;
 	case V4L2_CID_AUDIO_VOLUME:
 	case V4L2_CID_AUDIO_BASS:
 	case V4L2_CID_AUDIO_TREBLE:
@@ -632,8 +649,9 @@
 	case V4L2_CID_BRIGHTNESS:
 		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
 	case V4L2_CID_SATURATION:
+		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
 	case V4L2_CID_HUE:
-		/* Not yet implemented */
+		return v4l2_ctrl_query_fill(qc, -32768, 32768, 1, 0);
 	default:
 		break;
 	}
diff --git a/drivers/media/dvb/frontends/au8522_priv.h b/drivers/media/dvb/frontends/au8522_priv.h
index f328f2b..c74c4e7 100644
--- a/drivers/media/dvb/frontends/au8522_priv.h
+++ b/drivers/media/dvb/frontends/au8522_priv.h
@@ -62,6 +62,8 @@
 	u32 rev;
 	u8 brightness;
 	u8 contrast;
+	u8 saturation;
+	s16 hue;
 };
 
 /* These are routines shared by both the VSB/QAM demodulator and the analog
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
index ffbcfab..00a4e8f 100644
--- a/drivers/media/dvb/frontends/cx24110.c
+++ b/drivers/media/dvb/frontends/cx24110.c
@@ -1,4 +1,4 @@
-	/*
+/*
     cx24110 - Single Chip Satellite Channel Receiver driver module
 
     Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on
@@ -96,7 +96,7 @@
 	 {0x42,0x00}, /* @ middle bytes " */
 	 {0x43,0x00}, /* @ LSB          " */
 		      /* leave the carrier tracking loop parameters on default */
-		      /* leave the bit timing loop parameters at gefault */
+		      /* leave the bit timing loop parameters at default */
 	 {0x56,0x4d}, /* set the filtune voltage to 2.7V, as recommended by */
 		      /* the cx24108 data sheet for symbol rates above 15MS/s */
 	 {0x57,0x00}, /* @ Filter sigma delta enabled, positive */
diff --git a/drivers/media/dvb/frontends/cx24113.c b/drivers/media/dvb/frontends/cx24113.c
index 075b2b5..e9ee555 100644
--- a/drivers/media/dvb/frontends/cx24113.c
+++ b/drivers/media/dvb/frontends/cx24113.c
@@ -589,7 +589,7 @@
 		info("detected CX24113 variant\n");
 		break;
 	case REV_CX24113:
-		info("sucessfully detected\n");
+		info("successfully detected\n");
 		break;
 	default:
 		err("unsupported device id: %x\n", state->rev);
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c
index 136b9d2..ad4c8cf 100644
--- a/drivers/media/dvb/frontends/dib3000mb.c
+++ b/drivers/media/dvb/frontends/dib3000mb.c
@@ -154,7 +154,7 @@
 			case BANDWIDTH_AUTO:
 				return -EOPNOTSUPP;
 			default:
-				err("unkown bandwidth value.");
+				err("unknown bandwidth value.");
 				return -EINVAL;
 		}
 	}
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
index 0781f94..750ae61 100644
--- a/drivers/media/dvb/frontends/dib7000p.c
+++ b/drivers/media/dvb/frontends/dib7000p.c
@@ -108,7 +108,7 @@
 
 	outreg = 0;
 	fifo_threshold = 1792;
-	smo_mode = (dib7000p_read_word(state, 235) & 0x0010) | (1 << 1);
+	smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
 
 	dprintk( "setting output mode for demod %p to %d",
 			&state->demod, mode);
@@ -162,18 +162,19 @@
 	if (state->div_force_off) {
 		dprintk( "diversity combination deactivated - forced by COFDM parameters");
 		onoff = 0;
-	}
+		dib7000p_write_word(state, 207, 0);
+	} else
+		dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
+
 	state->div_state = (u8)onoff;
 
 	if (onoff) {
 		dib7000p_write_word(state, 204, 6);
 		dib7000p_write_word(state, 205, 16);
 		/* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
-		dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
 	} else {
 		dib7000p_write_word(state, 204, 1);
 		dib7000p_write_word(state, 205, 0);
-		dib7000p_write_word(state, 207, 0);
 	}
 
 	return 0;
@@ -1188,7 +1189,7 @@
 		*stat |= FE_HAS_VITERBI;
 	if (lock & 0x0010)
 		*stat |= FE_HAS_SYNC;
-	if (lock & 0x0008)
+    if ((lock & 0x0038) == 0x38)
 		*stat |= FE_HAS_LOCK;
 
 	return 0;
@@ -1302,6 +1303,24 @@
 }
 EXPORT_SYMBOL(dib7000p_get_i2c_master);
 
+int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
+{
+    struct dib7000p_state *state = fe->demodulator_priv;
+    u16 val = dib7000p_read_word(state, 235) & 0xffef;
+    val |= (onoff & 0x1) << 4;
+    dprintk("PID filter enabled %d", onoff);
+    return dib7000p_write_word(state, 235, val);
+}
+EXPORT_SYMBOL(dib7000p_pid_filter_ctrl);
+
+int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
+{
+    struct dib7000p_state *state = fe->demodulator_priv;
+    dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
+    return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0);
+}
+EXPORT_SYMBOL(dib7000p_pid_filter);
+
 int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
 {
 	struct dib7000p_state st = { .i2c_adap = i2c };
@@ -1314,8 +1333,10 @@
 		/* designated i2c address */
 		new_addr          = (0x40 + k) << 1;
 		st.i2c_addr = new_addr;
+		dib7000p_write_word(&st, 1287, 0x0003); /* sram lead in, rdy */
 		if (dib7000p_identify(&st) != 0) {
 			st.i2c_addr = default_addr;
+			dib7000p_write_word(&st, 1287, 0x0003); /* sram lead in, rdy */
 			if (dib7000p_identify(&st) != 0) {
 				dprintk("DiB7000P #%d: not identified\n", k);
 				return -EIO;
@@ -1372,6 +1393,8 @@
 	demod->demodulator_priv = st;
 	memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));
 
+    dib7000p_write_word(st, 1287, 0x0003); /* sram lead in, rdy */
+
 	if (dib7000p_identify(st) != 0)
 		goto error;
 
diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h
index 02a4c82..805dd13 100644
--- a/drivers/media/dvb/frontends/dib7000p.h
+++ b/drivers/media/dvb/frontends/dib7000p.h
@@ -51,6 +51,8 @@
 extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
 extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value);
 extern int dib7000pc_detection(struct i2c_adapter *i2c_adap);
+extern int dib7000p_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
+extern int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff);
 #else
 static inline
 struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
@@ -95,6 +97,17 @@
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return -ENODEV;
 }
+static inline int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
+{
+    printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+    return -ENODEV;
+}
+
+static inline int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, uint8_t onoff)
+{
+    printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+    return -ENODEV;
+}
 #endif
 
 #endif
diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c
index 852c790..898400d 100644
--- a/drivers/media/dvb/frontends/dib8000.c
+++ b/drivers/media/dvb/frontends/dib8000.c
@@ -954,7 +954,7 @@
 	u8 guard, crate, constellation, timeI;
 	u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
 	u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff;	// All 13 segments enabled
-	const s16 *ncoeff, *ana_fe;
+	const s16 *ncoeff = NULL, *ana_fe;
 	u16 tmcc_pow = 0;
 	u16 coff_pow = 0x2800;
 	u16 init_prbs = 0xfff;
@@ -2121,7 +2121,7 @@
 	else
 		result -= intlog10(2) * 10 * noise_exp - 100;
 
-	*snr = result / (1 << 24);
+	*snr = result / ((1 << 24) / 10);
 	return 0;
 }
 
@@ -2195,6 +2195,25 @@
 
 EXPORT_SYMBOL(dib8000_get_i2c_master);
 
+int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
+{
+	struct dib8000_state *st = fe->demodulator_priv;
+    u16 val = dib8000_read_word(st, 299) & 0xffef;
+    val |= (onoff & 0x1) << 4;
+
+    dprintk("pid filter enabled %d", onoff);
+    return dib8000_write_word(st, 299, val);
+}
+EXPORT_SYMBOL(dib8000_pid_filter_ctrl);
+
+int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
+{
+	struct dib8000_state *st = fe->demodulator_priv;
+    dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
+    return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0);
+}
+EXPORT_SYMBOL(dib8000_pid_filter);
+
 static const struct dvb_frontend_ops dib8000_ops = {
 	.info = {
 		 .name = "DiBcom 8000 ISDB-T",
diff --git a/drivers/media/dvb/frontends/dib8000.h b/drivers/media/dvb/frontends/dib8000.h
index a86de34..8c89482 100644
--- a/drivers/media/dvb/frontends/dib8000.h
+++ b/drivers/media/dvb/frontends/dib8000.h
@@ -44,6 +44,8 @@
 
 extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
 extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value);
+extern int dib8000_pid_filter_ctrl(struct dvb_frontend *, u8 onoff);
+extern int dib8000_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
 #else
 static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
 {
@@ -74,6 +76,18 @@
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return -ENODEV;
 }
+
+int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return -ENODEV;
+}
+
+int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return -ENODEV;
+}
 #endif
 
 #endif
diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c
index 0100755..868b78b 100644
--- a/drivers/media/dvb/frontends/drx397xD.c
+++ b/drivers/media/dvb/frontends/drx397xD.c
@@ -81,7 +81,7 @@
 #include "drx397xD_fw.h"
 };
 
-/* use only with writer lock aquired */
+/* use only with writer lock acquired */
 static void _drx_release_fw(struct drx397xD_state *s, enum fw_ix ix)
 {
 	memset(&fw[ix].data[0], 0, sizeof(fw[0].data));
diff --git a/drivers/media/dvb/frontends/ds3000.c b/drivers/media/dvb/frontends/ds3000.c
new file mode 100644
index 0000000..cff3535
--- /dev/null
+++ b/drivers/media/dvb/frontends/ds3000.c
@@ -0,0 +1,1367 @@
+/*
+    Montage Technology DS3000/TS2020 - DVBS/S2 Demodulator/Tuner driver
+    Copyright (C) 2009 Konstantin Dimitrov <kosio.dimitrov@gmail.com>
+
+    Copyright (C) 2009 TurboSight.com
+
+    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.
+ */
+
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/firmware.h>
+
+#include "dvb_frontend.h"
+#include "ds3000.h"
+
+static int debug;
+
+#define dprintk(args...) \
+	do { \
+		if (debug) \
+			printk(args); \
+	} while (0)
+
+/* as of March 2009 current DS3000 firmware version is 1.78 */
+/* DS3000 FW v1.78 MD5: a32d17910c4f370073f9346e71d34b80 */
+#define DS3000_DEFAULT_FIRMWARE "dvb-fe-ds3000.fw"
+
+#define DS3000_SAMPLE_RATE 96000 /* in kHz */
+#define DS3000_XTAL_FREQ   27000 /* in kHz */
+
+/* Register values to initialise the demod in DVB-S mode */
+static u8 ds3000_dvbs_init_tab[] = {
+	0x23, 0x05,
+	0x08, 0x03,
+	0x0c, 0x00,
+	0x21, 0x54,
+	0x25, 0x82,
+	0x27, 0x31,
+	0x30, 0x08,
+	0x31, 0x40,
+	0x32, 0x32,
+	0x33, 0x35,
+	0x35, 0xff,
+	0x3a, 0x00,
+	0x37, 0x10,
+	0x38, 0x10,
+	0x39, 0x02,
+	0x42, 0x60,
+	0x4a, 0x40,
+	0x4b, 0x04,
+	0x4d, 0x91,
+	0x5d, 0xc8,
+	0x50, 0x77,
+	0x51, 0x77,
+	0x52, 0x36,
+	0x53, 0x36,
+	0x56, 0x01,
+	0x63, 0x43,
+	0x64, 0x30,
+	0x65, 0x40,
+	0x68, 0x26,
+	0x69, 0x4c,
+	0x70, 0x20,
+	0x71, 0x70,
+	0x72, 0x04,
+	0x73, 0x00,
+	0x70, 0x40,
+	0x71, 0x70,
+	0x72, 0x04,
+	0x73, 0x00,
+	0x70, 0x60,
+	0x71, 0x70,
+	0x72, 0x04,
+	0x73, 0x00,
+	0x70, 0x80,
+	0x71, 0x70,
+	0x72, 0x04,
+	0x73, 0x00,
+	0x70, 0xa0,
+	0x71, 0x70,
+	0x72, 0x04,
+	0x73, 0x00,
+	0x70, 0x1f,
+	0x76, 0x00,
+	0x77, 0xd1,
+	0x78, 0x0c,
+	0x79, 0x80,
+	0x7f, 0x04,
+	0x7c, 0x00,
+	0x80, 0x86,
+	0x81, 0xa6,
+	0x85, 0x04,
+	0xcd, 0xf4,
+	0x90, 0x33,
+	0xa0, 0x44,
+	0xc0, 0x18,
+	0xc3, 0x10,
+	0xc4, 0x08,
+	0xc5, 0x80,
+	0xc6, 0x80,
+	0xc7, 0x0a,
+	0xc8, 0x1a,
+	0xc9, 0x80,
+	0xfe, 0x92,
+	0xe0, 0xf8,
+	0xe6, 0x8b,
+	0xd0, 0x40,
+	0xf8, 0x20,
+	0xfa, 0x0f,
+	0xfd, 0x20,
+	0xad, 0x20,
+	0xae, 0x07,
+	0xb8, 0x00,
+};
+
+/* Register values to initialise the demod in DVB-S2 mode */
+static u8 ds3000_dvbs2_init_tab[] = {
+	0x23, 0x0f,
+	0x08, 0x07,
+	0x0c, 0x00,
+	0x21, 0x54,
+	0x25, 0x82,
+	0x27, 0x31,
+	0x30, 0x08,
+	0x31, 0x32,
+	0x32, 0x32,
+	0x33, 0x35,
+	0x35, 0xff,
+	0x3a, 0x00,
+	0x37, 0x10,
+	0x38, 0x10,
+	0x39, 0x02,
+	0x42, 0x60,
+	0x4a, 0x80,
+	0x4b, 0x04,
+	0x4d, 0x81,
+	0x5d, 0x88,
+	0x50, 0x36,
+	0x51, 0x36,
+	0x52, 0x36,
+	0x53, 0x36,
+	0x63, 0x60,
+	0x64, 0x10,
+	0x65, 0x10,
+	0x68, 0x04,
+	0x69, 0x29,
+	0x70, 0x20,
+	0x71, 0x70,
+	0x72, 0x04,
+	0x73, 0x00,
+	0x70, 0x40,
+	0x71, 0x70,
+	0x72, 0x04,
+	0x73, 0x00,
+	0x70, 0x60,
+	0x71, 0x70,
+	0x72, 0x04,
+	0x73, 0x00,
+	0x70, 0x80,
+	0x71, 0x70,
+	0x72, 0x04,
+	0x73, 0x00,
+	0x70, 0xa0,
+	0x71, 0x70,
+	0x72, 0x04,
+	0x73, 0x00,
+	0x70, 0x1f,
+	0xa0, 0x44,
+	0xc0, 0x08,
+	0xc1, 0x10,
+	0xc2, 0x08,
+	0xc3, 0x10,
+	0xc4, 0x08,
+	0xc5, 0xf0,
+	0xc6, 0xf0,
+	0xc7, 0x0a,
+	0xc8, 0x1a,
+	0xc9, 0x80,
+	0xca, 0x23,
+	0xcb, 0x24,
+	0xce, 0x74,
+	0x90, 0x03,
+	0x76, 0x80,
+	0x77, 0x42,
+	0x78, 0x0a,
+	0x79, 0x80,
+	0xad, 0x40,
+	0xae, 0x07,
+	0x7f, 0xd4,
+	0x7c, 0x00,
+	0x80, 0xa8,
+	0x81, 0xda,
+	0x7c, 0x01,
+	0x80, 0xda,
+	0x81, 0xec,
+	0x7c, 0x02,
+	0x80, 0xca,
+	0x81, 0xeb,
+	0x7c, 0x03,
+	0x80, 0xba,
+	0x81, 0xdb,
+	0x85, 0x08,
+	0x86, 0x00,
+	0x87, 0x02,
+	0x89, 0x80,
+	0x8b, 0x44,
+	0x8c, 0xaa,
+	0x8a, 0x10,
+	0xba, 0x00,
+	0xf5, 0x04,
+	0xfe, 0x44,
+	0xd2, 0x32,
+	0xb8, 0x00,
+};
+
+/* DS3000 doesn't need some parameters as input and auto-detects them */
+/* save input from the application of those parameters */
+struct ds3000_tuning {
+	u32 frequency;
+	u32 symbol_rate;
+	fe_spectral_inversion_t inversion;
+	enum fe_code_rate fec;
+
+	/* input values */
+	u8 inversion_val;
+	fe_modulation_t delivery;
+	u8 rolloff;
+};
+
+struct ds3000_state {
+	struct i2c_adapter *i2c;
+	const struct ds3000_config *config;
+
+	struct dvb_frontend frontend;
+
+	struct ds3000_tuning dcur;
+	struct ds3000_tuning dnxt;
+
+	u8 skip_fw_load;
+
+	/* previous uncorrected block counter for DVB-S2 */
+	u16 prevUCBS2;
+};
+
+static int ds3000_writereg(struct ds3000_state *state, int reg, int data)
+{
+	u8 buf[] = { reg, data };
+	struct i2c_msg msg = { .addr = state->config->demod_address,
+		.flags = 0, .buf = buf, .len = 2 };
+	int err;
+
+	dprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data);
+
+	err = i2c_transfer(state->i2c, &msg, 1);
+	if (err != 1) {
+		printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x,"
+			 " value == 0x%02x)\n", __func__, err, reg, data);
+		return -EREMOTEIO;
+	}
+
+	return 0;
+}
+
+static int ds3000_tuner_writereg(struct ds3000_state *state, int reg, int data)
+{
+	u8 buf[] = { reg, data };
+	struct i2c_msg msg = { .addr = 0x60,
+		.flags = 0, .buf = buf, .len = 2 };
+	int err;
+
+	dprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data);
+
+	ds3000_writereg(state, 0x03, 0x11);
+	err = i2c_transfer(state->i2c, &msg, 1);
+	if (err != 1) {
+		printk("%s: writereg error(err == %i, reg == 0x%02x,"
+			 " value == 0x%02x)\n", __func__, err, reg, data);
+		return -EREMOTEIO;
+	}
+
+	return 0;
+}
+
+/* I2C write for 8k firmware load */
+static int ds3000_writeFW(struct ds3000_state *state, int reg,
+				const u8 *data, u16 len)
+{
+	int i, ret = -EREMOTEIO;
+	struct i2c_msg msg;
+	u8 *buf;
+
+	buf = kmalloc(3, GFP_KERNEL);
+	if (buf == NULL) {
+		printk(KERN_ERR "Unable to kmalloc\n");
+		ret = -ENOMEM;
+		goto error;
+	}
+
+	*(buf) = reg;
+
+	msg.addr = state->config->demod_address;
+	msg.flags = 0;
+	msg.buf = buf;
+	msg.len = 3;
+
+	for (i = 0; i < len; i += 2) {
+		memcpy(buf + 1, data + i, 2);
+
+		dprintk("%s: write reg 0x%02x, len = %d\n", __func__, reg, len);
+
+		ret = i2c_transfer(state->i2c, &msg, 1);
+		if (ret != 1) {
+			printk(KERN_ERR "%s: write error(err == %i, "
+				"reg == 0x%02x\n", __func__, ret, reg);
+			ret = -EREMOTEIO;
+		}
+	}
+
+error:
+	kfree(buf);
+
+	return ret;
+}
+
+static int ds3000_readreg(struct ds3000_state *state, u8 reg)
+{
+	int ret;
+	u8 b0[] = { reg };
+	u8 b1[] = { 0 };
+	struct i2c_msg msg[] = {
+		{
+			.addr = state->config->demod_address,
+			.flags = 0,
+			.buf = b0,
+			.len = 1
+		}, {
+			.addr = state->config->demod_address,
+			.flags = I2C_M_RD,
+			.buf = b1,
+			.len = 1
+		}
+	};
+
+	ret = i2c_transfer(state->i2c, msg, 2);
+
+	if (ret != 2) {
+		printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
+		return ret;
+	}
+
+	dprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]);
+
+	return b1[0];
+}
+
+static int ds3000_tuner_readreg(struct ds3000_state *state, u8 reg)
+{
+	int ret;
+	u8 b0[] = { reg };
+	u8 b1[] = { 0 };
+	struct i2c_msg msg[] = {
+		{
+			.addr = 0x60,
+			.flags = 0,
+			.buf = b0,
+			.len = 1
+		}, {
+			.addr = 0x60,
+			.flags = I2C_M_RD,
+			.buf = b1,
+			.len = 1
+		}
+	};
+
+	ds3000_writereg(state, 0x03, 0x12);
+	ret = i2c_transfer(state->i2c, msg, 2);
+
+	if (ret != 2) {
+		printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
+		return ret;
+	}
+
+	dprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]);
+
+	return b1[0];
+}
+
+static int ds3000_set_inversion(struct ds3000_state *state,
+					fe_spectral_inversion_t inversion)
+{
+	dprintk("%s(%d)\n", __func__, inversion);
+
+	switch (inversion) {
+	case INVERSION_OFF:
+	case INVERSION_ON:
+	case INVERSION_AUTO:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	state->dnxt.inversion = inversion;
+
+	return 0;
+}
+
+static int ds3000_set_symbolrate(struct ds3000_state *state, u32 rate)
+{
+	int ret = 0;
+
+	dprintk("%s()\n", __func__);
+
+	dprintk("%s() symbol_rate = %d\n", __func__, state->dnxt.symbol_rate);
+
+	/*  check if symbol rate is within limits */
+	if ((state->dnxt.symbol_rate >
+				state->frontend.ops.info.symbol_rate_max) ||
+	    (state->dnxt.symbol_rate <
+				state->frontend.ops.info.symbol_rate_min))
+		ret = -EOPNOTSUPP;
+
+	state->dnxt.symbol_rate = rate;
+
+	return ret;
+}
+
+static int ds3000_load_firmware(struct dvb_frontend *fe,
+					const struct firmware *fw);
+
+static int ds3000_firmware_ondemand(struct dvb_frontend *fe)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	const struct firmware *fw;
+	int ret = 0;
+
+	dprintk("%s()\n", __func__);
+
+	if (ds3000_readreg(state, 0xb2) <= 0)
+		return ret;
+
+	if (state->skip_fw_load)
+		return 0;
+	/* Load firmware */
+	/* request the firmware, this will block until someone uploads it */
+	printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__,
+				DS3000_DEFAULT_FIRMWARE);
+	ret = request_firmware(&fw, DS3000_DEFAULT_FIRMWARE,
+				state->i2c->dev.parent);
+	printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__);
+	if (ret) {
+		printk(KERN_ERR "%s: No firmware uploaded (timeout or file not "
+				"found?)\n", __func__);
+		return ret;
+	}
+
+	/* Make sure we don't recurse back through here during loading */
+	state->skip_fw_load = 1;
+
+	ret = ds3000_load_firmware(fe, fw);
+	if (ret)
+		printk("%s: Writing firmware to device failed\n", __func__);
+
+	release_firmware(fw);
+
+	dprintk("%s: Firmware upload %s\n", __func__,
+			ret == 0 ? "complete" : "failed");
+
+	/* Ensure firmware is always loaded if required */
+	state->skip_fw_load = 0;
+
+	return ret;
+}
+
+static int ds3000_load_firmware(struct dvb_frontend *fe,
+					const struct firmware *fw)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+
+	dprintk("%s\n", __func__);
+	dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
+			fw->size,
+			fw->data[0],
+			fw->data[1],
+			fw->data[fw->size - 2],
+			fw->data[fw->size - 1]);
+
+	/* Begin the firmware load process */
+	ds3000_writereg(state, 0xb2, 0x01);
+	/* write the entire firmware */
+	ds3000_writeFW(state, 0xb0, fw->data, fw->size);
+	ds3000_writereg(state, 0xb2, 0x00);
+
+	return 0;
+}
+
+static void ds3000_dump_registers(struct dvb_frontend *fe)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	int x, y, reg = 0, val;
+
+	for (y = 0; y < 16; y++) {
+		dprintk("%s: %02x: ", __func__, y);
+		for (x = 0; x < 16; x++) {
+			reg = (y << 4) + x;
+			val = ds3000_readreg(state, reg);
+			if (x != 15)
+				dprintk("%02x ",  val);
+			else
+				dprintk("%02x\n", val);
+		}
+	}
+	dprintk("%s: -- DS3000 DUMP DONE --\n", __func__);
+}
+
+static int ds3000_read_status(struct dvb_frontend *fe, fe_status_t* status)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	int lock;
+
+	*status = 0;
+
+	switch (c->delivery_system) {
+	case SYS_DVBS:
+		lock = ds3000_readreg(state, 0xd1);
+		if ((lock & 0x07) == 0x07)
+			*status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
+				FE_HAS_VITERBI | FE_HAS_SYNC |
+				FE_HAS_LOCK;
+
+		break;
+	case SYS_DVBS2:
+		lock = ds3000_readreg(state, 0x0d);
+		if ((lock & 0x8f) == 0x8f)
+			*status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
+				FE_HAS_VITERBI | FE_HAS_SYNC |
+				FE_HAS_LOCK;
+
+		break;
+	default:
+		return 1;
+	}
+
+	dprintk("%s: status = 0x%02x\n", __func__, lock);
+
+	return 0;
+}
+
+#define FE_IS_TUNED (FE_HAS_SIGNAL + FE_HAS_LOCK)
+static int ds3000_is_tuned(struct dvb_frontend *fe)
+{
+	fe_status_t tunerstat;
+
+	ds3000_read_status(fe, &tunerstat);
+
+	return ((tunerstat & FE_IS_TUNED) == FE_IS_TUNED);
+}
+
+/* read DS3000 BER value */
+static int ds3000_read_ber(struct dvb_frontend *fe, u32* ber)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	u8 data;
+	u32 ber_reading, lpdc_frames;
+
+	dprintk("%s()\n", __func__);
+
+	switch (c->delivery_system) {
+	case SYS_DVBS:
+		/* set the number of bytes checked during
+		BER estimation */
+		ds3000_writereg(state, 0xf9, 0x04);
+		/* read BER estimation status */
+		data = ds3000_readreg(state, 0xf8);
+		/* check if BER estimation is ready */
+		if ((data & 0x10) == 0) {
+			/* this is the number of error bits,
+			to calculate the bit error rate
+			divide to 8388608 */
+			*ber = (ds3000_readreg(state, 0xf7) << 8) |
+				ds3000_readreg(state, 0xf6);
+			/* start counting error bits */
+			/* need to be set twice
+			otherwise it fails sometimes */
+			data |= 0x10;
+			ds3000_writereg(state, 0xf8, data);
+			ds3000_writereg(state, 0xf8, data);
+		} else
+			/* used to indicate that BER estimation
+			is not ready, i.e. BER is unknown */
+			*ber = 0xffffffff;
+		break;
+	case SYS_DVBS2:
+		/* read the number of LPDC decoded frames */
+		lpdc_frames = (ds3000_readreg(state, 0xd7) << 16) |
+				(ds3000_readreg(state, 0xd6) << 8) |
+				ds3000_readreg(state, 0xd5);
+		/* read the number of packets with bad CRC */
+		ber_reading = (ds3000_readreg(state, 0xf8) << 8) |
+				ds3000_readreg(state, 0xf7);
+		if (lpdc_frames > 750) {
+			/* clear LPDC frame counters */
+			ds3000_writereg(state, 0xd1, 0x01);
+			/* clear bad packets counter */
+			ds3000_writereg(state, 0xf9, 0x01);
+			/* enable bad packets counter */
+			ds3000_writereg(state, 0xf9, 0x00);
+			/* enable LPDC frame counters */
+			ds3000_writereg(state, 0xd1, 0x00);
+			*ber = ber_reading;
+		} else
+			/* used to indicate that BER estimation is not ready,
+			i.e. BER is unknown */
+			*ber = 0xffffffff;
+		break;
+	default:
+		return 1;
+	}
+
+	return 0;
+}
+
+/* read TS2020 signal strength */
+static int ds3000_read_signal_strength(struct dvb_frontend *fe,
+						u16 *signal_strength)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	u16 sig_reading, sig_strength;
+	u8 rfgain, bbgain;
+
+	dprintk("%s()\n", __func__);
+
+	rfgain = ds3000_tuner_readreg(state, 0x3d) & 0x1f;
+	bbgain = ds3000_tuner_readreg(state, 0x21) & 0x1f;
+
+	if (rfgain > 15)
+		rfgain = 15;
+	if (bbgain > 13)
+		bbgain = 13;
+
+	sig_reading = rfgain * 2 + bbgain * 3;
+
+	sig_strength = 40 + (64 - sig_reading) * 50 / 64 ;
+
+	/* cook the value to be suitable for szap-s2 human readable output */
+	*signal_strength = sig_strength * 1000;
+
+	dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n", __func__,
+			sig_reading, *signal_strength);
+
+	return 0;
+}
+
+/* calculate DS3000 snr value in dB */
+static int ds3000_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	u8 snr_reading, snr_value;
+	u32 dvbs2_signal_reading, dvbs2_noise_reading, tmp;
+	static const u16 dvbs_snr_tab[] = { /* 20 x Table (rounded up) */
+		0x0000, 0x1b13, 0x2aea, 0x3627, 0x3ede, 0x45fe, 0x4c03,
+		0x513a, 0x55d4, 0x59f2, 0x5dab, 0x6111, 0x6431, 0x6717,
+		0x69c9, 0x6c4e, 0x6eac, 0x70e8, 0x7304, 0x7505
+	};
+	static const u16 dvbs2_snr_tab[] = { /* 80 x Table (rounded up) */
+		0x0000, 0x0bc2, 0x12a3, 0x1785, 0x1b4e, 0x1e65, 0x2103,
+		0x2347, 0x2546, 0x2710, 0x28ae, 0x2a28, 0x2b83, 0x2cc5,
+		0x2df1, 0x2f09, 0x3010, 0x3109, 0x31f4, 0x32d2, 0x33a6,
+		0x3470, 0x3531, 0x35ea, 0x369b, 0x3746, 0x37ea, 0x3888,
+		0x3920, 0x39b3, 0x3a42, 0x3acc, 0x3b51, 0x3bd3, 0x3c51,
+		0x3ccb, 0x3d42, 0x3db6, 0x3e27, 0x3e95, 0x3f00, 0x3f68,
+		0x3fcf, 0x4033, 0x4094, 0x40f4, 0x4151, 0x41ac, 0x4206,
+		0x425e, 0x42b4, 0x4308, 0x435b, 0x43ac, 0x43fc, 0x444a,
+		0x4497, 0x44e2, 0x452d, 0x4576, 0x45bd, 0x4604, 0x4649,
+		0x468e, 0x46d1, 0x4713, 0x4755, 0x4795, 0x47d4, 0x4813,
+		0x4851, 0x488d, 0x48c9, 0x4904, 0x493f, 0x4978, 0x49b1,
+		0x49e9, 0x4a20, 0x4a57
+	};
+
+	dprintk("%s()\n", __func__);
+
+	switch (c->delivery_system) {
+	case SYS_DVBS:
+		snr_reading = ds3000_readreg(state, 0xff);
+		snr_reading /= 8;
+		if (snr_reading == 0)
+			*snr = 0x0000;
+		else {
+			if (snr_reading > 20)
+				snr_reading = 20;
+			snr_value = dvbs_snr_tab[snr_reading - 1] * 10 / 23026;
+			/* cook the value to be suitable for szap-s2
+			human readable output */
+			*snr = snr_value * 8 * 655;
+		}
+		dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
+				snr_reading, *snr);
+		break;
+	case SYS_DVBS2:
+		dvbs2_noise_reading = (ds3000_readreg(state, 0x8c) & 0x3f) +
+				(ds3000_readreg(state, 0x8d) << 4);
+		dvbs2_signal_reading = ds3000_readreg(state, 0x8e);
+		tmp = dvbs2_signal_reading * dvbs2_signal_reading >> 1;
+		if (dvbs2_signal_reading == 0) {
+			*snr = 0x0000;
+			return 0;
+		}
+		if (dvbs2_noise_reading == 0) {
+			snr_value = 0x0013;
+			/* cook the value to be suitable for szap-s2
+			human readable output */
+			*snr = 0xffff;
+			return 0;
+		}
+		if (tmp > dvbs2_noise_reading) {
+			snr_reading = tmp / dvbs2_noise_reading;
+			if (snr_reading > 80)
+				snr_reading = 80;
+			snr_value = dvbs2_snr_tab[snr_reading - 1] / 1000;
+			/* cook the value to be suitable for szap-s2
+			human readable output */
+			*snr = snr_value * 5 * 655;
+		} else {
+			snr_reading = dvbs2_noise_reading / tmp;
+			if (snr_reading > 80)
+				snr_reading = 80;
+			*snr = -(dvbs2_snr_tab[snr_reading] / 1000);
+		}
+		dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
+				snr_reading, *snr);
+		break;
+	default:
+		return 1;
+	}
+
+	return 0;
+}
+
+/* read DS3000 uncorrected blocks */
+static int ds3000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	u8 data;
+	u16 _ucblocks;
+
+	dprintk("%s()\n", __func__);
+
+	switch (c->delivery_system) {
+	case SYS_DVBS:
+		*ucblocks = (ds3000_readreg(state, 0xf5) << 8) |
+				ds3000_readreg(state, 0xf4);
+		data = ds3000_readreg(state, 0xf8);
+		/* clear packet counters */
+		data &= ~0x20;
+		ds3000_writereg(state, 0xf8, data);
+		/* enable packet counters */
+		data |= 0x20;
+		ds3000_writereg(state, 0xf8, data);
+		break;
+	case SYS_DVBS2:
+		_ucblocks = (ds3000_readreg(state, 0xe2) << 8) |
+				ds3000_readreg(state, 0xe1);
+		if (_ucblocks > state->prevUCBS2)
+			*ucblocks = _ucblocks - state->prevUCBS2;
+		else
+			*ucblocks = state->prevUCBS2 - _ucblocks;
+		state->prevUCBS2 = _ucblocks;
+		break;
+	default:
+		return 1;
+	}
+
+	return 0;
+}
+
+/* Overwrite the current tuning params, we are about to tune */
+static void ds3000_clone_params(struct dvb_frontend *fe)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur));
+}
+
+static int ds3000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	u8 data;
+
+	dprintk("%s(%d)\n", __func__, tone);
+	if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
+		printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone);
+		return -EINVAL;
+	}
+
+	data = ds3000_readreg(state, 0xa2);
+	data &= ~0xc0;
+	ds3000_writereg(state, 0xa2, data);
+
+	switch (tone) {
+	case SEC_TONE_ON:
+		dprintk("%s: setting tone on\n", __func__);
+		data = ds3000_readreg(state, 0xa1);
+		data &= ~0x43;
+		data |= 0x04;
+		ds3000_writereg(state, 0xa1, data);
+		break;
+	case SEC_TONE_OFF:
+		dprintk("%s: setting tone off\n", __func__);
+		data = ds3000_readreg(state, 0xa2);
+		data |= 0x80;
+		ds3000_writereg(state, 0xa2, data);
+		break;
+	}
+
+	return 0;
+}
+
+static int ds3000_send_diseqc_msg(struct dvb_frontend *fe,
+				struct dvb_diseqc_master_cmd *d)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	int i;
+	u8 data;
+
+	/* Dump DiSEqC message */
+	dprintk("%s(", __func__);
+	for (i = 0 ; i < d->msg_len;) {
+		dprintk("0x%02x", d->msg[i]);
+		if (++i < d->msg_len)
+			dprintk(", ");
+	}
+
+	/* enable DiSEqC message send pin */
+	data = ds3000_readreg(state, 0xa2);
+	data &= ~0xc0;
+	ds3000_writereg(state, 0xa2, data);
+
+	/* DiSEqC message */
+	for (i = 0; i < d->msg_len; i++)
+		ds3000_writereg(state, 0xa3 + i, d->msg[i]);
+
+	data = ds3000_readreg(state, 0xa1);
+	/* clear DiSEqC message length and status,
+	enable DiSEqC message send */
+	data &= ~0xf8;
+	/* set DiSEqC mode, modulation active during 33 pulses,
+	set DiSEqC message length */
+	data |= ((d->msg_len - 1) << 3) | 0x07;
+	ds3000_writereg(state, 0xa1, data);
+
+	/* wait up to 150ms for DiSEqC transmission to complete */
+	for (i = 0; i < 15; i++) {
+		data = ds3000_readreg(state, 0xa1);
+		if ((data & 0x40) == 0)
+			break;
+		msleep(10);
+	}
+
+	/* DiSEqC timeout after 150ms */
+	if (i == 15) {
+		data = ds3000_readreg(state, 0xa1);
+		data &= ~0x80;
+		data |= 0x40;
+		ds3000_writereg(state, 0xa1, data);
+
+		data = ds3000_readreg(state, 0xa2);
+		data &= ~0xc0;
+		data |= 0x80;
+		ds3000_writereg(state, 0xa2, data);
+
+		return 1;
+	}
+
+	data = ds3000_readreg(state, 0xa2);
+	data &= ~0xc0;
+	data |= 0x80;
+	ds3000_writereg(state, 0xa2, data);
+
+	return 0;
+}
+
+/* Send DiSEqC burst */
+static int ds3000_diseqc_send_burst(struct dvb_frontend *fe,
+					fe_sec_mini_cmd_t burst)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	int i;
+	u8 data;
+
+	dprintk("%s()\n", __func__);
+
+	data = ds3000_readreg(state, 0xa2);
+	data &= ~0xc0;
+	ds3000_writereg(state, 0xa2, data);
+
+	/* DiSEqC burst */
+	if (burst == SEC_MINI_A)
+		/* Unmodulated tone burst */
+		ds3000_writereg(state, 0xa1, 0x02);
+	else if (burst == SEC_MINI_B)
+		/* Modulated tone burst */
+		ds3000_writereg(state, 0xa1, 0x01);
+	else
+		return -EINVAL;
+
+	msleep(13);
+	for (i = 0; i < 5; i++) {
+		data = ds3000_readreg(state, 0xa1);
+		if ((data & 0x40) == 0)
+			break;
+		msleep(1);
+	}
+
+	if (i == 5) {
+		data = ds3000_readreg(state, 0xa1);
+		data &= ~0x80;
+		data |= 0x40;
+		ds3000_writereg(state, 0xa1, data);
+
+		data = ds3000_readreg(state, 0xa2);
+		data &= ~0xc0;
+		data |= 0x80;
+		ds3000_writereg(state, 0xa2, data);
+
+		return 1;
+	}
+
+	data = ds3000_readreg(state, 0xa2);
+	data &= ~0xc0;
+	data |= 0x80;
+	ds3000_writereg(state, 0xa2, data);
+
+	return 0;
+}
+
+static void ds3000_release(struct dvb_frontend *fe)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	dprintk("%s\n", __func__);
+	kfree(state);
+}
+
+static struct dvb_frontend_ops ds3000_ops;
+
+struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
+				    struct i2c_adapter *i2c)
+{
+	struct ds3000_state *state = NULL;
+	int ret;
+
+	dprintk("%s\n", __func__);
+
+	/* allocate memory for the internal state */
+	state = kmalloc(sizeof(struct ds3000_state), GFP_KERNEL);
+	if (state == NULL) {
+		printk(KERN_ERR "Unable to kmalloc\n");
+		goto error2;
+	}
+
+	/* setup the state */
+	memset(state, 0, sizeof(struct ds3000_state));
+
+	state->config = config;
+	state->i2c = i2c;
+	state->prevUCBS2 = 0;
+
+	/* check if the demod is present */
+	ret = ds3000_readreg(state, 0x00) & 0xfe;
+	if (ret != 0xe0) {
+		printk(KERN_ERR "Invalid probe, probably not a DS3000\n");
+		goto error3;
+	}
+
+	printk(KERN_INFO "DS3000 chip version: %d.%d attached.\n",
+			ds3000_readreg(state, 0x02),
+			ds3000_readreg(state, 0x01));
+
+	memcpy(&state->frontend.ops, &ds3000_ops,
+			sizeof(struct dvb_frontend_ops));
+	state->frontend.demodulator_priv = state;
+	return &state->frontend;
+
+error3:
+	kfree(state);
+error2:
+	return NULL;
+}
+EXPORT_SYMBOL(ds3000_attach);
+
+static int ds3000_set_property(struct dvb_frontend *fe,
+	struct dtv_property *tvp)
+{
+	dprintk("%s(..)\n", __func__);
+	return 0;
+}
+
+static int ds3000_get_property(struct dvb_frontend *fe,
+	struct dtv_property *tvp)
+{
+	dprintk("%s(..)\n", __func__);
+	return 0;
+}
+
+static int ds3000_tune(struct dvb_frontend *fe,
+				struct dvb_frontend_parameters *p)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+	int ret = 0, retune, i;
+	u8 status, mlpf, mlpf_new, mlpf_max, mlpf_min, nlpf;
+	u16 value, ndiv;
+	u32 f3db;
+
+	dprintk("%s() ", __func__);
+
+	/* Load the firmware if required */
+	ret = ds3000_firmware_ondemand(fe);
+	if (ret != 0) {
+		printk(KERN_ERR "%s: Unable initialise the firmware\n",
+								__func__);
+		return ret;
+	}
+
+	state->dnxt.delivery = c->modulation;
+	state->dnxt.frequency = c->frequency;
+	state->dnxt.rolloff = 2; /* fixme */
+	state->dnxt.fec = c->fec_inner;
+
+	ret = ds3000_set_inversion(state, p->inversion);
+	if (ret !=  0)
+		return ret;
+
+	ret = ds3000_set_symbolrate(state, c->symbol_rate);
+	if (ret !=  0)
+		return ret;
+
+	/* discard the 'current' tuning parameters and prepare to tune */
+	ds3000_clone_params(fe);
+
+	retune = 1;	/* try 1 times */
+	dprintk("%s:   retune = %d\n", __func__, retune);
+	dprintk("%s:   frequency   = %d\n", __func__, state->dcur.frequency);
+	dprintk("%s:   symbol_rate = %d\n", __func__, state->dcur.symbol_rate);
+	dprintk("%s:   FEC	 = %d \n", __func__,
+		state->dcur.fec);
+	dprintk("%s:   Inversion   = %d\n", __func__, state->dcur.inversion);
+
+	do {
+		/* Reset status register */
+		status = 0;
+		/* Tune */
+		/* TS2020 init */
+		ds3000_tuner_writereg(state, 0x42, 0x73);
+		ds3000_tuner_writereg(state, 0x05, 0x01);
+		ds3000_tuner_writereg(state, 0x62, 0xf5);
+		/* unknown */
+		ds3000_tuner_writereg(state, 0x07, 0x02);
+		ds3000_tuner_writereg(state, 0x10, 0x00);
+		ds3000_tuner_writereg(state, 0x60, 0x79);
+		ds3000_tuner_writereg(state, 0x08, 0x01);
+		ds3000_tuner_writereg(state, 0x00, 0x01);
+		/* calculate and set freq divider */
+		if (state->dcur.frequency < 1146000) {
+			ds3000_tuner_writereg(state, 0x10, 0x11);
+			ndiv = ((state->dcur.frequency * (6 + 8) * 4) +
+					(DS3000_XTAL_FREQ / 2)) /
+					DS3000_XTAL_FREQ - 1024;
+		} else {
+			ds3000_tuner_writereg(state, 0x10, 0x01);
+			ndiv = ((state->dcur.frequency * (6 + 8) * 2) +
+					(DS3000_XTAL_FREQ / 2)) /
+					DS3000_XTAL_FREQ - 1024;
+		}
+
+		ds3000_tuner_writereg(state, 0x01, (ndiv & 0x0f00) >> 8);
+		ds3000_tuner_writereg(state, 0x02, ndiv & 0x00ff);
+
+		/* set pll */
+		ds3000_tuner_writereg(state, 0x03, 0x06);
+		ds3000_tuner_writereg(state, 0x51, 0x0f);
+		ds3000_tuner_writereg(state, 0x51, 0x1f);
+		ds3000_tuner_writereg(state, 0x50, 0x10);
+		ds3000_tuner_writereg(state, 0x50, 0x00);
+		msleep(5);
+
+		/* unknown */
+		ds3000_tuner_writereg(state, 0x51, 0x17);
+		ds3000_tuner_writereg(state, 0x51, 0x1f);
+		ds3000_tuner_writereg(state, 0x50, 0x08);
+		ds3000_tuner_writereg(state, 0x50, 0x00);
+		msleep(5);
+
+		value = ds3000_tuner_readreg(state, 0x3d);
+		value &= 0x0f;
+		if ((value > 4) && (value < 15)) {
+			value -= 3;
+			if (value < 4)
+				value = 4;
+			value = ((value << 3) | 0x01) & 0x79;
+		}
+
+		ds3000_tuner_writereg(state, 0x60, value);
+		ds3000_tuner_writereg(state, 0x51, 0x17);
+		ds3000_tuner_writereg(state, 0x51, 0x1f);
+		ds3000_tuner_writereg(state, 0x50, 0x08);
+		ds3000_tuner_writereg(state, 0x50, 0x00);
+
+		/* set low-pass filter period */
+		ds3000_tuner_writereg(state, 0x04, 0x2e);
+		ds3000_tuner_writereg(state, 0x51, 0x1b);
+		ds3000_tuner_writereg(state, 0x51, 0x1f);
+		ds3000_tuner_writereg(state, 0x50, 0x04);
+		ds3000_tuner_writereg(state, 0x50, 0x00);
+		msleep(5);
+
+		f3db = ((state->dcur.symbol_rate / 1000) << 2) / 5 + 2000;
+		if ((state->dcur.symbol_rate / 1000) < 5000)
+			f3db += 3000;
+		if (f3db < 7000)
+			f3db = 7000;
+		if (f3db > 40000)
+			f3db = 40000;
+
+		/* set low-pass filter baseband */
+		value = ds3000_tuner_readreg(state, 0x26);
+		mlpf = 0x2e * 207 / ((value << 1) + 151);
+		mlpf_max = mlpf * 135 / 100;
+		mlpf_min = mlpf * 78 / 100;
+		if (mlpf_max > 63)
+			mlpf_max = 63;
+
+		/* rounded to the closest integer */
+		nlpf = ((mlpf * f3db * 1000) + (2766 * DS3000_XTAL_FREQ / 2))
+				/ (2766 * DS3000_XTAL_FREQ);
+		if (nlpf > 23)
+			nlpf = 23;
+		if (nlpf < 1)
+			nlpf = 1;
+
+		/* rounded to the closest integer */
+		mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) +
+				(1000 * f3db / 2)) / (1000 * f3db);
+
+		if (mlpf_new < mlpf_min) {
+			nlpf++;
+			mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) +
+					(1000 * f3db / 2)) / (1000 * f3db);
+		}
+
+		if (mlpf_new > mlpf_max)
+			mlpf_new = mlpf_max;
+
+		ds3000_tuner_writereg(state, 0x04, mlpf_new);
+		ds3000_tuner_writereg(state, 0x06, nlpf);
+		ds3000_tuner_writereg(state, 0x51, 0x1b);
+		ds3000_tuner_writereg(state, 0x51, 0x1f);
+		ds3000_tuner_writereg(state, 0x50, 0x04);
+		ds3000_tuner_writereg(state, 0x50, 0x00);
+		msleep(5);
+
+		/* unknown */
+		ds3000_tuner_writereg(state, 0x51, 0x1e);
+		ds3000_tuner_writereg(state, 0x51, 0x1f);
+		ds3000_tuner_writereg(state, 0x50, 0x01);
+		ds3000_tuner_writereg(state, 0x50, 0x00);
+		msleep(60);
+
+		/* ds3000 global reset */
+		ds3000_writereg(state, 0x07, 0x80);
+		ds3000_writereg(state, 0x07, 0x00);
+		/* ds3000 build-in uC reset */
+		ds3000_writereg(state, 0xb2, 0x01);
+		/* ds3000 software reset */
+		ds3000_writereg(state, 0x00, 0x01);
+
+		switch (c->delivery_system) {
+		case SYS_DVBS:
+			/* initialise the demod in DVB-S mode */
+			for (i = 0; i < sizeof(ds3000_dvbs_init_tab); i += 2)
+				ds3000_writereg(state,
+					ds3000_dvbs_init_tab[i],
+					ds3000_dvbs_init_tab[i + 1]);
+			value = ds3000_readreg(state, 0xfe);
+			value &= 0xc0;
+			value |= 0x1b;
+			ds3000_writereg(state, 0xfe, value);
+			break;
+		case SYS_DVBS2:
+			/* initialise the demod in DVB-S2 mode */
+			for (i = 0; i < sizeof(ds3000_dvbs2_init_tab); i += 2)
+				ds3000_writereg(state,
+					ds3000_dvbs2_init_tab[i],
+					ds3000_dvbs2_init_tab[i + 1]);
+			ds3000_writereg(state, 0xfe, 0x54);
+			break;
+		default:
+			return 1;
+		}
+
+		/* enable 27MHz clock output */
+		ds3000_writereg(state, 0x29, 0x80);
+		/* enable ac coupling */
+		ds3000_writereg(state, 0x25, 0x8a);
+
+		/* enhance symbol rate performance */
+		if ((state->dcur.symbol_rate / 1000) <= 5000) {
+			value = 29777 / (state->dcur.symbol_rate / 1000) + 1;
+			if (value % 2 != 0)
+				value++;
+			ds3000_writereg(state, 0xc3, 0x0d);
+			ds3000_writereg(state, 0xc8, value);
+			ds3000_writereg(state, 0xc4, 0x10);
+			ds3000_writereg(state, 0xc7, 0x0e);
+		} else if ((state->dcur.symbol_rate / 1000) <= 10000) {
+			value = 92166 / (state->dcur.symbol_rate / 1000) + 1;
+			if (value % 2 != 0)
+				value++;
+			ds3000_writereg(state, 0xc3, 0x07);
+			ds3000_writereg(state, 0xc8, value);
+			ds3000_writereg(state, 0xc4, 0x09);
+			ds3000_writereg(state, 0xc7, 0x12);
+		} else if ((state->dcur.symbol_rate / 1000) <= 20000) {
+			value = 64516 / (state->dcur.symbol_rate / 1000) + 1;
+			ds3000_writereg(state, 0xc3, value);
+			ds3000_writereg(state, 0xc8, 0x0e);
+			ds3000_writereg(state, 0xc4, 0x07);
+			ds3000_writereg(state, 0xc7, 0x18);
+		} else {
+			value = 129032 / (state->dcur.symbol_rate / 1000) + 1;
+			ds3000_writereg(state, 0xc3, value);
+			ds3000_writereg(state, 0xc8, 0x0a);
+			ds3000_writereg(state, 0xc4, 0x05);
+			ds3000_writereg(state, 0xc7, 0x24);
+		}
+
+		/* normalized symbol rate rounded to the closest integer */
+		value = (((state->dcur.symbol_rate / 1000) << 16) +
+				(DS3000_SAMPLE_RATE / 2)) / DS3000_SAMPLE_RATE;
+		ds3000_writereg(state, 0x61, value & 0x00ff);
+		ds3000_writereg(state, 0x62, (value & 0xff00) >> 8);
+
+		/* co-channel interference cancellation disabled */
+		ds3000_writereg(state, 0x56, 0x00);
+
+		/* equalizer disabled */
+		ds3000_writereg(state, 0x76, 0x00);
+
+		/*ds3000_writereg(state, 0x08, 0x03);
+		ds3000_writereg(state, 0xfd, 0x22);
+		ds3000_writereg(state, 0x08, 0x07);
+		ds3000_writereg(state, 0xfd, 0x42);
+		ds3000_writereg(state, 0x08, 0x07);*/
+
+		/* ds3000 out of software reset */
+		ds3000_writereg(state, 0x00, 0x00);
+		/* start ds3000 build-in uC */
+		ds3000_writereg(state, 0xb2, 0x00);
+
+		/* TODO: calculate and set carrier offset */
+
+		/* wait before retrying */
+		for (i = 0; i < 30 ; i++) {
+			if (ds3000_is_tuned(fe)) {
+				dprintk("%s: Tuned\n", __func__);
+				ds3000_dump_registers(fe);
+				goto tuned;
+			}
+			msleep(1);
+		}
+
+		dprintk("%s: Not tuned\n", __func__);
+		ds3000_dump_registers(fe);
+
+	} while (--retune);
+
+tuned:
+	return ret;
+}
+
+static enum dvbfe_algo ds3000_get_algo(struct dvb_frontend *fe)
+{
+	dprintk("%s()\n", __func__);
+	return DVBFE_ALGO_SW;
+}
+
+/*
+ * Initialise or wake up device
+ *
+ * Power config will reset and load initial firmware if required
+ */
+static int ds3000_initfe(struct dvb_frontend *fe)
+{
+	dprintk("%s()\n", __func__);
+	return 0;
+}
+
+/* Put device to sleep */
+static int ds3000_sleep(struct dvb_frontend *fe)
+{
+	dprintk("%s()\n", __func__);
+	return 0;
+}
+
+static struct dvb_frontend_ops ds3000_ops = {
+
+	.info = {
+		.name = "Montage Technology DS3000/TS2020",
+		.type = FE_QPSK,
+		.frequency_min = 950000,
+		.frequency_max = 2150000,
+		.frequency_stepsize = 1011, /* kHz for QPSK frontends */
+		.frequency_tolerance = 5000,
+		.symbol_rate_min = 1000000,
+		.symbol_rate_max = 45000000,
+		.caps = FE_CAN_INVERSION_AUTO |
+			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+			FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
+			FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+			FE_CAN_2G_MODULATION |
+			FE_CAN_QPSK | FE_CAN_RECOVER
+	},
+
+	.release = ds3000_release,
+
+	.init = ds3000_initfe,
+	.sleep = ds3000_sleep,
+	.read_status = ds3000_read_status,
+	.read_ber = ds3000_read_ber,
+	.read_signal_strength = ds3000_read_signal_strength,
+	.read_snr = ds3000_read_snr,
+	.read_ucblocks = ds3000_read_ucblocks,
+	.set_tone = ds3000_set_tone,
+	.diseqc_send_master_cmd = ds3000_send_diseqc_msg,
+	.diseqc_send_burst = ds3000_diseqc_send_burst,
+	.get_frontend_algo = ds3000_get_algo,
+
+	.set_property = ds3000_set_property,
+	.get_property = ds3000_get_property,
+	.set_frontend = ds3000_tune,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
+
+MODULE_DESCRIPTION("DVB Frontend module for Montage Technology "
+			"DS3000/TS2020 hardware");
+MODULE_AUTHOR("Konstantin Dimitrov");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/ds3000.h b/drivers/media/dvb/frontends/ds3000.h
new file mode 100644
index 0000000..67f6703
--- /dev/null
+++ b/drivers/media/dvb/frontends/ds3000.h
@@ -0,0 +1,45 @@
+/*
+    Montage Technology DS3000/TS2020 - DVBS/S2 Satellite demod/tuner driver
+    Copyright (C) 2009 Konstantin Dimitrov <kosio.dimitrov@gmail.com>
+
+    Copyright (C) 2009 TurboSight.com
+
+    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.
+*/
+
+#ifndef DS3000_H
+#define DS3000_H
+
+#include <linux/dvb/frontend.h>
+
+struct ds3000_config {
+	/* the demodulator's i2c address */
+	u8 demod_address;
+};
+
+#if defined(CONFIG_DVB_DS3000) || \
+			(defined(CONFIG_DVB_DS3000_MODULE) && defined(MODULE))
+extern struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
+					struct i2c_adapter *i2c);
+#else
+static inline
+struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
+					struct i2c_adapter *i2c)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif /* CONFIG_DVB_DS3000 */
+#endif /* DS3000_H */
diff --git a/drivers/media/dvb/frontends/ec100.c b/drivers/media/dvb/frontends/ec100.c
new file mode 100644
index 0000000..2414dc6
--- /dev/null
+++ b/drivers/media/dvb/frontends/ec100.c
@@ -0,0 +1,335 @@
+/*
+ * E3C EC100 demodulator driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ *
+ *    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.
+ *
+ */
+
+#include "dvb_frontend.h"
+#include "ec100_priv.h"
+#include "ec100.h"
+
+int ec100_debug;
+module_param_named(debug, ec100_debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+struct ec100_state {
+	struct i2c_adapter *i2c;
+	struct dvb_frontend frontend;
+	struct ec100_config config;
+
+	u16 ber;
+};
+
+/* write single register */
+static int ec100_write_reg(struct ec100_state *state, u8 reg, u8 val)
+{
+	u8 buf[2] = {reg, val};
+	struct i2c_msg msg = {
+		.addr = state->config.demod_address,
+		.flags = 0,
+		.len = 2,
+		.buf = buf};
+
+	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
+		warn("I2C write failed reg:%02x", reg);
+		return -EREMOTEIO;
+	}
+	return 0;
+}
+
+/* read single register */
+static int ec100_read_reg(struct ec100_state *state, u8 reg, u8 *val)
+{
+	struct i2c_msg msg[2] = {
+		{
+			.addr = state->config.demod_address,
+			.flags = 0,
+			.len = 1,
+			.buf = &reg
+		}, {
+			.addr = state->config.demod_address,
+			.flags = I2C_M_RD,
+			.len = 1,
+			.buf = val
+		}
+	};
+
+	if (i2c_transfer(state->i2c, msg, 2) != 2) {
+		warn("I2C read failed reg:%02x", reg);
+		return -EREMOTEIO;
+	}
+	return 0;
+}
+
+static int ec100_set_frontend(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *params)
+{
+	struct ec100_state *state = fe->demodulator_priv;
+	int ret;
+	u8 tmp, tmp2;
+
+	deb_info("%s: freq:%d bw:%d\n", __func__, params->frequency,
+		params->u.ofdm.bandwidth);
+
+	/* program tuner */
+	if (fe->ops.tuner_ops.set_params)
+		fe->ops.tuner_ops.set_params(fe, params);
+
+	ret = ec100_write_reg(state, 0x04, 0x06);
+	if (ret)
+		goto error;
+	ret = ec100_write_reg(state, 0x67, 0x58);
+	if (ret)
+		goto error;
+	ret = ec100_write_reg(state, 0x05, 0x18);
+	if (ret)
+		goto error;
+
+	/* reg/bw |   6  |   7  |   8
+	   -------+------+------+------
+	   A 0x1b | 0xa1 | 0xe7 | 0x2c
+	   A 0x1c | 0x55 | 0x63 | 0x72
+	   -------+------+------+------
+	   B 0x1b | 0xb7 | 0x00 | 0x49
+	   B 0x1c | 0x55 | 0x64 | 0x72 */
+
+	switch (params->u.ofdm.bandwidth) {
+	case BANDWIDTH_6_MHZ:
+		tmp = 0xb7;
+		tmp2 = 0x55;
+		break;
+	case BANDWIDTH_7_MHZ:
+		tmp = 0x00;
+		tmp2 = 0x64;
+		break;
+	case BANDWIDTH_8_MHZ:
+	default:
+		tmp = 0x49;
+		tmp2 = 0x72;
+	}
+
+	ret = ec100_write_reg(state, 0x1b, tmp);
+	if (ret)
+		goto error;
+	ret = ec100_write_reg(state, 0x1c, tmp2);
+	if (ret)
+		goto error;
+
+	ret = ec100_write_reg(state, 0x0c, 0xbb); /* if freq */
+	if (ret)
+		goto error;
+	ret = ec100_write_reg(state, 0x0d, 0x31); /* if freq */
+	if (ret)
+		goto error;
+
+	ret = ec100_write_reg(state, 0x08, 0x24);
+	if (ret)
+		goto error;
+
+	ret = ec100_write_reg(state, 0x00, 0x00); /* go */
+	if (ret)
+		goto error;
+	ret = ec100_write_reg(state, 0x00, 0x20); /* go */
+	if (ret)
+		goto error;
+
+	return ret;
+error:
+	deb_info("%s: failed:%d\n", __func__, ret);
+	return ret;
+}
+
+static int ec100_get_tune_settings(struct dvb_frontend *fe,
+	struct dvb_frontend_tune_settings *fesettings)
+{
+	fesettings->min_delay_ms = 300;
+	fesettings->step_size = 0;
+	fesettings->max_drift = 0;
+
+	return 0;
+}
+
+static int ec100_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+	struct ec100_state *state = fe->demodulator_priv;
+	int ret;
+	u8 tmp;
+	*status = 0;
+
+	ret = ec100_read_reg(state, 0x42, &tmp);
+	if (ret)
+		goto error;
+
+	if (tmp & 0x80) {
+		/* bit7 set - have lock */
+		*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
+			FE_HAS_SYNC | FE_HAS_LOCK;
+	} else {
+		ret = ec100_read_reg(state, 0x01, &tmp);
+		if (ret)
+			goto error;
+
+		if (tmp & 0x10) {
+			/* bit4 set - have signal */
+			*status |= FE_HAS_SIGNAL;
+			if (!(tmp & 0x01)) {
+				/* bit0 clear - have ~valid signal */
+				*status |= FE_HAS_CARRIER |  FE_HAS_VITERBI;
+			}
+		}
+	}
+
+	return ret;
+error:
+	deb_info("%s: failed:%d\n", __func__, ret);
+	return ret;
+}
+
+static int ec100_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+	struct ec100_state *state = fe->demodulator_priv;
+	int ret;
+	u8 tmp, tmp2;
+	u16 ber2;
+
+	*ber = 0;
+
+	ret = ec100_read_reg(state, 0x65, &tmp);
+	if (ret)
+		goto error;
+	ret = ec100_read_reg(state, 0x66, &tmp2);
+	if (ret)
+		goto error;
+
+	ber2 = (tmp2 << 8) | tmp;
+
+	/* if counter overflow or clear */
+	if (ber2 < state->ber)
+		*ber = ber2;
+	else
+		*ber = ber2 - state->ber;
+
+	state->ber = ber2;
+
+	return ret;
+error:
+	deb_info("%s: failed:%d\n", __func__, ret);
+	return ret;
+}
+
+static int ec100_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+	struct ec100_state *state = fe->demodulator_priv;
+	int ret;
+	u8 tmp;
+
+	ret = ec100_read_reg(state, 0x24, &tmp);
+	if (ret) {
+		*strength = 0;
+		goto error;
+	}
+
+	*strength = ((tmp << 8) | tmp);
+
+	return ret;
+error:
+	deb_info("%s: failed:%d\n", __func__, ret);
+	return ret;
+}
+
+static int ec100_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	*snr = 0;
+	return 0;
+}
+
+static int ec100_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+	*ucblocks = 0;
+	return 0;
+}
+
+static void ec100_release(struct dvb_frontend *fe)
+{
+	struct ec100_state *state = fe->demodulator_priv;
+	kfree(state);
+}
+
+static struct dvb_frontend_ops ec100_ops;
+
+struct dvb_frontend *ec100_attach(const struct ec100_config *config,
+	struct i2c_adapter *i2c)
+{
+	int ret;
+	struct ec100_state *state = NULL;
+	u8 tmp;
+
+	/* allocate memory for the internal state */
+	state = kzalloc(sizeof(struct ec100_state), GFP_KERNEL);
+	if (state == NULL)
+		goto error;
+
+	/* setup the state */
+	state->i2c = i2c;
+	memcpy(&state->config, config, sizeof(struct ec100_config));
+
+	/* check if the demod is there */
+	ret = ec100_read_reg(state, 0x33, &tmp);
+	if (ret || tmp != 0x0b)
+		goto error;
+
+	/* create dvb_frontend */
+	memcpy(&state->frontend.ops, &ec100_ops,
+		sizeof(struct dvb_frontend_ops));
+	state->frontend.demodulator_priv = state;
+
+	return &state->frontend;
+error:
+	kfree(state);
+	return NULL;
+}
+EXPORT_SYMBOL(ec100_attach);
+
+static struct dvb_frontend_ops ec100_ops = {
+	.info = {
+		.name = "E3C EC100 DVB-T",
+		.type = FE_OFDM,
+		.caps =
+			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+			FE_CAN_QPSK | FE_CAN_QAM_16 |
+			FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+			FE_CAN_TRANSMISSION_MODE_AUTO |
+			FE_CAN_GUARD_INTERVAL_AUTO |
+			FE_CAN_HIERARCHY_AUTO |
+			FE_CAN_MUTE_TS
+	},
+
+	.release = ec100_release,
+	.set_frontend = ec100_set_frontend,
+	.get_tune_settings = ec100_get_tune_settings,
+	.read_status = ec100_read_status,
+	.read_ber = ec100_read_ber,
+	.read_signal_strength = ec100_read_signal_strength,
+	.read_snr = ec100_read_snr,
+	.read_ucblocks = ec100_read_ucblocks,
+};
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("E3C EC100 DVB-T demodulator driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/ec100.h b/drivers/media/dvb/frontends/ec100.h
new file mode 100644
index 0000000..ee8e524
--- /dev/null
+++ b/drivers/media/dvb/frontends/ec100.h
@@ -0,0 +1,46 @@
+/*
+ * E3C EC100 demodulator driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ *
+ *    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.
+ *
+ */
+
+#ifndef EC100_H
+#define EC100_H
+
+#include <linux/dvb/frontend.h>
+
+struct ec100_config {
+	/* demodulator's I2C address */
+	u8 demod_address;
+};
+
+
+#if defined(CONFIG_DVB_EC100) || \
+	(defined(CONFIG_DVB_EC100_MODULE) && defined(MODULE))
+extern struct dvb_frontend *ec100_attach(const struct ec100_config *config,
+	struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *ec100_attach(
+	const struct ec100_config *config, struct i2c_adapter *i2c)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif
+
+#endif /* EC100_H */
diff --git a/drivers/media/dvb/frontends/ec100_priv.h b/drivers/media/dvb/frontends/ec100_priv.h
new file mode 100644
index 0000000..5c99014
--- /dev/null
+++ b/drivers/media/dvb/frontends/ec100_priv.h
@@ -0,0 +1,39 @@
+/*
+ * E3C EC100 demodulator driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ *
+ *    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.
+ *
+ */
+
+#ifndef EC100_PRIV
+#define EC100_PRIV
+
+#define LOG_PREFIX "ec100"
+
+#define dprintk(var, level, args...) \
+	do { if ((var & level)) printk(args); } while (0)
+
+#define deb_info(args...) dprintk(ec100_debug, 0x01, args)
+
+#undef err
+#define err(f, arg...)  printk(KERN_ERR     LOG_PREFIX": " f "\n" , ## arg)
+#undef info
+#define info(f, arg...) printk(KERN_INFO    LOG_PREFIX": " f "\n" , ## arg)
+#undef warn
+#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
+
+#endif /* EC100_PRIV */
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c
index 056387b..43971e6 100644
--- a/drivers/media/dvb/frontends/lgdt330x.c
+++ b/drivers/media/dvb/frontends/lgdt330x.c
@@ -479,7 +479,7 @@
 	switch (state->current_modulation) {
 	case QAM_256:
 	case QAM_64:
-		/* Need to undestand why there are 3 lock levels here */
+		/* Need to understand why there are 3 lock levels here */
 		if ((buf[0] & 0x07) == 0x07)
 			*status |= FE_HAS_CARRIER;
 		break;
@@ -520,7 +520,7 @@
 	switch (state->current_modulation) {
 	case QAM_256:
 	case QAM_64:
-		/* Need to undestand why there are 3 lock levels here */
+		/* Need to understand why there are 3 lock levels here */
 		if ((buf[0] & 0x07) == 0x07)
 			*status |= FE_HAS_CARRIER;
 		else
diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c
index fb30115..0e2f61a 100644
--- a/drivers/media/dvb/frontends/s5h1409.c
+++ b/drivers/media/dvb/frontends/s5h1409.c
@@ -44,7 +44,15 @@
 	int if_freq;
 
 	u32 is_qam_locked;
-	u32 qam_state;
+
+	/* QAM tuning state goes through the following state transitions */
+#define QAM_STATE_UNTUNED 0
+#define QAM_STATE_TUNING_STARTED 1
+#define QAM_STATE_INTERLEAVE_SET 2
+#define QAM_STATE_QAM_OPTIMIZED_L1 3
+#define QAM_STATE_QAM_OPTIMIZED_L2 4
+#define QAM_STATE_QAM_OPTIMIZED_L3 5
+	u8  qam_state;
 };
 
 static int debug;
@@ -347,7 +355,7 @@
 	s5h1409_writereg(state, 0xf5, 0);
 	s5h1409_writereg(state, 0xf5, 1);
 	state->is_qam_locked = 0;
-	state->qam_state = 0;
+	state->qam_state = QAM_STATE_UNTUNED;
 	return 0;
 }
 
@@ -474,6 +482,59 @@
 	struct s5h1409_state *state = fe->demodulator_priv;
 	u16 reg;
 
+	if (state->qam_state < QAM_STATE_INTERLEAVE_SET) {
+		/* We should not perform amhum optimization until
+		   the interleave mode has been configured */
+		return;
+	}
+
+	if (state->qam_state == QAM_STATE_QAM_OPTIMIZED_L3) {
+		/* We've already reached the maximum optimization level, so
+		   dont bother banging on the status registers */
+		return;
+	}
+
+	/* QAM EQ lock check */
+	reg = s5h1409_readreg(state, 0xf0);
+
+	if ((reg >> 13) & 0x1) {
+		reg &= 0xff;
+
+		s5h1409_writereg(state, 0x96, 0x000c);
+		if (reg < 0x68) {
+			if (state->qam_state < QAM_STATE_QAM_OPTIMIZED_L3) {
+				dprintk("%s() setting QAM state to OPT_L3\n",
+					__func__);
+				s5h1409_writereg(state, 0x93, 0x3130);
+				s5h1409_writereg(state, 0x9e, 0x2836);
+				state->qam_state = QAM_STATE_QAM_OPTIMIZED_L3;
+			}
+		} else {
+			if (state->qam_state < QAM_STATE_QAM_OPTIMIZED_L2) {
+				dprintk("%s() setting QAM state to OPT_L2\n",
+					__func__);
+				s5h1409_writereg(state, 0x93, 0x3332);
+				s5h1409_writereg(state, 0x9e, 0x2c37);
+				state->qam_state = QAM_STATE_QAM_OPTIMIZED_L2;
+			}
+		}
+
+	} else {
+		if (state->qam_state < QAM_STATE_QAM_OPTIMIZED_L1) {
+			dprintk("%s() setting QAM state to OPT_L1\n", __func__);
+			s5h1409_writereg(state, 0x96, 0x0008);
+			s5h1409_writereg(state, 0x93, 0x3332);
+			s5h1409_writereg(state, 0x9e, 0x2c37);
+			state->qam_state = QAM_STATE_QAM_OPTIMIZED_L1;
+		}
+	}
+}
+
+static void s5h1409_set_qam_amhum_mode_legacy(struct dvb_frontend *fe)
+{
+	struct s5h1409_state *state = fe->demodulator_priv;
+	u16 reg;
+
 	if (state->is_qam_locked)
 		return;
 
@@ -506,6 +567,44 @@
 	struct s5h1409_state *state = fe->demodulator_priv;
 	u16 reg, reg1, reg2;
 
+	if (state->qam_state >= QAM_STATE_INTERLEAVE_SET) {
+		/* We've done the optimization already */
+		return;
+	}
+
+	reg = s5h1409_readreg(state, 0xf1);
+
+	/* Master lock */
+	if ((reg >> 15) & 0x1) {
+		if (state->qam_state == QAM_STATE_UNTUNED ||
+		    state->qam_state == QAM_STATE_TUNING_STARTED) {
+			dprintk("%s() setting QAM state to INTERLEAVE_SET\n",
+				__func__);
+			reg1 = s5h1409_readreg(state, 0xb2);
+			reg2 = s5h1409_readreg(state, 0xad);
+
+			s5h1409_writereg(state, 0x96, 0x0020);
+			s5h1409_writereg(state, 0xad,
+				(((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff)));
+			state->qam_state = QAM_STATE_INTERLEAVE_SET;
+		}
+	} else {
+		if (state->qam_state == QAM_STATE_UNTUNED) {
+			dprintk("%s() setting QAM state to TUNING_STARTED\n",
+				__func__);
+			s5h1409_writereg(state, 0x96, 0x08);
+			s5h1409_writereg(state, 0xab,
+				s5h1409_readreg(state, 0xab) | 0x1001);
+			state->qam_state = QAM_STATE_TUNING_STARTED;
+		}
+	}
+}
+
+static void s5h1409_set_qam_interleave_mode_legacy(struct dvb_frontend *fe)
+{
+	struct s5h1409_state *state = fe->demodulator_priv;
+	u16 reg, reg1, reg2;
+
 	reg = s5h1409_readreg(state, 0xf1);
 
 	/* Master lock */
@@ -553,16 +652,24 @@
 			fe->ops.i2c_gate_ctrl(fe, 0);
 	}
 
-	/* Optimize the demod for QAM */
-	if (p->u.vsb.modulation != VSB_8) {
-		s5h1409_set_qam_amhum_mode(fe);
-		s5h1409_set_qam_interleave_mode(fe);
-	}
-
 	/* Issue a reset to the demod so it knows to resync against the
 	   newly tuned frequency */
 	s5h1409_softreset(fe);
 
+	/* Optimize the demod for QAM */
+	if (state->current_modulation != VSB_8) {
+		/* This almost certainly applies to all boards, but for now
+		   only do it for the HVR-1600.  Once the other boards are
+		   tested, the "legacy" versions can just go away */
+		if (state->config->hvr1600_opt == S5H1409_HVR1600_OPTIMIZE) {
+			s5h1409_set_qam_interleave_mode(fe);
+			s5h1409_set_qam_amhum_mode(fe);
+		} else {
+			s5h1409_set_qam_amhum_mode_legacy(fe);
+			s5h1409_set_qam_interleave_mode_legacy(fe);
+		}
+	}
+
 	return 0;
 }
 
@@ -614,6 +721,21 @@
 	/* The datasheet says that after initialisation, VSB is default */
 	state->current_modulation = VSB_8;
 
+	/* Optimize for the HVR-1600 if appropriate.  Note that some of these
+	   may get folded into the generic case after testing with other
+	   devices */
+	if (state->config->hvr1600_opt == S5H1409_HVR1600_OPTIMIZE) {
+		/* VSB AGC REF */
+		s5h1409_writereg(state, 0x09, 0x0050);
+
+		/* Unknown but Windows driver does it... */
+		s5h1409_writereg(state, 0x21, 0x0001);
+		s5h1409_writereg(state, 0x50, 0x030e);
+
+		/* QAM AGC REF */
+		s5h1409_writereg(state, 0x82, 0x0800);
+	}
+
 	if (state->config->output_mode == S5H1409_SERIAL_OUTPUT)
 		s5h1409_writereg(state, 0xab,
 			s5h1409_readreg(state, 0xab) | 0x100); /* Serial */
@@ -641,6 +763,17 @@
 
 	*status = 0;
 
+	/* Optimize the demod for QAM */
+	if (state->current_modulation != VSB_8) {
+		/* This almost certainly applies to all boards, but for now
+		   only do it for the HVR-1600.  Once the other boards are
+		   tested, the "legacy" versions can just go away */
+		if (state->config->hvr1600_opt == S5H1409_HVR1600_OPTIMIZE) {
+			s5h1409_set_qam_interleave_mode(fe);
+			s5h1409_set_qam_amhum_mode(fe);
+		}
+	}
+
 	/* Get the demodulator status */
 	reg = s5h1409_readreg(state, 0xf1);
 	if (reg & 0x1000)
diff --git a/drivers/media/dvb/frontends/s5h1409.h b/drivers/media/dvb/frontends/s5h1409.h
index 070d974..91f2ebd 100644
--- a/drivers/media/dvb/frontends/s5h1409.h
+++ b/drivers/media/dvb/frontends/s5h1409.h
@@ -57,6 +57,13 @@
 #define S5H1409_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK    2
 #define S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3
 	u16 mpeg_timing;
+
+	/* HVR-1600 optimizations (to better work with MXL5005s)
+	   Note: some of these are likely to be folded into the generic driver
+	   after being regression tested with other boards */
+#define S5H1409_HVR1600_NOOPTIMIZE 0
+#define S5H1409_HVR1600_OPTIMIZE   1
+	u8 hvr1600_opt;
 };
 
 #if defined(CONFIG_DVB_S5H1409) || (defined(CONFIG_DVB_S5H1409_MODULE) \
diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c
index a04c782..1570669 100644
--- a/drivers/media/dvb/frontends/stb0899_drv.c
+++ b/drivers/media/dvb/frontends/stb0899_drv.c
@@ -1571,7 +1571,7 @@
  * stb0899_track
  * periodically check the signal level against a specified
  * threshold level and perform derotator centering.
- * called once we have a lock from a succesful search
+ * called once we have a lock from a successful search
  * event.
  *
  * Will be called periodically called to maintain the
diff --git a/drivers/media/dvb/frontends/stb6100_proc.h b/drivers/media/dvb/frontends/stb6100_proc.h
new file mode 100644
index 0000000..112163a
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb6100_proc.h
@@ -0,0 +1,138 @@
+/*
+	STB6100 Silicon Tuner wrapper
+	Copyright (C)2009 Igor M. Liplianin (liplianin@me.by)
+
+	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.
+*/
+
+static int stb6100_get_freq(struct dvb_frontend *fe, u32 *frequency)
+{
+	struct dvb_frontend_ops	*frontend_ops = NULL;
+	struct dvb_tuner_ops	*tuner_ops = NULL;
+	struct tuner_state	state;
+	int err = 0;
+
+	if (&fe->ops)
+		frontend_ops = &fe->ops;
+	if (&frontend_ops->tuner_ops)
+		tuner_ops = &frontend_ops->tuner_ops;
+	if (tuner_ops->get_state) {
+		if (frontend_ops->i2c_gate_ctrl)
+			frontend_ops->i2c_gate_ctrl(fe, 1);
+
+		err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &state);
+		if (err < 0) {
+			printk(KERN_ERR "%s: Invalid parameter\n", __func__);
+			return err;
+		}
+
+		if (frontend_ops->i2c_gate_ctrl)
+			frontend_ops->i2c_gate_ctrl(fe, 0);
+
+		*frequency = state.frequency;
+	}
+
+	return 0;
+}
+
+static int stb6100_set_freq(struct dvb_frontend *fe, u32 frequency)
+{
+	struct dvb_frontend_ops	*frontend_ops = NULL;
+	struct dvb_tuner_ops	*tuner_ops = NULL;
+	struct tuner_state	state;
+	int err = 0;
+
+	state.frequency = frequency;
+	if (&fe->ops)
+		frontend_ops = &fe->ops;
+	if (&frontend_ops->tuner_ops)
+		tuner_ops = &frontend_ops->tuner_ops;
+	if (tuner_ops->set_state) {
+		if (frontend_ops->i2c_gate_ctrl)
+			frontend_ops->i2c_gate_ctrl(fe, 1);
+
+		err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &state);
+		if (err < 0) {
+			printk(KERN_ERR "%s: Invalid parameter\n", __func__);
+			return err;
+		}
+
+		if (frontend_ops->i2c_gate_ctrl)
+			frontend_ops->i2c_gate_ctrl(fe, 0);
+
+	}
+
+	return 0;
+}
+
+static int stb6100_get_bandw(struct dvb_frontend *fe, u32 *bandwidth)
+{
+	struct dvb_frontend_ops	*frontend_ops = NULL;
+	struct dvb_tuner_ops	*tuner_ops = NULL;
+	struct tuner_state	state;
+	int err = 0;
+
+	if (&fe->ops)
+		frontend_ops = &fe->ops;
+	if (&frontend_ops->tuner_ops)
+		tuner_ops = &frontend_ops->tuner_ops;
+	if (tuner_ops->get_state) {
+		if (frontend_ops->i2c_gate_ctrl)
+			frontend_ops->i2c_gate_ctrl(fe, 1);
+
+		err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &state);
+		if (err < 0) {
+			printk(KERN_ERR "%s: Invalid parameter\n", __func__);
+			return err;
+		}
+
+		if (frontend_ops->i2c_gate_ctrl)
+			frontend_ops->i2c_gate_ctrl(fe, 0);
+
+		*bandwidth = state.bandwidth;
+	}
+
+	return 0;
+}
+
+static int stb6100_set_bandw(struct dvb_frontend *fe, u32 bandwidth)
+{
+	struct dvb_frontend_ops	*frontend_ops = NULL;
+	struct dvb_tuner_ops	*tuner_ops = NULL;
+	struct tuner_state	state;
+	int err = 0;
+
+	state.bandwidth = bandwidth;
+	if (&fe->ops)
+		frontend_ops = &fe->ops;
+	if (&frontend_ops->tuner_ops)
+		tuner_ops = &frontend_ops->tuner_ops;
+	if (tuner_ops->set_state) {
+		if (frontend_ops->i2c_gate_ctrl)
+			frontend_ops->i2c_gate_ctrl(fe, 1);
+
+		err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &state);
+		if (err < 0) {
+			printk(KERN_ERR "%s: Invalid parameter\n", __func__);
+			return err;
+		}
+
+		if (frontend_ops->i2c_gate_ctrl)
+			frontend_ops->i2c_gate_ctrl(fe, 0);
+
+	}
+
+	return 0;
+}
diff --git a/drivers/media/dvb/frontends/stv0900.h b/drivers/media/dvb/frontends/stv0900.h
index bf4e9b6..29c3fa8 100644
--- a/drivers/media/dvb/frontends/stv0900.h
+++ b/drivers/media/dvb/frontends/stv0900.h
@@ -36,6 +36,7 @@
 
 struct stv0900_config {
 	u8 demod_address;
+	u8 demod_mode;
 	u32 xtal;
 	u8 clkmode;/* 0 for CLKI,  2 for XTALI */
 
@@ -48,6 +49,8 @@
 	u8 tun2_maddress;
 	u8 tun1_adc;/* 1 for stv6110, 2 for stb6100 */
 	u8 tun2_adc;
+	/* Set device param to start dma */
+	int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
 };
 
 #if defined(CONFIG_DVB_STV0900) || (defined(CONFIG_DVB_STV0900_MODULE) \
diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c
index 3bde332..df49ea0 100644
--- a/drivers/media/dvb/frontends/stv0900_core.c
+++ b/drivers/media/dvb/frontends/stv0900_core.c
@@ -34,7 +34,7 @@
 #include "stv0900_priv.h"
 #include "stv0900_init.h"
 
-static int stvdebug = 1;
+int stvdebug = 1;
 module_param_named(debug, stvdebug, int, 0644);
 
 /* internal params node */
@@ -105,7 +105,8 @@
 		while (new_node->next_inode != NULL)
 			new_node = new_node->next_inode;
 
-		new_node->next_inode = kmalloc(sizeof(struct stv0900_inode), GFP_KERNEL);
+		new_node->next_inode = kmalloc(sizeof(struct stv0900_inode),
+								GFP_KERNEL);
 		if (new_node->next_inode != NULL)
 			new_node = new_node->next_inode;
 		else
@@ -128,13 +129,13 @@
 		return (a >= (1 << (width - 1))) ? (a - (1 << width)) : a;
 }
 
-void stv0900_write_reg(struct stv0900_internal *i_params, u16 reg_addr,
+void stv0900_write_reg(struct stv0900_internal *intp, u16 reg_addr,
 								u8 reg_data)
 {
 	u8 data[3];
 	int ret;
 	struct i2c_msg i2cmsg = {
-		.addr  = i_params->i2c_addr,
+		.addr  = intp->i2c_addr,
 		.flags = 0,
 		.len   = 3,
 		.buf   = data,
@@ -144,33 +145,33 @@
 	data[1] = LSB(reg_addr);
 	data[2] = reg_data;
 
-	ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1);
+	ret = i2c_transfer(intp->i2c_adap, &i2cmsg, 1);
 	if (ret != 1)
-		dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret);
+		dprintk("%s: i2c error %d\n", __func__, ret);
 }
 
-u8 stv0900_read_reg(struct stv0900_internal *i_params, u16 reg)
+u8 stv0900_read_reg(struct stv0900_internal *intp, u16 reg)
 {
 	int ret;
 	u8 b0[] = { MSB(reg), LSB(reg) };
 	u8 buf = 0;
 	struct i2c_msg msg[] = {
 		{
-			.addr	= i_params->i2c_addr,
+			.addr	= intp->i2c_addr,
 			.flags	= 0,
 			.buf = b0,
 			.len = 2,
 		}, {
-			.addr	= i_params->i2c_addr,
+			.addr	= intp->i2c_addr,
 			.flags	= I2C_M_RD,
 			.buf = &buf,
 			.len = 1,
 		},
 	};
 
-	ret = i2c_transfer(i_params->i2c_adap, msg, 2);
+	ret = i2c_transfer(intp->i2c_adap, msg, 2);
 	if (ret != 2)
-		dprintk(KERN_ERR "%s: i2c error %d, reg[0x%02x]\n",
+		dprintk("%s: i2c error %d, reg[0x%02x]\n",
 				__func__, ret, reg);
 
 	return buf;
@@ -190,169 +191,165 @@
 	(*pos) = (i - 1);
 }
 
-void stv0900_write_bits(struct stv0900_internal *i_params, u32 label, u8 val)
+void stv0900_write_bits(struct stv0900_internal *intp, u32 label, u8 val)
 {
 	u8 reg, mask, pos;
 
-	reg = stv0900_read_reg(i_params, (label >> 16) & 0xffff);
+	reg = stv0900_read_reg(intp, (label >> 16) & 0xffff);
 	extract_mask_pos(label, &mask, &pos);
 
 	val = mask & (val << pos);
 
 	reg = (reg & (~mask)) | val;
-	stv0900_write_reg(i_params, (label >> 16) & 0xffff, reg);
+	stv0900_write_reg(intp, (label >> 16) & 0xffff, reg);
 
 }
 
-u8 stv0900_get_bits(struct stv0900_internal *i_params, u32 label)
+u8 stv0900_get_bits(struct stv0900_internal *intp, u32 label)
 {
 	u8 val = 0xff;
 	u8 mask, pos;
 
 	extract_mask_pos(label, &mask, &pos);
 
-	val = stv0900_read_reg(i_params, label >> 16);
+	val = stv0900_read_reg(intp, label >> 16);
 	val = (val & mask) >> pos;
 
 	return val;
 }
 
-enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *i_params)
+enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *intp)
 {
 	s32 i;
-	enum fe_stv0900_error error;
 
-	if (i_params != NULL) {
-		i_params->chip_id = stv0900_read_reg(i_params, R0900_MID);
-		if (i_params->errs == STV0900_NO_ERROR) {
-			/*Startup sequence*/
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5c);
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5c);
-			stv0900_write_reg(i_params, R0900_P1_TNRCFG, 0x6c);
-			stv0900_write_reg(i_params, R0900_P2_TNRCFG, 0x6f);
-			stv0900_write_reg(i_params, R0900_P1_I2CRPT, 0x20);
-			stv0900_write_reg(i_params, R0900_P2_I2CRPT, 0x20);
-			stv0900_write_reg(i_params, R0900_NCOARSE, 0x13);
-			msleep(3);
-			stv0900_write_reg(i_params, R0900_I2CCFG, 0x08);
+	if (intp == NULL)
+		return STV0900_INVALID_HANDLE;
 
-			switch (i_params->clkmode) {
-			case 0:
-			case 2:
-				stv0900_write_reg(i_params, R0900_SYNTCTRL, 0x20
-						| i_params->clkmode);
-				break;
-			default:
-				/* preserve SELOSCI bit */
-				i = 0x02 & stv0900_read_reg(i_params, R0900_SYNTCTRL);
-				stv0900_write_reg(i_params, R0900_SYNTCTRL, 0x20 | i);
-				break;
-			}
+	intp->chip_id = stv0900_read_reg(intp, R0900_MID);
 
-			msleep(3);
-			for (i = 0; i < 182; i++)
-				stv0900_write_reg(i_params, STV0900_InitVal[i][0], STV0900_InitVal[i][1]);
+	if (intp->errs != STV0900_NO_ERROR)
+		return intp->errs;
 
-			if (stv0900_read_reg(i_params, R0900_MID) >= 0x20) {
-				stv0900_write_reg(i_params, R0900_TSGENERAL, 0x0c);
-				for (i = 0; i < 32; i++)
-					stv0900_write_reg(i_params, STV0900_Cut20_AddOnVal[i][0], STV0900_Cut20_AddOnVal[i][1]);
-			}
+	/*Startup sequence*/
+	stv0900_write_reg(intp, R0900_P1_DMDISTATE, 0x5c);
+	stv0900_write_reg(intp, R0900_P2_DMDISTATE, 0x5c);
+	msleep(3);
+	stv0900_write_reg(intp, R0900_P1_TNRCFG, 0x6c);
+	stv0900_write_reg(intp, R0900_P2_TNRCFG, 0x6f);
+	stv0900_write_reg(intp, R0900_P1_I2CRPT, 0x20);
+	stv0900_write_reg(intp, R0900_P2_I2CRPT, 0x20);
+	stv0900_write_reg(intp, R0900_NCOARSE, 0x13);
+	msleep(3);
+	stv0900_write_reg(intp, R0900_I2CCFG, 0x08);
 
-			stv0900_write_reg(i_params, R0900_P1_FSPYCFG, 0x6c);
-			stv0900_write_reg(i_params, R0900_P2_FSPYCFG, 0x6c);
-			stv0900_write_reg(i_params, R0900_TSTRES0, 0x80);
-			stv0900_write_reg(i_params, R0900_TSTRES0, 0x00);
-		}
-		error = i_params->errs;
-	} else
-		error = STV0900_INVALID_HANDLE;
+	switch (intp->clkmode) {
+	case 0:
+	case 2:
+		stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20
+				| intp->clkmode);
+		break;
+	default:
+		/* preserve SELOSCI bit */
+		i = 0x02 & stv0900_read_reg(intp, R0900_SYNTCTRL);
+		stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 | i);
+		break;
+	}
 
-	return error;
+	msleep(3);
+	for (i = 0; i < 181; i++)
+		stv0900_write_reg(intp, STV0900_InitVal[i][0],
+				STV0900_InitVal[i][1]);
 
+	if (stv0900_read_reg(intp, R0900_MID) >= 0x20) {
+		stv0900_write_reg(intp, R0900_TSGENERAL, 0x0c);
+		for (i = 0; i < 32; i++)
+			stv0900_write_reg(intp, STV0900_Cut20_AddOnVal[i][0],
+					STV0900_Cut20_AddOnVal[i][1]);
+	}
+
+	stv0900_write_reg(intp, R0900_P1_FSPYCFG, 0x6c);
+	stv0900_write_reg(intp, R0900_P2_FSPYCFG, 0x6c);
+
+	stv0900_write_reg(intp, R0900_P1_PDELCTRL2, 0x01);
+	stv0900_write_reg(intp, R0900_P2_PDELCTRL2, 0x21);
+
+	stv0900_write_reg(intp, R0900_P1_PDELCTRL3, 0x20);
+	stv0900_write_reg(intp, R0900_P2_PDELCTRL3, 0x20);
+
+	stv0900_write_reg(intp, R0900_TSTRES0, 0x80);
+	stv0900_write_reg(intp, R0900_TSTRES0, 0x00);
+
+	return STV0900_NO_ERROR;
 }
 
-u32 stv0900_get_mclk_freq(struct stv0900_internal *i_params, u32 ext_clk)
+u32 stv0900_get_mclk_freq(struct stv0900_internal *intp, u32 ext_clk)
 {
 	u32 mclk = 90000000, div = 0, ad_div = 0;
 
-	div = stv0900_get_bits(i_params, F0900_M_DIV);
-	ad_div = ((stv0900_get_bits(i_params, F0900_SELX1RATIO) == 1) ? 4 : 6);
+	div = stv0900_get_bits(intp, F0900_M_DIV);
+	ad_div = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6);
 
 	mclk = (div + 1) * ext_clk / ad_div;
 
-	dprintk(KERN_INFO "%s: Calculated Mclk = %d\n", __func__, mclk);
+	dprintk("%s: Calculated Mclk = %d\n", __func__, mclk);
 
 	return mclk;
 }
 
-enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *i_params, u32 mclk)
+enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32 mclk)
 {
-	enum fe_stv0900_error error = STV0900_NO_ERROR;
 	u32 m_div, clk_sel;
 
-	dprintk(KERN_INFO "%s: Mclk set to %d, Quartz = %d\n", __func__, mclk,
-			i_params->quartz);
+	dprintk("%s: Mclk set to %d, Quartz = %d\n", __func__, mclk,
+			intp->quartz);
 
-	if (i_params == NULL)
-		error = STV0900_INVALID_HANDLE;
-	else {
-		if (i_params->errs)
-			error = STV0900_I2C_ERROR;
-		else {
-			clk_sel = ((stv0900_get_bits(i_params, F0900_SELX1RATIO) == 1) ? 4 : 6);
-			m_div = ((clk_sel * mclk) / i_params->quartz) - 1;
-			stv0900_write_bits(i_params, F0900_M_DIV, m_div);
-			i_params->mclk = stv0900_get_mclk_freq(i_params,
-							i_params->quartz);
+	if (intp == NULL)
+		return STV0900_INVALID_HANDLE;
 
-			/*Set the DiseqC frequency to 22KHz */
-			/*
-				Formula:
-				DiseqC_TX_Freq= MasterClock/(32*F22TX_Reg)
-				DiseqC_RX_Freq= MasterClock/(32*F22RX_Reg)
-			*/
-			m_div = i_params->mclk / 704000;
-			stv0900_write_reg(i_params, R0900_P1_F22TX, m_div);
-			stv0900_write_reg(i_params, R0900_P1_F22RX, m_div);
+	if (intp->errs)
+		return STV0900_I2C_ERROR;
 
-			stv0900_write_reg(i_params, R0900_P2_F22TX, m_div);
-			stv0900_write_reg(i_params, R0900_P2_F22RX, m_div);
+	clk_sel = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6);
+	m_div = ((clk_sel * mclk) / intp->quartz) - 1;
+	stv0900_write_bits(intp, F0900_M_DIV, m_div);
+	intp->mclk = stv0900_get_mclk_freq(intp,
+					intp->quartz);
 
-			if ((i_params->errs))
-				error = STV0900_I2C_ERROR;
-		}
-	}
+	/*Set the DiseqC frequency to 22KHz */
+	/*
+		Formula:
+		DiseqC_TX_Freq= MasterClock/(32*F22TX_Reg)
+		DiseqC_RX_Freq= MasterClock/(32*F22RX_Reg)
+	*/
+	m_div = intp->mclk / 704000;
+	stv0900_write_reg(intp, R0900_P1_F22TX, m_div);
+	stv0900_write_reg(intp, R0900_P1_F22RX, m_div);
 
-	return error;
+	stv0900_write_reg(intp, R0900_P2_F22TX, m_div);
+	stv0900_write_reg(intp, R0900_P2_F22RX, m_div);
+
+	if ((intp->errs))
+		return STV0900_I2C_ERROR;
+
+	return STV0900_NO_ERROR;
 }
 
-u32 stv0900_get_err_count(struct stv0900_internal *i_params, int cntr,
+u32 stv0900_get_err_count(struct stv0900_internal *intp, int cntr,
 					enum fe_stv0900_demod_num demod)
 {
 	u32 lsb, msb, hsb, err_val;
-	s32 err1field_hsb, err1field_msb, err1field_lsb;
-	s32 err2field_hsb, err2field_msb, err2field_lsb;
-
-	dmd_reg(err1field_hsb, F0900_P1_ERR_CNT12, F0900_P2_ERR_CNT12);
-	dmd_reg(err1field_msb, F0900_P1_ERR_CNT11, F0900_P2_ERR_CNT11);
-	dmd_reg(err1field_lsb, F0900_P1_ERR_CNT10, F0900_P2_ERR_CNT10);
-
-	dmd_reg(err2field_hsb, F0900_P1_ERR_CNT22, F0900_P2_ERR_CNT22);
-	dmd_reg(err2field_msb, F0900_P1_ERR_CNT21, F0900_P2_ERR_CNT21);
-	dmd_reg(err2field_lsb, F0900_P1_ERR_CNT20, F0900_P2_ERR_CNT20);
 
 	switch (cntr) {
 	case 0:
 	default:
-		hsb = stv0900_get_bits(i_params, err1field_hsb);
-		msb = stv0900_get_bits(i_params, err1field_msb);
-		lsb = stv0900_get_bits(i_params, err1field_lsb);
+		hsb = stv0900_get_bits(intp, ERR_CNT12);
+		msb = stv0900_get_bits(intp, ERR_CNT11);
+		lsb = stv0900_get_bits(intp, ERR_CNT10);
 		break;
 	case 1:
-		hsb = stv0900_get_bits(i_params, err2field_hsb);
-		msb = stv0900_get_bits(i_params, err2field_msb);
-		lsb = stv0900_get_bits(i_params, err2field_lsb);
+		hsb = stv0900_get_bits(intp, ERR_CNT22);
+		msb = stv0900_get_bits(intp, ERR_CNT21);
+		lsb = stv0900_get_bits(intp, ERR_CNT20);
 		break;
 	}
 
@@ -364,26 +361,22 @@
 static int stv0900_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
 
-	u32 fi2c;
-
-	dmd_reg(fi2c, F0900_P1_I2CT_ON, F0900_P2_I2CT_ON);
-
-	stv0900_write_bits(i_params, fi2c, enable);
+	stv0900_write_bits(intp, I2CT_ON, enable);
 
 	return 0;
 }
 
-static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params,
+static void stv0900_set_ts_parallel_serial(struct stv0900_internal *intp,
 					enum fe_stv0900_clock_type path1_ts,
 					enum fe_stv0900_clock_type path2_ts)
 {
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
-	if (i_params->chip_id >= 0x20) {
+	if (intp->chip_id >= 0x20) {
 		switch (path1_ts) {
 		case STV0900_PARALLEL_PUNCT_CLOCK:
 		case STV0900_DVBCI_CLOCK:
@@ -391,20 +384,20 @@
 			case STV0900_SERIAL_PUNCT_CLOCK:
 			case STV0900_SERIAL_CONT_CLOCK:
 			default:
-				stv0900_write_reg(i_params, R0900_TSGENERAL,
+				stv0900_write_reg(intp, R0900_TSGENERAL,
 							0x00);
 				break;
 			case STV0900_PARALLEL_PUNCT_CLOCK:
 			case STV0900_DVBCI_CLOCK:
-				stv0900_write_reg(i_params, R0900_TSGENERAL,
+				stv0900_write_reg(intp, R0900_TSGENERAL,
 							0x06);
-				stv0900_write_bits(i_params,
+				stv0900_write_bits(intp,
 						F0900_P1_TSFIFO_MANSPEED, 3);
-				stv0900_write_bits(i_params,
+				stv0900_write_bits(intp,
 						F0900_P2_TSFIFO_MANSPEED, 0);
-				stv0900_write_reg(i_params,
+				stv0900_write_reg(intp,
 						R0900_P1_TSSPEED, 0x14);
-				stv0900_write_reg(i_params,
+				stv0900_write_reg(intp,
 						R0900_P2_TSSPEED, 0x28);
 				break;
 			}
@@ -416,14 +409,14 @@
 			case STV0900_SERIAL_PUNCT_CLOCK:
 			case STV0900_SERIAL_CONT_CLOCK:
 			default:
-				stv0900_write_reg(i_params,
+				stv0900_write_reg(intp,
 						R0900_TSGENERAL, 0x0C);
 				break;
 			case STV0900_PARALLEL_PUNCT_CLOCK:
 			case STV0900_DVBCI_CLOCK:
-				stv0900_write_reg(i_params,
+				stv0900_write_reg(intp,
 						R0900_TSGENERAL, 0x0A);
-				dprintk(KERN_INFO "%s: 0x0a\n", __func__);
+				dprintk("%s: 0x0a\n", __func__);
 				break;
 			}
 			break;
@@ -436,20 +429,20 @@
 			case STV0900_SERIAL_PUNCT_CLOCK:
 			case STV0900_SERIAL_CONT_CLOCK:
 			default:
-				stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+				stv0900_write_reg(intp, R0900_TSGENERAL1X,
 							0x10);
 				break;
 			case STV0900_PARALLEL_PUNCT_CLOCK:
 			case STV0900_DVBCI_CLOCK:
-				stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+				stv0900_write_reg(intp, R0900_TSGENERAL1X,
 							0x16);
-				stv0900_write_bits(i_params,
+				stv0900_write_bits(intp,
 						F0900_P1_TSFIFO_MANSPEED, 3);
-				stv0900_write_bits(i_params,
+				stv0900_write_bits(intp,
 						F0900_P2_TSFIFO_MANSPEED, 0);
-				stv0900_write_reg(i_params, R0900_P1_TSSPEED,
+				stv0900_write_reg(intp, R0900_P1_TSSPEED,
 							0x14);
-				stv0900_write_reg(i_params, R0900_P2_TSSPEED,
+				stv0900_write_reg(intp, R0900_P2_TSSPEED,
 							0x28);
 				break;
 			}
@@ -462,14 +455,14 @@
 			case STV0900_SERIAL_PUNCT_CLOCK:
 			case STV0900_SERIAL_CONT_CLOCK:
 			default:
-				stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+				stv0900_write_reg(intp, R0900_TSGENERAL1X,
 							0x14);
 				break;
 			case STV0900_PARALLEL_PUNCT_CLOCK:
 			case STV0900_DVBCI_CLOCK:
-				stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+				stv0900_write_reg(intp, R0900_TSGENERAL1X,
 							0x12);
-				dprintk(KERN_INFO "%s: 0x12\n", __func__);
+				dprintk("%s: 0x12\n", __func__);
 				break;
 			}
 
@@ -479,20 +472,20 @@
 
 	switch (path1_ts) {
 	case STV0900_PARALLEL_PUNCT_CLOCK:
-		stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x00);
-		stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x00);
+		stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x00);
+		stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x00);
 		break;
 	case STV0900_DVBCI_CLOCK:
-		stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x00);
-		stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x01);
+		stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x00);
+		stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x01);
 		break;
 	case STV0900_SERIAL_PUNCT_CLOCK:
-		stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x01);
-		stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x00);
+		stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x01);
+		stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x00);
 		break;
 	case STV0900_SERIAL_CONT_CLOCK:
-		stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x01);
-		stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x01);
+		stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x01);
+		stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x01);
 		break;
 	default:
 		break;
@@ -500,29 +493,29 @@
 
 	switch (path2_ts) {
 	case STV0900_PARALLEL_PUNCT_CLOCK:
-		stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x00);
-		stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x00);
+		stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x00);
+		stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x00);
 		break;
 	case STV0900_DVBCI_CLOCK:
-		stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x00);
-		stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x01);
+		stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x00);
+		stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x01);
 		break;
 	case STV0900_SERIAL_PUNCT_CLOCK:
-		stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x01);
-		stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x00);
+		stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x01);
+		stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x00);
 		break;
 	case STV0900_SERIAL_CONT_CLOCK:
-		stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x01);
-		stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x01);
+		stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x01);
+		stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x01);
 		break;
 	default:
 		break;
 	}
 
-	stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 1);
-	stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 0);
-	stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 1);
-	stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 0);
+	stv0900_write_bits(intp, F0900_P2_RST_HWARE, 1);
+	stv0900_write_bits(intp, F0900_P2_RST_HWARE, 0);
+	stv0900_write_bits(intp, F0900_P1_RST_HWARE, 1);
+	stv0900_write_bits(intp, F0900_P1_RST_HWARE, 0);
 }
 
 void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency,
@@ -574,7 +567,7 @@
 	}
 }
 
-static s32 stv0900_get_rf_level(struct stv0900_internal *i_params,
+static s32 stv0900_get_rf_level(struct stv0900_internal *intp,
 				const struct stv0900_table *lookup,
 				enum fe_stv0900_demod_num demod)
 {
@@ -584,45 +577,41 @@
 		i,
 		rf_lvl = 0;
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
-	if ((lookup != NULL) && lookup->size) {
-		switch (demod) {
-		case STV0900_DEMOD_1:
-		default:
-			agc_gain = MAKEWORD(stv0900_get_bits(i_params, F0900_P1_AGCIQ_VALUE1),
-						stv0900_get_bits(i_params, F0900_P1_AGCIQ_VALUE0));
-			break;
-		case STV0900_DEMOD_2:
-			agc_gain = MAKEWORD(stv0900_get_bits(i_params, F0900_P2_AGCIQ_VALUE1),
-						stv0900_get_bits(i_params, F0900_P2_AGCIQ_VALUE0));
-			break;
+	if ((lookup == NULL) || (lookup->size <= 0))
+		return 0;
+
+	agc_gain = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1),
+				stv0900_get_bits(intp, AGCIQ_VALUE0));
+
+	imin = 0;
+	imax = lookup->size - 1;
+	if (INRANGE(lookup->table[imin].regval, agc_gain,
+					lookup->table[imax].regval)) {
+		while ((imax - imin) > 1) {
+			i = (imax + imin) >> 1;
+
+			if (INRANGE(lookup->table[imin].regval,
+					agc_gain,
+					lookup->table[i].regval))
+				imax = i;
+			else
+				imin = i;
 		}
 
-		imin = 0;
-		imax = lookup->size - 1;
-		if (INRANGE(lookup->table[imin].regval, agc_gain, lookup->table[imax].regval)) {
-			while ((imax - imin) > 1) {
-				i = (imax + imin) >> 1;
+		rf_lvl = (s32)agc_gain - lookup->table[imin].regval;
+		rf_lvl *= (lookup->table[imax].realval -
+				lookup->table[imin].realval);
+		rf_lvl /= (lookup->table[imax].regval -
+				lookup->table[imin].regval);
+		rf_lvl += lookup->table[imin].realval;
+	} else if (agc_gain > lookup->table[0].regval)
+		rf_lvl = 5;
+	else if (agc_gain < lookup->table[lookup->size-1].regval)
+		rf_lvl = -100;
 
-				if (INRANGE(lookup->table[imin].regval, agc_gain, lookup->table[i].regval))
-					imax = i;
-				else
-					imin = i;
-			}
-
-			rf_lvl = (((s32)agc_gain - lookup->table[imin].regval)
-					* (lookup->table[imax].realval - lookup->table[imin].realval)
-					/ (lookup->table[imax].regval - lookup->table[imin].regval))
-					+ lookup->table[imin].realval;
-		} else if (agc_gain > lookup->table[0].regval)
-			rf_lvl = 5;
-		else if (agc_gain < lookup->table[lookup->size-1].regval)
-			rf_lvl = -100;
-
-	}
-
-	dprintk(KERN_INFO "%s: RFLevel = %d\n", __func__, rf_lvl);
+	dprintk("%s: RFLevel = %d\n", __func__, rf_lvl);
 
 	return rf_lvl;
 }
@@ -634,50 +623,51 @@
 	s32 rflevel = stv0900_get_rf_level(internal, &stv0900_rf,
 								state->demod);
 
-	*strength = (rflevel + 100) * (16383 / 105);
+	rflevel = (rflevel + 100) * (65535 / 70);
+	if (rflevel < 0)
+		rflevel = 0;
+
+	if (rflevel > 65535)
+		rflevel = 65535;
+
+	*strength = rflevel;
 
 	return 0;
 }
 
-
 static s32 stv0900_carr_get_quality(struct dvb_frontend *fe,
 					const struct stv0900_table *lookup)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
 
-	s32 c_n = -100,
-		regval, imin, imax,
+	s32	c_n = -100,
+		regval,
+		imin,
+		imax,
 		i,
-		lock_flag_field,
 		noise_field1,
 		noise_field0;
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
-	dmd_reg(lock_flag_field, F0900_P1_LOCK_DEFINITIF,
-					F0900_P2_LOCK_DEFINITIF);
 	if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) {
-		dmd_reg(noise_field1, F0900_P1_NOSPLHT_NORMED1,
-					F0900_P2_NOSPLHT_NORMED1);
-		dmd_reg(noise_field0, F0900_P1_NOSPLHT_NORMED0,
-					F0900_P2_NOSPLHT_NORMED0);
+		noise_field1 = NOSPLHT_NORMED1;
+		noise_field0 = NOSPLHT_NORMED0;
 	} else {
-		dmd_reg(noise_field1, F0900_P1_NOSDATAT_NORMED1,
-					F0900_P2_NOSDATAT_NORMED1);
-		dmd_reg(noise_field0, F0900_P1_NOSDATAT_NORMED0,
-					F0900_P2_NOSDATAT_NORMED0);
+		noise_field1 = NOSDATAT_NORMED1;
+		noise_field0 = NOSDATAT_NORMED0;
 	}
 
-	if (stv0900_get_bits(i_params, lock_flag_field)) {
+	if (stv0900_get_bits(intp, LOCK_DEFINITIF)) {
 		if ((lookup != NULL) && lookup->size) {
 			regval = 0;
 			msleep(5);
 			for (i = 0; i < 16; i++) {
-				regval += MAKEWORD(stv0900_get_bits(i_params,
+				regval += MAKEWORD(stv0900_get_bits(intp,
 								noise_field1),
-						stv0900_get_bits(i_params,
+						stv0900_get_bits(intp,
 								noise_field0));
 				msleep(1);
 			}
@@ -715,10 +705,9 @@
 static int stv0900_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
 	u8 err_val1, err_val0;
-	s32 err_field1, err_field0;
 	u32 header_err_val = 0;
 
 	*ucblocks = 0x0;
@@ -726,24 +715,14 @@
 		/* DVB-S2 delineator errors count */
 
 		/* retreiving number for errnous headers */
-		dmd_reg(err_field0, R0900_P1_BBFCRCKO0,
-					R0900_P2_BBFCRCKO0);
-		dmd_reg(err_field1, R0900_P1_BBFCRCKO1,
-					R0900_P2_BBFCRCKO1);
-
-		err_val1 = stv0900_read_reg(i_params, err_field1);
-		err_val0 = stv0900_read_reg(i_params, err_field0);
-		header_err_val = (err_val1<<8) | err_val0;
+		err_val1 = stv0900_read_reg(intp, BBFCRCKO1);
+		err_val0 = stv0900_read_reg(intp, BBFCRCKO0);
+		header_err_val = (err_val1 << 8) | err_val0;
 
 		/* retreiving number for errnous packets */
-		dmd_reg(err_field0, R0900_P1_UPCRCKO0,
-					R0900_P2_UPCRCKO0);
-		dmd_reg(err_field1, R0900_P1_UPCRCKO1,
-					R0900_P2_UPCRCKO1);
-
-		err_val1 = stv0900_read_reg(i_params, err_field1);
-		err_val0 = stv0900_read_reg(i_params, err_field0);
-		*ucblocks = (err_val1<<8) | err_val0;
+		err_val1 = stv0900_read_reg(intp, UPCRCKO1);
+		err_val0 = stv0900_read_reg(intp, UPCRCKO0);
+		*ucblocks = (err_val1 << 8) | err_val0;
 		*ucblocks += header_err_val;
 	}
 
@@ -752,33 +731,27 @@
 
 static int stv0900_read_snr(struct dvb_frontend *fe, u16 *snr)
 {
-	*snr = stv0900_carr_get_quality(fe,
+	s32 snrlcl = stv0900_carr_get_quality(fe,
 			(const struct stv0900_table *)&stv0900_s2_cn);
-	*snr += 30;
-	*snr *= (16383 / 1030);
+	snrlcl = (snrlcl + 30) * 384;
+	if (snrlcl < 0)
+		snrlcl = 0;
+
+	if (snrlcl > 65535)
+		snrlcl = 65535;
+
+	*snr = snrlcl;
 
 	return 0;
 }
 
-static u32 stv0900_get_ber(struct stv0900_internal *i_params,
+static u32 stv0900_get_ber(struct stv0900_internal *intp,
 				enum fe_stv0900_demod_num demod)
 {
 	u32 ber = 10000000, i;
-	s32 dmd_state_reg;
 	s32 demod_state;
-	s32 vstatus_reg;
-	s32 prvit_field;
-	s32 pdel_status_reg;
-	s32 pdel_lock_field;
 
-	dmd_reg(dmd_state_reg, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
-	dmd_reg(vstatus_reg, R0900_P1_VSTATUSVIT, R0900_P2_VSTATUSVIT);
-	dmd_reg(prvit_field, F0900_P1_PRFVIT, F0900_P2_PRFVIT);
-	dmd_reg(pdel_status_reg, R0900_P1_PDELSTATUS1, R0900_P2_PDELSTATUS1);
-	dmd_reg(pdel_lock_field, F0900_P1_PKTDELIN_LOCK,
-				F0900_P2_PKTDELIN_LOCK);
-
-	demod_state = stv0900_get_bits(i_params, dmd_state_reg);
+	demod_state = stv0900_get_bits(intp, HEADER_MODE);
 
 	switch (demod_state) {
 	case STV0900_SEARCH:
@@ -790,11 +763,11 @@
 		ber = 0;
 		for (i = 0; i < 5; i++) {
 			msleep(5);
-			ber += stv0900_get_err_count(i_params, 0, demod);
+			ber += stv0900_get_err_count(intp, 0, demod);
 		}
 
 		ber /= 5;
-		if (stv0900_get_bits(i_params, prvit_field)) {
+		if (stv0900_get_bits(intp, PRFVIT)) {
 			ber *= 9766;
 			ber = ber >> 13;
 		}
@@ -804,11 +777,11 @@
 		ber = 0;
 		for (i = 0; i < 5; i++) {
 			msleep(5);
-			ber += stv0900_get_err_count(i_params, 0, demod);
+			ber += stv0900_get_err_count(intp, 0, demod);
 		}
 
 		ber /= 5;
-		if (stv0900_get_bits(i_params, pdel_lock_field)) {
+		if (stv0900_get_bits(intp, PKTDELIN_LOCK)) {
 			ber *= 9766;
 			ber = ber >> 13;
 		}
@@ -829,20 +802,16 @@
 	return 0;
 }
 
-int stv0900_get_demod_lock(struct stv0900_internal *i_params,
+int stv0900_get_demod_lock(struct stv0900_internal *intp,
 			enum fe_stv0900_demod_num demod, s32 time_out)
 {
 	s32 timer = 0,
-		lock = 0,
-		header_field,
-		lock_field;
+		lock = 0;
 
 	enum fe_stv0900_search_state	dmd_state;
 
-	dmd_reg(header_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
-	dmd_reg(lock_field, F0900_P1_LOCK_DEFINITIF, F0900_P2_LOCK_DEFINITIF);
 	while ((timer < time_out) && (lock == 0)) {
-		dmd_state = stv0900_get_bits(i_params, header_field);
+		dmd_state = stv0900_get_bits(intp, HEADER_MODE);
 		dprintk("Demod State = %d\n", dmd_state);
 		switch (dmd_state) {
 		case STV0900_SEARCH:
@@ -852,7 +821,7 @@
 			break;
 		case STV0900_DVBS2_FOUND:
 		case STV0900_DVBS_FOUND:
-			lock = stv0900_get_bits(i_params, lock_field);
+			lock = stv0900_get_bits(intp, LOCK_DEFINITIF);
 			break;
 		}
 
@@ -870,56 +839,40 @@
 	return lock;
 }
 
-void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params,
+void stv0900_stop_all_s2_modcod(struct stv0900_internal *intp,
 				enum fe_stv0900_demod_num demod)
 {
 	s32 regflist,
 	i;
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
-	dmd_reg(regflist, R0900_P1_MODCODLST0, R0900_P2_MODCODLST0);
+	regflist = MODCODLST0;
 
 	for (i = 0; i < 16; i++)
-		stv0900_write_reg(i_params, regflist + i, 0xff);
+		stv0900_write_reg(intp, regflist + i, 0xff);
 }
 
-void stv0900_activate_s2_modcode(struct stv0900_internal *i_params,
+void stv0900_activate_s2_modcod(struct stv0900_internal *intp,
 				enum fe_stv0900_demod_num demod)
 {
 	u32 matype,
-	mod_code,
-	fmod,
-	reg_index,
-	field_index;
+		mod_code,
+		fmod,
+		reg_index,
+		field_index;
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
-	if (i_params->chip_id <= 0x11) {
+	if (intp->chip_id <= 0x11) {
 		msleep(5);
 
-		switch (demod) {
-		case STV0900_DEMOD_1:
-		default:
-			mod_code = stv0900_read_reg(i_params,
-							R0900_P1_PLHMODCOD);
-			matype = mod_code & 0x3;
-			mod_code = (mod_code & 0x7f) >> 2;
+		mod_code = stv0900_read_reg(intp, PLHMODCOD);
+		matype = mod_code & 0x3;
+		mod_code = (mod_code & 0x7f) >> 2;
 
-			reg_index = R0900_P1_MODCODLSTF - mod_code / 2;
-			field_index = mod_code % 2;
-			break;
-		case STV0900_DEMOD_2:
-			mod_code = stv0900_read_reg(i_params,
-							R0900_P2_PLHMODCOD);
-			matype = mod_code & 0x3;
-			mod_code = (mod_code & 0x7f) >> 2;
-
-			reg_index = R0900_P2_MODCODLSTF - mod_code / 2;
-			field_index = mod_code % 2;
-			break;
-		}
-
+		reg_index = MODCODLSTF - mod_code / 2;
+		field_index = mod_code % 2;
 
 		switch (matype) {
 		case 0:
@@ -938,70 +891,41 @@
 		}
 
 		if ((INRANGE(STV0900_QPSK_12, mod_code, STV0900_8PSK_910))
-							&& (matype <= 1)) {
+						&& (matype <= 1)) {
 			if (field_index == 0)
-				stv0900_write_reg(i_params, reg_index,
+				stv0900_write_reg(intp, reg_index,
 							0xf0 | fmod);
 			else
-				stv0900_write_reg(i_params, reg_index,
+				stv0900_write_reg(intp, reg_index,
 							(fmod << 4) | 0xf);
 		}
-	} else if (i_params->chip_id >= 0x12) {
-		switch (demod) {
-		case STV0900_DEMOD_1:
-		default:
-			for (reg_index = 0; reg_index < 7; reg_index++)
-				stv0900_write_reg(i_params, R0900_P1_MODCODLST0 + reg_index, 0xff);
 
-			stv0900_write_reg(i_params, R0900_P1_MODCODLSTE, 0xff);
-			stv0900_write_reg(i_params, R0900_P1_MODCODLSTF, 0xcf);
-			for (reg_index = 0; reg_index < 8; reg_index++)
-				stv0900_write_reg(i_params, R0900_P1_MODCODLST7 + reg_index, 0xcc);
+	} else if (intp->chip_id >= 0x12) {
+		for (reg_index = 0; reg_index < 7; reg_index++)
+			stv0900_write_reg(intp, MODCODLST0 + reg_index, 0xff);
 
-			break;
-		case STV0900_DEMOD_2:
-			for (reg_index = 0; reg_index < 7; reg_index++)
-				stv0900_write_reg(i_params, R0900_P2_MODCODLST0 + reg_index, 0xff);
+		stv0900_write_reg(intp, MODCODLSTE, 0xff);
+		stv0900_write_reg(intp, MODCODLSTF, 0xcf);
+		for (reg_index = 0; reg_index < 8; reg_index++)
+			stv0900_write_reg(intp, MODCODLST7 + reg_index, 0xcc);
 
-			stv0900_write_reg(i_params, R0900_P2_MODCODLSTE, 0xff);
-			stv0900_write_reg(i_params, R0900_P2_MODCODLSTF, 0xcf);
-			for (reg_index = 0; reg_index < 8; reg_index++)
-				stv0900_write_reg(i_params, R0900_P2_MODCODLST7 + reg_index, 0xcc);
-
-			break;
-		}
 
 	}
 }
 
-void stv0900_activate_s2_modcode_single(struct stv0900_internal *i_params,
+void stv0900_activate_s2_modcod_single(struct stv0900_internal *intp,
 					enum fe_stv0900_demod_num demod)
 {
 	u32 reg_index;
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		stv0900_write_reg(i_params, R0900_P1_MODCODLST0, 0xff);
-		stv0900_write_reg(i_params, R0900_P1_MODCODLST1, 0xf0);
-		stv0900_write_reg(i_params, R0900_P1_MODCODLSTF, 0x0f);
-		for (reg_index = 0; reg_index < 13; reg_index++)
-			stv0900_write_reg(i_params,
-					R0900_P1_MODCODLST2 + reg_index, 0);
+	stv0900_write_reg(intp, MODCODLST0, 0xff);
+	stv0900_write_reg(intp, MODCODLST1, 0xf0);
+	stv0900_write_reg(intp, MODCODLSTF, 0x0f);
+	for (reg_index = 0; reg_index < 13; reg_index++)
+		stv0900_write_reg(intp, MODCODLST2 + reg_index, 0);
 
-		break;
-	case STV0900_DEMOD_2:
-		stv0900_write_reg(i_params, R0900_P2_MODCODLST0, 0xff);
-		stv0900_write_reg(i_params, R0900_P2_MODCODLST1, 0xf0);
-		stv0900_write_reg(i_params, R0900_P2_MODCODLSTF, 0x0f);
-		for (reg_index = 0; reg_index < 13; reg_index++)
-			stv0900_write_reg(i_params,
-					R0900_P2_MODCODLST2 + reg_index, 0);
-
-		break;
-	}
 }
 
 static enum dvbfe_algo stv0900_frontend_algo(struct dvb_frontend *fe)
@@ -1012,7 +936,7 @@
 static int stb0900_set_property(struct dvb_frontend *fe,
 				struct dtv_property *tvp)
 {
-	dprintk(KERN_INFO "%s(..)\n", __func__);
+	dprintk("%s(..)\n", __func__);
 
 	return 0;
 }
@@ -1020,166 +944,123 @@
 static int stb0900_get_property(struct dvb_frontend *fe,
 				struct dtv_property *tvp)
 {
-	dprintk(KERN_INFO "%s(..)\n", __func__);
+	dprintk("%s(..)\n", __func__);
 
 	return 0;
 }
 
-void stv0900_start_search(struct stv0900_internal *i_params,
+void stv0900_start_search(struct stv0900_internal *intp,
 				enum fe_stv0900_demod_num demod)
 {
+	u32 freq;
+	s16 freq_s16 ;
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x1f);
+	stv0900_write_bits(intp, DEMOD_MODE, 0x1f);
+	if (intp->chip_id == 0x10)
+		stv0900_write_reg(intp, CORRELEXP, 0xaa);
 
-		if (i_params->chip_id == 0x10)
-			stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0xaa);
+	if (intp->chip_id < 0x20)
+		stv0900_write_reg(intp, CARHDR, 0x55);
 
-		if (i_params->chip_id < 0x20)
-			stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x55);
-
-		if (i_params->dmd1_symbol_rate <= 5000000) {
-			stv0900_write_reg(i_params, R0900_P1_CARCFG, 0x44);
-			stv0900_write_reg(i_params, R0900_P1_CFRUP1, 0x0f);
-			stv0900_write_reg(i_params, R0900_P1_CFRUP0, 0xff);
-			stv0900_write_reg(i_params, R0900_P1_CFRLOW1, 0xf0);
-			stv0900_write_reg(i_params, R0900_P1_CFRLOW0, 0x00);
-			stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x68);
+	if (intp->chip_id <= 0x20) {
+		if (intp->symbol_rate[0] <= 5000000) {
+			stv0900_write_reg(intp, CARCFG, 0x44);
+			stv0900_write_reg(intp, CFRUP1, 0x0f);
+			stv0900_write_reg(intp, CFRUP0, 0xff);
+			stv0900_write_reg(intp, CFRLOW1, 0xf0);
+			stv0900_write_reg(intp, CFRLOW0, 0x00);
+			stv0900_write_reg(intp, RTCS2, 0x68);
 		} else {
-			stv0900_write_reg(i_params, R0900_P1_CARCFG, 0xc4);
-			stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x44);
+			stv0900_write_reg(intp, CARCFG, 0xc4);
+			stv0900_write_reg(intp, RTCS2, 0x44);
 		}
 
-		stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0);
-		stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0);
+	} else { /*cut 3.0 above*/
+		if (intp->symbol_rate[demod] <= 5000000)
+			stv0900_write_reg(intp, RTCS2, 0x68);
+		else
+			stv0900_write_reg(intp, RTCS2, 0x44);
 
-		if (i_params->chip_id >= 0x20) {
-			stv0900_write_reg(i_params, R0900_P1_EQUALCFG, 0x41);
-			stv0900_write_reg(i_params, R0900_P1_FFECFG, 0x41);
-
-			if ((i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS1) || (i_params->dmd1_srch_standard == STV0900_SEARCH_DSS) || (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH)) {
-				stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x82);
-				stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0);
-			}
-		}
-
-		stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x00);
-		stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0xe0);
-		stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0xc0);
-		stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 0);
-		stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
-		stv0900_write_bits(i_params, F0900_P1_S1S2_SEQUENTIAL, 0);
-		stv0900_write_reg(i_params, R0900_P1_RTC, 0x88);
-		if (i_params->chip_id >= 0x20) {
-			if (i_params->dmd1_symbol_rate < 2000000) {
-				stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x39);
-				stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x40);
-			}
-
-			if (i_params->dmd1_symbol_rate < 10000000) {
-				stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x4c);
-				stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x20);
-			} else {
-				stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x4b);
-				stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x20);
-			}
-
+		stv0900_write_reg(intp, CARCFG, 0x46);
+		if (intp->srch_algo[demod] == STV0900_WARM_START) {
+			freq = 1000 << 16;
+			freq /= (intp->mclk / 1000);
+			freq_s16 = (s16)freq;
 		} else {
-			if (i_params->dmd1_symbol_rate < 10000000)
-				stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xef);
+			freq = (intp->srch_range[demod] / 2000);
+			if (intp->symbol_rate[demod] <= 5000000)
+				freq += 80;
 			else
-				stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed);
+				freq += 600;
+
+			freq = freq << 16;
+			freq /= (intp->mclk / 1000);
+			freq_s16 = (s16)freq;
 		}
 
-		switch (i_params->dmd1_srch_algo) {
-		case STV0900_WARM_START:
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f);
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
-			break;
-		case STV0900_COLD_START:
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f);
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15);
-			break;
-		default:
-			break;
+		stv0900_write_bits(intp, CFR_UP1, MSB(freq_s16));
+		stv0900_write_bits(intp, CFR_UP0, LSB(freq_s16));
+		freq_s16 *= (-1);
+		stv0900_write_bits(intp, CFR_LOW1, MSB(freq_s16));
+		stv0900_write_bits(intp, CFR_LOW0, LSB(freq_s16));
+	}
+
+	stv0900_write_reg(intp, CFRINIT1, 0);
+	stv0900_write_reg(intp, CFRINIT0, 0);
+
+	if (intp->chip_id >= 0x20) {
+		stv0900_write_reg(intp, EQUALCFG, 0x41);
+		stv0900_write_reg(intp, FFECFG, 0x41);
+
+		if ((intp->srch_standard[demod] == STV0900_SEARCH_DVBS1) ||
+			(intp->srch_standard[demod] == STV0900_SEARCH_DSS) ||
+			(intp->srch_standard[demod] == STV0900_AUTO_SEARCH)) {
+			stv0900_write_reg(intp, VITSCALE,
+								0x82);
+			stv0900_write_reg(intp, VAVSRVIT, 0x0);
+		}
+	}
+
+	stv0900_write_reg(intp, SFRSTEP, 0x00);
+	stv0900_write_reg(intp, TMGTHRISE, 0xe0);
+	stv0900_write_reg(intp, TMGTHFALL, 0xc0);
+	stv0900_write_bits(intp, SCAN_ENABLE, 0);
+	stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
+	stv0900_write_bits(intp, S1S2_SEQUENTIAL, 0);
+	stv0900_write_reg(intp, RTC, 0x88);
+	if (intp->chip_id >= 0x20) {
+		if (intp->symbol_rate[demod] < 2000000) {
+			if (intp->chip_id <= 0x20)
+				stv0900_write_reg(intp, CARFREQ, 0x39);
+			else  /*cut 3.0*/
+				stv0900_write_reg(intp, CARFREQ, 0x89);
+
+			stv0900_write_reg(intp, CARHDR, 0x40);
+		} else if (intp->symbol_rate[demod] < 10000000) {
+			stv0900_write_reg(intp, CARFREQ, 0x4c);
+			stv0900_write_reg(intp, CARHDR, 0x20);
+		} else {
+			stv0900_write_reg(intp, CARFREQ, 0x4b);
+			stv0900_write_reg(intp, CARHDR, 0x20);
 		}
 
+	} else {
+		if (intp->symbol_rate[demod] < 10000000)
+			stv0900_write_reg(intp, CARFREQ, 0xef);
+		else
+			stv0900_write_reg(intp, CARFREQ, 0xed);
+	}
+
+	switch (intp->srch_algo[demod]) {
+	case STV0900_WARM_START:
+		stv0900_write_reg(intp, DMDISTATE, 0x1f);
+		stv0900_write_reg(intp, DMDISTATE, 0x18);
 		break;
-	case STV0900_DEMOD_2:
-		stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x1f);
-		if (i_params->chip_id == 0x10)
-			stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0xaa);
-
-		if (i_params->chip_id < 0x20)
-			stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x55);
-
-		if (i_params->dmd2_symbol_rate <= 5000000) {
-			stv0900_write_reg(i_params, R0900_P2_CARCFG, 0x44);
-			stv0900_write_reg(i_params, R0900_P2_CFRUP1, 0x0f);
-			stv0900_write_reg(i_params, R0900_P2_CFRUP0, 0xff);
-			stv0900_write_reg(i_params, R0900_P2_CFRLOW1, 0xf0);
-			stv0900_write_reg(i_params, R0900_P2_CFRLOW0, 0x00);
-			stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x68);
-		} else {
-			stv0900_write_reg(i_params, R0900_P2_CARCFG, 0xc4);
-			stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x44);
-		}
-
-		stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0);
-		stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0);
-
-		if (i_params->chip_id >= 0x20) {
-			stv0900_write_reg(i_params, R0900_P2_EQUALCFG, 0x41);
-			stv0900_write_reg(i_params, R0900_P2_FFECFG, 0x41);
-			if ((i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS1) || (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DSS) || (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH)) {
-				stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x82);
-				stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0);
-			}
-		}
-
-		stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x00);
-		stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0xe0);
-		stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0xc0);
-		stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 0);
-		stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
-		stv0900_write_bits(i_params, F0900_P2_S1S2_SEQUENTIAL, 0);
-		stv0900_write_reg(i_params, R0900_P2_RTC, 0x88);
-		if (i_params->chip_id >= 0x20) {
-			if (i_params->dmd2_symbol_rate < 2000000) {
-				stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x39);
-				stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x40);
-			}
-
-			if (i_params->dmd2_symbol_rate < 10000000) {
-				stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x4c);
-				stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x20);
-			} else {
-				stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x4b);
-				stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x20);
-			}
-
-		} else {
-			if (i_params->dmd2_symbol_rate < 10000000)
-				stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xef);
-			else
-				stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed);
-		}
-
-		switch (i_params->dmd2_srch_algo) {
-		case STV0900_WARM_START:
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f);
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
-			break;
-		case STV0900_COLD_START:
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f);
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15);
-			break;
-		default:
-			break;
-		}
-
+	case STV0900_COLD_START:
+		stv0900_write_reg(intp, DMDISTATE, 0x1f);
+		stv0900_write_reg(intp, DMDISTATE, 0x15);
+		break;
+	default:
 		break;
 	}
 }
@@ -1188,33 +1069,40 @@
 							s32 pilot, u8 chip_id)
 {
 	u8 aclc_value = 0x29;
-	s32	i;
-	const struct stv0900_car_loop_optim *car_loop_s2;
+	s32 i;
+	const struct stv0900_car_loop_optim *cls2, *cllqs2, *cllas2;
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
-	if (chip_id <= 0x12)
-		car_loop_s2 = FE_STV0900_S2CarLoop;
-	else if (chip_id == 0x20)
-		car_loop_s2 = FE_STV0900_S2CarLoopCut20;
-	else
-		car_loop_s2 = FE_STV0900_S2CarLoop;
+	if (chip_id <= 0x12) {
+		cls2 = FE_STV0900_S2CarLoop;
+		cllqs2 = FE_STV0900_S2LowQPCarLoopCut30;
+		cllas2 = FE_STV0900_S2APSKCarLoopCut30;
+	} else if (chip_id == 0x20) {
+		cls2 = FE_STV0900_S2CarLoopCut20;
+		cllqs2 = FE_STV0900_S2LowQPCarLoopCut20;
+		cllas2 = FE_STV0900_S2APSKCarLoopCut20;
+	} else {
+		cls2 = FE_STV0900_S2CarLoopCut30;
+		cllqs2 = FE_STV0900_S2LowQPCarLoopCut30;
+		cllas2 = FE_STV0900_S2APSKCarLoopCut30;
+	}
 
 	if (modcode < STV0900_QPSK_12) {
 		i = 0;
-		while ((i < 3) && (modcode != FE_STV0900_S2LowQPCarLoopCut20[i].modcode))
+		while ((i < 3) && (modcode != cllqs2[i].modcode))
 			i++;
 
 		if (i >= 3)
 			i = 2;
 	} else {
 		i = 0;
-		while ((i < 14) && (modcode != car_loop_s2[i].modcode))
+		while ((i < 14) && (modcode != cls2[i].modcode))
 			i++;
 
 		if (i >= 14) {
 			i = 0;
-			while ((i < 11) && (modcode != FE_STV0900_S2APSKCarLoopCut20[i].modcode))
+			while ((i < 11) && (modcode != cllas2[i].modcode))
 				i++;
 
 			if (i >= 11)
@@ -1225,76 +1113,82 @@
 	if (modcode <= STV0900_QPSK_25) {
 		if (pilot) {
 			if (srate <= 3000000)
-				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_2;
+				aclc_value = cllqs2[i].car_loop_pilots_on_2;
 			else if (srate <= 7000000)
-				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_5;
+				aclc_value = cllqs2[i].car_loop_pilots_on_5;
 			else if (srate <= 15000000)
-				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_10;
+				aclc_value = cllqs2[i].car_loop_pilots_on_10;
 			else if (srate <= 25000000)
-				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_20;
+				aclc_value = cllqs2[i].car_loop_pilots_on_20;
 			else
-				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_30;
+				aclc_value = cllqs2[i].car_loop_pilots_on_30;
 		} else {
 			if (srate <= 3000000)
-				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_2;
+				aclc_value = cllqs2[i].car_loop_pilots_off_2;
 			else if (srate <= 7000000)
-				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_5;
+				aclc_value = cllqs2[i].car_loop_pilots_off_5;
 			else if (srate <= 15000000)
-				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_10;
+				aclc_value = cllqs2[i].car_loop_pilots_off_10;
 			else if (srate <= 25000000)
-				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_20;
+				aclc_value = cllqs2[i].car_loop_pilots_off_20;
 			else
-				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_30;
+				aclc_value = cllqs2[i].car_loop_pilots_off_30;
 		}
 
 	} else if (modcode <= STV0900_8PSK_910) {
 		if (pilot) {
 			if (srate <= 3000000)
-				aclc_value = car_loop_s2[i].car_loop_pilots_on_2;
+				aclc_value = cls2[i].car_loop_pilots_on_2;
 			else if (srate <= 7000000)
-				aclc_value = car_loop_s2[i].car_loop_pilots_on_5;
+				aclc_value = cls2[i].car_loop_pilots_on_5;
 			else if (srate <= 15000000)
-				aclc_value = car_loop_s2[i].car_loop_pilots_on_10;
+				aclc_value = cls2[i].car_loop_pilots_on_10;
 			else if (srate <= 25000000)
-				aclc_value = car_loop_s2[i].car_loop_pilots_on_20;
+				aclc_value = cls2[i].car_loop_pilots_on_20;
 			else
-				aclc_value = car_loop_s2[i].car_loop_pilots_on_30;
+				aclc_value = cls2[i].car_loop_pilots_on_30;
 		} else {
 			if (srate <= 3000000)
-				aclc_value = car_loop_s2[i].car_loop_pilots_off_2;
+				aclc_value = cls2[i].car_loop_pilots_off_2;
 			else if (srate <= 7000000)
-				aclc_value = car_loop_s2[i].car_loop_pilots_off_5;
+				aclc_value = cls2[i].car_loop_pilots_off_5;
 			else if (srate <= 15000000)
-				aclc_value = car_loop_s2[i].car_loop_pilots_off_10;
+				aclc_value = cls2[i].car_loop_pilots_off_10;
 			else if (srate <= 25000000)
-				aclc_value = car_loop_s2[i].car_loop_pilots_off_20;
+				aclc_value = cls2[i].car_loop_pilots_off_20;
 			else
-				aclc_value = car_loop_s2[i].car_loop_pilots_off_30;
+				aclc_value = cls2[i].car_loop_pilots_off_30;
 		}
 
 	} else {
 		if (srate <= 3000000)
-			aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_2;
+			aclc_value = cllas2[i].car_loop_pilots_on_2;
 		else if (srate <= 7000000)
-			aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_5;
+			aclc_value = cllas2[i].car_loop_pilots_on_5;
 		else if (srate <= 15000000)
-			aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_10;
+			aclc_value = cllas2[i].car_loop_pilots_on_10;
 		else if (srate <= 25000000)
-			aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_20;
+			aclc_value = cllas2[i].car_loop_pilots_on_20;
 		else
-			aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_30;
+			aclc_value = cllas2[i].car_loop_pilots_on_30;
 	}
 
 	return aclc_value;
 }
 
-u8 stv0900_get_optim_short_carr_loop(s32 srate, enum fe_stv0900_modulation modulation, u8 chip_id)
+u8 stv0900_get_optim_short_carr_loop(s32 srate,
+				enum fe_stv0900_modulation modulation,
+				u8 chip_id)
 {
+	const struct stv0900_short_frames_car_loop_optim *s2scl;
+	const struct stv0900_short_frames_car_loop_optim_vs_mod *s2sclc30;
 	s32 mod_index = 0;
-
 	u8 aclc_value = 0x0b;
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
+
+	s2scl = FE_STV0900_S2ShortCarLoop;
+	s2sclc30 = FE_STV0900_S2ShortCarLoopCut30;
 
 	switch (modulation) {
 	case STV0900_QPSK:
@@ -1312,75 +1206,116 @@
 		break;
 	}
 
-	switch (chip_id) {
-	case 0x20:
+	if (chip_id >= 0x30) {
 		if (srate <= 3000000)
-			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_2;
+			aclc_value = s2sclc30[mod_index].car_loop_2;
 		else if (srate <= 7000000)
-			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_5;
+			aclc_value = s2sclc30[mod_index].car_loop_5;
 		else if (srate <= 15000000)
-			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_10;
+			aclc_value = s2sclc30[mod_index].car_loop_10;
 		else if (srate <= 25000000)
-			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_20;
+			aclc_value = s2sclc30[mod_index].car_loop_20;
 		else
-			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_30;
+			aclc_value = s2sclc30[mod_index].car_loop_30;
 
-		break;
-	case 0x12:
-	default:
+	} else if (chip_id >= 0x20) {
 		if (srate <= 3000000)
-			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_2;
+			aclc_value = s2scl[mod_index].car_loop_cut20_2;
 		else if (srate <= 7000000)
-			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_5;
+			aclc_value = s2scl[mod_index].car_loop_cut20_5;
 		else if (srate <= 15000000)
-			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_10;
+			aclc_value = s2scl[mod_index].car_loop_cut20_10;
 		else if (srate <= 25000000)
-			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_20;
+			aclc_value = s2scl[mod_index].car_loop_cut20_20;
 		else
-			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_30;
+			aclc_value = s2scl[mod_index].car_loop_cut20_30;
 
-		break;
+	} else {
+		if (srate <= 3000000)
+			aclc_value = s2scl[mod_index].car_loop_cut12_2;
+		else if (srate <= 7000000)
+			aclc_value = s2scl[mod_index].car_loop_cut12_5;
+		else if (srate <= 15000000)
+			aclc_value = s2scl[mod_index].car_loop_cut12_10;
+		else if (srate <= 25000000)
+			aclc_value = s2scl[mod_index].car_loop_cut12_20;
+		else
+			aclc_value = s2scl[mod_index].car_loop_cut12_30;
+
 	}
 
 	return aclc_value;
 }
 
-static enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *i_params,
+static
+enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *intp,
 					enum fe_stv0900_demod_mode LDPC_Mode,
 					enum fe_stv0900_demod_num demod)
 {
 	enum fe_stv0900_error error = STV0900_NO_ERROR;
+	s32 reg_ind;
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
 	switch (LDPC_Mode) {
 	case STV0900_DUAL:
 	default:
-		if ((i_params->demod_mode != STV0900_DUAL)
-			|| (stv0900_get_bits(i_params, F0900_DDEMOD) != 1)) {
-			stv0900_write_reg(i_params, R0900_GENCFG, 0x1d);
+		if ((intp->demod_mode != STV0900_DUAL)
+			|| (stv0900_get_bits(intp, F0900_DDEMOD) != 1)) {
+			stv0900_write_reg(intp, R0900_GENCFG, 0x1d);
 
-			i_params->demod_mode = STV0900_DUAL;
+			intp->demod_mode = STV0900_DUAL;
 
-			stv0900_write_bits(i_params, F0900_FRESFEC, 1);
-			stv0900_write_bits(i_params, F0900_FRESFEC, 0);
+			stv0900_write_bits(intp, F0900_FRESFEC, 1);
+			stv0900_write_bits(intp, F0900_FRESFEC, 0);
+
+			for (reg_ind = 0; reg_ind < 7; reg_ind++)
+				stv0900_write_reg(intp,
+						R0900_P1_MODCODLST0 + reg_ind,
+						0xff);
+			for (reg_ind = 0; reg_ind < 8; reg_ind++)
+				stv0900_write_reg(intp,
+						R0900_P1_MODCODLST7 + reg_ind,
+						0xcc);
+
+			stv0900_write_reg(intp, R0900_P1_MODCODLSTE, 0xff);
+			stv0900_write_reg(intp, R0900_P1_MODCODLSTF, 0xcf);
+
+			for (reg_ind = 0; reg_ind < 7; reg_ind++)
+				stv0900_write_reg(intp,
+						R0900_P2_MODCODLST0 + reg_ind,
+						0xff);
+			for (reg_ind = 0; reg_ind < 8; reg_ind++)
+				stv0900_write_reg(intp,
+						R0900_P2_MODCODLST7 + reg_ind,
+						0xcc);
+
+			stv0900_write_reg(intp, R0900_P2_MODCODLSTE, 0xff);
+			stv0900_write_reg(intp, R0900_P2_MODCODLSTF, 0xcf);
 		}
 
 		break;
 	case STV0900_SINGLE:
-		if (demod == STV0900_DEMOD_2)
-			stv0900_write_reg(i_params, R0900_GENCFG, 0x06);
-		else
-			stv0900_write_reg(i_params, R0900_GENCFG, 0x04);
+		if (demod == STV0900_DEMOD_2) {
+			stv0900_stop_all_s2_modcod(intp, STV0900_DEMOD_1);
+			stv0900_activate_s2_modcod_single(intp,
+							STV0900_DEMOD_2);
+			stv0900_write_reg(intp, R0900_GENCFG, 0x06);
+		} else {
+			stv0900_stop_all_s2_modcod(intp, STV0900_DEMOD_2);
+			stv0900_activate_s2_modcod_single(intp,
+							STV0900_DEMOD_1);
+			stv0900_write_reg(intp, R0900_GENCFG, 0x04);
+		}
 
-		i_params->demod_mode = STV0900_SINGLE;
+		intp->demod_mode = STV0900_SINGLE;
 
-		stv0900_write_bits(i_params, F0900_FRESFEC, 1);
-		stv0900_write_bits(i_params, F0900_FRESFEC, 0);
-		stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 1);
-		stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 0);
-		stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 1);
-		stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 0);
+		stv0900_write_bits(intp, F0900_FRESFEC, 1);
+		stv0900_write_bits(intp, F0900_FRESFEC, 0);
+		stv0900_write_bits(intp, F0900_P1_ALGOSWRST, 1);
+		stv0900_write_bits(intp, F0900_P1_ALGOSWRST, 0);
+		stv0900_write_bits(intp, F0900_P2_ALGOSWRST, 1);
+		stv0900_write_bits(intp, F0900_P2_ALGOSWRST, 0);
 		break;
 	}
 
@@ -1393,131 +1328,131 @@
 	struct stv0900_state *state = fe->demodulator_priv;
 	enum fe_stv0900_error error = STV0900_NO_ERROR;
 	enum fe_stv0900_error demodError = STV0900_NO_ERROR;
+	struct stv0900_internal *intp = NULL;
+
 	int selosci, i;
 
 	struct stv0900_inode *temp_int = find_inode(state->i2c_adap,
 						state->config->demod_address);
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
-	if (temp_int != NULL) {
+	if ((temp_int != NULL) && (p_init->demod_mode == STV0900_DUAL)) {
 		state->internal = temp_int->internal;
 		(state->internal->dmds_used)++;
-		dprintk(KERN_INFO "%s: Find Internal Structure!\n", __func__);
+		dprintk("%s: Find Internal Structure!\n", __func__);
 		return STV0900_NO_ERROR;
 	} else {
-		state->internal = kmalloc(sizeof(struct stv0900_internal), GFP_KERNEL);
+		state->internal = kmalloc(sizeof(struct stv0900_internal),
+								GFP_KERNEL);
 		temp_int = append_internal(state->internal);
 		state->internal->dmds_used = 1;
 		state->internal->i2c_adap = state->i2c_adap;
 		state->internal->i2c_addr = state->config->demod_address;
 		state->internal->clkmode = state->config->clkmode;
 		state->internal->errs = STV0900_NO_ERROR;
-		dprintk(KERN_INFO "%s: Create New Internal Structure!\n", __func__);
+		dprintk("%s: Create New Internal Structure!\n", __func__);
 	}
 
-	if (state->internal != NULL) {
-		demodError = stv0900_initialize(state->internal);
-		if (demodError == STV0900_NO_ERROR) {
-				error = STV0900_NO_ERROR;
-		} else {
-			if (demodError == STV0900_INVALID_HANDLE)
-				error = STV0900_INVALID_HANDLE;
-			else
-				error = STV0900_I2C_ERROR;
-		}
+	if (state->internal == NULL) {
+		error = STV0900_INVALID_HANDLE;
+		return error;
+	}
 
-		if (state->internal != NULL) {
-			if (error == STV0900_NO_ERROR) {
-				state->internal->demod_mode = p_init->demod_mode;
-
-				stv0900_st_dvbs2_single(state->internal, state->internal->demod_mode, STV0900_DEMOD_1);
-
-				state->internal->chip_id = stv0900_read_reg(state->internal, R0900_MID);
-				state->internal->rolloff = p_init->rolloff;
-				state->internal->quartz = p_init->dmd_ref_clk;
-
-				stv0900_write_bits(state->internal, F0900_P1_ROLLOFF_CONTROL, p_init->rolloff);
-				stv0900_write_bits(state->internal, F0900_P2_ROLLOFF_CONTROL, p_init->rolloff);
-
-				state->internal->ts_config = p_init->ts_config;
-				if (state->internal->ts_config == NULL)
-					stv0900_set_ts_parallel_serial(state->internal,
-							p_init->path1_ts_clock,
-							p_init->path2_ts_clock);
-				else {
-					for (i = 0; state->internal->ts_config[i].addr != 0xffff; i++)
-						stv0900_write_reg(state->internal,
-								state->internal->ts_config[i].addr,
-								state->internal->ts_config[i].val);
-
-					stv0900_write_bits(state->internal, F0900_P2_RST_HWARE, 1);
-					stv0900_write_bits(state->internal, F0900_P2_RST_HWARE, 0);
-					stv0900_write_bits(state->internal, F0900_P1_RST_HWARE, 1);
-					stv0900_write_bits(state->internal, F0900_P1_RST_HWARE, 0);
-				}
-
-				stv0900_write_bits(state->internal, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress);
-				switch (p_init->tuner1_adc) {
-				case 1:
-					stv0900_write_reg(state->internal, R0900_TSTTNR1, 0x26);
-					break;
-				default:
-					break;
-				}
-
-				stv0900_write_bits(state->internal, F0900_P2_TUN_MADDRESS, p_init->tun2_maddress);
-				switch (p_init->tuner2_adc) {
-				case 1:
-					stv0900_write_reg(state->internal, R0900_TSTTNR3, 0x26);
-					break;
-				default:
-					break;
-				}
-
-				stv0900_write_bits(state->internal, F0900_P1_TUN_IQSWAP, p_init->tun1_iq_inversion);
-				stv0900_write_bits(state->internal, F0900_P2_TUN_IQSWAP, p_init->tun2_iq_inversion);
-				stv0900_set_mclk(state->internal, 135000000);
-				msleep(3);
-
-				switch (state->internal->clkmode) {
-				case 0:
-				case 2:
-					stv0900_write_reg(state->internal, R0900_SYNTCTRL, 0x20 | state->internal->clkmode);
-					break;
-				default:
-					selosci = 0x02 & stv0900_read_reg(state->internal, R0900_SYNTCTRL);
-					stv0900_write_reg(state->internal, R0900_SYNTCTRL, 0x20 | selosci);
-					break;
-				}
-				msleep(3);
-
-				state->internal->mclk = stv0900_get_mclk_freq(state->internal, state->internal->quartz);
-				if (state->internal->errs)
-					error = STV0900_I2C_ERROR;
-			}
-		} else {
+	demodError = stv0900_initialize(state->internal);
+	if (demodError == STV0900_NO_ERROR) {
+			error = STV0900_NO_ERROR;
+	} else {
+		if (demodError == STV0900_INVALID_HANDLE)
 			error = STV0900_INVALID_HANDLE;
-		}
+		else
+			error = STV0900_I2C_ERROR;
+
+		return error;
 	}
 
+	if (state->internal == NULL) {
+		error = STV0900_INVALID_HANDLE;
+		return error;
+	}
+
+	intp = state->internal;
+
+	intp->demod_mode = p_init->demod_mode;
+	stv0900_st_dvbs2_single(intp, intp->demod_mode,	STV0900_DEMOD_1);
+	intp->chip_id = stv0900_read_reg(intp, R0900_MID);
+	intp->rolloff = p_init->rolloff;
+	intp->quartz = p_init->dmd_ref_clk;
+
+	stv0900_write_bits(intp, F0900_P1_ROLLOFF_CONTROL, p_init->rolloff);
+	stv0900_write_bits(intp, F0900_P2_ROLLOFF_CONTROL, p_init->rolloff);
+
+	intp->ts_config = p_init->ts_config;
+	if (intp->ts_config == NULL)
+		stv0900_set_ts_parallel_serial(intp,
+				p_init->path1_ts_clock,
+				p_init->path2_ts_clock);
+	else {
+		for (i = 0; intp->ts_config[i].addr != 0xffff; i++)
+			stv0900_write_reg(intp,
+					intp->ts_config[i].addr,
+					intp->ts_config[i].val);
+
+		stv0900_write_bits(intp, F0900_P2_RST_HWARE, 1);
+		stv0900_write_bits(intp, F0900_P2_RST_HWARE, 0);
+		stv0900_write_bits(intp, F0900_P1_RST_HWARE, 1);
+		stv0900_write_bits(intp, F0900_P1_RST_HWARE, 0);
+	}
+
+	stv0900_write_bits(intp, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress);
+	switch (p_init->tuner1_adc) {
+	case 1:
+		stv0900_write_reg(intp, R0900_TSTTNR1, 0x26);
+		break;
+	default:
+		break;
+	}
+
+	stv0900_write_bits(intp, F0900_P2_TUN_MADDRESS, p_init->tun2_maddress);
+	switch (p_init->tuner2_adc) {
+	case 1:
+		stv0900_write_reg(intp, R0900_TSTTNR3, 0x26);
+		break;
+	default:
+		break;
+	}
+
+	stv0900_write_bits(intp, F0900_P1_TUN_IQSWAP, p_init->tun1_iq_inv);
+	stv0900_write_bits(intp, F0900_P2_TUN_IQSWAP, p_init->tun2_iq_inv);
+	stv0900_set_mclk(intp, 135000000);
+	msleep(3);
+
+	switch (intp->clkmode) {
+	case 0:
+	case 2:
+		stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 | intp->clkmode);
+		break;
+	default:
+		selosci = 0x02 & stv0900_read_reg(intp, R0900_SYNTCTRL);
+		stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 | selosci);
+		break;
+	}
+	msleep(3);
+
+	intp->mclk = stv0900_get_mclk_freq(intp, intp->quartz);
+	if (intp->errs)
+		error = STV0900_I2C_ERROR;
+
 	return error;
 }
 
-static int stv0900_status(struct stv0900_internal *i_params,
+static int stv0900_status(struct stv0900_internal *intp,
 					enum fe_stv0900_demod_num demod)
 {
 	enum fe_stv0900_search_state demod_state;
-	s32 mode_field, delin_field, lock_field, fifo_field, lockedvit_field;
 	int locked = FALSE;
 
-	dmd_reg(mode_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
-	dmd_reg(lock_field, F0900_P1_LOCK_DEFINITIF, F0900_P2_LOCK_DEFINITIF);
-	dmd_reg(delin_field, F0900_P1_PKTDELIN_LOCK, F0900_P2_PKTDELIN_LOCK);
-	dmd_reg(fifo_field, F0900_P1_TSFIFO_LINEOK, F0900_P2_TSFIFO_LINEOK);
-	dmd_reg(lockedvit_field, F0900_P1_LOCKEDVIT, F0900_P2_LOCKEDVIT);
-
-	demod_state = stv0900_get_bits(i_params, mode_field);
+	demod_state = stv0900_get_bits(intp, HEADER_MODE);
 	switch (demod_state) {
 	case STV0900_SEARCH:
 	case STV0900_PLH_DETECTED:
@@ -1525,17 +1460,19 @@
 		locked = FALSE;
 		break;
 	case STV0900_DVBS2_FOUND:
-		locked = stv0900_get_bits(i_params, lock_field) &&
-				stv0900_get_bits(i_params, delin_field) &&
-				stv0900_get_bits(i_params, fifo_field);
+		locked = stv0900_get_bits(intp, LOCK_DEFINITIF) &&
+				stv0900_get_bits(intp, PKTDELIN_LOCK) &&
+				stv0900_get_bits(intp, TSFIFO_LINEOK);
 		break;
 	case STV0900_DVBS_FOUND:
-		locked = stv0900_get_bits(i_params, lock_field) &&
-				stv0900_get_bits(i_params, lockedvit_field) &&
-				stv0900_get_bits(i_params, fifo_field);
+		locked = stv0900_get_bits(intp, LOCK_DEFINITIF) &&
+				stv0900_get_bits(intp, LOCKEDVIT) &&
+				stv0900_get_bits(intp, TSFIFO_LINEOK);
 		break;
 	}
 
+	dprintk("%s: locked = %d\n", __func__, locked);
+
 	return locked;
 }
 
@@ -1543,7 +1480,8 @@
 					struct dvb_frontend_parameters *params)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
+	enum fe_stv0900_demod_num demod = state->demod;
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 
 	struct stv0900_search_params p_search;
@@ -1551,10 +1489,16 @@
 
 	enum fe_stv0900_error error = STV0900_NO_ERROR;
 
-	dprintk(KERN_INFO "%s: ", __func__);
+	dprintk("%s: ", __func__);
+
+	if (!(INRANGE(100000, c->symbol_rate, 70000000)))
+		return DVBFE_ALGO_SEARCH_FAILED;
+
+	if (state->config->set_ts_params)
+		state->config->set_ts_params(fe, 0);
 
 	p_result.locked = FALSE;
-	p_search.path = state->demod;
+	p_search.path = demod;
 	p_search.frequency = c->frequency;
 	p_search.symbol_rate = c->symbol_rate;
 	p_search.search_range = 10000000;
@@ -1563,103 +1507,47 @@
 	p_search.iq_inversion = STV0900_IQ_AUTO;
 	p_search.search_algo = STV0900_BLIND_SEARCH;
 
-	if ((INRANGE(100000, p_search.symbol_rate, 70000000)) &&
-			(INRANGE(100000, p_search.search_range, 50000000))) {
-		switch (p_search.path) {
-		case STV0900_DEMOD_1:
+	intp->srch_standard[demod] = p_search.standard;
+	intp->symbol_rate[demod] = p_search.symbol_rate;
+	intp->srch_range[demod] = p_search.search_range;
+	intp->freq[demod] = p_search.frequency;
+	intp->srch_algo[demod] = p_search.search_algo;
+	intp->srch_iq_inv[demod] = p_search.iq_inversion;
+	intp->fec[demod] = p_search.fec;
+	if ((stv0900_algo(fe) == STV0900_RANGEOK) &&
+				(intp->errs == STV0900_NO_ERROR)) {
+		p_result.locked = intp->result[demod].locked;
+		p_result.standard = intp->result[demod].standard;
+		p_result.frequency = intp->result[demod].frequency;
+		p_result.symbol_rate = intp->result[demod].symbol_rate;
+		p_result.fec = intp->result[demod].fec;
+		p_result.modcode = intp->result[demod].modcode;
+		p_result.pilot = intp->result[demod].pilot;
+		p_result.frame_len = intp->result[demod].frame_len;
+		p_result.spectrum = intp->result[demod].spectrum;
+		p_result.rolloff = intp->result[demod].rolloff;
+		p_result.modulation = intp->result[demod].modulation;
+	} else {
+		p_result.locked = FALSE;
+		switch (intp->err[demod]) {
+		case STV0900_I2C_ERROR:
+			error = STV0900_I2C_ERROR;
+			break;
+		case STV0900_NO_ERROR:
 		default:
-			i_params->dmd1_srch_standard = p_search.standard;
-			i_params->dmd1_symbol_rate = p_search.symbol_rate;
-			i_params->dmd1_srch_range = p_search.search_range;
-			i_params->tuner1_freq = p_search.frequency;
-			i_params->dmd1_srch_algo = p_search.search_algo;
-			i_params->dmd1_srch_iq_inv = p_search.iq_inversion;
-			i_params->dmd1_fec = p_search.fec;
-			break;
-
-		case STV0900_DEMOD_2:
-			i_params->dmd2_srch_stndrd = p_search.standard;
-			i_params->dmd2_symbol_rate = p_search.symbol_rate;
-			i_params->dmd2_srch_range = p_search.search_range;
-			i_params->tuner2_freq = p_search.frequency;
-			i_params->dmd2_srch_algo = p_search.search_algo;
-			i_params->dmd2_srch_iq_inv = p_search.iq_inversion;
-			i_params->dmd2_fec = p_search.fec;
+			error = STV0900_SEARCH_FAILED;
 			break;
 		}
-
-		if ((stv0900_algo(fe) == STV0900_RANGEOK) &&
-					(i_params->errs == STV0900_NO_ERROR)) {
-			switch (p_search.path) {
-			case STV0900_DEMOD_1:
-			default:
-				p_result.locked = i_params->dmd1_rslts.locked;
-				p_result.standard = i_params->dmd1_rslts.standard;
-				p_result.frequency = i_params->dmd1_rslts.frequency;
-				p_result.symbol_rate = i_params->dmd1_rslts.symbol_rate;
-				p_result.fec = i_params->dmd1_rslts.fec;
-				p_result.modcode = i_params->dmd1_rslts.modcode;
-				p_result.pilot = i_params->dmd1_rslts.pilot;
-				p_result.frame_length = i_params->dmd1_rslts.frame_length;
-				p_result.spectrum = i_params->dmd1_rslts.spectrum;
-				p_result.rolloff = i_params->dmd1_rslts.rolloff;
-				p_result.modulation = i_params->dmd1_rslts.modulation;
-				break;
-			case STV0900_DEMOD_2:
-				p_result.locked = i_params->dmd2_rslts.locked;
-				p_result.standard = i_params->dmd2_rslts.standard;
-				p_result.frequency = i_params->dmd2_rslts.frequency;
-				p_result.symbol_rate = i_params->dmd2_rslts.symbol_rate;
-				p_result.fec = i_params->dmd2_rslts.fec;
-				p_result.modcode = i_params->dmd2_rslts.modcode;
-				p_result.pilot = i_params->dmd2_rslts.pilot;
-				p_result.frame_length = i_params->dmd2_rslts.frame_length;
-				p_result.spectrum = i_params->dmd2_rslts.spectrum;
-				p_result.rolloff = i_params->dmd2_rslts.rolloff;
-				p_result.modulation = i_params->dmd2_rslts.modulation;
-				break;
-			}
-
-		} else {
-			p_result.locked = FALSE;
-			switch (p_search.path) {
-			case STV0900_DEMOD_1:
-				switch (i_params->dmd1_err) {
-				case STV0900_I2C_ERROR:
-					error = STV0900_I2C_ERROR;
-					break;
-				case STV0900_NO_ERROR:
-				default:
-					error = STV0900_SEARCH_FAILED;
-					break;
-				}
-				break;
-			case STV0900_DEMOD_2:
-				switch (i_params->dmd2_err) {
-				case STV0900_I2C_ERROR:
-					error = STV0900_I2C_ERROR;
-					break;
-				case STV0900_NO_ERROR:
-				default:
-					error = STV0900_SEARCH_FAILED;
-					break;
-				}
-				break;
-			}
-		}
-
-	} else
-		error = STV0900_BAD_PARAMETER;
+	}
 
 	if ((p_result.locked == TRUE) && (error == STV0900_NO_ERROR)) {
-		dprintk(KERN_INFO "Search Success\n");
+		dprintk("Search Success\n");
 		return DVBFE_ALGO_SEARCH_SUCCESS;
 	} else {
-		dprintk(KERN_INFO "Search Fail\n");
+		dprintk("Search Fail\n");
 		return DVBFE_ALGO_SEARCH_FAILED;
 	}
 
-	return DVBFE_ALGO_SEARCH_ERROR;
 }
 
 static int stv0900_read_status(struct dvb_frontend *fe, enum fe_status *status)
@@ -1690,16 +1578,13 @@
 {
 
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
-	s32 rst_field;
-
-	dmd_reg(rst_field, F0900_P1_RST_HWARE, F0900_P2_RST_HWARE);
 
 	if (stop_ts == TRUE)
-		stv0900_write_bits(i_params, rst_field, 1);
+		stv0900_write_bits(intp, RST_HWARE, 1);
 	else
-		stv0900_write_bits(i_params, rst_field, 0);
+		stv0900_write_bits(intp, RST_HWARE, 0);
 
 	return 0;
 }
@@ -1707,23 +1592,19 @@
 static int stv0900_diseqc_init(struct dvb_frontend *fe)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
-	s32 mode_field, reset_field;
 
-	dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE);
-	dmd_reg(reset_field, F0900_P1_DISEQC_RESET, F0900_P2_DISEQC_RESET);
-
-	stv0900_write_bits(i_params, mode_field, state->config->diseqc_mode);
-	stv0900_write_bits(i_params, reset_field, 1);
-	stv0900_write_bits(i_params, reset_field, 0);
+	stv0900_write_bits(intp, DISTX_MODE, state->config->diseqc_mode);
+	stv0900_write_bits(intp, DISEQC_RESET, 1);
+	stv0900_write_bits(intp, DISEQC_RESET, 0);
 
 	return 0;
 }
 
 static int stv0900_init(struct dvb_frontend *fe)
 {
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
 	stv0900_stop_ts(fe, 1);
 	stv0900_diseqc_init(fe);
@@ -1731,48 +1612,24 @@
 	return 0;
 }
 
-static int stv0900_diseqc_send(struct stv0900_internal *i_params , u8 *Data,
+static int stv0900_diseqc_send(struct stv0900_internal *intp , u8 *data,
 				u32 NbData, enum fe_stv0900_demod_num demod)
 {
 	s32 i = 0;
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		stv0900_write_bits(i_params, F0900_P1_DIS_PRECHARGE, 1);
-		while (i < NbData) {
-			while (stv0900_get_bits(i_params, F0900_P1_FIFO_FULL))
-				;/* checkpatch complains */
-			stv0900_write_reg(i_params, R0900_P1_DISTXDATA, Data[i]);
-			i++;
-		}
+	stv0900_write_bits(intp, DIS_PRECHARGE, 1);
+	while (i < NbData) {
+		while (stv0900_get_bits(intp, FIFO_FULL))
+			;/* checkpatch complains */
+		stv0900_write_reg(intp, DISTXDATA, data[i]);
+		i++;
+	}
 
-		stv0900_write_bits(i_params, F0900_P1_DIS_PRECHARGE, 0);
-		i = 0;
-		while ((stv0900_get_bits(i_params, F0900_P1_TX_IDLE) != 1) && (i < 10)) {
-			msleep(10);
-			i++;
-		}
-
-		break;
-	case STV0900_DEMOD_2:
-		stv0900_write_bits(i_params, F0900_P2_DIS_PRECHARGE, 1);
-
-		while (i < NbData) {
-			while (stv0900_get_bits(i_params, F0900_P2_FIFO_FULL))
-				;/* checkpatch complains */
-			stv0900_write_reg(i_params, R0900_P2_DISTXDATA, Data[i]);
-			i++;
-		}
-
-		stv0900_write_bits(i_params, F0900_P2_DIS_PRECHARGE, 0);
-		i = 0;
-		while ((stv0900_get_bits(i_params, F0900_P2_TX_IDLE) != 1) && (i < 10)) {
-			msleep(10);
-			i++;
-		}
-
-		break;
+	stv0900_write_bits(intp, DIS_PRECHARGE, 0);
+	i = 0;
+	while ((stv0900_get_bits(intp, TX_IDLE) != 1) && (i < 10)) {
+		msleep(10);
+		i++;
 	}
 
 	return 0;
@@ -1792,22 +1649,21 @@
 static int stv0900_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
-	s32 mode_field;
-	u32 diseqc_fifo;
+	u8 data;
 
-	dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE);
-	dmd_reg(diseqc_fifo, R0900_P1_DISTXDATA, R0900_P2_DISTXDATA);
 
 	switch (burst) {
 	case SEC_MINI_A:
-		stv0900_write_bits(i_params, mode_field, 3);/* Unmodulated */
-		stv0900_write_reg(i_params, diseqc_fifo, 0x00);
+		stv0900_write_bits(intp, DISTX_MODE, 3);/* Unmodulated */
+		data = 0x00;
+		stv0900_diseqc_send(intp, &data, 1, state->demod);
 		break;
 	case SEC_MINI_B:
-		stv0900_write_bits(i_params, mode_field, 2);/* Modulated */
-		stv0900_write_reg(i_params, diseqc_fifo, 0xff);
+		stv0900_write_bits(intp, DISTX_MODE, 2);/* Modulated */
+		data = 0xff;
+		stv0900_diseqc_send(intp, &data, 1, state->demod);
 		break;
 	}
 
@@ -1818,68 +1674,54 @@
 				struct dvb_diseqc_slave_reply *reply)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
+	enum fe_stv0900_demod_num demod = state->demod;
 	s32 i = 0;
 
-	switch (state->demod) {
-	case STV0900_DEMOD_1:
-	default:
-		reply->msg_len = 0;
+	reply->msg_len = 0;
 
-		while ((stv0900_get_bits(i_params, F0900_P1_RX_END) != 1) && (i < 10)) {
-			msleep(10);
-			i++;
-		}
+	while ((stv0900_get_bits(intp, RX_END) != 1) && (i < 10)) {
+		msleep(10);
+		i++;
+	}
 
-		if (stv0900_get_bits(i_params, F0900_P1_RX_END)) {
-			reply->msg_len = stv0900_get_bits(i_params, F0900_P1_FIFO_BYTENBR);
+	if (stv0900_get_bits(intp, RX_END)) {
+		reply->msg_len = stv0900_get_bits(intp, FIFO_BYTENBR);
 
-			for (i = 0; i < reply->msg_len; i++)
-				reply->msg[i] = stv0900_read_reg(i_params, R0900_P1_DISRXDATA);
-		}
-		break;
-	case STV0900_DEMOD_2:
-		reply->msg_len = 0;
-
-		while ((stv0900_get_bits(i_params, F0900_P2_RX_END) != 1) && (i < 10)) {
-			msleep(10);
-			i++;
-		}
-
-		if (stv0900_get_bits(i_params, F0900_P2_RX_END)) {
-			reply->msg_len = stv0900_get_bits(i_params, F0900_P2_FIFO_BYTENBR);
-
-			for (i = 0; i < reply->msg_len; i++)
-				reply->msg[i] = stv0900_read_reg(i_params, R0900_P2_DISRXDATA);
-		}
-		break;
+		for (i = 0; i < reply->msg_len; i++)
+			reply->msg[i] = stv0900_read_reg(intp, DISRXDATA);
 	}
 
 	return 0;
 }
 
-static int stv0900_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+static int stv0900_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t toneoff)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
-	s32 mode_field, reset_field;
 
-	dprintk(KERN_INFO "%s: %s\n", __func__, ((tone == 0) ? "Off" : "On"));
+	dprintk("%s: %s\n", __func__, ((toneoff == 0) ? "On" : "Off"));
 
-	dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE);
-	dmd_reg(reset_field, F0900_P1_DISEQC_RESET, F0900_P2_DISEQC_RESET);
-
-	if (tone) {
-		/*Set the DiseqC mode to 22Khz continues tone*/
-		stv0900_write_bits(i_params, mode_field, 0);
-		stv0900_write_bits(i_params, reset_field, 1);
+	switch (toneoff) {
+	case SEC_TONE_ON:
+		/*Set the DiseqC mode to 22Khz _continues_ tone*/
+		stv0900_write_bits(intp, DISTX_MODE, 0);
+		stv0900_write_bits(intp, DISEQC_RESET, 1);
 		/*release DiseqC reset to enable the 22KHz tone*/
-		stv0900_write_bits(i_params, reset_field, 0);
-	} else {
-		stv0900_write_bits(i_params, mode_field, 0);
+		stv0900_write_bits(intp, DISEQC_RESET, 0);
+		break;
+	case SEC_TONE_OFF:
+		/*return diseqc mode to config->diseqc_mode.
+		Usually it's without _continues_ tone */
+		stv0900_write_bits(intp, DISTX_MODE,
+				state->config->diseqc_mode);
 		/*maintain the DiseqC reset to disable the 22KHz tone*/
-		stv0900_write_bits(i_params, reset_field, 1);
+		stv0900_write_bits(intp, DISEQC_RESET, 1);
+		stv0900_write_bits(intp, DISEQC_RESET, 0);
+		break;
+	default:
+		return -EINVAL;
 	}
 
 	return 0;
@@ -1889,11 +1731,11 @@
 {
 	struct stv0900_state *state = fe->demodulator_priv;
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
 	if ((--(state->internal->dmds_used)) <= 0) {
 
-		dprintk(KERN_INFO "%s: Actually removing\n", __func__);
+		dprintk("%s: Actually removing\n", __func__);
 
 		remove_inode(state->internal);
 		kfree(state->internal);
@@ -1963,17 +1805,17 @@
 	case 0:
 	case 1:
 		init_params.dmd_ref_clk  	= config->xtal;
-		init_params.demod_mode		= STV0900_DUAL;
+		init_params.demod_mode		= config->demod_mode;
 		init_params.rolloff		= STV0900_35;
 		init_params.path1_ts_clock	= config->path1_mode;
 		init_params.tun1_maddress	= config->tun1_maddress;
-		init_params.tun1_iq_inversion	= STV0900_IQ_NORMAL;
+		init_params.tun1_iq_inv		= STV0900_IQ_NORMAL;
 		init_params.tuner1_adc		= config->tun1_adc;
 		init_params.path2_ts_clock	= config->path2_mode;
 		init_params.ts_config		= config->ts_config_regs;
 		init_params.tun2_maddress	= config->tun2_maddress;
 		init_params.tuner2_adc		= config->tun2_adc;
-		init_params.tun2_iq_inversion	= STV0900_IQ_SWAPPED;
+		init_params.tun2_iq_inv		= STV0900_IQ_SWAPPED;
 
 		err_stv0900 = stv0900_init_internal(&state->frontend,
 							&init_params);
diff --git a/drivers/media/dvb/frontends/stv0900_init.h b/drivers/media/dvb/frontends/stv0900_init.h
index ff388b4..b684df9 100644
--- a/drivers/media/dvb/frontends/stv0900_init.h
+++ b/drivers/media/dvb/frontends/stv0900_init.h
@@ -141,85 +141,228 @@
 
 };
 
+struct stv0900_short_frames_car_loop_optim_vs_mod {
+	enum fe_stv0900_modulation modulation;
+	u8 car_loop_2;	  /* SR<3msps      */
+	u8 car_loop_5;	  /* 3<SR<=7msps   */
+	u8 car_loop_10;   /* 7<SR<=15msps  */
+	u8 car_loop_20;   /* 10<SR<=25msps */
+	u8 car_loop_30;   /* 10<SR<=45msps */
+};
+
 /* Cut 1.x Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */
-static const struct stv0900_car_loop_optim	FE_STV0900_S2CarLoop[14] = {
-	/*Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon 	10MPoff	20MPon 	20MPoff	30MPon 	30MPoff */
-	{ STV0900_QPSK_12,	0x1C,	0x0D,	0x1B,	0x2C,	0x3A,	0x1C,	0x2A,	0x3B,	0x2A,	0x1B },
-	{ STV0900_QPSK_35,	0x2C,	0x0D,	0x2B,	0x2C,	0x3A,	0x0C,	0x3A,	0x2B,	0x2A,	0x0B },
-	{ STV0900_QPSK_23,	0x2C,	0x0D,	0x2B,	0x2C,	0x0B,	0x0C,	0x3A,	0x1B,	0x2A,	0x3A },
-	{ STV0900_QPSK_34,	0x3C,	0x0D,	0x3B,	0x1C,	0x0B,	0x3B,	0x3A,	0x0B,	0x2A,	0x3A },
-	{ STV0900_QPSK_45,	0x3C,	0x0D,	0x3B,	0x1C,	0x0B,	0x3B,	0x3A,	0x0B,	0x2A,	0x3A },
-	{ STV0900_QPSK_56,	0x0D,	0x0D,	0x3B,	0x1C,	0x0B,	0x3B,	0x3A,	0x0B,	0x2A,	0x3A },
-	{ STV0900_QPSK_89,	0x0D,	0x0D,	0x3B,	0x1C,	0x1B,	0x3B,	0x3A,	0x0B,	0x2A,	0x3A },
-	{ STV0900_QPSK_910,	0x1D,	0x0D,	0x3B,	0x1C,	0x1B,	0x3B,	0x3A,	0x0B,	0x2A,	0x3A },
-	{ STV0900_8PSK_35,	0x29,	0x3B,	0x09,	0x2B,	0x38,	0x0B,	0x18,	0x1A,	0x08,	0x0A },
-	{ STV0900_8PSK_23,	0x0A,	0x3B,	0x29,	0x2B,	0x19,	0x0B,	0x38,	0x1A,	0x18,	0x0A },
-	{ STV0900_8PSK_34,	0x3A,	0x3B,	0x2A,	0x2B,	0x39,	0x0B,	0x19,	0x1A,	0x38,	0x0A },
-	{ STV0900_8PSK_56,	0x1B,	0x3B,	0x0B,	0x2B,	0x1A,	0x0B,	0x39,	0x1A,	0x19,	0x0A },
-	{ STV0900_8PSK_89,	0x3B,	0x3B,	0x0B,	0x2B,	0x2A,	0x0B,	0x39,	0x1A,	0x29,	0x39 },
-	{ STV0900_8PSK_910,	0x3B,	0x3B, 	0x0B,	0x2B, 	0x2A,	0x0B,	0x39,	0x1A,	0x29,	0x39 }
+static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoop[14] = {
+	/*Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon
+				10MPoff	20MPon 	20MPoff	30MPon 	30MPoff */
+	{ STV0900_QPSK_12,	0x1C,	0x0D,	0x1B,	0x2C,	0x3A,
+				0x1C,	0x2A,	0x3B,	0x2A,	0x1B },
+	{ STV0900_QPSK_35,	0x2C,	0x0D,	0x2B,	0x2C,	0x3A,
+				0x0C,	0x3A,	0x2B,	0x2A,	0x0B },
+	{ STV0900_QPSK_23,	0x2C,	0x0D,	0x2B,	0x2C,	0x0B,
+				0x0C,	0x3A,	0x1B,	0x2A,	0x3A },
+	{ STV0900_QPSK_34,	0x3C,	0x0D,	0x3B,	0x1C,	0x0B,
+				0x3B,	0x3A,	0x0B,	0x2A,	0x3A },
+	{ STV0900_QPSK_45,	0x3C,	0x0D,	0x3B,	0x1C,	0x0B,
+				0x3B,	0x3A,	0x0B,	0x2A,	0x3A },
+	{ STV0900_QPSK_56,	0x0D,	0x0D,	0x3B,	0x1C,	0x0B,
+				0x3B,	0x3A,	0x0B,	0x2A,	0x3A },
+	{ STV0900_QPSK_89,	0x0D,	0x0D,	0x3B,	0x1C,	0x1B,
+				0x3B,	0x3A,	0x0B,	0x2A,	0x3A },
+	{ STV0900_QPSK_910,	0x1D,	0x0D,	0x3B,	0x1C,	0x1B,
+				0x3B,	0x3A,	0x0B,	0x2A,	0x3A },
+	{ STV0900_8PSK_35,	0x29,	0x3B,	0x09,	0x2B,	0x38,
+				0x0B,	0x18,	0x1A,	0x08,	0x0A },
+	{ STV0900_8PSK_23,	0x0A,	0x3B,	0x29,	0x2B,	0x19,
+				0x0B,	0x38,	0x1A,	0x18,	0x0A },
+	{ STV0900_8PSK_34,	0x3A,	0x3B,	0x2A,	0x2B,	0x39,
+				0x0B,	0x19,	0x1A,	0x38,	0x0A },
+	{ STV0900_8PSK_56,	0x1B,	0x3B,	0x0B,	0x2B,	0x1A,
+				0x0B,	0x39,	0x1A,	0x19,	0x0A },
+	{ STV0900_8PSK_89,	0x3B,	0x3B,	0x0B,	0x2B,	0x2A,
+				0x0B,	0x39,	0x1A,	0x29,	0x39 },
+	{ STV0900_8PSK_910,	0x3B,	0x3B, 	0x0B,	0x2B, 	0x2A,
+				0x0B,	0x39,	0x1A,	0x29,	0x39 }
 };
 
 
 /* Cut 2.0 Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */
-static const struct stv0900_car_loop_optim	FE_STV0900_S2CarLoopCut20[14]	= {
-	/* Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon 	10MPoff	20MPon 	20MPoff	30MPon 	30MPoff */
-	{ STV0900_QPSK_12,	0x1F,	0x3F,	0x1E,	0x3F,	0x3D,	0x1F,	0x3D,	0x3E,	0x3D,	0x1E },
-	{ STV0900_QPSK_35,	0x2F,	0x3F,	0x2E,	0x2F,	0x3D,	0x0F,	0x0E,	0x2E,	0x3D,	0x0E },
-	{ STV0900_QPSK_23,	0x2F,	0x3F,	0x2E,	0x2F,	0x0E,	0x0F,	0x0E,	0x1E,	0x3D,	0x3D },
-	{ STV0900_QPSK_34,	0x3F,	0x3F,	0x3E,	0x1F,	0x0E,	0x3E,	0x0E,	0x1E,	0x3D,	0x3D },
-	{ STV0900_QPSK_45,	0x3F,	0x3F,	0x3E,	0x1F,	0x0E,	0x3E,	0x0E,	0x1E,	0x3D,	0x3D },
-	{ STV0900_QPSK_56,	0x3F,	0x3F,	0x3E,	0x1F,	0x0E,	0x3E,	0x0E,	0x1E,	0x3D,	0x3D },
-	{ STV0900_QPSK_89,	0x3F,	0x3F,	0x3E,	0x1F,	0x1E,	0x3E,	0x0E,	0x1E,	0x3D,	0x3D },
-	{ STV0900_QPSK_910,	0x3F,	0x3F,	0x3E,	0x1F,	0x1E,	0x3E,	0x0E,	0x1E,	0x3D,	0x3D },
-	{ STV0900_8PSK_35,	0x3c,	0x0c,	0x1c,	0x3b,	0x0c,	0x3b,	0x2b,	0x2b,	0x1b,	0x2b },
-	{ STV0900_8PSK_23,	0x1d,	0x0c,	0x3c,	0x0c,	0x2c,	0x3b,	0x0c,	0x2b,	0x2b,	0x2b },
-	{ STV0900_8PSK_34,	0x0e,	0x1c,	0x3d,	0x0c,	0x0d,	0x3b,	0x2c,	0x3b,	0x0c,	0x2b },
-	{ STV0900_8PSK_56,	0x2e,	0x3e,	0x1e,	0x2e,	0x2d,	0x1e,	0x3c,	0x2d,	0x2c,	0x1d },
-	{ STV0900_8PSK_89,	0x3e,	0x3e,	0x1e,	0x2e,	0x3d,	0x1e,	0x0d,	0x2d,	0x3c,	0x1d },
-	{ STV0900_8PSK_910,	0x3e,	0x3e, 	0x1e,	0x2e, 	0x3d,	0x1e,	0x1d,	0x2d,	0x0d,	0x1d }
+static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut20[14] = {
+	/* Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon
+				10MPoff	20MPon 	20MPoff	30MPon 	30MPoff */
+	{ STV0900_QPSK_12,	0x1F,	0x3F,	0x1E,	0x3F,	0x3D,
+				0x1F,	0x3D,	0x3E,	0x3D,	0x1E },
+	{ STV0900_QPSK_35,	0x2F,	0x3F,	0x2E,	0x2F,	0x3D,
+				0x0F,	0x0E,	0x2E,	0x3D,	0x0E },
+	{ STV0900_QPSK_23,	0x2F,	0x3F,	0x2E,	0x2F,	0x0E,
+				0x0F,	0x0E,	0x1E,	0x3D,	0x3D },
+	{ STV0900_QPSK_34,	0x3F,	0x3F,	0x3E,	0x1F,	0x0E,
+				0x3E,	0x0E,	0x1E,	0x3D,	0x3D },
+	{ STV0900_QPSK_45,	0x3F,	0x3F,	0x3E,	0x1F,	0x0E,
+				0x3E,	0x0E,	0x1E,	0x3D,	0x3D },
+	{ STV0900_QPSK_56,	0x3F,	0x3F,	0x3E,	0x1F,	0x0E,
+				0x3E,	0x0E,	0x1E,	0x3D,	0x3D },
+	{ STV0900_QPSK_89,	0x3F,	0x3F,	0x3E,	0x1F,	0x1E,
+				0x3E,	0x0E,	0x1E,	0x3D,	0x3D },
+	{ STV0900_QPSK_910,	0x3F,	0x3F,	0x3E,	0x1F,	0x1E,
+				0x3E,	0x0E,	0x1E,	0x3D,	0x3D },
+	{ STV0900_8PSK_35,	0x3c,	0x0c,	0x1c,	0x3b,	0x0c,
+				0x3b,	0x2b,	0x2b,	0x1b,	0x2b },
+	{ STV0900_8PSK_23,	0x1d,	0x0c,	0x3c,	0x0c,	0x2c,
+				0x3b,	0x0c,	0x2b,	0x2b,	0x2b },
+	{ STV0900_8PSK_34,	0x0e,	0x1c,	0x3d,	0x0c,	0x0d,
+				0x3b,	0x2c,	0x3b,	0x0c,	0x2b },
+	{ STV0900_8PSK_56,	0x2e,	0x3e,	0x1e,	0x2e,	0x2d,
+				0x1e,	0x3c,	0x2d,	0x2c,	0x1d },
+	{ STV0900_8PSK_89,	0x3e,	0x3e,	0x1e,	0x2e,	0x3d,
+				0x1e,	0x0d,	0x2d,	0x3c,	0x1d },
+	{ STV0900_8PSK_910,	0x3e,	0x3e, 	0x1e,	0x2e, 	0x3d,
+				0x1e,	0x1d,	0x2d,	0x0d,	0x1d },
 };
 
 
 
 /* Cut 2.0 Tracking carrier loop carrier 16APSK 2/3 to 32APSK 9/10 long Frame */
 static const struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut20[11] = {
-	/* Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon 	10MPoff	20MPon 	20MPoff	30MPon 	30MPoff */
-	{ STV0900_16APSK_23,	0x0C,	0x0C,	0x0C,	0x0C,	0x1D,	0x0C,	0x3C,	0x0C,	0x2C,	0x0C },
-	{ STV0900_16APSK_34,	0x0C,	0x0C,	0x0C,	0x0C,	0x0E,	0x0C,	0x2D,	0x0C,	0x1D,	0x0C },
-	{ STV0900_16APSK_45,	0x0C,	0x0C,	0x0C,	0x0C,	0x1E,	0x0C,	0x3D,	0x0C,	0x2D,	0x0C },
-	{ STV0900_16APSK_56,	0x0C,	0x0C,	0x0C,	0x0C,	0x1E,	0x0C,	0x3D,	0x0C,	0x2D,	0x0C },
-	{ STV0900_16APSK_89,	0x0C,	0x0C,	0x0C,	0x0C,	0x2E,	0x0C,	0x0E,	0x0C,	0x3D,	0x0C },
-	{ STV0900_16APSK_910,	0x0C,	0x0C,	0x0C,	0x0C,	0x2E,	0x0C,	0x0E,	0x0C,	0x3D,	0x0C },
-	{ STV0900_32APSK_34,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C },
-	{ STV0900_32APSK_45,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C },
-	{ STV0900_32APSK_56,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C },
-	{ STV0900_32APSK_89,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C },
-	{ STV0900_32APSK_910,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C }
+	/* Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon
+				10MPoff	20MPon 	20MPoff	30MPon 	30MPoff */
+	{ STV0900_16APSK_23,	0x0C,	0x0C,	0x0C,	0x0C,	0x1D,
+				0x0C,	0x3C,	0x0C,	0x2C,	0x0C },
+	{ STV0900_16APSK_34,	0x0C,	0x0C,	0x0C,	0x0C,	0x0E,
+				0x0C,	0x2D,	0x0C,	0x1D,	0x0C },
+	{ STV0900_16APSK_45,	0x0C,	0x0C,	0x0C,	0x0C,	0x1E,
+				0x0C,	0x3D,	0x0C,	0x2D,	0x0C },
+	{ STV0900_16APSK_56,	0x0C,	0x0C,	0x0C,	0x0C,	0x1E,
+				0x0C,	0x3D,	0x0C,	0x2D,	0x0C },
+	{ STV0900_16APSK_89,	0x0C,	0x0C,	0x0C,	0x0C,	0x2E,
+				0x0C,	0x0E,	0x0C,	0x3D,	0x0C },
+	{ STV0900_16APSK_910,	0x0C,	0x0C,	0x0C,	0x0C,	0x2E,
+				0x0C,	0x0E,	0x0C,	0x3D,	0x0C },
+	{ STV0900_32APSK_34,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,
+				0x0C,	0x0C,	0x0C,	0x0C,	0x0C },
+	{ STV0900_32APSK_45,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,
+				0x0C,	0x0C,	0x0C,	0x0C,	0x0C },
+	{ STV0900_32APSK_56,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,
+				0x0C,	0x0C,	0x0C,	0x0C,	0x0C },
+	{ STV0900_32APSK_89,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,
+				0x0C,	0x0C,	0x0C,	0x0C,	0x0C },
+	{ STV0900_32APSK_910,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,
+				0x0C,	0x0C,	0x0C,	0x0C,	0x0C },
 };
 
 
 /* Cut 2.0 Tracking carrier loop carrier QPSK 1/4 to QPSK 2/5 long Frame */
 static const struct stv0900_car_loop_optim FE_STV0900_S2LowQPCarLoopCut20[3] = {
-	/* Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon 	10MPoff	20MPon 	20MPoff	30MPon 	30MPoff */
-	{ STV0900_QPSK_14,	0x0F,	0x3F,	0x0E,	0x3F,	0x2D,	0x2F,	0x2D,	0x1F,	0x3D,	0x3E },
-	{ STV0900_QPSK_13,	0x0F,	0x3F,	0x0E,	0x3F,	0x2D,	0x2F,	0x3D,	0x0F,	0x3D,	0x2E },
-	{ STV0900_QPSK_25,	0x1F,	0x3F,	0x1E,	0x3F,	0x3D,	0x1F,	0x3D,	0x3E,	0x3D,	0x2E }
+	/* Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon
+				10MPoff	20MPon 	20MPoff	30MPon 	30MPoff */
+	{ STV0900_QPSK_14,	0x0F,	0x3F,	0x0E,	0x3F,	0x2D,
+				0x2F,	0x2D,	0x1F,	0x3D,	0x3E },
+	{ STV0900_QPSK_13,	0x0F,	0x3F,	0x0E,	0x3F,	0x2D,
+				0x2F,	0x3D,	0x0F,	0x3D,	0x2E },
+	{ STV0900_QPSK_25,	0x1F,	0x3F,	0x1E,	0x3F,	0x3D,
+				0x1F,	0x3D,	0x3E,	0x3D,	0x2E }
 };
 
 
 /* Cut 2.0 Tracking carrier loop carrier  short Frame, cut 1.2 and 2.0 */
-static const struct stv0900_short_frames_car_loop_optim FE_STV0900_S2ShortCarLoop[4]	= {
-	/*Mod	2M_cut1.2 2M_cut2.0 5M_cut1.2 5M_cut2.0 10M_cut1.2 10M_cut2.0 20M_cut1.2 20M_cut2.0 30M_cut1.2 30M_cut2.0 */
-	{ STV0900_QPSK,		0x3C,	0x2F,	0x2B,	0x2E,	0x0B,	0x0E,	0x3A,	0x0E,	0x2A,	0x3D },
-	{ STV0900_8PSK,		0x0B,	0x3E,	0x2A,	0x0E,	0x0A,	0x2D,	0x19,	0x0D,	0x09,	0x3C },
-	{ STV0900_16APSK,	0x1B,	0x1E,	0x1B,	0x1E,	0x1B,	0x1E,	0x3A,	0x3D,	0x2A,	0x2D },
-	{ STV0900_32APSK,	0x1B,	0x1E,	0x1B,	0x1E,	0x1B,	0x1E,	0x3A,	0x3D,	0x2A,	0x2D }
+static const
+struct stv0900_short_frames_car_loop_optim FE_STV0900_S2ShortCarLoop[4] = {
+	/*Mod		2Mcut1.2 2Mcut2.0 5Mcut1.2 5Mcut2.0 10Mcut1.2
+			10Mcut2.0 20Mcut1.2 20M_cut2.0 30Mcut1.2 30Mcut2.0*/
+	{ STV0900_QPSK,		0x3C,	0x2F,	0x2B,	0x2E,	0x0B,
+				0x0E,	0x3A,	0x0E,	0x2A,	0x3D },
+	{ STV0900_8PSK,		0x0B,	0x3E,	0x2A,	0x0E,	0x0A,
+				0x2D,	0x19,	0x0D,	0x09,	0x3C },
+	{ STV0900_16APSK,	0x1B,	0x1E,	0x1B,	0x1E,	0x1B,
+				0x1E,	0x3A,	0x3D,	0x2A,	0x2D },
+	{ STV0900_32APSK,	0x1B,	0x1E,	0x1B,	0x1E,	0x1B,
+				0x1E,	0x3A,	0x3D,	0x2A,	0x2D }
 };
 
-static const u16 STV0900_InitVal[182][2] = {
+static	const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut30[14] = {
+	/*Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon
+				10MPoff	20MPon 	20MPoff	30MPon 	30MPoff	*/
+	{ STV0900_QPSK_12,	0x3C,	0x2C,	0x0C,	0x2C,	0x1B,
+				0x2C,	0x1B,	0x1C,	0x0B, 	0x3B },
+	{ STV0900_QPSK_35,	0x0D,	0x0D,	0x0C,	0x0D,	0x1B,
+				0x3C,	0x1B,	0x1C,	0x0B,	0x3B },
+	{ STV0900_QPSK_23,	0x1D,	0x0D,	0x0C,	0x1D,	0x2B,
+				0x3C,	0x1B,	0x1C,	0x0B,	0x3B },
+	{ STV0900_QPSK_34,	0x1D,	0x1D,	0x0C,	0x1D,	0x2B,
+				0x3C,	0x1B,	0x1C,	0x0B,	0x3B },
+	{ STV0900_QPSK_45,	0x2D,	0x1D,	0x1C,	0x1D,	0x2B,
+				0x3C,	0x2B,	0x0C,	0x1B,	0x3B },
+	{ STV0900_QPSK_56,	0x2D,	0x1D,	0x1C,	0x1D,	0x2B,
+				0x3C,	0x2B,	0x0C,	0x1B,	0x3B },
+	{ STV0900_QPSK_89,	0x3D,	0x2D,	0x1C,	0x1D,	0x3B,
+				0x3C,	0x2B,	0x0C,	0x1B,	0x3B },
+	{ STV0900_QPSK_910,	0x3D,	0x2D,	0x1C,	0x1D,	0x3B,
+				0x3C,	0x2B,	0x0C,	0x1B,	0x3B },
+	{ STV0900_8PSK_35,	0x39,	0x19,	0x39,	0x19,	0x19,
+				0x19,	0x19,	0x19,	0x09,	0x19 },
+	{ STV0900_8PSK_23,	0x2A,	0x39,	0x1A,	0x0A,	0x39,
+				0x0A,	0x29,	0x39,	0x29,	0x0A },
+	{ STV0900_8PSK_34,	0x0B,	0x3A,	0x0B,	0x0B,	0x3A,
+				0x1B,	0x1A,	0x0B,	0x1A,	0x3A },
+	{ STV0900_8PSK_56,	0x0C,	0x1B,	0x3B,	0x2B,	0x1B,
+				0x3B,	0x3A,	0x3B,	0x3A,	0x1B },
+	{ STV0900_8PSK_89,	0x2C,	0x2C,	0x2C,	0x1C,	0x2B,
+				0x0C,	0x0B,	0x3B,	0x0B,	0x1B },
+	{ STV0900_8PSK_910,	0x2C,	0x3C,	0x2C,	0x1C,	0x3B,
+				0x1C,	0x0B,	0x3B,	0x0B,	0x1B }
+};
+
+static	const
+struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut30[11] = {
+	/*Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon
+				10MPoff	20MPon 	20MPoff	30MPon 	30MPoff	*/
+	{ STV0900_16APSK_23,	0x0A,	0x0A,	0x0A,	0x0A,	0x1A,
+				0x0A,	0x3A,	0x0A,	0x2A,	0x0A },
+	{ STV0900_16APSK_34,	0x0A,	0x0A,	0x0A,	0x0A,	0x0B,
+				0x0A,	0x3B,	0x0A,	0x1B,	0x0A },
+	{ STV0900_16APSK_45,	0x0A,	0x0A,	0x0A,	0x0A,	0x1B,
+				0x0A,	0x3B,	0x0A,	0x2B,	0x0A },
+	{ STV0900_16APSK_56,	0x0A,	0x0A,	0x0A,	0x0A,	0x1B,
+				0x0A,	0x3B,	0x0A,	0x2B,	0x0A },
+	{ STV0900_16APSK_89,	0x0A,	0x0A,	0x0A,	0x0A,	0x2B,
+				0x0A,	0x0C,	0x0A,	0x3B,	0x0A },
+	{ STV0900_16APSK_910,	0x0A,	0x0A,	0x0A,	0x0A,	0x2B,
+				0x0A,	0x0C,	0x0A,	0x3B,	0x0A },
+	{ STV0900_32APSK_34,	0x0A,	0x0A,	0x0A,	0x0A,	0x0A,
+				0x0A,	0x0A,	0x0A,	0x0A,	0x0A },
+	{ STV0900_32APSK_45,	0x0A,	0x0A,	0x0A,	0x0A,	0x0A,
+				0x0A,	0x0A,	0x0A,	0x0A,	0x0A },
+	{ STV0900_32APSK_56,	0x0A,	0x0A,	0x0A,	0x0A,	0x0A,
+				0x0A,	0x0A,	0x0A,	0x0A,	0x0A },
+	{ STV0900_32APSK_89,	0x0A,	0x0A,	0x0A,	0x0A,	0x0A,
+				0x0A,	0x0A,	0x0A,	0x0A,	0x0A },
+	{ STV0900_32APSK_910,	0x0A,	0x0A,	0x0A,	0x0A,	0x0A,
+				0x0A,	0x0A,	0x0A,	0x0A,	0x0A }
+};
+
+static	const
+struct stv0900_car_loop_optim FE_STV0900_S2LowQPCarLoopCut30[3] = {
+	/*Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon
+				10MPoff	20MPon 	20MPoff	30MPon 	30MPoff*/
+	{ STV0900_QPSK_14,	0x0C,	0x3C,	0x0B,	0x3C,	0x2A,
+				0x2C,	0x2A,	0x1C,	0x3A,	0x3B },
+	{ STV0900_QPSK_13,	0x0C,	0x3C,	0x0B,	0x3C,	0x2A,
+				0x2C,	0x3A,	0x0C,	0x3A,	0x2B },
+	{ STV0900_QPSK_25,	0x1C,	0x3C,	0x1B,	0x3C,	0x3A,
+				0x1C,	0x3A,	0x3B,	0x3A,	0x2B }
+};
+
+static	const struct stv0900_short_frames_car_loop_optim_vs_mod
+FE_STV0900_S2ShortCarLoopCut30[4] = {
+	/*Mod		2Mcut3.0 5Mcut3.0 10Mcut3.0 20Mcut3.0 30Mcut3.0*/
+	{ STV0900_QPSK,		0x2C,	0x2B,	0x0B,	0x0B,	0x3A },
+	{ STV0900_8PSK,		0x3B,	0x0B,	0x2A,	0x0A,	0x39 },
+	{ STV0900_16APSK,	0x1B,	0x1B,	0x1B,	0x3A,	0x2A },
+	{ STV0900_32APSK,	0x1B,	0x1B,	0x1B,	0x3A,	0x2A },
+
+};
+
+static const u16 STV0900_InitVal[181][2] = {
 	{ R0900_OUTCFG		, 0x00	},
-	{ R0900_MODECFG		, 0xff	},
 	{ R0900_AGCRF1CFG	, 0x11	},
 	{ R0900_AGCRF2CFG	, 0x13	},
 	{ R0900_TSGENERAL1X	, 0x14	},
@@ -381,7 +524,7 @@
 	{ R0900_GAINLLR_NF15	, 0x1A	},
 	{ R0900_GAINLLR_NF16	, 0x1F	},
 	{ R0900_GAINLLR_NF17	, 0x21	},
-	{ R0900_RCCFGH		, 0x20	},
+	{ R0900_RCCFG2		, 0x20	},
 	{ R0900_P1_FECM		, 0x01	}, /*disable DSS modes*/
 	{ R0900_P2_FECM		, 0x01	}, /*disable DSS modes*/
 	{ R0900_P1_PRVIT	, 0x2F	}, /*disable puncture rate 6/7*/
diff --git a/drivers/media/dvb/frontends/stv0900_priv.h b/drivers/media/dvb/frontends/stv0900_priv.h
index 5ed7a14..d8ba8a9 100644
--- a/drivers/media/dvb/frontends/stv0900_priv.h
+++ b/drivers/media/dvb/frontends/stv0900_priv.h
@@ -46,22 +46,6 @@
 #define FALSE (!TRUE)
 #endif
 
-#define	dmd_reg(a, b, c) \
-	do { \
-		a = 0; \
-		switch (demod) { \
-		case STV0900_DEMOD_1: \
-		default: \
-			a = b; \
-			break; \
-		case STV0900_DEMOD_2: \
-			a = c; \
-			break; \
-		} \
-	} while (0)
-
-static int stvdebug;
-
 #define dprintk(args...) \
 	do { \
 		if (stvdebug) \
@@ -70,6 +54,8 @@
 
 #define STV0900_MAXLOOKUPSIZE 500
 #define STV0900_BLIND_SEARCH_AGC2_TH 700
+#define STV0900_BLIND_SEARCH_AGC2_TH_CUT30 1400
+#define IQPOWER_THRESHOLD  30
 
 /* One point of the lookup table */
 struct stv000_lookpoint {
@@ -263,14 +249,14 @@
 	int	tuner1_adc;
 
 	/* IQ from the tuner1 to the demod */
-	enum stv0900_iq_inversion	tun1_iq_inversion;
+	enum stv0900_iq_inversion	tun1_iq_inv;
 	enum fe_stv0900_clock_type	path2_ts_clock;
 
 	u8	tun2_maddress;
 	int	tuner2_adc;
 
 	/* IQ from the tuner2 to the demod */
-	enum stv0900_iq_inversion	tun2_iq_inversion;
+	enum stv0900_iq_inversion	tun2_iq_inv;
 	struct stv0900_reg		*ts_config;
 };
 
@@ -300,7 +286,7 @@
 	enum fe_stv0900_modcode			modcode;
 	enum fe_stv0900_modulation		modulation;
 	enum fe_stv0900_pilot			pilot;
-	enum fe_stv0900_frame_length		frame_length;
+	enum fe_stv0900_frame_length		frame_len;
 	enum stv0900_iq_inversion		spectrum;
 	enum fe_stv0900_rolloff			rolloff;
 
@@ -318,47 +304,25 @@
 	/* Demodulator use for single demod or for dual demod) */
 	enum fe_stv0900_demod_mode	demod_mode;
 
-	/*Demod 1*/
-	s32	tuner1_freq;
-	s32	tuner1_bw;
-	s32	dmd1_symbol_rate;
-	s32	dmd1_srch_range;
+	/*Demods */
+	s32	freq[2];
+	s32	bw[2];
+	s32	symbol_rate[2];
+	s32	srch_range[2];
 
 	/* algorithm for search Blind, Cold or Warm*/
-	enum fe_stv0900_search_algo	dmd1_srch_algo;
+	enum fe_stv0900_search_algo	srch_algo[2];
 	/* search standard: Auto, DVBS1/DSS only or DVBS2 only*/
-	enum fe_stv0900_search_standard	dmd1_srch_standard;
+	enum fe_stv0900_search_standard	srch_standard[2];
 	/* inversion search : auto, auto norma first, normal or inverted */
-	enum fe_stv0900_search_iq	dmd1_srch_iq_inv;
-	enum fe_stv0900_modcode		dmd1_modcode;
-	enum fe_stv0900_modulation	dmd1_modulation;
-	enum fe_stv0900_fec		dmd1_fec;
+	enum fe_stv0900_search_iq	srch_iq_inv[2];
+	enum fe_stv0900_modcode		modcode[2];
+	enum fe_stv0900_modulation	modulation[2];
+	enum fe_stv0900_fec		fec[2];
 
-	struct stv0900_signal_info	dmd1_rslts;
-	enum fe_stv0900_signal_type	dmd1_state;
+	struct stv0900_signal_info	result[2];
+	enum fe_stv0900_error		err[2];
 
-	enum fe_stv0900_error		dmd1_err;
-
-	/*Demod 2*/
-	s32	tuner2_freq;
-	s32	tuner2_bw;
-	s32	dmd2_symbol_rate;
-	s32	dmd2_srch_range;
-
-	enum fe_stv0900_search_algo	dmd2_srch_algo;
-	enum fe_stv0900_search_standard	dmd2_srch_stndrd;
-	/* inversion search : auto, auto normal first, normal or inverted */
-	enum fe_stv0900_search_iq	dmd2_srch_iq_inv;
-	enum fe_stv0900_modcode		dmd2_modcode;
-	enum fe_stv0900_modulation	dmd2_modulation;
-	enum fe_stv0900_fec		dmd2_fec;
-
-	/* results of the search*/
-	struct stv0900_signal_info	dmd2_rslts;
-	/* current state of the search algorithm */
-	enum fe_stv0900_signal_type	dmd2_state;
-
-	enum fe_stv0900_error		dmd2_err;
 
 	struct i2c_adapter	*i2c_adap;
 	u8			i2c_addr;
@@ -379,6 +343,8 @@
 	int demod;
 };
 
+extern int stvdebug;
+
 extern s32 ge2comp(s32 a, s32 width);
 
 extern void stv0900_write_reg(struct stv0900_internal *i_params,
@@ -418,13 +384,14 @@
 extern void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params,
 				enum fe_stv0900_demod_num demod);
 
-extern void stv0900_activate_s2_modcode(struct stv0900_internal *i_params,
+extern void stv0900_activate_s2_modcod(struct stv0900_internal *i_params,
 				enum fe_stv0900_demod_num demod);
 
-extern void stv0900_activate_s2_modcode_single(struct stv0900_internal *i_params,
+extern void stv0900_activate_s2_modcod_single(struct stv0900_internal *i_params,
 				enum fe_stv0900_demod_num demod);
 
-extern enum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
+extern enum
+fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
 				enum fe_stv0900_demod_num demod);
 
 #endif
diff --git a/drivers/media/dvb/frontends/stv0900_reg.h b/drivers/media/dvb/frontends/stv0900_reg.h
index 264f9cf..7b8edf1 100644
--- a/drivers/media/dvb/frontends/stv0900_reg.h
+++ b/drivers/media/dvb/frontends/stv0900_reg.h
@@ -14,7 +14,7 @@
  *
  * 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
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  *
  * GNU General Public License for more details.
  *
@@ -26,3762 +26,3950 @@
 #ifndef STV0900_REG_H
 #define STV0900_REG_H
 
+extern s32 shiftx(s32 x, int demod, s32 shift);
+
+#define REGx(x) shiftx(x, demod, 0x200)
+#define FLDx(x) shiftx(x, demod, 0x2000000)
+
 /*MID*/
-#define R0900_MID  0xf100
-#define F0900_MCHIP_IDENT  0xf10000f0
-#define F0900_MRELEASE  0xf100000f
+#define R0900_MID 0xf100
+#define F0900_MCHIP_IDENT 0xf10000f0
+#define F0900_MRELEASE 0xf100000f
 
 /*DACR1*/
-#define R0900_DACR1  0xf113
-#define F0900_DAC_MODE  0xf11300e0
-#define F0900_DAC_VALUE1  0xf113000f
+#define R0900_DACR1 0xf113
+#define F0900_DAC_MODE 0xf11300e0
+#define F0900_DAC_VALUE1 0xf113000f
 
 /*DACR2*/
-#define R0900_DACR2  0xf114
-#define F0900_DAC_VALUE0  0xf11400ff
+#define R0900_DACR2 0xf114
+#define F0900_DAC_VALUE0 0xf11400ff
 
 /*OUTCFG*/
-#define R0900_OUTCFG  0xf11c
-#define F0900_INV_DATA6  0xf11c0080
-#define F0900_OUTSERRS1_HZ  0xf11c0040
-#define F0900_OUTSERRS2_HZ  0xf11c0020
-#define F0900_OUTSERRS3_HZ  0xf11c0010
-#define F0900_OUTPARRS3_HZ  0xf11c0008
-#define F0900_OUTHZ3_CONTROL  0xf11c0007
-
-/*MODECFG*/
-#define R0900_MODECFG  0xf11d
-#define F0900_FECSPY_SEL_2  0xf11d0020
-#define F0900_HWARE_SEL_2  0xf11d0010
-#define F0900_PKTDEL_SEL_2  0xf11d0008
-#define F0900_DISEQC_SEL_2  0xf11d0004
-#define F0900_VIT_SEL_2  0xf11d0002
-#define F0900_DEMOD_SEL_2  0xf11d0001
+#define R0900_OUTCFG 0xf11c
+#define F0900_OUTSERRS1_HZ 0xf11c0040
+#define F0900_OUTSERRS2_HZ 0xf11c0020
+#define F0900_OUTSERRS3_HZ 0xf11c0010
+#define F0900_OUTPARRS3_HZ 0xf11c0008
 
 /*IRQSTATUS3*/
-#define R0900_IRQSTATUS3  0xf120
-#define F0900_SPLL_LOCK  0xf1200020
-#define F0900_SSTREAM_LCK_3  0xf1200010
-#define F0900_SSTREAM_LCK_2  0xf1200008
-#define F0900_SSTREAM_LCK_1  0xf1200004
-#define F0900_SDVBS1_PRF_2  0xf1200002
-#define F0900_SDVBS1_PRF_1  0xf1200001
+#define R0900_IRQSTATUS3 0xf120
+#define F0900_SPLL_LOCK 0xf1200020
+#define F0900_SSTREAM_LCK_3 0xf1200010
+#define F0900_SSTREAM_LCK_2 0xf1200008
+#define F0900_SSTREAM_LCK_1 0xf1200004
+#define F0900_SDVBS1_PRF_2 0xf1200002
+#define F0900_SDVBS1_PRF_1 0xf1200001
 
 /*IRQSTATUS2*/
-#define R0900_IRQSTATUS2  0xf121
-#define F0900_SSPY_ENDSIM_3  0xf1210080
-#define F0900_SSPY_ENDSIM_2  0xf1210040
-#define F0900_SSPY_ENDSIM_1  0xf1210020
-#define F0900_SPKTDEL_ERROR_2  0xf1210010
-#define F0900_SPKTDEL_LOCKB_2  0xf1210008
-#define F0900_SPKTDEL_LOCK_2  0xf1210004
-#define F0900_SPKTDEL_ERROR_1  0xf1210002
-#define F0900_SPKTDEL_LOCKB_1  0xf1210001
+#define R0900_IRQSTATUS2 0xf121
+#define F0900_SSPY_ENDSIM_3 0xf1210080
+#define F0900_SSPY_ENDSIM_2 0xf1210040
+#define F0900_SSPY_ENDSIM_1 0xf1210020
+#define F0900_SPKTDEL_ERROR_2 0xf1210010
+#define F0900_SPKTDEL_LOCKB_2 0xf1210008
+#define F0900_SPKTDEL_LOCK_2 0xf1210004
+#define F0900_SPKTDEL_ERROR_1 0xf1210002
+#define F0900_SPKTDEL_LOCKB_1 0xf1210001
 
 /*IRQSTATUS1*/
-#define R0900_IRQSTATUS1  0xf122
-#define F0900_SPKTDEL_LOCK_1  0xf1220080
-#define F0900_SEXTPINB2  0xf1220040
-#define F0900_SEXTPIN2  0xf1220020
-#define F0900_SEXTPINB1  0xf1220010
-#define F0900_SEXTPIN1  0xf1220008
-#define F0900_SDEMOD_LOCKB_2  0xf1220004
-#define F0900_SDEMOD_LOCK_2  0xf1220002
-#define F0900_SDEMOD_IRQ_2  0xf1220001
+#define R0900_IRQSTATUS1 0xf122
+#define F0900_SPKTDEL_LOCK_1 0xf1220080
+#define F0900_SDEMOD_LOCKB_2 0xf1220004
+#define F0900_SDEMOD_LOCK_2 0xf1220002
+#define F0900_SDEMOD_IRQ_2 0xf1220001
 
 /*IRQSTATUS0*/
-#define R0900_IRQSTATUS0  0xf123
-#define F0900_SDEMOD_LOCKB_1  0xf1230080
-#define F0900_SDEMOD_LOCK_1  0xf1230040
-#define F0900_SDEMOD_IRQ_1  0xf1230020
-#define F0900_SBCH_ERRFLAG  0xf1230010
-#define F0900_SDISEQC2RX_IRQ  0xf1230008
-#define F0900_SDISEQC2TX_IRQ  0xf1230004
-#define F0900_SDISEQC1RX_IRQ  0xf1230002
-#define F0900_SDISEQC1TX_IRQ  0xf1230001
+#define R0900_IRQSTATUS0 0xf123
+#define F0900_SDEMOD_LOCKB_1 0xf1230080
+#define F0900_SDEMOD_LOCK_1 0xf1230040
+#define F0900_SDEMOD_IRQ_1 0xf1230020
+#define F0900_SBCH_ERRFLAG 0xf1230010
+#define F0900_SDISEQC2RX_IRQ 0xf1230008
+#define F0900_SDISEQC2TX_IRQ 0xf1230004
+#define F0900_SDISEQC1RX_IRQ 0xf1230002
+#define F0900_SDISEQC1TX_IRQ 0xf1230001
 
 /*IRQMASK3*/
-#define R0900_IRQMASK3  0xf124
-#define F0900_MPLL_LOCK  0xf1240020
-#define F0900_MSTREAM_LCK_3  0xf1240010
-#define F0900_MSTREAM_LCK_2  0xf1240008
-#define F0900_MSTREAM_LCK_1  0xf1240004
-#define F0900_MDVBS1_PRF_2  0xf1240002
-#define F0900_MDVBS1_PRF_1  0xf1240001
+#define R0900_IRQMASK3 0xf124
+#define F0900_MPLL_LOCK 0xf1240020
+#define F0900_MSTREAM_LCK_3 0xf1240010
+#define F0900_MSTREAM_LCK_2 0xf1240008
+#define F0900_MSTREAM_LCK_1 0xf1240004
+#define F0900_MDVBS1_PRF_2 0xf1240002
+#define F0900_MDVBS1_PRF_1 0xf1240001
 
 /*IRQMASK2*/
-#define R0900_IRQMASK2  0xf125
-#define F0900_MSPY_ENDSIM_3  0xf1250080
-#define F0900_MSPY_ENDSIM_2  0xf1250040
-#define F0900_MSPY_ENDSIM_1  0xf1250020
-#define F0900_MPKTDEL_ERROR_2  0xf1250010
-#define F0900_MPKTDEL_LOCKB_2  0xf1250008
-#define F0900_MPKTDEL_LOCK_2  0xf1250004
-#define F0900_MPKTDEL_ERROR_1  0xf1250002
-#define F0900_MPKTDEL_LOCKB_1  0xf1250001
+#define R0900_IRQMASK2 0xf125
+#define F0900_MSPY_ENDSIM_3 0xf1250080
+#define F0900_MSPY_ENDSIM_2 0xf1250040
+#define F0900_MSPY_ENDSIM_1 0xf1250020
+#define F0900_MPKTDEL_ERROR_2 0xf1250010
+#define F0900_MPKTDEL_LOCKB_2 0xf1250008
+#define F0900_MPKTDEL_LOCK_2 0xf1250004
+#define F0900_MPKTDEL_ERROR_1 0xf1250002
+#define F0900_MPKTDEL_LOCKB_1 0xf1250001
 
 /*IRQMASK1*/
-#define R0900_IRQMASK1  0xf126
-#define F0900_MPKTDEL_LOCK_1  0xf1260080
-#define F0900_MEXTPINB2  0xf1260040
-#define F0900_MEXTPIN2  0xf1260020
-#define F0900_MEXTPINB1  0xf1260010
-#define F0900_MEXTPIN1  0xf1260008
-#define F0900_MDEMOD_LOCKB_2  0xf1260004
-#define F0900_MDEMOD_LOCK_2  0xf1260002
-#define F0900_MDEMOD_IRQ_2  0xf1260001
+#define R0900_IRQMASK1 0xf126
+#define F0900_MPKTDEL_LOCK_1 0xf1260080
+#define F0900_MEXTPINB2 0xf1260040
+#define F0900_MEXTPIN2 0xf1260020
+#define F0900_MEXTPINB1 0xf1260010
+#define F0900_MEXTPIN1 0xf1260008
+#define F0900_MDEMOD_LOCKB_2 0xf1260004
+#define F0900_MDEMOD_LOCK_2 0xf1260002
+#define F0900_MDEMOD_IRQ_2 0xf1260001
 
 /*IRQMASK0*/
-#define R0900_IRQMASK0  0xf127
-#define F0900_MDEMOD_LOCKB_1  0xf1270080
-#define F0900_MDEMOD_LOCK_1  0xf1270040
-#define F0900_MDEMOD_IRQ_1  0xf1270020
-#define F0900_MBCH_ERRFLAG  0xf1270010
-#define F0900_MDISEQC2RX_IRQ  0xf1270008
-#define F0900_MDISEQC2TX_IRQ  0xf1270004
-#define F0900_MDISEQC1RX_IRQ  0xf1270002
-#define F0900_MDISEQC1TX_IRQ  0xf1270001
+#define R0900_IRQMASK0 0xf127
+#define F0900_MDEMOD_LOCKB_1 0xf1270080
+#define F0900_MDEMOD_LOCK_1 0xf1270040
+#define F0900_MDEMOD_IRQ_1 0xf1270020
+#define F0900_MBCH_ERRFLAG 0xf1270010
+#define F0900_MDISEQC2RX_IRQ 0xf1270008
+#define F0900_MDISEQC2TX_IRQ 0xf1270004
+#define F0900_MDISEQC1RX_IRQ 0xf1270002
+#define F0900_MDISEQC1TX_IRQ 0xf1270001
 
 /*I2CCFG*/
-#define R0900_I2CCFG  0xf129
-#define F0900_I2C2_FASTMODE  0xf1290080
-#define F0900_STATUS_WR2  0xf1290040
-#define F0900_I2C2ADDR_INC  0xf1290030
-#define F0900_I2C_FASTMODE  0xf1290008
-#define F0900_STATUS_WR  0xf1290004
-#define F0900_I2CADDR_INC  0xf1290003
+#define R0900_I2CCFG 0xf129
+#define F0900_I2C_FASTMODE 0xf1290008
+#define F0900_I2CADDR_INC 0xf1290003
 
 /*P1_I2CRPT*/
-#define R0900_P1_I2CRPT  0xf12a
-#define F0900_P1_I2CT_ON  0xf12a0080
-#define F0900_P1_ENARPT_LEVEL  0xf12a0070
-#define F0900_P1_SCLT_DELAY  0xf12a0008
-#define F0900_P1_STOP_ENABLE  0xf12a0004
-#define F0900_P1_STOP_SDAT2SDA  0xf12a0002
+#define R0900_P1_I2CRPT 0xf12a
+#define I2CRPT shiftx(R0900_P1_I2CRPT, demod, -1)
+#define F0900_P1_I2CT_ON 0xf12a0080
+#define I2CT_ON shiftx(F0900_P1_I2CT_ON, demod, -0x10000)
+#define F0900_P1_ENARPT_LEVEL 0xf12a0070
+#define F0900_P1_SCLT_DELAY 0xf12a0008
+#define F0900_P1_STOP_ENABLE 0xf12a0004
+#define F0900_P1_STOP_SDAT2SDA 0xf12a0002
 
 /*P2_I2CRPT*/
-#define R0900_P2_I2CRPT  0xf12b
-#define F0900_P2_I2CT_ON  0xf12b0080
-#define F0900_P2_ENARPT_LEVEL  0xf12b0070
-#define F0900_P2_SCLT_DELAY  0xf12b0008
-#define F0900_P2_STOP_ENABLE  0xf12b0004
-#define F0900_P2_STOP_SDAT2SDA  0xf12b0002
+#define R0900_P2_I2CRPT 0xf12b
+#define F0900_P2_I2CT_ON 0xf12b0080
+#define F0900_P2_ENARPT_LEVEL 0xf12b0070
+#define F0900_P2_SCLT_DELAY 0xf12b0008
+#define F0900_P2_STOP_ENABLE 0xf12b0004
+#define F0900_P2_STOP_SDAT2SDA 0xf12b0002
+
+/*IOPVALUE6*/
+#define R0900_IOPVALUE6 0xf138
+#define F0900_VSCL 0xf1380004
+#define F0900_VSDA 0xf1380002
+#define F0900_VDATA3_0 0xf1380001
+
+/*IOPVALUE5*/
+#define R0900_IOPVALUE5 0xf139
+#define F0900_VDATA3_1 0xf1390080
+#define F0900_VDATA3_2 0xf1390040
+#define F0900_VDATA3_3 0xf1390020
+#define F0900_VDATA3_4 0xf1390010
+#define F0900_VDATA3_5 0xf1390008
+#define F0900_VDATA3_6 0xf1390004
+#define F0900_VDATA3_7 0xf1390002
+#define F0900_VCLKOUT3 0xf1390001
+
+/*IOPVALUE4*/
+#define R0900_IOPVALUE4 0xf13a
+#define F0900_VSTROUT3 0xf13a0080
+#define F0900_VDPN3 0xf13a0040
+#define F0900_VERROR3 0xf13a0020
+#define F0900_VDATA2_7 0xf13a0010
+#define F0900_VCLKOUT2 0xf13a0008
+#define F0900_VSTROUT2 0xf13a0004
+#define F0900_VDPN2 0xf13a0002
+#define F0900_VERROR2 0xf13a0001
+
+/*IOPVALUE3*/
+#define R0900_IOPVALUE3 0xf13b
+#define F0900_VDATA1_7 0xf13b0080
+#define F0900_VCLKOUT1 0xf13b0040
+#define F0900_VSTROUT1 0xf13b0020
+#define F0900_VDPN1 0xf13b0010
+#define F0900_VERROR1 0xf13b0008
+#define F0900_VCLKOUT27 0xf13b0004
+#define F0900_VDISEQCOUT2 0xf13b0002
+#define F0900_VSCLT2 0xf13b0001
+
+/*IOPVALUE2*/
+#define R0900_IOPVALUE2 0xf13c
+#define F0900_VSDAT2 0xf13c0080
+#define F0900_VAGCRF2 0xf13c0040
+#define F0900_VDISEQCOUT1 0xf13c0020
+#define F0900_VSCLT1 0xf13c0010
+#define F0900_VSDAT1 0xf13c0008
+#define F0900_VAGCRF1 0xf13c0004
+#define F0900_VDIRCLK 0xf13c0002
+#define F0900_VSTDBY 0xf13c0001
+
+/*IOPVALUE1*/
+#define R0900_IOPVALUE1 0xf13d
+#define F0900_VCS1 0xf13d0080
+#define F0900_VCS0 0xf13d0040
+#define F0900_VGPIO13 0xf13d0020
+#define F0900_VGPIO12 0xf13d0010
+#define F0900_VGPIO11 0xf13d0008
+#define F0900_VGPIO10 0xf13d0004
+#define F0900_VGPIO9 0xf13d0002
+#define F0900_VGPIO8 0xf13d0001
+
+/*IOPVALUE0*/
+#define R0900_IOPVALUE0 0xf13e
+#define F0900_VGPIO7 0xf13e0080
+#define F0900_VGPIO6 0xf13e0040
+#define F0900_VGPIO5 0xf13e0020
+#define F0900_VGPIO4 0xf13e0010
+#define F0900_VGPIO3 0xf13e0008
+#define F0900_VGPIO2 0xf13e0004
+#define F0900_VGPIO1 0xf13e0002
+#define F0900_VCLKI2 0xf13e0001
 
 /*CLKI2CFG*/
-#define R0900_CLKI2CFG  0xf140
-#define F0900_CLKI2_OPD  0xf1400080
-#define F0900_CLKI2_CONFIG  0xf140007e
-#define F0900_CLKI2_XOR  0xf1400001
+#define R0900_CLKI2CFG 0xf140
+#define F0900_CLKI2_OPD 0xf1400080
+#define F0900_CLKI2_CONFIG 0xf140007e
+#define F0900_CLKI2_XOR 0xf1400001
 
 /*GPIO1CFG*/
-#define R0900_GPIO1CFG  0xf141
-#define F0900_GPIO1_OPD  0xf1410080
-#define F0900_GPIO1_CONFIG  0xf141007e
-#define F0900_GPIO1_XOR  0xf1410001
+#define R0900_GPIO1CFG 0xf141
+#define F0900_GPIO1_OPD 0xf1410080
+#define F0900_GPIO1_CONFIG 0xf141007e
+#define F0900_GPIO1_XOR 0xf1410001
 
 /*GPIO2CFG*/
-#define R0900_GPIO2CFG  0xf142
-#define F0900_GPIO2_OPD  0xf1420080
-#define F0900_GPIO2_CONFIG  0xf142007e
-#define F0900_GPIO2_XOR  0xf1420001
+#define R0900_GPIO2CFG 0xf142
+#define F0900_GPIO2_OPD 0xf1420080
+#define F0900_GPIO2_CONFIG 0xf142007e
+#define F0900_GPIO2_XOR 0xf1420001
 
 /*GPIO3CFG*/
-#define R0900_GPIO3CFG  0xf143
-#define F0900_GPIO3_OPD  0xf1430080
-#define F0900_GPIO3_CONFIG  0xf143007e
-#define F0900_GPIO3_XOR  0xf1430001
+#define R0900_GPIO3CFG 0xf143
+#define F0900_GPIO3_OPD 0xf1430080
+#define F0900_GPIO3_CONFIG 0xf143007e
+#define F0900_GPIO3_XOR 0xf1430001
 
 /*GPIO4CFG*/
-#define R0900_GPIO4CFG  0xf144
-#define F0900_GPIO4_OPD  0xf1440080
-#define F0900_GPIO4_CONFIG  0xf144007e
-#define F0900_GPIO4_XOR  0xf1440001
+#define R0900_GPIO4CFG 0xf144
+#define F0900_GPIO4_OPD 0xf1440080
+#define F0900_GPIO4_CONFIG 0xf144007e
+#define F0900_GPIO4_XOR 0xf1440001
 
 /*GPIO5CFG*/
-#define R0900_GPIO5CFG  0xf145
-#define F0900_GPIO5_OPD  0xf1450080
-#define F0900_GPIO5_CONFIG  0xf145007e
-#define F0900_GPIO5_XOR  0xf1450001
+#define R0900_GPIO5CFG 0xf145
+#define F0900_GPIO5_OPD 0xf1450080
+#define F0900_GPIO5_CONFIG 0xf145007e
+#define F0900_GPIO5_XOR 0xf1450001
 
 /*GPIO6CFG*/
-#define R0900_GPIO6CFG  0xf146
-#define F0900_GPIO6_OPD  0xf1460080
-#define F0900_GPIO6_CONFIG  0xf146007e
-#define F0900_GPIO6_XOR  0xf1460001
+#define R0900_GPIO6CFG 0xf146
+#define F0900_GPIO6_OPD 0xf1460080
+#define F0900_GPIO6_CONFIG 0xf146007e
+#define F0900_GPIO6_XOR 0xf1460001
 
 /*GPIO7CFG*/
-#define R0900_GPIO7CFG  0xf147
-#define F0900_GPIO7_OPD  0xf1470080
-#define F0900_GPIO7_CONFIG  0xf147007e
-#define F0900_GPIO7_XOR  0xf1470001
+#define R0900_GPIO7CFG 0xf147
+#define F0900_GPIO7_OPD 0xf1470080
+#define F0900_GPIO7_CONFIG 0xf147007e
+#define F0900_GPIO7_XOR 0xf1470001
 
 /*GPIO8CFG*/
-#define R0900_GPIO8CFG  0xf148
-#define F0900_GPIO8_OPD  0xf1480080
-#define F0900_GPIO8_CONFIG  0xf148007e
-#define F0900_GPIO8_XOR  0xf1480001
+#define R0900_GPIO8CFG 0xf148
+#define F0900_GPIO8_OPD 0xf1480080
+#define F0900_GPIO8_CONFIG 0xf148007e
+#define F0900_GPIO8_XOR 0xf1480001
 
 /*GPIO9CFG*/
-#define R0900_GPIO9CFG  0xf149
-#define F0900_GPIO9_OPD  0xf1490080
-#define F0900_GPIO9_CONFIG  0xf149007e
-#define F0900_GPIO9_XOR  0xf1490001
+#define R0900_GPIO9CFG 0xf149
+#define F0900_GPIO9_OPD 0xf1490080
+#define F0900_GPIO9_CONFIG 0xf149007e
+#define F0900_GPIO9_XOR 0xf1490001
 
 /*GPIO10CFG*/
-#define R0900_GPIO10CFG  0xf14a
-#define F0900_GPIO10_OPD  0xf14a0080
-#define F0900_GPIO10_CONFIG  0xf14a007e
-#define F0900_GPIO10_XOR  0xf14a0001
+#define R0900_GPIO10CFG 0xf14a
+#define F0900_GPIO10_OPD 0xf14a0080
+#define F0900_GPIO10_CONFIG 0xf14a007e
+#define F0900_GPIO10_XOR 0xf14a0001
 
 /*GPIO11CFG*/
-#define R0900_GPIO11CFG  0xf14b
-#define F0900_GPIO11_OPD  0xf14b0080
-#define F0900_GPIO11_CONFIG  0xf14b007e
-#define F0900_GPIO11_XOR  0xf14b0001
+#define R0900_GPIO11CFG 0xf14b
+#define F0900_GPIO11_OPD 0xf14b0080
+#define F0900_GPIO11_CONFIG 0xf14b007e
+#define F0900_GPIO11_XOR 0xf14b0001
 
 /*GPIO12CFG*/
-#define R0900_GPIO12CFG  0xf14c
-#define F0900_GPIO12_OPD  0xf14c0080
-#define F0900_GPIO12_CONFIG  0xf14c007e
-#define F0900_GPIO12_XOR  0xf14c0001
+#define R0900_GPIO12CFG 0xf14c
+#define F0900_GPIO12_OPD 0xf14c0080
+#define F0900_GPIO12_CONFIG 0xf14c007e
+#define F0900_GPIO12_XOR 0xf14c0001
 
 /*GPIO13CFG*/
-#define R0900_GPIO13CFG  0xf14d
-#define F0900_GPIO13_OPD  0xf14d0080
-#define F0900_GPIO13_CONFIG  0xf14d007e
-#define F0900_GPIO13_XOR  0xf14d0001
+#define R0900_GPIO13CFG 0xf14d
+#define F0900_GPIO13_OPD 0xf14d0080
+#define F0900_GPIO13_CONFIG 0xf14d007e
+#define F0900_GPIO13_XOR 0xf14d0001
 
 /*CS0CFG*/
-#define R0900_CS0CFG  0xf14e
-#define F0900_CS0_OPD  0xf14e0080
-#define F0900_CS0_CONFIG  0xf14e007e
-#define F0900_CS0_XOR  0xf14e0001
+#define R0900_CS0CFG 0xf14e
+#define F0900_CS0_OPD 0xf14e0080
+#define F0900_CS0_CONFIG 0xf14e007e
+#define F0900_CS0_XOR 0xf14e0001
 
 /*CS1CFG*/
-#define R0900_CS1CFG  0xf14f
-#define F0900_CS1_OPD  0xf14f0080
-#define F0900_CS1_CONFIG  0xf14f007e
-#define F0900_CS1_XOR  0xf14f0001
+#define R0900_CS1CFG 0xf14f
+#define F0900_CS1_OPD 0xf14f0080
+#define F0900_CS1_CONFIG 0xf14f007e
+#define F0900_CS1_XOR 0xf14f0001
 
 /*STDBYCFG*/
-#define R0900_STDBYCFG  0xf150
-#define F0900_STDBY_OPD  0xf1500080
-#define F0900_STDBY_CONFIG  0xf150007e
-#define F0900_STBDY_XOR  0xf1500001
+#define R0900_STDBYCFG 0xf150
+#define F0900_STDBY_OPD 0xf1500080
+#define F0900_STDBY_CONFIG 0xf150007e
+#define F0900_STBDY_XOR 0xf1500001
 
 /*DIRCLKCFG*/
-#define R0900_DIRCLKCFG  0xf151
-#define F0900_DIRCLK_OPD  0xf1510080
-#define F0900_DIRCLK_CONFIG  0xf151007e
-#define F0900_DIRCLK_XOR  0xf1510001
+#define R0900_DIRCLKCFG 0xf151
+#define F0900_DIRCLK_OPD 0xf1510080
+#define F0900_DIRCLK_CONFIG 0xf151007e
+#define F0900_DIRCLK_XOR 0xf1510001
 
 /*AGCRF1CFG*/
-#define R0900_AGCRF1CFG  0xf152
-#define F0900_AGCRF1_OPD  0xf1520080
-#define F0900_AGCRF1_CONFIG  0xf152007e
-#define F0900_AGCRF1_XOR  0xf1520001
+#define R0900_AGCRF1CFG 0xf152
+#define F0900_AGCRF1_OPD 0xf1520080
+#define F0900_AGCRF1_CONFIG 0xf152007e
+#define F0900_AGCRF1_XOR 0xf1520001
 
 /*SDAT1CFG*/
-#define R0900_SDAT1CFG  0xf153
-#define F0900_SDAT1_OPD  0xf1530080
-#define F0900_SDAT1_CONFIG  0xf153007e
-#define F0900_SDAT1_XOR  0xf1530001
+#define R0900_SDAT1CFG 0xf153
+#define F0900_SDAT1_OPD 0xf1530080
+#define F0900_SDAT1_CONFIG 0xf153007e
+#define F0900_SDAT1_XOR 0xf1530001
 
 /*SCLT1CFG*/
-#define R0900_SCLT1CFG  0xf154
-#define F0900_SCLT1_OPD  0xf1540080
-#define F0900_SCLT1_CONFIG  0xf154007e
-#define F0900_SCLT1_XOR  0xf1540001
+#define R0900_SCLT1CFG 0xf154
+#define F0900_SCLT1_OPD 0xf1540080
+#define F0900_SCLT1_CONFIG 0xf154007e
+#define F0900_SCLT1_XOR 0xf1540001
 
 /*DISEQCO1CFG*/
-#define R0900_DISEQCO1CFG  0xf155
-#define F0900_DISEQCO1_OPD  0xf1550080
-#define F0900_DISEQCO1_CONFIG  0xf155007e
-#define F0900_DISEQC1_XOR  0xf1550001
+#define R0900_DISEQCO1CFG 0xf155
+#define F0900_DISEQCO1_OPD 0xf1550080
+#define F0900_DISEQCO1_CONFIG 0xf155007e
+#define F0900_DISEQC1_XOR 0xf1550001
 
 /*AGCRF2CFG*/
-#define R0900_AGCRF2CFG  0xf156
-#define F0900_AGCRF2_OPD  0xf1560080
-#define F0900_AGCRF2_CONFIG  0xf156007e
-#define F0900_AGCRF2_XOR  0xf1560001
+#define R0900_AGCRF2CFG 0xf156
+#define F0900_AGCRF2_OPD 0xf1560080
+#define F0900_AGCRF2_CONFIG 0xf156007e
+#define F0900_AGCRF2_XOR 0xf1560001
 
 /*SDAT2CFG*/
-#define R0900_SDAT2CFG  0xf157
-#define F0900_SDAT2_OPD  0xf1570080
-#define F0900_SDAT2_CONFIG  0xf157007e
-#define F0900_SDAT2_XOR  0xf1570001
+#define R0900_SDAT2CFG 0xf157
+#define F0900_SDAT2_OPD 0xf1570080
+#define F0900_SDAT2_CONFIG 0xf157007e
+#define F0900_SDAT2_XOR 0xf1570001
 
 /*SCLT2CFG*/
-#define R0900_SCLT2CFG  0xf158
-#define F0900_SCLT2_OPD  0xf1580080
-#define F0900_SCLT2_CONFIG  0xf158007e
-#define F0900_SCLT2_XOR  0xf1580001
+#define R0900_SCLT2CFG 0xf158
+#define F0900_SCLT2_OPD 0xf1580080
+#define F0900_SCLT2_CONFIG 0xf158007e
+#define F0900_SCLT2_XOR 0xf1580001
 
 /*DISEQCO2CFG*/
-#define R0900_DISEQCO2CFG  0xf159
-#define F0900_DISEQCO2_OPD  0xf1590080
-#define F0900_DISEQCO2_CONFIG  0xf159007e
-#define F0900_DISEQC2_XOR  0xf1590001
+#define R0900_DISEQCO2CFG 0xf159
+#define F0900_DISEQCO2_OPD 0xf1590080
+#define F0900_DISEQCO2_CONFIG 0xf159007e
+#define F0900_DISEQC2_XOR 0xf1590001
 
 /*CLKOUT27CFG*/
-#define R0900_CLKOUT27CFG  0xf15a
-#define F0900_CLKOUT27_OPD  0xf15a0080
-#define F0900_CLKOUT27_CONFIG  0xf15a007e
-#define F0900_CLKOUT27_XOR  0xf15a0001
+#define R0900_CLKOUT27CFG 0xf15a
+#define F0900_CLKOUT27_OPD 0xf15a0080
+#define F0900_CLKOUT27_CONFIG 0xf15a007e
+#define F0900_CLKOUT27_XOR 0xf15a0001
 
 /*ERROR1CFG*/
-#define R0900_ERROR1CFG  0xf15b
-#define F0900_ERROR1_OPD  0xf15b0080
-#define F0900_ERROR1_CONFIG  0xf15b007e
-#define F0900_ERROR1_XOR  0xf15b0001
+#define R0900_ERROR1CFG 0xf15b
+#define F0900_ERROR1_OPD 0xf15b0080
+#define F0900_ERROR1_CONFIG 0xf15b007e
+#define F0900_ERROR1_XOR 0xf15b0001
 
 /*DPN1CFG*/
-#define R0900_DPN1CFG  0xf15c
-#define F0900_DPN1_OPD  0xf15c0080
-#define F0900_DPN1_CONFIG  0xf15c007e
-#define F0900_DPN1_XOR  0xf15c0001
+#define R0900_DPN1CFG 0xf15c
+#define F0900_DPN1_OPD 0xf15c0080
+#define F0900_DPN1_CONFIG 0xf15c007e
+#define F0900_DPN1_XOR 0xf15c0001
 
 /*STROUT1CFG*/
-#define R0900_STROUT1CFG  0xf15d
-#define F0900_STROUT1_OPD  0xf15d0080
-#define F0900_STROUT1_CONFIG  0xf15d007e
-#define F0900_STROUT1_XOR  0xf15d0001
+#define R0900_STROUT1CFG 0xf15d
+#define F0900_STROUT1_OPD 0xf15d0080
+#define F0900_STROUT1_CONFIG 0xf15d007e
+#define F0900_STROUT1_XOR 0xf15d0001
 
 /*CLKOUT1CFG*/
-#define R0900_CLKOUT1CFG  0xf15e
-#define F0900_CLKOUT1_OPD  0xf15e0080
-#define F0900_CLKOUT1_CONFIG  0xf15e007e
-#define F0900_CLKOUT1_XOR  0xf15e0001
+#define R0900_CLKOUT1CFG 0xf15e
+#define F0900_CLKOUT1_OPD 0xf15e0080
+#define F0900_CLKOUT1_CONFIG 0xf15e007e
+#define F0900_CLKOUT1_XOR 0xf15e0001
 
 /*DATA71CFG*/
-#define R0900_DATA71CFG  0xf15f
-#define F0900_DATA71_OPD  0xf15f0080
-#define F0900_DATA71_CONFIG  0xf15f007e
-#define F0900_DATA71_XOR  0xf15f0001
+#define R0900_DATA71CFG 0xf15f
+#define F0900_DATA71_OPD 0xf15f0080
+#define F0900_DATA71_CONFIG 0xf15f007e
+#define F0900_DATA71_XOR 0xf15f0001
 
 /*ERROR2CFG*/
-#define R0900_ERROR2CFG  0xf160
-#define F0900_ERROR2_OPD  0xf1600080
-#define F0900_ERROR2_CONFIG  0xf160007e
-#define F0900_ERROR2_XOR  0xf1600001
+#define R0900_ERROR2CFG 0xf160
+#define F0900_ERROR2_OPD 0xf1600080
+#define F0900_ERROR2_CONFIG 0xf160007e
+#define F0900_ERROR2_XOR 0xf1600001
 
 /*DPN2CFG*/
-#define R0900_DPN2CFG  0xf161
-#define F0900_DPN2_OPD  0xf1610080
-#define F0900_DPN2_CONFIG  0xf161007e
-#define F0900_DPN2_XOR  0xf1610001
+#define R0900_DPN2CFG 0xf161
+#define F0900_DPN2_OPD 0xf1610080
+#define F0900_DPN2_CONFIG 0xf161007e
+#define F0900_DPN2_XOR 0xf1610001
 
 /*STROUT2CFG*/
-#define R0900_STROUT2CFG  0xf162
-#define F0900_STROUT2_OPD  0xf1620080
-#define F0900_STROUT2_CONFIG  0xf162007e
-#define F0900_STROUT2_XOR  0xf1620001
+#define R0900_STROUT2CFG 0xf162
+#define F0900_STROUT2_OPD 0xf1620080
+#define F0900_STROUT2_CONFIG 0xf162007e
+#define F0900_STROUT2_XOR 0xf1620001
 
 /*CLKOUT2CFG*/
-#define R0900_CLKOUT2CFG  0xf163
-#define F0900_CLKOUT2_OPD  0xf1630080
-#define F0900_CLKOUT2_CONFIG  0xf163007e
-#define F0900_CLKOUT2_XOR  0xf1630001
+#define R0900_CLKOUT2CFG 0xf163
+#define F0900_CLKOUT2_OPD 0xf1630080
+#define F0900_CLKOUT2_CONFIG 0xf163007e
+#define F0900_CLKOUT2_XOR 0xf1630001
 
 /*DATA72CFG*/
-#define R0900_DATA72CFG  0xf164
-#define F0900_DATA72_OPD  0xf1640080
-#define F0900_DATA72_CONFIG  0xf164007e
-#define F0900_DATA72_XOR  0xf1640001
+#define R0900_DATA72CFG 0xf164
+#define F0900_DATA72_OPD 0xf1640080
+#define F0900_DATA72_CONFIG 0xf164007e
+#define F0900_DATA72_XOR 0xf1640001
 
 /*ERROR3CFG*/
-#define R0900_ERROR3CFG  0xf165
-#define F0900_ERROR3_OPD  0xf1650080
-#define F0900_ERROR3_CONFIG  0xf165007e
-#define F0900_ERROR3_XOR  0xf1650001
+#define R0900_ERROR3CFG 0xf165
+#define F0900_ERROR3_OPD 0xf1650080
+#define F0900_ERROR3_CONFIG 0xf165007e
+#define F0900_ERROR3_XOR 0xf1650001
 
 /*DPN3CFG*/
-#define R0900_DPN3CFG  0xf166
-#define F0900_DPN3_OPD  0xf1660080
-#define F0900_DPN3_CONFIG  0xf166007e
-#define F0900_DPN3_XOR  0xf1660001
+#define R0900_DPN3CFG 0xf166
+#define F0900_DPN3_OPD 0xf1660080
+#define F0900_DPN3_CONFIG 0xf166007e
+#define F0900_DPN3_XOR 0xf1660001
 
 /*STROUT3CFG*/
-#define R0900_STROUT3CFG  0xf167
-#define F0900_STROUT3_OPD  0xf1670080
-#define F0900_STROUT3_CONFIG  0xf167007e
-#define F0900_STROUT3_XOR  0xf1670001
+#define R0900_STROUT3CFG 0xf167
+#define F0900_STROUT3_OPD 0xf1670080
+#define F0900_STROUT3_CONFIG 0xf167007e
+#define F0900_STROUT3_XOR 0xf1670001
 
 /*CLKOUT3CFG*/
-#define R0900_CLKOUT3CFG  0xf168
-#define F0900_CLKOUT3_OPD  0xf1680080
-#define F0900_CLKOUT3_CONFIG  0xf168007e
-#define F0900_CLKOUT3_XOR  0xf1680001
+#define R0900_CLKOUT3CFG 0xf168
+#define F0900_CLKOUT3_OPD 0xf1680080
+#define F0900_CLKOUT3_CONFIG 0xf168007e
+#define F0900_CLKOUT3_XOR 0xf1680001
 
 /*DATA73CFG*/
-#define R0900_DATA73CFG  0xf169
-#define F0900_DATA73_OPD  0xf1690080
-#define F0900_DATA73_CONFIG  0xf169007e
-#define F0900_DATA73_XOR  0xf1690001
+#define R0900_DATA73CFG 0xf169
+#define F0900_DATA73_OPD 0xf1690080
+#define F0900_DATA73_CONFIG 0xf169007e
+#define F0900_DATA73_XOR 0xf1690001
+
+/*STRSTATUS1*/
+#define R0900_STRSTATUS1 0xf16a
+#define F0900_STRSTATUS_SEL2 0xf16a00f0
+#define F0900_STRSTATUS_SEL1 0xf16a000f
+
+/*STRSTATUS2*/
+#define R0900_STRSTATUS2 0xf16b
+#define F0900_STRSTATUS_SEL4 0xf16b00f0
+#define F0900_STRSTATUS_SEL3 0xf16b000f
+
+/*STRSTATUS3*/
+#define R0900_STRSTATUS3 0xf16c
+#define F0900_STRSTATUS_SEL6 0xf16c00f0
+#define F0900_STRSTATUS_SEL5 0xf16c000f
 
 /*FSKTFC2*/
-#define R0900_FSKTFC2  0xf170
-#define F0900_FSKT_KMOD  0xf17000fc
-#define F0900_FSKT_CAR2  0xf1700003
+#define R0900_FSKTFC2 0xf170
+#define F0900_FSKT_KMOD 0xf17000fc
+#define F0900_FSKT_CAR2 0xf1700003
 
 /*FSKTFC1*/
-#define R0900_FSKTFC1  0xf171
-#define F0900_FSKT_CAR1  0xf17100ff
+#define R0900_FSKTFC1 0xf171
+#define F0900_FSKT_CAR1 0xf17100ff
 
 /*FSKTFC0*/
-#define R0900_FSKTFC0  0xf172
-#define F0900_FSKT_CAR0  0xf17200ff
+#define R0900_FSKTFC0 0xf172
+#define F0900_FSKT_CAR0 0xf17200ff
 
 /*FSKTDELTAF1*/
-#define R0900_FSKTDELTAF1  0xf173
-#define F0900_FSKT_DELTAF1  0xf173000f
+#define R0900_FSKTDELTAF1 0xf173
+#define F0900_FSKT_DELTAF1 0xf173000f
 
 /*FSKTDELTAF0*/
-#define R0900_FSKTDELTAF0  0xf174
-#define F0900_FSKT_DELTAF0  0xf17400ff
+#define R0900_FSKTDELTAF0 0xf174
+#define F0900_FSKT_DELTAF0 0xf17400ff
 
 /*FSKTCTRL*/
-#define R0900_FSKTCTRL  0xf175
-#define F0900_FSKT_EN_SGN  0xf1750040
-#define F0900_FSKT_MOD_SGN  0xf1750020
-#define F0900_FSKT_MOD_EN  0xf175001c
-#define F0900_FSKT_DACMODE  0xf1750003
+#define R0900_FSKTCTRL 0xf175
+#define F0900_FSKT_EN_SGN 0xf1750040
+#define F0900_FSKT_MOD_SGN 0xf1750020
+#define F0900_FSKT_MOD_EN 0xf175001c
+#define F0900_FSKT_DACMODE 0xf1750003
 
 /*FSKRFC2*/
-#define R0900_FSKRFC2  0xf176
-#define F0900_FSKR_DETSGN  0xf1760040
-#define F0900_FSKR_OUTSGN  0xf1760020
-#define F0900_FSKR_KAGC  0xf176001c
-#define F0900_FSKR_CAR2  0xf1760003
+#define R0900_FSKRFC2 0xf176
+#define F0900_FSKR_DETSGN 0xf1760040
+#define F0900_FSKR_OUTSGN 0xf1760020
+#define F0900_FSKR_KAGC 0xf176001c
+#define F0900_FSKR_CAR2 0xf1760003
 
 /*FSKRFC1*/
-#define R0900_FSKRFC1  0xf177
-#define F0900_FSKR_CAR1  0xf17700ff
+#define R0900_FSKRFC1 0xf177
+#define F0900_FSKR_CAR1 0xf17700ff
 
 /*FSKRFC0*/
-#define R0900_FSKRFC0  0xf178
-#define F0900_FSKR_CAR0  0xf17800ff
+#define R0900_FSKRFC0 0xf178
+#define F0900_FSKR_CAR0 0xf17800ff
 
 /*FSKRK1*/
-#define R0900_FSKRK1  0xf179
-#define F0900_FSKR_K1_EXP  0xf17900e0
-#define F0900_FSKR_K1_MANT  0xf179001f
+#define R0900_FSKRK1 0xf179
+#define F0900_FSKR_K1_EXP 0xf17900e0
+#define F0900_FSKR_K1_MANT 0xf179001f
 
 /*FSKRK2*/
-#define R0900_FSKRK2  0xf17a
-#define F0900_FSKR_K2_EXP  0xf17a00e0
-#define F0900_FSKR_K2_MANT  0xf17a001f
+#define R0900_FSKRK2 0xf17a
+#define F0900_FSKR_K2_EXP 0xf17a00e0
+#define F0900_FSKR_K2_MANT 0xf17a001f
 
 /*FSKRAGCR*/
-#define R0900_FSKRAGCR  0xf17b
-#define F0900_FSKR_OUTCTL  0xf17b00c0
-#define F0900_FSKR_AGC_REF  0xf17b003f
+#define R0900_FSKRAGCR 0xf17b
+#define F0900_FSKR_OUTCTL 0xf17b00c0
+#define F0900_FSKR_AGC_REF 0xf17b003f
 
 /*FSKRAGC*/
-#define R0900_FSKRAGC  0xf17c
-#define F0900_FSKR_AGC_ACCU  0xf17c00ff
+#define R0900_FSKRAGC 0xf17c
+#define F0900_FSKR_AGC_ACCU 0xf17c00ff
 
 /*FSKRALPHA*/
-#define R0900_FSKRALPHA  0xf17d
-#define F0900_FSKR_ALPHA_EXP  0xf17d001c
-#define F0900_FSKR_ALPHA_M  0xf17d0003
+#define R0900_FSKRALPHA 0xf17d
+#define F0900_FSKR_ALPHA_EXP 0xf17d001c
+#define F0900_FSKR_ALPHA_M 0xf17d0003
 
 /*FSKRPLTH1*/
-#define R0900_FSKRPLTH1  0xf17e
-#define F0900_FSKR_BETA  0xf17e00f0
-#define F0900_FSKR_PLL_TRESH1  0xf17e000f
+#define R0900_FSKRPLTH1 0xf17e
+#define F0900_FSKR_BETA 0xf17e00f0
+#define F0900_FSKR_PLL_TRESH1 0xf17e000f
 
 /*FSKRPLTH0*/
-#define R0900_FSKRPLTH0  0xf17f
-#define F0900_FSKR_PLL_TRESH0  0xf17f00ff
+#define R0900_FSKRPLTH0 0xf17f
+#define F0900_FSKR_PLL_TRESH0 0xf17f00ff
 
 /*FSKRDF1*/
-#define R0900_FSKRDF1  0xf180
-#define F0900_FSKR_OUT  0xf1800080
-#define F0900_FSKR_DELTAF1  0xf180001f
+#define R0900_FSKRDF1 0xf180
+#define F0900_FSKR_OUT 0xf1800080
+#define F0900_FSKR_DELTAF1 0xf180001f
 
 /*FSKRDF0*/
-#define R0900_FSKRDF0  0xf181
-#define F0900_FSKR_DELTAF0  0xf18100ff
+#define R0900_FSKRDF0 0xf181
+#define F0900_FSKR_DELTAF0 0xf18100ff
 
 /*FSKRSTEPP*/
-#define R0900_FSKRSTEPP  0xf182
-#define F0900_FSKR_STEP_PLUS  0xf18200ff
+#define R0900_FSKRSTEPP 0xf182
+#define F0900_FSKR_STEP_PLUS 0xf18200ff
 
 /*FSKRSTEPM*/
-#define R0900_FSKRSTEPM  0xf183
-#define F0900_FSKR_STEP_MINUS  0xf18300ff
+#define R0900_FSKRSTEPM 0xf183
+#define F0900_FSKR_STEP_MINUS 0xf18300ff
 
 /*FSKRDET1*/
-#define R0900_FSKRDET1  0xf184
-#define F0900_FSKR_DETECT  0xf1840080
-#define F0900_FSKR_CARDET_ACCU1  0xf184000f
+#define R0900_FSKRDET1 0xf184
+#define F0900_FSKR_DETECT 0xf1840080
+#define F0900_FSKR_CARDET_ACCU1 0xf184000f
 
 /*FSKRDET0*/
-#define R0900_FSKRDET0  0xf185
-#define F0900_FSKR_CARDET_ACCU0  0xf18500ff
+#define R0900_FSKRDET0 0xf185
+#define F0900_FSKR_CARDET_ACCU0 0xf18500ff
 
 /*FSKRDTH1*/
-#define R0900_FSKRDTH1  0xf186
-#define F0900_FSKR_CARLOSS_THRESH1  0xf18600f0
-#define F0900_FSKR_CARDET_THRESH1  0xf186000f
+#define R0900_FSKRDTH1 0xf186
+#define F0900_FSKR_CARLOSS_THRESH1 0xf18600f0
+#define F0900_FSKR_CARDET_THRESH1 0xf186000f
 
 /*FSKRDTH0*/
-#define R0900_FSKRDTH0  0xf187
-#define F0900_FSKR_CARDET_THRESH0  0xf18700ff
+#define R0900_FSKRDTH0 0xf187
+#define F0900_FSKR_CARDET_THRESH0 0xf18700ff
 
 /*FSKRLOSS*/
-#define R0900_FSKRLOSS  0xf188
-#define F0900_FSKR_CARLOSS_THRESH0  0xf18800ff
+#define R0900_FSKRLOSS 0xf188
+#define F0900_FSKR_CARLOSS_THRESH0 0xf18800ff
 
 /*P2_DISTXCTL*/
-#define R0900_P2_DISTXCTL  0xf190
-#define F0900_P2_TIM_OFF  0xf1900080
-#define F0900_P2_DISEQC_RESET  0xf1900040
-#define F0900_P2_TIM_CMD  0xf1900030
-#define F0900_P2_DIS_PRECHARGE  0xf1900008
-#define F0900_P2_DISTX_MODE  0xf1900007
+#define R0900_P2_DISTXCTL 0xf190
+#define F0900_P2_TIM_OFF 0xf1900080
+#define F0900_P2_DISEQC_RESET 0xf1900040
+#define F0900_P2_TIM_CMD 0xf1900030
+#define F0900_P2_DIS_PRECHARGE 0xf1900008
+#define F0900_P2_DISTX_MODE 0xf1900007
 
 /*P2_DISRXCTL*/
-#define R0900_P2_DISRXCTL  0xf191
-#define F0900_P2_RECEIVER_ON  0xf1910080
-#define F0900_P2_IGNO_SHORT22K  0xf1910040
-#define F0900_P2_ONECHIP_TRX  0xf1910020
-#define F0900_P2_EXT_ENVELOP  0xf1910010
-#define F0900_P2_PIN_SELECT  0xf191000c
-#define F0900_P2_IRQ_RXEND  0xf1910002
-#define F0900_P2_IRQ_4NBYTES  0xf1910001
+#define R0900_P2_DISRXCTL 0xf191
+#define F0900_P2_RECEIVER_ON 0xf1910080
+#define F0900_P2_IGNO_SHORT22K 0xf1910040
+#define F0900_P2_ONECHIP_TRX 0xf1910020
+#define F0900_P2_EXT_ENVELOP 0xf1910010
+#define F0900_P2_PIN_SELECT0 0xf191000c
+#define F0900_P2_IRQ_RXEND 0xf1910002
+#define F0900_P2_IRQ_4NBYTES 0xf1910001
 
 /*P2_DISRX_ST0*/
-#define R0900_P2_DISRX_ST0  0xf194
-#define F0900_P2_RX_END  0xf1940080
-#define F0900_P2_RX_ACTIVE  0xf1940040
-#define F0900_P2_SHORT_22KHZ  0xf1940020
-#define F0900_P2_CONT_TONE  0xf1940010
-#define F0900_P2_FIFO_4BREADY  0xf1940008
-#define F0900_P2_FIFO_EMPTY  0xf1940004
-#define F0900_P2_ABORT_DISRX  0xf1940001
+#define R0900_P2_DISRX_ST0 0xf194
+#define F0900_P2_RX_END 0xf1940080
+#define F0900_P2_RX_ACTIVE 0xf1940040
+#define F0900_P2_SHORT_22KHZ 0xf1940020
+#define F0900_P2_CONT_TONE 0xf1940010
+#define F0900_P2_FIFO_4BREADY 0xf1940008
+#define F0900_P2_FIFO_EMPTY 0xf1940004
+#define F0900_P2_ABORT_DISRX 0xf1940001
 
 /*P2_DISRX_ST1*/
-#define R0900_P2_DISRX_ST1  0xf195
-#define F0900_P2_RX_FAIL  0xf1950080
-#define F0900_P2_FIFO_PARITYFAIL  0xf1950040
-#define F0900_P2_RX_NONBYTE  0xf1950020
-#define F0900_P2_FIFO_OVERFLOW  0xf1950010
-#define F0900_P2_FIFO_BYTENBR  0xf195000f
+#define R0900_P2_DISRX_ST1 0xf195
+#define F0900_P2_RX_FAIL 0xf1950080
+#define F0900_P2_FIFO_PARITYFAIL 0xf1950040
+#define F0900_P2_RX_NONBYTE 0xf1950020
+#define F0900_P2_FIFO_OVERFLOW 0xf1950010
+#define F0900_P2_FIFO_BYTENBR 0xf195000f
 
 /*P2_DISRXDATA*/
-#define R0900_P2_DISRXDATA  0xf196
-#define F0900_P2_DISRX_DATA  0xf19600ff
+#define R0900_P2_DISRXDATA 0xf196
+#define F0900_P2_DISRX_DATA 0xf19600ff
 
 /*P2_DISTXDATA*/
-#define R0900_P2_DISTXDATA  0xf197
-#define F0900_P2_DISEQC_FIFO  0xf19700ff
+#define R0900_P2_DISTXDATA 0xf197
+#define F0900_P2_DISEQC_FIFO 0xf19700ff
 
 /*P2_DISTXSTATUS*/
-#define R0900_P2_DISTXSTATUS  0xf198
-#define F0900_P2_TX_FAIL  0xf1980080
-#define F0900_P2_FIFO_FULL  0xf1980040
-#define F0900_P2_TX_IDLE  0xf1980020
-#define F0900_P2_GAP_BURST  0xf1980010
-#define F0900_P2_TXFIFO_BYTES  0xf198000f
+#define R0900_P2_DISTXSTATUS 0xf198
+#define F0900_P2_TX_FAIL 0xf1980080
+#define F0900_P2_FIFO_FULL 0xf1980040
+#define F0900_P2_TX_IDLE 0xf1980020
+#define F0900_P2_GAP_BURST 0xf1980010
+#define F0900_P2_TXFIFO_BYTES 0xf198000f
 
 /*P2_F22TX*/
-#define R0900_P2_F22TX  0xf199
-#define F0900_P2_F22_REG  0xf19900ff
+#define R0900_P2_F22TX 0xf199
+#define F0900_P2_F22_REG 0xf19900ff
 
 /*P2_F22RX*/
-#define R0900_P2_F22RX  0xf19a
-#define F0900_P2_F22RX_REG  0xf19a00ff
+#define R0900_P2_F22RX 0xf19a
+#define F0900_P2_F22RX_REG 0xf19a00ff
 
 /*P2_ACRPRESC*/
-#define R0900_P2_ACRPRESC  0xf19c
-#define F0900_P2_ACR_CODFRDY  0xf19c0008
-#define F0900_P2_ACR_PRESC  0xf19c0007
+#define R0900_P2_ACRPRESC 0xf19c
+#define F0900_P2_ACR_PRESC 0xf19c0007
 
 /*P2_ACRDIV*/
-#define R0900_P2_ACRDIV  0xf19d
-#define F0900_P2_ACR_DIV  0xf19d00ff
+#define R0900_P2_ACRDIV 0xf19d
+#define F0900_P2_ACR_DIV 0xf19d00ff
 
 /*P1_DISTXCTL*/
-#define R0900_P1_DISTXCTL  0xf1a0
-#define F0900_P1_TIM_OFF  0xf1a00080
-#define F0900_P1_DISEQC_RESET  0xf1a00040
-#define F0900_P1_TIM_CMD  0xf1a00030
-#define F0900_P1_DIS_PRECHARGE  0xf1a00008
-#define F0900_P1_DISTX_MODE  0xf1a00007
+#define R0900_P1_DISTXCTL 0xf1a0
+#define DISTXCTL shiftx(R0900_P1_DISTXCTL, demod, 0x10)
+#define F0900_P1_TIM_OFF 0xf1a00080
+#define F0900_P1_DISEQC_RESET 0xf1a00040
+#define DISEQC_RESET shiftx(F0900_P1_DISEQC_RESET, demod, 0x100000)
+#define F0900_P1_TIM_CMD 0xf1a00030
+#define F0900_P1_DIS_PRECHARGE 0xf1a00008
+#define DIS_PRECHARGE shiftx(F0900_P1_DIS_PRECHARGE, demod, 0x100000)
+#define F0900_P1_DISTX_MODE 0xf1a00007
+#define DISTX_MODE shiftx(F0900_P1_DISTX_MODE, demod, 0x100000)
 
 /*P1_DISRXCTL*/
-#define R0900_P1_DISRXCTL  0xf1a1
-#define F0900_P1_RECEIVER_ON  0xf1a10080
-#define F0900_P1_IGNO_SHORT22K  0xf1a10040
-#define F0900_P1_ONECHIP_TRX  0xf1a10020
-#define F0900_P1_EXT_ENVELOP  0xf1a10010
-#define F0900_P1_PIN_SELECT  0xf1a1000c
-#define F0900_P1_IRQ_RXEND  0xf1a10002
-#define F0900_P1_IRQ_4NBYTES  0xf1a10001
+#define R0900_P1_DISRXCTL 0xf1a1
+#define DISRXCTL shiftx(R0900_P1_DISRXCTL, demod, 0x10)
+#define F0900_P1_RECEIVER_ON 0xf1a10080
+#define F0900_P1_IGNO_SHORT22K 0xf1a10040
+#define F0900_P1_ONECHIP_TRX 0xf1a10020
+#define F0900_P1_EXT_ENVELOP 0xf1a10010
+#define F0900_P1_PIN_SELECT0 0xf1a1000c
+#define F0900_P1_IRQ_RXEND 0xf1a10002
+#define F0900_P1_IRQ_4NBYTES 0xf1a10001
 
 /*P1_DISRX_ST0*/
-#define R0900_P1_DISRX_ST0  0xf1a4
-#define F0900_P1_RX_END  0xf1a40080
-#define F0900_P1_RX_ACTIVE  0xf1a40040
-#define F0900_P1_SHORT_22KHZ  0xf1a40020
-#define F0900_P1_CONT_TONE  0xf1a40010
-#define F0900_P1_FIFO_4BREADY  0xf1a40008
-#define F0900_P1_FIFO_EMPTY  0xf1a40004
-#define F0900_P1_ABORT_DISRX  0xf1a40001
+#define R0900_P1_DISRX_ST0 0xf1a4
+#define DISRX_ST0 shiftx(R0900_P1_DISRX_ST0, demod, 0x10)
+#define F0900_P1_RX_END 0xf1a40080
+#define RX_END shiftx(F0900_P1_RX_END, demod, 0x100000)
+#define F0900_P1_RX_ACTIVE 0xf1a40040
+#define F0900_P1_SHORT_22KHZ 0xf1a40020
+#define F0900_P1_CONT_TONE 0xf1a40010
+#define F0900_P1_FIFO_4BREADY 0xf1a40008
+#define F0900_P1_FIFO_EMPTY 0xf1a40004
+#define F0900_P1_ABORT_DISRX 0xf1a40001
 
 /*P1_DISRX_ST1*/
-#define R0900_P1_DISRX_ST1  0xf1a5
-#define F0900_P1_RX_FAIL  0xf1a50080
-#define F0900_P1_FIFO_PARITYFAIL  0xf1a50040
-#define F0900_P1_RX_NONBYTE  0xf1a50020
-#define F0900_P1_FIFO_OVERFLOW  0xf1a50010
-#define F0900_P1_FIFO_BYTENBR  0xf1a5000f
+#define R0900_P1_DISRX_ST1 0xf1a5
+#define DISRX_ST1 shiftx(R0900_P1_DISRX_ST1, demod, 0x10)
+#define F0900_P1_RX_FAIL 0xf1a50080
+#define F0900_P1_FIFO_PARITYFAIL 0xf1a50040
+#define F0900_P1_RX_NONBYTE 0xf1a50020
+#define F0900_P1_FIFO_OVERFLOW 0xf1a50010
+#define F0900_P1_FIFO_BYTENBR 0xf1a5000f
+#define FIFO_BYTENBR shiftx(F0900_P1_FIFO_BYTENBR, demod, 0x100000)
 
 /*P1_DISRXDATA*/
-#define R0900_P1_DISRXDATA  0xf1a6
-#define F0900_P1_DISRX_DATA  0xf1a600ff
+#define R0900_P1_DISRXDATA 0xf1a6
+#define DISRXDATA shiftx(R0900_P1_DISRXDATA, demod, 0x10)
+#define F0900_P1_DISRX_DATA 0xf1a600ff
 
 /*P1_DISTXDATA*/
-#define R0900_P1_DISTXDATA  0xf1a7
-#define F0900_P1_DISEQC_FIFO  0xf1a700ff
+#define R0900_P1_DISTXDATA 0xf1a7
+#define DISTXDATA shiftx(R0900_P1_DISTXDATA, demod, 0x10)
+#define F0900_P1_DISEQC_FIFO 0xf1a700ff
 
 /*P1_DISTXSTATUS*/
-#define R0900_P1_DISTXSTATUS  0xf1a8
-#define F0900_P1_TX_FAIL  0xf1a80080
-#define F0900_P1_FIFO_FULL  0xf1a80040
-#define F0900_P1_TX_IDLE  0xf1a80020
-#define F0900_P1_GAP_BURST  0xf1a80010
-#define F0900_P1_TXFIFO_BYTES  0xf1a8000f
+#define R0900_P1_DISTXSTATUS 0xf1a8
+#define F0900_P1_TX_FAIL 0xf1a80080
+#define F0900_P1_FIFO_FULL 0xf1a80040
+#define FIFO_FULL shiftx(F0900_P1_FIFO_FULL, demod, 0x100000)
+#define F0900_P1_TX_IDLE 0xf1a80020
+#define TX_IDLE shiftx(F0900_P1_TX_IDLE, demod, 0x100000)
+#define F0900_P1_GAP_BURST 0xf1a80010
+#define F0900_P1_TXFIFO_BYTES 0xf1a8000f
 
 /*P1_F22TX*/
-#define R0900_P1_F22TX  0xf1a9
-#define F0900_P1_F22_REG  0xf1a900ff
+#define R0900_P1_F22TX 0xf1a9
+#define F22TX shiftx(R0900_P1_F22TX, demod, 0x10)
+#define F0900_P1_F22_REG 0xf1a900ff
 
 /*P1_F22RX*/
-#define R0900_P1_F22RX  0xf1aa
-#define F0900_P1_F22RX_REG  0xf1aa00ff
+#define R0900_P1_F22RX 0xf1aa
+#define F22RX shiftx(R0900_P1_F22RX, demod, 0x10)
+#define F0900_P1_F22RX_REG 0xf1aa00ff
 
 /*P1_ACRPRESC*/
-#define R0900_P1_ACRPRESC  0xf1ac
-#define F0900_P1_ACR_CODFRDY  0xf1ac0008
-#define F0900_P1_ACR_PRESC  0xf1ac0007
+#define R0900_P1_ACRPRESC 0xf1ac
+#define ACRPRESC shiftx(R0900_P1_ACRPRESC, demod, 0x10)
+#define F0900_P1_ACR_PRESC 0xf1ac0007
 
 /*P1_ACRDIV*/
-#define R0900_P1_ACRDIV  0xf1ad
-#define F0900_P1_ACR_DIV  0xf1ad00ff
+#define R0900_P1_ACRDIV 0xf1ad
+#define ACRDIV shiftx(R0900_P1_ACRDIV, demod, 0x10)
+#define F0900_P1_ACR_DIV 0xf1ad00ff
 
 /*NCOARSE*/
-#define R0900_NCOARSE  0xf1b3
-#define F0900_M_DIV  0xf1b300ff
+#define R0900_NCOARSE 0xf1b3
+#define F0900_M_DIV 0xf1b300ff
 
 /*SYNTCTRL*/
-#define R0900_SYNTCTRL  0xf1b6
-#define F0900_STANDBY  0xf1b60080
-#define F0900_BYPASSPLLCORE  0xf1b60040
-#define F0900_SELX1RATIO  0xf1b60020
-#define F0900_I2C_TUD  0xf1b60010
-#define F0900_STOP_PLL  0xf1b60008
-#define F0900_BYPASSPLLFSK  0xf1b60004
-#define F0900_SELOSCI  0xf1b60002
-#define F0900_BYPASSPLLADC  0xf1b60001
+#define R0900_SYNTCTRL 0xf1b6
+#define F0900_STANDBY 0xf1b60080
+#define F0900_BYPASSPLLCORE 0xf1b60040
+#define F0900_SELX1RATIO 0xf1b60020
+#define F0900_STOP_PLL 0xf1b60008
+#define F0900_BYPASSPLLFSK 0xf1b60004
+#define F0900_SELOSCI 0xf1b60002
+#define F0900_BYPASSPLLADC 0xf1b60001
 
 /*FILTCTRL*/
-#define R0900_FILTCTRL  0xf1b7
-#define F0900_INV_CLK135  0xf1b70080
-#define F0900_PERM_BYPDIS  0xf1b70040
-#define F0900_SEL_FSKCKDIV  0xf1b70004
-#define F0900_INV_CLKFSK  0xf1b70002
-#define F0900_BYPASS_APPLI  0xf1b70001
+#define R0900_FILTCTRL 0xf1b7
+#define F0900_INV_CLK135 0xf1b70080
+#define F0900_SEL_FSKCKDIV 0xf1b70004
+#define F0900_INV_CLKFSK 0xf1b70002
+#define F0900_BYPASS_APPLI 0xf1b70001
 
 /*PLLSTAT*/
-#define R0900_PLLSTAT  0xf1b8
-#define F0900_ACM_SEL  0xf1b80080
-#define F0900_DTV_SEL  0xf1b80040
-#define F0900_PLLLOCK  0xf1b80001
+#define R0900_PLLSTAT 0xf1b8
+#define F0900_PLLLOCK 0xf1b80001
 
 /*STOPCLK1*/
-#define R0900_STOPCLK1  0xf1c2
-#define F0900_STOP_CLKPKDT2  0xf1c20040
-#define F0900_STOP_CLKPKDT1  0xf1c20020
-#define F0900_STOP_CLKFEC  0xf1c20010
-#define F0900_STOP_CLKADCI2  0xf1c20008
-#define F0900_INV_CLKADCI2  0xf1c20004
-#define F0900_STOP_CLKADCI1  0xf1c20002
-#define F0900_INV_CLKADCI1  0xf1c20001
+#define R0900_STOPCLK1 0xf1c2
+#define F0900_STOP_CLKPKDT2 0xf1c20040
+#define F0900_STOP_CLKPKDT1 0xf1c20020
+#define F0900_STOP_CLKFEC 0xf1c20010
+#define F0900_STOP_CLKADCI2 0xf1c20008
+#define F0900_INV_CLKADCI2 0xf1c20004
+#define F0900_STOP_CLKADCI1 0xf1c20002
+#define F0900_INV_CLKADCI1 0xf1c20001
 
 /*STOPCLK2*/
-#define R0900_STOPCLK2  0xf1c3
-#define F0900_STOP_CLKSAMP2  0xf1c30010
-#define F0900_STOP_CLKSAMP1  0xf1c30008
-#define F0900_STOP_CLKVIT2  0xf1c30004
-#define F0900_STOP_CLKVIT1  0xf1c30002
-#define F0900_STOP_CLKTS  0xf1c30001
+#define R0900_STOPCLK2 0xf1c3
+#define F0900_STOP_CLKSAMP2 0xf1c30010
+#define F0900_STOP_CLKSAMP1 0xf1c30008
+#define F0900_STOP_CLKVIT2 0xf1c30004
+#define F0900_STOP_CLKVIT1 0xf1c30002
+#define STOP_CLKVIT shiftx(F0900_STOP_CLKVIT1, demod, -2)
+#define F0900_STOP_CLKTS 0xf1c30001
 
 /*TSTTNR0*/
-#define R0900_TSTTNR0  0xf1df
-#define F0900_SEL_FSK  0xf1df0080
-#define F0900_FSK_PON  0xf1df0004
-#define F0900_FSK_OPENLOOP  0xf1df0002
+#define R0900_TSTTNR0 0xf1df
+#define F0900_SEL_FSK 0xf1df0080
+#define F0900_FSK_PON 0xf1df0004
 
 /*TSTTNR1*/
-#define R0900_TSTTNR1  0xf1e0
-#define F0900_BYPASS_ADC1  0xf1e00080
-#define F0900_INVADC1_CKOUT  0xf1e00040
-#define F0900_SELIQSRC1  0xf1e00030
-#define F0900_ADC1_PON  0xf1e00002
-#define F0900_ADC1_INMODE  0xf1e00001
+#define R0900_TSTTNR1 0xf1e0
+#define F0900_ADC1_PON 0xf1e00002
+#define F0900_ADC1_INMODE 0xf1e00001
 
 /*TSTTNR2*/
-#define R0900_TSTTNR2  0xf1e1
-#define F0900_DISEQC1_PON  0xf1e10020
-#define F0900_DISEQC1_TEST  0xf1e1001f
+#define R0900_TSTTNR2 0xf1e1
+#define F0900_DISEQC1_PON 0xf1e10020
 
 /*TSTTNR3*/
-#define R0900_TSTTNR3  0xf1e2
-#define F0900_BYPASS_ADC2  0xf1e20080
-#define F0900_INVADC2_CKOUT  0xf1e20040
-#define F0900_SELIQSRC2  0xf1e20030
-#define F0900_ADC2_PON  0xf1e20002
-#define F0900_ADC2_INMODE  0xf1e20001
+#define R0900_TSTTNR3 0xf1e2
+#define F0900_ADC2_PON 0xf1e20002
+#define F0900_ADC2_INMODE 0xf1e20001
 
 /*TSTTNR4*/
-#define R0900_TSTTNR4  0xf1e3
-#define F0900_DISEQC2_PON  0xf1e30020
-#define F0900_DISEQC2_TEST  0xf1e3001f
+#define R0900_TSTTNR4 0xf1e3
+#define F0900_DISEQC2_PON 0xf1e30020
 
 /*P2_IQCONST*/
-#define R0900_P2_IQCONST  0xf200
-#define F0900_P2_CONSTEL_SELECT  0xf2000060
-#define F0900_P2_IQSYMB_SEL  0xf200001f
+#define R0900_P2_IQCONST 0xf200
+#define F0900_P2_CONSTEL_SELECT 0xf2000060
+#define F0900_P2_IQSYMB_SEL 0xf200001f
 
 /*P2_NOSCFG*/
-#define R0900_P2_NOSCFG  0xf201
-#define F0900_P2_DUMMYPL_NOSDATA  0xf2010020
-#define F0900_P2_NOSPLH_BETA  0xf2010018
-#define F0900_P2_NOSDATA_BETA  0xf2010007
+#define R0900_P2_NOSCFG 0xf201
+#define F0900_P2_DUMMYPL_NOSDATA 0xf2010020
+#define F0900_P2_NOSPLH_BETA 0xf2010018
+#define F0900_P2_NOSDATA_BETA 0xf2010007
 
 /*P2_ISYMB*/
-#define R0900_P2_ISYMB  0xf202
-#define F0900_P2_I_SYMBOL  0xf20201ff
+#define R0900_P2_ISYMB 0xf202
+#define F0900_P2_I_SYMBOL 0xf20201ff
 
 /*P2_QSYMB*/
-#define R0900_P2_QSYMB  0xf203
-#define F0900_P2_Q_SYMBOL  0xf20301ff
+#define R0900_P2_QSYMB 0xf203
+#define F0900_P2_Q_SYMBOL 0xf20301ff
 
 /*P2_AGC1CFG*/
-#define R0900_P2_AGC1CFG  0xf204
-#define F0900_P2_DC_FROZEN  0xf2040080
-#define F0900_P2_DC_CORRECT  0xf2040040
-#define F0900_P2_AMM_FROZEN  0xf2040020
-#define F0900_P2_AMM_CORRECT  0xf2040010
-#define F0900_P2_QUAD_FROZEN  0xf2040008
-#define F0900_P2_QUAD_CORRECT  0xf2040004
-#define F0900_P2_DCCOMP_SLOW  0xf2040002
-#define F0900_P2_IQMISM_SLOW  0xf2040001
+#define R0900_P2_AGC1CFG 0xf204
+#define F0900_P2_DC_FROZEN 0xf2040080
+#define F0900_P2_DC_CORRECT 0xf2040040
+#define F0900_P2_AMM_FROZEN 0xf2040020
+#define F0900_P2_AMM_CORRECT 0xf2040010
+#define F0900_P2_QUAD_FROZEN 0xf2040008
+#define F0900_P2_QUAD_CORRECT 0xf2040004
 
 /*P2_AGC1CN*/
-#define R0900_P2_AGC1CN  0xf206
-#define F0900_P2_AGC1_LOCKED  0xf2060080
-#define F0900_P2_AGC1_OVERFLOW  0xf2060040
-#define F0900_P2_AGC1_NOSLOWLK  0xf2060020
-#define F0900_P2_AGC1_MINPOWER  0xf2060010
-#define F0900_P2_AGCOUT_FAST  0xf2060008
-#define F0900_P2_AGCIQ_BETA  0xf2060007
+#define R0900_P2_AGC1CN 0xf206
+#define F0900_P2_AGC1_LOCKED 0xf2060080
+#define F0900_P2_AGC1_MINPOWER 0xf2060010
+#define F0900_P2_AGCOUT_FAST 0xf2060008
+#define F0900_P2_AGCIQ_BETA 0xf2060007
 
 /*P2_AGC1REF*/
-#define R0900_P2_AGC1REF  0xf207
-#define F0900_P2_AGCIQ_REF  0xf20700ff
+#define R0900_P2_AGC1REF 0xf207
+#define F0900_P2_AGCIQ_REF 0xf20700ff
 
 /*P2_IDCCOMP*/
-#define R0900_P2_IDCCOMP  0xf208
-#define F0900_P2_IAVERAGE_ADJ  0xf20801ff
+#define R0900_P2_IDCCOMP 0xf208
+#define F0900_P2_IAVERAGE_ADJ 0xf20801ff
 
 /*P2_QDCCOMP*/
-#define R0900_P2_QDCCOMP  0xf209
-#define F0900_P2_QAVERAGE_ADJ  0xf20901ff
+#define R0900_P2_QDCCOMP 0xf209
+#define F0900_P2_QAVERAGE_ADJ 0xf20901ff
 
 /*P2_POWERI*/
-#define R0900_P2_POWERI  0xf20a
-#define F0900_P2_POWER_I  0xf20a00ff
+#define R0900_P2_POWERI 0xf20a
+#define F0900_P2_POWER_I 0xf20a00ff
 
 /*P2_POWERQ*/
-#define R0900_P2_POWERQ  0xf20b
-#define F0900_P2_POWER_Q  0xf20b00ff
+#define R0900_P2_POWERQ 0xf20b
+#define F0900_P2_POWER_Q 0xf20b00ff
 
 /*P2_AGC1AMM*/
-#define R0900_P2_AGC1AMM  0xf20c
-#define F0900_P2_AMM_VALUE  0xf20c00ff
+#define R0900_P2_AGC1AMM 0xf20c
+#define F0900_P2_AMM_VALUE 0xf20c00ff
 
 /*P2_AGC1QUAD*/
-#define R0900_P2_AGC1QUAD  0xf20d
-#define F0900_P2_QUAD_VALUE  0xf20d01ff
+#define R0900_P2_AGC1QUAD 0xf20d
+#define F0900_P2_QUAD_VALUE 0xf20d01ff
 
 /*P2_AGCIQIN1*/
-#define R0900_P2_AGCIQIN1  0xf20e
-#define F0900_P2_AGCIQ_VALUE1  0xf20e00ff
+#define R0900_P2_AGCIQIN1 0xf20e
+#define F0900_P2_AGCIQ_VALUE1 0xf20e00ff
 
 /*P2_AGCIQIN0*/
-#define R0900_P2_AGCIQIN0  0xf20f
-#define F0900_P2_AGCIQ_VALUE0  0xf20f00ff
+#define R0900_P2_AGCIQIN0 0xf20f
+#define F0900_P2_AGCIQ_VALUE0 0xf20f00ff
 
 /*P2_DEMOD*/
-#define R0900_P2_DEMOD  0xf210
-#define F0900_P2_DEMOD_STOP  0xf2100040
-#define F0900_P2_SPECINV_CONTROL  0xf2100030
-#define F0900_P2_FORCE_ENASAMP  0xf2100008
-#define F0900_P2_MANUAL_ROLLOFF  0xf2100004
-#define F0900_P2_ROLLOFF_CONTROL  0xf2100003
+#define R0900_P2_DEMOD 0xf210
+#define F0900_P2_MANUALS2_ROLLOFF 0xf2100080
+#define F0900_P2_SPECINV_CONTROL 0xf2100030
+#define F0900_P2_FORCE_ENASAMP 0xf2100008
+#define F0900_P2_MANUALSX_ROLLOFF 0xf2100004
+#define F0900_P2_ROLLOFF_CONTROL 0xf2100003
 
 /*P2_DMDMODCOD*/
-#define R0900_P2_DMDMODCOD  0xf211
-#define F0900_P2_MANUAL_MODCOD  0xf2110080
-#define F0900_P2_DEMOD_MODCOD  0xf211007c
-#define F0900_P2_DEMOD_TYPE  0xf2110003
+#define R0900_P2_DMDMODCOD 0xf211
+#define F0900_P2_MANUAL_MODCOD 0xf2110080
+#define F0900_P2_DEMOD_MODCOD 0xf211007c
+#define F0900_P2_DEMOD_TYPE 0xf2110003
 
 /*P2_DSTATUS*/
-#define R0900_P2_DSTATUS  0xf212
-#define F0900_P2_CAR_LOCK  0xf2120080
-#define F0900_P2_TMGLOCK_QUALITY  0xf2120060
-#define F0900_P2_SDVBS1_ENABLE  0xf2120010
-#define F0900_P2_LOCK_DEFINITIF  0xf2120008
-#define F0900_P2_TIMING_IS_LOCKED  0xf2120004
-#define F0900_P2_COARSE_TMGLOCK  0xf2120002
-#define F0900_P2_COARSE_CARLOCK  0xf2120001
+#define R0900_P2_DSTATUS 0xf212
+#define F0900_P2_CAR_LOCK 0xf2120080
+#define F0900_P2_TMGLOCK_QUALITY 0xf2120060
+#define F0900_P2_LOCK_DEFINITIF 0xf2120008
+#define F0900_P2_OVADC_DETECT 0xf2120001
 
 /*P2_DSTATUS2*/
-#define R0900_P2_DSTATUS2  0xf213
-#define F0900_P2_DEMOD_DELOCK  0xf2130080
-#define F0900_P2_DEMOD_TIMEOUT  0xf2130040
-#define F0900_P2_MODCODRQ_SYNCTAG  0xf2130020
-#define F0900_P2_POLYPH_SATEVENT  0xf2130010
-#define F0900_P2_AGC1_NOSIGNALACK  0xf2130008
-#define F0900_P2_AGC2_OVERFLOW  0xf2130004
-#define F0900_P2_CFR_OVERFLOW  0xf2130002
-#define F0900_P2_GAMMA_OVERUNDER  0xf2130001
+#define R0900_P2_DSTATUS2 0xf213
+#define F0900_P2_DEMOD_DELOCK 0xf2130080
+#define F0900_P2_AGC1_NOSIGNALACK 0xf2130008
+#define F0900_P2_AGC2_OVERFLOW 0xf2130004
+#define F0900_P2_CFR_OVERFLOW 0xf2130002
+#define F0900_P2_GAMMA_OVERUNDER 0xf2130001
 
 /*P2_DMDCFGMD*/
-#define R0900_P2_DMDCFGMD  0xf214
-#define F0900_P2_DVBS2_ENABLE  0xf2140080
-#define F0900_P2_DVBS1_ENABLE  0xf2140040
-#define F0900_P2_CFR_AUTOSCAN  0xf2140020
-#define F0900_P2_SCAN_ENABLE  0xf2140010
-#define F0900_P2_TUN_AUTOSCAN  0xf2140008
-#define F0900_P2_NOFORCE_RELOCK  0xf2140004
-#define F0900_P2_TUN_RNG  0xf2140003
+#define R0900_P2_DMDCFGMD 0xf214
+#define F0900_P2_DVBS2_ENABLE 0xf2140080
+#define F0900_P2_DVBS1_ENABLE 0xf2140040
+#define F0900_P2_SCAN_ENABLE 0xf2140010
+#define F0900_P2_CFR_AUTOSCAN 0xf2140008
+#define F0900_P2_TUN_RNG 0xf2140003
 
 /*P2_DMDCFG2*/
-#define R0900_P2_DMDCFG2  0xf215
-#define F0900_P2_AGC1_WAITLOCK  0xf2150080
-#define F0900_P2_S1S2_SEQUENTIAL  0xf2150040
-#define F0900_P2_OVERFLOW_TIMEOUT  0xf2150020
-#define F0900_P2_SCANFAIL_TIMEOUT  0xf2150010
-#define F0900_P2_DMDTOUT_BACK  0xf2150008
-#define F0900_P2_CARLOCK_S1ENABLE  0xf2150004
-#define F0900_P2_COARSE_LK3MODE  0xf2150002
-#define F0900_P2_COARSE_LK2MODE  0xf2150001
+#define R0900_P2_DMDCFG2 0xf215
+#define F0900_P2_S1S2_SEQUENTIAL 0xf2150040
+#define F0900_P2_INFINITE_RELOCK 0xf2150010
 
 /*P2_DMDISTATE*/
-#define R0900_P2_DMDISTATE  0xf216
-#define F0900_P2_I2C_NORESETDMODE  0xf2160080
-#define F0900_P2_FORCE_ETAPED  0xf2160040
-#define F0900_P2_SDMDRST_DIRCLK  0xf2160020
-#define F0900_P2_I2C_DEMOD_MODE  0xf216001f
+#define R0900_P2_DMDISTATE 0xf216
+#define F0900_P2_I2C_DEMOD_MODE 0xf216001f
 
 /*P2_DMDT0M*/
-#define R0900_P2_DMDT0M  0xf217
-#define F0900_P2_DMDT0_MIN  0xf21700ff
+#define R0900_P2_DMDT0M 0xf217
+#define F0900_P2_DMDT0_MIN 0xf21700ff
 
 /*P2_DMDSTATE*/
-#define R0900_P2_DMDSTATE  0xf21b
-#define F0900_P2_DEMOD_LOCKED  0xf21b0080
-#define F0900_P2_HEADER_MODE  0xf21b0060
-#define F0900_P2_DEMOD_MODE  0xf21b001f
+#define R0900_P2_DMDSTATE 0xf21b
+#define F0900_P2_HEADER_MODE 0xf21b0060
 
 /*P2_DMDFLYW*/
-#define R0900_P2_DMDFLYW  0xf21c
-#define F0900_P2_I2C_IRQVAL  0xf21c00f0
-#define F0900_P2_FLYWHEEL_CPT  0xf21c000f
+#define R0900_P2_DMDFLYW 0xf21c
+#define F0900_P2_I2C_IRQVAL 0xf21c00f0
+#define F0900_P2_FLYWHEEL_CPT 0xf21c000f
 
 /*P2_DSTATUS3*/
-#define R0900_P2_DSTATUS3  0xf21d
-#define F0900_P2_CFR_ZIGZAG  0xf21d0080
-#define F0900_P2_DEMOD_CFGMODE  0xf21d0060
-#define F0900_P2_GAMMA_LOWBAUDRATE  0xf21d0010
-#define F0900_P2_RELOCK_MODE  0xf21d0008
-#define F0900_P2_DEMOD_FAIL  0xf21d0004
-#define F0900_P2_ETAPE1A_DVBXMEM  0xf21d0003
+#define R0900_P2_DSTATUS3 0xf21d
+#define F0900_P2_DEMOD_CFGMODE 0xf21d0060
 
 /*P2_DMDCFG3*/
-#define R0900_P2_DMDCFG3  0xf21e
-#define F0900_P2_DVBS1_TMGWAIT  0xf21e0080
-#define F0900_P2_NO_BWCENTERING  0xf21e0040
-#define F0900_P2_INV_SEQSRCH  0xf21e0020
-#define F0900_P2_DIS_SFRUPLOW_TRK  0xf21e0010
-#define F0900_P2_NOSTOP_FIFOFULL  0xf21e0008
-#define F0900_P2_LOCKTIME_MODE  0xf21e0007
+#define R0900_P2_DMDCFG3 0xf21e
+#define F0900_P2_NOSTOP_FIFOFULL 0xf21e0008
 
 /*P2_DMDCFG4*/
-#define R0900_P2_DMDCFG4  0xf21f
-#define F0900_P2_TUNER_NRELAUNCH  0xf21f0008
-#define F0900_P2_DIS_CLKENABLE  0xf21f0004
-#define F0900_P2_DIS_HDRDIVLOCK  0xf21f0002
-#define F0900_P2_NO_TNRWBINIT  0xf21f0001
+#define R0900_P2_DMDCFG4 0xf21f
+#define F0900_P2_TUNER_NRELAUNCH 0xf21f0008
 
 /*P2_CORRELMANT*/
-#define R0900_P2_CORRELMANT  0xf220
-#define F0900_P2_CORREL_MANT  0xf22000ff
+#define R0900_P2_CORRELMANT 0xf220
+#define F0900_P2_CORREL_MANT 0xf22000ff
 
 /*P2_CORRELABS*/
-#define R0900_P2_CORRELABS  0xf221
-#define F0900_P2_CORREL_ABS  0xf22100ff
+#define R0900_P2_CORRELABS 0xf221
+#define F0900_P2_CORREL_ABS 0xf22100ff
 
 /*P2_CORRELEXP*/
-#define R0900_P2_CORRELEXP  0xf222
-#define F0900_P2_CORREL_ABSEXP  0xf22200f0
-#define F0900_P2_CORREL_EXP  0xf222000f
+#define R0900_P2_CORRELEXP 0xf222
+#define F0900_P2_CORREL_ABSEXP 0xf22200f0
+#define F0900_P2_CORREL_EXP 0xf222000f
 
 /*P2_PLHMODCOD*/
-#define R0900_P2_PLHMODCOD  0xf224
-#define F0900_P2_SPECINV_DEMOD  0xf2240080
-#define F0900_P2_PLH_MODCOD  0xf224007c
-#define F0900_P2_PLH_TYPE  0xf2240003
+#define R0900_P2_PLHMODCOD 0xf224
+#define F0900_P2_SPECINV_DEMOD 0xf2240080
+#define F0900_P2_PLH_MODCOD 0xf224007c
+#define F0900_P2_PLH_TYPE 0xf2240003
 
-/*P2_AGCK32*/
-#define R0900_P2_AGCK32  0xf22b
-#define F0900_P2_R3ADJOFF_32APSK  0xf22b0080
-#define F0900_P2_R2ADJOFF_32APSK  0xf22b0040
-#define F0900_P2_R1ADJOFF_32APSK  0xf22b0020
-#define F0900_P2_RADJ_32APSK  0xf22b001f
+/*P2_DMDREG*/
+#define R0900_P2_DMDREG 0xf225
+#define F0900_P2_DECIM_PLFRAMES 0xf2250001
 
 /*P2_AGC2O*/
-#define R0900_P2_AGC2O  0xf22c
-#define F0900_P2_AGC2REF_ADJUSTING  0xf22c0080
-#define F0900_P2_AGC2_COARSEFAST  0xf22c0040
-#define F0900_P2_AGC2_LKSQRT  0xf22c0020
-#define F0900_P2_AGC2_LKMODE  0xf22c0010
-#define F0900_P2_AGC2_LKEQUA  0xf22c0008
-#define F0900_P2_AGC2_COEF  0xf22c0007
+#define R0900_P2_AGC2O 0xf22c
+#define F0900_P2_AGC2_COEF 0xf22c0007
 
 /*P2_AGC2REF*/
-#define R0900_P2_AGC2REF  0xf22d
-#define F0900_P2_AGC2_REF  0xf22d00ff
+#define R0900_P2_AGC2REF 0xf22d
+#define F0900_P2_AGC2_REF 0xf22d00ff
 
 /*P2_AGC1ADJ*/
-#define R0900_P2_AGC1ADJ  0xf22e
-#define F0900_P2_AGC1ADJ_MANUAL  0xf22e0080
-#define F0900_P2_AGC1_ADJUSTED  0xf22e017f
+#define R0900_P2_AGC1ADJ 0xf22e
+#define F0900_P2_AGC1_ADJUSTED 0xf22e007f
 
 /*P2_AGC2I1*/
-#define R0900_P2_AGC2I1  0xf236
-#define F0900_P2_AGC2_INTEGRATOR1  0xf23600ff
+#define R0900_P2_AGC2I1 0xf236
+#define F0900_P2_AGC2_INTEGRATOR1 0xf23600ff
 
 /*P2_AGC2I0*/
-#define R0900_P2_AGC2I0  0xf237
-#define F0900_P2_AGC2_INTEGRATOR0  0xf23700ff
+#define R0900_P2_AGC2I0 0xf237
+#define F0900_P2_AGC2_INTEGRATOR0 0xf23700ff
 
 /*P2_CARCFG*/
-#define R0900_P2_CARCFG  0xf238
-#define F0900_P2_CFRUPLOW_AUTO  0xf2380080
-#define F0900_P2_CFRUPLOW_TEST  0xf2380040
-#define F0900_P2_EN_CAR2CENTER  0xf2380020
-#define F0900_P2_CARHDR_NODIV8  0xf2380010
-#define F0900_P2_I2C_ROTA  0xf2380008
-#define F0900_P2_ROTAON  0xf2380004
-#define F0900_P2_PH_DET_ALGO  0xf2380003
+#define R0900_P2_CARCFG 0xf238
+#define F0900_P2_CFRUPLOW_AUTO 0xf2380080
+#define F0900_P2_CFRUPLOW_TEST 0xf2380040
+#define F0900_P2_ROTAON 0xf2380004
+#define F0900_P2_PH_DET_ALGO 0xf2380003
 
 /*P2_ACLC*/
-#define R0900_P2_ACLC  0xf239
-#define F0900_P2_STOP_S2ALPHA  0xf23900c0
-#define F0900_P2_CAR_ALPHA_MANT  0xf2390030
-#define F0900_P2_CAR_ALPHA_EXP  0xf239000f
+#define R0900_P2_ACLC 0xf239
+#define F0900_P2_CAR_ALPHA_MANT 0xf2390030
+#define F0900_P2_CAR_ALPHA_EXP 0xf239000f
 
 /*P2_BCLC*/
-#define R0900_P2_BCLC  0xf23a
-#define F0900_P2_STOP_S2BETA  0xf23a00c0
-#define F0900_P2_CAR_BETA_MANT  0xf23a0030
-#define F0900_P2_CAR_BETA_EXP  0xf23a000f
+#define R0900_P2_BCLC 0xf23a
+#define F0900_P2_CAR_BETA_MANT 0xf23a0030
+#define F0900_P2_CAR_BETA_EXP 0xf23a000f
 
 /*P2_CARFREQ*/
-#define R0900_P2_CARFREQ  0xf23d
-#define F0900_P2_KC_COARSE_EXP  0xf23d00f0
-#define F0900_P2_BETA_FREQ  0xf23d000f
+#define R0900_P2_CARFREQ 0xf23d
+#define F0900_P2_KC_COARSE_EXP 0xf23d00f0
+#define F0900_P2_BETA_FREQ 0xf23d000f
 
 /*P2_CARHDR*/
-#define R0900_P2_CARHDR  0xf23e
-#define F0900_P2_K_FREQ_HDR  0xf23e00ff
+#define R0900_P2_CARHDR 0xf23e
+#define F0900_P2_K_FREQ_HDR 0xf23e00ff
 
 /*P2_LDT*/
-#define R0900_P2_LDT  0xf23f
-#define F0900_P2_CARLOCK_THRES  0xf23f01ff
+#define R0900_P2_LDT 0xf23f
+#define F0900_P2_CARLOCK_THRES 0xf23f01ff
 
 /*P2_LDT2*/
-#define R0900_P2_LDT2  0xf240
-#define F0900_P2_CARLOCK_THRES2  0xf24001ff
+#define R0900_P2_LDT2 0xf240
+#define F0900_P2_CARLOCK_THRES2 0xf24001ff
 
 /*P2_CFRICFG*/
-#define R0900_P2_CFRICFG  0xf241
-#define F0900_P2_CFRINIT_UNVALRNG  0xf2410080
-#define F0900_P2_CFRINIT_LUNVALCPT  0xf2410040
-#define F0900_P2_CFRINIT_ABORTDBL  0xf2410020
-#define F0900_P2_CFRINIT_ABORTPRED  0xf2410010
-#define F0900_P2_CFRINIT_UNVALSKIP  0xf2410008
-#define F0900_P2_CFRINIT_CSTINC  0xf2410004
-#define F0900_P2_NEG_CFRSTEP  0xf2410001
+#define R0900_P2_CFRICFG 0xf241
+#define F0900_P2_NEG_CFRSTEP 0xf2410001
 
 /*P2_CFRUP1*/
-#define R0900_P2_CFRUP1  0xf242
-#define F0900_P2_CFR_UP1  0xf24201ff
+#define R0900_P2_CFRUP1 0xf242
+#define F0900_P2_CFR_UP1 0xf24201ff
 
 /*P2_CFRUP0*/
-#define R0900_P2_CFRUP0  0xf243
-#define F0900_P2_CFR_UP0  0xf24300ff
+#define R0900_P2_CFRUP0 0xf243
+#define F0900_P2_CFR_UP0 0xf24300ff
 
 /*P2_CFRLOW1*/
-#define R0900_P2_CFRLOW1  0xf246
-#define F0900_P2_CFR_LOW1  0xf24601ff
+#define R0900_P2_CFRLOW1 0xf246
+#define F0900_P2_CFR_LOW1 0xf24601ff
 
 /*P2_CFRLOW0*/
-#define R0900_P2_CFRLOW0  0xf247
-#define F0900_P2_CFR_LOW0  0xf24700ff
+#define R0900_P2_CFRLOW0 0xf247
+#define F0900_P2_CFR_LOW0 0xf24700ff
 
 /*P2_CFRINIT1*/
-#define R0900_P2_CFRINIT1  0xf248
-#define F0900_P2_CFR_INIT1  0xf24801ff
+#define R0900_P2_CFRINIT1 0xf248
+#define F0900_P2_CFR_INIT1 0xf24801ff
 
 /*P2_CFRINIT0*/
-#define R0900_P2_CFRINIT0  0xf249
-#define F0900_P2_CFR_INIT0  0xf24900ff
+#define R0900_P2_CFRINIT0 0xf249
+#define F0900_P2_CFR_INIT0 0xf24900ff
 
 /*P2_CFRINC1*/
-#define R0900_P2_CFRINC1  0xf24a
-#define F0900_P2_MANUAL_CFRINC  0xf24a0080
-#define F0900_P2_CFR_INC1  0xf24a017f
+#define R0900_P2_CFRINC1 0xf24a
+#define F0900_P2_MANUAL_CFRINC 0xf24a0080
+#define F0900_P2_CFR_INC1 0xf24a003f
 
 /*P2_CFRINC0*/
-#define R0900_P2_CFRINC0  0xf24b
-#define F0900_P2_CFR_INC0  0xf24b00f0
+#define R0900_P2_CFRINC0 0xf24b
+#define F0900_P2_CFR_INC0 0xf24b00f8
 
 /*P2_CFR2*/
-#define R0900_P2_CFR2  0xf24c
-#define F0900_P2_CAR_FREQ2  0xf24c01ff
+#define R0900_P2_CFR2 0xf24c
+#define F0900_P2_CAR_FREQ2 0xf24c01ff
 
 /*P2_CFR1*/
-#define R0900_P2_CFR1  0xf24d
-#define F0900_P2_CAR_FREQ1  0xf24d00ff
+#define R0900_P2_CFR1 0xf24d
+#define F0900_P2_CAR_FREQ1 0xf24d00ff
 
 /*P2_CFR0*/
-#define R0900_P2_CFR0  0xf24e
-#define F0900_P2_CAR_FREQ0  0xf24e00ff
+#define R0900_P2_CFR0 0xf24e
+#define F0900_P2_CAR_FREQ0 0xf24e00ff
 
 /*P2_LDI*/
-#define R0900_P2_LDI  0xf24f
-#define F0900_P2_LOCK_DET_INTEGR  0xf24f01ff
+#define R0900_P2_LDI 0xf24f
+#define F0900_P2_LOCK_DET_INTEGR 0xf24f01ff
 
 /*P2_TMGCFG*/
-#define R0900_P2_TMGCFG  0xf250
-#define F0900_P2_TMGLOCK_BETA  0xf25000c0
-#define F0900_P2_NOTMG_GROUPDELAY  0xf2500020
-#define F0900_P2_DO_TIMING_CORR  0xf2500010
-#define F0900_P2_MANUAL_SCAN  0xf250000c
-#define F0900_P2_TMG_MINFREQ  0xf2500003
+#define R0900_P2_TMGCFG 0xf250
+#define F0900_P2_TMGLOCK_BETA 0xf25000c0
+#define F0900_P2_DO_TIMING_CORR 0xf2500010
+#define F0900_P2_TMG_MINFREQ 0xf2500003
 
 /*P2_RTC*/
-#define R0900_P2_RTC  0xf251
-#define F0900_P2_TMGALPHA_EXP  0xf25100f0
-#define F0900_P2_TMGBETA_EXP  0xf251000f
+#define R0900_P2_RTC 0xf251
+#define F0900_P2_TMGALPHA_EXP 0xf25100f0
+#define F0900_P2_TMGBETA_EXP 0xf251000f
 
 /*P2_RTCS2*/
-#define R0900_P2_RTCS2  0xf252
-#define F0900_P2_TMGALPHAS2_EXP  0xf25200f0
-#define F0900_P2_TMGBETAS2_EXP  0xf252000f
+#define R0900_P2_RTCS2 0xf252
+#define F0900_P2_TMGALPHAS2_EXP 0xf25200f0
+#define F0900_P2_TMGBETAS2_EXP 0xf252000f
 
 /*P2_TMGTHRISE*/
-#define R0900_P2_TMGTHRISE  0xf253
-#define F0900_P2_TMGLOCK_THRISE  0xf25300ff
+#define R0900_P2_TMGTHRISE 0xf253
+#define F0900_P2_TMGLOCK_THRISE 0xf25300ff
 
 /*P2_TMGTHFALL*/
-#define R0900_P2_TMGTHFALL  0xf254
-#define F0900_P2_TMGLOCK_THFALL  0xf25400ff
+#define R0900_P2_TMGTHFALL 0xf254
+#define F0900_P2_TMGLOCK_THFALL 0xf25400ff
 
 /*P2_SFRUPRATIO*/
-#define R0900_P2_SFRUPRATIO  0xf255
-#define F0900_P2_SFR_UPRATIO  0xf25500ff
+#define R0900_P2_SFRUPRATIO 0xf255
+#define F0900_P2_SFR_UPRATIO 0xf25500ff
 
 /*P2_SFRLOWRATIO*/
-#define R0900_P2_SFRLOWRATIO  0xf256
-#define F0900_P2_SFR_LOWRATIO  0xf25600ff
+#define R0900_P2_SFRLOWRATIO 0xf256
+#define F0900_P2_SFR_LOWRATIO 0xf25600ff
 
 /*P2_KREFTMG*/
-#define R0900_P2_KREFTMG  0xf258
-#define F0900_P2_KREF_TMG  0xf25800ff
+#define R0900_P2_KREFTMG 0xf258
+#define F0900_P2_KREF_TMG 0xf25800ff
 
 /*P2_SFRSTEP*/
-#define R0900_P2_SFRSTEP  0xf259
-#define F0900_P2_SFR_SCANSTEP  0xf25900f0
-#define F0900_P2_SFR_CENTERSTEP  0xf259000f
+#define R0900_P2_SFRSTEP 0xf259
+#define F0900_P2_SFR_SCANSTEP 0xf25900f0
+#define F0900_P2_SFR_CENTERSTEP 0xf259000f
 
 /*P2_TMGCFG2*/
-#define R0900_P2_TMGCFG2  0xf25a
-#define F0900_P2_DIS_AUTOSAMP  0xf25a0008
-#define F0900_P2_SCANINIT_QUART  0xf25a0004
-#define F0900_P2_NOTMG_DVBS1DERAT  0xf25a0002
-#define F0900_P2_SFRRATIO_FINE  0xf25a0001
+#define R0900_P2_TMGCFG2 0xf25a
+#define F0900_P2_SFRRATIO_FINE 0xf25a0001
+
+/*P2_KREFTMG2*/
+#define R0900_P2_KREFTMG2 0xf25b
+#define F0900_P2_KREF_TMG2 0xf25b00ff
 
 /*P2_SFRINIT1*/
-#define R0900_P2_SFRINIT1  0xf25e
-#define F0900_P2_SFR_INIT1  0xf25e00ff
+#define R0900_P2_SFRINIT1 0xf25e
+#define F0900_P2_SFR_INIT1 0xf25e007f
 
 /*P2_SFRINIT0*/
-#define R0900_P2_SFRINIT0  0xf25f
-#define F0900_P2_SFR_INIT0  0xf25f00ff
+#define R0900_P2_SFRINIT0 0xf25f
+#define F0900_P2_SFR_INIT0 0xf25f00ff
 
 /*P2_SFRUP1*/
-#define R0900_P2_SFRUP1  0xf260
-#define F0900_P2_AUTO_GUP  0xf2600080
-#define F0900_P2_SYMB_FREQ_UP1  0xf260007f
+#define R0900_P2_SFRUP1 0xf260
+#define F0900_P2_AUTO_GUP 0xf2600080
+#define F0900_P2_SYMB_FREQ_UP1 0xf260007f
 
 /*P2_SFRUP0*/
-#define R0900_P2_SFRUP0  0xf261
-#define F0900_P2_SYMB_FREQ_UP0  0xf26100ff
+#define R0900_P2_SFRUP0 0xf261
+#define F0900_P2_SYMB_FREQ_UP0 0xf26100ff
 
 /*P2_SFRLOW1*/
-#define R0900_P2_SFRLOW1  0xf262
-#define F0900_P2_AUTO_GLOW  0xf2620080
-#define F0900_P2_SYMB_FREQ_LOW1  0xf262007f
+#define R0900_P2_SFRLOW1 0xf262
+#define F0900_P2_AUTO_GLOW 0xf2620080
+#define F0900_P2_SYMB_FREQ_LOW1 0xf262007f
 
 /*P2_SFRLOW0*/
-#define R0900_P2_SFRLOW0  0xf263
-#define F0900_P2_SYMB_FREQ_LOW0  0xf26300ff
+#define R0900_P2_SFRLOW0 0xf263
+#define F0900_P2_SYMB_FREQ_LOW0 0xf26300ff
 
 /*P2_SFR3*/
-#define R0900_P2_SFR3  0xf264
-#define F0900_P2_SYMB_FREQ3  0xf26400ff
+#define R0900_P2_SFR3 0xf264
+#define F0900_P2_SYMB_FREQ3 0xf26400ff
 
 /*P2_SFR2*/
-#define R0900_P2_SFR2  0xf265
-#define F0900_P2_SYMB_FREQ2  0xf26500ff
+#define R0900_P2_SFR2 0xf265
+#define F0900_P2_SYMB_FREQ2 0xf26500ff
 
 /*P2_SFR1*/
-#define R0900_P2_SFR1  0xf266
-#define F0900_P2_SYMB_FREQ1  0xf26600ff
+#define R0900_P2_SFR1 0xf266
+#define F0900_P2_SYMB_FREQ1 0xf26600ff
 
 /*P2_SFR0*/
-#define R0900_P2_SFR0  0xf267
-#define F0900_P2_SYMB_FREQ0  0xf26700ff
+#define R0900_P2_SFR0 0xf267
+#define F0900_P2_SYMB_FREQ0 0xf26700ff
 
 /*P2_TMGREG2*/
-#define R0900_P2_TMGREG2  0xf268
-#define F0900_P2_TMGREG2  0xf26800ff
+#define R0900_P2_TMGREG2 0xf268
+#define F0900_P2_TMGREG2 0xf26800ff
 
 /*P2_TMGREG1*/
-#define R0900_P2_TMGREG1  0xf269
-#define F0900_P2_TMGREG1  0xf26900ff
+#define R0900_P2_TMGREG1 0xf269
+#define F0900_P2_TMGREG1 0xf26900ff
 
 /*P2_TMGREG0*/
-#define R0900_P2_TMGREG0  0xf26a
-#define F0900_P2_TMGREG0  0xf26a00ff
+#define R0900_P2_TMGREG0 0xf26a
+#define F0900_P2_TMGREG0 0xf26a00ff
 
 /*P2_TMGLOCK1*/
-#define R0900_P2_TMGLOCK1  0xf26b
-#define F0900_P2_TMGLOCK_LEVEL1  0xf26b01ff
+#define R0900_P2_TMGLOCK1 0xf26b
+#define F0900_P2_TMGLOCK_LEVEL1 0xf26b01ff
 
 /*P2_TMGLOCK0*/
-#define R0900_P2_TMGLOCK0  0xf26c
-#define F0900_P2_TMGLOCK_LEVEL0  0xf26c00ff
+#define R0900_P2_TMGLOCK0 0xf26c
+#define F0900_P2_TMGLOCK_LEVEL0 0xf26c00ff
 
 /*P2_TMGOBS*/
-#define R0900_P2_TMGOBS  0xf26d
-#define F0900_P2_ROLLOFF_STATUS  0xf26d00c0
-#define F0900_P2_SCAN_SIGN  0xf26d0030
-#define F0900_P2_TMG_SCANNING  0xf26d0008
-#define F0900_P2_CHCENTERING_MODE  0xf26d0004
-#define F0900_P2_TMG_SCANFAIL  0xf26d0002
+#define R0900_P2_TMGOBS 0xf26d
+#define F0900_P2_ROLLOFF_STATUS 0xf26d00c0
 
 /*P2_EQUALCFG*/
-#define R0900_P2_EQUALCFG  0xf26f
-#define F0900_P2_NOTMG_NEGALWAIT  0xf26f0080
-#define F0900_P2_EQUAL_ON  0xf26f0040
-#define F0900_P2_SEL_EQUALCOR  0xf26f0038
-#define F0900_P2_MU_EQUALDFE  0xf26f0007
+#define R0900_P2_EQUALCFG 0xf26f
+#define F0900_P2_EQUAL_ON 0xf26f0040
+#define F0900_P2_MU_EQUALDFE 0xf26f0007
 
 /*P2_EQUAI1*/
-#define R0900_P2_EQUAI1  0xf270
-#define F0900_P2_EQUA_ACCI1  0xf27001ff
+#define R0900_P2_EQUAI1 0xf270
+#define F0900_P2_EQUA_ACCI1 0xf27001ff
 
 /*P2_EQUAQ1*/
-#define R0900_P2_EQUAQ1  0xf271
-#define F0900_P2_EQUA_ACCQ1  0xf27101ff
+#define R0900_P2_EQUAQ1 0xf271
+#define F0900_P2_EQUA_ACCQ1 0xf27101ff
 
 /*P2_EQUAI2*/
-#define R0900_P2_EQUAI2  0xf272
-#define F0900_P2_EQUA_ACCI2  0xf27201ff
+#define R0900_P2_EQUAI2 0xf272
+#define F0900_P2_EQUA_ACCI2 0xf27201ff
 
 /*P2_EQUAQ2*/
-#define R0900_P2_EQUAQ2  0xf273
-#define F0900_P2_EQUA_ACCQ2  0xf27301ff
+#define R0900_P2_EQUAQ2 0xf273
+#define F0900_P2_EQUA_ACCQ2 0xf27301ff
 
 /*P2_EQUAI3*/
-#define R0900_P2_EQUAI3  0xf274
-#define F0900_P2_EQUA_ACCI3  0xf27401ff
+#define R0900_P2_EQUAI3 0xf274
+#define F0900_P2_EQUA_ACCI3 0xf27401ff
 
 /*P2_EQUAQ3*/
-#define R0900_P2_EQUAQ3  0xf275
-#define F0900_P2_EQUA_ACCQ3  0xf27501ff
+#define R0900_P2_EQUAQ3 0xf275
+#define F0900_P2_EQUA_ACCQ3 0xf27501ff
 
 /*P2_EQUAI4*/
-#define R0900_P2_EQUAI4  0xf276
-#define F0900_P2_EQUA_ACCI4  0xf27601ff
+#define R0900_P2_EQUAI4 0xf276
+#define F0900_P2_EQUA_ACCI4 0xf27601ff
 
 /*P2_EQUAQ4*/
-#define R0900_P2_EQUAQ4  0xf277
-#define F0900_P2_EQUA_ACCQ4  0xf27701ff
+#define R0900_P2_EQUAQ4 0xf277
+#define F0900_P2_EQUA_ACCQ4 0xf27701ff
 
 /*P2_EQUAI5*/
-#define R0900_P2_EQUAI5  0xf278
-#define F0900_P2_EQUA_ACCI5  0xf27801ff
+#define R0900_P2_EQUAI5 0xf278
+#define F0900_P2_EQUA_ACCI5 0xf27801ff
 
 /*P2_EQUAQ5*/
-#define R0900_P2_EQUAQ5  0xf279
-#define F0900_P2_EQUA_ACCQ5  0xf27901ff
+#define R0900_P2_EQUAQ5 0xf279
+#define F0900_P2_EQUA_ACCQ5 0xf27901ff
 
 /*P2_EQUAI6*/
-#define R0900_P2_EQUAI6  0xf27a
-#define F0900_P2_EQUA_ACCI6  0xf27a01ff
+#define R0900_P2_EQUAI6 0xf27a
+#define F0900_P2_EQUA_ACCI6 0xf27a01ff
 
 /*P2_EQUAQ6*/
-#define R0900_P2_EQUAQ6  0xf27b
-#define F0900_P2_EQUA_ACCQ6  0xf27b01ff
+#define R0900_P2_EQUAQ6 0xf27b
+#define F0900_P2_EQUA_ACCQ6 0xf27b01ff
 
 /*P2_EQUAI7*/
-#define R0900_P2_EQUAI7  0xf27c
-#define F0900_P2_EQUA_ACCI7  0xf27c01ff
+#define R0900_P2_EQUAI7 0xf27c
+#define F0900_P2_EQUA_ACCI7 0xf27c01ff
 
 /*P2_EQUAQ7*/
-#define R0900_P2_EQUAQ7  0xf27d
-#define F0900_P2_EQUA_ACCQ7  0xf27d01ff
+#define R0900_P2_EQUAQ7 0xf27d
+#define F0900_P2_EQUA_ACCQ7 0xf27d01ff
 
 /*P2_EQUAI8*/
-#define R0900_P2_EQUAI8  0xf27e
-#define F0900_P2_EQUA_ACCI8  0xf27e01ff
+#define R0900_P2_EQUAI8 0xf27e
+#define F0900_P2_EQUA_ACCI8 0xf27e01ff
 
 /*P2_EQUAQ8*/
-#define R0900_P2_EQUAQ8  0xf27f
-#define F0900_P2_EQUA_ACCQ8  0xf27f01ff
+#define R0900_P2_EQUAQ8 0xf27f
+#define F0900_P2_EQUA_ACCQ8 0xf27f01ff
 
 /*P2_NNOSDATAT1*/
-#define R0900_P2_NNOSDATAT1  0xf280
-#define F0900_P2_NOSDATAT_NORMED1  0xf28000ff
+#define R0900_P2_NNOSDATAT1 0xf280
+#define F0900_P2_NOSDATAT_NORMED1 0xf28000ff
 
 /*P2_NNOSDATAT0*/
-#define R0900_P2_NNOSDATAT0  0xf281
-#define F0900_P2_NOSDATAT_NORMED0  0xf28100ff
+#define R0900_P2_NNOSDATAT0 0xf281
+#define F0900_P2_NOSDATAT_NORMED0 0xf28100ff
 
 /*P2_NNOSDATA1*/
-#define R0900_P2_NNOSDATA1  0xf282
-#define F0900_P2_NOSDATA_NORMED1  0xf28200ff
+#define R0900_P2_NNOSDATA1 0xf282
+#define F0900_P2_NOSDATA_NORMED1 0xf28200ff
 
 /*P2_NNOSDATA0*/
-#define R0900_P2_NNOSDATA0  0xf283
-#define F0900_P2_NOSDATA_NORMED0  0xf28300ff
+#define R0900_P2_NNOSDATA0 0xf283
+#define F0900_P2_NOSDATA_NORMED0 0xf28300ff
 
 /*P2_NNOSPLHT1*/
-#define R0900_P2_NNOSPLHT1  0xf284
-#define F0900_P2_NOSPLHT_NORMED1  0xf28400ff
+#define R0900_P2_NNOSPLHT1 0xf284
+#define F0900_P2_NOSPLHT_NORMED1 0xf28400ff
 
 /*P2_NNOSPLHT0*/
-#define R0900_P2_NNOSPLHT0  0xf285
-#define F0900_P2_NOSPLHT_NORMED0  0xf28500ff
+#define R0900_P2_NNOSPLHT0 0xf285
+#define F0900_P2_NOSPLHT_NORMED0 0xf28500ff
 
 /*P2_NNOSPLH1*/
-#define R0900_P2_NNOSPLH1  0xf286
-#define F0900_P2_NOSPLH_NORMED1  0xf28600ff
+#define R0900_P2_NNOSPLH1 0xf286
+#define F0900_P2_NOSPLH_NORMED1 0xf28600ff
 
 /*P2_NNOSPLH0*/
-#define R0900_P2_NNOSPLH0  0xf287
-#define F0900_P2_NOSPLH_NORMED0  0xf28700ff
+#define R0900_P2_NNOSPLH0 0xf287
+#define F0900_P2_NOSPLH_NORMED0 0xf28700ff
 
 /*P2_NOSDATAT1*/
-#define R0900_P2_NOSDATAT1  0xf288
-#define F0900_P2_NOSDATAT_UNNORMED1  0xf28800ff
+#define R0900_P2_NOSDATAT1 0xf288
+#define F0900_P2_NOSDATAT_UNNORMED1 0xf28800ff
 
 /*P2_NOSDATAT0*/
-#define R0900_P2_NOSDATAT0  0xf289
-#define F0900_P2_NOSDATAT_UNNORMED0  0xf28900ff
+#define R0900_P2_NOSDATAT0 0xf289
+#define F0900_P2_NOSDATAT_UNNORMED0 0xf28900ff
 
 /*P2_NOSDATA1*/
-#define R0900_P2_NOSDATA1  0xf28a
-#define F0900_P2_NOSDATA_UNNORMED1  0xf28a00ff
+#define R0900_P2_NOSDATA1 0xf28a
+#define F0900_P2_NOSDATA_UNNORMED1 0xf28a00ff
 
 /*P2_NOSDATA0*/
-#define R0900_P2_NOSDATA0  0xf28b
-#define F0900_P2_NOSDATA_UNNORMED0  0xf28b00ff
+#define R0900_P2_NOSDATA0 0xf28b
+#define F0900_P2_NOSDATA_UNNORMED0 0xf28b00ff
 
 /*P2_NOSPLHT1*/
-#define R0900_P2_NOSPLHT1  0xf28c
-#define F0900_P2_NOSPLHT_UNNORMED1  0xf28c00ff
+#define R0900_P2_NOSPLHT1 0xf28c
+#define F0900_P2_NOSPLHT_UNNORMED1 0xf28c00ff
 
 /*P2_NOSPLHT0*/
-#define R0900_P2_NOSPLHT0  0xf28d
-#define F0900_P2_NOSPLHT_UNNORMED0  0xf28d00ff
+#define R0900_P2_NOSPLHT0 0xf28d
+#define F0900_P2_NOSPLHT_UNNORMED0 0xf28d00ff
 
 /*P2_NOSPLH1*/
-#define R0900_P2_NOSPLH1  0xf28e
-#define F0900_P2_NOSPLH_UNNORMED1  0xf28e00ff
+#define R0900_P2_NOSPLH1 0xf28e
+#define F0900_P2_NOSPLH_UNNORMED1 0xf28e00ff
 
 /*P2_NOSPLH0*/
-#define R0900_P2_NOSPLH0  0xf28f
-#define F0900_P2_NOSPLH_UNNORMED0  0xf28f00ff
+#define R0900_P2_NOSPLH0 0xf28f
+#define F0900_P2_NOSPLH_UNNORMED0 0xf28f00ff
 
 /*P2_CAR2CFG*/
-#define R0900_P2_CAR2CFG  0xf290
-#define F0900_P2_DESCRAMB_OFF  0xf2900080
-#define F0900_P2_PN4_SELECT  0xf2900040
-#define F0900_P2_CFR2_STOPDVBS1  0xf2900020
-#define F0900_P2_STOP_CFR2UPDATE  0xf2900010
-#define F0900_P2_STOP_NCO2UPDATE  0xf2900008
-#define F0900_P2_ROTA2ON  0xf2900004
-#define F0900_P2_PH_DET_ALGO2  0xf2900003
+#define R0900_P2_CAR2CFG 0xf290
+#define F0900_P2_CARRIER3_DISABLE 0xf2900040
+#define F0900_P2_ROTA2ON 0xf2900004
+#define F0900_P2_PH_DET_ALGO2 0xf2900003
 
-/*P2_ACLC2*/
-#define R0900_P2_ACLC2  0xf291
-#define F0900_P2_CAR2_PUNCT_ADERAT  0xf2910040
-#define F0900_P2_CAR2_ALPHA_MANT  0xf2910030
-#define F0900_P2_CAR2_ALPHA_EXP  0xf291000f
-
-/*P2_BCLC2*/
-#define R0900_P2_BCLC2  0xf292
-#define F0900_P2_DVBS2_NIP  0xf2920080
-#define F0900_P2_CAR2_PUNCT_BDERAT  0xf2920040
-#define F0900_P2_CAR2_BETA_MANT  0xf2920030
-#define F0900_P2_CAR2_BETA_EXP  0xf292000f
+/*P2_CFR2CFR1*/
+#define R0900_P2_CFR2CFR1 0xf291
+#define F0900_P2_CFR2TOCFR1_DVBS1 0xf29100c0
+#define F0900_P2_EN_S2CAR2CENTER 0xf2910020
+#define F0900_P2_DIS_BCHERRCFR2 0xf2910010
+#define F0900_P2_CFR2TOCFR1_BETA 0xf2910007
 
 /*P2_CFR22*/
-#define R0900_P2_CFR22  0xf293
-#define F0900_P2_CAR2_FREQ2  0xf29301ff
+#define R0900_P2_CFR22 0xf293
+#define F0900_P2_CAR2_FREQ2 0xf29301ff
 
 /*P2_CFR21*/
-#define R0900_P2_CFR21  0xf294
-#define F0900_P2_CAR2_FREQ1  0xf29400ff
+#define R0900_P2_CFR21 0xf294
+#define F0900_P2_CAR2_FREQ1 0xf29400ff
 
 /*P2_CFR20*/
-#define R0900_P2_CFR20  0xf295
-#define F0900_P2_CAR2_FREQ0  0xf29500ff
+#define R0900_P2_CFR20 0xf295
+#define F0900_P2_CAR2_FREQ0 0xf29500ff
 
 /*P2_ACLC2S2Q*/
-#define R0900_P2_ACLC2S2Q  0xf297
-#define F0900_P2_ENAB_SPSKSYMB  0xf2970080
-#define F0900_P2_CAR2S2_QADERAT  0xf2970040
-#define F0900_P2_CAR2S2_Q_ALPH_M  0xf2970030
-#define F0900_P2_CAR2S2_Q_ALPH_E  0xf297000f
+#define R0900_P2_ACLC2S2Q 0xf297
+#define F0900_P2_ENAB_SPSKSYMB 0xf2970080
+#define F0900_P2_CAR2S2_Q_ALPH_M 0xf2970030
+#define F0900_P2_CAR2S2_Q_ALPH_E 0xf297000f
 
 /*P2_ACLC2S28*/
-#define R0900_P2_ACLC2S28  0xf298
-#define F0900_P2_OLDI3Q_MODE  0xf2980080
-#define F0900_P2_CAR2S2_8ADERAT  0xf2980040
-#define F0900_P2_CAR2S2_8_ALPH_M  0xf2980030
-#define F0900_P2_CAR2S2_8_ALPH_E  0xf298000f
+#define R0900_P2_ACLC2S28 0xf298
+#define F0900_P2_OLDI3Q_MODE 0xf2980080
+#define F0900_P2_CAR2S2_8_ALPH_M 0xf2980030
+#define F0900_P2_CAR2S2_8_ALPH_E 0xf298000f
 
 /*P2_ACLC2S216A*/
-#define R0900_P2_ACLC2S216A  0xf299
-#define F0900_P2_CAR2S2_16ADERAT  0xf2990040
-#define F0900_P2_CAR2S2_16A_ALPH_M  0xf2990030
-#define F0900_P2_CAR2S2_16A_ALPH_E  0xf299000f
+#define R0900_P2_ACLC2S216A 0xf299
+#define F0900_P2_DIS_C3STOPA2 0xf2990080
+#define F0900_P2_CAR2S2_16ADERAT 0xf2990040
+#define F0900_P2_CAR2S2_16A_ALPH_M 0xf2990030
+#define F0900_P2_CAR2S2_16A_ALPH_E 0xf299000f
 
 /*P2_ACLC2S232A*/
-#define R0900_P2_ACLC2S232A  0xf29a
-#define F0900_P2_CAR2S2_32ADERAT  0xf29a0040
-#define F0900_P2_CAR2S2_32A_ALPH_M  0xf29a0030
-#define F0900_P2_CAR2S2_32A_ALPH_E  0xf29a000f
+#define R0900_P2_ACLC2S232A 0xf29a
+#define F0900_P2_CAR2S2_32ADERAT 0xf29a0040
+#define F0900_P2_CAR2S2_32A_ALPH_M 0xf29a0030
+#define F0900_P2_CAR2S2_32A_ALPH_E 0xf29a000f
 
 /*P2_BCLC2S2Q*/
-#define R0900_P2_BCLC2S2Q  0xf29c
-#define F0900_P2_DVBS2S2Q_NIP  0xf29c0080
-#define F0900_P2_CAR2S2_QBDERAT  0xf29c0040
-#define F0900_P2_CAR2S2_Q_BETA_M  0xf29c0030
-#define F0900_P2_CAR2S2_Q_BETA_E  0xf29c000f
+#define R0900_P2_BCLC2S2Q 0xf29c
+#define F0900_P2_CAR2S2_Q_BETA_M 0xf29c0030
+#define F0900_P2_CAR2S2_Q_BETA_E 0xf29c000f
 
 /*P2_BCLC2S28*/
-#define R0900_P2_BCLC2S28  0xf29d
-#define F0900_P2_DVBS2S28_NIP  0xf29d0080
-#define F0900_P2_CAR2S2_8BDERAT  0xf29d0040
-#define F0900_P2_CAR2S2_8_BETA_M  0xf29d0030
-#define F0900_P2_CAR2S2_8_BETA_E  0xf29d000f
+#define R0900_P2_BCLC2S28 0xf29d
+#define F0900_P2_CAR2S2_8_BETA_M 0xf29d0030
+#define F0900_P2_CAR2S2_8_BETA_E 0xf29d000f
 
 /*P2_BCLC2S216A*/
-#define R0900_P2_BCLC2S216A  0xf29e
-#define F0900_P2_DVBS2S216A_NIP  0xf29e0080
-#define F0900_P2_CAR2S2_16BDERAT  0xf29e0040
-#define F0900_P2_CAR2S2_16A_BETA_M  0xf29e0030
-#define F0900_P2_CAR2S2_16A_BETA_E  0xf29e000f
+#define R0900_P2_BCLC2S216A 0xf29e
 
 /*P2_BCLC2S232A*/
-#define R0900_P2_BCLC2S232A  0xf29f
-#define F0900_P2_DVBS2S232A_NIP  0xf29f0080
-#define F0900_P2_CAR2S2_32BDERAT  0xf29f0040
-#define F0900_P2_CAR2S2_32A_BETA_M  0xf29f0030
-#define F0900_P2_CAR2S2_32A_BETA_E  0xf29f000f
+#define R0900_P2_BCLC2S232A 0xf29f
 
 /*P2_PLROOT2*/
-#define R0900_P2_PLROOT2  0xf2ac
-#define F0900_P2_SHORTFR_DISABLE  0xf2ac0080
-#define F0900_P2_LONGFR_DISABLE  0xf2ac0040
-#define F0900_P2_DUMMYPL_DISABLE  0xf2ac0020
-#define F0900_P2_SHORTFR_AVOID  0xf2ac0010
-#define F0900_P2_PLSCRAMB_MODE  0xf2ac000c
-#define F0900_P2_PLSCRAMB_ROOT2  0xf2ac0003
+#define R0900_P2_PLROOT2 0xf2ac
+#define F0900_P2_PLSCRAMB_MODE 0xf2ac000c
+#define F0900_P2_PLSCRAMB_ROOT2 0xf2ac0003
 
 /*P2_PLROOT1*/
-#define R0900_P2_PLROOT1  0xf2ad
-#define F0900_P2_PLSCRAMB_ROOT1  0xf2ad00ff
+#define R0900_P2_PLROOT1 0xf2ad
+#define F0900_P2_PLSCRAMB_ROOT1 0xf2ad00ff
 
 /*P2_PLROOT0*/
-#define R0900_P2_PLROOT0  0xf2ae
-#define F0900_P2_PLSCRAMB_ROOT0  0xf2ae00ff
+#define R0900_P2_PLROOT0 0xf2ae
+#define F0900_P2_PLSCRAMB_ROOT0 0xf2ae00ff
 
 /*P2_MODCODLST0*/
-#define R0900_P2_MODCODLST0  0xf2b0
-#define F0900_P2_EN_TOKEN31  0xf2b00080
-#define F0900_P2_SYNCTAG_SELECT  0xf2b00040
-#define F0900_P2_MODCODRQ_MODE  0xf2b00030
+#define R0900_P2_MODCODLST0 0xf2b0
 
 /*P2_MODCODLST1*/
-#define R0900_P2_MODCODLST1  0xf2b1
-#define F0900_P2_DIS_MODCOD29  0xf2b100f0
-#define F0900_P2_DIS_32PSK_9_10  0xf2b1000f
+#define R0900_P2_MODCODLST1 0xf2b1
+#define F0900_P2_DIS_MODCOD29 0xf2b100f0
+#define F0900_P2_DIS_32PSK_9_10 0xf2b1000f
 
 /*P2_MODCODLST2*/
-#define R0900_P2_MODCODLST2  0xf2b2
-#define F0900_P2_DIS_32PSK_8_9  0xf2b200f0
-#define F0900_P2_DIS_32PSK_5_6  0xf2b2000f
+#define R0900_P2_MODCODLST2 0xf2b2
+#define F0900_P2_DIS_32PSK_8_9 0xf2b200f0
+#define F0900_P2_DIS_32PSK_5_6 0xf2b2000f
 
 /*P2_MODCODLST3*/
-#define R0900_P2_MODCODLST3  0xf2b3
-#define F0900_P2_DIS_32PSK_4_5  0xf2b300f0
-#define F0900_P2_DIS_32PSK_3_4  0xf2b3000f
+#define R0900_P2_MODCODLST3 0xf2b3
+#define F0900_P2_DIS_32PSK_4_5 0xf2b300f0
+#define F0900_P2_DIS_32PSK_3_4 0xf2b3000f
 
 /*P2_MODCODLST4*/
-#define R0900_P2_MODCODLST4  0xf2b4
-#define F0900_P2_DIS_16PSK_9_10  0xf2b400f0
-#define F0900_P2_DIS_16PSK_8_9  0xf2b4000f
+#define R0900_P2_MODCODLST4 0xf2b4
+#define F0900_P2_DIS_16PSK_9_10 0xf2b400f0
+#define F0900_P2_DIS_16PSK_8_9 0xf2b4000f
 
 /*P2_MODCODLST5*/
-#define R0900_P2_MODCODLST5  0xf2b5
-#define F0900_P2_DIS_16PSK_5_6  0xf2b500f0
-#define F0900_P2_DIS_16PSK_4_5  0xf2b5000f
+#define R0900_P2_MODCODLST5 0xf2b5
+#define F0900_P2_DIS_16PSK_5_6 0xf2b500f0
+#define F0900_P2_DIS_16PSK_4_5 0xf2b5000f
 
 /*P2_MODCODLST6*/
-#define R0900_P2_MODCODLST6  0xf2b6
-#define F0900_P2_DIS_16PSK_3_4  0xf2b600f0
-#define F0900_P2_DIS_16PSK_2_3  0xf2b6000f
+#define R0900_P2_MODCODLST6 0xf2b6
+#define F0900_P2_DIS_16PSK_3_4 0xf2b600f0
+#define F0900_P2_DIS_16PSK_2_3 0xf2b6000f
 
 /*P2_MODCODLST7*/
-#define R0900_P2_MODCODLST7  0xf2b7
-#define F0900_P2_DIS_8P_9_10  0xf2b700f0
-#define F0900_P2_DIS_8P_8_9  0xf2b7000f
+#define R0900_P2_MODCODLST7 0xf2b7
+#define F0900_P2_DIS_8P_9_10 0xf2b700f0
+#define F0900_P2_DIS_8P_8_9 0xf2b7000f
 
 /*P2_MODCODLST8*/
-#define R0900_P2_MODCODLST8  0xf2b8
-#define F0900_P2_DIS_8P_5_6  0xf2b800f0
-#define F0900_P2_DIS_8P_3_4  0xf2b8000f
+#define R0900_P2_MODCODLST8 0xf2b8
+#define F0900_P2_DIS_8P_5_6 0xf2b800f0
+#define F0900_P2_DIS_8P_3_4 0xf2b8000f
 
 /*P2_MODCODLST9*/
-#define R0900_P2_MODCODLST9  0xf2b9
-#define F0900_P2_DIS_8P_2_3  0xf2b900f0
-#define F0900_P2_DIS_8P_3_5  0xf2b9000f
+#define R0900_P2_MODCODLST9 0xf2b9
+#define F0900_P2_DIS_8P_2_3 0xf2b900f0
+#define F0900_P2_DIS_8P_3_5 0xf2b9000f
 
 /*P2_MODCODLSTA*/
-#define R0900_P2_MODCODLSTA  0xf2ba
-#define F0900_P2_DIS_QP_9_10  0xf2ba00f0
-#define F0900_P2_DIS_QP_8_9  0xf2ba000f
+#define R0900_P2_MODCODLSTA 0xf2ba
+#define F0900_P2_DIS_QP_9_10 0xf2ba00f0
+#define F0900_P2_DIS_QP_8_9 0xf2ba000f
 
 /*P2_MODCODLSTB*/
-#define R0900_P2_MODCODLSTB  0xf2bb
-#define F0900_P2_DIS_QP_5_6  0xf2bb00f0
-#define F0900_P2_DIS_QP_4_5  0xf2bb000f
+#define R0900_P2_MODCODLSTB 0xf2bb
+#define F0900_P2_DIS_QP_5_6 0xf2bb00f0
+#define F0900_P2_DIS_QP_4_5 0xf2bb000f
 
 /*P2_MODCODLSTC*/
-#define R0900_P2_MODCODLSTC  0xf2bc
-#define F0900_P2_DIS_QP_3_4  0xf2bc00f0
-#define F0900_P2_DIS_QP_2_3  0xf2bc000f
+#define R0900_P2_MODCODLSTC 0xf2bc
+#define F0900_P2_DIS_QP_3_4 0xf2bc00f0
+#define F0900_P2_DIS_QP_2_3 0xf2bc000f
 
 /*P2_MODCODLSTD*/
-#define R0900_P2_MODCODLSTD  0xf2bd
-#define F0900_P2_DIS_QP_3_5  0xf2bd00f0
-#define F0900_P2_DIS_QP_1_2  0xf2bd000f
+#define R0900_P2_MODCODLSTD 0xf2bd
+#define F0900_P2_DIS_QP_3_5 0xf2bd00f0
+#define F0900_P2_DIS_QP_1_2 0xf2bd000f
 
 /*P2_MODCODLSTE*/
-#define R0900_P2_MODCODLSTE  0xf2be
-#define F0900_P2_DIS_QP_2_5  0xf2be00f0
-#define F0900_P2_DIS_QP_1_3  0xf2be000f
+#define R0900_P2_MODCODLSTE 0xf2be
+#define F0900_P2_DIS_QP_2_5 0xf2be00f0
+#define F0900_P2_DIS_QP_1_3 0xf2be000f
 
 /*P2_MODCODLSTF*/
-#define R0900_P2_MODCODLSTF  0xf2bf
-#define F0900_P2_DIS_QP_1_4  0xf2bf00f0
-#define F0900_P2_DDEMOD_SET  0xf2bf0002
-#define F0900_P2_DDEMOD_MASK  0xf2bf0001
+#define R0900_P2_MODCODLSTF 0xf2bf
+#define F0900_P2_DIS_QP_1_4 0xf2bf00f0
+
+/*P2_GAUSSR0*/
+#define R0900_P2_GAUSSR0 0xf2c0
+#define F0900_P2_EN_CCIMODE 0xf2c00080
+#define F0900_P2_R0_GAUSSIEN 0xf2c0007f
+
+/*P2_CCIR0*/
+#define R0900_P2_CCIR0 0xf2c1
+#define F0900_P2_CCIDETECT_PLHONLY 0xf2c10080
+#define F0900_P2_R0_CCI 0xf2c1007f
+
+/*P2_CCIQUANT*/
+#define R0900_P2_CCIQUANT 0xf2c2
+#define F0900_P2_CCI_BETA 0xf2c200e0
+#define F0900_P2_CCI_QUANT 0xf2c2001f
+
+/*P2_CCITHRES*/
+#define R0900_P2_CCITHRES 0xf2c3
+#define F0900_P2_CCI_THRESHOLD 0xf2c300ff
+
+/*P2_CCIACC*/
+#define R0900_P2_CCIACC 0xf2c4
+#define F0900_P2_CCI_VALUE 0xf2c400ff
 
 /*P2_DMDRESCFG*/
-#define R0900_P2_DMDRESCFG  0xf2c6
-#define F0900_P2_DMDRES_RESET  0xf2c60080
-#define F0900_P2_DMDRES_NOISESQR  0xf2c60010
-#define F0900_P2_DMDRES_STRALL  0xf2c60008
-#define F0900_P2_DMDRES_NEWONLY  0xf2c60004
-#define F0900_P2_DMDRES_NOSTORE  0xf2c60002
-#define F0900_P2_DMDRES_AGC2MEM  0xf2c60001
+#define R0900_P2_DMDRESCFG 0xf2c6
+#define F0900_P2_DMDRES_RESET 0xf2c60080
+#define F0900_P2_DMDRES_STRALL 0xf2c60008
+#define F0900_P2_DMDRES_NEWONLY 0xf2c60004
+#define F0900_P2_DMDRES_NOSTORE 0xf2c60002
 
 /*P2_DMDRESADR*/
-#define R0900_P2_DMDRESADR  0xf2c7
-#define F0900_P2_SUSP_PREDCANAL  0xf2c70080
-#define F0900_P2_DMDRES_VALIDCFR  0xf2c70040
-#define F0900_P2_DMDRES_MEMFULL  0xf2c70030
-#define F0900_P2_DMDRES_RESNBR  0xf2c7000f
+#define R0900_P2_DMDRESADR 0xf2c7
+#define F0900_P2_DMDRES_VALIDCFR 0xf2c70040
+#define F0900_P2_DMDRES_MEMFULL 0xf2c70030
+#define F0900_P2_DMDRES_RESNBR 0xf2c7000f
 
 /*P2_DMDRESDATA7*/
-#define R0900_P2_DMDRESDATA7  0xf2c8
-#define F0900_P2_DMDRES_DATA7  0xf2c800ff
+#define R0900_P2_DMDRESDATA7 0xf2c8
+#define F0900_P2_DMDRES_DATA7 0xf2c800ff
 
 /*P2_DMDRESDATA6*/
-#define R0900_P2_DMDRESDATA6  0xf2c9
-#define F0900_P2_DMDRES_DATA6  0xf2c900ff
+#define R0900_P2_DMDRESDATA6 0xf2c9
+#define F0900_P2_DMDRES_DATA6 0xf2c900ff
 
 /*P2_DMDRESDATA5*/
-#define R0900_P2_DMDRESDATA5  0xf2ca
-#define F0900_P2_DMDRES_DATA5  0xf2ca00ff
+#define R0900_P2_DMDRESDATA5 0xf2ca
+#define F0900_P2_DMDRES_DATA5 0xf2ca00ff
 
 /*P2_DMDRESDATA4*/
-#define R0900_P2_DMDRESDATA4  0xf2cb
-#define F0900_P2_DMDRES_DATA4  0xf2cb00ff
+#define R0900_P2_DMDRESDATA4 0xf2cb
+#define F0900_P2_DMDRES_DATA4 0xf2cb00ff
 
 /*P2_DMDRESDATA3*/
-#define R0900_P2_DMDRESDATA3  0xf2cc
-#define F0900_P2_DMDRES_DATA3  0xf2cc00ff
+#define R0900_P2_DMDRESDATA3 0xf2cc
+#define F0900_P2_DMDRES_DATA3 0xf2cc00ff
 
 /*P2_DMDRESDATA2*/
-#define R0900_P2_DMDRESDATA2  0xf2cd
-#define F0900_P2_DMDRES_DATA2  0xf2cd00ff
+#define R0900_P2_DMDRESDATA2 0xf2cd
+#define F0900_P2_DMDRES_DATA2 0xf2cd00ff
 
 /*P2_DMDRESDATA1*/
-#define R0900_P2_DMDRESDATA1  0xf2ce
-#define F0900_P2_DMDRES_DATA1  0xf2ce00ff
+#define R0900_P2_DMDRESDATA1 0xf2ce
+#define F0900_P2_DMDRES_DATA1 0xf2ce00ff
 
 /*P2_DMDRESDATA0*/
-#define R0900_P2_DMDRESDATA0  0xf2cf
-#define F0900_P2_DMDRES_DATA0  0xf2cf00ff
+#define R0900_P2_DMDRESDATA0 0xf2cf
+#define F0900_P2_DMDRES_DATA0 0xf2cf00ff
 
 /*P2_FFEI1*/
-#define R0900_P2_FFEI1  0xf2d0
-#define F0900_P2_FFE_ACCI1  0xf2d001ff
+#define R0900_P2_FFEI1 0xf2d0
+#define F0900_P2_FFE_ACCI1 0xf2d001ff
 
 /*P2_FFEQ1*/
-#define R0900_P2_FFEQ1  0xf2d1
-#define F0900_P2_FFE_ACCQ1  0xf2d101ff
+#define R0900_P2_FFEQ1 0xf2d1
+#define F0900_P2_FFE_ACCQ1 0xf2d101ff
 
 /*P2_FFEI2*/
-#define R0900_P2_FFEI2  0xf2d2
-#define F0900_P2_FFE_ACCI2  0xf2d201ff
+#define R0900_P2_FFEI2 0xf2d2
+#define F0900_P2_FFE_ACCI2 0xf2d201ff
 
 /*P2_FFEQ2*/
-#define R0900_P2_FFEQ2  0xf2d3
-#define F0900_P2_FFE_ACCQ2  0xf2d301ff
+#define R0900_P2_FFEQ2 0xf2d3
+#define F0900_P2_FFE_ACCQ2 0xf2d301ff
 
 /*P2_FFEI3*/
-#define R0900_P2_FFEI3  0xf2d4
-#define F0900_P2_FFE_ACCI3  0xf2d401ff
+#define R0900_P2_FFEI3 0xf2d4
+#define F0900_P2_FFE_ACCI3 0xf2d401ff
 
 /*P2_FFEQ3*/
-#define R0900_P2_FFEQ3  0xf2d5
-#define F0900_P2_FFE_ACCQ3  0xf2d501ff
+#define R0900_P2_FFEQ3 0xf2d5
+#define F0900_P2_FFE_ACCQ3 0xf2d501ff
 
 /*P2_FFEI4*/
-#define R0900_P2_FFEI4  0xf2d6
-#define F0900_P2_FFE_ACCI4  0xf2d601ff
+#define R0900_P2_FFEI4 0xf2d6
+#define F0900_P2_FFE_ACCI4 0xf2d601ff
 
 /*P2_FFEQ4*/
-#define R0900_P2_FFEQ4  0xf2d7
-#define F0900_P2_FFE_ACCQ4  0xf2d701ff
+#define R0900_P2_FFEQ4 0xf2d7
+#define F0900_P2_FFE_ACCQ4 0xf2d701ff
 
 /*P2_FFECFG*/
-#define R0900_P2_FFECFG  0xf2d8
-#define F0900_P2_EQUALFFE_ON  0xf2d80040
-#define F0900_P2_EQUAL_USEDSYMB  0xf2d80030
-#define F0900_P2_MU_EQUALFFE  0xf2d80007
+#define R0900_P2_FFECFG 0xf2d8
+#define F0900_P2_EQUALFFE_ON 0xf2d80040
+#define F0900_P2_MU_EQUALFFE 0xf2d80007
 
 /*P2_TNRCFG*/
-#define R0900_P2_TNRCFG  0xf2e0
-#define F0900_P2_TUN_ACKFAIL  0xf2e00080
-#define F0900_P2_TUN_TYPE  0xf2e00070
-#define F0900_P2_TUN_SECSTOP  0xf2e00008
-#define F0900_P2_TUN_VCOSRCH  0xf2e00004
-#define F0900_P2_TUN_MADDRESS  0xf2e00003
+#define R0900_P2_TNRCFG 0xf2e0
+#define F0900_P2_TUN_ACKFAIL 0xf2e00080
+#define F0900_P2_TUN_TYPE 0xf2e00070
+#define F0900_P2_TUN_SECSTOP 0xf2e00008
+#define F0900_P2_TUN_VCOSRCH 0xf2e00004
+#define F0900_P2_TUN_MADDRESS 0xf2e00003
 
 /*P2_TNRCFG2*/
-#define R0900_P2_TNRCFG2  0xf2e1
-#define F0900_P2_TUN_IQSWAP  0xf2e10080
-#define F0900_P2_STB6110_STEP2MHZ  0xf2e10040
-#define F0900_P2_STB6120_DBLI2C  0xf2e10020
-#define F0900_P2_DIS_FCCK  0xf2e10010
-#define F0900_P2_DIS_LPEN  0xf2e10008
-#define F0900_P2_DIS_BWCALC  0xf2e10004
-#define F0900_P2_SHORT_WAITSTATES  0xf2e10002
-#define F0900_P2_DIS_2BWAGC1  0xf2e10001
+#define R0900_P2_TNRCFG2 0xf2e1
+#define F0900_P2_TUN_IQSWAP 0xf2e10080
+#define F0900_P2_DIS_BWCALC 0xf2e10004
+#define F0900_P2_SHORT_WAITSTATES 0xf2e10002
 
 /*P2_TNRXTAL*/
-#define R0900_P2_TNRXTAL  0xf2e4
-#define F0900_P2_TUN_MCLKDECIMAL  0xf2e400e0
-#define F0900_P2_TUN_XTALFREQ  0xf2e4001f
+#define R0900_P2_TNRXTAL 0xf2e4
+#define F0900_P2_TUN_XTALFREQ 0xf2e4001f
 
 /*P2_TNRSTEPS*/
-#define R0900_P2_TNRSTEPS  0xf2e7
-#define F0900_P2_TUNER_BW1P6  0xf2e70080
-#define F0900_P2_BWINC_OFFSET  0xf2e70070
-#define F0900_P2_SOFTSTEP_RNG  0xf2e70008
-#define F0900_P2_TUN_BWOFFSET  0xf2e70107
+#define R0900_P2_TNRSTEPS 0xf2e7
+#define F0900_P2_TUNER_BW0P125 0xf2e70080
+#define F0900_P2_BWINC_OFFSET 0xf2e70170
+#define F0900_P2_SOFTSTEP_RNG 0xf2e70008
+#define F0900_P2_TUN_BWOFFSET 0xf2e70007
 
 /*P2_TNRGAIN*/
-#define R0900_P2_TNRGAIN  0xf2e8
-#define F0900_P2_TUN_KDIVEN  0xf2e800c0
-#define F0900_P2_STB6X00_OCK  0xf2e80030
-#define F0900_P2_TUN_GAIN  0xf2e8000f
+#define R0900_P2_TNRGAIN 0xf2e8
+#define F0900_P2_TUN_KDIVEN 0xf2e800c0
+#define F0900_P2_STB6X00_OCK 0xf2e80030
+#define F0900_P2_TUN_GAIN 0xf2e8000f
 
 /*P2_TNRRF1*/
-#define R0900_P2_TNRRF1  0xf2e9
-#define F0900_P2_TUN_RFFREQ2  0xf2e900ff
+#define R0900_P2_TNRRF1 0xf2e9
+#define F0900_P2_TUN_RFFREQ2 0xf2e900ff
 
 /*P2_TNRRF0*/
-#define R0900_P2_TNRRF0  0xf2ea
-#define F0900_P2_TUN_RFFREQ1  0xf2ea00ff
+#define R0900_P2_TNRRF0 0xf2ea
+#define F0900_P2_TUN_RFFREQ1 0xf2ea00ff
 
 /*P2_TNRBW*/
-#define R0900_P2_TNRBW  0xf2eb
-#define F0900_P2_TUN_RFFREQ0  0xf2eb00c0
-#define F0900_P2_TUN_BW  0xf2eb003f
+#define R0900_P2_TNRBW 0xf2eb
+#define F0900_P2_TUN_RFFREQ0 0xf2eb00c0
+#define F0900_P2_TUN_BW 0xf2eb003f
 
 /*P2_TNRADJ*/
-#define R0900_P2_TNRADJ  0xf2ec
-#define F0900_P2_STB61X0_RCLK  0xf2ec0080
-#define F0900_P2_STB61X0_CALTIME  0xf2ec0040
-#define F0900_P2_STB6X00_DLB  0xf2ec0038
-#define F0900_P2_STB6000_FCL  0xf2ec0007
+#define R0900_P2_TNRADJ 0xf2ec
+#define F0900_P2_STB61X0_CALTIME 0xf2ec0040
 
 /*P2_TNRCTL2*/
-#define R0900_P2_TNRCTL2  0xf2ed
-#define F0900_P2_STB61X0_LCP1_RCCKOFF  0xf2ed0080
-#define F0900_P2_STB61X0_LCP0  0xf2ed0040
-#define F0900_P2_STB61X0_XTOUT_RFOUTS  0xf2ed0020
-#define F0900_P2_STB61X0_XTON_MCKDV  0xf2ed0010
-#define F0900_P2_STB61X0_CALOFF_DCOFF  0xf2ed0008
-#define F0900_P2_STB6110_LPT  0xf2ed0004
-#define F0900_P2_STB6110_RX  0xf2ed0002
-#define F0900_P2_STB6110_SYN  0xf2ed0001
+#define R0900_P2_TNRCTL2 0xf2ed
+#define F0900_P2_STB61X0_RCCKOFF 0xf2ed0080
+#define F0900_P2_STB61X0_ICP_SDOFF 0xf2ed0040
+#define F0900_P2_STB61X0_DCLOOPOFF 0xf2ed0020
+#define F0900_P2_STB61X0_REFOUTSEL 0xf2ed0010
+#define F0900_P2_STB61X0_CALOFF 0xf2ed0008
+#define F0900_P2_STB6XX0_LPT_BEN 0xf2ed0004
+#define F0900_P2_STB6XX0_RX_OSCP 0xf2ed0002
+#define F0900_P2_STB6XX0_SYN 0xf2ed0001
 
 /*P2_TNRCFG3*/
-#define R0900_P2_TNRCFG3  0xf2ee
-#define F0900_P2_STB6120_DISCTRL1  0xf2ee0080
-#define F0900_P2_STB6120_INVORDER  0xf2ee0040
-#define F0900_P2_STB6120_ENCTRL6  0xf2ee0020
-#define F0900_P2_TUN_PLLFREQ  0xf2ee001c
-#define F0900_P2_TUN_I2CFREQ_MODE  0xf2ee0003
+#define R0900_P2_TNRCFG3 0xf2ee
+#define F0900_P2_TUN_PLLFREQ 0xf2ee001c
+#define F0900_P2_TUN_I2CFREQ_MODE 0xf2ee0003
 
 /*P2_TNRLAUNCH*/
-#define R0900_P2_TNRLAUNCH  0xf2f0
+#define R0900_P2_TNRLAUNCH 0xf2f0
 
 /*P2_TNRLD*/
-#define R0900_P2_TNRLD  0xf2f0
-#define F0900_P2_TUNLD_VCOING  0xf2f00080
-#define F0900_P2_TUN_REG1FAIL  0xf2f00040
-#define F0900_P2_TUN_REG2FAIL  0xf2f00020
-#define F0900_P2_TUN_REG3FAIL  0xf2f00010
-#define F0900_P2_TUN_REG4FAIL  0xf2f00008
-#define F0900_P2_TUN_REG5FAIL  0xf2f00004
-#define F0900_P2_TUN_BWING  0xf2f00002
-#define F0900_P2_TUN_LOCKED  0xf2f00001
+#define R0900_P2_TNRLD 0xf2f0
+#define F0900_P2_TUNLD_VCOING 0xf2f00080
+#define F0900_P2_TUN_REG1FAIL 0xf2f00040
+#define F0900_P2_TUN_REG2FAIL 0xf2f00020
+#define F0900_P2_TUN_REG3FAIL 0xf2f00010
+#define F0900_P2_TUN_REG4FAIL 0xf2f00008
+#define F0900_P2_TUN_REG5FAIL 0xf2f00004
+#define F0900_P2_TUN_BWING 0xf2f00002
+#define F0900_P2_TUN_LOCKED 0xf2f00001
 
 /*P2_TNROBSL*/
-#define R0900_P2_TNROBSL  0xf2f6
-#define F0900_P2_TUN_I2CABORTED  0xf2f60080
-#define F0900_P2_TUN_LPEN  0xf2f60040
-#define F0900_P2_TUN_FCCK  0xf2f60020
-#define F0900_P2_TUN_I2CLOCKED  0xf2f60010
-#define F0900_P2_TUN_PROGDONE  0xf2f6000c
-#define F0900_P2_TUN_RFRESTE1  0xf2f60003
+#define R0900_P2_TNROBSL 0xf2f6
+#define F0900_P2_TUN_I2CABORTED 0xf2f60080
+#define F0900_P2_TUN_LPEN 0xf2f60040
+#define F0900_P2_TUN_FCCK 0xf2f60020
+#define F0900_P2_TUN_I2CLOCKED 0xf2f60010
+#define F0900_P2_TUN_PROGDONE 0xf2f6000c
+#define F0900_P2_TUN_RFRESTE1 0xf2f60003
 
 /*P2_TNRRESTE*/
-#define R0900_P2_TNRRESTE  0xf2f7
-#define F0900_P2_TUN_RFRESTE0  0xf2f700ff
+#define R0900_P2_TNRRESTE 0xf2f7
+#define F0900_P2_TUN_RFRESTE0 0xf2f700ff
 
 /*P2_SMAPCOEF7*/
-#define R0900_P2_SMAPCOEF7  0xf300
-#define F0900_P2_DIS_QSCALE  0xf3000080
-#define F0900_P2_SMAPCOEF_Q_LLR12  0xf300017f
+#define R0900_P2_SMAPCOEF7 0xf300
+#define F0900_P2_DIS_QSCALE 0xf3000080
+#define F0900_P2_SMAPCOEF_Q_LLR12 0xf300017f
 
 /*P2_SMAPCOEF6*/
-#define R0900_P2_SMAPCOEF6  0xf301
-#define F0900_P2_DIS_NEWSCALE  0xf3010008
-#define F0900_P2_ADJ_8PSKLLR1  0xf3010004
-#define F0900_P2_OLD_8PSKLLR1  0xf3010002
-#define F0900_P2_DIS_AB8PSK  0xf3010001
+#define R0900_P2_SMAPCOEF6 0xf301
+#define F0900_P2_ADJ_8PSKLLR1 0xf3010004
+#define F0900_P2_OLD_8PSKLLR1 0xf3010002
+#define F0900_P2_DIS_AB8PSK 0xf3010001
 
 /*P2_SMAPCOEF5*/
-#define R0900_P2_SMAPCOEF5  0xf302
-#define F0900_P2_DIS_8SCALE  0xf3020080
-#define F0900_P2_SMAPCOEF_8P_LLR23  0xf302017f
+#define R0900_P2_SMAPCOEF5 0xf302
+#define F0900_P2_DIS_8SCALE 0xf3020080
+#define F0900_P2_SMAPCOEF_8P_LLR23 0xf302017f
+
+/*P2_NCO2MAX1*/
+#define R0900_P2_NCO2MAX1 0xf314
+#define F0900_P2_TETA2_MAXVABS1 0xf31400ff
+
+/*P2_NCO2MAX0*/
+#define R0900_P2_NCO2MAX0 0xf315
+#define F0900_P2_TETA2_MAXVABS0 0xf31500ff
+
+/*P2_NCO2FR1*/
+#define R0900_P2_NCO2FR1 0xf316
+#define F0900_P2_NCO2FINAL_ANGLE1 0xf31600ff
+
+/*P2_NCO2FR0*/
+#define R0900_P2_NCO2FR0 0xf317
+#define F0900_P2_NCO2FINAL_ANGLE0 0xf31700ff
+
+/*P2_CFR2AVRGE1*/
+#define R0900_P2_CFR2AVRGE1 0xf318
+#define F0900_P2_I2C_CFR2AVERAGE1 0xf31800ff
+
+/*P2_CFR2AVRGE0*/
+#define R0900_P2_CFR2AVRGE0 0xf319
+#define F0900_P2_I2C_CFR2AVERAGE0 0xf31900ff
 
 /*P2_DMDPLHSTAT*/
-#define R0900_P2_DMDPLHSTAT  0xf320
-#define F0900_P2_PLH_STATISTIC  0xf32000ff
+#define R0900_P2_DMDPLHSTAT 0xf320
+#define F0900_P2_PLH_STATISTIC 0xf32000ff
 
 /*P2_LOCKTIME3*/
-#define R0900_P2_LOCKTIME3  0xf322
-#define F0900_P2_DEMOD_LOCKTIME3  0xf32200ff
+#define R0900_P2_LOCKTIME3 0xf322
+#define F0900_P2_DEMOD_LOCKTIME3 0xf32200ff
 
 /*P2_LOCKTIME2*/
-#define R0900_P2_LOCKTIME2  0xf323
-#define F0900_P2_DEMOD_LOCKTIME2  0xf32300ff
+#define R0900_P2_LOCKTIME2 0xf323
+#define F0900_P2_DEMOD_LOCKTIME2 0xf32300ff
 
 /*P2_LOCKTIME1*/
-#define R0900_P2_LOCKTIME1  0xf324
-#define F0900_P2_DEMOD_LOCKTIME1  0xf32400ff
+#define R0900_P2_LOCKTIME1 0xf324
+#define F0900_P2_DEMOD_LOCKTIME1 0xf32400ff
 
 /*P2_LOCKTIME0*/
-#define R0900_P2_LOCKTIME0  0xf325
-#define F0900_P2_DEMOD_LOCKTIME0  0xf32500ff
+#define R0900_P2_LOCKTIME0 0xf325
+#define F0900_P2_DEMOD_LOCKTIME0 0xf32500ff
 
 /*P2_VITSCALE*/
-#define R0900_P2_VITSCALE  0xf332
-#define F0900_P2_NVTH_NOSRANGE  0xf3320080
-#define F0900_P2_VERROR_MAXMODE  0xf3320040
-#define F0900_P2_KDIV_MODE  0xf3320030
-#define F0900_P2_NSLOWSN_LOCKED  0xf3320008
-#define F0900_P2_DELOCK_PRFLOSS  0xf3320004
-#define F0900_P2_DIS_RSFLOCK  0xf3320002
+#define R0900_P2_VITSCALE 0xf332
+#define F0900_P2_NVTH_NOSRANGE 0xf3320080
+#define F0900_P2_VERROR_MAXMODE 0xf3320040
+#define F0900_P2_NSLOWSN_LOCKED 0xf3320008
+#define F0900_P2_DIS_RSFLOCK 0xf3320002
 
 /*P2_FECM*/
-#define R0900_P2_FECM  0xf333
-#define F0900_P2_DSS_DVB  0xf3330080
-#define F0900_P2_DEMOD_BYPASS  0xf3330040
-#define F0900_P2_CMP_SLOWMODE  0xf3330020
-#define F0900_P2_DSS_SRCH  0xf3330010
-#define F0900_P2_DIFF_MODEVIT  0xf3330004
-#define F0900_P2_SYNCVIT  0xf3330002
-#define F0900_P2_IQINV  0xf3330001
+#define R0900_P2_FECM 0xf333
+#define F0900_P2_DSS_DVB 0xf3330080
+#define F0900_P2_DSS_SRCH 0xf3330010
+#define F0900_P2_SYNCVIT 0xf3330002
+#define F0900_P2_IQINV 0xf3330001
 
 /*P2_VTH12*/
-#define R0900_P2_VTH12  0xf334
-#define F0900_P2_VTH12  0xf33400ff
+#define R0900_P2_VTH12 0xf334
+#define F0900_P2_VTH12 0xf33400ff
 
 /*P2_VTH23*/
-#define R0900_P2_VTH23  0xf335
-#define F0900_P2_VTH23  0xf33500ff
+#define R0900_P2_VTH23 0xf335
+#define F0900_P2_VTH23 0xf33500ff
 
 /*P2_VTH34*/
-#define R0900_P2_VTH34  0xf336
-#define F0900_P2_VTH34  0xf33600ff
+#define R0900_P2_VTH34 0xf336
+#define F0900_P2_VTH34 0xf33600ff
 
 /*P2_VTH56*/
-#define R0900_P2_VTH56  0xf337
-#define F0900_P2_VTH56  0xf33700ff
+#define R0900_P2_VTH56 0xf337
+#define F0900_P2_VTH56 0xf33700ff
 
 /*P2_VTH67*/
-#define R0900_P2_VTH67  0xf338
-#define F0900_P2_VTH67  0xf33800ff
+#define R0900_P2_VTH67 0xf338
+#define F0900_P2_VTH67 0xf33800ff
 
 /*P2_VTH78*/
-#define R0900_P2_VTH78  0xf339
-#define F0900_P2_VTH78  0xf33900ff
+#define R0900_P2_VTH78 0xf339
+#define F0900_P2_VTH78 0xf33900ff
 
 /*P2_VITCURPUN*/
-#define R0900_P2_VITCURPUN  0xf33a
-#define F0900_P2_VIT_MAPPING  0xf33a00e0
-#define F0900_P2_VIT_CURPUN  0xf33a001f
+#define R0900_P2_VITCURPUN 0xf33a
+#define F0900_P2_VIT_CURPUN 0xf33a001f
 
 /*P2_VERROR*/
-#define R0900_P2_VERROR  0xf33b
-#define F0900_P2_REGERR_VIT  0xf33b00ff
+#define R0900_P2_VERROR 0xf33b
+#define F0900_P2_REGERR_VIT 0xf33b00ff
 
 /*P2_PRVIT*/
-#define R0900_P2_PRVIT  0xf33c
-#define F0900_P2_DIS_VTHLOCK  0xf33c0040
-#define F0900_P2_E7_8VIT  0xf33c0020
-#define F0900_P2_E6_7VIT  0xf33c0010
-#define F0900_P2_E5_6VIT  0xf33c0008
-#define F0900_P2_E3_4VIT  0xf33c0004
-#define F0900_P2_E2_3VIT  0xf33c0002
-#define F0900_P2_E1_2VIT  0xf33c0001
+#define R0900_P2_PRVIT 0xf33c
+#define F0900_P2_DIS_VTHLOCK 0xf33c0040
+#define F0900_P2_E7_8VIT 0xf33c0020
+#define F0900_P2_E6_7VIT 0xf33c0010
+#define F0900_P2_E5_6VIT 0xf33c0008
+#define F0900_P2_E3_4VIT 0xf33c0004
+#define F0900_P2_E2_3VIT 0xf33c0002
+#define F0900_P2_E1_2VIT 0xf33c0001
 
 /*P2_VAVSRVIT*/
-#define R0900_P2_VAVSRVIT  0xf33d
-#define F0900_P2_AMVIT  0xf33d0080
-#define F0900_P2_FROZENVIT  0xf33d0040
-#define F0900_P2_SNVIT  0xf33d0030
-#define F0900_P2_TOVVIT  0xf33d000c
-#define F0900_P2_HYPVIT  0xf33d0003
+#define R0900_P2_VAVSRVIT 0xf33d
+#define F0900_P2_AMVIT 0xf33d0080
+#define F0900_P2_FROZENVIT 0xf33d0040
+#define F0900_P2_SNVIT 0xf33d0030
+#define F0900_P2_TOVVIT 0xf33d000c
+#define F0900_P2_HYPVIT 0xf33d0003
 
 /*P2_VSTATUSVIT*/
-#define R0900_P2_VSTATUSVIT  0xf33e
-#define F0900_P2_VITERBI_ON  0xf33e0080
-#define F0900_P2_END_LOOPVIT  0xf33e0040
-#define F0900_P2_VITERBI_DEPRF  0xf33e0020
-#define F0900_P2_PRFVIT  0xf33e0010
-#define F0900_P2_LOCKEDVIT  0xf33e0008
-#define F0900_P2_VITERBI_DELOCK  0xf33e0004
-#define F0900_P2_VIT_DEMODSEL  0xf33e0002
-#define F0900_P2_VITERBI_COMPOUT  0xf33e0001
+#define R0900_P2_VSTATUSVIT 0xf33e
+#define F0900_P2_PRFVIT 0xf33e0010
+#define F0900_P2_LOCKEDVIT 0xf33e0008
 
 /*P2_VTHINUSE*/
-#define R0900_P2_VTHINUSE  0xf33f
-#define F0900_P2_VIT_INUSE  0xf33f00ff
+#define R0900_P2_VTHINUSE 0xf33f
+#define F0900_P2_VIT_INUSE 0xf33f00ff
 
 /*P2_KDIV12*/
-#define R0900_P2_KDIV12  0xf340
-#define F0900_P2_KDIV12_MANUAL  0xf3400080
-#define F0900_P2_K_DIVIDER_12  0xf340007f
+#define R0900_P2_KDIV12 0xf340
+#define F0900_P2_K_DIVIDER_12 0xf340007f
 
 /*P2_KDIV23*/
-#define R0900_P2_KDIV23  0xf341
-#define F0900_P2_KDIV23_MANUAL  0xf3410080
-#define F0900_P2_K_DIVIDER_23  0xf341007f
+#define R0900_P2_KDIV23 0xf341
+#define F0900_P2_K_DIVIDER_23 0xf341007f
 
 /*P2_KDIV34*/
-#define R0900_P2_KDIV34  0xf342
-#define F0900_P2_KDIV34_MANUAL  0xf3420080
-#define F0900_P2_K_DIVIDER_34  0xf342007f
+#define R0900_P2_KDIV34 0xf342
+#define F0900_P2_K_DIVIDER_34 0xf342007f
 
 /*P2_KDIV56*/
-#define R0900_P2_KDIV56  0xf343
-#define F0900_P2_KDIV56_MANUAL  0xf3430080
-#define F0900_P2_K_DIVIDER_56  0xf343007f
+#define R0900_P2_KDIV56 0xf343
+#define F0900_P2_K_DIVIDER_56 0xf343007f
 
 /*P2_KDIV67*/
-#define R0900_P2_KDIV67  0xf344
-#define F0900_P2_KDIV67_MANUAL  0xf3440080
-#define F0900_P2_K_DIVIDER_67  0xf344007f
+#define R0900_P2_KDIV67 0xf344
+#define F0900_P2_K_DIVIDER_67 0xf344007f
 
 /*P2_KDIV78*/
-#define R0900_P2_KDIV78  0xf345
-#define F0900_P2_KDIV78_MANUAL  0xf3450080
-#define F0900_P2_K_DIVIDER_78  0xf345007f
+#define R0900_P2_KDIV78 0xf345
+#define F0900_P2_K_DIVIDER_78 0xf345007f
 
 /*P2_PDELCTRL1*/
-#define R0900_P2_PDELCTRL1  0xf350
-#define F0900_P2_INV_MISMASK  0xf3500080
-#define F0900_P2_FORCE_ACCEPTED  0xf3500040
-#define F0900_P2_FILTER_EN  0xf3500020
-#define F0900_P2_FORCE_PKTDELINUSE  0xf3500010
-#define F0900_P2_HYSTEN  0xf3500008
-#define F0900_P2_HYSTSWRST  0xf3500004
-#define F0900_P2_EN_MIS00  0xf3500002
-#define F0900_P2_ALGOSWRST  0xf3500001
+#define R0900_P2_PDELCTRL1 0xf350
+#define F0900_P2_INV_MISMASK 0xf3500080
+#define F0900_P2_FILTER_EN 0xf3500020
+#define F0900_P2_EN_MIS00 0xf3500002
+#define F0900_P2_ALGOSWRST 0xf3500001
 
 /*P2_PDELCTRL2*/
-#define R0900_P2_PDELCTRL2  0xf351
-#define F0900_P2_FORCE_CONTINUOUS  0xf3510080
-#define F0900_P2_RESET_UPKO_COUNT  0xf3510040
-#define F0900_P2_USER_PKTDELIN_NB  0xf3510020
-#define F0900_P2_FORCE_LOCKED  0xf3510010
-#define F0900_P2_DATA_UNBBSCRAM  0xf3510008
-#define F0900_P2_FORCE_LONGPKT  0xf3510004
-#define F0900_P2_FRAME_MODE  0xf3510002
+#define R0900_P2_PDELCTRL2 0xf351
+#define F0900_P2_RESET_UPKO_COUNT 0xf3510040
+#define F0900_P2_FRAME_MODE 0xf3510002
+#define F0900_P2_NOBCHERRFLG_USE 0xf3510001
 
 /*P2_HYSTTHRESH*/
-#define R0900_P2_HYSTTHRESH  0xf354
-#define F0900_P2_UNLCK_THRESH  0xf35400f0
-#define F0900_P2_DELIN_LCK_THRESH  0xf354000f
+#define R0900_P2_HYSTTHRESH 0xf354
+#define F0900_P2_UNLCK_THRESH 0xf35400f0
+#define F0900_P2_DELIN_LCK_THRESH 0xf354000f
 
 /*P2_ISIENTRY*/
-#define R0900_P2_ISIENTRY  0xf35e
-#define F0900_P2_ISI_ENTRY  0xf35e00ff
+#define R0900_P2_ISIENTRY 0xf35e
+#define F0900_P2_ISI_ENTRY 0xf35e00ff
 
 /*P2_ISIBITENA*/
-#define R0900_P2_ISIBITENA  0xf35f
-#define F0900_P2_ISI_BIT_EN  0xf35f00ff
+#define R0900_P2_ISIBITENA 0xf35f
+#define F0900_P2_ISI_BIT_EN 0xf35f00ff
 
 /*P2_MATSTR1*/
-#define R0900_P2_MATSTR1  0xf360
-#define F0900_P2_MATYPE_CURRENT1  0xf36000ff
+#define R0900_P2_MATSTR1 0xf360
+#define F0900_P2_MATYPE_CURRENT1 0xf36000ff
 
 /*P2_MATSTR0*/
-#define R0900_P2_MATSTR0  0xf361
-#define F0900_P2_MATYPE_CURRENT0  0xf36100ff
+#define R0900_P2_MATSTR0 0xf361
+#define F0900_P2_MATYPE_CURRENT0 0xf36100ff
 
 /*P2_UPLSTR1*/
-#define R0900_P2_UPLSTR1  0xf362
-#define F0900_P2_UPL_CURRENT1  0xf36200ff
+#define R0900_P2_UPLSTR1 0xf362
+#define F0900_P2_UPL_CURRENT1 0xf36200ff
 
 /*P2_UPLSTR0*/
-#define R0900_P2_UPLSTR0  0xf363
-#define F0900_P2_UPL_CURRENT0  0xf36300ff
+#define R0900_P2_UPLSTR0 0xf363
+#define F0900_P2_UPL_CURRENT0 0xf36300ff
 
 /*P2_DFLSTR1*/
-#define R0900_P2_DFLSTR1  0xf364
-#define F0900_P2_DFL_CURRENT1  0xf36400ff
+#define R0900_P2_DFLSTR1 0xf364
+#define F0900_P2_DFL_CURRENT1 0xf36400ff
 
 /*P2_DFLSTR0*/
-#define R0900_P2_DFLSTR0  0xf365
-#define F0900_P2_DFL_CURRENT0  0xf36500ff
+#define R0900_P2_DFLSTR0 0xf365
+#define F0900_P2_DFL_CURRENT0 0xf36500ff
 
 /*P2_SYNCSTR*/
-#define R0900_P2_SYNCSTR  0xf366
-#define F0900_P2_SYNC_CURRENT  0xf36600ff
+#define R0900_P2_SYNCSTR 0xf366
+#define F0900_P2_SYNC_CURRENT 0xf36600ff
 
 /*P2_SYNCDSTR1*/
-#define R0900_P2_SYNCDSTR1  0xf367
-#define F0900_P2_SYNCD_CURRENT1  0xf36700ff
+#define R0900_P2_SYNCDSTR1 0xf367
+#define F0900_P2_SYNCD_CURRENT1 0xf36700ff
 
 /*P2_SYNCDSTR0*/
-#define R0900_P2_SYNCDSTR0  0xf368
-#define F0900_P2_SYNCD_CURRENT0  0xf36800ff
+#define R0900_P2_SYNCDSTR0 0xf368
+#define F0900_P2_SYNCD_CURRENT0 0xf36800ff
 
 /*P2_PDELSTATUS1*/
-#define R0900_P2_PDELSTATUS1  0xf369
-#define F0900_P2_PKTDELIN_DELOCK  0xf3690080
-#define F0900_P2_SYNCDUPDFL_BADDFL  0xf3690040
-#define F0900_P2_CONTINUOUS_STREAM  0xf3690020
-#define F0900_P2_UNACCEPTED_STREAM  0xf3690010
-#define F0900_P2_BCH_ERROR_FLAG  0xf3690008
-#define F0900_P2_BBHCRCKO  0xf3690004
-#define F0900_P2_PKTDELIN_LOCK  0xf3690002
-#define F0900_P2_FIRST_LOCK  0xf3690001
+#define R0900_P2_PDELSTATUS1 0xf369
+#define F0900_P2_PKTDELIN_DELOCK 0xf3690080
+#define F0900_P2_SYNCDUPDFL_BADDFL 0xf3690040
+#define F0900_P2_CONTINUOUS_STREAM 0xf3690020
+#define F0900_P2_UNACCEPTED_STREAM 0xf3690010
+#define F0900_P2_BCH_ERROR_FLAG 0xf3690008
+#define F0900_P2_PKTDELIN_LOCK 0xf3690002
+#define F0900_P2_FIRST_LOCK 0xf3690001
 
 /*P2_PDELSTATUS2*/
-#define R0900_P2_PDELSTATUS2  0xf36a
-#define F0900_P2_PKTDEL_DEMODSEL  0xf36a0080
-#define F0900_P2_FRAME_MODCOD  0xf36a007c
-#define F0900_P2_FRAME_TYPE  0xf36a0003
+#define R0900_P2_PDELSTATUS2 0xf36a
+#define F0900_P2_FRAME_MODCOD 0xf36a007c
+#define F0900_P2_FRAME_TYPE 0xf36a0003
 
 /*P2_BBFCRCKO1*/
-#define R0900_P2_BBFCRCKO1  0xf36b
-#define F0900_P2_BBHCRC_KOCNT1  0xf36b00ff
+#define R0900_P2_BBFCRCKO1 0xf36b
+#define F0900_P2_BBHCRC_KOCNT1 0xf36b00ff
 
 /*P2_BBFCRCKO0*/
-#define R0900_P2_BBFCRCKO0  0xf36c
-#define F0900_P2_BBHCRC_KOCNT0  0xf36c00ff
+#define R0900_P2_BBFCRCKO0 0xf36c
+#define F0900_P2_BBHCRC_KOCNT0 0xf36c00ff
 
 /*P2_UPCRCKO1*/
-#define R0900_P2_UPCRCKO1  0xf36d
-#define F0900_P2_PKTCRC_KOCNT1  0xf36d00ff
+#define R0900_P2_UPCRCKO1 0xf36d
+#define F0900_P2_PKTCRC_KOCNT1 0xf36d00ff
 
 /*P2_UPCRCKO0*/
-#define R0900_P2_UPCRCKO0  0xf36e
-#define F0900_P2_PKTCRC_KOCNT0  0xf36e00ff
+#define R0900_P2_UPCRCKO0 0xf36e
+#define F0900_P2_PKTCRC_KOCNT0 0xf36e00ff
+
+/*P2_PDELCTRL3*/
+#define R0900_P2_PDELCTRL3 0xf36f
+#define F0900_P2_PKTDEL_CONTFAIL 0xf36f0080
+#define F0900_P2_NOFIFO_BCHERR 0xf36f0020
 
 /*P2_TSSTATEM*/
-#define R0900_P2_TSSTATEM  0xf370
-#define F0900_P2_TSDIL_ON  0xf3700080
-#define F0900_P2_TSSKIPRS_ON  0xf3700040
-#define F0900_P2_TSRS_ON  0xf3700020
-#define F0900_P2_TSDESCRAMB_ON  0xf3700010
-#define F0900_P2_TSFRAME_MODE  0xf3700008
-#define F0900_P2_TS_DISABLE  0xf3700004
-#define F0900_P2_TSACM_MODE  0xf3700002
-#define F0900_P2_TSOUT_NOSYNC  0xf3700001
+#define R0900_P2_TSSTATEM 0xf370
+#define F0900_P2_TSDIL_ON 0xf3700080
+#define F0900_P2_TSRS_ON 0xf3700020
+#define F0900_P2_TSDESCRAMB_ON 0xf3700010
+#define F0900_P2_TSFRAME_MODE 0xf3700008
+#define F0900_P2_TS_DISABLE 0xf3700004
+#define F0900_P2_TSOUT_NOSYNC 0xf3700001
 
 /*P2_TSCFGH*/
-#define R0900_P2_TSCFGH  0xf372
-#define F0900_P2_TSFIFO_DVBCI  0xf3720080
-#define F0900_P2_TSFIFO_SERIAL  0xf3720040
-#define F0900_P2_TSFIFO_TEIUPDATE  0xf3720020
-#define F0900_P2_TSFIFO_DUTY50  0xf3720010
-#define F0900_P2_TSFIFO_HSGNLOUT  0xf3720008
-#define F0900_P2_TSFIFO_ERRMODE  0xf3720006
-#define F0900_P2_RST_HWARE  0xf3720001
+#define R0900_P2_TSCFGH 0xf372
+#define F0900_P2_TSFIFO_DVBCI 0xf3720080
+#define F0900_P2_TSFIFO_SERIAL 0xf3720040
+#define F0900_P2_TSFIFO_TEIUPDATE 0xf3720020
+#define F0900_P2_TSFIFO_DUTY50 0xf3720010
+#define F0900_P2_TSFIFO_HSGNLOUT 0xf3720008
+#define F0900_P2_TSFIFO_ERRMODE 0xf3720006
+#define F0900_P2_RST_HWARE 0xf3720001
 
 /*P2_TSCFGM*/
-#define R0900_P2_TSCFGM  0xf373
-#define F0900_P2_TSFIFO_MANSPEED  0xf37300c0
-#define F0900_P2_TSFIFO_PERMDATA  0xf3730020
-#define F0900_P2_TSFIFO_NONEWSGNL  0xf3730010
-#define F0900_P2_TSFIFO_BITSPEED  0xf3730008
-#define F0900_P2_NPD_SPECDVBS2  0xf3730004
-#define F0900_P2_TSFIFO_STOPCKDIS  0xf3730002
-#define F0900_P2_TSFIFO_INVDATA  0xf3730001
+#define R0900_P2_TSCFGM 0xf373
+#define F0900_P2_TSFIFO_MANSPEED 0xf37300c0
+#define F0900_P2_TSFIFO_PERMDATA 0xf3730020
+#define F0900_P2_TSFIFO_DPUNACT 0xf3730002
+#define F0900_P2_TSFIFO_INVDATA 0xf3730001
 
 /*P2_TSCFGL*/
-#define R0900_P2_TSCFGL  0xf374
-#define F0900_P2_TSFIFO_BCLKDEL1CK  0xf37400c0
-#define F0900_P2_BCHERROR_MODE  0xf3740030
-#define F0900_P2_TSFIFO_NSGNL2DATA  0xf3740008
-#define F0900_P2_TSFIFO_EMBINDVB  0xf3740004
-#define F0900_P2_TSFIFO_DPUNACT  0xf3740002
-#define F0900_P2_TSFIFO_NPDOFF  0xf3740001
+#define R0900_P2_TSCFGL 0xf374
+#define F0900_P2_TSFIFO_BCLKDEL1CK 0xf37400c0
+#define F0900_P2_BCHERROR_MODE 0xf3740030
+#define F0900_P2_TSFIFO_NSGNL2DATA 0xf3740008
+#define F0900_P2_TSFIFO_EMBINDVB 0xf3740004
+#define F0900_P2_TSFIFO_BITSPEED 0xf3740003
 
 /*P2_TSINSDELH*/
-#define R0900_P2_TSINSDELH  0xf376
-#define F0900_P2_TSDEL_SYNCBYTE  0xf3760080
-#define F0900_P2_TSDEL_XXHEADER  0xf3760040
-#define F0900_P2_TSDEL_BBHEADER  0xf3760020
-#define F0900_P2_TSDEL_DATAFIELD  0xf3760010
-#define F0900_P2_TSINSDEL_ISCR  0xf3760008
-#define F0900_P2_TSINSDEL_NPD  0xf3760004
-#define F0900_P2_TSINSDEL_RSPARITY  0xf3760002
-#define F0900_P2_TSINSDEL_CRC8  0xf3760001
+#define R0900_P2_TSINSDELH 0xf376
+#define F0900_P2_TSDEL_SYNCBYTE 0xf3760080
+#define F0900_P2_TSDEL_XXHEADER 0xf3760040
+#define F0900_P2_TSDEL_BBHEADER 0xf3760020
+#define F0900_P2_TSDEL_DATAFIELD 0xf3760010
+#define F0900_P2_TSINSDEL_ISCR 0xf3760008
+#define F0900_P2_TSINSDEL_NPD 0xf3760004
+#define F0900_P2_TSINSDEL_RSPARITY 0xf3760002
+#define F0900_P2_TSINSDEL_CRC8 0xf3760001
+
+/*P2_TSDIVN*/
+#define R0900_P2_TSDIVN 0xf379
+#define F0900_P2_TSFIFO_SPEEDMODE 0xf37900c0
+
+/*P2_TSCFG4*/
+#define R0900_P2_TSCFG4 0xf37a
+#define F0900_P2_TSFIFO_TSSPEEDMODE 0xf37a00c0
 
 /*P2_TSSPEED*/
-#define R0900_P2_TSSPEED  0xf380
-#define F0900_P2_TSFIFO_OUTSPEED  0xf38000ff
+#define R0900_P2_TSSPEED 0xf380
+#define F0900_P2_TSFIFO_OUTSPEED 0xf38000ff
 
 /*P2_TSSTATUS*/
-#define R0900_P2_TSSTATUS  0xf381
-#define F0900_P2_TSFIFO_LINEOK  0xf3810080
-#define F0900_P2_TSFIFO_ERROR  0xf3810040
-#define F0900_P2_TSFIFO_DATA7  0xf3810020
-#define F0900_P2_TSFIFO_NOSYNC  0xf3810010
-#define F0900_P2_ISCR_INITIALIZED  0xf3810008
-#define F0900_P2_ISCR_UPDATED  0xf3810004
-#define F0900_P2_SOFFIFO_UNREGUL  0xf3810002
-#define F0900_P2_DIL_READY  0xf3810001
+#define R0900_P2_TSSTATUS 0xf381
+#define F0900_P2_TSFIFO_LINEOK 0xf3810080
+#define F0900_P2_TSFIFO_ERROR 0xf3810040
+#define F0900_P2_DIL_READY 0xf3810001
 
 /*P2_TSSTATUS2*/
-#define R0900_P2_TSSTATUS2  0xf382
-#define F0900_P2_TSFIFO_DEMODSEL  0xf3820080
-#define F0900_P2_TSFIFOSPEED_STORE  0xf3820040
-#define F0900_P2_DILXX_RESET  0xf3820020
-#define F0900_P2_TSSERIAL_IMPOS  0xf3820010
-#define F0900_P2_TSFIFO_LINENOK  0xf3820008
-#define F0900_P2_BITSPEED_EVENT  0xf3820004
-#define F0900_P2_SCRAMBDETECT  0xf3820002
-#define F0900_P2_ULDTV67_FALSELOCK  0xf3820001
+#define R0900_P2_TSSTATUS2 0xf382
+#define F0900_P2_TSFIFO_DEMODSEL 0xf3820080
+#define F0900_P2_TSFIFOSPEED_STORE 0xf3820040
+#define F0900_P2_DILXX_RESET 0xf3820020
+#define F0900_P2_TSSERIAL_IMPOS 0xf3820010
+#define F0900_P2_SCRAMBDETECT 0xf3820002
 
 /*P2_TSBITRATE1*/
-#define R0900_P2_TSBITRATE1  0xf383
-#define F0900_P2_TSFIFO_BITRATE1  0xf38300ff
+#define R0900_P2_TSBITRATE1 0xf383
+#define F0900_P2_TSFIFO_BITRATE1 0xf38300ff
 
 /*P2_TSBITRATE0*/
-#define R0900_P2_TSBITRATE0  0xf384
-#define F0900_P2_TSFIFO_BITRATE0  0xf38400ff
+#define R0900_P2_TSBITRATE0 0xf384
+#define F0900_P2_TSFIFO_BITRATE0 0xf38400ff
 
 /*P2_ERRCTRL1*/
-#define R0900_P2_ERRCTRL1  0xf398
-#define F0900_P2_ERR_SOURCE1  0xf39800f0
-#define F0900_P2_NUM_EVENT1  0xf3980007
+#define R0900_P2_ERRCTRL1 0xf398
+#define F0900_P2_ERR_SOURCE1 0xf39800f0
+#define F0900_P2_NUM_EVENT1 0xf3980007
 
 /*P2_ERRCNT12*/
-#define R0900_P2_ERRCNT12  0xf399
-#define F0900_P2_ERRCNT1_OLDVALUE  0xf3990080
-#define F0900_P2_ERR_CNT12  0xf399007f
+#define R0900_P2_ERRCNT12 0xf399
+#define F0900_P2_ERRCNT1_OLDVALUE 0xf3990080
+#define F0900_P2_ERR_CNT12 0xf399007f
 
 /*P2_ERRCNT11*/
-#define R0900_P2_ERRCNT11  0xf39a
-#define F0900_P2_ERR_CNT11  0xf39a00ff
+#define R0900_P2_ERRCNT11 0xf39a
+#define F0900_P2_ERR_CNT11 0xf39a00ff
 
 /*P2_ERRCNT10*/
-#define R0900_P2_ERRCNT10  0xf39b
-#define F0900_P2_ERR_CNT10  0xf39b00ff
+#define R0900_P2_ERRCNT10 0xf39b
+#define F0900_P2_ERR_CNT10 0xf39b00ff
 
 /*P2_ERRCTRL2*/
-#define R0900_P2_ERRCTRL2  0xf39c
-#define F0900_P2_ERR_SOURCE2  0xf39c00f0
-#define F0900_P2_NUM_EVENT2  0xf39c0007
+#define R0900_P2_ERRCTRL2 0xf39c
+#define F0900_P2_ERR_SOURCE2 0xf39c00f0
+#define F0900_P2_NUM_EVENT2 0xf39c0007
 
 /*P2_ERRCNT22*/
-#define R0900_P2_ERRCNT22  0xf39d
-#define F0900_P2_ERRCNT2_OLDVALUE  0xf39d0080
-#define F0900_P2_ERR_CNT22  0xf39d007f
+#define R0900_P2_ERRCNT22 0xf39d
+#define F0900_P2_ERRCNT2_OLDVALUE 0xf39d0080
+#define F0900_P2_ERR_CNT22 0xf39d007f
 
 /*P2_ERRCNT21*/
-#define R0900_P2_ERRCNT21  0xf39e
-#define F0900_P2_ERR_CNT21  0xf39e00ff
+#define R0900_P2_ERRCNT21 0xf39e
+#define F0900_P2_ERR_CNT21 0xf39e00ff
 
 /*P2_ERRCNT20*/
-#define R0900_P2_ERRCNT20  0xf39f
-#define F0900_P2_ERR_CNT20  0xf39f00ff
+#define R0900_P2_ERRCNT20 0xf39f
+#define F0900_P2_ERR_CNT20 0xf39f00ff
 
 /*P2_FECSPY*/
-#define R0900_P2_FECSPY  0xf3a0
-#define F0900_P2_SPY_ENABLE  0xf3a00080
-#define F0900_P2_NO_SYNCBYTE  0xf3a00040
-#define F0900_P2_SERIAL_MODE  0xf3a00020
-#define F0900_P2_UNUSUAL_PACKET  0xf3a00010
-#define F0900_P2_BER_PACKMODE  0xf3a00008
-#define F0900_P2_BERMETER_LMODE  0xf3a00002
-#define F0900_P2_BERMETER_RESET  0xf3a00001
+#define R0900_P2_FECSPY 0xf3a0
+#define F0900_P2_SPY_ENABLE 0xf3a00080
+#define F0900_P2_NO_SYNCBYTE 0xf3a00040
+#define F0900_P2_SERIAL_MODE 0xf3a00020
+#define F0900_P2_UNUSUAL_PACKET 0xf3a00010
+#define F0900_P2_BERMETER_DATAMODE 0xf3a00008
+#define F0900_P2_BERMETER_LMODE 0xf3a00002
+#define F0900_P2_BERMETER_RESET 0xf3a00001
 
 /*P2_FSPYCFG*/
-#define R0900_P2_FSPYCFG  0xf3a1
-#define F0900_P2_FECSPY_INPUT  0xf3a100c0
-#define F0900_P2_RST_ON_ERROR  0xf3a10020
-#define F0900_P2_ONE_SHOT  0xf3a10010
-#define F0900_P2_I2C_MODE  0xf3a1000c
-#define F0900_P2_SPY_HYSTERESIS  0xf3a10003
+#define R0900_P2_FSPYCFG 0xf3a1
+#define F0900_P2_FECSPY_INPUT 0xf3a100c0
+#define F0900_P2_RST_ON_ERROR 0xf3a10020
+#define F0900_P2_ONE_SHOT 0xf3a10010
+#define F0900_P2_I2C_MODE 0xf3a1000c
+#define F0900_P2_SPY_HYSTERESIS 0xf3a10003
 
 /*P2_FSPYDATA*/
-#define R0900_P2_FSPYDATA  0xf3a2
-#define F0900_P2_SPY_STUFFING  0xf3a20080
-#define F0900_P2_NOERROR_PKTJITTER  0xf3a20040
-#define F0900_P2_SPY_CNULLPKT  0xf3a20020
-#define F0900_P2_SPY_OUTDATA_MODE  0xf3a2001f
+#define R0900_P2_FSPYDATA 0xf3a2
+#define F0900_P2_SPY_STUFFING 0xf3a20080
+#define F0900_P2_SPY_CNULLPKT 0xf3a20020
+#define F0900_P2_SPY_OUTDATA_MODE 0xf3a2001f
 
 /*P2_FSPYOUT*/
-#define R0900_P2_FSPYOUT  0xf3a3
-#define F0900_P2_FSPY_DIRECT  0xf3a30080
-#define F0900_P2_SPY_OUTDATA_BUS  0xf3a30038
-#define F0900_P2_STUFF_MODE  0xf3a30007
+#define R0900_P2_FSPYOUT 0xf3a3
+#define F0900_P2_FSPY_DIRECT 0xf3a30080
+#define F0900_P2_STUFF_MODE 0xf3a30007
 
 /*P2_FSTATUS*/
-#define R0900_P2_FSTATUS  0xf3a4
-#define F0900_P2_SPY_ENDSIM  0xf3a40080
-#define F0900_P2_VALID_SIM  0xf3a40040
-#define F0900_P2_FOUND_SIGNAL  0xf3a40020
-#define F0900_P2_DSS_SYNCBYTE  0xf3a40010
-#define F0900_P2_RESULT_STATE  0xf3a4000f
+#define R0900_P2_FSTATUS 0xf3a4
+#define F0900_P2_SPY_ENDSIM 0xf3a40080
+#define F0900_P2_VALID_SIM 0xf3a40040
+#define F0900_P2_FOUND_SIGNAL 0xf3a40020
+#define F0900_P2_DSS_SYNCBYTE 0xf3a40010
+#define F0900_P2_RESULT_STATE 0xf3a4000f
 
 /*P2_FBERCPT4*/
-#define R0900_P2_FBERCPT4  0xf3a8
-#define F0900_P2_FBERMETER_CPT4  0xf3a800ff
+#define R0900_P2_FBERCPT4 0xf3a8
+#define F0900_P2_FBERMETER_CPT4 0xf3a800ff
 
 /*P2_FBERCPT3*/
-#define R0900_P2_FBERCPT3  0xf3a9
-#define F0900_P2_FBERMETER_CPT3  0xf3a900ff
+#define R0900_P2_FBERCPT3 0xf3a9
+#define F0900_P2_FBERMETER_CPT3 0xf3a900ff
 
 /*P2_FBERCPT2*/
-#define R0900_P2_FBERCPT2  0xf3aa
-#define F0900_P2_FBERMETER_CPT2  0xf3aa00ff
+#define R0900_P2_FBERCPT2 0xf3aa
+#define F0900_P2_FBERMETER_CPT2 0xf3aa00ff
 
 /*P2_FBERCPT1*/
-#define R0900_P2_FBERCPT1  0xf3ab
-#define F0900_P2_FBERMETER_CPT1  0xf3ab00ff
+#define R0900_P2_FBERCPT1 0xf3ab
+#define F0900_P2_FBERMETER_CPT1 0xf3ab00ff
 
 /*P2_FBERCPT0*/
-#define R0900_P2_FBERCPT0  0xf3ac
-#define F0900_P2_FBERMETER_CPT0  0xf3ac00ff
+#define R0900_P2_FBERCPT0 0xf3ac
+#define F0900_P2_FBERMETER_CPT0 0xf3ac00ff
 
 /*P2_FBERERR2*/
-#define R0900_P2_FBERERR2  0xf3ad
-#define F0900_P2_FBERMETER_ERR2  0xf3ad00ff
+#define R0900_P2_FBERERR2 0xf3ad
+#define F0900_P2_FBERMETER_ERR2 0xf3ad00ff
 
 /*P2_FBERERR1*/
-#define R0900_P2_FBERERR1  0xf3ae
-#define F0900_P2_FBERMETER_ERR1  0xf3ae00ff
+#define R0900_P2_FBERERR1 0xf3ae
+#define F0900_P2_FBERMETER_ERR1 0xf3ae00ff
 
 /*P2_FBERERR0*/
-#define R0900_P2_FBERERR0  0xf3af
-#define F0900_P2_FBERMETER_ERR0  0xf3af00ff
+#define R0900_P2_FBERERR0 0xf3af
+#define F0900_P2_FBERMETER_ERR0 0xf3af00ff
 
 /*P2_FSPYBER*/
-#define R0900_P2_FSPYBER  0xf3b2
-#define F0900_P2_FSPYOBS_XORREAD  0xf3b20040
-#define F0900_P2_FSPYBER_OBSMODE  0xf3b20020
-#define F0900_P2_FSPYBER_SYNCBYTE  0xf3b20010
-#define F0900_P2_FSPYBER_UNSYNC  0xf3b20008
-#define F0900_P2_FSPYBER_CTIME  0xf3b20007
+#define R0900_P2_FSPYBER 0xf3b2
+#define F0900_P2_FSPYBER_SYNCBYTE 0xf3b20010
+#define F0900_P2_FSPYBER_UNSYNC 0xf3b20008
+#define F0900_P2_FSPYBER_CTIME 0xf3b20007
 
 /*P1_IQCONST*/
-#define R0900_P1_IQCONST  0xf400
-#define F0900_P1_CONSTEL_SELECT  0xf4000060
-#define F0900_P1_IQSYMB_SEL  0xf400001f
+#define R0900_P1_IQCONST 0xf400
+#define IQCONST REGx(R0900_P1_IQCONST)
+#define F0900_P1_CONSTEL_SELECT 0xf4000060
+#define F0900_P1_IQSYMB_SEL 0xf400001f
 
 /*P1_NOSCFG*/
-#define R0900_P1_NOSCFG  0xf401
-#define F0900_P1_DUMMYPL_NOSDATA  0xf4010020
-#define F0900_P1_NOSPLH_BETA  0xf4010018
-#define F0900_P1_NOSDATA_BETA  0xf4010007
+#define R0900_P1_NOSCFG 0xf401
+#define NOSCFG REGx(R0900_P1_NOSCFG)
+#define F0900_P1_DUMMYPL_NOSDATA 0xf4010020
+#define F0900_P1_NOSPLH_BETA 0xf4010018
+#define F0900_P1_NOSDATA_BETA 0xf4010007
 
 /*P1_ISYMB*/
-#define R0900_P1_ISYMB  0xf402
-#define F0900_P1_I_SYMBOL  0xf40201ff
+#define R0900_P1_ISYMB 0xf402
+#define ISYMB REGx(R0900_P1_ISYMB)
+#define F0900_P1_I_SYMBOL 0xf40201ff
 
 /*P1_QSYMB*/
-#define R0900_P1_QSYMB  0xf403
-#define F0900_P1_Q_SYMBOL  0xf40301ff
+#define R0900_P1_QSYMB 0xf403
+#define QSYMB REGx(R0900_P1_QSYMB)
+#define F0900_P1_Q_SYMBOL 0xf40301ff
 
 /*P1_AGC1CFG*/
-#define R0900_P1_AGC1CFG  0xf404
-#define F0900_P1_DC_FROZEN  0xf4040080
-#define F0900_P1_DC_CORRECT  0xf4040040
-#define F0900_P1_AMM_FROZEN  0xf4040020
-#define F0900_P1_AMM_CORRECT  0xf4040010
-#define F0900_P1_QUAD_FROZEN  0xf4040008
-#define F0900_P1_QUAD_CORRECT  0xf4040004
-#define F0900_P1_DCCOMP_SLOW  0xf4040002
-#define F0900_P1_IQMISM_SLOW  0xf4040001
+#define R0900_P1_AGC1CFG 0xf404
+#define AGC1CFG REGx(R0900_P1_AGC1CFG)
+#define F0900_P1_DC_FROZEN 0xf4040080
+#define F0900_P1_DC_CORRECT 0xf4040040
+#define F0900_P1_AMM_FROZEN 0xf4040020
+#define F0900_P1_AMM_CORRECT 0xf4040010
+#define F0900_P1_QUAD_FROZEN 0xf4040008
+#define F0900_P1_QUAD_CORRECT 0xf4040004
 
 /*P1_AGC1CN*/
-#define R0900_P1_AGC1CN  0xf406
-#define F0900_P1_AGC1_LOCKED  0xf4060080
-#define F0900_P1_AGC1_OVERFLOW  0xf4060040
-#define F0900_P1_AGC1_NOSLOWLK  0xf4060020
-#define F0900_P1_AGC1_MINPOWER  0xf4060010
-#define F0900_P1_AGCOUT_FAST  0xf4060008
-#define F0900_P1_AGCIQ_BETA  0xf4060007
+#define R0900_P1_AGC1CN 0xf406
+#define AGC1CN REGx(R0900_P1_AGC1CN)
+#define F0900_P1_AGC1_LOCKED 0xf4060080
+#define F0900_P1_AGC1_MINPOWER 0xf4060010
+#define F0900_P1_AGCOUT_FAST 0xf4060008
+#define F0900_P1_AGCIQ_BETA 0xf4060007
 
 /*P1_AGC1REF*/
-#define R0900_P1_AGC1REF  0xf407
-#define F0900_P1_AGCIQ_REF  0xf40700ff
+#define R0900_P1_AGC1REF 0xf407
+#define AGC1REF REGx(R0900_P1_AGC1REF)
+#define F0900_P1_AGCIQ_REF 0xf40700ff
 
 /*P1_IDCCOMP*/
-#define R0900_P1_IDCCOMP  0xf408
-#define F0900_P1_IAVERAGE_ADJ  0xf40801ff
+#define R0900_P1_IDCCOMP 0xf408
+#define IDCCOMP REGx(R0900_P1_IDCCOMP)
+#define F0900_P1_IAVERAGE_ADJ 0xf40801ff
 
 /*P1_QDCCOMP*/
-#define R0900_P1_QDCCOMP  0xf409
-#define F0900_P1_QAVERAGE_ADJ  0xf40901ff
+#define R0900_P1_QDCCOMP 0xf409
+#define QDCCOMP REGx(R0900_P1_QDCCOMP)
+#define F0900_P1_QAVERAGE_ADJ 0xf40901ff
 
 /*P1_POWERI*/
-#define R0900_P1_POWERI  0xf40a
-#define F0900_P1_POWER_I  0xf40a00ff
+#define R0900_P1_POWERI 0xf40a
+#define POWERI REGx(R0900_P1_POWERI)
+#define F0900_P1_POWER_I 0xf40a00ff
+#define POWER_I FLDx(F0900_P1_POWER_I)
 
 /*P1_POWERQ*/
-#define R0900_P1_POWERQ  0xf40b
-#define F0900_P1_POWER_Q  0xf40b00ff
+#define R0900_P1_POWERQ 0xf40b
+#define POWERQ REGx(R0900_P1_POWERQ)
+#define F0900_P1_POWER_Q 0xf40b00ff
+#define POWER_Q FLDx(F0900_P1_POWER_Q)
 
 /*P1_AGC1AMM*/
-#define R0900_P1_AGC1AMM  0xf40c
-#define F0900_P1_AMM_VALUE  0xf40c00ff
+#define R0900_P1_AGC1AMM 0xf40c
+#define AGC1AMM REGx(R0900_P1_AGC1AMM)
+#define F0900_P1_AMM_VALUE 0xf40c00ff
 
 /*P1_AGC1QUAD*/
-#define R0900_P1_AGC1QUAD  0xf40d
-#define F0900_P1_QUAD_VALUE  0xf40d01ff
+#define R0900_P1_AGC1QUAD 0xf40d
+#define AGC1QUAD REGx(R0900_P1_AGC1QUAD)
+#define F0900_P1_QUAD_VALUE 0xf40d01ff
 
 /*P1_AGCIQIN1*/
-#define R0900_P1_AGCIQIN1  0xf40e
-#define F0900_P1_AGCIQ_VALUE1  0xf40e00ff
+#define R0900_P1_AGCIQIN1 0xf40e
+#define AGCIQIN1 REGx(R0900_P1_AGCIQIN1)
+#define F0900_P1_AGCIQ_VALUE1 0xf40e00ff
+#define AGCIQ_VALUE1 FLDx(F0900_P1_AGCIQ_VALUE1)
 
 /*P1_AGCIQIN0*/
-#define R0900_P1_AGCIQIN0  0xf40f
-#define F0900_P1_AGCIQ_VALUE0  0xf40f00ff
+#define R0900_P1_AGCIQIN0 0xf40f
+#define AGCIQIN0 REGx(R0900_P1_AGCIQIN0)
+#define F0900_P1_AGCIQ_VALUE0 0xf40f00ff
+#define AGCIQ_VALUE0 FLDx(F0900_P1_AGCIQ_VALUE0)
 
 /*P1_DEMOD*/
-#define R0900_P1_DEMOD  0xf410
-#define F0900_P1_DEMOD_STOP  0xf4100040
-#define F0900_P1_SPECINV_CONTROL  0xf4100030
-#define F0900_P1_FORCE_ENASAMP  0xf4100008
-#define F0900_P1_MANUAL_ROLLOFF  0xf4100004
-#define F0900_P1_ROLLOFF_CONTROL  0xf4100003
+#define R0900_P1_DEMOD 0xf410
+#define DEMOD REGx(R0900_P1_DEMOD)
+#define F0900_P1_MANUALS2_ROLLOFF 0xf4100080
+#define MANUALS2_ROLLOFF FLDx(F0900_P1_MANUALS2_ROLLOFF)
+
+#define F0900_P1_SPECINV_CONTROL 0xf4100030
+#define SPECINV_CONTROL FLDx(F0900_P1_SPECINV_CONTROL)
+#define F0900_P1_FORCE_ENASAMP 0xf4100008
+#define F0900_P1_MANUALSX_ROLLOFF 0xf4100004
+#define MANUALSX_ROLLOFF FLDx(F0900_P1_MANUALSX_ROLLOFF)
+#define F0900_P1_ROLLOFF_CONTROL 0xf4100003
+#define ROLLOFF_CONTROL FLDx(F0900_P1_ROLLOFF_CONTROL)
 
 /*P1_DMDMODCOD*/
-#define R0900_P1_DMDMODCOD  0xf411
-#define F0900_P1_MANUAL_MODCOD  0xf4110080
-#define F0900_P1_DEMOD_MODCOD  0xf411007c
-#define F0900_P1_DEMOD_TYPE  0xf4110003
+#define R0900_P1_DMDMODCOD 0xf411
+#define DMDMODCOD REGx(R0900_P1_DMDMODCOD)
+#define F0900_P1_MANUAL_MODCOD 0xf4110080
+#define F0900_P1_DEMOD_MODCOD 0xf411007c
+#define DEMOD_MODCOD FLDx(F0900_P1_DEMOD_MODCOD)
+#define F0900_P1_DEMOD_TYPE 0xf4110003
+#define DEMOD_TYPE FLDx(F0900_P1_DEMOD_TYPE)
 
 /*P1_DSTATUS*/
-#define R0900_P1_DSTATUS  0xf412
-#define F0900_P1_CAR_LOCK  0xf4120080
-#define F0900_P1_TMGLOCK_QUALITY  0xf4120060
-#define F0900_P1_SDVBS1_ENABLE  0xf4120010
-#define F0900_P1_LOCK_DEFINITIF  0xf4120008
-#define F0900_P1_TIMING_IS_LOCKED  0xf4120004
-#define F0900_P1_COARSE_TMGLOCK  0xf4120002
-#define F0900_P1_COARSE_CARLOCK  0xf4120001
+#define R0900_P1_DSTATUS 0xf412
+#define DSTATUS REGx(R0900_P1_DSTATUS)
+#define F0900_P1_CAR_LOCK 0xf4120080
+#define F0900_P1_TMGLOCK_QUALITY 0xf4120060
+#define TMGLOCK_QUALITY FLDx(F0900_P1_TMGLOCK_QUALITY)
+#define F0900_P1_LOCK_DEFINITIF 0xf4120008
+#define LOCK_DEFINITIF FLDx(F0900_P1_LOCK_DEFINITIF)
+#define F0900_P1_OVADC_DETECT 0xf4120001
 
 /*P1_DSTATUS2*/
-#define R0900_P1_DSTATUS2  0xf413
-#define F0900_P1_DEMOD_DELOCK  0xf4130080
-#define F0900_P1_DEMOD_TIMEOUT  0xf4130040
-#define F0900_P1_MODCODRQ_SYNCTAG  0xf4130020
-#define F0900_P1_POLYPH_SATEVENT  0xf4130010
-#define F0900_P1_AGC1_NOSIGNALACK  0xf4130008
-#define F0900_P1_AGC2_OVERFLOW  0xf4130004
-#define F0900_P1_CFR_OVERFLOW  0xf4130002
-#define F0900_P1_GAMMA_OVERUNDER  0xf4130001
+#define R0900_P1_DSTATUS2 0xf413
+#define DSTATUS2 REGx(R0900_P1_DSTATUS2)
+#define F0900_P1_DEMOD_DELOCK 0xf4130080
+#define F0900_P1_AGC1_NOSIGNALACK 0xf4130008
+#define F0900_P1_AGC2_OVERFLOW 0xf4130004
+#define F0900_P1_CFR_OVERFLOW 0xf4130002
+#define F0900_P1_GAMMA_OVERUNDER 0xf4130001
 
 /*P1_DMDCFGMD*/
-#define R0900_P1_DMDCFGMD  0xf414
-#define F0900_P1_DVBS2_ENABLE  0xf4140080
-#define F0900_P1_DVBS1_ENABLE  0xf4140040
-#define F0900_P1_CFR_AUTOSCAN  0xf4140020
-#define F0900_P1_SCAN_ENABLE  0xf4140010
-#define F0900_P1_TUN_AUTOSCAN  0xf4140008
-#define F0900_P1_NOFORCE_RELOCK  0xf4140004
-#define F0900_P1_TUN_RNG  0xf4140003
+#define R0900_P1_DMDCFGMD 0xf414
+#define DMDCFGMD REGx(R0900_P1_DMDCFGMD)
+#define F0900_P1_DVBS2_ENABLE 0xf4140080
+#define DVBS2_ENABLE FLDx(F0900_P1_DVBS2_ENABLE)
+#define F0900_P1_DVBS1_ENABLE 0xf4140040
+#define DVBS1_ENABLE FLDx(F0900_P1_DVBS1_ENABLE)
+#define F0900_P1_SCAN_ENABLE 0xf4140010
+#define SCAN_ENABLE FLDx(F0900_P1_SCAN_ENABLE)
+#define F0900_P1_CFR_AUTOSCAN 0xf4140008
+#define CFR_AUTOSCAN FLDx(F0900_P1_CFR_AUTOSCAN)
+#define F0900_P1_TUN_RNG 0xf4140003
 
 /*P1_DMDCFG2*/
-#define R0900_P1_DMDCFG2  0xf415
-#define F0900_P1_AGC1_WAITLOCK  0xf4150080
-#define F0900_P1_S1S2_SEQUENTIAL  0xf4150040
-#define F0900_P1_OVERFLOW_TIMEOUT  0xf4150020
-#define F0900_P1_SCANFAIL_TIMEOUT  0xf4150010
-#define F0900_P1_DMDTOUT_BACK  0xf4150008
-#define F0900_P1_CARLOCK_S1ENABLE  0xf4150004
-#define F0900_P1_COARSE_LK3MODE  0xf4150002
-#define F0900_P1_COARSE_LK2MODE  0xf4150001
+#define R0900_P1_DMDCFG2 0xf415
+#define DMDCFG2 REGx(R0900_P1_DMDCFG2)
+#define F0900_P1_S1S2_SEQUENTIAL 0xf4150040
+#define S1S2_SEQUENTIAL FLDx(F0900_P1_S1S2_SEQUENTIAL)
+#define F0900_P1_INFINITE_RELOCK 0xf4150010
 
 /*P1_DMDISTATE*/
-#define R0900_P1_DMDISTATE  0xf416
-#define F0900_P1_I2C_NORESETDMODE  0xf4160080
-#define F0900_P1_FORCE_ETAPED  0xf4160040
-#define F0900_P1_SDMDRST_DIRCLK  0xf4160020
-#define F0900_P1_I2C_DEMOD_MODE  0xf416001f
+#define R0900_P1_DMDISTATE 0xf416
+#define DMDISTATE REGx(R0900_P1_DMDISTATE)
+#define F0900_P1_I2C_DEMOD_MODE 0xf416001f
+#define DEMOD_MODE FLDx(F0900_P1_I2C_DEMOD_MODE)
 
 /*P1_DMDT0M*/
-#define R0900_P1_DMDT0M  0xf417
-#define F0900_P1_DMDT0_MIN  0xf41700ff
+#define R0900_P1_DMDT0M 0xf417
+#define DMDT0M REGx(R0900_P1_DMDT0M)
+#define F0900_P1_DMDT0_MIN 0xf41700ff
 
 /*P1_DMDSTATE*/
-#define R0900_P1_DMDSTATE  0xf41b
-#define F0900_P1_DEMOD_LOCKED  0xf41b0080
-#define F0900_P1_HEADER_MODE  0xf41b0060
-#define F0900_P1_DEMOD_MODE  0xf41b001f
+#define R0900_P1_DMDSTATE 0xf41b
+#define DMDSTATE REGx(R0900_P1_DMDSTATE)
+#define F0900_P1_HEADER_MODE 0xf41b0060
+#define HEADER_MODE FLDx(F0900_P1_HEADER_MODE)
 
 /*P1_DMDFLYW*/
-#define R0900_P1_DMDFLYW  0xf41c
-#define F0900_P1_I2C_IRQVAL  0xf41c00f0
-#define F0900_P1_FLYWHEEL_CPT  0xf41c000f
+#define R0900_P1_DMDFLYW 0xf41c
+#define DMDFLYW REGx(R0900_P1_DMDFLYW)
+#define F0900_P1_I2C_IRQVAL 0xf41c00f0
+#define F0900_P1_FLYWHEEL_CPT 0xf41c000f
+#define FLYWHEEL_CPT FLDx(F0900_P1_FLYWHEEL_CPT)
 
 /*P1_DSTATUS3*/
-#define R0900_P1_DSTATUS3  0xf41d
-#define F0900_P1_CFR_ZIGZAG  0xf41d0080
-#define F0900_P1_DEMOD_CFGMODE  0xf41d0060
-#define F0900_P1_GAMMA_LOWBAUDRATE  0xf41d0010
-#define F0900_P1_RELOCK_MODE  0xf41d0008
-#define F0900_P1_DEMOD_FAIL  0xf41d0004
-#define F0900_P1_ETAPE1A_DVBXMEM  0xf41d0003
+#define R0900_P1_DSTATUS3 0xf41d
+#define DSTATUS3 REGx(R0900_P1_DSTATUS3)
+#define F0900_P1_DEMOD_CFGMODE 0xf41d0060
 
 /*P1_DMDCFG3*/
-#define R0900_P1_DMDCFG3  0xf41e
-#define F0900_P1_DVBS1_TMGWAIT  0xf41e0080
-#define F0900_P1_NO_BWCENTERING  0xf41e0040
-#define F0900_P1_INV_SEQSRCH  0xf41e0020
-#define F0900_P1_DIS_SFRUPLOW_TRK  0xf41e0010
-#define F0900_P1_NOSTOP_FIFOFULL  0xf41e0008
-#define F0900_P1_LOCKTIME_MODE  0xf41e0007
+#define R0900_P1_DMDCFG3 0xf41e
+#define DMDCFG3 REGx(R0900_P1_DMDCFG3)
+#define F0900_P1_NOSTOP_FIFOFULL 0xf41e0008
 
 /*P1_DMDCFG4*/
-#define R0900_P1_DMDCFG4  0xf41f
-#define F0900_P1_TUNER_NRELAUNCH  0xf41f0008
-#define F0900_P1_DIS_CLKENABLE  0xf41f0004
-#define F0900_P1_DIS_HDRDIVLOCK  0xf41f0002
-#define F0900_P1_NO_TNRWBINIT  0xf41f0001
+#define R0900_P1_DMDCFG4 0xf41f
+#define DMDCFG4 REGx(R0900_P1_DMDCFG4)
+#define F0900_P1_TUNER_NRELAUNCH 0xf41f0008
 
 /*P1_CORRELMANT*/
-#define R0900_P1_CORRELMANT  0xf420
-#define F0900_P1_CORREL_MANT  0xf42000ff
+#define R0900_P1_CORRELMANT 0xf420
+#define CORRELMANT REGx(R0900_P1_CORRELMANT)
+#define F0900_P1_CORREL_MANT 0xf42000ff
 
 /*P1_CORRELABS*/
-#define R0900_P1_CORRELABS  0xf421
-#define F0900_P1_CORREL_ABS  0xf42100ff
+#define R0900_P1_CORRELABS 0xf421
+#define CORRELABS REGx(R0900_P1_CORRELABS)
+#define F0900_P1_CORREL_ABS 0xf42100ff
 
 /*P1_CORRELEXP*/
-#define R0900_P1_CORRELEXP  0xf422
-#define F0900_P1_CORREL_ABSEXP  0xf42200f0
-#define F0900_P1_CORREL_EXP  0xf422000f
+#define R0900_P1_CORRELEXP 0xf422
+#define CORRELEXP REGx(R0900_P1_CORRELEXP)
+#define F0900_P1_CORREL_ABSEXP 0xf42200f0
+#define F0900_P1_CORREL_EXP 0xf422000f
 
 /*P1_PLHMODCOD*/
-#define R0900_P1_PLHMODCOD  0xf424
-#define F0900_P1_SPECINV_DEMOD  0xf4240080
-#define F0900_P1_PLH_MODCOD  0xf424007c
-#define F0900_P1_PLH_TYPE  0xf4240003
+#define R0900_P1_PLHMODCOD 0xf424
+#define PLHMODCOD REGx(R0900_P1_PLHMODCOD)
+#define F0900_P1_SPECINV_DEMOD 0xf4240080
+#define SPECINV_DEMOD FLDx(F0900_P1_SPECINV_DEMOD)
+#define F0900_P1_PLH_MODCOD 0xf424007c
+#define F0900_P1_PLH_TYPE 0xf4240003
 
-/*P1_AGCK32*/
-#define R0900_P1_AGCK32  0xf42b
-#define F0900_P1_R3ADJOFF_32APSK  0xf42b0080
-#define F0900_P1_R2ADJOFF_32APSK  0xf42b0040
-#define F0900_P1_R1ADJOFF_32APSK  0xf42b0020
-#define F0900_P1_RADJ_32APSK  0xf42b001f
+/*P1_DMDREG*/
+#define R0900_P1_DMDREG 0xf425
+#define DMDREG REGx(R0900_P1_DMDREG)
+#define F0900_P1_DECIM_PLFRAMES 0xf4250001
 
 /*P1_AGC2O*/
-#define R0900_P1_AGC2O  0xf42c
-#define F0900_P1_AGC2REF_ADJUSTING  0xf42c0080
-#define F0900_P1_AGC2_COARSEFAST  0xf42c0040
-#define F0900_P1_AGC2_LKSQRT  0xf42c0020
-#define F0900_P1_AGC2_LKMODE  0xf42c0010
-#define F0900_P1_AGC2_LKEQUA  0xf42c0008
-#define F0900_P1_AGC2_COEF  0xf42c0007
+#define R0900_P1_AGC2O 0xf42c
+#define AGC2O REGx(R0900_P1_AGC2O)
+#define F0900_P1_AGC2_COEF 0xf42c0007
 
 /*P1_AGC2REF*/
-#define R0900_P1_AGC2REF  0xf42d
-#define F0900_P1_AGC2_REF  0xf42d00ff
+#define R0900_P1_AGC2REF 0xf42d
+#define AGC2REF REGx(R0900_P1_AGC2REF)
+#define F0900_P1_AGC2_REF 0xf42d00ff
 
 /*P1_AGC1ADJ*/
-#define R0900_P1_AGC1ADJ  0xf42e
-#define F0900_P1_AGC1ADJ_MANUAL  0xf42e0080
-#define F0900_P1_AGC1_ADJUSTED  0xf42e017f
+#define R0900_P1_AGC1ADJ 0xf42e
+#define AGC1ADJ REGx(R0900_P1_AGC1ADJ)
+#define F0900_P1_AGC1_ADJUSTED 0xf42e007f
 
 /*P1_AGC2I1*/
-#define R0900_P1_AGC2I1  0xf436
-#define F0900_P1_AGC2_INTEGRATOR1  0xf43600ff
+#define R0900_P1_AGC2I1 0xf436
+#define AGC2I1 REGx(R0900_P1_AGC2I1)
+#define F0900_P1_AGC2_INTEGRATOR1 0xf43600ff
 
 /*P1_AGC2I0*/
-#define R0900_P1_AGC2I0  0xf437
-#define F0900_P1_AGC2_INTEGRATOR0  0xf43700ff
+#define R0900_P1_AGC2I0 0xf437
+#define AGC2I0 REGx(R0900_P1_AGC2I0)
+#define F0900_P1_AGC2_INTEGRATOR0 0xf43700ff
 
 /*P1_CARCFG*/
-#define R0900_P1_CARCFG  0xf438
-#define F0900_P1_CFRUPLOW_AUTO  0xf4380080
-#define F0900_P1_CFRUPLOW_TEST  0xf4380040
-#define F0900_P1_EN_CAR2CENTER  0xf4380020
-#define F0900_P1_CARHDR_NODIV8  0xf4380010
-#define F0900_P1_I2C_ROTA  0xf4380008
-#define F0900_P1_ROTAON  0xf4380004
-#define F0900_P1_PH_DET_ALGO  0xf4380003
+#define R0900_P1_CARCFG 0xf438
+#define CARCFG REGx(R0900_P1_CARCFG)
+#define F0900_P1_CFRUPLOW_AUTO 0xf4380080
+#define F0900_P1_CFRUPLOW_TEST 0xf4380040
+#define F0900_P1_ROTAON 0xf4380004
+#define F0900_P1_PH_DET_ALGO 0xf4380003
 
 /*P1_ACLC*/
-#define R0900_P1_ACLC  0xf439
-#define F0900_P1_STOP_S2ALPHA  0xf43900c0
-#define F0900_P1_CAR_ALPHA_MANT  0xf4390030
-#define F0900_P1_CAR_ALPHA_EXP  0xf439000f
+#define R0900_P1_ACLC 0xf439
+#define ACLC REGx(R0900_P1_ACLC)
+#define F0900_P1_CAR_ALPHA_MANT 0xf4390030
+#define F0900_P1_CAR_ALPHA_EXP 0xf439000f
 
 /*P1_BCLC*/
-#define R0900_P1_BCLC  0xf43a
-#define F0900_P1_STOP_S2BETA  0xf43a00c0
-#define F0900_P1_CAR_BETA_MANT  0xf43a0030
-#define F0900_P1_CAR_BETA_EXP  0xf43a000f
+#define R0900_P1_BCLC 0xf43a
+#define BCLC REGx(R0900_P1_BCLC)
+#define F0900_P1_CAR_BETA_MANT 0xf43a0030
+#define F0900_P1_CAR_BETA_EXP 0xf43a000f
 
 /*P1_CARFREQ*/
-#define R0900_P1_CARFREQ  0xf43d
-#define F0900_P1_KC_COARSE_EXP  0xf43d00f0
-#define F0900_P1_BETA_FREQ  0xf43d000f
+#define R0900_P1_CARFREQ 0xf43d
+#define CARFREQ REGx(R0900_P1_CARFREQ)
+#define F0900_P1_KC_COARSE_EXP 0xf43d00f0
+#define F0900_P1_BETA_FREQ 0xf43d000f
 
 /*P1_CARHDR*/
-#define R0900_P1_CARHDR  0xf43e
-#define F0900_P1_K_FREQ_HDR  0xf43e00ff
+#define R0900_P1_CARHDR 0xf43e
+#define CARHDR REGx(R0900_P1_CARHDR)
+#define F0900_P1_K_FREQ_HDR 0xf43e00ff
 
 /*P1_LDT*/
-#define R0900_P1_LDT  0xf43f
-#define F0900_P1_CARLOCK_THRES  0xf43f01ff
+#define R0900_P1_LDT 0xf43f
+#define LDT REGx(R0900_P1_LDT)
+#define F0900_P1_CARLOCK_THRES 0xf43f01ff
 
 /*P1_LDT2*/
-#define R0900_P1_LDT2  0xf440
-#define F0900_P1_CARLOCK_THRES2  0xf44001ff
+#define R0900_P1_LDT2 0xf440
+#define LDT2 REGx(R0900_P1_LDT2)
+#define F0900_P1_CARLOCK_THRES2 0xf44001ff
 
 /*P1_CFRICFG*/
-#define R0900_P1_CFRICFG  0xf441
-#define F0900_P1_CFRINIT_UNVALRNG  0xf4410080
-#define F0900_P1_CFRINIT_LUNVALCPT  0xf4410040
-#define F0900_P1_CFRINIT_ABORTDBL  0xf4410020
-#define F0900_P1_CFRINIT_ABORTPRED  0xf4410010
-#define F0900_P1_CFRINIT_UNVALSKIP  0xf4410008
-#define F0900_P1_CFRINIT_CSTINC  0xf4410004
-#define F0900_P1_NEG_CFRSTEP  0xf4410001
+#define R0900_P1_CFRICFG 0xf441
+#define CFRICFG REGx(R0900_P1_CFRICFG)
+#define F0900_P1_NEG_CFRSTEP 0xf4410001
 
 /*P1_CFRUP1*/
-#define R0900_P1_CFRUP1  0xf442
-#define F0900_P1_CFR_UP1  0xf44201ff
+#define R0900_P1_CFRUP1 0xf442
+#define CFRUP1 REGx(R0900_P1_CFRUP1)
+#define F0900_P1_CFR_UP1 0xf44201ff
+#define CFR_UP1 FLDx(F0900_P1_CFR_UP1)
 
 /*P1_CFRUP0*/
-#define R0900_P1_CFRUP0  0xf443
-#define F0900_P1_CFR_UP0  0xf44300ff
+#define R0900_P1_CFRUP0 0xf443
+#define CFRUP0 REGx(R0900_P1_CFRUP0)
+#define F0900_P1_CFR_UP0 0xf44300ff
+#define CFR_UP0 FLDx(F0900_P1_CFR_UP0)
 
 /*P1_CFRLOW1*/
-#define R0900_P1_CFRLOW1  0xf446
-#define F0900_P1_CFR_LOW1  0xf44601ff
+#define R0900_P1_CFRLOW1 0xf446
+#define CFRLOW1 REGx(R0900_P1_CFRLOW1)
+#define F0900_P1_CFR_LOW1 0xf44601ff
+#define CFR_LOW1 FLDx(F0900_P1_CFR_LOW1)
 
 /*P1_CFRLOW0*/
-#define R0900_P1_CFRLOW0  0xf447
-#define F0900_P1_CFR_LOW0  0xf44700ff
+#define R0900_P1_CFRLOW0 0xf447
+#define CFRLOW0 REGx(R0900_P1_CFRLOW0)
+#define F0900_P1_CFR_LOW0 0xf44700ff
+#define CFR_LOW0 FLDx(F0900_P1_CFR_LOW0)
 
 /*P1_CFRINIT1*/
-#define R0900_P1_CFRINIT1  0xf448
-#define F0900_P1_CFR_INIT1  0xf44801ff
+#define R0900_P1_CFRINIT1 0xf448
+#define CFRINIT1 REGx(R0900_P1_CFRINIT1)
+#define F0900_P1_CFR_INIT1 0xf44801ff
+#define CFR_INIT1 FLDx(F0900_P1_CFR_INIT1)
 
 /*P1_CFRINIT0*/
-#define R0900_P1_CFRINIT0  0xf449
-#define F0900_P1_CFR_INIT0  0xf44900ff
+#define R0900_P1_CFRINIT0 0xf449
+#define CFRINIT0 REGx(R0900_P1_CFRINIT0)
+#define F0900_P1_CFR_INIT0 0xf44900ff
+#define CFR_INIT0 FLDx(F0900_P1_CFR_INIT0)
 
 /*P1_CFRINC1*/
-#define R0900_P1_CFRINC1  0xf44a
-#define F0900_P1_MANUAL_CFRINC  0xf44a0080
-#define F0900_P1_CFR_INC1  0xf44a017f
+#define R0900_P1_CFRINC1 0xf44a
+#define CFRINC1 REGx(R0900_P1_CFRINC1)
+#define F0900_P1_MANUAL_CFRINC 0xf44a0080
+#define F0900_P1_CFR_INC1 0xf44a003f
 
 /*P1_CFRINC0*/
-#define R0900_P1_CFRINC0  0xf44b
-#define F0900_P1_CFR_INC0  0xf44b00f0
+#define R0900_P1_CFRINC0 0xf44b
+#define CFRINC0 REGx(R0900_P1_CFRINC0)
+#define F0900_P1_CFR_INC0 0xf44b00f8
 
 /*P1_CFR2*/
-#define R0900_P1_CFR2  0xf44c
-#define F0900_P1_CAR_FREQ2  0xf44c01ff
+#define R0900_P1_CFR2 0xf44c
+#define CFR2 REGx(R0900_P1_CFR2)
+#define F0900_P1_CAR_FREQ2 0xf44c01ff
+#define CAR_FREQ2 FLDx(F0900_P1_CAR_FREQ2)
 
 /*P1_CFR1*/
-#define R0900_P1_CFR1  0xf44d
-#define F0900_P1_CAR_FREQ1  0xf44d00ff
+#define R0900_P1_CFR1 0xf44d
+#define CFR1 REGx(R0900_P1_CFR1)
+#define F0900_P1_CAR_FREQ1 0xf44d00ff
+#define CAR_FREQ1 FLDx(F0900_P1_CAR_FREQ1)
 
 /*P1_CFR0*/
-#define R0900_P1_CFR0  0xf44e
-#define F0900_P1_CAR_FREQ0  0xf44e00ff
+#define R0900_P1_CFR0 0xf44e
+#define CFR0 REGx(R0900_P1_CFR0)
+#define F0900_P1_CAR_FREQ0 0xf44e00ff
+#define CAR_FREQ0 FLDx(F0900_P1_CAR_FREQ0)
 
 /*P1_LDI*/
-#define R0900_P1_LDI  0xf44f
-#define F0900_P1_LOCK_DET_INTEGR  0xf44f01ff
+#define R0900_P1_LDI 0xf44f
+#define LDI REGx(R0900_P1_LDI)
+#define F0900_P1_LOCK_DET_INTEGR 0xf44f01ff
 
 /*P1_TMGCFG*/
-#define R0900_P1_TMGCFG  0xf450
-#define F0900_P1_TMGLOCK_BETA  0xf45000c0
-#define F0900_P1_NOTMG_GROUPDELAY  0xf4500020
-#define F0900_P1_DO_TIMING_CORR  0xf4500010
-#define F0900_P1_MANUAL_SCAN  0xf450000c
-#define F0900_P1_TMG_MINFREQ  0xf4500003
+#define R0900_P1_TMGCFG 0xf450
+#define TMGCFG REGx(R0900_P1_TMGCFG)
+#define F0900_P1_TMGLOCK_BETA 0xf45000c0
+#define F0900_P1_DO_TIMING_CORR 0xf4500010
+#define F0900_P1_TMG_MINFREQ 0xf4500003
 
 /*P1_RTC*/
-#define R0900_P1_RTC  0xf451
-#define F0900_P1_TMGALPHA_EXP  0xf45100f0
-#define F0900_P1_TMGBETA_EXP  0xf451000f
+#define R0900_P1_RTC 0xf451
+#define RTC REGx(R0900_P1_RTC)
+#define F0900_P1_TMGALPHA_EXP 0xf45100f0
+#define F0900_P1_TMGBETA_EXP 0xf451000f
 
 /*P1_RTCS2*/
-#define R0900_P1_RTCS2  0xf452
-#define F0900_P1_TMGALPHAS2_EXP  0xf45200f0
-#define F0900_P1_TMGBETAS2_EXP  0xf452000f
+#define R0900_P1_RTCS2 0xf452
+#define RTCS2 REGx(R0900_P1_RTCS2)
+#define F0900_P1_TMGALPHAS2_EXP 0xf45200f0
+#define F0900_P1_TMGBETAS2_EXP 0xf452000f
 
 /*P1_TMGTHRISE*/
-#define R0900_P1_TMGTHRISE  0xf453
-#define F0900_P1_TMGLOCK_THRISE  0xf45300ff
+#define R0900_P1_TMGTHRISE 0xf453
+#define TMGTHRISE REGx(R0900_P1_TMGTHRISE)
+#define F0900_P1_TMGLOCK_THRISE 0xf45300ff
 
 /*P1_TMGTHFALL*/
-#define R0900_P1_TMGTHFALL  0xf454
-#define F0900_P1_TMGLOCK_THFALL  0xf45400ff
+#define R0900_P1_TMGTHFALL 0xf454
+#define TMGTHFALL REGx(R0900_P1_TMGTHFALL)
+#define F0900_P1_TMGLOCK_THFALL 0xf45400ff
 
 /*P1_SFRUPRATIO*/
-#define R0900_P1_SFRUPRATIO  0xf455
-#define F0900_P1_SFR_UPRATIO  0xf45500ff
+#define R0900_P1_SFRUPRATIO 0xf455
+#define SFRUPRATIO REGx(R0900_P1_SFRUPRATIO)
+#define F0900_P1_SFR_UPRATIO 0xf45500ff
 
 /*P1_SFRLOWRATIO*/
-#define R0900_P1_SFRLOWRATIO  0xf456
-#define F0900_P1_SFR_LOWRATIO  0xf45600ff
+#define R0900_P1_SFRLOWRATIO 0xf456
+#define F0900_P1_SFR_LOWRATIO 0xf45600ff
 
 /*P1_KREFTMG*/
-#define R0900_P1_KREFTMG  0xf458
-#define F0900_P1_KREF_TMG  0xf45800ff
+#define R0900_P1_KREFTMG 0xf458
+#define KREFTMG REGx(R0900_P1_KREFTMG)
+#define F0900_P1_KREF_TMG 0xf45800ff
 
 /*P1_SFRSTEP*/
-#define R0900_P1_SFRSTEP  0xf459
-#define F0900_P1_SFR_SCANSTEP  0xf45900f0
-#define F0900_P1_SFR_CENTERSTEP  0xf459000f
+#define R0900_P1_SFRSTEP 0xf459
+#define SFRSTEP REGx(R0900_P1_SFRSTEP)
+#define F0900_P1_SFR_SCANSTEP 0xf45900f0
+#define F0900_P1_SFR_CENTERSTEP 0xf459000f
 
 /*P1_TMGCFG2*/
-#define R0900_P1_TMGCFG2  0xf45a
-#define F0900_P1_DIS_AUTOSAMP  0xf45a0008
-#define F0900_P1_SCANINIT_QUART  0xf45a0004
-#define F0900_P1_NOTMG_DVBS1DERAT  0xf45a0002
-#define F0900_P1_SFRRATIO_FINE  0xf45a0001
+#define R0900_P1_TMGCFG2 0xf45a
+#define TMGCFG2 REGx(R0900_P1_TMGCFG2)
+#define F0900_P1_SFRRATIO_FINE 0xf45a0001
+
+/*P1_KREFTMG2*/
+#define R0900_P1_KREFTMG2 0xf45b
+#define KREFTMG2 REGx(R0900_P1_KREFTMG2)
+#define F0900_P1_KREF_TMG2 0xf45b00ff
 
 /*P1_SFRINIT1*/
-#define R0900_P1_SFRINIT1  0xf45e
-#define F0900_P1_SFR_INIT1  0xf45e00ff
+#define R0900_P1_SFRINIT1 0xf45e
+#define SFRINIT1 REGx(R0900_P1_SFRINIT1)
+#define F0900_P1_SFR_INIT1 0xf45e007f
 
 /*P1_SFRINIT0*/
-#define R0900_P1_SFRINIT0  0xf45f
-#define F0900_P1_SFR_INIT0  0xf45f00ff
+#define R0900_P1_SFRINIT0 0xf45f
+#define SFRINIT0 REGx(R0900_P1_SFRINIT0)
+#define F0900_P1_SFR_INIT0 0xf45f00ff
 
 /*P1_SFRUP1*/
-#define R0900_P1_SFRUP1  0xf460
-#define F0900_P1_AUTO_GUP  0xf4600080
-#define F0900_P1_SYMB_FREQ_UP1  0xf460007f
+#define R0900_P1_SFRUP1 0xf460
+#define SFRUP1 REGx(R0900_P1_SFRUP1)
+#define F0900_P1_AUTO_GUP 0xf4600080
+#define AUTO_GUP FLDx(F0900_P1_AUTO_GUP)
+#define F0900_P1_SYMB_FREQ_UP1 0xf460007f
 
 /*P1_SFRUP0*/
-#define R0900_P1_SFRUP0  0xf461
-#define F0900_P1_SYMB_FREQ_UP0  0xf46100ff
+#define R0900_P1_SFRUP0 0xf461
+#define SFRUP0 REGx(R0900_P1_SFRUP0)
+#define F0900_P1_SYMB_FREQ_UP0 0xf46100ff
 
 /*P1_SFRLOW1*/
-#define R0900_P1_SFRLOW1  0xf462
-#define F0900_P1_AUTO_GLOW  0xf4620080
-#define F0900_P1_SYMB_FREQ_LOW1  0xf462007f
+#define R0900_P1_SFRLOW1 0xf462
+#define SFRLOW1 REGx(R0900_P1_SFRLOW1)
+#define F0900_P1_AUTO_GLOW 0xf4620080
+#define AUTO_GLOW FLDx(F0900_P1_AUTO_GLOW)
+#define F0900_P1_SYMB_FREQ_LOW1 0xf462007f
 
 /*P1_SFRLOW0*/
-#define R0900_P1_SFRLOW0  0xf463
-#define F0900_P1_SYMB_FREQ_LOW0  0xf46300ff
+#define R0900_P1_SFRLOW0 0xf463
+#define SFRLOW0 REGx(R0900_P1_SFRLOW0)
+#define F0900_P1_SYMB_FREQ_LOW0 0xf46300ff
 
 /*P1_SFR3*/
-#define R0900_P1_SFR3  0xf464
-#define F0900_P1_SYMB_FREQ3  0xf46400ff
+#define R0900_P1_SFR3 0xf464
+#define SFR3 REGx(R0900_P1_SFR3)
+#define F0900_P1_SYMB_FREQ3 0xf46400ff
+#define SYMB_FREQ3 FLDx(F0900_P1_SYMB_FREQ3)
 
 /*P1_SFR2*/
-#define R0900_P1_SFR2  0xf465
-#define F0900_P1_SYMB_FREQ2  0xf46500ff
+#define R0900_P1_SFR2 0xf465
+#define SFR2 REGx(R0900_P1_SFR2)
+#define F0900_P1_SYMB_FREQ2 0xf46500ff
+#define SYMB_FREQ2 FLDx(F0900_P1_SYMB_FREQ2)
 
 /*P1_SFR1*/
-#define R0900_P1_SFR1  0xf466
-#define F0900_P1_SYMB_FREQ1  0xf46600ff
+#define R0900_P1_SFR1 0xf466
+#define SFR1 REGx(R0900_P1_SFR1)
+#define F0900_P1_SYMB_FREQ1 0xf46600ff
+#define SYMB_FREQ1 FLDx(F0900_P1_SYMB_FREQ1)
 
 /*P1_SFR0*/
-#define R0900_P1_SFR0  0xf467
-#define F0900_P1_SYMB_FREQ0  0xf46700ff
+#define R0900_P1_SFR0 0xf467
+#define SFR0 REGx(R0900_P1_SFR0)
+#define F0900_P1_SYMB_FREQ0 0xf46700ff
+#define SYMB_FREQ0 FLDx(F0900_P1_SYMB_FREQ0)
 
 /*P1_TMGREG2*/
-#define R0900_P1_TMGREG2  0xf468
-#define F0900_P1_TMGREG2  0xf46800ff
+#define R0900_P1_TMGREG2 0xf468
+#define TMGREG2 REGx(R0900_P1_TMGREG2)
+#define F0900_P1_TMGREG2 0xf46800ff
 
 /*P1_TMGREG1*/
-#define R0900_P1_TMGREG1  0xf469
-#define F0900_P1_TMGREG1  0xf46900ff
+#define R0900_P1_TMGREG1 0xf469
+#define TMGREG1 REGx(R0900_P1_TMGREG1)
+#define F0900_P1_TMGREG1 0xf46900ff
 
 /*P1_TMGREG0*/
-#define R0900_P1_TMGREG0  0xf46a
-#define F0900_P1_TMGREG0  0xf46a00ff
+#define R0900_P1_TMGREG0 0xf46a
+#define TMGREG0 REGx(R0900_P1_TMGREG0)
+#define F0900_P1_TMGREG0 0xf46a00ff
 
 /*P1_TMGLOCK1*/
-#define R0900_P1_TMGLOCK1  0xf46b
-#define F0900_P1_TMGLOCK_LEVEL1  0xf46b01ff
+#define R0900_P1_TMGLOCK1 0xf46b
+#define TMGLOCK1 REGx(R0900_P1_TMGLOCK1)
+#define F0900_P1_TMGLOCK_LEVEL1 0xf46b01ff
 
 /*P1_TMGLOCK0*/
-#define R0900_P1_TMGLOCK0  0xf46c
-#define F0900_P1_TMGLOCK_LEVEL0  0xf46c00ff
+#define R0900_P1_TMGLOCK0 0xf46c
+#define TMGLOCK0 REGx(R0900_P1_TMGLOCK0)
+#define F0900_P1_TMGLOCK_LEVEL0 0xf46c00ff
 
 /*P1_TMGOBS*/
-#define R0900_P1_TMGOBS  0xf46d
-#define F0900_P1_ROLLOFF_STATUS  0xf46d00c0
-#define F0900_P1_SCAN_SIGN  0xf46d0030
-#define F0900_P1_TMG_SCANNING  0xf46d0008
-#define F0900_P1_CHCENTERING_MODE  0xf46d0004
-#define F0900_P1_TMG_SCANFAIL  0xf46d0002
+#define R0900_P1_TMGOBS 0xf46d
+#define TMGOBS REGx(R0900_P1_TMGOBS)
+#define F0900_P1_ROLLOFF_STATUS 0xf46d00c0
+#define ROLLOFF_STATUS FLDx(F0900_P1_ROLLOFF_STATUS)
 
 /*P1_EQUALCFG*/
-#define R0900_P1_EQUALCFG  0xf46f
-#define F0900_P1_NOTMG_NEGALWAIT  0xf46f0080
-#define F0900_P1_EQUAL_ON  0xf46f0040
-#define F0900_P1_SEL_EQUALCOR  0xf46f0038
-#define F0900_P1_MU_EQUALDFE  0xf46f0007
+#define R0900_P1_EQUALCFG 0xf46f
+#define EQUALCFG REGx(R0900_P1_EQUALCFG)
+#define F0900_P1_EQUAL_ON 0xf46f0040
+#define F0900_P1_MU_EQUALDFE 0xf46f0007
 
 /*P1_EQUAI1*/
-#define R0900_P1_EQUAI1  0xf470
-#define F0900_P1_EQUA_ACCI1  0xf47001ff
+#define R0900_P1_EQUAI1 0xf470
+#define EQUAI1 REGx(R0900_P1_EQUAI1)
+#define F0900_P1_EQUA_ACCI1 0xf47001ff
 
 /*P1_EQUAQ1*/
-#define R0900_P1_EQUAQ1  0xf471
-#define F0900_P1_EQUA_ACCQ1  0xf47101ff
+#define R0900_P1_EQUAQ1 0xf471
+#define EQUAQ1 REGx(R0900_P1_EQUAQ1)
+#define F0900_P1_EQUA_ACCQ1 0xf47101ff
 
 /*P1_EQUAI2*/
-#define R0900_P1_EQUAI2  0xf472
-#define F0900_P1_EQUA_ACCI2  0xf47201ff
+#define R0900_P1_EQUAI2 0xf472
+#define EQUAI2 REGx(R0900_P1_EQUAI2)
+#define F0900_P1_EQUA_ACCI2 0xf47201ff
 
 /*P1_EQUAQ2*/
-#define R0900_P1_EQUAQ2  0xf473
-#define F0900_P1_EQUA_ACCQ2  0xf47301ff
+#define R0900_P1_EQUAQ2 0xf473
+#define EQUAQ2 REGx(R0900_P1_EQUAQ2)
+#define F0900_P1_EQUA_ACCQ2 0xf47301ff
 
 /*P1_EQUAI3*/
-#define R0900_P1_EQUAI3  0xf474
-#define F0900_P1_EQUA_ACCI3  0xf47401ff
+#define R0900_P1_EQUAI3 0xf474
+#define EQUAI3 REGx(R0900_P1_EQUAI3)
+#define F0900_P1_EQUA_ACCI3 0xf47401ff
 
 /*P1_EQUAQ3*/
-#define R0900_P1_EQUAQ3  0xf475
-#define F0900_P1_EQUA_ACCQ3  0xf47501ff
+#define R0900_P1_EQUAQ3 0xf475
+#define EQUAQ3 REGx(R0900_P1_EQUAQ3)
+#define F0900_P1_EQUA_ACCQ3 0xf47501ff
 
 /*P1_EQUAI4*/
-#define R0900_P1_EQUAI4  0xf476
-#define F0900_P1_EQUA_ACCI4  0xf47601ff
+#define R0900_P1_EQUAI4 0xf476
+#define EQUAI4 REGx(R0900_P1_EQUAI4)
+#define F0900_P1_EQUA_ACCI4 0xf47601ff
 
 /*P1_EQUAQ4*/
-#define R0900_P1_EQUAQ4  0xf477
-#define F0900_P1_EQUA_ACCQ4  0xf47701ff
+#define R0900_P1_EQUAQ4 0xf477
+#define EQUAQ4 REGx(R0900_P1_EQUAQ4)
+#define F0900_P1_EQUA_ACCQ4 0xf47701ff
 
 /*P1_EQUAI5*/
-#define R0900_P1_EQUAI5  0xf478
-#define F0900_P1_EQUA_ACCI5  0xf47801ff
+#define R0900_P1_EQUAI5 0xf478
+#define EQUAI5 REGx(R0900_P1_EQUAI5)
+#define F0900_P1_EQUA_ACCI5 0xf47801ff
 
 /*P1_EQUAQ5*/
-#define R0900_P1_EQUAQ5  0xf479
-#define F0900_P1_EQUA_ACCQ5  0xf47901ff
+#define R0900_P1_EQUAQ5 0xf479
+#define EQUAQ5 REGx(R0900_P1_EQUAQ5)
+#define F0900_P1_EQUA_ACCQ5 0xf47901ff
 
 /*P1_EQUAI6*/
-#define R0900_P1_EQUAI6  0xf47a
-#define F0900_P1_EQUA_ACCI6  0xf47a01ff
+#define R0900_P1_EQUAI6 0xf47a
+#define EQUAI6 REGx(R0900_P1_EQUAI6)
+#define F0900_P1_EQUA_ACCI6 0xf47a01ff
 
 /*P1_EQUAQ6*/
-#define R0900_P1_EQUAQ6  0xf47b
-#define F0900_P1_EQUA_ACCQ6  0xf47b01ff
+#define R0900_P1_EQUAQ6 0xf47b
+#define EQUAQ6 REGx(R0900_P1_EQUAQ6)
+#define F0900_P1_EQUA_ACCQ6 0xf47b01ff
 
 /*P1_EQUAI7*/
-#define R0900_P1_EQUAI7  0xf47c
-#define F0900_P1_EQUA_ACCI7  0xf47c01ff
+#define R0900_P1_EQUAI7 0xf47c
+#define EQUAI7 REGx(R0900_P1_EQUAI7)
+#define F0900_P1_EQUA_ACCI7 0xf47c01ff
 
 /*P1_EQUAQ7*/
-#define R0900_P1_EQUAQ7  0xf47d
-#define F0900_P1_EQUA_ACCQ7  0xf47d01ff
+#define R0900_P1_EQUAQ7 0xf47d
+#define EQUAQ7 REGx(R0900_P1_EQUAQ7)
+#define F0900_P1_EQUA_ACCQ7 0xf47d01ff
 
 /*P1_EQUAI8*/
-#define R0900_P1_EQUAI8  0xf47e
-#define F0900_P1_EQUA_ACCI8  0xf47e01ff
+#define R0900_P1_EQUAI8 0xf47e
+#define EQUAI8 REGx(R0900_P1_EQUAI8)
+#define F0900_P1_EQUA_ACCI8 0xf47e01ff
 
 /*P1_EQUAQ8*/
-#define R0900_P1_EQUAQ8  0xf47f
-#define F0900_P1_EQUA_ACCQ8  0xf47f01ff
+#define R0900_P1_EQUAQ8 0xf47f
+#define EQUAQ8 REGx(R0900_P1_EQUAQ8)
+#define F0900_P1_EQUA_ACCQ8 0xf47f01ff
 
 /*P1_NNOSDATAT1*/
-#define R0900_P1_NNOSDATAT1  0xf480
-#define F0900_P1_NOSDATAT_NORMED1  0xf48000ff
+#define R0900_P1_NNOSDATAT1 0xf480
+#define NNOSDATAT1 REGx(R0900_P1_NNOSDATAT1)
+#define F0900_P1_NOSDATAT_NORMED1 0xf48000ff
+#define NOSDATAT_NORMED1 FLDx(F0900_P1_NOSDATAT_NORMED1)
 
 /*P1_NNOSDATAT0*/
-#define R0900_P1_NNOSDATAT0  0xf481
-#define F0900_P1_NOSDATAT_NORMED0  0xf48100ff
+#define R0900_P1_NNOSDATAT0 0xf481
+#define NNOSDATAT0 REGx(R0900_P1_NNOSDATAT0)
+#define F0900_P1_NOSDATAT_NORMED0 0xf48100ff
+#define NOSDATAT_NORMED0 FLDx(F0900_P1_NOSDATAT_NORMED0)
 
 /*P1_NNOSDATA1*/
-#define R0900_P1_NNOSDATA1  0xf482
-#define F0900_P1_NOSDATA_NORMED1  0xf48200ff
+#define R0900_P1_NNOSDATA1 0xf482
+#define NNOSDATA1 REGx(R0900_P1_NNOSDATA1)
+#define F0900_P1_NOSDATA_NORMED1 0xf48200ff
 
 /*P1_NNOSDATA0*/
-#define R0900_P1_NNOSDATA0  0xf483
-#define F0900_P1_NOSDATA_NORMED0  0xf48300ff
+#define R0900_P1_NNOSDATA0 0xf483
+#define NNOSDATA0 REGx(R0900_P1_NNOSDATA0)
+#define F0900_P1_NOSDATA_NORMED0 0xf48300ff
 
 /*P1_NNOSPLHT1*/
-#define R0900_P1_NNOSPLHT1  0xf484
-#define F0900_P1_NOSPLHT_NORMED1  0xf48400ff
+#define R0900_P1_NNOSPLHT1 0xf484
+#define NNOSPLHT1 REGx(R0900_P1_NNOSPLHT1)
+#define F0900_P1_NOSPLHT_NORMED1 0xf48400ff
+#define NOSPLHT_NORMED1 FLDx(F0900_P1_NOSPLHT_NORMED1)
 
 /*P1_NNOSPLHT0*/
-#define R0900_P1_NNOSPLHT0  0xf485
-#define F0900_P1_NOSPLHT_NORMED0  0xf48500ff
+#define R0900_P1_NNOSPLHT0 0xf485
+#define NNOSPLHT0 REGx(R0900_P1_NNOSPLHT0)
+#define F0900_P1_NOSPLHT_NORMED0 0xf48500ff
+#define NOSPLHT_NORMED0 FLDx(F0900_P1_NOSPLHT_NORMED0)
 
 /*P1_NNOSPLH1*/
-#define R0900_P1_NNOSPLH1  0xf486
-#define F0900_P1_NOSPLH_NORMED1  0xf48600ff
+#define R0900_P1_NNOSPLH1 0xf486
+#define NNOSPLH1 REGx(R0900_P1_NNOSPLH1)
+#define F0900_P1_NOSPLH_NORMED1 0xf48600ff
 
 /*P1_NNOSPLH0*/
-#define R0900_P1_NNOSPLH0  0xf487
-#define F0900_P1_NOSPLH_NORMED0  0xf48700ff
+#define R0900_P1_NNOSPLH0 0xf487
+#define NNOSPLH0 REGx(R0900_P1_NNOSPLH0)
+#define F0900_P1_NOSPLH_NORMED0 0xf48700ff
 
 /*P1_NOSDATAT1*/
-#define R0900_P1_NOSDATAT1  0xf488
-#define F0900_P1_NOSDATAT_UNNORMED1  0xf48800ff
+#define R0900_P1_NOSDATAT1 0xf488
+#define NOSDATAT1 REGx(R0900_P1_NOSDATAT1)
+#define F0900_P1_NOSDATAT_UNNORMED1 0xf48800ff
 
 /*P1_NOSDATAT0*/
-#define R0900_P1_NOSDATAT0  0xf489
-#define F0900_P1_NOSDATAT_UNNORMED0  0xf48900ff
+#define R0900_P1_NOSDATAT0 0xf489
+#define NOSDATAT0 REGx(R0900_P1_NOSDATAT0)
+#define F0900_P1_NOSDATAT_UNNORMED0 0xf48900ff
 
 /*P1_NOSDATA1*/
-#define R0900_P1_NOSDATA1  0xf48a
-#define F0900_P1_NOSDATA_UNNORMED1  0xf48a00ff
+#define R0900_P1_NOSDATA1 0xf48a
+#define NOSDATA1 REGx(R0900_P1_NOSDATA1)
+#define F0900_P1_NOSDATA_UNNORMED1 0xf48a00ff
 
 /*P1_NOSDATA0*/
-#define R0900_P1_NOSDATA0  0xf48b
-#define F0900_P1_NOSDATA_UNNORMED0  0xf48b00ff
+#define R0900_P1_NOSDATA0 0xf48b
+#define NOSDATA0 REGx(R0900_P1_NOSDATA0)
+#define F0900_P1_NOSDATA_UNNORMED0 0xf48b00ff
 
 /*P1_NOSPLHT1*/
-#define R0900_P1_NOSPLHT1  0xf48c
-#define F0900_P1_NOSPLHT_UNNORMED1  0xf48c00ff
+#define R0900_P1_NOSPLHT1 0xf48c
+#define NOSPLHT1 REGx(R0900_P1_NOSPLHT1)
+#define F0900_P1_NOSPLHT_UNNORMED1 0xf48c00ff
 
 /*P1_NOSPLHT0*/
-#define R0900_P1_NOSPLHT0  0xf48d
-#define F0900_P1_NOSPLHT_UNNORMED0  0xf48d00ff
+#define R0900_P1_NOSPLHT0 0xf48d
+#define NOSPLHT0 REGx(R0900_P1_NOSPLHT0)
+#define F0900_P1_NOSPLHT_UNNORMED0 0xf48d00ff
 
 /*P1_NOSPLH1*/
-#define R0900_P1_NOSPLH1  0xf48e
-#define F0900_P1_NOSPLH_UNNORMED1  0xf48e00ff
+#define R0900_P1_NOSPLH1 0xf48e
+#define NOSPLH1 REGx(R0900_P1_NOSPLH1)
+#define F0900_P1_NOSPLH_UNNORMED1 0xf48e00ff
 
 /*P1_NOSPLH0*/
-#define R0900_P1_NOSPLH0  0xf48f
-#define F0900_P1_NOSPLH_UNNORMED0  0xf48f00ff
+#define R0900_P1_NOSPLH0 0xf48f
+#define NOSPLH0 REGx(R0900_P1_NOSPLH0)
+#define F0900_P1_NOSPLH_UNNORMED0 0xf48f00ff
 
 /*P1_CAR2CFG*/
-#define R0900_P1_CAR2CFG  0xf490
-#define F0900_P1_DESCRAMB_OFF  0xf4900080
-#define F0900_P1_PN4_SELECT  0xf4900040
-#define F0900_P1_CFR2_STOPDVBS1  0xf4900020
-#define F0900_P1_STOP_CFR2UPDATE  0xf4900010
-#define F0900_P1_STOP_NCO2UPDATE  0xf4900008
-#define F0900_P1_ROTA2ON  0xf4900004
-#define F0900_P1_PH_DET_ALGO2  0xf4900003
+#define R0900_P1_CAR2CFG 0xf490
+#define CAR2CFG REGx(R0900_P1_CAR2CFG)
+#define F0900_P1_CARRIER3_DISABLE 0xf4900040
+#define F0900_P1_ROTA2ON 0xf4900004
+#define F0900_P1_PH_DET_ALGO2 0xf4900003
 
-/*P1_ACLC2*/
-#define R0900_P1_ACLC2  0xf491
-#define F0900_P1_CAR2_PUNCT_ADERAT  0xf4910040
-#define F0900_P1_CAR2_ALPHA_MANT  0xf4910030
-#define F0900_P1_CAR2_ALPHA_EXP  0xf491000f
-
-/*P1_BCLC2*/
-#define R0900_P1_BCLC2  0xf492
-#define F0900_P1_DVBS2_NIP  0xf4920080
-#define F0900_P1_CAR2_PUNCT_BDERAT  0xf4920040
-#define F0900_P1_CAR2_BETA_MANT  0xf4920030
-#define F0900_P1_CAR2_BETA_EXP  0xf492000f
+/*P1_CFR2CFR1*/
+#define R0900_P1_CFR2CFR1 0xf491
+#define CFR2CFR1 REGx(R0900_P1_CFR2CFR1)
+#define F0900_P1_CFR2TOCFR1_DVBS1 0xf49100c0
+#define F0900_P1_EN_S2CAR2CENTER 0xf4910020
+#define F0900_P1_DIS_BCHERRCFR2 0xf4910010
+#define F0900_P1_CFR2TOCFR1_BETA 0xf4910007
 
 /*P1_CFR22*/
-#define R0900_P1_CFR22  0xf493
-#define F0900_P1_CAR2_FREQ2  0xf49301ff
+#define R0900_P1_CFR22 0xf493
+#define CFR22 REGx(R0900_P1_CFR22)
+#define F0900_P1_CAR2_FREQ2 0xf49301ff
 
 /*P1_CFR21*/
-#define R0900_P1_CFR21  0xf494
-#define F0900_P1_CAR2_FREQ1  0xf49400ff
+#define R0900_P1_CFR21 0xf494
+#define CFR21 REGx(R0900_P1_CFR21)
+#define F0900_P1_CAR2_FREQ1 0xf49400ff
 
 /*P1_CFR20*/
-#define R0900_P1_CFR20  0xf495
-#define F0900_P1_CAR2_FREQ0  0xf49500ff
+#define R0900_P1_CFR20 0xf495
+#define CFR20 REGx(R0900_P1_CFR20)
+#define F0900_P1_CAR2_FREQ0 0xf49500ff
 
 /*P1_ACLC2S2Q*/
-#define R0900_P1_ACLC2S2Q  0xf497
-#define F0900_P1_ENAB_SPSKSYMB  0xf4970080
-#define F0900_P1_CAR2S2_QADERAT  0xf4970040
-#define F0900_P1_CAR2S2_Q_ALPH_M  0xf4970030
-#define F0900_P1_CAR2S2_Q_ALPH_E  0xf497000f
+#define R0900_P1_ACLC2S2Q 0xf497
+#define ACLC2S2Q REGx(R0900_P1_ACLC2S2Q)
+#define F0900_P1_ENAB_SPSKSYMB 0xf4970080
+#define F0900_P1_CAR2S2_Q_ALPH_M 0xf4970030
+#define F0900_P1_CAR2S2_Q_ALPH_E 0xf497000f
 
 /*P1_ACLC2S28*/
-#define R0900_P1_ACLC2S28  0xf498
-#define F0900_P1_OLDI3Q_MODE  0xf4980080
-#define F0900_P1_CAR2S2_8ADERAT  0xf4980040
-#define F0900_P1_CAR2S2_8_ALPH_M  0xf4980030
-#define F0900_P1_CAR2S2_8_ALPH_E  0xf498000f
+#define R0900_P1_ACLC2S28 0xf498
+#define ACLC2S28 REGx(R0900_P1_ACLC2S28)
+#define F0900_P1_OLDI3Q_MODE 0xf4980080
+#define F0900_P1_CAR2S2_8_ALPH_M 0xf4980030
+#define F0900_P1_CAR2S2_8_ALPH_E 0xf498000f
 
 /*P1_ACLC2S216A*/
-#define R0900_P1_ACLC2S216A  0xf499
-#define F0900_P1_CAR2S2_16ADERAT  0xf4990040
-#define F0900_P1_CAR2S2_16A_ALPH_M  0xf4990030
-#define F0900_P1_CAR2S2_16A_ALPH_E  0xf499000f
+#define R0900_P1_ACLC2S216A 0xf499
+#define ACLC2S216A REGx(R0900_P1_ACLC2S216A)
+#define F0900_P1_DIS_C3STOPA2 0xf4990080
+#define F0900_P1_CAR2S2_16ADERAT 0xf4990040
+#define F0900_P1_CAR2S2_16A_ALPH_M 0xf4990030
+#define F0900_P1_CAR2S2_16A_ALPH_E 0xf499000f
 
 /*P1_ACLC2S232A*/
-#define R0900_P1_ACLC2S232A  0xf49a
-#define F0900_P1_CAR2S2_32ADERAT  0xf49a0040
-#define F0900_P1_CAR2S2_32A_ALPH_M  0xf49a0030
-#define F0900_P1_CAR2S2_32A_ALPH_E  0xf49a000f
+#define R0900_P1_ACLC2S232A 0xf49a
+#define ACLC2S232A REGx(R0900_P1_ACLC2S232A)
+#define F0900_P1_CAR2S2_32ADERAT 0xf49a0040
+#define F0900_P1_CAR2S2_32A_ALPH_M 0xf49a0030
+#define F0900_P1_CAR2S2_32A_ALPH_E 0xf49a000f
 
 /*P1_BCLC2S2Q*/
-#define R0900_P1_BCLC2S2Q  0xf49c
-#define F0900_P1_DVBS2S2Q_NIP  0xf49c0080
-#define F0900_P1_CAR2S2_QBDERAT  0xf49c0040
-#define F0900_P1_CAR2S2_Q_BETA_M  0xf49c0030
-#define F0900_P1_CAR2S2_Q_BETA_E  0xf49c000f
+#define R0900_P1_BCLC2S2Q 0xf49c
+#define BCLC2S2Q REGx(R0900_P1_BCLC2S2Q)
+#define F0900_P1_CAR2S2_Q_BETA_M 0xf49c0030
+#define F0900_P1_CAR2S2_Q_BETA_E 0xf49c000f
 
 /*P1_BCLC2S28*/
-#define R0900_P1_BCLC2S28  0xf49d
-#define F0900_P1_DVBS2S28_NIP  0xf49d0080
-#define F0900_P1_CAR2S2_8BDERAT  0xf49d0040
-#define F0900_P1_CAR2S2_8_BETA_M  0xf49d0030
-#define F0900_P1_CAR2S2_8_BETA_E  0xf49d000f
+#define R0900_P1_BCLC2S28 0xf49d
+#define BCLC2S28 REGx(R0900_P1_BCLC2S28)
+#define F0900_P1_CAR2S2_8_BETA_M 0xf49d0030
+#define F0900_P1_CAR2S2_8_BETA_E 0xf49d000f
 
 /*P1_BCLC2S216A*/
-#define R0900_P1_BCLC2S216A  0xf49e
-#define F0900_P1_DVBS2S216A_NIP  0xf49e0080
-#define F0900_P1_CAR2S2_16BDERAT  0xf49e0040
-#define F0900_P1_CAR2S2_16A_BETA_M  0xf49e0030
-#define F0900_P1_CAR2S2_16A_BETA_E  0xf49e000f
+#define R0900_P1_BCLC2S216A 0xf49e
+#define BCLC2S216A REGx(R0900_P1_BCLC2S216A)
 
 /*P1_BCLC2S232A*/
-#define R0900_P1_BCLC2S232A  0xf49f
-#define F0900_P1_DVBS2S232A_NIP  0xf49f0080
-#define F0900_P1_CAR2S2_32BDERAT  0xf49f0040
-#define F0900_P1_CAR2S2_32A_BETA_M  0xf49f0030
-#define F0900_P1_CAR2S2_32A_BETA_E  0xf49f000f
+#define R0900_P1_BCLC2S232A 0xf49f
+#define BCLC2S232A REGx(R0900_P1_BCLC2S232A)
 
 /*P1_PLROOT2*/
-#define R0900_P1_PLROOT2  0xf4ac
-#define F0900_P1_SHORTFR_DISABLE  0xf4ac0080
-#define F0900_P1_LONGFR_DISABLE  0xf4ac0040
-#define F0900_P1_DUMMYPL_DISABLE  0xf4ac0020
-#define F0900_P1_SHORTFR_AVOID  0xf4ac0010
-#define F0900_P1_PLSCRAMB_MODE  0xf4ac000c
-#define F0900_P1_PLSCRAMB_ROOT2  0xf4ac0003
+#define R0900_P1_PLROOT2 0xf4ac
+#define PLROOT2 REGx(R0900_P1_PLROOT2)
+#define F0900_P1_PLSCRAMB_MODE 0xf4ac000c
+#define F0900_P1_PLSCRAMB_ROOT2 0xf4ac0003
 
 /*P1_PLROOT1*/
-#define R0900_P1_PLROOT1  0xf4ad
-#define F0900_P1_PLSCRAMB_ROOT1  0xf4ad00ff
+#define R0900_P1_PLROOT1 0xf4ad
+#define PLROOT1 REGx(R0900_P1_PLROOT1)
+#define F0900_P1_PLSCRAMB_ROOT1 0xf4ad00ff
 
 /*P1_PLROOT0*/
-#define R0900_P1_PLROOT0  0xf4ae
-#define F0900_P1_PLSCRAMB_ROOT0  0xf4ae00ff
+#define R0900_P1_PLROOT0 0xf4ae
+#define PLROOT0 REGx(R0900_P1_PLROOT0)
+#define F0900_P1_PLSCRAMB_ROOT0 0xf4ae00ff
 
 /*P1_MODCODLST0*/
-#define R0900_P1_MODCODLST0  0xf4b0
-#define F0900_P1_EN_TOKEN31  0xf4b00080
-#define F0900_P1_SYNCTAG_SELECT  0xf4b00040
-#define F0900_P1_MODCODRQ_MODE  0xf4b00030
+#define R0900_P1_MODCODLST0 0xf4b0
+#define MODCODLST0 REGx(R0900_P1_MODCODLST0)
 
 /*P1_MODCODLST1*/
-#define R0900_P1_MODCODLST1  0xf4b1
-#define F0900_P1_DIS_MODCOD29  0xf4b100f0
-#define F0900_P1_DIS_32PSK_9_10  0xf4b1000f
+#define R0900_P1_MODCODLST1 0xf4b1
+#define MODCODLST1 REGx(R0900_P1_MODCODLST1)
+#define F0900_P1_DIS_MODCOD29 0xf4b100f0
+#define F0900_P1_DIS_32PSK_9_10 0xf4b1000f
 
 /*P1_MODCODLST2*/
-#define R0900_P1_MODCODLST2  0xf4b2
-#define F0900_P1_DIS_32PSK_8_9  0xf4b200f0
-#define F0900_P1_DIS_32PSK_5_6  0xf4b2000f
+#define R0900_P1_MODCODLST2 0xf4b2
+#define MODCODLST2 REGx(R0900_P1_MODCODLST2)
+#define F0900_P1_DIS_32PSK_8_9 0xf4b200f0
+#define F0900_P1_DIS_32PSK_5_6 0xf4b2000f
 
 /*P1_MODCODLST3*/
-#define R0900_P1_MODCODLST3  0xf4b3
-#define F0900_P1_DIS_32PSK_4_5  0xf4b300f0
-#define F0900_P1_DIS_32PSK_3_4  0xf4b3000f
+#define R0900_P1_MODCODLST3 0xf4b3
+#define MODCODLST3 REGx(R0900_P1_MODCODLST3)
+#define F0900_P1_DIS_32PSK_4_5 0xf4b300f0
+#define F0900_P1_DIS_32PSK_3_4 0xf4b3000f
 
 /*P1_MODCODLST4*/
-#define R0900_P1_MODCODLST4  0xf4b4
-#define F0900_P1_DIS_16PSK_9_10  0xf4b400f0
-#define F0900_P1_DIS_16PSK_8_9  0xf4b4000f
+#define R0900_P1_MODCODLST4 0xf4b4
+#define MODCODLST4 REGx(R0900_P1_MODCODLST4)
+#define F0900_P1_DIS_16PSK_9_10 0xf4b400f0
+#define F0900_P1_DIS_16PSK_8_9 0xf4b4000f
 
 /*P1_MODCODLST5*/
-#define R0900_P1_MODCODLST5  0xf4b5
-#define F0900_P1_DIS_16PSK_5_6  0xf4b500f0
-#define F0900_P1_DIS_16PSK_4_5  0xf4b5000f
+#define R0900_P1_MODCODLST5 0xf4b5
+#define MODCODLST5 REGx(R0900_P1_MODCODLST5)
+#define F0900_P1_DIS_16PSK_5_6 0xf4b500f0
+#define F0900_P1_DIS_16PSK_4_5 0xf4b5000f
 
 /*P1_MODCODLST6*/
-#define R0900_P1_MODCODLST6  0xf4b6
-#define F0900_P1_DIS_16PSK_3_4  0xf4b600f0
-#define F0900_P1_DIS_16PSK_2_3  0xf4b6000f
+#define R0900_P1_MODCODLST6 0xf4b6
+#define MODCODLST6 REGx(R0900_P1_MODCODLST6)
+#define F0900_P1_DIS_16PSK_3_4 0xf4b600f0
+#define F0900_P1_DIS_16PSK_2_3 0xf4b6000f
 
 /*P1_MODCODLST7*/
-#define R0900_P1_MODCODLST7  0xf4b7
-#define F0900_P1_DIS_8P_9_10  0xf4b700f0
-#define F0900_P1_DIS_8P_8_9  0xf4b7000f
+#define R0900_P1_MODCODLST7 0xf4b7
+#define MODCODLST7 REGx(R0900_P1_MODCODLST7)
+#define F0900_P1_DIS_8P_9_10 0xf4b700f0
+#define F0900_P1_DIS_8P_8_9 0xf4b7000f
 
 /*P1_MODCODLST8*/
-#define R0900_P1_MODCODLST8  0xf4b8
-#define F0900_P1_DIS_8P_5_6  0xf4b800f0
-#define F0900_P1_DIS_8P_3_4  0xf4b8000f
+#define R0900_P1_MODCODLST8 0xf4b8
+#define MODCODLST8 REGx(R0900_P1_MODCODLST8)
+#define F0900_P1_DIS_8P_5_6 0xf4b800f0
+#define F0900_P1_DIS_8P_3_4 0xf4b8000f
 
 /*P1_MODCODLST9*/
-#define R0900_P1_MODCODLST9  0xf4b9
-#define F0900_P1_DIS_8P_2_3  0xf4b900f0
-#define F0900_P1_DIS_8P_3_5  0xf4b9000f
+#define R0900_P1_MODCODLST9 0xf4b9
+#define MODCODLST9 REGx(R0900_P1_MODCODLST9)
+#define F0900_P1_DIS_8P_2_3 0xf4b900f0
+#define F0900_P1_DIS_8P_3_5 0xf4b9000f
 
 /*P1_MODCODLSTA*/
-#define R0900_P1_MODCODLSTA  0xf4ba
-#define F0900_P1_DIS_QP_9_10  0xf4ba00f0
-#define F0900_P1_DIS_QP_8_9  0xf4ba000f
+#define R0900_P1_MODCODLSTA 0xf4ba
+#define MODCODLSTA REGx(R0900_P1_MODCODLSTA)
+#define F0900_P1_DIS_QP_9_10 0xf4ba00f0
+#define F0900_P1_DIS_QP_8_9 0xf4ba000f
 
 /*P1_MODCODLSTB*/
-#define R0900_P1_MODCODLSTB  0xf4bb
-#define F0900_P1_DIS_QP_5_6  0xf4bb00f0
-#define F0900_P1_DIS_QP_4_5  0xf4bb000f
+#define R0900_P1_MODCODLSTB 0xf4bb
+#define MODCODLSTB REGx(R0900_P1_MODCODLSTB)
+#define F0900_P1_DIS_QP_5_6 0xf4bb00f0
+#define F0900_P1_DIS_QP_4_5 0xf4bb000f
 
 /*P1_MODCODLSTC*/
-#define R0900_P1_MODCODLSTC  0xf4bc
-#define F0900_P1_DIS_QP_3_4  0xf4bc00f0
-#define F0900_P1_DIS_QP_2_3  0xf4bc000f
+#define R0900_P1_MODCODLSTC 0xf4bc
+#define MODCODLSTC REGx(R0900_P1_MODCODLSTC)
+#define F0900_P1_DIS_QP_3_4 0xf4bc00f0
+#define F0900_P1_DIS_QP_2_3 0xf4bc000f
 
 /*P1_MODCODLSTD*/
-#define R0900_P1_MODCODLSTD  0xf4bd
-#define F0900_P1_DIS_QP_3_5  0xf4bd00f0
-#define F0900_P1_DIS_QP_1_2  0xf4bd000f
+#define R0900_P1_MODCODLSTD 0xf4bd
+#define MODCODLSTD REGx(R0900_P1_MODCODLSTD)
+#define F0900_P1_DIS_QP_3_5 0xf4bd00f0
+#define F0900_P1_DIS_QP_1_2 0xf4bd000f
 
 /*P1_MODCODLSTE*/
-#define R0900_P1_MODCODLSTE  0xf4be
-#define F0900_P1_DIS_QP_2_5  0xf4be00f0
-#define F0900_P1_DIS_QP_1_3  0xf4be000f
+#define R0900_P1_MODCODLSTE 0xf4be
+#define MODCODLSTE REGx(R0900_P1_MODCODLSTE)
+#define F0900_P1_DIS_QP_2_5 0xf4be00f0
+#define F0900_P1_DIS_QP_1_3 0xf4be000f
 
 /*P1_MODCODLSTF*/
-#define R0900_P1_MODCODLSTF  0xf4bf
-#define F0900_P1_DIS_QP_1_4  0xf4bf00f0
-#define F0900_P1_DDEMOD_SET  0xf4bf0002
-#define F0900_P1_DDEMOD_MASK  0xf4bf0001
+#define R0900_P1_MODCODLSTF 0xf4bf
+#define MODCODLSTF REGx(R0900_P1_MODCODLSTF)
+#define F0900_P1_DIS_QP_1_4 0xf4bf00f0
+
+/*P1_GAUSSR0*/
+#define R0900_P1_GAUSSR0 0xf4c0
+#define GAUSSR0 REGx(R0900_P1_GAUSSR0)
+#define F0900_P1_EN_CCIMODE 0xf4c00080
+#define F0900_P1_R0_GAUSSIEN 0xf4c0007f
+
+/*P1_CCIR0*/
+#define R0900_P1_CCIR0 0xf4c1
+#define CCIR0 REGx(R0900_P1_CCIR0)
+#define F0900_P1_CCIDETECT_PLHONLY 0xf4c10080
+#define F0900_P1_R0_CCI 0xf4c1007f
+
+/*P1_CCIQUANT*/
+#define R0900_P1_CCIQUANT 0xf4c2
+#define CCIQUANT REGx(R0900_P1_CCIQUANT)
+#define F0900_P1_CCI_BETA 0xf4c200e0
+#define F0900_P1_CCI_QUANT 0xf4c2001f
+
+/*P1_CCITHRES*/
+#define R0900_P1_CCITHRES 0xf4c3
+#define CCITHRES REGx(R0900_P1_CCITHRES)
+#define F0900_P1_CCI_THRESHOLD 0xf4c300ff
+
+/*P1_CCIACC*/
+#define R0900_P1_CCIACC 0xf4c4
+#define CCIACC REGx(R0900_P1_CCIACC)
+#define F0900_P1_CCI_VALUE 0xf4c400ff
 
 /*P1_DMDRESCFG*/
-#define R0900_P1_DMDRESCFG  0xf4c6
-#define F0900_P1_DMDRES_RESET  0xf4c60080
-#define F0900_P1_DMDRES_NOISESQR  0xf4c60010
-#define F0900_P1_DMDRES_STRALL  0xf4c60008
-#define F0900_P1_DMDRES_NEWONLY  0xf4c60004
-#define F0900_P1_DMDRES_NOSTORE  0xf4c60002
-#define F0900_P1_DMDRES_AGC2MEM  0xf4c60001
+#define R0900_P1_DMDRESCFG 0xf4c6
+#define DMDRESCFG REGx(R0900_P1_DMDRESCFG)
+#define F0900_P1_DMDRES_RESET 0xf4c60080
+#define F0900_P1_DMDRES_STRALL 0xf4c60008
+#define F0900_P1_DMDRES_NEWONLY 0xf4c60004
+#define F0900_P1_DMDRES_NOSTORE 0xf4c60002
 
 /*P1_DMDRESADR*/
-#define R0900_P1_DMDRESADR  0xf4c7
-#define F0900_P1_SUSP_PREDCANAL  0xf4c70080
-#define F0900_P1_DMDRES_VALIDCFR  0xf4c70040
-#define F0900_P1_DMDRES_MEMFULL  0xf4c70030
-#define F0900_P1_DMDRES_RESNBR  0xf4c7000f
+#define R0900_P1_DMDRESADR 0xf4c7
+#define DMDRESADR REGx(R0900_P1_DMDRESADR)
+#define F0900_P1_DMDRES_VALIDCFR 0xf4c70040
+#define F0900_P1_DMDRES_MEMFULL 0xf4c70030
+#define F0900_P1_DMDRES_RESNBR 0xf4c7000f
 
 /*P1_DMDRESDATA7*/
-#define R0900_P1_DMDRESDATA7  0xf4c8
-#define F0900_P1_DMDRES_DATA7  0xf4c800ff
+#define R0900_P1_DMDRESDATA7 0xf4c8
+#define F0900_P1_DMDRES_DATA7 0xf4c800ff
 
 /*P1_DMDRESDATA6*/
-#define R0900_P1_DMDRESDATA6  0xf4c9
-#define F0900_P1_DMDRES_DATA6  0xf4c900ff
+#define R0900_P1_DMDRESDATA6 0xf4c9
+#define F0900_P1_DMDRES_DATA6 0xf4c900ff
 
 /*P1_DMDRESDATA5*/
-#define R0900_P1_DMDRESDATA5  0xf4ca
-#define F0900_P1_DMDRES_DATA5  0xf4ca00ff
+#define R0900_P1_DMDRESDATA5 0xf4ca
+#define F0900_P1_DMDRES_DATA5 0xf4ca00ff
 
 /*P1_DMDRESDATA4*/
-#define R0900_P1_DMDRESDATA4  0xf4cb
-#define F0900_P1_DMDRES_DATA4  0xf4cb00ff
+#define R0900_P1_DMDRESDATA4 0xf4cb
+#define F0900_P1_DMDRES_DATA4 0xf4cb00ff
 
 /*P1_DMDRESDATA3*/
-#define R0900_P1_DMDRESDATA3  0xf4cc
-#define F0900_P1_DMDRES_DATA3  0xf4cc00ff
+#define R0900_P1_DMDRESDATA3 0xf4cc
+#define F0900_P1_DMDRES_DATA3 0xf4cc00ff
 
 /*P1_DMDRESDATA2*/
-#define R0900_P1_DMDRESDATA2  0xf4cd
-#define F0900_P1_DMDRES_DATA2  0xf4cd00ff
+#define R0900_P1_DMDRESDATA2 0xf4cd
+#define F0900_P1_DMDRES_DATA2 0xf4cd00ff
 
 /*P1_DMDRESDATA1*/
-#define R0900_P1_DMDRESDATA1  0xf4ce
-#define F0900_P1_DMDRES_DATA1  0xf4ce00ff
+#define R0900_P1_DMDRESDATA1 0xf4ce
+#define F0900_P1_DMDRES_DATA1 0xf4ce00ff
 
 /*P1_DMDRESDATA0*/
-#define R0900_P1_DMDRESDATA0  0xf4cf
-#define F0900_P1_DMDRES_DATA0  0xf4cf00ff
+#define R0900_P1_DMDRESDATA0 0xf4cf
+#define F0900_P1_DMDRES_DATA0 0xf4cf00ff
 
 /*P1_FFEI1*/
-#define R0900_P1_FFEI1  0xf4d0
-#define F0900_P1_FFE_ACCI1  0xf4d001ff
+#define R0900_P1_FFEI1 0xf4d0
+#define FFEI1 REGx(R0900_P1_FFEI1)
+#define F0900_P1_FFE_ACCI1 0xf4d001ff
 
 /*P1_FFEQ1*/
-#define R0900_P1_FFEQ1  0xf4d1
-#define F0900_P1_FFE_ACCQ1  0xf4d101ff
+#define R0900_P1_FFEQ1 0xf4d1
+#define FFEQ1 REGx(R0900_P1_FFEQ1)
+#define F0900_P1_FFE_ACCQ1 0xf4d101ff
 
 /*P1_FFEI2*/
-#define R0900_P1_FFEI2  0xf4d2
-#define F0900_P1_FFE_ACCI2  0xf4d201ff
+#define R0900_P1_FFEI2 0xf4d2
+#define FFEI2 REGx(R0900_P1_FFEI2)
+#define F0900_P1_FFE_ACCI2 0xf4d201ff
 
 /*P1_FFEQ2*/
-#define R0900_P1_FFEQ2  0xf4d3
-#define F0900_P1_FFE_ACCQ2  0xf4d301ff
+#define R0900_P1_FFEQ2 0xf4d3
+#define FFEQ2 REGx(R0900_P1_FFEQ2)
+#define F0900_P1_FFE_ACCQ2 0xf4d301ff
 
 /*P1_FFEI3*/
-#define R0900_P1_FFEI3  0xf4d4
-#define F0900_P1_FFE_ACCI3  0xf4d401ff
+#define R0900_P1_FFEI3 0xf4d4
+#define FFEI3 REGx(R0900_P1_FFEI3)
+#define F0900_P1_FFE_ACCI3 0xf4d401ff
 
 /*P1_FFEQ3*/
-#define R0900_P1_FFEQ3  0xf4d5
-#define F0900_P1_FFE_ACCQ3  0xf4d501ff
+#define R0900_P1_FFEQ3 0xf4d5
+#define FFEQ3 REGx(R0900_P1_FFEQ3)
+#define F0900_P1_FFE_ACCQ3 0xf4d501ff
 
 /*P1_FFEI4*/
-#define R0900_P1_FFEI4  0xf4d6
-#define F0900_P1_FFE_ACCI4  0xf4d601ff
+#define R0900_P1_FFEI4 0xf4d6
+#define FFEI4 REGx(R0900_P1_FFEI4)
+#define F0900_P1_FFE_ACCI4 0xf4d601ff
 
 /*P1_FFEQ4*/
-#define R0900_P1_FFEQ4  0xf4d7
-#define F0900_P1_FFE_ACCQ4  0xf4d701ff
+#define R0900_P1_FFEQ4 0xf4d7
+#define FFEQ4 REGx(R0900_P1_FFEQ4)
+#define F0900_P1_FFE_ACCQ4 0xf4d701ff
 
 /*P1_FFECFG*/
-#define R0900_P1_FFECFG  0xf4d8
-#define F0900_P1_EQUALFFE_ON  0xf4d80040
-#define F0900_P1_EQUAL_USEDSYMB  0xf4d80030
-#define F0900_P1_MU_EQUALFFE  0xf4d80007
+#define R0900_P1_FFECFG 0xf4d8
+#define FFECFG REGx(R0900_P1_FFECFG)
+#define F0900_P1_EQUALFFE_ON 0xf4d80040
+#define F0900_P1_MU_EQUALFFE 0xf4d80007
 
 /*P1_TNRCFG*/
-#define R0900_P1_TNRCFG  0xf4e0
-#define F0900_P1_TUN_ACKFAIL  0xf4e00080
-#define F0900_P1_TUN_TYPE  0xf4e00070
-#define F0900_P1_TUN_SECSTOP  0xf4e00008
-#define F0900_P1_TUN_VCOSRCH  0xf4e00004
-#define F0900_P1_TUN_MADDRESS  0xf4e00003
+#define R0900_P1_TNRCFG 0xf4e0
+#define TNRCFG REGx(R0900_P1_TNRCFG)
+#define F0900_P1_TUN_ACKFAIL 0xf4e00080
+#define F0900_P1_TUN_TYPE 0xf4e00070
+#define F0900_P1_TUN_SECSTOP 0xf4e00008
+#define F0900_P1_TUN_VCOSRCH 0xf4e00004
+#define F0900_P1_TUN_MADDRESS 0xf4e00003
 
 /*P1_TNRCFG2*/
-#define R0900_P1_TNRCFG2  0xf4e1
-#define F0900_P1_TUN_IQSWAP  0xf4e10080
-#define F0900_P1_STB6110_STEP2MHZ  0xf4e10040
-#define F0900_P1_STB6120_DBLI2C  0xf4e10020
-#define F0900_P1_DIS_FCCK  0xf4e10010
-#define F0900_P1_DIS_LPEN  0xf4e10008
-#define F0900_P1_DIS_BWCALC  0xf4e10004
-#define F0900_P1_SHORT_WAITSTATES  0xf4e10002
-#define F0900_P1_DIS_2BWAGC1  0xf4e10001
+#define R0900_P1_TNRCFG2 0xf4e1
+#define TNRCFG2 REGx(R0900_P1_TNRCFG2)
+#define F0900_P1_TUN_IQSWAP 0xf4e10080
+#define F0900_P1_DIS_BWCALC 0xf4e10004
+#define F0900_P1_SHORT_WAITSTATES 0xf4e10002
 
 /*P1_TNRXTAL*/
-#define R0900_P1_TNRXTAL  0xf4e4
-#define F0900_P1_TUN_MCLKDECIMAL  0xf4e400e0
-#define F0900_P1_TUN_XTALFREQ  0xf4e4001f
+#define R0900_P1_TNRXTAL 0xf4e4
+#define TNRXTAL REGx(R0900_P1_TNRXTAL)
+#define F0900_P1_TUN_XTALFREQ 0xf4e4001f
 
 /*P1_TNRSTEPS*/
-#define R0900_P1_TNRSTEPS  0xf4e7
-#define F0900_P1_TUNER_BW1P6  0xf4e70080
-#define F0900_P1_BWINC_OFFSET  0xf4e70070
-#define F0900_P1_SOFTSTEP_RNG  0xf4e70008
-#define F0900_P1_TUN_BWOFFSET  0xf4e70107
+#define R0900_P1_TNRSTEPS 0xf4e7
+#define TNRSTEPS REGx(R0900_P1_TNRSTEPS)
+#define F0900_P1_TUNER_BW0P125 0xf4e70080
+#define F0900_P1_BWINC_OFFSET 0xf4e70170
+#define F0900_P1_SOFTSTEP_RNG 0xf4e70008
+#define F0900_P1_TUN_BWOFFSET 0xf4e70007
 
 /*P1_TNRGAIN*/
-#define R0900_P1_TNRGAIN  0xf4e8
-#define F0900_P1_TUN_KDIVEN  0xf4e800c0
-#define F0900_P1_STB6X00_OCK  0xf4e80030
-#define F0900_P1_TUN_GAIN  0xf4e8000f
+#define R0900_P1_TNRGAIN 0xf4e8
+#define TNRGAIN REGx(R0900_P1_TNRGAIN)
+#define F0900_P1_TUN_KDIVEN 0xf4e800c0
+#define F0900_P1_STB6X00_OCK 0xf4e80030
+#define F0900_P1_TUN_GAIN 0xf4e8000f
 
 /*P1_TNRRF1*/
-#define R0900_P1_TNRRF1  0xf4e9
-#define F0900_P1_TUN_RFFREQ2  0xf4e900ff
+#define R0900_P1_TNRRF1 0xf4e9
+#define TNRRF1 REGx(R0900_P1_TNRRF1)
+#define F0900_P1_TUN_RFFREQ2 0xf4e900ff
 
 /*P1_TNRRF0*/
-#define R0900_P1_TNRRF0  0xf4ea
-#define F0900_P1_TUN_RFFREQ1  0xf4ea00ff
+#define R0900_P1_TNRRF0 0xf4ea
+#define TNRRF0 REGx(R0900_P1_TNRRF0)
+#define F0900_P1_TUN_RFFREQ1 0xf4ea00ff
 
 /*P1_TNRBW*/
-#define R0900_P1_TNRBW  0xf4eb
-#define F0900_P1_TUN_RFFREQ0  0xf4eb00c0
-#define F0900_P1_TUN_BW  0xf4eb003f
+#define R0900_P1_TNRBW 0xf4eb
+#define TNRBW REGx(R0900_P1_TNRBW)
+#define F0900_P1_TUN_RFFREQ0 0xf4eb00c0
+#define F0900_P1_TUN_BW 0xf4eb003f
 
 /*P1_TNRADJ*/
-#define R0900_P1_TNRADJ  0xf4ec
-#define F0900_P1_STB61X0_RCLK  0xf4ec0080
-#define F0900_P1_STB61X0_CALTIME  0xf4ec0040
-#define F0900_P1_STB6X00_DLB  0xf4ec0038
-#define F0900_P1_STB6000_FCL  0xf4ec0007
+#define R0900_P1_TNRADJ 0xf4ec
+#define TNRADJ REGx(R0900_P1_TNRADJ)
+#define F0900_P1_STB61X0_CALTIME 0xf4ec0040
 
 /*P1_TNRCTL2*/
-#define R0900_P1_TNRCTL2  0xf4ed
-#define F0900_P1_STB61X0_LCP1_RCCKOFF  0xf4ed0080
-#define F0900_P1_STB61X0_LCP0  0xf4ed0040
-#define F0900_P1_STB61X0_XTOUT_RFOUTS  0xf4ed0020
-#define F0900_P1_STB61X0_XTON_MCKDV  0xf4ed0010
-#define F0900_P1_STB61X0_CALOFF_DCOFF  0xf4ed0008
-#define F0900_P1_STB6110_LPT  0xf4ed0004
-#define F0900_P1_STB6110_RX  0xf4ed0002
-#define F0900_P1_STB6110_SYN  0xf4ed0001
+#define R0900_P1_TNRCTL2 0xf4ed
+#define TNRCTL2 REGx(R0900_P1_TNRCTL2)
+#define F0900_P1_STB61X0_RCCKOFF 0xf4ed0080
+#define F0900_P1_STB61X0_ICP_SDOFF 0xf4ed0040
+#define F0900_P1_STB61X0_DCLOOPOFF 0xf4ed0020
+#define F0900_P1_STB61X0_REFOUTSEL 0xf4ed0010
+#define F0900_P1_STB61X0_CALOFF 0xf4ed0008
+#define F0900_P1_STB6XX0_LPT_BEN 0xf4ed0004
+#define F0900_P1_STB6XX0_RX_OSCP 0xf4ed0002
+#define F0900_P1_STB6XX0_SYN 0xf4ed0001
 
 /*P1_TNRCFG3*/
-#define R0900_P1_TNRCFG3  0xf4ee
-#define F0900_P1_STB6120_DISCTRL1  0xf4ee0080
-#define F0900_P1_STB6120_INVORDER  0xf4ee0040
-#define F0900_P1_STB6120_ENCTRL6  0xf4ee0020
-#define F0900_P1_TUN_PLLFREQ  0xf4ee001c
-#define F0900_P1_TUN_I2CFREQ_MODE  0xf4ee0003
+#define R0900_P1_TNRCFG3 0xf4ee
+#define TNRCFG3 REGx(R0900_P1_TNRCFG3)
+#define F0900_P1_TUN_PLLFREQ 0xf4ee001c
+#define F0900_P1_TUN_I2CFREQ_MODE 0xf4ee0003
 
 /*P1_TNRLAUNCH*/
-#define R0900_P1_TNRLAUNCH  0xf4f0
+#define R0900_P1_TNRLAUNCH 0xf4f0
+#define TNRLAUNCH REGx(R0900_P1_TNRLAUNCH)
 
 /*P1_TNRLD*/
-#define R0900_P1_TNRLD  0xf4f0
-#define F0900_P1_TUNLD_VCOING  0xf4f00080
-#define F0900_P1_TUN_REG1FAIL  0xf4f00040
-#define F0900_P1_TUN_REG2FAIL  0xf4f00020
-#define F0900_P1_TUN_REG3FAIL  0xf4f00010
-#define F0900_P1_TUN_REG4FAIL  0xf4f00008
-#define F0900_P1_TUN_REG5FAIL  0xf4f00004
-#define F0900_P1_TUN_BWING  0xf4f00002
-#define F0900_P1_TUN_LOCKED  0xf4f00001
+#define R0900_P1_TNRLD 0xf4f0
+#define TNRLD REGx(R0900_P1_TNRLD)
+#define F0900_P1_TUNLD_VCOING 0xf4f00080
+#define F0900_P1_TUN_REG1FAIL 0xf4f00040
+#define F0900_P1_TUN_REG2FAIL 0xf4f00020
+#define F0900_P1_TUN_REG3FAIL 0xf4f00010
+#define F0900_P1_TUN_REG4FAIL 0xf4f00008
+#define F0900_P1_TUN_REG5FAIL 0xf4f00004
+#define F0900_P1_TUN_BWING 0xf4f00002
+#define F0900_P1_TUN_LOCKED 0xf4f00001
 
 /*P1_TNROBSL*/
-#define R0900_P1_TNROBSL  0xf4f6
-#define F0900_P1_TUN_I2CABORTED  0xf4f60080
-#define F0900_P1_TUN_LPEN  0xf4f60040
-#define F0900_P1_TUN_FCCK  0xf4f60020
-#define F0900_P1_TUN_I2CLOCKED  0xf4f60010
-#define F0900_P1_TUN_PROGDONE  0xf4f6000c
-#define F0900_P1_TUN_RFRESTE1  0xf4f60003
+#define R0900_P1_TNROBSL 0xf4f6
+#define TNROBSL REGx(R0900_P1_TNROBSL)
+#define F0900_P1_TUN_I2CABORTED 0xf4f60080
+#define F0900_P1_TUN_LPEN 0xf4f60040
+#define F0900_P1_TUN_FCCK 0xf4f60020
+#define F0900_P1_TUN_I2CLOCKED 0xf4f60010
+#define F0900_P1_TUN_PROGDONE 0xf4f6000c
+#define F0900_P1_TUN_RFRESTE1 0xf4f60003
 
 /*P1_TNRRESTE*/
-#define R0900_P1_TNRRESTE  0xf4f7
-#define F0900_P1_TUN_RFRESTE0  0xf4f700ff
+#define R0900_P1_TNRRESTE 0xf4f7
+#define TNRRESTE REGx(R0900_P1_TNRRESTE)
+#define F0900_P1_TUN_RFRESTE0 0xf4f700ff
 
 /*P1_SMAPCOEF7*/
-#define R0900_P1_SMAPCOEF7  0xf500
-#define F0900_P1_DIS_QSCALE  0xf5000080
-#define F0900_P1_SMAPCOEF_Q_LLR12  0xf500017f
+#define R0900_P1_SMAPCOEF7 0xf500
+#define SMAPCOEF7 REGx(R0900_P1_SMAPCOEF7)
+#define F0900_P1_DIS_QSCALE 0xf5000080
+#define F0900_P1_SMAPCOEF_Q_LLR12 0xf500017f
 
 /*P1_SMAPCOEF6*/
-#define R0900_P1_SMAPCOEF6  0xf501
-#define F0900_P1_DIS_NEWSCALE  0xf5010008
-#define F0900_P1_ADJ_8PSKLLR1  0xf5010004
-#define F0900_P1_OLD_8PSKLLR1  0xf5010002
-#define F0900_P1_DIS_AB8PSK  0xf5010001
+#define R0900_P1_SMAPCOEF6 0xf501
+#define SMAPCOEF6 REGx(R0900_P1_SMAPCOEF6)
+#define F0900_P1_ADJ_8PSKLLR1 0xf5010004
+#define F0900_P1_OLD_8PSKLLR1 0xf5010002
+#define F0900_P1_DIS_AB8PSK 0xf5010001
 
 /*P1_SMAPCOEF5*/
-#define R0900_P1_SMAPCOEF5  0xf502
-#define F0900_P1_DIS_8SCALE  0xf5020080
-#define F0900_P1_SMAPCOEF_8P_LLR23  0xf502017f
+#define R0900_P1_SMAPCOEF5 0xf502
+#define SMAPCOEF5 REGx(R0900_P1_SMAPCOEF5)
+#define F0900_P1_DIS_8SCALE 0xf5020080
+#define F0900_P1_SMAPCOEF_8P_LLR23 0xf502017f
+
+/*P1_NCO2MAX1*/
+#define R0900_P1_NCO2MAX1 0xf514
+#define NCO2MAX1 REGx(R0900_P1_NCO2MAX1)
+#define F0900_P1_TETA2_MAXVABS1 0xf51400ff
+
+/*P1_NCO2MAX0*/
+#define R0900_P1_NCO2MAX0 0xf515
+#define NCO2MAX0 REGx(R0900_P1_NCO2MAX0)
+#define F0900_P1_TETA2_MAXVABS0 0xf51500ff
+
+/*P1_NCO2FR1*/
+#define R0900_P1_NCO2FR1 0xf516
+#define NCO2FR1 REGx(R0900_P1_NCO2FR1)
+#define F0900_P1_NCO2FINAL_ANGLE1 0xf51600ff
+
+/*P1_NCO2FR0*/
+#define R0900_P1_NCO2FR0 0xf517
+#define NCO2FR0 REGx(R0900_P1_NCO2FR0)
+#define F0900_P1_NCO2FINAL_ANGLE0 0xf51700ff
+
+/*P1_CFR2AVRGE1*/
+#define R0900_P1_CFR2AVRGE1 0xf518
+#define CFR2AVRGE1 REGx(R0900_P1_CFR2AVRGE1)
+#define F0900_P1_I2C_CFR2AVERAGE1 0xf51800ff
+
+/*P1_CFR2AVRGE0*/
+#define R0900_P1_CFR2AVRGE0 0xf519
+#define CFR2AVRGE0 REGx(R0900_P1_CFR2AVRGE0)
+#define F0900_P1_I2C_CFR2AVERAGE0 0xf51900ff
 
 /*P1_DMDPLHSTAT*/
-#define R0900_P1_DMDPLHSTAT  0xf520
-#define F0900_P1_PLH_STATISTIC  0xf52000ff
+#define R0900_P1_DMDPLHSTAT 0xf520
+#define DMDPLHSTAT REGx(R0900_P1_DMDPLHSTAT)
+#define F0900_P1_PLH_STATISTIC 0xf52000ff
 
 /*P1_LOCKTIME3*/
-#define R0900_P1_LOCKTIME3  0xf522
-#define F0900_P1_DEMOD_LOCKTIME3  0xf52200ff
+#define R0900_P1_LOCKTIME3 0xf522
+#define LOCKTIME3 REGx(R0900_P1_LOCKTIME3)
+#define F0900_P1_DEMOD_LOCKTIME3 0xf52200ff
 
 /*P1_LOCKTIME2*/
-#define R0900_P1_LOCKTIME2  0xf523
-#define F0900_P1_DEMOD_LOCKTIME2  0xf52300ff
+#define R0900_P1_LOCKTIME2 0xf523
+#define LOCKTIME2 REGx(R0900_P1_LOCKTIME2)
+#define F0900_P1_DEMOD_LOCKTIME2 0xf52300ff
 
 /*P1_LOCKTIME1*/
-#define R0900_P1_LOCKTIME1  0xf524
-#define F0900_P1_DEMOD_LOCKTIME1  0xf52400ff
+#define R0900_P1_LOCKTIME1 0xf524
+#define LOCKTIME1 REGx(R0900_P1_LOCKTIME1)
+#define F0900_P1_DEMOD_LOCKTIME1 0xf52400ff
 
 /*P1_LOCKTIME0*/
-#define R0900_P1_LOCKTIME0  0xf525
-#define F0900_P1_DEMOD_LOCKTIME0  0xf52500ff
+#define R0900_P1_LOCKTIME0 0xf525
+#define LOCKTIME0 REGx(R0900_P1_LOCKTIME0)
+#define F0900_P1_DEMOD_LOCKTIME0 0xf52500ff
 
 /*P1_VITSCALE*/
-#define R0900_P1_VITSCALE  0xf532
-#define F0900_P1_NVTH_NOSRANGE  0xf5320080
-#define F0900_P1_VERROR_MAXMODE  0xf5320040
-#define F0900_P1_KDIV_MODE  0xf5320030
-#define F0900_P1_NSLOWSN_LOCKED  0xf5320008
-#define F0900_P1_DELOCK_PRFLOSS  0xf5320004
-#define F0900_P1_DIS_RSFLOCK  0xf5320002
+#define R0900_P1_VITSCALE 0xf532
+#define VITSCALE REGx(R0900_P1_VITSCALE)
+#define F0900_P1_NVTH_NOSRANGE 0xf5320080
+#define F0900_P1_VERROR_MAXMODE 0xf5320040
+#define F0900_P1_NSLOWSN_LOCKED 0xf5320008
+#define F0900_P1_DIS_RSFLOCK 0xf5320002
 
 /*P1_FECM*/
-#define R0900_P1_FECM  0xf533
-#define F0900_P1_DSS_DVB  0xf5330080
-#define F0900_P1_DEMOD_BYPASS  0xf5330040
-#define F0900_P1_CMP_SLOWMODE  0xf5330020
-#define F0900_P1_DSS_SRCH  0xf5330010
-#define F0900_P1_DIFF_MODEVIT  0xf5330004
-#define F0900_P1_SYNCVIT  0xf5330002
-#define F0900_P1_IQINV  0xf5330001
+#define R0900_P1_FECM 0xf533
+#define FECM REGx(R0900_P1_FECM)
+#define F0900_P1_DSS_DVB 0xf5330080
+#define DSS_DVB FLDx(F0900_P1_DSS_DVB)
+#define F0900_P1_DSS_SRCH 0xf5330010
+#define F0900_P1_SYNCVIT 0xf5330002
+#define F0900_P1_IQINV 0xf5330001
+#define IQINV FLDx(F0900_P1_IQINV)
 
 /*P1_VTH12*/
-#define R0900_P1_VTH12  0xf534
-#define F0900_P1_VTH12  0xf53400ff
+#define R0900_P1_VTH12 0xf534
+#define VTH12 REGx(R0900_P1_VTH12)
+#define F0900_P1_VTH12 0xf53400ff
 
 /*P1_VTH23*/
-#define R0900_P1_VTH23  0xf535
-#define F0900_P1_VTH23  0xf53500ff
+#define R0900_P1_VTH23 0xf535
+#define VTH23 REGx(R0900_P1_VTH23)
+#define F0900_P1_VTH23 0xf53500ff
 
 /*P1_VTH34*/
-#define R0900_P1_VTH34  0xf536
-#define F0900_P1_VTH34  0xf53600ff
+#define R0900_P1_VTH34 0xf536
+#define VTH34 REGx(R0900_P1_VTH34)
+#define F0900_P1_VTH34 0xf53600ff
 
 /*P1_VTH56*/
-#define R0900_P1_VTH56  0xf537
-#define F0900_P1_VTH56  0xf53700ff
+#define R0900_P1_VTH56 0xf537
+#define VTH56 REGx(R0900_P1_VTH56)
+#define F0900_P1_VTH56 0xf53700ff
 
 /*P1_VTH67*/
-#define R0900_P1_VTH67  0xf538
-#define F0900_P1_VTH67  0xf53800ff
+#define R0900_P1_VTH67 0xf538
+#define VTH67 REGx(R0900_P1_VTH67)
+#define F0900_P1_VTH67 0xf53800ff
 
 /*P1_VTH78*/
-#define R0900_P1_VTH78  0xf539
-#define F0900_P1_VTH78  0xf53900ff
+#define R0900_P1_VTH78 0xf539
+#define VTH78 REGx(R0900_P1_VTH78)
+#define F0900_P1_VTH78 0xf53900ff
 
 /*P1_VITCURPUN*/
-#define R0900_P1_VITCURPUN  0xf53a
-#define F0900_P1_VIT_MAPPING  0xf53a00e0
-#define F0900_P1_VIT_CURPUN  0xf53a001f
+#define R0900_P1_VITCURPUN 0xf53a
+#define VITCURPUN REGx(R0900_P1_VITCURPUN)
+#define F0900_P1_VIT_CURPUN 0xf53a001f
+#define VIT_CURPUN FLDx(F0900_P1_VIT_CURPUN)
 
 /*P1_VERROR*/
-#define R0900_P1_VERROR  0xf53b
-#define F0900_P1_REGERR_VIT  0xf53b00ff
+#define R0900_P1_VERROR 0xf53b
+#define VERROR REGx(R0900_P1_VERROR)
+#define F0900_P1_REGERR_VIT 0xf53b00ff
 
 /*P1_PRVIT*/
-#define R0900_P1_PRVIT  0xf53c
-#define F0900_P1_DIS_VTHLOCK  0xf53c0040
-#define F0900_P1_E7_8VIT  0xf53c0020
-#define F0900_P1_E6_7VIT  0xf53c0010
-#define F0900_P1_E5_6VIT  0xf53c0008
-#define F0900_P1_E3_4VIT  0xf53c0004
-#define F0900_P1_E2_3VIT  0xf53c0002
-#define F0900_P1_E1_2VIT  0xf53c0001
+#define R0900_P1_PRVIT 0xf53c
+#define PRVIT REGx(R0900_P1_PRVIT)
+#define F0900_P1_DIS_VTHLOCK 0xf53c0040
+#define F0900_P1_E7_8VIT 0xf53c0020
+#define F0900_P1_E6_7VIT 0xf53c0010
+#define F0900_P1_E5_6VIT 0xf53c0008
+#define F0900_P1_E3_4VIT 0xf53c0004
+#define F0900_P1_E2_3VIT 0xf53c0002
+#define F0900_P1_E1_2VIT 0xf53c0001
 
 /*P1_VAVSRVIT*/
-#define R0900_P1_VAVSRVIT  0xf53d
-#define F0900_P1_AMVIT  0xf53d0080
-#define F0900_P1_FROZENVIT  0xf53d0040
-#define F0900_P1_SNVIT  0xf53d0030
-#define F0900_P1_TOVVIT  0xf53d000c
-#define F0900_P1_HYPVIT  0xf53d0003
+#define R0900_P1_VAVSRVIT 0xf53d
+#define VAVSRVIT REGx(R0900_P1_VAVSRVIT)
+#define F0900_P1_AMVIT 0xf53d0080
+#define F0900_P1_FROZENVIT 0xf53d0040
+#define F0900_P1_SNVIT 0xf53d0030
+#define F0900_P1_TOVVIT 0xf53d000c
+#define F0900_P1_HYPVIT 0xf53d0003
 
 /*P1_VSTATUSVIT*/
-#define R0900_P1_VSTATUSVIT  0xf53e
-#define F0900_P1_VITERBI_ON  0xf53e0080
-#define F0900_P1_END_LOOPVIT  0xf53e0040
-#define F0900_P1_VITERBI_DEPRF  0xf53e0020
-#define F0900_P1_PRFVIT  0xf53e0010
-#define F0900_P1_LOCKEDVIT  0xf53e0008
-#define F0900_P1_VITERBI_DELOCK  0xf53e0004
-#define F0900_P1_VIT_DEMODSEL  0xf53e0002
-#define F0900_P1_VITERBI_COMPOUT  0xf53e0001
+#define R0900_P1_VSTATUSVIT 0xf53e
+#define VSTATUSVIT REGx(R0900_P1_VSTATUSVIT)
+#define F0900_P1_PRFVIT 0xf53e0010
+#define PRFVIT FLDx(F0900_P1_PRFVIT)
+#define F0900_P1_LOCKEDVIT 0xf53e0008
+#define LOCKEDVIT FLDx(F0900_P1_LOCKEDVIT)
 
 /*P1_VTHINUSE*/
-#define R0900_P1_VTHINUSE  0xf53f
-#define F0900_P1_VIT_INUSE  0xf53f00ff
+#define R0900_P1_VTHINUSE 0xf53f
+#define VTHINUSE REGx(R0900_P1_VTHINUSE)
+#define F0900_P1_VIT_INUSE 0xf53f00ff
 
 /*P1_KDIV12*/
-#define R0900_P1_KDIV12  0xf540
-#define F0900_P1_KDIV12_MANUAL  0xf5400080
-#define F0900_P1_K_DIVIDER_12  0xf540007f
+#define R0900_P1_KDIV12 0xf540
+#define KDIV12 REGx(R0900_P1_KDIV12)
+#define F0900_P1_K_DIVIDER_12 0xf540007f
 
 /*P1_KDIV23*/
-#define R0900_P1_KDIV23  0xf541
-#define F0900_P1_KDIV23_MANUAL  0xf5410080
-#define F0900_P1_K_DIVIDER_23  0xf541007f
+#define R0900_P1_KDIV23 0xf541
+#define KDIV23 REGx(R0900_P1_KDIV23)
+#define F0900_P1_K_DIVIDER_23 0xf541007f
 
 /*P1_KDIV34*/
-#define R0900_P1_KDIV34  0xf542
-#define F0900_P1_KDIV34_MANUAL  0xf5420080
-#define F0900_P1_K_DIVIDER_34  0xf542007f
+#define R0900_P1_KDIV34 0xf542
+#define KDIV34 REGx(R0900_P1_KDIV34)
+#define F0900_P1_K_DIVIDER_34 0xf542007f
 
 /*P1_KDIV56*/
-#define R0900_P1_KDIV56  0xf543
-#define F0900_P1_KDIV56_MANUAL  0xf5430080
-#define F0900_P1_K_DIVIDER_56  0xf543007f
+#define R0900_P1_KDIV56 0xf543
+#define KDIV56 REGx(R0900_P1_KDIV56)
+#define F0900_P1_K_DIVIDER_56 0xf543007f
 
 /*P1_KDIV67*/
-#define R0900_P1_KDIV67  0xf544
-#define F0900_P1_KDIV67_MANUAL  0xf5440080
-#define F0900_P1_K_DIVIDER_67  0xf544007f
+#define R0900_P1_KDIV67 0xf544
+#define KDIV67 REGx(R0900_P1_KDIV67)
+#define F0900_P1_K_DIVIDER_67 0xf544007f
 
 /*P1_KDIV78*/
-#define R0900_P1_KDIV78  0xf545
-#define F0900_P1_KDIV78_MANUAL  0xf5450080
-#define F0900_P1_K_DIVIDER_78  0xf545007f
+#define R0900_P1_KDIV78 0xf545
+#define KDIV78 REGx(R0900_P1_KDIV78)
+#define F0900_P1_K_DIVIDER_78 0xf545007f
 
 /*P1_PDELCTRL1*/
-#define R0900_P1_PDELCTRL1  0xf550
-#define F0900_P1_INV_MISMASK  0xf5500080
-#define F0900_P1_FORCE_ACCEPTED  0xf5500040
-#define F0900_P1_FILTER_EN  0xf5500020
-#define F0900_P1_FORCE_PKTDELINUSE  0xf5500010
-#define F0900_P1_HYSTEN  0xf5500008
-#define F0900_P1_HYSTSWRST  0xf5500004
-#define F0900_P1_EN_MIS00  0xf5500002
-#define F0900_P1_ALGOSWRST  0xf5500001
+#define R0900_P1_PDELCTRL1 0xf550
+#define PDELCTRL1 REGx(R0900_P1_PDELCTRL1)
+#define F0900_P1_INV_MISMASK 0xf5500080
+#define F0900_P1_FILTER_EN 0xf5500020
+#define F0900_P1_EN_MIS00 0xf5500002
+#define F0900_P1_ALGOSWRST 0xf5500001
+#define ALGOSWRST FLDx(F0900_P1_ALGOSWRST)
 
 /*P1_PDELCTRL2*/
-#define R0900_P1_PDELCTRL2  0xf551
-#define F0900_P1_FORCE_CONTINUOUS  0xf5510080
-#define F0900_P1_RESET_UPKO_COUNT  0xf5510040
-#define F0900_P1_USER_PKTDELIN_NB  0xf5510020
-#define F0900_P1_FORCE_LOCKED  0xf5510010
-#define F0900_P1_DATA_UNBBSCRAM  0xf5510008
-#define F0900_P1_FORCE_LONGPKT  0xf5510004
-#define F0900_P1_FRAME_MODE  0xf5510002
+#define R0900_P1_PDELCTRL2 0xf551
+#define PDELCTRL2 REGx(R0900_P1_PDELCTRL2)
+#define F0900_P1_RESET_UPKO_COUNT 0xf5510040
+#define RESET_UPKO_COUNT FLDx(F0900_P1_RESET_UPKO_COUNT)
+#define F0900_P1_FRAME_MODE 0xf5510002
+#define F0900_P1_NOBCHERRFLG_USE 0xf5510001
 
 /*P1_HYSTTHRESH*/
-#define R0900_P1_HYSTTHRESH  0xf554
-#define F0900_P1_UNLCK_THRESH  0xf55400f0
-#define F0900_P1_DELIN_LCK_THRESH  0xf554000f
+#define R0900_P1_HYSTTHRESH 0xf554
+#define HYSTTHRESH REGx(R0900_P1_HYSTTHRESH)
+#define F0900_P1_UNLCK_THRESH 0xf55400f0
+#define F0900_P1_DELIN_LCK_THRESH 0xf554000f
 
 /*P1_ISIENTRY*/
-#define R0900_P1_ISIENTRY  0xf55e
-#define F0900_P1_ISI_ENTRY  0xf55e00ff
+#define R0900_P1_ISIENTRY 0xf55e
+#define ISIENTRY REGx(R0900_P1_ISIENTRY)
+#define F0900_P1_ISI_ENTRY 0xf55e00ff
 
 /*P1_ISIBITENA*/
-#define R0900_P1_ISIBITENA  0xf55f
-#define F0900_P1_ISI_BIT_EN  0xf55f00ff
+#define R0900_P1_ISIBITENA 0xf55f
+#define ISIBITENA REGx(R0900_P1_ISIBITENA)
+#define F0900_P1_ISI_BIT_EN 0xf55f00ff
 
 /*P1_MATSTR1*/
-#define R0900_P1_MATSTR1  0xf560
-#define F0900_P1_MATYPE_CURRENT1  0xf56000ff
+#define R0900_P1_MATSTR1 0xf560
+#define MATSTR1 REGx(R0900_P1_MATSTR1)
+#define F0900_P1_MATYPE_CURRENT1 0xf56000ff
 
 /*P1_MATSTR0*/
-#define R0900_P1_MATSTR0  0xf561
-#define F0900_P1_MATYPE_CURRENT0  0xf56100ff
+#define R0900_P1_MATSTR0 0xf561
+#define MATSTR0 REGx(R0900_P1_MATSTR0)
+#define F0900_P1_MATYPE_CURRENT0 0xf56100ff
 
 /*P1_UPLSTR1*/
-#define R0900_P1_UPLSTR1  0xf562
-#define F0900_P1_UPL_CURRENT1  0xf56200ff
+#define R0900_P1_UPLSTR1 0xf562
+#define UPLSTR1 REGx(R0900_P1_UPLSTR1)
+#define F0900_P1_UPL_CURRENT1 0xf56200ff
 
 /*P1_UPLSTR0*/
-#define R0900_P1_UPLSTR0  0xf563
-#define F0900_P1_UPL_CURRENT0  0xf56300ff
+#define R0900_P1_UPLSTR0 0xf563
+#define UPLSTR0 REGx(R0900_P1_UPLSTR0)
+#define F0900_P1_UPL_CURRENT0 0xf56300ff
 
 /*P1_DFLSTR1*/
-#define R0900_P1_DFLSTR1  0xf564
-#define F0900_P1_DFL_CURRENT1  0xf56400ff
+#define R0900_P1_DFLSTR1 0xf564
+#define DFLSTR1 REGx(R0900_P1_DFLSTR1)
+#define F0900_P1_DFL_CURRENT1 0xf56400ff
 
 /*P1_DFLSTR0*/
-#define R0900_P1_DFLSTR0  0xf565
-#define F0900_P1_DFL_CURRENT0  0xf56500ff
+#define R0900_P1_DFLSTR0 0xf565
+#define DFLSTR0 REGx(R0900_P1_DFLSTR0)
+#define F0900_P1_DFL_CURRENT0 0xf56500ff
 
 /*P1_SYNCSTR*/
-#define R0900_P1_SYNCSTR  0xf566
-#define F0900_P1_SYNC_CURRENT  0xf56600ff
+#define R0900_P1_SYNCSTR 0xf566
+#define SYNCSTR REGx(R0900_P1_SYNCSTR)
+#define F0900_P1_SYNC_CURRENT 0xf56600ff
 
 /*P1_SYNCDSTR1*/
-#define R0900_P1_SYNCDSTR1  0xf567
-#define F0900_P1_SYNCD_CURRENT1  0xf56700ff
+#define R0900_P1_SYNCDSTR1 0xf567
+#define SYNCDSTR1 REGx(R0900_P1_SYNCDSTR1)
+#define F0900_P1_SYNCD_CURRENT1 0xf56700ff
 
 /*P1_SYNCDSTR0*/
-#define R0900_P1_SYNCDSTR0  0xf568
-#define F0900_P1_SYNCD_CURRENT0  0xf56800ff
+#define R0900_P1_SYNCDSTR0 0xf568
+#define SYNCDSTR0 REGx(R0900_P1_SYNCDSTR0)
+#define F0900_P1_SYNCD_CURRENT0 0xf56800ff
 
 /*P1_PDELSTATUS1*/
-#define R0900_P1_PDELSTATUS1  0xf569
-#define F0900_P1_PKTDELIN_DELOCK  0xf5690080
-#define F0900_P1_SYNCDUPDFL_BADDFL  0xf5690040
-#define F0900_P1_CONTINUOUS_STREAM  0xf5690020
-#define F0900_P1_UNACCEPTED_STREAM  0xf5690010
-#define F0900_P1_BCH_ERROR_FLAG  0xf5690008
-#define F0900_P1_BBHCRCKO  0xf5690004
-#define F0900_P1_PKTDELIN_LOCK  0xf5690002
-#define F0900_P1_FIRST_LOCK  0xf5690001
+#define R0900_P1_PDELSTATUS1 0xf569
+#define F0900_P1_PKTDELIN_DELOCK 0xf5690080
+#define F0900_P1_SYNCDUPDFL_BADDFL 0xf5690040
+#define F0900_P1_CONTINUOUS_STREAM 0xf5690020
+#define F0900_P1_UNACCEPTED_STREAM 0xf5690010
+#define F0900_P1_BCH_ERROR_FLAG 0xf5690008
+#define F0900_P1_PKTDELIN_LOCK 0xf5690002
+#define PKTDELIN_LOCK FLDx(F0900_P1_PKTDELIN_LOCK)
+#define F0900_P1_FIRST_LOCK 0xf5690001
 
 /*P1_PDELSTATUS2*/
-#define R0900_P1_PDELSTATUS2  0xf56a
-#define F0900_P1_PKTDEL_DEMODSEL  0xf56a0080
-#define F0900_P1_FRAME_MODCOD  0xf56a007c
-#define F0900_P1_FRAME_TYPE  0xf56a0003
+#define R0900_P1_PDELSTATUS2 0xf56a
+#define F0900_P1_FRAME_MODCOD 0xf56a007c
+#define F0900_P1_FRAME_TYPE 0xf56a0003
 
 /*P1_BBFCRCKO1*/
-#define R0900_P1_BBFCRCKO1  0xf56b
-#define F0900_P1_BBHCRC_KOCNT1  0xf56b00ff
+#define R0900_P1_BBFCRCKO1 0xf56b
+#define BBFCRCKO1 REGx(R0900_P1_BBFCRCKO1)
+#define F0900_P1_BBHCRC_KOCNT1 0xf56b00ff
 
 /*P1_BBFCRCKO0*/
-#define R0900_P1_BBFCRCKO0  0xf56c
-#define F0900_P1_BBHCRC_KOCNT0  0xf56c00ff
+#define R0900_P1_BBFCRCKO0 0xf56c
+#define BBFCRCKO0 REGx(R0900_P1_BBFCRCKO0)
+#define F0900_P1_BBHCRC_KOCNT0 0xf56c00ff
 
 /*P1_UPCRCKO1*/
-#define R0900_P1_UPCRCKO1  0xf56d
-#define F0900_P1_PKTCRC_KOCNT1  0xf56d00ff
+#define R0900_P1_UPCRCKO1 0xf56d
+#define UPCRCKO1 REGx(R0900_P1_UPCRCKO1)
+#define F0900_P1_PKTCRC_KOCNT1 0xf56d00ff
 
 /*P1_UPCRCKO0*/
-#define R0900_P1_UPCRCKO0  0xf56e
-#define F0900_P1_PKTCRC_KOCNT0  0xf56e00ff
+#define R0900_P1_UPCRCKO0 0xf56e
+#define UPCRCKO0 REGx(R0900_P1_UPCRCKO0)
+#define F0900_P1_PKTCRC_KOCNT0 0xf56e00ff
+
+/*P1_PDELCTRL3*/
+#define R0900_P1_PDELCTRL3 0xf56f
+#define PDELCTRL3 REGx(R0900_P1_PDELCTRL3)
+#define F0900_P1_PKTDEL_CONTFAIL 0xf56f0080
+#define F0900_P1_NOFIFO_BCHERR 0xf56f0020
 
 /*P1_TSSTATEM*/
-#define R0900_P1_TSSTATEM  0xf570
-#define F0900_P1_TSDIL_ON  0xf5700080
-#define F0900_P1_TSSKIPRS_ON  0xf5700040
-#define F0900_P1_TSRS_ON  0xf5700020
-#define F0900_P1_TSDESCRAMB_ON  0xf5700010
-#define F0900_P1_TSFRAME_MODE  0xf5700008
-#define F0900_P1_TS_DISABLE  0xf5700004
-#define F0900_P1_TSACM_MODE  0xf5700002
-#define F0900_P1_TSOUT_NOSYNC  0xf5700001
+#define R0900_P1_TSSTATEM 0xf570
+#define TSSTATEM REGx(R0900_P1_TSSTATEM)
+#define F0900_P1_TSDIL_ON 0xf5700080
+#define F0900_P1_TSRS_ON 0xf5700020
+#define F0900_P1_TSDESCRAMB_ON 0xf5700010
+#define F0900_P1_TSFRAME_MODE 0xf5700008
+#define F0900_P1_TS_DISABLE 0xf5700004
+#define F0900_P1_TSOUT_NOSYNC 0xf5700001
 
 /*P1_TSCFGH*/
-#define R0900_P1_TSCFGH  0xf572
-#define F0900_P1_TSFIFO_DVBCI  0xf5720080
-#define F0900_P1_TSFIFO_SERIAL  0xf5720040
-#define F0900_P1_TSFIFO_TEIUPDATE  0xf5720020
-#define F0900_P1_TSFIFO_DUTY50  0xf5720010
-#define F0900_P1_TSFIFO_HSGNLOUT  0xf5720008
-#define F0900_P1_TSFIFO_ERRMODE  0xf5720006
-#define F0900_P1_RST_HWARE  0xf5720001
+#define R0900_P1_TSCFGH 0xf572
+#define TSCFGH REGx(R0900_P1_TSCFGH)
+#define F0900_P1_TSFIFO_DVBCI 0xf5720080
+#define F0900_P1_TSFIFO_SERIAL 0xf5720040
+#define F0900_P1_TSFIFO_TEIUPDATE 0xf5720020
+#define F0900_P1_TSFIFO_DUTY50 0xf5720010
+#define F0900_P1_TSFIFO_HSGNLOUT 0xf5720008
+#define F0900_P1_TSFIFO_ERRMODE 0xf5720006
+#define F0900_P1_RST_HWARE 0xf5720001
+#define RST_HWARE FLDx(F0900_P1_RST_HWARE)
 
 /*P1_TSCFGM*/
-#define R0900_P1_TSCFGM  0xf573
-#define F0900_P1_TSFIFO_MANSPEED  0xf57300c0
-#define F0900_P1_TSFIFO_PERMDATA  0xf5730020
-#define F0900_P1_TSFIFO_NONEWSGNL  0xf5730010
-#define F0900_P1_TSFIFO_BITSPEED  0xf5730008
-#define F0900_P1_NPD_SPECDVBS2  0xf5730004
-#define F0900_P1_TSFIFO_STOPCKDIS  0xf5730002
-#define F0900_P1_TSFIFO_INVDATA  0xf5730001
+#define R0900_P1_TSCFGM 0xf573
+#define TSCFGM REGx(R0900_P1_TSCFGM)
+#define F0900_P1_TSFIFO_MANSPEED 0xf57300c0
+#define F0900_P1_TSFIFO_PERMDATA 0xf5730020
+#define F0900_P1_TSFIFO_DPUNACT 0xf5730002
+#define F0900_P1_TSFIFO_INVDATA 0xf5730001
 
 /*P1_TSCFGL*/
-#define R0900_P1_TSCFGL  0xf574
-#define F0900_P1_TSFIFO_BCLKDEL1CK  0xf57400c0
-#define F0900_P1_BCHERROR_MODE  0xf5740030
-#define F0900_P1_TSFIFO_NSGNL2DATA  0xf5740008
-#define F0900_P1_TSFIFO_EMBINDVB  0xf5740004
-#define F0900_P1_TSFIFO_DPUNACT  0xf5740002
-#define F0900_P1_TSFIFO_NPDOFF  0xf5740001
+#define R0900_P1_TSCFGL 0xf574
+#define TSCFGL REGx(R0900_P1_TSCFGL)
+#define F0900_P1_TSFIFO_BCLKDEL1CK 0xf57400c0
+#define F0900_P1_BCHERROR_MODE 0xf5740030
+#define F0900_P1_TSFIFO_NSGNL2DATA 0xf5740008
+#define F0900_P1_TSFIFO_EMBINDVB 0xf5740004
+#define F0900_P1_TSFIFO_BITSPEED 0xf5740003
 
 /*P1_TSINSDELH*/
-#define R0900_P1_TSINSDELH  0xf576
-#define F0900_P1_TSDEL_SYNCBYTE  0xf5760080
-#define F0900_P1_TSDEL_XXHEADER  0xf5760040
-#define F0900_P1_TSDEL_BBHEADER  0xf5760020
-#define F0900_P1_TSDEL_DATAFIELD  0xf5760010
-#define F0900_P1_TSINSDEL_ISCR  0xf5760008
-#define F0900_P1_TSINSDEL_NPD  0xf5760004
-#define F0900_P1_TSINSDEL_RSPARITY  0xf5760002
-#define F0900_P1_TSINSDEL_CRC8  0xf5760001
+#define R0900_P1_TSINSDELH 0xf576
+#define TSINSDELH REGx(R0900_P1_TSINSDELH)
+#define F0900_P1_TSDEL_SYNCBYTE 0xf5760080
+#define F0900_P1_TSDEL_XXHEADER 0xf5760040
+#define F0900_P1_TSDEL_BBHEADER 0xf5760020
+#define F0900_P1_TSDEL_DATAFIELD 0xf5760010
+#define F0900_P1_TSINSDEL_ISCR 0xf5760008
+#define F0900_P1_TSINSDEL_NPD 0xf5760004
+#define F0900_P1_TSINSDEL_RSPARITY 0xf5760002
+#define F0900_P1_TSINSDEL_CRC8 0xf5760001
+
+/*P1_TSDIVN*/
+#define R0900_P1_TSDIVN 0xf579
+#define TSDIVN REGx(R0900_P1_TSDIVN)
+#define F0900_P1_TSFIFO_SPEEDMODE 0xf57900c0
+
+/*P1_TSCFG4*/
+#define R0900_P1_TSCFG4 0xf57a
+#define TSCFG4 REGx(R0900_P1_TSCFG4)
+#define F0900_P1_TSFIFO_TSSPEEDMODE 0xf57a00c0
 
 /*P1_TSSPEED*/
-#define R0900_P1_TSSPEED  0xf580
-#define F0900_P1_TSFIFO_OUTSPEED  0xf58000ff
+#define R0900_P1_TSSPEED 0xf580
+#define TSSPEED REGx(R0900_P1_TSSPEED)
+#define F0900_P1_TSFIFO_OUTSPEED 0xf58000ff
 
 /*P1_TSSTATUS*/
-#define R0900_P1_TSSTATUS  0xf581
-#define F0900_P1_TSFIFO_LINEOK  0xf5810080
-#define F0900_P1_TSFIFO_ERROR  0xf5810040
-#define F0900_P1_TSFIFO_DATA7  0xf5810020
-#define F0900_P1_TSFIFO_NOSYNC  0xf5810010
-#define F0900_P1_ISCR_INITIALIZED  0xf5810008
-#define F0900_P1_ISCR_UPDATED  0xf5810004
-#define F0900_P1_SOFFIFO_UNREGUL  0xf5810002
-#define F0900_P1_DIL_READY  0xf5810001
+#define R0900_P1_TSSTATUS 0xf581
+#define TSSTATUS REGx(R0900_P1_TSSTATUS)
+#define F0900_P1_TSFIFO_LINEOK 0xf5810080
+#define TSFIFO_LINEOK FLDx(F0900_P1_TSFIFO_LINEOK)
+#define F0900_P1_TSFIFO_ERROR 0xf5810040
+#define F0900_P1_DIL_READY 0xf5810001
 
 /*P1_TSSTATUS2*/
-#define R0900_P1_TSSTATUS2  0xf582
-#define F0900_P1_TSFIFO_DEMODSEL  0xf5820080
-#define F0900_P1_TSFIFOSPEED_STORE  0xf5820040
-#define F0900_P1_DILXX_RESET  0xf5820020
-#define F0900_P1_TSSERIAL_IMPOS  0xf5820010
-#define F0900_P1_TSFIFO_LINENOK  0xf5820008
-#define F0900_P1_BITSPEED_EVENT  0xf5820004
-#define F0900_P1_SCRAMBDETECT  0xf5820002
-#define F0900_P1_ULDTV67_FALSELOCK  0xf5820001
+#define R0900_P1_TSSTATUS2 0xf582
+#define TSSTATUS2 REGx(R0900_P1_TSSTATUS2)
+#define F0900_P1_TSFIFO_DEMODSEL 0xf5820080
+#define F0900_P1_TSFIFOSPEED_STORE 0xf5820040
+#define F0900_P1_DILXX_RESET 0xf5820020
+#define F0900_P1_TSSERIAL_IMPOS 0xf5820010
+#define F0900_P1_SCRAMBDETECT 0xf5820002
 
 /*P1_TSBITRATE1*/
-#define R0900_P1_TSBITRATE1  0xf583
-#define F0900_P1_TSFIFO_BITRATE1  0xf58300ff
+#define R0900_P1_TSBITRATE1 0xf583
+#define TSBITRATE1 REGx(R0900_P1_TSBITRATE1)
+#define F0900_P1_TSFIFO_BITRATE1 0xf58300ff
 
 /*P1_TSBITRATE0*/
-#define R0900_P1_TSBITRATE0  0xf584
-#define F0900_P1_TSFIFO_BITRATE0  0xf58400ff
+#define R0900_P1_TSBITRATE0 0xf584
+#define TSBITRATE0 REGx(R0900_P1_TSBITRATE0)
+#define F0900_P1_TSFIFO_BITRATE0 0xf58400ff
 
 /*P1_ERRCTRL1*/
-#define R0900_P1_ERRCTRL1  0xf598
-#define F0900_P1_ERR_SOURCE1  0xf59800f0
-#define F0900_P1_NUM_EVENT1  0xf5980007
+#define R0900_P1_ERRCTRL1 0xf598
+#define ERRCTRL1 REGx(R0900_P1_ERRCTRL1)
+#define F0900_P1_ERR_SOURCE1 0xf59800f0
+#define F0900_P1_NUM_EVENT1 0xf5980007
 
 /*P1_ERRCNT12*/
-#define R0900_P1_ERRCNT12  0xf599
-#define F0900_P1_ERRCNT1_OLDVALUE  0xf5990080
-#define F0900_P1_ERR_CNT12  0xf599007f
+#define R0900_P1_ERRCNT12 0xf599
+#define ERRCNT12 REGx(R0900_P1_ERRCNT12)
+#define F0900_P1_ERRCNT1_OLDVALUE 0xf5990080
+#define F0900_P1_ERR_CNT12 0xf599007f
+#define ERR_CNT12 FLDx(F0900_P1_ERR_CNT12)
 
 /*P1_ERRCNT11*/
-#define R0900_P1_ERRCNT11  0xf59a
-#define F0900_P1_ERR_CNT11  0xf59a00ff
+#define R0900_P1_ERRCNT11 0xf59a
+#define ERRCNT11 REGx(R0900_P1_ERRCNT11)
+#define F0900_P1_ERR_CNT11 0xf59a00ff
+#define ERR_CNT11 FLDx(F0900_P1_ERR_CNT11)
 
 /*P1_ERRCNT10*/
-#define R0900_P1_ERRCNT10  0xf59b
-#define F0900_P1_ERR_CNT10  0xf59b00ff
+#define R0900_P1_ERRCNT10 0xf59b
+#define ERRCNT10 REGx(R0900_P1_ERRCNT10)
+#define F0900_P1_ERR_CNT10 0xf59b00ff
+#define ERR_CNT10 FLDx(F0900_P1_ERR_CNT10)
 
 /*P1_ERRCTRL2*/
-#define R0900_P1_ERRCTRL2  0xf59c
-#define F0900_P1_ERR_SOURCE2  0xf59c00f0
-#define F0900_P1_NUM_EVENT2  0xf59c0007
+#define R0900_P1_ERRCTRL2 0xf59c
+#define ERRCTRL2 REGx(R0900_P1_ERRCTRL2)
+#define F0900_P1_ERR_SOURCE2 0xf59c00f0
+#define F0900_P1_NUM_EVENT2 0xf59c0007
 
 /*P1_ERRCNT22*/
-#define R0900_P1_ERRCNT22  0xf59d
-#define F0900_P1_ERRCNT2_OLDVALUE  0xf59d0080
-#define F0900_P1_ERR_CNT22  0xf59d007f
+#define R0900_P1_ERRCNT22 0xf59d
+#define ERRCNT22 REGx(R0900_P1_ERRCNT22)
+#define F0900_P1_ERRCNT2_OLDVALUE 0xf59d0080
+#define F0900_P1_ERR_CNT22 0xf59d007f
+#define ERR_CNT22 FLDx(F0900_P1_ERR_CNT22)
 
 /*P1_ERRCNT21*/
-#define R0900_P1_ERRCNT21  0xf59e
-#define F0900_P1_ERR_CNT21  0xf59e00ff
+#define R0900_P1_ERRCNT21 0xf59e
+#define ERRCNT21 REGx(R0900_P1_ERRCNT21)
+#define F0900_P1_ERR_CNT21 0xf59e00ff
+#define ERR_CNT21 FLDx(F0900_P1_ERR_CNT21)
 
 /*P1_ERRCNT20*/
-#define R0900_P1_ERRCNT20  0xf59f
-#define F0900_P1_ERR_CNT20  0xf59f00ff
+#define R0900_P1_ERRCNT20 0xf59f
+#define ERRCNT20 REGx(R0900_P1_ERRCNT20)
+#define F0900_P1_ERR_CNT20 0xf59f00ff
+#define ERR_CNT20 FLDx(F0900_P1_ERR_CNT20)
 
 /*P1_FECSPY*/
-#define R0900_P1_FECSPY  0xf5a0
-#define F0900_P1_SPY_ENABLE  0xf5a00080
-#define F0900_P1_NO_SYNCBYTE  0xf5a00040
-#define F0900_P1_SERIAL_MODE  0xf5a00020
-#define F0900_P1_UNUSUAL_PACKET  0xf5a00010
-#define F0900_P1_BER_PACKMODE  0xf5a00008
-#define F0900_P1_BERMETER_LMODE  0xf5a00002
-#define F0900_P1_BERMETER_RESET  0xf5a00001
+#define R0900_P1_FECSPY 0xf5a0
+#define FECSPY REGx(R0900_P1_FECSPY)
+#define F0900_P1_SPY_ENABLE 0xf5a00080
+#define F0900_P1_NO_SYNCBYTE 0xf5a00040
+#define F0900_P1_SERIAL_MODE 0xf5a00020
+#define F0900_P1_UNUSUAL_PACKET 0xf5a00010
+#define F0900_P1_BERMETER_DATAMODE 0xf5a00008
+#define F0900_P1_BERMETER_LMODE 0xf5a00002
+#define F0900_P1_BERMETER_RESET 0xf5a00001
 
 /*P1_FSPYCFG*/
-#define R0900_P1_FSPYCFG  0xf5a1
-#define F0900_P1_FECSPY_INPUT  0xf5a100c0
-#define F0900_P1_RST_ON_ERROR  0xf5a10020
-#define F0900_P1_ONE_SHOT  0xf5a10010
-#define F0900_P1_I2C_MODE  0xf5a1000c
-#define F0900_P1_SPY_HYSTERESIS  0xf5a10003
+#define R0900_P1_FSPYCFG 0xf5a1
+#define FSPYCFG REGx(R0900_P1_FSPYCFG)
+#define F0900_P1_FECSPY_INPUT 0xf5a100c0
+#define F0900_P1_RST_ON_ERROR 0xf5a10020
+#define F0900_P1_ONE_SHOT 0xf5a10010
+#define F0900_P1_I2C_MODE 0xf5a1000c
+#define F0900_P1_SPY_HYSTERESIS 0xf5a10003
 
 /*P1_FSPYDATA*/
-#define R0900_P1_FSPYDATA  0xf5a2
-#define F0900_P1_SPY_STUFFING  0xf5a20080
-#define F0900_P1_NOERROR_PKTJITTER  0xf5a20040
-#define F0900_P1_SPY_CNULLPKT  0xf5a20020
-#define F0900_P1_SPY_OUTDATA_MODE  0xf5a2001f
+#define R0900_P1_FSPYDATA 0xf5a2
+#define FSPYDATA REGx(R0900_P1_FSPYDATA)
+#define F0900_P1_SPY_STUFFING 0xf5a20080
+#define F0900_P1_SPY_CNULLPKT 0xf5a20020
+#define F0900_P1_SPY_OUTDATA_MODE 0xf5a2001f
 
 /*P1_FSPYOUT*/
-#define R0900_P1_FSPYOUT  0xf5a3
-#define F0900_P1_FSPY_DIRECT  0xf5a30080
-#define F0900_P1_SPY_OUTDATA_BUS  0xf5a30038
-#define F0900_P1_STUFF_MODE  0xf5a30007
+#define R0900_P1_FSPYOUT 0xf5a3
+#define FSPYOUT REGx(R0900_P1_FSPYOUT)
+#define F0900_P1_FSPY_DIRECT 0xf5a30080
+#define F0900_P1_STUFF_MODE 0xf5a30007
 
 /*P1_FSTATUS*/
-#define R0900_P1_FSTATUS  0xf5a4
-#define F0900_P1_SPY_ENDSIM  0xf5a40080
-#define F0900_P1_VALID_SIM  0xf5a40040
-#define F0900_P1_FOUND_SIGNAL  0xf5a40020
-#define F0900_P1_DSS_SYNCBYTE  0xf5a40010
-#define F0900_P1_RESULT_STATE  0xf5a4000f
+#define R0900_P1_FSTATUS 0xf5a4
+#define FSTATUS REGx(R0900_P1_FSTATUS)
+#define F0900_P1_SPY_ENDSIM 0xf5a40080
+#define F0900_P1_VALID_SIM 0xf5a40040
+#define F0900_P1_FOUND_SIGNAL 0xf5a40020
+#define F0900_P1_DSS_SYNCBYTE 0xf5a40010
+#define F0900_P1_RESULT_STATE 0xf5a4000f
 
 /*P1_FBERCPT4*/
-#define R0900_P1_FBERCPT4  0xf5a8
-#define F0900_P1_FBERMETER_CPT4  0xf5a800ff
+#define R0900_P1_FBERCPT4 0xf5a8
+#define FBERCPT4 REGx(R0900_P1_FBERCPT4)
+#define F0900_P1_FBERMETER_CPT4 0xf5a800ff
 
 /*P1_FBERCPT3*/
-#define R0900_P1_FBERCPT3  0xf5a9
-#define F0900_P1_FBERMETER_CPT3  0xf5a900ff
+#define R0900_P1_FBERCPT3 0xf5a9
+#define FBERCPT3 REGx(R0900_P1_FBERCPT3)
+#define F0900_P1_FBERMETER_CPT3 0xf5a900ff
 
 /*P1_FBERCPT2*/
-#define R0900_P1_FBERCPT2  0xf5aa
-#define F0900_P1_FBERMETER_CPT2  0xf5aa00ff
+#define R0900_P1_FBERCPT2 0xf5aa
+#define FBERCPT2 REGx(R0900_P1_FBERCPT2)
+#define F0900_P1_FBERMETER_CPT2 0xf5aa00ff
 
 /*P1_FBERCPT1*/
-#define R0900_P1_FBERCPT1  0xf5ab
-#define F0900_P1_FBERMETER_CPT1  0xf5ab00ff
+#define R0900_P1_FBERCPT1 0xf5ab
+#define FBERCPT1 REGx(R0900_P1_FBERCPT1)
+#define F0900_P1_FBERMETER_CPT1 0xf5ab00ff
 
 /*P1_FBERCPT0*/
-#define R0900_P1_FBERCPT0  0xf5ac
-#define F0900_P1_FBERMETER_CPT0  0xf5ac00ff
+#define R0900_P1_FBERCPT0 0xf5ac
+#define FBERCPT0 REGx(R0900_P1_FBERCPT0)
+#define F0900_P1_FBERMETER_CPT0 0xf5ac00ff
 
 /*P1_FBERERR2*/
-#define R0900_P1_FBERERR2  0xf5ad
-#define F0900_P1_FBERMETER_ERR2  0xf5ad00ff
+#define R0900_P1_FBERERR2 0xf5ad
+#define FBERERR2 REGx(R0900_P1_FBERERR2)
+#define F0900_P1_FBERMETER_ERR2 0xf5ad00ff
 
 /*P1_FBERERR1*/
-#define R0900_P1_FBERERR1  0xf5ae
-#define F0900_P1_FBERMETER_ERR1  0xf5ae00ff
+#define R0900_P1_FBERERR1 0xf5ae
+#define FBERERR1 REGx(R0900_P1_FBERERR1)
+#define F0900_P1_FBERMETER_ERR1 0xf5ae00ff
 
 /*P1_FBERERR0*/
-#define R0900_P1_FBERERR0  0xf5af
-#define F0900_P1_FBERMETER_ERR0  0xf5af00ff
+#define R0900_P1_FBERERR0 0xf5af
+#define FBERERR0 REGx(R0900_P1_FBERERR0)
+#define F0900_P1_FBERMETER_ERR0 0xf5af00ff
 
 /*P1_FSPYBER*/
-#define R0900_P1_FSPYBER  0xf5b2
-#define F0900_P1_FSPYOBS_XORREAD  0xf5b20040
-#define F0900_P1_FSPYBER_OBSMODE  0xf5b20020
-#define F0900_P1_FSPYBER_SYNCBYTE  0xf5b20010
-#define F0900_P1_FSPYBER_UNSYNC  0xf5b20008
-#define F0900_P1_FSPYBER_CTIME  0xf5b20007
+#define R0900_P1_FSPYBER 0xf5b2
+#define FSPYBER REGx(R0900_P1_FSPYBER)
+#define F0900_P1_FSPYBER_SYNCBYTE 0xf5b20010
+#define F0900_P1_FSPYBER_UNSYNC 0xf5b20008
+#define F0900_P1_FSPYBER_CTIME 0xf5b20007
 
-/*RCCFGH*/
-#define R0900_RCCFGH  0xf600
-#define F0900_TSRCFIFO_DVBCI  0xf6000080
-#define F0900_TSRCFIFO_SERIAL  0xf6000040
-#define F0900_TSRCFIFO_DISABLE  0xf6000020
-#define F0900_TSFIFO_2TORC  0xf6000010
-#define F0900_TSRCFIFO_HSGNLOUT  0xf6000008
-#define F0900_TSRCFIFO_ERRMODE  0xf6000006
+/*RCCFG2*/
+#define R0900_RCCFG2 0xf600
 
 /*TSGENERAL*/
-#define R0900_TSGENERAL  0xf630
-#define F0900_TSFIFO_BCLK1ALL  0xf6300020
-#define F0900_MUXSTREAM_OUTMODE  0xf6300008
-#define F0900_TSFIFO_PERMPARAL  0xf6300006
-#define F0900_RST_REEDSOLO  0xf6300001
+#define R0900_TSGENERAL 0xf630
+#define F0900_TSFIFO_DISTS2PAR 0xf6300040
+#define F0900_MUXSTREAM_OUTMODE 0xf6300008
+#define F0900_TSFIFO_PERMPARAL 0xf6300006
 
 /*TSGENERAL1X*/
-#define R0900_TSGENERAL1X  0xf670
-#define F0900_TSFIFO1X_BCLK1ALL  0xf6700020
-#define F0900_MUXSTREAM1X_OUTMODE  0xf6700008
-#define F0900_TSFIFO1X_PERMPARAL  0xf6700006
-#define F0900_RST1X_REEDSOLO  0xf6700001
+#define R0900_TSGENERAL1X 0xf670
 
 /*NBITER_NF4*/
-#define R0900_NBITER_NF4  0xfa03
-#define F0900_NBITER_NF_QP_1_2  0xfa0300ff
+#define R0900_NBITER_NF4 0xfa03
+#define F0900_NBITER_NF_QP_1_2 0xfa0300ff
 
 /*NBITER_NF5*/
-#define R0900_NBITER_NF5  0xfa04
-#define F0900_NBITER_NF_QP_3_5  0xfa0400ff
+#define R0900_NBITER_NF5 0xfa04
+#define F0900_NBITER_NF_QP_3_5 0xfa0400ff
 
 /*NBITER_NF6*/
-#define R0900_NBITER_NF6  0xfa05
-#define F0900_NBITER_NF_QP_2_3  0xfa0500ff
+#define R0900_NBITER_NF6 0xfa05
+#define F0900_NBITER_NF_QP_2_3 0xfa0500ff
 
 /*NBITER_NF7*/
-#define R0900_NBITER_NF7  0xfa06
-#define F0900_NBITER_NF_QP_3_4  0xfa0600ff
+#define R0900_NBITER_NF7 0xfa06
+#define F0900_NBITER_NF_QP_3_4 0xfa0600ff
 
 /*NBITER_NF8*/
-#define R0900_NBITER_NF8  0xfa07
-#define F0900_NBITER_NF_QP_4_5  0xfa0700ff
+#define R0900_NBITER_NF8 0xfa07
+#define F0900_NBITER_NF_QP_4_5 0xfa0700ff
 
 /*NBITER_NF9*/
-#define R0900_NBITER_NF9  0xfa08
-#define F0900_NBITER_NF_QP_5_6  0xfa0800ff
+#define R0900_NBITER_NF9 0xfa08
+#define F0900_NBITER_NF_QP_5_6 0xfa0800ff
 
 /*NBITER_NF10*/
-#define R0900_NBITER_NF10  0xfa09
-#define F0900_NBITER_NF_QP_8_9  0xfa0900ff
+#define R0900_NBITER_NF10 0xfa09
+#define F0900_NBITER_NF_QP_8_9 0xfa0900ff
 
 /*NBITER_NF11*/
-#define R0900_NBITER_NF11  0xfa0a
-#define F0900_NBITER_NF_QP_9_10  0xfa0a00ff
+#define R0900_NBITER_NF11 0xfa0a
+#define F0900_NBITER_NF_QP_9_10 0xfa0a00ff
 
 /*NBITER_NF12*/
-#define R0900_NBITER_NF12  0xfa0b
-#define F0900_NBITER_NF_8P_3_5  0xfa0b00ff
+#define R0900_NBITER_NF12 0xfa0b
+#define F0900_NBITER_NF_8P_3_5 0xfa0b00ff
 
 /*NBITER_NF13*/
-#define R0900_NBITER_NF13  0xfa0c
-#define F0900_NBITER_NF_8P_2_3  0xfa0c00ff
+#define R0900_NBITER_NF13 0xfa0c
+#define F0900_NBITER_NF_8P_2_3 0xfa0c00ff
 
 /*NBITER_NF14*/
-#define R0900_NBITER_NF14  0xfa0d
-#define F0900_NBITER_NF_8P_3_4  0xfa0d00ff
+#define R0900_NBITER_NF14 0xfa0d
+#define F0900_NBITER_NF_8P_3_4 0xfa0d00ff
 
 /*NBITER_NF15*/
-#define R0900_NBITER_NF15  0xfa0e
-#define F0900_NBITER_NF_8P_5_6  0xfa0e00ff
+#define R0900_NBITER_NF15 0xfa0e
+#define F0900_NBITER_NF_8P_5_6 0xfa0e00ff
 
 /*NBITER_NF16*/
-#define R0900_NBITER_NF16  0xfa0f
-#define F0900_NBITER_NF_8P_8_9  0xfa0f00ff
+#define R0900_NBITER_NF16 0xfa0f
+#define F0900_NBITER_NF_8P_8_9 0xfa0f00ff
 
 /*NBITER_NF17*/
-#define R0900_NBITER_NF17  0xfa10
-#define F0900_NBITER_NF_8P_9_10  0xfa1000ff
+#define R0900_NBITER_NF17 0xfa10
+#define F0900_NBITER_NF_8P_9_10 0xfa1000ff
 
 /*NBITERNOERR*/
-#define R0900_NBITERNOERR  0xfa3f
-#define F0900_NBITER_STOP_CRIT  0xfa3f000f
+#define R0900_NBITERNOERR 0xfa3f
+#define F0900_NBITER_STOP_CRIT 0xfa3f000f
 
 /*GAINLLR_NF4*/
-#define R0900_GAINLLR_NF4  0xfa43
-#define F0900_GAINLLR_NF_QP_1_2  0xfa43007f
+#define R0900_GAINLLR_NF4 0xfa43
+#define F0900_GAINLLR_NF_QP_1_2 0xfa43007f
 
 /*GAINLLR_NF5*/
-#define R0900_GAINLLR_NF5  0xfa44
-#define F0900_GAINLLR_NF_QP_3_5  0xfa44007f
+#define R0900_GAINLLR_NF5 0xfa44
+#define F0900_GAINLLR_NF_QP_3_5 0xfa44007f
 
 /*GAINLLR_NF6*/
-#define R0900_GAINLLR_NF6  0xfa45
-#define F0900_GAINLLR_NF_QP_2_3  0xfa45007f
+#define R0900_GAINLLR_NF6 0xfa45
+#define F0900_GAINLLR_NF_QP_2_3 0xfa45007f
 
 /*GAINLLR_NF7*/
-#define R0900_GAINLLR_NF7  0xfa46
-#define F0900_GAINLLR_NF_QP_3_4  0xfa46007f
+#define R0900_GAINLLR_NF7 0xfa46
+#define F0900_GAINLLR_NF_QP_3_4 0xfa46007f
 
 /*GAINLLR_NF8*/
-#define R0900_GAINLLR_NF8  0xfa47
-#define F0900_GAINLLR_NF_QP_4_5  0xfa47007f
+#define R0900_GAINLLR_NF8 0xfa47
+#define F0900_GAINLLR_NF_QP_4_5 0xfa47007f
 
 /*GAINLLR_NF9*/
-#define R0900_GAINLLR_NF9  0xfa48
-#define F0900_GAINLLR_NF_QP_5_6  0xfa48007f
+#define R0900_GAINLLR_NF9 0xfa48
+#define F0900_GAINLLR_NF_QP_5_6 0xfa48007f
 
 /*GAINLLR_NF10*/
-#define R0900_GAINLLR_NF10  0xfa49
-#define F0900_GAINLLR_NF_QP_8_9  0xfa49007f
+#define R0900_GAINLLR_NF10 0xfa49
+#define F0900_GAINLLR_NF_QP_8_9 0xfa49007f
 
 /*GAINLLR_NF11*/
-#define R0900_GAINLLR_NF11  0xfa4a
-#define F0900_GAINLLR_NF_QP_9_10  0xfa4a007f
+#define R0900_GAINLLR_NF11 0xfa4a
+#define F0900_GAINLLR_NF_QP_9_10 0xfa4a007f
 
 /*GAINLLR_NF12*/
-#define R0900_GAINLLR_NF12  0xfa4b
-#define F0900_GAINLLR_NF_8P_3_5  0xfa4b007f
+#define R0900_GAINLLR_NF12 0xfa4b
+#define F0900_GAINLLR_NF_8P_3_5 0xfa4b007f
 
 /*GAINLLR_NF13*/
-#define R0900_GAINLLR_NF13  0xfa4c
-#define F0900_GAINLLR_NF_8P_2_3  0xfa4c007f
+#define R0900_GAINLLR_NF13 0xfa4c
+#define F0900_GAINLLR_NF_8P_2_3 0xfa4c007f
 
 /*GAINLLR_NF14*/
-#define R0900_GAINLLR_NF14  0xfa4d
-#define F0900_GAINLLR_NF_8P_3_4  0xfa4d007f
+#define R0900_GAINLLR_NF14 0xfa4d
+#define F0900_GAINLLR_NF_8P_3_4 0xfa4d007f
 
 /*GAINLLR_NF15*/
-#define R0900_GAINLLR_NF15  0xfa4e
-#define F0900_GAINLLR_NF_8P_5_6  0xfa4e007f
+#define R0900_GAINLLR_NF15 0xfa4e
+#define F0900_GAINLLR_NF_8P_5_6 0xfa4e007f
 
 /*GAINLLR_NF16*/
-#define R0900_GAINLLR_NF16  0xfa4f
-#define F0900_GAINLLR_NF_8P_8_9  0xfa4f007f
+#define R0900_GAINLLR_NF16 0xfa4f
+#define F0900_GAINLLR_NF_8P_8_9 0xfa4f007f
 
 /*GAINLLR_NF17*/
-#define R0900_GAINLLR_NF17  0xfa50
-#define F0900_GAINLLR_NF_8P_9_10  0xfa50007f
+#define R0900_GAINLLR_NF17 0xfa50
+#define F0900_GAINLLR_NF_8P_9_10 0xfa50007f
 
 /*CFGEXT*/
-#define R0900_CFGEXT  0xfa80
-#define F0900_STAGMODE  0xfa800080
-#define F0900_BYPBCH  0xfa800040
-#define F0900_BYPLDPC  0xfa800020
-#define F0900_LDPCMODE  0xfa800010
-#define F0900_INVLLRSIGN  0xfa800008
-#define F0900_SHORTMULT  0xfa800004
-#define F0900_EXTERNTX  0xfa800001
+#define R0900_CFGEXT 0xfa80
+#define F0900_STAGMODE 0xfa800080
+#define F0900_BYPBCH 0xfa800040
+#define F0900_BYPLDPC 0xfa800020
+#define F0900_LDPCMODE 0xfa800010
+#define F0900_INVLLRSIGN 0xfa800008
+#define F0900_SHORTMULT 0xfa800004
+#define F0900_EXTERNTX 0xfa800001
 
 /*GENCFG*/
-#define R0900_GENCFG  0xfa86
-#define F0900_BROADCAST  0xfa860010
-#define F0900_NOSHFRD2  0xfa860008
-#define F0900_BCHERRFLAG  0xfa860004
-#define F0900_PRIORITY  0xfa860002
-#define F0900_DDEMOD  0xfa860001
+#define R0900_GENCFG 0xfa86
+#define F0900_BROADCAST 0xfa860010
+#define F0900_PRIORITY 0xfa860002
+#define F0900_DDEMOD 0xfa860001
 
 /*LDPCERR1*/
-#define R0900_LDPCERR1  0xfa96
-#define F0900_LDPC_ERRORS_COUNTER1  0xfa9600ff
+#define R0900_LDPCERR1 0xfa96
+#define F0900_LDPC_ERRORS_COUNTER1 0xfa9600ff
 
 /*LDPCERR0*/
-#define R0900_LDPCERR0  0xfa97
-#define F0900_LDPC_ERRORS_COUNTER0  0xfa9700ff
+#define R0900_LDPCERR0 0xfa97
+#define F0900_LDPC_ERRORS_COUNTER0 0xfa9700ff
 
 /*BCHERR*/
-#define R0900_BCHERR  0xfa98
-#define F0900_ERRORFLAG  0xfa980010
-#define F0900_BCH_ERRORS_COUNTER  0xfa98000f
+#define R0900_BCHERR 0xfa98
+#define F0900_ERRORFLAG 0xfa980010
+#define F0900_BCH_ERRORS_COUNTER 0xfa98000f
 
 /*TSTRES0*/
-#define R0900_TSTRES0  0xff11
-#define F0900_FRESFEC  0xff110080
-#define F0900_FRESTS  0xff110040
-#define F0900_FRESVIT1  0xff110020
-#define F0900_FRESVIT2  0xff110010
-#define F0900_FRESSYM1  0xff110008
-#define F0900_FRESSYM2  0xff110004
-#define F0900_FRESMAS  0xff110002
-#define F0900_FRESINT  0xff110001
+#define R0900_TSTRES0 0xff11
+#define F0900_FRESFEC 0xff110080
+
+/*P2_TCTL4*/
+#define R0900_P2_TCTL4 0xff28
+#define F0900_P2_PN4_SELECT 0xff280020
+
+/*P1_TCTL4*/
+#define R0900_P1_TCTL4 0xff48
+#define TCTL4 shiftx(R0900_P1_TCTL4, demod, 0x20)
+#define F0900_P1_PN4_SELECT 0xff480020
 
 /*P2_TSTDISRX*/
-#define R0900_P2_TSTDISRX  0xff65
-#define F0900_P2_EN_DISRX  0xff650080
-#define F0900_P2_TST_CURRSRC  0xff650040
-#define F0900_P2_IN_DIGSIGNAL  0xff650020
-#define F0900_P2_HIZ_CURRENTSRC  0xff650010
-#define F0900_TST_P2_PIN_SELECT  0xff650008
-#define F0900_P2_TST_DISRX  0xff650007
+#define R0900_P2_TSTDISRX 0xff65
+#define F0900_P2_PIN_SELECT1 0xff650008
 
 /*P1_TSTDISRX*/
-#define R0900_P1_TSTDISRX  0xff67
-#define F0900_P1_EN_DISRX  0xff670080
-#define F0900_P1_TST_CURRSRC  0xff670040
-#define F0900_P1_IN_DIGSIGNAL  0xff670020
-#define F0900_P1_HIZ_CURRENTSRC  0xff670010
-#define F0900_TST_P1_PIN_SELECT  0xff670008
-#define F0900_P1_TST_DISRX  0xff670007
+#define R0900_P1_TSTDISRX 0xff67
+#define TSTDISRX shiftx(R0900_P1_TSTDISRX, demod, 2)
+#define F0900_P1_PIN_SELECT1 0xff670008
+#define PIN_SELECT1 shiftx(F0900_P1_PIN_SELECT1, demod, 0x20000)
 
-#define STV0900_NBREGS		684
-#define STV0900_NBFIELDS		1702
+#define STV0900_NBREGS 723
+#define STV0900_NBFIELDS 1420
 
 #endif
 
diff --git a/drivers/media/dvb/frontends/stv0900_sw.c b/drivers/media/dvb/frontends/stv0900_sw.c
index 962fde1..b8da87f 100644
--- a/drivers/media/dvb/frontends/stv0900_sw.c
+++ b/drivers/media/dvb/frontends/stv0900_sw.c
@@ -27,56 +27,45 @@
 #include "stv0900_reg.h"
 #include "stv0900_priv.h"
 
-int stv0900_check_signal_presence(struct stv0900_internal *i_params,
+s32 shiftx(s32 x, int demod, s32 shift)
+{
+	if (demod == 1)
+		return x - shift;
+
+	return x;
+}
+
+int stv0900_check_signal_presence(struct stv0900_internal *intp,
 					enum fe_stv0900_demod_num demod)
 {
-	s32 carr_offset,
-	agc2_integr,
-	max_carrier;
+	s32	carr_offset,
+		agc2_integr,
+		max_carrier;
 
-	int no_signal;
+	int no_signal = FALSE;
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		carr_offset = (stv0900_read_reg(i_params, R0900_P1_CFR2) << 8)
-						| stv0900_read_reg(i_params,
-						R0900_P1_CFR1);
-		carr_offset = ge2comp(carr_offset, 16);
-		agc2_integr = (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8)
-						| stv0900_read_reg(i_params,
-						R0900_P1_AGC2I0);
-		max_carrier = i_params->dmd1_srch_range / 1000;
-		break;
-	case STV0900_DEMOD_2:
-		carr_offset = (stv0900_read_reg(i_params, R0900_P2_CFR2) << 8)
-						| stv0900_read_reg(i_params,
-						R0900_P2_CFR1);
-		carr_offset = ge2comp(carr_offset, 16);
-		agc2_integr = (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8)
-						| stv0900_read_reg(i_params,
-						R0900_P2_AGC2I0);
-		max_carrier = i_params->dmd2_srch_range / 1000;
-		break;
-	}
+	carr_offset = (stv0900_read_reg(intp, CFR2) << 8)
+					| stv0900_read_reg(intp, CFR1);
+	carr_offset = ge2comp(carr_offset, 16);
+	agc2_integr = (stv0900_read_reg(intp, AGC2I1) << 8)
+					| stv0900_read_reg(intp, AGC2I0);
+	max_carrier = intp->srch_range[demod] / 1000;
 
 	max_carrier += (max_carrier / 10);
 	max_carrier = 65536 * (max_carrier / 2);
-	max_carrier /= i_params->mclk / 1000;
+	max_carrier /= intp->mclk / 1000;
 	if (max_carrier > 0x4000)
 		max_carrier = 0x4000;
 
 	if ((agc2_integr > 0x2000)
-			|| (carr_offset > + 2*max_carrier)
-			|| (carr_offset < -2*max_carrier))
+			|| (carr_offset > (2 * max_carrier))
+			|| (carr_offset < (-2 * max_carrier)))
 		no_signal = TRUE;
-	else
-		no_signal = FALSE;
 
 	return no_signal;
 }
 
-static void stv0900_get_sw_loop_params(struct stv0900_internal *i_params,
+static void stv0900_get_sw_loop_params(struct stv0900_internal *intp,
 				s32 *frequency_inc, s32 *sw_timeout,
 				s32 *steps,
 				enum fe_stv0900_demod_num demod)
@@ -85,30 +74,19 @@
 
 	enum fe_stv0900_search_standard	standard;
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		srate = i_params->dmd1_symbol_rate;
-		max_carrier = i_params->dmd1_srch_range / 1000;
-		max_carrier += max_carrier / 10;
-		standard = i_params->dmd1_srch_standard;
-		break;
-	case STV0900_DEMOD_2:
-		srate = i_params->dmd2_symbol_rate;
-		max_carrier = i_params->dmd2_srch_range / 1000;
-		max_carrier += max_carrier / 10;
-		standard = i_params->dmd2_srch_stndrd;
-		break;
-	}
+	srate = intp->symbol_rate[demod];
+	max_carrier = intp->srch_range[demod] / 1000;
+	max_carrier += max_carrier / 10;
+	standard = intp->srch_standard[demod];
 
 	max_carrier = 65536 * (max_carrier / 2);
-	max_carrier /= i_params->mclk / 1000;
+	max_carrier /= intp->mclk / 1000;
 
 	if (max_carrier > 0x4000)
 		max_carrier = 0x4000;
 
 	freq_inc = srate;
-	freq_inc /= i_params->mclk >> 10;
+	freq_inc /= intp->mclk >> 10;
 	freq_inc = freq_inc << 6;
 
 	switch (standard) {
@@ -154,7 +132,7 @@
 
 }
 
-static int stv0900_search_carr_sw_loop(struct stv0900_internal *i_params,
+static int stv0900_search_carr_sw_loop(struct stv0900_internal *intp,
 				s32 FreqIncr, s32 Timeout, int zigzag,
 				s32 MaxStep, enum fe_stv0900_demod_num demod)
 {
@@ -164,20 +142,11 @@
 		freqOffset,
 		max_carrier;
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		max_carrier = i_params->dmd1_srch_range / 1000;
-		max_carrier += (max_carrier / 10);
-		break;
-	case STV0900_DEMOD_2:
-		max_carrier = i_params->dmd2_srch_range / 1000;
-		max_carrier += (max_carrier / 10);
-		break;
-	}
+	max_carrier = intp->srch_range[demod] / 1000;
+	max_carrier += (max_carrier / 10);
 
 	max_carrier = 65536 * (max_carrier / 2);
-	max_carrier /= i_params->mclk / 1000;
+	max_carrier /= intp->mclk / 1000;
 
 	if (max_carrier > 0x4000)
 		max_carrier = 0x4000;
@@ -190,40 +159,15 @@
 	stepCpt = 0;
 
 	do {
-		switch (demod) {
-		case STV0900_DEMOD_1:
-		default:
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C);
-			stv0900_write_reg(i_params, R0900_P1_CFRINIT1,
-					(freqOffset / 256) & 0xFF);
-			stv0900_write_reg(i_params, R0900_P1_CFRINIT0,
-					 freqOffset & 0xFF);
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
-			stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 1);
+		stv0900_write_reg(intp, DMDISTATE, 0x1c);
+		stv0900_write_reg(intp, CFRINIT1, (freqOffset / 256) & 0xff);
+		stv0900_write_reg(intp, CFRINIT0, freqOffset & 0xff);
+		stv0900_write_reg(intp, DMDISTATE, 0x18);
+		stv0900_write_bits(intp, ALGOSWRST, 1);
 
-			if (i_params->chip_id == 0x12) {
-				stv0900_write_bits(i_params,
-						F0900_P1_RST_HWARE, 1);
-				stv0900_write_bits(i_params,
-						F0900_P1_RST_HWARE, 0);
-			}
-			break;
-		case STV0900_DEMOD_2:
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C);
-			stv0900_write_reg(i_params, R0900_P2_CFRINIT1,
-					(freqOffset / 256) & 0xFF);
-			stv0900_write_reg(i_params, R0900_P2_CFRINIT0,
-					freqOffset & 0xFF);
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
-			stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 1);
-
-			if (i_params->chip_id == 0x12) {
-				stv0900_write_bits(i_params,
-						F0900_P2_RST_HWARE, 1);
-				stv0900_write_bits(i_params,
-						F0900_P2_RST_HWARE, 0);
-			}
-			break;
+		if (intp->chip_id == 0x12) {
+			stv0900_write_bits(intp, RST_HWARE, 1);
+			stv0900_write_bits(intp, RST_HWARE, 0);
 		}
 
 		if (zigzag == TRUE) {
@@ -235,8 +179,8 @@
 			freqOffset += + 2 * FreqIncr;
 
 		stepCpt++;
-		lock = stv0900_get_demod_lock(i_params, demod, Timeout);
-		no_signal = stv0900_check_signal_presence(i_params, demod);
+		lock = stv0900_get_demod_lock(intp, demod, Timeout);
+		no_signal = stv0900_check_signal_presence(intp, demod);
 
 	} while ((lock == FALSE)
 			&& (no_signal == FALSE)
@@ -244,269 +188,138 @@
 			&& ((freqOffset + FreqIncr) > -max_carrier)
 			&& (stepCpt < MaxStep));
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 0);
-		break;
-	case STV0900_DEMOD_2:
-		stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 0);
-		break;
-	}
+	stv0900_write_bits(intp, ALGOSWRST, 0);
 
 	return lock;
 }
 
-int stv0900_sw_algo(struct stv0900_internal *i_params,
+int stv0900_sw_algo(struct stv0900_internal *intp,
 				enum fe_stv0900_demod_num demod)
 {
-	int lock = FALSE;
+	int	lock = FALSE,
+		no_signal,
+		zigzag;
+	s32	s2fw,
+		fqc_inc,
+		sft_stp_tout,
+		trial_cntr,
+		max_steps;
 
-	int no_signal,
-	zigzag;
-	s32 dvbs2_fly_wheel;
-
-	s32 freqIncrement, softStepTimeout, trialCounter, max_steps;
-
-	stv0900_get_sw_loop_params(i_params, &freqIncrement, &softStepTimeout,
+	stv0900_get_sw_loop_params(intp, &fqc_inc, &sft_stp_tout,
 					&max_steps, demod);
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		switch (i_params->dmd1_srch_standard) {
-		case STV0900_SEARCH_DVBS1:
-		case STV0900_SEARCH_DSS:
-			if (i_params->chip_id >= 0x20)
-				stv0900_write_reg(i_params, R0900_P1_CARFREQ,
-						0x3B);
-			else
-				stv0900_write_reg(i_params, R0900_P1_CARFREQ,
-						0xef);
+	switch (intp->srch_standard[demod]) {
+	case STV0900_SEARCH_DVBS1:
+	case STV0900_SEARCH_DSS:
+		if (intp->chip_id >= 0x20)
+			stv0900_write_reg(intp, CARFREQ, 0x3b);
+		else
+			stv0900_write_reg(intp, CARFREQ, 0xef);
 
-			stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, 0x49);
-			zigzag = FALSE;
-			break;
-		case STV0900_SEARCH_DVBS2:
-			if (i_params->chip_id >= 0x20)
-				stv0900_write_reg(i_params, R0900_P1_CORRELABS,
-						0x79);
-			else
-				stv0900_write_reg(i_params, R0900_P1_CORRELABS,
-						0x68);
-
-			stv0900_write_reg(i_params, R0900_P1_DMDCFGMD,
-						0x89);
-
-			zigzag = TRUE;
-			break;
-		case STV0900_AUTO_SEARCH:
-		default:
-			if (i_params->chip_id >= 0x20) {
-				stv0900_write_reg(i_params, R0900_P1_CARFREQ,
-							0x3B);
-				stv0900_write_reg(i_params, R0900_P1_CORRELABS,
-							0x79);
-			} else {
-				stv0900_write_reg(i_params, R0900_P1_CARFREQ,
-							0xef);
-				stv0900_write_reg(i_params, R0900_P1_CORRELABS,
-							0x68);
-			}
-
-			stv0900_write_reg(i_params, R0900_P1_DMDCFGMD,
-							0xc9);
-			zigzag = FALSE;
-			break;
-		}
-
-		trialCounter = 0;
-		do {
-			lock = stv0900_search_carr_sw_loop(i_params,
-							freqIncrement,
-							softStepTimeout,
-							zigzag,
-							max_steps,
-							demod);
-			no_signal = stv0900_check_signal_presence(i_params,
-								demod);
-			trialCounter++;
-			if ((lock == TRUE)
-					|| (no_signal == TRUE)
-					|| (trialCounter == 2)) {
-
-				if (i_params->chip_id >= 0x20) {
-					stv0900_write_reg(i_params,
-							R0900_P1_CARFREQ,
-							0x49);
-					stv0900_write_reg(i_params,
-							R0900_P1_CORRELABS,
-							0x9e);
-				} else {
-					stv0900_write_reg(i_params,
-							R0900_P1_CARFREQ,
-							0xed);
-					stv0900_write_reg(i_params,
-							R0900_P1_CORRELABS,
-							0x88);
-				}
-
-				if ((lock == TRUE) && (stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS2_FOUND)) {
-					msleep(softStepTimeout);
-					dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P1_FLYWHEEL_CPT);
-
-					if (dvbs2_fly_wheel < 0xd) {
-						msleep(softStepTimeout);
-						dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P1_FLYWHEEL_CPT);
-					}
-
-					if (dvbs2_fly_wheel < 0xd) {
-						lock = FALSE;
-
-						if (trialCounter < 2) {
-							if (i_params->chip_id >= 0x20)
-								stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x79);
-							else
-								stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x68);
-
-							stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, 0x89);
-						}
-					}
-				}
-			}
-
-		} while ((lock == FALSE)
-			&& (trialCounter < 2)
-			&& (no_signal == FALSE));
-
+		stv0900_write_reg(intp, DMDCFGMD, 0x49);
+		zigzag = FALSE;
 		break;
-	case STV0900_DEMOD_2:
-		switch (i_params->dmd2_srch_stndrd) {
-		case STV0900_SEARCH_DVBS1:
-		case STV0900_SEARCH_DSS:
-			if (i_params->chip_id >= 0x20)
-				stv0900_write_reg(i_params, R0900_P2_CARFREQ,
-						0x3b);
-			else
-				stv0900_write_reg(i_params, R0900_P2_CARFREQ,
-						0xef);
+	case STV0900_SEARCH_DVBS2:
+		if (intp->chip_id >= 0x20)
+			stv0900_write_reg(intp, CORRELABS, 0x79);
+		else
+			stv0900_write_reg(intp, CORRELABS, 0x68);
 
-			stv0900_write_reg(i_params, R0900_P2_DMDCFGMD,
-						0x49);
-			zigzag = FALSE;
-			break;
-		case STV0900_SEARCH_DVBS2:
-			if (i_params->chip_id >= 0x20)
-				stv0900_write_reg(i_params, R0900_P2_CORRELABS,
-						0x79);
-			else
-				stv0900_write_reg(i_params, R0900_P2_CORRELABS,
-						0x68);
+		stv0900_write_reg(intp, DMDCFGMD, 0x89);
 
-			stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0x89);
-			zigzag = TRUE;
-			break;
-		case STV0900_AUTO_SEARCH:
-		default:
-			if (i_params->chip_id >= 0x20) {
-				stv0900_write_reg(i_params, R0900_P2_CARFREQ,
-						0x3b);
-				stv0900_write_reg(i_params, R0900_P2_CORRELABS,
-						0x79);
-			} else {
-				stv0900_write_reg(i_params, R0900_P2_CARFREQ,
-						0xef);
-				stv0900_write_reg(i_params, R0900_P2_CORRELABS,
-						0x68);
-			}
-
-			stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0xc9);
-
-			zigzag = FALSE;
-			break;
+		zigzag = TRUE;
+		break;
+	case STV0900_AUTO_SEARCH:
+	default:
+		if (intp->chip_id >= 0x20) {
+			stv0900_write_reg(intp, CARFREQ, 0x3b);
+			stv0900_write_reg(intp, CORRELABS, 0x79);
+		} else {
+			stv0900_write_reg(intp, CARFREQ, 0xef);
+			stv0900_write_reg(intp, CORRELABS, 0x68);
 		}
 
-		trialCounter = 0;
-
-		do {
-			lock = stv0900_search_carr_sw_loop(i_params,
-							freqIncrement,
-							softStepTimeout,
-							zigzag,
-							max_steps,
-							demod);
-			no_signal = stv0900_check_signal_presence(i_params,
-								demod);
-			trialCounter++;
-			if ((lock == TRUE)
-					|| (no_signal == TRUE)
-					|| (trialCounter == 2)) {
-				if (i_params->chip_id >= 0x20) {
-					stv0900_write_reg(i_params,
-							R0900_P2_CARFREQ,
-							0x49);
-					stv0900_write_reg(i_params,
-							R0900_P2_CORRELABS,
-							0x9e);
-				} else {
-					stv0900_write_reg(i_params,
-							R0900_P2_CARFREQ,
-							0xed);
-					stv0900_write_reg(i_params,
-							R0900_P2_CORRELABS,
-							0x88);
-				}
-
-				if ((lock == TRUE) && (stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS2_FOUND)) {
-					msleep(softStepTimeout);
-					dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P2_FLYWHEEL_CPT);
-					if (dvbs2_fly_wheel < 0xd) {
-						msleep(softStepTimeout);
-						dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P2_FLYWHEEL_CPT);
-					}
-
-					if (dvbs2_fly_wheel < 0xd) {
-						lock = FALSE;
-						if (trialCounter < 2) {
-							if (i_params->chip_id >= 0x20)
-								stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x79);
-							else
-								stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x68);
-
-							stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0x89);
-						}
-					}
-				}
-			}
-
-		} while ((lock == FALSE) && (trialCounter < 2) && (no_signal == FALSE));
-
+		stv0900_write_reg(intp, DMDCFGMD, 0xc9);
+		zigzag = FALSE;
 		break;
 	}
 
+	trial_cntr = 0;
+	do {
+		lock = stv0900_search_carr_sw_loop(intp,
+						fqc_inc,
+						sft_stp_tout,
+						zigzag,
+						max_steps,
+						demod);
+		no_signal = stv0900_check_signal_presence(intp, demod);
+		trial_cntr++;
+		if ((lock == TRUE)
+				|| (no_signal == TRUE)
+				|| (trial_cntr == 2)) {
+
+			if (intp->chip_id >= 0x20) {
+				stv0900_write_reg(intp, CARFREQ, 0x49);
+				stv0900_write_reg(intp, CORRELABS, 0x9e);
+			} else {
+				stv0900_write_reg(intp, CARFREQ, 0xed);
+				stv0900_write_reg(intp, CORRELABS, 0x88);
+			}
+
+			if ((stv0900_get_bits(intp, HEADER_MODE) ==
+						STV0900_DVBS2_FOUND) &&
+							(lock == TRUE)) {
+				msleep(sft_stp_tout);
+				s2fw = stv0900_get_bits(intp, FLYWHEEL_CPT);
+
+				if (s2fw < 0xd) {
+					msleep(sft_stp_tout);
+					s2fw = stv0900_get_bits(intp,
+								FLYWHEEL_CPT);
+				}
+
+				if (s2fw < 0xd) {
+					lock = FALSE;
+
+					if (trial_cntr < 2) {
+						if (intp->chip_id >= 0x20)
+							stv0900_write_reg(intp,
+								CORRELABS,
+								0x79);
+						else
+							stv0900_write_reg(intp,
+								CORRELABS,
+								0x68);
+
+						stv0900_write_reg(intp,
+								DMDCFGMD,
+								0x89);
+					}
+				}
+			}
+		}
+
+	} while ((lock == FALSE)
+		&& (trial_cntr < 2)
+		&& (no_signal == FALSE));
+
 	return lock;
 }
 
-static u32 stv0900_get_symbol_rate(struct stv0900_internal *i_params,
+static u32 stv0900_get_symbol_rate(struct stv0900_internal *intp,
 					u32 mclk,
 					enum fe_stv0900_demod_num demod)
 {
-	s32 sfr_field3, sfr_field2, sfr_field1, sfr_field0,
-	rem1, rem2, intval1, intval2, srate;
+	s32	rem1, rem2, intval1, intval2, srate;
 
-	dmd_reg(sfr_field3, F0900_P1_SYMB_FREQ3, F0900_P2_SYMB_FREQ3);
-	dmd_reg(sfr_field2, F0900_P1_SYMB_FREQ2, F0900_P2_SYMB_FREQ2);
-	dmd_reg(sfr_field1, F0900_P1_SYMB_FREQ1, F0900_P2_SYMB_FREQ1);
-	dmd_reg(sfr_field0, F0900_P1_SYMB_FREQ0, F0900_P2_SYMB_FREQ0);
-
-	srate = (stv0900_get_bits(i_params, sfr_field3) << 24) +
-		(stv0900_get_bits(i_params, sfr_field2) << 16) +
-		(stv0900_get_bits(i_params, sfr_field1) << 8) +
-		(stv0900_get_bits(i_params, sfr_field0));
+	srate = (stv0900_get_bits(intp, SYMB_FREQ3) << 24) +
+		(stv0900_get_bits(intp, SYMB_FREQ2) << 16) +
+		(stv0900_get_bits(intp, SYMB_FREQ1) << 8) +
+		(stv0900_get_bits(intp, SYMB_FREQ0));
 	dprintk("lock: srate=%d r0=0x%x r1=0x%x r2=0x%x r3=0x%x \n",
-		srate, stv0900_get_bits(i_params, sfr_field0),
-		stv0900_get_bits(i_params, sfr_field1),
-		stv0900_get_bits(i_params, sfr_field2),
-		stv0900_get_bits(i_params, sfr_field3));
+		srate, stv0900_get_bits(intp, SYMB_FREQ0),
+		stv0900_get_bits(intp, SYMB_FREQ1),
+		stv0900_get_bits(intp, SYMB_FREQ2),
+		stv0900_get_bits(intp, SYMB_FREQ3));
 
 	intval1 = (mclk) >> 16;
 	intval2 = (srate) >> 16;
@@ -520,18 +333,15 @@
 	return srate;
 }
 
-static void stv0900_set_symbol_rate(struct stv0900_internal *i_params,
+static void stv0900_set_symbol_rate(struct stv0900_internal *intp,
 					u32 mclk, u32 srate,
 					enum fe_stv0900_demod_num demod)
 {
-	s32 sfr_init_reg;
 	u32 symb;
 
-	dprintk(KERN_INFO "%s: Mclk %d, SR %d, Dmd %d\n", __func__, mclk,
+	dprintk("%s: Mclk %d, SR %d, Dmd %d\n", __func__, mclk,
 							srate, demod);
 
-	dmd_reg(sfr_init_reg, R0900_P1_SFRINIT1, R0900_P2_SFRINIT1);
-
 	if (srate > 60000000) {
 		symb = srate << 4;
 		symb /= (mclk >> 12);
@@ -543,19 +353,16 @@
 		symb /= (mclk >> 7);
 	}
 
-	stv0900_write_reg(i_params, sfr_init_reg, (symb >> 8) & 0x7F);
-	stv0900_write_reg(i_params, sfr_init_reg + 1, (symb & 0xFF));
+	stv0900_write_reg(intp, SFRINIT1, (symb >> 8) & 0x7f);
+	stv0900_write_reg(intp, SFRINIT1 + 1, (symb & 0xff));
 }
 
-static void stv0900_set_max_symbol_rate(struct stv0900_internal *i_params,
+static void stv0900_set_max_symbol_rate(struct stv0900_internal *intp,
 					u32 mclk, u32 srate,
 					enum fe_stv0900_demod_num demod)
 {
-	s32 sfr_max_reg;
 	u32 symb;
 
-	dmd_reg(sfr_max_reg, R0900_P1_SFRUP1, R0900_P2_SFRUP1);
-
 	srate = 105 * (srate / 100);
 
 	if (srate > 60000000) {
@@ -570,23 +377,20 @@
 	}
 
 	if (symb < 0x7fff) {
-		stv0900_write_reg(i_params, sfr_max_reg, (symb >> 8) & 0x7F);
-		stv0900_write_reg(i_params, sfr_max_reg + 1, (symb & 0xFF));
+		stv0900_write_reg(intp, SFRUP1, (symb >> 8) & 0x7f);
+		stv0900_write_reg(intp, SFRUP1 + 1, (symb & 0xff));
 	} else {
-		stv0900_write_reg(i_params, sfr_max_reg, 0x7F);
-		stv0900_write_reg(i_params, sfr_max_reg + 1, 0xFF);
+		stv0900_write_reg(intp, SFRUP1, 0x7f);
+		stv0900_write_reg(intp, SFRUP1 + 1, 0xff);
 	}
 }
 
-static void stv0900_set_min_symbol_rate(struct stv0900_internal *i_params,
+static void stv0900_set_min_symbol_rate(struct stv0900_internal *intp,
 					u32 mclk, u32 srate,
 					enum fe_stv0900_demod_num demod)
 {
-	s32 sfr_min_reg;
 	u32	symb;
 
-	dmd_reg(sfr_min_reg, R0900_P1_SFRLOW1, R0900_P2_SFRLOW1);
-
 	srate = 95 * (srate / 100);
 	if (srate > 60000000) {
 		symb = srate << 4;
@@ -601,22 +405,20 @@
 		symb /= (mclk >> 7);
 	}
 
-	stv0900_write_reg(i_params, sfr_min_reg, (symb >> 8) & 0xFF);
-	stv0900_write_reg(i_params, sfr_min_reg + 1, (symb & 0xFF));
+	stv0900_write_reg(intp, SFRLOW1, (symb >> 8) & 0xff);
+	stv0900_write_reg(intp, SFRLOW1 + 1, (symb & 0xff));
 }
 
-static s32 stv0900_get_timing_offst(struct stv0900_internal *i_params,
+static s32 stv0900_get_timing_offst(struct stv0900_internal *intp,
 					u32 srate,
 					enum fe_stv0900_demod_num demod)
 {
-	s32 tmgreg,
-	timingoffset;
+	s32 timingoffset;
 
-	dmd_reg(tmgreg, R0900_P1_TMGREG2, R0900_P2_TMGREG2);
 
-	timingoffset = (stv0900_read_reg(i_params, tmgreg) << 16) +
-		       (stv0900_read_reg(i_params, tmgreg + 1) << 8) +
-		       (stv0900_read_reg(i_params, tmgreg + 2));
+	timingoffset = (stv0900_read_reg(intp, TMGREG2) << 16) +
+		       (stv0900_read_reg(intp, TMGREG2 + 1) << 8) +
+		       (stv0900_read_reg(intp, TMGREG2 + 2));
 
 	timingoffset = ge2comp(timingoffset, 24);
 
@@ -630,22 +432,19 @@
 	return timingoffset;
 }
 
-static void stv0900_set_dvbs2_rolloff(struct stv0900_internal *i_params,
+static void stv0900_set_dvbs2_rolloff(struct stv0900_internal *intp,
 					enum fe_stv0900_demod_num demod)
 {
-	s32 rolloff, man_fld, matstr_reg, rolloff_ctl_fld;
+	s32 rolloff;
 
-	dmd_reg(man_fld, F0900_P1_MANUAL_ROLLOFF, F0900_P2_MANUAL_ROLLOFF);
-	dmd_reg(matstr_reg, R0900_P1_MATSTR1, R0900_P2_MATSTR1);
-	dmd_reg(rolloff_ctl_fld, F0900_P1_ROLLOFF_CONTROL,
-				F0900_P2_ROLLOFF_CONTROL);
-
-	if (i_params->chip_id == 0x10) {
-		stv0900_write_bits(i_params, man_fld, 1);
-		rolloff = stv0900_read_reg(i_params, matstr_reg) & 0x03;
-		stv0900_write_bits(i_params, rolloff_ctl_fld, rolloff);
-	} else
-		stv0900_write_bits(i_params, man_fld, 0);
+	if (intp->chip_id == 0x10) {
+		stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
+		rolloff = stv0900_read_reg(intp, MATSTR1) & 0x03;
+		stv0900_write_bits(intp, ROLLOFF_CONTROL, rolloff);
+	} else if (intp->chip_id <= 0x20)
+		stv0900_write_bits(intp, MANUALSX_ROLLOFF, 0);
+	else /* cut 3.0 */
+		stv0900_write_bits(intp, MANUALS2_ROLLOFF, 0);
 }
 
 static u32 stv0900_carrier_width(u32 srate, enum fe_stv0900_rolloff ro)
@@ -668,85 +467,48 @@
 	return srate  + (srate * rolloff) / 100;
 }
 
-static int stv0900_check_timing_lock(struct stv0900_internal *i_params,
+static int stv0900_check_timing_lock(struct stv0900_internal *intp,
 				enum fe_stv0900_demod_num demod)
 {
 	int timingLock = FALSE;
-	s32 i,
-	timingcpt = 0;
-	u8 carFreq,
-	tmgTHhigh,
-	tmgTHLow;
+	s32	i,
+		timingcpt = 0;
+	u8	car_freq,
+		tmg_th_high,
+		tmg_th_low;
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		carFreq = stv0900_read_reg(i_params, R0900_P1_CARFREQ);
-		tmgTHhigh = stv0900_read_reg(i_params, R0900_P1_TMGTHRISE);
-		tmgTHLow = stv0900_read_reg(i_params, R0900_P1_TMGTHFALL);
-		stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0x20);
-		stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0x0);
-		stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
-		stv0900_write_reg(i_params, R0900_P1_RTC, 0x80);
-		stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x40);
-		stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x0);
-		stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0x0);
-		stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0x0);
-		stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x65);
-		stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
-		msleep(7);
+	car_freq = stv0900_read_reg(intp, CARFREQ);
+	tmg_th_high = stv0900_read_reg(intp, TMGTHRISE);
+	tmg_th_low = stv0900_read_reg(intp, TMGTHFALL);
+	stv0900_write_reg(intp, TMGTHRISE, 0x20);
+	stv0900_write_reg(intp, TMGTHFALL, 0x0);
+	stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
+	stv0900_write_reg(intp, RTC, 0x80);
+	stv0900_write_reg(intp, RTCS2, 0x40);
+	stv0900_write_reg(intp, CARFREQ, 0x0);
+	stv0900_write_reg(intp, CFRINIT1, 0x0);
+	stv0900_write_reg(intp, CFRINIT0, 0x0);
+	stv0900_write_reg(intp, AGC2REF, 0x65);
+	stv0900_write_reg(intp, DMDISTATE, 0x18);
+	msleep(7);
 
-		for (i = 0; i < 10; i++) {
-			if (stv0900_get_bits(i_params, F0900_P1_TMGLOCK_QUALITY) >= 2)
-				timingcpt++;
+	for (i = 0; i < 10; i++) {
+		if (stv0900_get_bits(intp, TMGLOCK_QUALITY) >= 2)
+			timingcpt++;
 
-			msleep(1);
-		}
-
-		if (timingcpt >= 3)
-			timingLock = TRUE;
-
-		stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38);
-		stv0900_write_reg(i_params, R0900_P1_RTC, 0x88);
-		stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x68);
-		stv0900_write_reg(i_params, R0900_P1_CARFREQ, carFreq);
-		stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, tmgTHhigh);
-		stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, tmgTHLow);
-		break;
-	case STV0900_DEMOD_2:
-		carFreq = stv0900_read_reg(i_params, R0900_P2_CARFREQ);
-		tmgTHhigh = stv0900_read_reg(i_params, R0900_P2_TMGTHRISE);
-		tmgTHLow = stv0900_read_reg(i_params, R0900_P2_TMGTHFALL);
-		stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0x20);
-		stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0);
-		stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
-		stv0900_write_reg(i_params, R0900_P2_RTC, 0x80);
-		stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x40);
-		stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x0);
-		stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0x0);
-		stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0x0);
-		stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x65);
-		stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
-		msleep(5);
-		for (i = 0; i < 10; i++) {
-			if (stv0900_get_bits(i_params, F0900_P2_TMGLOCK_QUALITY) >= 2)
-				timingcpt++;
-
-			msleep(1);
-		}
-
-		if (timingcpt >= 3)
-			timingLock = TRUE;
-
-		stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38);
-		stv0900_write_reg(i_params, R0900_P2_RTC, 0x88);
-		stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x68);
-		stv0900_write_reg(i_params, R0900_P2_CARFREQ, carFreq);
-		stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, tmgTHhigh);
-		stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, tmgTHLow);
-		break;
+		msleep(1);
 	}
 
+	if (timingcpt >= 3)
+		timingLock = TRUE;
+
+	stv0900_write_reg(intp, AGC2REF, 0x38);
+	stv0900_write_reg(intp, RTC, 0x88);
+	stv0900_write_reg(intp, RTCS2, 0x68);
+	stv0900_write_reg(intp, CARFREQ, car_freq);
+	stv0900_write_reg(intp, TMGTHRISE, tmg_th_high);
+	stv0900_write_reg(intp, TMGTHFALL, tmg_th_low);
+
 	return	timingLock;
 }
 
@@ -754,142 +516,114 @@
 					s32 demod_timeout)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
+	int	lock = FALSE,
+		d = demod;
+	s32	srate,
+		search_range,
+		locktimeout,
+		currier_step,
+		nb_steps,
+		current_step,
+		direction,
+		tuner_freq,
+		timeout,
+		freq;
 
-	int lock = FALSE;
-	s32 srate, search_range, locktimeout,
-		currier_step, nb_steps, current_step,
-		direction, tuner_freq, timeout;
-
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		srate = i_params->dmd1_symbol_rate;
-		search_range = i_params->dmd1_srch_range;
-		break;
-
-	case STV0900_DEMOD_2:
-		srate = i_params->dmd2_symbol_rate;
-		search_range = i_params->dmd2_srch_range;
-		break;
-	}
+	srate = intp->symbol_rate[d];
+	search_range = intp->srch_range[d];
 
 	if (srate >= 10000000)
 		locktimeout = demod_timeout / 3;
 	else
 		locktimeout = demod_timeout / 2;
 
-	lock = stv0900_get_demod_lock(i_params, demod, locktimeout);
+	lock = stv0900_get_demod_lock(intp, d, locktimeout);
 
-	if (lock == FALSE) {
-		if (srate >= 10000000) {
-			if (stv0900_check_timing_lock(i_params, demod) == TRUE) {
-				switch (demod) {
-				case STV0900_DEMOD_1:
-				default:
-					stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f);
-					stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15);
-					break;
-				case STV0900_DEMOD_2:
-					stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f);
-					stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15);
-					break;
-				}
+	if (lock != FALSE)
+		return lock;
 
-				lock = stv0900_get_demod_lock(i_params, demod, demod_timeout);
-			} else
-				lock = FALSE;
-		} else {
-			if (srate <= 4000000)
-				currier_step = 1000;
-			else if (srate <= 7000000)
-				currier_step = 2000;
-			else if (srate <= 10000000)
-				currier_step = 3000;
-			else
-				currier_step = 5000;
+	if (srate >= 10000000) {
+		if (stv0900_check_timing_lock(intp, d) == TRUE) {
+			stv0900_write_reg(intp, DMDISTATE, 0x1f);
+			stv0900_write_reg(intp, DMDISTATE, 0x15);
+			lock = stv0900_get_demod_lock(intp, d, demod_timeout);
+		} else
+			lock = FALSE;
 
-			nb_steps = ((search_range / 1000) / currier_step);
-			nb_steps /= 2;
-			nb_steps = (2 * (nb_steps + 1));
-			if (nb_steps < 0)
-				nb_steps = 2;
-			else if (nb_steps > 12)
-				nb_steps = 12;
+		return lock;
+	}
 
-			current_step = 1;
-			direction = 1;
+	if (intp->chip_id <= 0x20) {
+		if (srate <= 1000000)
+			currier_step = 500;
+		else if (srate <= 4000000)
+			currier_step = 1000;
+		else if (srate <= 7000000)
+			currier_step = 2000;
+		else if (srate <= 10000000)
+			currier_step = 3000;
+		else
+			currier_step = 5000;
+
+		if (srate >= 2000000) {
 			timeout = (demod_timeout / 3);
 			if (timeout > 1000)
 				timeout = 1000;
+		} else
+			timeout = (demod_timeout / 2);
+	} else {
+		/*cut 3.0 */
+		currier_step = srate / 4000;
+		timeout = (demod_timeout * 3) / 4;
+	}
 
-			switch (demod) {
-			case STV0900_DEMOD_1:
-			default:
-				if (lock == FALSE) {
-					tuner_freq = i_params->tuner1_freq;
-					i_params->tuner1_bw = stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + i_params->dmd1_symbol_rate;
+	nb_steps = ((search_range / 1000) / currier_step);
 
-					while ((current_step <= nb_steps) && (lock == FALSE)) {
+	if ((nb_steps % 2) != 0)
+		nb_steps += 1;
 
-						if (direction > 0)
-							tuner_freq += (current_step * currier_step);
-						else
-							tuner_freq -= (current_step * currier_step);
+	if (nb_steps <= 0)
+		nb_steps = 2;
+	else if (nb_steps > 12)
+		nb_steps = 12;
 
-						stv0900_set_tuner(fe, tuner_freq, i_params->tuner1_bw);
-						stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C);
-						if (i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS2) {
-							stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0);
-							stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
-							stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
-							stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
-						}
+	current_step = 1;
+	direction = 1;
 
-						stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0);
-						stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0);
-						stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F);
-						stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15);
-						lock = stv0900_get_demod_lock(i_params, demod, timeout);
-						direction *= -1;
-						current_step++;
-					}
-				}
-				break;
-			case STV0900_DEMOD_2:
-				if (lock == FALSE) {
-					tuner_freq = i_params->tuner2_freq;
-					i_params->tuner2_bw = stv0900_carrier_width(srate, i_params->rolloff) + srate;
+	if (intp->chip_id <= 0x20) {
+		tuner_freq = intp->freq[d];
+		intp->bw[d] = stv0900_carrier_width(intp->symbol_rate[d],
+				intp->rolloff) + intp->symbol_rate[d];
+	} else
+		tuner_freq = 0;
 
-					while ((current_step <= nb_steps) && (lock == FALSE)) {
+	while ((current_step <= nb_steps) && (lock == FALSE)) {
+		if (direction > 0)
+			tuner_freq += (current_step * currier_step);
+		else
+			tuner_freq -= (current_step * currier_step);
 
-						if (direction > 0)
-							tuner_freq += (current_step * currier_step);
-						else
-							tuner_freq -= (current_step * currier_step);
-
-						stv0900_set_tuner(fe, tuner_freq, i_params->tuner2_bw);
-						stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C);
-						if (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS2) {
-							stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0);
-							stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
-							stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
-							stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
-						}
-
-						stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0);
-						stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0);
-						stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F);
-						stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15);
-						lock = stv0900_get_demod_lock(i_params, demod, timeout);
-						direction *= -1;
-						current_step++;
-					}
-				}
-				break;
-			}
+		if (intp->chip_id <= 0x20) {
+			stv0900_set_tuner(fe, tuner_freq, intp->bw[d]);
+			stv0900_write_reg(intp, DMDISTATE, 0x1c);
+			stv0900_write_reg(intp, CFRINIT1, 0);
+			stv0900_write_reg(intp, CFRINIT0, 0);
+			stv0900_write_reg(intp, DMDISTATE, 0x1f);
+			stv0900_write_reg(intp, DMDISTATE, 0x15);
+		} else {
+			stv0900_write_reg(intp, DMDISTATE, 0x1c);
+			freq = (tuner_freq * 65536) / (intp->mclk / 1000);
+			stv0900_write_bits(intp, CFR_INIT1, MSB(freq));
+			stv0900_write_bits(intp, CFR_INIT0, LSB(freq));
+			stv0900_write_reg(intp, DMDISTATE, 0x1f);
+			stv0900_write_reg(intp, DMDISTATE, 0x05);
 		}
+
+		lock = stv0900_get_demod_lock(intp, d, timeout);
+		direction *= -1;
+		current_step++;
 	}
 
 	return	lock;
@@ -931,9 +665,7 @@
 		} else if (srate <= 20000000) {
 			(*demod_timeout) = 400;
 			(*fec_timeout) = 130;
-		}
-
-		else {
+		} else {
 			(*demod_timeout) = 300;
 			(*fec_timeout) = 100;
 		}
@@ -946,95 +678,77 @@
 		(*demod_timeout) /= 2;
 }
 
-static void stv0900_set_viterbi_tracq(struct stv0900_internal *i_params,
+static void stv0900_set_viterbi_tracq(struct stv0900_internal *intp,
 					enum fe_stv0900_demod_num demod)
 {
 
-	s32 vth_reg;
+	s32 vth_reg = VTH12;
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
-	dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12);
-
-	stv0900_write_reg(i_params, vth_reg++, 0xd0);
-	stv0900_write_reg(i_params, vth_reg++, 0x7d);
-	stv0900_write_reg(i_params, vth_reg++, 0x53);
-	stv0900_write_reg(i_params, vth_reg++, 0x2F);
-	stv0900_write_reg(i_params, vth_reg++, 0x24);
-	stv0900_write_reg(i_params, vth_reg++, 0x1F);
+	stv0900_write_reg(intp, vth_reg++, 0xd0);
+	stv0900_write_reg(intp, vth_reg++, 0x7d);
+	stv0900_write_reg(intp, vth_reg++, 0x53);
+	stv0900_write_reg(intp, vth_reg++, 0x2f);
+	stv0900_write_reg(intp, vth_reg++, 0x24);
+	stv0900_write_reg(intp, vth_reg++, 0x1f);
 }
 
-static void stv0900_set_viterbi_standard(struct stv0900_internal *i_params,
-				   enum fe_stv0900_search_standard Standard,
-				   enum fe_stv0900_fec PunctureRate,
+static void stv0900_set_viterbi_standard(struct stv0900_internal *intp,
+				   enum fe_stv0900_search_standard standard,
+				   enum fe_stv0900_fec fec,
 				   enum fe_stv0900_demod_num demod)
 {
+	dprintk("%s: ViterbiStandard = ", __func__);
 
-	s32 fecmReg,
-	prvitReg;
-
-	dprintk(KERN_INFO "%s: ViterbiStandard = ", __func__);
-
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		fecmReg = R0900_P1_FECM;
-		prvitReg = R0900_P1_PRVIT;
-		break;
-	case STV0900_DEMOD_2:
-		fecmReg = R0900_P2_FECM;
-		prvitReg = R0900_P2_PRVIT;
-		break;
-	}
-
-	switch (Standard) {
+	switch (standard) {
 	case STV0900_AUTO_SEARCH:
 		dprintk("Auto\n");
-		stv0900_write_reg(i_params, fecmReg, 0x10);
-		stv0900_write_reg(i_params, prvitReg, 0x3F);
+		stv0900_write_reg(intp, FECM, 0x10);
+		stv0900_write_reg(intp, PRVIT, 0x3f);
 		break;
 	case STV0900_SEARCH_DVBS1:
 		dprintk("DVBS1\n");
-		stv0900_write_reg(i_params, fecmReg, 0x00);
-		switch (PunctureRate) {
+		stv0900_write_reg(intp, FECM, 0x00);
+		switch (fec) {
 		case STV0900_FEC_UNKNOWN:
 		default:
-			stv0900_write_reg(i_params, prvitReg, 0x2F);
+			stv0900_write_reg(intp, PRVIT, 0x2f);
 			break;
 		case STV0900_FEC_1_2:
-			stv0900_write_reg(i_params, prvitReg, 0x01);
+			stv0900_write_reg(intp, PRVIT, 0x01);
 			break;
 		case STV0900_FEC_2_3:
-			stv0900_write_reg(i_params, prvitReg, 0x02);
+			stv0900_write_reg(intp, PRVIT, 0x02);
 			break;
 		case STV0900_FEC_3_4:
-			stv0900_write_reg(i_params, prvitReg, 0x04);
+			stv0900_write_reg(intp, PRVIT, 0x04);
 			break;
 		case STV0900_FEC_5_6:
-			stv0900_write_reg(i_params, prvitReg, 0x08);
+			stv0900_write_reg(intp, PRVIT, 0x08);
 			break;
 		case STV0900_FEC_7_8:
-			stv0900_write_reg(i_params, prvitReg, 0x20);
+			stv0900_write_reg(intp, PRVIT, 0x20);
 			break;
 		}
 
 		break;
 	case STV0900_SEARCH_DSS:
 		dprintk("DSS\n");
-		stv0900_write_reg(i_params, fecmReg, 0x80);
-		switch (PunctureRate) {
+		stv0900_write_reg(intp, FECM, 0x80);
+		switch (fec) {
 		case STV0900_FEC_UNKNOWN:
 		default:
-			stv0900_write_reg(i_params, prvitReg, 0x13);
+			stv0900_write_reg(intp, PRVIT, 0x13);
 			break;
 		case STV0900_FEC_1_2:
-			stv0900_write_reg(i_params, prvitReg, 0x01);
+			stv0900_write_reg(intp, PRVIT, 0x01);
 			break;
 		case STV0900_FEC_2_3:
-			stv0900_write_reg(i_params, prvitReg, 0x02);
+			stv0900_write_reg(intp, PRVIT, 0x02);
 			break;
 		case STV0900_FEC_6_7:
-			stv0900_write_reg(i_params, prvitReg, 0x10);
+			stv0900_write_reg(intp, PRVIT, 0x10);
 			break;
 		}
 		break;
@@ -1043,495 +757,11 @@
 	}
 }
 
-static void stv0900_track_optimization(struct dvb_frontend *fe)
-{
-	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
-	enum fe_stv0900_demod_num demod = state->demod;
-
-	s32 srate, pilots, aclc, freq1, freq0,
-		i = 0, timed, timef, blindTunSw = 0;
-
-	enum fe_stv0900_rolloff rolloff;
-	enum fe_stv0900_modcode foundModcod;
-
-	dprintk(KERN_INFO "%s\n", __func__);
-
-	srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
-	srate += stv0900_get_timing_offst(i_params, srate, demod);
-
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		switch (i_params->dmd1_rslts.standard) {
-		case STV0900_DVBS1_STANDARD:
-			if (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH) {
-				stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
-				stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
-			}
-
-			stv0900_write_bits(i_params, F0900_P1_ROLLOFF_CONTROL, i_params->rolloff);
-			stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1);
-			stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75);
-			break;
-		case STV0900_DSS_STANDARD:
-			if (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH) {
-				stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
-				stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
-			}
-
-			stv0900_write_bits(i_params, F0900_P1_ROLLOFF_CONTROL, i_params->rolloff);
-			stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1);
-			stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75);
-			break;
-		case STV0900_DVBS2_STANDARD:
-			stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
-			stv0900_write_reg(i_params, R0900_P1_ACLC, 0);
-			stv0900_write_reg(i_params, R0900_P1_BCLC, 0);
-			if (i_params->dmd1_rslts.frame_length == STV0900_LONG_FRAME) {
-				foundModcod = stv0900_get_bits(i_params, F0900_P1_DEMOD_MODCOD);
-				pilots = stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE) & 0x01;
-				aclc = stv0900_get_optim_carr_loop(srate, foundModcod, pilots, i_params->chip_id);
-				if (foundModcod <= STV0900_QPSK_910)
-					stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, aclc);
-				else if (foundModcod <= STV0900_8PSK_910) {
-					stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
-					stv0900_write_reg(i_params, R0900_P1_ACLC2S28, aclc);
-				}
-
-				if ((i_params->demod_mode == STV0900_SINGLE) && (foundModcod > STV0900_8PSK_910)) {
-					if (foundModcod <= STV0900_16APSK_910) {
-						stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
-						stv0900_write_reg(i_params, R0900_P1_ACLC2S216A, aclc);
-					} else if (foundModcod <= STV0900_32APSK_910) {
-						stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
-						stv0900_write_reg(i_params, R0900_P1_ACLC2S232A, aclc);
-					}
-				}
-
-			} else {
-				aclc = stv0900_get_optim_short_carr_loop(srate, i_params->dmd1_rslts.modulation, i_params->chip_id);
-				if (i_params->dmd1_rslts.modulation == STV0900_QPSK)
-					stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, aclc);
-
-				else if (i_params->dmd1_rslts.modulation == STV0900_8PSK) {
-					stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
-					stv0900_write_reg(i_params, R0900_P1_ACLC2S28, aclc);
-				} else if (i_params->dmd1_rslts.modulation == STV0900_16APSK) {
-					stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
-					stv0900_write_reg(i_params, R0900_P1_ACLC2S216A, aclc);
-				} else if (i_params->dmd1_rslts.modulation == STV0900_32APSK) {
-					stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
-					stv0900_write_reg(i_params, R0900_P1_ACLC2S232A, aclc);
-				}
-
-			}
-
-			if (i_params->chip_id <= 0x11) {
-				if (i_params->demod_mode != STV0900_SINGLE)
-					stv0900_activate_s2_modcode(i_params, demod);
-
-			}
-
-			stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x67);
-			break;
-		case STV0900_UNKNOWN_STANDARD:
-		default:
-			stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
-			break;
-		}
-
-		freq1 = stv0900_read_reg(i_params, R0900_P1_CFR2);
-		freq0 = stv0900_read_reg(i_params, R0900_P1_CFR1);
-		rolloff = stv0900_get_bits(i_params, F0900_P1_ROLLOFF_STATUS);
-		if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) {
-			stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x00);
-			stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
-			stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01);
-			stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod);
-			stv0900_set_max_symbol_rate(i_params, i_params->mclk, srate, demod);
-			stv0900_set_min_symbol_rate(i_params, i_params->mclk, srate, demod);
-			blindTunSw = 1;
-		}
-
-		if (i_params->chip_id >= 0x20) {
-			if ((i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS1) || (i_params->dmd1_srch_standard == STV0900_SEARCH_DSS) || (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH)) {
-				stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0a);
-				stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x0);
-			}
-		}
-
-		if (i_params->chip_id < 0x20)
-			stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x08);
-
-		if (i_params->chip_id == 0x10)
-			stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0x0A);
-
-		stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38);
-
-		if ((i_params->chip_id >= 0x20) || (blindTunSw == 1) || (i_params->dmd1_symbol_rate < 10000000)) {
-			stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
-			stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
-			i_params->tuner1_bw = stv0900_carrier_width(srate, i_params->rolloff) + 10000000;
-
-			if ((i_params->chip_id >= 0x20) || (blindTunSw == 1)) {
-				if (i_params->dmd1_srch_algo != STV0900_WARM_START)
-					stv0900_set_bandwidth(fe, i_params->tuner1_bw);
-			}
-
-			if ((i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd1_symbol_rate < 10000000))
-				msleep(50);
-			else
-				msleep(5);
-
-			stv0900_get_lock_timeout(&timed, &timef, srate, STV0900_WARM_START);
-
-			if (stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) {
-				stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F);
-				stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
-				stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
-				stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
-				i = 0;
-				while ((stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) && (i <= 2)) {
-					stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F);
-					stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
-					stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
-					stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
-					i++;
-				}
-			}
-
-		}
-
-		if (i_params->chip_id >= 0x20)
-			stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x49);
-
-		if ((i_params->dmd1_rslts.standard == STV0900_DVBS1_STANDARD) || (i_params->dmd1_rslts.standard == STV0900_DSS_STANDARD))
-			stv0900_set_viterbi_tracq(i_params, demod);
-
-		break;
-
-	case STV0900_DEMOD_2:
-		switch (i_params->dmd2_rslts.standard) {
-		case STV0900_DVBS1_STANDARD:
-
-			if (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH) {
-				stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
-				stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
-			}
-
-			stv0900_write_bits(i_params, F0900_P2_ROLLOFF_CONTROL, i_params->rolloff);
-			stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1);
-			stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75);
-			break;
-		case STV0900_DSS_STANDARD:
-			if (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH) {
-				stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
-				stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
-			}
-
-			stv0900_write_bits(i_params, F0900_P2_ROLLOFF_CONTROL, i_params->rolloff);
-			stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1);
-			stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75);
-			break;
-		case STV0900_DVBS2_STANDARD:
-			stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
-			stv0900_write_reg(i_params, R0900_P2_ACLC, 0);
-			stv0900_write_reg(i_params, R0900_P2_BCLC, 0);
-			if (i_params->dmd2_rslts.frame_length == STV0900_LONG_FRAME) {
-				foundModcod = stv0900_get_bits(i_params, F0900_P2_DEMOD_MODCOD);
-				pilots = stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE) & 0x01;
-				aclc = stv0900_get_optim_carr_loop(srate, foundModcod, pilots, i_params->chip_id);
-				if (foundModcod <= STV0900_QPSK_910)
-					stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, aclc);
-				else if (foundModcod <= STV0900_8PSK_910) {
-					stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
-					stv0900_write_reg(i_params, R0900_P2_ACLC2S28, aclc);
-				}
-
-				if ((i_params->demod_mode == STV0900_SINGLE) && (foundModcod > STV0900_8PSK_910)) {
-					if (foundModcod <= STV0900_16APSK_910) {
-						stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
-						stv0900_write_reg(i_params, R0900_P2_ACLC2S216A, aclc);
-					} else if (foundModcod <= STV0900_32APSK_910) {
-						stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
-						stv0900_write_reg(i_params, R0900_P2_ACLC2S232A, aclc);
-					}
-
-				}
-
-			} else {
-				aclc = stv0900_get_optim_short_carr_loop(srate,
-									i_params->dmd2_rslts.modulation,
-									i_params->chip_id);
-
-				if (i_params->dmd2_rslts.modulation == STV0900_QPSK)
-					stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, aclc);
-
-				else if (i_params->dmd2_rslts.modulation == STV0900_8PSK) {
-					stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
-					stv0900_write_reg(i_params, R0900_P2_ACLC2S28, aclc);
-				} else if (i_params->dmd2_rslts.modulation == STV0900_16APSK) {
-					stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
-					stv0900_write_reg(i_params, R0900_P2_ACLC2S216A, aclc);
-				} else if (i_params->dmd2_rslts.modulation == STV0900_32APSK) {
-					stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
-					stv0900_write_reg(i_params, R0900_P2_ACLC2S232A, aclc);
-				}
-			}
-
-			stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x67);
-
-			break;
-		case STV0900_UNKNOWN_STANDARD:
-		default:
-			stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
-			break;
-		}
-
-		freq1 = stv0900_read_reg(i_params, R0900_P2_CFR2);
-		freq0 = stv0900_read_reg(i_params, R0900_P2_CFR1);
-		rolloff = stv0900_get_bits(i_params, F0900_P2_ROLLOFF_STATUS);
-		if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) {
-			stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x00);
-			stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
-			stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01);
-			stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod);
-			stv0900_set_max_symbol_rate(i_params, i_params->mclk, srate, demod);
-			stv0900_set_min_symbol_rate(i_params, i_params->mclk, srate, demod);
-			blindTunSw = 1;
-		}
-
-		if (i_params->chip_id >= 0x20) {
-			if ((i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS1) || (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DSS) || (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH)) {
-				stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0a);
-				stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x0);
-			}
-		}
-
-		if (i_params->chip_id < 0x20)
-			stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x08);
-
-		if (i_params->chip_id == 0x10)
-			stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0x0a);
-
-		stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38);
-		if ((i_params->chip_id >= 0x20) || (blindTunSw == 1) || (i_params->dmd2_symbol_rate < 10000000)) {
-			stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
-			stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
-			i_params->tuner2_bw = stv0900_carrier_width(srate, i_params->rolloff) + 10000000;
-
-			if ((i_params->chip_id >= 0x20) || (blindTunSw == 1)) {
-				if (i_params->dmd2_srch_algo != STV0900_WARM_START)
-					stv0900_set_bandwidth(fe, i_params->tuner2_bw);
-			}
-
-			if ((i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd2_symbol_rate < 10000000))
-				msleep(50);
-			else
-				msleep(5);
-
-			stv0900_get_lock_timeout(&timed, &timef, srate, STV0900_WARM_START);
-			if (stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) {
-				stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F);
-				stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
-				stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
-				stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
-				i = 0;
-				while ((stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) && (i <= 2)) {
-					stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F);
-					stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
-					stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
-					stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
-					i++;
-				}
-			}
-		}
-
-		if (i_params->chip_id >= 0x20)
-			stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x49);
-
-		if ((i_params->dmd2_rslts.standard == STV0900_DVBS1_STANDARD) || (i_params->dmd2_rslts.standard == STV0900_DSS_STANDARD))
-			stv0900_set_viterbi_tracq(i_params, demod);
-
-		break;
-	}
-}
-
-static int stv0900_get_fec_lock(struct stv0900_internal *i_params, enum fe_stv0900_demod_num demod, s32 time_out)
-{
-	s32 timer = 0, lock = 0, header_field, pktdelin_field, lock_vit_field;
-
-	enum fe_stv0900_search_state dmd_state;
-
-	dprintk(KERN_INFO "%s\n", __func__);
-
-	dmd_reg(header_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
-	dmd_reg(pktdelin_field, F0900_P1_PKTDELIN_LOCK, F0900_P2_PKTDELIN_LOCK);
-	dmd_reg(lock_vit_field, F0900_P1_LOCKEDVIT, F0900_P2_LOCKEDVIT);
-
-	dmd_state = stv0900_get_bits(i_params, header_field);
-
-	while ((timer < time_out) && (lock == 0)) {
-		switch (dmd_state) {
-		case STV0900_SEARCH:
-		case STV0900_PLH_DETECTED:
-		default:
-			lock = 0;
-			break;
-		case STV0900_DVBS2_FOUND:
-			lock = stv0900_get_bits(i_params, pktdelin_field);
-			break;
-		case STV0900_DVBS_FOUND:
-			lock = stv0900_get_bits(i_params, lock_vit_field);
-			break;
-		}
-
-		if (lock == 0) {
-			msleep(10);
-			timer += 10;
-		}
-	}
-
-	if (lock)
-		dprintk("DEMOD FEC LOCK OK\n");
-	else
-		dprintk("DEMOD FEC LOCK FAIL\n");
-
-	return lock;
-}
-
-static int stv0900_wait_for_lock(struct stv0900_internal *i_params,
-				enum fe_stv0900_demod_num demod,
-				s32 dmd_timeout, s32 fec_timeout)
-{
-
-	s32 timer = 0, lock = 0, str_merg_rst_fld, str_merg_lock_fld;
-
-	dprintk(KERN_INFO "%s\n", __func__);
-
-	dmd_reg(str_merg_rst_fld, F0900_P1_RST_HWARE, F0900_P2_RST_HWARE);
-	dmd_reg(str_merg_lock_fld, F0900_P1_TSFIFO_LINEOK, F0900_P2_TSFIFO_LINEOK);
-
-	lock = stv0900_get_demod_lock(i_params, demod, dmd_timeout);
-
-	if (lock)
-		lock = lock && stv0900_get_fec_lock(i_params, demod, fec_timeout);
-
-	if (lock) {
-		lock = 0;
-
-		dprintk(KERN_INFO "%s: Timer = %d, time_out = %d\n", __func__, timer, fec_timeout);
-
-		while ((timer < fec_timeout) && (lock == 0)) {
-			lock = stv0900_get_bits(i_params, str_merg_lock_fld);
-			msleep(1);
-			timer++;
-		}
-	}
-
-	if (lock)
-		dprintk(KERN_INFO "%s: DEMOD LOCK OK\n", __func__);
-	else
-		dprintk(KERN_INFO "%s: DEMOD LOCK FAIL\n", __func__);
-
-	if (lock)
-		return TRUE;
-	else
-		return FALSE;
-}
-
-enum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
+static enum fe_stv0900_fec stv0900_get_vit_fec(struct stv0900_internal *intp,
 						enum fe_stv0900_demod_num demod)
 {
-	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
-	enum fe_stv0900_tracking_standard fnd_standard;
-	s32 state_field,
-	dss_dvb_field;
-
-	dprintk(KERN_INFO "%s\n", __func__);
-
-	dmd_reg(state_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
-	dmd_reg(dss_dvb_field, F0900_P1_DSS_DVB, F0900_P2_DSS_DVB);
-
-	if (stv0900_get_bits(i_params, state_field) == 2)
-		fnd_standard = STV0900_DVBS2_STANDARD;
-
-	else if (stv0900_get_bits(i_params, state_field) == 3) {
-		if (stv0900_get_bits(i_params, dss_dvb_field) == 1)
-			fnd_standard = STV0900_DSS_STANDARD;
-		else
-			fnd_standard = STV0900_DVBS1_STANDARD;
-	} else
-		fnd_standard = STV0900_UNKNOWN_STANDARD;
-
-	return fnd_standard;
-}
-
-static s32 stv0900_get_carr_freq(struct stv0900_internal *i_params, u32 mclk,
-					enum fe_stv0900_demod_num demod)
-{
-	s32 cfr_field2, cfr_field1, cfr_field0,
-		derot, rem1, rem2, intval1, intval2;
-
-	dmd_reg(cfr_field2, F0900_P1_CAR_FREQ2, F0900_P2_CAR_FREQ2);
-	dmd_reg(cfr_field1, F0900_P1_CAR_FREQ1, F0900_P2_CAR_FREQ1);
-	dmd_reg(cfr_field0, F0900_P1_CAR_FREQ0, F0900_P2_CAR_FREQ0);
-
-	derot = (stv0900_get_bits(i_params, cfr_field2) << 16) +
-		(stv0900_get_bits(i_params, cfr_field1) << 8) +
-		(stv0900_get_bits(i_params, cfr_field0));
-
-	derot = ge2comp(derot, 24);
-	intval1 = mclk >> 12;
-	intval2 = derot >> 12;
-	rem1 = mclk % 0x1000;
-	rem2 = derot % 0x1000;
-	derot = (intval1 * intval2) +
-		((intval1 * rem2) >> 12) +
-		((intval2 * rem1) >> 12);
-
-	return derot;
-}
-
-static u32 stv0900_get_tuner_freq(struct dvb_frontend *fe)
-{
-	struct dvb_frontend_ops	*frontend_ops = NULL;
-	struct dvb_tuner_ops *tuner_ops = NULL;
-	u32 frequency = 0;
-
-	if (&fe->ops)
-		frontend_ops = &fe->ops;
-
-	if (&frontend_ops->tuner_ops)
-		tuner_ops = &frontend_ops->tuner_ops;
-
-	if (tuner_ops->get_frequency) {
-		if ((tuner_ops->get_frequency(fe, &frequency)) < 0)
-			dprintk("%s: Invalid parameter\n", __func__);
-		else
-			dprintk("%s: Frequency=%d\n", __func__, frequency);
-
-	}
-
-	return frequency;
-}
-
-static enum fe_stv0900_fec stv0900_get_vit_fec(struct stv0900_internal *i_params,
-						enum fe_stv0900_demod_num demod)
-{
-	s32 rate_fld, vit_curpun_fld;
 	enum fe_stv0900_fec prate;
-
-	dmd_reg(vit_curpun_fld, F0900_P1_VIT_CURPUN, F0900_P2_VIT_CURPUN);
-	rate_fld = stv0900_get_bits(i_params, vit_curpun_fld);
+	s32 rate_fld = stv0900_get_bits(intp, VIT_CURPUN);
 
 	switch (rate_fld) {
 	case 13:
@@ -1560,258 +790,532 @@
 	return prate;
 }
 
-static enum fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe)
+void stv0900_set_dvbs1_track_car_loop(struct stv0900_internal *intp,
+					enum fe_stv0900_demod_num demod,
+					u32 srate)
+{
+	if (intp->chip_id >= 0x30) {
+		if (srate >= 15000000) {
+			stv0900_write_reg(intp, ACLC, 0x2b);
+			stv0900_write_reg(intp, BCLC, 0x1a);
+		} else if ((srate >= 7000000) && (15000000 > srate)) {
+			stv0900_write_reg(intp, ACLC, 0x0c);
+			stv0900_write_reg(intp, BCLC, 0x1b);
+		} else if (srate < 7000000) {
+			stv0900_write_reg(intp, ACLC, 0x2c);
+			stv0900_write_reg(intp, BCLC, 0x1c);
+		}
+
+	} else { /*cut 2.0 and 1.x*/
+		stv0900_write_reg(intp, ACLC, 0x1a);
+		stv0900_write_reg(intp, BCLC, 0x09);
+	}
+
+}
+
+static void stv0900_track_optimization(struct dvb_frontend *fe)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
+	enum fe_stv0900_demod_num demod = state->demod;
+
+	s32	srate,
+		pilots,
+		aclc,
+		freq1,
+		freq0,
+		i = 0,
+		timed,
+		timef,
+		blind_tun_sw = 0,
+		modulation;
+
+	enum fe_stv0900_rolloff rolloff;
+	enum fe_stv0900_modcode foundModcod;
+
+	dprintk("%s\n", __func__);
+
+	srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
+	srate += stv0900_get_timing_offst(intp, srate, demod);
+
+	switch (intp->result[demod].standard) {
+	case STV0900_DVBS1_STANDARD:
+	case STV0900_DSS_STANDARD:
+		dprintk("%s: found DVB-S or DSS\n", __func__);
+		if (intp->srch_standard[demod] == STV0900_AUTO_SEARCH) {
+			stv0900_write_bits(intp, DVBS1_ENABLE, 1);
+			stv0900_write_bits(intp, DVBS2_ENABLE, 0);
+		}
+
+		stv0900_write_bits(intp, ROLLOFF_CONTROL, intp->rolloff);
+		stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
+
+		if (intp->chip_id < 0x30) {
+			stv0900_write_reg(intp, ERRCTRL1, 0x75);
+			break;
+		}
+
+		if (stv0900_get_vit_fec(intp, demod) == STV0900_FEC_1_2) {
+			stv0900_write_reg(intp, GAUSSR0, 0x98);
+			stv0900_write_reg(intp, CCIR0, 0x18);
+		} else {
+			stv0900_write_reg(intp, GAUSSR0, 0x18);
+			stv0900_write_reg(intp, CCIR0, 0x18);
+		}
+
+		stv0900_write_reg(intp, ERRCTRL1, 0x75);
+		break;
+	case STV0900_DVBS2_STANDARD:
+		dprintk("%s: found DVB-S2\n", __func__);
+		stv0900_write_bits(intp, DVBS1_ENABLE, 0);
+		stv0900_write_bits(intp, DVBS2_ENABLE, 1);
+		stv0900_write_reg(intp, ACLC, 0);
+		stv0900_write_reg(intp, BCLC, 0);
+		if (intp->result[demod].frame_len == STV0900_LONG_FRAME) {
+			foundModcod = stv0900_get_bits(intp, DEMOD_MODCOD);
+			pilots = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01;
+			aclc = stv0900_get_optim_carr_loop(srate,
+							foundModcod,
+							pilots,
+							intp->chip_id);
+			if (foundModcod <= STV0900_QPSK_910)
+				stv0900_write_reg(intp, ACLC2S2Q, aclc);
+			else if (foundModcod <= STV0900_8PSK_910) {
+				stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
+				stv0900_write_reg(intp, ACLC2S28, aclc);
+			}
+
+			if ((intp->demod_mode == STV0900_SINGLE) &&
+					(foundModcod > STV0900_8PSK_910)) {
+				if (foundModcod <= STV0900_16APSK_910) {
+					stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
+					stv0900_write_reg(intp, ACLC2S216A,
+									aclc);
+				} else if (foundModcod <= STV0900_32APSK_910) {
+					stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
+					stv0900_write_reg(intp,	ACLC2S232A,
+									aclc);
+				}
+			}
+
+		} else {
+			modulation = intp->result[demod].modulation;
+			aclc = stv0900_get_optim_short_carr_loop(srate,
+					modulation, intp->chip_id);
+			if (modulation == STV0900_QPSK)
+				stv0900_write_reg(intp, ACLC2S2Q, aclc);
+			else if (modulation == STV0900_8PSK) {
+				stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
+				stv0900_write_reg(intp, ACLC2S28, aclc);
+			} else if (modulation == STV0900_16APSK) {
+				stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
+				stv0900_write_reg(intp, ACLC2S216A, aclc);
+			} else if (modulation == STV0900_32APSK) {
+				stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
+				stv0900_write_reg(intp, ACLC2S232A, aclc);
+			}
+
+		}
+
+		if (intp->chip_id <= 0x11) {
+			if (intp->demod_mode != STV0900_SINGLE)
+				stv0900_activate_s2_modcod(intp, demod);
+
+		}
+
+		stv0900_write_reg(intp, ERRCTRL1, 0x67);
+		break;
+	case STV0900_UNKNOWN_STANDARD:
+	default:
+		dprintk("%s: found unknown standard\n", __func__);
+		stv0900_write_bits(intp, DVBS1_ENABLE, 1);
+		stv0900_write_bits(intp, DVBS2_ENABLE, 1);
+		break;
+	}
+
+	freq1 = stv0900_read_reg(intp, CFR2);
+	freq0 = stv0900_read_reg(intp, CFR1);
+	rolloff = stv0900_get_bits(intp, ROLLOFF_STATUS);
+	if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) {
+		stv0900_write_reg(intp, SFRSTEP, 0x00);
+		stv0900_write_bits(intp, SCAN_ENABLE, 0);
+		stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
+		stv0900_write_reg(intp, TMGCFG2, 0xc1);
+		stv0900_set_symbol_rate(intp, intp->mclk, srate, demod);
+		blind_tun_sw = 1;
+		if (intp->result[demod].standard != STV0900_DVBS2_STANDARD)
+			stv0900_set_dvbs1_track_car_loop(intp, demod, srate);
+
+	}
+
+	if (intp->chip_id >= 0x20) {
+		if ((intp->srch_standard[demod] == STV0900_SEARCH_DVBS1) ||
+				(intp->srch_standard[demod] ==
+							STV0900_SEARCH_DSS) ||
+				(intp->srch_standard[demod] ==
+							STV0900_AUTO_SEARCH)) {
+			stv0900_write_reg(intp, VAVSRVIT, 0x0a);
+			stv0900_write_reg(intp, VITSCALE, 0x0);
+		}
+	}
+
+	if (intp->chip_id < 0x20)
+		stv0900_write_reg(intp, CARHDR, 0x08);
+
+	if (intp->chip_id == 0x10)
+		stv0900_write_reg(intp, CORRELEXP, 0x0a);
+
+	stv0900_write_reg(intp, AGC2REF, 0x38);
+
+	if ((intp->chip_id >= 0x20) ||
+			(blind_tun_sw == 1) ||
+			(intp->symbol_rate[demod] < 10000000)) {
+		stv0900_write_reg(intp, CFRINIT1, freq1);
+		stv0900_write_reg(intp, CFRINIT0, freq0);
+		intp->bw[demod] = stv0900_carrier_width(srate,
+					intp->rolloff) + 10000000;
+
+		if ((intp->chip_id >= 0x20) || (blind_tun_sw == 1)) {
+			if (intp->srch_algo[demod] != STV0900_WARM_START)
+				stv0900_set_bandwidth(fe, intp->bw[demod]);
+		}
+
+		if ((intp->srch_algo[demod] == STV0900_BLIND_SEARCH) ||
+				(intp->symbol_rate[demod] < 10000000))
+			msleep(50);
+		else
+			msleep(5);
+
+		stv0900_get_lock_timeout(&timed, &timef, srate,
+						STV0900_WARM_START);
+
+		if (stv0900_get_demod_lock(intp, demod, timed / 2) == FALSE) {
+			stv0900_write_reg(intp, DMDISTATE, 0x1f);
+			stv0900_write_reg(intp, CFRINIT1, freq1);
+			stv0900_write_reg(intp, CFRINIT0, freq0);
+			stv0900_write_reg(intp, DMDISTATE, 0x18);
+			i = 0;
+			while ((stv0900_get_demod_lock(intp,
+							demod,
+							timed / 2) == FALSE) &&
+						(i <= 2)) {
+				stv0900_write_reg(intp, DMDISTATE, 0x1f);
+				stv0900_write_reg(intp, CFRINIT1, freq1);
+				stv0900_write_reg(intp, CFRINIT0, freq0);
+				stv0900_write_reg(intp, DMDISTATE, 0x18);
+				i++;
+			}
+		}
+
+	}
+
+	if (intp->chip_id >= 0x20)
+		stv0900_write_reg(intp, CARFREQ, 0x49);
+
+	if ((intp->result[demod].standard == STV0900_DVBS1_STANDARD) ||
+			(intp->result[demod].standard == STV0900_DSS_STANDARD))
+		stv0900_set_viterbi_tracq(intp, demod);
+
+}
+
+static int stv0900_get_fec_lock(struct stv0900_internal *intp,
+				enum fe_stv0900_demod_num demod, s32 time_out)
+{
+	s32 timer = 0, lock = 0;
+
+	enum fe_stv0900_search_state dmd_state;
+
+	dprintk("%s\n", __func__);
+
+	dmd_state = stv0900_get_bits(intp, HEADER_MODE);
+
+	while ((timer < time_out) && (lock == 0)) {
+		switch (dmd_state) {
+		case STV0900_SEARCH:
+		case STV0900_PLH_DETECTED:
+		default:
+			lock = 0;
+			break;
+		case STV0900_DVBS2_FOUND:
+			lock = stv0900_get_bits(intp, PKTDELIN_LOCK);
+			break;
+		case STV0900_DVBS_FOUND:
+			lock = stv0900_get_bits(intp, LOCKEDVIT);
+			break;
+		}
+
+		if (lock == 0) {
+			msleep(10);
+			timer += 10;
+		}
+	}
+
+	if (lock)
+		dprintk("%s: DEMOD FEC LOCK OK\n", __func__);
+	else
+		dprintk("%s: DEMOD FEC LOCK FAIL\n", __func__);
+
+	return lock;
+}
+
+static int stv0900_wait_for_lock(struct stv0900_internal *intp,
+				enum fe_stv0900_demod_num demod,
+				s32 dmd_timeout, s32 fec_timeout)
+{
+
+	s32 timer = 0, lock = 0;
+
+	dprintk("%s\n", __func__);
+
+	lock = stv0900_get_demod_lock(intp, demod, dmd_timeout);
+
+	if (lock)
+		lock = lock && stv0900_get_fec_lock(intp, demod, fec_timeout);
+
+	if (lock) {
+		lock = 0;
+
+		dprintk("%s: Timer = %d, time_out = %d\n",
+				__func__, timer, fec_timeout);
+
+		while ((timer < fec_timeout) && (lock == 0)) {
+			lock = stv0900_get_bits(intp, TSFIFO_LINEOK);
+			msleep(1);
+			timer++;
+		}
+	}
+
+	if (lock)
+		dprintk("%s: DEMOD LOCK OK\n", __func__);
+	else
+		dprintk("%s: DEMOD LOCK FAIL\n", __func__);
+
+	if (lock)
+		return TRUE;
+	else
+		return FALSE;
+}
+
+enum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
+						enum fe_stv0900_demod_num demod)
+{
+	struct stv0900_state *state = fe->demodulator_priv;
+	struct stv0900_internal *intp = state->internal;
+	enum fe_stv0900_tracking_standard fnd_standard;
+
+	int hdr_mode = stv0900_get_bits(intp, HEADER_MODE);
+
+	switch (hdr_mode) {
+	case 2:
+		fnd_standard = STV0900_DVBS2_STANDARD;
+		break;
+	case 3:
+		if (stv0900_get_bits(intp, DSS_DVB) == 1)
+			fnd_standard = STV0900_DSS_STANDARD;
+		else
+			fnd_standard = STV0900_DVBS1_STANDARD;
+
+		break;
+	default:
+		fnd_standard = STV0900_UNKNOWN_STANDARD;
+	}
+
+	dprintk("%s: standard %d\n", __func__, fnd_standard);
+
+	return fnd_standard;
+}
+
+static s32 stv0900_get_carr_freq(struct stv0900_internal *intp, u32 mclk,
+					enum fe_stv0900_demod_num demod)
+{
+	s32	derot,
+		rem1,
+		rem2,
+		intval1,
+		intval2;
+
+	derot = (stv0900_get_bits(intp, CAR_FREQ2) << 16) +
+		(stv0900_get_bits(intp, CAR_FREQ1) << 8) +
+		(stv0900_get_bits(intp, CAR_FREQ0));
+
+	derot = ge2comp(derot, 24);
+	intval1 = mclk >> 12;
+	intval2 = derot >> 12;
+	rem1 = mclk % 0x1000;
+	rem2 = derot % 0x1000;
+	derot = (intval1 * intval2) +
+		((intval1 * rem2) >> 12) +
+		((intval2 * rem1) >> 12);
+
+	return derot;
+}
+
+static u32 stv0900_get_tuner_freq(struct dvb_frontend *fe)
+{
+	struct dvb_frontend_ops	*frontend_ops = NULL;
+	struct dvb_tuner_ops *tuner_ops = NULL;
+	u32 freq = 0;
+
+	if (&fe->ops)
+		frontend_ops = &fe->ops;
+
+	if (&frontend_ops->tuner_ops)
+		tuner_ops = &frontend_ops->tuner_ops;
+
+	if (tuner_ops->get_frequency) {
+		if ((tuner_ops->get_frequency(fe, &freq)) < 0)
+			dprintk("%s: Invalid parameter\n", __func__);
+		else
+			dprintk("%s: Frequency=%d\n", __func__, freq);
+
+	}
+
+	return freq;
+}
+
+static enum
+fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe)
+{
+	struct stv0900_state *state = fe->demodulator_priv;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
 	enum fe_stv0900_signal_type range = STV0900_OUTOFRANGE;
-	s32 offsetFreq,
-	srate_offset,
-	i = 0;
+	struct stv0900_signal_info *result = &intp->result[demod];
+	s32	offsetFreq,
+		srate_offset;
+	int	i = 0,
+		d = demod;
 
 	u8 timing;
 
 	msleep(5);
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) {
-			timing = stv0900_read_reg(i_params, R0900_P1_TMGREG2);
-			i = 0;
-			stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x5c);
+	if (intp->srch_algo[d] == STV0900_BLIND_SEARCH) {
+		timing = stv0900_read_reg(intp, TMGREG2);
+		i = 0;
+		stv0900_write_reg(intp, SFRSTEP, 0x5c);
 
-			while ((i <= 50) && (timing != 0) && (timing != 0xFF)) {
-				timing = stv0900_read_reg(i_params, R0900_P1_TMGREG2);
-				msleep(5);
-				i += 5;
-			}
+		while ((i <= 50) && (timing != 0) && (timing != 0xff)) {
+			timing = stv0900_read_reg(intp, TMGREG2);
+			msleep(5);
+			i += 5;
 		}
+	}
 
-		i_params->dmd1_rslts.standard = stv0900_get_standard(fe, demod);
-		i_params->dmd1_rslts.frequency = stv0900_get_tuner_freq(fe);
-		offsetFreq = stv0900_get_carr_freq(i_params, i_params->mclk, demod) / 1000;
-		i_params->dmd1_rslts.frequency += offsetFreq;
-		i_params->dmd1_rslts.symbol_rate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
-		srate_offset = stv0900_get_timing_offst(i_params, i_params->dmd1_rslts.symbol_rate, demod);
-		i_params->dmd1_rslts.symbol_rate += srate_offset;
-		i_params->dmd1_rslts.fec = stv0900_get_vit_fec(i_params, demod);
-		i_params->dmd1_rslts.modcode = stv0900_get_bits(i_params, F0900_P1_DEMOD_MODCOD);
-		i_params->dmd1_rslts.pilot = stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE) & 0x01;
-		i_params->dmd1_rslts.frame_length = ((u32)stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE)) >> 1;
-		i_params->dmd1_rslts.rolloff = stv0900_get_bits(i_params, F0900_P1_ROLLOFF_STATUS);
-		switch (i_params->dmd1_rslts.standard) {
-		case STV0900_DVBS2_STANDARD:
-			i_params->dmd1_rslts.spectrum = stv0900_get_bits(i_params, F0900_P1_SPECINV_DEMOD);
-			if (i_params->dmd1_rslts.modcode <= STV0900_QPSK_910)
-				i_params->dmd1_rslts.modulation = STV0900_QPSK;
-			else if (i_params->dmd1_rslts.modcode <= STV0900_8PSK_910)
-				i_params->dmd1_rslts.modulation = STV0900_8PSK;
-			else if (i_params->dmd1_rslts.modcode <= STV0900_16APSK_910)
-				i_params->dmd1_rslts.modulation = STV0900_16APSK;
-			else if (i_params->dmd1_rslts.modcode <= STV0900_32APSK_910)
-				i_params->dmd1_rslts.modulation = STV0900_32APSK;
-			else
-				i_params->dmd1_rslts.modulation = STV0900_UNKNOWN;
-			break;
-		case STV0900_DVBS1_STANDARD:
-		case STV0900_DSS_STANDARD:
-			i_params->dmd1_rslts.spectrum = stv0900_get_bits(i_params, F0900_P1_IQINV);
-			i_params->dmd1_rslts.modulation = STV0900_QPSK;
-			break;
-		default:
-			break;
-		}
-
-		if ((i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd1_symbol_rate < 10000000)) {
-			offsetFreq =	i_params->dmd1_rslts.frequency - i_params->tuner1_freq;
-			i_params->tuner1_freq = stv0900_get_tuner_freq(fe);
-			if (ABS(offsetFreq) <= ((i_params->dmd1_srch_range / 2000) + 500))
-				range = STV0900_RANGEOK;
-			else
-				if (ABS(offsetFreq) <= (stv0900_carrier_width(i_params->dmd1_rslts.symbol_rate, i_params->dmd1_rslts.rolloff) / 2000))
-					range = STV0900_RANGEOK;
-				else
-					range = STV0900_OUTOFRANGE;
-
-		} else {
-			if (ABS(offsetFreq) <= ((i_params->dmd1_srch_range / 2000) + 500))
-				range = STV0900_RANGEOK;
-			else
-				range = STV0900_OUTOFRANGE;
-		}
+	result->standard = stv0900_get_standard(fe, d);
+	result->frequency = stv0900_get_tuner_freq(fe);
+	offsetFreq = stv0900_get_carr_freq(intp, intp->mclk, d) / 1000;
+	result->frequency += offsetFreq;
+	result->symbol_rate = stv0900_get_symbol_rate(intp, intp->mclk, d);
+	srate_offset = stv0900_get_timing_offst(intp, result->symbol_rate, d);
+	result->symbol_rate += srate_offset;
+	result->fec = stv0900_get_vit_fec(intp, d);
+	result->modcode = stv0900_get_bits(intp, DEMOD_MODCOD);
+	result->pilot = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01;
+	result->frame_len = ((u32)stv0900_get_bits(intp, DEMOD_TYPE)) >> 1;
+	result->rolloff = stv0900_get_bits(intp, ROLLOFF_STATUS);
+	switch (result->standard) {
+	case STV0900_DVBS2_STANDARD:
+		result->spectrum = stv0900_get_bits(intp, SPECINV_DEMOD);
+		if (result->modcode <= STV0900_QPSK_910)
+			result->modulation = STV0900_QPSK;
+		else if (result->modcode <= STV0900_8PSK_910)
+			result->modulation = STV0900_8PSK;
+		else if (result->modcode <= STV0900_16APSK_910)
+			result->modulation = STV0900_16APSK;
+		else if (result->modcode <= STV0900_32APSK_910)
+			result->modulation = STV0900_32APSK;
+		else
+			result->modulation = STV0900_UNKNOWN;
 		break;
-	case STV0900_DEMOD_2:
-		if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) {
-			timing = stv0900_read_reg(i_params, R0900_P2_TMGREG2);
-			i = 0;
-			stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x5c);
-
-			while ((i <= 50) && (timing != 0) && (timing != 0xff)) {
-				timing = stv0900_read_reg(i_params, R0900_P2_TMGREG2);
-				msleep(5);
-				i += 5;
-			}
-		}
-
-		i_params->dmd2_rslts.standard = stv0900_get_standard(fe, demod);
-		i_params->dmd2_rslts.frequency = stv0900_get_tuner_freq(fe);
-		offsetFreq = stv0900_get_carr_freq(i_params, i_params->mclk, demod) / 1000;
-		i_params->dmd2_rslts.frequency += offsetFreq;
-		i_params->dmd2_rslts.symbol_rate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
-		srate_offset = stv0900_get_timing_offst(i_params, i_params->dmd2_rslts.symbol_rate, demod);
-		i_params->dmd2_rslts.symbol_rate += srate_offset;
-		i_params->dmd2_rslts.fec = stv0900_get_vit_fec(i_params, demod);
-		i_params->dmd2_rslts.modcode = stv0900_get_bits(i_params, F0900_P2_DEMOD_MODCOD);
-		i_params->dmd2_rslts.pilot = stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE) & 0x01;
-		i_params->dmd2_rslts.frame_length = ((u32)stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE)) >> 1;
-		i_params->dmd2_rslts.rolloff = stv0900_get_bits(i_params, F0900_P2_ROLLOFF_STATUS);
-		switch (i_params->dmd2_rslts.standard) {
-		case STV0900_DVBS2_STANDARD:
-			i_params->dmd2_rslts.spectrum = stv0900_get_bits(i_params, F0900_P2_SPECINV_DEMOD);
-			if (i_params->dmd2_rslts.modcode <= STV0900_QPSK_910)
-				i_params->dmd2_rslts.modulation = STV0900_QPSK;
-			else if (i_params->dmd2_rslts.modcode <= STV0900_8PSK_910)
-				i_params->dmd2_rslts.modulation = STV0900_8PSK;
-			else if (i_params->dmd2_rslts.modcode <= STV0900_16APSK_910)
-				i_params->dmd2_rslts.modulation = STV0900_16APSK;
-			else if (i_params->dmd2_rslts.modcode <= STV0900_32APSK_910)
-				i_params->dmd2_rslts.modulation = STV0900_32APSK;
-			else
-				i_params->dmd2_rslts.modulation = STV0900_UNKNOWN;
-			break;
-		case STV0900_DVBS1_STANDARD:
-		case STV0900_DSS_STANDARD:
-			i_params->dmd2_rslts.spectrum = stv0900_get_bits(i_params, F0900_P2_IQINV);
-			i_params->dmd2_rslts.modulation = STV0900_QPSK;
-			break;
-		default:
-			break;
-		}
-
-		if ((i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd2_symbol_rate < 10000000)) {
-			offsetFreq =	i_params->dmd2_rslts.frequency - i_params->tuner2_freq;
-			i_params->tuner2_freq = stv0900_get_tuner_freq(fe);
-
-			if (ABS(offsetFreq) <= ((i_params->dmd2_srch_range / 2000) + 500))
-				range = STV0900_RANGEOK;
-			else
-				if (ABS(offsetFreq) <= (stv0900_carrier_width(i_params->dmd2_rslts.symbol_rate, i_params->dmd2_rslts.rolloff) / 2000))
-					range = STV0900_RANGEOK;
-				else
-					range = STV0900_OUTOFRANGE;
-		} else {
-			if (ABS(offsetFreq) <= ((i_params->dmd2_srch_range / 2000) + 500))
-				range = STV0900_RANGEOK;
-			else
-				range = STV0900_OUTOFRANGE;
-		}
-
+	case STV0900_DVBS1_STANDARD:
+	case STV0900_DSS_STANDARD:
+		result->spectrum = stv0900_get_bits(intp, IQINV);
+		result->modulation = STV0900_QPSK;
+		break;
+	default:
 		break;
 	}
 
+	if ((intp->srch_algo[d] == STV0900_BLIND_SEARCH) ||
+				(intp->symbol_rate[d] < 10000000)) {
+		offsetFreq = result->frequency - intp->freq[d];
+		intp->freq[d] = stv0900_get_tuner_freq(fe);
+		if (ABS(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500))
+			range = STV0900_RANGEOK;
+		else if (ABS(offsetFreq) <=
+				(stv0900_carrier_width(result->symbol_rate,
+						result->rolloff) / 2000))
+			range = STV0900_RANGEOK;
+
+	} else if (ABS(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500))
+		range = STV0900_RANGEOK;
+
+	dprintk("%s: range %d\n", __func__, range);
+
 	return range;
 }
 
-static enum fe_stv0900_signal_type stv0900_dvbs1_acq_workaround(struct dvb_frontend *fe)
+static enum
+fe_stv0900_signal_type stv0900_dvbs1_acq_workaround(struct dvb_frontend *fe)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
-
-	s32 srate, demod_timeout,
-		fec_timeout, freq1, freq0;
 	enum fe_stv0900_signal_type signal_type = STV0900_NODATA;
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		i_params->dmd1_rslts.locked = FALSE;
-		if (stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS_FOUND) {
-			srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
-			srate += stv0900_get_timing_offst(i_params, srate, demod);
-			if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH)
-				stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod);
+	s32	srate,
+		demod_timeout,
+		fec_timeout,
+		freq1,
+		freq0;
 
-			stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, srate, STV0900_WARM_START);
-			freq1 = stv0900_read_reg(i_params, R0900_P1_CFR2);
-			freq0 = stv0900_read_reg(i_params, R0900_P1_CFR1);
-			stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
-			stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, STV0900_IQ_FORCE_SWAPPED);
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C);
-			stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
-			stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
-			if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) {
-				i_params->dmd1_rslts.locked = TRUE;
+	intp->result[demod].locked = FALSE;
+
+	if (stv0900_get_bits(intp, HEADER_MODE) == STV0900_DVBS_FOUND) {
+		srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
+		srate += stv0900_get_timing_offst(intp, srate, demod);
+		if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH)
+			stv0900_set_symbol_rate(intp, intp->mclk, srate, demod);
+
+		stv0900_get_lock_timeout(&demod_timeout, &fec_timeout,
+					srate, STV0900_WARM_START);
+		freq1 = stv0900_read_reg(intp, CFR2);
+		freq0 = stv0900_read_reg(intp, CFR1);
+		stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
+		stv0900_write_bits(intp, SPECINV_CONTROL,
+					STV0900_IQ_FORCE_SWAPPED);
+		stv0900_write_reg(intp, DMDISTATE, 0x1c);
+		stv0900_write_reg(intp, CFRINIT1, freq1);
+		stv0900_write_reg(intp, CFRINIT0, freq0);
+		stv0900_write_reg(intp, DMDISTATE, 0x18);
+		if (stv0900_wait_for_lock(intp, demod,
+				demod_timeout, fec_timeout) == TRUE) {
+			intp->result[demod].locked = TRUE;
+			signal_type = stv0900_get_signal_params(fe);
+			stv0900_track_optimization(fe);
+		} else {
+			stv0900_write_bits(intp, SPECINV_CONTROL,
+					STV0900_IQ_FORCE_NORMAL);
+			stv0900_write_reg(intp, DMDISTATE, 0x1c);
+			stv0900_write_reg(intp, CFRINIT1, freq1);
+			stv0900_write_reg(intp, CFRINIT0, freq0);
+			stv0900_write_reg(intp, DMDISTATE, 0x18);
+			if (stv0900_wait_for_lock(intp, demod,
+					demod_timeout, fec_timeout) == TRUE) {
+				intp->result[demod].locked = TRUE;
 				signal_type = stv0900_get_signal_params(fe);
 				stv0900_track_optimization(fe);
-			} else {
-				stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, STV0900_IQ_FORCE_NORMAL);
-				stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1c);
-				stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
-				stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
-				stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
-				if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) {
-					i_params->dmd1_rslts.locked = TRUE;
-					signal_type = stv0900_get_signal_params(fe);
-					stv0900_track_optimization(fe);
-				}
-
 			}
 
-		} else
-			i_params->dmd1_rslts.locked = FALSE;
+		}
 
-		break;
-	case STV0900_DEMOD_2:
-		i_params->dmd2_rslts.locked = FALSE;
-		if (stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS_FOUND) {
-			srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
-			srate += stv0900_get_timing_offst(i_params, srate, demod);
-
-			if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH)
-				stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod);
-
-			stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, srate, STV0900_WARM_START);
-			freq1 = stv0900_read_reg(i_params, R0900_P2_CFR2);
-			freq0 = stv0900_read_reg(i_params, R0900_P2_CFR1);
-			stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
-			stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, STV0900_IQ_FORCE_SWAPPED);
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C);
-			stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
-			stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
-
-			if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) {
-				i_params->dmd2_rslts.locked = TRUE;
-				signal_type = stv0900_get_signal_params(fe);
-				stv0900_track_optimization(fe);
-			} else {
-				stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, STV0900_IQ_FORCE_NORMAL);
-				stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1c);
-				stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
-				stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
-				stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
-
-				if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) {
-					i_params->dmd2_rslts.locked = TRUE;
-					signal_type = stv0900_get_signal_params(fe);
-					stv0900_track_optimization(fe);
-				}
-
-			}
-
-		} else
-			i_params->dmd1_rslts.locked = FALSE;
-
-		break;
-	}
+	} else
+		intp->result[demod].locked = FALSE;
 
 	return signal_type;
 }
 
-static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *i_params,
+static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *intp,
 					enum fe_stv0900_demod_num demod)
 {
 	u32 minagc2level = 0xffff,
@@ -1820,105 +1324,54 @@
 
 	s32 i, j, nb_steps, direction;
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38);
-		stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 1);
-		stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 1);
+	stv0900_write_reg(intp, AGC2REF, 0x38);
+	stv0900_write_bits(intp, SCAN_ENABLE, 0);
+	stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
 
-		stv0900_write_reg(i_params, R0900_P1_SFRUP1, 0x83);
-		stv0900_write_reg(i_params, R0900_P1_SFRUP0, 0xc0);
+	stv0900_write_bits(intp, AUTO_GUP, 1);
+	stv0900_write_bits(intp, AUTO_GLOW, 1);
 
-		stv0900_write_reg(i_params, R0900_P1_SFRLOW1, 0x82);
-		stv0900_write_reg(i_params, R0900_P1_SFRLOW0, 0xa0);
-		stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x0);
+	stv0900_write_reg(intp, DMDT0M, 0x0);
 
-		stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod);
-		nb_steps = -1 + (i_params->dmd1_srch_range / 1000000);
-		nb_steps /= 2;
-		nb_steps = (2 * nb_steps) + 1;
+	stv0900_set_symbol_rate(intp, intp->mclk, 1000000, demod);
+	nb_steps = -1 + (intp->srch_range[demod] / 1000000);
+	nb_steps /= 2;
+	nb_steps = (2 * nb_steps) + 1;
 
-		if (nb_steps < 0)
-			nb_steps = 1;
+	if (nb_steps < 0)
+		nb_steps = 1;
 
-		direction = 1;
+	direction = 1;
 
-		freq_step = (1000000 << 8) / (i_params->mclk >> 8);
+	freq_step = (1000000 << 8) / (intp->mclk >> 8);
 
-		init_freq = 0;
+	init_freq = 0;
 
-		for (i = 0; i < nb_steps; i++) {
-			if (direction > 0)
-				init_freq = init_freq + (freq_step * i);
-			else
-				init_freq = init_freq - (freq_step * i);
+	for (i = 0; i < nb_steps; i++) {
+		if (direction > 0)
+			init_freq = init_freq + (freq_step * i);
+		else
+			init_freq = init_freq - (freq_step * i);
 
-			direction *= -1;
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5C);
-			stv0900_write_reg(i_params, R0900_P1_CFRINIT1, (init_freq >> 8) & 0xff);
-			stv0900_write_reg(i_params, R0900_P1_CFRINIT0, init_freq  & 0xff);
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x58);
-			msleep(10);
-			agc2level = 0;
+		direction *= -1;
+		stv0900_write_reg(intp, DMDISTATE, 0x5C);
+		stv0900_write_reg(intp, CFRINIT1, (init_freq >> 8) & 0xff);
+		stv0900_write_reg(intp, CFRINIT0, init_freq  & 0xff);
+		stv0900_write_reg(intp, DMDISTATE, 0x58);
+		msleep(10);
+		agc2level = 0;
 
-			for (j = 0; j < 10; j++)
-				agc2level += (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8)
-						| stv0900_read_reg(i_params, R0900_P1_AGC2I0);
+		for (j = 0; j < 10; j++)
+			agc2level += (stv0900_read_reg(intp, AGC2I1) << 8)
+					| stv0900_read_reg(intp, AGC2I0);
 
-			agc2level /= 10;
+		agc2level /= 10;
 
-			if (agc2level < minagc2level)
-				minagc2level = agc2level;
-		}
-		break;
-	case STV0900_DEMOD_2:
-		stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38);
-		stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 1);
-		stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 1);
-		stv0900_write_reg(i_params, R0900_P2_SFRUP1, 0x83);
-		stv0900_write_reg(i_params, R0900_P2_SFRUP0, 0xc0);
-		stv0900_write_reg(i_params, R0900_P2_SFRLOW1, 0x82);
-		stv0900_write_reg(i_params, R0900_P2_SFRLOW0, 0xa0);
-		stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x0);
-		stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod);
-		nb_steps = -1 + (i_params->dmd2_srch_range / 1000000);
-		nb_steps /= 2;
-		nb_steps = (2 * nb_steps) + 1;
+		if (agc2level < minagc2level)
+			minagc2level = agc2level;
 
-		if (nb_steps < 0)
-			nb_steps = 1;
-
-		direction = 1;
-		freq_step = (1000000 << 8) / (i_params->mclk >> 8);
-		init_freq = 0;
-		for (i = 0; i < nb_steps; i++) {
-			if (direction > 0)
-				init_freq = init_freq + (freq_step * i);
-			else
-				init_freq = init_freq - (freq_step * i);
-
-			direction *= -1;
-
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5C);
-			stv0900_write_reg(i_params, R0900_P2_CFRINIT1, (init_freq >> 8) & 0xff);
-			stv0900_write_reg(i_params, R0900_P2_CFRINIT0, init_freq  & 0xff);
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x58);
-
-			msleep(10);
-			agc2level = 0;
-			for (j = 0; j < 10; j++)
-				agc2level += (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8)
-						| stv0900_read_reg(i_params, R0900_P2_AGC2I0);
-
-			agc2level /= 10;
-
-			if (agc2level < minagc2level)
-				minagc2level = agc2level;
-		}
-		break;
 	}
 
 	return (u16)minagc2level;
@@ -1927,336 +1380,192 @@
 static u32 stv0900_search_srate_coarse(struct dvb_frontend *fe)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
-	int timingLock = FALSE;
+	int timing_lck = FALSE;
 	s32 i, timingcpt = 0,
 		direction = 1,
 		nb_steps,
 		current_step = 0,
 		tuner_freq;
+	u32 agc2_th,
+		coarse_srate = 0,
+		agc2_integr = 0,
+		currier_step = 1200;
 
-	u32 coarse_srate = 0, agc2_integr = 0, currier_step = 1200;
+	if (intp->chip_id >= 0x30)
+		agc2_th = 0x2e00;
+	else
+		agc2_th = 0x1f00;
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x1F);
-		stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0x12);
-		stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0xf0);
-		stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0xe0);
-		stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 1);
-		stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 1);
-		stv0900_write_reg(i_params, R0900_P1_SFRUP1, 0x83);
-		stv0900_write_reg(i_params, R0900_P1_SFRUP0, 0xc0);
-		stv0900_write_reg(i_params, R0900_P1_SFRLOW1, 0x82);
-		stv0900_write_reg(i_params, R0900_P1_SFRLOW0, 0xa0);
-		stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x0);
-		stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x50);
+	stv0900_write_bits(intp, DEMOD_MODE, 0x1f);
+	stv0900_write_reg(intp, TMGCFG, 0x12);
+	stv0900_write_reg(intp, TMGTHRISE, 0xf0);
+	stv0900_write_reg(intp, TMGTHFALL, 0xe0);
+	stv0900_write_bits(intp, SCAN_ENABLE, 1);
+	stv0900_write_bits(intp, CFR_AUTOSCAN, 1);
+	stv0900_write_reg(intp, SFRUP1, 0x83);
+	stv0900_write_reg(intp, SFRUP0, 0xc0);
+	stv0900_write_reg(intp, SFRLOW1, 0x82);
+	stv0900_write_reg(intp, SFRLOW0, 0xa0);
+	stv0900_write_reg(intp, DMDT0M, 0x0);
+	stv0900_write_reg(intp, AGC2REF, 0x50);
 
-		if (i_params->chip_id >= 0x20) {
-			stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x6a);
-			stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x95);
-		} else {
-			stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed);
-			stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x73);
-		}
-
-		if (i_params->dmd1_symbol_rate <= 2000000)
-			currier_step = 1000;
-		else if (i_params->dmd1_symbol_rate <= 5000000)
-			currier_step = 2000;
-		else if (i_params->dmd1_symbol_rate <= 12000000)
-			currier_step = 3000;
-		else
-			currier_step = 5000;
-
-		nb_steps = -1 + ((i_params->dmd1_srch_range / 1000) / currier_step);
-		nb_steps /= 2;
-		nb_steps = (2 * nb_steps) + 1;
-
-		if (nb_steps < 0)
-			nb_steps = 1;
-
-		else if (nb_steps > 10) {
-			nb_steps = 11;
-			currier_step = (i_params->dmd1_srch_range / 1000) / 10;
-		}
-
-		current_step = 0;
-
-		direction = 1;
-		tuner_freq = i_params->tuner1_freq;
-
-		while ((timingLock == FALSE) && (current_step < nb_steps)) {
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5F);
-			stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x0);
-
-			msleep(50);
-
-			for (i = 0; i < 10; i++) {
-				if (stv0900_get_bits(i_params, F0900_P1_TMGLOCK_QUALITY) >= 2)
-					timingcpt++;
-
-				agc2_integr += (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8) | stv0900_read_reg(i_params, R0900_P1_AGC2I0);
-
-			}
-
-			agc2_integr /= 10;
-			coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
-			current_step++;
-			direction *= -1;
-
-			dprintk("lock: I2C_DEMOD_MODE_FIELD =0. Search started. tuner freq=%d agc2=0x%x srate_coarse=%d tmg_cpt=%d\n", tuner_freq, agc2_integr, coarse_srate, timingcpt);
-
-			if ((timingcpt >= 5) && (agc2_integr < 0x1F00) && (coarse_srate < 55000000) && (coarse_srate > 850000)) {
-				timingLock = TRUE;
-			}
-
-			else if (current_step < nb_steps) {
-				if (direction > 0)
-					tuner_freq += (current_step * currier_step);
-				else
-					tuner_freq -= (current_step * currier_step);
-
-				stv0900_set_tuner(fe, tuner_freq, i_params->tuner1_bw);
-			}
-		}
-
-		if (timingLock == FALSE)
-			coarse_srate = 0;
-		else
-			coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
-		break;
-	case STV0900_DEMOD_2:
-		stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x1F);
-		stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0x12);
-		stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0xf0);
-		stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0xe0);
-		stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 1);
-		stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 1);
-		stv0900_write_reg(i_params, R0900_P2_SFRUP1, 0x83);
-		stv0900_write_reg(i_params, R0900_P2_SFRUP0, 0xc0);
-		stv0900_write_reg(i_params, R0900_P2_SFRLOW1, 0x82);
-		stv0900_write_reg(i_params, R0900_P2_SFRLOW0, 0xa0);
-		stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x0);
-		stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x50);
-
-		if (i_params->chip_id >= 0x20) {
-			stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x6a);
-			stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x95);
-		} else {
-			stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed);
-			stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x73);
-		}
-
-		if (i_params->dmd2_symbol_rate <= 2000000)
-			currier_step = 1000;
-		else if (i_params->dmd2_symbol_rate <= 5000000)
-			currier_step = 2000;
-		else if (i_params->dmd2_symbol_rate <= 12000000)
-			currier_step = 3000;
-		else
-			currier_step = 5000;
-
-
-		nb_steps = -1 + ((i_params->dmd2_srch_range / 1000) / currier_step);
-		nb_steps /= 2;
-		nb_steps = (2 * nb_steps) + 1;
-
-		if (nb_steps < 0)
-			nb_steps = 1;
-		else if (nb_steps > 10) {
-			nb_steps = 11;
-			currier_step = (i_params->dmd2_srch_range / 1000) / 10;
-		}
-
-		current_step = 0;
-		direction = 1;
-		tuner_freq = i_params->tuner2_freq;
-
-		while ((timingLock == FALSE) && (current_step < nb_steps)) {
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5F);
-			stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x0);
-
-			msleep(50);
-			timingcpt = 0;
-
-			for (i = 0; i < 20; i++) {
-				if (stv0900_get_bits(i_params, F0900_P2_TMGLOCK_QUALITY) >= 2)
-					timingcpt++;
-				agc2_integr += (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8)
-								| stv0900_read_reg(i_params, R0900_P2_AGC2I0);
-			}
-
-			agc2_integr /= 20;
-			coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
-			if ((timingcpt >= 10) && (agc2_integr < 0x1F00) && (coarse_srate < 55000000) && (coarse_srate > 850000))
-				timingLock = TRUE;
-			else {
-				current_step++;
-				direction *= -1;
-
-				if (direction > 0)
-					tuner_freq += (current_step * currier_step);
-				else
-					tuner_freq -= (current_step * currier_step);
-
-				stv0900_set_tuner(fe, tuner_freq, i_params->tuner2_bw);
-			}
-		}
-
-		if (timingLock == FALSE)
-			coarse_srate = 0;
-		else
-			coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
-		break;
+	if (intp->chip_id >= 0x30) {
+		stv0900_write_reg(intp, CARFREQ, 0x99);
+		stv0900_write_reg(intp, SFRSTEP, 0x98);
+	} else if (intp->chip_id >= 0x20) {
+		stv0900_write_reg(intp, CARFREQ, 0x6a);
+		stv0900_write_reg(intp, SFRSTEP, 0x95);
+	} else {
+		stv0900_write_reg(intp, CARFREQ, 0xed);
+		stv0900_write_reg(intp, SFRSTEP, 0x73);
 	}
 
+	if (intp->symbol_rate[demod] <= 2000000)
+		currier_step = 1000;
+	else if (intp->symbol_rate[demod] <= 5000000)
+		currier_step = 2000;
+	else if (intp->symbol_rate[demod] <= 12000000)
+		currier_step = 3000;
+	else
+			currier_step = 5000;
+
+	nb_steps = -1 + ((intp->srch_range[demod] / 1000) / currier_step);
+	nb_steps /= 2;
+	nb_steps = (2 * nb_steps) + 1;
+
+	if (nb_steps < 0)
+		nb_steps = 1;
+	else if (nb_steps > 10) {
+		nb_steps = 11;
+		currier_step = (intp->srch_range[demod] / 1000) / 10;
+	}
+
+	current_step = 0;
+	direction = 1;
+
+	tuner_freq = intp->freq[demod];
+
+	while ((timing_lck == FALSE) && (current_step < nb_steps)) {
+		stv0900_write_reg(intp, DMDISTATE, 0x5f);
+		stv0900_write_bits(intp, DEMOD_MODE, 0);
+
+		msleep(50);
+
+		for (i = 0; i < 10; i++) {
+			if (stv0900_get_bits(intp, TMGLOCK_QUALITY) >= 2)
+				timingcpt++;
+
+			agc2_integr += (stv0900_read_reg(intp, AGC2I1) << 8) |
+					stv0900_read_reg(intp, AGC2I0);
+		}
+
+		agc2_integr /= 10;
+		coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
+		current_step++;
+		direction *= -1;
+
+		dprintk("lock: I2C_DEMOD_MODE_FIELD =0. Search started."
+			" tuner freq=%d agc2=0x%x srate_coarse=%d tmg_cpt=%d\n",
+			tuner_freq, agc2_integr, coarse_srate, timingcpt);
+
+		if ((timingcpt >= 5) &&
+				(agc2_integr < agc2_th) &&
+				(coarse_srate < 55000000) &&
+				(coarse_srate > 850000))
+			timing_lck = TRUE;
+		else if (current_step < nb_steps) {
+			if (direction > 0)
+				tuner_freq += (current_step * currier_step);
+			else
+				tuner_freq -= (current_step * currier_step);
+
+			stv0900_set_tuner(fe, tuner_freq, intp->bw[demod]);
+		}
+	}
+
+	if (timing_lck == FALSE)
+		coarse_srate = 0;
+	else
+		coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
+
 	return coarse_srate;
 }
 
 static u32 stv0900_search_srate_fine(struct dvb_frontend *fe)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
-	u32 coarse_srate,
-	coarse_freq,
-	symb;
+	u32	coarse_srate,
+		coarse_freq,
+		symb,
+		symbmax,
+		symbmin,
+		symbcomp;
 
-	coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+	coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		coarse_freq = (stv0900_read_reg(i_params, R0900_P1_CFR2) << 8)
-						| stv0900_read_reg(i_params, R0900_P1_CFR1);
-		symb = 13 * (coarse_srate / 10);
+	if (coarse_srate > 3000000) {
+		symbmax = 13 * (coarse_srate / 10);
+		symbmax = (symbmax / 1000) * 65536;
+		symbmax /= (intp->mclk / 1000);
 
-		if (symb < i_params->dmd1_symbol_rate)
-			coarse_srate = 0;
-		else {
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F);
-			stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01);
-			stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0x20);
-			stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0x00);
-			stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0xd2);
-			stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
+		symbmin = 10 * (coarse_srate / 13);
+		symbmin = (symbmin / 1000)*65536;
+		symbmin /= (intp->mclk / 1000);
 
-			if (i_params->chip_id >= 0x20)
-				stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x49);
-			else
-				stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed);
+		symb = (coarse_srate / 1000) * 65536;
+		symb /= (intp->mclk / 1000);
+	} else {
+		symbmax = 13 * (coarse_srate / 10);
+		symbmax = (symbmax / 100) * 65536;
+		symbmax /= (intp->mclk / 100);
 
-			if (coarse_srate > 3000000) {
-				symb = 13 * (coarse_srate / 10);
-				symb = (symb / 1000) * 65536;
-				symb /= (i_params->mclk / 1000);
-				stv0900_write_reg(i_params, R0900_P1_SFRUP1, (symb >> 8) & 0x7F);
-				stv0900_write_reg(i_params, R0900_P1_SFRUP0, (symb & 0xFF));
+		symbmin = 10 * (coarse_srate / 14);
+		symbmin = (symbmin / 100) * 65536;
+		symbmin /= (intp->mclk / 100);
 
-				symb = 10 * (coarse_srate / 13);
-				symb = (symb / 1000) * 65536;
-				symb /= (i_params->mclk / 1000);
+		symb = (coarse_srate / 100) * 65536;
+		symb /= (intp->mclk / 100);
+	}
 
-				stv0900_write_reg(i_params, R0900_P1_SFRLOW1, (symb >> 8) & 0x7F);
-				stv0900_write_reg(i_params, R0900_P1_SFRLOW0, (symb & 0xFF));
+	symbcomp = 13 * (coarse_srate / 10);
+		coarse_freq = (stv0900_read_reg(intp, CFR2) << 8)
+					| stv0900_read_reg(intp, CFR1);
 
-				symb = (coarse_srate / 1000) * 65536;
-				symb /= (i_params->mclk / 1000);
-				stv0900_write_reg(i_params, R0900_P1_SFRINIT1, (symb >> 8) & 0xFF);
-				stv0900_write_reg(i_params, R0900_P1_SFRINIT0, (symb & 0xFF));
-			} else {
-				symb = 13 * (coarse_srate / 10);
-				symb = (symb / 100) * 65536;
-				symb /= (i_params->mclk / 100);
-				stv0900_write_reg(i_params, R0900_P1_SFRUP1, (symb >> 8) & 0x7F);
-				stv0900_write_reg(i_params, R0900_P1_SFRUP0, (symb & 0xFF));
+	if (symbcomp < intp->symbol_rate[demod])
+		coarse_srate = 0;
+	else {
+		stv0900_write_reg(intp, DMDISTATE, 0x1f);
+		stv0900_write_reg(intp, TMGCFG2, 0xc1);
+		stv0900_write_reg(intp, TMGTHRISE, 0x20);
+		stv0900_write_reg(intp, TMGTHFALL, 0x00);
+		stv0900_write_reg(intp, TMGCFG, 0xd2);
+		stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
+		stv0900_write_reg(intp, AGC2REF, 0x38);
 
-				symb = 10 * (coarse_srate / 14);
-				symb = (symb / 100) * 65536;
-				symb /= (i_params->mclk / 100);
-				stv0900_write_reg(i_params, R0900_P1_SFRLOW1, (symb >> 8) & 0x7F);
-				stv0900_write_reg(i_params, R0900_P1_SFRLOW0, (symb & 0xFF));
+		if (intp->chip_id >= 0x30)
+			stv0900_write_reg(intp, CARFREQ, 0x79);
+		else if (intp->chip_id >= 0x20)
+			stv0900_write_reg(intp, CARFREQ, 0x49);
+		else
+			stv0900_write_reg(intp, CARFREQ, 0xed);
 
-				symb = (coarse_srate / 100) * 65536;
-				symb /= (i_params->mclk / 100);
-				stv0900_write_reg(i_params, R0900_P1_SFRINIT1, (symb >> 8) & 0xFF);
-				stv0900_write_reg(i_params, R0900_P1_SFRINIT0, (symb & 0xFF));
-			}
+		stv0900_write_reg(intp, SFRUP1, (symbmax >> 8) & 0x7f);
+		stv0900_write_reg(intp, SFRUP0, (symbmax & 0xff));
 
-			stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x20);
-			stv0900_write_reg(i_params, R0900_P1_CFRINIT1, (coarse_freq >> 8) & 0xff);
-			stv0900_write_reg(i_params, R0900_P1_CFRINIT0, coarse_freq  & 0xff);
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15);
-		}
-		break;
-	case STV0900_DEMOD_2:
-		coarse_freq = (stv0900_read_reg(i_params, R0900_P2_CFR2) << 8)
-						| stv0900_read_reg(i_params, R0900_P2_CFR1);
+		stv0900_write_reg(intp, SFRLOW1, (symbmin >> 8) & 0x7f);
+		stv0900_write_reg(intp, SFRLOW0, (symbmin & 0xff));
 
-		symb = 13 * (coarse_srate / 10);
+		stv0900_write_reg(intp, SFRINIT1, (symb >> 8) & 0xff);
+		stv0900_write_reg(intp, SFRINIT0, (symb & 0xff));
 
-		if (symb < i_params->dmd2_symbol_rate)
-			coarse_srate = 0;
-		else {
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F);
-			stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01);
-			stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0x20);
-			stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0x00);
-			stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0xd2);
-			stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
-
-			if (i_params->chip_id >= 0x20)
-				stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x49);
-			else
-				stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed);
-
-			if (coarse_srate > 3000000) {
-				symb = 13 * (coarse_srate / 10);
-				symb = (symb / 1000) * 65536;
-				symb /= (i_params->mclk / 1000);
-				stv0900_write_reg(i_params, R0900_P2_SFRUP1, (symb >> 8) & 0x7F);
-				stv0900_write_reg(i_params, R0900_P2_SFRUP0, (symb & 0xFF));
-
-				symb = 10 * (coarse_srate / 13);
-				symb = (symb / 1000) * 65536;
-				symb /= (i_params->mclk / 1000);
-
-				stv0900_write_reg(i_params, R0900_P2_SFRLOW1, (symb >> 8) & 0x7F);
-				stv0900_write_reg(i_params, R0900_P2_SFRLOW0, (symb & 0xFF));
-
-				symb = (coarse_srate / 1000) * 65536;
-				symb /= (i_params->mclk / 1000);
-				stv0900_write_reg(i_params, R0900_P2_SFRINIT1, (symb >> 8) & 0xFF);
-				stv0900_write_reg(i_params, R0900_P2_SFRINIT0, (symb & 0xFF));
-			} else {
-				symb = 13 * (coarse_srate / 10);
-				symb = (symb / 100) * 65536;
-				symb /= (i_params->mclk / 100);
-				stv0900_write_reg(i_params, R0900_P2_SFRUP1, (symb >> 8) & 0x7F);
-				stv0900_write_reg(i_params, R0900_P2_SFRUP0, (symb & 0xFF));
-
-				symb = 10 * (coarse_srate / 14);
-				symb = (symb / 100) * 65536;
-				symb /= (i_params->mclk / 100);
-				stv0900_write_reg(i_params, R0900_P2_SFRLOW1, (symb >> 8) & 0x7F);
-				stv0900_write_reg(i_params, R0900_P2_SFRLOW0, (symb & 0xFF));
-
-				symb = (coarse_srate / 100) * 65536;
-				symb /= (i_params->mclk / 100);
-				stv0900_write_reg(i_params, R0900_P2_SFRINIT1, (symb >> 8) & 0xFF);
-				stv0900_write_reg(i_params, R0900_P2_SFRINIT0, (symb & 0xFF));
-			}
-
-			stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x20);
-			stv0900_write_reg(i_params, R0900_P2_CFRINIT1, (coarse_freq >> 8) & 0xff);
-			stv0900_write_reg(i_params, R0900_P2_CFRINIT0, coarse_freq  & 0xff);
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15);
-		}
-
-		break;
+		stv0900_write_reg(intp, DMDT0M, 0x20);
+		stv0900_write_reg(intp, CFRINIT1, (coarse_freq >> 8) & 0xff);
+		stv0900_write_reg(intp, CFRINIT0, coarse_freq  & 0xff);
+		stv0900_write_reg(intp, DMDISTATE, 0x15);
 	}
 
 	return coarse_srate;
@@ -2265,163 +1574,135 @@
 static int stv0900_blind_search_algo(struct dvb_frontend *fe)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
-	u8 k_ref_tmg, k_ref_tmg_max, k_ref_tmg_min;
-	u32 coarse_srate;
-	int lock = FALSE, coarse_fail = FALSE;
-	s32 demod_timeout = 500, fec_timeout = 50, kref_tmg_reg, fail_cpt, i, agc2_overflow;
-	u16 agc2_integr;
-	u8 dstatus2;
+	u8	k_ref_tmg,
+		k_ref_tmg_max,
+		k_ref_tmg_min;
+	u32	coarse_srate,
+		agc2_th;
+	int	lock = FALSE,
+		coarse_fail = FALSE;
+	s32	demod_timeout = 500,
+		fec_timeout = 50,
+		fail_cpt,
+		i,
+		agc2_overflow;
+	u16	agc2_int;
+	u8	dstatus2;
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
-	if (i_params->chip_id < 0x20) {
+	if (intp->chip_id < 0x20) {
 		k_ref_tmg_max = 233;
 		k_ref_tmg_min = 143;
 	} else {
-		k_ref_tmg_max = 120;
-		k_ref_tmg_min = 30;
+		k_ref_tmg_max = 110;
+		k_ref_tmg_min = 10;
 	}
 
-	agc2_integr = stv0900_blind_check_agc2_min_level(i_params, demod);
+	if (intp->chip_id <= 0x20)
+		agc2_th = STV0900_BLIND_SEARCH_AGC2_TH;
+	else
+		agc2_th = STV0900_BLIND_SEARCH_AGC2_TH_CUT30;
 
-	if (agc2_integr > STV0900_BLIND_SEARCH_AGC2_TH) {
-		lock = FALSE;
+	agc2_int = stv0900_blind_check_agc2_min_level(intp, demod);
 
-	} else {
-		switch (demod) {
-		case STV0900_DEMOD_1:
-		default:
-			if (i_params->chip_id == 0x10)
-				stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0xAA);
+	if (agc2_int > STV0900_BLIND_SEARCH_AGC2_TH)
+		return FALSE;
 
-			if (i_params->chip_id < 0x20)
-				stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x55);
+	if (intp->chip_id == 0x10)
+		stv0900_write_reg(intp, CORRELEXP, 0xaa);
 
-			stv0900_write_reg(i_params, R0900_P1_CARCFG, 0xC4);
-			stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x44);
+	if (intp->chip_id < 0x20)
+		stv0900_write_reg(intp, CARHDR, 0x55);
+	else
+		stv0900_write_reg(intp, CARHDR, 0x20);
 
-			if (i_params->chip_id >= 0x20) {
-				stv0900_write_reg(i_params, R0900_P1_EQUALCFG, 0x41);
-				stv0900_write_reg(i_params, R0900_P1_FFECFG, 0x41);
-				stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x82);
-				stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0);
-			}
+	if (intp->chip_id <= 0x20)
+		stv0900_write_reg(intp, CARCFG, 0xc4);
+	else
+		stv0900_write_reg(intp, CARCFG, 0x6);
 
-			kref_tmg_reg = R0900_P1_KREFTMG;
-			break;
-		case STV0900_DEMOD_2:
-			if (i_params->chip_id == 0x10)
-				stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0xAA);
+	stv0900_write_reg(intp, RTCS2, 0x44);
 
-			if (i_params->chip_id < 0x20)
-				stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x55);
+	if (intp->chip_id >= 0x20) {
+		stv0900_write_reg(intp, EQUALCFG, 0x41);
+		stv0900_write_reg(intp, FFECFG, 0x41);
+		stv0900_write_reg(intp, VITSCALE, 0x82);
+		stv0900_write_reg(intp, VAVSRVIT, 0x0);
+	}
 
-			stv0900_write_reg(i_params, R0900_P2_CARCFG, 0xC4);
-			stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x44);
+	k_ref_tmg = k_ref_tmg_max;
 
-			if (i_params->chip_id >= 0x20) {
-				stv0900_write_reg(i_params, R0900_P2_EQUALCFG, 0x41);
-				stv0900_write_reg(i_params, R0900_P2_FFECFG, 0x41);
-				stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x82);
-				stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0);
-			}
+	do {
+		stv0900_write_reg(intp, KREFTMG, k_ref_tmg);
+		if (stv0900_search_srate_coarse(fe) != 0) {
+			coarse_srate = stv0900_search_srate_fine(fe);
 
-			kref_tmg_reg = R0900_P2_KREFTMG;
-			break;
-		}
-
-		k_ref_tmg = k_ref_tmg_max;
-
-		do {
-			stv0900_write_reg(i_params, kref_tmg_reg, k_ref_tmg);
-			if (stv0900_search_srate_coarse(fe) != 0) {
-				coarse_srate = stv0900_search_srate_fine(fe);
-
-				if (coarse_srate != 0) {
-					stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, coarse_srate, STV0900_BLIND_SEARCH);
-					lock = stv0900_get_demod_lock(i_params, demod, demod_timeout);
-				} else
-					lock = FALSE;
-			} else {
-				fail_cpt = 0;
-				agc2_overflow = 0;
-
-				switch (demod) {
-				case STV0900_DEMOD_1:
-				default:
-					for (i = 0; i < 10; i++) {
-						agc2_integr = (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8)
-								| stv0900_read_reg(i_params, R0900_P1_AGC2I0);
-
-						if (agc2_integr >= 0xff00)
-							agc2_overflow++;
-
-						dstatus2 = stv0900_read_reg(i_params, R0900_P1_DSTATUS2);
-
-						if (((dstatus2 & 0x1) == 0x1) && ((dstatus2 >> 7) == 1))
-							fail_cpt++;
-					}
-					break;
-				case STV0900_DEMOD_2:
-					for (i = 0; i < 10; i++) {
-						agc2_integr = (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8)
-								| stv0900_read_reg(i_params, R0900_P2_AGC2I0);
-
-						if (agc2_integr >= 0xff00)
-							agc2_overflow++;
-
-						dstatus2 = stv0900_read_reg(i_params, R0900_P2_DSTATUS2);
-
-						if (((dstatus2 & 0x1) == 0x1) && ((dstatus2 >> 7) == 1))
-							fail_cpt++;
-					}
-					break;
-				}
-
-				if ((fail_cpt > 7) || (agc2_overflow > 7))
-					coarse_fail = TRUE;
-
+			if (coarse_srate != 0) {
+				stv0900_get_lock_timeout(&demod_timeout,
+							&fec_timeout,
+							coarse_srate,
+							STV0900_BLIND_SEARCH);
+				lock = stv0900_get_demod_lock(intp,
+							demod,
+							demod_timeout);
+			} else
 				lock = FALSE;
+		} else {
+			fail_cpt = 0;
+			agc2_overflow = 0;
+
+			for (i = 0; i < 10; i++) {
+				agc2_int = (stv0900_read_reg(intp, AGC2I1) << 8)
+					| stv0900_read_reg(intp, AGC2I0);
+
+				if (agc2_int >= 0xff00)
+					agc2_overflow++;
+
+				dstatus2 = stv0900_read_reg(intp, DSTATUS2);
+
+				if (((dstatus2 & 0x1) == 0x1) &&
+						((dstatus2 >> 7) == 1))
+					fail_cpt++;
 			}
-			k_ref_tmg -= 30;
-		} while ((k_ref_tmg >= k_ref_tmg_min) && (lock == FALSE) && (coarse_fail == FALSE));
-	}
+
+			if ((fail_cpt > 7) || (agc2_overflow > 7))
+				coarse_fail = TRUE;
+
+			lock = FALSE;
+		}
+		k_ref_tmg -= 30;
+	} while ((k_ref_tmg >= k_ref_tmg_min) &&
+				(lock == FALSE) &&
+				(coarse_fail == FALSE));
 
 	return lock;
 }
 
-static void stv0900_set_viterbi_acq(struct stv0900_internal *i_params,
+static void stv0900_set_viterbi_acq(struct stv0900_internal *intp,
 					enum fe_stv0900_demod_num demod)
 {
-	s32 vth_reg;
+	s32 vth_reg = VTH12;
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
-	dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12);
-
-	stv0900_write_reg(i_params, vth_reg++, 0x96);
-	stv0900_write_reg(i_params, vth_reg++, 0x64);
-	stv0900_write_reg(i_params, vth_reg++, 0x36);
-	stv0900_write_reg(i_params, vth_reg++, 0x23);
-	stv0900_write_reg(i_params, vth_reg++, 0x1E);
-	stv0900_write_reg(i_params, vth_reg++, 0x19);
+	stv0900_write_reg(intp, vth_reg++, 0x96);
+	stv0900_write_reg(intp, vth_reg++, 0x64);
+	stv0900_write_reg(intp, vth_reg++, 0x36);
+	stv0900_write_reg(intp, vth_reg++, 0x23);
+	stv0900_write_reg(intp, vth_reg++, 0x1e);
+	stv0900_write_reg(intp, vth_reg++, 0x19);
 }
 
-static void stv0900_set_search_standard(struct stv0900_internal *i_params,
+static void stv0900_set_search_standard(struct stv0900_internal *intp,
 					enum fe_stv0900_demod_num demod)
 {
 
-	int sstndrd;
+	dprintk("%s\n", __func__);
 
-	dprintk(KERN_INFO "%s\n", __func__);
-
-	sstndrd = i_params->dmd1_srch_standard;
-	if (demod == 1)
-		sstndrd = i_params->dmd2_srch_stndrd;
-
-	switch (sstndrd) {
+	switch (intp->srch_standard[demod]) {
 	case STV0900_SEARCH_DVBS1:
 		dprintk("Search Standard = DVBS1\n");
 		break;
@@ -2436,129 +1717,74 @@
 		break;
 	}
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		switch (i_params->dmd1_srch_standard) {
-		case STV0900_SEARCH_DVBS1:
-		case STV0900_SEARCH_DSS:
-			stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
+	switch (intp->srch_standard[demod]) {
+	case STV0900_SEARCH_DVBS1:
+	case STV0900_SEARCH_DSS:
+		stv0900_write_bits(intp, DVBS1_ENABLE, 1);
+		stv0900_write_bits(intp, DVBS2_ENABLE, 0);
+		stv0900_write_bits(intp, STOP_CLKVIT, 0);
+		stv0900_set_dvbs1_track_car_loop(intp,
+						demod,
+						intp->symbol_rate[demod]);
+		stv0900_write_reg(intp, CAR2CFG, 0x22);
 
-			stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 0);
-			stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a);
-			stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09);
-			stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x22);
+		stv0900_set_viterbi_acq(intp, demod);
+		stv0900_set_viterbi_standard(intp,
+					intp->srch_standard[demod],
+					intp->fec[demod], demod);
 
-			stv0900_set_viterbi_acq(i_params, demod);
-			stv0900_set_viterbi_standard(i_params,
-						i_params->dmd1_srch_standard,
-						i_params->dmd1_fec, demod);
-
-			break;
-		case STV0900_SEARCH_DVBS2:
-			stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 1);
-			stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a);
-			stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09);
-			stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x26);
-			if (i_params->demod_mode != STV0900_SINGLE) {
-				if (i_params->chip_id <= 0x11)
-					stv0900_stop_all_s2_modcod(i_params, demod);
-				else
-					stv0900_activate_s2_modcode(i_params, demod);
-
-			} else
-				stv0900_activate_s2_modcode_single(i_params, demod);
-
-			stv0900_set_viterbi_tracq(i_params, demod);
-
-			break;
-		case STV0900_AUTO_SEARCH:
-		default:
-			stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 0);
-			stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a);
-			stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09);
-			stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x26);
-			if (i_params->demod_mode != STV0900_SINGLE) {
-				if (i_params->chip_id <= 0x11)
-					stv0900_stop_all_s2_modcod(i_params, demod);
-				else
-					stv0900_activate_s2_modcode(i_params, demod);
-
-			} else
-				stv0900_activate_s2_modcode_single(i_params, demod);
-
-			if (i_params->dmd1_symbol_rate >= 2000000)
-				stv0900_set_viterbi_acq(i_params, demod);
-			else
-				stv0900_set_viterbi_tracq(i_params, demod);
-
-			stv0900_set_viterbi_standard(i_params, i_params->dmd1_srch_standard, i_params->dmd1_fec, demod);
-
-			break;
-		}
 		break;
-	case STV0900_DEMOD_2:
-		switch (i_params->dmd2_srch_stndrd) {
-		case STV0900_SEARCH_DVBS1:
-		case STV0900_SEARCH_DSS:
-			stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 0);
-			stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a);
-			stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09);
-			stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x22);
-			stv0900_set_viterbi_acq(i_params, demod);
-			stv0900_set_viterbi_standard(i_params, i_params->dmd2_srch_stndrd, i_params->dmd2_fec, demod);
-			break;
-		case STV0900_SEARCH_DVBS2:
-			stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 1);
-			stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a);
-			stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09);
-			stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x26);
-			if (i_params->demod_mode != STV0900_SINGLE)
-				stv0900_activate_s2_modcode(i_params, demod);
+	case STV0900_SEARCH_DVBS2:
+		stv0900_write_bits(intp, DVBS1_ENABLE, 0);
+		stv0900_write_bits(intp, DVBS2_ENABLE, 1);
+		stv0900_write_bits(intp, STOP_CLKVIT, 1);
+		stv0900_write_reg(intp, ACLC, 0x1a);
+		stv0900_write_reg(intp, BCLC, 0x09);
+		if (intp->chip_id <= 0x20) /*cut 1.x and 2.0*/
+			stv0900_write_reg(intp, CAR2CFG, 0x26);
+		else
+			stv0900_write_reg(intp, CAR2CFG, 0x66);
+
+		if (intp->demod_mode != STV0900_SINGLE) {
+			if (intp->chip_id <= 0x11)
+				stv0900_stop_all_s2_modcod(intp, demod);
 			else
-				stv0900_activate_s2_modcode_single(i_params, demod);
+				stv0900_activate_s2_modcod(intp, demod);
 
-			stv0900_set_viterbi_tracq(i_params, demod);
-			break;
-		case STV0900_AUTO_SEARCH:
-		default:
-			stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 0);
-			stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a);
-			stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09);
-			stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x26);
-			if (i_params->demod_mode != STV0900_SINGLE)
-				stv0900_activate_s2_modcode(i_params, demod);
+		} else
+			stv0900_activate_s2_modcod_single(intp, demod);
+
+		stv0900_set_viterbi_tracq(intp, demod);
+
+		break;
+	case STV0900_AUTO_SEARCH:
+	default:
+		stv0900_write_bits(intp, DVBS1_ENABLE, 1);
+		stv0900_write_bits(intp, DVBS2_ENABLE, 1);
+		stv0900_write_bits(intp, STOP_CLKVIT, 0);
+		stv0900_write_reg(intp, ACLC, 0x1a);
+		stv0900_write_reg(intp, BCLC, 0x09);
+		stv0900_set_dvbs1_track_car_loop(intp,
+						demod,
+						intp->symbol_rate[demod]);
+		if (intp->chip_id <= 0x20) /*cut 1.x and 2.0*/
+			stv0900_write_reg(intp, CAR2CFG, 0x26);
+		else
+			stv0900_write_reg(intp, CAR2CFG, 0x66);
+
+		if (intp->demod_mode != STV0900_SINGLE) {
+			if (intp->chip_id <= 0x11)
+				stv0900_stop_all_s2_modcod(intp, demod);
 			else
-				stv0900_activate_s2_modcode_single(i_params, demod);
+				stv0900_activate_s2_modcod(intp, demod);
 
-			if (i_params->dmd2_symbol_rate >= 2000000)
-				stv0900_set_viterbi_acq(i_params, demod);
-			else
-				stv0900_set_viterbi_tracq(i_params, demod);
+		} else
+			stv0900_activate_s2_modcod_single(intp, demod);
 
-			stv0900_set_viterbi_standard(i_params, i_params->dmd2_srch_stndrd, i_params->dmd2_fec, demod);
-
-			break;
-		}
+		stv0900_set_viterbi_tracq(intp, demod);
+		stv0900_set_viterbi_standard(intp,
+						intp->srch_standard[demod],
+						intp->fec[demod], demod);
 
 		break;
 	}
@@ -2567,10 +1793,11 @@
 enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
 
-	s32 demod_timeout = 500, fec_timeout = 50, stream_merger_field;
+	s32 demod_timeout = 500, fec_timeout = 50;
+	s32 aq_power, agc1_power, i;
 
 	int lock = FALSE, low_sr = FALSE;
 
@@ -2578,157 +1805,117 @@
 	enum fe_stv0900_search_algo algo;
 	int no_signal = FALSE;
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		algo = i_params->dmd1_srch_algo;
-
-		stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 1);
-		stream_merger_field = F0900_P1_RST_HWARE;
-
-		stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5C);
-
-		if (i_params->chip_id >= 0x20)
-			stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x9e);
+	algo = intp->srch_algo[demod];
+	stv0900_write_bits(intp, RST_HWARE, 1);
+	stv0900_write_reg(intp, DMDISTATE, 0x5c);
+	if (intp->chip_id >= 0x20) {
+		if (intp->symbol_rate[demod] > 5000000)
+			stv0900_write_reg(intp, CORRELABS, 0x9e);
 		else
-			stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x88);
+			stv0900_write_reg(intp, CORRELABS, 0x82);
+	} else
+		stv0900_write_reg(intp, CORRELABS, 0x88);
 
-		stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, i_params->dmd1_symbol_rate, i_params->dmd1_srch_algo);
+	stv0900_get_lock_timeout(&demod_timeout, &fec_timeout,
+				intp->symbol_rate[demod],
+				intp->srch_algo[demod]);
 
-		if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) {
-			i_params->tuner1_bw = 2 * 36000000;
+	if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) {
+		intp->bw[demod] = 2 * 36000000;
 
-			stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x00);
-			stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x70);
+		stv0900_write_reg(intp, TMGCFG2, 0xc0);
+		stv0900_write_reg(intp, CORRELMANT, 0x70);
 
-			stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod);
+		stv0900_set_symbol_rate(intp, intp->mclk, 1000000, demod);
+	} else {
+		stv0900_write_reg(intp, DMDT0M, 0x20);
+		stv0900_write_reg(intp, TMGCFG, 0xd2);
+
+		if (intp->symbol_rate[demod] < 2000000)
+			stv0900_write_reg(intp, CORRELMANT, 0x63);
+		else
+			stv0900_write_reg(intp, CORRELMANT, 0x70);
+
+		stv0900_write_reg(intp, AGC2REF, 0x38);
+
+		intp->bw[demod] =
+				stv0900_carrier_width(intp->symbol_rate[demod],
+								intp->rolloff);
+		if (intp->chip_id >= 0x20) {
+			stv0900_write_reg(intp, KREFTMG, 0x5a);
+
+			if (intp->srch_algo[demod] == STV0900_COLD_START) {
+				intp->bw[demod] += 10000000;
+				intp->bw[demod] *= 15;
+				intp->bw[demod] /= 10;
+			} else if (intp->srch_algo[demod] == STV0900_WARM_START)
+				intp->bw[demod] += 10000000;
+
 		} else {
-			stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x20);
-			stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0xd2);
-
-			if (i_params->dmd1_symbol_rate < 2000000)
-				stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x63);
-			else
-				stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x70);
-
-			stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38);
-			if (i_params->chip_id >= 0x20) {
-				stv0900_write_reg(i_params, R0900_P1_KREFTMG, 0x5a);
-
-				if (i_params->dmd1_srch_algo == STV0900_COLD_START)
-					i_params->tuner1_bw = (15 * (stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000)) / 10;
-				else if (i_params->dmd1_srch_algo == STV0900_WARM_START)
-					i_params->tuner1_bw = stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000;
-			} else {
-				stv0900_write_reg(i_params, R0900_P1_KREFTMG, 0xc1);
-				i_params->tuner1_bw = (15 * (stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000)) / 10;
-			}
-
-			stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01);
-
-			stv0900_set_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod);
-			stv0900_set_max_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod);
-			stv0900_set_min_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod);
-			if (i_params->dmd1_symbol_rate >= 10000000)
-				low_sr = FALSE;
-			else
-				low_sr = TRUE;
-
+			stv0900_write_reg(intp, KREFTMG, 0xc1);
+			intp->bw[demod] += 10000000;
+			intp->bw[demod] *= 15;
+			intp->bw[demod] /= 10;
 		}
 
-		stv0900_set_tuner(fe, i_params->tuner1_freq, i_params->tuner1_bw);
+		stv0900_write_reg(intp, TMGCFG2, 0xc1);
 
-		stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, i_params->dmd1_srch_iq_inv);
-		stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1);
-
-		stv0900_set_search_standard(i_params, demod);
-
-		if (i_params->dmd1_srch_algo != STV0900_BLIND_SEARCH)
-			stv0900_start_search(i_params, demod);
-		break;
-	case STV0900_DEMOD_2:
-		algo = i_params->dmd2_srch_algo;
-
-		stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 1);
-
-		stream_merger_field = F0900_P2_RST_HWARE;
-
-		stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5C);
-
-		if (i_params->chip_id >= 0x20)
-			stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x9e);
+		stv0900_set_symbol_rate(intp, intp->mclk,
+					intp->symbol_rate[demod], demod);
+		stv0900_set_max_symbol_rate(intp, intp->mclk,
+					intp->symbol_rate[demod], demod);
+		stv0900_set_min_symbol_rate(intp, intp->mclk,
+					intp->symbol_rate[demod], demod);
+		if (intp->symbol_rate[demod] >= 10000000)
+			low_sr = FALSE;
 		else
-			stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x88);
+			low_sr = TRUE;
 
-		stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, i_params->dmd2_symbol_rate, i_params->dmd2_srch_algo);
-
-		if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) {
-			i_params->tuner2_bw = 2 * 36000000;
-
-			stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x00);
-			stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x70);
-
-			stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod);
-		} else {
-			stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x20);
-			stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0xd2);
-
-			if (i_params->dmd2_symbol_rate < 2000000)
-				stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x63);
-			else
-				stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x70);
-
-			if (i_params->dmd2_symbol_rate >= 10000000)
-				stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38);
-			else
-				stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x60);
-
-			if (i_params->chip_id >= 0x20) {
-				stv0900_write_reg(i_params, R0900_P2_KREFTMG, 0x5a);
-
-				if (i_params->dmd2_srch_algo == STV0900_COLD_START)
-					i_params->tuner2_bw = (15 * (stv0900_carrier_width(i_params->dmd2_symbol_rate,
-							i_params->rolloff) + 10000000)) / 10;
-				else if (i_params->dmd2_srch_algo == STV0900_WARM_START)
-					i_params->tuner2_bw = stv0900_carrier_width(i_params->dmd2_symbol_rate,
-							i_params->rolloff) + 10000000;
-			} else {
-				stv0900_write_reg(i_params, R0900_P2_KREFTMG, 0xc1);
-				i_params->tuner2_bw = (15 * (stv0900_carrier_width(i_params->dmd2_symbol_rate,
-									i_params->rolloff) + 10000000)) / 10;
-			}
-
-			stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01);
-
-			stv0900_set_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod);
-			stv0900_set_max_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod);
-			stv0900_set_min_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod);
-			if (i_params->dmd2_symbol_rate >= 10000000)
-				low_sr = FALSE;
-			else
-				low_sr = TRUE;
-
-		}
-
-		stv0900_set_tuner(fe, i_params->tuner2_freq, i_params->tuner2_bw);
-
-		stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, i_params->dmd2_srch_iq_inv);
-		stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1);
-
-		stv0900_set_search_standard(i_params, demod);
-
-		if (i_params->dmd2_srch_algo != STV0900_BLIND_SEARCH)
-			stv0900_start_search(i_params, demod);
-		break;
 	}
 
-	if (i_params->chip_id == 0x12) {
-		stv0900_write_bits(i_params, stream_merger_field, 0);
+	stv0900_set_tuner(fe, intp->freq[demod], intp->bw[demod]);
+
+	agc1_power = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1),
+				stv0900_get_bits(intp, AGCIQ_VALUE0));
+
+	aq_power = 0;
+
+	if (agc1_power == 0) {
+		for (i = 0; i < 5; i++)
+			aq_power += (stv0900_get_bits(intp, POWER_I) +
+					stv0900_get_bits(intp, POWER_Q)) / 2;
+
+		aq_power /= 5;
+	}
+
+	if ((agc1_power == 0) && (aq_power < IQPOWER_THRESHOLD)) {
+		intp->result[demod].locked = FALSE;
+		signal_type = STV0900_NOAGC1;
+		dprintk("%s: NO AGC1, POWERI, POWERQ\n", __func__);
+	} else {
+		stv0900_write_bits(intp, SPECINV_CONTROL,
+					intp->srch_iq_inv[demod]);
+		if (intp->chip_id <= 0x20) /*cut 2.0*/
+			stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
+		else /*cut 3.0*/
+			stv0900_write_bits(intp, MANUALS2_ROLLOFF, 1);
+
+		stv0900_set_search_standard(intp, demod);
+
+		if (intp->srch_algo[demod] != STV0900_BLIND_SEARCH)
+			stv0900_start_search(intp, demod);
+	}
+
+	if (signal_type == STV0900_NOAGC1)
+		return signal_type;
+
+	if (intp->chip_id == 0x12) {
+		stv0900_write_bits(intp, RST_HWARE, 0);
 		msleep(3);
-		stv0900_write_bits(i_params, stream_merger_field, 1);
-		stv0900_write_bits(i_params, stream_merger_field, 0);
+		stv0900_write_bits(intp, RST_HWARE, 1);
+		stv0900_write_bits(intp, RST_HWARE, 0);
 	}
 
 	if (algo == STV0900_BLIND_SEARCH)
@@ -2736,12 +1923,12 @@
 	else if (algo == STV0900_COLD_START)
 		lock = stv0900_get_demod_cold_lock(fe, demod_timeout);
 	else if (algo == STV0900_WARM_START)
-		lock = stv0900_get_demod_lock(i_params, demod, demod_timeout);
+		lock = stv0900_get_demod_lock(intp, demod, demod_timeout);
 
 	if ((lock == FALSE) && (algo == STV0900_COLD_START)) {
 		if (low_sr == FALSE) {
-			if (stv0900_check_timing_lock(i_params, demod) == TRUE)
-				lock = stv0900_sw_algo(i_params, demod);
+			if (stv0900_check_timing_lock(intp, demod) == TRUE)
+				lock = stv0900_sw_algo(intp, demod);
 		}
 	}
 
@@ -2750,98 +1937,64 @@
 
 	if ((lock == TRUE) && (signal_type == STV0900_RANGEOK)) {
 		stv0900_track_optimization(fe);
-		if (i_params->chip_id <= 0x11) {
-			if ((stv0900_get_standard(fe, STV0900_DEMOD_1) == STV0900_DVBS1_STANDARD) && (stv0900_get_standard(fe, STV0900_DEMOD_2) == STV0900_DVBS1_STANDARD)) {
+		if (intp->chip_id <= 0x11) {
+			if ((stv0900_get_standard(fe, 0) ==
+						STV0900_DVBS1_STANDARD) &&
+			   (stv0900_get_standard(fe, 1) ==
+						STV0900_DVBS1_STANDARD)) {
 				msleep(20);
-				stv0900_write_bits(i_params, stream_merger_field, 0);
+				stv0900_write_bits(intp, RST_HWARE, 0);
 			} else {
-				stv0900_write_bits(i_params, stream_merger_field, 0);
+				stv0900_write_bits(intp, RST_HWARE, 0);
 				msleep(3);
-				stv0900_write_bits(i_params, stream_merger_field, 1);
-				stv0900_write_bits(i_params, stream_merger_field, 0);
+				stv0900_write_bits(intp, RST_HWARE, 1);
+				stv0900_write_bits(intp, RST_HWARE, 0);
 			}
-		} else if (i_params->chip_id == 0x20) {
-			stv0900_write_bits(i_params, stream_merger_field, 0);
+
+		} else if (intp->chip_id >= 0x20) {
+			stv0900_write_bits(intp, RST_HWARE, 0);
 			msleep(3);
-			stv0900_write_bits(i_params, stream_merger_field, 1);
-			stv0900_write_bits(i_params, stream_merger_field, 0);
+			stv0900_write_bits(intp, RST_HWARE, 1);
+			stv0900_write_bits(intp, RST_HWARE, 0);
 		}
 
-		if (stv0900_wait_for_lock(i_params, demod, fec_timeout, fec_timeout) == TRUE) {
+		if (stv0900_wait_for_lock(intp, demod,
+					fec_timeout, fec_timeout) == TRUE) {
 			lock = TRUE;
-			switch (demod) {
-			case STV0900_DEMOD_1:
-			default:
-				i_params->dmd1_rslts.locked = TRUE;
-				if (i_params->dmd1_rslts.standard == STV0900_DVBS2_STANDARD) {
-					stv0900_set_dvbs2_rolloff(i_params, demod);
-					stv0900_write_reg(i_params, R0900_P1_PDELCTRL2, 0x40);
-					stv0900_write_reg(i_params, R0900_P1_PDELCTRL2, 0);
-					stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x67);
-				} else {
-					stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75);
-				}
-
-				stv0900_write_reg(i_params, R0900_P1_FBERCPT4, 0);
-				stv0900_write_reg(i_params, R0900_P1_ERRCTRL2, 0xc1);
-				break;
-			case STV0900_DEMOD_2:
-				i_params->dmd2_rslts.locked = TRUE;
-
-				if (i_params->dmd2_rslts.standard == STV0900_DVBS2_STANDARD) {
-					stv0900_set_dvbs2_rolloff(i_params, demod);
-					stv0900_write_reg(i_params, R0900_P2_PDELCTRL2, 0x60);
-					stv0900_write_reg(i_params, R0900_P2_PDELCTRL2, 0x20);
-					stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x67);
-				} else {
-					stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75);
-				}
-
-				stv0900_write_reg(i_params, R0900_P2_FBERCPT4, 0);
-
-				stv0900_write_reg(i_params, R0900_P2_ERRCTRL2, 0xc1);
-				break;
+			intp->result[demod].locked = TRUE;
+			if (intp->result[demod].standard ==
+						STV0900_DVBS2_STANDARD) {
+				stv0900_set_dvbs2_rolloff(intp, demod);
+				stv0900_write_bits(intp, RESET_UPKO_COUNT, 1);
+				stv0900_write_bits(intp, RESET_UPKO_COUNT, 0);
+				stv0900_write_reg(intp, ERRCTRL1, 0x67);
+			} else {
+				stv0900_write_reg(intp, ERRCTRL1, 0x75);
 			}
+
+			stv0900_write_reg(intp, FBERCPT4, 0);
+			stv0900_write_reg(intp, ERRCTRL2, 0xc1);
 		} else {
 			lock = FALSE;
 			signal_type = STV0900_NODATA;
-			no_signal = stv0900_check_signal_presence(i_params, demod);
+			no_signal = stv0900_check_signal_presence(intp, demod);
 
-			switch (demod) {
-			case STV0900_DEMOD_1:
-			default:
-				i_params->dmd1_rslts.locked = FALSE;
-				break;
-			case STV0900_DEMOD_2:
-				i_params->dmd2_rslts.locked = FALSE;
-				break;
-			}
+				intp->result[demod].locked = FALSE;
 		}
 	}
 
-	if ((signal_type == STV0900_NODATA) && (no_signal == FALSE)) {
-		switch (demod) {
-		case STV0900_DEMOD_1:
-		default:
-			if (i_params->chip_id <= 0x11) {
-				if ((stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS_FOUND) &&
-						(i_params->dmd1_srch_iq_inv <= STV0900_IQ_AUTO_NORMAL_FIRST))
-					signal_type = stv0900_dvbs1_acq_workaround(fe);
-			} else
-				i_params->dmd1_rslts.locked = FALSE;
+	if ((signal_type != STV0900_NODATA) || (no_signal != FALSE))
+		return signal_type;
 
-			break;
-		case STV0900_DEMOD_2:
-			if (i_params->chip_id <= 0x11) {
-				if ((stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS_FOUND) &&
-						(i_params->dmd2_srch_iq_inv <= STV0900_IQ_AUTO_NORMAL_FIRST))
-					signal_type = stv0900_dvbs1_acq_workaround(fe);
-			} else
-				i_params->dmd2_rslts.locked = FALSE;
-			break;
-		}
+	if (intp->chip_id > 0x11) {
+		intp->result[demod].locked = FALSE;
+		return signal_type;
 	}
 
+	if ((stv0900_get_bits(intp, HEADER_MODE) == STV0900_DVBS_FOUND) &&
+	   (intp->srch_iq_inv[demod] <= STV0900_IQ_AUTO_NORMAL_FIRST))
+		signal_type = stv0900_dvbs1_acq_workaround(fe);
+
 	return signal_type;
 }
 
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c
index 488bdfb..48edd54 100644
--- a/drivers/media/dvb/frontends/stv090x.c
+++ b/drivers/media/dvb/frontends/stv090x.c
@@ -825,7 +825,7 @@
 		sym /= (state->mclk >> 7);
 	}
 
-	if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0xff)) < 0) /* MSB */
+	if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0x7f)) < 0) /* MSB */
 		goto err;
 	if (STV090x_WRITE_DEMOD(state, SFRLOW0, (sym & 0xff)) < 0) /* LSB */
 		goto err;
@@ -1238,6 +1238,8 @@
 				goto err;
 		}
 
+		if (stv090x_set_vit_thtracq(state) < 0)
+			goto err;
 		break;
 
 	case STV090x_SEARCH_AUTO:
@@ -1278,17 +1280,8 @@
 				goto err;
 		}
 
-		if (state->srate >= 2000000) {
-			/* Srate >= 2MSPS, Viterbi threshold to acquire */
-			if (stv090x_set_vit_thacq(state) < 0)
-				goto err;
-		} else {
-			/* Srate < 2MSPS, Reset Viterbi thresholdto track
-			 * and then re-acquire
-			 */
-			if (stv090x_set_vit_thtracq(state) < 0)
-				goto err;
-		}
+		if (stv090x_set_vit_thacq(state) < 0)
+			goto err;
 
 		if (stv090x_set_viterbi(state) < 0)
 			goto err;
@@ -1317,7 +1310,7 @@
 				goto err;
 			if (STV090x_WRITE_DEMOD(state, CFRUP1, 0x0f) < 0)
 				goto err;
-			if (STV090x_WRITE_DEMOD(state, CFRUP1, 0xff) < 0)
+			if (STV090x_WRITE_DEMOD(state, CFRUP0, 0xff) < 0)
 				goto err;
 			if (STV090x_WRITE_DEMOD(state, CFRLOW1, 0xf0) < 0)
 				goto err;
@@ -1371,7 +1364,7 @@
 
 		if (STV090x_WRITE_DEMOD(state, CFRUP1, MSB(freq)) < 0)
 			goto err;
-		if (STV090x_WRITE_DEMOD(state, CFRUP1, LSB(freq)) < 0)
+		if (STV090x_WRITE_DEMOD(state, CFRUP0, LSB(freq)) < 0)
 			goto err;
 
 		freq *= -1;
@@ -1422,6 +1415,9 @@
 	if (STV090x_WRITE_DEMOD(state, DMDCFG2, reg) < 0)
 		goto err;
 
+	if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0)
+		goto err;
+
 	if (state->dev_ver >= 0x20) {
 		/*Frequency offset detector setting*/
 		if (state->srate < 2000000) {
@@ -1430,20 +1426,22 @@
 				if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x39) < 0)
 					goto err;
 			} else {
-				/* Cut 2 */
+				/* Cut 3 */
 				if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x89) < 0)
 					goto err;
 			}
 			if (STV090x_WRITE_DEMOD(state, CARHDR, 0x40) < 0)
 				goto err;
-		}
-
-		if (state->srate < 10000000) {
+		} else if (state->srate < 10000000) {
 			if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4c) < 0)
 				goto err;
+			if (STV090x_WRITE_DEMOD(state, CARHDR, 0x20) < 0)
+				goto err;
 		} else {
 			if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4b) < 0)
 				goto err;
+			if (STV090x_WRITE_DEMOD(state, CARHDR, 0x20) < 0)
+				goto err;
 		}
 	} else {
 		if (state->srate < 10000000) {
@@ -1485,14 +1483,14 @@
 
 static int stv090x_get_agc2_min_level(struct stv090x_state *state)
 {
-	u32 agc2_min = 0, agc2 = 0, freq_init, freq_step, reg;
+	u32 agc2_min = 0xffff, agc2 = 0, freq_init, freq_step, reg;
 	s32 i, j, steps, dir;
 
 	if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
 		goto err;
 	reg = STV090x_READ_DEMOD(state, DMDCFGMD);
-	STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 1);
-	STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 1);
+	STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0);
+	STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0);
 	if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
 		goto err;
 
@@ -1509,10 +1507,8 @@
 	if (stv090x_set_srate(state, 1000000) < 0)
 		goto err;
 
-	steps  = -1 + state->search_range / 1000000;
-	steps /= 2;
-	steps  = (2 * steps) + 1;
-	if (steps < 0)
+	steps  = state->search_range / 1000000;
+	if (steps <= 0)
 		steps = 1;
 
 	dir = 1;
@@ -1525,7 +1521,7 @@
 		else
 			freq_init = freq_init - (freq_step * i);
 
-		dir = -1;
+		dir *= -1;
 
 		if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod RESET */
 			goto err;
@@ -1536,13 +1532,14 @@
 		if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x58) < 0) /* Demod RESET */
 			goto err;
 		msleep(10);
+
+		agc2 = 0;
 		for (j = 0; j < 10; j++) {
-			agc2 += STV090x_READ_DEMOD(state, AGC2I1) << 8;
-			agc2 |= STV090x_READ_DEMOD(state, AGC2I0);
+			agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) |
+				STV090x_READ_DEMOD(state, AGC2I0);
 		}
 		agc2 /= 10;
-		agc2_min = 0xffff;
-		if (agc2 < 0xffff)
+		if (agc2 < agc2_min)
 			agc2_min = agc2;
 	}
 
@@ -1584,6 +1581,12 @@
 	int tmg_lock = 0, i;
 	s32 tmg_cpt = 0, dir = 1, steps, cur_step = 0, freq;
 	u32 srate_coarse = 0, agc2 = 0, car_step = 1200, reg;
+	u32 agc2th;
+
+	if (state->dev_ver >= 0x30)
+		agc2th = 0x2e00;
+	else
+		agc2th = 0x1f00;
 
 	reg = STV090x_READ_DEMOD(state, DMDISTATE);
 	STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f); /* Demod RESET */
@@ -1591,13 +1594,15 @@
 		goto err;
 	if (STV090x_WRITE_DEMOD(state, TMGCFG, 0x12) < 0)
 		goto err;
+	if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc0) < 0)
+		goto err;
 	if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0xf0) < 0)
 		goto err;
 	if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0xe0) < 0)
 		goto err;
 	reg = STV090x_READ_DEMOD(state, DMDCFGMD);
 	STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 1);
-	STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 1);
+	STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0);
 	if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
 		goto err;
 
@@ -1611,13 +1616,13 @@
 		goto err;
 	if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0)
 		goto err;
-	if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x60) < 0)
+	if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x50) < 0)
 		goto err;
 
 	if (state->dev_ver >= 0x30) {
 		if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x99) < 0)
 			goto err;
-		if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0)
+		if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x98) < 0)
 			goto err;
 
 	} else if (state->dev_ver >= 0x20) {
@@ -1652,23 +1657,31 @@
 	while ((!tmg_lock) && (cur_step < steps)) {
 		if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5f) < 0) /* Demod RESET */
 			goto err;
-		reg = STV090x_READ_DEMOD(state, DMDISTATE);
-		STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x00); /* trigger acquisition */
-		if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0)
+		if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0)
+			goto err;
+		if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
+			goto err;
+		if (STV090x_WRITE_DEMOD(state, SFRINIT1, 0x00) < 0)
+			goto err;
+		if (STV090x_WRITE_DEMOD(state, SFRINIT0, 0x00) < 0)
+			goto err;
+		/* trigger acquisition */
+		if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x40) < 0)
 			goto err;
 		msleep(50);
 		for (i = 0; i < 10; i++) {
 			reg = STV090x_READ_DEMOD(state, DSTATUS);
 			if (STV090x_GETFIELD_Px(reg, TMGLOCK_QUALITY_FIELD) >= 2)
 				tmg_cpt++;
-			agc2 += STV090x_READ_DEMOD(state, AGC2I1) << 8;
-			agc2 |= STV090x_READ_DEMOD(state, AGC2I0);
+			agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) |
+				STV090x_READ_DEMOD(state, AGC2I0);
 		}
 		agc2 /= 10;
 		srate_coarse = stv090x_get_srate(state, state->mclk);
 		cur_step++;
 		dir *= -1;
-		if ((tmg_cpt >= 5) && (agc2 < 0x1f00) && (srate_coarse < 55000000) && (srate_coarse > 850000))
+		if ((tmg_cpt >= 5) && (agc2 < agc2th) &&
+		    (srate_coarse < 50000000) && (srate_coarse > 850000))
 			tmg_lock = 1;
 		else if (cur_step < steps) {
 			if (dir > 0)
@@ -1681,7 +1694,7 @@
 				goto err;
 
 			if (state->config->tuner_set_frequency) {
-				if (state->config->tuner_set_frequency(fe, state->frequency) < 0)
+				if (state->config->tuner_set_frequency(fe, freq) < 0)
 					goto err;
 			}
 
@@ -1738,7 +1751,7 @@
 	else {
 		if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) /* Demod RESET */
 			goto err;
-		if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0x01) < 0)
+		if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0)
 			goto err;
 		if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0x20) < 0)
 			goto err;
@@ -1751,6 +1764,9 @@
 		if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
 			goto err;
 
+		if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
+			goto err;
+
 		if (state->dev_ver >= 0x30) {
 			if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x79) < 0)
 				goto err;
@@ -1856,12 +1872,12 @@
 static int stv090x_blind_search(struct stv090x_state *state)
 {
 	u32 agc2, reg, srate_coarse;
-	s32 timeout_dmd = 500, cpt_fail, agc2_ovflw, i;
+	s32 cpt_fail, agc2_ovflw, i;
 	u8 k_ref, k_max, k_min;
 	int coarse_fail, lock;
 
-	k_max = 120;
-	k_min = 30;
+	k_max = 110;
+	k_min = 10;
 
 	agc2 = stv090x_get_agc2_min_level(state);
 
@@ -1900,7 +1916,8 @@
 				srate_coarse = stv090x_srate_srch_fine(state);
 				if (srate_coarse != 0) {
 					stv090x_get_lock_tmg(state);
-					lock = stv090x_get_dmdlock(state, timeout_dmd);
+					lock = stv090x_get_dmdlock(state,
+							state->DemodTimeout);
 				} else {
 					lock = 0;
 				}
@@ -1908,8 +1925,8 @@
 				cpt_fail = 0;
 				agc2_ovflw = 0;
 				for (i = 0; i < 10; i++) {
-					agc2  = STV090x_READ_DEMOD(state, AGC2I1) << 8;
-					agc2 |= STV090x_READ_DEMOD(state, AGC2I0);
+					agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) |
+						STV090x_READ_DEMOD(state, AGC2I0);
 					if (agc2 >= 0xff00)
 						agc2_ovflw++;
 					reg = STV090x_READ_DEMOD(state, DSTATUS2);
@@ -1923,7 +1940,7 @@
 
 				lock = 0;
 			}
-			k_ref -= 30;
+			k_ref -= 20;
 		} while ((k_ref >= k_min) && (!lock) && (!coarse_fail));
 	}
 
@@ -2062,7 +2079,7 @@
 						goto err;
 
 					if (state->config->tuner_set_frequency) {
-						if (state->config->tuner_set_frequency(fe, state->frequency) < 0)
+						if (state->config->tuner_set_frequency(fe, freq) < 0)
 							goto err;
 					}
 
@@ -2093,17 +2110,6 @@
 						goto err;
 
 					STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c);
-					if (state->delsys == STV090x_DVBS2) {
-						reg = STV090x_READ_DEMOD(state, DMDCFGMD);
-						STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0);
-						STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
-						if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
-							goto err;
-						STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
-						STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
-						if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
-							goto err;
-					}
 					if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0)
 						goto err;
 					if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
@@ -2425,7 +2431,7 @@
 
 	derot = (int_1 * int_2) +
 		((int_1 * tmp_2) >> 12) +
-		((int_1 * tmp_1) >> 12);
+		((int_2 * tmp_1) >> 12);
 
 	return derot;
 }
@@ -2732,7 +2738,7 @@
 	switch (state->delsys) {
 	case STV090x_DVBS1:
 	case STV090x_DSS:
-		if (state->algo == STV090x_SEARCH_AUTO) {
+		if (state->search_mode == STV090x_SEARCH_AUTO) {
 			reg = STV090x_READ_DEMOD(state, DMDCFGMD);
 			STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
 			STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
@@ -2857,6 +2863,9 @@
 		if (stv090x_set_srate(state, srate) < 0)
 			goto err;
 		blind_tune = 1;
+
+		if (stv090x_dvbs_track_crl(state) < 0)
+			goto err;
 	}
 
 	if (state->dev_ver >= 0x20) {
@@ -3042,7 +3051,7 @@
 	struct dvb_frontend *fe = &state->frontend;
 	enum stv090x_signal_state signal_state = STV090x_NOCARRIER;
 	u32 reg;
-	s32 timeout_dmd = 500, timeout_fec = 50, agc1_power, power_iq = 0, i;
+	s32 agc1_power, power_iq = 0, i;
 	int lock = 0, low_sr = 0, no_signal = 0;
 
 	reg = STV090x_READ_DEMOD(state, TSCFGH);
@@ -3054,8 +3063,13 @@
 		goto err;
 
 	if (state->dev_ver >= 0x20) {
-		if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) /* cut 2.0 */
-			goto err;
+		if (state->srate > 5000000) {
+			if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0)
+				goto err;
+		} else {
+			if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x82) < 0)
+				goto err;
+		}
 	}
 
 	stv090x_get_lock_tmg(state);
@@ -3175,7 +3189,7 @@
 	if ((agc1_power == 0) && (power_iq < STV090x_IQPOWER_THRESHOLD)) {
 		dprintk(FE_ERROR, 1, "No Signal: POWER_IQ=0x%02x", power_iq);
 		lock = 0;
-
+		signal_state = STV090x_NOAGC1;
 	} else {
 		reg = STV090x_READ_DEMOD(state, DEMOD);
 		STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, state->inversion);
@@ -3199,18 +3213,17 @@
 		}
 	}
 
-	/* need to check for AGC1 state */
-
-
+	if (signal_state == STV090x_NOAGC1)
+		return signal_state;
 
 	if (state->algo == STV090x_BLIND_SEARCH)
 		lock = stv090x_blind_search(state);
 
 	else if (state->algo == STV090x_COLD_SEARCH)
-		lock = stv090x_get_coldlock(state, timeout_dmd);
+		lock = stv090x_get_coldlock(state, state->DemodTimeout);
 
 	else if (state->algo == STV090x_WARM_SEARCH)
-		lock = stv090x_get_dmdlock(state, timeout_dmd);
+		lock = stv090x_get_dmdlock(state, state->DemodTimeout);
 
 	if ((!lock) && (state->algo == STV090x_COLD_SEARCH)) {
 		if (!low_sr) {
@@ -3245,8 +3258,9 @@
 				goto err;
 		}
 
-		if (stv090x_get_lock(state, timeout_fec, timeout_fec)) {
-			lock = 1;
+		lock = stv090x_get_lock(state, state->FecTimeout,
+				state->FecTimeout);
+		if (lock) {
 			if (state->delsys == STV090x_DVBS2) {
 				stv090x_set_s2rolloff(state);
 
@@ -3273,7 +3287,6 @@
 			if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0)
 				goto err;
 		} else {
-			lock = 0;
 			signal_state = STV090x_NODATA;
 			no_signal = stv090x_chk_signal(state);
 		}
@@ -3296,7 +3309,13 @@
 	state->search_mode = STV090x_SEARCH_AUTO;
 	state->algo = STV090x_COLD_SEARCH;
 	state->fec = STV090x_PRERR;
-	state->search_range = 2000000;
+	if (state->srate > 10000000) {
+		dprintk(FE_DEBUG, 1, "Search range: 10 MHz");
+		state->search_range = 10000000;
+	} else {
+		dprintk(FE_DEBUG, 1, "Search range: 5 MHz");
+		state->search_range = 5000000;
+	}
 
 	if (stv090x_algo(state) == STV090x_RANGEOK) {
 		dprintk(FE_DEBUG, 1, "Search success!");
@@ -3309,7 +3328,6 @@
 	return DVBFE_ALGO_SEARCH_ERROR;
 }
 
-/* FIXME! */
 static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status)
 {
 	struct stv090x_state *state = fe->demodulator_priv;
@@ -3331,9 +3349,15 @@
 		dprintk(FE_DEBUG, 1, "Delivery system: DVB-S2");
 		reg = STV090x_READ_DEMOD(state, DSTATUS);
 		if (STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD)) {
-			reg = STV090x_READ_DEMOD(state, TSSTATUS);
-			if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) {
-				*status = FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+			reg = STV090x_READ_DEMOD(state, PDELSTATUS1);
+			if (STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD)) {
+				reg = STV090x_READ_DEMOD(state, TSSTATUS);
+				if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) {
+					*status = FE_HAS_CARRIER |
+						  FE_HAS_VITERBI |
+						  FE_HAS_SYNC |
+						  FE_HAS_LOCK;
+				}
 			}
 		}
 		break;
@@ -3412,14 +3436,12 @@
 	int res = 0;
 	int min = 0, med;
 
-	if (val < tab[min].read)
-		res = tab[min].real;
-	else if (val >= tab[max].read)
-		res = tab[max].real;
-	else {
+	if ((val >= tab[min].read && val < tab[max].read) ||
+	    (val >= tab[max].read && val < tab[min].read)) {
 		while ((max - min) > 1) {
 			med = (max + min) / 2;
-			if (val >= tab[min].read && val < tab[med].read)
+			if ((val >= tab[min].read && val < tab[med].read) ||
+			    (val >= tab[med].read && val < tab[min].read))
 				max = med;
 			else
 				min = med;
@@ -3428,6 +3450,18 @@
 		       (tab[max].real - tab[min].real) /
 		       (tab[max].read - tab[min].read)) +
 			tab[min].real;
+	} else {
+		if (tab[min].read < tab[max].read) {
+			if (val < tab[min].read)
+				res = tab[min].real;
+			else if (val >= tab[max].read)
+				res = tab[max].real;
+		} else {
+			if (val >= tab[min].read)
+				res = tab[min].real;
+			else if (val < tab[max].read)
+				res = tab[max].real;
+		}
 	}
 
 	return res;
@@ -3437,16 +3471,22 @@
 {
 	struct stv090x_state *state = fe->demodulator_priv;
 	u32 reg;
-	s32 agc;
+	s32 agc_0, agc_1, agc;
+	s32 str;
 
 	reg = STV090x_READ_DEMOD(state, AGCIQIN1);
-	agc = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD);
+	agc_1 = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD);
+	reg = STV090x_READ_DEMOD(state, AGCIQIN0);
+	agc_0 = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD);
+	agc = MAKEWORD16(agc_1, agc_0);
 
-	*strength = stv090x_table_lookup(stv090x_rf_tab, ARRAY_SIZE(stv090x_rf_tab) - 1, agc);
+	str = stv090x_table_lookup(stv090x_rf_tab,
+		ARRAY_SIZE(stv090x_rf_tab) - 1, agc);
 	if (agc > stv090x_rf_tab[0].read)
-		*strength = 5;
+		str = 0;
 	else if (agc < stv090x_rf_tab[ARRAY_SIZE(stv090x_rf_tab) - 1].read)
-		*strength = -100;
+		str = -100;
+	*strength = (str + 100) * 0xFFFF / 100;
 
 	return 0;
 }
@@ -3457,6 +3497,8 @@
 	u32 reg_0, reg_1, reg, i;
 	s32 val_0, val_1, val = 0;
 	u8 lock_f;
+	s32 div;
+	u32 last;
 
 	switch (state->delsys) {
 	case STV090x_DVBS2:
@@ -3468,14 +3510,15 @@
 				reg_1 = STV090x_READ_DEMOD(state, NNOSPLHT1);
 				val_1 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD);
 				reg_0 = STV090x_READ_DEMOD(state, NNOSPLHT0);
-				val_0 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD);
+				val_0 = STV090x_GETFIELD_Px(reg_0, NOSPLHT_NORMED_FIELD);
 				val  += MAKEWORD16(val_1, val_0);
 				msleep(1);
 			}
 			val /= 16;
-			*cnr = stv090x_table_lookup(stv090x_s2cn_tab, ARRAY_SIZE(stv090x_s2cn_tab) - 1, val);
-			if (val < stv090x_s2cn_tab[ARRAY_SIZE(stv090x_s2cn_tab) - 1].read)
-				*cnr = 1000;
+			last = ARRAY_SIZE(stv090x_s2cn_tab) - 1;
+			div = stv090x_s2cn_tab[0].read -
+			      stv090x_s2cn_tab[last].read;
+			*cnr = 0xFFFF - ((val * 0xFFFF) / div);
 		}
 		break;
 
@@ -3489,14 +3532,15 @@
 				reg_1 = STV090x_READ_DEMOD(state, NOSDATAT1);
 				val_1 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD);
 				reg_0 = STV090x_READ_DEMOD(state, NOSDATAT0);
-				val_0 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD);
+				val_0 = STV090x_GETFIELD_Px(reg_0, NOSDATAT_UNNORMED_FIELD);
 				val  += MAKEWORD16(val_1, val_0);
 				msleep(1);
 			}
 			val /= 16;
-			*cnr = stv090x_table_lookup(stv090x_s1cn_tab, ARRAY_SIZE(stv090x_s1cn_tab) - 1, val);
-			if (val < stv090x_s2cn_tab[ARRAY_SIZE(stv090x_s1cn_tab) - 1].read)
-				*cnr = 1000;
+			last = ARRAY_SIZE(stv090x_s1cn_tab) - 1;
+			div = stv090x_s1cn_tab[0].read -
+			      stv090x_s1cn_tab[last].read;
+			*cnr = 0xFFFF - ((val * 0xFFFF) / div);
 		}
 		break;
 	default:
@@ -3732,6 +3776,8 @@
 {
 	u32 reg = 0;
 
+	reg = stv090x_read_reg(state, STV090x_GENCFG);
+
 	switch (ldpc_mode) {
 	case STV090x_DUAL:
 	default:
diff --git a/drivers/media/dvb/frontends/stv090x_priv.h b/drivers/media/dvb/frontends/stv090x_priv.h
index 5a4a017..5921a8d 100644
--- a/drivers/media/dvb/frontends/stv090x_priv.h
+++ b/drivers/media/dvb/frontends/stv090x_priv.h
@@ -83,7 +83,7 @@
 
 #define STV090x_IQPOWER_THRESHOLD	  30
 #define STV090x_SEARCH_AGC2_TH_CUT20	 700
-#define STV090x_SEARCH_AGC2_TH_CUT30	1200
+#define STV090x_SEARCH_AGC2_TH_CUT30	1400
 
 #define STV090x_SEARCH_AGC2_TH(__ver)	\
 	((__ver <= 0x20) ?		\
@@ -91,6 +91,7 @@
 	STV090x_SEARCH_AGC2_TH_CUT30)
 
 enum stv090x_signal_state {
+	STV090x_NOAGC1,
 	STV090x_NOCARRIER,
 	STV090x_NODATA,
 	STV090x_DATAOK,
diff --git a/drivers/media/dvb/frontends/stv090x_reg.h b/drivers/media/dvb/frontends/stv090x_reg.h
index 57b6abb..2502855 100644
--- a/drivers/media/dvb/frontends/stv090x_reg.h
+++ b/drivers/media/dvb/frontends/stv090x_reg.h
@@ -44,7 +44,7 @@
 #define STV090x_OFFST_OUTSERRS2_HZ_FIELD	5
 #define STV090x_WIDTH_OUTSERRS2_HZ_FIELD	1
 #define STV090x_OFFST_OUTSERRS3_HZ_FIELD	4
-#define STV090x_WIDTH_OUTPARRS3_HZ_FIELD	1
+#define STV090x_WIDTH_OUTSERRS3_HZ_FIELD	1
 #define STV090x_OFFST_OUTPARRS3_HZ_FIELD	3
 #define STV090x_WIDTH_OUTPARRS3_HZ_FIELD	1
 
@@ -113,24 +113,24 @@
 #define STV090x_IRQMASK3			0xf124
 #define STV090x_OFFST_MPLL_LOCK_FIELD		5
 #define STV090x_WIDTH_MPLL_LOCK_FIELD		1
-#define STV090x_OFFST_MSTREAM_LCK_3_FIELD	2
-#define STV090x_WIDTH_MSTREAM_LCK_3_FIELD	3
-#define STV090x_OFFST_MSTREAM_LCK_2_FIELD	2
-#define STV090x_WIDTH_MSTREAM_LCK_2_FIELD	3
+#define STV090x_OFFST_MSTREAM_LCK_3_FIELD	4
+#define STV090x_WIDTH_MSTREAM_LCK_3_FIELD	1
+#define STV090x_OFFST_MSTREAM_LCK_2_FIELD	3
+#define STV090x_WIDTH_MSTREAM_LCK_2_FIELD	1
 #define STV090x_OFFST_MSTREAM_LCK_1_FIELD	2
-#define STV090x_WIDTH_MSTREAM_LCK_1_FIELD	3
+#define STV090x_WIDTH_MSTREAM_LCK_1_FIELD	1
 #define STV090x_OFFST_MDVBS1_PRF_2_FIELD	1
 #define STV090x_WIDTH_MDVBS1_PRF_2_FIELD	1
 #define STV090x_OFFST_MDVBS1_PRF_1_FIELD	0
 #define STV090x_WIDTH_MDVBS1_PRF_1_FIELD	1
 
 #define STV090x_IRQMASK2			0xf125
-#define STV090x_OFFST_MSPY_ENDSIM_3_FIELD	5
-#define STV090x_WIDTH_MSPY_ENDSIM_3_FIELD	3
-#define STV090x_OFFST_MSPY_ENDSIM_2_FIELD	5
-#define STV090x_WIDTH_MSPY_ENDSIM_2_FIELD	3
+#define STV090x_OFFST_MSPY_ENDSIM_3_FIELD	7
+#define STV090x_WIDTH_MSPY_ENDSIM_3_FIELD	1
+#define STV090x_OFFST_MSPY_ENDSIM_2_FIELD	6
+#define STV090x_WIDTH_MSPY_ENDSIM_2_FIELD	1
 #define STV090x_OFFST_MSPY_ENDSIM_1_FIELD	5
-#define STV090x_WIDTH_MSPY_ENDSIM_1_FIELD	3
+#define STV090x_WIDTH_MSPY_ENDSIM_1_FIELD	1
 #define STV090x_OFFST_MPKTDEL_ERROR_2_FIELD	4
 #define STV090x_WIDTH_MPKTDEL_ERROR_2_FIELD	1
 #define STV090x_OFFST_MPKTDEL_LOCKB_2_FIELD	3
@@ -370,7 +370,7 @@
 #define STV090x_OFFST_SELX1RATIO_FIELD		5
 #define STV090x_WIDTH_SELX1RATIO_FIELD		1
 #define STV090x_OFFST_STOP_PLL_FIELD		3
-#define STV090x_WIDTH_SELX1RATIO_FIELD		1
+#define STV090x_WIDTH_STOP_PLL_FIELD		1
 #define STV090x_OFFST_BYPASSPLLFSK_FIELD	2
 #define STV090x_WIDTH_BYPASSPLLFSK_FIELD	1
 #define STV090x_OFFST_SELOSCI_FIELD		1
@@ -616,7 +616,7 @@
 #define STV090x_OFFST_Px_CONT_TONE_FIELD	4
 #define STV090x_WIDTH_Px_CONT_TONE_FIELD	1
 #define STV090x_OFFST_Px_FIFO_4BREADY_FIELD	3
-#define STV090x_WIDTH_Px_FIFO_4BREADY_FIELD	2
+#define STV090x_WIDTH_Px_FIFO_4BREADY_FIELD	1
 #define STV090x_OFFST_Px_FIFO_EMPTY_FIELD	2
 #define STV090x_WIDTH_Px_FIFO_EMPTY_FIELD	1
 #define STV090x_OFFST_Px_ABORT_DISRX_FIELD	0
@@ -847,12 +847,10 @@
 #define STV090x_WIDTH_Px_DVBS2_ENABLE_FIELD	1
 #define STV090x_OFFST_Px_DVBS1_ENABLE_FIELD	6
 #define STV090x_WIDTH_Px_DVBS1_ENABLE_FIELD	1
-#define STV090x_OFFST_Px_CFR_AUTOSCAN_FIELD	5 /* check */
-#define STV090x_WIDTH_Px_CFR_AUTOSCAN_FIELD	1
-#define STV090x_OFFST_Px_SCAN_ENABLE_FIELD	4 /* check */
+#define STV090x_OFFST_Px_SCAN_ENABLE_FIELD	4
 #define STV090x_WIDTH_Px_SCAN_ENABLE_FIELD	1
-#define STV090x_OFFST_Px_TUN_AUTOSCAN_FIELD	3
-#define STV090x_WIDTH_Px_TUN_AUTOSCAN_FIELD	1
+#define STV090x_OFFST_Px_CFR_AUTOSCAN_FIELD	3
+#define STV090x_WIDTH_Px_CFR_AUTOSCAN_FIELD	1
 #define STV090x_OFFST_Px_NOFORCE_RELOCK_FIELD	2
 #define STV090x_WIDTH_Px_NOFORCE_RELOCK_FIELD	1
 #define STV090x_OFFST_Px_TUN_RNG_FIELD		0
@@ -885,7 +883,7 @@
 #define STV090x_P2_DMDFLYW			STV090x_Px_DMDFLYW(2)
 #define STV090x_OFFST_Px_I2C_IRQVAL_FIELD	4
 #define STV090x_WIDTH_Px_I2C_IRQVAL_FIELD	4
-#define STV090x_OFFST_Px_FLYWHEEL_CPT_FIELD	0 /* check */
+#define STV090x_OFFST_Px_FLYWHEEL_CPT_FIELD	0
 #define STV090x_WIDTH_Px_FLYWHEEL_CPT_FIELD	4
 
 #define STV090x_Px_DSTATUS3(__x)		(0xF41D - (__x - 1) * 0x200)
@@ -1048,12 +1046,12 @@
 #define STV090x_P1_CFRINC1			STV090x_Px_CFRINC1(1)
 #define STV090x_P2_CFRINC1			STV090x_Px_CFRINC1(2)
 #define STV090x_OFFST_Px_CFR_INC1_FIELD		0
-#define STV090x_WIDTH_Px_CFR_INC1_FIELD		7
+#define STV090x_WIDTH_Px_CFR_INC1_FIELD		7 /* check */
 
 #define STV090x_Px_CFRINC0(__x)			(0xF44B - (__x - 1) * 0x200)
 #define STV090x_P1_CFRINC0			STV090x_Px_CFRINC0(1)
 #define STV090x_P2_CFRINC0			STV090x_Px_CFRINC0(2)
-#define STV090x_OFFST_Px_CFR_INC0_FIELD		4
+#define STV090x_OFFST_Px_CFR_INC0_FIELD		4 /* check */
 #define STV090x_WIDTH_Px_CFR_INC0_FIELD		4
 
 #define STV090x_Pn_CFRy(__x, __y)		(0xF44E - (__x - 1) * 0x200 - __y * 0x1)
@@ -1145,14 +1143,14 @@
 #define STV090x_Px_SFRINIT1(__x)		(0xF45E - (__x - 1) * 0x200)
 #define STV090x_P1_SFRINIT1			STV090x_Px_SFRINIT1(1)
 #define STV090x_P2_SFRINIT1			STV090x_Px_SFRINIT1(2)
-#define STV090x_OFFST_Px_SFR_INIT_FIELD		0
-#define STV090x_WIDTH_Px_SFR_INIT_FIELD		8
+#define STV090x_OFFST_Px_SFR_INIT1_FIELD	0
+#define STV090x_WIDTH_Px_SFR_INIT1_FIELD	7
 
 #define STV090x_Px_SFRINIT0(__x)		(0xF45F - (__x - 1) * 0x200)
 #define STV090x_P1_SFRINIT0			STV090x_Px_SFRINIT0(1)
 #define STV090x_P2_SFRINIT0			STV090x_Px_SFRINIT0(2)
-#define STV090x_OFFST_Px_SFR_INIT_FIELD		0
-#define STV090x_WIDTH_Px_SFR_INIT_FIELD		8
+#define STV090x_OFFST_Px_SFR_INIT0_FIELD	0
+#define STV090x_WIDTH_Px_SFR_INIT0_FIELD	8
 
 #define STV090x_Px_SFRUP1(__x)			(0xF460 - (__x - 1) * 0x200)
 #define STV090x_P1_SFRUP1			STV090x_Px_SFRUP1(1)
@@ -1178,7 +1176,7 @@
 #define STV090x_OFFST_Px_SYMB_FREQ_LOW0_FIELD	0
 #define STV090x_WIDTH_Px_SYMB_FREQ_LOW0_FIELD	8
 
-#define STV090x_Px_SFRy(__x, __y)		(0xF464 - (__x-1) * 0x200 + (3 - __y))
+#define STV090x_Px_SFRy(__x, __y)		(0xF467 - (__x-1) * 0x200 - __y)
 #define STV090x_P1_SFR0				STV090x_Px_SFRy(1, 0)
 #define STV090x_P1_SFR1				STV090x_Px_SFRy(1, 1)
 #define STV090x_P1_SFR2				STV090x_Px_SFRy(1, 2)
@@ -1188,7 +1186,7 @@
 #define STV090x_P2_SFR2				STV090x_Px_SFRy(2, 2)
 #define STV090x_P2_SFR3				STV090x_Px_SFRy(2, 3)
 #define STV090x_OFFST_Px_SYMB_FREQ_FIELD	0
-#define STV090x_WIDTH_Px_SYMB_FREQ_FIELD	32
+#define STV090x_WIDTH_Px_SYMB_FREQ_FIELD	8
 
 #define STV090x_Px_TMGREG2(__x)			(0xF468 - (__x - 1) * 0x200)
 #define STV090x_P1_TMGREG2			STV090x_Px_TMGREG2(1)
@@ -1198,7 +1196,7 @@
 
 #define STV090x_Px_TMGREG1(__x)			(0xF469 - (__x - 1) * 0x200)
 #define STV090x_P1_TMGREG1			STV090x_Px_TMGREG1(1)
-#define STV090x_P2_TMGREG1				STV090x_Px_TMGREG1(2)
+#define STV090x_P2_TMGREG1			STV090x_Px_TMGREG1(2)
 #define STV090x_OFFST_Px_TMGREG_FIELD		0
 #define STV090x_WIDTH_Px_TMGREG_FIELD		8
 
@@ -1230,7 +1228,7 @@
 #define STV090x_OFFST_Px_MU_EQUALDFE_FIELD	0
 #define STV090x_WIDTH_Px_MU_EQUALDFE_FIELD	3
 
-#define STV090x_Px_EQUAIy(__x, __y)		(0xf470 - (__x - 1) * 0x200 + (__y - 1))
+#define STV090x_Px_EQUAIy(__x, __y)	(0xf470 - (__x-1) * 0x200 + 2 * (__y-1))
 #define STV090x_P1_EQUAI1			STV090x_Px_EQUAIy(1, 1)
 #define STV090x_P1_EQUAI2			STV090x_Px_EQUAIy(1, 2)
 #define STV090x_P1_EQUAI3			STV090x_Px_EQUAIy(1, 3)
@@ -1251,7 +1249,7 @@
 #define STV090x_OFFST_Px_EQUA_ACCIy_FIELD	0
 #define STV090x_WIDTH_Px_EQUA_ACCIy_FIELD	8
 
-#define STV090x_Px_EQUAQy(__x, __y)		(0xf471 - (__x - 1) * 0x200 + (__y - 1))
+#define STV090x_Px_EQUAQy(__x, __y)	(0xf471 - (__x-1) * 0x200 + 2 * (__y-1))
 #define STV090x_P1_EQUAQ1			STV090x_Px_EQUAQy(1, 1)
 #define STV090x_P1_EQUAQ2			STV090x_Px_EQUAQy(1, 2)
 #define STV090x_P1_EQUAQ3			STV090x_Px_EQUAQy(1, 3)
@@ -1390,7 +1388,7 @@
 #define STV090x_OFFST_Px_CAR2S2_16A_ALPH_E_FIELD	0
 #define STV090x_WIDTH_Px_CAR2S2_16A_ALPH_E_FIELD	4
 
-#define STV090x_Px_ACLC2S232A(__x)		(0xf499 - (__x - 1) * 0x200)
+#define STV090x_Px_ACLC2S232A(__x)		(0xf49A - (__x - 1) * 0x200)
 #define STV090x_P1_ACLC2S232A			STV090x_Px_ACLC2S232A(1)
 #define STV090x_P2_ACLC2S232A			STV090x_Px_ACLC2S232A(2)
 #define STV090x_OFFST_Px_CAR2S2_32A_ALPH_M_FIELD	4
@@ -1414,7 +1412,7 @@
 #define STV090x_OFFST_Px_CAR2S2_8_BETA_E_FIELD	0
 #define STV090x_WIDTH_Px_CAR2S2_8_BETA_E_FIELD	4
 
-#define STV090x_Px_BCLC2S216A(__x)		(0xf49d - (__x - 1) * 0x200)
+#define STV090x_Px_BCLC2S216A(__x)		(0xf49e - (__x - 1) * 0x200)
 #define STV090x_P1_BCLC2S216A			STV090x_Px_BCLC2S216A(1)
 #define STV090x_P2_BCLC2S216A			STV090x_Px_BCLC2S216A(1)
 #define STV090x_OFFST_Px_CAR2S2_16A_BETA_M_FIELD	4
@@ -1422,7 +1420,7 @@
 #define STV090x_OFFST_Px_CAR2S2_16A_BETA_E_FIELD	0
 #define STV090x_WIDTH_Px_CAR2S2_16A_BETA_E_FIELD	4
 
-#define STV090x_Px_BCLC2S232A(__x)		(0xf49d - (__x - 1) * 0x200)
+#define STV090x_Px_BCLC2S232A(__x)		(0xf49f - (__x - 1) * 0x200)
 #define STV090x_P1_BCLC2S232A			STV090x_Px_BCLC2S232A(1)
 #define STV090x_P2_BCLC2S232A			STV090x_Px_BCLC2S232A(1)
 #define STV090x_OFFST_Px_CAR2S2_32A_BETA_M_FIELD	4
@@ -1458,7 +1456,7 @@
 #define STV090x_P1_MODCODLST1			STV090x_Px_MODCODLST1(1)
 #define STV090x_P2_MODCODLST1			STV090x_Px_MODCODLST1(2)
 #define STV090x_OFFST_Px_DIS_MODCOD29_FIELD	4
-#define STV090x_WIDTH_Px_DIS_MODCOD29T_FIELD	4
+#define STV090x_WIDTH_Px_DIS_MODCOD29_FIELD	4
 #define STV090x_OFFST_Px_DIS_32PSK_9_10_FIELD	0
 #define STV090x_WIDTH_Px_DIS_32PSK_9_10_FIELD	4
 
@@ -2180,7 +2178,7 @@
 #define STV090x_WIDTH_Px_TSFIFOSPEED_STORE_FIELD	1
 #define STV090x_OFFST_Px_DILXX_RESET_FIELD		5
 #define STV090x_WIDTH_Px_DILXX_RESET_FIELD		1
-#define STV090x_OFFST_Px_TSSERIAL_IMPOS_FIELD		5
+#define STV090x_OFFST_Px_TSSERIAL_IMPOS_FIELD		4
 #define STV090x_WIDTH_Px_TSSERIAL_IMPOS_FIELD		1
 #define STV090x_OFFST_Px_SCRAMBDETECT_FIELD		1
 #define STV090x_WIDTH_Px_SCRAMBDETECT_FIELD		1
@@ -2190,7 +2188,7 @@
 #define STV090x_P1_TSBITRATE1				STV090x_Px_TSBITRATEy(1, 1)
 #define STV090x_P2_TSBITRATE0				STV090x_Px_TSBITRATEy(2, 0)
 #define STV090x_P2_TSBITRATE1				STV090x_Px_TSBITRATEy(2, 1)
-#define STV090x_OFFST_Px_TSFIFO_BITRATE_FIELD		7
+#define STV090x_OFFST_Px_TSFIFO_BITRATE_FIELD		0
 #define STV090x_WIDTH_Px_TSFIFO_BITRATE_FIELD		8
 
 #define STV090x_Px_ERRCTRL1(__x)			(0xF598 - (__x - 1) * 0x200)
diff --git a/drivers/media/dvb/frontends/stv6110.c b/drivers/media/dvb/frontends/stv6110.c
index dcf1b21..bef0cc8 100644
--- a/drivers/media/dvb/frontends/stv6110.c
+++ b/drivers/media/dvb/frontends/stv6110.c
@@ -37,6 +37,7 @@
 
 	u32 mclk;
 	u8 clk_div;
+	u8 gain;
 	u8 regs[8];
 };
 
@@ -255,7 +256,7 @@
 	u8 ret = 0x04;
 	u32 divider, ref, p, presc, i, result_freq, vco_freq;
 	s32 p_calc, p_calc_opt = 1000, r_div, r_div_opt = 0, p_val;
-	s32 srate; u8 gain;
+	s32 srate;
 
 	dprintk("%s, freq=%d kHz, mclk=%d Hz\n", __func__,
 						frequency, priv->mclk);
@@ -273,15 +274,8 @@
 	} else
 		srate = 15000000;
 
-	if (srate >= 15000000)
-		gain = 3; /* +6 dB */
-	else if (srate >= 5000000)
-		gain = 3; /* +6 dB */
-	else
-		gain = 3; /* +6 dB */
-
 	priv->regs[RSTV6110_CTRL2] &= ~0x0f;
-	priv->regs[RSTV6110_CTRL2] |= (gain & 0x0f);
+	priv->regs[RSTV6110_CTRL2] |= (priv->gain & 0x0f);
 
 	if (frequency <= 1023000) {
 		p = 1;
@@ -436,6 +430,7 @@
 	priv->i2c = i2c;
 	priv->mclk = config->mclk;
 	priv->clk_div = config->clk_div;
+	priv->gain = config->gain;
 
 	memcpy(&priv->regs, &reg0[1], 8);
 
diff --git a/drivers/media/dvb/frontends/stv6110.h b/drivers/media/dvb/frontends/stv6110.h
index 9db2402..fe71bba 100644
--- a/drivers/media/dvb/frontends/stv6110.h
+++ b/drivers/media/dvb/frontends/stv6110.h
@@ -41,6 +41,7 @@
 struct stv6110_config {
 	u8 i2c_address;
 	u32 mclk;
+	u8 gain;
 	u8 clk_div;	/* divisor value for the output clock */
 };
 
diff --git a/drivers/media/dvb/frontends/stv6110x.c b/drivers/media/dvb/frontends/stv6110x.c
index 3d8a2e0..bcfcb65 100644
--- a/drivers/media/dvb/frontends/stv6110x.c
+++ b/drivers/media/dvb/frontends/stv6110x.c
@@ -95,7 +95,7 @@
 {
 	struct stv6110x_state *stv6110x = fe->tuner_priv;
 	u32 rDiv, divider;
-	s32 pVal, pCalc, rDivOpt = 0;
+	s32 pVal, pCalc, rDivOpt = 0, pCalcOpt = 1000;
 	u8 i;
 
 	STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16));
@@ -121,8 +121,10 @@
 	for (rDiv = 0; rDiv <= 3; rDiv++) {
 		pCalc = (REFCLOCK_kHz / 100) / R_DIV(rDiv);
 
-		if ((abs((s32)(pCalc - pVal))) < (abs((s32)(1000 - pVal))))
+		if ((abs((s32)(pCalc - pVal))) < (abs((s32)(pCalcOpt - pVal))))
 			rDivOpt = rDiv;
+
+		pCalcOpt = (REFCLOCK_kHz / 100) / R_DIV(rDivOpt);
 	}
 
 	divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz;
diff --git a/drivers/media/dvb/pt1/pt1.c b/drivers/media/dvb/pt1/pt1.c
index 1fd8306..81e623a 100644
--- a/drivers/media/dvb/pt1/pt1.c
+++ b/drivers/media/dvb/pt1/pt1.c
@@ -27,7 +27,6 @@
 #include <linux/pci.h>
 #include <linux/kthread.h>
 #include <linux/freezer.h>
-#include <linux/vmalloc.h>
 
 #include "dvbdev.h"
 #include "dvb_demux.h"
diff --git a/drivers/media/dvb/pt1/va1j5jf8007s.c b/drivers/media/dvb/pt1/va1j5jf8007s.c
index 2db940f..fc65949 100644
--- a/drivers/media/dvb/pt1/va1j5jf8007s.c
+++ b/drivers/media/dvb/pt1/va1j5jf8007s.c
@@ -48,6 +48,60 @@
 	enum va1j5jf8007s_tune_state tune_state;
 };
 
+static int va1j5jf8007s_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	struct va1j5jf8007s_state *state;
+	u8 addr;
+	int i;
+	u8 write_buf[1], read_buf[1];
+	struct i2c_msg msgs[2];
+	s32 word, x1, x2, x3, x4, x5, y;
+
+	state = fe->demodulator_priv;
+	addr = state->config->demod_address;
+
+	word = 0;
+	for (i = 0; i < 2; i++) {
+		write_buf[0] = 0xbc + i;
+
+		msgs[0].addr = addr;
+		msgs[0].flags = 0;
+		msgs[0].len = sizeof(write_buf);
+		msgs[0].buf = write_buf;
+
+		msgs[1].addr = addr;
+		msgs[1].flags = I2C_M_RD;
+		msgs[1].len = sizeof(read_buf);
+		msgs[1].buf = read_buf;
+
+		if (i2c_transfer(state->adap, msgs, 2) != 2)
+			return -EREMOTEIO;
+
+		word <<= 8;
+		word |= read_buf[0];
+	}
+
+	word -= 3000;
+	if (word < 0)
+		word = 0;
+
+	x1 = int_sqrt(word << 16) * ((15625ll << 21) / 1000000);
+	x2 = (s64)x1 * x1 >> 31;
+	x3 = (s64)x2 * x1 >> 31;
+	x4 = (s64)x2 * x2 >> 31;
+	x5 = (s64)x4 * x1 >> 31;
+
+	y = (58857ll << 23) / 1000;
+	y -= (s64)x1 * ((89565ll << 24) / 1000) >> 30;
+	y += (s64)x2 * ((88977ll << 24) / 1000) >> 28;
+	y -= (s64)x3 * ((50259ll << 25) / 1000) >> 27;
+	y += (s64)x4 * ((14341ll << 27) / 1000) >> 27;
+	y -= (s64)x5 * ((16346ll << 30) / 10000) >> 28;
+
+	*snr = y < 0 ? 0 : y >> 15;
+	return 0;
+}
+
 static int va1j5jf8007s_get_frontend_algo(struct dvb_frontend *fe)
 {
 	return DVBFE_ALGO_HW;
@@ -337,7 +391,7 @@
 {
 	struct va1j5jf8007s_state *state;
 	int ret;
-	int lock;
+	int lock = 0;
 
 	state = fe->demodulator_priv;
 
@@ -536,6 +590,7 @@
 			FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
 	},
 
+	.read_snr = va1j5jf8007s_read_snr,
 	.get_frontend_algo = va1j5jf8007s_get_frontend_algo,
 	.read_status = va1j5jf8007s_read_status,
 	.tune = va1j5jf8007s_tune,
diff --git a/drivers/media/dvb/pt1/va1j5jf8007t.c b/drivers/media/dvb/pt1/va1j5jf8007t.c
index 71117f4..3db4f3e3 100644
--- a/drivers/media/dvb/pt1/va1j5jf8007t.c
+++ b/drivers/media/dvb/pt1/va1j5jf8007t.c
@@ -46,6 +46,52 @@
 	enum va1j5jf8007t_tune_state tune_state;
 };
 
+static int va1j5jf8007t_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	struct va1j5jf8007t_state *state;
+	u8 addr;
+	int i;
+	u8 write_buf[1], read_buf[1];
+	struct i2c_msg msgs[2];
+	s32 word, x, y;
+
+	state = fe->demodulator_priv;
+	addr = state->config->demod_address;
+
+	word = 0;
+	for (i = 0; i < 3; i++) {
+		write_buf[0] = 0x8b + i;
+
+		msgs[0].addr = addr;
+		msgs[0].flags = 0;
+		msgs[0].len = sizeof(write_buf);
+		msgs[0].buf = write_buf;
+
+		msgs[1].addr = addr;
+		msgs[1].flags = I2C_M_RD;
+		msgs[1].len = sizeof(read_buf);
+		msgs[1].buf = read_buf;
+
+		if (i2c_transfer(state->adap, msgs, 2) != 2)
+			return -EREMOTEIO;
+
+		word <<= 8;
+		word |= read_buf[0];
+	}
+
+	if (!word)
+		return -EIO;
+
+	x = 10 * (intlog10(0x540000 * 100 / word) - (2 << 24));
+	y = (24ll << 46) / 1000000;
+	y = ((s64)y * x >> 30) - (16ll << 40) / 10000;
+	y = ((s64)y * x >> 29) + (398ll << 35) / 10000;
+	y = ((s64)y * x >> 30) + (5491ll << 29) / 10000;
+	y = ((s64)y * x >> 30) + (30965ll << 23) / 10000;
+	*snr = y >> 15;
+	return 0;
+}
+
 static int va1j5jf8007t_get_frontend_algo(struct dvb_frontend *fe)
 {
 	return DVBFE_ALGO_HW;
@@ -224,7 +270,7 @@
 {
 	struct va1j5jf8007t_state *state;
 	int ret;
-	int lock, retry;
+	int lock = 0, retry = 0;
 
 	state = fe->demodulator_priv;
 
@@ -393,6 +439,7 @@
 			FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
 	},
 
+	.read_snr = va1j5jf8007t_read_snr,
 	.get_frontend_algo = va1j5jf8007t_get_frontend_algo,
 	.read_status = va1j5jf8007t_read_status,
 	.tune = va1j5jf8007t_tune,
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c
index 0420e28..1067b22 100644
--- a/drivers/media/dvb/siano/sms-cards.c
+++ b/drivers/media/dvb/siano/sms-cards.c
@@ -97,7 +97,7 @@
 	},
 };
 
-struct sms_board *sms_get_board(int id)
+struct sms_board *sms_get_board(unsigned id)
 {
 	BUG_ON(id >= ARRAY_SIZE(sms_boards));
 
@@ -294,6 +294,8 @@
 	case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A:
 	case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B:
 	case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
+	case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
+	case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
 		request_module("smsdvb");
 		break;
 	default:
diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h
index 38f062f..8f19fc0 100644
--- a/drivers/media/dvb/siano/sms-cards.h
+++ b/drivers/media/dvb/siano/sms-cards.h
@@ -81,7 +81,7 @@
 	int led_power, led_hi, led_lo, lna_ctrl, rf_switch;
 };
 
-struct sms_board *sms_get_board(int id);
+struct sms_board *sms_get_board(unsigned id);
 
 extern struct smscore_device_t *coredev;
 
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c
index fa6a623..ca758bc 100644
--- a/drivers/media/dvb/siano/smscoreapi.c
+++ b/drivers/media/dvb/siano/smscoreapi.c
@@ -1373,7 +1373,7 @@
 
 	*pGroupCfg = 1;
 
-	if (PinNum >= 0 && PinNum <= 1)	{
+	if (PinNum <= 1)	{
 		*pTranslatedPinNum = 0;
 		*pGroupNum = 9;
 		*pGroupCfg = 2;
diff --git a/drivers/media/dvb/siano/smssdio.c b/drivers/media/dvb/siano/smssdio.c
index d1d652e..24206cb 100644
--- a/drivers/media/dvb/siano/smssdio.c
+++ b/drivers/media/dvb/siano/smssdio.c
@@ -78,7 +78,7 @@
 
 static int smssdio_sendrequest(void *context, void *buffer, size_t size)
 {
-	int ret;
+	int ret = 0;
 	struct smssdio_device *smsdev;
 
 	smsdev = context;
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index 8d65c65..baf3159 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -2425,7 +2425,7 @@
 		 * use 0x15 to track VPE  interrupts - increase by 1 every vpeirq() is called
 		 */
 		saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
-		/* set event counter 1 treshold to maximum allowed value        (rEC p55) */
+		/* set event counter 1 threshold to maximum allowed value        (rEC p55) */
 		saa7146_write(dev, ECT1R,  0x3fff );
 #endif
 		/* Set RPS1 Address register to point to RPS code               (r108 p42) */
@@ -2559,7 +2559,7 @@
 		 * use 0x15 to track VPE  interrupts - increase by 1 every vpeirq() is called
 		 */
 		saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
-		/* set event counter 1 treshold to maximum allowed value        (rEC p55) */
+		/* set event counter 1 threshold to maximum allowed value        (rEC p55) */
 		saa7146_write(dev, ECT1R,  0x3fff );
 #endif
 		/* Setup BUDGETPATCH MAIN RPS1 "program" (p35) */
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 8ea9152..983672a 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -1055,7 +1055,7 @@
 	{ STB0899_TSCFGH		, 0x0c },
 	{ STB0899_TSCFGM		, 0x00 },
 	{ STB0899_TSCFGL		, 0x0c },
-	{ STB0899_TSOUT			, 0x0d }, /* 0x0d for CAM */
+	{ STB0899_TSOUT			, 0x4d }, /* 0x0d for CAM */
 	{ STB0899_RSSYNCDEL		, 0x00 },
 	{ STB0899_TSINHDELH		, 0x02 },
 	{ STB0899_TSINHDELM		, 0x00 },
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index b5c6813..7d193eb 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -178,7 +178,7 @@
 	if (budget_ci->ir.last_raw != raw || !timer_pending(&budget_ci->ir.timer_keyup)) {
 		ir_input_nokey(dev, &budget_ci->ir.state);
 		ir_input_keydown(dev, &budget_ci->ir.state,
-				 budget_ci->ir.ir_key, raw);
+				 budget_ci->ir.ir_key);
 		budget_ci->ir.last_raw = raw;
 	}
 
@@ -224,8 +224,10 @@
 	case 0x1011:
 	case 0x1012:
 		/* The hauppauge keymap is a superset of these remotes */
-		ir_input_init(input_dev, &budget_ci->ir.state,
+		error = ir_input_init(input_dev, &budget_ci->ir.state,
 			      IR_TYPE_RC5, &ir_codes_hauppauge_new_table);
+		if (error < 0)
+			goto out2;
 
 		if (rc5_device < 0)
 			budget_ci->ir.rc5_device = 0x1f;
@@ -236,8 +238,10 @@
 	case 0x1017:
 	case 0x101a:
 		/* for the Technotrend 1500 bundled remote */
-		ir_input_init(input_dev, &budget_ci->ir.state,
+		error = ir_input_init(input_dev, &budget_ci->ir.state,
 			      IR_TYPE_RC5, &ir_codes_tt_1500_table);
+		if (error < 0)
+			goto out2;
 
 		if (rc5_device < 0)
 			budget_ci->ir.rc5_device = IR_DEVICE_ANY;
@@ -246,8 +250,10 @@
 		break;
 	default:
 		/* unknown remote */
-		ir_input_init(input_dev, &budget_ci->ir.state,
+		error = ir_input_init(input_dev, &budget_ci->ir.state,
 			      IR_TYPE_RC5, &ir_codes_budget_ci_old_table);
+		if (error < 0)
+			goto out2;
 
 		if (rc5_device < 0)
 			budget_ci->ir.rc5_device = IR_DEVICE_ANY;
@@ -280,6 +286,7 @@
 	return 0;
 
 out2:
+	ir_input_free(input_dev);
 	input_free_device(input_dev);
 out1:
 	return error;
@@ -297,6 +304,7 @@
 	del_timer_sync(&dev->timer);
 	ir_input_nokey(dev, &budget_ci->ir.state);
 
+	ir_input_free(dev);
 	input_unregister_device(dev);
 }
 
@@ -1248,7 +1256,7 @@
 	{ STB0899_TSCFGH        	, 0x0c },
 	{ STB0899_TSCFGM        	, 0x00 },
 	{ STB0899_TSCFGL        	, 0x0c },
-	{ STB0899_TSOUT			, 0x0d }, /* 0x0d for CAM */
+	{ STB0899_TSOUT			, 0x4d }, /* 0x0d for CAM */
 	{ STB0899_RSSYNCDEL     	, 0x00 },
 	{ STB0899_TSINHDELH     	, 0x02 },
 	{ STB0899_TSINHDELM		, 0x00 },
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c
index 60136688..9c92f9d 100644
--- a/drivers/media/dvb/ttpci/budget-patch.c
+++ b/drivers/media/dvb/ttpci/budget-patch.c
@@ -456,7 +456,7 @@
 	// use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
 	// use 0x15 to track VPE  interrupts - increase by 1 every vpeirq() is called
 	saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
-	// set event counter 1 treshold to maximum allowed value        (rEC p55)
+	// set event counter 1 threshold to maximum allowed value        (rEC p55)
 	saa7146_write(dev, ECT1R,  0x3fff );
 #endif
 	// Fix VSYNC level
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index d91e063..53baccb 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -1198,7 +1198,7 @@
 	int err;
 
 	usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys));
-	strlcpy(dec->rc_phys, "/input0", sizeof(dec->rc_phys));
+	strlcat(dec->rc_phys, "/input0", sizeof(dec->rc_phys));
 
 	input_dev = input_allocate_device();
 	if (!input_dev)
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index b134553..4c2b8a2 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -197,7 +197,8 @@
 
 config RADIO_MIROPCM20
 	tristate "miroSOUND PCM20 radio"
-	depends on ISA && VIDEO_V4L2
+	depends on ISA && VIDEO_V4L2 && SND
+	select SND_ISA
 	select SND_MIRO
 	---help---
 	  Choose Y here if you have this FM radio card. You also need to enable
@@ -419,4 +420,16 @@
 	  Say Y here if TEA5764 have a 32768 Hz crystal in circuit, say N
 	  here if TEA5764 reference frequency is connected in FREQIN.
 
+config RADIO_TEF6862
+	tristate "TEF6862 Car Radio Enhanced Selectivity Tuner"
+	depends on I2C && VIDEO_V4L2
+	---help---
+	  Say Y here if you want to use the TEF6862 Car Radio Enhanced
+	  Selectivity Tuner, found for instance on the Russellville development
+	  board. On the russellville the device is connected to internal
+	  timberdale I2C bus.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called TEF6862.
+
 endif # RADIO_ADAPTERS
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 8a63d54..01922ad 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -23,5 +23,6 @@
 obj-$(CONFIG_RADIO_SI470X) += si470x/
 obj-$(CONFIG_USB_MR800) += radio-mr800.o
 obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o
+obj-$(CONFIG_RADIO_TEF6862) += tef6862.o
 
 EXTRA_CFLAGS += -Isound
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index a123908..949f605 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -28,7 +28,7 @@
  * http://av-usbradio.sourceforge.net/index.php
  * http://sourceforge.net/projects/av-usbradio/
  * Latest release of theirs project was in 2005.
- * Probably, this driver could be improved trough using their
+ * Probably, this driver could be improved through using their
  * achievements (specifications given).
  * Also, Faidon Liambotis <paravoid@debian.org> wrote nice driver for this radio
  * in 2007. He allowed to use his driver to improve current mr800 radio driver.
@@ -85,6 +85,9 @@
 #define amradio_dev_warn(dev, fmt, arg...)				\
 		dev_warn(dev, MR800_DRIVER_NAME " - " fmt, ##arg)
 
+#define amradio_dev_err(dev, fmt, arg...) \
+		dev_err(dev, MR800_DRIVER_NAME " - " fmt, ##arg)
+
 /* Probably USB_TIMEOUT should be modified in module parameter */
 #define BUFFER_LENGTH 8
 #define USB_TIMEOUT 500
@@ -129,18 +132,20 @@
 struct amradio_device {
 	/* reference to USB and video device */
 	struct usb_device *usbdev;
-	struct video_device *videodev;
+	struct usb_interface *intf;
+	struct video_device videodev;
 	struct v4l2_device v4l2_dev;
 
 	unsigned char *buffer;
 	struct mutex lock;	/* buffer locking */
 	int curfreq;
 	int stereo;
-	int users;
-	int removed;
 	int muted;
+	int initialized;
 };
 
+#define vdev_to_amradio(r) container_of(r, struct amradio_device, videodev)
+
 /* USB Device ID List */
 static struct usb_device_id usb_amradio_device_table[] = {
 	{USB_DEVICE_AND_INTERFACE_INFO(USB_AMRADIO_VENDOR, USB_AMRADIO_PRODUCT,
@@ -159,7 +164,7 @@
 	.resume			= usb_amradio_resume,
 	.reset_resume		= usb_amradio_resume,
 	.id_table		= usb_amradio_device_table,
-	.supports_autosuspend	= 0,
+	.supports_autosuspend	= 1,
 };
 
 /* switch on/off the radio. Send 8 bytes to device */
@@ -168,11 +173,7 @@
 	int retval;
 	int size;
 
-	/* safety check */
-	if (radio->removed)
-		return -EIO;
-
-	mutex_lock(&radio->lock);
+	BUG_ON(!mutex_is_locked(&radio->lock));
 
 	radio->buffer[0] = 0x00;
 	radio->buffer[1] = 0x55;
@@ -187,14 +188,12 @@
 		(void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
 
 	if (retval < 0 || size != BUFFER_LENGTH) {
-		mutex_unlock(&radio->lock);
+		amradio_dev_warn(&radio->videodev.dev, "set mute failed\n");
 		return retval;
 	}
 
 	radio->muted = argument;
 
-	mutex_unlock(&radio->lock);
-
 	return retval;
 }
 
@@ -205,11 +204,7 @@
 	int size;
 	unsigned short freq_send = 0x10 + (freq >> 3) / 25;
 
-	/* safety check */
-	if (radio->removed)
-		return -EIO;
-
-	mutex_lock(&radio->lock);
+	BUG_ON(!mutex_is_locked(&radio->lock));
 
 	radio->buffer[0] = 0x00;
 	radio->buffer[1] = 0x55;
@@ -223,10 +218,8 @@
 	retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
 		(void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
 
-	if (retval < 0 || size != BUFFER_LENGTH) {
-		mutex_unlock(&radio->lock);
-		return retval;
-	}
+	if (retval < 0 || size != BUFFER_LENGTH)
+		goto out_err;
 
 	/* frequency is calculated from freq_send and placed in first 2 bytes */
 	radio->buffer[0] = (freq_send >> 8) & 0xff;
@@ -240,13 +233,15 @@
 	retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
 		(void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
 
-	if (retval < 0 || size != BUFFER_LENGTH) {
-		mutex_unlock(&radio->lock);
-		return retval;
-	}
+	if (retval < 0 || size != BUFFER_LENGTH)
+		goto out_err;
 
-	mutex_unlock(&radio->lock);
+	radio->curfreq = freq;
+	goto out;
 
+out_err:
+	amradio_dev_warn(&radio->videodev.dev, "set frequency failed\n");
+out:
 	return retval;
 }
 
@@ -255,11 +250,7 @@
 	int retval;
 	int size;
 
-	/* safety check */
-	if (radio->removed)
-		return -EIO;
-
-	mutex_lock(&radio->lock);
+	BUG_ON(!mutex_is_locked(&radio->lock));
 
 	radio->buffer[0] = 0x00;
 	radio->buffer[1] = 0x55;
@@ -274,14 +265,14 @@
 		(void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
 
 	if (retval < 0 || size != BUFFER_LENGTH) {
-		radio->stereo = -1;
-		mutex_unlock(&radio->lock);
+		amradio_dev_warn(&radio->videodev.dev, "set stereo failed\n");
 		return retval;
 	}
 
-	radio->stereo = 1;
-
-	mutex_unlock(&radio->lock);
+	if (argument == WANT_STEREO)
+		radio->stereo = 1;
+	else
+		radio->stereo = 0;
 
 	return retval;
 }
@@ -296,19 +287,19 @@
 	struct amradio_device *radio = usb_get_intfdata(intf);
 
 	mutex_lock(&radio->lock);
-	radio->removed = 1;
+	radio->usbdev = NULL;
 	mutex_unlock(&radio->lock);
 
 	usb_set_intfdata(intf, NULL);
-	video_unregister_device(radio->videodev);
 	v4l2_device_disconnect(&radio->v4l2_dev);
+	video_unregister_device(&radio->videodev);
 }
 
 /* vidioc_querycap - query device capabilities */
 static int vidioc_querycap(struct file *file, void *priv,
 					struct v4l2_capability *v)
 {
-	struct amradio_device *radio = video_drvdata(file);
+	struct amradio_device *radio = file->private_data;
 
 	strlcpy(v->driver, "radio-mr800", sizeof(v->driver));
 	strlcpy(v->card, "AverMedia MR 800 USB FM Radio", sizeof(v->card));
@@ -322,13 +313,9 @@
 static int vidioc_g_tuner(struct file *file, void *priv,
 				struct v4l2_tuner *v)
 {
-	struct amradio_device *radio = video_get_drvdata(video_devdata(file));
+	struct amradio_device *radio = file->private_data;
 	int retval;
 
-	/* safety check */
-	if (radio->removed)
-		return -EIO;
-
 	if (v->index > 0)
 		return -EINVAL;
 
@@ -341,9 +328,6 @@
  * amradio_set_stereo shouldn't be here
  */
 	retval = amradio_set_stereo(radio, WANT_STEREO);
-	if (retval < 0)
-		amradio_dev_warn(&radio->videodev->dev,
-			"set stereo failed\n");
 
 	strcpy(v->name, "FM");
 	v->type = V4L2_TUNER_RADIO;
@@ -357,19 +341,16 @@
 		v->audmode = V4L2_TUNER_MODE_MONO;
 	v->signal = 0xffff;     /* Can't get the signal strength, sad.. */
 	v->afc = 0; /* Don't know what is this */
-	return 0;
+
+	return retval;
 }
 
 /* vidioc_s_tuner - set tuner attributes */
 static int vidioc_s_tuner(struct file *file, void *priv,
 				struct v4l2_tuner *v)
 {
-	struct amradio_device *radio = video_get_drvdata(video_devdata(file));
-	int retval;
-
-	/* safety check */
-	if (radio->removed)
-		return -EIO;
+	struct amradio_device *radio = file->private_data;
+	int retval = -EINVAL;
 
 	if (v->index > 0)
 		return -EINVAL;
@@ -378,57 +359,33 @@
 	switch (v->audmode) {
 	case V4L2_TUNER_MODE_MONO:
 		retval = amradio_set_stereo(radio, WANT_MONO);
-		if (retval < 0)
-			amradio_dev_warn(&radio->videodev->dev,
-				"set mono failed\n");
 		break;
 	case V4L2_TUNER_MODE_STEREO:
 		retval = amradio_set_stereo(radio, WANT_STEREO);
-		if (retval < 0)
-			amradio_dev_warn(&radio->videodev->dev,
-				"set stereo failed\n");
 		break;
-	default:
-		return -EINVAL;
 	}
 
-	return 0;
+	return retval;
 }
 
 /* vidioc_s_frequency - set tuner radio frequency */
 static int vidioc_s_frequency(struct file *file, void *priv,
 				struct v4l2_frequency *f)
 {
-	struct amradio_device *radio = video_get_drvdata(video_devdata(file));
-	int retval;
+	struct amradio_device *radio = file->private_data;
 
-	/* safety check */
-	if (radio->removed)
-		return -EIO;
-
-	mutex_lock(&radio->lock);
-	radio->curfreq = f->frequency;
-	mutex_unlock(&radio->lock);
-
-	retval = amradio_setfreq(radio, radio->curfreq);
-	if (retval < 0)
-		amradio_dev_warn(&radio->videodev->dev,
-			"set frequency failed\n");
-	return 0;
+	return amradio_setfreq(radio, f->frequency);
 }
 
 /* vidioc_g_frequency - get tuner radio frequency */
 static int vidioc_g_frequency(struct file *file, void *priv,
 				struct v4l2_frequency *f)
 {
-	struct amradio_device *radio = video_get_drvdata(video_devdata(file));
-
-	/* safety check */
-	if (radio->removed)
-		return -EIO;
+	struct amradio_device *radio = file->private_data;
 
 	f->type = V4L2_TUNER_RADIO;
 	f->frequency = radio->curfreq;
+
 	return 0;
 }
 
@@ -448,17 +405,14 @@
 static int vidioc_g_ctrl(struct file *file, void *priv,
 				struct v4l2_control *ctrl)
 {
-	struct amradio_device *radio = video_get_drvdata(video_devdata(file));
-
-	/* safety check */
-	if (radio->removed)
-		return -EIO;
+	struct amradio_device *radio = file->private_data;
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
 		ctrl->value = radio->muted;
 		return 0;
 	}
+
 	return -EINVAL;
 }
 
@@ -466,33 +420,20 @@
 static int vidioc_s_ctrl(struct file *file, void *priv,
 				struct v4l2_control *ctrl)
 {
-	struct amradio_device *radio = video_get_drvdata(video_devdata(file));
-	int retval;
-
-	/* safety check */
-	if (radio->removed)
-		return -EIO;
+	struct amradio_device *radio = file->private_data;
+	int retval = -EINVAL;
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
-		if (ctrl->value) {
+		if (ctrl->value)
 			retval = amradio_set_mute(radio, AMRADIO_STOP);
-			if (retval < 0) {
-				amradio_dev_warn(&radio->videodev->dev,
-					"amradio_stop failed\n");
-				return -1;
-			}
-		} else {
+		else
 			retval = amradio_set_mute(radio, AMRADIO_START);
-			if (retval < 0) {
-				amradio_dev_warn(&radio->videodev->dev,
-					"amradio_start failed\n");
-				return -1;
-			}
-		}
-		return 0;
+
+		break;
 	}
-	return -EINVAL;
+
+	return retval;
 }
 
 /* vidioc_g_audio - get audio attributes */
@@ -531,75 +472,108 @@
 	return 0;
 }
 
+static int usb_amradio_init(struct amradio_device *radio)
+{
+	int retval;
+
+	retval = amradio_set_mute(radio, AMRADIO_STOP);
+	if (retval)
+		goto out_err;
+
+	retval = amradio_set_stereo(radio, WANT_STEREO);
+	if (retval)
+		goto out_err;
+
+	radio->initialized = 1;
+	goto out;
+
+out_err:
+	amradio_dev_err(&radio->videodev.dev, "initialization failed\n");
+out:
+	return retval;
+}
+
 /* open device - amradio_start() and amradio_setfreq() */
 static int usb_amradio_open(struct file *file)
 {
-	struct amradio_device *radio = video_get_drvdata(video_devdata(file));
-	int retval;
+	struct amradio_device *radio = vdev_to_amradio(video_devdata(file));
+	int retval = 0;
 
-	lock_kernel();
+	mutex_lock(&radio->lock);
 
-	radio->users = 1;
-	radio->muted = 1;
-
-	retval = amradio_set_mute(radio, AMRADIO_START);
-	if (retval < 0) {
-		amradio_dev_warn(&radio->videodev->dev,
-			"radio did not start up properly\n");
-		radio->users = 0;
-		unlock_kernel();
-		return -EIO;
+	if (!radio->usbdev) {
+		retval = -EIO;
+		goto unlock;
 	}
 
-	retval = amradio_set_stereo(radio, WANT_STEREO);
-	if (retval < 0)
-		amradio_dev_warn(&radio->videodev->dev,
-			"set stereo failed\n");
+	file->private_data = radio;
+	retval = usb_autopm_get_interface(radio->intf);
+	if (retval)
+		goto unlock;
 
-	retval = amradio_setfreq(radio, radio->curfreq);
-	if (retval < 0)
-		amradio_dev_warn(&radio->videodev->dev,
-			"set frequency failed\n");
+	if (unlikely(!radio->initialized)) {
+		retval = usb_amradio_init(radio);
+		if (retval)
+			usb_autopm_put_interface(radio->intf);
+	}
 
-	unlock_kernel();
-	return 0;
+unlock:
+	mutex_unlock(&radio->lock);
+	return retval;
 }
 
 /*close device */
 static int usb_amradio_close(struct file *file)
 {
-	struct amradio_device *radio = video_get_drvdata(video_devdata(file));
-	int retval;
-
-	if (!radio)
-		return -ENODEV;
+	struct amradio_device *radio = file->private_data;
+	int retval = 0;
 
 	mutex_lock(&radio->lock);
-	radio->users = 0;
-	mutex_unlock(&radio->lock);
 
-	if (!radio->removed) {
-		retval = amradio_set_mute(radio, AMRADIO_STOP);
-		if (retval < 0)
-			amradio_dev_warn(&radio->videodev->dev,
-				"amradio_stop failed\n");
+	if (!radio->usbdev)
+		retval = -EIO;
+	else
+		usb_autopm_put_interface(radio->intf);
+
+	mutex_unlock(&radio->lock);
+	return retval;
+}
+
+static long usb_amradio_ioctl(struct file *file, unsigned int cmd,
+				unsigned long arg)
+{
+	struct amradio_device *radio = file->private_data;
+	long retval = 0;
+
+	mutex_lock(&radio->lock);
+
+	if (!radio->usbdev) {
+		retval = -EIO;
+		goto unlock;
 	}
 
-	return 0;
+	retval = video_ioctl2(file, cmd, arg);
+
+unlock:
+	mutex_unlock(&radio->lock);
+	return retval;
 }
 
 /* Suspend device - stop device. Need to be checked and fixed */
 static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message)
 {
 	struct amradio_device *radio = usb_get_intfdata(intf);
-	int retval;
 
-	retval = amradio_set_mute(radio, AMRADIO_STOP);
-	if (retval < 0)
-		dev_warn(&intf->dev, "amradio_stop failed\n");
+	mutex_lock(&radio->lock);
+
+	if (!radio->muted && radio->initialized) {
+		amradio_set_mute(radio, AMRADIO_STOP);
+		radio->muted = 0;
+	}
 
 	dev_info(&intf->dev, "going into suspend..\n");
 
+	mutex_unlock(&radio->lock);
 	return 0;
 }
 
@@ -607,14 +581,26 @@
 static int usb_amradio_resume(struct usb_interface *intf)
 {
 	struct amradio_device *radio = usb_get_intfdata(intf);
-	int retval;
 
-	retval = amradio_set_mute(radio, AMRADIO_START);
-	if (retval < 0)
-		dev_warn(&intf->dev, "amradio_start failed\n");
+	mutex_lock(&radio->lock);
 
+	if (unlikely(!radio->initialized))
+		goto unlock;
+
+	if (radio->stereo)
+		amradio_set_stereo(radio, WANT_STEREO);
+	else
+		amradio_set_stereo(radio, WANT_MONO);
+
+	amradio_setfreq(radio, radio->curfreq);
+
+	if (!radio->muted)
+		amradio_set_mute(radio, AMRADIO_START);
+
+unlock:
 	dev_info(&intf->dev, "coming out of suspend..\n");
 
+	mutex_unlock(&radio->lock);
 	return 0;
 }
 
@@ -623,7 +609,7 @@
 	.owner		= THIS_MODULE,
 	.open		= usb_amradio_open,
 	.release	= usb_amradio_close,
-	.ioctl		= video_ioctl2,
+	.ioctl		= usb_amradio_ioctl,
 };
 
 static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = {
@@ -643,10 +629,7 @@
 
 static void usb_amradio_video_device_release(struct video_device *videodev)
 {
-	struct amradio_device *radio = video_get_drvdata(videodev);
-
-	/* we call v4l to free radio->videodev */
-	video_device_release(videodev);
+	struct amradio_device *radio = vdev_to_amradio(videodev);
 
 	v4l2_device_unregister(&radio->v4l2_dev);
 
@@ -660,70 +643,63 @@
 				const struct usb_device_id *id)
 {
 	struct amradio_device *radio;
-	struct v4l2_device *v4l2_dev;
-	int retval;
+	int retval = 0;
 
 	radio = kzalloc(sizeof(struct amradio_device), GFP_KERNEL);
 
 	if (!radio) {
 		dev_err(&intf->dev, "kmalloc for amradio_device failed\n");
-		return -ENOMEM;
+		retval = -ENOMEM;
+		goto err;
 	}
 
 	radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL);
 
 	if (!radio->buffer) {
 		dev_err(&intf->dev, "kmalloc for radio->buffer failed\n");
-		kfree(radio);
-		return -ENOMEM;
+		retval = -ENOMEM;
+		goto err_nobuf;
 	}
 
-	v4l2_dev = &radio->v4l2_dev;
-	retval = v4l2_device_register(&intf->dev, v4l2_dev);
+	retval = v4l2_device_register(&intf->dev, &radio->v4l2_dev);
 	if (retval < 0) {
 		dev_err(&intf->dev, "couldn't register v4l2_device\n");
-		kfree(radio->buffer);
-		kfree(radio);
-		return retval;
+		goto err_v4l2;
 	}
 
-	radio->videodev = video_device_alloc();
+	strlcpy(radio->videodev.name, radio->v4l2_dev.name,
+		sizeof(radio->videodev.name));
+	radio->videodev.v4l2_dev = &radio->v4l2_dev;
+	radio->videodev.fops = &usb_amradio_fops;
+	radio->videodev.ioctl_ops = &usb_amradio_ioctl_ops;
+	radio->videodev.release = usb_amradio_video_device_release;
 
-	if (!radio->videodev) {
-		dev_err(&intf->dev, "video_device_alloc failed\n");
-		kfree(radio->buffer);
-		kfree(radio);
-		return -ENOMEM;
-	}
-
-	strlcpy(radio->videodev->name, v4l2_dev->name, sizeof(radio->videodev->name));
-	radio->videodev->v4l2_dev = v4l2_dev;
-	radio->videodev->fops = &usb_amradio_fops;
-	radio->videodev->ioctl_ops = &usb_amradio_ioctl_ops;
-	radio->videodev->release = usb_amradio_video_device_release;
-
-	radio->removed = 0;
-	radio->users = 0;
 	radio->usbdev = interface_to_usbdev(intf);
+	radio->intf = intf;
 	radio->curfreq = 95.16 * FREQ_MUL;
-	radio->stereo = -1;
 
 	mutex_init(&radio->lock);
 
-	video_set_drvdata(radio->videodev, radio);
+	video_set_drvdata(&radio->videodev, radio);
 
-	retval = video_register_device(radio->videodev,	VFL_TYPE_RADIO,	radio_nr);
+	retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO,
+					radio_nr);
 	if (retval < 0) {
 		dev_err(&intf->dev, "could not register video device\n");
-		video_device_release(radio->videodev);
-		v4l2_device_unregister(v4l2_dev);
-		kfree(radio->buffer);
-		kfree(radio);
-		return -EIO;
+		goto err_vdev;
 	}
 
 	usb_set_intfdata(intf, radio);
 	return 0;
+
+err_vdev:
+	v4l2_device_unregister(&radio->v4l2_dev);
+err_v4l2:
+	kfree(radio->buffer);
+err_nobuf:
+	kfree(radio);
+err:
+	return retval;
 }
 
 static int __init amradio_init(void)
diff --git a/drivers/media/radio/tef6862.c b/drivers/media/radio/tef6862.c
new file mode 100644
index 0000000..6e607ff
--- /dev/null
+++ b/drivers/media/radio/tef6862.c
@@ -0,0 +1,232 @@
+/*
+ * tef6862.c Philips TEF6862 Car Radio Enhanced Selectivity Tuner
+ * Copyright (c) 2009 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.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+
+#define DRIVER_NAME "tef6862"
+
+#define FREQ_MUL 16000
+
+#define TEF6862_LO_FREQ (875 * FREQ_MUL / 10)
+#define TEF6862_HI_FREQ (108 * FREQ_MUL)
+
+/* Write mode sub addresses */
+#define WM_SUB_BANDWIDTH	0x0
+#define WM_SUB_PLLM		0x1
+#define WM_SUB_PLLL		0x2
+#define WM_SUB_DAA		0x3
+#define WM_SUB_AGC		0x4
+#define WM_SUB_BAND		0x5
+#define WM_SUB_CONTROL		0x6
+#define WM_SUB_LEVEL		0x7
+#define WM_SUB_IFCF		0x8
+#define WM_SUB_IFCAP		0x9
+#define WM_SUB_ACD		0xA
+#define WM_SUB_TEST		0xF
+
+/* Different modes of the MSA register */
+#define MODE_BUFFER		0x0
+#define MODE_PRESET		0x1
+#define MODE_SEARCH		0x2
+#define MODE_AF_UPDATE		0x3
+#define MODE_JUMP		0x4
+#define MODE_CHECK		0x5
+#define MODE_LOAD		0x6
+#define MODE_END		0x7
+#define MODE_SHIFT		5
+
+struct tef6862_state {
+	struct v4l2_subdev sd;
+	unsigned long freq;
+};
+
+static inline struct tef6862_state *to_state(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct tef6862_state, sd);
+}
+
+static u16 tef6862_sigstr(struct i2c_client *client)
+{
+	u8 buf[4];
+	int err = i2c_master_recv(client, buf, sizeof(buf));
+	if (err == sizeof(buf))
+		return buf[3] << 8;
+	return 0;
+}
+
+static int tef6862_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v)
+{
+	if (v->index > 0)
+		return -EINVAL;
+
+	/* only support FM for now */
+	strlcpy(v->name, "FM", sizeof(v->name));
+	v->type = V4L2_TUNER_RADIO;
+	v->rangelow = TEF6862_LO_FREQ;
+	v->rangehigh = TEF6862_HI_FREQ;
+	v->rxsubchans = V4L2_TUNER_SUB_MONO;
+	v->capability = V4L2_TUNER_CAP_LOW;
+	v->audmode = V4L2_TUNER_MODE_STEREO;
+	v->signal = tef6862_sigstr(v4l2_get_subdevdata(sd));
+
+	return 0;
+}
+
+static int tef6862_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v)
+{
+	return v->index ? -EINVAL : 0;
+}
+
+static int tef6862_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
+{
+	struct tef6862_state *state = to_state(sd);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	u16 pll;
+	u8 i2cmsg[3];
+	int err;
+
+	if (f->tuner != 0)
+		return -EINVAL;
+
+	pll = 1964 + ((f->frequency - TEF6862_LO_FREQ) * 20) / FREQ_MUL;
+	i2cmsg[0] = (MODE_PRESET << MODE_SHIFT) | WM_SUB_PLLM;
+	i2cmsg[1] = (pll >> 8) & 0xff;
+	i2cmsg[2] = pll & 0xff;
+
+	err = i2c_master_send(client, i2cmsg, sizeof(i2cmsg));
+	if (!err)
+		state->freq = f->frequency;
+	return err;
+}
+
+static int tef6862_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
+{
+	struct tef6862_state *state = to_state(sd);
+
+	if (f->tuner != 0)
+		return -EINVAL;
+	f->type = V4L2_TUNER_RADIO;
+	f->frequency = state->freq;
+	return 0;
+}
+
+static int tef6862_g_chip_ident(struct v4l2_subdev *sd,
+	struct v4l2_dbg_chip_ident *chip)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEF6862, 0);
+}
+
+static const struct v4l2_subdev_tuner_ops tef6862_tuner_ops = {
+	.g_tuner = tef6862_g_tuner,
+	.s_tuner = tef6862_s_tuner,
+	.s_frequency = tef6862_s_frequency,
+	.g_frequency = tef6862_g_frequency,
+};
+
+static const struct v4l2_subdev_core_ops tef6862_core_ops = {
+	.g_chip_ident = tef6862_g_chip_ident,
+};
+
+static const struct v4l2_subdev_ops tef6862_ops = {
+	.core = &tef6862_core_ops,
+	.tuner = &tef6862_tuner_ops,
+};
+
+/*
+ * Generic i2c probe
+ * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
+ */
+
+static int __devinit tef6862_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct tef6862_state *state;
+	struct v4l2_subdev *sd;
+
+	/* Check if the adapter supports the needed features */
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -EIO;
+
+	v4l_info(client, "chip found @ 0x%02x (%s)\n",
+			client->addr << 1, client->adapter->name);
+
+	state = kmalloc(sizeof(struct tef6862_state), GFP_KERNEL);
+	if (state == NULL)
+		return -ENOMEM;
+	state->freq = TEF6862_LO_FREQ;
+
+	sd = &state->sd;
+	v4l2_i2c_subdev_init(sd, client, &tef6862_ops);
+
+	return 0;
+}
+
+static int __devexit tef6862_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+	v4l2_device_unregister_subdev(sd);
+	kfree(to_state(sd));
+	return 0;
+}
+
+static const struct i2c_device_id tef6862_id[] = {
+	{DRIVER_NAME, 0},
+	{},
+};
+
+MODULE_DEVICE_TABLE(i2c, tef6862_id);
+
+static struct i2c_driver tef6862_driver = {
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= DRIVER_NAME,
+	},
+	.probe		= tef6862_probe,
+	.remove		= tef6862_remove,
+	.id_table	= tef6862_id,
+};
+
+static __init int tef6862_init(void)
+{
+	return i2c_add_driver(&tef6862_driver);
+}
+
+static __exit void tef6862_exit(void)
+{
+	i2c_del_driver(&tef6862_driver);
+}
+
+module_init(tef6862_init);
+module_exit(tef6862_exit);
+
+MODULE_DESCRIPTION("TEF6862 Car Radio Enhanced Selectivity Tuner");
+MODULE_AUTHOR("Mocean Laboratories");
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index e6186b3..9dc74c9 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -600,7 +600,7 @@
 
 config VIDEO_PMS
 	tristate "Mediavision Pro Movie Studio Video For Linux"
-	depends on ISA && VIDEO_V4L1
+	depends on ISA && VIDEO_V4L2
 	help
 	  Say Y if you have such a thing.
 
@@ -847,6 +847,12 @@
 	help
 	  This driver supports MT9V022 cameras from Micron
 
+config SOC_CAMERA_RJ54N1
+	tristate "rj54n1cb0c support"
+	depends on SOC_CAMERA && I2C
+	help
+	  This is a rj54n1cb0c video driver
+
 config SOC_CAMERA_TW9910
 	tristate "tw9910 support"
 	depends on SOC_CAMERA && I2C
@@ -865,6 +871,12 @@
 	help
 	  This is a ov772x camera driver
 
+config SOC_CAMERA_OV9640
+	tristate "ov9640 camera support"
+	depends on SOC_CAMERA && I2C
+	help
+	  This is a ov9640 camera driver
+
 config MX1_VIDEO
 	bool
 
@@ -939,9 +951,14 @@
 source "drivers/media/video/et61x251/Kconfig"
 
 config VIDEO_OVCAMCHIP
-	tristate "OmniVision Camera Chip support"
+	tristate "OmniVision Camera Chip support (DEPRECATED)"
 	depends on I2C && VIDEO_V4L1
 	---help---
+	  This driver is DEPRECATED please use the gspca ov519 module
+	  instead. Note that for the ov511 / ov518 support of the gspca module
+	  you need atleast version 0.6.0 of libv4l and for the w9968cf
+	  atleast version 0.6.3 of libv4l.
+
 	  Support for the OmniVision OV6xxx and OV7xxx series of camera chips.
 	  This driver is intended to be used with the ov511 and w9968cf USB
 	  camera drivers.
@@ -950,9 +967,13 @@
 	  module will be called ovcamchip.
 
 config USB_W9968CF
-	tristate "USB W996[87]CF JPEG Dual Mode Camera support"
+	tristate "USB W996[87]CF JPEG Dual Mode Camera support (DEPRECATED)"
 	depends on VIDEO_V4L1 && I2C && VIDEO_OVCAMCHIP
 	---help---
+	  This driver is DEPRECATED please use the gspca ov519 module
+	  instead. Note that for the w9968cf support of the gspca module
+	  you need atleast version 0.6.3 of libv4l.
+
 	  Say Y here if you want support for cameras based on OV681 or
 	  Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips.
 
@@ -995,9 +1016,13 @@
 source "drivers/media/video/sn9c102/Kconfig"
 
 config USB_STV680
-	tristate "USB STV680 (Pencam) Camera support"
+	tristate "USB STV680 (Pencam) Camera support (DEPRECATED)"
 	depends on VIDEO_V4L1
 	---help---
+	  This driver is DEPRECATED please use the gspca stv0680 module
+	  instead. Note that for the gspca stv0680 module you need
+	  atleast version 0.6.3 of libv4l.
+
 	  Say Y here if you want to connect this type of camera to your
 	  computer's USB port. This includes the Pencam line of cameras.
 	  See <file:Documentation/video4linux/stv680.txt> for more information
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index e541932..7a2dcc3 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -77,6 +77,8 @@
 obj-$(CONFIG_SOC_CAMERA_MT9T031)	+= mt9t031.o
 obj-$(CONFIG_SOC_CAMERA_MT9V022)	+= mt9v022.o
 obj-$(CONFIG_SOC_CAMERA_OV772X)		+= ov772x.o
+obj-$(CONFIG_SOC_CAMERA_OV9640)		+= ov9640.o
+obj-$(CONFIG_SOC_CAMERA_RJ54N1)		+= rj54n1cb0c.o
 obj-$(CONFIG_SOC_CAMERA_TW9910)		+= tw9910.o
 
 # And now the v4l2 drivers:
diff --git a/drivers/media/video/adv7180.c b/drivers/media/video/adv7180.c
index 1b3cbd0..0826f0d 100644
--- a/drivers/media/video/adv7180.c
+++ b/drivers/media/video/adv7180.c
@@ -27,17 +27,40 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
+#include <linux/mutex.h>
 
 #define DRIVER_NAME "adv7180"
 
-#define ADV7180_INPUT_CONTROL_REG	0x00
-#define ADV7180_INPUT_CONTROL_PAL_BG_NTSC_J_SECAM	0x00
-#define ADV7180_AUTODETECT_ENABLE_REG	0x07
-#define ADV7180_AUTODETECT_DEFAULT	0x7f
+#define ADV7180_INPUT_CONTROL_REG			0x00
+#define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM	0x00
+#define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM_PED 0x10
+#define ADV7180_INPUT_CONTROL_AD_PAL_N_NTSC_J_SECAM	0x20
+#define ADV7180_INPUT_CONTROL_AD_PAL_N_NTSC_M_SECAM	0x30
+#define ADV7180_INPUT_CONTROL_NTSC_J			0x40
+#define ADV7180_INPUT_CONTROL_NTSC_M			0x50
+#define ADV7180_INPUT_CONTROL_PAL60			0x60
+#define ADV7180_INPUT_CONTROL_NTSC_443			0x70
+#define ADV7180_INPUT_CONTROL_PAL_BG			0x80
+#define ADV7180_INPUT_CONTROL_PAL_N			0x90
+#define ADV7180_INPUT_CONTROL_PAL_M			0xa0
+#define ADV7180_INPUT_CONTROL_PAL_M_PED			0xb0
+#define ADV7180_INPUT_CONTROL_PAL_COMB_N		0xc0
+#define ADV7180_INPUT_CONTROL_PAL_COMB_N_PED		0xd0
+#define ADV7180_INPUT_CONTROL_PAL_SECAM			0xe0
+#define ADV7180_INPUT_CONTROL_PAL_SECAM_PED		0xf0
 
+#define ADV7180_EXTENDED_OUTPUT_CONTROL_REG		0x04
+#define ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS		0xC5
 
-#define ADV7180_STATUS1_REG 0x10
-#define ADV7180_STATUS1_AUTOD_MASK 0x70
+#define ADV7180_AUTODETECT_ENABLE_REG			0x07
+#define ADV7180_AUTODETECT_DEFAULT			0x7f
+
+#define ADV7180_ADI_CTRL_REG				0x0e
+#define ADV7180_ADI_CTRL_IRQ_SPACE			0x20
+
+#define ADV7180_STATUS1_REG				0x10
+#define ADV7180_STATUS1_IN_LOCK		0x01
+#define ADV7180_STATUS1_AUTOD_MASK	0x70
 #define ADV7180_STATUS1_AUTOD_NTSM_M_J	0x00
 #define ADV7180_STATUS1_AUTOD_NTSC_4_43 0x10
 #define ADV7180_STATUS1_AUTOD_PAL_M	0x20
@@ -50,18 +73,37 @@
 #define ADV7180_IDENT_REG 0x11
 #define ADV7180_ID_7180 0x18
 
+#define ADV7180_ICONF1_ADI		0x40
+#define ADV7180_ICONF1_ACTIVE_LOW	0x01
+#define ADV7180_ICONF1_PSYNC_ONLY	0x10
+#define ADV7180_ICONF1_ACTIVE_TO_CLR	0xC0
+
+#define ADV7180_IRQ1_LOCK	0x01
+#define ADV7180_IRQ1_UNLOCK	0x02
+#define ADV7180_ISR1_ADI	0x42
+#define ADV7180_ICR1_ADI	0x43
+#define ADV7180_IMR1_ADI	0x44
+#define ADV7180_IMR2_ADI	0x48
+#define ADV7180_IRQ3_AD_CHANGE	0x08
+#define ADV7180_ISR3_ADI	0x4A
+#define ADV7180_ICR3_ADI	0x4B
+#define ADV7180_IMR3_ADI	0x4C
+#define ADV7180_IMR4_ADI	0x50
 
 struct adv7180_state {
-	struct v4l2_subdev sd;
+	struct v4l2_subdev	sd;
+	struct work_struct	work;
+	struct mutex		mutex; /* mutual excl. when accessing chip */
+	int			irq;
+	v4l2_std_id		curr_norm;
+	bool			autodetect;
 };
 
-static v4l2_std_id determine_norm(struct i2c_client *client)
+static v4l2_std_id adv7180_std_to_v4l2(u8 status1)
 {
-	u8 status1 = i2c_smbus_read_byte_data(client, ADV7180_STATUS1_REG);
-
 	switch (status1 & ADV7180_STATUS1_AUTOD_MASK) {
 	case ADV7180_STATUS1_AUTOD_NTSM_M_J:
-		return V4L2_STD_NTSC_M_JP;
+		return V4L2_STD_NTSC;
 	case ADV7180_STATUS1_AUTOD_NTSC_4_43:
 		return V4L2_STD_NTSC_443;
 	case ADV7180_STATUS1_AUTOD_PAL_M:
@@ -81,6 +123,53 @@
 	}
 }
 
+static int v4l2_std_to_adv7180(v4l2_std_id std)
+{
+	if (std == V4L2_STD_PAL_60)
+		return ADV7180_INPUT_CONTROL_PAL60;
+	if (std == V4L2_STD_NTSC_443)
+		return ADV7180_INPUT_CONTROL_NTSC_443;
+	if (std == V4L2_STD_PAL_N)
+		return ADV7180_INPUT_CONTROL_PAL_N;
+	if (std == V4L2_STD_PAL_M)
+		return ADV7180_INPUT_CONTROL_PAL_M;
+	if (std == V4L2_STD_PAL_Nc)
+		return ADV7180_INPUT_CONTROL_PAL_COMB_N;
+
+	if (std & V4L2_STD_PAL)
+		return ADV7180_INPUT_CONTROL_PAL_BG;
+	if (std & V4L2_STD_NTSC)
+		return ADV7180_INPUT_CONTROL_NTSC_M;
+	if (std & V4L2_STD_SECAM)
+		return ADV7180_INPUT_CONTROL_PAL_SECAM;
+
+	return -EINVAL;
+}
+
+static u32 adv7180_status_to_v4l2(u8 status1)
+{
+	if (!(status1 & ADV7180_STATUS1_IN_LOCK))
+		return V4L2_IN_ST_NO_SIGNAL;
+
+	return 0;
+}
+
+static int __adv7180_status(struct i2c_client *client, u32 *status,
+	v4l2_std_id *std)
+{
+	int status1 = i2c_smbus_read_byte_data(client, ADV7180_STATUS1_REG);
+
+	if (status1 < 0)
+		return status1;
+
+	if (status)
+		*status = adv7180_status_to_v4l2(status1);
+	if (std)
+		*std = adv7180_std_to_v4l2(status1);
+
+	return 0;
+}
+
 static inline struct adv7180_state *to_state(struct v4l2_subdev *sd)
 {
 	return container_of(sd, struct adv7180_state, sd);
@@ -88,10 +177,31 @@
 
 static int adv7180_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct adv7180_state *state = to_state(sd);
+	int err = mutex_lock_interruptible(&state->mutex);
+	if (err)
+		return err;
 
-	*std = determine_norm(client);
-	return 0;
+	/* when we are interrupt driven we know the state */
+	if (!state->autodetect || state->irq > 0)
+		*std = state->curr_norm;
+	else
+		err = __adv7180_status(v4l2_get_subdevdata(sd), NULL, std);
+
+	mutex_unlock(&state->mutex);
+	return err;
+}
+
+static int adv7180_g_input_status(struct v4l2_subdev *sd, u32 *status)
+{
+	struct adv7180_state *state = to_state(sd);
+	int ret = mutex_lock_interruptible(&state->mutex);
+	if (ret)
+		return ret;
+
+	ret = __adv7180_status(v4l2_get_subdevdata(sd), status, NULL);
+	mutex_unlock(&state->mutex);
+	return ret;
 }
 
 static int adv7180_g_chip_ident(struct v4l2_subdev *sd,
@@ -102,12 +212,51 @@
 	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7180, 0);
 }
 
+static int adv7180_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+	struct adv7180_state *state = to_state(sd);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int ret = mutex_lock_interruptible(&state->mutex);
+	if (ret)
+		return ret;
+
+	/* all standards -> autodetect */
+	if (std == V4L2_STD_ALL) {
+		ret = i2c_smbus_write_byte_data(client,
+			ADV7180_INPUT_CONTROL_REG,
+			ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM);
+		if (ret < 0)
+			goto out;
+
+		__adv7180_status(client, NULL, &state->curr_norm);
+		state->autodetect = true;
+	} else {
+		ret = v4l2_std_to_adv7180(std);
+		if (ret < 0)
+			goto out;
+
+		ret = i2c_smbus_write_byte_data(client,
+			ADV7180_INPUT_CONTROL_REG, ret);
+		if (ret < 0)
+			goto out;
+
+		state->curr_norm = std;
+		state->autodetect = false;
+	}
+	ret = 0;
+out:
+	mutex_unlock(&state->mutex);
+	return ret;
+}
+
 static const struct v4l2_subdev_video_ops adv7180_video_ops = {
 	.querystd = adv7180_querystd,
+	.g_input_status = adv7180_g_input_status,
 };
 
 static const struct v4l2_subdev_core_ops adv7180_core_ops = {
 	.g_chip_ident = adv7180_g_chip_ident,
+	.s_std = adv7180_s_std,
 };
 
 static const struct v4l2_subdev_ops adv7180_ops = {
@@ -115,12 +264,45 @@
 	.video = &adv7180_video_ops,
 };
 
+static void adv7180_work(struct work_struct *work)
+{
+	struct adv7180_state *state = container_of(work, struct adv7180_state,
+		work);
+	struct i2c_client *client = v4l2_get_subdevdata(&state->sd);
+	u8 isr3;
+
+	mutex_lock(&state->mutex);
+	i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
+		ADV7180_ADI_CTRL_IRQ_SPACE);
+	isr3 = i2c_smbus_read_byte_data(client, ADV7180_ISR3_ADI);
+	/* clear */
+	i2c_smbus_write_byte_data(client, ADV7180_ICR3_ADI, isr3);
+	i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG, 0);
+
+	if (isr3 & ADV7180_IRQ3_AD_CHANGE && state->autodetect)
+		__adv7180_status(client, NULL, &state->curr_norm);
+	mutex_unlock(&state->mutex);
+
+	enable_irq(state->irq);
+}
+
+static irqreturn_t adv7180_irq(int irq, void *devid)
+{
+	struct adv7180_state *state = devid;
+
+	schedule_work(&state->work);
+
+	disable_irq_nosync(state->irq);
+
+	return IRQ_HANDLED;
+}
+
 /*
  * Generic i2c probe
  * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
  */
 
-static int adv7180_probe(struct i2c_client *client,
+static __devinit int adv7180_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
 	struct adv7180_state *state;
@@ -135,32 +317,111 @@
 			client->addr << 1, client->adapter->name);
 
 	state = kzalloc(sizeof(struct adv7180_state), GFP_KERNEL);
-	if (state == NULL)
-		return -ENOMEM;
+	if (state == NULL) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	state->irq = client->irq;
+	INIT_WORK(&state->work, adv7180_work);
+	mutex_init(&state->mutex);
+	state->autodetect = true;
 	sd = &state->sd;
 	v4l2_i2c_subdev_init(sd, client, &adv7180_ops);
 
 	/* Initialize adv7180 */
-	/* enable autodetection */
+	/* Enable autodetection */
 	ret = i2c_smbus_write_byte_data(client, ADV7180_INPUT_CONTROL_REG,
-		ADV7180_INPUT_CONTROL_PAL_BG_NTSC_J_SECAM);
-	if (ret > 0)
-		ret = i2c_smbus_write_byte_data(client,
-			ADV7180_AUTODETECT_ENABLE_REG,
-			ADV7180_AUTODETECT_DEFAULT);
-	if (ret < 0) {
-		printk(KERN_ERR DRIVER_NAME
-			": Failed to communicate to chip: %d\n", ret);
-		return ret;
+		ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM);
+	if (ret < 0)
+		goto err_unreg_subdev;
+
+	ret = i2c_smbus_write_byte_data(client, ADV7180_AUTODETECT_ENABLE_REG,
+		ADV7180_AUTODETECT_DEFAULT);
+	if (ret < 0)
+		goto err_unreg_subdev;
+
+	/* ITU-R BT.656-4 compatible */
+	ret = i2c_smbus_write_byte_data(client,
+		ADV7180_EXTENDED_OUTPUT_CONTROL_REG,
+		ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS);
+	if (ret < 0)
+		goto err_unreg_subdev;
+
+	/* read current norm */
+	__adv7180_status(client, NULL, &state->curr_norm);
+
+	/* register for interrupts */
+	if (state->irq > 0) {
+		ret = request_irq(state->irq, adv7180_irq, 0, DRIVER_NAME,
+			state);
+		if (ret)
+			goto err_unreg_subdev;
+
+		ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
+			ADV7180_ADI_CTRL_IRQ_SPACE);
+		if (ret < 0)
+			goto err_unreg_subdev;
+
+		/* config the Interrupt pin to be active low */
+		ret = i2c_smbus_write_byte_data(client, ADV7180_ICONF1_ADI,
+			ADV7180_ICONF1_ACTIVE_LOW | ADV7180_ICONF1_PSYNC_ONLY);
+		if (ret < 0)
+			goto err_unreg_subdev;
+
+		ret = i2c_smbus_write_byte_data(client, ADV7180_IMR1_ADI, 0);
+		if (ret < 0)
+			goto err_unreg_subdev;
+
+		ret = i2c_smbus_write_byte_data(client, ADV7180_IMR2_ADI, 0);
+		if (ret < 0)
+			goto err_unreg_subdev;
+
+		/* enable AD change interrupts interrupts */
+		ret = i2c_smbus_write_byte_data(client, ADV7180_IMR3_ADI,
+			ADV7180_IRQ3_AD_CHANGE);
+		if (ret < 0)
+			goto err_unreg_subdev;
+
+		ret = i2c_smbus_write_byte_data(client, ADV7180_IMR4_ADI, 0);
+		if (ret < 0)
+			goto err_unreg_subdev;
+
+		ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
+			0);
+		if (ret < 0)
+			goto err_unreg_subdev;
 	}
 
 	return 0;
+
+err_unreg_subdev:
+	mutex_destroy(&state->mutex);
+	v4l2_device_unregister_subdev(sd);
+	kfree(state);
+err:
+	printk(KERN_ERR DRIVER_NAME ": Failed to probe: %d\n", ret);
+	return ret;
 }
 
-static int adv7180_remove(struct i2c_client *client)
+static __devexit int adv7180_remove(struct i2c_client *client)
 {
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct adv7180_state *state = to_state(sd);
 
+	if (state->irq > 0) {
+		free_irq(client->irq, state);
+		if (cancel_work_sync(&state->work)) {
+			/*
+			 * Work was pending, therefore we need to enable
+			 * IRQ here to balance the disable_irq() done in the
+			 * interrupt handler.
+			 */
+			enable_irq(state->irq);
+		}
+	}
+
+	mutex_destroy(&state->mutex);
 	v4l2_device_unregister_subdev(sd);
 	kfree(to_state(sd));
 	return 0;
@@ -179,7 +440,7 @@
 		.name	= DRIVER_NAME,
 	},
 	.probe		= adv7180_probe,
-	.remove		= adv7180_remove,
+	.remove		= __devexit_p(adv7180_remove),
 	.id_table	= adv7180_id,
 };
 
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
index 51527d7..1485aee 100644
--- a/drivers/media/video/au0828/au0828-video.c
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -830,7 +830,7 @@
 		au0828_uninit_isoc(dev);
 
 		/* Save some power by putting tuner to sleep */
-		v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby);
+		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
 
 		/* When close the device, set the usb intf0 into alt0 to free
 		   USB bandwidth */
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c
index f9330e3..5bb0f9e 100644
--- a/drivers/media/video/bt819.c
+++ b/drivers/media/video/bt819.c
@@ -299,7 +299,7 @@
 
 	v4l2_dbg(1, debug, sd, "set input %x\n", input);
 
-	if (input < 0 || input > 7)
+	if (input > 7)
 		return -EINVAL;
 
 	if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c
index ebd51af..84a957e 100644
--- a/drivers/media/video/bt8xx/bttv-input.c
+++ b/drivers/media/video/bt8xx/bttv-input.c
@@ -73,12 +73,12 @@
 
 	if ((ir->mask_keydown  &&  (0 != (gpio & ir->mask_keydown))) ||
 	    (ir->mask_keyup    &&  (0 == (gpio & ir->mask_keyup)))) {
-		ir_input_keydown(ir->dev,&ir->ir,data,data);
+		ir_input_keydown(ir->dev, &ir->ir, data);
 	} else {
 		/* HACK: Probably, ir->mask_keydown is missing
 		   for this board */
 		if (btv->c.type == BTTV_BOARD_WINFAST2000)
-			ir_input_keydown(ir->dev, &ir->ir, data, data);
+			ir_input_keydown(ir->dev, &ir->ir, data);
 
 		ir_input_nokey(ir->dev,&ir->ir);
 	}
@@ -104,7 +104,7 @@
 			gpio, data,
 			(gpio & ir->mask_keyup) ? " up" : "up/down");
 
-		ir_input_keydown(ir->dev, &ir->ir, data, data);
+		ir_input_keydown(ir->dev, &ir->ir, data);
 		if (keyup)
 			ir_input_nokey(ir->dev, &ir->ir);
 	} else {
@@ -118,7 +118,7 @@
 		if (keyup)
 			ir_input_nokey(ir->dev, &ir->ir);
 		else
-			ir_input_keydown(ir->dev, &ir->ir, data, data);
+			ir_input_keydown(ir->dev, &ir->ir, data);
 	}
 
 	ir->last_gpio = data | keyup;
@@ -368,7 +368,10 @@
 	snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
 		 pci_name(btv->c.pci));
 
-	ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
+	err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
+	if (err < 0)
+		goto err_out_free;
+
 	input_dev->name = ir->name;
 	input_dev->phys = ir->phys;
 	input_dev->id.bustype = BUS_PCI;
@@ -400,6 +403,7 @@
 	bttv_ir_stop(btv);
 	btv->remote = NULL;
  err_out_free:
+	ir_input_free(input_dev);
 	input_free_device(input_dev);
 	kfree(ir);
 	return err;
@@ -411,6 +415,7 @@
 		return;
 
 	bttv_ir_stop(btv);
+	ir_input_free(btv->remote->dev);
 	input_unregister_device(btv->remote->dev);
 	kfree(btv->remote);
 	btv->remote = NULL;
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index 536dedb..4392c76 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -99,10 +99,8 @@
 			     or_value);
 }
 
-static int cx18_av_init(struct v4l2_subdev *sd, u32 val)
+static void cx18_av_init(struct cx18 *cx)
 {
-	struct cx18 *cx = v4l2_get_subdevdata(sd);
-
 	/*
 	 * The crystal freq used in calculations in this driver will be
 	 * 28.636360 MHz.
@@ -125,7 +123,6 @@
 
 	/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
 	cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
-	return 0;
 }
 
 static void cx18_av_initialize(struct v4l2_subdev *sd)
@@ -198,7 +195,7 @@
 	cx18_av_and_or4(cx, CXADEC_CHIP_CTRL, 0xFFFBFFFF, 0x00120000);
 
 	/* Setup the Video and and Aux/Audio PLLs */
-	cx18_av_init(sd, 0);
+	cx18_av_init(cx);
 
 	/* set video to auto-detect */
 	/* Clear bits 11-12 to enable slow locking mode.  Set autodetect mode */
@@ -1355,7 +1352,6 @@
 static const struct v4l2_subdev_core_ops cx18_av_general_ops = {
 	.g_chip_ident = cx18_av_g_chip_ident,
 	.log_status = cx18_av_log_status,
-	.init = cx18_av_init,
 	.load_fw = cx18_av_load_fw,
 	.reset = cx18_av_reset,
 	.queryctrl = cx18_av_queryctrl,
@@ -1399,6 +1395,7 @@
 {
 	struct cx18_av_state *state = &cx->av_state;
 	struct v4l2_subdev *sd;
+	int err;
 
 	state->rev = cx18_av_read4(cx, CXADEC_CHIP_CTRL) & 0xffff;
 	state->id = ((state->rev >> 4) == CXADEC_CHIP_TYPE_MAKO)
@@ -1417,5 +1414,8 @@
 	snprintf(sd->name, sizeof(sd->name),
 		 "%s %03x", cx->v4l2_dev.name, (state->rev >> 4));
 	sd->grp_id = CX18_HW_418_AV;
-	return v4l2_device_register_subdev(&cx->v4l2_dev, sd);
+	err = v4l2_device_register_subdev(&cx->v4l2_dev, sd);
+	if (!err)
+		cx18_av_init(cx);
+	return err;
 }
diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h
index 9b84a0c..cafb7e9 100644
--- a/drivers/media/video/cx18/cx18-av-core.h
+++ b/drivers/media/video/cx18/cx18-av-core.h
@@ -294,7 +294,7 @@
 #define CXADEC_QAM_CONST_DEC       0x924
 #define CXADEC_QAM_ROTATOR_FREQ    0x948
 
-/* Bit defintions / settings used in Mako Audio */
+/* Bit definitions / settings used in Mako Audio */
 #define CXADEC_PREF_MODE_MONO_LANGA        0
 #define CXADEC_PREF_MODE_MONO_LANGB        1
 #define CXADEC_PREF_MODE_MONO_LANGC        2
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
index 444e3c7..af3d716 100644
--- a/drivers/media/video/cx18/cx18-cards.h
+++ b/drivers/media/video/cx18/cx18-cards.h
@@ -34,6 +34,9 @@
 #define CX18_HW_Z8F0811_IR_HAUP	(CX18_HW_Z8F0811_IR_RX_HAUP | \
 				 CX18_HW_Z8F0811_IR_TX_HAUP)
 
+#define CX18_HW_IR_ANY (CX18_HW_Z8F0811_IR_RX_HAUP | \
+			CX18_HW_Z8F0811_IR_TX_HAUP)
+
 /* video inputs */
 #define	CX18_CARD_INPUT_VID_TUNER	1
 #define	CX18_CARD_INPUT_SVIDEO1 	2
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 6dd51e2..7f65a47 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -87,7 +87,6 @@
 static int enc_mpg_bufsize = CX18_DEFAULT_ENC_MPG_BUFSIZE;
 static int enc_idx_bufsize = CX18_DEFAULT_ENC_IDX_BUFSIZE;
 static int enc_yuv_bufsize = CX18_DEFAULT_ENC_YUV_BUFSIZE;
-/* VBI bufsize based on standards supported by card tuner for now */
 static int enc_pcm_bufsize = CX18_DEFAULT_ENC_PCM_BUFSIZE;
 
 static int enc_ts_bufs = -1;
@@ -128,7 +127,6 @@
 module_param(enc_mpg_bufsize, int, 0644);
 module_param(enc_idx_bufsize, int, 0644);
 module_param(enc_yuv_bufsize, int, 0644);
-/* VBI bufsize based on standards supported by card tuner for now */
 module_param(enc_pcm_bufsize, int, 0644);
 
 module_param(enc_ts_bufs, int, 0644);
@@ -211,7 +209,9 @@
 		 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS));
 MODULE_PARM_DESC(enc_yuv_bufsize,
 		 "Size of an encoder YUV buffer (kB)\n"
-		 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFSIZE));
+		 "\t\t\tAllowed values are multiples of 33.75 kB rounded up\n"
+		 "\t\t\t(multiples of size required for 32 screen lines)\n"
+		 "\t\t\tDefault: 102");
 MODULE_PARM_DESC(enc_yuv_bufs,
 		 "Number of encoder YUV buffers\n"
 		 "\t\t\tDefault is computed from other enc_yuv_* parameters");
@@ -220,7 +220,7 @@
 		 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_VBI_BUFFERS));
 MODULE_PARM_DESC(enc_vbi_bufs,
 		 "Number of encoder VBI buffers\n"
-		 "\t\t\tDefault is computed from enc_vbi_buffers & tuner std");
+		 "\t\t\tDefault is computed from enc_vbi_buffers");
 MODULE_PARM_DESC(enc_pcm_buffers,
 		 "Encoder PCM buffer memory (MB). (enc_pcm_bufs can override)\n"
 		 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS));
@@ -499,10 +499,27 @@
 			continue;
 		}
 		/*
+		 * YUV is a special case where the stream_buf_size needs to be
+		 * an integral multiple of 33.75 kB (storage for 32 screens
+		 * lines to maintain alignment in case of lost buffers
+		 */
+		if (i == CX18_ENC_STREAM_TYPE_YUV) {
+			cx->stream_buf_size[i] *= 1024;
+			cx->stream_buf_size[i] -=
+			   (cx->stream_buf_size[i] % CX18_UNIT_ENC_YUV_BUFSIZE);
+
+			if (cx->stream_buf_size[i] < CX18_UNIT_ENC_YUV_BUFSIZE)
+				cx->stream_buf_size[i] =
+						CX18_UNIT_ENC_YUV_BUFSIZE;
+		}
+		/*
+		 * YUV is a special case where the stream_buf_size is
+		 * now in bytes.
 		 * VBI is a special case where the stream_buf_size is fixed
 		 * and already in bytes
 		 */
-		if (i == CX18_ENC_STREAM_TYPE_VBI) {
+		if (i == CX18_ENC_STREAM_TYPE_VBI ||
+		    i == CX18_ENC_STREAM_TYPE_YUV) {
 			if (cx->stream_buffers[i] < 0) {
 				cx->stream_buffers[i] =
 					cx->options.megabytes[i] * 1024 * 1024
@@ -513,18 +530,24 @@
 					cx->stream_buffers[i]
 					* cx->stream_buf_size[i]/(1024 * 1024);
 			}
-			continue;
-		}
-		/* All other streams have stream_buf_size in kB at this point */
-		if (cx->stream_buffers[i] < 0) {
-			cx->stream_buffers[i] = cx->options.megabytes[i] * 1024
-						/ cx->stream_buf_size[i];
 		} else {
-			/* N.B. This might round down to 0 */
-			cx->options.megabytes[i] =
-			  cx->stream_buffers[i] * cx->stream_buf_size[i] / 1024;
+			/* All other streams have stream_buf_size in kB here */
+			if (cx->stream_buffers[i] < 0) {
+				cx->stream_buffers[i] =
+						cx->options.megabytes[i] * 1024
+						/ cx->stream_buf_size[i];
+			} else {
+				/* N.B. This might round down to 0 */
+				cx->options.megabytes[i] =
+						cx->stream_buffers[i]
+						* cx->stream_buf_size[i] / 1024;
+			}
+			/* convert from kB to bytes */
+			cx->stream_buf_size[i] *= 1024;
 		}
-		cx->stream_buf_size[i] *= 1024; /* convert from kB to bytes */
+		CX18_DEBUG_INFO("Stream type %d options: %d MB, %d buffers, "
+				"%d bytes\n", i, cx->options.megabytes[i],
+				cx->stream_buffers[i], cx->stream_buf_size[i]);
 	}
 
 	cx->options.cardtype = cardtype[cx->instance];
@@ -669,6 +692,12 @@
 	cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
 	cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced;
 
+	/* IVTV style VBI insertion into MPEG streams */
+	INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_buf.list);
+	INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_mdl.list);
+	INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_mdl.buf_list);
+	list_add(&cx->vbi.sliced_mpeg_buf.list,
+		 &cx->vbi.sliced_mpeg_mdl.buf_list);
 	return 0;
 }
 
@@ -883,7 +912,6 @@
 		CX18_ERR("Could not register A/V decoder subdevice\n");
 		goto free_map;
 	}
-	cx18_call_hw(cx, CX18_HW_418_AV, core, init, 0);
 
 	/* Initialize GPIO Reset Controller to do chip resets during i2c init */
 	if (cx->card->hw_all & CX18_HW_GPIO_RESET_CTRL) {
@@ -1200,7 +1228,7 @@
       .remove =   cx18_remove,
 };
 
-static int module_start(void)
+static int __init module_start(void)
 {
 	printk(KERN_INFO "cx18:  Start initialization, version %s\n", CX18_VERSION);
 
@@ -1224,7 +1252,7 @@
 	return 0;
 }
 
-static void module_cleanup(void)
+static void __exit module_cleanup(void)
 {
 	pci_unregister_driver(&cx18_pci_driver);
 }
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index c6a1e90..e3f7911 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -50,6 +50,7 @@
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-device.h>
 #include <media/tuner.h>
+#include <media/ir-kbd-i2c.h>
 #include "cx18-mailbox.h"
 #include "cx18-av-core.h"
 #include "cx23418.h"
@@ -120,12 +121,16 @@
 /* Maximum firmware DMA buffers per stream */
 #define CX18_MAX_FW_MDLS_PER_STREAM 63
 
+/* YUV buffer sizes in bytes to ensure integer # of frames per buffer */
+#define CX18_UNIT_ENC_YUV_BUFSIZE	(720 *  32 * 3 / 2) /* bytes */
+#define CX18_625_LINE_ENC_YUV_BUFSIZE	(CX18_UNIT_ENC_YUV_BUFSIZE * 576/32)
+#define CX18_525_LINE_ENC_YUV_BUFSIZE	(CX18_UNIT_ENC_YUV_BUFSIZE * 480/32)
+
 /* DMA buffer, default size in kB allocated */
 #define CX18_DEFAULT_ENC_TS_BUFSIZE   32
 #define CX18_DEFAULT_ENC_MPG_BUFSIZE  32
 #define CX18_DEFAULT_ENC_IDX_BUFSIZE  32
-#define CX18_DEFAULT_ENC_YUV_BUFSIZE 128
-/* Default VBI bufsize based on standards supported by card tuner for now */
+#define CX18_DEFAULT_ENC_YUV_BUFSIZE  (CX18_UNIT_ENC_YUV_BUFSIZE * 3 / 1024 + 1)
 #define CX18_DEFAULT_ENC_PCM_BUFSIZE   4
 
 /* i2c stuff */
@@ -246,8 +251,8 @@
 	int radio;		/* enable/disable radio */
 };
 
-/* per-buffer bit flags */
-#define CX18_F_B_NEED_BUF_SWAP  0	/* this buffer should be byte swapped */
+/* per-mdl bit flags */
+#define CX18_F_M_NEED_SWAP  0	/* mdl buffer data must be endianess swapped */
 
 /* per-stream, s_flags */
 #define CX18_F_S_CLAIMED 	3	/* this stream is claimed */
@@ -274,18 +279,29 @@
 struct cx18_buffer {
 	struct list_head list;
 	dma_addr_t dma_handle;
-	u32 id;
-	unsigned long b_flags;
-	unsigned skipped;
 	char *buf;
 
 	u32 bytesused;
 	u32 readpos;
 };
 
+struct cx18_mdl {
+	struct list_head list;
+	u32 id;		/* index into cx->scb->cpu_mdl[] of 1st cx18_mdl_ent */
+
+	unsigned int skipped;
+	unsigned long m_flags;
+
+	struct list_head buf_list;
+	struct cx18_buffer *curr_buf; /* current buffer in list for reading */
+
+	u32 bytesused;
+	u32 readpos;
+};
+
 struct cx18_queue {
 	struct list_head list;
-	atomic_t buffers;
+	atomic_t depth;
 	u32 bytesused;
 	spinlock_t lock;
 };
@@ -337,7 +353,7 @@
 	const char *name;		/* name of the stream */
 	int type;			/* stream type */
 	u32 handle;			/* task handle */
-	unsigned mdl_offset;
+	unsigned int mdl_base_idx;
 
 	u32 id;
 	unsigned long s_flags;	/* status flags, see above */
@@ -346,14 +362,20 @@
 				   PCI_DMA_NONE */
 	wait_queue_head_t waitq;
 
-	/* Buffer Stats */
-	u32 buffers;
-	u32 buf_size;
+	/* Buffers */
+	struct list_head buf_pool;	/* buffers not attached to an MDL */
+	u32 buffers;			/* total buffers owned by this stream */
+	u32 buf_size;			/* size in bytes of a single buffer */
 
-	/* Buffer Queues */
-	struct cx18_queue q_free;	/* free buffers */
-	struct cx18_queue q_busy;	/* busy buffers - in use by firmware */
-	struct cx18_queue q_full;	/* full buffers - data for user apps */
+	/* MDL sizes - all stream MDLs are the same size */
+	u32 bufs_per_mdl;
+	u32 mdl_size;		/* total bytes in all buffers in a mdl */
+
+	/* MDL Queues */
+	struct cx18_queue q_free;	/* free - in rotation, not committed */
+	struct cx18_queue q_busy;	/* busy - in use by firmware */
+	struct cx18_queue q_full;	/* full - data for user apps */
+	struct cx18_queue q_idle;	/* idle - not in rotation */
 
 	struct work_struct out_work_order;
 
@@ -481,10 +503,11 @@
 	u32 inserted_frame;
 
 	/*
-	 * A dummy driver stream transfer buffer with a copy of the next
+	 * A dummy driver stream transfer mdl & buffer with a copy of the next
 	 * sliced_mpeg_data[] buffer for output to userland apps.
 	 * Only used in cx18-fileops.c, but its state needs to persist at times.
 	 */
+	struct cx18_mdl sliced_mpeg_mdl;
 	struct cx18_buffer sliced_mpeg_buf;
 };
 
@@ -511,10 +534,9 @@
 	u8 is_60hz;
 	u8 nof_inputs;		/* number of video inputs */
 	u8 nof_audio_inputs;	/* number of audio inputs */
-	u16 buffer_id;		/* buffer ID counter */
 	u32 v4l2_cap;		/* V4L2 capabilities of card */
 	u32 hw_flags; 		/* Hardware description of the board */
-	unsigned mdl_offset;
+	unsigned int free_mdl_idx;
 	struct cx18_scb __iomem *scb; /* pointer to SCB */
 	struct mutex epu2apu_mb_lock; /* protect driver to chip mailbox in SCB*/
 	struct mutex epu2cpu_mb_lock; /* protect driver to chip mailbox in SCB*/
@@ -585,6 +607,8 @@
 	struct i2c_algo_bit_data i2c_algo[2];
 	struct cx18_i2c_algo_callback_data i2c_algo_cb_data[2];
 
+	struct IR_i2c_init_data ir_i2c_init_data;
+
 	/* gpio */
 	u32 gpio_dir;
 	u32 gpio_val;
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index 51a0c33..71ad2d1 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -61,6 +61,7 @@
 	.top		 = MXL5005S_TOP_25P2,
 	.mod_mode        = MXL_DIGITAL_MODE,
 	.if_mode         = MXL_ZERO_IF,
+	.qam_gain        = 0x02,
 	.AgcMasterByte   = 0x00,
 };
 
@@ -71,7 +72,8 @@
 	.qam_if        = 44000,
 	.inversion     = S5H1409_INVERSION_OFF,
 	.status_mode   = S5H1409_DEMODLOCKING,
-	.mpeg_timing   = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
+	.mpeg_timing   = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
+	.hvr1600_opt   = S5H1409_HVR1600_OPTIMIZE
 };
 
 /*
@@ -360,9 +362,10 @@
 	dvb_net_init(dvb_adapter, &dvb->dvbnet, dmx);
 
 	CX18_INFO("DVB Frontend registered\n");
-	CX18_INFO("Registered DVB adapter%d for %s (%d x %d kB)\n",
+	CX18_INFO("Registered DVB adapter%d for %s (%d x %d.%02d kB)\n",
 		  stream->dvb.dvb_adapter.num, stream->name,
-		  stream->buffers, stream->buf_size/1024);
+		  stream->buffers, stream->buf_size/1024,
+		  (stream->buf_size * 100 / 1024) % 100);
 
 	mutex_init(&dvb->feedlock);
 	dvb->enabled = 1;
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index 04d9c25..4e278db 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -166,11 +166,12 @@
 }
 
 
-static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block, int *err)
+static struct cx18_mdl *cx18_get_mdl(struct cx18_stream *s, int non_block,
+				     int *err)
 {
 	struct cx18 *cx = s->cx;
 	struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
-	struct cx18_buffer *buf;
+	struct cx18_mdl *mdl;
 	DEFINE_WAIT(wait);
 
 	*err = 0;
@@ -185,32 +186,33 @@
 			}
 			if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
 			    !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
-				while ((buf = cx18_dequeue(s_vbi, &s_vbi->q_full))) {
+				while ((mdl = cx18_dequeue(s_vbi,
+							   &s_vbi->q_full))) {
 					/* byteswap and process VBI data */
-					cx18_process_vbi_data(cx, buf,
+					cx18_process_vbi_data(cx, mdl,
 							      s_vbi->type);
-					cx18_stream_put_buf_fw(s_vbi, buf);
+					cx18_stream_put_mdl_fw(s_vbi, mdl);
 				}
 			}
-			buf = &cx->vbi.sliced_mpeg_buf;
-			if (buf->readpos != buf->bytesused)
-				return buf;
+			mdl = &cx->vbi.sliced_mpeg_mdl;
+			if (mdl->readpos != mdl->bytesused)
+				return mdl;
 		}
 
 		/* do we have new data? */
-		buf = cx18_dequeue(s, &s->q_full);
-		if (buf) {
-			if (!test_and_clear_bit(CX18_F_B_NEED_BUF_SWAP,
-						&buf->b_flags))
-				return buf;
+		mdl = cx18_dequeue(s, &s->q_full);
+		if (mdl) {
+			if (!test_and_clear_bit(CX18_F_M_NEED_SWAP,
+						&mdl->m_flags))
+				return mdl;
 			if (s->type == CX18_ENC_STREAM_TYPE_MPG)
 				/* byteswap MPG data */
-				cx18_buf_swap(buf);
+				cx18_mdl_swap(mdl);
 			else {
 				/* byteswap and process VBI data */
-				cx18_process_vbi_data(cx, buf, s->type);
+				cx18_process_vbi_data(cx, mdl, s->type);
 			}
-			return buf;
+			return mdl;
 		}
 
 		/* return if end of stream */
@@ -229,7 +231,7 @@
 		prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
 		/* New buffers might have become available before we were added
 		   to the waitqueue */
-		if (!atomic_read(&s->q_full.buffers))
+		if (!atomic_read(&s->q_full.depth))
 			schedule();
 		finish_wait(&s->waitq, &wait);
 		if (signal_pending(current)) {
@@ -241,21 +243,28 @@
 	}
 }
 
-static void cx18_setup_sliced_vbi_buf(struct cx18 *cx)
+static void cx18_setup_sliced_vbi_mdl(struct cx18 *cx)
 {
+	struct cx18_mdl *mdl = &cx->vbi.sliced_mpeg_mdl;
+	struct cx18_buffer *buf = &cx->vbi.sliced_mpeg_buf;
 	int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
 
-	cx->vbi.sliced_mpeg_buf.buf = cx->vbi.sliced_mpeg_data[idx];
-	cx->vbi.sliced_mpeg_buf.bytesused = cx->vbi.sliced_mpeg_size[idx];
-	cx->vbi.sliced_mpeg_buf.readpos = 0;
+	buf->buf = cx->vbi.sliced_mpeg_data[idx];
+	buf->bytesused = cx->vbi.sliced_mpeg_size[idx];
+	buf->readpos = 0;
+
+	mdl->curr_buf = NULL;
+	mdl->bytesused = cx->vbi.sliced_mpeg_size[idx];
+	mdl->readpos = 0;
 }
 
 static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
-		struct cx18_buffer *buf, char __user *ubuf, size_t ucount)
+	struct cx18_buffer *buf, char __user *ubuf, size_t ucount, bool *stop)
 {
 	struct cx18 *cx = s->cx;
 	size_t len = buf->bytesused - buf->readpos;
 
+	*stop = false;
 	if (len > ucount)
 		len = ucount;
 	if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG &&
@@ -335,7 +344,8 @@
 				/* We declare we actually found a Program Pack*/
 				cx->search_pack_header = 0; /* expect vid PES */
 				len = (char *)q - start;
-				cx18_setup_sliced_vbi_buf(cx);
+				cx18_setup_sliced_vbi_mdl(cx);
+				*stop = true;
 				break;
 			}
 		}
@@ -352,6 +362,60 @@
 	return len;
 }
 
+/**
+ * list_entry_is_past_end - check if a previous loop cursor is off list end
+ * @pos:	the type * previously used as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Check if the entry's list_head is the head of the list, thus it's not a
+ * real entry but was the loop cursor that walked past the end
+ */
+#define list_entry_is_past_end(pos, head, member) \
+	(&pos->member == (head))
+
+static size_t cx18_copy_mdl_to_user(struct cx18_stream *s,
+		struct cx18_mdl *mdl, char __user *ubuf, size_t ucount)
+{
+	size_t tot_written = 0;
+	int rc;
+	bool stop = false;
+
+	if (mdl->curr_buf == NULL)
+		mdl->curr_buf = list_first_entry(&mdl->buf_list,
+						 struct cx18_buffer, list);
+
+	if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
+		/*
+		 * For some reason we've exhausted the buffers, but the MDL
+		 * object still said some data was unread.
+		 * Fix that and bail out.
+		 */
+		mdl->readpos = mdl->bytesused;
+		return 0;
+	}
+
+	list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) {
+
+		if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused)
+			continue;
+
+		rc = cx18_copy_buf_to_user(s, mdl->curr_buf, ubuf + tot_written,
+					   ucount - tot_written, &stop);
+		if (rc < 0)
+			return rc;
+		mdl->readpos += rc;
+		tot_written += rc;
+
+		if (stop ||	/* Forced stopping point for VBI insertion */
+		    tot_written >= ucount ||	/* Reader request statisfied */
+		    mdl->curr_buf->readpos < mdl->curr_buf->bytesused ||
+		    mdl->readpos >= mdl->bytesused) /* MDL buffers drained */
+			break;
+	}
+	return tot_written;
+}
+
 static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
 		size_t tot_count, int non_block)
 {
@@ -373,12 +437,12 @@
 		single_frame = 1;
 
 	for (;;) {
-		struct cx18_buffer *buf;
+		struct cx18_mdl *mdl;
 		int rc;
 
-		buf = cx18_get_buffer(s, non_block, &rc);
+		mdl = cx18_get_mdl(s, non_block, &rc);
 		/* if there is no data available... */
-		if (buf == NULL) {
+		if (mdl == NULL) {
 			/* if we got data, then return that regardless */
 			if (tot_written)
 				break;
@@ -392,20 +456,20 @@
 			return rc;
 		}
 
-		rc = cx18_copy_buf_to_user(s, buf, ubuf + tot_written,
+		rc = cx18_copy_mdl_to_user(s, mdl, ubuf + tot_written,
 				tot_count - tot_written);
 
-		if (buf != &cx->vbi.sliced_mpeg_buf) {
-			if (buf->readpos == buf->bytesused)
-				cx18_stream_put_buf_fw(s, buf);
+		if (mdl != &cx->vbi.sliced_mpeg_mdl) {
+			if (mdl->readpos == mdl->bytesused)
+				cx18_stream_put_mdl_fw(s, mdl);
 			else
-				cx18_push(s, buf, &s->q_full);
-		} else if (buf->readpos == buf->bytesused) {
+				cx18_push(s, mdl, &s->q_full);
+		} else if (mdl->readpos == mdl->bytesused) {
 			int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
 
 			cx->vbi.sliced_mpeg_size[idx] = 0;
 			cx->vbi.inserted_frame++;
-			cx->vbi_data_inserted += buf->bytesused;
+			cx->vbi_data_inserted += mdl->bytesused;
 		}
 		if (rc < 0)
 			return rc;
@@ -543,7 +607,7 @@
 	CX18_DEBUG_HI_FILE("Encoder poll\n");
 	poll_wait(filp, &s->waitq, wait);
 
-	if (atomic_read(&s->q_full.buffers))
+	if (atomic_read(&s->q_full.depth))
 		return POLLIN | POLLRDNORM;
 	if (eof)
 		return POLLHUP;
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index 2477461..eecf29a 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -28,7 +28,6 @@
 #include "cx18-gpio.h"
 #include "cx18-i2c.h"
 #include "cx18-irq.h"
-#include <media/ir-kbd-i2c.h>
 
 #define CX18_REG_I2C_1_WR   0xf15000
 #define CX18_REG_I2C_1_RD   0xf15008
@@ -97,17 +96,11 @@
 	"ir_rx_z8f0811_haup",
 };
 
-static const struct IR_i2c_init_data z8f0811_ir_init_data = {
-	.ir_codes = &ir_codes_hauppauge_new_table,
-	.internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR,
-	.type = IR_TYPE_RC5,
-	.name = "CX23418 Z8F0811 Hauppauge",
-};
-
-static int cx18_i2c_new_ir(struct i2c_adapter *adap, u32 hw, const char *type,
-			   u8 addr)
+static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
+			   const char *type, u8 addr)
 {
 	struct i2c_board_info info;
+	struct IR_i2c_init_data *init_data = &cx->ir_i2c_init_data;
 	unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
 
 	memset(&info, 0, sizeof(struct i2c_board_info));
@@ -116,9 +109,11 @@
 	/* Our default information for ir-kbd-i2c.c to use */
 	switch (hw) {
 	case CX18_HW_Z8F0811_IR_RX_HAUP:
-		info.platform_data = (void *) &z8f0811_ir_init_data;
-		break;
-	default:
+		init_data->ir_codes = &ir_codes_hauppauge_new_table;
+		init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
+		init_data->type = IR_TYPE_RC5;
+		init_data->name = cx->card_name;
+		info.platform_data = init_data;
 		break;
 	}
 
@@ -154,8 +149,8 @@
 		return sd != NULL ? 0 : -1;
 	}
 
-	if (hw & CX18_HW_Z8F0811_IR_HAUP)
-		return cx18_i2c_new_ir(adap, hw, type, hw_addrs[idx]);
+	if (hw & CX18_HW_IR_ANY)
+		return cx18_i2c_new_ir(cx, adap, hw, type, hw_addrs[idx]);
 
 	/* Is it not an I2C device or one we do not wish to register? */
 	if (!hw_addrs[idx])
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index fc76e4d..3e4fc19 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -910,7 +910,8 @@
 			continue;
 		CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n",
 			  s->name, s->s_flags,
-			  atomic_read(&s->q_full.buffers) * 100 / s->buffers,
+			  atomic_read(&s->q_full.depth) * s->bufs_per_mdl * 100
+			   / s->buffers,
 			  (s->buffers * s->buf_size) / 1024, s->buffers);
 	}
 	CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index afe46c3..f231dd0 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -131,13 +131,39 @@
  * Functions that run in a work_queue work handling context
  */
 
+static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl)
+{
+	struct cx18_buffer *buf;
+
+	if (!s->dvb.enabled || mdl->bytesused == 0)
+		return;
+
+	/* We ignore mdl and buf readpos accounting here - it doesn't matter */
+
+	/* The likely case */
+	if (list_is_singular(&mdl->buf_list)) {
+		buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
+				       list);
+		if (buf->bytesused)
+			dvb_dmx_swfilter(&s->dvb.demux,
+					 buf->buf, buf->bytesused);
+		return;
+	}
+
+	list_for_each_entry(buf, &mdl->buf_list, list) {
+		if (buf->bytesused == 0)
+			break;
+		dvb_dmx_swfilter(&s->dvb.demux, buf->buf, buf->bytesused);
+	}
+}
+
 static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
 {
 	u32 handle, mdl_ack_count, id;
 	struct cx18_mailbox *mb;
 	struct cx18_mdl_ack *mdl_ack;
 	struct cx18_stream *s;
-	struct cx18_buffer *buf;
+	struct cx18_mdl *mdl;
 	int i;
 
 	mb = &order->mb;
@@ -158,7 +184,7 @@
 		id = mdl_ack->id;
 		/*
 		 * Simple integrity check for processing a stale (and possibly
-		 * inconsistent mailbox): make sure the buffer id is in the
+		 * inconsistent mailbox): make sure the MDL id is in the
 		 * valid range for the stream.
 		 *
 		 * We go through the trouble of dealing with stale mailboxes
@@ -169,44 +195,42 @@
 		 * There are occasions when we get a half changed mailbox,
 		 * which this check catches for a handle & id mismatch.  If the
 		 * handle and id do correspond, the worst case is that we
-		 * completely lost the old buffer, but pick up the new buffer
+		 * completely lost the old MDL, but pick up the new MDL
 		 * early (but the new mdl_ack is guaranteed to be good in this
 		 * case as the firmware wouldn't point us to a new mdl_ack until
 		 * it's filled in).
 		 *
-		 * cx18_queue_get buf() will detect the lost buffers
+		 * cx18_queue_get_mdl() will detect the lost MDLs
 		 * and send them back to q_free for fw rotation eventually.
 		 */
 		if ((order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) &&
-		    !(id >= s->mdl_offset &&
-		      id < (s->mdl_offset + s->buffers))) {
+		    !(id >= s->mdl_base_idx &&
+		      id < (s->mdl_base_idx + s->buffers))) {
 			CX18_WARN("Fell behind! Ignoring stale mailbox with "
-				  " inconsistent data. Lost buffer for mailbox "
+				  " inconsistent data. Lost MDL for mailbox "
 				  "seq no %d\n", mb->request);
 			break;
 		}
-		buf = cx18_queue_get_buf(s, id, mdl_ack->data_used);
+		mdl = cx18_queue_get_mdl(s, id, mdl_ack->data_used);
 
-		CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id);
-		if (buf == NULL) {
-			CX18_WARN("Could not find buf %d for stream %s\n",
+		CX18_DEBUG_HI_DMA("DMA DONE for %s (MDL %d)\n", s->name, id);
+		if (mdl == NULL) {
+			CX18_WARN("Could not find MDL %d for stream %s\n",
 				  id, s->name);
 			continue;
 		}
 
 		CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n",
-				  s->name, buf->bytesused);
+				  s->name, mdl->bytesused);
 
 		if (s->type != CX18_ENC_STREAM_TYPE_TS)
-			cx18_enqueue(s, buf, &s->q_full);
+			cx18_enqueue(s, mdl, &s->q_full);
 		else {
-			if (s->dvb.enabled)
-				dvb_dmx_swfilter(&s->dvb.demux, buf->buf,
-						 buf->bytesused);
-			cx18_enqueue(s, buf, &s->q_free);
+			cx18_mdl_send_to_dvb(s, mdl);
+			cx18_enqueue(s, mdl, &s->q_free);
 		}
 	}
-	/* Put as many buffers as possible back into fw use */
+	/* Put as many MDLs as possible back into fw use */
 	cx18_stream_load_fw_queue(s);
 
 	wake_up(&cx->dma_waitq);
@@ -616,7 +640,7 @@
 
 	/*
 	 * Wait for XPU to perform extra actions for the caller in some cases.
-	 * e.g. CX18_CPU_DE_RELEASE_MDL will cause the CPU to send all buffers
+	 * e.g. CX18_CPU_DE_RELEASE_MDL will cause the CPU to send all MDLs
 	 * back in a burst shortly thereafter
 	 */
 	if (info->flags & API_SLOW)
diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/video/cx18/cx18-mailbox.h
index e23aaac..33a3491 100644
--- a/drivers/media/video/cx18/cx18-mailbox.h
+++ b/drivers/media/video/cx18/cx18-mailbox.h
@@ -39,14 +39,14 @@
 struct cx18;
 
 /*
- * This structure is used by CPU to provide completed buffers information
- * Its structure is dictrated by the layout of the SCB, required by the
- * firmware, but its defintion needs to be here, instead of in cx18-scb.h,
+ * This structure is used by CPU to provide completed MDL & buffers information.
+ * Its structure is dictated by the layout of the SCB, required by the
+ * firmware, but its definition needs to be here, instead of in cx18-scb.h,
  * for mailbox work order scheduling
  */
 struct cx18_mdl_ack {
     u32 id;        /* ID of a completed MDL */
-    u32 data_used; /* Total data filled in the MDL for buffer 'id' */
+    u32 data_used; /* Total data filled in the MDL with 'id' */
 };
 
 /* The cx18_mailbox struct is the mailbox structure which is used for passing
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index fa1ed78..6330482 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -26,6 +26,7 @@
 #include "cx18-queue.h"
 #include "cx18-streams.h"
 #include "cx18-scb.h"
+#include "cx18-io.h"
 
 void cx18_buf_swap(struct cx18_buffer *buf)
 {
@@ -35,151 +36,312 @@
 		swab32s((u32 *)(buf->buf + i));
 }
 
+void _cx18_mdl_swap(struct cx18_mdl *mdl)
+{
+	struct cx18_buffer *buf;
+
+	list_for_each_entry(buf, &mdl->buf_list, list) {
+		if (buf->bytesused == 0)
+			break;
+		cx18_buf_swap(buf);
+	}
+}
+
 void cx18_queue_init(struct cx18_queue *q)
 {
 	INIT_LIST_HEAD(&q->list);
-	atomic_set(&q->buffers, 0);
+	atomic_set(&q->depth, 0);
 	q->bytesused = 0;
 }
 
-struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
+struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl,
 				 struct cx18_queue *q, int to_front)
 {
-	/* clear the buffer if it is not to be enqueued to the full queue */
+	/* clear the mdl if it is not to be enqueued to the full queue */
 	if (q != &s->q_full) {
-		buf->bytesused = 0;
-		buf->readpos = 0;
-		buf->b_flags = 0;
-		buf->skipped = 0;
+		mdl->bytesused = 0;
+		mdl->readpos = 0;
+		mdl->m_flags = 0;
+		mdl->skipped = 0;
+		mdl->curr_buf = NULL;
 	}
 
 	/* q_busy is restricted to a max buffer count imposed by firmware */
 	if (q == &s->q_busy &&
-	    atomic_read(&q->buffers) >= CX18_MAX_FW_MDLS_PER_STREAM)
+	    atomic_read(&q->depth) >= CX18_MAX_FW_MDLS_PER_STREAM)
 		q = &s->q_free;
 
 	spin_lock(&q->lock);
 
 	if (to_front)
-		list_add(&buf->list, &q->list); /* LIFO */
+		list_add(&mdl->list, &q->list); /* LIFO */
 	else
-		list_add_tail(&buf->list, &q->list); /* FIFO */
-	q->bytesused += buf->bytesused - buf->readpos;
-	atomic_inc(&q->buffers);
+		list_add_tail(&mdl->list, &q->list); /* FIFO */
+	q->bytesused += mdl->bytesused - mdl->readpos;
+	atomic_inc(&q->depth);
 
 	spin_unlock(&q->lock);
 	return q;
 }
 
-struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
+struct cx18_mdl *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
 {
-	struct cx18_buffer *buf = NULL;
+	struct cx18_mdl *mdl = NULL;
 
 	spin_lock(&q->lock);
 	if (!list_empty(&q->list)) {
-		buf = list_first_entry(&q->list, struct cx18_buffer, list);
-		list_del_init(&buf->list);
-		q->bytesused -= buf->bytesused - buf->readpos;
-		buf->skipped = 0;
-		atomic_dec(&q->buffers);
+		mdl = list_first_entry(&q->list, struct cx18_mdl, list);
+		list_del_init(&mdl->list);
+		q->bytesused -= mdl->bytesused - mdl->readpos;
+		mdl->skipped = 0;
+		atomic_dec(&q->depth);
 	}
 	spin_unlock(&q->lock);
-	return buf;
+	return mdl;
 }
 
-struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id,
+static void _cx18_mdl_update_bufs_for_cpu(struct cx18_stream *s,
+					  struct cx18_mdl *mdl)
+{
+	struct cx18_buffer *buf;
+	u32 buf_size = s->buf_size;
+	u32 bytesused = mdl->bytesused;
+
+	list_for_each_entry(buf, &mdl->buf_list, list) {
+		buf->readpos = 0;
+		if (bytesused >= buf_size) {
+			buf->bytesused = buf_size;
+			bytesused -= buf_size;
+		} else {
+			buf->bytesused = bytesused;
+			bytesused = 0;
+		}
+		cx18_buf_sync_for_cpu(s, buf);
+	}
+}
+
+static inline void cx18_mdl_update_bufs_for_cpu(struct cx18_stream *s,
+						struct cx18_mdl *mdl)
+{
+	struct cx18_buffer *buf;
+
+	if (list_is_singular(&mdl->buf_list)) {
+		buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
+				       list);
+		buf->bytesused = mdl->bytesused;
+		buf->readpos = 0;
+		cx18_buf_sync_for_cpu(s, buf);
+	} else {
+		_cx18_mdl_update_bufs_for_cpu(s, mdl);
+	}
+}
+
+struct cx18_mdl *cx18_queue_get_mdl(struct cx18_stream *s, u32 id,
 	u32 bytesused)
 {
 	struct cx18 *cx = s->cx;
-	struct cx18_buffer *buf;
-	struct cx18_buffer *tmp;
-	struct cx18_buffer *ret = NULL;
+	struct cx18_mdl *mdl;
+	struct cx18_mdl *tmp;
+	struct cx18_mdl *ret = NULL;
 	LIST_HEAD(sweep_up);
 
 	/*
 	 * We don't have to acquire multiple q locks here, because we are
 	 * serialized by the single threaded work handler.
-	 * Buffers from the firmware will thus remain in order as
+	 * MDLs from the firmware will thus remain in order as
 	 * they are moved from q_busy to q_full or to the dvb ring buffer.
 	 */
 	spin_lock(&s->q_busy.lock);
-	list_for_each_entry_safe(buf, tmp, &s->q_busy.list, list) {
+	list_for_each_entry_safe(mdl, tmp, &s->q_busy.list, list) {
 		/*
 		 * We should find what the firmware told us is done,
 		 * right at the front of the queue.  If we don't, we likely have
-		 * missed a buffer done message from the firmware.
-		 * Once we skip a buffer repeatedly, relative to the size of
+		 * missed an mdl done message from the firmware.
+		 * Once we skip an mdl repeatedly, relative to the size of
 		 * q_busy, we have high confidence we've missed it.
 		 */
-		if (buf->id != id) {
-			buf->skipped++;
-			if (buf->skipped >= atomic_read(&s->q_busy.buffers)-1) {
-				/* buffer must have fallen out of rotation */
-				CX18_WARN("Skipped %s, buffer %d, %d "
+		if (mdl->id != id) {
+			mdl->skipped++;
+			if (mdl->skipped >= atomic_read(&s->q_busy.depth)-1) {
+				/* mdl must have fallen out of rotation */
+				CX18_WARN("Skipped %s, MDL %d, %d "
 					  "times - it must have dropped out of "
-					  "rotation\n", s->name, buf->id,
-					  buf->skipped);
+					  "rotation\n", s->name, mdl->id,
+					  mdl->skipped);
 				/* Sweep it up to put it back into rotation */
-				list_move_tail(&buf->list, &sweep_up);
-				atomic_dec(&s->q_busy.buffers);
+				list_move_tail(&mdl->list, &sweep_up);
+				atomic_dec(&s->q_busy.depth);
 			}
 			continue;
 		}
 		/*
-		 * We pull the desired buffer off of the queue here.  Something
+		 * We pull the desired mdl off of the queue here.  Something
 		 * will have to put it back on a queue later.
 		 */
-		list_del_init(&buf->list);
-		atomic_dec(&s->q_busy.buffers);
-		ret = buf;
+		list_del_init(&mdl->list);
+		atomic_dec(&s->q_busy.depth);
+		ret = mdl;
 		break;
 	}
 	spin_unlock(&s->q_busy.lock);
 
 	/*
-	 * We found the buffer for which we were looking.  Get it ready for
+	 * We found the mdl for which we were looking.  Get it ready for
 	 * the caller to put on q_full or in the dvb ring buffer.
 	 */
 	if (ret != NULL) {
 		ret->bytesused = bytesused;
 		ret->skipped = 0;
-		/* readpos and b_flags were 0'ed when the buf went on q_busy */
-		cx18_buf_sync_for_cpu(s, ret);
+		/* 0'ed readpos, m_flags & curr_buf when mdl went on q_busy */
+		cx18_mdl_update_bufs_for_cpu(s, ret);
 		if (s->type != CX18_ENC_STREAM_TYPE_TS)
-			set_bit(CX18_F_B_NEED_BUF_SWAP, &ret->b_flags);
+			set_bit(CX18_F_M_NEED_SWAP, &ret->m_flags);
 	}
 
-	/* Put any buffers the firmware is ignoring back into normal rotation */
-	list_for_each_entry_safe(buf, tmp, &sweep_up, list) {
-		list_del_init(&buf->list);
-		cx18_enqueue(s, buf, &s->q_free);
+	/* Put any mdls the firmware is ignoring back into normal rotation */
+	list_for_each_entry_safe(mdl, tmp, &sweep_up, list) {
+		list_del_init(&mdl->list);
+		cx18_enqueue(s, mdl, &s->q_free);
 	}
 	return ret;
 }
 
-/* Move all buffers of a queue to q_free, while flushing the buffers */
-static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q)
+/* Move all mdls of a queue, while flushing the mdl */
+static void cx18_queue_flush(struct cx18_stream *s,
+			     struct cx18_queue *q_src, struct cx18_queue *q_dst)
 {
-	struct cx18_buffer *buf;
+	struct cx18_mdl *mdl;
 
-	if (q == &s->q_free)
+	/* It only makes sense to flush to q_free or q_idle */
+	if (q_src == q_dst || q_dst == &s->q_full || q_dst == &s->q_busy)
 		return;
 
-	spin_lock(&q->lock);
-	while (!list_empty(&q->list)) {
-		buf = list_first_entry(&q->list, struct cx18_buffer, list);
-		list_move_tail(&buf->list, &s->q_free.list);
-		buf->bytesused = buf->readpos = buf->b_flags = buf->skipped = 0;
-		atomic_inc(&s->q_free.buffers);
+	spin_lock(&q_src->lock);
+	spin_lock(&q_dst->lock);
+	while (!list_empty(&q_src->list)) {
+		mdl = list_first_entry(&q_src->list, struct cx18_mdl, list);
+		list_move_tail(&mdl->list, &q_dst->list);
+		mdl->bytesused = 0;
+		mdl->readpos = 0;
+		mdl->m_flags = 0;
+		mdl->skipped = 0;
+		mdl->curr_buf = NULL;
+		atomic_inc(&q_dst->depth);
 	}
-	cx18_queue_init(q);
-	spin_unlock(&q->lock);
+	cx18_queue_init(q_src);
+	spin_unlock(&q_src->lock);
+	spin_unlock(&q_dst->lock);
 }
 
 void cx18_flush_queues(struct cx18_stream *s)
 {
-	cx18_queue_flush(s, &s->q_busy);
-	cx18_queue_flush(s, &s->q_full);
+	cx18_queue_flush(s, &s->q_busy, &s->q_free);
+	cx18_queue_flush(s, &s->q_full, &s->q_free);
+}
+
+/*
+ * Note, s->buf_pool is not protected by a lock,
+ * the stream better not have *anything* going on when calling this
+ */
+void cx18_unload_queues(struct cx18_stream *s)
+{
+	struct cx18_queue *q_idle = &s->q_idle;
+	struct cx18_mdl *mdl;
+	struct cx18_buffer *buf;
+
+	/* Move all MDLS to q_idle */
+	cx18_queue_flush(s, &s->q_busy, q_idle);
+	cx18_queue_flush(s, &s->q_full, q_idle);
+	cx18_queue_flush(s, &s->q_free, q_idle);
+
+	/* Reset MDL id's and move all buffers back to the stream's buf_pool */
+	spin_lock(&q_idle->lock);
+	list_for_each_entry(mdl, &q_idle->list, list) {
+		while (!list_empty(&mdl->buf_list)) {
+			buf = list_first_entry(&mdl->buf_list,
+					       struct cx18_buffer, list);
+			list_move_tail(&buf->list, &s->buf_pool);
+			buf->bytesused = 0;
+			buf->readpos = 0;
+		}
+		mdl->id = s->mdl_base_idx; /* reset id to a "safe" value */
+		/* all other mdl fields were cleared by cx18_queue_flush() */
+	}
+	spin_unlock(&q_idle->lock);
+}
+
+/*
+ * Note, s->buf_pool is not protected by a lock,
+ * the stream better not have *anything* going on when calling this
+ */
+void cx18_load_queues(struct cx18_stream *s)
+{
+	struct cx18 *cx = s->cx;
+	struct cx18_mdl *mdl;
+	struct cx18_buffer *buf;
+	int mdl_id;
+	int i;
+	u32 partial_buf_size;
+
+	/*
+	 * Attach buffers to MDLs, give the MDLs ids, and add MDLs to q_free
+	 * Excess MDLs are left on q_idle
+	 * Excess buffers are left in buf_pool and/or on an MDL in q_idle
+	 */
+	mdl_id = s->mdl_base_idx;
+	for (mdl = cx18_dequeue(s, &s->q_idle), i = s->bufs_per_mdl;
+	     mdl != NULL && i == s->bufs_per_mdl;
+	     mdl = cx18_dequeue(s, &s->q_idle)) {
+
+		mdl->id = mdl_id;
+
+		for (i = 0; i < s->bufs_per_mdl; i++) {
+			if (list_empty(&s->buf_pool))
+				break;
+
+			buf = list_first_entry(&s->buf_pool, struct cx18_buffer,
+					       list);
+			list_move_tail(&buf->list, &mdl->buf_list);
+
+			/* update the firmware's MDL array with this buffer */
+			cx18_writel(cx, buf->dma_handle,
+				    &cx->scb->cpu_mdl[mdl_id + i].paddr);
+			cx18_writel(cx, s->buf_size,
+				    &cx->scb->cpu_mdl[mdl_id + i].length);
+		}
+
+		if (i == s->bufs_per_mdl) {
+			/*
+			 * The encoder doesn't honor s->mdl_size.  So in the
+			 * case of a non-integral number of buffers to meet
+			 * mdl_size, we lie about the size of the last buffer
+			 * in the MDL to get the encoder to really only send
+			 * us mdl_size bytes per MDL transfer.
+			 */
+			partial_buf_size = s->mdl_size % s->buf_size;
+			if (partial_buf_size) {
+				cx18_writel(cx, partial_buf_size,
+				      &cx->scb->cpu_mdl[mdl_id + i - 1].length);
+			}
+			cx18_enqueue(s, mdl, &s->q_free);
+		} else {
+			/* Not enough buffers for this MDL; we won't use it */
+			cx18_push(s, mdl, &s->q_idle);
+		}
+		mdl_id += i;
+	}
+}
+
+void _cx18_mdl_sync_for_device(struct cx18_stream *s, struct cx18_mdl *mdl)
+{
+	int dma = s->dma;
+	u32 buf_size = s->buf_size;
+	struct pci_dev *pci_dev = s->cx->pci_dev;
+	struct cx18_buffer *buf;
+
+	list_for_each_entry(buf, &mdl->buf_list, list)
+		pci_dma_sync_single_for_device(pci_dev, buf->dma_handle,
+					       buf_size, dma);
 }
 
 int cx18_stream_alloc(struct cx18_stream *s)
@@ -190,44 +352,62 @@
 	if (s->buffers == 0)
 		return 0;
 
-	CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers (%dkB total)\n",
+	CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers "
+			"(%d.%02d kB total)\n",
 		s->name, s->buffers, s->buf_size,
-		s->buffers * s->buf_size / 1024);
+		s->buffers * s->buf_size / 1024,
+		(s->buffers * s->buf_size * 100 / 1024) % 100);
 
-	if (((char __iomem *)&cx->scb->cpu_mdl[cx->mdl_offset + s->buffers] -
+	if (((char __iomem *)&cx->scb->cpu_mdl[cx->free_mdl_idx + s->buffers] -
 				(char __iomem *)cx->scb) > SCB_RESERVED_SIZE) {
 		unsigned bufsz = (((char __iomem *)cx->scb) + SCB_RESERVED_SIZE -
 					((char __iomem *)cx->scb->cpu_mdl));
 
 		CX18_ERR("Too many buffers, cannot fit in SCB area\n");
 		CX18_ERR("Max buffers = %zd\n",
-			bufsz / sizeof(struct cx18_mdl));
+			bufsz / sizeof(struct cx18_mdl_ent));
 		return -ENOMEM;
 	}
 
-	s->mdl_offset = cx->mdl_offset;
+	s->mdl_base_idx = cx->free_mdl_idx;
 
-	/* allocate stream buffers. Initially all buffers are in q_free. */
+	/* allocate stream buffers and MDLs */
 	for (i = 0; i < s->buffers; i++) {
-		struct cx18_buffer *buf = kzalloc(sizeof(struct cx18_buffer),
-						GFP_KERNEL|__GFP_NOWARN);
+		struct cx18_mdl *mdl;
+		struct cx18_buffer *buf;
 
-		if (buf == NULL)
+		/* 1 MDL per buffer to handle the worst & also default case */
+		mdl = kzalloc(sizeof(struct cx18_mdl), GFP_KERNEL|__GFP_NOWARN);
+		if (mdl == NULL)
 			break;
+
+		buf = kzalloc(sizeof(struct cx18_buffer),
+				GFP_KERNEL|__GFP_NOWARN);
+		if (buf == NULL) {
+			kfree(mdl);
+			break;
+		}
+
 		buf->buf = kmalloc(s->buf_size, GFP_KERNEL|__GFP_NOWARN);
 		if (buf->buf == NULL) {
+			kfree(mdl);
 			kfree(buf);
 			break;
 		}
-		buf->id = cx->buffer_id++;
+
+		INIT_LIST_HEAD(&mdl->list);
+		INIT_LIST_HEAD(&mdl->buf_list);
+		mdl->id = s->mdl_base_idx; /* a somewhat safe value */
+		cx18_enqueue(s, mdl, &s->q_idle);
+
 		INIT_LIST_HEAD(&buf->list);
 		buf->dma_handle = pci_map_single(s->cx->pci_dev,
 				buf->buf, s->buf_size, s->dma);
 		cx18_buf_sync_for_cpu(s, buf);
-		cx18_enqueue(s, buf, &s->q_free);
+		list_add_tail(&buf->list, &s->buf_pool);
 	}
 	if (i == s->buffers) {
-		cx->mdl_offset += s->buffers;
+		cx->free_mdl_idx += s->buffers;
 		return 0;
 	}
 	CX18_ERR("Couldn't allocate buffers for %s stream\n", s->name);
@@ -237,13 +417,21 @@
 
 void cx18_stream_free(struct cx18_stream *s)
 {
+	struct cx18_mdl *mdl;
 	struct cx18_buffer *buf;
 
-	/* move all buffers to q_free */
-	cx18_flush_queues(s);
+	/* move all buffers to buf_pool and all MDLs to q_idle */
+	cx18_unload_queues(s);
 
-	/* empty q_free */
-	while ((buf = cx18_dequeue(s, &s->q_free))) {
+	/* empty q_idle */
+	while ((mdl = cx18_dequeue(s, &s->q_idle)))
+		kfree(mdl);
+
+	/* empty buf_pool */
+	while (!list_empty(&s->buf_pool)) {
+		buf = list_first_entry(&s->buf_pool, struct cx18_buffer, list);
+		list_del_init(&buf->list);
+
 		pci_unmap_single(s->cx->pci_dev, buf->dma_handle,
 				s->buf_size, s->dma);
 		kfree(buf->buf);
diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h
index 4de0626..88a6d34 100644
--- a/drivers/media/video/cx18/cx18-queue.h
+++ b/drivers/media/video/cx18/cx18-queue.h
@@ -40,32 +40,59 @@
 				s->buf_size, s->dma);
 }
 
+void _cx18_mdl_sync_for_device(struct cx18_stream *s, struct cx18_mdl *mdl);
+
+static inline void cx18_mdl_sync_for_device(struct cx18_stream *s,
+					    struct cx18_mdl *mdl)
+{
+	if (list_is_singular(&mdl->buf_list))
+		cx18_buf_sync_for_device(s, list_first_entry(&mdl->buf_list,
+							     struct cx18_buffer,
+							     list));
+	else
+		_cx18_mdl_sync_for_device(s, mdl);
+}
+
 void cx18_buf_swap(struct cx18_buffer *buf);
+void _cx18_mdl_swap(struct cx18_mdl *mdl);
+
+static inline void cx18_mdl_swap(struct cx18_mdl *mdl)
+{
+	if (list_is_singular(&mdl->buf_list))
+		cx18_buf_swap(list_first_entry(&mdl->buf_list,
+					       struct cx18_buffer, list));
+	else
+		_cx18_mdl_swap(mdl);
+}
 
 /* cx18_queue utility functions */
-struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
+struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl,
 				 struct cx18_queue *q, int to_front);
 
 static inline
-struct cx18_queue *cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
+struct cx18_queue *cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl,
 				struct cx18_queue *q)
 {
-	return _cx18_enqueue(s, buf, q, 0); /* FIFO */
+	return _cx18_enqueue(s, mdl, q, 0); /* FIFO */
 }
 
 static inline
-struct cx18_queue *cx18_push(struct cx18_stream *s, struct cx18_buffer *buf,
+struct cx18_queue *cx18_push(struct cx18_stream *s, struct cx18_mdl *mdl,
 			     struct cx18_queue *q)
 {
-	return _cx18_enqueue(s, buf, q, 1); /* LIFO */
+	return _cx18_enqueue(s, mdl, q, 1); /* LIFO */
 }
 
 void cx18_queue_init(struct cx18_queue *q);
-struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q);
-struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id,
+struct cx18_mdl *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q);
+struct cx18_mdl *cx18_queue_get_mdl(struct cx18_stream *s, u32 id,
 	u32 bytesused);
 void cx18_flush_queues(struct cx18_stream *s);
 
+/* queue MDL reconfiguration helpers */
+void cx18_unload_queues(struct cx18_stream *s);
+void cx18_load_queues(struct cx18_stream *s);
+
 /* cx18_stream utility functions */
 int cx18_stream_alloc(struct cx18_stream *s);
 void cx18_stream_free(struct cx18_stream *s);
diff --git a/drivers/media/video/cx18/cx18-scb.h b/drivers/media/video/cx18/cx18-scb.h
index 1dc1c43..368f23d 100644
--- a/drivers/media/video/cx18/cx18-scb.h
+++ b/drivers/media/video/cx18/cx18-scb.h
@@ -81,7 +81,7 @@
 
 
 /* This structure is used by EPU to provide memory descriptors in its memory */
-struct cx18_mdl {
+struct cx18_mdl_ent {
     u32 paddr;  /* Physical address of a buffer segment */
     u32 length; /* Length of the buffer segment */
 };
@@ -272,7 +272,7 @@
 	struct cx18_mailbox  ppu2epu_mb;
 
 	struct cx18_mdl_ack  cpu_mdl_ack[CX18_MAX_STREAMS][CX18_MAX_MDL_ACKS];
-	struct cx18_mdl      cpu_mdl[1];
+	struct cx18_mdl_ent  cpu_mdl[1];
 };
 
 void cx18_init_scb(struct cx18 *cx);
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 7df513a2..c398651 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -115,6 +115,9 @@
 	s->dma = cx18_stream_info[type].dma;
 	s->buffers = cx->stream_buffers[type];
 	s->buf_size = cx->stream_buf_size[type];
+	INIT_LIST_HEAD(&s->buf_pool);
+	s->bufs_per_mdl = 1;
+	s->mdl_size = s->buf_size * s->bufs_per_mdl;
 
 	init_waitqueue_head(&s->waitq);
 	s->id = -1;
@@ -124,6 +127,8 @@
 	cx18_queue_init(&s->q_busy);
 	spin_lock_init(&s->q_full.lock);
 	cx18_queue_init(&s->q_full);
+	spin_lock_init(&s->q_idle.lock);
+	cx18_queue_init(&s->q_idle);
 
 	INIT_WORK(&s->out_work_order, cx18_out_work_handler);
 }
@@ -257,9 +262,11 @@
 
 	switch (vfl_type) {
 	case VFL_TYPE_GRABBER:
-		CX18_INFO("Registered device video%d for %s (%d x %d kB)\n",
+		CX18_INFO("Registered device video%d for %s "
+			  "(%d x %d.%02d kB)\n",
 			  num, s->name, cx->stream_buffers[type],
-			  cx->stream_buf_size[type]/1024);
+			  cx->stream_buf_size[type] / 1024,
+			  (cx->stream_buf_size[type] * 100 / 1024) % 100);
 		break;
 
 	case VFL_TYPE_RADIO:
@@ -441,8 +448,8 @@
 }
 
 static
-struct cx18_queue *_cx18_stream_put_buf_fw(struct cx18_stream *s,
-					   struct cx18_buffer *buf)
+struct cx18_queue *_cx18_stream_put_mdl_fw(struct cx18_stream *s,
+					   struct cx18_mdl *mdl)
 {
 	struct cx18 *cx = s->cx;
 	struct cx18_queue *q;
@@ -451,16 +458,16 @@
 	if (s->handle == CX18_INVALID_TASK_HANDLE ||
 	    test_bit(CX18_F_S_STOPPING, &s->s_flags) ||
 	    !test_bit(CX18_F_S_STREAMING, &s->s_flags))
-		return cx18_enqueue(s, buf, &s->q_free);
+		return cx18_enqueue(s, mdl, &s->q_free);
 
-	q = cx18_enqueue(s, buf, &s->q_busy);
+	q = cx18_enqueue(s, mdl, &s->q_busy);
 	if (q != &s->q_busy)
-		return q; /* The firmware has the max buffers it can handle */
+		return q; /* The firmware has the max MDLs it can handle */
 
-	cx18_buf_sync_for_device(s, buf);
+	cx18_mdl_sync_for_device(s, mdl);
 	cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
-		  (void __iomem *) &cx->scb->cpu_mdl[buf->id] - cx->enc_mem,
-		  1, buf->id, s->buf_size);
+		  (void __iomem *) &cx->scb->cpu_mdl[mdl->id] - cx->enc_mem,
+		  s->bufs_per_mdl, mdl->id, s->mdl_size);
 	return q;
 }
 
@@ -468,19 +475,19 @@
 void _cx18_stream_load_fw_queue(struct cx18_stream *s)
 {
 	struct cx18_queue *q;
-	struct cx18_buffer *buf;
+	struct cx18_mdl *mdl;
 
-	if (atomic_read(&s->q_free.buffers) == 0 ||
-	    atomic_read(&s->q_busy.buffers) >= CX18_MAX_FW_MDLS_PER_STREAM)
+	if (atomic_read(&s->q_free.depth) == 0 ||
+	    atomic_read(&s->q_busy.depth) >= CX18_MAX_FW_MDLS_PER_STREAM)
 		return;
 
 	/* Move from q_free to q_busy notifying the firmware, until the limit */
 	do {
-		buf = cx18_dequeue(s, &s->q_free);
-		if (buf == NULL)
+		mdl = cx18_dequeue(s, &s->q_free);
+		if (mdl == NULL)
 			break;
-		q = _cx18_stream_put_buf_fw(s, buf);
-	} while (atomic_read(&s->q_busy.buffers) < CX18_MAX_FW_MDLS_PER_STREAM
+		q = _cx18_stream_put_mdl_fw(s, mdl);
+	} while (atomic_read(&s->q_busy.depth) < CX18_MAX_FW_MDLS_PER_STREAM
 		 && q == &s->q_busy);
 }
 
@@ -492,11 +499,51 @@
 	_cx18_stream_load_fw_queue(s);
 }
 
+static void cx18_stream_configure_mdls(struct cx18_stream *s)
+{
+	cx18_unload_queues(s);
+
+	switch (s->type) {
+	case CX18_ENC_STREAM_TYPE_YUV:
+		/*
+		 * Height should be a multiple of 32 lines.
+		 * Set the MDL size to the exact size needed for one frame.
+		 * Use enough buffers per MDL to cover the MDL size
+		 */
+		s->mdl_size = 720 * s->cx->params.height * 3 / 2;
+		s->bufs_per_mdl = s->mdl_size / s->buf_size;
+		if (s->mdl_size % s->buf_size)
+			s->bufs_per_mdl++;
+		break;
+	case CX18_ENC_STREAM_TYPE_VBI:
+		s->bufs_per_mdl = 1;
+		if  (cx18_raw_vbi(s->cx)) {
+			s->mdl_size = (s->cx->is_60hz ? 12 : 18)
+						       * 2 * vbi_active_samples;
+		} else {
+			/*
+			 * See comment in cx18_vbi_setup() below about the
+			 * extra lines we capture in sliced VBI mode due to
+			 * the lines on which EAV RP codes toggle.
+			*/
+			s->mdl_size = s->cx->is_60hz
+				   ? (21 - 4 + 1) * 2 * vbi_hblank_samples_60Hz
+				   : (23 - 2 + 1) * 2 * vbi_hblank_samples_50Hz;
+		}
+		break;
+	default:
+		s->bufs_per_mdl = 1;
+		s->mdl_size = s->buf_size * s->bufs_per_mdl;
+		break;
+	}
+
+	cx18_load_queues(s);
+}
+
 int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
 {
 	u32 data[MAX_MB_ARGUMENTS];
 	struct cx18 *cx = s->cx;
-	struct cx18_buffer *buf;
 	int captype = 0;
 	struct cx18_api_func_private priv;
 
@@ -619,14 +666,7 @@
 		(void __iomem *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem);
 
 	/* Init all the cpu_mdls for this stream */
-	cx18_flush_queues(s);
-	spin_lock(&s->q_free.lock);
-	list_for_each_entry(buf, &s->q_free.list, list) {
-		cx18_writel(cx, buf->dma_handle,
-					&cx->scb->cpu_mdl[buf->id].paddr);
-		cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length);
-	}
-	spin_unlock(&s->q_free.lock);
+	cx18_stream_configure_mdls(s);
 	_cx18_stream_load_fw_queue(s);
 
 	/* begin_capture */
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
index 1afc3fd..4a01db5 100644
--- a/drivers/media/video/cx18/cx18-streams.h
+++ b/drivers/media/video/cx18/cx18-streams.h
@@ -28,18 +28,18 @@
 int cx18_streams_register(struct cx18 *cx);
 void cx18_streams_cleanup(struct cx18 *cx, int unregister);
 
-/* Related to submission of buffers to firmware */
+/* Related to submission of mdls to firmware */
 static inline void cx18_stream_load_fw_queue(struct cx18_stream *s)
 {
 	struct cx18 *cx = s->cx;
 	queue_work(cx->out_work_queue, &s->out_work_order);
 }
 
-static inline void cx18_stream_put_buf_fw(struct cx18_stream *s,
-					  struct cx18_buffer *buf)
+static inline void cx18_stream_put_mdl_fw(struct cx18_stream *s,
+					  struct cx18_mdl *mdl)
 {
-	/* Put buf on q_free; the out work handler will move buf(s) to q_busy */
-	cx18_enqueue(s, buf, &s->q_free);
+	/* Put mdl on q_free; the out work handler will move mdl(s) to q_busy */
+	cx18_enqueue(s, mdl, &s->q_free);
 	cx18_stream_load_fw_queue(s);
 }
 
diff --git a/drivers/media/video/cx18/cx18-vbi.c b/drivers/media/video/cx18/cx18-vbi.c
index c2aef4a..574c1c6 100644
--- a/drivers/media/video/cx18/cx18-vbi.c
+++ b/drivers/media/video/cx18/cx18-vbi.c
@@ -105,6 +105,7 @@
 
 /* Compress raw VBI format, removes leading SAV codes and surplus space
    after the frame.  Returns new compressed size. */
+/* FIXME - this function ignores the input size. */
 static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size, u32 hdr_size)
 {
 	u32 line_size = vbi_active_samples;
@@ -185,8 +186,7 @@
 	return line;
 }
 
-void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
-			   int streamtype)
+static void _cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf)
 {
 	/*
 	 * The CX23418 provides a 12 byte header in its raw VBI buffers to us:
@@ -203,9 +203,6 @@
 	u32 pts;
 	int lines;
 
-	if (streamtype != CX18_ENC_STREAM_TYPE_VBI)
-		return;
-
 	/*
 	 * The CX23418 sends us data that is 32 bit little-endian swapped,
 	 * but we want the raw VBI bytes in the order they were in the raster
@@ -250,3 +247,31 @@
 		copy_vbi_data(cx, lines, pts);
 	cx->vbi.frame++;
 }
+
+void cx18_process_vbi_data(struct cx18 *cx, struct cx18_mdl *mdl,
+			   int streamtype)
+{
+	struct cx18_buffer *buf;
+	u32 orig_used;
+
+	if (streamtype != CX18_ENC_STREAM_TYPE_VBI)
+		return;
+
+	/*
+	 * Big assumption here:
+	 * Every buffer hooked to the MDL's buf_list is a complete VBI frame
+	 * that ends at the end of the buffer.
+	 *
+	 * To assume anything else would make the code in this file
+	 * more complex, or require extra memcpy()'s to make the
+	 * buffers satisfy the above assumption.  It's just simpler to set
+	 * up the encoder buffer transfers to make the assumption true.
+	 */
+	list_for_each_entry(buf, &mdl->buf_list, list) {
+		orig_used = buf->bytesused;
+		if (orig_used == 0)
+			break;
+		_cx18_process_vbi_data(cx, buf);
+		mdl->bytesused -= (orig_used - buf->bytesused);
+	}
+}
diff --git a/drivers/media/video/cx18/cx18-vbi.h b/drivers/media/video/cx18/cx18-vbi.h
index e7e1ae4..b365cf4 100644
--- a/drivers/media/video/cx18/cx18-vbi.h
+++ b/drivers/media/video/cx18/cx18-vbi.h
@@ -21,6 +21,6 @@
  *  02111-1307  USA
  */
 
-void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
+void cx18_process_vbi_data(struct cx18 *cx, struct cx18_mdl *mdl,
 			   int streamtype);
 int cx18_used_line(struct cx18 *cx, int line, int field);
diff --git a/drivers/media/video/cx18/cx18-version.h b/drivers/media/video/cx18/cx18-version.h
index 45494b0..9c0b5bb 100644
--- a/drivers/media/video/cx18/cx18-version.h
+++ b/drivers/media/video/cx18/cx18-version.h
@@ -24,7 +24,7 @@
 
 #define CX18_DRIVER_NAME "cx18"
 #define CX18_DRIVER_VERSION_MAJOR 1
-#define CX18_DRIVER_VERSION_MINOR 2
+#define CX18_DRIVER_VERSION_MINOR 3
 #define CX18_DRIVER_VERSION_PATCHLEVEL 0
 
 #define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL)
diff --git a/drivers/media/video/cx18/cx23418.h b/drivers/media/video/cx18/cx23418.h
index 9956abf..868806e 100644
--- a/drivers/media/video/cx18/cx23418.h
+++ b/drivers/media/video/cx18/cx23418.h
@@ -363,7 +363,7 @@
 /* Description: This command provides the offset to a Memory Descriptor List
    IN[0] - Task handle. Handle of the task to start
    IN[1] - Offset of the MDL from the beginning of the local DDR.
-   IN[2] - Number of cx18_mdl structures in the array pointed to by IN[1]
+   IN[2] - Number of cx18_mdl_ent structures in the array pointed to by IN[1]
    IN[3] - Buffer ID
    IN[4] - Total buffer length
    ReturnCode - One of the ERR_DE_... */
diff --git a/drivers/media/video/cx231xx/cx231xx-avcore.c b/drivers/media/video/cx231xx/cx231xx-avcore.c
index 28f48f4..c217441 100644
--- a/drivers/media/video/cx231xx/cx231xx-avcore.c
+++ b/drivers/media/video/cx231xx/cx231xx-avcore.c
@@ -2414,9 +2414,11 @@
 		cx231xx_info("No ACK after %d msec -GPIO I2C failed!",
 			     nInit * 10);
 
-	/* readAck
-	   throuth clock stretch ,slave has given a SCL signal,
-	   so the SDA data can be directly read.  */
+	/*
+	 * readAck
+	 * through clock stretch, slave has given a SCL signal,
+	 * so the SDA data can be directly read.
+	 */
 	status = cx231xx_get_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
 
 	if ((dev->gpio_val & 1 << dev->board.tuner_sda_gpio) == 0) {
diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c
index 48f22fa..cd135f0 100644
--- a/drivers/media/video/cx231xx/cx231xx-input.c
+++ b/drivers/media/video/cx231xx/cx231xx-input.c
@@ -126,8 +126,7 @@
 
 	if (do_sendkey) {
 		dprintk("sending keypress\n");
-		ir_input_keydown(ir->input, &ir->ir, poll_result.rc_data[0],
-				 poll_result.rc_data[0]);
+		ir_input_keydown(ir->input, &ir->ir, poll_result.rc_data[0]);
 		ir_input_nokey(ir->input, &ir->ir);
 	}
 
@@ -198,7 +197,11 @@
 	usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
 	strlcat(ir->phys, "/input0", sizeof(ir->phys));
 
-	ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER, dev->board.ir_codes);
+	err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER,
+			    dev->board.ir_codes);
+	if (err < 0)
+		goto err_out_free;
+
 	input_dev->name = ir->name;
 	input_dev->phys = ir->phys;
 	input_dev->id.bustype = BUS_USB;
@@ -223,6 +226,7 @@
 	cx231xx_ir_stop(ir);
 	dev->ir = NULL;
 err_out_free:
+	ir_input_free(input_dev);
 	input_free_device(input_dev);
 	kfree(ir);
 	return err;
@@ -237,6 +241,7 @@
 		return 0;
 
 	cx231xx_ir_stop(ir);
+	ir_input_free(ir->input);
 	input_unregister_device(ir->input);
 	kfree(ir);
 
diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c
index 3650372..d095aa0 100644
--- a/drivers/media/video/cx231xx/cx231xx-video.c
+++ b/drivers/media/video/cx231xx/cx231xx-video.c
@@ -2106,7 +2106,7 @@
 		}
 
 		/* Save some power by putting tuner to sleep */
-		call_all(dev, tuner, s_standby);
+		call_all(dev, core, s_power, 0);
 
 		/* do this before setting alternate! */
 		cx231xx_uninit_isoc(dev);
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
index fd3fc3e..bcdda9a 100644
--- a/drivers/media/video/cx23885/Kconfig
+++ b/drivers/media/video/cx23885/Kconfig
@@ -18,7 +18,9 @@
 	select DVB_TDA10048 if !DVB_FE_CUSTOMISE
 	select DVB_LNBP21 if !DVB_FE_CUSTOMISE
 	select DVB_STV6110 if !DVB_FE_CUSTOMISE
+	select DVB_CX24116 if !DVB_FE_CUSTOMISE
 	select DVB_STV0900 if !DVB_FE_CUSTOMISE
+	select DVB_DS3000 if !DVB_FE_CUSTOMISE
 	select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE
 	select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
 	select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile
index ab8ea35..5787ae2 100644
--- a/drivers/media/video/cx23885/Makefile
+++ b/drivers/media/video/cx23885/Makefile
@@ -1,6 +1,7 @@
 cx23885-objs	:= cx23885-cards.o cx23885-video.o cx23885-vbi.o \
 		    cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o \
-		    netup-init.o cimax2.o netup-eeprom.o
+		    cx23885-ioctl.o cx23885-ir.o cx23885-input.o cx23888-ir.o \
+		    netup-init.o cimax2.o netup-eeprom.o cx23885-f300.o
 
 obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
 
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index 6c3b51c..0eed852 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -37,6 +37,7 @@
 #include <media/cx2341x.h>
 
 #include "cx23885.h"
+#include "cx23885-ioctl.h"
 
 #define CX23885_FIRM_IMAGE_SIZE 376836
 #define CX23885_FIRM_IMAGE_NAME "v4l-cx23885-enc.fw"
@@ -318,7 +319,7 @@
 	}
 }
 
-static int mc417_register_write(struct cx23885_dev *dev, u16 address, u32 value)
+int mc417_register_write(struct cx23885_dev *dev, u16 address, u32 value)
 {
 	u32 regval;
 
@@ -382,7 +383,7 @@
 	return mc417_wait_ready(dev);
 }
 
-static int mc417_register_read(struct cx23885_dev *dev, u16 address, u32 *value)
+int mc417_register_read(struct cx23885_dev *dev, u16 address, u32 *value)
 {
 	int retval;
 	u32 regval;
@@ -1724,6 +1725,11 @@
 	.vidioc_log_status	 = vidioc_log_status,
 	.vidioc_querymenu	 = vidioc_querymenu,
 	.vidioc_queryctrl	 = vidioc_queryctrl,
+	.vidioc_g_chip_ident	 = cx23885_g_chip_ident,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_register	 = cx23885_g_register,
+	.vidioc_s_register	 = cx23885_s_register,
+#endif
 };
 
 static struct video_device cx23885_mpeg_template = {
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index bfdf79f..1ec4816 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -28,6 +28,7 @@
 #include "cx23885.h"
 #include "tuner-xc2028.h"
 #include "netup-init.h"
+#include "cx23888-ir.h"
 
 /* ------------------------------------------------------------------ */
 /* board config info                                                  */
@@ -199,11 +200,61 @@
 	},
 	[CX23885_BOARD_MYGICA_X8506] = {
 		.name		= "Mygica X8506 DMB-TH",
+		.tuner_type = TUNER_XC5000,
+		.tuner_addr = 0x61,
+		.porta		= CX23885_ANALOG_VIDEO,
 		.portb		= CX23885_MPEG_DVB,
+		.input		= {
+			{
+				.type   = CX23885_VMUX_TELEVISION,
+				.vmux   = CX25840_COMPOSITE2,
+			},
+			{
+				.type   = CX23885_VMUX_COMPOSITE1,
+				.vmux   = CX25840_COMPOSITE8,
+			},
+			{
+				.type   = CX23885_VMUX_SVIDEO,
+				.vmux   = CX25840_SVIDEO_LUMA3 |
+						CX25840_SVIDEO_CHROMA4,
+			},
+			{
+				.type   = CX23885_VMUX_COMPONENT,
+				.vmux   = CX25840_COMPONENT_ON |
+					CX25840_VIN1_CH1 |
+					CX25840_VIN6_CH2 |
+					CX25840_VIN7_CH3,
+			},
+		},
 	},
 	[CX23885_BOARD_MAGICPRO_PROHDTVE2] = {
 		.name		= "Magic-Pro ProHDTV Extreme 2",
+		.tuner_type = TUNER_XC5000,
+		.tuner_addr = 0x61,
+		.porta		= CX23885_ANALOG_VIDEO,
 		.portb		= CX23885_MPEG_DVB,
+		.input		= {
+			{
+				.type   = CX23885_VMUX_TELEVISION,
+				.vmux   = CX25840_COMPOSITE2,
+			},
+			{
+				.type   = CX23885_VMUX_COMPOSITE1,
+				.vmux   = CX25840_COMPOSITE8,
+			},
+			{
+				.type   = CX23885_VMUX_SVIDEO,
+				.vmux   = CX25840_SVIDEO_LUMA3 |
+						CX25840_SVIDEO_CHROMA4,
+			},
+			{
+				.type   = CX23885_VMUX_COMPONENT,
+				.vmux   = CX25840_COMPONENT_ON |
+					CX25840_VIN1_CH1 |
+					CX25840_VIN6_CH2 |
+					CX25840_VIN7_CH3,
+			},
+		},
 	},
 	[CX23885_BOARD_HAUPPAUGE_HVR1850] = {
 		.name		= "Hauppauge WinTV-HVR1850",
@@ -214,6 +265,15 @@
 		.name		= "Compro VideoMate E800",
 		.portc		= CX23885_MPEG_DVB,
 	},
+	[CX23885_BOARD_HAUPPAUGE_HVR1290] = {
+		.name		= "Hauppauge WinTV-HVR1290",
+		.portc		= CX23885_MPEG_DVB,
+	},
+	[CX23885_BOARD_MYGICA_X8558PRO] = {
+		.name		= "Mygica X8558 PRO DMB-TH",
+		.portb		= CX23885_MPEG_DVB,
+		.portc		= CX23885_MPEG_DVB,
+	},
 };
 const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
 
@@ -349,6 +409,14 @@
 		.subvendor = 0x1858,
 		.subdevice = 0xe800,
 		.card      = CX23885_BOARD_COMPRO_VIDEOMATE_E800,
+	}, {
+		.subvendor = 0x0070,
+		.subdevice = 0x8551,
+		.card      = CX23885_BOARD_HAUPPAUGE_HVR1290,
+	}, {
+		.subvendor = 0x14f1,
+		.subdevice = 0x8578,
+		.card      = CX23885_BOARD_MYGICA_X8558PRO,
 	},
 };
 const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -509,9 +577,13 @@
 		 * DVB-T and MPEG2 HW Encoder */
 		break;
 	case 85021:
-		/* WinTV-HVR1850 (PCIe, OEM, RCA in, IR, FM,
+		/* WinTV-HVR1850 (PCIe, Retail, 3.5mm in, IR, FM,
 			Dual channel ATSC and MPEG2 HW Encoder */
 		break;
+	case 85721:
+		/* WinTV-HVR1290 (PCIe, OEM, RCA in, IR,
+			Dual channel ATSC and Basic analog */
+		break;
 	default:
 		printk(KERN_WARNING "%s: warning: "
 			"unknown hauppauge model #%d\n",
@@ -710,10 +782,14 @@
 		cx_set(GP0_IO, 0x00040004);
 		break;
 	case CX23885_BOARD_TBS_6920:
-	case CX23885_BOARD_TEVII_S470:
 		cx_write(MC417_CTL, 0x00000036);
 		cx_write(MC417_OEN, 0x00001000);
-		cx_write(MC417_RWD, 0x00001800);
+		cx_set(MC417_RWD, 0x00000002);
+		mdelay(200);
+		cx_clear(MC417_RWD, 0x00000800);
+		mdelay(200);
+		cx_set(MC417_RWD, 0x00000800);
+		mdelay(200);
 		break;
 	case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
 		/* GPIO-0 INTA from CiMax1
@@ -758,15 +834,26 @@
 		break;
 	case CX23885_BOARD_MYGICA_X8506:
 	case CX23885_BOARD_MAGICPRO_PROHDTVE2:
+		/* GPIO-0 (0)Analog / (1)Digital TV */
 		/* GPIO-1 reset XC5000 */
 		/* GPIO-2 reset LGS8GL5 / LGS8G75 */
-		cx_set(GP0_IO, 0x00060000);
-		cx_clear(GP0_IO, 0x00000006);
+		cx23885_gpio_enable(dev, GPIO_0 | GPIO_1 | GPIO_2, 1);
+		cx23885_gpio_clear(dev, GPIO_1 | GPIO_2);
 		mdelay(100);
-		cx_set(GP0_IO, 0x00060006);
+		cx23885_gpio_set(dev, GPIO_0 | GPIO_1 | GPIO_2);
+		mdelay(100);
+		break;
+	case CX23885_BOARD_MYGICA_X8558PRO:
+		/* GPIO-0 reset first ATBM8830 */
+		/* GPIO-1 reset second ATBM8830 */
+		cx23885_gpio_enable(dev, GPIO_0 | GPIO_1, 1);
+		cx23885_gpio_clear(dev, GPIO_0 | GPIO_1);
+		mdelay(100);
+		cx23885_gpio_set(dev, GPIO_0 | GPIO_1);
 		mdelay(100);
 		break;
 	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
 		/* GPIO-0 656_CLK */
 		/* GPIO-1 656_D0 */
 		/* GPIO-2 Wake# */
@@ -801,6 +888,7 @@
 
 int cx23885_ir_init(struct cx23885_dev *dev)
 {
+	int ret = 0;
 	switch (dev->board) {
 	case CX23885_BOARD_HAUPPAUGE_HVR1250:
 	case CX23885_BOARD_HAUPPAUGE_HVR1500:
@@ -812,15 +900,46 @@
 	case CX23885_BOARD_HAUPPAUGE_HVR1275:
 	case CX23885_BOARD_HAUPPAUGE_HVR1255:
 	case CX23885_BOARD_HAUPPAUGE_HVR1210:
-	case CX23885_BOARD_HAUPPAUGE_HVR1850:
 		/* FIXME: Implement me */
 		break;
+	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
+		ret = cx23888_ir_probe(dev);
+		if (ret)
+			break;
+		dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_888_IR);
+		dev->pci_irqmask |= PCI_MSK_IR;
+		break;
 	case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP:
 		request_module("ir-kbd-i2c");
 		break;
 	}
 
-	return 0;
+	return ret;
+}
+
+void cx23885_ir_fini(struct cx23885_dev *dev)
+{
+	switch (dev->board) {
+	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
+		dev->pci_irqmask &= ~PCI_MSK_IR;
+		cx_clear(PCI_INT_MSK, PCI_MSK_IR);
+		cx23888_ir_remove(dev);
+		dev->sd_ir = NULL;
+		break;
+	}
+}
+
+void cx23885_ir_pci_int_enable(struct cx23885_dev *dev)
+{
+	switch (dev->board) {
+	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
+		if (dev->sd_ir && (dev->pci_irqmask & PCI_MSK_IR))
+			cx_set(PCI_INT_MSK, PCI_MSK_IR);
+		break;
+	}
 }
 
 void cx23885_card_setup(struct cx23885_dev *dev)
@@ -853,6 +972,7 @@
 	case CX23885_BOARD_HAUPPAUGE_HVR1255:
 	case CX23885_BOARD_HAUPPAUGE_HVR1210:
 	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
 		if (dev->i2c_bus[0].i2c_rc == 0)
 			hauppauge_eeprom(dev, eeprom+0xc0);
 		break;
@@ -886,8 +1006,12 @@
 		ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
 		ts2->src_sel_val   = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
 		break;
-	case CX23885_BOARD_TEVII_S470:
 	case CX23885_BOARD_TBS_6920:
+		ts1->gen_ctrl_val  = 0x4; /* Parallel */
+		ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
+		ts1->src_sel_val   = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
+		break;
+	case CX23885_BOARD_TEVII_S470:
 	case CX23885_BOARD_DVBWORLD_2005:
 		ts1->gen_ctrl_val  = 0x5; /* Parallel */
 		ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
@@ -907,6 +1031,14 @@
 		ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
 		ts1->src_sel_val   = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
 		break;
+	case CX23885_BOARD_MYGICA_X8558PRO:
+		ts1->gen_ctrl_val  = 0x5; /* Parallel */
+		ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
+		ts1->src_sel_val   = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
+		ts2->gen_ctrl_val  = 0xc; /* Serial bus + punctured clock */
+		ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
+		ts2->src_sel_val   = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
+		break;
 	case CX23885_BOARD_HAUPPAUGE_HVR1250:
 	case CX23885_BOARD_HAUPPAUGE_HVR1500:
 	case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
@@ -922,6 +1054,7 @@
 	case CX23885_BOARD_HAUPPAUGE_HVR1210:
 	case CX23885_BOARD_HAUPPAUGE_HVR1850:
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
 	default:
 		ts2->gen_ctrl_val  = 0xc; /* Serial bus + punctured clock */
 		ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
@@ -939,6 +1072,10 @@
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
 	case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
+	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_MYGICA_X8506:
+	case CX23885_BOARD_MAGICPRO_PROHDTVE2:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
 		dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
 				&dev->i2c_bus[2].i2c_adap,
 				"cx25840", "cx25840", 0x88 >> 1, NULL);
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index c31284b..04b12d2 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -32,6 +32,9 @@
 
 #include "cx23885.h"
 #include "cimax2.h"
+#include "cx23888-ir.h"
+#include "cx23885-ir.h"
+#include "cx23885-input.h"
 
 MODULE_DESCRIPTION("Driver for cx23885 based TV cards");
 MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
@@ -753,6 +756,23 @@
 			__func__, dev->hwrevision);
 }
 
+/* Find the first v4l2_subdev member of the group id in hw */
+struct v4l2_subdev *cx23885_find_hw(struct cx23885_dev *dev, u32 hw)
+{
+	struct v4l2_subdev *result = NULL;
+	struct v4l2_subdev *sd;
+
+	spin_lock(&dev->v4l2_dev.lock);
+	v4l2_device_for_each_subdev(sd, &dev->v4l2_dev) {
+		if (sd->grp_id == hw) {
+			result = sd;
+			break;
+		}
+	}
+	spin_unlock(&dev->v4l2_dev.lock);
+	return result;
+}
+
 static int cx23885_dev_setup(struct cx23885_dev *dev)
 {
 	int i;
@@ -899,7 +919,7 @@
 	cx23885_i2c_register(&dev->i2c_bus[1]);
 	cx23885_i2c_register(&dev->i2c_bus[2]);
 	cx23885_card_setup(dev);
-	call_all(dev, tuner, s_standby);
+	call_all(dev, core, s_power, 0);
 	cx23885_ir_init(dev);
 
 	if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) {
@@ -1637,6 +1657,7 @@
 	u32 ts1_status, ts1_mask;
 	u32 ts2_status, ts2_mask;
 	int vida_count = 0, ts1_count = 0, ts2_count = 0, handled = 0;
+	bool ir_handled = false;
 
 	pci_status = cx_read(PCI_INT_STAT);
 	pci_mask = cx_read(PCI_INT_MSK);
@@ -1662,18 +1683,12 @@
 	dprintk(7, "ts2_status: 0x%08x  ts2_mask: 0x%08x count: 0x%x\n",
 		ts2_status, ts2_mask, ts2_count);
 
-	if ((pci_status & PCI_MSK_RISC_RD) ||
-	    (pci_status & PCI_MSK_RISC_WR) ||
-	    (pci_status & PCI_MSK_AL_RD) ||
-	    (pci_status & PCI_MSK_AL_WR) ||
-	    (pci_status & PCI_MSK_APB_DMA) ||
-	    (pci_status & PCI_MSK_VID_C) ||
-	    (pci_status & PCI_MSK_VID_B) ||
-	    (pci_status & PCI_MSK_VID_A) ||
-	    (pci_status & PCI_MSK_AUD_INT) ||
-	    (pci_status & PCI_MSK_AUD_EXT) ||
-	    (pci_status & PCI_MSK_GPIO0) ||
-	    (pci_status & PCI_MSK_GPIO1)) {
+	if (pci_status & (PCI_MSK_RISC_RD | PCI_MSK_RISC_WR |
+			  PCI_MSK_AL_RD   | PCI_MSK_AL_WR   | PCI_MSK_APB_DMA |
+			  PCI_MSK_VID_C   | PCI_MSK_VID_B   | PCI_MSK_VID_A   |
+			  PCI_MSK_AUD_INT | PCI_MSK_AUD_EXT |
+			  PCI_MSK_GPIO0   | PCI_MSK_GPIO1   |
+			  PCI_MSK_IR)) {
 
 		if (pci_status & PCI_MSK_RISC_RD)
 			dprintk(7, " (PCI_MSK_RISC_RD   0x%08x)\n",
@@ -1722,6 +1737,10 @@
 		if (pci_status & PCI_MSK_GPIO1)
 			dprintk(7, " (PCI_MSK_GPIO1     0x%08x)\n",
 				PCI_MSK_GPIO1);
+
+		if (pci_status & PCI_MSK_IR)
+			dprintk(7, " (PCI_MSK_IR        0x%08x)\n",
+				PCI_MSK_IR);
 	}
 
 	if (cx23885_boards[dev->board].cimax > 0 &&
@@ -1752,12 +1771,48 @@
 	if (vida_status)
 		handled += cx23885_video_irq(dev, vida_status);
 
+	if (pci_status & PCI_MSK_IR) {
+		v4l2_subdev_call(dev->sd_ir, ir, interrupt_service_routine,
+				 pci_status, &ir_handled);
+		if (ir_handled)
+			handled++;
+	}
+
 	if (handled)
 		cx_write(PCI_INT_STAT, pci_status);
 out:
 	return IRQ_RETVAL(handled);
 }
 
+static void cx23885_v4l2_dev_notify(struct v4l2_subdev *sd,
+				    unsigned int notification, void *arg)
+{
+	struct cx23885_dev *dev;
+
+	if (sd == NULL)
+		return;
+
+	dev = to_cx23885(sd->v4l2_dev);
+
+	switch (notification) {
+	case V4L2_SUBDEV_IR_RX_NOTIFY: /* Called in an IRQ context */
+		if (sd == dev->sd_ir)
+			cx23885_ir_rx_v4l2_dev_notify(sd, *(u32 *)arg);
+		break;
+	case V4L2_SUBDEV_IR_TX_NOTIFY: /* Called in an IRQ context */
+		if (sd == dev->sd_ir)
+			cx23885_ir_tx_v4l2_dev_notify(sd, *(u32 *)arg);
+		break;
+	}
+}
+
+static void cx23885_v4l2_dev_notify_init(struct cx23885_dev *dev)
+{
+	INIT_WORK(&dev->ir_rx_work, cx23885_ir_rx_work_handler);
+	INIT_WORK(&dev->ir_tx_work, cx23885_ir_tx_work_handler);
+	dev->v4l2_dev.notify = cx23885_v4l2_dev_notify;
+}
+
 static inline int encoder_on_portb(struct cx23885_dev *dev)
 {
 	return cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER;
@@ -1816,6 +1871,26 @@
 		printk(KERN_INFO "%s: Unsupported\n", dev->name);
 }
 
+u32 cx23885_gpio_get(struct cx23885_dev *dev, u32 mask)
+{
+	if (mask & 0x00000007)
+		return (cx_read(GP0_IO) >> 8) & mask & 0x7;
+
+	if (mask & 0x0007fff8) {
+		if (encoder_on_portb(dev) || encoder_on_portc(dev))
+			printk(KERN_ERR
+				"%s: Reading GPIO moving on encoder ports\n",
+				dev->name);
+		return (cx_read(MC417_RWD) & ((mask & 0x7fff8) >> 3)) << 3;
+	}
+
+	/* TODO: 23-19 */
+	if (mask & 0x00f80000)
+		printk(KERN_INFO "%s: Unsupported\n", dev->name);
+
+	return 0;
+}
+
 void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput)
 {
 	if ((mask & 0x00000007) && asoutput)
@@ -1854,6 +1929,9 @@
 	if (err < 0)
 		goto fail_free;
 
+	/* Prepare to handle notifications from subdevices */
+	cx23885_v4l2_dev_notify_init(dev);
+
 	/* pci init */
 	dev->pci = pci_dev;
 	if (pci_enable_device(pci_dev)) {
@@ -1896,6 +1974,14 @@
 		break;
 	}
 
+	/*
+	 * The CX2388[58] IR controller can start firing interrupts when
+	 * enabled, so these have to take place after the cx23885_irq() handler
+	 * is hooked up by the call to request_irq() above.
+	 */
+	cx23885_ir_pci_int_enable(dev);
+	cx23885_input_init(dev);
+
 	return 0;
 
 fail_irq:
@@ -1912,6 +1998,9 @@
 	struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
 	struct cx23885_dev *dev = to_cx23885(v4l2_dev);
 
+	cx23885_input_fini(dev);
+	cx23885_ir_fini(dev);
+
 	cx23885_shutdown(dev);
 
 	pci_disable_device(pci_dev);
@@ -1957,7 +2046,7 @@
 	.resume   = NULL,
 };
 
-static int cx23885_init(void)
+static int __init cx23885_init(void)
 {
 	printk(KERN_INFO "cx23885 driver version %d.%d.%d loaded\n",
 	       (CX23885_VERSION_CODE >> 16) & 0xff,
@@ -1970,7 +2059,7 @@
 	return pci_register_driver(&cx23885_pci_driver);
 }
 
-static void cx23885_fini(void)
+static void __exit cx23885_fini(void)
 {
 	pci_unregister_driver(&cx23885_pci_driver);
 }
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 45e13ee..e45d2df 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -38,6 +38,7 @@
 #include "tda18271.h"
 #include "lgdt330x.h"
 #include "xc5000.h"
+#include "max2165.h"
 #include "tda10048.h"
 #include "tuner-xc2028.h"
 #include "tuner-simple.h"
@@ -54,6 +55,9 @@
 #include "netup-eeprom.h"
 #include "netup-init.h"
 #include "lgdt3305.h"
+#include "atbm8830.h"
+#include "ds3000.h"
+#include "cx23885-f300.h"
 
 static unsigned int debug;
 
@@ -400,6 +404,7 @@
 
 static struct stv0900_config netup_stv0900_config = {
 	.demod_address = 0x68,
+	.demod_mode = 1, /* dual */
 	.xtal = 8000000,
 	.clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
 	.diseqc_mode = 2,/* 2/3 PWM */
@@ -414,34 +419,22 @@
 	.i2c_address = 0x60,
 	.mclk = 16000000,
 	.clk_div = 1,
+	.gain = 8, /* +16 dB  - maximum gain */
 };
 
 static struct stv6110_config netup_stv6110_tunerconfig_b = {
 	.i2c_address = 0x63,
 	.mclk = 16000000,
 	.clk_div = 1,
+	.gain = 8, /* +16 dB  - maximum gain */
 };
 
-static int tbs_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
-{
-	struct cx23885_tsport *port = fe->dvb->priv;
-	struct cx23885_dev *dev = port->dev;
-
-	if (voltage == SEC_VOLTAGE_18)
-		cx_write(MC417_RWD, 0x00001e00);/* GPIO-13 high */
-	else if (voltage == SEC_VOLTAGE_13)
-		cx_write(MC417_RWD, 0x00001a00);/* GPIO-13 low */
-	else
-		cx_write(MC417_RWD, 0x00001800);/* GPIO-12 low */
-	return 0;
-}
-
 static struct cx24116_config tbs_cx24116_config = {
-	.demod_address = 0x05,
+	.demod_address = 0x55,
 };
 
-static struct cx24116_config tevii_cx24116_config = {
-	.demod_address = 0x55,
+static struct ds3000_config tevii_ds3000_config = {
+	.demod_address = 0x68,
 };
 
 static struct cx24116_config dvbworld_cx24116_config = {
@@ -486,11 +479,40 @@
 			break;
 		}
 		break;
+	case CX23885_BOARD_MYGICA_X8506:
+	case CX23885_BOARD_MAGICPRO_PROHDTVE2:
+		/* Select Digital TV */
+		cx23885_gpio_set(dev, GPIO_0);
+		break;
 	}
-	return (port->set_frontend_save) ?
-		port->set_frontend_save(fe, param) : -ENODEV;
+	return 0;
 }
 
+static int cx23885_dvb_fe_ioctl_override(struct dvb_frontend *fe,
+					 unsigned int cmd, void *parg,
+					 unsigned int stage)
+{
+	int err = 0;
+
+	switch (stage) {
+	case DVB_FE_IOCTL_PRE:
+
+		switch (cmd) {
+		case FE_SET_FRONTEND:
+			err = cx23885_dvb_set_frontend(fe,
+				(struct dvb_frontend_parameters *) parg);
+			break;
+		}
+		break;
+
+	case DVB_FE_IOCTL_POST:
+		/* no post-ioctl handling required */
+		break;
+	}
+	return err;
+};
+
+
 static struct lgs8gxx_config magicpro_prohdtve2_lgs8g75_config = {
 	.prod = LGS8GXX_PROD_LGS8G75,
 	.demod_address = 0x19,
@@ -511,6 +533,38 @@
 	.if_khz = 6500,
 };
 
+static struct atbm8830_config mygica_x8558pro_atbm8830_cfg1 = {
+	.prod = ATBM8830_PROD_8830,
+	.demod_address = 0x44,
+	.serial_ts = 0,
+	.ts_sampling_edge = 1,
+	.ts_clk_gated = 0,
+	.osc_clk_freq = 30400, /* in kHz */
+	.if_freq = 0, /* zero IF */
+	.zif_swap_iq = 1,
+};
+
+static struct max2165_config mygic_x8558pro_max2165_cfg1 = {
+	.i2c_address = 0x60,
+	.osc_clk = 20
+};
+
+static struct atbm8830_config mygica_x8558pro_atbm8830_cfg2 = {
+	.prod = ATBM8830_PROD_8830,
+	.demod_address = 0x44,
+	.serial_ts = 1,
+	.ts_sampling_edge = 1,
+	.ts_clk_gated = 0,
+	.osc_clk_freq = 30400, /* in kHz */
+	.if_freq = 0, /* zero IF */
+	.zif_swap_iq = 1,
+};
+
+static struct max2165_config mygic_x8558pro_max2165_cfg2 = {
+	.i2c_address = 0x60,
+	.osc_clk = 20
+};
+
 static int dvb_register(struct cx23885_tsport *port)
 {
 	struct cx23885_dev *dev = port->dev;
@@ -550,12 +604,6 @@
 				   0x60, &dev->i2c_bus[1].i2c_adap,
 				   &hauppauge_hvr127x_config);
 		}
-
-		/* FIXME: temporary hack */
-		/* define bridge override to set_frontend */
-		port->set_frontend_save = fe0->dvb.frontend->ops.set_frontend;
-		fe0->dvb.frontend->ops.set_frontend = cx23885_dvb_set_frontend;
-
 		break;
 	case CX23885_BOARD_HAUPPAUGE_HVR1255:
 		i2c_bus = &dev->i2c_bus[0];
@@ -772,23 +820,23 @@
 		}
 		break;
 	case CX23885_BOARD_TBS_6920:
-		i2c_bus = &dev->i2c_bus[0];
+		i2c_bus = &dev->i2c_bus[1];
 
 		fe0->dvb.frontend = dvb_attach(cx24116_attach,
-			&tbs_cx24116_config,
-			&i2c_bus->i2c_adap);
+					&tbs_cx24116_config,
+					&i2c_bus->i2c_adap);
 		if (fe0->dvb.frontend != NULL)
-			fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage;
+			fe0->dvb.frontend->ops.set_voltage = f300_set_voltage;
 
 		break;
 	case CX23885_BOARD_TEVII_S470:
 		i2c_bus = &dev->i2c_bus[1];
 
-		fe0->dvb.frontend = dvb_attach(cx24116_attach,
-			&tevii_cx24116_config,
-			&i2c_bus->i2c_adap);
+		fe0->dvb.frontend = dvb_attach(ds3000_attach,
+					&tevii_ds3000_config,
+					&i2c_bus->i2c_adap);
 		if (fe0->dvb.frontend != NULL)
-			fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage;
+			fe0->dvb.frontend->ops.set_voltage = f300_set_voltage;
 
 		break;
 	case CX23885_BOARD_DVBWORLD_2005:
@@ -814,8 +862,8 @@
 					if (!dvb_attach(lnbh24_attach,
 							fe0->dvb.frontend,
 							&i2c_bus->i2c_adap,
-							LNBH24_PCL,
-							LNBH24_TTX, 0x09))
+							LNBH24_PCL | LNBH24_TTX,
+							LNBH24_TEN, 0x09))
 						printk(KERN_ERR
 							"No LNBH24 found!\n");
 
@@ -835,8 +883,8 @@
 					if (!dvb_attach(lnbh24_attach,
 							fe0->dvb.frontend,
 							&i2c_bus->i2c_adap,
-							LNBH24_PCL,
-							LNBH24_TTX, 0x0a))
+							LNBH24_PCL | LNBH24_TTX,
+							LNBH24_TEN, 0x0a))
 						printk(KERN_ERR
 							"No LNBH24 found!\n");
 
@@ -872,6 +920,7 @@
 		}
 		break;
 	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
 		i2c_bus = &dev->i2c_bus[0];
 		fe0->dvb.frontend = dvb_attach(s5h1411_attach,
 			&hcw_s5h1411_config,
@@ -881,6 +930,36 @@
 				0x60, &dev->i2c_bus[0].i2c_adap,
 				&hauppauge_tda18271_config);
 		break;
+	case CX23885_BOARD_MYGICA_X8558PRO:
+		switch (port->nr) {
+		/* port B */
+		case 1:
+			i2c_bus = &dev->i2c_bus[0];
+			fe0->dvb.frontend = dvb_attach(atbm8830_attach,
+				&mygica_x8558pro_atbm8830_cfg1,
+				&i2c_bus->i2c_adap);
+			if (fe0->dvb.frontend != NULL) {
+				dvb_attach(max2165_attach,
+					fe0->dvb.frontend,
+					&i2c_bus->i2c_adap,
+					&mygic_x8558pro_max2165_cfg1);
+			}
+			break;
+		/* port C */
+		case 2:
+			i2c_bus = &dev->i2c_bus[1];
+			fe0->dvb.frontend = dvb_attach(atbm8830_attach,
+				&mygica_x8558pro_atbm8830_cfg2,
+				&i2c_bus->i2c_adap);
+			if (fe0->dvb.frontend != NULL) {
+				dvb_attach(max2165_attach,
+					fe0->dvb.frontend,
+					&i2c_bus->i2c_adap,
+					&mygic_x8558pro_max2165_cfg2);
+			}
+			break;
+		}
+		break;
 
 	default:
 		printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
@@ -897,14 +976,15 @@
 	fe0->dvb.frontend->callback = cx23885_tuner_callback;
 
 	/* Put the analog decoder in standby to keep it quiet */
-	call_all(dev, tuner, s_standby);
+	call_all(dev, core, s_power, 0);
 
 	if (fe0->dvb.frontend->ops.analog_ops.standby)
 		fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend);
 
 	/* register everything */
 	ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
-		&dev->pci->dev, adapter_nr, 0);
+					&dev->pci->dev, adapter_nr, 0,
+					cx23885_dvb_fe_ioctl_override);
 
 	/* init CI & MAC */
 	switch (dev->board) {
@@ -940,7 +1020,7 @@
 	int err, i;
 
 	/* Here we need to allocate the correct number of frontends,
-	 * as reflected in the cards struct. The reality is that currrently
+	 * as reflected in the cards struct. The reality is that currently
 	 * no cx23885 boards support this - yet. But, if we don't modify this
 	 * code then the second frontend would never be allocated (later)
 	 * and fail with error before the attach in dvb_register().
diff --git a/drivers/media/video/cx23885/cx23885-f300.c b/drivers/media/video/cx23885/cx23885-f300.c
new file mode 100644
index 0000000..93998f2
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-f300.c
@@ -0,0 +1,177 @@
+/*
+ * Driver for Silicon Labs C8051F300 microcontroller.
+ *
+ * It is used for LNB power control in TeVii S470,
+ * TBS 6920 PCIe DVB-S2 cards.
+ *
+ * Microcontroller connected to cx23885 GPIO pins:
+ * GPIO0 - data		- P0.3 F300
+ * GPIO1 - reset	- P0.2 F300
+ * GPIO2 - clk		- P0.1 F300
+ * GPIO3 - busy		- P0.0 F300
+ *
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@me.by>
+ *
+ * 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.
+ */
+
+#include "cx23885.h"
+
+#define F300_DATA	GPIO_0
+#define F300_RESET	GPIO_1
+#define F300_CLK	GPIO_2
+#define F300_BUSY	GPIO_3
+
+static void f300_set_line(struct cx23885_dev *dev, u32 line, u8 lvl)
+{
+	cx23885_gpio_enable(dev, line, 1);
+	if (lvl == 1)
+		cx23885_gpio_set(dev, line);
+	else
+		cx23885_gpio_clear(dev, line);
+}
+
+static u8 f300_get_line(struct cx23885_dev *dev, u32 line)
+{
+	cx23885_gpio_enable(dev, line, 0);
+
+	return cx23885_gpio_get(dev, line);
+}
+
+static void f300_send_byte(struct cx23885_dev *dev, u8 dta)
+{
+	u8 i;
+
+	for (i = 0; i < 8; i++) {
+		f300_set_line(dev, F300_CLK, 0);
+		udelay(30);
+		f300_set_line(dev, F300_DATA, (dta & 0x80) >> 7);/* msb first */
+		udelay(30);
+		dta <<= 1;
+		f300_set_line(dev, F300_CLK, 1);
+		udelay(30);
+	}
+}
+
+static u8 f300_get_byte(struct cx23885_dev *dev)
+{
+	u8 i, dta = 0;
+
+	for (i = 0; i < 8; i++) {
+		f300_set_line(dev, F300_CLK, 0);
+		udelay(30);
+		dta <<= 1;
+		f300_set_line(dev, F300_CLK, 1);
+		udelay(30);
+		dta |= f300_get_line(dev, F300_DATA);/* msb first */
+
+	}
+
+	return dta;
+}
+
+static u8 f300_xfer(struct dvb_frontend *fe, u8 *buf)
+{
+	struct cx23885_tsport *port = fe->dvb->priv;
+	struct cx23885_dev *dev = port->dev;
+	u8 i, temp, ret = 0;
+
+	temp = buf[0];
+	for (i = 0; i < buf[0]; i++)
+		temp += buf[i + 1];
+	temp = (~temp + 1);/* get check sum */
+	buf[1 + buf[0]] = temp;
+
+	f300_set_line(dev, F300_RESET, 1);
+	f300_set_line(dev, F300_CLK, 1);
+	udelay(30);
+	f300_set_line(dev, F300_DATA, 1);
+	msleep(1);
+
+	/* question: */
+	f300_set_line(dev, F300_RESET, 0);/* begin to send data */
+	msleep(1);
+
+	f300_send_byte(dev, 0xe0);/* the slave address is 0xe0, write */
+	msleep(1);
+
+	temp = buf[0];
+	temp += 2;
+	for (i = 0; i < temp; i++)
+		f300_send_byte(dev, buf[i]);
+
+	f300_set_line(dev, F300_RESET, 1);/* sent data over */
+	f300_set_line(dev, F300_DATA, 1);
+
+	/* answer: */
+	temp = 0;
+	for (i = 0; ((i < 8) & (temp == 0)); i++) {
+		msleep(1);
+		if (f300_get_line(dev, F300_BUSY) == 0)
+			temp = 1;
+	}
+
+	if (i > 7) {
+		printk(KERN_ERR "%s: timeout, the slave no response\n",
+								__func__);
+		ret = 1; /* timeout, the slave no response */
+	} else { /* the slave not busy, prepare for getting data */
+		f300_set_line(dev, F300_RESET, 0);/*ready...*/
+		msleep(1);
+		f300_send_byte(dev, 0xe1);/* 0xe1 is Read */
+		msleep(1);
+		temp = f300_get_byte(dev);/*get the data length */
+		if (temp > 14)
+			temp = 14;
+
+		for (i = 0; i < (temp + 1); i++)
+			f300_get_byte(dev);/* get data to empty buffer */
+
+		f300_set_line(dev, F300_RESET, 1);/* received data over */
+		f300_set_line(dev, F300_DATA, 1);
+	}
+
+	return ret;
+}
+
+int f300_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+	u8 buf[16];
+
+	buf[0] = 0x05;
+	buf[1] = 0x38;/* write port */
+	buf[2] = 0x01;/* A port, lnb power */
+
+	switch (voltage) {
+	case SEC_VOLTAGE_13:
+		buf[3] = 0x01;/* power on */
+		buf[4] = 0x02;/* B port, H/V */
+		buf[5] = 0x00;/*13V v*/
+		break;
+	case SEC_VOLTAGE_18:
+		buf[3] = 0x01;
+		buf[4] = 0x02;
+		buf[5] = 0x01;/* 18V h*/
+		break;
+	case SEC_VOLTAGE_OFF:
+		buf[3] = 0x00;/* power off */
+		buf[4] = 0x00;
+		buf[5] = 0x00;
+		break;
+	}
+
+	return f300_xfer(fe, buf);
+}
diff --git a/drivers/media/video/cx23885/cx23885-f300.h b/drivers/media/video/cx23885/cx23885-f300.h
new file mode 100644
index 0000000..e73344c
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-f300.h
@@ -0,0 +1,2 @@
+extern int f300_set_voltage(struct dvb_frontend *fe,
+				fe_sec_voltage_t voltage);
diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c
new file mode 100644
index 0000000..469e083
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-input.c
@@ -0,0 +1,427 @@
+/*
+ *  Driver for the Conexant CX23885/7/8 PCIe bridge
+ *
+ *  Infrared remote control input device
+ *
+ *  Most of this file is
+ *
+ *  Copyright (C) 2009  Andy Walls <awalls@radix.net>
+ *
+ *  However, the cx23885_input_{init,fini} functions contained herein are
+ *  derived from Linux kernel files linux/media/video/.../...-input.c marked as:
+ *
+ *  Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+ *  Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
+ *		       Markus Rechberger <mrechberger@gmail.com>
+ *		       Mauro Carvalho Chehab <mchehab@infradead.org>
+ *		       Sascha Sommer <saschasommer@freenet.de>
+ *  Copyright (C) 2004, 2005 Chris Pascoe
+ *  Copyright (C) 2003, 2004 Gerd Knorr
+ *  Copyright (C) 2003 Pavel Machek
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA
+ *  02110-1301, USA.
+ */
+
+#include <linux/input.h>
+#include <media/ir-common.h>
+#include <media/v4l2-subdev.h>
+
+#include "cx23885.h"
+
+#define RC5_BITS		14
+#define RC5_HALF_BITS		(2*RC5_BITS)
+#define RC5_HALF_BITS_MASK	((1 << RC5_HALF_BITS) - 1)
+
+#define RC5_START_BITS_NORMAL	0x3 /* Command range  0 -  63 */
+#define RC5_START_BITS_EXTENDED	0x2 /* Command range 64 - 127 */
+
+#define RC5_EXTENDED_COMMAND_OFFSET	64
+
+static inline unsigned int rc5_command(u32 rc5_baseband)
+{
+	return RC5_INSTR(rc5_baseband) +
+		((RC5_START(rc5_baseband) == RC5_START_BITS_EXTENDED)
+			? RC5_EXTENDED_COMMAND_OFFSET : 0);
+}
+
+static void cx23885_input_process_raw_rc5(struct cx23885_dev *dev)
+{
+	struct card_ir *ir_input = dev->ir_input;
+	unsigned int code, command;
+	u32 rc5;
+
+	/* Ignore codes that are too short to be valid RC-5 */
+	if (ir_input->last_bit < (RC5_HALF_BITS - 1))
+		return;
+
+	/* The library has the manchester coding backwards; XOR to adapt. */
+	code = (ir_input->code & RC5_HALF_BITS_MASK) ^ RC5_HALF_BITS_MASK;
+	rc5 = ir_rc5_decode(code);
+
+	switch (RC5_START(rc5)) {
+	case RC5_START_BITS_NORMAL:
+		break;
+	case RC5_START_BITS_EXTENDED:
+		/* Don't allow if the remote only emits standard commands */
+		if (ir_input->start == RC5_START_BITS_NORMAL)
+			return;
+		break;
+	default:
+		return;
+	}
+
+	if (ir_input->addr != RC5_ADDR(rc5))
+		return;
+
+	/* Don't generate a keypress for RC-5 auto-repeated keypresses */
+	command = rc5_command(rc5);
+	if (RC5_TOGGLE(rc5) != RC5_TOGGLE(ir_input->last_rc5) ||
+	    command != rc5_command(ir_input->last_rc5) ||
+	    /* Catch T == 0, CMD == 0 (e.g. '0') as first keypress after init */
+	    RC5_START(ir_input->last_rc5) == 0) {
+		/* This keypress is differnet: not an auto repeat */
+		ir_input_nokey(ir_input->dev, &ir_input->ir);
+		ir_input_keydown(ir_input->dev, &ir_input->ir, command);
+	}
+	ir_input->last_rc5 = rc5;
+
+	/* Schedule when we should do the key up event: ir_input_nokey() */
+	mod_timer(&ir_input->timer_keyup,
+		  jiffies + msecs_to_jiffies(ir_input->rc5_key_timeout));
+}
+
+static void cx23885_input_next_pulse_width_rc5(struct cx23885_dev *dev,
+					       u32 ns_pulse)
+{
+	const int rc5_quarterbit_ns = 444444; /* 32 cycles/36 kHz/2 = 444 us */
+	struct card_ir *ir_input = dev->ir_input;
+	int i, level, quarterbits, halfbits;
+
+	if (!ir_input->active) {
+		ir_input->active = 1;
+		/* assume an initial space that we may not detect or measure */
+		ir_input->code = 0;
+		ir_input->last_bit = 0;
+	}
+
+	if (ns_pulse == V4L2_SUBDEV_IR_PULSE_RX_SEQ_END) {
+		ir_input->last_bit++; /* Account for the final space */
+		ir_input->active = 0;
+		cx23885_input_process_raw_rc5(dev);
+		return;
+	}
+
+	level = (ns_pulse & V4L2_SUBDEV_IR_PULSE_LEVEL_MASK) ? 1 : 0;
+
+	/* Skip any leading space to sync to the start bit */
+	if (ir_input->last_bit == 0 && level == 0)
+		return;
+
+	/*
+	 * With valid RC-5 we can get up to two consecutive half-bits in a
+	 * single pulse measurment.  Experiments have shown that the duration
+	 * of a half-bit can vary.  Make sure we always end up with an even
+	 * number of quarter bits at the same level (mark or space).
+	 */
+	ns_pulse &= V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS;
+	quarterbits = ns_pulse / rc5_quarterbit_ns;
+	if (quarterbits & 1)
+		quarterbits++;
+	halfbits = quarterbits / 2;
+
+	for (i = 0; i < halfbits; i++) {
+		ir_input->last_bit++;
+		ir_input->code |= (level << ir_input->last_bit);
+
+		if (ir_input->last_bit >= RC5_HALF_BITS-1) {
+			ir_input->active = 0;
+			cx23885_input_process_raw_rc5(dev);
+			/*
+			 * If level is 1, a leading mark is invalid for RC5.
+			 * If level is 0, we scan past extra intial space.
+			 * Either way we don't want to reactivate collecting
+			 * marks or spaces here with any left over half-bits.
+			 */
+			break;
+		}
+	}
+}
+
+static void cx23885_input_process_pulse_widths_rc5(struct cx23885_dev *dev,
+						   bool add_eom)
+{
+	struct card_ir *ir_input = dev->ir_input;
+	struct ir_input_state *ir_input_state = &ir_input->ir;
+
+	u32 ns_pulse[RC5_HALF_BITS+1];
+	ssize_t num = 0;
+	int count, i;
+
+	do {
+		v4l2_subdev_call(dev->sd_ir, ir, rx_read, (u8 *) ns_pulse,
+				 sizeof(ns_pulse), &num);
+
+		count = num / sizeof(u32);
+
+		/* Append an end of Rx seq, if the caller requested */
+		if (add_eom && count < ARRAY_SIZE(ns_pulse)) {
+			ns_pulse[count] = V4L2_SUBDEV_IR_PULSE_RX_SEQ_END;
+			count++;
+		}
+
+		/* Just drain the Rx FIFO, if we're called, but not RC-5 */
+		if (ir_input_state->ir_type != IR_TYPE_RC5)
+			continue;
+
+		for (i = 0; i < count; i++)
+			cx23885_input_next_pulse_width_rc5(dev, ns_pulse[i]);
+	} while (num != 0);
+}
+
+void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events)
+{
+	struct v4l2_subdev_ir_parameters params;
+	int overrun, data_available;
+
+	if (dev->sd_ir == NULL || events == 0)
+		return;
+
+	switch (dev->board) {
+	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
+		/*
+		 * The only board we handle right now.  However other boards
+		 * using the CX2388x integrated IR controller should be similar
+		 */
+		break;
+	default:
+		return;
+	}
+
+	overrun = events & (V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN |
+			    V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN);
+
+	data_available = events & (V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED |
+				   V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ);
+
+	if (overrun) {
+		/* If there was a FIFO overrun, stop the device */
+		v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
+		params.enable = false;
+		/* Mitigate race with cx23885_input_ir_stop() */
+		params.shutdown = atomic_read(&dev->ir_input_stopping);
+		v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, &params);
+	}
+
+	if (data_available)
+		cx23885_input_process_pulse_widths_rc5(dev, overrun);
+
+	if (overrun) {
+		/* If there was a FIFO overrun, clear & restart the device */
+		params.enable = true;
+		/* Mitigate race with cx23885_input_ir_stop() */
+		params.shutdown = atomic_read(&dev->ir_input_stopping);
+		v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, &params);
+	}
+}
+
+static void cx23885_input_ir_start(struct cx23885_dev *dev)
+{
+	struct card_ir *ir_input = dev->ir_input;
+	struct ir_input_state *ir_input_state = &ir_input->ir;
+	struct v4l2_subdev_ir_parameters params;
+
+	if (dev->sd_ir == NULL)
+		return;
+
+	atomic_set(&dev->ir_input_stopping, 0);
+
+	/* keyup timer set up, if needed */
+	switch (dev->board) {
+	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
+		setup_timer(&ir_input->timer_keyup,
+			    ir_rc5_timer_keyup,	/* Not actually RC-5 specific */
+			    (unsigned long) ir_input);
+		if (ir_input_state->ir_type == IR_TYPE_RC5) {
+			/*
+			 * RC-5 repeats a held key every
+			 * 64 bits * (2 * 32/36000) sec/bit = 113.778 ms
+			 */
+			ir_input->rc5_key_timeout = 115;
+		}
+		break;
+	}
+
+	v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
+	switch (dev->board) {
+	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
+		/*
+		 * The IR controller on this board only returns pulse widths.
+		 * Any other mode setting will fail to set up the device.
+		*/
+		params.mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
+		params.enable = true;
+		params.interrupt_enable = true;
+		params.shutdown = false;
+
+		/* Setup for baseband compatible with both RC-5 and RC-6A */
+		params.modulation = false;
+		/* RC-5:  2,222,222 ns = 1/36 kHz * 32 cycles * 2 marks * 1.25*/
+		/* RC-6A: 3,333,333 ns = 1/36 kHz * 16 cycles * 6 marks * 1.25*/
+		params.max_pulse_width = 3333333; /* ns */
+		/* RC-5:    666,667 ns = 1/36 kHz * 32 cycles * 1 mark * 0.75 */
+		/* RC-6A:   333,333 ns = 1/36 kHz * 16 cycles * 1 mark * 0.75 */
+		params.noise_filter_min_width = 333333; /* ns */
+		/*
+		 * This board has inverted receive sense:
+		 * mark is received as low logic level;
+		 * falling edges are detected as rising edges; etc.
+		 */
+		params.invert = true;
+		break;
+	}
+	v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, &params);
+}
+
+static void cx23885_input_ir_stop(struct cx23885_dev *dev)
+{
+	struct card_ir *ir_input = dev->ir_input;
+	struct v4l2_subdev_ir_parameters params;
+
+	if (dev->sd_ir == NULL)
+		return;
+
+	/*
+	 * Stop the sd_ir subdevice from generating notifications and
+	 * scheduling work.
+	 * It is shutdown this way in order to mitigate a race with
+	 * cx23885_input_rx_work_handler() in the overrun case, which could
+	 * re-enable the subdevice.
+	 */
+	atomic_set(&dev->ir_input_stopping, 1);
+	v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
+	while (params.shutdown == false) {
+		params.enable = false;
+		params.interrupt_enable = false;
+		params.shutdown = true;
+		v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, &params);
+		v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
+	}
+
+	flush_scheduled_work();
+
+	switch (dev->board) {
+	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
+		del_timer_sync(&ir_input->timer_keyup);
+		break;
+	}
+}
+
+int cx23885_input_init(struct cx23885_dev *dev)
+{
+	struct card_ir *ir;
+	struct input_dev *input_dev;
+	struct ir_scancode_table *ir_codes = NULL;
+	int ir_type, ir_addr, ir_start;
+	int ret;
+
+	/*
+	 * If the IR device (hardware registers, chip, GPIO lines, etc.) isn't
+	 * encapsulated in a v4l2_subdev, then I'm not going to deal with it.
+	 */
+	if (dev->sd_ir == NULL)
+		return -ENODEV;
+
+	switch (dev->board) {
+	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
+		/* Parameters for the grey Hauppauge remote for the HVR-1850 */
+		ir_codes = &ir_codes_hauppauge_new_table;
+		ir_type = IR_TYPE_RC5;
+		ir_addr = 0x1e; /* RC-5 system bits emitted by the remote */
+		ir_start = RC5_START_BITS_NORMAL; /* A basic RC-5 remote */
+		break;
+	}
+	if (ir_codes == NULL)
+		return -ENODEV;
+
+	ir = kzalloc(sizeof(*ir), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!ir || !input_dev) {
+		ret = -ENOMEM;
+		goto err_out_free;
+	}
+
+	ir->dev = input_dev;
+	ir->addr = ir_addr;
+	ir->start = ir_start;
+
+	/* init input device */
+	snprintf(ir->name, sizeof(ir->name), "cx23885 IR (%s)",
+		 cx23885_boards[dev->board].name);
+	snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(dev->pci));
+
+	ret = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
+	if (ret < 0)
+		goto err_out_free;
+
+	input_dev->name = ir->name;
+	input_dev->phys = ir->phys;
+	input_dev->id.bustype = BUS_PCI;
+	input_dev->id.version = 1;
+	if (dev->pci->subsystem_vendor) {
+		input_dev->id.vendor  = dev->pci->subsystem_vendor;
+		input_dev->id.product = dev->pci->subsystem_device;
+	} else {
+		input_dev->id.vendor  = dev->pci->vendor;
+		input_dev->id.product = dev->pci->device;
+	}
+	input_dev->dev.parent = &dev->pci->dev;
+
+	dev->ir_input = ir;
+	cx23885_input_ir_start(dev);
+
+	ret = input_register_device(ir->dev);
+	if (ret)
+		goto err_out_stop;
+
+	return 0;
+
+err_out_stop:
+	cx23885_input_ir_stop(dev);
+	dev->ir_input = NULL;
+err_out_free:
+	ir_input_free(input_dev);
+	input_free_device(input_dev);
+	kfree(ir);
+	return ret;
+}
+
+void cx23885_input_fini(struct cx23885_dev *dev)
+{
+	/* Always stop the IR hardware from generating interrupts */
+	cx23885_input_ir_stop(dev);
+
+	if (dev->ir_input == NULL)
+		return;
+	ir_input_free(dev->ir_input->dev);
+	input_unregister_device(dev->ir_input->dev);
+	kfree(dev->ir_input);
+	dev->ir_input = NULL;
+}
diff --git a/drivers/media/video/cx23885/cx23885-input.h b/drivers/media/video/cx23885/cx23885-input.h
new file mode 100644
index 0000000..3572cb1
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-input.h
@@ -0,0 +1,30 @@
+/*
+ *  Driver for the Conexant CX23885/7/8 PCIe bridge
+ *
+ *  Infrared remote control input device
+ *
+ *  Copyright (C) 2009  Andy Walls <awalls@radix.net>
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA
+ *  02110-1301, USA.
+ */
+
+#ifndef _CX23885_INPUT_H_
+#define _CX23885_INPUT_H_
+int cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events);
+
+int cx23885_input_init(struct cx23885_dev *dev);
+void cx23885_input_fini(struct cx23885_dev *dev);
+#endif
diff --git a/drivers/media/video/cx23885/cx23885-ioctl.c b/drivers/media/video/cx23885/cx23885-ioctl.c
new file mode 100644
index 0000000..dfb4627
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-ioctl.c
@@ -0,0 +1,208 @@
+/*
+ *  Driver for the Conexant CX23885/7/8 PCIe bridge
+ *
+ *  Various common ioctl() support functions
+ *
+ *  Copyright (c) 2009 Andy Walls <awalls@radix.net>
+ *
+ *  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.
+ */
+
+#include "cx23885.h"
+#include <media/v4l2-chip-ident.h>
+
+int cx23885_g_chip_ident(struct file *file, void *fh,
+			 struct v4l2_dbg_chip_ident *chip)
+{
+	struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
+	int err = 0;
+	u8 rev;
+
+	chip->ident = V4L2_IDENT_NONE;
+	chip->revision = 0;
+	switch (chip->match.type) {
+	case V4L2_CHIP_MATCH_HOST:
+		switch (chip->match.addr) {
+		case 0:
+			rev = cx_read(RDR_CFG2) & 0xff;
+			switch (dev->pci->device) {
+			case 0x8852:
+				/* rev 0x04 could be '885 or '888. Pick '888. */
+				if (rev == 0x04)
+					chip->ident = V4L2_IDENT_CX23888;
+				else
+					chip->ident = V4L2_IDENT_CX23885;
+				break;
+			case 0x8880:
+				if (rev == 0x0e || rev == 0x0f)
+					chip->ident = V4L2_IDENT_CX23887;
+				else
+					chip->ident = V4L2_IDENT_CX23888;
+				break;
+			default:
+				chip->ident = V4L2_IDENT_UNKNOWN;
+				break;
+			}
+			chip->revision = (dev->pci->device << 16) | (rev << 8) |
+					 (dev->hwrevision & 0xff);
+			break;
+		case 1:
+			if (dev->v4l_device != NULL) {
+				chip->ident = V4L2_IDENT_CX23417;
+				chip->revision = 0;
+			}
+			break;
+		case 2:
+			/*
+			 * The integrated IR controller on the CX23888 is
+			 * host chip 2.  It may not be used/initialized or sd_ir
+			 * may be pointing at the cx25840 subdevice for the
+			 * IR controller on the CX23885.  Thus we find it
+			 * without using the dev->sd_ir pointer.
+			 */
+			call_hw(dev, CX23885_HW_888_IR, core, g_chip_ident,
+				chip);
+			break;
+		default:
+			err = -EINVAL; /* per V4L2 spec */
+			break;
+		}
+		break;
+	case V4L2_CHIP_MATCH_I2C_DRIVER:
+		/* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */
+		call_all(dev, core, g_chip_ident, chip);
+		break;
+	case V4L2_CHIP_MATCH_I2C_ADDR:
+		/*
+		 * We could return V4L2_IDENT_UNKNOWN, but we don't do the work
+		 * to look if a chip is at the address with no driver.  That's a
+		 * dangerous thing to do with EEPROMs anyway.
+		 */
+		call_all(dev, core, g_chip_ident, chip);
+		break;
+	default:
+		err = -EINVAL;
+		break;
+	}
+	return err;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int cx23885_g_host_register(struct cx23885_dev *dev,
+				   struct v4l2_dbg_register *reg)
+{
+	if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0))
+		return -EINVAL;
+
+	reg->size = 4;
+	reg->val = cx_read(reg->reg);
+	return 0;
+}
+
+static int cx23417_g_register(struct cx23885_dev *dev,
+			      struct v4l2_dbg_register *reg)
+{
+	u32 value;
+
+	if (dev->v4l_device == NULL)
+		return -EINVAL;
+
+	if ((reg->reg & 0x3) != 0 || reg->reg >= 0x10000)
+		return -EINVAL;
+
+	if (mc417_register_read(dev, (u16) reg->reg, &value))
+		return -EINVAL; /* V4L2 spec, but -EREMOTEIO really */
+
+	reg->size = 4;
+	reg->val = value;
+	return 0;
+}
+
+int cx23885_g_register(struct file *file, void *fh,
+		       struct v4l2_dbg_register *reg)
+{
+	struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (reg->match.type == V4L2_CHIP_MATCH_HOST) {
+		switch (reg->match.addr) {
+		case 0:
+			return cx23885_g_host_register(dev, reg);
+		case 1:
+			return cx23417_g_register(dev, reg);
+		default:
+			break;
+		}
+	}
+
+	/* FIXME - any error returns should not be ignored */
+	call_all(dev, core, g_register, reg);
+	return 0;
+}
+
+static int cx23885_s_host_register(struct cx23885_dev *dev,
+				   struct v4l2_dbg_register *reg)
+{
+	if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0))
+		return -EINVAL;
+
+	reg->size = 4;
+	cx_write(reg->reg, reg->val);
+	return 0;
+}
+
+static int cx23417_s_register(struct cx23885_dev *dev,
+			      struct v4l2_dbg_register *reg)
+{
+	if (dev->v4l_device == NULL)
+		return -EINVAL;
+
+	if ((reg->reg & 0x3) != 0 || reg->reg >= 0x10000)
+		return -EINVAL;
+
+	if (mc417_register_write(dev, (u16) reg->reg, (u32) reg->val))
+		return -EINVAL; /* V4L2 spec, but -EREMOTEIO really */
+
+	reg->size = 4;
+	return 0;
+}
+
+int cx23885_s_register(struct file *file, void *fh,
+		       struct v4l2_dbg_register *reg)
+{
+	struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (reg->match.type == V4L2_CHIP_MATCH_HOST) {
+		switch (reg->match.addr) {
+		case 0:
+			return cx23885_s_host_register(dev, reg);
+		case 1:
+			return cx23417_s_register(dev, reg);
+		default:
+			break;
+		}
+	}
+
+	/* FIXME - any error returns should not be ignored */
+	call_all(dev, core, s_register, reg);
+	return 0;
+}
+#endif
diff --git a/drivers/media/video/cx23885/cx23885-ioctl.h b/drivers/media/video/cx23885/cx23885-ioctl.h
new file mode 100644
index 0000000..80b0f49
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-ioctl.h
@@ -0,0 +1,39 @@
+/*
+ *  Driver for the Conexant CX23885/7/8 PCIe bridge
+ *
+ *  Various common ioctl() support functions
+ *
+ *  Copyright (c) 2009 Andy Walls <awalls@radix.net>
+ *
+ *  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.
+ */
+
+#ifndef _CX23885_IOCTL_H_
+#define _CX23885_IOCTL_H_
+
+int cx23885_g_chip_ident(struct file *file, void *fh,
+			 struct v4l2_dbg_chip_ident *chip);
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+int cx23885_g_register(struct file *file, void *fh,
+		       struct v4l2_dbg_register *reg);
+
+
+int cx23885_s_register(struct file *file, void *fh,
+		       struct v4l2_dbg_register *reg);
+
+#endif
+#endif
diff --git a/drivers/media/video/cx23885/cx23885-ir.c b/drivers/media/video/cx23885/cx23885-ir.c
new file mode 100644
index 0000000..6ae982c
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-ir.c
@@ -0,0 +1,101 @@
+/*
+ *  Driver for the Conexant CX23885/7/8 PCIe bridge
+ *
+ *  Infrared device support routines - non-input, non-vl42_subdev routines
+ *
+ *  Copyright (C) 2009  Andy Walls <awalls@radix.net>
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA
+ *  02110-1301, USA.
+ */
+
+#include <media/v4l2-device.h>
+
+#include "cx23885.h"
+#include "cx23885-input.h"
+
+#define CX23885_IR_RX_FIFO_SERVICE_REQ		0
+#define CX23885_IR_RX_END_OF_RX_DETECTED	1
+#define CX23885_IR_RX_HW_FIFO_OVERRUN		2
+#define CX23885_IR_RX_SW_FIFO_OVERRUN		3
+
+#define CX23885_IR_TX_FIFO_SERVICE_REQ		0
+
+
+void cx23885_ir_rx_work_handler(struct work_struct *work)
+{
+	struct cx23885_dev *dev =
+			     container_of(work, struct cx23885_dev, ir_rx_work);
+	u32 events = 0;
+	unsigned long *notifications = &dev->ir_rx_notifications;
+
+	if (test_and_clear_bit(CX23885_IR_RX_SW_FIFO_OVERRUN, notifications))
+		events |= V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN;
+	if (test_and_clear_bit(CX23885_IR_RX_HW_FIFO_OVERRUN, notifications))
+		events |= V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN;
+	if (test_and_clear_bit(CX23885_IR_RX_END_OF_RX_DETECTED, notifications))
+		events |= V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED;
+	if (test_and_clear_bit(CX23885_IR_RX_FIFO_SERVICE_REQ, notifications))
+		events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ;
+
+	if (events == 0)
+		return;
+
+	if (dev->ir_input)
+		cx23885_input_rx_work_handler(dev, events);
+}
+
+void cx23885_ir_tx_work_handler(struct work_struct *work)
+{
+	struct cx23885_dev *dev =
+			     container_of(work, struct cx23885_dev, ir_tx_work);
+	u32 events = 0;
+	unsigned long *notifications = &dev->ir_tx_notifications;
+
+	if (test_and_clear_bit(CX23885_IR_TX_FIFO_SERVICE_REQ, notifications))
+		events |= V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ;
+
+	if (events == 0)
+		return;
+
+}
+
+/* Called in an IRQ context */
+void cx23885_ir_rx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events)
+{
+	struct cx23885_dev *dev = to_cx23885(sd->v4l2_dev);
+	unsigned long *notifications = &dev->ir_rx_notifications;
+
+	if (events & V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ)
+		set_bit(CX23885_IR_RX_FIFO_SERVICE_REQ, notifications);
+	if (events & V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED)
+		set_bit(CX23885_IR_RX_END_OF_RX_DETECTED, notifications);
+	if (events & V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN)
+		set_bit(CX23885_IR_RX_HW_FIFO_OVERRUN, notifications);
+	if (events & V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN)
+		set_bit(CX23885_IR_RX_SW_FIFO_OVERRUN, notifications);
+	schedule_work(&dev->ir_rx_work);
+}
+
+/* Called in an IRQ context */
+void cx23885_ir_tx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events)
+{
+	struct cx23885_dev *dev = to_cx23885(sd->v4l2_dev);
+	unsigned long *notifications = &dev->ir_tx_notifications;
+
+	if (events & V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ)
+		set_bit(CX23885_IR_TX_FIFO_SERVICE_REQ, notifications);
+	schedule_work(&dev->ir_tx_work);
+}
diff --git a/drivers/media/video/cx23885/cx23885-ir.h b/drivers/media/video/cx23885/cx23885-ir.h
new file mode 100644
index 0000000..9b8a6d5
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-ir.h
@@ -0,0 +1,31 @@
+/*
+ *  Driver for the Conexant CX23885/7/8 PCIe bridge
+ *
+ *  Infrared device support routines - non-input, non-vl42_subdev routines
+ *
+ *  Copyright (C) 2009  Andy Walls <awalls@radix.net>
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA
+ *  02110-1301, USA.
+ */
+
+#ifndef _CX23885_IR_H_
+#define _CX23885_IR_H_
+void cx23885_ir_rx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events);
+void cx23885_ir_tx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events);
+
+void cx23885_ir_rx_work_handler(struct work_struct *work);
+void cx23885_ir_tx_work_handler(struct work_struct *work);
+#endif
diff --git a/drivers/media/video/cx23885/cx23885-reg.h b/drivers/media/video/cx23885/cx23885-reg.h
index eafbe52..c0bc9a0 100644
--- a/drivers/media/video/cx23885/cx23885-reg.h
+++ b/drivers/media/video/cx23885/cx23885-reg.h
@@ -212,8 +212,9 @@
 
 #define DEV_CNTRL2	0x00040000
 
-#define PCI_MSK_GPIO1   (1 << 24)
-#define PCI_MSK_GPIO0   (1 << 23)
+#define PCI_MSK_IR        (1 << 28)
+#define PCI_MSK_GPIO1     (1 << 24)
+#define PCI_MSK_GPIO0     (1 << 23)
 #define PCI_MSK_APB_DMA   (1 << 12)
 #define PCI_MSK_AL_WR     (1 << 11)
 #define PCI_MSK_AL_RD     (1 << 10)
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 654cc25..8b372b4 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -35,6 +35,7 @@
 #include "cx23885.h"
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
+#include "cx23885-ioctl.h"
 
 MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards");
 MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
@@ -401,6 +402,13 @@
 		INPUT(input)->gpio2, INPUT(input)->gpio3);
 	dev->input = input;
 
+	if (dev->board == CX23885_BOARD_MYGICA_X8506 ||
+		dev->board == CX23885_BOARD_MAGICPRO_PROHDTVE2) {
+		/* Select Analog TV */
+		if (INPUT(input)->type == CX23885_VMUX_TELEVISION)
+			cx23885_gpio_clear(dev, GPIO_0);
+	}
+
 	/* Tell the internal A/V decoder */
 	v4l2_subdev_call(dev->sd_cx25840, video, s_routing,
 			INPUT(input)->vmux, 0, 0);
@@ -1144,6 +1152,7 @@
 		[CX23885_VMUX_COMPOSITE3] = "Composite3",
 		[CX23885_VMUX_COMPOSITE4] = "Composite4",
 		[CX23885_VMUX_SVIDEO]     = "S-Video",
+		[CX23885_VMUX_COMPONENT]  = "Component",
 		[CX23885_VMUX_TELEVISION] = "Television",
 		[CX23885_VMUX_CABLE]      = "Cable TV",
 		[CX23885_VMUX_DVB]        = "DVB",
@@ -1312,34 +1321,6 @@
 		cx23885_set_freq(dev, f);
 }
 
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int vidioc_g_register(struct file *file, void *fh,
-				struct v4l2_dbg_register *reg)
-{
-	struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
-
-	if (!v4l2_chip_match_host(&reg->match))
-		return -EINVAL;
-
-	call_all(dev, core, g_register, reg);
-
-	return 0;
-}
-
-static int vidioc_s_register(struct file *file, void *fh,
-				struct v4l2_dbg_register *reg)
-{
-	struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
-
-	if (!v4l2_chip_match_host(&reg->match))
-		return -EINVAL;
-
-	call_all(dev, core, s_register, reg);
-
-	return 0;
-}
-#endif
-
 /* ----------------------------------------------------------- */
 
 static void cx23885_vid_timeout(unsigned long data)
@@ -1449,9 +1430,10 @@
 	.vidioc_s_tuner       = vidioc_s_tuner,
 	.vidioc_g_frequency   = vidioc_g_frequency,
 	.vidioc_s_frequency   = vidioc_s_frequency,
+	.vidioc_g_chip_ident  = cx23885_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-	.vidioc_g_register    = vidioc_g_register,
-	.vidioc_s_register    = vidioc_s_register,
+	.vidioc_g_register    = cx23885_g_register,
+	.vidioc_s_register    = cx23885_s_register,
 #endif
 };
 
@@ -1529,9 +1511,11 @@
 		if (sd) {
 			struct tuner_setup tun_setup;
 
+			memset(&tun_setup, 0, sizeof(tun_setup));
 			tun_setup.mode_mask = T_ANALOG_TV;
 			tun_setup.type = dev->tuner_type;
 			tun_setup.addr = v4l2_i2c_subdev_addr(sd);
+			tun_setup.tuner_callback = cx23885_tuner_callback;
 
 			v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup);
 		}
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index cc7a165..fa74476 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -79,6 +79,8 @@
 #define CX23885_BOARD_MAGICPRO_PROHDTVE2       23
 #define CX23885_BOARD_HAUPPAUGE_HVR1850        24
 #define CX23885_BOARD_COMPRO_VIDEOMATE_E800    25
+#define CX23885_BOARD_HAUPPAUGE_HVR1290        26
+#define CX23885_BOARD_MYGICA_X8558PRO          27
 
 #define GPIO_0 0x00000001
 #define GPIO_1 0x00000002
@@ -157,6 +159,7 @@
 	CX23885_VMUX_COMPOSITE3,
 	CX23885_VMUX_COMPOSITE4,
 	CX23885_VMUX_SVIDEO,
+	CX23885_VMUX_COMPONENT,
 	CX23885_VMUX_TELEVISION,
 	CX23885_VMUX_CABLE,
 	CX23885_VMUX_DVB,
@@ -297,10 +300,6 @@
 	/* Allow a single tsport to have multiple frontends */
 	u32                        num_frontends;
 	void                       *port_priv;
-
-	/* FIXME: temporary hack */
-	int (*set_frontend_save) (struct dvb_frontend *,
-				  struct dvb_frontend_parameters *);
 };
 
 struct cx23885_dev {
@@ -356,6 +355,16 @@
 	unsigned int               has_radio;
 	struct v4l2_subdev 	   *sd_cx25840;
 
+	/* Infrared */
+	struct v4l2_subdev         *sd_ir;
+	struct work_struct	   ir_rx_work;
+	unsigned long		   ir_rx_notifications;
+	struct work_struct	   ir_tx_work;
+	unsigned long		   ir_tx_notifications;
+
+	struct card_ir		   *ir_input;
+	atomic_t		   ir_input_stopping;
+
 	/* V4l */
 	u32                        freq;
 	struct video_device        *video_dev;
@@ -383,6 +392,13 @@
 #define call_all(dev, o, f, args...) \
 	v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args)
 
+#define CX23885_HW_888_IR (1 << 0)
+
+#define call_hw(dev, grpid, o, f, args...) \
+	v4l2_device_call_all(&dev->v4l2_dev, grpid, o, f, ##args)
+
+extern struct v4l2_subdev *cx23885_find_hw(struct cx23885_dev *dev, u32 hw);
+
 extern struct list_head cx23885_devlist;
 
 #define SRAM_CH01  0 /* Video A */
@@ -455,6 +471,7 @@
 
 extern void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask);
 extern void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask);
+extern u32 cx23885_gpio_get(struct cx23885_dev *dev, u32 mask);
 extern void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask,
 	int asoutput);
 
@@ -471,6 +488,8 @@
 	int command, int arg);
 extern void cx23885_card_list(struct cx23885_dev *dev);
 extern int  cx23885_ir_init(struct cx23885_dev *dev);
+extern void cx23885_ir_pci_int_enable(struct cx23885_dev *dev);
+extern void cx23885_ir_fini(struct cx23885_dev *dev);
 extern void cx23885_gpio_setup(struct cx23885_dev *dev);
 extern void cx23885_card_setup(struct cx23885_dev *dev);
 extern void cx23885_card_setup_pre_i2c(struct cx23885_dev *dev);
@@ -515,6 +534,10 @@
 extern void cx23885_mc417_init(struct cx23885_dev *dev);
 extern int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value);
 extern int mc417_memory_write(struct cx23885_dev *dev, u32 address, u32 value);
+extern int mc417_register_read(struct cx23885_dev *dev,
+				u16 address, u32 *value);
+extern int mc417_register_write(struct cx23885_dev *dev,
+				u16 address, u32 value);
 extern void mc417_gpio_set(struct cx23885_dev *dev, u32 mask);
 extern void mc417_gpio_clear(struct cx23885_dev *dev, u32 mask);
 extern void mc417_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput);
diff --git a/drivers/media/video/cx23885/cx23888-ir.c b/drivers/media/video/cx23885/cx23888-ir.c
new file mode 100644
index 0000000..3ccc8af
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23888-ir.c
@@ -0,0 +1,1239 @@
+/*
+ *  Driver for the Conexant CX23885/7/8 PCIe bridge
+ *
+ *  CX23888 Integrated Consumer Infrared Controller
+ *
+ *  Copyright (C) 2009  Andy Walls <awalls@radix.net>
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA
+ *  02110-1301, USA.
+ */
+
+#include <linux/kfifo.h>
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+
+#include "cx23885.h"
+
+static unsigned int ir_888_debug;
+module_param(ir_888_debug, int, 0644);
+MODULE_PARM_DESC(ir_888_debug, "enable debug messages [CX23888 IR controller]");
+
+#define CX23888_IR_REG_BASE 	0x170000
+/*
+ * These CX23888 register offsets have a straightforward one to one mapping
+ * to the CX23885 register offsets of 0x200 through 0x218
+ */
+#define CX23888_IR_CNTRL_REG	0x170000
+#define CNTRL_WIN_3_3	0x00000000
+#define CNTRL_WIN_4_3	0x00000001
+#define CNTRL_WIN_3_4	0x00000002
+#define CNTRL_WIN_4_4	0x00000003
+#define CNTRL_WIN	0x00000003
+#define CNTRL_EDG_NONE	0x00000000
+#define CNTRL_EDG_FALL	0x00000004
+#define CNTRL_EDG_RISE	0x00000008
+#define CNTRL_EDG_BOTH	0x0000000C
+#define CNTRL_EDG	0x0000000C
+#define CNTRL_DMD	0x00000010
+#define CNTRL_MOD	0x00000020
+#define CNTRL_RFE	0x00000040
+#define CNTRL_TFE	0x00000080
+#define CNTRL_RXE	0x00000100
+#define CNTRL_TXE	0x00000200
+#define CNTRL_RIC	0x00000400
+#define CNTRL_TIC	0x00000800
+#define CNTRL_CPL	0x00001000
+#define CNTRL_LBM	0x00002000
+#define CNTRL_R		0x00004000
+
+#define CX23888_IR_TXCLK_REG	0x170004
+#define TXCLK_TCD	0x0000FFFF
+
+#define CX23888_IR_RXCLK_REG	0x170008
+#define RXCLK_RCD	0x0000FFFF
+
+#define CX23888_IR_CDUTY_REG	0x17000C
+#define CDUTY_CDC	0x0000000F
+
+#define CX23888_IR_STATS_REG	0x170010
+#define STATS_RTO	0x00000001
+#define STATS_ROR	0x00000002
+#define STATS_RBY	0x00000004
+#define STATS_TBY	0x00000008
+#define STATS_RSR	0x00000010
+#define STATS_TSR	0x00000020
+
+#define CX23888_IR_IRQEN_REG	0x170014
+#define IRQEN_RTE	0x00000001
+#define IRQEN_ROE	0x00000002
+#define IRQEN_RSE	0x00000010
+#define IRQEN_TSE	0x00000020
+
+#define CX23888_IR_FILTR_REG	0x170018
+#define FILTR_LPF	0x0000FFFF
+
+/* This register doesn't follow the pattern; it's 0x23C on a CX23885 */
+#define CX23888_IR_FIFO_REG	0x170040
+#define FIFO_RXTX	0x0000FFFF
+#define FIFO_RXTX_LVL	0x00010000
+#define FIFO_RXTX_RTO	0x0001FFFF
+#define FIFO_RX_NDV	0x00020000
+#define FIFO_RX_DEPTH	8
+#define FIFO_TX_DEPTH	8
+
+/* CX23888 unique registers */
+#define CX23888_IR_SEEDP_REG	0x17001C
+#define CX23888_IR_TIMOL_REG	0x170020
+#define CX23888_IR_WAKE0_REG	0x170024
+#define CX23888_IR_WAKE1_REG	0x170028
+#define CX23888_IR_WAKE2_REG	0x17002C
+#define CX23888_IR_MASK0_REG	0x170030
+#define CX23888_IR_MASK1_REG	0x170034
+#define CX23888_IR_MAKS2_REG	0x170038
+#define CX23888_IR_DPIPG_REG	0x17003C
+#define CX23888_IR_LEARN_REG	0x170044
+
+#define CX23888_VIDCLK_FREQ	108000000 /* 108 MHz, BT.656 */
+#define CX23888_IR_REFCLK_FREQ	(CX23888_VIDCLK_FREQ / 2)
+
+#define CX23888_IR_RX_KFIFO_SIZE	(512 * sizeof(u32))
+#define CX23888_IR_TX_KFIFO_SIZE	(512 * sizeof(u32))
+
+struct cx23888_ir_state {
+	struct v4l2_subdev sd;
+	struct cx23885_dev *dev;
+	u32 id;
+	u32 rev;
+
+	struct v4l2_subdev_ir_parameters rx_params;
+	struct mutex rx_params_lock;
+	atomic_t rxclk_divider;
+	atomic_t rx_invert;
+
+	struct kfifo *rx_kfifo;
+	spinlock_t rx_kfifo_lock;
+
+	struct v4l2_subdev_ir_parameters tx_params;
+	struct mutex tx_params_lock;
+	atomic_t txclk_divider;
+
+	struct kfifo *tx_kfifo;
+	spinlock_t tx_kfifo_lock;
+};
+
+static inline struct cx23888_ir_state *to_state(struct v4l2_subdev *sd)
+{
+	return v4l2_get_subdevdata(sd);
+}
+
+/*
+ * IR register block read and write functions
+ */
+static
+inline int cx23888_ir_write4(struct cx23885_dev *dev, u32 addr, u32 value)
+{
+	cx_write(addr, value);
+	return 0;
+}
+
+static inline u32 cx23888_ir_read4(struct cx23885_dev *dev, u32 addr)
+{
+	return cx_read(addr);
+}
+
+static inline int cx23888_ir_and_or4(struct cx23885_dev *dev, u32 addr,
+				     u32 and_mask, u32 or_value)
+{
+	cx_andor(addr, ~and_mask, or_value);
+	return 0;
+}
+
+/*
+ * Rx and Tx Clock Divider register computations
+ *
+ * Note the largest clock divider value of 0xffff corresponds to:
+ * 	(0xffff + 1) * 1000 / 108/2 MHz = 1,213,629.629... ns
+ * which fits in 21 bits, so we'll use unsigned int for time arguments.
+ */
+static inline u16 count_to_clock_divider(unsigned int d)
+{
+	if (d > RXCLK_RCD + 1)
+		d = RXCLK_RCD;
+	else if (d < 2)
+		d = 1;
+	else
+		d--;
+	return (u16) d;
+}
+
+static inline u16 ns_to_clock_divider(unsigned int ns)
+{
+	return count_to_clock_divider(
+		DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ / 1000000 * ns, 1000));
+}
+
+static inline unsigned int clock_divider_to_ns(unsigned int divider)
+{
+	/* Period of the Rx or Tx clock in ns */
+	return DIV_ROUND_CLOSEST((divider + 1) * 1000,
+				 CX23888_IR_REFCLK_FREQ / 1000000);
+}
+
+static inline u16 carrier_freq_to_clock_divider(unsigned int freq)
+{
+	return count_to_clock_divider(
+			  DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, freq * 16));
+}
+
+static inline unsigned int clock_divider_to_carrier_freq(unsigned int divider)
+{
+	return DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, (divider + 1) * 16);
+}
+
+static inline u16 freq_to_clock_divider(unsigned int freq,
+					unsigned int rollovers)
+{
+	return count_to_clock_divider(
+		   DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, freq * rollovers));
+}
+
+static inline unsigned int clock_divider_to_freq(unsigned int divider,
+						 unsigned int rollovers)
+{
+	return DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ,
+				 (divider + 1) * rollovers);
+}
+
+/*
+ * Low Pass Filter register calculations
+ *
+ * Note the largest count value of 0xffff corresponds to:
+ * 	0xffff * 1000 / 108/2 MHz = 1,213,611.11... ns
+ * which fits in 21 bits, so we'll use unsigned int for time arguments.
+ */
+static inline u16 count_to_lpf_count(unsigned int d)
+{
+	if (d > FILTR_LPF)
+		d = FILTR_LPF;
+	else if (d < 4)
+		d = 0;
+	return (u16) d;
+}
+
+static inline u16 ns_to_lpf_count(unsigned int ns)
+{
+	return count_to_lpf_count(
+		DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ / 1000000 * ns, 1000));
+}
+
+static inline unsigned int lpf_count_to_ns(unsigned int count)
+{
+	/* Duration of the Low Pass Filter rejection window in ns */
+	return DIV_ROUND_CLOSEST(count * 1000,
+				 CX23888_IR_REFCLK_FREQ / 1000000);
+}
+
+static inline unsigned int lpf_count_to_us(unsigned int count)
+{
+	/* Duration of the Low Pass Filter rejection window in us */
+	return DIV_ROUND_CLOSEST(count, CX23888_IR_REFCLK_FREQ / 1000000);
+}
+
+/*
+ * FIFO register pulse width count compuations
+ */
+static u32 clock_divider_to_resolution(u16 divider)
+{
+	/*
+	 * Resolution is the duration of 1 tick of the readable portion of
+	 * of the pulse width counter as read from the FIFO.  The two lsb's are
+	 * not readable, hence the << 2.  This function returns ns.
+	 */
+	return DIV_ROUND_CLOSEST((1 << 2)  * ((u32) divider + 1) * 1000,
+				 CX23888_IR_REFCLK_FREQ / 1000000);
+}
+
+static u64 pulse_width_count_to_ns(u16 count, u16 divider)
+{
+	u64 n;
+	u32 rem;
+
+	/*
+	 * The 2 lsb's of the pulse width timer count are not readable, hence
+	 * the (count << 2) | 0x3
+	 */
+	n = (((u64) count << 2) | 0x3) * (divider + 1) * 1000; /* millicycles */
+	rem = do_div(n, CX23888_IR_REFCLK_FREQ / 1000000);     /* / MHz => ns */
+	if (rem >= CX23888_IR_REFCLK_FREQ / 1000000 / 2)
+		n++;
+	return n;
+}
+
+static unsigned int pulse_width_count_to_us(u16 count, u16 divider)
+{
+	u64 n;
+	u32 rem;
+
+	/*
+	 * The 2 lsb's of the pulse width timer count are not readable, hence
+	 * the (count << 2) | 0x3
+	 */
+	n = (((u64) count << 2) | 0x3) * (divider + 1);    /* cycles      */
+	rem = do_div(n, CX23888_IR_REFCLK_FREQ / 1000000); /* / MHz => us */
+	if (rem >= CX23888_IR_REFCLK_FREQ / 1000000 / 2)
+		n++;
+	return (unsigned int) n;
+}
+
+/*
+ * Pulse Clocks computations: Combined Pulse Width Count & Rx Clock Counts
+ *
+ * The total pulse clock count is an 18 bit pulse width timer count as the most
+ * significant part and (up to) 16 bit clock divider count as a modulus.
+ * When the Rx clock divider ticks down to 0, it increments the 18 bit pulse
+ * width timer count's least significant bit.
+ */
+static u64 ns_to_pulse_clocks(u32 ns)
+{
+	u64 clocks;
+	u32 rem;
+	clocks = CX23888_IR_REFCLK_FREQ / 1000000 * (u64) ns; /* millicycles  */
+	rem = do_div(clocks, 1000);                         /* /1000 = cycles */
+	if (rem >= 1000 / 2)
+		clocks++;
+	return clocks;
+}
+
+static u16 pulse_clocks_to_clock_divider(u64 count)
+{
+	u32 rem;
+
+	rem = do_div(count, (FIFO_RXTX << 2) | 0x3);
+
+	/* net result needs to be rounded down and decremented by 1 */
+	if (count > RXCLK_RCD + 1)
+		count = RXCLK_RCD;
+	else if (count < 2)
+		count = 1;
+	else
+		count--;
+	return (u16) count;
+}
+
+/*
+ * IR Control Register helpers
+ */
+enum tx_fifo_watermark {
+	TX_FIFO_HALF_EMPTY = 0,
+	TX_FIFO_EMPTY      = CNTRL_TIC,
+};
+
+enum rx_fifo_watermark {
+	RX_FIFO_HALF_FULL = 0,
+	RX_FIFO_NOT_EMPTY = CNTRL_RIC,
+};
+
+static inline void control_tx_irq_watermark(struct cx23885_dev *dev,
+					    enum tx_fifo_watermark level)
+{
+	cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_TIC, level);
+}
+
+static inline void control_rx_irq_watermark(struct cx23885_dev *dev,
+					    enum rx_fifo_watermark level)
+{
+	cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_RIC, level);
+}
+
+static inline void control_tx_enable(struct cx23885_dev *dev, bool enable)
+{
+	cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~(CNTRL_TXE | CNTRL_TFE),
+			   enable ? (CNTRL_TXE | CNTRL_TFE) : 0);
+}
+
+static inline void control_rx_enable(struct cx23885_dev *dev, bool enable)
+{
+	cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~(CNTRL_RXE | CNTRL_RFE),
+			   enable ? (CNTRL_RXE | CNTRL_RFE) : 0);
+}
+
+static inline void control_tx_modulation_enable(struct cx23885_dev *dev,
+						bool enable)
+{
+	cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_MOD,
+			   enable ? CNTRL_MOD : 0);
+}
+
+static inline void control_rx_demodulation_enable(struct cx23885_dev *dev,
+						  bool enable)
+{
+	cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_DMD,
+			   enable ? CNTRL_DMD : 0);
+}
+
+static inline void control_rx_s_edge_detection(struct cx23885_dev *dev,
+					       u32 edge_types)
+{
+	cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_EDG_BOTH,
+			   edge_types & CNTRL_EDG_BOTH);
+}
+
+static void control_rx_s_carrier_window(struct cx23885_dev *dev,
+					unsigned int carrier,
+					unsigned int *carrier_range_low,
+					unsigned int *carrier_range_high)
+{
+	u32 v;
+	unsigned int c16 = carrier * 16;
+
+	if (*carrier_range_low < DIV_ROUND_CLOSEST(c16, 16 + 3)) {
+		v = CNTRL_WIN_3_4;
+		*carrier_range_low = DIV_ROUND_CLOSEST(c16, 16 + 4);
+	} else {
+		v = CNTRL_WIN_3_3;
+		*carrier_range_low = DIV_ROUND_CLOSEST(c16, 16 + 3);
+	}
+
+	if (*carrier_range_high > DIV_ROUND_CLOSEST(c16, 16 - 3)) {
+		v |= CNTRL_WIN_4_3;
+		*carrier_range_high = DIV_ROUND_CLOSEST(c16, 16 - 4);
+	} else {
+		v |= CNTRL_WIN_3_3;
+		*carrier_range_high = DIV_ROUND_CLOSEST(c16, 16 - 3);
+	}
+	cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_WIN, v);
+}
+
+static inline void control_tx_polarity_invert(struct cx23885_dev *dev,
+					      bool invert)
+{
+	cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_CPL,
+			   invert ? CNTRL_CPL : 0);
+}
+
+/*
+ * IR Rx & Tx Clock Register helpers
+ */
+static unsigned int txclk_tx_s_carrier(struct cx23885_dev *dev,
+				       unsigned int freq,
+				       u16 *divider)
+{
+	*divider = carrier_freq_to_clock_divider(freq);
+	cx23888_ir_write4(dev, CX23888_IR_TXCLK_REG, *divider);
+	return clock_divider_to_carrier_freq(*divider);
+}
+
+static unsigned int rxclk_rx_s_carrier(struct cx23885_dev *dev,
+				       unsigned int freq,
+				       u16 *divider)
+{
+	*divider = carrier_freq_to_clock_divider(freq);
+	cx23888_ir_write4(dev, CX23888_IR_RXCLK_REG, *divider);
+	return clock_divider_to_carrier_freq(*divider);
+}
+
+static u32 txclk_tx_s_max_pulse_width(struct cx23885_dev *dev, u32 ns,
+				      u16 *divider)
+{
+	u64 pulse_clocks;
+
+	if (ns > V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS)
+		ns = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS;
+	pulse_clocks = ns_to_pulse_clocks(ns);
+	*divider = pulse_clocks_to_clock_divider(pulse_clocks);
+	cx23888_ir_write4(dev, CX23888_IR_TXCLK_REG, *divider);
+	return (u32) pulse_width_count_to_ns(FIFO_RXTX, *divider);
+}
+
+static u32 rxclk_rx_s_max_pulse_width(struct cx23885_dev *dev, u32 ns,
+				      u16 *divider)
+{
+	u64 pulse_clocks;
+
+	if (ns > V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS)
+		ns = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS;
+	pulse_clocks = ns_to_pulse_clocks(ns);
+	*divider = pulse_clocks_to_clock_divider(pulse_clocks);
+	cx23888_ir_write4(dev, CX23888_IR_RXCLK_REG, *divider);
+	return (u32) pulse_width_count_to_ns(FIFO_RXTX, *divider);
+}
+
+/*
+ * IR Tx Carrier Duty Cycle register helpers
+ */
+static unsigned int cduty_tx_s_duty_cycle(struct cx23885_dev *dev,
+					  unsigned int duty_cycle)
+{
+	u32 n;
+	n = DIV_ROUND_CLOSEST(duty_cycle * 100, 625); /* 16ths of 100% */
+	if (n != 0)
+		n--;
+	if (n > 15)
+		n = 15;
+	cx23888_ir_write4(dev, CX23888_IR_CDUTY_REG, n);
+	return DIV_ROUND_CLOSEST((n + 1) * 100, 16);
+}
+
+/*
+ * IR Filter Register helpers
+ */
+static u32 filter_rx_s_min_width(struct cx23885_dev *dev, u32 min_width_ns)
+{
+	u32 count = ns_to_lpf_count(min_width_ns);
+	cx23888_ir_write4(dev, CX23888_IR_FILTR_REG, count);
+	return lpf_count_to_ns(count);
+}
+
+/*
+ * IR IRQ Enable Register helpers
+ */
+static inline void irqenable_rx(struct cx23885_dev *dev, u32 mask)
+{
+	mask &= (IRQEN_RTE | IRQEN_ROE | IRQEN_RSE);
+	cx23888_ir_and_or4(dev, CX23888_IR_IRQEN_REG,
+			   ~(IRQEN_RTE | IRQEN_ROE | IRQEN_RSE), mask);
+}
+
+static inline void irqenable_tx(struct cx23885_dev *dev, u32 mask)
+{
+	mask &= IRQEN_TSE;
+	cx23888_ir_and_or4(dev, CX23888_IR_IRQEN_REG, ~IRQEN_TSE, mask);
+}
+
+/*
+ * V4L2 Subdevice IR Ops
+ */
+static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status,
+				  bool *handled)
+{
+	struct cx23888_ir_state *state = to_state(sd);
+	struct cx23885_dev *dev = state->dev;
+
+	u32 cntrl = cx23888_ir_read4(dev, CX23888_IR_CNTRL_REG);
+	u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG);
+	u32 stats = cx23888_ir_read4(dev, CX23888_IR_STATS_REG);
+
+	u32 rx_data[FIFO_RX_DEPTH];
+	int i, j, k;
+	u32 events, v;
+	int tsr, rsr, rto, ror, tse, rse, rte, roe, kror;
+
+	tsr = stats & STATS_TSR; /* Tx FIFO Service Request */
+	rsr = stats & STATS_RSR; /* Rx FIFO Service Request */
+	rto = stats & STATS_RTO; /* Rx Pulse Width Timer Time Out */
+	ror = stats & STATS_ROR; /* Rx FIFO Over Run */
+
+	tse = irqen & IRQEN_TSE; /* Tx FIFO Service Request IRQ Enable */
+	rse = irqen & IRQEN_RSE; /* Rx FIFO Service Reuqest IRQ Enable */
+	rte = irqen & IRQEN_RTE; /* Rx Pulse Width Timer Time Out IRQ Enable */
+	roe = irqen & IRQEN_ROE; /* Rx FIFO Over Run IRQ Enable */
+
+	*handled = false;
+	v4l2_dbg(2, ir_888_debug, sd, "IRQ Status:  %s %s %s %s %s %s\n",
+		 tsr ? "tsr" : "   ", rsr ? "rsr" : "   ",
+		 rto ? "rto" : "   ", ror ? "ror" : "   ",
+		 stats & STATS_TBY ? "tby" : "   ",
+		 stats & STATS_RBY ? "rby" : "   ");
+
+	v4l2_dbg(2, ir_888_debug, sd, "IRQ Enables: %s %s %s %s\n",
+		 tse ? "tse" : "   ", rse ? "rse" : "   ",
+		 rte ? "rte" : "   ", roe ? "roe" : "   ");
+
+	/*
+	 * Transmitter interrupt service
+	 */
+	if (tse && tsr) {
+		/*
+		 * TODO:
+		 * Check the watermark threshold setting
+		 * Pull FIFO_TX_DEPTH or FIFO_TX_DEPTH/2 entries from tx_kfifo
+		 * Push the data to the hardware FIFO.
+		 * If there was nothing more to send in the tx_kfifo, disable
+		 *	the TSR IRQ and notify the v4l2_device.
+		 * If there was something in the tx_kfifo, check the tx_kfifo
+		 *      level and notify the v4l2_device, if it is low.
+		 */
+		/* For now, inhibit TSR interrupt until Tx is implemented */
+		irqenable_tx(dev, 0);
+		events = V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ;
+		v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_TX_NOTIFY, &events);
+		*handled = true;
+	}
+
+	/*
+	 * Receiver interrupt service
+	 */
+	kror = 0;
+	if ((rse && rsr) || (rte && rto)) {
+		/*
+		 * Receive data on RSR to clear the STATS_RSR.
+		 * Receive data on RTO, since we may not have yet hit the RSR
+		 * watermark when we receive the RTO.
+		 */
+		for (i = 0, v = FIFO_RX_NDV;
+		     (v & FIFO_RX_NDV) && !kror; i = 0) {
+			for (j = 0;
+			     (v & FIFO_RX_NDV) && j < FIFO_RX_DEPTH; j++) {
+				v = cx23888_ir_read4(dev, CX23888_IR_FIFO_REG);
+				rx_data[i++] = v & ~FIFO_RX_NDV;
+			}
+			if (i == 0)
+				break;
+			j = i * sizeof(u32);
+			k = kfifo_put(state->rx_kfifo,
+				      (unsigned char *) rx_data, j);
+			if (k != j)
+				kror++; /* rx_kfifo over run */
+		}
+		*handled = true;
+	}
+
+	events = 0;
+	v = 0;
+	if (kror) {
+		events |= V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN;
+		v4l2_err(sd, "IR receiver software FIFO overrun\n");
+	}
+	if (roe && ror) {
+		/*
+		 * The RX FIFO Enable (CNTRL_RFE) must be toggled to clear
+		 * the Rx FIFO Over Run status (STATS_ROR)
+		 */
+		v |= CNTRL_RFE;
+		events |= V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN;
+		v4l2_err(sd, "IR receiver hardware FIFO overrun\n");
+	}
+	if (rte && rto) {
+		/*
+		 * The IR Receiver Enable (CNTRL_RXE) must be toggled to clear
+		 * the Rx Pulse Width Timer Time Out (STATS_RTO)
+		 */
+		v |= CNTRL_RXE;
+		events |= V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED;
+	}
+	if (v) {
+		/* Clear STATS_ROR & STATS_RTO as needed by reseting hardware */
+		cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl & ~v);
+		cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl);
+		*handled = true;
+	}
+	if (kfifo_len(state->rx_kfifo) >= CX23888_IR_RX_KFIFO_SIZE / 2)
+		events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ;
+
+	if (events)
+		v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_RX_NOTIFY, &events);
+	return 0;
+}
+
+/* Receiver */
+static int cx23888_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count,
+			      ssize_t *num)
+{
+	struct cx23888_ir_state *state = to_state(sd);
+	bool invert = (bool) atomic_read(&state->rx_invert);
+	u16 divider = (u16) atomic_read(&state->rxclk_divider);
+
+	unsigned int i, n;
+	u32 *p;
+	u32 u, v;
+
+	n = count / sizeof(u32) * sizeof(u32);
+	if (n == 0) {
+		*num = 0;
+		return 0;
+	}
+
+	n = kfifo_get(state->rx_kfifo, buf, n);
+
+	n /= sizeof(u32);
+	*num = n * sizeof(u32);
+
+	for (p = (u32 *) buf, i = 0; i < n; p++, i++) {
+		if ((*p & FIFO_RXTX_RTO) == FIFO_RXTX_RTO) {
+			*p = V4L2_SUBDEV_IR_PULSE_RX_SEQ_END;
+			v4l2_dbg(2, ir_888_debug, sd, "rx read: end of rx\n");
+			continue;
+		}
+
+		u = (*p & FIFO_RXTX_LVL) ? V4L2_SUBDEV_IR_PULSE_LEVEL_MASK : 0;
+		if (invert)
+			u = u ? 0 : V4L2_SUBDEV_IR_PULSE_LEVEL_MASK;
+
+		v = (u32) pulse_width_count_to_ns((u16) (*p & FIFO_RXTX),
+						  divider);
+		if (v >= V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS)
+			v = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS - 1;
+
+		*p = u | v;
+
+		v4l2_dbg(2, ir_888_debug, sd, "rx read: %10u ns  %s\n",
+			 v, u ? "mark" : "space");
+	}
+	return 0;
+}
+
+static int cx23888_ir_rx_g_parameters(struct v4l2_subdev *sd,
+				      struct v4l2_subdev_ir_parameters *p)
+{
+	struct cx23888_ir_state *state = to_state(sd);
+	mutex_lock(&state->rx_params_lock);
+	memcpy(p, &state->rx_params, sizeof(struct v4l2_subdev_ir_parameters));
+	mutex_unlock(&state->rx_params_lock);
+	return 0;
+}
+
+static int cx23888_ir_rx_shutdown(struct v4l2_subdev *sd)
+{
+	struct cx23888_ir_state *state = to_state(sd);
+	struct cx23885_dev *dev = state->dev;
+
+	mutex_lock(&state->rx_params_lock);
+
+	/* Disable or slow down all IR Rx circuits and counters */
+	irqenable_rx(dev, 0);
+	control_rx_enable(dev, false);
+	control_rx_demodulation_enable(dev, false);
+	control_rx_s_edge_detection(dev, CNTRL_EDG_NONE);
+	filter_rx_s_min_width(dev, 0);
+	cx23888_ir_write4(dev, CX23888_IR_RXCLK_REG, RXCLK_RCD);
+
+	state->rx_params.shutdown = true;
+
+	mutex_unlock(&state->rx_params_lock);
+	return 0;
+}
+
+static int cx23888_ir_rx_s_parameters(struct v4l2_subdev *sd,
+				      struct v4l2_subdev_ir_parameters *p)
+{
+	struct cx23888_ir_state *state = to_state(sd);
+	struct cx23885_dev *dev = state->dev;
+	struct v4l2_subdev_ir_parameters *o = &state->rx_params;
+	u16 rxclk_divider;
+
+	if (p->shutdown)
+		return cx23888_ir_rx_shutdown(sd);
+
+	if (p->mode != V4L2_SUBDEV_IR_MODE_PULSE_WIDTH)
+		return -ENOSYS;
+
+	mutex_lock(&state->rx_params_lock);
+
+	o->shutdown = p->shutdown;
+
+	o->mode = p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
+
+	o->bytes_per_data_element = p->bytes_per_data_element = sizeof(u32);
+
+	/* Before we tweak the hardware, we have to disable the receiver */
+	irqenable_rx(dev, 0);
+	control_rx_enable(dev, false);
+
+	control_rx_demodulation_enable(dev, p->modulation);
+	o->modulation = p->modulation;
+
+	if (p->modulation) {
+		p->carrier_freq = rxclk_rx_s_carrier(dev, p->carrier_freq,
+						     &rxclk_divider);
+
+		o->carrier_freq = p->carrier_freq;
+
+		o->duty_cycle = p->duty_cycle = 50;
+
+		control_rx_s_carrier_window(dev, p->carrier_freq,
+					    &p->carrier_range_lower,
+					    &p->carrier_range_upper);
+		o->carrier_range_lower = p->carrier_range_lower;
+		o->carrier_range_upper = p->carrier_range_upper;
+	} else {
+		p->max_pulse_width =
+			    rxclk_rx_s_max_pulse_width(dev, p->max_pulse_width,
+						       &rxclk_divider);
+		o->max_pulse_width = p->max_pulse_width;
+	}
+	atomic_set(&state->rxclk_divider, rxclk_divider);
+
+	p->noise_filter_min_width =
+			  filter_rx_s_min_width(dev, p->noise_filter_min_width);
+	o->noise_filter_min_width = p->noise_filter_min_width;
+
+	p->resolution = clock_divider_to_resolution(rxclk_divider);
+	o->resolution = p->resolution;
+
+	/* FIXME - make this dependent on resolution for better performance */
+	control_rx_irq_watermark(dev, RX_FIFO_HALF_FULL);
+
+	control_rx_s_edge_detection(dev, CNTRL_EDG_BOTH);
+
+	o->invert = p->invert;
+	atomic_set(&state->rx_invert, p->invert);
+
+	o->interrupt_enable = p->interrupt_enable;
+	o->enable = p->enable;
+	if (p->enable) {
+		kfifo_reset(state->rx_kfifo);
+		if (p->interrupt_enable)
+			irqenable_rx(dev, IRQEN_RSE | IRQEN_RTE | IRQEN_ROE);
+		control_rx_enable(dev, p->enable);
+	}
+
+	mutex_unlock(&state->rx_params_lock);
+	return 0;
+}
+
+/* Transmitter */
+static int cx23888_ir_tx_write(struct v4l2_subdev *sd, u8 *buf, size_t count,
+			       ssize_t *num)
+{
+	struct cx23888_ir_state *state = to_state(sd);
+	struct cx23885_dev *dev = state->dev;
+	/* For now enable the Tx FIFO Service interrupt & pretend we did work */
+	irqenable_tx(dev, IRQEN_TSE);
+	*num = count;
+	return 0;
+}
+
+static int cx23888_ir_tx_g_parameters(struct v4l2_subdev *sd,
+				      struct v4l2_subdev_ir_parameters *p)
+{
+	struct cx23888_ir_state *state = to_state(sd);
+	mutex_lock(&state->tx_params_lock);
+	memcpy(p, &state->tx_params, sizeof(struct v4l2_subdev_ir_parameters));
+	mutex_unlock(&state->tx_params_lock);
+	return 0;
+}
+
+static int cx23888_ir_tx_shutdown(struct v4l2_subdev *sd)
+{
+	struct cx23888_ir_state *state = to_state(sd);
+	struct cx23885_dev *dev = state->dev;
+
+	mutex_lock(&state->tx_params_lock);
+
+	/* Disable or slow down all IR Tx circuits and counters */
+	irqenable_tx(dev, 0);
+	control_tx_enable(dev, false);
+	control_tx_modulation_enable(dev, false);
+	cx23888_ir_write4(dev, CX23888_IR_TXCLK_REG, TXCLK_TCD);
+
+	state->tx_params.shutdown = true;
+
+	mutex_unlock(&state->tx_params_lock);
+	return 0;
+}
+
+static int cx23888_ir_tx_s_parameters(struct v4l2_subdev *sd,
+				      struct v4l2_subdev_ir_parameters *p)
+{
+	struct cx23888_ir_state *state = to_state(sd);
+	struct cx23885_dev *dev = state->dev;
+	struct v4l2_subdev_ir_parameters *o = &state->tx_params;
+	u16 txclk_divider;
+
+	if (p->shutdown)
+		return cx23888_ir_tx_shutdown(sd);
+
+	if (p->mode != V4L2_SUBDEV_IR_MODE_PULSE_WIDTH)
+		return -ENOSYS;
+
+	mutex_lock(&state->tx_params_lock);
+
+	o->shutdown = p->shutdown;
+
+	o->mode = p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
+
+	o->bytes_per_data_element = p->bytes_per_data_element = sizeof(u32);
+
+	/* Before we tweak the hardware, we have to disable the transmitter */
+	irqenable_tx(dev, 0);
+	control_tx_enable(dev, false);
+
+	control_tx_modulation_enable(dev, p->modulation);
+	o->modulation = p->modulation;
+
+	if (p->modulation) {
+		p->carrier_freq = txclk_tx_s_carrier(dev, p->carrier_freq,
+						     &txclk_divider);
+		o->carrier_freq = p->carrier_freq;
+
+		p->duty_cycle = cduty_tx_s_duty_cycle(dev, p->duty_cycle);
+		o->duty_cycle = p->duty_cycle;
+	} else {
+		p->max_pulse_width =
+			    txclk_tx_s_max_pulse_width(dev, p->max_pulse_width,
+						       &txclk_divider);
+		o->max_pulse_width = p->max_pulse_width;
+	}
+	atomic_set(&state->txclk_divider, txclk_divider);
+
+	p->resolution = clock_divider_to_resolution(txclk_divider);
+	o->resolution = p->resolution;
+
+	/* FIXME - make this dependent on resolution for better performance */
+	control_tx_irq_watermark(dev, TX_FIFO_HALF_EMPTY);
+
+	control_tx_polarity_invert(dev, p->invert);
+	o->invert = p->invert;
+
+	o->interrupt_enable = p->interrupt_enable;
+	o->enable = p->enable;
+	if (p->enable) {
+		kfifo_reset(state->tx_kfifo);
+		if (p->interrupt_enable)
+			irqenable_tx(dev, IRQEN_TSE);
+		control_tx_enable(dev, p->enable);
+	}
+
+	mutex_unlock(&state->tx_params_lock);
+	return 0;
+}
+
+
+/*
+ * V4L2 Subdevice Core Ops
+ */
+static int cx23888_ir_log_status(struct v4l2_subdev *sd)
+{
+	struct cx23888_ir_state *state = to_state(sd);
+	struct cx23885_dev *dev = state->dev;
+	char *s;
+	int i, j;
+
+	u32 cntrl = cx23888_ir_read4(dev, CX23888_IR_CNTRL_REG);
+	u32 txclk = cx23888_ir_read4(dev, CX23888_IR_TXCLK_REG) & TXCLK_TCD;
+	u32 rxclk = cx23888_ir_read4(dev, CX23888_IR_RXCLK_REG) & RXCLK_RCD;
+	u32 cduty = cx23888_ir_read4(dev, CX23888_IR_CDUTY_REG) & CDUTY_CDC;
+	u32 stats = cx23888_ir_read4(dev, CX23888_IR_STATS_REG);
+	u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG);
+	u32 filtr = cx23888_ir_read4(dev, CX23888_IR_FILTR_REG) & FILTR_LPF;
+
+	v4l2_info(sd, "IR Receiver:\n");
+	v4l2_info(sd, "\tEnabled:                           %s\n",
+		  cntrl & CNTRL_RXE ? "yes" : "no");
+	v4l2_info(sd, "\tDemodulation from a carrier:       %s\n",
+		  cntrl & CNTRL_DMD ? "enabled" : "disabled");
+	v4l2_info(sd, "\tFIFO:                              %s\n",
+		  cntrl & CNTRL_RFE ? "enabled" : "disabled");
+	switch (cntrl & CNTRL_EDG) {
+	case CNTRL_EDG_NONE:
+		s = "disabled";
+		break;
+	case CNTRL_EDG_FALL:
+		s = "falling edge";
+		break;
+	case CNTRL_EDG_RISE:
+		s = "rising edge";
+		break;
+	case CNTRL_EDG_BOTH:
+		s = "rising & falling edges";
+		break;
+	default:
+		s = "??? edge";
+		break;
+	}
+	v4l2_info(sd, "\tPulse timers' start/stop trigger:  %s\n", s);
+	v4l2_info(sd, "\tFIFO data on pulse timer overflow: %s\n",
+		  cntrl & CNTRL_R ? "not loaded" : "overflow marker");
+	v4l2_info(sd, "\tFIFO interrupt watermark:          %s\n",
+		  cntrl & CNTRL_RIC ? "not empty" : "half full or greater");
+	v4l2_info(sd, "\tLoopback mode:                     %s\n",
+		  cntrl & CNTRL_LBM ? "loopback active" : "normal receive");
+	if (cntrl & CNTRL_DMD) {
+		v4l2_info(sd, "\tExpected carrier (16 clocks):      %u Hz\n",
+			  clock_divider_to_carrier_freq(rxclk));
+		switch (cntrl & CNTRL_WIN) {
+		case CNTRL_WIN_3_3:
+			i = 3;
+			j = 3;
+			break;
+		case CNTRL_WIN_4_3:
+			i = 4;
+			j = 3;
+			break;
+		case CNTRL_WIN_3_4:
+			i = 3;
+			j = 4;
+			break;
+		case CNTRL_WIN_4_4:
+			i = 4;
+			j = 4;
+			break;
+		default:
+			i = 0;
+			j = 0;
+			break;
+		}
+		v4l2_info(sd, "\tNext carrier edge window:          16 clocks "
+			  "-%1d/+%1d, %u to %u Hz\n", i, j,
+			  clock_divider_to_freq(rxclk, 16 + j),
+			  clock_divider_to_freq(rxclk, 16 - i));
+	} else {
+		v4l2_info(sd, "\tMax measurable pulse width:        %u us, "
+			  "%llu ns\n",
+			  pulse_width_count_to_us(FIFO_RXTX, rxclk),
+			  pulse_width_count_to_ns(FIFO_RXTX, rxclk));
+	}
+	v4l2_info(sd, "\tLow pass filter:                   %s\n",
+		  filtr ? "enabled" : "disabled");
+	if (filtr)
+		v4l2_info(sd, "\tMin acceptable pulse width (LPF):  %u us, "
+			  "%u ns\n",
+			  lpf_count_to_us(filtr),
+			  lpf_count_to_ns(filtr));
+	v4l2_info(sd, "\tPulse width timer timed-out:       %s\n",
+		  stats & STATS_RTO ? "yes" : "no");
+	v4l2_info(sd, "\tPulse width timer time-out intr:   %s\n",
+		  irqen & IRQEN_RTE ? "enabled" : "disabled");
+	v4l2_info(sd, "\tFIFO overrun:                      %s\n",
+		  stats & STATS_ROR ? "yes" : "no");
+	v4l2_info(sd, "\tFIFO overrun interrupt:            %s\n",
+		  irqen & IRQEN_ROE ? "enabled" : "disabled");
+	v4l2_info(sd, "\tBusy:                              %s\n",
+		  stats & STATS_RBY ? "yes" : "no");
+	v4l2_info(sd, "\tFIFO service requested:            %s\n",
+		  stats & STATS_RSR ? "yes" : "no");
+	v4l2_info(sd, "\tFIFO service request interrupt:    %s\n",
+		  irqen & IRQEN_RSE ? "enabled" : "disabled");
+
+	v4l2_info(sd, "IR Transmitter:\n");
+	v4l2_info(sd, "\tEnabled:                           %s\n",
+		  cntrl & CNTRL_TXE ? "yes" : "no");
+	v4l2_info(sd, "\tModulation onto a carrier:         %s\n",
+		  cntrl & CNTRL_MOD ? "enabled" : "disabled");
+	v4l2_info(sd, "\tFIFO:                              %s\n",
+		  cntrl & CNTRL_TFE ? "enabled" : "disabled");
+	v4l2_info(sd, "\tFIFO interrupt watermark:          %s\n",
+		  cntrl & CNTRL_TIC ? "not empty" : "half full or less");
+	v4l2_info(sd, "\tSignal polarity:                   %s\n",
+		  cntrl & CNTRL_CPL ? "0:mark 1:space" : "0:space 1:mark");
+	if (cntrl & CNTRL_MOD) {
+		v4l2_info(sd, "\tCarrier (16 clocks):               %u Hz\n",
+			  clock_divider_to_carrier_freq(txclk));
+		v4l2_info(sd, "\tCarrier duty cycle:                %2u/16\n",
+			  cduty + 1);
+	} else {
+		v4l2_info(sd, "\tMax pulse width:                   %u us, "
+			  "%llu ns\n",
+			  pulse_width_count_to_us(FIFO_RXTX, txclk),
+			  pulse_width_count_to_ns(FIFO_RXTX, txclk));
+	}
+	v4l2_info(sd, "\tBusy:                              %s\n",
+		  stats & STATS_TBY ? "yes" : "no");
+	v4l2_info(sd, "\tFIFO service requested:            %s\n",
+		  stats & STATS_TSR ? "yes" : "no");
+	v4l2_info(sd, "\tFIFO service request interrupt:    %s\n",
+		  irqen & IRQEN_TSE ? "enabled" : "disabled");
+
+	return 0;
+}
+
+static inline int cx23888_ir_dbg_match(const struct v4l2_dbg_match *match)
+{
+	return match->type == V4L2_CHIP_MATCH_HOST && match->addr == 2;
+}
+
+static int cx23888_ir_g_chip_ident(struct v4l2_subdev *sd,
+				   struct v4l2_dbg_chip_ident *chip)
+{
+	struct cx23888_ir_state *state = to_state(sd);
+
+	if (cx23888_ir_dbg_match(&chip->match)) {
+		chip->ident = state->id;
+		chip->revision = state->rev;
+	}
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int cx23888_ir_g_register(struct v4l2_subdev *sd,
+				 struct v4l2_dbg_register *reg)
+{
+	struct cx23888_ir_state *state = to_state(sd);
+	u32 addr = CX23888_IR_REG_BASE + (u32) reg->reg;
+
+	if (!cx23888_ir_dbg_match(&reg->match))
+		return -EINVAL;
+	if ((addr & 0x3) != 0)
+		return -EINVAL;
+	if (addr < CX23888_IR_CNTRL_REG || addr > CX23888_IR_LEARN_REG)
+		return -EINVAL;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+	reg->size = 4;
+	reg->val = cx23888_ir_read4(state->dev, addr);
+	return 0;
+}
+
+static int cx23888_ir_s_register(struct v4l2_subdev *sd,
+				 struct v4l2_dbg_register *reg)
+{
+	struct cx23888_ir_state *state = to_state(sd);
+	u32 addr = CX23888_IR_REG_BASE + (u32) reg->reg;
+
+	if (!cx23888_ir_dbg_match(&reg->match))
+		return -EINVAL;
+	if ((addr & 0x3) != 0)
+		return -EINVAL;
+	if (addr < CX23888_IR_CNTRL_REG || addr > CX23888_IR_LEARN_REG)
+		return -EINVAL;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+	cx23888_ir_write4(state->dev, addr, reg->val);
+	return 0;
+}
+#endif
+
+static const struct v4l2_subdev_core_ops cx23888_ir_core_ops = {
+	.g_chip_ident = cx23888_ir_g_chip_ident,
+	.log_status = cx23888_ir_log_status,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.g_register = cx23888_ir_g_register,
+	.s_register = cx23888_ir_s_register,
+#endif
+};
+
+static const struct v4l2_subdev_ir_ops cx23888_ir_ir_ops = {
+	.interrupt_service_routine = cx23888_ir_irq_handler,
+
+	.rx_read = cx23888_ir_rx_read,
+	.rx_g_parameters = cx23888_ir_rx_g_parameters,
+	.rx_s_parameters = cx23888_ir_rx_s_parameters,
+
+	.tx_write = cx23888_ir_tx_write,
+	.tx_g_parameters = cx23888_ir_tx_g_parameters,
+	.tx_s_parameters = cx23888_ir_tx_s_parameters,
+};
+
+static const struct v4l2_subdev_ops cx23888_ir_controller_ops = {
+	.core = &cx23888_ir_core_ops,
+	.ir = &cx23888_ir_ir_ops,
+};
+
+static const struct v4l2_subdev_ir_parameters default_rx_params = {
+	.bytes_per_data_element = sizeof(u32),
+	.mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH,
+
+	.enable = false,
+	.interrupt_enable = false,
+	.shutdown = true,
+
+	.modulation = true,
+	.carrier_freq = 36000, /* 36 kHz - RC-5, RC-6, and RC-6A carrier */
+
+	/* RC-5:    666,667 ns = 1/36 kHz * 32 cycles * 1 mark * 0.75 */
+	/* RC-6A:   333,333 ns = 1/36 kHz * 16 cycles * 1 mark * 0.75 */
+	.noise_filter_min_width = 333333, /* ns */
+	.carrier_range_lower = 35000,
+	.carrier_range_upper = 37000,
+	.invert = false,
+};
+
+static const struct v4l2_subdev_ir_parameters default_tx_params = {
+	.bytes_per_data_element = sizeof(u32),
+	.mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH,
+
+	.enable = false,
+	.interrupt_enable = false,
+	.shutdown = true,
+
+	.modulation = true,
+	.carrier_freq = 36000, /* 36 kHz - RC-5 carrier */
+	.duty_cycle = 25,      /* 25 %   - RC-5 carrier */
+	.invert = false,
+};
+
+int cx23888_ir_probe(struct cx23885_dev *dev)
+{
+	struct cx23888_ir_state *state;
+	struct v4l2_subdev *sd;
+	struct v4l2_subdev_ir_parameters default_params;
+	int ret;
+
+	state = kzalloc(sizeof(struct cx23888_ir_state), GFP_KERNEL);
+	if (state == NULL)
+		return -ENOMEM;
+
+	spin_lock_init(&state->rx_kfifo_lock);
+	state->rx_kfifo = kfifo_alloc(CX23888_IR_RX_KFIFO_SIZE, GFP_KERNEL,
+				      &state->rx_kfifo_lock);
+	if (state->rx_kfifo == NULL)
+		return -ENOMEM;
+
+	spin_lock_init(&state->tx_kfifo_lock);
+	state->tx_kfifo = kfifo_alloc(CX23888_IR_TX_KFIFO_SIZE, GFP_KERNEL,
+				      &state->tx_kfifo_lock);
+	if (state->tx_kfifo == NULL) {
+		kfifo_free(state->rx_kfifo);
+		return -ENOMEM;
+	}
+
+	state->dev = dev;
+	state->id = V4L2_IDENT_CX23888_IR;
+	state->rev = 0;
+	sd = &state->sd;
+
+	v4l2_subdev_init(sd, &cx23888_ir_controller_ops);
+	v4l2_set_subdevdata(sd, state);
+	/* FIXME - fix the formatting of dev->v4l2_dev.name and use it */
+	snprintf(sd->name, sizeof(sd->name), "%s/888-ir", dev->name);
+	sd->grp_id = CX23885_HW_888_IR;
+
+	ret = v4l2_device_register_subdev(&dev->v4l2_dev, sd);
+	if (ret == 0) {
+		/*
+		 * Ensure no interrupts arrive from '888 specific conditions,
+		 * since we ignore them in this driver to have commonality with
+		 * similar IR controller cores.
+		 */
+		cx23888_ir_write4(dev, CX23888_IR_IRQEN_REG, 0);
+
+		mutex_init(&state->rx_params_lock);
+		memcpy(&default_params, &default_rx_params,
+		       sizeof(struct v4l2_subdev_ir_parameters));
+		v4l2_subdev_call(sd, ir, rx_s_parameters, &default_params);
+
+		mutex_init(&state->tx_params_lock);
+		memcpy(&default_params, &default_tx_params,
+		       sizeof(struct v4l2_subdev_ir_parameters));
+		v4l2_subdev_call(sd, ir, tx_s_parameters, &default_params);
+	} else {
+		kfifo_free(state->rx_kfifo);
+		kfifo_free(state->tx_kfifo);
+	}
+	return ret;
+}
+
+int cx23888_ir_remove(struct cx23885_dev *dev)
+{
+	struct v4l2_subdev *sd;
+	struct cx23888_ir_state *state;
+
+	sd = cx23885_find_hw(dev, CX23885_HW_888_IR);
+	if (sd == NULL)
+		return -ENODEV;
+
+	cx23888_ir_rx_shutdown(sd);
+	cx23888_ir_tx_shutdown(sd);
+
+	state = to_state(sd);
+	v4l2_device_unregister_subdev(sd);
+	kfifo_free(state->rx_kfifo);
+	kfifo_free(state->tx_kfifo);
+	kfree(state);
+	/* Nothing more to free() as state held the actual v4l2_subdev object */
+	return 0;
+}
diff --git a/drivers/media/video/cx23885/cx23888-ir.h b/drivers/media/video/cx23885/cx23888-ir.h
new file mode 100644
index 0000000..3d446f9
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23888-ir.h
@@ -0,0 +1,28 @@
+/*
+ *  Driver for the Conexant CX23885/7/8 PCIe bridge
+ *
+ *  CX23888 Integrated Consumer Infrared Controller
+ *
+ *  Copyright (C) 2009  Andy Walls <awalls@radix.net>
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA
+ *  02110-1301, USA.
+ */
+
+#ifndef _CX23888_IR_H_
+#define _CX23888_IR_H_
+int cx23888_ir_probe(struct cx23885_dev *dev);
+int cx23888_ir_remove(struct cx23885_dev *dev);
+#endif
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c
index 2f846f5e..45608d50 100644
--- a/drivers/media/video/cx25840/cx25840-audio.c
+++ b/drivers/media/video/cx25840/cx25840-audio.c
@@ -23,87 +23,137 @@
 
 #include "cx25840-core.h"
 
-static int set_audclk_freq(struct i2c_client *client, u32 freq)
+/*
+ * Note: The PLL and SRC parameters are based on a reference frequency that
+ * would ideally be:
+ *
+ * NTSC Color subcarrier freq * 8 = 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
+ *
+ * However, it's not the exact reference frequency that matters, only that the
+ * firmware and modules that comprise the driver for a particular board all
+ * use the same value (close to the ideal value).
+ *
+ * Comments below will note which reference frequency is assumed for various
+ * parameters.  They will usually be one of
+ *
+ *	ref_freq = 28.636360 MHz
+ *		or
+ *	ref_freq = 28.636363 MHz
+ */
+
+static int cx25840_set_audclk_freq(struct i2c_client *client, u32 freq)
 {
 	struct cx25840_state *state = to_state(i2c_get_clientdata(client));
 
-	if (freq != 32000 && freq != 44100 && freq != 48000)
-		return -EINVAL;
-
-	/* common for all inputs and rates */
-	/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
-	if (!state->is_cx23885 && !state->is_cx231xx)
-		cx25840_write(client, 0x127, 0x50);
-
 	if (state->aud_input != CX25840_AUDIO_SERIAL) {
 		switch (freq) {
 		case 32000:
-			if (state->is_cx23885) {
-				/* We don't have register values
-				 * so avoid destroying registers. */
-				break;
-			}
+			/*
+			 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
+			 * AUX_PLL Integer = 0x06, AUX PLL Post Divider = 0x10
+			 */
+			cx25840_write4(client, 0x108, 0x1006040f);
 
-			if (!state->is_cx231xx) {
-				/* VID_PLL and AUX_PLL */
-				cx25840_write4(client, 0x108, 0x1006040f);
+			/*
+			 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
+			 * 28636360 * 0xf.15f17f0/4 = 108 MHz
+			 * 432 MHz pre-postdivide
+			 */
 
-				/* AUX_PLL_FRAC */
-				cx25840_write4(client, 0x110, 0x01bb39ee);
-			}
+			/*
+			 * AUX_PLL Fraction = 0x1bb39ee
+			 * 28636363 * 0x6.dd9cf70/0x10 = 32000 * 384
+			 * 196.6 MHz pre-postdivide
+			 * FIXME < 200 MHz is out of specified valid range
+			 * FIXME 28636363 ref_freq doesn't match VID PLL ref
+			 */
+			cx25840_write4(client, 0x110, 0x01bb39ee);
 
-			if (state->is_cx25836)
+			/*
+			 * SA_MCLK_SEL = 1
+			 * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider
+			 */
+			cx25840_write(client, 0x127, 0x50);
+
+			if (is_cx2583x(state))
 				break;
 
-			/* src3/4/6_ctl = 0x0801f77f */
+			/* src3/4/6_ctl */
+			/* 0x1.f77f = (4 * 28636360/8 * 2/455) / 32000 */
 			cx25840_write4(client, 0x900, 0x0801f77f);
 			cx25840_write4(client, 0x904, 0x0801f77f);
 			cx25840_write4(client, 0x90c, 0x0801f77f);
 			break;
 
 		case 44100:
-			if (state->is_cx23885) {
-				/* We don't have register values
-				 * so avoid destroying registers. */
-				break;
-			}
+			/*
+			 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
+			 * AUX_PLL Integer = 0x09, AUX PLL Post Divider = 0x10
+			 */
+			cx25840_write4(client, 0x108, 0x1009040f);
 
-			if (!state->is_cx231xx) {
-				/* VID_PLL and AUX_PLL */
-				cx25840_write4(client, 0x108, 0x1009040f);
+			/*
+			 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
+			 * 28636360 * 0xf.15f17f0/4 = 108 MHz
+			 * 432 MHz pre-postdivide
+			 */
 
-				/* AUX_PLL_FRAC */
-				cx25840_write4(client, 0x110, 0x00ec6bd6);
-			}
+			/*
+			 * AUX_PLL Fraction = 0x0ec6bd6
+			 * 28636363 * 0x9.7635eb0/0x10 = 44100 * 384
+			 * 271 MHz pre-postdivide
+			 * FIXME 28636363 ref_freq doesn't match VID PLL ref
+			 */
+			cx25840_write4(client, 0x110, 0x00ec6bd6);
 
-			if (state->is_cx25836)
+			/*
+			 * SA_MCLK_SEL = 1
+			 * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider
+			 */
+			cx25840_write(client, 0x127, 0x50);
+
+			if (is_cx2583x(state))
 				break;
 
-			/* src3/4/6_ctl = 0x08016d59 */
+			/* src3/4/6_ctl */
+			/* 0x1.6d59 = (4 * 28636360/8 * 2/455) / 44100 */
 			cx25840_write4(client, 0x900, 0x08016d59);
 			cx25840_write4(client, 0x904, 0x08016d59);
 			cx25840_write4(client, 0x90c, 0x08016d59);
 			break;
 
 		case 48000:
-			if (state->is_cx23885) {
-				/* We don't have register values
-				 * so avoid destroying registers. */
-				break;
-			}
+			/*
+			 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
+			 * AUX_PLL Integer = 0x0a, AUX PLL Post Divider = 0x10
+			 */
+			cx25840_write4(client, 0x108, 0x100a040f);
 
-			if (!state->is_cx231xx) {
-				/* VID_PLL and AUX_PLL */
-				cx25840_write4(client, 0x108, 0x100a040f);
+			/*
+			 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
+			 * 28636360 * 0xf.15f17f0/4 = 108 MHz
+			 * 432 MHz pre-postdivide
+			 */
 
-				/* AUX_PLL_FRAC */
-				cx25840_write4(client, 0x110, 0x0098d6e5);
-			}
+			/*
+			 * AUX_PLL Fraction = 0x098d6e5
+			 * 28636363 * 0xa.4c6b728/0x10 = 48000 * 384
+			 * 295 MHz pre-postdivide
+			 * FIXME 28636363 ref_freq doesn't match VID PLL ref
+			 */
+			cx25840_write4(client, 0x110, 0x0098d6e5);
 
-			if (state->is_cx25836)
+			/*
+			 * SA_MCLK_SEL = 1
+			 * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider
+			 */
+			cx25840_write(client, 0x127, 0x50);
+
+			if (is_cx2583x(state))
 				break;
 
-			/* src3/4/6_ctl = 0x08014faa */
+			/* src3/4/6_ctl */
+			/* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
 			cx25840_write4(client, 0x900, 0x08014faa);
 			cx25840_write4(client, 0x904, 0x08014faa);
 			cx25840_write4(client, 0x90c, 0x08014faa);
@@ -112,91 +162,126 @@
 	} else {
 		switch (freq) {
 		case 32000:
-			if (state->is_cx23885) {
-				/* We don't have register values
-				 * so avoid destroying registers. */
-				break;
-			}
+			/*
+			 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
+			 * AUX_PLL Integer = 0x08, AUX PLL Post Divider = 0x1e
+			 */
+			cx25840_write4(client, 0x108, 0x1e08040f);
 
-			if (!state->is_cx231xx) {
-				/* VID_PLL and AUX_PLL */
-				cx25840_write4(client, 0x108, 0x1e08040f);
+			/*
+			 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
+			 * 28636360 * 0xf.15f17f0/4 = 108 MHz
+			 * 432 MHz pre-postdivide
+			 */
 
-				/* AUX_PLL_FRAC */
-				cx25840_write4(client, 0x110, 0x012a0869);
-			}
+			/*
+			 * AUX_PLL Fraction = 0x12a0869
+			 * 28636363 * 0x8.9504348/0x1e = 32000 * 256
+			 * 246 MHz pre-postdivide
+			 * FIXME 28636363 ref_freq doesn't match VID PLL ref
+			 */
+			cx25840_write4(client, 0x110, 0x012a0869);
 
-			if (state->is_cx25836)
+			/*
+			 * SA_MCLK_SEL = 1
+			 * SA_MCLK_DIV = 0x14 = 256/384 * AUX_PLL post dvivider
+			 */
+			cx25840_write(client, 0x127, 0x54);
+
+			if (is_cx2583x(state))
 				break;
 
-			/* src1_ctl = 0x08010000 */
+			/* src1_ctl */
+			/* 0x1.0000 = 32000/32000 */
 			cx25840_write4(client, 0x8f8, 0x08010000);
 
-			/* src3/4/6_ctl = 0x08020000 */
+			/* src3/4/6_ctl */
+			/* 0x2.0000 = 2 * (32000/32000) */
 			cx25840_write4(client, 0x900, 0x08020000);
 			cx25840_write4(client, 0x904, 0x08020000);
 			cx25840_write4(client, 0x90c, 0x08020000);
-
-			/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */
-			cx25840_write(client, 0x127, 0x54);
 			break;
 
 		case 44100:
-			if (state->is_cx23885) {
-				/* We don't have register values
-				 * so avoid destroying registers. */
-				break;
-			}
+			/*
+			 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
+			 * AUX_PLL Integer = 0x09, AUX PLL Post Divider = 0x18
+			 */
+			cx25840_write4(client, 0x108, 0x1809040f);
 
+			/*
+			 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
+			 * 28636360 * 0xf.15f17f0/4 = 108 MHz
+			 * 432 MHz pre-postdivide
+			 */
 
-			if (!state->is_cx231xx) {
-				/* VID_PLL and AUX_PLL */
-				cx25840_write4(client, 0x108, 0x1809040f);
+			/*
+			 * AUX_PLL Fraction = 0x0ec6bd6
+			 * 28636363 * 0x9.7635eb0/0x18 = 44100 * 256
+			 * 271 MHz pre-postdivide
+			 * FIXME 28636363 ref_freq doesn't match VID PLL ref
+			 */
+			cx25840_write4(client, 0x110, 0x00ec6bd6);
 
-				/* AUX_PLL_FRAC */
-				cx25840_write4(client, 0x110, 0x00ec6bd6);
-			}
+			/*
+			 * SA_MCLK_SEL = 1
+			 * SA_MCLK_DIV = 0x10 = 256/384 * AUX_PLL post dvivider
+			 */
+			cx25840_write(client, 0x127, 0x50);
 
-			if (state->is_cx25836)
+			if (is_cx2583x(state))
 				break;
 
-			/* src1_ctl = 0x08010000 */
+			/* src1_ctl */
+			/* 0x1.60cd = 44100/32000 */
 			cx25840_write4(client, 0x8f8, 0x080160cd);
 
-			/* src3/4/6_ctl = 0x08020000 */
+			/* src3/4/6_ctl */
+			/* 0x1.7385 = 2 * (32000/44100) */
 			cx25840_write4(client, 0x900, 0x08017385);
 			cx25840_write4(client, 0x904, 0x08017385);
 			cx25840_write4(client, 0x90c, 0x08017385);
 			break;
 
 		case 48000:
-			if (!state->is_cx23885 && !state->is_cx231xx) {
-				/* VID_PLL and AUX_PLL */
-				cx25840_write4(client, 0x108, 0x180a040f);
+			/*
+			 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
+			 * AUX_PLL Integer = 0x0a, AUX PLL Post Divider = 0x18
+			 */
+			cx25840_write4(client, 0x108, 0x180a040f);
 
-				/* AUX_PLL_FRAC */
-				cx25840_write4(client, 0x110, 0x0098d6e5);
-			}
+			/*
+			 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
+			 * 28636360 * 0xf.15f17f0/4 = 108 MHz
+			 * 432 MHz pre-postdivide
+			 */
 
-			if (state->is_cx25836)
+			/*
+			 * AUX_PLL Fraction = 0x098d6e5
+			 * 28636363 * 0xa.4c6b728/0x18 = 48000 * 256
+			 * 295 MHz pre-postdivide
+			 * FIXME 28636363 ref_freq doesn't match VID PLL ref
+			 */
+			cx25840_write4(client, 0x110, 0x0098d6e5);
+
+			/*
+			 * SA_MCLK_SEL = 1
+			 * SA_MCLK_DIV = 0x10 = 256/384 * AUX_PLL post dvivider
+			 */
+			cx25840_write(client, 0x127, 0x50);
+
+			if (is_cx2583x(state))
 				break;
 
-			if (!state->is_cx23885 && !state->is_cx231xx) {
-				/* src1_ctl */
-				cx25840_write4(client, 0x8f8, 0x08018000);
+			/* src1_ctl */
+			/* 0x1.8000 = 48000/32000 */
+			cx25840_write4(client, 0x8f8, 0x08018000);
 
-				/* src3/4/6_ctl */
-				cx25840_write4(client, 0x900, 0x08015555);
-				cx25840_write4(client, 0x904, 0x08015555);
-				cx25840_write4(client, 0x90c, 0x08015555);
-			} else {
-
-				cx25840_write4(client, 0x8f8, 0x0801867c);
-
-				cx25840_write4(client, 0x900, 0x08014faa);
-				cx25840_write4(client, 0x904, 0x08014faa);
-				cx25840_write4(client, 0x90c, 0x08014faa);
-			}
+			/* src3/4/6_ctl */
+			/* 0x1.5555 = 2 * (32000/48000) */
+			cx25840_write4(client, 0x900, 0x08015555);
+			cx25840_write4(client, 0x904, 0x08015555);
+			cx25840_write4(client, 0x90c, 0x08015555);
 			break;
 		}
 	}
@@ -206,6 +291,148 @@
 	return 0;
 }
 
+static inline int cx25836_set_audclk_freq(struct i2c_client *client, u32 freq)
+{
+	return cx25840_set_audclk_freq(client, freq);
+}
+
+static int cx23885_set_audclk_freq(struct i2c_client *client, u32 freq)
+{
+	struct cx25840_state *state = to_state(i2c_get_clientdata(client));
+
+	if (state->aud_input != CX25840_AUDIO_SERIAL) {
+		switch (freq) {
+		case 32000:
+		case 44100:
+		case 48000:
+			/* We don't have register values
+			 * so avoid destroying registers. */
+			/* FIXME return -EINVAL; */
+			break;
+		}
+	} else {
+		switch (freq) {
+		case 32000:
+		case 44100:
+			/* We don't have register values
+			 * so avoid destroying registers. */
+			/* FIXME return -EINVAL; */
+			break;
+
+		case 48000:
+			/* src1_ctl */
+			/* 0x1.867c = 48000 / (2 * 28636360/8 * 2/455) */
+			cx25840_write4(client, 0x8f8, 0x0801867c);
+
+			/* src3/4/6_ctl */
+			/* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
+			cx25840_write4(client, 0x900, 0x08014faa);
+			cx25840_write4(client, 0x904, 0x08014faa);
+			cx25840_write4(client, 0x90c, 0x08014faa);
+			break;
+		}
+	}
+
+	state->audclk_freq = freq;
+
+	return 0;
+}
+
+static int cx231xx_set_audclk_freq(struct i2c_client *client, u32 freq)
+{
+	struct cx25840_state *state = to_state(i2c_get_clientdata(client));
+
+	if (state->aud_input != CX25840_AUDIO_SERIAL) {
+		switch (freq) {
+		case 32000:
+			/* src3/4/6_ctl */
+			/* 0x1.f77f = (4 * 28636360/8 * 2/455) / 32000 */
+			cx25840_write4(client, 0x900, 0x0801f77f);
+			cx25840_write4(client, 0x904, 0x0801f77f);
+			cx25840_write4(client, 0x90c, 0x0801f77f);
+			break;
+
+		case 44100:
+			/* src3/4/6_ctl */
+			/* 0x1.6d59 = (4 * 28636360/8 * 2/455) / 44100 */
+			cx25840_write4(client, 0x900, 0x08016d59);
+			cx25840_write4(client, 0x904, 0x08016d59);
+			cx25840_write4(client, 0x90c, 0x08016d59);
+			break;
+
+		case 48000:
+			/* src3/4/6_ctl */
+			/* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
+			cx25840_write4(client, 0x900, 0x08014faa);
+			cx25840_write4(client, 0x904, 0x08014faa);
+			cx25840_write4(client, 0x90c, 0x08014faa);
+			break;
+		}
+	} else {
+		switch (freq) {
+		/* FIXME These cases make different assumptions about audclk */
+		case 32000:
+			/* src1_ctl */
+			/* 0x1.0000 = 32000/32000 */
+			cx25840_write4(client, 0x8f8, 0x08010000);
+
+			/* src3/4/6_ctl */
+			/* 0x2.0000 = 2 * (32000/32000) */
+			cx25840_write4(client, 0x900, 0x08020000);
+			cx25840_write4(client, 0x904, 0x08020000);
+			cx25840_write4(client, 0x90c, 0x08020000);
+			break;
+
+		case 44100:
+			/* src1_ctl */
+			/* 0x1.60cd = 44100/32000 */
+			cx25840_write4(client, 0x8f8, 0x080160cd);
+
+			/* src3/4/6_ctl */
+			/* 0x1.7385 = 2 * (32000/44100) */
+			cx25840_write4(client, 0x900, 0x08017385);
+			cx25840_write4(client, 0x904, 0x08017385);
+			cx25840_write4(client, 0x90c, 0x08017385);
+			break;
+
+		case 48000:
+			/* src1_ctl */
+			/* 0x1.867c = 48000 / (2 * 28636360/8 * 2/455) */
+			cx25840_write4(client, 0x8f8, 0x0801867c);
+
+			/* src3/4/6_ctl */
+			/* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
+			cx25840_write4(client, 0x900, 0x08014faa);
+			cx25840_write4(client, 0x904, 0x08014faa);
+			cx25840_write4(client, 0x90c, 0x08014faa);
+			break;
+		}
+	}
+
+	state->audclk_freq = freq;
+
+	return 0;
+}
+
+static int set_audclk_freq(struct i2c_client *client, u32 freq)
+{
+	struct cx25840_state *state = to_state(i2c_get_clientdata(client));
+
+	if (freq != 32000 && freq != 44100 && freq != 48000)
+		return -EINVAL;
+
+	if (is_cx231xx(state))
+		return cx231xx_set_audclk_freq(client, freq);
+
+	if (is_cx2388x(state))
+		return cx23885_set_audclk_freq(client, freq);
+
+	if (is_cx2583x(state))
+		return cx25836_set_audclk_freq(client, freq);
+
+	return cx25840_set_audclk_freq(client, freq);
+}
+
 void cx25840_audio_set_path(struct i2c_client *client)
 {
 	struct cx25840_state *state = to_state(i2c_get_clientdata(client));
@@ -243,7 +470,7 @@
 	cx25840_and_or(client, 0x810, ~0x1, 0x00);
 
 	/* Ensure the controller is running when we exit */
-	if (state->is_cx23885 || state->is_cx231xx)
+	if (is_cx2388x(state) || is_cx231xx(state))
 		cx25840_and_or(client, 0x803, ~0x10, 0x10);
 }
 
@@ -383,7 +610,7 @@
 	struct cx25840_state *state = to_state(sd);
 	int retval;
 
-	if (!state->is_cx25836)
+	if (!is_cx2583x(state))
 		cx25840_and_or(client, 0x810, ~0x1, 1);
 	if (state->aud_input != CX25840_AUDIO_SERIAL) {
 		cx25840_and_or(client, 0x803, ~0x10, 0);
@@ -392,7 +619,7 @@
 	retval = set_audclk_freq(client, freq);
 	if (state->aud_input != CX25840_AUDIO_SERIAL)
 		cx25840_and_or(client, 0x803, ~0x10, 0x10);
-	if (!state->is_cx25836)
+	if (!is_cx2583x(state))
 		cx25840_and_or(client, 0x810, ~0x1, 0);
 	return retval;
 }
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 1aeaf18..385ecd5 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -259,6 +259,13 @@
 	struct cx25840_state *state = to_state(i2c_get_clientdata(client));
 	struct workqueue_struct *q;
 
+	/*
+	 * Come out of digital power down
+	 * The CX23888, at least, needs this, otherwise registers aside from
+	 * 0x0-0x2 can't be read or written.
+	 */
+	cx25840_write(client, 0x000, 0);
+
 	/* Internal Reset */
 	cx25840_and_or(client, 0x102, ~0x01, 0x01);
 	cx25840_and_or(client, 0x102, ~0x01, 0x00);
@@ -269,18 +276,45 @@
 	/* DIF in reset? */
 	cx25840_write(client, 0x398, 0);
 
-	/* Trust the default xtal, no division */
-	/* This changes for the cx23888 products */
+	/*
+	 * Trust the default xtal, no division
+	 * '885: 28.636363... MHz
+	 * '887: 25.000000 MHz
+	 * '888: 50.000000 MHz
+	 */
 	cx25840_write(client, 0x2, 0x76);
 
-	/* Bring down the regulator for AUX clk */
+	/* Power up all the PLL's and DLL */
 	cx25840_write(client, 0x1, 0x40);
 
-	/* Sys PLL frac */
-	cx25840_write4(client, 0x11c, 0x01d1744c);
-
-	/* Sys PLL int */
-	cx25840_write4(client, 0x118, 0x00000416);
+	/* Sys PLL */
+	switch (state->id) {
+	case V4L2_IDENT_CX23888_AV:
+		/*
+		 * 50.0 MHz * (0xb + 0xe8ba26/0x2000000)/4 = 5 * 28.636363 MHz
+		 * 572.73 MHz before post divide
+		 */
+		cx25840_write4(client, 0x11c, 0x00e8ba26);
+		cx25840_write4(client, 0x118, 0x0000040b);
+		break;
+	case V4L2_IDENT_CX23887_AV:
+		/*
+		 * 25.0 MHz * (0x16 + 0x1d1744c/0x2000000)/4 = 5 * 28.636363 MHz
+		 * 572.73 MHz before post divide
+		 */
+		cx25840_write4(client, 0x11c, 0x01d1744c);
+		cx25840_write4(client, 0x118, 0x00000416);
+		break;
+	case V4L2_IDENT_CX23885_AV:
+	default:
+		/*
+		 * 28.636363 MHz * (0x14 + 0x0/0x2000000)/4 = 5 * 28.636363 MHz
+		 * 572.73 MHz before post divide
+		 */
+		cx25840_write4(client, 0x11c, 0x00000000);
+		cx25840_write4(client, 0x118, 0x00000414);
+		break;
+	}
 
 	/* Disable DIF bypass */
 	cx25840_write4(client, 0x33c, 0x00000001);
@@ -288,11 +322,15 @@
 	/* DIF Src phase inc */
 	cx25840_write4(client, 0x340, 0x0df7df83);
 
-	/* Vid PLL frac */
-	cx25840_write4(client, 0x10c, 0x01b6db7b);
-
-	/* Vid PLL int */
-	cx25840_write4(client, 0x108, 0x00000512);
+	/*
+	 * Vid PLL
+	 * Setup for a BT.656 pixel clock of 13.5 Mpixels/second
+	 *
+	 * 28.636363 MHz * (0xf + 0x02be2c9/0x2000000)/4 = 8 * 13.5 MHz
+	 * 432.0 MHz before post divide
+	 */
+	cx25840_write4(client, 0x10c, 0x002be2c9);
+	cx25840_write4(client, 0x108, 0x0000040f);
 
 	/* Luma */
 	cx25840_write4(client, 0x414, 0x00107d12);
@@ -300,11 +338,43 @@
 	/* Chroma */
 	cx25840_write4(client, 0x420, 0x3d008282);
 
-	/* Aux PLL frac */
-	cx25840_write4(client, 0x114, 0x017dbf48);
-
-	/* Aux PLL int */
-	cx25840_write4(client, 0x110, 0x000a030e);
+	/*
+	 * Aux PLL
+	 * Initial setup for audio sample clock:
+	 * 48 ksps, 16 bits/sample, x160 multiplier = 122.88 MHz
+	 * Intial I2S output/master clock(?):
+	 * 48 ksps, 16 bits/sample, x16 multiplier = 12.288 MHz
+	 */
+	switch (state->id) {
+	case V4L2_IDENT_CX23888_AV:
+		/*
+		 * 50.0 MHz * (0x7 + 0x0bedfa4/0x2000000)/3 = 122.88 MHz
+		 * 368.64 MHz before post divide
+		 * 122.88 MHz / 0xa = 12.288 MHz
+		 */
+		cx25840_write4(client, 0x114, 0x00bedfa4);
+		cx25840_write4(client, 0x110, 0x000a0307);
+		break;
+	case V4L2_IDENT_CX23887_AV:
+		/*
+		 * 25.0 MHz * (0xe + 0x17dbf48/0x2000000)/3 = 122.88 MHz
+		 * 368.64 MHz before post divide
+		 * 122.88 MHz / 0xa = 12.288 MHz
+		 */
+		cx25840_write4(client, 0x114, 0x017dbf48);
+		cx25840_write4(client, 0x110, 0x000a030e);
+		break;
+	case V4L2_IDENT_CX23885_AV:
+	default:
+		/*
+		 * 28.636363 MHz * (0xc + 0x1bf0c9e/0x2000000)/3 = 122.88 MHz
+		 * 368.64 MHz before post divide
+		 * 122.88 MHz / 0xa = 12.288 MHz
+		 */
+		cx25840_write4(client, 0x114, 0x01bf0c9e);
+		cx25840_write4(client, 0x110, 0x000a030c);
+		break;
+	};
 
 	/* ADC2 input select */
 	cx25840_write(client, 0x102, 0x10);
@@ -494,7 +564,7 @@
 	}
 
 	/* DEBUG: Displays configured PLL frequency */
-	if (!state->is_cx231xx) {
+	if (!is_cx231xx(state)) {
 		pll_int = cx25840_read(client, 0x108);
 		pll_frac = cx25840_read4(client, 0x10c) & 0x1ffffff;
 		pll_post = cx25840_read(client, 0x109);
@@ -615,13 +685,30 @@
 		}
 		cx25840_write(client, 0x80b, 0x00);
 	} else if (std & V4L2_STD_PAL) {
-		/* Follow tuner change procedure for PAL */
+		/* Autodetect audio standard and audio system */
 		cx25840_write(client, 0x808, 0xff);
-		cx25840_write(client, 0x80b, 0x10);
+		/* Since system PAL-L is pretty much non-existant and
+		   not used by any public broadcast network, force
+		   6.5 MHz carrier to be interpreted as System DK,
+		   this avoids DK audio detection instability */
+	       cx25840_write(client, 0x80b, 0x00);
 	} else if (std & V4L2_STD_SECAM) {
-		/* Select autodetect for SECAM */
+		/* Autodetect audio standard and audio system */
 		cx25840_write(client, 0x808, 0xff);
-		cx25840_write(client, 0x80b, 0x10);
+		/* If only one of SECAM-DK / SECAM-L is required, then force
+		  6.5MHz carrier, else autodetect it */
+		if ((std & V4L2_STD_SECAM_DK) &&
+		    !(std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))) {
+			/* 6.5 MHz carrier to be interpreted as System DK */
+			cx25840_write(client, 0x80b, 0x00);
+	       } else if (!(std & V4L2_STD_SECAM_DK) &&
+			  (std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))) {
+			/* 6.5 MHz carrier to be interpreted as System L */
+			cx25840_write(client, 0x80b, 0x08);
+	       } else {
+			/* 6.5 MHz carrier to be autodetected */
+			cx25840_write(client, 0x80b, 0x10);
+	       }
 	}
 
 	cx25840_and_or(client, 0x810, ~0x01, 0);
@@ -633,6 +720,10 @@
 	struct cx25840_state *state = to_state(i2c_get_clientdata(client));
 	u8 is_composite = (vid_input >= CX25840_COMPOSITE1 &&
 			   vid_input <= CX25840_COMPOSITE8);
+	u8 is_component = (vid_input & CX25840_COMPONENT_ON) ==
+			CX25840_COMPONENT_ON;
+	int luma = vid_input & 0xf0;
+	int chroma = vid_input & 0xf00;
 	u8 reg;
 
 	v4l_dbg(1, cx25840_debug, client,
@@ -645,18 +736,14 @@
 		reg = vid_input & 0xff;
 		if ((vid_input & CX25840_SVIDEO_ON) == CX25840_SVIDEO_ON)
 			is_composite = 0;
-		else
+		else if ((vid_input & CX25840_COMPONENT_ON) == 0)
 			is_composite = 1;
 
 		v4l_dbg(1, cx25840_debug, client, "mux cfg 0x%x comp=%d\n",
 			reg, is_composite);
-	} else
-	if (is_composite) {
+	} else if (is_composite) {
 		reg = 0xf0 + (vid_input - CX25840_COMPOSITE1);
 	} else {
-		int luma = vid_input & 0xf0;
-		int chroma = vid_input & 0xf00;
-
 		if ((vid_input & ~0xff0) ||
 		    luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA8 ||
 		    chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) {
@@ -678,7 +765,7 @@
 	 * configuration in reg (for the cx23885) so we have no
 	 * need to attempt to flip bits for earlier av decoders.
 	 */
-	if (!state->is_cx23885 && !state->is_cx231xx) {
+	if (!is_cx2388x(state) && !is_cx231xx(state)) {
 		switch (aud_input) {
 		case CX25840_AUDIO_SERIAL:
 			/* do nothing, use serial audio input */
@@ -698,10 +785,13 @@
 
 	cx25840_write(client, 0x103, reg);
 
-	/* Set INPUT_MODE to Composite (0) or S-Video (1) */
-	cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02);
+	/* Set INPUT_MODE to Composite, S-Video or Component */
+	if (is_component)
+		cx25840_and_or(client, 0x401, ~0x6, 0x6);
+	else
+		cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02);
 
-	if (!state->is_cx23885 && !state->is_cx231xx) {
+	if (!is_cx2388x(state) && !is_cx231xx(state)) {
 		/* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
 		cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
 		/* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2&CH3 */
@@ -710,22 +800,31 @@
 		else
 			cx25840_and_or(client, 0x102, ~0x4, 0);
 	} else {
-		if (is_composite)
+		/* Set DUAL_MODE_ADC2 to 1 if component*/
+		cx25840_and_or(client, 0x102, ~0x4, is_component ? 0x4 : 0x0);
+		if (is_composite) {
 			/* ADC2 input select channel 2 */
 			cx25840_and_or(client, 0x102, ~0x2, 0);
-		else
-			/* ADC2 input select channel 3 */
-			cx25840_and_or(client, 0x102, ~0x2, 2);
+		} else if (!is_component) {
+			/* S-Video */
+			if (chroma >= CX25840_SVIDEO_CHROMA7) {
+				/* ADC2 input select channel 3 */
+				cx25840_and_or(client, 0x102, ~0x2, 2);
+			} else {
+				/* ADC2 input select channel 2 */
+				cx25840_and_or(client, 0x102, ~0x2, 0);
+			}
+		}
 	}
 
 	state->vid_input = vid_input;
 	state->aud_input = aud_input;
-	if (!state->is_cx25836) {
+	if (!is_cx2583x(state)) {
 		cx25840_audio_set_path(client);
 		input_change(client);
 	}
 
-	if (state->is_cx23885) {
+	if (is_cx2388x(state)) {
 		/* Audio channel 1 src : Parallel 1 */
 		cx25840_write(client, 0x124, 0x03);
 
@@ -741,7 +840,7 @@
 		 */
 		cx25840_write(client, 0x918, 0xa0);
 		cx25840_write(client, 0x919, 0x01);
-	} else if (state->is_cx231xx) {
+	} else if (is_cx231xx(state)) {
 		/* Audio channel 1 src : Parallel 1 */
 		cx25840_write(client, 0x124, 0x03);
 
@@ -805,7 +904,7 @@
 	cx25840_and_or(client, 0x400, ~0xf, fmt);
 	cx25840_and_or(client, 0x403, ~0x3, pal_m);
 	cx25840_std_setup(client);
-	if (!state->is_cx25836)
+	if (!is_cx2583x(state))
 		input_change(client);
 	return 0;
 }
@@ -868,7 +967,7 @@
 	case V4L2_CID_AUDIO_TREBLE:
 	case V4L2_CID_AUDIO_BALANCE:
 	case V4L2_CID_AUDIO_MUTE:
-		if (state->is_cx25836)
+		if (is_cx2583x(state))
 			return -EINVAL;
 		return cx25840_audio_s_ctrl(sd, ctrl);
 
@@ -905,7 +1004,7 @@
 	case V4L2_CID_AUDIO_TREBLE:
 	case V4L2_CID_AUDIO_BALANCE:
 	case V4L2_CID_AUDIO_MUTE:
-		if (state->is_cx25836)
+		if (is_cx2583x(state))
 			return -EINVAL;
 		return cx25840_audio_g_ctrl(sd, ctrl);
 	default:
@@ -1209,11 +1308,11 @@
 	if (!state->is_initialized) {
 		/* initialize and load firmware */
 		state->is_initialized = 1;
-		if (state->is_cx25836)
+		if (is_cx2583x(state))
 			cx25836_initialize(client);
-		else if (state->is_cx23885)
+		else if (is_cx2388x(state))
 			cx23885_initialize(client);
-		else if (state->is_cx231xx)
+		else if (is_cx231xx(state))
 			cx231xx_initialize(client);
 		else
 			cx25840_initialize(client);
@@ -1256,17 +1355,17 @@
 	v4l_dbg(1, cx25840_debug, client, "%s output\n",
 			enable ? "enable" : "disable");
 	if (enable) {
-		if (state->is_cx23885 || state->is_cx231xx) {
+		if (is_cx2388x(state) || is_cx231xx(state)) {
 			u8 v = (cx25840_read(client, 0x421) | 0x0b);
 			cx25840_write(client, 0x421, v);
 		} else {
 			cx25840_write(client, 0x115,
-					state->is_cx25836 ? 0x0c : 0x8c);
+					is_cx2583x(state) ? 0x0c : 0x8c);
 			cx25840_write(client, 0x116,
-					state->is_cx25836 ? 0x04 : 0x07);
+					is_cx2583x(state) ? 0x04 : 0x07);
 		}
 	} else {
-		if (state->is_cx23885 || state->is_cx231xx) {
+		if (is_cx2388x(state) || is_cx231xx(state)) {
 			u8 v = cx25840_read(client, 0x421) & ~(0x0b);
 			cx25840_write(client, 0x421, v);
 		} else {
@@ -1292,7 +1391,7 @@
 	default:
 		break;
 	}
-	if (state->is_cx25836)
+	if (is_cx2583x(state))
 		return -EINVAL;
 
 	switch (qc->id) {
@@ -1346,7 +1445,7 @@
 	struct cx25840_state *state = to_state(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (state->is_cx25836)
+	if (is_cx2583x(state))
 		return -EINVAL;
 	return set_input(client, state->vid_input, input);
 }
@@ -1356,7 +1455,7 @@
 	struct cx25840_state *state = to_state(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (!state->is_cx25836)
+	if (!is_cx2583x(state))
 		input_change(client);
 	return 0;
 }
@@ -1373,7 +1472,7 @@
 		return 0;
 
 	vt->signal = vpres ? 0xffff : 0x0;
-	if (state->is_cx25836)
+	if (is_cx2583x(state))
 		return 0;
 
 	vt->capability |=
@@ -1404,7 +1503,7 @@
 	struct cx25840_state *state = to_state(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (state->radio || state->is_cx25836)
+	if (state->radio || is_cx2583x(state))
 		return 0;
 
 	switch (vt->audmode) {
@@ -1445,11 +1544,11 @@
 	struct cx25840_state *state = to_state(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (state->is_cx25836)
+	if (is_cx2583x(state))
 		cx25836_initialize(client);
-	else if (state->is_cx23885)
+	else if (is_cx2388x(state))
 		cx23885_initialize(client);
-	else if (state->is_cx231xx)
+	else if (is_cx231xx(state))
 		cx231xx_initialize(client);
 	else
 		cx25840_initialize(client);
@@ -1470,7 +1569,7 @@
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
 	log_video_status(client);
-	if (!state->is_cx25836)
+	if (!is_cx2583x(state))
 		log_audio_status(client);
 	return 0;
 }
@@ -1521,12 +1620,50 @@
 
 /* ----------------------------------------------------------------------- */
 
+static u32 get_cx2388x_ident(struct i2c_client *client)
+{
+	u32 ret;
+
+	/* Come out of digital power down */
+	cx25840_write(client, 0x000, 0);
+
+	/* Detecting whether the part is cx23885/7/8 is more
+	 * difficult than it needs to be. No ID register. Instead we
+	 * probe certain registers indicated in the datasheets to look
+	 * for specific defaults that differ between the silicon designs. */
+
+	/* It's either 885/7 if the IR Tx Clk Divider register exists */
+	if (cx25840_read4(client, 0x204) & 0xffff) {
+		/* CX23885 returns bogus repetitive byte values for the DIF,
+		 * which doesn't exist for it. (Ex. 8a8a8a8a or 31313131) */
+		ret = cx25840_read4(client, 0x300);
+		if (((ret & 0xffff0000) >> 16) == (ret & 0xffff)) {
+			/* No DIF */
+			ret = V4L2_IDENT_CX23885_AV;
+		} else {
+			/* CX23887 has a broken DIF, but the registers
+			 * appear valid (but unsed), good enough to detect. */
+			ret = V4L2_IDENT_CX23887_AV;
+		}
+	} else if (cx25840_read4(client, 0x300) & 0x0fffffff) {
+		/* DIF PLL Freq Word reg exists; chip must be a CX23888 */
+		ret = V4L2_IDENT_CX23888_AV;
+	} else {
+		v4l_err(client, "Unable to detect h/w, assuming cx23887\n");
+		ret = V4L2_IDENT_CX23887_AV;
+	}
+
+	/* Back into digital power down */
+	cx25840_write(client, 0x000, 2);
+	return ret;
+}
+
 static int cx25840_probe(struct i2c_client *client,
 			 const struct i2c_device_id *did)
 {
 	struct cx25840_state *state;
 	struct v4l2_subdev *sd;
-	u32 id;
+	u32 id = V4L2_IDENT_NONE;
 	u16 device_id;
 
 	/* Check if the adapter supports the needed features */
@@ -1543,17 +1680,22 @@
 	 * 0x83 for the cx2583x and 0x84 for the cx2584x */
 	if ((device_id & 0xff00) == 0x8300) {
 		id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
-	}
-	else if ((device_id & 0xff00) == 0x8400) {
+	} else if ((device_id & 0xff00) == 0x8400) {
 		id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf);
 	} else if (device_id == 0x0000) {
-		id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
-	} else if (device_id == 0x1313) {
-		id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
+		id = get_cx2388x_ident(client);
 	} else if ((device_id & 0xfff0) == 0x5A30) {
-		id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf);
-	}
-	else {
+		/* The CX23100 (0x5A3C = 23100) doesn't have an A/V decoder */
+		id = V4L2_IDENT_CX2310X_AV;
+	} else if ((device_id & 0xff) == (device_id >> 8)) {
+		v4l_err(client,
+			"likely a confused/unresponsive cx2388[578] A/V decoder"
+			" found @ 0x%x (%s)\n",
+			client->addr << 1, client->adapter->name);
+		v4l_err(client, "A method to reset it from the cx25840 driver"
+			" software is not known at this time\n");
+		return -ENODEV;
+	} else {
 		v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n");
 		return -ENODEV;
 	}
@@ -1564,17 +1706,45 @@
 
 	sd = &state->sd;
 	v4l2_i2c_subdev_init(sd, client, &cx25840_ops);
-	/* Note: revision '(device_id & 0x0f) == 2' was never built. The
-	   marking skips from 0x1 == 22 to 0x3 == 23. */
-	v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n",
-		    (device_id & 0xfff0) >> 4,
-		    (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : (device_id & 0x0f),
-		    client->addr << 1, client->adapter->name);
+	switch (id) {
+	case V4L2_IDENT_CX23885_AV:
+		v4l_info(client, "cx23885 A/V decoder found @ 0x%x (%s)\n",
+			 client->addr << 1, client->adapter->name);
+		break;
+	case V4L2_IDENT_CX23887_AV:
+		v4l_info(client, "cx23887 A/V decoder found @ 0x%x (%s)\n",
+			 client->addr << 1, client->adapter->name);
+		break;
+	case V4L2_IDENT_CX23888_AV:
+		v4l_info(client, "cx23888 A/V decoder found @ 0x%x (%s)\n",
+			 client->addr << 1, client->adapter->name);
+		break;
+	case V4L2_IDENT_CX2310X_AV:
+		v4l_info(client, "cx%d A/V decoder found @ 0x%x (%s)\n",
+			 device_id, client->addr << 1, client->adapter->name);
+		break;
+	case V4L2_IDENT_CX25840:
+	case V4L2_IDENT_CX25841:
+	case V4L2_IDENT_CX25842:
+	case V4L2_IDENT_CX25843:
+		/* Note: revision '(device_id & 0x0f) == 2' was never built. The
+		   marking skips from 0x1 == 22 to 0x3 == 23. */
+		v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n",
+			 (device_id & 0xfff0) >> 4,
+			 (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1
+						: (device_id & 0x0f),
+			 client->addr << 1, client->adapter->name);
+		break;
+	case V4L2_IDENT_CX25836:
+	case V4L2_IDENT_CX25837:
+	default:
+		v4l_info(client, "cx25%3x-%x found @ 0x%x (%s)\n",
+			 (device_id & 0xfff0) >> 4, device_id & 0x0f,
+			 client->addr << 1, client->adapter->name);
+		break;
+	}
 
 	state->c = client;
-	state->is_cx25836 = ((device_id & 0xff00) == 0x8300);
-	state->is_cx23885 = (device_id == 0x0000) || (device_id == 0x1313);
-	state->is_cx231xx = (device_id == 0x5a3e);
 	state->vid_input = CX25840_COMPOSITE7;
 	state->aud_input = CX25840_AUDIO8;
 	state->audclk_freq = 48000;
diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h
index 814b565..5534544 100644
--- a/drivers/media/video/cx25840/cx25840-core.h
+++ b/drivers/media/video/cx25840/cx25840-core.h
@@ -23,6 +23,7 @@
 
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
 #include <linux/i2c.h>
 
 /* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is
@@ -48,9 +49,6 @@
 	int vbi_line_offset;
 	u32 id;
 	u32 rev;
-	int is_cx25836;
-	int is_cx23885;
-	int is_cx231xx;
 	int is_initialized;
 	wait_queue_head_t fw_wait;    /* wake up when the fw load is finished */
 	struct work_struct fw_work;   /* work entry for fw load */
@@ -61,6 +59,24 @@
 	return container_of(sd, struct cx25840_state, sd);
 }
 
+static inline bool is_cx2583x(struct cx25840_state *state)
+{
+	return state->id == V4L2_IDENT_CX25836 ||
+	       state->id == V4L2_IDENT_CX25837;
+}
+
+static inline bool is_cx231xx(struct cx25840_state *state)
+{
+	return state->id == V4L2_IDENT_CX2310X_AV;
+}
+
+static inline bool is_cx2388x(struct cx25840_state *state)
+{
+	return state->id == V4L2_IDENT_CX23885_AV ||
+	       state->id == V4L2_IDENT_CX23887_AV ||
+	       state->id == V4L2_IDENT_CX23888_AV;
+}
+
 /* ----------------------------------------------------------------------- */
 /* cx25850-core.c 							   */
 int cx25840_write(struct i2c_client *client, u16 addr, u8 value);
diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c
index 1f483c1..8150200 100644
--- a/drivers/media/video/cx25840/cx25840-firmware.c
+++ b/drivers/media/video/cx25840/cx25840-firmware.c
@@ -67,9 +67,9 @@
 
 	if (firmware[0])
 		return firmware;
-	if (state->is_cx23885)
+	if (is_cx2388x(state))
 		return "v4l-cx23885-avcore-01.fw";
-	if (state->is_cx231xx)
+	if (is_cx231xx(state))
 		return "v4l-cx231xx-avcore-01.fw";
 	return "v4l-cx25840.fw";
 }
@@ -112,13 +112,13 @@
 	int MAX_BUF_SIZE = FWSEND;
 	u32 gpio_oe = 0, gpio_da = 0;
 
-	if (state->is_cx23885) {
+	if (is_cx2388x(state)) {
 		/* Preserve the GPIO OE and output bits */
 		gpio_oe = cx25840_read(client, 0x160);
 		gpio_da = cx25840_read(client, 0x164);
 	}
 
-	if ((state->is_cx231xx) && MAX_BUF_SIZE > 16) {
+	if (is_cx231xx(state) && MAX_BUF_SIZE > 16) {
 		v4l_err(client, " Firmware download size changed to 16 bytes max length\n");
 		MAX_BUF_SIZE = 16;  /* cx231xx cannot accept more than 16 bytes at a time */
 	}
@@ -156,7 +156,7 @@
 	size = fw->size;
 	release_firmware(fw);
 
-	if (state->is_cx23885) {
+	if (is_cx2388x(state)) {
 		/* Restore GPIO configuration after f/w load */
 		cx25840_write(client, 0x160, gpio_oe);
 		cx25840_write(client, 0x164, gpio_da);
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 4995298..c7e5851 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -61,6 +61,8 @@
 	select DVB_STV0299 if !DVB_FE_CUSTOMISE
 	select DVB_STV0288 if !DVB_FE_CUSTOMISE
 	select DVB_STB6000 if !DVB_FE_CUSTOMISE
+	select DVB_STV0900 if !DVB_FE_CUSTOMISE
+	select DVB_STB6100 if !DVB_FE_CUSTOMISE
 	select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
 	---help---
 	  This adds support for DVB/ATSC cards based on the
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 33be636..d844f2a 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -2075,6 +2075,18 @@
 		},
 		.mpeg           = CX88_MPEG_DVB,
 	},
+	[CX88_BOARD_PROF_7301] = {
+		.name           = "Prof 7301 DVB-S/S2",
+		.tuner_type     = UNSET,
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.input          = { {
+			.type   = CX88_VMUX_DVB,
+			.vmux   = 0,
+		} },
+		.mpeg           = CX88_MPEG_DVB,
+	},
 };
 
 /* ------------------------------------------------------------------ */
@@ -2535,6 +2547,10 @@
 		.subvendor = 0x107d,
 		.subdevice = 0x6618,
 		.card      = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL,
+	}, {
+		.subvendor = 0xb034,
+		.subdevice = 0x3034,
+		.card      = CX88_BOARD_PROF_7301,
 	},
 };
 
@@ -3211,6 +3227,7 @@
 	case  CX88_BOARD_TBS_8920:
 	case  CX88_BOARD_PROF_6200:
 	case  CX88_BOARD_PROF_7300:
+	case  CX88_BOARD_PROF_7301:
 	case  CX88_BOARD_SATTRADE_ST4200:
 		cx_write(MO_GP0_IO, 0x8000);
 		msleep(100);
@@ -3267,7 +3284,7 @@
 			    ctl.fname);
 		call_all(core, tuner, s_config, &xc2028_cfg);
 	}
-	call_all(core, tuner, s_standby);
+	call_all(core, core, s_power, 0);
 }
 
 /* ------------------------------------------------------------------ */
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index cf63460..b354111 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -624,7 +624,7 @@
 	/* setup image format */
 	cx_andor(MO_COLOR_CTRL, 0x4000, 0x4000);
 
-	/* setup FIFO Threshholds */
+	/* setup FIFO Thresholds */
 	cx_write(MO_PDMA_STHRSH,   0x0807);
 	cx_write(MO_PDMA_DTHRSH,   0x0807);
 
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 518bcfe..b142969 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -53,6 +53,9 @@
 #include "stv0288.h"
 #include "stb6000.h"
 #include "cx24116.h"
+#include "stv0900.h"
+#include "stb6100.h"
+#include "stb6100_proc.h"
 
 MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
 MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
@@ -573,6 +576,15 @@
 	return 0;
 }
 
+static int stv0900_set_ts_param(struct dvb_frontend *fe,
+	int is_punctured)
+{
+	struct cx8802_dev *dev = fe->dvb->priv;
+	dev->ts_gen_cntrl = 0;
+
+	return 0;
+}
+
 static int cx24116_reset_device(struct dvb_frontend *fe)
 {
 	struct cx8802_dev *dev = fe->dvb->priv;
@@ -601,6 +613,23 @@
 	.reset_device  = cx24116_reset_device,
 };
 
+static struct stv0900_config prof_7301_stv0900_config = {
+	.demod_address = 0x6a,
+/*	demod_mode = 0,*/
+	.xtal = 27000000,
+	.clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
+	.diseqc_mode = 2,/* 2/3 PWM */
+	.tun1_maddress = 0,/* 0x60 */
+	.tun1_adc = 0,/* 2 Vpp */
+	.path1_mode = 3,
+	.set_ts_params = stv0900_set_ts_param,
+};
+
+static struct stb6100_config prof_7301_stb6100_config = {
+	.tuner_address = 0x60,
+	.refclock = 27000000,
+};
+
 static struct stv0299_config tevii_tuner_sharp_config = {
 	.demod_address = 0x68,
 	.inittab = sharp_z0194a_inittab,
@@ -1149,6 +1178,31 @@
 				goto frontend_detach;
 		}
 		break;
+	case CX88_BOARD_PROF_7301:{
+		struct dvb_tuner_ops *tuner_ops = NULL;
+
+		fe0->dvb.frontend = dvb_attach(stv0900_attach,
+						&prof_7301_stv0900_config,
+						&core->i2c_adap, 0);
+		if (fe0->dvb.frontend != NULL) {
+			if (!dvb_attach(stb6100_attach, fe0->dvb.frontend,
+					&prof_7301_stb6100_config,
+					&core->i2c_adap))
+				goto frontend_detach;
+
+			tuner_ops = &fe0->dvb.frontend->ops.tuner_ops;
+			tuner_ops->set_frequency = stb6100_set_freq;
+			tuner_ops->get_frequency = stb6100_get_freq;
+			tuner_ops->set_bandwidth = stb6100_set_bandw;
+			tuner_ops->get_bandwidth = stb6100_get_bandw;
+
+			core->prev_set_voltage =
+					fe0->dvb.frontend->ops.set_voltage;
+			fe0->dvb.frontend->ops.set_voltage =
+					tevii_dvbs_set_voltage;
+		}
+		break;
+		}
 	default:
 		printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
 		       core->name);
@@ -1170,11 +1224,11 @@
 		fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
 
 	/* Put the analog decoder in standby to keep it quiet */
-	call_all(core, tuner, s_standby);
+	call_all(core, core, s_power, 0);
 
 	/* register everything */
 	return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
-		&dev->pci->dev, adapter_nr, mfe_shared);
+					 &dev->pci->dev, adapter_nr, mfe_shared, NULL);
 
 frontend_detach:
 	core->gate_ctrl = NULL;
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 78b3635..92b8cdf 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -118,13 +118,13 @@
 
 		data = (data << 4) | ((gpio_key & 0xf0) >> 4);
 
-		ir_input_keydown(ir->input, &ir->ir, data, data);
+		ir_input_keydown(ir->input, &ir->ir, data);
 		ir_input_nokey(ir->input, &ir->ir);
 
 	} else if (ir->mask_keydown) {
 		/* bit set on keydown */
 		if (gpio & ir->mask_keydown) {
-			ir_input_keydown(ir->input, &ir->ir, data, data);
+			ir_input_keydown(ir->input, &ir->ir, data);
 		} else {
 			ir_input_nokey(ir->input, &ir->ir);
 		}
@@ -132,14 +132,14 @@
 	} else if (ir->mask_keyup) {
 		/* bit cleared on keydown */
 		if (0 == (gpio & ir->mask_keyup)) {
-			ir_input_keydown(ir->input, &ir->ir, data, data);
+			ir_input_keydown(ir->input, &ir->ir, data);
 		} else {
 			ir_input_nokey(ir->input, &ir->ir);
 		}
 
 	} else {
 		/* can't distinguish keydown/up :-/ */
-		ir_input_keydown(ir->input, &ir->ir, data, data);
+		ir_input_keydown(ir->input, &ir->ir, data);
 		ir_input_nokey(ir->input, &ir->ir);
 	}
 }
@@ -303,6 +303,23 @@
 		ir->mask_keydown = 0x02;
 		ir->polling      = 50; /* ms */
 		break;
+	case CX88_BOARD_OMICOM_SS4_PCI:
+	case CX88_BOARD_SATTRADE_ST4200:
+	case CX88_BOARD_TBS_8920:
+	case CX88_BOARD_TBS_8910:
+	case CX88_BOARD_PROF_7300:
+	case CX88_BOARD_PROF_7301:
+	case CX88_BOARD_PROF_6200:
+		ir_codes = &ir_codes_tbs_nec_table;
+		ir_type = IR_TYPE_PD;
+		ir->sampling = 0xff00; /* address */
+		break;
+	case CX88_BOARD_TEVII_S460:
+	case CX88_BOARD_TEVII_S420:
+		ir_codes = &ir_codes_tevii_nec_table;
+		ir_type = IR_TYPE_PD;
+		ir->sampling = 0xff00; /* address */
+		break;
 	case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
 		ir_codes         = &ir_codes_dntv_live_dvbt_pro_table;
 		ir_type          = IR_TYPE_PD;
@@ -343,7 +360,10 @@
 	snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name);
 	snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci));
 
-	ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
+	err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
+	if (err < 0)
+		goto err_out_free;
+
 	input_dev->name = ir->name;
 	input_dev->phys = ir->phys;
 	input_dev->id.bustype = BUS_PCI;
@@ -373,6 +393,7 @@
 	cx88_ir_stop(core, ir);
 	core->ir = NULL;
  err_out_free:
+	ir_input_free(input_dev);
 	input_free_device(input_dev);
 	kfree(ir);
 	return err;
@@ -387,6 +408,7 @@
 		return 0;
 
 	cx88_ir_stop(core, ir);
+	ir_input_free(ir->input);
 	input_unregister_device(ir->input);
 	kfree(ir);
 
@@ -432,8 +454,17 @@
 
 	/* decode it */
 	switch (core->boardnr) {
+	case CX88_BOARD_TEVII_S460:
+	case CX88_BOARD_TEVII_S420:
 	case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
 	case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
+	case CX88_BOARD_OMICOM_SS4_PCI:
+	case CX88_BOARD_SATTRADE_ST4200:
+	case CX88_BOARD_TBS_8920:
+	case CX88_BOARD_TBS_8910:
+	case CX88_BOARD_PROF_7300:
+	case CX88_BOARD_PROF_7301:
+	case CX88_BOARD_PROF_6200:
 		ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4);
 
 		if (ircode == 0xffffffff) { /* decoding error */
@@ -461,7 +492,7 @@
 
 		ir_dprintk("Key Code: %x\n", (ircode >> 16) & 0x7f);
 
-		ir_input_keydown(ir->input, &ir->ir, (ircode >> 16) & 0x7f, (ircode >> 16) & 0xff);
+		ir_input_keydown(ir->input, &ir->ir, (ircode >> 16) & 0x7f);
 		ir->release = jiffies + msecs_to_jiffies(120);
 		break;
 	case CX88_BOARD_HAUPPAUGE:
@@ -498,7 +529,7 @@
 		if ( dev != 0x1e && dev != 0x1f )
 			/* not a hauppauge remote */
 			break;
-		ir_input_keydown(ir->input, &ir->ir, code, ircode);
+		ir_input_keydown(ir->input, &ir->ir, code);
 		ir->release = jiffies + msecs_to_jiffies(120);
 		break;
 	case CX88_BOARD_PINNACLE_PCTV_HD_800i:
@@ -506,7 +537,7 @@
 		ir_dprintk("biphase decoded: %x\n", ircode);
 		if ((ircode & 0xfffff000) != 0x3000)
 			break;
-		ir_input_keydown(ir->input, &ir->ir, ircode & 0x3f, ircode);
+		ir_input_keydown(ir->input, &ir->ir, ircode & 0x3f);
 		ir->release = jiffies + msecs_to_jiffies(120);
 		break;
 	}
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 57e6b12..d7e8fce 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -935,7 +935,7 @@
 
 	mutex_lock(&dev->core->lock);
 	if(atomic_dec_and_test(&dev->core->users))
-		call_all(dev->core, tuner, s_standby);
+		call_all(dev->core, core, s_power, 0);
 	mutex_unlock(&dev->core->lock);
 
 	return 0;
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index d5cea41..e1c5217 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -238,6 +238,7 @@
 #define CX88_BOARD_HAUPPAUGE_IRONLY        80
 #define CX88_BOARD_WINFAST_DTV1800H        81
 #define CX88_BOARD_WINFAST_DTV2000H_J      82
+#define CX88_BOARD_PROF_7301               83
 
 enum cx88_itype {
 	CX88_VMUX_COMPOSITE1 = 1,
diff --git a/drivers/media/video/davinci/dm355_ccdc.c b/drivers/media/video/davinci/dm355_ccdc.c
index 4629cab..3143900 100644
--- a/drivers/media/video/davinci/dm355_ccdc.c
+++ b/drivers/media/video/davinci/dm355_ccdc.c
@@ -285,7 +285,7 @@
 
 	if ((ccdcparam->med_filt_thres < 0) ||
 	   (ccdcparam->med_filt_thres > CCDC_MED_FILT_THRESH)) {
-		dev_dbg(dev, "Invalid value of median filter thresold\n");
+		dev_dbg(dev, "Invalid value of median filter threshold\n");
 		return -EINVAL;
 	}
 
@@ -959,7 +959,7 @@
 	},
 };
 
-static int dm355_ccdc_init(void)
+static int __init dm355_ccdc_init(void)
 {
 	printk(KERN_NOTICE "dm355_ccdc_init\n");
 	if (vpfe_register_ccdc_device(&ccdc_hw_dev) < 0)
@@ -969,7 +969,7 @@
 	return 0;
 }
 
-static void dm355_ccdc_exit(void)
+static void __exit dm355_ccdc_exit(void)
 {
 	vpfe_unregister_ccdc_device(&ccdc_hw_dev);
 }
diff --git a/drivers/media/video/davinci/dm644x_ccdc.c b/drivers/media/video/davinci/dm644x_ccdc.c
index 2f19a91..d5fa193 100644
--- a/drivers/media/video/davinci/dm644x_ccdc.c
+++ b/drivers/media/video/davinci/dm644x_ccdc.c
@@ -859,7 +859,7 @@
 	},
 };
 
-static int dm644x_ccdc_init(void)
+static int __init dm644x_ccdc_init(void)
 {
 	printk(KERN_NOTICE "dm644x_ccdc_init\n");
 	if (vpfe_register_ccdc_device(&ccdc_hw_dev) < 0)
@@ -869,7 +869,7 @@
 	return 0;
 }
 
-static void dm644x_ccdc_exit(void)
+static void __exit dm644x_ccdc_exit(void)
 {
 	vpfe_unregister_ccdc_device(&ccdc_hw_dev);
 }
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c
index 402ce43..12a1b3d7 100644
--- a/drivers/media/video/davinci/vpfe_capture.c
+++ b/drivers/media/video/davinci/vpfe_capture.c
@@ -660,7 +660,7 @@
 
 	frame_format = ccdc_dev->hw_ops.get_frame_format();
 	if (frame_format == CCDC_FRMFMT_PROGRESSIVE)
-		free_irq(IRQ_VDINT1, vpfe_dev);
+		free_irq(vpfe_dev->ccdc_irq1, vpfe_dev);
 }
 
 static int vpfe_attach_irq(struct vpfe_device *vpfe_dev)
@@ -1338,7 +1338,7 @@
 	vpfe_dev->memory = req_buf->memory;
 	videobuf_queue_dma_contig_init(&vpfe_dev->buffer_queue,
 				&vpfe_videobuf_qops,
-				NULL,
+				vpfe_dev->pdev,
 				&vpfe_dev->irqlock,
 				req_buf->type,
 				vpfe_dev->fmt.fmt.pix.field,
@@ -1413,6 +1413,41 @@
 				      buf, file->f_flags & O_NONBLOCK);
 }
 
+static int vpfe_queryctrl(struct file *file, void *priv,
+		struct v4l2_queryctrl *qctrl)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+	struct vpfe_subdev_info *sdinfo;
+
+	sdinfo = vpfe_dev->current_subdev;
+
+	return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
+					 core, queryctrl, qctrl);
+
+}
+
+static int vpfe_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+	struct vpfe_subdev_info *sdinfo;
+
+	sdinfo = vpfe_dev->current_subdev;
+
+	return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
+					 core, g_ctrl, ctrl);
+}
+
+static int vpfe_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+	struct vpfe_subdev_info *sdinfo;
+
+	sdinfo = vpfe_dev->current_subdev;
+
+	return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
+					 core, s_ctrl, ctrl);
+}
+
 /*
  * vpfe_calculate_offsets : This function calculates buffers offset
  * for top and bottom field
@@ -1577,7 +1612,7 @@
 
 	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_cropcap\n");
 
-	if (vpfe_dev->std_index > ARRAY_SIZE(vpfe_standards))
+	if (vpfe_dev->std_index >= ARRAY_SIZE(vpfe_standards))
 		return -EINVAL;
 
 	memset(crop, 0, sizeof(struct v4l2_cropcap));
@@ -1710,6 +1745,9 @@
 	.vidioc_querystd	 = vpfe_querystd,
 	.vidioc_s_std		 = vpfe_s_std,
 	.vidioc_g_std		 = vpfe_g_std,
+	.vidioc_queryctrl	 = vpfe_queryctrl,
+	.vidioc_g_ctrl		 = vpfe_g_ctrl,
+	.vidioc_s_ctrl		 = vpfe_s_ctrl,
 	.vidioc_reqbufs		 = vpfe_reqbufs,
 	.vidioc_querybuf	 = vpfe_querybuf,
 	.vidioc_qbuf		 = vpfe_qbuf,
@@ -1978,8 +2016,7 @@
 	platform_set_drvdata(pdev, vpfe_dev);
 	/* set driver private data */
 	video_set_drvdata(vpfe_dev->video_dev, vpfe_dev);
-	i2c_adap = i2c_get_adapter(1);
-	vpfe_cfg = pdev->dev.platform_data;
+	i2c_adap = i2c_get_adapter(vpfe_cfg->i2c_adapter_id);
 	num_subdevs = vpfe_cfg->num_subdevs;
 	vpfe_dev->sd = kmalloc(sizeof(struct v4l2_subdev *) * num_subdevs,
 				GFP_KERNEL);
diff --git a/drivers/media/video/davinci/vpss.c b/drivers/media/video/davinci/vpss.c
index 6d709ca..453236b 100644
--- a/drivers/media/video/davinci/vpss.c
+++ b/drivers/media/video/davinci/vpss.c
@@ -53,7 +53,7 @@
 	int (*enable_clock)(enum vpss_clock_sel clock_sel, int en);
 	/* select input to ccdc */
 	void (*select_ccdc_source)(enum vpss_ccdc_source_sel src_sel);
-	/* clear wbl overlflow bit */
+	/* clear wbl overflow bit */
 	int (*clear_wbl_overflow)(enum vpss_wbl_sel wbl_sel);
 };
 
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index ac947ae..bd78338 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -293,7 +293,7 @@
 	dprintk("opening device and trying to acquire exclusive lock\n");
 
 	if (!dev) {
-		printk(KERN_ERR "BUG: em28xx can't find device struct."
+		em28xx_err("BUG: em28xx can't find device struct."
 				" Can't proceed with open\n");
 		return -ENODEV;
 	}
@@ -325,7 +325,7 @@
 
 	return 0;
 err:
-	printk(KERN_ERR "Error while configuring em28xx mixer\n");
+	em28xx_err("Error while configuring em28xx mixer\n");
 	return ret;
 }
 
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index c0fd5c6..82da205 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -225,6 +225,14 @@
 	{	-1,		-1,	-1,		-1},
 };
 
+static struct em28xx_reg_seq vc211a_enable[] = {
+	{EM28XX_R08_GPIO,	0xff,	0x07,		10},
+	{EM28XX_R08_GPIO,	0xff,	0x0f,		10},
+	{EM28XX_R08_GPIO,	0xff,	0x0b,		10},
+	{	-1,		-1,	-1,		-1},
+};
+
+
 /*
  *  Board definitions
  */
@@ -829,7 +837,7 @@
 		.mts_firmware   = 1,
 		.has_dvb        = 1,
 		.dvb_gpio       = hauppauge_wintv_hvr_900_digital,
-		.ir_codes       = &ir_codes_hauppauge_new_table,
+		.ir_codes       = &ir_codes_rc5_hauppauge_new_table,
 		.decoder        = EM28XX_TVP5150,
 		.input          = { {
 			.type     = EM28XX_VMUX_TELEVISION,
@@ -1009,6 +1017,23 @@
 			.amux     = EM28XX_AMUX_LINE_IN,
 		} },
 	},
+	[EM2800_BOARD_VC211A] = {
+		.name         = "Actionmaster/LinXcel/Digitus VC211A",
+		.is_em2800    = 1,
+		.tuner_type   = TUNER_ABSENT,	/* Capture-only board */
+		.decoder      = EM28XX_SAA711X,
+		.input        = { {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = SAA7115_COMPOSITE0,
+			.amux     = EM28XX_AMUX_LINE_IN,
+			.gpio     = vc211a_enable,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = SAA7115_SVIDEO3,
+			.amux     = EM28XX_AMUX_LINE_IN,
+			.gpio     = vc211a_enable,
+		} },
+	},
 	[EM2800_BOARD_LEADTEK_WINFAST_USBII] = {
 		.name         = "Leadtek Winfast USB II",
 		.is_em2800    = 1,
@@ -1381,10 +1406,14 @@
 	},
 	[EM2882_BOARD_TERRATEC_HYBRID_XS] = {
 		.name         = "Terratec Hybrid XS (em2882)",
-		.valid        = EM28XX_BOARD_NOT_VALIDATED,
 		.tuner_type   = TUNER_XC2028,
 		.tuner_gpio   = default_tuner_gpio,
+		.mts_firmware = 1,
 		.decoder      = EM28XX_TVP5150,
+		.has_dvb      = 1,
+		.dvb_gpio     = hauppauge_wintv_hvr_900_digital,
+		.ir_codes     = &ir_codes_terratec_cinergy_xs_table,
+		.xclk         = EM28XX_XCLK_FREQUENCY_12MHZ,
 		.input        = { {
 			.type     = EM28XX_VMUX_TELEVISION,
 			.vmux     = TVP5150_COMPOSITE0,
@@ -1608,6 +1637,8 @@
 			.driver_info = EM2820_BOARD_UNKNOWN },
 	{ USB_DEVICE(0xeb1a, 0x2861),
 			.driver_info = EM2820_BOARD_UNKNOWN },
+	{ USB_DEVICE(0xeb1a, 0x2862),
+			.driver_info = EM2820_BOARD_UNKNOWN },
 	{ USB_DEVICE(0xeb1a, 0x2870),
 			.driver_info = EM2820_BOARD_UNKNOWN },
 	{ USB_DEVICE(0xeb1a, 0x2881),
@@ -2050,6 +2081,7 @@
 	switch (dev->model) {
 	case EM2880_BOARD_EMPIRE_DUAL_TV:
 	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
+	case EM2882_BOARD_TERRATEC_HYBRID_XS:
 		ctl->demod = XC3028_FE_ZARLINK456;
 		break;
 	case EM2880_BOARD_TERRATEC_HYBRID_XS:
@@ -2227,6 +2259,7 @@
 /* ----------------------------------------------------------------------- */
 void em28xx_register_i2c_ir(struct em28xx *dev)
 {
+	struct i2c_board_info info;
 	const unsigned short addr_list[] = {
 		 0x30, 0x47, I2C_CLIENT_END
 	};
@@ -2234,9 +2267,9 @@
 	if (disable_ir)
 		return;
 
-	memset(&dev->info, 0, sizeof(&dev->info));
+	memset(&info, 0, sizeof(struct i2c_board_info));
 	memset(&dev->init_data, 0, sizeof(dev->init_data));
-	strlcpy(dev->info.type, "ir_video", I2C_NAME_SIZE);
+	strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
 
 	/* detect & configure */
 	switch (dev->model) {
@@ -2259,8 +2292,8 @@
 	}
 
 	if (dev->init_data.name)
-		dev->info.platform_data = &dev->init_data;
-	i2c_new_probed_device(&dev->i2c_adap, &dev->info, addr_list);
+		info.platform_data = &dev->init_data;
+	i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
 }
 
 void em28xx_card_setup(struct em28xx *dev)
@@ -2524,6 +2557,9 @@
 		dev->chip_id = retval;
 
 		switch (dev->chip_id) {
+		case CHIP_ID_EM2800:
+			em28xx_info("chip ID is em2800\n");
+			break;
 		case CHIP_ID_EM2710:
 			em28xx_info("chip ID is em2710\n");
 			break;
@@ -2650,7 +2686,7 @@
 	em28xx_init_extension(dev);
 
 	/* Save some power by putting tuner to sleep */
-	v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby);
+	v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
 
 	return 0;
 
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index a88257a..3f86d36 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -50,7 +50,7 @@
 		printk(KERN_INFO "%s %s :"fmt, \
 			 dev->name, __func__ , ##arg); } while (0)
 
-static int alt = EM28XX_PINOUT;
+static int alt;
 module_param(alt, int, 0644);
 MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
 
@@ -533,8 +533,15 @@
 
 	vid1 = em28xx_read_ac97(dev, AC97_VENDOR_ID1);
 	if (vid1 < 0) {
-		/* Device likely doesn't support AC97 */
+		/*
+		 * Device likely doesn't support AC97
+		 * Note: (some) em2800 devices without eeprom reports 0x91 on
+		 *	 CHIPCFG register, even not having an AC97 chip
+		 */
 		em28xx_warn("AC97 chip type couldn't be determined\n");
+		dev->audio_mode.ac97 = EM28XX_NO_AC97;
+		dev->has_alsa_audio = 0;
+		dev->audio_mode.has_audio = 0;
 		goto init_audio;
 	}
 
@@ -778,6 +785,16 @@
 	int i;
 	unsigned int min_pkt_size = dev->width * 2 + 4;
 
+	/*
+	 * alt = 0 is used only for control messages, so, only values
+	 * greater than 0 can be used for streaming.
+	 */
+	if (alt && alt < dev->num_alt) {
+		em28xx_coredbg("alternate forced to %d\n", dev->alt);
+		dev->alt = alt;
+		goto set_alt;
+	}
+
 	/* When image size is bigger than a certain value,
 	   the frame size should be increased, otherwise, only
 	   green screen will be received.
@@ -798,6 +815,7 @@
 			dev->alt = i;
 	}
 
+set_alt:
 	if (dev->alt != prev_alt) {
 		em28xx_coredbg("minimum isoc packet size: %u (alt=%d)\n",
 				min_pkt_size, dev->alt);
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index db74946..cc0505e 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -313,22 +313,20 @@
 	cfg.i2c_addr  = addr;
 
 	if (!dev->dvb->frontend) {
-		printk(KERN_ERR "%s/2: dvb frontend not attached. "
-				"Can't attach xc3028\n",
-		       dev->name);
+		em28xx_errdev("/2: dvb frontend not attached. "
+				"Can't attach xc3028\n");
 		return -EINVAL;
 	}
 
 	fe = dvb_attach(xc2028_attach, dev->dvb->frontend, &cfg);
 	if (!fe) {
-		printk(KERN_ERR "%s/2: xc3028 attach failed\n",
-		       dev->name);
+		em28xx_errdev("/2: xc3028 attach failed\n");
 		dvb_frontend_detach(dev->dvb->frontend);
 		dev->dvb->frontend = NULL;
 		return -EINVAL;
 	}
 
-	printk(KERN_INFO "%s/2: xc3028 attached\n", dev->name);
+	em28xx_info("%s/2: xc3028 attached\n", dev->name);
 
 	return 0;
 }
@@ -463,7 +461,7 @@
 	dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL);
 
 	if (dvb == NULL) {
-		printk(KERN_INFO "em28xx_dvb: memory allocation failed\n");
+		em28xx_info("em28xx_dvb: memory allocation failed\n");
 		return -ENOMEM;
 	}
 	dev->dvb = dvb;
@@ -493,6 +491,7 @@
 		}
 		break;
 	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
+	case EM2882_BOARD_TERRATEC_HYBRID_XS:
 	case EM2880_BOARD_EMPIRE_DUAL_TV:
 		dvb->frontend = dvb_attach(zl10353_attach,
 					   &em28xx_zl10353_xc3028_no_i2c_gate,
@@ -569,15 +568,12 @@
 		}
 		break;
 	default:
-		printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card"
-				" isn't supported yet\n",
-		       dev->name);
+		em28xx_errdev("/2: The frontend of your DVB/ATSC card"
+				" isn't supported yet\n");
 		break;
 	}
 	if (NULL == dvb->frontend) {
-		printk(KERN_ERR
-		       "%s/2: frontend initialization failed\n",
-		       dev->name);
+		em28xx_errdev("/2: frontend initialization failed\n");
 		result = -EINVAL;
 		goto out_free;
 	}
@@ -591,7 +587,7 @@
 		goto out_free;
 
 	em28xx_set_mode(dev, EM28XX_SUSPEND);
-	printk(KERN_INFO "Successfully loaded em28xx-dvb\n");
+	em28xx_info("Successfully loaded em28xx-dvb\n");
 	return 0;
 
 out_free:
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index 7a0fe38..d96ec7c 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -70,6 +70,7 @@
 	int polling;
 	struct delayed_work work;
 	unsigned int last_toggle:1;
+	unsigned int full_code:1;
 	unsigned int last_readcount;
 	unsigned int repeat_interval;
 
@@ -246,9 +247,10 @@
 		return;
 	}
 
-	dprintk("ir->get_key result tb=%02x rc=%02x lr=%02x data=%02x\n",
+	dprintk("ir->get_key result tb=%02x rc=%02x lr=%02x data=%02x%02x\n",
 		poll_result.toggle_bit, poll_result.read_count,
-		ir->last_readcount, poll_result.rc_data[0]);
+		ir->last_readcount, poll_result.rc_address,
+		poll_result.rc_data[0]);
 
 	if (ir->dev->chip_id == CHIP_ID_EM2874) {
 		/* The em2874 clears the readcount field every time the
@@ -282,8 +284,15 @@
 
 	if (do_sendkey) {
 		dprintk("sending keypress\n");
-		ir_input_keydown(ir->input, &ir->ir, poll_result.rc_data[0],
-				 poll_result.rc_data[0]);
+
+		if (ir->full_code)
+			ir_input_keydown(ir->input, &ir->ir,
+					 poll_result.rc_address << 8 |
+					 poll_result.rc_data[0]);
+		else
+			ir_input_keydown(ir->input, &ir->ir,
+					 poll_result.rc_data[0]);
+
 		ir_input_nokey(ir->input, &ir->ir);
 	}
 
@@ -333,6 +342,8 @@
 	switch (dev->chip_id) {
 	case CHIP_ID_EM2860:
 	case CHIP_ID_EM2883:
+		if (dev->model == EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950)
+			ir->full_code = 1;
 		ir->get_key = default_polling_getkey;
 		break;
 	case CHIP_ID_EM2874:
@@ -356,7 +367,11 @@
 	usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
 	strlcat(ir->phys, "/input0", sizeof(ir->phys));
 
-	ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER, dev->board.ir_codes);
+	err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER,
+			     dev->board.ir_codes);
+	if (err < 0)
+		goto err_out_free;
+
 	input_dev->name = ir->name;
 	input_dev->phys = ir->phys;
 	input_dev->id.bustype = BUS_USB;
@@ -381,6 +396,7 @@
 	em28xx_ir_stop(ir);
 	dev->ir = NULL;
  err_out_free:
+	ir_input_free(input_dev);
 	input_free_device(input_dev);
 	kfree(ir);
 	return err;
@@ -395,6 +411,7 @@
 		return 0;
 
 	em28xx_ir_stop(ir);
+	ir_input_free(ir->input);
 	input_unregister_device(ir->input);
 	kfree(ir);
 
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h
index ed12e7f..058ac87 100644
--- a/drivers/media/video/em28xx/em28xx-reg.h
+++ b/drivers/media/video/em28xx/em28xx-reg.h
@@ -192,6 +192,7 @@
 
 /* FIXME: Need to be populated with the other chip ID's */
 enum em28xx_chip_id {
+	CHIP_ID_EM2800 = 7,
 	CHIP_ID_EM2710 = 17,
 	CHIP_ID_EM2820 = 18,	/* Also used by some em2710 */
 	CHIP_ID_EM2840 = 20,
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 3a1dfb7..7ad6537 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -1060,12 +1060,6 @@
 		/* the em2800 can only scale down to 50% */
 		height = height > (3 * maxh / 4) ? maxh : maxh / 2;
 		width = width > (3 * maxw / 4) ? maxw : maxw / 2;
-		/* According to empiatech support the MaxPacketSize is too small
-		 * to support framesizes larger than 640x480 @ 30 fps or 640x576
-		 * @ 25 fps.  As this would cut of a part of the image we prefer
-		 * 360x576 or 360x480 for now */
-		if (width == maxw && height == maxh)
-			width /= 2;
 	} else {
 		/* width must even because of the YUYV format
 		   height must be even because of interlacing */
@@ -2225,7 +2219,7 @@
 		}
 
 		/* Save some power by putting tuner to sleep */
-		v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby);
+		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
 
 		/* do this before setting alternate! */
 		em28xx_uninit_isoc(dev);
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 0a73e8b..441df64 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -110,6 +110,7 @@
 #define EM2820_BOARD_SILVERCREST_WEBCAM           71
 #define EM2861_BOARD_GADMEI_UTV330PLUS           72
 #define EM2870_BOARD_REDDO_DVB_C_USB_BOX          73
+#define EM2800_BOARD_VC211A			  74
 
 /* Limits minimum and default number of buffers */
 #define EM28XX_MIN_BUF 4
@@ -143,9 +144,6 @@
  */
 #define EM28XX_NUM_PACKETS 40
 
-/* default alternate; 0 means choose the best */
-#define EM28XX_PINOUT 0
-
 #define EM28XX_INTERLACED_DEFAULT 1
 
 /*
@@ -615,7 +613,6 @@
 	struct em28xx_dvb *dvb;
 
 	/* I2C keyboard data */
-	struct i2c_board_info info;
 	struct IR_i2c_init_data init_data;
 };
 
@@ -800,7 +797,7 @@
 	if (dev->board.is_webcam)
 		return dev->sensor_xres;
 
-	if (dev->board.max_range_640_480)
+	if (dev->board.max_range_640_480 || dev->board.is_em2800)
 		return 640;
 
 	return 720;
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index fe2e490..609d65b 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -76,10 +76,11 @@
 	  module will be called gspca_mr97310a.
 
 config USB_GSPCA_OV519
-	tristate "OV519 USB Camera Driver"
+	tristate "OV51x / OVFX2 / W996xCF USB Camera Driver"
 	depends on VIDEO_V4L2 && USB_GSPCA
 	help
-	  Say Y here if you want support for cameras based on the OV519 chip.
+	  Say Y here if you want support for cameras based on one of these:
+	  OV511(+), OV518(+), OV519, OVFX2, W9967CF, W9968CF
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called gspca_ov519.
@@ -103,6 +104,15 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called gspca_pac207.
 
+config USB_GSPCA_PAC7302
+	tristate "Pixart PAC7302 USB Camera Driver"
+	depends on VIDEO_V4L2 && USB_GSPCA
+	help
+	  Say Y here if you want support for cameras based on the PAC7302 chip.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called gspca_pac7302.
+
 config USB_GSPCA_PAC7311
 	tristate "Pixart PAC7311 USB Camera Driver"
 	depends on VIDEO_V4L2 && USB_GSPCA
@@ -229,6 +239,15 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called gspca_stk014.
 
+config USB_GSPCA_STV0680
+	tristate "STV0680 USB Camera Driver"
+	depends on VIDEO_V4L2 && USB_GSPCA
+	help
+	  Say Y here if you want support for cameras based on the STV0680 chip.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called gspca_stv0680.
+
 config USB_GSPCA_SUNPLUS
 	tristate "SUNPLUS USB Camera Driver"
 	depends on VIDEO_V4L2 && USB_GSPCA
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index b742081..ff2c727 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -8,6 +8,7 @@
 obj-$(CONFIG_USB_GSPCA_OV519)    += gspca_ov519.o
 obj-$(CONFIG_USB_GSPCA_OV534)    += gspca_ov534.o
 obj-$(CONFIG_USB_GSPCA_PAC207)   += gspca_pac207.o
+obj-$(CONFIG_USB_GSPCA_PAC7302)  += gspca_pac7302.o
 obj-$(CONFIG_USB_GSPCA_PAC7311)  += gspca_pac7311.o
 obj-$(CONFIG_USB_GSPCA_SN9C20X)  += gspca_sn9c20x.o
 obj-$(CONFIG_USB_GSPCA_SONIXB)   += gspca_sonixb.o
@@ -22,6 +23,7 @@
 obj-$(CONFIG_USB_GSPCA_SQ905C)   += gspca_sq905c.o
 obj-$(CONFIG_USB_GSPCA_SUNPLUS)  += gspca_sunplus.o
 obj-$(CONFIG_USB_GSPCA_STK014)   += gspca_stk014.o
+obj-$(CONFIG_USB_GSPCA_STV0680)  += gspca_stv0680.o
 obj-$(CONFIG_USB_GSPCA_T613)     += gspca_t613.o
 obj-$(CONFIG_USB_GSPCA_TV8532)   += gspca_tv8532.o
 obj-$(CONFIG_USB_GSPCA_VC032X)   += gspca_vc032x.o
@@ -37,6 +39,7 @@
 gspca_ov519-objs    := ov519.o
 gspca_ov534-objs    := ov534.o
 gspca_pac207-objs   := pac207.o
+gspca_pac7302-objs  := pac7302.o
 gspca_pac7311-objs  := pac7311.o
 gspca_sn9c20x-objs  := sn9c20x.o
 gspca_sonixb-objs   := sonixb.o
@@ -50,6 +53,7 @@
 gspca_sq905-objs    := sq905.o
 gspca_sq905c-objs   := sq905c.o
 gspca_stk014-objs   := stk014.o
+gspca_stv0680-objs  := stv0680.o
 gspca_sunplus-objs  := sunplus.o
 gspca_t613-objs     := t613.o
 gspca_tv8532-objs   := tv8532.o
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index eca0035..2f0b8d6 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -888,8 +888,7 @@
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -897,16 +896,15 @@
 	if (data[0] == 0xff && data[1] == 0xd8) {
 
 		/* start of frame */
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-					data, 0);
+		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 
 		/* put the JPEG header in the new frame */
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
-			sd->jpeg_hdr, JPEG_HDR_SZ);
+		gspca_frame_add(gspca_dev, FIRST_PACKET,
+				sd->jpeg_hdr, JPEG_HDR_SZ);
 		data += 2;
 		len -= 2;
 	}
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static void setbrightness(struct gspca_dev*gspca_dev)
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
index c1461e6..9de8641 100644
--- a/drivers/media/video/gspca/etoms.c
+++ b/drivers/media/video/gspca/etoms.c
@@ -752,8 +752,7 @@
 #undef LIMIT
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	int seqframe;
@@ -767,14 +766,13 @@
 		       data[2], data[3], data[4], data[5]);
 		data += 30;
 		/* don't change datalength as the chips provided it */
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-					data, 0);
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
+		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 		return;
 	}
 	if (len) {
 		data += 8;
-		gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+		gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 	} else {			/* Drop Packet */
 		gspca_dev->last_packet_type = DISCARD_PACKET;
 	}
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c
index 480ec5c..5d90e74 100644
--- a/drivers/media/video/gspca/finepix.c
+++ b/drivers/media/video/gspca/finepix.c
@@ -82,7 +82,6 @@
 	struct gspca_dev *gspca_dev = &dev->gspca_dev;
 	struct urb *urb = gspca_dev->urb[0];
 	u8 *data = urb->transfer_buffer;
-	struct gspca_frame *frame;
 	int ret = 0;
 	int len;
 
@@ -118,10 +117,6 @@
 			}
 			if (!gspca_dev->present || !gspca_dev->streaming)
 				goto out;
-			frame = gspca_get_i_frame(&dev->gspca_dev);
-			if (frame == NULL)
-				gspca_dev->last_packet_type = DISCARD_PACKET;
-
 			if (len < FPIX_MAX_TRANSFER ||
 				(data[len - 2] == 0xff &&
 					data[len - 1] == 0xd9)) {
@@ -132,21 +127,17 @@
 				 * but there's nothing we can do. We also end
 				 * here if the the jpeg ends right at the end
 				 * of the frame. */
-				if (frame)
-					frame = gspca_frame_add(gspca_dev,
-							LAST_PACKET,
-							frame,
-							data, len);
+				gspca_frame_add(gspca_dev, LAST_PACKET,
+						data, len);
 				break;
 			}
 
 			/* got a partial image */
-			if (frame)
-				gspca_frame_add(gspca_dev,
-						gspca_dev->last_packet_type
-							== LAST_PACKET
-						? FIRST_PACKET : INTER_PACKET,
-						frame, data, len);
+			gspca_frame_add(gspca_dev,
+					gspca_dev->last_packet_type
+						== LAST_PACKET
+					? FIRST_PACKET : INTER_PACKET,
+					data, len);
 		}
 
 		/* We must wait before trying reading the next
diff --git a/drivers/media/video/gspca/gl860/gl860-mi1320.c b/drivers/media/video/gspca/gl860/gl860-mi1320.c
index 39f6261..1355e52 100644
--- a/drivers/media/video/gspca/gl860/gl860-mi1320.c
+++ b/drivers/media/video/gspca/gl860/gl860-mi1320.c
@@ -1,6 +1,5 @@
-/* @file gl860-mi1320.c
- * @author Olivier LORIN from my logs
- * @date 2009-08-27
+/* Subdriver for the GL860 chip with the MI1320 sensor
+ * Author Olivier LORIN from own logs
  *
  * 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
@@ -127,49 +126,49 @@
 
 static u8 dat_hvflip1[] = {0xf0, 0x00, 0xf1, 0x00};
 
-static u8 s000[] =
+static u8 dat_common00[] =
 	"\x00\x01\x07\x6a\x06\x63\x0d\x6a" "\xc0\x00\x10\x10\xc1\x03\xc2\x42"
 	"\xd8\x04\x58\x00\x04\x02";
-static u8 s001[] =
+static u8 dat_common01[] =
 	"\x0d\x00\xf1\x0b\x0d\x00\xf1\x08" "\x35\x00\xf1\x22\x68\x00\xf1\x5d"
 	"\xf0\x00\xf1\x01\x06\x70\xf1\x0e" "\xf0\x00\xf1\x02\xdd\x18\xf1\xe0";
-static u8 s002[] =
+static u8 dat_common02[] =
 	"\x05\x01\xf1\x84\x06\x00\xf1\x44" "\x07\x00\xf1\xbe\x08\x00\xf1\x1e"
 	"\x20\x01\xf1\x03\x21\x84\xf1\x00" "\x22\x0d\xf1\x0f\x24\x80\xf1\x00"
 	"\x34\x18\xf1\x2d\x35\x00\xf1\x22" "\x43\x83\xf1\x83\x59\x00\xf1\xff";
-static u8 s003[] =
+static u8 dat_common03[] =
 	"\xf0\x00\xf1\x02\x39\x06\xf1\x8c" "\x3a\x06\xf1\x8c\x3b\x03\xf1\xda"
 	"\x3c\x05\xf1\x30\x57\x01\xf1\x0c" "\x58\x01\xf1\x42\x59\x01\xf1\x0c"
 	"\x5a\x01\xf1\x42\x5c\x13\xf1\x0e" "\x5d\x17\xf1\x12\x64\x1e\xf1\x1c";
-static u8 s004[] =
+static u8 dat_common04[] =
 	"\xf0\x00\xf1\x02\x24\x5f\xf1\x20" "\x28\xea\xf1\x02\x5f\x41\xf1\x43";
-static u8 s005[] =
+static u8 dat_common05[] =
 	"\x02\x00\xf1\xee\x03\x29\xf1\x1a" "\x04\x02\xf1\xa4\x09\x00\xf1\x68"
 	"\x0a\x00\xf1\x2a\x0b\x00\xf1\x04" "\x0c\x00\xf1\x93\x0d\x00\xf1\x82"
 	"\x0e\x00\xf1\x40\x0f\x00\xf1\x5f" "\x10\x00\xf1\x4e\x11\x00\xf1\x5b";
-static u8 s006[] =
+static u8 dat_common06[] =
 	"\x15\x00\xf1\xc9\x16\x00\xf1\x5e" "\x17\x00\xf1\x9d\x18\x00\xf1\x06"
 	"\x19\x00\xf1\x89\x1a\x00\xf1\x12" "\x1b\x00\xf1\xa1\x1c\x00\xf1\xe4"
 	"\x1d\x00\xf1\x7a\x1e\x00\xf1\x64" "\xf6\x00\xf1\x5f";
-static u8 s007[] =
+static u8 dat_common07[] =
 	"\xf0\x00\xf1\x01\x53\x09\xf1\x03" "\x54\x3d\xf1\x1c\x55\x99\xf1\x72"
 	"\x56\xc1\xf1\xb1\x57\xd8\xf1\xce" "\x58\xe0\xf1\x00\xdc\x0a\xf1\x03"
 	"\xdd\x45\xf1\x20\xde\xae\xf1\x82" "\xdf\xdc\xf1\xc9\xe0\xf6\xf1\xea"
 	"\xe1\xff\xf1\x00";
-static u8 s008[] =
+static u8 dat_common08[] =
 	"\xf0\x00\xf1\x01\x80\x00\xf1\x06" "\x81\xf6\xf1\x08\x82\xfb\xf1\xf7"
 	"\x83\x00\xf1\xfe\xb6\x07\xf1\x03" "\xb7\x18\xf1\x0c\x84\xfb\xf1\x06"
 	"\x85\xfb\xf1\xf9\x86\x00\xf1\xff" "\xb8\x07\xf1\x04\xb9\x16\xf1\x0a";
-static u8 s009[] =
+static u8 dat_common09[] =
 	"\x87\xfa\xf1\x05\x88\xfc\xf1\xf9" "\x89\x00\xf1\xff\xba\x06\xf1\x03"
 	"\xbb\x17\xf1\x09\x8a\xe8\xf1\x14" "\x8b\xf7\xf1\xf0\x8c\xfd\xf1\xfa"
 	"\x8d\x00\xf1\x00\xbc\x05\xf1\x01" "\xbd\x0c\xf1\x08\xbe\x00\xf1\x14";
-static u8 s010[] =
+static u8 dat_common10[] =
 	"\x8e\xea\xf1\x13\x8f\xf7\xf1\xf2" "\x90\xfd\xf1\xfa\x91\x00\xf1\x00"
 	"\xbf\x05\xf1\x01\xc0\x0a\xf1\x08" "\xc1\x00\xf1\x0c\x92\xed\xf1\x0f"
 	"\x93\xf9\xf1\xf4\x94\xfe\xf1\xfb" "\x95\x00\xf1\x00\xc2\x04\xf1\x01"
 	"\xc3\x0a\xf1\x07\xc4\x00\xf1\x10";
-static u8 s011[] =
+static u8 dat_common11[] =
 	"\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x25\x00\xf1\x55\x34\x10\xf1\x10"
 	"\x35\xf0\xf1\x10\x3a\x02\xf1\x03" "\x3b\x04\xf1\x2a\x9b\x43\xf1\x00"
 	"\xa4\x03\xf1\xc0\xa7\x02\xf1\x81";
@@ -222,26 +221,26 @@
 
 static void common(struct gspca_dev *gspca_dev)
 {
-	s32 n; /* reserved for FETCH macros */
+	s32 n; /* reserved for FETCH functions */
 
-	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 22, s000);
+	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 22, dat_common00);
 	ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL);
-	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 32, s001);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 32, dat_common01);
 	n = fetch_validx(gspca_dev, tbl_common, ARRAY_SIZE(tbl_common));
-	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s002);
-	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s003);
-	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 16, s004);
-	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s005);
-	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 44, s006);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common02);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common03);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 16, dat_common04);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common05);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 44, dat_common06);
 	keep_on_fetching_validx(gspca_dev, tbl_common,
 					ARRAY_SIZE(tbl_common), n);
-	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 52, s007);
-	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s008);
-	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s009);
-	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 56, s010);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 52, dat_common07);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common08);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common09);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 56, dat_common10);
 	keep_on_fetching_validx(gspca_dev, tbl_common,
 					ARRAY_SIZE(tbl_common), n);
-	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, s011);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, dat_common11);
 	keep_on_fetching_validx(gspca_dev, tbl_common,
 					ARRAY_SIZE(tbl_common), n);
 }
diff --git a/drivers/media/video/gspca/gl860/gl860-mi2020.c b/drivers/media/video/gspca/gl860/gl860-mi2020.c
index ffb09fe..80cb3f1 100644
--- a/drivers/media/video/gspca/gl860/gl860-mi2020.c
+++ b/drivers/media/video/gspca/gl860/gl860-mi2020.c
@@ -1,7 +1,6 @@
-/* @file gl860-mi2020.c
- * @author Olivier LORIN, from Ice/Soro2005's logs(A), Fret_saw/Hulkie's
+/* Subdriver for the GL860 chip with the MI2020 sensor
+ * Author Olivier LORIN, from Ice/Soro2005's logs(A), Fret_saw/Hulkie's
  * logs(B) and Tricid"s logs(C). With the help of Kytrix/BUGabundo/Blazercist.
- * @date 2009-08-27
  *
  * 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
@@ -41,7 +40,7 @@
 static u8 dat_multi5[] = { 0x8c, 0xa1, 0x03 };
 static u8 dat_multi6[] = { 0x90, 0x00, 0x05 };
 
-static struct validx tbl_common_a[] = {
+static struct validx tbl_common1[] = {
 	{0x0000, 0x0000},
 	{1, 0xffff}, /* msleep(35); */
 	{0x006a, 0x0007}, {0x0063, 0x0006}, {0x006a, 0x000d}, {0x0000, 0x00c0},
@@ -49,7 +48,7 @@
 	{0x0000, 0x0058}, {0x0002, 0x0004}, {0x0041, 0x0000},
 };
 
-static struct validx tbl_common_b[] = {
+static struct validx tbl_common2[] = {
 	{0x006a, 0x0007},
 	{35, 0xffff},
 	{0x00ef, 0x0006},
@@ -60,7 +59,7 @@
 	{0x0004, 0x00d8}, {0x0000, 0x0058}, {0x0041, 0x0000},
 };
 
-static struct idxdata tbl_common_c[] = {
+static struct idxdata tbl_common3[] = {
 	{0x32, "\x02\x00\x08"}, {0x33, "\xf4\x03\x1d"},
 	{6, "\xff\xff\xff"}, /* 12 */
 	{0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
@@ -109,7 +108,7 @@
 	{0x33, "\x8c\xa2\x03"}, {0x33, "\x90\x00\xbb"},
 };
 
-static struct idxdata tbl_common_d[] = {
+static struct idxdata tbl_common4[] = {
 	{0x33, "\x8c\x22\x2e"}, {0x33, "\x90\x00\xa0"}, {0x33, "\x8c\xa4\x08"},
 	{0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x21"},
 	{0x33, "\x8c\xa4\x0a"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\xa4\x0b"},
@@ -118,7 +117,7 @@
 	{0x33, "\x90\x00\xa0"}, {0x33, "\x8c\x24\x17"}, {0x33, "\x90\x00\xc0"},
 };
 
-static struct idxdata tbl_common_e[] = {
+static struct idxdata tbl_common5[] = {
 	{0x33, "\x8c\xa4\x04"}, {0x33, "\x90\x00\x80"}, {0x33, "\x8c\xa7\x9d"},
 	{0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa7\x9e"}, {0x33, "\x90\x00\x00"},
 	{0x33, "\x8c\xa2\x0c"}, {0x33, "\x90\x00\x17"}, {0x33, "\x8c\xa2\x15"},
@@ -180,7 +179,7 @@
 	{53, 0xffff},
 };
 
-static struct idxdata tbl_init_post_alt_low_a[] = {
+static struct idxdata tbl_init_post_alt_low1[] = {
 	{0x33, "\x8c\x27\x15"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\x22\x2e"},
 	{0x33, "\x90\x00\x81"}, {0x33, "\x8c\xa4\x08"}, {0x33, "\x90\x00\x17"},
 	{0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x1a"}, {0x33, "\x8c\xa4\x0a"},
@@ -189,7 +188,7 @@
 	{0x33, "\x90\x00\x9b"},
 };
 
-static struct idxdata tbl_init_post_alt_low_b[] = {
+static struct idxdata tbl_init_post_alt_low2[] = {
 	{0x33, "\x8c\x27\x03"}, {0x33, "\x90\x03\x24"}, {0x33, "\x8c\x27\x05"},
 	{0x33, "\x90\x02\x58"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
 	{2, "\xff\xff\xff"},
@@ -197,7 +196,7 @@
 	{2, "\xff\xff\xff"},
 };
 
-static struct idxdata tbl_init_post_alt_low_c[] = {
+static struct idxdata tbl_init_post_alt_low3[] = {
 	{0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
 	{2, "\xff\xff\xff"},
 	{0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\xa1\x20"},
@@ -221,7 +220,7 @@
 	{1, "\xff\xff\xff"},
 };
 
-static struct idxdata tbl_init_post_alt_low_d[] = {
+static struct idxdata tbl_init_post_alt_low4[] = {
 	{0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
 	{0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
 	{0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
@@ -267,7 +266,7 @@
 	{0x32, "\x6c\x14\x08"},
 };
 
-static struct idxdata tbl_init_post_alt_big_a[] = {
+static struct idxdata tbl_init_post_alt_big1[] = {
 	{0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
 	{2, "\xff\xff\xff"},
 	{0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
@@ -288,7 +287,7 @@
 	{0x34, "\x04\x00\x2a"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"},
 };
 
-static struct idxdata tbl_init_post_alt_big_b[] = {
+static struct idxdata tbl_init_post_alt_big2[] = {
 	{0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
 	{0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
 	{0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
@@ -317,7 +316,7 @@
 	{0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"}, {0x33, "\x90\x00\x3c"},
 };
 
-static struct idxdata tbl_init_post_alt_big_c[] = {
+static struct idxdata tbl_init_post_alt_big3[] = {
 	{0x33, "\x8c\xa1\x02"},
 	{0x33, "\x90\x00\x1f"},
 	{0x33, "\x8c\xa1\x02"},
@@ -388,14 +387,14 @@
 	s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
 
 	if (_MI2020b_) {
-		fetch_validx(gspca_dev, tbl_common_a, ARRAY_SIZE(tbl_common_a));
+		fetch_validx(gspca_dev, tbl_common1, ARRAY_SIZE(tbl_common1));
 	} else {
 		if (_MI2020_)
 			ctrl_out(gspca_dev, 0x40,  1, 0x0008, 0x0004,  0, NULL);
 		else
 			ctrl_out(gspca_dev, 0x40,  1, 0x0002, 0x0004,  0, NULL);
 		msleep(35);
-		fetch_validx(gspca_dev, tbl_common_b, ARRAY_SIZE(tbl_common_b));
+		fetch_validx(gspca_dev, tbl_common2, ARRAY_SIZE(tbl_common2));
 	}
 	ctrl_out(gspca_dev, 0x40,  3, 0x7a00, 0x0033,  3, "\x86\x25\x01");
 	ctrl_out(gspca_dev, 0x40,  3, 0x7a00, 0x0033,  3, "\x86\x25\x00");
@@ -403,13 +402,13 @@
 	ctrl_out(gspca_dev, 0x40,  3, 0x7a00, 0x0030,  3, "\x1a\x0a\xcc");
 	if (reso == IMAGE_1600)
 		msleep(2); /* 1600 */
-	fetch_idxdata(gspca_dev, tbl_common_c, ARRAY_SIZE(tbl_common_c));
+	fetch_idxdata(gspca_dev, tbl_common3, ARRAY_SIZE(tbl_common3));
 
 	if (_MI2020b_ || _MI2020_)
-		fetch_idxdata(gspca_dev, tbl_common_d,
-				ARRAY_SIZE(tbl_common_d));
+		fetch_idxdata(gspca_dev, tbl_common4,
+				ARRAY_SIZE(tbl_common4));
 
-	fetch_idxdata(gspca_dev, tbl_common_e, ARRAY_SIZE(tbl_common_e));
+	fetch_idxdata(gspca_dev, tbl_common5, ARRAY_SIZE(tbl_common5));
 	if (_MI2020b_ || _MI2020_) {
 		/* Different from fret */
 		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x78");
@@ -525,15 +524,15 @@
 				12, dat_800);
 
 		if (_MI2020c_)
-			fetch_idxdata(gspca_dev, tbl_init_post_alt_low_a,
-					ARRAY_SIZE(tbl_init_post_alt_low_a));
+			fetch_idxdata(gspca_dev, tbl_init_post_alt_low1,
+					ARRAY_SIZE(tbl_init_post_alt_low1));
 
 		if (reso == IMAGE_800)
-			fetch_idxdata(gspca_dev, tbl_init_post_alt_low_b,
-					ARRAY_SIZE(tbl_init_post_alt_low_b));
+			fetch_idxdata(gspca_dev, tbl_init_post_alt_low2,
+					ARRAY_SIZE(tbl_init_post_alt_low2));
 
-		fetch_idxdata(gspca_dev, tbl_init_post_alt_low_c,
-				ARRAY_SIZE(tbl_init_post_alt_low_c));
+		fetch_idxdata(gspca_dev, tbl_init_post_alt_low3,
+				ARRAY_SIZE(tbl_init_post_alt_low3));
 
 		if (_MI2020b_) {
 			ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
@@ -574,8 +573,8 @@
 		msleep(5);/* " */
 
 		if (_MI2020c_) {
-			fetch_idxdata(gspca_dev, tbl_init_post_alt_low_d,
-					ARRAY_SIZE(tbl_init_post_alt_low_d));
+			fetch_idxdata(gspca_dev, tbl_init_post_alt_low4,
+					ARRAY_SIZE(tbl_init_post_alt_low4));
 		} else {
 			ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, &c);
 			msleep(14); /* 0xd8 */
@@ -644,8 +643,8 @@
 					3, "\x90\x04\xb0");
 		}
 
-		fetch_idxdata(gspca_dev, tbl_init_post_alt_big_a,
-				ARRAY_SIZE(tbl_init_post_alt_big_a));
+		fetch_idxdata(gspca_dev, tbl_init_post_alt_big1,
+				ARRAY_SIZE(tbl_init_post_alt_big1));
 
 		if (reso == IMAGE_1600)
 			msleep(13); /* 1600 */
@@ -708,8 +707,8 @@
 		msleep(14);
 
 		if (_MI2020c_)
-			fetch_idxdata(gspca_dev, tbl_init_post_alt_big_b,
-					ARRAY_SIZE(tbl_init_post_alt_big_b));
+			fetch_idxdata(gspca_dev, tbl_init_post_alt_big2,
+					ARRAY_SIZE(tbl_init_post_alt_big2));
 
 		/* flip/mirror */
 		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1);
@@ -738,8 +737,8 @@
 		sd->nbIm = 0;
 
 		if (_MI2020c_)
-			fetch_idxdata(gspca_dev, tbl_init_post_alt_big_c,
-					ARRAY_SIZE(tbl_init_post_alt_big_c));
+			fetch_idxdata(gspca_dev, tbl_init_post_alt_big3,
+					ARRAY_SIZE(tbl_init_post_alt_big3));
 	}
 
 	sd->vold.mirror    = mirror;
diff --git a/drivers/media/video/gspca/gl860/gl860-ov2640.c b/drivers/media/video/gspca/gl860/gl860-ov2640.c
index 14b9c37..768cac5 100644
--- a/drivers/media/video/gspca/gl860/gl860-ov2640.c
+++ b/drivers/media/video/gspca/gl860/gl860-ov2640.c
@@ -1,6 +1,5 @@
-/* @file gl860-ov2640.c
- * @author Olivier LORIN, from Malmostoso's logs
- * @date 2009-08-27
+/* Subdriver for the GL860 chip with the OV2640 sensor
+ * Author Olivier LORIN, from Malmostoso's logs
  *
  * 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
@@ -21,8 +20,12 @@
 #include "gl860.h"
 
 static u8 dat_init1[] = "\x00\x41\x07\x6a\x06\x61\x0d\x6a" "\x10\x10\xc1\x01";
-static u8 dat_init2[] = {0x61}; /* expected */
-static u8 dat_init3[] = {0x51}; /* expected */
+
+static u8 c61[] = {0x61}; /* expected */
+static u8 c51[] = {0x51}; /* expected */
+static u8 c50[] = {0x50}; /* expected */
+static u8 c28[] = {0x28}; /* expected */
+static u8 ca8[] = {0xa8}; /* expected */
 
 static u8 dat_post[] =
 	"\x00\x41\x07\x6a\x06\xef\x0d\x6a" "\x10\x10\xc1\x01";
@@ -32,10 +35,6 @@
 static u8 dat_1280[] = "\xd0\x01\xd1\x18\xd2\xc0\xd3\x02\xd4\x28\xd5\x01";
 static u8 dat_1600[] = "\xd0\x01\xd1\x20\xd2\xb0\xd3\x02\xd4\x30\xd5\x41";
 
-static u8 c50[] = {0x50}; /* expected */
-static u8 c28[] = {0x28}; /* expected */
-static u8 ca8[] = {0xa8}; /* expected */
-
 static struct validx tbl_init_at_startup[] = {
 	{0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1},
 	{0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d},
@@ -92,7 +91,7 @@
 	{0x6000, 0x0010},
 };
 
-static struct validx tbl_sensor_settings_common_a[] = {
+static struct validx tbl_sensor_settings_common1[] = {
 	{0x0041, 0x0000}, {0x006a, 0x0007}, {0x00ef, 0x0006}, {0x006a, 0x000d},
 	{0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1}, {0x0041, 0x00c2},
 	{0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058}, {0x0041, 0x0000},
@@ -104,40 +103,10 @@
 	{0x0040, 0x0000},
 };
 
-static struct validx tbl_sensor_settings_common_b[] = {
+static struct validx tbl_sensor_settings_common2[] = {
 	{0x6001, 0x00ff}, {0x6038, 0x000c},
 	{10, 0xffff},
 	{0x6000, 0x0011},
-	/* backlight=31/64 */
-	{0x6001, 0x00ff}, {0x603e, 0x0024}, {0x6034, 0x0025},
-	/* bright=0/256 */
-	{0x6000, 0x00ff}, {0x6009, 0x007c}, {0x6000, 0x007d},
-	/* wbal=64/128 */
-	{0x6000, 0x00ff}, {0x6003, 0x007c}, {0x6040, 0x007d},
-	/* cntr=0/256 */
-	{0x6000, 0x00ff}, {0x6007, 0x007c}, {0x6000, 0x007d},
-	/* sat=128/256 */
-	{0x6000, 0x00ff}, {0x6001, 0x007c}, {0x6080, 0x007d},
-	/* sharpness=0/32 */
-	{0x6000, 0x00ff}, {0x6001, 0x0092}, {0x60c0, 0x0093},
-	/* hue=0/256 */
-	{0x6000, 0x00ff}, {0x6002, 0x007c}, {0x6000, 0x007d},
-	/* gam=32/64 */
-	{0x6000, 0x00ff}, {0x6008, 0x007c}, {0x6020, 0x007d},
-	/* image right up */
-	{0xffff, 0xffff},
-	{15, 0xffff},
-	{0x6001, 0x00ff}, {0x6000, 0x8004},
-	{0xffff, 0xffff},
-	{0x60a8, 0x0004},
-	{15, 0xffff},
-	{0x6001, 0x00ff}, {0x6000, 0x8004},
-	{0xffff, 0xffff},
-	{0x60f8, 0x0004},
-	/* image right up */
-	{0xffff, 0xffff},
-	/* backlight=31/64 */
-	{0x6001, 0x00ff}, {0x603e, 0x0024}, {0x6034, 0x0025},
 };
 
 static struct validx tbl_640[] = {
@@ -166,7 +135,7 @@
 	{0x60ff, 0x00dd}, {0x6020, 0x008c}, {0x6001, 0x00ff}, {0x6044, 0x0018},
 };
 
-static struct validx tbl_big_a[] = {
+static struct validx tbl_big1[] = {
 	{0x0002, 0x00c1}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
 	{0x6001, 0x00ff}, {0x6000, 0x0012}, {0x6000, 0x0000}, {0x6000, 0x0045},
 	{0x6000, 0x0010}, {0x6000, 0x0011}, {0x6011, 0x0017}, {0x6075, 0x0018},
@@ -176,14 +145,14 @@
 	{0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x6000, 0x008c},
 };
 
-static struct validx tbl_big_b[] = {
+static struct validx tbl_big2[] = {
 	{0x603d, 0x0086}, {0x6000, 0x0050}, {0x6090, 0x0051}, {0x602c, 0x0052},
 	{0x6000, 0x0053}, {0x6000, 0x0054}, {0x6088, 0x0055}, {0x6000, 0x0057},
 	{0x6040, 0x005a}, {0x60f0, 0x005b}, {0x6001, 0x005c}, {0x6082, 0x00d3},
 	{0x6000, 0x008e},
 };
 
-static struct validx tbl_big_c[] = {
+static struct validx tbl_big3[] = {
 	{0x6004, 0x00da}, {0x6000, 0x00e0}, {0x6067, 0x00e1}, {0x60ff, 0x00dd},
 	{0x6001, 0x00ff}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
 	{0x6001, 0x00ff}, {0x6000, 0x0011}, {0x6000, 0x00ff}, {0x6010, 0x00c7},
@@ -223,17 +192,19 @@
 	sd->vcur.hue        =   0;
 	sd->vcur.saturation = 128;
 	sd->vcur.whitebal   =  64;
+	sd->vcur.mirror     =   0;
+	sd->vcur.flip       =   0;
 
 	sd->vmax.backlight  =  64;
 	sd->vmax.brightness = 255;
 	sd->vmax.sharpness  =  31;
 	sd->vmax.contrast   = 255;
 	sd->vmax.gamma      =  64;
-	sd->vmax.hue        = 255 + 1;
+	sd->vmax.hue        = 254 + 2;
 	sd->vmax.saturation = 255;
 	sd->vmax.whitebal   = 128;
-	sd->vmax.mirror     = 0;
-	sd->vmax.flip       = 0;
+	sd->vmax.mirror     = 1;
+	sd->vmax.flip       = 1;
 	sd->vmax.AC50Hz     = 0;
 
 	sd->dev_camera_settings = ov2640_camera_settings;
@@ -259,11 +230,11 @@
 
 	common(gspca_dev);
 
-	ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0006, 1, dat_init2);
+	ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0006, 1, c61);
 
 	ctrl_out(gspca_dev, 0x40, 1, 0x00ef, 0x0006, 0, NULL);
 
-	ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, dat_init3);
+	ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c51);
 
 	ctrl_out(gspca_dev, 0x40, 1, 0x0051, 0x0000, 0, NULL);
 /*	ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */
@@ -275,6 +246,8 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
+	sd->mirrorMask = 0;
+
 	sd->vold.backlight  = -1;
 	sd->vold.brightness = -1;
 	sd->vold.sharpness  = -1;
@@ -283,6 +256,8 @@
 	sd->vold.gamma    = -1;
 	sd->vold.hue      = -1;
 	sd->vold.whitebal = -1;
+	sd->vold.mirror = -1;
+	sd->vold.flip   = -1;
 
 	ov2640_init_post_alt(gspca_dev);
 
@@ -292,16 +267,16 @@
 static int ov2640_init_post_alt(struct gspca_dev *gspca_dev)
 {
 	s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
-	s32 n; /* reserved for FETCH macros */
+	s32 n; /* reserved for FETCH functions */
 
 	ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
 
-	n = fetch_validx(gspca_dev, tbl_sensor_settings_common_a,
-			ARRAY_SIZE(tbl_sensor_settings_common_a));
+	n = fetch_validx(gspca_dev, tbl_sensor_settings_common1,
+			ARRAY_SIZE(tbl_sensor_settings_common1));
 	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_post);
 	common(gspca_dev);
-	keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_a,
-				ARRAY_SIZE(tbl_sensor_settings_common_a), n);
+	keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common1,
+				ARRAY_SIZE(tbl_sensor_settings_common1), n);
 
 	switch (reso) {
 	case IMAGE_640:
@@ -316,18 +291,18 @@
 
 	case IMAGE_1600:
 	case IMAGE_1280:
-		n = fetch_validx(gspca_dev, tbl_big_a, ARRAY_SIZE(tbl_big_a));
+		n = fetch_validx(gspca_dev, tbl_big1, ARRAY_SIZE(tbl_big1));
 
 		if (reso == IMAGE_1280) {
-			n = fetch_validx(gspca_dev, tbl_big_b,
-					ARRAY_SIZE(tbl_big_b));
+			n = fetch_validx(gspca_dev, tbl_big2,
+					ARRAY_SIZE(tbl_big2));
 		} else {
 			ctrl_out(gspca_dev, 0x40, 1, 0x601d, 0x0086, 0, NULL);
 			ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00d7, 0, NULL);
 			ctrl_out(gspca_dev, 0x40, 1, 0x6082, 0x00d3, 0, NULL);
 		}
 
-		n = fetch_validx(gspca_dev, tbl_big_c, ARRAY_SIZE(tbl_big_c));
+		n = fetch_validx(gspca_dev, tbl_big3, ARRAY_SIZE(tbl_big3));
 
 		if (reso == IMAGE_1280) {
 			ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
@@ -343,20 +318,8 @@
 		break;
 	}
 
-	n = fetch_validx(gspca_dev, tbl_sensor_settings_common_b,
-			ARRAY_SIZE(tbl_sensor_settings_common_b));
-	ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50);
-	keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
-				ARRAY_SIZE(tbl_sensor_settings_common_b), n);
-	ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, c28);
-	keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
-				ARRAY_SIZE(tbl_sensor_settings_common_b), n);
-	ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, ca8);
-	keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
-				ARRAY_SIZE(tbl_sensor_settings_common_b), n);
-	ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50);
-	keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
-				ARRAY_SIZE(tbl_sensor_settings_common_b), n);
+	n = fetch_validx(gspca_dev, tbl_sensor_settings_common2,
+			ARRAY_SIZE(tbl_sensor_settings_common2));
 
 	ov2640_camera_settings(gspca_dev);
 
@@ -393,18 +356,20 @@
 	s32 sat    = sd->vcur.saturation;
 	s32 hue    = sd->vcur.hue;
 	s32 wbal   = sd->vcur.whitebal;
+	s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) == 0);
+	s32 flip   = (((sd->vcur.flip   > 0) ^ sd->mirrorMask) == 0);
 
 	if (backlight != sd->vold.backlight) {
+		/* No sd->vold.backlight=backlight; (to be done again later) */
 		if (backlight < 0 || backlight > sd->vmax.backlight)
 			backlight = 0;
 
 		ctrl_out(gspca_dev, 0x40, 1, 0x6001                 , 0x00ff,
 				0, NULL);
-		ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight     , 0x0024,
+		ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight     , 0x0024,
 				0, NULL);
-		ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight - 10, 0x0025,
+		ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight - 10, 0x0025,
 				0, NULL);
-		/* No sd->vold.backlight=backlight; (to be done again later) */
 	}
 
 	if (bright != sd->vold.brightness) {
@@ -466,7 +431,7 @@
 		ctrl_out(gspca_dev, 0x40, 1, 0x6002     , 0x007c, 0, NULL);
 		ctrl_out(gspca_dev, 0x40, 1, 0x6000 + hue * (hue < 255), 0x007d,
 				0, NULL);
-		if (hue >= sd->vmax.hue)
+		if (hue >= 255)
 			sd->swapRB = 1;
 		else
 			sd->swapRB = 0;
@@ -482,14 +447,33 @@
 		ctrl_out(gspca_dev, 0x40, 1, 0x6000 + gam, 0x007d, 0, NULL);
 	}
 
+	if (mirror != sd->vold.mirror || flip != sd->vold.flip) {
+		sd->vold.mirror = mirror;
+		sd->vold.flip   = flip;
+
+		mirror = 0x80 * mirror;
+		ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x8004, 0, NULL);
+		ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, c28);
+		ctrl_out(gspca_dev, 0x40, 1, 0x6028 + mirror, 0x0004, 0, NULL);
+
+		flip = 0x50 * flip + mirror;
+		ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x8004, 0, NULL);
+		ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, ca8);
+		ctrl_out(gspca_dev, 0x40, 1, 0x6028 + flip, 0x0004, 0, NULL);
+
+		ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50);
+	}
+
 	if (backlight != sd->vold.backlight) {
 		sd->vold.backlight = backlight;
 
 		ctrl_out(gspca_dev, 0x40, 1, 0x6001                 , 0x00ff,
 				0, NULL);
-		ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight     , 0x0024,
+		ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight     , 0x0024,
 				0, NULL);
-		ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight - 10, 0x0025,
+		ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight - 10, 0x0025,
 				0, NULL);
 	}
 
diff --git a/drivers/media/video/gspca/gl860/gl860-ov9655.c b/drivers/media/video/gspca/gl860/gl860-ov9655.c
index eda3346..d412694 100644
--- a/drivers/media/video/gspca/gl860/gl860-ov9655.c
+++ b/drivers/media/video/gspca/gl860/gl860-ov9655.c
@@ -1,7 +1,6 @@
-/* @file gl860-ov9655.c
- * @author Olivier LORIN, from logs done by Simon (Sur3) and Almighurt
+/* Subdriver for the GL860 chip with the OV9655 sensor
+ * Author Olivier LORIN, from logs done by Simon (Sur3) and Almighurt
  * on dsd's weblog
- * @date 2009-08-27
  *
  * 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
@@ -104,14 +103,14 @@
 };
 
 static u8 c04[] = {0x04};
-static u8 dat_post_1[] = "\x04\x00\x10\x20\xa1\x00\x00\x02";
-static u8 dat_post_2[] = "\x10\x10\xc1\x02";
-static u8 dat_post_3[] = "\x04\x00\x10\x7c\xa1\x00\x00\x04";
-static u8 dat_post_4[] = "\x10\x02\xc1\x06";
-static u8 dat_post_5[] = "\x04\x00\x10\x7b\xa1\x00\x00\x08";
-static u8 dat_post_6[] = "\x10\x10\xc1\x05";
-static u8 dat_post_7[] = "\x04\x00\x10\x7c\xa1\x00\x00\x08";
-static u8 dat_post_8[] = "\x04\x00\x10\x7c\xa1\x00\x00\x09";
+static u8 dat_post1[] = "\x04\x00\x10\x20\xa1\x00\x00\x02";
+static u8 dat_post2[] = "\x10\x10\xc1\x02";
+static u8 dat_post3[] = "\x04\x00\x10\x7c\xa1\x00\x00\x04";
+static u8 dat_post4[] = "\x10\x02\xc1\x06";
+static u8 dat_post5[] = "\x04\x00\x10\x7b\xa1\x00\x00\x08";
+static u8 dat_post6[] = "\x10\x10\xc1\x05";
+static u8 dat_post7[] = "\x04\x00\x10\x7c\xa1\x00\x00\x08";
+static u8 dat_post8[] = "\x04\x00\x10\x7c\xa1\x00\x00\x09";
 
 static struct validx tbl_init_post_alt[] = {
 	{0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x603c, 0x00ff},
@@ -212,7 +211,7 @@
 static int ov9655_init_post_alt(struct gspca_dev *gspca_dev)
 {
 	s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
-	s32 n; /* reserved for FETCH macros */
+	s32 n; /* reserved for FETCH functions */
 	s32 i;
 	u8 **tbl;
 
@@ -243,7 +242,7 @@
 	ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
 	keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
 					ARRAY_SIZE(tbl_init_post_alt), n);
-	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1);
+	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1);
 	keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
 					ARRAY_SIZE(tbl_init_post_alt), n);
 
@@ -259,7 +258,7 @@
 	ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
 	keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
 					ARRAY_SIZE(tbl_init_post_alt), n);
-	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1);
+	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1);
 	keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
 					ARRAY_SIZE(tbl_init_post_alt), n);
 
@@ -270,18 +269,18 @@
 	keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
 					ARRAY_SIZE(tbl_init_post_alt), n);
 
-	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1);
+	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1);
 
-	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_2);
-	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_3);
+	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post2);
+	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post3);
 
-	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_4);
-	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_5);
+	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post4);
+	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post5);
 
-	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_6);
-	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_7);
+	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post6);
+	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post7);
 
-	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_8);
+	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post8);
 
 	ov9655_camera_settings(gspca_dev);
 
diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c
index 6ef59ac..a695e0a 100644
--- a/drivers/media/video/gspca/gl860/gl860.c
+++ b/drivers/media/video/gspca/gl860/gl860.c
@@ -1,9 +1,7 @@
-/* @file gl860.c
- * @date 2009-08-27
+/* GSPCA subdrivers for Genesys Logic webcams with the GL860 chip
+ * Subdriver core
  *
- * Genesys Logic webcam with gl860 subdrivers
- *
- * Driver by Olivier Lorin <o.lorin@laposte.net>
+ * 2009/09/24 Olivier Lorin <o.lorin@laposte.net>
  * GSPCA by Jean-Francois Moine <http://moinejf.free.fr>
  * Thanks BUGabundo and Malmostoso for your amazing help!
  *
@@ -23,8 +21,8 @@
 #include "gspca.h"
 #include "gl860.h"
 
-MODULE_AUTHOR("Olivier Lorin <lorin@laposte.net>");
-MODULE_DESCRIPTION("GSPCA/Genesys Logic GL860 USB Camera Driver");
+MODULE_AUTHOR("Olivier Lorin <o.lorin@laposte.net>");
+MODULE_DESCRIPTION("Genesys Logic USB PC Camera Driver");
 MODULE_LICENSE("GPL");
 
 /*======================== static function declarations ====================*/
@@ -38,7 +36,7 @@
 static int  sd_start(struct gspca_dev *gspca_dev);
 static void sd_stop0(struct gspca_dev *gspca_dev);
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame, u8 *data, s32 len);
+			u8 *data, int len);
 static void sd_callback(struct gspca_dev *gspca_dev);
 
 static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
@@ -53,7 +51,7 @@
 static char sensor[7];
 module_param_string(sensor, sensor, sizeof(sensor), 0644);
 MODULE_PARM_DESC(sensor,
-		" Driver sensor ('MI1320'/'MI2020'/'OV9655'/'OV2640'/'')");
+		" Driver sensor ('MI1320'/'MI2020'/'OV9655'/'OV2640')");
 
 /*============================ webcam controls =============================*/
 
@@ -156,7 +154,7 @@
 	SET_MY_CTRL(V4L2_CID_VFLIP,
 		V4L2_CTRL_TYPE_BOOLEAN, "Flip", flip)
 	SET_MY_CTRL(V4L2_CID_POWER_LINE_FREQUENCY,
-		V4L2_CTRL_TYPE_BOOLEAN, "50Hz", AC50Hz)
+		V4L2_CTRL_TYPE_BOOLEAN, "AC power 50Hz", AC50Hz)
 
 	return nCtrls;
 }
@@ -435,7 +433,7 @@
 
 /* This function is called when an image is being received */
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame, u8 *data, s32 len)
+			u8 *data, int len)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	static s32 nSkipped;
@@ -447,11 +445,11 @@
 	/* Test only against 0202h, so endianess does not matter */
 	switch (*(s16 *) data) {
 	case 0x0202:		/* End of frame, start a new one */
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0);
+		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 		nSkipped = 0;
 		if (sd->nbIm >= 0 && sd->nbIm < 10)
 			sd->nbIm++;
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
 		break;
 
 	default:
@@ -466,7 +464,7 @@
 				nSkipped = nToSkip + 1;
 			}
 			gspca_frame_add(gspca_dev,
-				INTER_PACKET, frame, data, len);
+				INTER_PACKET, data, len);
 		}
 		break;
 	}
@@ -702,6 +700,7 @@
 		ctrl_out(gspca_dev, 0x40, 1, 0x006a, 0x000d, 0, NULL);
 		msleep(56);
 
+		PDEBUG(D_PROBE, "probing for sensor MI2020 or OVXXXX");
 		nOV = 0;
 		for (ntry = 0; ntry < 4; ntry++) {
 			ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
@@ -711,14 +710,14 @@
 			ctrl_out(gspca_dev, 0x40, 1, 0x7a00, 0x8030, 0, NULL);
 			msleep(10);
 			ctrl_in(gspca_dev, 0xc0, 2, 0x7a00, 0x8030, 1, &probe);
-			PDEBUG(D_PROBE, "1st probe=%02x", probe);
+			PDEBUG(D_PROBE, "probe=0x%02x", probe);
 			if (probe == 0xff)
 				nOV++;
 		}
 
 		if (nOV) {
-			PDEBUG(D_PROBE, "0xff -> sensor OVXXXX");
-			PDEBUG(D_PROBE, "Probing for sensor OV2640 or OV9655");
+			PDEBUG(D_PROBE, "0xff -> OVXXXX");
+			PDEBUG(D_PROBE, "probing for sensor OV2640 or OV9655");
 
 			nb26 = nb96 = 0;
 			for (ntry = 0; ntry < 4; ntry++) {
@@ -728,40 +727,38 @@
 				ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x800a,
 						0, NULL);
 				msleep(10);
+
 				/* Wait for 26(OV2640) or 96(OV9655) */
 				ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x800a,
 						1, &probe);
 
-				PDEBUG(D_PROBE, "2nd probe=%02x", probe);
-				if (probe == 0x00)
-					nb26++;
 				if (probe == 0x26 || probe == 0x40) {
+					PDEBUG(D_PROBE,
+						"probe=0x%02x -> OV2640",
+						probe);
 					sd->sensor = ID_OV2640;
 					nb26 += 4;
 					break;
 				}
 				if (probe == 0x96 || probe == 0x55) {
+					PDEBUG(D_PROBE,
+						"probe=0x%02x -> OV9655",
+						probe);
 					sd->sensor = ID_OV9655;
 					nb96 += 4;
 					break;
 				}
+				PDEBUG(D_PROBE, "probe=0x%02x", probe);
+				if (probe == 0x00)
+					nb26++;
 				if (probe == 0xff)
 					nb96++;
 				msleep(3);
 			}
-			if (nb26 < 4 && nb96 < 4) {
-				PDEBUG(D_PROBE, "No relevant answer ");
-				PDEBUG(D_PROBE, "* 1.3Mpixels -> use OV9655");
-				PDEBUG(D_PROBE, "* 2.0Mpixels -> use OV2640");
-				PDEBUG(D_PROBE,
-					"To force a sensor, add that line to "
-					"/etc/modprobe.d/options.conf:");
-				PDEBUG(D_PROBE, "options gspca_gl860 "
-					"sensor=\"OV2640\" or \"OV9655\"");
+			if (nb26 < 4 && nb96 < 4)
 				return -1;
-			}
-		} else { /* probe = 0 */
-			PDEBUG(D_PROBE, "No 0xff -> sensor MI2020");
+		} else {
+			PDEBUG(D_PROBE, "Not any 0xff -> MI2020");
 			sd->sensor = ID_MI2020;
 		}
 	}
diff --git a/drivers/media/video/gspca/gl860/gl860.h b/drivers/media/video/gspca/gl860/gl860.h
index cef4e24..305061f 100644
--- a/drivers/media/video/gspca/gl860/gl860.h
+++ b/drivers/media/video/gspca/gl860/gl860.h
@@ -1,6 +1,7 @@
-/* @file gl860.h
- * @author Olivier LORIN, tiré du pilote Syntek par Nicolas VIVIEN
- * @date 2009-08-27
+/* GSPCA subdrivers for Genesys Logic webcams with the GL860 chip
+ * Subdriver declarations
+ *
+ * 2009/10/14 Olivier LORIN <o.lorin@laposte.net>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 23d3fb7..4076f8e 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -47,7 +47,7 @@
 MODULE_DESCRIPTION("GSPCA USB Camera Driver");
 MODULE_LICENSE("GPL");
 
-#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 7, 0)
+#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 8, 0)
 
 #ifdef GSPCA_DEBUG
 int gspca_debug = D_ERR | D_PROBE;
@@ -74,7 +74,7 @@
 #define PDEBUG_MODE(txt, pixfmt, w, h)
 #endif
 
-/* specific memory types - !! should different from V4L2_MEMORY_xxx */
+/* specific memory types - !! should be different from V4L2_MEMORY_xxx */
 #define GSPCA_MEMORY_NO 0	/* V4L2_MEMORY_xxx starts from 1 */
 #define GSPCA_MEMORY_READ 7
 
@@ -126,7 +126,6 @@
 static void fill_frame(struct gspca_dev *gspca_dev,
 			struct urb *urb)
 {
-	struct gspca_frame *frame;
 	u8 *data;		/* address of data in the iso message */
 	int i, len, st;
 	cam_pkt_op pkt_scan;
@@ -135,21 +134,16 @@
 		if (urb->status == -ESHUTDOWN)
 			return;		/* disconnection */
 #ifdef CONFIG_PM
-		if (!gspca_dev->frozen)
+		if (gspca_dev->frozen)
+			return;
 #endif
-			PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
-		return;
+		PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
+		urb->status = 0;
+		goto resubmit;
 	}
 	pkt_scan = gspca_dev->sd_desc->pkt_scan;
 	for (i = 0; i < urb->number_of_packets; i++) {
 
-		/* check the availability of the frame buffer */
-		frame = gspca_get_i_frame(gspca_dev);
-		if (!frame) {
-			gspca_dev->last_packet_type = DISCARD_PACKET;
-			break;
-		}
-
 		/* check the packet status and length */
 		len = urb->iso_frame_desc[i].actual_length;
 		if (len == 0) {
@@ -171,9 +165,10 @@
 			i, urb->iso_frame_desc[i].offset, len);
 		data = (u8 *) urb->transfer_buffer
 					+ urb->iso_frame_desc[i].offset;
-		pkt_scan(gspca_dev, frame, data, len);
+		pkt_scan(gspca_dev, data, len);
 	}
 
+resubmit:
 	/* resubmit the URB */
 	st = usb_submit_urb(urb, GFP_ATOMIC);
 	if (st < 0)
@@ -201,7 +196,6 @@
 static void bulk_irq(struct urb *urb)
 {
 	struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
-	struct gspca_frame *frame;
 	int st;
 
 	PDEBUG(D_PACK, "bulk irq");
@@ -212,29 +206,22 @@
 		break;
 	case -ESHUTDOWN:
 		return;		/* disconnection */
-	case -ECONNRESET:
-		urb->status = 0;
-		break;
 	default:
 #ifdef CONFIG_PM
-		if (!gspca_dev->frozen)
+		if (gspca_dev->frozen)
+			return;
 #endif
-			PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
-		return;
+		PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
+		urb->status = 0;
+		goto resubmit;
 	}
 
-	/* check the availability of the frame buffer */
-	frame = gspca_get_i_frame(gspca_dev);
-	if (!frame) {
-		gspca_dev->last_packet_type = DISCARD_PACKET;
-	} else {
-		PDEBUG(D_PACK, "packet l:%d", urb->actual_length);
-		gspca_dev->sd_desc->pkt_scan(gspca_dev,
-					frame,
-					urb->transfer_buffer,
-					urb->actual_length);
-	}
+	PDEBUG(D_PACK, "packet l:%d", urb->actual_length);
+	gspca_dev->sd_desc->pkt_scan(gspca_dev,
+				urb->transfer_buffer,
+				urb->actual_length);
 
+resubmit:
 	/* resubmit the URB */
 	if (gspca_dev->cam.bulk_nurbs != 0) {
 		st = usb_submit_urb(urb, GFP_ATOMIC);
@@ -255,24 +242,27 @@
  * DISCARD_PACKET invalidates the whole frame.
  * On LAST_PACKET, a new frame is returned.
  */
-struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
-				    enum gspca_packet_type packet_type,
-				    struct gspca_frame *frame,
-				    const __u8 *data,
-				    int len)
+void gspca_frame_add(struct gspca_dev *gspca_dev,
+			enum gspca_packet_type packet_type,
+			const u8 *data,
+			int len)
 {
+	struct gspca_frame *frame;
 	int i, j;
 
 	PDEBUG(D_PACK, "add t:%d l:%d",	packet_type, len);
 
+	/* check the availability of the frame buffer */
+	frame = gspca_dev->cur_frame;
+	if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
+					!= V4L2_BUF_FLAG_QUEUED) {
+		gspca_dev->last_packet_type = DISCARD_PACKET;
+		return;
+	}
+
 	/* when start of a new frame, if the current frame buffer
 	 * is not queued, discard the whole frame */
 	if (packet_type == FIRST_PACKET) {
-		if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
-						!= V4L2_BUF_FLAG_QUEUED) {
-			gspca_dev->last_packet_type = DISCARD_PACKET;
-			return frame;
-		}
 		frame->data_end = frame->data;
 		jiffies_to_timeval(get_jiffies_64(),
 				   &frame->v4l2_buf.timestamp);
@@ -280,7 +270,7 @@
 	} else if (gspca_dev->last_packet_type == DISCARD_PACKET) {
 		if (packet_type == LAST_PACKET)
 			gspca_dev->last_packet_type = packet_type;
-		return frame;
+		return;
 	}
 
 	/* append the packet to the frame buffer */
@@ -312,9 +302,9 @@
 			i,
 			gspca_dev->fr_o);
 		j = gspca_dev->fr_queue[i];
-		frame = &gspca_dev->frame[j];
+		gspca_dev->cur_frame = &gspca_dev->frame[j];
 	}
-	return frame;
+	return;
 }
 EXPORT_SYMBOL(gspca_frame_add);
 
@@ -395,6 +385,7 @@
 		frame->v4l2_buf.m.offset = i * frsz;
 	}
 	gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0;
+	gspca_dev->cur_frame = &gspca_dev->frame[0];
 	gspca_dev->last_packet_type = DISCARD_PACKET;
 	gspca_dev->sequence = 0;
 	return 0;
@@ -475,10 +466,18 @@
 	xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK
 				   : USB_ENDPOINT_XFER_ISOC;
 	i = gspca_dev->alt;			/* previous alt setting */
-	while (--i >= 0) {
-		ep = alt_xfer(&intf->altsetting[i], xfer);
-		if (ep)
-			break;
+	if (gspca_dev->cam.reverse_alts) {
+		while (++i < gspca_dev->nbalt) {
+			ep = alt_xfer(&intf->altsetting[i], xfer);
+			if (ep)
+				break;
+		}
+	} else {
+		while (--i >= 0) {
+			ep = alt_xfer(&intf->altsetting[i], xfer);
+			if (ep)
+				break;
+		}
 	}
 	if (ep == NULL) {
 		err("no transfer endpoint found");
@@ -599,7 +598,11 @@
 
 	/* set the higher alternate setting and
 	 * loop until urb submit succeeds */
-	gspca_dev->alt = gspca_dev->nbalt;
+	if (gspca_dev->cam.reverse_alts)
+		gspca_dev->alt = 0;
+	else
+		gspca_dev->alt = gspca_dev->nbalt;
+
 	if (gspca_dev->sd_desc->isoc_init) {
 		ret = gspca_dev->sd_desc->isoc_init(gspca_dev);
 		if (ret < 0)
@@ -641,15 +644,19 @@
 		}
 		if (ret >= 0)
 			break;
-		PDEBUG(D_ERR|D_STREAM,
-			"usb_submit_urb alt %d err %d", gspca_dev->alt, ret);
 		gspca_dev->streaming = 0;
 		destroy_urbs(gspca_dev);
-		if (ret != -ENOSPC)
+		if (ret != -ENOSPC) {
+			PDEBUG(D_ERR|D_STREAM,
+				"usb_submit_urb alt %d err %d",
+				gspca_dev->alt, ret);
 			goto out;
+		}
 
 		/* the bandwidth is not wide enough
 		 * negociate or try a lower alternate setting */
+		PDEBUG(D_ERR|D_STREAM,
+			"bandwidth not wide enough - trying again");
 		msleep(20);	/* wait for kill complete */
 		if (gspca_dev->sd_desc->isoc_nego) {
 			ret = gspca_dev->sd_desc->isoc_nego(gspca_dev);
@@ -980,7 +987,7 @@
 {
 	struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev);
 
-	PDEBUG(D_STREAM, "device released");
+	PDEBUG(D_PROBE, "/dev/video%d released", gspca_dev->vdev.num);
 
 	kfree(gspca_dev->usb_buf);
 	kfree(gspca_dev);
@@ -991,7 +998,7 @@
 	struct gspca_dev *gspca_dev;
 	int ret;
 
-	PDEBUG(D_STREAM, "%s open", current->comm);
+	PDEBUG(D_STREAM, "[%s] open", current->comm);
 	gspca_dev = (struct gspca_dev *) video_devdata(file);
 	if (mutex_lock_interruptible(&gspca_dev->queue_lock))
 		return -ERESTARTSYS;
@@ -1037,7 +1044,7 @@
 {
 	struct gspca_dev *gspca_dev = file->private_data;
 
-	PDEBUG(D_STREAM, "%s close", current->comm);
+	PDEBUG(D_STREAM, "[%s] close", current->comm);
 	if (mutex_lock_interruptible(&gspca_dev->queue_lock))
 		return -ERESTARTSYS;
 	gspca_dev->users--;
@@ -1138,10 +1145,13 @@
 		}
 	} else {
 		ctrls = get_ctrl(gspca_dev, id);
+		i = ctrls - gspca_dev->sd_desc->ctrls;
 	}
 	if (ctrls == NULL)
 		return -EINVAL;
 	memcpy(q_ctrl, ctrls, sizeof *q_ctrl);
+	if (gspca_dev->ctrl_inac & (1 << i))
+		q_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
 	return 0;
 }
 
@@ -1603,7 +1613,7 @@
 		size -= PAGE_SIZE;
 	}
 
-	vma->vm_ops = &gspca_vm_ops;
+	vma->vm_ops = (struct vm_operations_struct *) &gspca_vm_ops;
 	vma->vm_private_data = frame;
 	gspca_vm_open(vma);
 	ret = 0;
@@ -2001,11 +2011,15 @@
 	PDEBUG(D_PROBE, "probing %04x:%04x", id->idVendor, id->idProduct);
 
 	/* we don't handle multi-config cameras */
-	if (dev->descriptor.bNumConfigurations != 1)
+	if (dev->descriptor.bNumConfigurations != 1) {
+		PDEBUG(D_ERR, "Too many config");
 		return -ENODEV;
+	}
 	interface = &intf->cur_altsetting->desc;
-	if (interface->bInterfaceNumber > 0)
+	if (interface->bInterfaceNumber > 0) {
+		PDEBUG(D_ERR, "intf != 0");
 		return -ENODEV;
+	}
 
 	/* create the device */
 	if (dev_size < sizeof *gspca_dev)
@@ -2059,7 +2073,7 @@
 	}
 
 	usb_set_intfdata(intf, gspca_dev);
-	PDEBUG(D_PROBE, "probe ok");
+	PDEBUG(D_PROBE, "/dev/video%d created", gspca_dev->vdev.num);
 	return 0;
 out:
 	kfree(gspca_dev->usb_buf);
@@ -2078,6 +2092,7 @@
 {
 	struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
 
+	PDEBUG(D_PROBE, "/dev/video%d disconnect", gspca_dev->vdev.num);
 	mutex_lock(&gspca_dev->usb_lock);
 	gspca_dev->present = 0;
 
@@ -2096,7 +2111,7 @@
 	/* (this will call gspca_release() immediatly or on last close) */
 	video_unregister_device(&gspca_dev->vdev);
 
-	PDEBUG(D_PROBE, "disconnect complete");
+/*	PDEBUG(D_PROBE, "disconnect complete"); */
 }
 EXPORT_SYMBOL(gspca_disconnect);
 
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 70b1fd8..1816173 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -58,6 +58,7 @@
 	u8 npkt;		/* number of packets in an ISOC message
 				 * 0 is the default value: 32 packets */
 	u32 input_flags;	/* value for ENUM_INPUT status flags */
+	char reverse_alts;	/* Alt settings are in high to low order */
 };
 
 struct gspca_dev;
@@ -78,8 +79,7 @@
 typedef int (*cam_qmnu_op) (struct gspca_dev *,
 			struct v4l2_querymenu *);
 typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev,
-				struct gspca_frame *frame,
-				__u8 *data,
+				u8 *data,
 				int len);
 
 struct ctrl {
@@ -142,6 +142,7 @@
 	struct cam cam;				/* device information */
 	const struct sd_desc *sd_desc;		/* subdriver description */
 	unsigned ctrl_dis;		/* disabled controls (bit map) */
+	unsigned ctrl_inac;		/* inactive controls (bit map) */
 
 #define USB_BUF_SZ 64
 	__u8 *usb_buf;				/* buffer for USB exchanges */
@@ -149,6 +150,7 @@
 
 	__u8 *frbuf;				/* buffer for nframes */
 	struct gspca_frame frame[GSPCA_MAX_FRAMES];
+	struct gspca_frame *cur_frame;		/* frame beeing filled */
 	__u32 frsz;				/* frame size */
 	char nframes;				/* number of frames */
 	char fr_i;				/* frame being filled */
@@ -189,11 +191,10 @@
 		int dev_size,
 		struct module *module);
 void gspca_disconnect(struct usb_interface *intf);
-struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
-				    enum gspca_packet_type packet_type,
-				    struct gspca_frame *frame,
-				    const __u8 *data,
-				    int len);
+void gspca_frame_add(struct gspca_dev *gspca_dev,
+			enum gspca_packet_type packet_type,
+			const u8 *data,
+			int len);
 struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev);
 #ifdef CONFIG_PM
 int gspca_suspend(struct usb_interface *intf, pm_message_t message);
diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/video/gspca/jeilinj.c
index a11c97e..2019b04 100644
--- a/drivers/media/video/gspca/jeilinj.c
+++ b/drivers/media/video/gspca/jeilinj.c
@@ -181,11 +181,9 @@
 {
 	struct sd *dev = container_of(work, struct sd, work_struct);
 	struct gspca_dev *gspca_dev = &dev->gspca_dev;
-	struct gspca_frame *frame;
 	int blocks_left; /* 0x200-sized blocks remaining in current frame. */
 	int size_in_blocks;
 	int act_len;
-	int discarding = 0; /* true if we failed to get space for frame. */
 	int packet_type;
 	int ret;
 	u8 *buffer;
@@ -196,15 +194,6 @@
 		goto quit_stream;
 	}
 	while (gspca_dev->present && gspca_dev->streaming) {
-		if (!gspca_dev->present)
-			goto quit_stream;
-		/* Start a new frame, and add the JPEG header, first thing */
-		frame = gspca_get_i_frame(gspca_dev);
-		if (frame && !discarding)
-			gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
-					dev->jpeg_hdr, JPEG_HDR_SZ);
-		 else
-			discarding = 1;
 		/*
 		 * Now request data block 0. Line 0 reports the size
 		 * to download, in blocks of size 0x200, and also tells the
@@ -222,14 +211,15 @@
 		size_in_blocks = buffer[0x0a];
 		blocks_left = buffer[0x0a] - 1;
 		PDEBUG(D_STREAM, "blocks_left = 0x%x", blocks_left);
-		packet_type = INTER_PACKET;
-		if (frame && !discarding)
-			/* Toss line 0 of data block 0, keep the rest. */
-			gspca_frame_add(gspca_dev, packet_type,
-				frame, buffer + FRAME_HEADER_LEN,
+
+		/* Start a new frame, and add the JPEG header, first thing */
+		gspca_frame_add(gspca_dev, FIRST_PACKET,
+				dev->jpeg_hdr, JPEG_HDR_SZ);
+		/* Toss line 0 of data block 0, keep the rest. */
+		gspca_frame_add(gspca_dev, INTER_PACKET,
+				buffer + FRAME_HEADER_LEN,
 				JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN);
-			else
-				discarding = 1;
+
 		while (blocks_left > 0) {
 			if (!gspca_dev->present)
 				goto quit_stream;
@@ -246,12 +236,8 @@
 				packet_type = LAST_PACKET;
 			else
 				packet_type = INTER_PACKET;
-			if (frame && !discarding)
-				gspca_frame_add(gspca_dev, packet_type,
-						frame, buffer,
-						JEILINJ_MAX_TRANSFER);
-			else
-				discarding = 1;
+			gspca_frame_add(gspca_dev, packet_type,
+					buffer, JEILINJ_MAX_TRANSFER);
 		}
 	}
 quit_stream:
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index 7f1e541..844fc1d 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -274,8 +274,7 @@
 }
 
 static void m5602_urb_complete(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,
-			__u8 *data, int len)
+				u8 *data, int len)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
@@ -295,19 +294,27 @@
 		len -= 6;
 
 		/* Complete the last frame (if any) */
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET,
-					frame, data, 0);
+		gspca_frame_add(gspca_dev, LAST_PACKET,
+				NULL, 0);
 		sd->frame_count++;
 
 		/* Create a new frame */
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 
 		PDEBUG(D_FRAM, "Starting new frame %d",
 		       sd->frame_count);
 
 	} else {
-		int cur_frame_len = frame->data_end - frame->data;
+		struct gspca_frame *frame;
+		int cur_frame_len;
 
+		frame = gspca_get_i_frame(gspca_dev);
+		if (frame == NULL) {
+			gspca_dev->last_packet_type = DISCARD_PACKET;
+			return;
+		}
+
+		cur_frame_len = frame->data_end - frame->data;
 		/* Remove urb header */
 		data += 4;
 		len -= 4;
@@ -316,12 +323,12 @@
 			PDEBUG(D_FRAM, "Continuing frame %d copying %d bytes",
 			       sd->frame_count, len);
 
-			gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+			gspca_frame_add(gspca_dev, INTER_PACKET,
 					data, len);
 		} else if (frame->v4l2_buf.length - cur_frame_len > 0) {
 			/* Add the remaining data up to frame size */
-			gspca_frame_add(gspca_dev, INTER_PACKET, frame, data,
-					frame->v4l2_buf.length - cur_frame_len);
+			gspca_frame_add(gspca_dev, INTER_PACKET, data,
+				    frame->v4l2_buf.length - cur_frame_len);
 		}
 	}
 }
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
index de769ca..9cf8d68 100644
--- a/drivers/media/video/gspca/mars.c
+++ b/drivers/media/video/gspca/mars.c
@@ -325,8 +325,7 @@
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -348,11 +347,11 @@
 			    || data[5 + p] == 0x67) {
 				PDEBUG(D_PACK, "sof offset: %d len: %d",
 					p, len);
-				frame = gspca_frame_add(gspca_dev, LAST_PACKET,
-							frame, data, p);
+				gspca_frame_add(gspca_dev, LAST_PACKET,
+						data, p);
 
 				/* put the JPEG header */
-				gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+				gspca_frame_add(gspca_dev, FIRST_PACKET,
 					sd->jpeg_hdr, JPEG_HDR_SZ);
 				data += p + 16;
 				len -= p + 16;
@@ -360,7 +359,7 @@
 			}
 		}
 	}
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
index f8328b9..126d968 100644
--- a/drivers/media/video/gspca/mr97310a.c
+++ b/drivers/media/video/gspca/mr97310a.c
@@ -1,23 +1,30 @@
 /*
  * Mars MR97310A library
  *
+ * The original mr97310a driver, which supported the Aiptek Pencam VGA+, is
  * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com>
  *
  * Support for the MR97310A cameras in addition to the Aiptek Pencam VGA+
  * and for the routines for detecting and classifying these various cameras,
+ * is Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
  *
+ * Support for the control settings for the CIF cameras is
+ * Copyright (C) 2009 Hans de Goede <hdgoede@redhat.com> and
+ * Thomas Kaiser <thomas@kaiser-linux.li>
+ *
+ * Support for the control settings for the VGA cameras is
  * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
  *
- * Acknowledgements:
+ * Several previously unsupported cameras are owned and have been tested by
+ * Hans de Goede <hdgoede@redhat.com> and
+ * Thomas Kaiser <thomas@kaiser-linux.li> and
+ * Theodore Kilgore <kilgota@auburn.edu> and
+ * Edmond Rodriguez <erodrig_97@yahoo.com> and
+ * Aurelien Jacobs <aurel@gnuage.org>
  *
  * The MR97311A support in gspca/mars.c has been helpful in understanding some
  * of the registers in these cameras.
  *
- * Hans de Goede <hdgoede@redhat.com> and
- * Thomas Kaiser <thomas@kaiser-linux.li>
- * have assisted with their experience. Each of them has also helped by
- * testing a previously unsupported camera.
- *
  * 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
@@ -40,11 +47,9 @@
 #define CAM_TYPE_CIF			0
 #define CAM_TYPE_VGA			1
 
-#define MR97310A_BRIGHTNESS_MIN		-254
-#define MR97310A_BRIGHTNESS_MAX		255
 #define MR97310A_BRIGHTNESS_DEFAULT	0
 
-#define MR97310A_EXPOSURE_MIN		300
+#define MR97310A_EXPOSURE_MIN		0
 #define MR97310A_EXPOSURE_MAX		4095
 #define MR97310A_EXPOSURE_DEFAULT	1000
 
@@ -52,6 +57,10 @@
 #define MR97310A_GAIN_MAX		31
 #define MR97310A_GAIN_DEFAULT		25
 
+#define MR97310A_MIN_CLOCKDIV_MIN	3
+#define MR97310A_MIN_CLOCKDIV_MAX	8
+#define MR97310A_MIN_CLOCKDIV_DEFAULT	3
+
 MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>,"
 	      "Theodore Kilgore <kilgota@auburn.edu>");
 MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");
@@ -69,10 +78,12 @@
 	u8 cam_type;	/* 0 is CIF and 1 is VGA */
 	u8 sensor_type;	/* We use 0 and 1 here, too. */
 	u8 do_lcd_stop;
+	u8 adj_colors;
 
 	int brightness;
 	u16 exposure;
 	u8 gain;
+	u8 min_clockdiv;
 };
 
 struct sensor_w_data {
@@ -82,26 +93,31 @@
 	int len;
 };
 
+static void sd_stopN(struct gspca_dev *gspca_dev);
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val);
 static void setbrightness(struct gspca_dev *gspca_dev);
 static void setexposure(struct gspca_dev *gspca_dev);
 static void setgain(struct gspca_dev *gspca_dev);
 
 /* V4L2 controls supported by the driver */
 static struct ctrl sd_ctrls[] = {
+/* Separate brightness control description for Argus QuickClix as it has
+   different limits from the other mr97310a cameras */
 	{
-#define BRIGHTNESS_IDX 0
+#define NORM_BRIGHTNESS_IDX 0
 		{
 			.id = V4L2_CID_BRIGHTNESS,
 			.type = V4L2_CTRL_TYPE_INTEGER,
 			.name = "Brightness",
-			.minimum = MR97310A_BRIGHTNESS_MIN,
-			.maximum = MR97310A_BRIGHTNESS_MAX,
+			.minimum = -254,
+			.maximum = 255,
 			.step = 1,
 			.default_value = MR97310A_BRIGHTNESS_DEFAULT,
 			.flags = 0,
@@ -110,7 +126,22 @@
 		.get = sd_getbrightness,
 	},
 	{
-#define EXPOSURE_IDX 1
+#define ARGUS_QC_BRIGHTNESS_IDX 1
+		{
+			.id = V4L2_CID_BRIGHTNESS,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "Brightness",
+			.minimum = 0,
+			.maximum = 15,
+			.step = 1,
+			.default_value = MR97310A_BRIGHTNESS_DEFAULT,
+			.flags = 0,
+		},
+		.set = sd_setbrightness,
+		.get = sd_getbrightness,
+	},
+	{
+#define EXPOSURE_IDX 2
 		{
 			.id = V4L2_CID_EXPOSURE,
 			.type = V4L2_CTRL_TYPE_INTEGER,
@@ -125,7 +156,7 @@
 		.get = sd_getexposure,
 	},
 	{
-#define GAIN_IDX 2
+#define GAIN_IDX 3
 		{
 			.id = V4L2_CID_GAIN,
 			.type = V4L2_CTRL_TYPE_INTEGER,
@@ -139,6 +170,21 @@
 		.set = sd_setgain,
 		.get = sd_getgain,
 	},
+	{
+#define MIN_CLOCKDIV_IDX 4
+		{
+			.id = V4L2_CID_PRIVATE_BASE,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "Minimum Clock Divider",
+			.minimum = MR97310A_MIN_CLOCKDIV_MIN,
+			.maximum = MR97310A_MIN_CLOCKDIV_MAX,
+			.step = 1,
+			.default_value = MR97310A_MIN_CLOCKDIV_DEFAULT,
+			.flags = 0,
+		},
+		.set = sd_setmin_clockdiv,
+		.get = sd_getmin_clockdiv,
+	},
 };
 
 static const struct v4l2_pix_format vga_mode[] = {
@@ -230,12 +276,17 @@
 	int rc;
 
 	buf = data;
-	rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1);
+	if (sd->cam_type == CAM_TYPE_CIF) {
+		rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1);
+		confirm_reg = sd->sensor_type ? 0x13 : 0x11;
+	} else {
+		rc = sensor_write_reg(gspca_dev, reg, 0x00, &buf, 1);
+		confirm_reg = 0x11;
+	}
 	if (rc < 0)
 		return rc;
 
 	buf = 0x01;
-	confirm_reg = sd->sensor_type ? 0x13 : 0x11;
 	rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1);
 	if (rc < 0)
 		return rc;
@@ -243,18 +294,26 @@
 	return 0;
 }
 
-static int cam_get_response16(struct gspca_dev *gspca_dev)
+static int cam_get_response16(struct gspca_dev *gspca_dev, u8 reg, int verbose)
 {
-	__u8 *data = gspca_dev->usb_buf;
 	int err_code;
 
-	data[0] = 0x21;
+	gspca_dev->usb_buf[0] = reg;
 	err_code = mr_write(gspca_dev, 1);
 	if (err_code < 0)
 		return err_code;
 
 	err_code = mr_read(gspca_dev, 16);
-	return err_code;
+	if (err_code < 0)
+		return err_code;
+
+	if (verbose)
+		PDEBUG(D_PROBE, "Register: %02x reads %02x%02x%02x", reg,
+		       gspca_dev->usb_buf[0],
+		       gspca_dev->usb_buf[1],
+		       gspca_dev->usb_buf[2]);
+
+	return 0;
 }
 
 static int zero_the_pointer(struct gspca_dev *gspca_dev)
@@ -264,7 +323,7 @@
 	u8 status = 0;
 	int tries = 0;
 
-	err_code = cam_get_response16(gspca_dev);
+	err_code = cam_get_response16(gspca_dev, 0x21, 0);
 	if (err_code < 0)
 		return err_code;
 
@@ -275,7 +334,7 @@
 	if (err_code < 0)
 		return err_code;
 
-	err_code = cam_get_response16(gspca_dev);
+	err_code = cam_get_response16(gspca_dev, 0x21, 0);
 	if (err_code < 0)
 		return err_code;
 
@@ -285,7 +344,7 @@
 	if (err_code < 0)
 		return err_code;
 
-	err_code = cam_get_response16(gspca_dev);
+	err_code = cam_get_response16(gspca_dev, 0x21, 0);
 	if (err_code < 0)
 		return err_code;
 
@@ -295,7 +354,7 @@
 	if (err_code < 0)
 		return err_code;
 
-	err_code = cam_get_response16(gspca_dev);
+	err_code = cam_get_response16(gspca_dev, 0x21, 0);
 	if (err_code < 0)
 		return err_code;
 
@@ -306,7 +365,7 @@
 		return err_code;
 
 	while (status != 0x0a && tries < 256) {
-		err_code = cam_get_response16(gspca_dev);
+		err_code = cam_get_response16(gspca_dev, 0x21, 0);
 		status = data[0];
 		tries++;
 		if (err_code < 0)
@@ -323,7 +382,7 @@
 		if (err_code < 0)
 			return err_code;
 
-		err_code = cam_get_response16(gspca_dev);
+		err_code = cam_get_response16(gspca_dev, 0x21, 0);
 		status = data[0];
 		tries++;
 		if (err_code < 0)
@@ -342,89 +401,202 @@
 	return 0;
 }
 
-static u8 get_sensor_id(struct gspca_dev *gspca_dev)
+static int stream_start(struct gspca_dev *gspca_dev)
 {
-	int err_code;
-
-	gspca_dev->usb_buf[0] = 0x1e;
-	err_code = mr_write(gspca_dev, 1);
-	if (err_code < 0)
-		return err_code;
-
-	err_code = mr_read(gspca_dev, 16);
-	if (err_code < 0)
-		return err_code;
-
-	PDEBUG(D_PROBE, "Byte zero reported is %01x", gspca_dev->usb_buf[0]);
-
-	return gspca_dev->usb_buf[0];
+	gspca_dev->usb_buf[0] = 0x01;
+	gspca_dev->usb_buf[1] = 0x01;
+	return mr_write(gspca_dev, 2);
 }
 
-/* this function is called at probe time */
+static void stream_stop(struct gspca_dev *gspca_dev)
+{
+	gspca_dev->usb_buf[0] = 0x01;
+	gspca_dev->usb_buf[1] = 0x00;
+	if (mr_write(gspca_dev, 2) < 0)
+		PDEBUG(D_ERR, "Stream Stop failed");
+}
+
+static void lcd_stop(struct gspca_dev *gspca_dev)
+{
+	gspca_dev->usb_buf[0] = 0x19;
+	gspca_dev->usb_buf[1] = 0x54;
+	if (mr_write(gspca_dev, 2) < 0)
+		PDEBUG(D_ERR, "LCD Stop failed");
+}
+
+static int isoc_enable(struct gspca_dev *gspca_dev)
+{
+	gspca_dev->usb_buf[0] = 0x00;
+	gspca_dev->usb_buf[1] = 0x4d;  /* ISOC transfering enable... */
+	return mr_write(gspca_dev, 2);
+}
+
+/* This function is called at probe time */
 static int sd_config(struct gspca_dev *gspca_dev,
 		     const struct usb_device_id *id)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam;
-	__u8 *data = gspca_dev->usb_buf;
 	int err_code;
 
 	cam = &gspca_dev->cam;
 	cam->cam_mode = vga_mode;
 	cam->nmodes = ARRAY_SIZE(vga_mode);
+	sd->do_lcd_stop = 0;
 
-	if (id->idProduct == 0x010e) {
+	/* Several of the supported CIF cameras share the same USB ID but
+	 * require different initializations and different control settings.
+	 * The same is true of the VGA cameras. Therefore, we are forced
+	 * to start the initialization process in order to determine which
+	 * camera is present. Some of the supported cameras require the
+	 * memory pointer to be set to 0 as the very first item of business
+	 * or else they will not stream. So we do that immediately.
+	 */
+	err_code = zero_the_pointer(gspca_dev);
+	if (err_code < 0)
+		return err_code;
+
+	err_code = stream_start(gspca_dev);
+	if (err_code < 0)
+		return err_code;
+
+	if (id->idProduct == 0x0110 || id->idProduct == 0x010e) {
 		sd->cam_type = CAM_TYPE_CIF;
 		cam->nmodes--;
+		err_code = cam_get_response16(gspca_dev, 0x06, 1);
+		if (err_code < 0)
+			return err_code;
+		/*
+		 * All but one of the known CIF cameras share the same USB ID,
+		 * but two different init routines are in use, and the control
+		 * settings are different, too. We need to detect which camera
+		 * of the two known varieties is connected!
+		 *
+		 * A list of known CIF cameras follows. They all report either
+		 * 0002 for type 0 or 0003 for type 1.
+		 * If you have another to report, please do
+		 *
+		 * Name		sd->sensor_type		reported by
+		 *
+		 * Sakar Spy-shot	0		T. Kilgore
+		 * Innovage		0		T. Kilgore
+		 * Vivitar Mini		0		H. De Goede
+		 * Vivitar Mini		0		E. Rodriguez
+		 * Vivitar Mini		1		T. Kilgore
+		 * Elta-Media 8212dc	1		T. Kaiser
+		 * Philips dig. keych.	1		T. Kilgore
+		 * Trust Spyc@m 100	1		A. Jacobs
+		 */
+		switch (gspca_dev->usb_buf[1]) {
+		case 2:
+			sd->sensor_type = 0;
+			break;
+		case 3:
+			sd->sensor_type = 1;
+			break;
+		default:
+			PDEBUG(D_ERR, "Unknown CIF Sensor id : %02x",
+			       gspca_dev->usb_buf[1]);
+			return -ENODEV;
+		}
+		PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d",
+		       sd->sensor_type);
+	} else {
+		sd->cam_type = CAM_TYPE_VGA;
 
-		data[0] = 0x01;
-		data[1] = 0x01;
-		err_code = mr_write(gspca_dev, 2);
+		err_code = cam_get_response16(gspca_dev, 0x07, 1);
 		if (err_code < 0)
 			return err_code;
 
-		msleep(200);
-		data[0] = get_sensor_id(gspca_dev);
 		/*
-		 * Known CIF cameras. If you have another to report, please do
+		 * Here is a table of the responses to the previous command
+		 * from the known MR97310A VGA cameras.
 		 *
-		 * Name			byte just read		sd->sensor_type
-		 *					reported by
-		 * Sakar Spy-shot	0x28		T. Kilgore	0
-		 * Innovage		0xf5 (unstable)	T. Kilgore	0
-		 * Vivitar Mini		0x53		H. De Goede	0
-		 * Vivitar Mini		0x04 / 0x24	E. Rodriguez	0
-		 * Vivitar Mini		0x08		T. Kilgore	1
-		 * Elta-Media 8212dc	0x23		T. Kaiser	1
-		 * Philips dig. keych.	0x37		T. Kilgore	1
+		 * Name			gspca_dev->usb_buf[]	sd->sensor_type
+		 *				sd->do_lcd_stop
+		 * Aiptek Pencam VGA+	0300		0		1
+		 * ION digital		0350		0		1
+		 * Argus DC-1620	0450		1		0
+		 * Argus QuickClix	0420		1		1
+		 *
+		 * Based upon these results, we assume default settings
+		 * and then correct as necessary, as follows.
+		 *
 		 */
-		if ((data[0] & 0x78) == 8 ||
-		    ((data[0] & 0x2) == 0x2 && data[0] != 0x53))
-			sd->sensor_type = 1;
-		else
-			sd->sensor_type = 0;
 
-		PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d",
-		       sd->sensor_type);
-
-		if (force_sensor_type != -1) {
-			sd->sensor_type = !! force_sensor_type;
-			PDEBUG(D_PROBE, "Forcing sensor type to: %d",
-			       sd->sensor_type);
+		sd->sensor_type = 1;
+		sd->do_lcd_stop = 0;
+		sd->adj_colors = 0;
+		if ((gspca_dev->usb_buf[0] != 0x03) &&
+					(gspca_dev->usb_buf[0] != 0x04)) {
+			PDEBUG(D_ERR, "Unknown VGA Sensor id Byte 0: %02x",
+					gspca_dev->usb_buf[1]);
+			PDEBUG(D_ERR, "Defaults assumed, may not work");
+			PDEBUG(D_ERR, "Please report this");
 		}
+		/* Sakar Digital color needs to be adjusted. */
+		if ((gspca_dev->usb_buf[0] == 0x03) &&
+					(gspca_dev->usb_buf[1] == 0x50))
+			sd->adj_colors = 1;
+		if (gspca_dev->usb_buf[0] == 0x04) {
+			sd->do_lcd_stop = 1;
+			switch (gspca_dev->usb_buf[1]) {
+			case 0x50:
+				sd->sensor_type = 0;
+				PDEBUG(D_PROBE, "sensor_type corrected to 0");
+				break;
+			case 0x20:
+				/* Nothing to do here. */
+				break;
+			default:
+				PDEBUG(D_ERR,
+					"Unknown VGA Sensor id Byte 1: %02x",
+					gspca_dev->usb_buf[1]);
+				PDEBUG(D_ERR,
+					"Defaults assumed, may not work");
+				PDEBUG(D_ERR, "Please report this");
+			}
+		}
+		PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d",
+		       sd->sensor_type);
+	}
+	/* Stop streaming as we've started it to probe the sensor type. */
+	sd_stopN(gspca_dev);
 
+	if (force_sensor_type != -1) {
+		sd->sensor_type = !!force_sensor_type;
+		PDEBUG(D_PROBE, "Forcing sensor type to: %d",
+		       sd->sensor_type);
+	}
+
+	/* Setup controls depending on camera type */
+	if (sd->cam_type == CAM_TYPE_CIF) {
+		/* No brightness for sensor_type 0 */
 		if (sd->sensor_type == 0)
-			gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX);
+			gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
+					      (1 << ARGUS_QC_BRIGHTNESS_IDX);
+		else
+			gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) |
+					      (1 << MIN_CLOCKDIV_IDX);
 	} else {
-		sd->cam_type = CAM_TYPE_VGA;
-		PDEBUG(D_PROBE, "MR97310A VGA camera detected");
-		gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX) |
-				      (1 << EXPOSURE_IDX) | (1 << GAIN_IDX);
+		/* All controls need to be disabled if VGA sensor_type is 0 */
+		if (sd->sensor_type == 0)
+			gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
+					      (1 << ARGUS_QC_BRIGHTNESS_IDX) |
+					      (1 << EXPOSURE_IDX) |
+					      (1 << GAIN_IDX) |
+					      (1 << MIN_CLOCKDIV_IDX);
+		else if (sd->do_lcd_stop)
+			/* Argus QuickClix has different brightness limits */
+			gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX);
+		else
+			gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX);
 	}
 
 	sd->brightness = MR97310A_BRIGHTNESS_DEFAULT;
 	sd->exposure = MR97310A_EXPOSURE_DEFAULT;
 	sd->gain = MR97310A_GAIN_DEFAULT;
+	sd->min_clockdiv = MR97310A_MIN_CLOCKDIV_DEFAULT;
 
 	return 0;
 }
@@ -455,11 +627,6 @@
 	};
 
 	/* Note: Some of the above descriptions guessed from MR97113A driver */
-	data[0] = 0x01;
-	data[1] = 0x01;
-	err_code = mr_write(gspca_dev, 2);
-	if (err_code < 0)
-		return err_code;
 
 	memcpy(data, startup_string, 11);
 	if (sd->sensor_type)
@@ -533,22 +700,7 @@
 		err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
 					 ARRAY_SIZE(cif_sensor1_init_data));
 	}
-	if (err_code < 0)
-		return err_code;
-
-	setbrightness(gspca_dev);
-	setexposure(gspca_dev);
-	setgain(gspca_dev);
-
-	msleep(200);
-
-	data[0] = 0x00;
-	data[1] = 0x4d;  /* ISOC transfering enable... */
-	err_code = mr_write(gspca_dev, 2);
-	if (err_code < 0)
-		return err_code;
-
-	return 0;
+	return err_code;
 }
 
 static int start_vga_cam(struct gspca_dev *gspca_dev)
@@ -558,84 +710,8 @@
 	int err_code;
 	const __u8 startup_string[] = {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b,
 				       0x00, 0x00, 0x00, 0x50, 0xc0};
-
 	/* What some of these mean is explained in start_cif_cam(), above */
-	sd->sof_read = 0;
 
-	/*
-	 * We have to know which camera we have, because the register writes
-	 * depend upon the camera. This test, run before we actually enter
-	 * the initialization routine, distinguishes most of the cameras, If
-	 * needed, another routine is done later, too.
-	 */
-	memset(data, 0, 16);
-	data[0] = 0x20;
-	err_code = mr_write(gspca_dev, 1);
-	if (err_code < 0)
-		return err_code;
-
-	err_code = mr_read(gspca_dev, 16);
-	if (err_code < 0)
-		return err_code;
-
-	PDEBUG(D_PROBE, "Byte reported is %02x", data[0]);
-
-	msleep(200);
-	/*
-	 * Known VGA cameras. If you have another to report, please do
-	 *
-	 * Name			byte just read		sd->sensor_type
-	 *				sd->do_lcd_stop
-	 * Aiptek Pencam VGA+	0x31		0	1
-	 * ION digital		0x31		0	1
-	 * Argus DC-1620	0x30		1	0
-	 * Argus QuickClix	0x30		1	1 (not caught here)
-	 */
-	sd->sensor_type = data[0] & 1;
-	sd->do_lcd_stop = (~data[0]) & 1;
-
-
-
-	/* Streaming setup begins here. */
-
-
-	data[0] = 0x01;
-	data[1] = 0x01;
-	err_code = mr_write(gspca_dev, 2);
-	if (err_code < 0)
-		return err_code;
-
-	/*
-	 * A second test can now resolve any remaining ambiguity in the
-	 * identification of the camera type,
-	 */
-	if (!sd->sensor_type) {
-		data[0] = get_sensor_id(gspca_dev);
-		if (data[0] == 0x7f) {
-			sd->sensor_type = 1;
-			PDEBUG(D_PROBE, "sensor_type corrected to 1");
-		}
-		msleep(200);
-	}
-
-	if (force_sensor_type != -1) {
-		sd->sensor_type = !! force_sensor_type;
-		PDEBUG(D_PROBE, "Forcing sensor type to: %d",
-		       sd->sensor_type);
-	}
-
-	/*
-	 * Known VGA cameras.
-	 * This test is only run if the previous test returned 0x30, but
-	 * here is the information for all others, too, just for reference.
-	 *
-	 * Name			byte just read		sd->sensor_type
-	 *
-	 * Aiptek Pencam VGA+	0xfb	(this test not run)	1
-	 * ION digital		0xbd	(this test not run)	1
-	 * Argus DC-1620	0xe5	(no change)		0
-	 * Argus QuickClix	0x7f	(reclassified)		1
-	 */
 	memcpy(data, startup_string, 11);
 	if (!sd->sensor_type) {
 		data[5]  = 0x00;
@@ -689,29 +765,44 @@
 		err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
 					 ARRAY_SIZE(vga_sensor0_init_data));
 	} else {	/* sd->sensor_type = 1 */
-		const struct sensor_w_data vga_sensor1_init_data[] = {
+		const struct sensor_w_data color_adj[] = {
 			{0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
-				0x07, 0x00, 0x01}, 8},
+				/* adjusted blue, green, red gain correct
+				   too much blue from the Sakar Digital */
+				0x05, 0x01, 0x04}, 8}
+		};
+
+		const struct sensor_w_data color_no_adj[] = {
+			{0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
+				/* default blue, green, red gain settings */
+				0x07, 0x00, 0x01}, 8}
+		};
+
+		const struct sensor_w_data vga_sensor1_init_data[] = {
 			{0x11, 0x04, {0x01}, 1},
-			/*{0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01, */
-			{0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01,
+			{0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01,
+			/* These settings may be better for some cameras */
+			/* {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01, */
 				0x00, 0x0a}, 7},
 			{0x11, 0x04, {0x01}, 1},
 			{0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6},
 			{0x11, 0x04, {0x01}, 1},
 			{0, 0, {0}, 0}
 		};
+
+		if (sd->adj_colors)
+			err_code = sensor_write_regs(gspca_dev, color_adj,
+					 ARRAY_SIZE(color_adj));
+		else
+			err_code = sensor_write_regs(gspca_dev, color_no_adj,
+					 ARRAY_SIZE(color_no_adj));
+
+		if (err_code < 0)
+			return err_code;
+
 		err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
 					 ARRAY_SIZE(vga_sensor1_init_data));
 	}
-	if (err_code < 0)
-		return err_code;
-
-	msleep(200);
-	data[0] = 0x00;
-	data[1] = 0x4d;  /* ISOC transfering enable... */
-	err_code = mr_write(gspca_dev, 2);
-
 	return err_code;
 }
 
@@ -719,97 +810,120 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int err_code;
-	struct cam *cam;
 
-	cam = &gspca_dev->cam;
 	sd->sof_read = 0;
-	/*
-	 * Some of the supported cameras require the memory pointer to be
-	 * set to 0, or else they will not stream.
-	 */
-	zero_the_pointer(gspca_dev);
-	msleep(200);
+
+	/* Some of the VGA cameras require the memory pointer
+	 * to be set to 0 again. We have been forced to start the
+	 * stream in sd_config() to detect the hardware, and closed it.
+	 * Thus, we need here to do a completely fresh and clean start. */
+	err_code = zero_the_pointer(gspca_dev);
+	if (err_code < 0)
+		return err_code;
+
+	err_code = stream_start(gspca_dev);
+	if (err_code < 0)
+		return err_code;
+
 	if (sd->cam_type == CAM_TYPE_CIF) {
 		err_code = start_cif_cam(gspca_dev);
 	} else {
 		err_code = start_vga_cam(gspca_dev);
 	}
-	return err_code;
+	if (err_code < 0)
+		return err_code;
+
+	setbrightness(gspca_dev);
+	setexposure(gspca_dev);
+	setgain(gspca_dev);
+
+	return isoc_enable(gspca_dev);
 }
 
 static void sd_stopN(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int result;
 
-	gspca_dev->usb_buf[0] = 1;
-	gspca_dev->usb_buf[1] = 0;
-	result = mr_write(gspca_dev, 2);
-	if (result < 0)
-		PDEBUG(D_ERR, "Camera Stop failed");
-
+	stream_stop(gspca_dev);
 	/* Not all the cams need this, but even if not, probably a good idea */
 	zero_the_pointer(gspca_dev);
-	if (sd->do_lcd_stop) {
-		gspca_dev->usb_buf[0] = 0x19;
-		gspca_dev->usb_buf[1] = 0x54;
-		result = mr_write(gspca_dev, 2);
-		if (result < 0)
-			PDEBUG(D_ERR, "Camera Stop failed");
-	}
+	if (sd->do_lcd_stop)
+		lcd_stop(gspca_dev);
 }
 
 static void setbrightness(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	u8 val;
-
-	if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS_IDX))
+	u8 sign_reg = 7;  /* This reg and the next one used on CIF cams. */
+	u8 value_reg = 8; /* VGA cams seem to use regs 0x0b and 0x0c */
+	const u8 quick_clix_table[] =
+	/*	  0  1  2   3  4  5  6  7  8  9  10  11  12  13  14  15 */
+		{ 0, 4, 8, 12, 1, 2, 3, 5, 6, 9,  7, 10, 13, 11, 14, 15};
+	/*
+	 * This control is disabled for CIF type 1 and VGA type 0 cameras.
+	 * It does not quite act linearly for the Argus QuickClix camera,
+	 * but it does control brightness. The values are 0 - 15 only, and
+	 * the table above makes them act consecutively.
+	 */
+	if ((gspca_dev->ctrl_dis & (1 << NORM_BRIGHTNESS_IDX)) &&
+	    (gspca_dev->ctrl_dis & (1 << ARGUS_QC_BRIGHTNESS_IDX)))
 		return;
 
-	/* Note register 7 is also seen as 0x8x or 0xCx in dumps */
+	if (sd->cam_type == CAM_TYPE_VGA) {
+		sign_reg += 4;
+		value_reg += 4;
+	}
+
+	/* Note register 7 is also seen as 0x8x or 0xCx in some dumps */
 	if (sd->brightness > 0) {
-		sensor_write1(gspca_dev, 7, 0x00);
+		sensor_write1(gspca_dev, sign_reg, 0x00);
 		val = sd->brightness;
 	} else {
-		sensor_write1(gspca_dev, 7, 0x01);
-		val = 257 - sd->brightness;
+		sensor_write1(gspca_dev, sign_reg, 0x01);
+		val = (257 - sd->brightness);
 	}
-	sensor_write1(gspca_dev, 8, val);
+	/* Use lookup table for funky Argus QuickClix brightness */
+	if (sd->do_lcd_stop)
+		val = quick_clix_table[val];
+
+	sensor_write1(gspca_dev, value_reg, val);
 }
 
 static void setexposure(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	u8 val;
+	int exposure;
+	u8 buf[2];
 
 	if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX))
 		return;
 
-	if (sd->sensor_type) {
-		val = sd->exposure >> 4;
-		sensor_write1(gspca_dev, 3, val);
-		val = sd->exposure & 0xf;
-		sensor_write1(gspca_dev, 4, val);
+	if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) {
+		/* This cam does not like exposure settings < 300,
+		   so scale 0 - 4095 to 300 - 4095 */
+		exposure = (sd->exposure * 9267) / 10000 + 300;
+		sensor_write1(gspca_dev, 3, exposure >> 4);
+		sensor_write1(gspca_dev, 4, exposure & 0x0f);
 	} else {
-		u8 clockdiv;
-		int exposure;
-
 		/* We have both a clock divider and an exposure register.
 		   We first calculate the clock divider, as that determines
-		   the maximum exposure and then we calculayte the exposure
+		   the maximum exposure and then we calculate the exposure
 		   register setting (which goes from 0 - 511).
 
 		   Note our 0 - 4095 exposure is mapped to 0 - 511
 		   milliseconds exposure time */
-		clockdiv = (60 * sd->exposure + 7999) / 8000;
+		u8 clockdiv = (60 * sd->exposure + 7999) / 8000;
 
 		/* Limit framerate to not exceed usb bandwidth */
-		if (clockdiv < 3 && gspca_dev->width >= 320)
-			clockdiv = 3;
+		if (clockdiv < sd->min_clockdiv && gspca_dev->width >= 320)
+			clockdiv = sd->min_clockdiv;
 		else if (clockdiv < 2)
 			clockdiv = 2;
 
+		if (sd->cam_type == CAM_TYPE_VGA && clockdiv < 4)
+			clockdiv = 4;
+
 		/* Frame exposure time in ms = 1000 * clockdiv / 60 ->
 		exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */
 		exposure = (60 * 511 * sd->exposure) / (8000 * clockdiv);
@@ -819,9 +933,10 @@
 		/* exposure register value is reversed! */
 		exposure = 511 - exposure;
 
+		buf[0] = exposure & 0xff;
+		buf[1] = exposure >> 8;
+		sensor_write_reg(gspca_dev, 0x0e, 0, buf, 2);
 		sensor_write1(gspca_dev, 0x02, clockdiv);
-		sensor_write1(gspca_dev, 0x0e, exposure & 0xff);
-		sensor_write1(gspca_dev, 0x0f, exposure >> 8);
 	}
 }
 
@@ -832,7 +947,7 @@
 	if (gspca_dev->ctrl_dis & (1 << GAIN_IDX))
 		return;
 
-	if (sd->sensor_type) {
+	if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) {
 		sensor_write1(gspca_dev, 0x0e, sd->gain);
 	} else {
 		sensor_write1(gspca_dev, 0x10, sd->gain);
@@ -893,17 +1008,35 @@
 	return 0;
 }
 
+static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->min_clockdiv = val;
+	if (gspca_dev->streaming)
+		setexposure(gspca_dev);
+	return 0;
+}
+
+static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->min_clockdiv;
+	return 0;
+}
+
 /* Include pac common sof detection functions */
 #include "pac_common.h"
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,    /* target */
-			__u8 *data,                   /* isoc packet */
-			int len)                      /* iso packet length */
+			u8 *data,		/* isoc packet */
+			int len)		/* iso packet length */
 {
+	struct sd *sd = (struct sd *) gspca_dev;
 	unsigned char *sof;
 
-	sof = pac_find_sof(gspca_dev, data, len);
+	sof = pac_find_sof(&sd->sof_read, data, len);
 	if (sof) {
 		int n;
 
@@ -913,15 +1046,15 @@
 			n -= sizeof pac_sof_marker;
 		else
 			n = 0;
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+		gspca_frame_add(gspca_dev, LAST_PACKET,
 					data, n);
 		/* Start next frame. */
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+		gspca_frame_add(gspca_dev, FIRST_PACKET,
 			pac_sof_marker, sizeof pac_sof_marker);
 		len -= sof - data;
 		data = sof;
 	}
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 /* sub-driver description */
@@ -938,6 +1071,7 @@
 
 /* -- module initialisation -- */
 static const __devinitdata struct usb_device_id device_table[] = {
+	{USB_DEVICE(0x08ca, 0x0110)},	/* Trust Spyc@m 100 */
 	{USB_DEVICE(0x08ca, 0x0111)},	/* Aiptek Pencam VGA+ */
 	{USB_DEVICE(0x093a, 0x010f)},	/* All other known MR97310A VGA cams */
 	{USB_DEVICE(0x093a, 0x010e)},	/* All known MR97310A CIF cams */
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index a5c190e..ad9ec33 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -2,14 +2,19 @@
  * OV519 driver
  *
  * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr)
+ * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
  *
  * This module is adapted from the ov51x-jpeg package, which itself
  * was adapted from the ov511 driver.
  *
  * Original copyright for the ov511 driver is:
  *
- * Copyright (c) 1999-2004 Mark W. McClelland
+ * Copyright (c) 1999-2006 Mark W. McClelland
  * Support for OV519, OV8610 Copyright (c) 2003 Joerg Heckenbach
+ * Many improvements by Bret Wallach <bwallac1@san.rr.com>
+ * Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000)
+ * OV7620 fixes by Charl P. Botha <cpbotha@ieee.org>
+ * Changes by Claudio Matsuoka <claudio@conectiva.com>
  *
  * ov51x-jpeg original copyright is:
  *
@@ -58,6 +63,8 @@
 #define BRIDGE_OV518		2
 #define BRIDGE_OV518PLUS	3
 #define BRIDGE_OV519		4
+#define BRIDGE_OVFX2		5
+#define BRIDGE_W9968CF		6
 #define BRIDGE_MASK		7
 
 	char invert_led;
@@ -73,6 +80,10 @@
 	__u8 vflip;
 	__u8 autobrightness;
 	__u8 freq;
+	__u8 quality;
+#define QUALITY_MIN 50
+#define QUALITY_MAX 70
+#define QUALITY_DEF 50
 
 	__u8 stopped;		/* Streaming is temporarily paused */
 
@@ -81,17 +92,31 @@
 
 	char sensor;		/* Type of image sensor chip (SEN_*) */
 #define SEN_UNKNOWN 0
-#define SEN_OV6620 1
-#define SEN_OV6630 2
-#define SEN_OV66308AF 3
-#define SEN_OV7610 4
-#define SEN_OV7620 5
-#define SEN_OV7640 6
-#define SEN_OV7670 7
-#define SEN_OV76BE 8
-#define SEN_OV8610 9
+#define SEN_OV2610 1
+#define SEN_OV3610 2
+#define SEN_OV6620 3
+#define SEN_OV6630 4
+#define SEN_OV66308AF 5
+#define SEN_OV7610 6
+#define SEN_OV7620 7
+#define SEN_OV7640 8
+#define SEN_OV7670 9
+#define SEN_OV76BE 10
+#define SEN_OV8610 11
+
+	u8 sensor_addr;
+	int sensor_width;
+	int sensor_height;
+	int sensor_reg_cache[256];
+
+	u8 *jpeg_hdr;
 };
 
+/* Note this is a bit of a hack, but the w9968cf driver needs the code for all
+   the ov sensors which is already present here. When we have the time we
+   really should move the sensor drivers to v4l2 sub drivers. */
+#include "w996Xcf.c"
+
 /* V4L2 controls supported by the driver */
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
@@ -345,6 +370,75 @@
 		.priv = 0},
 };
 
+static const struct v4l2_pix_format ovfx2_vga_mode[] = {
+	{320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 320,
+		.sizeimage = 320 * 240,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1},
+	{640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 640,
+		.sizeimage = 640 * 480,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0},
+};
+static const struct v4l2_pix_format ovfx2_cif_mode[] = {
+	{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 160,
+		.sizeimage = 160 * 120,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 3},
+	{176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 176,
+		.sizeimage = 176 * 144,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1},
+	{320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 320,
+		.sizeimage = 320 * 240,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 2},
+	{352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 352,
+		.sizeimage = 352 * 288,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0},
+};
+static const struct v4l2_pix_format ovfx2_ov2610_mode[] = {
+	{1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 1600,
+		.sizeimage = 1600 * 1200,
+		.colorspace = V4L2_COLORSPACE_SRGB},
+};
+static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
+	{640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 640,
+		.sizeimage = 640 * 480,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1},
+	{800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 800,
+		.sizeimage = 800 * 600,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1},
+	{1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 1024,
+		.sizeimage = 1024 * 768,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1},
+	{1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 1600,
+		.sizeimage = 1600 * 1200,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0},
+	{2048, 1536, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 2048,
+		.sizeimage = 2048 * 1536,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0},
+};
+
+
 /* Registers common to OV511 / OV518 */
 #define R51x_FIFO_PSIZE			0x30	/* 2 bytes wide w/ OV518(+) */
 #define R51x_SYS_RESET          	0x50
@@ -406,6 +500,30 @@
 
 #define OV511_ENDPOINT_ADDRESS  1	/* Isoc endpoint number */
 
+/*
+ * The FX2 chip does not give us a zero length read at end of frame.
+ * It does, however, give a short read at the end of a frame, if
+ * neccessary, rather than run two frames together.
+ *
+ * By choosing the right bulk transfer size, we are guaranteed to always
+ * get a short read for the last read of each frame.  Frame sizes are
+ * always a composite number (width * height, or a multiple) so if we
+ * choose a prime number, we are guaranteed that the last read of a
+ * frame will be short.
+ *
+ * But it isn't that easy: the 2.6 kernel requires a multiple of 4KB,
+ * otherwise EOVERFLOW "babbling" errors occur.  I have not been able
+ * to figure out why.  [PMiller]
+ *
+ * The constant (13 * 4096) is the largest "prime enough" number less than 64KB.
+ *
+ * It isn't enough to know the number of bytes per frame, in case we
+ * have data dropouts or buffer overruns (even though the FX2 double
+ * buffers, there are some pretty strict real time constraints for
+ * isochronous transfer for larger frame sizes).
+ */
+#define OVFX2_BULK_SIZE (13 * 4096)
+
 /* I2C registers */
 #define R51x_I2C_W_SID		0x41
 #define R51x_I2C_SADDR_3	0x42
@@ -413,9 +531,11 @@
 #define R51x_I2C_R_SID		0x44
 #define R51x_I2C_DATA		0x45
 #define R518_I2C_CTL		0x47	/* OV518(+) only */
+#define OVFX2_I2C_ADDR		0x00
 
 /* I2C ADDRESSES */
 #define OV7xx0_SID   0x42
+#define OV_HIRES_SID 0x60		/* OV9xxx / OV2xxx / OV3xxx */
 #define OV8xx0_SID   0xa0
 #define OV6xx0_SID   0xc0
 
@@ -508,6 +628,696 @@
 	__u8 val;
 };
 
+/* Settings for OV2610 camera chip */
+static const struct ov_i2c_regvals norm_2610[] =
+{
+	{ 0x12, 0x80 },	/* reset */
+};
+
+static const struct ov_i2c_regvals norm_3620b[] =
+{
+	/*
+	 * From the datasheet: "Note that after writing to register COMH
+	 * (0x12) to change the sensor mode, registers related to the
+	 * sensor’s cropping window will be reset back to their default
+	 * values."
+	 *
+	 * "wait 4096 external clock ... to make sure the sensor is
+	 * stable and ready to access registers" i.e. 160us at 24MHz
+	 */
+
+	{ 0x12, 0x80 }, /* COMH reset */
+	{ 0x12, 0x00 }, /* QXGA, master */
+
+	/*
+	 * 11 CLKRC "Clock Rate Control"
+	 * [7] internal frequency doublers: on
+	 * [6] video port mode: master
+	 * [5:0] clock divider: 1
+	 */
+	{ 0x11, 0x80 },
+
+	/*
+	 * 13 COMI "Common Control I"
+	 *                  = 192 (0xC0) 11000000
+	 *    COMI[7] "AEC speed selection"
+	 *                  =   1 (0x01) 1....... "Faster AEC correction"
+	 *    COMI[6] "AEC speed step selection"
+	 *                  =   1 (0x01) .1...... "Big steps, fast"
+	 *    COMI[5] "Banding filter on off"
+	 *                  =   0 (0x00) ..0..... "Off"
+	 *    COMI[4] "Banding filter option"
+	 *                  =   0 (0x00) ...0.... "Main clock is 48 MHz and
+	 *                                         the PLL is ON"
+	 *    COMI[3] "Reserved"
+	 *                  =   0 (0x00) ....0...
+	 *    COMI[2] "AGC auto manual control selection"
+	 *                  =   0 (0x00) .....0.. "Manual"
+	 *    COMI[1] "AWB auto manual control selection"
+	 *                  =   0 (0x00) ......0. "Manual"
+	 *    COMI[0] "Exposure control"
+	 *                  =   0 (0x00) .......0 "Manual"
+	 */
+	{ 0x13, 0xC0 },
+
+	/*
+	 * 09 COMC "Common Control C"
+	 *                  =   8 (0x08) 00001000
+	 *    COMC[7:5] "Reserved"
+	 *                  =   0 (0x00) 000.....
+	 *    COMC[4] "Sleep Mode Enable"
+	 *                  =   0 (0x00) ...0.... "Normal mode"
+	 *    COMC[3:2] "Sensor sampling reset timing selection"
+	 *                  =   2 (0x02) ....10.. "Longer reset time"
+	 *    COMC[1:0] "Output drive current select"
+	 *                  =   0 (0x00) ......00 "Weakest"
+	 */
+	{ 0x09, 0x08 },
+
+	/*
+	 * 0C COMD "Common Control D"
+	 *                  =   8 (0x08) 00001000
+	 *    COMD[7] "Reserved"
+	 *                  =   0 (0x00) 0.......
+	 *    COMD[6] "Swap MSB and LSB at the output port"
+	 *                  =   0 (0x00) .0...... "False"
+	 *    COMD[5:3] "Reserved"
+	 *                  =   1 (0x01) ..001...
+	 *    COMD[2] "Output Average On Off"
+	 *                  =   0 (0x00) .....0.. "Output Normal"
+	 *    COMD[1] "Sensor precharge voltage selection"
+	 *                  =   0 (0x00) ......0. "Selects internal
+	 *                                         reference precharge
+	 *                                         voltage"
+	 *    COMD[0] "Snapshot option"
+	 *                  =   0 (0x00) .......0 "Enable live video output
+	 *                                         after snapshot sequence"
+	 */
+	{ 0x0c, 0x08 },
+
+	/*
+	 * 0D COME "Common Control E"
+	 *                  = 161 (0xA1) 10100001
+	 *    COME[7] "Output average option"
+	 *                  =   1 (0x01) 1....... "Output average of 4 pixels"
+	 *    COME[6] "Anti-blooming control"
+	 *                  =   0 (0x00) .0...... "Off"
+	 *    COME[5:3] "Reserved"
+	 *                  =   4 (0x04) ..100...
+	 *    COME[2] "Clock output power down pin status"
+	 *                  =   0 (0x00) .....0.. "Tri-state data output pin
+	 *                                         on power down"
+	 *    COME[1] "Data output pin status selection at power down"
+	 *                  =   0 (0x00) ......0. "Tri-state VSYNC, PCLK,
+	 *                                         HREF, and CHSYNC pins on
+	 *                                         power down"
+	 *    COME[0] "Auto zero circuit select"
+	 *                  =   1 (0x01) .......1 "On"
+	 */
+	{ 0x0d, 0xA1 },
+
+	/*
+	 * 0E COMF "Common Control F"
+	 *                  = 112 (0x70) 01110000
+	 *    COMF[7] "System clock selection"
+	 *                  =   0 (0x00) 0....... "Use 24 MHz system clock"
+	 *    COMF[6:4] "Reserved"
+	 *                  =   7 (0x07) .111....
+	 *    COMF[3] "Manual auto negative offset canceling selection"
+	 *                  =   0 (0x00) ....0... "Auto detect negative
+	 *                                         offset and cancel it"
+	 *    COMF[2:0] "Reserved"
+	 *                  =   0 (0x00) .....000
+	 */
+	{ 0x0e, 0x70 },
+
+	/*
+	 * 0F COMG "Common Control G"
+	 *                  =  66 (0x42) 01000010
+	 *    COMG[7] "Optical black output selection"
+	 *                  =   0 (0x00) 0....... "Disable"
+	 *    COMG[6] "Black level calibrate selection"
+	 *                  =   1 (0x01) .1...... "Use optical black pixels
+	 *                                         to calibrate"
+	 *    COMG[5:4] "Reserved"
+	 *                  =   0 (0x00) ..00....
+	 *    COMG[3] "Channel offset adjustment"
+	 *                  =   0 (0x00) ....0... "Disable offset adjustment"
+	 *    COMG[2] "ADC black level calibration option"
+	 *                  =   0 (0x00) .....0.. "Use B/G line and G/R
+	 *                                         line to calibrate each
+	 *                                         channel's black level"
+	 *    COMG[1] "Reserved"
+	 *                  =   1 (0x01) ......1.
+	 *    COMG[0] "ADC black level calibration enable"
+	 *                  =   0 (0x00) .......0 "Disable"
+	 */
+	{ 0x0f, 0x42 },
+
+	/*
+	 * 14 COMJ "Common Control J"
+	 *                  = 198 (0xC6) 11000110
+	 *    COMJ[7:6] "AGC gain ceiling"
+	 *                  =   3 (0x03) 11...... "8x"
+	 *    COMJ[5:4] "Reserved"
+	 *                  =   0 (0x00) ..00....
+	 *    COMJ[3] "Auto banding filter"
+	 *                  =   0 (0x00) ....0... "Banding filter is always
+	 *                                         on off depending on
+	 *                                         COMI[5] setting"
+	 *    COMJ[2] "VSYNC drop option"
+	 *                  =   1 (0x01) .....1.. "SYNC is dropped if frame
+	 *                                         data is dropped"
+	 *    COMJ[1] "Frame data drop"
+	 *                  =   1 (0x01) ......1. "Drop frame data if
+	 *                                         exposure is not within
+	 *                                         tolerance.  In AEC mode,
+	 *                                         data is normally dropped
+	 *                                         when data is out of
+	 *                                         range."
+	 *    COMJ[0] "Reserved"
+	 *                  =   0 (0x00) .......0
+	 */
+	{ 0x14, 0xC6 },
+
+	/*
+	 * 15 COMK "Common Control K"
+	 *                  =   2 (0x02) 00000010
+	 *    COMK[7] "CHSYNC pin output swap"
+	 *                  =   0 (0x00) 0....... "CHSYNC"
+	 *    COMK[6] "HREF pin output swap"
+	 *                  =   0 (0x00) .0...... "HREF"
+	 *    COMK[5] "PCLK output selection"
+	 *                  =   0 (0x00) ..0..... "PCLK always output"
+	 *    COMK[4] "PCLK edge selection"
+	 *                  =   0 (0x00) ...0.... "Data valid on falling edge"
+	 *    COMK[3] "HREF output polarity"
+	 *                  =   0 (0x00) ....0... "positive"
+	 *    COMK[2] "Reserved"
+	 *                  =   0 (0x00) .....0..
+	 *    COMK[1] "VSYNC polarity"
+	 *                  =   1 (0x01) ......1. "negative"
+	 *    COMK[0] "HSYNC polarity"
+	 *                  =   0 (0x00) .......0 "positive"
+	 */
+	{ 0x15, 0x02 },
+
+	/*
+	 * 33 CHLF "Current Control"
+	 *                  =   9 (0x09) 00001001
+	 *    CHLF[7:6] "Sensor current control"
+	 *                  =   0 (0x00) 00......
+	 *    CHLF[5] "Sensor current range control"
+	 *                  =   0 (0x00) ..0..... "normal range"
+	 *    CHLF[4] "Sensor current"
+	 *                  =   0 (0x00) ...0.... "normal current"
+	 *    CHLF[3] "Sensor buffer current control"
+	 *                  =   1 (0x01) ....1... "half current"
+	 *    CHLF[2] "Column buffer current control"
+	 *                  =   0 (0x00) .....0.. "normal current"
+	 *    CHLF[1] "Analog DSP current control"
+	 *                  =   0 (0x00) ......0. "normal current"
+	 *    CHLF[1] "ADC current control"
+	 *                  =   0 (0x00) ......0. "normal current"
+	 */
+	{ 0x33, 0x09 },
+
+	/*
+	 * 34 VBLM "Blooming Control"
+	 *                  =  80 (0x50) 01010000
+	 *    VBLM[7] "Hard soft reset switch"
+	 *                  =   0 (0x00) 0....... "Hard reset"
+	 *    VBLM[6:4] "Blooming voltage selection"
+	 *                  =   5 (0x05) .101....
+	 *    VBLM[3:0] "Sensor current control"
+	 *                  =   0 (0x00) ....0000
+	 */
+	{ 0x34, 0x50 },
+
+	/*
+	 * 36 VCHG "Sensor Precharge Voltage Control"
+	 *                  =   0 (0x00) 00000000
+	 *    VCHG[7] "Reserved"
+	 *                  =   0 (0x00) 0.......
+	 *    VCHG[6:4] "Sensor precharge voltage control"
+	 *                  =   0 (0x00) .000....
+	 *    VCHG[3:0] "Sensor array common reference"
+	 *                  =   0 (0x00) ....0000
+	 */
+	{ 0x36, 0x00 },
+
+	/*
+	 * 37 ADC "ADC Reference Control"
+	 *                  =   4 (0x04) 00000100
+	 *    ADC[7:4] "Reserved"
+	 *                  =   0 (0x00) 0000....
+	 *    ADC[3] "ADC input signal range"
+	 *                  =   0 (0x00) ....0... "Input signal 1.0x"
+	 *    ADC[2:0] "ADC range control"
+	 *                  =   4 (0x04) .....100
+	 */
+	{ 0x37, 0x04 },
+
+	/*
+	 * 38 ACOM "Analog Common Ground"
+	 *                  =  82 (0x52) 01010010
+	 *    ACOM[7] "Analog gain control"
+	 *                  =   0 (0x00) 0....... "Gain 1x"
+	 *    ACOM[6] "Analog black level calibration"
+	 *                  =   1 (0x01) .1...... "On"
+	 *    ACOM[5:0] "Reserved"
+	 *                  =  18 (0x12) ..010010
+	 */
+	{ 0x38, 0x52 },
+
+	/*
+	 * 3A FREFA "Internal Reference Adjustment"
+	 *                  =   0 (0x00) 00000000
+	 *    FREFA[7:0] "Range"
+	 *                  =   0 (0x00) 00000000
+	 */
+	{ 0x3a, 0x00 },
+
+	/*
+	 * 3C FVOPT "Internal Reference Adjustment"
+	 *                  =  31 (0x1F) 00011111
+	 *    FVOPT[7:0] "Range"
+	 *                  =  31 (0x1F) 00011111
+	 */
+	{ 0x3c, 0x1F },
+
+	/*
+	 * 44 Undocumented  =   0 (0x00) 00000000
+	 *    44[7:0] "It's a secret"
+	 *                  =   0 (0x00) 00000000
+	 */
+	{ 0x44, 0x00 },
+
+	/*
+	 * 40 Undocumented  =   0 (0x00) 00000000
+	 *    40[7:0] "It's a secret"
+	 *                  =   0 (0x00) 00000000
+	 */
+	{ 0x40, 0x00 },
+
+	/*
+	 * 41 Undocumented  =   0 (0x00) 00000000
+	 *    41[7:0] "It's a secret"
+	 *                  =   0 (0x00) 00000000
+	 */
+	{ 0x41, 0x00 },
+
+	/*
+	 * 42 Undocumented  =   0 (0x00) 00000000
+	 *    42[7:0] "It's a secret"
+	 *                  =   0 (0x00) 00000000
+	 */
+	{ 0x42, 0x00 },
+
+	/*
+	 * 43 Undocumented  =   0 (0x00) 00000000
+	 *    43[7:0] "It's a secret"
+	 *                  =   0 (0x00) 00000000
+	 */
+	{ 0x43, 0x00 },
+
+	/*
+	 * 45 Undocumented  = 128 (0x80) 10000000
+	 *    45[7:0] "It's a secret"
+	 *                  = 128 (0x80) 10000000
+	 */
+	{ 0x45, 0x80 },
+
+	/*
+	 * 48 Undocumented  = 192 (0xC0) 11000000
+	 *    48[7:0] "It's a secret"
+	 *                  = 192 (0xC0) 11000000
+	 */
+	{ 0x48, 0xC0 },
+
+	/*
+	 * 49 Undocumented  =  25 (0x19) 00011001
+	 *    49[7:0] "It's a secret"
+	 *                  =  25 (0x19) 00011001
+	 */
+	{ 0x49, 0x19 },
+
+	/*
+	 * 4B Undocumented  = 128 (0x80) 10000000
+	 *    4B[7:0] "It's a secret"
+	 *                  = 128 (0x80) 10000000
+	 */
+	{ 0x4B, 0x80 },
+
+	/*
+	 * 4D Undocumented  = 196 (0xC4) 11000100
+	 *    4D[7:0] "It's a secret"
+	 *                  = 196 (0xC4) 11000100
+	 */
+	{ 0x4D, 0xC4 },
+
+	/*
+	 * 35 VREF "Reference Voltage Control"
+	 *                  =  76 (0x4C) 01001100
+	 *    VREF[7:5] "Column high reference control"
+	 *                  =   2 (0x02) 010..... "higher voltage"
+	 *    VREF[4:2] "Column low reference control"
+	 *                  =   3 (0x03) ...011.. "Highest voltage"
+	 *    VREF[1:0] "Reserved"
+	 *                  =   0 (0x00) ......00
+	 */
+	{ 0x35, 0x4C },
+
+	/*
+	 * 3D Undocumented  =   0 (0x00) 00000000
+	 *    3D[7:0] "It's a secret"
+	 *                  =   0 (0x00) 00000000
+	 */
+	{ 0x3D, 0x00 },
+
+	/*
+	 * 3E Undocumented  =   0 (0x00) 00000000
+	 *    3E[7:0] "It's a secret"
+	 *                  =   0 (0x00) 00000000
+	 */
+	{ 0x3E, 0x00 },
+
+	/*
+	 * 3B FREFB "Internal Reference Adjustment"
+	 *                  =  24 (0x18) 00011000
+	 *    FREFB[7:0] "Range"
+	 *                  =  24 (0x18) 00011000
+	 */
+	{ 0x3b, 0x18 },
+
+	/*
+	 * 33 CHLF "Current Control"
+	 *                  =  25 (0x19) 00011001
+	 *    CHLF[7:6] "Sensor current control"
+	 *                  =   0 (0x00) 00......
+	 *    CHLF[5] "Sensor current range control"
+	 *                  =   0 (0x00) ..0..... "normal range"
+	 *    CHLF[4] "Sensor current"
+	 *                  =   1 (0x01) ...1.... "double current"
+	 *    CHLF[3] "Sensor buffer current control"
+	 *                  =   1 (0x01) ....1... "half current"
+	 *    CHLF[2] "Column buffer current control"
+	 *                  =   0 (0x00) .....0.. "normal current"
+	 *    CHLF[1] "Analog DSP current control"
+	 *                  =   0 (0x00) ......0. "normal current"
+	 *    CHLF[1] "ADC current control"
+	 *                  =   0 (0x00) ......0. "normal current"
+	 */
+	{ 0x33, 0x19 },
+
+	/*
+	 * 34 VBLM "Blooming Control"
+	 *                  =  90 (0x5A) 01011010
+	 *    VBLM[7] "Hard soft reset switch"
+	 *                  =   0 (0x00) 0....... "Hard reset"
+	 *    VBLM[6:4] "Blooming voltage selection"
+	 *                  =   5 (0x05) .101....
+	 *    VBLM[3:0] "Sensor current control"
+	 *                  =  10 (0x0A) ....1010
+	 */
+	{ 0x34, 0x5A },
+
+	/*
+	 * 3B FREFB "Internal Reference Adjustment"
+	 *                  =   0 (0x00) 00000000
+	 *    FREFB[7:0] "Range"
+	 *                  =   0 (0x00) 00000000
+	 */
+	{ 0x3b, 0x00 },
+
+	/*
+	 * 33 CHLF "Current Control"
+	 *                  =   9 (0x09) 00001001
+	 *    CHLF[7:6] "Sensor current control"
+	 *                  =   0 (0x00) 00......
+	 *    CHLF[5] "Sensor current range control"
+	 *                  =   0 (0x00) ..0..... "normal range"
+	 *    CHLF[4] "Sensor current"
+	 *                  =   0 (0x00) ...0.... "normal current"
+	 *    CHLF[3] "Sensor buffer current control"
+	 *                  =   1 (0x01) ....1... "half current"
+	 *    CHLF[2] "Column buffer current control"
+	 *                  =   0 (0x00) .....0.. "normal current"
+	 *    CHLF[1] "Analog DSP current control"
+	 *                  =   0 (0x00) ......0. "normal current"
+	 *    CHLF[1] "ADC current control"
+	 *                  =   0 (0x00) ......0. "normal current"
+	 */
+	{ 0x33, 0x09 },
+
+	/*
+	 * 34 VBLM "Blooming Control"
+	 *                  =  80 (0x50) 01010000
+	 *    VBLM[7] "Hard soft reset switch"
+	 *                  =   0 (0x00) 0....... "Hard reset"
+	 *    VBLM[6:4] "Blooming voltage selection"
+	 *                  =   5 (0x05) .101....
+	 *    VBLM[3:0] "Sensor current control"
+	 *                  =   0 (0x00) ....0000
+	 */
+	{ 0x34, 0x50 },
+
+	/*
+	 * 12 COMH "Common Control H"
+	 *                  =  64 (0x40) 01000000
+	 *    COMH[7] "SRST"
+	 *                  =   0 (0x00) 0....... "No-op"
+	 *    COMH[6:4] "Resolution selection"
+	 *                  =   4 (0x04) .100.... "XGA"
+	 *    COMH[3] "Master slave selection"
+	 *                  =   0 (0x00) ....0... "Master mode"
+	 *    COMH[2] "Internal B/R channel option"
+	 *                  =   0 (0x00) .....0.. "B/R use same channel"
+	 *    COMH[1] "Color bar test pattern"
+	 *                  =   0 (0x00) ......0. "Off"
+	 *    COMH[0] "Reserved"
+	 *                  =   0 (0x00) .......0
+	 */
+	{ 0x12, 0x40 },
+
+	/*
+	 * 17 HREFST "Horizontal window start"
+	 *                  =  31 (0x1F) 00011111
+	 *    HREFST[7:0] "Horizontal window start, 8 MSBs"
+	 *                  =  31 (0x1F) 00011111
+	 */
+	{ 0x17, 0x1F },
+
+	/*
+	 * 18 HREFEND "Horizontal window end"
+	 *                  =  95 (0x5F) 01011111
+	 *    HREFEND[7:0] "Horizontal Window End, 8 MSBs"
+	 *                  =  95 (0x5F) 01011111
+	 */
+	{ 0x18, 0x5F },
+
+	/*
+	 * 19 VSTRT "Vertical window start"
+	 *                  =   0 (0x00) 00000000
+	 *    VSTRT[7:0] "Vertical Window Start, 8 MSBs"
+	 *                  =   0 (0x00) 00000000
+	 */
+	{ 0x19, 0x00 },
+
+	/*
+	 * 1A VEND "Vertical window end"
+	 *                  =  96 (0x60) 01100000
+	 *    VEND[7:0] "Vertical Window End, 8 MSBs"
+	 *                  =  96 (0x60) 01100000
+	 */
+	{ 0x1a, 0x60 },
+
+	/*
+	 * 32 COMM "Common Control M"
+	 *                  =  18 (0x12) 00010010
+	 *    COMM[7:6] "Pixel clock divide option"
+	 *                  =   0 (0x00) 00...... "/1"
+	 *    COMM[5:3] "Horizontal window end position, 3 LSBs"
+	 *                  =   2 (0x02) ..010...
+	 *    COMM[2:0] "Horizontal window start position, 3 LSBs"
+	 *                  =   2 (0x02) .....010
+	 */
+	{ 0x32, 0x12 },
+
+	/*
+	 * 03 COMA "Common Control A"
+	 *                  =  74 (0x4A) 01001010
+	 *    COMA[7:4] "AWB Update Threshold"
+	 *                  =   4 (0x04) 0100....
+	 *    COMA[3:2] "Vertical window end line control 2 LSBs"
+	 *                  =   2 (0x02) ....10..
+	 *    COMA[1:0] "Vertical window start line control 2 LSBs"
+	 *                  =   2 (0x02) ......10
+	 */
+	{ 0x03, 0x4A },
+
+	/*
+	 * 11 CLKRC "Clock Rate Control"
+	 *                  = 128 (0x80) 10000000
+	 *    CLKRC[7] "Internal frequency doublers on off seclection"
+	 *                  =   1 (0x01) 1....... "On"
+	 *    CLKRC[6] "Digital video master slave selection"
+	 *                  =   0 (0x00) .0...... "Master mode, sensor
+	 *                                         provides PCLK"
+	 *    CLKRC[5:0] "Clock divider { CLK = PCLK/(1+CLKRC[5:0]) }"
+	 *                  =   0 (0x00) ..000000
+	 */
+	{ 0x11, 0x80 },
+
+	/*
+	 * 12 COMH "Common Control H"
+	 *                  =   0 (0x00) 00000000
+	 *    COMH[7] "SRST"
+	 *                  =   0 (0x00) 0....... "No-op"
+	 *    COMH[6:4] "Resolution selection"
+	 *                  =   0 (0x00) .000.... "QXGA"
+	 *    COMH[3] "Master slave selection"
+	 *                  =   0 (0x00) ....0... "Master mode"
+	 *    COMH[2] "Internal B/R channel option"
+	 *                  =   0 (0x00) .....0.. "B/R use same channel"
+	 *    COMH[1] "Color bar test pattern"
+	 *                  =   0 (0x00) ......0. "Off"
+	 *    COMH[0] "Reserved"
+	 *                  =   0 (0x00) .......0
+	 */
+	{ 0x12, 0x00 },
+
+	/*
+	 * 12 COMH "Common Control H"
+	 *                  =  64 (0x40) 01000000
+	 *    COMH[7] "SRST"
+	 *                  =   0 (0x00) 0....... "No-op"
+	 *    COMH[6:4] "Resolution selection"
+	 *                  =   4 (0x04) .100.... "XGA"
+	 *    COMH[3] "Master slave selection"
+	 *                  =   0 (0x00) ....0... "Master mode"
+	 *    COMH[2] "Internal B/R channel option"
+	 *                  =   0 (0x00) .....0.. "B/R use same channel"
+	 *    COMH[1] "Color bar test pattern"
+	 *                  =   0 (0x00) ......0. "Off"
+	 *    COMH[0] "Reserved"
+	 *                  =   0 (0x00) .......0
+	 */
+	{ 0x12, 0x40 },
+
+	/*
+	 * 17 HREFST "Horizontal window start"
+	 *                  =  31 (0x1F) 00011111
+	 *    HREFST[7:0] "Horizontal window start, 8 MSBs"
+	 *                  =  31 (0x1F) 00011111
+	 */
+	{ 0x17, 0x1F },
+
+	/*
+	 * 18 HREFEND "Horizontal window end"
+	 *                  =  95 (0x5F) 01011111
+	 *    HREFEND[7:0] "Horizontal Window End, 8 MSBs"
+	 *                  =  95 (0x5F) 01011111
+	 */
+	{ 0x18, 0x5F },
+
+	/*
+	 * 19 VSTRT "Vertical window start"
+	 *                  =   0 (0x00) 00000000
+	 *    VSTRT[7:0] "Vertical Window Start, 8 MSBs"
+	 *                  =   0 (0x00) 00000000
+	 */
+	{ 0x19, 0x00 },
+
+	/*
+	 * 1A VEND "Vertical window end"
+	 *                  =  96 (0x60) 01100000
+	 *    VEND[7:0] "Vertical Window End, 8 MSBs"
+	 *                  =  96 (0x60) 01100000
+	 */
+	{ 0x1a, 0x60 },
+
+	/*
+	 * 32 COMM "Common Control M"
+	 *                  =  18 (0x12) 00010010
+	 *    COMM[7:6] "Pixel clock divide option"
+	 *                  =   0 (0x00) 00...... "/1"
+	 *    COMM[5:3] "Horizontal window end position, 3 LSBs"
+	 *                  =   2 (0x02) ..010...
+	 *    COMM[2:0] "Horizontal window start position, 3 LSBs"
+	 *                  =   2 (0x02) .....010
+	 */
+	{ 0x32, 0x12 },
+
+	/*
+	 * 03 COMA "Common Control A"
+	 *                  =  74 (0x4A) 01001010
+	 *    COMA[7:4] "AWB Update Threshold"
+	 *                  =   4 (0x04) 0100....
+	 *    COMA[3:2] "Vertical window end line control 2 LSBs"
+	 *                  =   2 (0x02) ....10..
+	 *    COMA[1:0] "Vertical window start line control 2 LSBs"
+	 *                  =   2 (0x02) ......10
+	 */
+	{ 0x03, 0x4A },
+
+	/*
+	 * 02 RED "Red Gain Control"
+	 *                  = 175 (0xAF) 10101111
+	 *    RED[7] "Action"
+	 *                  =   1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
+	 *    RED[6:0] "Value"
+	 *                  =  47 (0x2F) .0101111
+	 */
+	{ 0x02, 0xAF },
+
+	/*
+	 * 2D ADDVSL "VSYNC Pulse Width"
+	 *                  = 210 (0xD2) 11010010
+	 *    ADDVSL[7:0] "VSYNC pulse width, LSB"
+	 *                  = 210 (0xD2) 11010010
+	 */
+	{ 0x2d, 0xD2 },
+
+	/*
+	 * 00 GAIN          =  24 (0x18) 00011000
+	 *    GAIN[7:6] "Reserved"
+	 *                  =   0 (0x00) 00......
+	 *    GAIN[5] "Double"
+	 *                  =   0 (0x00) ..0..... "False"
+	 *    GAIN[4] "Double"
+	 *                  =   1 (0x01) ...1.... "True"
+	 *    GAIN[3:0] "Range"
+	 *                  =   8 (0x08) ....1000
+	 */
+	{ 0x00, 0x18 },
+
+	/*
+	 * 01 BLUE "Blue Gain Control"
+	 *                  = 240 (0xF0) 11110000
+	 *    BLUE[7] "Action"
+	 *                  =   1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
+	 *    BLUE[6:0] "Value"
+	 *                  = 112 (0x70) .1110000
+	 */
+	{ 0x01, 0xF0 },
+
+	/*
+	 * 10 AEC "Automatic Exposure Control"
+	 *                  =  10 (0x0A) 00001010
+	 *    AEC[7:0] "Automatic Exposure Control, 8 MSBs"
+	 *                  =  10 (0x0A) 00001010
+	 */
+	{ 0x10, 0x0A },
+
+	{ 0xE1, 0x67 },
+	{ 0xE3, 0x03 },
+	{ 0xE4, 0x26 },
+	{ 0xE5, 0x3E },
+	{ 0xF8, 0x01 },
+	{ 0xFF, 0x01 },
+};
+
 static const struct ov_i2c_regvals norm_6x20[] = {
 	{ 0x12, 0x80 }, /* reset */
 	{ 0x11, 0x01 },
@@ -678,6 +1488,7 @@
 };
 
 static const struct ov_i2c_regvals norm_7620[] = {
+	{ 0x12, 0x80 },		/* reset */
 	{ 0x00, 0x00 },		/* gain */
 	{ 0x01, 0x80 },		/* blue gain */
 	{ 0x02, 0x80 },		/* red gain */
@@ -1042,10 +1853,28 @@
 }
 
 /* Write a OV519 register */
-static int reg_w(struct sd *sd, __u16 index, __u8 value)
+static int reg_w(struct sd *sd, __u16 index, __u16 value)
 {
-	int ret;
-	int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 2 : 1;
+	int ret, req = 0;
+
+	switch (sd->bridge) {
+	case BRIDGE_OV511:
+	case BRIDGE_OV511PLUS:
+		req = 2;
+		break;
+	case BRIDGE_OVFX2:
+		req = 0x0a;
+		/* fall through */
+	case BRIDGE_W9968CF:
+		ret = usb_control_msg(sd->gspca_dev.dev,
+			usb_sndctrlpipe(sd->gspca_dev.dev, 0),
+			req,
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			value, index, NULL, 0, 500);
+		goto leave;
+	default:
+		req = 1;
+	}
 
 	sd->gspca_dev.usb_buf[0] = value;
 	ret = usb_control_msg(sd->gspca_dev.dev,
@@ -1054,17 +1883,35 @@
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			0, index,
 			sd->gspca_dev.usb_buf, 1, 500);
-	if (ret < 0)
-		PDEBUG(D_ERR, "Write reg [%02x] %02x failed", index, value);
-	return ret;
+leave:
+	if (ret < 0) {
+		PDEBUG(D_ERR, "Write reg 0x%04x -> [0x%02x] failed",
+		       value, index);
+		return ret;
+	}
+
+	PDEBUG(D_USBO, "Write reg 0x%04x -> [0x%02x]", value, index);
+	return 0;
 }
 
-/* Read from a OV519 register */
+/* Read from a OV519 register, note not valid for the w9968cf!! */
 /* returns: negative is error, pos or zero is data */
 static int reg_r(struct sd *sd, __u16 index)
 {
 	int ret;
-	int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 3 : 1;
+	int req;
+
+	switch (sd->bridge) {
+	case BRIDGE_OV511:
+	case BRIDGE_OV511PLUS:
+		req = 3;
+		break;
+	case BRIDGE_OVFX2:
+		req = 0x0b;
+		break;
+	default:
+		req = 1;
+	}
 
 	ret = usb_control_msg(sd->gspca_dev.dev,
 			usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
@@ -1072,10 +1919,12 @@
 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			0, index, sd->gspca_dev.usb_buf, 1, 500);
 
-	if (ret >= 0)
+	if (ret >= 0) {
 		ret = sd->gspca_dev.usb_buf[0];
-	else
+		PDEBUG(D_USBI, "Read reg [0x%02X] -> 0x%04X", index, ret);
+	} else
 		PDEBUG(D_ERR, "Read reg [0x%02x] failed", index);
+
 	return ret;
 }
 
@@ -1095,6 +1944,7 @@
 		ret = sd->gspca_dev.usb_buf[0];
 	else
 		PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index);
+
 	return ret;
 }
 
@@ -1140,9 +1990,12 @@
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			0, index,
 			sd->gspca_dev.usb_buf, n, 500);
-	if (ret < 0)
+	if (ret < 0) {
 		PDEBUG(D_ERR, "Write reg32 [%02x] %08x failed", index, value);
-	return ret;
+		return ret;
+	}
+
+	return 0;
 }
 
 static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value)
@@ -1324,32 +2177,110 @@
 	return value;
 }
 
+static int ovfx2_i2c_w(struct sd *sd, __u8 reg, __u8 value)
+{
+	int ret;
+
+	ret = usb_control_msg(sd->gspca_dev.dev,
+			usb_sndctrlpipe(sd->gspca_dev.dev, 0),
+			0x02,
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			(__u16)value, (__u16)reg, NULL, 0, 500);
+
+	if (ret < 0) {
+		PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg);
+		return ret;
+	}
+
+	PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
+	return 0;
+}
+
+static int ovfx2_i2c_r(struct sd *sd, __u8 reg)
+{
+	int ret;
+
+	ret = usb_control_msg(sd->gspca_dev.dev,
+			usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
+			0x03,
+			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			0, (__u16)reg, sd->gspca_dev.usb_buf, 1, 500);
+
+	if (ret >= 0) {
+		ret = sd->gspca_dev.usb_buf[0];
+		PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, ret);
+	} else
+		PDEBUG(D_ERR, "i2c read [0x%02x] failed", reg);
+
+	return ret;
+}
+
 static int i2c_w(struct sd *sd, __u8 reg, __u8 value)
 {
+	int ret = -1;
+
+	if (sd->sensor_reg_cache[reg] == value)
+		return 0;
+
 	switch (sd->bridge) {
 	case BRIDGE_OV511:
 	case BRIDGE_OV511PLUS:
-		return ov511_i2c_w(sd, reg, value);
+		ret = ov511_i2c_w(sd, reg, value);
+		break;
 	case BRIDGE_OV518:
 	case BRIDGE_OV518PLUS:
 	case BRIDGE_OV519:
-		return ov518_i2c_w(sd, reg, value);
+		ret = ov518_i2c_w(sd, reg, value);
+		break;
+	case BRIDGE_OVFX2:
+		ret = ovfx2_i2c_w(sd, reg, value);
+		break;
+	case BRIDGE_W9968CF:
+		ret = w9968cf_i2c_w(sd, reg, value);
+		break;
 	}
-	return -1; /* Should never happen */
+
+	if (ret >= 0) {
+		/* Up on sensor reset empty the register cache */
+		if (reg == 0x12 && (value & 0x80))
+			memset(sd->sensor_reg_cache, -1,
+			       sizeof(sd->sensor_reg_cache));
+		else
+			sd->sensor_reg_cache[reg] = value;
+	}
+
+	return ret;
 }
 
 static int i2c_r(struct sd *sd, __u8 reg)
 {
+	int ret = -1;
+
+	if (sd->sensor_reg_cache[reg] != -1)
+		return sd->sensor_reg_cache[reg];
+
 	switch (sd->bridge) {
 	case BRIDGE_OV511:
 	case BRIDGE_OV511PLUS:
-		return ov511_i2c_r(sd, reg);
+		ret = ov511_i2c_r(sd, reg);
+		break;
 	case BRIDGE_OV518:
 	case BRIDGE_OV518PLUS:
 	case BRIDGE_OV519:
-		return ov518_i2c_r(sd, reg);
+		ret = ov518_i2c_r(sd, reg);
+		break;
+	case BRIDGE_OVFX2:
+		ret = ovfx2_i2c_r(sd, reg);
+		break;
+	case BRIDGE_W9968CF:
+		ret = w9968cf_i2c_r(sd, reg);
+		break;
 	}
-	return -1; /* Should never happen */
+
+	if (ret >= 0)
+		sd->sensor_reg_cache[reg] = ret;
+
+	return ret;
 }
 
 /* Writes bits at positions specified by mask to an I2C reg. Bits that are in
@@ -1389,6 +2320,10 @@
 		return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
 	case BRIDGE_OV519:
 		return reg_w(sd, OV519_SYS_RESET1, 0x0f);
+	case BRIDGE_OVFX2:
+		return reg_w_mask(sd, 0x0f, 0x00, 0x02);
+	case BRIDGE_W9968CF:
+		return reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */
 	}
 
 	return 0;
@@ -1418,18 +2353,27 @@
 		return reg_w(sd, R51x_SYS_RESET, 0x00);
 	case BRIDGE_OV519:
 		return reg_w(sd, OV519_SYS_RESET1, 0x00);
+	case BRIDGE_OVFX2:
+		return reg_w_mask(sd, 0x0f, 0x02, 0x02);
+	case BRIDGE_W9968CF:
+		return reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */
 	}
 
 	return 0;
 }
 
+static int ov51x_set_slave_ids(struct sd *sd, __u8 slave);
+
 /* This does an initial reset of an OmniVision sensor and ensures that I2C
  * is synchronized. Returns <0 on failure.
  */
-static int init_ov_sensor(struct sd *sd)
+static int init_ov_sensor(struct sd *sd, __u8 slave)
 {
 	int i;
 
+	if (ov51x_set_slave_ids(sd, slave) < 0)
+		return -EIO;
+
 	/* Reset the sensor */
 	if (i2c_w(sd, 0x12, 0x80) < 0)
 		return -EIO;
@@ -1466,6 +2410,14 @@
 {
 	int rc;
 
+	switch (sd->bridge) {
+	case BRIDGE_OVFX2:
+		return reg_w(sd, OVFX2_I2C_ADDR, slave);
+	case BRIDGE_W9968CF:
+		sd->sensor_addr = slave;
+		return 0;
+	}
+
 	rc = reg_w(sd, R51x_I2C_W_SID, slave);
 	if (rc < 0)
 		return rc;
@@ -1508,6 +2460,39 @@
  *
  ***************************************************************************/
 
+/* This initializes the OV2x10 / OV3610 / OV3620 */
+static int ov_hires_configure(struct sd *sd)
+{
+	int high, low;
+
+	if (sd->bridge != BRIDGE_OVFX2) {
+		PDEBUG(D_ERR, "error hires sensors only supported with ovfx2");
+		return -1;
+	}
+
+	PDEBUG(D_PROBE, "starting ov hires configuration");
+
+	/* Detect sensor (sub)type */
+	high = i2c_r(sd, 0x0a);
+	low = i2c_r(sd, 0x0b);
+	/* info("%x, %x", high, low); */
+	if (high == 0x96 && low == 0x40) {
+		PDEBUG(D_PROBE, "Sensor is an OV2610");
+		sd->sensor = SEN_OV2610;
+	} else if (high == 0x36 && (low & 0x0f) == 0x00) {
+		PDEBUG(D_PROBE, "Sensor is an OV3610");
+		sd->sensor = SEN_OV3610;
+	} else {
+		PDEBUG(D_ERR, "Error unknown sensor type: 0x%02x%02x",
+		       high, low);
+		return -1;
+	}
+
+	/* Set sensor-specific vars */
+	return 0;
+}
+
+
 /* This initializes the OV8110, OV8610 sensor. The OV8110 uses
  * the same register settings as the OV8610, since they are very similar.
  */
@@ -1966,12 +2951,29 @@
 	return write_regvals(sd, init_519, ARRAY_SIZE(init_519));
 }
 
+static int ovfx2_configure(struct sd *sd)
+{
+	static const struct ov_regvals init_fx2[] = {
+		{ 0x00, 0x60 },
+		{ 0x02, 0x01 },
+		{ 0x0f, 0x1d },
+		{ 0xe9, 0x82 },
+		{ 0xea, 0xc7 },
+		{ 0xeb, 0x10 },
+		{ 0xec, 0xf6 },
+	};
+
+	sd->stopped = 1;
+
+	return write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2));
+}
+
 /* this function is called at probe time */
 static int sd_config(struct gspca_dev *gspca_dev,
 			const struct usb_device_id *id)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	struct cam *cam;
+	struct cam *cam = &gspca_dev->cam;
 	int ret = 0;
 
 	sd->bridge = id->driver_info & BRIDGE_MASK;
@@ -1989,6 +2991,16 @@
 	case BRIDGE_OV519:
 		ret = ov519_configure(sd);
 		break;
+	case BRIDGE_OVFX2:
+		ret = ovfx2_configure(sd);
+		cam->bulk_size = OVFX2_BULK_SIZE;
+		cam->bulk_nurbs = MAX_NURBS;
+		cam->bulk = 1;
+		break;
+	case BRIDGE_W9968CF:
+		ret = w9968cf_configure(sd);
+		cam->reverse_alts = 1;
+		break;
 	}
 
 	if (ret)
@@ -1996,49 +3008,39 @@
 
 	ov51x_led_control(sd, 0);	/* turn LED off */
 
-	/* Test for 76xx */
-	if (ov51x_set_slave_ids(sd, OV7xx0_SID) < 0)
-		goto error;
-
 	/* The OV519 must be more aggressive about sensor detection since
 	 * I2C write will never fail if the sensor is not present. We have
 	 * to try to initialize the sensor to detect its presence */
-	if (init_ov_sensor(sd) >= 0) {
+
+	/* Test for 76xx */
+	if (init_ov_sensor(sd, OV7xx0_SID) >= 0) {
 		if (ov7xx0_configure(sd) < 0) {
 			PDEBUG(D_ERR, "Failed to configure OV7xx0");
 			goto error;
 		}
-	} else {
-
-		/* Test for 6xx0 */
-		if (ov51x_set_slave_ids(sd, OV6xx0_SID) < 0)
+	/* Test for 6xx0 */
+	} else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) {
+		if (ov6xx0_configure(sd) < 0) {
+			PDEBUG(D_ERR, "Failed to configure OV6xx0");
 			goto error;
-
-		if (init_ov_sensor(sd) >= 0) {
-			if (ov6xx0_configure(sd) < 0) {
-				PDEBUG(D_ERR, "Failed to configure OV6xx0");
-				goto error;
-			}
-		} else {
-
-			/* Test for 8xx0 */
-			if (ov51x_set_slave_ids(sd, OV8xx0_SID) < 0)
-				goto error;
-
-			if (init_ov_sensor(sd) < 0) {
-				PDEBUG(D_ERR,
-					"Can't determine sensor slave IDs");
-				goto error;
-			}
-			if (ov8xx0_configure(sd) < 0) {
-				PDEBUG(D_ERR,
-					"Failed to configure OV8xx0 sensor");
-				goto error;
-			}
 		}
+	/* Test for 8xx0 */
+	} else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) {
+		if (ov8xx0_configure(sd) < 0) {
+			PDEBUG(D_ERR, "Failed to configure OV8xx0");
+			goto error;
+		}
+	/* Test for 3xxx / 2xxx */
+	} else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) {
+		if (ov_hires_configure(sd) < 0) {
+			PDEBUG(D_ERR, "Failed to configure high res OV");
+			goto error;
+		}
+	} else {
+		PDEBUG(D_ERR, "Can't determine sensor slave IDs");
+		goto error;
 	}
 
-	cam = &gspca_dev->cam;
 	switch (sd->bridge) {
 	case BRIDGE_OV511:
 	case BRIDGE_OV511PLUS:
@@ -2069,6 +3071,31 @@
 			cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
 		}
 		break;
+	case BRIDGE_OVFX2:
+		if (sd->sensor == SEN_OV2610) {
+			cam->cam_mode = ovfx2_ov2610_mode;
+			cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode);
+		} else if (sd->sensor == SEN_OV3610) {
+			cam->cam_mode = ovfx2_ov3610_mode;
+			cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode);
+		} else if (!sd->sif) {
+			cam->cam_mode = ov519_vga_mode;
+			cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
+		} else {
+			cam->cam_mode = ov519_sif_mode;
+			cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
+		}
+		break;
+	case BRIDGE_W9968CF:
+		cam->cam_mode = w9968cf_vga_mode;
+		cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode);
+		if (sd->sif)
+			cam->nmodes--;
+
+		/* w9968cf needs initialisation once the sensor is known */
+		if (w9968cf_init(sd) < 0)
+			goto error;
+		break;
 	}
 	sd->brightness = BRIGHTNESS_DEF;
 	if (sd->sensor == SEN_OV6630 || sd->sensor == SEN_OV66308AF)
@@ -2087,11 +3114,15 @@
 		gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) |
 				      (1 << OV7670_FREQ_IDX);
 	}
+	sd->quality = QUALITY_DEF;
 	if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670)
 		gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX;
 	/* OV8610 Frequency filter control should work but needs testing */
 	if (sd->sensor == SEN_OV8610)
 		gspca_dev->ctrl_dis |= 1 << FREQ_IDX;
+	/* No controls for the OV2610/OV3610 */
+	if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
+		gspca_dev->ctrl_dis |= 0xFF;
 
 	return 0;
 error:
@@ -2106,6 +3137,20 @@
 
 	/* initialize the sensor */
 	switch (sd->sensor) {
+	case SEN_OV2610:
+		if (write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610)))
+			return -EIO;
+		/* Enable autogain, autoexpo, awb, bandfilter */
+		if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
+			return -EIO;
+		break;
+	case SEN_OV3610:
+		if (write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b)))
+			return -EIO;
+		/* Enable autogain, autoexpo, awb, bandfilter */
+		if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
+			return -EIO;
+		break;
 	case SEN_OV6620:
 		if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)))
 			return -EIO;
@@ -2548,19 +3593,60 @@
 static int mode_init_ov_sensor_regs(struct sd *sd)
 {
 	struct gspca_dev *gspca_dev;
-	int qvga;
+	int qvga, xstart, xend, ystart, yend;
+	__u8 v;
 
 	gspca_dev = &sd->gspca_dev;
 	qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
 
 	/******** Mode (VGA/QVGA) and sensor specific regs ********/
 	switch (sd->sensor) {
+	case SEN_OV2610:
+		i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
+		i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
+		i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
+		i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
+		i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
+		i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
+		i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
+		return 0;
+	case SEN_OV3610:
+		if (qvga) {
+			xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4);
+			ystart = (776 - gspca_dev->height) / 2;
+		} else {
+			xstart = (2076 - gspca_dev->width) / 2 + (0x10 << 4);
+			ystart = (1544 - gspca_dev->height) / 2;
+		}
+		xend = xstart + gspca_dev->width;
+		yend = ystart + gspca_dev->height;
+		/* Writing to the COMH register resets the other windowing regs
+		   to their default values, so we must do this first. */
+		i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0xf0);
+		i2c_w_mask(sd, 0x32,
+			   (((xend >> 1) & 7) << 3) | ((xstart >> 1) & 7),
+			   0x3f);
+		i2c_w_mask(sd, 0x03,
+			   (((yend >> 1) & 3) << 2) | ((ystart >> 1) & 3),
+			   0x0f);
+		i2c_w(sd, 0x17, xstart >> 4);
+		i2c_w(sd, 0x18, xend >> 4);
+		i2c_w(sd, 0x19, ystart >> 3);
+		i2c_w(sd, 0x1a, yend >> 3);
+		return 0;
 	case SEN_OV8610:
 		/* For OV8610 qvga means qsvga */
 		i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5);
+		i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
+		i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
+		i2c_w_mask(sd, 0x2d, 0x00, 0x40); /* from windrv 090403 */
+		i2c_w_mask(sd, 0x28, 0x20, 0x20); /* progressive mode on */
 		break;
 	case SEN_OV7610:
 		i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
+		i2c_w(sd, 0x35, qvga?0x1e:0x9e);
+		i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
+		i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
 		break;
 	case SEN_OV7620:
 	case SEN_OV76BE:
@@ -2571,6 +3657,10 @@
 		i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
 		i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0);
 		i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
+		i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
+		i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
+		if (sd->sensor == SEN_OV76BE)
+			i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
 		break;
 	case SEN_OV7640:
 		i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
@@ -2580,6 +3670,7 @@
 /*		i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); */
 /*		i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); */
 /*		i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); */
+		i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */
 		break;
 	case SEN_OV7670:
 		/* set COM7_FMT_VGA or COM7_FMT_QVGA
@@ -2588,55 +3679,56 @@
 		i2c_w_mask(sd, OV7670_REG_COM7,
 			 qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA,
 			 OV7670_COM7_FMT_MASK);
+		i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
+		i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB,
+				OV7670_COM8_AWB);
+		if (qvga) {		/* QVGA from ov7670.c by
+					 * Jonathan Corbet */
+			xstart = 164;
+			xend = 28;
+			ystart = 14;
+			yend = 494;
+		} else {		/* VGA */
+			xstart = 158;
+			xend = 14;
+			ystart = 10;
+			yend = 490;
+		}
+		/* OV7670 hardware window registers are split across
+		 * multiple locations */
+		i2c_w(sd, OV7670_REG_HSTART, xstart >> 3);
+		i2c_w(sd, OV7670_REG_HSTOP, xend >> 3);
+		v = i2c_r(sd, OV7670_REG_HREF);
+		v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07);
+		msleep(10);	/* need to sleep between read and write to
+				 * same reg! */
+		i2c_w(sd, OV7670_REG_HREF, v);
+
+		i2c_w(sd, OV7670_REG_VSTART, ystart >> 2);
+		i2c_w(sd, OV7670_REG_VSTOP, yend >> 2);
+		v = i2c_r(sd, OV7670_REG_VREF);
+		v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03);
+		msleep(10);	/* need to sleep between read and write to
+				 * same reg! */
+		i2c_w(sd, OV7670_REG_VREF, v);
 		break;
 	case SEN_OV6620:
+		i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
+		i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
+		i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
+		break;
 	case SEN_OV6630:
 	case SEN_OV66308AF:
 		i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
+		i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
 		break;
 	default:
 		return -EINVAL;
 	}
 
-	/******** Palette-specific regs ********/
-
-	/* The OV518 needs special treatment. Although both the OV518
-	 * and the OV6630 support a 16-bit video bus, only the 8 bit Y
-	 * bus is actually used. The UV bus is tied to ground.
-	 * Therefore, the OV6630 needs to be in 8-bit multiplexed
-	 * output mode */
-
-	/* OV7640 is 8-bit only */
-
-	if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV66308AF &&
-					sd->sensor != SEN_OV7640)
-		i2c_w_mask(sd, 0x13, 0x00, 0x20);
-
 	/******** Clock programming ********/
 	i2c_w(sd, 0x11, sd->clockdiv);
 
-	/******** Special Features ********/
-/* no evidence this is possible with OV7670, either */
-	/* Test Pattern */
-	if (sd->sensor != SEN_OV7640 && sd->sensor != SEN_OV7670)
-		i2c_w_mask(sd, 0x12, 0x00, 0x02);
-
-	/* Enable auto white balance */
-	if (sd->sensor == SEN_OV7670)
-		i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB,
-				OV7670_COM8_AWB);
-	else
-		i2c_w_mask(sd, 0x12, 0x04, 0x04);
-
-	/* This will go away as soon as ov51x_mode_init_sensor_regs() */
-	/* is fully tested. */
-	/* 7620/6620/6630? don't have register 0x35, so play it safe */
-	if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) {
-		if (!qvga)
-			i2c_w(sd, 0x35, 0x9e);
-		else
-			i2c_w(sd, 0x35, 0x1e);
-	}
 	return 0;
 }
 
@@ -2659,8 +3751,12 @@
 	struct gspca_dev *gspca_dev;
 	int qvga, crop;
 	int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
-	int ret, hstart, hstop, vstop, vstart;
-	__u8 v;
+	int ret;
+
+	/* mode setup is fully handled in mode_init_ov_sensor_regs for these */
+	if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610 ||
+	    sd->sensor == SEN_OV7670)
+		return mode_init_ov_sensor_regs(sd);
 
 	gspca_dev = &sd->gspca_dev;
 	qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
@@ -2708,11 +3804,6 @@
 		hwebase = 0x1a;
 		vwsbase = vwebase = 0x03;
 		break;
-	case SEN_OV7670:
-		/*handling of OV7670 hardware sensor start and stop values
-		 * is very odd, compared to the other OV sensors */
-		vwsbase = vwebase = hwebase = hwsbase = 0x00;
-		break;
 	default:
 		return -EINVAL;
 	}
@@ -2753,58 +3844,11 @@
 	if (ret < 0)
 		return ret;
 
-	if (sd->sensor == SEN_OV8610) {
-		i2c_w_mask(sd, 0x2d, 0x05, 0x40);
-				/* old 0x95, new 0x05 from windrv 090403 */
-						/* bits 5-7: reserved */
-		i2c_w_mask(sd, 0x28, 0x20, 0x20);
-					/* bit 5: progressive mode on */
-	}
+	i2c_w(sd, 0x17, hwsbase);
+	i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale));
+	i2c_w(sd, 0x19, vwsbase);
+	i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale));
 
-	/* The below is wrong for OV7670s because their window registers
-	 * only store the high bits in 0x17 to 0x1a */
-
-	/* SRH Use sd->max values instead of requested win values */
-	/* SCS Since we're sticking with only the max hardware widths
-	 * for a given mode */
-	/* I can hard code this for OV7670s */
-	/* Yes, these numbers do look odd, but they're tested and work! */
-	if (sd->sensor == SEN_OV7670) {
-		if (qvga) {		/* QVGA from ov7670.c by
-					 * Jonathan Corbet */
-			hstart = 164;
-			hstop = 28;
-			vstart = 14;
-			vstop = 494;
-		} else {		/* VGA */
-			hstart = 158;
-			hstop = 14;
-			vstart = 10;
-			vstop = 490;
-		}
-		/* OV7670 hardware window registers are split across
-		 * multiple locations */
-		i2c_w(sd, OV7670_REG_HSTART, hstart >> 3);
-		i2c_w(sd, OV7670_REG_HSTOP, hstop >> 3);
-		v = i2c_r(sd, OV7670_REG_HREF);
-		v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07);
-		msleep(10);	/* need to sleep between read and write to
-				 * same reg! */
-		i2c_w(sd, OV7670_REG_HREF, v);
-
-		i2c_w(sd, OV7670_REG_VSTART, vstart >> 2);
-		i2c_w(sd, OV7670_REG_VSTOP, vstop >> 2);
-		v = i2c_r(sd, OV7670_REG_VREF);
-		v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03);
-		msleep(10);	/* need to sleep between read and write to
-				 * same reg! */
-		i2c_w(sd, OV7670_REG_VREF, v);
-	} else {
-		i2c_w(sd, 0x17, hwsbase);
-		i2c_w(sd, 0x18, hwebase + (sd->gspca_dev.width >> hwscale));
-		i2c_w(sd, 0x19, vwsbase);
-		i2c_w(sd, 0x1a, vwebase + (sd->gspca_dev.height >> vwscale));
-	}
 	return 0;
 }
 
@@ -2814,6 +3858,10 @@
 	struct sd *sd = (struct sd *) gspca_dev;
 	int ret = 0;
 
+	/* Default for most bridges, allow bridge_mode_init_regs to override */
+	sd->sensor_width = sd->gspca_dev.width;
+	sd->sensor_height = sd->gspca_dev.height;
+
 	switch (sd->bridge) {
 	case BRIDGE_OV511:
 	case BRIDGE_OV511PLUS:
@@ -2826,6 +3874,10 @@
 	case BRIDGE_OV519:
 		ret = ov519_mode_init_regs(sd);
 		break;
+	/* case BRIDGE_OVFX2: nothing to do */
+	case BRIDGE_W9968CF:
+		ret = w9968cf_mode_init_regs(sd);
+		break;
 	}
 	if (ret < 0)
 		goto out;
@@ -2859,10 +3911,17 @@
 	ov51x_led_control(sd, 0);
 }
 
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->bridge == BRIDGE_W9968CF)
+		w9968cf_stop0(sd);
+}
+
 static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *in,			/* isoc packet */
-			int len)			/* iso packet length */
+			u8 *in,			/* isoc packet */
+			int len)		/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
@@ -2893,11 +3952,11 @@
 				return;
 			}
 			/* Add 11 byte footer to frame, might be usefull */
-			gspca_frame_add(gspca_dev, LAST_PACKET, frame, in, 11);
+			gspca_frame_add(gspca_dev, LAST_PACKET, in, 11);
 			return;
 		} else {
 			/* Frame start */
-			gspca_frame_add(gspca_dev, FIRST_PACKET, frame, in, 0);
+			gspca_frame_add(gspca_dev, FIRST_PACKET, in, 0);
 			sd->packet_nr = 0;
 		}
 	}
@@ -2906,12 +3965,11 @@
 	len--;
 
 	/* intermediate packet */
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, in, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, in, len);
 }
 
 static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -2919,8 +3977,8 @@
 	/* A false positive here is likely, until OVT gives me
 	 * the definitive SOF/EOF format */
 	if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0);
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0);
+		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
 		sd->packet_nr = 0;
 	}
 
@@ -2944,12 +4002,11 @@
 	}
 
 	/* intermediate packet */
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	/* Header of ov519 is 16 bytes:
@@ -2972,7 +4029,7 @@
 			len -= HDRSZ;
 #undef HDRSZ
 			if (data[0] == 0xff || data[1] == 0xd8)
-				gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+				gspca_frame_add(gspca_dev, FIRST_PACKET,
 						data, len);
 			else
 				gspca_dev->last_packet_type = DISCARD_PACKET;
@@ -2980,20 +4037,31 @@
 		case 0x51:		/* end of frame */
 			if (data[9] != 0)
 				gspca_dev->last_packet_type = DISCARD_PACKET;
-			gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-					data, 0);
+			gspca_frame_add(gspca_dev, LAST_PACKET,
+					NULL, 0);
 			return;
 		}
 	}
 
 	/* intermediate packet */
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame,
-			data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
+}
+
+static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
+			u8 *data,			/* isoc packet */
+			int len)			/* iso packet length */
+{
+	/* A short read signals EOF */
+	if (len < OVFX2_BULK_SIZE) {
+		gspca_frame_add(gspca_dev, LAST_PACKET, data, len);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
+		return;
+	}
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -3001,14 +4069,20 @@
 	switch (sd->bridge) {
 	case BRIDGE_OV511:
 	case BRIDGE_OV511PLUS:
-		ov511_pkt_scan(gspca_dev, frame, data, len);
+		ov511_pkt_scan(gspca_dev, data, len);
 		break;
 	case BRIDGE_OV518:
 	case BRIDGE_OV518PLUS:
-		ov518_pkt_scan(gspca_dev, frame, data, len);
+		ov518_pkt_scan(gspca_dev, data, len);
 		break;
 	case BRIDGE_OV519:
-		ov519_pkt_scan(gspca_dev, frame, data, len);
+		ov519_pkt_scan(gspca_dev, data, len);
+		break;
+	case BRIDGE_OVFX2:
+		ovfx2_pkt_scan(gspca_dev, data, len);
+		break;
+	case BRIDGE_W9968CF:
+		w9968cf_pkt_scan(gspca_dev, data, len);
 		break;
 	}
 }
@@ -3124,7 +4198,8 @@
 
 static void setautobrightness(struct sd *sd)
 {
-	if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670)
+	if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670 ||
+	    sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
 		return;
 
 	i2c_w_mask(sd, 0x2d, sd->autobrightness ? 0x10 : 0x00, 0x10);
@@ -3132,6 +4207,9 @@
 
 static void setfreq(struct sd *sd)
 {
+	if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
+		return;
+
 	if (sd->sensor == SEN_OV7670) {
 		switch (sd->freq) {
 		case 0: /* Banding filter disabled */
@@ -3301,8 +4379,12 @@
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	sd->freq = val;
-	if (gspca_dev->streaming)
+	if (gspca_dev->streaming) {
 		setfreq(sd);
+		/* Ugly but necessary */
+		if (sd->bridge == BRIDGE_W9968CF)
+			w9968cf_set_crop_window(sd);
+	}
 	return 0;
 }
 
@@ -3343,6 +4425,45 @@
 	return -EINVAL;
 }
 
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+			struct v4l2_jpegcompression *jcomp)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->bridge != BRIDGE_W9968CF)
+		return -EINVAL;
+
+	memset(jcomp, 0, sizeof *jcomp);
+	jcomp->quality = sd->quality;
+	jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT |
+			      V4L2_JPEG_MARKER_DRI;
+	return 0;
+}
+
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+			struct v4l2_jpegcompression *jcomp)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->bridge != BRIDGE_W9968CF)
+		return -EINVAL;
+
+	if (gspca_dev->streaming)
+		return -EBUSY;
+
+	if (jcomp->quality < QUALITY_MIN)
+		sd->quality = QUALITY_MIN;
+	else if (jcomp->quality > QUALITY_MAX)
+		sd->quality = QUALITY_MAX;
+	else
+		sd->quality = jcomp->quality;
+
+	/* Return resulting jcomp params to app */
+	sd_get_jcomp(gspca_dev, jcomp);
+
+	return 0;
+}
+
 /* sub-driver description */
 static const struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
@@ -3352,18 +4473,23 @@
 	.init = sd_init,
 	.start = sd_start,
 	.stopN = sd_stopN,
+	.stop0 = sd_stop0,
 	.pkt_scan = sd_pkt_scan,
 	.querymenu = sd_querymenu,
+	.get_jcomp = sd_get_jcomp,
+	.set_jcomp = sd_set_jcomp,
 };
 
 /* -- module initialisation -- */
 static const __devinitdata struct usb_device_id device_table[] = {
+	{USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF },
 	{USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x041e, 0x4064),
 	 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
+	{USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x041e, 0x4068),
 	 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
 	{USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
@@ -3373,11 +4499,16 @@
 	{USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
 	{USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 },
+	{USB_DEVICE(0x05a9, 0x2800), .driver_info = BRIDGE_OVFX2 },
 	{USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x05a9, 0xa511), .driver_info = BRIDGE_OV511PLUS },
 	{USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS },
 	{USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS },
+	{USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 },
+	{USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 },
+	{USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF },
+	{USB_DEVICE(0x8020, 0xEF04), .driver_info = BRIDGE_OVFX2 },
 	{}
 };
 
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 4b528b3..4dbb882 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -1,5 +1,6 @@
 /*
  * ov534 gspca driver
+ *
  * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
  * Copyright (C) 2008 Jim Paris <jim@jtan.com>
  * Copyright (C) 2009 Jean-Francois Moine http://moinejf.free.fr
@@ -8,6 +9,10 @@
  * USB protocol reverse engineered by Jim Paris <jim@jtan.com>
  * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/
  *
+ * PS3 Eye camera enhanced by Richard Kaswy http://kaswy.free.fr
+ * PS3 Eye camera, brightness, contrast, hue, AWB control added
+ *	by Max Thrun <bear24rw@gmail.com>
+ *
  * 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
@@ -51,16 +56,335 @@
 	u16 last_fid;
 	u8 frame_rate;
 
+	u8 brightness;
+	u8 contrast;
+	u8 gain;
+	u8 exposure;
+	u8 redblc;
+	u8 blueblc;
+	u8 hue;
+	u8 autogain;
+	u8 awb;
+	s8 sharpness;
+	u8 hflip;
+	u8 vflip;
+	u8 satur;
+	u8 lightfreq;
+
 	u8 sensor;
 #define SENSOR_OV772X 0
 #define SENSOR_OV965X 1
 };
 
 /* V4L2 controls supported by the driver */
-static struct ctrl sd_ctrls[] = {
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getredblc(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setblueblc(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getblueblc(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
+
+static struct ctrl sd_ctrls_ov772x[] = {
+    {							/* 0 */
+	{
+		.id      = V4L2_CID_BRIGHTNESS,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Brightness",
+		.minimum = 0,
+		.maximum = 255,
+		.step    = 1,
+#define BRIGHTNESS_77_DEF 20
+		.default_value = BRIGHTNESS_77_DEF,
+	},
+	.set = sd_setbrightness,
+	.get = sd_getbrightness,
+    },
+    {							/* 1 */
+	{
+		.id      = V4L2_CID_CONTRAST,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Contrast",
+		.minimum = 0,
+		.maximum = 255,
+		.step    = 1,
+#define CONTRAST_77_DEF 37
+		.default_value = CONTRAST_77_DEF,
+	},
+	.set = sd_setcontrast,
+	.get = sd_getcontrast,
+    },
+    {							/* 2 */
+	{
+	    .id      = V4L2_CID_GAIN,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Main Gain",
+	    .minimum = 0,
+	    .maximum = 63,
+	    .step    = 1,
+#define GAIN_DEF 20
+	    .default_value = GAIN_DEF,
+	},
+	.set = sd_setgain,
+	.get = sd_getgain,
+    },
+    {							/* 3 */
+	{
+	    .id      = V4L2_CID_EXPOSURE,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Exposure",
+	    .minimum = 0,
+	    .maximum = 255,
+	    .step    = 1,
+#define EXPO_77_DEF 120
+	    .default_value = EXPO_77_DEF,
+	},
+	.set = sd_setexposure,
+	.get = sd_getexposure,
+    },
+    {							/* 4 */
+	{
+	    .id      = V4L2_CID_RED_BALANCE,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Red Balance",
+	    .minimum = 0,
+	    .maximum = 255,
+	    .step    = 1,
+#define RED_BALANCE_DEF 128
+	    .default_value = RED_BALANCE_DEF,
+	},
+	.set = sd_setredblc,
+	.get = sd_getredblc,
+    },
+    {							/* 5 */
+	{
+	    .id      = V4L2_CID_BLUE_BALANCE,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Blue Balance",
+	    .minimum = 0,
+	    .maximum = 255,
+	    .step    = 1,
+#define BLUE_BALANCE_DEF 128
+	    .default_value = BLUE_BALANCE_DEF,
+	},
+	.set = sd_setblueblc,
+	.get = sd_getblueblc,
+    },
+    {							/* 6 */
+	{
+		.id      = V4L2_CID_HUE,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Hue",
+		.minimum = 0,
+		.maximum = 255,
+		.step    = 1,
+#define HUE_DEF 143
+		.default_value = HUE_DEF,
+	},
+	.set = sd_sethue,
+	.get = sd_gethue,
+    },
+    {							/* 7 */
+	{
+	    .id      = V4L2_CID_AUTOGAIN,
+	    .type    = V4L2_CTRL_TYPE_BOOLEAN,
+	    .name    = "Autogain",
+	    .minimum = 0,
+	    .maximum = 1,
+	    .step    = 1,
+#define AUTOGAIN_77_DEF 0
+	    .default_value = AUTOGAIN_77_DEF,
+	},
+	.set = sd_setautogain,
+	.get = sd_getautogain,
+    },
+#define AWB_77_IDX 8
+    {							/* 8 */
+	{
+		.id      = V4L2_CID_AUTO_WHITE_BALANCE,
+		.type    = V4L2_CTRL_TYPE_BOOLEAN,
+		.name    = "Auto White Balance",
+		.minimum = 0,
+		.maximum = 1,
+		.step    = 1,
+#define AWB_DEF 0
+		.default_value = AWB_DEF,
+	},
+	.set = sd_setawb,
+	.get = sd_getawb,
+    },
+    {							/* 9 */
+	{
+	    .id      = V4L2_CID_SHARPNESS,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Sharpness",
+	    .minimum = 0,
+	    .maximum = 63,
+	    .step    = 1,
+#define SHARPNESS_77_DEF 0
+	    .default_value = SHARPNESS_77_DEF,
+	},
+	.set = sd_setsharpness,
+	.get = sd_getsharpness,
+    },
+    {							/* 10 */
+	{
+	    .id      = V4L2_CID_HFLIP,
+	    .type    = V4L2_CTRL_TYPE_BOOLEAN,
+	    .name    = "HFlip",
+	    .minimum = 0,
+	    .maximum = 1,
+	    .step    = 1,
+#define HFLIP_DEF 0
+	    .default_value = HFLIP_DEF,
+	},
+	.set = sd_sethflip,
+	.get = sd_gethflip,
+    },
+    {							/* 11 */
+	{
+	    .id      = V4L2_CID_VFLIP,
+	    .type    = V4L2_CTRL_TYPE_BOOLEAN,
+	    .name    = "VFlip",
+	    .minimum = 0,
+	    .maximum = 1,
+	    .step    = 1,
+#define VFLIP_DEF 0
+	    .default_value = VFLIP_DEF,
+	},
+	.set = sd_setvflip,
+	.get = sd_getvflip,
+    },
+};
+static struct ctrl sd_ctrls_ov965x[] = {
+    {							/* 0 */
+	{
+		.id      = V4L2_CID_BRIGHTNESS,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Brightness",
+		.minimum = 0,
+		.maximum = 15,
+		.step    = 1,
+#define BRIGHTNESS_96_DEF 7
+		.default_value = BRIGHTNESS_96_DEF,
+	},
+	.set = sd_setbrightness,
+	.get = sd_getbrightness,
+    },
+    {							/* 1 */
+	{
+		.id      = V4L2_CID_CONTRAST,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Contrast",
+		.minimum = 0,
+		.maximum = 15,
+		.step    = 1,
+#define CONTRAST_96_DEF 3
+		.default_value = CONTRAST_96_DEF,
+	},
+	.set = sd_setcontrast,
+	.get = sd_getcontrast,
+    },
+    {							/* 2 */
+	{
+	    .id      = V4L2_CID_AUTOGAIN,
+	    .type    = V4L2_CTRL_TYPE_BOOLEAN,
+	    .name    = "Autogain",
+	    .minimum = 0,
+	    .maximum = 1,
+	    .step    = 1,
+#define AUTOGAIN_96_DEF 1
+	    .default_value = AUTOGAIN_96_DEF,
+	},
+	.set = sd_setautogain,
+	.get = sd_getautogain,
+    },
+#define EXPO_96_IDX 3
+    {							/* 3 */
+	{
+	    .id      = V4L2_CID_EXPOSURE,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Exposure",
+	    .minimum = 0,
+	    .maximum = 3,
+	    .step    = 1,
+#define EXPO_96_DEF 0
+	    .default_value = EXPO_96_DEF,
+	},
+	.set = sd_setexposure,
+	.get = sd_getexposure,
+    },
+    {							/* 4 */
+	{
+	    .id      = V4L2_CID_SHARPNESS,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Sharpness",
+	    .minimum = -1,		/* -1 = auto */
+	    .maximum = 4,
+	    .step    = 1,
+#define SHARPNESS_96_DEF -1
+	    .default_value = SHARPNESS_96_DEF,
+	},
+	.set = sd_setsharpness,
+	.get = sd_getsharpness,
+    },
+    {							/* 5 */
+	{
+		.id      = V4L2_CID_SATURATION,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Saturation",
+		.minimum = 0,
+		.maximum = 4,
+		.step    = 1,
+#define SATUR_DEF 2
+		.default_value = SATUR_DEF,
+	},
+	.set = sd_setsatur,
+	.get = sd_getsatur,
+    },
+    {
+	{
+		.id	 = V4L2_CID_POWER_LINE_FREQUENCY,
+		.type    = V4L2_CTRL_TYPE_MENU,
+		.name    = "Light frequency filter",
+		.minimum = 0,
+		.maximum = 2,	/* 0: 0, 1: 50Hz, 2:60Hz */
+		.step    = 1,
+#define FREQ_DEF 0
+		.default_value = FREQ_DEF,
+	},
+	.set = sd_setfreq,
+	.get = sd_getfreq,
+    },
 };
 
-static const struct v4l2_pix_format vga_yuyv_mode[] = {
+static const struct v4l2_pix_format ov772x_mode[] = {
+	{320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
+	 .bytesperline = 320 * 2,
+	 .sizeimage = 320 * 240 * 2,
+	 .colorspace = V4L2_COLORSPACE_SRGB,
+	 .priv = 1},
 	{640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
 	 .bytesperline = 640 * 2,
 	 .sizeimage = 640 * 480 * 2,
@@ -68,20 +392,35 @@
 	 .priv = 0},
 };
 
-static const struct v4l2_pix_format vga_jpeg_mode[] = {
+static const struct v4l2_pix_format ov965x_mode[] = {
 	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 	 .bytesperline = 320,
 	 .sizeimage = 320 * 240 * 3 / 8 + 590,
 	 .colorspace = V4L2_COLORSPACE_JPEG,
-	 .priv = 1},
+	 .priv = 4},
 	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 	 .bytesperline = 640,
 	 .sizeimage = 640 * 480 * 3 / 8 + 590,
 	 .colorspace = V4L2_COLORSPACE_JPEG,
+	 .priv = 3},
+	{800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+	 .bytesperline = 800,
+	 .sizeimage = 800 * 600 * 3 / 8 + 590,
+	 .colorspace = V4L2_COLORSPACE_JPEG,
+	 .priv = 2},
+	{1024, 768, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+	 .bytesperline = 1024,
+	 .sizeimage = 1024 * 768 * 3 / 8 + 590,
+	 .colorspace = V4L2_COLORSPACE_JPEG,
+	 .priv = 1},
+	{1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+	 .bytesperline = 1280,
+	 .sizeimage = 1280 * 1024 * 3 / 8 + 590,
+	 .colorspace = V4L2_COLORSPACE_JPEG,
 	 .priv = 0},
 };
 
-static const u8 bridge_init_ov722x[][2] = {
+static const u8 bridge_init_ov772x[][2] = {
 	{ 0xc2, 0x0c },
 	{ 0x88, 0xf8 },
 	{ 0xc3, 0x69 },
@@ -122,6 +461,7 @@
 	{ 0x1d, 0x40 },
 	{ 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */
 	{ 0x1d, 0x00 }, /* payload size */
+
 	{ 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */
 	{ 0x1d, 0x58 }, /* frame size */
 	{ 0x1d, 0x00 }, /* frame size */
@@ -138,10 +478,20 @@
 	{ 0xc1, 0x3c },
 	{ 0xc2, 0x0c },
 };
-
-static const u8 sensor_init_ov722x[][2] = {
+static const u8 sensor_init_ov772x[][2] = {
 	{ 0x12, 0x80 },
 	{ 0x11, 0x01 },
+/*fixme: better have a delay?*/
+	{ 0x11, 0x01 },
+	{ 0x11, 0x01 },
+	{ 0x11, 0x01 },
+	{ 0x11, 0x01 },
+	{ 0x11, 0x01 },
+	{ 0x11, 0x01 },
+	{ 0x11, 0x01 },
+	{ 0x11, 0x01 },
+	{ 0x11, 0x01 },
+	{ 0x11, 0x01 },
 
 	{ 0x3d, 0x03 },
 	{ 0x17, 0x26 },
@@ -154,10 +504,10 @@
 	{ 0x65, 0x20 },
 	{ 0x11, 0x01 },
 	{ 0x42, 0x7f },
-	{ 0x63, 0xe0 },
+	{ 0x63, 0xaa },		/* AWB - was e0 */
 	{ 0x64, 0xff },
 	{ 0x66, 0x00 },
-	{ 0x13, 0xf0 },
+	{ 0x13, 0xf0 },		/* com8 */
 	{ 0x0d, 0x41 },
 	{ 0x0f, 0xc5 },
 	{ 0x14, 0x11 },
@@ -170,7 +520,7 @@
 	{ 0x2a, 0x00 },
 	{ 0x2b, 0x00 },
 	{ 0x6b, 0xaa },
-	{ 0x13, 0xff },
+	{ 0x13, 0xff },		/* AWB */
 
 	{ 0x90, 0x05 },
 	{ 0x91, 0x01 },
@@ -218,9 +568,51 @@
 	{ 0x14, 0x41 },
 	{ 0x0e, 0xcd },
 	{ 0xac, 0xbf },
-	{ 0x8e, 0x00 },
+	{ 0x8e, 0x00 },		/* De-noise threshold */
 	{ 0x0c, 0xd0 }
 };
+static const u8 bridge_start_ov772x_vga[][2] = {
+	{0x1c, 0x00},
+	{0x1d, 0x40},
+	{0x1d, 0x02},
+	{0x1d, 0x00},
+	{0x1d, 0x02},
+	{0x1d, 0x58},
+	{0x1d, 0x00},
+	{0xc0, 0x50},
+	{0xc1, 0x3c},
+};
+static const u8 sensor_start_ov772x_vga[][2] = {
+	{0x12, 0x00},
+	{0x17, 0x26},
+	{0x18, 0xa0},
+	{0x19, 0x07},
+	{0x1a, 0xf0},
+	{0x29, 0xa0},
+	{0x2c, 0xf0},
+	{0x65, 0x20},
+};
+static const u8 bridge_start_ov772x_qvga[][2] = {
+	{0x1c, 0x00},
+	{0x1d, 0x40},
+	{0x1d, 0x02},
+	{0x1d, 0x00},
+	{0x1d, 0x01},
+	{0x1d, 0x4b},
+	{0x1d, 0x00},
+	{0xc0, 0x28},
+	{0xc1, 0x1e},
+};
+static const u8 sensor_start_ov772x_qvga[][2] = {
+	{0x12, 0x40},
+	{0x17, 0x3f},
+	{0x18, 0x50},
+	{0x19, 0x03},
+	{0x1a, 0x78},
+	{0x29, 0x50},
+	{0x2c, 0x78},
+	{0x65, 0x2f},
+};
 
 static const u8 bridge_init_ov965x[][2] = {
 	{0x88, 0xf8},
@@ -403,7 +795,7 @@
 	{0xcb, 0xf0},
 	{0xcc, 0xd8},
 	{0xcd, 0xf1},
-	{0x4f, 0x98},
+	{0x4f, 0x98},	/* matrix */
 	{0x50, 0x98},
 	{0x51, 0x00},
 	{0x52, 0x28},
@@ -412,6 +804,7 @@
 	{0x58, 0x1a},
 	{0xff, 0x41},	/* read 41, write ff 00 */
 	{0x41, 0x40},	/* com16 */
+
 	{0xc5, 0x03},	/* 60 Hz banding filter */
 	{0x6a, 0x02},	/* 50 Hz banding filter */
 
@@ -455,8 +848,8 @@
 	{0x52, 0x3c},
 	{0x53, 0x00},
 	{0x54, 0x00},
-	{0x55, 0x00},	/* brightness */
-	{0x57, 0x00},	/* contrast 2 */
+	{0x55, 0x00},
+	{0x57, 0x00},
 	{0x5c, 0x00},
 	{0x5a, 0xa0},
 	{0x5b, 0x78},
@@ -479,14 +872,16 @@
 	{0xa3, 0x3e},
 	{0x2d, 0x00},
 	{0xff, 0x42},	/* read 42, write ff 00 */
-	{0x42, 0xc0},
+	{0x42, 0xc0},	/* com17 */
 	{0x2d, 0x00},
 	{0xff, 0x42},	/* read 42, write ff 00 */
-	{0x42, 0xc1},
+	{0x42, 0xc1},	/* com17 */
+/* sharpness */
 	{0x3f, 0x01},
 	{0xff, 0x42},	/* read 42, write ff 00 */
-	{0x42, 0xc1},
-	{0x4f, 0x98},
+	{0x42, 0xc1},	/* com17 */
+/* saturation */
+	{0x4f, 0x98},	/* matrix */
 	{0x50, 0x98},
 	{0x51, 0x00},
 	{0x52, 0x28},
@@ -495,14 +890,17 @@
 	{0x58, 0x1a},
 	{0xff, 0x41},	/* read 41, write ff 00 */
 	{0x41, 0x40},	/* com16 */
+/* contrast */
 	{0x56, 0x40},
+/* brightness */
 	{0x55, 0x8f},
+/* expo */
 	{0x10, 0x25},	/* aech - exposure high bits */
 	{0xff, 0x13},	/* read 13, write ff 00 */
 	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
 };
 
-static const u8 sensor_start_ov965x[][2] = {
+static const u8 sensor_start_ov965x_1_vga[][2] = {	/* same for qvga */
 	{0x12, 0x62},	/* com7 - 30fps VGA YUV */
 	{0x36, 0xfa},	/* aref3 */
 	{0x69, 0x0a},	/* hv */
@@ -523,10 +921,77 @@
 	{0x1a, 0x3d},	/* vstop */
 	{0x32, 0xff},	/* href */
 	{0xc0, 0xaa},
-	{}
 };
 
-static const u8 bridge_start_ov965x[][2] = {
+static const u8 sensor_start_ov965x_1_svga[][2] = {
+	{0x12, 0x02},	/* com7 - YUYV - VGA 15 full resolution */
+	{0x36, 0xf8},	/* aref3 */
+	{0x69, 0x02},	/* hv */
+	{0x8c, 0x0d},	/* com22 */
+	{0x3e, 0x0c},	/* com14 */
+	{0x41, 0x40},	/* com16 */
+	{0x72, 0x00},
+	{0x73, 0x01},
+	{0x74, 0x3a},
+	{0x75, 0x35},
+	{0x76, 0x01},
+	{0xc7, 0x80},	/* com24 */
+	{0x03, 0x1b},	/* vref */
+	{0x17, 0x1d},	/* hstart */
+	{0x18, 0xbd},	/* hstop */
+	{0x19, 0x01},	/* vstrt */
+	{0x1a, 0x81},	/* vstop */
+	{0x32, 0xff},	/* href */
+	{0xc0, 0xe2},
+};
+
+static const u8 sensor_start_ov965x_1_xga[][2] = {
+	{0x12, 0x02},	/* com7 */
+	{0x36, 0xf8},	/* aref3 */
+	{0x69, 0x02},	/* hv */
+	{0x8c, 0x89},	/* com22 */
+	{0x14, 0x28},	/* com9 */
+	{0x3e, 0x0c},	/* com14 */
+	{0x41, 0x40},	/* com16 */
+	{0x72, 0x00},
+	{0x73, 0x01},
+	{0x74, 0x3a},
+	{0x75, 0x35},
+	{0x76, 0x01},
+	{0xc7, 0x80},	/* com24 */
+	{0x03, 0x1b},	/* vref */
+	{0x17, 0x1d},	/* hstart */
+	{0x18, 0xbd},	/* hstop */
+	{0x19, 0x01},	/* vstrt */
+	{0x1a, 0x81},	/* vstop */
+	{0x32, 0xff},	/* href */
+	{0xc0, 0xe2},
+};
+
+static const u8 sensor_start_ov965x_1_sxga[][2] = {
+	{0x12, 0x02},	/* com7 */
+	{0x36, 0xf8},	/* aref3 */
+	{0x69, 0x02},	/* hv */
+	{0x8c, 0x89},	/* com22 */
+	{0x14, 0x28},	/* com9 */
+	{0x3e, 0x0c},	/* com14 */
+	{0x41, 0x40},	/* com16 */
+	{0x72, 0x00},
+	{0x73, 0x01},
+	{0x74, 0x3a},
+	{0x75, 0x35},
+	{0x76, 0x01},
+	{0xc7, 0x80},	/* com24 */
+	{0x03, 0x1b},	/* vref */
+	{0x17, 0x1d},	/* hstart */
+	{0x18, 0x02},	/* hstop */
+	{0x19, 0x01},	/* vstrt */
+	{0x1a, 0x81},	/* vstop */
+	{0x32, 0xff},	/* href */
+	{0xc0, 0xe2},
+};
+
+static const u8 bridge_start_ov965x_qvga[][2] = {
 	{0x94, 0xaa},
 	{0xf1, 0x60},
 	{0xe5, 0x04},
@@ -535,30 +1000,7 @@
 	{0x8c, 0x00},
 	{0x8d, 0x1c},
 	{0x34, 0x05},
-	{}
-};
 
-static const u8 bridge_start_ov965x_vga[][2] = {
-	{0xc2, 0x0c},
-	{0xc3, 0xf9},
-	{0xda, 0x01},
-	{0x50, 0x00},
-	{0x51, 0xa0},
-	{0x52, 0x3c},
-	{0x53, 0x00},
-	{0x54, 0x00},
-	{0x55, 0x00},
-	{0x57, 0x00},
-	{0x5c, 0x00},
-	{0x5a, 0xa0},
-	{0x5b, 0x78},
-	{0x35, 0x02},
-	{0xd9, 0x10},
-	{0x94, 0x11},
-	{}
-};
-
-static const u8 bridge_start_ov965x_cif[][2] = {
 	{0xc2, 0x4c},
 	{0xc3, 0xf9},
 	{0xda, 0x00},
@@ -575,27 +1017,107 @@
 	{0x35, 0x02},
 	{0xd9, 0x10},
 	{0x94, 0x11},
-	{}
 };
 
-static const u8 sensor_start_ov965x_vga[][2] = {
-	{0x3b, 0xc4},	/* com11 - night mode 1/4 frame rate */
-	{0x1e, 0x04},	/* mvfp */
-	{0x13, 0xe0},	/* com8 */
-	{0x00, 0x00},
-	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
-	{0x11, 0x03},	/* clkrc */
-	{0x6b, 0x5a},	/* dblv */
-	{0x6a, 0x05},	/* 50 Hz banding filter */
-	{0xc5, 0x07},	/* 60 Hz banding filter */
-	{0xa2, 0x4b},	/* bd50 */
-	{0xa3, 0x3e},	/* bd60 */
-
-	{0x2d, 0x00},	/* advfl */
-	{}
+static const u8 bridge_start_ov965x_vga[][2] = {
+	{0x94, 0xaa},
+	{0xf1, 0x60},
+	{0xe5, 0x04},
+	{0xc0, 0x50},
+	{0xc1, 0x3c},
+	{0x8c, 0x00},
+	{0x8d, 0x1c},
+	{0x34, 0x05},
+	{0xc2, 0x0c},
+	{0xc3, 0xf9},
+	{0xda, 0x01},
+	{0x50, 0x00},
+	{0x51, 0xa0},
+	{0x52, 0x3c},
+	{0x53, 0x00},
+	{0x54, 0x00},
+	{0x55, 0x00},
+	{0x57, 0x00},
+	{0x5c, 0x00},
+	{0x5a, 0xa0},
+	{0x5b, 0x78},
+	{0x35, 0x02},
+	{0xd9, 0x10},
+	{0x94, 0x11},
 };
 
-static const u8 sensor_start_ov965x_cif[][2] = {
+static const u8 bridge_start_ov965x_svga[][2] = {
+	{0x94, 0xaa},
+	{0xf1, 0x60},
+	{0xe5, 0x04},
+	{0xc0, 0xa0},
+	{0xc1, 0x80},
+	{0x8c, 0x00},
+	{0x8d, 0x1c},
+	{0x34, 0x05},
+	{0xc2, 0x4c},
+	{0xc3, 0xf9},
+	{0x50, 0x00},
+	{0x51, 0x40},
+	{0x52, 0x00},
+	{0x53, 0x00},
+	{0x54, 0x00},
+	{0x55, 0x88},
+	{0x57, 0x00},
+	{0x5c, 0x00},
+	{0x5a, 0xc8},
+	{0x5b, 0x96},
+	{0x35, 0x02},
+	{0xd9, 0x10},
+	{0xda, 0x00},
+	{0x94, 0x11},
+};
+
+static const u8 bridge_start_ov965x_xga[][2] = {
+	{0x94, 0xaa},
+	{0xf1, 0x60},
+	{0xe5, 0x04},
+	{0xc0, 0xa0},
+	{0xc1, 0x80},
+	{0x8c, 0x00},
+	{0x8d, 0x1c},
+	{0x34, 0x05},
+	{0xc2, 0x4c},
+	{0xc3, 0xf9},
+	{0x50, 0x00},
+	{0x51, 0x40},
+	{0x52, 0x00},
+	{0x53, 0x00},
+	{0x54, 0x00},
+	{0x55, 0x88},
+	{0x57, 0x00},
+	{0x5c, 0x01},
+	{0x5a, 0x00},
+	{0x5b, 0xc0},
+	{0x35, 0x02},
+	{0xd9, 0x10},
+	{0xda, 0x01},
+	{0x94, 0x11},
+};
+
+static const u8 bridge_start_ov965x_sxga[][2] = {
+	{0x94, 0xaa},
+	{0xf1, 0x60},
+	{0xe5, 0x04},
+	{0xc0, 0xa0},
+	{0xc1, 0x80},
+	{0x8c, 0x00},
+	{0x8d, 0x1c},
+	{0x34, 0x05},
+	{0xc2, 0x0c},
+	{0xc3, 0xf9},
+	{0xda, 0x00},
+	{0x35, 0x02},
+	{0xd9, 0x10},
+	{0x94, 0x11},
+};
+
+static const u8 sensor_start_ov965x_2_qvga[][2] = {
 	{0x3b, 0xe4},	/* com11 - night mode 1/4 frame rate */
 	{0x1e, 0x04},	/* mvfp */
 	{0x13, 0xe0},	/* com8 */
@@ -611,15 +1133,51 @@
 	{0xff, 0x13},	/* read 13, write ff 00 */
 	{0x13, 0xe7},
 	{0x3a, 0x80},	/* tslb - yuyv */
-	{}
 };
 
-static const u8 sensor_start_ov965x_2[][2] = {
-	{0xff, 0x42},	/* read 42, write ff 00 */
-	{0x42, 0xc1},	/* com17 - 50 Hz filter */
-	{}
+static const u8 sensor_start_ov965x_2_vga[][2] = {
+	{0x3b, 0xc4},	/* com11 - night mode 1/4 frame rate */
+	{0x1e, 0x04},	/* mvfp */
+	{0x13, 0xe0},	/* com8 */
+	{0x00, 0x00},
+	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
+	{0x11, 0x03},	/* clkrc */
+	{0x6b, 0x5a},	/* dblv */
+	{0x6a, 0x05},	/* 50 Hz banding filter */
+	{0xc5, 0x07},	/* 60 Hz banding filter */
+	{0xa2, 0x4b},	/* bd50 */
+	{0xa3, 0x3e},	/* bd60 */
+
+	{0x2d, 0x00},	/* advfl */
 };
 
+static const u8 sensor_start_ov965x_2_svga[][2] = {	/* same for xga */
+	{0x3b, 0xc4},	/* com11 - night mode 1/4 frame rate */
+	{0x1e, 0x04},	/* mvfp */
+	{0x13, 0xe0},	/* com8 */
+	{0x00, 0x00},
+	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
+	{0x11, 0x01},	/* clkrc */
+	{0x6b, 0x5a},	/* dblv */
+	{0x6a, 0x0c},	/* 50 Hz banding filter */
+	{0xc5, 0x0f},	/* 60 Hz banding filter */
+	{0xa2, 0x4e},	/* bd50 */
+	{0xa3, 0x41},	/* bd60 */
+};
+
+static const u8 sensor_start_ov965x_2_sxga[][2] = {
+	{0x13, 0xe0},	/* com8 */
+	{0x00, 0x00},
+	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
+	{0x3b, 0xc4},	/* com11 - night mode 1/4 frame rate */
+	{0x1e, 0x04},	/* mvfp */
+	{0x11, 0x01},	/* clkrc */
+	{0x6b, 0x5a},	/* dblv */
+	{0x6a, 0x0c},	/* 50 Hz banding filter */
+	{0xc5, 0x0f},	/* 60 Hz banding filter */
+	{0xa2, 0x4e},	/* bd50 */
+	{0xa3, 0x41},	/* bd60 */
+};
 
 static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
 {
@@ -753,39 +1311,310 @@
 	}
 }
 
-/* set framerate */
-static void ov534_set_frame_rate(struct gspca_dev *gspca_dev)
+/* ov772x specific controls */
+static void set_frame_rate(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int fr = sd->frame_rate;
+	int i;
+	struct rate_s {
+		u8 fps;
+		u8 r11;
+		u8 r0d;
+		u8 re5;
+	};
+	const struct rate_s *r;
+	static const struct rate_s rate_0[] = {	/* 640x480 */
+		{60, 0x01, 0xc1, 0x04},
+		{50, 0x01, 0x41, 0x02},
+		{40, 0x02, 0xc1, 0x04},
+		{30, 0x04, 0x81, 0x02},
+		{15, 0x03, 0x41, 0x04},
+	};
+	static const struct rate_s rate_1[] = {	/* 320x240 */
+		{125, 0x02, 0x81, 0x02},
+		{100, 0x02, 0xc1, 0x04},
+		{75, 0x03, 0xc1, 0x04},
+		{60, 0x04, 0xc1, 0x04},
+		{50, 0x02, 0x41, 0x04},
+		{40, 0x03, 0x41, 0x04},
+		{30, 0x04, 0x41, 0x04},
+	};
 
-	switch (fr) {
-	case 50:
-		sccb_reg_write(gspca_dev, 0x11, 0x01);
-		sccb_reg_write(gspca_dev, 0x0d, 0x41);
-		ov534_reg_write(gspca_dev, 0xe5, 0x02);
-		break;
-	case 40:
-		sccb_reg_write(gspca_dev, 0x11, 0x02);
-		sccb_reg_write(gspca_dev, 0x0d, 0xc1);
-		ov534_reg_write(gspca_dev, 0xe5, 0x04);
-		break;
-/*	case 30: */
-	default:
-		fr = 30;
-		sccb_reg_write(gspca_dev, 0x11, 0x04);
-		sccb_reg_write(gspca_dev, 0x0d, 0x81);
-		ov534_reg_write(gspca_dev, 0xe5, 0x02);
-		break;
-	case 15:
-		sccb_reg_write(gspca_dev, 0x11, 0x03);
-		sccb_reg_write(gspca_dev, 0x0d, 0x41);
-		ov534_reg_write(gspca_dev, 0xe5, 0x04);
-		break;
+	if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv == 0) {
+		r = rate_0;
+		i = ARRAY_SIZE(rate_0);
+	} else {
+		r = rate_1;
+		i = ARRAY_SIZE(rate_1);
+	}
+	while (--i > 0) {
+		if (sd->frame_rate >= r->fps)
+			break;
+		r++;
 	}
 
-	sd->frame_rate = fr;
-	PDEBUG(D_PROBE, "frame_rate: %d", fr);
+	sccb_reg_write(gspca_dev, 0x11, r->r11);
+	sccb_reg_write(gspca_dev, 0x0d, r->r0d);
+	ov534_reg_write(gspca_dev, 0xe5, r->re5);
+
+	PDEBUG(D_PROBE, "frame_rate: %d", r->fps);
+}
+
+static void setbrightness_77(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sccb_reg_write(gspca_dev, 0x9B, sd->brightness);
+}
+
+static void setcontrast_77(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sccb_reg_write(gspca_dev, 0x9C, sd->contrast);
+}
+
+static void setgain(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val;
+
+	val = sd->gain;
+	switch (val & 0x30) {
+	case 0x00:
+		val &= 0x0f;
+		break;
+	case 0x10:
+		val &= 0x0f;
+		val |= 0x30;
+		break;
+	case 0x20:
+		val &= 0x0f;
+		val |= 0x70;
+		break;
+	default:
+/*	case 0x30: */
+		val &= 0x0f;
+		val |= 0xf0;
+		break;
+	}
+	sccb_reg_write(gspca_dev, 0x00, val);
+}
+
+static void setexposure_77(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val;
+
+	val = sd->exposure;
+	sccb_reg_write(gspca_dev, 0x08, val >> 7);
+	sccb_reg_write(gspca_dev, 0x10, val << 1);
+}
+
+static void setredblc(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sccb_reg_write(gspca_dev, 0x43, sd->redblc);
+}
+
+static void setblueblc(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sccb_reg_write(gspca_dev, 0x42, sd->blueblc);
+}
+
+static void sethue(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sccb_reg_write(gspca_dev, 0x01, sd->hue);
+}
+
+static void setautogain_77(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->autogain) {
+		sccb_reg_write(gspca_dev, 0x13, 0xf7); /* AGC,AEC,AWB ON */
+		sccb_reg_write(gspca_dev, 0x64,
+				sccb_reg_read(gspca_dev, 0x64) | 0x03);
+	} else {
+		sccb_reg_write(gspca_dev, 0x13, 0xf0); /* AGC,AEC,AWB OFF */
+		sccb_reg_write(gspca_dev, 0x64,
+				sccb_reg_read(gspca_dev, 0x64) & 0xfc);
+	}
+}
+
+static void setawb(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->awb)
+		sccb_reg_write(gspca_dev, 0x63, 0xe0);	/* AWB on */
+	else
+		sccb_reg_write(gspca_dev, 0x63, 0xaa);	/* AWB off */
+}
+
+static void setsharpness_77(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val;
+
+	val = sd->sharpness;
+	sccb_reg_write(gspca_dev, 0x91, val);	/* vga noise */
+	sccb_reg_write(gspca_dev, 0x8e, val);	/* qvga noise */
+}
+
+static void sethflip(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->hflip == 0)
+		sccb_reg_write(gspca_dev, 0x0c,
+				sccb_reg_read(gspca_dev, 0x0c) | 0x40);
+	else
+		sccb_reg_write(gspca_dev, 0x0c,
+				sccb_reg_read(gspca_dev, 0x0c) & 0xbf);
+}
+
+static void setvflip(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->vflip == 0)
+		sccb_reg_write(gspca_dev, 0x0c,
+				sccb_reg_read(gspca_dev, 0x0c) | 0x80);
+	else
+		sccb_reg_write(gspca_dev, 0x0c,
+				sccb_reg_read(gspca_dev, 0x0c) & 0x7f);
+}
+
+/* ov965x specific controls */
+static void setbrightness_96(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val;
+
+	val = sd->brightness;
+	if (val < 8)
+		val = 15 - val;		/* f .. 8 */
+	else
+		val = val - 8;		/* 0 .. 7 */
+	sccb_reg_write(gspca_dev, 0x55,	/* brtn - brightness adjustment */
+			0x0f | (val << 4));
+}
+
+static void setcontrast_96(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sccb_reg_write(gspca_dev, 0x56,	/* cnst1 - contrast 1 ctrl coeff */
+			sd->contrast << 4);
+}
+
+static void setexposure_96(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val;
+	static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e};
+
+	sccb_reg_write(gspca_dev, 0x10,			/* aec[9:2] */
+			expo[sd->exposure]);
+	val = sccb_reg_read(gspca_dev, 0x13);		/* com8 */
+	sccb_reg_write(gspca_dev, 0xff, 0x00);
+	sccb_reg_write(gspca_dev, 0x13, val);
+	val = sccb_reg_read(gspca_dev, 0xa1);		/* aech */
+	sccb_reg_write(gspca_dev, 0xff, 0x00);
+	sccb_reg_write(gspca_dev, 0xa1, val & 0xe0);	/* aec[15:10] = 0 */
+}
+
+static void setsharpness_96(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val;
+
+	val = sd->sharpness;
+	if (val < 0) {				/* auto */
+		val = sccb_reg_read(gspca_dev, 0x42);	/* com17 */
+		sccb_reg_write(gspca_dev, 0xff, 0x00);
+		sccb_reg_write(gspca_dev, 0x42, val | 0x40);
+				/* Edge enhancement strength auto adjust */
+		return;
+	}
+	if (val != 0)
+		val = 1 << (val - 1);
+	sccb_reg_write(gspca_dev, 0x3f,	/* edge - edge enhance. factor */
+			val);
+	val = sccb_reg_read(gspca_dev, 0x42);		/* com17 */
+	sccb_reg_write(gspca_dev, 0xff, 0x00);
+	sccb_reg_write(gspca_dev, 0x42, val & 0xbf);
+}
+
+static void setautogain_96(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val;
+
+/*fixme: should adjust agc/awb/aec by different controls */
+	val = sd->autogain;
+	val = sccb_reg_read(gspca_dev, 0x13);		/* com8 */
+	sccb_reg_write(gspca_dev, 0xff, 0x00);
+	if (sd->autogain)
+		val |= 0x05;		/* agc & aec */
+	else
+		val &= 0xfa;
+	sccb_reg_write(gspca_dev, 0x13, val);
+}
+
+static void setsatur(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val1, val2, val3;
+	static const u8 matrix[5][2] = {
+		{0x14, 0x38},
+		{0x1e, 0x54},
+		{0x28, 0x70},
+		{0x32, 0x8c},
+		{0x48, 0x90}
+	};
+
+	val1 = matrix[sd->satur][0];
+	val2 = matrix[sd->satur][1];
+	val3 = val1 + val2;
+	sccb_reg_write(gspca_dev, 0x4f, val3);	/* matrix coeff */
+	sccb_reg_write(gspca_dev, 0x50, val3);
+	sccb_reg_write(gspca_dev, 0x51, 0x00);
+	sccb_reg_write(gspca_dev, 0x52, val1);
+	sccb_reg_write(gspca_dev, 0x53, val2);
+	sccb_reg_write(gspca_dev, 0x54, val3);
+	sccb_reg_write(gspca_dev, 0x58, 0x1a);	/* mtxs - coeff signs */
+	val1 = sccb_reg_read(gspca_dev, 0x41);	/* com16 */
+	sccb_reg_write(gspca_dev, 0xff, 0x00);
+	sccb_reg_write(gspca_dev, 0x41, val1);
+}
+
+static void setfreq(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val;
+
+	val = sccb_reg_read(gspca_dev, 0x13);		/* com8 */
+	sccb_reg_write(gspca_dev, 0xff, 0x00);
+	if (sd->lightfreq == 0) {
+		sccb_reg_write(gspca_dev, 0x13, val & 0xdf);
+		return;
+	}
+	sccb_reg_write(gspca_dev, 0x13, val | 0x20);
+
+	val = sccb_reg_read(gspca_dev, 0x42);		/* com17 */
+	sccb_reg_write(gspca_dev, 0xff, 0x00);
+	if (sd->lightfreq == 1)
+		val |= 0x01;
+	else
+		val &= 0xfe;
+	sccb_reg_write(gspca_dev, 0x42, val);
 }
 
 /* this function is called at probe time */
@@ -800,17 +1629,60 @@
 	cam = &gspca_dev->cam;
 
 	if (sd->sensor == SENSOR_OV772X) {
-		cam->cam_mode = vga_yuyv_mode;
-		cam->nmodes = ARRAY_SIZE(vga_yuyv_mode);
+		cam->cam_mode = ov772x_mode;
+		cam->nmodes = ARRAY_SIZE(ov772x_mode);
 
 		cam->bulk = 1;
 		cam->bulk_size = 16384;
 		cam->bulk_nurbs = 2;
 	} else {		/* ov965x */
-		cam->cam_mode = vga_jpeg_mode;
-		cam->nmodes = ARRAY_SIZE(vga_jpeg_mode);
+		cam->cam_mode = ov965x_mode;
+		cam->nmodes = ARRAY_SIZE(ov965x_mode);
 	}
 
+	sd->frame_rate = 30;
+
+	if (sd->sensor == SENSOR_OV772X) {
+		sd->brightness = BRIGHTNESS_77_DEF;
+		sd->contrast = CONTRAST_77_DEF;
+		sd->gain = GAIN_DEF;
+		sd->exposure = EXPO_77_DEF;
+		sd->redblc = RED_BALANCE_DEF;
+		sd->blueblc = BLUE_BALANCE_DEF;
+		sd->hue = HUE_DEF;
+#if AUTOGAIN_77_DEF != 0
+		sd->autogain = AUTOGAIN_77_DEF;
+#else
+		gspca_dev->ctrl_inac |= (1 << AWB_77_IDX);
+#endif
+#if AWB_DEF != 0
+		sd->awb = AWB_DEF
+#endif
+#if SHARPNESS_77_DEF != 0
+		sd->sharpness = SHARPNESS_77_DEF;
+#endif
+#if HFLIP_DEF != 0
+		sd->hflip = HFLIP_DEF;
+#endif
+#if VFLIP_DEF != 0
+		sd->vflip = VFLIP_DEF;
+#endif
+	} else {
+		sd->brightness = BRIGHTNESS_96_DEF;
+		sd->contrast = CONTRAST_96_DEF;
+#if AUTOGAIN_96_DEF != 0
+		sd->autogain = AUTOGAIN_96_DEF;
+		gspca_dev->ctrl_inac |= (1 << EXPO_96_IDX);
+#endif
+#if EXPO_96_DEF != 0
+		sd->exposure = EXPO_96_DEF;
+#endif
+#if SHARPNESS_96_DEF != 0
+		sd->sharpness = SHARPNESS_96_DEF;
+#endif
+		sd->satur = SATUR_DEF;
+		sd->lightfreq = FREQ_DEF;
+	}
 	return 0;
 }
 
@@ -847,14 +1719,14 @@
 	/* initialize */
 	switch (sd->sensor) {
 	case SENSOR_OV772X:
-		reg_w_array(gspca_dev, bridge_init_ov722x,
-				ARRAY_SIZE(bridge_init_ov722x));
+		reg_w_array(gspca_dev, bridge_init_ov772x,
+				ARRAY_SIZE(bridge_init_ov772x));
 		ov534_set_led(gspca_dev, 1);
-		sccb_w_array(gspca_dev, sensor_init_ov722x,
-				ARRAY_SIZE(sensor_init_ov722x));
+		sccb_w_array(gspca_dev, sensor_init_ov772x,
+				ARRAY_SIZE(sensor_init_ov772x));
 		ov534_reg_write(gspca_dev, 0xe0, 0x09);
 		ov534_set_led(gspca_dev, 0);
-		ov534_set_frame_rate(gspca_dev);
+		set_frame_rate(gspca_dev);
 		break;
 	default:
 /*	case SENSOR_OV965X: */
@@ -875,60 +1747,115 @@
 	return 0;
 }
 
-static int sd_start(struct gspca_dev *gspca_dev)
+static int sd_start_ov772x(struct gspca_dev *gspca_dev)
 {
-	struct sd *sd = (struct sd *) gspca_dev;
 	int mode;
 
-	switch (sd->sensor) {
-	case SENSOR_OV772X:
-		ov534_set_led(gspca_dev, 1);
-		ov534_reg_write(gspca_dev, 0xe0, 0x00);
-		break;
-	default:
-/*	case SENSOR_OV965X: */
-
-		sccb_w_array(gspca_dev, sensor_start_ov965x,
-				ARRAY_SIZE(sensor_start_ov965x));
-		reg_w_array(gspca_dev, bridge_start_ov965x,
-				ARRAY_SIZE(bridge_start_ov965x));
-		mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
-		if (mode != 0) {	/* 320x240 */
-			reg_w_array(gspca_dev, bridge_start_ov965x_cif,
-					ARRAY_SIZE(bridge_start_ov965x_cif));
-			sccb_w_array(gspca_dev, sensor_start_ov965x_cif,
-					ARRAY_SIZE(sensor_start_ov965x_cif));
-		} else {		/* 640x480 */
-			reg_w_array(gspca_dev, bridge_start_ov965x_vga,
-					ARRAY_SIZE(bridge_start_ov965x_vga));
-			sccb_w_array(gspca_dev, sensor_start_ov965x_vga,
-					ARRAY_SIZE(sensor_start_ov965x_vga));
-		}
-		sccb_w_array(gspca_dev, sensor_start_ov965x_2,
-				ARRAY_SIZE(sensor_start_ov965x_2));
-		ov534_reg_write(gspca_dev, 0xe0, 0x00);
-		ov534_reg_write(gspca_dev, 0xe0, 0x00);
-		ov534_set_led(gspca_dev, 1);
+	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
+	if (mode != 0) {	/* 320x240 */
+		reg_w_array(gspca_dev, bridge_start_ov772x_qvga,
+				ARRAY_SIZE(bridge_start_ov772x_qvga));
+		sccb_w_array(gspca_dev, sensor_start_ov772x_qvga,
+				ARRAY_SIZE(sensor_start_ov772x_qvga));
+	} else {		/* 640x480 */
+		reg_w_array(gspca_dev, bridge_start_ov772x_vga,
+				ARRAY_SIZE(bridge_start_ov772x_vga));
+		sccb_w_array(gspca_dev, sensor_start_ov772x_vga,
+				ARRAY_SIZE(sensor_start_ov772x_vga));
 	}
+	set_frame_rate(gspca_dev);
+
+	setautogain_77(gspca_dev);
+	setawb(gspca_dev);
+	setgain(gspca_dev);
+	setredblc(gspca_dev);
+	setblueblc(gspca_dev);
+	sethue(gspca_dev);
+	setexposure_77(gspca_dev);
+	setbrightness_77(gspca_dev);
+	setcontrast_77(gspca_dev);
+	setsharpness_77(gspca_dev);
+	setvflip(gspca_dev);
+	sethflip(gspca_dev);
+
+	ov534_set_led(gspca_dev, 1);
+	ov534_reg_write(gspca_dev, 0xe0, 0x00);
 	return 0;
 }
 
-static void sd_stopN(struct gspca_dev *gspca_dev)
+static int sd_start_ov965x(struct gspca_dev *gspca_dev)
 {
-	struct sd *sd = (struct sd *) gspca_dev;
+	int mode;
 
-	switch (sd->sensor) {
-	case SENSOR_OV772X:
-		ov534_reg_write(gspca_dev, 0xe0, 0x09);
-		ov534_set_led(gspca_dev, 0);
-		break;
+	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
+	switch (mode) {
 	default:
-/*	case SENSOR_OV965X: */
-		ov534_reg_write(gspca_dev, 0xe0, 0x01);
-		ov534_set_led(gspca_dev, 0);
-		ov534_reg_write(gspca_dev, 0xe0, 0x00);
+/*	case 4:			 * 320x240 */
+		sccb_w_array(gspca_dev, sensor_start_ov965x_1_vga,
+				ARRAY_SIZE(sensor_start_ov965x_1_vga));
+		reg_w_array(gspca_dev, bridge_start_ov965x_qvga,
+				ARRAY_SIZE(bridge_start_ov965x_qvga));
+		sccb_w_array(gspca_dev, sensor_start_ov965x_2_qvga,
+				ARRAY_SIZE(sensor_start_ov965x_2_qvga));
+		break;
+	case 3:			/* 640x480 */
+		sccb_w_array(gspca_dev, sensor_start_ov965x_1_vga,
+				ARRAY_SIZE(sensor_start_ov965x_1_vga));
+		reg_w_array(gspca_dev, bridge_start_ov965x_vga,
+				ARRAY_SIZE(bridge_start_ov965x_vga));
+		sccb_w_array(gspca_dev, sensor_start_ov965x_2_vga,
+				ARRAY_SIZE(sensor_start_ov965x_2_vga));
+		break;
+	case 2:			/* 800x600 */
+		sccb_w_array(gspca_dev, sensor_start_ov965x_1_svga,
+				ARRAY_SIZE(sensor_start_ov965x_1_svga));
+		reg_w_array(gspca_dev, bridge_start_ov965x_svga,
+				ARRAY_SIZE(bridge_start_ov965x_svga));
+		sccb_w_array(gspca_dev, sensor_start_ov965x_2_svga,
+				ARRAY_SIZE(sensor_start_ov965x_2_svga));
+		break;
+	case 1:			/* 1024x768 */
+		sccb_w_array(gspca_dev, sensor_start_ov965x_1_xga,
+				ARRAY_SIZE(sensor_start_ov965x_1_xga));
+		reg_w_array(gspca_dev, bridge_start_ov965x_xga,
+				ARRAY_SIZE(bridge_start_ov965x_xga));
+		sccb_w_array(gspca_dev, sensor_start_ov965x_2_svga,
+				ARRAY_SIZE(sensor_start_ov965x_2_svga));
+		break;
+	case 0:			/* 1280x1024 */
+		sccb_w_array(gspca_dev, sensor_start_ov965x_1_sxga,
+				ARRAY_SIZE(sensor_start_ov965x_1_sxga));
+		reg_w_array(gspca_dev, bridge_start_ov965x_sxga,
+				ARRAY_SIZE(bridge_start_ov965x_sxga));
+		sccb_w_array(gspca_dev, sensor_start_ov965x_2_sxga,
+				ARRAY_SIZE(sensor_start_ov965x_2_sxga));
 		break;
 	}
+	setfreq(gspca_dev);
+	setautogain_96(gspca_dev);
+	setbrightness_96(gspca_dev);
+	setcontrast_96(gspca_dev);
+	setexposure_96(gspca_dev);
+	setsharpness_96(gspca_dev);
+	setsatur(gspca_dev);
+
+	ov534_reg_write(gspca_dev, 0xe0, 0x00);
+	ov534_reg_write(gspca_dev, 0xe0, 0x00);
+	ov534_set_led(gspca_dev, 1);
+	return 0;
+}
+
+static void sd_stopN_ov772x(struct gspca_dev *gspca_dev)
+{
+	ov534_reg_write(gspca_dev, 0xe0, 0x09);
+	ov534_set_led(gspca_dev, 0);
+}
+
+static void sd_stopN_ov965x(struct gspca_dev *gspca_dev)
+{
+	ov534_reg_write(gspca_dev, 0xe0, 0x01);
+	ov534_set_led(gspca_dev, 0);
+	ov534_reg_write(gspca_dev, 0xe0, 0x00);
 }
 
 /* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
@@ -941,8 +1868,8 @@
 #define UVC_STREAM_EOF	(1 << 1)
 #define UVC_STREAM_FID	(1 << 0)
 
-static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
-			__u8 *data, int len)
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+			u8 *data, int len)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	__u32 this_pts;
@@ -983,32 +1910,30 @@
 		/* If PTS or FID has changed, start a new frame. */
 		if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
 			if (gspca_dev->last_packet_type == INTER_PACKET)
-				frame = gspca_frame_add(gspca_dev,
-							LAST_PACKET, frame,
-							NULL, 0);
+				gspca_frame_add(gspca_dev, LAST_PACKET,
+						NULL, 0);
 			sd->last_pts = this_pts;
 			sd->last_fid = this_fid;
-			gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+			gspca_frame_add(gspca_dev, FIRST_PACKET,
 					data + 12, len - 12);
 		/* If this packet is marked as EOF, end the frame */
 		} else if (data[1] & UVC_STREAM_EOF) {
 			sd->last_pts = 0;
-			frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-						data + 12, len - 12);
+			gspca_frame_add(gspca_dev, LAST_PACKET,
+					data + 12, len - 12);
 		} else {
 
 			/* Add the data from this payload */
-			gspca_frame_add(gspca_dev, INTER_PACKET, frame,
-						data + 12, len - 12);
+			gspca_frame_add(gspca_dev, INTER_PACKET,
+					data + 12, len - 12);
 		}
 
-
 		/* Done this payload */
 		goto scan_next;
 
 discard:
 		/* Discard data until a new frame starts. */
-		gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0);
+		gspca_dev->last_packet_type = DISCARD_PACKET;
 
 scan_next:
 		remaining_len -= len;
@@ -1016,6 +1941,291 @@
 	} while (remaining_len > 0);
 }
 
+/* controls */
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->gain = val;
+	if (gspca_dev->streaming)
+		setgain(gspca_dev);
+	return 0;
+}
+
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->gain;
+	return 0;
+}
+
+static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->exposure = val;
+	if (gspca_dev->streaming) {
+		if (sd->sensor == SENSOR_OV772X)
+			setexposure_77(gspca_dev);
+		else
+			setexposure_96(gspca_dev);
+	}
+	return 0;
+}
+
+static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->exposure;
+	return 0;
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->brightness = val;
+	if (gspca_dev->streaming) {
+		if (sd->sensor == SENSOR_OV772X)
+			setbrightness_77(gspca_dev);
+		else
+			setbrightness_96(gspca_dev);
+	}
+	return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->brightness;
+	return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->contrast = val;
+	if (gspca_dev->streaming) {
+		if (sd->sensor == SENSOR_OV772X)
+			setcontrast_77(gspca_dev);
+		else
+			setcontrast_96(gspca_dev);
+	}
+	return 0;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->contrast;
+	return 0;
+}
+
+static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->satur = val;
+	if (gspca_dev->streaming)
+		setsatur(gspca_dev);
+	return 0;
+}
+
+static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->satur;
+	return 0;
+}
+static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->lightfreq = val;
+	if (gspca_dev->streaming)
+		setfreq(gspca_dev);
+	return 0;
+}
+
+static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->lightfreq;
+	return 0;
+}
+
+static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->redblc = val;
+	if (gspca_dev->streaming)
+		setredblc(gspca_dev);
+	return 0;
+}
+
+static int sd_getredblc(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->redblc;
+	return 0;
+}
+
+static int sd_setblueblc(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->blueblc = val;
+	if (gspca_dev->streaming)
+		setblueblc(gspca_dev);
+	return 0;
+}
+
+static int sd_getblueblc(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->blueblc;
+	return 0;
+}
+
+static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->hue = val;
+	if (gspca_dev->streaming)
+		sethue(gspca_dev);
+	return 0;
+}
+
+static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->hue;
+	return 0;
+}
+
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->autogain = val;
+
+	if (gspca_dev->streaming) {
+		if (sd->sensor == SENSOR_OV772X) {
+
+			/* the auto white balance control works only
+			 * when auto gain is set */
+			if (val)
+				gspca_dev->ctrl_inac &= ~(1 << AWB_77_IDX);
+			else
+				gspca_dev->ctrl_inac |= (1 << AWB_77_IDX);
+			setautogain_77(gspca_dev);
+		} else {
+			if (val)
+				gspca_dev->ctrl_inac |= (1 << EXPO_96_IDX);
+			else
+				gspca_dev->ctrl_inac &= ~(1 << EXPO_96_IDX);
+			setautogain_96(gspca_dev);
+		}
+	}
+	return 0;
+}
+
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->autogain;
+	return 0;
+}
+
+static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->awb = val;
+	if (gspca_dev->streaming)
+		setawb(gspca_dev);
+	return 0;
+}
+
+static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->awb;
+	return 0;
+}
+
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->sharpness = val;
+	if (gspca_dev->streaming) {
+		if (sd->sensor == SENSOR_OV772X)
+			setsharpness_77(gspca_dev);
+		else
+			setsharpness_96(gspca_dev);
+	}
+	return 0;
+}
+
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->sharpness;
+	return 0;
+}
+
+static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->hflip = val;
+	if (gspca_dev->streaming)
+		sethflip(gspca_dev);
+	return 0;
+}
+
+static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->hflip;
+	return 0;
+}
+
+static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->vflip = val;
+	if (gspca_dev->streaming)
+		setvflip(gspca_dev);
+	return 0;
+}
+
+static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->vflip;
+	return 0;
+}
+
 /* get stream parameters (framerate) */
 static int sd_get_streamparm(struct gspca_dev *gspca_dev,
 			     struct v4l2_streamparm *parm)
@@ -1047,7 +2257,8 @@
 
 	/* Set requested framerate */
 	sd->frame_rate = tpf->denominator / tpf->numerator;
-	ov534_set_frame_rate(gspca_dev);
+	if (gspca_dev->streaming && sd->sensor == SENSOR_OV772X)
+		set_frame_rate(gspca_dev);
 
 	/* Return the actual framerate */
 	tpf->numerator = 1;
@@ -1056,20 +2267,53 @@
 	return 0;
 }
 
+static int sd_querymenu(struct gspca_dev *gspca_dev,
+			struct v4l2_querymenu *menu)
+{
+	switch (menu->id) {
+	case V4L2_CID_POWER_LINE_FREQUENCY:
+		switch (menu->index) {
+		case 0:		/* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
+			strcpy((char *) menu->name, "NoFliker");
+			return 0;
+		case 1:		/* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
+			strcpy((char *) menu->name, "50 Hz");
+			return 0;
+		case 2:		/* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
+			strcpy((char *) menu->name, "60 Hz");
+			return 0;
+		}
+		break;
+	}
+	return -EINVAL;
+}
+
 /* sub-driver description */
-static const struct sd_desc sd_desc = {
+static const struct sd_desc sd_desc_ov772x = {
 	.name     = MODULE_NAME,
-	.ctrls    = sd_ctrls,
-	.nctrls   = ARRAY_SIZE(sd_ctrls),
+	.ctrls    = sd_ctrls_ov772x,
+	.nctrls   = ARRAY_SIZE(sd_ctrls_ov772x),
 	.config   = sd_config,
 	.init     = sd_init,
-	.start    = sd_start,
-	.stopN    = sd_stopN,
+	.start    = sd_start_ov772x,
+	.stopN    = sd_stopN_ov772x,
 	.pkt_scan = sd_pkt_scan,
 	.get_streamparm = sd_get_streamparm,
 	.set_streamparm = sd_set_streamparm,
 };
 
+static const struct sd_desc sd_desc_ov965x = {
+	.name     = MODULE_NAME,
+	.ctrls    = sd_ctrls_ov965x,
+	.nctrls   = ARRAY_SIZE(sd_ctrls_ov965x),
+	.config   = sd_config,
+	.init     = sd_init,
+	.start    = sd_start_ov965x,
+	.stopN    = sd_stopN_ov965x,
+	.pkt_scan = sd_pkt_scan,
+	.querymenu = sd_querymenu,
+};
+
 /* -- module initialisation -- */
 static const __devinitdata struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x06f8, 0x3003), .driver_info = SENSOR_OV965X},
@@ -1082,8 +2326,12 @@
 /* -- device connect -- */
 static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
-	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
-			       THIS_MODULE);
+	return gspca_dev_probe(intf, id,
+				id->driver_info == SENSOR_OV772X
+					? &sd_desc_ov772x
+					: &sd_desc_ov965x,
+				sizeof(struct sd),
+				THIS_MODULE);
 }
 
 static struct usb_driver sd_driver = {
@@ -1101,6 +2349,7 @@
 static int __init sd_mod_init(void)
 {
 	int ret;
+
 	ret = usb_register(&sd_driver);
 	if (ret < 0)
 		return ret;
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index 9665943..4706a82 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -337,14 +337,13 @@
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,
-			__u8 *data,
+			u8 *data,
 			int len)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	unsigned char *sof;
 
-	sof = pac_find_sof(gspca_dev, data, len);
+	sof = pac_find_sof(&sd->sof_read, data, len);
 	if (sof) {
 		int n;
 
@@ -354,10 +353,10 @@
 			n -= sizeof pac_sof_marker;
 		else
 			n = 0;
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-					data, n);
+		gspca_frame_add(gspca_dev, LAST_PACKET,
+				data, n);
 		sd->header_read = 0;
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
 		len -= sof - data;
 		data = sof;
 	}
@@ -381,7 +380,7 @@
 		sd->header_read = 11;
 	}
 
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static void setbrightness(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c
new file mode 100644
index 0000000..74accee
--- /dev/null
+++ b/drivers/media/video/gspca/pac7302.c
@@ -0,0 +1,1272 @@
+/*
+ *		Pixart PAC7302 library
+ *		Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
+ *
+ * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ *
+ * Separated from Pixart PAC7311 library by Márton Németh <nm127@freemail.hu>
+ *
+ * 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
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* Some documentation about various registers as determined by trial and error.
+   When the register addresses differ between the 7202 and the 7311 the 2
+   different addresses are written as 7302addr/7311addr, when one of the 2
+   addresses is a - sign that register description is not valid for the
+   matching IC.
+
+   Register page 1:
+
+   Address	Description
+   -/0x08	Unknown compressor related, must always be 8 except when not
+		in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 !
+   -/0x1b	Auto white balance related, bit 0 is AWB enable (inverted)
+		bits 345 seem to toggle per color gains on/off (inverted)
+   0x78		Global control, bit 6 controls the LED (inverted)
+   -/0x80	JPEG compression ratio ? Best not touched
+
+   Register page 3/4:
+
+   Address	Description
+   0x02		Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on
+		the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
+   -/0x0f	Master gain 1-245, low value = high gain
+   0x10/-	Master gain 0-31
+   -/0x10	Another gain 0-15, limited influence (1-2x gain I guess)
+   0x21		Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
+   -/0x27	Seems to toggle various gains on / off, Setting bit 7 seems to
+		completely disable the analog amplification block. Set to 0x68
+		for max gain, 0x14 for minimal gain.
+
+   The registers are accessed in the following functions:
+
+   Page | Register   | Function
+   -----+------------+---------------------------------------------------
+    0   | 0x0f..0x20 | setcolors()
+    0   | 0xa2..0xab | setbrightcont()
+    0   | 0xc5       | setredbalance()
+    0   | 0xc6       | setwhitebalance()
+    0   | 0xc7       | setbluebalance()
+    0   | 0xdc       | setbrightcont(), setcolors()
+    3   | 0x02       | setexposure()
+    3   | 0x10       | setgain()
+    3   | 0x11       | setcolors(), setgain(), setexposure(), sethvflip()
+    3   | 0x21       | sethvflip()
+*/
+
+#define MODULE_NAME "pac7302"
+
+#include <media/v4l2-chip-ident.h>
+#include "gspca.h"
+
+MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
+MODULE_DESCRIPTION("Pixart PAC7302");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor for pac7302 */
+struct sd {
+	struct gspca_dev gspca_dev;		/* !! must be the first item */
+
+	unsigned char brightness;
+	unsigned char contrast;
+	unsigned char colors;
+	unsigned char white_balance;
+	unsigned char red_balance;
+	unsigned char blue_balance;
+	unsigned char gain;
+	unsigned char exposure;
+	unsigned char autogain;
+	__u8 hflip;
+	__u8 vflip;
+
+	u8 sof_read;
+	u8 autogain_ignore_frames;
+
+	atomic_t avg_lum;
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
+
+static struct ctrl sd_ctrls[] = {
+/* This control is pac7302 only */
+	{
+	    {
+		.id      = V4L2_CID_BRIGHTNESS,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Brightness",
+		.minimum = 0,
+#define BRIGHTNESS_MAX 0x20
+		.maximum = BRIGHTNESS_MAX,
+		.step    = 1,
+#define BRIGHTNESS_DEF 0x10
+		.default_value = BRIGHTNESS_DEF,
+	    },
+	    .set = sd_setbrightness,
+	    .get = sd_getbrightness,
+	},
+/* This control is for both the 7302 and the 7311 */
+	{
+	    {
+		.id      = V4L2_CID_CONTRAST,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Contrast",
+		.minimum = 0,
+#define CONTRAST_MAX 255
+		.maximum = CONTRAST_MAX,
+		.step    = 1,
+#define CONTRAST_DEF 127
+		.default_value = CONTRAST_DEF,
+	    },
+	    .set = sd_setcontrast,
+	    .get = sd_getcontrast,
+	},
+/* This control is pac7302 only */
+	{
+	    {
+		.id      = V4L2_CID_SATURATION,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Saturation",
+		.minimum = 0,
+#define COLOR_MAX 255
+		.maximum = COLOR_MAX,
+		.step    = 1,
+#define COLOR_DEF 127
+		.default_value = COLOR_DEF,
+	    },
+	    .set = sd_setcolors,
+	    .get = sd_getcolors,
+	},
+	{
+	    {
+		.id      = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "White Balance",
+		.minimum = 0,
+		.maximum = 255,
+		.step    = 1,
+#define WHITEBALANCE_DEF 4
+		.default_value = WHITEBALANCE_DEF,
+	    },
+	    .set = sd_setwhitebalance,
+	    .get = sd_getwhitebalance,
+	},
+	{
+	    {
+		.id      = V4L2_CID_RED_BALANCE,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Red",
+		.minimum = 0,
+		.maximum = 3,
+		.step    = 1,
+#define REDBALANCE_DEF 1
+		.default_value = REDBALANCE_DEF,
+	    },
+	    .set = sd_setredbalance,
+	    .get = sd_getredbalance,
+	},
+	{
+	    {
+		.id      = V4L2_CID_BLUE_BALANCE,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Blue",
+		.minimum = 0,
+		.maximum = 3,
+		.step    = 1,
+#define BLUEBALANCE_DEF 1
+		.default_value = BLUEBALANCE_DEF,
+	    },
+	    .set = sd_setbluebalance,
+	    .get = sd_getbluebalance,
+	},
+/* All controls below are for both the 7302 and the 7311 */
+	{
+	    {
+		.id      = V4L2_CID_GAIN,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Gain",
+		.minimum = 0,
+#define GAIN_MAX 255
+		.maximum = GAIN_MAX,
+		.step    = 1,
+#define GAIN_DEF 127
+#define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */
+		.default_value = GAIN_DEF,
+	    },
+	    .set = sd_setgain,
+	    .get = sd_getgain,
+	},
+	{
+	    {
+		.id      = V4L2_CID_EXPOSURE,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Exposure",
+		.minimum = 0,
+#define EXPOSURE_MAX 255
+		.maximum = EXPOSURE_MAX,
+		.step    = 1,
+#define EXPOSURE_DEF  16 /*  32 ms / 30 fps */
+#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
+		.default_value = EXPOSURE_DEF,
+	    },
+	    .set = sd_setexposure,
+	    .get = sd_getexposure,
+	},
+	{
+	    {
+		.id      = V4L2_CID_AUTOGAIN,
+		.type    = V4L2_CTRL_TYPE_BOOLEAN,
+		.name    = "Auto Gain",
+		.minimum = 0,
+		.maximum = 1,
+		.step    = 1,
+#define AUTOGAIN_DEF 1
+		.default_value = AUTOGAIN_DEF,
+	    },
+	    .set = sd_setautogain,
+	    .get = sd_getautogain,
+	},
+	{
+	    {
+		.id      = V4L2_CID_HFLIP,
+		.type    = V4L2_CTRL_TYPE_BOOLEAN,
+		.name    = "Mirror",
+		.minimum = 0,
+		.maximum = 1,
+		.step    = 1,
+#define HFLIP_DEF 0
+		.default_value = HFLIP_DEF,
+	    },
+	    .set = sd_sethflip,
+	    .get = sd_gethflip,
+	},
+	{
+	    {
+		.id      = V4L2_CID_VFLIP,
+		.type    = V4L2_CTRL_TYPE_BOOLEAN,
+		.name    = "Vflip",
+		.minimum = 0,
+		.maximum = 1,
+		.step    = 1,
+#define VFLIP_DEF 0
+		.default_value = VFLIP_DEF,
+	    },
+	    .set = sd_setvflip,
+	    .get = sd_getvflip,
+	},
+};
+
+static const struct v4l2_pix_format vga_mode[] = {
+	{640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
+		.bytesperline = 640,
+		.sizeimage = 640 * 480 * 3 / 8 + 590,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.priv = 0},
+};
+
+#define LOAD_PAGE3		255
+#define LOAD_PAGE4		254
+#define END_OF_SEQUENCE		0
+
+/* pac 7302 */
+static const __u8 init_7302[] = {
+/*	index,value */
+	0xff, 0x01,		/* page 1 */
+	0x78, 0x00,		/* deactivate */
+	0xff, 0x01,
+	0x78, 0x40,		/* led off */
+};
+static const __u8 start_7302[] = {
+/*	index, len, [value]* */
+	0xff, 1,	0x00,		/* page 0 */
+	0x00, 12,	0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
+			0x00, 0x00, 0x00, 0x00,
+	0x0d, 24,	0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
+			0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
+			0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
+	0x26, 2,	0xaa, 0xaa,
+	0x2e, 1,	0x31,
+	0x38, 1,	0x01,
+	0x3a, 3,	0x14, 0xff, 0x5a,
+	0x43, 11,	0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
+			0x00, 0x54, 0x11,
+	0x55, 1,	0x00,
+	0x62, 4, 	0x10, 0x1e, 0x1e, 0x18,
+	0x6b, 1,	0x00,
+	0x6e, 3,	0x08, 0x06, 0x00,
+	0x72, 3,	0x00, 0xff, 0x00,
+	0x7d, 23,	0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
+			0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
+			0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
+	0xa2, 10,	0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
+			0xd2, 0xeb,
+	0xaf, 1,	0x02,
+	0xb5, 2,	0x08, 0x08,
+	0xb8, 2,	0x08, 0x88,
+	0xc4, 4,	0xae, 0x01, 0x04, 0x01,
+	0xcc, 1,	0x00,
+	0xd1, 11,	0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
+			0xc1, 0xd7, 0xec,
+	0xdc, 1,	0x01,
+	0xff, 1,	0x01,		/* page 1 */
+	0x12, 3,	0x02, 0x00, 0x01,
+	0x3e, 2,	0x00, 0x00,
+	0x76, 5,	0x01, 0x20, 0x40, 0x00, 0xf2,
+	0x7c, 1,	0x00,
+	0x7f, 10,	0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
+			0x02, 0x00,
+	0x96, 5,	0x01, 0x10, 0x04, 0x01, 0x04,
+	0xc8, 14,	0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
+			0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
+	0xd8, 1,	0x01,
+	0xdb, 2,	0x00, 0x01,
+	0xde, 7,	0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
+	0xe6, 4,	0x00, 0x00, 0x00, 0x01,
+	0xeb, 1,	0x00,
+	0xff, 1,	0x02,		/* page 2 */
+	0x22, 1,	0x00,
+	0xff, 1,	0x03,		/* page 3 */
+	0, LOAD_PAGE3,			/* load the page 3 */
+	0x11, 1,	0x01,
+	0xff, 1,	0x02,		/* page 2 */
+	0x13, 1,	0x00,
+	0x22, 4,	0x1f, 0xa4, 0xf0, 0x96,
+	0x27, 2,	0x14, 0x0c,
+	0x2a, 5,	0xc8, 0x00, 0x18, 0x12, 0x22,
+	0x64, 8,	0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
+	0x6e, 1,	0x08,
+	0xff, 1,	0x01,		/* page 1 */
+	0x78, 1,	0x00,
+	0, END_OF_SEQUENCE		/* end of sequence */
+};
+
+#define SKIP		0xaa
+/* page 3 - the value SKIP says skip the index - see reg_w_page() */
+static const __u8 page3_7302[] = {
+	0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16,
+	0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
+	0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
+	0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
+	0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
+	0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
+	0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
+	0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
+	0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+	0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
+	0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
+	0x00
+};
+
+static int reg_w_buf(struct gspca_dev *gspca_dev,
+		  __u8 index,
+		  const char *buffer, int len)
+{
+	int ret;
+
+	memcpy(gspca_dev->usb_buf, buffer, len);
+	ret = usb_control_msg(gspca_dev->dev,
+			usb_sndctrlpipe(gspca_dev->dev, 0),
+			1,		/* request */
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			0,		/* value */
+			index, gspca_dev->usb_buf, len,
+			500);
+	if (ret < 0)
+		PDEBUG(D_ERR, "reg_w_buf(): "
+		"Failed to write registers to index 0x%x, error %i",
+		index, ret);
+	return ret;
+}
+
+
+static int reg_w(struct gspca_dev *gspca_dev,
+		  __u8 index,
+		  __u8 value)
+{
+	int ret;
+
+	gspca_dev->usb_buf[0] = value;
+	ret = usb_control_msg(gspca_dev->dev,
+			usb_sndctrlpipe(gspca_dev->dev, 0),
+			0,			/* request */
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			0, index, gspca_dev->usb_buf, 1,
+			500);
+	if (ret < 0)
+		PDEBUG(D_ERR, "reg_w(): "
+		"Failed to write register to index 0x%x, value 0x%x, error %i",
+		index, value, ret);
+	return ret;
+}
+
+static int reg_w_seq(struct gspca_dev *gspca_dev,
+		const __u8 *seq, int len)
+{
+	int ret = 0;
+	while (--len >= 0) {
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, seq[0], seq[1]);
+		seq += 2;
+	}
+	return ret;
+}
+
+/* load the beginning of a page */
+static int reg_w_page(struct gspca_dev *gspca_dev,
+			const __u8 *page, int len)
+{
+	int index;
+	int ret = 0;
+
+	for (index = 0; index < len; index++) {
+		if (page[index] == SKIP)		/* skip this index */
+			continue;
+		gspca_dev->usb_buf[0] = page[index];
+		ret = usb_control_msg(gspca_dev->dev,
+				usb_sndctrlpipe(gspca_dev->dev, 0),
+				0,			/* request */
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+				0, index, gspca_dev->usb_buf, 1,
+				500);
+		if (ret < 0) {
+			PDEBUG(D_ERR, "reg_w_page(): "
+			"Failed to write register to index 0x%x, "
+			"value 0x%x, error %i",
+			index, page[index], ret);
+			break;
+		}
+	}
+	return ret;
+}
+
+/* output a variable sequence */
+static int reg_w_var(struct gspca_dev *gspca_dev,
+			const __u8 *seq,
+			const __u8 *page3, unsigned int page3_len,
+			const __u8 *page4, unsigned int page4_len)
+{
+	int index, len;
+	int ret = 0;
+
+	for (;;) {
+		index = *seq++;
+		len = *seq++;
+		switch (len) {
+		case END_OF_SEQUENCE:
+			return ret;
+		case LOAD_PAGE4:
+			ret = reg_w_page(gspca_dev, page4, page4_len);
+			break;
+		case LOAD_PAGE3:
+			ret = reg_w_page(gspca_dev, page3, page3_len);
+			break;
+		default:
+			if (len > USB_BUF_SZ) {
+				PDEBUG(D_ERR|D_STREAM,
+					"Incorrect variable sequence");
+				return -EINVAL;
+			}
+			while (len > 0) {
+				if (len < 8) {
+					ret = reg_w_buf(gspca_dev,
+						index, seq, len);
+					if (ret < 0)
+						return ret;
+					seq += len;
+					break;
+				}
+				ret = reg_w_buf(gspca_dev, index, seq, 8);
+				seq += 8;
+				index += 8;
+				len -= 8;
+			}
+		}
+		if (ret < 0)
+			return ret;
+	}
+	/* not reached */
+}
+
+/* this function is called at probe time for pac7302 */
+static int sd_config(struct gspca_dev *gspca_dev,
+			const struct usb_device_id *id)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	struct cam *cam;
+
+	cam = &gspca_dev->cam;
+
+	PDEBUG(D_CONF, "Find Sensor PAC7302");
+	cam->cam_mode = vga_mode;	/* only 640x480 */
+	cam->nmodes = ARRAY_SIZE(vga_mode);
+
+	sd->brightness = BRIGHTNESS_DEF;
+	sd->contrast = CONTRAST_DEF;
+	sd->colors = COLOR_DEF;
+	sd->white_balance = WHITEBALANCE_DEF;
+	sd->red_balance = REDBALANCE_DEF;
+	sd->blue_balance = BLUEBALANCE_DEF;
+	sd->gain = GAIN_DEF;
+	sd->exposure = EXPOSURE_DEF;
+	sd->autogain = AUTOGAIN_DEF;
+	sd->hflip = HFLIP_DEF;
+	sd->vflip = VFLIP_DEF;
+	return 0;
+}
+
+/* This function is used by pac7302 only */
+static int setbrightcont(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int i, v;
+	int ret;
+	static const __u8 max[10] =
+		{0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
+		 0xd4, 0xec};
+	static const __u8 delta[10] =
+		{0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
+		 0x11, 0x0b};
+
+	ret = reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
+	for (i = 0; i < 10; i++) {
+		v = max[i];
+		v += (sd->brightness - BRIGHTNESS_MAX)
+			* 150 / BRIGHTNESS_MAX;		/* 200 ? */
+		v -= delta[i] * sd->contrast / CONTRAST_MAX;
+		if (v < 0)
+			v = 0;
+		else if (v > 0xff)
+			v = 0xff;
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0xa2 + i, v);
+	}
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xdc, 0x01);
+	return ret;
+}
+
+/* This function is used by pac7302 only */
+static int setcolors(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int i, v;
+	int ret;
+	static const int a[9] =
+		{217, -212, 0, -101, 170, -67, -38, -315, 355};
+	static const int b[9] =
+		{19, 106, 0, 19, 106, 1, 19, 106, 1};
+
+	ret = reg_w(gspca_dev, 0xff, 0x03);	/* page 3 */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x11, 0x01);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
+	for (i = 0; i < 9; i++) {
+		v = a[i] * sd->colors / COLOR_MAX + b[i];
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
+	}
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xdc, 0x01);
+	PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
+	return ret;
+}
+
+static int setwhitebalance(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
+
+	ret = reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xc6, sd->white_balance);
+
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xdc, 0x01);
+	PDEBUG(D_CONF|D_STREAM, "white_balance: %i", sd->white_balance);
+	return ret;
+}
+
+static int setredbalance(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
+
+	ret = reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xc5, sd->red_balance);
+
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xdc, 0x01);
+	PDEBUG(D_CONF|D_STREAM, "red_balance: %i", sd->red_balance);
+	return ret;
+}
+
+static int setbluebalance(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
+
+	ret = reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xc7, sd->blue_balance);
+
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xdc, 0x01);
+	PDEBUG(D_CONF|D_STREAM, "blue_balance: %i", sd->blue_balance);
+	return ret;
+}
+
+static int setgain(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
+
+	ret = reg_w(gspca_dev, 0xff, 0x03);		/* page 3 */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x10, sd->gain >> 3);
+
+	/* load registers to sensor (Bit 0, auto clear) */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x11, 0x01);
+	return ret;
+}
+
+static int setexposure(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
+	__u8 reg;
+
+	/* register 2 of frame 3/4 contains the clock divider configuring the
+	   no fps according to the formula: 60 / reg. sd->exposure is the
+	   desired exposure time in ms. */
+	reg = 120 * sd->exposure / 1000;
+	if (reg < 2)
+		reg = 2;
+	else if (reg > 63)
+		reg = 63;
+
+	/* On the pac7302 reg2 MUST be a multiple of 3, so round it to
+	   the nearest multiple of 3, except when between 6 and 12? */
+	if (reg < 6 || reg > 12)
+		reg = ((reg + 1) / 3) * 3;
+	ret = reg_w(gspca_dev, 0xff, 0x03);		/* page 3 */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x02, reg);
+
+	/* load registers to sensor (Bit 0, auto clear) */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x11, 0x01);
+	return ret;
+}
+
+static int sethvflip(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
+	__u8 data;
+
+	ret = reg_w(gspca_dev, 0xff, 0x03);		/* page 3 */
+	data = (sd->hflip ? 0x08 : 0x00) | (sd->vflip ? 0x04 : 0x00);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x21, data);
+	/* load registers to sensor (Bit 0, auto clear) */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x11, 0x01);
+	return ret;
+}
+
+/* this function is called at probe and resume time for pac7302 */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+	return reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
+}
+
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret = 0;
+
+	sd->sof_read = 0;
+
+	ret = reg_w_var(gspca_dev, start_7302,
+		page3_7302, sizeof(page3_7302),
+		NULL, 0);
+	if (0 <= ret)
+		ret = setbrightcont(gspca_dev);
+	if (0 <= ret)
+		ret = setcolors(gspca_dev);
+	if (0 <= ret)
+		ret = setwhitebalance(gspca_dev);
+	if (0 <= ret)
+		ret = setredbalance(gspca_dev);
+	if (0 <= ret)
+		ret = setbluebalance(gspca_dev);
+	if (0 <= ret)
+		ret = setgain(gspca_dev);
+	if (0 <= ret)
+		ret = setexposure(gspca_dev);
+	if (0 <= ret)
+		ret = sethvflip(gspca_dev);
+
+	/* only resolution 640x480 is supported for pac7302 */
+
+	sd->sof_read = 0;
+	sd->autogain_ignore_frames = 0;
+	atomic_set(&sd->avg_lum, -1);
+
+	/* start stream */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xff, 0x01);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x78, 0x01);
+
+	return ret;
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+	int ret;
+
+	/* stop stream */
+	ret = reg_w(gspca_dev, 0xff, 0x01);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x78, 0x00);
+}
+
+/* called on streamoff with alt 0 and on disconnect for pac7302 */
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+	int ret;
+
+	if (!gspca_dev->present)
+		return;
+	ret = reg_w(gspca_dev, 0xff, 0x01);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x78, 0x40);
+}
+
+/* Include pac common sof detection functions */
+#include "pac_common.h"
+
+static void do_autogain(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int avg_lum = atomic_read(&sd->avg_lum);
+	int desired_lum, deadzone;
+
+	if (avg_lum == -1)
+		return;
+
+	desired_lum = 270 + sd->brightness * 4;
+	/* Hack hack, with the 7202 the first exposure step is
+	   pretty large, so if we're about to make the first
+	   exposure increase make the deadzone large to avoid
+	   oscilating */
+	if (desired_lum > avg_lum && sd->gain == GAIN_DEF &&
+			sd->exposure > EXPOSURE_DEF &&
+			sd->exposure < 42)
+		deadzone = 90;
+	else
+		deadzone = 30;
+
+	if (sd->autogain_ignore_frames > 0)
+		sd->autogain_ignore_frames--;
+	else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum,
+			deadzone, GAIN_KNEE, EXPOSURE_KNEE))
+		sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
+}
+
+/* JPEG header, part 1 */
+static const unsigned char pac_jpeg_header1[] = {
+  0xff, 0xd8,		/* SOI: Start of Image */
+
+  0xff, 0xc0,		/* SOF0: Start of Frame (Baseline DCT) */
+  0x00, 0x11,		/* length = 17 bytes (including this length field) */
+  0x08			/* Precision: 8 */
+  /* 2 bytes is placed here: number of image lines */
+  /* 2 bytes is placed here: samples per line */
+};
+
+/* JPEG header, continued */
+static const unsigned char pac_jpeg_header2[] = {
+  0x03,			/* Number of image components: 3 */
+  0x01, 0x21, 0x00,	/* ID=1, Subsampling 1x1, Quantization table: 0 */
+  0x02, 0x11, 0x01,	/* ID=2, Subsampling 2x1, Quantization table: 1 */
+  0x03, 0x11, 0x01,	/* ID=3, Subsampling 2x1, Quantization table: 1 */
+
+  0xff, 0xda,		/* SOS: Start Of Scan */
+  0x00, 0x0c,		/* length = 12 bytes (including this length field) */
+  0x03,			/* number of components: 3 */
+  0x01, 0x00,		/* selector 1, table 0x00 */
+  0x02, 0x11,		/* selector 2, table 0x11 */
+  0x03, 0x11,		/* selector 3, table 0x11 */
+  0x00, 0x3f,		/* Spectral selection: 0 .. 63 */
+  0x00			/* Successive approximation: 0 */
+};
+
+static void pac_start_frame(struct gspca_dev *gspca_dev,
+		struct gspca_frame *frame,
+		__u16 lines, __u16 samples_per_line)
+{
+	unsigned char tmpbuf[4];
+
+	gspca_frame_add(gspca_dev, FIRST_PACKET,
+		pac_jpeg_header1, sizeof(pac_jpeg_header1));
+
+	tmpbuf[0] = lines >> 8;
+	tmpbuf[1] = lines & 0xff;
+	tmpbuf[2] = samples_per_line >> 8;
+	tmpbuf[3] = samples_per_line & 0xff;
+
+	gspca_frame_add(gspca_dev, INTER_PACKET,
+		tmpbuf, sizeof(tmpbuf));
+	gspca_frame_add(gspca_dev, INTER_PACKET,
+		pac_jpeg_header2, sizeof(pac_jpeg_header2));
+}
+
+/* this function is run at interrupt level */
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+			u8 *data,			/* isoc packet */
+			int len)			/* iso packet length */
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	struct gspca_frame *frame;
+	unsigned char *sof;
+
+	sof = pac_find_sof(&sd->sof_read, data, len);
+	if (sof) {
+		int n, lum_offset, footer_length;
+
+		frame = gspca_get_i_frame(gspca_dev);
+		if (frame == NULL) {
+			gspca_dev->last_packet_type = DISCARD_PACKET;
+			return;
+		}
+
+		/* 6 bytes after the FF D9 EOF marker a number of lumination
+		   bytes are send corresponding to different parts of the
+		   image, the 14th and 15th byte after the EOF seem to
+		   correspond to the center of the image */
+		lum_offset = 61 + sizeof pac_sof_marker;
+		footer_length = 74;
+
+		/* Finish decoding current frame */
+		n = (sof - data) - (footer_length + sizeof pac_sof_marker);
+		if (n < 0) {
+			frame->data_end += n;
+			n = 0;
+		}
+		gspca_frame_add(gspca_dev, INTER_PACKET,
+					data, n);
+		if (gspca_dev->last_packet_type != DISCARD_PACKET &&
+				frame->data_end[-2] == 0xff &&
+				frame->data_end[-1] == 0xd9)
+			gspca_frame_add(gspca_dev, LAST_PACKET,
+						NULL, 0);
+
+		n = sof - data;
+		len -= n;
+		data = sof;
+
+		/* Get average lumination */
+		if (gspca_dev->last_packet_type == LAST_PACKET &&
+				n >= lum_offset)
+			atomic_set(&sd->avg_lum, data[-lum_offset] +
+						data[-lum_offset + 1]);
+		else
+			atomic_set(&sd->avg_lum, -1);
+
+		/* Start the new frame with the jpeg header */
+		/* The PAC7302 has the image rotated 90 degrees */
+		pac_start_frame(gspca_dev, frame,
+			gspca_dev->width, gspca_dev->height);
+	}
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->brightness = val;
+	if (gspca_dev->streaming)
+		setbrightcont(gspca_dev);
+	return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->brightness;
+	return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->contrast = val;
+	if (gspca_dev->streaming) {
+		setbrightcont(gspca_dev);
+	}
+	return 0;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->contrast;
+	return 0;
+}
+
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->colors = val;
+	if (gspca_dev->streaming)
+		setcolors(gspca_dev);
+	return 0;
+}
+
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->colors;
+	return 0;
+}
+
+static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret = 0;
+
+	sd->white_balance = val;
+	if (gspca_dev->streaming)
+		ret = setwhitebalance(gspca_dev);
+	if (0 <= ret)
+		ret = 0;
+	return ret;
+}
+
+static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->white_balance;
+	return 0;
+}
+
+static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret = 0;
+
+	sd->red_balance = val;
+	if (gspca_dev->streaming)
+		ret = setredbalance(gspca_dev);
+	if (0 <= ret)
+		ret = 0;
+	return ret;
+}
+
+static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->red_balance;
+	return 0;
+}
+
+static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret = 0;
+
+	sd->blue_balance = val;
+	if (gspca_dev->streaming)
+		ret = setbluebalance(gspca_dev);
+	if (0 <= ret)
+		ret = 0;
+	return ret;
+}
+
+static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->blue_balance;
+	return 0;
+}
+
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->gain = val;
+	if (gspca_dev->streaming)
+		setgain(gspca_dev);
+	return 0;
+}
+
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->gain;
+	return 0;
+}
+
+static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->exposure = val;
+	if (gspca_dev->streaming)
+		setexposure(gspca_dev);
+	return 0;
+}
+
+static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->exposure;
+	return 0;
+}
+
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->autogain = val;
+	/* when switching to autogain set defaults to make sure
+	   we are on a valid point of the autogain gain /
+	   exposure knee graph, and give this change time to
+	   take effect before doing autogain. */
+	if (sd->autogain) {
+		sd->exposure = EXPOSURE_DEF;
+		sd->gain = GAIN_DEF;
+		if (gspca_dev->streaming) {
+			sd->autogain_ignore_frames =
+				PAC_AUTOGAIN_IGNORE_FRAMES;
+			setexposure(gspca_dev);
+			setgain(gspca_dev);
+		}
+	}
+
+	return 0;
+}
+
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->autogain;
+	return 0;
+}
+
+static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->hflip = val;
+	if (gspca_dev->streaming)
+		sethvflip(gspca_dev);
+	return 0;
+}
+
+static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->hflip;
+	return 0;
+}
+
+static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->vflip = val;
+	if (gspca_dev->streaming)
+		sethvflip(gspca_dev);
+	return 0;
+}
+
+static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->vflip;
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
+			struct v4l2_dbg_register *reg)
+{
+	int ret = -EINVAL;
+	__u8 index;
+	__u8 value;
+
+	/* reg->reg: bit0..15: reserved for register index (wIndex is 16bit
+			       long on the USB bus)
+	*/
+	if (reg->match.type == V4L2_CHIP_MATCH_HOST &&
+	    reg->match.addr == 0 &&
+	    (reg->reg < 0x000000ff) &&
+	    (reg->val <= 0x000000ff)
+	) {
+		/* Currently writing to page 0 is only supported. */
+		/* reg_w() only supports 8bit index */
+		index = reg->reg & 0x000000ff;
+		value = reg->val & 0x000000ff;
+
+		/* Note that there shall be no access to other page
+		   by any other function between the page swith and
+		   the actual register write */
+		ret = reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, index, value);
+
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0xdc, 0x01);
+	}
+	return ret;
+}
+
+static int sd_chip_ident(struct gspca_dev *gspca_dev,
+			struct v4l2_dbg_chip_ident *chip)
+{
+	int ret = -EINVAL;
+
+	if (chip->match.type == V4L2_CHIP_MATCH_HOST &&
+	    chip->match.addr == 0) {
+		chip->revision = 0;
+		chip->ident = V4L2_IDENT_UNKNOWN;
+		ret = 0;
+	}
+	return ret;
+}
+#endif
+
+/* sub-driver description for pac7302 */
+static struct sd_desc sd_desc = {
+	.name = MODULE_NAME,
+	.ctrls = sd_ctrls,
+	.nctrls = ARRAY_SIZE(sd_ctrls),
+	.config = sd_config,
+	.init = sd_init,
+	.start = sd_start,
+	.stopN = sd_stopN,
+	.stop0 = sd_stop0,
+	.pkt_scan = sd_pkt_scan,
+	.dq_callback = do_autogain,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.set_register = sd_dbg_s_register,
+	.get_chip_ident = sd_chip_ident,
+#endif
+};
+
+/* -- module initialisation -- */
+static __devinitdata struct usb_device_id device_table[] = {
+	{USB_DEVICE(0x06f8, 0x3009)},
+	{USB_DEVICE(0x093a, 0x2620)},
+	{USB_DEVICE(0x093a, 0x2621)},
+	{USB_DEVICE(0x093a, 0x2622)},
+	{USB_DEVICE(0x093a, 0x2624)},
+	{USB_DEVICE(0x093a, 0x2626)},
+	{USB_DEVICE(0x093a, 0x2628)},
+	{USB_DEVICE(0x093a, 0x2629)},
+	{USB_DEVICE(0x093a, 0x262a)},
+	{USB_DEVICE(0x093a, 0x262c)},
+	{}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+			const struct usb_device_id *id)
+{
+	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+				THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+	.name = MODULE_NAME,
+	.id_table = device_table,
+	.probe = sd_probe,
+	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
+	PDEBUG(D_PROBE, "registered");
+	return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+	usb_deregister(&sd_driver);
+	PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index 0527144..e5697a6 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -57,23 +57,17 @@
 MODULE_DESCRIPTION("Pixart PAC7311");
 MODULE_LICENSE("GPL");
 
-/* specific webcam descriptor */
+/* specific webcam descriptor for pac7311 */
 struct sd {
 	struct gspca_dev gspca_dev;		/* !! must be the first item */
 
-	unsigned char brightness;
 	unsigned char contrast;
-	unsigned char colors;
 	unsigned char gain;
 	unsigned char exposure;
 	unsigned char autogain;
 	__u8 hflip;
 	__u8 vflip;
 
-	__u8 sensor;
-#define SENSOR_PAC7302 0
-#define SENSOR_PAC7311 1
-
 	u8 sof_read;
 	u8 autogain_ignore_frames;
 
@@ -81,12 +75,8 @@
 };
 
 /* V4L2 controls supported by the driver */
-static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
@@ -99,23 +89,6 @@
 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
 
 static struct ctrl sd_ctrls[] = {
-/* This control is pac7302 only */
-#define BRIGHTNESS_IDX 0
-	{
-	    {
-		.id      = V4L2_CID_BRIGHTNESS,
-		.type    = V4L2_CTRL_TYPE_INTEGER,
-		.name    = "Brightness",
-		.minimum = 0,
-#define BRIGHTNESS_MAX 0x20
-		.maximum = BRIGHTNESS_MAX,
-		.step    = 1,
-#define BRIGHTNESS_DEF 0x10
-		.default_value = BRIGHTNESS_DEF,
-	    },
-	    .set = sd_setbrightness,
-	    .get = sd_getbrightness,
-	},
 /* This control is for both the 7302 and the 7311 */
 	{
 	    {
@@ -132,23 +105,6 @@
 	    .set = sd_setcontrast,
 	    .get = sd_getcontrast,
 	},
-/* This control is pac7302 only */
-#define SATURATION_IDX 2
-	{
-	    {
-		.id      = V4L2_CID_SATURATION,
-		.type    = V4L2_CTRL_TYPE_INTEGER,
-		.name    = "Saturation",
-		.minimum = 0,
-#define COLOR_MAX 255
-		.maximum = COLOR_MAX,
-		.step    = 1,
-#define COLOR_DEF 127
-		.default_value = COLOR_DEF,
-	    },
-	    .set = sd_setcolors,
-	    .get = sd_getcolors,
-	},
 /* All controls below are for both the 7302 and the 7311 */
 	{
 	    {
@@ -244,101 +200,9 @@
 		.priv = 0},
 };
 
-/* pac 7302 */
-static const __u8 init_7302[] = {
-/*	index,value */
-	0xff, 0x01,		/* page 1 */
-	0x78, 0x00,		/* deactivate */
-	0xff, 0x01,
-	0x78, 0x40,		/* led off */
-};
-static const __u8 start_7302[] = {
-/*	index, len, [value]* */
-	0xff, 1,	0x00,		/* page 0 */
-	0x00, 12,	0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
-			0x00, 0x00, 0x00, 0x00,
-	0x0d, 24,	0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
-			0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
-			0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
-	0x26, 2,	0xaa, 0xaa,
-	0x2e, 1,	0x31,
-	0x38, 1,	0x01,
-	0x3a, 3,	0x14, 0xff, 0x5a,
-	0x43, 11,	0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
-			0x00, 0x54, 0x11,
-	0x55, 1,	0x00,
-	0x62, 4, 	0x10, 0x1e, 0x1e, 0x18,
-	0x6b, 1,	0x00,
-	0x6e, 3,	0x08, 0x06, 0x00,
-	0x72, 3,	0x00, 0xff, 0x00,
-	0x7d, 23,	0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
-			0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
-			0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
-	0xa2, 10,	0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
-			0xd2, 0xeb,
-	0xaf, 1,	0x02,
-	0xb5, 2,	0x08, 0x08,
-	0xb8, 2,	0x08, 0x88,
-	0xc4, 4,	0xae, 0x01, 0x04, 0x01,
-	0xcc, 1,	0x00,
-	0xd1, 11,	0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
-			0xc1, 0xd7, 0xec,
-	0xdc, 1,	0x01,
-	0xff, 1,	0x01,		/* page 1 */
-	0x12, 3,	0x02, 0x00, 0x01,
-	0x3e, 2,	0x00, 0x00,
-	0x76, 5,	0x01, 0x20, 0x40, 0x00, 0xf2,
-	0x7c, 1,	0x00,
-	0x7f, 10,	0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
-			0x02, 0x00,
-	0x96, 5,	0x01, 0x10, 0x04, 0x01, 0x04,
-	0xc8, 14,	0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
-			0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
-	0xd8, 1,	0x01,
-	0xdb, 2,	0x00, 0x01,
-	0xde, 7,	0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
-	0xe6, 4,	0x00, 0x00, 0x00, 0x01,
-	0xeb, 1,	0x00,
-	0xff, 1,	0x02,		/* page 2 */
-	0x22, 1,	0x00,
-	0xff, 1,	0x03,		/* page 3 */
-	0x00, 255,			/* load the page 3 */
-	0x11, 1,	0x01,
-	0xff, 1,	0x02,		/* page 2 */
-	0x13, 1,	0x00,
-	0x22, 4,	0x1f, 0xa4, 0xf0, 0x96,
-	0x27, 2,	0x14, 0x0c,
-	0x2a, 5,	0xc8, 0x00, 0x18, 0x12, 0x22,
-	0x64, 8,	0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
-	0x6e, 1,	0x08,
-	0xff, 1,	0x01,		/* page 1 */
-	0x78, 1,	0x00,
-	0, 0				/* end of sequence */
-};
-
-/* page 3 - the value 0xaa says skip the index - see reg_w_page() */
-static const __u8 page3_7302[] = {
-	0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16,
-	0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
-	0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
-	0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
-	0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
-	0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
-	0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
-	0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
-	0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
-	0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
-	0x00
-};
+#define LOAD_PAGE3		255
+#define LOAD_PAGE4		254
+#define END_OF_SEQUENCE		0
 
 /* pac 7311 */
 static const __u8 init_7311[] = {
@@ -378,119 +242,154 @@
 	0xf0, 13,	0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00,
 			0x3f, 0x00, 0x0a, 0x01, 0x00,
 	0xff, 1,	0x04,		/* page 4 */
-	0x00, 254,			/* load the page 4 */
+	0, LOAD_PAGE4,			/* load the page 4 */
 	0x11, 1,	0x01,
-	0, 0				/* end of sequence */
+	0, END_OF_SEQUENCE		/* end of sequence */
 };
 
-/* page 4 - the value 0xaa says skip the index - see reg_w_page() */
+#define SKIP		0xaa
+/* page 4 - the value SKIP says skip the index - see reg_w_page() */
 static const __u8 page4_7311[] = {
-	0xaa, 0xaa, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f,
-	0x09, 0x00, 0xaa, 0xaa, 0x07, 0x00, 0x00, 0x62,
-	0x08, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, 0xaa,
-	0xaa, 0x00, 0x08, 0xaa, 0x03, 0xaa, 0x00, 0x68,
+	SKIP, SKIP, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f,
+	0x09, 0x00, SKIP, SKIP, 0x07, 0x00, 0x00, 0x62,
+	0x08, SKIP, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, SKIP,
+	SKIP, 0x00, 0x08, SKIP, 0x03, SKIP, 0x00, 0x68,
 	0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00,
 	0x23, 0x28, 0x04, 0x11, 0x00, 0x00
 };
 
-static void reg_w_buf(struct gspca_dev *gspca_dev,
+static int reg_w_buf(struct gspca_dev *gspca_dev,
 		  __u8 index,
 		  const char *buffer, int len)
 {
+	int ret;
+
 	memcpy(gspca_dev->usb_buf, buffer, len);
-	usb_control_msg(gspca_dev->dev,
+	ret = usb_control_msg(gspca_dev->dev,
 			usb_sndctrlpipe(gspca_dev->dev, 0),
 			1,		/* request */
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			0,		/* value */
 			index, gspca_dev->usb_buf, len,
 			500);
+	if (ret < 0)
+		PDEBUG(D_ERR, "reg_w_buf(): "
+		"Failed to write registers to index 0x%x, error %i",
+		index, ret);
+	return ret;
 }
 
 
-static void reg_w(struct gspca_dev *gspca_dev,
+static int reg_w(struct gspca_dev *gspca_dev,
 		  __u8 index,
 		  __u8 value)
 {
+	int ret;
+
 	gspca_dev->usb_buf[0] = value;
-	usb_control_msg(gspca_dev->dev,
+	ret = usb_control_msg(gspca_dev->dev,
 			usb_sndctrlpipe(gspca_dev->dev, 0),
 			0,			/* request */
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			0, index, gspca_dev->usb_buf, 1,
 			500);
+	if (ret < 0)
+		PDEBUG(D_ERR, "reg_w(): "
+		"Failed to write register to index 0x%x, value 0x%x, error %i",
+		index, value, ret);
+	return ret;
 }
 
-static void reg_w_seq(struct gspca_dev *gspca_dev,
+static int reg_w_seq(struct gspca_dev *gspca_dev,
 		const __u8 *seq, int len)
 {
+	int ret = 0;
 	while (--len >= 0) {
-		reg_w(gspca_dev, seq[0], seq[1]);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, seq[0], seq[1]);
 		seq += 2;
 	}
+	return ret;
 }
 
 /* load the beginning of a page */
-static void reg_w_page(struct gspca_dev *gspca_dev,
+static int reg_w_page(struct gspca_dev *gspca_dev,
 			const __u8 *page, int len)
 {
 	int index;
+	int ret = 0;
 
 	for (index = 0; index < len; index++) {
-		if (page[index] == 0xaa)		/* skip this index */
+		if (page[index] == SKIP)		/* skip this index */
 			continue;
 		gspca_dev->usb_buf[0] = page[index];
-		usb_control_msg(gspca_dev->dev,
+		ret = usb_control_msg(gspca_dev->dev,
 				usb_sndctrlpipe(gspca_dev->dev, 0),
 				0,			/* request */
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 				0, index, gspca_dev->usb_buf, 1,
 				500);
+		if (ret < 0) {
+			PDEBUG(D_ERR, "reg_w_page(): "
+			"Failed to write register to index 0x%x, "
+			"value 0x%x, error %i",
+			index, page[index], ret);
+			break;
+		}
 	}
+	return ret;
 }
 
 /* output a variable sequence */
-static void reg_w_var(struct gspca_dev *gspca_dev,
-			const __u8 *seq)
+static int reg_w_var(struct gspca_dev *gspca_dev,
+			const __u8 *seq,
+			const __u8 *page3, unsigned int page3_len,
+			const __u8 *page4, unsigned int page4_len)
 {
 	int index, len;
+	int ret = 0;
 
 	for (;;) {
 		index = *seq++;
 		len = *seq++;
 		switch (len) {
-		case 0:
-			return;
-		case 254:
-			reg_w_page(gspca_dev, page4_7311, sizeof page4_7311);
+		case END_OF_SEQUENCE:
+			return ret;
+		case LOAD_PAGE4:
+			ret = reg_w_page(gspca_dev, page4, page4_len);
 			break;
-		case 255:
-			reg_w_page(gspca_dev, page3_7302, sizeof page3_7302);
+		case LOAD_PAGE3:
+			ret = reg_w_page(gspca_dev, page3, page3_len);
 			break;
 		default:
-			if (len > 64) {
+			if (len > USB_BUF_SZ) {
 				PDEBUG(D_ERR|D_STREAM,
 					"Incorrect variable sequence");
-				return;
+				return -EINVAL;
 			}
 			while (len > 0) {
 				if (len < 8) {
-					reg_w_buf(gspca_dev, index, seq, len);
+					ret = reg_w_buf(gspca_dev,
+						index, seq, len);
+					if (ret < 0)
+						return ret;
 					seq += len;
 					break;
 				}
-				reg_w_buf(gspca_dev, index, seq, 8);
+				ret = reg_w_buf(gspca_dev, index, seq, 8);
 				seq += 8;
 				index += 8;
 				len -= 8;
 			}
 		}
+		if (ret < 0)
+			return ret;
 	}
 	/* not reached */
 }
 
-/* this function is called at probe time */
+/* this function is called at probe time for pac7311 */
 static int sd_config(struct gspca_dev *gspca_dev,
 			const struct usb_device_id *id)
 {
@@ -499,22 +398,11 @@
 
 	cam = &gspca_dev->cam;
 
-	sd->sensor = id->driver_info;
-	if (sd->sensor == SENSOR_PAC7302) {
-		PDEBUG(D_CONF, "Find Sensor PAC7302");
-		cam->cam_mode = &vga_mode[2];	/* only 640x480 */
-		cam->nmodes = 1;
-	} else {
-		PDEBUG(D_CONF, "Find Sensor PAC7311");
-		cam->cam_mode = vga_mode;
-		cam->nmodes = ARRAY_SIZE(vga_mode);
-		gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX)
-				| (1 << SATURATION_IDX);
-	}
+	PDEBUG(D_CONF, "Find Sensor PAC7311");
+	cam->cam_mode = vga_mode;
+	cam->nmodes = ARRAY_SIZE(vga_mode);
 
-	sd->brightness = BRIGHTNESS_DEF;
 	sd->contrast = CONTRAST_DEF;
-	sd->colors = COLOR_DEF;
 	sd->gain = GAIN_DEF;
 	sd->exposure = EXPOSURE_DEF;
 	sd->autogain = AUTOGAIN_DEF;
@@ -523,91 +411,47 @@
 	return 0;
 }
 
-/* This function is used by pac7302 only */
-static void setbrightcont(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	int i, v;
-	static const __u8 max[10] =
-		{0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
-		 0xd4, 0xec};
-	static const __u8 delta[10] =
-		{0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
-		 0x11, 0x0b};
-
-	reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
-	for (i = 0; i < 10; i++) {
-		v = max[i];
-		v += (sd->brightness - BRIGHTNESS_MAX)
-			* 150 / BRIGHTNESS_MAX;		/* 200 ? */
-		v -= delta[i] * sd->contrast / CONTRAST_MAX;
-		if (v < 0)
-			v = 0;
-		else if (v > 0xff)
-			v = 0xff;
-		reg_w(gspca_dev, 0xa2 + i, v);
-	}
-	reg_w(gspca_dev, 0xdc, 0x01);
-}
-
 /* This function is used by pac7311 only */
-static void setcontrast(struct gspca_dev *gspca_dev)
+static int setcontrast(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
 
-	reg_w(gspca_dev, 0xff, 0x04);
-	reg_w(gspca_dev, 0x10, sd->contrast >> 4);
+	ret = reg_w(gspca_dev, 0xff, 0x04);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x10, sd->contrast >> 4);
 	/* load registers to sensor (Bit 0, auto clear) */
-	reg_w(gspca_dev, 0x11, 0x01);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x11, 0x01);
+	return ret;
 }
 
-/* This function is used by pac7302 only */
-static void setcolors(struct gspca_dev *gspca_dev)
+static int setgain(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int i, v;
-	static const int a[9] =
-		{217, -212, 0, -101, 170, -67, -38, -315, 355};
-	static const int b[9] =
-		{19, 106, 0, 19, 106, 1, 19, 106, 1};
+	int gain = GAIN_MAX - sd->gain;
+	int ret;
 
-	reg_w(gspca_dev, 0xff, 0x03);	/* page 3 */
-	reg_w(gspca_dev, 0x11, 0x01);
-	reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
-	reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
-	for (i = 0; i < 9; i++) {
-		v = a[i] * sd->colors / COLOR_MAX + b[i];
-		reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
-		reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
-	}
-	reg_w(gspca_dev, 0xdc, 0x01);
-	PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
-}
+	if (gain < 1)
+		gain = 1;
+	else if (gain > 245)
+		gain = 245;
+	ret = reg_w(gspca_dev, 0xff, 0x04);		/* page 4 */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x0e, 0x00);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x0f, gain);
 
-static void setgain(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	if (sd->sensor == SENSOR_PAC7302) {
-		reg_w(gspca_dev, 0xff, 0x03);		/* page 3 */
-		reg_w(gspca_dev, 0x10, sd->gain >> 3);
-	} else {
-		int gain = GAIN_MAX - sd->gain;
-		if (gain < 1)
-			gain = 1;
-		else if (gain > 245)
-			gain = 245;
-		reg_w(gspca_dev, 0xff, 0x04);		/* page 4 */
-		reg_w(gspca_dev, 0x0e, 0x00);
-		reg_w(gspca_dev, 0x0f, gain);
-	}
 	/* load registers to sensor (Bit 0, auto clear) */
-	reg_w(gspca_dev, 0x11, 0x01);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x11, 0x01);
+	return ret;
 }
 
-static void setexposure(struct gspca_dev *gspca_dev)
+static int setexposure(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
 	__u8 reg;
 
 	/* register 2 of frame 3/4 contains the clock divider configuring the
@@ -619,97 +463,94 @@
 	else if (reg > 63)
 		reg = 63;
 
-	if (sd->sensor == SENSOR_PAC7302) {
-		/* On the pac7302 reg2 MUST be a multiple of 3, so round it to
-		   the nearest multiple of 3, except when between 6 and 12? */
-		if (reg < 6 || reg > 12)
-			reg = ((reg + 1) / 3) * 3;
-		reg_w(gspca_dev, 0xff, 0x03);		/* page 3 */
-		reg_w(gspca_dev, 0x02, reg);
+	ret = reg_w(gspca_dev, 0xff, 0x04);		/* page 4 */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x02, reg);
+	/* Page 1 register 8 must always be 0x08 except when not in
+	   640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xff, 0x01);
+	if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
+			reg <= 3) {
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0x08, 0x09);
 	} else {
-		reg_w(gspca_dev, 0xff, 0x04);		/* page 4 */
-		reg_w(gspca_dev, 0x02, reg);
-		/* Page 1 register 8 must always be 0x08 except when not in
-		   640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
-		reg_w(gspca_dev, 0xff, 0x01);
-		if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
-				reg <= 3)
-			reg_w(gspca_dev, 0x08, 0x09);
-		else
-			reg_w(gspca_dev, 0x08, 0x08);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0x08, 0x08);
 	}
+
 	/* load registers to sensor (Bit 0, auto clear) */
-	reg_w(gspca_dev, 0x11, 0x01);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x11, 0x01);
+	return ret;
 }
 
-static void sethvflip(struct gspca_dev *gspca_dev)
+static int sethvflip(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
 	__u8 data;
 
-	if (sd->sensor == SENSOR_PAC7302) {
-		reg_w(gspca_dev, 0xff, 0x03);		/* page 3 */
-		data = (sd->hflip ? 0x08 : 0x00)
-			| (sd->vflip ? 0x04 : 0x00);
-	} else {
-		reg_w(gspca_dev, 0xff, 0x04);		/* page 4 */
-		data = (sd->hflip ? 0x04 : 0x00)
-			| (sd->vflip ? 0x08 : 0x00);
-	}
-	reg_w(gspca_dev, 0x21, data);
+	ret = reg_w(gspca_dev, 0xff, 0x04);		/* page 4 */
+	data = (sd->hflip ? 0x04 : 0x00) | (sd->vflip ? 0x08 : 0x00);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x21, data);
 	/* load registers to sensor (Bit 0, auto clear) */
-	reg_w(gspca_dev, 0x11, 0x01);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x11, 0x01);
+	return ret;
 }
 
-/* this function is called at probe and resume time */
+/* this function is called at probe and resume time for pac7311 */
 static int sd_init(struct gspca_dev *gspca_dev)
 {
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	if (sd->sensor == SENSOR_PAC7302)
-		reg_w_seq(gspca_dev, init_7302, sizeof init_7302);
-	else
-		reg_w_seq(gspca_dev, init_7311, sizeof init_7311);
-
-	return 0;
+	return reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2);
 }
 
 static int sd_start(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
 
 	sd->sof_read = 0;
 
-	if (sd->sensor == SENSOR_PAC7302) {
-		reg_w_var(gspca_dev, start_7302);
-		setbrightcont(gspca_dev);
-		setcolors(gspca_dev);
-	} else {
-		reg_w_var(gspca_dev, start_7311);
-		setcontrast(gspca_dev);
-	}
-	setgain(gspca_dev);
-	setexposure(gspca_dev);
-	sethvflip(gspca_dev);
+	ret = reg_w_var(gspca_dev, start_7311,
+		NULL, 0,
+		page4_7311, sizeof(page4_7311));
+	if (0 <= ret)
+		ret = setcontrast(gspca_dev);
+	if (0 <= ret)
+		ret = setgain(gspca_dev);
+	if (0 <= ret)
+		ret = setexposure(gspca_dev);
+	if (0 <= ret)
+		ret = sethvflip(gspca_dev);
 
 	/* set correct resolution */
 	switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
 	case 2:					/* 160x120 pac7311 */
-		reg_w(gspca_dev, 0xff, 0x01);
-		reg_w(gspca_dev, 0x17, 0x20);
-		reg_w(gspca_dev, 0x87, 0x10);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0xff, 0x01);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0x17, 0x20);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0x87, 0x10);
 		break;
 	case 1:					/* 320x240 pac7311 */
-		reg_w(gspca_dev, 0xff, 0x01);
-		reg_w(gspca_dev, 0x17, 0x30);
-		reg_w(gspca_dev, 0x87, 0x11);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0xff, 0x01);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0x17, 0x30);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0x87, 0x11);
 		break;
 	case 0:					/* 640x480 */
-		if (sd->sensor == SENSOR_PAC7302)
-			break;
-		reg_w(gspca_dev, 0xff, 0x01);
-		reg_w(gspca_dev, 0x17, 0x00);
-		reg_w(gspca_dev, 0x87, 0x12);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0xff, 0x01);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0x17, 0x00);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0x87, 0x12);
 		break;
 	}
 
@@ -718,47 +559,42 @@
 	atomic_set(&sd->avg_lum, -1);
 
 	/* start stream */
-	reg_w(gspca_dev, 0xff, 0x01);
-	if (sd->sensor == SENSOR_PAC7302)
-		reg_w(gspca_dev, 0x78, 0x01);
-	else
-		reg_w(gspca_dev, 0x78, 0x05);
-	return 0;
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xff, 0x01);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x78, 0x05);
+
+	return ret;
 }
 
 static void sd_stopN(struct gspca_dev *gspca_dev)
 {
-	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
 
-	if (sd->sensor == SENSOR_PAC7302) {
-		reg_w(gspca_dev, 0xff, 0x01);
-		reg_w(gspca_dev, 0x78, 0x00);
-		reg_w(gspca_dev, 0x78, 0x00);
-		return;
-	}
-	reg_w(gspca_dev, 0xff, 0x04);
-	reg_w(gspca_dev, 0x27, 0x80);
-	reg_w(gspca_dev, 0x28, 0xca);
-	reg_w(gspca_dev, 0x29, 0x53);
-	reg_w(gspca_dev, 0x2a, 0x0e);
-	reg_w(gspca_dev, 0xff, 0x01);
-	reg_w(gspca_dev, 0x3e, 0x20);
-	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
-	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
-	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
+	ret = reg_w(gspca_dev, 0xff, 0x04);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x27, 0x80);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x28, 0xca);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x29, 0x53);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x2a, 0x0e);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xff, 0x01);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x3e, 0x20);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
 }
 
-/* called on streamoff with alt 0 and on disconnect */
+/* called on streamoff with alt 0 and on disconnect for 7311 */
 static void sd_stop0(struct gspca_dev *gspca_dev)
 {
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	if (!gspca_dev->present)
-		return;
-	if (sd->sensor == SENSOR_PAC7302) {
-		reg_w(gspca_dev, 0xff, 0x01);
-		reg_w(gspca_dev, 0x78, 0x40);
-	}
 }
 
 /* Include pac common sof detection functions */
@@ -773,22 +609,8 @@
 	if (avg_lum == -1)
 		return;
 
-	if (sd->sensor == SENSOR_PAC7302) {
-		desired_lum = 270 + sd->brightness * 4;
-		/* Hack hack, with the 7202 the first exposure step is
-		   pretty large, so if we're about to make the first
-		   exposure increase make the deadzone large to avoid
-		   oscilating */
-		if (desired_lum > avg_lum && sd->gain == GAIN_DEF &&
-				sd->exposure > EXPOSURE_DEF &&
-				sd->exposure < 42)
-			deadzone = 90;
-		else
-			deadzone = 30;
-	} else {
-		desired_lum = 200;
-		deadzone = 20;
-	}
+	desired_lum = 200;
+	deadzone = 20;
 
 	if (sd->autogain_ignore_frames > 0)
 		sd->autogain_ignore_frames--;
@@ -797,53 +619,92 @@
 		sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
 }
 
-static const unsigned char pac7311_jpeg_header1[] = {
-  0xff, 0xd8, 0xff, 0xc0, 0x00, 0x11, 0x08
+/* JPEG header, part 1 */
+static const unsigned char pac_jpeg_header1[] = {
+  0xff, 0xd8,		/* SOI: Start of Image */
+
+  0xff, 0xc0,		/* SOF0: Start of Frame (Baseline DCT) */
+  0x00, 0x11,		/* length = 17 bytes (including this length field) */
+  0x08			/* Precision: 8 */
+  /* 2 bytes is placed here: number of image lines */
+  /* 2 bytes is placed here: samples per line */
 };
 
-static const unsigned char pac7311_jpeg_header2[] = {
-  0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda,
-  0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00
+/* JPEG header, continued */
+static const unsigned char pac_jpeg_header2[] = {
+  0x03,			/* Number of image components: 3 */
+  0x01, 0x21, 0x00,	/* ID=1, Subsampling 1x1, Quantization table: 0 */
+  0x02, 0x11, 0x01,	/* ID=2, Subsampling 2x1, Quantization table: 1 */
+  0x03, 0x11, 0x01,	/* ID=3, Subsampling 2x1, Quantization table: 1 */
+
+  0xff, 0xda,		/* SOS: Start Of Scan */
+  0x00, 0x0c,		/* length = 12 bytes (including this length field) */
+  0x03,			/* number of components: 3 */
+  0x01, 0x00,		/* selector 1, table 0x00 */
+  0x02, 0x11,		/* selector 2, table 0x11 */
+  0x03, 0x11,		/* selector 3, table 0x11 */
+  0x00, 0x3f,		/* Spectral selection: 0 .. 63 */
+  0x00			/* Successive approximation: 0 */
 };
 
+static void pac_start_frame(struct gspca_dev *gspca_dev,
+		struct gspca_frame *frame,
+		__u16 lines, __u16 samples_per_line)
+{
+	unsigned char tmpbuf[4];
+
+	gspca_frame_add(gspca_dev, FIRST_PACKET,
+		pac_jpeg_header1, sizeof(pac_jpeg_header1));
+
+	tmpbuf[0] = lines >> 8;
+	tmpbuf[1] = lines & 0xff;
+	tmpbuf[2] = samples_per_line >> 8;
+	tmpbuf[3] = samples_per_line & 0xff;
+
+	gspca_frame_add(gspca_dev, INTER_PACKET,
+		tmpbuf, sizeof(tmpbuf));
+	gspca_frame_add(gspca_dev, INTER_PACKET,
+		pac_jpeg_header2, sizeof(pac_jpeg_header2));
+}
+
 /* this function is run at interrupt level */
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	unsigned char *sof;
+	struct gspca_frame *frame;
 
-	sof = pac_find_sof(gspca_dev, data, len);
+	sof = pac_find_sof(&sd->sof_read, data, len);
 	if (sof) {
-		unsigned char tmpbuf[4];
 		int n, lum_offset, footer_length;
 
-		if (sd->sensor == SENSOR_PAC7302) {
-		  /* 6 bytes after the FF D9 EOF marker a number of lumination
-		     bytes are send corresponding to different parts of the
-		     image, the 14th and 15th byte after the EOF seem to
-		     correspond to the center of the image */
-		  lum_offset = 61 + sizeof pac_sof_marker;
-		  footer_length = 74;
-		} else {
-		  lum_offset = 24 + sizeof pac_sof_marker;
-		  footer_length = 26;
+		frame = gspca_get_i_frame(gspca_dev);
+		if (frame == NULL) {
+			gspca_dev->last_packet_type = DISCARD_PACKET;
+			return;
 		}
 
+		/* 6 bytes after the FF D9 EOF marker a number of lumination
+		   bytes are send corresponding to different parts of the
+		   image, the 14th and 15th byte after the EOF seem to
+		   correspond to the center of the image */
+		lum_offset = 24 + sizeof pac_sof_marker;
+		footer_length = 26;
+
 		/* Finish decoding current frame */
 		n = (sof - data) - (footer_length + sizeof pac_sof_marker);
 		if (n < 0) {
 			frame->data_end += n;
 			n = 0;
 		}
-		frame = gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+		gspca_frame_add(gspca_dev, INTER_PACKET,
 					data, n);
 		if (gspca_dev->last_packet_type != DISCARD_PACKET &&
 				frame->data_end[-2] == 0xff &&
 				frame->data_end[-1] == 0xd9)
-			frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+			gspca_frame_add(gspca_dev, LAST_PACKET,
 						NULL, 0);
 
 		n = sof - data;
@@ -859,43 +720,10 @@
 			atomic_set(&sd->avg_lum, -1);
 
 		/* Start the new frame with the jpeg header */
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
-			pac7311_jpeg_header1, sizeof(pac7311_jpeg_header1));
-		if (sd->sensor == SENSOR_PAC7302) {
-			/* The PAC7302 has the image rotated 90 degrees */
-			tmpbuf[0] = gspca_dev->width >> 8;
-			tmpbuf[1] = gspca_dev->width & 0xff;
-			tmpbuf[2] = gspca_dev->height >> 8;
-			tmpbuf[3] = gspca_dev->height & 0xff;
-		} else {
-			tmpbuf[0] = gspca_dev->height >> 8;
-			tmpbuf[1] = gspca_dev->height & 0xff;
-			tmpbuf[2] = gspca_dev->width >> 8;
-			tmpbuf[3] = gspca_dev->width & 0xff;
-		}
-		gspca_frame_add(gspca_dev, INTER_PACKET, frame, tmpbuf, 4);
-		gspca_frame_add(gspca_dev, INTER_PACKET, frame,
-			pac7311_jpeg_header2, sizeof(pac7311_jpeg_header2));
+		pac_start_frame(gspca_dev, frame,
+			gspca_dev->height, gspca_dev->width);
 	}
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
-}
-
-static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	sd->brightness = val;
-	if (gspca_dev->streaming)
-		setbrightcont(gspca_dev);
-	return 0;
-}
-
-static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	*val = sd->brightness;
-	return 0;
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
@@ -904,10 +732,7 @@
 
 	sd->contrast = val;
 	if (gspca_dev->streaming) {
-		if (sd->sensor == SENSOR_PAC7302)
-			setbrightcont(gspca_dev);
-		else
-			setcontrast(gspca_dev);
+		setcontrast(gspca_dev);
 	}
 	return 0;
 }
@@ -920,24 +745,6 @@
 	return 0;
 }
 
-static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	sd->colors = val;
-	if (gspca_dev->streaming)
-		setcolors(gspca_dev);
-	return 0;
-}
-
-static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	*val = sd->colors;
-	return 0;
-}
-
 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -1041,7 +848,7 @@
 	return 0;
 }
 
-/* sub-driver description */
+/* sub-driver description for pac7311 */
 static struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
 	.ctrls = sd_ctrls,
@@ -1057,21 +864,12 @@
 
 /* -- module initialisation -- */
 static __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x06f8, 0x3009), .driver_info = SENSOR_PAC7302},
-	{USB_DEVICE(0x093a, 0x2600), .driver_info = SENSOR_PAC7311},
-	{USB_DEVICE(0x093a, 0x2601), .driver_info = SENSOR_PAC7311},
-	{USB_DEVICE(0x093a, 0x2603), .driver_info = SENSOR_PAC7311},
-	{USB_DEVICE(0x093a, 0x2608), .driver_info = SENSOR_PAC7311},
-	{USB_DEVICE(0x093a, 0x260e), .driver_info = SENSOR_PAC7311},
-	{USB_DEVICE(0x093a, 0x260f), .driver_info = SENSOR_PAC7311},
-	{USB_DEVICE(0x093a, 0x2620), .driver_info = SENSOR_PAC7302},
-	{USB_DEVICE(0x093a, 0x2621), .driver_info = SENSOR_PAC7302},
-	{USB_DEVICE(0x093a, 0x2622), .driver_info = SENSOR_PAC7302},
-	{USB_DEVICE(0x093a, 0x2624), .driver_info = SENSOR_PAC7302},
-	{USB_DEVICE(0x093a, 0x2626), .driver_info = SENSOR_PAC7302},
-	{USB_DEVICE(0x093a, 0x2629), .driver_info = SENSOR_PAC7302},
-	{USB_DEVICE(0x093a, 0x262a), .driver_info = SENSOR_PAC7302},
-	{USB_DEVICE(0x093a, 0x262c), .driver_info = SENSOR_PAC7302},
+	{USB_DEVICE(0x093a, 0x2600)},
+	{USB_DEVICE(0x093a, 0x2601)},
+	{USB_DEVICE(0x093a, 0x2603)},
+	{USB_DEVICE(0x093a, 0x2608)},
+	{USB_DEVICE(0x093a, 0x260e)},
+	{USB_DEVICE(0x093a, 0x260f)},
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
diff --git a/drivers/media/video/gspca/pac_common.h b/drivers/media/video/gspca/pac_common.h
index 34d4b14..20f67d9 100644
--- a/drivers/media/video/gspca/pac_common.h
+++ b/drivers/media/video/gspca/pac_common.h
@@ -33,26 +33,101 @@
 static const unsigned char pac_sof_marker[5] =
 		{ 0xff, 0xff, 0x00, 0xff, 0x96 };
 
-static unsigned char *pac_find_sof(struct gspca_dev *gspca_dev,
+/*
+   The following state machine finds the SOF marker sequence
+   0xff, 0xff, 0x00, 0xff, 0x96 in a byte stream.
+
+	   +----------+
+	   | 0: START |<---------------\
+	   +----------+<-\             |
+	     |       \---/otherwise    |
+	     v 0xff                    |
+	   +----------+ otherwise      |
+	   |     1    |--------------->*
+	   |          |                ^
+	   +----------+                |
+	     |                         |
+	     v 0xff                    |
+	   +----------+<-\0xff         |
+	/->|          |--/             |
+	|  |     2    |--------------->*
+	|  |          | otherwise      ^
+	|  +----------+                |
+	|    |                         |
+	|    v 0x00                    |
+	|  +----------+                |
+	|  |     3    |                |
+	|  |          |--------------->*
+	|  +----------+ otherwise      ^
+	|    |                         |
+   0xff |    v 0xff                    |
+	|  +----------+                |
+	\--|     4    |                |
+	   |          |----------------/
+	   +----------+ otherwise
+	     |
+	     v 0x96
+	   +----------+
+	   |  FOUND   |
+	   +----------+
+*/
+
+static unsigned char *pac_find_sof(u8 *sof_read,
 					unsigned char *m, int len)
 {
-	struct sd *sd = (struct sd *) gspca_dev;
 	int i;
 
 	/* Search for the SOF marker (fixed part) in the header */
 	for (i = 0; i < len; i++) {
-		if (m[i] == pac_sof_marker[sd->sof_read]) {
-			sd->sof_read++;
-			if (sd->sof_read == sizeof(pac_sof_marker)) {
+		switch (*sof_read) {
+		case 0:
+			if (m[i] == 0xff)
+				*sof_read = 1;
+			break;
+		case 1:
+			if (m[i] == 0xff)
+				*sof_read = 2;
+			else
+				*sof_read = 0;
+			break;
+		case 2:
+			switch (m[i]) {
+			case 0x00:
+				*sof_read = 3;
+				break;
+			case 0xff:
+				/* stay in this state */
+				break;
+			default:
+				*sof_read = 0;
+			}
+			break;
+		case 3:
+			if (m[i] == 0xff)
+				*sof_read = 4;
+			else
+				*sof_read = 0;
+			break;
+		case 4:
+			switch (m[i]) {
+			case 0x96:
+				/* Pattern found */
 				PDEBUG(D_FRAM,
 					"SOF found, bytes to analyze: %u."
 					" Frame starts at byte #%u",
 					len, i + 1);
-				sd->sof_read = 0;
+				*sof_read = 0;
 				return m + i + 1;
+				break;
+			case 0xff:
+				*sof_read = 2;
+				break;
+			default:
+				*sof_read = 0;
 			}
-		} else {
-			sd->sof_read = 0;
+			break;
+		default:
+			*sof_read = 0;
 		}
 	}
 
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
index cdad3db..b1944a7 100644
--- a/drivers/media/video/gspca/sn9c20x.c
+++ b/drivers/media/video/gspca/sn9c20x.c
@@ -2342,7 +2342,6 @@
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
 			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
@@ -2378,22 +2377,22 @@
 		avg_lum >>= 9;
 		atomic_set(&sd->avg_lum, avg_lum);
 		gspca_frame_add(gspca_dev, LAST_PACKET,
-				frame, data, len);
+				data, len);
 		return;
 	}
 	if (gspca_dev->last_packet_type == LAST_PACKET) {
 		if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv
 				& MODE_JPEG) {
-			gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+			gspca_frame_add(gspca_dev, FIRST_PACKET,
 				sd->jpeg_hdr, JPEG_HDR_SZ);
-			gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+			gspca_frame_add(gspca_dev, INTER_PACKET,
 				data, len);
 		} else {
-			gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+			gspca_frame_add(gspca_dev, FIRST_PACKET,
 				data, len);
 		}
 	} else {
-		gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+		gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 	}
 }
 
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index cf3af8d..5be95bc 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -304,7 +304,7 @@
 };
 static const __u8 ov6650_sensor_init[][8] =
 {
-	/* Bright, contrast, etc are set througth SCBB interface.
+	/* Bright, contrast, etc are set through SCBB interface.
 	 * AVCAP on win2 do not send any data on this 	controls. */
 	/* Anyway, some registers appears to alter bright and constrat */
 
@@ -995,8 +995,7 @@
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			unsigned char *data,		/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	int i;
@@ -1054,12 +1053,12 @@
 					pkt_type = DISCARD_PACKET;
 				}
 
-				frame = gspca_frame_add(gspca_dev, pkt_type,
-							frame, data, 0);
+				gspca_frame_add(gspca_dev, pkt_type,
+						NULL, 0);
 				data += i + fr_h_sz;
 				len -= i + fr_h_sz;
 				gspca_frame_add(gspca_dev, FIRST_PACKET,
-						frame, data, len);
+						data, len);
 				return;
 			}
 		}
@@ -1068,15 +1067,21 @@
 	if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
 		/* In raw mode we sometimes get some garbage after the frame
 		   ignore this */
-		int used = frame->data_end - frame->data;
+		struct gspca_frame *frame;
+		int used;
 		int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
 
+		frame = gspca_get_i_frame(gspca_dev);
+		if (frame == NULL) {
+			gspca_dev->last_packet_type = DISCARD_PACKET;
+			return;
+		}
+		used = frame->data_end - frame->data;
 		if (used + len > size)
 			len = size - used;
 	}
 
-	gspca_frame_add(gspca_dev, INTER_PACKET,
-			frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 33f4d0a..0bd36a0 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -1,8 +1,8 @@
 /*
- *		Sonix sn9c102p sn9c105 sn9c120 (jpeg) library
- *		Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
+ * Sonix sn9c102p sn9c105 sn9c120 (jpeg) subdriver
  *
- * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ * Copyright (C) 2009 Jean-Francois Moine <http://moinejf.free.fr>
+ * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
  *
  * 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
@@ -72,8 +72,9 @@
 #define SENSOR_OV7630 5
 #define SENSOR_OV7648 6
 #define SENSOR_OV7660 7
-#define SENSOR_SP80708 8
-	u8 i2c_base;
+#define SENSOR_PO1030 8
+#define SENSOR_SP80708 9
+	u8 i2c_addr;
 
 	u8 *jpeg_hdr;
 };
@@ -250,7 +251,7 @@
 		.minimum = 0,
 		.maximum = 2,	/* 0: 0, 1: 50Hz, 2:60Hz */
 		.step    = 1,
-#define FREQ_DEF 2
+#define FREQ_DEF 1
 		.default_value = FREQ_DEF,
 	    },
 	    .set = sd_setfreq,
@@ -277,7 +278,9 @@
 	(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
 						/* SENSOR_OV7660 7 */
 	(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) |
-			      (1 << FREQ_IDX),	/* SENSOR_SP80708 8 */
+			      (1 << FREQ_IDX),	/* SENSOR_PO1030 8 */
+	(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) |
+			      (1 << FREQ_IDX),	/* SENSOR_SP80708 9 */
 };
 
 static const struct v4l2_pix_format vga_mode[] = {
@@ -304,7 +307,7 @@
 /*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
 	0x00,	0x03,	0x64,	0x00,	0x1a,	0x20,	0x20,	0x20,
 /*	reg8	reg9	rega	regb	regc	regd	rege	regf */
-	0xa1,	0x11,	0x02,	0x09,	0x00,	0x00,	0x00,	0x10,
+	0x81,	0x11,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
 /*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
 	0x03,	0x00,	0x00,	0x01,	0x03,	0x28,	0x1e,	0x41,
 /*	reg18	reg19	reg1a	reg1b */
@@ -315,7 +318,7 @@
 /*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
 	0x00,	0x61,	0x44,	0x00,	0x1a,	0x20,	0x20,	0x20,
 /*	reg8	reg9	rega	regb	regc	regd	rege	regf */
-	0xb1,	0x5d,	0x07,	0x00,	0x00,	0x00,	0x00,	0x10,
+	0x81,	0x5d,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
 /*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
 	0x03,	0x00,	0x00,	0x02,	0x0a,	0x28,	0x1e,	0x61,
 /*	reg18	reg19	reg1a	reg1b */
@@ -337,7 +340,7 @@
 /*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
 	0x00,	0x61,	0x40,	0x00,	0x1a,	0x20,	0x20,	0x20,
 /*	reg8	reg9	rega	regb	regc	regd	rege	regf */
-	0x81,	0x5c,	0x07,	0x00,	0x00,	0x00,	0x00,	0x00,
+	0x81,	0x5c,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
 /*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
 	0x03,	0x00,	0x00,	0x02,	0x1c,	0x28,	0x1e,	0x40,
 /*	reg18	reg19	reg1a	reg1b */
@@ -346,7 +349,7 @@
 
 static const u8 sn_om6802[0x1c] = {
 /*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
-	0x00,	0x23,	0x72,	0x00,	0x1a,	0x34,	0x27,	0x20,
+	0x00,	0x23,	0x72,	0x00,	0x1a,	0x20,	0x20,	0x19,
 /*	reg8	reg9	rega	regb	regc	regd	rege	regf */
 	0x80,	0x34,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
 /*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
@@ -359,7 +362,7 @@
 /*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
 	0x00,	0x21,	0x40,	0x00,	0x1a,	0x20,	0x1f,	0x20,
 /*	reg8	reg9	rega	regb	regc	regd	rege	regf */
-	0xa1,	0x21,	0x76,	0x21,	0x00,	0x00,	0x00,	0x10,
+	0x81,	0x21,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
 /*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
 	0x03,	0x00,	0x04,	0x01,	0x0a,	0x28,	0x1e,	0xc2,
 /*	reg18	reg19	reg1a	reg1b */
@@ -370,7 +373,7 @@
 /*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
 	0x00,	0x63,	0x40,	0x00,	0x1a,	0x20,	0x20,	0x20,
 /*	reg8	reg9	rega	regb	regc	regd	rege	regf */
-	0x81,	0x21,	0x00,	0x00,	0x00,	0x00,	0x00,	0x10,
+	0x81,	0x21,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
 /*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
 	0x03,	0x00,	0x00,	0x01,	0x00,	0x28,	0x1e,	0x00,
 /*	reg18	reg19	reg1a	reg1b */
@@ -388,11 +391,22 @@
 	0x07,	0x00,	0x00,	0x00
 };
 
+static const u8 sn_po1030[0x1c] = {
+/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
+	0x00,	0x21,	0x62,	0x00,	0x1a,	0x20,	0x20,	0x20,
+/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
+	0x81,	0x6e,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
+/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
+	0x03,	0x00,	0x00,	0x06,	0x06,	0x28,	0x1e,	0x00,
+/*	reg18	reg19	reg1a	reg1b */
+	0x07,	0x00,	0x00,	0x00
+};
+
 static const u8 sn_sp80708[0x1c] = {
 /*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
 	0x00,	0x63,	0x60,	0x00,	0x1a,	0x20,	0x20,	0x20,
 /*	reg8	reg9	rega	regb	regc	regd	rege	regf */
-	0x81,	0x18,	0x07,	0x00,	0x00,	0x00,	0x00,	0x00,
+	0x81,	0x18,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
 /*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
 	0x03,	0x00,	0x00,	0x03,	0x04,	0x28,	0x1e,	0x00,
 /*	reg18	reg19	reg1a	reg1b */
@@ -409,6 +423,7 @@
 	sn_ov7630,
 	sn_ov7648,
 	sn_ov7660,
+	sn_po1030,
 	sn_sp80708
 };
 
@@ -455,7 +470,7 @@
 
 	{0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
-	{0xa1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
 
@@ -464,6 +479,8 @@
 	{0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10},
+							/* set sensor clock */
 	{}
 };
 static const u8 mi0360_sensor_init[][8] = {
@@ -545,7 +562,7 @@
 };
 static const u8 mt9v111_sensor_init[][8] = {
 	{0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
-	/* delay 20 ms */
+	{0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
 	{0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
 	{0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
 	{0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
@@ -572,7 +589,9 @@
 	{0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
 	{0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
 	{0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
-	/*******/
+	{}
+};
+static const u8 mt9v111_sensor_param1[][8] = {
 	{0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
 	{0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
 	{0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10},
@@ -585,14 +604,20 @@
 	{0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
 	{}
 };
+static const u8 om6802_init0[2][8] = {
+/*fixme: variable*/
+	{0xa0, 0x34, 0x29, 0x0e, 0x00, 0x00, 0x00, 0x10},
+	{0xa0, 0x34, 0x23, 0xb0, 0x00, 0x00, 0x00, 0x10},
+};
 static const u8 om6802_sensor_init[][8] = {
-	{0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
-	{0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
-	{0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
+	{0xa0, 0x34, 0xdf, 0x6d, 0x00, 0x00, 0x00, 0x10},
+						/* factory mode */
 	{0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
+						/* output raw RGB */
+	{0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
 /*	{0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
 	{0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
-					/* white balance & auto-exposure */
+		/* auto-exposure speed (0) / white balance mode (auto RGB) */
 /*	{0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
 							 * set color mode */
 /*	{0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
@@ -606,26 +631,29 @@
 /*	{0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
 							 * preset gamma */
 	{0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
-					/* luminance mode (0x4f = AE) */
+				/* luminance mode (0x4f -> AutoExpo on) */
 	{0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
 							/* preset shutter */
 /*	{0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
 							 * auto frame rate */
 /*	{0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
-
-/*	{0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
-/*	{0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
-/*	{0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
-/*	{0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
+	{0xa0, 0x34, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
+	{}
+};
+static const u8 om6802_sensor_param1[][8] = {
+	{0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10},
+	{0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10},
+	{0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10},
+	{0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10},
 	{}
 };
 static const u8 ov7630_sensor_init[][8] = {
 	{0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
-/* win: delay 20ms */
+	{0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
 	{0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
-/* win: delay 20ms */
+	{0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
 	{0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
 /* win: i2c_r from 00 to 80 */
 	{0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
@@ -677,6 +705,7 @@
 static const u8 ov7648_sensor_init[][8] = {
 	{0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},	/* reset */
+	{0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
 	{0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
 	{0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
 	{0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
@@ -701,7 +730,9 @@
 /*	{0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
 /*	{0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
 /*	{0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */
-/*...*/
+	{}
+};
+static const u8 ov7648_sensor_param1[][8] = {
 /*	{0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
 /*	{0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10},   * COMN
 							 * set by setvflip */
@@ -723,7 +754,7 @@
 
 static const u8 ov7660_sensor_init[][8] = {
 	{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
-/*		(delay 20ms) */
+	{0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
 	{0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
 						/* Outformat = rawRGB */
 	{0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
@@ -783,8 +814,11 @@
 	{0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
 	{0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
 	{0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
+/* not in all ms-win traces*/
 	{0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
-/****** (some exchanges in the win trace) ******/
+	{}
+};
+static const u8 ov7660_sensor_param1[][8] = {
 	{0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
 						/* bits[3..0]reserved */
 	{0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
@@ -797,6 +831,7 @@
 	{0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
 /*	{0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
 /****** (some exchanges in the win trace) ******/
+/*fixme:param2*/
 	{0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
 	{0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
 	{0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
@@ -804,6 +839,7 @@
 /*	{0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10},  * RED */
 /****** (some exchanges in the win trace) ******/
 /******!! startsensor KO if changed !!****/
+/*fixme: param3*/
 	{0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
@@ -811,6 +847,60 @@
 	{}
 };
 
+static const u8 po1030_sensor_init[][8] = {
+/* the sensor registers are described in m5602/m5602_po1030.h */
+	{0xa1, 0x6e, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x10}, /* sensor reset */
+	{0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
+	{0xa1, 0x6e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x6e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x6e, 0x04, 0x02, 0xb1, 0x02, 0x39, 0x10},
+	{0xd1, 0x6e, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
+	{0xd1, 0x6e, 0x0c, 0x02, 0x7f, 0x01, 0xe0, 0x10},
+	{0xd1, 0x6e, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
+	{0xd1, 0x6e, 0x16, 0x85, 0x40, 0x4a, 0x40, 0x10}, /* r/g1/b/g2 gains */
+	{0xc1, 0x6e, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10},
+	{0xd1, 0x6e, 0x1d, 0x08, 0x03, 0x00, 0x00, 0x10},
+	{0xd1, 0x6e, 0x23, 0x00, 0xb0, 0x00, 0x94, 0x10},
+	{0xd1, 0x6e, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
+	{0xb1, 0x6e, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x6e, 0x2d, 0x14, 0x35, 0x61, 0x84, 0x10}, /* gamma corr */
+	{0xd1, 0x6e, 0x31, 0xa2, 0xbd, 0xd8, 0xff, 0x10},
+	{0xd1, 0x6e, 0x35, 0x06, 0x1e, 0x12, 0x02, 0x10}, /* color matrix */
+	{0xd1, 0x6e, 0x39, 0xaa, 0x53, 0x37, 0xd5, 0x10},
+	{0xa1, 0x6e, 0x3d, 0xf2, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x6e, 0x3e, 0x00, 0x00, 0x80, 0x03, 0x10},
+	{0xd1, 0x6e, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
+	{0xc1, 0x6e, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
+	{0xd1, 0x6e, 0x4b, 0x02, 0xef, 0x08, 0xcd, 0x10},
+	{0xd1, 0x6e, 0x4f, 0x00, 0xd0, 0x00, 0xa0, 0x10},
+	{0xd1, 0x6e, 0x53, 0x01, 0xaa, 0x01, 0x40, 0x10},
+	{0xd1, 0x6e, 0x5a, 0x50, 0x04, 0x30, 0x03, 0x10}, /* raw rgb bayer */
+	{0xa1, 0x6e, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x6e, 0x5f, 0x10, 0x40, 0xff, 0x00, 0x10},
+
+	{0xd1, 0x6e, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
+	{0xd1, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x6e, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x6e, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xc1, 0x6e, 0x73, 0x10, 0x80, 0xeb, 0x00, 0x10},
+	{}
+};
+static const u8 po1030_sensor_param1[][8] = {
+/* from ms-win traces - these values change with auto gain/expo/wb.. */
+	{0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
+/* mean values */
+	{0xc1, 0x6e, 0x1a, 0x02, 0xd4, 0xa4, 0x00, 0x10}, /* integlines */
+	{0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, /* global gain */
+	{0xc1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10}, /* r/g1/b gains */
+
+	{0xa1, 0x6e, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x10}, /* control1 */
+	{0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, /* frameheight */
+	{0xa1, 0x6e, 0x07, 0xd5, 0x00, 0x00, 0x00, 0x10},
+/*	{0xc1, 0x6e, 0x16, 0x49, 0x40, 0x45, 0x00, 0x10}, */
+	{}
+};
+
 static const u8 sp80708_sensor_init[][8] = {
 	{0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
@@ -883,7 +973,9 @@
 	{0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
-	/********/
+	{}
+};
+static const u8 sp80708_sensor_param1[][8] = {
 	{0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
@@ -894,6 +986,19 @@
 	{}
 };
 
+static const u8 (*sensor_init[10])[8] = {
+	hv7131r_sensor_init,	/* HV7131R 0 */
+	mi0360_sensor_init,	/* MI0360 1 */
+	mo4000_sensor_init,	/* MO4000 2 */
+	mt9v111_sensor_init,	/* MT9V111 3 */
+	om6802_sensor_init,	/* OM6802 4 */
+	ov7630_sensor_init,	/* OV7630 5 */
+	ov7648_sensor_init,	/* OV7648 6 */
+	ov7660_sensor_init,	/* OV7660 7 */
+	po1030_sensor_init,	/* PO1030 8 */
+	sp80708_sensor_init,	/* SP80708 9 */
+};
+
 /* read <len> bytes to gspca_dev->usb_buf */
 static void reg_r(struct gspca_dev *gspca_dev,
 		  u16 value, int len)
@@ -958,8 +1063,15 @@
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
-	gspca_dev->usb_buf[0] = 0x81 | (2 << 4);	/* = a1 */
-	gspca_dev->usb_buf[1] = sd->i2c_base;
+	switch (sd->sensor) {
+	case SENSOR_OM6802:		/* i2c command = a0 (100 kHz) */
+		gspca_dev->usb_buf[0] = 0x80 | (2 << 4);
+		break;
+	default:			/* i2c command = a1 (400 kHz) */
+		gspca_dev->usb_buf[0] = 0x81 | (2 << 4);
+		break;
+	}
+	gspca_dev->usb_buf[1] = sd->i2c_addr;
 	gspca_dev->usb_buf[2] = reg;
 	gspca_dev->usb_buf[3] = val;
 	gspca_dev->usb_buf[4] = 0;
@@ -991,14 +1103,21 @@
 	msleep(2);
 }
 
-/* read 5 bytes in gspca_dev->usb_buf */
-static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg)
+/* sensor read 'len' (1..5) bytes in gspca_dev->usb_buf */
+static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	u8 mode[8];
 
-	mode[0] = 0x81 | 0x10;
-	mode[1] = sd->i2c_base;
+	switch (sd->sensor) {
+	case SENSOR_OM6802:		/* i2c command = 90 (100 kHz) */
+		mode[0] = 0x80 | 0x10;
+		break;
+	default:			/* i2c command = 91 (400 kHz) */
+		mode[0] = 0x81 | 0x10;
+		break;
+	}
+	mode[1] = sd->i2c_addr;
 	mode[2] = reg;
 	mode[3] = 0;
 	mode[4] = 0;
@@ -1007,33 +1126,43 @@
 	mode[7] = 0x10;
 	i2c_w8(gspca_dev, mode);
 	msleep(2);
-	mode[0] = 0x81 | (5 << 4) | 0x02;
+	mode[0] = (mode[0] & 0x81) | (len << 4) | 0x02;
 	mode[2] = 0;
 	i2c_w8(gspca_dev, mode);
 	msleep(2);
 	reg_r(gspca_dev, 0x0a, 5);
 }
 
-static int hv7131r_probe(struct gspca_dev *gspca_dev)
+static void i2c_w_seq(struct gspca_dev *gspca_dev,
+			const u8 (*data)[8])
+{
+	while ((*data)[0] != 0) {
+		if ((*data)[0] != 0xdd)
+			i2c_w8(gspca_dev, *data);
+		else
+			msleep((*data)[1]);
+		data++;
+	}
+}
+
+static void hv7131r_probe(struct gspca_dev *gspca_dev)
 {
 	i2c_w1(gspca_dev, 0x02, 0);			/* sensor wakeup */
 	msleep(10);
 	reg_w1(gspca_dev, 0x02, 0x66);			/* Gpio on */
 	msleep(10);
-	i2c_r5(gspca_dev, 0);				/* read sensor id */
+	i2c_r(gspca_dev, 0, 5);				/* read sensor id */
 	if (gspca_dev->usb_buf[0] == 0x02
 	    && gspca_dev->usb_buf[1] == 0x09
 	    && gspca_dev->usb_buf[2] == 0x01
 	    && gspca_dev->usb_buf[3] == 0x00
 	    && gspca_dev->usb_buf[4] == 0x00) {
-		PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
-		return 0;
+		PDEBUG(D_PROBE, "Sensor sn9c102P HV7131R found");
+		return;
 	}
-	PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
+	PDEBUG(D_PROBE, "Sensor 0x%02x 0x%02x 0x%02x - sn9c102P not found",
 		gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
 		gspca_dev->usb_buf[2]);
-	PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
-	return -ENODEV;
 }
 
 static void mi0360_probe(struct gspca_dev *gspca_dev)
@@ -1075,7 +1204,6 @@
 	case 0x823a:
 		PDEBUG(D_PROBE, "Sensor mt9v111");
 		sd->sensor = SENSOR_MT9V111;
-		sd->i2c_base = 0x5c;
 		break;
 	case 0x8243:
 		PDEBUG(D_PROBE, "Sensor mi0360");
@@ -1086,7 +1214,42 @@
 	}
 }
 
-static int configure_gpio(struct gspca_dev *gspca_dev,
+static void ov7648_probe(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	/* check ov76xx */
+	reg_w1(gspca_dev, 0x17, 0x62);
+	reg_w1(gspca_dev, 0x01, 0x08);
+	sd->i2c_addr = 0x21;
+	i2c_r(gspca_dev, 0x0a, 2);
+	if (gspca_dev->usb_buf[3] == 0x76) {	/* ov76xx */
+		PDEBUG(D_PROBE, "Sensor ov%02x%02x",
+			gspca_dev->usb_buf[3], gspca_dev->usb_buf[4]);
+		return;
+	}
+
+	/* reset */
+	reg_w1(gspca_dev, 0x01, 0x29);
+	reg_w1(gspca_dev, 0x17, 0x42);
+
+	/* check po1030 */
+	reg_w1(gspca_dev, 0x17, 0x62);
+	reg_w1(gspca_dev, 0x01, 0x08);
+	sd->i2c_addr = 0x6e;
+	i2c_r(gspca_dev, 0x00, 2);
+	if (gspca_dev->usb_buf[3] == 0x10	/* po1030 */
+	    && gspca_dev->usb_buf[4] == 0x30) {
+		PDEBUG(D_PROBE, "Sensor po1030");
+		sd->sensor = SENSOR_PO1030;
+		return;
+	}
+
+	PDEBUG(D_PROBE, "Unknown sensor %02x%02x",
+		gspca_dev->usb_buf[3], gspca_dev->usb_buf[4]);
+}
+
+static void bridge_init(struct gspca_dev *gspca_dev,
 			  const u8 *sn9c1xx)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -1103,9 +1266,10 @@
 	/* configure gpio */
 	reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
 	reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
-	reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);	/* jfm len was 3 */
+	reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
 	switch (sd->sensor) {
 	case SENSOR_OV7660:
+	case SENSOR_PO1030:
 	case SENSOR_SP80708:
 		reg9a = reg9a_spec;
 		break;
@@ -1115,7 +1279,7 @@
 	}
 	reg_w(gspca_dev, 0x9a, reg9a, 6);
 
-	reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
+	reg_w(gspca_dev, 0xd4, regd4, sizeof regd4);
 
 	reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
 
@@ -1127,10 +1291,22 @@
 		reg_w1(gspca_dev, 0x01, 0x40);
 		break;
 	case SENSOR_OM6802:
-		reg_w1(gspca_dev, 0x02, 0x71);
-		reg_w1(gspca_dev, 0x01, 0x42);
+		msleep(10);
+		reg_w1(gspca_dev, 0x02, 0x73);
+		reg_w1(gspca_dev, 0x17, 0x60);
+		reg_w1(gspca_dev, 0x01, 0x22);
+		msleep(100);
+		reg_w1(gspca_dev, 0x01, 0x62);
+		reg_w1(gspca_dev, 0x17, 0x64);
 		reg_w1(gspca_dev, 0x17, 0x64);
 		reg_w1(gspca_dev, 0x01, 0x42);
+		msleep(10);
+		reg_w1(gspca_dev, 0x01, 0x42);
+		i2c_w8(gspca_dev, om6802_init0[0]);
+		i2c_w8(gspca_dev, om6802_init0[1]);
+		msleep(15);
+		reg_w1(gspca_dev, 0x02, 0x71);
+		msleep(150);
 		break;
 	case SENSOR_OV7630:
 		reg_w1(gspca_dev, 0x01, 0x61);
@@ -1144,7 +1320,14 @@
 		reg_w1(gspca_dev, 0x01, 0x62);
 		reg_w1(gspca_dev, 0x01, 0x42);
 		break;
+	case SENSOR_PO1030:
+		reg_w1(gspca_dev, 0x01, 0x61);
+		reg_w1(gspca_dev, 0x17, 0x20);
+		reg_w1(gspca_dev, 0x01, 0x60);
+		reg_w1(gspca_dev, 0x01, 0x40);
+		break;
 	case SENSOR_OV7660:
+		/* fall thru */
 	case SENSOR_SP80708:
 		reg_w1(gspca_dev, 0x01, 0x63);
 		reg_w1(gspca_dev, 0x17, 0x20);
@@ -1153,143 +1336,18 @@
 		msleep(100);
 		reg_w1(gspca_dev, 0x02, 0x62);
 		break;
+	default:
 /*	case SENSOR_HV7131R: */
 /*	case SENSOR_MI0360: */
 /*	case SENSOR_MO4000: */
-	default:
 		reg_w1(gspca_dev, 0x01, 0x43);
 		reg_w1(gspca_dev, 0x17, 0x61);
 		reg_w1(gspca_dev, 0x01, 0x42);
-		if (sd->sensor == SENSOR_HV7131R) {
-			if (hv7131r_probe(gspca_dev) < 0)
-				return -ENODEV;
-		}
+		if (sd->sensor == SENSOR_HV7131R
+		    && sd->bridge == BRIDGE_SN9C102P)
+			hv7131r_probe(gspca_dev);
 		break;
 	}
-	return 0;
-}
-
-static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
-{
-	int i = 0;
-	static const u8 SetSensorClk[] =	/* 0x08 Mclk */
-		{ 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
-
-	while (hv7131r_sensor_init[i][0]) {
-		i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
-		i++;
-	}
-	i2c_w8(gspca_dev, SetSensorClk);
-}
-
-static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
-{
-	int i = 0;
-
-	while (mi0360_sensor_init[i][0]) {
-		i2c_w8(gspca_dev, mi0360_sensor_init[i]);
-		i++;
-	}
-}
-
-static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
-{
-	int i = 0;
-
-	while (mo4000_sensor_init[i][0]) {
-		i2c_w8(gspca_dev, mo4000_sensor_init[i]);
-		i++;
-	}
-}
-
-static void mt9v111_InitSensor(struct gspca_dev *gspca_dev)
-{
-	int i = 0;
-
-	i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
-	i++;
-	msleep(20);
-	while (mt9v111_sensor_init[i][0]) {
-		i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
-		i++;
-	}
-}
-
-static void om6802_InitSensor(struct gspca_dev *gspca_dev)
-{
-	int i = 0;
-
-	while (om6802_sensor_init[i][0]) {
-		i2c_w8(gspca_dev, om6802_sensor_init[i]);
-		i++;
-	}
-}
-
-static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
-{
-	int i = 0;
-
-	i2c_w8(gspca_dev, ov7630_sensor_init[i]);	/* 76 01 */
-	i++;
-	i2c_w8(gspca_dev, ov7630_sensor_init[i]);	/* 12 c8 (RGB+SRST) */
-	i++;
-	msleep(20);
-	i2c_w8(gspca_dev, ov7630_sensor_init[i]);	/* 12 48 */
-	i++;
-	i2c_w8(gspca_dev, ov7630_sensor_init[i]);	/* 12 c8 */
-	i++;
-	msleep(20);
-	i2c_w8(gspca_dev, ov7630_sensor_init[i]);	/* 12 48 */
-	i++;
-/*jfm:win i2c_r from 00 to 80*/
-
-	while (ov7630_sensor_init[i][0]) {
-		i2c_w8(gspca_dev, ov7630_sensor_init[i]);
-		i++;
-	}
-}
-
-static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
-{
-	int i = 0;
-
-	i2c_w8(gspca_dev, ov7648_sensor_init[i]);
-	i++;
-/* win: dble reset */
-	i2c_w8(gspca_dev, ov7648_sensor_init[i]);	/* reset */
-	i++;
-	msleep(20);
-/* win: i2c reg read 00..7f */
-	while (ov7648_sensor_init[i][0]) {
-		i2c_w8(gspca_dev, ov7648_sensor_init[i]);
-		i++;
-	}
-}
-
-static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
-{
-	int i = 0;
-
-	i2c_w8(gspca_dev, ov7660_sensor_init[i]);	/* reset SCCB */
-	i++;
-	msleep(20);
-	while (ov7660_sensor_init[i][0]) {
-		i2c_w8(gspca_dev, ov7660_sensor_init[i]);
-		i++;
-	}
-}
-
-static void sp80708_InitSensor(struct gspca_dev *gspca_dev)
-{
-	int i = 0;
-
-	i2c_w8(gspca_dev, sp80708_sensor_init[i]);	/* reset SCCB */
-	i++;
-	msleep(20);
-	while (sp80708_sensor_init[i][0]) {
-		i2c_w8(gspca_dev, sp80708_sensor_init[i]);
-		i++;
-	}
 }
 
 /* this function is called at probe time */
@@ -1305,8 +1363,7 @@
 	cam->npkt = 24;			/* 24 packets per ISOC message */
 
 	sd->bridge = id->driver_info >> 16;
-	sd->sensor = id->driver_info >> 8;
-	sd->i2c_base = id->driver_info;
+	sd->sensor = id->driver_info;
 
 	sd->brightness = BRIGHTNESS_DEF;
 	sd->contrast = CONTRAST_DEF;
@@ -1322,7 +1379,6 @@
 	sd->quality = QUALITY_DEF;
 	sd->jpegqual = 80;
 
-	gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
 	return 0;
 }
 
@@ -1330,6 +1386,7 @@
 static int sd_init(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	const u8 *sn9c1xx;
 	u8 regGpio[] = { 0x29, 0x74 };
 	u8 regF1;
 
@@ -1356,8 +1413,14 @@
 	case BRIDGE_SN9C120:
 		if (regF1 != 0x12)
 			return -ENODEV;
-		if (sd->sensor == SENSOR_MI0360)
+		switch (sd->sensor) {
+		case SENSOR_MI0360:
 			mi0360_probe(gspca_dev);
+			break;
+		case SENSOR_OV7648:
+			ov7648_probe(gspca_dev);
+			break;
+		}
 		regGpio[1] = 0x70;
 		reg_w(gspca_dev, 0x01, regGpio, 2);
 		break;
@@ -1372,6 +1435,12 @@
 
 	reg_w1(gspca_dev, 0xf1, 0x01);
 
+	/* set the i2c address */
+	sn9c1xx = sn_tb[sd->sensor];
+	sd->i2c_addr = sn9c1xx[9];
+
+	gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
+
 	return 0;
 }
 
@@ -1383,7 +1452,7 @@
 	switch (sd->sensor) {
 	case SENSOR_HV7131R: {
 		u8 Expodoit[] =
-			{ 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
+			{ 0xc1, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16 };
 
 		Expodoit[3] = expo >> 16;
 		Expodoit[4] = expo >> 8;
@@ -1393,7 +1462,7 @@
 	    }
 	case SENSOR_MI0360: {
 		u8 expoMi[] =		/* exposure 0x0635 -> 4 fp/s 0x10 */
-			{ 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
+			{ 0xb1, 0x5d, 0x09, 0x00, 0x00, 0x00, 0x00, 0x16 };
 		static const u8 doit[] =		/* update sensor */
 			{ 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
 		static const u8 sensorgo[] =		/* sensor on */
@@ -1412,9 +1481,9 @@
 	    }
 	case SENSOR_MO4000: {
 		u8 expoMof[] =
-			{ 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
+			{ 0xa1, 0x21, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x10 };
 		u8 expoMo10[] =
-			{ 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
+			{ 0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10 };
 		static const u8 gainMo[] =
 			{ 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
 
@@ -1450,6 +1519,7 @@
 	case SENSOR_OM6802: {
 		u8 gainOm[] =
 			{ 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
+				/* preset AGC - works when AutoExpo = off */
 
 		if (expo > 0x03ff)
 			expo = 0x03ff;
@@ -1457,7 +1527,7 @@
 			expo = 0x0001;
 		gainOm[3] = expo >> 2;
 		i2c_w8(gspca_dev, gainOm);
-		reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
+		reg_w1(gspca_dev, 0x96, expo >> 5);
 		PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
 		break;
 	    }
@@ -1489,7 +1559,7 @@
 	case SENSOR_MT9V111:
 		expo = sd->brightness >> 8;
 		sd->exposure = setexposure(gspca_dev, expo);
-		break;
+		return;			/* don't set the Y offset */
 	case SENSOR_OM6802:
 		expo = sd->brightness >> 6;
 		sd->exposure = setexposure(gspca_dev, expo);
@@ -1497,8 +1567,7 @@
 		break;
 	}
 
-	if (sd->sensor != SENSOR_MT9V111)
-		reg_w1(gspca_dev, 0x96, k2);	/* color matrix Y offset */
+	reg_w1(gspca_dev, 0x96, k2);	/* color matrix Y offset */
 }
 
 static void setcontrast(struct gspca_dev *gspca_dev)
@@ -1526,6 +1595,7 @@
 		-24, -38, 64,		/* UR UG UB */
 		 62, -51, -9		/* VR VG VB */
 	};
+
 	for (i = 0; i < 6; i++) {
 		v = uv[i] * sd->colors / COLOR_DEF;
 		reg8a[i * 2] = v;
@@ -1605,6 +1675,8 @@
 {
 	u8 comn;
 
+	if (sd->gspca_dev.ctrl_dis & (1 << VFLIP_IDX))
+		return;
 	if (sd->sensor == SENSOR_OV7630) {
 		comn = 0x02;
 		if (!sd->vflip)
@@ -1726,8 +1798,9 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int i;
-	u8 reg1, reg17;
+	u8 reg1, reg2, reg17;
 	const u8 *sn9c1xx;
+	const u8 (*init)[8];
 	int mode;
 	static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
 	static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
@@ -1743,8 +1816,26 @@
 			0x21);		/* JPEG 422 */
 	jpeg_set_qual(sd->jpeg_hdr, sd->quality);
 
-	sn9c1xx = sn_tb[(int) sd->sensor];
-	configure_gpio(gspca_dev, sn9c1xx);
+	/* initialize the bridge */
+	sn9c1xx = sn_tb[sd->sensor];
+	bridge_init(gspca_dev, sn9c1xx);
+
+	/* initialize the sensor */
+	i2c_w_seq(gspca_dev, sensor_init[sd->sensor]);
+
+	switch (sd->sensor) {
+	case SENSOR_OM6802:
+		reg2 = 0x71;
+		break;
+	case SENSOR_SP80708:
+		reg2 = 0x62;
+		break;
+	default:
+		reg2 = 0x40;
+		break;
+	}
+	reg_w1(gspca_dev, 0x02, reg2);
+	reg_w1(gspca_dev, 0x02, reg2);
 
 	reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
 	reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
@@ -1771,6 +1862,9 @@
 	case SENSOR_OV7660:
 		reg17 = 0xa0;
 		break;
+	case SENSOR_PO1030:
+		reg17 = 0xa0;
+		break;
 	default:
 		reg17 = 0x60;
 		break;
@@ -1791,6 +1885,10 @@
 		reg_w1(gspca_dev, 0x9a, 0x07);
 		reg_w1(gspca_dev, 0x99, 0x59);
 		break;
+	case SENSOR_OM6802:
+		reg_w1(gspca_dev, 0x9a, 0x08);
+		reg_w1(gspca_dev, 0x99, 0x10);
+		break;
 	case SENSOR_OV7648:
 		reg_w1(gspca_dev, 0x9a, 0x0a);
 		reg_w1(gspca_dev, 0x99, 0x60);
@@ -1806,21 +1904,20 @@
 		break;
 	}
 
-	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
+	reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
+	reg_w1(gspca_dev, 0x05, sn9c1xx[5]);	/* red */
+	reg_w1(gspca_dev, 0x07, sn9c1xx[7]);	/* green */
+	reg_w1(gspca_dev, 0x06, sn9c1xx[6]);	/* blue */
+
+	init = NULL;
+	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
 	if (mode)
 		reg1 = 0x46;	/* 320x240: clk 48Mhz, video trf enable */
 	else
 		reg1 = 0x06;	/* 640x480: clk 24Mhz, video trf enable */
 	reg17 = 0x61;		/* 0x:20: enable sensor clock */
 	switch (sd->sensor) {
-	case SENSOR_HV7131R:
-		hv7131R_InitSensor(gspca_dev);
-		break;
-	case SENSOR_MI0360:
-		mi0360_InitSensor(gspca_dev);
-		break;
 	case SENSOR_MO4000:
-		mo4000_InitSensor(gspca_dev);
 		if (mode) {
 /*			reg1 = 0x46;	 * 320 clk 48Mhz 60fp/s */
 			reg1 = 0x06;	/* clk 24Mz */
@@ -1830,7 +1927,7 @@
 		}
 		break;
 	case SENSOR_MT9V111:
-		mt9v111_InitSensor(gspca_dev);
+		init = mt9v111_sensor_param1;
 		if (mode) {
 			reg1 = 0x04;	/* 320 clk 48Mhz */
 		} else {
@@ -1839,22 +1936,21 @@
 		}
 		break;
 	case SENSOR_OM6802:
-		om6802_InitSensor(gspca_dev);
+		init = om6802_sensor_param1;
 		reg17 = 0x64;		/* 640 MCKSIZE */
 		break;
 	case SENSOR_OV7630:
-		ov7630_InitSensor(gspca_dev);
 		setvflip(sd);
 		reg17 = 0xe2;
 		reg1 = 0x44;
 		break;
 	case SENSOR_OV7648:
-		ov7648_InitSensor(gspca_dev);
+		init = ov7648_sensor_param1;
 		reg17 = 0x21;
 /*		reg1 = 0x42;		 * 42 - 46? */
 		break;
 	case SENSOR_OV7660:
-		ov7660_InitSensor(gspca_dev);
+		init = ov7660_sensor_param1;
 		if (sd->bridge == BRIDGE_SN9C120) {
 			if (mode) {		/* 320x240 - 160x120 */
 				reg17 = 0xa2;
@@ -1866,9 +1962,14 @@
 					 * inverse power down */
 		}
 		break;
+	case SENSOR_PO1030:
+		init = po1030_sensor_param1;
+		reg17 = 0xa2;
+		reg1 = 0x44;
+		break;
 	default:
 /*	case SENSOR_SP80708: */
-		sp80708_InitSensor(gspca_dev);
+		init = sp80708_sensor_param1;
 		if (mode) {
 /*??			reg1 = 0x04;	 * 320 clk 48Mhz */
 		} else {
@@ -1877,6 +1978,13 @@
 		}
 		break;
 	}
+
+	/* more sensor initialization - param1 */
+	if (init != NULL) {
+		i2c_w_seq(gspca_dev, init);
+/*		init = NULL; */
+	}
+
 	reg_w(gspca_dev, 0xc0, C0, 6);
 	reg_w(gspca_dev, 0xca, CA, 4);
 	switch (sd->sensor) {
@@ -1891,6 +1999,7 @@
 		break;
 	}
 
+
 	/* here change size mode 0 -> VGA; 1 -> CIF */
 	sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40;
 	reg_w1(gspca_dev, 0x18, sd->reg18);
@@ -1898,6 +2007,7 @@
 
 	reg_w1(gspca_dev, 0x17, reg17);
 	reg_w1(gspca_dev, 0x01, reg1);
+
 	switch (sd->sensor) {
 	case SENSOR_OV7630:
 		setvflip(sd);
@@ -1937,14 +2047,11 @@
 		/* fall thru */
 	case SENSOR_MT9V111:
 	case SENSOR_OV7630:
+	case SENSOR_PO1030:
 		data = 0x29;
 		break;
-	default:
-/*	case SENSOR_MO4000: */
-/*	case SENSOR_OV7660: */
-		break;
 	}
-	sn9c1xx = sn_tb[(int) sd->sensor];
+	sn9c1xx = sn_tb[sd->sensor];
 	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
 	reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
 	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
@@ -1987,11 +2094,19 @@
 			sd->exposure = setexposure(gspca_dev,
 					(unsigned int) (expotimes << 8));
 			break;
+		case SENSOR_OM6802:
+			expotimes = sd->exposure;
+			expotimes += (luma_mean - delta) >> 2;
+			if (expotimes < 0)
+				expotimes = 0;
+			sd->exposure = setexposure(gspca_dev,
+						   (unsigned int) expotimes);
+			setredblue(gspca_dev);
+			break;
 		default:
 /*		case SENSOR_MO4000: */
 /*		case SENSOR_MI0360: */
 /*		case SENSOR_MT9V111: */
-/*		case SENSOR_OM6802: */
 			expotimes = sd->exposure;
 			expotimes += (luma_mean - delta) >> 6;
 			if (expotimes < 0)
@@ -2007,7 +2122,6 @@
 /* scan the URB packets */
 /* This function is run at interrupt level. */
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
 			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
@@ -2019,7 +2133,7 @@
 
 		/* end of frame */
 		gspca_frame_add(gspca_dev, LAST_PACKET,
-				frame, data, sof + 2);
+				data, sof + 2);
 		if (sd->ag_cnt < 0)
 			return;
 /* w1 w2 w3 */
@@ -2042,10 +2156,10 @@
 	if (gspca_dev->last_packet_type == LAST_PACKET) {
 
 		/* put the JPEG 422 header */
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+		gspca_frame_add(gspca_dev, FIRST_PACKET,
 			sd->jpeg_hdr, JPEG_HDR_SZ);
 	}
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -2295,69 +2409,69 @@
 };
 
 /* -- module initialisation -- */
-#define BSI(bridge, sensor, i2c_addr) \
+#define BS(bridge, sensor) \
 	.driver_info = (BRIDGE_ ## bridge << 16) \
-			| (SENSOR_ ## sensor << 8) \
-			| (i2c_addr)
+			| SENSOR_ ## sensor
 static const __devinitdata struct usb_device_id device_table[] = {
 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
-	{USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
-	{USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
+	{USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)},
+	{USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)},
 #endif
-	{USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
-	{USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
-	{USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
-	{USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
-	{USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
-	{USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
-	{USB_DEVICE(0x06f8, 0x3008), BSI(SN9C105, OV7660, 0x21)},
-	{USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
-/* bw600.inf:
-	{USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
-/*	{USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
-/*	{USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
-	{USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
-/*	{USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
-	{USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
-/*	{USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6802, 0x??)}, */
-/*	{USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
-	{USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
-/*	{USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
-/*	{USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
-	{USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
+	{USB_DEVICE(0x045e, 0x00f5), BS(SN9C105, OV7660)},
+	{USB_DEVICE(0x045e, 0x00f7), BS(SN9C105, OV7660)},
+	{USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)},
+	{USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)},
+	{USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)},
+	{USB_DEVICE(0x06f8, 0x3004), BS(SN9C105, OV7660)},
+	{USB_DEVICE(0x06f8, 0x3008), BS(SN9C105, OV7660)},
+/*	{USB_DEVICE(0x0c45, 0x603a), BS(SN9C102P, OV7648)}, */
+	{USB_DEVICE(0x0c45, 0x6040), BS(SN9C102P, HV7131R)},
+/*	{USB_DEVICE(0x0c45, 0x607a), BS(SN9C102P, OV7648)}, */
+/*	{USB_DEVICE(0x0c45, 0x607b), BS(SN9C102P, OV7660)}, */
+	{USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)},
+/*	{USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */
+	{USB_DEVICE(0x0c45, 0x60c0), BS(SN9C105, MI0360)},
+/*	{USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
+/*	{USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
+/*	{USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */
+	{USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)},
+/*	{USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */
+/*	{USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */
+	{USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)},
 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
-	{USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
-	{USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
+	{USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)},
+	{USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)},
 #endif
-	{USB_DEVICE(0x0c45, 0x6100), BSI(SN9C120, MI0360, 0x5d)}, /*sn9c128*/
-/*	{USB_DEVICE(0x0c45, 0x6102), BSI(SN9C120, PO2030N, ??)}, */
-/*	{USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6802, 0x21)}, */
-	{USB_DEVICE(0x0c45, 0x610a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c128*/
-	{USB_DEVICE(0x0c45, 0x610b), BSI(SN9C120, OV7660, 0x21)}, /*sn9c128*/
-	{USB_DEVICE(0x0c45, 0x610c), BSI(SN9C120, HV7131R, 0x11)}, /*sn9c128*/
-	{USB_DEVICE(0x0c45, 0x610e), BSI(SN9C120, OV7630, 0x21)}, /*sn9c128*/
-/*	{USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
-/*	{USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
-	{USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
+	{USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)},	/*sn9c128*/
+/*	{USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, P1030xC)}, */
+/*	{USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */
+	{USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)},	/*sn9c128*/
+	{USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)},	/*sn9c128*/
+	{USB_DEVICE(0x0c45, 0x610c), BS(SN9C120, HV7131R)},	/*sn9c128*/
+	{USB_DEVICE(0x0c45, 0x610e), BS(SN9C120, OV7630)},	/*sn9c128*/
+/*	{USB_DEVICE(0x0c45, 0x610f), BS(SN9C120, S5K53BEB)}, */
+/*	{USB_DEVICE(0x0c45, 0x6122), BS(SN9C110, ICM105C)}, */
+/*	{USB_DEVICE(0x0c45, 0x6123), BS(SN9C110, SanyoCCD)}, */
+	{USB_DEVICE(0x0c45, 0x6128), BS(SN9C120, OM6802)},	/*sn9c325?*/
 /*bw600.inf:*/
-	{USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
-	{USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
-	{USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
-/*	{USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
+	{USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)},	/*sn9c325?*/
+	{USB_DEVICE(0x0c45, 0x612c), BS(SN9C110, MO4000)},
+	{USB_DEVICE(0x0c45, 0x612e), BS(SN9C110, OV7630)},
+/*	{USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */
 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
-	{USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
+	{USB_DEVICE(0x0c45, 0x6130), BS(SN9C120, MI0360)},
 #endif
-/*	{USB_DEVICE(0x0c45, 0x6132), BSI(SN9C120, OV7670, 0x21)}, */
-	{USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
-	{USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
+/*	{USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */
+	{USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)},
+	{USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)},
 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
-	{USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
+	{USB_DEVICE(0x0c45, 0x613b), BS(SN9C120, OV7660)},
 #endif
-	{USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
-	{USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x21)},
-/*	{USB_DEVICE(0x0c45, 0x6142), BSI(SN9C120, PO2030N, ??)}, *sn9c120b*/
-	{USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)}, /*sn9c120b*/
-	{USB_DEVICE(0x0c45, 0x6148), BSI(SN9C120, OM6802, 0x21)}, /*sn9c120b*/
+	{USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)},
+	{USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)},
+/*	{USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)},	 *sn9c120b*/
+	{USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)},	/*sn9c120b*/
+	{USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)},	/*sn9c120b*/
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
index fab7ef8..fe46868 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/video/gspca/spca500.c
@@ -589,7 +589,7 @@
 	int err;
 	__u8 Data;
 
-	/* some unknow command from Aiptek pocket dv and family300 */
+	/* some unknown command from Aiptek pocket dv and family300 */
 
 	reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
 	reg_w(gspca_dev, 0x00, 0x0d03, 0x00);
@@ -899,8 +899,7 @@
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -913,11 +912,11 @@
 /*			gspca_dev->last_packet_type = DISCARD_PACKET; */
 			return;
 		}
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+		gspca_frame_add(gspca_dev, LAST_PACKET,
 					ffd9, 2);
 
 		/* put the JPEG header in the new frame */
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+		gspca_frame_add(gspca_dev, FIRST_PACKET,
 			sd->jpeg_hdr, JPEG_HDR_SZ);
 
 		data += SPCA500_OFFSET_DATA;
@@ -931,7 +930,7 @@
 	i = 0;
 	do {
 		if (data[i] == 0xff) {
-			gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+			gspca_frame_add(gspca_dev, INTER_PACKET,
 					data, i + 1);
 			len -= i;
 			data += i;
@@ -940,7 +939,7 @@
 		}
 		i++;
 	} while (i < len);
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static void setbrightness(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c
index b74a342..6761a30 100644
--- a/drivers/media/video/gspca/spca501.c
+++ b/drivers/media/video/gspca/spca501.c
@@ -1636,7 +1636,7 @@
 	{}
 };
 
-/* Unknow camera from Ori Usbid 0x0000:0x0000 */
+/* Unknown camera from Ori Usbid 0x0000:0x0000 */
 /* Based on snoops from Ori Cohen */
 static const __u16 spca501c_mysterious_open_data[][3] = {
 	{0x02, 0x000f, 0x0005},
@@ -1945,7 +1945,7 @@
 			goto error;
 		break;
 	case MystFromOriUnknownCamera:
-		/* UnKnow Ori CMOS Camera data */
+		/* Unknown Ori CMOS Camera data */
 		if (write_vector(gspca_dev, spca501c_mysterious_open_data))
 			goto error;
 		break;
@@ -1978,7 +1978,7 @@
 		write_vector(gspca_dev, spca501c_arowana_open_data);
 		break;
 	case MystFromOriUnknownCamera:
-		/* UnKnow  CMOS Camera data */
+		/* Unknown CMOS Camera data */
 		write_vector(gspca_dev, spca501c_mysterious_init_data);
 		break;
 	default:
@@ -2032,20 +2032,15 @@
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	switch (data[0]) {
 	case 0:				/* start of frame */
-		frame = gspca_frame_add(gspca_dev,
-					LAST_PACKET,
-					frame,
-					data, 0);
+		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 		data += SPCA501_OFFSET_DATA;
 		len -= SPCA501_OFFSET_DATA;
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
-				data, len);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 		return;
 	case 0xff:			/* drop */
 /*		gspca_dev->last_packet_type = DISCARD_PACKET; */
@@ -2053,8 +2048,7 @@
 	}
 	data++;
 	len--;
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame,
-			data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
index ea8c9fe..0f9232f 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/video/gspca/spca505.c
@@ -739,26 +739,22 @@
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
 			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	switch (data[0]) {
 	case 0:				/* start of frame */
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-					data, 0);
+		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 		data += SPCA50X_OFFSET_DATA;
 		len -= SPCA50X_OFFSET_DATA;
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
-				data, len);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 		break;
 	case 0xff:			/* drop */
 		break;
 	default:
 		data += 1;
 		len -= 1;
-		gspca_frame_add(gspca_dev, INTER_PACKET, frame,
-				data, len);
+		gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 		break;
 	}
 }
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
index a199298..ab28cc2 100644
--- a/drivers/media/video/gspca/spca506.c
+++ b/drivers/media/video/gspca/spca506.c
@@ -543,18 +543,15 @@
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	switch (data[0]) {
 	case 0:				/* start of frame */
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-					data, 0);
+		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 		data += SPCA50X_OFFSET_DATA;
 		len -= SPCA50X_OFFSET_DATA;
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
-				data, len);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 		break;
 	case 0xff:			/* drop */
 /*		gspca_dev->last_packet_type = DISCARD_PACKET; */
@@ -562,8 +559,7 @@
 	default:
 		data += 1;
 		len -= 1;
-		gspca_frame_add(gspca_dev, INTER_PACKET, frame,
-				data, len);
+		gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 		break;
 	}
 }
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index 9696c4c..4d8e6cf 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -1447,26 +1447,22 @@
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
 			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	switch (data[0]) {
 	case 0:				/* start of frame */
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-					data, 0);
+		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 		data += SPCA508_OFFSET_DATA;
 		len -= SPCA508_OFFSET_DATA;
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
-				data, len);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 		break;
 	case 0xff:			/* drop */
 		break;
 	default:
 		data += 1;
 		len -= 1;
-		gspca_frame_add(gspca_dev, INTER_PACKET, frame,
-				data, len);
+		gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 		break;
 	}
 }
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index 27e82b3..58c2f00 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -779,8 +779,7 @@
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame, /* target */
-			__u8 *data,		/* isoc packet */
+			u8 *data,		/* isoc packet */
 			int len)		/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -788,12 +787,10 @@
 	len--;
 	switch (*data++) {			/* sequence number */
 	case 0:					/* start of frame */
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-					data, 0);
+		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 		if (data[1] & 0x10) {
 			/* compressed bayer */
-			gspca_frame_add(gspca_dev, FIRST_PACKET,
-					frame, data, len);
+			gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 		} else {
 			/* raw bayer (with a header, which we skip) */
 			if (sd->chip_revision == Rev012A) {
@@ -803,14 +800,13 @@
 				data += 16;
 				len -= 16;
 			}
-			gspca_frame_add(gspca_dev, FIRST_PACKET,
-						frame, data, len);
+			gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 		}
 		return;
 	case 0xff:			/* drop (empty mpackets) */
 		return;
 	}
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 /* rev 72a only */
diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c
index 715a68f..1fcaca6 100644
--- a/drivers/media/video/gspca/sq905.c
+++ b/drivers/media/video/gspca/sq905.c
@@ -168,18 +168,22 @@
  *  request and read a block of data - see warning on sq905_command.
  */
 static int
-sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size)
+sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size, int need_lock)
 {
 	int ret;
 	int act_len;
 
 	gspca_dev->usb_buf[0] = '\0';
+	if (need_lock)
+		mutex_lock(&gspca_dev->usb_lock);
 	ret = usb_control_msg(gspca_dev->dev,
 			      usb_sndctrlpipe(gspca_dev->dev, 0),
 			      USB_REQ_SYNCH_FRAME,                /* request */
 			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			      SQ905_BULK_READ, size, gspca_dev->usb_buf,
 			      1, SQ905_CMD_TIMEOUT);
+	if (need_lock)
+		mutex_unlock(&gspca_dev->usb_lock);
 	if (ret < 0) {
 		PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret);
 		return ret;
@@ -210,11 +214,9 @@
 {
 	struct sd *dev = container_of(work, struct sd, work_struct);
 	struct gspca_dev *gspca_dev = &dev->gspca_dev;
-	struct gspca_frame *frame;
 	int bytes_left; /* bytes remaining in current frame. */
 	int data_len;   /* size to use for the next read. */
 	int header_read; /* true if we have already read the frame header. */
-	int discarding; /* true if we failed to get space for frame. */
 	int packet_type;
 	int frame_sz;
 	int ret;
@@ -222,7 +224,6 @@
 	u8 *buffer;
 
 	buffer = kmalloc(SQ905_MAX_TRANSFER, GFP_KERNEL | GFP_DMA);
-	mutex_lock(&gspca_dev->usb_lock);
 	if (!buffer) {
 		PDEBUG(D_ERR, "Couldn't allocate USB buffer");
 		goto quit_stream;
@@ -232,28 +233,22 @@
 			+ FRAME_HEADER_LEN;
 
 	while (gspca_dev->present && gspca_dev->streaming) {
-		/* Need a short delay to ensure streaming flag was set by
-		 * gspca and to make sure gspca can grab the mutex. */
-		mutex_unlock(&gspca_dev->usb_lock);
-		msleep(1);
-
 		/* request some data and then read it until we have
 		 * a complete frame. */
 		bytes_left = frame_sz;
 		header_read = 0;
-		discarding = 0;
 
-		while (bytes_left > 0) {
+		/* Note we do not check for gspca_dev->streaming here, as
+		   we must finish reading an entire frame, otherwise the
+		   next time we stream we start reading in the middle of a
+		   frame. */
+		while (bytes_left > 0 && gspca_dev->present) {
 			data_len = bytes_left > SQ905_MAX_TRANSFER ?
 				SQ905_MAX_TRANSFER : bytes_left;
-			mutex_lock(&gspca_dev->usb_lock);
-			if (!gspca_dev->present)
-				goto quit_stream;
-			ret = sq905_read_data(gspca_dev, buffer, data_len);
+			ret = sq905_read_data(gspca_dev, buffer, data_len, 1);
 			if (ret < 0)
 				goto quit_stream;
-			mutex_unlock(&gspca_dev->usb_lock);
-			PDEBUG(D_STREAM,
+			PDEBUG(D_PACK,
 				"Got %d bytes out of %d for frame",
 				data_len, bytes_left);
 			bytes_left -= data_len;
@@ -270,34 +265,30 @@
 			} else {
 				packet_type = INTER_PACKET;
 			}
-			frame = gspca_get_i_frame(gspca_dev);
-			if (frame && !discarding) {
-				frame = gspca_frame_add(gspca_dev, packet_type,
-						frame, data, data_len);
-				/* If entire frame fits in one packet we still
-				   need to add a LAST_PACKET */
-				if (packet_type == FIRST_PACKET &&
-				    bytes_left == 0)
-					frame = gspca_frame_add(gspca_dev,
-							LAST_PACKET,
-							frame, data, 0);
-			} else {
-				discarding = 1;
-			}
+			gspca_frame_add(gspca_dev, packet_type,
+					data, data_len);
+			/* If entire frame fits in one packet we still
+			   need to add a LAST_PACKET */
+			if (packet_type == FIRST_PACKET &&
+			    bytes_left == 0)
+				gspca_frame_add(gspca_dev, LAST_PACKET,
+						NULL, 0);
 		}
-		/* acknowledge the frame */
-		mutex_lock(&gspca_dev->usb_lock);
-		if (!gspca_dev->present)
-			goto quit_stream;
-		ret = sq905_ack_frame(gspca_dev);
-		if (ret < 0)
-			goto quit_stream;
+		if (gspca_dev->present) {
+			/* acknowledge the frame */
+			mutex_lock(&gspca_dev->usb_lock);
+			ret = sq905_ack_frame(gspca_dev);
+			mutex_unlock(&gspca_dev->usb_lock);
+			if (ret < 0)
+				goto quit_stream;
+		}
 	}
 quit_stream:
-	/* the usb_lock is already acquired */
-	if (gspca_dev->present)
+	if (gspca_dev->present) {
+		mutex_lock(&gspca_dev->usb_lock);
 		sq905_command(gspca_dev, SQ905_CLEAR);
-	mutex_unlock(&gspca_dev->usb_lock);
+		mutex_unlock(&gspca_dev->usb_lock);
+	}
 	kfree(buffer);
 }
 
@@ -346,7 +337,7 @@
 	ret = sq905_command(gspca_dev, SQ905_ID);
 	if (ret < 0)
 		return ret;
-	ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4);
+	ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4, 0);
 	if (ret < 0)
 		return ret;
 	/* usb_buf is allocated with kmalloc so is aligned.
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c
index 9168925..d70b156 100644
--- a/drivers/media/video/gspca/sq905c.c
+++ b/drivers/media/video/gspca/sq905c.c
@@ -115,11 +115,9 @@
 {
 	struct sd *dev = container_of(work, struct sd, work_struct);
 	struct gspca_dev *gspca_dev = &dev->gspca_dev;
-	struct gspca_frame *frame;
 	int bytes_left; /* bytes remaining in current frame. */
 	int data_len;   /* size to use for the next read. */
 	int act_len;
-	int discarding = 0; /* true if we failed to get space for frame. */
 	int packet_type;
 	int ret;
 	u8 *buffer;
@@ -131,8 +129,6 @@
 	}
 
 	while (gspca_dev->present && gspca_dev->streaming) {
-		if (!gspca_dev->present)
-			goto quit_stream;
 		/* Request the header, which tells the size to download */
 		ret = usb_bulk_msg(gspca_dev->dev,
 				usb_rcvbulkpipe(gspca_dev->dev, 0x81),
@@ -149,17 +145,11 @@
 		PDEBUG(D_STREAM, "bytes_left = 0x%x", bytes_left);
 		/* We keep the header. It has other information, too. */
 		packet_type = FIRST_PACKET;
-		frame = gspca_get_i_frame(gspca_dev);
-		if (frame && !discarding) {
-			gspca_frame_add(gspca_dev, packet_type,
-				frame, buffer, FRAME_HEADER_LEN);
-			} else
-				discarding = 1;
-		while (bytes_left > 0) {
+		gspca_frame_add(gspca_dev, packet_type,
+				buffer, FRAME_HEADER_LEN);
+		while (bytes_left > 0 && gspca_dev->present) {
 			data_len = bytes_left > SQ905C_MAX_TRANSFER ?
 				SQ905C_MAX_TRANSFER : bytes_left;
-			if (!gspca_dev->present)
-				goto quit_stream;
 			ret = usb_bulk_msg(gspca_dev->dev,
 				usb_rcvbulkpipe(gspca_dev->dev, 0x81),
 				buffer, data_len, &act_len,
@@ -174,19 +164,16 @@
 				packet_type = LAST_PACKET;
 			else
 				packet_type = INTER_PACKET;
-			frame = gspca_get_i_frame(gspca_dev);
-			if (frame && !discarding)
-				gspca_frame_add(gspca_dev, packet_type,
-						frame, buffer, data_len);
-			else
-				discarding = 1;
+			gspca_frame_add(gspca_dev, packet_type,
+					buffer, data_len);
 		}
 	}
 quit_stream:
-	mutex_lock(&gspca_dev->usb_lock);
-	if (gspca_dev->present)
+	if (gspca_dev->present) {
+		mutex_lock(&gspca_dev->usb_lock);
 		sq905c_command(gspca_dev, SQ905C_CLEAR, 0);
-	mutex_unlock(&gspca_dev->usb_lock);
+		mutex_unlock(&gspca_dev->usb_lock);
+	}
 	kfree(buffer);
 }
 
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
index 4762896..8e23320 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/video/gspca/stk014.c
@@ -418,8 +418,7 @@
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -435,11 +434,11 @@
 	 *		(without ending - ff d9)
 	 */
 	if (data[0] == 0xff && data[1] == 0xfe) {
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-					ffd9, 2);
+		gspca_frame_add(gspca_dev, LAST_PACKET,
+				ffd9, 2);
 
 		/* put the JPEG 411 header */
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+		gspca_frame_add(gspca_dev, FIRST_PACKET,
 			sd->jpeg_hdr, JPEG_HDR_SZ);
 
 		/* beginning of the frame */
@@ -447,7 +446,7 @@
 		data += STKHDRSZ;
 		len -= STKHDRSZ;
 	}
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/stv0680.c b/drivers/media/video/gspca/stv0680.c
new file mode 100644
index 0000000..2a69d7c
--- /dev/null
+++ b/drivers/media/video/gspca/stv0680.c
@@ -0,0 +1,364 @@
+/*
+ * STV0680 USB Camera Driver
+ *
+ * Copyright (C) 2009 Hans de Goede <hdgoede@redhat.com>
+ *
+ * This module is adapted from the in kernel v4l1 stv680 driver:
+ *
+ *  STV0680 USB Camera Driver, by Kevin Sisson (kjsisson@bellsouth.net)
+ *
+ * Thanks to STMicroelectronics for information on the usb commands, and
+ * to Steve Miller at STM for his help and encouragement while I was
+ * writing this driver.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define MODULE_NAME "stv0680"
+
+#include "gspca.h"
+
+MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>");
+MODULE_DESCRIPTION("STV0680 USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+	struct gspca_dev gspca_dev;		/* !! must be the first item */
+	struct v4l2_pix_format mode;
+	u8 orig_mode;
+	u8 video_mode;
+	u8 current_mode;
+};
+
+/* V4L2 controls supported by the driver */
+static struct ctrl sd_ctrls[] = {
+};
+
+static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val,
+		       int size)
+{
+	int ret = -1;
+	u8 req_type = 0;
+
+	switch (set) {
+	case 0: /*  0xc1  */
+		req_type = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
+		break;
+	case 1: /*  0x41  */
+		req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
+		break;
+	case 2:	/*  0x80  */
+		req_type = USB_DIR_IN | USB_RECIP_DEVICE;
+		break;
+	case 3:	/*  0x40  */
+		req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
+		break;
+	}
+
+	ret = usb_control_msg(gspca_dev->dev,
+			      usb_rcvctrlpipe(gspca_dev->dev, 0),
+			      req, req_type,
+			      val, 0, gspca_dev->usb_buf, size, 500);
+
+	if ((ret < 0) && (req != 0x0a))
+		PDEBUG(D_ERR,
+		       "usb_control_msg error %i, request = 0x%x, error = %i",
+		       set, req, ret);
+
+	return ret;
+}
+
+static int stv0680_handle_error(struct gspca_dev *gspca_dev, int ret)
+{
+	stv_sndctrl(gspca_dev, 0, 0x80, 0, 0x02); /* Get Last Error */
+	PDEBUG(D_ERR, "last error: %i,  command = 0x%x",
+	       gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
+	return ret;
+}
+
+static int stv0680_get_video_mode(struct gspca_dev *gspca_dev)
+{
+	/* Note not sure if this init of usb_buf is really necessary */
+	memset(gspca_dev->usb_buf, 0, 8);
+	gspca_dev->usb_buf[0] = 0x0f;
+
+	if (stv_sndctrl(gspca_dev, 0, 0x87, 0, 0x08) != 0x08) {
+		PDEBUG(D_ERR, "Get_Camera_Mode failed");
+		return stv0680_handle_error(gspca_dev, -EIO);
+	}
+
+	return gspca_dev->usb_buf[0]; /* 01 = VGA, 03 = QVGA, 00 = CIF */
+}
+
+static int stv0680_set_video_mode(struct gspca_dev *gspca_dev, u8 mode)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->current_mode == mode)
+		return 0;
+
+	memset(gspca_dev->usb_buf, 0, 8);
+	gspca_dev->usb_buf[0] = mode;
+
+	if (stv_sndctrl(gspca_dev, 3, 0x07, 0x0100, 0x08) != 0x08) {
+		PDEBUG(D_ERR, "Set_Camera_Mode failed");
+		return stv0680_handle_error(gspca_dev, -EIO);
+	}
+
+	/* Verify we got what we've asked for */
+	if (stv0680_get_video_mode(gspca_dev) != mode) {
+		PDEBUG(D_ERR, "Error setting camera video mode!");
+		return -EIO;
+	}
+
+	sd->current_mode = mode;
+
+	return 0;
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+			const struct usb_device_id *id)
+{
+	int ret;
+	struct sd *sd = (struct sd *) gspca_dev;
+	struct cam *cam = &gspca_dev->cam;
+
+	/* ping camera to be sure STV0680 is present */
+	if (stv_sndctrl(gspca_dev, 0, 0x88, 0x5678, 0x02) != 0x02 ||
+	    gspca_dev->usb_buf[0] != 0x56 || gspca_dev->usb_buf[1] != 0x78) {
+		PDEBUG(D_ERR, "STV(e): camera ping failed!!");
+		return stv0680_handle_error(gspca_dev, -ENODEV);
+	}
+
+	/* get camera descriptor */
+	if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0200, 0x09) != 0x09)
+		return stv0680_handle_error(gspca_dev, -ENODEV);
+
+	if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0200, 0x22) != 0x22 ||
+	    gspca_dev->usb_buf[7] != 0xa0 || gspca_dev->usb_buf[8] != 0x23) {
+		PDEBUG(D_ERR, "Could not get descriptor 0200.");
+		return stv0680_handle_error(gspca_dev, -ENODEV);
+	}
+	if (stv_sndctrl(gspca_dev, 0, 0x8a, 0, 0x02) != 0x02)
+		return stv0680_handle_error(gspca_dev, -ENODEV);
+	if (stv_sndctrl(gspca_dev, 0, 0x8b, 0, 0x24) != 0x24)
+		return stv0680_handle_error(gspca_dev, -ENODEV);
+	if (stv_sndctrl(gspca_dev, 0, 0x85, 0, 0x10) != 0x10)
+		return stv0680_handle_error(gspca_dev, -ENODEV);
+
+	if (!(gspca_dev->usb_buf[7] & 0x09)) {
+		PDEBUG(D_ERR, "Camera supports neither CIF nor QVGA mode");
+		return -ENODEV;
+	}
+	if (gspca_dev->usb_buf[7] & 0x01)
+		PDEBUG(D_PROBE, "Camera supports CIF mode");
+	if (gspca_dev->usb_buf[7] & 0x02)
+		PDEBUG(D_PROBE, "Camera supports VGA mode");
+	if (gspca_dev->usb_buf[7] & 0x08)
+		PDEBUG(D_PROBE, "Camera supports QVGA mode");
+
+	if (gspca_dev->usb_buf[7] & 0x01)
+		sd->video_mode = 0x00; /* CIF */
+	else
+		sd->video_mode = 0x03; /* QVGA */
+
+	/* FW rev, ASIC rev, sensor ID  */
+	PDEBUG(D_PROBE, "Firmware rev is %i.%i",
+	       gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
+	PDEBUG(D_PROBE, "ASIC rev is %i.%i",
+	       gspca_dev->usb_buf[2], gspca_dev->usb_buf[3]);
+	PDEBUG(D_PROBE, "Sensor ID is %i",
+	       (gspca_dev->usb_buf[4]*16) + (gspca_dev->usb_buf[5]>>4));
+
+
+	ret = stv0680_get_video_mode(gspca_dev);
+	if (ret < 0)
+		return ret;
+	sd->current_mode = sd->orig_mode = ret;
+
+	ret = stv0680_set_video_mode(gspca_dev, sd->video_mode);
+	if (ret < 0)
+		return ret;
+
+	/* Get mode details */
+	if (stv_sndctrl(gspca_dev, 0, 0x8f, 0, 0x10) != 0x10)
+		return stv0680_handle_error(gspca_dev, -EIO);
+
+	cam->bulk = 1;
+	cam->bulk_nurbs = 1; /* The cam cannot handle more */
+	cam->bulk_size = (gspca_dev->usb_buf[0] << 24) |
+			 (gspca_dev->usb_buf[1] << 16) |
+			 (gspca_dev->usb_buf[2] << 8) |
+			 (gspca_dev->usb_buf[3]);
+	sd->mode.width = (gspca_dev->usb_buf[4] << 8) |
+			 (gspca_dev->usb_buf[5]);  /* 322, 356, 644 */
+	sd->mode.height = (gspca_dev->usb_buf[6] << 8) |
+			  (gspca_dev->usb_buf[7]); /* 242, 292, 484 */
+	sd->mode.pixelformat = V4L2_PIX_FMT_STV0680;
+	sd->mode.field = V4L2_FIELD_NONE;
+	sd->mode.bytesperline = sd->mode.width;
+	sd->mode.sizeimage = cam->bulk_size;
+	sd->mode.colorspace = V4L2_COLORSPACE_SRGB;
+
+	/* origGain = gspca_dev->usb_buf[12]; */
+
+	cam->cam_mode = &sd->mode;
+	cam->nmodes = 1;
+
+
+	ret = stv0680_set_video_mode(gspca_dev, sd->orig_mode);
+	if (ret < 0)
+		return ret;
+
+	if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0100, 0x12) != 0x12 ||
+	    gspca_dev->usb_buf[8] != 0x53 || gspca_dev->usb_buf[9] != 0x05) {
+		PDEBUG(D_ERR, "Could not get descriptor 0100.");
+		return stv0680_handle_error(gspca_dev, -EIO);
+	}
+
+	return 0;
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+	return 0;
+}
+
+/* -- start the camera -- */
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+	int ret;
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	ret = stv0680_set_video_mode(gspca_dev, sd->video_mode);
+	if (ret < 0)
+		return ret;
+
+	if (stv_sndctrl(gspca_dev, 0, 0x85, 0, 0x10) != 0x10)
+		return stv0680_handle_error(gspca_dev, -EIO);
+
+	/* Start stream at:
+	   0x0000 = CIF (352x288)
+	   0x0100 = VGA (640x480)
+	   0x0300 = QVGA (320x240) */
+	if (stv_sndctrl(gspca_dev, 1, 0x09, sd->video_mode << 8, 0x0) != 0x0)
+		return stv0680_handle_error(gspca_dev, -EIO);
+
+	return 0;
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+	/* This is a high priority command; it stops all lower order cmds */
+	if (stv_sndctrl(gspca_dev, 1, 0x04, 0x0000, 0x0) != 0x0)
+		stv0680_handle_error(gspca_dev, -EIO);
+}
+
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (!sd->gspca_dev.present)
+		return;
+
+	stv0680_set_video_mode(gspca_dev, sd->orig_mode);
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+			u8 *data,
+			int len)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	/* Every now and then the camera sends a 16 byte packet, no idea
+	   what it contains, but it is not image data, when this
+	   happens the frame received before this packet is corrupt,
+	   so discard it. */
+	if (len != sd->mode.sizeimage) {
+		gspca_dev->last_packet_type = DISCARD_PACKET;
+		return;
+	}
+
+	/* Finish the previous frame, we do this upon reception of the next
+	   packet, even though it is already complete so that the strange 16
+	   byte packets send after a corrupt frame can discard it. */
+	gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
+
+	/* Store the just received frame */
+	gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+	.name = MODULE_NAME,
+	.ctrls = sd_ctrls,
+	.nctrls = ARRAY_SIZE(sd_ctrls),
+	.config = sd_config,
+	.init = sd_init,
+	.start = sd_start,
+	.stopN = sd_stopN,
+	.stop0 = sd_stop0,
+	.pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+static const __devinitdata struct usb_device_id device_table[] = {
+	{USB_DEVICE(0x0553, 0x0202)},
+	{USB_DEVICE(0x041e, 0x4007)},
+	{}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+			const struct usb_device_id *id)
+{
+	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+				THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+	.name = MODULE_NAME,
+	.id_table = device_table,
+	.probe = sd_probe,
+	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
+	PDEBUG(D_PROBE, "registered");
+	return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+	usb_deregister(&sd_driver);
+	PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index bfae63f..5d0241b 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -312,8 +312,7 @@
  * The 0005 and 0100 chunks seem to appear only in compressed stream.
  */
 static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -366,7 +365,7 @@
 				sd->to_skip -= skip;
 			}
 
-			gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+			gspca_frame_add(gspca_dev, INTER_PACKET,
 					data, chunk_len);
 			break;
 
@@ -378,7 +377,7 @@
 
 			/* Create a new frame, chunk length should be zero */
 			gspca_frame_add(gspca_dev, FIRST_PACKET,
-					frame, data, 0);
+					NULL, 0);
 
 			if (sd->bridge == BRIDGE_ST6422)
 				sd->to_skip = gspca_dev->width * 4;
@@ -394,8 +393,8 @@
 			PDEBUG(D_PACK, "End of frame detected");
 
 			/* Complete the last frame (if any) */
-			frame = gspca_frame_add(gspca_dev, LAST_PACKET,
-						frame, data, 0);
+			gspca_frame_add(gspca_dev, LAST_PACKET,
+					NULL, 0);
 
 			if (chunk_len)
 				PDEBUG(D_ERR, "Chunk length is "
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index aa8f995..72bf3b4 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -631,7 +631,7 @@
 	count = 200;
 	while (--count > 0) {
 		msleep(10);
-		/* gsmart mini2 write a each wait setting 1 ms is enought */
+		/* gsmart mini2 write a each wait setting 1 ms is enough */
 /*		reg_w_riv(dev, req, idx, val); */
 		status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
 		if (status == endcode) {
@@ -1116,7 +1116,6 @@
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
 			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
@@ -1186,11 +1185,11 @@
 		break;
 	}
 	if (sof) {		/* start of frame */
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-					ffd9, 2);
+		gspca_frame_add(gspca_dev, LAST_PACKET,
+				ffd9, 2);
 
 		/* put the JPEG header in the new frame */
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+		gspca_frame_add(gspca_dev, FIRST_PACKET,
 			sd->jpeg_hdr, JPEG_HDR_SZ);
 	}
 
@@ -1198,7 +1197,7 @@
 	i = 0;
 	do {
 		if (data[i] == 0xff) {
-			gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+			gspca_frame_add(gspca_dev, INTER_PACKET,
 					data, i + 1);
 			len -= i;
 			data += i;
@@ -1207,7 +1206,7 @@
 		}
 		i++;
 	} while (i < len);
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index 1d321c3..55ef6a7 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -938,7 +938,6 @@
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
 			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
@@ -956,9 +955,9 @@
 		/* extra bytes....., could be processed too but would be
 		 * a waste of time, right now leave the application and
 		 * libjpeg do it for ourserlves.. */
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+		gspca_frame_add(gspca_dev, LAST_PACKET,
 					ffd9, 2);
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 		return;
 	}
 
@@ -967,7 +966,7 @@
 		 * other's do not include it... */
 		len -= 2;
 	}
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index 4b44dde..b74a3b6 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -398,8 +398,7 @@
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -424,9 +423,9 @@
 	 * - 4 bytes
 	 */
 	gspca_frame_add(gspca_dev, packet_type0,
-			frame, data + 2, gspca_dev->width);
+			data + 2, gspca_dev->width);
 	gspca_frame_add(gspca_dev, packet_type1,
-			frame, data + gspca_dev->width + 5, gspca_dev->width);
+			data + gspca_dev->width + 5, gspca_dev->width);
 }
 
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 589042f..c090efc 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -2987,7 +2987,6 @@
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
 			u8 *data,			/* isoc packet */
 			int len)			/* iso pkt length */
 {
@@ -2996,21 +2995,25 @@
 	if (data[0] == 0xff && data[1] == 0xd8) {
 		PDEBUG(D_PACK,
 			"vc032x header packet found len %d", len);
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-						data, 0);
+		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 		data += sd->image_offset;
 		len -= sd->image_offset;
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
-				data, len);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 		return;
 	}
 
 	/* The vc0321 sends some additional data after sending the complete
 	 * frame, we ignore this. */
-	if (sd->bridge == BRIDGE_VC0321
-	    && len > frame->v4l2_buf.length - (frame->data_end - frame->data))
-		len = frame->v4l2_buf.length - (frame->data_end - frame->data);
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	if (sd->bridge == BRIDGE_VC0321) {
+		struct gspca_frame *frame;
+		int l;
+
+		frame = gspca_get_i_frame(gspca_dev);
+		l = frame->data_end - frame->data;
+		if (len > frame->v4l2_buf.length - l)
+			len = frame->v4l2_buf.length - l;
+	}
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -3092,6 +3095,8 @@
 
 	switch (menu->id) {
 	case V4L2_CID_POWER_LINE_FREQUENCY:
+		if (menu->index >= ARRAY_SIZE(freq_nm))
+			break;
 		strcpy((char *) menu->name, freq_nm[menu->index]);
 		return 0;
 	}
diff --git a/drivers/media/video/gspca/w996Xcf.c b/drivers/media/video/gspca/w996Xcf.c
new file mode 100644
index 0000000..2fffe20
--- /dev/null
+++ b/drivers/media/video/gspca/w996Xcf.c
@@ -0,0 +1,609 @@
+/**
+ *
+ * GSPCA sub driver for W996[78]CF JPEG USB Dual Mode Camera Chip.
+ *
+ * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This module is adapted from the in kernel v4l1 w9968cf driver:
+ *
+ * Copyright (C) 2002-2004 by Luca Risolia <luca.risolia@studio.unibo.it>
+ *
+ * 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
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/* Note this is not a stand alone driver, it gets included in ov519.c, this
+   is a bit of a hack, but it needs the driver code for a lot of different
+   ov sensors which is already present in ov519.c (the old v4l1 driver used
+   the ovchipcam framework). When we have the time we really should move
+   the sensor drivers to v4l2 sub drivers, and properly split of this
+   driver from ov519.c */
+
+/* The CONEX_CAM define for jpeg.h needs renaming, now its used here too */
+#define CONEX_CAM
+#include "jpeg.h"
+
+#define W9968CF_I2C_BUS_DELAY    4 /* delay in us for I2C bit r/w operations */
+
+#define Y_QUANTABLE (sd->jpeg_hdr + JPEG_QT0_OFFSET)
+#define UV_QUANTABLE (sd->jpeg_hdr + JPEG_QT1_OFFSET)
+
+static const struct v4l2_pix_format w9968cf_vga_mode[] = {
+	{160, 120, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
+		.bytesperline = 160 * 2,
+		.sizeimage = 160 * 120 * 2,
+		.colorspace = V4L2_COLORSPACE_JPEG},
+	{176, 144, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
+		.bytesperline = 176 * 2,
+		.sizeimage = 176 * 144 * 2,
+		.colorspace = V4L2_COLORSPACE_JPEG},
+	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+		.bytesperline = 320 * 2,
+		.sizeimage = 320 * 240 * 2,
+		.colorspace = V4L2_COLORSPACE_JPEG},
+	{352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+		.bytesperline = 352 * 2,
+		.sizeimage = 352 * 288 * 2,
+		.colorspace = V4L2_COLORSPACE_JPEG},
+	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+		.bytesperline = 640 * 2,
+		.sizeimage = 640 * 480 * 2,
+		.colorspace = V4L2_COLORSPACE_JPEG},
+};
+
+static int reg_w(struct sd *sd, __u16 index, __u16 value);
+
+/*--------------------------------------------------------------------------
+  Write 64-bit data to the fast serial bus registers.
+  Return 0 on success, -1 otherwise.
+  --------------------------------------------------------------------------*/
+static int w9968cf_write_fsb(struct sd *sd, u16* data)
+{
+	struct usb_device* udev = sd->gspca_dev.dev;
+	u16 value;
+	int ret;
+
+	value = *data++;
+	memcpy(sd->gspca_dev.usb_buf, data, 6);
+
+	ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
+			      USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
+			      value, 0x06, sd->gspca_dev.usb_buf, 6, 500);
+	if (ret < 0) {
+		PDEBUG(D_ERR, "Write FSB registers failed (%d)", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/*--------------------------------------------------------------------------
+  Write data to the serial bus control register.
+  Return 0 on success, a negative number otherwise.
+  --------------------------------------------------------------------------*/
+static int w9968cf_write_sb(struct sd *sd, u16 value)
+{
+	int ret;
+
+	/* We don't use reg_w here, as that would cause all writes when
+	   bitbanging i2c to be logged, making the logs impossible to read */
+	ret = usb_control_msg(sd->gspca_dev.dev,
+		usb_sndctrlpipe(sd->gspca_dev.dev, 0),
+		0,
+		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		value, 0x01, NULL, 0, 500);
+
+	udelay(W9968CF_I2C_BUS_DELAY);
+
+	if (ret < 0) {
+		PDEBUG(D_ERR, "Write SB reg [01] %04x failed", value);
+		return ret;
+	}
+
+	return 0;
+}
+
+/*--------------------------------------------------------------------------
+  Read data from the serial bus control register.
+  Return 0 on success, a negative number otherwise.
+  --------------------------------------------------------------------------*/
+static int w9968cf_read_sb(struct sd *sd)
+{
+	int ret;
+
+	/* We don't use reg_r here, as the w9968cf is special and has 16
+	   bit registers instead of 8 bit */
+	ret = usb_control_msg(sd->gspca_dev.dev,
+			usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
+			1,
+			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			0, 0x01, sd->gspca_dev.usb_buf, 2, 500);
+	if (ret >= 0)
+		ret = sd->gspca_dev.usb_buf[0] |
+		      (sd->gspca_dev.usb_buf[1] << 8);
+	else
+		PDEBUG(D_ERR, "Read SB reg [01] failed");
+
+	udelay(W9968CF_I2C_BUS_DELAY);
+
+	return ret;
+}
+
+/*--------------------------------------------------------------------------
+  Upload quantization tables for the JPEG compression.
+  This function is called by w9968cf_start_transfer().
+  Return 0 on success, a negative number otherwise.
+  --------------------------------------------------------------------------*/
+static int w9968cf_upload_quantizationtables(struct sd *sd)
+{
+	u16 a, b;
+	int ret = 0, i, j;
+
+	ret += reg_w(sd, 0x39, 0x0010); /* JPEG clock enable */
+
+	for (i = 0, j = 0; i < 32; i++, j += 2) {
+		a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j+1]) << 8);
+		b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j+1]) << 8);
+		ret += reg_w(sd, 0x40+i, a);
+		ret += reg_w(sd, 0x60+i, b);
+	}
+	ret += reg_w(sd, 0x39, 0x0012); /* JPEG encoder enable */
+
+	return ret;
+}
+
+/****************************************************************************
+ * Low-level I2C I/O functions.                                             *
+ * The adapter supports the following I2C transfer functions:               *
+ * i2c_adap_fastwrite_byte_data() (at 400 kHz bit frequency only)           *
+ * i2c_adap_read_byte_data()                                                *
+ * i2c_adap_read_byte()                                                     *
+ ****************************************************************************/
+
+static int w9968cf_smbus_start(struct sd *sd)
+{
+	int ret = 0;
+
+	ret += w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
+	ret += w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
+
+	return ret;
+}
+
+static int w9968cf_smbus_stop(struct sd *sd)
+{
+	int ret = 0;
+
+	ret += w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
+	ret += w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
+	ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
+
+	return ret;
+}
+
+static int w9968cf_smbus_write_byte(struct sd *sd, u8 v)
+{
+	u8 bit;
+	int ret = 0, sda;
+
+	for (bit = 0 ; bit < 8 ; bit++) {
+		sda = (v & 0x80) ? 2 : 0;
+		v <<= 1;
+		/* SDE=1, SDA=sda, SCL=0 */
+		ret += w9968cf_write_sb(sd, 0x10 | sda);
+		/* SDE=1, SDA=sda, SCL=1 */
+		ret += w9968cf_write_sb(sd, 0x11 | sda);
+		/* SDE=1, SDA=sda, SCL=0 */
+		ret += w9968cf_write_sb(sd, 0x10 | sda);
+	}
+
+	return ret;
+}
+
+static int w9968cf_smbus_read_byte(struct sd *sd, u8* v)
+{
+	u8 bit;
+	int ret = 0;
+
+	/* No need to ensure SDA is high as we are always called after
+	   read_ack which ends with SDA high */
+	*v = 0;
+	for (bit = 0 ; bit < 8 ; bit++) {
+		*v <<= 1;
+		/* SDE=1, SDA=1, SCL=1 */
+		ret += w9968cf_write_sb(sd, 0x0013);
+		*v |= (w9968cf_read_sb(sd) & 0x0008) ? 1 : 0;
+		/* SDE=1, SDA=1, SCL=0 */
+		ret += w9968cf_write_sb(sd, 0x0012);
+	}
+
+	return ret;
+}
+
+static int w9968cf_smbus_write_nack(struct sd *sd)
+{
+	int ret = 0;
+
+	/* No need to ensure SDA is high as we are always called after
+	   read_byte which ends with SDA high */
+	ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
+	ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
+
+	return ret;
+}
+
+static int w9968cf_smbus_read_ack(struct sd *sd)
+{
+	int ret = 0, sda;
+
+	/* Ensure SDA is high before raising clock to avoid a spurious stop */
+	ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
+	ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
+	sda = w9968cf_read_sb(sd);
+	ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
+	if (sda < 0)
+		ret += sda;
+	else if (sda & 0x08) {
+		PDEBUG(D_USBI, "Did not receive i2c ACK");
+		ret += -1;
+	}
+
+	return ret;
+}
+
+/* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */
+static int w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
+{
+	u16* data = (u16 *)sd->gspca_dev.usb_buf;
+	int ret = 0;
+
+	data[0] = 0x082f | ((sd->sensor_addr & 0x80) ? 0x1500 : 0x0);
+	data[0] |= (sd->sensor_addr & 0x40) ? 0x4000 : 0x0;
+	data[1] = 0x2082 | ((sd->sensor_addr & 0x40) ? 0x0005 : 0x0);
+	data[1] |= (sd->sensor_addr & 0x20) ? 0x0150 : 0x0;
+	data[1] |= (sd->sensor_addr & 0x10) ? 0x5400 : 0x0;
+	data[2] = 0x8208 | ((sd->sensor_addr & 0x08) ? 0x0015 : 0x0);
+	data[2] |= (sd->sensor_addr & 0x04) ? 0x0540 : 0x0;
+	data[2] |= (sd->sensor_addr & 0x02) ? 0x5000 : 0x0;
+	data[3] = 0x1d20 | ((sd->sensor_addr & 0x02) ? 0x0001 : 0x0);
+	data[3] |= (sd->sensor_addr & 0x01) ? 0x0054 : 0x0;
+
+	ret += w9968cf_write_fsb(sd, data);
+
+	data[0] = 0x8208 | ((reg & 0x80) ? 0x0015 : 0x0);
+	data[0] |= (reg & 0x40) ? 0x0540 : 0x0;
+	data[0] |= (reg & 0x20) ? 0x5000 : 0x0;
+	data[1] = 0x0820 | ((reg & 0x20) ? 0x0001 : 0x0);
+	data[1] |= (reg & 0x10) ? 0x0054 : 0x0;
+	data[1] |= (reg & 0x08) ? 0x1500 : 0x0;
+	data[1] |= (reg & 0x04) ? 0x4000 : 0x0;
+	data[2] = 0x2082 | ((reg & 0x04) ? 0x0005 : 0x0);
+	data[2] |= (reg & 0x02) ? 0x0150 : 0x0;
+	data[2] |= (reg & 0x01) ? 0x5400 : 0x0;
+	data[3] = 0x001d;
+
+	ret += w9968cf_write_fsb(sd, data);
+
+	data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0);
+	data[0] |= (value & 0x40) ? 0x0540 : 0x0;
+	data[0] |= (value & 0x20) ? 0x5000 : 0x0;
+	data[1] = 0x0820 | ((value & 0x20) ? 0x0001 : 0x0);
+	data[1] |= (value & 0x10) ? 0x0054 : 0x0;
+	data[1] |= (value & 0x08) ? 0x1500 : 0x0;
+	data[1] |= (value & 0x04) ? 0x4000 : 0x0;
+	data[2] = 0x2082 | ((value & 0x04) ? 0x0005 : 0x0);
+	data[2] |= (value & 0x02) ? 0x0150 : 0x0;
+	data[2] |= (value & 0x01) ? 0x5400 : 0x0;
+	data[3] = 0xfe1d;
+
+	ret += w9968cf_write_fsb(sd, data);
+
+	if (!ret)
+		PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
+	else
+		PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg);
+
+	return ret;
+}
+
+/* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */
+static int w9968cf_i2c_r(struct sd *sd, u8 reg)
+{
+	int ret = 0;
+	u8 value;
+
+	/* Fast serial bus data control disable */
+	ret += w9968cf_write_sb(sd, 0x0013); /* don't change ! */
+
+	ret += w9968cf_smbus_start(sd);
+	ret += w9968cf_smbus_write_byte(sd, sd->sensor_addr);
+	ret += w9968cf_smbus_read_ack(sd);
+	ret += w9968cf_smbus_write_byte(sd, reg);
+	ret += w9968cf_smbus_read_ack(sd);
+	ret += w9968cf_smbus_stop(sd);
+	ret += w9968cf_smbus_start(sd);
+	ret += w9968cf_smbus_write_byte(sd, sd->sensor_addr + 1);
+	ret += w9968cf_smbus_read_ack(sd);
+	ret += w9968cf_smbus_read_byte(sd, &value);
+	/* signal we don't want to read anymore, the v4l1 driver used to
+	   send an ack here which is very wrong! (and then fixed
+	   the issues this gave by retrying reads) */
+	ret += w9968cf_smbus_write_nack(sd);
+	ret += w9968cf_smbus_stop(sd);
+
+	/* Fast serial bus data control re-enable */
+	ret += w9968cf_write_sb(sd, 0x0030);
+
+	if (!ret) {
+		ret = value;
+		PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
+	} else
+		PDEBUG(D_ERR, "i2c read [0x%02x] failed", reg);
+
+	return ret;
+}
+
+
+/*--------------------------------------------------------------------------
+  Turn on the LED on some webcams. A beep should be heard too.
+  Return 0 on success, a negative number otherwise.
+  --------------------------------------------------------------------------*/
+static int w9968cf_configure(struct sd *sd)
+{
+	int ret = 0;
+
+	ret += reg_w(sd, 0x00, 0xff00); /* power-down */
+	ret += reg_w(sd, 0x00, 0xbf17); /* reset everything */
+	ret += reg_w(sd, 0x00, 0xbf10); /* normal operation */
+	ret += reg_w(sd, 0x01, 0x0010); /* serial bus, SDS high */
+	ret += reg_w(sd, 0x01, 0x0000); /* serial bus, SDS low */
+	ret += reg_w(sd, 0x01, 0x0010); /* ..high 'beep-beep' */
+	ret += reg_w(sd, 0x01, 0x0030); /* Set sda scl to FSB mode */
+
+	if (ret)
+		PDEBUG(D_ERR, "Couldn't turn on the LED");
+
+	sd->stopped = 1;
+
+	return ret;
+}
+
+static int w9968cf_init(struct sd *sd)
+{
+	int ret = 0;
+	unsigned long hw_bufsize = sd->sif ? (352 * 288 * 2) : (640 * 480 * 2),
+		      y0 = 0x0000,
+		      u0 = y0 + hw_bufsize/2,
+		      v0 = u0 + hw_bufsize/4,
+		      y1 = v0 + hw_bufsize/4,
+		      u1 = y1 + hw_bufsize/2,
+		      v1 = u1 + hw_bufsize/4;
+
+	ret += reg_w(sd, 0x00, 0xff00); /* power off */
+	ret += reg_w(sd, 0x00, 0xbf10); /* power on */
+
+	ret += reg_w(sd, 0x03, 0x405d); /* DRAM timings */
+	ret += reg_w(sd, 0x04, 0x0030); /* SDRAM timings */
+
+	ret += reg_w(sd, 0x20, y0 & 0xffff); /* Y buf.0, low */
+	ret += reg_w(sd, 0x21, y0 >> 16);    /* Y buf.0, high */
+	ret += reg_w(sd, 0x24, u0 & 0xffff); /* U buf.0, low */
+	ret += reg_w(sd, 0x25, u0 >> 16);    /* U buf.0, high */
+	ret += reg_w(sd, 0x28, v0 & 0xffff); /* V buf.0, low */
+	ret += reg_w(sd, 0x29, v0 >> 16);    /* V buf.0, high */
+
+	ret += reg_w(sd, 0x22, y1 & 0xffff); /* Y buf.1, low */
+	ret += reg_w(sd, 0x23, y1 >> 16);    /* Y buf.1, high */
+	ret += reg_w(sd, 0x26, u1 & 0xffff); /* U buf.1, low */
+	ret += reg_w(sd, 0x27, u1 >> 16);    /* U buf.1, high */
+	ret += reg_w(sd, 0x2a, v1 & 0xffff); /* V buf.1, low */
+	ret += reg_w(sd, 0x2b, v1 >> 16);    /* V buf.1, high */
+
+	ret += reg_w(sd, 0x32, y1 & 0xffff); /* JPEG buf 0 low */
+	ret += reg_w(sd, 0x33, y1 >> 16);    /* JPEG buf 0 high */
+
+	ret += reg_w(sd, 0x34, y1 & 0xffff); /* JPEG buf 1 low */
+	ret += reg_w(sd, 0x35, y1 >> 16);    /* JPEG bug 1 high */
+
+	ret += reg_w(sd, 0x36, 0x0000);/* JPEG restart interval */
+	ret += reg_w(sd, 0x37, 0x0804);/*JPEG VLE FIFO threshold*/
+	ret += reg_w(sd, 0x38, 0x0000);/* disable hw up-scaling */
+	ret += reg_w(sd, 0x3f, 0x0000); /* JPEG/MCTL test data */
+
+	return ret;
+}
+
+static int w9968cf_set_crop_window(struct sd *sd)
+{
+	int ret = 0, start_cropx, start_cropy,  x, y, fw, fh, cw, ch,
+	    max_width, max_height;
+
+	if (sd->sif) {
+		max_width  = 352;
+		max_height = 288;
+	} else {
+		max_width  = 640;
+		max_height = 480;
+	}
+
+	if (sd->sensor == SEN_OV7620) {
+		/* Sigh, this is dependend on the clock / framerate changes
+		   made by the frequency control, sick. */
+		if (sd->freq == 1) {
+			start_cropx = 277;
+			start_cropy = 37;
+		} else {
+			start_cropx = 105;
+			start_cropy = 37;
+		}
+	} else {
+		start_cropx = 320;
+		start_cropy = 35;
+	}
+
+	/* Work around to avoid FP arithmetics */
+	#define SC(x) ((x) << 10)
+
+	/* Scaling factors */
+	fw = SC(sd->gspca_dev.width) / max_width;
+	fh = SC(sd->gspca_dev.height) / max_height;
+
+	cw = (fw >= fh) ? max_width : SC(sd->gspca_dev.width)/fh;
+	ch = (fw >= fh) ? SC(sd->gspca_dev.height)/fw : max_height;
+
+	sd->sensor_width = max_width;
+	sd->sensor_height = max_height;
+
+	x = (max_width - cw) / 2;
+	y = (max_height - ch) / 2;
+
+	ret += reg_w(sd, 0x10, start_cropx + x);
+	ret += reg_w(sd, 0x11, start_cropy + y);
+	ret += reg_w(sd, 0x12, start_cropx + x + cw);
+	ret += reg_w(sd, 0x13, start_cropy + y + ch);
+
+	return ret;
+}
+
+static int w9968cf_mode_init_regs(struct sd *sd)
+{
+	int ret = 0, val, vs_polarity, hs_polarity;
+
+	ret += w9968cf_set_crop_window(sd);
+
+	ret += reg_w(sd, 0x14, sd->gspca_dev.width);
+	ret += reg_w(sd, 0x15, sd->gspca_dev.height);
+
+	/* JPEG width & height */
+	ret += reg_w(sd, 0x30, sd->gspca_dev.width);
+	ret += reg_w(sd, 0x31, sd->gspca_dev.height);
+
+	/* Y & UV frame buffer strides (in WORD) */
+	if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
+	    V4L2_PIX_FMT_JPEG) {
+		ret += reg_w(sd, 0x2c, sd->gspca_dev.width/2);
+		ret += reg_w(sd, 0x2d, sd->gspca_dev.width/4);
+	} else
+		ret += reg_w(sd, 0x2c, sd->gspca_dev.width);
+
+	ret += reg_w(sd, 0x00, 0xbf17); /* reset everything */
+	ret += reg_w(sd, 0x00, 0xbf10); /* normal operation */
+
+	/* Transfer size in WORDS (for UYVY format only) */
+	val = sd->gspca_dev.width * sd->gspca_dev.height;
+	ret += reg_w(sd, 0x3d, val & 0xffff); /* low bits */
+	ret += reg_w(sd, 0x3e, val >> 16);    /* high bits */
+
+	if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
+	    V4L2_PIX_FMT_JPEG) {
+		/* We may get called multiple times (usb isoc bw negotiat.) */
+		if (!sd->jpeg_hdr)
+			sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+		if (!sd->jpeg_hdr)
+			return -ENOMEM;
+
+		jpeg_define(sd->jpeg_hdr, sd->gspca_dev.height,
+			    sd->gspca_dev.width, 0x22); /* JPEG 420 */
+		jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+		ret += w9968cf_upload_quantizationtables(sd);
+	}
+
+	/* Video Capture Control Register */
+	if (sd->sensor == SEN_OV7620) {
+		/* Seems to work around a bug in the image sensor */
+		vs_polarity = 1;
+		hs_polarity = 1;
+	} else {
+		vs_polarity = 1;
+		hs_polarity = 0;
+	}
+
+	val = (vs_polarity << 12) | (hs_polarity << 11);
+
+	/* NOTE: We may not have enough memory to do double buffering while
+	   doing compression (amount of memory differs per model cam).
+	   So we use the second image buffer also as jpeg stream buffer
+	   (see w9968cf_init), and disable double buffering. */
+	if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
+	    V4L2_PIX_FMT_JPEG) {
+		/* val |= 0x0002; YUV422P */
+		val |= 0x0003; /* YUV420P */
+	} else
+		val |= 0x0080; /* Enable HW double buffering */
+
+	/* val |= 0x0020; enable clamping */
+	/* val |= 0x0008; enable (1-2-1) filter */
+	/* val |= 0x000c; enable (2-3-6-3-2) filter */
+
+	val |= 0x8000; /* capt. enable */
+
+	ret += reg_w(sd, 0x16, val);
+
+	sd->gspca_dev.empty_packet = 0;
+
+	return ret;
+}
+
+static void w9968cf_stop0(struct sd *sd)
+{
+	if (sd->gspca_dev.present) {
+		reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */
+		reg_w(sd, 0x16, 0x0000); /* stop video capture */
+	}
+
+	kfree(sd->jpeg_hdr);
+	sd->jpeg_hdr = NULL;
+}
+
+/* The w9968cf docs say that a 0 sized packet means EOF (and also SOF
+   for the next frame). This seems to simply not be true when operating
+   in JPEG mode, in this case there may be empty packets within the
+   frame. So in JPEG mode use the JPEG SOI marker to detect SOF.
+
+   Note to make things even more interesting the w9968cf sends *PLANAR* jpeg,
+   to be precise it sends: SOI, SOF, DRI, SOS, Y-data, SOS, U-data, SOS,
+   V-data, EOI. */
+static void w9968cf_pkt_scan(struct gspca_dev *gspca_dev,
+			u8 *data,			/* isoc packet */
+			int len)			/* iso packet length */
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (w9968cf_vga_mode[gspca_dev->curr_mode].pixelformat ==
+	    V4L2_PIX_FMT_JPEG) {
+		if (len >= 2 &&
+		    data[0] == 0xff &&
+		    data[1] == 0xd8) {
+			gspca_frame_add(gspca_dev, LAST_PACKET,
+					NULL, 0);
+			gspca_frame_add(gspca_dev, FIRST_PACKET,
+					sd->jpeg_hdr, JPEG_HDR_SZ);
+			/* Strip the ff d8, our own header (which adds
+			   huffman and quantization tables) already has this */
+			len -= 2;
+			data += 2;
+		}
+	} else {
+		/* In UYVY mode an empty packet signals EOF */
+		if (gspca_dev->empty_packet) {
+			gspca_frame_add(gspca_dev, LAST_PACKET,
+						NULL, 0);
+			gspca_frame_add(gspca_dev, FIRST_PACKET,
+					NULL, 0);
+			gspca_dev->empty_packet = 0;
+		}
+	}
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
+}
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index cdf3357..69e5dc4 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -61,17 +61,18 @@
 #define SENSOR_HV7131C 6
 #define SENSOR_ICM105A 7
 #define SENSOR_MC501CB 8
-#define SENSOR_OV7620 9
-/*#define SENSOR_OV7648 9 - same values */
-#define SENSOR_OV7630C 10
-#define SENSOR_PAS106 11
-#define SENSOR_PAS202B 12
-#define SENSOR_PB0330 13
-#define SENSOR_PO2030 14
-#define SENSOR_TAS5130CK 15
-#define SENSOR_TAS5130CXX 16
-#define SENSOR_TAS5130C_VF0250 17
-#define SENSOR_MAX 18
+#define SENSOR_MI0360SOC 9
+#define SENSOR_OV7620 10
+/*#define SENSOR_OV7648 10 - same values */
+#define SENSOR_OV7630C 11
+#define SENSOR_PAS106 12
+#define SENSOR_PAS202B 13
+#define SENSOR_PB0330 14	/* (MI0360) */
+#define SENSOR_PO2030 15
+#define SENSOR_TAS5130CK 16
+#define SENSOR_TAS5130CXX 17
+#define SENSOR_TAS5130C_VF0250 18
+#define SENSOR_MAX 19
 	unsigned short chip_revision;
 
 	u8 *jpeg_hdr;
@@ -420,9 +421,7 @@
 	{0xaa, 0xfe, 0x0010},				/* 00,fe,10,aa */
 	{}
 };
-static const struct usb_action cs2102_Initial[] = {
-	{0xa1, 0x01, 0x0008},
-	{0xa1, 0x01, 0x0008},
+static const struct usb_action cs2102_Initial[] = {	/* 320x240 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -471,88 +470,10 @@
 	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
 	{0xa0, 0x68, ZC3XX_R18D_YTARGET},
 	{0xa0, 0x00, 0x01ad},
-	{0xa1, 0x01, 0x0002},
-	{0xa1, 0x01, 0x0008},
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* 00 */
-	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},	/* sharpness+ */
-	{0xa1, 0x01, 0x01c8},
-	{0xa1, 0x01, 0x01c9},
-	{0xa1, 0x01, 0x01ca},
-	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},	/* sharpness- */
-	{0xa0, 0x24, ZC3XX_R120_GAMMA00},	/* gamma 5 */
-	{0xa0, 0x44, ZC3XX_R121_GAMMA01},
-	{0xa0, 0x64, ZC3XX_R122_GAMMA02},
-	{0xa0, 0x84, ZC3XX_R123_GAMMA03},
-	{0xa0, 0x9d, ZC3XX_R124_GAMMA04},
-	{0xa0, 0xb2, ZC3XX_R125_GAMMA05},
-	{0xa0, 0xc4, ZC3XX_R126_GAMMA06},
-	{0xa0, 0xd3, ZC3XX_R127_GAMMA07},
-	{0xa0, 0xe0, ZC3XX_R128_GAMMA08},
-	{0xa0, 0xeb, ZC3XX_R129_GAMMA09},
-	{0xa0, 0xf4, ZC3XX_R12A_GAMMA0A},
-	{0xa0, 0xfb, ZC3XX_R12B_GAMMA0B},
-	{0xa0, 0xff, ZC3XX_R12C_GAMMA0C},
-	{0xa0, 0xff, ZC3XX_R12D_GAMMA0D},
-	{0xa0, 0xff, ZC3XX_R12E_GAMMA0E},
-	{0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
-	{0xa0, 0x18, ZC3XX_R130_GAMMA10},
-	{0xa0, 0x20, ZC3XX_R131_GAMMA11},
-	{0xa0, 0x20, ZC3XX_R132_GAMMA12},
-	{0xa0, 0x1c, ZC3XX_R133_GAMMA13},
-	{0xa0, 0x16, ZC3XX_R134_GAMMA14},
-	{0xa0, 0x13, ZC3XX_R135_GAMMA15},
-	{0xa0, 0x10, ZC3XX_R136_GAMMA16},
-	{0xa0, 0x0e, ZC3XX_R137_GAMMA17},
-	{0xa0, 0x0b, ZC3XX_R138_GAMMA18},
-	{0xa0, 0x09, ZC3XX_R139_GAMMA19},
-	{0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
-	{0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
-	{0xa0, 0x00, ZC3XX_R13C_GAMMA1C},
-	{0xa0, 0x00, ZC3XX_R13D_GAMMA1D},
-	{0xa0, 0x00, ZC3XX_R13E_GAMMA1E},
-	{0xa0, 0x01, ZC3XX_R13F_GAMMA1F},
-	{0xa0, 0x58, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xf4, ZC3XX_R10B_RGB01},
-	{0xa0, 0xf4, ZC3XX_R10C_RGB02},
-	{0xa0, 0xf4, ZC3XX_R10D_RGB10},
-	{0xa0, 0x58, ZC3XX_R10E_RGB11},
-	{0xa0, 0xf4, ZC3XX_R10F_RGB12},
-	{0xa0, 0xf4, ZC3XX_R110_RGB20},
-	{0xa0, 0xf4, ZC3XX_R111_RGB21},
-	{0xa0, 0x58, ZC3XX_R112_RGB22},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
-	{0xaa, 0x23, 0x0001},
-	{0xaa, 0x24, 0x0055},
-	{0xaa, 0x25, 0x00cc},
-	{0xaa, 0x21, 0x003f},
-	{0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH},
-	{0xa0, 0xab, ZC3XX_R191_EXPOSURELIMITMID},
-	{0xa0, 0x98, ZC3XX_R192_EXPOSURELIMITLOW},
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
-	{0xa0, 0x30, ZC3XX_R196_ANTIFLICKERMID},
-	{0xa0, 0xd4, ZC3XX_R197_ANTIFLICKERLOW},
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
-	{0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
-	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
-	{0xa0, 0x39, ZC3XX_R01D_HSYNC_0},
-	{0xa0, 0x70, ZC3XX_R01E_HSYNC_1},
-	{0xa0, 0xb0, ZC3XX_R01F_HSYNC_2},
-	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
-	{0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x40, ZC3XX_R116_RGAIN},
-	{0xa0, 0x40, ZC3XX_R117_GGAIN},
-	{0xa0, 0x40, ZC3XX_R118_BGAIN},
 	{}
 };
 
-static const struct usb_action cs2102_InitialScale[] = {
-	{0xa1, 0x01, 0x0008},
-	{0xa1, 0x01, 0x0008},
+static const struct usb_action cs2102_InitialScale[] = {	/* 640x480 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -601,57 +522,75 @@
 	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
 	{0xa0, 0x68, ZC3XX_R18D_YTARGET},
 	{0xa0, 0x00, 0x01ad},
-	{0xa1, 0x01, 0x0002},
-	{0xa1, 0x01, 0x0008},
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* 00 */
-	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},	/* sharpness+ */
-	{0xa1, 0x01, 0x01c8},
-	{0xa1, 0x01, 0x01c9},
-	{0xa1, 0x01, 0x01ca},
-	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},	/* sharpness- */
-	{0xa0, 0x24, ZC3XX_R120_GAMMA00},	/* gamma 5 */
-	{0xa0, 0x44, ZC3XX_R121_GAMMA01},
-	{0xa0, 0x64, ZC3XX_R122_GAMMA02},
-	{0xa0, 0x84, ZC3XX_R123_GAMMA03},
-	{0xa0, 0x9d, ZC3XX_R124_GAMMA04},
-	{0xa0, 0xb2, ZC3XX_R125_GAMMA05},
-	{0xa0, 0xc4, ZC3XX_R126_GAMMA06},
-	{0xa0, 0xd3, ZC3XX_R127_GAMMA07},
-	{0xa0, 0xe0, ZC3XX_R128_GAMMA08},
-	{0xa0, 0xeb, ZC3XX_R129_GAMMA09},
-	{0xa0, 0xf4, ZC3XX_R12A_GAMMA0A},
-	{0xa0, 0xfb, ZC3XX_R12B_GAMMA0B},
-	{0xa0, 0xff, ZC3XX_R12C_GAMMA0C},
-	{0xa0, 0xff, ZC3XX_R12D_GAMMA0D},
-	{0xa0, 0xff, ZC3XX_R12E_GAMMA0E},
-	{0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
-	{0xa0, 0x18, ZC3XX_R130_GAMMA10},
-	{0xa0, 0x20, ZC3XX_R131_GAMMA11},
-	{0xa0, 0x20, ZC3XX_R132_GAMMA12},
-	{0xa0, 0x1c, ZC3XX_R133_GAMMA13},
-	{0xa0, 0x16, ZC3XX_R134_GAMMA14},
-	{0xa0, 0x13, ZC3XX_R135_GAMMA15},
-	{0xa0, 0x10, ZC3XX_R136_GAMMA16},
-	{0xa0, 0x0e, ZC3XX_R137_GAMMA17},
-	{0xa0, 0x0b, ZC3XX_R138_GAMMA18},
-	{0xa0, 0x09, ZC3XX_R139_GAMMA19},
-	{0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
-	{0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
-	{0xa0, 0x00, ZC3XX_R13C_GAMMA1C},
-	{0xa0, 0x00, ZC3XX_R13D_GAMMA1D},
-	{0xa0, 0x00, ZC3XX_R13E_GAMMA1E},
-	{0xa0, 0x01, ZC3XX_R13F_GAMMA1F},
-	{0xa0, 0x58, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xf4, ZC3XX_R10B_RGB01},
-	{0xa0, 0xf4, ZC3XX_R10C_RGB02},
-	{0xa0, 0xf4, ZC3XX_R10D_RGB10},
-	{0xa0, 0x58, ZC3XX_R10E_RGB11},
-	{0xa0, 0xf4, ZC3XX_R10F_RGB12},
-	{0xa0, 0xf4, ZC3XX_R110_RGB20},
-	{0xa0, 0xf4, ZC3XX_R111_RGB21},
-	{0xa0, 0x58, ZC3XX_R112_RGB22},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+	{}
+};
+static const struct usb_action cs2102_50HZ[] = {
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xaa, 0x23, 0x0001},
+	{0xaa, 0x24, 0x005f},
+	{0xaa, 0x25, 0x0090},
+	{0xaa, 0x21, 0x00dd},
+	{0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0xbf, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x3a, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x98, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0xdd, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0xe4, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0xf0, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+	{}
+};
+static const struct usb_action cs2102_50HZScale[] = {
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xaa, 0x23, 0x0000},
+	{0xaa, 0x24, 0x00af},
+	{0xaa, 0x25, 0x00c8},
+	{0xaa, 0x21, 0x0068},
+	{0xa0, 0x01, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x5f, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x90, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x1d, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x4c, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x68, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0xe3, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0xf0, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+	{}
+};
+static const struct usb_action cs2102_60HZ[] = {
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xaa, 0x23, 0x0001},
+	{0xaa, 0x24, 0x0055},
+	{0xaa, 0x25, 0x00cc},
+	{0xaa, 0x21, 0x003f},
+	{0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0xab, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x98, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x30, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0xd4, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x39, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x70, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0xb0, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+	{}
+};
+static const struct usb_action cs2102_60HZScale[] = {
 	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
 	{0xaa, 0x23, 0x0000},
 	{0xaa, 0x24, 0x00aa},
@@ -671,162 +610,50 @@
 	{0xa0, 0xa5, ZC3XX_R01E_HSYNC_1},
 	{0xa0, 0xf0, ZC3XX_R01F_HSYNC_2},
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
-	{0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x40, ZC3XX_R116_RGAIN},
-	{0xa0, 0x40, ZC3XX_R117_GGAIN},
-	{0xa0, 0x40, ZC3XX_R118_BGAIN},
-	{}
-};
-static const struct usb_action cs2102_50HZ[] = {
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xaa, 0x0f, 0x008c}, /* 00,0f,8c,aa */
-	{0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
-	{0xaa, 0x04, 0x00ac}, /* 00,04,ac,aa */
-	{0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
-	{0xaa, 0x11, 0x00ac}, /* 00,11,ac,aa */
-	{0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
-	{0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
-	{0xaa, 0x1d, 0x00ac}, /* 00,1d,ac,aa */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
-	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x42, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,42,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
-	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
-	{0xa0, 0x8c, ZC3XX_R01D_HSYNC_0}, /* 00,1d,8c,cc */
-	{0xa0, 0xb0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,b0,cc */
-	{0xa0, 0xd0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,d0,cc */
-	{}
-};
-static const struct usb_action cs2102_50HZScale[] = {
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xaa, 0x0f, 0x0093}, /* 00,0f,93,aa */
-	{0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
-	{0xaa, 0x04, 0x00a1}, /* 00,04,a1,aa */
-	{0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
-	{0xaa, 0x11, 0x00a1}, /* 00,11,a1,aa */
-	{0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
-	{0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
-	{0xaa, 0x1d, 0x00a1}, /* 00,1d,a1,aa */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
-	{0xa0, 0xf7, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f7,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x83, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,83,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
-	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
-	{0xa0, 0x93, ZC3XX_R01D_HSYNC_0}, /* 00,1d,93,cc */
-	{0xa0, 0xb0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,b0,cc */
-	{0xa0, 0xd0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,d0,cc */
-	{}
-};
-static const struct usb_action cs2102_60HZ[] = {
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xaa, 0x0f, 0x005d}, /* 00,0f,5d,aa */
-	{0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
-	{0xaa, 0x04, 0x00aa}, /* 00,04,aa,aa */
-	{0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
-	{0xaa, 0x11, 0x00aa}, /* 00,11,aa,aa */
-	{0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
-	{0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
-	{0xaa, 0x1d, 0x00aa}, /* 00,1d,aa,aa */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
-	{0xa0, 0xe4, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e4,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3a,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
-	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
-	{0xa0, 0x5d, ZC3XX_R01D_HSYNC_0}, /* 00,1d,5d,cc */
-	{0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
-	{0xa0, 0xd0, 0x00c8}, /* 00,c8,d0,cc */
-	{}
-};
-static const struct usb_action cs2102_60HZScale[] = {
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xaa, 0x0f, 0x00b7}, /* 00,0f,b7,aa */
-	{0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
-	{0xaa, 0x04, 0x00be}, /* 00,04,be,aa */
-	{0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
-	{0xaa, 0x11, 0x00be}, /* 00,11,be,aa */
-	{0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
-	{0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
-	{0xaa, 0x1d, 0x00be}, /* 00,1d,be,aa */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
-	{0xa0, 0xfc, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,fc,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x69, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,69,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
-	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
-	{0xa0, 0xb7, ZC3XX_R01D_HSYNC_0}, /* 00,1d,b7,cc */
-	{0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */
-	{0xa0, 0xe8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e8,cc */
 	{}
 };
 static const struct usb_action cs2102_NoFliker[] = {
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xaa, 0x0f, 0x0059}, /* 00,0f,59,aa */
-	{0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
-	{0xaa, 0x04, 0x0080}, /* 00,04,80,aa */
-	{0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
-	{0xaa, 0x11, 0x0080}, /* 00,11,80,aa */
-	{0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
-	{0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
-	{0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
-	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
-	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
-	{0xa0, 0x59, ZC3XX_R01D_HSYNC_0}, /* 00,1d,59,cc */
-	{0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
-	{0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xaa, 0x23, 0x0001},
+	{0xaa, 0x24, 0x005f},
+	{0xaa, 0x25, 0x0000},
+	{0xaa, 0x21, 0x0001},
+	{0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0xbf, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x80, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x01, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x40, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0xa0, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
 	{}
 };
 static const struct usb_action cs2102_NoFlikerScale[] = {
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xaa, 0x0f, 0x0059}, /* 00,0f,59,aa */
-	{0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
-	{0xaa, 0x04, 0x0080}, /* 00,04,80,aa */
-	{0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
-	{0xaa, 0x11, 0x0080}, /* 00,11,80,aa */
-	{0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
-	{0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
-	{0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
-	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
-	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
-	{0xa0, 0x59, ZC3XX_R01D_HSYNC_0}, /* 00,1d,59,cc */
-	{0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
-	{0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xaa, 0x23, 0x0000},
+	{0xaa, 0x24, 0x00af},
+	{0xaa, 0x25, 0x0080},
+	{0xaa, 0x21, 0x0001},
+	{0xa0, 0x01, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x5f, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x80, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x80, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x01, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x40, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0xa0, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
 	{}
 };
 
@@ -4409,153 +4236,8 @@
 	{}
 };
 
-static const struct usb_action pb03303x_Initial[] = {
-	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
-	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
-	{0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
-	{0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
-	{0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
-	{0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
-	{0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
-	{0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},	/* 8b -> dc */
-	{0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
-	{0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
-	{0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
-	{0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
-	{0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
-	{0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
-	{0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
-	{0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
-	{0xaa, 0x01, 0x0001},
-	{0xaa, 0x06, 0x0000},
-	{0xaa, 0x08, 0x0483},
-	{0xaa, 0x01, 0x0004},
-	{0xaa, 0x08, 0x0006},
-	{0xaa, 0x02, 0x0011},
-	{0xaa, 0x03, 0x01e7},
-	{0xaa, 0x04, 0x0287},
-	{0xaa, 0x07, 0x3002},
-	{0xaa, 0x20, 0x1100},
-	{0xaa, 0x35, 0x0050},
-	{0xaa, 0x30, 0x0005},
-	{0xaa, 0x31, 0x0000},
-	{0xaa, 0x58, 0x0078},
-	{0xaa, 0x62, 0x0411},
-	{0xaa, 0x2b, 0x0028},
-	{0xaa, 0x2c, 0x0030},
-	{0xaa, 0x2d, 0x0030},
-	{0xaa, 0x2e, 0x0028},
-	{0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},
-	{0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
-	{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
-	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
-	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
-	{0xa0, 0x00, 0x01ad},
-	{0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
-	{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
-	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
-	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
-	{0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
-	{0xa0, 0x78, ZC3XX_R18D_YTARGET},
-	{0xa0, 0x61, ZC3XX_R116_RGAIN},
-	{0xa0, 0x65, ZC3XX_R118_BGAIN},
-
-	{0xa1, 0x01, 0x0002},
-	{0xa0, 0x09, 0x01ad},
-	{0xa0, 0x15, 0x01ae},
-	{0xa0, 0x0d, 0x003a},
-	{0xa0, 0x02, 0x003b},
-	{0xa0, 0x00, 0x0038},
-	{0xa0, 0x50, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xf8, ZC3XX_R10B_RGB01},
-	{0xa0, 0xf8, ZC3XX_R10C_RGB02},
-	{0xa0, 0xf8, ZC3XX_R10D_RGB10},
-	{0xa0, 0x50, ZC3XX_R10E_RGB11},
-	{0xa0, 0xf8, ZC3XX_R10F_RGB12},
-	{0xa0, 0xf8, ZC3XX_R110_RGB20},
-	{0xa0, 0xf8, ZC3XX_R111_RGB21},
-	{0xa0, 0x50, ZC3XX_R112_RGB22},
-
-	{0xa1, 0x01, 0x0008},
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
-	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},
-	{0xa1, 0x01, 0x01c8},
-	{0xa1, 0x01, 0x01c9},
-	{0xa1, 0x01, 0x01ca},
-	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},	/* sharpness- */
-	{0xa0, 0x13, ZC3XX_R120_GAMMA00},	/* gamma 4 */
-	{0xa0, 0x38, ZC3XX_R121_GAMMA01},
-	{0xa0, 0x59, ZC3XX_R122_GAMMA02},
-	{0xa0, 0x79, ZC3XX_R123_GAMMA03},
-	{0xa0, 0x92, ZC3XX_R124_GAMMA04},
-	{0xa0, 0xa7, ZC3XX_R125_GAMMA05},
-	{0xa0, 0xb9, ZC3XX_R126_GAMMA06},
-	{0xa0, 0xc8, ZC3XX_R127_GAMMA07},
-	{0xa0, 0xd4, ZC3XX_R128_GAMMA08},
-	{0xa0, 0xdf, ZC3XX_R129_GAMMA09},
-	{0xa0, 0xe7, ZC3XX_R12A_GAMMA0A},
-	{0xa0, 0xee, ZC3XX_R12B_GAMMA0B},
-	{0xa0, 0xf4, ZC3XX_R12C_GAMMA0C},
-	{0xa0, 0xf9, ZC3XX_R12D_GAMMA0D},
-	{0xa0, 0xfc, ZC3XX_R12E_GAMMA0E},
-	{0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
-	{0xa0, 0x26, ZC3XX_R130_GAMMA10},
-	{0xa0, 0x22, ZC3XX_R131_GAMMA11},
-	{0xa0, 0x20, ZC3XX_R132_GAMMA12},
-	{0xa0, 0x1c, ZC3XX_R133_GAMMA13},
-	{0xa0, 0x16, ZC3XX_R134_GAMMA14},
-	{0xa0, 0x13, ZC3XX_R135_GAMMA15},
-	{0xa0, 0x10, ZC3XX_R136_GAMMA16},
-	{0xa0, 0x0d, ZC3XX_R137_GAMMA17},
-	{0xa0, 0x0b, ZC3XX_R138_GAMMA18},
-	{0xa0, 0x09, ZC3XX_R139_GAMMA19},
-	{0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
-	{0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
-	{0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
-	{0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
-	{0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
-	{0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
-	{0xa0, 0x50, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xf8, ZC3XX_R10B_RGB01},
-	{0xa0, 0xf8, ZC3XX_R10C_RGB02},
-	{0xa0, 0xf8, ZC3XX_R10D_RGB10},
-	{0xa0, 0x50, ZC3XX_R10E_RGB11},
-	{0xa0, 0xf8, ZC3XX_R10F_RGB12},
-	{0xa0, 0xf8, ZC3XX_R110_RGB20},
-	{0xa0, 0xf8, ZC3XX_R111_RGB21},
-	{0xa0, 0x50, ZC3XX_R112_RGB22},
-
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
-	{0xaa, 0x05, 0x0009},
-	{0xaa, 0x09, 0x0134},
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
-	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
-	{0xa0, 0xec, ZC3XX_R192_EXPOSURELIMITLOW},
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
-	{0xa0, 0x9c, ZC3XX_R197_ANTIFLICKERLOW},
-	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
-	{0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
-	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
-	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
-	{0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
-	{0xa0, 0xf4, ZC3XX_R01E_HSYNC_1},
-	{0xa0, 0xf9, ZC3XX_R01F_HSYNC_2},
-	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
-	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x09, 0x01ad},
-	{0xa0, 0x15, 0x01ae},
-	{0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
-	{}
-};
-
-static const struct usb_action pb03303x_InitialScale[] = {
+/* mi0360soc and pb0330 from vm30x.inf for 0ac8:301b and 0ac8:303b 07/02/13 */
+static const struct usb_action mi0360soc_Initial[] = {	/* 640x480 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
 	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
@@ -4564,15 +4246,70 @@
 	{0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
 	{0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
 	{0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
-	{0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},	/* 8b -> dc */
+	{0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
 	{0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
-	{0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
-	{0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
+	{0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC},	/*jfm: was 03*/
+/*	{0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, */
 	{0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
 	{0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
 	{0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
 	{0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
 	{0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
+	{0xdd, 0x00, 0x0200},
+	{0xaa, 0x01, 0x0001},
+	{0xaa, 0x06, 0x0000},
+	{0xaa, 0x08, 0x0483},
+	{0xaa, 0x01, 0x0004},
+	{0xaa, 0x08, 0x0006},
+	{0xaa, 0x02, 0x0011},
+	{0xaa, 0x03, 0x01e5},			/*jfm: was 01e7*/
+	{0xaa, 0x04, 0x0285},			/*jfm: was 0287*/
+	{0xaa, 0x07, 0x3002},
+	{0xaa, 0x20, 0x5100},			/*jfm: was 1100*/
+	{0xaa, 0x35, 0x507f},			/*jfm: was 0050*/
+	{0xaa, 0x30, 0x0005},
+	{0xaa, 0x31, 0x0000},
+	{0xaa, 0x58, 0x0078},
+	{0xaa, 0x62, 0x0411},
+	{0xaa, 0x2b, 0x0028},
+	{0xaa, 0x2c, 0x007f},			/*jfm: was 0030*/
+	{0xaa, 0x2d, 0x007f},			/*jfm: was 0030*/
+	{0xaa, 0x2e, 0x007f},			/*jfm: was 0030*/
+	{0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},
+	{0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /*jfm: was 37*/
+	{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+	{0xa0, 0x09, 0x01ad},			/*jfm: was 00*/
+	{0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+	{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+	{0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
+	{0xa0, 0x6c, ZC3XX_R18D_YTARGET},	/* jfm: was 78 */
+	{0xa0, 0x61, ZC3XX_R116_RGAIN},
+	{0xa0, 0x65, ZC3XX_R118_BGAIN},
+	{}
+};
+static const struct usb_action mi0360soc_InitialScale[] = {	/* 320x240 */
+	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
+	{0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
+	{0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+	{0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+	{0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+	{0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+	{0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
+	{0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+	{0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC},	/*jfm: was 03*/
+/*	{0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, */
+	{0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
+	{0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
+	{0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+	{0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+	{0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
+	{0xdd, 0x00, 0x0200},
 	{0xaa, 0x01, 0x0001},
 	{0xaa, 0x06, 0x0000},
 	{0xaa, 0x08, 0x0483},
@@ -4582,111 +4319,111 @@
 	{0xaa, 0x03, 0x01e7},
 	{0xaa, 0x04, 0x0287},
 	{0xaa, 0x07, 0x3002},
-	{0xaa, 0x20, 0x1100},
-	{0xaa, 0x35, 0x0050},
+	{0xaa, 0x20, 0x5100},			/*jfm: was 1100*/
+	{0xaa, 0x35, 0x007f},			/*jfm: was 0050*/
 	{0xaa, 0x30, 0x0005},
 	{0xaa, 0x31, 0x0000},
 	{0xaa, 0x58, 0x0078},
 	{0xaa, 0x62, 0x0411},
-	{0xaa, 0x2b, 0x0028},
-	{0xaa, 0x2c, 0x0030},
-	{0xaa, 0x2d, 0x0030},
-	{0xaa, 0x2e, 0x0028},
+	{0xaa, 0x2b, 0x007f},			/*jfm: was 28*/
+	{0xaa, 0x2c, 0x007f},			/*jfm: was 30*/
+	{0xaa, 0x2d, 0x007f},			/*jfm: was 30*/
+	{0xaa, 0x2e, 0x007f},			/*jfm: was 28*/
 	{0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},
-	{0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
+	{0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION},	/*jfm: was 37*/
 	{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
 	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
 	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
-	{0xa0, 0x00, 0x01ad},
+	{0xa0, 0x09, 0x01ad},			/*jfm: was 00*/
 	{0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
 	{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
 	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
 	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
 	{0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
-	{0xa0, 0x78, ZC3XX_R18D_YTARGET},
+	{0xa0, 0x6c, ZC3XX_R18D_YTARGET},	/*jfm: was 78*/
 	{0xa0, 0x61, ZC3XX_R116_RGAIN},
 	{0xa0, 0x65, ZC3XX_R118_BGAIN},
-
-	{0xa1, 0x01, 0x0002},
-
-	{0xa0, 0x09, 0x01ad},
-	{0xa0, 0x15, 0x01ae},
-
-	{0xa0, 0x0d, 0x003a},
-	{0xa0, 0x02, 0x003b},
-	{0xa0, 0x00, 0x0038},
-	{0xa0, 0x50, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xf8, ZC3XX_R10B_RGB01},
-	{0xa0, 0xf8, ZC3XX_R10C_RGB02},
-	{0xa0, 0xf8, ZC3XX_R10D_RGB10},
-	{0xa0, 0x50, ZC3XX_R10E_RGB11},
-	{0xa0, 0xf8, ZC3XX_R10F_RGB12},
-	{0xa0, 0xf8, ZC3XX_R110_RGB20},
-	{0xa0, 0xf8, ZC3XX_R111_RGB21},
-	{0xa0, 0x50, ZC3XX_R112_RGB22},
-
-	{0xa1, 0x01, 0x0008},
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* clock ? */
-	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},	/* sharpness+ */
-	{0xa1, 0x01, 0x01c8},
-	{0xa1, 0x01, 0x01c9},
-	{0xa1, 0x01, 0x01ca},
-	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},	/* sharpness- */
-
-	{0xa0, 0x13, ZC3XX_R120_GAMMA00},	/* gamma 4 */
-	{0xa0, 0x38, ZC3XX_R121_GAMMA01},
-	{0xa0, 0x59, ZC3XX_R122_GAMMA02},
-	{0xa0, 0x79, ZC3XX_R123_GAMMA03},
-	{0xa0, 0x92, ZC3XX_R124_GAMMA04},
-	{0xa0, 0xa7, ZC3XX_R125_GAMMA05},
-	{0xa0, 0xb9, ZC3XX_R126_GAMMA06},
-	{0xa0, 0xc8, ZC3XX_R127_GAMMA07},
-	{0xa0, 0xd4, ZC3XX_R128_GAMMA08},
-	{0xa0, 0xdf, ZC3XX_R129_GAMMA09},
-	{0xa0, 0xe7, ZC3XX_R12A_GAMMA0A},
-	{0xa0, 0xee, ZC3XX_R12B_GAMMA0B},
-	{0xa0, 0xf4, ZC3XX_R12C_GAMMA0C},
-	{0xa0, 0xf9, ZC3XX_R12D_GAMMA0D},
-	{0xa0, 0xfc, ZC3XX_R12E_GAMMA0E},
-	{0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
-	{0xa0, 0x26, ZC3XX_R130_GAMMA10},
-	{0xa0, 0x22, ZC3XX_R131_GAMMA11},
-	{0xa0, 0x20, ZC3XX_R132_GAMMA12},
-	{0xa0, 0x1c, ZC3XX_R133_GAMMA13},
-	{0xa0, 0x16, ZC3XX_R134_GAMMA14},
-	{0xa0, 0x13, ZC3XX_R135_GAMMA15},
-	{0xa0, 0x10, ZC3XX_R136_GAMMA16},
-	{0xa0, 0x0d, ZC3XX_R137_GAMMA17},
-	{0xa0, 0x0b, ZC3XX_R138_GAMMA18},
-	{0xa0, 0x09, ZC3XX_R139_GAMMA19},
-	{0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
-	{0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
-	{0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
-	{0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
-	{0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
-	{0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
-	{0xa0, 0x50, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xf8, ZC3XX_R10B_RGB01},
-	{0xa0, 0xf8, ZC3XX_R10C_RGB02},
-	{0xa0, 0xf8, ZC3XX_R10D_RGB10},
-	{0xa0, 0x50, ZC3XX_R10E_RGB11},
-	{0xa0, 0xf8, ZC3XX_R10F_RGB12},
-	{0xa0, 0xf8, ZC3XX_R110_RGB20},
-	{0xa0, 0xf8, ZC3XX_R111_RGB21},
-	{0xa0, 0x50, ZC3XX_R112_RGB22},
-
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+	{}
+};
+static const struct usb_action mi360soc_AE50HZ[] = {
 	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
 	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
-	{0xaa, 0x05, 0x0009},
-	{0xaa, 0x09, 0x0134},
+	{0xbb, 0x00, 0x0562},
+	{0xbb, 0x01, 0x09aa},
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
-	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
-	{0xa0, 0xec, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x9b, ZC3XX_R192_EXPOSURELIMITLOW},
 	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
 	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
-	{0xa0, 0x9c, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x62, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x90, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0xc8, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+	{}
+};
+static const struct usb_action mi360soc_AE50HZScale[] = {
+	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xbb, 0x00, 0x0509},
+	{0xbb, 0x01, 0x0934},
+	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xd2, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x9a, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0xf4, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0xf9, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+	{}
+};
+static const struct usb_action mi360soc_AE60HZ[] = {
+	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xbb, 0x00, 0x053d},
+	{0xbb, 0x01, 0x096e},
+	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xdd, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x62, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x90, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0xc8, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+	{}
+};
+static const struct usb_action mi360soc_AE60HZScale[] = {
+	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xbb, 0x00, 0x0509},
+	{0xbb, 0x01, 0x0983},
+	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x8f, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW},
 	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
 	{0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
 	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
@@ -4696,16 +4433,105 @@
 	{0xa0, 0xf9, ZC3XX_R01F_HSYNC_2},
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
 	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x09, 0x01ad},
-	{0xa0, 0x15, 0x01ae},
-	{0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa1, 0x01, 0x0180},
+	{}
+};
+static const struct usb_action mi360soc_AENoFliker[] = {
+	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xbb, 0x00, 0x0509},
+	{0xbb, 0x01, 0x0960},
+	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x09, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x40, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
+	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
 	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
 	{}
 };
-static const struct usb_action pb0330xx_Initial[] = {
-	{0xa1, 0x01, 0x0008},
-	{0xa1, 0x01, 0x0008},
+static const struct usb_action mi360soc_AENoFlikerScale[] = {
+	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xbb, 0x00, 0x0534},
+	{0xbb, 0x02, 0x0960},
+	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x34, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x60, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
+	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+	{}
+};
+
+static const struct usb_action pb0330_Initial[] = {	/* 640x480 */
+	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* 00 */
+	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
+	{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
+	{0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+	{0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+	{0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+	{0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+	{0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+	{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+	{0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC},
+	{0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
+	{0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
+	{0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+	{0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+	{0xdd, 0x00, 0x0200},
+	{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+	{0xaa, 0x01, 0x0006},
+	{0xaa, 0x02, 0x0011},
+	{0xaa, 0x03, 0x01e5},			/*jfm: was 1e7*/
+	{0xaa, 0x04, 0x0285},			/*jfm: was 0287*/
+	{0xaa, 0x06, 0x0003},
+	{0xaa, 0x07, 0x3002},
+	{0xaa, 0x20, 0x1100},
+	{0xaa, 0x2f, 0xf7b0},
+	{0xaa, 0x30, 0x0005},
+	{0xaa, 0x31, 0x0000},
+	{0xaa, 0x34, 0x0100},
+	{0xaa, 0x35, 0x0060},
+	{0xaa, 0x3d, 0x068f},
+	{0xaa, 0x40, 0x01e0},
+	{0xaa, 0x58, 0x0078},
+	{0xaa, 0x62, 0x0411},
+	{0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},
+	{0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
+	{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+	{0xa0, 0x09, 0x01ad},			/*jfm: was 00 */
+	{0xa0, 0x15, 0x01ae},
+	{0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+	{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+	{0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
+	{0xa0, 0x78, ZC3XX_R18D_YTARGET},	/*jfm: was 6c*/
+	{}
+};
+static const struct usb_action pb0330_InitialScale[] = {	/* 320x240 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* 00 */
 	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
@@ -4721,6 +4547,7 @@
 	{0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
 	{0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
 	{0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+	{0xdd, 0x00, 0x0200},
 	{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
 	{0xaa, 0x01, 0x0006},
 	{0xaa, 0x02, 0x0011},
@@ -4743,293 +4570,146 @@
 	{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
 	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
 	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
-	{0xa0, 0x00, 0x01ad},
+	{0xa0, 0x09, 0x01ad},
+	{0xa0, 0x15, 0x01ae},
 	{0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
 	{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
 	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
 	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
 	{0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
-	{0xa0, 0x6c, ZC3XX_R18D_YTARGET},
-	{0xa1, 0x01, 0x0002},
-	{0xa0, 0x09, 0x01ad},
-	{0xa0, 0x15, 0x01ae},
-	{0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x02, ZC3XX_R090_I2CCOMMAND},
-	{0xa1, 0x01, 0x0091},
-	{0xa1, 0x01, 0x0095},
-	{0xa1, 0x01, 0x0096},
-	{0xa0, 0x50, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xf8, ZC3XX_R10B_RGB01},
-	{0xa0, 0xf8, ZC3XX_R10C_RGB02},
-	{0xa0, 0xf8, ZC3XX_R10D_RGB10},
-	{0xa0, 0x50, ZC3XX_R10E_RGB11},
-	{0xa0, 0xf8, ZC3XX_R10F_RGB12},
-	{0xa0, 0xf8, ZC3XX_R110_RGB20},
-	{0xa0, 0xf8, ZC3XX_R111_RGB21},
-	{0xa0, 0x50, ZC3XX_R112_RGB22},
-	{0xa1, 0x01, 0x0008},
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* clock ? */
-	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},	/* sharpness+ */
-	{0xa1, 0x01, 0x01c8},
-	{0xa1, 0x01, 0x01c9},
-	{0xa1, 0x01, 0x01ca},
-	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},	/* sharpness- */
-
-	{0xa0, 0x50, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xf8, ZC3XX_R10B_RGB01},
-	{0xa0, 0xf8, ZC3XX_R10C_RGB02},
-	{0xa0, 0xf8, ZC3XX_R10D_RGB10},
-	{0xa0, 0x50, ZC3XX_R10E_RGB11},
-	{0xa0, 0xf8, ZC3XX_R10F_RGB12},
-	{0xa0, 0xf8, ZC3XX_R110_RGB20},
-	{0xa0, 0xf8, ZC3XX_R111_RGB21},
-	{0xa0, 0x50, ZC3XX_R112_RGB22},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
-	{0xaa, 0x05, 0x0066},
-	{0xaa, 0x09, 0x02b2},
-	{0xaa, 0x10, 0x0002},
-
-	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
-	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
-	{0xa0, 0x8c, ZC3XX_R192_EXPOSURELIMITLOW},
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
-	{0xa0, 0x8a, ZC3XX_R197_ANTIFLICKERLOW},
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
-	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
-	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
-	{0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
-	{0xa0, 0xf0, ZC3XX_R01E_HSYNC_1},
-	{0xa0, 0xf8, ZC3XX_R01F_HSYNC_2},
-	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
-	{0xa0, 0x09, 0x01ad},
-	{0xa0, 0x15, 0x01ae},
-	{0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa1, 0x01, 0x0008},
-	{0xa1, 0x01, 0x0007},
-/*	{0xa0, 0x30, 0x0007}, */
-/*	{0xa0, 0x00, 0x0007}, */
-	{}
-};
-
-static const struct usb_action pb0330xx_InitialScale[] = {
-	{0xa1, 0x01, 0x0008},
-	{0xa1, 0x01, 0x0008},
-	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* 00 */
-	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
-	{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},	/* 10 */
-	{0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
-	{0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
-	{0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
-	{0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
-	{0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
-	{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
-	{0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC},
-	{0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
-	{0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
-	{0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
-	{0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
-	{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
-	{0xaa, 0x01, 0x0006},
-	{0xaa, 0x02, 0x0011},
-	{0xaa, 0x03, 0x01e7},
-	{0xaa, 0x04, 0x0287},
-	{0xaa, 0x06, 0x0003},
-	{0xaa, 0x07, 0x3002},
-	{0xaa, 0x20, 0x1100},
-	{0xaa, 0x2f, 0xf7b0},
-	{0xaa, 0x30, 0x0005},
-	{0xaa, 0x31, 0x0000},
-	{0xaa, 0x34, 0x0100},
-	{0xaa, 0x35, 0x0060},
-	{0xaa, 0x3d, 0x068f},
-	{0xaa, 0x40, 0x01e0},
-	{0xaa, 0x58, 0x0078},
-	{0xaa, 0x62, 0x0411},
-	{0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},
-	{0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
-	{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
-	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
-	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
-	{0xa0, 0x00, 0x01ad},
-	{0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
-	{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
-	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
-	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
-	{0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
-	{0xa0, 0x6c, ZC3XX_R18D_YTARGET},
-	{0xa1, 0x01, 0x0002},
-	{0xa0, 0x09, 0x01ad},
-	{0xa0, 0x15, 0x01ae},
-	{0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x02, ZC3XX_R090_I2CCOMMAND},
-	{0xa1, 0x01, 0x0091},
-	{0xa1, 0x01, 0x0095},
-	{0xa1, 0x01, 0x0096},
-	{0xa0, 0x50, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xf8, ZC3XX_R10B_RGB01},
-	{0xa0, 0xf8, ZC3XX_R10C_RGB02},
-	{0xa0, 0xf8, ZC3XX_R10D_RGB10},
-	{0xa0, 0x50, ZC3XX_R10E_RGB11},
-	{0xa0, 0xf8, ZC3XX_R10F_RGB12},
-	{0xa0, 0xf8, ZC3XX_R110_RGB20},
-	{0xa0, 0xf8, ZC3XX_R111_RGB21},
-	{0xa0, 0x50, ZC3XX_R112_RGB22},
-	{0xa1, 0x01, 0x0008},
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* clock ? */
-	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},	/* sharpness+ */
-	{0xa1, 0x01, 0x01c8},
-	{0xa1, 0x01, 0x01c9},
-	{0xa1, 0x01, 0x01ca},
-	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},	/* sharpness- */
-
-	{0xa0, 0x50, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xf8, ZC3XX_R10B_RGB01},
-	{0xa0, 0xf8, ZC3XX_R10C_RGB02},
-	{0xa0, 0xf8, ZC3XX_R10D_RGB10},
-	{0xa0, 0x50, ZC3XX_R10E_RGB11},
-	{0xa0, 0xf8, ZC3XX_R10F_RGB12},
-	{0xa0, 0xf8, ZC3XX_R110_RGB20},
-	{0xa0, 0xf8, ZC3XX_R111_RGB21},
-	{0xa0, 0x50, ZC3XX_R112_RGB22},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
-	{0xaa, 0x05, 0x0066},
-	{0xaa, 0x09, 0x02b2},
-	{0xaa, 0x10, 0x0002},
-	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
-	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
-	{0xa0, 0x8c, ZC3XX_R192_EXPOSURELIMITLOW},
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
-	{0xa0, 0x8a, ZC3XX_R197_ANTIFLICKERLOW},
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
-	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
-	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
-	{0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
-	{0xa0, 0xf0, ZC3XX_R01E_HSYNC_1},
-	{0xa0, 0xf8, ZC3XX_R01F_HSYNC_2},
-	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
-	{0xa0, 0x09, 0x01ad},
-	{0xa0, 0x15, 0x01ae},
-	{0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa1, 0x01, 0x0008},
-	{0xa1, 0x01, 0x0007},
-/*	{0xa0, 0x30, 0x0007}, */
-/*	{0xa0, 0x00, 0x0007}, */
+	{0xa0, 0x78, ZC3XX_R18D_YTARGET},	/*jfm: was 6c*/
 	{}
 };
 static const struct usb_action pb0330_50HZ[] = {
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
-	{0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,ee,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x46, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,46,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
-	{0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
-	{0xa0, 0x68, ZC3XX_R01D_HSYNC_0}, /* 00,1d,68,cc */
-	{0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
-	{0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xbb, 0x00, 0x055c},
+	{0xbb, 0x01, 0x09aa},
+	{0xbb, 0x00, 0x1001},
+	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xc4, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x5c, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x90, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0xc8, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
 	{}
 };
 static const struct usb_action pb0330_50HZScale[] = {
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
-	{0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,a0,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x7a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7a,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
-	{0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
-	{0xa0, 0xe5, ZC3XX_R01D_HSYNC_0}, /* 00,1d,e5,cc */
-	{0xa0, 0xf0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,f0,cc */
-	{0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f8,cc */
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xbb, 0x00, 0x0566},
+	{0xbb, 0x02, 0x09b2},
+	{0xbb, 0x00, 0x1002},
+	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x8c, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x8a, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0xf0, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0xf8, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
 	{}
 };
 static const struct usb_action pb0330_60HZ[] = {
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
-	{0xa0, 0xdd, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,dd,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3d,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
-	{0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
-	{0xa0, 0x43, ZC3XX_R01D_HSYNC_0}, /* 00,1d,43,cc */
-	{0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */
-	{0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xbb, 0x00, 0x0535},
+	{0xbb, 0x01, 0x0974},
+	{0xbb, 0x00, 0x1001},
+	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xfe, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x3e, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x35, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x50, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xd0, ZC3XX_R020_HSYNC_3},
 	{}
 };
 static const struct usb_action pb0330_60HZScale[] = {
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
-	{0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,a0,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x7a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7a,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
-	{0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
-	{0xa0, 0x41, ZC3XX_R01D_HSYNC_0}, /* 00,1d,41,cc */
-	{0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */
-	{0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xbb, 0x00, 0x0535},
+	{0xbb, 0x02, 0x096c},
+	{0xbb, 0x00, 0x1002},
+	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xc0, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x7c, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x35, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x50, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xd0, ZC3XX_R020_HSYNC_3},
 	{}
 };
 static const struct usb_action pb0330_NoFliker[] = {
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
-	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
-	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
-	{0xa0, 0x09, ZC3XX_R01D_HSYNC_0}, /* 00,1d,09,cc */
-	{0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, /* 00,1e,40,cc */
-	{0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xbb, 0x00, 0x0509},
+	{0xbb, 0x02, 0x0940},
+	{0xbb, 0x00, 0x1002},
+	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x09, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x40, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
 	{}
 };
 static const struct usb_action pb0330_NoFlikerScale[] = {
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
-	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},	/* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},	/* 01,8f,20,cc */
-	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
-	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
-	{0xa0, 0x09, ZC3XX_R01D_HSYNC_0},	/* 00,1d,09,cc */
-	{0xa0, 0x40, ZC3XX_R01E_HSYNC_1},	/* 00,1e,40,cc */
-	{0xa0, 0x90, ZC3XX_R01F_HSYNC_2},	/* 00,1f,90,cc */
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xbb, 0x00, 0x0535},
+	{0xbb, 0x01, 0x0980},
+	{0xbb, 0x00, 0x1001},
+	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x35, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x60, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
 	{}
 };
 
@@ -5655,7 +5335,7 @@
 	{}
 };
 
-static const struct usb_action tas5130cxx_Initial[] = {
+static const struct usb_action tas5130cxx_InitialScale[] = {	/* 320x240 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x50, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
@@ -5684,74 +5364,19 @@
 	{0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION},
 	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
 	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
-	{0xa0, 0x68, ZC3XX_R18D_YTARGET},
-	{0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
+	{0xa0, 0x95, ZC3XX_R18D_YTARGET},
+	{0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN},
 	{0xa0, 0x00, 0x01ad},
 	{0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
 	{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
 	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
 	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
-	{0xa1, 0x01, 0x0002},
-	{0xa1, 0x01, 0x0008},
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* clock ? */
-	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},	/* sharpness+ */
-	{0xa1, 0x01, 0x01c8},
-	{0xa1, 0x01, 0x01c9},
-	{0xa1, 0x01, 0x01ca},
-	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},	/* sharpness- */
-
-	{0xa0, 0x68, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xec, ZC3XX_R10B_RGB01},
-	{0xa0, 0xec, ZC3XX_R10C_RGB02},
-	{0xa0, 0xec, ZC3XX_R10D_RGB10},
-	{0xa0, 0x68, ZC3XX_R10E_RGB11},
-	{0xa0, 0xec, ZC3XX_R10F_RGB12},
-	{0xa0, 0xec, ZC3XX_R110_RGB20},
-	{0xa0, 0xec, ZC3XX_R111_RGB21},
-	{0xa0, 0x68, ZC3XX_R112_RGB22},
-
-	{0xa1, 0x01, 0x018d},
-	{0xa0, 0x90, ZC3XX_R18D_YTARGET},	/* 90 */
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
-
-	{0xaa, 0xa3, 0x0001},
-	{0xaa, 0xa4, 0x0077},
-	{0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH},
-	{0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW},
-
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},	/* 00 */
-	{0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID},	/* 03 */
-	{0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW},	/* e8 */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},	/* 0 */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},	/* 0 */
-	{0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW},	/* 7d */
-
-	{0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
-	{0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
-	{0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},	/* 08 */
-	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},	/* 24 */
-	{0xa0, 0xf0, ZC3XX_R01D_HSYNC_0},
-	{0xa0, 0xf4, ZC3XX_R01E_HSYNC_1},
-	{0xa0, 0xf8, ZC3XX_R01F_HSYNC_2},
-	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
-	{0xa0, 0x03, ZC3XX_R09F_MAXXHIGH},
-	{0xa0, 0xc0, ZC3XX_R0A0_MAXXLOW},
-	{0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},	/* 50 */
-	{0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
 	{}
 };
-static const struct usb_action tas5130cxx_InitialScale[] = {
-/*??	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, */
+static const struct usb_action tas5130cxx_Initial[] = {	/* 640x480 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x40, ZC3XX_R002_CLOCKSELECT},
-
 	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
-	{0xa1, 0x01, 0x0008},
-
 	{0xa0, 0x02, ZC3XX_R010_CMOSSENSORSELECT},
 	{0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
 	{0xa0, 0x00, ZC3XX_R001_SYSTEMOPERATING},
@@ -5775,63 +5400,13 @@
 	{0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
 	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
 	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
-	{0xa0, 0x68, ZC3XX_R18D_YTARGET},
-	{0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
+	{0xa0, 0x95, ZC3XX_R18D_YTARGET},
+	{0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN},
 	{0xa0, 0x00, 0x01ad},
 	{0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
 	{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
 	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
 	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
-	{0xa1, 0x01, 0x0002},
-	{0xa1, 0x01, 0x0008},
-
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
-	{0xa1, 0x01, 0x0008},	/* clock ? */
-	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},	/* sharpness+ */
-	{0xa1, 0x01, 0x01c8},
-	{0xa1, 0x01, 0x01c9},
-	{0xa1, 0x01, 0x01ca},
-	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},	/* sharpness- */
-
-	{0xa0, 0x68, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xec, ZC3XX_R10B_RGB01},
-	{0xa0, 0xec, ZC3XX_R10C_RGB02},
-	{0xa0, 0xec, ZC3XX_R10D_RGB10},
-	{0xa0, 0x68, ZC3XX_R10E_RGB11},
-	{0xa0, 0xec, ZC3XX_R10F_RGB12},
-	{0xa0, 0xec, ZC3XX_R110_RGB20},
-	{0xa0, 0xec, ZC3XX_R111_RGB21},
-	{0xa0, 0x68, ZC3XX_R112_RGB22},
-
-	{0xa1, 0x01, 0x018d},
-	{0xa0, 0x90, ZC3XX_R18D_YTARGET},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
-	{0xaa, 0xa3, 0x0001},
-	{0xaa, 0xa4, 0x0063},
-	{0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH},
-	{0xa0, 0x63, ZC3XX_R0A4_EXPOSURETIMELOW},
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
-	{0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
-	{0xa0, 0x38, ZC3XX_R192_EXPOSURELIMITLOW},
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
-	{0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW},
-	{0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
-	{0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
-	{0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
-	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
-	{0xa0, 0xd3, ZC3XX_R01D_HSYNC_0},
-	{0xa0, 0xda, ZC3XX_R01E_HSYNC_1},
-	{0xa0, 0xea, ZC3XX_R01F_HSYNC_2},
-	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
-	{0xa0, 0x03, ZC3XX_R09F_MAXXHIGH},
-	{0xa0, 0x4c, ZC3XX_R0A0_MAXXLOW},
-	{0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
-	{0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
 	{}
 };
 static const struct usb_action tas5130cxx_50HZ[] = {
@@ -5841,20 +5416,22 @@
 	{0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
 	{0xa0, 0x63, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,63,cc */
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */
-	{0xa0, 0x38, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,38,cc */
+	{0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xfe, ZC3XX_R192_EXPOSURELIMITLOW},
 	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
 	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
 	{0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,47,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
-	{0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
+	{0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
 	{0xa0, 0xd3, ZC3XX_R01D_HSYNC_0}, /* 00,1d,d3,cc */
 	{0xa0, 0xda, ZC3XX_R01E_HSYNC_1}, /* 00,1e,da,cc */
 	{0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ea,cc */
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
 	{0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
+	{0xa0, 0x4c, ZC3XX_R0A0_MAXXLOW},
+	{0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
 	{}
 };
 static const struct usb_action tas5130cxx_50HZScale[] = {
@@ -5864,20 +5441,22 @@
 	{0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
 	{0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */
-	{0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e8,cc */
+	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xd0, ZC3XX_R192_EXPOSURELIMITLOW},
 	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
 	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
 	{0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */
-	{0xa0, 0x14, ZC3XX_R18C_AEFREEZE}, /* 01,8c,14,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
-	{0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
+	{0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
 	{0xa0, 0xf0, ZC3XX_R01D_HSYNC_0}, /* 00,1d,f0,cc */
 	{0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,f4,cc */
 	{0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f8,cc */
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
 	{0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
+	{0xa0, 0xc0, ZC3XX_R0A0_MAXXLOW},
+	{0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
 	{}
 };
 static const struct usb_action tas5130cxx_60HZ[] = {
@@ -5887,20 +5466,22 @@
 	{0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
 	{0xa0, 0x36, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,36,cc */
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x01, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,01,cc */
-	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
+	{0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x54, ZC3XX_R192_EXPOSURELIMITLOW},
 	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
 	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
 	{0xa0, 0x3e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3e,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
-	{0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
+	{0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
 	{0xa0, 0xca, ZC3XX_R01D_HSYNC_0}, /* 00,1d,ca,cc */
 	{0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */
 	{0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
 	{0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
+	{0xa0, 0x28, ZC3XX_R0A0_MAXXLOW},
+	{0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
 	{}
 };
 static const struct usb_action tas5130cxx_60HZScale[] = {
@@ -5910,20 +5491,22 @@
 	{0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
 	{0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */
-	{0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e8,cc */
+	{0xa0, 0x09, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x47, ZC3XX_R192_EXPOSURELIMITLOW},
 	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
 	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
 	{0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */
-	{0xa0, 0x14, ZC3XX_R18C_AEFREEZE}, /* 01,8c,14,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
-	{0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
+	{0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
 	{0xa0, 0xc8, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c8,cc */
 	{0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */
 	{0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
 	{0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
+	{0xa0, 0x20, ZC3XX_R0A0_MAXXLOW},
+	{0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
 	{}
 };
 static const struct usb_action tas5130cxx_NoFliker[] = {
@@ -5933,13 +5516,13 @@
 	{0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
 	{0xa0, 0x40, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,40,cc */
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x01, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,01,cc */
-	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+	{0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
 	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
 	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
 	{0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */
@@ -5947,6 +5530,8 @@
 	{0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
 	{0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */
+	{0xa0, 0xf0, ZC3XX_R0A0_MAXXLOW},
+	{0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
 	{}
 };
 
@@ -5957,13 +5542,13 @@
 	{0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
 	{0xa0, 0x90, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,90,cc */
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */
-	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+	{0xa0, 0x0a, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
 	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
 	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
 	{0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */
@@ -5971,6 +5556,8 @@
 	{0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
 	{0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */
+	{0xa0, 0xf0, ZC3XX_R0A0_MAXXLOW},
+	{0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
 	{}
 };
 
@@ -6303,8 +5890,10 @@
 
 	reg_w_i(gspca_dev->dev, reg, 0x0092);
 	reg_w_i(gspca_dev->dev, 0x02, 0x0090);		/* <- read command */
-	msleep(25);
+	msleep(20);
 	retbyte = reg_r_i(gspca_dev, 0x0091);		/* read status */
+	if (retbyte != 0x00)
+		err("i2c_r status error %02x", retbyte);
 	retval = reg_r_i(gspca_dev, 0x0095);		/* read Lowbyte */
 	retval |= reg_r_i(gspca_dev, 0x0096) << 8;	/* read Hightbyte */
 	PDEBUG(D_USBI, "i2c r [%02x] -> %04x (%02x)",
@@ -6323,8 +5912,10 @@
 	reg_w_i(gspca_dev->dev, valL, 0x93);
 	reg_w_i(gspca_dev->dev, valH, 0x94);
 	reg_w_i(gspca_dev->dev, 0x01, 0x90);		/* <- write command */
-	msleep(15);
+	msleep(1);
 	retbyte = reg_r_i(gspca_dev, 0x0091);		/* read status */
+	if (retbyte != 0x00)
+		err("i2c_w status error %02x", retbyte);
 	PDEBUG(D_USBO, "i2c w [%02x] = %02x%02x (%02x)",
 			reg, valH, valL, retbyte);
 	return retbyte;
@@ -6359,7 +5950,7 @@
 			break;
 		}
 		action++;
-/*		msleep(1); */
+		msleep(1);
 	}
 }
 
@@ -6380,11 +5971,13 @@
 		{0x4c, 0xf5, 0xff, 0xf9, 0x51, 0xf5, 0xfb, 0xed, 0x5f};
 	static const __u8 po2030_matrix[9] =
 		{0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60};
+	static const u8 tas5130c_matrix[9] =
+		{0x68, 0xec, 0xec, 0xec, 0x68, 0xec, 0xec, 0xec, 0x68};
 	static const __u8 vf0250_matrix[9] =
 		{0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b};
 	static const __u8 *matrix_tb[SENSOR_MAX] = {
 		adcm2700_matrix, /* SENSOR_ADCM2700 0 */
-		NULL,		/* SENSOR_CS2102 1 */
+		ov7620_matrix,	/* SENSOR_CS2102 1 */
 		NULL,		/* SENSOR_CS2102K 2 */
 		gc0305_matrix,	/* SENSOR_GC0305 3 */
 		NULL,		/* SENSOR_HDCS2020b 4 */
@@ -6392,15 +5985,16 @@
 		NULL,		/* SENSOR_HV7131C 6 */
 		NULL,		/* SENSOR_ICM105A 7 */
 		NULL,		/* SENSOR_MC501CB 8 */
-		ov7620_matrix,	/* SENSOR_OV7620 9 */
-		NULL,		/* SENSOR_OV7630C 10 */
-		NULL,		/* SENSOR_PAS106 11 */
-		pas202b_matrix,	/* SENSOR_PAS202B 12 */
-		NULL,		/* SENSOR_PB0330 13 */
-		po2030_matrix,	/* SENSOR_PO2030 14 */
-		NULL,		/* SENSOR_TAS5130CK 15 */
-		NULL,		/* SENSOR_TAS5130CXX 16 */
-		vf0250_matrix,	/* SENSOR_TAS5130C_VF0250 17 */
+		gc0305_matrix,	/* SENSOR_MI0360SOC 9 */
+		ov7620_matrix,	/* SENSOR_OV7620 10 */
+		NULL,		/* SENSOR_OV7630C 11 */
+		NULL,		/* SENSOR_PAS106 12 */
+		pas202b_matrix,	/* SENSOR_PAS202B 13 */
+		gc0305_matrix,	/* SENSOR_PB0330 14 */
+		po2030_matrix,	/* SENSOR_PO2030 15 */
+		NULL,		/* SENSOR_TAS5130CK 16 */
+		tas5130c_matrix, /* SENSOR_TAS5130CXX 17 */
+		vf0250_matrix,	/* SENSOR_TAS5130C_VF0250 18 */
 	};
 
 	matrix = matrix_tb[sd->sensor];
@@ -6640,39 +6234,43 @@
 		{MC501CB_NoFliker, MC501CB_NoFlikerScale,
 		 MC501CB_50HZ, MC501CB_50HZScale,
 		 MC501CB_60HZ, MC501CB_60HZScale},
-/* SENSOR_OV7620 9 */
+/* SENSOR_MI0360SOC 9 */
+		{mi360soc_AENoFlikerScale, mi360soc_AENoFliker,
+		 mi360soc_AE50HZScale, mi360soc_AE50HZ,
+		 mi360soc_AE60HZScale, mi360soc_AE60HZ},
+/* SENSOR_OV7620 10 */
 		{OV7620_NoFliker, OV7620_NoFliker,
 		 OV7620_50HZ, OV7620_50HZ,
 		 OV7620_60HZ, OV7620_60HZ},
-/* SENSOR_OV7630C 10 */
+/* SENSOR_OV7630C 11 */
 		{NULL, NULL,
 		 NULL, NULL,
 		 NULL, NULL},
-/* SENSOR_PAS106 11 */
+/* SENSOR_PAS106 12 */
 		{pas106b_NoFliker, pas106b_NoFliker,
 		 pas106b_50HZ, pas106b_50HZ,
 		 pas106b_60HZ, pas106b_60HZ},
-/* SENSOR_PAS202B 12 */
+/* SENSOR_PAS202B 13 */
 		{pas202b_NoFlikerScale, pas202b_NoFliker,
 		 pas202b_50HZScale, pas202b_50HZ,
 		 pas202b_60HZScale, pas202b_60HZ},
-/* SENSOR_PB0330 13 */
-		{pb0330_NoFliker, pb0330_NoFlikerScale,
-		 pb0330_50HZ, pb0330_50HZScale,
-		 pb0330_60HZ, pb0330_60HZScale},
-/* SENSOR_PO2030 14 */
+/* SENSOR_PB0330 14 */
+		{pb0330_NoFlikerScale, pb0330_NoFliker,
+		 pb0330_50HZScale, pb0330_50HZ,
+		 pb0330_60HZScale, pb0330_60HZ},
+/* SENSOR_PO2030 15 */
 		{PO2030_NoFliker, PO2030_NoFliker,
 		 PO2030_50HZ, PO2030_50HZ,
 		 PO2030_60HZ, PO2030_60HZ},
-/* SENSOR_TAS5130CK 15 */
-		{tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale,
-		 tas5130cxx_50HZ, tas5130cxx_50HZScale,
-		 tas5130cxx_60HZ, tas5130cxx_60HZScale},
-/* SENSOR_TAS5130CXX 16 */
-		{tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale,
-		 tas5130cxx_50HZ, tas5130cxx_50HZScale,
-		 tas5130cxx_60HZ, tas5130cxx_60HZScale},
-/* SENSOR_TAS5130C_VF0250 17 */
+/* SENSOR_TAS5130CK 16 */
+		{tas5130cxx_NoFlikerScale, tas5130cxx_NoFliker,
+		 tas5130cxx_50HZScale, tas5130cxx_50HZ,
+		 tas5130cxx_60HZScale, tas5130cxx_60HZ},
+/* SENSOR_TAS5130CXX 17 */
+		{tas5130cxx_NoFlikerScale, tas5130cxx_NoFliker,
+		 tas5130cxx_50HZScale, tas5130cxx_50HZ,
+		 tas5130cxx_60HZScale, tas5130cxx_60HZ},
+/* SENSOR_TAS5130C_VF0250 18 */
 		{tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale,
 		 tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale,
 		 tas5130c_vf0250_60HZ, tas5130c_vf0250_60HZScale},
@@ -6729,6 +6327,7 @@
 	case SENSOR_ADCM2700:
 	case SENSOR_GC0305:
 	case SENSOR_OV7620:
+	case SENSOR_MI0360SOC:
 	case SENSOR_PB0330:
 	case SENSOR_PO2030:
 		reg_w(dev, 0x0d, 0x003a);
@@ -6820,7 +6419,7 @@
 	start_2wr_probe(dev, 0x0e);		/* PAS202BCB */
 	reg_w(dev, 0x08, 0x008d);
 	i2c_write(gspca_dev, 0x03, 0xaa, 0x00);
-	msleep(500);
+	msleep(50);
 	retword = i2c_read(gspca_dev, 0x03);
 	if (retword != 0)
 		return 0x0e;			/* PAS202BCB */
@@ -6863,7 +6462,8 @@
 	__u8 internal_sensor_id;
 };
 static const struct sensor_by_chipset_revision chipset_revision_sensor[] = {
-	{0xc001, 0x13},		/* MI0360 */
+	{0xc000, 0x12},		/* TAS5130C */
+	{0xc001, 0x13},		/* MI0360SOC */
 	{0xe001, 0x13},
 	{0x8001, 0x13},
 	{0x8000, 0x14},		/* CS2102K */
@@ -6963,7 +6563,6 @@
 	reg_w(dev, 0x01, 0x0001);
 	reg_w(dev, 0xee, 0x008b);
 	reg_w(dev, 0x03, 0x0012);
-/*	msleep(150); */
 	reg_w(dev, 0x01, 0x0012);
 	reg_w(dev, 0x05, 0x0012);
 	retword = i2c_read(gspca_dev, 0x00) << 8;	/* ID 0 */
@@ -7025,7 +6624,7 @@
 	int vga = 1;		/* 1: vga, 0: sif */
 	static const __u8 gamma[SENSOR_MAX] = {
 		4,	/* SENSOR_ADCM2700 0 */
-		5,	/* SENSOR_CS2102 1 */
+		4,	/* SENSOR_CS2102 1 */
 		5,	/* SENSOR_CS2102K 2 */
 		4,	/* SENSOR_GC0305 3 */
 		4,	/* SENSOR_HDCS2020b 4 */
@@ -7033,15 +6632,16 @@
 		4,	/* SENSOR_HV7131C 6 */
 		4,	/* SENSOR_ICM105A 7 */
 		4,	/* SENSOR_MC501CB 8 */
-		3,	/* SENSOR_OV7620 9 */
-		4,	/* SENSOR_OV7630C 10 */
-		4,	/* SENSOR_PAS106 11 */
-		4,	/* SENSOR_PAS202B 12 */
-		4,	/* SENSOR_PB0330 13 */
-		4,	/* SENSOR_PO2030 14 */
-		4,	/* SENSOR_TAS5130CK 15 */
-		4,	/* SENSOR_TAS5130CXX 16 */
-		3,	/* SENSOR_TAS5130C_VF0250 17 */
+		4,	/* SENSOR_MI0360SOC 9 */
+		3,	/* SENSOR_OV7620 10 */
+		4,	/* SENSOR_OV7630C 11 */
+		4,	/* SENSOR_PAS106 12 */
+		4,	/* SENSOR_PAS202B 13 */
+		4,	/* SENSOR_PB0330 14 */
+		4,	/* SENSOR_PO2030 15 */
+		4,	/* SENSOR_TAS5130CK 16 */
+		3,	/* SENSOR_TAS5130CXX 17 */
+		3,	/* SENSOR_TAS5130C_VF0250 18 */
 	};
 
 	/* define some sensors from the vendor/product */
@@ -7065,7 +6665,7 @@
 				break;
 			default:
 				PDEBUG(D_PROBE,
-					"Sensor UNKNOW_0 force Tas5130");
+					"Sensor UNKNOWN_0 force Tas5130");
 				sd->sensor = SENSOR_TAS5130CXX;
 			}
 			break;
@@ -7103,7 +6703,7 @@
 			break;
 		case 0x10:
 		case 0x12:
-			PDEBUG(D_PROBE, "Find Sensor TAS5130");
+			PDEBUG(D_PROBE, "Find Sensor TAS5130C");
 			sd->sensor = SENSOR_TAS5130CXX;
 			break;
 		case 0x11:
@@ -7112,9 +6712,9 @@
 			break;
 		case 0x13:
 			PDEBUG(D_PROBE,
-				"Find Sensor MI0360. Chip revision %x",
+				"Find Sensor MI0360SOC. Chip revision %x",
 				sd->chip_revision);
-			sd->sensor = SENSOR_PB0330;
+			sd->sensor = SENSOR_MI0360SOC;
 			break;
 		case 0x14:
 			PDEBUG(D_PROBE,
@@ -7228,17 +6828,17 @@
 		{hv7131cxx_InitialScale, hv7131cxx_Initial},	/* 6 */
 		{icm105axx_InitialScale, icm105axx_Initial},	/* 7 */
 		{MC501CB_InitialScale, MC501CB_Initial},	/* 8 */
-		{OV7620_mode0, OV7620_mode1},			/* 9 */
-		{ov7630c_InitialScale, ov7630c_Initial},	/* 10 */
-		{pas106b_InitialScale, pas106b_Initial},	/* 11 */
-		{pas202b_Initial, pas202b_InitialScale},	/* 12 */
-		{pb0330xx_InitialScale, pb0330xx_Initial},	/* 13 */
-/* or		{pb03303x_InitialScale, pb03303x_Initial}, */
-		{PO2030_mode0, PO2030_mode1},			/* 14 */
-		{tas5130CK_InitialScale, tas5130CK_Initial},	/* 15 */
-		{tas5130cxx_InitialScale, tas5130cxx_Initial},	/* 16 */
+		{mi0360soc_Initial, mi0360soc_InitialScale},	/* 9 */
+		{OV7620_mode0, OV7620_mode1},			/* 10 */
+		{ov7630c_InitialScale, ov7630c_Initial},	/* 11 */
+		{pas106b_InitialScale, pas106b_Initial},	/* 12 */
+		{pas202b_Initial, pas202b_InitialScale},	/* 13 */
+		{pb0330_Initial, pb0330_InitialScale},		/* 14 */
+		{PO2030_mode0, PO2030_mode1},			/* 15 */
+		{tas5130CK_InitialScale, tas5130CK_Initial},	/* 16 */
+		{tas5130cxx_Initial, tas5130cxx_InitialScale},	/* 17 */
 		{tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial},
-								/* 17 */
+								/* 18 */
 	};
 
 	/* create the JPEG header */
@@ -7258,19 +6858,6 @@
 	case SENSOR_PAS106:
 		usb_exchange(gspca_dev, pas106b_Initial_com);
 		break;
-	case SENSOR_PB0330:
-		if (mode) {
-			if (sd->chip_revision == 0xc001
-			    || sd->chip_revision == 0xe001
-			    || sd->chip_revision == 0x8001)
-				zc3_init = pb03303x_Initial;
-		} else {
-			if (sd->chip_revision == 0xc001
-			    || sd->chip_revision == 0xe001
-			    || sd->chip_revision == 0x8001)
-				zc3_init = pb03303x_InitialScale;
-		}
-		break;
 	}
 	usb_exchange(gspca_dev, zc3_init);
 
@@ -7310,10 +6897,8 @@
 
 	/* set the gamma tables when not set */
 	switch (sd->sensor) {
-	case SENSOR_CS2102:		/* gamma set in xxx_Initial */
-	case SENSOR_CS2102K:
+	case SENSOR_CS2102K:		/* gamma set in xxx_Initial */
 	case SENSOR_HDCS2020b:
-	case SENSOR_PB0330:		/* pb with chip_revision - see above */
 	case SENSOR_OV7630C:
 	case SENSOR_TAS5130CK:
 		break;
@@ -7365,7 +6950,7 @@
 	setautogain(gspca_dev);
 	switch (sd->sensor) {
 	case SENSOR_PO2030:
-		msleep(500);
+		msleep(50);
 		reg_r(gspca_dev, 0x0008);
 		reg_r(gspca_dev, 0x0007);
 		/*fall thru*/
@@ -7389,17 +6974,16 @@
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,
-			__u8 *data,
+			u8 *data,
 			int len)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	if (data[0] == 0xff && data[1] == 0xd8) {	/* start of frame */
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-					data, 0);
+		gspca_frame_add(gspca_dev, LAST_PACKET,
+					NULL, 0);
 		/* put the JPEG header in the new frame */
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+		gspca_frame_add(gspca_dev, FIRST_PACKET,
 			sd->jpeg_hdr, JPEG_HDR_SZ);
 
 		/* remove the webcam's header:
@@ -7411,7 +6995,7 @@
 		data += 18;
 		len -= 18;
 	}
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c
index 2eb9dc2..b5439ca 100644
--- a/drivers/media/video/hdpvr/hdpvr-video.c
+++ b/drivers/media/video/hdpvr/hdpvr-video.c
@@ -139,7 +139,7 @@
 		urb = usb_alloc_urb(0, GFP_KERNEL);
 		if (!urb) {
 			v4l2_err(&dev->v4l2_dev, "cannot allocate urb\n");
-			goto exit;
+			goto exit_urb;
 		}
 		buf->urb = urb;
 
@@ -148,7 +148,7 @@
 		if (!mem) {
 			v4l2_err(&dev->v4l2_dev,
 				 "cannot allocate usb transfer buffer\n");
-			goto exit;
+			goto exit_urb_buffer;
 		}
 
 		usb_fill_bulk_urb(buf->urb, dev->udev,
@@ -161,6 +161,10 @@
 		list_add_tail(&buf->buff_list, &dev->free_buff_list);
 	}
 	return 0;
+exit_urb_buffer:
+	usb_free_urb(urb);
+exit_urb:
+	kfree(buf);
 exit:
 	hdpvr_free_buffers(dev);
 	return retval;
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c
index 71c2114..60d992e 100644
--- a/drivers/media/video/hexium_gemini.c
+++ b/drivers/media/video/hexium_gemini.c
@@ -251,7 +251,7 @@
 
 	DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
 
-	if (input < 0 || input >= HEXIUM_INPUTS)
+	if (input >= HEXIUM_INPUTS)
 		return -EINVAL;
 
 	hexium->cur_input = input;
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c
index 39d65ca..938a1f8 100644
--- a/drivers/media/video/hexium_orion.c
+++ b/drivers/media/video/hexium_orion.c
@@ -350,7 +350,7 @@
 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 	struct hexium *hexium = (struct hexium *) dev->ext_priv;
 
-	if (input < 0 || input >= HEXIUM_INPUTS)
+	if (input >= HEXIUM_INPUTS)
 		return -EINVAL;
 
 	hexium->cur_input = input;
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 247d311..64360d2 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -275,7 +275,7 @@
 	if (0 == rc) {
 		ir_input_nokey(ir->input, &ir->ir);
 	} else {
-		ir_input_keydown(ir->input, &ir->ir, ir_key, ir_raw);
+		ir_input_keydown(ir->input, &ir->ir, ir_key);
 	}
 }
 
@@ -299,7 +299,7 @@
 {
 	struct ir_scancode_table *ir_codes = NULL;
 	const char *name = NULL;
-	int ir_type;
+	int ir_type = 0;
 	struct IR_i2c *ir;
 	struct input_dev *input_dev;
 	struct i2c_adapter *adap = client->adapter;
@@ -353,10 +353,8 @@
 		ir_type     = IR_TYPE_RC5;
 		ir_codes    = &ir_codes_fusionhdtv_mce_table;
 		break;
-	case 0x7a:
 	case 0x47:
 	case 0x71:
-	case 0x2d:
 		if (adap->id == I2C_HW_B_CX2388x ||
 		    adap->id == I2C_HW_B_CX2341X) {
 			/* Handled by cx88-input */
@@ -381,10 +379,6 @@
 		ir_type     = IR_TYPE_OTHER;
 		ir_codes    = &ir_codes_avermedia_cardbus_table;
 		break;
-	default:
-		dprintk(1, DEVNAME ": Unsupported i2c address 0x%02x\n", addr);
-		err = -ENODEV;
-		goto err_out_free;
 	}
 
 	/* Let the caller override settings */
@@ -427,7 +421,7 @@
 	}
 
 	/* Make sure we are all setup before going on */
-	if (!name || !ir->get_key || !ir_codes) {
+	if (!name || !ir->get_key || !ir_type || !ir_codes) {
 		dprintk(1, DEVNAME ": Unsupported device at address 0x%02x\n",
 			addr);
 		err = -ENODEV;
@@ -443,7 +437,10 @@
 		 dev_name(&client->dev));
 
 	/* init + register input device */
-	ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes);
+	err = ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes);
+	if (err < 0)
+		goto err_out_free;
+
 	input_dev->id.bustype = BUS_I2C;
 	input_dev->name       = ir->name;
 	input_dev->phys       = ir->phys;
@@ -462,6 +459,7 @@
 	return 0;
 
  err_out_free:
+	ir_input_free(input_dev);
 	input_free_device(input_dev);
 	kfree(ir);
 	return err;
@@ -475,6 +473,7 @@
 	cancel_delayed_work_sync(&ir->work);
 
 	/* unregister device */
+	ir_input_free(ir->input);
 	input_unregister_device(ir->input);
 
 	/* free memory */
diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c
index 4873b6c..79d0fe4 100644
--- a/drivers/media/video/ivtv/ivtv-cards.c
+++ b/drivers/media/video/ivtv/ivtv-cards.c
@@ -136,7 +136,8 @@
 	.hw_audio = IVTV_HW_MSP34XX,
 	.hw_audio_ctrl = IVTV_HW_MSP34XX,
 	.hw_all = IVTV_HW_MSP34XX | IVTV_HW_SAA7115 |
-		  IVTV_HW_SAA7127 | IVTV_HW_TVEEPROM | IVTV_HW_TUNER,
+		  IVTV_HW_SAA7127 | IVTV_HW_TVEEPROM | IVTV_HW_TUNER |
+		  IVTV_HW_I2C_IR_RX_HAUP_EXT | IVTV_HW_I2C_IR_RX_HAUP_INT,
 	.video_inputs = {
 		{ IVTV_CARD_INPUT_VID_TUNER,  0, IVTV_SAA71XX_COMPOSITE4 },
 		{ IVTV_CARD_INPUT_SVIDEO1,    1, IVTV_SAA71XX_SVIDEO0    },
@@ -199,7 +200,9 @@
 	.hw_audio_ctrl = IVTV_HW_CX25840,
 	.hw_muxer = IVTV_HW_WM8775,
 	.hw_all = IVTV_HW_WM8775 | IVTV_HW_CX25840 |
-		  IVTV_HW_TVEEPROM | IVTV_HW_TUNER,
+		  IVTV_HW_TVEEPROM | IVTV_HW_TUNER |
+		  IVTV_HW_I2C_IR_RX_HAUP_EXT | IVTV_HW_I2C_IR_RX_HAUP_INT |
+		  IVTV_HW_Z8F0811_IR_HAUP,
 	.video_inputs = {
 		{ IVTV_CARD_INPUT_VID_TUNER,  0, CX25840_COMPOSITE7 },
 		{ IVTV_CARD_INPUT_SVIDEO1,    1, CX25840_SVIDEO1    },
@@ -955,7 +958,8 @@
 	.hw_video = IVTV_HW_CX25840,
 	.hw_audio = IVTV_HW_CX25840,
 	.hw_audio_ctrl = IVTV_HW_CX25840,
-	.hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | IVTV_HW_WM8739,
+	.hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | IVTV_HW_WM8739 |
+		  IVTV_HW_I2C_IR_RX_AVER,
 	.video_inputs = {
 		{ IVTV_CARD_INPUT_VID_TUNER,  0, CX25840_COMPOSITE2 },
 		{ IVTV_CARD_INPUT_SVIDEO1,    1, CX25840_SVIDEO3    },
@@ -965,6 +969,7 @@
 		{ IVTV_CARD_INPUT_AUD_TUNER,  CX25840_AUDIO5       },
 		{ IVTV_CARD_INPUT_LINE_IN1,   CX25840_AUDIO_SERIAL, 1 },
 	},
+	.radio_input = { IVTV_CARD_INPUT_AUD_TUNER,  CX25840_AUDIO5 },
 	/* enable line-in */
 	.gpio_init = { .direction = 0xe000, .initial_value = 0x4000 },
 	.xceive_pin = 10,
@@ -1025,13 +1030,15 @@
 /* AVerMedia UltraTV 1500 MCE (newer non-cx88 version, M113 variant) card */
 
 static const struct ivtv_card_pci_info ivtv_pci_aver_ultra1500mce[] = {
-	{ PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc019 },
+	{ PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc019 }, /* NTSC */
+	{ PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc01b }, /* PAL/SECAM */
 	{ 0, 0, 0 }
 };
 
 static const struct ivtv_card ivtv_card_aver_ultra1500mce = {
 	.type = IVTV_CARD_AVER_ULTRA1500MCE,
 	.name = "AVerMedia UltraTV 1500 MCE / AVerTV M113 Philips Tuner",
+	.comment = "For non-NTSC tuners, use the pal= or secam= module options",
 	.v4l2_capabilities = IVTV_CAP_ENCODER,
 	.hw_video = IVTV_HW_CX25840,
 	.hw_audio = IVTV_HW_CX25840,
@@ -1058,6 +1065,7 @@
 	.tuners = {
 		/* The UltraTV 1500 MCE has a Philips FM1236 MK5 TV/FM tuner */
 		{ .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FM1236_MK3 },
+		{ .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216MK5 },
 	},
 	.pci_list = ivtv_pci_aver_ultra1500mce,
 	.i2c = &ivtv_i2c_std,
diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h
index e99a0a2..6148827 100644
--- a/drivers/media/video/ivtv/ivtv-cards.h
+++ b/drivers/media/video/ivtv/ivtv-cards.h
@@ -87,26 +87,43 @@
 #define IVTV_PCI_ID_GOTVIEW1		0xffac
 #define IVTV_PCI_ID_GOTVIEW2 		0xffad
 
-/* hardware flags, no gaps allowed, IVTV_HW_GPIO must always be last */
-#define IVTV_HW_CX25840   (1 << 0)
-#define IVTV_HW_SAA7115   (1 << 1)
-#define IVTV_HW_SAA7127   (1 << 2)
-#define IVTV_HW_MSP34XX   (1 << 3)
-#define IVTV_HW_TUNER     (1 << 4)
-#define IVTV_HW_WM8775    (1 << 5)
-#define IVTV_HW_CS53L32A  (1 << 6)
-#define IVTV_HW_TVEEPROM  (1 << 7)
-#define IVTV_HW_SAA7114   (1 << 8)
-#define IVTV_HW_UPD64031A (1 << 9)
-#define IVTV_HW_UPD6408X  (1 << 10)
-#define IVTV_HW_SAA717X   (1 << 11)
-#define IVTV_HW_WM8739    (1 << 12)
-#define IVTV_HW_VP27SMPX  (1 << 13)
-#define IVTV_HW_M52790    (1 << 14)
-#define IVTV_HW_GPIO      (1 << 15)
+/* hardware flags, no gaps allowed */
+#define IVTV_HW_CX25840			(1 << 0)
+#define IVTV_HW_SAA7115			(1 << 1)
+#define IVTV_HW_SAA7127			(1 << 2)
+#define IVTV_HW_MSP34XX			(1 << 3)
+#define IVTV_HW_TUNER			(1 << 4)
+#define IVTV_HW_WM8775			(1 << 5)
+#define IVTV_HW_CS53L32A		(1 << 6)
+#define IVTV_HW_TVEEPROM		(1 << 7)
+#define IVTV_HW_SAA7114			(1 << 8)
+#define IVTV_HW_UPD64031A		(1 << 9)
+#define IVTV_HW_UPD6408X		(1 << 10)
+#define IVTV_HW_SAA717X			(1 << 11)
+#define IVTV_HW_WM8739			(1 << 12)
+#define IVTV_HW_VP27SMPX		(1 << 13)
+#define IVTV_HW_M52790			(1 << 14)
+#define IVTV_HW_GPIO			(1 << 15)
+#define IVTV_HW_I2C_IR_RX_AVER		(1 << 16)
+#define IVTV_HW_I2C_IR_RX_HAUP_EXT	(1 << 17) /* External before internal */
+#define IVTV_HW_I2C_IR_RX_HAUP_INT	(1 << 18)
+#define IVTV_HW_Z8F0811_IR_TX_HAUP	(1 << 19)
+#define IVTV_HW_Z8F0811_IR_RX_HAUP	(1 << 20)
+
+#define IVTV_HW_Z8F0811_IR_HAUP	(IVTV_HW_Z8F0811_IR_RX_HAUP | \
+				 IVTV_HW_Z8F0811_IR_TX_HAUP)
 
 #define IVTV_HW_SAA711X   (IVTV_HW_SAA7115 | IVTV_HW_SAA7114)
 
+#define IVTV_HW_IR_RX_ANY (IVTV_HW_I2C_IR_RX_AVER | \
+			   IVTV_HW_I2C_IR_RX_HAUP_EXT | \
+			   IVTV_HW_I2C_IR_RX_HAUP_INT | \
+			   IVTV_HW_Z8F0811_IR_RX_HAUP)
+
+#define IVTV_HW_IR_TX_ANY (IVTV_HW_Z8F0811_IR_TX_HAUP)
+
+#define IVTV_HW_IR_ANY	  (IVTV_HW_IR_RX_ANY | IVTV_HW_IR_TX_ANY)
+
 /* video inputs */
 #define	IVTV_CARD_INPUT_VID_TUNER	1
 #define	IVTV_CARD_INPUT_SVIDEO1 	2
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 463ec34..347c334 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -91,10 +91,15 @@
 				     -1, -1, -1, -1, -1, -1, -1, -1,
 				     -1, -1, -1, -1, -1, -1, -1, -1,
 				     -1, -1, -1, -1, -1, -1, -1, -1 };
+static int i2c_clock_period[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
+					       -1, -1, -1, -1, -1, -1, -1, -1,
+					       -1, -1, -1, -1, -1, -1, -1, -1,
+					       -1, -1, -1, -1, -1, -1, -1, -1 };
 
 static unsigned int cardtype_c = 1;
 static unsigned int tuner_c = 1;
 static unsigned int radio_c = 1;
+static unsigned int i2c_clock_period_c = 1;
 static char pal[] = "---";
 static char secam[] = "--";
 static char ntsc[] = "-";
@@ -151,6 +156,7 @@
 
 module_param(tunertype, int, 0644);
 module_param(newi2c, int, 0644);
+module_param_array(i2c_clock_period, int, &i2c_clock_period_c, 0644);
 
 MODULE_PARM_DESC(tuner, "Tuner type selection,\n"
 			"\t\t\tsee tuner.h for values");
@@ -245,6 +251,10 @@
 		 "Use new I2C implementation\n"
 		 "\t\t\t-1 is autodetect, 0 is off, 1 is on\n"
 		 "\t\t\tDefault is autodetect");
+MODULE_PARM_DESC(i2c_clock_period,
+		 "Period of SCL for the I2C bus controlled by the CX23415/6\n"
+		 "\t\t\tMin: 10 usec (100 kHz), Max: 4500 usec (222 Hz)\n"
+		 "\t\t\tDefault: " __stringify(IVTV_DEFAULT_I2C_CLOCK_PERIOD));
 
 MODULE_PARM_DESC(ivtv_first_minor, "Set device node number assigned to first card");
 
@@ -600,6 +610,15 @@
 	itv->options.cardtype = cardtype[itv->instance];
 	itv->options.tuner = tuner[itv->instance];
 	itv->options.radio = radio[itv->instance];
+
+	itv->options.i2c_clock_period = i2c_clock_period[itv->instance];
+	if (itv->options.i2c_clock_period == -1)
+		itv->options.i2c_clock_period = IVTV_DEFAULT_I2C_CLOCK_PERIOD;
+	else if (itv->options.i2c_clock_period < 10)
+		itv->options.i2c_clock_period = 10;
+	else if (itv->options.i2c_clock_period > 4500)
+		itv->options.i2c_clock_period = 4500;
+
 	itv->options.newi2c = newi2c;
 	if (tunertype < -1 || tunertype > 1) {
 		IVTV_WARN("Invalid tunertype argument, will autodetect instead\n");
@@ -865,6 +884,10 @@
 			itv->hw_flags |= device;
 	}
 
+	/* probe for legacy IR controllers that aren't in card definitions */
+	if ((itv->hw_flags & IVTV_HW_IR_ANY) == 0)
+		ivtv_i2c_new_ir_legacy(itv);
+
 	if (itv->card->hw_all & IVTV_HW_CX25840)
 		itv->sd_video = ivtv_find_hw(itv, IVTV_HW_CX25840);
 	else if (itv->card->hw_all & IVTV_HW_SAA717X)
@@ -1361,7 +1384,7 @@
       .remove =   ivtv_remove,
 };
 
-static int module_start(void)
+static int __init module_start(void)
 {
 	printk(KERN_INFO "ivtv: Start initialization, version %s\n", IVTV_VERSION);
 
@@ -1385,7 +1408,7 @@
 	return 0;
 }
 
-static void module_cleanup(void)
+static void __exit module_cleanup(void)
 {
 	pci_unregister_driver(&ivtv_pci_driver);
 }
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index 440f732..e4816da 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -64,6 +64,7 @@
 #include <media/v4l2-device.h>
 #include <media/tuner.h>
 #include <media/cx2341x.h>
+#include <media/ir-kbd-i2c.h>
 
 #include <linux/ivtv.h>
 
@@ -176,12 +177,16 @@
 
 #define IVTV_MAX_PGM_INDEX (400)
 
+/* Default I2C SCL period in microseconds */
+#define IVTV_DEFAULT_I2C_CLOCK_PERIOD	20
+
 struct ivtv_options {
 	int kilobytes[IVTV_MAX_STREAMS];        /* size in kilobytes of each stream */
 	int cardtype;				/* force card type on load */
 	int tuner;				/* set tuner on load */
 	int radio;				/* enable/disable radio */
 	int newi2c;				/* new I2C algorithm */
+	int i2c_clock_period;			/* period of SCL for I2C bus */
 };
 
 /* ivtv-specific mailbox template */
@@ -677,6 +682,7 @@
 	int i2c_state;                  /* i2c bit state */
 	struct mutex i2c_bus_lock;      /* lock i2c bus */
 
+	struct IR_i2c_init_data ir_i2c_init_data;
 
 	/* Program Index information */
 	u32 pgm_info_offset;            /* start of pgm info in encoder memory */
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index b9c71e6..2ee03c2 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -88,6 +88,11 @@
 #define IVTV_UPD64083_I2C_ADDR 		0x5c
 #define IVTV_VP27SMPX_I2C_ADDR      	0x5b
 #define IVTV_M52790_I2C_ADDR      	0x48
+#define IVTV_AVERMEDIA_IR_RX_I2C_ADDR	0x40
+#define IVTV_HAUP_EXT_IR_RX_I2C_ADDR 	0x1a
+#define IVTV_HAUP_INT_IR_RX_I2C_ADDR 	0x18
+#define IVTV_Z8F0811_IR_TX_I2C_ADDR	0x70
+#define IVTV_Z8F0811_IR_RX_I2C_ADDR	0x71
 
 /* This array should match the IVTV_HW_ defines */
 static const u8 hw_addrs[] = {
@@ -106,7 +111,12 @@
 	IVTV_WM8739_I2C_ADDR,
 	IVTV_VP27SMPX_I2C_ADDR,
 	IVTV_M52790_I2C_ADDR,
-	0 		/* IVTV_HW_GPIO dummy driver ID */
+	0,				/* IVTV_HW_GPIO dummy driver ID */
+	IVTV_AVERMEDIA_IR_RX_I2C_ADDR,	/* IVTV_HW_I2C_IR_RX_AVER */
+	IVTV_HAUP_EXT_IR_RX_I2C_ADDR,	/* IVTV_HW_I2C_IR_RX_HAUP_EXT */
+	IVTV_HAUP_INT_IR_RX_I2C_ADDR,	/* IVTV_HW_I2C_IR_RX_HAUP_INT */
+	IVTV_Z8F0811_IR_TX_I2C_ADDR,	/* IVTV_HW_Z8F0811_IR_TX_HAUP */
+	IVTV_Z8F0811_IR_RX_I2C_ADDR,	/* IVTV_HW_Z8F0811_IR_RX_HAUP */
 };
 
 /* This array should match the IVTV_HW_ defines */
@@ -126,7 +136,12 @@
 	"wm8739",
 	"vp27smpx",
 	"m52790",
-	NULL
+	NULL,
+	NULL,		/* IVTV_HW_I2C_IR_RX_AVER */
+	NULL,		/* IVTV_HW_I2C_IR_RX_HAUP_EXT */
+	NULL,		/* IVTV_HW_I2C_IR_RX_HAUP_INT */
+	NULL,		/* IVTV_HW_Z8F0811_IR_TX_HAUP */
+	NULL,		/* IVTV_HW_Z8F0811_IR_RX_HAUP */
 };
 
 /* This array should match the IVTV_HW_ defines */
@@ -147,8 +162,95 @@
 	"vp27smpx",
 	"m52790",
 	"gpio",
+	"ir_video",		/* IVTV_HW_I2C_IR_RX_AVER */
+	"ir_video",		/* IVTV_HW_I2C_IR_RX_HAUP_EXT */
+	"ir_video",		/* IVTV_HW_I2C_IR_RX_HAUP_INT */
+	"ir_tx_z8f0811_haup",	/* IVTV_HW_Z8F0811_IR_TX_HAUP */
+	"ir_rx_z8f0811_haup",	/* IVTV_HW_Z8F0811_IR_RX_HAUP */
 };
 
+static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
+{
+	struct i2c_board_info info;
+	struct i2c_adapter *adap = &itv->i2c_adap;
+	struct IR_i2c_init_data *init_data = &itv->ir_i2c_init_data;
+	unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
+
+	/* Only allow one IR transmitter to be registered per board */
+	if (hw & IVTV_HW_IR_TX_ANY) {
+		if (itv->hw_flags & IVTV_HW_IR_TX_ANY)
+			return -1;
+		memset(&info, 0, sizeof(struct i2c_board_info));
+		strlcpy(info.type, type, I2C_NAME_SIZE);
+		return i2c_new_probed_device(adap, &info, addr_list) == NULL
+								     ? -1 : 0;
+	}
+
+	/* Only allow one IR receiver to be registered per board */
+	if (itv->hw_flags & IVTV_HW_IR_RX_ANY)
+		return -1;
+
+	/* Our default information for ir-kbd-i2c.c to use */
+	switch (hw) {
+	case IVTV_HW_I2C_IR_RX_AVER:
+		init_data->ir_codes = &ir_codes_avermedia_cardbus_table;
+		init_data->internal_get_key_func =
+					IR_KBD_GET_KEY_AVERMEDIA_CARDBUS;
+		init_data->type = IR_TYPE_OTHER;
+		init_data->name = "AVerMedia AVerTV card";
+		break;
+	case IVTV_HW_I2C_IR_RX_HAUP_EXT:
+	case IVTV_HW_I2C_IR_RX_HAUP_INT:
+		/* Default to old black remote */
+		init_data->ir_codes = &ir_codes_rc5_tv_table;
+		init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP;
+		init_data->type = IR_TYPE_RC5;
+		init_data->name = itv->card_name;
+		break;
+	case IVTV_HW_Z8F0811_IR_RX_HAUP:
+		/* Default to grey remote */
+		init_data->ir_codes = &ir_codes_hauppauge_new_table;
+		init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
+		init_data->type = IR_TYPE_RC5;
+		init_data->name = itv->card_name;
+		break;
+	}
+
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	info.platform_data = init_data;
+	strlcpy(info.type, type, I2C_NAME_SIZE);
+
+	return i2c_new_probed_device(adap, &info, addr_list) == NULL ? -1 : 0;
+}
+
+/* Instantiate the IR receiver device using probing -- undesirable */
+struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv)
+{
+	struct i2c_board_info info;
+	/*
+	 * The external IR receiver is at i2c address 0x34.
+	 * The internal IR receiver is at i2c address 0x30.
+	 *
+	 * In theory, both can be fitted, and Hauppauge suggests an external
+	 * overrides an internal.  That's why we probe 0x1a (~0x34) first. CB
+	 *
+	 * Some of these addresses we probe may collide with other i2c address
+	 * allocations, so this function must be called after all other i2c
+	 * devices we care about are registered.
+	 */
+	const unsigned short addr_list[] = {
+		0x1a,	/* Hauppauge IR external - collides with WM8739 */
+		0x18,	/* Hauppauge IR internal */
+		0x71,	/* Hauppauge IR (PVR150) */
+		0x6b,	/* Adaptec IR */
+		I2C_CLIENT_END
+	};
+
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+	return i2c_new_probed_device(&itv->i2c_adap, &info, addr_list);
+}
+
 int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
 {
 	struct v4l2_subdev *sd;
@@ -178,8 +280,15 @@
 			sd->grp_id = 1 << idx;
 		return sd ? 0 : -1;
 	}
+
+	if (hw & IVTV_HW_IR_ANY)
+		return ivtv_i2c_new_ir(itv, hw, type, hw_addrs[idx]);
+
+	/* Is it not an I2C device or one we do not wish to register? */
 	if (!hw_addrs[idx])
 		return -1;
+
+	/* It's an I2C device other than an analog tuner or IR chip */
 	if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) {
 		sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
 				adap, mod, type, 0, I2C_ADDRS(hw_addrs[idx]));
@@ -564,20 +673,22 @@
 	.owner = THIS_MODULE,
 };
 
+#define IVTV_ALGO_BIT_TIMEOUT	(2)	/* seconds */
+
 static const struct i2c_algo_bit_data ivtv_i2c_algo_template = {
 	.setsda		= ivtv_setsda_old,
 	.setscl		= ivtv_setscl_old,
 	.getsda		= ivtv_getsda_old,
 	.getscl		= ivtv_getscl_old,
-	.udelay		= 10,
-	.timeout	= 200,
+	.udelay		= IVTV_DEFAULT_I2C_CLOCK_PERIOD / 2,  /* microseconds */
+	.timeout	= IVTV_ALGO_BIT_TIMEOUT * HZ,         /* jiffies */
 };
 
 static struct i2c_client ivtv_i2c_client_template = {
 	.name = "ivtv internal",
 };
 
-/* init + register i2c adapter + instantiate IR receiver */
+/* init + register i2c adapter */
 int init_ivtv_i2c(struct ivtv *itv)
 {
 	int retval;
@@ -585,11 +696,10 @@
 	IVTV_DEBUG_I2C("i2c init\n");
 
 	/* Sanity checks for the I2C hardware arrays. They must be the
-	 * same size and GPIO must be the last entry.
+	 * same size.
 	 */
 	if (ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) ||
-	    ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_modules) ||
-	    IVTV_HW_GPIO != (1 << (ARRAY_SIZE(hw_addrs) - 1))) {
+	    ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_modules)) {
 		IVTV_ERR("Mismatched I2C hardware arrays\n");
 		return -ENODEV;
 	}
@@ -602,6 +712,7 @@
 		memcpy(&itv->i2c_algo, &ivtv_i2c_algo_template,
 		       sizeof(struct i2c_algo_bit_data));
 	}
+	itv->i2c_algo.udelay = itv->options.i2c_clock_period / 2;
 	itv->i2c_algo.data = itv;
 	itv->i2c_adap.algo_data = &itv->i2c_algo;
 
@@ -623,32 +734,6 @@
 	else
 		retval = i2c_bit_add_bus(&itv->i2c_adap);
 
-	/* Instantiate the IR receiver device, if present */
-	if (retval == 0) {
-		struct i2c_board_info info;
-		/* The external IR receiver is at i2c address 0x34 (0x35 for
-		   reads).  Future Hauppauge cards will have an internal
-		   receiver at 0x30 (0x31 for reads).  In theory, both can be
-		   fitted, and Hauppauge suggest an external overrides an
-		   internal.
-
-		   That's why we probe 0x1a (~0x34) first. CB
-		*/
-		const unsigned short addr_list[] = {
-			0x1a,	/* Hauppauge IR external */
-			0x18,	/* Hauppauge IR internal */
-			0x71,	/* Hauppauge IR (PVR150) */
-			0x64,	/* Pixelview IR */
-			0x30,	/* KNC ONE IR */
-			0x6b,	/* Adaptec IR */
-			I2C_CLIENT_END
-		};
-
-		memset(&info, 0, sizeof(struct i2c_board_info));
-		strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
-		i2c_new_probed_device(&itv->i2c_adap, &info, addr_list);
-	}
-
 	return retval;
 }
 
diff --git a/drivers/media/video/ivtv/ivtv-i2c.h b/drivers/media/video/ivtv/ivtv-i2c.h
index 396928a..9332920 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.h
+++ b/drivers/media/video/ivtv/ivtv-i2c.h
@@ -21,6 +21,7 @@
 #ifndef IVTV_I2C_H
 #define IVTV_I2C_H
 
+struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv);
 int ivtv_i2c_register(struct ivtv *itv, unsigned idx);
 struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw);
 
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index 3454070..c1fc6dc 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -478,7 +478,7 @@
 
 	DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
 
-	if (input < 0 || input >= MXB_INPUTS)
+	if (input >= MXB_INPUTS)
 		return -EINVAL;
 
 	mxb->cur_input = input;
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index eccb40a..2052293 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -247,7 +247,7 @@
 
 /* COM5 */
 #define AFR_ON_OFF      0x80	/* Auto frame rate control ON/OFF selection */
-#define AFR_SPPED       0x40	/* Auto frame rate control speed slection */
+#define AFR_SPPED       0x40	/* Auto frame rate control speed selection */
 				/* Auto frame rate max rate control */
 #define AFR_NO_RATE     0x00	/*     No  reduction of frame rate */
 #define AFR_1p2         0x10	/*     Max reduction to 1/2 frame rate */
diff --git a/drivers/media/video/ov9640.c b/drivers/media/video/ov9640.c
new file mode 100644
index 0000000..c81ae219
--- /dev/null
+++ b/drivers/media/video/ov9640.c
@@ -0,0 +1,801 @@
+/*
+ * OmniVision OV96xx Camera Driver
+ *
+ * Copyright (C) 2009 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on ov772x camera driver:
+ *
+ * Copyright (C) 2008 Renesas Solutions Corp.
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on ov7670 and soc_camera_platform driver,
+ *
+ * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
+ * Copyright (C) 2008 Magnus Damm
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-common.h>
+#include <media/soc_camera.h>
+
+#include "ov9640.h"
+
+/* default register setup */
+static const struct ov9640_reg ov9640_regs_dflt[] = {
+	{ OV9640_COM5,	OV9640_COM5_SYSCLK | OV9640_COM5_LONGEXP },
+	{ OV9640_COM6,	OV9640_COM6_OPT_BLC | OV9640_COM6_ADBLC_BIAS |
+			OV9640_COM6_FMT_RST | OV9640_COM6_ADBLC_OPTEN },
+	{ OV9640_PSHFT,	OV9640_PSHFT_VAL(0x01) },
+	{ OV9640_ACOM,	OV9640_ACOM_2X_ANALOG | OV9640_ACOM_RSVD },
+	{ OV9640_TSLB,	OV9640_TSLB_YUYV_UYVY },
+	{ OV9640_COM16,	OV9640_COM16_RB_AVG },
+
+	/* Gamma curve P */
+	{ 0x6c, 0x40 },	{ 0x6d, 0x30 },	{ 0x6e, 0x4b },	{ 0x6f, 0x60 },
+	{ 0x70, 0x70 },	{ 0x71, 0x70 },	{ 0x72, 0x70 },	{ 0x73, 0x70 },
+	{ 0x74, 0x60 },	{ 0x75, 0x60 },	{ 0x76, 0x50 },	{ 0x77, 0x48 },
+	{ 0x78, 0x3a },	{ 0x79, 0x2e },	{ 0x7a, 0x28 },	{ 0x7b, 0x22 },
+
+	/* Gamma curve T */
+	{ 0x7c, 0x04 },	{ 0x7d, 0x07 },	{ 0x7e, 0x10 },	{ 0x7f, 0x28 },
+	{ 0x80, 0x36 },	{ 0x81, 0x44 },	{ 0x82, 0x52 },	{ 0x83, 0x60 },
+	{ 0x84, 0x6c },	{ 0x85, 0x78 },	{ 0x86, 0x8c },	{ 0x87, 0x9e },
+	{ 0x88, 0xbb },	{ 0x89, 0xd2 },	{ 0x8a, 0xe6 },
+};
+
+/* Configurations
+ * NOTE: for YUV, alter the following registers:
+ * 		COM12 |= OV9640_COM12_YUV_AVG
+ *
+ *	 for RGB, alter the following registers:
+ *	 	COM7  |= OV9640_COM7_RGB
+ *	 	COM13 |= OV9640_COM13_RGB_AVG
+ *	 	COM15 |= proper RGB color encoding mode
+ */
+static const struct ov9640_reg ov9640_regs_qqcif[] = {
+	{ OV9640_CLKRC,	OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x0f) },
+	{ OV9640_COM1,	OV9640_COM1_QQFMT | OV9640_COM1_HREF_2SKIP },
+	{ OV9640_COM4,	OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
+	{ OV9640_COM7,	OV9640_COM7_QCIF },
+	{ OV9640_COM12,	OV9640_COM12_RSVD },
+	{ OV9640_COM13,	OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
+	{ OV9640_COM15,	OV9640_COM15_OR_10F0 },
+};
+
+static const struct ov9640_reg ov9640_regs_qqvga[] = {
+	{ OV9640_CLKRC,	OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x07) },
+	{ OV9640_COM1,	OV9640_COM1_QQFMT | OV9640_COM1_HREF_2SKIP },
+	{ OV9640_COM4,	OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
+	{ OV9640_COM7,	OV9640_COM7_QVGA },
+	{ OV9640_COM12,	OV9640_COM12_RSVD },
+	{ OV9640_COM13,	OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
+	{ OV9640_COM15,	OV9640_COM15_OR_10F0 },
+};
+
+static const struct ov9640_reg ov9640_regs_qcif[] = {
+	{ OV9640_CLKRC,	OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x07) },
+	{ OV9640_COM4,	OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
+	{ OV9640_COM7,	OV9640_COM7_QCIF },
+	{ OV9640_COM12,	OV9640_COM12_RSVD },
+	{ OV9640_COM13,	OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
+	{ OV9640_COM15,	OV9640_COM15_OR_10F0 },
+};
+
+static const struct ov9640_reg ov9640_regs_qvga[] = {
+	{ OV9640_CLKRC,	OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x03) },
+	{ OV9640_COM4,	OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
+	{ OV9640_COM7,	OV9640_COM7_QVGA },
+	{ OV9640_COM12,	OV9640_COM12_RSVD },
+	{ OV9640_COM13,	OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
+	{ OV9640_COM15,	OV9640_COM15_OR_10F0 },
+};
+
+static const struct ov9640_reg ov9640_regs_cif[] = {
+	{ OV9640_CLKRC,	OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x03) },
+	{ OV9640_COM3,	OV9640_COM3_VP },
+	{ OV9640_COM7,	OV9640_COM7_CIF },
+	{ OV9640_COM12,	OV9640_COM12_RSVD },
+	{ OV9640_COM13,	OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
+	{ OV9640_COM15,	OV9640_COM15_OR_10F0 },
+};
+
+static const struct ov9640_reg ov9640_regs_vga[] = {
+	{ OV9640_CLKRC,	OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x01) },
+	{ OV9640_COM3,	OV9640_COM3_VP },
+	{ OV9640_COM7,	OV9640_COM7_VGA },
+	{ OV9640_COM12,	OV9640_COM12_RSVD },
+	{ OV9640_COM13,	OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
+	{ OV9640_COM15,	OV9640_COM15_OR_10F0 },
+};
+
+static const struct ov9640_reg ov9640_regs_sxga[] = {
+	{ OV9640_CLKRC,	OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x01) },
+	{ OV9640_COM3,	OV9640_COM3_VP },
+	{ OV9640_COM7,	0 },
+	{ OV9640_COM12,	OV9640_COM12_RSVD },
+	{ OV9640_COM13,	OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
+	{ OV9640_COM15,	OV9640_COM15_OR_10F0 },
+};
+
+static const struct ov9640_reg ov9640_regs_yuv[] = {
+	{ OV9640_MTX1,	0x58 },
+	{ OV9640_MTX2,	0x48 },
+	{ OV9640_MTX3,	0x10 },
+	{ OV9640_MTX4,	0x28 },
+	{ OV9640_MTX5,	0x48 },
+	{ OV9640_MTX6,	0x70 },
+	{ OV9640_MTX7,	0x40 },
+	{ OV9640_MTX8,	0x40 },
+	{ OV9640_MTX9,	0x40 },
+	{ OV9640_MTXS,	0x0f },
+};
+
+static const struct ov9640_reg ov9640_regs_rgb[] = {
+	{ OV9640_MTX1,	0x71 },
+	{ OV9640_MTX2,	0x3e },
+	{ OV9640_MTX3,	0x0c },
+	{ OV9640_MTX4,	0x33 },
+	{ OV9640_MTX5,	0x72 },
+	{ OV9640_MTX6,	0x00 },
+	{ OV9640_MTX7,	0x2b },
+	{ OV9640_MTX8,	0x66 },
+	{ OV9640_MTX9,	0xd2 },
+	{ OV9640_MTXS,	0x65 },
+};
+
+/*
+ * TODO: this sensor also supports RGB555 and RGB565 formats, but support for
+ * them has not yet been sufficiently tested and so it is not included with
+ * this version of the driver. To test and debug these formats add two entries
+ * to the below array, see ov722x.c for an example.
+ */
+static const struct soc_camera_data_format ov9640_fmt_lists[] = {
+	{
+		.name		= "UYVY",
+		.fourcc		= V4L2_PIX_FMT_UYVY,
+		.depth		= 16,
+		.colorspace	= V4L2_COLORSPACE_JPEG,
+	},
+};
+
+static const struct v4l2_queryctrl ov9640_controls[] = {
+	{
+		.id		= V4L2_CID_VFLIP,
+		.type		= V4L2_CTRL_TYPE_BOOLEAN,
+		.name		= "Flip Vertically",
+		.minimum	= 0,
+		.maximum	= 1,
+		.step		= 1,
+		.default_value	= 0,
+	},
+	{
+		.id		= V4L2_CID_HFLIP,
+		.type		= V4L2_CTRL_TYPE_BOOLEAN,
+		.name		= "Flip Horizontally",
+		.minimum	= 0,
+		.maximum	= 1,
+		.step		= 1,
+		.default_value	= 0,
+	},
+};
+
+/* read a register */
+static int ov9640_reg_read(struct i2c_client *client, u8 reg, u8 *val)
+{
+	int ret;
+	u8 data = reg;
+	struct i2c_msg msg = {
+		.addr	= client->addr,
+		.flags	= 0,
+		.len	= 1,
+		.buf	= &data,
+	};
+
+	ret = i2c_transfer(client->adapter, &msg, 1);
+	if (ret < 0)
+		goto err;
+
+	msg.flags = I2C_M_RD;
+	ret = i2c_transfer(client->adapter, &msg, 1);
+	if (ret < 0)
+		goto err;
+
+	*val = data;
+	return 0;
+
+err:
+	dev_err(&client->dev, "Failed reading register 0x%02x!\n", reg);
+	return ret;
+}
+
+/* write a register */
+static int ov9640_reg_write(struct i2c_client *client, u8 reg, u8 val)
+{
+	int ret;
+	u8 _val;
+	unsigned char data[2] = { reg, val };
+	struct i2c_msg msg = {
+		.addr	= client->addr,
+		.flags	= 0,
+		.len	= 2,
+		.buf	= data,
+	};
+
+	ret = i2c_transfer(client->adapter, &msg, 1);
+	if (ret < 0) {
+		dev_err(&client->dev, "Failed writing register 0x%02x!\n", reg);
+		return ret;
+	}
+
+	/* we have to read the register back ... no idea why, maybe HW bug */
+	ret = ov9640_reg_read(client, reg, &_val);
+	if (ret)
+		dev_err(&client->dev,
+			"Failed reading back register 0x%02x!\n", reg);
+
+	return 0;
+}
+
+
+/* Read a register, alter its bits, write it back */
+static int ov9640_reg_rmw(struct i2c_client *client, u8 reg, u8 set, u8 unset)
+{
+	u8 val;
+	int ret;
+
+	ret = ov9640_reg_read(client, reg, &val);
+	if (ret) {
+		dev_err(&client->dev,
+			"[Read]-Modify-Write of register %02x failed!\n", reg);
+		return val;
+	}
+
+	val |= set;
+	val &= ~unset;
+
+	ret = ov9640_reg_write(client, reg, val);
+	if (ret)
+		dev_err(&client->dev,
+			"Read-Modify-[Write] of register %02x failed!\n", reg);
+
+	return ret;
+}
+
+/* Soft reset the camera. This has nothing to do with the RESET pin! */
+static int ov9640_reset(struct i2c_client *client)
+{
+	int ret;
+
+	ret = ov9640_reg_write(client, OV9640_COM7, OV9640_COM7_SCCB_RESET);
+	if (ret)
+		dev_err(&client->dev,
+			"An error occured while entering soft reset!\n");
+
+	return ret;
+}
+
+/* Start/Stop streaming from the device */
+static int ov9640_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	return 0;
+}
+
+/* Alter bus settings on camera side */
+static int ov9640_set_bus_param(struct soc_camera_device *icd,
+				unsigned long flags)
+{
+	return 0;
+}
+
+/* Request bus settings on camera side */
+static unsigned long ov9640_query_bus_param(struct soc_camera_device *icd)
+{
+	struct soc_camera_link *icl = to_soc_camera_link(icd);
+
+	/*
+	 * REVISIT: the camera probably can do 10 bit transfers, but I don't
+	 *          have those pins connected on my hardware.
+	 */
+	unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
+		SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
+		SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
+
+	return soc_camera_apply_sensor_flags(icl, flags);
+}
+
+/* Get status of additional camera capabilities */
+static int ov9640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct i2c_client *client = sd->priv;
+	struct ov9640_priv *priv = container_of(i2c_get_clientdata(client),
+					struct ov9640_priv, subdev);
+
+	switch (ctrl->id) {
+	case V4L2_CID_VFLIP:
+		ctrl->value = priv->flag_vflip;
+		break;
+	case V4L2_CID_HFLIP:
+		ctrl->value = priv->flag_hflip;
+		break;
+	}
+	return 0;
+}
+
+/* Set status of additional camera capabilities */
+static int ov9640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct i2c_client *client = sd->priv;
+	struct ov9640_priv *priv = container_of(i2c_get_clientdata(client),
+					struct ov9640_priv, subdev);
+
+	int ret = 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_VFLIP:
+		priv->flag_vflip = ctrl->value;
+		if (ctrl->value)
+			ret = ov9640_reg_rmw(client, OV9640_MVFP,
+							OV9640_MVFP_V, 0);
+		else
+			ret = ov9640_reg_rmw(client, OV9640_MVFP,
+							0, OV9640_MVFP_V);
+		break;
+	case V4L2_CID_HFLIP:
+		priv->flag_hflip = ctrl->value;
+		if (ctrl->value)
+			ret = ov9640_reg_rmw(client, OV9640_MVFP,
+							OV9640_MVFP_H, 0);
+		else
+			ret = ov9640_reg_rmw(client, OV9640_MVFP,
+							0, OV9640_MVFP_H);
+		break;
+	}
+
+	return ret;
+}
+
+/* Get chip identification */
+static int ov9640_g_chip_ident(struct v4l2_subdev *sd,
+				struct v4l2_dbg_chip_ident *id)
+{
+	struct i2c_client *client = sd->priv;
+	struct ov9640_priv *priv = container_of(i2c_get_clientdata(client),
+					struct ov9640_priv, subdev);
+
+	id->ident	= priv->model;
+	id->revision	= priv->revision;
+
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int ov9640_get_register(struct v4l2_subdev *sd,
+				struct v4l2_dbg_register *reg)
+{
+	struct i2c_client *client = sd->priv;
+	int ret;
+	u8 val;
+
+	if (reg->reg & ~0xff)
+		return -EINVAL;
+
+	reg->size = 1;
+
+	ret = ov9640_reg_read(client, reg->reg, &val);
+	if (ret)
+		return ret;
+
+	reg->val = (__u64)val;
+
+	return 0;
+}
+
+static int ov9640_set_register(struct v4l2_subdev *sd,
+				struct v4l2_dbg_register *reg)
+{
+	struct i2c_client *client = sd->priv;
+
+	if (reg->reg & ~0xff || reg->val & ~0xff)
+		return -EINVAL;
+
+	return ov9640_reg_write(client, reg->reg, reg->val);
+}
+#endif
+
+/* select nearest higher resolution for capture */
+static void ov9640_res_roundup(u32 *width, u32 *height)
+{
+	int i;
+	enum { QQCIF, QQVGA, QCIF, QVGA, CIF, VGA, SXGA };
+	int res_x[] = { 88, 160, 176, 320, 352, 640, 1280 };
+	int res_y[] = { 72, 120, 144, 240, 288, 480, 960 };
+
+	for (i = 0; i < ARRAY_SIZE(res_x); i++) {
+		if (res_x[i] >= *width && res_y[i] >= *height) {
+			*width = res_x[i];
+			*height = res_y[i];
+			return;
+		}
+	}
+
+	*width = res_x[SXGA];
+	*height = res_y[SXGA];
+}
+
+/* Prepare necessary register changes depending on color encoding */
+static void ov9640_alter_regs(u32 pixfmt, struct ov9640_reg_alt *alt)
+{
+	switch (pixfmt) {
+	case V4L2_PIX_FMT_UYVY:
+		alt->com12	= OV9640_COM12_YUV_AVG;
+		alt->com13	= OV9640_COM13_Y_DELAY_EN |
+					OV9640_COM13_YUV_DLY(0x01);
+		break;
+	case V4L2_PIX_FMT_RGB555:
+		alt->com7	= OV9640_COM7_RGB;
+		alt->com13	= OV9640_COM13_RGB_AVG;
+		alt->com15	= OV9640_COM15_RGB_555;
+		break;
+	case V4L2_PIX_FMT_RGB565:
+		alt->com7	= OV9640_COM7_RGB;
+		alt->com13	= OV9640_COM13_RGB_AVG;
+		alt->com15	= OV9640_COM15_RGB_565;
+		break;
+	};
+}
+
+/* Setup registers according to resolution and color encoding */
+static int ov9640_write_regs(struct i2c_client *client,
+		u32 width, u32 pixfmt, struct ov9640_reg_alt *alts)
+{
+	const struct ov9640_reg	*ov9640_regs, *matrix_regs;
+	int			ov9640_regs_len, matrix_regs_len;
+	int			i, ret;
+	u8			val;
+
+	/* select register configuration for given resolution */
+	switch (width) {
+	case W_QQCIF:
+		ov9640_regs	= ov9640_regs_qqcif;
+		ov9640_regs_len	= ARRAY_SIZE(ov9640_regs_qqcif);
+		break;
+	case W_QQVGA:
+		ov9640_regs	= ov9640_regs_qqvga;
+		ov9640_regs_len	= ARRAY_SIZE(ov9640_regs_qqvga);
+		break;
+	case W_QCIF:
+		ov9640_regs	= ov9640_regs_qcif;
+		ov9640_regs_len	= ARRAY_SIZE(ov9640_regs_qcif);
+		break;
+	case W_QVGA:
+		ov9640_regs	= ov9640_regs_qvga;
+		ov9640_regs_len	= ARRAY_SIZE(ov9640_regs_qvga);
+		break;
+	case W_CIF:
+		ov9640_regs	= ov9640_regs_cif;
+		ov9640_regs_len	= ARRAY_SIZE(ov9640_regs_cif);
+		break;
+	case W_VGA:
+		ov9640_regs	= ov9640_regs_vga;
+		ov9640_regs_len	= ARRAY_SIZE(ov9640_regs_vga);
+		break;
+	case W_SXGA:
+		ov9640_regs	= ov9640_regs_sxga;
+		ov9640_regs_len	= ARRAY_SIZE(ov9640_regs_sxga);
+		break;
+	default:
+		dev_err(&client->dev, "Failed to select resolution!\n");
+		return -EINVAL;
+	}
+
+	/* select color matrix configuration for given color encoding */
+	if (pixfmt == V4L2_PIX_FMT_UYVY) {
+		matrix_regs	= ov9640_regs_yuv;
+		matrix_regs_len	= ARRAY_SIZE(ov9640_regs_yuv);
+	} else {
+		matrix_regs	= ov9640_regs_rgb;
+		matrix_regs_len	= ARRAY_SIZE(ov9640_regs_rgb);
+	}
+
+	/* write register settings into the module */
+	for (i = 0; i < ov9640_regs_len; i++) {
+		val = ov9640_regs[i].val;
+
+		switch (ov9640_regs[i].reg) {
+		case OV9640_COM7:
+			val |= alts->com7;
+			break;
+		case OV9640_COM12:
+			val |= alts->com12;
+			break;
+		case OV9640_COM13:
+			val |= alts->com13;
+			break;
+		case OV9640_COM15:
+			val |= alts->com15;
+			break;
+		}
+
+		ret = ov9640_reg_write(client, ov9640_regs[i].reg, val);
+		if (ret)
+			return ret;
+	}
+
+	/* write color matrix configuration into the module */
+	for (i = 0; i < matrix_regs_len; i++) {
+		ret = ov9640_reg_write(client, matrix_regs[i].reg,
+						matrix_regs[i].val);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+/* program default register values */
+static int ov9640_prog_dflt(struct i2c_client *client)
+{
+	int i, ret;
+
+	for (i = 0; i < ARRAY_SIZE(ov9640_regs_dflt); i++) {
+		ret = ov9640_reg_write(client, ov9640_regs_dflt[i].reg,
+						ov9640_regs_dflt[i].val);
+		if (ret)
+			return ret;
+	}
+
+	/* wait for the changes to actually happen, 140ms are not enough yet */
+	mdelay(150);
+
+	return 0;
+}
+
+/* set the format we will capture in */
+static int ov9640_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+	struct i2c_client *client = sd->priv;
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+	struct ov9640_reg_alt alts = {0};
+	int ret;
+
+	ov9640_res_roundup(&pix->width, &pix->height);
+	ov9640_alter_regs(pix->pixelformat, &alts);
+
+	ov9640_reset(client);
+
+	ret = ov9640_prog_dflt(client);
+	if (ret)
+		return ret;
+
+	return ov9640_write_regs(client, pix->width, pix->pixelformat, &alts);
+}
+
+static int ov9640_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+
+	ov9640_res_roundup(&pix->width, &pix->height);
+	pix->field  = V4L2_FIELD_NONE;
+
+	return 0;
+}
+
+static int ov9640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+{
+	a->c.left	= 0;
+	a->c.top	= 0;
+	a->c.width	= W_SXGA;
+	a->c.height	= H_SXGA;
+	a->type		= V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	return 0;
+}
+
+static int ov9640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
+{
+	a->bounds.left			= 0;
+	a->bounds.top			= 0;
+	a->bounds.width			= W_SXGA;
+	a->bounds.height		= H_SXGA;
+	a->defrect			= a->bounds;
+	a->type				= V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	a->pixelaspect.numerator	= 1;
+	a->pixelaspect.denominator	= 1;
+
+	return 0;
+}
+
+
+
+static int ov9640_video_probe(struct soc_camera_device *icd,
+				struct i2c_client *client)
+{
+	struct ov9640_priv *priv = i2c_get_clientdata(client);
+	u8		pid, ver, midh, midl;
+	const char	*devname;
+	int		ret = 0;
+
+	/*
+	 * We must have a parent by now. And it cannot be a wrong one.
+	 * So this entire test is completely redundant.
+	 */
+	if (!icd->dev.parent ||
+	    to_soc_camera_host(icd->dev.parent)->nr != icd->iface) {
+		dev_err(&client->dev, "Parent missing or invalid!\n");
+		ret = -ENODEV;
+		goto err;
+	}
+
+	icd->formats		= ov9640_fmt_lists;
+	icd->num_formats	= ARRAY_SIZE(ov9640_fmt_lists);
+
+	/*
+	 * check and show product ID and manufacturer ID
+	 */
+
+	ret = ov9640_reg_read(client, OV9640_PID, &pid);
+	if (ret)
+		goto err;
+
+	ret = ov9640_reg_read(client, OV9640_VER, &ver);
+	if (ret)
+		goto err;
+
+	ret = ov9640_reg_read(client, OV9640_MIDH, &midh);
+	if (ret)
+		goto err;
+
+	ret = ov9640_reg_read(client, OV9640_MIDL, &midl);
+	if (ret)
+		goto err;
+
+	switch (VERSION(pid, ver)) {
+	case OV9640_V2:
+		devname		= "ov9640";
+		priv->model	= V4L2_IDENT_OV9640;
+		priv->revision	= 2;
+	case OV9640_V3:
+		devname		= "ov9640";
+		priv->model	= V4L2_IDENT_OV9640;
+		priv->revision	= 3;
+		break;
+	default:
+		dev_err(&client->dev, "Product ID error %x:%x\n", pid, ver);
+		ret = -ENODEV;
+		goto err;
+	}
+
+	dev_info(&client->dev, "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
+		 devname, pid, ver, midh, midl);
+
+err:
+	return ret;
+}
+
+static struct soc_camera_ops ov9640_ops = {
+	.set_bus_param		= ov9640_set_bus_param,
+	.query_bus_param	= ov9640_query_bus_param,
+	.controls		= ov9640_controls,
+	.num_controls		= ARRAY_SIZE(ov9640_controls),
+};
+
+static struct v4l2_subdev_core_ops ov9640_core_ops = {
+	.g_ctrl			= ov9640_g_ctrl,
+	.s_ctrl			= ov9640_s_ctrl,
+	.g_chip_ident		= ov9640_g_chip_ident,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.g_register		= ov9640_get_register,
+	.s_register		= ov9640_set_register,
+#endif
+
+};
+
+static struct v4l2_subdev_video_ops ov9640_video_ops = {
+	.s_stream		= ov9640_s_stream,
+	.s_fmt			= ov9640_s_fmt,
+	.try_fmt		= ov9640_try_fmt,
+	.cropcap		= ov9640_cropcap,
+	.g_crop			= ov9640_g_crop,
+
+};
+
+static struct v4l2_subdev_ops ov9640_subdev_ops = {
+	.core	= &ov9640_core_ops,
+	.video	= &ov9640_video_ops,
+};
+
+/*
+ * i2c_driver function
+ */
+static int ov9640_probe(struct i2c_client *client,
+			const struct i2c_device_id *did)
+{
+	struct ov9640_priv *priv;
+	struct soc_camera_device *icd	= client->dev.platform_data;
+	struct soc_camera_link *icl;
+	int ret;
+
+	if (!icd) {
+		dev_err(&client->dev, "Missing soc-camera data!\n");
+		return -EINVAL;
+	}
+
+	icl = to_soc_camera_link(icd);
+	if (!icl) {
+		dev_err(&client->dev, "Missing platform_data for driver\n");
+		return -EINVAL;
+	}
+
+	priv = kzalloc(sizeof(struct ov9640_priv), GFP_KERNEL);
+	if (!priv) {
+		dev_err(&client->dev,
+			"Failed to allocate memory for private data!\n");
+		return -ENOMEM;
+	}
+
+	v4l2_i2c_subdev_init(&priv->subdev, client, &ov9640_subdev_ops);
+
+	icd->ops	= &ov9640_ops;
+
+	ret = ov9640_video_probe(icd, client);
+
+	if (ret) {
+		icd->ops = NULL;
+		i2c_set_clientdata(client, NULL);
+		kfree(priv);
+	}
+
+	return ret;
+}
+
+static int ov9640_remove(struct i2c_client *client)
+{
+	struct ov9640_priv *priv = i2c_get_clientdata(client);
+
+	i2c_set_clientdata(client, NULL);
+	kfree(priv);
+	return 0;
+}
+
+static const struct i2c_device_id ov9640_id[] = {
+	{ "ov9640", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ov9640_id);
+
+static struct i2c_driver ov9640_i2c_driver = {
+	.driver = {
+		.name = "ov9640",
+	},
+	.probe    = ov9640_probe,
+	.remove   = ov9640_remove,
+	.id_table = ov9640_id,
+};
+
+static int __init ov9640_module_init(void)
+{
+	return i2c_add_driver(&ov9640_i2c_driver);
+}
+
+static void __exit ov9640_module_exit(void)
+{
+	i2c_del_driver(&ov9640_i2c_driver);
+}
+
+module_init(ov9640_module_init);
+module_exit(ov9640_module_exit);
+
+MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV96xx");
+MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/ov9640.h b/drivers/media/video/ov9640.h
new file mode 100644
index 0000000..f8a51b7
--- /dev/null
+++ b/drivers/media/video/ov9640.h
@@ -0,0 +1,209 @@
+/*
+ * OmniVision OV96xx Camera Header File
+ *
+ * Copyright (C) 2009 Marek Vasut <marek.vasut@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.
+ */
+
+#ifndef	__DRIVERS_MEDIA_VIDEO_OV9640_H__
+#define	__DRIVERS_MEDIA_VIDEO_OV9640_H__
+
+/* Register definitions */
+#define	OV9640_GAIN	0x00
+#define	OV9640_BLUE	0x01
+#define	OV9640_RED	0x02
+#define	OV9640_VFER	0x03
+#define	OV9640_COM1	0x04
+#define	OV9640_BAVE	0x05
+#define	OV9640_GEAVE	0x06
+#define	OV9640_RSID	0x07
+#define	OV9640_RAVE	0x08
+#define	OV9640_COM2	0x09
+#define	OV9640_PID	0x0a
+#define	OV9640_VER	0x0b
+#define	OV9640_COM3	0x0c
+#define	OV9640_COM4	0x0d
+#define	OV9640_COM5	0x0e
+#define	OV9640_COM6	0x0f
+#define	OV9640_AECH	0x10
+#define	OV9640_CLKRC	0x11
+#define	OV9640_COM7	0x12
+#define	OV9640_COM8	0x13
+#define	OV9640_COM9	0x14
+#define	OV9640_COM10	0x15
+/* 0x16 - RESERVED */
+#define	OV9640_HSTART	0x17
+#define	OV9640_HSTOP	0x18
+#define	OV9640_VSTART	0x19
+#define	OV9640_VSTOP	0x1a
+#define	OV9640_PSHFT	0x1b
+#define	OV9640_MIDH	0x1c
+#define	OV9640_MIDL	0x1d
+#define	OV9640_MVFP	0x1e
+#define	OV9640_LAEC	0x1f
+#define	OV9640_BOS	0x20
+#define	OV9640_GBOS	0x21
+#define	OV9640_GROS	0x22
+#define	OV9640_ROS	0x23
+#define	OV9640_AEW	0x24
+#define	OV9640_AEB	0x25
+#define	OV9640_VPT	0x26
+#define	OV9640_BBIAS	0x27
+#define	OV9640_GBBIAS	0x28
+/* 0x29 - RESERVED */
+#define	OV9640_EXHCH	0x2a
+#define	OV9640_EXHCL	0x2b
+#define	OV9640_RBIAS	0x2c
+#define	OV9640_ADVFL	0x2d
+#define	OV9640_ADVFH	0x2e
+#define	OV9640_YAVE	0x2f
+#define	OV9640_HSYST	0x30
+#define	OV9640_HSYEN	0x31
+#define	OV9640_HREF	0x32
+#define	OV9640_CHLF	0x33
+#define	OV9640_ARBLM	0x34
+/* 0x35..0x36 - RESERVED */
+#define	OV9640_ADC	0x37
+#define	OV9640_ACOM	0x38
+#define	OV9640_OFON	0x39
+#define	OV9640_TSLB	0x3a
+#define	OV9640_COM11	0x3b
+#define	OV9640_COM12	0x3c
+#define	OV9640_COM13	0x3d
+#define	OV9640_COM14	0x3e
+#define	OV9640_EDGE	0x3f
+#define	OV9640_COM15	0x40
+#define	OV9640_COM16	0x41
+#define	OV9640_COM17	0x42
+/* 0x43..0x4e - RESERVED */
+#define	OV9640_MTX1	0x4f
+#define	OV9640_MTX2	0x50
+#define	OV9640_MTX3	0x51
+#define	OV9640_MTX4	0x52
+#define	OV9640_MTX5	0x53
+#define	OV9640_MTX6	0x54
+#define	OV9640_MTX7	0x55
+#define	OV9640_MTX8	0x56
+#define	OV9640_MTX9	0x57
+#define	OV9640_MTXS	0x58
+/* 0x59..0x61 - RESERVED */
+#define	OV9640_LCC1	0x62
+#define	OV9640_LCC2	0x63
+#define	OV9640_LCC3	0x64
+#define	OV9640_LCC4	0x65
+#define	OV9640_LCC5	0x66
+#define	OV9640_MANU	0x67
+#define	OV9640_MANV	0x68
+#define	OV9640_HV	0x69
+#define	OV9640_MBD	0x6a
+#define	OV9640_DBLV	0x6b
+#define	OV9640_GSP	0x6c	/* ... till 0x7b */
+#define	OV9640_GST	0x7c	/* ... till 0x8a */
+
+#define	OV9640_CLKRC_DPLL_EN	0x80
+#define	OV9640_CLKRC_DIRECT	0x40
+#define	OV9640_CLKRC_DIV(x)	((x) & 0x3f)
+
+#define	OV9640_PSHFT_VAL(x)	((x) & 0xff)
+
+#define	OV9640_ACOM_2X_ANALOG	0x80
+#define	OV9640_ACOM_RSVD	0x12
+
+#define	OV9640_MVFP_V		0x10
+#define	OV9640_MVFP_H		0x20
+
+#define	OV9640_COM1_HREF_NOSKIP	0x00
+#define	OV9640_COM1_HREF_2SKIP	0x04
+#define	OV9640_COM1_HREF_3SKIP	0x08
+#define	OV9640_COM1_QQFMT	0x20
+
+#define	OV9640_COM2_SSM		0x10
+
+#define	OV9640_COM3_VP		0x04
+
+#define	OV9640_COM4_QQ_VP	0x80
+#define	OV9640_COM4_RSVD	0x40
+
+#define	OV9640_COM5_SYSCLK	0x80
+#define	OV9640_COM5_LONGEXP	0x01
+
+#define	OV9640_COM6_OPT_BLC	0x40
+#define	OV9640_COM6_ADBLC_BIAS	0x08
+#define	OV9640_COM6_FMT_RST	0x82
+#define	OV9640_COM6_ADBLC_OPTEN	0x01
+
+#define	OV9640_COM7_RAW_RGB	0x01
+#define	OV9640_COM7_RGB		0x04
+#define	OV9640_COM7_QCIF	0x08
+#define	OV9640_COM7_QVGA	0x10
+#define	OV9640_COM7_CIF		0x20
+#define	OV9640_COM7_VGA		0x40
+#define	OV9640_COM7_SCCB_RESET	0x80
+
+#define	OV9640_TSLB_YVYU_YUYV	0x04
+#define	OV9640_TSLB_YUYV_UYVY	0x08
+
+#define	OV9640_COM12_YUV_AVG	0x04
+#define	OV9640_COM12_RSVD	0x40
+
+#define	OV9640_COM13_GAMMA_NONE	0x00
+#define	OV9640_COM13_GAMMA_Y	0x40
+#define	OV9640_COM13_GAMMA_RAW	0x80
+#define	OV9640_COM13_RGB_AVG	0x20
+#define	OV9640_COM13_MATRIX_EN	0x10
+#define	OV9640_COM13_Y_DELAY_EN	0x08
+#define	OV9640_COM13_YUV_DLY(x)	((x) & 0x07)
+
+#define	OV9640_COM15_OR_00FF	0x00
+#define	OV9640_COM15_OR_01FE	0x40
+#define	OV9640_COM15_OR_10F0	0xc0
+#define	OV9640_COM15_RGB_NORM	0x00
+#define	OV9640_COM15_RGB_565	0x10
+#define	OV9640_COM15_RGB_555	0x30
+
+#define	OV9640_COM16_RB_AVG	0x01
+
+/* IDs */
+#define	OV9640_V2		0x9648
+#define	OV9640_V3		0x9649
+#define	VERSION(pid, ver)	(((pid) << 8) | ((ver) & 0xFF))
+
+/* supported resolutions */
+enum {
+	W_QQCIF	= 88,
+	W_QQVGA	= 160,
+	W_QCIF	= 176,
+	W_QVGA	= 320,
+	W_CIF	= 352,
+	W_VGA	= 640,
+	W_SXGA	= 1280
+};
+#define	H_SXGA	960
+
+/* Misc. structures */
+struct ov9640_reg_alt {
+	u8	com7;
+	u8	com12;
+	u8	com13;
+	u8	com15;
+};
+
+struct ov9640_reg {
+	u8	reg;
+	u8	val;
+};
+
+struct ov9640_priv {
+	struct v4l2_subdev		subdev;
+
+	int				model;
+	int				revision;
+
+	bool				flag_vflip;
+	bool				flag_hflip;
+};
+
+#endif	/* __DRIVERS_MEDIA_VIDEO_OV9640_H__ */
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
index a1ad38f..73ec970 100644
--- a/drivers/media/video/pms.c
+++ b/drivers/media/video/pms.c
@@ -14,8 +14,10 @@
  *	unless the userspace driver also doesn't work for you...
  *
  *      Changes:
- *      08/07/2003        Daniele Bellucci <bellucda@tiscali.it>
- *                        - pms_capture: report back -EFAULT
+ *	25-11-2009 	Hans Verkuil <hverkuil@xs4all.nl>
+ * 			- converted to version 2 of the V4L API.
+ *      08/07/2003      Daniele Bellucci <bellucda@tiscali.it>
+ *                      - pms_capture: report back -EFAULT
  */
 
 #include <linux/module.h>
@@ -27,175 +29,183 @@
 #include <linux/mm.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
+#include <linux/version.h>
+#include <linux/mutex.h>
+#include <asm/uaccess.h>
 #include <asm/io.h>
-#include <linux/videodev.h>
+
+#include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
-#include <linux/mutex.h>
+#include <media/v4l2-device.h>
 
-#include <asm/uaccess.h>
+MODULE_LICENSE("GPL");
 
 
 #define MOTOROLA	1
-#define PHILIPS2	2
+#define PHILIPS2	2               /* SAA7191 */
 #define PHILIPS1	3
 #define MVVMEMORYWIDTH	0x40		/* 512 bytes */
 
-struct pms_device
-{
-	struct video_device v;
-	struct video_picture picture;
-	int height;
-	int width;
-	unsigned long in_use;
-	struct mutex lock;
-};
-
-struct i2c_info
-{
+struct i2c_info {
 	u8 slave;
 	u8 sub;
 	u8 data;
 	u8 hits;
 };
 
-static int i2c_count;
-static struct i2c_info i2cinfo[64];
+struct pms {
+	struct v4l2_device v4l2_dev;
+	struct video_device vdev;
+	int height;
+	int width;
+	int depth;
+	int input;
+	s32 brightness, saturation, hue, contrast;
+	unsigned long in_use;
+	struct mutex lock;
+	int i2c_count;
+	struct i2c_info i2cinfo[64];
 
-static int decoder 		= PHILIPS2;
-static int standard;	/* 0 - auto 1 - ntsc 2 - pal 3 - secam */
+	int decoder;
+	int standard;	/* 0 - auto 1 - ntsc 2 - pal 3 - secam */
+	v4l2_std_id std;
+	int io;
+	int data;
+	void __iomem *mem;
+};
+
+static struct pms pms_card;
 
 /*
  *	I/O ports and Shared Memory
  */
 
-static int io_port		=	0x250;
-static int data_port		=	0x251;
-static int mem_base		=	0xC8000;
-static void __iomem *mem;
-static int video_nr             =       -1;
+static int io_port = 0x250;
+module_param(io_port, int, 0);
+
+static int mem_base = 0xc8000;
+module_param(mem_base, int, 0);
+
+static int video_nr = -1;
+module_param(video_nr, int, 0);
 
 
-
-static inline void mvv_write(u8 index, u8 value)
+static inline void mvv_write(struct pms *dev, u8 index, u8 value)
 {
-	outw(index|(value<<8), io_port);
+	outw(index | (value << 8), dev->io);
 }
 
-static inline u8 mvv_read(u8 index)
+static inline u8 mvv_read(struct pms *dev, u8 index)
 {
-	outb(index, io_port);
-	return inb(data_port);
+	outb(index, dev->io);
+	return inb(dev->data);
 }
 
-static int pms_i2c_stat(u8 slave)
+static int pms_i2c_stat(struct pms *dev, u8 slave)
 {
-	int counter;
+	int counter = 0;
 	int i;
 
-	outb(0x28, io_port);
+	outb(0x28, dev->io);
 
-	counter=0;
-	while((inb(data_port)&0x01)==0)
-		if(counter++==256)
+	while ((inb(dev->data) & 0x01) == 0)
+		if (counter++ == 256)
 			break;
 
-	while((inb(data_port)&0x01)!=0)
-		if(counter++==256)
+	while ((inb(dev->data) & 0x01) != 0)
+		if (counter++ == 256)
 			break;
 
-	outb(slave, io_port);
+	outb(slave, dev->io);
 
-	counter=0;
-	while((inb(data_port)&0x01)==0)
-		if(counter++==256)
+	counter = 0;
+	while ((inb(dev->data) & 0x01) == 0)
+		if (counter++ == 256)
 			break;
 
-	while((inb(data_port)&0x01)!=0)
-		if(counter++==256)
+	while ((inb(dev->data) & 0x01) != 0)
+		if (counter++ == 256)
 			break;
 
-	for(i=0;i<12;i++)
-	{
-		char st=inb(data_port);
-		if((st&2)!=0)
+	for (i = 0; i < 12; i++) {
+		char st = inb(dev->data);
+
+		if ((st & 2) != 0)
 			return -1;
-		if((st&1)==0)
+		if ((st & 1) == 0)
 			break;
 	}
-	outb(0x29, io_port);
-	return inb(data_port);
+	outb(0x29, dev->io);
+	return inb(dev->data);
 }
 
-static int pms_i2c_write(u16 slave, u16 sub, u16 data)
+static int pms_i2c_write(struct pms *dev, u16 slave, u16 sub, u16 data)
 {
-	int skip=0;
+	int skip = 0;
 	int count;
 	int i;
 
-	for(i=0;i<i2c_count;i++)
-	{
-		if((i2cinfo[i].slave==slave) &&
-		   (i2cinfo[i].sub == sub))
-		{
-			if(i2cinfo[i].data==data)
-				skip=1;
-			i2cinfo[i].data=data;
-			i=i2c_count+1;
+	for (i = 0; i < dev->i2c_count; i++) {
+		if ((dev->i2cinfo[i].slave == slave) &&
+		    (dev->i2cinfo[i].sub == sub)) {
+			if (dev->i2cinfo[i].data == data)
+				skip = 1;
+			dev->i2cinfo[i].data = data;
+			i = dev->i2c_count + 1;
 		}
 	}
 
-	if(i==i2c_count && i2c_count<64)
-	{
-		i2cinfo[i2c_count].slave=slave;
-		i2cinfo[i2c_count].sub=sub;
-		i2cinfo[i2c_count].data=data;
-		i2c_count++;
+	if (i == dev->i2c_count && dev->i2c_count < 64) {
+		dev->i2cinfo[dev->i2c_count].slave = slave;
+		dev->i2cinfo[dev->i2c_count].sub = sub;
+		dev->i2cinfo[dev->i2c_count].data = data;
+		dev->i2c_count++;
 	}
 
-	if(skip)
+	if (skip)
 		return 0;
 
-	mvv_write(0x29, sub);
-	mvv_write(0x2A, data);
-	mvv_write(0x28, slave);
+	mvv_write(dev, 0x29, sub);
+	mvv_write(dev, 0x2A, data);
+	mvv_write(dev, 0x28, slave);
 
-	outb(0x28, io_port);
+	outb(0x28, dev->io);
 
-	count=0;
-	while((inb(data_port)&1)==0)
-		if(count>255)
+	count = 0;
+	while ((inb(dev->data) & 1) == 0)
+		if (count > 255)
 			break;
-	while((inb(data_port)&1)!=0)
-		if(count>255)
+	while ((inb(dev->data) & 1) != 0)
+		if (count > 255)
 			break;
 
-	count=inb(data_port);
+	count = inb(dev->data);
 
-	if(count&2)
+	if (count & 2)
 		return -1;
 	return count;
 }
 
-static int pms_i2c_read(int slave, int sub)
+static int pms_i2c_read(struct pms *dev, int slave, int sub)
 {
-	int i=0;
-	for(i=0;i<i2c_count;i++)
-	{
-		if(i2cinfo[i].slave==slave && i2cinfo[i].sub==sub)
-			return i2cinfo[i].data;
+	int i;
+
+	for (i = 0; i < dev->i2c_count; i++) {
+		if (dev->i2cinfo[i].slave == slave && dev->i2cinfo[i].sub == sub)
+			return dev->i2cinfo[i].data;
 	}
 	return 0;
 }
 
 
-static void pms_i2c_andor(int slave, int sub, int and, int or)
+static void pms_i2c_andor(struct pms *dev, int slave, int sub, int and, int or)
 {
 	u8 tmp;
 
-	tmp=pms_i2c_read(slave, sub);
-	tmp = (tmp&and)|or;
-	pms_i2c_write(slave, sub, tmp);
+	tmp = pms_i2c_read(dev, slave, sub);
+	tmp = (tmp & and) | or;
+	pms_i2c_write(dev, slave, sub, tmp);
 }
 
 /*
@@ -203,100 +213,108 @@
  */
 
 
-static void pms_videosource(short source)
+static void pms_videosource(struct pms *dev, short source)
 {
-	mvv_write(0x2E, source?0x31:0x30);
+	switch (dev->decoder) {
+	case MOTOROLA:
+		break;
+	case PHILIPS2:
+		pms_i2c_andor(dev, 0x8a, 0x06, 0x7f, source ? 0x80 : 0);
+		break;
+	case PHILIPS1:
+		break;
+	}
+	mvv_write(dev, 0x2E, 0x31);
+	/* Was: mvv_write(dev, 0x2E, source ? 0x31 : 0x30);
+	   But could not make this work correctly. Only Composite input
+	   worked for me. */
 }
 
-static void pms_hue(short hue)
+static void pms_hue(struct pms *dev, short hue)
 {
-	switch(decoder)
-	{
-		case MOTOROLA:
-			pms_i2c_write(0x8A, 0x00, hue);
-			break;
-		case PHILIPS2:
-			pms_i2c_write(0x8A, 0x07, hue);
-			break;
-		case PHILIPS1:
-			pms_i2c_write(0x42, 0x07, hue);
-			break;
+	switch (dev->decoder) {
+	case MOTOROLA:
+		pms_i2c_write(dev, 0x8a, 0x00, hue);
+		break;
+	case PHILIPS2:
+		pms_i2c_write(dev, 0x8a, 0x07, hue);
+		break;
+	case PHILIPS1:
+		pms_i2c_write(dev, 0x42, 0x07, hue);
+		break;
 	}
 }
 
-static void pms_colour(short colour)
+static void pms_saturation(struct pms *dev, short sat)
 {
-	switch(decoder)
-	{
-		case MOTOROLA:
-			pms_i2c_write(0x8A, 0x00, colour);
-			break;
-		case PHILIPS1:
-			pms_i2c_write(0x42, 0x12, colour);
-			break;
+	switch (dev->decoder) {
+	case MOTOROLA:
+		pms_i2c_write(dev, 0x8a, 0x00, sat);
+		break;
+	case PHILIPS1:
+		pms_i2c_write(dev, 0x42, 0x12, sat);
+		break;
 	}
 }
 
 
-static void pms_contrast(short contrast)
+static void pms_contrast(struct pms *dev, short contrast)
 {
-	switch(decoder)
-	{
-		case MOTOROLA:
-			pms_i2c_write(0x8A, 0x00, contrast);
-			break;
-		case PHILIPS1:
-			pms_i2c_write(0x42, 0x13, contrast);
-			break;
+	switch (dev->decoder) {
+	case MOTOROLA:
+		pms_i2c_write(dev, 0x8a, 0x00, contrast);
+		break;
+	case PHILIPS1:
+		pms_i2c_write(dev, 0x42, 0x13, contrast);
+		break;
 	}
 }
 
-static void pms_brightness(short brightness)
+static void pms_brightness(struct pms *dev, short brightness)
 {
-	switch(decoder)
-	{
-		case MOTOROLA:
-			pms_i2c_write(0x8A, 0x00, brightness);
-			pms_i2c_write(0x8A, 0x00, brightness);
-			pms_i2c_write(0x8A, 0x00, brightness);
-			break;
-		case PHILIPS1:
-			pms_i2c_write(0x42, 0x19, brightness);
-			break;
+	switch (dev->decoder) {
+	case MOTOROLA:
+		pms_i2c_write(dev, 0x8a, 0x00, brightness);
+		pms_i2c_write(dev, 0x8a, 0x00, brightness);
+		pms_i2c_write(dev, 0x8a, 0x00, brightness);
+		break;
+	case PHILIPS1:
+		pms_i2c_write(dev, 0x42, 0x19, brightness);
+		break;
 	}
 }
 
 
-static void pms_format(short format)
+static void pms_format(struct pms *dev, short format)
 {
 	int target;
-	standard = format;
 
-	if(decoder==PHILIPS1)
-		target=0x42;
-	else if(decoder==PHILIPS2)
-		target=0x8A;
+	dev->standard = format;
+
+	if (dev->decoder == PHILIPS1)
+		target = 0x42;
+	else if (dev->decoder == PHILIPS2)
+		target = 0x8a;
 	else
 		return;
 
-	switch(format)
-	{
-		case 0:	/* Auto */
-			pms_i2c_andor(target, 0x0D, 0xFE,0x00);
-			pms_i2c_andor(target, 0x0F, 0x3F,0x80);
-			break;
-		case 1: /* NTSC */
-			pms_i2c_andor(target, 0x0D, 0xFE, 0x00);
-			pms_i2c_andor(target, 0x0F, 0x3F, 0x40);
-			break;
-		case 2: /* PAL */
-			pms_i2c_andor(target, 0x0D, 0xFE, 0x00);
-			pms_i2c_andor(target, 0x0F, 0x3F, 0x00);
-			break;
-		case 3:	/* SECAM */
-			pms_i2c_andor(target, 0x0D, 0xFE, 0x01);
-			pms_i2c_andor(target, 0x0F, 0x3F, 0x00);
-			break;
+	switch (format) {
+	case 0:	/* Auto */
+		pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
+		pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x80);
+		break;
+	case 1: /* NTSC */
+		pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
+		pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x40);
+		break;
+	case 2: /* PAL */
+		pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
+		pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x00);
+		break;
+	case 3:	/* SECAM */
+		pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x01);
+		pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x00);
+		break;
 	}
 }
 
@@ -308,18 +326,17 @@
  *	people need it. We also don't yet use the PMS interrupt.
  */
 
-static void pms_hstart(short start)
+static void pms_hstart(struct pms *dev, short start)
 {
-	switch(decoder)
-	{
-		case PHILIPS1:
-			pms_i2c_write(0x8A, 0x05, start);
-			pms_i2c_write(0x8A, 0x18, start);
-			break;
-		case PHILIPS2:
-			pms_i2c_write(0x42, 0x05, start);
-			pms_i2c_write(0x42, 0x18, start);
-			break;
+	switch (dev->decoder) {
+	case PHILIPS1:
+		pms_i2c_write(dev, 0x8a, 0x05, start);
+		pms_i2c_write(dev, 0x8a, 0x18, start);
+		break;
+	case PHILIPS2:
+		pms_i2c_write(dev, 0x42, 0x05, start);
+		pms_i2c_write(dev, 0x42, 0x18, start);
+		break;
 	}
 }
 
@@ -327,293 +344,271 @@
  *	Bandpass filters
  */
 
-static void pms_bandpass(short pass)
+static void pms_bandpass(struct pms *dev, short pass)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0x8A, 0x06, 0xCF, (pass&0x03)<<4);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42, 0x06, 0xCF, (pass&0x03)<<4);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0x8a, 0x06, 0xcf, (pass & 0x03) << 4);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x06, 0xcf, (pass & 0x03) << 4);
 }
 
-static void pms_antisnow(short snow)
+static void pms_antisnow(struct pms *dev, short snow)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0x8A, 0x06, 0xF3, (snow&0x03)<<2);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42, 0x06, 0xF3, (snow&0x03)<<2);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0x8a, 0x06, 0xf3, (snow & 0x03) << 2);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x06, 0xf3, (snow & 0x03) << 2);
 }
 
-static void pms_sharpness(short sharp)
+static void pms_sharpness(struct pms *dev, short sharp)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0x8A, 0x06, 0xFC, sharp&0x03);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42, 0x06, 0xFC, sharp&0x03);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0x8a, 0x06, 0xfc, sharp & 0x03);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x06, 0xfc, sharp & 0x03);
 }
 
-static void pms_chromaagc(short agc)
+static void pms_chromaagc(struct pms *dev, short agc)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0x8A, 0x0C, 0x9F, (agc&0x03)<<5);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42, 0x0C, 0x9F, (agc&0x03)<<5);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0x8a, 0x0c, 0x9f, (agc & 0x03) << 5);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x0c, 0x9f, (agc & 0x03) << 5);
 }
 
-static void pms_vertnoise(short noise)
+static void pms_vertnoise(struct pms *dev, short noise)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0x8A, 0x10, 0xFC, noise&3);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42, 0x10, 0xFC, noise&3);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0x8a, 0x10, 0xfc, noise & 3);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x10, 0xfc, noise & 3);
 }
 
-static void pms_forcecolour(short colour)
+static void pms_forcecolour(struct pms *dev, short colour)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0x8A, 0x0C, 0x7F, (colour&1)<<7);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42, 0x0C, 0x7, (colour&1)<<7);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0x8a, 0x0c, 0x7f, (colour & 1) << 7);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x0c, 0x7, (colour & 1) << 7);
 }
 
-static void pms_antigamma(short gamma)
+static void pms_antigamma(struct pms *dev, short gamma)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0xB8, 0x00, 0x7F, (gamma&1)<<7);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42, 0x20, 0x7, (gamma&1)<<7);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0xb8, 0x00, 0x7f, (gamma & 1) << 7);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x20, 0x7, (gamma & 1) << 7);
 }
 
-static void pms_prefilter(short filter)
+static void pms_prefilter(struct pms *dev, short filter)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0x8A, 0x06, 0xBF, (filter&1)<<6);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42, 0x06, 0xBF, (filter&1)<<6);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0x8a, 0x06, 0xbf, (filter & 1) << 6);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x06, 0xbf, (filter & 1) << 6);
 }
 
-static void pms_hfilter(short filter)
+static void pms_hfilter(struct pms *dev, short filter)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0xB8, 0x04, 0x1F, (filter&7)<<5);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42, 0x24, 0x1F, (filter&7)<<5);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0xb8, 0x04, 0x1f, (filter & 7) << 5);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x24, 0x1f, (filter & 7) << 5);
 }
 
-static void pms_vfilter(short filter)
+static void pms_vfilter(struct pms *dev, short filter)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0xB8, 0x08, 0x9F, (filter&3)<<5);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42, 0x28, 0x9F, (filter&3)<<5);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0xb8, 0x08, 0x9f, (filter & 3) << 5);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x28, 0x9f, (filter & 3) << 5);
 }
 
-static void pms_killcolour(short colour)
+static void pms_killcolour(struct pms *dev, short colour)
 {
-	if(decoder==PHILIPS2)
-	{
-		pms_i2c_andor(0x8A, 0x08, 0x07, (colour&0x1F)<<3);
-		pms_i2c_andor(0x8A, 0x09, 0x07, (colour&0x1F)<<3);
-	}
-	else if(decoder==PHILIPS1)
-	{
-		pms_i2c_andor(0x42, 0x08, 0x07, (colour&0x1F)<<3);
-		pms_i2c_andor(0x42, 0x09, 0x07, (colour&0x1F)<<3);
+	if (dev->decoder == PHILIPS2) {
+		pms_i2c_andor(dev, 0x8a, 0x08, 0x07, (colour & 0x1f) << 3);
+		pms_i2c_andor(dev, 0x8a, 0x09, 0x07, (colour & 0x1f) << 3);
+	} else if (dev->decoder == PHILIPS1) {
+		pms_i2c_andor(dev, 0x42, 0x08, 0x07, (colour & 0x1f) << 3);
+		pms_i2c_andor(dev, 0x42, 0x09, 0x07, (colour & 0x1f) << 3);
 	}
 }
 
-static void pms_chromagain(short chroma)
+static void pms_chromagain(struct pms *dev, short chroma)
 {
-	if(decoder==PHILIPS2)
-	{
-		pms_i2c_write(0x8A, 0x11, chroma);
-	}
-	else if(decoder==PHILIPS1)
-	{
-		pms_i2c_write(0x42, 0x11, chroma);
-	}
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_write(dev, 0x8a, 0x11, chroma);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_write(dev, 0x42, 0x11, chroma);
 }
 
 
-static void pms_spacialcompl(short data)
+static void pms_spacialcompl(struct pms *dev, short data)
 {
-	mvv_write(0x3B, data);
+	mvv_write(dev, 0x3b, data);
 }
 
-static void pms_spacialcomph(short data)
+static void pms_spacialcomph(struct pms *dev, short data)
 {
-	mvv_write(0x3A, data);
+	mvv_write(dev, 0x3a, data);
 }
 
-static void pms_vstart(short start)
+static void pms_vstart(struct pms *dev, short start)
 {
-	mvv_write(0x16, start);
-	mvv_write(0x17, (start>>8)&0x01);
+	mvv_write(dev, 0x16, start);
+	mvv_write(dev, 0x17, (start >> 8) & 0x01);
 }
 
 #endif
 
-static void pms_secamcross(short cross)
+static void pms_secamcross(struct pms *dev, short cross)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0x8A, 0x0F, 0xDF, (cross&1)<<5);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42, 0x0F, 0xDF, (cross&1)<<5);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0x8a, 0x0f, 0xdf, (cross & 1) << 5);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x0f, 0xdf, (cross & 1) << 5);
 }
 
 
-static void pms_swsense(short sense)
+static void pms_swsense(struct pms *dev, short sense)
 {
-	if(decoder==PHILIPS2)
-	{
-		pms_i2c_write(0x8A, 0x0A, sense);
-		pms_i2c_write(0x8A, 0x0B, sense);
-	}
-	else if(decoder==PHILIPS1)
-	{
-		pms_i2c_write(0x42, 0x0A, sense);
-		pms_i2c_write(0x42, 0x0B, sense);
+	if (dev->decoder == PHILIPS2) {
+		pms_i2c_write(dev, 0x8a, 0x0a, sense);
+		pms_i2c_write(dev, 0x8a, 0x0b, sense);
+	} else if (dev->decoder == PHILIPS1) {
+		pms_i2c_write(dev, 0x42, 0x0a, sense);
+		pms_i2c_write(dev, 0x42, 0x0b, sense);
 	}
 }
 
 
-static void pms_framerate(short frr)
+static void pms_framerate(struct pms *dev, short frr)
 {
-	int fps=(standard==1)?30:25;
-	if(frr==0)
+	int fps = (dev->std & V4L2_STD_525_60) ? 30 : 25;
+
+	if (frr == 0)
 		return;
-	fps=fps/frr;
-	mvv_write(0x14,0x80|fps);
-	mvv_write(0x15,1);
+	fps = fps/frr;
+	mvv_write(dev, 0x14, 0x80 | fps);
+	mvv_write(dev, 0x15, 1);
 }
 
-static void pms_vert(u8 deciden, u8 decinum)
+static void pms_vert(struct pms *dev, u8 deciden, u8 decinum)
 {
-	mvv_write(0x1C, deciden);	/* Denominator */
-	mvv_write(0x1D, decinum);	/* Numerator */
+	mvv_write(dev, 0x1c, deciden);	/* Denominator */
+	mvv_write(dev, 0x1d, decinum);	/* Numerator */
 }
 
 /*
  *	Turn 16bit ratios into best small ratio the chipset can grok
  */
 
-static void pms_vertdeci(unsigned short decinum, unsigned short deciden)
+static void pms_vertdeci(struct pms *dev, unsigned short decinum, unsigned short deciden)
 {
-	/* Knock it down by /5 once */
-	if(decinum%5==0)
-	{
-		deciden/=5;
-		decinum/=5;
+	/* Knock it down by / 5 once */
+	if (decinum % 5 == 0) {
+		deciden /= 5;
+		decinum /= 5;
 	}
 	/*
 	 *	3's
 	 */
-	while(decinum%3==0 && deciden%3==0)
-	{
-		deciden/=3;
-		decinum/=3;
+	while (decinum % 3 == 0 && deciden % 3 == 0) {
+		deciden /= 3;
+		decinum /= 3;
 	}
 	/*
 	 *	2's
 	 */
-	while(decinum%2==0 && deciden%2==0)
-	{
-		decinum/=2;
-		deciden/=2;
+	while (decinum % 2 == 0 && deciden % 2 == 0) {
+		decinum /= 2;
+		deciden /= 2;
 	}
 	/*
 	 *	Fudgyify
 	 */
-	while(deciden>32)
-	{
-		deciden/=2;
-		decinum=(decinum+1)/2;
+	while (deciden > 32) {
+		deciden /= 2;
+		decinum = (decinum + 1) / 2;
 	}
-	if(deciden==32)
+	if (deciden == 32)
 		deciden--;
-	pms_vert(deciden,decinum);
+	pms_vert(dev, deciden, decinum);
 }
 
-static void pms_horzdeci(short decinum, short deciden)
+static void pms_horzdeci(struct pms *dev, short decinum, short deciden)
 {
-	if(decinum<=512)
-	{
-		if(decinum%5==0)
-		{
-			decinum/=5;
-			deciden/=5;
+	if (decinum <= 512) {
+		if (decinum % 5 == 0) {
+			decinum /= 5;
+			deciden /= 5;
 		}
-	}
-	else
-	{
-		decinum=512;
-		deciden=640;	/* 768 would be ideal */
+	} else {
+		decinum = 512;
+		deciden = 640;	/* 768 would be ideal */
 	}
 
-	while(((decinum|deciden)&1)==0)
-	{
-		decinum>>=1;
-		deciden>>=1;
+	while (((decinum | deciden) & 1) == 0) {
+		decinum >>= 1;
+		deciden >>= 1;
 	}
-	while(deciden>32)
-	{
-		deciden>>=1;
-		decinum=(decinum+1)>>1;
+	while (deciden > 32) {
+		deciden >>= 1;
+		decinum = (decinum + 1) >> 1;
 	}
-	if(deciden==32)
+	if (deciden == 32)
 		deciden--;
 
-	mvv_write(0x24, 0x80|deciden);
-	mvv_write(0x25, decinum);
+	mvv_write(dev, 0x24, 0x80 | deciden);
+	mvv_write(dev, 0x25, decinum);
 }
 
-static void pms_resolution(short width, short height)
+static void pms_resolution(struct pms *dev, short width, short height)
 {
 	int fg_height;
 
-	fg_height=height;
-	if(fg_height>280)
-		fg_height=280;
+	fg_height = height;
+	if (fg_height > 280)
+		fg_height = 280;
 
-	mvv_write(0x18, fg_height);
-	mvv_write(0x19, fg_height>>8);
+	mvv_write(dev, 0x18, fg_height);
+	mvv_write(dev, 0x19, fg_height >> 8);
 
-	if(standard==1)
-	{
-		mvv_write(0x1A, 0xFC);
-		mvv_write(0x1B, 0x00);
-		if(height>fg_height)
-			pms_vertdeci(240,240);
+	if (dev->std & V4L2_STD_525_60) {
+		mvv_write(dev, 0x1a, 0xfc);
+		mvv_write(dev, 0x1b, 0x00);
+		if (height > fg_height)
+			pms_vertdeci(dev, 240, 240);
 		else
-			pms_vertdeci(fg_height,240);
-	}
-	else
-	{
-		mvv_write(0x1A, 0x1A);
-		mvv_write(0x1B, 0x01);
-		if(fg_height>256)
-			pms_vertdeci(270,270);
+			pms_vertdeci(dev, fg_height, 240);
+	} else {
+		mvv_write(dev, 0x1a, 0x1a);
+		mvv_write(dev, 0x1b, 0x01);
+		if (fg_height > 256)
+			pms_vertdeci(dev, 270, 270);
 		else
-			pms_vertdeci(fg_height, 270);
+			pms_vertdeci(dev, fg_height, 270);
 	}
-	mvv_write(0x12,0);
-	mvv_write(0x13, MVVMEMORYWIDTH);
-	mvv_write(0x42, 0x00);
-	mvv_write(0x43, 0x00);
-	mvv_write(0x44, MVVMEMORYWIDTH);
+	mvv_write(dev, 0x12, 0);
+	mvv_write(dev, 0x13, MVVMEMORYWIDTH);
+	mvv_write(dev, 0x42, 0x00);
+	mvv_write(dev, 0x43, 0x00);
+	mvv_write(dev, 0x44, MVVMEMORYWIDTH);
 
-	mvv_write(0x22, width+8);
-	mvv_write(0x23, (width+8)>> 8);
+	mvv_write(dev, 0x22, width + 8);
+	mvv_write(dev, 0x23, (width + 8) >> 8);
 
-	if(standard==1)
-		pms_horzdeci(width,640);
+	if (dev->std & V4L2_STD_525_60)
+		pms_horzdeci(dev, width, 640);
 	else
-		pms_horzdeci(width+8, 768);
+		pms_horzdeci(dev, width + 8, 768);
 
-	mvv_write(0x30, mvv_read(0x30)&0xFE);
-	mvv_write(0x08, mvv_read(0x08)|0x01);
-	mvv_write(0x01, mvv_read(0x01)&0xFD);
-	mvv_write(0x32, 0x00);
-	mvv_write(0x33, MVVMEMORYWIDTH);
+	mvv_write(dev, 0x30, mvv_read(dev, 0x30) & 0xfe);
+	mvv_write(dev, 0x08, mvv_read(dev, 0x08) | 0x01);
+	mvv_write(dev, 0x01, mvv_read(dev, 0x01) & 0xfd);
+	mvv_write(dev, 0x32, 0x00);
+	mvv_write(dev, 0x33, MVVMEMORYWIDTH);
 }
 
 
@@ -621,52 +616,49 @@
  *	Set Input
  */
 
-static void pms_vcrinput(short input)
+static void pms_vcrinput(struct pms *dev, short input)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0x8A,0x0D,0x7F,(input&1)<<7);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42,0x0D,0x7F,(input&1)<<7);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0x8a, 0x0d, 0x7f, (input & 1) << 7);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x0d, 0x7f, (input & 1) << 7);
 }
 
 
-static int pms_capture(struct pms_device *dev, char __user *buf, int rgb555, int count)
+static int pms_capture(struct pms *dev, char __user *buf, int rgb555, int count)
 {
 	int y;
-	int dw = 2*dev->width;
-
-	char tmp[dw+32]; /* using a temp buffer is faster than direct  */
+	int dw = 2 * dev->width;
+	char tmp[dw + 32]; /* using a temp buffer is faster than direct  */
 	int cnt = 0;
-	int len=0;
+	int len = 0;
 	unsigned char r8 = 0x5;  /* value for reg8  */
 
 	if (rgb555)
 		r8 |= 0x20; /* else use untranslated rgb = 565 */
-	mvv_write(0x08,r8); /* capture rgb555/565, init DRAM, PC enable */
+	mvv_write(dev, 0x08, r8); /* capture rgb555/565, init DRAM, PC enable */
 
 /*	printf("%d %d %d %d %d %x %x\n",width,height,voff,nom,den,mvv_buf); */
 
-	for (y = 0; y < dev->height; y++ )
-	{
-		writeb(0, mem);  /* synchronisiert neue Zeile */
+	for (y = 0; y < dev->height; y++) {
+		writeb(0, dev->mem);  /* synchronisiert neue Zeile */
 
 		/*
 		 *	This is in truth a fifo, be very careful as if you
 		 *	forgot this odd things will occur 8)
 		 */
 
-		memcpy_fromio(tmp, mem, dw+32); /* discard 16 word   */
+		memcpy_fromio(tmp, dev->mem, dw + 32); /* discard 16 word   */
 		cnt -= dev->height;
-		while (cnt <= 0)
-		{
+		while (cnt <= 0) {
 			/*
 			 *	Don't copy too far
 			 */
-			int dt=dw;
-			if(dt+len>count)
-				dt=count-len;
+			int dt = dw;
+			if (dt + len > count)
+				dt = count - len;
 			cnt += dev->height;
-			if (copy_to_user(buf, tmp+32, dt))
+			if (copy_to_user(buf, tmp + 32, dt))
 				return len ? len : -EFAULT;
 			buf += dt;
 			len += dt;
@@ -680,221 +672,278 @@
  *	Video4linux interfacing
  */
 
-static long pms_do_ioctl(struct file *file, unsigned int cmd, void *arg)
+static int pms_querycap(struct file *file, void  *priv,
+					struct v4l2_capability *vcap)
 {
-	struct video_device *dev = video_devdata(file);
-	struct pms_device *pd=(struct pms_device *)dev;
+	struct pms *dev = video_drvdata(file);
 
-	switch(cmd)
-	{
-		case VIDIOCGCAP:
-		{
-			struct video_capability *b = arg;
-			strcpy(b->name, "Mediavision PMS");
-			b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES;
-			b->channels = 4;
-			b->audios = 0;
-			b->maxwidth = 640;
-			b->maxheight = 480;
-			b->minwidth = 16;
-			b->minheight = 16;
-			return 0;
-		}
-		case VIDIOCGCHAN:
-		{
-			struct video_channel *v = arg;
-			if(v->channel<0 || v->channel>3)
-				return -EINVAL;
-			v->flags=0;
-			v->tuners=1;
-			/* Good question.. its composite or SVHS so.. */
-			v->type = VIDEO_TYPE_CAMERA;
-			switch(v->channel)
-			{
-				case 0:
-					strcpy(v->name, "Composite");break;
-				case 1:
-					strcpy(v->name, "SVideo");break;
-				case 2:
-					strcpy(v->name, "Composite(VCR)");break;
-				case 3:
-					strcpy(v->name, "SVideo(VCR)");break;
-			}
-			return 0;
-		}
-		case VIDIOCSCHAN:
-		{
-			struct video_channel *v = arg;
-			if(v->channel<0 || v->channel>3)
-				return -EINVAL;
-			mutex_lock(&pd->lock);
-			pms_videosource(v->channel&1);
-			pms_vcrinput(v->channel>>1);
-			mutex_unlock(&pd->lock);
-			return 0;
-		}
-		case VIDIOCGTUNER:
-		{
-			struct video_tuner *v = arg;
-			if(v->tuner)
-				return -EINVAL;
-			strcpy(v->name, "Format");
-			v->rangelow=0;
-			v->rangehigh=0;
-			v->flags= VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM;
-			switch(standard)
-			{
-				case 0:
-					v->mode = VIDEO_MODE_AUTO;
-					break;
-				case 1:
-					v->mode = VIDEO_MODE_NTSC;
-					break;
-				case 2:
-					v->mode = VIDEO_MODE_PAL;
-					break;
-				case 3:
-					v->mode = VIDEO_MODE_SECAM;
-					break;
-			}
-			return 0;
-		}
-		case VIDIOCSTUNER:
-		{
-			struct video_tuner *v = arg;
-			if(v->tuner)
-				return -EINVAL;
-			mutex_lock(&pd->lock);
-			switch(v->mode)
-			{
-				case VIDEO_MODE_AUTO:
-					pms_framerate(25);
-					pms_secamcross(0);
-					pms_format(0);
-					break;
-				case VIDEO_MODE_NTSC:
-					pms_framerate(30);
-					pms_secamcross(0);
-					pms_format(1);
-					break;
-				case VIDEO_MODE_PAL:
-					pms_framerate(25);
-					pms_secamcross(0);
-					pms_format(2);
-					break;
-				case VIDEO_MODE_SECAM:
-					pms_framerate(25);
-					pms_secamcross(1);
-					pms_format(2);
-					break;
-				default:
-					mutex_unlock(&pd->lock);
-					return -EINVAL;
-			}
-			mutex_unlock(&pd->lock);
-			return 0;
-		}
-		case VIDIOCGPICT:
-		{
-			struct video_picture *p = arg;
-			*p = pd->picture;
-			return 0;
-		}
-		case VIDIOCSPICT:
-		{
-			struct video_picture *p = arg;
-			if(!((p->palette==VIDEO_PALETTE_RGB565 && p->depth==16)
-			    ||(p->palette==VIDEO_PALETTE_RGB555 && p->depth==15)))
-				return -EINVAL;
-			pd->picture= *p;
-
-			/*
-			 *	Now load the card.
-			 */
-
-			mutex_lock(&pd->lock);
-			pms_brightness(p->brightness>>8);
-			pms_hue(p->hue>>8);
-			pms_colour(p->colour>>8);
-			pms_contrast(p->contrast>>8);
-			mutex_unlock(&pd->lock);
-			return 0;
-		}
-		case VIDIOCSWIN:
-		{
-			struct video_window *vw = arg;
-			if(vw->flags)
-				return -EINVAL;
-			if(vw->clipcount)
-				return -EINVAL;
-			if(vw->height<16||vw->height>480)
-				return -EINVAL;
-			if(vw->width<16||vw->width>640)
-				return -EINVAL;
-			pd->width=vw->width;
-			pd->height=vw->height;
-			mutex_lock(&pd->lock);
-			pms_resolution(pd->width, pd->height);
-			mutex_unlock(&pd->lock);			/* Ok we figured out what to use from our wide choice */
-			return 0;
-		}
-		case VIDIOCGWIN:
-		{
-			struct video_window *vw = arg;
-			memset(vw,0,sizeof(*vw));
-			vw->width=pd->width;
-			vw->height=pd->height;
-			return 0;
-		}
-		case VIDIOCKEY:
-			return 0;
-		case VIDIOCCAPTURE:
-		case VIDIOCGFBUF:
-		case VIDIOCSFBUF:
-		case VIDIOCGFREQ:
-		case VIDIOCSFREQ:
-		case VIDIOCGAUDIO:
-		case VIDIOCSAUDIO:
-			return -EINVAL;
-		default:
-			return -ENOIOCTLCMD;
-	}
+	strlcpy(vcap->driver, dev->v4l2_dev.name, sizeof(vcap->driver));
+	strlcpy(vcap->card, "Mediavision PMS", sizeof(vcap->card));
+	strlcpy(vcap->bus_info, "ISA", sizeof(vcap->bus_info));
+	vcap->version = KERNEL_VERSION(0, 0, 3);
+	vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
 	return 0;
 }
 
-static long pms_ioctl(struct file *file,
-		     unsigned int cmd, unsigned long arg)
+static int pms_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
 {
-	return video_usercopy(file, cmd, arg, pms_do_ioctl);
+	static const char *inputs[4] = {
+		"Composite",
+		"S-Video",
+		"Composite (VCR)",
+		"S-Video (VCR)"
+	};
+
+	if (vin->index > 3)
+		return -EINVAL;
+	strlcpy(vin->name, inputs[vin->index], sizeof(vin->name));
+	vin->type = V4L2_INPUT_TYPE_CAMERA;
+	vin->audioset = 0;
+	vin->tuner = 0;
+	vin->std = V4L2_STD_ALL;
+	vin->status = 0;
+	return 0;
+}
+
+static int pms_g_input(struct file *file, void *fh, unsigned int *inp)
+{
+	struct pms *dev = video_drvdata(file);
+
+	*inp = dev->input;
+	return 0;
+}
+
+static int pms_s_input(struct file *file, void *fh, unsigned int inp)
+{
+	struct pms *dev = video_drvdata(file);
+
+	if (inp > 3)
+		return -EINVAL;
+
+	mutex_lock(&dev->lock);
+	dev->input = inp;
+	pms_videosource(dev, inp & 1);
+	pms_vcrinput(dev, inp >> 1);
+	mutex_unlock(&dev->lock);
+	return 0;
+}
+
+static int pms_g_std(struct file *file, void *fh, v4l2_std_id *std)
+{
+	struct pms *dev = video_drvdata(file);
+
+	*std = dev->std;
+	return 0;
+}
+
+static int pms_s_std(struct file *file, void *fh, v4l2_std_id *std)
+{
+	struct pms *dev = video_drvdata(file);
+	int ret = 0;
+
+	dev->std = *std;
+	mutex_lock(&dev->lock);
+	if (dev->std & V4L2_STD_NTSC) {
+		pms_framerate(dev, 30);
+		pms_secamcross(dev, 0);
+		pms_format(dev, 1);
+	} else if (dev->std & V4L2_STD_PAL) {
+		pms_framerate(dev, 25);
+		pms_secamcross(dev, 0);
+		pms_format(dev, 2);
+	} else if (dev->std & V4L2_STD_SECAM) {
+		pms_framerate(dev, 25);
+		pms_secamcross(dev, 1);
+		pms_format(dev, 2);
+	} else {
+		ret = -EINVAL;
+	}
+	/*
+	switch (v->mode) {
+	case VIDEO_MODE_AUTO:
+		pms_framerate(dev, 25);
+		pms_secamcross(dev, 0);
+		pms_format(dev, 0);
+		break;
+	}*/
+	mutex_unlock(&dev->lock);
+	return 0;
+}
+
+static int pms_queryctrl(struct file *file, void *priv,
+					struct v4l2_queryctrl *qc)
+{
+	switch (qc->id) {
+	case V4L2_CID_BRIGHTNESS:
+		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 139);
+	case V4L2_CID_CONTRAST:
+		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 70);
+	case V4L2_CID_SATURATION:
+		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 64);
+	case V4L2_CID_HUE:
+		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 0);
+	}
+	return -EINVAL;
+}
+
+static int pms_g_ctrl(struct file *file, void *priv,
+					struct v4l2_control *ctrl)
+{
+	struct pms *dev = video_drvdata(file);
+	int ret = 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		ctrl->value = dev->brightness;
+		break;
+	case V4L2_CID_CONTRAST:
+		ctrl->value = dev->contrast;
+		break;
+	case V4L2_CID_SATURATION:
+		ctrl->value = dev->saturation;
+		break;
+	case V4L2_CID_HUE:
+		ctrl->value = dev->hue;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int pms_s_ctrl(struct file *file, void *priv,
+					struct v4l2_control *ctrl)
+{
+	struct pms *dev = video_drvdata(file);
+	int ret = 0;
+
+	mutex_lock(&dev->lock);
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		dev->brightness = ctrl->value;
+		pms_brightness(dev, dev->brightness);
+		break;
+	case V4L2_CID_CONTRAST:
+		dev->contrast = ctrl->value;
+		pms_contrast(dev, dev->contrast);
+		break;
+	case V4L2_CID_SATURATION:
+		dev->saturation = ctrl->value;
+		pms_saturation(dev, dev->saturation);
+		break;
+	case V4L2_CID_HUE:
+		dev->hue = ctrl->value;
+		pms_hue(dev, dev->hue);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	mutex_unlock(&dev->lock);
+	return ret;
+}
+
+static int pms_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+	struct pms *dev = video_drvdata(file);
+	struct v4l2_pix_format *pix = &fmt->fmt.pix;
+
+	pix->width = dev->width;
+	pix->height = dev->height;
+	pix->pixelformat = dev->width == 15 ?
+			    V4L2_PIX_FMT_RGB555 : V4L2_PIX_FMT_RGB565;
+	pix->field = V4L2_FIELD_NONE;
+	pix->bytesperline = 2 * dev->width;
+	pix->sizeimage = 2 * dev->width * dev->height;
+	/* Just a guess */
+	pix->colorspace = V4L2_COLORSPACE_SRGB;
+	return 0;
+}
+
+static int pms_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+	struct v4l2_pix_format *pix = &fmt->fmt.pix;
+
+	if (pix->height < 16 || pix->height > 480)
+		return -EINVAL;
+	if (pix->width < 16 || pix->width > 640)
+		return -EINVAL;
+	if (pix->pixelformat != V4L2_PIX_FMT_RGB555 &&
+	    pix->pixelformat != V4L2_PIX_FMT_RGB565)
+		return -EINVAL;
+	pix->field = V4L2_FIELD_NONE;
+	pix->bytesperline = 2 * pix->width;
+	pix->sizeimage = 2 * pix->width * pix->height;
+	/* Just a guess */
+	pix->colorspace = V4L2_COLORSPACE_SRGB;
+	return 0;
+}
+
+static int pms_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+	struct pms *dev = video_drvdata(file);
+	struct v4l2_pix_format *pix = &fmt->fmt.pix;
+	int ret = pms_try_fmt_vid_cap(file, fh, fmt);
+
+	if (ret)
+		return ret;
+	mutex_lock(&dev->lock);
+	dev->width = pix->width;
+	dev->height = pix->height;
+	dev->depth = (pix->pixelformat == V4L2_PIX_FMT_RGB555) ? 15 : 16;
+	pms_resolution(dev, dev->width, dev->height);
+	/* Ok we figured out what to use from our wide choice */
+	mutex_unlock(&dev->lock);
+	return 0;
+}
+
+static int pms_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
+{
+	static struct v4l2_fmtdesc formats[] = {
+		{ 0, 0, 0,
+		  "RGB 5:5:5", V4L2_PIX_FMT_RGB555,
+		  { 0, 0, 0, 0 }
+		},
+		{ 0, 0, 0,
+		  "RGB 5:6:5", V4L2_PIX_FMT_RGB565,
+		  { 0, 0, 0, 0 }
+		},
+	};
+	enum v4l2_buf_type type = fmt->type;
+
+	if (fmt->index > 1)
+		return -EINVAL;
+
+	*fmt = formats[fmt->index];
+	fmt->type = type;
+	return 0;
 }
 
 static ssize_t pms_read(struct file *file, char __user *buf,
 		    size_t count, loff_t *ppos)
 {
-	struct video_device *v = video_devdata(file);
-	struct pms_device *pd=(struct pms_device *)v;
+	struct pms *dev = video_drvdata(file);
 	int len;
 
-	mutex_lock(&pd->lock);
-	len=pms_capture(pd, buf, (pd->picture.depth==16)?0:1,count);
-	mutex_unlock(&pd->lock);
+	mutex_lock(&dev->lock);
+	len = pms_capture(dev, buf, (dev->depth == 15), count);
+	mutex_unlock(&dev->lock);
 	return len;
 }
 
 static int pms_exclusive_open(struct file *file)
 {
-	struct video_device *v = video_devdata(file);
-	struct pms_device *pd = (struct pms_device *)v;
+	struct pms *dev = video_drvdata(file);
 
-	return test_and_set_bit(0, &pd->in_use) ? -EBUSY : 0;
+	return test_and_set_bit(0, &dev->in_use) ? -EBUSY : 0;
 }
 
 static int pms_exclusive_release(struct file *file)
 {
-	struct video_device *v = video_devdata(file);
-	struct pms_device *pd = (struct pms_device *)v;
+	struct pms *dev = video_drvdata(file);
 
-	clear_bit(0, &pd->in_use);
+	clear_bit(0, &dev->in_use);
 	return 0;
 }
 
@@ -902,78 +951,81 @@
 	.owner		= THIS_MODULE,
 	.open           = pms_exclusive_open,
 	.release        = pms_exclusive_release,
-	.ioctl          = pms_ioctl,
+	.ioctl		= video_ioctl2,
 	.read           = pms_read,
 };
 
-static struct video_device pms_template=
-{
-	.name		= "Mediavision PMS",
-	.fops           = &pms_fops,
-	.release 	= video_device_release_empty,
+static const struct v4l2_ioctl_ops pms_ioctl_ops = {
+	.vidioc_querycap    		    = pms_querycap,
+	.vidioc_g_input      		    = pms_g_input,
+	.vidioc_s_input      		    = pms_s_input,
+	.vidioc_enum_input   		    = pms_enum_input,
+	.vidioc_g_std 			    = pms_g_std,
+	.vidioc_s_std 			    = pms_s_std,
+	.vidioc_queryctrl 		    = pms_queryctrl,
+	.vidioc_g_ctrl  		    = pms_g_ctrl,
+	.vidioc_s_ctrl 			    = pms_s_ctrl,
+	.vidioc_enum_fmt_vid_cap 	    = pms_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap 		    = pms_g_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap  		    = pms_s_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap  	    = pms_try_fmt_vid_cap,
 };
 
-static struct pms_device pms_device;
-
-
 /*
  *	Probe for and initialise the Mediavision PMS
  */
 
-static int init_mediavision(void)
+static int init_mediavision(struct pms *dev)
 {
 	int id;
 	int idec, decst;
 	int i;
-
-	unsigned char i2c_defs[]={
-		0x4C,0x30,0x00,0xE8,
-		0xB6,0xE2,0x00,0x00,
-		0xFF,0xFF,0x00,0x00,
-		0x00,0x00,0x78,0x98,
-		0x00,0x00,0x00,0x00,
-		0x34,0x0A,0xF4,0xCE,
-		0xE4
+	static const unsigned char i2c_defs[] = {
+		0x4c, 0x30, 0x00, 0xe8,
+		0xb6, 0xe2, 0x00, 0x00,
+		0xff, 0xff, 0x00, 0x00,
+		0x00, 0x00, 0x78, 0x98,
+		0x00, 0x00, 0x00, 0x00,
+		0x34, 0x0a, 0xf4, 0xce,
+		0xe4
 	};
 
-	mem = ioremap(mem_base, 0x800);
-	if (!mem)
+	dev->mem = ioremap(mem_base, 0x800);
+	if (!dev->mem)
 		return -ENOMEM;
 
-	if (!request_region(0x9A01, 1, "Mediavision PMS config"))
-	{
-		printk(KERN_WARNING "mediavision: unable to detect: 0x9A01 in use.\n");
-		iounmap(mem);
+	if (!request_region(0x9a01, 1, "Mediavision PMS config")) {
+		printk(KERN_WARNING "mediavision: unable to detect: 0x9a01 in use.\n");
+		iounmap(dev->mem);
 		return -EBUSY;
 	}
-	if (!request_region(io_port, 3, "Mediavision PMS"))
-	{
-		printk(KERN_WARNING "mediavision: I/O port %d in use.\n", io_port);
-		release_region(0x9A01, 1);
-		iounmap(mem);
+	if (!request_region(dev->io, 3, "Mediavision PMS")) {
+		printk(KERN_WARNING "mediavision: I/O port %d in use.\n", dev->io);
+		release_region(0x9a01, 1);
+		iounmap(dev->mem);
 		return -EBUSY;
 	}
-	outb(0xB8, 0x9A01);		/* Unlock */
-	outb(io_port>>4, 0x9A01);	/* Set IO port */
+	outb(0xb8, 0x9a01);		/* Unlock */
+	outb(dev->io >> 4, 0x9a01);	/* Set IO port */
 
 
-	id=mvv_read(3);
-	decst=pms_i2c_stat(0x43);
+	id = mvv_read(dev, 3);
+	decst = pms_i2c_stat(dev, 0x43);
 
-	if(decst!=-1)
-		idec=2;
-	else if(pms_i2c_stat(0xb9)!=-1)
-		idec=3;
-	else if(pms_i2c_stat(0x8b)!=-1)
-		idec=1;
+	if (decst != -1)
+		idec = 2;
+	else if (pms_i2c_stat(dev, 0xb9) != -1)
+		idec = 3;
+	else if (pms_i2c_stat(dev, 0x8b) != -1)
+		idec = 1;
 	else
-		idec=0;
+		idec = 0;
 
 	printk(KERN_INFO "PMS type is %d\n", idec);
-	if(idec == 0) {
-		release_region(io_port, 3);
-		release_region(0x9A01, 1);
-		iounmap(mem);
+	if (idec == 0) {
+		release_region(dev->io, 3);
+		release_region(0x9a01, 1);
+		iounmap(dev->mem);
 		return -ENODEV;
 	}
 
@@ -981,51 +1033,50 @@
 	 *	Ok we have a PMS of some sort
 	 */
 
-	mvv_write(0x04, mem_base>>12);	/* Set the memory area */
+	mvv_write(dev, 0x04, mem_base >> 12);	/* Set the memory area */
 
 	/* Ok now load the defaults */
 
-	for(i=0;i<0x19;i++)
-	{
-		if(i2c_defs[i]==0xFF)
-			pms_i2c_andor(0x8A, i, 0x07,0x00);
+	for (i = 0; i < 0x19; i++) {
+		if (i2c_defs[i] == 0xff)
+			pms_i2c_andor(dev, 0x8a, i, 0x07, 0x00);
 		else
-			pms_i2c_write(0x8A, i, i2c_defs[i]);
+			pms_i2c_write(dev, 0x8a, i, i2c_defs[i]);
 	}
 
-	pms_i2c_write(0xB8,0x00,0x12);
-	pms_i2c_write(0xB8,0x04,0x00);
-	pms_i2c_write(0xB8,0x07,0x00);
-	pms_i2c_write(0xB8,0x08,0x00);
-	pms_i2c_write(0xB8,0x09,0xFF);
-	pms_i2c_write(0xB8,0x0A,0x00);
-	pms_i2c_write(0xB8,0x0B,0x10);
-	pms_i2c_write(0xB8,0x10,0x03);
+	pms_i2c_write(dev, 0xb8, 0x00, 0x12);
+	pms_i2c_write(dev, 0xb8, 0x04, 0x00);
+	pms_i2c_write(dev, 0xb8, 0x07, 0x00);
+	pms_i2c_write(dev, 0xb8, 0x08, 0x00);
+	pms_i2c_write(dev, 0xb8, 0x09, 0xff);
+	pms_i2c_write(dev, 0xb8, 0x0a, 0x00);
+	pms_i2c_write(dev, 0xb8, 0x0b, 0x10);
+	pms_i2c_write(dev, 0xb8, 0x10, 0x03);
 
-	mvv_write(0x01, 0x00);
-	mvv_write(0x05, 0xA0);
-	mvv_write(0x08, 0x25);
-	mvv_write(0x09, 0x00);
-	mvv_write(0x0A, 0x20|MVVMEMORYWIDTH);
+	mvv_write(dev, 0x01, 0x00);
+	mvv_write(dev, 0x05, 0xa0);
+	mvv_write(dev, 0x08, 0x25);
+	mvv_write(dev, 0x09, 0x00);
+	mvv_write(dev, 0x0a, 0x20 | MVVMEMORYWIDTH);
 
-	mvv_write(0x10, 0x02);
-	mvv_write(0x1E, 0x0C);
-	mvv_write(0x1F, 0x03);
-	mvv_write(0x26, 0x06);
+	mvv_write(dev, 0x10, 0x02);
+	mvv_write(dev, 0x1e, 0x0c);
+	mvv_write(dev, 0x1f, 0x03);
+	mvv_write(dev, 0x26, 0x06);
 
-	mvv_write(0x2B, 0x00);
-	mvv_write(0x2C, 0x20);
-	mvv_write(0x2D, 0x00);
-	mvv_write(0x2F, 0x70);
-	mvv_write(0x32, 0x00);
-	mvv_write(0x33, MVVMEMORYWIDTH);
-	mvv_write(0x34, 0x00);
-	mvv_write(0x35, 0x00);
-	mvv_write(0x3A, 0x80);
-	mvv_write(0x3B, 0x10);
-	mvv_write(0x20, 0x00);
-	mvv_write(0x21, 0x00);
-	mvv_write(0x30, 0x22);
+	mvv_write(dev, 0x2b, 0x00);
+	mvv_write(dev, 0x2c, 0x20);
+	mvv_write(dev, 0x2d, 0x00);
+	mvv_write(dev, 0x2f, 0x70);
+	mvv_write(dev, 0x32, 0x00);
+	mvv_write(dev, 0x33, MVVMEMORYWIDTH);
+	mvv_write(dev, 0x34, 0x00);
+	mvv_write(dev, 0x35, 0x00);
+	mvv_write(dev, 0x3a, 0x80);
+	mvv_write(dev, 0x3b, 0x10);
+	mvv_write(dev, 0x20, 0x00);
+	mvv_write(dev, 0x21, 0x00);
+	mvv_write(dev, 0x30, 0x22);
 	return 0;
 }
 
@@ -1038,53 +1089,77 @@
 module_param(enable, int, 0);
 #endif
 
-static int __init init_pms_cards(void)
+static int __init pms_init(void)
 {
-	printk(KERN_INFO "Mediavision Pro Movie Studio driver 0.02\n");
+	struct pms *dev = &pms_card;
+	struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
+	int res;
+
+	strlcpy(v4l2_dev->name, "pms", sizeof(v4l2_dev->name));
+
+	v4l2_info(v4l2_dev, "Mediavision Pro Movie Studio driver 0.03\n");
 
 #ifndef MODULE
 	if (!enable) {
-		printk(KERN_INFO "PMS: not enabled, use pms.enable=1 to "
-				 "probe\n");
+		v4l2_err(v4l2_dev,
+			"PMS: not enabled, use pms.enable=1 to probe\n");
 		return -ENODEV;
 	}
 #endif
 
-	data_port = io_port +1;
+	dev->decoder = PHILIPS2;
+	dev->io = io_port;
+	dev->data = io_port + 1;
 
-	if(init_mediavision())
-	{
-		printk(KERN_INFO "Board not found.\n");
+	if (init_mediavision(dev)) {
+		v4l2_err(v4l2_dev, "Board not found.\n");
 		return -ENODEV;
 	}
-	memcpy(&pms_device, &pms_template, sizeof(pms_template));
-	mutex_init(&pms_device.lock);
-	pms_device.height=240;
-	pms_device.width=320;
-	pms_swsense(75);
-	pms_resolution(320,240);
-	return video_register_device((struct video_device *)&pms_device, VFL_TYPE_GRABBER, video_nr);
+
+	res = v4l2_device_register(NULL, v4l2_dev);
+	if (res < 0) {
+		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+		return res;
+	}
+
+	strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+	dev->vdev.v4l2_dev = v4l2_dev;
+	dev->vdev.fops = &pms_fops;
+	dev->vdev.ioctl_ops = &pms_ioctl_ops;
+	dev->vdev.release = video_device_release_empty;
+	video_set_drvdata(&dev->vdev, dev);
+	mutex_init(&dev->lock);
+	dev->std = V4L2_STD_NTSC_M;
+	dev->height = 240;
+	dev->width = 320;
+	dev->depth = 15;
+	dev->brightness = 139;
+	dev->contrast = 70;
+	dev->hue = 0;
+	dev->saturation = 64;
+	pms_swsense(dev, 75);
+	pms_resolution(dev, 320, 240);
+	pms_videosource(dev, 0);
+	pms_vcrinput(dev, 0);
+	if (video_register_device(&dev->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
+		v4l2_device_unregister(&dev->v4l2_dev);
+		release_region(dev->io, 3);
+		release_region(0x9a01, 1);
+		iounmap(dev->mem);
+		return -EINVAL;
+	}
+	return 0;
 }
 
-module_param(io_port, int, 0);
-module_param(mem_base, int, 0);
-module_param(video_nr, int, 0);
-MODULE_LICENSE("GPL");
-
-
-static void __exit shutdown_mediavision(void)
+static void __exit pms_exit(void)
 {
-	release_region(io_port,3);
-	release_region(0x9A01, 1);
+	struct pms *dev = &pms_card;
+
+	video_unregister_device(&dev->vdev);
+	release_region(dev->io, 3);
+	release_region(0x9a01, 1);
+	iounmap(dev->mem);
 }
 
-static void __exit cleanup_pms_module(void)
-{
-	shutdown_mediavision();
-	video_unregister_device((struct video_device *)&pms_device);
-	iounmap(mem);
-}
-
-module_init(init_pms_cards);
-module_exit(cleanup_pms_module);
-
+module_init(pms_init);
+module_exit(pms_exit);
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
index fbe3856..ae97766 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
@@ -142,6 +142,9 @@
 {
 	int bcnt = 0;
 	int ccnt;
+	ccnt = scnprintf(buf, acnt, "Driver hardware description: %s\n",
+			 pvr2_hdw_get_desc(hdw));
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
 	ccnt = scnprintf(buf,acnt,"Driver state info:\n");
 	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
 	ccnt = pvr2_hdw_state_report(hdw,buf,acnt);
@@ -249,11 +252,15 @@
 			scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
 			if (scnt && wptr) {
 				count -= scnt; buf += scnt;
-				if (debugifc_match_keyword(wptr,wlen,"prom")) {
-					pvr2_hdw_cpufw_set_enabled(hdw,!0,!0);
-				} else if (debugifc_match_keyword(wptr,wlen,
-								  "ram")) {
-					pvr2_hdw_cpufw_set_enabled(hdw,0,!0);
+				if (debugifc_match_keyword(wptr, wlen,
+							   "prom")) {
+					pvr2_hdw_cpufw_set_enabled(hdw, 2, !0);
+				} else if (debugifc_match_keyword(wptr, wlen,
+								  "ram8k")) {
+					pvr2_hdw_cpufw_set_enabled(hdw, 0, !0);
+				} else if (debugifc_match_keyword(wptr, wlen,
+								  "ram16k")) {
+					pvr2_hdw_cpufw_set_enabled(hdw, 1, !0);
 				} else {
 					return -EINVAL;
 				}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index e4d7c13..6bc16c1 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -58,7 +58,7 @@
 };
 
 static const struct pvr2_device_desc pvr2_device_29xxx = {
-		.description = "WinTV PVR USB2 Model Category 29xxx",
+		.description = "WinTV PVR USB2 Model 29xxx",
 		.shortname = "29xxx",
 		.client_table.lst = pvr2_cli_29xxx,
 		.client_table.cnt = ARRAY_SIZE(pvr2_cli_29xxx),
@@ -91,7 +91,7 @@
 };
 
 static const struct pvr2_device_desc pvr2_device_24xxx = {
-		.description = "WinTV PVR USB2 Model Category 24xxx",
+		.description = "WinTV PVR USB2 Model 24xxx",
 		.shortname = "24xxx",
 		.client_table.lst = pvr2_cli_24xxx,
 		.client_table.cnt = ARRAY_SIZE(pvr2_cli_24xxx),
@@ -340,7 +340,7 @@
 };
 
 static const struct pvr2_device_desc pvr2_device_73xxx = {
-		.description = "WinTV HVR-1900 Model Category 73xxx",
+		.description = "WinTV HVR-1900 Model 73xxx",
 		.shortname = "73xxx",
 		.client_table.lst = pvr2_cli_73xxx,
 		.client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
@@ -351,6 +351,7 @@
 		.flag_has_analogtuner = !0,
 		.flag_has_composite = !0,
 		.flag_has_svideo = !0,
+		.flag_fx2_16kb = !0,
 		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
 		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
 		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
@@ -445,7 +446,7 @@
 };
 
 static const struct pvr2_device_desc pvr2_device_750xx = {
-		.description = "WinTV HVR-1950 Model Category 750xx",
+		.description = "WinTV HVR-1950 Model 750xx",
 		.shortname = "750xx",
 		.client_table.lst = pvr2_cli_73xxx,
 		.client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
@@ -456,6 +457,7 @@
 		.flag_has_analogtuner = !0,
 		.flag_has_composite = !0,
 		.flag_has_svideo = !0,
+		.flag_fx2_16kb = !0,
 		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
 		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
 		.default_std_mask = V4L2_STD_NTSC_M,
@@ -467,7 +469,7 @@
 };
 
 static const struct pvr2_device_desc pvr2_device_751xx = {
-		.description = "WinTV HVR-1950 Model Category 751xx",
+		.description = "WinTV HVR-1950 Model 751xx",
 		.shortname = "751xx",
 		.client_table.lst = pvr2_cli_73xxx,
 		.client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
@@ -478,6 +480,7 @@
 		.flag_has_analogtuner = !0,
 		.flag_has_composite = !0,
 		.flag_has_svideo = !0,
+		.flag_fx2_16kb = !0,
 		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
 		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
 		.default_std_mask = V4L2_STD_NTSC_M,
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
index ea04ecf..e5b9594 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
@@ -176,6 +176,7 @@
 	unsigned int flag_has_analogtuner:1;   /* Has analog tuner */
 	unsigned int flag_has_composite:1;     /* Has composite input */
 	unsigned int flag_has_svideo:1;        /* Has s-video input */
+	unsigned int flag_fx2_16kb:1;          /* 16KB FX2 firmware OK here */
 };
 
 extern struct usb_device_id pvr2_device_table[];
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
index 54ac534..e046fda 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
@@ -294,7 +294,10 @@
 			pvr2_trace(
 				PVR2_TRACE_ERROR_LEGS,
 				"Giving up on command."
-				"  This is normally recovered by the driver.");
+				"  This is normally recovered via a firmware"
+				" reload and re-initialization; concern"
+				" is only warranted if this happens repeatedly"
+				" and rapidly.");
 			break;
 		}
 		wrData[0] = 0x7;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index 5b152ff..de5485f 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -270,6 +270,7 @@
 
 	int force_dirty;        /* consider all controls dirty if true */
 	int flag_ok;            /* device in known good state */
+	int flag_modulefail;    /* true if at least one module failed to load */
 	int flag_disconnected;  /* flag_ok == 0 due to disconnect */
 	int flag_init_ok;       /* true if structure is fully initialized */
 	int fw1_state;          /* current situation with fw1 */
@@ -332,7 +333,7 @@
 
 	/* Bit mask of PVR2_CVAL_INPUT choices which are valid for the hardware */
 	unsigned int input_avail_mask;
-	/* Bit mask of PVR2_CVAL_INPUT choices which are currenly allowed */
+	/* Bit mask of PVR2_CVAL_INPUT choices which are currently allowed */
 	unsigned int input_allowed_mask;
 
 	/* Location of eeprom or a negative number if none */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 13639b3..1bbdab0 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -1447,6 +1447,7 @@
 	const struct firmware *fw_entry = NULL;
 	void  *fw_ptr;
 	unsigned int pipe;
+	unsigned int fwsize;
 	int ret;
 	u16 address;
 
@@ -1473,9 +1474,21 @@
 	usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f));
 
 	pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
+	fwsize = fw_entry->size;
 
-	if (fw_entry->size != 0x2000){
-		pvr2_trace(PVR2_TRACE_ERROR_LEGS,"wrong fx2 firmware size");
+	if ((fwsize != 0x2000) &&
+	    (!(hdw->hdw_desc->flag_fx2_16kb && (fwsize == 0x4000)))) {
+		if (hdw->hdw_desc->flag_fx2_16kb) {
+			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+				   "Wrong fx2 firmware size"
+				   " (expected 8192 or 16384, got %u)",
+				   fwsize);
+		} else {
+			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+				   "Wrong fx2 firmware size"
+				   " (expected 8192, got %u)",
+				   fwsize);
+		}
 		release_firmware(fw_entry);
 		return -ENOMEM;
 	}
@@ -1493,7 +1506,7 @@
 	   chunk. */
 
 	ret = 0;
-	for(address = 0; address < fw_entry->size; address += 0x800) {
+	for (address = 0; address < fwsize; address += 0x800) {
 		memcpy(fw_ptr, fw_entry->data + address, 0x800);
 		ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address,
 				       0, fw_ptr, 0x800, HZ);
@@ -1509,8 +1522,8 @@
 
 	trace_firmware("Upload done (%d bytes sent)",ret);
 
-	/* We should have written 8192 bytes */
-	if (ret == 8192) {
+	/* We should have written fwsize bytes */
+	if (ret == fwsize) {
 		hdw->fw1_state = FW1_STATE_RELOAD;
 		return 0;
 	}
@@ -2030,7 +2043,8 @@
 	fname = (mid < ARRAY_SIZE(module_names)) ? module_names[mid] : NULL;
 	if (!fname) {
 		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
-			   "Module ID %u for device %s has no name",
+			   "Module ID %u for device %s has no name?"
+			   "  The driver might have a configuration problem.",
 			   mid,
 			   hdw->hdw_desc->description);
 		return -EINVAL;
@@ -2058,7 +2072,8 @@
 	if (!i2ccnt) {
 		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 			   "Module ID %u (%s) for device %s:"
-			   " No i2c addresses",
+			   " No i2c addresses."
+			   "  The driver might have a configuration problem.",
 			   mid, fname, hdw->hdw_desc->description);
 		return -EINVAL;
 	}
@@ -2090,7 +2105,9 @@
 
 	if (!sd) {
 		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
-			   "Module ID %u (%s) for device %s failed to load",
+			   "Module ID %u (%s) for device %s failed to load."
+			   "  Possible missing sub-device kernel module or"
+			   " initialization failure within module.",
 			   mid, fname, hdw->hdw_desc->description);
 		return -EIO;
 	}
@@ -2132,7 +2149,10 @@
 	for (idx = 0; idx < ct->cnt; idx++) {
 		if (pvr2_hdw_load_subdev(hdw, &ct->lst[idx]) < 0) okFl = 0;
 	}
-	if (!okFl) pvr2_hdw_render_useless(hdw);
+	if (!okFl) {
+		hdw->flag_modulefail = !0;
+		pvr2_hdw_render_useless(hdw);
+	}
 }
 
 
@@ -2334,6 +2354,20 @@
 				break;
 			}
 		}
+		if (hdw->flag_modulefail) {
+			pvr2_trace(
+				PVR2_TRACE_ERROR_LEGS,
+				"***WARNING*** pvrusb2 driver initialization"
+				" failed due to the failure of one or more"
+				" sub-device kernel modules.");
+			pvr2_trace(
+				PVR2_TRACE_ERROR_LEGS,
+				"You need to resolve the failing condition"
+				" before this driver can function.  There"
+				" should be some earlier messages giving more"
+				" information about the problem.");
+			break;
+		}
 		if (procreload) {
 			pvr2_trace(
 				PVR2_TRACE_ERROR_LEGS,
@@ -2419,6 +2453,8 @@
 	hdw = kzalloc(sizeof(*hdw),GFP_KERNEL);
 	pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"",
 		   hdw,hdw_desc->description);
+	pvr2_trace(PVR2_TRACE_INFO, "Hardware description: %s",
+		hdw_desc->description);
 	if (!hdw) goto fail;
 
 	init_timer(&hdw->quiescent_timer);
@@ -3480,7 +3516,7 @@
 
 
 void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw,
-				int prom_flag,
+				int mode,
 				int enable_flag)
 {
 	int ret;
@@ -3503,11 +3539,12 @@
 			break;
 		}
 
-		hdw->fw_cpu_flag = (prom_flag == 0);
+		hdw->fw_cpu_flag = (mode != 2);
 		if (hdw->fw_cpu_flag) {
+			hdw->fw_size = (mode == 1) ? 0x4000 : 0x2000;
 			pvr2_trace(PVR2_TRACE_FIRMWARE,
-				   "Preparing to suck out CPU firmware");
-			hdw->fw_size = 0x2000;
+				   "Preparing to suck out CPU firmware"
+				   " (size=%u)", hdw->fw_size);
 			hdw->fw_buffer = kzalloc(hdw->fw_size,GFP_KERNEL);
 			if (!hdw->fw_buffer) {
 				hdw->fw_size = 0;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index 7b69405..56e70ea 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -219,7 +219,7 @@
    this may prevent the device from running (and leaving this mode may
    imply a device reset). */
 void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *,
-				int prom_flag,
+				int mode, /* 0=8KB FX2, 1=16KB FX2, 2=PROM */
 				int enable_flag);
 
 /* Return true if we're in a mode for retrieval CPU firmware */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index a334b1a..7cbe18c 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -50,6 +50,7 @@
 
 /* Mapping of IR schemes to known I2C addresses - if any */
 static const unsigned char ir_video_addresses[] = {
+	[PVR2_IR_SCHEME_ZILOG] = 0x71,
 	[PVR2_IR_SCHEME_29XXX] = 0x18,
 	[PVR2_IR_SCHEME_24XXX] = 0x18,
 };
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 2d8825e..6aa48e0 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -913,6 +913,15 @@
 }
 
 
+static void pvr2_v4l2_dev_disassociate_parent(struct pvr2_v4l2_dev *dip)
+{
+	if (!dip) return;
+	if (!dip->devbase.parent) return;
+	dip->devbase.parent = NULL;
+	device_move(&dip->devbase.dev, NULL, DPM_ORDER_NONE);
+}
+
+
 static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
 {
 	if (vp->dev_video) {
@@ -943,6 +952,8 @@
 	struct pvr2_v4l2 *vp;
 	vp = container_of(chp,struct pvr2_v4l2,channel);
 	if (!vp->channel.mc_head->disconnect_flag) return;
+	pvr2_v4l2_dev_disassociate_parent(vp->dev_video);
+	pvr2_v4l2_dev_disassociate_parent(vp->dev_radio);
 	if (vp->vfirst) return;
 	pvr2_v4l2_destroy_no_lock(vp);
 }
@@ -1250,12 +1261,13 @@
 			       struct pvr2_v4l2 *vp,
 			       int v4l_type)
 {
+	struct usb_device *usbdev;
 	int mindevnum;
 	int unit_number;
 	int *nr_ptr = NULL;
 	dip->v4lp = vp;
 
-
+	usbdev = pvr2_hdw_get_dev(vp->channel.mc_head->hdw);
 	dip->v4l_type = v4l_type;
 	switch (v4l_type) {
 	case VFL_TYPE_GRABBER:
@@ -1296,6 +1308,7 @@
 	if (nr_ptr && (unit_number >= 0) && (unit_number < PVR_NUM)) {
 		mindevnum = nr_ptr[unit_number];
 	}
+	dip->devbase.parent = &usbdev->dev;
 	if ((video_register_device(&dip->devbase,
 				   dip->v4l_type, mindevnum) < 0) &&
 	    (video_register_device(&dip->devbase,
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index f976df4..89b620f 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -68,6 +68,7 @@
 #endif
 #include <linux/vmalloc.h>
 #include <asm/io.h>
+#include <linux/kernel.h>		/* simple_strtol() */
 
 #include "pwc.h"
 #include "pwc-kiara.h"
@@ -1916,19 +1917,6 @@
 	unlock_kernel();
 }
 
-/* *grunt* We have to do atoi ourselves :-( */
-static int pwc_atoi(const char *s)
-{
-	int k = 0;
-
-	k = 0;
-	while (*s != '\0' && *s >= '0' && *s <= '9') {
-		k = 10 * k + (*s - '0');
-		s++;
-	}
-	return k;
-}
-
 
 /*
  * Initialization code & module stuff
@@ -2078,13 +2066,16 @@
 				}
 				else {
 					/* No type or serial number specified, just a number. */
-					device_hint[i].device_node = pwc_atoi(s);
+					device_hint[i].device_node =
+						simple_strtol(s, NULL, 10);
 				}
 			}
 			else {
 				/* There's a colon, so we have at least a type and a device node */
-				device_hint[i].type = pwc_atoi(s);
-				device_hint[i].device_node = pwc_atoi(colon + 1);
+				device_hint[i].type =
+					simple_strtol(s, NULL, 10);
+				device_hint[i].device_node =
+					simple_strtol(colon + 1, NULL, 10);
 				if (*dot != '\0') {
 					/* There's a serial number as well */
 					int k;
diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/video/rj54n1cb0c.c
new file mode 100644
index 0000000..373f2a3
--- /dev/null
+++ b/drivers/media/video/rj54n1cb0c.c
@@ -0,0 +1,1219 @@
+/*
+ * Driver for RJ54N1CB0C CMOS Image Sensor from Micron
+ *
+ * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/soc_camera.h>
+
+#define RJ54N1_DEV_CODE			0x0400
+#define RJ54N1_DEV_CODE2		0x0401
+#define RJ54N1_OUT_SEL			0x0403
+#define RJ54N1_XY_OUTPUT_SIZE_S_H	0x0404
+#define RJ54N1_X_OUTPUT_SIZE_S_L	0x0405
+#define RJ54N1_Y_OUTPUT_SIZE_S_L	0x0406
+#define RJ54N1_XY_OUTPUT_SIZE_P_H	0x0407
+#define RJ54N1_X_OUTPUT_SIZE_P_L	0x0408
+#define RJ54N1_Y_OUTPUT_SIZE_P_L	0x0409
+#define RJ54N1_LINE_LENGTH_PCK_S_H	0x040a
+#define RJ54N1_LINE_LENGTH_PCK_S_L	0x040b
+#define RJ54N1_LINE_LENGTH_PCK_P_H	0x040c
+#define RJ54N1_LINE_LENGTH_PCK_P_L	0x040d
+#define RJ54N1_RESIZE_N			0x040e
+#define RJ54N1_RESIZE_N_STEP		0x040f
+#define RJ54N1_RESIZE_STEP		0x0410
+#define RJ54N1_RESIZE_HOLD_H		0x0411
+#define RJ54N1_RESIZE_HOLD_L		0x0412
+#define RJ54N1_H_OBEN_OFS		0x0413
+#define RJ54N1_V_OBEN_OFS		0x0414
+#define RJ54N1_RESIZE_CONTROL		0x0415
+#define RJ54N1_INC_USE_SEL_H		0x0425
+#define RJ54N1_INC_USE_SEL_L		0x0426
+#define RJ54N1_MIRROR_STILL_MODE	0x0427
+#define RJ54N1_INIT_START		0x0428
+#define RJ54N1_SCALE_1_2_LEV		0x0429
+#define RJ54N1_SCALE_4_LEV		0x042a
+#define RJ54N1_Y_GAIN			0x04d8
+#define RJ54N1_APT_GAIN_UP		0x04fa
+#define RJ54N1_RA_SEL_UL		0x0530
+#define RJ54N1_BYTE_SWAP		0x0531
+#define RJ54N1_OUT_SIGPO		0x053b
+#define RJ54N1_FRAME_LENGTH_S_H		0x0595
+#define RJ54N1_FRAME_LENGTH_S_L		0x0596
+#define RJ54N1_FRAME_LENGTH_P_H		0x0597
+#define RJ54N1_FRAME_LENGTH_P_L		0x0598
+#define RJ54N1_IOC			0x05ef
+#define RJ54N1_TG_BYPASS		0x0700
+#define RJ54N1_PLL_L			0x0701
+#define RJ54N1_PLL_N			0x0702
+#define RJ54N1_PLL_EN			0x0704
+#define RJ54N1_RATIO_TG			0x0706
+#define RJ54N1_RATIO_T			0x0707
+#define RJ54N1_RATIO_R			0x0708
+#define RJ54N1_RAMP_TGCLK_EN		0x0709
+#define RJ54N1_OCLK_DSP			0x0710
+#define RJ54N1_RATIO_OP			0x0711
+#define RJ54N1_RATIO_O			0x0712
+#define RJ54N1_OCLK_SEL_EN		0x0713
+#define RJ54N1_CLK_RST			0x0717
+#define RJ54N1_RESET_STANDBY		0x0718
+
+#define E_EXCLK				(1 << 7)
+#define SOFT_STDBY			(1 << 4)
+#define SEN_RSTX			(1 << 2)
+#define TG_RSTX				(1 << 1)
+#define DSP_RSTX			(1 << 0)
+
+#define RESIZE_HOLD_SEL			(1 << 2)
+#define RESIZE_GO			(1 << 1)
+
+#define RJ54N1_COLUMN_SKIP		0
+#define RJ54N1_ROW_SKIP			0
+#define RJ54N1_MAX_WIDTH		1600
+#define RJ54N1_MAX_HEIGHT		1200
+
+/* I2C addresses: 0x50, 0x51, 0x60, 0x61 */
+
+static const struct soc_camera_data_format rj54n1_colour_formats[] = {
+	{
+		.name		= "YUYV",
+		.depth		= 16,
+		.fourcc		= V4L2_PIX_FMT_YUYV,
+		.colorspace	= V4L2_COLORSPACE_JPEG,
+	}, {
+		.name		= "RGB565",
+		.depth		= 16,
+		.fourcc		= V4L2_PIX_FMT_RGB565,
+		.colorspace	= V4L2_COLORSPACE_SRGB,
+	}
+};
+
+struct rj54n1_clock_div {
+	u8 ratio_tg;
+	u8 ratio_t;
+	u8 ratio_r;
+	u8 ratio_op;
+	u8 ratio_o;
+};
+
+struct rj54n1 {
+	struct v4l2_subdev subdev;
+	struct v4l2_rect rect;	/* Sensor window */
+	unsigned short width;	/* Output window */
+	unsigned short height;
+	unsigned short resize;	/* Sensor * 1024 / resize = Output */
+	struct rj54n1_clock_div clk_div;
+	u32 fourcc;
+	unsigned short scale;
+	u8 bank;
+};
+
+struct rj54n1_reg_val {
+	u16 reg;
+	u8 val;
+};
+
+const static struct rj54n1_reg_val bank_4[] = {
+	{0x417, 0},
+	{0x42c, 0},
+	{0x42d, 0xf0},
+	{0x42e, 0},
+	{0x42f, 0x50},
+	{0x430, 0xf5},
+	{0x431, 0x16},
+	{0x432, 0x20},
+	{0x433, 0},
+	{0x434, 0xc8},
+	{0x43c, 8},
+	{0x43e, 0x90},
+	{0x445, 0x83},
+	{0x4ba, 0x58},
+	{0x4bb, 4},
+	{0x4bc, 0x20},
+	{0x4db, 4},
+	{0x4fe, 2},
+};
+
+const static struct rj54n1_reg_val bank_5[] = {
+	{0x514, 0},
+	{0x516, 0},
+	{0x518, 0},
+	{0x51a, 0},
+	{0x51d, 0xff},
+	{0x56f, 0x28},
+	{0x575, 0x40},
+	{0x5bc, 0x48},
+	{0x5c1, 6},
+	{0x5e5, 0x11},
+	{0x5e6, 0x43},
+	{0x5e7, 0x33},
+	{0x5e8, 0x21},
+	{0x5e9, 0x30},
+	{0x5ea, 0x0},
+	{0x5eb, 0xa5},
+	{0x5ec, 0xff},
+	{0x5fe, 2},
+};
+
+const static struct rj54n1_reg_val bank_7[] = {
+	{0x70a, 0},
+	{0x714, 0xff},
+	{0x715, 0xff},
+	{0x716, 0x1f},
+	{0x7FE, 0x02},
+};
+
+const static struct rj54n1_reg_val bank_8[] = {
+	{0x800, 0x00},
+	{0x801, 0x01},
+	{0x802, 0x61},
+	{0x805, 0x00},
+	{0x806, 0x00},
+	{0x807, 0x00},
+	{0x808, 0x00},
+	{0x809, 0x01},
+	{0x80A, 0x61},
+	{0x80B, 0x00},
+	{0x80C, 0x01},
+	{0x80D, 0x00},
+	{0x80E, 0x00},
+	{0x80F, 0x00},
+	{0x810, 0x00},
+	{0x811, 0x01},
+	{0x812, 0x61},
+	{0x813, 0x00},
+	{0x814, 0x11},
+	{0x815, 0x00},
+	{0x816, 0x41},
+	{0x817, 0x00},
+	{0x818, 0x51},
+	{0x819, 0x01},
+	{0x81A, 0x1F},
+	{0x81B, 0x00},
+	{0x81C, 0x01},
+	{0x81D, 0x00},
+	{0x81E, 0x11},
+	{0x81F, 0x00},
+	{0x820, 0x41},
+	{0x821, 0x00},
+	{0x822, 0x51},
+	{0x823, 0x00},
+	{0x824, 0x00},
+	{0x825, 0x00},
+	{0x826, 0x47},
+	{0x827, 0x01},
+	{0x828, 0x4F},
+	{0x829, 0x00},
+	{0x82A, 0x00},
+	{0x82B, 0x00},
+	{0x82C, 0x30},
+	{0x82D, 0x00},
+	{0x82E, 0x40},
+	{0x82F, 0x00},
+	{0x830, 0xB3},
+	{0x831, 0x00},
+	{0x832, 0xE3},
+	{0x833, 0x00},
+	{0x834, 0x00},
+	{0x835, 0x00},
+	{0x836, 0x00},
+	{0x837, 0x00},
+	{0x838, 0x00},
+	{0x839, 0x01},
+	{0x83A, 0x61},
+	{0x83B, 0x00},
+	{0x83C, 0x01},
+	{0x83D, 0x00},
+	{0x83E, 0x00},
+	{0x83F, 0x00},
+	{0x840, 0x00},
+	{0x841, 0x01},
+	{0x842, 0x61},
+	{0x843, 0x00},
+	{0x844, 0x1D},
+	{0x845, 0x00},
+	{0x846, 0x00},
+	{0x847, 0x00},
+	{0x848, 0x00},
+	{0x849, 0x01},
+	{0x84A, 0x1F},
+	{0x84B, 0x00},
+	{0x84C, 0x05},
+	{0x84D, 0x00},
+	{0x84E, 0x19},
+	{0x84F, 0x01},
+	{0x850, 0x21},
+	{0x851, 0x01},
+	{0x852, 0x5D},
+	{0x853, 0x00},
+	{0x854, 0x00},
+	{0x855, 0x00},
+	{0x856, 0x19},
+	{0x857, 0x01},
+	{0x858, 0x21},
+	{0x859, 0x00},
+	{0x85A, 0x00},
+	{0x85B, 0x00},
+	{0x85C, 0x00},
+	{0x85D, 0x00},
+	{0x85E, 0x00},
+	{0x85F, 0x00},
+	{0x860, 0xB3},
+	{0x861, 0x00},
+	{0x862, 0xE3},
+	{0x863, 0x00},
+	{0x864, 0x00},
+	{0x865, 0x00},
+	{0x866, 0x00},
+	{0x867, 0x00},
+	{0x868, 0x00},
+	{0x869, 0xE2},
+	{0x86A, 0x00},
+	{0x86B, 0x01},
+	{0x86C, 0x06},
+	{0x86D, 0x00},
+	{0x86E, 0x00},
+	{0x86F, 0x00},
+	{0x870, 0x60},
+	{0x871, 0x8C},
+	{0x872, 0x10},
+	{0x873, 0x00},
+	{0x874, 0xE0},
+	{0x875, 0x00},
+	{0x876, 0x27},
+	{0x877, 0x01},
+	{0x878, 0x00},
+	{0x879, 0x00},
+	{0x87A, 0x00},
+	{0x87B, 0x03},
+	{0x87C, 0x00},
+	{0x87D, 0x00},
+	{0x87E, 0x00},
+	{0x87F, 0x00},
+	{0x880, 0x00},
+	{0x881, 0x00},
+	{0x882, 0x00},
+	{0x883, 0x00},
+	{0x884, 0x00},
+	{0x885, 0x00},
+	{0x886, 0xF8},
+	{0x887, 0x00},
+	{0x888, 0x03},
+	{0x889, 0x00},
+	{0x88A, 0x64},
+	{0x88B, 0x00},
+	{0x88C, 0x03},
+	{0x88D, 0x00},
+	{0x88E, 0xB1},
+	{0x88F, 0x00},
+	{0x890, 0x03},
+	{0x891, 0x01},
+	{0x892, 0x1D},
+	{0x893, 0x00},
+	{0x894, 0x03},
+	{0x895, 0x01},
+	{0x896, 0x4B},
+	{0x897, 0x00},
+	{0x898, 0xE5},
+	{0x899, 0x00},
+	{0x89A, 0x01},
+	{0x89B, 0x00},
+	{0x89C, 0x01},
+	{0x89D, 0x04},
+	{0x89E, 0xC8},
+	{0x89F, 0x00},
+	{0x8A0, 0x01},
+	{0x8A1, 0x01},
+	{0x8A2, 0x61},
+	{0x8A3, 0x00},
+	{0x8A4, 0x01},
+	{0x8A5, 0x00},
+	{0x8A6, 0x00},
+	{0x8A7, 0x00},
+	{0x8A8, 0x00},
+	{0x8A9, 0x00},
+	{0x8AA, 0x7F},
+	{0x8AB, 0x03},
+	{0x8AC, 0x00},
+	{0x8AD, 0x00},
+	{0x8AE, 0x00},
+	{0x8AF, 0x00},
+	{0x8B0, 0x00},
+	{0x8B1, 0x00},
+	{0x8B6, 0x00},
+	{0x8B7, 0x01},
+	{0x8B8, 0x00},
+	{0x8B9, 0x00},
+	{0x8BA, 0x02},
+	{0x8BB, 0x00},
+	{0x8BC, 0xFF},
+	{0x8BD, 0x00},
+	{0x8FE, 0x02},
+};
+
+const static struct rj54n1_reg_val bank_10[] = {
+	{0x10bf, 0x69}
+};
+
+/* Clock dividers - these are default register values, divider = register + 1 */
+const static struct rj54n1_clock_div clk_div = {
+	.ratio_tg	= 3 /* default: 5 */,
+	.ratio_t	= 4 /* default: 1 */,
+	.ratio_r	= 4 /* default: 0 */,
+	.ratio_op	= 1 /* default: 5 */,
+	.ratio_o	= 9 /* default: 0 */,
+};
+
+static struct rj54n1 *to_rj54n1(const struct i2c_client *client)
+{
+	return container_of(i2c_get_clientdata(client), struct rj54n1, subdev);
+}
+
+static int reg_read(struct i2c_client *client, const u16 reg)
+{
+	struct rj54n1 *rj54n1 = to_rj54n1(client);
+	int ret;
+
+	/* set bank */
+	if (rj54n1->bank != reg >> 8) {
+		dev_dbg(&client->dev, "[0x%x] = 0x%x\n", 0xff, reg >> 8);
+		ret = i2c_smbus_write_byte_data(client, 0xff, reg >> 8);
+		if (ret < 0)
+			return ret;
+		rj54n1->bank = reg >> 8;
+	}
+	return i2c_smbus_read_byte_data(client, reg & 0xff);
+}
+
+static int reg_write(struct i2c_client *client, const u16 reg,
+		     const u8 data)
+{
+	struct rj54n1 *rj54n1 = to_rj54n1(client);
+	int ret;
+
+	/* set bank */
+	if (rj54n1->bank != reg >> 8) {
+		dev_dbg(&client->dev, "[0x%x] = 0x%x\n", 0xff, reg >> 8);
+		ret = i2c_smbus_write_byte_data(client, 0xff, reg >> 8);
+		if (ret < 0)
+			return ret;
+		rj54n1->bank = reg >> 8;
+	}
+	dev_dbg(&client->dev, "[0x%x] = 0x%x\n", reg & 0xff, data);
+	return i2c_smbus_write_byte_data(client, reg & 0xff, data);
+}
+
+static int reg_set(struct i2c_client *client, const u16 reg,
+		   const u8 data, const u8 mask)
+{
+	int ret;
+
+	ret = reg_read(client, reg);
+	if (ret < 0)
+		return ret;
+	return reg_write(client, reg, (ret & ~mask) | (data & mask));
+}
+
+static int reg_write_multiple(struct i2c_client *client,
+			      const struct rj54n1_reg_val *rv, const int n)
+{
+	int i, ret;
+
+	for (i = 0; i < n; i++) {
+		ret = reg_write(client, rv->reg, rv->val);
+		if (ret < 0)
+			return ret;
+		rv++;
+	}
+
+	return 0;
+}
+
+static int rj54n1_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	/* TODO: start / stop streaming */
+	return 0;
+}
+
+static int rj54n1_set_bus_param(struct soc_camera_device *icd,
+				unsigned long flags)
+{
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	struct i2c_client *client = sd->priv;
+	/* Figures 2.5-1 to 2.5-3 - default falling pixclk edge */
+
+	if (flags & SOCAM_PCLK_SAMPLE_RISING)
+		return reg_write(client, RJ54N1_OUT_SIGPO, 1 << 4);
+	else
+		return reg_write(client, RJ54N1_OUT_SIGPO, 0);
+}
+
+static unsigned long rj54n1_query_bus_param(struct soc_camera_device *icd)
+{
+	struct soc_camera_link *icl = to_soc_camera_link(icd);
+	const unsigned long flags =
+		SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING |
+		SOCAM_MASTER | SOCAM_DATAWIDTH_8 |
+		SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
+		SOCAM_DATA_ACTIVE_HIGH;
+
+	return soc_camera_apply_sensor_flags(icl, flags);
+}
+
+static int rj54n1_set_rect(struct i2c_client *client,
+			   u16 reg_x, u16 reg_y, u16 reg_xy,
+			   u32 width, u32 height)
+{
+	int ret;
+
+	ret = reg_write(client, reg_xy,
+			((width >> 4) & 0x70) |
+			((height >> 8) & 7));
+
+	if (!ret)
+		ret = reg_write(client, reg_x, width & 0xff);
+	if (!ret)
+		ret = reg_write(client, reg_y, height & 0xff);
+
+	return ret;
+}
+
+/*
+ * Some commands, specifically certain initialisation sequences, require
+ * a commit operation.
+ */
+static int rj54n1_commit(struct i2c_client *client)
+{
+	int ret = reg_write(client, RJ54N1_INIT_START, 1);
+	msleep(10);
+	if (!ret)
+		ret = reg_write(client, RJ54N1_INIT_START, 0);
+	return ret;
+}
+
+static int rj54n1_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+{
+	struct i2c_client *client = sd->priv;
+	struct rj54n1 *rj54n1 = to_rj54n1(client);
+
+	a->c	= rj54n1->rect;
+	a->type	= V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	return 0;
+}
+
+static int rj54n1_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
+{
+	a->bounds.left			= RJ54N1_COLUMN_SKIP;
+	a->bounds.top			= RJ54N1_ROW_SKIP;
+	a->bounds.width			= RJ54N1_MAX_WIDTH;
+	a->bounds.height		= RJ54N1_MAX_HEIGHT;
+	a->defrect			= a->bounds;
+	a->type				= V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	a->pixelaspect.numerator	= 1;
+	a->pixelaspect.denominator	= 1;
+
+	return 0;
+}
+
+static int rj54n1_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+	struct i2c_client *client = sd->priv;
+	struct rj54n1 *rj54n1 = to_rj54n1(client);
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+
+	pix->pixelformat	= rj54n1->fourcc;
+	pix->field		= V4L2_FIELD_NONE;
+	pix->width		= rj54n1->width;
+	pix->height		= rj54n1->height;
+
+	return 0;
+}
+
+/*
+ * The actual geometry configuration routine. It scales the input window into
+ * the output one, updates the window sizes and returns an error or the resize
+ * coefficient on success. Note: we only use the "Fixed Scaling" on this camera.
+ */
+static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h,
+			       u32 *out_w, u32 *out_h)
+{
+	struct i2c_client *client = sd->priv;
+	unsigned int skip, resize, input_w = *in_w, input_h = *in_h,
+		output_w = *out_w, output_h = *out_h;
+	u16 inc_sel;
+	int ret;
+
+	ret = rj54n1_set_rect(client, RJ54N1_X_OUTPUT_SIZE_S_L,
+			      RJ54N1_Y_OUTPUT_SIZE_S_L,
+			      RJ54N1_XY_OUTPUT_SIZE_S_H, output_w, output_h);
+	if (!ret)
+		ret = rj54n1_set_rect(client, RJ54N1_X_OUTPUT_SIZE_P_L,
+			      RJ54N1_Y_OUTPUT_SIZE_P_L,
+			      RJ54N1_XY_OUTPUT_SIZE_P_H, output_w, output_h);
+
+	if (ret < 0)
+		return ret;
+
+	if (output_w > input_w || output_h > input_h) {
+		input_w = output_w;
+		input_h = output_h;
+
+		resize = 1024;
+	} else {
+		unsigned int resize_x, resize_y;
+		resize_x = input_w * 1024 / output_w;
+		resize_y = input_h * 1024 / output_h;
+
+		resize = min(resize_x, resize_y);
+
+		/* Prohibited value ranges */
+		switch (resize) {
+		case 2040 ... 2047:
+			resize = 2039;
+			break;
+		case 4080 ... 4095:
+			resize = 4079;
+			break;
+		case 8160 ... 8191:
+			resize = 8159;
+			break;
+		case 16320 ... 16383:
+			resize = 16319;
+		}
+
+		input_w = output_w * resize / 1024;
+		input_h = output_h * resize / 1024;
+	}
+
+	/* Set scaling */
+	ret = reg_write(client, RJ54N1_RESIZE_HOLD_L, resize & 0xff);
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RESIZE_HOLD_H, resize >> 8);
+
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * Configure a skipping bitmask. The sensor will select a skipping value
+	 * among set bits automatically.
+	 */
+	skip = min(resize / 1024, (unsigned)15);
+	inc_sel = 1 << skip;
+
+	if (inc_sel <= 2)
+		inc_sel = 0xc;
+	else if (resize & 1023 && skip < 15)
+		inc_sel |= 1 << (skip + 1);
+
+	ret = reg_write(client, RJ54N1_INC_USE_SEL_L, inc_sel & 0xfc);
+	if (!ret)
+		ret = reg_write(client, RJ54N1_INC_USE_SEL_H, inc_sel >> 8);
+
+	/* Start resizing */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RESIZE_CONTROL,
+				RESIZE_HOLD_SEL | RESIZE_GO | 1);
+
+	if (ret < 0)
+		return ret;
+
+	dev_dbg(&client->dev, "resize %u, skip %u\n", resize, skip);
+
+	/* Constant taken from manufacturer's example */
+	msleep(230);
+
+	ret = reg_write(client, RJ54N1_RESIZE_CONTROL, RESIZE_HOLD_SEL | 1);
+	if (ret < 0)
+		return ret;
+
+	*in_w = input_w;
+	*in_h = input_h;
+	*out_w = output_w;
+	*out_h = output_h;
+
+	return resize;
+}
+
+static int rj54n1_set_clock(struct i2c_client *client)
+{
+	struct rj54n1 *rj54n1 = to_rj54n1(client);
+	int ret;
+
+	/* Enable external clock */
+	ret = reg_write(client, RJ54N1_RESET_STANDBY, E_EXCLK | SOFT_STDBY);
+	/* Leave stand-by */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RESET_STANDBY, E_EXCLK);
+
+	if (!ret)
+		ret = reg_write(client, RJ54N1_PLL_L, 2);
+	if (!ret)
+		ret = reg_write(client, RJ54N1_PLL_N, 0x31);
+
+	/* TGCLK dividers */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RATIO_TG,
+				rj54n1->clk_div.ratio_tg);
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RATIO_T,
+				rj54n1->clk_div.ratio_t);
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RATIO_R,
+				rj54n1->clk_div.ratio_r);
+
+	/* Enable TGCLK & RAMP */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RAMP_TGCLK_EN, 3);
+
+	/* Disable clock output */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_OCLK_DSP, 0);
+
+	/* Set divisors */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RATIO_OP,
+				rj54n1->clk_div.ratio_op);
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RATIO_O,
+				rj54n1->clk_div.ratio_o);
+
+	/* Enable OCLK */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_OCLK_SEL_EN, 1);
+
+	/* Use PLL for Timing Generator, write 2 to reserved bits */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_TG_BYPASS, 2);
+
+	/* Take sensor out of reset */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RESET_STANDBY,
+				E_EXCLK | SEN_RSTX);
+	/* Enable PLL */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_PLL_EN, 1);
+
+	/* Wait for PLL to stabilise */
+	msleep(10);
+
+	/* Enable clock to frequency divider */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_CLK_RST, 1);
+
+	if (!ret)
+		ret = reg_read(client, RJ54N1_CLK_RST);
+	if (ret != 1) {
+		dev_err(&client->dev,
+			"Resetting RJ54N1CB0C clock failed: %d!\n", ret);
+		return -EIO;
+	}
+	/* Start the PLL */
+	ret = reg_set(client, RJ54N1_OCLK_DSP, 1, 1);
+
+	/* Enable OCLK */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_OCLK_SEL_EN, 1);
+
+	return ret;
+}
+
+static int rj54n1_reg_init(struct i2c_client *client)
+{
+	int ret = rj54n1_set_clock(client);
+
+	if (!ret)
+		ret = reg_write_multiple(client, bank_7, ARRAY_SIZE(bank_7));
+	if (!ret)
+		ret = reg_write_multiple(client, bank_10, ARRAY_SIZE(bank_10));
+
+	/* Set binning divisors */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_SCALE_1_2_LEV, 3 | (7 << 4));
+	if (!ret)
+		ret = reg_write(client, RJ54N1_SCALE_4_LEV, 0xf);
+
+	/* Switch to fixed resize mode */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RESIZE_CONTROL,
+				RESIZE_HOLD_SEL | 1);
+
+	/* Set gain */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_Y_GAIN, 0x84);
+
+	/* Mirror the image back: default is upside down and left-to-right... */
+	if (!ret)
+		ret = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 3, 3);
+
+	if (!ret)
+		ret = reg_write_multiple(client, bank_4, ARRAY_SIZE(bank_4));
+	if (!ret)
+		ret = reg_write_multiple(client, bank_5, ARRAY_SIZE(bank_5));
+	if (!ret)
+		ret = reg_write_multiple(client, bank_8, ARRAY_SIZE(bank_8));
+
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RESET_STANDBY,
+				E_EXCLK | DSP_RSTX | SEN_RSTX);
+
+	/* Commit init */
+	if (!ret)
+		ret = rj54n1_commit(client);
+
+	/* Take DSP, TG, sensor out of reset */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RESET_STANDBY,
+				E_EXCLK | DSP_RSTX | TG_RSTX | SEN_RSTX);
+
+	if (!ret)
+		ret = reg_write(client, 0x7fe, 2);
+
+	/* Constant taken from manufacturer's example */
+	msleep(700);
+
+	return ret;
+}
+
+/* FIXME: streaming output only up to 800x600 is functional */
+static int rj54n1_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+
+	pix->field = V4L2_FIELD_NONE;
+
+	if (pix->width > 800)
+		pix->width = 800;
+	if (pix->height > 600)
+		pix->height = 600;
+
+	return 0;
+}
+
+static int rj54n1_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+	struct i2c_client *client = sd->priv;
+	struct rj54n1 *rj54n1 = to_rj54n1(client);
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+	unsigned int output_w, output_h,
+		input_w = rj54n1->rect.width, input_h = rj54n1->rect.height;
+	int ret;
+
+	/*
+	 * The host driver can call us without .try_fmt(), so, we have to take
+	 * care ourseleves
+	 */
+	ret = rj54n1_try_fmt(sd, f);
+
+	/*
+	 * Verify if the sensor has just been powered on. TODO: replace this
+	 * with proper PM, when a suitable API is available.
+	 */
+	if (!ret)
+		ret = reg_read(client, RJ54N1_RESET_STANDBY);
+	if (ret < 0)
+		return ret;
+
+	if (!(ret & E_EXCLK)) {
+		ret = rj54n1_reg_init(client);
+		if (ret < 0)
+			return ret;
+	}
+
+	/* RA_SEL_UL is only relevant for raw modes, ignored otherwise. */
+	switch (pix->pixelformat) {
+	case V4L2_PIX_FMT_YUYV:
+		ret = reg_write(client, RJ54N1_OUT_SEL, 0);
+		if (!ret)
+			ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
+		break;
+	case V4L2_PIX_FMT_RGB565:
+		ret = reg_write(client, RJ54N1_OUT_SEL, 0x11);
+		if (!ret)
+			ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	if (ret < 0)
+		return ret;
+
+	/* Supported scales 1:1 - 1:16 */
+	if (pix->width < input_w / 16)
+		pix->width = input_w / 16;
+	if (pix->height < input_h / 16)
+		pix->height = input_h / 16;
+
+	output_w = pix->width;
+	output_h = pix->height;
+
+	ret = rj54n1_sensor_scale(sd, &input_w, &input_h, &output_w, &output_h);
+	if (ret < 0)
+		return ret;
+
+	rj54n1->fourcc		= pix->pixelformat;
+	rj54n1->resize		= ret;
+	rj54n1->rect.width	= input_w;
+	rj54n1->rect.height	= input_h;
+	rj54n1->width		= output_w;
+	rj54n1->height		= output_h;
+
+	pix->width		= output_w;
+	pix->height		= output_h;
+	pix->field		= V4L2_FIELD_NONE;
+
+	return ret;
+}
+
+static int rj54n1_g_chip_ident(struct v4l2_subdev *sd,
+			       struct v4l2_dbg_chip_ident *id)
+{
+	struct i2c_client *client = sd->priv;
+
+	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
+		return -EINVAL;
+
+	if (id->match.addr != client->addr)
+		return -ENODEV;
+
+	id->ident	= V4L2_IDENT_RJ54N1CB0C;
+	id->revision	= 0;
+
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int rj54n1_g_register(struct v4l2_subdev *sd,
+			     struct v4l2_dbg_register *reg)
+{
+	struct i2c_client *client = sd->priv;
+
+	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR ||
+	    reg->reg < 0x400 || reg->reg > 0x1fff)
+		/* Registers > 0x0800 are only available from Sharp support */
+		return -EINVAL;
+
+	if (reg->match.addr != client->addr)
+		return -ENODEV;
+
+	reg->size = 1;
+	reg->val = reg_read(client, reg->reg);
+
+	if (reg->val > 0xff)
+		return -EIO;
+
+	return 0;
+}
+
+static int rj54n1_s_register(struct v4l2_subdev *sd,
+			     struct v4l2_dbg_register *reg)
+{
+	struct i2c_client *client = sd->priv;
+
+	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR ||
+	    reg->reg < 0x400 || reg->reg > 0x1fff)
+		/* Registers >= 0x0800 are only available from Sharp support */
+		return -EINVAL;
+
+	if (reg->match.addr != client->addr)
+		return -ENODEV;
+
+	if (reg_write(client, reg->reg, reg->val) < 0)
+		return -EIO;
+
+	return 0;
+}
+#endif
+
+static const struct v4l2_queryctrl rj54n1_controls[] = {
+	{
+		.id		= V4L2_CID_VFLIP,
+		.type		= V4L2_CTRL_TYPE_BOOLEAN,
+		.name		= "Flip Vertically",
+		.minimum	= 0,
+		.maximum	= 1,
+		.step		= 1,
+		.default_value	= 0,
+	}, {
+		.id		= V4L2_CID_HFLIP,
+		.type		= V4L2_CTRL_TYPE_BOOLEAN,
+		.name		= "Flip Horizontally",
+		.minimum	= 0,
+		.maximum	= 1,
+		.step		= 1,
+		.default_value	= 0,
+	}, {
+		.id		= V4L2_CID_GAIN,
+		.type		= V4L2_CTRL_TYPE_INTEGER,
+		.name		= "Gain",
+		.minimum	= 0,
+		.maximum	= 127,
+		.step		= 1,
+		.default_value	= 66,
+		.flags		= V4L2_CTRL_FLAG_SLIDER,
+	},
+};
+
+static struct soc_camera_ops rj54n1_ops = {
+	.set_bus_param		= rj54n1_set_bus_param,
+	.query_bus_param	= rj54n1_query_bus_param,
+	.controls		= rj54n1_controls,
+	.num_controls		= ARRAY_SIZE(rj54n1_controls),
+};
+
+static int rj54n1_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct i2c_client *client = sd->priv;
+	int data;
+
+	switch (ctrl->id) {
+	case V4L2_CID_VFLIP:
+		data = reg_read(client, RJ54N1_MIRROR_STILL_MODE);
+		if (data < 0)
+			return -EIO;
+		ctrl->value = !(data & 1);
+		break;
+	case V4L2_CID_HFLIP:
+		data = reg_read(client, RJ54N1_MIRROR_STILL_MODE);
+		if (data < 0)
+			return -EIO;
+		ctrl->value = !(data & 2);
+		break;
+	case V4L2_CID_GAIN:
+		data = reg_read(client, RJ54N1_Y_GAIN);
+		if (data < 0)
+			return -EIO;
+
+		ctrl->value = data / 2;
+		break;
+	}
+
+	return 0;
+}
+
+static int rj54n1_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	int data;
+	struct i2c_client *client = sd->priv;
+	const struct v4l2_queryctrl *qctrl;
+
+	qctrl = soc_camera_find_qctrl(&rj54n1_ops, ctrl->id);
+	if (!qctrl)
+		return -EINVAL;
+
+	switch (ctrl->id) {
+	case V4L2_CID_VFLIP:
+		if (ctrl->value)
+			data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 1);
+		else
+			data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 1, 1);
+		if (data < 0)
+			return -EIO;
+		break;
+	case V4L2_CID_HFLIP:
+		if (ctrl->value)
+			data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 2);
+		else
+			data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 2, 2);
+		if (data < 0)
+			return -EIO;
+		break;
+	case V4L2_CID_GAIN:
+		if (ctrl->value > qctrl->maximum ||
+		    ctrl->value < qctrl->minimum)
+			return -EINVAL;
+		else if (reg_write(client, RJ54N1_Y_GAIN, ctrl->value * 2) < 0)
+			return -EIO;
+		break;
+	}
+
+	return 0;
+}
+
+static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = {
+	.g_ctrl		= rj54n1_g_ctrl,
+	.s_ctrl		= rj54n1_s_ctrl,
+	.g_chip_ident	= rj54n1_g_chip_ident,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.g_register	= rj54n1_g_register,
+	.s_register	= rj54n1_s_register,
+#endif
+};
+
+static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = {
+	.s_stream	= rj54n1_s_stream,
+	.s_fmt		= rj54n1_s_fmt,
+	.g_fmt		= rj54n1_g_fmt,
+	.try_fmt	= rj54n1_try_fmt,
+	.g_crop		= rj54n1_g_crop,
+	.cropcap	= rj54n1_cropcap,
+};
+
+static struct v4l2_subdev_ops rj54n1_subdev_ops = {
+	.core	= &rj54n1_subdev_core_ops,
+	.video	= &rj54n1_subdev_video_ops,
+};
+
+static int rj54n1_pin_config(struct i2c_client *client)
+{
+	/*
+	 * Experimentally found out IOCTRL wired to 0. TODO: add to platform
+	 * data: 0 or 1 << 7.
+	 */
+	return reg_write(client, RJ54N1_IOC, 0);
+}
+
+/*
+ * Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one
+ */
+static int rj54n1_video_probe(struct soc_camera_device *icd,
+			      struct i2c_client *client)
+{
+	int data1, data2;
+	int ret;
+
+	/* This could be a BUG_ON() or a WARN_ON(), or remove it completely */
+	if (!icd->dev.parent ||
+	    to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
+		return -ENODEV;
+
+	/* Read out the chip version register */
+	data1 = reg_read(client, RJ54N1_DEV_CODE);
+	data2 = reg_read(client, RJ54N1_DEV_CODE2);
+
+	if (data1 != 0x51 || data2 != 0x10) {
+		ret = -ENODEV;
+		dev_info(&client->dev, "No RJ54N1CB0C found, read 0x%x:0x%x\n",
+			 data1, data2);
+		goto ei2c;
+	}
+
+	ret = rj54n1_pin_config(client);
+	if (ret < 0)
+		goto ei2c;
+
+	dev_info(&client->dev, "Detected a RJ54N1CB0C chip ID 0x%x:0x%x\n",
+		 data1, data2);
+
+ei2c:
+	return ret;
+}
+
+static int rj54n1_probe(struct i2c_client *client,
+			const struct i2c_device_id *did)
+{
+	struct rj54n1 *rj54n1;
+	struct soc_camera_device *icd = client->dev.platform_data;
+	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+	struct soc_camera_link *icl;
+	int ret;
+
+	if (!icd) {
+		dev_err(&client->dev, "RJ54N1CB0C: missing soc-camera data!\n");
+		return -EINVAL;
+	}
+
+	icl = to_soc_camera_link(icd);
+	if (!icl) {
+		dev_err(&client->dev, "RJ54N1CB0C: missing platform data!\n");
+		return -EINVAL;
+	}
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+		dev_warn(&adapter->dev,
+			 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_BYTE\n");
+		return -EIO;
+	}
+
+	rj54n1 = kzalloc(sizeof(struct rj54n1), GFP_KERNEL);
+	if (!rj54n1)
+		return -ENOMEM;
+
+	v4l2_i2c_subdev_init(&rj54n1->subdev, client, &rj54n1_subdev_ops);
+
+	icd->ops		= &rj54n1_ops;
+
+	rj54n1->clk_div		= clk_div;
+	rj54n1->rect.left	= RJ54N1_COLUMN_SKIP;
+	rj54n1->rect.top	= RJ54N1_ROW_SKIP;
+	rj54n1->rect.width	= RJ54N1_MAX_WIDTH;
+	rj54n1->rect.height	= RJ54N1_MAX_HEIGHT;
+	rj54n1->width		= RJ54N1_MAX_WIDTH;
+	rj54n1->height		= RJ54N1_MAX_HEIGHT;
+	rj54n1->fourcc		= V4L2_PIX_FMT_YUYV;
+	rj54n1->resize		= 1024;
+
+	ret = rj54n1_video_probe(icd, client);
+	if (ret < 0) {
+		icd->ops = NULL;
+		i2c_set_clientdata(client, NULL);
+		kfree(rj54n1);
+		return ret;
+	}
+
+	icd->formats		= rj54n1_colour_formats;
+	icd->num_formats	= ARRAY_SIZE(rj54n1_colour_formats);
+
+	return ret;
+}
+
+static int rj54n1_remove(struct i2c_client *client)
+{
+	struct rj54n1 *rj54n1 = to_rj54n1(client);
+	struct soc_camera_device *icd = client->dev.platform_data;
+	struct soc_camera_link *icl = to_soc_camera_link(icd);
+
+	icd->ops = NULL;
+	if (icl->free_bus)
+		icl->free_bus(icl);
+	i2c_set_clientdata(client, NULL);
+	client->driver = NULL;
+	kfree(rj54n1);
+
+	return 0;
+}
+
+static const struct i2c_device_id rj54n1_id[] = {
+	{ "rj54n1cb0c", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, rj54n1_id);
+
+static struct i2c_driver rj54n1_i2c_driver = {
+	.driver = {
+		.name = "rj54n1cb0c",
+	},
+	.probe		= rj54n1_probe,
+	.remove		= rj54n1_remove,
+	.id_table	= rj54n1_id,
+};
+
+static int __init rj54n1_mod_init(void)
+{
+	return i2c_add_driver(&rj54n1_i2c_driver);
+}
+
+static void __exit rj54n1_mod_exit(void)
+{
+	i2c_del_driver(&rj54n1_i2c_driver);
+}
+
+module_init(rj54n1_mod_init);
+module_exit(rj54n1_mod_exit);
+
+MODULE_DESCRIPTION("Sharp RJ54N1CB0C Camera driver");
+MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index 2c0bb06..41765f3 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -1958,7 +1958,7 @@
 				if (pdword[1] >= MAX_CHANNELS)
 					break;
 				cc = G_chnmap[pdword[1]];
-				if (!(cc >= 0 && cc < MAX_CHANNELS))
+				if (cc >= MAX_CHANNELS)
 					break;
 				switch (pdword[2]) {
 				case S2255_RESPONSE_SETMODE:
@@ -1980,7 +1980,7 @@
 					wake_up(&dev->fw_data->wait_fw);
 					break;
 				default:
-					printk(KERN_INFO "s2255 unknwn resp\n");
+					printk(KERN_INFO "s2255 unknown resp\n");
 				}
 			default:
 				pdata++;
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c
index 5c24c99..3bca744 100644
--- a/drivers/media/video/saa7110.c
+++ b/drivers/media/video/saa7110.c
@@ -304,7 +304,7 @@
 {
 	struct saa7110 *decoder = to_saa7110(sd);
 
-	if (input < 0 || input >= SAA7110_MAX_INPUT) {
+	if (input >= SAA7110_MAX_INPUT) {
 		v4l2_dbg(1, debug, sd, "input=%d not available\n", input);
 		return -EINVAL;
 	}
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 0901322..7e40d6d 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -5239,6 +5239,7 @@
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
+		.mpeg           = SAA7134_MPEG_DVB,
 		.inputs         = { {
 			.name = name_tv,
 			.vmux = 2,
@@ -5279,6 +5280,46 @@
 			.amux = TV,
 		},
 	},
+	[SAA7134_BOARD_ASUS_EUROPA_HYBRID] = {
+		.name           = "Asus Europa Hybrid OEM",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_TD1316,
+		.radio_type     = UNSET,
+		.tuner_addr	= 0x61,
+		.radio_addr	= ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE,
+		.mpeg           = SAA7134_MPEG_DVB,
+		.inputs = { {
+			.name   = name_tv,
+			.vmux   = 3,
+			.amux   = TV,
+			.tv     = 1,
+		}, {
+			.name   = name_comp1,
+			.vmux   = 4,
+			.amux   = LINE2,
+		}, {
+			.name   = name_svideo,
+			.vmux   = 8,
+			.amux   = LINE2,
+		} },
+	},
+	[SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S] = {
+		.name           = "Leadtek Winfast DTV1000S",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_TDA8290,
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.mpeg           = SAA7134_MPEG_DVB,
+		.inputs         = { {
+			.name = name_comp1,
+			.vmux = 3,
+		}, {
+			.name = name_svideo,
+			.vmux = 8,
+		} },
+	},
 
 };
 
@@ -6418,6 +6459,18 @@
 		.subdevice    = 0x2004,
 		.driver_data  = SAA7134_BOARD_ZOLID_HYBRID_PCI,
 	}, {
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+		.subvendor    = 0x1043,
+		.subdevice    = 0x4847,
+		.driver_data  = SAA7134_BOARD_ASUS_EUROPA_HYBRID,
+	}, {
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
+		.subvendor    = 0x107d,
+		.subdevice    = 0x6655,
+		.driver_data  = SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S,
+	}, {
 		/* --- boards without eeprom + subsystem ID --- */
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -6748,6 +6801,7 @@
 	case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG:
 	case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS:
 	case SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM:
+	case SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S:
 		dev->has_remote = SAA7134_REMOTE_GPIO;
 		break;
 	case SAA7134_BOARD_FLYDVBS_LR300:
@@ -7079,6 +7133,7 @@
 		/* break intentionally omitted */
 	case SAA7134_BOARD_VIDEOMATE_DVBT_300:
 	case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
+	case SAA7134_BOARD_ASUS_EUROPA_HYBRID:
 	{
 
 		/* The Philips EUROPA based hybrid boards have the tuner
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index f87757f..0ba7f5a 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -1032,7 +1032,7 @@
 	saa7134_irq_video_signalchange(dev);
 
 	if (TUNER_ABSENT != dev->tuner_type)
-		saa_call_all(dev, tuner, s_standby);
+		saa_call_all(dev, core, s_power, 0);
 
 	/* register v4l devices */
 	if (saa7134_no_overlay > 0)
@@ -1319,7 +1319,7 @@
 #endif
 };
 
-static int saa7134_init(void)
+static int __init saa7134_init(void)
 {
 	INIT_LIST_HEAD(&saa7134_devlist);
 	printk(KERN_INFO "saa7130/34: v4l2 driver version %d.%d.%d loaded\n",
@@ -1333,7 +1333,7 @@
 	return pci_register_driver(&saa7134_pci_driver);
 }
 
-static void saa7134_fini(void)
+static void __exit saa7134_fini(void)
 {
 	pci_unregister_driver(&saa7134_pci_driver);
 }
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index a26e997..73739d2 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -40,6 +40,7 @@
 #include "tda1004x.h"
 #include "nxt200x.h"
 #include "tuner-xc2028.h"
+#include "xc5000.h"
 
 #include "tda10086.h"
 #include "tda826x.h"
@@ -871,6 +872,20 @@
 	.disable_i2c_gate_ctrl = 1,
 };
 
+static struct xc5000_config behold_x7_tunerconfig = {
+	.i2c_address      = 0xc2>>1,
+	.if_khz           = 4560,
+	.radio_input      = XC5000_RADIO_FM1,
+};
+
+static struct zl10353_config behold_x7_config = {
+	.demod_address = 0x1e>>1,
+	.if2           = 45600,
+	.no_tuner      = 1,
+	.parallel_ts   = 1,
+	.disable_i2c_gate_ctrl = 1,
+};
+
 /* ==================================================================
  * tda10086 based DVB-S cards, helper functions
  */
@@ -1030,6 +1045,32 @@
 	.gate    = TDA18271_GATE_ANALOG,
 };
 
+static struct tda10048_config dtv1000s_tda10048_config = {
+	.demod_address    = 0x10 >> 1,
+	.output_mode      = TDA10048_PARALLEL_OUTPUT,
+	.fwbulkwritelen   = TDA10048_BULKWRITE_200,
+	.inversion        = TDA10048_INVERSION_ON,
+	.dtv6_if_freq_khz = TDA10048_IF_3300,
+	.dtv7_if_freq_khz = TDA10048_IF_3800,
+	.dtv8_if_freq_khz = TDA10048_IF_4300,
+	.clk_freq_khz     = TDA10048_CLK_16000,
+	.disable_gate_access = 1,
+};
+
+static struct tda18271_std_map dtv1000s_tda18271_std_map = {
+	.dvbt_6   = { .if_freq = 3300, .agc_mode = 3, .std = 4,
+		      .if_lvl = 1, .rfagc_top = 0x37, },
+	.dvbt_7   = { .if_freq = 3800, .agc_mode = 3, .std = 5,
+		      .if_lvl = 1, .rfagc_top = 0x37, },
+	.dvbt_8   = { .if_freq = 4300, .agc_mode = 3, .std = 6,
+		      .if_lvl = 1, .rfagc_top = 0x37, },
+};
+
+static struct tda18271_config dtv1000s_tda18271_config = {
+	.std_map = &dtv1000s_tda18271_std_map,
+	.gate    = TDA18271_GATE_ANALOG,
+};
+
 /* ==================================================================
  * Core code
  */
@@ -1116,6 +1157,7 @@
 		break;
 	case SAA7134_BOARD_PHILIPS_EUROPA:
 	case SAA7134_BOARD_VIDEOMATE_DVBT_300:
+	case SAA7134_BOARD_ASUS_EUROPA_HYBRID:
 		fe0->dvb.frontend = dvb_attach(tda10046_attach,
 					       &philips_europa_config,
 					       &dev->i2c_adap);
@@ -1482,6 +1524,15 @@
 				   TUNER_PHILIPS_FMD1216MEX_MK3);
 		}
 		break;
+	case SAA7134_BOARD_BEHOLD_X7:
+		fe0->dvb.frontend = dvb_attach(zl10353_attach,
+						&behold_x7_config,
+						&dev->i2c_adap);
+		if (fe0->dvb.frontend) {
+			dvb_attach(xc5000_attach, fe0->dvb.frontend,
+				   &dev->i2c_adap, &behold_x7_tunerconfig);
+		}
+		break;
 	case SAA7134_BOARD_AVERMEDIA_A700_PRO:
 	case SAA7134_BOARD_AVERMEDIA_A700_HYBRID:
 		/* Zarlink ZL10313 */
@@ -1518,6 +1569,19 @@
 				   &zolid_tda18271_config);
 		}
 		break;
+	case SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S:
+		fe0->dvb.frontend = dvb_attach(tda10048_attach,
+					       &dtv1000s_tda10048_config,
+					       &dev->i2c_adap);
+		if (fe0->dvb.frontend != NULL) {
+			dvb_attach(tda829x_attach, fe0->dvb.frontend,
+				   &dev->i2c_adap, 0x4b,
+				   &tda829x_no_probe);
+			dvb_attach(tda18271_attach, fe0->dvb.frontend,
+				   0x60, &dev->i2c_adap,
+				   &dtv1000s_tda18271_config);
+		}
+		break;
 	default:
 		wprintk("Huh? unknown DVB card?\n");
 		break;
@@ -1550,7 +1614,7 @@
 
 	/* register everything else */
 	ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
-		&dev->pci->dev, adapter_nr, 0);
+					&dev->pci->dev, adapter_nr, 0, NULL);
 
 	/* this sequence is necessary to make the tda1004x load its firmware
 	 * and to enter analog mode of hybrid boards
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index a0e8c62..744918b 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -102,14 +102,14 @@
 		if (data == ir->mask_keycode)
 			ir_input_nokey(ir->dev, &ir->ir);
 		else
-			ir_input_keydown(ir->dev, &ir->ir, data, data);
+			ir_input_keydown(ir->dev, &ir->ir, data);
 		return 0;
 	}
 
 	if (ir->polling) {
 		if ((ir->mask_keydown  &&  (0 != (gpio & ir->mask_keydown))) ||
 		    (ir->mask_keyup    &&  (0 == (gpio & ir->mask_keyup)))) {
-			ir_input_keydown(ir->dev, &ir->ir, data, data);
+			ir_input_keydown(ir->dev, &ir->ir, data);
 		} else {
 			ir_input_nokey(ir->dev, &ir->ir);
 		}
@@ -117,7 +117,7 @@
 	else {	/* IRQ driven mode - handle key press and release in one go */
 		if ((ir->mask_keydown  &&  (0 != (gpio & ir->mask_keydown))) ||
 		    (ir->mask_keyup    &&  (0 == (gpio & ir->mask_keyup)))) {
-			ir_input_keydown(ir->dev, &ir->ir, data, data);
+			ir_input_keydown(ir->dev, &ir->ir, data);
 			ir_input_nokey(ir->dev, &ir->ir);
 		}
 	}
@@ -616,6 +616,12 @@
 		mask_keycode = 0x003f00;
 		mask_keydown = 0x040000;
 		break;
+	case SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S:
+		ir_codes     = &ir_codes_winfast_table;
+		mask_keycode = 0x5f00;
+		mask_keyup   = 0x020000;
+		polling      = 50; /* ms */
+		break;
 	}
 	if (NULL == ir_codes) {
 		printk("%s: Oops: IR config error [card=%d]\n",
@@ -646,7 +652,10 @@
 	snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
 		 pci_name(dev->pci));
 
-	ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
+	err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
+	if (err < 0)
+		goto err_out_free;
+
 	input_dev->name = ir->name;
 	input_dev->phys = ir->phys;
 	input_dev->id.bustype = BUS_PCI;
@@ -677,6 +686,7 @@
 	saa7134_ir_stop(dev);
 	dev->remote = NULL;
  err_out_free:
+	ir_input_free(input_dev);
 	input_free_device(input_dev);
 	kfree(ir);
 	return err;
@@ -688,6 +698,7 @@
 		return;
 
 	saa7134_ir_stop(dev);
+	ir_input_free(dev->remote->dev);
 	input_unregister_device(dev->remote->dev);
 	kfree(dev->remote);
 	dev->remote = NULL;
@@ -695,10 +706,7 @@
 
 void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
 {
-	const unsigned short addr_list[] = {
-		0x7a, 0x47, 0x71, 0x2d,
-		I2C_CLIENT_END
-	};
+	struct i2c_board_info info;
 
 	struct i2c_msg msg_msi = {
 		.addr = 0x50,
@@ -714,9 +722,9 @@
 		return;
 	}
 
-	memset(&dev->info, 0, sizeof(dev->info));
+	memset(&info, 0, sizeof(struct i2c_board_info));
 	memset(&dev->init_data, 0, sizeof(dev->init_data));
-	strlcpy(dev->info.type, "ir_video", I2C_NAME_SIZE);
+	strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
 
 	switch (dev->board) {
 	case SAA7134_BOARD_PINNACLE_PCTV_110i:
@@ -725,23 +733,24 @@
 		if (pinnacle_remote == 0) {
 			dev->init_data.get_key = get_key_pinnacle_color;
 			dev->init_data.ir_codes = &ir_codes_pinnacle_color_table;
-			dev->info.addr = 0x47;
+			info.addr = 0x47;
 		} else {
 			dev->init_data.get_key = get_key_pinnacle_grey;
 			dev->init_data.ir_codes = &ir_codes_pinnacle_grey_table;
-			dev->info.addr = 0x47;
+			info.addr = 0x47;
 		}
 		break;
 	case SAA7134_BOARD_UPMOST_PURPLE_TV:
 		dev->init_data.name = "Purple TV";
 		dev->init_data.get_key = get_key_purpletv;
 		dev->init_data.ir_codes = &ir_codes_purpletv_table;
+		info.addr = 0x7a;
 		break;
 	case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
 		dev->init_data.name = "MSI TV@nywhere Plus";
 		dev->init_data.get_key = get_key_msi_tvanywhere_plus;
 		dev->init_data.ir_codes = &ir_codes_msi_tvanywhere_plus_table;
-		dev->info.addr = 0x30;
+		info.addr = 0x30;
 		/* MSI TV@nywhere Plus controller doesn't seem to
 		   respond to probes unless we read something from
 		   an existing device. Weird...
@@ -755,6 +764,7 @@
 		dev->init_data.name = "HVR 1110";
 		dev->init_data.get_key = get_key_hvr1110;
 		dev->init_data.ir_codes = &ir_codes_hauppauge_new_table;
+		info.addr = 0x71;
 		break;
 	case SAA7134_BOARD_BEHOLD_607FM_MK3:
 	case SAA7134_BOARD_BEHOLD_607FM_MK5:
@@ -772,23 +782,20 @@
 		dev->init_data.name = "BeholdTV";
 		dev->init_data.get_key = get_key_beholdm6xx;
 		dev->init_data.ir_codes = &ir_codes_behold_table;
+		info.addr = 0x2d;
 		break;
 	case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
 	case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
-		dev->info.addr = 0x40;
+		info.addr = 0x40;
 		break;
-	}
-
-	if (dev->init_data.name)
-		dev->info.platform_data = &dev->init_data;
-	/* No need to probe if address is known */
-	if (dev->info.addr) {
-		i2c_new_device(&dev->i2c_adap, &dev->info);
+	default:
+		dprintk("No I2C IR support for board %x\n", dev->board);
 		return;
 	}
 
-	/* Address not known, fallback to probing */
-	i2c_new_probed_device(&dev->i2c_adap, &dev->info, addr_list);
+	if (dev->init_data.name)
+		info.platform_data = &dev->init_data;
+	i2c_new_device(&dev->i2c_adap, &info);
 }
 
 static int saa7134_rc5_irq(struct saa7134_dev *dev)
@@ -936,7 +943,7 @@
 		dprintk("scancode = 0x%02x (code = 0x%02x, notcode= 0x%02x)\n",
 			 ir->code, ircode, not_code);
 
-		ir_input_keydown(ir->dev, &ir->ir, ir->code, ir->code);
+		ir_input_keydown(ir->dev, &ir->ir, ir->code);
 	} else
 		dprintk("Repeat last key\n");
 
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index da26f47..35f8daa 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -1499,7 +1499,7 @@
 	saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0);
 	saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0);
 
-	saa_call_all(dev, tuner, s_standby);
+	saa_call_all(dev, core, s_power, 0);
 	if (fh->radio)
 		saa_call_all(dev, core, ioctl, RDS_CMD_CLOSE, &cmd);
 
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index f8697d4..53b7e0b 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -297,6 +297,8 @@
 #define SAA7134_BOARD_BEHOLD_X7             171
 #define SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM 172
 #define SAA7134_BOARD_ZOLID_HYBRID_PCI		173
+#define SAA7134_BOARD_ASUS_EUROPA_HYBRID	174
+#define SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S 175
 
 #define SAA7134_MAXBOARDS 32
 #define SAA7134_INPUT_MAX 8
@@ -592,7 +594,6 @@
 	unsigned int               insuspend;
 
 	/* I2C keyboard data */
-	struct i2c_board_info      info;
 	struct IR_i2c_init_data    init_data;
 
 	/* SAA7134_MPEG_* */
diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c
index 709affc..e6aa0fb 100644
--- a/drivers/media/video/saa7164/saa7164-core.c
+++ b/drivers/media/video/saa7164/saa7164-core.c
@@ -724,13 +724,13 @@
 	.resume   = NULL,
 };
 
-static int saa7164_init(void)
+static int __init saa7164_init(void)
 {
 	printk(KERN_INFO "saa7164 driver loaded\n");
 	return pci_register_driver(&saa7164_pci_driver);
 }
 
-static void saa7164_fini(void)
+static void __exit saa7164_fini(void)
 {
 	pci_unregister_driver(&saa7164_pci_driver);
 }
diff --git a/drivers/media/video/saa7164/saa7164-dvb.c b/drivers/media/video/saa7164/saa7164-dvb.c
index 6a2d847d..cf099c5 100644
--- a/drivers/media/video/saa7164/saa7164-dvb.c
+++ b/drivers/media/video/saa7164/saa7164-dvb.c
@@ -68,6 +68,7 @@
 	.std_map	= &hauppauge_tda18271_std_map,
 	.gate		= TDA18271_GATE_ANALOG,
 	.role		= TDA18271_SLAVE,
+	.output_opt     = TDA18271_OUTPUT_LT_OFF,
 	.rf_cal_on_startup = 1
 };
 
diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c
index b15c409..6818df5 100644
--- a/drivers/media/video/saa717x.c
+++ b/drivers/media/video/saa717x.c
@@ -1115,7 +1115,7 @@
 	v4l2_dbg(1, debug, sd, "decoder set input (%d)\n", input);
 	/* inputs from 0-9 are available*/
 	/* saa717x have mode0-mode9 but mode5 is reserved. */
-	if (input < 0 || input > 9 || input == 5)
+	if (input > 9 || input == 5)
 		return -EINVAL;
 
 	if (decoder->input != input) {
@@ -1312,7 +1312,7 @@
 		"MONO", "STEREO", "LANG1", "LANG2/SAP"
 	};
 
-	audio_mode = V4L2_TUNER_MODE_STEREO;
+	audio_mode = TUNER_AUDIO_STEREO;
 
 	switch (vt->audmode) {
 		case V4L2_TUNER_MODE_MONO:
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 9c8b7c7..a4f3472 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -153,6 +153,40 @@
 	return ioread32(priv->base + reg_offs);
 }
 
+static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev)
+{
+	int i, success = 0;
+	struct soc_camera_device *icd = pcdev->icd;
+
+	ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
+
+	/* wait CSTSR.CPTON bit */
+	for (i = 0; i < 1000; i++) {
+		if (!(ceu_read(pcdev, CSTSR) & 1)) {
+			success++;
+			break;
+		}
+		udelay(1);
+	}
+
+	/* wait CAPSR.CPKIL bit */
+	for (i = 0; i < 1000; i++) {
+		if (!(ceu_read(pcdev, CAPSR) & (1 << 16))) {
+			success++;
+			break;
+		}
+		udelay(1);
+	}
+
+
+	if (2 != success) {
+		dev_warn(&icd->dev, "soft reset time out\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
 /*
  *  Videobuf operations
  */
@@ -202,26 +236,45 @@
 #define CEU_CETCR_MAGIC 0x0317f313 /* acknowledge magical interrupt sources */
 #define CEU_CETCR_IGRW (1 << 4) /* prohibited register access interrupt bit */
 #define CEU_CEIER_CPEIE (1 << 0) /* one-frame capture end interrupt */
+#define CEU_CEIER_VBP   (1 << 20) /* vbp error */
 #define CEU_CAPCR_CTNCP (1 << 16) /* continuous capture mode (if set) */
+#define CEU_CEIER_MASK (CEU_CEIER_CPEIE | CEU_CEIER_VBP)
 
 
-static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
+/*
+ * return value doesn't reflex the success/failure to queue the new buffer,
+ * but rather the status of the previous buffer.
+ */
+static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
 {
 	struct soc_camera_device *icd = pcdev->icd;
 	dma_addr_t phys_addr_top, phys_addr_bottom;
+	u32 status;
+	int ret = 0;
 
 	/* The hardware is _very_ picky about this sequence. Especially
 	 * the CEU_CETCR_MAGIC value. It seems like we need to acknowledge
 	 * several not-so-well documented interrupt sources in CETCR.
 	 */
-	ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~CEU_CEIER_CPEIE);
-	ceu_write(pcdev, CETCR, ~ceu_read(pcdev, CETCR) & CEU_CETCR_MAGIC);
-	ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_CPEIE);
+	ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~CEU_CEIER_MASK);
+	status = ceu_read(pcdev, CETCR);
+	ceu_write(pcdev, CETCR, ~status & CEU_CETCR_MAGIC);
+	ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_MASK);
 	ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~CEU_CAPCR_CTNCP);
 	ceu_write(pcdev, CETCR, CEU_CETCR_MAGIC ^ CEU_CETCR_IGRW);
 
+	/*
+	 * When a VBP interrupt occurs, a capture end interrupt does not occur
+	 * and the image of that frame is not captured correctly. So, soft reset
+	 * is needed here.
+	 */
+	if (status & CEU_CEIER_VBP) {
+		sh_mobile_ceu_soft_reset(pcdev);
+		ret = -EIO;
+	}
+
 	if (!pcdev->active)
-		return;
+		return ret;
 
 	phys_addr_top = videobuf_to_dma_contig(pcdev->active);
 	ceu_write(pcdev, CDAYR, phys_addr_top);
@@ -247,6 +300,8 @@
 
 	pcdev->active->state = VIDEOBUF_ACTIVE;
 	ceu_write(pcdev, CAPSR, 0x1); /* start capture */
+
+	return ret;
 }
 
 static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq,
@@ -319,6 +374,11 @@
 	list_add_tail(&vb->queue, &pcdev->capture);
 
 	if (!pcdev->active) {
+		/*
+		 * Because there were no active buffer at this moment,
+		 * we are not interested in the return value of
+		 * sh_mobile_ceu_capture here.
+		 */
 		pcdev->active = vb;
 		sh_mobile_ceu_capture(pcdev);
 	}
@@ -379,9 +439,8 @@
 	else
 		pcdev->active = NULL;
 
-	sh_mobile_ceu_capture(pcdev);
-
-	vb->state = VIDEOBUF_DONE;
+	vb->state = (sh_mobile_ceu_capture(pcdev) < 0) ?
+		VIDEOBUF_ERROR : VIDEOBUF_DONE;
 	do_gettimeofday(&vb->ts);
 	vb->field_count++;
 	wake_up(&vb->done);
@@ -407,13 +466,9 @@
 
 	pm_runtime_get_sync(ici->v4l2_dev.dev);
 
-	ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
-	while (ceu_read(pcdev, CSTSR) & 1)
-		msleep(1);
-
 	pcdev->icd = icd;
 
-	return 0;
+	return sh_mobile_ceu_soft_reset(pcdev);
 }
 
 /* Called with .video_lock held */
@@ -427,7 +482,7 @@
 
 	/* disable capture, disable interrupts */
 	ceu_write(pcdev, CEIER, 0);
-	ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
+	sh_mobile_ceu_soft_reset(pcdev);
 
 	/* make sure active buffer is canceled */
 	spin_lock_irqsave(&pcdev->lock, flags);
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index aba92e2..5b3eaa1 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -320,6 +320,7 @@
 	struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
 	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
 	unsigned char buffer[4];
+	int tune_now = 1;
 
 	if (type == UNSET || type == TUNER_ABSENT) {
 		tuner_dbg ("tuner 0x%02x: Tuner type absent\n",c->addr);
@@ -328,7 +329,7 @@
 
 	t->type = type;
 	/* prevent invalid config values */
-	t->config = ((new_config >= 0) && (new_config < 256)) ? new_config : 0;
+	t->config = new_config < 256 ? new_config : 0;
 	if (tuner_callback != NULL) {
 		tuner_dbg("defining GPIO callback\n");
 		t->fe.callback = tuner_callback;
@@ -404,6 +405,7 @@
 		};
 		if (!dvb_attach(xc2028_attach, &t->fe, &cfg))
 			goto attach_failed;
+		tune_now = 0;
 		break;
 	}
 	case TUNER_TDA9887:
@@ -419,6 +421,7 @@
 		if (!dvb_attach(xc5000_attach,
 				&t->fe, t->i2c->adapter, &xc5000_cfg))
 			goto attach_failed;
+		tune_now = 0;
 		break;
 	}
 	case TUNER_NXP_TDA18271:
@@ -430,6 +433,7 @@
 		if (!dvb_attach(tda18271_attach, &t->fe, t->i2c->addr,
 				t->i2c->adapter, &cfg))
 			goto attach_failed;
+		tune_now = 0;
 		break;
 	}
 	default:
@@ -458,12 +462,13 @@
 	if (t->mode_mask == T_UNINITIALIZED)
 		t->mode_mask = new_mode_mask;
 
-	/* xc2028/3028 and xc5000 requires a firmware to be set-up later
+	/* Some tuners require more initialization setup before use,
+	   such as firmware download or device calibration.
 	   trying to set a frequency here will just fail
 	   FIXME: better to move set_freq to the tuner code. This is needed
 	   on analog tuners for PLL to properly work
 	 */
-	if (t->type != TUNER_XC2028 && t->type != TUNER_XC5000)
+	if (tune_now)
 		set_freq(c, (V4L2_TUNER_RADIO == t->mode) ?
 			    t->radio_freq : t->tv_freq);
 
@@ -752,14 +757,17 @@
 	return 0;
 }
 
-static int tuner_s_standby(struct v4l2_subdev *sd)
+static int tuner_s_power(struct v4l2_subdev *sd, int on)
 {
 	struct tuner *t = to_tuner(sd);
 	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
 
+	if (on)
+		return 0;
+
 	tuner_dbg("Putting tuner to sleep\n");
 
-	if (check_mode(t, "s_standby") == -EINVAL)
+	if (check_mode(t, "s_power") == -EINVAL)
 		return 0;
 	t->mode = T_STANDBY;
 	if (analog_ops->standby)
@@ -961,6 +969,7 @@
 static const struct v4l2_subdev_core_ops tuner_core_ops = {
 	.log_status = tuner_log_status,
 	.s_std = tuner_s_std,
+	.s_power = tuner_s_power,
 };
 
 static const struct v4l2_subdev_tuner_ops tuner_tuner_ops = {
@@ -971,7 +980,6 @@
 	.g_frequency = tuner_g_frequency,
 	.s_type_addr = tuner_s_type_addr,
 	.s_config = tuner_s_config,
-	.s_standby = tuner_s_standby,
 };
 
 static const struct v4l2_subdev_ops tuner_ops = {
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 0869baf..800fc1b 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -1919,7 +1919,7 @@
 	.s_radio = tvaudio_s_radio,
 	.s_frequency = tvaudio_s_frequency,
 	.s_tuner = tvaudio_s_tuner,
-	.s_tuner = tvaudio_g_tuner,
+	.g_tuner = tvaudio_g_tuner,
 };
 
 static const struct v4l2_subdev_audio_ops tvaudio_audio_ops = {
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index 2443726..26b4e71 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -272,7 +272,7 @@
 read_again:
 
 	err = i2c_smbus_read_byte_data(client, reg);
-	if (err == -1) {
+	if (err < 0) {
 		if (retry <= I2C_RETRY_COUNT) {
 			v4l2_warn(sd, "Read: retry ... %d\n", retry);
 			retry++;
diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/media/video/usbvideo/konicawc.c
index 31d57f2..a0addcb 100644
--- a/drivers/media/video/usbvideo/konicawc.c
+++ b/drivers/media/video/usbvideo/konicawc.c
@@ -225,7 +225,7 @@
 	int error;
 
 	usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
-	strncat(cam->input_physname, "/input0", sizeof(cam->input_physname));
+	strlcat(cam->input_physname, "/input0", sizeof(cam->input_physname));
 
 	cam->input = input_dev = input_allocate_device();
 	if (!input_dev) {
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c
index 803d3e4..c4d1b96 100644
--- a/drivers/media/video/usbvideo/quickcam_messenger.c
+++ b/drivers/media/video/usbvideo/quickcam_messenger.c
@@ -89,7 +89,7 @@
 	int error;
 
 	usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
-	strncat(cam->input_physname, "/input0", sizeof(cam->input_physname));
+	strlcat(cam->input_physname, "/input0", sizeof(cam->input_physname));
 
 	cam->input = input_dev = input_allocate_device();
 	if (!input_dev) {
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index a2a50d6..c07b0ac 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -601,7 +601,7 @@
 {
 	struct usb_usbvision *usbvision = video_drvdata(file);
 
-	if ((input >= usbvision->video_inputs) || (input < 0) )
+	if (input >= usbvision->video_inputs)
 		return -EINVAL;
 
 	mutex_lock(&usbvision->lock);
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 1b89735..0469d7a 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -742,17 +742,7 @@
 	v4l2_id &= V4L2_CTRL_ID_MASK;
 
 	/* Find the control. */
-	__uvc_find_control(chain->processing, v4l2_id, mapping, &ctrl, next);
-	if (ctrl && !next)
-		return ctrl;
-
-	list_for_each_entry(entity, &chain->iterms, chain) {
-		__uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
-		if (ctrl && !next)
-			return ctrl;
-	}
-
-	list_for_each_entry(entity, &chain->extensions, chain) {
+	list_for_each_entry(entity, &chain->entities, chain) {
 		__uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
 		if (ctrl && !next)
 			return ctrl;
@@ -826,6 +816,13 @@
 		ret = 0;
 		goto out;
 
+	case V4L2_CTRL_TYPE_BUTTON:
+		v4l2_ctrl->minimum = 0;
+		v4l2_ctrl->maximum = 0;
+		v4l2_ctrl->step = 0;
+		ret = 0;
+		goto out;
+
 	default:
 		break;
 	}
@@ -944,17 +941,7 @@
 	int ret = 0;
 
 	/* Find the control. */
-	ret = uvc_ctrl_commit_entity(chain->dev, chain->processing, rollback);
-	if (ret < 0)
-		goto done;
-
-	list_for_each_entry(entity, &chain->iterms, chain) {
-		ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
-		if (ret < 0)
-			goto done;
-	}
-
-	list_for_each_entry(entity, &chain->extensions, chain) {
+	list_for_each_entry(entity, &chain->entities, chain) {
 		ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
 		if (ret < 0)
 			goto done;
@@ -1068,8 +1055,9 @@
 	int ret;
 
 	/* Find the extension unit. */
-	list_for_each_entry(entity, &chain->extensions, chain) {
-		if (entity->id == xctrl->unit)
+	list_for_each_entry(entity, &chain->entities, chain) {
+		if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT &&
+		    entity->id == xctrl->unit)
 			break;
 	}
 
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 8756be5..c31bc50 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -46,6 +46,7 @@
 unsigned int uvc_no_drop_param;
 static unsigned int uvc_quirks_param;
 unsigned int uvc_trace_param;
+unsigned int uvc_timeout_param = UVC_CTRL_STREAMING_TIMEOUT;
 
 /* ------------------------------------------------------------------------
  * Video formats
@@ -248,29 +249,9 @@
 		entity = list_entry(&dev->entities, struct uvc_entity, list);
 
 	list_for_each_entry_continue(entity, &dev->entities, list) {
-		switch (UVC_ENTITY_TYPE(entity)) {
-		case UVC_TT_STREAMING:
-			if (entity->output.bSourceID == id)
+		for (i = 0; i < entity->bNrInPins; ++i)
+			if (entity->baSourceID[i] == id)
 				return entity;
-			break;
-
-		case UVC_VC_PROCESSING_UNIT:
-			if (entity->processing.bSourceID == id)
-				return entity;
-			break;
-
-		case UVC_VC_SELECTOR_UNIT:
-			for (i = 0; i < entity->selector.bNrInPins; ++i)
-				if (entity->selector.baSourceID[i] == id)
-					return entity;
-			break;
-
-		case UVC_VC_EXTENSION_UNIT:
-			for (i = 0; i < entity->extension.bNrInPins; ++i)
-				if (entity->extension.baSourceID[i] == id)
-					return entity;
-			break;
-		}
 	}
 
 	return NULL;
@@ -426,7 +407,8 @@
 	/* Parse the frame descriptors. Only uncompressed, MJPEG and frame
 	 * based formats have frame descriptors.
 	 */
-	while (buflen > 2 && buffer[2] == ftype) {
+	while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
+	       buffer[2] == ftype) {
 		frame = &format->frame[format->nframes];
 		if (ftype != UVC_VS_FRAME_FRAME_BASED)
 			n = buflen > 25 ? buffer[25] : 0;
@@ -503,12 +485,14 @@
 		buffer += buffer[0];
 	}
 
-	if (buflen > 2 && buffer[2] == UVC_VS_STILL_IMAGE_FRAME) {
+	if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
+	    buffer[2] == UVC_VS_STILL_IMAGE_FRAME) {
 		buflen -= buffer[0];
 		buffer += buffer[0];
 	}
 
-	if (buflen > 2 && buffer[2] == UVC_VS_COLORFORMAT) {
+	if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
+	    buffer[2] == UVC_VS_COLORFORMAT) {
 		if (buflen < 6) {
 			uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
 			       "interface %d COLORFORMAT error\n",
@@ -749,6 +733,11 @@
 		buffer += buffer[0];
 	}
 
+	if (buflen)
+		uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface "
+			"%d has %u bytes of trailing descriptor garbage.\n",
+			dev->udev->devnum, alts->desc.bInterfaceNumber, buflen);
+
 	/* Parse the alternate settings to find the maximum bandwidth. */
 	for (i = 0; i < intf->num_altsetting; ++i) {
 		struct usb_host_endpoint *ep;
@@ -776,6 +765,28 @@
 	return ret;
 }
 
+static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id,
+		unsigned int num_pads, unsigned int extra_size)
+{
+	struct uvc_entity *entity;
+	unsigned int num_inputs;
+	unsigned int size;
+
+	num_inputs = (type & UVC_TERM_OUTPUT) ? num_pads : num_pads - 1;
+	size = sizeof(*entity) + extra_size + num_inputs;
+	entity = kzalloc(size, GFP_KERNEL);
+	if (entity == NULL)
+		return NULL;
+
+	entity->id = id;
+	entity->type = type;
+
+	entity->bNrInPins = num_inputs;
+	entity->baSourceID = ((__u8 *)entity) + sizeof(*entity) + extra_size;
+
+	return entity;
+}
+
 /* Parse vendor-specific extensions. */
 static int uvc_parse_vendor_control(struct uvc_device *dev,
 	const unsigned char *buffer, int buflen)
@@ -827,21 +838,18 @@
 			break;
 		}
 
-		unit = kzalloc(sizeof *unit + p + 2*n, GFP_KERNEL);
+		unit = uvc_alloc_entity(UVC_VC_EXTENSION_UNIT, buffer[3],
+					p + 1, 2*n);
 		if (unit == NULL)
 			return -ENOMEM;
 
-		unit->id = buffer[3];
-		unit->type = UVC_VC_EXTENSION_UNIT;
 		memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
 		unit->extension.bNumControls = buffer[20];
-		unit->extension.bNrInPins = get_unaligned_le16(&buffer[21]);
-		unit->extension.baSourceID = (__u8 *)unit + sizeof *unit;
-		memcpy(unit->extension.baSourceID, &buffer[22], p);
+		memcpy(unit->baSourceID, &buffer[22], p);
 		unit->extension.bControlSize = buffer[22+p];
-		unit->extension.bmControls = (__u8 *)unit + sizeof *unit + p;
-		unit->extension.bmControlsType = (__u8 *)unit + sizeof *unit
-					       + p + n;
+		unit->extension.bmControls = (__u8 *)unit + sizeof(*unit);
+		unit->extension.bmControlsType = (__u8 *)unit + sizeof(*unit)
+					       + n;
 		memcpy(unit->extension.bmControls, &buffer[23+p], 2*n);
 
 		if (buffer[24+p+2*n] != 0)
@@ -938,13 +946,11 @@
 			return -EINVAL;
 		}
 
-		term = kzalloc(sizeof *term + n + p, GFP_KERNEL);
+		term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3],
+					1, n + p);
 		if (term == NULL)
 			return -ENOMEM;
 
-		term->id = buffer[3];
-		term->type = type | UVC_TERM_INPUT;
-
 		if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) {
 			term->camera.bControlSize = n;
 			term->camera.bmControls = (__u8 *)term + sizeof *term;
@@ -999,13 +1005,12 @@
 			return 0;
 		}
 
-		term = kzalloc(sizeof *term, GFP_KERNEL);
+		term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3],
+					1, 0);
 		if (term == NULL)
 			return -ENOMEM;
 
-		term->id = buffer[3];
-		term->type = type | UVC_TERM_OUTPUT;
-		term->output.bSourceID = buffer[7];
+		memcpy(term->baSourceID, &buffer[7], 1);
 
 		if (buffer[8] != 0)
 			usb_string(udev, buffer[8], term->name,
@@ -1026,15 +1031,11 @@
 			return -EINVAL;
 		}
 
-		unit = kzalloc(sizeof *unit + p, GFP_KERNEL);
+		unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0);
 		if (unit == NULL)
 			return -ENOMEM;
 
-		unit->id = buffer[3];
-		unit->type = buffer[2];
-		unit->selector.bNrInPins = buffer[4];
-		unit->selector.baSourceID = (__u8 *)unit + sizeof *unit;
-		memcpy(unit->selector.baSourceID, &buffer[5], p);
+		memcpy(unit->baSourceID, &buffer[5], p);
 
 		if (buffer[5+p] != 0)
 			usb_string(udev, buffer[5+p], unit->name,
@@ -1056,13 +1057,11 @@
 			return -EINVAL;
 		}
 
-		unit = kzalloc(sizeof *unit + n, GFP_KERNEL);
+		unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n);
 		if (unit == NULL)
 			return -ENOMEM;
 
-		unit->id = buffer[3];
-		unit->type = buffer[2];
-		unit->processing.bSourceID = buffer[4];
+		memcpy(unit->baSourceID, &buffer[4], 1);
 		unit->processing.wMaxMultiplier =
 			get_unaligned_le16(&buffer[5]);
 		unit->processing.bControlSize = buffer[7];
@@ -1091,19 +1090,15 @@
 			return -EINVAL;
 		}
 
-		unit = kzalloc(sizeof *unit + p + n, GFP_KERNEL);
+		unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n);
 		if (unit == NULL)
 			return -ENOMEM;
 
-		unit->id = buffer[3];
-		unit->type = buffer[2];
 		memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
 		unit->extension.bNumControls = buffer[20];
-		unit->extension.bNrInPins = get_unaligned_le16(&buffer[21]);
-		unit->extension.baSourceID = (__u8 *)unit + sizeof *unit;
-		memcpy(unit->extension.baSourceID, &buffer[22], p);
+		memcpy(unit->baSourceID, &buffer[22], p);
 		unit->extension.bControlSize = buffer[22+p];
-		unit->extension.bmControls = (__u8 *)unit + sizeof *unit + p;
+		unit->extension.bmControls = (__u8 *)unit + sizeof *unit;
 		memcpy(unit->extension.bmControls, &buffer[23+p], n);
 
 		if (buffer[23+p+n] != 0)
@@ -1209,13 +1204,12 @@
 		if (uvc_trace_param & UVC_TRACE_PROBE)
 			printk(" <- XU %d", entity->id);
 
-		if (entity->extension.bNrInPins != 1) {
+		if (entity->bNrInPins != 1) {
 			uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has more "
 				"than 1 input pin.\n", entity->id);
 			return -1;
 		}
 
-		list_add_tail(&entity->chain, &chain->extensions);
 		break;
 
 	case UVC_VC_PROCESSING_UNIT:
@@ -1236,7 +1230,7 @@
 			printk(" <- SU %d", entity->id);
 
 		/* Single-input selector units are ignored. */
-		if (entity->selector.bNrInPins == 1)
+		if (entity->bNrInPins == 1)
 			break;
 
 		if (chain->selector != NULL) {
@@ -1254,20 +1248,17 @@
 		if (uvc_trace_param & UVC_TRACE_PROBE)
 			printk(" <- IT %d\n", entity->id);
 
-		list_add_tail(&entity->chain, &chain->iterms);
 		break;
 
 	case UVC_TT_STREAMING:
-		if (uvc_trace_param & UVC_TRACE_PROBE)
-			printk(" <- IT %d\n", entity->id);
-
-		if (!UVC_ENTITY_IS_ITERM(entity)) {
-			uvc_trace(UVC_TRACE_DESCR, "Unsupported input "
-				"terminal %u.\n", entity->id);
-			return -1;
+		if (UVC_ENTITY_IS_ITERM(entity)) {
+			if (uvc_trace_param & UVC_TRACE_PROBE)
+				printk(" <- IT %d\n", entity->id);
+		} else {
+			if (uvc_trace_param & UVC_TRACE_PROBE)
+				printk(" OT %d", entity->id);
 		}
 
-		list_add_tail(&entity->chain, &chain->iterms);
 		break;
 
 	default:
@@ -1276,6 +1267,7 @@
 		return -1;
 	}
 
+	list_add_tail(&entity->chain, &chain->entities);
 	return 0;
 }
 
@@ -1299,14 +1291,14 @@
 
 		switch (UVC_ENTITY_TYPE(forward)) {
 		case UVC_VC_EXTENSION_UNIT:
-			if (forward->extension.bNrInPins != 1) {
+			if (forward->bNrInPins != 1) {
 				uvc_trace(UVC_TRACE_DESCR, "Extension unit %d "
 					  "has more than 1 input pin.\n",
 					  entity->id);
 				return -EINVAL;
 			}
 
-			list_add_tail(&forward->chain, &chain->extensions);
+			list_add_tail(&forward->chain, &chain->entities);
 			if (uvc_trace_param & UVC_TRACE_PROBE) {
 				if (!found)
 					printk(" (->");
@@ -1326,7 +1318,7 @@
 				return -EINVAL;
 			}
 
-			list_add_tail(&forward->chain, &chain->oterms);
+			list_add_tail(&forward->chain, &chain->entities);
 			if (uvc_trace_param & UVC_TRACE_PROBE) {
 				if (!found)
 					printk(" (->");
@@ -1344,24 +1336,22 @@
 }
 
 static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
-	struct uvc_entity *entity)
+	struct uvc_entity **_entity)
 {
+	struct uvc_entity *entity = *_entity;
 	struct uvc_entity *term;
-	int id = -1, i;
+	int id = -EINVAL, i;
 
 	switch (UVC_ENTITY_TYPE(entity)) {
 	case UVC_VC_EXTENSION_UNIT:
-		id = entity->extension.baSourceID[0];
-		break;
-
 	case UVC_VC_PROCESSING_UNIT:
-		id = entity->processing.bSourceID;
+		id = entity->baSourceID[0];
 		break;
 
 	case UVC_VC_SELECTOR_UNIT:
 		/* Single-input selector units are ignored. */
-		if (entity->selector.bNrInPins == 1) {
-			id = entity->selector.baSourceID[0];
+		if (entity->bNrInPins == 1) {
+			id = entity->baSourceID[0];
 			break;
 		}
 
@@ -1369,8 +1359,8 @@
 			printk(" <- IT");
 
 		chain->selector = entity;
-		for (i = 0; i < entity->selector.bNrInPins; ++i) {
-			id = entity->selector.baSourceID[i];
+		for (i = 0; i < entity->bNrInPins; ++i) {
+			id = entity->baSourceID[i];
 			term = uvc_entity_by_id(chain->dev, id);
 			if (term == NULL || !UVC_ENTITY_IS_ITERM(term)) {
 				uvc_trace(UVC_TRACE_DESCR, "Selector unit %d "
@@ -1382,7 +1372,7 @@
 			if (uvc_trace_param & UVC_TRACE_PROBE)
 				printk(" %d", term->id);
 
-			list_add_tail(&term->chain, &chain->iterms);
+			list_add_tail(&term->chain, &chain->entities);
 			uvc_scan_chain_forward(chain, term, entity);
 		}
 
@@ -1391,34 +1381,49 @@
 
 		id = 0;
 		break;
+
+	case UVC_ITT_VENDOR_SPECIFIC:
+	case UVC_ITT_CAMERA:
+	case UVC_ITT_MEDIA_TRANSPORT_INPUT:
+	case UVC_OTT_VENDOR_SPECIFIC:
+	case UVC_OTT_DISPLAY:
+	case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
+	case UVC_TT_STREAMING:
+		id = UVC_ENTITY_IS_OTERM(entity) ? entity->baSourceID[0] : 0;
+		break;
 	}
 
-	return id;
+	if (id <= 0) {
+		*_entity = NULL;
+		return id;
+	}
+
+	entity = uvc_entity_by_id(chain->dev, id);
+	if (entity == NULL) {
+		uvc_trace(UVC_TRACE_DESCR, "Found reference to "
+			"unknown entity %d.\n", id);
+		return -EINVAL;
+	}
+
+	*_entity = entity;
+	return 0;
 }
 
 static int uvc_scan_chain(struct uvc_video_chain *chain,
-			  struct uvc_entity *oterm)
+			  struct uvc_entity *term)
 {
 	struct uvc_entity *entity, *prev;
-	int id;
 
-	entity = oterm;
-	list_add_tail(&entity->chain, &chain->oterms);
-	uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain: OT %d", entity->id);
+	uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain:");
 
-	id = entity->output.bSourceID;
-	while (id != 0) {
-		prev = entity;
-		entity = uvc_entity_by_id(chain->dev, id);
-		if (entity == NULL) {
-			uvc_trace(UVC_TRACE_DESCR, "Found reference to "
-				"unknown entity %d.\n", id);
-			return -EINVAL;
-		}
+	entity = term;
+	prev = NULL;
 
+	while (entity != NULL) {
+		/* Entity must not be part of an existing chain */
 		if (entity->chain.next || entity->chain.prev) {
 			uvc_trace(UVC_TRACE_DESCR, "Found reference to "
-				"entity %d already in chain.\n", id);
+				"entity %d already in chain.\n", entity->id);
 			return -EINVAL;
 		}
 
@@ -1430,34 +1435,34 @@
 		if (uvc_scan_chain_forward(chain, entity, prev) < 0)
 			return -EINVAL;
 
-		/* Stop when a terminal is found. */
-		if (UVC_ENTITY_IS_TERM(entity))
-			break;
-
 		/* Backward scan */
-		id = uvc_scan_chain_backward(chain, entity);
-		if (id < 0)
-			return id;
+		prev = entity;
+		if (uvc_scan_chain_backward(chain, &entity) < 0)
+			return -EINVAL;
 	}
 
 	return 0;
 }
 
-static unsigned int uvc_print_terms(struct list_head *terms, char *buffer)
+static unsigned int uvc_print_terms(struct list_head *terms, u16 dir,
+		char *buffer)
 {
 	struct uvc_entity *term;
 	unsigned int nterms = 0;
 	char *p = buffer;
 
 	list_for_each_entry(term, terms, chain) {
-		p += sprintf(p, "%u", term->id);
-		if (term->chain.next != terms) {
+		if (!UVC_ENTITY_IS_TERM(term) ||
+		    UVC_TERM_DIRECTION(term) != dir)
+			continue;
+
+		if (nterms)
 			p += sprintf(p, ",");
-			if (++nterms >= 4) {
-				p += sprintf(p, "...");
-				break;
-			}
+		if (++nterms >= 4) {
+			p += sprintf(p, "...");
+			break;
 		}
+		p += sprintf(p, "%u", term->id);
 	}
 
 	return p - buffer;
@@ -1468,9 +1473,9 @@
 	static char buffer[43];
 	char *p = buffer;
 
-	p += uvc_print_terms(&chain->iterms, p);
+	p += uvc_print_terms(&chain->entities, UVC_TERM_INPUT, p);
 	p += sprintf(p, " -> ");
-	uvc_print_terms(&chain->oterms, p);
+	uvc_print_terms(&chain->entities, UVC_TERM_OUTPUT, p);
 
 	return buffer;
 }
@@ -1501,9 +1506,7 @@
 		if (chain == NULL)
 			return -ENOMEM;
 
-		INIT_LIST_HEAD(&chain->iterms);
-		INIT_LIST_HEAD(&chain->oterms);
-		INIT_LIST_HEAD(&chain->extensions);
+		INIT_LIST_HEAD(&chain->entities);
 		mutex_init(&chain->ctrl_mutex);
 		chain->dev = dev;
 
@@ -1531,22 +1534,92 @@
  */
 
 /*
+ * Delete the UVC device.
+ *
+ * Called by the kernel when the last reference to the uvc_device structure
+ * is released.
+ *
+ * As this function is called after or during disconnect(), all URBs have
+ * already been canceled by the USB core. There is no need to kill the
+ * interrupt URB manually.
+ */
+static void uvc_delete(struct uvc_device *dev)
+{
+	struct list_head *p, *n;
+
+	usb_put_intf(dev->intf);
+	usb_put_dev(dev->udev);
+
+	uvc_status_cleanup(dev);
+	uvc_ctrl_cleanup_device(dev);
+
+	list_for_each_safe(p, n, &dev->chains) {
+		struct uvc_video_chain *chain;
+		chain = list_entry(p, struct uvc_video_chain, list);
+		kfree(chain);
+	}
+
+	list_for_each_safe(p, n, &dev->entities) {
+		struct uvc_entity *entity;
+		entity = list_entry(p, struct uvc_entity, list);
+		kfree(entity);
+	}
+
+	list_for_each_safe(p, n, &dev->streams) {
+		struct uvc_streaming *streaming;
+		streaming = list_entry(p, struct uvc_streaming, list);
+		usb_driver_release_interface(&uvc_driver.driver,
+			streaming->intf);
+		usb_put_intf(streaming->intf);
+		kfree(streaming->format);
+		kfree(streaming->header.bmaControls);
+		kfree(streaming);
+	}
+
+	kfree(dev);
+}
+
+static void uvc_release(struct video_device *vdev)
+{
+	struct uvc_streaming *stream = video_get_drvdata(vdev);
+	struct uvc_device *dev = stream->dev;
+
+	video_device_release(vdev);
+
+	/* Decrement the registered streams count and delete the device when it
+	 * reaches zero.
+	 */
+	if (atomic_dec_and_test(&dev->nstreams))
+		uvc_delete(dev);
+}
+
+/*
  * Unregister the video devices.
  */
 static void uvc_unregister_video(struct uvc_device *dev)
 {
 	struct uvc_streaming *stream;
 
+	/* Unregistering all video devices might result in uvc_delete() being
+	 * called from inside the loop if there's no open file handle. To avoid
+	 * that, increment the stream count before iterating over the streams
+	 * and decrement it when done.
+	 */
+	atomic_inc(&dev->nstreams);
+
 	list_for_each_entry(stream, &dev->streams, list) {
 		if (stream->vdev == NULL)
 			continue;
 
-		if (stream->vdev->minor == -1)
-			video_device_release(stream->vdev);
-		else
-			video_unregister_device(stream->vdev);
+		video_unregister_device(stream->vdev);
 		stream->vdev = NULL;
 	}
+
+	/* Decrement the stream count and call uvc_delete explicitly if there
+	 * are no stream left.
+	 */
+	if (atomic_dec_and_test(&dev->nstreams))
+		uvc_delete(dev);
 }
 
 static int uvc_register_video(struct uvc_device *dev,
@@ -1580,7 +1653,7 @@
 	vdev->parent = &dev->intf->dev;
 	vdev->minor = -1;
 	vdev->fops = &uvc_fops;
-	vdev->release = video_device_release;
+	vdev->release = uvc_release;
 	strlcpy(vdev->name, dev->name, sizeof vdev->name);
 
 	/* Set the driver data before calling video_register_device, otherwise
@@ -1598,6 +1671,7 @@
 		return ret;
 	}
 
+	atomic_inc(&dev->nstreams);
 	return 0;
 }
 
@@ -1605,13 +1679,13 @@
  * Register all video devices in all chains.
  */
 static int uvc_register_terms(struct uvc_device *dev,
-	struct uvc_video_chain *chain, struct list_head *terms)
+	struct uvc_video_chain *chain)
 {
 	struct uvc_streaming *stream;
 	struct uvc_entity *term;
 	int ret;
 
-	list_for_each_entry(term, terms, chain) {
+	list_for_each_entry(term, &chain->entities, chain) {
 		if (UVC_ENTITY_TYPE(term) != UVC_TT_STREAMING)
 			continue;
 
@@ -1637,11 +1711,7 @@
 	int ret;
 
 	list_for_each_entry(chain, &dev->chains, list) {
-		ret = uvc_register_terms(dev, chain, &chain->iterms);
-		if (ret < 0)
-			return ret;
-
-		ret = uvc_register_terms(dev, chain, &chain->oterms);
+		ret = uvc_register_terms(dev, chain);
 		if (ret < 0)
 			return ret;
 	}
@@ -1653,61 +1723,6 @@
  * USB probe, disconnect, suspend and resume
  */
 
-/*
- * Delete the UVC device.
- *
- * Called by the kernel when the last reference to the uvc_device structure
- * is released.
- *
- * Unregistering the video devices is done here because every opened instance
- * must be closed before the device can be unregistered. An alternative would
- * have been to use another reference count for uvc_v4l2_open/uvc_release, and
- * unregister the video devices on disconnect when that reference count drops
- * to zero.
- *
- * As this function is called after or during disconnect(), all URBs have
- * already been canceled by the USB core. There is no need to kill the
- * interrupt URB manually.
- */
-void uvc_delete(struct kref *kref)
-{
-	struct uvc_device *dev = container_of(kref, struct uvc_device, kref);
-	struct list_head *p, *n;
-
-	/* Unregister the video devices. */
-	uvc_unregister_video(dev);
-	usb_put_intf(dev->intf);
-	usb_put_dev(dev->udev);
-
-	uvc_status_cleanup(dev);
-	uvc_ctrl_cleanup_device(dev);
-
-	list_for_each_safe(p, n, &dev->chains) {
-		struct uvc_video_chain *chain;
-		chain = list_entry(p, struct uvc_video_chain, list);
-		kfree(chain);
-	}
-
-	list_for_each_safe(p, n, &dev->entities) {
-		struct uvc_entity *entity;
-		entity = list_entry(p, struct uvc_entity, list);
-		kfree(entity);
-	}
-
-	list_for_each_safe(p, n, &dev->streams) {
-		struct uvc_streaming *streaming;
-		streaming = list_entry(p, struct uvc_streaming, list);
-		usb_driver_release_interface(&uvc_driver.driver,
-			streaming->intf);
-		usb_put_intf(streaming->intf);
-		kfree(streaming->format);
-		kfree(streaming->header.bmaControls);
-		kfree(streaming);
-	}
-
-	kfree(dev);
-}
-
 static int uvc_probe(struct usb_interface *intf,
 		     const struct usb_device_id *id)
 {
@@ -1730,7 +1745,7 @@
 	INIT_LIST_HEAD(&dev->entities);
 	INIT_LIST_HEAD(&dev->chains);
 	INIT_LIST_HEAD(&dev->streams);
-	kref_init(&dev->kref);
+	atomic_set(&dev->nstreams, 0);
 	atomic_set(&dev->users, 0);
 
 	dev->udev = usb_get_dev(udev);
@@ -1792,7 +1807,7 @@
 	return 0;
 
 error:
-	kref_put(&dev->kref, uvc_delete);
+	uvc_unregister_video(dev);
 	return -ENODEV;
 }
 
@@ -1809,21 +1824,9 @@
 	    UVC_SC_VIDEOSTREAMING)
 		return;
 
-	/* uvc_v4l2_open() might race uvc_disconnect(). A static driver-wide
-	 * lock is needed to prevent uvc_disconnect from releasing its
-	 * reference to the uvc_device instance after uvc_v4l2_open() received
-	 * the pointer to the device (video_devdata) but before it got the
-	 * chance to increase the reference count (kref_get).
-	 *
-	 * Note that the reference can't be released with the lock held,
-	 * otherwise a AB-BA deadlock can occur with videodev_lock that
-	 * videodev acquires in videodev_open() and video_unregister_device().
-	 */
-	mutex_lock(&uvc_driver.open_mutex);
 	dev->state |= UVC_DEV_DISCONNECTED;
-	mutex_unlock(&uvc_driver.open_mutex);
 
-	kref_put(&dev->kref, uvc_delete);
+	uvc_unregister_video(dev);
 }
 
 static int uvc_suspend(struct usb_interface *intf, pm_message_t message)
@@ -1899,6 +1902,15 @@
  * though they are compliant.
  */
 static struct usb_device_id uvc_ids[] = {
+	/* Genius eFace 2025 */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x0458,
+	  .idProduct		= 0x706e,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
 	/* Microsoft Lifecam NX-6000 */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2123,6 +2135,15 @@
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
 	  .driver_info		= UVC_QUIRK_STATUS_INTERVAL },
+	/* MSI StarCam 370i */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x1b3b,
+	  .idProduct		= 0x2951,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
 	/* SiGma Micro USB Web Camera */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2159,7 +2180,6 @@
 
 	INIT_LIST_HEAD(&uvc_driver.devices);
 	INIT_LIST_HEAD(&uvc_driver.controls);
-	mutex_init(&uvc_driver.open_mutex);
 	mutex_init(&uvc_driver.ctrl_mutex);
 
 	uvc_ctrl_init();
@@ -2184,6 +2204,8 @@
 MODULE_PARM_DESC(quirks, "Forced device quirks");
 module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(trace, "Trace level bitmask");
+module_param_named(timeout, uvc_timeout_param, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(timeout, "Streaming control requests timeout");
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index a2bdd80..23239a4 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -364,37 +364,30 @@
  * unprivileged state. Only a single instance can be in a privileged state at
  * a given time. Trying to perform an operation that requires privileges will
  * automatically acquire the required privileges if possible, or return -EBUSY
- * otherwise. Privileges are dismissed when closing the instance.
+ * otherwise. Privileges are dismissed when closing the instance or when
+ * freeing the video buffers using VIDIOC_REQBUFS.
  *
  * Operations that require privileges are:
  *
  * - VIDIOC_S_INPUT
  * - VIDIOC_S_PARM
  * - VIDIOC_S_FMT
- * - VIDIOC_TRY_FMT
  * - VIDIOC_REQBUFS
  */
 static int uvc_acquire_privileges(struct uvc_fh *handle)
 {
-	int ret = 0;
-
 	/* Always succeed if the handle is already privileged. */
 	if (handle->state == UVC_HANDLE_ACTIVE)
 		return 0;
 
 	/* Check if the device already has a privileged handle. */
-	mutex_lock(&uvc_driver.open_mutex);
 	if (atomic_inc_return(&handle->stream->active) != 1) {
 		atomic_dec(&handle->stream->active);
-		ret = -EBUSY;
-		goto done;
+		return -EBUSY;
 	}
 
 	handle->state = UVC_HANDLE_ACTIVE;
-
-done:
-	mutex_unlock(&uvc_driver.open_mutex);
-	return ret;
+	return 0;
 }
 
 static void uvc_dismiss_privileges(struct uvc_fh *handle)
@@ -421,24 +414,20 @@
 	int ret = 0;
 
 	uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n");
-	mutex_lock(&uvc_driver.open_mutex);
 	stream = video_drvdata(file);
 
-	if (stream->dev->state & UVC_DEV_DISCONNECTED) {
-		ret = -ENODEV;
-		goto done;
-	}
+	if (stream->dev->state & UVC_DEV_DISCONNECTED)
+		return -ENODEV;
 
 	ret = usb_autopm_get_interface(stream->dev->intf);
 	if (ret < 0)
-		goto done;
+		return ret;
 
 	/* Create the device handle. */
 	handle = kzalloc(sizeof *handle, GFP_KERNEL);
 	if (handle == NULL) {
 		usb_autopm_put_interface(stream->dev->intf);
-		ret = -ENOMEM;
-		goto done;
+		return -ENOMEM;
 	}
 
 	if (atomic_inc_return(&stream->dev->users) == 1) {
@@ -447,7 +436,7 @@
 			usb_autopm_put_interface(stream->dev->intf);
 			atomic_dec(&stream->dev->users);
 			kfree(handle);
-			goto done;
+			return ret;
 		}
 	}
 
@@ -456,11 +445,7 @@
 	handle->state = UVC_HANDLE_PASSIVE;
 	file->private_data = handle;
 
-	kref_get(&stream->dev->kref);
-
-done:
-	mutex_unlock(&uvc_driver.open_mutex);
-	return ret;
+	return 0;
 }
 
 static int uvc_v4l2_release(struct file *file)
@@ -490,7 +475,6 @@
 		uvc_status_stop(stream->dev);
 
 	usb_autopm_put_interface(stream->dev->intf);
-	kref_put(&stream->dev->kref, uvc_delete);
 	return 0;
 }
 
@@ -636,12 +620,16 @@
 		    (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
 			if (index != 0)
 				return -EINVAL;
-			iterm = list_first_entry(&chain->iterms,
-					struct uvc_entity, chain);
+			list_for_each_entry(iterm, &chain->entities, chain) {
+				if (UVC_ENTITY_IS_ITERM(iterm))
+					break;
+			}
 			pin = iterm->id;
-		} else if (pin < selector->selector.bNrInPins) {
-			pin = selector->selector.baSourceID[index];
-			list_for_each_entry(iterm, chain->iterms.next, chain) {
+		} else if (pin < selector->bNrInPins) {
+			pin = selector->baSourceID[index];
+			list_for_each_entry(iterm, &chain->entities, chain) {
+				if (!UVC_ENTITY_IS_ITERM(iterm))
+					continue;
 				if (iterm->id == pin)
 					break;
 			}
@@ -692,7 +680,7 @@
 			break;
 		}
 
-		if (input == 0 || input > chain->selector->selector.bNrInPins)
+		if (input == 0 || input > chain->selector->bNrInPins)
 			return -EINVAL;
 
 		return uvc_query_ctrl(chain->dev, UVC_SET_CUR,
@@ -731,9 +719,6 @@
 	{
 		struct uvc_streaming_control probe;
 
-		if ((ret = uvc_acquire_privileges(handle)) < 0)
-			return ret;
-
 		return uvc_v4l2_try_format(stream, arg, &probe, NULL, NULL);
 	}
 
@@ -888,6 +873,9 @@
 		if (ret < 0)
 			return ret;
 
+		if (ret == 0)
+			uvc_dismiss_privileges(handle);
+
 		rb->count = ret;
 		ret = 0;
 		break;
@@ -1051,7 +1039,7 @@
 		    size_t count, loff_t *ppos)
 {
 	uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_read: not implemented.\n");
-	return -ENODEV;
+	return -EINVAL;
 }
 
 /*
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index a6e41d1..05139a4 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -135,7 +135,7 @@
 
 	ret = __uvc_query_ctrl(stream->dev, query, 0, stream->intfnum,
 		probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data,
-		size, UVC_CTRL_STREAMING_TIMEOUT);
+		size, uvc_timeout_param);
 
 	if ((query == UVC_GET_MIN || query == UVC_GET_MAX) && ret == 2) {
 		/* Some cameras, mostly based on Bison Electronics chipsets,
@@ -239,7 +239,7 @@
 
 	ret = __uvc_query_ctrl(stream->dev, UVC_SET_CUR, 0, stream->intfnum,
 		probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data,
-		size, UVC_CTRL_STREAMING_TIMEOUT);
+		size, uvc_timeout_param);
 	if (ret != size) {
 		uvc_printk(KERN_ERR, "Failed to set UVC %s control : "
 			"%d (exp. %u).\n", probe ? "probe" : "commit",
@@ -770,8 +770,9 @@
 	/* Retry allocations until one succeed. */
 	for (; npackets > 1; npackets /= 2) {
 		for (i = 0; i < UVC_URBS; ++i) {
+			stream->urb_size = psize * npackets;
 			stream->urb_buffer[i] = usb_buffer_alloc(
-				stream->dev->udev, psize * npackets,
+				stream->dev->udev, stream->urb_size,
 				gfp_flags | __GFP_NOWARN, &stream->urb_dma[i]);
 			if (!stream->urb_buffer[i]) {
 				uvc_free_urb_buffers(stream);
@@ -780,11 +781,15 @@
 		}
 
 		if (i == UVC_URBS) {
-			stream->urb_size = psize * npackets;
+			uvc_trace(UVC_TRACE_VIDEO, "Allocated %u URB buffers "
+				"of %ux%u bytes each.\n", UVC_URBS, npackets,
+				psize);
 			return npackets;
 		}
 	}
 
+	uvc_trace(UVC_TRACE_VIDEO, "Failed to allocate URB buffers (%u bytes "
+		"per packet).\n", psize);
 	return 0;
 }
 
@@ -935,10 +940,12 @@
 		bandwidth = stream->ctrl.dwMaxPayloadTransferSize;
 
 		if (bandwidth == 0) {
-			uvc_printk(KERN_WARNING, "device %s requested null "
-				"bandwidth, defaulting to lowest.\n",
-				stream->dev->name);
+			uvc_trace(UVC_TRACE_VIDEO, "Device requested null "
+				"bandwidth, defaulting to lowest.\n");
 			bandwidth = 1;
+		} else {
+			uvc_trace(UVC_TRACE_VIDEO, "Device requested %u "
+				"B/frame bandwidth.\n", bandwidth);
 		}
 
 		for (i = 0; i < intf->num_altsetting; ++i) {
@@ -955,8 +962,11 @@
 				break;
 		}
 
-		if (i >= intf->num_altsetting)
+		if (i >= intf->num_altsetting) {
+			uvc_trace(UVC_TRACE_VIDEO, "No fast enough alt setting "
+				"for requested bandwidth.\n");
 			return -EIO;
+		}
 
 		ret = usb_set_interface(stream->dev->udev, intfnum, i);
 		if (ret < 0)
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index e7958aa..7ec9a04 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -75,6 +75,7 @@
 
 #define UVC_TERM_INPUT			0x0000
 #define UVC_TERM_OUTPUT			0x8000
+#define UVC_TERM_DIRECTION(term)	((term)->type & 0x8000)
 
 #define UVC_ENTITY_TYPE(entity)		((entity)->type & 0x7fff)
 #define UVC_ENTITY_IS_UNIT(entity)	(((entity)->type & 0xff00) == 0)
@@ -148,7 +149,7 @@
 #define UVC_MAX_STATUS_SIZE	16
 
 #define UVC_CTRL_CONTROL_TIMEOUT	300
-#define UVC_CTRL_STREAMING_TIMEOUT	1000
+#define UVC_CTRL_STREAMING_TIMEOUT	3000
 
 /* Devices quirks */
 #define UVC_QUIRK_STATUS_INTERVAL	0x00000001
@@ -292,11 +293,9 @@
 		} media;
 
 		struct {
-			__u8  bSourceID;
 		} output;
 
 		struct {
-			__u8  bSourceID;
 			__u16 wMaxMultiplier;
 			__u8  bControlSize;
 			__u8  *bmControls;
@@ -304,21 +303,20 @@
 		} processing;
 
 		struct {
-			__u8  bNrInPins;
-			__u8  *baSourceID;
 		} selector;
 
 		struct {
 			__u8  guidExtensionCode[16];
 			__u8  bNumControls;
-			__u8  bNrInPins;
-			__u8  *baSourceID;
 			__u8  bControlSize;
 			__u8  *bmControls;
 			__u8  *bmControlsType;
 		} extension;
 	};
 
+	__u8 bNrInPins;
+	__u8 *baSourceID;
+
 	unsigned int ncontrols;
 	struct uvc_control *controls;
 };
@@ -408,11 +406,9 @@
 	struct uvc_device *dev;
 	struct list_head list;
 
-	struct list_head iterms;		/* Input terminals */
-	struct list_head oterms;		/* Output terminals */
+	struct list_head entities;		/* All entities */
 	struct uvc_entity *processing;		/* Processing unit */
 	struct uvc_entity *selector;		/* Selector unit */
-	struct list_head extensions;		/* Extension units */
 
 	struct mutex ctrl_mutex;
 };
@@ -475,7 +471,6 @@
 	char name[32];
 
 	enum uvc_device_state state;
-	struct kref kref;
 	struct list_head list;
 	atomic_t users;
 
@@ -488,6 +483,7 @@
 
 	/* Video Streaming interfaces */
 	struct list_head streams;
+	atomic_t nstreams;
 
 	/* Status Interrupt Endpoint */
 	struct usb_host_endpoint *int_ep;
@@ -511,8 +507,6 @@
 struct uvc_driver {
 	struct usb_driver driver;
 
-	struct mutex open_mutex;	/* protects from open/disconnect race */
-
 	struct list_head devices;	/* struct uvc_device list */
 	struct list_head controls;	/* struct uvc_control_info list */
 	struct mutex ctrl_mutex;	/* protects controls and devices
@@ -533,12 +527,14 @@
 #define UVC_TRACE_FRAME		(1 << 7)
 #define UVC_TRACE_SUSPEND	(1 << 8)
 #define UVC_TRACE_STATUS	(1 << 9)
+#define UVC_TRACE_VIDEO		(1 << 10)
 
 #define UVC_WARN_MINMAX		0
 #define UVC_WARN_PROBE_DEF	1
 
 extern unsigned int uvc_no_drop_param;
 extern unsigned int uvc_trace_param;
+extern unsigned int uvc_timeout_param;
 
 #define uvc_trace(flag, msg...) \
 	do { \
@@ -571,7 +567,6 @@
 
 /* Core driver */
 extern struct uvc_driver uvc_driver;
-extern void uvc_delete(struct kref *kref);
 
 /* Video buffers queue management. */
 extern void uvc_queue_init(struct uvc_video_queue *queue,
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index f5a93ae..e8e5aff 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -431,6 +431,8 @@
 	case V4L2_CID_CHROMA_AGC:		return "Chroma AGC";
 	case V4L2_CID_COLOR_KILLER:		return "Color Killer";
 	case V4L2_CID_COLORFX:			return "Color Effects";
+	case V4L2_CID_ROTATE:			return "Rotate";
+	case V4L2_CID_BG_COLOR:			return "Background color";
 
 	/* MPEG controls */
 	case V4L2_CID_MPEG_CLASS: 		return "MPEG Encoder Controls";
@@ -587,6 +589,13 @@
 		qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 		min = max = step = def = 0;
 		break;
+	case V4L2_CID_BG_COLOR:
+		qctrl->type = V4L2_CTRL_TYPE_INTEGER;
+		step = 1;
+		min = 0;
+		/* Max is calculated as RGB888 that is 2^24 */
+		max = 0xFFFFFF;
+		break;
 	default:
 		qctrl->type = V4L2_CTRL_TYPE_INTEGER;
 		break;
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
index 8e93c6f..bb0a1c8 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/video/videobuf-core.c
@@ -110,7 +110,7 @@
 
 
 void videobuf_queue_core_init(struct videobuf_queue *q,
-			 struct videobuf_queue_ops *ops,
+			 const struct videobuf_queue_ops *ops,
 			 struct device *dev,
 			 spinlock_t *irqlock,
 			 enum v4l2_buf_type type,
@@ -360,7 +360,7 @@
 		q->bufs[i]->bsize  = bsize;
 		switch (memory) {
 		case V4L2_MEMORY_MMAP:
-			q->bufs[i]->boff  = bsize * i;
+			q->bufs[i]->boff = PAGE_ALIGN(bsize) * i;
 			break;
 		case V4L2_MEMORY_USERPTR:
 		case V4L2_MEMORY_OVERLAY:
@@ -430,9 +430,9 @@
 		count = VIDEO_MAX_FRAME;
 	size = 0;
 	q->ops->buf_setup(q, &count, &size);
-	size = PAGE_ALIGN(size);
-	dprintk(1, "reqbufs: bufs=%d, size=0x%x [%d pages total]\n",
-		count, size, (count*size)>>PAGE_SHIFT);
+	dprintk(1, "reqbufs: bufs=%d, size=0x%x [%u pages total]\n",
+		count, size,
+		(unsigned int)((count*PAGE_ALIGN(size))>>PAGE_SHIFT) );
 
 	retval = __videobuf_mmap_setup(q, count, size, req->memory);
 	if (retval < 0) {
@@ -1099,7 +1099,7 @@
 	mbuf->size   = 0;
 	for (i = 0; i < mbuf->frames; i++) {
 		mbuf->offsets[i]  = q->bufs[i]->boff;
-		mbuf->size       += q->bufs[i]->bsize;
+		mbuf->size       += PAGE_ALIGN(q->bufs[i]->bsize);
 	}
 
 	return 0;
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c
index c3065c4..d25f284 100644
--- a/drivers/media/video/videobuf-dma-contig.c
+++ b/drivers/media/video/videobuf-dma-contig.c
@@ -429,7 +429,7 @@
 };
 
 void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
-				    struct videobuf_queue_ops *ops,
+				    const struct videobuf_queue_ops *ops,
 				    struct device *dev,
 				    spinlock_t *irqlock,
 				    enum v4l2_buf_type type,
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index 032ebae..fa78555 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -588,7 +588,7 @@
 			retval = -EBUSY;
 			goto done;
 		}
-		size += q->bufs[last]->bsize;
+		size += PAGE_ALIGN(q->bufs[last]->bsize);
 		if (size == (vma->vm_end - vma->vm_start))
 			break;
 	}
@@ -610,7 +610,7 @@
 			continue;
 		q->bufs[i]->map   = map;
 		q->bufs[i]->baddr = vma->vm_start + size;
-		size += q->bufs[i]->bsize;
+		size += PAGE_ALIGN(q->bufs[i]->bsize);
 	}
 
 	map->count    = 1;
@@ -702,7 +702,7 @@
 }
 
 void videobuf_queue_sg_init(struct videobuf_queue* q,
-			 struct videobuf_queue_ops *ops,
+			 const struct videobuf_queue_ops *ops,
 			 struct device *dev,
 			 spinlock_t *irqlock,
 			 enum v4l2_buf_type type,
diff --git a/drivers/media/video/videobuf-dvb.c b/drivers/media/video/videobuf-dvb.c
index 0e7dcba..a56cf0d 100644
--- a/drivers/media/video/videobuf-dvb.c
+++ b/drivers/media/video/videobuf-dvb.c
@@ -139,7 +139,9 @@
 			  struct device *device,
 			  char *adapter_name,
 			  short *adapter_nr,
-			  int mfe_shared)
+			  int mfe_shared,
+			  int (*fe_ioctl_override)(struct dvb_frontend *,
+					unsigned int, void *, unsigned int))
 {
 	int result;
 
@@ -154,6 +156,7 @@
 	}
 	fe->adapter.priv = adapter_priv;
 	fe->adapter.mfe_shared = mfe_shared;
+	fe->adapter.fe_ioctl_override = fe_ioctl_override;
 
 	return result;
 }
@@ -253,7 +256,9 @@
 			  void *adapter_priv,
 			  struct device *device,
 			  short *adapter_nr,
-			  int mfe_shared)
+			  int mfe_shared,
+			  int (*fe_ioctl_override)(struct dvb_frontend *,
+					unsigned int, void *, unsigned int))
 {
 	struct list_head *list, *q;
 	struct videobuf_dvb_frontend *fe;
@@ -267,7 +272,7 @@
 
 	/* Bring up the adapter */
 	res = videobuf_dvb_register_adapter(f, module, adapter_priv, device,
-		fe->dvb.name, adapter_nr, mfe_shared);
+		fe->dvb.name, adapter_nr, mfe_shared, fe_ioctl_override);
 	if (res < 0) {
 		printk(KERN_WARNING "videobuf_dvb_register_adapter failed (errno = %d)\n", res);
 		return res;
diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c
index 35f3900..d6e6a28 100644
--- a/drivers/media/video/videobuf-vmalloc.c
+++ b/drivers/media/video/videobuf-vmalloc.c
@@ -391,8 +391,8 @@
 };
 
 void videobuf_queue_vmalloc_init(struct videobuf_queue* q,
-			 struct videobuf_queue_ops *ops,
-			 void *dev,
+			 const struct videobuf_queue_ops *ops,
+			 struct device *dev,
 			 spinlock_t *irqlock,
 			 enum v4l2_buf_type type,
 			 enum v4l2_field field,
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c
index 97e0ce2..33205d7 100644
--- a/drivers/media/video/vpx3220.c
+++ b/drivers/media/video/vpx3220.c
@@ -391,7 +391,7 @@
 		{0x0e, 1}
 	};
 
-	if (input < 0 || input > 2)
+	if (input > 2)
 		return -EINVAL;
 
 	v4l2_dbg(1, debug, sd, "input switched to %s\n", inputs[input]);
diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h
index d439c76..cb1de7e 100644
--- a/drivers/media/video/zoran/zoran.h
+++ b/drivers/media/video/zoran/zoran.h
@@ -106,7 +106,7 @@
 	unsigned long jpeg_markers;	/* Which markers should go into the JPEG output.
 					 * Unless you exactly know what you do, leave them untouched.
 					 * Inluding less markers will make the resulting code
-					 * smaller, but there will be fewer aplications
+					 * smaller, but there will be fewer applications
 					 * which can read it.
 					 * The presence of the APP and COM marker is
 					 * influenced by APP0_len and COM_len ONLY! */
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
index 47137de..e9f72ca 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/video/zoran/zoran_driver.c
@@ -2764,7 +2764,7 @@
 	struct zoran_fh *fh = __fh;
 	struct zoran *zr = fh->zr;
 
-	if (inp->index < 0 || inp->index >= zr->card.inputs)
+	if (inp->index >= zr->card.inputs)
 		return -EINVAL;
 	else {
 		int id = inp->index;
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
index 9aae011..2ef110b 100644
--- a/drivers/media/video/zr364xx.c
+++ b/drivers/media/video/zr364xx.c
@@ -115,6 +115,7 @@
 	{USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 },
 	{USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 },
 	{USB_DEVICE(0x08ca, 0x2102), .driver_info = METHOD2 },
+	{USB_DEVICE(0x06d6, 0x003d), .driver_info = METHOD0 },
 	{}			/* Terminating entry */
 };
 
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 8dd4d21..b494867 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -76,8 +76,8 @@
 #define COPYRIGHT	"Copyright (c) 1999-2008 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON	"3.04.12"
-#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.04.12"
+#define MPT_LINUX_VERSION_COMMON	"3.04.13"
+#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.04.13"
 #define WHAT_MAGIC_STRING		"@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index 9b2e219..352acd0 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -621,11 +621,8 @@
 	 */
 	iocnumX = khdr.iocnum & 0xFF;
 	if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
-	    (iocp == NULL)) {
-		printk(KERN_DEBUG MYNAM "%s::mptctl_ioctl() @%d - ioc%d not found!\n",
-				__FILE__, __LINE__, iocnumX);
+	    (iocp == NULL))
 		return -ENODEV;
-	}
 
 	if (!iocp->active) {
 		printk(KERN_DEBUG MYNAM "%s::mptctl_ioctl() @%d - Controller disabled.\n",
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index c295786..5775275 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -792,11 +792,36 @@
 			 *  precedence!
 			 */
 			sc->result = (DID_OK << 16) | scsi_status;
-			if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
-				/* Have already saved the status and sense data
+			if (!(scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
+
+				/*
+				 * For an Errata on LSI53C1030
+				 * When the length of request data
+				 * and transfer data are different
+				 * with result of command (READ or VERIFY),
+				 * DID_SOFT_ERROR is set.
 				 */
-				;
-			} else {
+				if (ioc->bus_type == SPI) {
+					if (pScsiReq->CDB[0] == READ_6  ||
+					    pScsiReq->CDB[0] == READ_10 ||
+					    pScsiReq->CDB[0] == READ_12 ||
+					    pScsiReq->CDB[0] == READ_16 ||
+					    pScsiReq->CDB[0] == VERIFY  ||
+					    pScsiReq->CDB[0] == VERIFY_16) {
+						if (scsi_bufflen(sc) !=
+							xfer_cnt) {
+							sc->result =
+							DID_SOFT_ERROR << 16;
+						    printk(KERN_WARNING "Errata"
+						    "on LSI53C1030 occurred."
+						    "sc->req_bufflen=0x%02x,"
+						    "xfer_cnt=0x%02x\n",
+						    scsi_bufflen(sc),
+						    xfer_cnt);
+						}
+					}
+				}
+
 				if (xfer_cnt < sc->underflow) {
 					if (scsi_status == SAM_STAT_BUSY)
 						sc->result = SAM_STAT_BUSY;
@@ -835,7 +860,58 @@
 			sc->result = (DID_OK << 16) | scsi_status;
 			if (scsi_state == 0) {
 				;
-			} else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
+			} else if (scsi_state &
+			    MPI_SCSI_STATE_AUTOSENSE_VALID) {
+
+				/*
+				 * For potential trouble on LSI53C1030.
+				 * (date:2007.xx.)
+				 * It is checked whether the length of
+				 * request data is equal to
+				 * the length of transfer and residual.
+				 * MEDIUM_ERROR is set by incorrect data.
+				 */
+				if ((ioc->bus_type == SPI) &&
+					(sc->sense_buffer[2] & 0x20)) {
+					u32	 difftransfer;
+					difftransfer =
+					sc->sense_buffer[3] << 24 |
+					sc->sense_buffer[4] << 16 |
+					sc->sense_buffer[5] << 8 |
+					sc->sense_buffer[6];
+					if (((sc->sense_buffer[3] & 0x80) ==
+						0x80) && (scsi_bufflen(sc)
+						!= xfer_cnt)) {
+						sc->sense_buffer[2] =
+						    MEDIUM_ERROR;
+						sc->sense_buffer[12] = 0xff;
+						sc->sense_buffer[13] = 0xff;
+						printk(KERN_WARNING"Errata"
+						"on LSI53C1030 occurred."
+						"sc->req_bufflen=0x%02x,"
+						"xfer_cnt=0x%02x\n" ,
+						scsi_bufflen(sc),
+						xfer_cnt);
+					}
+					if (((sc->sense_buffer[3] & 0x80)
+						!= 0x80) &&
+						(scsi_bufflen(sc) !=
+						xfer_cnt + difftransfer)) {
+						sc->sense_buffer[2] =
+							MEDIUM_ERROR;
+						sc->sense_buffer[12] = 0xff;
+						sc->sense_buffer[13] = 0xff;
+						printk(KERN_WARNING
+						"Errata on LSI53C1030 occurred"
+						"sc->req_bufflen=0x%02x,"
+						" xfer_cnt=0x%02x,"
+						"difftransfer=0x%02x\n",
+						scsi_bufflen(sc),
+						xfer_cnt,
+						difftransfer);
+					}
+				}
+
 				/*
 				 * If running against circa 200003dd 909 MPT f/w,
 				 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
@@ -2275,11 +2351,12 @@
  *	mptscsih_change_queue_depth - This function will set a devices queue depth
  *	@sdev: per scsi_device pointer
  *	@qdepth: requested queue depth
+ *	@reason: calling context
  *
  *	Adding support for new 'change_queue_depth' api.
 */
 int
-mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
+mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
 {
 	MPT_SCSI_HOST		*hd = shost_priv(sdev->host);
 	VirtTarget 		*vtarget;
@@ -2291,6 +2368,9 @@
 	starget = scsi_target(sdev);
 	vtarget = starget->hostdata;
 
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (ioc->bus_type == SPI) {
 		if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
 			max_depth = 1;
@@ -2357,7 +2437,8 @@
 		    ioc->name, vtarget->negoFlags, vtarget->maxOffset,
 		    vtarget->minSyncFactor));
 
-	mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
+	mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH,
+				    SCSI_QDEPTH_DEFAULT);
 	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 		"tagged %d, simple %d, ordered %d\n",
 		ioc->name,sdev->tagged_supported, sdev->simple_tags,
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index e0b33e0..45a5ff3 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -128,7 +128,8 @@
 extern int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
 extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
 extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
-extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth);
+extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth,
+				       int reason);
 extern u8 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id);
 extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id);
 extern struct device_attribute *mptscsih_host_attrs[];
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index d505b68..e39986a 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -940,7 +940,7 @@
  *	Allocate memory for the i2o_block_device struct, gendisk and request
  *	queue and initialize them as far as no additional information is needed.
  *
- *	Returns a pointer to the allocated I2O Block device on succes or a
+ *	Returns a pointer to the allocated I2O Block device on success or a
  *	negative error code on failure.
  */
 static struct i2o_block_device *i2o_block_device_alloc(void)
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c
index 27cf4af..e5ab621 100644
--- a/drivers/message/i2o/iop.c
+++ b/drivers/message/i2o/iop.c
@@ -132,7 +132,7 @@
  *	Removes a previously added pointer from the context list and returns
  *	the matching context id.
  *
- *	Returns context id on succes or 0 on failure.
+ *	Returns context id on success or 0 on failure.
  */
 u32 i2o_cntxt_list_remove(struct i2o_controller * c, void *ptr)
 {
@@ -198,7 +198,7 @@
  *	@c: controller to which the context list belong
  *	@ptr: pointer to which the context id should be fetched
  *
- *	Returns context id which matches to the pointer on succes or 0 on
+ *	Returns context id which matches to the pointer on success or 0 on
  *	failure.
  */
 u32 i2o_cntxt_list_get_ptr(struct i2o_controller * c, void *ptr)
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 08f2d07..a296e71 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -35,6 +35,14 @@
 	  This driver supports the ASIC3 multifunction chip found on many
 	  PDAs (mainly iPAQ and HTC based ones)
 
+config MFD_SH_MOBILE_SDHI
+	bool "Support for SuperH Mobile SDHI"
+	depends on SUPERH
+	select MFD_CORE
+	 ---help---
+	  This driver supports the SDHI hardware block found in many
+	  SuperH Mobile SoCs.
+
 config MFD_DM355EVM_MSP
 	bool "DaVinci DM355 EVM microcontroller"
 	depends on I2C && MACH_DAVINCI_DM355_EVM
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index af0fc90..11350c1 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_MFD_SM501)		+= sm501.o
 obj-$(CONFIG_MFD_ASIC3)		+= asic3.o
+obj-$(CONFIG_MFD_SH_MOBILE_SDHI)		+= sh_mobile_sdhi.o
 
 obj-$(CONFIG_HTC_EGPIO)		+= htc-egpio.o
 obj-$(CONFIG_HTC_PASIC3)	+= htc-pasic3.o
diff --git a/drivers/mfd/sh_mobile_sdhi.c b/drivers/mfd/sh_mobile_sdhi.c
new file mode 100644
index 0000000..03efae8
--- /dev/null
+++ b/drivers/mfd/sh_mobile_sdhi.c
@@ -0,0 +1,156 @@
+/*
+ * SuperH Mobile SDHI
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * 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.
+ *
+ * Based on "Compaq ASIC3 support":
+ *
+ * Copyright 2001 Compaq Computer Corporation.
+ * Copyright 2004-2005 Phil Blundell
+ * Copyright 2007-2008 OpenedHand Ltd.
+ *
+ * Authors: Phil Blundell <pb@handhelds.org>,
+ *	    Samuel Ortiz <sameo@openedhand.com>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+
+#include <linux/mfd/core.h>
+#include <linux/mfd/tmio.h>
+#include <linux/mfd/sh_mobile_sdhi.h>
+
+struct sh_mobile_sdhi {
+	struct clk *clk;
+	struct tmio_mmc_data mmc_data;
+	struct mfd_cell cell_mmc;
+};
+
+static struct resource sh_mobile_sdhi_resources[] = {
+	{
+		.start = 0x000,
+		.end   = 0x1ff,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = 0,
+		.end   = 0,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct mfd_cell sh_mobile_sdhi_cell = {
+	.name          = "tmio-mmc",
+	.num_resources = ARRAY_SIZE(sh_mobile_sdhi_resources),
+	.resources     = sh_mobile_sdhi_resources,
+};
+
+static void sh_mobile_sdhi_set_pwr(struct platform_device *tmio, int state)
+{
+	struct platform_device *pdev = to_platform_device(tmio->dev.parent);
+	struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
+
+	if (p && p->set_pwr)
+		p->set_pwr(pdev, state);
+}
+
+static int __init sh_mobile_sdhi_probe(struct platform_device *pdev)
+{
+	struct sh_mobile_sdhi *priv;
+	struct resource *mem;
+	char clk_name[8];
+	int ret, irq;
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mem)
+		dev_err(&pdev->dev, "missing MEM resource\n");
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		dev_err(&pdev->dev, "missing IRQ resource\n");
+
+	if (!mem || (irq < 0))
+		return -EINVAL;
+
+	priv = kzalloc(sizeof(struct sh_mobile_sdhi), GFP_KERNEL);
+	if (priv == NULL) {
+		dev_err(&pdev->dev, "kzalloc failed\n");
+		return -ENOMEM;
+	}
+
+	snprintf(clk_name, sizeof(clk_name), "sdhi%d", pdev->id);
+	priv->clk = clk_get(&pdev->dev, clk_name);
+	if (IS_ERR(priv->clk)) {
+		dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
+		ret = PTR_ERR(priv->clk);
+		kfree(priv);
+		return ret;
+	}
+
+	clk_enable(priv->clk);
+
+	/* FIXME: silly const unsigned int hclk */
+	*(unsigned int *)&priv->mmc_data.hclk = clk_get_rate(priv->clk);
+	priv->mmc_data.set_pwr = sh_mobile_sdhi_set_pwr;
+
+	memcpy(&priv->cell_mmc, &sh_mobile_sdhi_cell, sizeof(priv->cell_mmc));
+	priv->cell_mmc.driver_data = &priv->mmc_data;
+	priv->cell_mmc.platform_data = &priv->cell_mmc;
+	priv->cell_mmc.data_size = sizeof(priv->cell_mmc);
+
+	platform_set_drvdata(pdev, priv);
+
+	ret = mfd_add_devices(&pdev->dev, pdev->id,
+			      &priv->cell_mmc, 1, mem, irq);
+	if (ret) {
+		clk_disable(priv->clk);
+		clk_put(priv->clk);
+		kfree(priv);
+	}
+
+	return ret;
+}
+
+static int sh_mobile_sdhi_remove(struct platform_device *pdev)
+{
+	struct sh_mobile_sdhi *priv = platform_get_drvdata(pdev);
+
+	mfd_remove_devices(&pdev->dev);
+	clk_disable(priv->clk);
+	clk_put(priv->clk);
+	kfree(priv);
+
+	return 0;
+}
+
+static struct platform_driver sh_mobile_sdhi_driver = {
+	.driver		= {
+		.name	= "sh_mobile_sdhi",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= sh_mobile_sdhi_probe,
+	.remove		= __devexit_p(sh_mobile_sdhi_remove),
+};
+
+static int __init sh_mobile_sdhi_init(void)
+{
+	return platform_driver_register(&sh_mobile_sdhi_driver);
+}
+
+static void __exit sh_mobile_sdhi_exit(void)
+{
+	platform_driver_unregister(&sh_mobile_sdhi_driver);
+}
+
+module_init(sh_mobile_sdhi_init);
+module_exit(sh_mobile_sdhi_exit);
+
+MODULE_DESCRIPTION("SuperH Mobile SDHI driver");
+MODULE_AUTHOR("Magnus Damm");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/ucb1400_core.c b/drivers/mfd/ucb1400_core.c
index fa294b6..85fd942 100644
--- a/drivers/mfd/ucb1400_core.c
+++ b/drivers/mfd/ucb1400_core.c
@@ -51,6 +51,7 @@
 	struct ucb1400_ts ucb_ts;
 	struct ucb1400_gpio ucb_gpio;
 	struct snd_ac97 *ac97;
+	struct ucb1400_pdata *pdata = dev->platform_data;
 
 	memset(&ucb_ts, 0, sizeof(ucb_ts));
 	memset(&ucb_gpio, 0, sizeof(ucb_gpio));
@@ -88,6 +89,12 @@
 
 	/* TOUCHSCREEN */
 	ucb_ts.ac97 = ac97;
+
+	if (pdata != NULL && pdata->irq >= 0)
+		ucb_ts.irq = pdata->irq;
+	else
+		ucb_ts.irq = -1;
+
 	ucb->ucb1400_ts = platform_device_alloc("ucb1400_ts", -1);
 	if (!ucb->ucb1400_ts) {
 		err = -ENOMEM;
diff --git a/drivers/misc/hpilo.h b/drivers/misc/hpilo.h
index 3857605..247eb38 100644
--- a/drivers/misc/hpilo.h
+++ b/drivers/misc/hpilo.h
@@ -44,9 +44,20 @@
 
 	struct pci_dev *ilo_dev;
 
+	/*
+	 * open_lock      serializes ccb_cnt during open and close
+	 * [ irq disabled ]
+	 * -> alloc_lock  used when adding/removing/searching ccb_alloc,
+	 *                which represents all ccbs open on the device
+	 * --> fifo_lock  controls access to fifo queues shared with hw
+	 *
+	 * Locks must be taken in this order, but open_lock and alloc_lock
+	 * are optional, they do not need to be held in order to take a
+	 * lower level lock.
+	 */
+	spinlock_t open_lock;
 	spinlock_t alloc_lock;
 	spinlock_t fifo_lock;
-	spinlock_t open_lock;
 
 	struct cdev cdev;
 };
diff --git a/drivers/misc/kgdbts.c b/drivers/misc/kgdbts.c
index e4ff50b..fcb6ec1 100644
--- a/drivers/misc/kgdbts.c
+++ b/drivers/misc/kgdbts.c
@@ -712,6 +712,12 @@
 
 	/* End of packet == #XX so look for the '#' */
 	if (put_buf_cnt > 3 && put_buf[put_buf_cnt - 3] == '#') {
+		if (put_buf_cnt >= BUFMAX) {
+			eprintk("kgdbts: ERROR: put buffer overflow on"
+				" '%s' line %i\n", ts.name, ts.idx);
+			put_buf_cnt = 0;
+			return 0;
+		}
 		put_buf[put_buf_cnt] = '\0';
 		v2printk("put%i: %s\n", ts.idx, put_buf);
 		/* Trigger check here */
@@ -885,16 +891,16 @@
 	int nmi_sleep = 0;
 	int i;
 
-	ptr = strstr(config, "F");
+	ptr = strchr(config, 'F');
 	if (ptr)
 		fork_test = simple_strtol(ptr + 1, NULL, 10);
-	ptr = strstr(config, "S");
+	ptr = strchr(config, 'S');
 	if (ptr)
 		do_sys_open_test = simple_strtol(ptr + 1, NULL, 10);
-	ptr = strstr(config, "N");
+	ptr = strchr(config, 'N');
 	if (ptr)
 		nmi_sleep = simple_strtol(ptr+1, NULL, 10);
-	ptr = strstr(config, "I");
+	ptr = strchr(config, 'I');
 	if (ptr)
 		sstep_test = simple_strtol(ptr+1, NULL, 10);
 
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c
index 41c8fe2..ce5eda9 100644
--- a/drivers/misc/sgi-gru/grufile.c
+++ b/drivers/misc/sgi-gru/grufile.c
@@ -92,7 +92,7 @@
 /*
  * gru_file_mmap
  *
- * Called when mmaping the device.  Initializes the vma with a fault handler
+ * Called when mmapping the device.  Initializes the vma with a fault handler
  * and private data structure necessary to allocate, track, and free the
  * underlying pages.
  */
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c
index 36a8d53..f537555 100644
--- a/drivers/mmc/card/sdio_uart.c
+++ b/drivers/mmc/card/sdio_uart.c
@@ -29,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/sched.h>
 #include <linux/mutex.h>
 #include <linux/seq_file.h>
 #include <linux/serial_reg.h>
@@ -73,11 +74,10 @@
 };
 
 struct sdio_uart_port {
+	struct tty_port		port;
 	struct kref		kref;
 	struct tty_struct	*tty;
 	unsigned int		index;
-	unsigned int		opened;
-	struct mutex		open_lock;
 	struct sdio_func	*func;
 	struct mutex		func_lock;
 	struct task_struct	*in_sdio_uart_irq;
@@ -87,6 +87,7 @@
 	struct uart_icount	icount;
 	unsigned int		uartclk;
 	unsigned int		mctrl;
+	unsigned int		rx_mctrl;
 	unsigned int		read_status_mask;
 	unsigned int		ignore_status_mask;
 	unsigned char		x_char;
@@ -102,7 +103,6 @@
 	int index, ret = -EBUSY;
 
 	kref_init(&port->kref);
-	mutex_init(&port->open_lock);
 	mutex_init(&port->func_lock);
 	spin_lock_init(&port->write_lock);
 
@@ -151,6 +151,7 @@
 static void sdio_uart_port_remove(struct sdio_uart_port *port)
 {
 	struct sdio_func *func;
+	struct tty_struct *tty;
 
 	BUG_ON(sdio_uart_table[port->index] != port);
 
@@ -165,15 +166,19 @@
 	 * give up on that port ASAP.
 	 * Beware: the lock ordering is critical.
 	 */
-	mutex_lock(&port->open_lock);
+	mutex_lock(&port->port.mutex);
 	mutex_lock(&port->func_lock);
 	func = port->func;
 	sdio_claim_host(func);
 	port->func = NULL;
 	mutex_unlock(&port->func_lock);
-	if (port->opened)
-		tty_hangup(port->tty);
-	mutex_unlock(&port->open_lock);
+	tty = tty_port_tty_get(&port->port);
+	/* tty_hangup is async so is this safe as is ?? */
+	if (tty) {
+		tty_hangup(tty);
+		tty_kref_put(tty);
+	}
+	mutex_unlock(&port->port.mutex);
 	sdio_release_irq(func);
 	sdio_disable_func(func);
 	sdio_release_host(func);
@@ -217,6 +222,8 @@
 	unsigned char status;
 	unsigned int ret;
 
+	/* FIXME: What stops this losing the delta bits and breaking
+	   sdio_uart_check_modem_status ? */
 	status = sdio_in(port, UART_MSR);
 
 	ret = 0;
@@ -231,7 +238,8 @@
 	return ret;
 }
 
-static void sdio_uart_write_mctrl(struct sdio_uart_port *port, unsigned int mctrl)
+static void sdio_uart_write_mctrl(struct sdio_uart_port *port,
+				  unsigned int mctrl)
 {
 	unsigned char mcr = 0;
 
@@ -387,9 +395,10 @@
 	sdio_out(port, UART_IER, port->ier);
 }
 
-static void sdio_uart_receive_chars(struct sdio_uart_port *port, unsigned int *status)
+static void sdio_uart_receive_chars(struct sdio_uart_port *port,
+				    unsigned int *status)
 {
-	struct tty_struct *tty = port->tty;
+	struct tty_struct *tty = tty_port_tty_get(&port->port);
 	unsigned int ch, flag;
 	int max_count = 256;
 
@@ -399,7 +408,7 @@
 		port->icount.rx++;
 
 		if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE |
-				        UART_LSR_FE | UART_LSR_OE))) {
+					UART_LSR_FE | UART_LSR_OE))) {
 			/*
 			 * For statistics only
 			 */
@@ -417,33 +426,39 @@
 			 * Mask off conditions which should be ignored.
 			 */
 			*status &= port->read_status_mask;
-			if (*status & UART_LSR_BI) {
+			if (*status & UART_LSR_BI)
 				flag = TTY_BREAK;
-			} else if (*status & UART_LSR_PE)
+			else if (*status & UART_LSR_PE)
 				flag = TTY_PARITY;
 			else if (*status & UART_LSR_FE)
 				flag = TTY_FRAME;
 		}
 
 		if ((*status & port->ignore_status_mask & ~UART_LSR_OE) == 0)
-			tty_insert_flip_char(tty, ch, flag);
+			if (tty)
+				tty_insert_flip_char(tty, ch, flag);
 
 		/*
 		 * Overrun is special.  Since it's reported immediately,
 		 * it doesn't affect the current character.
 		 */
 		if (*status & ~port->ignore_status_mask & UART_LSR_OE)
-			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+			if (tty)
+				tty_insert_flip_char(tty, 0, TTY_OVERRUN);
 
 		*status = sdio_in(port, UART_LSR);
 	} while ((*status & UART_LSR_DR) && (max_count-- > 0));
-	tty_flip_buffer_push(tty);
+	if (tty) {
+		tty_flip_buffer_push(tty);
+		tty_kref_put(tty);
+	}
 }
 
 static void sdio_uart_transmit_chars(struct sdio_uart_port *port)
 {
 	struct circ_buf *xmit = &port->xmit;
 	int count;
+	struct tty_struct *tty;
 
 	if (port->x_char) {
 		sdio_out(port, UART_TX, port->x_char);
@@ -451,8 +466,13 @@
 		port->x_char = 0;
 		return;
 	}
-	if (circ_empty(xmit) || port->tty->stopped || port->tty->hw_stopped) {
+
+	tty = tty_port_tty_get(&port->port);
+
+	if (tty == NULL || circ_empty(xmit) ||
+				tty->stopped || tty->hw_stopped) {
 		sdio_uart_stop_tx(port);
+		tty_kref_put(tty);
 		return;
 	}
 
@@ -466,15 +486,17 @@
 	} while (--count > 0);
 
 	if (circ_chars_pending(xmit) < WAKEUP_CHARS)
-		tty_wakeup(port->tty);
+		tty_wakeup(tty);
 
 	if (circ_empty(xmit))
 		sdio_uart_stop_tx(port);
+	tty_kref_put(tty);
 }
 
 static void sdio_uart_check_modem_status(struct sdio_uart_port *port)
 {
 	int status;
+	struct tty_struct *tty;
 
 	status = sdio_in(port, UART_MSR);
 
@@ -485,25 +507,39 @@
 		port->icount.rng++;
 	if (status & UART_MSR_DDSR)
 		port->icount.dsr++;
-	if (status & UART_MSR_DDCD)
+	if (status & UART_MSR_DDCD) {
 		port->icount.dcd++;
+		/* DCD raise - wake for open */
+		if (status & UART_MSR_DCD)
+			wake_up_interruptible(&port->port.open_wait);
+		else {
+			/* DCD drop - hang up if tty attached */
+			tty = tty_port_tty_get(&port->port);
+			if (tty) {
+				tty_hangup(tty);
+				tty_kref_put(tty);
+			}
+		}
+	}
 	if (status & UART_MSR_DCTS) {
 		port->icount.cts++;
-		if (port->tty->termios->c_cflag & CRTSCTS) {
+		tty = tty_port_tty_get(&port->port);
+		if (tty && (tty->termios->c_cflag & CRTSCTS)) {
 			int cts = (status & UART_MSR_CTS);
-			if (port->tty->hw_stopped) {
+			if (tty->hw_stopped) {
 				if (cts) {
-					port->tty->hw_stopped = 0;
+					tty->hw_stopped = 0;
 					sdio_uart_start_tx(port);
-					tty_wakeup(port->tty);
+					tty_wakeup(tty);
 				}
 			} else {
 				if (!cts) {
-					port->tty->hw_stopped = 1;
+					tty->hw_stopped = 1;
 					sdio_uart_stop_tx(port);
 				}
 			}
 		}
+		tty_kref_put(tty);
 	}
 }
 
@@ -540,8 +576,62 @@
 	port->in_sdio_uart_irq = NULL;
 }
 
-static int sdio_uart_startup(struct sdio_uart_port *port)
+static int uart_carrier_raised(struct tty_port *tport)
 {
+	struct sdio_uart_port *port =
+			container_of(tport, struct sdio_uart_port, port);
+	unsigned int ret = sdio_uart_claim_func(port);
+	if (ret)	/* Missing hardware shoudn't block for carrier */
+		return 1;
+	ret = sdio_uart_get_mctrl(port);
+	sdio_uart_release_func(port);
+	if (ret & TIOCM_CAR)
+		return 1;
+	return 0;
+}
+
+/**
+ *	uart_dtr_rts		-	 port helper to set uart signals
+ *	@tport: tty port to be updated
+ *	@onoff: set to turn on DTR/RTS
+ *
+ *	Called by the tty port helpers when the modem signals need to be
+ *	adjusted during an open, close and hangup.
+ */
+
+static void uart_dtr_rts(struct tty_port *tport, int onoff)
+{
+	struct sdio_uart_port *port =
+			container_of(tport, struct sdio_uart_port, port);
+	int ret = sdio_uart_claim_func(port);
+	if (ret)
+		return;
+	if (onoff == 0)
+		sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+	else
+		sdio_uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+	sdio_uart_release_func(port);
+}
+
+/**
+ *	sdio_uart_activate	-	start up hardware
+ *	@tport: tty port to activate
+ *	@tty: tty bound to this port
+ *
+ *	Activate a tty port. The port locking guarantees us this will be
+ *	run exactly once per set of opens, and if successful will see the
+ *	shutdown method run exactly once to match. Start up and shutdown are
+ *	protected from each other by the internal locking and will not run
+ *	at the same time even during a hangup event.
+ *
+ *	If we successfully start up the port we take an extra kref as we
+ *	will keep it around until shutdown when the kref is dropped.
+ */
+
+static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty)
+{
+	struct sdio_uart_port *port =
+			container_of(tport, struct sdio_uart_port, port);
 	unsigned long page;
 	int ret;
 
@@ -549,7 +639,7 @@
 	 * Set the TTY IO error marker - we will only clear this
 	 * once we have successfully opened the port.
 	 */
-	set_bit(TTY_IO_ERROR, &port->tty->flags);
+	set_bit(TTY_IO_ERROR, &tty->flags);
 
 	/* Initialise and allocate the transmit buffer. */
 	page = __get_free_page(GFP_KERNEL);
@@ -574,7 +664,7 @@
 	 */
 	sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO);
 	sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO |
-			UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+		       UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
 	sdio_out(port, UART_FCR, 0);
 
 	/*
@@ -590,19 +680,19 @@
 	 */
 	sdio_out(port, UART_LCR, UART_LCR_WLEN8);
 
-	port->ier = UART_IER_RLSI | UART_IER_RDI | UART_IER_RTOIE | UART_IER_UUE;
+	port->ier = UART_IER_RLSI|UART_IER_RDI|UART_IER_RTOIE|UART_IER_UUE;
 	port->mctrl = TIOCM_OUT2;
 
-	sdio_uart_change_speed(port, port->tty->termios, NULL);
+	sdio_uart_change_speed(port, tty->termios, NULL);
 
-	if (port->tty->termios->c_cflag & CBAUD)
+	if (tty->termios->c_cflag & CBAUD)
 		sdio_uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
 
-	if (port->tty->termios->c_cflag & CRTSCTS)
+	if (tty->termios->c_cflag & CRTSCTS)
 		if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS))
-			port->tty->hw_stopped = 1;
+			tty->hw_stopped = 1;
 
-	clear_bit(TTY_IO_ERROR, &port->tty->flags);
+	clear_bit(TTY_IO_ERROR, &tty->flags);
 
 	/* Kick the IRQ handler once while we're still holding the host lock */
 	sdio_uart_irq(port->func);
@@ -619,8 +709,20 @@
 	return ret;
 }
 
-static void sdio_uart_shutdown(struct sdio_uart_port *port)
+/**
+ *	sdio_uart_shutdown	-	stop hardware
+ *	@tport: tty port to shut down
+ *
+ *	Deactivate a tty port. The port locking guarantees us this will be
+ *	run only if a successful matching activate already ran. The two are
+ *	protected from each other by the internal locking and will not run
+ *	at the same time even during a hangup event.
+ */
+
+static void sdio_uart_shutdown(struct tty_port *tport)
 {
+	struct sdio_uart_port *port =
+			container_of(tport, struct sdio_uart_port, port);
 	int ret;
 
 	ret = sdio_uart_claim_func(port);
@@ -629,13 +731,7 @@
 
 	sdio_uart_stop_rx(port);
 
-	/* TODO: wait here for TX FIFO to drain */
-
-	/* Turn off DTR and RTS early. */
-	if (port->tty->termios->c_cflag & HUPCL)
-		sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
-
-	 /* Disable interrupts from this port */
+	/* Disable interrupts from this port */
 	sdio_release_irq(port->func);
 	port->ier = 0;
 	sdio_out(port, UART_IER, 0);
@@ -659,77 +755,70 @@
 	free_page((unsigned long)port->xmit.buf);
 }
 
-static int sdio_uart_open (struct tty_struct *tty, struct file * filp)
+/**
+ *	sdio_uart_install	-	install method
+ *	@driver: the driver in use (sdio_uart in our case)
+ *	@tty: the tty being bound
+ *
+ *	Look up and bind the tty and the driver together. Initialize
+ *	any needed private data (in our case the termios)
+ */
+
+static int sdio_uart_install(struct tty_driver *driver, struct tty_struct *tty)
 {
-	struct sdio_uart_port *port;
-	int ret;
+	int idx = tty->index;
+	struct sdio_uart_port *port = sdio_uart_port_get(idx);
+	int ret = tty_init_termios(tty);
 
-	port = sdio_uart_port_get(tty->index);
-	if (!port)
-		return -ENODEV;
-
-	mutex_lock(&port->open_lock);
-
-	/*
-	 * Make sure not to mess up with a dead port
-	 * which has not been closed yet.
-	 */
-	if (tty->driver_data && tty->driver_data != port) {
-		mutex_unlock(&port->open_lock);
-		sdio_uart_port_put(port);
-		return -EBUSY;
-	}
-
-	if (!port->opened) {
+	if (ret == 0) {
+		tty_driver_kref_get(driver);
+		tty->count++;
+		/* This is the ref sdio_uart_port get provided */
 		tty->driver_data = port;
-		port->tty = tty;
-		ret = sdio_uart_startup(port);
-		if (ret) {
-			tty->driver_data = NULL;
-			port->tty = NULL;
-			mutex_unlock(&port->open_lock);
-			sdio_uart_port_put(port);
-			return ret;
-		}
-	}
-	port->opened++;
-	mutex_unlock(&port->open_lock);
-	return 0;
+		driver->ttys[idx] = tty;
+	} else
+		sdio_uart_port_put(port);
+	return ret;
+}
+
+/**
+ *	sdio_uart_cleanup	-	called on the last tty kref drop
+ *	@tty: the tty being destroyed
+ *
+ *	Called asynchronously when the last reference to the tty is dropped.
+ *	We cannot destroy the tty->driver_data port kref until this point
+ */
+
+static void sdio_uart_cleanup(struct tty_struct *tty)
+{
+	struct sdio_uart_port *port = tty->driver_data;
+	tty->driver_data = NULL;	/* Bug trap */
+	sdio_uart_port_put(port);
+}
+
+/*
+ *	Open/close/hangup is now entirely boilerplate
+ */
+
+static int sdio_uart_open(struct tty_struct *tty, struct file *filp)
+{
+	struct sdio_uart_port *port = tty->driver_data;
+	return tty_port_open(&port->port, tty, filp);
 }
 
 static void sdio_uart_close(struct tty_struct *tty, struct file * filp)
 {
 	struct sdio_uart_port *port = tty->driver_data;
-
-	if (!port)
-		return;
-
-	mutex_lock(&port->open_lock);
-	BUG_ON(!port->opened);
-
-	/*
-	 * This is messy.  The tty layer calls us even when open()
-	 * returned an error.  Ignore this close request if tty->count
-	 * is larger than port->count.
-	 */
-	if (tty->count > port->opened) {
-		mutex_unlock(&port->open_lock);
-		return;
-	}
-
-	if (--port->opened == 0) {
-		tty->closing = 1;
-		sdio_uart_shutdown(port);
-		tty_ldisc_flush(tty);
-		port->tty = NULL;
-		tty->driver_data = NULL;
-		tty->closing = 0;
-	}
-	mutex_unlock(&port->open_lock);
-	sdio_uart_port_put(port);
+	tty_port_close(&port->port, tty, filp);
 }
 
-static int sdio_uart_write(struct tty_struct * tty, const unsigned char *buf,
+static void sdio_uart_hangup(struct tty_struct *tty)
+{
+	struct sdio_uart_port *port = tty->driver_data;
+	tty_port_hangup(&port->port);
+}
+
+static int sdio_uart_write(struct tty_struct *tty, const unsigned char *buf,
 			   int count)
 {
 	struct sdio_uart_port *port = tty->driver_data;
@@ -754,7 +843,7 @@
 	}
 	spin_unlock(&port->write_lock);
 
-	if ( !(port->ier & UART_IER_THRI)) {
+	if (!(port->ier & UART_IER_THRI)) {
 		int err = sdio_uart_claim_func(port);
 		if (!err) {
 			sdio_uart_start_tx(port);
@@ -841,17 +930,12 @@
 	sdio_uart_release_func(port);
 }
 
-static void sdio_uart_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
+static void sdio_uart_set_termios(struct tty_struct *tty,
+						struct ktermios *old_termios)
 {
 	struct sdio_uart_port *port = tty->driver_data;
 	unsigned int cflag = tty->termios->c_cflag;
 
-#define RELEVANT_IFLAG(iflag)   ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
-
-	if ((cflag ^ old_termios->c_cflag) == 0 &&
-	    RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0)
-		return;
-
 	if (sdio_uart_claim_func(port) != 0)
 		return;
 
@@ -925,8 +1009,8 @@
 	struct sdio_uart_port *port = tty->driver_data;
 	int result;
 
-	result =sdio_uart_claim_func(port);
-	if(!result) {
+	result = sdio_uart_claim_func(port);
+	if (!result) {
 		sdio_uart_update_mctrl(port, set, clear);
 		sdio_uart_release_func(port);
 	}
@@ -944,33 +1028,33 @@
 		struct sdio_uart_port *port = sdio_uart_port_get(i);
 		if (port) {
 			seq_printf(m, "%d: uart:SDIO", i);
-			if(capable(CAP_SYS_ADMIN)) {
+			if (capable(CAP_SYS_ADMIN)) {
 				seq_printf(m, " tx:%d rx:%d",
-					       port->icount.tx, port->icount.rx);
+					      port->icount.tx, port->icount.rx);
 				if (port->icount.frame)
 					seq_printf(m, " fe:%d",
-						       port->icount.frame);
+						      port->icount.frame);
 				if (port->icount.parity)
 					seq_printf(m, " pe:%d",
-						       port->icount.parity);
+						      port->icount.parity);
 				if (port->icount.brk)
 					seq_printf(m, " brk:%d",
-						       port->icount.brk);
+						      port->icount.brk);
 				if (port->icount.overrun)
 					seq_printf(m, " oe:%d",
-						       port->icount.overrun);
+						      port->icount.overrun);
 				if (port->icount.cts)
 					seq_printf(m, " cts:%d",
-						       port->icount.cts);
+						      port->icount.cts);
 				if (port->icount.dsr)
 					seq_printf(m, " dsr:%d",
-						       port->icount.dsr);
+						      port->icount.dsr);
 				if (port->icount.rng)
 					seq_printf(m, " rng:%d",
-						       port->icount.rng);
+						      port->icount.rng);
 				if (port->icount.dcd)
 					seq_printf(m, " dcd:%d",
-						       port->icount.dcd);
+						      port->icount.dcd);
 			}
 			sdio_uart_port_put(port);
 			seq_putc(m, '\n');
@@ -992,6 +1076,13 @@
 	.release	= single_release,
 };
 
+static const struct tty_port_operations sdio_uart_port_ops = {
+	.dtr_rts = uart_dtr_rts,
+	.carrier_raised = uart_carrier_raised,
+	.shutdown = sdio_uart_shutdown,
+	.activate = sdio_uart_activate,
+};
+
 static const struct tty_operations sdio_uart_ops = {
 	.open			= sdio_uart_open,
 	.close			= sdio_uart_close,
@@ -1002,9 +1093,12 @@
 	.throttle		= sdio_uart_throttle,
 	.unthrottle		= sdio_uart_unthrottle,
 	.set_termios		= sdio_uart_set_termios,
+	.hangup			= sdio_uart_hangup,
 	.break_ctl		= sdio_uart_break_ctl,
 	.tiocmget		= sdio_uart_tiocmget,
 	.tiocmset		= sdio_uart_tiocmset,
+	.install		= sdio_uart_install,
+	.cleanup		= sdio_uart_cleanup,
 	.proc_fops		= &sdio_uart_proc_fops,
 };
 
@@ -1041,7 +1135,7 @@
 		}
 		if (!tpl) {
 			printk(KERN_WARNING
-			       "%s: can't find tuple 0x91 subtuple 0 (SUBTPL_SIOREG) for GPS class\n",
+       "%s: can't find tuple 0x91 subtuple 0 (SUBTPL_SIOREG) for GPS class\n",
 			       sdio_func_id(func));
 			kfree(port);
 			return -EINVAL;
@@ -1066,13 +1160,16 @@
 
 	port->func = func;
 	sdio_set_drvdata(func, port);
+	tty_port_init(&port->port);
+	port->port.ops = &sdio_uart_port_ops;
 
 	ret = sdio_uart_add_port(port);
 	if (ret) {
 		kfree(port);
 	} else {
 		struct device *dev;
-		dev = tty_register_device(sdio_uart_tty_driver, port->index, &func->dev);
+		dev = tty_register_device(sdio_uart_tty_driver,
+						port->index, &func->dev);
 		if (IS_ERR(dev)) {
 			sdio_uart_port_remove(port);
 			ret = PTR_ERR(dev);
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 432ae83..e04b751 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -329,7 +329,7 @@
 
 config MMC_TMIO
 	tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support"
-	depends on MFD_TMIO || MFD_ASIC3
+	depends on MFD_TMIO || MFD_ASIC3 || SUPERH
 	help
 	  This provides support for the SD/MMC cell found in TC6393XB,
 	  T7L66XB and also HTC ASIC3
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index 99b74a3..941a4d3 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -1360,7 +1360,7 @@
 
 static struct s3c24xx_mci_pdata s3cmci_def_pdata = {
 	/* This is currently here to avoid a number of if (host->pdata)
-	 * checks. Any zero fields to ensure reaonable defaults are picked. */
+	 * checks. Any zero fields to ensure reasonable defaults are picked. */
 };
 
 #ifdef CONFIG_CPU_FREQ
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig
index 9408099..35c6a23 100644
--- a/drivers/mtd/chips/Kconfig
+++ b/drivers/mtd/chips/Kconfig
@@ -1,5 +1,3 @@
-# drivers/mtd/chips/Kconfig
-
 menu "RAM/ROM/Flash chip drivers"
 	depends on MTD!=n
 
@@ -242,4 +240,3 @@
 	  then say N.
 
 endmenu
-
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index c222514..35081ce 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -1,5 +1,3 @@
-# drivers/mtd/maps/Kconfig
-
 menu "Self-contained MTD device drivers"
 	depends on MTD!=n
 
@@ -308,4 +306,3 @@
 	  you have managed to wipe the first block.
 
 endmenu
-
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
index 3aa05cd..592016a 100644
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -18,7 +18,7 @@
                 to specify the offset instead of the absolute address
 
   NOTE:
-  With slram it's only possible to map a contigous memory region. Therfore
+  With slram it's only possible to map a contiguous memory region. Therefore
   if there's a device mapped somewhere in the region specified slram will
   fail to load (see kernel log if modprobe fails).
 
diff --git a/drivers/mtd/lpddr/Kconfig b/drivers/mtd/lpddr/Kconfig
index 5a401d8..265f969 100644
--- a/drivers/mtd/lpddr/Kconfig
+++ b/drivers/mtd/lpddr/Kconfig
@@ -1,5 +1,3 @@
-# drivers/mtd/chips/Kconfig
-
 menu "LPDDR flash memory drivers"
 	depends on MTD!=n
 
@@ -20,4 +18,3 @@
 	    families of devices. This serves similar purpose of CFI on legacy
 	    Flash products
 endmenu
-
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 14be075..847e214 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -1,5 +1,3 @@
-# drivers/mtd/maps/Kconfig
-
 menu "Mapping drivers for chip access"
 	depends on MTD!=n
 
@@ -389,9 +387,9 @@
 	depends on MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP2000
 	help
 	  This enables MTD access to flash devices on platforms based
-	  on Intel's IXP2000 family of network processors such as the
-	  IXDP425 and Coyote. If you have an IXP2000 based board and
-	  would like to use the flash chips on it, say 'Y'.
+	  on Intel's IXP2000 family of network processors. If you have an
+	  IXP2000 based board and would like to use the flash chips on it,
+	  say 'Y'.
 
 config MTD_FORTUNET
 	tristate "CFI Flash device mapped on the FortuNet board"
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 8f8e87b..0e35e1a 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -1,5 +1,3 @@
-# drivers/mtd/nand/Kconfig
-
 menuconfig MTD_NAND
 	tristate "NAND Device Support"
 	depends on MTD
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index e51c1ed7..b126cf8 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -1056,7 +1056,7 @@
 };
 
 /* Find the (I)NFTL Media Header, and optionally also the mirror media header.
-   On sucessful return, buf will contain a copy of the media header for
+   On successful return, buf will contain a copy of the media header for
    further processing.  id is the string to scan for, and will presumably be
    either "ANAND" or "BNAND".  If findmirror=1, also look for the mirror media
    header.  The page #s of the found media headers are placed in mh0_page and
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c
index db7ae9d..92320a6 100644
--- a/drivers/mtd/nand/nand_ecc.c
+++ b/drivers/mtd/nand/nand_ecc.c
@@ -475,7 +475,7 @@
 		 *
 		 * The b2 shift is there to get rid of the lowest two bits.
 		 * We could also do addressbits[b2] >> 1 but for the
-		 * performace it does not make any difference
+		 * performance it does not make any difference
 		 */
 		if (eccsize_mult == 1)
 			byte_addr = (addressbits[b1] << 4) + addressbits[b0];
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index 11dc7e6..68b5b3a 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -875,7 +875,7 @@
  * @info: The controller instance.
  * @nmtd: The driver version of the MTD instance.
  *
- * This routine is called after the chip probe has succesfully completed
+ * This routine is called after the chip probe has successfully completed
  * and the relevant per-chip information updated. This call ensure that
  * we update the internal state accordingly.
  *
diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig
index a38f580..3a9f157 100644
--- a/drivers/mtd/onenand/Kconfig
+++ b/drivers/mtd/onenand/Kconfig
@@ -1,7 +1,3 @@
-#
-# linux/drivers/mtd/onenand/Kconfig
-#
-
 menuconfig MTD_ONENAND
 	tristate "OneNAND Device Support"
 	depends on MTD
diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig
index b1cd7a1..0a8c7ea 100644
--- a/drivers/mtd/ubi/Kconfig
+++ b/drivers/mtd/ubi/Kconfig
@@ -1,5 +1,3 @@
-# drivers/mtd/ubi/Kconfig
-
 menu "UBI - Unsorted block images"
 	depends on MTD
 
diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c
index 88a72e9..277786e 100644
--- a/drivers/mtd/ubi/kapi.c
+++ b/drivers/mtd/ubi/kapi.c
@@ -22,6 +22,8 @@
 
 #include <linux/module.h>
 #include <linux/err.h>
+#include <linux/namei.h>
+#include <linux/fs.h>
 #include <asm/div64.h>
 #include "ubi.h"
 
@@ -280,6 +282,44 @@
 EXPORT_SYMBOL_GPL(ubi_open_volume_nm);
 
 /**
+ * ubi_open_volume_path - open UBI volume by its character device node path.
+ * @pathname: volume character device node path
+ * @mode: open mode
+ *
+ * This function is similar to 'ubi_open_volume()', but opens a volume the path
+ * to its character device node.
+ */
+struct ubi_volume_desc *ubi_open_volume_path(const char *pathname, int mode)
+{
+	int error, ubi_num, vol_id;
+	struct ubi_volume_desc *ret;
+	struct inode *inode;
+	struct path path;
+
+	dbg_gen("open volume %s, mode %d", pathname, mode);
+
+	if (!pathname || !*pathname)
+		return ERR_PTR(-EINVAL);
+
+	error = kern_path(pathname, LOOKUP_FOLLOW, &path);
+	if (error)
+		return ERR_PTR(error);
+
+	inode = path.dentry->d_inode;
+	ubi_num = ubi_major2num(imajor(inode));
+	vol_id = iminor(inode) - 1;
+
+	if (vol_id >= 0 && ubi_num >= 0)
+		ret = ubi_open_volume(ubi_num, vol_id, mode);
+	else
+		ret = ERR_PTR(-ENODEV);
+
+	path_put(&path);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(ubi_open_volume_path);
+
+/**
  * ubi_close_volume - close UBI volume.
  * @desc: volume descriptor
  */
diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c
index 74fdc40..c1d7b88 100644
--- a/drivers/mtd/ubi/upd.c
+++ b/drivers/mtd/ubi/upd.c
@@ -147,12 +147,14 @@
 	}
 
 	if (bytes == 0) {
+		err = ubi_wl_flush(ubi);
+		if (err)
+			return err;
+
 		err = clear_update_marker(ubi, vol, 0);
 		if (err)
 			return err;
-		err = ubi_wl_flush(ubi);
-		if (!err)
-			vol->updating = 0;
+		vol->updating = 0;
 	}
 
 	vol->upd_buf = vmalloc(ubi->leb_size);
@@ -362,16 +364,16 @@
 
 	ubi_assert(vol->upd_received <= vol->upd_bytes);
 	if (vol->upd_received == vol->upd_bytes) {
+		err = ubi_wl_flush(ubi);
+		if (err)
+			return err;
 		/* The update is finished, clear the update marker */
 		err = clear_update_marker(ubi, vol, vol->upd_bytes);
 		if (err)
 			return err;
-		err = ubi_wl_flush(ubi);
-		if (err == 0) {
-			vol->updating = 0;
-			err = to_write;
-			vfree(vol->upd_buf);
-		}
+		vol->updating = 0;
+		err = to_write;
+		vfree(vol->upd_buf);
 	}
 
 	return err;
diff --git a/drivers/net/82596.c b/drivers/net/82596.c
index ea6b139..1663bc9 100644
--- a/drivers/net/82596.c
+++ b/drivers/net/82596.c
@@ -19,7 +19,7 @@
    TBD:
    * look at deferring rx frames rather than discarding (as per tulip)
    * handle tx ring full as per tulip
-   * performace test to tune rx_copybreak
+   * performance test to tune rx_copybreak
 
    Most of my modifications relate to the braindead big-endian
    implementation by Intel.  When the i596 is operating in
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index 4e6359f..766aabf 100644
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -1633,8 +1633,13 @@
 	readl(lp->mmio + CMD7);
 	return 0;
 }
-/* This function is called when a packet transmission fails to complete within a  resonable period, on the assumption that an interrupts have been failed or the  interface is locked up. This function will reinitialize the hardware */
 
+/*
+ * This function is called when a packet transmission fails to complete
+ * within a reasonable period, on the assumption that an interrupt have
+ * failed or the interface is locked up. This function will reinitialize
+ * the hardware.
+ */
 static void amd8111e_tx_timeout(struct net_device *dev)
 {
 	struct amd8111e_priv* lp = netdev_priv(dev);
diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c
index 50cecf4..73b38c2 100644
--- a/drivers/net/appletalk/cops.c
+++ b/drivers/net/appletalk/cops.c
@@ -120,7 +120,7 @@
  *      DAYNA driver mode:
  *              Dayna DL2000/DaynaTalk PC (Half Length), COPS LT-95, 
  *		Farallon PhoneNET PC III, Farallon PhoneNET PC II
- *	Other cards possibly supported mode unkown though:
+ *	Other cards possibly supported mode unknown though:
  *		Dayna DL2000 (Full length), COPS LT/M (Micro-Channel)
  *
  *	Cards NOT supported by this driver but supported by the ltpc.c
diff --git a/drivers/net/ariadne.h b/drivers/net/ariadne.h
index bb613f2..727be5c 100644
--- a/drivers/net/ariadne.h
+++ b/drivers/net/ariadne.h
@@ -244,7 +244,7 @@
 #define DLNKTST		0x0010	/* Disable Link Status */
 #define DAPC		0x0008	/* Disable Automatic Polarity Correction */
 #define MENDECL		0x0004	/* MENDEC Loopback Mode */
-#define LRTTSEL		0x0002	/* Low Receive Treshold/Transmit Mode Select */
+#define LRTTSEL		0x0002	/* Low Receive Threshold/Transmit Mode Select */
 #define PORTSEL1	0x0001	/* Port Select Bits */
 #define PORTSEL2	0x8000	/* Port Select Bits */
 #define INTL		0x4000	/* Internal Loopback */
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c
index 666261b..2f4be59 100644
--- a/drivers/net/atl1c/atl1c_main.c
+++ b/drivers/net/atl1c/atl1c_main.c
@@ -1541,7 +1541,7 @@
 		if (status & ISR_OVER)
 			if (netif_msg_intr(adapter))
 				dev_warn(&pdev->dev,
-					"TX/RX over flow (status = 0x%x)\n",
+					"TX/RX overflow (status = 0x%x)\n",
 					status & ISR_OVER);
 
 		/* link event */
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index e7323be..92b87ef 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -444,7 +444,7 @@
  * filtering capabilities. */
 struct be_cmd_req_if_create {
 	struct be_cmd_req_hdr hdr;
-	u32 version;		/* ignore currntly */
+	u32 version;		/* ignore currently */
 	u32 capability_flags;
 	u32 enable_flags;
 	u8 mac_addr[ETH_ALEN];
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 957a0f7..24c7d99 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -1982,7 +1982,7 @@
 		goto fw_exit;
 	}
 
-	dev_info(&adapter->pdev->dev, "Firmware flashed succesfully\n");
+	dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n");
 
 fw_exit:
 	release_firmware(fw);
diff --git a/drivers/net/bnx2x_reg.h b/drivers/net/bnx2x_reg.h
index b668173..944964e 100644
--- a/drivers/net/bnx2x_reg.h
+++ b/drivers/net/bnx2x_reg.h
@@ -2536,7 +2536,7 @@
 /* [RC 1] A flag to indicate that overflow error occurred in one of the
    queues. */
 #define QM_REG_OVFERROR 					 0x16805c
-/* [RC 7] the Q were the qverflow occurs */
+/* [RC 7] the Q where the overflow occurs */
 #define QM_REG_OVFQNUM						 0x168058
 /* [R 16] Pause state for physical queues 15-0 */
 #define QM_REG_PAUSESTATE0					 0x168410
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 0d30d1e..00ab51e 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -556,7 +556,7 @@
 		}
 	}
 
-	/* do not update the entries again untill this counter is zero so that
+	/* do not update the entries again until this counter is zero so that
 	 * not to confuse the clients.
 	 */
 	bond_info->rlb_update_delay_counter = RLB_UPDATE_DELAY;
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 49f3de7..bdbd147 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -1285,7 +1285,7 @@
 
 	/*
 	 * We do not use Tx completion interrupts to free DMAd Tx packets.
-	 * This is good for performamce but means that we rely on new Tx
+	 * This is good for performance but means that we rely on new Tx
 	 * packets arriving to run the destructors of completed packets,
 	 * which open up space in their sockets' send queues.  Sometimes
 	 * we do not get such new packets causing Tx to stall.  A single
diff --git a/drivers/net/ehea/ehea_ethtool.c b/drivers/net/ehea/ehea_ethtool.c
index d768852..75b099c 100644
--- a/drivers/net/ehea/ehea_ethtool.c
+++ b/drivers/net/ehea/ehea_ethtool.c
@@ -118,7 +118,7 @@
 	ret = ehea_set_portspeed(port, sp);
 
 	if (!ret)
-		ehea_info("%s: Port speed succesfully set: %dMbps "
+		ehea_info("%s: Port speed successfully set: %dMbps "
 			  "%s Duplex",
 			  port->netdev->name, port->port_speed,
 			  port->full_duplex == 1 ? "Full" : "Half");
@@ -134,7 +134,7 @@
 	ret = ehea_set_portspeed(port, EHEA_SPEED_AUTONEG);
 
 	if (!ret)
-		ehea_info("%s: Port speed succesfully set: %dMbps "
+		ehea_info("%s: Port speed successfully set: %dMbps "
 			  "%s Duplex",
 			  port->netdev->name, port->port_speed,
 			  port->full_duplex == 1 ? "Full" : "Half");
diff --git a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c
index ed60fd6..0cab992 100644
--- a/drivers/net/hamradio/baycom_ser_fdx.c
+++ b/drivers/net/hamradio/baycom_ser_fdx.c
@@ -35,7 +35,7 @@
  *          driver only supports standard serial hardware (8250, 16450, 16550A)
  *
  *          This modem usually draws its supply current out of the otherwise unused
- *          TXD pin of the serial port. Thus a contignuous stream of 0x00-bytes
+ *          TXD pin of the serial port. Thus a contiguous stream of 0x00-bytes
  *          is transmitted to achieve a positive supply voltage.
  *
  *  hsk:    This is a 4800 baud FSK modem, designed for TNC use. It works fine
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index 1e8dd8c..8f7d0d1 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -115,7 +115,7 @@
 	unsigned short vendor; /* PCI vendor ID */
 	unsigned short device; /* PCI vendor ID */
 	unsigned short subvendor; /* PCI subsystem vendor ID */
-	unsigned short subdevice; /* PCI sybsystem device ID */
+	unsigned short subdevice; /* PCI subsystem device ID */
 	unsigned short sir_io; /* I/O port for SIR */
 	unsigned short fir_io; /* I/O port for FIR */
 	unsigned char  fir_irq; /* FIR IRQ */
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index 4999719..16c9191 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -1384,7 +1384,7 @@
 	unsigned long done;
 	int i = 1;
 
-	/* FIXME: skbs are continguous in real addresses.  Do we
+	/* FIXME: skbs are contiguous in real addresses.  Do we
 	 * really need to break it into PAGE_SIZE chunks, or can we do
 	 * it just at the granularity of iSeries real->absolute
 	 * mapping?  Indeed, given the way the allocator works, can we
diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c
index a0c5785..b77238d 100644
--- a/drivers/net/lasi_82596.c
+++ b/drivers/net/lasi_82596.c
@@ -47,7 +47,7 @@
    TBD:
    * look at deferring rx frames rather than discarding (as per tulip)
    * handle tx ring full as per tulip
-   * performace test to tune rx_copybreak
+   * performance test to tune rx_copybreak
 
    Most of my modifications relate to the braindead big-endian
    implementation by Intel.  When the i596 is operating in
diff --git a/drivers/net/lib82596.c b/drivers/net/lib82596.c
index 7a07430..b117f7f 100644
--- a/drivers/net/lib82596.c
+++ b/drivers/net/lib82596.c
@@ -47,7 +47,7 @@
    TBD:
    * look at deferring rx frames rather than discarding (as per tulip)
    * handle tx ring full as per tulip
-   * performace test to tune rx_copybreak
+   * performance test to tune rx_copybreak
 
    Most of my modifications relate to the braindead big-endian
    implementation by Intel.  When the i596 is operating in
diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c
index 03b781a..829b9ec 100644
--- a/drivers/net/mlx4/en_rx.c
+++ b/drivers/net/mlx4/en_rx.c
@@ -204,7 +204,7 @@
 		en_dbg(DRV, priv, "Freeing fragment:%d\n", nr);
 		dma = be64_to_cpu(rx_desc->data[nr].addr);
 
-		en_dbg(DRV, priv, "Unmaping buffer at dma:0x%llx\n", (u64) dma);
+		en_dbg(DRV, priv, "Unmapping buffer at dma:0x%llx\n", (u64) dma);
 		pci_unmap_single(mdev->pdev, dma, skb_frags[nr].size,
 				 PCI_DMA_FROMDEVICE);
 		put_page(skb_frags[nr].page);
diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c
index 8c72799..3d1396a 100644
--- a/drivers/net/mlx4/en_tx.c
+++ b/drivers/net/mlx4/en_tx.c
@@ -47,7 +47,7 @@
 static int inline_thold __read_mostly = MAX_INLINE;
 
 module_param_named(inline_thold, inline_thold, int, 0444);
-MODULE_PARM_DESC(inline_thold, "treshold for using inline data");
+MODULE_PARM_DESC(inline_thold, "threshold for using inline data");
 
 int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv,
 			   struct mlx4_en_tx_ring *ring, u32 size,
diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h
index 4376147..82c3ebc 100644
--- a/drivers/net/mlx4/mlx4_en.h
+++ b/drivers/net/mlx4/mlx4_en.h
@@ -162,7 +162,7 @@
 #define MLX4_EN_DEF_RX_PAUSE	1
 #define MLX4_EN_DEF_TX_PAUSE	1
 
-/* Interval between sucessive polls in the Tx routine when polling is used
+/* Interval between successive polls in the Tx routine when polling is used
    instead of interrupts (in per-core Tx rings) - should be power of 2 */
 #define MLX4_EN_TX_POLL_MODER	16
 #define MLX4_EN_TX_POLL_TIMEOUT	(HZ / 4)
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
index 89c4948..0c76859 100644
--- a/drivers/net/ps3_gelic_net.c
+++ b/drivers/net/ps3_gelic_net.c
@@ -314,7 +314,7 @@
  * @card: card structure
  * @descr: descriptor to re-init
  *
- * return 0 on succes, <0 on failure
+ * return 0 on success, <0 on failure
  *
  * allocates a new rx skb, iommu-maps it and attaches it to the descriptor.
  * Activate the descriptor state-wise
diff --git a/drivers/net/ps3_gelic_wireless.h b/drivers/net/ps3_gelic_wireless.h
index 5b631c6..0a88b53 100644
--- a/drivers/net/ps3_gelic_wireless.h
+++ b/drivers/net/ps3_gelic_wireless.h
@@ -199,7 +199,7 @@
 /* for 'stat' member of gelic_wl_info */
 enum gelic_wl_info_status_bit {
 	GELIC_WL_STAT_CONFIGURED,
-	GELIC_WL_STAT_CH_INFO,   /* ch info aquired */
+	GELIC_WL_STAT_CH_INFO,   /* ch info acquired */
 	GELIC_WL_STAT_ESSID_SET, /* ESSID specified by userspace */
 	GELIC_WL_STAT_BSSID_SET, /* BSSID specified by userspace */
 	GELIC_WL_STAT_WPA_PSK_SET, /* PMK specified by userspace */
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index e3e6bc9..dd35066 100644
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -3651,7 +3651,7 @@
 		ql_sem_unlock(qdev, QL_DRVR_SEM_MASK);
 	} else {
 		printk(KERN_ERR PFX
-		       "%s: Could not aquire driver lock.\n",
+		       "%s: Could not acquire driver lock.\n",
 		       ndev->name);
 		goto err_lock;
 	}
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 0dd7839..cc42186 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -3238,7 +3238,7 @@
 
 /**
  *  s2io_chk_xpak_counter - Function to check the status of the xpak counters
- *  @counter      : couter value to be updated
+ *  @counter      : counter value to be updated
  *  @flag         : flag to indicate the status
  *  @type         : counter type
  *  Description:
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index 9a12d88..7360d4b 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -1760,7 +1760,7 @@
 				sis_priv->rx_ring[entry].bufptr, RX_BUF_SIZE,
 				PCI_DMA_FROMDEVICE);
 
-			/* refill the Rx buffer, what if there is not enought
+			/* refill the Rx buffer, what if there is not enough
 			 * memory for new socket buffer ?? */
 			if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) {
 				/*
@@ -1775,7 +1775,7 @@
 			}
 
 			/* This situation should never happen, but due to
-			   some unknow bugs, it is possible that
+			   some unknown bugs, it is possible that
 			   we are working on NULL sk_buff :-( */
 			if (sis_priv->rx_skbuff[entry] == NULL) {
 				if (netif_msg_rx_err(sis_priv))
diff --git a/drivers/net/skfp/h/smc.h b/drivers/net/skfp/h/smc.h
index 1758d95..026a83b 100644
--- a/drivers/net/skfp/h/smc.h
+++ b/drivers/net/skfp/h/smc.h
@@ -393,10 +393,10 @@
 					 */
 	u_long	mac_d_max ;		/* MAC : D_Max timer value */
 
-	u_long lct_short ;		/* LCT : error threshhold */
-	u_long lct_medium ;		/* LCT : error threshhold */
-	u_long lct_long ;		/* LCT : error threshhold */
-	u_long lct_extended ;		/* LCT : error threshhold */
+	u_long lct_short ;		/* LCT : error threshold */
+	u_long lct_medium ;		/* LCT : error threshold */
+	u_long lct_long ;		/* LCT : error threshold */
+	u_long lct_extended ;		/* LCT : error threshold */
 } ;
 
 #ifdef	DEBUG
diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c
index b27156eaf..db216a7 100644
--- a/drivers/net/skfp/skfddi.c
+++ b/drivers/net/skfp/skfddi.c
@@ -1002,7 +1002,7 @@
 		}
 		break;
 	default:
-		printk("ioctl for %s: unknow cmd: %04x\n", dev->name, ioc.cmd);
+		printk("ioctl for %s: unknown cmd: %04x\n", dev->name, ioc.cmd);
 		status = -EOPNOTSUPP;
 
 	}			// switch
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 013c9f5..89a05d6 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -2017,7 +2017,7 @@
 
 	netif_carrier_off(sky2->netdev);
 
-	/* Turn on link LED */
+	/* Turn off link LED */
 	sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
 
 	if (netif_msg_link(sky2))
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index 4d0d5c5..20d6095 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -816,7 +816,7 @@
 	SMSC_TRACE(HW, "Passed Loop Back Test");
 #endif				/* USE_PHY_WORK_AROUND */
 
-	SMSC_TRACE(HW, "phy initialised succesfully");
+	SMSC_TRACE(HW, "phy initialised successfully");
 	return 0;
 }
 
diff --git a/drivers/net/smsc911x.h b/drivers/net/smsc911x.h
index b5716bd..016360c 100644
--- a/drivers/net/smsc911x.h
+++ b/drivers/net/smsc911x.h
@@ -30,7 +30,7 @@
 #define SMSC_NAPI_WEIGHT	16
 
 /* implements a PHY loopback test at initialisation time, to ensure a packet
- * can be succesfully looped back */
+ * can be successfully looped back */
 #define USE_PHY_WORK_AROUND
 
 #define DPRINTK(nlevel, klevel, fmt, args...) \
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index 782910c..2185248 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -410,7 +410,7 @@
  * @card: card structure
  * @descr: descriptor to re-init
  *
- * Return 0 on succes, <0 on failure.
+ * Return 0 on success, <0 on failure.
  *
  * Allocates a new rx skb, iommu-maps it and attaches it to the
  * descriptor. Mark the descriptor as activated, ready-to-use.
diff --git a/drivers/net/stmmac/gmac.c b/drivers/net/stmmac/gmac.c
index b624bb5..52586ee 100644
--- a/drivers/net/stmmac/gmac.c
+++ b/drivers/net/stmmac/gmac.c
@@ -112,7 +112,7 @@
 			      " (threshold = %d)\n", txmode);
 		csr6 &= ~DMA_CONTROL_TSF;
 		csr6 &= DMA_CONTROL_TC_TX_MASK;
-		/* Set the transmit threashold */
+		/* Set the transmit threshold */
 		if (txmode <= 32)
 			csr6 |= DMA_CONTROL_TTC_32;
 		else if (txmode <= 64)
diff --git a/drivers/net/stmmac/gmac.h b/drivers/net/stmmac/gmac.h
index 684a363..2e82d6c 100644
--- a/drivers/net/stmmac/gmac.h
+++ b/drivers/net/stmmac/gmac.h
@@ -154,14 +154,14 @@
 #define DMA_CONTROL_DT		0x04000000 /* Disable Drop TCP/IP csum error */
 #define DMA_CONTROL_RSF		0x02000000 /* Receive Store and Forward */
 #define DMA_CONTROL_DFF		0x01000000 /* Disaable flushing */
-/* Theshold for Activating the FC */
+/* Threshold for Activating the FC */
 enum rfa {
 	act_full_minus_1 = 0x00800000,
 	act_full_minus_2 = 0x00800200,
 	act_full_minus_3 = 0x00800400,
 	act_full_minus_4 = 0x00800600,
 };
-/* Theshold for Deactivating the FC */
+/* Threshold for Deactivating the FC */
 enum rfd {
 	deac_full_minus_1 = 0x00400000,
 	deac_full_minus_2 = 0x00400800,
diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
index 5db0270..66272f2 100644
--- a/drivers/net/tokenring/ibmtr.c
+++ b/drivers/net/tokenring/ibmtr.c
@@ -96,7 +96,7 @@
  *
  *      Change by Mike Sullivan et al.:
  *      + added turbo card support. No need to use lanaid to configure
- *      the adapter into isa compatiblity mode.
+ *      the adapter into isa compatibility mode.
  *
  *      Changes by Burt Silverman to allow the computer to behave nicely when
  *	a cable is pulled or not in place, or a PCMCIA card is removed hot.
diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c
index 427a8970..5401d86 100644
--- a/drivers/net/tokenring/smctr.c
+++ b/drivers/net/tokenring/smctr.c
@@ -426,7 +426,7 @@
         smctr_malloc(dev, 1L);
 
         /* Allocate Non-MAC receive data buffers.
-         * To guarantee a minimum of 256 contigous memory to
+         * To guarantee a minimum of 256 contiguous memory to
          * UM_Receive_Packet's lookahead pointer, before a page
          * change or ring end is encountered, place each rx buffer on
          * a 256 byte boundary.
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 9f44c99..afaf088 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -3798,7 +3798,7 @@
 		prop = of_get_property(np, "tx-clock", NULL);
 		if (!prop) {
 			printk(KERN_ERR
-				"ucc_geth: mising tx-clock-name property\n");
+				"ucc_geth: missing tx-clock-name property\n");
 			return -EINVAL;
 		}
 		if ((*prop < QE_CLK_NONE) || (*prop > QE_CLK24)) {
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h
index 03a6ca0..a007e2a 100644
--- a/drivers/net/ucc_geth.h
+++ b/drivers/net/ucc_geth.h
@@ -80,16 +80,16 @@
 				   frames) received that were between 128
 				   (Including FCS length==4) and 255 octets */
 	u32 txok;		/* Total number of octets residing in frames
-				   that where involved in succesfull
+				   that where involved in successfull
 				   transmission */
 	u16 txcf;		/* Total number of PAUSE control frames
 				   transmitted by this MAC */
 	u8 res4[0x2];
 	u32 tmca;		/* Total number of frames that were transmitted
-				   succesfully with the group address bit set
+				   successfully with the group address bit set
 				   that are not broadcast frames */
 	u32 tbca;		/* Total number of frames transmitted
-				   succesfully that had destination address
+				   successfully that had destination address
 				   field equal to the broadcast address */
 	u32 rxfok;		/* Total number of frames received OK */
 	u32 rxbok;		/* Total number of octets received OK */
@@ -98,9 +98,9 @@
 				   HW because it includes octets in frames that
 				   never even reach the UCC */
 	u32 rmca;		/* Total number of frames that were received
-				   succesfully with the group address bit set
+				   successfully with the group address bit set
 				   that are not broadcast frames */
-	u32 rbca;		/* Total number of frames received succesfully
+	u32 rbca;		/* Total number of frames received successfully
 				   that had destination address equal to the
 				   broadcast address */
 	u32 scar;		/* Statistics carry register */
@@ -759,15 +759,15 @@
 				   frames) received that were between 128
 				   (Including FCS length==4) and 255 octets */
 	u32 txok;		/* Total number of octets residing in frames
-				   that where involved in succesfull
+				   that where involved in successfull
 				   transmission */
 	u16 txcf;		/* Total number of PAUSE control frames
 				   transmitted by this MAC */
 	u32 tmca;		/* Total number of frames that were transmitted
-				   succesfully with the group address bit set
+				   successfully with the group address bit set
 				   that are not broadcast frames */
 	u32 tbca;		/* Total number of frames transmitted
-				   succesfully that had destination address
+				   successfully that had destination address
 				   field equal to the broadcast address */
 	u32 rxfok;		/* Total number of frames received OK */
 	u32 rxbok;		/* Total number of octets received OK */
@@ -776,9 +776,9 @@
 				   HW because it includes octets in frames that
 				   never even reach the UCC */
 	u32 rmca;		/* Total number of frames that were received
-				   succesfully with the group address bit set
+				   successfully with the group address bit set
 				   that are not broadcast frames */
-	u32 rbca;		/* Total number of frames received succesfully
+	u32 rbca;		/* Total number of frames received successfully
 				   that had destination address equal to the
 				   broadcast address */
 } __attribute__ ((packed));
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index c6c9222..0c3c738 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -748,7 +748,7 @@
 	mii_nway_restart(&dev->mii);
 
 	if (netif_msg_ifup(dev))
-		devdbg(dev, "phy initialised succesfully");
+		devdbg(dev, "phy initialised successfully");
 	return 0;
 }
 
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index a7d4fc1..0e52993 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -182,7 +182,7 @@
 		if (pvc->dlci == dlci)
 			return pvc;
 		if (pvc->dlci > dlci)
-			return NULL; /* the listed is sorted */
+			return NULL; /* the list is sorted */
 		pvc = pvc->next;
 	}
 
diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
index 2ebe935..4b6f27e 100644
--- a/drivers/net/wan/lmc/lmc_main.c
+++ b/drivers/net/wan/lmc/lmc_main.c
@@ -927,7 +927,7 @@
         sc->lmc_media = &lmc_t1_media;
         break;
     default:
-	printk(KERN_WARNING "%s: LMC UNKOWN CARD!\n", dev->name);
+	printk(KERN_WARNING "%s: LMC UNKNOWN CARD!\n", dev->name);
         break;
     }
 
diff --git a/drivers/net/wimax/i2400m/rx.c b/drivers/net/wimax/i2400m/rx.c
index e3d2a9d..7ddb173 100644
--- a/drivers/net/wimax/i2400m/rx.c
+++ b/drivers/net/wimax/i2400m/rx.c
@@ -1194,7 +1194,7 @@
  * device. See the file header for the format. Run all checks on the
  * buffer header, then run over each payload's descriptors, verify
  * their consistency and act on each payload's contents.  If
- * everything is succesful, update the device's statistics.
+ * everything is successful, update the device's statistics.
  *
  * Note: You need to set the skb to contain only the length of the
  * received buffer; for that, use skb_trim(skb, RECEIVED_SIZE).
diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c
index 47e84ef..3b48681 100644
--- a/drivers/net/wimax/i2400m/usb.c
+++ b/drivers/net/wimax/i2400m/usb.c
@@ -579,7 +579,7 @@
  *
  *    As well, the device might refuse going to sleep for whichever
  *    reason. In this case we just fail. For system suspend/hibernate,
- *    we *can't* fail. We look at usb_dev->auto_pm to see if the
+ *    we *can't* fail. We check PM_EVENT_AUTO to see if the
  *    suspend call comes from the USB stack or from the system and act
  *    in consequence.
  *
@@ -591,14 +591,11 @@
 	int result = 0;
 	struct device *dev = &iface->dev;
 	struct i2400mu *i2400mu = usb_get_intfdata(iface);
-#ifdef CONFIG_PM
-	struct usb_device *usb_dev = i2400mu->usb_dev;
-#endif
 	unsigned is_autosuspend = 0;
 	struct i2400m *i2400m = &i2400mu->i2400m;
 
 #ifdef CONFIG_PM
-	if (usb_dev->auto_pm > 0)
+	if (pm_msg.event & PM_EVENT_AUTO)
 		is_autosuspend = 1;
 #endif
 
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index b72338c..952b3a2 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -36,7 +36,7 @@
  */
 
 /*
- * Defintions for the Atheros Wireless LAN controller driver.
+ * Definitions for the Atheros Wireless LAN controller driver.
  */
 #ifndef _DEV_ATH_ATHVAR_H
 #define _DEV_ATH_ATHVAR_H
@@ -190,7 +190,7 @@
 	struct ath5k_txq	*cabq;		/* content after beacon */
 
 	int 			power_level;	/* Requested tx power in dbm */
-	bool			assoc;		/* assocate state */
+	bool			assoc;		/* associate state */
 	bool			enable_beacon;	/* true if beacons are on */
 };
 
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index 7918852..5d1c867 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -1491,7 +1491,7 @@
  * This info is used to calibrate the baseband power table. Imagine
  * that for each channel there is a power curve that's hw specific
  * (depends on amplifier etc) and we try to "correct" this curve using
- * offests we pass on to phy chip (baseband -> before amplifier) so that
+ * offsets we pass on to phy chip (baseband -> before amplifier) so that
  * it can use accurate power values when setting tx power (takes amplifier's
  * performance on each channel into account).
  *
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index bbfdcd5..72474c0 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -117,7 +117,7 @@
 
 /*
  * This code is used to optimize rf gain on different environments
- * (temprature mostly) based on feedback from a power detector.
+ * (temperature mostly) based on feedback from a power detector.
  *
  * It's only used on RF5111 and RF5112, later RF chips seem to have
  * auto adjustment on hw -notice they have a much smaller BANK 7 and
@@ -2746,7 +2746,7 @@
 		/* Fill curves in reverse order
 		 * from lower power (max gain)
 		 * to higher power. Use curve -> idx
-		 * backmaping we did on eeprom init */
+		 * backmapping we did on eeprom init */
 		u8 idx = pdg_curve_to_idx[pdg];
 
 		/* Grab the needed curves by index */
@@ -2848,7 +2848,7 @@
 	/* Now we have a set of curves for this
 	 * channel on tmpL (x range is table_max - table_min
 	 * and y values are tmpL[pdg][]) sorted in the same
-	 * order as EEPROM (because we've used the backmaping).
+	 * order as EEPROM (because we've used the backmapping).
 	 * So for RF5112 it's from higher power to lower power
 	 * and for RF2413 it's from lower power to higher power.
 	 * For RF5111 we only have one curve. */
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index c915954..70fdb9d 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -880,7 +880,7 @@
 				 * Since this probe succeeded, we allow the next
 				 * probe twice as soon.  This allows the maxRate
 				 * to move up faster if the probes are
-				 * succesful.
+				 * successful.
 				 */
 				ath_rc_priv->probe_time =
 					now_msec - rate_table->probe_interval / 2;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 19b4eae..4c41cfe 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -2958,7 +2958,7 @@
 /* Periodic work locking policy:
  * 	The whole periodic work handler is protected by
  * 	wl->mutex. If another lock is needed somewhere in the
- * 	pwork callchain, it's aquired in-place, where it's needed.
+ * 	pwork callchain, it's acquired in-place, where it's needed.
  */
 static void b43_periodic_work_handler(struct work_struct *work)
 {
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index ab6a18c..4a905b6 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -2277,7 +2277,7 @@
 /* Periodic work locking policy:
  * 	The whole periodic work handler is protected by
  * 	wl->mutex. If another lock is needed somewhere in the
- * 	pwork callchain, it's aquired in-place, where it's needed.
+ * 	pwork callchain, it's acquired in-place, where it's needed.
  */
 static void b43legacy_periodic_work_handler(struct work_struct *work)
 {
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 17a9cb3..56afcf0 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -578,7 +578,7 @@
 		/* get number of entries */
 		field_count = *(((u16 *) & field_info) + 1);
 
-		/* abort if no enought memory */
+		/* abort if no enough memory */
 		total_length = field_len * field_count;
 		if (total_length > *len) {
 			*len = total_length;
@@ -3127,7 +3127,7 @@
 			     IPW_MAX_BDS)) {
 			/* TODO: Support merging buffers if more than
 			 * IPW_MAX_BDS are used */
-			IPW_DEBUG_INFO("%s: Maximum BD theshold exceeded.  "
+			IPW_DEBUG_INFO("%s: Maximum BD threshold exceeded.  "
 				       "Increase fragmentation level.\n",
 				       priv->net_dev->name);
 		}
@@ -6897,7 +6897,7 @@
 	range->max_qual.updated = 7;	/* Updated all three */
 
 	range->avg_qual.qual = 70;	/* > 8% missed beacons is 'bad' */
-	/* TODO: Find real 'good' to 'bad' threshol value for RSSI */
+	/* TODO: Find real 'good' to 'bad' threshold value for RSSI */
 	range->avg_qual.level = 20 + IPW2100_RSSI_TO_DBM;
 	range->avg_qual.noise = 0;
 	range->avg_qual.updated = 7;	/* Updated all three */
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index c28984a..09ddd3e 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -792,7 +792,7 @@
 		/* get number of entries */
 		field_count = *(((u16 *) & field_info) + 1);
 
-		/* abort if not enought memory */
+		/* abort if not enough memory */
 		total_len = field_len * field_count;
 		if (total_len > *len) {
 			*len = total_len;
@@ -7760,7 +7760,7 @@
 	case SEC_LEVEL_0:
 		break;
 	default:
-		printk(KERN_ERR "Unknow security level %d\n",
+		printk(KERN_ERR "Unknown security level %d\n",
 		       priv->ieee->sec.level);
 		break;
 	}
@@ -8926,7 +8926,7 @@
 	range->max_qual.updated = 7;	/* Updated all three */
 
 	range->avg_qual.qual = 70;
-	/* TODO: Find real 'good' to 'bad' threshol value for RSSI */
+	/* TODO: Find real 'good' to 'bad' threshold value for RSSI */
 	range->avg_qual.level = 0;	/* FIXME to real average level */
 	range->avg_qual.noise = 0;
 	range->avg_qual.updated = 7;	/* Updated all three */
@@ -10299,7 +10299,7 @@
 		case SEC_LEVEL_0:
 			break;
 		default:
-			printk(KERN_ERR "Unknow security level %d\n",
+			printk(KERN_ERR "Unknown security level %d\n",
 			       priv->ieee->sec.level);
 			break;
 		}
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c
index bf21eb3..1ae0b2b 100644
--- a/drivers/net/wireless/ipw2x00/libipw_module.c
+++ b/drivers/net/wireless/ipw2x00/libipw_module.c
@@ -199,7 +199,7 @@
 	ieee->host_decrypt = 1;
 	ieee->host_mc_decrypt = 1;
 
-	/* Host fragementation in Open mode. Default is enabled.
+	/* Host fragmentation in Open mode. Default is enabled.
 	 * Note: host fragmentation is always enabled if host encryption
 	 * is enabled. For cards can do hardware encryption, they must do
 	 * hardware fragmentation as well. So we don't need a variable
diff --git a/drivers/net/wireless/iwmc3200wifi/hal.c b/drivers/net/wireless/iwmc3200wifi/hal.c
index c430418..d13c885 100644
--- a/drivers/net/wireless/iwmc3200wifi/hal.c
+++ b/drivers/net/wireless/iwmc3200wifi/hal.c
@@ -411,7 +411,7 @@
 /*
  * iwm_hal_send_host_cmd(): sends commands to the UMAC or the LMAC.
  * Sending command to the LMAC is equivalent to sending a
- * regular UMAC command with the LMAC passtrough or the LMAC
+ * regular UMAC command with the LMAC passthrough or the LMAC
  * wrapper UMAC command IDs.
  */
 int iwm_hal_send_host_cmd(struct iwm_priv *iwm,
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 72c27a3e..1c57c1f 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -1578,7 +1578,7 @@
 		kfree_skb(packet->skb);
 		break;
 	default:
-		IWM_ERR(iwm, "Unknow ticket action: %d\n",
+		IWM_ERR(iwm, "Unknown ticket action: %d\n",
 			le16_to_cpu(ticket_node->ticket->action));
 		kfree_skb(packet->skb);
 	}
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 09fcfad..7a73f62 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -993,7 +993,7 @@
 	}
 
 	if (i == ARRAY_SIZE(if_sdio_models)) {
-		lbs_pr_err("unkown card model 0x%x\n", card->model);
+		lbs_pr_err("unknown card model 0x%x\n", card->model);
 		ret = -ENODEV;
 		goto free;
 	}
diff --git a/drivers/net/wireless/orinoco/hermes_dld.c b/drivers/net/wireless/orinoco/hermes_dld.c
index 6d5660d..fb157eb 100644
--- a/drivers/net/wireless/orinoco/hermes_dld.c
+++ b/drivers/net/wireless/orinoco/hermes_dld.c
@@ -550,7 +550,7 @@
 
 #define DEFAULT_PDR(pid) default_pdr_data_##pid
 
-/*  HWIF Compatiblity */
+/*  HWIF Compatibility */
 DEFINE_DEFAULT_PDR(0x0005, 10, "\x00\x00\x06\x00\x01\x00\x01\x00\x01\x00");
 
 /* PPPPSign */
@@ -656,7 +656,7 @@
 					 record_id + 1, pdi);
 			}
 			break;
-		case 0x5: /*  HWIF Compatiblity */
+		case 0x5: /*  HWIF Compatibility */
 			default_pdi = (struct pdi *) &DEFAULT_PDR(0x0005);
 			break;
 		case 0x108: /* PPPPSign */
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index bc08464..f7f5c79 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -1897,7 +1897,7 @@
 	return 0;
 }
 
-/* Setting policy also clears the MAC acl, even if we don't change the defaut
+/* Setting policy also clears the MAC acl, even if we don't change the default
  * policy
  */
 
@@ -2323,7 +2323,7 @@
 
 	case DOT11_OID_BEACON:
 		send_formatted_event(priv,
-				     "Received a beacon from an unkown AP",
+				     "Received a beacon from an unknown AP",
 				     mlme, 0);
 		break;
 
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h
index 6c21ef6..c3dea69 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.h
+++ b/drivers/net/wireless/rt2x00/rt2400pci.h
@@ -35,7 +35,7 @@
 
 /*
  * Signal information.
- * Defaul offset is required for RSSI <-> dBm conversion.
+ * Default offset is required for RSSI <-> dBm conversion.
  */
 #define DEFAULT_RSSI_OFFSET		100
 
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h
index b007567..c6bd1fc 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.h
+++ b/drivers/net/wireless/rt2x00/rt2500pci.h
@@ -46,7 +46,7 @@
 
 /*
  * Signal information.
- * Defaul offset is required for RSSI <-> dBm conversion.
+ * Default offset is required for RSSI <-> dBm conversion.
  */
 #define DEFAULT_RSSI_OFFSET		121
 
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h
index 341a704..b493306 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.h
+++ b/drivers/net/wireless/rt2x00/rt2500usb.h
@@ -46,7 +46,7 @@
 
 /*
  * Signal information.
- * Defaul offset is required for RSSI <-> dBm conversion.
+ * Default offset is required for RSSI <-> dBm conversion.
  */
 #define DEFAULT_RSSI_OFFSET		120
 
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index 6f33f7f..8f13810 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -37,7 +37,7 @@
 
 /*
  * Signal information.
- * Defaul offset is required for RSSI <-> dBm conversion.
+ * Default offset is required for RSSI <-> dBm conversion.
  */
 #define DEFAULT_RSSI_OFFSET		120
 
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index e783a09..7942f81 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -37,7 +37,7 @@
 
 /*
  * Signal information.
- * Defaul offset is required for RSSI <-> dBm conversion.
+ * Default offset is required for RSSI <-> dBm conversion.
  */
 #define DEFAULT_RSSI_OFFSET		120
 
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 8a24373..cf51e8f 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -374,7 +374,7 @@
  * zd_mac_tx_failed - callback for failed frames
  * @dev: the mac80211 wireless device
  *
- * This function is called if a frame couldn't be succesfully be
+ * This function is called if a frame couldn't be successfully be
  * transferred. The first frame from the tx queue, will be selected and
  * reported as error to the upper layers.
  */
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index baa051d..a869b45 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -42,6 +42,7 @@
 #include <linux/mm.h>
 #include <net/ip.h>
 
+#include <xen/xen.h>
 #include <xen/xenbus.h>
 #include <xen/events.h>
 #include <xen/page.h>
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index a6b4a5a..f511e70 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -650,7 +650,7 @@
  * Mark the I/O Pdir entries invalid and blow away the corresponding I/O
  * TLB entries.
  *
- * FIXME: at some threshhold it might be "cheaper" to just blow
+ * FIXME: at some threshold it might be "cheaper" to just blow
  *        away the entire I/O TLB instead of individual entries.
  *
  * FIXME: Uturn has 256 TLB entries. We don't need to purge every
diff --git a/drivers/parisc/eisa_eeprom.c b/drivers/parisc/eisa_eeprom.c
index 8c0b26e9..cce00ed 100644
--- a/drivers/parisc/eisa_eeprom.c
+++ b/drivers/parisc/eisa_eeprom.c
@@ -75,17 +75,8 @@
 	return ret;
 }
 
-static int eisa_eeprom_ioctl(struct inode *inode, struct file *file, 
-			   unsigned int cmd,
-			   unsigned long arg)
-{
-	return -ENOTTY;
-}
-
 static int eisa_eeprom_open(struct inode *inode, struct file *file)
 {
-	cycle_kernel_lock();
-
 	if (file->f_mode & FMODE_WRITE)
 		return -EINVAL;
    
@@ -104,7 +95,6 @@
 	.owner =	THIS_MODULE,
 	.llseek =	eisa_eeprom_llseek,
 	.read =		eisa_eeprom_read,
-	.ioctl =	eisa_eeprom_ioctl,
 	.open =		eisa_eeprom_open,
 	.release =	eisa_eeprom_release,
 };
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index fdc864f..b1ecefa 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -27,10 +27,10 @@
 	default y
 	help
 	  Say Y here if you want to include support for the deprecated
-	  pci_find_slot() and pci_find_device() APIs.  Most drivers have
-	  been converted over to using the proper hotplug APIs, so this
-	  option serves to include/exclude only a few drivers that are
-	  still using this API.
+	  pci_find_device() API.  Most drivers have been converted over
+	  to using the proper hotplug APIs, so this option serves to
+	  include/exclude only a few drivers that are still using this
+	  API.
 
 config PCI_DEBUG
 	bool "PCI Debugging"
@@ -69,3 +69,10 @@
 	  physical resources.
 
 	  If unsure, say N.
+
+config PCI_IOAPIC
+	bool
+	depends on PCI
+	depends on ACPI
+	depends on HOTPLUG
+	default y
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 4a7f11d..4df48d5 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -14,6 +14,8 @@
 # Build PCI Express stuff if needed
 obj-$(CONFIG_PCIEPORTBUS) += pcie/
 
+obj-$(CONFIG_PCI_IOAPIC) += ioapic.o
+
 obj-$(CONFIG_HOTPLUG) += hotplug.o
 
 # Build the PCI Hotplug drivers if we were asked to
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 416f6ac..6cdc931 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -320,7 +320,7 @@
 	for (bus = dev->bus; bus; bus = bus->parent) {
 		struct pci_dev *bridge = bus->self;
 
-		if (!bridge || !bridge->is_pcie ||
+		if (!bridge || !pci_is_pcie(bridge) ||
 		    bridge->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE)
 			return 0;
 
@@ -645,8 +645,11 @@
 			       "x2apic and Intr-remapping.\n");
 #endif
 #ifdef CONFIG_DMAR
-		if (ret && !no_iommu && !iommu_detected && !dmar_disabled)
+		if (ret && !no_iommu && !iommu_detected && !dmar_disabled) {
 			iommu_detected = 1;
+			/* Make sure ACS will be enabled */
+			pci_request_acs();
+		}
 #endif
 #ifdef CONFIG_X86
 		if (ret)
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile
index 3625b09..6cd9f3c 100644
--- a/drivers/pci/hotplug/Makefile
+++ b/drivers/pci/hotplug/Makefile
@@ -6,18 +6,22 @@
 obj-$(CONFIG_HOTPLUG_PCI_COMPAQ)	+= cpqphp.o
 obj-$(CONFIG_HOTPLUG_PCI_IBM)		+= ibmphp.o
 
-# pciehp should be linked before acpiphp in order to allow the native driver
-# to attempt to bind first. We can then fall back to generic support.
+# native drivers should be linked before acpiphp in order to allow the
+# native driver to attempt to bind first. We can then fall back to
+# generic support.
 
 obj-$(CONFIG_HOTPLUG_PCI_PCIE)		+= pciehp.o
-obj-$(CONFIG_HOTPLUG_PCI_ACPI)		+= acpiphp.o
-obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM)	+= acpiphp_ibm.o
 obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550)	+= cpcihp_zt5550.o
 obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC)	+= cpcihp_generic.o
 obj-$(CONFIG_HOTPLUG_PCI_SHPC)		+= shpchp.o
 obj-$(CONFIG_HOTPLUG_PCI_RPA)		+= rpaphp.o
 obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR)	+= rpadlpar_io.o
 obj-$(CONFIG_HOTPLUG_PCI_SGI)		+= sgi_hotplug.o
+obj-$(CONFIG_HOTPLUG_PCI_ACPI)		+= acpiphp.o
+
+# acpiphp_ibm extends acpiphp, so should be linked afterwards.
+
+obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM)	+= acpiphp_ibm.o
 
 # Link this last so it doesn't claim devices that have a real hotplug driver
 obj-$(CONFIG_HOTPLUG_PCI_FAKE)		+= fakephp.o
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c
index a73028e..3c76fc6 100644
--- a/drivers/pci/hotplug/acpi_pcihp.c
+++ b/drivers/pci/hotplug/acpi_pcihp.c
@@ -362,6 +362,8 @@
 		status = acpi_pci_osc_control_set(handle, flags);
 		if (ACPI_SUCCESS(status))
 			goto got_one;
+		if (status == AE_SUPPORT)
+			goto no_control;
 		kfree(string.pointer);
 		string = (struct acpi_buffer){ ACPI_ALLOCATE_BUFFER, NULL };
 	}
@@ -394,10 +396,9 @@
 		if (ACPI_FAILURE(status))
 			break;
 	}
-
+no_control:
 	dbg("Cannot get control of hotplug hardware for pci %s\n",
 	    pci_name(pdev));
-
 	kfree(string.pointer);
 	return -ENODEV;
 got_one:
@@ -471,7 +472,7 @@
 		return found;
 
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
-			    check_hotplug, (void *)&found, NULL);
+			    check_hotplug, NULL, (void *)&found, NULL);
 	return found;
 }
 EXPORT_SYMBOL_GPL(acpi_pci_detect_ejectable);
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index 7d938df..bab5204 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -146,12 +146,6 @@
 	struct module *owner;
 };
 
-struct acpiphp_ioapic {
-	struct pci_dev *dev;
-	u32 gsi_base;
-	struct list_head list;
-};
-
 /* PCI bus bridge HID */
 #define ACPI_PCI_HOST_HID		"PNP0A03"
 
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 58d25a1..8e952fd 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -52,8 +52,6 @@
 #include "acpiphp.h"
 
 static LIST_HEAD(bridge_list);
-static LIST_HEAD(ioapic_list);
-static DEFINE_SPINLOCK(ioapic_list_lock);
 
 #define MY_NAME "acpiphp_glue"
 
@@ -266,7 +264,7 @@
 	int found = acpi_pci_detect_ejectable(handle);
 	if (!found) {
 		acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				    is_pci_dock_device, (void *)&found, NULL);
+				    is_pci_dock_device, NULL, (void *)&found, NULL);
 	}
 	return found;
 }
@@ -281,7 +279,7 @@
 
 	/* register all slot objects under this bridge */
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1,
-				     register_slot, bridge, NULL);
+				     register_slot, NULL, bridge, NULL);
 	if (ACPI_FAILURE(status)) {
 		list_del(&bridge->list);
 		return;
@@ -311,17 +309,13 @@
 /* find acpiphp_func from acpiphp_bridge */
 static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle)
 {
-	struct list_head *node, *l;
 	struct acpiphp_bridge *bridge;
 	struct acpiphp_slot *slot;
 	struct acpiphp_func *func;
 
-	list_for_each(node, &bridge_list) {
-		bridge = list_entry(node, struct acpiphp_bridge, list);
+	list_for_each_entry(bridge, &bridge_list, list) {
 		for (slot = bridge->slots; slot; slot = slot->next) {
-			list_for_each(l, &slot->funcs) {
-				func = list_entry(l, struct acpiphp_func,
-							sibling);
+			list_for_each_entry(func, &slot->funcs, sibling) {
 				if (func->handle == handle)
 					return func;
 			}
@@ -447,7 +441,7 @@
 
 	/* search P2P bridges under this p2p bridge */
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				     find_p2p_bridge, NULL, NULL);
+				     find_p2p_bridge, NULL, NULL, NULL);
 	if (ACPI_FAILURE(status))
 		warn("find_p2p_bridge failed (error code = 0x%x)\n", status);
 
@@ -485,7 +479,7 @@
 
 	/* search P2P bridges under this host bridge */
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				     find_p2p_bridge, NULL, NULL);
+				     find_p2p_bridge, NULL, NULL, NULL);
 
 	if (ACPI_FAILURE(status))
 		warn("find_p2p_bridge failed (error code = 0x%x)\n", status);
@@ -495,21 +489,19 @@
 
 static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle)
 {
-	struct list_head *head;
-	list_for_each(head, &bridge_list) {
-		struct acpiphp_bridge *bridge = list_entry(head,
-						struct acpiphp_bridge, list);
+	struct acpiphp_bridge *bridge;
+
+	list_for_each_entry(bridge, &bridge_list, list)
 		if (bridge->handle == handle)
 			return bridge;
-	}
 
 	return NULL;
 }
 
 static void cleanup_bridge(struct acpiphp_bridge *bridge)
 {
-	struct list_head *list, *tmp;
-	struct acpiphp_slot *slot;
+	struct acpiphp_slot *slot, *next;
+	struct acpiphp_func *func, *tmp;
 	acpi_status status;
 	acpi_handle handle = bridge->handle;
 
@@ -530,10 +522,8 @@
 
 	slot = bridge->slots;
 	while (slot) {
-		struct acpiphp_slot *next = slot->next;
-		list_for_each_safe (list, tmp, &slot->funcs) {
-			struct acpiphp_func *func;
-			func = list_entry(list, struct acpiphp_func, sibling);
+		next = slot->next;
+		list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) {
 			if (is_dock_device(func->handle)) {
 				unregister_hotplug_dock_device(func->handle);
 				unregister_dock_notifier(&func->nb);
@@ -545,7 +535,7 @@
 				if (ACPI_FAILURE(status))
 					err("failed to remove notify handler\n");
 			}
-			list_del(list);
+			list_del(&func->sibling);
 			kfree(func);
 		}
 		acpiphp_unregister_hotplug_slot(slot);
@@ -573,7 +563,7 @@
 	/* cleanup p2p bridges under this P2P bridge
 	   in a depth-first manner */
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				cleanup_p2p_bridge, NULL, NULL);
+				cleanup_p2p_bridge, NULL, NULL, NULL);
 
 	bridge = acpiphp_handle_to_bridge(handle);
 	if (bridge)
@@ -589,7 +579,7 @@
 	/* cleanup p2p bridges under this host bridge
 	   in a depth-first manner */
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
-				(u32)1, cleanup_p2p_bridge, NULL, NULL);
+				(u32)1, cleanup_p2p_bridge, NULL, NULL, NULL);
 
 	/*
 	 * On root bridges with hotplug slots directly underneath (ie,
@@ -606,204 +596,17 @@
 					   handle_hotplug_event_bridge);
 }
 
-static struct pci_dev * get_apic_pci_info(acpi_handle handle)
-{
-	struct pci_dev *dev;
-
-	dev = acpi_get_pci_dev(handle);
-	if (!dev)
-		return NULL;
-
-	if ((dev->class != PCI_CLASS_SYSTEM_PIC_IOAPIC) &&
-	    (dev->class != PCI_CLASS_SYSTEM_PIC_IOXAPIC))
-	{
-		pci_dev_put(dev);
-		return NULL;
-	}
-
-	return dev;
-}
-
-static int get_gsi_base(acpi_handle handle, u32 *gsi_base)
-{
-	acpi_status status;
-	int result = -1;
-	unsigned long long gsb;
-	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
-	union acpi_object *obj;
-	void *table;
-
-	status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb);
-	if (ACPI_SUCCESS(status)) {
-		*gsi_base = (u32)gsb;
-		return 0;
-	}
-
-	status = acpi_evaluate_object(handle, "_MAT", NULL, &buffer);
-	if (ACPI_FAILURE(status) || !buffer.length || !buffer.pointer)
-		return -1;
-
-	obj = buffer.pointer;
-	if (obj->type != ACPI_TYPE_BUFFER)
-		goto out;
-
-	table = obj->buffer.pointer;
-	switch (((struct acpi_subtable_header *)table)->type) {
-	case ACPI_MADT_TYPE_IO_SAPIC:
-		*gsi_base = ((struct acpi_madt_io_sapic *)table)->global_irq_base;
-		result = 0;
-		break;
-	case ACPI_MADT_TYPE_IO_APIC:
-		*gsi_base = ((struct acpi_madt_io_apic *)table)->global_irq_base;
-		result = 0;
-		break;
-	default:
-		break;
-	}
- out:
-	kfree(buffer.pointer);
-	return result;
-}
-
-static acpi_status
-ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
-	acpi_status status;
-	unsigned long long sta;
-	acpi_handle tmp;
-	struct pci_dev *pdev;
-	u32 gsi_base;
-	u64 phys_addr;
-	struct acpiphp_ioapic *ioapic;
-
-	/* Evaluate _STA if present */
-	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
-	if (ACPI_SUCCESS(status) && sta != ACPI_STA_ALL)
-		return AE_CTRL_DEPTH;
-
-	/* Scan only PCI bus scope */
-	status = acpi_get_handle(handle, "_HID", &tmp);
-	if (ACPI_SUCCESS(status))
-		return AE_CTRL_DEPTH;
-
-	if (get_gsi_base(handle, &gsi_base))
-		return AE_OK;
-
-	ioapic = kmalloc(sizeof(*ioapic), GFP_KERNEL);
-	if (!ioapic)
-		return AE_NO_MEMORY;
-
-	pdev = get_apic_pci_info(handle);
-	if (!pdev)
-		goto exit_kfree;
-
-	if (pci_enable_device(pdev))
-		goto exit_pci_dev_put;
-
-	pci_set_master(pdev);
-
-	if (pci_request_region(pdev, 0, "I/O APIC(acpiphp)"))
-		goto exit_pci_disable_device;
-
-	phys_addr = pci_resource_start(pdev, 0);
-	if (acpi_register_ioapic(handle, phys_addr, gsi_base))
-		goto exit_pci_release_region;
-
-	ioapic->gsi_base = gsi_base;
-	ioapic->dev = pdev;
-	spin_lock(&ioapic_list_lock);
-	list_add_tail(&ioapic->list, &ioapic_list);
-	spin_unlock(&ioapic_list_lock);
-
-	return AE_OK;
-
- exit_pci_release_region:
-	pci_release_region(pdev, 0);
- exit_pci_disable_device:
-	pci_disable_device(pdev);
- exit_pci_dev_put:
-	pci_dev_put(pdev);
- exit_kfree:
-	kfree(ioapic);
-
-	return AE_OK;
-}
-
-static acpi_status
-ioapic_remove(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
-	acpi_status status;
-	unsigned long long sta;
-	acpi_handle tmp;
-	u32 gsi_base;
-	struct acpiphp_ioapic *pos, *n, *ioapic = NULL;
-
-	/* Evaluate _STA if present */
-	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
-	if (ACPI_SUCCESS(status) && sta != ACPI_STA_ALL)
-		return AE_CTRL_DEPTH;
-
-	/* Scan only PCI bus scope */
-	status = acpi_get_handle(handle, "_HID", &tmp);
-	if (ACPI_SUCCESS(status))
-		return AE_CTRL_DEPTH;
-
-	if (get_gsi_base(handle, &gsi_base))
-		return AE_OK;
-
-	acpi_unregister_ioapic(handle, gsi_base);
-
-	spin_lock(&ioapic_list_lock);
-	list_for_each_entry_safe(pos, n, &ioapic_list, list) {
-		if (pos->gsi_base != gsi_base)
-			continue;
-		ioapic = pos;
-		list_del(&ioapic->list);
-		break;
-	}
-	spin_unlock(&ioapic_list_lock);
-
-	if (!ioapic)
-		return AE_OK;
-
-	pci_release_region(ioapic->dev, 0);
-	pci_disable_device(ioapic->dev);
-	pci_dev_put(ioapic->dev);
-	kfree(ioapic);
-
-	return AE_OK;
-}
-
-static int acpiphp_configure_ioapics(acpi_handle handle)
-{
-	ioapic_add(handle, 0, NULL, NULL);
-	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
-			    ACPI_UINT32_MAX, ioapic_add, NULL, NULL);
-	return 0;
-}
-
-static int acpiphp_unconfigure_ioapics(acpi_handle handle)
-{
-	ioapic_remove(handle, 0, NULL, NULL);
-	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
-			    ACPI_UINT32_MAX, ioapic_remove, NULL, NULL);
-	return 0;
-}
-
 static int power_on_slot(struct acpiphp_slot *slot)
 {
 	acpi_status status;
 	struct acpiphp_func *func;
-	struct list_head *l;
 	int retval = 0;
 
 	/* if already enabled, just skip */
 	if (slot->flags & SLOT_POWEREDON)
 		goto err_exit;
 
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
-
+	list_for_each_entry(func, &slot->funcs, sibling) {
 		if (func->flags & FUNC_HAS_PS0) {
 			dbg("%s: executing _PS0\n", __func__);
 			status = acpi_evaluate_object(func->handle, "_PS0", NULL, NULL);
@@ -829,7 +632,6 @@
 {
 	acpi_status status;
 	struct acpiphp_func *func;
-	struct list_head *l;
 
 	int retval = 0;
 
@@ -837,9 +639,7 @@
 	if ((slot->flags & SLOT_POWEREDON) == 0)
 		goto err_exit;
 
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
-
+	list_for_each_entry(func, &slot->funcs, sibling) {
 		if (func->flags & FUNC_HAS_PS3) {
 			status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL);
 			if (ACPI_FAILURE(status)) {
@@ -966,7 +766,6 @@
 {
 	struct pci_dev *dev;
 	struct pci_bus *bus = slot->bridge->pci_bus;
-	struct list_head *l;
 	struct acpiphp_func *func;
 	int retval = 0;
 	int num, max, pass;
@@ -1006,21 +805,16 @@
 		}
 	}
 
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
+	list_for_each_entry(func, &slot->funcs, sibling)
 		acpiphp_bus_add(func);
-	}
 
 	pci_bus_assign_resources(bus);
 	acpiphp_sanitize_bus(bus);
 	acpiphp_set_hpp_values(bus);
-	list_for_each_entry(func, &slot->funcs, sibling)
-		acpiphp_configure_ioapics(func->handle);
 	pci_enable_bridges(bus);
 	pci_bus_add_devices(bus);
 
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
+	list_for_each_entry(func, &slot->funcs, sibling) {
 		dev = pci_get_slot(bus, PCI_DEVFN(slot->device,
 						  func->function));
 		if (!dev)
@@ -1091,7 +885,6 @@
 	}
 
 	list_for_each_entry(func, &slot->funcs, sibling) {
-		acpiphp_unconfigure_ioapics(func->handle);
 		acpiphp_bus_trim(func->handle);
 	}
 
@@ -1119,12 +912,9 @@
 	acpi_status status;
 	unsigned long long sta = 0;
 	u32 dvid;
-	struct list_head *l;
 	struct acpiphp_func *func;
 
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
-
+	list_for_each_entry(func, &slot->funcs, sibling) {
 		if (func->flags & FUNC_HAS_STA) {
 			status = acpi_evaluate_integer(func->handle, "_STA", NULL, &sta);
 			if (ACPI_SUCCESS(status) && sta)
@@ -1152,13 +942,10 @@
 {
 	acpi_status status;
 	struct acpiphp_func *func;
-	struct list_head *l;
 	struct acpi_object_list arg_list;
 	union acpi_object arg;
 
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
-
+	list_for_each_entry(func, &slot->funcs, sibling) {
 		/* We don't want to call _EJ0 on non-existing functions. */
 		if ((func->flags & FUNC_HAS_EJ0)) {
 			/* _EJ0 method take one argument */
@@ -1275,7 +1062,6 @@
 	acpiphp_sanitize_bus(bus);
 	acpiphp_set_hpp_values(bus);
 	pci_enable_bridges(bus);
-	acpiphp_configure_ioapics(handle);
 	return 0;
 }
 
@@ -1367,7 +1153,7 @@
 	bridge = acpiphp_handle_to_bridge(handle);
 	if (type == ACPI_NOTIFY_BUS_CHECK) {
 		acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, ACPI_UINT32_MAX,
-			count_sub_bridges, &num_sub_bridges, NULL);
+			count_sub_bridges, NULL, &num_sub_bridges, NULL);
 	}
 
 	if (!bridge && !num_sub_bridges) {
@@ -1388,7 +1174,7 @@
 		}
 		if (num_sub_bridges)
 			acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
-				ACPI_UINT32_MAX, check_sub_bridges, NULL, NULL);
+				ACPI_UINT32_MAX, check_sub_bridges, NULL, NULL, NULL);
 		break;
 
 	case ACPI_NOTIFY_DEVICE_CHECK:
@@ -1512,7 +1298,7 @@
 	int num = 0;
 
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-			ACPI_UINT32_MAX, find_root_bridges, &num, NULL);
+			ACPI_UINT32_MAX, find_root_bridges, NULL, &num, NULL);
 
 	if (num <= 0)
 		return -1;
@@ -1542,7 +1328,7 @@
 	struct acpiphp_bridge *bridge;
 	int num_slots = 0;
 
-	list_for_each_entry (bridge, &bridge_list, list) {
+	list_for_each_entry(bridge, &bridge_list, list) {
 		dbg("Bus %04x:%02x has %d slot%s\n",
 				pci_domain_nr(bridge->pci_bus),
 				bridge->pci_bus->number, bridge->nr_slots,
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c
index e7be66d..aa5df48 100644
--- a/drivers/pci/hotplug/acpiphp_ibm.c
+++ b/drivers/pci/hotplug/acpiphp_ibm.c
@@ -434,7 +434,7 @@
 	dbg("%s\n", __func__);
 
 	if (acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-			ACPI_UINT32_MAX, ibm_find_acpi_device,
+			ACPI_UINT32_MAX, ibm_find_acpi_device, NULL,
 			&ibm_acpi_handle, NULL) != FOUND_APCI) {
 		err("%s: acpi_walk_namespace failed\n", __func__);
 		retval = -ENODEV;
diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c
index 83f337c..c7084f0 100644
--- a/drivers/pci/hotplug/ibmphp_hpc.c
+++ b/drivers/pci/hotplug/ibmphp_hpc.c
@@ -890,7 +890,7 @@
 			msleep(POLL_INTERVAL_SEC * 1000);
 
 			if (kthread_should_stop())
-				break;
+				goto out_sleep;
 			
 			down (&semOperations);
 			
@@ -904,6 +904,7 @@
 		/* give up the hardware semaphore */
 		up (&semOperations);
 		/* sleep for a short time just for good measure */
+out_sleep:
 		msleep(100);
 	}
 	up (&sem_exit);
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
index 0325d98..38183a5 100644
--- a/drivers/pci/hotplug/pci_hotplug_core.c
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -68,26 +68,26 @@
 static char *pci_bus_speed_strings[] = {
 	"33 MHz PCI",		/* 0x00 */
 	"66 MHz PCI",		/* 0x01 */
-	"66 MHz PCIX", 		/* 0x02 */
-	"100 MHz PCIX",		/* 0x03 */
-	"133 MHz PCIX",		/* 0x04 */
+	"66 MHz PCI-X",		/* 0x02 */
+	"100 MHz PCI-X",	/* 0x03 */
+	"133 MHz PCI-X",	/* 0x04 */
 	NULL,			/* 0x05 */
 	NULL,			/* 0x06 */
 	NULL,			/* 0x07 */
 	NULL,			/* 0x08 */
-	"66 MHz PCIX 266",	/* 0x09 */
-	"100 MHz PCIX 266",	/* 0x0a */
-	"133 MHz PCIX 266",	/* 0x0b */
+	"66 MHz PCI-X 266",	/* 0x09 */
+	"100 MHz PCI-X 266",	/* 0x0a */
+	"133 MHz PCI-X 266",	/* 0x0b */
 	NULL,			/* 0x0c */
 	NULL,			/* 0x0d */
 	NULL,			/* 0x0e */
 	NULL,			/* 0x0f */
 	NULL,			/* 0x10 */
-	"66 MHz PCIX 533",	/* 0x11 */
-	"100 MHz PCIX 533",	/* 0x12 */
-	"133 MHz PCIX 533",	/* 0x13 */
-	"2.5 GT/s PCI-E",	/* 0x14 */
-	"5.0 GT/s PCI-E",	/* 0x15 */
+	"66 MHz PCI-X 533",	/* 0x11 */
+	"100 MHz PCI-X 533",	/* 0x12 */
+	"133 MHz PCI-X 533",	/* 0x13 */
+	"2.5 GT/s PCIe",	/* 0x14 */
+	"5.0 GT/s PCIe",	/* 0x15 */
 };
 
 #ifdef CONFIG_HOTPLUG_PCI_CPCI
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 3070f77..4ed76b4 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -91,7 +91,6 @@
 	struct slot *slot;
 	wait_queue_head_t queue;	/* sleep & wake process */
 	u32 slot_cap;
-	u8 cap_base;
 	struct timer_list poll_timer;
 	unsigned int cmd_busy:1;
 	unsigned int no_cmd_complete:1;
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c
index 37c8d3d..b09b083 100644
--- a/drivers/pci/hotplug/pciehp_acpi.c
+++ b/drivers/pci/hotplug/pciehp_acpi.c
@@ -87,7 +87,8 @@
 	/* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */
 	if (pciehp_get_hp_hw_control_from_firmware(pdev))
 		return -ENODEV;
-	if (!(pos = pci_find_capability(pdev, PCI_CAP_ID_EXP)))
+	pos = pci_pcie_cap(pdev);
+	if (!pos)
 		return -ENODEV;
 	pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &slot_cap);
 	slot = kzalloc(sizeof(*slot), GFP_KERNEL);
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index bc23471..5674b20 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -72,18 +72,6 @@
 static int get_max_bus_speed	(struct hotplug_slot *slot, enum pci_bus_speed *value);
 static int get_cur_bus_speed	(struct hotplug_slot *slot, enum pci_bus_speed *value);
 
-static struct hotplug_slot_ops pciehp_hotplug_slot_ops = {
-	.set_attention_status =	set_attention_status,
-	.enable_slot =		enable_slot,
-	.disable_slot =		disable_slot,
-	.get_power_status =	get_power_status,
-	.get_attention_status =	get_attention_status,
-	.get_latch_status =	get_latch_status,
-	.get_adapter_status =	get_adapter_status,
-  	.get_max_bus_speed =	get_max_bus_speed,
-  	.get_cur_bus_speed =	get_cur_bus_speed,
-};
-
 /**
  * release_slot - free up the memory used by a slot
  * @hotplug_slot: slot to free
@@ -95,6 +83,7 @@
 	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",
 		 __func__, hotplug_slot_name(hotplug_slot));
 
+	kfree(hotplug_slot->ops);
 	kfree(hotplug_slot->info);
 	kfree(hotplug_slot);
 }
@@ -104,6 +93,7 @@
 	struct slot *slot = ctrl->slot;
 	struct hotplug_slot *hotplug = NULL;
 	struct hotplug_slot_info *info = NULL;
+	struct hotplug_slot_ops *ops = NULL;
 	char name[SLOT_NAME_SIZE];
 	int retval = -ENOMEM;
 
@@ -115,11 +105,28 @@
 	if (!info)
 		goto out;
 
+	/* Setup hotplug slot ops */
+	ops = kzalloc(sizeof(*ops), GFP_KERNEL);
+	if (!ops)
+		goto out;
+	ops->enable_slot = enable_slot;
+	ops->disable_slot = disable_slot;
+	ops->get_power_status = get_power_status;
+	ops->get_adapter_status = get_adapter_status;
+	ops->get_max_bus_speed = get_max_bus_speed;
+	ops->get_cur_bus_speed = get_cur_bus_speed;
+	if (MRL_SENS(ctrl))
+		ops->get_latch_status = get_latch_status;
+	if (ATTN_LED(ctrl)) {
+		ops->get_attention_status = get_attention_status;
+		ops->set_attention_status = set_attention_status;
+	}
+
 	/* register this slot with the hotplug pci core */
 	hotplug->info = info;
 	hotplug->private = slot;
 	hotplug->release = &release_slot;
-	hotplug->ops = &pciehp_hotplug_slot_ops;
+	hotplug->ops = ops;
 	slot->hotplug_slot = hotplug;
 	snprintf(name, SLOT_NAME_SIZE, "%u", PSN(ctrl));
 
@@ -128,17 +135,12 @@
 		 ctrl->pcie->port->subordinate->number, PSN(ctrl));
 	retval = pci_hp_register(hotplug,
 				 ctrl->pcie->port->subordinate, 0, name);
-	if (retval) {
+	if (retval)
 		ctrl_err(ctrl,
 			 "pci_hp_register failed with error %d\n", retval);
-		goto out;
-	}
-	get_power_status(hotplug, &info->power_status);
-	get_attention_status(hotplug, &info->attention_status);
-	get_latch_status(hotplug, &info->latch_status);
-	get_adapter_status(hotplug, &info->adapter_status);
 out:
 	if (retval) {
+		kfree(ops);
 		kfree(info);
 		kfree(hotplug);
 	}
@@ -160,12 +162,7 @@
 	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",
 		  __func__, slot_name(slot));
 
-	hotplug_slot->info->attention_status = status;
-
-	if (ATTN_LED(slot->ctrl))
-		pciehp_set_attention_status(slot, status);
-
-	return 0;
+	return pciehp_set_attention_status(slot, status);
 }
 
 
@@ -193,92 +190,62 @@
 static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
 {
 	struct slot *slot = hotplug_slot->private;
-	int retval;
 
 	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",
 		  __func__, slot_name(slot));
 
-	retval = pciehp_get_power_status(slot, value);
-	if (retval < 0)
-		*value = hotplug_slot->info->power_status;
-
-	return 0;
+	return pciehp_get_power_status(slot, value);
 }
 
 static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
 {
 	struct slot *slot = hotplug_slot->private;
-	int retval;
 
 	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",
 		  __func__, slot_name(slot));
 
-	retval = pciehp_get_attention_status(slot, value);
-	if (retval < 0)
-		*value = hotplug_slot->info->attention_status;
-
-	return 0;
+	return pciehp_get_attention_status(slot, value);
 }
 
 static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
 {
 	struct slot *slot = hotplug_slot->private;
-	int retval;
 
 	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",
 		 __func__, slot_name(slot));
 
-	retval = pciehp_get_latch_status(slot, value);
-	if (retval < 0)
-		*value = hotplug_slot->info->latch_status;
-
-	return 0;
+	return pciehp_get_latch_status(slot, value);
 }
 
 static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
 {
 	struct slot *slot = hotplug_slot->private;
-	int retval;
 
 	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",
 		 __func__, slot_name(slot));
 
-	retval = pciehp_get_adapter_status(slot, value);
-	if (retval < 0)
-		*value = hotplug_slot->info->adapter_status;
-
-	return 0;
+	return pciehp_get_adapter_status(slot, value);
 }
 
 static int get_max_bus_speed(struct hotplug_slot *hotplug_slot,
 				enum pci_bus_speed *value)
 {
 	struct slot *slot = hotplug_slot->private;
-	int retval;
 
 	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",
 		 __func__, slot_name(slot));
 
-	retval = pciehp_get_max_link_speed(slot, value);
-	if (retval < 0)
-		*value = PCI_SPEED_UNKNOWN;
-
-	return 0;
+	return pciehp_get_max_link_speed(slot, value);
 }
 
 static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
 {
 	struct slot *slot = hotplug_slot->private;
-	int retval;
 
 	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",
 		 __func__, slot_name(slot));
 
-	retval = pciehp_get_cur_link_speed(slot, value);
-	if (retval < 0)
-		*value = PCI_SPEED_UNKNOWN;
-
-	return 0;
+	return pciehp_get_cur_link_speed(slot, value);
 }
 
 static int pciehp_probe(struct pcie_device *dev)
@@ -286,14 +253,13 @@
 	int rc;
 	struct controller *ctrl;
 	struct slot *slot;
-	u8 value;
-	struct pci_dev *pdev = dev->port;
+	u8 occupied, poweron;
 
 	if (pciehp_force)
 		dev_info(&dev->device,
 			 "Bypassing BIOS check for pciehp use on %s\n",
-			 pci_name(pdev));
-	else if (pciehp_get_hp_hw_control_from_firmware(pdev))
+			 pci_name(dev->port));
+	else if (pciehp_get_hp_hw_control_from_firmware(dev->port))
 		goto err_out_none;
 
 	ctrl = pcie_init(dev);
@@ -318,23 +284,18 @@
 	rc = pcie_init_notification(ctrl);
 	if (rc) {
 		ctrl_err(ctrl, "Notification initialization failed\n");
-		goto err_out_release_ctlr;
+		goto err_out_free_ctrl_slot;
 	}
 
 	/* Check if slot is occupied */
 	slot = ctrl->slot;
-	pciehp_get_adapter_status(slot, &value);
-	if (value) {
-		if (pciehp_force)
-			pciehp_enable_slot(slot);
-	} else {
-		/* Power off slot if not occupied */
-		if (POWER_CTRL(ctrl)) {
-			rc = pciehp_power_off_slot(slot);
-			if (rc)
-				goto err_out_free_ctrl_slot;
-		}
-	}
+	pciehp_get_adapter_status(slot, &occupied);
+	pciehp_get_power_status(slot, &poweron);
+	if (occupied && pciehp_force)
+		pciehp_enable_slot(slot);
+	/* If empty slot's power status is on, turn power off */
+	if (!occupied && poweron && POWER_CTRL(ctrl))
+		pciehp_power_off_slot(slot);
 
 	return 0;
 
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 84487d1..d6ac1b2 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -142,23 +142,9 @@
 
 	/* power fault */
 	ctrl_dbg(ctrl, "Power fault interrupt received\n");
-
-	if (!pciehp_query_power_fault(p_slot)) {
-		/*
-		 * power fault Cleared
-		 */
-		ctrl_info(ctrl, "Power fault cleared on Slot(%s)\n",
-			  slot_name(p_slot));
-		event_type = INT_POWER_FAULT_CLEAR;
-	} else {
-		/*
-		 *   power fault
-		 */
-		ctrl_info(ctrl, "Power fault on Slot(%s)\n", slot_name(p_slot));
-		event_type = INT_POWER_FAULT;
-		ctrl_info(ctrl, "Power fault bit %x set\n", 0);
-	}
-
+	ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot));
+	event_type = INT_POWER_FAULT;
+	ctrl_info(ctrl, "Power fault bit %x set\n", 0);
 	queue_interrupt_event(p_slot, event_type);
 
 	return 1;
@@ -224,13 +210,12 @@
 	retval = pciehp_check_link_status(ctrl);
 	if (retval) {
 		ctrl_err(ctrl, "Failed to check link status\n");
-		set_slot_off(ctrl, p_slot);
-		return retval;
+		goto err_exit;
 	}
 
 	/* Check for a power fault */
-	if (pciehp_query_power_fault(p_slot)) {
-		ctrl_dbg(ctrl, "Power fault detected\n");
+	if (ctrl->power_fault_detected || pciehp_query_power_fault(p_slot)) {
+		ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot));
 		retval = -EIO;
 		goto err_exit;
 	}
@@ -363,25 +348,6 @@
 	mutex_unlock(&p_slot->lock);
 }
 
-static int update_slot_info(struct slot *slot)
-{
-	struct hotplug_slot_info *info;
-	int result;
-
-	info = kmalloc(sizeof(*info), GFP_KERNEL);
-	if (!info)
-		return -ENOMEM;
-
-	pciehp_get_power_status(slot, &info->power_status);
-	pciehp_get_attention_status(slot, &info->attention_status);
-	pciehp_get_latch_status(slot, &info->latch_status);
-	pciehp_get_adapter_status(slot, &info->adapter_status);
-
-	result = pci_hp_change_slot_info(slot->hotplug_slot, info);
-	kfree (info);
-	return result;
-}
-
 /*
  * Note: This function must be called with slot->lock held
  */
@@ -442,7 +408,6 @@
 		 * to hot-add or hot-remove is undergoing
 		 */
 		ctrl_info(ctrl, "Button ignore on Slot(%s)\n", slot_name(p_slot));
-		update_slot_info(p_slot);
 		break;
 	default:
 		ctrl_warn(ctrl, "Not a valid state\n");
@@ -500,11 +465,9 @@
 		if (!HP_SUPR_RM(ctrl))
 			break;
 		ctrl_dbg(ctrl, "Surprise Removal\n");
-		update_slot_info(p_slot);
 		handle_surprise_event(p_slot);
 		break;
 	default:
-		update_slot_info(p_slot);
 		break;
 	}
 	mutex_unlock(&p_slot->lock);
@@ -547,9 +510,6 @@
 	if (rc) {
 		pciehp_get_latch_status(p_slot, &getstatus);
 	}
-
-	update_slot_info(p_slot);
-
 	return rc;
 }
 
@@ -590,10 +550,7 @@
 		}
 	}
 
-	ret = remove_board(p_slot);
-	update_slot_info(p_slot);
-
-	return ret;
+	return remove_board(p_slot);
 }
 
 int pciehp_sysfs_enable_slot(struct slot *p_slot)
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 9ef4605..10040d5 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -45,25 +45,25 @@
 static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value)
 {
 	struct pci_dev *dev = ctrl->pcie->port;
-	return pci_read_config_word(dev, ctrl->cap_base + reg, value);
+	return pci_read_config_word(dev, pci_pcie_cap(dev) + reg, value);
 }
 
 static inline int pciehp_readl(struct controller *ctrl, int reg, u32 *value)
 {
 	struct pci_dev *dev = ctrl->pcie->port;
-	return pci_read_config_dword(dev, ctrl->cap_base + reg, value);
+	return pci_read_config_dword(dev, pci_pcie_cap(dev) + reg, value);
 }
 
 static inline int pciehp_writew(struct controller *ctrl, int reg, u16 value)
 {
 	struct pci_dev *dev = ctrl->pcie->port;
-	return pci_write_config_word(dev, ctrl->cap_base + reg, value);
+	return pci_write_config_word(dev, pci_pcie_cap(dev) + reg, value);
 }
 
 static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value)
 {
 	struct pci_dev *dev = ctrl->pcie->port;
-	return pci_write_config_dword(dev, ctrl->cap_base + reg, value);
+	return pci_write_config_dword(dev, pci_pcie_cap(dev) + reg, value);
 }
 
 /* Power Control Command */
@@ -318,8 +318,8 @@
 		return retval;
 	}
 
-	ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n",
-		 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_ctrl);
+	ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", __func__,
+		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl);
 
 	atten_led_state = (slot_ctrl & PCI_EXP_SLTCTL_AIC) >> 6;
 
@@ -356,8 +356,8 @@
 		ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__);
 		return retval;
 	}
-	ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n",
-		 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_ctrl);
+	ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n", __func__,
+		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl);
 
 	pwr_state = (slot_ctrl & PCI_EXP_SLTCTL_PCC) >> 10;
 
@@ -427,27 +427,24 @@
 	struct controller *ctrl = slot->ctrl;
 	u16 slot_cmd;
 	u16 cmd_mask;
-	int rc;
 
 	cmd_mask = PCI_EXP_SLTCTL_AIC;
 	switch (value) {
-		case 0 :	/* turn off */
-			slot_cmd = 0x00C0;
-			break;
-		case 1:		/* turn on */
-			slot_cmd = 0x0040;
-			break;
-		case 2:		/* turn blink */
-			slot_cmd = 0x0080;
-			break;
-		default:
-			return -1;
+	case 0 :	/* turn off */
+		slot_cmd = 0x00C0;
+		break;
+	case 1:		/* turn on */
+		slot_cmd = 0x0040;
+		break;
+	case 2:		/* turn blink */
+		slot_cmd = 0x0080;
+		break;
+	default:
+		return -EINVAL;
 	}
-	rc = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
-	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
-		 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
-
-	return rc;
+	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
+		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
+	return pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
 }
 
 void pciehp_green_led_on(struct slot *slot)
@@ -459,8 +456,8 @@
 	slot_cmd = 0x0100;
 	cmd_mask = PCI_EXP_SLTCTL_PIC;
 	pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
-	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
-		 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
+	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
+		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
 }
 
 void pciehp_green_led_off(struct slot *slot)
@@ -472,8 +469,8 @@
 	slot_cmd = 0x0300;
 	cmd_mask = PCI_EXP_SLTCTL_PIC;
 	pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
-	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
-		 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
+	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
+		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
 }
 
 void pciehp_green_led_blink(struct slot *slot)
@@ -485,8 +482,8 @@
 	slot_cmd = 0x0200;
 	cmd_mask = PCI_EXP_SLTCTL_PIC;
 	pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
-	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
-		 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
+	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
+		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
 }
 
 int pciehp_power_on_slot(struct slot * slot)
@@ -514,97 +511,38 @@
 			return retval;
 		}
 	}
+	ctrl->power_fault_detected = 0;
 
 	slot_cmd = POWER_ON;
 	cmd_mask = PCI_EXP_SLTCTL_PCC;
-	if (!pciehp_poll_mode) {
-		/* Enable power fault detection turned off at power off time */
-		slot_cmd |= PCI_EXP_SLTCTL_PFDE;
-		cmd_mask |= PCI_EXP_SLTCTL_PFDE;
-	}
-
 	retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
 	if (retval) {
 		ctrl_err(ctrl, "Write %x command failed!\n", slot_cmd);
 		return retval;
 	}
-	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
-		 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
+	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
+		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
 
-	ctrl->power_fault_detected = 0;
 	return retval;
 }
 
-static inline int pcie_mask_bad_dllp(struct controller *ctrl)
-{
-	struct pci_dev *dev = ctrl->pcie->port;
-	int pos;
-	u32 reg;
-
-	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
-	if (!pos)
-		return 0;
-	pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &reg);
-	if (reg & PCI_ERR_COR_BAD_DLLP)
-		return 0;
-	reg |= PCI_ERR_COR_BAD_DLLP;
-	pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg);
-	return 1;
-}
-
-static inline void pcie_unmask_bad_dllp(struct controller *ctrl)
-{
-	struct pci_dev *dev = ctrl->pcie->port;
-	u32 reg;
-	int pos;
-
-	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
-	if (!pos)
-		return;
-	pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &reg);
-	if (!(reg & PCI_ERR_COR_BAD_DLLP))
-		return;
-	reg &= ~PCI_ERR_COR_BAD_DLLP;
-	pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg);
-}
-
 int pciehp_power_off_slot(struct slot * slot)
 {
 	struct controller *ctrl = slot->ctrl;
 	u16 slot_cmd;
 	u16 cmd_mask;
-	int retval = 0;
-	int changed;
-
-	/*
-	 * Set Bad DLLP Mask bit in Correctable Error Mask
-	 * Register. This is the workaround against Bad DLLP error
-	 * that sometimes happens during turning power off the slot
-	 * which conforms to PCI Express 1.0a spec.
-	 */
-	changed = pcie_mask_bad_dllp(ctrl);
+	int retval;
 
 	slot_cmd = POWER_OFF;
 	cmd_mask = PCI_EXP_SLTCTL_PCC;
-	if (!pciehp_poll_mode) {
-		/* Disable power fault detection */
-		slot_cmd &= ~PCI_EXP_SLTCTL_PFDE;
-		cmd_mask |= PCI_EXP_SLTCTL_PFDE;
-	}
-
 	retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
 	if (retval) {
 		ctrl_err(ctrl, "Write command failed!\n");
-		retval = -1;
-		goto out;
+		return retval;
 	}
-	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
-		 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
- out:
-	if (changed)
-		pcie_unmask_bad_dllp(ctrl);
-
-	return retval;
+	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
+		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
+	return 0;
 }
 
 static irqreturn_t pcie_isr(int irq, void *dev_id)
@@ -840,11 +778,19 @@
 {
 	u16 cmd, mask;
 
+	/*
+	 * TBD: Power fault detected software notification support.
+	 *
+	 * Power fault detected software notification is not enabled
+	 * now, because it caused power fault detected interrupt storm
+	 * on some machines. On those machines, power fault detected
+	 * bit in the slot status register was set again immediately
+	 * when it is cleared in the interrupt service routine, and
+	 * next power fault detected interrupt was notified again.
+	 */
 	cmd = PCI_EXP_SLTCTL_PDCE;
 	if (ATTN_BUTTN(ctrl))
 		cmd |= PCI_EXP_SLTCTL_ABPE;
-	if (POWER_CTRL(ctrl))
-		cmd |= PCI_EXP_SLTCTL_PFDE;
 	if (MRL_SENS(ctrl))
 		cmd |= PCI_EXP_SLTCTL_MRLSCE;
 	if (!pciehp_poll_mode)
@@ -866,7 +812,8 @@
 	u16 mask;
 	mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE |
 		PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE |
-		PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE);
+		PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE |
+		PCI_EXP_SLTCTL_DLLSCE);
 	if (pcie_write_cmd(ctrl, 0, mask))
 		ctrl_warn(ctrl, "Cannot disable software notification\n");
 }
@@ -934,7 +881,8 @@
 		  pdev->subsystem_device);
 	ctrl_info(ctrl, "  Subsystem Vendor ID  : 0x%04x\n",
 		  pdev->subsystem_vendor);
-	ctrl_info(ctrl, "  PCIe Cap offset      : 0x%02x\n", ctrl->cap_base);
+	ctrl_info(ctrl, "  PCIe Cap offset      : 0x%02x\n",
+		  pci_pcie_cap(pdev));
 	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
 		if (!pci_resource_len(pdev, i))
 			continue;
@@ -978,8 +926,7 @@
 		goto abort;
 	}
 	ctrl->pcie = dev;
-	ctrl->cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP);
-	if (!ctrl->cap_base) {
+	if (!pci_pcie_cap(pdev)) {
 		ctrl_err(ctrl, "Cannot find PCI Express capability\n");
 		goto abort_ctrl;
 	}
diff --git a/drivers/pci/hotplug/pcihp_slot.c b/drivers/pci/hotplug/pcihp_slot.c
index cc8ec3a..80b461c 100644
--- a/drivers/pci/hotplug/pcihp_slot.c
+++ b/drivers/pci/hotplug/pcihp_slot.c
@@ -43,7 +43,7 @@
 		 * Perhaps we *should* use default settings for PCIe, but
 		 * pciehp didn't, so we won't either.
 		 */
-		if (dev->is_pcie)
+		if (pci_is_pcie(dev))
 			return;
 		dev_info(&dev->dev, "using default PCI settings\n");
 		hpp = &pci_default_type0;
@@ -102,7 +102,7 @@
 		return;
 
 	/* Find PCI Express capability */
-	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	pos = pci_pcie_cap(dev);
 	if (!pos)
 		return;
 
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index 9261327..8d61594 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -1611,7 +1611,7 @@
 			return ret;
 		parent = parent->bus->self;
 	}
-	if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */
+	if (pci_is_pcie(tmp)) /* this is a PCIE-to-PCI bridge */
 		return domain_context_mapping_one(domain,
 					pci_domain_nr(tmp->subordinate),
 					tmp->subordinate->number, 0,
@@ -1651,7 +1651,7 @@
 			return ret;
 		parent = parent->bus->self;
 	}
-	if (tmp->is_pcie)
+	if (pci_is_pcie(tmp))
 		return device_context_mapped(iommu, tmp->subordinate->number,
 					     0);
 	else
@@ -1821,7 +1821,7 @@
 
 	dev_tmp = pci_find_upstream_pcie_bridge(pdev);
 	if (dev_tmp) {
-		if (dev_tmp->is_pcie) {
+		if (pci_is_pcie(dev_tmp)) {
 			bus = dev_tmp->subordinate->number;
 			devfn = 0;
 		} else {
@@ -2182,7 +2182,7 @@
 	 * the 1:1 domain, just in _case_ one of their siblings turns out
 	 * not to be able to map all of memory.
 	 */
-	if (!pdev->is_pcie) {
+	if (!pci_is_pcie(pdev)) {
 		if (!pci_is_root_bus(pdev->bus))
 			return 0;
 		if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
@@ -3319,7 +3319,7 @@
 					 parent->devfn);
 			parent = parent->bus->self;
 		}
-		if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */
+		if (pci_is_pcie(tmp)) /* this is a PCIE-to-PCI bridge */
 			iommu_detach_dev(iommu,
 				tmp->subordinate->number, 0);
 		else /* this is a legacy PCI bridge */
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c
index 0ed78a7..1487bf2 100644
--- a/drivers/pci/intr_remapping.c
+++ b/drivers/pci/intr_remapping.c
@@ -2,6 +2,7 @@
 #include <linux/dmar.h>
 #include <linux/spinlock.h>
 #include <linux/jiffies.h>
+#include <linux/hpet.h>
 #include <linux/pci.h>
 #include <linux/irq.h>
 #include <asm/io_apic.h>
@@ -14,7 +15,8 @@
 #include "pci.h"
 
 static struct ioapic_scope ir_ioapic[MAX_IO_APICS];
-static int ir_ioapic_num;
+static struct hpet_scope ir_hpet[MAX_HPET_TBS];
+static int ir_ioapic_num, ir_hpet_num;
 int intr_remapping_enabled;
 
 static int disable_intremap;
@@ -343,6 +345,16 @@
 	return rc;
 }
 
+struct intel_iommu *map_hpet_to_ir(u8 hpet_id)
+{
+	int i;
+
+	for (i = 0; i < MAX_HPET_TBS; i++)
+		if (ir_hpet[i].id == hpet_id)
+			return ir_hpet[i].iommu;
+	return NULL;
+}
+
 struct intel_iommu *map_ioapic_to_ir(int apic)
 {
 	int i;
@@ -470,6 +482,36 @@
 	return 0;
 }
 
+int set_hpet_sid(struct irte *irte, u8 id)
+{
+	int i;
+	u16 sid = 0;
+
+	if (!irte)
+		return -1;
+
+	for (i = 0; i < MAX_HPET_TBS; i++) {
+		if (ir_hpet[i].id == id) {
+			sid = (ir_hpet[i].bus << 8) | ir_hpet[i].devfn;
+			break;
+		}
+	}
+
+	if (sid == 0) {
+		pr_warning("Failed to set source-id of HPET block (%d)\n", id);
+		return -1;
+	}
+
+	/*
+	 * Should really use SQ_ALL_16. Some platforms are broken.
+	 * While we figure out the right quirks for these broken platforms, use
+	 * SQ_13_IGNORE_3 for now.
+	 */
+	set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_13_IGNORE_3, sid);
+
+	return 0;
+}
+
 int set_msi_sid(struct irte *irte, struct pci_dev *dev)
 {
 	struct pci_dev *bridge;
@@ -478,7 +520,7 @@
 		return -1;
 
 	/* PCIe device or Root Complex integrated PCI device */
-	if (dev->is_pcie || !dev->bus->parent) {
+	if (pci_is_pcie(dev) || !dev->bus->parent) {
 		set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_ALL_16,
 			     (dev->bus->number << 8) | dev->devfn);
 		return 0;
@@ -486,7 +528,7 @@
 
 	bridge = pci_find_upstream_pcie_bridge(dev);
 	if (bridge) {
-		if (bridge->is_pcie) /* this is a PCIE-to-PCI/PCIX bridge */
+		if (pci_is_pcie(bridge))/* this is a PCIE-to-PCI/PCIX bridge */
 			set_irte_sid(irte, SVT_VERIFY_BUS, SQ_ALL_16,
 				(bridge->bus->number << 8) | dev->bus->number);
 		else /* this is a legacy PCI bridge */
@@ -711,6 +753,34 @@
 	return -1;
 }
 
+static void ir_parse_one_hpet_scope(struct acpi_dmar_device_scope *scope,
+				      struct intel_iommu *iommu)
+{
+	struct acpi_dmar_pci_path *path;
+	u8 bus;
+	int count;
+
+	bus = scope->bus;
+	path = (struct acpi_dmar_pci_path *)(scope + 1);
+	count = (scope->length - sizeof(struct acpi_dmar_device_scope))
+		/ sizeof(struct acpi_dmar_pci_path);
+
+	while (--count > 0) {
+		/*
+		 * Access PCI directly due to the PCI
+		 * subsystem isn't initialized yet.
+		 */
+		bus = read_pci_config_byte(bus, path->dev, path->fn,
+					   PCI_SECONDARY_BUS);
+		path++;
+	}
+	ir_hpet[ir_hpet_num].bus   = bus;
+	ir_hpet[ir_hpet_num].devfn = PCI_DEVFN(path->dev, path->fn);
+	ir_hpet[ir_hpet_num].iommu = iommu;
+	ir_hpet[ir_hpet_num].id    = scope->enumeration_id;
+	ir_hpet_num++;
+}
+
 static void ir_parse_one_ioapic_scope(struct acpi_dmar_device_scope *scope,
 				      struct intel_iommu *iommu)
 {
@@ -740,8 +810,8 @@
 	ir_ioapic_num++;
 }
 
-static int ir_parse_ioapic_scope(struct acpi_dmar_header *header,
-				 struct intel_iommu *iommu)
+static int ir_parse_ioapic_hpet_scope(struct acpi_dmar_header *header,
+				      struct intel_iommu *iommu)
 {
 	struct acpi_dmar_hardware_unit *drhd;
 	struct acpi_dmar_device_scope *scope;
@@ -765,6 +835,17 @@
 			       drhd->address);
 
 			ir_parse_one_ioapic_scope(scope, iommu);
+		} else if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_HPET) {
+			if (ir_hpet_num == MAX_HPET_TBS) {
+				printk(KERN_WARNING "Exceeded Max HPET blocks\n");
+				return -1;
+			}
+
+			printk(KERN_INFO "HPET id %d under DRHD base"
+			       " 0x%Lx\n", scope->enumeration_id,
+			       drhd->address);
+
+			ir_parse_one_hpet_scope(scope, iommu);
 		}
 		start += scope->length;
 	}
@@ -785,7 +866,7 @@
 		struct intel_iommu *iommu = drhd->iommu;
 
 		if (ecap_ir_support(iommu->ecap)) {
-			if (ir_parse_ioapic_scope(drhd->hdr, iommu))
+			if (ir_parse_ioapic_hpet_scope(drhd->hdr, iommu))
 				return -1;
 
 			ir_supported = 1;
diff --git a/drivers/pci/intr_remapping.h b/drivers/pci/intr_remapping.h
index 63a263c..5662fec 100644
--- a/drivers/pci/intr_remapping.h
+++ b/drivers/pci/intr_remapping.h
@@ -7,4 +7,11 @@
 	unsigned int devfn;	/* PCI devfn number */
 };
 
+struct hpet_scope {
+	struct intel_iommu *iommu;
+	u8 id;
+	unsigned int bus;
+	unsigned int devfn;
+};
+
 #define IR_X2APIC_MODE(mode) (mode ? (1 << 11) : 0)
diff --git a/drivers/pci/ioapic.c b/drivers/pci/ioapic.c
new file mode 100644
index 0000000..3e0d7b5
--- /dev/null
+++ b/drivers/pci/ioapic.c
@@ -0,0 +1,127 @@
+/*
+ * IOAPIC/IOxAPIC/IOSAPIC driver
+ *
+ * Copyright (C) 2009 Fujitsu Limited.
+ * (c) Copyright 2009 Hewlett-Packard Development Company, L.P.
+ *
+ * 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.
+ */
+
+/*
+ * This driver manages PCI I/O APICs added by hotplug after boot.  We try to
+ * claim all I/O APIC PCI devices, but those present at boot were registered
+ * when we parsed the ACPI MADT, so we'll fail when we try to re-register
+ * them.
+ */
+
+#include <linux/pci.h>
+#include <linux/acpi.h>
+#include <acpi/acpi_bus.h>
+
+struct ioapic {
+	acpi_handle	handle;
+	u32		gsi_base;
+};
+
+static int ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent)
+{
+	acpi_handle handle;
+	acpi_status status;
+	unsigned long long gsb;
+	struct ioapic *ioapic;
+	u64 addr;
+	int ret;
+	char *type;
+
+	handle = DEVICE_ACPI_HANDLE(&dev->dev);
+	if (!handle)
+		return -EINVAL;
+
+	status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb);
+	if (ACPI_FAILURE(status))
+		return -EINVAL;
+
+	/*
+	 * The previous code in acpiphp evaluated _MAT if _GSB failed, but
+	 * ACPI spec 4.0 sec 6.2.2 requires _GSB for hot-pluggable I/O APICs.
+	 */
+
+	ioapic = kzalloc(sizeof(*ioapic), GFP_KERNEL);
+	if (!ioapic)
+		return -ENOMEM;
+
+	ioapic->handle = handle;
+	ioapic->gsi_base = (u32) gsb;
+
+	if (dev->class == PCI_CLASS_SYSTEM_PIC_IOAPIC)
+		type = "IOAPIC";
+	else
+		type = "IOxAPIC";
+
+	ret = pci_enable_device(dev);
+	if (ret < 0)
+		goto exit_free;
+
+	pci_set_master(dev);
+
+	if (pci_request_region(dev, 0, type))
+		goto exit_disable;
+
+	addr = pci_resource_start(dev, 0);
+	if (acpi_register_ioapic(ioapic->handle, addr, ioapic->gsi_base))
+		goto exit_release;
+
+	pci_set_drvdata(dev, ioapic);
+	dev_info(&dev->dev, "%s at %#llx, GSI %u\n", type, addr,
+		 ioapic->gsi_base);
+	return 0;
+
+exit_release:
+	pci_release_region(dev, 0);
+exit_disable:
+	pci_disable_device(dev);
+exit_free:
+	kfree(ioapic);
+	return -ENODEV;
+}
+
+static void ioapic_remove(struct pci_dev *dev)
+{
+	struct ioapic *ioapic = pci_get_drvdata(dev);
+
+	acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base);
+	pci_release_region(dev, 0);
+	pci_disable_device(dev);
+	kfree(ioapic);
+}
+
+
+static struct pci_device_id ioapic_devices[] = {
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	  PCI_CLASS_SYSTEM_PIC_IOAPIC << 8, 0xffff00, },
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	  PCI_CLASS_SYSTEM_PIC_IOXAPIC << 8, 0xffff00, },
+	{ }
+};
+
+static struct pci_driver ioapic_driver = {
+	.name		= "ioapic",
+	.id_table	= ioapic_devices,
+	.probe		= ioapic_probe,
+	.remove		= __devexit_p(ioapic_remove),
+};
+
+static int __init ioapic_init(void)
+{
+	return pci_register_driver(&ioapic_driver);
+}
+
+static void __exit ioapic_exit(void)
+{
+	pci_unregister_driver(&ioapic_driver);
+}
+
+module_init(ioapic_init);
+module_exit(ioapic_exit);
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index e03fe98..b2a448e 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -555,7 +555,7 @@
 {
 	int pos;
 
-	if (!dev->is_pcie)
+	if (!pci_is_pcie(dev))
 		return -ENODEV;
 
 	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV);
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 33317df..cc617dd 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -116,7 +116,7 @@
 		int ret;
 
 		ret = acpi_pm_device_sleep_wake(&bridge->dev, enable);
-		if (!ret || bridge->is_pcie)
+		if (!ret || pci_is_pcie(bridge))
 			return;
 		bus = bus->parent;
 	}
@@ -131,7 +131,7 @@
 	if (acpi_pci_can_wakeup(dev))
 		return acpi_pm_device_sleep_wake(&dev->dev, enable);
 
-	if (!dev->is_pcie)
+	if (!pci_is_pcie(dev))
 		acpi_pci_propagate_wakeup_enable(dev->bus, enable);
 
 	return 0;
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 0f6382f..c5df94e 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -74,7 +74,11 @@
 	const struct cpumask *mask;
 	int len;
 
+#ifdef CONFIG_NUMA
+	mask = cpumask_of_node(dev_to_node(dev));
+#else
 	mask = cpumask_of_pcibus(to_pci_dev(dev)->bus);
+#endif
 	len = cpumask_scnprintf(buf, PAGE_SIZE-2, mask);
 	buf[len++] = '\n';
 	buf[len] = '\0';
@@ -88,7 +92,11 @@
 	const struct cpumask *mask;
 	int len;
 
+#ifdef CONFIG_NUMA
+	mask = cpumask_of_node(dev_to_node(dev));
+#else
 	mask = cpumask_of_pcibus(to_pci_dev(dev)->bus);
+#endif
 	len = cpulist_scnprintf(buf, PAGE_SIZE-2, mask);
 	buf[len++] = '\n';
 	buf[len] = '\0';
@@ -176,6 +184,21 @@
 #endif
 
 static ssize_t
+dma_mask_bits_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+
+	return sprintf (buf, "%d\n", fls64(pdev->dma_mask));
+}
+
+static ssize_t
+consistent_dma_mask_bits_show(struct device *dev, struct device_attribute *attr,
+				 char *buf)
+{
+	return sprintf (buf, "%d\n", fls64(dev->coherent_dma_mask));
+}
+
+static ssize_t
 msi_bus_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
@@ -306,6 +329,8 @@
 #ifdef CONFIG_NUMA
 	__ATTR_RO(numa_node),
 #endif
+	__ATTR_RO(dma_mask_bits),
+	__ATTR_RO(consistent_dma_mask_bits),
 	__ATTR(enable, 0600, is_enabled_show, is_enabled_store),
 	__ATTR(broken_parity_status,(S_IRUGO|S_IWUSR),
 		broken_parity_status_show,broken_parity_status_store),
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 4e4c295..0bc27e0 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -47,6 +47,15 @@
 unsigned long pci_hotplug_io_size  = DEFAULT_HOTPLUG_IO_SIZE;
 unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE;
 
+/*
+ * The default CLS is used if arch didn't set CLS explicitly and not
+ * all pci devices agree on the same value.  Arch can override either
+ * the dfl or actual value as it sees fit.  Don't forget this is
+ * measured in 32-bit words, not bytes.
+ */
+u8 pci_dfl_cache_line_size __devinitdata = L1_CACHE_BYTES >> 2;
+u8 pci_cache_line_size;
+
 /**
  * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children
  * @bus: pointer to PCI bus structure to search
@@ -373,8 +382,12 @@
 			continue;	/* Wrong type */
 		if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH))
 			return r;	/* Exact match */
-		if ((res->flags & IORESOURCE_PREFETCH) && !(r->flags & IORESOURCE_PREFETCH))
-			best = r;	/* Approximating prefetchable by non-prefetchable */
+		/* We can't insert a non-prefetch resource inside a prefetchable parent .. */
+		if (r->flags & IORESOURCE_PREFETCH)
+			continue;
+		/* .. but we can put a prefetchable resource inside a non-prefetchable one */
+		if (!best)
+			best = r;
 	}
 	return best;
 }
@@ -728,8 +741,8 @@
 	u16 *cap;
 	u16 flags;
 
-	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
-	if (pos <= 0)
+	pos = pci_pcie_cap(dev);
+	if (!pos)
 		return 0;
 
 	save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP);
@@ -837,7 +850,7 @@
 	int i;
 	/* XXX: 100% dword access ok here? */
 	for (i = 0; i < 16; i++)
-		pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]);
+		pci_read_config_dword(dev, i * 4, &dev->saved_config_space[i]);
 	dev->state_saved = true;
 	if ((i = pci_save_pcie_state(dev)) != 0)
 		return i;
@@ -1202,7 +1215,7 @@
 
 	pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr);
 
-	dev_printk(KERN_INFO, &dev->dev, "PME# %s\n",
+	dev_printk(KERN_DEBUG, &dev->dev, "PME# %s\n",
 			enable ? "enabled" : "disabled");
 }
 
@@ -1413,7 +1426,8 @@
 
 	pmc &= PCI_PM_CAP_PME_MASK;
 	if (pmc) {
-		dev_info(&dev->dev, "PME# supported from%s%s%s%s%s\n",
+		dev_printk(KERN_DEBUG, &dev->dev,
+			 "PME# supported from%s%s%s%s%s\n",
 			 (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "",
 			 (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "",
 			 (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "",
@@ -1510,7 +1524,7 @@
 	u16 ctrl;
 	struct pci_dev *bridge;
 
-	if (!dev->is_pcie || dev->devfn)
+	if (!pci_is_pcie(dev) || dev->devfn)
 		return;
 
 	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI);
@@ -1518,10 +1532,10 @@
 		return;
 
 	bridge = dev->bus->self;
-	if (!bridge || !bridge->is_pcie)
+	if (!bridge || !pci_is_pcie(bridge))
 		return;
 
-	pos = pci_find_capability(bridge, PCI_CAP_ID_EXP);
+	pos = pci_pcie_cap(bridge);
 	if (!pos)
 		return;
 
@@ -1536,6 +1550,54 @@
 	bridge->ari_enabled = 1;
 }
 
+static int pci_acs_enable;
+
+/**
+ * pci_request_acs - ask for ACS to be enabled if supported
+ */
+void pci_request_acs(void)
+{
+	pci_acs_enable = 1;
+}
+
+/**
+ * pci_enable_acs - enable ACS if hardware support it
+ * @dev: the PCI device
+ */
+void pci_enable_acs(struct pci_dev *dev)
+{
+	int pos;
+	u16 cap;
+	u16 ctrl;
+
+	if (!pci_acs_enable)
+		return;
+
+	if (!pci_is_pcie(dev))
+		return;
+
+	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
+	if (!pos)
+		return;
+
+	pci_read_config_word(dev, pos + PCI_ACS_CAP, &cap);
+	pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl);
+
+	/* Source Validation */
+	ctrl |= (cap & PCI_ACS_SV);
+
+	/* P2P Request Redirect */
+	ctrl |= (cap & PCI_ACS_RR);
+
+	/* P2P Completion Redirect */
+	ctrl |= (cap & PCI_ACS_CR);
+
+	/* Upstream Forwarding */
+	ctrl |= (cap & PCI_ACS_UF);
+
+	pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl);
+}
+
 /**
  * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge
  * @dev: the PCI device
@@ -1669,9 +1731,7 @@
 	return 0;
 
 err_out:
-	dev_warn(&pdev->dev, "BAR %d: can't reserve %s region %pR\n",
-		 bar,
-		 pci_resource_flags(pdev, bar) & IORESOURCE_IO ? "I/O" : "mem",
+	dev_warn(&pdev->dev, "BAR %d: can't reserve %pR\n", bar,
 		 &pdev->resource[bar]);
 	return -EBUSY;
 }
@@ -1866,31 +1926,6 @@
 	__pci_set_master(dev, false);
 }
 
-#ifdef PCI_DISABLE_MWI
-int pci_set_mwi(struct pci_dev *dev)
-{
-	return 0;
-}
-
-int pci_try_set_mwi(struct pci_dev *dev)
-{
-	return 0;
-}
-
-void pci_clear_mwi(struct pci_dev *dev)
-{
-}
-
-#else
-
-#ifndef PCI_CACHE_LINE_BYTES
-#define PCI_CACHE_LINE_BYTES L1_CACHE_BYTES
-#endif
-
-/* This can be overridden by arch code. */
-/* Don't forget this is measured in 32-bit words, not bytes */
-u8 pci_cache_line_size = PCI_CACHE_LINE_BYTES / 4;
-
 /**
  * pci_set_cacheline_size - ensure the CACHE_LINE_SIZE register is programmed
  * @dev: the PCI device for which MWI is to be enabled
@@ -1901,13 +1936,12 @@
  *
  * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
  */
-static int
-pci_set_cacheline_size(struct pci_dev *dev)
+int pci_set_cacheline_size(struct pci_dev *dev)
 {
 	u8 cacheline_size;
 
 	if (!pci_cache_line_size)
-		return -EINVAL;		/* The system doesn't support MWI. */
+		return -EINVAL;
 
 	/* Validate current setting: the PCI_CACHE_LINE_SIZE must be
 	   equal to or multiple of the right value. */
@@ -1928,6 +1962,24 @@
 
 	return -EINVAL;
 }
+EXPORT_SYMBOL_GPL(pci_set_cacheline_size);
+
+#ifdef PCI_DISABLE_MWI
+int pci_set_mwi(struct pci_dev *dev)
+{
+	return 0;
+}
+
+int pci_try_set_mwi(struct pci_dev *dev)
+{
+	return 0;
+}
+
+void pci_clear_mwi(struct pci_dev *dev)
+{
+}
+
+#else
 
 /**
  * pci_set_mwi - enables memory-write-invalidate PCI transaction
@@ -2062,6 +2114,7 @@
 		return -EIO;
 
 	dev->dma_mask = mask;
+	dev_dbg(&dev->dev, "using %dbit DMA mask\n", fls64(mask));
 
 	return 0;
 }
@@ -2073,6 +2126,7 @@
 		return -EIO;
 
 	dev->dev.coherent_dma_mask = mask;
+	dev_dbg(&dev->dev, "using %dbit consistent DMA mask\n", fls64(mask));
 
 	return 0;
 }
@@ -2099,9 +2153,9 @@
 	int i;
 	int pos;
 	u32 cap;
-	u16 status;
+	u16 status, control;
 
-	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	pos = pci_pcie_cap(dev);
 	if (!pos)
 		return -ENOTTY;
 
@@ -2126,8 +2180,10 @@
 			"proceeding with reset anyway\n");
 
 clear:
-	pci_write_config_word(dev, pos + PCI_EXP_DEVCTL,
-				PCI_EXP_DEVCTL_BCR_FLR);
+	pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &control);
+	control |= PCI_EXP_DEVCTL_BCR_FLR;
+	pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, control);
+
 	msleep(100);
 
 	return 0;
@@ -2450,7 +2506,7 @@
 	int ret, cap;
 	u16 ctl;
 
-	cap = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	cap = pci_pcie_cap(dev);
 	if (!cap)
 		return -EINVAL;
 
@@ -2480,7 +2536,7 @@
 
 	v = (ffs(rq) - 8) << 12;
 
-	cap = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	cap = pci_pcie_cap(dev);
 	if (!cap)
 		goto out;
 
@@ -2540,7 +2596,7 @@
 			return reg;
 	}
 
-	dev_err(&dev->dev, "BAR: invalid resource #%d\n", resno);
+	dev_err(&dev->dev, "BAR %d: invalid resource\n", resno);
 	return 0;
 }
 
@@ -2590,7 +2646,7 @@
 
 #define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE
 static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0};
-spinlock_t resource_alignment_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(resource_alignment_lock);
 
 /**
  * pci_specified_resource_alignment - get resource alignment specified by user.
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index d92d195..33ed8e0 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -311,4 +311,6 @@
 	return resource_alignment(res);
 }
 
+extern void pci_enable_acs(struct pci_dev *dev);
+
 #endif /* DRIVERS_PCI_H */
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c
index 62d15f6..7fcd5331 100644
--- a/drivers/pci/pcie/aer/aer_inject.c
+++ b/drivers/pci/pcie/aer/aer_inject.c
@@ -23,6 +23,7 @@
 #include <linux/pci.h>
 #include <linux/fs.h>
 #include <linux/uaccess.h>
+#include <linux/stddef.h>
 #include "aerdrv.h"
 
 struct aer_error_inj {
@@ -35,10 +36,12 @@
 	u32 header_log1;
 	u32 header_log2;
 	u32 header_log3;
+	u16 domain;
 };
 
 struct aer_error {
 	struct list_head list;
+	u16 domain;
 	unsigned int bus;
 	unsigned int devfn;
 	int pos_cap_err;
@@ -66,22 +69,27 @@
 /* Protect einjected and pci_bus_ops_list */
 static DEFINE_SPINLOCK(inject_lock);
 
-static void aer_error_init(struct aer_error *err, unsigned int bus,
-			   unsigned int devfn, int pos_cap_err)
+static void aer_error_init(struct aer_error *err, u16 domain,
+			   unsigned int bus, unsigned int devfn,
+			   int pos_cap_err)
 {
 	INIT_LIST_HEAD(&err->list);
+	err->domain = domain;
 	err->bus = bus;
 	err->devfn = devfn;
 	err->pos_cap_err = pos_cap_err;
 }
 
 /* inject_lock must be held before calling */
-static struct aer_error *__find_aer_error(unsigned int bus, unsigned int devfn)
+static struct aer_error *__find_aer_error(u16 domain, unsigned int bus,
+					  unsigned int devfn)
 {
 	struct aer_error *err;
 
 	list_for_each_entry(err, &einjected, list) {
-		if (bus == err->bus && devfn == err->devfn)
+		if (domain == err->domain &&
+		    bus == err->bus &&
+		    devfn == err->devfn)
 			return err;
 	}
 	return NULL;
@@ -90,7 +98,10 @@
 /* inject_lock must be held before calling */
 static struct aer_error *__find_aer_error_by_dev(struct pci_dev *dev)
 {
-	return __find_aer_error(dev->bus->number, dev->devfn);
+	int domain = pci_domain_nr(dev->bus);
+	if (domain < 0)
+		return NULL;
+	return __find_aer_error((u16)domain, dev->bus->number, dev->devfn);
 }
 
 /* inject_lock must be held before calling */
@@ -172,11 +183,15 @@
 	struct aer_error *err;
 	unsigned long flags;
 	struct pci_ops *ops;
+	int domain;
 
 	spin_lock_irqsave(&inject_lock, flags);
 	if (size != sizeof(u32))
 		goto out;
-	err = __find_aer_error(bus->number, devfn);
+	domain = pci_domain_nr(bus);
+	if (domain < 0)
+		goto out;
+	err = __find_aer_error((u16)domain, bus->number, devfn);
 	if (!err)
 		goto out;
 
@@ -200,11 +215,15 @@
 	unsigned long flags;
 	int rw1cs;
 	struct pci_ops *ops;
+	int domain;
 
 	spin_lock_irqsave(&inject_lock, flags);
 	if (size != sizeof(u32))
 		goto out;
-	err = __find_aer_error(bus->number, devfn);
+	domain = pci_domain_nr(bus);
+	if (domain < 0)
+		goto out;
+	err = __find_aer_error((u16)domain, bus->number, devfn);
 	if (!err)
 		goto out;
 
@@ -262,7 +281,7 @@
 static struct pci_dev *pcie_find_root_port(struct pci_dev *dev)
 {
 	while (1) {
-		if (!dev->is_pcie)
+		if (!pci_is_pcie(dev))
 			break;
 		if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
 			return dev;
@@ -305,25 +324,25 @@
 	u32 sever;
 	int ret = 0;
 
-	dev = pci_get_bus_and_slot(einj->bus, devfn);
+	dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn);
 	if (!dev)
-		return -EINVAL;
+		return -ENODEV;
 	rpdev = pcie_find_root_port(dev);
 	if (!rpdev) {
-		ret = -EINVAL;
+		ret = -ENOTTY;
 		goto out_put;
 	}
 
 	pos_cap_err = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
 	if (!pos_cap_err) {
-		ret = -EIO;
+		ret = -ENOTTY;
 		goto out_put;
 	}
 	pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever);
 
 	rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR);
 	if (!rp_pos_cap_err) {
-		ret = -EIO;
+		ret = -ENOTTY;
 		goto out_put;
 	}
 
@@ -344,7 +363,8 @@
 	if (!err) {
 		err = err_alloc;
 		err_alloc = NULL;
-		aer_error_init(err, einj->bus, devfn, pos_cap_err);
+		aer_error_init(err, einj->domain, einj->bus, devfn,
+			       pos_cap_err);
 		list_add(&err->list, &einjected);
 	}
 	err->uncor_status |= einj->uncor_status;
@@ -358,7 +378,8 @@
 	if (!rperr) {
 		rperr = rperr_alloc;
 		rperr_alloc = NULL;
-		aer_error_init(rperr, rpdev->bus->number, rpdev->devfn,
+		aer_error_init(rperr, pci_domain_nr(rpdev->bus),
+			       rpdev->bus->number, rpdev->devfn,
 			       rp_pos_cap_err);
 		list_add(&rperr->list, &einjected);
 	}
@@ -411,10 +432,11 @@
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
-
-	if (usize != sizeof(struct aer_error_inj))
+	if (usize < offsetof(struct aer_error_inj, domain) ||
+	    usize > sizeof(einj))
 		return -EINVAL;
 
+	memset(&einj, 0, sizeof(einj));
 	if (copy_from_user(&einj, ubuf, usize))
 		return -EFAULT;
 
@@ -452,7 +474,7 @@
 	}
 
 	spin_lock_irqsave(&inject_lock, flags);
-	list_for_each_entry_safe(err, err_next, &pci_bus_ops_list, list) {
+	list_for_each_entry_safe(err, err_next, &einjected, list) {
 		list_del(&err->list);
 		kfree(err);
 	}
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index 40c3cc5..97a3459 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -53,7 +53,7 @@
 
 static struct pcie_port_service_driver aerdriver = {
 	.name		= "aer",
-	.port_type	= PCIE_RC_PORT,
+	.port_type	= PCI_EXP_TYPE_ROOT_PORT,
 	.service	= PCIE_PORT_SERVICE_AER,
 
 	.probe		= aer_probe,
@@ -295,7 +295,7 @@
 	u16 reg16;
 
 	/* Clean up Root device status */
-	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	pos = pci_pcie_cap(dev);
 	pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &reg16);
 	pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, reg16);
 
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 9f5ccbe..ae672ca 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -35,11 +35,14 @@
 	u16 reg16 = 0;
 	int pos;
 
+	if (dev->aer_firmware_first)
+		return -EIO;
+
 	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
 	if (!pos)
 		return -EIO;
 
-	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	pos = pci_pcie_cap(dev);
 	if (!pos)
 		return -EIO;
 
@@ -60,7 +63,10 @@
 	u16 reg16 = 0;
 	int pos;
 
-	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	if (dev->aer_firmware_first)
+		return -EIO;
+
+	pos = pci_pcie_cap(dev);
 	if (!pos)
 		return -EIO;
 
@@ -78,48 +84,27 @@
 int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
 {
 	int pos;
-	u32 status, mask;
-
-	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
-	if (!pos)
-		return -EIO;
-
-	pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status);
-	pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask);
-	if (dev->error_state == pci_channel_io_normal)
-		status &= ~mask; /* Clear corresponding nonfatal bits */
-	else
-		status &= mask; /* Clear corresponding fatal bits */
-	pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status);
-
-#if 0
-int pci_cleanup_aer_correct_error_status(struct pci_dev *dev)
-{
-	int pos;
 	u32 status;
 
 	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
 	if (!pos)
 		return -EIO;
 
-	pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &status);
-	pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, status);
+	pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status);
+	if (status)
+		pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status);
 
 	return 0;
 }
-#endif  /*  0  */
+EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status);
 
 static int set_device_error_reporting(struct pci_dev *dev, void *data)
 {
 	bool enable = *((bool *)data);
 
-	if (dev->pcie_type == PCIE_RC_PORT ||
-	    dev->pcie_type == PCIE_SW_UPSTREAM_PORT ||
-	    dev->pcie_type == PCIE_SW_DOWNSTREAM_PORT) {
+	if ((dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) ||
+	    (dev->pcie_type == PCI_EXP_TYPE_UPSTREAM) ||
+	    (dev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)) {
 		if (enable)
 			pci_enable_pcie_error_reporting(dev);
 		else
@@ -218,7 +203,7 @@
 	 */
 	if (atomic_read(&dev->enable_cnt) == 0)
 		return 0;
-	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	pos = pci_pcie_cap(dev);
 	if (!pos)
 		return 0;
 	/* Check if AER is enabled */
@@ -431,10 +416,9 @@
 	result = (struct find_aer_service_data *) data;
 
 	if (device->bus == &pcie_port_bus_type) {
-		struct pcie_port_data *port_data;
+		struct pcie_device *pcie = to_pcie_device(device);
 
-		port_data = pci_get_drvdata(to_pcie_device(device)->port);
-		if (port_data->port_type == PCIE_SW_DOWNSTREAM_PORT)
+		if (pcie->port->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)
 			result->is_downstream = 1;
 
 		driver = device->driver;
@@ -612,7 +596,7 @@
 	u16 reg16;
 	u32 reg32;
 
-	pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+	pos = pci_pcie_cap(pdev);
 	/* Clear PCIE Capability's Device Status */
 	pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, &reg16);
 	pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16);
@@ -874,8 +858,22 @@
  */
 int aer_init(struct pcie_device *dev)
 {
-	if (aer_osc_setup(dev) && !forceload)
-		return -ENXIO;
+	if (dev->port->aer_firmware_first) {
+		dev_printk(KERN_DEBUG, &dev->device,
+			   "PCIe errors handled by platform firmware.\n");
+		goto out;
+	}
+
+	if (aer_osc_setup(dev))
+		goto out;
 
 	return 0;
+out:
+	if (forceload) {
+		dev_printk(KERN_DEBUG, &dev->device,
+			   "aerdrv forceload requested.\n");
+		dev->port->aer_firmware_first = 0;
+		return 0;
+	}
+	return -ENXIO;
 }
diff --git a/drivers/pci/pcie/aer/ecrc.c b/drivers/pci/pcie/aer/ecrc.c
index a928d8a..a2747a6 100644
--- a/drivers/pci/pcie/aer/ecrc.c
+++ b/drivers/pci/pcie/aer/ecrc.c
@@ -51,7 +51,7 @@
 	int pos;
 	u32 reg32;
 
-	if (!dev->is_pcie)
+	if (!pci_is_pcie(dev))
 		return -ENODEV;
 
 	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
@@ -79,7 +79,7 @@
 	int pos;
 	u32 reg32;
 
-	if (!dev->is_pcie)
+	if (!pci_is_pcie(dev))
 		return -ENODEV;
 
 	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 5b7056c..5a01fc7 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -122,7 +122,7 @@
 	struct pci_bus *linkbus = link->pdev->subordinate;
 
 	list_for_each_entry(child, &linkbus->devices, bus_list) {
-		pos = pci_find_capability(child, PCI_CAP_ID_EXP);
+		pos = pci_pcie_cap(child);
 		if (!pos)
 			return;
 		pci_read_config_word(child, pos + PCI_EXP_LNKCTL, &reg16);
@@ -156,7 +156,7 @@
 
 	/* All functions should have the same cap and state, take the worst */
 	list_for_each_entry(child, &linkbus->devices, bus_list) {
-		pos = pci_find_capability(child, PCI_CAP_ID_EXP);
+		pos = pci_pcie_cap(child);
 		if (!pos)
 			return;
 		pci_read_config_dword(child, pos + PCI_EXP_LNKCAP, &reg32);
@@ -191,23 +191,23 @@
 	 * Configuration, so just check one function
 	 */
 	child = list_entry(linkbus->devices.next, struct pci_dev, bus_list);
-	BUG_ON(!child->is_pcie);
+	BUG_ON(!pci_is_pcie(child));
 
 	/* Check downstream component if bit Slot Clock Configuration is 1 */
-	cpos = pci_find_capability(child, PCI_CAP_ID_EXP);
+	cpos = pci_pcie_cap(child);
 	pci_read_config_word(child, cpos + PCI_EXP_LNKSTA, &reg16);
 	if (!(reg16 & PCI_EXP_LNKSTA_SLC))
 		same_clock = 0;
 
 	/* Check upstream component if bit Slot Clock Configuration is 1 */
-	ppos = pci_find_capability(parent, PCI_CAP_ID_EXP);
+	ppos = pci_pcie_cap(parent);
 	pci_read_config_word(parent, ppos + PCI_EXP_LNKSTA, &reg16);
 	if (!(reg16 & PCI_EXP_LNKSTA_SLC))
 		same_clock = 0;
 
 	/* Configure downstream component, all functions */
 	list_for_each_entry(child, &linkbus->devices, bus_list) {
-		cpos = pci_find_capability(child, PCI_CAP_ID_EXP);
+		cpos = pci_pcie_cap(child);
 		pci_read_config_word(child, cpos + PCI_EXP_LNKCTL, &reg16);
 		child_reg[PCI_FUNC(child->devfn)] = reg16;
 		if (same_clock)
@@ -247,7 +247,7 @@
 	dev_printk(KERN_ERR, &parent->dev,
 		   "ASPM: Could not configure common clock\n");
 	list_for_each_entry(child, &linkbus->devices, bus_list) {
-		cpos = pci_find_capability(child, PCI_CAP_ID_EXP);
+		cpos = pci_pcie_cap(child);
 		pci_write_config_word(child, cpos + PCI_EXP_LNKCTL,
 				      child_reg[PCI_FUNC(child->devfn)]);
 	}
@@ -300,7 +300,7 @@
 	u16 reg16;
 	u32 reg32;
 
-	pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+	pos = pci_pcie_cap(pdev);
 	pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, &reg32);
 	info->support = (reg32 & PCI_EXP_LNKCAP_ASPMS) >> 10;
 	info->latency_encoding_l0s = (reg32 & PCI_EXP_LNKCAP_L0SEL) >> 12;
@@ -420,7 +420,7 @@
 		    child->pcie_type != PCI_EXP_TYPE_LEG_END)
 			continue;
 
-		pos = pci_find_capability(child, PCI_CAP_ID_EXP);
+		pos = pci_pcie_cap(child);
 		pci_read_config_dword(child, pos + PCI_EXP_DEVCAP, &reg32);
 		/* Calculate endpoint L0s acceptable latency */
 		encoding = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6;
@@ -436,7 +436,7 @@
 static void pcie_config_aspm_dev(struct pci_dev *pdev, u32 val)
 {
 	u16 reg16;
-	int pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+	int pos = pci_pcie_cap(pdev);
 
 	pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
 	reg16 &= ~0x3;
@@ -503,7 +503,7 @@
 	 * very strange. Disable ASPM for the whole slot
 	 */
 	list_for_each_entry(child, &pdev->subordinate->devices, bus_list) {
-		pos = pci_find_capability(child, PCI_CAP_ID_EXP);
+		pos = pci_pcie_cap(child);
 		if (!pos)
 			return -EINVAL;
 		/*
@@ -563,7 +563,7 @@
 	struct pcie_link_state *link;
 	int blacklist = !!pcie_aspm_sanity_check(pdev);
 
-	if (aspm_disabled || !pdev->is_pcie || pdev->link_state)
+	if (aspm_disabled || !pci_is_pcie(pdev) || pdev->link_state)
 		return;
 	if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
 	    pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
@@ -629,7 +629,8 @@
 	struct pci_dev *parent = pdev->bus->self;
 	struct pcie_link_state *link, *root, *parent_link;
 
-	if (aspm_disabled || !pdev->is_pcie || !parent || !parent->link_state)
+	if (aspm_disabled || !pci_is_pcie(pdev) ||
+	    !parent || !parent->link_state)
 		return;
 	if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
 	    (parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))
@@ -670,7 +671,7 @@
 {
 	struct pcie_link_state *link = pdev->link_state;
 
-	if (aspm_disabled || !pdev->is_pcie || !link)
+	if (aspm_disabled || !pci_is_pcie(pdev) || !link)
 		return;
 	if ((pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
 	    (pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))
@@ -696,7 +697,7 @@
 	struct pci_dev *parent = pdev->bus->self;
 	struct pcie_link_state *link;
 
-	if (aspm_disabled || !pdev->is_pcie)
+	if (aspm_disabled || !pci_is_pcie(pdev))
 		return;
 	if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT ||
 	    pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)
@@ -841,8 +842,9 @@
 {
 	struct pcie_link_state *link_state = pdev->link_state;
 
-	if (!pdev->is_pcie || (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
-		pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
+	if (!pci_is_pcie(pdev) ||
+	    (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
+	     pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
 		return;
 
 	if (link_state->aspm_support)
@@ -857,8 +859,9 @@
 {
 	struct pcie_link_state *link_state = pdev->link_state;
 
-	if (!pdev->is_pcie || (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
-		pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
+	if (!pci_is_pcie(pdev) ||
+	    (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
+	     pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
 		return;
 
 	if (link_state->aspm_support)
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h
index 17ad538..aaeb9d2 100644
--- a/drivers/pci/pcie/portdrv.h
+++ b/drivers/pci/pcie/portdrv.h
@@ -11,31 +11,16 @@
 
 #include <linux/compiler.h>
 
-#if !defined(PCI_CAP_ID_PME)
-#define PCI_CAP_ID_PME			1
-#endif
-
-#if !defined(PCI_CAP_ID_EXP)
-#define PCI_CAP_ID_EXP			0x10
-#endif
-
-#define PORT_TYPE_MASK			0xf
-#define PORT_TO_SLOT_MASK		0x100
-#define SLOT_HP_CAPABLE_MASK		0x40
-#define PCIE_CAPABILITIES_REG		0x2
-#define PCIE_SLOT_CAPABILITIES_REG	0x14
-#define PCIE_PORT_DEVICE_MAXSERVICES	4
-#define PCIE_PORT_MSI_VECTOR_MASK	0x1f
+#define PCIE_PORT_DEVICE_MAXSERVICES   4
 /*
- * According to the PCI Express Base Specification 2.0, the indices of the MSI-X
- * table entires used by port services must not exceed 31
+ * According to the PCI Express Base Specification 2.0, the indices of
+ * the MSI-X table entires used by port services must not exceed 31
  */
 #define PCIE_PORT_MAX_MSIX_ENTRIES	32
 
 #define get_descriptor_id(type, service) (((type - 4) << 4) | service)
 
 extern struct bus_type pcie_port_bus_type;
-extern int pcie_port_device_probe(struct pci_dev *dev);
 extern int pcie_port_device_register(struct pci_dev *dev);
 #ifdef CONFIG_PM
 extern int pcie_port_device_suspend(struct device *dev);
diff --git a/drivers/pci/pcie/portdrv_bus.c b/drivers/pci/pcie/portdrv_bus.c
index ef3a4ee..18bf90f 100644
--- a/drivers/pci/pcie/portdrv_bus.c
+++ b/drivers/pci/pcie/portdrv_bus.c
@@ -26,7 +26,6 @@
 static int pcie_port_bus_match(struct device *dev, struct device_driver *drv)
 {
 	struct pcie_device *pciedev;
-	struct pcie_port_data *port_data;
 	struct pcie_port_service_driver *driver;
 
 	if (drv->bus != &pcie_port_bus_type || dev->bus != &pcie_port_bus_type)
@@ -38,10 +37,8 @@
 	if (driver->service != pciedev->service)
 		return 0;
 
-	port_data = pci_get_drvdata(pciedev->port);
-
-	if (driver->port_type != PCIE_ANY_PORT
-	     && driver->port_type != port_data->port_type)
+	if ((driver->port_type != PCIE_ANY_PORT) &&
+	    (driver->port_type != pciedev->port->pcie_type))
 		return 0;
 
 	return 1;
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 52f84fc..413262e 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -108,9 +108,9 @@
 		 * the value in this field indicates which MSI-X Table entry is
 		 * used to generate the interrupt message."
 		 */
-		pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
-		pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, &reg16);
-		entry = (reg16 >> 9) & PCIE_PORT_MSI_VECTOR_MASK;
+		pos = pci_pcie_cap(dev);
+		pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &reg16);
+		entry = (reg16 & PCI_EXP_FLAGS_IRQ) >> 9;
 		if (entry >= nr_entries)
 			goto Error;
 
@@ -177,37 +177,40 @@
 }
 
 /**
- * assign_interrupt_mode - choose interrupt mode for PCI Express port services
- *                         (INTx, MSI-X, MSI) and set up vectors
+ * init_service_irqs - initialize irqs for PCI Express port services
  * @dev: PCI Express port to handle
- * @vectors: Array of interrupt vectors to populate
+ * @irqs: Array of irqs to populate
  * @mask: Bitmask of port capabilities returned by get_port_device_capability()
  *
  * Return value: Interrupt mode associated with the port
  */
-static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask)
+static int init_service_irqs(struct pci_dev *dev, int *irqs, int mask)
 {
-	int irq, interrupt_mode = PCIE_PORT_NO_IRQ;
-	int i;
+	int i, irq;
 
 	/* Try to use MSI-X if supported */
-	if (!pcie_port_enable_msix(dev, vectors, mask))
-		return PCIE_PORT_MSIX_MODE;
-
+	if (!pcie_port_enable_msix(dev, irqs, mask))
+		return 0;
 	/* We're not going to use MSI-X, so try MSI and fall back to INTx */
-	if (!pci_enable_msi(dev))
-		interrupt_mode = PCIE_PORT_MSI_MODE;
+	irq = -1;
+	if (!pci_enable_msi(dev) || dev->pin)
+		irq = dev->irq;
 
-	if (interrupt_mode == PCIE_PORT_NO_IRQ && dev->pin)
-		interrupt_mode = PCIE_PORT_INTx_MODE;
-
-	irq = interrupt_mode != PCIE_PORT_NO_IRQ ? dev->irq : -1;
 	for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)
-		vectors[i] = irq;
+		irqs[i] = irq;
+	irqs[PCIE_PORT_SERVICE_VC_SHIFT] = -1;
 
-	vectors[PCIE_PORT_SERVICE_VC_SHIFT] = -1;
+	if (irq < 0)
+		return -ENODEV;
+	return 0;
+}
 
-	return interrupt_mode;
+static void cleanup_service_irqs(struct pci_dev *dev)
+{
+	if (dev->msix_enabled)
+		pci_disable_msix(dev);
+	else if (dev->msi_enabled)
+		pci_disable_msi(dev);
 }
 
 /**
@@ -226,13 +229,12 @@
 	u16 reg16;
 	u32 reg32;
 
-	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
-	pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, &reg16);
+	pos = pci_pcie_cap(dev);
+	pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &reg16);
 	/* Hot-Plug Capable */
-	if (reg16 & PORT_TO_SLOT_MASK) {
-		pci_read_config_dword(dev, 
-			pos + PCIE_SLOT_CAPABILITIES_REG, &reg32);
-		if (reg32 & SLOT_HP_CAPABLE_MASK)
+	if (reg16 & PCI_EXP_FLAGS_SLOT) {
+		pci_read_config_dword(dev, pos + PCI_EXP_SLTCAP, &reg32);
+		if (reg32 & PCI_EXP_SLTCAP_HPC)
 			services |= PCIE_PORT_SERVICE_HP;
 	}
 	/* AER capable */
@@ -241,80 +243,47 @@
 	/* VC support */
 	if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC))
 		services |= PCIE_PORT_SERVICE_VC;
+	/* Root ports are capable of generating PME too */
+	if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
+		services |= PCIE_PORT_SERVICE_PME;
 
 	return services;
 }
 
 /**
- * pcie_device_init - initialize PCI Express port service device
- * @dev: Port service device to initialize
- * @parent: PCI Express port to associate the service device with
- * @port_type: Type of the port
- * @service_type: Type of service to associate with the service device
+ * pcie_device_init - allocate and initialize PCI Express port service device
+ * @pdev: PCI Express port to associate the service device with
+ * @service: Type of service to associate with the service device
  * @irq: Interrupt vector to associate with the service device
  */
-static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev, 
-	int service_type, int irq)
+static int pcie_device_init(struct pci_dev *pdev, int service, int irq)
 {
-	struct pcie_port_data *port_data = pci_get_drvdata(parent);
+	int retval;
+	struct pcie_device *pcie;
 	struct device *device;
-	int port_type = port_data->port_type;
 
-	dev->port = parent;
-	dev->irq = irq;
-	dev->service = service_type;
+	pcie = kzalloc(sizeof(*pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+	pcie->port = pdev;
+	pcie->irq = irq;
+	pcie->service = service;
 
 	/* Initialize generic device interface */
-	device = &dev->device;
-	memset(device, 0, sizeof(struct device));
+	device = &pcie->device;
 	device->bus = &pcie_port_bus_type;
-	device->driver = NULL;
-	dev_set_drvdata(device, NULL);
 	device->release = release_pcie_device;	/* callback to free pcie dev */
 	dev_set_name(device, "%s:pcie%02x",
-		 pci_name(parent), get_descriptor_id(port_type, service_type));
-	device->parent = &parent->dev;
-}
+		     pci_name(pdev),
+		     get_descriptor_id(pdev->pcie_type, service));
+	device->parent = &pdev->dev;
 
-/**
- * alloc_pcie_device - allocate PCI Express port service device structure
- * @parent: PCI Express port to associate the service device with
- * @port_type: Type of the port
- * @service_type: Type of service to associate with the service device
- * @irq: Interrupt vector to associate with the service device
- */
-static struct pcie_device* alloc_pcie_device(struct pci_dev *parent,
-	int service_type, int irq)
-{
-	struct pcie_device *device;
-
-	device = kzalloc(sizeof(struct pcie_device), GFP_KERNEL);
-	if (!device)
-		return NULL;
-
-	pcie_device_init(parent, device, service_type, irq);
-	return device;
-}
-
-/**
- * pcie_port_device_probe - check if device is a PCI Express port
- * @dev: Device to check
- */
-int pcie_port_device_probe(struct pci_dev *dev)
-{
-	int pos, type;
-	u16 reg;
-
-	if (!(pos = pci_find_capability(dev, PCI_CAP_ID_EXP)))
-		return -ENODEV;
-
-	pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, &reg);
-	type = (reg >> 4) & PORT_TYPE_MASK;
-	if (	type == PCIE_RC_PORT || type == PCIE_SW_UPSTREAM_PORT ||
-		type == PCIE_SW_DOWNSTREAM_PORT )
-		return 0;
-
-	return -ENODEV;
+	retval = device_register(device);
+	if (retval)
+		kfree(pcie);
+	else
+		get_device(device);
+	return retval;
 }
 
 /**
@@ -326,77 +295,49 @@
  */
 int pcie_port_device_register(struct pci_dev *dev)
 {
-	struct pcie_port_data *port_data;
-	int status, capabilities, irq_mode, i, nr_serv;
-	int vectors[PCIE_PORT_DEVICE_MAXSERVICES];
-	u16 reg16;
+	int status, capabilities, i, nr_service;
+	int irqs[PCIE_PORT_DEVICE_MAXSERVICES];
 
-	port_data = kzalloc(sizeof(*port_data), GFP_KERNEL);
-	if (!port_data)
-		return -ENOMEM;
-	pci_set_drvdata(dev, port_data);
-
-	/* Get port type */
-	pci_read_config_word(dev,
-		pci_find_capability(dev, PCI_CAP_ID_EXP) +
-		PCIE_CAPABILITIES_REG, &reg16);
-	port_data->port_type = (reg16 >> 4) & PORT_TYPE_MASK;
-
+	/* Get and check PCI Express port services */
 	capabilities = get_port_device_capability(dev);
-	/* Root ports are capable of generating PME too */
-	if (port_data->port_type == PCIE_RC_PORT)
-		capabilities |= PCIE_PORT_SERVICE_PME;
+	if (!capabilities)
+		return -ENODEV;
 
-	irq_mode = assign_interrupt_mode(dev, vectors, capabilities);
-	if (irq_mode == PCIE_PORT_NO_IRQ) {
-		/*
-		 * Don't use service devices that require interrupts if there is
-		 * no way to generate them.
-		 */
-		if (!(capabilities & PCIE_PORT_SERVICE_VC)) {
-			status = -ENODEV;
-			goto Error;
-		}
-		capabilities = PCIE_PORT_SERVICE_VC;
-	}
-	port_data->port_irq_mode = irq_mode;
-
+	/* Enable PCI Express port device */
 	status = pci_enable_device(dev);
 	if (status)
-		goto Error;
+		return status;
 	pci_set_master(dev);
+	/*
+	 * Initialize service irqs. Don't use service devices that
+	 * require interrupts if there is no way to generate them.
+	 */
+	status = init_service_irqs(dev, irqs, capabilities);
+	if (status) {
+		capabilities &= PCIE_PORT_SERVICE_VC;
+		if (!capabilities)
+			goto error_disable;
+	}
 
 	/* Allocate child services if any */
-	for (i = 0, nr_serv = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
-		struct pcie_device *child;
+	status = -ENODEV;
+	nr_service = 0;
+	for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
 		int service = 1 << i;
-
 		if (!(capabilities & service))
 			continue;
-
-		child = alloc_pcie_device(dev, service, vectors[i]);
-		if (!child)
-			continue;
-
-		status = device_register(&child->device);
-		if (status) {
-			kfree(child);
-			continue;
-		}
-
-		get_device(&child->device);
-		nr_serv++;
+		if (!pcie_device_init(dev, service, irqs[i]))
+			nr_service++;
 	}
-	if (!nr_serv) {
-		pci_disable_device(dev);
-		status = -ENODEV;
-		goto Error;
-	}
+	if (!nr_service)
+		goto error_cleanup_irqs;
 
 	return 0;
 
- Error:
-	kfree(port_data);
+error_cleanup_irqs:
+	cleanup_service_irqs(dev);
+error_disable:
+	pci_disable_device(dev);
 	return status;
 }
 
@@ -464,21 +405,9 @@
  */
 void pcie_port_device_remove(struct pci_dev *dev)
 {
-	struct pcie_port_data *port_data = pci_get_drvdata(dev);
-
 	device_for_each_child(&dev->dev, NULL, remove_iter);
+	cleanup_service_irqs(dev);
 	pci_disable_device(dev);
-
-	switch (port_data->port_irq_mode) {
-	case PCIE_PORT_MSIX_MODE:
-		pci_disable_msix(dev);
-		break;
-	case PCIE_PORT_MSI_MODE:
-		pci_disable_msi(dev);
-		break;
-	}
-
-	kfree(port_data);
 }
 
 /**
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index f635e47..ce52ea3 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -67,14 +67,16 @@
  * this port device.
  *
  */
-static int __devinit pcie_portdrv_probe (struct pci_dev *dev, 
-				const struct pci_device_id *id )
+static int __devinit pcie_portdrv_probe(struct pci_dev *dev,
+					const struct pci_device_id *id)
 {
-	int			status;
+	int status;
 
-	status = pcie_port_device_probe(dev);
-	if (status)
-		return status;
+	if (!pci_is_pcie(dev) ||
+	    ((dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
+	     (dev->pcie_type != PCI_EXP_TYPE_UPSTREAM) &&
+	     (dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)))
+		return -ENODEV;
 
         if (!dev->irq && dev->pin) {
 		dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; "
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 8105e32..98ffb2d 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/cpumask.h>
 #include <linux/pci-aspm.h>
+#include <acpi/acpi_hest.h>
 #include "pci.h"
 
 #define CARDBUS_LATENCY_TIMER	176	/* secondary latency timer */
@@ -163,12 +164,12 @@
 {
 	u32 l, sz, mask;
 
-	mask = type ? ~PCI_ROM_ADDRESS_ENABLE : ~0;
+	mask = type ? PCI_ROM_ADDRESS_MASK : ~0;
 
 	res->name = pci_name(dev);
 
 	pci_read_config_dword(dev, pos, &l);
-	pci_write_config_dword(dev, pos, mask);
+	pci_write_config_dword(dev, pos, l | mask);
 	pci_read_config_dword(dev, pos, &sz);
 	pci_write_config_dword(dev, pos, l);
 
@@ -223,9 +224,13 @@
 			goto fail;
 
 		if ((sizeof(resource_size_t) < 8) && (sz64 > 0x100000000ULL)) {
-			dev_err(&dev->dev, "can't handle 64-bit BAR\n");
+			dev_err(&dev->dev, "reg %x: can't handle 64-bit BAR\n",
+				pos);
 			goto fail;
-		} else if ((sizeof(resource_size_t) < 8) && l) {
+		}
+
+		res->flags |= IORESOURCE_MEM_64;
+		if ((sizeof(resource_size_t) < 8) && l) {
 			/* Address above 32-bit boundary; disable the BAR */
 			pci_write_config_dword(dev, pos, 0);
 			pci_write_config_dword(dev, pos + 4, 0);
@@ -234,14 +239,9 @@
 		} else {
 			res->start = l64;
 			res->end = l64 + sz64;
-			dev_printk(KERN_DEBUG, &dev->dev,
-				"reg %x %s: %pR\n", pos,
-				 (res->flags & IORESOURCE_PREFETCH) ?
-					"64bit mmio pref" : "64bit mmio",
-				 res);
+			dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n",
+				   pos, res);
 		}
-
-		res->flags |= IORESOURCE_MEM_64;
 	} else {
 		sz = pci_size(l, sz, mask);
 
@@ -251,11 +251,7 @@
 		res->start = l;
 		res->end = l + sz;
 
-		dev_printk(KERN_DEBUG, &dev->dev, "reg %x %s: %pR\n", pos,
-			(res->flags & IORESOURCE_IO) ? "io port" :
-			 ((res->flags & IORESOURCE_PREFETCH) ?
-				 "32bit mmio pref" : "32bit mmio"),
-			res);
+		dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res);
 	}
 
  out:
@@ -297,8 +293,11 @@
 	if (pci_is_root_bus(child))	/* It's a host bus, nothing to read */
 		return;
 
+	dev_info(&dev->dev, "PCI bridge to [bus %02x-%02x]%s\n",
+		 child->secondary, child->subordinate,
+		 dev->transparent ? " (subtractive decode)": "");
+
 	if (dev->transparent) {
-		dev_info(&dev->dev, "transparent bridge\n");
 		for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++)
 			child->resource[i] = child->parent->resource[i - 3];
 	}
@@ -323,7 +322,7 @@
 			res->start = base;
 		if (!res->end)
 			res->end = limit + 0xfff;
-		dev_printk(KERN_DEBUG, &dev->dev, "bridge io port: %pR\n", res);
+		dev_printk(KERN_DEBUG, &dev->dev, "  bridge window %pR\n", res);
 	}
 
 	res = child->resource[1];
@@ -335,8 +334,7 @@
 		res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
 		res->start = base;
 		res->end = limit + 0xfffff;
-		dev_printk(KERN_DEBUG, &dev->dev, "bridge 32bit mmio: %pR\n",
-			res);
+		dev_printk(KERN_DEBUG, &dev->dev, "  bridge window %pR\n", res);
 	}
 
 	res = child->resource[2];
@@ -375,9 +373,7 @@
 			res->flags |= IORESOURCE_MEM_64;
 		res->start = base;
 		res->end = limit + 0xfffff;
-		dev_printk(KERN_DEBUG, &dev->dev, "bridge %sbit mmio pref: %pR\n",
-			(res->flags & PCI_PREF_RANGE_TYPE_64) ? "64" : "32",
-			res);
+		dev_printk(KERN_DEBUG, &dev->dev, "  bridge window %pR\n", res);
 	}
 }
 
@@ -651,13 +647,14 @@
 		    (child->number > bus->subordinate) ||
 		    (child->number < bus->number) ||
 		    (child->subordinate < bus->number)) {
-			pr_debug("PCI: Bus #%02x (-#%02x) is %s "
-				"hidden behind%s bridge #%02x (-#%02x)\n",
+			dev_info(&child->dev, "[bus %02x-%02x] %s "
+				"hidden behind%s bridge %s [bus %02x-%02x]\n",
 				child->number, child->subordinate,
 				(bus->number > child->subordinate &&
 				 bus->subordinate < child->number) ?
 					"wholly" : "partially",
 				bus->self->transparent ? " transparent" : "",
+				dev_name(&bus->dev),
 				bus->number, bus->subordinate);
 		}
 		bus = bus->parent;
@@ -693,6 +690,7 @@
 	if (!pos)
 		return;
 	pdev->is_pcie = 1;
+	pdev->pcie_cap = pos;
 	pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
 	pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4;
 }
@@ -703,7 +701,7 @@
 	u16 reg16;
 	u32 reg32;
 
-	pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+	pos = pci_pcie_cap(pdev);
 	if (!pos)
 		return;
 	pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
@@ -714,6 +712,12 @@
 		pdev->is_hotplug_bridge = 1;
 }
 
+static void set_pci_aer_firmware_first(struct pci_dev *pdev)
+{
+	if (acpi_hest_firmware_first_pci(pdev))
+		pdev->aer_firmware_first = 1;
+}
+
 #define LEGACY_IO_RESOURCE	(IORESOURCE_IO | IORESOURCE_PCI_FIXED)
 
 /**
@@ -731,6 +735,7 @@
 	u32 class;
 	u8 hdr_type;
 	struct pci_slot *slot;
+	int pos = 0;
 
 	if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type))
 		return -EIO;
@@ -742,6 +747,7 @@
 	dev->multifunction = !!(hdr_type & 0x80);
 	dev->error_state = pci_channel_io_normal;
 	set_pcie_port_type(dev);
+	set_pci_aer_firmware_first(dev);
 
 	list_for_each_entry(slot, &dev->bus->slots, list)
 		if (PCI_SLOT(dev->devfn) == slot->number)
@@ -822,6 +828,11 @@
 		dev->transparent = ((dev->class & 0xff) == 1);
 		pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
 		set_pcie_hotplug_bridge(dev);
+		pos = pci_find_capability(dev, PCI_CAP_ID_SSVID);
+		if (pos) {
+			pci_read_config_word(dev, pos + PCI_SSVID_VENDOR_ID, &dev->subsystem_vendor);
+			pci_read_config_word(dev, pos + PCI_SSVID_DEVICE_ID, &dev->subsystem_device);
+		}
 		break;
 
 	case PCI_HEADER_TYPE_CARDBUS:		    /* CardBus bridge header */
@@ -907,7 +918,7 @@
 	if (class == PCI_CLASS_BRIDGE_HOST)
 		return pci_cfg_space_size_ext(dev);
 
-	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	pos = pci_pcie_cap(dev);
 	if (!pos) {
 		pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
 		if (!pos)
@@ -1014,6 +1025,9 @@
 
 	/* Single Root I/O Virtualization */
 	pci_iov_init(dev);
+
+	/* Enable ACS P2P upstream forwarding */
+	pci_enable_acs(dev);
 }
 
 void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
@@ -1110,7 +1124,7 @@
 	unsigned int devfn, pass, max = bus->secondary;
 	struct pci_dev *dev;
 
-	pr_debug("PCI: Scanning bus %04x:%02x\n", pci_domain_nr(bus), bus->number);
+	dev_dbg(&bus->dev, "scanning bus\n");
 
 	/* Go find them, Rover! */
 	for (devfn = 0; devfn < 0x100; devfn += 8)
@@ -1124,8 +1138,7 @@
 	 * all PCI-to-PCI bridges on this bus.
 	 */
 	if (!bus->is_added) {
-		pr_debug("PCI: Fixups for bus %04x:%02x\n",
-			 pci_domain_nr(bus), bus->number);
+		dev_dbg(&bus->dev, "fixups for bus\n");
 		pcibios_fixup_bus(bus);
 		if (pci_is_root_bus(bus))
 			bus->is_added = 1;
@@ -1145,8 +1158,7 @@
 	 *
 	 * Return how far we've got finding sub-buses.
 	 */
-	pr_debug("PCI: Bus scan for %04x:%02x returning with max=%02x\n",
-		pci_domain_nr(bus), bus->number, max);
+	dev_dbg(&bus->dev, "bus scan returning with max=%02x\n", max);
 	return max;
 }
 
@@ -1154,7 +1166,7 @@
 		int bus, struct pci_ops *ops, void *sysdata)
 {
 	int error;
-	struct pci_bus *b;
+	struct pci_bus *b, *b2;
 	struct device *dev;
 
 	b = pci_alloc_bus();
@@ -1170,9 +1182,10 @@
 	b->sysdata = sysdata;
 	b->ops = ops;
 
-	if (pci_find_bus(pci_domain_nr(b), bus)) {
+	b2 = pci_find_bus(pci_domain_nr(b), bus);
+	if (b2) {
 		/* If we already got to this bus through a different bridge, ignore it */
-		pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus);
+		dev_dbg(&b2->dev, "bus already known\n");
 		goto err_out;
 	}
 
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 245d2cd..7cfa7c3 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -357,7 +357,7 @@
 		pcibios_bus_to_resource(dev, res, &bus_region);
 
 		pci_claim_resource(dev, nr);
-		dev_info(&dev->dev, "quirk: region %04x-%04x claimed by %s\n", region, region + size - 1, name);
+		dev_info(&dev->dev, "quirk: %pR claimed by %s\n", res, name);
 	}
 }	
 
@@ -1680,6 +1680,7 @@
  */
 #define AMD_813X_MISC			0x40
 #define AMD_813X_NOIOAMODE		(1<<0)
+#define AMD_813X_REV_B1			0x12
 #define AMD_813X_REV_B2			0x13
 
 static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev)
@@ -1688,7 +1689,8 @@
 
 	if (noioapicquirk)
 		return;
-	if (dev->revision == AMD_813X_REV_B2)
+	if ((dev->revision == AMD_813X_REV_B1) ||
+	    (dev->revision == AMD_813X_REV_B2))
 		return;
 
 	pci_read_config_dword(dev, AMD_813X_MISC, &pci_config_dword);
@@ -1698,8 +1700,10 @@
 	dev_info(&dev->dev, "disabled boot interrupts on device [%04x:%04x]\n",
 		 dev->vendor, dev->device);
 }
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,   PCI_DEVICE_ID_AMD_8131_BRIDGE, 	quirk_disable_amd_813x_boot_interrupt);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD,   PCI_DEVICE_ID_AMD_8132_BRIDGE, 	quirk_disable_amd_813x_boot_interrupt);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_8131_BRIDGE,	quirk_disable_amd_813x_boot_interrupt);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_8131_BRIDGE,	quirk_disable_amd_813x_boot_interrupt);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_8132_BRIDGE,	quirk_disable_amd_813x_boot_interrupt);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_8132_BRIDGE,	quirk_disable_amd_813x_boot_interrupt);
 
 #define AMD_8111_PCI_IRQ_ROUTING	0x56
 
@@ -2595,9 +2599,37 @@
 static int __init pci_apply_final_quirks(void)
 {
 	struct pci_dev *dev = NULL;
+	u8 cls = 0;
+	u8 tmp;
+
+	if (pci_cache_line_size)
+		printk(KERN_DEBUG "PCI: CLS %u bytes\n",
+		       pci_cache_line_size << 2);
 
 	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		pci_fixup_device(pci_fixup_final, dev);
+		/*
+		 * If arch hasn't set it explicitly yet, use the CLS
+		 * value shared by all PCI devices.  If there's a
+		 * mismatch, fall back to the default value.
+		 */
+		if (!pci_cache_line_size) {
+			pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp);
+			if (!cls)
+				cls = tmp;
+			if (!tmp || cls == tmp)
+				continue;
+
+			printk(KERN_DEBUG "PCI: CLS mismatch (%u != %u), "
+			       "using %u bytes\n", cls << 2, tmp << 2,
+			       pci_dfl_cache_line_size << 2);
+			pci_cache_line_size = pci_dfl_cache_line_size;
+		}
+	}
+	if (!pci_cache_line_size) {
+		printk(KERN_DEBUG "PCI: CLS %u bytes, default %u\n",
+		       cls << 2, pci_dfl_cache_line_size << 2);
+		pci_cache_line_size = cls;
 	}
 
 	return 0;
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index ec41535..6dae871 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -26,14 +26,14 @@
 {
 	struct pci_dev *tmp = NULL;
 
-	if (pdev->is_pcie)
+	if (pci_is_pcie(pdev))
 		return NULL;
 	while (1) {
 		if (pci_is_root_bus(pdev->bus))
 			break;
 		pdev = pdev->bus->self;
 		/* a p2p bridge */
-		if (!pdev->is_pcie) {
+		if (!pci_is_pcie(pdev)) {
 			tmp = pdev;
 			continue;
 		}
@@ -149,32 +149,33 @@
 }
 
 /**
- * pci_get_bus_and_slot - locate PCI device from a given PCI bus & slot
- * @bus: number of PCI bus on which desired PCI device resides
- * @devfn: encodes number of PCI slot in which the desired PCI
- * device resides and the logical device number within that slot
- * in case of multi-function devices.
+ * pci_get_domain_bus_and_slot - locate PCI device for a given PCI domain (segment), bus, and slot
+ * @domain: PCI domain/segment on which the PCI device resides.
+ * @bus: PCI bus on which desired PCI device resides
+ * @devfn: encodes number of PCI slot in which the desired PCI device
+ * resides and the logical device number within that slot in case of
+ * multi-function devices.
  *
- * Note: the bus/slot search is limited to PCI domain (segment) 0.
- *
- * Given a PCI bus and slot/function number, the desired PCI device
- * is located in system global list of PCI devices.  If the device
- * is found, a pointer to its data structure is returned.  If no
- * device is found, %NULL is returned. The returned device has its
- * reference count bumped by one.
+ * Given a PCI domain, bus, and slot/function number, the desired PCI
+ * device is located in the list of PCI devices. If the device is
+ * found, its reference count is increased and this function returns a
+ * pointer to its data structure.  The caller must decrement the
+ * reference count by calling pci_dev_put().  If no device is found,
+ * %NULL is returned.
  */
-
-struct pci_dev * pci_get_bus_and_slot(unsigned int bus, unsigned int devfn)
+struct pci_dev *pci_get_domain_bus_and_slot(int domain, unsigned int bus,
+					    unsigned int devfn)
 {
 	struct pci_dev *dev = NULL;
 
 	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-		if (pci_domain_nr(dev->bus) == 0 &&
-		   (dev->bus->number == bus && dev->devfn == devfn))
+		if (pci_domain_nr(dev->bus) == domain &&
+		    (dev->bus->number == bus && dev->devfn == devfn))
 			return dev;
 	}
 	return NULL;
 }
+EXPORT_SYMBOL(pci_get_domain_bus_and_slot);
 
 static int match_pci_dev_by_id(struct device *dev, void *data)
 {
@@ -354,5 +355,4 @@
 EXPORT_SYMBOL(pci_get_device);
 EXPORT_SYMBOL(pci_get_subsys);
 EXPORT_SYMBOL(pci_get_slot);
-EXPORT_SYMBOL(pci_get_bus_and_slot);
 EXPORT_SYMBOL(pci_get_class);
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index cb1a027..c48cd37 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -71,53 +71,50 @@
 void pci_setup_cardbus(struct pci_bus *bus)
 {
 	struct pci_dev *bridge = bus->self;
+	struct resource *res;
 	struct pci_bus_region region;
 
-	dev_info(&bridge->dev, "CardBus bridge, secondary bus %04x:%02x\n",
-		 pci_domain_nr(bus), bus->number);
+	dev_info(&bridge->dev, "CardBus bridge to [bus %02x-%02x]\n",
+		 bus->secondary, bus->subordinate);
 
-	pcibios_resource_to_bus(bridge, &region, bus->resource[0]);
-	if (bus->resource[0]->flags & IORESOURCE_IO) {
+	res = bus->resource[0];
+	pcibios_resource_to_bus(bridge, &region, res);
+	if (res->flags & IORESOURCE_IO) {
 		/*
 		 * The IO resource is allocated a range twice as large as it
 		 * would normally need.  This allows us to set both IO regs.
 		 */
-		dev_info(&bridge->dev, "  IO window: %#08lx-%#08lx\n",
-		       (unsigned long)region.start,
-		       (unsigned long)region.end);
+		dev_info(&bridge->dev, "  bridge window %pR\n", res);
 		pci_write_config_dword(bridge, PCI_CB_IO_BASE_0,
 					region.start);
 		pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0,
 					region.end);
 	}
 
-	pcibios_resource_to_bus(bridge, &region, bus->resource[1]);
-	if (bus->resource[1]->flags & IORESOURCE_IO) {
-		dev_info(&bridge->dev, "  IO window: %#08lx-%#08lx\n",
-		       (unsigned long)region.start,
-		       (unsigned long)region.end);
+	res = bus->resource[1];
+	pcibios_resource_to_bus(bridge, &region, res);
+	if (res->flags & IORESOURCE_IO) {
+		dev_info(&bridge->dev, "  bridge window %pR\n", res);
 		pci_write_config_dword(bridge, PCI_CB_IO_BASE_1,
 					region.start);
 		pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1,
 					region.end);
 	}
 
-	pcibios_resource_to_bus(bridge, &region, bus->resource[2]);
-	if (bus->resource[2]->flags & IORESOURCE_MEM) {
-		dev_info(&bridge->dev, "  PREFETCH window: %#08lx-%#08lx\n",
-		       (unsigned long)region.start,
-		       (unsigned long)region.end);
+	res = bus->resource[2];
+	pcibios_resource_to_bus(bridge, &region, res);
+	if (res->flags & IORESOURCE_MEM) {
+		dev_info(&bridge->dev, "  bridge window %pR\n", res);
 		pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0,
 					region.start);
 		pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0,
 					region.end);
 	}
 
-	pcibios_resource_to_bus(bridge, &region, bus->resource[3]);
-	if (bus->resource[3]->flags & IORESOURCE_MEM) {
-		dev_info(&bridge->dev, "  MEM window: %#08lx-%#08lx\n",
-		       (unsigned long)region.start,
-		       (unsigned long)region.end);
+	res = bus->resource[3];
+	pcibios_resource_to_bus(bridge, &region, res);
+	if (res->flags & IORESOURCE_MEM) {
+		dev_info(&bridge->dev, "  bridge window %pR\n", res);
 		pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1,
 					region.start);
 		pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1,
@@ -140,34 +137,33 @@
 static void pci_setup_bridge(struct pci_bus *bus)
 {
 	struct pci_dev *bridge = bus->self;
+	struct resource *res;
 	struct pci_bus_region region;
 	u32 l, bu, lu, io_upper16;
-	int pref_mem64;
 
 	if (pci_is_enabled(bridge))
 		return;
 
-	dev_info(&bridge->dev, "PCI bridge, secondary bus %04x:%02x\n",
-		 pci_domain_nr(bus), bus->number);
+	dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n",
+		 bus->secondary, bus->subordinate);
 
 	/* Set up the top and bottom of the PCI I/O segment for this bus. */
-	pcibios_resource_to_bus(bridge, &region, bus->resource[0]);
-	if (bus->resource[0]->flags & IORESOURCE_IO) {
+	res = bus->resource[0];
+	pcibios_resource_to_bus(bridge, &region, res);
+	if (res->flags & IORESOURCE_IO) {
 		pci_read_config_dword(bridge, PCI_IO_BASE, &l);
 		l &= 0xffff0000;
 		l |= (region.start >> 8) & 0x00f0;
 		l |= region.end & 0xf000;
 		/* Set up upper 16 bits of I/O base/limit. */
 		io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
-		dev_info(&bridge->dev, "  IO window: %#04lx-%#04lx\n",
-		    (unsigned long)region.start,
-		    (unsigned long)region.end);
+		dev_info(&bridge->dev, "  bridge window %pR\n", res);
 	}
 	else {
 		/* Clear upper 16 bits of I/O base/limit. */
 		io_upper16 = 0;
 		l = 0x00f0;
-		dev_info(&bridge->dev, "  IO window: disabled\n");
+		dev_info(&bridge->dev, "  bridge window [io  disabled]\n");
 	}
 	/* Temporarily disable the I/O range before updating PCI_IO_BASE. */
 	pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0x0000ffff);
@@ -178,17 +174,16 @@
 
 	/* Set up the top and bottom of the PCI Memory segment
 	   for this bus. */
-	pcibios_resource_to_bus(bridge, &region, bus->resource[1]);
-	if (bus->resource[1]->flags & IORESOURCE_MEM) {
+	res = bus->resource[1];
+	pcibios_resource_to_bus(bridge, &region, res);
+	if (res->flags & IORESOURCE_MEM) {
 		l = (region.start >> 16) & 0xfff0;
 		l |= region.end & 0xfff00000;
-		dev_info(&bridge->dev, "  MEM window: %#08lx-%#08lx\n",
-		    (unsigned long)region.start,
-		    (unsigned long)region.end);
+		dev_info(&bridge->dev, "  bridge window %pR\n", res);
 	}
 	else {
 		l = 0x0000fff0;
-		dev_info(&bridge->dev, "  MEM window: disabled\n");
+		dev_info(&bridge->dev, "  bridge window [mem disabled]\n");
 	}
 	pci_write_config_dword(bridge, PCI_MEMORY_BASE, l);
 
@@ -198,34 +193,27 @@
 	pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
 
 	/* Set up PREF base/limit. */
-	pref_mem64 = 0;
 	bu = lu = 0;
-	pcibios_resource_to_bus(bridge, &region, bus->resource[2]);
-	if (bus->resource[2]->flags & IORESOURCE_PREFETCH) {
-		int width = 8;
+	res = bus->resource[2];
+	pcibios_resource_to_bus(bridge, &region, res);
+	if (res->flags & IORESOURCE_PREFETCH) {
 		l = (region.start >> 16) & 0xfff0;
 		l |= region.end & 0xfff00000;
-		if (bus->resource[2]->flags & IORESOURCE_MEM_64) {
-			pref_mem64 = 1;
+		if (res->flags & IORESOURCE_MEM_64) {
 			bu = upper_32_bits(region.start);
 			lu = upper_32_bits(region.end);
-			width = 16;
 		}
-		dev_info(&bridge->dev, "  PREFETCH window: %#0*llx-%#0*llx\n",
-				width, (unsigned long long)region.start,
-				width, (unsigned long long)region.end);
+		dev_info(&bridge->dev, "  bridge window %pR\n", res);
 	}
 	else {
 		l = 0x0000fff0;
-		dev_info(&bridge->dev, "  PREFETCH window: disabled\n");
+		dev_info(&bridge->dev, "  bridge window [mem pref disabled]\n");
 	}
 	pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
 
-	if (pref_mem64) {
-		/* Set the upper 32 bits of PREF base & limit. */
-		pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu);
-		pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
-	}
+	/* Set the upper 32 bits of PREF base & limit. */
+	pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu);
+	pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
 
 	pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl);
 }
@@ -345,6 +333,10 @@
 #endif
 	size = ALIGN(size + size1, 4096);
 	if (!size) {
+		if (b_res->start || b_res->end)
+			dev_info(&bus->self->dev, "disabling bridge window "
+				 "%pR to [bus %02x-%02x] (unused)\n", b_res,
+				 bus->secondary, bus->subordinate);
 		b_res->flags = 0;
 		return;
 	}
@@ -390,8 +382,9 @@
 			align = pci_resource_alignment(dev, r);
 			order = __ffs(align) - 20;
 			if (order > 11) {
-				dev_warn(&dev->dev, "BAR %d bad alignment %llx: "
-					 "%pR\n", i, (unsigned long long)align, r);
+				dev_warn(&dev->dev, "disabling BAR %d: %pR "
+					 "(bad alignment %#llx)\n", i, r,
+					 (unsigned long long) align);
 				r->flags = 0;
 				continue;
 			}
@@ -425,6 +418,10 @@
 	}
 	size = ALIGN(size, min_align);
 	if (!size) {
+		if (b_res->start || b_res->end)
+			dev_info(&bus->self->dev, "disabling bridge window "
+				 "%pR to [bus %02x-%02x] (unused)\n", b_res,
+				 bus->secondary, bus->subordinate);
 		b_res->flags = 0;
 		return 1;
 	}
@@ -582,10 +579,7 @@
                 if (!res || !res->end)
                         continue;
 
-		dev_printk(KERN_DEBUG, &bus->dev, "resource %d %s %pR\n", i,
-			   (res->flags & IORESOURCE_IO) ? "io: " :
-			    ((res->flags & IORESOURCE_PREFETCH)? "pref mem":"mem:"),
-			   res);
+		dev_printk(KERN_DEBUG, &bus->dev, "resource %d %pR\n", i, res);
         }
 }
 
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index c54526b..7d678bb 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -51,12 +51,6 @@
 
 	pcibios_resource_to_bus(dev, &region, res);
 
-	dev_dbg(&dev->dev, "BAR %d: got res %pR bus [%#llx-%#llx] "
-		"flags %#lx\n", resno, res,
-		 (unsigned long long)region.start,
-		 (unsigned long long)region.end,
-		 (unsigned long)res->flags);
-
 	new = region.start | (res->flags & PCI_REGION_FLAG_MASK);
 	if (res->flags & IORESOURCE_IO)
 		mask = (u32)PCI_BASE_ADDRESS_IO_MASK;
@@ -91,9 +85,9 @@
 		}
 	}
 	res->flags &= ~IORESOURCE_UNSET;
-	dev_dbg(&dev->dev, "BAR %d: moved to bus [%#llx-%#llx] flags %#lx\n",
-		resno, (unsigned long long)region.start,
-		(unsigned long long)region.end, res->flags);
+	dev_info(&dev->dev, "BAR %d: set to %pR (PCI address [%#llx-%#llx]\n",
+		 resno, res, (unsigned long long)region.start,
+		 (unsigned long long)region.end);
 }
 
 int pci_claim_resource(struct pci_dev *dev, int resource)
@@ -103,20 +97,17 @@
 	int err;
 
 	root = pci_find_parent_resource(dev, res);
-
-	err = -EINVAL;
-	if (root != NULL)
-		err = request_resource(root, res);
-
-	if (err) {
-		const char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge";
-		dev_err(&dev->dev, "BAR %d: %s of %s %pR\n",
-			resource,
-			root ? "address space collision on" :
-				"no parent found for",
-			dtype, res);
+	if (!root) {
+		dev_err(&dev->dev, "no compatible bridge window for %pR\n",
+			res);
+		return -EINVAL;
 	}
 
+	err = request_resource(root, res);
+	if (err)
+		dev_err(&dev->dev,
+			"address space collision: %pR already in use\n", res);
+
 	return err;
 }
 EXPORT_SYMBOL(pci_claim_resource);
@@ -124,7 +115,7 @@
 #ifdef CONFIG_PCI_QUIRKS
 void pci_disable_bridge_window(struct pci_dev *dev)
 {
-	dev_dbg(&dev->dev, "Disabling bridge window.\n");
+	dev_info(&dev->dev, "disabling bridge mem windows\n");
 
 	/* MMIO Base/Limit */
 	pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0);
@@ -165,6 +156,7 @@
 
 	if (!ret) {
 		res->flags &= ~IORESOURCE_STARTALIGN;
+		dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res);
 		if (resno < PCI_BRIDGE_RESOURCES)
 			pci_update_resource(dev, resno);
 	}
@@ -178,12 +170,12 @@
 	resource_size_t align;
 	struct pci_bus *bus;
 	int ret;
+	char *type;
 
 	align = pci_resource_alignment(dev, res);
 	if (!align) {
-		dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus "
-			"alignment) %pR flags %#lx\n",
-			resno, res, res->flags);
+		dev_info(&dev->dev, "BAR %d: can't assign %pR "
+			 "(bogus alignment)\n", resno, res);
 		return -EINVAL;
 	}
 
@@ -198,9 +190,20 @@
 		break;
 	}
 
-	if (ret)
-		dev_info(&dev->dev, "BAR %d: can't allocate %s resource %pR\n",
-			resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res);
+	if (ret) {
+		if (res->flags & IORESOURCE_MEM)
+			if (res->flags & IORESOURCE_PREFETCH)
+				type = "mem pref";
+			else
+				type = "mem";
+		else if (res->flags & IORESOURCE_IO)
+			type = "io";
+		else
+			type = "unknown";
+		dev_info(&dev->dev,
+			 "BAR %d: can't assign %s (size %#llx)\n",
+			 resno, type, (unsigned long long) resource_size(res));
+	}
 
 	return ret;
 }
@@ -225,9 +228,8 @@
 
 		r_align = pci_resource_alignment(dev, r);
 		if (!r_align) {
-			dev_warn(&dev->dev, "BAR %d: bogus alignment "
-				"%pR flags %#lx\n",
-				i, r, r->flags);
+			dev_warn(&dev->dev, "BAR %d: %pR has bogus alignment\n",
+				 i, r);
 			continue;
 		}
 		for (list = head; ; list = list->next) {
@@ -274,8 +276,8 @@
 			continue;
 
 		if (!r->parent) {
-			dev_err(&dev->dev, "device not available because of "
-				"BAR %d %pR collisions\n", i, r);
+			dev_err(&dev->dev, "device not available "
+				"(can't reserve %pR)\n", r);
 			return -EINVAL;
 		}
 
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
index 4cd70d0..a73b040 100644
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -184,26 +184,33 @@
     
 =====================================================================*/
 
-/*
- * Since there is only one interrupt available to CardBus
- * devices, all devices downstream of this device must
- * be using this IRQ.
- */
-static void cardbus_assign_irqs(struct pci_bus *bus, int irq)
+static void cardbus_config_irq_and_cls(struct pci_bus *bus, int irq)
 {
 	struct pci_dev *dev;
 
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		u8 irq_pin;
 
+		/*
+		 * Since there is only one interrupt available to
+		 * CardBus devices, all devices downstream of this
+		 * device must be using this IRQ.
+		 */
 		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin);
 		if (irq_pin) {
 			dev->irq = irq;
 			pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
 		}
 
+		/*
+		 * Some controllers transfer very slowly with 0 CLS.
+		 * Configure it.  This may fail as CLS configuration
+		 * is mandatory only for MWI.
+		 */
+		pci_set_cacheline_size(dev);
+
 		if (dev->subordinate)
-			cardbus_assign_irqs(dev->subordinate, irq);
+			cardbus_config_irq_and_cls(dev->subordinate, irq);
 	}
 }
 
@@ -228,7 +235,7 @@
 	 */
 	pci_bus_size_bridges(bus);
 	pci_bus_assign_resources(bus);
-	cardbus_assign_irqs(bus, s->pci_irq);
+	cardbus_config_irq_and_cls(bus, s->pci_irq);
 
 	/* socket specific tune function */
 	if (s->tune_bridge)
diff --git a/drivers/platform/Kconfig b/drivers/platform/Kconfig
index 9652c3f..8390dca 100644
--- a/drivers/platform/Kconfig
+++ b/drivers/platform/Kconfig
@@ -1,5 +1,3 @@
-# drivers/platform/Kconfig
-
 if X86
 source "drivers/platform/x86/Kconfig"
 endif
diff --git a/drivers/platform/x86/intel_menlow.c b/drivers/platform/x86/intel_menlow.c
index 29432a5..f0a90a6 100644
--- a/drivers/platform/x86/intel_menlow.c
+++ b/drivers/platform/x86/intel_menlow.c
@@ -510,7 +510,7 @@
 	/* Looking for sensors in each ACPI thermal zone */
 	status = acpi_walk_namespace(ACPI_TYPE_THERMAL, ACPI_ROOT_OBJECT,
 				     ACPI_UINT32_MAX,
-				     intel_menlow_register_sensor, NULL, NULL);
+				     intel_menlow_register_sensor, NULL, NULL, NULL);
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
 
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index a2a742c..7a2cc8a 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -1203,7 +1203,7 @@
 
 	if (debug) {
 		status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_nc_acpi_handle,
-					     1, sony_walk_callback, NULL, NULL);
+					     1, sony_walk_callback, NULL, NULL, NULL);
 		if (ACPI_FAILURE(status)) {
 			printk(KERN_WARNING DRV_PFX "unable to walk acpi resources\n");
 			result = -ENODEV;
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index a848c7e..0ed8480 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -1087,7 +1087,7 @@
 	 */
 
 	status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3,
-				     tpacpi_acpi_walk_find_bcl, NULL,
+				     tpacpi_acpi_walk_find_bcl, NULL, NULL,
 				     &bcl_ptr);
 
 	if (ACPI_SUCCESS(status) && bcl_levels > 2) {
@@ -6545,7 +6545,7 @@
  * 	The speeds are stored on handles
  * 	(FANA:FAN9), (FANC:FANB), (FANE:FAND).
  *
- * 	There are three default speed sets, acessible as handles:
+ * 	There are three default speed sets, accessible as handles:
  * 	FS1L,FS1M,FS1H; FS2L,FS2M,FS2H; FS3L,FS3M,FS3H
  *
  * 	ACPI DSDT switches which set is in use depending on various
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
index 87b4f49..a5135eb 100644
--- a/drivers/pnp/pnpbios/rsparser.c
+++ b/drivers/pnp/pnpbios/rsparser.c
@@ -191,7 +191,7 @@
 			return (unsigned char *)p;
 			break;
 
-		default:	/* an unkown tag */
+		default:	/* an unknown tag */
 len_err:
 			dev_err(&dev->dev, "unknown tag %#x length %d\n",
 				tag, len);
@@ -405,7 +405,7 @@
 		case SMALL_TAG_END:
 			return p + 2;
 
-		default:	/* an unkown tag */
+		default:	/* an unknown tag */
 len_err:
 			dev_err(&dev->dev, "unknown tag %#x length %d\n",
 				tag, len);
@@ -475,7 +475,7 @@
 			return (unsigned char *)p;
 			break;
 
-		default:	/* an unkown tag */
+		default:	/* an unknown tag */
 len_err:
 			dev_err(&dev->dev, "unknown tag %#x length %d\n",
 				tag, len);
@@ -744,7 +744,7 @@
 			return (unsigned char *)p;
 			break;
 
-		default:	/* an unkown tag */
+		default:	/* an unknown tag */
 len_err:
 			dev_err(&dev->dev, "unknown tag %#x length %d\n",
 				tag, len);
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index 8473fe5..dfbd5a6 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -285,15 +285,10 @@
 				 * the PCI region, and that might prevent a PCI
 				 * driver from requesting its resources.
 				 */
-				dev_warn(&dev->dev, "%s resource "
-					"(0x%llx-0x%llx) overlaps %s BAR %d "
-					"(0x%llx-0x%llx), disabling\n",
-					pnp_resource_type_name(res),
-					(unsigned long long) pnp_start,
-					(unsigned long long) pnp_end,
-					pci_name(pdev), i,
-					(unsigned long long) pci_start,
-					(unsigned long long) pci_end);
+				dev_warn(&dev->dev,
+					 "disabling %pR because it overlaps "
+					 "%s BAR %d %pR\n", res,
+					 pci_name(pdev), i, &pdev->resource[i]);
 				res->flags |= IORESOURCE_DISABLED;
 			}
 		}
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index ba97654..64d0596 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -517,7 +517,7 @@
 	res->start = irq;
 	res->end = irq;
 
-	pnp_dbg(&dev->dev, "  add irq %d flags %#x\n", irq, flags);
+	pnp_dbg(&dev->dev, "  add %pr\n", res);
 	return pnp_res;
 }
 
@@ -538,7 +538,7 @@
 	res->start = dma;
 	res->end = dma;
 
-	pnp_dbg(&dev->dev, "  add dma %d flags %#x\n", dma, flags);
+	pnp_dbg(&dev->dev, "  add %pr\n", res);
 	return pnp_res;
 }
 
@@ -562,8 +562,7 @@
 	res->start = start;
 	res->end = end;
 
-	pnp_dbg(&dev->dev, "  add io  %#llx-%#llx flags %#x\n",
-		(unsigned long long) start, (unsigned long long) end, flags);
+	pnp_dbg(&dev->dev, "  add %pr\n", res);
 	return pnp_res;
 }
 
@@ -587,8 +586,7 @@
 	res->start = start;
 	res->end = end;
 
-	pnp_dbg(&dev->dev, "  add mem %#llx-%#llx flags %#x\n",
-		(unsigned long long) start, (unsigned long long) end, flags);
+	pnp_dbg(&dev->dev, "  add %pr\n", res);
 	return pnp_res;
 }
 
diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c
index 63087d5..9585c1c 100644
--- a/drivers/pnp/support.c
+++ b/drivers/pnp/support.c
@@ -75,47 +75,14 @@
 
 void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
 {
-	char buf[128];
-	int len;
 	struct pnp_resource *pnp_res;
-	struct resource *res;
 
-	if (list_empty(&dev->resources)) {
+	if (list_empty(&dev->resources))
 		pnp_dbg(&dev->dev, "%s: no current resources\n", desc);
-		return;
-	}
-
-	pnp_dbg(&dev->dev, "%s: current resources:\n", desc);
-	list_for_each_entry(pnp_res, &dev->resources, list) {
-		res = &pnp_res->res;
-		len = 0;
-
-		len += scnprintf(buf + len, sizeof(buf) - len, "  %-3s ",
-				 pnp_resource_type_name(res));
-
-		if (res->flags & IORESOURCE_DISABLED) {
-			pnp_dbg(&dev->dev, "%sdisabled\n", buf);
-			continue;
-		}
-
-		switch (pnp_resource_type(res)) {
-		case IORESOURCE_IO:
-		case IORESOURCE_MEM:
-			len += scnprintf(buf + len, sizeof(buf) - len,
-					 "%#llx-%#llx flags %#lx",
-					 (unsigned long long) res->start,
-					 (unsigned long long) res->end,
-					 res->flags);
-			break;
-		case IORESOURCE_IRQ:
-		case IORESOURCE_DMA:
-			len += scnprintf(buf + len, sizeof(buf) - len,
-					 "%lld flags %#lx",
-					 (unsigned long long) res->start,
-					 res->flags);
-			break;
-		}
-		pnp_dbg(&dev->dev, "%s\n", buf);
+	else {
+		pnp_dbg(&dev->dev, "%s: current resources:\n", desc);
+		list_for_each_entry(pnp_res, &dev->resources, list)
+			pnp_dbg(&dev->dev, "%pr\n", &pnp_res->res);
 	}
 }
 
diff --git a/drivers/pnp/system.c b/drivers/pnp/system.c
index 59b9092..49c1720 100644
--- a/drivers/pnp/system.c
+++ b/drivers/pnp/system.c
@@ -22,11 +22,11 @@
 	{"", 0}
 };
 
-static void reserve_range(struct pnp_dev *dev, resource_size_t start,
-			  resource_size_t end, int port)
+static void reserve_range(struct pnp_dev *dev, struct resource *r, int port)
 {
 	char *regionid;
 	const char *pnpid = dev_name(&dev->dev);
+	resource_size_t start = r->start, end = r->end;
 	struct resource *res;
 
 	regionid = kmalloc(16, GFP_KERNEL);
@@ -48,10 +48,8 @@
 	 * example do reserve stuff they know about too, so we may well
 	 * have double reservations.
 	 */
-	dev_info(&dev->dev, "%s range 0x%llx-0x%llx %s reserved\n",
-		port ? "ioport" : "iomem",
-		(unsigned long long) start, (unsigned long long) end,
-		res ? "has been" : "could not be");
+	dev_info(&dev->dev, "%pR %s reserved\n", r,
+		 res ? "has been" : "could not be");
 }
 
 static void reserve_resources_of_dev(struct pnp_dev *dev)
@@ -77,14 +75,14 @@
 		if (res->end < res->start)
 			continue;	/* invalid */
 
-		reserve_range(dev, res->start, res->end, 1);
+		reserve_range(dev, res, 1);
 	}
 
 	for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
 		if (res->flags & IORESOURCE_DISABLED)
 			continue;
 
-		reserve_range(dev, res->start, res->end, 0);
+		reserve_range(dev, res, 0);
 	}
 }
 
diff --git a/drivers/ps3/ps3-sys-manager.c b/drivers/ps3/ps3-sys-manager.c
index 88cb740..3cbaf18 100644
--- a/drivers/ps3/ps3-sys-manager.c
+++ b/drivers/ps3/ps3-sys-manager.c
@@ -46,7 +46,7 @@
 /**
  * struct ps3_sys_manager_header - System manager message header.
  * @version: Header version, currently 1.
- * @size: Header size in bytes, curently 16.
+ * @size: Header size in bytes, currently 16.
  * @payload_size: Message payload size in bytes.
  * @service_id: Message type, one of enum ps3_sys_manager_service_id.
  * @request_tag: Unique number to identify reply.
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c
index d490628..1e73c8f 100644
--- a/drivers/rtc/rtc-ds1302.c
+++ b/drivers/rtc/rtc-ds1302.c
@@ -201,7 +201,7 @@
 		.name	= DRV_NAME,
 		.owner	= THIS_MODULE,
 	},
-	.remove		= __exit_p(ds1302_rtc_remove),
+	.remove		= __devexit_p(ds1302_rtc_remove),
 };
 
 static int __init ds1302_rtc_init(void)
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c
index 0b6b773..539676e 100644
--- a/drivers/rtc/rtc-ds1511.c
+++ b/drivers/rtc/rtc-ds1511.c
@@ -2,7 +2,7 @@
  * An rtc driver for the Dallas DS1511
  *
  * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
- * Copyright (C) 2007 Andrew Sharp <andy.sharp@onstor.com>
+ * Copyright (C) 2007 Andrew Sharp <andy.sharp@lsi.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
@@ -636,7 +636,7 @@
 module_init(ds1511_rtc_init);
 module_exit(ds1511_rtc_exit);
 
-MODULE_AUTHOR("Andrew Sharp <andy.sharp@onstor.com>");
+MODULE_AUTHOR("Andrew Sharp <andy.sharp@lsi.com>");
 MODULE_DESCRIPTION("Dallas DS1511 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c
index 7d1547b..d491eb2 100644
--- a/drivers/rtc/rtc-stk17ta8.c
+++ b/drivers/rtc/rtc-stk17ta8.c
@@ -286,7 +286,7 @@
 	.write = stk17ta8_nvram_write,
 };
 
-static int __init stk17ta8_rtc_probe(struct platform_device *pdev)
+static int __devinit stk17ta8_rtc_probe(struct platform_device *pdev)
 {
 	struct rtc_device *rtc;
 	struct resource *res;
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c
index 423cd5a..ad741af 100644
--- a/drivers/rtc/rtc-v3020.c
+++ b/drivers/rtc/rtc-v3020.c
@@ -335,7 +335,7 @@
 		goto err_io;
 	}
 
-	/* Make sure frequency measurment mode, test modes, and lock
+	/* Make sure frequency measurement mode, test modes, and lock
 	 * are all disabled */
 	v3020_set_reg(chip, V3020_STATUS_0, 0x0);
 
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index aaccc8e..fdb2e7c 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -24,7 +24,6 @@
 #include <asm/ccwdev.h>
 #include <asm/ebcdic.h>
 #include <asm/idals.h>
-#include <asm/todclk.h>
 #include <asm/itcw.h>
 
 /* This is ugly... */
@@ -64,6 +63,7 @@
 static void dasd_return_cqr_cb(struct dasd_ccw_req *, void *);
 static void dasd_device_timeout(unsigned long);
 static void dasd_block_timeout(unsigned long);
+static void __dasd_process_erp(struct dasd_device *, struct dasd_ccw_req *);
 
 /*
  * SECTION: Operations on the device structure.
@@ -960,7 +960,7 @@
 	device = (struct dasd_device *) ptr;
 	spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
 	/* re-activate request queue */
-        device->stopped &= ~DASD_STOPPED_PENDING;
+	dasd_device_remove_stop_bits(device, DASD_STOPPED_PENDING);
 	spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 	dasd_schedule_device_bh(device);
 }
@@ -994,10 +994,9 @@
 		return;
 	cqr = (struct dasd_ccw_req *) intparm;
 	if (cqr->status != DASD_CQR_IN_IO) {
-		DBF_EVENT(DBF_DEBUG,
-			"invalid status in handle_killed_request: "
-			"bus_id %s, status %02x",
-			dev_name(&cdev->dev), cqr->status);
+		DBF_EVENT_DEVID(DBF_DEBUG, cdev,
+				"invalid status in handle_killed_request: "
+				"%02x", cqr->status);
 		return;
 	}
 
@@ -1023,7 +1022,7 @@
 	/* First of all start sense subsystem status request. */
 	dasd_eer_snss(device);
 
-	device->stopped &= ~DASD_STOPPED_PENDING;
+	dasd_device_remove_stop_bits(device, DASD_STOPPED_PENDING);
 	dasd_schedule_device_bh(device);
 	if (device->block)
 		dasd_schedule_block_bh(device->block);
@@ -1045,12 +1044,13 @@
 		case -EIO:
 			break;
 		case -ETIMEDOUT:
-			DBF_EVENT(DBF_WARNING, "%s(%s): request timed out\n",
-			       __func__, dev_name(&cdev->dev));
+			DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s: "
+					"request timed out\n", __func__);
 			break;
 		default:
-			DBF_EVENT(DBF_WARNING, "%s(%s): unknown error %ld\n",
-			       __func__, dev_name(&cdev->dev), PTR_ERR(irb));
+			DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s: "
+					"unknown error %ld\n", __func__,
+					PTR_ERR(irb));
 		}
 		dasd_handle_killed_request(cdev, intparm);
 		return;
@@ -1405,6 +1405,20 @@
 	tasklet_hi_schedule(&device->tasklet);
 }
 
+void dasd_device_set_stop_bits(struct dasd_device *device, int bits)
+{
+	device->stopped |= bits;
+}
+EXPORT_SYMBOL_GPL(dasd_device_set_stop_bits);
+
+void dasd_device_remove_stop_bits(struct dasd_device *device, int bits)
+{
+	device->stopped &= ~bits;
+	if (!device->stopped)
+		wake_up(&generic_waitq);
+}
+EXPORT_SYMBOL_GPL(dasd_device_remove_stop_bits);
+
 /*
  * Queue a request to the head of the device ccw_queue.
  * Start the I/O if possible.
@@ -1465,28 +1479,126 @@
 }
 
 /*
+ * checks if error recovery is necessary, returns 1 if yes, 0 otherwise.
+ */
+static int __dasd_sleep_on_erp(struct dasd_ccw_req *cqr)
+{
+	struct dasd_device *device;
+	dasd_erp_fn_t erp_fn;
+
+	if (cqr->status == DASD_CQR_FILLED)
+		return 0;
+	device = cqr->startdev;
+	if (test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags)) {
+		if (cqr->status == DASD_CQR_TERMINATED) {
+			device->discipline->handle_terminated_request(cqr);
+			return 1;
+		}
+		if (cqr->status == DASD_CQR_NEED_ERP) {
+			erp_fn = device->discipline->erp_action(cqr);
+			erp_fn(cqr);
+			return 1;
+		}
+		if (cqr->status == DASD_CQR_FAILED)
+			dasd_log_sense(cqr, &cqr->irb);
+		if (cqr->refers) {
+			__dasd_process_erp(device, cqr);
+			return 1;
+		}
+	}
+	return 0;
+}
+
+static int __dasd_sleep_on_loop_condition(struct dasd_ccw_req *cqr)
+{
+	if (test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags)) {
+		if (cqr->refers) /* erp is not done yet */
+			return 1;
+		return ((cqr->status != DASD_CQR_DONE) &&
+			(cqr->status != DASD_CQR_FAILED));
+	} else
+		return (cqr->status == DASD_CQR_FILLED);
+}
+
+static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible)
+{
+	struct dasd_device *device;
+	int rc;
+	struct list_head ccw_queue;
+	struct dasd_ccw_req *cqr;
+
+	INIT_LIST_HEAD(&ccw_queue);
+	maincqr->status = DASD_CQR_FILLED;
+	device = maincqr->startdev;
+	list_add(&maincqr->blocklist, &ccw_queue);
+	for (cqr = maincqr;  __dasd_sleep_on_loop_condition(cqr);
+	     cqr = list_first_entry(&ccw_queue,
+				    struct dasd_ccw_req, blocklist)) {
+
+		if (__dasd_sleep_on_erp(cqr))
+			continue;
+		if (cqr->status != DASD_CQR_FILLED) /* could be failed */
+			continue;
+
+		/* Non-temporary stop condition will trigger fail fast */
+		if (device->stopped & ~DASD_STOPPED_PENDING &&
+		    test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) &&
+		    (!dasd_eer_enabled(device))) {
+			cqr->status = DASD_CQR_FAILED;
+			continue;
+		}
+
+		/* Don't try to start requests if device is stopped */
+		if (interruptible) {
+			rc = wait_event_interruptible(
+				generic_waitq, !(device->stopped));
+			if (rc == -ERESTARTSYS) {
+				cqr->status = DASD_CQR_FAILED;
+				maincqr->intrc = rc;
+				continue;
+			}
+		} else
+			wait_event(generic_waitq, !(device->stopped));
+
+		cqr->callback = dasd_wakeup_cb;
+		cqr->callback_data = (void *) &generic_waitq;
+		dasd_add_request_tail(cqr);
+		if (interruptible) {
+			rc = wait_event_interruptible(
+				generic_waitq, _wait_for_wakeup(cqr));
+			if (rc == -ERESTARTSYS) {
+				dasd_cancel_req(cqr);
+				/* wait (non-interruptible) for final status */
+				wait_event(generic_waitq,
+					   _wait_for_wakeup(cqr));
+				cqr->status = DASD_CQR_FAILED;
+				maincqr->intrc = rc;
+				continue;
+			}
+		} else
+			wait_event(generic_waitq, _wait_for_wakeup(cqr));
+	}
+
+	maincqr->endclk = get_clock();
+	if ((maincqr->status != DASD_CQR_DONE) &&
+	    (maincqr->intrc != -ERESTARTSYS))
+		dasd_log_sense(maincqr, &maincqr->irb);
+	if (maincqr->status == DASD_CQR_DONE)
+		rc = 0;
+	else if (maincqr->intrc)
+		rc = maincqr->intrc;
+	else
+		rc = -EIO;
+	return rc;
+}
+
+/*
  * Queue a request to the tail of the device ccw_queue and wait for
  * it's completion.
  */
 int dasd_sleep_on(struct dasd_ccw_req *cqr)
 {
-	struct dasd_device *device;
-	int rc;
-
-	device = cqr->startdev;
-
-	cqr->callback = dasd_wakeup_cb;
-	cqr->callback_data = (void *) &generic_waitq;
-	dasd_add_request_tail(cqr);
-	wait_event(generic_waitq, _wait_for_wakeup(cqr));
-
-	if (cqr->status == DASD_CQR_DONE)
-		rc = 0;
-	else if (cqr->intrc)
-		rc = cqr->intrc;
-	else
-		rc = -EIO;
-	return rc;
+	return _dasd_sleep_on(cqr, 0);
 }
 
 /*
@@ -1495,28 +1607,7 @@
  */
 int dasd_sleep_on_interruptible(struct dasd_ccw_req *cqr)
 {
-	struct dasd_device *device;
-	int rc;
-
-	device = cqr->startdev;
-	cqr->callback = dasd_wakeup_cb;
-	cqr->callback_data = (void *) &generic_waitq;
-	dasd_add_request_tail(cqr);
-	rc = wait_event_interruptible(generic_waitq, _wait_for_wakeup(cqr));
-	if (rc == -ERESTARTSYS) {
-		dasd_cancel_req(cqr);
-		/* wait (non-interruptible) for final status */
-		wait_event(generic_waitq, _wait_for_wakeup(cqr));
-		cqr->intrc = rc;
-	}
-
-	if (cqr->status == DASD_CQR_DONE)
-		rc = 0;
-	else if (cqr->intrc)
-		rc = cqr->intrc;
-	else
-		rc = -EIO;
-	return rc;
+	return _dasd_sleep_on(cqr, 1);
 }
 
 /*
@@ -1630,7 +1721,7 @@
 	block = (struct dasd_block *) ptr;
 	spin_lock_irqsave(get_ccwdev_lock(block->base->cdev), flags);
 	/* re-activate request queue */
-	block->base->stopped &= ~DASD_STOPPED_PENDING;
+	dasd_device_remove_stop_bits(block->base, DASD_STOPPED_PENDING);
 	spin_unlock_irqrestore(get_ccwdev_lock(block->base->cdev), flags);
 	dasd_schedule_block_bh(block);
 }
@@ -1657,11 +1748,10 @@
 /*
  * Process finished error recovery ccw.
  */
-static inline void __dasd_block_process_erp(struct dasd_block *block,
-					    struct dasd_ccw_req *cqr)
+static void __dasd_process_erp(struct dasd_device *device,
+			       struct dasd_ccw_req *cqr)
 {
 	dasd_erp_fn_t erp_fn;
-	struct dasd_device *device = block->base;
 
 	if (cqr->status == DASD_CQR_DONE)
 		DBF_DEV_EVENT(DBF_NOTICE, device, "%s", "ERP successful");
@@ -1725,9 +1815,12 @@
 				 */
 				if (!list_empty(&block->ccw_queue))
 					break;
-				spin_lock_irqsave(get_ccwdev_lock(basedev->cdev), flags);
-				basedev->stopped |= DASD_STOPPED_PENDING;
-				spin_unlock_irqrestore(get_ccwdev_lock(basedev->cdev), flags);
+				spin_lock_irqsave(
+					get_ccwdev_lock(basedev->cdev), flags);
+				dasd_device_set_stop_bits(basedev,
+							  DASD_STOPPED_PENDING);
+				spin_unlock_irqrestore(
+					get_ccwdev_lock(basedev->cdev), flags);
 				dasd_block_set_timer(block, HZ/2);
 				break;
 			}
@@ -1813,7 +1906,7 @@
 			cqr->status = DASD_CQR_FILLED;
 			cqr->retries = 255;
 			spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
-			base->stopped |= DASD_STOPPED_QUIESCE;
+			dasd_device_set_stop_bits(base, DASD_STOPPED_QUIESCE);
 			spin_unlock_irqrestore(get_ccwdev_lock(base->cdev),
 					       flags);
 			goto restart;
@@ -1821,7 +1914,7 @@
 
 		/* Process finished ERP request. */
 		if (cqr->refers) {
-			__dasd_block_process_erp(block, cqr);
+			__dasd_process_erp(base, cqr);
 			goto restart;
 		}
 
@@ -1952,7 +2045,7 @@
 		/* Process finished ERP request. */
 		if (cqr->refers) {
 			spin_lock_bh(&block->queue_lock);
-			__dasd_block_process_erp(block, cqr);
+			__dasd_process_erp(block->base, cqr);
 			spin_unlock_bh(&block->queue_lock);
 			/* restart list_for_xx loop since dasd_process_erp
 			 * might remove multiple elements */
@@ -2208,18 +2301,11 @@
 {
 	int ret;
 
-	ret = ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
-	if (ret) {
-		DBF_EVENT(DBF_WARNING,
-		       "dasd_generic_probe: could not set ccw-device options "
-		       "for %s\n", dev_name(&cdev->dev));
-		return ret;
-	}
 	ret = dasd_add_sysfs_files(cdev);
 	if (ret) {
-		DBF_EVENT(DBF_WARNING,
-		       "dasd_generic_probe: could not add sysfs entries "
-		       "for %s\n", dev_name(&cdev->dev));
+		DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s",
+				"dasd_generic_probe: could not add "
+				"sysfs entries");
 		return ret;
 	}
 	cdev->handler = &dasd_int_handler;
@@ -2418,16 +2504,16 @@
 				cqr->status = DASD_CQR_QUEUED;
 				cqr->retries++;
 			}
-		device->stopped |= DASD_STOPPED_DC_WAIT;
+		dasd_device_set_stop_bits(device, DASD_STOPPED_DC_WAIT);
 		dasd_device_clear_timer(device);
 		dasd_schedule_device_bh(device);
 		ret = 1;
 		break;
 	case CIO_OPER:
 		/* FIXME: add a sanity check. */
-		device->stopped &= ~DASD_STOPPED_DC_WAIT;
+		dasd_device_remove_stop_bits(device, DASD_STOPPED_DC_WAIT);
 		if (device->stopped & DASD_UNRESUMED_PM) {
-			device->stopped &= ~DASD_UNRESUMED_PM;
+			dasd_device_remove_stop_bits(device, DASD_UNRESUMED_PM);
 			dasd_restore_device(device);
 			ret = 1;
 			break;
@@ -2452,7 +2538,7 @@
 	if (IS_ERR(device))
 		return PTR_ERR(device);
 	/* disallow new I/O  */
-	device->stopped |= DASD_STOPPED_PM;
+	dasd_device_set_stop_bits(device, DASD_STOPPED_PM);
 	/* clear active requests */
 	INIT_LIST_HEAD(&freeze_queue);
 	spin_lock_irq(get_ccwdev_lock(cdev));
@@ -2504,14 +2590,18 @@
 		return PTR_ERR(device);
 
 	/* allow new IO again */
-	device->stopped &= ~DASD_STOPPED_PM;
-	device->stopped &= ~DASD_UNRESUMED_PM;
+	dasd_device_remove_stop_bits(device,
+				     (DASD_STOPPED_PM | DASD_UNRESUMED_PM));
 
 	dasd_schedule_device_bh(device);
 
-	if (device->discipline->restore)
+	/*
+	 * call discipline restore function
+	 * if device is stopped do nothing e.g. for disconnected devices
+	 */
+	if (device->discipline->restore && !(device->stopped))
 		rc = device->discipline->restore(device);
-	if (rc)
+	if (rc || device->stopped)
 		/*
 		 * if the resume failed for the DASD we put it in
 		 * an UNRESUMED stop state
@@ -2561,8 +2651,7 @@
 	cqr->startdev = device;
 	cqr->memdev = device;
 	cqr->expires = 10*HZ;
-	clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
-	cqr->retries = 2;
+	cqr->retries = 256;
 	cqr->buildclk = get_clock();
 	cqr->status = DASD_CQR_FILLED;
 	return cqr;
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index e8ff7b0..44796ba 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -12,7 +12,6 @@
 #include <linux/timer.h>
 #include <linux/slab.h>
 #include <asm/idals.h>
-#include <asm/todclk.h>
 
 #define PRINTK_HEADER "dasd_erp(3990): "
 
@@ -70,8 +69,7 @@
  *   processing until the started timer has expired or an related
  *   interrupt was received.
  */
-static void
-dasd_3990_erp_block_queue(struct dasd_ccw_req * erp, int expires)
+static void dasd_3990_erp_block_queue(struct dasd_ccw_req *erp, int expires)
 {
 
 	struct dasd_device *device = erp->startdev;
@@ -81,10 +79,13 @@
 		    "blocking request queue for %is", expires/HZ);
 
 	spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
-	device->stopped |= DASD_STOPPED_PENDING;
+	dasd_device_set_stop_bits(device, DASD_STOPPED_PENDING);
 	spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 	erp->status = DASD_CQR_FILLED;
-	dasd_block_set_timer(device->block, expires);
+	if (erp->block)
+		dasd_block_set_timer(erp->block, expires);
+	else
+		dasd_device_set_timer(device, expires);
 }
 
 /*
@@ -243,9 +244,13 @@
  * DESCRIPTION
  *   Setup ERP to do the ERP action 1 (see Reference manual).
  *   Repeat the operation on a different channel path.
- *   If all alternate paths have been tried, the request is posted with a
- *   permanent error.
- *   Note: duplex handling is not implemented (yet).
+ *   As deviation from the recommended recovery action, we reset the path mask
+ *   after we have tried each path and go through all paths a second time.
+ *   This will cover situations where only one path at a time is actually down,
+ *   but all paths fail and recover just with the same sequence and timing as
+ *   we try to use them (flapping links).
+ *   If all alternate paths have been tried twice, the request is posted with
+ *   a permanent error.
  *
  *  PARAMETER
  *   erp		pointer to the current ERP
@@ -254,17 +259,25 @@
  *   erp		pointer to the ERP
  *
  */
-static struct dasd_ccw_req *
-dasd_3990_erp_action_1(struct dasd_ccw_req * erp)
+static struct dasd_ccw_req *dasd_3990_erp_action_1_sec(struct dasd_ccw_req *erp)
 {
-
-	erp->function = dasd_3990_erp_action_1;
-
+	erp->function = dasd_3990_erp_action_1_sec;
 	dasd_3990_erp_alternate_path(erp);
-
 	return erp;
+}
 
-}				/* end dasd_3990_erp_action_1 */
+static struct dasd_ccw_req *dasd_3990_erp_action_1(struct dasd_ccw_req *erp)
+{
+	erp->function = dasd_3990_erp_action_1;
+	dasd_3990_erp_alternate_path(erp);
+	if (erp->status == DASD_CQR_FAILED) {
+		erp->status = DASD_CQR_FILLED;
+		erp->retries = 10;
+		erp->lpm = LPM_ANYPATH;
+		erp->function = dasd_3990_erp_action_1_sec;
+	}
+	return erp;
+}				/* end dasd_3990_erp_action_1(b) */
 
 /*
  * DASD_3990_ERP_ACTION_4
@@ -2295,6 +2308,7 @@
 		return cqr;
 	}
 
+	ccw = cqr->cpaddr;
 	if (cqr->cpmode == 1) {
 		/* make a shallow copy of the original tcw but set new tsb */
 		erp->cpmode = 1;
@@ -2303,6 +2317,9 @@
 		tsb = (struct tsb *) &tcw[1];
 		*tcw = *((struct tcw *)cqr->cpaddr);
 		tcw->tsb = (long)tsb;
+	} else if (ccw->cmd_code == DASD_ECKD_CCW_PSF) {
+		/* PSF cannot be chained from NOOP/TIC */
+		erp->cpaddr = cqr->cpaddr;
 	} else {
 		/* initialize request with default TIC to current ERP/CQR */
 		ccw = erp->cpaddr;
@@ -2487,6 +2504,8 @@
 
 		erp = dasd_3990_erp_action_1(erp);
 
+	} else if (erp->function == dasd_3990_erp_action_1_sec) {
+		erp = dasd_3990_erp_action_1_sec(erp);
 	} else if (erp->function == dasd_3990_erp_action_5) {
 
 		/* retries have not been successful */
diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c
index 70a008c..fd12317 100644
--- a/drivers/s390/block/dasd_alias.c
+++ b/drivers/s390/block/dasd_alias.c
@@ -152,6 +152,7 @@
 	INIT_WORK(&lcu->suc_data.worker, summary_unit_check_handling_work);
 	INIT_DELAYED_WORK(&lcu->ruac_data.dwork, lcu_update_work);
 	spin_lock_init(&lcu->lock);
+	init_completion(&lcu->lcu_setup);
 	return lcu;
 
 out_err4:
@@ -240,6 +241,67 @@
 }
 
 /*
+ * The first device to be registered on an LCU will have to do
+ * some additional setup steps to configure that LCU on the
+ * storage server. All further devices should wait with their
+ * initialization until the first device is done.
+ * To synchronize this work, the first device will call
+ * dasd_alias_lcu_setup_complete when it is done, and all
+ * other devices will wait for it with dasd_alias_wait_for_lcu_setup.
+ */
+void dasd_alias_lcu_setup_complete(struct dasd_device *device)
+{
+	struct dasd_eckd_private *private;
+	unsigned long flags;
+	struct alias_server *server;
+	struct alias_lcu *lcu;
+	struct dasd_uid *uid;
+
+	private = (struct dasd_eckd_private *) device->private;
+	uid = &private->uid;
+	lcu = NULL;
+	spin_lock_irqsave(&aliastree.lock, flags);
+	server = _find_server(uid);
+	if (server)
+		lcu = _find_lcu(server, uid);
+	spin_unlock_irqrestore(&aliastree.lock, flags);
+	if (!lcu) {
+		DBF_EVENT_DEVID(DBF_ERR, device->cdev,
+				"could not find lcu for %04x %02x",
+				uid->ssid, uid->real_unit_addr);
+		WARN_ON(1);
+		return;
+	}
+	complete_all(&lcu->lcu_setup);
+}
+
+void dasd_alias_wait_for_lcu_setup(struct dasd_device *device)
+{
+	struct dasd_eckd_private *private;
+	unsigned long flags;
+	struct alias_server *server;
+	struct alias_lcu *lcu;
+	struct dasd_uid *uid;
+
+	private = (struct dasd_eckd_private *) device->private;
+	uid = &private->uid;
+	lcu = NULL;
+	spin_lock_irqsave(&aliastree.lock, flags);
+	server = _find_server(uid);
+	if (server)
+		lcu = _find_lcu(server, uid);
+	spin_unlock_irqrestore(&aliastree.lock, flags);
+	if (!lcu) {
+		DBF_EVENT_DEVID(DBF_ERR, device->cdev,
+				"could not find lcu for %04x %02x",
+				uid->ssid, uid->real_unit_addr);
+		WARN_ON(1);
+		return;
+	}
+	wait_for_completion(&lcu->lcu_setup);
+}
+
+/*
  * This function removes a device from the scope of alias management.
  * The complicated part is to make sure that it is not in use by
  * any of the workers. If necessary cancel the work.
@@ -755,11 +817,11 @@
 {
 	/* If pos == device then device is already locked! */
 	if (pos == device) {
-		pos->stopped |= DASD_STOPPED_SU;
+		dasd_device_set_stop_bits(pos, DASD_STOPPED_SU);
 		return;
 	}
 	spin_lock(get_ccwdev_lock(pos->cdev));
-	pos->stopped |= DASD_STOPPED_SU;
+	dasd_device_set_stop_bits(pos, DASD_STOPPED_SU);
 	spin_unlock(get_ccwdev_lock(pos->cdev));
 }
 
@@ -793,26 +855,26 @@
 
 	list_for_each_entry(device, &lcu->active_devices, alias_list) {
 		spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
-		device->stopped &= ~DASD_STOPPED_SU;
+		dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
 		spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 	}
 
 	list_for_each_entry(device, &lcu->inactive_devices, alias_list) {
 		spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
-		device->stopped &= ~DASD_STOPPED_SU;
+		dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
 		spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 	}
 
 	list_for_each_entry(pavgroup, &lcu->grouplist, group) {
 		list_for_each_entry(device, &pavgroup->baselist, alias_list) {
 			spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
-			device->stopped &= ~DASD_STOPPED_SU;
+			dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
 			spin_unlock_irqrestore(get_ccwdev_lock(device->cdev),
 					       flags);
 		}
 		list_for_each_entry(device, &pavgroup->aliaslist, alias_list) {
 			spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
-			device->stopped &= ~DASD_STOPPED_SU;
+			dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
 			spin_unlock_irqrestore(get_ccwdev_lock(device->cdev),
 					       flags);
 		}
@@ -836,7 +898,8 @@
 
 	/* 2. reset summary unit check */
 	spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
-	device->stopped &= ~(DASD_STOPPED_SU | DASD_STOPPED_PENDING);
+	dasd_device_remove_stop_bits(device,
+				     (DASD_STOPPED_SU | DASD_STOPPED_PENDING));
 	spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 	reset_summary_unit_check(lcu, device, suc_data->reason);
 
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index 4e49b4a..f64d0db8 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -24,7 +24,6 @@
 #include <asm/ebcdic.h>
 #include <asm/io.h>
 #include <asm/s390_ext.h>
-#include <asm/todclk.h>
 #include <asm/vtoc.h>
 #include <asm/diag.h>
 
@@ -145,6 +144,15 @@
 
 	mdsk_term_io(device);
 	rc = mdsk_init_io(device, device->block->bp_block, 0, NULL);
+	if (rc == 4) {
+		if (!(device->features & DASD_FEATURE_READONLY)) {
+			dev_warn(&device->cdev->dev,
+				 "The access mode of a DIAG device changed"
+				 " to read-only");
+			device->features |= DASD_FEATURE_READONLY;
+		}
+		rc = 0;
+	}
 	if (rc)
 		dev_warn(&device->cdev->dev, "DIAG ERP failed with "
 			    "rc=%d\n", rc);
@@ -433,16 +441,20 @@
 	for (sb = 512; sb < bsize; sb = sb << 1)
 		block->s2b_shift++;
 	rc = mdsk_init_io(device, block->bp_block, 0, NULL);
-	if (rc) {
+	if (rc && (rc != 4)) {
 		dev_warn(&device->cdev->dev, "DIAG initialization "
 			"failed with rc=%d\n", rc);
 		rc = -EIO;
 	} else {
+		if (rc == 4)
+			device->features |= DASD_FEATURE_READONLY;
 		dev_info(&device->cdev->dev,
-			 "New DASD with %ld byte/block, total size %ld KB\n",
+			 "New DASD with %ld byte/block, total size %ld KB%s\n",
 			 (unsigned long) block->bp_block,
 			 (unsigned long) (block->blocks <<
-					  block->s2b_shift) >> 1);
+					  block->s2b_shift) >> 1,
+			 (rc == 4) ? ", read-only device" : "");
+		rc = 0;
 	}
 out_label:
 	free_page((long) label);
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 417b97c..5819dc0 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -24,7 +24,6 @@
 #include <asm/idals.h>
 #include <asm/ebcdic.h>
 #include <asm/io.h>
-#include <asm/todclk.h>
 #include <asm/uaccess.h>
 #include <asm/cio.h>
 #include <asm/ccwdev.h>
@@ -78,6 +77,11 @@
 
 static struct ccw_driver dasd_eckd_driver; /* see below */
 
+#define INIT_CQR_OK 0
+#define INIT_CQR_UNFORMATTED 1
+#define INIT_CQR_ERROR 2
+
+
 /* initial attempt at a probe function. this can be simplified once
  * the other detection code is gone */
 static int
@@ -86,11 +90,12 @@
 	int ret;
 
 	/* set ECKD specific ccw-device options */
-	ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE);
+	ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE |
+				     CCWDEV_DO_PATHGROUP | CCWDEV_DO_MULTIPATH);
 	if (ret) {
-		DBF_EVENT(DBF_WARNING,
-		       "dasd_eckd_probe: could not set ccw-device options "
-		       "for %s\n", dev_name(&cdev->dev));
+		DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s",
+				"dasd_eckd_probe: could not set "
+				"ccw-device options");
 		return ret;
 	}
 	ret = dasd_generic_probe(cdev, &dasd_eckd_discipline);
@@ -749,8 +754,7 @@
 	cqr->block = NULL;
 	cqr->expires = 10*HZ;
 	cqr->lpm = lpm;
-	clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
-	cqr->retries = 2;
+	cqr->retries = 256;
 	cqr->buildclk = get_clock();
 	cqr->status = DASD_CQR_FILLED;
 	return cqr;
@@ -885,16 +889,15 @@
 			rc = dasd_eckd_read_conf_lpm(device, &conf_data,
 						     &conf_len, lpm);
 			if (rc && rc != -EOPNOTSUPP) {	/* -EOPNOTSUPP is ok */
-				DBF_EVENT(DBF_WARNING,
+				DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
 					  "Read configuration data returned "
-					  "error %d for device: %s", rc,
-					  dev_name(&device->cdev->dev));
+					  "error %d", rc);
 				return rc;
 			}
 			if (conf_data == NULL) {
-				DBF_EVENT(DBF_WARNING, "No configuration "
-					  "data retrieved for device: %s",
-					  dev_name(&device->cdev->dev));
+				DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
+						"No configuration data "
+						"retrieved");
 				continue;	/* no error */
 			}
 			/* save first valid configuration data */
@@ -941,16 +944,14 @@
 				    sizeof(struct dasd_rssd_features)),
 				   device);
 	if (IS_ERR(cqr)) {
-		DBF_EVENT(DBF_WARNING, "Could not allocate initialization "
-			  "request for device: %s",
-			  dev_name(&device->cdev->dev));
+		DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", "Could not "
+				"allocate initialization request");
 		return PTR_ERR(cqr);
 	}
 	cqr->startdev = device;
 	cqr->memdev = device;
 	cqr->block = NULL;
-	clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
-	cqr->retries = 5;
+	cqr->retries = 256;
 	cqr->expires = 10 * HZ;
 
 	/* Prepare for Read Subsystem Data */
@@ -1012,9 +1013,9 @@
 	}
 	psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data;
 	psf_ssc_data->order = PSF_ORDER_SSC;
-	psf_ssc_data->suborder = 0x40;
+	psf_ssc_data->suborder = 0xc0;
 	if (enable_pav) {
-		psf_ssc_data->suborder |= 0x88;
+		psf_ssc_data->suborder |= 0x08;
 		psf_ssc_data->reserved[0] = 0x88;
 	}
 	ccw = cqr->cpaddr;
@@ -1025,6 +1026,7 @@
 	cqr->startdev = device;
 	cqr->memdev = device;
 	cqr->block = NULL;
+	cqr->retries = 256;
 	cqr->expires = 10*HZ;
 	cqr->buildclk = get_clock();
 	cqr->status = DASD_CQR_FILLED;
@@ -1057,7 +1059,7 @@
 /*
  * Valide storage server of current device.
  */
-static int dasd_eckd_validate_server(struct dasd_device *device)
+static void dasd_eckd_validate_server(struct dasd_device *device)
 {
 	int rc;
 	struct dasd_eckd_private *private;
@@ -1068,15 +1070,12 @@
 	else
 		enable_pav = 1;
 	rc = dasd_eckd_psf_ssc(device, enable_pav);
+
 	/* may be requested feature is not available on server,
 	 * therefore just report error and go ahead */
 	private = (struct dasd_eckd_private *) device->private;
-	DBF_EVENT(DBF_WARNING, "PSF-SSC on storage subsystem %s.%s.%04x "
-		  "returned rc=%d for device: %s",
-		  private->uid.vendor, private->uid.serial,
-		  private->uid.ssid, rc, dev_name(&device->cdev->dev));
-	/* RE-Read Configuration Data */
-	return dasd_eckd_read_conf(device);
+	DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "PSF-SSC for SSID %04x "
+			"returned rc=%d", private->uid.ssid, rc);
 }
 
 /*
@@ -1090,6 +1089,15 @@
 	struct dasd_block *block;
 	int is_known, rc;
 
+	if (!ccw_device_is_pathgroup(device->cdev)) {
+		dev_warn(&device->cdev->dev,
+			 "A channel path group could not be established\n");
+		return -EIO;
+	}
+	if (!ccw_device_is_multipath(device->cdev)) {
+		dev_info(&device->cdev->dev,
+			 "The DASD is not operating in multipath mode\n");
+	}
 	private = (struct dasd_eckd_private *) device->private;
 	if (!private) {
 		private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA);
@@ -1123,9 +1131,9 @@
 	if (private->uid.type == UA_BASE_DEVICE) {
 		block = dasd_alloc_block();
 		if (IS_ERR(block)) {
-			DBF_EVENT(DBF_WARNING, "could not allocate dasd "
-				  "block structure for device: %s",
-				  dev_name(&device->cdev->dev));
+			DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
+					"could not allocate dasd "
+					"block structure");
 			rc = PTR_ERR(block);
 			goto out_err1;
 		}
@@ -1139,12 +1147,21 @@
 		rc = is_known;
 		goto out_err2;
 	}
+	/*
+	 * dasd_eckd_vaildate_server is done on the first device that
+	 * is found for an LCU. All later other devices have to wait
+	 * for it, so they will read the correct feature codes.
+	 */
 	if (!is_known) {
-		/* new lcu found */
-		rc = dasd_eckd_validate_server(device); /* will switch pav on */
-		if (rc)
-			goto out_err3;
-	}
+		dasd_eckd_validate_server(device);
+		dasd_alias_lcu_setup_complete(device);
+	} else
+		dasd_alias_wait_for_lcu_setup(device);
+
+	/* device may report different configuration data after LCU setup */
+	rc = dasd_eckd_read_conf(device);
+	if (rc)
+		goto out_err3;
 
 	/* Read Feature Codes */
 	dasd_eckd_read_features(device);
@@ -1153,9 +1170,8 @@
 	rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC,
 					 &private->rdc_data, 64);
 	if (rc) {
-		DBF_EVENT(DBF_WARNING,
-			  "Read device characteristics failed, rc=%d for "
-			  "device: %s", rc, dev_name(&device->cdev->dev));
+		DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
+				"Read device characteristic failed, rc=%d", rc);
 		goto out_err3;
 	}
 	/* find the vaild cylinder size */
@@ -1256,12 +1272,29 @@
 	cqr->block = NULL;
 	cqr->startdev = device;
 	cqr->memdev = device;
-	cqr->retries = 0;
+	cqr->retries = 255;
 	cqr->buildclk = get_clock();
 	cqr->status = DASD_CQR_FILLED;
 	return cqr;
 }
 
+/* differentiate between 'no record found' and any other error */
+static int dasd_eckd_analysis_evaluation(struct dasd_ccw_req *init_cqr)
+{
+	char *sense;
+	if (init_cqr->status == DASD_CQR_DONE)
+		return INIT_CQR_OK;
+	else if (init_cqr->status == DASD_CQR_NEED_ERP ||
+		 init_cqr->status == DASD_CQR_FAILED) {
+		sense = dasd_get_sense(&init_cqr->irb);
+		if (sense && (sense[1] & SNS1_NO_REC_FOUND))
+			return INIT_CQR_UNFORMATTED;
+		else
+			return INIT_CQR_ERROR;
+	} else
+		return INIT_CQR_ERROR;
+}
+
 /*
  * This is the callback function for the init_analysis cqr. It saves
  * the status of the initial analysis ccw before it frees it and kicks
@@ -1269,21 +1302,20 @@
  * dasd_eckd_do_analysis again (if the devices has not been marked
  * for deletion in the meantime).
  */
-static void
-dasd_eckd_analysis_callback(struct dasd_ccw_req *init_cqr, void *data)
+static void dasd_eckd_analysis_callback(struct dasd_ccw_req *init_cqr,
+					void *data)
 {
 	struct dasd_eckd_private *private;
 	struct dasd_device *device;
 
 	device = init_cqr->startdev;
 	private = (struct dasd_eckd_private *) device->private;
-	private->init_cqr_status = init_cqr->status;
+	private->init_cqr_status = dasd_eckd_analysis_evaluation(init_cqr);
 	dasd_sfree_request(init_cqr, device);
 	dasd_kick_device(device);
 }
 
-static int
-dasd_eckd_start_analysis(struct dasd_block *block)
+static int dasd_eckd_start_analysis(struct dasd_block *block)
 {
 	struct dasd_eckd_private *private;
 	struct dasd_ccw_req *init_cqr;
@@ -1295,27 +1327,44 @@
 	init_cqr->callback = dasd_eckd_analysis_callback;
 	init_cqr->callback_data = NULL;
 	init_cqr->expires = 5*HZ;
+	/* first try without ERP, so we can later handle unformatted
+	 * devices as special case
+	 */
+	clear_bit(DASD_CQR_FLAGS_USE_ERP, &init_cqr->flags);
+	init_cqr->retries = 0;
 	dasd_add_request_head(init_cqr);
 	return -EAGAIN;
 }
 
-static int
-dasd_eckd_end_analysis(struct dasd_block *block)
+static int dasd_eckd_end_analysis(struct dasd_block *block)
 {
 	struct dasd_device *device;
 	struct dasd_eckd_private *private;
 	struct eckd_count *count_area;
 	unsigned int sb, blk_per_trk;
 	int status, i;
+	struct dasd_ccw_req *init_cqr;
 
 	device = block->base;
 	private = (struct dasd_eckd_private *) device->private;
 	status = private->init_cqr_status;
 	private->init_cqr_status = -1;
-	if (status != DASD_CQR_DONE) {
-		dev_warn(&device->cdev->dev,
-			    "The DASD is not formatted\n");
+	if (status == INIT_CQR_ERROR) {
+		/* try again, this time with full ERP */
+		init_cqr = dasd_eckd_analysis_ccw(device);
+		dasd_sleep_on(init_cqr);
+		status = dasd_eckd_analysis_evaluation(init_cqr);
+		dasd_sfree_request(init_cqr, device);
+	}
+
+	if (status == INIT_CQR_UNFORMATTED) {
+		dev_warn(&device->cdev->dev, "The DASD is not formatted\n");
 		return -EMEDIUMTYPE;
+	} else if (status == INIT_CQR_ERROR) {
+		dev_err(&device->cdev->dev,
+			"Detecting the DASD disk layout failed because "
+			"of an I/O error\n");
+		return -EIO;
 	}
 
 	private->uses_cdl = 1;
@@ -1607,8 +1656,7 @@
 	}
 	fcp->startdev = device;
 	fcp->memdev = device;
-	clear_bit(DASD_CQR_FLAGS_USE_ERP, &fcp->flags);
-	fcp->retries = 5;	/* set retry counter to enable default ERP */
+	fcp->retries = 256;
 	fcp->buildclk = get_clock();
 	fcp->status = DASD_CQR_FILLED;
 	return fcp;
@@ -2690,6 +2738,7 @@
 	cqr->startdev = device;
 	cqr->memdev = device;
 	cqr->retries = 0;
+	clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
 	cqr->expires = 10 * HZ;
 
 	/* Prepare for Read Subsystem Data */
@@ -3240,11 +3289,15 @@
 	if (is_known < 0)
 		return is_known;
 	if (!is_known) {
-		/* new lcu found */
-		rc = dasd_eckd_validate_server(device); /* will switch pav on */
-		if (rc)
-			goto out_err;
-	}
+		dasd_eckd_validate_server(device);
+		dasd_alias_lcu_setup_complete(device);
+	} else
+		dasd_alias_wait_for_lcu_setup(device);
+
+	/* RE-Read Configuration Data */
+	rc = dasd_eckd_read_conf(device);
+	if (rc)
+		goto out_err;
 
 	/* Read Feature Codes */
 	dasd_eckd_read_features(device);
@@ -3253,9 +3306,8 @@
 	rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC,
 					 &temp_rdc_data, 64);
 	if (rc) {
-		DBF_EVENT(DBF_WARNING,
-			  "Read device characteristics failed, rc=%d for "
-			  "device: %s", rc, dev_name(&device->cdev->dev));
+		DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
+				"Read device characteristic failed, rc=%d", rc);
 		goto out_err;
 	}
 	spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h
index ad45bca..864d53c 100644
--- a/drivers/s390/block/dasd_eckd.h
+++ b/drivers/s390/block/dasd_eckd.h
@@ -414,6 +414,7 @@
 	struct summary_unit_check_work_data suc_data;
 	struct read_uac_work_data ruac_data;
 	struct dasd_ccw_req *rsu_cqr;
+	struct completion lcu_setup;
 };
 
 struct alias_pav_group {
@@ -460,5 +461,6 @@
 struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *);
 void dasd_alias_handle_summary_unit_check(struct dasd_device *, struct irb *);
 void dasd_eckd_reset_ccw_to_base_io(struct dasd_ccw_req *);
-
+void dasd_alias_lcu_setup_complete(struct dasd_device *);
+void dasd_alias_wait_for_lcu_setup(struct dasd_device *);
 #endif				/* DASD_ECKD_H */
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c
index d96039e..1f3e967 100644
--- a/drivers/s390/block/dasd_eer.c
+++ b/drivers/s390/block/dasd_eer.c
@@ -536,7 +536,6 @@
 	eerb = kzalloc(sizeof(struct eerbuffer), GFP_KERNEL);
 	if (!eerb)
 		return -ENOMEM;
-	lock_kernel();
 	eerb->buffer_page_count = eer_pages;
 	if (eerb->buffer_page_count < 1 ||
 	    eerb->buffer_page_count > INT_MAX / PAGE_SIZE) {
@@ -544,7 +543,6 @@
 		DBF_EVENT(DBF_WARNING, "can't open device since module "
 			"parameter eer_pages is smaller than 1 or"
 			" bigger than %d", (int)(INT_MAX / PAGE_SIZE));
-		unlock_kernel();
 		return -EINVAL;
 	}
 	eerb->buffersize = eerb->buffer_page_count * PAGE_SIZE;
@@ -552,14 +550,12 @@
 			       GFP_KERNEL);
         if (!eerb->buffer) {
 		kfree(eerb);
-		unlock_kernel();
                 return -ENOMEM;
 	}
 	if (dasd_eer_allocate_buffer_pages(eerb->buffer,
 					   eerb->buffer_page_count)) {
 		kfree(eerb->buffer);
 		kfree(eerb);
-		unlock_kernel();
 		return -ENOMEM;
 	}
 	filp->private_data = eerb;
@@ -567,7 +563,6 @@
 	list_add(&eerb->list, &bufferlist);
 	spin_unlock_irqrestore(&bufferlock, flags);
 
-	unlock_kernel();
 	return nonseekable_open(inp,filp);
 }
 
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index f245377..0f15244 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -20,7 +20,6 @@
 #include <asm/idals.h>
 #include <asm/ebcdic.h>
 #include <asm/io.h>
-#include <asm/todclk.h>
 #include <asm/ccwdev.h>
 
 #include "dasd_int.h"
@@ -141,9 +140,8 @@
 	}
 	block = dasd_alloc_block();
 	if (IS_ERR(block)) {
-		DBF_EVENT(DBF_WARNING, "could not allocate dasd block "
-			  "structure for device: %s",
-			  dev_name(&device->cdev->dev));
+		DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s", "could not allocate "
+				"dasd block structure");
 		device->private = NULL;
 		kfree(private);
 		return PTR_ERR(block);
@@ -155,9 +153,8 @@
 	rc = dasd_generic_read_dev_chars(device, DASD_FBA_MAGIC,
 					 &private->rdc_data, 32);
 	if (rc) {
-		DBF_EVENT(DBF_WARNING, "Read device characteristics returned "
-			  "error %d for device: %s",
-			  rc, dev_name(&device->cdev->dev));
+		DBF_EVENT_DEVID(DBF_WARNING, cdev, "Read device "
+				"characteristics returned error %d", rc);
 		device->block = NULL;
 		dasd_free_block(block);
 		device->private = NULL;
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 8afd9fa..e4c2143 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -108,6 +108,16 @@
 			    d_data); \
 } while(0)
 
+#define DBF_EVENT_DEVID(d_level, d_cdev, d_str, d_data...)	\
+do { \
+	struct ccw_dev_id __dev_id;			\
+	ccw_device_get_id(d_cdev, &__dev_id);		\
+	debug_sprintf_event(dasd_debug_area,		\
+			    d_level,					\
+			    "0.%x.%04x " d_str "\n",			\
+			    __dev_id.ssid, __dev_id.devno, d_data);	\
+} while (0)
+
 #define DBF_EXC(d_level, d_str, d_data...)\
 do { \
 	debug_sprintf_exception(dasd_debug_area, \
@@ -595,6 +605,9 @@
 int dasd_generic_read_dev_chars(struct dasd_device *, int, void *, int);
 char *dasd_get_sense(struct irb *);
 
+void dasd_device_set_stop_bits(struct dasd_device *, int);
+void dasd_device_remove_stop_bits(struct dasd_device *, int);
+
 /* externals in dasd_devmap.c */
 extern int dasd_max_devindex;
 extern int dasd_probeonly;
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index f756a1b..478bcdb 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -101,7 +101,7 @@
 	pr_info("%s: The DASD has been put in the quiesce "
 		"state\n", dev_name(&base->cdev->dev));
 	spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
-	base->stopped |= DASD_STOPPED_QUIESCE;
+	dasd_device_set_stop_bits(base, DASD_STOPPED_QUIESCE);
 	spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
 	return 0;
 }
@@ -122,7 +122,7 @@
 	pr_info("%s: I/O operations have been resumed "
 		"on the DASD\n", dev_name(&base->cdev->dev));
 	spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
-	base->stopped &= ~DASD_STOPPED_QUIESCE;
+	dasd_device_remove_stop_bits(base, DASD_STOPPED_QUIESCE);
 	spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
 
 	dasd_schedule_block_bh(block);
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
index 654daa3..5f23eca 100644
--- a/drivers/s390/block/dasd_proc.c
+++ b/drivers/s390/block/dasd_proc.c
@@ -215,7 +215,7 @@
 	}
 
 	prof = &dasd_global_profile;
-	/* prevent couter 'overflow' on output */
+	/* prevent counter 'overflow' on output */
 	for (factor = 1; (prof->dasd_io_reqs / factor) > 9999999;
 	     factor *= 10);
 
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 21639d6..9d61683 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -857,7 +857,6 @@
 
 /*
  * 3215 console initialization code called from console_init().
- * NOTE: This is called before kmalloc is available.
  */
 static int __init con3215_init(void)
 {
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
index bb838bd..6bca81a 100644
--- a/drivers/s390/char/con3270.c
+++ b/drivers/s390/char/con3270.c
@@ -572,7 +572,6 @@
 
 /*
  * 3270 console initialization code called from console_init().
- * NOTE: This is called before kmalloc is available.
  */
 static int __init
 con3270_init(void)
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index 097d384..28e4649 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -38,6 +38,8 @@
 	size_t rdbuf_size;		/* size of data returned by RDBUF */
 };
 
+static DEFINE_MUTEX(fs3270_mutex);
+
 static void
 fs3270_wake_up(struct raw3270_request *rq, void *data)
 {
@@ -74,7 +76,7 @@
 		}
 		rc = raw3270_start(view, rq);
 		if (rc == 0) {
-			/* Started sucessfully. Now wait for completion. */
+			/* Started successfully. Now wait for completion. */
 			wait_event(fp->wait, raw3270_request_final(rq));
 		}
 	} while (rc == -EACCES);
@@ -328,7 +330,7 @@
 	if (!fp)
 		return -ENODEV;
 	rc = 0;
-	lock_kernel();
+	mutex_lock(&fs3270_mutex);
 	switch (cmd) {
 	case TUBICMD:
 		fp->read_command = arg;
@@ -354,7 +356,7 @@
 			rc = -EFAULT;
 		break;
 	}
-	unlock_kernel();
+	mutex_unlock(&fs3270_mutex);
 	return rc;
 }
 
@@ -437,7 +439,7 @@
 		minor = tty->index + RAW3270_FIRSTMINOR;
 		tty_kref_put(tty);
 	}
-	lock_kernel();
+	mutex_lock(&fs3270_mutex);
 	/* Check if some other program is already using fullscreen mode. */
 	fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor);
 	if (!IS_ERR(fp)) {
@@ -478,7 +480,7 @@
 	}
 	filp->private_data = fp;
 out:
-	unlock_kernel();
+	mutex_unlock(&fs3270_mutex);
 	return rc;
 }
 
diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c
index 66e21dd..60473f8 100644
--- a/drivers/s390/char/monreader.c
+++ b/drivers/s390/char/monreader.c
@@ -12,7 +12,6 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -283,7 +282,6 @@
 	/*
 	 * only one user allowed
 	 */
-	lock_kernel();
 	rc = -EBUSY;
 	if (test_and_set_bit(MON_IN_USE, &mon_in_use))
 		goto out;
@@ -321,7 +319,6 @@
 	}
 	filp->private_data = monpriv;
 	dev_set_drvdata(monreader_device, monpriv);
-	unlock_kernel();
 	return nonseekable_open(inode, filp);
 
 out_path:
@@ -331,7 +328,6 @@
 out_use:
 	clear_bit(MON_IN_USE, &mon_in_use);
 out:
-	unlock_kernel();
 	return rc;
 }
 
@@ -607,6 +603,10 @@
 	}
 	dcss_mkname(mon_dcss_name, &user_data_connect[8]);
 
+	/*
+	 * misc_register() has to be the last action in module_init(), because
+	 * file operations will be available right after this.
+	 */
 	rc = misc_register(&mon_dev);
 	if (rc < 0 )
 		goto out;
diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c
index 66fb8eb..6532ed8 100644
--- a/drivers/s390/char/monwriter.c
+++ b/drivers/s390/char/monwriter.c
@@ -13,7 +13,6 @@
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/errno.h>
-#include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/miscdevice.h>
@@ -185,13 +184,11 @@
 	monpriv = kzalloc(sizeof(struct mon_private), GFP_KERNEL);
 	if (!monpriv)
 		return -ENOMEM;
-	lock_kernel();
 	INIT_LIST_HEAD(&monpriv->list);
 	monpriv->hdr_to_read = sizeof(monpriv->hdr);
 	mutex_init(&monpriv->thread_mutex);
 	filp->private_data = monpriv;
 	list_add_tail(&monpriv->priv_list, &mon_priv_list);
-	unlock_kernel();
 	return nonseekable_open(inode, filp);
 }
 
@@ -364,6 +361,10 @@
 		goto out_driver;
 	}
 
+	/*
+	 * misc_register() has to be the last action in module_init(), because
+	 * file operations will be available right after this.
+	 */
 	rc = misc_register(&mon_dev);
 	if (rc)
 		goto out_device;
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index 5cc11c6..28b5afc 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -84,6 +84,7 @@
 		do {
 			memset(sccb, 0, sizeof(*sccb));
 			sccb->header.length = sizeof(*sccb);
+			sccb->header.function_code = 0x80;
 			sccb->header.control_mask[2] = 0x80;
 			rc = sclp_cmd_sync_early(commands[i], sccb);
 		} while (rc == -EBUSY);
diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h
index a263337..7a242f0 100644
--- a/drivers/s390/char/tape.h
+++ b/drivers/s390/char/tape.h
@@ -212,6 +212,9 @@
 	struct tape_class_device *	nt;
 	struct tape_class_device *	rt;
 
+	/* Device mutex to serialize tape commands. */
+	struct mutex			mutex;
+
 	/* Device discipline information. */
 	struct tape_discipline *	discipline;
 	void *				discdata;
@@ -292,9 +295,9 @@
 extern int tape_generic_probe(struct ccw_device *);
 extern void tape_generic_remove(struct ccw_device *);
 
-extern struct tape_device *tape_get_device(int devindex);
-extern struct tape_device *tape_get_device_reference(struct tape_device *);
-extern struct tape_device *tape_put_device(struct tape_device *);
+extern struct tape_device *tape_find_device(int devindex);
+extern struct tape_device *tape_get_device(struct tape_device *);
+extern void tape_put_device(struct tape_device *);
 
 /* Externals from tape_char.c */
 extern int tapechar_init(void);
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c
index 2fe45ff..3657fe1 100644
--- a/drivers/s390/char/tape_34xx.c
+++ b/drivers/s390/char/tape_34xx.c
@@ -113,16 +113,16 @@
 {
 	struct tape_34xx_work *p =
 		container_of(work, struct tape_34xx_work, work);
+	struct tape_device *device = p->device;
 
 	switch(p->op) {
 		case TO_MSEN:
-			tape_34xx_medium_sense(p->device);
+			tape_34xx_medium_sense(device);
 			break;
 		default:
 			DBF_EVENT(3, "T34XX: internal error: unknown work\n");
 	}
-
-	p->device = tape_put_device(p->device);
+	tape_put_device(device);
 	kfree(p);
 }
 
@@ -136,7 +136,7 @@
 
 	INIT_WORK(&p->work, tape_34xx_work_handler);
 
-	p->device = tape_get_device_reference(device);
+	p->device = tape_get_device(device);
 	p->op     = op;
 
 	schedule_work(&p->work);
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c
index e4cc3aa..0c72aad 100644
--- a/drivers/s390/char/tape_3590.c
+++ b/drivers/s390/char/tape_3590.c
@@ -608,7 +608,7 @@
 
 	INIT_WORK(&p->work, tape_3590_work_handler);
 
-	p->device = tape_get_device_reference(device);
+	p->device = tape_get_device(device);
 	p->op = op;
 
 	schedule_work(&p->work);
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c
index 0c0705b..4799cc2 100644
--- a/drivers/s390/char/tape_block.c
+++ b/drivers/s390/char/tape_block.c
@@ -54,7 +54,7 @@
 	.owner		 = THIS_MODULE,
 	.open		 = tapeblock_open,
 	.release	 = tapeblock_release,
-	.locked_ioctl           = tapeblock_ioctl,
+	.ioctl		 = tapeblock_ioctl,
 	.media_changed   = tapeblock_medium_changed,
 	.revalidate_disk = tapeblock_revalidate_disk,
 };
@@ -239,7 +239,7 @@
 	disk->major = tapeblock_major;
 	disk->first_minor = device->first_minor;
 	disk->fops = &tapeblock_fops;
-	disk->private_data = tape_get_device_reference(device);
+	disk->private_data = tape_get_device(device);
 	disk->queue = blkdat->request_queue;
 	set_capacity(disk, 0);
 	sprintf(disk->disk_name, "btibm%d",
@@ -247,11 +247,11 @@
 
 	blkdat->disk = disk;
 	blkdat->medium_changed = 1;
-	blkdat->request_queue->queuedata = tape_get_device_reference(device);
+	blkdat->request_queue->queuedata = tape_get_device(device);
 
 	add_disk(disk);
 
-	tape_get_device_reference(device);
+	tape_get_device(device);
 	INIT_WORK(&blkdat->requeue_task, tapeblock_requeue);
 
 	return 0;
@@ -274,13 +274,14 @@
 	}
 
 	del_gendisk(device->blk_data.disk);
-	device->blk_data.disk->private_data =
-		tape_put_device(device->blk_data.disk->private_data);
+	device->blk_data.disk->private_data = NULL;
+	tape_put_device(device);
 	put_disk(device->blk_data.disk);
 
 	device->blk_data.disk = NULL;
 cleanup_queue:
-	device->blk_data.request_queue->queuedata = tape_put_device(device);
+	device->blk_data.request_queue->queuedata = NULL;
+	tape_put_device(device);
 
 	blk_cleanup_queue(device->blk_data.request_queue);
 	device->blk_data.request_queue = NULL;
@@ -363,7 +364,7 @@
 	struct tape_device *	device;
 	int			rc;
 
-	device = tape_get_device_reference(disk->private_data);
+	device = tape_get_device(disk->private_data);
 
 	if (device->required_tapemarks) {
 		DBF_EVENT(2, "TBLOCK: missing tapemarks\n");
diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c
index 31566c5..23d773a 100644
--- a/drivers/s390/char/tape_char.c
+++ b/drivers/s390/char/tape_char.c
@@ -33,8 +33,7 @@
 static ssize_t tapechar_write(struct file *, const char __user *, size_t, loff_t *);
 static int tapechar_open(struct inode *,struct file *);
 static int tapechar_release(struct inode *,struct file *);
-static int tapechar_ioctl(struct inode *, struct file *, unsigned int,
-			  unsigned long);
+static long tapechar_ioctl(struct file *, unsigned int, unsigned long);
 static long tapechar_compat_ioctl(struct file *, unsigned int,
 			  unsigned long);
 
@@ -43,7 +42,7 @@
 	.owner = THIS_MODULE,
 	.read = tapechar_read,
 	.write = tapechar_write,
-	.ioctl = tapechar_ioctl,
+	.unlocked_ioctl = tapechar_ioctl,
 	.compat_ioctl = tapechar_compat_ioctl,
 	.open = tapechar_open,
 	.release = tapechar_release,
@@ -170,7 +169,6 @@
 	if (rc == 0) {
 		rc = block_size - request->rescnt;
 		DBF_EVENT(6, "TCHAR:rbytes:  %x\n", rc);
-		filp->f_pos += rc;
 		/* Copy data from idal buffer to user space. */
 		if (idal_buffer_to_user(device->char_data.idal_buf,
 					data, rc) != 0)
@@ -238,7 +236,6 @@
 			break;
 		DBF_EVENT(6, "TCHAR:wbytes: %lx\n",
 			  block_size - request->rescnt);
-		filp->f_pos += block_size - request->rescnt;
 		written += block_size - request->rescnt;
 		if (request->rescnt != 0)
 			break;
@@ -286,26 +283,20 @@
 	if (imajor(filp->f_path.dentry->d_inode) != tapechar_major)
 		return -ENODEV;
 
-	lock_kernel();
 	minor = iminor(filp->f_path.dentry->d_inode);
-	device = tape_get_device(minor / TAPE_MINORS_PER_DEV);
+	device = tape_find_device(minor / TAPE_MINORS_PER_DEV);
 	if (IS_ERR(device)) {
-		DBF_EVENT(3, "TCHAR:open: tape_get_device() failed\n");
-		rc = PTR_ERR(device);
-		goto out;
+		DBF_EVENT(3, "TCHAR:open: tape_find_device() failed\n");
+		return PTR_ERR(device);
 	}
 
-
 	rc = tape_open(device);
 	if (rc == 0) {
 		filp->private_data = device;
-		rc = nonseekable_open(inode, filp);
-	}
-	else
+		nonseekable_open(inode, filp);
+	} else
 		tape_put_device(device);
 
-out:
-	unlock_kernel();
 	return rc;
 }
 
@@ -342,7 +333,8 @@
 		device->char_data.idal_buf = NULL;
 	}
 	tape_release(device);
-	filp->private_data = tape_put_device(device);
+	filp->private_data = NULL;
+	tape_put_device(device);
 
 	return 0;
 }
@@ -351,16 +343,11 @@
  * Tape device io controls.
  */
 static int
-tapechar_ioctl(struct inode *inp, struct file *filp,
-	       unsigned int no, unsigned long data)
+__tapechar_ioctl(struct tape_device *device,
+		 unsigned int no, unsigned long data)
 {
-	struct tape_device *device;
 	int rc;
 
-	DBF_EVENT(6, "TCHAR:ioct\n");
-
-	device = (struct tape_device *) filp->private_data;
-
 	if (no == MTIOCTOP) {
 		struct mtop op;
 
@@ -453,15 +440,30 @@
 }
 
 static long
+tapechar_ioctl(struct file *filp, unsigned int no, unsigned long data)
+{
+	struct tape_device *device;
+	long rc;
+
+	DBF_EVENT(6, "TCHAR:ioct\n");
+
+	device = (struct tape_device *) filp->private_data;
+	mutex_lock(&device->mutex);
+	rc = __tapechar_ioctl(device, no, data);
+	mutex_unlock(&device->mutex);
+	return rc;
+}
+
+static long
 tapechar_compat_ioctl(struct file *filp, unsigned int no, unsigned long data)
 {
 	struct tape_device *device = filp->private_data;
 	int rval = -ENOIOCTLCMD;
 
 	if (device->discipline->ioctl_fn) {
-		lock_kernel();
+		mutex_lock(&device->mutex);
 		rval = device->discipline->ioctl_fn(device, no, data);
-		unlock_kernel();
+		mutex_unlock(&device->mutex);
 		if (rval == -EINVAL)
 			rval = -ENOIOCTLCMD;
 	}
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index 5cd31e0..f5d6802 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -492,6 +492,7 @@
 		kfree(device);
 		return ERR_PTR(-ENOMEM);
 	}
+	mutex_init(&device->mutex);
 	INIT_LIST_HEAD(&device->req_queue);
 	INIT_LIST_HEAD(&device->node);
 	init_waitqueue_head(&device->state_change_wq);
@@ -511,11 +512,12 @@
  * increment the reference count.
  */
 struct tape_device *
-tape_get_device_reference(struct tape_device *device)
+tape_get_device(struct tape_device *device)
 {
-	DBF_EVENT(4, "tape_get_device_reference(%p) = %i\n", device,
-		atomic_inc_return(&device->ref_count));
+	int count;
 
+	count = atomic_inc_return(&device->ref_count);
+	DBF_EVENT(4, "tape_get_device(%p) = %i\n", device, count);
 	return device;
 }
 
@@ -525,32 +527,25 @@
  * The function returns a NULL pointer to be used by the caller
  * for clearing reference pointers.
  */
-struct tape_device *
+void
 tape_put_device(struct tape_device *device)
 {
-	int remain;
+	int count;
 
-	remain = atomic_dec_return(&device->ref_count);
-	if (remain > 0) {
-		DBF_EVENT(4, "tape_put_device(%p) -> %i\n", device, remain);
-	} else {
-		if (remain < 0) {
-			DBF_EVENT(4, "put device without reference\n");
-		} else {
-			DBF_EVENT(4, "tape_free_device(%p)\n", device);
-			kfree(device->modeset_byte);
-			kfree(device);
-		}
+	count = atomic_dec_return(&device->ref_count);
+	DBF_EVENT(4, "tape_put_device(%p) -> %i\n", device, count);
+	BUG_ON(count < 0);
+	if (count == 0) {
+		kfree(device->modeset_byte);
+		kfree(device);
 	}
-
-	return NULL;			
 }
 
 /*
  * Find tape device by a device index.
  */
 struct tape_device *
-tape_get_device(int devindex)
+tape_find_device(int devindex)
 {
 	struct tape_device *device, *tmp;
 
@@ -558,7 +553,7 @@
 	read_lock(&tape_device_lock);
 	list_for_each_entry(tmp, &tape_device_list, node) {
 		if (tmp->first_minor / TAPE_MINORS_PER_DEV == devindex) {
-			device = tape_get_device_reference(tmp);
+			device = tape_get_device(tmp);
 			break;
 		}
 	}
@@ -579,7 +574,8 @@
 	device = tape_alloc_device();
 	if (IS_ERR(device))
 		return -ENODEV;
-	ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
+	ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP |
+				     CCWDEV_DO_MULTIPATH);
 	ret = sysfs_create_group(&cdev->dev.kobj, &tape_attr_group);
 	if (ret) {
 		tape_put_device(device);
@@ -606,7 +602,8 @@
 		list_del(&request->list);
 
 		/* Decrease ref_count for removed request. */
-		request->device = tape_put_device(device);
+		request->device = NULL;
+		tape_put_device(device);
 		request->rc = -EIO;
 		if (request->callback != NULL)
 			request->callback(request, request->callback_data);
@@ -664,9 +661,11 @@
 			tape_cleanup_device(device);
 	}
 
-	if (!dev_get_drvdata(&cdev->dev)) {
+	device = dev_get_drvdata(&cdev->dev);
+	if (device) {
 		sysfs_remove_group(&cdev->dev.kobj, &tape_attr_group);
-		dev_set_drvdata(&cdev->dev, tape_put_device(dev_get_drvdata(&cdev->dev)));
+		dev_set_drvdata(&cdev->dev, NULL);
+		tape_put_device(device);
 	}
 }
 
@@ -721,9 +720,8 @@
 {
 	DBF_LH(6, "Free request %p\n", request);
 
-	if (request->device != NULL) {
-		request->device = tape_put_device(request->device);
-	}
+	if (request->device)
+		tape_put_device(request->device);
 	kfree(request->cpdata);
 	kfree(request->cpaddr);
 	kfree(request);
@@ -838,7 +836,8 @@
 	BUG_ON(request->status != TAPE_REQUEST_LONG_BUSY);
 	DBF_LH(6, "%08x: Long busy timeout.\n", device->cdev_id);
 	__tape_start_next_request(device);
-	device->lb_timeout.data = (unsigned long) tape_put_device(device);
+	device->lb_timeout.data = 0UL;
+	tape_put_device(device);
 	spin_unlock_irq(get_ccwdev_lock(device->cdev));
 }
 
@@ -918,7 +917,7 @@
 	}
 
 	/* Increase use count of device for the added request. */
-	request->device = tape_get_device_reference(device);
+	request->device = tape_get_device(device);
 
 	if (list_empty(&device->req_queue)) {
 		/* No other requests are on the queue. Start this one. */
@@ -1117,8 +1116,8 @@
 		if (req->status == TAPE_REQUEST_LONG_BUSY) {
 			DBF_EVENT(3, "(%08x): del timer\n", device->cdev_id);
 			if (del_timer(&device->lb_timeout)) {
-				device->lb_timeout.data = (unsigned long)
-					tape_put_device(device);
+				device->lb_timeout.data = 0UL;
+				tape_put_device(device);
 				__tape_start_next_request(device);
 			}
 			return;
@@ -1173,7 +1172,7 @@
 			break;
 		case TAPE_IO_LONG_BUSY:
 			device->lb_timeout.data =
-				(unsigned long)tape_get_device_reference(device);
+				(unsigned long) tape_get_device(device);
 			device->lb_timeout.expires = jiffies +
 				LONG_BUSY_TIMEOUT * HZ;
 			DBF_EVENT(3, "(%08x): add timer\n", device->cdev_id);
@@ -1326,7 +1325,7 @@
 EXPORT_SYMBOL(tape_generic_offline);
 EXPORT_SYMBOL(tape_generic_pm_suspend);
 EXPORT_SYMBOL(tape_put_device);
-EXPORT_SYMBOL(tape_get_device_reference);
+EXPORT_SYMBOL(tape_get_device);
 EXPORT_SYMBOL(tape_state_verbose);
 EXPORT_SYMBOL(tape_op_verbose);
 EXPORT_SYMBOL(tape_state_set);
diff --git a/drivers/s390/char/tape_proc.c b/drivers/s390/char/tape_proc.c
index 202f421..ebd820c 100644
--- a/drivers/s390/char/tape_proc.c
+++ b/drivers/s390/char/tape_proc.c
@@ -45,7 +45,7 @@
 		seq_printf(m, "TapeNo\tBusID      CuType/Model\t"
 			"DevType/Model\tBlkSize\tState\tOp\tMedState\n");
 	}
-	device = tape_get_device(n);
+	device = tape_find_device(n);
 	if (IS_ERR(device))
 		return 0;
 	spin_lock_irq(get_ccwdev_lock(device->cdev));
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index 3838567..911822db 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -19,6 +19,7 @@
 
 #include <linux/slab.h>
 #include <linux/bootmem.h>
+#include <linux/compat.h>
 
 #include <asm/ccwdev.h>
 #include <asm/cio.h>
@@ -1731,6 +1732,22 @@
 	return kbd_ioctl(tp->kbd, file, cmd, arg);
 }
 
+#ifdef CONFIG_COMPAT
+static long
+tty3270_compat_ioctl(struct tty_struct *tty, struct file *file,
+	      unsigned int cmd, unsigned long arg)
+{
+	struct tty3270 *tp;
+
+	tp = tty->driver_data;
+	if (!tp)
+		return -ENODEV;
+	if (tty->flags & (1 << TTY_IO_ERROR))
+		return -EIO;
+	return kbd_ioctl(tp->kbd, file, cmd, (unsigned long)compat_ptr(arg));
+}
+#endif
+
 static const struct tty_operations tty3270_ops = {
 	.open = tty3270_open,
 	.close = tty3270_close,
@@ -1745,6 +1762,9 @@
 	.hangup = tty3270_hangup,
 	.wait_until_sent = tty3270_wait_until_sent,
 	.ioctl = tty3270_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = tty3270_compat_ioctl,
+#endif
 	.set_termios = tty3270_set_termios
 };
 
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index d1a142fa..899aa79 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -312,11 +312,9 @@
 		return -ENOSYS;
 
 	/* Besure this device hasn't already been opened */
-	lock_kernel();
 	spin_lock_bh(&logptr->priv_lock);
 	if (logptr->dev_in_use)	{
 		spin_unlock_bh(&logptr->priv_lock);
-		unlock_kernel();
 		return -EBUSY;
 	}
 	logptr->dev_in_use = 1;
@@ -360,9 +358,8 @@
 		   || (logptr->iucv_path_severed));
 	if (logptr->iucv_path_severed)
 		goto out_record;
- 	ret = nonseekable_open(inode, filp);
-	unlock_kernel();
-	return ret;
+	nonseekable_open(inode, filp);
+	return 0;
 
 out_record:
 	if (logptr->autorecording)
@@ -372,7 +369,6 @@
 	logptr->path = NULL;
 out_dev:
 	logptr->dev_in_use = 0;
-	unlock_kernel();
 	return -EIO;
 }
 
diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c
index 77571b6..cc56fc7 100644
--- a/drivers/s390/char/vmur.c
+++ b/drivers/s390/char/vmur.c
@@ -695,7 +695,6 @@
 
 	if (accmode == O_RDWR)
 		return -EACCES;
-	lock_kernel();
 	/*
 	 * We treat the minor number as the devno of the ur device
 	 * to find in the driver tree.
@@ -749,7 +748,6 @@
 		goto fail_urfile_free;
 	urf->file_reclen = rc;
 	file->private_data = urf;
-	unlock_kernel();
 	return 0;
 
 fail_urfile_free:
@@ -761,7 +759,6 @@
 fail_put:
 	urdev_put(urd);
 out:
-	unlock_kernel();
 	return rc;
 }
 
diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c
index f2bc287..c974058 100644
--- a/drivers/s390/char/vmwatchdog.c
+++ b/drivers/s390/char/vmwatchdog.c
@@ -19,7 +19,6 @@
 #include <linux/moduleparam.h>
 #include <linux/suspend.h>
 #include <linux/watchdog.h>
-#include <linux/smp_lock.h>
 
 #include <asm/ebcdic.h>
 #include <asm/io.h>
@@ -49,6 +48,8 @@
 static unsigned long vmwdt_is_open;
 static int vmwdt_expect_close;
 
+static DEFINE_MUTEX(vmwdt_mutex);
+
 #define VMWDT_OPEN	0	/* devnode is open or suspend in progress */
 #define VMWDT_RUNNING	1	/* The watchdog is armed */
 
@@ -133,15 +134,11 @@
 static int vmwdt_open(struct inode *i, struct file *f)
 {
 	int ret;
-	lock_kernel();
-	if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) {
-		unlock_kernel();
+	if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open))
 		return -EBUSY;
-	}
 	ret = vmwdt_keepalive();
 	if (ret)
 		clear_bit(VMWDT_OPEN, &vmwdt_is_open);
-	unlock_kernel();
 	return ret ? ret : nonseekable_open(i, f);
 }
 
@@ -160,8 +157,7 @@
 	.identity = "z/VM Watchdog Timer",
 };
 
-static int vmwdt_ioctl(struct inode *i, struct file *f,
-			  unsigned int cmd, unsigned long arg)
+static int __vmwdt_ioctl(unsigned int cmd, unsigned long arg)
 {
 	switch (cmd) {
 	case WDIOC_GETSUPPORT:
@@ -205,10 +201,19 @@
 	case WDIOC_KEEPALIVE:
 		return vmwdt_keepalive();
 	}
-
 	return -EINVAL;
 }
 
+static long vmwdt_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
+{
+	int rc;
+
+	mutex_lock(&vmwdt_mutex);
+	rc = __vmwdt_ioctl(cmd, arg);
+	mutex_unlock(&vmwdt_mutex);
+	return (long) rc;
+}
+
 static ssize_t vmwdt_write(struct file *f, const char __user *buf,
 				size_t count, loff_t *ppos)
 {
@@ -288,7 +293,7 @@
 static const struct file_operations vmwdt_fops = {
 	.open    = &vmwdt_open,
 	.release = &vmwdt_close,
-	.ioctl   = &vmwdt_ioctl,
+	.unlocked_ioctl = &vmwdt_ioctl,
 	.write   = &vmwdt_write,
 	.owner   = THIS_MODULE,
 };
@@ -309,6 +314,10 @@
 	ret = register_pm_notifier(&vmwdt_power_notifier);
 	if (ret)
 		return ret;
+	/*
+	 * misc_register() has to be the last action in module_init(), because
+	 * file operations will be available right after this.
+	 */
 	ret = misc_register(&vmwdt_dev);
 	if (ret) {
 		unregister_pm_notifier(&vmwdt_power_notifier);
diff --git a/drivers/s390/cio/Makefile b/drivers/s390/cio/Makefile
index fa4c966..d033414 100644
--- a/drivers/s390/cio/Makefile
+++ b/drivers/s390/cio/Makefile
@@ -3,7 +3,7 @@
 #
 
 obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o isc.o \
-	fcx.o itcw.o crw.o
+	fcx.o itcw.o crw.o ccwreq.o
 ccw_device-objs += device.o device_fsm.o device_ops.o
 ccw_device-objs += device_id.o device_pgid.o device_status.o
 obj-y += ccw_device.o cmf.o
diff --git a/drivers/s390/cio/ccwreq.c b/drivers/s390/cio/ccwreq.c
new file mode 100644
index 0000000..9509e38
--- /dev/null
+++ b/drivers/s390/cio/ccwreq.c
@@ -0,0 +1,328 @@
+/*
+ *  Handling of internal CCW device requests.
+ *
+ *    Copyright IBM Corp. 2009
+ *    Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
+ */
+
+#include <linux/types.h>
+#include <linux/err.h>
+#include <asm/ccwdev.h>
+#include <asm/cio.h>
+
+#include "io_sch.h"
+#include "cio.h"
+#include "device.h"
+#include "cio_debug.h"
+
+/**
+ * lpm_adjust - adjust path mask
+ * @lpm: path mask to adjust
+ * @mask: mask of available paths
+ *
+ * Shift @lpm right until @lpm and @mask have at least one bit in common or
+ * until @lpm is zero. Return the resulting lpm.
+ */
+int lpm_adjust(int lpm, int mask)
+{
+	while (lpm && ((lpm & mask) == 0))
+		lpm >>= 1;
+	return lpm;
+}
+
+/*
+ * Adjust path mask to use next path and reset retry count. Return resulting
+ * path mask.
+ */
+static u16 ccwreq_next_path(struct ccw_device *cdev)
+{
+	struct ccw_request *req = &cdev->private->req;
+
+	req->retries	= req->maxretries;
+	req->mask	= lpm_adjust(req->mask >>= 1, req->lpm);
+
+	return req->mask;
+}
+
+/*
+ * Clean up device state and report to callback.
+ */
+static void ccwreq_stop(struct ccw_device *cdev, int rc)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_request *req = &cdev->private->req;
+
+	if (req->done)
+		return;
+	req->done = 1;
+	ccw_device_set_timeout(cdev, 0);
+	memset(&cdev->private->irb, 0, sizeof(struct irb));
+	sch->lpm = sch->schib.pmcw.pam;
+	if (rc && rc != -ENODEV && req->drc)
+		rc = req->drc;
+	req->callback(cdev, req->data, rc);
+}
+
+/*
+ * (Re-)Start the operation until retries and paths are exhausted.
+ */
+static void ccwreq_do(struct ccw_device *cdev)
+{
+	struct ccw_request *req = &cdev->private->req;
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw1 *cp = req->cp;
+	int rc = -EACCES;
+
+	while (req->mask) {
+		if (req->retries-- == 0) {
+			/* Retries exhausted, try next path. */
+			ccwreq_next_path(cdev);
+			continue;
+		}
+		/* Perform start function. */
+		sch->lpm = 0xff;
+		memset(&cdev->private->irb, 0, sizeof(struct irb));
+		rc = cio_start(sch, cp, (u8) req->mask);
+		if (rc == 0) {
+			/* I/O started successfully. */
+			ccw_device_set_timeout(cdev, req->timeout);
+			return;
+		}
+		if (rc == -ENODEV) {
+			/* Permanent device error. */
+			break;
+		}
+		if (rc == -EACCES) {
+			/* Permant path error. */
+			ccwreq_next_path(cdev);
+			continue;
+		}
+		/* Temporary improper status. */
+		rc = cio_clear(sch);
+		if (rc)
+			break;
+		return;
+	}
+	ccwreq_stop(cdev, rc);
+}
+
+/**
+ * ccw_request_start - perform I/O request
+ * @cdev: ccw device
+ *
+ * Perform the I/O request specified by cdev->req.
+ */
+void ccw_request_start(struct ccw_device *cdev)
+{
+	struct ccw_request *req = &cdev->private->req;
+
+	/* Try all paths twice to counter link flapping. */
+	req->mask	= 0x8080;
+	req->retries	= req->maxretries;
+	req->mask	= lpm_adjust(req->mask, req->lpm);
+	req->drc	= 0;
+	req->done	= 0;
+	req->cancel	= 0;
+	if (!req->mask)
+		goto out_nopath;
+	ccwreq_do(cdev);
+	return;
+
+out_nopath:
+	ccwreq_stop(cdev, -EACCES);
+}
+
+/**
+ * ccw_request_cancel - cancel running I/O request
+ * @cdev: ccw device
+ *
+ * Cancel the I/O request specified by cdev->req. Return non-zero if request
+ * has already finished, zero otherwise.
+ */
+int ccw_request_cancel(struct ccw_device *cdev)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_request *req = &cdev->private->req;
+	int rc;
+
+	if (req->done)
+		return 1;
+	req->cancel = 1;
+	rc = cio_clear(sch);
+	if (rc)
+		ccwreq_stop(cdev, rc);
+	return 0;
+}
+
+/*
+ * Return the status of the internal I/O started on the specified ccw device.
+ * Perform BASIC SENSE if required.
+ */
+static enum io_status ccwreq_status(struct ccw_device *cdev, struct irb *lcirb)
+{
+	struct irb *irb = &cdev->private->irb;
+	struct cmd_scsw *scsw = &irb->scsw.cmd;
+
+	/* Perform BASIC SENSE if needed. */
+	if (ccw_device_accumulate_and_sense(cdev, lcirb))
+		return IO_RUNNING;
+	/* Check for halt/clear interrupt. */
+	if (scsw->fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC))
+		return IO_KILLED;
+	/* Check for path error. */
+	if (scsw->cc == 3 || scsw->pno)
+		return IO_PATH_ERROR;
+	/* Handle BASIC SENSE data. */
+	if (irb->esw.esw0.erw.cons) {
+		CIO_TRACE_EVENT(2, "sensedata");
+		CIO_HEX_EVENT(2, &cdev->private->dev_id,
+			      sizeof(struct ccw_dev_id));
+		CIO_HEX_EVENT(2, &cdev->private->irb.ecw, SENSE_MAX_COUNT);
+		/* Check for command reject. */
+		if (irb->ecw[0] & SNS0_CMD_REJECT)
+			return IO_REJECTED;
+		/* Assume that unexpected SENSE data implies an error. */
+		return IO_STATUS_ERROR;
+	}
+	/* Check for channel errors. */
+	if (scsw->cstat != 0)
+		return IO_STATUS_ERROR;
+	/* Check for device errors. */
+	if (scsw->dstat & ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END))
+		return IO_STATUS_ERROR;
+	/* Check for final state. */
+	if (!(scsw->dstat & DEV_STAT_DEV_END))
+		return IO_RUNNING;
+	/* Check for other improper status. */
+	if (scsw->cc == 1 && (scsw->stctl & SCSW_STCTL_ALERT_STATUS))
+		return IO_STATUS_ERROR;
+	return IO_DONE;
+}
+
+/*
+ * Log ccw request status.
+ */
+static void ccwreq_log_status(struct ccw_device *cdev, enum io_status status)
+{
+	struct ccw_request *req = &cdev->private->req;
+	struct {
+		struct ccw_dev_id dev_id;
+		u16 retries;
+		u8 lpm;
+		u8 status;
+	}  __attribute__ ((packed)) data;
+	data.dev_id	= cdev->private->dev_id;
+	data.retries	= req->retries;
+	data.lpm	= (u8) req->mask;
+	data.status	= (u8) status;
+	CIO_TRACE_EVENT(2, "reqstat");
+	CIO_HEX_EVENT(2, &data, sizeof(data));
+}
+
+/**
+ * ccw_request_handler - interrupt handler for I/O request procedure.
+ * @cdev: ccw device
+ *
+ * Handle interrupt during I/O request procedure.
+ */
+void ccw_request_handler(struct ccw_device *cdev)
+{
+	struct ccw_request *req = &cdev->private->req;
+	struct irb *irb = (struct irb *) __LC_IRB;
+	enum io_status status;
+	int rc = -EOPNOTSUPP;
+
+	/* Check status of I/O request. */
+	status = ccwreq_status(cdev, irb);
+	if (req->filter)
+		status = req->filter(cdev, req->data, irb, status);
+	if (status != IO_RUNNING)
+		ccw_device_set_timeout(cdev, 0);
+	if (status != IO_DONE && status != IO_RUNNING)
+		ccwreq_log_status(cdev, status);
+	switch (status) {
+	case IO_DONE:
+		break;
+	case IO_RUNNING:
+		return;
+	case IO_REJECTED:
+		goto err;
+	case IO_PATH_ERROR:
+		goto out_next_path;
+	case IO_STATUS_ERROR:
+		goto out_restart;
+	case IO_KILLED:
+		/* Check if request was cancelled on purpose. */
+		if (req->cancel) {
+			rc = -EIO;
+			goto err;
+		}
+		goto out_restart;
+	}
+	/* Check back with request initiator. */
+	if (!req->check)
+		goto out;
+	switch (req->check(cdev, req->data)) {
+	case 0:
+		break;
+	case -EAGAIN:
+		goto out_restart;
+	case -EACCES:
+		goto out_next_path;
+	default:
+		goto err;
+	}
+out:
+	ccwreq_stop(cdev, 0);
+	return;
+
+out_next_path:
+	/* Try next path and restart I/O. */
+	if (!ccwreq_next_path(cdev)) {
+		rc = -EACCES;
+		goto err;
+	}
+out_restart:
+	/* Restart. */
+	ccwreq_do(cdev);
+	return;
+err:
+	ccwreq_stop(cdev, rc);
+}
+
+
+/**
+ * ccw_request_timeout - timeout handler for I/O request procedure
+ * @cdev: ccw device
+ *
+ * Handle timeout during I/O request procedure.
+ */
+void ccw_request_timeout(struct ccw_device *cdev)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_request *req = &cdev->private->req;
+	int rc;
+
+	if (!ccwreq_next_path(cdev)) {
+		/* set the final return code for this request */
+		req->drc = -ETIME;
+	}
+	rc = cio_clear(sch);
+	if (rc)
+		goto err;
+	return;
+
+err:
+	ccwreq_stop(cdev, rc);
+}
+
+/**
+ * ccw_request_notoper - notoper handler for I/O request procedure
+ * @cdev: ccw device
+ *
+ * Handle timeout during I/O request procedure.
+ */
+void ccw_request_notoper(struct ccw_device *cdev)
+{
+	ccwreq_stop(cdev, -ENODEV);
+}
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c
index 8ab5160..c268a2e 100644
--- a/drivers/s390/cio/chp.c
+++ b/drivers/s390/cio/chp.c
@@ -65,7 +65,7 @@
 	chpid_to_chp(chpid)->state = onoff;
 }
 
-/* On succes return 0 if channel-path is varied offline, 1 if it is varied
+/* On success return 0 if channel-path is varied offline, 1 if it is varied
  * online. Return -ENODEV if channel-path is not registered. */
 int chp_get_status(struct chp_id chpid)
 {
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 138124f..126f240 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -618,6 +618,7 @@
 	old_regs = set_irq_regs(regs);
 	s390_idle_check();
 	irq_enter();
+	__get_cpu_var(s390_idle).nohz_delay = 1;
 	if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator)
 		/* Serve timer interrupts first. */
 		clock_comparator_work();
diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h
index 2e43558..bf7f80f 100644
--- a/drivers/s390/cio/cio.h
+++ b/drivers/s390/cio/cio.h
@@ -68,6 +68,11 @@
 	__u8 mda[4];		 /* model dependent area */
 } __attribute__ ((packed,aligned(4)));
 
+enum sch_todo {
+	SCH_TODO_NOTHING,
+	SCH_TODO_UNREG,
+};
+
 /* subchannel data structure used by I/O subroutines */
 struct subchannel {
 	struct subchannel_id schid;
@@ -95,7 +100,8 @@
 	struct device dev;	/* entry in device tree */
 	struct css_driver *driver;
 	void *private; /* private per subchannel type data */
-	struct work_struct work;
+	enum sch_todo todo;
+	struct work_struct todo_work;
 	struct schib_config config;
 } __attribute__ ((aligned(8)));
 
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
index 30f5161..2985eb4 100644
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -462,7 +462,7 @@
  * block of memory, which can not be moved as long as any channel
  * is active. Therefore, a maximum number of subchannels needs to
  * be defined somewhere. This is a module parameter, defaulting to
- * a resonable value of 1024, or 32 kb of memory.
+ * a reasonable value of 1024, or 32 kb of memory.
  * Current kernels don't allow kmalloc with more than 128kb, so the
  * maximum is 4096.
  */
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 91c2570..92ff88a 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -133,6 +133,8 @@
 	return rc;
 }
 
+static void css_sch_todo(struct work_struct *work);
+
 static struct subchannel *
 css_alloc_subchannel(struct subchannel_id schid)
 {
@@ -147,6 +149,7 @@
 		kfree(sch);
 		return ERR_PTR(ret);
 	}
+	INIT_WORK(&sch->todo_work, css_sch_todo);
 	return sch;
 }
 
@@ -190,6 +193,51 @@
 }
 EXPORT_SYMBOL_GPL(css_sch_device_unregister);
 
+static void css_sch_todo(struct work_struct *work)
+{
+	struct subchannel *sch;
+	enum sch_todo todo;
+
+	sch = container_of(work, struct subchannel, todo_work);
+	/* Find out todo. */
+	spin_lock_irq(sch->lock);
+	todo = sch->todo;
+	CIO_MSG_EVENT(4, "sch_todo: sch=0.%x.%04x, todo=%d\n", sch->schid.ssid,
+		      sch->schid.sch_no, todo);
+	sch->todo = SCH_TODO_NOTHING;
+	spin_unlock_irq(sch->lock);
+	/* Perform todo. */
+	if (todo == SCH_TODO_UNREG)
+		css_sch_device_unregister(sch);
+	/* Release workqueue ref. */
+	put_device(&sch->dev);
+}
+
+/**
+ * css_sched_sch_todo - schedule a subchannel operation
+ * @sch: subchannel
+ * @todo: todo
+ *
+ * Schedule the operation identified by @todo to be performed on the slow path
+ * workqueue. Do nothing if another operation with higher priority is already
+ * scheduled. Needs to be called with subchannel lock held.
+ */
+void css_sched_sch_todo(struct subchannel *sch, enum sch_todo todo)
+{
+	CIO_MSG_EVENT(4, "sch_todo: sched sch=0.%x.%04x todo=%d\n",
+		      sch->schid.ssid, sch->schid.sch_no, todo);
+	if (sch->todo >= todo)
+		return;
+	/* Get workqueue ref. */
+	if (!get_device(&sch->dev))
+		return;
+	sch->todo = todo;
+	if (!queue_work(slow_path_wq, &sch->todo_work)) {
+		/* Already queued, release workqueue ref. */
+		put_device(&sch->dev);
+	}
+}
+
 static void ssd_from_pmcw(struct chsc_ssd_info *ssd, struct pmcw *pmcw)
 {
 	int i;
@@ -376,8 +424,8 @@
 		/* Unusable - ignore. */
 		return 0;
 	}
-	CIO_MSG_EVENT(4, "Evaluating schid 0.%x.%04x, event %d, unknown, "
-			 "slow path.\n", schid.ssid, schid.sch_no, CIO_OPER);
+	CIO_MSG_EVENT(4, "event: sch 0.%x.%04x, new\n", schid.ssid,
+		      schid.sch_no);
 
 	return css_probe_device(schid);
 }
@@ -394,6 +442,10 @@
 				"Got subchannel machine check but "
 				"no sch_event handler provided.\n");
 	}
+	if (ret != 0 && ret != -EAGAIN) {
+		CIO_MSG_EVENT(2, "eval: sch 0.%x.%04x, rc=%d\n",
+			      sch->schid.ssid, sch->schid.sch_no, ret);
+	}
 	return ret;
 }
 
@@ -684,6 +736,7 @@
 	css->pseudo_subchannel->dev.parent = &css->device;
 	css->pseudo_subchannel->dev.release = css_subchannel_release;
 	dev_set_name(&css->pseudo_subchannel->dev, "defunct");
+	mutex_init(&css->pseudo_subchannel->reg_mutex);
 	ret = cio_create_sch_lock(css->pseudo_subchannel);
 	if (ret) {
 		kfree(css->pseudo_subchannel);
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index 68d6b0b..fe84b92 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -11,6 +11,8 @@
 #include <asm/chpid.h>
 #include <asm/schid.h>
 
+#include "cio.h"
+
 /*
  * path grouping stuff
  */
@@ -151,4 +153,5 @@
 
 extern struct workqueue_struct *slow_path_wq;
 void css_wait_for_slow_path(void);
+void css_sched_sch_todo(struct subchannel *sch, enum sch_todo todo);
 #endif
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 2490b74..9fecfb4 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -7,6 +7,10 @@
  *		 Cornelia Huck (cornelia.huck@de.ibm.com)
  *		 Martin Schwidefsky (schwidefsky@de.ibm.com)
  */
+
+#define KMSG_COMPONENT "cio"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
@@ -299,53 +303,18 @@
 
 static void ccw_device_unregister(struct ccw_device *cdev)
 {
-	if (test_and_clear_bit(1, &cdev->private->registered)) {
+	if (device_is_registered(&cdev->dev)) {
+		/* Undo device_add(). */
 		device_del(&cdev->dev);
+	}
+	if (cdev->private->flags.initialized) {
+		cdev->private->flags.initialized = 0;
 		/* Release reference from device_initialize(). */
 		put_device(&cdev->dev);
 	}
 }
 
-static void ccw_device_remove_orphan_cb(struct work_struct *work)
-{
-	struct ccw_device_private *priv;
-	struct ccw_device *cdev;
-
-	priv = container_of(work, struct ccw_device_private, kick_work);
-	cdev = priv->cdev;
-	ccw_device_unregister(cdev);
-	/* Release cdev reference for workqueue processing. */
-	put_device(&cdev->dev);
-}
-
-static void
-ccw_device_remove_disconnected(struct ccw_device *cdev)
-{
-	unsigned long flags;
-
-	/*
-	 * Forced offline in disconnected state means
-	 * 'throw away device'.
-	 */
-	if (ccw_device_is_orphan(cdev)) {
-		/*
-		 * Deregister ccw device.
-		 * Unfortunately, we cannot do this directly from the
-		 * attribute method.
-		 */
-		/* Get cdev reference for workqueue processing. */
-		if (!get_device(&cdev->dev))
-			return;
-		spin_lock_irqsave(cdev->ccwlock, flags);
-		cdev->private->state = DEV_STATE_NOT_OPER;
-		spin_unlock_irqrestore(cdev->ccwlock, flags);
-		PREPARE_WORK(&cdev->private->kick_work,
-				ccw_device_remove_orphan_cb);
-		queue_work(slow_path_wq, &cdev->private->kick_work);
-	} else
-		/* Deregister subchannel, which will kill the ccw device. */
-		ccw_device_schedule_sch_unregister(cdev);
-}
+static void io_subchannel_quiesce(struct subchannel *);
 
 /**
  * ccw_device_set_offline() - disable a ccw device for I/O
@@ -360,7 +329,8 @@
  */
 int ccw_device_set_offline(struct ccw_device *cdev)
 {
-	int ret;
+	struct subchannel *sch;
+	int ret, state;
 
 	if (!cdev)
 		return -ENODEV;
@@ -374,6 +344,7 @@
 	}
 	cdev->online = 0;
 	spin_lock_irq(cdev->ccwlock);
+	sch = to_subchannel(cdev->dev.parent);
 	/* Wait until a final state or DISCONNECTED is reached */
 	while (!dev_fsm_final_state(cdev) &&
 	       cdev->private->state != DEV_STATE_DISCONNECTED) {
@@ -382,20 +353,37 @@
 			   cdev->private->state == DEV_STATE_DISCONNECTED));
 		spin_lock_irq(cdev->ccwlock);
 	}
-	ret = ccw_device_offline(cdev);
-	if (ret)
-		goto error;
+	do {
+		ret = ccw_device_offline(cdev);
+		if (!ret)
+			break;
+		CIO_MSG_EVENT(0, "ccw_device_offline returned %d, device "
+			      "0.%x.%04x\n", ret, cdev->private->dev_id.ssid,
+			      cdev->private->dev_id.devno);
+		if (ret != -EBUSY)
+			goto error;
+		state = cdev->private->state;
+		spin_unlock_irq(cdev->ccwlock);
+		io_subchannel_quiesce(sch);
+		spin_lock_irq(cdev->ccwlock);
+		cdev->private->state = state;
+	} while (ret == -EBUSY);
 	spin_unlock_irq(cdev->ccwlock);
 	wait_event(cdev->private->wait_q, (dev_fsm_final_state(cdev) ||
 		   cdev->private->state == DEV_STATE_DISCONNECTED));
+	/* Inform the user if set offline failed. */
+	if (cdev->private->state == DEV_STATE_BOXED) {
+		pr_warning("%s: The device entered boxed state while "
+			   "being set offline\n", dev_name(&cdev->dev));
+	} else if (cdev->private->state == DEV_STATE_NOT_OPER) {
+		pr_warning("%s: The device stopped operating while "
+			   "being set offline\n", dev_name(&cdev->dev));
+	}
 	/* Give up reference from ccw_device_set_online(). */
 	put_device(&cdev->dev);
 	return 0;
 
 error:
-	CIO_MSG_EVENT(0, "ccw_device_offline returned %d, device 0.%x.%04x\n",
-		      ret, cdev->private->dev_id.ssid,
-		      cdev->private->dev_id.devno);
 	cdev->private->state = DEV_STATE_OFFLINE;
 	dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
 	spin_unlock_irq(cdev->ccwlock);
@@ -448,6 +436,16 @@
 	if ((cdev->private->state != DEV_STATE_ONLINE) &&
 	    (cdev->private->state != DEV_STATE_W4SENSE)) {
 		spin_unlock_irq(cdev->ccwlock);
+		/* Inform the user that set online failed. */
+		if (cdev->private->state == DEV_STATE_BOXED) {
+			pr_warning("%s: Setting the device online failed "
+				   "because it is boxed\n",
+				   dev_name(&cdev->dev));
+		} else if (cdev->private->state == DEV_STATE_NOT_OPER) {
+			pr_warning("%s: Setting the device online failed "
+				   "because it is not operational\n",
+				   dev_name(&cdev->dev));
+		}
 		/* Give up online reference since onlining failed. */
 		put_device(&cdev->dev);
 		return -ENODEV;
@@ -494,27 +492,22 @@
 
 static int online_store_handle_offline(struct ccw_device *cdev)
 {
-	if (cdev->private->state == DEV_STATE_DISCONNECTED)
-		ccw_device_remove_disconnected(cdev);
-	else if (cdev->online && cdev->drv && cdev->drv->set_offline)
+	if (cdev->private->state == DEV_STATE_DISCONNECTED) {
+		spin_lock_irq(cdev->ccwlock);
+		ccw_device_sched_todo(cdev, CDEV_TODO_UNREG_EVAL);
+		spin_unlock_irq(cdev->ccwlock);
+	} else if (cdev->online && cdev->drv && cdev->drv->set_offline)
 		return ccw_device_set_offline(cdev);
 	return 0;
 }
 
 static int online_store_recog_and_online(struct ccw_device *cdev)
 {
-	int ret;
-
 	/* Do device recognition, if needed. */
 	if (cdev->private->state == DEV_STATE_BOXED) {
-		ret = ccw_device_recognition(cdev);
-		if (ret) {
-			CIO_MSG_EVENT(0, "Couldn't start recognition "
-				      "for device 0.%x.%04x (ret=%d)\n",
-				      cdev->private->dev_id.ssid,
-				      cdev->private->dev_id.devno, ret);
-			return ret;
-		}
+		spin_lock_irq(cdev->ccwlock);
+		ccw_device_recognition(cdev);
+		spin_unlock_irq(cdev->ccwlock);
 		wait_event(cdev->private->wait_q,
 			   cdev->private->flags.recog_done);
 		if (cdev->private->state != DEV_STATE_OFFLINE)
@@ -553,11 +546,10 @@
 	int force, ret;
 	unsigned long i;
 
-	if ((cdev->private->state != DEV_STATE_OFFLINE &&
-	     cdev->private->state != DEV_STATE_ONLINE &&
-	     cdev->private->state != DEV_STATE_BOXED &&
-	     cdev->private->state != DEV_STATE_DISCONNECTED) ||
-	    atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0)
+	if (!dev_fsm_final_state(cdev) &&
+	    cdev->private->state != DEV_STATE_DISCONNECTED)
+		return -EAGAIN;
+	if (atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0)
 		return -EAGAIN;
 
 	if (cdev->drv && !try_module_get(cdev->drv->owner)) {
@@ -665,81 +657,31 @@
 			   cdev->private->dev_id.devno);
 	if (ret)
 		return ret;
-	ret = device_add(dev);
-	if (ret)
-		return ret;
-
-	set_bit(1, &cdev->private->registered);
-	return ret;
+	return device_add(dev);
 }
 
-struct match_data {
-	struct ccw_dev_id dev_id;
-	struct ccw_device * sibling;
-};
-
-static int
-match_devno(struct device * dev, void * data)
+static int match_dev_id(struct device *dev, void *data)
 {
-	struct match_data * d = data;
-	struct ccw_device * cdev;
+	struct ccw_device *cdev = to_ccwdev(dev);
+	struct ccw_dev_id *dev_id = data;
 
-	cdev = to_ccwdev(dev);
-	if ((cdev->private->state == DEV_STATE_DISCONNECTED) &&
-	    !ccw_device_is_orphan(cdev) &&
-	    ccw_dev_id_is_equal(&cdev->private->dev_id, &d->dev_id) &&
-	    (cdev != d->sibling))
-		return 1;
-	return 0;
-}
-
-static struct ccw_device * get_disc_ccwdev_by_dev_id(struct ccw_dev_id *dev_id,
-						     struct ccw_device *sibling)
-{
-	struct device *dev;
-	struct match_data data;
-
-	data.dev_id = *dev_id;
-	data.sibling = sibling;
-	dev = bus_find_device(&ccw_bus_type, NULL, &data, match_devno);
-
-	return dev ? to_ccwdev(dev) : NULL;
-}
-
-static int match_orphan(struct device *dev, void *data)
-{
-	struct ccw_dev_id *dev_id;
-	struct ccw_device *cdev;
-
-	dev_id = data;
-	cdev = to_ccwdev(dev);
 	return ccw_dev_id_is_equal(&cdev->private->dev_id, dev_id);
 }
 
-static struct ccw_device *
-get_orphaned_ccwdev_by_dev_id(struct channel_subsystem *css,
-			      struct ccw_dev_id *dev_id)
+static struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id)
 {
 	struct device *dev;
 
-	dev = device_find_child(&css->pseudo_subchannel->dev, dev_id,
-				match_orphan);
+	dev = bus_find_device(&ccw_bus_type, NULL, dev_id, match_dev_id);
 
 	return dev ? to_ccwdev(dev) : NULL;
 }
 
-void ccw_device_do_unbind_bind(struct work_struct *work)
+static void ccw_device_do_unbind_bind(struct ccw_device *cdev)
 {
-	struct ccw_device_private *priv;
-	struct ccw_device *cdev;
-	struct subchannel *sch;
 	int ret;
 
-	priv = container_of(work, struct ccw_device_private, kick_work);
-	cdev = priv->cdev;
-	sch = to_subchannel(cdev->dev.parent);
-
-	if (test_bit(1, &cdev->private->registered)) {
+	if (device_is_registered(&cdev->dev)) {
 		device_release_driver(&cdev->dev);
 		ret = device_attach(&cdev->dev);
 		WARN_ON(ret == -ENODEV);
@@ -773,6 +715,8 @@
 	return ERR_PTR(-ENOMEM);
 }
 
+static void ccw_device_todo(struct work_struct *work);
+
 static int io_subchannel_initialize_dev(struct subchannel *sch,
 					struct ccw_device *cdev)
 {
@@ -780,7 +724,7 @@
 	atomic_set(&cdev->private->onoff, 0);
 	cdev->dev.parent = &sch->dev;
 	cdev->dev.release = ccw_device_release;
-	INIT_WORK(&cdev->private->kick_work, NULL);
+	INIT_WORK(&cdev->private->todo_work, ccw_device_todo);
 	cdev->dev.groups = ccwdev_attr_groups;
 	/* Do first half of device_register. */
 	device_initialize(&cdev->dev);
@@ -789,6 +733,7 @@
 		put_device(&cdev->dev);
 		return -ENODEV;
 	}
+	cdev->private->flags.initialized = 1;
 	return 0;
 }
 
@@ -806,76 +751,7 @@
 	return cdev;
 }
 
-static int io_subchannel_recog(struct ccw_device *, struct subchannel *);
-
-static void sch_attach_device(struct subchannel *sch,
-			      struct ccw_device *cdev)
-{
-	css_update_ssd_info(sch);
-	spin_lock_irq(sch->lock);
-	sch_set_cdev(sch, cdev);
-	cdev->private->schid = sch->schid;
-	cdev->ccwlock = sch->lock;
-	ccw_device_trigger_reprobe(cdev);
-	spin_unlock_irq(sch->lock);
-}
-
-static void sch_attach_disconnected_device(struct subchannel *sch,
-					   struct ccw_device *cdev)
-{
-	struct subchannel *other_sch;
-	int ret;
-
-	/* Get reference for new parent. */
-	if (!get_device(&sch->dev))
-		return;
-	other_sch = to_subchannel(cdev->dev.parent);
-	/* Note: device_move() changes cdev->dev.parent */
-	ret = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV);
-	if (ret) {
-		CIO_MSG_EVENT(0, "Moving disconnected device 0.%x.%04x failed "
-			      "(ret=%d)!\n", cdev->private->dev_id.ssid,
-			      cdev->private->dev_id.devno, ret);
-		/* Put reference for new parent. */
-		put_device(&sch->dev);
-		return;
-	}
-	sch_set_cdev(other_sch, NULL);
-	/* No need to keep a subchannel without ccw device around. */
-	css_sch_device_unregister(other_sch);
-	sch_attach_device(sch, cdev);
-	/* Put reference for old parent. */
-	put_device(&other_sch->dev);
-}
-
-static void sch_attach_orphaned_device(struct subchannel *sch,
-				       struct ccw_device *cdev)
-{
-	int ret;
-	struct subchannel *pseudo_sch;
-
-	/* Get reference for new parent. */
-	if (!get_device(&sch->dev))
-		return;
-	pseudo_sch = to_subchannel(cdev->dev.parent);
-	/*
-	 * Try to move the ccw device to its new subchannel.
-	 * Note: device_move() changes cdev->dev.parent
-	 */
-	ret = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV);
-	if (ret) {
-		CIO_MSG_EVENT(0, "Moving device 0.%x.%04x from orphanage "
-			      "failed (ret=%d)!\n",
-			      cdev->private->dev_id.ssid,
-			      cdev->private->dev_id.devno, ret);
-		/* Put reference for new parent. */
-		put_device(&sch->dev);
-		return;
-	}
-	sch_attach_device(sch, cdev);
-	/* Put reference on pseudo subchannel. */
-	put_device(&pseudo_sch->dev);
-}
+static void io_subchannel_recog(struct ccw_device *, struct subchannel *);
 
 static void sch_create_and_recog_new_device(struct subchannel *sch)
 {
@@ -888,100 +764,19 @@
 		css_sch_device_unregister(sch);
 		return;
 	}
-	spin_lock_irq(sch->lock);
-	sch_set_cdev(sch, cdev);
-	spin_unlock_irq(sch->lock);
 	/* Start recognition for the new ccw device. */
-	if (io_subchannel_recog(cdev, sch)) {
-		spin_lock_irq(sch->lock);
-		sch_set_cdev(sch, NULL);
-		spin_unlock_irq(sch->lock);
-		css_sch_device_unregister(sch);
-		/* Put reference from io_subchannel_create_ccwdev(). */
-		put_device(&sch->dev);
-		/* Give up initial reference. */
-		put_device(&cdev->dev);
-	}
-}
-
-
-void ccw_device_move_to_orphanage(struct work_struct *work)
-{
-	struct ccw_device_private *priv;
-	struct ccw_device *cdev;
-	struct ccw_device *replacing_cdev;
-	struct subchannel *sch;
-	int ret;
-	struct channel_subsystem *css;
-	struct ccw_dev_id dev_id;
-
-	priv = container_of(work, struct ccw_device_private, kick_work);
-	cdev = priv->cdev;
-	sch = to_subchannel(cdev->dev.parent);
-	css = to_css(sch->dev.parent);
-	dev_id.devno = sch->schib.pmcw.dev;
-	dev_id.ssid = sch->schid.ssid;
-
-	/* Increase refcount for pseudo subchannel. */
-	get_device(&css->pseudo_subchannel->dev);
-	/*
-	 * Move the orphaned ccw device to the orphanage so the replacing
-	 * ccw device can take its place on the subchannel.
-	 * Note: device_move() changes cdev->dev.parent
-	 */
-	ret = device_move(&cdev->dev, &css->pseudo_subchannel->dev,
-		DPM_ORDER_NONE);
-	if (ret) {
-		CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to orphanage failed "
-			      "(ret=%d)!\n", cdev->private->dev_id.ssid,
-			      cdev->private->dev_id.devno, ret);
-		/* Decrease refcount for pseudo subchannel again. */
-		put_device(&css->pseudo_subchannel->dev);
-		return;
-	}
-	cdev->ccwlock = css->pseudo_subchannel->lock;
-	/*
-	 * Search for the replacing ccw device
-	 * - among the disconnected devices
-	 * - in the orphanage
-	 */
-	replacing_cdev = get_disc_ccwdev_by_dev_id(&dev_id, cdev);
-	if (replacing_cdev) {
-		sch_attach_disconnected_device(sch, replacing_cdev);
-		/* Release reference from get_disc_ccwdev_by_dev_id() */
-		put_device(&replacing_cdev->dev);
-		/* Release reference of subchannel from old cdev. */
-		put_device(&sch->dev);
-		return;
-	}
-	replacing_cdev = get_orphaned_ccwdev_by_dev_id(css, &dev_id);
-	if (replacing_cdev) {
-		sch_attach_orphaned_device(sch, replacing_cdev);
-		/* Release reference from get_orphaned_ccwdev_by_dev_id() */
-		put_device(&replacing_cdev->dev);
-		/* Release reference of subchannel from old cdev. */
-		put_device(&sch->dev);
-		return;
-	}
-	sch_create_and_recog_new_device(sch);
-	/* Release reference of subchannel from old cdev. */
-	put_device(&sch->dev);
+	io_subchannel_recog(cdev, sch);
 }
 
 /*
  * Register recognized device.
  */
-static void
-io_subchannel_register(struct work_struct *work)
+static void io_subchannel_register(struct ccw_device *cdev)
 {
-	struct ccw_device_private *priv;
-	struct ccw_device *cdev;
 	struct subchannel *sch;
 	int ret;
 	unsigned long flags;
 
-	priv = container_of(work, struct ccw_device_private, kick_work);
-	cdev = priv->cdev;
 	sch = to_subchannel(cdev->dev.parent);
 	/*
 	 * Check if subchannel is still registered. It may have become
@@ -1033,41 +828,23 @@
 	cdev->private->flags.recog_done = 1;
 	wake_up(&cdev->private->wait_q);
 out_err:
-	/* Release reference for workqueue processing. */
-	put_device(&cdev->dev);
 	if (atomic_dec_and_test(&ccw_device_init_count))
 		wake_up(&ccw_device_init_wq);
 }
 
-static void ccw_device_call_sch_unregister(struct work_struct *work)
+static void ccw_device_call_sch_unregister(struct ccw_device *cdev)
 {
-	struct ccw_device_private *priv;
-	struct ccw_device *cdev;
 	struct subchannel *sch;
 
-	priv = container_of(work, struct ccw_device_private, kick_work);
-	cdev = priv->cdev;
 	/* Get subchannel reference for local processing. */
 	if (!get_device(cdev->dev.parent))
 		return;
 	sch = to_subchannel(cdev->dev.parent);
 	css_sch_device_unregister(sch);
-	/* Release cdev reference for workqueue processing.*/
-	put_device(&cdev->dev);
 	/* Release subchannel reference for local processing. */
 	put_device(&sch->dev);
 }
 
-void ccw_device_schedule_sch_unregister(struct ccw_device *cdev)
-{
-	/* Get cdev reference for workqueue processing. */
-	if (!get_device(&cdev->dev))
-		return;
-	PREPARE_WORK(&cdev->private->kick_work,
-		     ccw_device_call_sch_unregister);
-	queue_work(slow_path_wq, &cdev->private->kick_work);
-}
-
 /*
  * subchannel recognition done. Called from the state machine.
  */
@@ -1083,7 +860,8 @@
 		/* Device did not respond in time. */
 	case DEV_STATE_NOT_OPER:
 		cdev->private->flags.recog_done = 1;
-		ccw_device_schedule_sch_unregister(cdev);
+		/* Remove device found not operational. */
+		ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 		if (atomic_dec_and_test(&ccw_device_init_count))
 			wake_up(&ccw_device_init_wq);
 		break;
@@ -1092,22 +870,15 @@
 		 * We can't register the device in interrupt context so
 		 * we schedule a work item.
 		 */
-		if (!get_device(&cdev->dev))
-			break;
-		PREPARE_WORK(&cdev->private->kick_work,
-			     io_subchannel_register);
-		queue_work(slow_path_wq, &cdev->private->kick_work);
+		ccw_device_sched_todo(cdev, CDEV_TODO_REGISTER);
 		break;
 	}
 }
 
-static int
-io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch)
+static void io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch)
 {
-	int rc;
 	struct ccw_device_private *priv;
 
-	sch_set_cdev(sch, cdev);
 	cdev->ccwlock = sch->lock;
 
 	/* Init private data. */
@@ -1125,62 +896,81 @@
 
 	/* Start async. device sensing. */
 	spin_lock_irq(sch->lock);
-	rc = ccw_device_recognition(cdev);
+	sch_set_cdev(sch, cdev);
+	ccw_device_recognition(cdev);
 	spin_unlock_irq(sch->lock);
-	if (rc) {
-		if (atomic_dec_and_test(&ccw_device_init_count))
-			wake_up(&ccw_device_init_wq);
-	}
-	return rc;
 }
 
-static void ccw_device_move_to_sch(struct work_struct *work)
+static int ccw_device_move_to_sch(struct ccw_device *cdev,
+				  struct subchannel *sch)
 {
-	struct ccw_device_private *priv;
-	int rc;
-	struct subchannel *sch;
-	struct ccw_device *cdev;
-	struct subchannel *former_parent;
+	struct subchannel *old_sch;
+	int rc, old_enabled = 0;
 
-	priv = container_of(work, struct ccw_device_private, kick_work);
-	sch = priv->sch;
-	cdev = priv->cdev;
-	former_parent = to_subchannel(cdev->dev.parent);
-	/* Get reference for new parent. */
+	old_sch = to_subchannel(cdev->dev.parent);
+	/* Obtain child reference for new parent. */
 	if (!get_device(&sch->dev))
-		return;
+		return -ENODEV;
+
+	if (!sch_is_pseudo_sch(old_sch)) {
+		spin_lock_irq(old_sch->lock);
+		old_enabled = old_sch->schib.pmcw.ena;
+		rc = 0;
+		if (old_enabled)
+			rc = cio_disable_subchannel(old_sch);
+		spin_unlock_irq(old_sch->lock);
+		if (rc == -EBUSY) {
+			/* Release child reference for new parent. */
+			put_device(&sch->dev);
+			return rc;
+		}
+	}
+
 	mutex_lock(&sch->reg_mutex);
-	/*
-	 * Try to move the ccw device to its new subchannel.
-	 * Note: device_move() changes cdev->dev.parent
-	 */
 	rc = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV);
 	mutex_unlock(&sch->reg_mutex);
 	if (rc) {
-		CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to subchannel "
-			      "0.%x.%04x failed (ret=%d)!\n",
+		CIO_MSG_EVENT(0, "device_move(0.%x.%04x,0.%x.%04x)=%d\n",
 			      cdev->private->dev_id.ssid,
 			      cdev->private->dev_id.devno, sch->schid.ssid,
-			      sch->schid.sch_no, rc);
-		css_sch_device_unregister(sch);
-		/* Put reference for new parent again. */
+			      sch->schib.pmcw.dev, rc);
+		if (old_enabled) {
+			/* Try to reenable the old subchannel. */
+			spin_lock_irq(old_sch->lock);
+			cio_enable_subchannel(old_sch, (u32)(addr_t)old_sch);
+			spin_unlock_irq(old_sch->lock);
+		}
+		/* Release child reference for new parent. */
 		put_device(&sch->dev);
-		goto out;
+		return rc;
 	}
-	if (!sch_is_pseudo_sch(former_parent)) {
-		spin_lock_irq(former_parent->lock);
-		sch_set_cdev(former_parent, NULL);
-		spin_unlock_irq(former_parent->lock);
-		css_sch_device_unregister(former_parent);
-		/* Reset intparm to zeroes. */
-		former_parent->config.intparm = 0;
-		cio_commit_config(former_parent);
+	/* Clean up old subchannel. */
+	if (!sch_is_pseudo_sch(old_sch)) {
+		spin_lock_irq(old_sch->lock);
+		sch_set_cdev(old_sch, NULL);
+		spin_unlock_irq(old_sch->lock);
+		css_schedule_eval(old_sch->schid);
 	}
-	sch_attach_device(sch, cdev);
-out:
-	/* Put reference for old parent. */
-	put_device(&former_parent->dev);
-	put_device(&cdev->dev);
+	/* Release child reference for old parent. */
+	put_device(&old_sch->dev);
+	/* Initialize new subchannel. */
+	spin_lock_irq(sch->lock);
+	cdev->private->schid = sch->schid;
+	cdev->ccwlock = sch->lock;
+	if (!sch_is_pseudo_sch(sch))
+		sch_set_cdev(sch, cdev);
+	spin_unlock_irq(sch->lock);
+	if (!sch_is_pseudo_sch(sch))
+		css_update_ssd_info(sch);
+	return 0;
+}
+
+static int ccw_device_move_to_orph(struct ccw_device *cdev)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct channel_subsystem *css = to_css(sch->dev.parent);
+
+	return ccw_device_move_to_sch(cdev, css->pseudo_subchannel);
 }
 
 static void io_subchannel_irq(struct subchannel *sch)
@@ -1199,9 +989,6 @@
 {
 	memset(&sch->config, 0, sizeof(sch->config));
 	sch->config.csense = 1;
-	/* Use subchannel mp mode when there is more than 1 installed CHPID. */
-	if ((sch->schib.pmcw.pim & (sch->schib.pmcw.pim - 1)) != 0)
-		sch->config.mp = 1;
 }
 
 static void io_subchannel_init_fields(struct subchannel *sch)
@@ -1222,23 +1009,6 @@
 	io_subchannel_init_config(sch);
 }
 
-static void io_subchannel_do_unreg(struct work_struct *work)
-{
-	struct subchannel *sch;
-
-	sch = container_of(work, struct subchannel, work);
-	css_sch_device_unregister(sch);
-	put_device(&sch->dev);
-}
-
-/* Schedule unregister if we have no cdev. */
-static void io_subchannel_schedule_removal(struct subchannel *sch)
-{
-	get_device(&sch->dev);
-	INIT_WORK(&sch->work, io_subchannel_do_unreg);
-	queue_work(slow_path_wq, &sch->work);
-}
-
 /*
  * Note: We always return 0 so that we bind to the device even on error.
  * This is needed so that our remove function is called on unregister.
@@ -1247,8 +1017,6 @@
 {
 	struct ccw_device *cdev;
 	int rc;
-	unsigned long flags;
-	struct ccw_dev_id dev_id;
 
 	if (cio_is_console(sch->schid)) {
 		rc = sysfs_create_group(&sch->dev.kobj,
@@ -1268,6 +1036,7 @@
 		cdev = sch_get_cdev(sch);
 		cdev->dev.groups = ccwdev_attr_groups;
 		device_initialize(&cdev->dev);
+		cdev->private->flags.initialized = 1;
 		ccw_device_register(cdev);
 		/*
 		 * Check if the device is already online. If it is
@@ -1292,44 +1061,14 @@
 	sch->private = kzalloc(sizeof(struct io_subchannel_private),
 			       GFP_KERNEL | GFP_DMA);
 	if (!sch->private)
-		goto out_err;
-	/*
-	 * First check if a fitting device may be found amongst the
-	 * disconnected devices or in the orphanage.
-	 */
-	dev_id.devno = sch->schib.pmcw.dev;
-	dev_id.ssid = sch->schid.ssid;
-	cdev = get_disc_ccwdev_by_dev_id(&dev_id, NULL);
-	if (!cdev)
-		cdev = get_orphaned_ccwdev_by_dev_id(to_css(sch->dev.parent),
-						     &dev_id);
-	if (cdev) {
-		/*
-		 * Schedule moving the device until when we have a registered
-		 * subchannel to move to and succeed the probe. We can
-		 * unregister later again, when the probe is through.
-		 */
-		cdev->private->sch = sch;
-		PREPARE_WORK(&cdev->private->kick_work,
-			     ccw_device_move_to_sch);
-		queue_work(slow_path_wq, &cdev->private->kick_work);
-		return 0;
-	}
-	cdev = io_subchannel_create_ccwdev(sch);
-	if (IS_ERR(cdev))
-		goto out_err;
-	rc = io_subchannel_recog(cdev, sch);
-	if (rc) {
-		spin_lock_irqsave(sch->lock, flags);
-		io_subchannel_recog_done(cdev);
-		spin_unlock_irqrestore(sch->lock, flags);
-	}
+		goto out_schedule;
+	css_schedule_eval(sch->schid);
 	return 0;
-out_err:
-	kfree(sch->private);
-	sysfs_remove_group(&sch->dev.kobj, &io_subchannel_attr_group);
+
 out_schedule:
-	io_subchannel_schedule_removal(sch);
+	spin_lock_irq(sch->lock);
+	css_sched_sch_todo(sch, SCH_TODO_UNREG);
+	spin_unlock_irq(sch->lock);
 	return 0;
 }
 
@@ -1337,32 +1076,23 @@
 io_subchannel_remove (struct subchannel *sch)
 {
 	struct ccw_device *cdev;
-	unsigned long flags;
 
 	cdev = sch_get_cdev(sch);
 	if (!cdev)
-		return 0;
+		goto out_free;
+	io_subchannel_quiesce(sch);
 	/* Set ccw device to not operational and drop reference. */
-	spin_lock_irqsave(cdev->ccwlock, flags);
+	spin_lock_irq(cdev->ccwlock);
 	sch_set_cdev(sch, NULL);
 	cdev->private->state = DEV_STATE_NOT_OPER;
-	spin_unlock_irqrestore(cdev->ccwlock, flags);
+	spin_unlock_irq(cdev->ccwlock);
 	ccw_device_unregister(cdev);
+out_free:
 	kfree(sch->private);
 	sysfs_remove_group(&sch->dev.kobj, &io_subchannel_attr_group);
 	return 0;
 }
 
-static int io_subchannel_notify(struct subchannel *sch, int event)
-{
-	struct ccw_device *cdev;
-
-	cdev = sch_get_cdev(sch);
-	if (!cdev)
-		return 0;
-	return ccw_device_notify(cdev, event);
-}
-
 static void io_subchannel_verify(struct subchannel *sch)
 {
 	struct ccw_device *cdev;
@@ -1372,36 +1102,6 @@
 		dev_fsm_event(cdev, DEV_EVENT_VERIFY);
 }
 
-static int check_for_io_on_path(struct subchannel *sch, int mask)
-{
-	if (cio_update_schib(sch))
-		return 0;
-	if (scsw_actl(&sch->schib.scsw) && sch->schib.pmcw.lpum == mask)
-		return 1;
-	return 0;
-}
-
-static void terminate_internal_io(struct subchannel *sch,
-				  struct ccw_device *cdev)
-{
-	if (cio_clear(sch)) {
-		/* Recheck device in case clear failed. */
-		sch->lpm = 0;
-		if (cdev->online)
-			dev_fsm_event(cdev, DEV_EVENT_VERIFY);
-		else
-			css_schedule_eval(sch->schid);
-		return;
-	}
-	cdev->private->state = DEV_STATE_CLEAR_VERIFY;
-	/* Request retry of internal operation. */
-	cdev->private->flags.intretry = 1;
-	/* Call handler. */
-	if (cdev->handler)
-		cdev->handler(cdev, cdev->private->intparm,
-			      ERR_PTR(-EIO));
-}
-
 static void io_subchannel_terminate_path(struct subchannel *sch, u8 mask)
 {
 	struct ccw_device *cdev;
@@ -1409,18 +1109,24 @@
 	cdev = sch_get_cdev(sch);
 	if (!cdev)
 		return;
-	if (check_for_io_on_path(sch, mask)) {
-		if (cdev->private->state == DEV_STATE_ONLINE)
-			ccw_device_kill_io(cdev);
-		else {
-			terminate_internal_io(sch, cdev);
-			/* Re-start path verification. */
-			dev_fsm_event(cdev, DEV_EVENT_VERIFY);
-		}
-	} else
-		/* trigger path verification. */
-		dev_fsm_event(cdev, DEV_EVENT_VERIFY);
+	if (cio_update_schib(sch))
+		goto err;
+	/* Check for I/O on path. */
+	if (scsw_actl(&sch->schib.scsw) == 0 || sch->schib.pmcw.lpum != mask)
+		goto out;
+	if (cdev->private->state == DEV_STATE_ONLINE) {
+		ccw_device_kill_io(cdev);
+		goto out;
+	}
+	if (cio_clear(sch))
+		goto err;
+out:
+	/* Trigger path verification. */
+	dev_fsm_event(cdev, DEV_EVENT_VERIFY);
+	return;
 
+err:
+	dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
 }
 
 static int io_subchannel_chp_event(struct subchannel *sch,
@@ -1457,46 +1163,41 @@
 	return 0;
 }
 
-static void
-io_subchannel_shutdown(struct subchannel *sch)
+static void io_subchannel_quiesce(struct subchannel *sch)
 {
 	struct ccw_device *cdev;
 	int ret;
 
+	spin_lock_irq(sch->lock);
 	cdev = sch_get_cdev(sch);
-
 	if (cio_is_console(sch->schid))
-		return;
+		goto out_unlock;
 	if (!sch->schib.pmcw.ena)
-		/* Nothing to do. */
-		return;
+		goto out_unlock;
 	ret = cio_disable_subchannel(sch);
 	if (ret != -EBUSY)
-		/* Subchannel is disabled, we're done. */
-		return;
-	cdev->private->state = DEV_STATE_QUIESCE;
+		goto out_unlock;
 	if (cdev->handler)
-		cdev->handler(cdev, cdev->private->intparm,
-			      ERR_PTR(-EIO));
-	ret = ccw_device_cancel_halt_clear(cdev);
-	if (ret == -EBUSY) {
-		ccw_device_set_timeout(cdev, HZ/10);
-		wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
+		cdev->handler(cdev, cdev->private->intparm, ERR_PTR(-EIO));
+	while (ret == -EBUSY) {
+		cdev->private->state = DEV_STATE_QUIESCE;
+		ret = ccw_device_cancel_halt_clear(cdev);
+		if (ret == -EBUSY) {
+			ccw_device_set_timeout(cdev, HZ/10);
+			spin_unlock_irq(sch->lock);
+			wait_event(cdev->private->wait_q,
+				   cdev->private->state != DEV_STATE_QUIESCE);
+			spin_lock_irq(sch->lock);
+		}
+		ret = cio_disable_subchannel(sch);
 	}
-	cio_disable_subchannel(sch);
+out_unlock:
+	spin_unlock_irq(sch->lock);
 }
 
-static int io_subchannel_get_status(struct subchannel *sch)
+static void io_subchannel_shutdown(struct subchannel *sch)
 {
-	struct schib schib;
-
-	if (stsch(sch->schid, &schib) || !schib.pmcw.dnv)
-		return CIO_GONE;
-	if (sch->schib.pmcw.dnv && (schib.pmcw.dev != sch->schib.pmcw.dev))
-		return CIO_REVALIDATE;
-	if (!sch->lpm)
-		return CIO_NO_PATH;
-	return CIO_OPER;
+	io_subchannel_quiesce(sch);
 }
 
 static int device_is_disconnected(struct ccw_device *cdev)
@@ -1575,20 +1276,16 @@
 static int purge_fn(struct device *dev, void *data)
 {
 	struct ccw_device *cdev = to_ccwdev(dev);
-	struct ccw_device_private *priv = cdev->private;
-	int unreg;
+	struct ccw_dev_id *id = &cdev->private->dev_id;
 
 	spin_lock_irq(cdev->ccwlock);
-	unreg = is_blacklisted(priv->dev_id.ssid, priv->dev_id.devno) &&
-		(priv->state == DEV_STATE_OFFLINE);
+	if (is_blacklisted(id->ssid, id->devno) &&
+	    (cdev->private->state == DEV_STATE_OFFLINE)) {
+		CIO_MSG_EVENT(3, "ccw: purging 0.%x.%04x\n", id->ssid,
+			      id->devno);
+		ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
+	}
 	spin_unlock_irq(cdev->ccwlock);
-	if (!unreg)
-		goto out;
-	CIO_MSG_EVENT(3, "ccw: purging 0.%x.%04x\n", priv->dev_id.ssid,
-		      priv->dev_id.devno);
-	ccw_device_schedule_sch_unregister(cdev);
-
-out:
 	/* Abort loop in case of pending signal. */
 	if (signal_pending(current))
 		return -EINTR;
@@ -1630,91 +1327,169 @@
 	cdev->private->state = DEV_STATE_NOT_OPER;
 }
 
-static int io_subchannel_sch_event(struct subchannel *sch, int slow)
+enum io_sch_action {
+	IO_SCH_UNREG,
+	IO_SCH_ORPH_UNREG,
+	IO_SCH_ATTACH,
+	IO_SCH_UNREG_ATTACH,
+	IO_SCH_ORPH_ATTACH,
+	IO_SCH_REPROBE,
+	IO_SCH_VERIFY,
+	IO_SCH_DISC,
+	IO_SCH_NOP,
+};
+
+static enum io_sch_action sch_get_action(struct subchannel *sch)
 {
-	int event, ret, disc;
-	unsigned long flags;
-	enum { NONE, UNREGISTER, UNREGISTER_PROBE, REPROBE, DISC } action;
 	struct ccw_device *cdev;
 
-	spin_lock_irqsave(sch->lock, flags);
 	cdev = sch_get_cdev(sch);
-	disc = device_is_disconnected(cdev);
-	if (disc && slow) {
-		/* Disconnected devices are evaluated directly only.*/
-		spin_unlock_irqrestore(sch->lock, flags);
-		return 0;
+	if (cio_update_schib(sch)) {
+		/* Not operational. */
+		if (!cdev)
+			return IO_SCH_UNREG;
+		if (!ccw_device_notify(cdev, CIO_GONE))
+			return IO_SCH_UNREG;
+		return IO_SCH_ORPH_UNREG;
 	}
-	/* No interrupt after machine check - kill pending timers. */
-	if (cdev)
-		ccw_device_set_timeout(cdev, 0);
-	if (!disc && !slow) {
-		/* Non-disconnected devices are evaluated on the slow path. */
-		spin_unlock_irqrestore(sch->lock, flags);
-		return -EAGAIN;
+	/* Operational. */
+	if (!cdev)
+		return IO_SCH_ATTACH;
+	if (sch->schib.pmcw.dev != cdev->private->dev_id.devno) {
+		if (!ccw_device_notify(cdev, CIO_GONE))
+			return IO_SCH_UNREG_ATTACH;
+		return IO_SCH_ORPH_ATTACH;
 	}
-	event = io_subchannel_get_status(sch);
-	CIO_MSG_EVENT(4, "Evaluating schid 0.%x.%04x, event %d, %s, %s path.\n",
-		      sch->schid.ssid, sch->schid.sch_no, event,
-		      disc ? "disconnected" : "normal",
-		      slow ? "slow" : "fast");
-	/* Analyze subchannel status. */
-	action = NONE;
-	switch (event) {
-	case CIO_NO_PATH:
-		if (disc) {
-			/* Check if paths have become available. */
-			action = REPROBE;
-			break;
-		}
-		/* fall through */
-	case CIO_GONE:
-		/* Ask driver what to do with device. */
-		if (io_subchannel_notify(sch, event))
-			action = DISC;
-		else
-			action = UNREGISTER;
-		break;
-	case CIO_REVALIDATE:
-		/* Device will be removed, so no notify necessary. */
-		if (disc)
-			/* Reprobe because immediate unregister might block. */
-			action = REPROBE;
-		else
-			action = UNREGISTER_PROBE;
-		break;
-	case CIO_OPER:
-		if (disc)
-			/* Get device operational again. */
-			action = REPROBE;
-		break;
+	if ((sch->schib.pmcw.pam & sch->opm) == 0) {
+		if (!ccw_device_notify(cdev, CIO_NO_PATH))
+			return IO_SCH_UNREG;
+		return IO_SCH_DISC;
 	}
-	/* Perform action. */
-	ret = 0;
+	if (device_is_disconnected(cdev))
+		return IO_SCH_REPROBE;
+	if (cdev->online)
+		return IO_SCH_VERIFY;
+	return IO_SCH_NOP;
+}
+
+/**
+ * io_subchannel_sch_event - process subchannel event
+ * @sch: subchannel
+ * @process: non-zero if function is called in process context
+ *
+ * An unspecified event occurred for this subchannel. Adjust data according
+ * to the current operational state of the subchannel and device. Return
+ * zero when the event has been handled sufficiently or -EAGAIN when this
+ * function should be called again in process context.
+ */
+static int io_subchannel_sch_event(struct subchannel *sch, int process)
+{
+	unsigned long flags;
+	struct ccw_device *cdev;
+	struct ccw_dev_id dev_id;
+	enum io_sch_action action;
+	int rc = -EAGAIN;
+
+	spin_lock_irqsave(sch->lock, flags);
+	if (!device_is_registered(&sch->dev))
+		goto out_unlock;
+	if (work_pending(&sch->todo_work))
+		goto out_unlock;
+	cdev = sch_get_cdev(sch);
+	if (cdev && work_pending(&cdev->private->todo_work))
+		goto out_unlock;
+	action = sch_get_action(sch);
+	CIO_MSG_EVENT(2, "event: sch 0.%x.%04x, process=%d, action=%d\n",
+		      sch->schid.ssid, sch->schid.sch_no, process,
+		      action);
+	/* Perform immediate actions while holding the lock. */
 	switch (action) {
-	case UNREGISTER:
-	case UNREGISTER_PROBE:
-		ccw_device_set_notoper(cdev);
-		/* Unregister device (will use subchannel lock). */
-		spin_unlock_irqrestore(sch->lock, flags);
-		css_sch_device_unregister(sch);
-		spin_lock_irqsave(sch->lock, flags);
-		break;
-	case REPROBE:
+	case IO_SCH_REPROBE:
+		/* Trigger device recognition. */
 		ccw_device_trigger_reprobe(cdev);
-		break;
-	case DISC:
+		rc = 0;
+		goto out_unlock;
+	case IO_SCH_VERIFY:
+		/* Trigger path verification. */
+		io_subchannel_verify(sch);
+		rc = 0;
+		goto out_unlock;
+	case IO_SCH_DISC:
+		ccw_device_set_disconnected(cdev);
+		rc = 0;
+		goto out_unlock;
+	case IO_SCH_ORPH_UNREG:
+	case IO_SCH_ORPH_ATTACH:
 		ccw_device_set_disconnected(cdev);
 		break;
+	case IO_SCH_UNREG_ATTACH:
+	case IO_SCH_UNREG:
+		if (cdev)
+			ccw_device_set_notoper(cdev);
+		break;
+	case IO_SCH_NOP:
+		rc = 0;
+		goto out_unlock;
 	default:
 		break;
 	}
 	spin_unlock_irqrestore(sch->lock, flags);
-	/* Probe if necessary. */
-	if (action == UNREGISTER_PROBE)
-		ret = css_probe_device(sch->schid);
+	/* All other actions require process context. */
+	if (!process)
+		goto out;
+	/* Handle attached ccw device. */
+	switch (action) {
+	case IO_SCH_ORPH_UNREG:
+	case IO_SCH_ORPH_ATTACH:
+		/* Move ccw device to orphanage. */
+		rc = ccw_device_move_to_orph(cdev);
+		if (rc)
+			goto out;
+		break;
+	case IO_SCH_UNREG_ATTACH:
+		/* Unregister ccw device. */
+		ccw_device_unregister(cdev);
+		break;
+	default:
+		break;
+	}
+	/* Handle subchannel. */
+	switch (action) {
+	case IO_SCH_ORPH_UNREG:
+	case IO_SCH_UNREG:
+		css_sch_device_unregister(sch);
+		break;
+	case IO_SCH_ORPH_ATTACH:
+	case IO_SCH_UNREG_ATTACH:
+	case IO_SCH_ATTACH:
+		dev_id.ssid = sch->schid.ssid;
+		dev_id.devno = sch->schib.pmcw.dev;
+		cdev = get_ccwdev_by_dev_id(&dev_id);
+		if (!cdev) {
+			sch_create_and_recog_new_device(sch);
+			break;
+		}
+		rc = ccw_device_move_to_sch(cdev, sch);
+		if (rc) {
+			/* Release reference from get_ccwdev_by_dev_id() */
+			put_device(&cdev->dev);
+			goto out;
+		}
+		spin_lock_irqsave(sch->lock, flags);
+		ccw_device_trigger_reprobe(cdev);
+		spin_unlock_irqrestore(sch->lock, flags);
+		/* Release reference from get_ccwdev_by_dev_id() */
+		put_device(&cdev->dev);
+		break;
+	default:
+		break;
+	}
+	return 0;
 
-	return ret;
+out_unlock:
+	spin_unlock_irqrestore(sch->lock, flags);
+out:
+	return rc;
 }
 
 #ifdef CONFIG_CCW_CONSOLE
@@ -1744,10 +1519,7 @@
 	sch->driver = &io_subchannel_driver;
 	/* Initialize the ccw_device structure. */
 	cdev->dev.parent= &sch->dev;
-	rc = io_subchannel_recog(cdev, sch);
-	if (rc)
-		return rc;
-
+	io_subchannel_recog(cdev, sch);
 	/* Now wait for the async. recognition to come to an end. */
 	spin_lock_irq(cdev->ccwlock);
 	while (!dev_fsm_final_state(cdev))
@@ -1763,7 +1535,7 @@
 	rc = 0;
 out_unlock:
 	spin_unlock_irq(cdev->ccwlock);
-	return 0;
+	return rc;
 }
 
 struct ccw_device *
@@ -1919,7 +1691,7 @@
 {
 	struct ccw_device *cdev = to_ccwdev(dev);
 
-	if (work_pending(&cdev->private->kick_work))
+	if (work_pending(&cdev->private->todo_work))
 		return -EAGAIN;
 	/* Fail while device is being set online/offline. */
 	if (atomic_read(&cdev->private->onoff))
@@ -2005,7 +1777,6 @@
 static void __ccw_device_pm_restore(struct ccw_device *cdev)
 {
 	struct subchannel *sch = to_subchannel(cdev->dev.parent);
-	int ret;
 
 	if (cio_is_console(sch->schid))
 		goto out;
@@ -2015,22 +1786,10 @@
 	 */
 	spin_lock_irq(sch->lock);
 	cdev->private->flags.resuming = 1;
-	ret = ccw_device_recognition(cdev);
+	ccw_device_recognition(cdev);
 	spin_unlock_irq(sch->lock);
-	if (ret) {
-		CIO_MSG_EVENT(0, "Couldn't start recognition for device "
-			      "0.%x.%04x (ret=%d)\n",
-			      cdev->private->dev_id.ssid,
-			      cdev->private->dev_id.devno, ret);
-		spin_lock_irq(sch->lock);
-		cdev->private->state = DEV_STATE_DISCONNECTED;
-		spin_unlock_irq(sch->lock);
-		/* notify driver after the resume cb */
-		goto out;
-	}
 	wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev) ||
 		   cdev->private->state == DEV_STATE_DISCONNECTED);
-
 out:
 	cdev->private->flags.resuming = 0;
 }
@@ -2040,7 +1799,7 @@
 	cdev->private->state = DEV_STATE_BOXED;
 	if (ccw_device_notify(cdev, CIO_BOXED))
 		return 0;
-	ccw_device_schedule_sch_unregister(cdev);
+	ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 	return -ENODEV;
 }
 
@@ -2049,7 +1808,7 @@
 	cdev->private->state = DEV_STATE_DISCONNECTED;
 	if (ccw_device_notify(cdev, CIO_GONE))
 		return 0;
-	ccw_device_schedule_sch_unregister(cdev);
+	ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 	return -ENODEV;
 }
 
@@ -2094,9 +1853,7 @@
 	/* check if the device type has changed */
 	if (!ccw_device_test_sense_data(cdev)) {
 		ccw_device_update_sense_data(cdev);
-		PREPARE_WORK(&cdev->private->kick_work,
-			     ccw_device_do_unbind_bind);
-		queue_work(ccw_device_work, &cdev->private->kick_work);
+		ccw_device_sched_todo(cdev, CDEV_TODO_REBIND);
 		ret = -ENODEV;
 		goto out_unlock;
 	}
@@ -2140,7 +1897,7 @@
 	goto out_restore;
 
 out_unreg_unlock:
-	ccw_device_schedule_sch_unregister(cdev);
+	ccw_device_sched_todo(cdev, CDEV_TODO_UNREG_EVAL);
 	ret = -ENODEV;
 out_unlock:
 	spin_unlock_irq(sch->lock);
@@ -2205,6 +1962,77 @@
 	return sch->schid;
 }
 
+static void ccw_device_todo(struct work_struct *work)
+{
+	struct ccw_device_private *priv;
+	struct ccw_device *cdev;
+	struct subchannel *sch;
+	enum cdev_todo todo;
+
+	priv = container_of(work, struct ccw_device_private, todo_work);
+	cdev = priv->cdev;
+	sch = to_subchannel(cdev->dev.parent);
+	/* Find out todo. */
+	spin_lock_irq(cdev->ccwlock);
+	todo = priv->todo;
+	priv->todo = CDEV_TODO_NOTHING;
+	CIO_MSG_EVENT(4, "cdev_todo: cdev=0.%x.%04x todo=%d\n",
+		      priv->dev_id.ssid, priv->dev_id.devno, todo);
+	spin_unlock_irq(cdev->ccwlock);
+	/* Perform todo. */
+	switch (todo) {
+	case CDEV_TODO_ENABLE_CMF:
+		cmf_reenable(cdev);
+		break;
+	case CDEV_TODO_REBIND:
+		ccw_device_do_unbind_bind(cdev);
+		break;
+	case CDEV_TODO_REGISTER:
+		io_subchannel_register(cdev);
+		break;
+	case CDEV_TODO_UNREG_EVAL:
+		if (!sch_is_pseudo_sch(sch))
+			css_schedule_eval(sch->schid);
+		/* fall-through */
+	case CDEV_TODO_UNREG:
+		if (sch_is_pseudo_sch(sch))
+			ccw_device_unregister(cdev);
+		else
+			ccw_device_call_sch_unregister(cdev);
+		break;
+	default:
+		break;
+	}
+	/* Release workqueue ref. */
+	put_device(&cdev->dev);
+}
+
+/**
+ * ccw_device_sched_todo - schedule ccw device operation
+ * @cdev: ccw device
+ * @todo: todo
+ *
+ * Schedule the operation identified by @todo to be performed on the slow path
+ * workqueue. Do nothing if another operation with higher priority is already
+ * scheduled. Needs to be called with ccwdev lock held.
+ */
+void ccw_device_sched_todo(struct ccw_device *cdev, enum cdev_todo todo)
+{
+	CIO_MSG_EVENT(4, "cdev_todo: sched cdev=0.%x.%04x todo=%d\n",
+		      cdev->private->dev_id.ssid, cdev->private->dev_id.devno,
+		      todo);
+	if (cdev->private->todo >= todo)
+		return;
+	cdev->private->todo = todo;
+	/* Get workqueue ref. */
+	if (!get_device(&cdev->dev))
+		return;
+	if (!queue_work(slow_path_wq, &cdev->private->todo_work)) {
+		/* Already queued, release workqueue ref. */
+		put_device(&cdev->dev);
+	}
+}
+
 MODULE_LICENSE("GPL");
 EXPORT_SYMBOL(ccw_device_set_online);
 EXPORT_SYMBOL(ccw_device_set_offline);
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index 246c648..bcfe13e 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -21,7 +21,6 @@
 	DEV_STATE_DISBAND_PGID,
 	DEV_STATE_BOXED,
 	/* states to wait for i/o completion before doing something */
-	DEV_STATE_CLEAR_VERIFY,
 	DEV_STATE_TIMEOUT_KILL,
 	DEV_STATE_QUIESCE,
 	/* special states for devices gone not operational */
@@ -29,6 +28,7 @@
 	DEV_STATE_DISCONNECTED_SENSE_ID,
 	DEV_STATE_CMFCHANGE,
 	DEV_STATE_CMFUPDATE,
+	DEV_STATE_STEAL_LOCK,
 	/* last element! */
 	NR_DEV_STATES
 };
@@ -81,17 +81,16 @@
 
 int ccw_device_cancel_halt_clear(struct ccw_device *);
 
-void ccw_device_do_unbind_bind(struct work_struct *);
-void ccw_device_move_to_orphanage(struct work_struct *);
 int ccw_device_is_orphan(struct ccw_device *);
 
-int ccw_device_recognition(struct ccw_device *);
+void ccw_device_recognition(struct ccw_device *);
 int ccw_device_online(struct ccw_device *);
 int ccw_device_offline(struct ccw_device *);
 void ccw_device_update_sense_data(struct ccw_device *);
 int ccw_device_test_sense_data(struct ccw_device *);
 void ccw_device_schedule_sch_unregister(struct ccw_device *);
 int ccw_purge_blacklisted(void);
+void ccw_device_sched_todo(struct ccw_device *cdev, enum cdev_todo todo);
 
 /* Function prototypes for device status and basic sense stuff. */
 void ccw_device_accumulate_irb(struct ccw_device *, struct irb *);
@@ -99,24 +98,28 @@
 int ccw_device_accumulate_and_sense(struct ccw_device *, struct irb *);
 int ccw_device_do_sense(struct ccw_device *, struct irb *);
 
+/* Function prototype for internal request handling. */
+int lpm_adjust(int lpm, int mask);
+void ccw_request_start(struct ccw_device *);
+int ccw_request_cancel(struct ccw_device *cdev);
+void ccw_request_handler(struct ccw_device *cdev);
+void ccw_request_timeout(struct ccw_device *cdev);
+void ccw_request_notoper(struct ccw_device *cdev);
+
 /* Function prototypes for sense id stuff. */
 void ccw_device_sense_id_start(struct ccw_device *);
-void ccw_device_sense_id_irq(struct ccw_device *, enum dev_event);
 void ccw_device_sense_id_done(struct ccw_device *, int);
 
 /* Function prototypes for path grouping stuff. */
-void ccw_device_sense_pgid_start(struct ccw_device *);
-void ccw_device_sense_pgid_irq(struct ccw_device *, enum dev_event);
-void ccw_device_sense_pgid_done(struct ccw_device *, int);
-
 void ccw_device_verify_start(struct ccw_device *);
-void ccw_device_verify_irq(struct ccw_device *, enum dev_event);
 void ccw_device_verify_done(struct ccw_device *, int);
 
 void ccw_device_disband_start(struct ccw_device *);
-void ccw_device_disband_irq(struct ccw_device *, enum dev_event);
 void ccw_device_disband_done(struct ccw_device *, int);
 
+void ccw_device_stlck_start(struct ccw_device *, void *, void *, void *);
+void ccw_device_stlck_done(struct ccw_device *, void *, int);
+
 int ccw_device_call_handler(struct ccw_device *);
 
 int ccw_device_stlck(struct ccw_device *);
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index b9613d7..ae76065 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -229,8 +229,8 @@
 
 	sch = to_subchannel(cdev->dev.parent);
 
-	ccw_device_set_timeout(cdev, 0);
-	cio_disable_subchannel(sch);
+	if (cio_disable_subchannel(sch))
+		state = DEV_STATE_NOT_OPER;
 	/*
 	 * Now that we tried recognition, we have performed device selection
 	 * through ssch() and the path information is up to date.
@@ -263,22 +263,10 @@
 	}
 	switch (state) {
 	case DEV_STATE_NOT_OPER:
-		CIO_MSG_EVENT(2, "SenseID : unknown device %04x on "
-			      "subchannel 0.%x.%04x\n",
-			      cdev->private->dev_id.devno,
-			      sch->schid.ssid, sch->schid.sch_no);
 		break;
 	case DEV_STATE_OFFLINE:
 		if (!cdev->online) {
 			ccw_device_update_sense_data(cdev);
-			/* Issue device info message. */
-			CIO_MSG_EVENT(4, "SenseID : device 0.%x.%04x reports: "
-				      "CU  Type/Mod = %04X/%02X, Dev Type/Mod "
-				      "= %04X/%02X\n",
-				      cdev->private->dev_id.ssid,
-				      cdev->private->dev_id.devno,
-				      cdev->id.cu_type, cdev->id.cu_model,
-				      cdev->id.dev_type, cdev->id.dev_model);
 			break;
 		}
 		cdev->private->state = DEV_STATE_OFFLINE;
@@ -289,16 +277,10 @@
 			wake_up(&cdev->private->wait_q);
 		} else {
 			ccw_device_update_sense_data(cdev);
-			PREPARE_WORK(&cdev->private->kick_work,
-				     ccw_device_do_unbind_bind);
-			queue_work(ccw_device_work, &cdev->private->kick_work);
+			ccw_device_sched_todo(cdev, CDEV_TODO_REBIND);
 		}
 		return;
 	case DEV_STATE_BOXED:
-		CIO_MSG_EVENT(0, "SenseID : boxed device %04x on "
-			      " subchannel 0.%x.%04x\n",
-			      cdev->private->dev_id.devno,
-			      sch->schid.ssid, sch->schid.sch_no);
 		if (cdev->id.cu_type != 0) { /* device was recognized before */
 			cdev->private->flags.recog_done = 1;
 			cdev->private->state = DEV_STATE_BOXED;
@@ -343,28 +325,16 @@
 	return cdev->drv->notify ? cdev->drv->notify(cdev, event) : 0;
 }
 
-static void cmf_reenable_delayed(struct work_struct *work)
-{
-	struct ccw_device_private *priv;
-	struct ccw_device *cdev;
-
-	priv = container_of(work, struct ccw_device_private, kick_work);
-	cdev = priv->cdev;
-	cmf_reenable(cdev);
-}
-
 static void ccw_device_oper_notify(struct ccw_device *cdev)
 {
 	if (ccw_device_notify(cdev, CIO_OPER)) {
 		/* Reenable channel measurements, if needed. */
-		PREPARE_WORK(&cdev->private->kick_work, cmf_reenable_delayed);
-		queue_work(ccw_device_work, &cdev->private->kick_work);
+		ccw_device_sched_todo(cdev, CDEV_TODO_ENABLE_CMF);
 		return;
 	}
 	/* Driver doesn't want device back. */
 	ccw_device_set_notoper(cdev);
-	PREPARE_WORK(&cdev->private->kick_work, ccw_device_do_unbind_bind);
-	queue_work(ccw_device_work, &cdev->private->kick_work);
+	ccw_device_sched_todo(cdev, CDEV_TODO_REBIND);
 }
 
 /*
@@ -392,14 +362,14 @@
 		CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n",
 			      cdev->private->dev_id.devno, sch->schid.sch_no);
 		if (cdev->online && !ccw_device_notify(cdev, CIO_BOXED))
-			ccw_device_schedule_sch_unregister(cdev);
+			ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 		cdev->private->flags.donotify = 0;
 		break;
 	case DEV_STATE_NOT_OPER:
 		CIO_MSG_EVENT(0, "Device %04x gone on subchannel %04x\n",
 			      cdev->private->dev_id.devno, sch->schid.sch_no);
 		if (!ccw_device_notify(cdev, CIO_GONE))
-			ccw_device_schedule_sch_unregister(cdev);
+			ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 		else
 			ccw_device_set_disconnected(cdev);
 		cdev->private->flags.donotify = 0;
@@ -409,7 +379,7 @@
 			      "%04x\n", cdev->private->dev_id.devno,
 			      sch->schid.sch_no);
 		if (!ccw_device_notify(cdev, CIO_NO_PATH))
-			ccw_device_schedule_sch_unregister(cdev);
+			ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 		else
 			ccw_device_set_disconnected(cdev);
 		cdev->private->flags.donotify = 0;
@@ -425,107 +395,12 @@
 	wake_up(&cdev->private->wait_q);
 }
 
-static int cmp_pgid(struct pgid *p1, struct pgid *p2)
-{
-	char *c1;
-	char *c2;
-
-	c1 = (char *)p1;
-	c2 = (char *)p2;
-
-	return memcmp(c1 + 1, c2 + 1, sizeof(struct pgid) - 1);
-}
-
-static void __ccw_device_get_common_pgid(struct ccw_device *cdev)
-{
-	int i;
-	int last;
-
-	last = 0;
-	for (i = 0; i < 8; i++) {
-		if (cdev->private->pgid[i].inf.ps.state1 == SNID_STATE1_RESET)
-			/* No PGID yet */
-			continue;
-		if (cdev->private->pgid[last].inf.ps.state1 ==
-		    SNID_STATE1_RESET) {
-			/* First non-zero PGID */
-			last = i;
-			continue;
-		}
-		if (cmp_pgid(&cdev->private->pgid[i],
-			     &cdev->private->pgid[last]) == 0)
-			/* Non-conflicting PGIDs */
-			continue;
-
-		/* PGID mismatch, can't pathgroup. */
-		CIO_MSG_EVENT(0, "SNID - pgid mismatch for device "
-			      "0.%x.%04x, can't pathgroup\n",
-			      cdev->private->dev_id.ssid,
-			      cdev->private->dev_id.devno);
-		cdev->private->options.pgroup = 0;
-		return;
-	}
-	if (cdev->private->pgid[last].inf.ps.state1 ==
-	    SNID_STATE1_RESET)
-		/* No previous pgid found */
-		memcpy(&cdev->private->pgid[0],
-		       &channel_subsystems[0]->global_pgid,
-		       sizeof(struct pgid));
-	else
-		/* Use existing pgid */
-		memcpy(&cdev->private->pgid[0], &cdev->private->pgid[last],
-		       sizeof(struct pgid));
-}
-
-/*
- * Function called from device_pgid.c after sense path ground has completed.
- */
-void
-ccw_device_sense_pgid_done(struct ccw_device *cdev, int err)
-{
-	struct subchannel *sch;
-
-	sch = to_subchannel(cdev->dev.parent);
-	switch (err) {
-	case -EOPNOTSUPP: /* path grouping not supported, use nop instead. */
-		cdev->private->options.pgroup = 0;
-		break;
-	case 0: /* success */
-	case -EACCES: /* partial success, some paths not operational */
-		/* Check if all pgids are equal or 0. */
-		__ccw_device_get_common_pgid(cdev);
-		break;
-	case -ETIME:		/* Sense path group id stopped by timeout. */
-	case -EUSERS:		/* device is reserved for someone else. */
-		ccw_device_done(cdev, DEV_STATE_BOXED);
-		return;
-	default:
-		ccw_device_done(cdev, DEV_STATE_NOT_OPER);
-		return;
-	}
-	/* Start Path Group verification. */
-	cdev->private->state = DEV_STATE_VERIFY;
-	cdev->private->flags.doverify = 0;
-	ccw_device_verify_start(cdev);
-}
-
 /*
  * Start device recognition.
  */
-int
-ccw_device_recognition(struct ccw_device *cdev)
+void ccw_device_recognition(struct ccw_device *cdev)
 {
-	struct subchannel *sch;
-	int ret;
-
-	sch = to_subchannel(cdev->dev.parent);
-	ret = cio_enable_subchannel(sch, (u32)(addr_t)sch);
-	if (ret != 0)
-		/* Couldn't enable the subchannel for i/o. Sick device. */
-		return ret;
-
-	/* After 60s the device recognition is considered to have failed. */
-	ccw_device_set_timeout(cdev, 60*HZ);
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
 
 	/*
 	 * We used to start here with a sense pgid to find out whether a device
@@ -537,32 +412,33 @@
 	 */
 	cdev->private->flags.recog_done = 0;
 	cdev->private->state = DEV_STATE_SENSE_ID;
+	if (cio_enable_subchannel(sch, (u32) (addr_t) sch)) {
+		ccw_device_recog_done(cdev, DEV_STATE_NOT_OPER);
+		return;
+	}
 	ccw_device_sense_id_start(cdev);
-	return 0;
 }
 
 /*
- * Handle timeout in device recognition.
+ * Handle events for states that use the ccw request infrastructure.
  */
-static void
-ccw_device_recog_timeout(struct ccw_device *cdev, enum dev_event dev_event)
+static void ccw_device_request_event(struct ccw_device *cdev, enum dev_event e)
 {
-	int ret;
-
-	ret = ccw_device_cancel_halt_clear(cdev);
-	switch (ret) {
-	case 0:
-		ccw_device_recog_done(cdev, DEV_STATE_BOXED);
+	switch (e) {
+	case DEV_EVENT_NOTOPER:
+		ccw_request_notoper(cdev);
 		break;
-	case -ENODEV:
-		ccw_device_recog_done(cdev, DEV_STATE_NOT_OPER);
+	case DEV_EVENT_INTERRUPT:
+		ccw_request_handler(cdev);
+		break;
+	case DEV_EVENT_TIMEOUT:
+		ccw_request_timeout(cdev);
 		break;
 	default:
-		ccw_device_set_timeout(cdev, 3*HZ);
+		break;
 	}
 }
 
-
 void
 ccw_device_verify_done(struct ccw_device *cdev, int err)
 {
@@ -571,21 +447,18 @@
 	sch = to_subchannel(cdev->dev.parent);
 	/* Update schib - pom may have changed. */
 	if (cio_update_schib(sch)) {
-		cdev->private->flags.donotify = 0;
-		ccw_device_done(cdev, DEV_STATE_NOT_OPER);
-		return;
+		err = -ENODEV;
+		goto callback;
 	}
 	/* Update lpm with verified path mask. */
 	sch->lpm = sch->vpm;
 	/* Repeat path verification? */
 	if (cdev->private->flags.doverify) {
-		cdev->private->flags.doverify = 0;
 		ccw_device_verify_start(cdev);
 		return;
 	}
+callback:
 	switch (err) {
-	case -EOPNOTSUPP: /* path grouping not supported, just set online. */
-		cdev->private->options.pgroup = 0;
 	case 0:
 		ccw_device_done(cdev, DEV_STATE_ONLINE);
 		/* Deliver fake irb to device driver, if needed. */
@@ -604,18 +477,20 @@
 		}
 		break;
 	case -ETIME:
+	case -EUSERS:
 		/* Reset oper notify indication after verify error. */
 		cdev->private->flags.donotify = 0;
 		ccw_device_done(cdev, DEV_STATE_BOXED);
 		break;
+	case -EACCES:
+		/* Reset oper notify indication after verify error. */
+		cdev->private->flags.donotify = 0;
+		ccw_device_done(cdev, DEV_STATE_DISCONNECTED);
+		break;
 	default:
 		/* Reset oper notify indication after verify error. */
 		cdev->private->flags.donotify = 0;
-		if (cdev->online) {
-			ccw_device_set_timeout(cdev, 0);
-			dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
-		} else
-			ccw_device_done(cdev, DEV_STATE_NOT_OPER);
+		ccw_device_done(cdev, DEV_STATE_NOT_OPER);
 		break;
 	}
 }
@@ -640,17 +515,9 @@
 			dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
 		return ret;
 	}
-	/* Do we want to do path grouping? */
-	if (!cdev->private->options.pgroup) {
-		/* Start initial path verification. */
-		cdev->private->state = DEV_STATE_VERIFY;
-		cdev->private->flags.doverify = 0;
-		ccw_device_verify_start(cdev);
-		return 0;
-	}
-	/* Do a SensePGID first. */
-	cdev->private->state = DEV_STATE_SENSE_PGID;
-	ccw_device_sense_pgid_start(cdev);
+	/* Start initial path verification. */
+	cdev->private->state = DEV_STATE_VERIFY;
+	ccw_device_verify_start(cdev);
 	return 0;
 }
 
@@ -666,7 +533,6 @@
 		break;
 	default:
 		cdev->private->flags.donotify = 0;
-		dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
 		ccw_device_done(cdev, DEV_STATE_NOT_OPER);
 		break;
 	}
@@ -703,7 +569,7 @@
 	if (cdev->private->state != DEV_STATE_ONLINE)
 		return -EINVAL;
 	/* Are we doing path grouping? */
-	if (!cdev->private->options.pgroup) {
+	if (!cdev->private->flags.pgroup) {
 		/* No, set state offline immediately. */
 		ccw_device_done(cdev, DEV_STATE_OFFLINE);
 		return 0;
@@ -715,43 +581,13 @@
 }
 
 /*
- * Handle timeout in device online/offline process.
- */
-static void
-ccw_device_onoff_timeout(struct ccw_device *cdev, enum dev_event dev_event)
-{
-	int ret;
-
-	ret = ccw_device_cancel_halt_clear(cdev);
-	switch (ret) {
-	case 0:
-		ccw_device_done(cdev, DEV_STATE_BOXED);
-		break;
-	case -ENODEV:
-		ccw_device_done(cdev, DEV_STATE_NOT_OPER);
-		break;
-	default:
-		ccw_device_set_timeout(cdev, 3*HZ);
-	}
-}
-
-/*
- * Handle not oper event in device recognition.
- */
-static void
-ccw_device_recog_notoper(struct ccw_device *cdev, enum dev_event dev_event)
-{
-	ccw_device_recog_done(cdev, DEV_STATE_NOT_OPER);
-}
-
-/*
  * Handle not operational event in non-special state.
  */
 static void ccw_device_generic_notoper(struct ccw_device *cdev,
 				       enum dev_event dev_event)
 {
 	if (!ccw_device_notify(cdev, CIO_GONE))
-		ccw_device_schedule_sch_unregister(cdev);
+		ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 	else
 		ccw_device_set_disconnected(cdev);
 }
@@ -802,11 +638,27 @@
 	}
 	/* Device is idle, we can do the path verification. */
 	cdev->private->state = DEV_STATE_VERIFY;
-	cdev->private->flags.doverify = 0;
 	ccw_device_verify_start(cdev);
 }
 
 /*
+ * Handle path verification event in boxed state.
+ */
+static void ccw_device_boxed_verify(struct ccw_device *cdev,
+				    enum dev_event dev_event)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+
+	if (cdev->online) {
+		if (cio_enable_subchannel(sch, (u32) (addr_t) sch))
+			ccw_device_done(cdev, DEV_STATE_NOT_OPER);
+		else
+			ccw_device_online_verify(cdev, dev_event);
+	} else
+		css_schedule_eval(sch->schid);
+}
+
+/*
  * Got an interrupt for a normal io (state online).
  */
 static void
@@ -904,12 +756,6 @@
 	 */
 	if (scsw_fctl(&irb->scsw) &
 	    (SCSW_FCTL_CLEAR_FUNC | SCSW_FCTL_HALT_FUNC)) {
-		/* Retry Basic Sense if requested. */
-		if (cdev->private->flags.intretry) {
-			cdev->private->flags.intretry = 0;
-			ccw_device_do_sense(cdev, irb);
-			return;
-		}
 		cdev->private->flags.dosense = 0;
 		memset(&cdev->private->irb, 0, sizeof(struct irb));
 		ccw_device_accumulate_irb(cdev, irb);
@@ -933,21 +779,6 @@
 }
 
 static void
-ccw_device_clear_verify(struct ccw_device *cdev, enum dev_event dev_event)
-{
-	struct irb *irb;
-
-	irb = (struct irb *) __LC_IRB;
-	/* Accumulate status. We don't do basic sense. */
-	ccw_device_accumulate_irb(cdev, irb);
-	/* Remember to clear irb to avoid residuals. */
-	memset(&cdev->private->irb, 0, sizeof(struct irb));
-	/* Try to start delayed device verification. */
-	ccw_device_online_verify(cdev, 0);
-	/* Note: Don't call handler for cio initiated clear! */
-}
-
-static void
 ccw_device_killing_irq(struct ccw_device *cdev, enum dev_event dev_event)
 {
 	struct subchannel *sch;
@@ -1004,32 +835,6 @@
 }
 
 static void
-ccw_device_stlck_done(struct ccw_device *cdev, enum dev_event dev_event)
-{
-	struct irb *irb;
-
-	switch (dev_event) {
-	case DEV_EVENT_INTERRUPT:
-		irb = (struct irb *) __LC_IRB;
-		/* Check for unsolicited interrupt. */
-		if ((scsw_stctl(&irb->scsw) ==
-		     (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) &&
-		    (!scsw_cc(&irb->scsw)))
-			/* FIXME: we should restart stlck here, but this
-			 * is extremely unlikely ... */
-			goto out_wakeup;
-
-		ccw_device_accumulate_irb(cdev, irb);
-		/* We don't care about basic sense etc. */
-		break;
-	default: /* timeout */
-		break;
-	}
-out_wakeup:
-	wake_up(&cdev->private->wait_q);
-}
-
-static void
 ccw_device_start_id(struct ccw_device *cdev, enum dev_event dev_event)
 {
 	struct subchannel *sch;
@@ -1038,10 +843,6 @@
 	if (cio_enable_subchannel(sch, (u32)(addr_t)sch) != 0)
 		/* Couldn't enable the subchannel for i/o. Sick device. */
 		return;
-
-	/* After 60s the device recognition is considered to have failed. */
-	ccw_device_set_timeout(cdev, 60*HZ);
-
 	cdev->private->state = DEV_STATE_DISCONNECTED_SENSE_ID;
 	ccw_device_sense_id_start(cdev);
 }
@@ -1072,22 +873,20 @@
 
 	/* We should also udate ssd info, but this has to wait. */
 	/* Check if this is another device which appeared on the same sch. */
-	if (sch->schib.pmcw.dev != cdev->private->dev_id.devno) {
-		PREPARE_WORK(&cdev->private->kick_work,
-			     ccw_device_move_to_orphanage);
-		queue_work(slow_path_wq, &cdev->private->kick_work);
-	} else
+	if (sch->schib.pmcw.dev != cdev->private->dev_id.devno)
+		css_schedule_eval(sch->schid);
+	else
 		ccw_device_start_id(cdev, 0);
 }
 
-static void
-ccw_device_offline_irq(struct ccw_device *cdev, enum dev_event dev_event)
+static void ccw_device_disabled_irq(struct ccw_device *cdev,
+				    enum dev_event dev_event)
 {
 	struct subchannel *sch;
 
 	sch = to_subchannel(cdev->dev.parent);
 	/*
-	 * An interrupt in state offline means a previous disable was not
+	 * An interrupt in a disabled state means a previous disable was not
 	 * successful - should not happen, but we try to disable again.
 	 */
 	cio_disable_subchannel(sch);
@@ -1113,10 +912,7 @@
 ccw_device_quiesce_done(struct ccw_device *cdev, enum dev_event dev_event)
 {
 	ccw_device_set_timeout(cdev, 0);
-	if (dev_event == DEV_EVENT_NOTOPER)
-		cdev->private->state = DEV_STATE_NOT_OPER;
-	else
-		cdev->private->state = DEV_STATE_OFFLINE;
+	cdev->private->state = DEV_STATE_NOT_OPER;
 	wake_up(&cdev->private->wait_q);
 }
 
@@ -1126,17 +922,11 @@
 	int ret;
 
 	ret = ccw_device_cancel_halt_clear(cdev);
-	switch (ret) {
-	case 0:
-		cdev->private->state = DEV_STATE_OFFLINE;
-		wake_up(&cdev->private->wait_q);
-		break;
-	case -ENODEV:
+	if (ret == -EBUSY) {
+		ccw_device_set_timeout(cdev, HZ/10);
+	} else {
 		cdev->private->state = DEV_STATE_NOT_OPER;
 		wake_up(&cdev->private->wait_q);
-		break;
-	default:
-		ccw_device_set_timeout(cdev, HZ/10);
 	}
 }
 
@@ -1150,50 +940,37 @@
 }
 
 /*
- * Bug operation action. 
- */
-static void
-ccw_device_bug(struct ccw_device *cdev, enum dev_event dev_event)
-{
-	CIO_MSG_EVENT(0, "Internal state [%i][%i] not handled for device "
-		      "0.%x.%04x\n", cdev->private->state, dev_event,
-		      cdev->private->dev_id.ssid,
-		      cdev->private->dev_id.devno);
-	BUG();
-}
-
-/*
  * device statemachine
  */
 fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = {
 	[DEV_STATE_NOT_OPER] = {
 		[DEV_EVENT_NOTOPER]	= ccw_device_nop,
-		[DEV_EVENT_INTERRUPT]	= ccw_device_bug,
+		[DEV_EVENT_INTERRUPT]	= ccw_device_disabled_irq,
 		[DEV_EVENT_TIMEOUT]	= ccw_device_nop,
 		[DEV_EVENT_VERIFY]	= ccw_device_nop,
 	},
 	[DEV_STATE_SENSE_PGID] = {
-		[DEV_EVENT_NOTOPER]	= ccw_device_generic_notoper,
-		[DEV_EVENT_INTERRUPT]	= ccw_device_sense_pgid_irq,
-		[DEV_EVENT_TIMEOUT]	= ccw_device_onoff_timeout,
+		[DEV_EVENT_NOTOPER]	= ccw_device_request_event,
+		[DEV_EVENT_INTERRUPT]	= ccw_device_request_event,
+		[DEV_EVENT_TIMEOUT]	= ccw_device_request_event,
 		[DEV_EVENT_VERIFY]	= ccw_device_nop,
 	},
 	[DEV_STATE_SENSE_ID] = {
-		[DEV_EVENT_NOTOPER]	= ccw_device_recog_notoper,
-		[DEV_EVENT_INTERRUPT]	= ccw_device_sense_id_irq,
-		[DEV_EVENT_TIMEOUT]	= ccw_device_recog_timeout,
+		[DEV_EVENT_NOTOPER]	= ccw_device_request_event,
+		[DEV_EVENT_INTERRUPT]	= ccw_device_request_event,
+		[DEV_EVENT_TIMEOUT]	= ccw_device_request_event,
 		[DEV_EVENT_VERIFY]	= ccw_device_nop,
 	},
 	[DEV_STATE_OFFLINE] = {
 		[DEV_EVENT_NOTOPER]	= ccw_device_generic_notoper,
-		[DEV_EVENT_INTERRUPT]	= ccw_device_offline_irq,
+		[DEV_EVENT_INTERRUPT]	= ccw_device_disabled_irq,
 		[DEV_EVENT_TIMEOUT]	= ccw_device_nop,
 		[DEV_EVENT_VERIFY]	= ccw_device_offline_verify,
 	},
 	[DEV_STATE_VERIFY] = {
-		[DEV_EVENT_NOTOPER]	= ccw_device_generic_notoper,
-		[DEV_EVENT_INTERRUPT]	= ccw_device_verify_irq,
-		[DEV_EVENT_TIMEOUT]	= ccw_device_onoff_timeout,
+		[DEV_EVENT_NOTOPER]	= ccw_device_request_event,
+		[DEV_EVENT_INTERRUPT]	= ccw_device_request_event,
+		[DEV_EVENT_TIMEOUT]	= ccw_device_request_event,
 		[DEV_EVENT_VERIFY]	= ccw_device_delay_verify,
 	},
 	[DEV_STATE_ONLINE] = {
@@ -1209,24 +986,18 @@
 		[DEV_EVENT_VERIFY]	= ccw_device_online_verify,
 	},
 	[DEV_STATE_DISBAND_PGID] = {
-		[DEV_EVENT_NOTOPER]	= ccw_device_generic_notoper,
-		[DEV_EVENT_INTERRUPT]	= ccw_device_disband_irq,
-		[DEV_EVENT_TIMEOUT]	= ccw_device_onoff_timeout,
+		[DEV_EVENT_NOTOPER]	= ccw_device_request_event,
+		[DEV_EVENT_INTERRUPT]	= ccw_device_request_event,
+		[DEV_EVENT_TIMEOUT]	= ccw_device_request_event,
 		[DEV_EVENT_VERIFY]	= ccw_device_nop,
 	},
 	[DEV_STATE_BOXED] = {
 		[DEV_EVENT_NOTOPER]	= ccw_device_generic_notoper,
-		[DEV_EVENT_INTERRUPT]	= ccw_device_stlck_done,
-		[DEV_EVENT_TIMEOUT]	= ccw_device_stlck_done,
-		[DEV_EVENT_VERIFY]	= ccw_device_nop,
+		[DEV_EVENT_INTERRUPT]	= ccw_device_nop,
+		[DEV_EVENT_TIMEOUT]	= ccw_device_nop,
+		[DEV_EVENT_VERIFY]	= ccw_device_boxed_verify,
 	},
 	/* states to wait for i/o completion before doing something */
-	[DEV_STATE_CLEAR_VERIFY] = {
-		[DEV_EVENT_NOTOPER]	= ccw_device_generic_notoper,
-		[DEV_EVENT_INTERRUPT]   = ccw_device_clear_verify,
-		[DEV_EVENT_TIMEOUT]	= ccw_device_nop,
-		[DEV_EVENT_VERIFY]	= ccw_device_nop,
-	},
 	[DEV_STATE_TIMEOUT_KILL] = {
 		[DEV_EVENT_NOTOPER]	= ccw_device_generic_notoper,
 		[DEV_EVENT_INTERRUPT]	= ccw_device_killing_irq,
@@ -1243,13 +1014,13 @@
 	[DEV_STATE_DISCONNECTED] = {
 		[DEV_EVENT_NOTOPER]	= ccw_device_nop,
 		[DEV_EVENT_INTERRUPT]	= ccw_device_start_id,
-		[DEV_EVENT_TIMEOUT]	= ccw_device_bug,
+		[DEV_EVENT_TIMEOUT]	= ccw_device_nop,
 		[DEV_EVENT_VERIFY]	= ccw_device_start_id,
 	},
 	[DEV_STATE_DISCONNECTED_SENSE_ID] = {
-		[DEV_EVENT_NOTOPER]	= ccw_device_recog_notoper,
-		[DEV_EVENT_INTERRUPT]	= ccw_device_sense_id_irq,
-		[DEV_EVENT_TIMEOUT]	= ccw_device_recog_timeout,
+		[DEV_EVENT_NOTOPER]	= ccw_device_request_event,
+		[DEV_EVENT_INTERRUPT]	= ccw_device_request_event,
+		[DEV_EVENT_TIMEOUT]	= ccw_device_request_event,
 		[DEV_EVENT_VERIFY]	= ccw_device_nop,
 	},
 	[DEV_STATE_CMFCHANGE] = {
@@ -1264,6 +1035,12 @@
 		[DEV_EVENT_TIMEOUT]	= ccw_device_update_cmfblock,
 		[DEV_EVENT_VERIFY]	= ccw_device_update_cmfblock,
 	},
+	[DEV_STATE_STEAL_LOCK] = {
+		[DEV_EVENT_NOTOPER]	= ccw_device_request_event,
+		[DEV_EVENT_INTERRUPT]	= ccw_device_request_event,
+		[DEV_EVENT_TIMEOUT]	= ccw_device_request_event,
+		[DEV_EVENT_VERIFY]	= ccw_device_nop,
+	},
 };
 
 EXPORT_SYMBOL_GPL(ccw_device_set_timeout);
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c
index 1bdaa61..78a0b43 100644
--- a/drivers/s390/cio/device_id.c
+++ b/drivers/s390/cio/device_id.c
@@ -1,40 +1,39 @@
 /*
- * drivers/s390/cio/device_id.c
+ *  CCW device SENSE ID I/O handling.
  *
- *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
- *			 IBM Corporation
- *    Author(s): Cornelia Huck (cornelia.huck@de.ibm.com)
- *		 Martin Schwidefsky (schwidefsky@de.ibm.com)
- *
- * Sense ID functions.
+ *    Copyright IBM Corp. 2002,2009
+ *    Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
+ *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
+ *		 Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
  */
 
-#include <linux/module.h>
-#include <linux/init.h>
 #include <linux/kernel.h>
-
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/errno.h>
 #include <asm/ccwdev.h>
-#include <asm/delay.h>
+#include <asm/setup.h>
 #include <asm/cio.h>
-#include <asm/lowcore.h>
 #include <asm/diag.h>
 
 #include "cio.h"
 #include "cio_debug.h"
-#include "css.h"
 #include "device.h"
-#include "ioasm.h"
 #include "io_sch.h"
 
+#define SENSE_ID_RETRIES	256
+#define SENSE_ID_TIMEOUT	(10 * HZ)
+#define SENSE_ID_MIN_LEN	4
+#define SENSE_ID_BASIC_LEN	7
+
 /**
- * vm_vdev_to_cu_type - Convert vm virtual device into control unit type
- *			for certain devices.
- * @class: virtual device class
- * @type: virtual device type
+ * diag210_to_senseid - convert diag 0x210 data to sense id information
+ * @senseid: sense id
+ * @diag: diag 0x210 data
  *
- * Returns control unit type if a match was made or %0xffff otherwise.
+ * Return 0 on success, non-zero otherwise.
  */
-static int vm_vdev_to_cu_type(int class, int type)
+static int diag210_to_senseid(struct senseid *senseid, struct diag210 *diag)
 {
 	static struct {
 		int class, type, cu_type;
@@ -71,253 +70,153 @@
 	};
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(vm_devices); i++)
-		if (class == vm_devices[i].class && type == vm_devices[i].type)
-			return vm_devices[i].cu_type;
-
-	return 0xffff;
-}
-
-/**
- * diag_get_dev_info - retrieve device information via DIAG X'210'
- * @devno: device number
- * @ps: pointer to sense ID data area
- *
- * Returns zero on success, non-zero otherwise.
- */
-static int diag_get_dev_info(u16 devno, struct senseid *ps)
-{
-	struct diag210 diag_data;
-	int ccode;
-
-	CIO_TRACE_EVENT (4, "VMvdinf");
-
-	diag_data = (struct diag210) {
-		.vrdcdvno = devno,
-		.vrdclen = sizeof (diag_data),
-	};
-
-	ccode = diag210 (&diag_data);
-	if ((ccode == 0) || (ccode == 2)) {
-		ps->reserved = 0xff;
-
-		/* Special case for osa devices. */
-		if (diag_data.vrdcvcla == 0x02 && diag_data.vrdcvtyp == 0x20) {
-			ps->cu_type = 0x3088;
-			ps->cu_model = 0x60;
+	/* Special case for osa devices. */
+	if (diag->vrdcvcla == 0x02 && diag->vrdcvtyp == 0x20) {
+		senseid->cu_type = 0x3088;
+		senseid->cu_model = 0x60;
+		senseid->reserved = 0xff;
+		return 0;
+	}
+	for (i = 0; i < ARRAY_SIZE(vm_devices); i++) {
+		if (diag->vrdcvcla == vm_devices[i].class &&
+		    diag->vrdcvtyp == vm_devices[i].type) {
+			senseid->cu_type = vm_devices[i].cu_type;
+			senseid->reserved = 0xff;
 			return 0;
 		}
-		ps->cu_type = vm_vdev_to_cu_type(diag_data.vrdcvcla,
-						diag_data.vrdcvtyp);
-		if (ps->cu_type != 0xffff)
-			return 0;
 	}
 
-	CIO_MSG_EVENT(0, "DIAG X'210' for device %04X returned (cc = %d):"
-		      "vdev class : %02X, vdev type : %04X \n ...  "
-		      "rdev class : %02X, rdev type : %04X, "
-		      "rdev model: %02X\n",
-		      devno, ccode,
-		      diag_data.vrdcvcla, diag_data.vrdcvtyp,
-		      diag_data.vrdcrccl, diag_data.vrdccrty,
-		      diag_data.vrdccrmd);
-
 	return -ENODEV;
 }
 
-/*
- * Start Sense ID helper function.
- * Try to obtain the 'control unit'/'device type' information
- *  associated with the subchannel.
+/**
+ * diag_get_dev_info - retrieve device information via diag 0x210
+ * @cdev: ccw device
+ *
+ * Returns zero on success, non-zero otherwise.
  */
-static int
-__ccw_device_sense_id_start(struct ccw_device *cdev)
+static int diag210_get_dev_info(struct ccw_device *cdev)
 {
-	struct subchannel *sch;
-	struct ccw1 *ccw;
-	int ret;
+	struct ccw_dev_id *dev_id = &cdev->private->dev_id;
+	struct senseid *senseid = &cdev->private->senseid;
+	struct diag210 diag_data;
+	int rc;
 
-	sch = to_subchannel(cdev->dev.parent);
-	/* Setup sense channel program. */
-	ccw = cdev->private->iccws;
-	ccw->cmd_code = CCW_CMD_SENSE_ID;
-	ccw->cda = (__u32) __pa (&cdev->private->senseid);
-	ccw->count = sizeof (struct senseid);
-	ccw->flags = CCW_FLAG_SLI;
+	if (dev_id->ssid != 0)
+		return -ENODEV;
+	memset(&diag_data, 0, sizeof(diag_data));
+	diag_data.vrdcdvno	= dev_id->devno;
+	diag_data.vrdclen	= sizeof(diag_data);
+	rc = diag210(&diag_data);
+	CIO_TRACE_EVENT(4, "diag210");
+	CIO_HEX_EVENT(4, &rc, sizeof(rc));
+	CIO_HEX_EVENT(4, &diag_data, sizeof(diag_data));
+	if (rc != 0 && rc != 2)
+		goto err_failed;
+	if (diag210_to_senseid(senseid, &diag_data))
+		goto err_unknown;
+	return 0;
 
-	/* Reset device status. */
-	memset(&cdev->private->irb, 0, sizeof(struct irb));
-
-	/* Try on every path. */
-	ret = -ENODEV;
-	while (cdev->private->imask != 0) {
-		cdev->private->senseid.cu_type = 0xFFFF;
-		if ((sch->opm & cdev->private->imask) != 0 &&
-		    cdev->private->iretry > 0) {
-			cdev->private->iretry--;
-			/* Reset internal retry indication. */
-			cdev->private->flags.intretry = 0;
-			ret = cio_start (sch, cdev->private->iccws,
-					 cdev->private->imask);
-			/* ret is 0, -EBUSY, -EACCES or -ENODEV */
-			if (ret != -EACCES)
-				return ret;
-		}
-		cdev->private->imask >>= 1;
-		cdev->private->iretry = 5;
-	}
-	return ret;
-}
-
-void
-ccw_device_sense_id_start(struct ccw_device *cdev)
-{
-	int ret;
-
-	memset (&cdev->private->senseid, 0, sizeof (struct senseid));
-	cdev->private->imask = 0x80;
-	cdev->private->iretry = 5;
-	ret = __ccw_device_sense_id_start(cdev);
-	if (ret && ret != -EBUSY)
-		ccw_device_sense_id_done(cdev, ret);
+err_unknown:
+	CIO_MSG_EVENT(0, "snsid: device 0.%x.%04x: unknown diag210 data\n",
+		      dev_id->ssid, dev_id->devno);
+	return -ENODEV;
+err_failed:
+	CIO_MSG_EVENT(0, "snsid: device 0.%x.%04x: diag210 failed (rc=%d)\n",
+		      dev_id->ssid, dev_id->devno, rc);
+	return -ENODEV;
 }
 
 /*
- * Called from interrupt context to check if a valid answer
- * to Sense ID was received.
+ * Initialize SENSE ID data.
  */
-static int
-ccw_device_check_sense_id(struct ccw_device *cdev)
+static void snsid_init(struct ccw_device *cdev)
 {
-	struct subchannel *sch;
-	struct irb *irb;
+	cdev->private->flags.esid = 0;
+	memset(&cdev->private->senseid, 0, sizeof(cdev->private->senseid));
+	cdev->private->senseid.cu_type = 0xffff;
+}
 
-	sch = to_subchannel(cdev->dev.parent);
-	irb = &cdev->private->irb;
+/*
+ * Check for complete SENSE ID data.
+ */
+static int snsid_check(struct ccw_device *cdev, void *data)
+{
+	struct cmd_scsw *scsw = &cdev->private->irb.scsw.cmd;
+	int len = sizeof(struct senseid) - scsw->count;
 
-	/* Check the error cases. */
-	if (irb->scsw.cmd.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
-		/* Retry Sense ID if requested. */
-		if (cdev->private->flags.intretry) {
-			cdev->private->flags.intretry = 0;
-			return -EAGAIN;
-		}
-		return -ETIME;
-	}
-	if (irb->esw.esw0.erw.cons && (irb->ecw[0] & SNS0_CMD_REJECT)) {
-		/*
-		 * if the device doesn't support the SenseID
-		 *  command further retries wouldn't help ...
-		 * NB: We don't check here for intervention required like we
-		 *     did before, because tape devices with no tape inserted
-		 *     may present this status *in conjunction with* the
-		 *     sense id information. So, for intervention required,
-		 *     we use the "whack it until it talks" strategy...
-		 */
-		CIO_MSG_EVENT(0, "SenseID : device %04x on Subchannel "
-			      "0.%x.%04x reports cmd reject\n",
-			      cdev->private->dev_id.devno, sch->schid.ssid,
-			      sch->schid.sch_no);
+	/* Check for incomplete SENSE ID data. */
+	if (len < SENSE_ID_MIN_LEN)
+		goto out_restart;
+	if (cdev->private->senseid.cu_type == 0xffff)
+		goto out_restart;
+	/* Check for incompatible SENSE ID data. */
+	if (cdev->private->senseid.reserved != 0xff)
 		return -EOPNOTSUPP;
-	}
-	if (irb->esw.esw0.erw.cons) {
-		CIO_MSG_EVENT(2, "SenseID : UC on dev 0.%x.%04x, "
-			      "lpum %02X, cnt %02d, sns :"
-			      " %02X%02X%02X%02X %02X%02X%02X%02X ...\n",
-			      cdev->private->dev_id.ssid,
-			      cdev->private->dev_id.devno,
-			      irb->esw.esw0.sublog.lpum,
-			      irb->esw.esw0.erw.scnt,
-			      irb->ecw[0], irb->ecw[1],
-			      irb->ecw[2], irb->ecw[3],
-			      irb->ecw[4], irb->ecw[5],
-			      irb->ecw[6], irb->ecw[7]);
-		return -EAGAIN;
-	}
-	if (irb->scsw.cmd.cc == 3) {
-		u8 lpm;
+	/* Check for extended-identification information. */
+	if (len > SENSE_ID_BASIC_LEN)
+		cdev->private->flags.esid = 1;
+	return 0;
 
-		lpm = to_io_private(sch)->orb.cmd.lpm;
-		if ((lpm & sch->schib.pmcw.pim & sch->schib.pmcw.pam) != 0)
-			CIO_MSG_EVENT(4, "SenseID : path %02X for device %04x "
-				      "on subchannel 0.%x.%04x is "
-				      "'not operational'\n", lpm,
-				      cdev->private->dev_id.devno,
-				      sch->schid.ssid, sch->schid.sch_no);
-		return -EACCES;
-	}
-
-	/* Did we get a proper answer ? */
-	if (irb->scsw.cmd.cc == 0 && cdev->private->senseid.cu_type != 0xFFFF &&
-	    cdev->private->senseid.reserved == 0xFF) {
-		if (irb->scsw.cmd.count < sizeof(struct senseid) - 8)
-			cdev->private->flags.esid = 1;
-		return 0; /* Success */
-	}
-
-	/* Hmm, whatever happened, try again. */
-	CIO_MSG_EVENT(2, "SenseID : start_IO() for device %04x on "
-		      "subchannel 0.%x.%04x returns status %02X%02X\n",
-		      cdev->private->dev_id.devno, sch->schid.ssid,
-		      sch->schid.sch_no,
-		      irb->scsw.cmd.dstat, irb->scsw.cmd.cstat);
+out_restart:
+	snsid_init(cdev);
 	return -EAGAIN;
 }
 
 /*
- * Got interrupt for Sense ID.
+ * Process SENSE ID request result.
  */
-void
-ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event)
+static void snsid_callback(struct ccw_device *cdev, void *data, int rc)
 {
-	struct subchannel *sch;
-	struct irb *irb;
-	int ret;
+	struct ccw_dev_id *id = &cdev->private->dev_id;
+	struct senseid *senseid = &cdev->private->senseid;
+	int vm = 0;
 
-	sch = to_subchannel(cdev->dev.parent);
-	irb = (struct irb *) __LC_IRB;
-	/* Retry sense id, if needed. */
-	if (irb->scsw.cmd.stctl ==
-	    (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
-		if ((irb->scsw.cmd.cc == 1) || !irb->scsw.cmd.actl) {
-			ret = __ccw_device_sense_id_start(cdev);
-			if (ret && ret != -EBUSY)
-				ccw_device_sense_id_done(cdev, ret);
+	if (rc && MACHINE_IS_VM) {
+		/* Try diag 0x210 fallback on z/VM. */
+		snsid_init(cdev);
+		if (diag210_get_dev_info(cdev) == 0) {
+			rc = 0;
+			vm = 1;
 		}
-		return;
 	}
-	if (ccw_device_accumulate_and_sense(cdev, irb) != 0)
-		return;
-	ret = ccw_device_check_sense_id(cdev);
-	memset(&cdev->private->irb, 0, sizeof(struct irb));
-	switch (ret) {
-	/* 0, -ETIME, -EOPNOTSUPP, -EAGAIN or -EACCES */
-	case 0:			/* Sense id succeeded. */
-	case -ETIME:		/* Sense id stopped by timeout. */
-		ccw_device_sense_id_done(cdev, ret);
-		break;
-	case -EACCES:		/* channel is not operational. */
-		sch->lpm &= ~cdev->private->imask;
-		cdev->private->imask >>= 1;
-		cdev->private->iretry = 5;
-		/* fall through. */
-	case -EAGAIN:		/* try again. */
-		ret = __ccw_device_sense_id_start(cdev);
-		if (ret == 0 || ret == -EBUSY)
-			break;
-		/* fall through. */
-	default:		/* Sense ID failed. Try asking VM. */
-		if (MACHINE_IS_VM)
-			ret = diag_get_dev_info(cdev->private->dev_id.devno,
-						&cdev->private->senseid);
-		else
-			/*
-			 * If we can't couldn't identify the device type we
-			 *  consider the device "not operational".
-			 */
-			ret = -ENODEV;
+	CIO_MSG_EVENT(2, "snsid: device 0.%x.%04x: rc=%d %04x/%02x "
+		      "%04x/%02x%s\n", id->ssid, id->devno, rc,
+		      senseid->cu_type, senseid->cu_model, senseid->dev_type,
+		      senseid->dev_model, vm ? " (diag210)" : "");
+	ccw_device_sense_id_done(cdev, rc);
+}
 
-		ccw_device_sense_id_done(cdev, ret);
-		break;
-	}
+/**
+ * ccw_device_sense_id_start - perform SENSE ID
+ * @cdev: ccw device
+ *
+ * Execute a SENSE ID channel program on @cdev to update its sense id
+ * information. When finished, call ccw_device_sense_id_done with a
+ * return code specifying the result.
+ */
+void ccw_device_sense_id_start(struct ccw_device *cdev)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_request *req = &cdev->private->req;
+	struct ccw1 *cp = cdev->private->iccws;
+
+	CIO_TRACE_EVENT(4, "snsid");
+	CIO_HEX_EVENT(4, &cdev->private->dev_id, sizeof(cdev->private->dev_id));
+	/* Data setup. */
+	snsid_init(cdev);
+	/* Channel program setup. */
+	cp->cmd_code	= CCW_CMD_SENSE_ID;
+	cp->cda		= (u32) (addr_t) &cdev->private->senseid;
+	cp->count	= sizeof(struct senseid);
+	cp->flags	= CCW_FLAG_SLI;
+	/* Request setup. */
+	memset(req, 0, sizeof(*req));
+	req->cp		= cp;
+	req->timeout	= SENSE_ID_TIMEOUT;
+	req->maxretries	= SENSE_ID_RETRIES;
+	req->lpm	= sch->schib.pmcw.pam & sch->opm;
+	req->check	= snsid_check;
+	req->callback	= snsid_callback;
+	ccw_request_start(cdev);
 }
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index 2d0efee..6da8454 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -11,6 +11,7 @@
 #include <linux/list.h>
 #include <linux/device.h>
 #include <linux/delay.h>
+#include <linux/completion.h>
 
 #include <asm/ccwdev.h>
 #include <asm/idals.h>
@@ -46,6 +47,7 @@
 	cdev->private->options.repall = (flags & CCWDEV_REPORT_ALL) != 0;
 	cdev->private->options.pgroup = (flags & CCWDEV_DO_PATHGROUP) != 0;
 	cdev->private->options.force = (flags & CCWDEV_ALLOW_FORCE) != 0;
+	cdev->private->options.mpath = (flags & CCWDEV_DO_MULTIPATH) != 0;
 	return 0;
 }
 
@@ -74,6 +76,7 @@
 	cdev->private->options.repall |= (flags & CCWDEV_REPORT_ALL) != 0;
 	cdev->private->options.pgroup |= (flags & CCWDEV_DO_PATHGROUP) != 0;
 	cdev->private->options.force |= (flags & CCWDEV_ALLOW_FORCE) != 0;
+	cdev->private->options.mpath |= (flags & CCWDEV_DO_MULTIPATH) != 0;
 	return 0;
 }
 
@@ -90,9 +93,34 @@
 	cdev->private->options.repall &= (flags & CCWDEV_REPORT_ALL) == 0;
 	cdev->private->options.pgroup &= (flags & CCWDEV_DO_PATHGROUP) == 0;
 	cdev->private->options.force &= (flags & CCWDEV_ALLOW_FORCE) == 0;
+	cdev->private->options.mpath &= (flags & CCWDEV_DO_MULTIPATH) == 0;
 }
 
 /**
+ * ccw_device_is_pathgroup - determine if paths to this device are grouped
+ * @cdev: ccw device
+ *
+ * Return non-zero if there is a path group, zero otherwise.
+ */
+int ccw_device_is_pathgroup(struct ccw_device *cdev)
+{
+	return cdev->private->flags.pgroup;
+}
+EXPORT_SYMBOL(ccw_device_is_pathgroup);
+
+/**
+ * ccw_device_is_multipath - determine if device is operating in multipath mode
+ * @cdev: ccw device
+ *
+ * Return non-zero if device is operating in multipath mode, zero otherwise.
+ */
+int ccw_device_is_multipath(struct ccw_device *cdev)
+{
+	return cdev->private->flags.mpath;
+}
+EXPORT_SYMBOL(ccw_device_is_multipath);
+
+/**
  * ccw_device_clear() - terminate I/O request processing
  * @cdev: target ccw device
  * @intparm: interruption parameter; value is only used if no I/O is
@@ -167,8 +195,7 @@
 		return -EINVAL;
 	if (cdev->private->state == DEV_STATE_NOT_OPER)
 		return -ENODEV;
-	if (cdev->private->state == DEV_STATE_VERIFY ||
-	    cdev->private->state == DEV_STATE_CLEAR_VERIFY) {
+	if (cdev->private->state == DEV_STATE_VERIFY) {
 		/* Remember to fake irb when finished. */
 		if (!cdev->private->flags.fake_irb) {
 			cdev->private->flags.fake_irb = 1;
@@ -478,74 +505,65 @@
 	return sch->lpm;
 }
 
-/*
- * Try to break the lock on a boxed device.
- */
-int
-ccw_device_stlck(struct ccw_device *cdev)
+struct stlck_data {
+	struct completion done;
+	int rc;
+};
+
+void ccw_device_stlck_done(struct ccw_device *cdev, void *data, int rc)
 {
-	void *buf, *buf2;
-	unsigned long flags;
-	struct subchannel *sch;
-	int ret;
+	struct stlck_data *sdata = data;
 
-	if (!cdev)
-		return -ENODEV;
+	sdata->rc = rc;
+	complete(&sdata->done);
+}
 
-	if (cdev->drv && !cdev->private->options.force)
-		return -EINVAL;
+/*
+ * Perform unconditional reserve + release.
+ */
+int ccw_device_stlck(struct ccw_device *cdev)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct stlck_data data;
+	u8 *buffer;
+	int rc;
 
-	sch = to_subchannel(cdev->dev.parent);
-	
-	CIO_TRACE_EVENT(2, "stl lock");
-	CIO_TRACE_EVENT(2, dev_name(&cdev->dev));
-
-	buf = kmalloc(32*sizeof(char), GFP_DMA|GFP_KERNEL);
-	if (!buf)
-		return -ENOMEM;
-	buf2 = kmalloc(32*sizeof(char), GFP_DMA|GFP_KERNEL);
-	if (!buf2) {
-		kfree(buf);
-		return -ENOMEM;
+	/* Check if steal lock operation is valid for this device. */
+	if (cdev->drv) {
+		if (!cdev->private->options.force)
+			return -EINVAL;
 	}
-	spin_lock_irqsave(sch->lock, flags);
-	ret = cio_enable_subchannel(sch, (u32)(addr_t)sch);
-	if (ret)
+	buffer = kzalloc(64, GFP_DMA | GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+	init_completion(&data.done);
+	data.rc = -EIO;
+	spin_lock_irq(sch->lock);
+	rc = cio_enable_subchannel(sch, (u32) (addr_t) sch);
+	if (rc)
 		goto out_unlock;
-	/*
-	 * Setup ccw. We chain an unconditional reserve and a release so we
-	 * only break the lock.
-	 */
-	cdev->private->iccws[0].cmd_code = CCW_CMD_STLCK;
-	cdev->private->iccws[0].cda = (__u32) __pa(buf);
-	cdev->private->iccws[0].count = 32;
-	cdev->private->iccws[0].flags = CCW_FLAG_CC;
-	cdev->private->iccws[1].cmd_code = CCW_CMD_RELEASE;
-	cdev->private->iccws[1].cda = (__u32) __pa(buf2);
-	cdev->private->iccws[1].count = 32;
-	cdev->private->iccws[1].flags = 0;
-	ret = cio_start(sch, cdev->private->iccws, 0);
-	if (ret) {
-		cio_disable_subchannel(sch); //FIXME: return code?
-		goto out_unlock;
+	/* Perform operation. */
+	cdev->private->state = DEV_STATE_STEAL_LOCK,
+	ccw_device_stlck_start(cdev, &data, &buffer[0], &buffer[32]);
+	spin_unlock_irq(sch->lock);
+	/* Wait for operation to finish. */
+	if (wait_for_completion_interruptible(&data.done)) {
+		/* Got a signal. */
+		spin_lock_irq(sch->lock);
+		ccw_request_cancel(cdev);
+		spin_unlock_irq(sch->lock);
+		wait_for_completion(&data.done);
 	}
-	cdev->private->irb.scsw.cmd.actl |= SCSW_ACTL_START_PEND;
-	spin_unlock_irqrestore(sch->lock, flags);
-	wait_event(cdev->private->wait_q,
-		   cdev->private->irb.scsw.cmd.actl == 0);
-	spin_lock_irqsave(sch->lock, flags);
-	cio_disable_subchannel(sch); //FIXME: return code?
-	if ((cdev->private->irb.scsw.cmd.dstat !=
-	     (DEV_STAT_CHN_END|DEV_STAT_DEV_END)) ||
-	    (cdev->private->irb.scsw.cmd.cstat != 0))
-		ret = -EIO;
-	/* Clear irb. */
-	memset(&cdev->private->irb, 0, sizeof(struct irb));
+	rc = data.rc;
+	/* Check results. */
+	spin_lock_irq(sch->lock);
+	cio_disable_subchannel(sch);
+	cdev->private->state = DEV_STATE_BOXED;
 out_unlock:
-	kfree(buf);
-	kfree(buf2);
-	spin_unlock_irqrestore(sch->lock, flags);
-	return ret;
+	spin_unlock_irq(sch->lock);
+	kfree(buffer);
+
+	return rc;
 }
 
 void *ccw_device_get_chp_desc(struct ccw_device *cdev, int chp_no)
diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c
index fc5ca1d..aad188e 100644
--- a/drivers/s390/cio/device_pgid.c
+++ b/drivers/s390/cio/device_pgid.c
@@ -1,594 +1,561 @@
 /*
- * drivers/s390/cio/device_pgid.c
+ *  CCW device PGID and path verification I/O handling.
  *
- *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
- *			 IBM Corporation
- *    Author(s): Cornelia Huck (cornelia.huck@de.ibm.com)
- *		 Martin Schwidefsky (schwidefsky@de.ibm.com)
- *
- * Path Group ID functions.
+ *    Copyright IBM Corp. 2002,2009
+ *    Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
+ *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
+ *		 Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
  */
 
-#include <linux/module.h>
-#include <linux/init.h>
-
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/bitops.h>
 #include <asm/ccwdev.h>
 #include <asm/cio.h>
-#include <asm/delay.h>
-#include <asm/lowcore.h>
 
 #include "cio.h"
 #include "cio_debug.h"
-#include "css.h"
 #include "device.h"
-#include "ioasm.h"
 #include "io_sch.h"
 
-/*
- * Helper function called from interrupt context to decide whether an
- * operation should be tried again.
- */
-static int __ccw_device_should_retry(union scsw *scsw)
-{
-	/* CC is only valid if start function bit is set. */
-	if ((scsw->cmd.fctl & SCSW_FCTL_START_FUNC) && scsw->cmd.cc == 1)
-		return 1;
-	/* No more activity. For sense and set PGID we stubbornly try again. */
-	if (!scsw->cmd.actl)
-		return 1;
-	return 0;
-}
+#define PGID_RETRIES	256
+#define PGID_TIMEOUT	(10 * HZ)
 
 /*
- * Start Sense Path Group ID helper function. Used in ccw_device_recog
- * and ccw_device_sense_pgid.
+ * Process path verification data and report result.
  */
-static int
-__ccw_device_sense_pgid_start(struct ccw_device *cdev)
-{
-	struct subchannel *sch;
-	struct ccw1 *ccw;
-	int ret;
-	int i;
-
-	sch = to_subchannel(cdev->dev.parent);
-	/* Return if we already checked on all paths. */
-	if (cdev->private->imask == 0)
-		return (sch->lpm == 0) ? -ENODEV : -EACCES;
-	i = 8 - ffs(cdev->private->imask);
-
-	/* Setup sense path group id channel program. */
-	ccw = cdev->private->iccws;
-	ccw->cmd_code = CCW_CMD_SENSE_PGID;
-	ccw->count = sizeof (struct pgid);
-	ccw->flags = CCW_FLAG_SLI;
-
-	/* Reset device status. */
-	memset(&cdev->private->irb, 0, sizeof(struct irb));
-	/* Try on every path. */
-	ret = -ENODEV;
-	while (cdev->private->imask != 0) {
-		/* Try every path multiple times. */
-		ccw->cda = (__u32) __pa (&cdev->private->pgid[i]);
-		if (cdev->private->iretry > 0) {
-			cdev->private->iretry--;
-			/* Reset internal retry indication. */
-			cdev->private->flags.intretry = 0;
-			ret = cio_start (sch, cdev->private->iccws, 
-					 cdev->private->imask);
-			/* ret is 0, -EBUSY, -EACCES or -ENODEV */
-			if (ret != -EACCES)
-				return ret;
-			CIO_MSG_EVENT(3, "SNID - Device %04x on Subchannel "
-				      "0.%x.%04x, lpm %02X, became 'not "
-				      "operational'\n",
-				      cdev->private->dev_id.devno,
-				      sch->schid.ssid,
-				      sch->schid.sch_no, cdev->private->imask);
-
-		}
-		cdev->private->imask >>= 1;
-		cdev->private->iretry = 5;
-		i++;
-	}
-
-	return ret;
-}
-
-void
-ccw_device_sense_pgid_start(struct ccw_device *cdev)
-{
-	int ret;
-
-	/* Set a timeout of 60s */
-	ccw_device_set_timeout(cdev, 60*HZ);
-
-	cdev->private->state = DEV_STATE_SENSE_PGID;
-	cdev->private->imask = 0x80;
-	cdev->private->iretry = 5;
-	memset (&cdev->private->pgid, 0, sizeof (cdev->private->pgid));
-	ret = __ccw_device_sense_pgid_start(cdev);
-	if (ret && ret != -EBUSY)
-		ccw_device_sense_pgid_done(cdev, ret);
-}
-
-/*
- * Called from interrupt context to check if a valid answer
- * to Sense Path Group ID was received.
- */
-static int
-__ccw_device_check_sense_pgid(struct ccw_device *cdev)
-{
-	struct subchannel *sch;
-	struct irb *irb;
-	int i;
-
-	sch = to_subchannel(cdev->dev.parent);
-	irb = &cdev->private->irb;
-	if (irb->scsw.cmd.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
-		/* Retry Sense PGID if requested. */
-		if (cdev->private->flags.intretry) {
-			cdev->private->flags.intretry = 0;
-			return -EAGAIN;
-		}
-		return -ETIME;
-	}
-	if (irb->esw.esw0.erw.cons &&
-	    (irb->ecw[0]&(SNS0_CMD_REJECT|SNS0_INTERVENTION_REQ))) {
-		/*
-		 * If the device doesn't support the Sense Path Group ID
-		 *  command further retries wouldn't help ...
-		 */
-		return -EOPNOTSUPP;
-	}
-	if (irb->esw.esw0.erw.cons) {
-		CIO_MSG_EVENT(2, "SNID - device 0.%x.%04x, unit check, "
-			      "lpum %02X, cnt %02d, sns : "
-			      "%02X%02X%02X%02X %02X%02X%02X%02X ...\n",
-			      cdev->private->dev_id.ssid,
-			      cdev->private->dev_id.devno,
-			      irb->esw.esw0.sublog.lpum,
-			      irb->esw.esw0.erw.scnt,
-			      irb->ecw[0], irb->ecw[1],
-			      irb->ecw[2], irb->ecw[3],
-			      irb->ecw[4], irb->ecw[5],
-			      irb->ecw[6], irb->ecw[7]);
-		return -EAGAIN;
-	}
-	if (irb->scsw.cmd.cc == 3) {
-		u8 lpm;
-
-		lpm = to_io_private(sch)->orb.cmd.lpm;
-		CIO_MSG_EVENT(3, "SNID - Device %04x on Subchannel 0.%x.%04x,"
-			      " lpm %02X, became 'not operational'\n",
-			      cdev->private->dev_id.devno, sch->schid.ssid,
-			      sch->schid.sch_no, lpm);
-		return -EACCES;
-	}
-	i = 8 - ffs(cdev->private->imask);
-	if (cdev->private->pgid[i].inf.ps.state2 == SNID_STATE2_RESVD_ELSE) {
-		CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x "
-			      "is reserved by someone else\n",
-			      cdev->private->dev_id.devno, sch->schid.ssid,
-			      sch->schid.sch_no);
-		return -EUSERS;
-	}
-	return 0;
-}
-
-/*
- * Got interrupt for Sense Path Group ID.
- */
-void
-ccw_device_sense_pgid_irq(struct ccw_device *cdev, enum dev_event dev_event)
-{
-	struct subchannel *sch;
-	struct irb *irb;
-	int ret;
-
-	irb = (struct irb *) __LC_IRB;
-
-	if (irb->scsw.cmd.stctl ==
-	    (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
-		if (__ccw_device_should_retry(&irb->scsw)) {
-			ret = __ccw_device_sense_pgid_start(cdev);
-			if (ret && ret != -EBUSY)
-				ccw_device_sense_pgid_done(cdev, ret);
-		}
-		return;
-	}
-	if (ccw_device_accumulate_and_sense(cdev, irb) != 0)
-		return;
-	sch = to_subchannel(cdev->dev.parent);
-	ret = __ccw_device_check_sense_pgid(cdev);
-	memset(&cdev->private->irb, 0, sizeof(struct irb));
-	switch (ret) {
-	/* 0, -ETIME, -EOPNOTSUPP, -EAGAIN, -EACCES or -EUSERS */
-	case -EOPNOTSUPP:	/* Sense Path Group ID not supported */
-		ccw_device_sense_pgid_done(cdev, -EOPNOTSUPP);
-		break;
-	case -ETIME:		/* Sense path group id stopped by timeout. */
-		ccw_device_sense_pgid_done(cdev, -ETIME);
-		break;
-	case -EACCES:		/* channel is not operational. */
-		sch->lpm &= ~cdev->private->imask;
-		/* Fall through. */
-	case 0:			/* Sense Path Group ID successful. */
-		cdev->private->imask >>= 1;
-		cdev->private->iretry = 5;
-		/* Fall through. */
-	case -EAGAIN:		/* Try again. */
-		ret = __ccw_device_sense_pgid_start(cdev);
-		if (ret != 0 && ret != -EBUSY)
-			ccw_device_sense_pgid_done(cdev, ret);
-		break;
-	case -EUSERS:		/* device is reserved for someone else. */
-		ccw_device_sense_pgid_done(cdev, -EUSERS);
-		break;
-	}
-}
-
-/*
- * Path Group ID helper function.
- */
-static int
-__ccw_device_do_pgid(struct ccw_device *cdev, __u8 func)
-{
-	struct subchannel *sch;
-	struct ccw1 *ccw;
-	int ret;
-
-	sch = to_subchannel(cdev->dev.parent);
-
-	/* Setup sense path group id channel program. */
-	cdev->private->pgid[0].inf.fc = func;
-	ccw = cdev->private->iccws;
-	if (cdev->private->flags.pgid_single)
-		cdev->private->pgid[0].inf.fc |= SPID_FUNC_SINGLE_PATH;
-	else
-		cdev->private->pgid[0].inf.fc |= SPID_FUNC_MULTI_PATH;
-	ccw->cmd_code = CCW_CMD_SET_PGID;
-	ccw->cda = (__u32) __pa (&cdev->private->pgid[0]);
-	ccw->count = sizeof (struct pgid);
-	ccw->flags = CCW_FLAG_SLI;
-
-	/* Reset device status. */
-	memset(&cdev->private->irb, 0, sizeof(struct irb));
-
-	/* Try multiple times. */
-	ret = -EACCES;
-	if (cdev->private->iretry > 0) {
-		cdev->private->iretry--;
-		/* Reset internal retry indication. */
-		cdev->private->flags.intretry = 0;
-		ret = cio_start (sch, cdev->private->iccws,
-				 cdev->private->imask);
-		/* We expect an interrupt in case of success or busy
-		 * indication. */
-		if ((ret == 0) || (ret == -EBUSY))
-			return ret;
-	}
-	/* PGID command failed on this path. */
-	CIO_MSG_EVENT(3, "SPID - Device %04x on Subchannel "
-		      "0.%x.%04x, lpm %02X, became 'not operational'\n",
-		      cdev->private->dev_id.devno, sch->schid.ssid,
-		      sch->schid.sch_no, cdev->private->imask);
-	return ret;
-}
-
-/*
- * Helper function to send a nop ccw down a path.
- */
-static int __ccw_device_do_nop(struct ccw_device *cdev)
-{
-	struct subchannel *sch;
-	struct ccw1 *ccw;
-	int ret;
-
-	sch = to_subchannel(cdev->dev.parent);
-
-	/* Setup nop channel program. */
-	ccw = cdev->private->iccws;
-	ccw->cmd_code = CCW_CMD_NOOP;
-	ccw->cda = 0;
-	ccw->count = 0;
-	ccw->flags = CCW_FLAG_SLI;
-
-	/* Reset device status. */
-	memset(&cdev->private->irb, 0, sizeof(struct irb));
-
-	/* Try multiple times. */
-	ret = -EACCES;
-	if (cdev->private->iretry > 0) {
-		cdev->private->iretry--;
-		/* Reset internal retry indication. */
-		cdev->private->flags.intretry = 0;
-		ret = cio_start (sch, cdev->private->iccws,
-				 cdev->private->imask);
-		/* We expect an interrupt in case of success or busy
-		 * indication. */
-		if ((ret == 0) || (ret == -EBUSY))
-			return ret;
-	}
-	/* nop command failed on this path. */
-	CIO_MSG_EVENT(3, "NOP - Device %04x on Subchannel "
-		      "0.%x.%04x, lpm %02X, became 'not operational'\n",
-		      cdev->private->dev_id.devno, sch->schid.ssid,
-		      sch->schid.sch_no, cdev->private->imask);
-	return ret;
-}
-
-
-/*
- * Called from interrupt context to check if a valid answer
- * to Set Path Group ID was received.
- */
-static int
-__ccw_device_check_pgid(struct ccw_device *cdev)
-{
-	struct subchannel *sch;
-	struct irb *irb;
-
-	sch = to_subchannel(cdev->dev.parent);
-	irb = &cdev->private->irb;
-	if (irb->scsw.cmd.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
-		/* Retry Set PGID if requested. */
-		if (cdev->private->flags.intretry) {
-			cdev->private->flags.intretry = 0;
-			return -EAGAIN;
-		}
-		return -ETIME;
-	}
-	if (irb->esw.esw0.erw.cons) {
-		if (irb->ecw[0] & SNS0_CMD_REJECT)
-			return -EOPNOTSUPP;
-		/* Hmm, whatever happened, try again. */
-		CIO_MSG_EVENT(2, "SPID - device 0.%x.%04x, unit check, "
-			      "cnt %02d, "
-			      "sns : %02X%02X%02X%02X %02X%02X%02X%02X ...\n",
-			      cdev->private->dev_id.ssid,
-			      cdev->private->dev_id.devno,
-			      irb->esw.esw0.erw.scnt,
-			      irb->ecw[0], irb->ecw[1],
-			      irb->ecw[2], irb->ecw[3],
-			      irb->ecw[4], irb->ecw[5],
-			      irb->ecw[6], irb->ecw[7]);
-		return -EAGAIN;
-	}
-	if (irb->scsw.cmd.cc == 3) {
-		CIO_MSG_EVENT(3, "SPID - Device %04x on Subchannel 0.%x.%04x,"
-			      " lpm %02X, became 'not operational'\n",
-			      cdev->private->dev_id.devno, sch->schid.ssid,
-			      sch->schid.sch_no, cdev->private->imask);
-		return -EACCES;
-	}
-	return 0;
-}
-
-/*
- * Called from interrupt context to check the path status after a nop has
- * been send.
- */
-static int __ccw_device_check_nop(struct ccw_device *cdev)
-{
-	struct subchannel *sch;
-	struct irb *irb;
-
-	sch = to_subchannel(cdev->dev.parent);
-	irb = &cdev->private->irb;
-	if (irb->scsw.cmd.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
-		/* Retry NOP if requested. */
-		if (cdev->private->flags.intretry) {
-			cdev->private->flags.intretry = 0;
-			return -EAGAIN;
-		}
-		return -ETIME;
-	}
-	if (irb->scsw.cmd.cc == 3) {
-		CIO_MSG_EVENT(3, "NOP - Device %04x on Subchannel 0.%x.%04x,"
-			      " lpm %02X, became 'not operational'\n",
-			      cdev->private->dev_id.devno, sch->schid.ssid,
-			      sch->schid.sch_no, cdev->private->imask);
-		return -EACCES;
-	}
-	return 0;
-}
-
-static void
-__ccw_device_verify_start(struct ccw_device *cdev)
-{
-	struct subchannel *sch;
-	__u8 func;
-	int ret;
-
-	sch = to_subchannel(cdev->dev.parent);
-	/* Repeat for all paths. */
-	for (; cdev->private->imask; cdev->private->imask >>= 1,
-				     cdev->private->iretry = 5) {
-		if ((cdev->private->imask & sch->schib.pmcw.pam) == 0)
-			/* Path not available, try next. */
-			continue;
-		if (cdev->private->options.pgroup) {
-			if (sch->opm & cdev->private->imask)
-				func = SPID_FUNC_ESTABLISH;
-			else
-				func = SPID_FUNC_RESIGN;
-			ret = __ccw_device_do_pgid(cdev, func);
-		} else
-			ret = __ccw_device_do_nop(cdev);
-		/* We expect an interrupt in case of success or busy
-		 * indication. */
-		if (ret == 0 || ret == -EBUSY)
-			return;
-		/* Permanent path failure, try next. */
-	}
-	/* Done with all paths. */
-	ccw_device_verify_done(cdev, (sch->vpm != 0) ? 0 : -ENODEV);
-}
-		
-/*
- * Got interrupt for Set Path Group ID.
- */
-void
-ccw_device_verify_irq(struct ccw_device *cdev, enum dev_event dev_event)
-{
-	struct subchannel *sch;
-	struct irb *irb;
-	int ret;
-
-	irb = (struct irb *) __LC_IRB;
-
-	if (irb->scsw.cmd.stctl ==
-	    (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
-		if (__ccw_device_should_retry(&irb->scsw))
-			__ccw_device_verify_start(cdev);
-		return;
-	}
-	if (ccw_device_accumulate_and_sense(cdev, irb) != 0)
-		return;
-	sch = to_subchannel(cdev->dev.parent);
-	if (cdev->private->options.pgroup)
-		ret = __ccw_device_check_pgid(cdev);
-	else
-		ret = __ccw_device_check_nop(cdev);
-	memset(&cdev->private->irb, 0, sizeof(struct irb));
-
-	switch (ret) {
-	/* 0, -ETIME, -EAGAIN, -EOPNOTSUPP or -EACCES */
-	case 0:
-		/* Path verification ccw finished successfully, update lpm. */
-		sch->vpm |= sch->opm & cdev->private->imask;
-		/* Go on with next path. */
-		cdev->private->imask >>= 1;
-		cdev->private->iretry = 5;
-		__ccw_device_verify_start(cdev);
-		break;
-	case -EOPNOTSUPP:
-		/*
-		 * One of those strange devices which claim to be able
-		 * to do multipathing but not for Set Path Group ID.
-		 */
-		if (cdev->private->flags.pgid_single)
-			cdev->private->options.pgroup = 0;
-		else
-			cdev->private->flags.pgid_single = 1;
-		/* Retry */
-		sch->vpm = 0;
-		cdev->private->imask = 0x80;
-		cdev->private->iretry = 5;
-		/* fall through. */
-	case -EAGAIN:		/* Try again. */
-		__ccw_device_verify_start(cdev);
-		break;
-	case -ETIME:		/* Set path group id stopped by timeout. */
-		ccw_device_verify_done(cdev, -ETIME);
-		break;
-	case -EACCES:		/* channel is not operational. */
-		cdev->private->imask >>= 1;
-		cdev->private->iretry = 5;
-		__ccw_device_verify_start(cdev);
-		break;
-	}
-}
-
-void
-ccw_device_verify_start(struct ccw_device *cdev)
+static void verify_done(struct ccw_device *cdev, int rc)
 {
 	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_dev_id *id = &cdev->private->dev_id;
+	int mpath = cdev->private->flags.mpath;
+	int pgroup = cdev->private->flags.pgroup;
 
-	cdev->private->flags.pgid_single = 0;
-	cdev->private->imask = 0x80;
-	cdev->private->iretry = 5;
-
-	/* Start with empty vpm. */
-	sch->vpm = 0;
-
-	/* Get current pam. */
-	if (cio_update_schib(sch)) {
-		ccw_device_verify_done(cdev, -ENODEV);
-		return;
+	if (rc)
+		goto out;
+	/* Ensure consistent multipathing state at device and channel. */
+	if (sch->config.mp != mpath) {
+		sch->config.mp = mpath;
+		rc = cio_commit_config(sch);
 	}
-	/* After 60s path verification is considered to have failed. */
-	ccw_device_set_timeout(cdev, 60*HZ);
-	__ccw_device_verify_start(cdev);
-}
-
-static void
-__ccw_device_disband_start(struct ccw_device *cdev)
-{
-	struct subchannel *sch;
-	int ret;
-
-	sch = to_subchannel(cdev->dev.parent);
-	while (cdev->private->imask != 0) {
-		if (sch->lpm & cdev->private->imask) {
-			ret = __ccw_device_do_pgid(cdev, SPID_FUNC_DISBAND);
-			if (ret == 0)
-				return;
-		}
-		cdev->private->iretry = 5;
-		cdev->private->imask >>= 1;
-	}
-	ccw_device_disband_done(cdev, (sch->lpm != 0) ? 0 : -ENODEV);
+out:
+	CIO_MSG_EVENT(2, "vrfy: device 0.%x.%04x: rc=%d pgroup=%d mpath=%d "
+			 "vpm=%02x\n", id->ssid, id->devno, rc, pgroup, mpath,
+			 sch->vpm);
+	ccw_device_verify_done(cdev, rc);
 }
 
 /*
- * Got interrupt for Unset Path Group ID.
+ * Create channel program to perform a NOOP.
  */
-void
-ccw_device_disband_irq(struct ccw_device *cdev, enum dev_event dev_event)
+static void nop_build_cp(struct ccw_device *cdev)
 {
-	struct subchannel *sch;
-	struct irb *irb;
-	int ret;
+	struct ccw_request *req = &cdev->private->req;
+	struct ccw1 *cp = cdev->private->iccws;
 
-	irb = (struct irb *) __LC_IRB;
+	cp->cmd_code	= CCW_CMD_NOOP;
+	cp->cda		= 0;
+	cp->count	= 0;
+	cp->flags	= CCW_FLAG_SLI;
+	req->cp		= cp;
+}
 
-	if (irb->scsw.cmd.stctl ==
-	    (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
-		if (__ccw_device_should_retry(&irb->scsw))
-			__ccw_device_disband_start(cdev);
-		return;
-	}
-	if (ccw_device_accumulate_and_sense(cdev, irb) != 0)
-		return;
-	sch = to_subchannel(cdev->dev.parent);
-	ret = __ccw_device_check_pgid(cdev);
-	memset(&cdev->private->irb, 0, sizeof(struct irb));
-	switch (ret) {
-	/* 0, -ETIME, -EAGAIN, -EOPNOTSUPP or -EACCES */
-	case 0:			/* disband successful. */
-		ccw_device_disband_done(cdev, ret);
+/*
+ * Perform NOOP on a single path.
+ */
+static void nop_do(struct ccw_device *cdev)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_request *req = &cdev->private->req;
+
+	/* Adjust lpm. */
+	req->lpm = lpm_adjust(req->lpm, sch->schib.pmcw.pam & sch->opm);
+	if (!req->lpm)
+		goto out_nopath;
+	nop_build_cp(cdev);
+	ccw_request_start(cdev);
+	return;
+
+out_nopath:
+	verify_done(cdev, sch->vpm ? 0 : -EACCES);
+}
+
+/*
+ * Adjust NOOP I/O status.
+ */
+static enum io_status nop_filter(struct ccw_device *cdev, void *data,
+				 struct irb *irb, enum io_status status)
+{
+	/* Only subchannel status might indicate a path error. */
+	if (status == IO_STATUS_ERROR && irb->scsw.cmd.cstat == 0)
+		return IO_DONE;
+	return status;
+}
+
+/*
+ * Process NOOP request result for a single path.
+ */
+static void nop_callback(struct ccw_device *cdev, void *data, int rc)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_request *req = &cdev->private->req;
+
+	if (rc == 0)
+		sch->vpm |= req->lpm;
+	else if (rc != -EACCES)
+		goto err;
+	req->lpm >>= 1;
+	nop_do(cdev);
+	return;
+
+err:
+	verify_done(cdev, rc);
+}
+
+/*
+ * Create channel program to perform SET PGID on a single path.
+ */
+static void spid_build_cp(struct ccw_device *cdev, u8 fn)
+{
+	struct ccw_request *req = &cdev->private->req;
+	struct ccw1 *cp = cdev->private->iccws;
+	int i = 8 - ffs(req->lpm);
+	struct pgid *pgid = &cdev->private->pgid[i];
+
+	pgid->inf.fc	= fn;
+	cp->cmd_code	= CCW_CMD_SET_PGID;
+	cp->cda		= (u32) (addr_t) pgid;
+	cp->count	= sizeof(*pgid);
+	cp->flags	= CCW_FLAG_SLI;
+	req->cp		= cp;
+}
+
+/*
+ * Perform establish/resign SET PGID on a single path.
+ */
+static void spid_do(struct ccw_device *cdev)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_request *req = &cdev->private->req;
+	u8 fn;
+
+	/* Use next available path that is not already in correct state. */
+	req->lpm = lpm_adjust(req->lpm, sch->schib.pmcw.pam & ~sch->vpm);
+	if (!req->lpm)
+		goto out_nopath;
+	/* Channel program setup. */
+	if (req->lpm & sch->opm)
+		fn = SPID_FUNC_ESTABLISH;
+	else
+		fn = SPID_FUNC_RESIGN;
+	if (cdev->private->flags.mpath)
+		fn |= SPID_FUNC_MULTI_PATH;
+	spid_build_cp(cdev, fn);
+	ccw_request_start(cdev);
+	return;
+
+out_nopath:
+	verify_done(cdev, sch->vpm ? 0 : -EACCES);
+}
+
+static void verify_start(struct ccw_device *cdev);
+
+/*
+ * Process SET PGID request result for a single path.
+ */
+static void spid_callback(struct ccw_device *cdev, void *data, int rc)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_request *req = &cdev->private->req;
+
+	switch (rc) {
+	case 0:
+		sch->vpm |= req->lpm & sch->opm;
+		break;
+	case -EACCES:
 		break;
 	case -EOPNOTSUPP:
-		/*
-		 * One of those strange devices which claim to be able
-		 * to do multipathing but not for Unset Path Group ID.
-		 */
-		cdev->private->flags.pgid_single = 1;
-		/* fall through. */
-	case -EAGAIN:		/* Try again. */
-		__ccw_device_disband_start(cdev);
+		if (cdev->private->flags.mpath) {
+			/* Try without multipathing. */
+			cdev->private->flags.mpath = 0;
+			goto out_restart;
+		}
+		/* Try without pathgrouping. */
+		cdev->private->flags.pgroup = 0;
+		goto out_restart;
+	default:
+		goto err;
+	}
+	req->lpm >>= 1;
+	spid_do(cdev);
+	return;
+
+out_restart:
+	verify_start(cdev);
+	return;
+err:
+	verify_done(cdev, rc);
+}
+
+static void spid_start(struct ccw_device *cdev)
+{
+	struct ccw_request *req = &cdev->private->req;
+
+	/* Initialize request data. */
+	memset(req, 0, sizeof(*req));
+	req->timeout	= PGID_TIMEOUT;
+	req->maxretries	= PGID_RETRIES;
+	req->lpm	= 0x80;
+	req->callback	= spid_callback;
+	spid_do(cdev);
+}
+
+static int pgid_cmp(struct pgid *p1, struct pgid *p2)
+{
+	return memcmp((char *) p1 + 1, (char *) p2 + 1,
+		      sizeof(struct pgid) - 1);
+}
+
+/*
+ * Determine pathgroup state from PGID data.
+ */
+static void pgid_analyze(struct ccw_device *cdev, struct pgid **p,
+			 int *mismatch, int *reserved, int *reset)
+{
+	struct pgid *pgid = &cdev->private->pgid[0];
+	struct pgid *first = NULL;
+	int lpm;
+	int i;
+
+	*mismatch = 0;
+	*reserved = 0;
+	*reset = 0;
+	for (i = 0, lpm = 0x80; i < 8; i++, pgid++, lpm >>= 1) {
+		if ((cdev->private->pgid_valid_mask & lpm) == 0)
+			continue;
+		if (pgid->inf.ps.state2 == SNID_STATE2_RESVD_ELSE)
+			*reserved = 1;
+		if (pgid->inf.ps.state1 == SNID_STATE1_RESET) {
+			/* A PGID was reset. */
+			*reset = 1;
+			continue;
+		}
+		if (!first) {
+			first = pgid;
+			continue;
+		}
+		if (pgid_cmp(pgid, first) != 0)
+			*mismatch = 1;
+	}
+	if (!first)
+		first = &channel_subsystems[0]->global_pgid;
+	*p = first;
+}
+
+static u8 pgid_to_vpm(struct ccw_device *cdev)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct pgid *pgid;
+	int i;
+	int lpm;
+	u8 vpm = 0;
+
+	/* Set VPM bits for paths which are already in the target state. */
+	for (i = 0; i < 8; i++) {
+		lpm = 0x80 >> i;
+		if ((cdev->private->pgid_valid_mask & lpm) == 0)
+			continue;
+		pgid = &cdev->private->pgid[i];
+		if (sch->opm & lpm) {
+			if (pgid->inf.ps.state1 != SNID_STATE1_GROUPED)
+				continue;
+		} else {
+			if (pgid->inf.ps.state1 != SNID_STATE1_UNGROUPED)
+				continue;
+		}
+		if (cdev->private->flags.mpath) {
+			if (pgid->inf.ps.state3 != SNID_STATE3_MULTI_PATH)
+				continue;
+		} else {
+			if (pgid->inf.ps.state3 != SNID_STATE3_SINGLE_PATH)
+				continue;
+		}
+		vpm |= lpm;
+	}
+
+	return vpm;
+}
+
+static void pgid_fill(struct ccw_device *cdev, struct pgid *pgid)
+{
+	int i;
+
+	for (i = 0; i < 8; i++)
+		memcpy(&cdev->private->pgid[i], pgid, sizeof(struct pgid));
+}
+
+/*
+ * Process SENSE PGID data and report result.
+ */
+static void snid_done(struct ccw_device *cdev, int rc)
+{
+	struct ccw_dev_id *id = &cdev->private->dev_id;
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct pgid *pgid;
+	int mismatch = 0;
+	int reserved = 0;
+	int reset = 0;
+
+	if (rc)
+		goto out;
+	pgid_analyze(cdev, &pgid, &mismatch, &reserved, &reset);
+	if (reserved)
+		rc = -EUSERS;
+	else if (mismatch)
+		rc = -EOPNOTSUPP;
+	else {
+		sch->vpm = pgid_to_vpm(cdev);
+		pgid_fill(cdev, pgid);
+	}
+out:
+	CIO_MSG_EVENT(2, "snid: device 0.%x.%04x: rc=%d pvm=%02x vpm=%02x "
+		      "mism=%d rsvd=%d reset=%d\n", id->ssid, id->devno, rc,
+		      cdev->private->pgid_valid_mask, sch->vpm, mismatch,
+		      reserved, reset);
+	switch (rc) {
+	case 0:
+		/* Anything left to do? */
+		if (sch->vpm == sch->schib.pmcw.pam) {
+			verify_done(cdev, sch->vpm == 0 ? -EACCES : 0);
+			return;
+		}
+		/* Perform path-grouping. */
+		spid_start(cdev);
 		break;
-	case -ETIME:		/* Set path group id stopped by timeout. */
-		ccw_device_disband_done(cdev, -ETIME);
+	case -EOPNOTSUPP:
+		/* Path-grouping not supported. */
+		cdev->private->flags.pgroup = 0;
+		cdev->private->flags.mpath = 0;
+		verify_start(cdev);
 		break;
-	case -EACCES:		/* channel is not operational. */
-		cdev->private->imask >>= 1;
-		cdev->private->iretry = 5;
-		__ccw_device_disband_start(cdev);
-		break;
+	default:
+		verify_done(cdev, rc);
 	}
 }
 
-void
-ccw_device_disband_start(struct ccw_device *cdev)
+/*
+ * Create channel program to perform a SENSE PGID on a single path.
+ */
+static void snid_build_cp(struct ccw_device *cdev)
 {
-	/* After 60s disbanding is considered to have failed. */
-	ccw_device_set_timeout(cdev, 60*HZ);
+	struct ccw_request *req = &cdev->private->req;
+	struct ccw1 *cp = cdev->private->iccws;
+	int i = 8 - ffs(req->lpm);
 
-	cdev->private->flags.pgid_single = 0;
-	cdev->private->iretry = 5;
-	cdev->private->imask = 0x80;
-	__ccw_device_disband_start(cdev);
+	/* Channel program setup. */
+	cp->cmd_code	= CCW_CMD_SENSE_PGID;
+	cp->cda		= (u32) (addr_t) &cdev->private->pgid[i];
+	cp->count	= sizeof(struct pgid);
+	cp->flags	= CCW_FLAG_SLI;
+	req->cp		= cp;
 }
+
+/*
+ * Perform SENSE PGID on a single path.
+ */
+static void snid_do(struct ccw_device *cdev)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_request *req = &cdev->private->req;
+
+	/* Adjust lpm if paths are not set in pam. */
+	req->lpm = lpm_adjust(req->lpm, sch->schib.pmcw.pam);
+	if (!req->lpm)
+		goto out_nopath;
+	snid_build_cp(cdev);
+	ccw_request_start(cdev);
+	return;
+
+out_nopath:
+	snid_done(cdev, cdev->private->pgid_valid_mask ? 0 : -EACCES);
+}
+
+/*
+ * Process SENSE PGID request result for single path.
+ */
+static void snid_callback(struct ccw_device *cdev, void *data, int rc)
+{
+	struct ccw_request *req = &cdev->private->req;
+
+	if (rc == 0)
+		cdev->private->pgid_valid_mask |= req->lpm;
+	else if (rc != -EACCES)
+		goto err;
+	req->lpm >>= 1;
+	snid_do(cdev);
+	return;
+
+err:
+	snid_done(cdev, rc);
+}
+
+/*
+ * Perform path verification.
+ */
+static void verify_start(struct ccw_device *cdev)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_request *req = &cdev->private->req;
+	struct ccw_dev_id *devid = &cdev->private->dev_id;
+
+	sch->vpm = 0;
+	/* Initialize request data. */
+	memset(req, 0, sizeof(*req));
+	req->timeout	= PGID_TIMEOUT;
+	req->maxretries	= PGID_RETRIES;
+	req->lpm	= 0x80;
+	if (cdev->private->flags.pgroup) {
+		CIO_TRACE_EVENT(4, "snid");
+		CIO_HEX_EVENT(4, devid, sizeof(*devid));
+		req->callback	= snid_callback;
+		snid_do(cdev);
+	} else {
+		CIO_TRACE_EVENT(4, "nop");
+		CIO_HEX_EVENT(4, devid, sizeof(*devid));
+		req->filter	= nop_filter;
+		req->callback	= nop_callback;
+		nop_do(cdev);
+	}
+}
+
+/**
+ * ccw_device_verify_start - perform path verification
+ * @cdev: ccw device
+ *
+ * Perform an I/O on each available channel path to @cdev to determine which
+ * paths are operational. The resulting path mask is stored in sch->vpm.
+ * If device options specify pathgrouping, establish a pathgroup for the
+ * operational paths. When finished, call ccw_device_verify_done with a
+ * return code specifying the result.
+ */
+void ccw_device_verify_start(struct ccw_device *cdev)
+{
+	CIO_TRACE_EVENT(4, "vrfy");
+	CIO_HEX_EVENT(4, &cdev->private->dev_id, sizeof(cdev->private->dev_id));
+	/* Initialize PGID data. */
+	memset(cdev->private->pgid, 0, sizeof(cdev->private->pgid));
+	cdev->private->pgid_valid_mask = 0;
+	/*
+	 * Initialize pathgroup and multipath state with target values.
+	 * They may change in the course of path verification.
+	 */
+	cdev->private->flags.pgroup = cdev->private->options.pgroup;
+	cdev->private->flags.mpath = cdev->private->options.mpath;
+	cdev->private->flags.doverify = 0;
+	verify_start(cdev);
+}
+
+/*
+ * Process disband SET PGID request result.
+ */
+static void disband_callback(struct ccw_device *cdev, void *data, int rc)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_dev_id *id = &cdev->private->dev_id;
+
+	if (rc)
+		goto out;
+	/* Ensure consistent multipathing state at device and channel. */
+	cdev->private->flags.mpath = 0;
+	if (sch->config.mp) {
+		sch->config.mp = 0;
+		rc = cio_commit_config(sch);
+	}
+out:
+	CIO_MSG_EVENT(0, "disb: device 0.%x.%04x: rc=%d\n", id->ssid, id->devno,
+		      rc);
+	ccw_device_disband_done(cdev, rc);
+}
+
+/**
+ * ccw_device_disband_start - disband pathgroup
+ * @cdev: ccw device
+ *
+ * Execute a SET PGID channel program on @cdev to disband a previously
+ * established pathgroup. When finished, call ccw_device_disband_done with
+ * a return code specifying the result.
+ */
+void ccw_device_disband_start(struct ccw_device *cdev)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_request *req = &cdev->private->req;
+	u8 fn;
+
+	CIO_TRACE_EVENT(4, "disb");
+	CIO_HEX_EVENT(4, &cdev->private->dev_id, sizeof(cdev->private->dev_id));
+	/* Request setup. */
+	memset(req, 0, sizeof(*req));
+	req->timeout	= PGID_TIMEOUT;
+	req->maxretries	= PGID_RETRIES;
+	req->lpm	= sch->schib.pmcw.pam & sch->opm;
+	req->callback	= disband_callback;
+	fn = SPID_FUNC_DISBAND;
+	if (cdev->private->flags.mpath)
+		fn |= SPID_FUNC_MULTI_PATH;
+	spid_build_cp(cdev, fn);
+	ccw_request_start(cdev);
+}
+
+static void stlck_build_cp(struct ccw_device *cdev, void *buf1, void *buf2)
+{
+	struct ccw_request *req = &cdev->private->req;
+	struct ccw1 *cp = cdev->private->iccws;
+
+	cp[0].cmd_code = CCW_CMD_STLCK;
+	cp[0].cda = (u32) (addr_t) buf1;
+	cp[0].count = 32;
+	cp[0].flags = CCW_FLAG_CC;
+	cp[1].cmd_code = CCW_CMD_RELEASE;
+	cp[1].cda = (u32) (addr_t) buf2;
+	cp[1].count = 32;
+	cp[1].flags = 0;
+	req->cp = cp;
+}
+
+static void stlck_callback(struct ccw_device *cdev, void *data, int rc)
+{
+	ccw_device_stlck_done(cdev, data, rc);
+}
+
+/**
+ * ccw_device_stlck_start - perform unconditional release
+ * @cdev: ccw device
+ * @data: data pointer to be passed to ccw_device_stlck_done
+ * @buf1: data pointer used in channel program
+ * @buf2: data pointer used in channel program
+ *
+ * Execute a channel program on @cdev to release an existing PGID reservation.
+ * When finished, call ccw_device_stlck_done with a return code specifying the
+ * result.
+ */
+void ccw_device_stlck_start(struct ccw_device *cdev, void *data, void *buf1,
+			    void *buf2)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_request *req = &cdev->private->req;
+
+	CIO_TRACE_EVENT(4, "stlck");
+	CIO_HEX_EVENT(4, &cdev->private->dev_id, sizeof(cdev->private->dev_id));
+	/* Request setup. */
+	memset(req, 0, sizeof(*req));
+	req->timeout	= PGID_TIMEOUT;
+	req->maxretries	= PGID_RETRIES;
+	req->lpm	= sch->schib.pmcw.pam & sch->opm;
+	req->data	= data;
+	req->callback	= stlck_callback;
+	stlck_build_cp(cdev, buf1, buf2);
+	ccw_request_start(cdev);
+}
+
diff --git a/drivers/s390/cio/device_status.c b/drivers/s390/cio/device_status.c
index 5814dbe..66d8066 100644
--- a/drivers/s390/cio/device_status.c
+++ b/drivers/s390/cio/device_status.c
@@ -336,9 +336,6 @@
 	sense_ccw->count = SENSE_MAX_COUNT;
 	sense_ccw->flags = CCW_FLAG_SLI;
 
-	/* Reset internal retry indication. */
-	cdev->private->flags.intretry = 0;
-
 	rc = cio_start(sch, sense_ccw, 0xff);
 	if (rc == -ENODEV || rc == -EACCES)
 		dev_fsm_event(cdev, DEV_EVENT_VERIFY);
diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h
index 0b8f381..d72ae4c 100644
--- a/drivers/s390/cio/io_sch.h
+++ b/drivers/s390/cio/io_sch.h
@@ -1,7 +1,10 @@
 #ifndef S390_IO_SCH_H
 #define S390_IO_SCH_H
 
+#include <linux/types.h>
 #include <asm/schid.h>
+#include <asm/ccwdev.h>
+#include "css.h"
 
 /*
  * command-mode operation request block
@@ -68,6 +71,52 @@
 #define MAX_CIWS 8
 
 /*
+ * Possible status values for a CCW request's I/O.
+ */
+enum io_status {
+	IO_DONE,
+	IO_RUNNING,
+	IO_STATUS_ERROR,
+	IO_PATH_ERROR,
+	IO_REJECTED,
+	IO_KILLED
+};
+
+/**
+ * ccw_request - Internal CCW request.
+ * @cp: channel program to start
+ * @timeout: maximum allowable time in jiffies between start I/O and interrupt
+ * @maxretries: number of retries per I/O operation and path
+ * @lpm: mask of paths to use
+ * @check: optional callback that determines if results are final
+ * @filter: optional callback to adjust request status based on IRB data
+ * @callback: final callback
+ * @data: user-defined pointer passed to all callbacks
+ * @mask: current path mask
+ * @retries: current number of retries
+ * @drc: delayed return code
+ * @cancel: non-zero if request was cancelled
+ * @done: non-zero if request was finished
+ */
+struct ccw_request {
+	struct ccw1 *cp;
+	unsigned long timeout;
+	u16 maxretries;
+	u8 lpm;
+	int (*check)(struct ccw_device *, void *);
+	enum io_status (*filter)(struct ccw_device *, void *, struct irb *,
+				 enum io_status);
+	void (*callback)(struct ccw_device *, void *, int);
+	void *data;
+	/* These fields are used internally. */
+	u16 mask;
+	u16 retries;
+	int drc;
+	int cancel:1;
+	int done:1;
+} __attribute__((packed));
+
+/*
  * sense-id response buffer layout
  */
 struct senseid {
@@ -82,32 +131,43 @@
 	struct ciw ciw[MAX_CIWS];	/* variable # of CIWs */
 }  __attribute__ ((packed, aligned(4)));
 
+enum cdev_todo {
+	CDEV_TODO_NOTHING,
+	CDEV_TODO_ENABLE_CMF,
+	CDEV_TODO_REBIND,
+	CDEV_TODO_REGISTER,
+	CDEV_TODO_UNREG,
+	CDEV_TODO_UNREG_EVAL,
+};
+
 struct ccw_device_private {
 	struct ccw_device *cdev;
 	struct subchannel *sch;
 	int state;		/* device state */
 	atomic_t onoff;
-	unsigned long registered;
 	struct ccw_dev_id dev_id;	/* device id */
 	struct subchannel_id schid;	/* subchannel number */
-	u8 imask;		/* lpm mask for SNID/SID/SPGID */
-	int iretry;		/* retry counter SNID/SID/SPGID */
+	struct ccw_request req;		/* internal I/O request */
+	int iretry;
+	u8 pgid_valid_mask;		/* mask of valid PGIDs */
 	struct {
 		unsigned int fast:1;	/* post with "channel end" */
 		unsigned int repall:1;	/* report every interrupt status */
 		unsigned int pgroup:1;	/* do path grouping */
 		unsigned int force:1;	/* allow forced online */
+		unsigned int mpath:1;	/* do multipathing */
 	} __attribute__ ((packed)) options;
 	struct {
-		unsigned int pgid_single:1; /* use single path for Set PGID */
 		unsigned int esid:1;	    /* Ext. SenseID supported by HW */
 		unsigned int dosense:1;	    /* delayed SENSE required */
 		unsigned int doverify:1;    /* delayed path verification */
 		unsigned int donotify:1;    /* call notify function */
 		unsigned int recog_done:1;  /* dev. recog. complete */
 		unsigned int fake_irb:1;    /* deliver faked irb */
-		unsigned int intretry:1;    /* retry internal operation */
 		unsigned int resuming:1;    /* recognition while resume */
+		unsigned int pgroup:1;	    /* pathgroup is set up */
+		unsigned int mpath:1;	    /* multipathing is set up */
+		unsigned int initialized:1; /* set if initial reference held */
 	} __attribute__((packed)) flags;
 	unsigned long intparm;	/* user interruption parameter */
 	struct qdio_irq *qdio_data;
@@ -115,7 +175,8 @@
 	struct senseid senseid;	/* SenseID info */
 	struct pgid pgid[8];	/* path group IDs per chpid*/
 	struct ccw1 iccws[2];	/* ccws for SNID/SID/SPGID commands */
-	struct work_struct kick_work;
+	struct work_struct todo_work;
+	enum cdev_todo todo;
 	wait_queue_head_t wait_q;
 	struct timer_list timer;
 	void *cmb;			/* measurement information */
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 1294876..20836ef 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -102,6 +102,7 @@
 static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait);
 static struct task_struct *ap_poll_kthread = NULL;
 static DEFINE_MUTEX(ap_poll_thread_mutex);
+static DEFINE_SPINLOCK(ap_poll_timer_lock);
 static void *ap_interrupt_indicator;
 static struct hrtimer ap_poll_timer;
 /* In LPAR poll with 4kHz frequency. Poll every 250000 nanoseconds.
@@ -282,6 +283,7 @@
  * @psmid: The program supplied message identifier
  * @msg: The message text
  * @length: The message length
+ * @special: Special Bit
  *
  * Returns AP queue status structure.
  * Condition code 1 on NQAP can't happen because the L bit is 1.
@@ -289,7 +291,8 @@
  * because a segment boundary was reached. The NQAP is repeated.
  */
 static inline struct ap_queue_status
-__ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length)
+__ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length,
+	  unsigned int special)
 {
 	typedef struct { char _[length]; } msgblock;
 	register unsigned long reg0 asm ("0") = qid | 0x40000000UL;
@@ -299,6 +302,9 @@
 	register unsigned long reg4 asm ("4") = (unsigned int) (psmid >> 32);
 	register unsigned long reg5 asm ("5") = (unsigned int) psmid;
 
+	if (special == 1)
+		reg0 |= 0x400000UL;
+
 	asm volatile (
 		"0: .long 0xb2ad0042\n"		/* DQAP */
 		"   brc   2,0b"
@@ -312,13 +318,15 @@
 {
 	struct ap_queue_status status;
 
-	status = __ap_send(qid, psmid, msg, length);
+	status = __ap_send(qid, psmid, msg, length, 0);
 	switch (status.response_code) {
 	case AP_RESPONSE_NORMAL:
 		return 0;
 	case AP_RESPONSE_Q_FULL:
 	case AP_RESPONSE_RESET_IN_PROGRESS:
 		return -EBUSY;
+	case AP_RESPONSE_REQ_FAC_NOT_INST:
+		return -EINVAL;
 	default:	/* Device is gone. */
 		return -ENODEV;
 	}
@@ -1008,7 +1016,7 @@
 	}
 
 	status = __ap_send(ap_dev->qid, 0x0102030405060708ULL,
-			   msg, sizeof(msg));
+			   msg, sizeof(msg), 0);
 	if (status.response_code != AP_RESPONSE_NORMAL) {
 		rc = -ENODEV;
 		goto out_free;
@@ -1163,16 +1171,19 @@
 static inline void ap_schedule_poll_timer(void)
 {
 	ktime_t hr_time;
+
+	spin_lock_bh(&ap_poll_timer_lock);
 	if (ap_using_interrupts() || ap_suspend_flag)
-		return;
+		goto out;
 	if (hrtimer_is_queued(&ap_poll_timer))
-		return;
+		goto out;
 	if (ktime_to_ns(hrtimer_expires_remaining(&ap_poll_timer)) <= 0) {
 		hr_time = ktime_set(0, poll_timeout);
 		hrtimer_forward_now(&ap_poll_timer, hr_time);
 		hrtimer_restart(&ap_poll_timer);
 	}
-	return;
+out:
+	spin_unlock_bh(&ap_poll_timer_lock);
 }
 
 /**
@@ -1243,7 +1254,7 @@
 	/* Start the next request on the queue. */
 	ap_msg = list_entry(ap_dev->requestq.next, struct ap_message, list);
 	status = __ap_send(ap_dev->qid, ap_msg->psmid,
-			   ap_msg->message, ap_msg->length);
+			   ap_msg->message, ap_msg->length, ap_msg->special);
 	switch (status.response_code) {
 	case AP_RESPONSE_NORMAL:
 		atomic_inc(&ap_poll_requests);
@@ -1261,6 +1272,7 @@
 		*flags |= 2;
 		break;
 	case AP_RESPONSE_MESSAGE_TOO_BIG:
+	case AP_RESPONSE_REQ_FAC_NOT_INST:
 		return -EINVAL;
 	default:
 		return -ENODEV;
@@ -1302,7 +1314,8 @@
 	if (list_empty(&ap_dev->requestq) &&
 	    ap_dev->queue_count < ap_dev->queue_depth) {
 		status = __ap_send(ap_dev->qid, ap_msg->psmid,
-				   ap_msg->message, ap_msg->length);
+				   ap_msg->message, ap_msg->length,
+				   ap_msg->special);
 		switch (status.response_code) {
 		case AP_RESPONSE_NORMAL:
 			list_add_tail(&ap_msg->list, &ap_dev->pendingq);
@@ -1317,6 +1330,7 @@
 			ap_dev->requestq_count++;
 			ap_dev->total_request_count++;
 			return -EBUSY;
+		case AP_RESPONSE_REQ_FAC_NOT_INST:
 		case AP_RESPONSE_MESSAGE_TOO_BIG:
 			ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL));
 			return -EINVAL;
@@ -1658,6 +1672,7 @@
 	 */
 	if (MACHINE_IS_VM)
 		poll_timeout = 1500000;
+	spin_lock_init(&ap_poll_timer_lock);
 	hrtimer_init(&ap_poll_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
 	ap_poll_timer.function = ap_poll_timeout;
 
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
index a353622..4785d07 100644
--- a/drivers/s390/crypto/ap_bus.h
+++ b/drivers/s390/crypto/ap_bus.h
@@ -87,6 +87,7 @@
 #define AP_RESPONSE_INDEX_TOO_BIG	0x11
 #define AP_RESPONSE_NO_FIRST_PART	0x13
 #define AP_RESPONSE_MESSAGE_TOO_BIG	0x15
+#define AP_RESPONSE_REQ_FAC_NOT_INST	0x16
 
 /*
  * Known device types
@@ -96,8 +97,8 @@
 #define AP_DEVICE_TYPE_PCIXCC	5
 #define AP_DEVICE_TYPE_CEX2A	6
 #define AP_DEVICE_TYPE_CEX2C	7
-#define AP_DEVICE_TYPE_CEX2A2	8
-#define AP_DEVICE_TYPE_CEX2C2	9
+#define AP_DEVICE_TYPE_CEX3A	8
+#define AP_DEVICE_TYPE_CEX3C	9
 
 /*
  * AP reset flag states
@@ -161,12 +162,25 @@
 	size_t length;			/* Message length. */
 
 	void *private;			/* ap driver private pointer. */
+	unsigned int special:1;		/* Used for special commands. */
 };
 
 #define AP_DEVICE(dt)					\
 	.dev_type=(dt),					\
 	.match_flags=AP_DEVICE_ID_MATCH_DEVICE_TYPE,
 
+/**
+ * ap_init_message() - Initialize ap_message.
+ * Initialize a message before using. Otherwise this might result in
+ * unexpected behaviour.
+ */
+static inline void ap_init_message(struct ap_message *ap_msg)
+{
+	ap_msg->psmid = 0;
+	ap_msg->length = 0;
+	ap_msg->special = 0;
+}
+
 /*
  * Note: don't use ap_send/ap_recv after using ap_queue_message
  * for the first time. Otherwise the ap message queue will get
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index 65b6a96..0d4d18b 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -299,9 +299,7 @@
  */
 static int zcrypt_open(struct inode *inode, struct file *filp)
 {
-	lock_kernel();
 	atomic_inc(&zcrypt_open_count);
-	unlock_kernel();
 	return 0;
 }
 
@@ -1009,6 +1007,10 @@
 		       zcrypt_count_type(ZCRYPT_CEX2C));
 	len += sprintf(resp_buff + len, "CEX2A count: %d\n",
 		       zcrypt_count_type(ZCRYPT_CEX2A));
+	len += sprintf(resp_buff + len, "CEX3C count: %d\n",
+		       zcrypt_count_type(ZCRYPT_CEX3C));
+	len += sprintf(resp_buff + len, "CEX3A count: %d\n",
+		       zcrypt_count_type(ZCRYPT_CEX3A));
 	len += sprintf(resp_buff + len, "requestq count: %d\n",
 		       zcrypt_requestq_count());
 	len += sprintf(resp_buff + len, "pendingq count: %d\n",
@@ -1017,7 +1019,7 @@
 		       atomic_read(&zcrypt_open_count));
 	zcrypt_status_mask(workarea);
 	len += sprinthx("Online devices: 1=PCICA 2=PCICC 3=PCIXCC(MCL2) "
-			"4=PCIXCC(MCL3) 5=CEX2C 6=CEX2A",
+			"4=PCIXCC(MCL3) 5=CEX2C 6=CEX2A 7=CEX3C 8=CEX3A",
 			resp_buff+len, workarea, AP_DEVICES);
 	zcrypt_qdepth_mask(workarea);
 	len += sprinthx("Waiting work element counts",
@@ -1095,8 +1097,9 @@
 		 * '0' for no device, '1' for PCICA, '2' for PCICC,
 		 * '3' for PCIXCC_MCL2, '4' for PCIXCC_MCL3,
 		 * '5' for CEX2C and '6' for CEX2A'
+		 * '7' for CEX3C and '8' for CEX3A
 		 */
-		if (*ptr >= '0' && *ptr <= '6')
+		if (*ptr >= '0' && *ptr <= '8')
 			j++;
 		else if (*ptr == 'd' || *ptr == 'D')
 			zcrypt_disable_card(j++);
diff --git a/drivers/s390/crypto/zcrypt_api.h b/drivers/s390/crypto/zcrypt_api.h
index 1d1ec74..8e7ffbf 100644
--- a/drivers/s390/crypto/zcrypt_api.h
+++ b/drivers/s390/crypto/zcrypt_api.h
@@ -71,6 +71,8 @@
 #define ZCRYPT_PCIXCC_MCL3	4
 #define ZCRYPT_CEX2C		5
 #define ZCRYPT_CEX2A		6
+#define ZCRYPT_CEX3C		7
+#define ZCRYPT_CEX3A		8
 
 /**
  * Large random numbers are pulled in 4096 byte chunks from the crypto cards
diff --git a/drivers/s390/crypto/zcrypt_cex2a.c b/drivers/s390/crypto/zcrypt_cex2a.c
index 326ea08..c6fb0aa 100644
--- a/drivers/s390/crypto/zcrypt_cex2a.c
+++ b/drivers/s390/crypto/zcrypt_cex2a.c
@@ -39,17 +39,24 @@
 
 #define CEX2A_MIN_MOD_SIZE	  1	/*    8 bits	*/
 #define CEX2A_MAX_MOD_SIZE	256	/* 2048 bits	*/
+#define CEX3A_MIN_MOD_SIZE	CEX2A_MIN_MOD_SIZE
+#define CEX3A_MAX_MOD_SIZE	CEX2A_MAX_MOD_SIZE
 
 #define CEX2A_SPEED_RATING	970
+#define CEX3A_SPEED_RATING	900 /* Fixme: Needs finetuning */
 
 #define CEX2A_MAX_MESSAGE_SIZE	0x390	/* sizeof(struct type50_crb2_msg)    */
 #define CEX2A_MAX_RESPONSE_SIZE 0x110	/* max outputdatalength + type80_hdr */
 
+#define CEX3A_MAX_MESSAGE_SIZE	CEX2A_MAX_MESSAGE_SIZE
+#define CEX3A_MAX_RESPONSE_SIZE	CEX2A_MAX_RESPONSE_SIZE
+
 #define CEX2A_CLEANUP_TIME	(15*HZ)
+#define CEX3A_CLEANUP_TIME	CEX2A_CLEANUP_TIME
 
 static struct ap_device_id zcrypt_cex2a_ids[] = {
 	{ AP_DEVICE(AP_DEVICE_TYPE_CEX2A) },
-	{ AP_DEVICE(AP_DEVICE_TYPE_CEX2A2) },
+	{ AP_DEVICE(AP_DEVICE_TYPE_CEX3A) },
 	{ /* end of list */ },
 };
 
@@ -298,6 +305,7 @@
 	struct completion work;
 	int rc;
 
+	ap_init_message(&ap_msg);
 	ap_msg.message = kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL);
 	if (!ap_msg.message)
 		return -ENOMEM;
@@ -335,6 +343,7 @@
 	struct completion work;
 	int rc;
 
+	ap_init_message(&ap_msg);
 	ap_msg.message = kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL);
 	if (!ap_msg.message)
 		return -ENOMEM;
@@ -373,31 +382,45 @@
  */
 static int zcrypt_cex2a_probe(struct ap_device *ap_dev)
 {
-	struct zcrypt_device *zdev;
-	int rc;
+	struct zcrypt_device *zdev = NULL;
+	int rc = 0;
 
-	zdev = zcrypt_device_alloc(CEX2A_MAX_RESPONSE_SIZE);
-	if (!zdev)
-		return -ENOMEM;
-	zdev->ap_dev = ap_dev;
-	zdev->ops = &zcrypt_cex2a_ops;
-	zdev->online = 1;
-	zdev->user_space_type = ZCRYPT_CEX2A;
-	zdev->type_string = "CEX2A";
-	zdev->min_mod_size = CEX2A_MIN_MOD_SIZE;
-	zdev->max_mod_size = CEX2A_MAX_MOD_SIZE;
-	zdev->short_crt = 1;
-	zdev->speed_rating = CEX2A_SPEED_RATING;
-	ap_dev->reply = &zdev->reply;
-	ap_dev->private = zdev;
-	rc = zcrypt_device_register(zdev);
-	if (rc)
-		goto out_free;
-	return 0;
-
-out_free:
-	ap_dev->private = NULL;
-	zcrypt_device_free(zdev);
+	switch (ap_dev->device_type) {
+	case AP_DEVICE_TYPE_CEX2A:
+		zdev = zcrypt_device_alloc(CEX2A_MAX_RESPONSE_SIZE);
+		if (!zdev)
+			return -ENOMEM;
+		zdev->user_space_type = ZCRYPT_CEX2A;
+		zdev->type_string = "CEX2A";
+		zdev->min_mod_size = CEX2A_MIN_MOD_SIZE;
+		zdev->max_mod_size = CEX2A_MAX_MOD_SIZE;
+		zdev->short_crt = 1;
+		zdev->speed_rating = CEX2A_SPEED_RATING;
+		break;
+	case AP_DEVICE_TYPE_CEX3A:
+		zdev = zcrypt_device_alloc(CEX3A_MAX_RESPONSE_SIZE);
+		if (!zdev)
+			return -ENOMEM;
+		zdev->user_space_type = ZCRYPT_CEX3A;
+		zdev->type_string = "CEX3A";
+		zdev->min_mod_size = CEX3A_MIN_MOD_SIZE;
+		zdev->max_mod_size = CEX3A_MAX_MOD_SIZE;
+		zdev->short_crt = 1;
+		zdev->speed_rating = CEX3A_SPEED_RATING;
+		break;
+	}
+	if (zdev != NULL) {
+		zdev->ap_dev = ap_dev;
+		zdev->ops = &zcrypt_cex2a_ops;
+		zdev->online = 1;
+		ap_dev->reply = &zdev->reply;
+		ap_dev->private = zdev;
+		rc = zcrypt_device_register(zdev);
+	}
+	if (rc) {
+		ap_dev->private = NULL;
+		zcrypt_device_free(zdev);
+	}
 	return rc;
 }
 
diff --git a/drivers/s390/crypto/zcrypt_pcica.c b/drivers/s390/crypto/zcrypt_pcica.c
index 17ba81b..e78df36 100644
--- a/drivers/s390/crypto/zcrypt_pcica.c
+++ b/drivers/s390/crypto/zcrypt_pcica.c
@@ -281,6 +281,7 @@
 	struct completion work;
 	int rc;
 
+	ap_init_message(&ap_msg);
 	ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL);
 	if (!ap_msg.message)
 		return -ENOMEM;
@@ -318,6 +319,7 @@
 	struct completion work;
 	int rc;
 
+	ap_init_message(&ap_msg);
 	ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL);
 	if (!ap_msg.message)
 		return -ENOMEM;
diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c
index f4b0c47..a23726a 100644
--- a/drivers/s390/crypto/zcrypt_pcicc.c
+++ b/drivers/s390/crypto/zcrypt_pcicc.c
@@ -483,6 +483,7 @@
 	struct completion work;
 	int rc;
 
+	ap_init_message(&ap_msg);
 	ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
 	if (!ap_msg.message)
 		return -ENOMEM;
@@ -521,6 +522,7 @@
 	struct completion work;
 	int rc;
 
+	ap_init_message(&ap_msg);
 	ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
 	if (!ap_msg.message)
 		return -ENOMEM;
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
index 5677b40..79c1205 100644
--- a/drivers/s390/crypto/zcrypt_pcixcc.c
+++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -43,10 +43,13 @@
 #define PCIXCC_MIN_MOD_SIZE	 16	/*  128 bits	*/
 #define PCIXCC_MIN_MOD_SIZE_OLD	 64	/*  512 bits	*/
 #define PCIXCC_MAX_MOD_SIZE	256	/* 2048 bits	*/
+#define CEX3C_MIN_MOD_SIZE	PCIXCC_MIN_MOD_SIZE
+#define CEX3C_MAX_MOD_SIZE	PCIXCC_MAX_MOD_SIZE
 
-#define PCIXCC_MCL2_SPEED_RATING	7870	/* FIXME: needs finetuning */
+#define PCIXCC_MCL2_SPEED_RATING	7870
 #define PCIXCC_MCL3_SPEED_RATING	7870
-#define CEX2C_SPEED_RATING		8540
+#define CEX2C_SPEED_RATING		7000
+#define CEX3C_SPEED_RATING		6500	/* FIXME: needs finetuning */
 
 #define PCIXCC_MAX_ICA_MESSAGE_SIZE 0x77c  /* max size type6 v2 crt message */
 #define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply	    */
@@ -72,7 +75,7 @@
 static struct ap_device_id zcrypt_pcixcc_ids[] = {
 	{ AP_DEVICE(AP_DEVICE_TYPE_PCIXCC) },
 	{ AP_DEVICE(AP_DEVICE_TYPE_CEX2C) },
-	{ AP_DEVICE(AP_DEVICE_TYPE_CEX2C2) },
+	{ AP_DEVICE(AP_DEVICE_TYPE_CEX3C) },
 	{ /* end of list */ },
 };
 
@@ -326,6 +329,11 @@
 	function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len;
 	memcpy(msg->hdr.function_code, function_code, sizeof(msg->hdr.function_code));
 
+	if (memcmp(function_code, "US", 2) == 0)
+		ap_msg->special = 1;
+	else
+		ap_msg->special = 0;
+
 	/* copy data block */
 	if (xcRB->request_data_length &&
 	    copy_from_user(req_data, xcRB->request_data_address,
@@ -688,6 +696,7 @@
 	};
 	int rc;
 
+	ap_init_message(&ap_msg);
 	ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
 	if (!ap_msg.message)
 		return -ENOMEM;
@@ -727,6 +736,7 @@
 	};
 	int rc;
 
+	ap_init_message(&ap_msg);
 	ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
 	if (!ap_msg.message)
 		return -ENOMEM;
@@ -766,6 +776,7 @@
 	};
 	int rc;
 
+	ap_init_message(&ap_msg);
 	ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
 	if (!ap_msg.message)
 		return -ENOMEM;
@@ -805,6 +816,7 @@
 	};
 	int rc;
 
+	ap_init_message(&ap_msg);
 	ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
 	if (!ap_msg.message)
 		return -ENOMEM;
@@ -972,6 +984,7 @@
 	} __attribute__((packed)) *reply;
 	int rc, i;
 
+	ap_init_message(&ap_msg);
 	ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
 	if (!ap_msg.message)
 		return -ENOMEM;
@@ -1016,14 +1029,15 @@
 static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
 {
 	struct zcrypt_device *zdev;
-	int rc;
+	int rc = 0;
 
 	zdev = zcrypt_device_alloc(PCIXCC_MAX_RESPONSE_SIZE);
 	if (!zdev)
 		return -ENOMEM;
 	zdev->ap_dev = ap_dev;
 	zdev->online = 1;
-	if (ap_dev->device_type == AP_DEVICE_TYPE_PCIXCC) {
+	switch (ap_dev->device_type) {
+	case AP_DEVICE_TYPE_PCIXCC:
 		rc = zcrypt_pcixcc_mcl(ap_dev);
 		if (rc < 0) {
 			zcrypt_device_free(zdev);
@@ -1041,13 +1055,25 @@
 			zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
 			zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
 		}
-	} else {
+		break;
+	case AP_DEVICE_TYPE_CEX2C:
 		zdev->user_space_type = ZCRYPT_CEX2C;
 		zdev->type_string = "CEX2C";
 		zdev->speed_rating = CEX2C_SPEED_RATING;
 		zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
 		zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
+		break;
+	case AP_DEVICE_TYPE_CEX3C:
+		zdev->user_space_type = ZCRYPT_CEX3C;
+		zdev->type_string = "CEX3C";
+		zdev->speed_rating = CEX3C_SPEED_RATING;
+		zdev->min_mod_size = CEX3C_MIN_MOD_SIZE;
+		zdev->max_mod_size = CEX3C_MAX_MOD_SIZE;
+		break;
+	default:
+		goto out_free;
 	}
+
 	rc = zcrypt_pcixcc_rng_supported(ap_dev);
 	if (rc < 0) {
 		zcrypt_device_free(zdev);
diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h
index 52c0343..1ba5115 100644
--- a/drivers/s390/net/qeth_core_mpc.h
+++ b/drivers/s390/net/qeth_core_mpc.h
@@ -528,7 +528,7 @@
 		(PDU_ENCAPSULATION(buffer) + 0x17)
 #define QETH_ULP_ENABLE_RESP_LINK_TYPE(buffer) \
 		(PDU_ENCAPSULATION(buffer) + 0x2b)
-/* Layer 2 defintions */
+/* Layer 2 definitions */
 #define QETH_PROT_LAYER2 0x08
 #define QETH_PROT_TCPIP  0x03
 #define QETH_PROT_OSN2   0x0a
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 2889e5f..9d0c941 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -31,6 +31,7 @@
 #include <linux/miscdevice.h>
 #include <linux/seq_file.h>
 #include "zfcp_ext.h"
+#include "zfcp_fc.h"
 
 #define ZFCP_BUS_ID_SIZE	20
 
@@ -80,48 +81,40 @@
 
 static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
 {
-	struct ccw_device *ccwdev;
+	struct ccw_device *cdev;
 	struct zfcp_adapter *adapter;
 	struct zfcp_port *port;
 	struct zfcp_unit *unit;
 
-	ccwdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
-	if (!ccwdev)
+	cdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
+	if (!cdev)
 		return;
 
-	if (ccw_device_set_online(ccwdev))
-		goto out_ccwdev;
+	if (ccw_device_set_online(cdev))
+		goto out_ccw_device;
 
-	mutex_lock(&zfcp_data.config_mutex);
-	adapter = dev_get_drvdata(&ccwdev->dev);
+	adapter = zfcp_ccw_adapter_by_cdev(cdev);
 	if (!adapter)
-		goto out_unlock;
-	zfcp_adapter_get(adapter);
+		goto out_ccw_device;
 
 	port = zfcp_get_port_by_wwpn(adapter, wwpn);
 	if (!port)
 		goto out_port;
 
-	zfcp_port_get(port);
 	unit = zfcp_unit_enqueue(port, lun);
 	if (IS_ERR(unit))
 		goto out_unit;
-	mutex_unlock(&zfcp_data.config_mutex);
 
 	zfcp_erp_unit_reopen(unit, 0, "auidc_1", NULL);
 	zfcp_erp_wait(adapter);
 	flush_work(&unit->scsi_work);
 
-	mutex_lock(&zfcp_data.config_mutex);
-	zfcp_unit_put(unit);
 out_unit:
-	zfcp_port_put(port);
+	put_device(&port->sysfs_device);
 out_port:
-	zfcp_adapter_put(adapter);
-out_unlock:
-	mutex_unlock(&zfcp_data.config_mutex);
-out_ccwdev:
-	put_device(&ccwdev->dev);
+	zfcp_ccw_adapter_put(adapter);
+out_ccw_device:
+	put_device(&cdev->dev);
 	return;
 }
 
@@ -167,7 +160,7 @@
 	int retval = -ENOMEM;
 
 	zfcp_data.gpn_ft_cache = zfcp_cache_hw_align("zfcp_gpn",
-					sizeof(struct ct_iu_gpn_ft_req));
+					sizeof(struct zfcp_fc_gpn_ft_req));
 	if (!zfcp_data.gpn_ft_cache)
 		goto out;
 
@@ -182,12 +175,14 @@
 		goto out_sr_cache;
 
 	zfcp_data.gid_pn_cache = zfcp_cache_hw_align("zfcp_gid",
-					sizeof(struct zfcp_gid_pn_data));
+					sizeof(struct zfcp_fc_gid_pn));
 	if (!zfcp_data.gid_pn_cache)
 		goto out_gid_cache;
 
-	mutex_init(&zfcp_data.config_mutex);
-	rwlock_init(&zfcp_data.config_lock);
+	zfcp_data.adisc_cache = zfcp_cache_hw_align("zfcp_adisc",
+					sizeof(struct zfcp_fc_els_adisc));
+	if (!zfcp_data.adisc_cache)
+		goto out_adisc_cache;
 
 	zfcp_data.scsi_transport_template =
 		fc_attach_transport(&zfcp_transport_functions);
@@ -200,7 +195,7 @@
 		goto out_misc;
 	}
 
-	retval = zfcp_ccw_register();
+	retval = ccw_driver_register(&zfcp_ccw_driver);
 	if (retval) {
 		pr_err("The zfcp device driver could not register with "
 		       "the common I/O layer\n");
@@ -216,6 +211,8 @@
 out_misc:
 	fc_release_transport(zfcp_data.scsi_transport_template);
 out_transport:
+	kmem_cache_destroy(zfcp_data.adisc_cache);
+out_adisc_cache:
 	kmem_cache_destroy(zfcp_data.gid_pn_cache);
 out_gid_cache:
 	kmem_cache_destroy(zfcp_data.sr_buffer_cache);
@@ -229,6 +226,20 @@
 
 module_init(zfcp_module_init);
 
+static void __exit zfcp_module_exit(void)
+{
+	ccw_driver_unregister(&zfcp_ccw_driver);
+	misc_deregister(&zfcp_cfdc_misc);
+	fc_release_transport(zfcp_data.scsi_transport_template);
+	kmem_cache_destroy(zfcp_data.adisc_cache);
+	kmem_cache_destroy(zfcp_data.gid_pn_cache);
+	kmem_cache_destroy(zfcp_data.sr_buffer_cache);
+	kmem_cache_destroy(zfcp_data.qtcb_cache);
+	kmem_cache_destroy(zfcp_data.gpn_ft_cache);
+}
+
+module_exit(zfcp_module_exit);
+
 /**
  * zfcp_get_unit_by_lun - find unit in unit list of port by FCP LUN
  * @port: pointer to port to search for unit
@@ -238,12 +249,18 @@
  */
 struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *port, u64 fcp_lun)
 {
+	unsigned long flags;
 	struct zfcp_unit *unit;
 
-	list_for_each_entry(unit, &port->unit_list_head, list)
-		if ((unit->fcp_lun == fcp_lun) &&
-		    !(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_REMOVE))
-		    return unit;
+	read_lock_irqsave(&port->unit_list_lock, flags);
+	list_for_each_entry(unit, &port->unit_list, list)
+		if (unit->fcp_lun == fcp_lun) {
+			if (!get_device(&unit->sysfs_device))
+				unit = NULL;
+			read_unlock_irqrestore(&port->unit_list_lock, flags);
+			return unit;
+		}
+	read_unlock_irqrestore(&port->unit_list_lock, flags);
 	return NULL;
 }
 
@@ -257,18 +274,35 @@
 struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *adapter,
 					u64 wwpn)
 {
+	unsigned long flags;
 	struct zfcp_port *port;
 
-	list_for_each_entry(port, &adapter->port_list_head, list)
-		if ((port->wwpn == wwpn) &&
-		    !(atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE))
+	read_lock_irqsave(&adapter->port_list_lock, flags);
+	list_for_each_entry(port, &adapter->port_list, list)
+		if (port->wwpn == wwpn) {
+			if (!get_device(&port->sysfs_device))
+				port = NULL;
+			read_unlock_irqrestore(&adapter->port_list_lock, flags);
 			return port;
+		}
+	read_unlock_irqrestore(&adapter->port_list_lock, flags);
 	return NULL;
 }
 
-static void zfcp_sysfs_unit_release(struct device *dev)
+/**
+ * zfcp_unit_release - dequeue unit
+ * @dev: pointer to device
+ *
+ * waits until all work is done on unit and removes it then from the unit->list
+ * of the associated port.
+ */
+static void zfcp_unit_release(struct device *dev)
 {
-	kfree(container_of(dev, struct zfcp_unit, sysfs_device));
+	struct zfcp_unit *unit = container_of(dev, struct zfcp_unit,
+					      sysfs_device);
+
+	put_device(&unit->port->sysfs_device);
+	kfree(unit);
 }
 
 /**
@@ -276,43 +310,40 @@
  * @port: pointer to port where unit is added
  * @fcp_lun: FCP LUN of unit to be enqueued
  * Returns: pointer to enqueued unit on success, ERR_PTR on error
- * Locks: config_mutex must be held to serialize changes to the unit list
  *
  * Sets up some unit internal structures and creates sysfs entry.
  */
 struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
 {
 	struct zfcp_unit *unit;
+	int retval = -ENOMEM;
 
-	read_lock_irq(&zfcp_data.config_lock);
-	if (zfcp_get_unit_by_lun(port, fcp_lun)) {
-		read_unlock_irq(&zfcp_data.config_lock);
-		return ERR_PTR(-EINVAL);
+	get_device(&port->sysfs_device);
+
+	unit = zfcp_get_unit_by_lun(port, fcp_lun);
+	if (unit) {
+		put_device(&unit->sysfs_device);
+		retval = -EEXIST;
+		goto err_out;
 	}
-	read_unlock_irq(&zfcp_data.config_lock);
 
 	unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL);
 	if (!unit)
-		return ERR_PTR(-ENOMEM);
-
-	atomic_set(&unit->refcount, 0);
-	init_waitqueue_head(&unit->remove_wq);
-	INIT_WORK(&unit->scsi_work, zfcp_scsi_scan);
+		goto err_out;
 
 	unit->port = port;
 	unit->fcp_lun = fcp_lun;
+	unit->sysfs_device.parent = &port->sysfs_device;
+	unit->sysfs_device.release = zfcp_unit_release;
 
 	if (dev_set_name(&unit->sysfs_device, "0x%016llx",
 			 (unsigned long long) fcp_lun)) {
 		kfree(unit);
-		return ERR_PTR(-ENOMEM);
+		goto err_out;
 	}
-	unit->sysfs_device.parent = &port->sysfs_device;
-	unit->sysfs_device.release = zfcp_sysfs_unit_release;
-	dev_set_drvdata(&unit->sysfs_device, unit);
+	retval = -EINVAL;
 
-	/* mark unit unusable as long as sysfs registration is not complete */
-	atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
+	INIT_WORK(&unit->scsi_work, zfcp_scsi_scan);
 
 	spin_lock_init(&unit->latencies.lock);
 	unit->latencies.write.channel.min = 0xFFFFFFFF;
@@ -324,50 +355,30 @@
 
 	if (device_register(&unit->sysfs_device)) {
 		put_device(&unit->sysfs_device);
-		return ERR_PTR(-EINVAL);
+		goto err_out;
 	}
 
 	if (sysfs_create_group(&unit->sysfs_device.kobj,
-			       &zfcp_sysfs_unit_attrs)) {
-		device_unregister(&unit->sysfs_device);
-		return ERR_PTR(-EINVAL);
-	}
+			       &zfcp_sysfs_unit_attrs))
+		goto err_out_put;
 
-	zfcp_unit_get(unit);
+	write_lock_irq(&port->unit_list_lock);
+	list_add_tail(&unit->list, &port->unit_list);
+	write_unlock_irq(&port->unit_list_lock);
 
-	write_lock_irq(&zfcp_data.config_lock);
-	list_add_tail(&unit->list, &port->unit_list_head);
-	atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
 	atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status);
 
-	write_unlock_irq(&zfcp_data.config_lock);
-
-	zfcp_port_get(port);
-
 	return unit;
-}
 
-/**
- * zfcp_unit_dequeue - dequeue unit
- * @unit: pointer to zfcp_unit
- *
- * waits until all work is done on unit and removes it then from the unit->list
- * of the associated port.
- */
-void zfcp_unit_dequeue(struct zfcp_unit *unit)
-{
-	wait_event(unit->remove_wq, atomic_read(&unit->refcount) == 0);
-	write_lock_irq(&zfcp_data.config_lock);
-	list_del(&unit->list);
-	write_unlock_irq(&zfcp_data.config_lock);
-	zfcp_port_put(unit->port);
-	sysfs_remove_group(&unit->sysfs_device.kobj, &zfcp_sysfs_unit_attrs);
+err_out_put:
 	device_unregister(&unit->sysfs_device);
+err_out:
+	put_device(&port->sysfs_device);
+	return ERR_PTR(retval);
 }
 
 static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
 {
-	/* must only be called with zfcp_data.config_mutex taken */
 	adapter->pool.erp_req =
 		mempool_create_kmalloc_pool(1, sizeof(struct zfcp_fsf_req));
 	if (!adapter->pool.erp_req)
@@ -405,9 +416,9 @@
 	if (!adapter->pool.status_read_data)
 		return -ENOMEM;
 
-	adapter->pool.gid_pn_data =
+	adapter->pool.gid_pn =
 		mempool_create_slab_pool(1, zfcp_data.gid_pn_cache);
-	if (!adapter->pool.gid_pn_data)
+	if (!adapter->pool.gid_pn)
 		return -ENOMEM;
 
 	return 0;
@@ -415,7 +426,6 @@
 
 static void zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter)
 {
-	/* zfcp_data.config_mutex must be held */
 	if (adapter->pool.erp_req)
 		mempool_destroy(adapter->pool.erp_req);
 	if (adapter->pool.scsi_req)
@@ -428,8 +438,8 @@
 		mempool_destroy(adapter->pool.status_read_req);
 	if (adapter->pool.status_read_data)
 		mempool_destroy(adapter->pool.status_read_data);
-	if (adapter->pool.gid_pn_data)
-		mempool_destroy(adapter->pool.gid_pn_data);
+	if (adapter->pool.gid_pn)
+		mempool_destroy(adapter->pool.gid_pn);
 }
 
 /**
@@ -497,53 +507,56 @@
  * zfcp_adapter_enqueue - enqueue a new adapter to the list
  * @ccw_device: pointer to the struct cc_device
  *
- * Returns:	0             if a new adapter was successfully enqueued
- *		-ENOMEM       if alloc failed
+ * Returns:	struct zfcp_adapter*
  * Enqueues an adapter at the end of the adapter list in the driver data.
  * All adapter internal structures are set up.
  * Proc-fs entries are also created.
- * locks: config_mutex must be held to serialize changes to the adapter list
  */
-int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
+struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device)
 {
 	struct zfcp_adapter *adapter;
 
-	/*
-	 * Note: It is safe to release the list_lock, as any list changes
-	 * are protected by the config_mutex, which must be held to get here
-	 */
+	if (!get_device(&ccw_device->dev))
+		return ERR_PTR(-ENODEV);
 
 	adapter = kzalloc(sizeof(struct zfcp_adapter), GFP_KERNEL);
-	if (!adapter)
-		return -ENOMEM;
+	if (!adapter) {
+		put_device(&ccw_device->dev);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	kref_init(&adapter->ref);
 
 	ccw_device->handler = NULL;
 	adapter->ccw_device = ccw_device;
-	atomic_set(&adapter->refcount, 0);
+
+	INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler);
+	INIT_WORK(&adapter->scan_work, zfcp_fc_scan_ports);
 
 	if (zfcp_qdio_setup(adapter))
-		goto qdio_failed;
+		goto failed;
 
 	if (zfcp_allocate_low_mem_buffers(adapter))
-		goto low_mem_buffers_failed;
+		goto failed;
 
 	if (zfcp_reqlist_alloc(adapter))
-		goto low_mem_buffers_failed;
+		goto failed;
 
 	if (zfcp_dbf_adapter_register(adapter))
-		goto debug_register_failed;
+		goto failed;
 
 	if (zfcp_setup_adapter_work_queue(adapter))
-		goto work_queue_failed;
+		goto failed;
 
 	if (zfcp_fc_gs_setup(adapter))
-		goto generic_services_failed;
+		goto failed;
 
-	init_waitqueue_head(&adapter->remove_wq);
+	rwlock_init(&adapter->port_list_lock);
+	INIT_LIST_HEAD(&adapter->port_list);
+
 	init_waitqueue_head(&adapter->erp_ready_wq);
 	init_waitqueue_head(&adapter->erp_done_wqh);
 
-	INIT_LIST_HEAD(&adapter->port_list_head);
 	INIT_LIST_HEAD(&adapter->erp_ready_head);
 	INIT_LIST_HEAD(&adapter->erp_running_head);
 
@@ -553,83 +566,85 @@
 	rwlock_init(&adapter->abort_lock);
 
 	if (zfcp_erp_thread_setup(adapter))
-		goto erp_thread_failed;
-
-	INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler);
-	INIT_WORK(&adapter->scan_work, _zfcp_fc_scan_ports_later);
+		goto failed;
 
 	adapter->service_level.seq_print = zfcp_print_sl;
 
-	/* mark adapter unusable as long as sysfs registration is not complete */
-	atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
-
 	dev_set_drvdata(&ccw_device->dev, adapter);
 
 	if (sysfs_create_group(&ccw_device->dev.kobj,
 			       &zfcp_sysfs_adapter_attrs))
-		goto sysfs_failed;
-
-	atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
+		goto failed;
 
 	if (!zfcp_adapter_scsi_register(adapter))
-		return 0;
+		return adapter;
 
-sysfs_failed:
-	zfcp_erp_thread_kill(adapter);
-erp_thread_failed:
-	zfcp_fc_gs_destroy(adapter);
-generic_services_failed:
+failed:
+	zfcp_adapter_unregister(adapter);
+	return ERR_PTR(-ENOMEM);
+}
+
+void zfcp_adapter_unregister(struct zfcp_adapter *adapter)
+{
+	struct ccw_device *cdev = adapter->ccw_device;
+
+	cancel_work_sync(&adapter->scan_work);
+	cancel_work_sync(&adapter->stat_work);
 	zfcp_destroy_adapter_work_queue(adapter);
-work_queue_failed:
+
+	zfcp_fc_wka_ports_force_offline(adapter->gs);
+	zfcp_adapter_scsi_unregister(adapter);
+	sysfs_remove_group(&cdev->dev.kobj, &zfcp_sysfs_adapter_attrs);
+
+	zfcp_erp_thread_kill(adapter);
 	zfcp_dbf_adapter_unregister(adapter->dbf);
-debug_register_failed:
-	dev_set_drvdata(&ccw_device->dev, NULL);
-	kfree(adapter->req_list);
-low_mem_buffers_failed:
-	zfcp_free_low_mem_buffers(adapter);
-qdio_failed:
 	zfcp_qdio_destroy(adapter->qdio);
-	kfree(adapter);
-	return -ENOMEM;
+
+	zfcp_ccw_adapter_put(adapter); /* final put to release */
 }
 
 /**
- * zfcp_adapter_dequeue - remove the adapter from the resource list
- * @adapter: pointer to struct zfcp_adapter which should be removed
+ * zfcp_adapter_release - remove the adapter from the resource list
+ * @ref: pointer to struct kref
  * locks:	adapter list write lock is assumed to be held by caller
  */
-void zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
+void zfcp_adapter_release(struct kref *ref)
 {
-	int retval = 0;
-	unsigned long flags;
+	struct zfcp_adapter *adapter = container_of(ref, struct zfcp_adapter,
+						    ref);
+	struct ccw_device *cdev = adapter->ccw_device;
 
-	cancel_work_sync(&adapter->stat_work);
-	zfcp_fc_wka_ports_force_offline(adapter->gs);
-	sysfs_remove_group(&adapter->ccw_device->dev.kobj,
-			   &zfcp_sysfs_adapter_attrs);
 	dev_set_drvdata(&adapter->ccw_device->dev, NULL);
-	/* sanity check: no pending FSF requests */
-	spin_lock_irqsave(&adapter->req_list_lock, flags);
-	retval = zfcp_reqlist_isempty(adapter);
-	spin_unlock_irqrestore(&adapter->req_list_lock, flags);
-	if (!retval)
-		return;
-
 	zfcp_fc_gs_destroy(adapter);
-	zfcp_erp_thread_kill(adapter);
-	zfcp_destroy_adapter_work_queue(adapter);
-	zfcp_dbf_adapter_unregister(adapter->dbf);
 	zfcp_free_low_mem_buffers(adapter);
-	zfcp_qdio_destroy(adapter->qdio);
 	kfree(adapter->req_list);
 	kfree(adapter->fc_stats);
 	kfree(adapter->stats_reset_data);
 	kfree(adapter);
+	put_device(&cdev->dev);
 }
 
-static void zfcp_sysfs_port_release(struct device *dev)
+/**
+ * zfcp_device_unregister - remove port, unit from system
+ * @dev: reference to device which is to be removed
+ * @grp: related reference to attribute group
+ *
+ * Helper function to unregister port, unit from system
+ */
+void zfcp_device_unregister(struct device *dev,
+			    const struct attribute_group *grp)
 {
-	kfree(container_of(dev, struct zfcp_port, sysfs_device));
+	sysfs_remove_group(&dev->kobj, grp);
+	device_unregister(dev);
+}
+
+static void zfcp_port_release(struct device *dev)
+{
+	struct zfcp_port *port = container_of(dev, struct zfcp_port,
+					      sysfs_device);
+
+	zfcp_ccw_adapter_put(port->adapter);
+	kfree(port);
 }
 
 /**
@@ -639,7 +654,6 @@
  * @status: initial status for the port
  * @d_id: destination id of the remote port to be enqueued
  * Returns: pointer to enqueued port on success, ERR_PTR on error
- * Locks: config_mutex must be held to serialize changes to the port list
  *
  * All port internal structures are set up and the sysfs entry is generated.
  * d_id is used to enqueue ports with a well known address like the Directory
@@ -649,20 +663,24 @@
 				     u32 status, u32 d_id)
 {
 	struct zfcp_port *port;
+	int retval = -ENOMEM;
 
-	read_lock_irq(&zfcp_data.config_lock);
-	if (zfcp_get_port_by_wwpn(adapter, wwpn)) {
-		read_unlock_irq(&zfcp_data.config_lock);
-		return ERR_PTR(-EINVAL);
+	kref_get(&adapter->ref);
+
+	port = zfcp_get_port_by_wwpn(adapter, wwpn);
+	if (port) {
+		put_device(&port->sysfs_device);
+		retval = -EEXIST;
+		goto err_out;
 	}
-	read_unlock_irq(&zfcp_data.config_lock);
 
 	port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL);
 	if (!port)
-		return ERR_PTR(-ENOMEM);
+		goto err_out;
 
-	init_waitqueue_head(&port->remove_wq);
-	INIT_LIST_HEAD(&port->unit_list_head);
+	rwlock_init(&port->unit_list_lock);
+	INIT_LIST_HEAD(&port->unit_list);
+
 	INIT_WORK(&port->gid_pn_work, zfcp_fc_port_did_lookup);
 	INIT_WORK(&port->test_link_work, zfcp_fc_link_test_work);
 	INIT_WORK(&port->rport_work, zfcp_scsi_rport_work);
@@ -671,58 +689,38 @@
 	port->d_id = d_id;
 	port->wwpn = wwpn;
 	port->rport_task = RPORT_NONE;
-
-	/* mark port unusable as long as sysfs registration is not complete */
-	atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status);
-	atomic_set(&port->refcount, 0);
+	port->sysfs_device.parent = &adapter->ccw_device->dev;
+	port->sysfs_device.release = zfcp_port_release;
 
 	if (dev_set_name(&port->sysfs_device, "0x%016llx",
 			 (unsigned long long)wwpn)) {
 		kfree(port);
-		return ERR_PTR(-ENOMEM);
+		goto err_out;
 	}
-	port->sysfs_device.parent = &adapter->ccw_device->dev;
-	port->sysfs_device.release = zfcp_sysfs_port_release;
-	dev_set_drvdata(&port->sysfs_device, port);
+	retval = -EINVAL;
 
 	if (device_register(&port->sysfs_device)) {
 		put_device(&port->sysfs_device);
-		return ERR_PTR(-EINVAL);
+		goto err_out;
 	}
 
 	if (sysfs_create_group(&port->sysfs_device.kobj,
-			       &zfcp_sysfs_port_attrs)) {
-		device_unregister(&port->sysfs_device);
-		return ERR_PTR(-EINVAL);
-	}
+			       &zfcp_sysfs_port_attrs))
+		goto err_out_put;
 
-	zfcp_port_get(port);
+	write_lock_irq(&adapter->port_list_lock);
+	list_add_tail(&port->list, &adapter->port_list);
+	write_unlock_irq(&adapter->port_list_lock);
 
-	write_lock_irq(&zfcp_data.config_lock);
-	list_add_tail(&port->list, &adapter->port_list_head);
-	atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
-	atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status);
+	atomic_set_mask(status | ZFCP_STATUS_COMMON_RUNNING, &port->status);
 
-	write_unlock_irq(&zfcp_data.config_lock);
-
-	zfcp_adapter_get(adapter);
 	return port;
-}
 
-/**
- * zfcp_port_dequeue - dequeues a port from the port list of the adapter
- * @port: pointer to struct zfcp_port which should be removed
- */
-void zfcp_port_dequeue(struct zfcp_port *port)
-{
-	write_lock_irq(&zfcp_data.config_lock);
-	list_del(&port->list);
-	write_unlock_irq(&zfcp_data.config_lock);
-	wait_event(port->remove_wq, atomic_read(&port->refcount) == 0);
-	cancel_work_sync(&port->rport_work); /* usually not necessary */
-	zfcp_adapter_put(port->adapter);
-	sysfs_remove_group(&port->sysfs_device.kobj, &zfcp_sysfs_port_attrs);
+err_out_put:
 	device_unregister(&port->sysfs_device);
+err_out:
+	zfcp_ccw_adapter_put(adapter);
+	return ERR_PTR(retval);
 }
 
 /**
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index e083394..c22cb72 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -13,28 +13,34 @@
 
 #define ZFCP_MODEL_PRIV 0x4
 
-static int zfcp_ccw_suspend(struct ccw_device *cdev)
+static DEFINE_SPINLOCK(zfcp_ccw_adapter_ref_lock);
 
+struct zfcp_adapter *zfcp_ccw_adapter_by_cdev(struct ccw_device *cdev)
 {
-	struct zfcp_adapter *adapter = dev_get_drvdata(&cdev->dev);
+	struct zfcp_adapter *adapter;
+	unsigned long flags;
 
-	if (!adapter)
-		return 0;
+	spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags);
+	adapter = dev_get_drvdata(&cdev->dev);
+	if (adapter)
+		kref_get(&adapter->ref);
+	spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
+	return adapter;
+}
 
-	mutex_lock(&zfcp_data.config_mutex);
+void zfcp_ccw_adapter_put(struct zfcp_adapter *adapter)
+{
+	unsigned long flags;
 
-	zfcp_erp_adapter_shutdown(adapter, 0, "ccsusp1", NULL);
-	zfcp_erp_wait(adapter);
-
-	mutex_unlock(&zfcp_data.config_mutex);
-
-	return 0;
+	spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags);
+	kref_put(&adapter->ref, zfcp_adapter_release);
+	spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
 }
 
 static int zfcp_ccw_activate(struct ccw_device *cdev)
 
 {
-	struct zfcp_adapter *adapter = dev_get_drvdata(&cdev->dev);
+	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
 
 	if (!adapter)
 		return 0;
@@ -46,6 +52,8 @@
 	zfcp_erp_wait(adapter);
 	flush_work(&adapter->scan_work);
 
+	zfcp_ccw_adapter_put(adapter);
+
 	return 0;
 }
 
@@ -67,28 +75,28 @@
 
 /**
  * zfcp_ccw_probe - probe function of zfcp driver
- * @ccw_device: pointer to belonging ccw device
+ * @cdev: pointer to belonging ccw device
  *
  * This function gets called by the common i/o layer for each FCP
  * device found on the current system. This is only a stub to make cio
  * work: To only allocate adapter resources for devices actually used,
  * the allocation is deferred to the first call to ccw_set_online.
  */
-static int zfcp_ccw_probe(struct ccw_device *ccw_device)
+static int zfcp_ccw_probe(struct ccw_device *cdev)
 {
 	return 0;
 }
 
 /**
  * zfcp_ccw_remove - remove function of zfcp driver
- * @ccw_device: pointer to belonging ccw device
+ * @cdev: pointer to belonging ccw device
  *
  * This function gets called by the common i/o layer and removes an adapter
  * from the system. Task of this function is to get rid of all units and
  * ports that belong to this adapter. And in addition all resources of this
  * adapter will be freed too.
  */
-static void zfcp_ccw_remove(struct ccw_device *ccw_device)
+static void zfcp_ccw_remove(struct ccw_device *cdev)
 {
 	struct zfcp_adapter *adapter;
 	struct zfcp_port *port, *p;
@@ -96,49 +104,37 @@
 	LIST_HEAD(unit_remove_lh);
 	LIST_HEAD(port_remove_lh);
 
-	ccw_device_set_offline(ccw_device);
+	ccw_device_set_offline(cdev);
 
-	mutex_lock(&zfcp_data.config_mutex);
-	adapter = dev_get_drvdata(&ccw_device->dev);
+	adapter = zfcp_ccw_adapter_by_cdev(cdev);
 	if (!adapter)
-		goto out;
-	mutex_unlock(&zfcp_data.config_mutex);
+		return;
 
-	cancel_work_sync(&adapter->scan_work);
-
-	mutex_lock(&zfcp_data.config_mutex);
-
-	/* this also removes the scsi devices, so call it first */
-	zfcp_adapter_scsi_unregister(adapter);
-
-	write_lock_irq(&zfcp_data.config_lock);
-	list_for_each_entry_safe(port, p, &adapter->port_list_head, list) {
-		list_for_each_entry_safe(unit, u, &port->unit_list_head, list) {
+	write_lock_irq(&adapter->port_list_lock);
+	list_for_each_entry_safe(port, p, &adapter->port_list, list) {
+		write_lock(&port->unit_list_lock);
+		list_for_each_entry_safe(unit, u, &port->unit_list, list)
 			list_move(&unit->list, &unit_remove_lh);
-			atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE,
-					&unit->status);
-		}
+		write_unlock(&port->unit_list_lock);
 		list_move(&port->list, &port_remove_lh);
-		atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
 	}
-	atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
-	write_unlock_irq(&zfcp_data.config_lock);
+	write_unlock_irq(&adapter->port_list_lock);
+	zfcp_ccw_adapter_put(adapter); /* put from zfcp_ccw_adapter_by_cdev */
 
-	list_for_each_entry_safe(port, p, &port_remove_lh, list) {
-		list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
-			zfcp_unit_dequeue(unit);
-		zfcp_port_dequeue(port);
-	}
-	wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0);
-	zfcp_adapter_dequeue(adapter);
+	list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
+		zfcp_device_unregister(&unit->sysfs_device,
+				       &zfcp_sysfs_unit_attrs);
 
-out:
-	mutex_unlock(&zfcp_data.config_mutex);
+	list_for_each_entry_safe(port, p, &port_remove_lh, list)
+		zfcp_device_unregister(&port->sysfs_device,
+				       &zfcp_sysfs_port_attrs);
+
+	zfcp_adapter_unregister(adapter);
 }
 
 /**
  * zfcp_ccw_set_online - set_online function of zfcp driver
- * @ccw_device: pointer to belonging ccw device
+ * @cdev: pointer to belonging ccw device
  *
  * This function gets called by the common i/o layer and sets an
  * adapter into state online.  The first call will allocate all
@@ -149,23 +145,20 @@
  * the SCSI stack, that the QDIO queues will be set up and that the
  * adapter will be opened.
  */
-static int zfcp_ccw_set_online(struct ccw_device *ccw_device)
+static int zfcp_ccw_set_online(struct ccw_device *cdev)
 {
-	struct zfcp_adapter *adapter;
-	int ret = 0;
-
-	mutex_lock(&zfcp_data.config_mutex);
-	adapter = dev_get_drvdata(&ccw_device->dev);
+	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
 
 	if (!adapter) {
-		ret = zfcp_adapter_enqueue(ccw_device);
-		if (ret) {
-			dev_err(&ccw_device->dev,
+		adapter = zfcp_adapter_enqueue(cdev);
+
+		if (IS_ERR(adapter)) {
+			dev_err(&cdev->dev,
 				"Setting up data structures for the "
 				"FCP adapter failed\n");
-			goto out;
+			return PTR_ERR(adapter);
 		}
-		adapter = dev_get_drvdata(&ccw_device->dev);
+		kref_get(&adapter->ref);
 	}
 
 	/* initialize request counter */
@@ -177,58 +170,61 @@
 	zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
 				"ccsonl2", NULL);
 	zfcp_erp_wait(adapter);
-out:
-	mutex_unlock(&zfcp_data.config_mutex);
-	if (!ret)
-		flush_work(&adapter->scan_work);
-	return ret;
+
+	flush_work(&adapter->scan_work);
+
+	zfcp_ccw_adapter_put(adapter);
+	return 0;
 }
 
 /**
  * zfcp_ccw_set_offline - set_offline function of zfcp driver
- * @ccw_device: pointer to belonging ccw device
+ * @cdev: pointer to belonging ccw device
  *
  * This function gets called by the common i/o layer and sets an adapter
  * into state offline.
  */
-static int zfcp_ccw_set_offline(struct ccw_device *ccw_device)
+static int zfcp_ccw_set_offline(struct ccw_device *cdev)
 {
-	struct zfcp_adapter *adapter;
+	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
 
-	mutex_lock(&zfcp_data.config_mutex);
-	adapter = dev_get_drvdata(&ccw_device->dev);
+	if (!adapter)
+		return 0;
+
 	zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1", NULL);
 	zfcp_erp_wait(adapter);
-	mutex_unlock(&zfcp_data.config_mutex);
+
+	zfcp_ccw_adapter_put(adapter);
 	return 0;
 }
 
 /**
  * zfcp_ccw_notify - ccw notify function
- * @ccw_device: pointer to belonging ccw device
+ * @cdev: pointer to belonging ccw device
  * @event: indicates if adapter was detached or attached
  *
  * This function gets called by the common i/o layer if an adapter has gone
  * or reappeared.
  */
-static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
+static int zfcp_ccw_notify(struct ccw_device *cdev, int event)
 {
-	struct zfcp_adapter *adapter = dev_get_drvdata(&ccw_device->dev);
+	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
+
+	if (!adapter)
+		return 1;
 
 	switch (event) {
 	case CIO_GONE:
-		dev_warn(&adapter->ccw_device->dev,
-			 "The FCP device has been detached\n");
+		dev_warn(&cdev->dev, "The FCP device has been detached\n");
 		zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1", NULL);
 		break;
 	case CIO_NO_PATH:
-		dev_warn(&adapter->ccw_device->dev,
+		dev_warn(&cdev->dev,
 			 "The CHPID for the FCP device is offline\n");
 		zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2", NULL);
 		break;
 	case CIO_OPER:
-		dev_info(&adapter->ccw_device->dev,
-			 "The FCP device is operational again\n");
+		dev_info(&cdev->dev, "The FCP device is operational again\n");
 		zfcp_erp_modify_adapter_status(adapter, "ccnoti3", NULL,
 					       ZFCP_STATUS_COMMON_RUNNING,
 					       ZFCP_SET);
@@ -236,11 +232,13 @@
 					"ccnoti4", NULL);
 		break;
 	case CIO_BOXED:
-		dev_warn(&adapter->ccw_device->dev, "The FCP device "
-			 "did not respond within the specified time\n");
+		dev_warn(&cdev->dev, "The FCP device did not respond within "
+				     "the specified time\n");
 		zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5", NULL);
 		break;
 	}
+
+	zfcp_ccw_adapter_put(adapter);
 	return 1;
 }
 
@@ -250,18 +248,16 @@
  */
 static void zfcp_ccw_shutdown(struct ccw_device *cdev)
 {
-	struct zfcp_adapter *adapter;
+	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
 
-	mutex_lock(&zfcp_data.config_mutex);
-	adapter = dev_get_drvdata(&cdev->dev);
 	if (!adapter)
-		goto out;
+		return;
 
 	zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1", NULL);
 	zfcp_erp_wait(adapter);
 	zfcp_erp_thread_kill(adapter);
-out:
-	mutex_unlock(&zfcp_data.config_mutex);
+
+	zfcp_ccw_adapter_put(adapter);
 }
 
 struct ccw_driver zfcp_ccw_driver = {
@@ -274,18 +270,7 @@
 	.set_offline = zfcp_ccw_set_offline,
 	.notify      = zfcp_ccw_notify,
 	.shutdown    = zfcp_ccw_shutdown,
-	.freeze      = zfcp_ccw_suspend,
+	.freeze      = zfcp_ccw_set_offline,
 	.thaw	     = zfcp_ccw_activate,
 	.restore     = zfcp_ccw_activate,
 };
-
-/**
- * zfcp_ccw_register - ccw register function
- *
- * Registers the driver at the common i/o layer. This function will be called
- * at module load time/system start.
- */
-int __init zfcp_ccw_register(void)
-{
-	return ccw_driver_register(&zfcp_ccw_driver);
-}
diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c
index ef681df..f932400 100644
--- a/drivers/s390/scsi/zfcp_cfdc.c
+++ b/drivers/s390/scsi/zfcp_cfdc.c
@@ -86,22 +86,17 @@
 static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno)
 {
 	char busid[9];
-	struct ccw_device *ccwdev;
-	struct zfcp_adapter *adapter = NULL;
+	struct ccw_device *cdev;
+	struct zfcp_adapter *adapter;
 
 	snprintf(busid, sizeof(busid), "0.0.%04x", devno);
-	ccwdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
-	if (!ccwdev)
-		goto out;
+	cdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
+	if (!cdev)
+		return NULL;
 
-	adapter = dev_get_drvdata(&ccwdev->dev);
-	if (!adapter)
-		goto out_put;
+	adapter = zfcp_ccw_adapter_by_cdev(cdev);
 
-	zfcp_adapter_get(adapter);
-out_put:
-	put_device(&ccwdev->dev);
-out:
+	put_device(&cdev->dev);
 	return adapter;
 }
 
@@ -212,7 +207,6 @@
 		retval = -ENXIO;
 		goto free_buffer;
 	}
-	zfcp_adapter_get(adapter);
 
 	retval = zfcp_cfdc_sg_setup(data->command, fsf_cfdc->sg,
 				    data_user->control_file);
@@ -245,7 +239,7 @@
  free_sg:
 	zfcp_sg_free_table(fsf_cfdc->sg, ZFCP_CFDC_PAGES);
  adapter_put:
-	zfcp_adapter_put(adapter);
+	zfcp_ccw_adapter_put(adapter);
  free_buffer:
 	kfree(data);
  no_mem_sense:
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index 215b707..8445095 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -13,6 +13,7 @@
 #include <asm/debug.h>
 #include "zfcp_dbf.h"
 #include "zfcp_ext.h"
+#include "zfcp_fc.h"
 
 static u32 dbfsize = 4;
 
@@ -177,8 +178,7 @@
 
 	case FSF_QTCB_SEND_ELS:
 		send_els = (struct zfcp_send_els *)fsf_req->data;
-		response->u.els.d_id = qtcb->bottom.support.d_id;
-		response->u.els.ls_code = send_els->ls_code >> 24;
+		response->u.els.d_id = ntoh24(qtcb->bottom.support.d_id);
 		break;
 
 	case FSF_QTCB_ABORT_FCP_CMND:
@@ -348,7 +348,6 @@
 
 	case FSF_QTCB_SEND_ELS:
 		zfcp_dbf_out(p, "d_id", "0x%06x", r->u.els.d_id);
-		zfcp_dbf_out(p, "ls_code", "0x%02x", r->u.els.ls_code);
 		break;
 
 	case FSF_QTCB_ABORT_FCP_CMND:
@@ -677,14 +676,14 @@
 /**
  * zfcp_dbf_san_ct_request - trace event for issued CT request
  * @fsf_req: request containing issued CT data
+ * @d_id: destination id where ct request is sent to
  */
-void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *fsf_req)
+void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *fsf_req, u32 d_id)
 {
-	struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
-	struct zfcp_wka_port *wka_port = ct->wka_port;
-	struct zfcp_adapter *adapter = wka_port->adapter;
+	struct zfcp_fsf_ct_els *ct = (struct zfcp_fsf_ct_els *)fsf_req->data;
+	struct zfcp_adapter *adapter = fsf_req->adapter;
 	struct zfcp_dbf *dbf = adapter->dbf;
-	struct ct_hdr *hdr = sg_virt(ct->req);
+	struct fc_ct_hdr *hdr = sg_virt(ct->req);
 	struct zfcp_dbf_san_record *r = &dbf->san_buf;
 	struct zfcp_dbf_san_record_ct_request *oct = &r->u.ct_req;
 	int level = 3;
@@ -695,19 +694,18 @@
 	strncpy(r->tag, "octc", ZFCP_DBF_TAG_SIZE);
 	r->fsf_reqid = fsf_req->req_id;
 	r->fsf_seqno = fsf_req->seq_no;
-	r->s_id = fc_host_port_id(adapter->scsi_host);
-	r->d_id = wka_port->d_id;
-	oct->cmd_req_code = hdr->cmd_rsp_code;
-	oct->revision = hdr->revision;
-	oct->gs_type = hdr->gs_type;
-	oct->gs_subtype = hdr->gs_subtype;
-	oct->options = hdr->options;
-	oct->max_res_size = hdr->max_res_size;
-	oct->len = min((int)ct->req->length - (int)sizeof(struct ct_hdr),
+	oct->d_id = d_id;
+	oct->cmd_req_code = hdr->ct_cmd;
+	oct->revision = hdr->ct_rev;
+	oct->gs_type = hdr->ct_fs_type;
+	oct->gs_subtype = hdr->ct_fs_subtype;
+	oct->options = hdr->ct_options;
+	oct->max_res_size = hdr->ct_mr_size;
+	oct->len = min((int)ct->req->length - (int)sizeof(struct fc_ct_hdr),
 		       ZFCP_DBF_SAN_MAX_PAYLOAD);
 	debug_event(dbf->san, level, r, sizeof(*r));
 	zfcp_dbf_hexdump(dbf->san, r, sizeof(*r), level,
-			 (void *)hdr + sizeof(struct ct_hdr), oct->len);
+			 (void *)hdr + sizeof(struct fc_ct_hdr), oct->len);
 	spin_unlock_irqrestore(&dbf->san_lock, flags);
 }
 
@@ -717,10 +715,9 @@
  */
 void zfcp_dbf_san_ct_response(struct zfcp_fsf_req *fsf_req)
 {
-	struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
-	struct zfcp_wka_port *wka_port = ct->wka_port;
-	struct zfcp_adapter *adapter = wka_port->adapter;
-	struct ct_hdr *hdr = sg_virt(ct->resp);
+	struct zfcp_fsf_ct_els *ct = (struct zfcp_fsf_ct_els *)fsf_req->data;
+	struct zfcp_adapter *adapter = fsf_req->adapter;
+	struct fc_ct_hdr *hdr = sg_virt(ct->resp);
 	struct zfcp_dbf *dbf = adapter->dbf;
 	struct zfcp_dbf_san_record *r = &dbf->san_buf;
 	struct zfcp_dbf_san_record_ct_response *rct = &r->u.ct_resp;
@@ -732,25 +729,23 @@
 	strncpy(r->tag, "rctc", ZFCP_DBF_TAG_SIZE);
 	r->fsf_reqid = fsf_req->req_id;
 	r->fsf_seqno = fsf_req->seq_no;
-	r->s_id = wka_port->d_id;
-	r->d_id = fc_host_port_id(adapter->scsi_host);
-	rct->cmd_rsp_code = hdr->cmd_rsp_code;
-	rct->revision = hdr->revision;
-	rct->reason_code = hdr->reason_code;
-	rct->expl = hdr->reason_code_expl;
-	rct->vendor_unique = hdr->vendor_unique;
-	rct->max_res_size = hdr->max_res_size;
-	rct->len = min((int)ct->resp->length - (int)sizeof(struct ct_hdr),
+	rct->cmd_rsp_code = hdr->ct_cmd;
+	rct->revision = hdr->ct_rev;
+	rct->reason_code = hdr->ct_reason;
+	rct->expl = hdr->ct_explan;
+	rct->vendor_unique = hdr->ct_vendor;
+	rct->max_res_size = hdr->ct_mr_size;
+	rct->len = min((int)ct->resp->length - (int)sizeof(struct fc_ct_hdr),
 		       ZFCP_DBF_SAN_MAX_PAYLOAD);
 	debug_event(dbf->san, level, r, sizeof(*r));
 	zfcp_dbf_hexdump(dbf->san, r, sizeof(*r), level,
-			 (void *)hdr + sizeof(struct ct_hdr), rct->len);
+			 (void *)hdr + sizeof(struct fc_ct_hdr), rct->len);
 	spin_unlock_irqrestore(&dbf->san_lock, flags);
 }
 
 static void zfcp_dbf_san_els(const char *tag, int level,
-			     struct zfcp_fsf_req *fsf_req, u32 s_id, u32 d_id,
-			     u8 ls_code, void *buffer, int buflen)
+			     struct zfcp_fsf_req *fsf_req, u32 d_id,
+			     void *buffer, int buflen)
 {
 	struct zfcp_adapter *adapter = fsf_req->adapter;
 	struct zfcp_dbf *dbf = adapter->dbf;
@@ -762,9 +757,7 @@
 	strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
 	rec->fsf_reqid = fsf_req->req_id;
 	rec->fsf_seqno = fsf_req->seq_no;
-	rec->s_id = s_id;
-	rec->d_id = d_id;
-	rec->u.els.ls_code = ls_code;
+	rec->u.els.d_id = d_id;
 	debug_event(dbf->san, level, rec, sizeof(*rec));
 	zfcp_dbf_hexdump(dbf->san, rec, sizeof(*rec), level,
 			 buffer, min(buflen, ZFCP_DBF_SAN_MAX_PAYLOAD));
@@ -777,12 +770,11 @@
  */
 void zfcp_dbf_san_els_request(struct zfcp_fsf_req *fsf_req)
 {
-	struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;
+	struct zfcp_fsf_ct_els *els = (struct zfcp_fsf_ct_els *)fsf_req->data;
+	u32 d_id = ntoh24(fsf_req->qtcb->bottom.support.d_id);
 
-	zfcp_dbf_san_els("oels", 2, fsf_req,
-			       fc_host_port_id(els->adapter->scsi_host),
-			       els->d_id, *(u8 *) sg_virt(els->req),
-			       sg_virt(els->req), els->req->length);
+	zfcp_dbf_san_els("oels", 2, fsf_req, d_id,
+			 sg_virt(els->req), els->req->length);
 }
 
 /**
@@ -791,12 +783,11 @@
  */
 void zfcp_dbf_san_els_response(struct zfcp_fsf_req *fsf_req)
 {
-	struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;
+	struct zfcp_fsf_ct_els *els = (struct zfcp_fsf_ct_els *)fsf_req->data;
+	u32 d_id = ntoh24(fsf_req->qtcb->bottom.support.d_id);
 
-	zfcp_dbf_san_els("rels", 2, fsf_req, els->d_id,
-			       fc_host_port_id(els->adapter->scsi_host),
-			       *(u8 *)sg_virt(els->req), sg_virt(els->resp),
-			       els->resp->length);
+	zfcp_dbf_san_els("rels", 2, fsf_req, d_id,
+			       sg_virt(els->resp), els->resp->length);
 }
 
 /**
@@ -805,16 +796,13 @@
  */
 void zfcp_dbf_san_incoming_els(struct zfcp_fsf_req *fsf_req)
 {
-	struct zfcp_adapter *adapter = fsf_req->adapter;
 	struct fsf_status_read_buffer *buf =
 			(struct fsf_status_read_buffer *)fsf_req->data;
 	int length = (int)buf->length -
 		     (int)((void *)&buf->payload - (void *)buf);
 
-	zfcp_dbf_san_els("iels", 1, fsf_req, buf->d_id,
-			       fc_host_port_id(adapter->scsi_host),
-			       buf->payload.data[0], (void *)buf->payload.data,
-			       length);
+	zfcp_dbf_san_els("iels", 1, fsf_req, ntoh24(buf->d_id),
+			       (void *)buf->payload.data, length);
 }
 
 static int zfcp_dbf_san_view_format(debug_info_t *id, struct debug_view *view,
@@ -829,11 +817,10 @@
 	zfcp_dbf_tag(&p, "tag", r->tag);
 	zfcp_dbf_out(&p, "fsf_reqid", "0x%0Lx", r->fsf_reqid);
 	zfcp_dbf_out(&p, "fsf_seqno", "0x%08x", r->fsf_seqno);
-	zfcp_dbf_out(&p, "s_id", "0x%06x", r->s_id);
-	zfcp_dbf_out(&p, "d_id", "0x%06x", r->d_id);
 
 	if (strncmp(r->tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) {
 		struct zfcp_dbf_san_record_ct_request *ct = &r->u.ct_req;
+		zfcp_dbf_out(&p, "d_id", "0x%06x", ct->d_id);
 		zfcp_dbf_out(&p, "cmd_req_code", "0x%04x", ct->cmd_req_code);
 		zfcp_dbf_out(&p, "revision", "0x%02x", ct->revision);
 		zfcp_dbf_out(&p, "gs_type", "0x%02x", ct->gs_type);
@@ -852,7 +839,7 @@
 		   strncmp(r->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 ||
 		   strncmp(r->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) {
 		struct zfcp_dbf_san_record_els *els = &r->u.els;
-		zfcp_dbf_out(&p, "ls_code", "0x%02x", els->ls_code);
+		zfcp_dbf_out(&p, "d_id", "0x%06x", els->d_id);
 	}
 	return p - out_buf;
 }
@@ -870,8 +857,9 @@
 	struct zfcp_dbf_scsi_record *rec = &dbf->scsi_buf;
 	struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec;
 	unsigned long flags;
-	struct fcp_rsp_iu *fcp_rsp;
-	char *fcp_rsp_info = NULL, *fcp_sns_info = NULL;
+	struct fcp_resp_with_ext *fcp_rsp;
+	struct fcp_resp_rsp_info *fcp_rsp_info = NULL;
+	char *fcp_sns_info = NULL;
 	int offset = 0, buflen = 0;
 
 	spin_lock_irqsave(&dbf->scsi_lock, flags);
@@ -895,20 +883,22 @@
 				rec->scsi_allowed = scsi_cmnd->allowed;
 			}
 			if (fsf_req != NULL) {
-				fcp_rsp = (struct fcp_rsp_iu *)
-				    &(fsf_req->qtcb->bottom.io.fcp_rsp);
-				fcp_rsp_info = (unsigned char *) &fcp_rsp[1];
-				fcp_sns_info =
-				    zfcp_get_fcp_sns_info_ptr(fcp_rsp);
+				fcp_rsp = (struct fcp_resp_with_ext *)
+					&(fsf_req->qtcb->bottom.io.fcp_rsp);
+				fcp_rsp_info = (struct fcp_resp_rsp_info *)
+					&fcp_rsp[1];
+				fcp_sns_info = (char *) &fcp_rsp[1];
+				if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL)
+					fcp_sns_info += fcp_rsp->ext.fr_sns_len;
 
-				rec->rsp_validity = fcp_rsp->validity.value;
-				rec->rsp_scsi_status = fcp_rsp->scsi_status;
-				rec->rsp_resid = fcp_rsp->fcp_resid;
-				if (fcp_rsp->validity.bits.fcp_rsp_len_valid)
-					rec->rsp_code = *(fcp_rsp_info + 3);
-				if (fcp_rsp->validity.bits.fcp_sns_len_valid) {
-					buflen = min((int)fcp_rsp->fcp_sns_len,
-						     ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO);
+				rec->rsp_validity = fcp_rsp->resp.fr_flags;
+				rec->rsp_scsi_status = fcp_rsp->resp.fr_status;
+				rec->rsp_resid = fcp_rsp->ext.fr_resid;
+				if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL)
+					rec->rsp_code = fcp_rsp_info->rsp_code;
+				if (fcp_rsp->resp.fr_flags & FCP_SNS_LEN_VAL) {
+					buflen = min(fcp_rsp->ext.fr_sns_len,
+					   (u32)ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO);
 					rec->sns_info_len = buflen;
 					memcpy(rec->sns_info, fcp_sns_info,
 					       min(buflen,
@@ -1067,6 +1057,8 @@
  */
 void zfcp_dbf_adapter_unregister(struct zfcp_dbf *dbf)
 {
+	if (!dbf)
+		return;
 	debug_unregister(dbf->scsi);
 	debug_unregister(dbf->san);
 	debug_unregister(dbf->hba);
diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h
index 6b1461e..8b7fd9a 100644
--- a/drivers/s390/scsi/zfcp_dbf.h
+++ b/drivers/s390/scsi/zfcp_dbf.h
@@ -22,6 +22,7 @@
 #ifndef ZFCP_DBF_H
 #define ZFCP_DBF_H
 
+#include <scsi/fc/fc_fcp.h>
 #include "zfcp_ext.h"
 #include "zfcp_fsf.h"
 #include "zfcp_def.h"
@@ -122,7 +123,6 @@
 		} unit;
 		struct {
 			u32 d_id;
-			u8 ls_code;
 		} els;
 	} u;
 } __attribute__ ((packed));
@@ -166,6 +166,7 @@
 	u8 options;
 	u16 max_res_size;
 	u32 len;
+	u32 d_id;
 } __attribute__ ((packed));
 
 struct zfcp_dbf_san_record_ct_response {
@@ -179,16 +180,13 @@
 } __attribute__ ((packed));
 
 struct zfcp_dbf_san_record_els {
-	u8 ls_code;
-	u32 len;
+	u32 d_id;
 } __attribute__ ((packed));
 
 struct zfcp_dbf_san_record {
 	u8 tag[ZFCP_DBF_TAG_SIZE];
 	u64 fsf_reqid;
 	u32 fsf_seqno;
-	u32 s_id;
-	u32 d_id;
 	union {
 		struct zfcp_dbf_san_record_ct_request ct_req;
 		struct zfcp_dbf_san_record_ct_response ct_resp;
@@ -343,7 +341,7 @@
 void zfcp_dbf_scsi_devreset(const char *tag, u8 flag, struct zfcp_unit *unit,
 			    struct scsi_cmnd *scsi_cmnd)
 {
-	zfcp_dbf_scsi(flag == FCP_TARGET_RESET ? "trst" : "lrst", tag, 1,
+	zfcp_dbf_scsi(flag == FCP_TMF_TGT_RESET ? "trst" : "lrst", tag, 1,
 			    unit->port->adapter->dbf, scsi_cmnd, NULL, 0);
 }
 
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 7da2fad..e1b5b88 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -71,131 +71,6 @@
 /* timeout value for "default timer" for fsf requests */
 #define ZFCP_FSF_REQUEST_TIMEOUT (60*HZ)
 
-/*************** FIBRE CHANNEL PROTOCOL SPECIFIC DEFINES ********************/
-
-/* task attribute values in FCP-2 FCP_CMND IU */
-#define SIMPLE_Q	0
-#define HEAD_OF_Q	1
-#define ORDERED_Q	2
-#define ACA_Q		4
-#define UNTAGGED	5
-
-/* task management flags in FCP-2 FCP_CMND IU */
-#define FCP_CLEAR_ACA		0x40
-#define FCP_TARGET_RESET	0x20
-#define FCP_LOGICAL_UNIT_RESET	0x10
-#define FCP_CLEAR_TASK_SET	0x04
-#define FCP_ABORT_TASK_SET	0x02
-
-#define FCP_CDB_LENGTH		16
-
-#define ZFCP_DID_MASK           0x00FFFFFF
-
-/* FCP(-2) FCP_CMND IU */
-struct fcp_cmnd_iu {
-	u64 fcp_lun;	   /* FCP logical unit number */
-	u8  crn;	           /* command reference number */
-	u8  reserved0:5;	   /* reserved */
-	u8  task_attribute:3;	   /* task attribute */
-	u8  task_management_flags; /* task management flags */
-	u8  add_fcp_cdb_length:6;  /* additional FCP_CDB length */
-	u8  rddata:1;              /* read data */
-	u8  wddata:1;              /* write data */
-	u8  fcp_cdb[FCP_CDB_LENGTH];
-} __attribute__((packed));
-
-/* FCP(-2) FCP_RSP IU */
-struct fcp_rsp_iu {
-	u8  reserved0[10];
-	union {
-		struct {
-			u8 reserved1:3;
-			u8 fcp_conf_req:1;
-			u8 fcp_resid_under:1;
-			u8 fcp_resid_over:1;
-			u8 fcp_sns_len_valid:1;
-			u8 fcp_rsp_len_valid:1;
-		} bits;
-		u8 value;
-	} validity;
-	u8  scsi_status;
-	u32 fcp_resid;
-	u32 fcp_sns_len;
-	u32 fcp_rsp_len;
-} __attribute__((packed));
-
-
-#define RSP_CODE_GOOD		 0
-#define RSP_CODE_LENGTH_MISMATCH 1
-#define RSP_CODE_FIELD_INVALID	 2
-#define RSP_CODE_RO_MISMATCH	 3
-#define RSP_CODE_TASKMAN_UNSUPP	 4
-#define RSP_CODE_TASKMAN_FAILED	 5
-
-/* see fc-fs */
-#define LS_RSCN  0x61
-#define LS_LOGO  0x05
-#define LS_PLOGI 0x03
-
-struct fcp_rscn_head {
-        u8  command;
-        u8  page_length; /* always 0x04 */
-        u16 payload_len;
-} __attribute__((packed));
-
-struct fcp_rscn_element {
-        u8  reserved:2;
-        u8  event_qual:4;
-        u8  addr_format:2;
-        u32 nport_did:24;
-} __attribute__((packed));
-
-/* see fc-ph */
-struct fcp_logo {
-        u32 command;
-        u32 nport_did;
-	u64 nport_wwpn;
-} __attribute__((packed));
-
-/*
- * FC-FS stuff
- */
-#define R_A_TOV				10 /* seconds */
-
-#define ZFCP_LS_RLS			0x0f
-#define ZFCP_LS_ADISC			0x52
-#define ZFCP_LS_RPS			0x56
-#define ZFCP_LS_RSCN			0x61
-#define ZFCP_LS_RNID			0x78
-
-struct zfcp_ls_adisc {
-	u8		code;
-	u8		field[3];
-	u32		hard_nport_id;
-	u64		wwpn;
-	u64		wwnn;
-	u32		nport_id;
-} __attribute__ ((packed));
-
-/*
- * FC-GS-2 stuff
- */
-#define ZFCP_CT_REVISION		0x01
-#define ZFCP_CT_DIRECTORY_SERVICE	0xFC
-#define ZFCP_CT_NAME_SERVER		0x02
-#define ZFCP_CT_SYNCHRONOUS		0x00
-#define ZFCP_CT_SCSI_FCP		0x08
-#define ZFCP_CT_UNABLE_TO_PERFORM_CMD	0x09
-#define ZFCP_CT_GID_PN			0x0121
-#define ZFCP_CT_GPN_FT			0x0172
-#define ZFCP_CT_ACCEPT			0x8002
-#define ZFCP_CT_REJECT			0x8001
-
-/*
- * FC-GS-4 stuff
- */
-#define ZFCP_CT_TIMEOUT			(3 * R_A_TOV)
-
 /*************** ADAPTER/PORT/UNIT AND FSF_REQ STATUS FLAGS ******************/
 
 /*
@@ -205,7 +80,6 @@
 #define ZFCP_COMMON_FLAGS			0xfff00000
 
 /* common status bits */
-#define ZFCP_STATUS_COMMON_REMOVE		0x80000000
 #define ZFCP_STATUS_COMMON_RUNNING		0x40000000
 #define ZFCP_STATUS_COMMON_ERP_FAILED		0x20000000
 #define ZFCP_STATUS_COMMON_UNBLOCKED		0x10000000
@@ -222,21 +96,10 @@
 #define ZFCP_STATUS_ADAPTER_ERP_PENDING		0x00000100
 #define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED	0x00000200
 
-/* FC-PH/FC-GS well-known address identifiers for generic services */
-#define ZFCP_DID_WKA				0xFFFFF0
-
 /* remote port status */
 #define ZFCP_STATUS_PORT_PHYS_OPEN		0x00000001
 #define ZFCP_STATUS_PORT_LINK_TEST		0x00000002
 
-/* well known address (WKA) port status*/
-enum zfcp_wka_status {
-	ZFCP_WKA_PORT_OFFLINE,
-	ZFCP_WKA_PORT_CLOSING,
-	ZFCP_WKA_PORT_OPENING,
-	ZFCP_WKA_PORT_ONLINE,
-};
-
 /* logical unit status */
 #define ZFCP_STATUS_UNIT_SHARED			0x00000004
 #define ZFCP_STATUS_UNIT_READONLY		0x00000008
@@ -247,10 +110,7 @@
 #define ZFCP_STATUS_FSFREQ_CLEANUP		0x00000010
 #define ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED	0x00000040
 #define ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED       0x00000080
-#define ZFCP_STATUS_FSFREQ_ABORTED              0x00000100
 #define ZFCP_STATUS_FSFREQ_TMFUNCFAILED         0x00000200
-#define ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP        0x00000400
-#define ZFCP_STATUS_FSFREQ_RETRY                0x00000800
 #define ZFCP_STATUS_FSFREQ_DISMISSED            0x00001000
 
 /************************* STRUCTURE DEFINITIONS *****************************/
@@ -265,125 +125,10 @@
 	mempool_t *scsi_abort;
 	mempool_t *status_read_req;
 	mempool_t *status_read_data;
-	mempool_t *gid_pn_data;
+	mempool_t *gid_pn;
 	mempool_t *qtcb_pool;
 };
 
-/*
- * header for CT_IU
- */
-struct ct_hdr {
-	u8 revision;		// 0x01
-	u8 in_id[3];		// 0x00
-	u8 gs_type;		// 0xFC	Directory Service
-	u8 gs_subtype;		// 0x02	Name Server
-	u8 options;		// 0x00 single bidirectional exchange
-	u8 reserved0;
-	u16 cmd_rsp_code;	// 0x0121 GID_PN, or 0x0100 GA_NXT
-	u16 max_res_size;	// <= (4096 - 16) / 4
-	u8 reserved1;
-	u8 reason_code;
-	u8 reason_code_expl;
-	u8 vendor_unique;
-} __attribute__ ((packed));
-
-/* nameserver request CT_IU -- for requests where
- * a port name is required */
-struct ct_iu_gid_pn_req {
-	struct ct_hdr header;
-	u64 wwpn;
-} __attribute__ ((packed));
-
-/* FS_ACC IU and data unit for GID_PN nameserver request */
-struct ct_iu_gid_pn_resp {
-	struct ct_hdr header;
-	u32 d_id;
-} __attribute__ ((packed));
-
-struct ct_iu_gpn_ft_req {
-	struct ct_hdr header;
-	u8 flags;
-	u8 domain_id_scope;
-	u8 area_id_scope;
-	u8 fc4_type;
-} __attribute__ ((packed));
-
-
-/**
- * struct zfcp_send_ct - used to pass parameters to function zfcp_fsf_send_ct
- * @wka_port: port where the request is sent to
- * @req: scatter-gather list for request
- * @resp: scatter-gather list for response
- * @handler: handler function (called for response to the request)
- * @handler_data: data passed to handler function
- * @completion: completion for synchronization purposes
- * @status: used to pass error status to calling function
- */
-struct zfcp_send_ct {
-	struct zfcp_wka_port *wka_port;
-	struct scatterlist *req;
-	struct scatterlist *resp;
-	void (*handler)(unsigned long);
-	unsigned long handler_data;
-	struct completion *completion;
-	int status;
-};
-
-/* used for name server requests in error recovery */
-struct zfcp_gid_pn_data {
-	struct zfcp_send_ct ct;
-	struct scatterlist req;
-	struct scatterlist resp;
-	struct ct_iu_gid_pn_req ct_iu_req;
-	struct ct_iu_gid_pn_resp ct_iu_resp;
-        struct zfcp_port *port;
-};
-
-/**
- * struct zfcp_send_els - used to pass parameters to function zfcp_fsf_send_els
- * @adapter: adapter where request is sent from
- * @port: port where ELS is destinated (port reference count has to be increased)
- * @d_id: destiniation id of port where request is sent to
- * @req: scatter-gather list for request
- * @resp: scatter-gather list for response
- * @handler: handler function (called for response to the request)
- * @handler_data: data passed to handler function
- * @completion: completion for synchronization purposes
- * @ls_code: hex code of ELS command
- * @status: used to pass error status to calling function
- */
-struct zfcp_send_els {
-	struct zfcp_adapter *adapter;
-	struct zfcp_port *port;
-	u32 d_id;
-	struct scatterlist *req;
-	struct scatterlist *resp;
-	void (*handler)(unsigned long);
-	unsigned long handler_data;
-	struct completion *completion;
-	int ls_code;
-	int status;
-};
-
-struct zfcp_wka_port {
-	struct zfcp_adapter	*adapter;
-	wait_queue_head_t	completion_wq;
-	enum zfcp_wka_status	status;
-	atomic_t		refcount;
-	u32			d_id;
-	u32			handle;
-	struct mutex		mutex;
-	struct delayed_work	work;
-};
-
-struct zfcp_wka_ports {
-	struct zfcp_wka_port ms; 	/* management service */
-	struct zfcp_wka_port ts; 	/* time service */
-	struct zfcp_wka_port ds; 	/* directory service */
-	struct zfcp_wka_port as; 	/* alias service */
-	struct zfcp_wka_port ks; 	/* key distribution service */
-};
-
 struct zfcp_qdio_queue {
 	struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q];
 	u8		   first;	/* index of next free bfr in queue */
@@ -446,9 +191,7 @@
 };
 
 struct zfcp_adapter {
-	atomic_t                refcount;          /* reference count */
-	wait_queue_head_t	remove_wq;         /* can be used to wait for
-						      refcount drop to zero */
+	struct kref		ref;
 	u64			peer_wwnn;	   /* P2P peer WWNN */
 	u64			peer_wwpn;	   /* P2P peer WWPN */
 	u32			peer_d_id;	   /* P2P peer D_ID */
@@ -461,7 +204,8 @@
         u32			hardware_version;  /* of FCP channel */
 	u16			timer_ticks;       /* time int for a tick */
 	struct Scsi_Host	*scsi_host;	   /* Pointer to mid-layer */
-	struct list_head	port_list_head;	   /* remote port list */
+	struct list_head	port_list;	   /* remote port list */
+	rwlock_t		port_list_lock;    /* port list lock */
 	unsigned long		req_no;		   /* unique FSF req number */
 	struct list_head	*req_list;	   /* list of pending reqs */
 	spinlock_t		req_list_lock;	   /* request list lock */
@@ -485,7 +229,7 @@
 	u32			erp_low_mem_count; /* nr of erp actions waiting
 						      for memory */
 	struct task_struct	*erp_thread;
-	struct zfcp_wka_ports	*gs;		   /* generic services */
+	struct zfcp_fc_wka_ports *gs;		   /* generic services */
 	struct zfcp_dbf		*dbf;		   /* debug traces */
 	struct zfcp_adapter_mempool	pool;      /* Adapter memory pools */
 	struct fc_host_statistics *fc_stats;
@@ -500,11 +244,9 @@
 	struct device          sysfs_device;   /* sysfs device */
 	struct fc_rport        *rport;         /* rport of fc transport class */
 	struct list_head       list;	       /* list of remote ports */
-	atomic_t               refcount;       /* reference count */
-	wait_queue_head_t      remove_wq;      /* can be used to wait for
-						  refcount drop to zero */
 	struct zfcp_adapter    *adapter;       /* adapter used to access port */
-	struct list_head       unit_list_head; /* head of logical unit list */
+	struct list_head	unit_list;	/* head of logical unit list */
+	rwlock_t		unit_list_lock; /* unit list lock */
 	atomic_t	       status;	       /* status of this remote port */
 	u64		       wwnn;	       /* WWNN if known */
 	u64		       wwpn;	       /* WWPN */
@@ -523,9 +265,6 @@
 struct zfcp_unit {
 	struct device          sysfs_device;   /* sysfs device */
 	struct list_head       list;	       /* list of logical units */
-	atomic_t               refcount;       /* reference count */
-	wait_queue_head_t      remove_wq;      /* can be used to wait for
-						  refcount drop to zero */
 	struct zfcp_port       *port;	       /* remote port of unit */
 	atomic_t	       status;	       /* status of this logical unit */
 	u64		       fcp_lun;	       /* own FCP_LUN */
@@ -601,14 +340,11 @@
 struct zfcp_data {
 	struct scsi_host_template scsi_host_template;
 	struct scsi_transport_template *scsi_transport_template;
-	rwlock_t                config_lock;        /* serialises changes
-						       to adapter/port/unit
-						       lists */
-	struct mutex		config_mutex;
 	struct kmem_cache	*gpn_ft_cache;
 	struct kmem_cache	*qtcb_cache;
 	struct kmem_cache	*sr_buffer_cache;
 	struct kmem_cache	*gid_pn_cache;
+	struct kmem_cache	*adisc_cache;
 };
 
 /********************** ZFCP SPECIFIC DEFINES ********************************/
@@ -657,47 +393,4 @@
 	return NULL;
 }
 
-/*
- *  functions needed for reference/usage counting
- */
-
-static inline void
-zfcp_unit_get(struct zfcp_unit *unit)
-{
-	atomic_inc(&unit->refcount);
-}
-
-static inline void
-zfcp_unit_put(struct zfcp_unit *unit)
-{
-	if (atomic_dec_return(&unit->refcount) == 0)
-		wake_up(&unit->remove_wq);
-}
-
-static inline void
-zfcp_port_get(struct zfcp_port *port)
-{
-	atomic_inc(&port->refcount);
-}
-
-static inline void
-zfcp_port_put(struct zfcp_port *port)
-{
-	if (atomic_dec_return(&port->refcount) == 0)
-		wake_up(&port->remove_wq);
-}
-
-static inline void
-zfcp_adapter_get(struct zfcp_adapter *adapter)
-{
-	atomic_inc(&adapter->refcount);
-}
-
-static inline void
-zfcp_adapter_put(struct zfcp_adapter *adapter)
-{
-	if (atomic_dec_return(&adapter->refcount) == 0)
-		wake_up(&adapter->remove_wq);
-}
-
 #endif /* ZFCP_DEF_H */
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index f73e218..b51a11a 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -99,9 +99,12 @@
 
 	if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_INUSE)
 		zfcp_erp_action_dismiss(&port->erp_action);
-	else
-		list_for_each_entry(unit, &port->unit_list_head, list)
-		    zfcp_erp_action_dismiss_unit(unit);
+	else {
+		read_lock(&port->unit_list_lock);
+		list_for_each_entry(unit, &port->unit_list, list)
+			zfcp_erp_action_dismiss_unit(unit);
+		read_unlock(&port->unit_list_lock);
+	}
 }
 
 static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter)
@@ -110,9 +113,12 @@
 
 	if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_INUSE)
 		zfcp_erp_action_dismiss(&adapter->erp_action);
-	else
-		list_for_each_entry(port, &adapter->port_list_head, list)
+	else {
+		read_lock(&adapter->port_list_lock);
+		list_for_each_entry(port, &adapter->port_list, list)
 		    zfcp_erp_action_dismiss_port(port);
+		read_unlock(&adapter->port_list_lock);
+	}
 }
 
 static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter,
@@ -168,7 +174,8 @@
 
 	switch (need) {
 	case ZFCP_ERP_ACTION_REOPEN_UNIT:
-		zfcp_unit_get(unit);
+		if (!get_device(&unit->sysfs_device))
+			return NULL;
 		atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status);
 		erp_action = &unit->erp_action;
 		if (!(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_RUNNING))
@@ -177,7 +184,8 @@
 
 	case ZFCP_ERP_ACTION_REOPEN_PORT:
 	case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
-		zfcp_port_get(port);
+		if (!get_device(&port->sysfs_device))
+			return NULL;
 		zfcp_erp_action_dismiss_port(port);
 		atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status);
 		erp_action = &port->erp_action;
@@ -186,7 +194,7 @@
 		break;
 
 	case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
-		zfcp_adapter_get(adapter);
+		kref_get(&adapter->ref);
 		zfcp_erp_action_dismiss_adapter(adapter);
 		atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status);
 		erp_action = &adapter->erp_action;
@@ -264,11 +272,16 @@
 {
 	unsigned long flags;
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	write_lock(&adapter->erp_lock);
-	_zfcp_erp_adapter_reopen(adapter, clear, id, ref);
-	write_unlock(&adapter->erp_lock);
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
+	zfcp_erp_adapter_block(adapter, clear);
+	zfcp_scsi_schedule_rports_block(adapter);
+
+	write_lock_irqsave(&adapter->erp_lock, flags);
+	if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED)
+		zfcp_erp_adapter_failed(adapter, "erareo1", NULL);
+	else
+		zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, adapter,
+					NULL, NULL, id, ref);
+	write_unlock_irqrestore(&adapter->erp_lock, flags);
 }
 
 /**
@@ -345,11 +358,9 @@
 	unsigned long flags;
 	struct zfcp_adapter *adapter = port->adapter;
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	write_lock(&adapter->erp_lock);
+	write_lock_irqsave(&adapter->erp_lock, flags);
 	_zfcp_erp_port_forced_reopen(port, clear, id, ref);
-	write_unlock(&adapter->erp_lock);
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
+	write_unlock_irqrestore(&adapter->erp_lock, flags);
 }
 
 static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id,
@@ -377,15 +388,13 @@
  */
 int zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, void *ref)
 {
-	unsigned long flags;
 	int retval;
+	unsigned long flags;
 	struct zfcp_adapter *adapter = port->adapter;
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	write_lock(&adapter->erp_lock);
+	write_lock_irqsave(&adapter->erp_lock, flags);
 	retval = _zfcp_erp_port_reopen(port, clear, id, ref);
-	write_unlock(&adapter->erp_lock);
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
+	write_unlock_irqrestore(&adapter->erp_lock, flags);
 
 	return retval;
 }
@@ -424,11 +433,9 @@
 	struct zfcp_port *port = unit->port;
 	struct zfcp_adapter *adapter = port->adapter;
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	write_lock(&adapter->erp_lock);
+	write_lock_irqsave(&adapter->erp_lock, flags);
 	_zfcp_erp_unit_reopen(unit, clear, id, ref);
-	write_unlock(&adapter->erp_lock);
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
+	write_unlock_irqrestore(&adapter->erp_lock, flags);
 }
 
 static int status_change_set(unsigned long mask, atomic_t *status)
@@ -540,8 +547,10 @@
 {
 	struct zfcp_port *port;
 
-	list_for_each_entry(port, &adapter->port_list_head, list)
+	read_lock(&adapter->port_list_lock);
+	list_for_each_entry(port, &adapter->port_list, list)
 		_zfcp_erp_port_reopen(port, clear, id, ref);
+	read_unlock(&adapter->port_list_lock);
 }
 
 static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear,
@@ -549,8 +558,10 @@
 {
 	struct zfcp_unit *unit;
 
-	list_for_each_entry(unit, &port->unit_list_head, list)
+	read_lock(&port->unit_list_lock);
+	list_for_each_entry(unit, &port->unit_list, list)
 		_zfcp_erp_unit_reopen(unit, clear, id, ref);
+	read_unlock(&port->unit_list_lock);
 }
 
 static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act)
@@ -590,16 +601,14 @@
 {
 	unsigned long flags;
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	read_lock(&adapter->erp_lock);
+	read_lock_irqsave(&adapter->erp_lock, flags);
 	if (list_empty(&adapter->erp_ready_head) &&
 	    list_empty(&adapter->erp_running_head)) {
 			atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING,
 					  &adapter->status);
 			wake_up(&adapter->erp_done_wqh);
 	}
-	read_unlock(&adapter->erp_lock);
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
+	read_unlock_irqrestore(&adapter->erp_lock, flags);
 }
 
 static int zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *act)
@@ -1170,28 +1179,28 @@
 	switch (act->action) {
 	case ZFCP_ERP_ACTION_REOPEN_UNIT:
 		if ((result == ZFCP_ERP_SUCCEEDED) && !unit->device) {
-			zfcp_unit_get(unit);
+			get_device(&unit->sysfs_device);
 			if (scsi_queue_work(unit->port->adapter->scsi_host,
 					    &unit->scsi_work) <= 0)
-				zfcp_unit_put(unit);
+				put_device(&unit->sysfs_device);
 		}
-		zfcp_unit_put(unit);
+		put_device(&unit->sysfs_device);
 		break;
 
 	case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
 	case ZFCP_ERP_ACTION_REOPEN_PORT:
 		if (result == ZFCP_ERP_SUCCEEDED)
 			zfcp_scsi_schedule_rport_register(port);
-		zfcp_port_put(port);
+		put_device(&port->sysfs_device);
 		break;
 
 	case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
 		if (result == ZFCP_ERP_SUCCEEDED) {
 			register_service_level(&adapter->service_level);
-			schedule_work(&adapter->scan_work);
+			queue_work(adapter->work_queue, &adapter->scan_work);
 		} else
 			unregister_service_level(&adapter->service_level);
-		zfcp_adapter_put(adapter);
+		kref_put(&adapter->ref, zfcp_adapter_release);
 		break;
 	}
 }
@@ -1214,12 +1223,12 @@
 static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
 {
 	int retval;
-	struct zfcp_adapter *adapter = erp_action->adapter;
 	unsigned long flags;
+	struct zfcp_adapter *adapter = erp_action->adapter;
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	write_lock(&adapter->erp_lock);
+	kref_get(&adapter->ref);
 
+	write_lock_irqsave(&adapter->erp_lock, flags);
 	zfcp_erp_strategy_check_fsfreq(erp_action);
 
 	if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) {
@@ -1231,11 +1240,9 @@
 	zfcp_erp_action_to_running(erp_action);
 
 	/* no lock to allow for blocking operations */
-	write_unlock(&adapter->erp_lock);
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
+	write_unlock_irqrestore(&adapter->erp_lock, flags);
 	retval = zfcp_erp_strategy_do_action(erp_action);
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	write_lock(&adapter->erp_lock);
+	write_lock_irqsave(&adapter->erp_lock, flags);
 
 	if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED)
 		retval = ZFCP_ERP_CONTINUES;
@@ -1273,12 +1280,12 @@
 		zfcp_erp_strategy_followup_failed(erp_action);
 
  unlock:
-	write_unlock(&adapter->erp_lock);
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
+	write_unlock_irqrestore(&adapter->erp_lock, flags);
 
 	if (retval != ZFCP_ERP_CONTINUES)
 		zfcp_erp_action_cleanup(erp_action, retval);
 
+	kref_put(&adapter->ref, zfcp_adapter_release);
 	return retval;
 }
 
@@ -1415,6 +1422,7 @@
 				    void *ref, u32 mask, int set_or_clear)
 {
 	struct zfcp_port *port;
+	unsigned long flags;
 	u32 common_mask = mask & ZFCP_COMMON_FLAGS;
 
 	if (set_or_clear == ZFCP_SET) {
@@ -1429,10 +1437,13 @@
 			atomic_set(&adapter->erp_counter, 0);
 	}
 
-	if (common_mask)
-		list_for_each_entry(port, &adapter->port_list_head, list)
+	if (common_mask) {
+		read_lock_irqsave(&adapter->port_list_lock, flags);
+		list_for_each_entry(port, &adapter->port_list, list)
 			zfcp_erp_modify_port_status(port, id, ref, common_mask,
 						    set_or_clear);
+		read_unlock_irqrestore(&adapter->port_list_lock, flags);
+	}
 }
 
 /**
@@ -1449,6 +1460,7 @@
 				 u32 mask, int set_or_clear)
 {
 	struct zfcp_unit *unit;
+	unsigned long flags;
 	u32 common_mask = mask & ZFCP_COMMON_FLAGS;
 
 	if (set_or_clear == ZFCP_SET) {
@@ -1463,10 +1475,13 @@
 			atomic_set(&port->erp_counter, 0);
 	}
 
-	if (common_mask)
-		list_for_each_entry(unit, &port->unit_list_head, list)
+	if (common_mask) {
+		read_lock_irqsave(&port->unit_list_lock, flags);
+		list_for_each_entry(unit, &port->unit_list, list)
 			zfcp_erp_modify_unit_status(unit, id, ref, common_mask,
 						    set_or_clear);
+		read_unlock_irqrestore(&port->unit_list_lock, flags);
+	}
 }
 
 /**
@@ -1502,12 +1517,8 @@
  */
 void zfcp_erp_port_boxed(struct zfcp_port *port, char *id, void *ref)
 {
-	unsigned long flags;
-
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
 	zfcp_erp_modify_port_status(port, id, ref,
 				    ZFCP_STATUS_COMMON_ACCESS_BOXED, ZFCP_SET);
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 	zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref);
 }
 
@@ -1535,13 +1546,9 @@
  */
 void zfcp_erp_port_access_denied(struct zfcp_port *port, char *id, void *ref)
 {
-	unsigned long flags;
-
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
 	zfcp_erp_modify_port_status(port, id, ref,
 				    ZFCP_STATUS_COMMON_ERP_FAILED |
 				    ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET);
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 }
 
 /**
@@ -1574,12 +1581,15 @@
 					 void *ref)
 {
 	struct zfcp_unit *unit;
+	unsigned long flags;
 	int status = atomic_read(&port->status);
 
 	if (!(status & (ZFCP_STATUS_COMMON_ACCESS_DENIED |
 			ZFCP_STATUS_COMMON_ACCESS_BOXED))) {
-		list_for_each_entry(unit, &port->unit_list_head, list)
+		read_lock_irqsave(&port->unit_list_lock, flags);
+		list_for_each_entry(unit, &port->unit_list, list)
 				    zfcp_erp_unit_access_changed(unit, id, ref);
+		read_unlock_irqrestore(&port->unit_list_lock, flags);
 		return;
 	}
 
@@ -1595,14 +1605,14 @@
 void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, char *id,
 				     void *ref)
 {
-	struct zfcp_port *port;
 	unsigned long flags;
+	struct zfcp_port *port;
 
 	if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
 		return;
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	list_for_each_entry(port, &adapter->port_list_head, list)
+	read_lock_irqsave(&adapter->port_list_lock, flags);
+	list_for_each_entry(port, &adapter->port_list, list)
 		zfcp_erp_port_access_changed(port, id, ref);
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
+	read_unlock_irqrestore(&adapter->port_list_lock, flags);
 }
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index b3f28de..03dec83 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -9,26 +9,31 @@
 #ifndef ZFCP_EXT_H
 #define ZFCP_EXT_H
 
+#include <linux/types.h>
+#include <scsi/fc/fc_els.h>
 #include "zfcp_def.h"
+#include "zfcp_fc.h"
 
 /* zfcp_aux.c */
 extern struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *, u64);
 extern struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *, u64);
-extern int zfcp_adapter_enqueue(struct ccw_device *);
-extern void zfcp_adapter_dequeue(struct zfcp_adapter *);
+extern struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *);
 extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, u64, u32,
 					   u32);
-extern void zfcp_port_dequeue(struct zfcp_port *);
 extern struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *, u64);
-extern void zfcp_unit_dequeue(struct zfcp_unit *);
 extern int zfcp_reqlist_isempty(struct zfcp_adapter *);
 extern void zfcp_sg_free_table(struct scatterlist *, int);
 extern int zfcp_sg_setup_table(struct scatterlist *, int);
+extern void zfcp_device_unregister(struct device *,
+				   const struct attribute_group *);
+extern void zfcp_adapter_release(struct kref *);
+extern void zfcp_adapter_unregister(struct zfcp_adapter *);
 
 /* zfcp_ccw.c */
-extern int zfcp_ccw_register(void);
 extern int zfcp_ccw_priv_sch(struct zfcp_adapter *);
 extern struct ccw_driver zfcp_ccw_driver;
+extern struct zfcp_adapter *zfcp_ccw_adapter_by_cdev(struct ccw_device *);
+extern void zfcp_ccw_adapter_put(struct zfcp_adapter *);
 
 /* zfcp_cfdc.c */
 extern struct miscdevice zfcp_cfdc_misc;
@@ -51,7 +56,7 @@
 					  struct fsf_status_read_buffer *);
 extern void zfcp_dbf_hba_qdio(struct zfcp_dbf *, unsigned int, int, int);
 extern void zfcp_dbf_hba_berr(struct zfcp_dbf *, struct zfcp_fsf_req *);
-extern void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *);
+extern void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *, u32);
 extern void zfcp_dbf_san_ct_response(struct zfcp_fsf_req *);
 extern void zfcp_dbf_san_els_request(struct zfcp_fsf_req *);
 extern void zfcp_dbf_san_els_response(struct zfcp_fsf_req *);
@@ -92,24 +97,22 @@
 extern void zfcp_erp_timeout_handler(unsigned long);
 
 /* zfcp_fc.c */
-extern int zfcp_fc_scan_ports(struct zfcp_adapter *);
-extern void _zfcp_fc_scan_ports_later(struct work_struct *);
+extern void zfcp_fc_scan_ports(struct work_struct *);
 extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *);
 extern void zfcp_fc_port_did_lookup(struct work_struct *);
 extern void zfcp_fc_trigger_did_lookup(struct zfcp_port *);
-extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *);
+extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fc_els_flogi *);
 extern void zfcp_fc_test_link(struct zfcp_port *);
 extern void zfcp_fc_link_test_work(struct work_struct *);
-extern void zfcp_fc_wka_ports_force_offline(struct zfcp_wka_ports *);
+extern void zfcp_fc_wka_ports_force_offline(struct zfcp_fc_wka_ports *);
 extern int zfcp_fc_gs_setup(struct zfcp_adapter *);
 extern void zfcp_fc_gs_destroy(struct zfcp_adapter *);
-extern int zfcp_fc_execute_els_fc_job(struct fc_bsg_job *);
-extern int zfcp_fc_execute_ct_fc_job(struct fc_bsg_job *);
+extern int zfcp_fc_exec_bsg_job(struct fc_bsg_job *);
 
 /* zfcp_fsf.c */
 extern int zfcp_fsf_open_port(struct zfcp_erp_action *);
-extern int zfcp_fsf_open_wka_port(struct zfcp_wka_port *);
-extern int zfcp_fsf_close_wka_port(struct zfcp_wka_port *);
+extern int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *);
+extern int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *);
 extern int zfcp_fsf_close_port(struct zfcp_erp_action *);
 extern int zfcp_fsf_close_physical_port(struct zfcp_erp_action *);
 extern int zfcp_fsf_open_unit(struct zfcp_erp_action *);
@@ -125,8 +128,10 @@
 extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *);
 extern int zfcp_fsf_status_read(struct zfcp_qdio *);
 extern int zfcp_status_read_refill(struct zfcp_adapter *adapter);
-extern int zfcp_fsf_send_ct(struct zfcp_send_ct *, mempool_t *);
-extern int zfcp_fsf_send_els(struct zfcp_send_els *);
+extern int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *, struct zfcp_fsf_ct_els *,
+			    mempool_t *);
+extern int zfcp_fsf_send_els(struct zfcp_adapter *, u32,
+			     struct zfcp_fsf_ct_els *);
 extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *,
 					  struct scsi_cmnd *);
 extern void zfcp_fsf_req_free(struct zfcp_fsf_req *);
@@ -153,7 +158,6 @@
 extern struct zfcp_data zfcp_data;
 extern int zfcp_adapter_scsi_register(struct zfcp_adapter *);
 extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *);
-extern char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *);
 extern struct fc_function_template zfcp_transport_functions;
 extern void zfcp_scsi_rport_work(struct work_struct *);
 extern void zfcp_scsi_schedule_rport_register(struct zfcp_port *);
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index df23bce..ac5e3b7 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -9,73 +9,38 @@
 #define KMSG_COMPONENT "zfcp"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
+#include <linux/types.h>
+#include <scsi/fc/fc_els.h>
+#include <scsi/libfc.h>
 #include "zfcp_ext.h"
+#include "zfcp_fc.h"
 
-enum rscn_address_format {
-	RSCN_PORT_ADDRESS	= 0x0,
-	RSCN_AREA_ADDRESS	= 0x1,
-	RSCN_DOMAIN_ADDRESS	= 0x2,
-	RSCN_FABRIC_ADDRESS	= 0x3,
+static u32 zfcp_fc_rscn_range_mask[] = {
+	[ELS_ADDR_FMT_PORT]		= 0xFFFFFF,
+	[ELS_ADDR_FMT_AREA]		= 0xFFFF00,
+	[ELS_ADDR_FMT_DOM]		= 0xFF0000,
+	[ELS_ADDR_FMT_FAB]		= 0x000000,
 };
 
-static u32 rscn_range_mask[] = {
-	[RSCN_PORT_ADDRESS]		= 0xFFFFFF,
-	[RSCN_AREA_ADDRESS]		= 0xFFFF00,
-	[RSCN_DOMAIN_ADDRESS]		= 0xFF0000,
-	[RSCN_FABRIC_ADDRESS]		= 0x000000,
-};
-
-struct gpn_ft_resp_acc {
-	u8 control;
-	u8 port_id[3];
-	u8 reserved[4];
-	u64 wwpn;
-} __attribute__ ((packed));
-
-#define ZFCP_CT_SIZE_ONE_PAGE	(PAGE_SIZE - sizeof(struct ct_hdr))
-#define ZFCP_GPN_FT_ENTRIES	(ZFCP_CT_SIZE_ONE_PAGE \
-					/ sizeof(struct gpn_ft_resp_acc))
-#define ZFCP_GPN_FT_BUFFERS 4
-#define ZFCP_GPN_FT_MAX_SIZE (ZFCP_GPN_FT_BUFFERS * PAGE_SIZE \
-				- sizeof(struct ct_hdr))
-#define ZFCP_GPN_FT_MAX_ENTRIES ZFCP_GPN_FT_BUFFERS * (ZFCP_GPN_FT_ENTRIES + 1)
-
-struct ct_iu_gpn_ft_resp {
-	struct ct_hdr header;
-	struct gpn_ft_resp_acc accept[ZFCP_GPN_FT_ENTRIES];
-} __attribute__ ((packed));
-
-struct zfcp_gpn_ft {
-	struct zfcp_send_ct ct;
-	struct scatterlist sg_req;
-	struct scatterlist sg_resp[ZFCP_GPN_FT_BUFFERS];
-};
-
-struct zfcp_fc_ns_handler_data {
-	struct completion done;
-	void (*handler)(unsigned long);
-	unsigned long handler_data;
-};
-
-static int zfcp_fc_wka_port_get(struct zfcp_wka_port *wka_port)
+static int zfcp_fc_wka_port_get(struct zfcp_fc_wka_port *wka_port)
 {
 	if (mutex_lock_interruptible(&wka_port->mutex))
 		return -ERESTARTSYS;
 
-	if (wka_port->status == ZFCP_WKA_PORT_OFFLINE ||
-	    wka_port->status == ZFCP_WKA_PORT_CLOSING) {
-		wka_port->status = ZFCP_WKA_PORT_OPENING;
+	if (wka_port->status == ZFCP_FC_WKA_PORT_OFFLINE ||
+	    wka_port->status == ZFCP_FC_WKA_PORT_CLOSING) {
+		wka_port->status = ZFCP_FC_WKA_PORT_OPENING;
 		if (zfcp_fsf_open_wka_port(wka_port))
-			wka_port->status = ZFCP_WKA_PORT_OFFLINE;
+			wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE;
 	}
 
 	mutex_unlock(&wka_port->mutex);
 
 	wait_event(wka_port->completion_wq,
-		   wka_port->status == ZFCP_WKA_PORT_ONLINE ||
-		   wka_port->status == ZFCP_WKA_PORT_OFFLINE);
+		   wka_port->status == ZFCP_FC_WKA_PORT_ONLINE ||
+		   wka_port->status == ZFCP_FC_WKA_PORT_OFFLINE);
 
-	if (wka_port->status == ZFCP_WKA_PORT_ONLINE) {
+	if (wka_port->status == ZFCP_FC_WKA_PORT_ONLINE) {
 		atomic_inc(&wka_port->refcount);
 		return 0;
 	}
@@ -85,24 +50,24 @@
 static void zfcp_fc_wka_port_offline(struct work_struct *work)
 {
 	struct delayed_work *dw = to_delayed_work(work);
-	struct zfcp_wka_port *wka_port =
-			container_of(dw, struct zfcp_wka_port, work);
+	struct zfcp_fc_wka_port *wka_port =
+			container_of(dw, struct zfcp_fc_wka_port, work);
 
 	mutex_lock(&wka_port->mutex);
 	if ((atomic_read(&wka_port->refcount) != 0) ||
-	    (wka_port->status != ZFCP_WKA_PORT_ONLINE))
+	    (wka_port->status != ZFCP_FC_WKA_PORT_ONLINE))
 		goto out;
 
-	wka_port->status = ZFCP_WKA_PORT_CLOSING;
+	wka_port->status = ZFCP_FC_WKA_PORT_CLOSING;
 	if (zfcp_fsf_close_wka_port(wka_port)) {
-		wka_port->status = ZFCP_WKA_PORT_OFFLINE;
+		wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE;
 		wake_up(&wka_port->completion_wq);
 	}
 out:
 	mutex_unlock(&wka_port->mutex);
 }
 
-static void zfcp_fc_wka_port_put(struct zfcp_wka_port *wka_port)
+static void zfcp_fc_wka_port_put(struct zfcp_fc_wka_port *wka_port)
 {
 	if (atomic_dec_return(&wka_port->refcount) != 0)
 		return;
@@ -110,7 +75,7 @@
 	schedule_delayed_work(&wka_port->work, HZ / 100);
 }
 
-static void zfcp_fc_wka_port_init(struct zfcp_wka_port *wka_port, u32 d_id,
+static void zfcp_fc_wka_port_init(struct zfcp_fc_wka_port *wka_port, u32 d_id,
 				  struct zfcp_adapter *adapter)
 {
 	init_waitqueue_head(&wka_port->completion_wq);
@@ -118,107 +83,107 @@
 	wka_port->adapter = adapter;
 	wka_port->d_id = d_id;
 
-	wka_port->status = ZFCP_WKA_PORT_OFFLINE;
+	wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE;
 	atomic_set(&wka_port->refcount, 0);
 	mutex_init(&wka_port->mutex);
 	INIT_DELAYED_WORK(&wka_port->work, zfcp_fc_wka_port_offline);
 }
 
-static void zfcp_fc_wka_port_force_offline(struct zfcp_wka_port *wka)
+static void zfcp_fc_wka_port_force_offline(struct zfcp_fc_wka_port *wka)
 {
 	cancel_delayed_work_sync(&wka->work);
 	mutex_lock(&wka->mutex);
-	wka->status = ZFCP_WKA_PORT_OFFLINE;
+	wka->status = ZFCP_FC_WKA_PORT_OFFLINE;
 	mutex_unlock(&wka->mutex);
 }
 
-void zfcp_fc_wka_ports_force_offline(struct zfcp_wka_ports *gs)
+void zfcp_fc_wka_ports_force_offline(struct zfcp_fc_wka_ports *gs)
 {
+	if (!gs)
+		return;
 	zfcp_fc_wka_port_force_offline(&gs->ms);
 	zfcp_fc_wka_port_force_offline(&gs->ts);
 	zfcp_fc_wka_port_force_offline(&gs->ds);
 	zfcp_fc_wka_port_force_offline(&gs->as);
-	zfcp_fc_wka_port_force_offline(&gs->ks);
 }
 
 static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
-				   struct fcp_rscn_element *elem)
+				   struct fc_els_rscn_page *page)
 {
 	unsigned long flags;
+	struct zfcp_adapter *adapter = fsf_req->adapter;
 	struct zfcp_port *port;
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	list_for_each_entry(port, &fsf_req->adapter->port_list_head, list) {
-		if ((port->d_id & range) == (elem->nport_did & range))
+	read_lock_irqsave(&adapter->port_list_lock, flags);
+	list_for_each_entry(port, &adapter->port_list, list) {
+		if ((port->d_id & range) == (ntoh24(page->rscn_fid) & range))
 			zfcp_fc_test_link(port);
 		if (!port->d_id)
 			zfcp_erp_port_reopen(port,
 					     ZFCP_STATUS_COMMON_ERP_FAILED,
 					     "fcrscn1", NULL);
 	}
-
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
+	read_unlock_irqrestore(&adapter->port_list_lock, flags);
 }
 
 static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req)
 {
 	struct fsf_status_read_buffer *status_buffer = (void *)fsf_req->data;
-	struct fcp_rscn_head *fcp_rscn_head;
-	struct fcp_rscn_element *fcp_rscn_element;
+	struct fc_els_rscn *head;
+	struct fc_els_rscn_page *page;
 	u16 i;
 	u16 no_entries;
-	u32 range_mask;
+	unsigned int afmt;
 
-	fcp_rscn_head = (struct fcp_rscn_head *) status_buffer->payload.data;
-	fcp_rscn_element = (struct fcp_rscn_element *) fcp_rscn_head;
+	head = (struct fc_els_rscn *) status_buffer->payload.data;
+	page = (struct fc_els_rscn_page *) head;
 
 	/* see FC-FS */
-	no_entries = fcp_rscn_head->payload_len /
-			sizeof(struct fcp_rscn_element);
+	no_entries = head->rscn_plen / sizeof(struct fc_els_rscn_page);
 
 	for (i = 1; i < no_entries; i++) {
 		/* skip head and start with 1st element */
-		fcp_rscn_element++;
-		range_mask = rscn_range_mask[fcp_rscn_element->addr_format];
-		_zfcp_fc_incoming_rscn(fsf_req, range_mask, fcp_rscn_element);
+		page++;
+		afmt = page->rscn_page_flags & ELS_RSCN_ADDR_FMT_MASK;
+		_zfcp_fc_incoming_rscn(fsf_req, zfcp_fc_rscn_range_mask[afmt],
+				       page);
 	}
-	schedule_work(&fsf_req->adapter->scan_work);
+	queue_work(fsf_req->adapter->work_queue, &fsf_req->adapter->scan_work);
 }
 
 static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, u64 wwpn)
 {
+	unsigned long flags;
 	struct zfcp_adapter *adapter = req->adapter;
 	struct zfcp_port *port;
-	unsigned long flags;
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	list_for_each_entry(port, &adapter->port_list_head, list)
-		if (port->wwpn == wwpn)
+	read_lock_irqsave(&adapter->port_list_lock, flags);
+	list_for_each_entry(port, &adapter->port_list, list)
+		if (port->wwpn == wwpn) {
+			zfcp_erp_port_forced_reopen(port, 0, "fciwwp1", req);
 			break;
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
-
-	if (port && (port->wwpn == wwpn))
-		zfcp_erp_port_forced_reopen(port, 0, "fciwwp1", req);
+		}
+	read_unlock_irqrestore(&adapter->port_list_lock, flags);
 }
 
 static void zfcp_fc_incoming_plogi(struct zfcp_fsf_req *req)
 {
-	struct fsf_status_read_buffer *status_buffer =
-		(struct fsf_status_read_buffer *)req->data;
-	struct fsf_plogi *els_plogi =
-		(struct fsf_plogi *) status_buffer->payload.data;
+	struct fsf_status_read_buffer *status_buffer;
+	struct fc_els_flogi *plogi;
 
-	zfcp_fc_incoming_wwpn(req, els_plogi->serv_param.wwpn);
+	status_buffer = (struct fsf_status_read_buffer *) req->data;
+	plogi = (struct fc_els_flogi *) status_buffer->payload.data;
+	zfcp_fc_incoming_wwpn(req, plogi->fl_wwpn);
 }
 
 static void zfcp_fc_incoming_logo(struct zfcp_fsf_req *req)
 {
 	struct fsf_status_read_buffer *status_buffer =
 		(struct fsf_status_read_buffer *)req->data;
-	struct fcp_logo *els_logo =
-		(struct fcp_logo *) status_buffer->payload.data;
+	struct fc_els_logo *logo =
+		(struct fc_els_logo *) status_buffer->payload.data;
 
-	zfcp_fc_incoming_wwpn(req, els_logo->nport_wwpn);
+	zfcp_fc_incoming_wwpn(req, logo->fl_n_port_wwn);
 }
 
 /**
@@ -232,79 +197,72 @@
 	unsigned int els_type = status_buffer->payload.data[0];
 
 	zfcp_dbf_san_incoming_els(fsf_req);
-	if (els_type == LS_PLOGI)
+	if (els_type == ELS_PLOGI)
 		zfcp_fc_incoming_plogi(fsf_req);
-	else if (els_type == LS_LOGO)
+	else if (els_type == ELS_LOGO)
 		zfcp_fc_incoming_logo(fsf_req);
-	else if (els_type == LS_RSCN)
+	else if (els_type == ELS_RSCN)
 		zfcp_fc_incoming_rscn(fsf_req);
 }
 
-static void zfcp_fc_ns_handler(unsigned long data)
+static void zfcp_fc_ns_gid_pn_eval(void *data)
 {
-	struct zfcp_fc_ns_handler_data *compl_rec =
-			(struct zfcp_fc_ns_handler_data *) data;
-
-	if (compl_rec->handler)
-		compl_rec->handler(compl_rec->handler_data);
-
-	complete(&compl_rec->done);
-}
-
-static void zfcp_fc_ns_gid_pn_eval(unsigned long data)
-{
-	struct zfcp_gid_pn_data *gid_pn = (struct zfcp_gid_pn_data *) data;
-	struct zfcp_send_ct *ct = &gid_pn->ct;
-	struct ct_iu_gid_pn_req *ct_iu_req = sg_virt(ct->req);
-	struct ct_iu_gid_pn_resp *ct_iu_resp = sg_virt(ct->resp);
+	struct zfcp_fc_gid_pn *gid_pn = data;
+	struct zfcp_fsf_ct_els *ct = &gid_pn->ct;
+	struct zfcp_fc_gid_pn_req *gid_pn_req = sg_virt(ct->req);
+	struct zfcp_fc_gid_pn_resp *gid_pn_resp = sg_virt(ct->resp);
 	struct zfcp_port *port = gid_pn->port;
 
 	if (ct->status)
 		return;
-	if (ct_iu_resp->header.cmd_rsp_code != ZFCP_CT_ACCEPT)
+	if (gid_pn_resp->ct_hdr.ct_cmd != FC_FS_ACC)
 		return;
 
 	/* paranoia */
-	if (ct_iu_req->wwpn != port->wwpn)
+	if (gid_pn_req->gid_pn.fn_wwpn != port->wwpn)
 		return;
 	/* looks like a valid d_id */
-	port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK;
+	port->d_id = ntoh24(gid_pn_resp->gid_pn.fp_fid);
+}
+
+static void zfcp_fc_complete(void *data)
+{
+	complete(data);
 }
 
 static int zfcp_fc_ns_gid_pn_request(struct zfcp_port *port,
-				     struct zfcp_gid_pn_data *gid_pn)
+				     struct zfcp_fc_gid_pn *gid_pn)
 {
 	struct zfcp_adapter *adapter = port->adapter;
-	struct zfcp_fc_ns_handler_data compl_rec;
+	DECLARE_COMPLETION_ONSTACK(completion);
 	int ret;
 
 	/* setup parameters for send generic command */
 	gid_pn->port = port;
-	gid_pn->ct.wka_port = &adapter->gs->ds;
-	gid_pn->ct.handler = zfcp_fc_ns_handler;
-	gid_pn->ct.handler_data = (unsigned long) &compl_rec;
-	gid_pn->ct.req = &gid_pn->req;
-	gid_pn->ct.resp = &gid_pn->resp;
-	sg_init_one(&gid_pn->req, &gid_pn->ct_iu_req,
-		    sizeof(struct ct_iu_gid_pn_req));
-	sg_init_one(&gid_pn->resp, &gid_pn->ct_iu_resp,
-		    sizeof(struct ct_iu_gid_pn_resp));
+	gid_pn->ct.handler = zfcp_fc_complete;
+	gid_pn->ct.handler_data = &completion;
+	gid_pn->ct.req = &gid_pn->sg_req;
+	gid_pn->ct.resp = &gid_pn->sg_resp;
+	sg_init_one(&gid_pn->sg_req, &gid_pn->gid_pn_req,
+		    sizeof(struct zfcp_fc_gid_pn_req));
+	sg_init_one(&gid_pn->sg_resp, &gid_pn->gid_pn_resp,
+		    sizeof(struct zfcp_fc_gid_pn_resp));
 
 	/* setup nameserver request */
-	gid_pn->ct_iu_req.header.revision = ZFCP_CT_REVISION;
-	gid_pn->ct_iu_req.header.gs_type = ZFCP_CT_DIRECTORY_SERVICE;
-	gid_pn->ct_iu_req.header.gs_subtype = ZFCP_CT_NAME_SERVER;
-	gid_pn->ct_iu_req.header.options = ZFCP_CT_SYNCHRONOUS;
-	gid_pn->ct_iu_req.header.cmd_rsp_code = ZFCP_CT_GID_PN;
-	gid_pn->ct_iu_req.header.max_res_size = ZFCP_CT_SIZE_ONE_PAGE / 4;
-	gid_pn->ct_iu_req.wwpn = port->wwpn;
+	gid_pn->gid_pn_req.ct_hdr.ct_rev = FC_CT_REV;
+	gid_pn->gid_pn_req.ct_hdr.ct_fs_type = FC_FST_DIR;
+	gid_pn->gid_pn_req.ct_hdr.ct_fs_subtype = FC_NS_SUBTYPE;
+	gid_pn->gid_pn_req.ct_hdr.ct_options = 0;
+	gid_pn->gid_pn_req.ct_hdr.ct_cmd = FC_NS_GID_PN;
+	gid_pn->gid_pn_req.ct_hdr.ct_mr_size = ZFCP_FC_CT_SIZE_PAGE / 4;
+	gid_pn->gid_pn_req.gid_pn.fn_wwpn = port->wwpn;
 
-	init_completion(&compl_rec.done);
-	compl_rec.handler = zfcp_fc_ns_gid_pn_eval;
-	compl_rec.handler_data = (unsigned long) gid_pn;
-	ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.gid_pn_req);
-	if (!ret)
-		wait_for_completion(&compl_rec.done);
+	ret = zfcp_fsf_send_ct(&adapter->gs->ds, &gid_pn->ct,
+			       adapter->pool.gid_pn_req);
+	if (!ret) {
+		wait_for_completion(&completion);
+		zfcp_fc_ns_gid_pn_eval(gid_pn);
+	}
 	return ret;
 }
 
@@ -316,10 +274,10 @@
 static int zfcp_fc_ns_gid_pn(struct zfcp_port *port)
 {
 	int ret;
-	struct zfcp_gid_pn_data *gid_pn;
+	struct zfcp_fc_gid_pn *gid_pn;
 	struct zfcp_adapter *adapter = port->adapter;
 
-	gid_pn = mempool_alloc(adapter->pool.gid_pn_data, GFP_ATOMIC);
+	gid_pn = mempool_alloc(adapter->pool.gid_pn, GFP_ATOMIC);
 	if (!gid_pn)
 		return -ENOMEM;
 
@@ -333,7 +291,7 @@
 
 	zfcp_fc_wka_port_put(&adapter->gs->ds);
 out:
-	mempool_free(gid_pn, adapter->pool.gid_pn_data);
+	mempool_free(gid_pn, adapter->pool.gid_pn);
 	return ret;
 }
 
@@ -357,7 +315,7 @@
 
 	zfcp_erp_port_reopen(port, 0, "fcgpn_3", NULL);
 out:
-	zfcp_port_put(port);
+	put_device(&port->sysfs_device);
 }
 
 /**
@@ -366,9 +324,9 @@
  */
 void zfcp_fc_trigger_did_lookup(struct zfcp_port *port)
 {
-	zfcp_port_get(port);
+	get_device(&port->sysfs_device);
 	if (!queue_work(port->adapter->work_queue, &port->gid_pn_work))
-		zfcp_port_put(port);
+		put_device(&port->sysfs_device);
 }
 
 /**
@@ -378,33 +336,36 @@
  *
  * Evaluate PLOGI playload and copy important fields into zfcp_port structure
  */
-void zfcp_fc_plogi_evaluate(struct zfcp_port *port, struct fsf_plogi *plogi)
+void zfcp_fc_plogi_evaluate(struct zfcp_port *port, struct fc_els_flogi *plogi)
 {
-	port->maxframe_size = plogi->serv_param.common_serv_param[7] |
-		((plogi->serv_param.common_serv_param[6] & 0x0F) << 8);
-	if (plogi->serv_param.class1_serv_param[0] & 0x80)
+	if (plogi->fl_wwpn != port->wwpn) {
+		port->d_id = 0;
+		dev_warn(&port->adapter->ccw_device->dev,
+			 "A port opened with WWPN 0x%016Lx returned data that "
+			 "identifies it as WWPN 0x%016Lx\n",
+			 (unsigned long long) port->wwpn,
+			 (unsigned long long) plogi->fl_wwpn);
+		return;
+	}
+
+	port->wwnn = plogi->fl_wwnn;
+	port->maxframe_size = plogi->fl_csp.sp_bb_data;
+
+	if (plogi->fl_cssp[0].cp_class & FC_CPC_VALID)
 		port->supported_classes |= FC_COS_CLASS1;
-	if (plogi->serv_param.class2_serv_param[0] & 0x80)
+	if (plogi->fl_cssp[1].cp_class & FC_CPC_VALID)
 		port->supported_classes |= FC_COS_CLASS2;
-	if (plogi->serv_param.class3_serv_param[0] & 0x80)
+	if (plogi->fl_cssp[2].cp_class & FC_CPC_VALID)
 		port->supported_classes |= FC_COS_CLASS3;
-	if (plogi->serv_param.class4_serv_param[0] & 0x80)
+	if (plogi->fl_cssp[3].cp_class & FC_CPC_VALID)
 		port->supported_classes |= FC_COS_CLASS4;
 }
 
-struct zfcp_els_adisc {
-	struct zfcp_send_els els;
-	struct scatterlist req;
-	struct scatterlist resp;
-	struct zfcp_ls_adisc ls_adisc;
-	struct zfcp_ls_adisc ls_adisc_acc;
-};
-
-static void zfcp_fc_adisc_handler(unsigned long data)
+static void zfcp_fc_adisc_handler(void *data)
 {
-	struct zfcp_els_adisc *adisc = (struct zfcp_els_adisc *) data;
+	struct zfcp_fc_els_adisc *adisc = data;
 	struct zfcp_port *port = adisc->els.port;
-	struct zfcp_ls_adisc *ls_adisc = &adisc->ls_adisc_acc;
+	struct fc_els_adisc *adisc_resp = &adisc->adisc_resp;
 
 	if (adisc->els.status) {
 		/* request rejected or timed out */
@@ -414,9 +375,9 @@
 	}
 
 	if (!port->wwnn)
-		port->wwnn = ls_adisc->wwnn;
+		port->wwnn = adisc_resp->adisc_wwnn;
 
-	if ((port->wwpn != ls_adisc->wwpn) ||
+	if ((port->wwpn != adisc_resp->adisc_wwpn) ||
 	    !(atomic_read(&port->status) & ZFCP_STATUS_COMMON_OPEN)) {
 		zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED,
 				     "fcadh_2", NULL);
@@ -427,40 +388,44 @@
 	zfcp_scsi_schedule_rport_register(port);
  out:
 	atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status);
-	zfcp_port_put(port);
-	kfree(adisc);
+	put_device(&port->sysfs_device);
+	kmem_cache_free(zfcp_data.adisc_cache, adisc);
 }
 
 static int zfcp_fc_adisc(struct zfcp_port *port)
 {
-	struct zfcp_els_adisc *adisc;
+	struct zfcp_fc_els_adisc *adisc;
 	struct zfcp_adapter *adapter = port->adapter;
+	int ret;
 
-	adisc = kzalloc(sizeof(struct zfcp_els_adisc), GFP_ATOMIC);
+	adisc = kmem_cache_alloc(zfcp_data.adisc_cache, GFP_ATOMIC);
 	if (!adisc)
 		return -ENOMEM;
 
+	adisc->els.port = port;
 	adisc->els.req = &adisc->req;
 	adisc->els.resp = &adisc->resp;
-	sg_init_one(adisc->els.req, &adisc->ls_adisc,
-		    sizeof(struct zfcp_ls_adisc));
-	sg_init_one(adisc->els.resp, &adisc->ls_adisc_acc,
-		    sizeof(struct zfcp_ls_adisc));
+	sg_init_one(adisc->els.req, &adisc->adisc_req,
+		    sizeof(struct fc_els_adisc));
+	sg_init_one(adisc->els.resp, &adisc->adisc_resp,
+		    sizeof(struct fc_els_adisc));
 
-	adisc->els.adapter = adapter;
-	adisc->els.port = port;
-	adisc->els.d_id = port->d_id;
 	adisc->els.handler = zfcp_fc_adisc_handler;
-	adisc->els.handler_data = (unsigned long) adisc;
-	adisc->els.ls_code = adisc->ls_adisc.code = ZFCP_LS_ADISC;
+	adisc->els.handler_data = adisc;
 
 	/* acc. to FC-FS, hard_nport_id in ADISC should not be set for ports
 	   without FC-AL-2 capability, so we don't set it */
-	adisc->ls_adisc.wwpn = fc_host_port_name(adapter->scsi_host);
-	adisc->ls_adisc.wwnn = fc_host_node_name(adapter->scsi_host);
-	adisc->ls_adisc.nport_id = fc_host_port_id(adapter->scsi_host);
+	adisc->adisc_req.adisc_wwpn = fc_host_port_name(adapter->scsi_host);
+	adisc->adisc_req.adisc_wwnn = fc_host_node_name(adapter->scsi_host);
+	adisc->adisc_req.adisc_cmd = ELS_ADISC;
+	hton24(adisc->adisc_req.adisc_port_id,
+	       fc_host_port_id(adapter->scsi_host));
 
-	return zfcp_fsf_send_els(&adisc->els);
+	ret = zfcp_fsf_send_els(adapter, port->d_id, &adisc->els);
+	if (ret)
+		kmem_cache_free(zfcp_data.adisc_cache, adisc);
+
+	return ret;
 }
 
 void zfcp_fc_link_test_work(struct work_struct *work)
@@ -469,7 +434,7 @@
 		container_of(work, struct zfcp_port, test_link_work);
 	int retval;
 
-	zfcp_port_get(port);
+	get_device(&port->sysfs_device);
 	port->rport_task = RPORT_DEL;
 	zfcp_scsi_rport_work(&port->rport_work);
 
@@ -488,7 +453,7 @@
 	zfcp_erp_port_forced_reopen(port, 0, "fcltwk1", NULL);
 
 out:
-	zfcp_port_put(port);
+	put_device(&port->sysfs_device);
 }
 
 /**
@@ -501,12 +466,12 @@
  */
 void zfcp_fc_test_link(struct zfcp_port *port)
 {
-	zfcp_port_get(port);
+	get_device(&port->sysfs_device);
 	if (!queue_work(port->adapter->work_queue, &port->test_link_work))
-		zfcp_port_put(port);
+		put_device(&port->sysfs_device);
 }
 
-static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft, int buf_num)
+static void zfcp_free_sg_env(struct zfcp_fc_gpn_ft *gpn_ft, int buf_num)
 {
 	struct scatterlist *sg = &gpn_ft->sg_req;
 
@@ -516,10 +481,10 @@
 	kfree(gpn_ft);
 }
 
-static struct zfcp_gpn_ft *zfcp_alloc_sg_env(int buf_num)
+static struct zfcp_fc_gpn_ft *zfcp_alloc_sg_env(int buf_num)
 {
-	struct zfcp_gpn_ft *gpn_ft;
-	struct ct_iu_gpn_ft_req *req;
+	struct zfcp_fc_gpn_ft *gpn_ft;
+	struct zfcp_fc_gpn_ft_req *req;
 
 	gpn_ft = kzalloc(sizeof(*gpn_ft), GFP_KERNEL);
 	if (!gpn_ft)
@@ -542,159 +507,152 @@
 }
 
 
-static int zfcp_fc_send_gpn_ft(struct zfcp_gpn_ft *gpn_ft,
+static int zfcp_fc_send_gpn_ft(struct zfcp_fc_gpn_ft *gpn_ft,
 			       struct zfcp_adapter *adapter, int max_bytes)
 {
-	struct zfcp_send_ct *ct = &gpn_ft->ct;
-	struct ct_iu_gpn_ft_req *req = sg_virt(&gpn_ft->sg_req);
-	struct zfcp_fc_ns_handler_data compl_rec;
+	struct zfcp_fsf_ct_els *ct = &gpn_ft->ct;
+	struct zfcp_fc_gpn_ft_req *req = sg_virt(&gpn_ft->sg_req);
+	DECLARE_COMPLETION_ONSTACK(completion);
 	int ret;
 
 	/* prepare CT IU for GPN_FT */
-	req->header.revision = ZFCP_CT_REVISION;
-	req->header.gs_type = ZFCP_CT_DIRECTORY_SERVICE;
-	req->header.gs_subtype = ZFCP_CT_NAME_SERVER;
-	req->header.options = ZFCP_CT_SYNCHRONOUS;
-	req->header.cmd_rsp_code = ZFCP_CT_GPN_FT;
-	req->header.max_res_size = max_bytes / 4;
-	req->flags = 0;
-	req->domain_id_scope = 0;
-	req->area_id_scope = 0;
-	req->fc4_type = ZFCP_CT_SCSI_FCP;
+	req->ct_hdr.ct_rev = FC_CT_REV;
+	req->ct_hdr.ct_fs_type = FC_FST_DIR;
+	req->ct_hdr.ct_fs_subtype = FC_NS_SUBTYPE;
+	req->ct_hdr.ct_options = 0;
+	req->ct_hdr.ct_cmd = FC_NS_GPN_FT;
+	req->ct_hdr.ct_mr_size = max_bytes / 4;
+	req->gpn_ft.fn_domain_id_scope = 0;
+	req->gpn_ft.fn_area_id_scope = 0;
+	req->gpn_ft.fn_fc4_type = FC_TYPE_FCP;
 
 	/* prepare zfcp_send_ct */
-	ct->wka_port = &adapter->gs->ds;
-	ct->handler = zfcp_fc_ns_handler;
-	ct->handler_data = (unsigned long)&compl_rec;
+	ct->handler = zfcp_fc_complete;
+	ct->handler_data = &completion;
 	ct->req = &gpn_ft->sg_req;
 	ct->resp = gpn_ft->sg_resp;
 
-	init_completion(&compl_rec.done);
-	compl_rec.handler = NULL;
-	ret = zfcp_fsf_send_ct(ct, NULL);
+	ret = zfcp_fsf_send_ct(&adapter->gs->ds, ct, NULL);
 	if (!ret)
-		wait_for_completion(&compl_rec.done);
+		wait_for_completion(&completion);
 	return ret;
 }
 
-static void zfcp_fc_validate_port(struct zfcp_port *port)
+static void zfcp_fc_validate_port(struct zfcp_port *port, struct list_head *lh)
 {
-	struct zfcp_adapter *adapter = port->adapter;
-
 	if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_NOESC))
 		return;
 
 	atomic_clear_mask(ZFCP_STATUS_COMMON_NOESC, &port->status);
 
 	if ((port->supported_classes != 0) ||
-	    !list_empty(&port->unit_list_head)) {
-		zfcp_port_put(port);
+	    !list_empty(&port->unit_list))
 		return;
-	}
-	zfcp_erp_port_shutdown(port, 0, "fcpval1", NULL);
-	zfcp_erp_wait(adapter);
-	zfcp_port_put(port);
-	zfcp_port_dequeue(port);
+
+	list_move_tail(&port->list, lh);
 }
 
-static int zfcp_fc_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries)
+static int zfcp_fc_eval_gpn_ft(struct zfcp_fc_gpn_ft *gpn_ft,
+			       struct zfcp_adapter *adapter, int max_entries)
 {
-	struct zfcp_send_ct *ct = &gpn_ft->ct;
+	struct zfcp_fsf_ct_els *ct = &gpn_ft->ct;
 	struct scatterlist *sg = gpn_ft->sg_resp;
-	struct ct_hdr *hdr = sg_virt(sg);
-	struct gpn_ft_resp_acc *acc = sg_virt(sg);
-	struct zfcp_adapter *adapter = ct->wka_port->adapter;
+	struct fc_ct_hdr *hdr = sg_virt(sg);
+	struct fc_gpn_ft_resp *acc = sg_virt(sg);
 	struct zfcp_port *port, *tmp;
+	unsigned long flags;
+	LIST_HEAD(remove_lh);
 	u32 d_id;
 	int ret = 0, x, last = 0;
 
 	if (ct->status)
 		return -EIO;
 
-	if (hdr->cmd_rsp_code != ZFCP_CT_ACCEPT) {
-		if (hdr->reason_code == ZFCP_CT_UNABLE_TO_PERFORM_CMD)
+	if (hdr->ct_cmd != FC_FS_ACC) {
+		if (hdr->ct_reason == FC_BA_RJT_UNABLE)
 			return -EAGAIN; /* might be a temporary condition */
 		return -EIO;
 	}
 
-	if (hdr->max_res_size) {
+	if (hdr->ct_mr_size) {
 		dev_warn(&adapter->ccw_device->dev,
 			 "The name server reported %d words residual data\n",
-			 hdr->max_res_size);
+			 hdr->ct_mr_size);
 		return -E2BIG;
 	}
 
-	mutex_lock(&zfcp_data.config_mutex);
-
 	/* first entry is the header */
 	for (x = 1; x < max_entries && !last; x++) {
-		if (x % (ZFCP_GPN_FT_ENTRIES + 1))
+		if (x % (ZFCP_FC_GPN_FT_ENT_PAGE + 1))
 			acc++;
 		else
 			acc = sg_virt(++sg);
 
-		last = acc->control & 0x80;
-		d_id = acc->port_id[0] << 16 | acc->port_id[1] << 8 |
-		       acc->port_id[2];
+		last = acc->fp_flags & FC_NS_FID_LAST;
+		d_id = ntoh24(acc->fp_fid);
 
 		/* don't attach ports with a well known address */
-		if ((d_id & ZFCP_DID_WKA) == ZFCP_DID_WKA)
+		if (d_id >= FC_FID_WELL_KNOWN_BASE)
 			continue;
 		/* skip the adapter's port and known remote ports */
-		if (acc->wwpn == fc_host_port_name(adapter->scsi_host))
-			continue;
-		port = zfcp_get_port_by_wwpn(adapter, acc->wwpn);
-		if (port)
+		if (acc->fp_wwpn == fc_host_port_name(adapter->scsi_host))
 			continue;
 
-		port = zfcp_port_enqueue(adapter, acc->wwpn,
+		port = zfcp_port_enqueue(adapter, acc->fp_wwpn,
 					 ZFCP_STATUS_COMMON_NOESC, d_id);
-		if (IS_ERR(port))
-			ret = PTR_ERR(port);
-		else
+		if (!IS_ERR(port))
 			zfcp_erp_port_reopen(port, 0, "fcegpf1", NULL);
+		else if (PTR_ERR(port) != -EEXIST)
+			ret = PTR_ERR(port);
 	}
 
 	zfcp_erp_wait(adapter);
-	list_for_each_entry_safe(port, tmp, &adapter->port_list_head, list)
-		zfcp_fc_validate_port(port);
-	mutex_unlock(&zfcp_data.config_mutex);
+	write_lock_irqsave(&adapter->port_list_lock, flags);
+	list_for_each_entry_safe(port, tmp, &adapter->port_list, list)
+		zfcp_fc_validate_port(port, &remove_lh);
+	write_unlock_irqrestore(&adapter->port_list_lock, flags);
+
+	list_for_each_entry_safe(port, tmp, &remove_lh, list) {
+		zfcp_erp_port_shutdown(port, 0, "fcegpf2", NULL);
+		zfcp_device_unregister(&port->sysfs_device,
+				       &zfcp_sysfs_port_attrs);
+	}
+
 	return ret;
 }
 
 /**
  * zfcp_fc_scan_ports - scan remote ports and attach new ports
- * @adapter: pointer to struct zfcp_adapter
+ * @work: reference to scheduled work
  */
-int zfcp_fc_scan_ports(struct zfcp_adapter *adapter)
+void zfcp_fc_scan_ports(struct work_struct *work)
 {
+	struct zfcp_adapter *adapter = container_of(work, struct zfcp_adapter,
+						    scan_work);
 	int ret, i;
-	struct zfcp_gpn_ft *gpn_ft;
+	struct zfcp_fc_gpn_ft *gpn_ft;
 	int chain, max_entries, buf_num, max_bytes;
 
 	chain = adapter->adapter_features & FSF_FEATURE_ELS_CT_CHAINED_SBALS;
-	buf_num = chain ? ZFCP_GPN_FT_BUFFERS : 1;
-	max_entries = chain ? ZFCP_GPN_FT_MAX_ENTRIES : ZFCP_GPN_FT_ENTRIES;
-	max_bytes = chain ? ZFCP_GPN_FT_MAX_SIZE : ZFCP_CT_SIZE_ONE_PAGE;
+	buf_num = chain ? ZFCP_FC_GPN_FT_NUM_BUFS : 1;
+	max_entries = chain ? ZFCP_FC_GPN_FT_MAX_ENT : ZFCP_FC_GPN_FT_ENT_PAGE;
+	max_bytes = chain ? ZFCP_FC_GPN_FT_MAX_SIZE : ZFCP_FC_CT_SIZE_PAGE;
 
 	if (fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPORT &&
 	    fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPIV)
-		return 0;
+		return;
 
-	ret = zfcp_fc_wka_port_get(&adapter->gs->ds);
-	if (ret)
-		return ret;
+	if (zfcp_fc_wka_port_get(&adapter->gs->ds))
+		return;
 
 	gpn_ft = zfcp_alloc_sg_env(buf_num);
-	if (!gpn_ft) {
-		ret = -ENOMEM;
+	if (!gpn_ft)
 		goto out;
-	}
 
 	for (i = 0; i < 3; i++) {
 		ret = zfcp_fc_send_gpn_ft(gpn_ft, adapter, max_bytes);
 		if (!ret) {
-			ret = zfcp_fc_eval_gpn_ft(gpn_ft, max_entries);
+			ret = zfcp_fc_eval_gpn_ft(gpn_ft, adapter, max_entries);
 			if (ret == -EAGAIN)
 				ssleep(1);
 			else
@@ -704,174 +662,116 @@
 	zfcp_free_sg_env(gpn_ft, buf_num);
 out:
 	zfcp_fc_wka_port_put(&adapter->gs->ds);
-	return ret;
 }
 
-
-void _zfcp_fc_scan_ports_later(struct work_struct *work)
+static void zfcp_fc_ct_els_job_handler(void *data)
 {
-	zfcp_fc_scan_ports(container_of(work, struct zfcp_adapter, scan_work));
-}
+	struct fc_bsg_job *job = data;
+	struct zfcp_fsf_ct_els *zfcp_ct_els = job->dd_data;
+	int status = zfcp_ct_els->status;
+	int reply_status;
 
-struct zfcp_els_fc_job {
-	struct zfcp_send_els els;
-	struct fc_bsg_job *job;
-};
-
-static void zfcp_fc_generic_els_handler(unsigned long data)
-{
-	struct zfcp_els_fc_job *els_fc_job = (struct zfcp_els_fc_job *) data;
-	struct fc_bsg_job *job = els_fc_job->job;
-	struct fc_bsg_reply *reply = job->reply;
-
-	if (els_fc_job->els.status) {
-		/* request rejected or timed out */
-		reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_REJECT;
-		goto out;
-	}
-
-	reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
-	reply->reply_payload_rcv_len = job->reply_payload.payload_len;
-
-out:
-	job->state_flags = FC_RQST_STATE_DONE;
-	job->job_done(job);
-	kfree(els_fc_job);
-}
-
-int zfcp_fc_execute_els_fc_job(struct fc_bsg_job *job)
-{
-	struct zfcp_els_fc_job *els_fc_job;
-	struct fc_rport *rport = job->rport;
-	struct Scsi_Host *shost;
-	struct zfcp_adapter *adapter;
-	struct zfcp_port *port;
-	u8 *port_did;
-
-	shost = rport ? rport_to_shost(rport) : job->shost;
-	adapter = (struct zfcp_adapter *)shost->hostdata[0];
-
-	if (!(atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_OPEN))
-		return -EINVAL;
-
-	els_fc_job = kzalloc(sizeof(struct zfcp_els_fc_job), GFP_KERNEL);
-	if (!els_fc_job)
-		return -ENOMEM;
-
-	els_fc_job->els.adapter = adapter;
-	if (rport) {
-		read_lock_irq(&zfcp_data.config_lock);
-		port = zfcp_get_port_by_wwpn(adapter, rport->port_name);
-		if (port)
-			els_fc_job->els.d_id = port->d_id;
-		read_unlock_irq(&zfcp_data.config_lock);
-		if (!port) {
-			kfree(els_fc_job);
-			return -EINVAL;
-		}
-	} else {
-		port_did = job->request->rqst_data.h_els.port_id;
-		els_fc_job->els.d_id = (port_did[0] << 16) +
-					(port_did[1] << 8) + port_did[2];
-	}
-
-	els_fc_job->els.req = job->request_payload.sg_list;
-	els_fc_job->els.resp = job->reply_payload.sg_list;
-	els_fc_job->els.handler = zfcp_fc_generic_els_handler;
-	els_fc_job->els.handler_data = (unsigned long) els_fc_job;
-	els_fc_job->job = job;
-
-	return zfcp_fsf_send_els(&els_fc_job->els);
-}
-
-struct zfcp_ct_fc_job {
-	struct zfcp_send_ct ct;
-	struct fc_bsg_job *job;
-};
-
-static void zfcp_fc_generic_ct_handler(unsigned long data)
-{
-	struct zfcp_ct_fc_job *ct_fc_job = (struct zfcp_ct_fc_job *) data;
-	struct fc_bsg_job *job = ct_fc_job->job;
-
-	job->reply->reply_data.ctels_reply.status = ct_fc_job->ct.status ?
-				FC_CTELS_STATUS_REJECT : FC_CTELS_STATUS_OK;
+	reply_status = status ? FC_CTELS_STATUS_REJECT : FC_CTELS_STATUS_OK;
+	job->reply->reply_data.ctels_reply.status = reply_status;
 	job->reply->reply_payload_rcv_len = job->reply_payload.payload_len;
-	job->state_flags = FC_RQST_STATE_DONE;
 	job->job_done(job);
-
-	zfcp_fc_wka_port_put(ct_fc_job->ct.wka_port);
-
-	kfree(ct_fc_job);
 }
 
-int zfcp_fc_execute_ct_fc_job(struct fc_bsg_job *job)
+static int zfcp_fc_exec_els_job(struct fc_bsg_job *job,
+				struct zfcp_adapter *adapter)
+{
+	struct zfcp_fsf_ct_els *els = job->dd_data;
+	struct fc_rport *rport = job->rport;
+	struct zfcp_port *port;
+	u32 d_id;
+
+	if (rport) {
+		port = zfcp_get_port_by_wwpn(adapter, rport->port_name);
+		if (!port)
+			return -EINVAL;
+
+		d_id = port->d_id;
+		put_device(&port->sysfs_device);
+	} else
+		d_id = ntoh24(job->request->rqst_data.h_els.port_id);
+
+	return zfcp_fsf_send_els(adapter, d_id, els);
+}
+
+static int zfcp_fc_exec_ct_job(struct fc_bsg_job *job,
+			       struct zfcp_adapter *adapter)
 {
 	int ret;
 	u8 gs_type;
-	struct fc_rport *rport = job->rport;
-	struct Scsi_Host *shost;
-	struct zfcp_adapter *adapter;
-	struct zfcp_ct_fc_job *ct_fc_job;
+	struct zfcp_fsf_ct_els *ct = job->dd_data;
+	struct zfcp_fc_wka_port *wka_port;
 	u32 preamble_word1;
 
-	shost = rport ? rport_to_shost(rport) : job->shost;
-
-	adapter = (struct zfcp_adapter *)shost->hostdata[0];
-	if (!(atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_OPEN))
-		return -EINVAL;
-
-	ct_fc_job = kzalloc(sizeof(struct zfcp_ct_fc_job), GFP_KERNEL);
-	if (!ct_fc_job)
-		return -ENOMEM;
-
 	preamble_word1 = job->request->rqst_data.r_ct.preamble_word1;
 	gs_type = (preamble_word1 & 0xff000000) >> 24;
 
 	switch (gs_type) {
 	case FC_FST_ALIAS:
-		ct_fc_job->ct.wka_port = &adapter->gs->as;
+		wka_port = &adapter->gs->as;
 		break;
 	case FC_FST_MGMT:
-		ct_fc_job->ct.wka_port = &adapter->gs->ms;
+		wka_port = &adapter->gs->ms;
 		break;
 	case FC_FST_TIME:
-		ct_fc_job->ct.wka_port = &adapter->gs->ts;
+		wka_port = &adapter->gs->ts;
 		break;
 	case FC_FST_DIR:
-		ct_fc_job->ct.wka_port = &adapter->gs->ds;
+		wka_port = &adapter->gs->ds;
 		break;
 	default:
-		kfree(ct_fc_job);
 		return -EINVAL; /* no such service */
 	}
 
-	ret = zfcp_fc_wka_port_get(ct_fc_job->ct.wka_port);
-	if (ret) {
-		kfree(ct_fc_job);
+	ret = zfcp_fc_wka_port_get(wka_port);
+	if (ret)
 		return ret;
-	}
 
-	ct_fc_job->ct.req = job->request_payload.sg_list;
-	ct_fc_job->ct.resp = job->reply_payload.sg_list;
-	ct_fc_job->ct.handler = zfcp_fc_generic_ct_handler;
-	ct_fc_job->ct.handler_data = (unsigned long) ct_fc_job;
-	ct_fc_job->ct.completion = NULL;
-	ct_fc_job->job = job;
+	ret = zfcp_fsf_send_ct(wka_port, ct, NULL);
+	if (ret)
+		zfcp_fc_wka_port_put(wka_port);
 
-	ret = zfcp_fsf_send_ct(&ct_fc_job->ct, NULL);
-	if (ret) {
-		kfree(ct_fc_job);
-		zfcp_fc_wka_port_put(ct_fc_job->ct.wka_port);
-	}
 	return ret;
 }
 
+int zfcp_fc_exec_bsg_job(struct fc_bsg_job *job)
+{
+	struct Scsi_Host *shost;
+	struct zfcp_adapter *adapter;
+	struct zfcp_fsf_ct_els *ct_els = job->dd_data;
+
+	shost = job->rport ? rport_to_shost(job->rport) : job->shost;
+	adapter = (struct zfcp_adapter *)shost->hostdata[0];
+
+	if (!(atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_OPEN))
+		return -EINVAL;
+
+	ct_els->req = job->request_payload.sg_list;
+	ct_els->resp = job->reply_payload.sg_list;
+	ct_els->handler = zfcp_fc_ct_els_job_handler;
+	ct_els->handler_data = job;
+
+	switch (job->request->msgcode) {
+	case FC_BSG_RPT_ELS:
+	case FC_BSG_HST_ELS_NOLOGIN:
+		return zfcp_fc_exec_els_job(job, adapter);
+	case FC_BSG_RPT_CT:
+	case FC_BSG_HST_CT:
+		return zfcp_fc_exec_ct_job(job, adapter);
+	default:
+		return -EINVAL;
+	}
+}
+
 int zfcp_fc_gs_setup(struct zfcp_adapter *adapter)
 {
-	struct zfcp_wka_ports *wka_ports;
+	struct zfcp_fc_wka_ports *wka_ports;
 
-	wka_ports = kzalloc(sizeof(struct zfcp_wka_ports), GFP_KERNEL);
+	wka_ports = kzalloc(sizeof(struct zfcp_fc_wka_ports), GFP_KERNEL);
 	if (!wka_ports)
 		return -ENOMEM;
 
@@ -880,7 +780,6 @@
 	zfcp_fc_wka_port_init(&wka_ports->ts, FC_FID_TIME_SERV, adapter);
 	zfcp_fc_wka_port_init(&wka_ports->ds, FC_FID_DIR_SERV, adapter);
 	zfcp_fc_wka_port_init(&wka_ports->as, FC_FID_ALIASES, adapter);
-	zfcp_fc_wka_port_init(&wka_ports->ks, FC_FID_SEC_KEY, adapter);
 
 	return 0;
 }
diff --git a/drivers/s390/scsi/zfcp_fc.h b/drivers/s390/scsi/zfcp_fc.h
new file mode 100644
index 0000000..cb2a366
--- /dev/null
+++ b/drivers/s390/scsi/zfcp_fc.h
@@ -0,0 +1,260 @@
+/*
+ * zfcp device driver
+ *
+ * Fibre Channel related definitions and inline functions for the zfcp
+ * device driver
+ *
+ * Copyright IBM Corporation 2009
+ */
+
+#ifndef ZFCP_FC_H
+#define ZFCP_FC_H
+
+#include <scsi/fc/fc_els.h>
+#include <scsi/fc/fc_fcp.h>
+#include <scsi/fc/fc_ns.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_tcq.h>
+#include "zfcp_fsf.h"
+
+#define ZFCP_FC_CT_SIZE_PAGE	  (PAGE_SIZE - sizeof(struct fc_ct_hdr))
+#define ZFCP_FC_GPN_FT_ENT_PAGE	  (ZFCP_FC_CT_SIZE_PAGE \
+					/ sizeof(struct fc_gpn_ft_resp))
+#define ZFCP_FC_GPN_FT_NUM_BUFS	  4 /* memory pages */
+
+#define ZFCP_FC_GPN_FT_MAX_SIZE	  (ZFCP_FC_GPN_FT_NUM_BUFS * PAGE_SIZE \
+					- sizeof(struct fc_ct_hdr))
+#define ZFCP_FC_GPN_FT_MAX_ENT	  (ZFCP_FC_GPN_FT_NUM_BUFS * \
+					(ZFCP_FC_GPN_FT_ENT_PAGE + 1))
+
+/**
+ * struct zfcp_fc_gid_pn_req - container for ct header plus gid_pn request
+ * @ct_hdr: FC GS common transport header
+ * @gid_pn: GID_PN request
+ */
+struct zfcp_fc_gid_pn_req {
+	struct fc_ct_hdr	ct_hdr;
+	struct fc_ns_gid_pn	gid_pn;
+} __packed;
+
+/**
+ * struct zfcp_fc_gid_pn_resp - container for ct header plus gid_pn response
+ * @ct_hdr: FC GS common transport header
+ * @gid_pn: GID_PN response
+ */
+struct zfcp_fc_gid_pn_resp {
+	struct fc_ct_hdr	ct_hdr;
+	struct fc_gid_pn_resp	gid_pn;
+} __packed;
+
+/**
+ * struct zfcp_fc_gid_pn - everything required in zfcp for gid_pn request
+ * @ct: data passed to zfcp_fsf for issuing fsf request
+ * @sg_req: scatterlist entry for request data
+ * @sg_resp: scatterlist entry for response data
+ * @gid_pn_req: GID_PN request data
+ * @gid_pn_resp: GID_PN response data
+ */
+struct zfcp_fc_gid_pn {
+	struct zfcp_fsf_ct_els ct;
+	struct scatterlist sg_req;
+	struct scatterlist sg_resp;
+	struct zfcp_fc_gid_pn_req gid_pn_req;
+	struct zfcp_fc_gid_pn_resp gid_pn_resp;
+	struct zfcp_port *port;
+};
+
+/**
+ * struct zfcp_fc_gpn_ft - container for ct header plus gpn_ft request
+ * @ct_hdr: FC GS common transport header
+ * @gpn_ft: GPN_FT request
+ */
+struct zfcp_fc_gpn_ft_req {
+	struct fc_ct_hdr	ct_hdr;
+	struct fc_ns_gid_ft	gpn_ft;
+} __packed;
+
+/**
+ * struct zfcp_fc_gpn_ft_resp - container for ct header plus gpn_ft response
+ * @ct_hdr: FC GS common transport header
+ * @gpn_ft: Array of gpn_ft response data to fill one memory page
+ */
+struct zfcp_fc_gpn_ft_resp {
+	struct fc_ct_hdr	ct_hdr;
+	struct fc_gpn_ft_resp	gpn_ft[ZFCP_FC_GPN_FT_ENT_PAGE];
+} __packed;
+
+/**
+ * struct zfcp_fc_gpn_ft - zfcp data for gpn_ft request
+ * @ct: data passed to zfcp_fsf for issuing fsf request
+ * @sg_req: scatter list entry for gpn_ft request
+ * @sg_resp: scatter list entries for gpn_ft responses (per memory page)
+ */
+struct zfcp_fc_gpn_ft {
+	struct zfcp_fsf_ct_els ct;
+	struct scatterlist sg_req;
+	struct scatterlist sg_resp[ZFCP_FC_GPN_FT_NUM_BUFS];
+};
+
+/**
+ * struct zfcp_fc_els_adisc - everything required in zfcp for issuing ELS ADISC
+ * @els: data required for issuing els fsf command
+ * @req: scatterlist entry for ELS ADISC request
+ * @resp: scatterlist entry for ELS ADISC response
+ * @adisc_req: ELS ADISC request data
+ * @adisc_resp: ELS ADISC response data
+ */
+struct zfcp_fc_els_adisc {
+	struct zfcp_fsf_ct_els els;
+	struct scatterlist req;
+	struct scatterlist resp;
+	struct fc_els_adisc adisc_req;
+	struct fc_els_adisc adisc_resp;
+};
+
+/**
+ * enum zfcp_fc_wka_status - FC WKA port status in zfcp
+ * @ZFCP_FC_WKA_PORT_OFFLINE: Port is closed and not in use
+ * @ZFCP_FC_WKA_PORT_CLOSING: The FSF "close port" request is pending
+ * @ZFCP_FC_WKA_PORT_OPENING: The FSF "open port" request is pending
+ * @ZFCP_FC_WKA_PORT_ONLINE: The port is open and the port handle is valid
+ */
+enum zfcp_fc_wka_status {
+	ZFCP_FC_WKA_PORT_OFFLINE,
+	ZFCP_FC_WKA_PORT_CLOSING,
+	ZFCP_FC_WKA_PORT_OPENING,
+	ZFCP_FC_WKA_PORT_ONLINE,
+};
+
+/**
+ * struct zfcp_fc_wka_port - representation of well-known-address (WKA) FC port
+ * @adapter: Pointer to adapter structure this WKA port belongs to
+ * @completion_wq: Wait for completion of open/close command
+ * @status: Current status of WKA port
+ * @refcount: Reference count to keep port open as long as it is in use
+ * @d_id: FC destination id or well-known-address
+ * @handle: FSF handle for the open WKA port
+ * @mutex: Mutex used during opening/closing state changes
+ * @work: For delaying the closing of the WKA port
+ */
+struct zfcp_fc_wka_port {
+	struct zfcp_adapter	*adapter;
+	wait_queue_head_t	completion_wq;
+	enum zfcp_fc_wka_status	status;
+	atomic_t		refcount;
+	u32			d_id;
+	u32			handle;
+	struct mutex		mutex;
+	struct delayed_work	work;
+};
+
+/**
+ * struct zfcp_fc_wka_ports - Data structures for FC generic services
+ * @ms: FC Management service
+ * @ts: FC time service
+ * @ds: FC directory service
+ * @as: FC alias service
+ */
+struct zfcp_fc_wka_ports {
+	struct zfcp_fc_wka_port ms;
+	struct zfcp_fc_wka_port ts;
+	struct zfcp_fc_wka_port ds;
+	struct zfcp_fc_wka_port as;
+};
+
+/**
+ * zfcp_fc_scsi_to_fcp - setup FCP command with data from scsi_cmnd
+ * @fcp: fcp_cmnd to setup
+ * @scsi: scsi_cmnd where to get LUN, task attributes/flags and CDB
+ */
+static inline
+void zfcp_fc_scsi_to_fcp(struct fcp_cmnd *fcp, struct scsi_cmnd *scsi)
+{
+	char tag[2];
+
+	int_to_scsilun(scsi->device->lun, (struct scsi_lun *) &fcp->fc_lun);
+
+	if (scsi_populate_tag_msg(scsi, tag)) {
+		switch (tag[0]) {
+		case MSG_ORDERED_TAG:
+			fcp->fc_pri_ta |= FCP_PTA_ORDERED;
+			break;
+		case MSG_SIMPLE_TAG:
+			fcp->fc_pri_ta |= FCP_PTA_SIMPLE;
+			break;
+		};
+	} else
+		fcp->fc_pri_ta = FCP_PTA_SIMPLE;
+
+	if (scsi->sc_data_direction == DMA_FROM_DEVICE)
+		fcp->fc_flags |= FCP_CFL_RDDATA;
+	if (scsi->sc_data_direction == DMA_TO_DEVICE)
+		fcp->fc_flags |= FCP_CFL_WRDATA;
+
+	memcpy(fcp->fc_cdb, scsi->cmnd, scsi->cmd_len);
+
+	fcp->fc_dl = scsi_bufflen(scsi);
+}
+
+/**
+ * zfcp_fc_fcp_tm - setup FCP command as task management command
+ * @fcp: fcp_cmnd to setup
+ * @dev: scsi_device where to send the task management command
+ * @tm: task management flags to setup tm command
+ */
+static inline
+void zfcp_fc_fcp_tm(struct fcp_cmnd *fcp, struct scsi_device *dev, u8 tm_flags)
+{
+	int_to_scsilun(dev->lun, (struct scsi_lun *) &fcp->fc_lun);
+	fcp->fc_tm_flags |= tm_flags;
+}
+
+/**
+ * zfcp_fc_evap_fcp_rsp - evaluate FCP RSP IU and update scsi_cmnd accordingly
+ * @fcp_rsp: FCP RSP IU to evaluate
+ * @scsi: SCSI command where to update status and sense buffer
+ */
+static inline
+void zfcp_fc_eval_fcp_rsp(struct fcp_resp_with_ext *fcp_rsp,
+			  struct scsi_cmnd *scsi)
+{
+	struct fcp_resp_rsp_info *rsp_info;
+	char *sense;
+	u32 sense_len, resid;
+	u8 rsp_flags;
+
+	set_msg_byte(scsi, COMMAND_COMPLETE);
+	scsi->result |= fcp_rsp->resp.fr_status;
+
+	rsp_flags = fcp_rsp->resp.fr_flags;
+
+	if (unlikely(rsp_flags & FCP_RSP_LEN_VAL)) {
+		rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1];
+		if (rsp_info->rsp_code == FCP_TMF_CMPL)
+			set_host_byte(scsi, DID_OK);
+		else {
+			set_host_byte(scsi, DID_ERROR);
+			return;
+		}
+	}
+
+	if (unlikely(rsp_flags & FCP_SNS_LEN_VAL)) {
+		sense = (char *) &fcp_rsp[1];
+		if (rsp_flags & FCP_RSP_LEN_VAL)
+			sense += fcp_rsp->ext.fr_sns_len;
+		sense_len = min(fcp_rsp->ext.fr_sns_len,
+				(u32) SCSI_SENSE_BUFFERSIZE);
+		memcpy(scsi->sense_buffer, sense, sense_len);
+	}
+
+	if (unlikely(rsp_flags & FCP_RESID_UNDER)) {
+		resid = fcp_rsp->ext.fr_resid;
+		scsi_set_resid(scsi, resid);
+		if (scsi_bufflen(scsi) - resid < scsi->underflow &&
+		     !(rsp_flags & FCP_SNS_LEN_VAL) &&
+		     fcp_rsp->resp.fr_status == SAM_STAT_GOOD)
+			set_host_byte(scsi, DID_ERROR);
+	}
+}
+
+#endif
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 4e41baa..482dcd9 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -10,7 +10,9 @@
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/blktrace_api.h>
+#include <scsi/fc/fc_els.h>
 #include "zfcp_ext.h"
+#include "zfcp_fc.h"
 #include "zfcp_dbf.h"
 
 static void zfcp_fsf_request_timeout_handler(unsigned long data)
@@ -122,36 +124,32 @@
 
 static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req)
 {
+	unsigned long flags;
 	struct fsf_status_read_buffer *sr_buf = req->data;
 	struct zfcp_adapter *adapter = req->adapter;
 	struct zfcp_port *port;
-	int d_id = sr_buf->d_id & ZFCP_DID_MASK;
-	unsigned long flags;
+	int d_id = ntoh24(sr_buf->d_id);
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	list_for_each_entry(port, &adapter->port_list_head, list)
+	read_lock_irqsave(&adapter->port_list_lock, flags);
+	list_for_each_entry(port, &adapter->port_list, list)
 		if (port->d_id == d_id) {
-			read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 			zfcp_erp_port_reopen(port, 0, "fssrpc1", req);
-			return;
+			break;
 		}
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
+	read_unlock_irqrestore(&adapter->port_list_lock, flags);
 }
 
 static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req, char *id,
 					 struct fsf_link_down_info *link_down)
 {
 	struct zfcp_adapter *adapter = req->adapter;
-	unsigned long flags;
 
 	if (atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED)
 		return;
 
 	atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status);
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
 	zfcp_scsi_schedule_rports_block(adapter);
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 
 	if (!link_down)
 		goto out;
@@ -291,7 +289,7 @@
 			zfcp_erp_adapter_access_changed(adapter, "fssrh_3",
 							req);
 		if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_INCOMING_ELS)
-			schedule_work(&adapter->scan_work);
+			queue_work(adapter->work_queue, &adapter->scan_work);
 		break;
 	case FSF_STATUS_READ_CFDC_UPDATED:
 		zfcp_erp_adapter_access_changed(adapter, "fssrh_4", req);
@@ -317,7 +315,6 @@
 	case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
 		return;
 	case FSF_SQ_COMMAND_ABORTED:
-		req->status |= ZFCP_STATUS_FSFREQ_ABORTED;
 		break;
 	case FSF_SQ_NO_RECOM:
 		dev_err(&req->adapter->ccw_device->dev,
@@ -358,8 +355,7 @@
 	zfcp_dbf_hba_fsf_response(req);
 
 	if (req->status & ZFCP_STATUS_FSFREQ_DISMISSED) {
-		req->status |= ZFCP_STATUS_FSFREQ_ERROR |
-			ZFCP_STATUS_FSFREQ_RETRY; /* only for SCSI cmnds. */
+		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		return;
 	}
 
@@ -377,7 +373,7 @@
 	case FSF_PROT_ERROR_STATE:
 	case FSF_PROT_SEQ_NUMB_ERROR:
 		zfcp_erp_adapter_reopen(adapter, 0, "fspse_2", req);
-		req->status |= ZFCP_STATUS_FSFREQ_RETRY;
+		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_PROT_UNSUPP_QTCB_TYPE:
 		dev_err(&adapter->ccw_device->dev,
@@ -480,20 +476,27 @@
 
 static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
 {
-	struct fsf_qtcb_bottom_config *bottom;
+	struct fsf_qtcb_bottom_config *bottom = &req->qtcb->bottom.config;
 	struct zfcp_adapter *adapter = req->adapter;
 	struct Scsi_Host *shost = adapter->scsi_host;
+	struct fc_els_flogi *nsp, *plogi;
 
-	bottom = &req->qtcb->bottom.config;
+	/* adjust pointers for missing command code */
+	nsp = (struct fc_els_flogi *) ((u8 *)&bottom->nport_serv_param
+					- sizeof(u32));
+	plogi = (struct fc_els_flogi *) ((u8 *)&bottom->plogi_payload
+					- sizeof(u32));
 
 	if (req->data)
 		memcpy(req->data, bottom, sizeof(*bottom));
 
-	fc_host_node_name(shost) = bottom->nport_serv_param.wwnn;
-	fc_host_port_name(shost) = bottom->nport_serv_param.wwpn;
-	fc_host_port_id(shost) = bottom->s_id & ZFCP_DID_MASK;
+	fc_host_port_name(shost) = nsp->fl_wwpn;
+	fc_host_node_name(shost) = nsp->fl_wwnn;
+	fc_host_port_id(shost) = ntoh24(bottom->s_id);
 	fc_host_speed(shost) = bottom->fc_link_speed;
 	fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;
+	fc_host_supported_fc4s(shost)[2] = 1; /* FCP */
+	fc_host_active_fc4s(shost)[2] = 1; /* FCP */
 
 	adapter->hydra_version = bottom->adapter_type;
 	adapter->timer_ticks = bottom->timer_interval;
@@ -503,9 +506,9 @@
 
 	switch (bottom->fc_topology) {
 	case FSF_TOPO_P2P:
-		adapter->peer_d_id = bottom->peer_d_id & ZFCP_DID_MASK;
-		adapter->peer_wwpn = bottom->plogi_payload.wwpn;
-		adapter->peer_wwnn = bottom->plogi_payload.wwnn;
+		adapter->peer_d_id = ntoh24(bottom->peer_d_id);
+		adapter->peer_wwpn = plogi->fl_wwpn;
+		adapter->peer_wwnn = plogi->fl_wwnn;
 		fc_host_port_type(shost) = FC_PORTTYPE_PTP;
 		break;
 	case FSF_TOPO_FABRIC:
@@ -881,13 +884,11 @@
 		break;
 	case FSF_PORT_BOXED:
 		zfcp_erp_port_boxed(unit->port, "fsafch3", req);
-		req->status |= ZFCP_STATUS_FSFREQ_ERROR |
-			       ZFCP_STATUS_FSFREQ_RETRY;
+		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_LUN_BOXED:
 		zfcp_erp_unit_boxed(unit, "fsafch4", req);
-		req->status |= ZFCP_STATUS_FSFREQ_ERROR |
-			       ZFCP_STATUS_FSFREQ_RETRY;
+		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                 break;
 	case FSF_ADAPTER_STATUS_AVAILABLE:
 		switch (fsq->word[0]) {
@@ -958,10 +959,10 @@
 static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req)
 {
 	struct zfcp_adapter *adapter = req->adapter;
-	struct zfcp_send_ct *send_ct = req->data;
+	struct zfcp_fsf_ct_els *ct = req->data;
 	struct fsf_qtcb_header *header = &req->qtcb->header;
 
-	send_ct->status = -EINVAL;
+	ct->status = -EINVAL;
 
 	if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
 		goto skip_fsfstatus;
@@ -969,7 +970,7 @@
 	switch (header->fsf_status) {
         case FSF_GOOD:
 		zfcp_dbf_san_ct_response(req);
-		send_ct->status = 0;
+		ct->status = 0;
 		break;
         case FSF_SERVICE_CLASS_NOT_SUPPORTED:
 		zfcp_fsf_class_not_supp(req);
@@ -985,8 +986,7 @@
 	case FSF_ACCESS_DENIED:
 		break;
         case FSF_PORT_BOXED:
-		req->status |= ZFCP_STATUS_FSFREQ_ERROR |
-			       ZFCP_STATUS_FSFREQ_RETRY;
+		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_PORT_HANDLE_NOT_VALID:
 		zfcp_erp_adapter_reopen(adapter, 0, "fsscth1", req);
@@ -1001,8 +1001,8 @@
 	}
 
 skip_fsfstatus:
-	if (send_ct->handler)
-		send_ct->handler(send_ct->handler_data);
+	if (ct->handler)
+		ct->handler(ct->handler_data);
 }
 
 static void zfcp_fsf_setup_ct_els_unchained(struct qdio_buffer_element *sbale,
@@ -1071,15 +1071,17 @@
 				 int max_sbals)
 {
 	int ret;
+	unsigned int fcp_chan_timeout;
 
 	ret = zfcp_fsf_setup_ct_els_sbals(req, sg_req, sg_resp, max_sbals);
 	if (ret)
 		return ret;
 
 	/* common settings for ct/gs and els requests */
+	fcp_chan_timeout = 2 * FC_DEF_R_A_TOV / 1000;
 	req->qtcb->bottom.support.service_class = FSF_CLASS_3;
-	req->qtcb->bottom.support.timeout = 2 * R_A_TOV;
-	zfcp_fsf_start_timer(req, (2 * R_A_TOV + 10) * HZ);
+	req->qtcb->bottom.support.timeout = fcp_chan_timeout;
+	zfcp_fsf_start_timer(req, (fcp_chan_timeout + 10) * HZ);
 
 	return 0;
 }
@@ -1089,9 +1091,9 @@
  * @ct: pointer to struct zfcp_send_ct with data for request
  * @pool: if non-null this mempool is used to allocate struct zfcp_fsf_req
  */
-int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool)
+int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port,
+		     struct zfcp_fsf_ct_els *ct, mempool_t *pool)
 {
-	struct zfcp_wka_port *wka_port = ct->wka_port;
 	struct zfcp_qdio *qdio = wka_port->adapter->qdio;
 	struct zfcp_fsf_req *req;
 	int ret = -EIO;
@@ -1117,7 +1119,7 @@
 	req->qtcb->header.port_handle = wka_port->handle;
 	req->data = ct;
 
-	zfcp_dbf_san_ct_request(req);
+	zfcp_dbf_san_ct_request(req, wka_port->d_id);
 
 	ret = zfcp_fsf_req_send(req);
 	if (ret)
@@ -1134,7 +1136,7 @@
 
 static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req)
 {
-	struct zfcp_send_els *send_els = req->data;
+	struct zfcp_fsf_ct_els *send_els = req->data;
 	struct zfcp_port *port = send_els->port;
 	struct fsf_qtcb_header *header = &req->qtcb->header;
 
@@ -1154,9 +1156,6 @@
 	case FSF_ADAPTER_STATUS_AVAILABLE:
 		switch (header->fsf_status_qual.word[0]){
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
-			if (port && (send_els->ls_code != ZFCP_LS_ADISC))
-				zfcp_fc_test_link(port);
-			/*fall through */
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
 		case FSF_SQ_RETRY_IF_POSSIBLE:
 			req->status |= ZFCP_STATUS_FSFREQ_ERROR;
@@ -1188,10 +1187,11 @@
  * zfcp_fsf_send_els - initiate an ELS command (FC-FS)
  * @els: pointer to struct zfcp_send_els with data for the command
  */
-int zfcp_fsf_send_els(struct zfcp_send_els *els)
+int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id,
+		      struct zfcp_fsf_ct_els *els)
 {
 	struct zfcp_fsf_req *req;
-	struct zfcp_qdio *qdio = els->adapter->qdio;
+	struct zfcp_qdio *qdio = adapter->qdio;
 	int ret = -EIO;
 
 	spin_lock_bh(&qdio->req_q_lock);
@@ -1211,7 +1211,7 @@
 	if (ret)
 		goto failed_send;
 
-	req->qtcb->bottom.support.d_id = els->d_id;
+	hton24(req->qtcb->bottom.support.d_id, d_id);
 	req->handler = zfcp_fsf_send_els_handler;
 	req->data = els;
 
@@ -1422,7 +1422,7 @@
 {
 	struct zfcp_port *port = req->data;
 	struct fsf_qtcb_header *header = &req->qtcb->header;
-	struct fsf_plogi *plogi;
+	struct fc_els_flogi *plogi;
 
 	if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
 		goto out;
@@ -1472,23 +1472,10 @@
 		 * another GID_PN straight after a port has been opened.
 		 * Alternately, an ADISC/PDISC ELS should suffice, as well.
 		 */
-		plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els;
+		plogi = (struct fc_els_flogi *) req->qtcb->bottom.support.els;
 		if (req->qtcb->bottom.support.els1_length >=
-		    FSF_PLOGI_MIN_LEN) {
-			if (plogi->serv_param.wwpn != port->wwpn) {
-				port->d_id = 0;
-				dev_warn(&port->adapter->ccw_device->dev,
-					 "A port opened with WWPN 0x%016Lx "
-					 "returned data that identifies it as "
-					 "WWPN 0x%016Lx\n",
-					 (unsigned long long) port->wwpn,
-					 (unsigned long long)
-					  plogi->serv_param.wwpn);
-			} else {
-				port->wwnn = plogi->serv_param.wwnn;
+		    FSF_PLOGI_MIN_LEN)
 				zfcp_fc_plogi_evaluate(port, plogi);
-			}
-		}
 		break;
 	case FSF_UNKNOWN_OP_SUBTYPE:
 		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
@@ -1496,7 +1483,7 @@
 	}
 
 out:
-	zfcp_port_put(port);
+	put_device(&port->sysfs_device);
 }
 
 /**
@@ -1530,18 +1517,18 @@
         sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
 	req->handler = zfcp_fsf_open_port_handler;
-	req->qtcb->bottom.support.d_id = port->d_id;
+	hton24(req->qtcb->bottom.support.d_id, port->d_id);
 	req->data = port;
 	req->erp_action = erp_action;
 	erp_action->fsf_req = req;
-	zfcp_port_get(port);
+	get_device(&port->sysfs_device);
 
 	zfcp_fsf_start_erp_timer(req);
 	retval = zfcp_fsf_req_send(req);
 	if (retval) {
 		zfcp_fsf_req_free(req);
 		erp_action->fsf_req = NULL;
-		zfcp_port_put(port);
+		put_device(&port->sysfs_device);
 	}
 out:
 	spin_unlock_bh(&qdio->req_q_lock);
@@ -1618,11 +1605,11 @@
 
 static void zfcp_fsf_open_wka_port_handler(struct zfcp_fsf_req *req)
 {
-	struct zfcp_wka_port *wka_port = req->data;
+	struct zfcp_fc_wka_port *wka_port = req->data;
 	struct fsf_qtcb_header *header = &req->qtcb->header;
 
 	if (req->status & ZFCP_STATUS_FSFREQ_ERROR) {
-		wka_port->status = ZFCP_WKA_PORT_OFFLINE;
+		wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE;
 		goto out;
 	}
 
@@ -1635,13 +1622,13 @@
 		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		/* fall through */
 	case FSF_ACCESS_DENIED:
-		wka_port->status = ZFCP_WKA_PORT_OFFLINE;
+		wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE;
 		break;
 	case FSF_GOOD:
 		wka_port->handle = header->port_handle;
 		/* fall through */
 	case FSF_PORT_ALREADY_OPEN:
-		wka_port->status = ZFCP_WKA_PORT_ONLINE;
+		wka_port->status = ZFCP_FC_WKA_PORT_ONLINE;
 	}
 out:
 	wake_up(&wka_port->completion_wq);
@@ -1649,10 +1636,10 @@
 
 /**
  * zfcp_fsf_open_wka_port - create and send open wka-port request
- * @wka_port: pointer to struct zfcp_wka_port
+ * @wka_port: pointer to struct zfcp_fc_wka_port
  * Returns: 0 on success, error otherwise
  */
-int zfcp_fsf_open_wka_port(struct zfcp_wka_port *wka_port)
+int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port)
 {
 	struct qdio_buffer_element *sbale;
 	struct zfcp_qdio *qdio = wka_port->adapter->qdio;
@@ -1677,7 +1664,7 @@
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
 	req->handler = zfcp_fsf_open_wka_port_handler;
-	req->qtcb->bottom.support.d_id = wka_port->d_id;
+	hton24(req->qtcb->bottom.support.d_id, wka_port->d_id);
 	req->data = wka_port;
 
 	zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
@@ -1691,23 +1678,23 @@
 
 static void zfcp_fsf_close_wka_port_handler(struct zfcp_fsf_req *req)
 {
-	struct zfcp_wka_port *wka_port = req->data;
+	struct zfcp_fc_wka_port *wka_port = req->data;
 
 	if (req->qtcb->header.fsf_status == FSF_PORT_HANDLE_NOT_VALID) {
 		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		zfcp_erp_adapter_reopen(wka_port->adapter, 0, "fscwph1", req);
 	}
 
-	wka_port->status = ZFCP_WKA_PORT_OFFLINE;
+	wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE;
 	wake_up(&wka_port->completion_wq);
 }
 
 /**
  * zfcp_fsf_close_wka_port - create and send close wka port request
- * @erp_action: pointer to struct zfcp_erp_action
+ * @wka_port: WKA port to open
  * Returns: 0 on success, error otherwise
  */
-int zfcp_fsf_close_wka_port(struct zfcp_wka_port *wka_port)
+int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port)
 {
 	struct qdio_buffer_element *sbale;
 	struct zfcp_qdio *qdio = wka_port->adapter->qdio;
@@ -1765,13 +1752,13 @@
 		/* can't use generic zfcp_erp_modify_port_status because
 		 * ZFCP_STATUS_COMMON_OPEN must not be reset for the port */
 		atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_OPEN, &port->status);
-		list_for_each_entry(unit, &port->unit_list_head, list)
+		read_lock(&port->unit_list_lock);
+		list_for_each_entry(unit, &port->unit_list, list)
 			atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN,
 					  &unit->status);
+		read_unlock(&port->unit_list_lock);
 		zfcp_erp_port_boxed(port, "fscpph2", req);
-		req->status |= ZFCP_STATUS_FSFREQ_ERROR |
-			       ZFCP_STATUS_FSFREQ_RETRY;
-
+		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_ADAPTER_STATUS_AVAILABLE:
 		switch (header->fsf_status_qual.word[0]) {
@@ -1787,9 +1774,11 @@
 		 * ZFCP_STATUS_COMMON_OPEN must not be reset for the port
 		 */
 		atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_OPEN, &port->status);
-		list_for_each_entry(unit, &port->unit_list_head, list)
+		read_lock(&port->unit_list_lock);
+		list_for_each_entry(unit, &port->unit_list, list)
 			atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN,
 					  &unit->status);
+		read_unlock(&port->unit_list_lock);
 		break;
 	}
 }
@@ -1873,8 +1862,7 @@
 		break;
 	case FSF_PORT_BOXED:
 		zfcp_erp_port_boxed(unit->port, "fsouh_2", req);
-		req->status |= ZFCP_STATUS_FSFREQ_ERROR |
-			       ZFCP_STATUS_FSFREQ_RETRY;
+		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_LUN_SHARING_VIOLATION:
 		if (header->fsf_status_qual.word[0])
@@ -2036,8 +2024,7 @@
 		break;
 	case FSF_PORT_BOXED:
 		zfcp_erp_port_boxed(unit->port, "fscuh_3", req);
-		req->status |= ZFCP_STATUS_FSFREQ_ERROR |
-			       ZFCP_STATUS_FSFREQ_RETRY;
+		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_ADAPTER_STATUS_AVAILABLE:
 		switch (req->qtcb->header.fsf_status_qual.word[0]) {
@@ -2109,72 +2096,57 @@
 	lat_rec->max = max(lat_rec->max, lat);
 }
 
-static void zfcp_fsf_req_latency(struct zfcp_fsf_req *req)
+static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi)
 {
-	struct fsf_qual_latency_info *lat_inf;
-	struct latency_cont *lat;
+	struct fsf_qual_latency_info *lat_in;
+	struct latency_cont *lat = NULL;
 	struct zfcp_unit *unit = req->unit;
+	struct zfcp_blk_drv_data blktrc;
+	int ticks = req->adapter->timer_ticks;
 
-	lat_inf = &req->qtcb->prefix.prot_status_qual.latency_info;
+	lat_in = &req->qtcb->prefix.prot_status_qual.latency_info;
 
-	switch (req->qtcb->bottom.io.data_direction) {
-	case FSF_DATADIR_READ:
-		lat = &unit->latencies.read;
-		break;
-	case FSF_DATADIR_WRITE:
-		lat = &unit->latencies.write;
-		break;
-	case FSF_DATADIR_CMND:
-		lat = &unit->latencies.cmd;
-		break;
-	default:
-		return;
+	blktrc.flags = 0;
+	blktrc.magic = ZFCP_BLK_DRV_DATA_MAGIC;
+	if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
+		blktrc.flags |= ZFCP_BLK_REQ_ERROR;
+	blktrc.inb_usage = req->queue_req.qdio_inb_usage;
+	blktrc.outb_usage = req->queue_req.qdio_outb_usage;
+
+	if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) {
+		blktrc.flags |= ZFCP_BLK_LAT_VALID;
+		blktrc.channel_lat = lat_in->channel_lat * ticks;
+		blktrc.fabric_lat = lat_in->fabric_lat * ticks;
+
+		switch (req->qtcb->bottom.io.data_direction) {
+		case FSF_DATADIR_READ:
+			lat = &unit->latencies.read;
+			break;
+		case FSF_DATADIR_WRITE:
+			lat = &unit->latencies.write;
+			break;
+		case FSF_DATADIR_CMND:
+			lat = &unit->latencies.cmd;
+			break;
+		}
+
+		if (lat) {
+			spin_lock(&unit->latencies.lock);
+			zfcp_fsf_update_lat(&lat->channel, lat_in->channel_lat);
+			zfcp_fsf_update_lat(&lat->fabric, lat_in->fabric_lat);
+			lat->counter++;
+			spin_unlock(&unit->latencies.lock);
+		}
 	}
 
-	spin_lock(&unit->latencies.lock);
-	zfcp_fsf_update_lat(&lat->channel, lat_inf->channel_lat);
-	zfcp_fsf_update_lat(&lat->fabric, lat_inf->fabric_lat);
-	lat->counter++;
-	spin_unlock(&unit->latencies.lock);
+	blk_add_driver_data(scsi->request->q, scsi->request, &blktrc,
+			    sizeof(blktrc));
 }
 
-#ifdef CONFIG_BLK_DEV_IO_TRACE
-static void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req)
-{
-	struct fsf_qual_latency_info *lat_inf;
-	struct scsi_cmnd *scsi_cmnd = (struct scsi_cmnd *)fsf_req->data;
-	struct request *req = scsi_cmnd->request;
-	struct zfcp_blk_drv_data trace;
-	int ticks = fsf_req->adapter->timer_ticks;
-
-	trace.flags = 0;
-	trace.magic = ZFCP_BLK_DRV_DATA_MAGIC;
-	if (fsf_req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) {
-		trace.flags |= ZFCP_BLK_LAT_VALID;
-		lat_inf = &fsf_req->qtcb->prefix.prot_status_qual.latency_info;
-		trace.channel_lat = lat_inf->channel_lat * ticks;
-		trace.fabric_lat = lat_inf->fabric_lat * ticks;
-	}
-	if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)
-		trace.flags |= ZFCP_BLK_REQ_ERROR;
-	trace.inb_usage = fsf_req->queue_req.qdio_inb_usage;
-	trace.outb_usage = fsf_req->queue_req.qdio_outb_usage;
-
-	blk_add_driver_data(req->q, req, &trace, sizeof(trace));
-}
-#else
-static inline void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req)
-{
-}
-#endif
-
 static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req)
 {
 	struct scsi_cmnd *scpnt;
-	struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *)
-	    &(req->qtcb->bottom.io.fcp_rsp);
-	u32 sns_len;
-	char *fcp_rsp_info = (unsigned char *) &fcp_rsp_iu[1];
+	struct fcp_resp_with_ext *fcp_rsp;
 	unsigned long flags;
 
 	read_lock_irqsave(&req->adapter->abort_lock, flags);
@@ -2185,50 +2157,16 @@
 		return;
 	}
 
-	if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ABORTED)) {
-		set_host_byte(scpnt, DID_SOFT_ERROR);
-		goto skip_fsfstatus;
-	}
-
 	if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
-		set_host_byte(scpnt, DID_ERROR);
+		set_host_byte(scpnt, DID_TRANSPORT_DISRUPTED);
 		goto skip_fsfstatus;
 	}
 
-	set_msg_byte(scpnt, COMMAND_COMPLETE);
+	fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp;
+	zfcp_fc_eval_fcp_rsp(fcp_rsp, scpnt);
 
-	scpnt->result |= fcp_rsp_iu->scsi_status;
+	zfcp_fsf_req_trace(req, scpnt);
 
-	if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA)
-		zfcp_fsf_req_latency(req);
-
-	zfcp_fsf_trace_latency(req);
-
-	if (unlikely(fcp_rsp_iu->validity.bits.fcp_rsp_len_valid)) {
-		if (fcp_rsp_info[3] == RSP_CODE_GOOD)
-			set_host_byte(scpnt, DID_OK);
-		else {
-			set_host_byte(scpnt, DID_ERROR);
-			goto skip_fsfstatus;
-		}
-	}
-
-	if (unlikely(fcp_rsp_iu->validity.bits.fcp_sns_len_valid)) {
-		sns_len = FSF_FCP_RSP_SIZE - sizeof(struct fcp_rsp_iu) +
-			  fcp_rsp_iu->fcp_rsp_len;
-		sns_len = min(sns_len, (u32) SCSI_SENSE_BUFFERSIZE);
-		sns_len = min(sns_len, fcp_rsp_iu->fcp_sns_len);
-
-		memcpy(scpnt->sense_buffer,
-		       zfcp_get_fcp_sns_info_ptr(fcp_rsp_iu), sns_len);
-	}
-
-	if (unlikely(fcp_rsp_iu->validity.bits.fcp_resid_under)) {
-		scsi_set_resid(scpnt, fcp_rsp_iu->fcp_resid);
-		if (scsi_bufflen(scpnt) - scsi_get_resid(scpnt) <
-		    scpnt->underflow)
-			set_host_byte(scpnt, DID_ERROR);
-	}
 skip_fsfstatus:
 	if (scpnt->result != 0)
 		zfcp_dbf_scsi_result("erro", 3, req->adapter->dbf, scpnt, req);
@@ -2250,11 +2188,13 @@
 
 static void zfcp_fsf_send_fcp_ctm_handler(struct zfcp_fsf_req *req)
 {
-	struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *)
-	    &(req->qtcb->bottom.io.fcp_rsp);
-	char *fcp_rsp_info = (unsigned char *) &fcp_rsp_iu[1];
+	struct fcp_resp_with_ext *fcp_rsp;
+	struct fcp_resp_rsp_info *rsp_info;
 
-	if ((fcp_rsp_info[3] != RSP_CODE_GOOD) ||
+	fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp;
+	rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1];
+
+	if ((rsp_info->rsp_code != FCP_TMF_CMPL) ||
 	     (req->status & ZFCP_STATUS_FSFREQ_ERROR))
 		req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED;
 }
@@ -2314,13 +2254,11 @@
 		break;
 	case FSF_PORT_BOXED:
 		zfcp_erp_port_boxed(unit->port, "fssfch5", req);
-		req->status |= ZFCP_STATUS_FSFREQ_ERROR |
-			       ZFCP_STATUS_FSFREQ_RETRY;
+		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_LUN_BOXED:
 		zfcp_erp_unit_boxed(unit, "fssfch6", req);
-		req->status |= ZFCP_STATUS_FSFREQ_ERROR |
-			       ZFCP_STATUS_FSFREQ_RETRY;
+		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_ADAPTER_STATUS_AVAILABLE:
 		if (header->fsf_status_qual.word[0] ==
@@ -2335,24 +2273,10 @@
 	else {
 		zfcp_fsf_send_fcp_command_task_handler(req);
 		req->unit = NULL;
-		zfcp_unit_put(unit);
+		put_device(&unit->sysfs_device);
 	}
 }
 
-static void zfcp_set_fcp_dl(struct fcp_cmnd_iu *fcp_cmd, u32 fcp_dl)
-{
-	u32 *fcp_dl_ptr;
-
-	/*
-	 * fcp_dl_addr = start address of fcp_cmnd structure +
-	 * size of fixed part + size of dynamically sized add_dcp_cdb field
-	 * SEE FCP-2 documentation
-	 */
-	fcp_dl_ptr = (u32 *) ((unsigned char *) &fcp_cmd[1] +
-			(fcp_cmd->add_fcp_cdb_length << 2));
-	*fcp_dl_ptr = fcp_dl;
-}
-
 /**
  * zfcp_fsf_send_fcp_command_task - initiate an FCP command (for a SCSI command)
  * @unit: unit where command is sent to
@@ -2362,7 +2286,7 @@
 				   struct scsi_cmnd *scsi_cmnd)
 {
 	struct zfcp_fsf_req *req;
-	struct fcp_cmnd_iu *fcp_cmnd_iu;
+	struct fcp_cmnd *fcp_cmnd;
 	unsigned int sbtype = SBAL_FLAGS0_TYPE_READ;
 	int real_bytes, retval = -EIO;
 	struct zfcp_adapter *adapter = unit->port->adapter;
@@ -2387,23 +2311,21 @@
 	}
 
 	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
-	zfcp_unit_get(unit);
+	get_device(&unit->sysfs_device);
 	req->unit = unit;
 	req->data = scsi_cmnd;
 	req->handler = zfcp_fsf_send_fcp_command_handler;
 	req->qtcb->header.lun_handle = unit->handle;
 	req->qtcb->header.port_handle = unit->port->handle;
 	req->qtcb->bottom.io.service_class = FSF_CLASS_3;
+	req->qtcb->bottom.io.fcp_cmnd_length = FCP_CMND_LEN;
 
 	scsi_cmnd->host_scribble = (unsigned char *) req->req_id;
 
-	fcp_cmnd_iu = (struct fcp_cmnd_iu *) &(req->qtcb->bottom.io.fcp_cmnd);
-	fcp_cmnd_iu->fcp_lun = unit->fcp_lun;
 	/*
 	 * set depending on data direction:
 	 *      data direction bits in SBALE (SB Type)
 	 *      data direction bits in QTCB
-	 *      data direction bits in FCP_CMND IU
 	 */
 	switch (scsi_cmnd->sc_data_direction) {
 	case DMA_NONE:
@@ -2411,32 +2333,17 @@
 		break;
 	case DMA_FROM_DEVICE:
 		req->qtcb->bottom.io.data_direction = FSF_DATADIR_READ;
-		fcp_cmnd_iu->rddata = 1;
 		break;
 	case DMA_TO_DEVICE:
 		req->qtcb->bottom.io.data_direction = FSF_DATADIR_WRITE;
 		sbtype = SBAL_FLAGS0_TYPE_WRITE;
-		fcp_cmnd_iu->wddata = 1;
 		break;
 	case DMA_BIDIRECTIONAL:
 		goto failed_scsi_cmnd;
 	}
 
-	if (likely((scsi_cmnd->device->simple_tags) ||
-		   ((atomic_read(&unit->status) & ZFCP_STATUS_UNIT_READONLY) &&
-		    (atomic_read(&unit->status) & ZFCP_STATUS_UNIT_SHARED))))
-		fcp_cmnd_iu->task_attribute = SIMPLE_Q;
-	else
-		fcp_cmnd_iu->task_attribute = UNTAGGED;
-
-	if (unlikely(scsi_cmnd->cmd_len > FCP_CDB_LENGTH))
-		fcp_cmnd_iu->add_fcp_cdb_length =
-			(scsi_cmnd->cmd_len - FCP_CDB_LENGTH) >> 2;
-
-	memcpy(fcp_cmnd_iu->fcp_cdb, scsi_cmnd->cmnd, scsi_cmnd->cmd_len);
-
-	req->qtcb->bottom.io.fcp_cmnd_length = sizeof(struct fcp_cmnd_iu) +
-		fcp_cmnd_iu->add_fcp_cdb_length + sizeof(u32);
+	fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd;
+	zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd);
 
 	real_bytes = zfcp_qdio_sbals_from_sg(qdio, &req->queue_req, sbtype,
 					     scsi_sglist(scsi_cmnd),
@@ -2454,8 +2361,6 @@
 		goto failed_scsi_cmnd;
 	}
 
-	zfcp_set_fcp_dl(fcp_cmnd_iu, real_bytes);
-
 	retval = zfcp_fsf_req_send(req);
 	if (unlikely(retval))
 		goto failed_scsi_cmnd;
@@ -2463,7 +2368,7 @@
 	goto out;
 
 failed_scsi_cmnd:
-	zfcp_unit_put(unit);
+	put_device(&unit->sysfs_device);
 	zfcp_fsf_req_free(req);
 	scsi_cmnd->host_scribble = NULL;
 out:
@@ -2481,7 +2386,7 @@
 {
 	struct qdio_buffer_element *sbale;
 	struct zfcp_fsf_req *req = NULL;
-	struct fcp_cmnd_iu *fcp_cmnd_iu;
+	struct fcp_cmnd *fcp_cmnd;
 	struct zfcp_qdio *qdio = unit->port->adapter->qdio;
 
 	if (unlikely(!(atomic_read(&unit->status) &
@@ -2507,16 +2412,14 @@
 	req->qtcb->header.port_handle = unit->port->handle;
 	req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND;
 	req->qtcb->bottom.io.service_class = FSF_CLASS_3;
-	req->qtcb->bottom.io.fcp_cmnd_length = 	sizeof(struct fcp_cmnd_iu) +
-						sizeof(u32);
+	req->qtcb->bottom.io.fcp_cmnd_length = FCP_CMND_LEN;
 
 	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
-	fcp_cmnd_iu = (struct fcp_cmnd_iu *) &req->qtcb->bottom.io.fcp_cmnd;
-	fcp_cmnd_iu->fcp_lun = unit->fcp_lun;
-	fcp_cmnd_iu->task_management_flags = tm_flags;
+	fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd;
+	zfcp_fc_fcp_tm(fcp_cmnd, unit->device, tm_flags);
 
 	zfcp_fsf_start_timer(req, ZFCP_SCSI_ER_TIMEOUT);
 	if (!zfcp_fsf_req_send(req))
diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h
index dcc7c1d..b3de682 100644
--- a/drivers/s390/scsi/zfcp_fsf.h
+++ b/drivers/s390/scsi/zfcp_fsf.h
@@ -11,6 +11,7 @@
 
 #include <linux/pfn.h>
 #include <linux/scatterlist.h>
+#include <scsi/libfc.h>
 
 #define FSF_QTCB_CURRENT_VERSION		0x00000001
 
@@ -228,7 +229,8 @@
 	u32 length;
 	u32 res1;
 	struct fsf_queue_designator queue_designator;
-	u32 d_id;
+	u8 res2;
+	u8 d_id[3];
 	u32 class;
 	u64 fcp_lun;
 	u8  res3[24];
@@ -309,22 +311,7 @@
 	u8  res4[16];
 } __attribute__ ((packed));
 
-struct fsf_nport_serv_param {
-	u8  common_serv_param[16];
-	u64 wwpn;
-	u64 wwnn;
-	u8  class1_serv_param[16];
-	u8  class2_serv_param[16];
-	u8  class3_serv_param[16];
-	u8  class4_serv_param[16];
-	u8  vendor_version_level[16];
-} __attribute__ ((packed));
-
 #define FSF_PLOGI_MIN_LEN	112
-struct fsf_plogi {
-	u32    code;
-	struct fsf_nport_serv_param serv_param;
-} __attribute__ ((packed));
 
 #define FSF_FCP_CMND_SIZE	288
 #define FSF_FCP_RSP_SIZE	128
@@ -342,8 +329,8 @@
 
 struct fsf_qtcb_bottom_support {
 	u32 operation_subtype;
-	u8  res1[12];
-	u32 d_id;
+	u8  res1[13];
+	u8 d_id[3];
 	u32 option;
 	u64 fcp_lun;
 	u64 res2;
@@ -372,18 +359,18 @@
 	u32 fc_topology;
 	u32 fc_link_speed;
 	u32 adapter_type;
-	u32 peer_d_id;
+	u8 res0;
+	u8 peer_d_id[3];
 	u8 res1[2];
 	u16 timer_interval;
-	u8 res2[8];
-	u32 s_id;
-	struct fsf_nport_serv_param nport_serv_param;
-	u8 reserved_nport_serv_param[16];
+	u8 res2[9];
+	u8 s_id[3];
+	u8 nport_serv_param[128];
 	u8 res3[8];
 	u32 adapter_ports;
 	u32 hardware_version;
 	u8 serial_number[32];
-	struct fsf_nport_serv_param plogi_payload;
+	u8 plogi_payload[112];
 	struct fsf_statistics_info stat_info;
 	u8 res4[112];
 } __attribute__ ((packed));
@@ -450,4 +437,22 @@
 	u64 fabric_lat;
 } __attribute__ ((packed));
 
+/**
+ * struct zfcp_fsf_ct_els - zfcp data for ct or els request
+ * @req: scatter-gather list for request
+ * @resp: scatter-gather list for response
+ * @handler: handler function (called for response to the request)
+ * @handler_data: data passed to handler function
+ * @port: Optional pointer to port for zfcp internal ELS (only test link ADISC)
+ * @status: used to pass error status to calling function
+ */
+struct zfcp_fsf_ct_els {
+	struct scatterlist *req;
+	struct scatterlist *resp;
+	void (*handler)(void *);
+	void *handler_data;
+	struct zfcp_port *port;
+	int status;
+};
+
 #endif				/* FSF_H */
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 0e1a346..771cc53 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -9,29 +9,33 @@
 #define KMSG_COMPONENT "zfcp"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
+#include <linux/types.h>
+#include <scsi/fc/fc_fcp.h>
 #include <asm/atomic.h>
 #include "zfcp_ext.h"
 #include "zfcp_dbf.h"
+#include "zfcp_fc.h"
 
 static unsigned int default_depth = 32;
 module_param_named(queue_depth, default_depth, uint, 0600);
 MODULE_PARM_DESC(queue_depth, "Default queue depth for new SCSI devices");
 
-/* Find start of Sense Information in FCP response unit*/
-char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *fcp_rsp_iu)
+static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth,
+					int reason)
 {
-	char *fcp_sns_info_ptr;
-
-	fcp_sns_info_ptr = (unsigned char *) &fcp_rsp_iu[1];
-	if (fcp_rsp_iu->validity.bits.fcp_rsp_len_valid)
-		fcp_sns_info_ptr += fcp_rsp_iu->fcp_rsp_len;
-
-	return fcp_sns_info_ptr;
-}
-
-static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth)
-{
-	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
+	switch (reason) {
+	case SCSI_QDEPTH_DEFAULT:
+		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
+		break;
+	case SCSI_QDEPTH_QFULL:
+		scsi_track_queue_full(sdev, depth);
+		break;
+	case SCSI_QDEPTH_RAMP_UP:
+		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
 	return sdev->queue_depth;
 }
 
@@ -39,7 +43,7 @@
 {
 	struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata;
 	unit->device = NULL;
-	zfcp_unit_put(unit);
+	put_device(&unit->sysfs_device);
 }
 
 static int zfcp_scsi_slave_configure(struct scsi_device *sdp)
@@ -99,12 +103,26 @@
 	}
 
 	status = atomic_read(&unit->status);
-	if (unlikely((status & ZFCP_STATUS_COMMON_ERP_FAILED) ||
-		     !(status & ZFCP_STATUS_COMMON_RUNNING))) {
+	if (unlikely(status & ZFCP_STATUS_COMMON_ERP_FAILED) &&
+		     !(atomic_read(&unit->port->status) &
+		       ZFCP_STATUS_COMMON_ERP_FAILED)) {
+		/* only unit access denied, but port is good
+		 * not covered by FC transport, have to fail here */
 		zfcp_scsi_command_fail(scpnt, DID_ERROR);
 		return 0;
 	}
 
+	if (unlikely(!(status & ZFCP_STATUS_COMMON_UNBLOCKED))) {
+		/* This could be either
+		 * open unit pending: this is temporary, will result in
+		 * 	open unit or ERP_FAILED, so retry command
+		 * call to rport_delete pending: mimic retry from
+		 * 	fc_remote_port_chkready until rport is BLOCKED
+		 */
+		zfcp_scsi_command_fail(scpnt, DID_IMM_RETRY);
+		return 0;
+	}
+
 	ret = zfcp_fsf_send_fcp_command_task(unit, scpnt);
 	if (unlikely(ret == -EBUSY))
 		return SCSI_MLQUEUE_DEVICE_BUSY;
@@ -115,49 +133,44 @@
 }
 
 static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *adapter,
-					  int channel, unsigned int id,
-					  unsigned int lun)
+					  unsigned int id, u64 lun)
 {
+	unsigned long flags;
 	struct zfcp_port *port;
-	struct zfcp_unit *unit;
-	int scsi_lun;
+	struct zfcp_unit *unit = NULL;
 
-	list_for_each_entry(port, &adapter->port_list_head, list) {
+	read_lock_irqsave(&adapter->port_list_lock, flags);
+	list_for_each_entry(port, &adapter->port_list, list) {
 		if (!port->rport || (id != port->rport->scsi_target_id))
 			continue;
-		list_for_each_entry(unit, &port->unit_list_head, list) {
-			scsi_lun = scsilun_to_int(
-				(struct scsi_lun *)&unit->fcp_lun);
-			if (lun == scsi_lun)
-				return unit;
-		}
+		unit = zfcp_get_unit_by_lun(port, lun);
+		if (unit)
+			break;
 	}
+	read_unlock_irqrestore(&adapter->port_list_lock, flags);
 
-	return NULL;
+	return unit;
 }
 
 static int zfcp_scsi_slave_alloc(struct scsi_device *sdp)
 {
 	struct zfcp_adapter *adapter;
 	struct zfcp_unit *unit;
-	unsigned long flags;
-	int retval = -ENXIO;
+	u64 lun;
 
 	adapter = (struct zfcp_adapter *) sdp->host->hostdata[0];
 	if (!adapter)
 		goto out;
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	unit = zfcp_unit_lookup(adapter, sdp->channel, sdp->id, sdp->lun);
+	int_to_scsilun(sdp->lun, (struct scsi_lun *)&lun);
+	unit = zfcp_unit_lookup(adapter, sdp->id, lun);
 	if (unit) {
 		sdp->hostdata = unit;
 		unit->device = sdp;
-		zfcp_unit_get(unit);
-		retval = 0;
+		return 0;
 	}
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 out:
-	return retval;
+	return -ENXIO;
 }
 
 static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
@@ -196,6 +209,7 @@
 			break;
 
 		zfcp_erp_wait(adapter);
+		fc_block_scsi_eh(scpnt);
 		if (!(atomic_read(&adapter->status) &
 		      ZFCP_STATUS_COMMON_RUNNING)) {
 			zfcp_dbf_scsi_abort("nres", adapter->dbf, scpnt, NULL,
@@ -235,6 +249,7 @@
 			break;
 
 		zfcp_erp_wait(adapter);
+		fc_block_scsi_eh(scpnt);
 		if (!(atomic_read(&adapter->status) &
 		      ZFCP_STATUS_COMMON_RUNNING)) {
 			zfcp_dbf_scsi_devreset("nres", tm_flags, unit, scpnt);
@@ -249,9 +264,6 @@
 	if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) {
 		zfcp_dbf_scsi_devreset("fail", tm_flags, unit, scpnt);
 		retval = FAILED;
-	} else if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP) {
-		zfcp_dbf_scsi_devreset("nsup", tm_flags, unit, scpnt);
-		retval = FAILED;
 	} else
 		zfcp_dbf_scsi_devreset("okay", tm_flags, unit, scpnt);
 
@@ -261,12 +273,12 @@
 
 static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
 {
-	return zfcp_task_mgmt_function(scpnt, FCP_LOGICAL_UNIT_RESET);
+	return zfcp_task_mgmt_function(scpnt, FCP_TMF_LUN_RESET);
 }
 
 static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
 {
-	return zfcp_task_mgmt_function(scpnt, FCP_TARGET_RESET);
+	return zfcp_task_mgmt_function(scpnt, FCP_TMF_TGT_RESET);
 }
 
 static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
@@ -276,6 +288,7 @@
 
 	zfcp_erp_adapter_reopen(adapter, 0, "schrh_1", scpnt);
 	zfcp_erp_wait(adapter);
+	fc_block_scsi_eh(scpnt);
 
 	return SUCCESS;
 }
@@ -303,7 +316,7 @@
 	adapter->scsi_host->max_lun = 1;
 	adapter->scsi_host->max_channel = 0;
 	adapter->scsi_host->unique_id = dev_id.devno;
-	adapter->scsi_host->max_cmd_len = 255;
+	adapter->scsi_host->max_cmd_len = 16; /* in struct fcp_cmnd */
 	adapter->scsi_host->transportt = zfcp_data.scsi_transport_template;
 
 	adapter->scsi_host->hostdata[0] = (unsigned long) adapter;
@@ -325,12 +338,11 @@
 	if (!shost)
 		return;
 
-	read_lock_irq(&zfcp_data.config_lock);
-	list_for_each_entry(port, &adapter->port_list_head, list)
-		if (port->rport)
-			port->rport = NULL;
+	read_lock_irq(&adapter->port_list_lock);
+	list_for_each_entry(port, &adapter->port_list, list)
+		port->rport = NULL;
+	read_unlock_irq(&adapter->port_list_lock);
 
-	read_unlock_irq(&zfcp_data.config_lock);
 	fc_remove_host(shost);
 	scsi_remove_host(shost);
 	scsi_host_put(shost);
@@ -348,7 +360,7 @@
 		fc_stats = kmalloc(sizeof(*fc_stats), GFP_KERNEL);
 		if (!fc_stats)
 			return NULL;
-		adapter->fc_stats = fc_stats; /* freed in adater_dequeue */
+		adapter->fc_stats = fc_stats; /* freed in adapter_release */
 	}
 	memset(adapter->fc_stats, 0, sizeof(*adapter->fc_stats));
 	return adapter->fc_stats;
@@ -464,7 +476,7 @@
 		adapter->stats_reset = jiffies/HZ;
 		kfree(adapter->stats_reset_data);
 		adapter->stats_reset_data = data; /* finally freed in
-						     adapter_dequeue */
+						     adapter_release */
 	}
 }
 
@@ -495,7 +507,7 @@
  * @rport: The FC rport where to teminate I/O
  *
  * Abort all pending SCSI commands for a port by closing the
- * port. Using a reopen for avoids a conflict with a shutdown
+ * port. Using a reopen avoiding a conflict with a shutdown
  * overwriting a reopen.
  */
 static void zfcp_scsi_terminate_rport_io(struct fc_rport *rport)
@@ -505,15 +517,11 @@
 	struct zfcp_adapter *adapter =
 		(struct zfcp_adapter *)shost->hostdata[0];
 
-	write_lock_irq(&zfcp_data.config_lock);
 	port = zfcp_get_port_by_wwpn(adapter, rport->port_name);
-	if (port)
-		zfcp_port_get(port);
-	write_unlock_irq(&zfcp_data.config_lock);
 
 	if (port) {
 		zfcp_erp_port_reopen(port, 0, "sctrpi1", NULL);
-		zfcp_port_put(port);
+		put_device(&port->sysfs_device);
 	}
 }
 
@@ -555,31 +563,34 @@
 
 void zfcp_scsi_schedule_rport_register(struct zfcp_port *port)
 {
-	zfcp_port_get(port);
+	get_device(&port->sysfs_device);
 	port->rport_task = RPORT_ADD;
 
 	if (!queue_work(port->adapter->work_queue, &port->rport_work))
-		zfcp_port_put(port);
+		put_device(&port->sysfs_device);
 }
 
 void zfcp_scsi_schedule_rport_block(struct zfcp_port *port)
 {
-	zfcp_port_get(port);
+	get_device(&port->sysfs_device);
 	port->rport_task = RPORT_DEL;
 
 	if (port->rport && queue_work(port->adapter->work_queue,
 				      &port->rport_work))
 		return;
 
-	zfcp_port_put(port);
+	put_device(&port->sysfs_device);
 }
 
 void zfcp_scsi_schedule_rports_block(struct zfcp_adapter *adapter)
 {
+	unsigned long flags;
 	struct zfcp_port *port;
 
-	list_for_each_entry(port, &adapter->port_list_head, list)
+	read_lock_irqsave(&adapter->port_list_lock, flags);
+	list_for_each_entry(port, &adapter->port_list, list)
 		zfcp_scsi_schedule_rport_block(port);
+	read_unlock_irqrestore(&adapter->port_list_lock, flags);
 }
 
 void zfcp_scsi_rport_work(struct work_struct *work)
@@ -597,7 +608,7 @@
 		}
 	}
 
-	zfcp_port_put(port);
+	put_device(&port->sysfs_device);
 }
 
 
@@ -615,21 +626,7 @@
 				 scsilun_to_int((struct scsi_lun *)
 						&unit->fcp_lun), 0);
 
-	zfcp_unit_put(unit);
-}
-
-static int zfcp_execute_fc_job(struct fc_bsg_job *job)
-{
-	switch (job->request->msgcode) {
-	case FC_BSG_RPT_ELS:
-	case FC_BSG_HST_ELS_NOLOGIN:
-		return zfcp_fc_execute_els_fc_job(job);
-	case FC_BSG_RPT_CT:
-	case FC_BSG_HST_CT:
-		return zfcp_fc_execute_ct_fc_job(job);
-	default:
-		return -EINVAL;
-	}
+	put_device(&unit->sysfs_device);
 }
 
 struct fc_function_template zfcp_transport_functions = {
@@ -643,6 +640,7 @@
 	.show_host_port_name = 1,
 	.show_host_permanent_port_name = 1,
 	.show_host_supported_classes = 1,
+	.show_host_supported_fc4s = 1,
 	.show_host_supported_speeds = 1,
 	.show_host_maxframe_size = 1,
 	.show_host_serial_number = 1,
@@ -652,13 +650,15 @@
 	.get_host_port_state = zfcp_get_host_port_state,
 	.terminate_rport_io = zfcp_scsi_terminate_rport_io,
 	.show_host_port_state = 1,
-	.bsg_request = zfcp_execute_fc_job,
+	.show_host_active_fc4s = 1,
+	.bsg_request = zfcp_fc_exec_bsg_job,
 	/* no functions registered for following dynamic attributes but
 	   directly set by LLDD */
 	.show_host_port_type = 1,
 	.show_host_speed = 1,
 	.show_host_port_id = 1,
 	.disable_target_scan = 1,
+	.dd_bsg_size = sizeof(struct zfcp_fsf_ct_els),
 };
 
 struct zfcp_data zfcp_data = {
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c
index d310008..f539e00 100644
--- a/drivers/s390/scsi/zfcp_sysfs.c
+++ b/drivers/s390/scsi/zfcp_sysfs.c
@@ -3,7 +3,7 @@
  *
  * sysfs attributes.
  *
- * Copyright IBM Corporation 2008
+ * Copyright IBM Corporation 2008, 2009
  */
 
 #define KMSG_COMPONENT "zfcp"
@@ -19,30 +19,44 @@
 						   struct device_attribute *at,\
 						   char *buf)		       \
 {									       \
-	struct _feat_def *_feat = dev_get_drvdata(dev);			       \
+	struct _feat_def *_feat = container_of(dev, struct _feat_def,	       \
+					       sysfs_device);		       \
 									       \
 	return sprintf(buf, _format, _value);				       \
 }									       \
 static ZFCP_DEV_ATTR(_feat, _name, S_IRUGO,				       \
 		     zfcp_sysfs_##_feat##_##_name##_show, NULL);
 
-ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, status, "0x%08x\n",
-		 atomic_read(&adapter->status));
-ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, peer_wwnn, "0x%016llx\n",
-		 (unsigned long long) adapter->peer_wwnn);
-ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, peer_wwpn, "0x%016llx\n",
-		 (unsigned long long) adapter->peer_wwpn);
-ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, peer_d_id, "0x%06x\n",
-		 adapter->peer_d_id);
-ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, card_version, "0x%04x\n",
-		 adapter->hydra_version);
-ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, lic_version, "0x%08x\n",
-		 adapter->fsf_lic_version);
-ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, hardware_version, "0x%08x\n",
-		 adapter->hardware_version);
-ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, in_recovery, "%d\n",
-		 (atomic_read(&adapter->status) &
-		  ZFCP_STATUS_COMMON_ERP_INUSE) != 0);
+#define ZFCP_DEFINE_A_ATTR(_name, _format, _value)			     \
+static ssize_t zfcp_sysfs_adapter_##_name##_show(struct device *dev,	     \
+						 struct device_attribute *at,\
+						 char *buf)		     \
+{									     \
+	struct ccw_device *cdev = to_ccwdev(dev);			     \
+	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);	     \
+	int i;								     \
+									     \
+	if (!adapter)							     \
+		return -ENODEV;						     \
+									     \
+	i = sprintf(buf, _format, _value);				     \
+	zfcp_ccw_adapter_put(adapter);					     \
+	return i;							     \
+}									     \
+static ZFCP_DEV_ATTR(adapter, _name, S_IRUGO,				     \
+		     zfcp_sysfs_adapter_##_name##_show, NULL);
+
+ZFCP_DEFINE_A_ATTR(status, "0x%08x\n", atomic_read(&adapter->status));
+ZFCP_DEFINE_A_ATTR(peer_wwnn, "0x%016llx\n",
+		   (unsigned long long) adapter->peer_wwnn);
+ZFCP_DEFINE_A_ATTR(peer_wwpn, "0x%016llx\n",
+		   (unsigned long long) adapter->peer_wwpn);
+ZFCP_DEFINE_A_ATTR(peer_d_id, "0x%06x\n", adapter->peer_d_id);
+ZFCP_DEFINE_A_ATTR(card_version, "0x%04x\n", adapter->hydra_version);
+ZFCP_DEFINE_A_ATTR(lic_version, "0x%08x\n", adapter->fsf_lic_version);
+ZFCP_DEFINE_A_ATTR(hardware_version, "0x%08x\n", adapter->hardware_version);
+ZFCP_DEFINE_A_ATTR(in_recovery, "%d\n", (atomic_read(&adapter->status) &
+					 ZFCP_STATUS_COMMON_ERP_INUSE) != 0);
 
 ZFCP_DEFINE_ATTR(zfcp_port, port, status, "0x%08x\n",
 		 atomic_read(&port->status));
@@ -73,7 +87,8 @@
 						struct device_attribute *attr, \
 						char *buf)		       \
 {									       \
-	struct _feat_def *_feat = dev_get_drvdata(dev);			       \
+	struct _feat_def *_feat = container_of(dev, struct _feat_def,	       \
+					       sysfs_device);		       \
 									       \
 	if (atomic_read(&_feat->status) & ZFCP_STATUS_COMMON_ERP_FAILED)       \
 		return sprintf(buf, "1\n");				       \
@@ -84,15 +99,13 @@
 						 struct device_attribute *attr,\
 						 const char *buf, size_t count)\
 {									       \
-	struct _feat_def *_feat = dev_get_drvdata(dev);			       \
+	struct _feat_def *_feat = container_of(dev, struct _feat_def,	       \
+					       sysfs_device);		       \
 	unsigned long val;						       \
 	int retval = 0;							       \
 									       \
-	mutex_lock(&zfcp_data.config_mutex);				       \
-	if (atomic_read(&_feat->status) & ZFCP_STATUS_COMMON_REMOVE) {	       \
-		retval = -EBUSY;					       \
-		goto out;						       \
-	}								       \
+	if (!(_feat && get_device(&_feat->sysfs_device)))		       \
+		return -EBUSY;						       \
 									       \
 	if (strict_strtoul(buf, 0, &val) || val != 0) {			       \
 		retval = -EINVAL;					       \
@@ -105,29 +118,82 @@
 				  _reopen_id, NULL);			       \
 	zfcp_erp_wait(_adapter);					       \
 out:									       \
-	mutex_unlock(&zfcp_data.config_mutex);				       \
+	put_device(&_feat->sysfs_device);				       \
 	return retval ? retval : (ssize_t) count;			       \
 }									       \
 static ZFCP_DEV_ATTR(_feat, failed, S_IWUSR | S_IRUGO,			       \
 		     zfcp_sysfs_##_feat##_failed_show,			       \
 		     zfcp_sysfs_##_feat##_failed_store);
 
-ZFCP_SYSFS_FAILED(zfcp_adapter, adapter, adapter, "syafai1", "syafai2");
 ZFCP_SYSFS_FAILED(zfcp_port, port, port->adapter, "sypfai1", "sypfai2");
 ZFCP_SYSFS_FAILED(zfcp_unit, unit, unit->port->adapter, "syufai1", "syufai2");
 
+static ssize_t zfcp_sysfs_adapter_failed_show(struct device *dev,
+					      struct device_attribute *attr,
+					      char *buf)
+{
+	struct ccw_device *cdev = to_ccwdev(dev);
+	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
+	int i;
+
+	if (!adapter)
+		return -ENODEV;
+
+	if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED)
+		i = sprintf(buf, "1\n");
+	else
+		i = sprintf(buf, "0\n");
+
+	zfcp_ccw_adapter_put(adapter);
+	return i;
+}
+
+static ssize_t zfcp_sysfs_adapter_failed_store(struct device *dev,
+					       struct device_attribute *attr,
+					       const char *buf, size_t count)
+{
+	struct ccw_device *cdev = to_ccwdev(dev);
+	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
+	unsigned long val;
+	int retval = 0;
+
+	if (!adapter)
+		return -ENODEV;
+
+	if (strict_strtoul(buf, 0, &val) || val != 0) {
+		retval = -EINVAL;
+		goto out;
+	}
+
+	zfcp_erp_modify_adapter_status(adapter, "syafai1", NULL,
+				       ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
+	zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
+				"syafai2", NULL);
+	zfcp_erp_wait(adapter);
+out:
+	zfcp_ccw_adapter_put(adapter);
+	return retval ? retval : (ssize_t) count;
+}
+static ZFCP_DEV_ATTR(adapter, failed, S_IWUSR | S_IRUGO,
+		     zfcp_sysfs_adapter_failed_show,
+		     zfcp_sysfs_adapter_failed_store);
+
 static ssize_t zfcp_sysfs_port_rescan_store(struct device *dev,
 					    struct device_attribute *attr,
 					    const char *buf, size_t count)
 {
-	struct zfcp_adapter *adapter = dev_get_drvdata(dev);
-	int ret;
+	struct ccw_device *cdev = to_ccwdev(dev);
+	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
 
-	if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE)
-		return -EBUSY;
+	if (!adapter)
+		return -ENODEV;
 
-	ret = zfcp_fc_scan_ports(adapter);
-	return ret ? ret : (ssize_t) count;
+	/* sync the user-space- with the kernel-invocation of scan_work */
+	queue_work(adapter->work_queue, &adapter->scan_work);
+	flush_work(&adapter->scan_work);
+	zfcp_ccw_adapter_put(adapter);
+
+	return (ssize_t) count;
 }
 static ZFCP_DEV_ATTR(adapter, port_rescan, S_IWUSR, NULL,
 		     zfcp_sysfs_port_rescan_store);
@@ -136,44 +202,34 @@
 					    struct device_attribute *attr,
 					    const char *buf, size_t count)
 {
-	struct zfcp_adapter *adapter = dev_get_drvdata(dev);
+	struct ccw_device *cdev = to_ccwdev(dev);
+	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
 	struct zfcp_port *port;
 	u64 wwpn;
-	int retval = 0;
-	LIST_HEAD(port_remove_lh);
+	int retval = -EINVAL;
 
-	mutex_lock(&zfcp_data.config_mutex);
-	if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE) {
-		retval = -EBUSY;
+	if (!adapter)
+		return -ENODEV;
+
+	if (strict_strtoull(buf, 0, (unsigned long long *) &wwpn))
 		goto out;
-	}
 
-	if (strict_strtoull(buf, 0, (unsigned long long *) &wwpn)) {
-		retval = -EINVAL;
-		goto out;
-	}
-
-	write_lock_irq(&zfcp_data.config_lock);
 	port = zfcp_get_port_by_wwpn(adapter, wwpn);
-	if (port && (atomic_read(&port->refcount) == 0)) {
-		zfcp_port_get(port);
-		atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
-		list_move(&port->list, &port_remove_lh);
-	} else
-		port = NULL;
-	write_unlock_irq(&zfcp_data.config_lock);
-
-	if (!port) {
-		retval = -ENXIO;
+	if (!port)
 		goto out;
-	}
+	else
+		retval = 0;
+
+	write_lock_irq(&adapter->port_list_lock);
+	list_del(&port->list);
+	write_unlock_irq(&adapter->port_list_lock);
+
+	put_device(&port->sysfs_device);
 
 	zfcp_erp_port_shutdown(port, 0, "syprs_1", NULL);
-	zfcp_erp_wait(adapter);
-	zfcp_port_put(port);
-	zfcp_port_dequeue(port);
+	zfcp_device_unregister(&port->sysfs_device, &zfcp_sysfs_port_attrs);
  out:
-	mutex_unlock(&zfcp_data.config_mutex);
+	zfcp_ccw_adapter_put(adapter);
 	return retval ? retval : (ssize_t) count;
 }
 static ZFCP_DEV_ATTR(adapter, port_remove, S_IWUSR, NULL,
@@ -202,16 +258,14 @@
 					 struct device_attribute *attr,
 					 const char *buf, size_t count)
 {
-	struct zfcp_port *port = dev_get_drvdata(dev);
+	struct zfcp_port *port = container_of(dev, struct zfcp_port,
+					      sysfs_device);
 	struct zfcp_unit *unit;
 	u64 fcp_lun;
 	int retval = -EINVAL;
 
-	mutex_lock(&zfcp_data.config_mutex);
-	if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) {
-		retval = -EBUSY;
-		goto out;
-	}
+	if (!(port && get_device(&port->sysfs_device)))
+		return -EBUSY;
 
 	if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun))
 		goto out;
@@ -219,15 +273,14 @@
 	unit = zfcp_unit_enqueue(port, fcp_lun);
 	if (IS_ERR(unit))
 		goto out;
-
-	retval = 0;
+	else
+		retval = 0;
 
 	zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL);
 	zfcp_erp_wait(unit->port->adapter);
 	flush_work(&unit->scsi_work);
-	zfcp_unit_put(unit);
 out:
-	mutex_unlock(&zfcp_data.config_mutex);
+	put_device(&port->sysfs_device);
 	return retval ? retval : (ssize_t) count;
 }
 static DEVICE_ATTR(unit_add, S_IWUSR, NULL, zfcp_sysfs_unit_add_store);
@@ -236,54 +289,37 @@
 					    struct device_attribute *attr,
 					    const char *buf, size_t count)
 {
-	struct zfcp_port *port = dev_get_drvdata(dev);
+	struct zfcp_port *port = container_of(dev, struct zfcp_port,
+					      sysfs_device);
 	struct zfcp_unit *unit;
 	u64 fcp_lun;
-	int retval = 0;
-	LIST_HEAD(unit_remove_lh);
+	int retval = -EINVAL;
 
-	mutex_lock(&zfcp_data.config_mutex);
-	if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) {
-		retval = -EBUSY;
+	if (!(port && get_device(&port->sysfs_device)))
+		return -EBUSY;
+
+	if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun))
 		goto out;
-	}
 
-	if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) {
-		retval = -EINVAL;
-		goto out;
-	}
-
-	write_lock_irq(&zfcp_data.config_lock);
 	unit = zfcp_get_unit_by_lun(port, fcp_lun);
-	if (unit) {
-		write_unlock_irq(&zfcp_data.config_lock);
-		/* wait for possible timeout during SCSI probe */
-		flush_work(&unit->scsi_work);
-		write_lock_irq(&zfcp_data.config_lock);
-
-		if (atomic_read(&unit->refcount) == 0) {
-			zfcp_unit_get(unit);
-			atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE,
-					&unit->status);
-			list_move(&unit->list, &unit_remove_lh);
-		} else {
-			unit = NULL;
-		}
-	}
-
-	write_unlock_irq(&zfcp_data.config_lock);
-
-	if (!unit) {
-		retval = -ENXIO;
+	if (!unit)
 		goto out;
-	}
+	else
+		retval = 0;
+
+	/* wait for possible timeout during SCSI probe */
+	flush_work(&unit->scsi_work);
+
+	write_lock_irq(&port->unit_list_lock);
+	list_del(&unit->list);
+	write_unlock_irq(&port->unit_list_lock);
+
+	put_device(&unit->sysfs_device);
 
 	zfcp_erp_unit_shutdown(unit, 0, "syurs_1", NULL);
-	zfcp_erp_wait(unit->port->adapter);
-	zfcp_unit_put(unit);
-	zfcp_unit_dequeue(unit);
+	zfcp_device_unregister(&unit->sysfs_device, &zfcp_sysfs_unit_attrs);
 out:
-	mutex_unlock(&zfcp_data.config_mutex);
+	put_device(&port->sysfs_device);
 	return retval ? retval : (ssize_t) count;
 }
 static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store);
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c
index 58e583b..aa2b60a 100644
--- a/drivers/sbus/char/envctrl.c
+++ b/drivers/sbus/char/envctrl.c
@@ -92,11 +92,11 @@
 #define ENVCTRL_CPUTEMP_MON			1    /* cpu temperature monitor */
 #define ENVCTRL_CPUVOLTAGE_MON	  	2    /* voltage monitor         */
 #define ENVCTRL_FANSTAT_MON  		3    /* fan status monitor      */
-#define ENVCTRL_ETHERTEMP_MON		4    /* ethernet temperarture */
+#define ENVCTRL_ETHERTEMP_MON		4    /* ethernet temperature */
 					     /* monitor                     */
 #define ENVCTRL_VOLTAGESTAT_MON	  	5    /* voltage status monitor  */
 #define ENVCTRL_MTHRBDTEMP_MON		6    /* motherboard temperature */
-#define ENVCTRL_SCSITEMP_MON		7    /* scsi temperarture */
+#define ENVCTRL_SCSITEMP_MON		7    /* scsi temperature */
 #define ENVCTRL_GLOBALADDR_MON		8    /* global address */
 
 /* Child device type.
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index 36c21b1..3bf7592 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -186,8 +186,12 @@
 } /* End twa_show_stats() */
 
 /* This function will set a devices queue depth */
-static int twa_change_queue_depth(struct scsi_device *sdev, int queue_depth)
+static int twa_change_queue_depth(struct scsi_device *sdev, int queue_depth,
+				  int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (queue_depth > TW_Q_LENGTH-2)
 		queue_depth = TW_Q_LENGTH-2;
 	scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
@@ -732,7 +736,7 @@
 		break;
 	case TW_IOCTL_GET_COMPATIBILITY_INFO:
 		tw_ioctl->driver_command.status = 0;
-		/* Copy compatiblity struct into ioctl data buffer */
+		/* Copy compatibility struct into ioctl data buffer */
 		tw_compat_info = (TW_Compatibility_Info *)tw_ioctl->data_buffer;
 		memcpy(tw_compat_info, &tw_dev->tw_compat_info, sizeof(TW_Compatibility_Info));
 		break;
diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c
new file mode 100644
index 0000000..4d314d7
--- /dev/null
+++ b/drivers/scsi/3w-sas.c
@@ -0,0 +1,1924 @@
+/*
+   3w-sas.c -- LSI 3ware SAS/SATA-RAID Controller device driver for Linux.
+
+   Written By: Adam Radford <linuxraid@lsi.com>
+
+   Copyright (C) 2009 LSI 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 of the License.
+
+   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.
+
+   NO WARRANTY
+   THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+   CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+   LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+   solely responsible for determining the appropriateness of using and
+   distributing the Program and assumes all risks associated with its
+   exercise of rights under this Agreement, including but not limited to
+   the risks and costs of program errors, damage to or loss of data,
+   programs or equipment, and unavailability or interruption of operations.
+
+   DISCLAIMER OF LIABILITY
+   NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+   DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
+   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+   TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+   USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+   HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+
+   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
+
+   Controllers supported by this driver:
+
+   LSI 3ware 9750 6Gb/s SAS/SATA-RAID
+
+   Bugs/Comments/Suggestions should be mailed to:
+   linuxraid@lsi.com
+
+   For more information, goto:
+   http://www.lsi.com
+
+   History
+   -------
+   3.26.02.000 - Initial driver release.
+*/
+
+#include <linux/module.h>
+#include <linux/reboot.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/moduleparam.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/time.h>
+#include <linux/mutex.h>
+#include <linux/smp_lock.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_cmnd.h>
+#include "3w-sas.h"
+
+/* Globals */
+#define TW_DRIVER_VERSION "3.26.02.000"
+static TW_Device_Extension *twl_device_extension_list[TW_MAX_SLOT];
+static unsigned int twl_device_extension_count;
+static int twl_major = -1;
+extern struct timezone sys_tz;
+
+/* Module parameters */
+MODULE_AUTHOR ("LSI");
+MODULE_DESCRIPTION ("LSI 3ware SAS/SATA-RAID Linux Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(TW_DRIVER_VERSION);
+
+static int use_msi;
+module_param(use_msi, int, S_IRUGO);
+MODULE_PARM_DESC(use_msi, "Use Message Signaled Interrupts. Default: 0");
+
+/* Function prototypes */
+static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset);
+
+/* Functions */
+
+/* This function returns AENs through sysfs */
+static ssize_t twl_sysfs_aen_read(struct kobject *kobj,
+				  struct bin_attribute *bin_attr,
+				  char *outbuf, loff_t offset, size_t count)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct Scsi_Host *shost = class_to_shost(dev);
+	TW_Device_Extension *tw_dev = (TW_Device_Extension *)shost->hostdata;
+	unsigned long flags = 0;
+	ssize_t ret;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	spin_lock_irqsave(tw_dev->host->host_lock, flags);
+	ret = memory_read_from_buffer(outbuf, count, &offset, tw_dev->event_queue[0], sizeof(TW_Event) * TW_Q_LENGTH);
+	spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
+
+	return ret;
+} /* End twl_sysfs_aen_read() */
+
+/* aen_read sysfs attribute initializer */
+static struct bin_attribute twl_sysfs_aen_read_attr = {
+	.attr = {
+		.name = "3ware_aen_read",
+		.mode = S_IRUSR,
+	}, 
+	.size = 0,
+	.read = twl_sysfs_aen_read
+};
+
+/* This function returns driver compatibility info through sysfs */
+static ssize_t twl_sysfs_compat_info(struct kobject *kobj,
+				     struct bin_attribute *bin_attr,
+				     char *outbuf, loff_t offset, size_t count)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct Scsi_Host *shost = class_to_shost(dev);
+	TW_Device_Extension *tw_dev = (TW_Device_Extension *)shost->hostdata;
+	unsigned long flags = 0;
+	ssize_t ret;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	spin_lock_irqsave(tw_dev->host->host_lock, flags);
+	ret = memory_read_from_buffer(outbuf, count, &offset, &tw_dev->tw_compat_info, sizeof(TW_Compatibility_Info));
+	spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
+
+	return ret;
+} /* End twl_sysfs_compat_info() */
+
+/* compat_info sysfs attribute initializer */
+static struct bin_attribute twl_sysfs_compat_info_attr = {
+	.attr = {
+		.name = "3ware_compat_info",
+		.mode = S_IRUSR,
+	}, 
+	.size = 0,
+	.read = twl_sysfs_compat_info
+};
+
+/* Show some statistics about the card */
+static ssize_t twl_show_stats(struct device *dev,
+			      struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *host = class_to_shost(dev);
+	TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
+	unsigned long flags = 0;
+	ssize_t len;
+
+	spin_lock_irqsave(tw_dev->host->host_lock, flags);
+	len = snprintf(buf, PAGE_SIZE, "3w-sas Driver version: %s\n"
+		       "Current commands posted:   %4d\n"
+		       "Max commands posted:       %4d\n"
+		       "Last sgl length:           %4d\n"
+		       "Max sgl length:            %4d\n"
+		       "Last sector count:         %4d\n"
+		       "Max sector count:          %4d\n"
+		       "SCSI Host Resets:          %4d\n"
+		       "AEN's:                     %4d\n", 
+		       TW_DRIVER_VERSION,
+		       tw_dev->posted_request_count,
+		       tw_dev->max_posted_request_count,
+		       tw_dev->sgl_entries,
+		       tw_dev->max_sgl_entries,
+		       tw_dev->sector_count,
+		       tw_dev->max_sector_count,
+		       tw_dev->num_resets,
+		       tw_dev->aen_count);
+	spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
+	return len;
+} /* End twl_show_stats() */
+
+/* This function will set a devices queue depth */
+static int twl_change_queue_depth(struct scsi_device *sdev, int queue_depth,
+				  int reason)
+{
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
+	if (queue_depth > TW_Q_LENGTH-2)
+		queue_depth = TW_Q_LENGTH-2;
+	scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
+	return queue_depth;
+} /* End twl_change_queue_depth() */
+
+/* stats sysfs attribute initializer */
+static struct device_attribute twl_host_stats_attr = {
+	.attr = {
+		.name = 	"3ware_stats",
+		.mode =		S_IRUGO,
+	},
+	.show = twl_show_stats
+};
+
+/* Host attributes initializer */
+static struct device_attribute *twl_host_attrs[] = {
+	&twl_host_stats_attr,
+	NULL,
+};
+
+/* This function will look up an AEN severity string */
+static char *twl_aen_severity_lookup(unsigned char severity_code)
+{
+	char *retval = NULL;
+
+	if ((severity_code < (unsigned char) TW_AEN_SEVERITY_ERROR) ||
+	    (severity_code > (unsigned char) TW_AEN_SEVERITY_DEBUG))
+		goto out;
+
+	retval = twl_aen_severity_table[severity_code];
+out:
+	return retval;
+} /* End twl_aen_severity_lookup() */
+
+/* This function will queue an event */
+static void twl_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
+{
+	u32 local_time;
+	struct timeval time;
+	TW_Event *event;
+	unsigned short aen;
+	char host[16];
+	char *error_str;
+
+	tw_dev->aen_count++;
+
+	/* Fill out event info */
+	event = tw_dev->event_queue[tw_dev->error_index];
+
+	host[0] = '\0';
+	if (tw_dev->host)
+		sprintf(host, " scsi%d:", tw_dev->host->host_no);
+
+	aen = le16_to_cpu(header->status_block.error);
+	memset(event, 0, sizeof(TW_Event));
+
+	event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
+	do_gettimeofday(&time);
+	local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
+	event->time_stamp_sec = local_time;
+	event->aen_code = aen;
+	event->retrieved = TW_AEN_NOT_RETRIEVED;
+	event->sequence_id = tw_dev->error_sequence_id;
+	tw_dev->error_sequence_id++;
+
+	/* Check for embedded error string */
+	error_str = &(header->err_specific_desc[strlen(header->err_specific_desc)+1]);
+
+	header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0';
+	event->parameter_len = strlen(header->err_specific_desc);
+	memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len + 1 + strlen(error_str));
+	if (event->severity != TW_AEN_SEVERITY_DEBUG)
+		printk(KERN_WARNING "3w-sas:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n",
+		       host,
+		       twl_aen_severity_lookup(TW_SEV_OUT(header->status_block.severity__reserved)),
+		       TW_MESSAGE_SOURCE_CONTROLLER_EVENT, aen, error_str,
+		       header->err_specific_desc);
+	else
+		tw_dev->aen_count--;
+
+	tw_dev->error_index = (tw_dev->error_index + 1 ) % TW_Q_LENGTH;
+} /* End twl_aen_queue_event() */
+
+/* This function will attempt to post a command packet to the board */
+static int twl_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
+{
+	dma_addr_t command_que_value;
+
+	command_que_value = tw_dev->command_packet_phys[request_id];
+	command_que_value += TW_COMMAND_OFFSET;
+
+	/* First write upper 4 bytes */
+	writel((u32)((u64)command_que_value >> 32), TWL_HIBQPH_REG_ADDR(tw_dev));
+	/* Then the lower 4 bytes */
+	writel((u32)(command_que_value | TWL_PULL_MODE), TWL_HIBQPL_REG_ADDR(tw_dev));
+
+	tw_dev->state[request_id] = TW_S_POSTED;
+	tw_dev->posted_request_count++;
+	if (tw_dev->posted_request_count > tw_dev->max_posted_request_count)
+		tw_dev->max_posted_request_count = tw_dev->posted_request_count;
+
+	return 0;
+} /* End twl_post_command_packet() */
+
+/* This function will perform a pci-dma mapping for a scatter gather list */
+static int twl_map_scsi_sg_data(TW_Device_Extension *tw_dev, int request_id)
+{
+	int use_sg;
+	struct scsi_cmnd *cmd = tw_dev->srb[request_id];
+
+	use_sg = scsi_dma_map(cmd);
+	if (!use_sg)
+		return 0;
+	else if (use_sg < 0) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1, "Failed to map scatter gather list");
+		return 0;
+	}
+
+	cmd->SCp.phase = TW_PHASE_SGLIST;
+	cmd->SCp.have_data_in = use_sg;
+
+	return use_sg;
+} /* End twl_map_scsi_sg_data() */
+
+/* This function hands scsi cdb's to the firmware */
+static int twl_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry_ISO *sglistarg)
+{
+	TW_Command_Full *full_command_packet;
+	TW_Command_Apache *command_packet;
+	int i, sg_count;
+	struct scsi_cmnd *srb = NULL;
+	struct scatterlist *sglist = NULL, *sg;
+	int retval = 1;
+
+	if (tw_dev->srb[request_id]) {
+		srb = tw_dev->srb[request_id];
+		if (scsi_sglist(srb))
+			sglist = scsi_sglist(srb);
+	}
+
+	/* Initialize command packet */
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+	full_command_packet->header.header_desc.size_header = 128;
+	full_command_packet->header.status_block.error = 0;
+	full_command_packet->header.status_block.severity__reserved = 0;
+
+	command_packet = &full_command_packet->command.newcommand;
+	command_packet->status = 0;
+	command_packet->opcode__reserved = TW_OPRES_IN(0, TW_OP_EXECUTE_SCSI);
+
+	/* We forced 16 byte cdb use earlier */
+	if (!cdb)
+		memcpy(command_packet->cdb, srb->cmnd, TW_MAX_CDB_LEN);
+	else
+		memcpy(command_packet->cdb, cdb, TW_MAX_CDB_LEN);
+
+	if (srb) {
+		command_packet->unit = srb->device->id;
+		command_packet->request_id__lunl =
+			cpu_to_le16(TW_REQ_LUN_IN(srb->device->lun, request_id));
+	} else {
+		command_packet->request_id__lunl =
+			cpu_to_le16(TW_REQ_LUN_IN(0, request_id));
+		command_packet->unit = 0;
+	}
+
+	command_packet->sgl_offset = 16;
+
+	if (!sglistarg) {
+		/* Map sglist from scsi layer to cmd packet */
+		if (scsi_sg_count(srb)) {
+			sg_count = twl_map_scsi_sg_data(tw_dev, request_id);
+			if (sg_count == 0)
+				goto out;
+
+			scsi_for_each_sg(srb, sg, sg_count, i) {
+				command_packet->sg_list[i].address = TW_CPU_TO_SGL(sg_dma_address(sg));
+				command_packet->sg_list[i].length = TW_CPU_TO_SGL(sg_dma_len(sg));
+			}
+			command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN((srb->device->lun >> 4), scsi_sg_count(tw_dev->srb[request_id])));
+		}
+	} else {
+		/* Internal cdb post */
+		for (i = 0; i < use_sg; i++) {
+			command_packet->sg_list[i].address = TW_CPU_TO_SGL(sglistarg[i].address);
+			command_packet->sg_list[i].length = TW_CPU_TO_SGL(sglistarg[i].length);
+		}
+		command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN(0, use_sg));
+	}
+
+	/* Update some stats */
+	if (srb) {
+		tw_dev->sector_count = scsi_bufflen(srb) / 512;
+		if (tw_dev->sector_count > tw_dev->max_sector_count)
+			tw_dev->max_sector_count = tw_dev->sector_count;
+		tw_dev->sgl_entries = scsi_sg_count(srb);
+		if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
+			tw_dev->max_sgl_entries = tw_dev->sgl_entries;
+	}
+
+	/* Now post the command to the board */
+	retval = twl_post_command_packet(tw_dev, request_id);
+
+out:
+	return retval;
+} /* End twl_scsiop_execute_scsi() */
+
+/* This function will read the aen queue from the isr */
+static int twl_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
+{
+	char cdb[TW_MAX_CDB_LEN];
+	TW_SG_Entry_ISO sglist[1];
+	TW_Command_Full *full_command_packet;
+	int retval = 1;
+
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+	memset(full_command_packet, 0, sizeof(TW_Command_Full));
+
+	/* Initialize cdb */
+	memset(&cdb, 0, TW_MAX_CDB_LEN);
+	cdb[0] = REQUEST_SENSE; /* opcode */
+	cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
+
+	/* Initialize sglist */
+	memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
+	sglist[0].length = TW_SECTOR_SIZE;
+	sglist[0].address = tw_dev->generic_buffer_phys[request_id];
+
+	/* Mark internal command */
+	tw_dev->srb[request_id] = NULL;
+
+	/* Now post the command packet */
+	if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2, "Post failed while reading AEN queue");
+		goto out;
+	}
+	retval = 0;
+out:
+	return retval;
+} /* End twl_aen_read_queue() */
+
+/* This function will sync firmware time with the host time */
+static void twl_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
+{
+	u32 schedulertime;
+	struct timeval utc;
+	TW_Command_Full *full_command_packet;
+	TW_Command *command_packet;
+	TW_Param_Apache *param;
+	u32 local_time;
+
+	/* Fill out the command packet */
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+	memset(full_command_packet, 0, sizeof(TW_Command_Full));
+	command_packet = &full_command_packet->command.oldcommand;
+	command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM);
+	command_packet->request_id = request_id;
+	command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
+	command_packet->byte8_offset.param.sgl[0].length = TW_CPU_TO_SGL(TW_SECTOR_SIZE);
+	command_packet->size = TW_COMMAND_SIZE;
+	command_packet->byte6_offset.parameter_count = cpu_to_le16(1);
+
+	/* Setup the param */
+	param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
+	memset(param, 0, TW_SECTOR_SIZE);
+	param->table_id = cpu_to_le16(TW_TIMEKEEP_TABLE | 0x8000); /* Controller time keep table */
+	param->parameter_id = cpu_to_le16(0x3); /* SchedulerTime */
+	param->parameter_size_bytes = cpu_to_le16(4);
+
+	/* Convert system time in UTC to local time seconds since last 
+           Sunday 12:00AM */
+	do_gettimeofday(&utc);
+	local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
+	schedulertime = local_time - (3 * 86400);
+	schedulertime = cpu_to_le32(schedulertime % 604800);
+
+	memcpy(param->data, &schedulertime, sizeof(u32));
+
+	/* Mark internal command */
+	tw_dev->srb[request_id] = NULL;
+
+	/* Now post the command */
+	twl_post_command_packet(tw_dev, request_id);
+} /* End twl_aen_sync_time() */
+
+/* This function will assign an available request id */
+static void twl_get_request_id(TW_Device_Extension *tw_dev, int *request_id)
+{
+	*request_id = tw_dev->free_queue[tw_dev->free_head];
+	tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH;
+	tw_dev->state[*request_id] = TW_S_STARTED;
+} /* End twl_get_request_id() */
+
+/* This function will free a request id */
+static void twl_free_request_id(TW_Device_Extension *tw_dev, int request_id)
+{
+	tw_dev->free_queue[tw_dev->free_tail] = request_id;
+	tw_dev->state[request_id] = TW_S_FINISHED;
+	tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH;
+} /* End twl_free_request_id() */
+
+/* This function will complete an aen request from the isr */
+static int twl_aen_complete(TW_Device_Extension *tw_dev, int request_id)
+{
+	TW_Command_Full *full_command_packet;
+	TW_Command *command_packet;
+	TW_Command_Apache_Header *header;
+	unsigned short aen;
+	int retval = 1;
+
+	header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
+	tw_dev->posted_request_count--;
+	aen = le16_to_cpu(header->status_block.error);
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+	command_packet = &full_command_packet->command.oldcommand;
+
+	/* First check for internal completion of set param for time sync */
+	if (TW_OP_OUT(command_packet->opcode__sgloffset) == TW_OP_SET_PARAM) {
+		/* Keep reading the queue in case there are more aen's */
+		if (twl_aen_read_queue(tw_dev, request_id))
+			goto out2;
+	        else {
+			retval = 0;
+			goto out;
+		}
+	}
+
+	switch (aen) {
+	case TW_AEN_QUEUE_EMPTY:
+		/* Quit reading the queue if this is the last one */
+		break;
+	case TW_AEN_SYNC_TIME_WITH_HOST:
+		twl_aen_sync_time(tw_dev, request_id);
+		retval = 0;
+		goto out;
+	default:
+		twl_aen_queue_event(tw_dev, header);
+
+		/* If there are more aen's, keep reading the queue */
+		if (twl_aen_read_queue(tw_dev, request_id))
+			goto out2;
+		else {
+			retval = 0;
+			goto out;
+		}
+	}
+	retval = 0;
+out2:
+	tw_dev->state[request_id] = TW_S_COMPLETED;
+	twl_free_request_id(tw_dev, request_id);
+	clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
+out:
+	return retval;
+} /* End twl_aen_complete() */
+
+/* This function will poll for a response */
+static int twl_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds)
+{
+	unsigned long before;
+	dma_addr_t mfa;
+	u32 regh, regl;
+	u32 response;
+	int retval = 1;
+	int found = 0;
+
+	before = jiffies;
+
+	while (!found) {
+		if (sizeof(dma_addr_t) > 4) {
+			regh = readl(TWL_HOBQPH_REG_ADDR(tw_dev));
+			regl = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
+			mfa = ((u64)regh << 32) | regl;
+		} else
+			mfa = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
+
+		response = (u32)mfa;
+
+		if (TW_RESID_OUT(response) == request_id)
+			found = 1;
+
+		if (time_after(jiffies, before + HZ * seconds))
+			goto out;
+
+		msleep(50);
+	}
+	retval = 0;
+out: 
+	return retval;
+} /* End twl_poll_response() */
+
+/* This function will drain the aen queue */
+static int twl_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset)
+{
+	int request_id = 0;
+	char cdb[TW_MAX_CDB_LEN];
+	TW_SG_Entry_ISO sglist[1];
+	int finished = 0, count = 0;
+	TW_Command_Full *full_command_packet;
+	TW_Command_Apache_Header *header;
+	unsigned short aen;
+	int first_reset = 0, queue = 0, retval = 1;
+
+	if (no_check_reset)
+		first_reset = 0;
+	else
+		first_reset = 1;
+
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+	memset(full_command_packet, 0, sizeof(TW_Command_Full));
+
+	/* Initialize cdb */
+	memset(&cdb, 0, TW_MAX_CDB_LEN);
+	cdb[0] = REQUEST_SENSE; /* opcode */
+	cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
+
+	/* Initialize sglist */
+	memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
+	sglist[0].length = TW_SECTOR_SIZE;
+	sglist[0].address = tw_dev->generic_buffer_phys[request_id];
+
+	/* Mark internal command */
+	tw_dev->srb[request_id] = NULL;
+
+	do {
+		/* Send command to the board */
+		if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
+			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x3, "Error posting request sense");
+			goto out;
+		}
+
+		/* Now poll for completion */
+		if (twl_poll_response(tw_dev, request_id, 30)) {
+			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x4, "No valid response while draining AEN queue");
+			tw_dev->posted_request_count--;
+			goto out;
+		}
+
+		tw_dev->posted_request_count--;
+		header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
+		aen = le16_to_cpu(header->status_block.error);
+		queue = 0;
+		count++;
+
+		switch (aen) {
+		case TW_AEN_QUEUE_EMPTY:
+			if (first_reset != 1)
+				goto out;
+			else
+				finished = 1;
+			break;
+		case TW_AEN_SOFT_RESET:
+			if (first_reset == 0)
+				first_reset = 1;
+			else
+				queue = 1;
+			break;
+		case TW_AEN_SYNC_TIME_WITH_HOST:
+			break;
+		default:
+			queue = 1;
+		}
+
+		/* Now queue an event info */
+		if (queue)
+			twl_aen_queue_event(tw_dev, header);
+	} while ((finished == 0) && (count < TW_MAX_AEN_DRAIN));
+
+	if (count == TW_MAX_AEN_DRAIN)
+		goto out;
+
+	retval = 0;
+out:
+	tw_dev->state[request_id] = TW_S_INITIAL;
+	return retval;
+} /* End twl_aen_drain_queue() */
+
+/* This function will allocate memory and check if it is correctly aligned */
+static int twl_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
+{
+	int i;
+	dma_addr_t dma_handle;
+	unsigned long *cpu_addr;
+	int retval = 1;
+
+	cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, &dma_handle);
+	if (!cpu_addr) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x5, "Memory allocation failed");
+		goto out;
+	}
+
+	memset(cpu_addr, 0, size*TW_Q_LENGTH);
+
+	for (i = 0; i < TW_Q_LENGTH; i++) {
+		switch(which) {
+		case 0:
+			tw_dev->command_packet_phys[i] = dma_handle+(i*size);
+			tw_dev->command_packet_virt[i] = (TW_Command_Full *)((unsigned char *)cpu_addr + (i*size));
+			break;
+		case 1:
+			tw_dev->generic_buffer_phys[i] = dma_handle+(i*size);
+			tw_dev->generic_buffer_virt[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
+			break;
+		case 2:
+			tw_dev->sense_buffer_phys[i] = dma_handle+(i*size);
+			tw_dev->sense_buffer_virt[i] = (TW_Command_Apache_Header *)((unsigned char *)cpu_addr + (i*size));
+			break;
+		}
+	}
+	retval = 0;
+out:
+	return retval;
+} /* End twl_allocate_memory() */
+
+/* This function will load the request id and various sgls for ioctls */
+static void twl_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length)
+{
+	TW_Command *oldcommand;
+	TW_Command_Apache *newcommand;
+	TW_SG_Entry_ISO *sgl;
+	unsigned int pae = 0;
+
+	if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4))
+		pae = 1;
+
+	if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
+		newcommand = &full_command_packet->command.newcommand;
+		newcommand->request_id__lunl =
+			cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id));
+		if (length) {
+			newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
+			newcommand->sg_list[0].length = TW_CPU_TO_SGL(length);
+		}
+		newcommand->sgl_entries__lunh =
+			cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), length ? 1 : 0));
+	} else {
+		oldcommand = &full_command_packet->command.oldcommand;
+		oldcommand->request_id = request_id;
+
+		if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) {
+			/* Load the sg list */
+			sgl = (TW_SG_Entry_ISO *)((u32 *)oldcommand+oldcommand->size - (sizeof(TW_SG_Entry_ISO)/4) + pae + (sizeof(dma_addr_t) > 4 ? 1 : 0));
+			sgl->address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
+			sgl->length = TW_CPU_TO_SGL(length);
+			oldcommand->size += pae;
+			oldcommand->size += sizeof(dma_addr_t) > 4 ? 1 : 0;
+		}
+	}
+} /* End twl_load_sgl() */
+
+/* This function handles ioctl for the character device
+   This interface is used by smartmontools open source software */
+static int twl_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	long timeout;
+	unsigned long *cpu_addr, data_buffer_length_adjusted = 0, flags = 0;
+	dma_addr_t dma_handle;
+	int request_id = 0;
+	TW_Ioctl_Driver_Command driver_command;
+	TW_Ioctl_Buf_Apache *tw_ioctl;
+	TW_Command_Full *full_command_packet;
+	TW_Device_Extension *tw_dev = twl_device_extension_list[iminor(inode)];
+	int retval = -EFAULT;
+	void __user *argp = (void __user *)arg;
+
+	/* Only let one of these through at a time */
+	if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) {
+		retval = -EINTR;
+		goto out;
+	}
+
+	/* First copy down the driver command */
+	if (copy_from_user(&driver_command, argp, sizeof(TW_Ioctl_Driver_Command)))
+		goto out2;
+
+	/* Check data buffer size */
+	if (driver_command.buffer_length > TW_MAX_SECTORS * 2048) {
+		retval = -EINVAL;
+		goto out2;
+	}
+
+	/* Hardware can only do multiple of 512 byte transfers */
+	data_buffer_length_adjusted = (driver_command.buffer_length + 511) & ~511;
+
+	/* Now allocate ioctl buf memory */
+	cpu_addr = dma_alloc_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, &dma_handle, GFP_KERNEL);
+	if (!cpu_addr) {
+		retval = -ENOMEM;
+		goto out2;
+	}
+
+	tw_ioctl = (TW_Ioctl_Buf_Apache *)cpu_addr;
+
+	/* Now copy down the entire ioctl */
+	if (copy_from_user(tw_ioctl, argp, driver_command.buffer_length + sizeof(TW_Ioctl_Buf_Apache) - 1))
+		goto out3;
+
+	/* See which ioctl we are doing */
+	switch (cmd) {
+	case TW_IOCTL_FIRMWARE_PASS_THROUGH:
+		spin_lock_irqsave(tw_dev->host->host_lock, flags);
+		twl_get_request_id(tw_dev, &request_id);
+
+		/* Flag internal command */
+		tw_dev->srb[request_id] = NULL;
+
+		/* Flag chrdev ioctl */
+		tw_dev->chrdev_request_id = request_id;
+
+		full_command_packet = (TW_Command_Full *)&tw_ioctl->firmware_command;
+
+		/* Load request id and sglist for both command types */
+		twl_load_sgl(tw_dev, full_command_packet, request_id, dma_handle, data_buffer_length_adjusted);
+
+		memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full));
+
+		/* Now post the command packet to the controller */
+		twl_post_command_packet(tw_dev, request_id);
+		spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
+
+		timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
+
+		/* Now wait for command to complete */
+		timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
+
+		/* We timed out, and didn't get an interrupt */
+		if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
+			/* Now we need to reset the board */
+			printk(KERN_WARNING "3w-sas: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, resetting card.\n",
+			       tw_dev->host->host_no, TW_DRIVER, 0x6,
+			       cmd);
+			retval = -EIO;
+			twl_reset_device_extension(tw_dev, 1);
+			goto out3;
+		}
+
+		/* Now copy in the command packet response */
+		memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virt[request_id], sizeof(TW_Command_Full));
+		
+		/* Now complete the io */
+		spin_lock_irqsave(tw_dev->host->host_lock, flags);
+		tw_dev->posted_request_count--;
+		tw_dev->state[request_id] = TW_S_COMPLETED;
+		twl_free_request_id(tw_dev, request_id);
+		spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
+		break;
+	default:
+		retval = -ENOTTY;
+		goto out3;
+	}
+
+	/* Now copy the entire response to userspace */
+	if (copy_to_user(argp, tw_ioctl, sizeof(TW_Ioctl_Buf_Apache) + driver_command.buffer_length - 1) == 0)
+		retval = 0;
+out3:
+	/* Now free ioctl buf memory */
+	dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, cpu_addr, dma_handle);
+out2:
+	mutex_unlock(&tw_dev->ioctl_lock);
+out:
+	return retval;
+} /* End twl_chrdev_ioctl() */
+
+/* This function handles open for the character device */
+static int twl_chrdev_open(struct inode *inode, struct file *file)
+{
+	unsigned int minor_number;
+	int retval = -ENODEV;
+
+	if (!capable(CAP_SYS_ADMIN)) {
+		retval = -EACCES;
+		goto out;
+	}
+
+	cycle_kernel_lock();
+	minor_number = iminor(inode);
+	if (minor_number >= twl_device_extension_count)
+		goto out;
+	retval = 0;
+out:
+	return retval;
+} /* End twl_chrdev_open() */
+
+/* File operations struct for character device */
+static const struct file_operations twl_fops = {
+	.owner		= THIS_MODULE,
+	.ioctl		= twl_chrdev_ioctl,
+	.open		= twl_chrdev_open,
+	.release	= NULL
+};
+
+/* This function passes sense data from firmware to scsi layer */
+static int twl_fill_sense(TW_Device_Extension *tw_dev, int i, int request_id, int copy_sense, int print_host)
+{
+	TW_Command_Apache_Header *header;
+	TW_Command_Full *full_command_packet;
+	unsigned short error;
+	char *error_str;
+	int retval = 1;
+
+	header = tw_dev->sense_buffer_virt[i];
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+
+	/* Get embedded firmware error string */
+	error_str = &(header->err_specific_desc[strlen(header->err_specific_desc) + 1]);
+
+	/* Don't print error for Logical unit not supported during rollcall */
+	error = le16_to_cpu(header->status_block.error);
+	if ((error != TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) && (error != TW_ERROR_UNIT_OFFLINE) && (error != TW_ERROR_INVALID_FIELD_IN_CDB)) {
+		if (print_host)
+			printk(KERN_WARNING "3w-sas: scsi%d: ERROR: (0x%02X:0x%04X): %s:%s.\n",
+			       tw_dev->host->host_no,
+			       TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
+			       header->status_block.error,
+			       error_str, 
+			       header->err_specific_desc);
+		else
+			printk(KERN_WARNING "3w-sas: ERROR: (0x%02X:0x%04X): %s:%s.\n",
+			       TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
+			       header->status_block.error,
+			       error_str,
+			       header->err_specific_desc);
+	}
+
+	if (copy_sense) {
+		memcpy(tw_dev->srb[request_id]->sense_buffer, header->sense_data, TW_SENSE_DATA_LENGTH);
+		tw_dev->srb[request_id]->result = (full_command_packet->command.newcommand.status << 1);
+		goto out;
+	}
+out:
+	return retval;
+} /* End twl_fill_sense() */
+
+/* This function will free up device extension resources */
+static void twl_free_device_extension(TW_Device_Extension *tw_dev)
+{
+	if (tw_dev->command_packet_virt[0])
+		pci_free_consistent(tw_dev->tw_pci_dev,
+				    sizeof(TW_Command_Full)*TW_Q_LENGTH,
+				    tw_dev->command_packet_virt[0],
+				    tw_dev->command_packet_phys[0]);
+
+	if (tw_dev->generic_buffer_virt[0])
+		pci_free_consistent(tw_dev->tw_pci_dev,
+				    TW_SECTOR_SIZE*TW_Q_LENGTH,
+				    tw_dev->generic_buffer_virt[0],
+				    tw_dev->generic_buffer_phys[0]);
+
+	if (tw_dev->sense_buffer_virt[0])
+		pci_free_consistent(tw_dev->tw_pci_dev,
+				    sizeof(TW_Command_Apache_Header)*
+				    TW_Q_LENGTH,
+				    tw_dev->sense_buffer_virt[0],
+				    tw_dev->sense_buffer_phys[0]);
+
+	kfree(tw_dev->event_queue[0]);
+} /* End twl_free_device_extension() */
+
+/* This function will get parameter table entries from the firmware */
+static void *twl_get_param(TW_Device_Extension *tw_dev, int request_id, int table_id, int parameter_id, int parameter_size_bytes)
+{
+	TW_Command_Full *full_command_packet;
+	TW_Command *command_packet;
+	TW_Param_Apache *param;
+	void *retval = NULL;
+
+	/* Setup the command packet */
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+	memset(full_command_packet, 0, sizeof(TW_Command_Full));
+	command_packet = &full_command_packet->command.oldcommand;
+
+	command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
+	command_packet->size              = TW_COMMAND_SIZE;
+	command_packet->request_id        = request_id;
+	command_packet->byte6_offset.block_count = cpu_to_le16(1);
+
+	/* Now setup the param */
+	param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
+	memset(param, 0, TW_SECTOR_SIZE);
+	param->table_id = cpu_to_le16(table_id | 0x8000);
+	param->parameter_id = cpu_to_le16(parameter_id);
+	param->parameter_size_bytes = cpu_to_le16(parameter_size_bytes);
+
+	command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
+	command_packet->byte8_offset.param.sgl[0].length = TW_CPU_TO_SGL(TW_SECTOR_SIZE);
+
+	/* Post the command packet to the board */
+	twl_post_command_packet(tw_dev, request_id);
+
+	/* Poll for completion */
+	if (twl_poll_response(tw_dev, request_id, 30))
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x7, "No valid response during get param")
+	else
+		retval = (void *)&(param->data[0]);
+
+	tw_dev->posted_request_count--;
+	tw_dev->state[request_id] = TW_S_INITIAL;
+
+	return retval;
+} /* End twl_get_param() */
+
+/* This function will send an initconnection command to controller */
+static int twl_initconnection(TW_Device_Extension *tw_dev, int message_credits,
+ 			      u32 set_features, unsigned short current_fw_srl, 
+			      unsigned short current_fw_arch_id, 
+			      unsigned short current_fw_branch, 
+			      unsigned short current_fw_build, 
+			      unsigned short *fw_on_ctlr_srl, 
+			      unsigned short *fw_on_ctlr_arch_id, 
+			      unsigned short *fw_on_ctlr_branch, 
+			      unsigned short *fw_on_ctlr_build, 
+			      u32 *init_connect_result)
+{
+	TW_Command_Full *full_command_packet;
+	TW_Initconnect *tw_initconnect;
+	int request_id = 0, retval = 1;
+
+	/* Initialize InitConnection command packet */
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+	memset(full_command_packet, 0, sizeof(TW_Command_Full));
+	full_command_packet->header.header_desc.size_header = 128;
+	
+	tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand;
+	tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION);
+	tw_initconnect->request_id = request_id;
+	tw_initconnect->message_credits = cpu_to_le16(message_credits);
+	tw_initconnect->features = set_features;
+
+	/* Turn on 64-bit sgl support if we need to */
+	tw_initconnect->features |= sizeof(dma_addr_t) > 4 ? 1 : 0;
+
+	tw_initconnect->features = cpu_to_le32(tw_initconnect->features);
+
+	if (set_features & TW_EXTENDED_INIT_CONNECT) {
+		tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE_EXTENDED;
+		tw_initconnect->fw_srl = cpu_to_le16(current_fw_srl);
+		tw_initconnect->fw_arch_id = cpu_to_le16(current_fw_arch_id);
+		tw_initconnect->fw_branch = cpu_to_le16(current_fw_branch);
+		tw_initconnect->fw_build = cpu_to_le16(current_fw_build);
+	} else 
+		tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE;
+
+	/* Send command packet to the board */
+	twl_post_command_packet(tw_dev, request_id);
+
+	/* Poll for completion */
+	if (twl_poll_response(tw_dev, request_id, 30)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x8, "No valid response during init connection");
+	} else {
+		if (set_features & TW_EXTENDED_INIT_CONNECT) {
+			*fw_on_ctlr_srl = le16_to_cpu(tw_initconnect->fw_srl);
+			*fw_on_ctlr_arch_id = le16_to_cpu(tw_initconnect->fw_arch_id);
+			*fw_on_ctlr_branch = le16_to_cpu(tw_initconnect->fw_branch);
+			*fw_on_ctlr_build = le16_to_cpu(tw_initconnect->fw_build);
+			*init_connect_result = le32_to_cpu(tw_initconnect->result);
+		}
+		retval = 0;
+	}
+
+	tw_dev->posted_request_count--;
+	tw_dev->state[request_id] = TW_S_INITIAL;
+
+	return retval;
+} /* End twl_initconnection() */
+
+/* This function will initialize the fields of a device extension */
+static int twl_initialize_device_extension(TW_Device_Extension *tw_dev)
+{
+	int i, retval = 1;
+
+	/* Initialize command packet buffers */
+	if (twl_allocate_memory(tw_dev, sizeof(TW_Command_Full), 0)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x9, "Command packet memory allocation failed");
+		goto out;
+	}
+
+	/* Initialize generic buffer */
+	if (twl_allocate_memory(tw_dev, TW_SECTOR_SIZE, 1)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xa, "Generic memory allocation failed");
+		goto out;
+	}
+
+	/* Allocate sense buffers */
+	if (twl_allocate_memory(tw_dev, sizeof(TW_Command_Apache_Header), 2)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xb, "Sense buffer allocation failed");
+		goto out;
+	}
+
+	/* Allocate event info space */
+	tw_dev->event_queue[0] = kcalloc(TW_Q_LENGTH, sizeof(TW_Event), GFP_KERNEL);
+	if (!tw_dev->event_queue[0]) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xc, "Event info memory allocation failed");
+		goto out;
+	}
+
+	for (i = 0; i < TW_Q_LENGTH; i++) {
+		tw_dev->event_queue[i] = (TW_Event *)((unsigned char *)tw_dev->event_queue[0] + (i * sizeof(TW_Event)));
+		tw_dev->free_queue[i] = i;
+		tw_dev->state[i] = TW_S_INITIAL;
+	}
+
+	tw_dev->free_head = TW_Q_START;
+	tw_dev->free_tail = TW_Q_START;
+	tw_dev->error_sequence_id = 1;
+	tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
+
+	mutex_init(&tw_dev->ioctl_lock);
+	init_waitqueue_head(&tw_dev->ioctl_wqueue);
+
+	retval = 0;
+out:
+	return retval;
+} /* End twl_initialize_device_extension() */
+
+/* This function will perform a pci-dma unmap */
+static void twl_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id)
+{
+	struct scsi_cmnd *cmd = tw_dev->srb[request_id];
+
+	if (cmd->SCp.phase == TW_PHASE_SGLIST)
+		scsi_dma_unmap(cmd);
+} /* End twl_unmap_scsi_data() */
+
+/* This function will handle attention interrupts */
+static int twl_handle_attention_interrupt(TW_Device_Extension *tw_dev)
+{
+	int retval = 1;
+	u32 request_id, doorbell;
+
+	/* Read doorbell status */
+	doorbell = readl(TWL_HOBDB_REG_ADDR(tw_dev));
+
+	/* Check for controller errors */
+	if (doorbell & TWL_DOORBELL_CONTROLLER_ERROR) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xd, "Microcontroller Error: clearing");
+		goto out;
+	}
+
+	/* Check if we need to perform an AEN drain */
+	if (doorbell & TWL_DOORBELL_ATTENTION_INTERRUPT) {
+		if (!(test_and_set_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags))) {
+			twl_get_request_id(tw_dev, &request_id);
+			if (twl_aen_read_queue(tw_dev, request_id)) {
+				tw_dev->state[request_id] = TW_S_COMPLETED;
+				twl_free_request_id(tw_dev, request_id);
+				clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
+			}
+		}
+	}
+
+	retval = 0;
+out:
+	/* Clear doorbell interrupt */
+	TWL_CLEAR_DB_INTERRUPT(tw_dev);
+
+	/* Make sure the clear was flushed by reading it back */
+	readl(TWL_HOBDBC_REG_ADDR(tw_dev));
+
+	return retval;
+} /* End twl_handle_attention_interrupt() */
+
+/* Interrupt service routine */
+static irqreturn_t twl_interrupt(int irq, void *dev_instance)
+{
+	TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
+	int i, handled = 0, error = 0;
+	dma_addr_t mfa = 0;
+	u32 reg, regl, regh, response, request_id = 0;
+	struct scsi_cmnd *cmd;
+	TW_Command_Full *full_command_packet;
+
+	spin_lock(tw_dev->host->host_lock);
+
+	/* Read host interrupt status */
+	reg = readl(TWL_HISTAT_REG_ADDR(tw_dev));
+
+	/* Check if this is our interrupt, otherwise bail */
+	if (!(reg & TWL_HISTATUS_VALID_INTERRUPT))
+		goto twl_interrupt_bail;
+
+	handled = 1;
+
+	/* If we are resetting, bail */
+	if (test_bit(TW_IN_RESET, &tw_dev->flags))
+		goto twl_interrupt_bail;
+
+	/* Attention interrupt */
+	if (reg & TWL_HISTATUS_ATTENTION_INTERRUPT) {
+		if (twl_handle_attention_interrupt(tw_dev)) {
+			TWL_MASK_INTERRUPTS(tw_dev);
+			goto twl_interrupt_bail;
+		}
+	}
+
+	/* Response interrupt */
+	while (reg & TWL_HISTATUS_RESPONSE_INTERRUPT) {
+		if (sizeof(dma_addr_t) > 4) {
+			regh = readl(TWL_HOBQPH_REG_ADDR(tw_dev));
+			regl = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
+			mfa = ((u64)regh << 32) | regl;
+		} else
+			mfa = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
+
+		error = 0;
+		response = (u32)mfa;
+
+		/* Check for command packet error */
+		if (!TW_NOTMFA_OUT(response)) {
+			for (i=0;i<TW_Q_LENGTH;i++) {
+				if (tw_dev->sense_buffer_phys[i] == mfa) {
+					request_id = le16_to_cpu(tw_dev->sense_buffer_virt[i]->header_desc.request_id);
+					if (tw_dev->srb[request_id] != NULL)
+						error = twl_fill_sense(tw_dev, i, request_id, 1, 1);
+					else {
+						/* Skip ioctl error prints */
+						if (request_id != tw_dev->chrdev_request_id)
+							error = twl_fill_sense(tw_dev, i, request_id, 0, 1);
+						else
+							memcpy(tw_dev->command_packet_virt[request_id], tw_dev->sense_buffer_virt[i], sizeof(TW_Command_Apache_Header));
+					}
+
+					/* Now re-post the sense buffer */
+					writel((u32)((u64)tw_dev->sense_buffer_phys[i] >> 32), TWL_HOBQPH_REG_ADDR(tw_dev));
+					writel((u32)tw_dev->sense_buffer_phys[i], TWL_HOBQPL_REG_ADDR(tw_dev));
+					break;
+				}
+			}
+		} else
+			request_id = TW_RESID_OUT(response);
+
+		full_command_packet = tw_dev->command_packet_virt[request_id];
+
+		/* Check for correct state */
+		if (tw_dev->state[request_id] != TW_S_POSTED) {
+			if (tw_dev->srb[request_id] != NULL) {
+				TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Received a request id that wasn't posted");
+				TWL_MASK_INTERRUPTS(tw_dev);
+				goto twl_interrupt_bail;
+			}
+		}
+
+		/* Check for internal command completion */
+		if (tw_dev->srb[request_id] == NULL) {
+			if (request_id != tw_dev->chrdev_request_id) {
+				if (twl_aen_complete(tw_dev, request_id))
+					TW_PRINTK(tw_dev->host, TW_DRIVER, 0xf, "Error completing AEN during attention interrupt");
+			} else {
+				tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
+				wake_up(&tw_dev->ioctl_wqueue);
+			}
+		} else {
+			cmd = tw_dev->srb[request_id];
+
+			if (!error)
+				cmd->result = (DID_OK << 16);
+			
+			/* Report residual bytes for single sgl */
+			if ((scsi_sg_count(cmd) <= 1) && (full_command_packet->command.newcommand.status == 0)) {
+				if (full_command_packet->command.newcommand.sg_list[0].length < scsi_bufflen(tw_dev->srb[request_id]))
+					scsi_set_resid(cmd, scsi_bufflen(cmd) - full_command_packet->command.newcommand.sg_list[0].length);
+			}
+
+			/* Now complete the io */
+			tw_dev->state[request_id] = TW_S_COMPLETED;
+			twl_free_request_id(tw_dev, request_id);
+			tw_dev->posted_request_count--;
+			tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
+			twl_unmap_scsi_data(tw_dev, request_id);
+		}
+
+		/* Check for another response interrupt */
+		reg = readl(TWL_HISTAT_REG_ADDR(tw_dev));
+	}
+
+twl_interrupt_bail:
+	spin_unlock(tw_dev->host->host_lock);
+	return IRQ_RETVAL(handled);
+} /* End twl_interrupt() */
+
+/* This function will poll for a register change */
+static int twl_poll_register(TW_Device_Extension *tw_dev, void *reg, u32 value, u32 result, int seconds)
+{
+	unsigned long before;
+	int retval = 1;
+	u32 reg_value;
+
+	reg_value = readl(reg);
+	before = jiffies;
+
+        while ((reg_value & value) != result) {
+		reg_value = readl(reg);
+		if (time_after(jiffies, before + HZ * seconds))
+			goto out;
+		msleep(50);
+	}
+	retval = 0;
+out:
+	return retval;
+} /* End twl_poll_register() */
+
+/* This function will reset a controller */
+static int twl_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset)
+{
+	int retval = 1;
+	int i = 0;
+	u32 status = 0;
+	unsigned short fw_on_ctlr_srl = 0, fw_on_ctlr_arch_id = 0;
+	unsigned short fw_on_ctlr_branch = 0, fw_on_ctlr_build = 0;
+	u32 init_connect_result = 0;
+	int tries = 0;
+	int do_soft_reset = soft_reset;
+
+	while (tries < TW_MAX_RESET_TRIES) {
+		/* Do a soft reset if one is needed */
+		if (do_soft_reset) {
+			TWL_SOFT_RESET(tw_dev);
+
+			/* Make sure controller is in a good state */
+			if (twl_poll_register(tw_dev, TWL_SCRPD3_REG_ADDR(tw_dev), TWL_CONTROLLER_READY, 0x0, 30)) {
+				TW_PRINTK(tw_dev->host, TW_DRIVER, 0x10, "Controller never went non-ready during reset sequence");
+				tries++;
+				continue;
+			}
+			if (twl_poll_register(tw_dev, TWL_SCRPD3_REG_ADDR(tw_dev), TWL_CONTROLLER_READY, TWL_CONTROLLER_READY, 60)) {
+				TW_PRINTK(tw_dev->host, TW_DRIVER, 0x11, "Controller not ready during reset sequence");
+				tries++;
+				continue;
+			}
+		}
+
+		/* Initconnect */
+		if (twl_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS,
+				       TW_EXTENDED_INIT_CONNECT, TW_CURRENT_DRIVER_SRL,
+				       TW_9750_ARCH_ID, TW_CURRENT_DRIVER_BRANCH,
+				       TW_CURRENT_DRIVER_BUILD, &fw_on_ctlr_srl,
+				       &fw_on_ctlr_arch_id, &fw_on_ctlr_branch,
+				       &fw_on_ctlr_build, &init_connect_result)) {
+			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x12, "Initconnection failed while checking SRL");
+			do_soft_reset = 1;
+			tries++;
+			continue;
+		}
+
+		/* Load sense buffers */
+		while (i < TW_Q_LENGTH) {
+			writel((u32)((u64)tw_dev->sense_buffer_phys[i] >> 32), TWL_HOBQPH_REG_ADDR(tw_dev));
+			writel((u32)tw_dev->sense_buffer_phys[i], TWL_HOBQPL_REG_ADDR(tw_dev));
+
+			/* Check status for over-run after each write */
+			status = readl(TWL_STATUS_REG_ADDR(tw_dev));
+			if (!(status & TWL_STATUS_OVERRUN_SUBMIT))
+			    i++;
+		}
+
+		/* Now check status */
+		status = readl(TWL_STATUS_REG_ADDR(tw_dev));
+		if (status) {
+			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x13, "Bad controller status after loading sense buffers");
+			do_soft_reset = 1;
+			tries++;
+			continue;
+		}
+
+		/* Drain the AEN queue */
+		if (twl_aen_drain_queue(tw_dev, soft_reset)) {
+			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x14, "AEN drain failed during reset sequence");
+			do_soft_reset = 1;
+			tries++;
+			continue;
+		}
+
+		/* Load rest of compatibility struct */
+		strncpy(tw_dev->tw_compat_info.driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION));
+		tw_dev->tw_compat_info.driver_srl_high = TW_CURRENT_DRIVER_SRL;
+		tw_dev->tw_compat_info.driver_branch_high = TW_CURRENT_DRIVER_BRANCH;
+		tw_dev->tw_compat_info.driver_build_high = TW_CURRENT_DRIVER_BUILD;
+		tw_dev->tw_compat_info.driver_srl_low = TW_BASE_FW_SRL;
+		tw_dev->tw_compat_info.driver_branch_low = TW_BASE_FW_BRANCH;
+		tw_dev->tw_compat_info.driver_build_low = TW_BASE_FW_BUILD;
+		tw_dev->tw_compat_info.fw_on_ctlr_srl = fw_on_ctlr_srl;
+		tw_dev->tw_compat_info.fw_on_ctlr_branch = fw_on_ctlr_branch;
+		tw_dev->tw_compat_info.fw_on_ctlr_build = fw_on_ctlr_build;
+
+		/* If we got here, controller is in a good state */
+		retval = 0;
+		goto out;
+	}
+out:
+	return retval;
+} /* End twl_reset_sequence() */
+
+/* This function will reset a device extension */
+static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset)
+{
+	int i = 0, retval = 1;
+	unsigned long flags = 0;
+
+	/* Block SCSI requests while we are resetting */
+	if (ioctl_reset)
+		scsi_block_requests(tw_dev->host);
+
+	set_bit(TW_IN_RESET, &tw_dev->flags);
+	TWL_MASK_INTERRUPTS(tw_dev);
+	TWL_CLEAR_DB_INTERRUPT(tw_dev);
+
+	spin_lock_irqsave(tw_dev->host->host_lock, flags);
+
+	/* Abort all requests that are in progress */
+	for (i = 0; i < TW_Q_LENGTH; i++) {
+		if ((tw_dev->state[i] != TW_S_FINISHED) &&
+		    (tw_dev->state[i] != TW_S_INITIAL) &&
+		    (tw_dev->state[i] != TW_S_COMPLETED)) {
+			if (tw_dev->srb[i]) {
+				tw_dev->srb[i]->result = (DID_RESET << 16);
+				tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
+				twl_unmap_scsi_data(tw_dev, i);
+			}
+		}
+	}
+
+	/* Reset queues and counts */
+	for (i = 0; i < TW_Q_LENGTH; i++) {
+		tw_dev->free_queue[i] = i;
+		tw_dev->state[i] = TW_S_INITIAL;
+	}
+	tw_dev->free_head = TW_Q_START;
+	tw_dev->free_tail = TW_Q_START;
+	tw_dev->posted_request_count = 0;
+
+	spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
+
+	if (twl_reset_sequence(tw_dev, 1))
+		goto out;
+
+	TWL_UNMASK_INTERRUPTS(tw_dev);
+
+	clear_bit(TW_IN_RESET, &tw_dev->flags);
+	tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
+
+	retval = 0;
+out:
+	if (ioctl_reset)
+		scsi_unblock_requests(tw_dev->host);
+	return retval;
+} /* End twl_reset_device_extension() */
+
+/* This funciton returns unit geometry in cylinders/heads/sectors */
+static int twl_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[])
+{
+	int heads, sectors;
+	TW_Device_Extension *tw_dev;
+
+	tw_dev = (TW_Device_Extension *)sdev->host->hostdata;
+
+	if (capacity >= 0x200000) {
+		heads = 255;
+		sectors = 63;
+	} else {
+		heads = 64;
+		sectors = 32;
+	}
+
+	geom[0] = heads;
+	geom[1] = sectors;
+	geom[2] = sector_div(capacity, heads * sectors); /* cylinders */
+
+	return 0;
+} /* End twl_scsi_biosparam() */
+
+/* This is the new scsi eh reset function */
+static int twl_scsi_eh_reset(struct scsi_cmnd *SCpnt)
+{
+	TW_Device_Extension *tw_dev = NULL;
+	int retval = FAILED;
+
+	tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
+
+	tw_dev->num_resets++;
+
+	sdev_printk(KERN_WARNING, SCpnt->device,
+		"WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n",
+		TW_DRIVER, 0x2c, SCpnt->cmnd[0]);
+
+	/* Make sure we are not issuing an ioctl or resetting from ioctl */
+	mutex_lock(&tw_dev->ioctl_lock);
+
+	/* Now reset the card and some of the device extension data */
+	if (twl_reset_device_extension(tw_dev, 0)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x15, "Controller reset failed during scsi host reset");
+		goto out;
+	}
+
+	retval = SUCCESS;
+out:
+	mutex_unlock(&tw_dev->ioctl_lock);
+	return retval;
+} /* End twl_scsi_eh_reset() */
+
+/* This is the main scsi queue function to handle scsi opcodes */
+static int twl_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+{
+	int request_id, retval;
+	TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
+
+	/* If we are resetting due to timed out ioctl, report as busy */
+	if (test_bit(TW_IN_RESET, &tw_dev->flags)) {
+		retval = SCSI_MLQUEUE_HOST_BUSY;
+		goto out;
+	}
+
+	/* Save done function into scsi_cmnd struct */
+	SCpnt->scsi_done = done;
+		
+	/* Get a free request id */
+	twl_get_request_id(tw_dev, &request_id);
+
+	/* Save the scsi command for use by the ISR */
+	tw_dev->srb[request_id] = SCpnt;
+
+	/* Initialize phase to zero */
+	SCpnt->SCp.phase = TW_PHASE_INITIAL;
+
+	retval = twl_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL);
+	if (retval) {
+		tw_dev->state[request_id] = TW_S_COMPLETED;
+		twl_free_request_id(tw_dev, request_id);
+		SCpnt->result = (DID_ERROR << 16);
+		done(SCpnt);
+		retval = 0;
+	}
+out:
+	return retval;
+} /* End twl_scsi_queue() */
+
+/* This function tells the controller to shut down */
+static void __twl_shutdown(TW_Device_Extension *tw_dev)
+{
+	/* Disable interrupts */
+	TWL_MASK_INTERRUPTS(tw_dev);
+
+	/* Free up the IRQ */
+	free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
+
+	printk(KERN_WARNING "3w-sas: Shutting down host %d.\n", tw_dev->host->host_no);
+
+	/* Tell the card we are shutting down */
+	if (twl_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x16, "Connection shutdown failed");
+	} else {
+		printk(KERN_WARNING "3w-sas: Shutdown complete.\n");
+	}
+
+	/* Clear doorbell interrupt just before exit */
+	TWL_CLEAR_DB_INTERRUPT(tw_dev);
+} /* End __twl_shutdown() */
+
+/* Wrapper for __twl_shutdown */
+static void twl_shutdown(struct pci_dev *pdev)
+{
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
+	TW_Device_Extension *tw_dev;
+
+	if (!host)
+		return;
+
+	tw_dev = (TW_Device_Extension *)host->hostdata;
+
+	if (tw_dev->online) 
+		__twl_shutdown(tw_dev);
+} /* End twl_shutdown() */
+
+/* This function configures unit settings when a unit is coming on-line */
+static int twl_slave_configure(struct scsi_device *sdev)
+{
+	/* Force 60 second timeout */
+	blk_queue_rq_timeout(sdev->request_queue, 60 * HZ);
+
+	return 0;
+} /* End twl_slave_configure() */
+
+/* scsi_host_template initializer */
+static struct scsi_host_template driver_template = {
+	.module			= THIS_MODULE,
+	.name			= "3w-sas",
+	.queuecommand		= twl_scsi_queue,
+	.eh_host_reset_handler	= twl_scsi_eh_reset,
+	.bios_param		= twl_scsi_biosparam,
+	.change_queue_depth	= twl_change_queue_depth,
+	.can_queue		= TW_Q_LENGTH-2,
+	.slave_configure	= twl_slave_configure,
+	.this_id		= -1,
+	.sg_tablesize		= TW_LIBERATOR_MAX_SGL_LENGTH,
+	.max_sectors		= TW_MAX_SECTORS,
+	.cmd_per_lun		= TW_MAX_CMDS_PER_LUN,
+	.use_clustering		= ENABLE_CLUSTERING,
+	.shost_attrs		= twl_host_attrs,
+	.emulated		= 1
+};
+
+/* This function will probe and initialize a card */
+static int __devinit twl_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
+{
+	struct Scsi_Host *host = NULL;
+	TW_Device_Extension *tw_dev;
+	int retval = -ENODEV;
+	int *ptr_phycount, phycount=0;
+
+	retval = pci_enable_device(pdev);
+	if (retval) {
+		TW_PRINTK(host, TW_DRIVER, 0x17, "Failed to enable pci device");
+		goto out_disable_device;
+	}
+
+	pci_set_master(pdev);
+	pci_try_set_mwi(pdev);
+
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
+	    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
+		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
+		    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
+			TW_PRINTK(host, TW_DRIVER, 0x18, "Failed to set dma mask");
+			retval = -ENODEV;
+			goto out_disable_device;
+		}
+
+	host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
+	if (!host) {
+		TW_PRINTK(host, TW_DRIVER, 0x19, "Failed to allocate memory for device extension");
+		retval = -ENOMEM;
+		goto out_disable_device;
+	}
+	tw_dev = shost_priv(host);
+
+	/* Save values to device extension */
+	tw_dev->host = host;
+	tw_dev->tw_pci_dev = pdev;
+
+	if (twl_initialize_device_extension(tw_dev)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Failed to initialize device extension");
+		goto out_free_device_extension;
+	}
+
+	/* Request IO regions */
+	retval = pci_request_regions(pdev, "3w-sas");
+	if (retval) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1b, "Failed to get mem region");
+		goto out_free_device_extension;
+	}
+
+	/* Save base address, use region 1 */
+	tw_dev->base_addr = pci_iomap(pdev, 1, 0);
+	if (!tw_dev->base_addr) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to ioremap");
+		goto out_release_mem_region;
+	}
+
+	/* Disable interrupts on the card */
+	TWL_MASK_INTERRUPTS(tw_dev);
+
+	/* Initialize the card */
+	if (twl_reset_sequence(tw_dev, 0)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1d, "Controller reset failed during probe");
+		goto out_iounmap;
+	}
+
+	/* Set host specific parameters */
+	host->max_id = TW_MAX_UNITS;
+	host->max_cmd_len = TW_MAX_CDB_LEN;
+	host->max_lun = TW_MAX_LUNS;
+	host->max_channel = 0;
+
+	/* Register the card with the kernel SCSI layer */
+	retval = scsi_add_host(host, &pdev->dev);
+	if (retval) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1e, "scsi add host failed");
+		goto out_iounmap;
+	}
+
+	pci_set_drvdata(pdev, host);
+
+	printk(KERN_WARNING "3w-sas: scsi%d: Found an LSI 3ware %s Controller at 0x%llx, IRQ: %d.\n",
+	       host->host_no,
+	       (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
+				     TW_PARAM_MODEL, TW_PARAM_MODEL_LENGTH),
+	       (u64)pci_resource_start(pdev, 1), pdev->irq);
+
+	ptr_phycount = twl_get_param(tw_dev, 2, TW_PARAM_PHY_SUMMARY_TABLE,
+				     TW_PARAM_PHYCOUNT, TW_PARAM_PHYCOUNT_LENGTH);
+	if (ptr_phycount)
+		phycount = le32_to_cpu(*(int *)ptr_phycount);
+
+	printk(KERN_WARNING "3w-sas: scsi%d: Firmware %s, BIOS %s, Phys: %d.\n",
+	       host->host_no,
+	       (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
+				     TW_PARAM_FWVER, TW_PARAM_FWVER_LENGTH),
+	       (char *)twl_get_param(tw_dev, 2, TW_VERSION_TABLE,
+				     TW_PARAM_BIOSVER, TW_PARAM_BIOSVER_LENGTH),
+	       phycount);
+
+	/* Try to enable MSI */
+	if (use_msi && !pci_enable_msi(pdev))
+		set_bit(TW_USING_MSI, &tw_dev->flags);
+
+	/* Now setup the interrupt handler */
+	retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
+	if (retval) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1f, "Error requesting IRQ");
+		goto out_remove_host;
+	}
+
+	twl_device_extension_list[twl_device_extension_count] = tw_dev;
+	twl_device_extension_count++;
+
+	/* Re-enable interrupts on the card */
+	TWL_UNMASK_INTERRUPTS(tw_dev);
+	
+	/* Finally, scan the host */
+	scsi_scan_host(host);
+
+	/* Add sysfs binary files */
+	if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr))
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x20, "Failed to create sysfs binary file: 3ware_aen_read");
+	if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr))
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x21, "Failed to create sysfs binary file: 3ware_compat_info");
+
+	if (twl_major == -1) {
+		if ((twl_major = register_chrdev (0, "twl", &twl_fops)) < 0)
+			TW_PRINTK(host, TW_DRIVER, 0x22, "Failed to register character device");
+	}
+	tw_dev->online = 1;
+	return 0;
+
+out_remove_host:
+	if (test_bit(TW_USING_MSI, &tw_dev->flags))
+		pci_disable_msi(pdev);
+	scsi_remove_host(host);
+out_iounmap:
+	iounmap(tw_dev->base_addr);
+out_release_mem_region:
+	pci_release_regions(pdev);
+out_free_device_extension:
+	twl_free_device_extension(tw_dev);
+	scsi_host_put(host);
+out_disable_device:
+	pci_disable_device(pdev);
+
+	return retval;
+} /* End twl_probe() */
+
+/* This function is called to remove a device */
+static void twl_remove(struct pci_dev *pdev)
+{
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
+	TW_Device_Extension *tw_dev;
+
+	if (!host)
+		return;
+
+	tw_dev = (TW_Device_Extension *)host->hostdata;
+
+	if (!tw_dev->online)
+		return;
+
+	/* Remove sysfs binary files */
+	sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr);
+	sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr);
+
+	scsi_remove_host(tw_dev->host);
+
+	/* Unregister character device */
+	if (twl_major >= 0) {
+		unregister_chrdev(twl_major, "twl");
+		twl_major = -1;
+	}
+
+	/* Shutdown the card */
+	__twl_shutdown(tw_dev);
+
+	/* Disable MSI if enabled */
+	if (test_bit(TW_USING_MSI, &tw_dev->flags))
+		pci_disable_msi(pdev);
+
+	/* Free IO remapping */
+	iounmap(tw_dev->base_addr);
+
+	/* Free up the mem region */
+	pci_release_regions(pdev);
+
+	/* Free up device extension resources */
+	twl_free_device_extension(tw_dev);
+
+	scsi_host_put(tw_dev->host);
+	pci_disable_device(pdev);
+	twl_device_extension_count--;
+} /* End twl_remove() */
+
+#ifdef CONFIG_PM
+/* This function is called on PCI suspend */
+static int twl_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
+	TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
+
+	printk(KERN_WARNING "3w-sas: Suspending host %d.\n", tw_dev->host->host_no);
+	/* Disable interrupts */
+	TWL_MASK_INTERRUPTS(tw_dev);
+
+	free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
+
+	/* Tell the card we are shutting down */
+	if (twl_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x23, "Connection shutdown failed during suspend");
+	} else {
+		printk(KERN_WARNING "3w-sas: Suspend complete.\n");
+	}
+
+	/* Clear doorbell interrupt */
+	TWL_CLEAR_DB_INTERRUPT(tw_dev);
+
+	pci_save_state(pdev);
+	pci_disable_device(pdev);
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+	return 0;
+} /* End twl_suspend() */
+
+/* This function is called on PCI resume */
+static int twl_resume(struct pci_dev *pdev)
+{
+	int retval = 0;
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
+	TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
+
+	printk(KERN_WARNING "3w-sas: Resuming host %d.\n", tw_dev->host->host_no);
+	pci_set_power_state(pdev, PCI_D0);
+	pci_enable_wake(pdev, PCI_D0, 0);
+	pci_restore_state(pdev);
+
+	retval = pci_enable_device(pdev);
+	if (retval) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x24, "Enable device failed during resume");
+		return retval;
+	}
+
+	pci_set_master(pdev);
+	pci_try_set_mwi(pdev);
+
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
+	    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
+		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
+		    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
+			TW_PRINTK(host, TW_DRIVER, 0x25, "Failed to set dma mask during resume");
+			retval = -ENODEV;
+			goto out_disable_device;
+		}
+
+	/* Initialize the card */
+	if (twl_reset_sequence(tw_dev, 0)) {
+		retval = -ENODEV;
+		goto out_disable_device;
+	}
+
+	/* Now setup the interrupt handler */
+	retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
+	if (retval) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x26, "Error requesting IRQ during resume");
+		retval = -ENODEV;
+		goto out_disable_device;
+	}
+
+	/* Now enable MSI if enabled */
+	if (test_bit(TW_USING_MSI, &tw_dev->flags))
+		pci_enable_msi(pdev);
+
+	/* Re-enable interrupts on the card */
+	TWL_UNMASK_INTERRUPTS(tw_dev);
+
+	printk(KERN_WARNING "3w-sas: Resume complete.\n");
+	return 0;
+
+out_disable_device:
+	scsi_remove_host(host);
+	pci_disable_device(pdev);
+
+	return retval;
+} /* End twl_resume() */
+#endif
+
+/* PCI Devices supported by this driver */
+static struct pci_device_id twl_pci_tbl[] __devinitdata = {
+	{ PCI_VDEVICE(3WARE, PCI_DEVICE_ID_3WARE_9750) },
+	{ }
+};
+MODULE_DEVICE_TABLE(pci, twl_pci_tbl);
+
+/* pci_driver initializer */
+static struct pci_driver twl_driver = {
+	.name		= "3w-sas",
+	.id_table	= twl_pci_tbl,
+	.probe		= twl_probe,
+	.remove		= twl_remove,
+#ifdef CONFIG_PM
+	.suspend	= twl_suspend,
+	.resume		= twl_resume,
+#endif
+	.shutdown	= twl_shutdown
+};
+
+/* This function is called on driver initialization */
+static int __init twl_init(void)
+{
+	printk(KERN_INFO "LSI 3ware SAS/SATA-RAID Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
+
+	return pci_register_driver(&twl_driver);
+} /* End twl_init() */
+
+/* This function is called on driver exit */
+static void __exit twl_exit(void)
+{
+	pci_unregister_driver(&twl_driver);
+} /* End twl_exit() */
+
+module_init(twl_init);
+module_exit(twl_exit);
+
diff --git a/drivers/scsi/3w-sas.h b/drivers/scsi/3w-sas.h
new file mode 100644
index 0000000..d474892
--- /dev/null
+++ b/drivers/scsi/3w-sas.h
@@ -0,0 +1,396 @@
+/*
+   3w-sas.h -- LSI 3ware SAS/SATA-RAID Controller device driver for Linux.
+
+   Written By: Adam Radford <linuxraid@lsi.com>
+
+   Copyright (C) 2009 LSI 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 of the License.
+
+   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.
+
+   NO WARRANTY
+   THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+   CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+   LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+   solely responsible for determining the appropriateness of using and
+   distributing the Program and assumes all risks associated with its
+   exercise of rights under this Agreement, including but not limited to
+   the risks and costs of program errors, damage to or loss of data,
+   programs or equipment, and unavailability or interruption of operations.
+
+   DISCLAIMER OF LIABILITY
+   NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+   DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
+   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+   TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+   USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+   HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+
+   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
+
+   Bugs/Comments/Suggestions should be mailed to:
+   linuxraid@lsi.com
+
+   For more information, goto:
+   http://www.lsi.com
+*/
+
+#ifndef _3W_SAS_H
+#define _3W_SAS_H
+
+/* AEN severity table */
+static char *twl_aen_severity_table[] =
+{
+	"None", "ERROR", "WARNING", "INFO", "DEBUG", NULL
+};
+
+/* Liberator register offsets */
+#define TWL_STATUS                         0x0  /* Status */
+#define TWL_HIBDB                          0x20 /* Inbound doorbell */
+#define TWL_HISTAT                         0x30 /* Host interrupt status */
+#define TWL_HIMASK                         0x34 /* Host interrupt mask */
+#define TWL_HOBDB			   0x9C /* Outbound doorbell */
+#define TWL_HOBDBC                         0xA0 /* Outbound doorbell clear */
+#define TWL_SCRPD3                         0xBC /* Scratchpad */
+#define TWL_HIBQPL                         0xC0 /* Host inbound Q low */
+#define TWL_HIBQPH                         0xC4 /* Host inbound Q high */
+#define TWL_HOBQPL                         0xC8 /* Host outbound Q low */
+#define TWL_HOBQPH                         0xCC /* Host outbound Q high */
+#define TWL_HISTATUS_VALID_INTERRUPT	   0xC
+#define TWL_HISTATUS_ATTENTION_INTERRUPT   0x4
+#define TWL_HISTATUS_RESPONSE_INTERRUPT	   0x8
+#define TWL_STATUS_OVERRUN_SUBMIT	   0x2000
+#define TWL_ISSUE_SOFT_RESET		   0x100
+#define TWL_CONTROLLER_READY		   0x2000
+#define TWL_DOORBELL_CONTROLLER_ERROR	   0x200000
+#define TWL_DOORBELL_ATTENTION_INTERRUPT   0x40000
+#define TWL_PULL_MODE			   0x1
+
+/* Command packet opcodes used by the driver */
+#define TW_OP_INIT_CONNECTION 0x1
+#define TW_OP_GET_PARAM	      0x12
+#define TW_OP_SET_PARAM	      0x13
+#define TW_OP_EXECUTE_SCSI    0x10
+
+/* Asynchronous Event Notification (AEN) codes used by the driver */
+#define TW_AEN_QUEUE_EMPTY       0x0000
+#define TW_AEN_SOFT_RESET        0x0001
+#define TW_AEN_SYNC_TIME_WITH_HOST 0x031
+#define TW_AEN_SEVERITY_ERROR    0x1
+#define TW_AEN_SEVERITY_DEBUG    0x4
+#define TW_AEN_NOT_RETRIEVED 0x1
+
+/* Command state defines */
+#define TW_S_INITIAL   0x1  /* Initial state */
+#define TW_S_STARTED   0x2  /* Id in use */
+#define TW_S_POSTED    0x4  /* Posted to the controller */
+#define TW_S_COMPLETED 0x8  /* Completed by isr */
+#define TW_S_FINISHED  0x10 /* I/O completely done */
+
+/* Compatibility defines */
+#define TW_9750_ARCH_ID 10
+#define TW_CURRENT_DRIVER_SRL 40
+#define TW_CURRENT_DRIVER_BUILD 0
+#define TW_CURRENT_DRIVER_BRANCH 0
+
+/* Phase defines */
+#define TW_PHASE_INITIAL 0
+#define TW_PHASE_SGLIST  2
+
+/* Misc defines */
+#define TW_SECTOR_SIZE                        512
+#define TW_MAX_UNITS			      32
+#define TW_INIT_MESSAGE_CREDITS		      0x100
+#define TW_INIT_COMMAND_PACKET_SIZE	      0x3
+#define TW_INIT_COMMAND_PACKET_SIZE_EXTENDED  0x6
+#define TW_EXTENDED_INIT_CONNECT	      0x2
+#define TW_BASE_FW_SRL			      24
+#define TW_BASE_FW_BRANCH		      0
+#define TW_BASE_FW_BUILD		      1
+#define TW_Q_LENGTH			      256
+#define TW_Q_START			      0
+#define TW_MAX_SLOT			      32
+#define TW_MAX_RESET_TRIES		      2
+#define TW_MAX_CMDS_PER_LUN		      254
+#define TW_MAX_AEN_DRAIN		      255
+#define TW_IN_RESET                           2
+#define TW_USING_MSI			      3
+#define TW_IN_ATTENTION_LOOP		      4
+#define TW_MAX_SECTORS                        256
+#define TW_MAX_CDB_LEN                        16
+#define TW_IOCTL_CHRDEV_TIMEOUT               60 /* 60 seconds */
+#define TW_IOCTL_CHRDEV_FREE                  -1
+#define TW_COMMAND_OFFSET                     128 /* 128 bytes */
+#define TW_VERSION_TABLE                      0x0402
+#define TW_TIMEKEEP_TABLE		      0x040A
+#define TW_INFORMATION_TABLE		      0x0403
+#define TW_PARAM_FWVER			      3
+#define TW_PARAM_FWVER_LENGTH		      16
+#define TW_PARAM_BIOSVER		      4
+#define TW_PARAM_BIOSVER_LENGTH		      16
+#define TW_PARAM_MODEL			      8
+#define TW_PARAM_MODEL_LENGTH		      16
+#define TW_PARAM_PHY_SUMMARY_TABLE	      1
+#define TW_PARAM_PHYCOUNT		      2
+#define TW_PARAM_PHYCOUNT_LENGTH	      1
+#define TW_IOCTL_FIRMWARE_PASS_THROUGH        0x108  // Used by smartmontools
+#define TW_ALLOCATION_LENGTH		      128
+#define TW_SENSE_DATA_LENGTH		      18
+#define TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED   0x10a
+#define TW_ERROR_INVALID_FIELD_IN_CDB	      0x10d
+#define TW_ERROR_UNIT_OFFLINE                 0x128
+#define TW_MESSAGE_SOURCE_CONTROLLER_ERROR    3
+#define TW_MESSAGE_SOURCE_CONTROLLER_EVENT    4
+#define TW_DRIVER 			      6
+#ifndef PCI_DEVICE_ID_3WARE_9750
+#define PCI_DEVICE_ID_3WARE_9750 0x1010
+#endif
+
+/* Bitmask macros to eliminate bitfields */
+
+/* opcode: 5, reserved: 3 */
+#define TW_OPRES_IN(x,y) ((x << 5) | (y & 0x1f))
+#define TW_OP_OUT(x) (x & 0x1f)
+
+/* opcode: 5, sgloffset: 3 */
+#define TW_OPSGL_IN(x,y) ((x << 5) | (y & 0x1f))
+#define TW_SGL_OUT(x) ((x >> 5) & 0x7)
+
+/* severity: 3, reserved: 5 */
+#define TW_SEV_OUT(x) (x & 0x7)
+
+/* not_mfa: 1, reserved: 7, status: 8, request_id: 16 */
+#define TW_RESID_OUT(x) ((x >> 16) & 0xffff)
+#define TW_NOTMFA_OUT(x) (x & 0x1)
+
+/* request_id: 12, lun: 4 */
+#define TW_REQ_LUN_IN(lun, request_id) (((lun << 12) & 0xf000) | (request_id & 0xfff))
+#define TW_LUN_OUT(lun) ((lun >> 12) & 0xf)
+
+/* Register access macros */
+#define TWL_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_STATUS)
+#define TWL_HOBQPL_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBQPL)
+#define TWL_HOBQPH_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBQPH)
+#define TWL_HOBDB_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBDB)
+#define TWL_HOBDBC_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBDBC)
+#define TWL_HIMASK_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIMASK)
+#define TWL_HISTAT_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HISTAT)
+#define TWL_HIBQPH_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBQPH)
+#define TWL_HIBQPL_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBQPL)
+#define TWL_HIBDB_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBDB)
+#define TWL_SCRPD3_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_SCRPD3)
+#define TWL_MASK_INTERRUPTS(x) (writel(~0, TWL_HIMASK_REG_ADDR(tw_dev)))
+#define TWL_UNMASK_INTERRUPTS(x) (writel(~TWL_HISTATUS_VALID_INTERRUPT, TWL_HIMASK_REG_ADDR(tw_dev)))
+#define TWL_CLEAR_DB_INTERRUPT(x) (writel(~0, TWL_HOBDBC_REG_ADDR(tw_dev)))
+#define TWL_SOFT_RESET(x) (writel(TWL_ISSUE_SOFT_RESET, TWL_HIBDB_REG_ADDR(tw_dev)))
+
+/* Macros */
+#define TW_PRINTK(h,a,b,c) { \
+if (h) \
+printk(KERN_WARNING "3w-sas: scsi%d: ERROR: (0x%02X:0x%04X): %s.\n",h->host_no,a,b,c); \
+else \
+printk(KERN_WARNING "3w-sas: ERROR: (0x%02X:0x%04X): %s.\n",a,b,c); \
+}
+#define TW_MAX_LUNS 16
+#define TW_COMMAND_SIZE (sizeof(dma_addr_t) > 4 ? 6 : 4)
+#define TW_LIBERATOR_MAX_SGL_LENGTH (sizeof(dma_addr_t) > 4 ? 46 : 92)
+#define TW_LIBERATOR_MAX_SGL_LENGTH_OLD (sizeof(dma_addr_t) > 4 ? 47 : 94)
+#define TW_PADDING_LENGTH_LIBERATOR 136
+#define TW_PADDING_LENGTH_LIBERATOR_OLD 132
+#define TW_CPU_TO_SGL(x) (sizeof(dma_addr_t) > 4 ? cpu_to_le64(x) : cpu_to_le32(x))
+
+#pragma pack(1)
+
+/* SGL entry */
+typedef struct TAG_TW_SG_Entry_ISO {
+	dma_addr_t address;
+	dma_addr_t length;
+} TW_SG_Entry_ISO;
+
+/* Old Command Packet with ISO SGL */
+typedef struct TW_Command {
+	unsigned char opcode__sgloffset;
+	unsigned char size;
+	unsigned char request_id;
+	unsigned char unit__hostid;
+	/* Second DWORD */
+	unsigned char status;
+	unsigned char flags;
+	union {
+		unsigned short block_count;
+		unsigned short parameter_count;
+	} byte6_offset;
+	union {
+		struct {
+			u32 lba;
+			TW_SG_Entry_ISO sgl[TW_LIBERATOR_MAX_SGL_LENGTH_OLD];
+			unsigned char padding[TW_PADDING_LENGTH_LIBERATOR_OLD];
+		} io;
+		struct {
+			TW_SG_Entry_ISO sgl[TW_LIBERATOR_MAX_SGL_LENGTH_OLD];
+			u32 padding;
+			unsigned char padding2[TW_PADDING_LENGTH_LIBERATOR_OLD];
+		} param;
+	} byte8_offset;
+} TW_Command;
+
+/* New Command Packet with ISO SGL */
+typedef struct TAG_TW_Command_Apache {
+	unsigned char opcode__reserved;
+	unsigned char unit;
+	unsigned short request_id__lunl;
+	unsigned char status;
+	unsigned char sgl_offset;
+	unsigned short sgl_entries__lunh;
+	unsigned char cdb[16];
+	TW_SG_Entry_ISO sg_list[TW_LIBERATOR_MAX_SGL_LENGTH];
+	unsigned char padding[TW_PADDING_LENGTH_LIBERATOR];
+} TW_Command_Apache;
+
+/* New command packet header */
+typedef struct TAG_TW_Command_Apache_Header {
+	unsigned char sense_data[TW_SENSE_DATA_LENGTH];
+	struct {
+		char reserved[4];
+		unsigned short error;
+		unsigned char padding;
+		unsigned char severity__reserved;
+	} status_block;
+	unsigned char err_specific_desc[98];
+	struct {
+		unsigned char size_header;
+		unsigned short request_id;
+		unsigned char size_sense;
+	} header_desc;
+} TW_Command_Apache_Header;
+
+/* This struct is a union of the 2 command packets */
+typedef struct TAG_TW_Command_Full {
+	TW_Command_Apache_Header header;
+	union {
+		TW_Command oldcommand;
+		TW_Command_Apache newcommand;
+	} command;
+} TW_Command_Full;
+
+/* Initconnection structure */
+typedef struct TAG_TW_Initconnect {
+	unsigned char opcode__reserved;
+	unsigned char size;
+	unsigned char request_id;
+	unsigned char res2;
+	unsigned char status;
+	unsigned char flags;
+	unsigned short message_credits;
+	u32 features;
+	unsigned short fw_srl;
+	unsigned short fw_arch_id;
+	unsigned short fw_branch;
+	unsigned short fw_build;
+	u32 result;
+} TW_Initconnect;
+
+/* Event info structure */
+typedef struct TAG_TW_Event
+{
+	unsigned int sequence_id;
+	unsigned int time_stamp_sec;
+	unsigned short aen_code;
+	unsigned char severity;
+	unsigned char retrieved;
+	unsigned char repeat_count;
+	unsigned char parameter_len;
+	unsigned char parameter_data[98];
+} TW_Event;
+
+typedef struct TAG_TW_Ioctl_Driver_Command {
+	unsigned int control_code;
+	unsigned int status;
+	unsigned int unique_id;
+	unsigned int sequence_id;
+	unsigned int os_specific;
+	unsigned int buffer_length;
+} TW_Ioctl_Driver_Command;
+
+typedef struct TAG_TW_Ioctl_Apache {
+	TW_Ioctl_Driver_Command driver_command;
+        char padding[488];
+	TW_Command_Full firmware_command;
+	char data_buffer[1];
+} TW_Ioctl_Buf_Apache;
+
+/* GetParam descriptor */
+typedef struct {
+	unsigned short	table_id;
+	unsigned short	parameter_id;
+	unsigned short	parameter_size_bytes;
+	unsigned short  actual_parameter_size_bytes;
+	unsigned char	data[1];
+} TW_Param_Apache;
+
+/* Compatibility information structure */
+typedef struct TAG_TW_Compatibility_Info
+{
+	char driver_version[32];
+	unsigned short working_srl;
+	unsigned short working_branch;
+	unsigned short working_build;
+	unsigned short driver_srl_high;
+	unsigned short driver_branch_high;
+	unsigned short driver_build_high;
+	unsigned short driver_srl_low;
+	unsigned short driver_branch_low;
+	unsigned short driver_build_low;
+	unsigned short fw_on_ctlr_srl;
+	unsigned short fw_on_ctlr_branch;
+	unsigned short fw_on_ctlr_build;
+} TW_Compatibility_Info;
+
+#pragma pack()
+
+typedef struct TAG_TW_Device_Extension {
+	void                     __iomem *base_addr;
+	unsigned long	       	*generic_buffer_virt[TW_Q_LENGTH];
+	dma_addr_t	       	generic_buffer_phys[TW_Q_LENGTH];
+	TW_Command_Full	       	*command_packet_virt[TW_Q_LENGTH];
+	dma_addr_t		command_packet_phys[TW_Q_LENGTH];
+	TW_Command_Apache_Header *sense_buffer_virt[TW_Q_LENGTH];
+	dma_addr_t		sense_buffer_phys[TW_Q_LENGTH];
+	struct pci_dev		*tw_pci_dev;
+	struct scsi_cmnd	*srb[TW_Q_LENGTH];
+	unsigned char		free_queue[TW_Q_LENGTH];
+	unsigned char		free_head;
+	unsigned char		free_tail;
+	int     		state[TW_Q_LENGTH];
+	unsigned int		posted_request_count;
+	unsigned int		max_posted_request_count;
+	unsigned int		max_sgl_entries;
+	unsigned int		sgl_entries;
+	unsigned int		num_resets;
+	unsigned int		sector_count;
+	unsigned int		max_sector_count;
+	unsigned int		aen_count;
+	struct Scsi_Host	*host;
+	long			flags;
+	TW_Event                *event_queue[TW_Q_LENGTH];
+	unsigned char           error_index;
+	unsigned int            error_sequence_id;
+	int			chrdev_request_id;
+	wait_queue_head_t	ioctl_wqueue;
+	struct mutex		ioctl_lock;
+	TW_Compatibility_Info	tw_compat_info;
+	char			online;
+} TW_Device_Extension;
+
+#endif /* _3W_SAS_H */
+
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index faa0fcf..f65a1e9 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -8,7 +8,7 @@
 
    Copyright (C) 1999-2009 3ware Inc.
 
-   Kernel compatiblity By: 	Andre Hedrick <andre@suse.com>
+   Kernel compatibility By: 	Andre Hedrick <andre@suse.com>
    Non-Copyright (C) 2000	Andre Hedrick <andre@suse.com>
    
    Further tiny build fixes and trivial hoovering    Alan Cox
@@ -521,8 +521,12 @@
 } /* End tw_show_stats() */
 
 /* This function will set a devices queue depth */
-static int tw_change_queue_depth(struct scsi_device *sdev, int queue_depth)
+static int tw_change_queue_depth(struct scsi_device *sdev, int queue_depth,
+				 int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (queue_depth > TW_Q_LENGTH-2)
 		queue_depth = TW_Q_LENGTH-2;
 	scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
index f5a9add..9f4a911 100644
--- a/drivers/scsi/53c700.c
+++ b/drivers/scsi/53c700.c
@@ -175,7 +175,7 @@
 STATIC int NCR_700_slave_alloc(struct scsi_device *SDpnt);
 STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt);
 STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt);
-static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth);
+static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth, int reason);
 static int NCR_700_change_queue_type(struct scsi_device *SDpnt, int depth);
 
 STATIC struct device_attribute *NCR_700_dev_attrs[];
@@ -1491,7 +1491,7 @@
 	unsigned long flags;
 	int handled = 0;
 
-	/* Use the host lock to serialise acess to the 53c700
+	/* Use the host lock to serialise access to the 53c700
 	 * hardware.  Note: In future, we may need to take the queue
 	 * lock to enter the done routines.  When that happens, we
 	 * need to ensure that for this driver, the host lock and the
@@ -2082,8 +2082,11 @@
 }
 
 static int
-NCR_700_change_queue_depth(struct scsi_device *SDp, int depth)
+NCR_700_change_queue_depth(struct scsi_device *SDp, int depth, int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (depth > NCR_700_MAX_TAGS)
 		depth = NCR_700_MAX_TAGS;
 
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index e11cca4..36900c7 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -399,6 +399,17 @@
 	  Please read the comments at the top of
 	  <file:drivers/scsi/3w-9xxx.c>.
 
+config SCSI_3W_SAS
+	tristate "3ware 97xx SAS/SATA-RAID support"
+	depends on PCI && SCSI
+	help
+	  This driver supports the LSI 3ware 9750 6Gb/s SAS/SATA-RAID cards.
+
+	  <http://www.lsi.com>
+
+	  Please read the comments at the top of
+	  <file:drivers/scsi/3w-sas.c>.
+
 config SCSI_7000FASST
 	tristate "7000FASST SCSI support"
 	depends on ISA && SCSI && ISA_DMA_API
@@ -621,6 +632,14 @@
 	  substantial, so users of MultiMaster Host Adapters may not
 	  wish to include it.
 
+config VMWARE_PVSCSI
+	tristate "VMware PVSCSI driver support"
+	depends on PCI && SCSI && X86
+	help
+	  This driver supports VMware's para virtualized SCSI HBA.
+	  To compile this driver as a module, choose M here: the
+	  module will be called vmw_pvscsi.
+
 config LIBFC
 	tristate "LibFC module"
 	select SCSI_FC_ATTRS
@@ -644,7 +663,7 @@
 config FCOE_FNIC
 	tristate "Cisco FNIC Driver"
 	depends on PCI && X86
-	select LIBFC
+	select LIBFCOE
 	help
 	  This is support for the Cisco PCI-Express FCoE HBA.
 
@@ -1818,6 +1837,14 @@
 	---help---
 	  This driver supports the PMC SIERRA MaxRAID adapters.
 
+config SCSI_PM8001
+	tristate "PMC-Sierra SPC 8001 SAS/SATA Based Host Adapter driver"
+	depends on PCI && SCSI
+	select SCSI_SAS_LIBSAS
+	help
+	  This driver supports PMC-Sierra PCIE SAS/SATA 8x6G SPC 8001 chip
+	  based host adapters.
+
 config SCSI_SRP
 	tristate "SCSI RDMA Protocol helper library"
 	depends on SCSI && PCI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 3ad61db..280d3c657 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -70,6 +70,7 @@
 obj-$(CONFIG_SCSI_AACRAID)	+= aacraid/
 obj-$(CONFIG_SCSI_AIC7XXX_OLD)	+= aic7xxx_old.o
 obj-$(CONFIG_SCSI_AIC94XX)	+= aic94xx/
+obj-$(CONFIG_SCSI_PM8001)	+= pm8001/
 obj-$(CONFIG_SCSI_IPS)		+= ips.o
 obj-$(CONFIG_SCSI_FD_MCS)	+= fd_mcs.o
 obj-$(CONFIG_SCSI_FUTURE_DOMAIN)+= fdomain.o
@@ -113,6 +114,7 @@
 obj-$(CONFIG_SCSI_MAC53C94)	+= mac53c94.o
 obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o
 obj-$(CONFIG_SCSI_3W_9XXX)	+= 3w-9xxx.o
+obj-$(CONFIG_SCSI_3W_SAS)	+= 3w-sas.o
 obj-$(CONFIG_SCSI_PPA)		+= ppa.o
 obj-$(CONFIG_SCSI_IMM)		+= imm.o
 obj-$(CONFIG_JAZZ_ESP)		+= esp_scsi.o	jazz_esp.o
@@ -133,6 +135,7 @@
 obj-$(CONFIG_SCSI_BNX2_ISCSI)	+= libiscsi.o bnx2i/
 obj-$(CONFIG_BE2ISCSI)		+= libiscsi.o be2iscsi/
 obj-$(CONFIG_SCSI_PMCRAID)	+= pmcraid.o
+obj-$(CONFIG_VMWARE_PVSCSI)	+= vmw_pvscsi.o
 
 obj-$(CONFIG_ARM)		+= arm/
 
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index cdbdec9..83986ed 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -526,10 +526,10 @@
 
 /*
  *	The adapter interface specs all queues to be located in the same
- *	physically contigous block. The host structure that defines the
+ *	physically contiguous block. The host structure that defines the
  *	commuication queues will assume they are each a separate physically
- *	contigous memory region that will support them all being one big
- *	contigous block.
+ *	contiguous memory region that will support them all being one big
+ *	contiguous block.
  *	There is a command and response queue for each level and direction of
  *	commuication. These regions are accessed by both the host and adapter.
  */
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index d598eba..666d515 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -226,7 +226,7 @@
 	spin_lock_init(&dev->fib_lock);
 
 	/*
-	 *	Allocate the physically contigous space for the commuication
+	 *	Allocate the physically contiguous space for the commuication
 	 *	queue headers. 
 	 */
 
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 9b97c3e..e9373a2 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -472,8 +472,12 @@
  *	total capacity and the queue depth supported by the target device.
  */
 
-static int aac_change_queue_depth(struct scsi_device *sdev, int depth)
+static int aac_change_queue_depth(struct scsi_device *sdev, int depth,
+				  int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (sdev->tagged_supported && (sdev->type == TYPE_DISK) &&
 	    (sdev_channel(sdev) == CONTAINER_CHANNEL)) {
 		struct scsi_device * dev;
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index b756041..22626ab 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -7969,7 +7969,7 @@
 		ASC_DBG(1, "before AscInitAsc1000Driver()\n");
 		status = AscInitAsc1000Driver(asc_dvc);
 
-		/* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
+		/* Refer to ASC_IERR_* definitions for meaning of 'err_code'. */
 		if (asc_dvc->err_code) {
 			scmd_printk(KERN_INFO, scp, "SCSI bus reset error: "
 				    "0x%x\n", asc_dvc->err_code);
diff --git a/drivers/scsi/aic7xxx/aic79xx.seq b/drivers/scsi/aic7xxx/aic79xx.seq
index 58bc175..2fb78e3 100644
--- a/drivers/scsi/aic7xxx/aic79xx.seq
+++ b/drivers/scsi/aic7xxx/aic79xx.seq
@@ -217,7 +217,7 @@
 scbdma_tohost_done:
 	test	CCSCBCTL, CCARREN jz fill_qoutfifo_dmadone;
 	/*
-	 * An SCB has been succesfully uploaded to the host.
+	 * An SCB has been successfully uploaded to the host.
 	 * If the SCB was uploaded for some reason other than
 	 * bad SCSI status (currently only for underruns), we
 	 * queue the SCB for normal completion.  Otherwise, we
@@ -1281,7 +1281,7 @@
  * Is it a disconnect message?  Set a flag in the SCB to remind us
  * and await the bus going free.  If this is an untagged transaction
  * store the SCB id for it in our untagged target table for lookup on
- * a reselction.
+ * a reselection.
  */
 mesgin_disconnect:
 	/*
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c
index 63b521d..4d419c1 100644
--- a/drivers/scsi/aic7xxx/aic79xx_core.c
+++ b/drivers/scsi/aic7xxx/aic79xx_core.c
@@ -2487,7 +2487,7 @@
 		/*
 		 * Although the driver does not care about the
 		 * 'Selection in Progress' status bit, the busy
-		 * LED does.  SELINGO is only cleared by a sucessfull
+		 * LED does.  SELINGO is only cleared by a successfull
 		 * selection, so we must manually clear it to insure
 		 * the LED turns off just incase no future successful
 		 * selections occur (e.g. no devices on the bus).
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 75b2331..1222a7a 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -2335,7 +2335,7 @@
 			/*
 			 * The sequencer will never re-reference the
 			 * in-core SCB.  To make sure we are notified
-			 * during reslection, set the MK_MESSAGE flag in
+			 * during reselection, set the MK_MESSAGE flag in
 			 * the card's copy of the SCB.
 			 */
 			ahd_outb(ahd, SCB_CONTROL,
diff --git a/drivers/scsi/aic7xxx/aic7xxx.seq b/drivers/scsi/aic7xxx/aic7xxx.seq
index 1519639..5a4cfc95 100644
--- a/drivers/scsi/aic7xxx/aic7xxx.seq
+++ b/drivers/scsi/aic7xxx/aic7xxx.seq
@@ -1693,7 +1693,7 @@
  * Is it a disconnect message?  Set a flag in the SCB to remind us
  * and await the bus going free.  If this is an untagged transaction
  * store the SCB id for it in our untagged target table for lookup on
- * a reselction.
+ * a reselection.
  */
 mesgin_disconnect:
 	/*
diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c
index 8dfb59d..45aa728 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_core.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_core.c
@@ -1733,7 +1733,7 @@
 		/*
 		 * Although the driver does not care about the
 		 * 'Selection in Progress' status bit, the busy
-		 * LED does.  SELINGO is only cleared by a sucessfull
+		 * LED does.  SELINGO is only cleared by a successfull
 		 * selection, so we must manually clear it to insure
 		 * the LED turns off just incase no future successful
 		 * selections occur (e.g. no devices on the bus).
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index fd2b978..8cb05dc 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -2290,7 +2290,7 @@
 		 * In the non-paging case, the sequencer will
 		 * never re-reference the in-core SCB.
 		 * To make sure we are notified during
-		 * reslection, set the MK_MESSAGE flag in
+		 * reselection, set the MK_MESSAGE flag in
 		 * the card's copy of the SCB.
 		 */
 		if ((ahc->flags & AHC_PAGESCBS) == 0) {
diff --git a/drivers/scsi/aic94xx/aic94xx_reg_def.h b/drivers/scsi/aic94xx/aic94xx_reg_def.h
index a43e8cd..28aaf34 100644
--- a/drivers/scsi/aic94xx/aic94xx_reg_def.h
+++ b/drivers/scsi/aic94xx/aic94xx_reg_def.h
@@ -1,5 +1,5 @@
 /*
- * Aic94xx SAS/SATA driver hardware registers defintions.
+ * Aic94xx SAS/SATA driver hardware registers definitions.
  *
  * Copyright (C) 2004 Adaptec, Inc.  All rights reserved.
  * Copyright (C) 2004 David Chaw <david_chaw@adaptec.com>
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 80aac01..47d5d19 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -98,8 +98,11 @@
 static const char *arcmsr_info(struct Scsi_Host *);
 static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb);
 static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev,
-								int queue_depth)
+					  int queue_depth, int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (queue_depth > ARCMSR_MAX_CMD_PERLUN)
 		queue_depth = ARCMSR_MAX_CMD_PERLUN;
 	scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h
index b36020d..a93a504 100644
--- a/drivers/scsi/be2iscsi/be.h
+++ b/drivers/scsi/be2iscsi/be.h
@@ -20,8 +20,10 @@
 
 #include <linux/pci.h>
 #include <linux/if_vlan.h>
-
-#define FW_VER_LEN 32
+#include <linux/blk-iopoll.h>
+#define FW_VER_LEN	32
+#define MCC_Q_LEN	128
+#define MCC_CQ_LEN	256
 
 struct be_dma_mem {
 	void *va;
@@ -74,18 +76,14 @@
 
 struct be_eq_obj {
 	struct be_queue_info q;
-	char desc[32];
-
-	/* Adaptive interrupt coalescing (AIC) info */
-	bool enable_aic;
-	u16 min_eqd;		/* in usecs */
-	u16 max_eqd;		/* in usecs */
-	u16 cur_eqd;		/* in usecs */
+	struct beiscsi_hba *phba;
+	struct be_queue_info *cq;
+	struct blk_iopoll	iopoll;
 };
 
 struct be_mcc_obj {
-	struct be_queue_info *q;
-	struct be_queue_info *cq;
+	struct be_queue_info q;
+	struct be_queue_info cq;
 };
 
 struct be_ctrl_info {
@@ -176,8 +174,4 @@
 	} while (len);
 #endif /* __BIG_ENDIAN */
 }
-
-extern void beiscsi_cq_notify(struct be_ctrl_info *ctrl, u16 qid, bool arm,
-			      u16 num_popped);
-
 #endif /* BEISCSI_H */
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 08007b6..698a527 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -19,6 +19,16 @@
 #include "be_mgmt.h"
 #include "be_main.h"
 
+static void be_mcc_notify(struct beiscsi_hba *phba)
+{
+	struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
+	u32 val = 0;
+
+	val |= mccq->id & DB_MCCQ_RING_ID_MASK;
+	val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT;
+	iowrite32(val, phba->db_va + DB_MCCQ_OFFSET);
+}
+
 static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl)
 {
 	if (compl->flags != 0) {
@@ -54,13 +64,56 @@
 	return 0;
 }
 
+
 static inline bool is_link_state_evt(u32 trailer)
 {
 	return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
-		ASYNC_TRAILER_EVENT_CODE_MASK) == ASYNC_EVENT_CODE_LINK_STATE);
+		  ASYNC_TRAILER_EVENT_CODE_MASK) ==
+		  ASYNC_EVENT_CODE_LINK_STATE);
 }
 
-void beiscsi_cq_notify(struct be_ctrl_info *ctrl, u16 qid, bool arm,
+static struct be_mcc_compl *be_mcc_compl_get(struct beiscsi_hba *phba)
+{
+	struct be_queue_info *mcc_cq = &phba->ctrl.mcc_obj.cq;
+	struct be_mcc_compl *compl = queue_tail_node(mcc_cq);
+
+	if (be_mcc_compl_is_new(compl)) {
+		queue_tail_inc(mcc_cq);
+		return compl;
+	}
+	return NULL;
+}
+
+static void be2iscsi_fail_session(struct iscsi_cls_session *cls_session)
+{
+	iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
+}
+
+static void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
+		struct be_async_event_link_state *evt)
+{
+	switch (evt->port_link_status) {
+	case ASYNC_EVENT_LINK_DOWN:
+		SE_DEBUG(DBG_LVL_1, "Link Down on Physical Port %d \n",
+						evt->physical_port);
+		phba->state |= BE_ADAPTER_LINK_DOWN;
+		break;
+	case ASYNC_EVENT_LINK_UP:
+		phba->state = BE_ADAPTER_UP;
+		SE_DEBUG(DBG_LVL_1, "Link UP on Physical Port %d \n",
+						evt->physical_port);
+		iscsi_host_for_each_session(phba->shost,
+					    be2iscsi_fail_session);
+		break;
+	default:
+		SE_DEBUG(DBG_LVL_1, "Unexpected Async Notification %d on"
+				    "Physical Port %d \n",
+				     evt->port_link_status,
+				     evt->physical_port);
+	}
+}
+
+static void beiscsi_cq_notify(struct beiscsi_hba *phba, u16 qid, bool arm,
 		       u16 num_popped)
 {
 	u32 val = 0;
@@ -68,7 +121,66 @@
 	if (arm)
 		val |= 1 << DB_CQ_REARM_SHIFT;
 	val |= num_popped << DB_CQ_NUM_POPPED_SHIFT;
-	iowrite32(val, ctrl->db + DB_CQ_OFFSET);
+	iowrite32(val, phba->db_va + DB_CQ_OFFSET);
+}
+
+
+int beiscsi_process_mcc(struct beiscsi_hba *phba)
+{
+	struct be_mcc_compl *compl;
+	int num = 0, status = 0;
+	struct be_ctrl_info *ctrl = &phba->ctrl;
+
+	spin_lock_bh(&phba->ctrl.mcc_cq_lock);
+	while ((compl = be_mcc_compl_get(phba))) {
+		if (compl->flags & CQE_FLAGS_ASYNC_MASK) {
+			/* Interpret flags as an async trailer */
+			BUG_ON(!is_link_state_evt(compl->flags));
+
+			/* Interpret compl as a async link evt */
+			beiscsi_async_link_state_process(phba,
+				(struct be_async_event_link_state *) compl);
+		} else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
+				status = be_mcc_compl_process(ctrl, compl);
+				atomic_dec(&phba->ctrl.mcc_obj.q.used);
+		}
+		be_mcc_compl_use(compl);
+		num++;
+	}
+
+	if (num)
+		beiscsi_cq_notify(phba, phba->ctrl.mcc_obj.cq.id, true, num);
+
+	spin_unlock_bh(&phba->ctrl.mcc_cq_lock);
+	return status;
+}
+
+/* Wait till no more pending mcc requests are present */
+static int be_mcc_wait_compl(struct beiscsi_hba *phba)
+{
+#define mcc_timeout		120000 /* 5s timeout */
+	int i, status;
+	for (i = 0; i < mcc_timeout; i++) {
+		status = beiscsi_process_mcc(phba);
+		if (status)
+			return status;
+
+		if (atomic_read(&phba->ctrl.mcc_obj.q.used) == 0)
+			break;
+		udelay(100);
+	}
+	if (i == mcc_timeout) {
+		dev_err(&phba->pcidev->dev, "mccq poll timed out\n");
+		return -1;
+	}
+	return 0;
+}
+
+/* Notify MCC requests and wait for completion */
+int be_mcc_notify_wait(struct beiscsi_hba *phba)
+{
+	be_mcc_notify(phba);
+	return be_mcc_wait_compl(phba);
 }
 
 static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
@@ -142,6 +254,52 @@
 	return 0;
 }
 
+/*
+ * Insert the mailbox address into the doorbell in two steps
+ * Polls on the mbox doorbell till a command completion (or a timeout) occurs
+ */
+static int be_mbox_notify_wait(struct beiscsi_hba *phba)
+{
+	int status;
+	u32 val = 0;
+	void __iomem *db = phba->ctrl.db + MPU_MAILBOX_DB_OFFSET;
+	struct be_dma_mem *mbox_mem = &phba->ctrl.mbox_mem;
+	struct be_mcc_mailbox *mbox = mbox_mem->va;
+	struct be_mcc_compl *compl = &mbox->compl;
+	struct be_ctrl_info *ctrl = &phba->ctrl;
+
+	val |= MPU_MAILBOX_DB_HI_MASK;
+	/* at bits 2 - 31 place mbox dma addr msb bits 34 - 63 */
+	val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2;
+	iowrite32(val, db);
+
+	/* wait for ready to be set */
+	status = be_mbox_db_ready_wait(ctrl);
+	if (status != 0)
+		return status;
+
+	val = 0;
+	/* at bits 2 - 31 place mbox dma addr lsb bits 4 - 33 */
+	val |= (u32)(mbox_mem->dma >> 4) << 2;
+	iowrite32(val, db);
+
+	status = be_mbox_db_ready_wait(ctrl);
+	if (status != 0)
+		return status;
+
+	/* A cq entry has been made now */
+	if (be_mcc_compl_is_new(compl)) {
+		status = be_mcc_compl_process(ctrl, &mbox->compl);
+		be_mcc_compl_use(compl);
+		if (status)
+			return status;
+	} else {
+		dev_err(&phba->pcidev->dev, "invalid mailbox completion\n");
+		return -1;
+	}
+	return 0;
+}
+
 void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len,
 				bool embedded, u8 sge_cnt)
 {
@@ -203,6 +361,20 @@
 	return &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb;
 }
 
+struct be_mcc_wrb *wrb_from_mccq(struct beiscsi_hba *phba)
+{
+	struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
+	struct be_mcc_wrb *wrb;
+
+	BUG_ON(atomic_read(&mccq->used) >= mccq->len);
+	wrb = queue_head_node(mccq);
+	queue_head_inc(mccq);
+	atomic_inc(&mccq->used);
+	memset(wrb, 0, sizeof(*wrb));
+	return wrb;
+}
+
+
 int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
 			  struct be_queue_info *eq, int eq_delay)
 {
@@ -212,6 +384,7 @@
 	struct be_dma_mem *q_mem = &eq->dma_mem;
 	int status;
 
+	SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_eq_create\n");
 	spin_lock(&ctrl->mbox_lock);
 	memset(wrb, 0, sizeof(*wrb));
 
@@ -249,6 +422,7 @@
 	int status;
 	u8 *endian_check;
 
+	SE_DEBUG(DBG_LVL_8, "In be_cmd_fw_initialize\n");
 	spin_lock(&ctrl->mbox_lock);
 	memset(wrb, 0, sizeof(*wrb));
 
@@ -282,6 +456,7 @@
 	void *ctxt = &req->context;
 	int status;
 
+	SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_cq_create \n");
 	spin_lock(&ctrl->mbox_lock);
 	memset(wrb, 0, sizeof(*wrb));
 
@@ -289,7 +464,6 @@
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 			OPCODE_COMMON_CQ_CREATE, sizeof(*req));
-
 	if (!q_mem->va)
 		SE_DEBUG(DBG_LVL_1, "uninitialized q_mem->va\n");
 
@@ -329,6 +503,53 @@
 		len_encoded = 0;
 	return len_encoded;
 }
+
+int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba,
+			struct be_queue_info *mccq,
+			struct be_queue_info *cq)
+{
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_mcc_create *req;
+	struct be_dma_mem *q_mem = &mccq->dma_mem;
+	struct be_ctrl_info *ctrl;
+	void *ctxt;
+	int status;
+
+	spin_lock(&phba->ctrl.mbox_lock);
+	ctrl = &phba->ctrl;
+	wrb = wrb_from_mbox(&ctrl->mbox_mem);
+	req = embedded_payload(wrb);
+	ctxt = &req->context;
+
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+			OPCODE_COMMON_MCC_CREATE, sizeof(*req));
+
+	req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
+
+	AMAP_SET_BITS(struct amap_mcc_context, fid, ctxt,
+		      PCI_FUNC(phba->pcidev->devfn));
+	AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1);
+	AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt,
+		be_encoded_q_len(mccq->len));
+	AMAP_SET_BITS(struct amap_mcc_context, cq_id, ctxt, cq->id);
+
+	be_dws_cpu_to_le(ctxt, sizeof(req->context));
+
+	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
+
+	status = be_mbox_notify_wait(phba);
+	if (!status) {
+		struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb);
+		mccq->id = le16_to_cpu(resp->id);
+		mccq->created = true;
+	}
+	spin_unlock(&phba->ctrl.mbox_lock);
+
+	return status;
+}
+
 int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
 			  int queue_type)
 {
@@ -337,6 +558,7 @@
 	u8 subsys = 0, opcode = 0;
 	int status;
 
+	SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_q_destroy \n");
 	spin_lock(&ctrl->mbox_lock);
 	memset(wrb, 0, sizeof(*wrb));
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -350,6 +572,10 @@
 		subsys = CMD_SUBSYSTEM_COMMON;
 		opcode = OPCODE_COMMON_CQ_DESTROY;
 		break;
+	case QTYPE_MCCQ:
+		subsys = CMD_SUBSYSTEM_COMMON;
+		opcode = OPCODE_COMMON_MCC_DESTROY;
+		break;
 	case QTYPE_WRBQ:
 		subsys = CMD_SUBSYSTEM_ISCSI;
 		opcode = OPCODE_COMMON_ISCSI_WRBQ_DESTROY;
@@ -377,30 +603,6 @@
 	return status;
 }
 
-int be_cmd_get_mac_addr(struct be_ctrl_info *ctrl, u8 *mac_addr)
-{
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
-	struct be_cmd_req_get_mac_addr *req = embedded_payload(wrb);
-	int status;
-
-	spin_lock(&ctrl->mbox_lock);
-	memset(wrb, 0, sizeof(*wrb));
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
-	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
-			   OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
-			   sizeof(*req));
-
-	status = be_mbox_notify(ctrl);
-	if (!status) {
-		struct be_cmd_resp_get_mac_addr *resp = embedded_payload(wrb);
-
-		memcpy(mac_addr, resp->mac_address, ETH_ALEN);
-	}
-
-	spin_unlock(&ctrl->mbox_lock);
-	return status;
-}
-
 int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl,
 				    struct be_queue_info *cq,
 				    struct be_queue_info *dq, int length,
@@ -412,6 +614,7 @@
 	void *ctxt = &req->context;
 	int status;
 
+	SE_DEBUG(DBG_LVL_8, "In be_cmd_create_default_pdu_queue\n");
 	spin_lock(&ctrl->mbox_lock);
 	memset(wrb, 0, sizeof(*wrb));
 
@@ -468,8 +671,10 @@
 	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
 
 	status = be_mbox_notify(ctrl);
-	if (!status)
+	if (!status) {
 		wrbq->id = le16_to_cpu(resp->cid);
+		wrbq->created = true;
+	}
 	spin_unlock(&ctrl->mbox_lock);
 	return status;
 }
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index c20d686..5de8acb 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -47,6 +47,8 @@
 
 #define CQE_FLAGS_VALID_MASK (1 << 31)
 #define CQE_FLAGS_ASYNC_MASK (1 << 30)
+#define CQE_FLAGS_COMPLETED_MASK 	(1 << 28)
+#define CQE_FLAGS_CONSUMED_MASK 	(1 << 27)
 
 /* Completion Status */
 #define MCC_STATUS_SUCCESS 0x0
@@ -173,7 +175,7 @@
 	u8 domain;		/* dword 0 */
 	u32 timeout;		/* dword 1 */
 	u32 request_length;	/* dword 2 */
-	u32 rsvd;		/* dword 3 */
+	u32 rsvd0;		/* dword 3 */
 };
 
 struct be_cmd_resp_hdr {
@@ -382,7 +384,6 @@
 
 #define ETH_ALEN	6
 
-
 struct be_cmd_req_get_mac_addr {
 	struct be_cmd_req_hdr hdr;
 	u32 nic_port_count;
@@ -417,14 +418,21 @@
 
 int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
 			  int type);
+int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba,
+			struct be_queue_info *mccq,
+			struct be_queue_info *cq);
+
 int be_poll_mcc(struct be_ctrl_info *ctrl);
-unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl);
-int be_cmd_get_mac_addr(struct be_ctrl_info *ctrl, u8 *mac_addr);
+unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
+				      struct beiscsi_hba *phba);
+int be_cmd_get_mac_addr(struct beiscsi_hba *phba, u8 *mac_addr);
 
 /*ISCSI Functuions */
 int be_cmd_fw_initialize(struct be_ctrl_info *ctrl);
 
 struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem);
+struct be_mcc_wrb *wrb_from_mccq(struct beiscsi_hba *phba);
+int be_mcc_notify_wait(struct beiscsi_hba *phba);
 
 int be_mbox_notify(struct be_ctrl_info *ctrl);
 
@@ -531,6 +539,23 @@
 	u8 valid;		/* dword 3 */
 } __packed;
 
+#define SOL_ICD_INDEX_MASK	0x0003FFC0
+struct amap_sol_cqe_ring {
+	u8 hw_sts[8];		/* dword 0 */
+	u8 i_sts[8];		/* dword 0 */
+	u8 i_resp[8];		/* dword 0 */
+	u8 i_flags[7];		/* dword 0 */
+	u8 s;			/* dword 0 */
+	u8 i_exp_cmd_sn[32];	/* dword 1 */
+	u8 code[6];		/* dword 2 */
+	u8 icd_index[12];	/* dword 2 */
+	u8 rsvd[6];		/* dword 2 */
+	u8 i_cmd_wnd[8];	/* dword 2 */
+	u8 i_res_cnt[31];	/* dword 3 */
+	u8 valid;		/* dword 3 */
+} __packed;
+
+
 
 /**
  * Post WRB Queue Doorbell Register used by the host Storage
@@ -664,8 +689,8 @@
 #define	OPCODE_COMMON_TCP_UPLOAD	56
 #define OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS 1
 /* --- CMD_ISCSI_INVALIDATE_CONNECTION_TYPE --- */
-#define CMD_ISCSI_CONNECTION_INVALIDATE 1
-#define CMD_ISCSI_CONNECTION_ISSUE_TCP_RST 2
+#define CMD_ISCSI_CONNECTION_INVALIDATE 0x8001
+#define CMD_ISCSI_CONNECTION_ISSUE_TCP_RST 0x8002
 #define OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION 42
 
 #define INI_WR_CMD			1	/* Initiator write command */
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index 2fd2544..d587b03 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -67,11 +67,11 @@
 		cmds_max = beiscsi_ep->phba->params.wrbs_per_cxn;
 	}
 
-	 cls_session = iscsi_session_setup(&beiscsi_iscsi_transport,
-					   shost, cmds_max,
-					   sizeof(*beiscsi_sess),
-					   sizeof(*io_task),
-					   initial_cmdsn, ISCSI_MAX_TARGET);
+	cls_session = iscsi_session_setup(&beiscsi_iscsi_transport,
+					  shost, cmds_max,
+					  sizeof(*beiscsi_sess),
+					  sizeof(*io_task),
+					  initial_cmdsn, ISCSI_MAX_TARGET);
 	if (!cls_session)
 		return NULL;
 	sess = cls_session->dd_data;
@@ -297,7 +297,7 @@
 
 	switch (param) {
 	case ISCSI_HOST_PARAM_HWADDRESS:
-		be_cmd_get_mac_addr(&phba->ctrl, phba->mac_address);
+		be_cmd_get_mac_addr(phba, phba->mac_address);
 		len = sysfs_format_mac(buf, phba->mac_address, ETH_ALEN);
 		break;
 	default:
@@ -377,16 +377,12 @@
 	struct beiscsi_conn *beiscsi_conn = conn->dd_data;
 	struct beiscsi_endpoint *beiscsi_ep;
 	struct beiscsi_offload_params params;
-	struct iscsi_session *session = conn->session;
-	struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session);
-	struct beiscsi_hba *phba = iscsi_host_priv(shost);
 
 	memset(&params, 0, sizeof(struct beiscsi_offload_params));
 	beiscsi_ep = beiscsi_conn->ep;
 	if (!beiscsi_ep)
 		SE_DEBUG(DBG_LVL_1, "In beiscsi_conn_start , no beiscsi_ep\n");
 
-	free_mgmt_sgl_handle(phba, beiscsi_conn->plogin_sgl_handle);
 	beiscsi_conn->login_in_progress = 0;
 	beiscsi_set_params_for_offld(beiscsi_conn, &params);
 	beiscsi_offload_connection(beiscsi_conn, &params);
@@ -498,6 +494,13 @@
 		SE_DEBUG(DBG_LVL_1, "shost is NULL \n");
 		return ERR_PTR(ret);
 	}
+
+	if (phba->state) {
+		ret = -EBUSY;
+		SE_DEBUG(DBG_LVL_1, "The Adapet state is Not UP \n");
+		return ERR_PTR(ret);
+	}
+
 	ep = iscsi_create_endpoint(sizeof(struct beiscsi_endpoint));
 	if (!ep) {
 		ret = -ENOMEM;
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 4f1aca3..1a557fa 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -39,7 +39,8 @@
 
 static unsigned int be_iopoll_budget = 10;
 static unsigned int be_max_phys_size = 64;
-static unsigned int enable_msix;
+static unsigned int enable_msix = 1;
+static unsigned int ring_mode;
 
 MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
 MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR);
@@ -58,6 +59,17 @@
 	return 0;
 }
 
+/*------------------- PCI Driver operations and data ----------------- */
+static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
+	{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
+	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) },
+	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) },
+	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID3) },
+	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID4) },
+	{ 0 }
+};
+MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
+
 static struct scsi_host_template beiscsi_sht = {
 	.module = THIS_MODULE,
 	.name = "ServerEngines 10Gbe open-iscsi Initiator Driver",
@@ -76,16 +88,8 @@
 	.cmd_per_lun = BEISCSI_CMD_PER_LUN,
 	.use_clustering = ENABLE_CLUSTERING,
 };
-static struct scsi_transport_template *beiscsi_scsi_transport;
 
-/*------------------- PCI Driver operations and data ----------------- */
-static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
-	{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
-	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) },
-	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) },
-	{ 0 }
-};
-MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
+static struct scsi_transport_template *beiscsi_scsi_transport;
 
 static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev)
 {
@@ -104,7 +108,6 @@
 	shost->max_cmd_len = BEISCSI_MAX_CMD_LEN;
 	shost->max_lun = BEISCSI_NUM_MAX_LUN;
 	shost->transportt = beiscsi_scsi_transport;
-
 	phba = iscsi_host_priv(shost);
 	memset(phba, 0, sizeof(*phba));
 	phba->shost = shost;
@@ -181,6 +184,7 @@
 		return ret;
 	}
 
+	pci_set_master(pcidev);
 	if (pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(64))) {
 		ret = pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(32));
 		if (ret) {
@@ -203,7 +207,6 @@
 	status = beiscsi_map_pci_bars(phba, pdev);
 	if (status)
 		return status;
-
 	mbox_mem_alloc->size = sizeof(struct be_mcc_mailbox) + 16;
 	mbox_mem_alloc->va = pci_alloc_consistent(pdev,
 						  mbox_mem_alloc->size,
@@ -219,6 +222,9 @@
 	mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16);
 	memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox));
 	spin_lock_init(&ctrl->mbox_lock);
+	spin_lock_init(&phba->ctrl.mcc_lock);
+	spin_lock_init(&phba->ctrl.mcc_cq_lock);
+
 	return status;
 }
 
@@ -268,6 +274,113 @@
 }
 
 /**
+ * be_isr_mcc - The isr routine of the driver.
+ * @irq: Not used
+ * @dev_id: Pointer to host adapter structure
+ */
+static irqreturn_t be_isr_mcc(int irq, void *dev_id)
+{
+	struct beiscsi_hba *phba;
+	struct be_eq_entry *eqe = NULL;
+	struct be_queue_info *eq;
+	struct be_queue_info *mcc;
+	unsigned int num_eq_processed;
+	struct be_eq_obj *pbe_eq;
+	unsigned long flags;
+
+	pbe_eq = dev_id;
+	eq = &pbe_eq->q;
+	phba =  pbe_eq->phba;
+	mcc = &phba->ctrl.mcc_obj.cq;
+	eqe = queue_tail_node(eq);
+	if (!eqe)
+		SE_DEBUG(DBG_LVL_1, "eqe is NULL\n");
+
+	num_eq_processed = 0;
+
+	while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
+				& EQE_VALID_MASK) {
+		if (((eqe->dw[offsetof(struct amap_eq_entry,
+		     resource_id) / 32] &
+		     EQE_RESID_MASK) >> 16) == mcc->id) {
+			spin_lock_irqsave(&phba->isr_lock, flags);
+			phba->todo_mcc_cq = 1;
+			spin_unlock_irqrestore(&phba->isr_lock, flags);
+		}
+		AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
+		queue_tail_inc(eq);
+		eqe = queue_tail_node(eq);
+		num_eq_processed++;
+	}
+	if (phba->todo_mcc_cq)
+		queue_work(phba->wq, &phba->work_cqs);
+	if (num_eq_processed)
+		hwi_ring_eq_db(phba, eq->id, 1,	num_eq_processed, 1, 1);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * be_isr_msix - The isr routine of the driver.
+ * @irq: Not used
+ * @dev_id: Pointer to host adapter structure
+ */
+static irqreturn_t be_isr_msix(int irq, void *dev_id)
+{
+	struct beiscsi_hba *phba;
+	struct be_eq_entry *eqe = NULL;
+	struct be_queue_info *eq;
+	struct be_queue_info *cq;
+	unsigned int num_eq_processed;
+	struct be_eq_obj *pbe_eq;
+	unsigned long flags;
+
+	pbe_eq = dev_id;
+	eq = &pbe_eq->q;
+	cq = pbe_eq->cq;
+	eqe = queue_tail_node(eq);
+	if (!eqe)
+		SE_DEBUG(DBG_LVL_1, "eqe is NULL\n");
+
+	phba = pbe_eq->phba;
+	num_eq_processed = 0;
+	if (blk_iopoll_enabled) {
+		while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
+					& EQE_VALID_MASK) {
+			if (!blk_iopoll_sched_prep(&pbe_eq->iopoll))
+				blk_iopoll_sched(&pbe_eq->iopoll);
+
+			AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
+			queue_tail_inc(eq);
+			eqe = queue_tail_node(eq);
+			num_eq_processed++;
+		}
+		if (num_eq_processed)
+			hwi_ring_eq_db(phba, eq->id, 1,	num_eq_processed, 0, 1);
+
+		return IRQ_HANDLED;
+	} else {
+		while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
+						& EQE_VALID_MASK) {
+			spin_lock_irqsave(&phba->isr_lock, flags);
+			phba->todo_cq = 1;
+			spin_unlock_irqrestore(&phba->isr_lock, flags);
+			AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
+			queue_tail_inc(eq);
+			eqe = queue_tail_node(eq);
+			num_eq_processed++;
+		}
+		if (phba->todo_cq)
+			queue_work(phba->wq, &phba->work_cqs);
+
+		if (num_eq_processed)
+			hwi_ring_eq_db(phba, eq->id, 1, num_eq_processed, 1, 1);
+
+		return IRQ_HANDLED;
+	}
+}
+
+/**
  * be_isr - The isr routine of the driver.
  * @irq: Not used
  * @dev_id: Pointer to host adapter structure
@@ -280,48 +393,70 @@
 	struct be_eq_entry *eqe = NULL;
 	struct be_queue_info *eq;
 	struct be_queue_info *cq;
+	struct be_queue_info *mcc;
 	unsigned long flags, index;
-	unsigned int num_eq_processed;
+	unsigned int num_mcceq_processed, num_ioeq_processed;
 	struct be_ctrl_info *ctrl;
+	struct be_eq_obj *pbe_eq;
 	int isr;
 
 	phba = dev_id;
-	if (!enable_msix) {
-		ctrl = &phba->ctrl;;
-		isr = ioread32(ctrl->csr + CEV_ISR0_OFFSET +
-			       (PCI_FUNC(ctrl->pdev->devfn) * CEV_ISR_SIZE));
-		if (!isr)
-			return IRQ_NONE;
-	}
+	ctrl = &phba->ctrl;;
+	isr = ioread32(ctrl->csr + CEV_ISR0_OFFSET +
+		       (PCI_FUNC(ctrl->pdev->devfn) * CEV_ISR_SIZE));
+	if (!isr)
+		return IRQ_NONE;
 
 	phwi_ctrlr = phba->phwi_ctrlr;
 	phwi_context = phwi_ctrlr->phwi_ctxt;
-	eq = &phwi_context->be_eq.q;
-	cq = &phwi_context->be_cq;
+	pbe_eq = &phwi_context->be_eq[0];
+
+	eq = &phwi_context->be_eq[0].q;
+	mcc = &phba->ctrl.mcc_obj.cq;
 	index = 0;
 	eqe = queue_tail_node(eq);
 	if (!eqe)
 		SE_DEBUG(DBG_LVL_1, "eqe is NULL\n");
 
-	num_eq_processed = 0;
+	num_ioeq_processed = 0;
+	num_mcceq_processed = 0;
 	if (blk_iopoll_enabled) {
 		while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
 					& EQE_VALID_MASK) {
-			if (!blk_iopoll_sched_prep(&phba->iopoll))
-				blk_iopoll_sched(&phba->iopoll);
-
+			if (((eqe->dw[offsetof(struct amap_eq_entry,
+			     resource_id) / 32] &
+			     EQE_RESID_MASK) >> 16) == mcc->id) {
+				spin_lock_irqsave(&phba->isr_lock, flags);
+				phba->todo_mcc_cq = 1;
+				spin_unlock_irqrestore(&phba->isr_lock, flags);
+				num_mcceq_processed++;
+			} else {
+				if (!blk_iopoll_sched_prep(&pbe_eq->iopoll))
+					blk_iopoll_sched(&pbe_eq->iopoll);
+				num_ioeq_processed++;
+			}
 			AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
 			queue_tail_inc(eq);
 			eqe = queue_tail_node(eq);
-			num_eq_processed++;
-			SE_DEBUG(DBG_LVL_8, "Valid EQE\n");
 		}
-		if (num_eq_processed) {
-			hwi_ring_eq_db(phba, eq->id, 0,	num_eq_processed, 0, 1);
+		if (num_ioeq_processed || num_mcceq_processed) {
+			if (phba->todo_mcc_cq)
+				queue_work(phba->wq, &phba->work_cqs);
+
+		if ((num_mcceq_processed) && (!num_ioeq_processed))
+				hwi_ring_eq_db(phba, eq->id, 0,
+					      (num_ioeq_processed +
+					       num_mcceq_processed) , 1, 1);
+			else
+				hwi_ring_eq_db(phba, eq->id, 0,
+					       (num_ioeq_processed +
+						num_mcceq_processed), 0, 1);
+
 			return IRQ_HANDLED;
 		} else
 			return IRQ_NONE;
 	} else {
+		cq = &phwi_context->be_cq[0];
 		while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
 						& EQE_VALID_MASK) {
 
@@ -339,13 +474,14 @@
 			AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
 			queue_tail_inc(eq);
 			eqe = queue_tail_node(eq);
-			num_eq_processed++;
+			num_ioeq_processed++;
 		}
 		if (phba->todo_cq || phba->todo_mcc_cq)
 			queue_work(phba->wq, &phba->work_cqs);
 
-		if (num_eq_processed) {
-			hwi_ring_eq_db(phba, eq->id, 0, num_eq_processed, 1, 1);
+		if (num_ioeq_processed) {
+			hwi_ring_eq_db(phba, eq->id, 0,
+				       num_ioeq_processed, 1, 1);
 			return IRQ_HANDLED;
 		} else
 			return IRQ_NONE;
@@ -355,13 +491,32 @@
 static int beiscsi_init_irqs(struct beiscsi_hba *phba)
 {
 	struct pci_dev *pcidev = phba->pcidev;
-	int ret;
+	struct hwi_controller *phwi_ctrlr;
+	struct hwi_context_memory *phwi_context;
+	int ret, msix_vec, i = 0;
+	char desc[32];
 
-	ret = request_irq(pcidev->irq, be_isr, IRQF_SHARED, "beiscsi", phba);
-	if (ret) {
-		shost_printk(KERN_ERR, phba->shost, "beiscsi_init_irqs-"
-			     "Failed to register irq\\n");
-		return ret;
+	phwi_ctrlr = phba->phwi_ctrlr;
+	phwi_context = phwi_ctrlr->phwi_ctxt;
+
+	if (phba->msix_enabled) {
+		for (i = 0; i < phba->num_cpus; i++) {
+			sprintf(desc, "beiscsi_msix_%04x", i);
+			msix_vec = phba->msix_entries[i].vector;
+			ret = request_irq(msix_vec, be_isr_msix, 0, desc,
+					  &phwi_context->be_eq[i]);
+		}
+		msix_vec = phba->msix_entries[i].vector;
+		ret = request_irq(msix_vec, be_isr_mcc, 0, "beiscsi_msix_mcc",
+				  &phwi_context->be_eq[i]);
+	} else {
+		ret = request_irq(pcidev->irq, be_isr, IRQF_SHARED,
+				  "beiscsi", phba);
+		if (ret) {
+			shost_printk(KERN_ERR, phba->shost, "beiscsi_init_irqs-"
+				     "Failed to register irq\\n");
+			return ret;
+		}
 	}
 	return 0;
 }
@@ -378,15 +533,6 @@
 	iowrite32(val, phba->db_va + DB_CQ_OFFSET);
 }
 
-/*
- * async pdus include
- * a. unsolicited NOP-In (target initiated NOP-In)
- * b. Async Messages
- * c. Reject PDU
- * d. Login response
- * These headers arrive unprocessed by the EP firmware and iSCSI layer
- * process them
- */
 static unsigned int
 beiscsi_process_async_pdu(struct beiscsi_conn *beiscsi_conn,
 			  struct beiscsi_hba *phba,
@@ -397,6 +543,9 @@
 {
 	struct iscsi_conn *conn = beiscsi_conn->conn;
 	struct iscsi_session *session = conn->session;
+	struct iscsi_task *task;
+	struct beiscsi_io_task *io_task;
+	struct iscsi_hdr *login_hdr;
 
 	switch (ppdu->dw[offsetof(struct amap_pdu_base, opcode) / 32] &
 						PDUBASE_OPCODE_MASK) {
@@ -412,6 +561,10 @@
 		SE_DEBUG(DBG_LVL_1, "In ISCSI_OP_REJECT\n");
 		break;
 	case ISCSI_OP_LOGIN_RSP:
+		task = conn->login_task;
+		io_task = task->dd_data;
+		login_hdr = (struct iscsi_hdr *)ppdu;
+		login_hdr->itt = io_task->libiscsi_itt;
 		break;
 	default:
 		shost_printk(KERN_WARNING, phba->shost,
@@ -440,7 +593,8 @@
 						io_sgl_alloc_index];
 		phba->io_sgl_hndl_base[phba->io_sgl_alloc_index] = NULL;
 		phba->io_sgl_hndl_avbl--;
-		if (phba->io_sgl_alloc_index == (phba->params.ios_per_ctrl - 1))
+		if (phba->io_sgl_alloc_index == (phba->params.
+						 ios_per_ctrl - 1))
 			phba->io_sgl_alloc_index = 0;
 		else
 			phba->io_sgl_alloc_index++;
@@ -490,9 +644,18 @@
 
 	phwi_ctrlr = phba->phwi_ctrlr;
 	pwrb_context = &phwi_ctrlr->wrb_context[cid];
-	pwrb_handle = pwrb_context->pwrb_handle_base[index];
-	pwrb_handle->wrb_index = index;
-	pwrb_handle->nxt_wrb_index = index;
+	if (pwrb_context->wrb_handles_available) {
+		pwrb_handle = pwrb_context->pwrb_handle_base[
+					    pwrb_context->alloc_index];
+		pwrb_context->wrb_handles_available--;
+		pwrb_handle->nxt_wrb_index = pwrb_handle->wrb_index;
+		if (pwrb_context->alloc_index ==
+						(phba->params.wrbs_per_cxn - 1))
+			pwrb_context->alloc_index = 0;
+		else
+			pwrb_context->alloc_index++;
+	} else
+		pwrb_handle = NULL;
 	return pwrb_handle;
 }
 
@@ -508,11 +671,20 @@
 free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context,
 		struct wrb_handle *pwrb_handle)
 {
+	if (!ring_mode)
+		pwrb_context->pwrb_handle_base[pwrb_context->free_index] =
+					       pwrb_handle;
+	pwrb_context->wrb_handles_available++;
+	if (pwrb_context->free_index == (phba->params.wrbs_per_cxn - 1))
+		pwrb_context->free_index = 0;
+	else
+		pwrb_context->free_index++;
+
 	SE_DEBUG(DBG_LVL_8,
-		 "FREE WRB: pwrb_handle=%p free_index=%d=0x%x"
+		 "FREE WRB: pwrb_handle=%p free_index=0x%x"
 		 "wrb_handles_available=%d \n",
 		 pwrb_handle, pwrb_context->free_index,
-		 pwrb_context->free_index, pwrb_context->wrb_handles_available);
+		 pwrb_context->wrb_handles_available);
 }
 
 static struct sgl_handle *alloc_mgmt_sgl_handle(struct beiscsi_hba *phba)
@@ -540,6 +712,8 @@
 free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)
 {
 
+	SE_DEBUG(DBG_LVL_8, "In  free_mgmt_sgl_handle,eh_sgl_free_index=%d \n",
+			     phba->eh_sgl_free_index);
 	if (phba->eh_sgl_hndl_base[phba->eh_sgl_free_index]) {
 		/*
 		 * this can happen if clean_task is called on a task that
@@ -572,10 +746,10 @@
 	u32 resid = 0, exp_cmdsn, max_cmdsn;
 	u8 rsp, status, flags;
 
-	exp_cmdsn = be32_to_cpu(psol->
+	exp_cmdsn = (psol->
 			dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32]
 			& SOL_EXP_CMD_SN_MASK);
-	max_cmdsn = be32_to_cpu((psol->
+	max_cmdsn = ((psol->
 			dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32]
 			& SOL_EXP_CMD_SN_MASK) +
 			((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
@@ -610,9 +784,9 @@
 	}
 
 	if (status == SAM_STAT_CHECK_CONDITION) {
+		unsigned short *slen = (unsigned short *)sts_bhs->sense_info;
 		sense = sts_bhs->sense_info + sizeof(unsigned short);
-		sense_len =
-		    cpu_to_be16((unsigned short)(sts_bhs->sense_info[0]));
+		sense_len =  cpu_to_be16(*slen);
 		memcpy(task->sc->sense_buffer, sense,
 		       min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE));
 	}
@@ -620,8 +794,8 @@
 		if (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32]
 							& SOL_RES_CNT_MASK)
 			 conn->rxdata_octets += (psol->
-			      dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32]
-							& SOL_RES_CNT_MASK);
+			     dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32]
+			     & SOL_RES_CNT_MASK);
 	}
 unmap:
 	scsi_dma_unmap(io_task->scsi_cmnd);
@@ -633,6 +807,7 @@
 		   struct iscsi_task *task, struct sol_cqe *psol)
 {
 	struct iscsi_logout_rsp *hdr;
+	struct beiscsi_io_task *io_task = task->dd_data;
 	struct iscsi_conn *conn = beiscsi_conn->conn;
 
 	hdr = (struct iscsi_logout_rsp *)task->hdr;
@@ -651,7 +826,7 @@
 			((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
 					/ 32] & SOL_CMD_WND_MASK) >> 24) - 1);
 	hdr->hlength = 0;
-
+	hdr->itt = io_task->libiscsi_itt;
 	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
 }
 
@@ -661,6 +836,7 @@
 {
 	struct iscsi_tm_rsp *hdr;
 	struct iscsi_conn *conn = beiscsi_conn->conn;
+	struct beiscsi_io_task *io_task = task->dd_data;
 
 	hdr = (struct iscsi_tm_rsp *)task->hdr;
 	hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32]
@@ -668,11 +844,12 @@
 	hdr->response = (psol->dw[offsetof(struct amap_sol_cqe, i_resp) /
 					32] & SOL_RESP_MASK);
 	hdr->exp_cmdsn = cpu_to_be32(psol->dw[offsetof(struct amap_sol_cqe,
-				     i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK);
+				    i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK);
 	hdr->max_cmdsn = be32_to_cpu((psol->dw[offsetof(struct amap_sol_cqe,
 			i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK) +
 			((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
 			/ 32] & SOL_CMD_WND_MASK) >> 24) - 1);
+	hdr->itt = io_task->libiscsi_itt;
 	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
 }
 
@@ -681,18 +858,36 @@
 		       struct beiscsi_hba *phba, struct sol_cqe *psol)
 {
 	struct hwi_wrb_context *pwrb_context;
-	struct wrb_handle *pwrb_handle;
+	struct wrb_handle *pwrb_handle = NULL;
+	struct sgl_handle *psgl_handle = NULL;
 	struct hwi_controller *phwi_ctrlr;
+	struct iscsi_task *task;
+	struct beiscsi_io_task *io_task;
 	struct iscsi_conn *conn = beiscsi_conn->conn;
 	struct iscsi_session *session = conn->session;
 
 	phwi_ctrlr = phba->phwi_ctrlr;
-	pwrb_context = &phwi_ctrlr->wrb_context[((psol->
+	if (ring_mode) {
+		psgl_handle = phba->sgl_hndl_array[((psol->
+			      dw[offsetof(struct amap_sol_cqe_ring, icd_index) /
+				32] & SOL_ICD_INDEX_MASK) >> 6)];
+		pwrb_context = &phwi_ctrlr->wrb_context[psgl_handle->cid];
+		task = psgl_handle->task;
+		pwrb_handle = NULL;
+	} else {
+		pwrb_context = &phwi_ctrlr->wrb_context[((psol->
 				dw[offsetof(struct amap_sol_cqe, cid) / 32] &
 				SOL_CID_MASK) >> 6)];
-	pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol->
+		pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol->
 				dw[offsetof(struct amap_sol_cqe, wrb_index) /
 				32] & SOL_WRB_INDEX_MASK) >> 16)];
+		task = pwrb_handle->pio_handle;
+	}
+
+	io_task = task->dd_data;
+	spin_lock(&phba->mgmt_sgl_lock);
+	free_mgmt_sgl_handle(phba, io_task->psgl_handle);
+	spin_unlock(&phba->mgmt_sgl_lock);
 	spin_lock_bh(&session->lock);
 	free_wrb_handle(phba, pwrb_context, pwrb_handle);
 	spin_unlock_bh(&session->lock);
@@ -704,6 +899,7 @@
 {
 	struct iscsi_nopin *hdr;
 	struct iscsi_conn *conn = beiscsi_conn->conn;
+	struct beiscsi_io_task *io_task = task->dd_data;
 
 	hdr = (struct iscsi_nopin *)task->hdr;
 	hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32]
@@ -715,6 +911,7 @@
 			((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
 			/ 32] & SOL_CMD_WND_MASK) >> 24) - 1);
 	hdr->opcode = ISCSI_OP_NOOP_IN;
+	hdr->itt = io_task->libiscsi_itt;
 	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
 }
 
@@ -726,25 +923,33 @@
 	struct iscsi_wrb *pwrb = NULL;
 	struct hwi_controller *phwi_ctrlr;
 	struct iscsi_task *task;
-	struct beiscsi_io_task *io_task;
+	struct sgl_handle *psgl_handle = NULL;
+	unsigned int type;
 	struct iscsi_conn *conn = beiscsi_conn->conn;
 	struct iscsi_session *session = conn->session;
 
 	phwi_ctrlr = phba->phwi_ctrlr;
-
-	pwrb_context = &phwi_ctrlr->
-		wrb_context[((psol->dw[offsetof(struct amap_sol_cqe, cid) / 32]
-		& SOL_CID_MASK) >> 6)];
-	pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol->
+	if (ring_mode) {
+		psgl_handle = phba->sgl_hndl_array[((psol->
+			      dw[offsetof(struct amap_sol_cqe_ring, icd_index) /
+			      32] & SOL_ICD_INDEX_MASK) >> 6)];
+		task = psgl_handle->task;
+		type = psgl_handle->type;
+	} else {
+		pwrb_context = &phwi_ctrlr->
+				wrb_context[((psol->dw[offsetof
+				(struct amap_sol_cqe, cid) / 32]
+				& SOL_CID_MASK) >> 6)];
+		pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol->
 				dw[offsetof(struct amap_sol_cqe, wrb_index) /
 				32] & SOL_WRB_INDEX_MASK) >> 16)];
-
-	task = pwrb_handle->pio_handle;
-	io_task = task->dd_data;
+		task = pwrb_handle->pio_handle;
+		pwrb = pwrb_handle->pwrb;
+		type = (pwrb->dw[offsetof(struct amap_iscsi_wrb, type) / 32] &
+			 WRB_TYPE_MASK) >> 28;
+	}
 	spin_lock_bh(&session->lock);
-	pwrb = pwrb_handle->pwrb;
-	switch ((pwrb->dw[offsetof(struct amap_iscsi_wrb, type) / 32] &
-		 WRB_TYPE_MASK) >> 28) {
+	switch (type) {
 	case HWH_TYPE_IO:
 	case HWH_TYPE_IO_RD:
 		if ((task->hdr->opcode & ISCSI_OPCODE_MASK) ==
@@ -773,12 +978,21 @@
 		break;
 
 	default:
-		shost_printk(KERN_WARNING, phba->shost,
-			    "wrb_index 0x%x CID 0x%x\n",
-			    ((psol->dw[offsetof(struct amap_iscsi_wrb, type) /
-					32] & SOL_WRB_INDEX_MASK) >> 16),
-			    ((psol->dw[offsetof(struct amap_sol_cqe, cid) / 32]
-					& SOL_CID_MASK) >> 6));
+		if (ring_mode)
+			shost_printk(KERN_WARNING, phba->shost,
+				"In hwi_complete_cmd, unknown type = %d"
+				"icd_index 0x%x CID 0x%x\n", type,
+				((psol->dw[offsetof(struct amap_sol_cqe_ring,
+				icd_index) / 32] & SOL_ICD_INDEX_MASK) >> 6),
+				psgl_handle->cid);
+		else
+			shost_printk(KERN_WARNING, phba->shost,
+				"In hwi_complete_cmd, unknown type = %d"
+				"wrb_index 0x%x CID 0x%x\n", type,
+				((psol->dw[offsetof(struct amap_iscsi_wrb,
+				type) / 32] & SOL_WRB_INDEX_MASK) >> 16),
+				((psol->dw[offsetof(struct amap_sol_cqe,
+				cid) / 32] & SOL_CID_MASK) >> 6));
 		break;
 	}
 
@@ -1208,40 +1422,55 @@
 	hwi_post_async_buffers(phba, pasync_handle->is_header);
 }
 
-static unsigned int beiscsi_process_cq(struct beiscsi_hba *phba)
+
+static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
 {
-	struct hwi_controller *phwi_ctrlr;
-	struct hwi_context_memory *phwi_context;
 	struct be_queue_info *cq;
 	struct sol_cqe *sol;
 	struct dmsg_cqe *dmsg;
 	unsigned int num_processed = 0;
 	unsigned int tot_nump = 0;
 	struct beiscsi_conn *beiscsi_conn;
+	struct sgl_handle *psgl_handle = NULL;
+	struct beiscsi_hba *phba;
 
-	phwi_ctrlr = phba->phwi_ctrlr;
-	phwi_context = phwi_ctrlr->phwi_ctxt;
-	cq = &phwi_context->be_cq;
+	cq = pbe_eq->cq;
 	sol = queue_tail_node(cq);
+	phba = pbe_eq->phba;
 
 	while (sol->dw[offsetof(struct amap_sol_cqe, valid) / 32] &
 	       CQE_VALID_MASK) {
 		be_dws_le_to_cpu(sol, sizeof(struct sol_cqe));
 
-		beiscsi_conn = phba->conn_table[(u32) (sol->
+		if (ring_mode) {
+			psgl_handle = phba->sgl_hndl_array[((sol->
+				      dw[offsetof(struct amap_sol_cqe_ring,
+				      icd_index) / 32] & SOL_ICD_INDEX_MASK)
+				      >> 6)];
+			beiscsi_conn = phba->conn_table[psgl_handle->cid];
+			if (!beiscsi_conn || !beiscsi_conn->ep) {
+				shost_printk(KERN_WARNING, phba->shost,
+				     "Connection table empty for cid = %d\n",
+				      psgl_handle->cid);
+				return 0;
+			}
+
+		} else {
+			beiscsi_conn = phba->conn_table[(u32) (sol->
 				 dw[offsetof(struct amap_sol_cqe, cid) / 32] &
 				 SOL_CID_MASK) >> 6];
 
-		if (!beiscsi_conn || !beiscsi_conn->ep) {
-			shost_printk(KERN_WARNING, phba->shost,
+			if (!beiscsi_conn || !beiscsi_conn->ep) {
+				shost_printk(KERN_WARNING, phba->shost,
 				     "Connection table empty for cid = %d\n",
 				     (u32)(sol->dw[offsetof(struct amap_sol_cqe,
 				     cid) / 32] & SOL_CID_MASK) >> 6);
-			return 0;
+				return 0;
+			}
 		}
 
 		if (num_processed >= 32) {
-			hwi_ring_cq_db(phba, phwi_context->be_cq.id,
+			hwi_ring_cq_db(phba, cq->id,
 					num_processed, 0, 0);
 			tot_nump += num_processed;
 			num_processed = 0;
@@ -1258,8 +1487,12 @@
 			hwi_complete_drvr_msgs(beiscsi_conn, phba, sol);
 			break;
 		case UNSOL_HDR_NOTIFY:
+			SE_DEBUG(DBG_LVL_8, "Received UNSOL_HDR_ NOTIFY\n");
+			hwi_process_default_pdu_ring(beiscsi_conn, phba,
+					     (struct i_t_dpdu_cqe *)sol);
+			break;
 		case UNSOL_DATA_NOTIFY:
-			SE_DEBUG(DBG_LVL_8, "Received UNSOL_HDR/DATA_NOTIFY\n");
+			SE_DEBUG(DBG_LVL_8, "Received UNSOL_DATA_NOTIFY\n");
 			hwi_process_default_pdu_ring(beiscsi_conn, phba,
 					     (struct i_t_dpdu_cqe *)sol);
 			break;
@@ -1278,13 +1511,21 @@
 		case CMD_CXN_KILLED_ITT_INVALID:
 		case CMD_CXN_KILLED_SEQ_OUTOFORDER:
 		case CMD_CXN_KILLED_INVALID_DATASN_RCVD:
-			SE_DEBUG(DBG_LVL_1,
+			if (ring_mode) {
+				SE_DEBUG(DBG_LVL_1,
+				 "CQ Error notification for cmd.. "
+				 "code %d cid 0x%x\n",
+				 sol->dw[offsetof(struct amap_sol_cqe, code) /
+				 32] & CQE_CODE_MASK, psgl_handle->cid);
+			} else {
+				SE_DEBUG(DBG_LVL_1,
 				 "CQ Error notification for cmd.. "
 				 "code %d cid 0x%x\n",
 				 sol->dw[offsetof(struct amap_sol_cqe, code) /
 				 32] & CQE_CODE_MASK,
 				 (sol->dw[offsetof(struct amap_sol_cqe, cid) /
 				 32] & SOL_CID_MASK));
+			}
 			break;
 		case UNSOL_DATA_DIGEST_ERROR_NOTIFY:
 			SE_DEBUG(DBG_LVL_1,
@@ -1306,23 +1547,37 @@
 		case CXN_KILLED_OVER_RUN_RESIDUAL:
 		case CXN_KILLED_UNDER_RUN_RESIDUAL:
 		case CXN_KILLED_CMND_DATA_NOT_ON_SAME_CONN:
-			SE_DEBUG(DBG_LVL_1, "CQ Error %d, resetting CID "
+			if (ring_mode) {
+				SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset CID "
+				 "0x%x...\n",
+				 sol->dw[offsetof(struct amap_sol_cqe, code) /
+				 32] & CQE_CODE_MASK, psgl_handle->cid);
+			} else {
+				SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset CID "
 				 "0x%x...\n",
 				 sol->dw[offsetof(struct amap_sol_cqe, code) /
 				 32] & CQE_CODE_MASK,
 				 sol->dw[offsetof(struct amap_sol_cqe, cid) /
 				 32] & CQE_CID_MASK);
+			}
 			iscsi_conn_failure(beiscsi_conn->conn,
 					   ISCSI_ERR_CONN_FAILED);
 			break;
 		case CXN_KILLED_RST_SENT:
 		case CXN_KILLED_RST_RCVD:
-			SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset received/sent "
-				 "on CID 0x%x...\n",
+			if (ring_mode) {
+				SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset"
+				"received/sent on CID 0x%x...\n",
+				 sol->dw[offsetof(struct amap_sol_cqe, code) /
+				 32] & CQE_CODE_MASK, psgl_handle->cid);
+			} else {
+				SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset"
+				"received/sent on CID 0x%x...\n",
 				 sol->dw[offsetof(struct amap_sol_cqe, code) /
 				 32] & CQE_CODE_MASK,
 				 sol->dw[offsetof(struct amap_sol_cqe, cid) /
 				 32] & CQE_CID_MASK);
+			}
 			iscsi_conn_failure(beiscsi_conn->conn,
 					   ISCSI_ERR_CONN_FAILED);
 			break;
@@ -1344,8 +1599,7 @@
 
 	if (num_processed > 0) {
 		tot_nump += num_processed;
-		hwi_ring_cq_db(phba, phwi_context->be_cq.id, num_processed,
-			       1, 0);
+		hwi_ring_cq_db(phba, cq->id, num_processed, 1, 0);
 	}
 	return tot_nump;
 }
@@ -1353,21 +1607,30 @@
 static void beiscsi_process_all_cqs(struct work_struct *work)
 {
 	unsigned long flags;
+	struct hwi_controller *phwi_ctrlr;
+	struct hwi_context_memory *phwi_context;
+	struct be_eq_obj *pbe_eq;
 	struct beiscsi_hba *phba =
 	    container_of(work, struct beiscsi_hba, work_cqs);
 
+	phwi_ctrlr = phba->phwi_ctrlr;
+	phwi_context = phwi_ctrlr->phwi_ctxt;
+	if (phba->msix_enabled)
+		pbe_eq = &phwi_context->be_eq[phba->num_cpus];
+	else
+		pbe_eq = &phwi_context->be_eq[0];
+
 	if (phba->todo_mcc_cq) {
 		spin_lock_irqsave(&phba->isr_lock, flags);
 		phba->todo_mcc_cq = 0;
 		spin_unlock_irqrestore(&phba->isr_lock, flags);
-		SE_DEBUG(DBG_LVL_1, "MCC Interrupt Not expected \n");
 	}
 
 	if (phba->todo_cq) {
 		spin_lock_irqsave(&phba->isr_lock, flags);
 		phba->todo_cq = 0;
 		spin_unlock_irqrestore(&phba->isr_lock, flags);
-		beiscsi_process_cq(phba);
+		beiscsi_process_cq(pbe_eq);
 	}
 }
 
@@ -1375,19 +1638,15 @@
 {
 	static unsigned int ret;
 	struct beiscsi_hba *phba;
+	struct be_eq_obj *pbe_eq;
 
-	phba = container_of(iop, struct beiscsi_hba, iopoll);
-
-	ret = beiscsi_process_cq(phba);
+	pbe_eq = container_of(iop, struct be_eq_obj, iopoll);
+	ret = beiscsi_process_cq(pbe_eq);
 	if (ret < budget) {
-		struct hwi_controller *phwi_ctrlr;
-		struct hwi_context_memory *phwi_context;
-
-		phwi_ctrlr = phba->phwi_ctrlr;
-		phwi_context = phwi_ctrlr->phwi_ctxt;
+		phba = pbe_eq->phba;
 		blk_iopoll_complete(iop);
-		hwi_ring_eq_db(phba, phwi_context->be_eq.q.id, 0,
-							0, 1, 1);
+		SE_DEBUG(DBG_LVL_8, "rearm pbe_eq->q.id =%d\n", pbe_eq->q.id);
+		hwi_ring_eq_db(phba, pbe_eq->q.id, 0, 0, 1, 1);
 	}
 	return ret;
 }
@@ -1537,14 +1796,12 @@
 
 static void beiscsi_find_mem_req(struct beiscsi_hba *phba)
 {
-	unsigned int num_cq_pages, num_eq_pages, num_async_pdu_buf_pages;
+	unsigned int num_cq_pages, num_async_pdu_buf_pages;
 	unsigned int num_async_pdu_data_pages, wrb_sz_per_cxn;
 	unsigned int num_async_pdu_buf_sgl_pages, num_async_pdu_data_sgl_pages;
 
 	num_cq_pages = PAGES_REQUIRED(phba->params.num_cq_entries * \
 				      sizeof(struct sol_cqe));
-	num_eq_pages = PAGES_REQUIRED(phba->params.num_eq_entries * \
-				      sizeof(struct be_eq_entry));
 	num_async_pdu_buf_pages =
 			PAGES_REQUIRED(phba->params.asyncpdus_per_ctrl * \
 				       phba->params.defpdu_hdr_sz);
@@ -1565,8 +1822,6 @@
 	phba->mem_req[HWI_MEM_ADDN_CONTEXT] =
 					    sizeof(struct hwi_context_memory);
 
-	phba->mem_req[HWI_MEM_CQ] = num_cq_pages * PAGE_SIZE;
-	phba->mem_req[HWI_MEM_EQ] = num_eq_pages * PAGE_SIZE;
 
 	phba->mem_req[HWI_MEM_WRB] = sizeof(struct iscsi_wrb)
 	    * (phba->params.wrbs_per_cxn)
@@ -1751,8 +2006,6 @@
 
 	for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) {
 		pwrb_context = &phwi_ctrlr->wrb_context[index];
-		SE_DEBUG(DBG_LVL_8, "cid=%d pwrb_context=%p \n", index,
-						pwrb_context);
 		pwrb_context->pwrb_handle_base =
 				kzalloc(sizeof(struct wrb_handle *) *
 					phba->params.wrbs_per_cxn, GFP_KERNEL);
@@ -1767,6 +2020,7 @@
 				pwrb_context->pwrb_handle_basestd[j] =
 								pwrb_handle;
 				pwrb_context->wrb_handles_available++;
+				pwrb_handle->wrb_index = j;
 				pwrb_handle++;
 			}
 			pwrb_context->free_index = 0;
@@ -1785,6 +2039,7 @@
 				pwrb_context->pwrb_handle_basestd[j] =
 				    pwrb_handle;
 				pwrb_context->wrb_handles_available++;
+				pwrb_handle->wrb_index = j;
 				pwrb_handle++;
 			}
 			pwrb_context->free_index = 0;
@@ -2042,79 +2297,126 @@
 	return 0;
 }
 
-static int beiscsi_create_eq(struct beiscsi_hba *phba,
+static int beiscsi_create_eqs(struct beiscsi_hba *phba,
 			     struct hwi_context_memory *phwi_context)
 {
-	unsigned int idx;
-	int ret;
+	unsigned int i, num_eq_pages;
+	int ret, eq_for_mcc;
 	struct be_queue_info *eq;
 	struct be_dma_mem *mem;
-	struct be_mem_descriptor *mem_descr;
 	void *eq_vaddress;
+	dma_addr_t paddr;
 
-	idx = 0;
-	eq = &phwi_context->be_eq.q;
-	mem = &eq->dma_mem;
-	mem_descr = phba->init_mem;
-	mem_descr += HWI_MEM_EQ;
-	eq_vaddress = mem_descr->mem_array[idx].virtual_address;
+	num_eq_pages = PAGES_REQUIRED(phba->params.num_eq_entries * \
+				      sizeof(struct be_eq_entry));
 
-	ret = be_fill_queue(eq, phba->params.num_eq_entries,
-			    sizeof(struct be_eq_entry), eq_vaddress);
-	if (ret) {
-		shost_printk(KERN_ERR, phba->shost,
-			     "be_fill_queue Failed for EQ \n");
-		return ret;
+	if (phba->msix_enabled)
+		eq_for_mcc = 1;
+	else
+		eq_for_mcc = 0;
+	for (i = 0; i < (phba->num_cpus + eq_for_mcc); i++) {
+		eq = &phwi_context->be_eq[i].q;
+		mem = &eq->dma_mem;
+		phwi_context->be_eq[i].phba = phba;
+		eq_vaddress = pci_alloc_consistent(phba->pcidev,
+						     num_eq_pages * PAGE_SIZE,
+						     &paddr);
+		if (!eq_vaddress)
+			goto create_eq_error;
+
+		mem->va = eq_vaddress;
+		ret = be_fill_queue(eq, phba->params.num_eq_entries,
+				    sizeof(struct be_eq_entry), eq_vaddress);
+		if (ret) {
+			shost_printk(KERN_ERR, phba->shost,
+				     "be_fill_queue Failed for EQ \n");
+			goto create_eq_error;
+		}
+
+		mem->dma = paddr;
+		ret = beiscsi_cmd_eq_create(&phba->ctrl, eq,
+					    phwi_context->cur_eqd);
+		if (ret) {
+			shost_printk(KERN_ERR, phba->shost,
+				     "beiscsi_cmd_eq_create"
+				     "Failedfor EQ \n");
+			goto create_eq_error;
+		}
+		SE_DEBUG(DBG_LVL_8, "eqid = %d\n", phwi_context->be_eq[i].q.id);
 	}
-
-	mem->dma = mem_descr->mem_array[idx].bus_address.u.a64.address;
-
-	ret = beiscsi_cmd_eq_create(&phba->ctrl, eq,
-				    phwi_context->be_eq.cur_eqd);
-	if (ret) {
-		shost_printk(KERN_ERR, phba->shost, "beiscsi_cmd_eq_create"
-			     "Failedfor EQ \n");
-		return ret;
-	}
-	SE_DEBUG(DBG_LVL_8, "eq id is %d\n", phwi_context->be_eq.q.id);
 	return 0;
+create_eq_error:
+	for (i = 0; i < (phba->num_cpus + 1); i++) {
+		eq = &phwi_context->be_eq[i].q;
+		mem = &eq->dma_mem;
+		if (mem->va)
+			pci_free_consistent(phba->pcidev, num_eq_pages
+					    * PAGE_SIZE,
+					    mem->va, mem->dma);
+	}
+	return ret;
 }
 
-static int beiscsi_create_cq(struct beiscsi_hba *phba,
+static int beiscsi_create_cqs(struct beiscsi_hba *phba,
 			     struct hwi_context_memory *phwi_context)
 {
-	unsigned int idx;
+	unsigned int i, num_cq_pages;
 	int ret;
 	struct be_queue_info *cq, *eq;
 	struct be_dma_mem *mem;
-	struct be_mem_descriptor *mem_descr;
+	struct be_eq_obj *pbe_eq;
 	void *cq_vaddress;
+	dma_addr_t paddr;
 
-	idx = 0;
-	cq = &phwi_context->be_cq;
-	eq = &phwi_context->be_eq.q;
-	mem = &cq->dma_mem;
-	mem_descr = phba->init_mem;
-	mem_descr += HWI_MEM_CQ;
-	cq_vaddress = mem_descr->mem_array[idx].virtual_address;
-	ret = be_fill_queue(cq, phba->params.icds_per_ctrl / 2,
-			    sizeof(struct sol_cqe), cq_vaddress);
-	if (ret) {
-		shost_printk(KERN_ERR, phba->shost,
-			     "be_fill_queue Failed for ISCSI CQ \n");
-		return ret;
-	}
+	num_cq_pages = PAGES_REQUIRED(phba->params.num_cq_entries * \
+				      sizeof(struct sol_cqe));
 
-	mem->dma = mem_descr->mem_array[idx].bus_address.u.a64.address;
-	ret = beiscsi_cmd_cq_create(&phba->ctrl, cq, eq, false, false, 0);
-	if (ret) {
-		shost_printk(KERN_ERR, phba->shost,
-			     "beiscsi_cmd_eq_create Failed for ISCSI CQ \n");
-		return ret;
+	for (i = 0; i < phba->num_cpus; i++) {
+		cq = &phwi_context->be_cq[i];
+		eq = &phwi_context->be_eq[i].q;
+		pbe_eq = &phwi_context->be_eq[i];
+		pbe_eq->cq = cq;
+		pbe_eq->phba = phba;
+		mem = &cq->dma_mem;
+		cq_vaddress = pci_alloc_consistent(phba->pcidev,
+						     num_cq_pages * PAGE_SIZE,
+						     &paddr);
+		if (!cq_vaddress)
+			goto create_cq_error;
+		ret = be_fill_queue(cq, phba->params.icds_per_ctrl / 2,
+				    sizeof(struct sol_cqe), cq_vaddress);
+		if (ret) {
+			shost_printk(KERN_ERR, phba->shost,
+				     "be_fill_queue Failed for ISCSI CQ \n");
+			goto create_cq_error;
+		}
+
+		mem->dma = paddr;
+		ret = beiscsi_cmd_cq_create(&phba->ctrl, cq, eq, false,
+					    false, 0);
+		if (ret) {
+			shost_printk(KERN_ERR, phba->shost,
+				     "beiscsi_cmd_eq_create"
+				     "Failed for ISCSI CQ \n");
+			goto create_cq_error;
+		}
+		SE_DEBUG(DBG_LVL_8, "iscsi cq_id is %d for eq_id %d\n",
+						 cq->id, eq->id);
+		SE_DEBUG(DBG_LVL_8, "ISCSI CQ CREATED\n");
 	}
-	SE_DEBUG(DBG_LVL_8, "iscsi cq id is %d\n", phwi_context->be_cq.id);
-	SE_DEBUG(DBG_LVL_8, "ISCSI CQ CREATED\n");
 	return 0;
+
+create_cq_error:
+	for (i = 0; i < phba->num_cpus; i++) {
+		cq = &phwi_context->be_cq[i];
+		mem = &cq->dma_mem;
+		if (mem->va)
+			pci_free_consistent(phba->pcidev, num_cq_pages
+					    * PAGE_SIZE,
+					    mem->va, mem->dma);
+	}
+	return ret;
+
 }
 
 static int
@@ -2132,7 +2434,7 @@
 
 	idx = 0;
 	dq = &phwi_context->be_def_hdrq;
-	cq = &phwi_context->be_cq;
+	cq = &phwi_context->be_cq[0];
 	mem = &dq->dma_mem;
 	mem_descr = phba->init_mem;
 	mem_descr += HWI_MEM_ASYNC_HEADER_RING;
@@ -2176,7 +2478,7 @@
 
 	idx = 0;
 	dataq = &phwi_context->be_def_dataq;
-	cq = &phwi_context->be_cq;
+	cq = &phwi_context->be_cq[0];
 	mem = &dataq->dma_mem;
 	mem_descr = phba->init_mem;
 	mem_descr += HWI_MEM_ASYNC_DATA_RING;
@@ -2239,6 +2541,30 @@
 	return 0;
 }
 
+static void be_queue_free(struct beiscsi_hba *phba, struct be_queue_info *q)
+{
+	struct be_dma_mem *mem = &q->dma_mem;
+	if (mem->va)
+		pci_free_consistent(phba->pcidev, mem->size,
+			mem->va, mem->dma);
+}
+
+static int be_queue_alloc(struct beiscsi_hba *phba, struct be_queue_info *q,
+		u16 len, u16 entry_size)
+{
+	struct be_dma_mem *mem = &q->dma_mem;
+
+	memset(q, 0, sizeof(*q));
+	q->len = len;
+	q->entry_size = entry_size;
+	mem->size = len * entry_size;
+	mem->va = pci_alloc_consistent(phba->pcidev, mem->size, &mem->dma);
+	if (!mem->va)
+		return -1;
+	memset(mem->va, 0, mem->size);
+	return 0;
+}
+
 static int
 beiscsi_create_wrb_rings(struct beiscsi_hba *phba,
 			 struct hwi_context_memory *phwi_context,
@@ -2328,13 +2654,29 @@
 	}
 }
 
+static void be_mcc_queues_destroy(struct beiscsi_hba *phba)
+{
+	struct be_queue_info *q;
+	struct be_ctrl_info *ctrl = &phba->ctrl;
+
+	q = &phba->ctrl.mcc_obj.q;
+	if (q->created)
+		beiscsi_cmd_q_destroy(ctrl, q, QTYPE_MCCQ);
+	be_queue_free(phba, q);
+
+	q = &phba->ctrl.mcc_obj.cq;
+	if (q->created)
+		beiscsi_cmd_q_destroy(ctrl, q, QTYPE_CQ);
+	be_queue_free(phba, q);
+}
+
 static void hwi_cleanup(struct beiscsi_hba *phba)
 {
 	struct be_queue_info *q;
 	struct be_ctrl_info *ctrl = &phba->ctrl;
 	struct hwi_controller *phwi_ctrlr;
 	struct hwi_context_memory *phwi_context;
-	int i;
+	int i, eq_num;
 
 	phwi_ctrlr = phba->phwi_ctrlr;
 	phwi_context = phwi_ctrlr->phwi_ctxt;
@@ -2343,7 +2685,6 @@
 		if (q->created)
 			beiscsi_cmd_q_destroy(ctrl, q, QTYPE_WRBQ);
 	}
-
 	free_wrb_handles(phba);
 
 	q = &phwi_context->be_def_hdrq;
@@ -2356,13 +2697,76 @@
 
 	beiscsi_cmd_q_destroy(ctrl, NULL, QTYPE_SGL);
 
-	q = &phwi_context->be_cq;
-	if (q->created)
-		beiscsi_cmd_q_destroy(ctrl, q, QTYPE_CQ);
+	for (i = 0; i < (phba->num_cpus); i++) {
+		q = &phwi_context->be_cq[i];
+		if (q->created)
+			beiscsi_cmd_q_destroy(ctrl, q, QTYPE_CQ);
+	}
+	if (phba->msix_enabled)
+		eq_num = 1;
+	else
+		eq_num = 0;
+	for (i = 0; i < (phba->num_cpus + eq_num); i++) {
+		q = &phwi_context->be_eq[i].q;
+		if (q->created)
+			beiscsi_cmd_q_destroy(ctrl, q, QTYPE_EQ);
+	}
+	be_mcc_queues_destroy(phba);
+}
 
-	q = &phwi_context->be_eq.q;
-	if (q->created)
-		beiscsi_cmd_q_destroy(ctrl, q, QTYPE_EQ);
+static int be_mcc_queues_create(struct beiscsi_hba *phba,
+				struct hwi_context_memory *phwi_context)
+{
+	struct be_queue_info *q, *cq;
+	struct be_ctrl_info *ctrl = &phba->ctrl;
+
+	/* Alloc MCC compl queue */
+	cq = &phba->ctrl.mcc_obj.cq;
+	if (be_queue_alloc(phba, cq, MCC_CQ_LEN,
+			sizeof(struct be_mcc_compl)))
+		goto err;
+	/* Ask BE to create MCC compl queue; */
+	if (phba->msix_enabled) {
+		if (beiscsi_cmd_cq_create(ctrl, cq, &phwi_context->be_eq
+					 [phba->num_cpus].q, false, true, 0))
+		goto mcc_cq_free;
+	} else {
+		if (beiscsi_cmd_cq_create(ctrl, cq, &phwi_context->be_eq[0].q,
+					  false, true, 0))
+		goto mcc_cq_free;
+	}
+
+	/* Alloc MCC queue */
+	q = &phba->ctrl.mcc_obj.q;
+	if (be_queue_alloc(phba, q, MCC_Q_LEN, sizeof(struct be_mcc_wrb)))
+		goto mcc_cq_destroy;
+
+	/* Ask BE to create MCC queue */
+	if (beiscsi_cmd_mccq_create(phba, q, cq))
+		goto mcc_q_free;
+
+	return 0;
+
+mcc_q_free:
+	be_queue_free(phba, q);
+mcc_cq_destroy:
+	beiscsi_cmd_q_destroy(ctrl, cq, QTYPE_CQ);
+mcc_cq_free:
+	be_queue_free(phba, cq);
+err:
+	return -1;
+}
+
+static int find_num_cpus(void)
+{
+	int  num_cpus = 0;
+
+	num_cpus = num_online_cpus();
+	if (num_cpus >= MAX_CPUS)
+		num_cpus = MAX_CPUS - 1;
+
+	SE_DEBUG(DBG_LVL_8, "num_cpus = %d \n", num_cpus);
+	return num_cpus;
 }
 
 static int hwi_init_port(struct beiscsi_hba *phba)
@@ -2376,26 +2780,33 @@
 	def_pdu_ring_sz =
 		phba->params.asyncpdus_per_ctrl * sizeof(struct phys_addr);
 	phwi_ctrlr = phba->phwi_ctrlr;
-
 	phwi_context = phwi_ctrlr->phwi_ctxt;
-	phwi_context->be_eq.max_eqd = 0;
-	phwi_context->be_eq.min_eqd = 0;
-	phwi_context->be_eq.cur_eqd = 64;
-	phwi_context->be_eq.enable_aic = false;
+	phwi_context->max_eqd = 0;
+	phwi_context->min_eqd = 0;
+	phwi_context->cur_eqd = 64;
 	be_cmd_fw_initialize(&phba->ctrl);
-	status = beiscsi_create_eq(phba, phwi_context);
+
+	status = beiscsi_create_eqs(phba, phwi_context);
 	if (status != 0) {
 		shost_printk(KERN_ERR, phba->shost, "EQ not created \n");
 		goto error;
 	}
 
-	status = mgmt_check_supported_fw(ctrl);
+	status = be_mcc_queues_create(phba, phwi_context);
+	if (status != 0)
+		goto error;
+
+	status = mgmt_check_supported_fw(ctrl, phba);
 	if (status != 0) {
 		shost_printk(KERN_ERR, phba->shost,
 			     "Unsupported fw version \n");
 		goto error;
 	}
 
+	if (phba->fw_config.iscsi_features == 0x1)
+		ring_mode = 1;
+	else
+		ring_mode = 0;
 	status = mgmt_get_fw_config(ctrl, phba);
 	if (status != 0) {
 		shost_printk(KERN_ERR, phba->shost,
@@ -2403,7 +2814,7 @@
 		goto error;
 	}
 
-	status = beiscsi_create_cq(phba, phwi_context);
+	status = beiscsi_create_cqs(phba, phwi_context);
 	if (status != 0) {
 		shost_printk(KERN_ERR, phba->shost, "CQ not created\n");
 		goto error;
@@ -2447,7 +2858,6 @@
 	return -ENOMEM;
 }
 
-
 static int hwi_init_controller(struct beiscsi_hba *phba)
 {
 	struct hwi_controller *phwi_ctrlr;
@@ -2530,6 +2940,18 @@
 
 	phba->io_sgl_hndl_avbl = 0;
 	phba->eh_sgl_hndl_avbl = 0;
+
+	if (ring_mode) {
+		phba->sgl_hndl_array = kzalloc(sizeof(struct sgl_handle *) *
+					      phba->params.icds_per_ctrl,
+						 GFP_KERNEL);
+		if (!phba->sgl_hndl_array) {
+			shost_printk(KERN_ERR, phba->shost,
+			     "Mem Alloc Failed. Failing to load\n");
+			return -ENOMEM;
+		}
+	}
+
 	mem_descr_sglh = phba->init_mem;
 	mem_descr_sglh += HWI_MEM_SGLH;
 	if (1 == mem_descr_sglh->num_elements) {
@@ -2537,6 +2959,8 @@
 						 phba->params.ios_per_ctrl,
 						 GFP_KERNEL);
 		if (!phba->io_sgl_hndl_base) {
+			if (ring_mode)
+				kfree(phba->sgl_hndl_array);
 			shost_printk(KERN_ERR, phba->shost,
 				     "Mem Alloc Failed. Failing to load\n");
 			return -ENOMEM;
@@ -2656,13 +3080,12 @@
 	struct hwi_context_memory *phwi_context;
 	struct be_queue_info *eq;
 	u8 __iomem *addr;
-	u32 reg;
+	u32 reg, i;
 	u32 enabled;
 
 	phwi_ctrlr = phba->phwi_ctrlr;
 	phwi_context = phwi_ctrlr->phwi_ctxt;
 
-	eq = &phwi_context->be_eq.q;
 	addr = (u8 __iomem *) ((u8 __iomem *) ctrl->pcicfg +
 			PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET);
 	reg = ioread32(addr);
@@ -2673,9 +3096,11 @@
 		reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
 		SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p \n", reg, addr);
 		iowrite32(reg, addr);
-		SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id);
-
-		hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
+		for (i = 0; i <= phba->num_cpus; i++) {
+			eq = &phwi_context->be_eq[i].q;
+			SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id);
+			hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
+		}
 	} else
 		shost_printk(KERN_WARNING, phba->shost,
 			     "In hwi_enable_intr, Not Enabled \n");
@@ -2720,6 +3145,8 @@
 	if (hba_setup_cid_tbls(phba)) {
 		shost_printk(KERN_ERR, phba->shost,
 			     "Failed in hba_setup_cid_tbls\n");
+		if (ring_mode)
+			kfree(phba->sgl_hndl_array);
 		kfree(phba->io_sgl_hndl_base);
 		kfree(phba->eh_sgl_hndl_base);
 		goto do_cleanup_ctrlr;
@@ -2738,17 +3165,25 @@
 	struct hwi_context_memory *phwi_context;
 	struct be_queue_info *eq;
 	struct be_eq_entry *eqe = NULL;
+	int i, eq_msix;
 
 	phwi_ctrlr = phba->phwi_ctrlr;
 	phwi_context = phwi_ctrlr->phwi_ctxt;
-	eq = &phwi_context->be_eq.q;
-	eqe = queue_tail_node(eq);
+	if (phba->msix_enabled)
+		eq_msix = 1;
+	else
+		eq_msix = 0;
 
-	while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
-						& EQE_VALID_MASK) {
-		AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
-		queue_tail_inc(eq);
+	for (i = 0; i < (phba->num_cpus + eq_msix); i++) {
+		eq = &phwi_context->be_eq[i].q;
 		eqe = queue_tail_node(eq);
+
+		while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
+					& EQE_VALID_MASK) {
+			AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
+			queue_tail_inc(eq);
+			eqe = queue_tail_node(eq);
+		}
 	}
 }
 
@@ -2762,6 +3197,8 @@
 			     "mgmt_epfw_cleanup FAILED \n");
 	hwi_cleanup(phba);
 	hwi_purge_eq(phba);
+	if (ring_mode)
+		kfree(phba->sgl_hndl_array);
 	kfree(phba->io_sgl_hndl_base);
 	kfree(phba->eh_sgl_hndl_base);
 	kfree(phba->cid_array);
@@ -2846,8 +3283,9 @@
 	be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_target_context_update_wrb));
 
 	doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK;
-	doorbell |= (pwrb_handle->wrb_index & DB_DEF_PDU_WRB_INDEX_MASK) <<
-					DB_DEF_PDU_WRB_INDEX_SHIFT;
+	if (!ring_mode)
+		doorbell |= (pwrb_handle->wrb_index & DB_DEF_PDU_WRB_INDEX_MASK)
+			     << DB_DEF_PDU_WRB_INDEX_SHIFT;
 	doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT;
 
 	iowrite32(doorbell, phba->db_va + DB_TXULP0_OFFSET);
@@ -2856,7 +3294,7 @@
 static void beiscsi_parse_pdu(struct iscsi_conn *conn, itt_t itt,
 			      int *index, int *age)
 {
-	*index = be32_to_cpu(itt) >> 16;
+	*index = (int)itt;
 	if (age)
 		*age = conn->session->age;
 }
@@ -2885,15 +3323,13 @@
 
 	io_task->cmd_bhs = pci_pool_alloc(beiscsi_sess->bhs_pool,
 					  GFP_KERNEL, &paddr);
-
 	if (!io_task->cmd_bhs)
 		return -ENOMEM;
-
 	io_task->bhs_pa.u.a64.address = paddr;
+	io_task->libiscsi_itt = (itt_t)task->itt;
 	io_task->pwrb_handle = alloc_wrb_handle(phba,
 						beiscsi_conn->beiscsi_conn_cid,
 						task->itt);
-	io_task->pwrb_handle->pio_handle = task;
 	io_task->conn = beiscsi_conn;
 
 	task->hdr = (struct iscsi_hdr *)&io_task->cmd_bhs->iscsi_hdr;
@@ -2905,7 +3341,6 @@
 		spin_unlock(&phba->io_sgl_lock);
 		if (!io_task->psgl_handle)
 			goto free_hndls;
-
 	} else {
 		io_task->scsi_cmnd = NULL;
 		if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN) {
@@ -2932,8 +3367,18 @@
 				goto free_hndls;
 		}
 	}
-	itt = (itt_t) cpu_to_be32(((unsigned int)task->itt << 16) |
-			(unsigned int)(io_task->psgl_handle->sgl_index));
+	itt = (itt_t) cpu_to_be32(((unsigned int)io_task->pwrb_handle->
+				 wrb_index << 16) | (unsigned int)
+				(io_task->psgl_handle->sgl_index));
+	if (ring_mode) {
+		phba->sgl_hndl_array[io_task->psgl_handle->sgl_index -
+				     phba->fw_config.iscsi_cid_start] =
+				     io_task->psgl_handle;
+		io_task->psgl_handle->task = task;
+		io_task->psgl_handle->cid = beiscsi_conn->beiscsi_conn_cid;
+	} else
+		io_task->pwrb_handle->pio_handle = task;
+
 	io_task->cmd_bhs->iscsi_hdr.itt = itt;
 	return 0;
 
@@ -3006,7 +3451,6 @@
 	io_task->bhs_len = sizeof(struct be_cmd_bhs);
 
 	if (writedir) {
-		SE_DEBUG(DBG_LVL_4, " WRITE Command \t");
 		memset(&io_task->cmd_bhs->iscsi_data_pdu, 0, 48);
 		AMAP_SET_BITS(struct amap_pdu_data_out, itt,
 			      &io_task->cmd_bhs->iscsi_data_pdu,
@@ -3016,11 +3460,18 @@
 			      ISCSI_OPCODE_SCSI_DATA_OUT);
 		AMAP_SET_BITS(struct amap_pdu_data_out, final_bit,
 			      &io_task->cmd_bhs->iscsi_data_pdu, 1);
-		AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_WR_CMD);
+		if (ring_mode)
+			io_task->psgl_handle->type = INI_WR_CMD;
+		else
+			AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
+				      INI_WR_CMD);
 		AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1);
 	} else {
-		SE_DEBUG(DBG_LVL_4, "READ Command \t");
-		AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_RD_CMD);
+		if (ring_mode)
+			io_task->psgl_handle->type = INI_RD_CMD;
+		else
+			AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
+				      INI_RD_CMD);
 		AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0);
 	}
 	memcpy(&io_task->cmd_bhs->iscsi_data_pdu.
@@ -3045,7 +3496,8 @@
 	be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb));
 
 	doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK;
-	doorbell |= (io_task->pwrb_handle->wrb_index &
+	if (!ring_mode)
+		doorbell |= (io_task->pwrb_handle->wrb_index &
 		     DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT;
 	doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT;
 
@@ -3059,10 +3511,16 @@
 	struct iscsi_conn *conn = task->conn;
 	struct beiscsi_conn *beiscsi_conn = conn->dd_data;
 	struct beiscsi_hba *phba = beiscsi_conn->phba;
+	struct iscsi_session *session;
 	struct iscsi_wrb *pwrb = NULL;
+	struct hwi_controller *phwi_ctrlr;
+	struct hwi_wrb_context *pwrb_context;
+	struct wrb_handle *pwrb_handle;
 	unsigned int doorbell = 0;
+	unsigned int i, cid;
 	struct iscsi_task *aborted_task;
 
+	cid = beiscsi_conn->beiscsi_conn_cid;
 	pwrb = io_task->pwrb_handle->pwrb;
 	AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb,
 		      be32_to_cpu(task->cmdsn));
@@ -3073,38 +3531,63 @@
 
 	switch (task->hdr->opcode & ISCSI_OPCODE_MASK) {
 	case ISCSI_OP_LOGIN:
-		AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, TGT_DM_CMD);
+		if (ring_mode)
+			io_task->psgl_handle->type = TGT_DM_CMD;
+		else
+			AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
+				      TGT_DM_CMD);
 		AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
 		AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, 1);
 		hwi_write_buffer(pwrb, task);
 		break;
 	case ISCSI_OP_NOOP_OUT:
-		AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_RD_CMD);
+		if (ring_mode)
+			io_task->psgl_handle->type = INI_RD_CMD;
+		else
+			AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
+				      INI_RD_CMD);
 		hwi_write_buffer(pwrb, task);
 		break;
 	case ISCSI_OP_TEXT:
-		AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_WR_CMD);
+		if (ring_mode)
+			io_task->psgl_handle->type = INI_WR_CMD;
+		else
+			AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
+				      INI_WR_CMD);
 		AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1);
 		hwi_write_buffer(pwrb, task);
 		break;
 	case ISCSI_OP_SCSI_TMFUNC:
-		aborted_task = iscsi_itt_to_task(conn,
-					((struct iscsi_tm *)task->hdr)->rtt);
+		session = conn->session;
+		i = ((struct iscsi_tm *)task->hdr)->rtt;
+		phwi_ctrlr = phba->phwi_ctrlr;
+		pwrb_context = &phwi_ctrlr->wrb_context[cid];
+		pwrb_handle = pwrb_context->pwrb_handle_basestd[be32_to_cpu(i)
+								>> 16];
+		aborted_task = pwrb_handle->pio_handle;
 		 if (!aborted_task)
 			return 0;
+
 		aborted_io_task = aborted_task->dd_data;
 		if (!aborted_io_task->scsi_cmnd)
 			return 0;
 
 		mgmt_invalidate_icds(phba,
 				     aborted_io_task->psgl_handle->sgl_index,
-				     beiscsi_conn->beiscsi_conn_cid);
-		AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_TMF_CMD);
+				     cid);
+		if (ring_mode)
+			io_task->psgl_handle->type = INI_TMF_CMD;
+		else
+			AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
+				      INI_TMF_CMD);
 		AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
 		hwi_write_buffer(pwrb, task);
 		break;
 	case ISCSI_OP_LOGOUT:
 		AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
+		if (ring_mode)
+			io_task->psgl_handle->type = HWH_TYPE_LOGOUT;
+		else
 		AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
 				HWH_TYPE_LOGOUT);
 		hwi_write_buffer(pwrb, task);
@@ -3122,8 +3605,9 @@
 		      io_task->pwrb_handle->nxt_wrb_index);
 	be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb));
 
-	doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK;
-	doorbell |= (io_task->pwrb_handle->wrb_index &
+	doorbell |= cid & DB_WRB_POST_CID_MASK;
+	if (!ring_mode)
+		doorbell |= (io_task->pwrb_handle->wrb_index &
 		     DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT;
 	doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT;
 	iowrite32(doorbell, phba->db_va + DB_TXULP0_OFFSET);
@@ -3165,9 +3649,14 @@
 	return beiscsi_iotask(task, sg, num_sg, xferlen, writedir);
 }
 
+
 static void beiscsi_remove(struct pci_dev *pcidev)
 {
 	struct beiscsi_hba *phba = NULL;
+	struct hwi_controller *phwi_ctrlr;
+	struct hwi_context_memory *phwi_context;
+	struct be_eq_obj *pbe_eq;
+	unsigned int i, msix_vec;
 
 	phba = (struct beiscsi_hba *)pci_get_drvdata(pcidev);
 	if (!phba) {
@@ -3175,12 +3664,24 @@
 		return;
 	}
 
+	phwi_ctrlr = phba->phwi_ctrlr;
+	phwi_context = phwi_ctrlr->phwi_ctxt;
 	hwi_disable_intr(phba);
-	if (phba->pcidev->irq)
-		free_irq(phba->pcidev->irq, phba);
+	if (phba->msix_enabled) {
+		for (i = 0; i <= phba->num_cpus; i++) {
+			msix_vec = phba->msix_entries[i].vector;
+			free_irq(msix_vec, &phwi_context->be_eq[i]);
+		}
+	} else
+		if (phba->pcidev->irq)
+			free_irq(phba->pcidev->irq, phba);
+	pci_disable_msix(phba->pcidev);
 	destroy_workqueue(phba->wq);
 	if (blk_iopoll_enabled)
-		blk_iopoll_disable(&phba->iopoll);
+		for (i = 0; i < phba->num_cpus; i++) {
+			pbe_eq = &phwi_context->be_eq[i];
+			blk_iopoll_disable(&pbe_eq->iopoll);
+		}
 
 	beiscsi_clean_port(phba);
 	beiscsi_free_mem(phba);
@@ -3194,11 +3695,29 @@
 	iscsi_host_free(phba->shost);
 }
 
+static void beiscsi_msix_enable(struct beiscsi_hba *phba)
+{
+	int i, status;
+
+	for (i = 0; i <= phba->num_cpus; i++)
+		phba->msix_entries[i].entry = i;
+
+	status = pci_enable_msix(phba->pcidev, phba->msix_entries,
+				 (phba->num_cpus + 1));
+	if (!status)
+		phba->msix_enabled = true;
+
+	return;
+}
+
 static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
 				const struct pci_device_id *id)
 {
 	struct beiscsi_hba *phba = NULL;
-	int ret;
+	struct hwi_controller *phwi_ctrlr;
+	struct hwi_context_memory *phwi_context;
+	struct be_eq_obj *pbe_eq;
+	int ret, msix_vec, num_cpus, i;
 
 	ret = beiscsi_enable_pci(pcidev);
 	if (ret < 0) {
@@ -3213,8 +3732,18 @@
 			" Failed in beiscsi_hba_alloc \n");
 		goto disable_pci;
 	}
+	SE_DEBUG(DBG_LVL_8, " phba = %p \n", phba);
 
 	pci_set_drvdata(pcidev, phba);
+	if (enable_msix)
+		num_cpus = find_num_cpus();
+	else
+		num_cpus = 1;
+	phba->num_cpus = num_cpus;
+	SE_DEBUG(DBG_LVL_8, "num_cpus = %d \n", phba->num_cpus);
+
+	if (enable_msix)
+		beiscsi_msix_enable(phba);
 	ret = be_ctrl_init(phba, pcidev);
 	if (ret) {
 		shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
@@ -3235,7 +3764,7 @@
 
 	snprintf(phba->wq_name, sizeof(phba->wq_name), "beiscsi_q_irq%u",
 		 phba->shost->host_no);
-	phba->wq = create_singlethread_workqueue(phba->wq_name);
+	phba->wq = create_workqueue(phba->wq_name);
 	if (!phba->wq) {
 		shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
 				"Failed to allocate work queue\n");
@@ -3244,11 +3773,16 @@
 
 	INIT_WORK(&phba->work_cqs, beiscsi_process_all_cqs);
 
+	phwi_ctrlr = phba->phwi_ctrlr;
+	phwi_context = phwi_ctrlr->phwi_ctxt;
 	if (blk_iopoll_enabled) {
-		blk_iopoll_init(&phba->iopoll, be_iopoll_budget, be_iopoll);
-		blk_iopoll_enable(&phba->iopoll);
+		for (i = 0; i < phba->num_cpus; i++) {
+			pbe_eq = &phwi_context->be_eq[i];
+			blk_iopoll_init(&pbe_eq->iopoll, be_iopoll_budget,
+					be_iopoll);
+			blk_iopoll_enable(&pbe_eq->iopoll);
+		}
 	}
-
 	ret = beiscsi_init_irqs(phba);
 	if (ret < 0) {
 		shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
@@ -3261,17 +3795,26 @@
 			     "Failed to hwi_enable_intr\n");
 		goto free_ctrlr;
 	}
-
 	SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED \n\n\n");
 	return 0;
 
 free_ctrlr:
-	if (phba->pcidev->irq)
-		free_irq(phba->pcidev->irq, phba);
+	if (phba->msix_enabled) {
+		for (i = 0; i <= phba->num_cpus; i++) {
+			msix_vec = phba->msix_entries[i].vector;
+			free_irq(msix_vec, &phwi_context->be_eq[i]);
+		}
+	} else
+		if (phba->pcidev->irq)
+			free_irq(phba->pcidev->irq, phba);
+	pci_disable_msix(phba->pcidev);
 free_blkenbld:
 	destroy_workqueue(phba->wq);
 	if (blk_iopoll_enabled)
-		blk_iopoll_disable(&phba->iopoll);
+		for (i = 0; i < phba->num_cpus; i++) {
+			pbe_eq = &phwi_context->be_eq[i];
+			blk_iopoll_disable(&pbe_eq->iopoll);
+		}
 free_twq:
 	beiscsi_clean_port(phba);
 	beiscsi_free_mem(phba);
@@ -3316,7 +3859,7 @@
 		ISCSI_USERNAME | ISCSI_PASSWORD |
 		ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
 		ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
-		ISCSI_LU_RESET_TMO |
+		ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO |
 		ISCSI_PING_TMO | ISCSI_RECV_TMO |
 		ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
 	.host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS |
@@ -3351,6 +3894,7 @@
 	.id_table = beiscsi_pci_id_table
 };
 
+
 static int __init beiscsi_module_init(void)
 {
 	int ret;
@@ -3373,6 +3917,7 @@
 			 "beiscsi pci driver.\n");
 		goto unregister_iscsi_transport;
 	}
+	ring_mode = 0;
 	return 0;
 
 unregister_iscsi_transport:
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 53c9b70..25e6b20 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -21,11 +21,9 @@
 #ifndef _BEISCSI_MAIN_
 #define _BEISCSI_MAIN_
 
-
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/in.h>
-#include <linux/blk-iopoll.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
@@ -35,12 +33,8 @@
 #include <scsi/scsi_transport_iscsi.h>
 
 #include "be.h"
-
-
-
 #define DRV_NAME		"be2iscsi"
 #define BUILD_STR		"2.0.527.0"
-
 #define BE_NAME			"ServerEngines BladeEngine2" \
 				"Linux iSCSI Driver version" BUILD_STR
 #define DRV_DESC		BE_NAME " " "Driver"
@@ -49,6 +43,8 @@
 #define BE_DEVICE_ID1		0x212
 #define OC_DEVICE_ID1		0x702
 #define OC_DEVICE_ID2		0x703
+#define OC_DEVICE_ID3		0x712
+#define OC_DEVICE_ID4		0x222
 
 #define BE2_MAX_SESSIONS	64
 #define BE2_CMDS_PER_CXN	128
@@ -63,6 +59,7 @@
 #define BE2_IO_DEPTH \
 	(BE2_MAX_ICDS / 2 - (BE2_LOGOUTS + BE2_TMFS + BE2_NOPOUT_REQ))
 
+#define MAX_CPUS		31
 #define BEISCSI_SGLIST_ELEMENTS	BE2_SGE
 
 #define BEISCSI_MAX_CMNDS	1024	/* Max IO's per Ctrlr sht->can_queue */
@@ -79,7 +76,7 @@
 #define BE_SENSE_INFO_SIZE		258
 #define BE_ISCSI_PDU_HEADER_SIZE	64
 #define BE_MIN_MEM_SIZE			16384
-
+#define MAX_CMD_SZ			65536
 #define IIOC_SCSI_DATA                  0x05	/* Write Operation */
 
 #define DBG_LVL				0x00000001
@@ -100,6 +97,8 @@
 	}						\
 } while (0);
 
+#define BE_ADAPTER_UP		0x00000000
+#define BE_ADAPTER_LINK_DOWN	0x00000001
 /**
  * hardware needs the async PDU buffers to be posted in multiples of 8
  * So have atleast 8 of them by default
@@ -160,21 +159,19 @@
 
 enum be_mem_enum {
 	HWI_MEM_ADDN_CONTEXT,
-	HWI_MEM_CQ,
-	HWI_MEM_EQ,
 	HWI_MEM_WRB,
 	HWI_MEM_WRBH,
-	HWI_MEM_SGLH,	/* 5 */
+	HWI_MEM_SGLH,
 	HWI_MEM_SGE,
-	HWI_MEM_ASYNC_HEADER_BUF,
+	HWI_MEM_ASYNC_HEADER_BUF, 	/* 5 */
 	HWI_MEM_ASYNC_DATA_BUF,
 	HWI_MEM_ASYNC_HEADER_RING,
-	HWI_MEM_ASYNC_DATA_RING,	/* 10 */
+	HWI_MEM_ASYNC_DATA_RING,
 	HWI_MEM_ASYNC_HEADER_HANDLE,
-	HWI_MEM_ASYNC_DATA_HANDLE,
+	HWI_MEM_ASYNC_DATA_HANDLE, 	/* 10 */
 	HWI_MEM_ASYNC_PDU_CONTEXT,
 	ISCSI_MEM_GLOBAL_HEADER,
-	SE_MEM_MAX  	/* 15 */
+	SE_MEM_MAX
 };
 
 struct be_bus_address32 {
@@ -212,6 +209,9 @@
 
 struct sgl_handle {
 	unsigned int sgl_index;
+	unsigned int type;
+	unsigned int cid;
+	struct iscsi_task *task;
 	struct iscsi_sge *pfrag;
 };
 
@@ -274,13 +274,17 @@
 	struct pci_dev *pcidev;
 	unsigned int state;
 	unsigned short asic_revision;
-	struct blk_iopoll	iopoll;
+	unsigned int num_cpus;
+	unsigned int nxt_cqid;
+	struct msix_entry msix_entries[MAX_CPUS + 1];
+	bool msix_enabled;
 	struct be_mem_descriptor *init_mem;
 
 	unsigned short io_sgl_alloc_index;
 	unsigned short io_sgl_free_index;
 	unsigned short io_sgl_hndl_avbl;
 	struct sgl_handle **io_sgl_hndl_base;
+	struct sgl_handle **sgl_hndl_array;
 
 	unsigned short eh_sgl_alloc_index;
 	unsigned short eh_sgl_free_index;
@@ -315,6 +319,7 @@
 		unsigned short cid_alloc;
 		unsigned short cid_free;
 		unsigned short avlbl_cids;
+		unsigned short iscsi_features;
 		spinlock_t cid_lock;
 	} fw_config;
 
@@ -343,6 +348,7 @@
 	unsigned short login_in_progress;
 	struct sgl_handle *plogin_sgl_handle;
 	struct beiscsi_session *beiscsi_sess;
+	struct iscsi_task *task;
 };
 
 /* This structure is used by the chip */
@@ -390,7 +396,7 @@
 	unsigned int flags;
 	unsigned short cid;
 	unsigned short header_len;
-
+	itt_t libiscsi_itt;
 	struct be_cmd_bhs *cmd_bhs;
 	struct be_bus_address bhs_pa;
 	unsigned short bhs_len;
@@ -599,7 +605,6 @@
 
 void beiscsi_process_eq(struct beiscsi_hba *phba);
 
-
 struct iscsi_wrb {
 	u32 dw[16];
 } __packed;
@@ -820,10 +825,12 @@
 };
 
 struct hwi_context_memory {
-	struct be_eq_obj be_eq;
-	struct be_queue_info be_cq;
-	struct be_queue_info be_mcc_cq;
-	struct be_queue_info be_mcc;
+	/* Adaptive interrupt coalescing (AIC) info */
+	u16 min_eqd;		/* in usecs */
+	u16 max_eqd;		/* in usecs */
+	u16 cur_eqd;		/* in usecs */
+	struct be_eq_obj be_eq[MAX_CPUS];
+	struct be_queue_info be_cq[MAX_CPUS];
 
 	struct be_queue_info be_def_hdrq;
 	struct be_queue_info be_def_dataq;
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 12e644f..79c2bd5 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -35,7 +35,6 @@
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 			   OPCODE_COMMON_QUERY_FIRMWARE_CONFIG, sizeof(*req));
-
 	status = be_mbox_notify(ctrl);
 	if (!status) {
 		struct be_fw_cfg *pfw_cfg;
@@ -58,7 +57,8 @@
 	return status;
 }
 
-unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl)
+unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
+				      struct beiscsi_hba *phba)
 {
 	struct be_dma_mem nonemb_cmd;
 	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
@@ -85,7 +85,6 @@
 	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
 	sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
 	sge->len = cpu_to_le32(nonemb_cmd.size);
-
 	status = be_mbox_notify(ctrl);
 	if (!status) {
 		struct be_mgmt_controller_attributes_resp *resp = nonemb_cmd.va;
@@ -95,21 +94,25 @@
 			resp->params.hba_attribs.firmware_version_string);
 		SE_DEBUG(DBG_LVL_8,
 			"Developer Build, not performing version check...\n");
-
+		phba->fw_config.iscsi_features =
+				resp->params.hba_attribs.iscsi_features;
+		SE_DEBUG(DBG_LVL_8, " phba->fw_config.iscsi_features = %d\n",
+				      phba->fw_config.iscsi_features);
 	} else
 		SE_DEBUG(DBG_LVL_1, " Failed in mgmt_check_supported_fw\n");
+	spin_unlock(&ctrl->mbox_lock);
 	if (nonemb_cmd.va)
 		pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
 				    nonemb_cmd.va, nonemb_cmd.dma);
 
-	spin_unlock(&ctrl->mbox_lock);
 	return status;
 }
 
+
 unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute)
 {
 	struct be_ctrl_info *ctrl = &phba->ctrl;
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
 	struct iscsi_cleanup_req *req = embedded_payload(wrb);
 	int status = 0;
 
@@ -124,7 +127,7 @@
 	req->hdr_ring_id = 0;
 	req->data_ring_id = 0;
 
-	status = be_mbox_notify(ctrl);
+	status =  be_mcc_notify_wait(phba);
 	if (status)
 		shost_printk(KERN_WARNING, phba->shost,
 			     " mgmt_epfw_cleanup , FAILED\n");
@@ -137,7 +140,7 @@
 {
 	struct be_dma_mem nonemb_cmd;
 	struct be_ctrl_info *ctrl = &phba->ctrl;
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
 	struct be_sge *sge = nonembedded_sgl(wrb);
 	struct invalidate_commands_params_in *req;
 	int status = 0;
@@ -169,7 +172,7 @@
 	sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
 	sge->len = cpu_to_le32(nonemb_cmd.size);
 
-	status = be_mbox_notify(ctrl);
+	status = be_mcc_notify_wait(phba);
 	if (status)
 		SE_DEBUG(DBG_LVL_1, "ICDS Invalidation Failed\n");
 	spin_unlock(&ctrl->mbox_lock);
@@ -186,7 +189,7 @@
 					 unsigned short savecfg_flag)
 {
 	struct be_ctrl_info *ctrl = &phba->ctrl;
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
 	struct iscsi_invalidate_connection_params_in *req =
 						embedded_payload(wrb);
 	int status = 0;
@@ -205,7 +208,7 @@
 	else
 		req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE;
 	req->save_cfg = savecfg_flag;
-	status = be_mbox_notify(ctrl);
+	status =  be_mcc_notify_wait(phba);
 	if (status)
 		SE_DEBUG(DBG_LVL_1, "Invalidation Failed\n");
 
@@ -217,7 +220,7 @@
 				unsigned short cid, unsigned int upload_flag)
 {
 	struct be_ctrl_info *ctrl = &phba->ctrl;
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
 	struct tcp_upload_params_in *req = embedded_payload(wrb);
 	int status = 0;
 
@@ -229,7 +232,7 @@
 			   OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
 	req->id = (unsigned short)cid;
 	req->upload_type = (unsigned char)upload_flag;
-	status = be_mbox_notify(ctrl);
+	status = be_mcc_notify_wait(phba);
 	if (status)
 		SE_DEBUG(DBG_LVL_1, "mgmt_upload_connection Failed\n");
 	spin_unlock(&ctrl->mbox_lock);
@@ -245,13 +248,14 @@
 	struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
 	struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
 	struct be_ctrl_info *ctrl = &phba->ctrl;
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
 	struct tcp_connect_and_offload_in *req = embedded_payload(wrb);
 	unsigned short def_hdr_id;
 	unsigned short def_data_id;
 	struct phys_addr template_address = { 0, 0 };
 	struct phys_addr *ptemplate_address;
 	int status = 0;
+	unsigned int i;
 	unsigned short cid = beiscsi_ep->ep_cid;
 
 	phwi_ctrlr = phba->phwi_ctrlr;
@@ -296,14 +300,18 @@
 
 	}
 	req->cid = cid;
-	req->cq_id = phwi_context->be_cq.id;
+	i = phba->nxt_cqid++;
+	if (phba->nxt_cqid == phba->num_cpus)
+		phba->nxt_cqid = 0;
+	req->cq_id = phwi_context->be_cq[i].id;
+	SE_DEBUG(DBG_LVL_8, "i=%d cq_id=%d \n", i, req->cq_id);
 	req->defq_id = def_hdr_id;
 	req->hdr_ring_id = def_hdr_id;
 	req->data_ring_id = def_data_id;
 	req->do_offload = 1;
 	req->dataout_template_pa.lo = ptemplate_address->lo;
 	req->dataout_template_pa.hi = ptemplate_address->hi;
-	status = be_mbox_notify(ctrl);
+	status = be_mcc_notify_wait(phba);
 	if (!status) {
 		struct iscsi_endpoint *ep;
 		struct tcp_connect_and_offload_out *ptcpcnct_out =
@@ -311,7 +319,7 @@
 
 		ep = phba->ep_array[ptcpcnct_out->cid];
 		beiscsi_ep = ep->dd_data;
-		beiscsi_ep->fw_handle = 0;
+		beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle;
 		beiscsi_ep->cid_vld = 1;
 		SE_DEBUG(DBG_LVL_8, "mgmt_open_connection Success\n");
 	} else
@@ -319,3 +327,30 @@
 	spin_unlock(&ctrl->mbox_lock);
 	return status;
 }
+
+int be_cmd_get_mac_addr(struct beiscsi_hba *phba, u8 *mac_addr)
+{
+	struct be_ctrl_info *ctrl = &phba->ctrl;
+	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
+	struct be_cmd_req_get_mac_addr *req = embedded_payload(wrb);
+	int status;
+
+	SE_DEBUG(DBG_LVL_8, "In be_cmd_get_mac_addr\n");
+	spin_lock(&ctrl->mbox_lock);
+	memset(wrb, 0, sizeof(*wrb));
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
+			   OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
+			   sizeof(*req));
+
+	status = be_mcc_notify_wait(phba);
+	if (!status) {
+		struct be_cmd_resp_get_mac_addr *resp = embedded_payload(wrb);
+
+		memcpy(mac_addr, resp->mac_address, ETH_ALEN);
+	}
+
+	spin_unlock(&ctrl->mbox_lock);
+	return status;
+}
+
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h
index 00e816e..24eaff9 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.h
+++ b/drivers/scsi/be2iscsi/be_mgmt.h
@@ -175,7 +175,9 @@
 	u8 phy_port;
 	u32 firmware_post_status;
 	u32 hba_mtu[8];
-	u32 future_u32[4];
+	u8 iscsi_features;
+	u8 future_u8[3];
+	u32 future_u32[3];
 } __packed;
 
 struct mgmt_controller_attributes {
@@ -246,4 +248,8 @@
 					 unsigned short cid,
 					 unsigned short issue_reset,
 					 unsigned short savecfg_flag);
+
+unsigned char mgmt_fw_cmd(struct be_ctrl_info *ctrl,
+			  struct beiscsi_hba *phba,
+			  char *buf, unsigned int len);
 #endif
diff --git a/drivers/scsi/bfa/bfa_cb_ioim_macros.h b/drivers/scsi/bfa/bfa_cb_ioim_macros.h
index 0050c83..961fe43 100644
--- a/drivers/scsi/bfa/bfa_cb_ioim_macros.h
+++ b/drivers/scsi/bfa/bfa_cb_ioim_macros.h
@@ -51,7 +51,7 @@
 	lun.bfa_lun     = 0;
 	lun.scsi_lun[0] = bfa_os_htons(luno);
 
-	return (lun.bfa_lun);
+	return lun.bfa_lun;
 }
 
 /**
@@ -68,7 +68,7 @@
 {
 	struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
 
-	return ((u8 *) cmnd->cmnd);
+	return (u8 *) cmnd->cmnd;
 }
 
 /**
@@ -97,7 +97,7 @@
 {
 	struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
 
-	return (scsi_bufflen(cmnd));
+	return scsi_bufflen(cmnd);
 }
 
 /**
@@ -129,7 +129,7 @@
 	sge = (struct scatterlist *)scsi_sglist(cmnd) + sgeid;
 	addr = (u64) sg_dma_address(sge);
 
-	return (*(union bfi_addr_u *) &addr);
+	return *((union bfi_addr_u *) &addr);
 }
 
 static inline u32
@@ -197,7 +197,7 @@
 {
 	struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
 
-	return (cmnd->cmd_len);
+	return cmnd->cmd_len;
 }
 
 
diff --git a/drivers/scsi/bfa/bfa_cee.c b/drivers/scsi/bfa/bfa_cee.c
index 7a959c3..2b91779 100644
--- a/drivers/scsi/bfa/bfa_cee.c
+++ b/drivers/scsi/bfa/bfa_cee.c
@@ -228,7 +228,7 @@
 u32
 bfa_cee_meminfo(void)
 {
-	return (bfa_cee_attr_meminfo() + bfa_cee_stats_meminfo());
+	return bfa_cee_attr_meminfo() + bfa_cee_stats_meminfo();
 }
 
 /**
diff --git a/drivers/scsi/bfa/bfa_csdebug.c b/drivers/scsi/bfa/bfa_csdebug.c
index 1b71d34..caeb114 100644
--- a/drivers/scsi/bfa/bfa_csdebug.c
+++ b/drivers/scsi/bfa/bfa_csdebug.c
@@ -47,12 +47,12 @@
 	tqe = bfa_q_next(q);
 	while (tqe != q) {
 		if (tqe == qe)
-			return (1);
+			return 1;
 		tqe = bfa_q_next(tqe);
 		if (tqe == NULL)
 			break;
 	}
-	return (0);
+	return 0;
 }
 
 
diff --git a/drivers/scsi/bfa/bfa_fcpim.c b/drivers/scsi/bfa/bfa_fcpim.c
index 401babe..790c945 100644
--- a/drivers/scsi/bfa/bfa_fcpim.c
+++ b/drivers/scsi/bfa/bfa_fcpim.c
@@ -131,7 +131,7 @@
 {
 	struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
 
-	return (fcpim->path_tov / 1000);
+	return fcpim->path_tov / 1000;
 }
 
 bfa_status_t
@@ -169,7 +169,7 @@
 {
 	struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
 
-	return (fcpim->q_depth);
+	return fcpim->q_depth;
 }
 
 
diff --git a/drivers/scsi/bfa/bfa_fcpim_priv.h b/drivers/scsi/bfa/bfa_fcpim_priv.h
index 153206c..5cf4184 100644
--- a/drivers/scsi/bfa/bfa_fcpim_priv.h
+++ b/drivers/scsi/bfa/bfa_fcpim_priv.h
@@ -35,7 +35,7 @@
 #define BFA_FCPIM_PATHTOV_MAX	(90 * 1000)	/* in millisecs */
 
 #define bfa_fcpim_stats(__fcpim, __stats)   \
-    (__fcpim)->stats.__stats ++
+    ((__fcpim)->stats.__stats++)
 
 struct bfa_fcpim_mod_s {
 	struct bfa_s 	*bfa;
@@ -143,7 +143,7 @@
 	struct bfa_itnim_hal_stats_s	stats;
 };
 
-#define bfa_itnim_is_online(_itnim) (_itnim)->is_online
+#define bfa_itnim_is_online(_itnim) ((_itnim)->is_online)
 #define BFA_FCPIM_MOD(_hal) (&(_hal)->modules.fcpim_mod)
 #define BFA_IOIM_FROM_TAG(_fcpim, _iotag)	\
 	(&fcpim->ioim_arr[_iotag])
diff --git a/drivers/scsi/bfa/bfa_fcport.c b/drivers/scsi/bfa/bfa_fcport.c
index 9924359..aef648b 100644
--- a/drivers/scsi/bfa/bfa_fcport.c
+++ b/drivers/scsi/bfa/bfa_fcport.c
@@ -388,32 +388,29 @@
 		bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
 		bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
 			     BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown");
-		if (BFA_PORT_IS_DISABLED(pport->bfa)) {
+		if (BFA_PORT_IS_DISABLED(pport->bfa))
 			bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
-		} else {
+		else
 			bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
-		}
 		break;
 
 	case BFA_PPORT_SM_STOP:
 		bfa_sm_set_state(pport, bfa_pport_sm_stopped);
 		bfa_pport_reset_linkinfo(pport);
-		if (BFA_PORT_IS_DISABLED(pport->bfa)) {
+		if (BFA_PORT_IS_DISABLED(pport->bfa))
 			bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
-		} else {
+		else
 			bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
-		}
 		break;
 
 	case BFA_PPORT_SM_HWFAIL:
 		bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
 		bfa_pport_reset_linkinfo(pport);
 		bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
-		if (BFA_PORT_IS_DISABLED(pport->bfa)) {
+		if (BFA_PORT_IS_DISABLED(pport->bfa))
 			bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
-		} else {
+		else
 			bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
-		}
 		break;
 
 	default:
@@ -999,10 +996,10 @@
 	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
 
 	if (pport->diag_busy)
-		return (BFA_STATUS_DIAG_BUSY);
+		return BFA_STATUS_DIAG_BUSY;
 	else if (bfa_sm_cmp_state
 		 (BFA_PORT_MOD(bfa), bfa_pport_sm_disabling_qwait))
-		return (BFA_STATUS_DEVBUSY);
+		return BFA_STATUS_DEVBUSY;
 
 	bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_ENABLE);
 	return BFA_STATUS_OK;
@@ -1032,7 +1029,7 @@
 
 	pport->cfg.speed = speed;
 
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 /**
@@ -1068,7 +1065,7 @@
 	}
 
 	pport->cfg.topology = topology;
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 /**
@@ -1094,7 +1091,7 @@
 	pport->cfg.cfg_hardalpa = BFA_TRUE;
 	pport->cfg.hardalpa = alpa;
 
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 bfa_status_t
@@ -1106,7 +1103,7 @@
 	bfa_trc(bfa, pport->cfg.hardalpa);
 
 	pport->cfg.cfg_hardalpa = BFA_FALSE;
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 bfa_boolean_t
@@ -1138,16 +1135,16 @@
 	 * with in range
 	 */
 	if ((maxfrsize > FC_MAX_PDUSZ) || (maxfrsize < FC_MIN_PDUSZ))
-		return (BFA_STATUS_INVLD_DFSZ);
+		return BFA_STATUS_INVLD_DFSZ;
 
 	/*
 	 * power of 2, if not the max frame size of 2112
 	 */
 	if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1)))
-		return (BFA_STATUS_INVLD_DFSZ);
+		return BFA_STATUS_INVLD_DFSZ;
 
 	pport->cfg.maxfrsize = maxfrsize;
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 u16
@@ -1415,7 +1412,7 @@
 
 	if (port->stats_busy) {
 		bfa_trc(bfa, port->stats_busy);
-		return (BFA_STATUS_DEVBUSY);
+		return BFA_STATUS_DEVBUSY;
 	}
 
 	port->stats_busy = BFA_TRUE;
@@ -1427,7 +1424,7 @@
 
 	bfa_timer_start(bfa, &port->timer, bfa_port_stats_timeout, port,
 			BFA_PORT_STATS_TOV);
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 bfa_status_t
@@ -1437,7 +1434,7 @@
 
 	if (port->stats_busy) {
 		bfa_trc(bfa, port->stats_busy);
-		return (BFA_STATUS_DEVBUSY);
+		return BFA_STATUS_DEVBUSY;
 	}
 
 	port->stats_busy = BFA_TRUE;
@@ -1448,7 +1445,7 @@
 
 	bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port,
 			BFA_PORT_STATS_TOV);
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 bfa_status_t
@@ -1515,7 +1512,7 @@
 	/*
 	 * QoS stats is embedded in port stats
 	 */
-	return (bfa_pport_get_stats(bfa, stats, cbfn, cbarg));
+	return bfa_pport_get_stats(bfa, stats, cbfn, cbarg);
 }
 
 bfa_status_t
@@ -1525,7 +1522,7 @@
 
 	if (port->stats_busy) {
 		bfa_trc(bfa, port->stats_busy);
-		return (BFA_STATUS_DEVBUSY);
+		return BFA_STATUS_DEVBUSY;
 	}
 
 	port->stats_busy = BFA_TRUE;
@@ -1536,7 +1533,7 @@
 
 	bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port,
 			BFA_PORT_STATS_TOV);
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 /**
@@ -1545,7 +1542,7 @@
 bfa_status_t
 bfa_pport_trunk_disable(struct bfa_s *bfa)
 {
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 bfa_boolean_t
@@ -1562,8 +1559,8 @@
 {
 	struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
 
-	return (bfa_sm_to_state(hal_pport_sm_table, port->sm) ==
-		BFA_PPORT_ST_DISABLED);
+	return bfa_sm_to_state(hal_pport_sm_table, port->sm) ==
+		BFA_PPORT_ST_DISABLED;
 
 }
 
@@ -1572,7 +1569,7 @@
 {
 	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
 
-return (pport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE);
+	return pport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE;
 
 }
 
@@ -1620,7 +1617,7 @@
 
 	pport->cfg.trl_def_speed = speed;
 
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 /**
@@ -1632,7 +1629,7 @@
 	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
 
 	bfa_trc(bfa, pport->cfg.trl_def_speed);
-	return (pport->cfg.trl_def_speed);
+	return pport->cfg.trl_def_speed;
 
 }
 
diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c
index 8975ed0..c7ab257 100644
--- a/drivers/scsi/bfa/bfa_fcs_lport.c
+++ b/drivers/scsi/bfa/bfa_fcs_lport.c
@@ -568,11 +568,10 @@
 
 	__port_action[port->fabric->fab_type].offline(port);
 
-	if (bfa_fcs_fabric_is_online(port->fabric) == BFA_TRUE) {
+	if (bfa_fcs_fabric_is_online(port->fabric) == BFA_TRUE)
 		bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_DISCONNECT);
-	} else {
+	else
 		bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_OFFLINE);
-	}
 	bfa_fcb_port_offline(port->fcs->bfad, port->port_cfg.roles,
 			port->fabric->vf_drv,
 			(port->vport == NULL) ? NULL : port->vport->vport_drv);
@@ -777,7 +776,7 @@
 	}
 
 	bfa_trc(port->fcs, pwwn);
-	return (NULL);
+	return NULL;
 }
 
 /**
@@ -796,7 +795,7 @@
 	}
 
 	bfa_trc(port->fcs, nwwn);
-	return (NULL);
+	return NULL;
 }
 
 /**
@@ -870,7 +869,7 @@
 bfa_boolean_t
 bfa_fcs_port_is_online(struct bfa_fcs_port_s *port)
 {
-	return (bfa_sm_cmp_state(port, bfa_fcs_port_sm_online));
+	return bfa_sm_cmp_state(port, bfa_fcs_port_sm_online);
 }
 
 /**
diff --git a/drivers/scsi/bfa/bfa_fcxp.c b/drivers/scsi/bfa/bfa_fcxp.c
index 4754a0e..cf0ad67 100644
--- a/drivers/scsi/bfa/bfa_fcxp.c
+++ b/drivers/scsi/bfa/bfa_fcxp.c
@@ -199,7 +199,7 @@
 	if (fcxp)
 		list_add_tail(&fcxp->qe, &fm->fcxp_active_q);
 
-	return (fcxp);
+	return fcxp;
 }
 
 static void
@@ -503,7 +503,7 @@
 
 	fcxp = bfa_fcxp_get(BFA_FCXP_MOD(bfa));
 	if (fcxp == NULL)
-		return (NULL);
+		return NULL;
 
 	bfa_trc(bfa, fcxp->fcxp_tag);
 
@@ -568,7 +568,7 @@
 		}
 	}
 
-	return (fcxp);
+	return fcxp;
 }
 
 /**
@@ -709,7 +709,7 @@
 bfa_fcxp_abort(struct bfa_fcxp_s *fcxp)
 {
 	bfa_assert(0);
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 void
diff --git a/drivers/scsi/bfa/bfa_intr.c b/drivers/scsi/bfa/bfa_intr.c
index 0ca1257..b36540e 100644
--- a/drivers/scsi/bfa/bfa_intr.c
+++ b/drivers/scsi/bfa/bfa_intr.c
@@ -59,7 +59,7 @@
 	qintr = intr & __HFN_INT_RME_MASK;
 	bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, qintr);
 
-	for (queue = 0; queue < BFI_IOC_MAX_CQS_ASIC; queue ++) {
+	for (queue = 0; queue < BFI_IOC_MAX_CQS_ASIC; queue++) {
 		if (intr & (__HFN_INT_RME_Q0 << queue))
 			bfa_msix_rspq(bfa, queue & (BFI_IOC_MAX_CQS - 1));
 	}
diff --git a/drivers/scsi/bfa/bfa_intr_priv.h b/drivers/scsi/bfa/bfa_intr_priv.h
index 8ce6e6b..5fc301c 100644
--- a/drivers/scsi/bfa/bfa_intr_priv.h
+++ b/drivers/scsi/bfa/bfa_intr_priv.h
@@ -26,9 +26,9 @@
 void bfa_isr_bind(enum bfi_mclass mc, bfa_isr_func_t isr_func);
 
 
-#define bfa_reqq_pi(__bfa, __reqq)	(__bfa)->iocfc.req_cq_pi[__reqq]
+#define bfa_reqq_pi(__bfa, __reqq)	((__bfa)->iocfc.req_cq_pi[__reqq])
 #define bfa_reqq_ci(__bfa, __reqq)					\
-	*(u32 *)((__bfa)->iocfc.req_cq_shadow_ci[__reqq].kva)
+	(*(u32 *)((__bfa)->iocfc.req_cq_shadow_ci[__reqq].kva))
 
 #define bfa_reqq_full(__bfa, __reqq)				\
 	(((bfa_reqq_pi(__bfa, __reqq) + 1) &			\
@@ -50,14 +50,16 @@
 } while (0)
 
 #define bfa_rspq_pi(__bfa, __rspq)					\
-	*(u32 *)((__bfa)->iocfc.rsp_cq_shadow_pi[__rspq].kva)
+	(*(u32 *)((__bfa)->iocfc.rsp_cq_shadow_pi[__rspq].kva))
 
-#define bfa_rspq_ci(__bfa, __rspq)	(__bfa)->iocfc.rsp_cq_ci[__rspq]
+#define bfa_rspq_ci(__bfa, __rspq)	((__bfa)->iocfc.rsp_cq_ci[__rspq])
 #define bfa_rspq_elem(__bfa, __rspq, __ci)				\
-	&((struct bfi_msg_s *)((__bfa)->iocfc.rsp_cq_ba[__rspq].kva))[__ci]
+	(&((struct bfi_msg_s *)((__bfa)->iocfc.rsp_cq_ba[__rspq].kva))[__ci])
 
-#define CQ_INCR(__index, __size)					\
-			(__index)++; (__index) &= ((__size) - 1)
+#define CQ_INCR(__index, __size) do {					\
+			(__index)++;					\
+			(__index) &= ((__size) - 1);      \
+} while (0)
 
 /**
  * Queue element to wait for room in request queue. FIFO order is
@@ -94,7 +96,7 @@
 	wqe->cbarg = cbarg;
 }
 
-#define bfa_reqq(__bfa, __reqq)	&(__bfa)->reqq_waitq[__reqq]
+#define bfa_reqq(__bfa, __reqq)	(&(__bfa)->reqq_waitq[__reqq])
 
 /**
  * static inline void
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c
index 1493489..397d7e9 100644
--- a/drivers/scsi/bfa/bfa_ioc.c
+++ b/drivers/scsi/bfa/bfa_ioc.c
@@ -51,7 +51,7 @@
 	 (sizeof(struct bfa_trc_mod_s) -			\
 	  BFA_TRC_MAX * sizeof(struct bfa_trc_s)))
 #define BFA_DBG_FWTRC_OFF(_fn)	(BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn))
-#define bfa_ioc_stats(_ioc, _stats)	(_ioc)->stats._stats ++
+#define bfa_ioc_stats(_ioc, _stats)	((_ioc)->stats._stats++)
 
 #define BFA_FLASH_CHUNK_NO(off)         (off / BFI_FLASH_CHUNK_SZ_WORDS)
 #define BFA_FLASH_OFFSET_IN_CHUNK(off)  (off % BFI_FLASH_CHUNK_SZ_WORDS)
@@ -1953,8 +1953,8 @@
 bfa_boolean_t
 bfa_ioc_is_disabled(struct bfa_ioc_s *ioc)
 {
-	return (bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabling)
-		|| bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled));
+	return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabling)
+		|| bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled);
 }
 
 /**
@@ -1963,9 +1963,9 @@
 bfa_boolean_t
 bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc)
 {
-	return (bfa_fsm_cmp_state(ioc, bfa_ioc_sm_reset)
+	return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_reset)
 		|| bfa_fsm_cmp_state(ioc, bfa_ioc_sm_fwcheck)
-		|| bfa_fsm_cmp_state(ioc, bfa_ioc_sm_mismatch));
+		|| bfa_fsm_cmp_state(ioc, bfa_ioc_sm_mismatch);
 }
 
 #define bfa_ioc_state_disabled(__sm)		\
diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h
index 58efd4b1..7c30f05 100644
--- a/drivers/scsi/bfa/bfa_ioc.h
+++ b/drivers/scsi/bfa/bfa_ioc.h
@@ -179,16 +179,16 @@
 	struct bfa_ioc_mbox_mod_s mbox_mod;
 };
 
-#define bfa_ioc_pcifn(__ioc)		(__ioc)->pcidev.pci_func
-#define bfa_ioc_devid(__ioc)		(__ioc)->pcidev.device_id
-#define bfa_ioc_bar0(__ioc)		(__ioc)->pcidev.pci_bar_kva
+#define bfa_ioc_pcifn(__ioc)		((__ioc)->pcidev.pci_func)
+#define bfa_ioc_devid(__ioc)		((__ioc)->pcidev.device_id)
+#define bfa_ioc_bar0(__ioc)		((__ioc)->pcidev.pci_bar_kva)
 #define bfa_ioc_portid(__ioc)		((__ioc)->port_id)
 #define bfa_ioc_fetch_stats(__ioc, __stats) \
-		((__stats)->drv_stats) = (__ioc)->stats
+		(((__stats)->drv_stats) = (__ioc)->stats)
 #define bfa_ioc_clr_stats(__ioc)	\
 		bfa_os_memset(&(__ioc)->stats, 0, sizeof((__ioc)->stats))
-#define bfa_ioc_maxfrsize(__ioc)	(__ioc)->attr->maxfrsize
-#define bfa_ioc_rx_bbcredit(__ioc)	(__ioc)->attr->rx_bbcredit
+#define bfa_ioc_maxfrsize(__ioc)	((__ioc)->attr->maxfrsize)
+#define bfa_ioc_rx_bbcredit(__ioc)	((__ioc)->attr->rx_bbcredit)
 #define bfa_ioc_speed_sup(__ioc)	\
 	BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop)
 
diff --git a/drivers/scsi/bfa/bfa_iocfc.c b/drivers/scsi/bfa/bfa_iocfc.c
index 12350b0..d7ab792 100644
--- a/drivers/scsi/bfa/bfa_iocfc.c
+++ b/drivers/scsi/bfa/bfa_iocfc.c
@@ -794,7 +794,7 @@
 
 	if (iocfc->stats_busy) {
 		bfa_trc(bfa, iocfc->stats_busy);
-		return (BFA_STATUS_DEVBUSY);
+		return BFA_STATUS_DEVBUSY;
 	}
 
 	iocfc->stats_busy = BFA_TRUE;
@@ -804,7 +804,7 @@
 
 	bfa_iocfc_stats_query(bfa);
 
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 bfa_status_t
@@ -814,7 +814,7 @@
 
 	if (iocfc->stats_busy) {
 		bfa_trc(bfa, iocfc->stats_busy);
-		return (BFA_STATUS_DEVBUSY);
+		return BFA_STATUS_DEVBUSY;
 	}
 
 	iocfc->stats_busy = BFA_TRUE;
@@ -822,7 +822,7 @@
 	iocfc->stats_cbarg = cbarg;
 
 	bfa_iocfc_stats_clear(bfa);
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 /**
diff --git a/drivers/scsi/bfa/bfa_iocfc.h b/drivers/scsi/bfa/bfa_iocfc.h
index 7ad177e..ce9a830 100644
--- a/drivers/scsi/bfa/bfa_iocfc.h
+++ b/drivers/scsi/bfa/bfa_iocfc.h
@@ -107,13 +107,13 @@
 
 #define bfa_lpuid(__bfa)		bfa_ioc_portid(&(__bfa)->ioc)
 #define bfa_msix_init(__bfa, __nvecs)	\
-	(__bfa)->iocfc.hwif.hw_msix_init(__bfa, __nvecs)
+	((__bfa)->iocfc.hwif.hw_msix_init(__bfa, __nvecs))
 #define bfa_msix_install(__bfa)	\
-	(__bfa)->iocfc.hwif.hw_msix_install(__bfa)
+	((__bfa)->iocfc.hwif.hw_msix_install(__bfa))
 #define bfa_msix_uninstall(__bfa)	\
-	(__bfa)->iocfc.hwif.hw_msix_uninstall(__bfa)
+	((__bfa)->iocfc.hwif.hw_msix_uninstall(__bfa))
 #define bfa_isr_mode_set(__bfa, __msix)	\
-	(__bfa)->iocfc.hwif.hw_isr_mode_set(__bfa, __msix)
+	((__bfa)->iocfc.hwif.hw_isr_mode_set(__bfa, __msix))
 #define bfa_msix_getvecs(__bfa, __vecmap, __nvecs, __maxvec)	\
 	(__bfa)->iocfc.hwif.hw_msix_getvecs(__bfa, __vecmap, __nvecs, __maxvec)
 
diff --git a/drivers/scsi/bfa/bfa_ioim.c b/drivers/scsi/bfa/bfa_ioim.c
index 7ae2552..f81d359 100644
--- a/drivers/scsi/bfa/bfa_ioim.c
+++ b/drivers/scsi/bfa/bfa_ioim.c
@@ -105,13 +105,13 @@
 				bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
 				list_del(&ioim->qe);
 				list_add_tail(&ioim->qe,
-					&ioim->fcpim->ioim_comp_q);
+						&ioim->fcpim->ioim_comp_q);
 				bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
 						__bfa_cb_ioim_pathtov, ioim);
 			} else {
 				list_del(&ioim->qe);
 				list_add_tail(&ioim->qe,
-					&ioim->itnim->pending_q);
+						&ioim->itnim->pending_q);
 			}
 			break;
 		}
diff --git a/drivers/scsi/bfa/bfa_itnim.c b/drivers/scsi/bfa/bfa_itnim.c
index 4d5c61a..eabf7d3 100644
--- a/drivers/scsi/bfa/bfa_itnim.c
+++ b/drivers/scsi/bfa/bfa_itnim.c
@@ -1029,7 +1029,7 @@
 	bfa_stats(itnim, creates);
 	bfa_sm_send_event(itnim, BFA_ITNIM_SM_CREATE);
 
-	return (itnim);
+	return itnim;
 }
 
 void
@@ -1061,7 +1061,7 @@
 bfa_boolean_t
 bfa_itnim_hold_io(struct bfa_itnim_s *itnim)
 {
-	return (
+	return
 		itnim->fcpim->path_tov && itnim->iotov_active &&
 		(bfa_sm_cmp_state(itnim, bfa_itnim_sm_fwcreate) ||
 		 bfa_sm_cmp_state(itnim, bfa_itnim_sm_sler) ||
@@ -1069,7 +1069,7 @@
 		 bfa_sm_cmp_state(itnim, bfa_itnim_sm_fwdelete) ||
 		 bfa_sm_cmp_state(itnim, bfa_itnim_sm_offline) ||
 		 bfa_sm_cmp_state(itnim, bfa_itnim_sm_iocdisable))
-);
+	;
 }
 
 void
diff --git a/drivers/scsi/bfa/bfa_log.c b/drivers/scsi/bfa/bfa_log.c
index c2735e5..e751401 100644
--- a/drivers/scsi/bfa/bfa_log.c
+++ b/drivers/scsi/bfa/bfa_log.c
@@ -231,9 +231,9 @@
 		return BFA_LOG_INVALID;
 
 	if (log_mod)
-		return (log_mod->log_level[mod_id]);
+		return log_mod->log_level[mod_id];
 	else
-		return (bfa_log_info[mod_id].level);
+		return bfa_log_info[mod_id].level;
 }
 
 enum bfa_log_severity
diff --git a/drivers/scsi/bfa/bfa_port_priv.h b/drivers/scsi/bfa/bfa_port_priv.h
index 4b97e27..51f698a 100644
--- a/drivers/scsi/bfa/bfa_port_priv.h
+++ b/drivers/scsi/bfa/bfa_port_priv.h
@@ -59,8 +59,8 @@
 	u8			*stats_kva;
 	u64		stats_pa;
 	union bfa_pport_stats_u *stats;	/*  pport stats */
-	u32		mypid : 24;
-	u32		rsvd_b : 8;
+	u32		mypid:24;
+	u32		rsvd_b:8;
 	struct bfa_timer_s 	timer;	/*  timer */
 	union bfa_pport_stats_u 	*stats_ret;
 					/*  driver stats location */
diff --git a/drivers/scsi/bfa/bfa_rport.c b/drivers/scsi/bfa/bfa_rport.c
index 16da77a..3e1990a 100644
--- a/drivers/scsi/bfa/bfa_rport.c
+++ b/drivers/scsi/bfa/bfa_rport.c
@@ -677,7 +677,7 @@
 	if (rport)
 		list_add_tail(&rport->qe, &mod->rp_active_q);
 
-	return (rport);
+	return rport;
 }
 
 static void
@@ -834,7 +834,7 @@
 	rp = bfa_rport_alloc(BFA_RPORT_MOD(bfa));
 
 	if (rp == NULL)
-		return (NULL);
+		return NULL;
 
 	rp->bfa = bfa;
 	rp->rport_drv = rport_drv;
@@ -843,7 +843,7 @@
 	bfa_assert(bfa_sm_cmp_state(rp, bfa_rport_sm_uninit));
 	bfa_sm_send_event(rp, BFA_RPORT_SM_CREATE);
 
-	return (rp);
+	return rp;
 }
 
 void
diff --git a/drivers/scsi/bfa/bfa_tskim.c b/drivers/scsi/bfa/bfa_tskim.c
index 010d40d..ff7a4dc 100644
--- a/drivers/scsi/bfa/bfa_tskim.c
+++ b/drivers/scsi/bfa/bfa_tskim.c
@@ -23,13 +23,14 @@
 /**
  * task management completion handling
  */
-#define bfa_tskim_qcomp(__tskim, __cbfn) do {			     \
-	bfa_cb_queue((__tskim)->bfa, &(__tskim)->hcb_qe, __cbfn, (__tskim)); \
+#define bfa_tskim_qcomp(__tskim, __cbfn) do {			\
+	bfa_cb_queue((__tskim)->bfa, &(__tskim)->hcb_qe,	\
+			 __cbfn, (__tskim));      \
 	bfa_tskim_notify_comp(__tskim);      \
 } while (0)
 
-#define bfa_tskim_notify_comp(__tskim) do {				     \
-	if ((__tskim)->notify)					     	     \
+#define bfa_tskim_notify_comp(__tskim) do {			 \
+	if ((__tskim)->notify)					 \
 		bfa_itnim_tskdone((__tskim)->itnim);      \
 } while (0)
 
diff --git a/drivers/scsi/bfa/bfa_uf.c b/drivers/scsi/bfa/bfa_uf.c
index ff5f9de..4b3c241 100644
--- a/drivers/scsi/bfa/bfa_uf.c
+++ b/drivers/scsi/bfa/bfa_uf.c
@@ -185,7 +185,7 @@
 	struct bfa_uf_s   *uf;
 
 	bfa_q_deq(&uf_mod->uf_free_q, &uf);
-	return (uf);
+	return uf;
 }
 
 static void
diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c
index 6f2be5a..b52b773 100644
--- a/drivers/scsi/bfa/bfad.c
+++ b/drivers/scsi/bfa/bfad.c
@@ -188,8 +188,8 @@
 bfad_get_drv_port(struct bfad_s *bfad, struct bfad_vf_s *vf_drv,
 		  struct bfad_vport_s *vp_drv)
 {
-	return ((vp_drv) ? (&(vp_drv)->drv_port)
-		: ((vf_drv) ? (&(vf_drv)->base_port) : (&(bfad)->pport)));
+	return (vp_drv) ? (&(vp_drv)->drv_port)
+		: ((vf_drv) ? (&(vf_drv)->base_port) : (&(bfad)->pport));
 }
 
 struct bfad_port_s *
@@ -716,7 +716,7 @@
 	if ((bfad->bfad_flags & BFAD_MSIX_ON)
 	    && bfad_install_msix_handler(bfad)) {
 		printk(KERN_WARNING "%s: install_msix failed, bfad%d\n",
-		       __FUNCTION__, bfad->inst_no);
+		       __func__, bfad->inst_no);
 	}
 
 	bfad_init_timer(bfad);
diff --git a/drivers/scsi/bfa/bfad_fwimg.c b/drivers/scsi/bfa/bfad_fwimg.c
index bd34b0d..2ad65f2 100644
--- a/drivers/scsi/bfa/bfad_fwimg.c
+++ b/drivers/scsi/bfa/bfad_fwimg.c
@@ -65,10 +65,10 @@
 	memcpy(*bfi_image, fw->data, fw->size);
 	*bfi_image_size = fw->size/sizeof(u32);
 
-	return(*bfi_image);
+	return *bfi_image;
 
 error:
-	return(NULL);
+	return NULL;
 }
 
 u32 *
@@ -78,12 +78,12 @@
 		if (bfi_image_ct_size == 0)
 			bfad_read_firmware(pdev, &bfi_image_ct,
 				&bfi_image_ct_size, BFAD_FW_FILE_CT);
-		return(bfi_image_ct);
+		return bfi_image_ct;
 	} else {
 		if (bfi_image_cb_size == 0)
 			bfad_read_firmware(pdev, &bfi_image_cb,
 				&bfi_image_cb_size, BFAD_FW_FILE_CB);
-		return(bfi_image_cb);
+		return bfi_image_cb;
 	}
 }
 
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c
index 55d012a..f788c2a 100644
--- a/drivers/scsi/bfa/bfad_im.c
+++ b/drivers/scsi/bfa/bfad_im.c
@@ -1050,7 +1050,7 @@
 		} else {
 			printk(KERN_WARNING
 				"%s: itnim %llx is already in online state\n",
-				__FUNCTION__,
+				__func__,
 				bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim));
 		}
 
diff --git a/drivers/scsi/bfa/bfad_im_compat.h b/drivers/scsi/bfa/bfad_im_compat.h
index 1d3e74e..b36be15 100644
--- a/drivers/scsi/bfa/bfad_im_compat.h
+++ b/drivers/scsi/bfa/bfad_im_compat.h
@@ -31,7 +31,7 @@
 static inline u32 *
 bfad_load_fwimg(struct pci_dev *pdev)
 {
-	return(bfad_get_firmware_buf(pdev));
+	return bfad_get_firmware_buf(pdev);
 }
 
 static inline void
diff --git a/drivers/scsi/bfa/bfad_intr.c b/drivers/scsi/bfa/bfad_intr.c
index f104e02..7de8832 100644
--- a/drivers/scsi/bfa/bfad_intr.c
+++ b/drivers/scsi/bfa/bfad_intr.c
@@ -23,13 +23,12 @@
 /**
  *  bfa_isr BFA driver interrupt functions
  */
-irqreturn_t bfad_intx(int irq, void *dev_id);
 static int msix_disable;
 module_param(msix_disable, int, S_IRUGO | S_IWUSR);
 /**
  * Line based interrupt handler.
  */
-irqreturn_t
+static irqreturn_t
 bfad_intx(int irq, void *dev_id)
 {
 	struct bfad_s         *bfad = dev_id;
diff --git a/drivers/scsi/bfa/fabric.c b/drivers/scsi/bfa/fabric.c
index a8b14c4..a4b5dd4 100644
--- a/drivers/scsi/bfa/fabric.c
+++ b/drivers/scsi/bfa/fabric.c
@@ -36,12 +36,12 @@
 #define BFA_FCS_FABRIC_RETRY_DELAY	(2000)	/* Milliseconds */
 #define BFA_FCS_FABRIC_CLEANUP_DELAY	(10000)	/* Milliseconds */
 
-#define bfa_fcs_fabric_set_opertype(__fabric) do {          \
-    if (bfa_pport_get_topology((__fabric)->fcs->bfa)    \
-				== BFA_PPORT_TOPOLOGY_P2P)   \
-	    (__fabric)->oper_type = BFA_PPORT_TYPE_NPORT;       \
-    else                                                    \
-	    (__fabric)->oper_type = BFA_PPORT_TYPE_NLPORT;      \
+#define bfa_fcs_fabric_set_opertype(__fabric) do {             \
+	if (bfa_pport_get_topology((__fabric)->fcs->bfa)       \
+				== BFA_PPORT_TOPOLOGY_P2P)     \
+		(__fabric)->oper_type = BFA_PPORT_TYPE_NPORT;  \
+	else                                                   \
+		(__fabric)->oper_type = BFA_PPORT_TYPE_NLPORT; \
 } while (0)
 
 /*
@@ -887,7 +887,7 @@
 bfa_boolean_t
 bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric)
 {
-	return (bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_loopback));
+	return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_loopback);
 }
 
 enum bfa_pport_type
@@ -974,7 +974,7 @@
 int
 bfa_fcs_fabric_is_online(struct bfa_fcs_fabric_s *fabric)
 {
-	return (bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_online));
+	return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_online);
 }
 
 
@@ -1015,7 +1015,7 @@
 u16
 bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric)
 {
-	return (fabric->num_vports);
+	return fabric->num_vports;
 }
 
 /**
diff --git a/drivers/scsi/bfa/fcbuild.c b/drivers/scsi/bfa/fcbuild.c
index d174706..fee5456 100644
--- a/drivers/scsi/bfa/fcbuild.c
+++ b/drivers/scsi/bfa/fcbuild.c
@@ -188,14 +188,14 @@
 	switch (els_cmd->els_code) {
 	case FC_ELS_LS_RJT:
 		if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY)
-			return (FC_PARSE_BUSY);
+			return FC_PARSE_BUSY;
 		else
-			return (FC_PARSE_FAILURE);
+			return FC_PARSE_FAILURE;
 
 	case FC_ELS_ACC:
-		return (FC_PARSE_OK);
+		return FC_PARSE_OK;
 	}
-	return (FC_PARSE_OK);
+	return FC_PARSE_OK;
 }
 
 static void
@@ -228,7 +228,7 @@
 	bfa_os_memcpy(&plogi->port_name, &port_name, sizeof(wwn_t));
 	bfa_os_memcpy(&plogi->node_name, &node_name, sizeof(wwn_t));
 
-	return (sizeof(struct fc_logi_s));
+	return sizeof(struct fc_logi_s);
 }
 
 u16
@@ -267,7 +267,7 @@
 	flogi->csp.npiv_supp    = 1; /* @todo. field name is not correct */
 	vvl_info[0]	= bfa_os_htonl(FLOGI_VVL_BRCD);
 
-	return (sizeof(struct fc_logi_s));
+	return sizeof(struct fc_logi_s);
 }
 
 u16
@@ -287,7 +287,7 @@
 
 	flogi->csp.bbcred = bfa_os_htons(local_bb_credits);
 
-	return (sizeof(struct fc_logi_s));
+	return sizeof(struct fc_logi_s);
 }
 
 u16
@@ -306,7 +306,7 @@
 	flogi->port_name = port_name;
 	flogi->node_name = node_name;
 
-	return (sizeof(struct fc_logi_s));
+	return sizeof(struct fc_logi_s);
 }
 
 u16
@@ -338,26 +338,26 @@
 	case FC_ELS_LS_RJT:
 		ls_rjt = (struct fc_ls_rjt_s *) (fchs + 1);
 		if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY)
-			return (FC_PARSE_BUSY);
+			return FC_PARSE_BUSY;
 		else
-			return (FC_PARSE_FAILURE);
+			return FC_PARSE_FAILURE;
 	case FC_ELS_ACC:
 		plogi = (struct fc_logi_s *) (fchs + 1);
 		if (len < sizeof(struct fc_logi_s))
-			return (FC_PARSE_FAILURE);
+			return FC_PARSE_FAILURE;
 
 		if (!wwn_is_equal(plogi->port_name, port_name))
-			return (FC_PARSE_FAILURE);
+			return FC_PARSE_FAILURE;
 
 		if (!plogi->class3.class_valid)
-			return (FC_PARSE_FAILURE);
+			return FC_PARSE_FAILURE;
 
 		if (bfa_os_ntohs(plogi->class3.rxsz) < (FC_MIN_PDUSZ))
-			return (FC_PARSE_FAILURE);
+			return FC_PARSE_FAILURE;
 
-		return (FC_PARSE_OK);
+		return FC_PARSE_OK;
 	default:
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 	}
 }
 
@@ -372,7 +372,7 @@
 	if ((bfa_os_ntohs(plogi->class3.rxsz) < FC_MIN_PDUSZ)
 	    || (bfa_os_ntohs(plogi->class3.rxsz) > FC_MAX_PDUSZ)
 	    || (plogi->class3.rxsz == 0))
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	return FC_PARSE_OK;
 }
@@ -393,7 +393,7 @@
 	prli->parampage.servparams.task_retry_id = 0;
 	prli->parampage.servparams.confirm       = 1;
 
-	return (sizeof(struct fc_prli_s));
+	return sizeof(struct fc_prli_s);
 }
 
 u16
@@ -414,41 +414,41 @@
 
 	prli->parampage.rspcode = FC_PRLI_ACC_XQTD;
 
-	return (sizeof(struct fc_prli_s));
+	return sizeof(struct fc_prli_s);
 }
 
 enum fc_parse_status
 fc_prli_rsp_parse(struct fc_prli_s *prli, int len)
 {
 	if (len < sizeof(struct fc_prli_s))
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	if (prli->command != FC_ELS_ACC)
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	if ((prli->parampage.rspcode != FC_PRLI_ACC_XQTD)
 	    && (prli->parampage.rspcode != FC_PRLI_ACC_PREDEF_IMG))
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	if (prli->parampage.servparams.target != 1)
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
-	return (FC_PARSE_OK);
+	return FC_PARSE_OK;
 }
 
 enum fc_parse_status
 fc_prli_parse(struct fc_prli_s *prli)
 {
 	if (prli->parampage.type != FC_TYPE_FCP)
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	if (!prli->parampage.imagepair)
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	if (!prli->parampage.servparams.initiator)
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
-	return (FC_PARSE_OK);
+	return FC_PARSE_OK;
 }
 
 u16
@@ -462,7 +462,7 @@
 	logo->nport_id = (s_id);
 	logo->orig_port_name = port_name;
 
-	return (sizeof(struct fc_logo_s));
+	return sizeof(struct fc_logo_s);
 }
 
 static          u16
@@ -484,7 +484,7 @@
 	adisc->orig_node_name = node_name;
 	adisc->nport_id = (s_id);
 
-	return (sizeof(struct fc_adisc_s));
+	return sizeof(struct fc_adisc_s);
 }
 
 u16
@@ -511,15 +511,15 @@
 {
 
 	if (len < sizeof(struct fc_adisc_s))
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	if (adisc->els_cmd.els_code != FC_ELS_ACC)
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	if (!wwn_is_equal(adisc->orig_port_name, port_name))
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
-	return (FC_PARSE_OK);
+	return FC_PARSE_OK;
 }
 
 enum fc_parse_status
@@ -529,14 +529,14 @@
 	struct fc_adisc_s     *adisc = (struct fc_adisc_s *) pld;
 
 	if (adisc->els_cmd.els_code != FC_ELS_ACC)
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	if ((adisc->nport_id == (host_dap))
 	    && wwn_is_equal(adisc->orig_port_name, port_name)
 	    && wwn_is_equal(adisc->orig_node_name, node_name))
-		return (FC_PARSE_OK);
+		return FC_PARSE_OK;
 
-	return (FC_PARSE_FAILURE);
+	return FC_PARSE_FAILURE;
 }
 
 enum fc_parse_status
@@ -550,13 +550,13 @@
 	if ((bfa_os_ntohs(pdisc->class3.rxsz) <
 		 (FC_MIN_PDUSZ - sizeof(struct fchs_s)))
 	    || (pdisc->class3.rxsz == 0))
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	if (!wwn_is_equal(pdisc->port_name, port_name))
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	if (!wwn_is_equal(pdisc->node_name, node_name))
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	return FC_PARSE_OK;
 }
@@ -570,7 +570,7 @@
 	fchs->s_id = (s_id);
 	fchs->ox_id = bfa_os_htons(ox_id);
 
-	return (sizeof(struct fchs_s));
+	return sizeof(struct fchs_s);
 }
 
 enum fc_parse_status
@@ -578,9 +578,9 @@
 {
 	if ((fchs->cat_info == FC_CAT_BA_ACC)
 	    || (fchs->cat_info == FC_CAT_BA_RJT))
-		return (FC_PARSE_OK);
+		return FC_PARSE_OK;
 
-	return (FC_PARSE_FAILURE);
+	return FC_PARSE_FAILURE;
 }
 
 u16
@@ -597,7 +597,7 @@
 	rrq->ox_id = bfa_os_htons(rrq_oxid);
 	rrq->rx_id = FC_RXID_ANY;
 
-	return (sizeof(struct fc_rrq_s));
+	return sizeof(struct fc_rrq_s);
 }
 
 u16
@@ -611,7 +611,7 @@
 	memset(acc, 0, sizeof(struct fc_els_cmd_s));
 	acc->els_code = FC_ELS_ACC;
 
-	return (sizeof(struct fc_els_cmd_s));
+	return sizeof(struct fc_els_cmd_s);
 }
 
 u16
@@ -627,7 +627,7 @@
 	ls_rjt->reason_code_expl = reason_code_expl;
 	ls_rjt->vendor_unique = 0x00;
 
-	return (sizeof(struct fc_ls_rjt_s));
+	return sizeof(struct fc_ls_rjt_s);
 }
 
 u16
@@ -643,7 +643,7 @@
 	ba_acc->ox_id = fchs->ox_id;
 	ba_acc->rx_id = fchs->rx_id;
 
-	return (sizeof(struct fc_ba_acc_s));
+	return sizeof(struct fc_ba_acc_s);
 }
 
 u16
@@ -654,7 +654,7 @@
 	memset(els_cmd, 0, sizeof(struct fc_els_cmd_s));
 	els_cmd->els_code = FC_ELS_ACC;
 
-	return (sizeof(struct fc_els_cmd_s));
+	return sizeof(struct fc_els_cmd_s);
 }
 
 int
@@ -696,7 +696,7 @@
 		tprlo_acc->tprlo_acc_params[page].orig_process_assc = 0;
 		tprlo_acc->tprlo_acc_params[page].resp_process_assc = 0;
 	}
-	return (bfa_os_ntohs(tprlo_acc->payload_len));
+	return bfa_os_ntohs(tprlo_acc->payload_len);
 }
 
 u16
@@ -721,7 +721,7 @@
 		prlo_acc->prlo_acc_params[page].resp_process_assc = 0;
 	}
 
-	return (bfa_os_ntohs(prlo_acc->payload_len));
+	return bfa_os_ntohs(prlo_acc->payload_len);
 }
 
 u16
@@ -735,7 +735,7 @@
 	rnid->els_cmd.els_code = FC_ELS_RNID;
 	rnid->node_id_data_format = data_format;
 
-	return (sizeof(struct fc_rnid_cmd_s));
+	return sizeof(struct fc_rnid_cmd_s);
 }
 
 u16
@@ -759,10 +759,10 @@
 		rnid_acc->specific_id_data_length =
 			sizeof(struct fc_rnid_general_topology_data_s);
 		bfa_os_assign(rnid_acc->gen_topology_data, *gen_topo_data);
-		return (sizeof(struct fc_rnid_acc_s));
+		return sizeof(struct fc_rnid_acc_s);
 	} else {
-		return (sizeof(struct fc_rnid_acc_s) -
-			sizeof(struct fc_rnid_general_topology_data_s));
+		return sizeof(struct fc_rnid_acc_s) -
+			sizeof(struct fc_rnid_general_topology_data_s);
 	}
 
 }
@@ -776,7 +776,7 @@
 	memset(rpsc, 0, sizeof(struct fc_rpsc_cmd_s));
 
 	rpsc->els_cmd.els_code = FC_ELS_RPSC;
-	return (sizeof(struct fc_rpsc_cmd_s));
+	return sizeof(struct fc_rpsc_cmd_s);
 }
 
 u16
@@ -797,8 +797,8 @@
 	for (i = 0; i < npids; i++)
 		rpsc2->pid_list[i].pid = pid_list[i];
 
-	return (sizeof(struct fc_rpsc2_cmd_s) + ((npids - 1) *
-			(sizeof(u32))));
+	return sizeof(struct fc_rpsc2_cmd_s) + ((npids - 1) *
+			(sizeof(u32)));
 }
 
 u16
@@ -819,7 +819,7 @@
 	rpsc_acc->speed_info[0].port_op_speed =
 		bfa_os_htons(oper_speed->port_op_speed);
 
-	return (sizeof(struct fc_rpsc_acc_s));
+	return sizeof(struct fc_rpsc_acc_s);
 
 }
 
@@ -856,7 +856,7 @@
 	pdisc->port_name = port_name;
 	pdisc->node_name = node_name;
 
-	return (sizeof(struct fc_logi_s));
+	return sizeof(struct fc_logi_s);
 }
 
 u16
@@ -865,21 +865,21 @@
 	struct fc_logi_s     *pdisc = (struct fc_logi_s *) (fchs + 1);
 
 	if (len < sizeof(struct fc_logi_s))
-		return (FC_PARSE_LEN_INVAL);
+		return FC_PARSE_LEN_INVAL;
 
 	if (pdisc->els_cmd.els_code != FC_ELS_ACC)
-		return (FC_PARSE_ACC_INVAL);
+		return FC_PARSE_ACC_INVAL;
 
 	if (!wwn_is_equal(pdisc->port_name, port_name))
-		return (FC_PARSE_PWWN_NOT_EQUAL);
+		return FC_PARSE_PWWN_NOT_EQUAL;
 
 	if (!pdisc->class3.class_valid)
-		return (FC_PARSE_NWWN_NOT_EQUAL);
+		return FC_PARSE_NWWN_NOT_EQUAL;
 
 	if (bfa_os_ntohs(pdisc->class3.rxsz) < (FC_MIN_PDUSZ))
-		return (FC_PARSE_RXSZ_INVAL);
+		return FC_PARSE_RXSZ_INVAL;
 
-	return (FC_PARSE_OK);
+	return FC_PARSE_OK;
 }
 
 u16
@@ -903,7 +903,7 @@
 		prlo->prlo_params[page].resp_process_assc = 0;
 	}
 
-	return (bfa_os_ntohs(prlo->payload_len));
+	return bfa_os_ntohs(prlo->payload_len);
 }
 
 u16
@@ -916,7 +916,7 @@
 	len = len;
 
 	if (prlo->command != FC_ELS_ACC)
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	num_pages = ((bfa_os_ntohs(prlo->payload_len)) - 4) / 16;
 
@@ -936,7 +936,7 @@
 		if (prlo->prlo_acc_params[page].resp_process_assc != 0)
 			return FC_PARSE_FAILURE;
 	}
-	return (FC_PARSE_OK);
+	return FC_PARSE_OK;
 
 }
 
@@ -968,7 +968,7 @@
 		}
 	}
 
-	return (bfa_os_ntohs(tprlo->payload_len));
+	return bfa_os_ntohs(tprlo->payload_len);
 }
 
 u16
@@ -981,23 +981,23 @@
 	len = len;
 
 	if (tprlo->command != FC_ELS_ACC)
-		return (FC_PARSE_ACC_INVAL);
+		return FC_PARSE_ACC_INVAL;
 
 	num_pages = (bfa_os_ntohs(tprlo->payload_len) - 4) / 16;
 
 	for (page = 0; page < num_pages; page++) {
 		if (tprlo->tprlo_acc_params[page].type != FC_TYPE_FCP)
-			return (FC_PARSE_NOT_FCP);
+			return FC_PARSE_NOT_FCP;
 		if (tprlo->tprlo_acc_params[page].opa_valid != 0)
-			return (FC_PARSE_OPAFLAG_INVAL);
+			return FC_PARSE_OPAFLAG_INVAL;
 		if (tprlo->tprlo_acc_params[page].rpa_valid != 0)
-			return (FC_PARSE_RPAFLAG_INVAL);
+			return FC_PARSE_RPAFLAG_INVAL;
 		if (tprlo->tprlo_acc_params[page].orig_process_assc != 0)
-			return (FC_PARSE_OPA_INVAL);
+			return FC_PARSE_OPA_INVAL;
 		if (tprlo->tprlo_acc_params[page].resp_process_assc != 0)
-			return (FC_PARSE_RPA_INVAL);
+			return FC_PARSE_RPA_INVAL;
 	}
-	return (FC_PARSE_OK);
+	return FC_PARSE_OK;
 }
 
 enum fc_parse_status
@@ -1024,7 +1024,7 @@
 	fchs->cat_info = FC_CAT_BA_RJT;
 	ba_rjt->reason_code = reason_code;
 	ba_rjt->reason_expl = reason_expl;
-	return (sizeof(struct fc_ba_rjt_s));
+	return sizeof(struct fc_ba_rjt_s);
 }
 
 static void
@@ -1073,7 +1073,7 @@
 
 	bfa_os_memset(gidpn, 0, sizeof(struct fcgs_gidpn_req_s));
 	gidpn->port_name = port_name;
-	return (sizeof(struct fcgs_gidpn_req_s) + sizeof(struct ct_hdr_s));
+	return sizeof(struct fcgs_gidpn_req_s) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1090,7 +1090,7 @@
 
 	bfa_os_memset(gpnid, 0, sizeof(fcgs_gpnid_req_t));
 	gpnid->dap = port_id;
-	return (sizeof(fcgs_gpnid_req_t) + sizeof(struct ct_hdr_s));
+	return sizeof(fcgs_gpnid_req_t) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1107,7 +1107,7 @@
 
 	bfa_os_memset(gnnid, 0, sizeof(fcgs_gnnid_req_t));
 	gnnid->dap = port_id;
-	return (sizeof(fcgs_gnnid_req_t) + sizeof(struct ct_hdr_s));
+	return sizeof(fcgs_gnnid_req_t) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1137,7 +1137,7 @@
 	if (set_br_reg)
 		scr->vu_reg_func = FC_VU_SCR_REG_FUNC_FABRIC_NAME_CHANGE;
 
-	return (sizeof(struct fc_scr_s));
+	return sizeof(struct fc_scr_s);
 }
 
 u16
@@ -1157,7 +1157,7 @@
 	rscn->event[0].format = FC_RSCN_FORMAT_PORTID;
 	rscn->event[0].portid = s_id;
 
-	return (sizeof(struct fc_rscn_pl_s));
+	return sizeof(struct fc_rscn_pl_s);
 }
 
 u16
@@ -1188,7 +1188,7 @@
 		rftid->fc4_type[index] |= bfa_os_htonl(type_value);
 	}
 
-	return (sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s));
+	return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1210,7 +1210,7 @@
 	bfa_os_memcpy((void *)rftid->fc4_type, (void *)fc4_bitmap,
 			(bitmap_size < 32 ? bitmap_size : 32));
 
-	return (sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s));
+	return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1231,7 +1231,7 @@
 	rffid->fc4ftr_bits  = fc4_ftrs;
 	rffid->fc4_type		= fc4_type;
 
-	return (sizeof(struct fcgs_rffid_req_s) + sizeof(struct ct_hdr_s));
+	return sizeof(struct fcgs_rffid_req_s) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1253,7 +1253,7 @@
 	rspnid->spn_len = (u8) strlen((char *)name);
 	strncpy((char *)rspnid->spn, (char *)name, rspnid->spn_len);
 
-	return (sizeof(struct fcgs_rspnid_req_s) + sizeof(struct ct_hdr_s));
+	return sizeof(struct fcgs_rspnid_req_s) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1275,7 +1275,7 @@
 	gidft->domain_id = 0;
 	gidft->area_id = 0;
 
-	return (sizeof(struct fcgs_gidft_req_s) + sizeof(struct ct_hdr_s));
+	return sizeof(struct fcgs_gidft_req_s) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1294,7 +1294,7 @@
 	rpnid->port_id = port_id;
 	rpnid->port_name = port_name;
 
-	return (sizeof(struct fcgs_rpnid_req_s) + sizeof(struct ct_hdr_s));
+	return sizeof(struct fcgs_rpnid_req_s) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1313,7 +1313,7 @@
 	rnnid->port_id = port_id;
 	rnnid->node_name = node_name;
 
-	return (sizeof(struct fcgs_rnnid_req_s) + sizeof(struct ct_hdr_s));
+	return sizeof(struct fcgs_rnnid_req_s) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1332,7 +1332,7 @@
 	rcsid->port_id = port_id;
 	rcsid->cos = cos;
 
-	return (sizeof(struct fcgs_rcsid_req_s) + sizeof(struct ct_hdr_s));
+	return sizeof(struct fcgs_rcsid_req_s) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1351,7 +1351,7 @@
 	rptid->port_id = port_id;
 	rptid->port_type = port_type;
 
-	return (sizeof(struct fcgs_rptid_req_s) + sizeof(struct ct_hdr_s));
+	return sizeof(struct fcgs_rptid_req_s) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1368,7 +1368,7 @@
 	bfa_os_memset(ganxt, 0, sizeof(struct fcgs_ganxt_req_s));
 	ganxt->port_id = port_id;
 
-	return (sizeof(struct ct_hdr_s) + sizeof(struct fcgs_ganxt_req_s));
+	return sizeof(struct ct_hdr_s) + sizeof(struct fcgs_ganxt_req_s);
 }
 
 /*
@@ -1385,7 +1385,7 @@
 	fc_gs_fchdr_build(fchs, d_id, s_id, 0);
 	fc_gs_fdmi_cthdr_build(cthdr, s_id, cmd_code);
 
-	return (sizeof(struct ct_hdr_s));
+	return sizeof(struct ct_hdr_s);
 }
 
 /*
@@ -1425,7 +1425,7 @@
 	bfa_os_memset(gmal, 0, sizeof(fcgs_gmal_req_t));
 	gmal->wwn = wwn;
 
-	return (sizeof(struct ct_hdr_s) + sizeof(fcgs_gmal_req_t));
+	return sizeof(struct ct_hdr_s) + sizeof(fcgs_gmal_req_t);
 }
 
 /*
@@ -1445,5 +1445,5 @@
 	bfa_os_memset(gfn, 0, sizeof(fcgs_gfn_req_t));
 	gfn->wwn = wwn;
 
-	return (sizeof(struct ct_hdr_s) + sizeof(fcgs_gfn_req_t));
+	return sizeof(struct ct_hdr_s) + sizeof(fcgs_gfn_req_t);
 }
diff --git a/drivers/scsi/bfa/fcbuild.h b/drivers/scsi/bfa/fcbuild.h
index 4d24842..8fa7f27 100644
--- a/drivers/scsi/bfa/fcbuild.h
+++ b/drivers/scsi/bfa/fcbuild.h
@@ -32,8 +32,8 @@
  * Utility Macros/functions
  */
 
-#define fcif_sof_set(_ifhdr, _sof)	(_ifhdr)->sof = FC_ ## _sof
-#define fcif_eof_set(_ifhdr, _eof)	(_ifhdr)->eof = FC_ ## _eof
+#define fcif_sof_set(_ifhdr, _sof)	((_ifhdr)->sof = FC_ ## _sof)
+#define fcif_eof_set(_ifhdr, _eof)	((_ifhdr)->eof = FC_ ## _eof)
 
 #define wwn_is_equal(_wwn1, _wwn2)		\
 	(memcmp(&(_wwn1), &(_wwn2), sizeof(wwn_t)) == 0)
@@ -49,7 +49,7 @@
 static inline   u32
 fc_get_ctresp_pyld_len(u32 resp_len)
 {
-	return (resp_len - sizeof(struct ct_hdr_s));
+	return resp_len - sizeof(struct ct_hdr_s);
 }
 
 /*
diff --git a/drivers/scsi/bfa/fcpim.c b/drivers/scsi/bfa/fcpim.c
index 8ce5d893..1f3c06e 100644
--- a/drivers/scsi/bfa/fcpim.c
+++ b/drivers/scsi/bfa/fcpim.c
@@ -286,11 +286,10 @@
 		bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_offline);
 		bfa_fcb_itnim_offline(itnim->itnim_drv);
 		bfa_itnim_offline(itnim->bfa_itnim);
-		if (bfa_fcs_port_is_online(itnim->rport->port) == BFA_TRUE) {
+		if (bfa_fcs_port_is_online(itnim->rport->port) == BFA_TRUE)
 			bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_DISCONNECT);
-		} else {
+		else
 			bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_OFFLINE);
-		}
 		break;
 
 	case BFA_FCS_ITNIM_SM_DELETE:
@@ -732,7 +731,7 @@
 		return NULL;
 
 	bfa_assert(rport->itnim != NULL);
-	return (rport->itnim);
+	return rport->itnim;
 }
 
 bfa_status_t
diff --git a/drivers/scsi/bfa/fcs.h b/drivers/scsi/bfa/fcs.h
index deee685..8d08230 100644
--- a/drivers/scsi/bfa/fcs.h
+++ b/drivers/scsi/bfa/fcs.h
@@ -23,7 +23,7 @@
 #ifndef __FCS_H__
 #define __FCS_H__
 
-#define __fcs_min_cfg(__fcs)       (__fcs)->min_cfg
+#define __fcs_min_cfg(__fcs)       ((__fcs)->min_cfg)
 
 void bfa_fcs_modexit_comp(struct bfa_fcs_s *fcs);
 
diff --git a/drivers/scsi/bfa/fdmi.c b/drivers/scsi/bfa/fdmi.c
index b845eb2..df2a1e5 100644
--- a/drivers/scsi/bfa/fdmi.c
+++ b/drivers/scsi/bfa/fdmi.c
@@ -72,9 +72,9 @@
 			struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld);
 static u16 bfa_fcs_port_fdmi_build_portattr_block(
 			struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld);
-void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi,
+static void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi,
 			struct bfa_fcs_fdmi_hba_attr_s *hba_attr);
-void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s *fdmi,
+static void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s *fdmi,
 			struct bfa_fcs_fdmi_port_attr_s *port_attr);
 /**
  *  fcs_fdmi_sm FCS FDMI state machine
@@ -1091,7 +1091,7 @@
 	bfa_sm_send_event(fdmi, FDMISM_EVENT_TIMEOUT);
 }
 
-void
+static void
 bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi,
 			 struct bfa_fcs_fdmi_hba_attr_s *hba_attr)
 {
@@ -1145,7 +1145,7 @@
 
 }
 
-void
+static void
 bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s *fdmi,
 			  struct bfa_fcs_fdmi_port_attr_s *port_attr)
 {
diff --git a/drivers/scsi/bfa/include/aen/bfa_aen.h b/drivers/scsi/bfa/include/aen/bfa_aen.h
index da8cac0..d9cbc2a 100644
--- a/drivers/scsi/bfa/include/aen/bfa_aen.h
+++ b/drivers/scsi/bfa/include/aen/bfa_aen.h
@@ -54,7 +54,7 @@
 static inline s32
 bfa_aen_get_meminfo(void)
 {
-	return (sizeof(struct bfa_aen_entry_s) * bfa_aen_get_max_cfg_entry());
+	return sizeof(struct bfa_aen_entry_s) * bfa_aen_get_max_cfg_entry();
 }
 
 static inline s32
diff --git a/drivers/scsi/bfa/include/bfa.h b/drivers/scsi/bfa/include/bfa.h
index 64c1412..d4bc0d9 100644
--- a/drivers/scsi/bfa/include/bfa.h
+++ b/drivers/scsi/bfa/include/bfa.h
@@ -76,11 +76,11 @@
 	struct bfa_mem_elem_s meminfo[BFA_MEM_TYPE_MAX];
 };
 #define bfa_meminfo_kva(_m)	\
-	(_m)->meminfo[BFA_MEM_TYPE_KVA - 1].kva_curp
+	((_m)->meminfo[BFA_MEM_TYPE_KVA - 1].kva_curp)
 #define bfa_meminfo_dma_virt(_m)	\
-	(_m)->meminfo[BFA_MEM_TYPE_DMA - 1].kva_curp
+	((_m)->meminfo[BFA_MEM_TYPE_DMA - 1].kva_curp)
 #define bfa_meminfo_dma_phys(_m)	\
-	(_m)->meminfo[BFA_MEM_TYPE_DMA - 1].dma_curp
+	((_m)->meminfo[BFA_MEM_TYPE_DMA - 1].dma_curp)
 
 /**
  * Generic Scatter Gather Element used by driver
@@ -100,7 +100,7 @@
 /*
  * bfa stats interfaces
  */
-#define bfa_stats(_mod, _stats)	(_mod)->stats._stats ++
+#define bfa_stats(_mod, _stats)	((_mod)->stats._stats++)
 
 #define bfa_ioc_get_stats(__bfa, __ioc_stats)	\
 	bfa_ioc_fetch_stats(&(__bfa)->ioc, __ioc_stats)
@@ -136,7 +136,7 @@
 void bfa_isr_disable(struct bfa_s *bfa);
 void bfa_msix_getvecs(struct bfa_s *bfa, u32 *msix_vecs_bmap,
 			u32 *num_vecs, u32 *max_vec_bit);
-#define bfa_msix(__bfa, __vec) (__bfa)->msix.handler[__vec](__bfa, __vec)
+#define bfa_msix(__bfa, __vec) ((__bfa)->msix.handler[__vec](__bfa, __vec))
 
 void bfa_comp_deq(struct bfa_s *bfa, struct list_head *comp_q);
 void bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q);
diff --git a/drivers/scsi/bfa/include/bfa_svc.h b/drivers/scsi/bfa/include/bfa_svc.h
index 0c80b74..268d956 100644
--- a/drivers/scsi/bfa/include/bfa_svc.h
+++ b/drivers/scsi/bfa/include/bfa_svc.h
@@ -34,10 +34,10 @@
  */
 struct bfa_rport_info_s {
 	u16        max_frmsz;	/*  max rcv pdu size               */
-	u32        pid : 24,	/*  remote port ID                 */
-			lp_tag : 8;
-	u32        local_pid : 24,	/*  local port ID		    */
-			cisc : 8;	/*  CIRO supported		    */
+	u32        pid:24,		/*  remote port ID                 */
+			lp_tag:8;
+	u32        local_pid:24,	/*  local port ID		    */
+			cisc:8;		/*  CIRO supported		    */
 	u8         fc_class;	/*  supported FC classes. enum fc_cos */
 	u8         vf_en;		/*  virtual fabric enable          */
 	u16        vf_id;		/*  virtual fabric ID              */
diff --git a/drivers/scsi/bfa/include/bfi/bfi.h b/drivers/scsi/bfa/include/bfi/bfi.h
index 6cadfe0..7042c18 100644
--- a/drivers/scsi/bfa/include/bfi/bfi.h
+++ b/drivers/scsi/bfa/include/bfi/bfi.h
@@ -93,13 +93,13 @@
  */
 struct bfi_sge_s {
 #ifdef __BIGENDIAN
-	u32        flags	: 2,
-			rsvd	: 2,
-			sg_len	: 28;
+	u32        flags:2,
+			rsvd:2,
+			sg_len:28;
 #else
-	u32        sg_len	: 28,
-			rsvd	: 2,
-			flags	: 2;
+	u32        sg_len:28,
+			rsvd:2,
+			flags:2;
 #endif
 	union bfi_addr_u sga;
 };
diff --git a/drivers/scsi/bfa/include/bfi/bfi_ioc.h b/drivers/scsi/bfa/include/bfi/bfi_ioc.h
index 026e9c0..96ef056 100644
--- a/drivers/scsi/bfa/include/bfi/bfi_ioc.h
+++ b/drivers/scsi/bfa/include/bfi/bfi_ioc.h
@@ -142,7 +142,7 @@
 	BFI_ADAPTER_UNSUPP    = 0x400000,	/*  unknown adapter type  */
 };
 
-#define BFI_ADAPTER_GETP(__prop,__adap_prop)          		\
+#define BFI_ADAPTER_GETP(__prop, __adap_prop)          		\
     (((__adap_prop) & BFI_ADAPTER_ ## __prop ## _MK) >>         \
      BFI_ADAPTER_ ## __prop ## _SH)
 #define BFI_ADAPTER_SETP(__prop, __val)         		\
diff --git a/drivers/scsi/bfa/include/bfi/bfi_lps.h b/drivers/scsi/bfa/include/bfi/bfi_lps.h
index 414b0e3..c59d47b 100644
--- a/drivers/scsi/bfa/include/bfi/bfi_lps.h
+++ b/drivers/scsi/bfa/include/bfi/bfi_lps.h
@@ -55,8 +55,8 @@
 	u16	bb_credit;
 	u8		f_port;
 	u8		npiv_en;
-	u32	lp_pid : 24;
-	u32	auth_req : 8;
+	u32	lp_pid:24;
+	u32	auth_req:8;
 	mac_t		lp_mac;
 	mac_t		fcf_mac;
 	u8		ext_status;
diff --git a/drivers/scsi/bfa/include/bfi/bfi_rport.h b/drivers/scsi/bfa/include/bfi/bfi_rport.h
index 3520f55..e1cd83b 100644
--- a/drivers/scsi/bfa/include/bfi/bfi_rport.h
+++ b/drivers/scsi/bfa/include/bfi/bfi_rport.h
@@ -38,10 +38,10 @@
 	struct bfi_mhdr_s  mh;		/*  common msg header		*/
 	u16        bfa_handle;	/*  host rport handle		*/
 	u16        max_frmsz;	/*  max rcv pdu size		*/
-	u32        pid       : 24,	/*  remote port ID		*/
-			lp_tag    : 8;	/*  local port tag		*/
-	u32        local_pid : 24,	/*  local port ID		*/
-			cisc      : 8;
+	u32        pid:24,		/*  remote port ID		*/
+			lp_tag:8;	/*  local port tag		*/
+	u32        local_pid:24,	/*  local port ID		*/
+			cisc:8;
 	u8         fc_class;	/*  supported FC classes	*/
 	u8         vf_en;		/*  virtual fabric enable	*/
 	u16        vf_id;		/*  virtual fabric ID		*/
diff --git a/drivers/scsi/bfa/include/cs/bfa_checksum.h b/drivers/scsi/bfa/include/cs/bfa_checksum.h
index af8c1d5..650f8d0 100644
--- a/drivers/scsi/bfa/include/cs/bfa_checksum.h
+++ b/drivers/scsi/bfa/include/cs/bfa_checksum.h
@@ -31,7 +31,7 @@
 	for (i = 0; i < m; i++)
 		sum ^= buf[i];
 
-	return (sum);
+	return sum;
 }
 
 static inline u16
@@ -43,7 +43,7 @@
 	for (i = 0; i < m; i++)
 		sum ^= buf[i];
 
-	return (sum);
+	return sum;
 }
 
 static inline u8
@@ -55,6 +55,6 @@
 	for (i = 0; i < sz; i++)
 		sum ^= buf[i];
 
-	return (sum);
+	return sum;
 }
 #endif
diff --git a/drivers/scsi/bfa/include/cs/bfa_sm.h b/drivers/scsi/bfa/include/cs/bfa_sm.h
index 9877066..b0a92ba 100644
--- a/drivers/scsi/bfa/include/cs/bfa_sm.h
+++ b/drivers/scsi/bfa/include/cs/bfa_sm.h
@@ -24,8 +24,8 @@
 
 typedef void (*bfa_sm_t)(void *sm, int event);
 
-#define bfa_sm_set_state(_sm, _state)	(_sm)->sm = (bfa_sm_t)(_state)
-#define bfa_sm_send_event(_sm, _event)	(_sm)->sm((_sm), (_event))
+#define bfa_sm_set_state(_sm, _state)	((_sm)->sm = (bfa_sm_t)(_state))
+#define bfa_sm_send_event(_sm, _event)	((_sm)->sm((_sm), (_event)))
 #define bfa_sm_get_state(_sm)		((_sm)->sm)
 #define bfa_sm_cmp_state(_sm, _state)	((_sm)->sm == (bfa_sm_t)(_state))
 
@@ -62,7 +62,7 @@
 } while (0)
 
 #define bfa_fsm_send_event(_fsm, _event)	\
-	(_fsm)->fsm((_fsm), (_event))
+	((_fsm)->fsm((_fsm), (_event)))
 #define bfa_fsm_cmp_state(_fsm, _state)		\
 	((_fsm)->fsm == (bfa_fsm_t)(_state))
 
diff --git a/drivers/scsi/bfa/include/cs/bfa_trc.h b/drivers/scsi/bfa/include/cs/bfa_trc.h
index 3e74392..310771c 100644
--- a/drivers/scsi/bfa/include/cs/bfa_trc.h
+++ b/drivers/scsi/bfa/include/cs/bfa_trc.h
@@ -24,7 +24,7 @@
 #endif
 
 #ifndef BFA_TRC_TS
-#define BFA_TRC_TS(_trcm)	((_trcm)->ticks ++)
+#define BFA_TRC_TS(_trcm)	((_trcm)->ticks++)
 #endif
 
 struct bfa_trc_s {
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_pport.h b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h
index a000bc4..bf32041 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_pport.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h
@@ -61,7 +61,7 @@
  * 		Port operational type (in sync with SNIA port type).
  */
 enum bfa_pport_type {
-	BFA_PPORT_TYPE_UNKNOWN = 1,	/*  port type is unkown */
+	BFA_PPORT_TYPE_UNKNOWN = 1,	/*  port type is unknown */
 	BFA_PPORT_TYPE_TRUNKED = 2,	/*  Trunked mode */
 	BFA_PPORT_TYPE_NPORT   = 5,	/*  P2P with switched fabric */
 	BFA_PPORT_TYPE_NLPORT  = 6,	/*  public loop */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h b/drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h
index 31881d2..ade763db 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h
@@ -25,7 +25,7 @@
  * Temperature sensor status values
  */
 enum bfa_tsensor_status {
-	BFA_TSENSOR_STATUS_UNKNOWN   = 1,   /*  unkown status */
+	BFA_TSENSOR_STATUS_UNKNOWN   = 1,   /*  unknown status */
 	BFA_TSENSOR_STATUS_FAULTY    = 2,   /*  sensor is faulty */
 	BFA_TSENSOR_STATUS_BELOW_MIN = 3,   /*  temperature below mininum */
 	BFA_TSENSOR_STATUS_NOMINAL   = 4,   /*  normal temperature */
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_fabric.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_fabric.h
index 4ffd224..08b79d5 100644
--- a/drivers/scsi/bfa/include/fcs/bfa_fcs_fabric.h
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_fabric.h
@@ -75,7 +75,7 @@
 							    */
 };
 
-#define bfa_fcs_fabric_npiv_capable(__f)    (__f)->is_npiv
+#define bfa_fcs_fabric_npiv_capable(__f)    ((__f)->is_npiv)
 #define bfa_fcs_fabric_is_switched(__f)			\
 	((__f)->fab_type == BFA_FCS_FABRIC_SWITCHED)
 
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h
index b85cba8..967ceb0 100644
--- a/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h
@@ -125,12 +125,12 @@
 struct bfa_fcs_port_s {
 	struct list_head         qe;	/*  used by port/vport */
 	bfa_sm_t               sm;	/*  state machine */
-	struct bfa_fcs_fabric_s *fabric;	/*  parent fabric */
-	struct bfa_port_cfg_s  port_cfg;	/*  port configuration */
+	struct bfa_fcs_fabric_s *fabric;/*  parent fabric */
+	struct bfa_port_cfg_s  port_cfg;/*  port configuration */
 	struct bfa_timer_s link_timer;	/*  timer for link offline */
-	u32        pid : 24;	/*  FC address */
-	u8         lp_tag;		/*  lport tag */
-	u16        num_rports;	/*  Num of r-ports */
+	u32 pid:24;	/*  FC address */
+	u8  lp_tag;	/*  lport tag */
+	u16 num_rports;	/*  Num of r-ports */
 	struct list_head rport_q;	/*  queue of discovered r-ports */
 	struct bfa_fcs_s *fcs;	/*  FCS instance */
 	union bfa_fcs_port_topo_u port_topo;	/*  fabric/loop/n2n details */
@@ -188,13 +188,14 @@
 }
 
 
-#define bfa_fcs_port_get_opertype(_lport)	(_lport)->fabric->oper_type
+#define bfa_fcs_port_get_opertype(_lport)	((_lport)->fabric->oper_type)
 
 
-#define bfa_fcs_port_get_fabric_name(_lport)	(_lport)->fabric->fabric_name
+#define bfa_fcs_port_get_fabric_name(_lport)	((_lport)->fabric->fabric_name)
 
 
-#define bfa_fcs_port_get_fabric_ipaddr(_lport)	(_lport)->fabric->fabric_ip_addr
+#define bfa_fcs_port_get_fabric_ipaddr(_lport) \
+		((_lport)->fabric->fabric_ip_addr)
 
 /**
  * bfa fcs port public functions
diff --git a/drivers/scsi/bfa/include/protocol/ct.h b/drivers/scsi/bfa/include/protocol/ct.h
index c59d663..b82540a 100644
--- a/drivers/scsi/bfa/include/protocol/ct.h
+++ b/drivers/scsi/bfa/include/protocol/ct.h
@@ -82,7 +82,7 @@
 };
 
 /*
- * defintions for CT reason code
+ * definitions for CT reason code
  */
 enum {
 	CT_RSN_INV_CMD		= 0x01,
@@ -129,7 +129,7 @@
 };
 
 /*
- * defintions for the explanation code for all servers
+ * definitions for the explanation code for all servers
  */
 enum {
 	CT_EXP_AUTH_EXCEPTION			= 0xF1,
@@ -193,11 +193,11 @@
 #define FC_GS_FCP_FC4_FEATURE_TARGET	 0x01
 
 struct fcgs_rffid_req_s{
-    u32    rsvd          :8;
-    u32    dap        	  :24;		/* port identifier	*/
-    u32    rsvd1         :16;
-    u32    fc4ftr_bits   :8;		/* fc4 feature bits	*/
-    u32    fc4_type      :8;		/* corresponding FC4 Type */
+    u32    rsvd:8;
+    u32    dap:24;		/* port identifier	*/
+    u32    rsvd1:16;
+    u32    fc4ftr_bits:8;	/* fc4 feature bits	*/
+    u32    fc4_type:8;	/* corresponding FC4 Type */
 };
 
 /**
diff --git a/drivers/scsi/bfa/include/protocol/fc.h b/drivers/scsi/bfa/include/protocol/fc.h
index 3e39ba5..14969ee 100644
--- a/drivers/scsi/bfa/include/protocol/fc.h
+++ b/drivers/scsi/bfa/include/protocol/fc.h
@@ -486,14 +486,14 @@
  * see FC-PH-X table 113 & 115 for explanation also FCP table 8
  */
 struct fc_prli_params_s{
-	u32        reserved: 16;
+	u32        reserved:16;
 #ifdef __BIGENDIAN
-	u32        reserved1: 5;
-	u32        rec_support : 1;
-	u32        task_retry_id : 1;
-	u32        retry : 1;
+	u32        reserved1:5;
+	u32        rec_support:1;
+	u32        task_retry_id:1;
+	u32        retry:1;
 
-	u32        confirm : 1;
+	u32        confirm:1;
 	u32        doverlay:1;
 	u32        initiator:1;
 	u32        target:1;
@@ -502,10 +502,10 @@
 	u32        rxrdisab:1;
 	u32        wxrdisab:1;
 #else
-	u32        retry : 1;
-	u32        task_retry_id : 1;
-	u32        rec_support : 1;
-	u32        reserved1: 5;
+	u32        retry:1;
+	u32        task_retry_id:1;
+	u32        rec_support:1;
+	u32        reserved1:5;
 
 	u32        wxrdisab:1;
 	u32        rxrdisab:1;
@@ -514,7 +514,7 @@
 	u32        target:1;
 	u32        initiator:1;
 	u32        doverlay:1;
-	u32        confirm : 1;
+	u32        confirm:1;
 #endif
 };
 
diff --git a/drivers/scsi/bfa/loop.c b/drivers/scsi/bfa/loop.c
index a418ded..f7c7f4f3 100644
--- a/drivers/scsi/bfa/loop.c
+++ b/drivers/scsi/bfa/loop.c
@@ -58,49 +58,16 @@
 /*
  * Local Functions
  */
-bfa_status_t    bfa_fcs_port_loop_send_plogi(struct bfa_fcs_port_s *port,
-					     u8 alpa);
+static bfa_status_t bfa_fcs_port_loop_send_plogi(struct bfa_fcs_port_s *port,
+					u8 alpa);
 
-void            bfa_fcs_port_loop_plogi_response(void *fcsarg,
-						 struct bfa_fcxp_s *fcxp,
-						 void *cbarg,
-						 bfa_status_t req_status,
-						 u32 rsp_len,
-						 u32 resid_len,
-						 struct fchs_s *rsp_fchs);
-
-bfa_status_t    bfa_fcs_port_loop_send_adisc(struct bfa_fcs_port_s *port,
-					     u8 alpa);
-
-void            bfa_fcs_port_loop_adisc_response(void *fcsarg,
-						 struct bfa_fcxp_s *fcxp,
-						 void *cbarg,
-						 bfa_status_t req_status,
-						 u32 rsp_len,
-						 u32 resid_len,
-						 struct fchs_s *rsp_fchs);
-
-bfa_status_t    bfa_fcs_port_loop_send_plogi_acc(struct bfa_fcs_port_s *port,
-						 u8 alpa);
-
-void            bfa_fcs_port_loop_plogi_acc_response(void *fcsarg,
-						     struct bfa_fcxp_s *fcxp,
-						     void *cbarg,
-						     bfa_status_t req_status,
-						     u32 rsp_len,
-						     u32 resid_len,
-						     struct fchs_s *rsp_fchs);
-
-bfa_status_t    bfa_fcs_port_loop_send_adisc_acc(struct bfa_fcs_port_s *port,
-						 u8 alpa);
-
-void            bfa_fcs_port_loop_adisc_acc_response(void *fcsarg,
-						     struct bfa_fcxp_s *fcxp,
-						     void *cbarg,
-						     bfa_status_t req_status,
-						     u32 rsp_len,
-						     u32 resid_len,
-						     struct fchs_s *rsp_fchs);
+static void bfa_fcs_port_loop_plogi_response(void *fcsarg,
+					struct bfa_fcxp_s *fcxp,
+					void *cbarg,
+					bfa_status_t req_status,
+					u32 rsp_len,
+					u32 resid_len,
+					struct fchs_s *rsp_fchs);
 /**
  *   Called by port to initializar in provate LOOP topology.
  */
@@ -179,7 +146,7 @@
 /**
  * Local Functions.
  */
-bfa_status_t
+static bfa_status_t
 bfa_fcs_port_loop_send_plogi(struct bfa_fcs_port_s *port, u8 alpa)
 {
 	struct fchs_s          fchs;
@@ -208,7 +175,7 @@
 /**
  *   Called by fcxp to notify the Plogi response
  */
-void
+static void
 bfa_fcs_port_loop_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
 				 void *cbarg, bfa_status_t req_status,
 				 u32 rsp_len, u32 resid_len,
@@ -244,179 +211,3 @@
 		bfa_assert(0);
 	}
 }
-
-bfa_status_t
-bfa_fcs_port_loop_send_plogi_acc(struct bfa_fcs_port_s *port, u8 alpa)
-{
-	struct fchs_s          fchs;
-	struct bfa_fcxp_s *fcxp;
-	int             len;
-
-	bfa_trc(port->fcs, alpa);
-
-	fcxp = bfa_fcxp_alloc(NULL, port->fcs->bfa, 0, 0, NULL, NULL, NULL,
-				  NULL);
-	bfa_assert(fcxp);
-
-	len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa,
-				 bfa_fcs_port_get_fcid(port), 0,
-				 port->port_cfg.pwwn, port->port_cfg.nwwn,
-				 bfa_pport_get_maxfrsize(port->fcs->bfa));
-
-	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
-				 FC_CLASS_3, len, &fchs,
-				 bfa_fcs_port_loop_plogi_acc_response,
-				 (void *)port, FC_MAX_PDUSZ, 0); /* No response
-								  * expected
-								  */
-
-	return BFA_STATUS_OK;
-}
-
-/*
- *  Plogi Acc Response
- * We donot do any processing here.
- */
-void
-bfa_fcs_port_loop_plogi_acc_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
-				     void *cbarg, bfa_status_t req_status,
-				     u32 rsp_len, u32 resid_len,
-				     struct fchs_s *rsp_fchs)
-{
-
-	struct bfa_fcs_port_s *port = (struct bfa_fcs_port_s *) cbarg;
-
-	bfa_trc(port->fcs, port->pid);
-
-	/*
-	 * Sanity Checks
-	 */
-	if (req_status != BFA_STATUS_OK) {
-		bfa_trc(port->fcs, req_status);
-		return;
-	}
-}
-
-bfa_status_t
-bfa_fcs_port_loop_send_adisc(struct bfa_fcs_port_s *port, u8 alpa)
-{
-	struct fchs_s          fchs;
-	struct bfa_fcxp_s *fcxp;
-	int             len;
-
-	bfa_trc(port->fcs, alpa);
-
-	fcxp = bfa_fcxp_alloc(NULL, port->fcs->bfa, 0, 0, NULL, NULL, NULL,
-				  NULL);
-	bfa_assert(fcxp);
-
-	len = fc_adisc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa,
-			     bfa_fcs_port_get_fcid(port), 0,
-			     port->port_cfg.pwwn, port->port_cfg.nwwn);
-
-	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
-			  FC_CLASS_3, len, &fchs,
-			  bfa_fcs_port_loop_adisc_response, (void *)port,
-			  FC_MAX_PDUSZ, FC_RA_TOV);
-
-	return BFA_STATUS_OK;
-}
-
-/**
- *   Called by fcxp to notify the ADISC response
- */
-void
-bfa_fcs_port_loop_adisc_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
-				 void *cbarg, bfa_status_t req_status,
-				 u32 rsp_len, u32 resid_len,
-				 struct fchs_s *rsp_fchs)
-{
-	struct bfa_fcs_port_s *port = (struct bfa_fcs_port_s *) cbarg;
-	struct bfa_fcs_rport_s *rport;
-	struct fc_adisc_s     *adisc_resp;
-	struct fc_els_cmd_s   *els_cmd;
-	u32        pid = rsp_fchs->s_id;
-
-	bfa_trc(port->fcs, req_status);
-
-	/*
-	 * Sanity Checks
-	 */
-	if (req_status != BFA_STATUS_OK) {
-		/*
-		 * TBD : we may need to retry certain requests
-		 */
-		bfa_fcxp_free(fcxp);
-		return;
-	}
-
-	els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
-	adisc_resp = (struct fc_adisc_s *) els_cmd;
-
-	if (els_cmd->els_code == FC_ELS_ACC) {
-	} else {
-		bfa_trc(port->fcs, adisc_resp->els_cmd.els_code);
-
-		/*
-		 * TBD: we may need to check for reject codes and retry
-		 */
-		rport = bfa_fcs_port_get_rport_by_pid(port, pid);
-		if (rport) {
-			list_del(&rport->qe);
-			bfa_fcs_rport_delete(rport);
-		}
-
-	}
-	return;
-}
-
-bfa_status_t
-bfa_fcs_port_loop_send_adisc_acc(struct bfa_fcs_port_s *port, u8 alpa)
-{
-	struct fchs_s          fchs;
-	struct bfa_fcxp_s *fcxp;
-	int             len;
-
-	bfa_trc(port->fcs, alpa);
-
-	fcxp = bfa_fcxp_alloc(NULL, port->fcs->bfa, 0, 0, NULL, NULL, NULL,
-				  NULL);
-	bfa_assert(fcxp);
-
-	len = fc_adisc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa,
-				 bfa_fcs_port_get_fcid(port), 0,
-				 port->port_cfg.pwwn, port->port_cfg.nwwn);
-
-	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
-				FC_CLASS_3, len, &fchs,
-				bfa_fcs_port_loop_adisc_acc_response,
-				(void *)port, FC_MAX_PDUSZ, 0); /* no reponse
-								 * expected
-								 */
-
-	return BFA_STATUS_OK;
-}
-
-/*
- *  Adisc Acc Response
- * We donot do any processing here.
- */
-void
-bfa_fcs_port_loop_adisc_acc_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
-				     void *cbarg, bfa_status_t req_status,
-				     u32 rsp_len, u32 resid_len,
-				     struct fchs_s *rsp_fchs)
-{
-
-	struct bfa_fcs_port_s *port = (struct bfa_fcs_port_s *) cbarg;
-
-	bfa_trc(port->fcs, port->pid);
-
-	/*
-	 * Sanity Checks
-	 */
-	if (req_status != BFA_STATUS_OK) {
-		bfa_trc(port->fcs, req_status);
-		return;
-	}
-}
diff --git a/drivers/scsi/bfa/lport_api.c b/drivers/scsi/bfa/lport_api.c
index 8f51a83..1e06792 100644
--- a/drivers/scsi/bfa/lport_api.c
+++ b/drivers/scsi/bfa/lport_api.c
@@ -43,7 +43,7 @@
 struct bfa_fcs_port_s *
 bfa_fcs_get_base_port(struct bfa_fcs_s *fcs)
 {
-	return (&fcs->fabric.bport);
+	return &fcs->fabric.bport;
 }
 
 wwn_t
@@ -88,11 +88,10 @@
 	}
 
 	bfa_trc(fcs, i);
-	if (rport) {
+	if (rport)
 		return rport->pwwn;
-	} else {
+	else
 		return (wwn_t) 0;
-	}
 }
 
 void
@@ -198,17 +197,17 @@
 	vf = bfa_fcs_vf_lookup(fcs, vf_id);
 	if (vf == NULL) {
 		bfa_trc(fcs, vf_id);
-		return (NULL);
+		return NULL;
 	}
 
 	if (!lpwwn || (vf->bport.port_cfg.pwwn == lpwwn))
-		return (&vf->bport);
+		return &vf->bport;
 
 	vport = bfa_fcs_fabric_vport_lookup(vf, lpwwn);
 	if (vport)
-		return (&vport->lport);
+		return &vport->lport;
 
-	return (NULL);
+	return NULL;
 }
 
 /*
diff --git a/drivers/scsi/bfa/ns.c b/drivers/scsi/bfa/ns.c
index 59fea99..2f8b880 100644
--- a/drivers/scsi/bfa/ns.c
+++ b/drivers/scsi/bfa/ns.c
@@ -932,11 +932,10 @@
 	}
 	ns->fcxp = fcxp;
 
-	if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
+	if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port))
 		fc4_ftrs = FC_GS_FCP_FC4_FEATURE_INITIATOR;
-	} else if (BFA_FCS_VPORT_IS_TARGET_MODE(ns->port)) {
+	else if (BFA_FCS_VPORT_IS_TARGET_MODE(ns->port))
 		fc4_ftrs = FC_GS_FCP_FC4_FEATURE_TARGET;
-	}
 
 	len = fc_rffid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
 			     bfa_fcs_port_get_fcid(port), 0, FC_TYPE_FCP,
diff --git a/drivers/scsi/bfa/plog.c b/drivers/scsi/bfa/plog.c
index 86af818..fcb8864 100644
--- a/drivers/scsi/bfa/plog.c
+++ b/drivers/scsi/bfa/plog.c
@@ -180,5 +180,5 @@
 bfa_boolean_t
 bfa_plog_get_setting(struct bfa_plog_s *plog)
 {
-	return((bfa_boolean_t)plog->plog_enabled);
+	return (bfa_boolean_t)plog->plog_enabled;
 }
diff --git a/drivers/scsi/bfa/rport_ftrs.c b/drivers/scsi/bfa/rport_ftrs.c
index 8a1f59d..e1932c8 100644
--- a/drivers/scsi/bfa/rport_ftrs.c
+++ b/drivers/scsi/bfa/rport_ftrs.c
@@ -79,7 +79,7 @@
 	bfa_trc(rport->fcs, event);
 
 	switch (event) {
-	case RPFSM_EVENT_RPORT_ONLINE :
+	case RPFSM_EVENT_RPORT_ONLINE:
 		if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
 			bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
 			rpf->rpsc_retries = 0;
@@ -87,7 +87,7 @@
 			break;
 		};
 
-	case RPFSM_EVENT_RPORT_OFFLINE :
+	case RPFSM_EVENT_RPORT_OFFLINE:
 		break;
 
 	default:
@@ -107,7 +107,7 @@
 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc);
 		break;
 
-	case RPFSM_EVENT_RPORT_OFFLINE :
+	case RPFSM_EVENT_RPORT_OFFLINE:
 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rpf->fcxp_wqe);
 		rpf->rpsc_retries = 0;
@@ -130,11 +130,10 @@
 	case RPFSM_EVENT_RPSC_COMP:
 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
 		/* Update speed info in f/w via BFA */
-		if (rpf->rpsc_speed != BFA_PPORT_SPEED_UNKNOWN) {
+		if (rpf->rpsc_speed != BFA_PPORT_SPEED_UNKNOWN)
 			bfa_rport_speed(rport->bfa_rport, rpf->rpsc_speed);
-		} else if (rpf->assigned_speed != BFA_PPORT_SPEED_UNKNOWN) {
+		else if (rpf->assigned_speed != BFA_PPORT_SPEED_UNKNOWN)
 			bfa_rport_speed(rport->bfa_rport, rpf->assigned_speed);
-		}
 		break;
 
 	case RPFSM_EVENT_RPSC_FAIL:
@@ -154,7 +153,7 @@
 		}
 		break;
 
-	case RPFSM_EVENT_RPORT_OFFLINE :
+	case RPFSM_EVENT_RPORT_OFFLINE:
 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
 		bfa_fcxp_discard(rpf->fcxp);
 		rpf->rpsc_retries = 0;
@@ -174,13 +173,13 @@
 	bfa_trc(rport->fcs, event);
 
 	switch (event) {
-	case RPFSM_EVENT_TIMEOUT :
+	case RPFSM_EVENT_TIMEOUT:
 		/* re-send the RPSC */
 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
 		bfa_fcs_rpf_send_rpsc2(rpf, NULL);
 		break;
 
-	case RPFSM_EVENT_RPORT_OFFLINE :
+	case RPFSM_EVENT_RPORT_OFFLINE:
 		bfa_timer_stop(&rpf->timer);
 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
 		rpf->rpsc_retries = 0;
@@ -201,7 +200,7 @@
 	bfa_trc(rport->fcs, event);
 
 	switch (event) {
-	case RPFSM_EVENT_RPORT_OFFLINE :
+	case RPFSM_EVENT_RPORT_OFFLINE:
 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
 		rpf->rpsc_retries = 0;
 		break;
@@ -221,12 +220,12 @@
 	bfa_trc(rport->fcs, event);
 
 	switch (event) {
-	case RPFSM_EVENT_RPORT_ONLINE :
+	case RPFSM_EVENT_RPORT_ONLINE:
 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
 		bfa_fcs_rpf_send_rpsc2(rpf, NULL);
 		break;
 
-	case RPFSM_EVENT_RPORT_OFFLINE :
+	case RPFSM_EVENT_RPORT_OFFLINE:
 		break;
 
 	default:
@@ -366,10 +365,9 @@
 		bfa_trc(rport->fcs, ls_rjt->reason_code);
 		bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
 		rport->stats.rpsc_rejects++;
-		if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP) {
+		if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP)
 			bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_FAIL);
-		} else {
+		else
 			bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
-		}
 	}
 }
diff --git a/drivers/scsi/bfa/vfapi.c b/drivers/scsi/bfa/vfapi.c
index 31d81fe..391a479 100644
--- a/drivers/scsi/bfa/vfapi.c
+++ b/drivers/scsi/bfa/vfapi.c
@@ -189,7 +189,7 @@
 {
 	bfa_trc(fcs, vf_id);
 	if (vf_id == FC_VF_ID_NULL)
-		return (&fcs->fabric);
+		return &fcs->fabric;
 
 	/**
 	 * @todo vf support
diff --git a/drivers/scsi/bfa/vport.c b/drivers/scsi/bfa/vport.c
index c10af06..e90f1e3 100644
--- a/drivers/scsi/bfa/vport.c
+++ b/drivers/scsi/bfa/vport.c
@@ -31,13 +31,13 @@
 
 BFA_TRC_FILE(FCS, VPORT);
 
-#define __vport_fcs(__vp)       (__vp)->lport.fcs
-#define __vport_pwwn(__vp)      (__vp)->lport.port_cfg.pwwn
-#define __vport_nwwn(__vp)      (__vp)->lport.port_cfg.nwwn
-#define __vport_bfa(__vp)       (__vp)->lport.fcs->bfa
-#define __vport_fcid(__vp)      (__vp)->lport.pid
-#define __vport_fabric(__vp)    (__vp)->lport.fabric
-#define __vport_vfid(__vp)      (__vp)->lport.fabric->vf_id
+#define __vport_fcs(__vp)       ((__vp)->lport.fcs)
+#define __vport_pwwn(__vp)      ((__vp)->lport.port_cfg.pwwn)
+#define __vport_nwwn(__vp)      ((__vp)->lport.port_cfg.nwwn)
+#define __vport_bfa(__vp)       ((__vp)->lport.fcs->bfa)
+#define __vport_fcid(__vp)      ((__vp)->lport.pid)
+#define __vport_fabric(__vp)    ((__vp)->lport.fabric)
+#define __vport_vfid(__vp)      ((__vp)->lport.fabric->vf_id)
 
 #define BFA_FCS_VPORT_MAX_RETRIES  5
 /*
@@ -641,9 +641,9 @@
 	bfa_get_attr(fcs->bfa, &ioc_attr);
 
 	if (ioc_attr.pci_attr.device_id == BFA_PCI_DEVICE_ID_CT)
-		return (BFA_FCS_MAX_VPORTS_SUPP_CT);
+		return BFA_FCS_MAX_VPORTS_SUPP_CT;
 	else
-		return (BFA_FCS_MAX_VPORTS_SUPP_CB);
+		return BFA_FCS_MAX_VPORTS_SUPP_CB;
 }
 
 
@@ -675,7 +675,7 @@
 		     struct bfad_vport_s *vport_drv)
 {
 	if (vport_cfg->pwwn == 0)
-		return (BFA_STATUS_INVALID_WWN);
+		return BFA_STATUS_INVALID_WWN;
 
 	if (bfa_fcs_port_get_pwwn(&fcs->fabric.bport) == vport_cfg->pwwn)
 		return BFA_STATUS_VPORT_WWN_BP;
diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h
index 5edde1a..2b973f3 100644
--- a/drivers/scsi/bnx2i/bnx2i.h
+++ b/drivers/scsi/bnx2i/bnx2i.h
@@ -232,7 +232,6 @@
 	struct iscsi_cls_conn *cls_conn;
 	struct bnx2i_hba *hba;
 	struct completion cmd_cleanup_cmpl;
-	int is_bound;
 
 	u32 iscsi_conn_cid;
 #define BNX2I_CID_RESERVED	0x5AFF
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index cafb888..132898c 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -1161,9 +1161,6 @@
 	struct bnx2i_cmd *cmd = task->dd_data;
 	struct iscsi_cmd *hdr = (struct iscsi_cmd *) task->hdr;
 
-	if (!bnx2i_conn->is_bound)
-		return -ENOTCONN;
-
 	/*
 	 * If there is no scsi_cmnd this must be a mgmt task
 	 */
@@ -1371,7 +1368,6 @@
 	bnx2i_conn->ep = bnx2i_ep;
 	bnx2i_conn->iscsi_conn_cid = bnx2i_ep->ep_iscsi_cid;
 	bnx2i_conn->fw_cid = bnx2i_ep->ep_cid;
-	bnx2i_conn->is_bound = 1;
 
 	ret_code = bnx2i_bind_conn_to_iscsi_cid(hba, bnx2i_conn,
 						bnx2i_ep->ep_iscsi_cid);
@@ -1883,7 +1879,7 @@
 
 	bnx2i_ep = ep->dd_data;
 
-	/* driver should not attempt connection cleanup untill TCP_CONNECT
+	/* driver should not attempt connection cleanup until TCP_CONNECT
 	 * completes either successfully or fails. Timeout is 9-secs, so
 	 * wait for it to complete
 	 */
@@ -1896,9 +1892,7 @@
 		conn = bnx2i_conn->cls_conn->dd_data;
 		session = conn->session;
 
-		spin_lock_bh(&session->lock);
-		bnx2i_conn->is_bound = 0;
-		spin_unlock_bh(&session->lock);
+		iscsi_suspend_queue(conn);
 	}
 
 	hba = bnx2i_ep->hba;
@@ -2034,7 +2028,7 @@
 				  ISCSI_USERNAME | ISCSI_PASSWORD |
 				  ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
 				  ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
-				  ISCSI_LU_RESET_TMO |
+				  ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO |
 				  ISCSI_PING_TMO | ISCSI_RECV_TMO |
 				  ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
 	.host_param_mask	= ISCSI_HOST_HWADDRESS | ISCSI_HOST_NETDEV_NAME,
diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c
index 63abb06..9129bcf 100644
--- a/drivers/scsi/constants.c
+++ b/drivers/scsi/constants.c
@@ -141,6 +141,7 @@
 static const struct value_name_pair serv_in16_arr[] = {
 	{0x10, "Read capacity(16)"},
 	{0x11, "Read long(16)"},
+	{0x12, "Get LBA status"},
 };
 #define SERV_IN16_SZ ARRAY_SIZE(serv_in16_arr)
 
diff --git a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
index 2631bdd..969c831 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
@@ -937,7 +937,7 @@
 				ISCSI_USERNAME | ISCSI_PASSWORD |
 				ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
 				ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
-				ISCSI_LU_RESET_TMO |
+				ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO |
 				ISCSI_PING_TMO | ISCSI_RECV_TMO |
 				ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
 	.host_param_mask	= ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS |
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
index 075e239..6c59c02 100644
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -1509,7 +1509,7 @@
 		 * Try anyway?
 		 *
 		 * We could, BUT: Sometimes the TRM_S1040 misses to produce a Selection
-		 * Timeout, a Disconnect or a Reselction IRQ, so we would be screwed!
+		 * Timeout, a Disconnect or a Reselection IRQ, so we would be screwed!
 		 * (This is likely to be a bug in the hardware. Obviously, most people
 		 *  only have one initiator per SCSI bus.)
 		 * Instead let this fail and have the timer make sure the command is 
diff --git a/drivers/scsi/device_handler/scsi_dh.c b/drivers/scsi/device_handler/scsi_dh.c
index 3ee1cbc..e19a1a5 100644
--- a/drivers/scsi/device_handler/scsi_dh.c
+++ b/drivers/scsi/device_handler/scsi_dh.c
@@ -226,7 +226,7 @@
 			 * Activate a device handler
 			 */
 			if (scsi_dh->activate)
-				err = scsi_dh->activate(sdev);
+				err = scsi_dh->activate(sdev, NULL, NULL);
 			else
 				err = 0;
 		}
@@ -304,18 +304,15 @@
 	sdev = to_scsi_device(dev);
 
 	if (action == BUS_NOTIFY_ADD_DEVICE) {
+		err = device_create_file(dev, &scsi_dh_state_attr);
+		/* don't care about err */
 		devinfo = device_handler_match(NULL, sdev);
-		if (!devinfo)
-			goto out;
-
-		err = scsi_dh_handler_attach(sdev, devinfo);
-		if (!err)
-			err = device_create_file(dev, &scsi_dh_state_attr);
+		if (devinfo)
+			err = scsi_dh_handler_attach(sdev, devinfo);
 	} else if (action == BUS_NOTIFY_DEL_DEVICE) {
 		device_remove_file(dev, &scsi_dh_state_attr);
 		scsi_dh_handler_detach(sdev, NULL);
 	}
-out:
 	return err;
 }
 
@@ -423,10 +420,17 @@
 /*
  * scsi_dh_activate - activate the path associated with the scsi_device
  *      corresponding to the given request queue.
- * @q - Request queue that is associated with the scsi_device to be
- *      activated.
+ *     Returns immediately without waiting for activation to be completed.
+ * @q    - Request queue that is associated with the scsi_device to be
+ *         activated.
+ * @fn   - Function to be called upon completion of the activation.
+ *         Function fn is called with data (below) and the error code.
+ *         Function fn may be called from the same calling context. So,
+ *         do not hold the lock in the caller which may be needed in fn.
+ * @data - data passed to the function fn upon completion.
+ *
  */
-int scsi_dh_activate(struct request_queue *q)
+int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data)
 {
 	int err = 0;
 	unsigned long flags;
@@ -445,7 +449,7 @@
 		return err;
 
 	if (scsi_dh->activate)
-		err = scsi_dh->activate(sdev);
+		err = scsi_dh->activate(sdev, fn, data);
 	put_device(&sdev->sdev_gendev);
 	return err;
 }
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index b5cdefa..4f0d013 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -60,11 +60,17 @@
 	int			bufflen;
 	unsigned char		sense[SCSI_SENSE_BUFFERSIZE];
 	int			senselen;
+	struct scsi_device	*sdev;
+	activate_complete	callback_fn;
+	void			*callback_data;
 };
 
 #define ALUA_POLICY_SWITCH_CURRENT	0
 #define ALUA_POLICY_SWITCH_ALL		1
 
+static char print_alua_state(int);
+static int alua_check_sense(struct scsi_device *, struct scsi_sense_hdr *);
+
 static inline struct alua_dh_data *get_alua_data(struct scsi_device *sdev)
 {
 	struct scsi_dh_data *scsi_dh_data = sdev->scsi_dh_data;
@@ -231,18 +237,71 @@
 }
 
 /*
+ * alua_stpg - Evaluate SET TARGET GROUP STATES
+ * @sdev: the device to be evaluated
+ * @state: the new target group state
+ *
+ * Send a SET TARGET GROUP STATES command to the device.
+ * We only have to test here if we should resubmit the command;
+ * any other error is assumed as a failure.
+ */
+static void stpg_endio(struct request *req, int error)
+{
+	struct alua_dh_data *h = req->end_io_data;
+	struct scsi_sense_hdr sense_hdr;
+	unsigned err = SCSI_DH_IO;
+
+	if (error || host_byte(req->errors) != DID_OK ||
+			msg_byte(req->errors) != COMMAND_COMPLETE)
+		goto done;
+
+	if (err == SCSI_DH_IO && h->senselen > 0) {
+		err = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE,
+					   &sense_hdr);
+		if (!err) {
+			err = SCSI_DH_IO;
+			goto done;
+		}
+		err = alua_check_sense(h->sdev, &sense_hdr);
+		if (err == ADD_TO_MLQUEUE) {
+			err = SCSI_DH_RETRY;
+			goto done;
+		}
+		sdev_printk(KERN_INFO, h->sdev,
+			    "%s: stpg sense code: %02x/%02x/%02x\n",
+			    ALUA_DH_NAME, sense_hdr.sense_key,
+			    sense_hdr.asc, sense_hdr.ascq);
+		err = SCSI_DH_IO;
+	}
+	if (err == SCSI_DH_OK) {
+		h->state = TPGS_STATE_OPTIMIZED;
+		sdev_printk(KERN_INFO, h->sdev,
+			    "%s: port group %02x switched to state %c\n",
+			    ALUA_DH_NAME, h->group_id,
+			    print_alua_state(h->state));
+	}
+done:
+	blk_put_request(req);
+	if (h->callback_fn) {
+		h->callback_fn(h->callback_data, err);
+		h->callback_fn = h->callback_data = NULL;
+	}
+	return;
+}
+
+/*
  * submit_stpg - Issue a SET TARGET GROUP STATES command
- * @sdev: sdev the command should be sent to
  *
  * Currently we're only setting the current target port group state
  * to 'active/optimized' and let the array firmware figure out
  * the states of the remaining groups.
  */
-static unsigned submit_stpg(struct scsi_device *sdev, struct alua_dh_data *h)
+static unsigned submit_stpg(struct alua_dh_data *h)
 {
 	struct request *rq;
 	int err = SCSI_DH_RES_TEMP_UNAVAIL;
 	int stpg_len = 8;
+	struct scsi_device *sdev = h->sdev;
 
 	/* Prepare the data buffer */
 	memset(h->buff, 0, stpg_len);
@@ -252,7 +311,7 @@
 
 	rq = get_alua_req(sdev, h->buff, stpg_len, WRITE);
 	if (!rq)
-		goto done;
+		return SCSI_DH_RES_TEMP_UNAVAIL;
 
 	/* Prepare the command. */
 	rq->cmd[0] = MAINTENANCE_OUT;
@@ -266,17 +325,9 @@
 	rq->sense = h->sense;
 	memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
 	rq->sense_len = h->senselen = 0;
+	rq->end_io_data = h;
 
-	err = blk_execute_rq(rq->q, NULL, rq, 1);
-	if (err == -EIO) {
-		sdev_printk(KERN_INFO, sdev,
-			    "%s: stpg failed with %x\n",
-			    ALUA_DH_NAME, rq->errors);
-		h->senselen = rq->sense_len;
-		err = SCSI_DH_IO;
-	}
-	blk_put_request(rq);
-done:
+	blk_execute_rq_nowait(rq->q, NULL, rq, 1, stpg_endio);
 	return err;
 }
 
@@ -477,50 +528,6 @@
 }
 
 /*
- * alua_stpg - Evaluate SET TARGET GROUP STATES
- * @sdev: the device to be evaluated
- * @state: the new target group state
- *
- * Send a SET TARGET GROUP STATES command to the device.
- * We only have to test here if we should resubmit the command;
- * any other error is assumed as a failure.
- */
-static int alua_stpg(struct scsi_device *sdev, int state,
-		     struct alua_dh_data *h)
-{
-	struct scsi_sense_hdr sense_hdr;
-	unsigned err;
-	int retry = ALUA_FAILOVER_RETRIES;
-
- retry:
-	err = submit_stpg(sdev, h);
-	if (err == SCSI_DH_IO && h->senselen > 0) {
-		err = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE,
-					   &sense_hdr);
-		if (!err)
-			return SCSI_DH_IO;
-		err = alua_check_sense(sdev, &sense_hdr);
-		if (retry > 0 && err == ADD_TO_MLQUEUE) {
-			retry--;
-			goto retry;
-		}
-		sdev_printk(KERN_INFO, sdev,
-			    "%s: stpg sense code: %02x/%02x/%02x\n",
-			    ALUA_DH_NAME, sense_hdr.sense_key,
-			    sense_hdr.asc, sense_hdr.ascq);
-		err = SCSI_DH_IO;
-	}
-	if (err == SCSI_DH_OK) {
-		h->state = state;
-		sdev_printk(KERN_INFO, sdev,
-			    "%s: port group %02x switched to state %c\n",
-			    ALUA_DH_NAME, h->group_id,
-			    print_alua_state(h->state) );
-	}
-	return err;
-}
-
-/*
  * alua_rtpg - Evaluate REPORT TARGET GROUP STATES
  * @sdev: the device to be evaluated.
  *
@@ -652,7 +659,8 @@
  * based on a certain policy. But until we actually encounter them it
  * should be okay.
  */
-static int alua_activate(struct scsi_device *sdev)
+static int alua_activate(struct scsi_device *sdev,
+			activate_complete fn, void *data)
 {
 	struct alua_dh_data *h = get_alua_data(sdev);
 	int err = SCSI_DH_OK;
@@ -663,11 +671,19 @@
 			goto out;
 	}
 
-	if (h->tpgs & TPGS_MODE_EXPLICIT && h->state != TPGS_STATE_OPTIMIZED)
-		err = alua_stpg(sdev, TPGS_STATE_OPTIMIZED, h);
+	if (h->tpgs & TPGS_MODE_EXPLICIT && h->state != TPGS_STATE_OPTIMIZED) {
+		h->callback_fn = fn;
+		h->callback_data = data;
+		err = submit_stpg(h);
+		if (err == SCSI_DH_OK)
+			return 0;
+		h->callback_fn = h->callback_data = NULL;
+	}
 
 out:
-	return err;
+	if (fn)
+		fn(data, err);
+	return 0;
 }
 
 /*
@@ -745,6 +761,7 @@
 	h->rel_port = -1;
 	h->buff = h->inq;
 	h->bufflen = ALUA_INQUIRY_SIZE;
+	h->sdev = sdev;
 
 	err = alua_initialize(sdev, h);
 	if (err != SCSI_DH_OK)
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c
index 0cffe84..61966750 100644
--- a/drivers/scsi/device_handler/scsi_dh_emc.c
+++ b/drivers/scsi/device_handler/scsi_dh_emc.c
@@ -528,7 +528,8 @@
 	return err;
 }
 
-static int clariion_activate(struct scsi_device *sdev)
+static int clariion_activate(struct scsi_device *sdev,
+				activate_complete fn, void *data)
 {
 	struct clariion_dh_data *csdev = get_clariion_data(sdev);
 	int result;
@@ -559,7 +560,9 @@
 		    csdev->port, lun_state[csdev->lun_state],
 		    csdev->default_sp + 'A');
 
-	return result;
+	if (fn)
+		fn(data, result);
+	return 0;
 }
 /*
  * params - parameters in the following format
diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
index f7da753..857fdd6 100644
--- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c
+++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
@@ -39,8 +39,14 @@
 	unsigned char sense[SCSI_SENSE_BUFFERSIZE];
 	int path_state;
 	int retries;
+	int retry_cnt;
+	struct scsi_device *sdev;
+	activate_complete	callback_fn;
+	void			*callback_data;
 };
 
+static int hp_sw_start_stop(struct hp_sw_dh_data *);
+
 static inline struct hp_sw_dh_data *get_hp_sw_data(struct scsi_device *sdev)
 {
 	struct scsi_dh_data *scsi_dh_data = sdev->scsi_dh_data;
@@ -191,19 +197,53 @@
 	return rc;
 }
 
+static void start_stop_endio(struct request *req, int error)
+{
+	struct hp_sw_dh_data *h = req->end_io_data;
+	unsigned err = SCSI_DH_OK;
+
+	if (error || host_byte(req->errors) != DID_OK ||
+			msg_byte(req->errors) != COMMAND_COMPLETE) {
+		sdev_printk(KERN_WARNING, h->sdev,
+			    "%s: sending start_stop_unit failed with %x\n",
+			    HP_SW_NAME, req->errors);
+		err = SCSI_DH_IO;
+		goto done;
+	}
+
+	if (req->sense_len > 0) {
+		err = start_done(h->sdev, h->sense);
+		if (err == SCSI_DH_RETRY) {
+			err = SCSI_DH_IO;
+			if (--h->retry_cnt) {
+				blk_put_request(req);
+				err = hp_sw_start_stop(h);
+				if (err == SCSI_DH_OK)
+					return;
+			}
+		}
+	}
+done:
+	blk_put_request(req);
+	if (h->callback_fn) {
+		h->callback_fn(h->callback_data, err);
+		h->callback_fn = h->callback_data = NULL;
+	}
+	return;
+
+}
+
 /*
  * hp_sw_start_stop - Send START STOP UNIT command
  * @sdev: sdev command should be sent to
  *
  * Sending START STOP UNIT activates the SP.
  */
-static int hp_sw_start_stop(struct scsi_device *sdev, struct hp_sw_dh_data *h)
+static int hp_sw_start_stop(struct hp_sw_dh_data *h)
 {
 	struct request *req;
-	int ret, retry;
 
-retry:
-	req = blk_get_request(sdev->request_queue, WRITE, GFP_NOIO);
+	req = blk_get_request(h->sdev->request_queue, WRITE, GFP_ATOMIC);
 	if (!req)
 		return SCSI_DH_RES_TEMP_UNAVAIL;
 
@@ -217,32 +257,10 @@
 	req->sense = h->sense;
 	memset(req->sense, 0, SCSI_SENSE_BUFFERSIZE);
 	req->sense_len = 0;
-	retry = h->retries;
+	req->end_io_data = h;
 
-	ret = blk_execute_rq(req->q, NULL, req, 1);
-	if (ret == -EIO) {
-		if (req->sense_len > 0) {
-			ret = start_done(sdev, h->sense);
-		} else {
-			sdev_printk(KERN_WARNING, sdev,
-				    "%s: sending start_stop_unit failed with %x\n",
-				    HP_SW_NAME, req->errors);
-			ret = SCSI_DH_IO;
-		}
-	} else
-		ret = SCSI_DH_OK;
-
-	if (ret == SCSI_DH_RETRY) {
-		if (--retry) {
-			blk_put_request(req);
-			goto retry;
-		}
-		ret = SCSI_DH_IO;
-	}
-
-	blk_put_request(req);
-
-	return ret;
+	blk_execute_rq_nowait(req->q, NULL, req, 1, start_stop_endio);
+	return SCSI_DH_OK;
 }
 
 static int hp_sw_prep_fn(struct scsi_device *sdev, struct request *req)
@@ -268,7 +286,8 @@
  * activate the passive path (and deactivate the
  * previously active one).
  */
-static int hp_sw_activate(struct scsi_device *sdev)
+static int hp_sw_activate(struct scsi_device *sdev,
+				activate_complete fn, void *data)
 {
 	int ret = SCSI_DH_OK;
 	struct hp_sw_dh_data *h = get_hp_sw_data(sdev);
@@ -276,14 +295,18 @@
 	ret = hp_sw_tur(sdev, h);
 
 	if (ret == SCSI_DH_OK && h->path_state == HP_SW_PATH_PASSIVE) {
-		ret = hp_sw_start_stop(sdev, h);
+		h->retry_cnt = h->retries;
+		h->callback_fn = fn;
+		h->callback_data = data;
+		ret = hp_sw_start_stop(h);
 		if (ret == SCSI_DH_OK)
-			sdev_printk(KERN_INFO, sdev,
-				    "%s: activated path\n",
-				    HP_SW_NAME);
+			return 0;
+		h->callback_fn = h->callback_data = NULL;
 	}
 
-	return ret;
+	if (fn)
+		fn(data, ret);
+	return 0;
 }
 
 static const struct scsi_dh_devlist hp_sw_dh_data_list[] = {
@@ -326,6 +349,7 @@
 	h = (struct hp_sw_dh_data *) scsi_dh_data->buf;
 	h->path_state = HP_SW_PATH_UNINITIALIZED;
 	h->retries = HP_SW_RETRIES;
+	h->sdev = sdev;
 
 	ret = hp_sw_tur(sdev, h);
 	if (ret != SCSI_DH_OK || h->path_state == HP_SW_PATH_UNINITIALIZED)
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index 268189d..47cfe1c 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -22,6 +22,7 @@
 #include <scsi/scsi.h>
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_dh.h>
+#include <linux/workqueue.h>
 
 #define RDAC_NAME "rdac"
 #define RDAC_RETRY_COUNT 5
@@ -138,7 +139,13 @@
 	} mode_select;
 	u8	index;
 	u8	array_name[ARRAY_LABEL_LEN];
+	spinlock_t		ms_lock;
+	int			ms_queued;
+	struct work_struct	ms_work;
+	struct scsi_device	*ms_sdev;
+	struct list_head	ms_head;
 };
+
 struct c8_inquiry {
 	u8	peripheral_info;
 	u8	page_code; /* 0xC8 */
@@ -198,8 +205,17 @@
 	"owned (AVT mode)",
 };
 
+struct rdac_queue_data {
+	struct list_head	entry;
+	struct rdac_dh_data	*h;
+	activate_complete	callback_fn;
+	void			*callback_data;
+};
+
 static LIST_HEAD(ctlr_list);
 static DEFINE_SPINLOCK(list_lock);
+static struct workqueue_struct *kmpath_rdacd;
+static void send_mode_select(struct work_struct *work);
 
 /*
  * module parameter to enable rdac debug logging.
@@ -281,7 +297,6 @@
 		rdac_pg->subpage_code = 0x1;
 		rdac_pg->page_len[0] = 0x01;
 		rdac_pg->page_len[1] = 0x28;
-		rdac_pg->lun_table[h->lun] = 0x81;
 	} else {
 		struct rdac_pg_legacy *rdac_pg;
 
@@ -291,7 +306,6 @@
 		common = &rdac_pg->common;
 		rdac_pg->page_code = RDAC_PAGE_CODE_REDUNDANT_CONTROLLER;
 		rdac_pg->page_len = 0x68;
-		rdac_pg->lun_table[h->lun] = 0x81;
 	}
 	common->rdac_mode[1] = RDAC_MODE_TRANSFER_SPECIFIED_LUNS;
 	common->quiescence_timeout = RDAC_QUIESCENCE_TIME;
@@ -325,6 +339,7 @@
 	struct rdac_controller *ctlr;
 	ctlr = container_of(kref, struct rdac_controller, kref);
 
+	flush_workqueue(kmpath_rdacd);
 	spin_lock(&list_lock);
 	list_del(&ctlr->node);
 	spin_unlock(&list_lock);
@@ -363,6 +378,11 @@
 
 	kref_init(&ctlr->kref);
 	ctlr->use_ms10 = -1;
+	ctlr->ms_queued = 0;
+	ctlr->ms_sdev = NULL;
+	spin_lock_init(&ctlr->ms_lock);
+	INIT_WORK(&ctlr->ms_work, send_mode_select);
+	INIT_LIST_HEAD(&ctlr->ms_head);
 	list_add(&ctlr->node, &ctlr_list);
 done:
 	spin_unlock(&list_lock);
@@ -490,7 +510,7 @@
 }
 
 static int mode_select_handle_sense(struct scsi_device *sdev,
-				    unsigned char *sensebuf)
+					unsigned char *sensebuf)
 {
 	struct scsi_sense_hdr sense_hdr;
 	int err = SCSI_DH_IO, ret;
@@ -533,11 +553,29 @@
 	return err;
 }
 
-static int send_mode_select(struct scsi_device *sdev, struct rdac_dh_data *h)
+static void send_mode_select(struct work_struct *work)
 {
+	struct rdac_controller *ctlr =
+		container_of(work, struct rdac_controller, ms_work);
 	struct request *rq;
+	struct scsi_device *sdev = ctlr->ms_sdev;
+	struct rdac_dh_data *h = get_rdac_data(sdev);
 	struct request_queue *q = sdev->request_queue;
 	int err, retry_cnt = RDAC_RETRY_COUNT;
+	struct rdac_queue_data *tmp, *qdata;
+	LIST_HEAD(list);
+	u8 *lun_table;
+
+	spin_lock(&ctlr->ms_lock);
+	list_splice_init(&ctlr->ms_head, &list);
+	ctlr->ms_queued = 0;
+	ctlr->ms_sdev = NULL;
+	spin_unlock(&ctlr->ms_lock);
+
+	if (ctlr->use_ms10)
+		lun_table = ctlr->mode_select.expanded.lun_table;
+	else
+		lun_table = ctlr->mode_select.legacy.lun_table;
 
 retry:
 	err = SCSI_DH_RES_TEMP_UNAVAIL;
@@ -545,6 +583,10 @@
 	if (!rq)
 		goto done;
 
+	list_for_each_entry(qdata, &list, entry) {
+		lun_table[qdata->h->lun] = 0x81;
+	}
+
 	RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, "
 		"%s MODE_SELECT command",
 		(char *) h->ctlr->array_name, h->ctlr->index,
@@ -565,10 +607,45 @@
 	}
 
 done:
-	return err;
+	list_for_each_entry_safe(qdata, tmp, &list, entry) {
+		list_del(&qdata->entry);
+		if (err == SCSI_DH_OK)
+			qdata->h->state = RDAC_STATE_ACTIVE;
+		if (qdata->callback_fn)
+			qdata->callback_fn(qdata->callback_data, err);
+		kfree(qdata);
+	}
+	return;
 }
 
-static int rdac_activate(struct scsi_device *sdev)
+static int queue_mode_select(struct scsi_device *sdev,
+				activate_complete fn, void *data)
+{
+	struct rdac_queue_data *qdata;
+	struct rdac_controller *ctlr;
+
+	qdata = kzalloc(sizeof(*qdata), GFP_KERNEL);
+	if (!qdata)
+		return SCSI_DH_RETRY;
+
+	qdata->h = get_rdac_data(sdev);
+	qdata->callback_fn = fn;
+	qdata->callback_data = data;
+
+	ctlr = qdata->h->ctlr;
+	spin_lock(&ctlr->ms_lock);
+	list_add_tail(&qdata->entry, &ctlr->ms_head);
+	if (!ctlr->ms_queued) {
+		ctlr->ms_queued = 1;
+		ctlr->ms_sdev = sdev;
+		queue_work(kmpath_rdacd, &ctlr->ms_work);
+	}
+	spin_unlock(&ctlr->ms_lock);
+	return SCSI_DH_OK;
+}
+
+static int rdac_activate(struct scsi_device *sdev,
+			activate_complete fn, void *data)
 {
 	struct rdac_dh_data *h = get_rdac_data(sdev);
 	int err = SCSI_DH_OK;
@@ -577,10 +654,15 @@
 	if (err != SCSI_DH_OK)
 		goto done;
 
-	if (h->lun_state == RDAC_LUN_UNOWNED)
-		err = send_mode_select(sdev, h);
+	if (h->lun_state == RDAC_LUN_UNOWNED) {
+		err = queue_mode_select(sdev, fn, data);
+		if (err == SCSI_DH_OK)
+			return 0;
+	}
 done:
-	return err;
+	if (fn)
+		fn(data, err);
+	return 0;
 }
 
 static int rdac_prep_fn(struct scsi_device *sdev, struct request *req)
@@ -790,13 +872,26 @@
 	int r;
 
 	r = scsi_register_device_handler(&rdac_dh);
-	if (r != 0)
+	if (r != 0) {
 		printk(KERN_ERR "Failed to register scsi device handler.");
+		goto done;
+	}
+
+	/*
+	 * Create workqueue to handle mode selects for rdac
+	 */
+	kmpath_rdacd = create_singlethread_workqueue("kmpath_rdacd");
+	if (!kmpath_rdacd) {
+		scsi_unregister_device_handler(&rdac_dh);
+		printk(KERN_ERR "kmpath_rdacd creation failed.\n");
+	}
+done:
 	return r;
 }
 
 static void __exit rdac_exit(void)
 {
+	destroy_workqueue(kmpath_rdacd);
 	scsi_unregister_device_handler(&rdac_dh);
 }
 
diff --git a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c
index fa738ec..207352c 100644
--- a/drivers/scsi/dmx3191d.c
+++ b/drivers/scsi/dmx3191d.c
@@ -31,7 +31,7 @@
 #include <scsi/scsi_host.h>
 
 /*
- * Defintions for the generic 5380 driver.
+ * Definitions for the generic 5380 driver.
  */
 #define AUTOSENSE
 
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 704b8e0..a30ffaa 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -66,14 +66,14 @@
 DEFINE_PER_CPU(struct fcoe_percpu_s, fcoe_percpu);
 
 /* Function Prototypes */
-static int fcoe_reset(struct Scsi_Host *shost);
+static int fcoe_reset(struct Scsi_Host *);
 static int fcoe_xmit(struct fc_lport *, struct fc_frame *);
 static int fcoe_rcv(struct sk_buff *, struct net_device *,
 		    struct packet_type *, struct net_device *);
-static int fcoe_percpu_receive_thread(void *arg);
-static void fcoe_clean_pending_queue(struct fc_lport *lp);
-static void fcoe_percpu_clean(struct fc_lport *lp);
-static int fcoe_link_ok(struct fc_lport *lp);
+static int fcoe_percpu_receive_thread(void *);
+static void fcoe_clean_pending_queue(struct fc_lport *);
+static void fcoe_percpu_clean(struct fc_lport *);
+static int fcoe_link_ok(struct fc_lport *);
 
 static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *);
 static int fcoe_hostlist_add(const struct fc_lport *);
@@ -82,15 +82,69 @@
 static int fcoe_device_notification(struct notifier_block *, ulong, void *);
 static void fcoe_dev_setup(void);
 static void fcoe_dev_cleanup(void);
-static struct fcoe_interface *
-	fcoe_hostlist_lookup_port(const struct net_device *dev);
+static struct fcoe_interface
+*fcoe_hostlist_lookup_port(const struct net_device *);
 
-/* notification function from net device */
+static int fcoe_fip_recv(struct sk_buff *, struct net_device *,
+			 struct packet_type *, struct net_device *);
+
+static void fcoe_fip_send(struct fcoe_ctlr *, struct sk_buff *);
+static void fcoe_update_src_mac(struct fc_lport *, u8 *);
+static u8 *fcoe_get_src_mac(struct fc_lport *);
+static void fcoe_destroy_work(struct work_struct *);
+
+static int fcoe_ddp_setup(struct fc_lport *, u16, struct scatterlist *,
+			  unsigned int);
+static int fcoe_ddp_done(struct fc_lport *, u16);
+
+static int fcoe_cpu_callback(struct notifier_block *, unsigned long, void *);
+
+static int fcoe_create(const char *, struct kernel_param *);
+static int fcoe_destroy(const char *, struct kernel_param *);
+
+static struct fc_seq *fcoe_elsct_send(struct fc_lport *,
+				      u32 did, struct fc_frame *,
+				      unsigned int op,
+				      void (*resp)(struct fc_seq *,
+						   struct fc_frame *,
+						   void *),
+				      void *, u32 timeout);
+static void fcoe_recv_frame(struct sk_buff *skb);
+
+static void fcoe_get_lesb(struct fc_lport *, struct fc_els_lesb *);
+
+module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR);
+__MODULE_PARM_TYPE(create, "string");
+MODULE_PARM_DESC(create, "Create fcoe fcoe using net device passed in.");
+module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR);
+__MODULE_PARM_TYPE(destroy, "string");
+MODULE_PARM_DESC(destroy, "Destroy fcoe fcoe");
+
+/* notification function for packets from net device */
 static struct notifier_block fcoe_notifier = {
 	.notifier_call = fcoe_device_notification,
 };
 
-static struct scsi_transport_template *scsi_transport_fcoe_sw;
+/* notification function for CPU hotplug events */
+static struct notifier_block fcoe_cpu_notifier = {
+	.notifier_call = fcoe_cpu_callback,
+};
+
+static struct scsi_transport_template *fcoe_transport_template;
+static struct scsi_transport_template *fcoe_vport_transport_template;
+
+static int fcoe_vport_destroy(struct fc_vport *);
+static int fcoe_vport_create(struct fc_vport *, bool disabled);
+static int fcoe_vport_disable(struct fc_vport *, bool disable);
+static void fcoe_set_vport_symbolic_name(struct fc_vport *);
+
+static struct libfc_function_template fcoe_libfc_fcn_templ = {
+	.frame_send = fcoe_xmit,
+	.ddp_setup = fcoe_ddp_setup,
+	.ddp_done = fcoe_ddp_done,
+	.elsct_send = fcoe_elsct_send,
+	.get_lesb = fcoe_get_lesb,
+};
 
 struct fc_function_template fcoe_transport_function = {
 	.show_host_node_name = 1,
@@ -123,6 +177,48 @@
 	.issue_fc_host_lip = fcoe_reset,
 
 	.terminate_rport_io = fc_rport_terminate_io,
+
+	.vport_create = fcoe_vport_create,
+	.vport_delete = fcoe_vport_destroy,
+	.vport_disable = fcoe_vport_disable,
+	.set_vport_symbolic_name = fcoe_set_vport_symbolic_name,
+
+	.bsg_request = fc_lport_bsg_request,
+};
+
+struct fc_function_template fcoe_vport_transport_function = {
+	.show_host_node_name = 1,
+	.show_host_port_name = 1,
+	.show_host_supported_classes = 1,
+	.show_host_supported_fc4s = 1,
+	.show_host_active_fc4s = 1,
+	.show_host_maxframe_size = 1,
+
+	.show_host_port_id = 1,
+	.show_host_supported_speeds = 1,
+	.get_host_speed = fc_get_host_speed,
+	.show_host_speed = 1,
+	.show_host_port_type = 1,
+	.get_host_port_state = fc_get_host_port_state,
+	.show_host_port_state = 1,
+	.show_host_symbolic_name = 1,
+
+	.dd_fcrport_size = sizeof(struct fc_rport_libfc_priv),
+	.show_rport_maxframe_size = 1,
+	.show_rport_supported_classes = 1,
+
+	.show_host_fabric_name = 1,
+	.show_starget_node_name = 1,
+	.show_starget_port_name = 1,
+	.show_starget_port_id = 1,
+	.set_rport_dev_loss_tmo = fc_set_rport_loss_tmo,
+	.show_rport_dev_loss_tmo = 1,
+	.get_fc_host_stats = fc_get_host_stats,
+	.issue_fc_host_lip = fcoe_reset,
+
+	.terminate_rport_io = fc_rport_terminate_io,
+
+	.bsg_request = fc_lport_bsg_request,
 };
 
 static struct scsi_host_template fcoe_shost_template = {
@@ -137,20 +233,17 @@
 	.change_queue_depth = fc_change_queue_depth,
 	.change_queue_type = fc_change_queue_type,
 	.this_id = -1,
-	.cmd_per_lun = 32,
+	.cmd_per_lun = 3,
 	.can_queue = FCOE_MAX_OUTSTANDING_COMMANDS,
 	.use_clustering = ENABLE_CLUSTERING,
 	.sg_tablesize = SG_ALL,
 	.max_sectors = 0xffff,
 };
 
-static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *dev,
-			 struct packet_type *ptype,
-			 struct net_device *orig_dev);
 /**
- * fcoe_interface_setup()
- * @fcoe: new fcoe_interface
- * @netdev : ptr to the associated netdevice struct
+ * fcoe_interface_setup() - Setup a FCoE interface
+ * @fcoe:   The new FCoE interface
+ * @netdev: The net device that the fcoe interface is on
  *
  * Returns : 0 for success
  * Locking: must be called with the RTNL mutex held
@@ -160,23 +253,36 @@
 {
 	struct fcoe_ctlr *fip = &fcoe->ctlr;
 	struct netdev_hw_addr *ha;
+	struct net_device *real_dev;
 	u8 flogi_maddr[ETH_ALEN];
+	const struct net_device_ops *ops;
 
 	fcoe->netdev = netdev;
 
+	/* Let LLD initialize for FCoE */
+	ops = netdev->netdev_ops;
+	if (ops->ndo_fcoe_enable) {
+		if (ops->ndo_fcoe_enable(netdev))
+			FCOE_NETDEV_DBG(netdev, "Failed to enable FCoE"
+					" specific feature for LLD.\n");
+	}
+
 	/* Do not support for bonding device */
 	if ((netdev->priv_flags & IFF_MASTER_ALB) ||
 	    (netdev->priv_flags & IFF_SLAVE_INACTIVE) ||
 	    (netdev->priv_flags & IFF_MASTER_8023AD)) {
+		FCOE_NETDEV_DBG(netdev, "Bonded interfaces not supported\n");
 		return -EOPNOTSUPP;
 	}
 
 	/* look for SAN MAC address, if multiple SAN MACs exist, only
 	 * use the first one for SPMA */
+	real_dev = (netdev->priv_flags & IFF_802_1Q_VLAN) ?
+		vlan_dev_real_dev(netdev) : netdev;
 	rcu_read_lock();
-	for_each_dev_addr(netdev, ha) {
+	for_each_dev_addr(real_dev, ha) {
 		if ((ha->type == NETDEV_HW_ADDR_T_SAN) &&
-		    (is_valid_ether_addr(fip->ctl_src_addr))) {
+		    (is_valid_ether_addr(ha->addr))) {
 			memcpy(fip->ctl_src_addr, ha->addr, ETH_ALEN);
 			fip->spma = 1;
 			break;
@@ -216,19 +322,16 @@
 	return 0;
 }
 
-static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb);
-static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new);
-static void fcoe_destroy_work(struct work_struct *work);
-
 /**
- * fcoe_interface_create()
- * @netdev: network interface
+ * fcoe_interface_create() - Create a FCoE interface on a net device
+ * @netdev: The net device to create the FCoE interface on
  *
  * Returns: pointer to a struct fcoe_interface or NULL on error
  */
 static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev)
 {
 	struct fcoe_interface *fcoe;
+	int err;
 
 	fcoe = kzalloc(sizeof(*fcoe), GFP_KERNEL);
 	if (!fcoe) {
@@ -245,15 +348,22 @@
 	fcoe_ctlr_init(&fcoe->ctlr);
 	fcoe->ctlr.send = fcoe_fip_send;
 	fcoe->ctlr.update_mac = fcoe_update_src_mac;
+	fcoe->ctlr.get_src_addr = fcoe_get_src_mac;
 
-	fcoe_interface_setup(fcoe, netdev);
+	err = fcoe_interface_setup(fcoe, netdev);
+	if (err) {
+		fcoe_ctlr_destroy(&fcoe->ctlr);
+		kfree(fcoe);
+		dev_put(netdev);
+		return NULL;
+	}
 
 	return fcoe;
 }
 
 /**
- * fcoe_interface_cleanup() - clean up netdev configurations
- * @fcoe:
+ * fcoe_interface_cleanup() - Clean up a FCoE interface
+ * @fcoe: The FCoE interface to be cleaned up
  *
  * Caller must be holding the RTNL mutex
  */
@@ -262,6 +372,7 @@
 	struct net_device *netdev = fcoe->netdev;
 	struct fcoe_ctlr *fip = &fcoe->ctlr;
 	u8 flogi_maddr[ETH_ALEN];
+	const struct net_device_ops *ops;
 
 	/*
 	 * Don't listen for Ethernet packets anymore.
@@ -276,16 +387,22 @@
 	/* Delete secondary MAC addresses */
 	memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
 	dev_unicast_delete(netdev, flogi_maddr);
-	if (!is_zero_ether_addr(fip->data_src_addr))
-		dev_unicast_delete(netdev, fip->data_src_addr);
 	if (fip->spma)
 		dev_unicast_delete(netdev, fip->ctl_src_addr);
 	dev_mc_delete(netdev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0);
+
+	/* Tell the LLD we are done w/ FCoE */
+	ops = netdev->netdev_ops;
+	if (ops->ndo_fcoe_disable) {
+		if (ops->ndo_fcoe_disable(netdev))
+			FCOE_NETDEV_DBG(netdev, "Failed to disable FCoE"
+					" specific feature for LLD.\n");
+	}
 }
 
 /**
  * fcoe_interface_release() - fcoe_port kref release function
- * @kref: embedded reference count in an fcoe_interface struct
+ * @kref: Embedded reference count in an fcoe_interface struct
  */
 static void fcoe_interface_release(struct kref *kref)
 {
@@ -301,8 +418,8 @@
 }
 
 /**
- * fcoe_interface_get()
- * @fcoe:
+ * fcoe_interface_get() - Get a reference to a FCoE interface
+ * @fcoe: The FCoE interface to be held
  */
 static inline void fcoe_interface_get(struct fcoe_interface *fcoe)
 {
@@ -310,8 +427,8 @@
 }
 
 /**
- * fcoe_interface_put()
- * @fcoe:
+ * fcoe_interface_put() - Put a reference to a FCoE interface
+ * @fcoe: The FCoE interface to be released
  */
 static inline void fcoe_interface_put(struct fcoe_interface *fcoe)
 {
@@ -319,15 +436,16 @@
 }
 
 /**
- * fcoe_fip_recv - handle a received FIP frame.
- * @skb: the receive skb
- * @dev: associated &net_device
- * @ptype: the &packet_type structure which was used to register this handler.
- * @orig_dev: original receive &net_device, in case @dev is a bond.
+ * fcoe_fip_recv() - Handler for received FIP frames
+ * @skb:      The receive skb
+ * @netdev:   The associated net device
+ * @ptype:    The packet_type structure which was used to register this handler
+ * @orig_dev: The original net_device the the skb was received on.
+ *	      (in case dev is a bond)
  *
  * Returns: 0 for success
  */
-static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *dev,
+static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *netdev,
 			 struct packet_type *ptype,
 			 struct net_device *orig_dev)
 {
@@ -339,9 +457,9 @@
 }
 
 /**
- * fcoe_fip_send() - send an Ethernet-encapsulated FIP frame.
- * @fip: FCoE controller.
- * @skb: FIP Packet.
+ * fcoe_fip_send() - Send an Ethernet-encapsulated FIP frame
+ * @fip: The FCoE controller
+ * @skb: The FIP packet to be sent
  */
 static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
 {
@@ -350,88 +468,101 @@
 }
 
 /**
- * fcoe_update_src_mac() - Update Ethernet MAC filters.
- * @fip: FCoE controller.
- * @old: Unicast MAC address to delete if the MAC is non-zero.
- * @new: Unicast MAC address to add.
+ * fcoe_update_src_mac() - Update the Ethernet MAC filters
+ * @lport: The local port to update the source MAC on
+ * @addr:  Unicast MAC address to add
  *
  * Remove any previously-set unicast MAC filter.
  * Add secondary FCoE MAC address filter for our OUI.
  */
-static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new)
+static void fcoe_update_src_mac(struct fc_lport *lport, u8 *addr)
 {
-	struct fcoe_interface *fcoe;
+	struct fcoe_port *port = lport_priv(lport);
+	struct fcoe_interface *fcoe = port->fcoe;
 
-	fcoe = fcoe_from_ctlr(fip);
 	rtnl_lock();
-	if (!is_zero_ether_addr(old))
-		dev_unicast_delete(fcoe->netdev, old);
-	dev_unicast_add(fcoe->netdev, new);
+	if (!is_zero_ether_addr(port->data_src_addr))
+		dev_unicast_delete(fcoe->netdev, port->data_src_addr);
+	if (!is_zero_ether_addr(addr))
+		dev_unicast_add(fcoe->netdev, addr);
+	memcpy(port->data_src_addr, addr, ETH_ALEN);
 	rtnl_unlock();
 }
 
 /**
- * fcoe_lport_config() - sets up the fc_lport
- * @lp: ptr to the fc_lport
+ * fcoe_get_src_mac() - return the Ethernet source address for an lport
+ * @lport: libfc lport
+ */
+static u8 *fcoe_get_src_mac(struct fc_lport *lport)
+{
+	struct fcoe_port *port = lport_priv(lport);
+
+	return port->data_src_addr;
+}
+
+/**
+ * fcoe_lport_config() - Set up a local port
+ * @lport: The local port to be setup
  *
  * Returns: 0 for success
  */
-static int fcoe_lport_config(struct fc_lport *lp)
+static int fcoe_lport_config(struct fc_lport *lport)
 {
-	lp->link_up = 0;
-	lp->qfull = 0;
-	lp->max_retry_count = 3;
-	lp->max_rport_retry_count = 3;
-	lp->e_d_tov = 2 * 1000;	/* FC-FS default */
-	lp->r_a_tov = 2 * 2 * 1000;
-	lp->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS |
-			      FCP_SPPF_RETRY | FCP_SPPF_CONF_COMPL);
+	lport->link_up = 0;
+	lport->qfull = 0;
+	lport->max_retry_count = 3;
+	lport->max_rport_retry_count = 3;
+	lport->e_d_tov = 2 * 1000;	/* FC-FS default */
+	lport->r_a_tov = 2 * 2 * 1000;
+	lport->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS |
+				 FCP_SPPF_RETRY | FCP_SPPF_CONF_COMPL);
+	lport->does_npiv = 1;
 
-	fc_lport_init_stats(lp);
+	fc_lport_init_stats(lport);
 
 	/* lport fc_lport related configuration */
-	fc_lport_config(lp);
+	fc_lport_config(lport);
 
 	/* offload related configuration */
-	lp->crc_offload = 0;
-	lp->seq_offload = 0;
-	lp->lro_enabled = 0;
-	lp->lro_xid = 0;
-	lp->lso_max = 0;
+	lport->crc_offload = 0;
+	lport->seq_offload = 0;
+	lport->lro_enabled = 0;
+	lport->lro_xid = 0;
+	lport->lso_max = 0;
 
 	return 0;
 }
 
 /**
- * fcoe_queue_timer() - fcoe queue timer
- * @lp: the fc_lport pointer
+ * fcoe_queue_timer() - The fcoe queue timer
+ * @lport: The local port
  *
  * Calls fcoe_check_wait_queue on timeout
- *
  */
-static void fcoe_queue_timer(ulong lp)
+static void fcoe_queue_timer(ulong lport)
 {
-	fcoe_check_wait_queue((struct fc_lport *)lp, NULL);
+	fcoe_check_wait_queue((struct fc_lport *)lport, NULL);
 }
 
 /**
- * fcoe_netdev_config() - Set up netdev for SW FCoE
- * @lp : ptr to the fc_lport
- * @netdev : ptr to the associated netdevice struct
+ * fcoe_netdev_config() - Set up net devive for SW FCoE
+ * @lport:  The local port that is associated with the net device
+ * @netdev: The associated net device
  *
- * Must be called after fcoe_lport_config() as it will use lport mutex
+ * Must be called after fcoe_lport_config() as it will use local port mutex
  *
- * Returns : 0 for success
+ * Returns: 0 for success
  */
-static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev)
+static int fcoe_netdev_config(struct fc_lport *lport, struct net_device *netdev)
 {
 	u32 mfs;
 	u64 wwnn, wwpn;
 	struct fcoe_interface *fcoe;
 	struct fcoe_port *port;
+	int vid = 0;
 
 	/* Setup lport private data to point to fcoe softc */
-	port = lport_priv(lp);
+	port = lport_priv(lport);
 	fcoe = port->fcoe;
 
 	/*
@@ -439,86 +570,112 @@
 	 * user-configured limit.  If the MFS is too low, fcoe_link_ok()
 	 * will return 0, so do this first.
 	 */
-	mfs = netdev->mtu - (sizeof(struct fcoe_hdr) +
-			     sizeof(struct fcoe_crc_eof));
-	if (fc_set_mfs(lp, mfs))
+	mfs = netdev->mtu;
+	if (netdev->features & NETIF_F_FCOE_MTU) {
+		mfs = FCOE_MTU;
+		FCOE_NETDEV_DBG(netdev, "Supports FCOE_MTU of %d bytes\n", mfs);
+	}
+	mfs -= (sizeof(struct fcoe_hdr) + sizeof(struct fcoe_crc_eof));
+	if (fc_set_mfs(lport, mfs))
 		return -EINVAL;
 
 	/* offload features support */
 	if (netdev->features & NETIF_F_SG)
-		lp->sg_supp = 1;
+		lport->sg_supp = 1;
 
 	if (netdev->features & NETIF_F_FCOE_CRC) {
-		lp->crc_offload = 1;
+		lport->crc_offload = 1;
 		FCOE_NETDEV_DBG(netdev, "Supports FCCRC offload\n");
 	}
 	if (netdev->features & NETIF_F_FSO) {
-		lp->seq_offload = 1;
-		lp->lso_max = netdev->gso_max_size;
+		lport->seq_offload = 1;
+		lport->lso_max = netdev->gso_max_size;
 		FCOE_NETDEV_DBG(netdev, "Supports LSO for max len 0x%x\n",
-				lp->lso_max);
+				lport->lso_max);
 	}
 	if (netdev->fcoe_ddp_xid) {
-		lp->lro_enabled = 1;
-		lp->lro_xid = netdev->fcoe_ddp_xid;
+		lport->lro_enabled = 1;
+		lport->lro_xid = netdev->fcoe_ddp_xid;
 		FCOE_NETDEV_DBG(netdev, "Supports LRO for max xid 0x%x\n",
-				lp->lro_xid);
+				lport->lro_xid);
 	}
 	skb_queue_head_init(&port->fcoe_pending_queue);
 	port->fcoe_pending_queue_active = 0;
-	setup_timer(&port->timer, fcoe_queue_timer, (unsigned long)lp);
+	setup_timer(&port->timer, fcoe_queue_timer, (unsigned long)lport);
 
-	wwnn = fcoe_wwn_from_mac(netdev->dev_addr, 1, 0);
-	fc_set_wwnn(lp, wwnn);
-	/* XXX - 3rd arg needs to be vlan id */
-	wwpn = fcoe_wwn_from_mac(netdev->dev_addr, 2, 0);
-	fc_set_wwpn(lp, wwpn);
+	if (!lport->vport) {
+		/*
+		 * Use NAA 1&2 (FC-FS Rev. 2.0, Sec. 15) to generate WWNN/WWPN:
+		 * For WWNN, we use NAA 1 w/ bit 27-16 of word 0 as 0.
+		 * For WWPN, we use NAA 2 w/ bit 27-16 of word 0 from VLAN ID
+		 */
+		if (netdev->priv_flags & IFF_802_1Q_VLAN)
+			vid = vlan_dev_vlan_id(netdev);
+		wwnn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr, 1, 0);
+		fc_set_wwnn(lport, wwnn);
+		wwpn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr, 2, vid);
+		fc_set_wwpn(lport, wwpn);
+	}
 
 	return 0;
 }
 
 /**
- * fcoe_shost_config() - Sets up fc_lport->host
- * @lp : ptr to the fc_lport
- * @shost : ptr to the associated scsi host
- * @dev : device associated to scsi host
+ * fcoe_shost_config() - Set up the SCSI host associated with a local port
+ * @lport: The local port
+ * @shost: The SCSI host to associate with the local port
+ * @dev:   The device associated with the SCSI host
  *
  * Must be called after fcoe_lport_config() and fcoe_netdev_config()
  *
- * Returns : 0 for success
+ * Returns: 0 for success
  */
-static int fcoe_shost_config(struct fc_lport *lp, struct Scsi_Host *shost,
-				struct device *dev)
+static int fcoe_shost_config(struct fc_lport *lport, struct Scsi_Host *shost,
+			     struct device *dev)
 {
 	int rc = 0;
 
 	/* lport scsi host config */
-	lp->host = shost;
-
-	lp->host->max_lun = FCOE_MAX_LUN;
-	lp->host->max_id = FCOE_MAX_FCP_TARGET;
-	lp->host->max_channel = 0;
-	lp->host->transportt = scsi_transport_fcoe_sw;
+	lport->host->max_lun = FCOE_MAX_LUN;
+	lport->host->max_id = FCOE_MAX_FCP_TARGET;
+	lport->host->max_channel = 0;
+	if (lport->vport)
+		lport->host->transportt = fcoe_vport_transport_template;
+	else
+		lport->host->transportt = fcoe_transport_template;
 
 	/* add the new host to the SCSI-ml */
-	rc = scsi_add_host(lp->host, dev);
+	rc = scsi_add_host(lport->host, dev);
 	if (rc) {
-		FCOE_NETDEV_DBG(fcoe_netdev(lp), "fcoe_shost_config: "
+		FCOE_NETDEV_DBG(fcoe_netdev(lport), "fcoe_shost_config: "
 				"error on scsi_add_host\n");
 		return rc;
 	}
-	sprintf(fc_host_symbolic_name(lp->host), "%s v%s over %s",
-		FCOE_NAME, FCOE_VERSION,
-		fcoe_netdev(lp)->name);
+
+	if (!lport->vport)
+		fc_host_max_npiv_vports(lport->host) = USHORT_MAX;
+
+	snprintf(fc_host_symbolic_name(lport->host), FC_SYMBOLIC_NAME_SIZE,
+		 "%s v%s over %s", FCOE_NAME, FCOE_VERSION,
+		 fcoe_netdev(lport)->name);
 
 	return 0;
 }
 
-/*
- * fcoe_oem_match() - match for read types IO
- * @fp: the fc_frame for new IO.
+/**
+ * fcoe_oem_match() - The match routine for the offloaded exchange manager
+ * @fp: The I/O frame
  *
- * Returns : true for read types IO, otherwise returns false.
+ * This routine will be associated with an exchange manager (EM). When
+ * the libfc exchange handling code is looking for an EM to use it will
+ * call this routine and pass it the frame that it wishes to send. This
+ * routine will return True if the associated EM is to be used and False
+ * if the echange code should continue looking for an EM.
+ *
+ * The offload EM that this routine is associated with will handle any
+ * packets that are for SCSI read requests.
+ *
+ * Returns: True for read types I/O, otherwise returns false.
  */
 bool fcoe_oem_match(struct fc_frame *fp)
 {
@@ -527,14 +684,14 @@
 }
 
 /**
- * fcoe_em_config() - allocates em for this lport
- * @lp: the fcoe that em is to allocated for
+ * fcoe_em_config() - Allocate and configure an exchange manager
+ * @lport: The local port that the new EM will be associated with
  *
- * Returns : 0 on success
+ * Returns: 0 on success
  */
-static inline int fcoe_em_config(struct fc_lport *lp)
+static inline int fcoe_em_config(struct fc_lport *lport)
 {
-	struct fcoe_port *port = lport_priv(lp);
+	struct fcoe_port *port = lport_priv(lport);
 	struct fcoe_interface *fcoe = port->fcoe;
 	struct fcoe_interface *oldfcoe = NULL;
 	struct net_device *old_real_dev, *cur_real_dev;
@@ -545,8 +702,9 @@
 	 * Check if need to allocate an em instance for
 	 * offload exchange ids to be shared across all VN_PORTs/lport.
 	 */
-	if (!lp->lro_enabled || !lp->lro_xid || (lp->lro_xid >= max_xid)) {
-		lp->lro_xid = 0;
+	if (!lport->lro_enabled || !lport->lro_xid ||
+	    (lport->lro_xid >= max_xid)) {
+		lport->lro_xid = 0;
 		goto skip_oem;
 	}
 
@@ -572,16 +730,16 @@
 	}
 
 	if (fcoe->oem) {
-		if (!fc_exch_mgr_add(lp, fcoe->oem, fcoe_oem_match)) {
+		if (!fc_exch_mgr_add(lport, fcoe->oem, fcoe_oem_match)) {
 			printk(KERN_ERR "fcoe_em_config: failed to add "
 			       "offload em:%p on interface:%s\n",
 			       fcoe->oem, fcoe->netdev->name);
 			return -ENOMEM;
 		}
 	} else {
-		fcoe->oem = fc_exch_mgr_alloc(lp, FC_CLASS_3,
-					    FCOE_MIN_XID, lp->lro_xid,
-					    fcoe_oem_match);
+		fcoe->oem = fc_exch_mgr_alloc(lport, FC_CLASS_3,
+					      FCOE_MIN_XID, lport->lro_xid,
+					      fcoe_oem_match);
 		if (!fcoe->oem) {
 			printk(KERN_ERR "fcoe_em_config: failed to allocate "
 			       "em for offload exches on interface:%s\n",
@@ -593,10 +751,10 @@
 	/*
 	 * Exclude offload EM xid range from next EM xid range.
 	 */
-	min_xid += lp->lro_xid + 1;
+	min_xid += lport->lro_xid + 1;
 
 skip_oem:
-	if (!fc_exch_mgr_alloc(lp, FC_CLASS_3, min_xid, max_xid, NULL)) {
+	if (!fc_exch_mgr_alloc(lport, FC_CLASS_3, min_xid, max_xid, NULL)) {
 		printk(KERN_ERR "fcoe_em_config: failed to "
 		       "allocate em on interface %s\n", fcoe->netdev->name);
 		return -ENOMEM;
@@ -606,8 +764,8 @@
 }
 
 /**
- * fcoe_if_destroy() - FCoE software HBA tear-down function
- * @lport: fc_lport to destroy
+ * fcoe_if_destroy() - Tear down a SW FCoE instance
+ * @lport: The local port to be destroyed
  */
 static void fcoe_if_destroy(struct fc_lport *lport)
 {
@@ -630,6 +788,11 @@
 	/* Free existing transmit skbs */
 	fcoe_clean_pending_queue(lport);
 
+	rtnl_lock();
+	if (!is_zero_ether_addr(port->data_src_addr))
+		dev_unicast_delete(netdev, port->data_src_addr);
+	rtnl_unlock();
+
 	/* receives may not be stopped until after this */
 	fcoe_interface_put(fcoe);
 
@@ -650,82 +813,89 @@
 	scsi_host_put(lport->host);
 }
 
-/*
- * fcoe_ddp_setup - calls LLD's ddp_setup through net_device
- * @lp:	the corresponding fc_lport
- * @xid: the exchange id for this ddp transfer
- * @sgl: the scatterlist describing this transfer
- * @sgc: number of sg items
+/**
+ * fcoe_ddp_setup() - Call a LLD's ddp_setup through the net device
+ * @lport: The local port to setup DDP for
+ * @xid:   The exchange ID for this DDP transfer
+ * @sgl:   The scatterlist describing this transfer
+ * @sgc:   The number of sg items
  *
- * Returns : 0 no ddp
+ * Returns: 0 if the DDP context was not configured
  */
-static int fcoe_ddp_setup(struct fc_lport *lp, u16 xid,
-			     struct scatterlist *sgl, unsigned int sgc)
+static int fcoe_ddp_setup(struct fc_lport *lport, u16 xid,
+			  struct scatterlist *sgl, unsigned int sgc)
 {
-	struct net_device *n = fcoe_netdev(lp);
+	struct net_device *netdev = fcoe_netdev(lport);
 
-	if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_setup)
-		return n->netdev_ops->ndo_fcoe_ddp_setup(n, xid, sgl, sgc);
+	if (netdev->netdev_ops->ndo_fcoe_ddp_setup)
+		return netdev->netdev_ops->ndo_fcoe_ddp_setup(netdev,
+							      xid, sgl,
+							      sgc);
 
 	return 0;
 }
 
-/*
- * fcoe_ddp_done - calls LLD's ddp_done through net_device
- * @lp:	the corresponding fc_lport
- * @xid: the exchange id for this ddp transfer
- *
- * Returns : the length of data that have been completed by ddp
- */
-static int fcoe_ddp_done(struct fc_lport *lp, u16 xid)
-{
-	struct net_device *n = fcoe_netdev(lp);
-
-	if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_done)
-		return n->netdev_ops->ndo_fcoe_ddp_done(n, xid);
-	return 0;
-}
-
-static struct libfc_function_template fcoe_libfc_fcn_templ = {
-	.frame_send = fcoe_xmit,
-	.ddp_setup = fcoe_ddp_setup,
-	.ddp_done = fcoe_ddp_done,
-};
-
 /**
- * fcoe_if_create() - this function creates the fcoe port
- * @fcoe: fcoe_interface structure to create an fc_lport instance on
- * @parent: device pointer to be the parent in sysfs for the SCSI host
+ * fcoe_ddp_done() - Call a LLD's ddp_done through the net device
+ * @lport: The local port to complete DDP on
+ * @xid:   The exchange ID for this DDP transfer
  *
- * Creates fc_lport struct and scsi_host for lport, configures lport.
+ * Returns: the length of data that have been completed by DDP
+ */
+static int fcoe_ddp_done(struct fc_lport *lport, u16 xid)
+{
+	struct net_device *netdev = fcoe_netdev(lport);
+
+	if (netdev->netdev_ops->ndo_fcoe_ddp_done)
+		return netdev->netdev_ops->ndo_fcoe_ddp_done(netdev, xid);
+	return 0;
+}
+
+/**
+ * fcoe_if_create() - Create a FCoE instance on an interface
+ * @fcoe:   The FCoE interface to create a local port on
+ * @parent: The device pointer to be the parent in sysfs for the SCSI host
+ * @npiv:   Indicates if the port is a vport or not
  *
- * Returns : The allocated fc_lport or an error pointer
+ * Creates a fc_lport instance and a Scsi_Host instance and configure them.
+ *
+ * Returns: The allocated fc_lport or an error pointer
  */
 static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe,
-				       struct device *parent)
+				       struct device *parent, int npiv)
 {
-	int rc;
+	struct net_device *netdev = fcoe->netdev;
 	struct fc_lport *lport = NULL;
 	struct fcoe_port *port;
 	struct Scsi_Host *shost;
-	struct net_device *netdev = fcoe->netdev;
+	int rc;
+	/*
+	 * parent is only a vport if npiv is 1,
+	 * but we'll only use vport in that case so go ahead and set it
+	 */
+	struct fc_vport *vport = dev_to_vport(parent);
 
 	FCOE_NETDEV_DBG(netdev, "Create Interface\n");
 
-	shost = libfc_host_alloc(&fcoe_shost_template,
-				 sizeof(struct fcoe_port));
-	if (!shost) {
+	if (!npiv) {
+		lport = libfc_host_alloc(&fcoe_shost_template,
+					 sizeof(struct fcoe_port));
+	} else	{
+		lport = libfc_vport_create(vport,
+					   sizeof(struct fcoe_port));
+	}
+	if (!lport) {
 		FCOE_NETDEV_DBG(netdev, "Could not allocate host structure\n");
 		rc = -ENOMEM;
 		goto out;
 	}
-	lport = shost_priv(shost);
+	shost = lport->host;
 	port = lport_priv(lport);
 	port->lport = lport;
 	port->fcoe = fcoe;
 	INIT_WORK(&port->destroy_work, fcoe_destroy_work);
 
-	/* configure fc_lport, e.g., em */
+	/* configure a fc_lport including the exchange manager */
 	rc = fcoe_lport_config(lport);
 	if (rc) {
 		FCOE_NETDEV_DBG(netdev, "Could not configure lport for the "
@@ -733,6 +903,13 @@
 		goto out_host_put;
 	}
 
+	if (npiv) {
+		FCOE_NETDEV_DBG(netdev, "Setting vport names, 0x%llX 0x%llX\n",
+				vport->node_name, vport->port_name);
+		fc_set_wwnn(lport, vport->node_name);
+		fc_set_wwpn(lport, vport->port_name);
+	}
+
 	/* configure lport network properties */
 	rc = fcoe_netdev_config(lport, netdev);
 	if (rc) {
@@ -757,21 +934,24 @@
 		goto out_lp_destroy;
 	}
 
-	/*
-	 * fcoe_em_alloc() and fcoe_hostlist_add() both
-	 * need to be atomic with respect to other changes to the hostlist
-	 * since fcoe_em_alloc() looks for an existing EM
-	 * instance on host list updated by fcoe_hostlist_add().
-	 *
-	 * This is currently handled through the fcoe_config_mutex begin held.
-	 */
+	if (!npiv) {
+		/*
+		 * fcoe_em_alloc() and fcoe_hostlist_add() both
+		 * need to be atomic with respect to other changes to the
+		 * hostlist since fcoe_em_alloc() looks for an existing EM
+		 * instance on host list updated by fcoe_hostlist_add().
+		 *
+		 * This is currently handled through the fcoe_config_mutex
+		 * begin held.
+		 */
 
-	/* lport exch manager allocation */
-	rc = fcoe_em_config(lport);
-	if (rc) {
-		FCOE_NETDEV_DBG(netdev, "Could not configure the EM for the "
-				"interface\n");
-		goto out_lp_destroy;
+		/* lport exch manager allocation */
+		rc = fcoe_em_config(lport);
+		if (rc) {
+			FCOE_NETDEV_DBG(netdev, "Could not configure the EM "
+					"for the interface\n");
+			goto out_lp_destroy;
+		}
 	}
 
 	fcoe_interface_get(fcoe);
@@ -786,17 +966,20 @@
 }
 
 /**
- * fcoe_if_init() - attach to scsi transport
+ * fcoe_if_init() - Initialization routine for fcoe.ko
  *
- * Returns : 0 on success
+ * Attaches the SW FCoE transport to the FC transport
+ *
+ * Returns: 0 on success
  */
 static int __init fcoe_if_init(void)
 {
 	/* attach to scsi transport */
-	scsi_transport_fcoe_sw =
-		fc_attach_transport(&fcoe_transport_function);
+	fcoe_transport_template = fc_attach_transport(&fcoe_transport_function);
+	fcoe_vport_transport_template =
+		fc_attach_transport(&fcoe_vport_transport_function);
 
-	if (!scsi_transport_fcoe_sw) {
+	if (!fcoe_transport_template) {
 		printk(KERN_ERR "fcoe: Failed to attach to the FC transport\n");
 		return -ENODEV;
 	}
@@ -805,20 +988,24 @@
 }
 
 /**
- * fcoe_if_exit() - detach from scsi transport
+ * fcoe_if_exit() - Tear down fcoe.ko
  *
- * Returns : 0 on success
+ * Detaches the SW FCoE transport from the FC transport
+ *
+ * Returns: 0 on success
  */
 int __exit fcoe_if_exit(void)
 {
-	fc_release_transport(scsi_transport_fcoe_sw);
-	scsi_transport_fcoe_sw = NULL;
+	fc_release_transport(fcoe_transport_template);
+	fc_release_transport(fcoe_vport_transport_template);
+	fcoe_transport_template = NULL;
+	fcoe_vport_transport_template = NULL;
 	return 0;
 }
 
 /**
- * fcoe_percpu_thread_create() - Create a receive thread for an online cpu
- * @cpu: cpu index for the online cpu
+ * fcoe_percpu_thread_create() - Create a receive thread for an online CPU
+ * @cpu: The CPU index of the CPU to create a receive thread for
  */
 static void fcoe_percpu_thread_create(unsigned int cpu)
 {
@@ -841,8 +1028,8 @@
 }
 
 /**
- * fcoe_percpu_thread_destroy() - removes the rx thread for the given cpu
- * @cpu: cpu index the rx thread is to be removed
+ * fcoe_percpu_thread_destroy() - Remove the receive thread of a CPU
+ * @cpu: The CPU index of the CPU whose receive thread is to be destroyed
  *
  * Destroys a per-CPU Rx thread. Any pending skbs are moved to the
  * current CPU's Rx thread. If the thread being destroyed is bound to
@@ -890,7 +1077,7 @@
 		} else {
 			/*
 			 * The targeted CPU is not initialized and cannot accept
-			 * new  skbs. Unlock the targeted CPU and drop the skbs
+			 * new	skbs. Unlock the targeted CPU and drop the skbs
 			 * on the CPU that is going offline.
 			 */
 			while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL)
@@ -931,12 +1118,12 @@
 }
 
 /**
- * fcoe_cpu_callback() - fcoe cpu hotplug event callback
- * @nfb: callback data block
- * @action: event triggering the callback
- * @hcpu: index for the cpu of this event
+ * fcoe_cpu_callback() - Handler for CPU hotplug events
+ * @nfb:    The callback data block
+ * @action: The event triggering the callback
+ * @hcpu:   The index of the CPU that the event is for
  *
- * This creates or destroys per cpu data for fcoe
+ * This creates or destroys per-CPU data for fcoe
  *
  * Returns NOTIFY_OK always.
  */
@@ -962,25 +1149,22 @@
 	return NOTIFY_OK;
 }
 
-static struct notifier_block fcoe_cpu_notifier = {
-	.notifier_call = fcoe_cpu_callback,
-};
-
 /**
- * fcoe_rcv() - this is the fcoe receive function called by NET_RX_SOFTIRQ
- * @skb: the receive skb
- * @dev: associated net device
- * @ptype: context
- * @olddev: last device
+ * fcoe_rcv() - Receive packets from a net device
+ * @skb:    The received packet
+ * @netdev: The net device that the packet was received on
+ * @ptype:  The packet type context
+ * @olddev: The last device net device
  *
- * this function will receive the packet and build fc frame and pass it up
+ * This routine is called by NET_RX_SOFTIRQ. It receives a packet, builds a
+ * FC frame and passes the frame to libfc.
  *
  * Returns: 0 for success
  */
-int fcoe_rcv(struct sk_buff *skb, struct net_device *dev,
+int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev,
 	     struct packet_type *ptype, struct net_device *olddev)
 {
-	struct fc_lport *lp;
+	struct fc_lport *lport;
 	struct fcoe_rcv_info *fr;
 	struct fcoe_interface *fcoe;
 	struct fc_frame_header *fh;
@@ -988,15 +1172,15 @@
 	unsigned int cpu;
 
 	fcoe = container_of(ptype, struct fcoe_interface, fcoe_packet_type);
-	lp = fcoe->ctlr.lp;
-	if (unlikely(lp == NULL)) {
-		FCOE_NETDEV_DBG(dev, "Cannot find hba structure");
+	lport = fcoe->ctlr.lp;
+	if (unlikely(!lport)) {
+		FCOE_NETDEV_DBG(netdev, "Cannot find hba structure");
 		goto err2;
 	}
-	if (!lp->link_up)
+	if (!lport->link_up)
 		goto err2;
 
-	FCOE_NETDEV_DBG(dev, "skb_info: len:%d data_len:%d head:%p "
+	FCOE_NETDEV_DBG(netdev, "skb_info: len:%d data_len:%d head:%p "
 			"data:%p tail:%p end:%p sum:%d dev:%s",
 			skb->len, skb->data_len, skb->head, skb->data,
 			skb_tail_pointer(skb), skb_end_pointer(skb),
@@ -1004,7 +1188,7 @@
 
 	/* check for FCOE packet type */
 	if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) {
-		FCOE_NETDEV_DBG(dev, "Wrong FC type frame");
+		FCOE_NETDEV_DBG(netdev, "Wrong FC type frame");
 		goto err;
 	}
 
@@ -1013,14 +1197,14 @@
 	 * and FC headers are pulled into the linear data area.
 	 */
 	if (unlikely((skb->len < FCOE_MIN_FRAME) ||
-	    !pskb_may_pull(skb, FCOE_HEADER_LEN)))
+		     !pskb_may_pull(skb, FCOE_HEADER_LEN)))
 		goto err;
 
 	skb_set_transport_header(skb, sizeof(struct fcoe_hdr));
 	fh = (struct fc_frame_header *) skb_transport_header(skb);
 
 	fr = fcoe_dev_from_skb(skb);
-	fr->fr_dev = lp;
+	fr->fr_dev = lport;
 	fr->ptype = ptype;
 
 	/*
@@ -1042,7 +1226,7 @@
 		 * the first CPU now. For non-SMP systems this
 		 * will check the same CPU twice.
 		 */
-		FCOE_NETDEV_DBG(dev, "CPU is online, but no receive thread "
+		FCOE_NETDEV_DBG(netdev, "CPU is online, but no receive thread "
 				"ready for incoming skb- using first online "
 				"CPU.\n");
 
@@ -1061,15 +1245,29 @@
 	 * this skb. We also have this receive thread locked,
 	 * so we're free to queue skbs into it's queue.
 	 */
-	__skb_queue_tail(&fps->fcoe_rx_list, skb);
-	if (fps->fcoe_rx_list.qlen == 1)
-		wake_up_process(fps->thread);
 
-	spin_unlock_bh(&fps->fcoe_rx_list.lock);
+	/* If this is a SCSI-FCP frame, and this is already executing on the
+	 * correct CPU, and the queue for this CPU is empty, then go ahead
+	 * and process the frame directly in the softirq context.
+	 * This lets us process completions without context switching from the
+	 * NET_RX softirq, to our receive processing thread, and then back to
+	 * BLOCK softirq context.
+	 */
+	if (fh->fh_type == FC_TYPE_FCP &&
+	    cpu == smp_processor_id() &&
+	    skb_queue_empty(&fps->fcoe_rx_list)) {
+		spin_unlock_bh(&fps->fcoe_rx_list.lock);
+		fcoe_recv_frame(skb);
+	} else {
+		__skb_queue_tail(&fps->fcoe_rx_list, skb);
+		if (fps->fcoe_rx_list.qlen == 1)
+			wake_up_process(fps->thread);
+		spin_unlock_bh(&fps->fcoe_rx_list.lock);
+	}
 
 	return 0;
 err:
-	fc_lport_get_stats(lp)->ErrorFrames++;
+	fc_lport_get_stats(lport)->ErrorFrames++;
 
 err2:
 	kfree_skb(skb);
@@ -1077,17 +1275,21 @@
 }
 
 /**
- * fcoe_start_io() - pass to netdev to start xmit for fcoe
- * @skb: the skb to be xmitted
+ * fcoe_start_io() - Start FCoE I/O
+ * @skb: The packet to be transmitted
+ *
+ * This routine is called from the net device to start transmitting
+ * FCoE packets.
  *
  * Returns: 0 for success
  */
 static inline int fcoe_start_io(struct sk_buff *skb)
 {
+	struct sk_buff *nskb;
 	int rc;
 
-	skb_get(skb);
-	rc = dev_queue_xmit(skb);
+	nskb = skb_clone(skb, GFP_ATOMIC);
+	rc = dev_queue_xmit(nskb);
 	if (rc != 0)
 		return rc;
 	kfree_skb(skb);
@@ -1095,9 +1297,15 @@
 }
 
 /**
- * fcoe_get_paged_crc_eof() - in case we need to alloc a page for crc_eof
- * @skb: the skb to be xmitted
- * @tlen: total len
+ * fcoe_get_paged_crc_eof() - Allocate a page to be used for the trailer CRC
+ * @skb:  The packet to be transmitted
+ * @tlen: The total length of the trailer
+ *
+ * This routine allocates a page for frame trailers. The page is re-used if
+ * there is enough room left on it for the current trailer. If there isn't
+ * enough buffer left a new page is allocated for the trailer. Reference to
+ * the page from this function as well as the skbs using the page fragments
+ * ensure that the page is freed at the appropriate time.
  *
  * Returns: 0 for success
  */
@@ -1136,11 +1344,12 @@
 }
 
 /**
- * fcoe_fc_crc() - calculates FC CRC in this fcoe skb
- * @fp: the fc_frame containing data to be checksummed
+ * fcoe_fc_crc() - Calculates the CRC for a given frame
+ * @fp: The frame to be checksumed
  *
- * This uses crc32() to calculate the crc for port frame
- * Return   : 32 bit crc
+ * This uses crc32() routine to calculate the CRC for a frame
+ *
+ * Return: The 32 bit CRC value
  */
 u32 fcoe_fc_crc(struct fc_frame *fp)
 {
@@ -1171,13 +1380,13 @@
 }
 
 /**
- * fcoe_xmit() - FCoE frame transmit function
- * @lp:	the associated local fcoe
- * @fp: the fc_frame to be transmitted
+ * fcoe_xmit() - Transmit a FCoE frame
+ * @lport: The local port that the frame is to be transmitted for
+ * @fp:	   The frame to be transmitted
  *
- * Return   : 0 for success
+ * Return: 0 for success
  */
-int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
+int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)
 {
 	int wlen;
 	u32 crc;
@@ -1189,7 +1398,7 @@
 	unsigned int hlen;		/* header length implies the version */
 	unsigned int tlen;		/* trailer length */
 	unsigned int elen;		/* eth header, may include vlan */
-	struct fcoe_port *port = lport_priv(lp);
+	struct fcoe_port *port = lport_priv(lport);
 	struct fcoe_interface *fcoe = port->fcoe;
 	u8 sof, eof;
 	struct fcoe_hdr *hp;
@@ -1200,13 +1409,13 @@
 	skb = fp_skb(fp);
 	wlen = skb->len / FCOE_WORD_TO_BYTE;
 
-	if (!lp->link_up) {
+	if (!lport->link_up) {
 		kfree_skb(skb);
 		return 0;
 	}
 
 	if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ) &&
-	    fcoe_ctlr_els_send(&fcoe->ctlr, skb))
+	    fcoe_ctlr_els_send(&fcoe->ctlr, lport, skb))
 		return 0;
 
 	sof = fr_sof(fp);
@@ -1218,7 +1427,7 @@
 	wlen = (skb->len - tlen + sizeof(crc)) / FCOE_WORD_TO_BYTE;
 
 	/* crc offload */
-	if (likely(lp->crc_offload)) {
+	if (likely(lport->crc_offload)) {
 		skb->ip_summed = CHECKSUM_PARTIAL;
 		skb->csum_start = skb_headroom(skb);
 		skb->csum_offset = skb->len;
@@ -1271,7 +1480,7 @@
 	if (unlikely(fcoe->ctlr.flogi_oxid != FC_XID_UNKNOWN))
 		memcpy(eh->h_source, fcoe->ctlr.ctl_src_addr, ETH_ALEN);
 	else
-		memcpy(eh->h_source, fcoe->ctlr.data_src_addr, ETH_ALEN);
+		memcpy(eh->h_source, port->data_src_addr, ETH_ALEN);
 
 	hp = (struct fcoe_hdr *)(eh + 1);
 	memset(hp, 0, sizeof(*hp));
@@ -1280,7 +1489,7 @@
 	hp->fcoe_sof = sof;
 
 	/* fcoe lso, mss is in max_payload which is non-zero for FCP data */
-	if (lp->seq_offload && fr_max_payload(fp)) {
+	if (lport->seq_offload && fr_max_payload(fp)) {
 		skb_shinfo(skb)->gso_type = SKB_GSO_FCOE;
 		skb_shinfo(skb)->gso_size = fr_max_payload(fp);
 	} else {
@@ -1288,23 +1497,23 @@
 		skb_shinfo(skb)->gso_size = 0;
 	}
 	/* update tx stats: regardless if LLD fails */
-	stats = fc_lport_get_stats(lp);
+	stats = fc_lport_get_stats(lport);
 	stats->TxFrames++;
 	stats->TxWords += wlen;
 
 	/* send down to lld */
-	fr_dev(fp) = lp;
+	fr_dev(fp) = lport;
 	if (port->fcoe_pending_queue.qlen)
-		fcoe_check_wait_queue(lp, skb);
+		fcoe_check_wait_queue(lport, skb);
 	else if (fcoe_start_io(skb))
-		fcoe_check_wait_queue(lp, skb);
+		fcoe_check_wait_queue(lport, skb);
 
 	return 0;
 }
 
 /**
- * fcoe_percpu_flush_done() - Indicate percpu queue flush completion.
- * @skb: the skb being completed.
+ * fcoe_percpu_flush_done() - Indicate per-CPU queue flush completion
+ * @skb: The completed skb (argument required by destructor)
  */
 static void fcoe_percpu_flush_done(struct sk_buff *skb)
 {
@@ -1312,25 +1521,133 @@
 }
 
 /**
- * fcoe_percpu_receive_thread() - recv thread per cpu
- * @arg: ptr to the fcoe per cpu struct
+ * fcoe_recv_frame() - process a single received frame
+ * @skb: frame to process
+ */
+static void fcoe_recv_frame(struct sk_buff *skb)
+{
+	u32 fr_len;
+	struct fc_lport *lport;
+	struct fcoe_rcv_info *fr;
+	struct fcoe_dev_stats *stats;
+	struct fc_frame_header *fh;
+	struct fcoe_crc_eof crc_eof;
+	struct fc_frame *fp;
+	u8 *mac = NULL;
+	struct fcoe_port *port;
+	struct fcoe_hdr *hp;
+
+	fr = fcoe_dev_from_skb(skb);
+	lport = fr->fr_dev;
+	if (unlikely(!lport)) {
+		if (skb->destructor != fcoe_percpu_flush_done)
+			FCOE_NETDEV_DBG(skb->dev, "NULL lport in skb");
+		kfree_skb(skb);
+		return;
+	}
+
+	FCOE_NETDEV_DBG(skb->dev, "skb_info: len:%d data_len:%d "
+			"head:%p data:%p tail:%p end:%p sum:%d dev:%s",
+			skb->len, skb->data_len,
+			skb->head, skb->data, skb_tail_pointer(skb),
+			skb_end_pointer(skb), skb->csum,
+			skb->dev ? skb->dev->name : "<NULL>");
+
+	/*
+	 * Save source MAC address before discarding header.
+	 */
+	port = lport_priv(lport);
+	if (skb_is_nonlinear(skb))
+		skb_linearize(skb);	/* not ideal */
+	mac = eth_hdr(skb)->h_source;
+
+	/*
+	 * Frame length checks and setting up the header pointers
+	 * was done in fcoe_rcv already.
+	 */
+	hp = (struct fcoe_hdr *) skb_network_header(skb);
+	fh = (struct fc_frame_header *) skb_transport_header(skb);
+
+	stats = fc_lport_get_stats(lport);
+	if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) {
+		if (stats->ErrorFrames < 5)
+			printk(KERN_WARNING "fcoe: FCoE version "
+			       "mismatch: The frame has "
+			       "version %x, but the "
+			       "initiator supports version "
+			       "%x\n", FC_FCOE_DECAPS_VER(hp),
+			       FC_FCOE_VER);
+		stats->ErrorFrames++;
+		kfree_skb(skb);
+		return;
+	}
+
+	skb_pull(skb, sizeof(struct fcoe_hdr));
+	fr_len = skb->len - sizeof(struct fcoe_crc_eof);
+
+	stats->RxFrames++;
+	stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
+
+	fp = (struct fc_frame *)skb;
+	fc_frame_init(fp);
+	fr_dev(fp) = lport;
+	fr_sof(fp) = hp->fcoe_sof;
+
+	/* Copy out the CRC and EOF trailer for access */
+	if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) {
+		kfree_skb(skb);
+		return;
+	}
+	fr_eof(fp) = crc_eof.fcoe_eof;
+	fr_crc(fp) = crc_eof.fcoe_crc32;
+	if (pskb_trim(skb, fr_len)) {
+		kfree_skb(skb);
+		return;
+	}
+
+	/*
+	 * We only check CRC if no offload is available and if it is
+	 * it's solicited data, in which case, the FCP layer would
+	 * check it during the copy.
+	 */
+	if (lport->crc_offload &&
+	    skb->ip_summed == CHECKSUM_UNNECESSARY)
+		fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
+	else
+		fr_flags(fp) |= FCPHF_CRC_UNCHECKED;
+
+	fh = fc_frame_header_get(fp);
+	if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA &&
+	    fh->fh_type == FC_TYPE_FCP) {
+		fc_exch_recv(lport, fp);
+		return;
+	}
+	if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) {
+		if (le32_to_cpu(fr_crc(fp)) !=
+		    ~crc32(~0, skb->data, fr_len)) {
+			if (stats->InvalidCRCCount < 5)
+				printk(KERN_WARNING "fcoe: dropping "
+				       "frame with CRC error\n");
+			stats->InvalidCRCCount++;
+			stats->ErrorFrames++;
+			fc_frame_free(fp);
+			return;
+		}
+		fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
+	}
+	fc_exch_recv(lport, fp);
+}
+
+/**
+ * fcoe_percpu_receive_thread() - The per-CPU packet receive thread
+ * @arg: The per-CPU context
  *
  * Return: 0 for success
  */
 int fcoe_percpu_receive_thread(void *arg)
 {
 	struct fcoe_percpu_s *p = arg;
-	u32 fr_len;
-	struct fc_lport *lp;
-	struct fcoe_rcv_info *fr;
-	struct fcoe_dev_stats *stats;
-	struct fc_frame_header *fh;
 	struct sk_buff *skb;
-	struct fcoe_crc_eof crc_eof;
-	struct fc_frame *fp;
-	u8 *mac = NULL;
-	struct fcoe_port *port;
-	struct fcoe_hdr *hp;
 
 	set_user_nice(current, -20);
 
@@ -1347,129 +1664,27 @@
 			spin_lock_bh(&p->fcoe_rx_list.lock);
 		}
 		spin_unlock_bh(&p->fcoe_rx_list.lock);
-		fr = fcoe_dev_from_skb(skb);
-		lp = fr->fr_dev;
-		if (unlikely(lp == NULL)) {
-			if (skb->destructor != fcoe_percpu_flush_done)
-				FCOE_NETDEV_DBG(skb->dev, "NULL lport in skb");
-			kfree_skb(skb);
-			continue;
-		}
-
-		FCOE_NETDEV_DBG(skb->dev, "skb_info: len:%d data_len:%d "
-				"head:%p data:%p tail:%p end:%p sum:%d dev:%s",
-				skb->len, skb->data_len,
-				skb->head, skb->data, skb_tail_pointer(skb),
-				skb_end_pointer(skb), skb->csum,
-				skb->dev ? skb->dev->name : "<NULL>");
-
-		/*
-		 * Save source MAC address before discarding header.
-		 */
-		port = lport_priv(lp);
-		if (skb_is_nonlinear(skb))
-			skb_linearize(skb);	/* not ideal */
-		mac = eth_hdr(skb)->h_source;
-
-		/*
-		 * Frame length checks and setting up the header pointers
-		 * was done in fcoe_rcv already.
-		 */
-		hp = (struct fcoe_hdr *) skb_network_header(skb);
-		fh = (struct fc_frame_header *) skb_transport_header(skb);
-
-		stats = fc_lport_get_stats(lp);
-		if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) {
-			if (stats->ErrorFrames < 5)
-				printk(KERN_WARNING "fcoe: FCoE version "
-				       "mismatch: The frame has "
-				       "version %x, but the "
-				       "initiator supports version "
-				       "%x\n", FC_FCOE_DECAPS_VER(hp),
-				       FC_FCOE_VER);
-			stats->ErrorFrames++;
-			kfree_skb(skb);
-			continue;
-		}
-
-		skb_pull(skb, sizeof(struct fcoe_hdr));
-		fr_len = skb->len - sizeof(struct fcoe_crc_eof);
-
-		stats->RxFrames++;
-		stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
-
-		fp = (struct fc_frame *)skb;
-		fc_frame_init(fp);
-		fr_dev(fp) = lp;
-		fr_sof(fp) = hp->fcoe_sof;
-
-		/* Copy out the CRC and EOF trailer for access */
-		if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) {
-			kfree_skb(skb);
-			continue;
-		}
-		fr_eof(fp) = crc_eof.fcoe_eof;
-		fr_crc(fp) = crc_eof.fcoe_crc32;
-		if (pskb_trim(skb, fr_len)) {
-			kfree_skb(skb);
-			continue;
-		}
-
-		/*
-		 * We only check CRC if no offload is available and if it is
-		 * it's solicited data, in which case, the FCP layer would
-		 * check it during the copy.
-		 */
-		if (lp->crc_offload && skb->ip_summed == CHECKSUM_UNNECESSARY)
-			fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
-		else
-			fr_flags(fp) |= FCPHF_CRC_UNCHECKED;
-
-		fh = fc_frame_header_get(fp);
-		if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA &&
-		    fh->fh_type == FC_TYPE_FCP) {
-			fc_exch_recv(lp, fp);
-			continue;
-		}
-		if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) {
-			if (le32_to_cpu(fr_crc(fp)) !=
-			    ~crc32(~0, skb->data, fr_len)) {
-				if (stats->InvalidCRCCount < 5)
-					printk(KERN_WARNING "fcoe: dropping "
-					       "frame with CRC error\n");
-				stats->InvalidCRCCount++;
-				stats->ErrorFrames++;
-				fc_frame_free(fp);
-				continue;
-			}
-			fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
-		}
-		if (unlikely(port->fcoe->ctlr.flogi_oxid != FC_XID_UNKNOWN) &&
-		    fcoe_ctlr_recv_flogi(&port->fcoe->ctlr, fp, mac)) {
-			fc_frame_free(fp);
-			continue;
-		}
-		fc_exch_recv(lp, fp);
+		fcoe_recv_frame(skb);
 	}
 	return 0;
 }
 
 /**
- * fcoe_check_wait_queue() - attempt to clear the transmit backlog
- * @lp: the fc_lport
+ * fcoe_check_wait_queue() - Attempt to clear the transmit backlog
+ * @lport: The local port whose backlog is to be cleared
  *
- * This empties the wait_queue, dequeue the head of the wait_queue queue
- * and calls fcoe_start_io() for each packet, if all skb have been
- * transmitted, return qlen or -1 if a error occurs, then restore
- * wait_queue and try again later.
+ * This empties the wait_queue, dequeues the head of the wait_queue queue
+ * and calls fcoe_start_io() for each packet. If all skb have been
+ * transmitted it returns the qlen. If an error occurs it restores
+ * wait_queue (to try again later) and returns -1.
  *
- * The wait_queue is used when the skb transmit fails. skb will go
- * in the wait_queue which will be emptied by the timer function or
+ * The wait_queue is used when the skb transmit fails. The failed skb
+ * will go in the wait_queue which will be emptied by the timer function or
  * by the next skb transmit.
  */
-static void fcoe_check_wait_queue(struct fc_lport *lp, struct sk_buff *skb)
+static void fcoe_check_wait_queue(struct fc_lport *lport, struct sk_buff *skb)
 {
-	struct fcoe_port *port = lport_priv(lp);
+	struct fcoe_port *port = lport_priv(lport);
 	int rc;
 
 	spin_lock_bh(&port->fcoe_pending_queue.lock);
@@ -1501,19 +1716,19 @@
 	}
 
 	if (port->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH)
-		lp->qfull = 0;
+		lport->qfull = 0;
 	if (port->fcoe_pending_queue.qlen && !timer_pending(&port->timer))
 		mod_timer(&port->timer, jiffies + 2);
 	port->fcoe_pending_queue_active = 0;
 out:
 	if (port->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH)
-		lp->qfull = 1;
+		lport->qfull = 1;
 	spin_unlock_bh(&port->fcoe_pending_queue.lock);
 	return;
 }
 
 /**
- * fcoe_dev_setup() - setup link change notification interface
+ * fcoe_dev_setup() - Setup the link change notification interface
  */
 static void fcoe_dev_setup(void)
 {
@@ -1521,7 +1736,7 @@
 }
 
 /**
- * fcoe_dev_cleanup() - cleanup link change notification interface
+ * fcoe_dev_cleanup() - Cleanup the link change notification interface
  */
 static void fcoe_dev_cleanup(void)
 {
@@ -1529,19 +1744,19 @@
 }
 
 /**
- * fcoe_device_notification() - netdev event notification callback
- * @notifier: context of the notification
- * @event: type of event
- * @ptr: fixed array for output parsed ifname
+ * fcoe_device_notification() - Handler for net device events
+ * @notifier: The context of the notification
+ * @event:    The type of event
+ * @ptr:      The net device that the event was on
  *
- * This function is called by the ethernet driver in case of link change event
+ * This function is called by the Ethernet driver in case of link change event.
  *
  * Returns: 0 for success
  */
 static int fcoe_device_notification(struct notifier_block *notifier,
 				    ulong event, void *ptr)
 {
-	struct fc_lport *lp = NULL;
+	struct fc_lport *lport = NULL;
 	struct net_device *netdev = ptr;
 	struct fcoe_interface *fcoe;
 	struct fcoe_port *port;
@@ -1552,11 +1767,11 @@
 
 	list_for_each_entry(fcoe, &fcoe_hostlist, list) {
 		if (fcoe->netdev == netdev) {
-			lp = fcoe->ctlr.lp;
+			lport = fcoe->ctlr.lp;
 			break;
 		}
 	}
-	if (lp == NULL) {
+	if (!lport) {
 		rc = NOTIFY_DONE;
 		goto out;
 	}
@@ -1570,10 +1785,12 @@
 	case NETDEV_CHANGE:
 		break;
 	case NETDEV_CHANGEMTU:
+		if (netdev->features & NETIF_F_FCOE_MTU)
+			break;
 		mfs = netdev->mtu - (sizeof(struct fcoe_hdr) +
 				     sizeof(struct fcoe_crc_eof));
 		if (mfs >= FC_MIN_MAX_FRAME)
-			fc_set_mfs(lp, mfs);
+			fc_set_mfs(lport, mfs);
 		break;
 	case NETDEV_REGISTER:
 		break;
@@ -1588,22 +1805,22 @@
 		FCOE_NETDEV_DBG(netdev, "Unknown event %ld "
 				"from netdev netlink\n", event);
 	}
-	if (link_possible && !fcoe_link_ok(lp))
+	if (link_possible && !fcoe_link_ok(lport))
 		fcoe_ctlr_link_up(&fcoe->ctlr);
 	else if (fcoe_ctlr_link_down(&fcoe->ctlr)) {
-		stats = fc_lport_get_stats(lp);
+		stats = fc_lport_get_stats(lport);
 		stats->LinkFailureCount++;
-		fcoe_clean_pending_queue(lp);
+		fcoe_clean_pending_queue(lport);
 	}
 out:
 	return rc;
 }
 
 /**
- * fcoe_if_to_netdev() - parse a name buffer to get netdev
- * @buffer: incoming buffer to be copied
+ * fcoe_if_to_netdev() - Parse a name buffer to get a net device
+ * @buffer: The name of the net device
  *
- * Returns: NULL or ptr to net_device
+ * Returns: NULL or a ptr to net_device
  */
 static struct net_device *fcoe_if_to_netdev(const char *buffer)
 {
@@ -1621,9 +1838,11 @@
 }
 
 /**
- * fcoe_destroy() - handles the destroy from sysfs
- * @buffer: expected to be an eth if name
- * @kp: associated kernel param
+ * fcoe_destroy() - Destroy a FCoE interface
+ * @buffer: The name of the Ethernet interface to be destroyed
+ * @kp:	    The associated kernel parameter
+ *
+ * Called from sysfs.
  *
  * Returns: 0 for success
  */
@@ -1631,7 +1850,7 @@
 {
 	struct fcoe_interface *fcoe;
 	struct net_device *netdev;
-	int rc;
+	int rc = 0;
 
 	mutex_lock(&fcoe_config_mutex);
 #ifdef CONFIG_FCOE_MODULE
@@ -1670,6 +1889,10 @@
 	return rc;
 }
 
+/**
+ * fcoe_destroy_work() - Destroy a FCoE port in a deferred work context
+ * @work: Handle to the FCoE port to be destroyed
+ */
 static void fcoe_destroy_work(struct work_struct *work)
 {
 	struct fcoe_port *port;
@@ -1681,9 +1904,11 @@
 }
 
 /**
- * fcoe_create() - Handles the create call from sysfs
- * @buffer: expected to be an eth if name
- * @kp: associated kernel param
+ * fcoe_create() - Create a fcoe interface
+ * @buffer: The name of the Ethernet interface to create on
+ * @kp:	    The associated kernel param
+ *
+ * Called from sysfs.
  *
  * Returns: 0 for success
  */
@@ -1726,7 +1951,7 @@
 		goto out_putdev;
 	}
 
-	lport = fcoe_if_create(fcoe, &netdev->dev);
+	lport = fcoe_if_create(fcoe, &netdev->dev, 0);
 	if (IS_ERR(lport)) {
 		printk(KERN_ERR "fcoe: Failed to create interface (%s)\n",
 		       netdev->name);
@@ -1762,16 +1987,9 @@
 	return rc;
 }
 
-module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR);
-__MODULE_PARM_TYPE(create, "string");
-MODULE_PARM_DESC(create, "Create fcoe fcoe using net device passed in.");
-module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR);
-__MODULE_PARM_TYPE(destroy, "string");
-MODULE_PARM_DESC(destroy, "Destroy fcoe fcoe");
-
 /**
- * fcoe_link_ok() - Check if link is ok for the fc_lport
- * @lp: ptr to the fc_lport
+ * fcoe_link_ok() - Check if the link is OK for a local port
+ * @lport: The local port to check link on
  *
  * Any permanently-disqualifying conditions have been previously checked.
  * This also updates the speed setting, which may change with link for 100/1000.
@@ -1783,26 +2001,26 @@
  * Returns: 0 if link is OK for use by FCoE.
  *
  */
-int fcoe_link_ok(struct fc_lport *lp)
+int fcoe_link_ok(struct fc_lport *lport)
 {
-	struct fcoe_port *port = lport_priv(lp);
-	struct net_device *dev = port->fcoe->netdev;
+	struct fcoe_port *port = lport_priv(lport);
+	struct net_device *netdev = port->fcoe->netdev;
 	struct ethtool_cmd ecmd = { ETHTOOL_GSET };
 
-	if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) &&
-	    (!dev_ethtool_get_settings(dev, &ecmd))) {
-		lp->link_supported_speeds &=
+	if ((netdev->flags & IFF_UP) && netif_carrier_ok(netdev) &&
+	    (!dev_ethtool_get_settings(netdev, &ecmd))) {
+		lport->link_supported_speeds &=
 			~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
 		if (ecmd.supported & (SUPPORTED_1000baseT_Half |
 				      SUPPORTED_1000baseT_Full))
-			lp->link_supported_speeds |= FC_PORTSPEED_1GBIT;
+			lport->link_supported_speeds |= FC_PORTSPEED_1GBIT;
 		if (ecmd.supported & SUPPORTED_10000baseT_Full)
-			lp->link_supported_speeds |=
+			lport->link_supported_speeds |=
 				FC_PORTSPEED_10GBIT;
 		if (ecmd.speed == SPEED_1000)
-			lp->link_speed = FC_PORTSPEED_1GBIT;
+			lport->link_speed = FC_PORTSPEED_1GBIT;
 		if (ecmd.speed == SPEED_10000)
-			lp->link_speed = FC_PORTSPEED_10GBIT;
+			lport->link_speed = FC_PORTSPEED_10GBIT;
 
 		return 0;
 	}
@@ -1810,8 +2028,8 @@
 }
 
 /**
- * fcoe_percpu_clean() - Clear the pending skbs for an lport
- * @lp: the fc_lport
+ * fcoe_percpu_clean() - Clear all pending skbs for an local port
+ * @lport: The local port whose skbs are to be cleared
  *
  * Must be called with fcoe_create_mutex held to single-thread completion.
  *
@@ -1820,7 +2038,7 @@
  * there no packets that will be handled by the lport, but also that any
  * threads already handling packet have returned.
  */
-void fcoe_percpu_clean(struct fc_lport *lp)
+void fcoe_percpu_clean(struct fc_lport *lport)
 {
 	struct fcoe_percpu_s *pp;
 	struct fcoe_rcv_info *fr;
@@ -1838,7 +2056,7 @@
 		     skb = next) {
 			next = skb->next;
 			fr = fcoe_dev_from_skb(skb);
-			if (fr->fr_dev == lp) {
+			if (fr->fr_dev == lport) {
 				__skb_unlink(skb, list);
 				kfree_skb(skb);
 			}
@@ -1867,13 +2085,11 @@
 
 /**
  * fcoe_clean_pending_queue() - Dequeue a skb and free it
- * @lp: the corresponding fc_lport
- *
- * Returns: none
+ * @lport: The local port to dequeue a skb on
  */
-void fcoe_clean_pending_queue(struct fc_lport *lp)
+void fcoe_clean_pending_queue(struct fc_lport *lport)
 {
-	struct fcoe_port  *port = lport_priv(lp);
+	struct fcoe_port  *port = lport_priv(lport);
 	struct sk_buff *skb;
 
 	spin_lock_bh(&port->fcoe_pending_queue.lock);
@@ -1886,10 +2102,10 @@
 }
 
 /**
- * fcoe_reset() - Resets the fcoe
- * @shost: shost the reset is from
+ * fcoe_reset() - Reset a local port
+ * @shost: The SCSI host associated with the local port to be reset
  *
- * Returns: always 0
+ * Returns: Always 0 (return value required by FC transport template)
  */
 int fcoe_reset(struct Scsi_Host *shost)
 {
@@ -1899,30 +2115,33 @@
 }
 
 /**
- * fcoe_hostlist_lookup_port() - find the corresponding lport by a given device
- * @dev: this is currently ptr to net_device
+ * fcoe_hostlist_lookup_port() - Find the FCoE interface associated with a net device
+ * @netdev: The net device used as a key
  *
- * Returns: NULL or the located fcoe_port
- * Locking: must be called with the RNL mutex held
+ * Locking: Must be called with the RNL mutex held.
+ *
+ * Returns: NULL or the FCoE interface
  */
 static struct fcoe_interface *
-fcoe_hostlist_lookup_port(const struct net_device *dev)
+fcoe_hostlist_lookup_port(const struct net_device *netdev)
 {
 	struct fcoe_interface *fcoe;
 
 	list_for_each_entry(fcoe, &fcoe_hostlist, list) {
-		if (fcoe->netdev == dev)
+		if (fcoe->netdev == netdev)
 			return fcoe;
 	}
 	return NULL;
 }
 
 /**
- * fcoe_hostlist_lookup() - Find the corresponding lport by netdev
- * @netdev: ptr to net_device
+ * fcoe_hostlist_lookup() - Find the local port associated with a
+ *			    given net device
+ * @netdev: The netdevice used as a key
  *
- * Returns: 0 for success
- * Locking: must be called with the RTNL mutex held
+ * Locking: Must be called with the RTNL mutex held
+ *
+ * Returns: NULL or the local port
  */
 static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev)
 {
@@ -1933,11 +2152,13 @@
 }
 
 /**
- * fcoe_hostlist_add() - Add a lport to lports list
- * @lp: ptr to the fc_lport to be added
+ * fcoe_hostlist_add() - Add the FCoE interface identified by a local
+ *			 port to the hostlist
+ * @lport: The local port that identifies the FCoE interface to be added
+ *
+ * Locking: must be called with the RTNL mutex held
  *
  * Returns: 0 for success
- * Locking: must be called with the RTNL mutex held
  */
 static int fcoe_hostlist_add(const struct fc_lport *lport)
 {
@@ -1954,15 +2175,15 @@
 }
 
 /**
- * fcoe_init() - fcoe module loading initialization
+ * fcoe_init() - Initialize fcoe.ko
  *
- * Returns 0 on success, negative on failure
+ * Returns: 0 on success, or a negative value on failure
  */
 static int __init fcoe_init(void)
 {
+	struct fcoe_percpu_s *p;
 	unsigned int cpu;
 	int rc = 0;
-	struct fcoe_percpu_s *p;
 
 	mutex_lock(&fcoe_config_mutex);
 
@@ -1999,15 +2220,15 @@
 module_init(fcoe_init);
 
 /**
- * fcoe_exit() - fcoe module unloading cleanup
+ * fcoe_exit() - Clean up fcoe.ko
  *
- * Returns 0 on success, negative on failure
+ * Returns: 0 on success or a  negative value on failure
  */
 static void __exit fcoe_exit(void)
 {
-	unsigned int cpu;
 	struct fcoe_interface *fcoe, *tmp;
 	struct fcoe_port *port;
+	unsigned int cpu;
 
 	mutex_lock(&fcoe_config_mutex);
 
@@ -2033,9 +2254,238 @@
 	/* flush any asyncronous interface destroys,
 	 * this should happen after the netdev notifier is unregistered */
 	flush_scheduled_work();
+	/* That will flush out all the N_Ports on the hostlist, but now we
+	 * may have NPIV VN_Ports scheduled for destruction */
+	flush_scheduled_work();
 
 	/* detach from scsi transport
 	 * must happen after all destroys are done, therefor after the flush */
 	fcoe_if_exit();
 }
 module_exit(fcoe_exit);
+
+/**
+ * fcoe_flogi_resp() - FCoE specific FLOGI and FDISC response handler
+ * @seq: active sequence in the FLOGI or FDISC exchange
+ * @fp: response frame, or error encoded in a pointer (timeout)
+ * @arg: pointer the the fcoe_ctlr structure
+ *
+ * This handles MAC address managment for FCoE, then passes control on to
+ * the libfc FLOGI response handler.
+ */
+static void fcoe_flogi_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
+{
+	struct fcoe_ctlr *fip = arg;
+	struct fc_exch *exch = fc_seq_exch(seq);
+	struct fc_lport *lport = exch->lp;
+	u8 *mac;
+
+	if (IS_ERR(fp))
+		goto done;
+
+	mac = fr_cb(fp)->granted_mac;
+	if (is_zero_ether_addr(mac)) {
+		/* pre-FIP */
+		if (fcoe_ctlr_recv_flogi(fip, lport, fp)) {
+			fc_frame_free(fp);
+			return;
+		}
+	}
+	fcoe_update_src_mac(lport, mac);
+done:
+	fc_lport_flogi_resp(seq, fp, lport);
+}
+
+/**
+ * fcoe_logo_resp() - FCoE specific LOGO response handler
+ * @seq: active sequence in the LOGO exchange
+ * @fp: response frame, or error encoded in a pointer (timeout)
+ * @arg: pointer the the fcoe_ctlr structure
+ *
+ * This handles MAC address managment for FCoE, then passes control on to
+ * the libfc LOGO response handler.
+ */
+static void fcoe_logo_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
+{
+	struct fc_lport *lport = arg;
+	static u8 zero_mac[ETH_ALEN] = { 0 };
+
+	if (!IS_ERR(fp))
+		fcoe_update_src_mac(lport, zero_mac);
+	fc_lport_logo_resp(seq, fp, lport);
+}
+
+/**
+ * fcoe_elsct_send - FCoE specific ELS handler
+ *
+ * This does special case handling of FIP encapsualted ELS exchanges for FCoE,
+ * using FCoE specific response handlers and passing the FIP controller as
+ * the argument (the lport is still available from the exchange).
+ *
+ * Most of the work here is just handed off to the libfc routine.
+ */
+static struct fc_seq *fcoe_elsct_send(struct fc_lport *lport, u32 did,
+				      struct fc_frame *fp, unsigned int op,
+				      void (*resp)(struct fc_seq *,
+						   struct fc_frame *,
+						   void *),
+				      void *arg, u32 timeout)
+{
+	struct fcoe_port *port = lport_priv(lport);
+	struct fcoe_interface *fcoe = port->fcoe;
+	struct fcoe_ctlr *fip = &fcoe->ctlr;
+	struct fc_frame_header *fh = fc_frame_header_get(fp);
+
+	switch (op) {
+	case ELS_FLOGI:
+	case ELS_FDISC:
+		return fc_elsct_send(lport, did, fp, op, fcoe_flogi_resp,
+				     fip, timeout);
+	case ELS_LOGO:
+		/* only hook onto fabric logouts, not port logouts */
+		if (ntoh24(fh->fh_d_id) != FC_FID_FLOGI)
+			break;
+		return fc_elsct_send(lport, did, fp, op, fcoe_logo_resp,
+				     lport, timeout);
+	}
+	return fc_elsct_send(lport, did, fp, op, resp, arg, timeout);
+}
+
+/**
+ * fcoe_vport_create() - create an fc_host/scsi_host for a vport
+ * @vport: fc_vport object to create a new fc_host for
+ * @disabled: start the new fc_host in a disabled state by default?
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_vport_create(struct fc_vport *vport, bool disabled)
+{
+	struct Scsi_Host *shost = vport_to_shost(vport);
+	struct fc_lport *n_port = shost_priv(shost);
+	struct fcoe_port *port = lport_priv(n_port);
+	struct fcoe_interface *fcoe = port->fcoe;
+	struct net_device *netdev = fcoe->netdev;
+	struct fc_lport *vn_port;
+
+	mutex_lock(&fcoe_config_mutex);
+	vn_port = fcoe_if_create(fcoe, &vport->dev, 1);
+	mutex_unlock(&fcoe_config_mutex);
+
+	if (IS_ERR(vn_port)) {
+		printk(KERN_ERR "fcoe: fcoe_vport_create(%s) failed\n",
+		       netdev->name);
+		return -EIO;
+	}
+
+	if (disabled) {
+		fc_vport_set_state(vport, FC_VPORT_DISABLED);
+	} else {
+		vn_port->boot_time = jiffies;
+		fc_fabric_login(vn_port);
+		fc_vport_setlink(vn_port);
+	}
+	return 0;
+}
+
+/**
+ * fcoe_vport_destroy() - destroy the fc_host/scsi_host for a vport
+ * @vport: fc_vport object that is being destroyed
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_vport_destroy(struct fc_vport *vport)
+{
+	struct Scsi_Host *shost = vport_to_shost(vport);
+	struct fc_lport *n_port = shost_priv(shost);
+	struct fc_lport *vn_port = vport->dd_data;
+	struct fcoe_port *port = lport_priv(vn_port);
+
+	mutex_lock(&n_port->lp_mutex);
+	list_del(&vn_port->list);
+	mutex_unlock(&n_port->lp_mutex);
+	schedule_work(&port->destroy_work);
+	return 0;
+}
+
+/**
+ * fcoe_vport_disable() - change vport state
+ * @vport: vport to bring online/offline
+ * @disable: should the vport be disabled?
+ */
+static int fcoe_vport_disable(struct fc_vport *vport, bool disable)
+{
+	struct fc_lport *lport = vport->dd_data;
+
+	if (disable) {
+		fc_vport_set_state(vport, FC_VPORT_DISABLED);
+		fc_fabric_logoff(lport);
+	} else {
+		lport->boot_time = jiffies;
+		fc_fabric_login(lport);
+		fc_vport_setlink(lport);
+	}
+
+	return 0;
+}
+
+/**
+ * fcoe_vport_set_symbolic_name() - append vport string to symbolic name
+ * @vport: fc_vport with a new symbolic name string
+ *
+ * After generating a new symbolic name string, a new RSPN_ID request is
+ * sent to the name server.  There is no response handler, so if it fails
+ * for some reason it will not be retried.
+ */
+static void fcoe_set_vport_symbolic_name(struct fc_vport *vport)
+{
+	struct fc_lport *lport = vport->dd_data;
+	struct fc_frame *fp;
+	size_t len;
+
+	snprintf(fc_host_symbolic_name(lport->host), FC_SYMBOLIC_NAME_SIZE,
+		 "%s v%s over %s : %s", FCOE_NAME, FCOE_VERSION,
+		 fcoe_netdev(lport)->name, vport->symbolic_name);
+
+	if (lport->state != LPORT_ST_READY)
+		return;
+
+	len = strnlen(fc_host_symbolic_name(lport->host), 255);
+	fp = fc_frame_alloc(lport,
+			    sizeof(struct fc_ct_hdr) +
+			    sizeof(struct fc_ns_rspn) + len);
+	if (!fp)
+		return;
+	lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, FC_NS_RSPN_ID,
+			     NULL, NULL, 3 * lport->r_a_tov);
+}
+
+/**
+ * fcoe_get_lesb() - Fill the FCoE Link Error Status Block
+ * @lport: the local port
+ * @fc_lesb: the link error status block
+ */
+static void fcoe_get_lesb(struct fc_lport *lport,
+			 struct fc_els_lesb *fc_lesb)
+{
+	unsigned int cpu;
+	u32 lfc, vlfc, mdac;
+	struct fcoe_dev_stats *devst;
+	struct fcoe_fc_els_lesb *lesb;
+	struct net_device *netdev = fcoe_netdev(lport);
+
+	lfc = 0;
+	vlfc = 0;
+	mdac = 0;
+	lesb = (struct fcoe_fc_els_lesb *)fc_lesb;
+	memset(lesb, 0, sizeof(*lesb));
+	for_each_possible_cpu(cpu) {
+		devst = per_cpu_ptr(lport->dev_stats, cpu);
+		lfc += devst->LinkFailureCount;
+		vlfc += devst->VLinkFailureCount;
+		mdac += devst->MissDiscAdvCount;
+	}
+	lesb->lesb_link_fail = htonl(lfc);
+	lesb->lesb_vlink_fail = htonl(vlfc);
+	lesb->lesb_miss_fka = htonl(mdac);
+	lesb->lesb_fcs_error = htonl(dev_get_stats(netdev)->rx_crc_errors);
+}
diff --git a/drivers/scsi/fcoe/fcoe.h b/drivers/scsi/fcoe/fcoe.h
index ce7f60f..c69b2c5 100644
--- a/drivers/scsi/fcoe/fcoe.h
+++ b/drivers/scsi/fcoe/fcoe.h
@@ -32,7 +32,7 @@
 #define FCOE_NAME	"fcoe"
 #define FCOE_VENDOR	"Open-FCoE.org"
 
-#define FCOE_MAX_LUN		255
+#define FCOE_MAX_LUN		0xFFFF
 #define FCOE_MAX_FCP_TARGET	256
 
 #define FCOE_MAX_OUTSTANDING_COMMANDS	1024
@@ -40,11 +40,17 @@
 #define FCOE_MIN_XID		0x0000	/* the min xid supported by fcoe_sw */
 #define FCOE_MAX_XID		0x0FFF	/* the max xid supported by fcoe_sw */
 
+/*
+ * Max MTU for FCoE: 14 (FCoE header) + 24 (FC header) + 2112 (max FC payload)
+ * + 4 (FC CRC) + 4 (FCoE trailer) =  2158 bytes
+ */
+#define FCOE_MTU	2158
+
 unsigned int fcoe_debug_logging;
 module_param_named(debug_logging, fcoe_debug_logging, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels");
 
-#define FCOE_LOGGING        0x01 /* General logging, not categorized */
+#define FCOE_LOGGING	    0x01 /* General logging, not categorized */
 #define FCOE_NETDEV_LOGGING 0x02 /* Netdevice logging */
 
 #define FCOE_CHECK_LOGGING(LEVEL, CMD)					\
@@ -64,8 +70,13 @@
 			   printk(KERN_INFO "fcoe: %s: " fmt,	\
 				  netdev->name, ##args);)
 
-/*
- * this percpu struct for fcoe
+/**
+ * struct fcoe_percpu_s - The per-CPU context for FCoE receive threads
+ * @thread:	    The thread context
+ * @fcoe_rx_list:   The queue of pending packets to process
+ * @page:	    The memory page for calculating frame trailer CRCs
+ * @crc_eof_offset: The offset into the CRC page pointing to available
+ *		    memory for a new trailer
  */
 struct fcoe_percpu_s {
 	struct task_struct *thread;
@@ -74,37 +85,62 @@
 	int crc_eof_offset;
 };
 
-/*
- * an FCoE interface, 1:1 with netdev
+/**
+ * struct fcoe_interface - A FCoE interface
+ * @list:	      Handle for a list of FCoE interfaces
+ * @netdev:	      The associated net device
+ * @fcoe_packet_type: FCoE packet type
+ * @fip_packet_type:  FIP packet type
+ * @ctlr:	      The FCoE controller (for FIP)
+ * @oem:	      The offload exchange manager for all local port
+ *		      instances associated with this port
+ * @kref:	      The kernel reference
+ *
+ * This structure is 1:1 with a net devive.
  */
 struct fcoe_interface {
-	struct list_head list;
-	struct net_device *netdev;
-	struct packet_type  fcoe_packet_type;
-	struct packet_type  fip_packet_type;
-	struct fcoe_ctlr ctlr;
-	struct fc_exch_mgr *oem;		/* offload exchange manager */
-	struct kref kref;
+	struct list_head   list;
+	struct net_device  *netdev;
+	struct packet_type fcoe_packet_type;
+	struct packet_type fip_packet_type;
+	struct fcoe_ctlr   ctlr;
+	struct fc_exch_mgr *oem;
+	struct kref	   kref;
 };
 
-/*
- * the FCoE private structure that's allocated along with the
- * Scsi_Host and libfc fc_lport structures
+/**
+ * struct fcoe_port - The FCoE private structure
+ * @fcoe:		       The associated fcoe interface
+ * @lport:		       The associated local port
+ * @fcoe_pending_queue:	       The pending Rx queue of skbs
+ * @fcoe_pending_queue_active: Indicates if the pending queue is active
+ * @timer:		       The queue timer
+ * @destroy_work:	       Handle for work context
+ *			       (to prevent RTNL deadlocks)
+ * @data_srt_addr:	       Source address for data
+ *
+ * An instance of this structure is to be allocated along with the
+ * Scsi_Host and libfc fc_lport structures.
  */
 struct fcoe_port {
 	struct fcoe_interface *fcoe;
-	struct fc_lport *lport;
-	struct sk_buff_head fcoe_pending_queue;
-	u8	fcoe_pending_queue_active;
-	struct timer_list timer;		/* queue timer */
-	struct work_struct destroy_work;	/* to prevent rtnl deadlocks */
+	struct fc_lport	      *lport;
+	struct sk_buff_head   fcoe_pending_queue;
+	u8		      fcoe_pending_queue_active;
+	struct timer_list     timer;
+	struct work_struct    destroy_work;
+	u8		      data_src_addr[ETH_ALEN];
 };
 
 #define fcoe_from_ctlr(fip) container_of(fip, struct fcoe_interface, ctlr)
 
-static inline struct net_device *fcoe_netdev(const struct fc_lport *lp)
+/**
+ * fcoe_netdev() - Return the net device associated with a local port
+ * @lport: The local port to get the net device from
+ */
+static inline struct net_device *fcoe_netdev(const struct fc_lport *lport)
 {
-	return ((struct fcoe_port *)lport_priv(lp))->fcoe->netdev;
+	return ((struct fcoe_port *)lport_priv(lport))->fcoe->netdev;
 }
 
 #endif /* _FCOE_H_ */
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index 11ae5c9..9823291 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -59,26 +59,30 @@
 module_param_named(debug_logging, libfcoe_debug_logging, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels");
 
-#define LIBFCOE_LOGGING     0x01 /* General logging, not categorized */
+#define LIBFCOE_LOGGING	    0x01 /* General logging, not categorized */
 #define LIBFCOE_FIP_LOGGING 0x02 /* FIP logging */
 
-#define LIBFCOE_CHECK_LOGGING(LEVEL, CMD)				\
-do {                                                            	\
-	if (unlikely(libfcoe_debug_logging & LEVEL))			\
-		do {							\
-			CMD;						\
-		} while (0);						\
+#define LIBFCOE_CHECK_LOGGING(LEVEL, CMD)		\
+do {							\
+	if (unlikely(libfcoe_debug_logging & LEVEL))	\
+		do {					\
+			CMD;				\
+		} while (0);				\
 } while (0)
 
 #define LIBFCOE_DBG(fmt, args...)					\
 	LIBFCOE_CHECK_LOGGING(LIBFCOE_LOGGING,				\
 			      printk(KERN_INFO "libfcoe: " fmt, ##args);)
 
-#define LIBFCOE_FIP_DBG(fmt, args...)					\
+#define LIBFCOE_FIP_DBG(fip, fmt, args...)				\
 	LIBFCOE_CHECK_LOGGING(LIBFCOE_FIP_LOGGING,			\
-			      printk(KERN_INFO "fip: " fmt, ##args);)
+			      printk(KERN_INFO "host%d: fip: " fmt, 	\
+				     (fip)->lp->host->host_no, ##args);)
 
-/*
+/**
+ * fcoe_ctlr_mtu_valid() - Check if a FCF's MTU is valid
+ * @fcf: The FCF to check
+ *
  * Return non-zero if FCF fcoe_size has been validated.
  */
 static inline int fcoe_ctlr_mtu_valid(const struct fcoe_fcf *fcf)
@@ -86,7 +90,10 @@
 	return (fcf->flags & FIP_FL_SOL) != 0;
 }
 
-/*
+/**
+ * fcoe_ctlr_fcf_usable() - Check if a FCF is usable
+ * @fcf: The FCF to check
+ *
  * Return non-zero if the FCF is usable.
  */
 static inline int fcoe_ctlr_fcf_usable(struct fcoe_fcf *fcf)
@@ -97,12 +104,13 @@
 }
 
 /**
- * fcoe_ctlr_init() - Initialize the FCoE Controller instance.
- * @fip:	FCoE controller.
+ * fcoe_ctlr_init() - Initialize the FCoE Controller instance
+ * @fip: The FCoE controller to initialize
  */
 void fcoe_ctlr_init(struct fcoe_ctlr *fip)
 {
 	fip->state = FIP_ST_LINK_WAIT;
+	fip->mode = FIP_ST_AUTO;
 	INIT_LIST_HEAD(&fip->fcfs);
 	spin_lock_init(&fip->lock);
 	fip->flogi_oxid = FC_XID_UNKNOWN;
@@ -114,8 +122,8 @@
 EXPORT_SYMBOL(fcoe_ctlr_init);
 
 /**
- * fcoe_ctlr_reset_fcfs() - Reset and free all FCFs for a controller.
- * @fip:	FCoE controller.
+ * fcoe_ctlr_reset_fcfs() - Reset and free all FCFs for a controller
+ * @fip: The FCoE controller whose FCFs are to be reset
  *
  * Called with &fcoe_ctlr lock held.
  */
@@ -134,8 +142,8 @@
 }
 
 /**
- * fcoe_ctlr_destroy() - Disable and tear-down the FCoE controller.
- * @fip:	FCoE controller.
+ * fcoe_ctlr_destroy() - Disable and tear down a FCoE controller
+ * @fip: The FCoE controller to tear down
  *
  * This is called by FCoE drivers before freeing the &fcoe_ctlr.
  *
@@ -148,9 +156,7 @@
 void fcoe_ctlr_destroy(struct fcoe_ctlr *fip)
 {
 	cancel_work_sync(&fip->recv_work);
-	spin_lock_bh(&fip->fip_recv_list.lock);
-	__skb_queue_purge(&fip->fip_recv_list);
-	spin_unlock_bh(&fip->fip_recv_list.lock);
+	skb_queue_purge(&fip->fip_recv_list);
 
 	spin_lock_bh(&fip->lock);
 	fip->state = FIP_ST_DISABLED;
@@ -162,8 +168,8 @@
 EXPORT_SYMBOL(fcoe_ctlr_destroy);
 
 /**
- * fcoe_ctlr_fcoe_size() - Return the maximum FCoE size required for VN_Port.
- * @fip:	FCoE controller.
+ * fcoe_ctlr_fcoe_size() - Return the maximum FCoE size required for VN_Port
+ * @fip: The FCoE controller to get the maximum FCoE size from
  *
  * Returns the maximum packet size including the FCoE header and trailer,
  * but not including any Ethernet or VLAN headers.
@@ -180,9 +186,9 @@
 }
 
 /**
- * fcoe_ctlr_solicit() - Send a solicitation.
- * @fip:	FCoE controller.
- * @fcf:	Destination FCF.  If NULL, a multicast solicitation is sent.
+ * fcoe_ctlr_solicit() - Send a FIP solicitation
+ * @fip: The FCoE controller to send the solicitation on
+ * @fcf: The destination FCF (if NULL, a multicast solicitation is sent)
  */
 static void fcoe_ctlr_solicit(struct fcoe_ctlr *fip, struct fcoe_fcf *fcf)
 {
@@ -241,8 +247,8 @@
 }
 
 /**
- * fcoe_ctlr_link_up() - Start FCoE controller.
- * @fip:	FCoE controller.
+ * fcoe_ctlr_link_up() - Start FCoE controller
+ * @fip: The FCoE controller to start
  *
  * Called from the LLD when the network link is ready.
  */
@@ -255,11 +261,12 @@
 		spin_unlock_bh(&fip->lock);
 		fc_linkup(fip->lp);
 	} else if (fip->state == FIP_ST_LINK_WAIT) {
-		fip->state = FIP_ST_AUTO;
+		fip->state = fip->mode;
 		fip->last_link = 1;
 		fip->link = 1;
 		spin_unlock_bh(&fip->lock);
-		LIBFCOE_FIP_DBG("%s", "setting AUTO mode.\n");
+		if (fip->state == FIP_ST_AUTO)
+			LIBFCOE_FIP_DBG(fip, "%s", "setting AUTO mode.\n");
 		fc_linkup(fip->lp);
 		fcoe_ctlr_solicit(fip, NULL);
 	} else
@@ -268,45 +275,23 @@
 EXPORT_SYMBOL(fcoe_ctlr_link_up);
 
 /**
- * fcoe_ctlr_reset() - Reset FIP.
- * @fip:	FCoE controller.
- * @new_state:	FIP state to be entered.
- *
- * Returns non-zero if the link was up and now isn't.
+ * fcoe_ctlr_reset() - Reset a FCoE controller
+ * @fip:       The FCoE controller to reset
  */
-static int fcoe_ctlr_reset(struct fcoe_ctlr *fip, enum fip_state new_state)
+static void fcoe_ctlr_reset(struct fcoe_ctlr *fip)
 {
-	struct fc_lport *lp = fip->lp;
-	int link_dropped;
-
-	spin_lock_bh(&fip->lock);
 	fcoe_ctlr_reset_fcfs(fip);
 	del_timer(&fip->timer);
-	fip->state = new_state;
 	fip->ctlr_ka_time = 0;
 	fip->port_ka_time = 0;
 	fip->sol_time = 0;
 	fip->flogi_oxid = FC_XID_UNKNOWN;
 	fip->map_dest = 0;
-	fip->last_link = 0;
-	link_dropped = fip->link;
-	fip->link = 0;
-	spin_unlock_bh(&fip->lock);
-
-	if (link_dropped)
-		fc_linkdown(lp);
-
-	if (new_state == FIP_ST_ENABLED) {
-		fcoe_ctlr_solicit(fip, NULL);
-		fc_linkup(lp);
-		link_dropped = 0;
-	}
-	return link_dropped;
 }
 
 /**
- * fcoe_ctlr_link_down() - Stop FCoE controller.
- * @fip:	FCoE controller.
+ * fcoe_ctlr_link_down() - Stop a FCoE controller
+ * @fip: The FCoE controller to be stopped
  *
  * Returns non-zero if the link was up and now isn't.
  *
@@ -315,15 +300,29 @@
  */
 int fcoe_ctlr_link_down(struct fcoe_ctlr *fip)
 {
-	return fcoe_ctlr_reset(fip, FIP_ST_LINK_WAIT);
+	int link_dropped;
+
+	LIBFCOE_FIP_DBG(fip, "link down.\n");
+	spin_lock_bh(&fip->lock);
+	fcoe_ctlr_reset(fip);
+	link_dropped = fip->link;
+	fip->link = 0;
+	fip->last_link = 0;
+	fip->state = FIP_ST_LINK_WAIT;
+	spin_unlock_bh(&fip->lock);
+
+	if (link_dropped)
+		fc_linkdown(fip->lp);
+	return link_dropped;
 }
 EXPORT_SYMBOL(fcoe_ctlr_link_down);
 
 /**
- * fcoe_ctlr_send_keep_alive() - Send a keep-alive to the selected FCF.
- * @fip:	FCoE controller.
- * @ports:	0 for controller keep-alive, 1 for port keep-alive.
- * @sa:		source MAC address.
+ * fcoe_ctlr_send_keep_alive() - Send a keep-alive to the selected FCF
+ * @fip:   The FCoE controller to send the FKA on
+ * @lport: libfc fc_lport to send from
+ * @ports: 0 for controller keep-alive, 1 for port keep-alive
+ * @sa:	   The source MAC address
  *
  * A controller keep-alive is sent every fka_period (typically 8 seconds).
  * The source MAC is the native MAC address.
@@ -332,7 +331,9 @@
  * The source MAC is the assigned mapped source address.
  * The destination is the FCF's F-port.
  */
-static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, int ports, u8 *sa)
+static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip,
+				      struct fc_lport *lport,
+				      int ports, u8 *sa)
 {
 	struct sk_buff *skb;
 	struct fip_kal {
@@ -350,8 +351,7 @@
 	if (!fcf || !fc_host_port_id(lp->host))
 		return;
 
-	len = fcoe_ctlr_fcoe_size(fip) + sizeof(struct ethhdr);
-	BUG_ON(len < sizeof(*kal) + sizeof(*vn));
+	len = sizeof(*kal) + ports * sizeof(*vn);
 	skb = dev_alloc_skb(len);
 	if (!skb)
 		return;
@@ -366,7 +366,7 @@
 	kal->fip.fip_op = htons(FIP_OP_CTRL);
 	kal->fip.fip_subcode = FIP_SC_KEEP_ALIVE;
 	kal->fip.fip_dl_len = htons((sizeof(kal->mac) +
-				    ports * sizeof(*vn)) / FIP_BPW);
+				     ports * sizeof(*vn)) / FIP_BPW);
 	kal->fip.fip_flags = htons(FIP_FL_FPMA);
 	if (fip->spma)
 		kal->fip.fip_flags |= htons(FIP_FL_SPMA);
@@ -374,16 +374,14 @@
 	kal->mac.fd_desc.fip_dtype = FIP_DT_MAC;
 	kal->mac.fd_desc.fip_dlen = sizeof(kal->mac) / FIP_BPW;
 	memcpy(kal->mac.fd_mac, fip->ctl_src_addr, ETH_ALEN);
-
 	if (ports) {
 		vn = (struct fip_vn_desc *)(kal + 1);
 		vn->fd_desc.fip_dtype = FIP_DT_VN_ID;
 		vn->fd_desc.fip_dlen = sizeof(*vn) / FIP_BPW;
-		memcpy(vn->fd_mac, fip->data_src_addr, ETH_ALEN);
+		memcpy(vn->fd_mac, fip->get_src_addr(lport), ETH_ALEN);
 		hton24(vn->fd_fc_id, fc_host_port_id(lp->host));
 		put_unaligned_be64(lp->wwpn, &vn->fd_wwpn);
 	}
-
 	skb_put(skb, len);
 	skb->protocol = htons(ETH_P_FIP);
 	skb_reset_mac_header(skb);
@@ -392,10 +390,10 @@
 }
 
 /**
- * fcoe_ctlr_encaps() - Encapsulate an ELS frame for FIP, without sending it.
- * @fip:	FCoE controller.
- * @dtype:	FIP descriptor type for the frame.
- * @skb:	FCoE ELS frame including FC header but no FCoE headers.
+ * fcoe_ctlr_encaps() - Encapsulate an ELS frame for FIP, without sending it
+ * @fip:   The FCoE controller for the ELS frame
+ * @dtype: The FIP descriptor type for the frame
+ * @skb:   The FCoE ELS frame including FC header but no FCoE headers
  *
  * Returns non-zero error code on failure.
  *
@@ -405,7 +403,7 @@
  * Headroom includes the FIP encapsulation description, FIP header, and
  * Ethernet header.  The tailroom is for the FIP MAC descriptor.
  */
-static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip,
+static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, struct fc_lport *lport,
 			    u8 dtype, struct sk_buff *skb)
 {
 	struct fip_encaps_head {
@@ -449,8 +447,8 @@
 	memset(mac, 0, sizeof(mac));
 	mac->fd_desc.fip_dtype = FIP_DT_MAC;
 	mac->fd_desc.fip_dlen = sizeof(*mac) / FIP_BPW;
-	if (dtype != FIP_DT_FLOGI)
-		memcpy(mac->fd_mac, fip->data_src_addr, ETH_ALEN);
+	if (dtype != FIP_DT_FLOGI && dtype != FIP_DT_FDISC)
+		memcpy(mac->fd_mac, fip->get_src_addr(lport), ETH_ALEN);
 	else if (fip->spma)
 		memcpy(mac->fd_mac, fip->ctl_src_addr, ETH_ALEN);
 
@@ -463,6 +461,7 @@
 /**
  * fcoe_ctlr_els_send() - Send an ELS frame encapsulated by FIP if appropriate.
  * @fip:	FCoE controller.
+ * @lport:	libfc fc_lport to send from
  * @skb:	FCoE ELS frame including FC header but no FCoE headers.
  *
  * Returns a non-zero error code if the frame should not be sent.
@@ -471,11 +470,13 @@
  * The caller must check that the length is a multiple of 4.
  * The SKB must have enough headroom (28 bytes) and tailroom (8 bytes).
  */
-int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
+int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport,
+		       struct sk_buff *skb)
 {
 	struct fc_frame_header *fh;
 	u16 old_xid;
 	u8 op;
+	u8 mac[ETH_ALEN];
 
 	fh = (struct fc_frame_header *)skb->data;
 	op = *(u8 *)(fh + 1);
@@ -498,6 +499,8 @@
 
 	if (fip->state == FIP_ST_NON_FIP)
 		return 0;
+	if (!fip->sel_fcf)
+		goto drop;
 
 	switch (op) {
 	case ELS_FLOGI:
@@ -530,14 +533,15 @@
 		 * FLOGI.
 		 */
 		fip->flogi_oxid = FC_XID_UNKNOWN;
-		fc_fcoe_set_mac(fip->data_src_addr, fh->fh_s_id);
+		fc_fcoe_set_mac(mac, fh->fh_d_id);
+		fip->update_mac(lport, mac);
 		return 0;
 	default:
 		if (fip->state != FIP_ST_ENABLED)
 			goto drop;
 		return 0;
 	}
-	if (fcoe_ctlr_encaps(fip, op, skb))
+	if (fcoe_ctlr_encaps(fip, lport, op, skb))
 		goto drop;
 	fip->send(fip, skb);
 	return -EINPROGRESS;
@@ -547,9 +551,9 @@
 }
 EXPORT_SYMBOL(fcoe_ctlr_els_send);
 
-/*
- * fcoe_ctlr_age_fcfs() - Reset and free all old FCFs for a controller.
- * @fip:	FCoE controller.
+/**
+ * fcoe_ctlr_age_fcfs() - Reset and free all old FCFs for a controller
+ * @fip: The FCoE controller to free FCFs on
  *
  * Called with lock held.
  *
@@ -558,14 +562,28 @@
  * times its keep-alive period including fuzz.
  *
  * In addition, determine the time when an FCF selection can occur.
+ *
+ * Also, increment the MissDiscAdvCount when no advertisement is received
+ * for the corresponding FCF for 1.5 * FKA_ADV_PERIOD (FC-BB-5 LESB).
  */
 static void fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
 {
 	struct fcoe_fcf *fcf;
 	struct fcoe_fcf *next;
 	unsigned long sel_time = 0;
+	unsigned long mda_time = 0;
 
 	list_for_each_entry_safe(fcf, next, &fip->fcfs, list) {
+		mda_time = fcf->fka_period + (fcf->fka_period >> 1);
+		if ((fip->sel_fcf == fcf) &&
+		    (time_after(jiffies, fcf->time + mda_time))) {
+			mod_timer(&fip->timer, jiffies + mda_time);
+			fc_lport_get_stats(fip->lp)->MissDiscAdvCount++;
+			printk(KERN_INFO "libfcoe: host%d: Missing Discovery "
+			       "Advertisement for fab %llx count %lld\n",
+			       fip->lp->host->host_no, fcf->fabric_name,
+			       fc_lport_get_stats(fip->lp)->MissDiscAdvCount);
+		}
 		if (time_after(jiffies, fcf->time + fcf->fka_period * 3 +
 			       msecs_to_jiffies(FIP_FCF_FUZZ * 3))) {
 			if (fip->sel_fcf == fcf)
@@ -574,6 +592,7 @@
 			WARN_ON(!fip->fcf_count);
 			fip->fcf_count--;
 			kfree(fcf);
+			fc_lport_get_stats(fip->lp)->VLinkFailureCount++;
 		} else if (fcoe_ctlr_mtu_valid(fcf) &&
 			   (!sel_time || time_before(sel_time, fcf->time))) {
 			sel_time = fcf->time;
@@ -590,14 +609,16 @@
 }
 
 /**
- * fcoe_ctlr_parse_adv() - Decode a FIP advertisement into a new FCF entry.
- * @skb:	received FIP advertisement frame
- * @fcf:	resulting FCF entry.
+ * fcoe_ctlr_parse_adv() - Decode a FIP advertisement into a new FCF entry
+ * @fip: The FCoE controller receiving the advertisement
+ * @skb: The received FIP advertisement frame
+ * @fcf: The resulting FCF entry
  *
  * Returns zero on a valid parsed advertisement,
  * otherwise returns non zero value.
  */
-static int fcoe_ctlr_parse_adv(struct sk_buff *skb, struct fcoe_fcf *fcf)
+static int fcoe_ctlr_parse_adv(struct fcoe_ctlr *fip,
+			       struct sk_buff *skb, struct fcoe_fcf *fcf)
 {
 	struct fip_header *fiph;
 	struct fip_desc *desc = NULL;
@@ -636,7 +657,7 @@
 			       ((struct fip_mac_desc *)desc)->fd_mac,
 			       ETH_ALEN);
 			if (!is_valid_ether_addr(fcf->fcf_mac)) {
-				LIBFCOE_FIP_DBG("Invalid MAC address "
+				LIBFCOE_FIP_DBG(fip, "Invalid MAC address "
 						"in FIP adv\n");
 				return -EINVAL;
 			}
@@ -659,6 +680,8 @@
 			if (dlen != sizeof(struct fip_fka_desc))
 				goto len_err;
 			fka = (struct fip_fka_desc *)desc;
+			if (fka->fd_flags & FIP_FKA_ADV_D)
+				fcf->fd_flags = 1;
 			t = ntohl(fka->fd_fka_period);
 			if (t >= FCOE_CTLR_MIN_FKA)
 				fcf->fka_period = msecs_to_jiffies(t);
@@ -670,7 +693,7 @@
 		case FIP_DT_LOGO:
 		case FIP_DT_ELP:
 		default:
-			LIBFCOE_FIP_DBG("unexpected descriptor type %x "
+			LIBFCOE_FIP_DBG(fip, "unexpected descriptor type %x "
 					"in FIP adv\n", desc->fip_dtype);
 			/* standard says ignore unknown descriptors >= 128 */
 			if (desc->fip_dtype < FIP_DT_VENDOR_BASE)
@@ -687,15 +710,15 @@
 	return 0;
 
 len_err:
-	LIBFCOE_FIP_DBG("FIP length error in descriptor type %x len %zu\n",
+	LIBFCOE_FIP_DBG(fip, "FIP length error in descriptor type %x len %zu\n",
 			desc->fip_dtype, dlen);
 	return -EINVAL;
 }
 
 /**
- * fcoe_ctlr_recv_adv() - Handle an incoming advertisement.
- * @fip:	FCoE controller.
- * @skb:	Received FIP packet.
+ * fcoe_ctlr_recv_adv() - Handle an incoming advertisement
+ * @fip: The FCoE controller receiving the advertisement
+ * @skb: The received FIP packet
  */
 static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
 {
@@ -706,7 +729,7 @@
 	int first = 0;
 	int mtu_valid;
 
-	if (fcoe_ctlr_parse_adv(skb, &new))
+	if (fcoe_ctlr_parse_adv(fip, skb, &new))
 		return;
 
 	spin_lock_bh(&fip->lock);
@@ -752,7 +775,7 @@
 	mtu_valid = fcoe_ctlr_mtu_valid(fcf);
 	fcf->time = jiffies;
 	if (!found) {
-		LIBFCOE_FIP_DBG("New FCF for fab %llx map %x val %d\n",
+		LIBFCOE_FIP_DBG(fip, "New FCF for fab %llx map %x val %d\n",
 				fcf->fabric_name, fcf->fc_map, mtu_valid);
 	}
 
@@ -778,7 +801,7 @@
 	 */
 	if (mtu_valid && !fip->sel_time && fcoe_ctlr_fcf_usable(fcf)) {
 		fip->sel_time = jiffies +
-				msecs_to_jiffies(FCOE_CTLR_START_DELAY);
+			msecs_to_jiffies(FCOE_CTLR_START_DELAY);
 		if (!timer_pending(&fip->timer) ||
 		    time_before(fip->sel_time, fip->timer.expires))
 			mod_timer(&fip->timer, fip->sel_time);
@@ -788,15 +811,15 @@
 }
 
 /**
- * fcoe_ctlr_recv_els() - Handle an incoming FIP-encapsulated ELS frame.
- * @fip:	FCoE controller.
- * @skb:	Received FIP packet.
+ * fcoe_ctlr_recv_els() - Handle an incoming FIP encapsulated ELS frame
+ * @fip: The FCoE controller which received the packet
+ * @skb: The received FIP packet
  */
 static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
 {
-	struct fc_lport *lp = fip->lp;
+	struct fc_lport *lport = fip->lp;
 	struct fip_header *fiph;
-	struct fc_frame *fp;
+	struct fc_frame *fp = (struct fc_frame *)skb;
 	struct fc_frame_header *fh = NULL;
 	struct fip_desc *desc;
 	struct fip_encaps *els;
@@ -831,10 +854,11 @@
 			       ((struct fip_mac_desc *)desc)->fd_mac,
 			       ETH_ALEN);
 			if (!is_valid_ether_addr(granted_mac)) {
-				LIBFCOE_FIP_DBG("Invalid MAC address "
+				LIBFCOE_FIP_DBG(fip, "Invalid MAC address "
 						"in FIP ELS\n");
 				goto drop;
 			}
+			memcpy(fr_cb(fp)->granted_mac, granted_mac, ETH_ALEN);
 			break;
 		case FIP_DT_FLOGI:
 		case FIP_DT_FDISC:
@@ -850,7 +874,7 @@
 			els_dtype = desc->fip_dtype;
 			break;
 		default:
-			LIBFCOE_FIP_DBG("unexpected descriptor type %x "
+			LIBFCOE_FIP_DBG(fip, "unexpected descriptor type %x "
 					"in FIP adv\n", desc->fip_dtype);
 			/* standard says ignore unknown descriptors >= 128 */
 			if (desc->fip_dtype < FIP_DT_VENDOR_BASE)
@@ -867,11 +891,8 @@
 
 	if (els_dtype == FIP_DT_FLOGI && sub == FIP_SC_REP &&
 	    fip->flogi_oxid == ntohs(fh->fh_ox_id) &&
-	    els_op == ELS_LS_ACC && is_valid_ether_addr(granted_mac)) {
+	    els_op == ELS_LS_ACC && is_valid_ether_addr(granted_mac))
 		fip->flogi_oxid = FC_XID_UNKNOWN;
-		fip->update_mac(fip, fip->data_src_addr, granted_mac);
-		memcpy(fip->data_src_addr, granted_mac, ETH_ALEN);
-	}
 
 	/*
 	 * Convert skb into an fc_frame containing only the ELS.
@@ -882,32 +903,32 @@
 	fc_frame_init(fp);
 	fr_sof(fp) = FC_SOF_I3;
 	fr_eof(fp) = FC_EOF_T;
-	fr_dev(fp) = lp;
+	fr_dev(fp) = lport;
 
-	stats = fc_lport_get_stats(lp);
+	stats = fc_lport_get_stats(lport);
 	stats->RxFrames++;
 	stats->RxWords += skb->len / FIP_BPW;
 
-	fc_exch_recv(lp, fp);
+	fc_exch_recv(lport, fp);
 	return;
 
 len_err:
-	LIBFCOE_FIP_DBG("FIP length error in descriptor type %x len %zu\n",
+	LIBFCOE_FIP_DBG(fip, "FIP length error in descriptor type %x len %zu\n",
 			desc->fip_dtype, dlen);
 drop:
 	kfree_skb(skb);
 }
 
 /**
- * fcoe_ctlr_recv_els() - Handle an incoming link reset frame.
- * @fip:	FCoE controller.
- * @fh:		Received FIP header.
+ * fcoe_ctlr_recv_els() - Handle an incoming link reset frame
+ * @fip: The FCoE controller that received the frame
+ * @fh:	 The received FIP header
  *
  * There may be multiple VN_Port descriptors.
  * The overall length has already been checked.
  */
 static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
-				      struct fip_header *fh)
+				     struct fip_header *fh)
 {
 	struct fip_desc *desc;
 	struct fip_mac_desc *mp;
@@ -916,13 +937,13 @@
 	size_t rlen;
 	size_t dlen;
 	struct fcoe_fcf *fcf = fip->sel_fcf;
-	struct fc_lport *lp = fip->lp;
+	struct fc_lport *lport = fip->lp;
 	u32	desc_mask;
 
-	LIBFCOE_FIP_DBG("Clear Virtual Link received\n");
+	LIBFCOE_FIP_DBG(fip, "Clear Virtual Link received\n");
 	if (!fcf)
 		return;
-	if (!fcf || !fc_host_port_id(lp->host))
+	if (!fcf || !fc_host_port_id(lport->host))
 		return;
 
 	/*
@@ -958,9 +979,10 @@
 			if (dlen < sizeof(*vp))
 				return;
 			if (compare_ether_addr(vp->fd_mac,
-			    fip->data_src_addr) == 0 &&
-			    get_unaligned_be64(&vp->fd_wwpn) == lp->wwpn &&
-			    ntoh24(vp->fd_fc_id) == fc_host_port_id(lp->host))
+					       fip->get_src_addr(lport)) == 0 &&
+			    get_unaligned_be64(&vp->fd_wwpn) == lport->wwpn &&
+			    ntoh24(vp->fd_fc_id) ==
+			    fc_host_port_id(lport->host))
 				desc_mask &= ~BIT(FIP_DT_VN_ID);
 			break;
 		default:
@@ -977,33 +999,39 @@
 	 * reset only if all required descriptors were present and valid.
 	 */
 	if (desc_mask) {
-		LIBFCOE_FIP_DBG("missing descriptors mask %x\n", desc_mask);
+		LIBFCOE_FIP_DBG(fip, "missing descriptors mask %x\n",
+				desc_mask);
 	} else {
-		LIBFCOE_FIP_DBG("performing Clear Virtual Link\n");
-		fcoe_ctlr_reset(fip, FIP_ST_ENABLED);
+		LIBFCOE_FIP_DBG(fip, "performing Clear Virtual Link\n");
+
+		spin_lock_bh(&fip->lock);
+		fc_lport_get_stats(lport)->VLinkFailureCount++;
+		fcoe_ctlr_reset(fip);
+		spin_unlock_bh(&fip->lock);
+
+		fc_lport_reset(fip->lp);
+		fcoe_ctlr_solicit(fip, NULL);
 	}
 }
 
 /**
- * fcoe_ctlr_recv() - Receive a FIP frame.
- * @fip:	FCoE controller.
- * @skb:	Received FIP packet.
+ * fcoe_ctlr_recv() - Receive a FIP packet
+ * @fip: The FCoE controller that received the packet
+ * @skb: The received FIP packet
  *
- * This is called from NET_RX_SOFTIRQ.
+ * This may be called from either NET_RX_SOFTIRQ or IRQ.
  */
 void fcoe_ctlr_recv(struct fcoe_ctlr *fip, struct sk_buff *skb)
 {
-	spin_lock_bh(&fip->fip_recv_list.lock);
-	__skb_queue_tail(&fip->fip_recv_list, skb);
-	spin_unlock_bh(&fip->fip_recv_list.lock);
+	skb_queue_tail(&fip->fip_recv_list, skb);
 	schedule_work(&fip->recv_work);
 }
 EXPORT_SYMBOL(fcoe_ctlr_recv);
 
 /**
- * fcoe_ctlr_recv_handler() - Receive a FIP frame.
- * @fip:	FCoE controller.
- * @skb:	Received FIP packet.
+ * fcoe_ctlr_recv_handler() - Receive a FIP frame
+ * @fip: The FCoE controller that received the frame
+ * @skb: The received FIP frame
  *
  * Returns non-zero if the frame is dropped.
  */
@@ -1038,7 +1066,7 @@
 		fip->map_dest = 0;
 		fip->state = FIP_ST_ENABLED;
 		state = FIP_ST_ENABLED;
-		LIBFCOE_FIP_DBG("Using FIP mode\n");
+		LIBFCOE_FIP_DBG(fip, "Using FIP mode\n");
 	}
 	spin_unlock_bh(&fip->lock);
 	if (state != FIP_ST_ENABLED)
@@ -1060,8 +1088,8 @@
 }
 
 /**
- * fcoe_ctlr_select() - Select the best FCF, if possible.
- * @fip:	FCoE controller.
+ * fcoe_ctlr_select() - Select the best FCF (if possible)
+ * @fip: The FCoE controller
  *
  * If there are conflicting advertisements, no FCF can be chosen.
  *
@@ -1073,11 +1101,11 @@
 	struct fcoe_fcf *best = NULL;
 
 	list_for_each_entry(fcf, &fip->fcfs, list) {
-		LIBFCOE_FIP_DBG("consider FCF for fab %llx VFID %d map %x "
+		LIBFCOE_FIP_DBG(fip, "consider FCF for fab %llx VFID %d map %x "
 				"val %d\n", fcf->fabric_name, fcf->vfid,
 				fcf->fc_map, fcoe_ctlr_mtu_valid(fcf));
 		if (!fcoe_ctlr_fcf_usable(fcf)) {
-			LIBFCOE_FIP_DBG("FCF for fab %llx map %x %svalid "
+			LIBFCOE_FIP_DBG(fip, "FCF for fab %llx map %x %svalid "
 					"%savailable\n", fcf->fabric_name,
 					fcf->fc_map, (fcf->flags & FIP_FL_SOL)
 					? "" : "in", (fcf->flags & FIP_FL_AVAIL)
@@ -1091,7 +1119,7 @@
 		if (fcf->fabric_name != best->fabric_name ||
 		    fcf->vfid != best->vfid ||
 		    fcf->fc_map != best->fc_map) {
-			LIBFCOE_FIP_DBG("Conflicting fabric, VFID, "
+			LIBFCOE_FIP_DBG(fip, "Conflicting fabric, VFID, "
 					"or FC-MAP\n");
 			return;
 		}
@@ -1102,8 +1130,8 @@
 }
 
 /**
- * fcoe_ctlr_timeout() - FIP timer function.
- * @arg:	&fcoe_ctlr pointer.
+ * fcoe_ctlr_timeout() - FIP timeout handler
+ * @arg: The FCoE controller that timed out
  *
  * Ages FCFs.  Triggers FCF selection if possible.  Sends keep-alives.
  */
@@ -1113,8 +1141,6 @@
 	struct fcoe_fcf *sel;
 	struct fcoe_fcf *fcf;
 	unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD);
-	u8 send_ctlr_ka;
-	u8 send_port_ka;
 
 	spin_lock_bh(&fip->lock);
 	if (fip->state == FIP_ST_DISABLED) {
@@ -1140,53 +1166,47 @@
 			       fip->lp->host->host_no, sel->fcf_mac);
 			memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN);
 			fip->port_ka_time = jiffies +
-					    msecs_to_jiffies(FIP_VN_KA_PERIOD);
+				msecs_to_jiffies(FIP_VN_KA_PERIOD);
 			fip->ctlr_ka_time = jiffies + sel->fka_period;
-			fip->link = 1;
 		} else {
 			printk(KERN_NOTICE "libfcoe: host%d: "
-			       "FIP Fibre-Channel Forwarder timed out.  "
+			       "FIP Fibre-Channel Forwarder timed out.	"
 			       "Starting FCF discovery.\n",
 			       fip->lp->host->host_no);
-			fip->link = 0;
+			fip->reset_req = 1;
+			schedule_work(&fip->link_work);
 		}
-		schedule_work(&fip->link_work);
 	}
 
-	send_ctlr_ka = 0;
-	send_port_ka = 0;
-	if (sel) {
+	if (sel && !sel->fd_flags) {
 		if (time_after_eq(jiffies, fip->ctlr_ka_time)) {
 			fip->ctlr_ka_time = jiffies + sel->fka_period;
-			send_ctlr_ka = 1;
+			fip->send_ctlr_ka = 1;
 		}
 		if (time_after(next_timer, fip->ctlr_ka_time))
 			next_timer = fip->ctlr_ka_time;
 
 		if (time_after_eq(jiffies, fip->port_ka_time)) {
 			fip->port_ka_time += jiffies +
-					msecs_to_jiffies(FIP_VN_KA_PERIOD);
-			send_port_ka = 1;
+				msecs_to_jiffies(FIP_VN_KA_PERIOD);
+			fip->send_port_ka = 1;
 		}
 		if (time_after(next_timer, fip->port_ka_time))
 			next_timer = fip->port_ka_time;
 		mod_timer(&fip->timer, next_timer);
 	} else if (fip->sel_time) {
 		next_timer = fip->sel_time +
-				msecs_to_jiffies(FCOE_CTLR_START_DELAY);
+			msecs_to_jiffies(FCOE_CTLR_START_DELAY);
 		mod_timer(&fip->timer, next_timer);
 	}
+	if (fip->send_ctlr_ka || fip->send_port_ka)
+		schedule_work(&fip->link_work);
 	spin_unlock_bh(&fip->lock);
-
-	if (send_ctlr_ka)
-		fcoe_ctlr_send_keep_alive(fip, 0, fip->ctl_src_addr);
-	if (send_port_ka)
-		fcoe_ctlr_send_keep_alive(fip, 1, fip->data_src_addr);
 }
 
 /**
- * fcoe_ctlr_link_work() - worker thread function for link changes.
- * @work:	pointer to link_work member inside &fcoe_ctlr.
+ * fcoe_ctlr_link_work() - Worker thread function for link changes
+ * @work: Handle to a FCoE controller
  *
  * See if the link status has changed and if so, report it.
  *
@@ -1196,27 +1216,49 @@
 static void fcoe_ctlr_link_work(struct work_struct *work)
 {
 	struct fcoe_ctlr *fip;
+	struct fc_lport *vport;
+	u8 *mac;
 	int link;
 	int last_link;
+	int reset;
 
 	fip = container_of(work, struct fcoe_ctlr, link_work);
 	spin_lock_bh(&fip->lock);
 	last_link = fip->last_link;
 	link = fip->link;
 	fip->last_link = link;
+	reset = fip->reset_req;
+	fip->reset_req = 0;
 	spin_unlock_bh(&fip->lock);
 
 	if (last_link != link) {
 		if (link)
 			fc_linkup(fip->lp);
 		else
-			fcoe_ctlr_reset(fip, FIP_ST_LINK_WAIT);
+			fc_linkdown(fip->lp);
+	} else if (reset && link)
+		fc_lport_reset(fip->lp);
+
+	if (fip->send_ctlr_ka) {
+		fip->send_ctlr_ka = 0;
+		fcoe_ctlr_send_keep_alive(fip, NULL, 0, fip->ctl_src_addr);
+	}
+	if (fip->send_port_ka) {
+		fip->send_port_ka = 0;
+		mutex_lock(&fip->lp->lp_mutex);
+		mac = fip->get_src_addr(fip->lp);
+		fcoe_ctlr_send_keep_alive(fip, fip->lp, 1, mac);
+		list_for_each_entry(vport, &fip->lp->vports, list) {
+			mac = fip->get_src_addr(vport);
+			fcoe_ctlr_send_keep_alive(fip, vport, 1, mac);
+		}
+		mutex_unlock(&fip->lp->lp_mutex);
 	}
 }
 
 /**
- * fcoe_ctlr_recv_work() - Worker thread function for receiving FIP frames.
- * @recv_work:	pointer to recv_work member inside &fcoe_ctlr.
+ * fcoe_ctlr_recv_work() - Worker thread function for receiving FIP frames
+ * @recv_work: Handle to a FCoE controller
  */
 static void fcoe_ctlr_recv_work(struct work_struct *recv_work)
 {
@@ -1224,20 +1266,14 @@
 	struct sk_buff *skb;
 
 	fip = container_of(recv_work, struct fcoe_ctlr, recv_work);
-	spin_lock_bh(&fip->fip_recv_list.lock);
-	while ((skb = __skb_dequeue(&fip->fip_recv_list))) {
-		spin_unlock_bh(&fip->fip_recv_list.lock);
+	while ((skb = skb_dequeue(&fip->fip_recv_list)))
 		fcoe_ctlr_recv_handler(fip, skb);
-		spin_lock_bh(&fip->fip_recv_list.lock);
-	}
-	spin_unlock_bh(&fip->fip_recv_list.lock);
 }
 
 /**
- * fcoe_ctlr_recv_flogi() - snoop Pre-FIP receipt of FLOGI response or request.
- * @fip:	FCoE controller.
- * @fp:		FC frame.
- * @sa:		Ethernet source MAC address from received FCoE frame.
+ * fcoe_ctlr_recv_flogi() - Snoop pre-FIP receipt of FLOGI response
+ * @fip: The FCoE controller
+ * @fp:	 The FC frame to snoop
  *
  * Snoop potential response to FLOGI or even incoming FLOGI.
  *
@@ -1245,15 +1281,18 @@
  * by fip->flogi_oxid != FC_XID_UNKNOWN.
  *
  * The caller is responsible for freeing the frame.
+ * Fill in the granted_mac address.
  *
  * Return non-zero if the frame should not be delivered to libfc.
  */
-int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_frame *fp, u8 *sa)
+int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_lport *lport,
+			 struct fc_frame *fp)
 {
 	struct fc_frame_header *fh;
 	u8 op;
-	u8 mac[ETH_ALEN];
+	u8 *sa;
 
+	sa = eth_hdr(&fp->skb)->h_source;
 	fh = fc_frame_header_get(fp);
 	if (fh->fh_type != FC_TYPE_ELS)
 		return 0;
@@ -1268,7 +1307,8 @@
 			return -EINVAL;
 		}
 		fip->state = FIP_ST_NON_FIP;
-		LIBFCOE_FIP_DBG("received FLOGI LS_ACC using non-FIP mode\n");
+		LIBFCOE_FIP_DBG(fip,
+				"received FLOGI LS_ACC using non-FIP mode\n");
 
 		/*
 		 * FLOGI accepted.
@@ -1283,11 +1323,8 @@
 			fip->map_dest = 0;
 		}
 		fip->flogi_oxid = FC_XID_UNKNOWN;
-		memcpy(mac, fip->data_src_addr, ETH_ALEN);
-		fc_fcoe_set_mac(fip->data_src_addr, fh->fh_d_id);
 		spin_unlock_bh(&fip->lock);
-
-		fip->update_mac(fip, mac, fip->data_src_addr);
+		fc_fcoe_set_mac(fr_cb(fp)->granted_mac, fh->fh_d_id);
 	} else if (op == ELS_FLOGI && fh->fh_r_ctl == FC_RCTL_ELS_REQ && sa) {
 		/*
 		 * Save source MAC for point-to-point responses.
@@ -1297,7 +1334,7 @@
 			memcpy(fip->dest_addr, sa, ETH_ALEN);
 			fip->map_dest = 0;
 			if (fip->state == FIP_ST_NON_FIP)
-				LIBFCOE_FIP_DBG("received FLOGI REQ, "
+				LIBFCOE_FIP_DBG(fip, "received FLOGI REQ, "
 						"using non-FIP mode\n");
 			fip->state = FIP_ST_NON_FIP;
 		}
@@ -1308,10 +1345,10 @@
 EXPORT_SYMBOL(fcoe_ctlr_recv_flogi);
 
 /**
- * fcoe_wwn_from_mac() - Converts 48-bit IEEE MAC address to 64-bit FC WWN.
- * @mac: mac address
- * @scheme: check port
- * @port: port indicator for converting
+ * fcoe_wwn_from_mac() - Converts a 48-bit IEEE MAC address to a 64-bit FC WWN
+ * @mac:    The MAC address to convert
+ * @scheme: The scheme to use when converting
+ * @port:   The port indicator for converting
  *
  * Returns: u64 fc world wide name
  */
@@ -1349,24 +1386,26 @@
 EXPORT_SYMBOL_GPL(fcoe_wwn_from_mac);
 
 /**
- * fcoe_libfc_config() - sets up libfc related properties for lport
- * @lp: ptr to the fc_lport
- * @tt: libfc function template
+ * fcoe_libfc_config() - Sets up libfc related properties for local port
+ * @lp: The local port to configure libfc for
+ * @tt: The libfc function template
  *
  * Returns : 0 for success
  */
-int fcoe_libfc_config(struct fc_lport *lp, struct libfc_function_template *tt)
+int fcoe_libfc_config(struct fc_lport *lport,
+		      struct libfc_function_template *tt)
 {
 	/* Set the function pointers set by the LLDD */
-	memcpy(&lp->tt, tt, sizeof(*tt));
-	if (fc_fcp_init(lp))
+	memcpy(&lport->tt, tt, sizeof(*tt));
+	if (fc_fcp_init(lport))
 		return -ENOMEM;
-	fc_exch_init(lp);
-	fc_elsct_init(lp);
-	fc_lport_init(lp);
-	fc_rport_init(lp);
-	fc_disc_init(lp);
+	fc_exch_init(lport);
+	fc_elsct_init(lport);
+	fc_lport_init(lport);
+	fc_rport_init(lport);
+	fc_disc_init(lport);
 
 	return 0;
 }
 EXPORT_SYMBOL_GPL(fcoe_libfc_config);
+
diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h
index e4c0a3d..bb208a6 100644
--- a/drivers/scsi/fnic/fnic.h
+++ b/drivers/scsi/fnic/fnic.h
@@ -22,6 +22,7 @@
 #include <linux/netdevice.h>
 #include <linux/workqueue.h>
 #include <scsi/libfc.h>
+#include <scsi/libfcoe.h>
 #include "fnic_io.h"
 #include "fnic_res.h"
 #include "vnic_dev.h"
@@ -44,7 +45,7 @@
 #define	FNIC_IO_LOCKS		64 /* IO locks: power of 2 */
 #define FNIC_DFLT_QUEUE_DEPTH	32
 #define	FNIC_STATS_RATE_LIMIT	4 /* limit rate at which stats are pulled up */
-
+#define FNIC_MAX_CMD_LEN        16 /* Supported CDB length */
 /*
  * Tag bits used for special requests.
  */
@@ -145,6 +146,7 @@
 /* Per-instance private data structure */
 struct fnic {
 	struct fc_lport *lport;
+	struct fcoe_ctlr ctlr;		/* FIP FCoE controller structure */
 	struct vnic_dev_bar bar0;
 
 	struct msix_entry msix_entry[FNIC_MSIX_INTR_MAX];
@@ -162,23 +164,16 @@
 	unsigned int wq_count;
 	unsigned int cq_count;
 
-	u32 fcoui_mode:1;		/* use fcoui address*/
 	u32 vlan_hw_insert:1;	        /* let hw insert the tag */
 	u32 in_remove:1;                /* fnic device in removal */
 	u32 stop_rx_link_events:1;      /* stop proc. rx frames, link events */
 
 	struct completion *remove_wait; /* device remove thread blocks */
 
-	struct fc_frame *flogi;
-	struct fc_frame *flogi_resp;
-	u16 flogi_oxid;
-	unsigned long s_id;
 	enum fnic_state state;
 	spinlock_t fnic_lock;
 
 	u16 vlan_id;	                /* VLAN tag including priority */
-	u8 mac_addr[ETH_ALEN];
-	u8 dest_addr[ETH_ALEN];
 	u8 data_src_addr[ETH_ALEN];
 	u64 fcp_input_bytes;		/* internal statistic */
 	u64 fcp_output_bytes;		/* internal statistic */
@@ -205,6 +200,7 @@
 	struct work_struct link_work;
 	struct work_struct frame_work;
 	struct sk_buff_head frame_queue;
+	struct sk_buff_head tx_queue;
 
 	/* copy work queue cache line section */
 	____cacheline_aligned struct vnic_wq_copy wq_copy[FNIC_WQ_COPY_MAX];
@@ -224,6 +220,11 @@
 	____cacheline_aligned struct vnic_intr intr[FNIC_MSIX_INTR_MAX];
 };
 
+static inline struct fnic *fnic_from_ctlr(struct fcoe_ctlr *fip)
+{
+	return container_of(fip, struct fnic, ctlr);
+}
+
 extern struct workqueue_struct *fnic_event_queue;
 extern struct device_attribute *fnic_attrs[];
 
@@ -239,7 +240,11 @@
 int fnic_rq_cmpl_handler(struct fnic *fnic, int);
 int fnic_alloc_rq_frame(struct vnic_rq *rq);
 void fnic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf);
-int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp);
+void fnic_flush_tx(struct fnic *);
+void fnic_eth_send(struct fcoe_ctlr *, struct sk_buff *skb);
+void fnic_set_port_id(struct fc_lport *, u32, struct fc_frame *);
+void fnic_update_mac(struct fc_lport *, u8 *new);
+void fnic_update_mac_locked(struct fnic *, u8 *new);
 
 int fnic_queuecommand(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *));
 int fnic_abort_cmd(struct scsi_cmnd *);
@@ -252,7 +257,7 @@
 void fnic_exch_mgr_reset(struct fc_lport *, u32, u32);
 int fnic_wq_copy_cmpl_handler(struct fnic *fnic, int);
 int fnic_wq_cmpl_handler(struct fnic *fnic, int);
-int fnic_flogi_reg_handler(struct fnic *fnic);
+int fnic_flogi_reg_handler(struct fnic *fnic, u32);
 void fnic_wq_copy_cleanup_handler(struct vnic_wq_copy *wq,
 				  struct fcpio_host_req *desc);
 int fnic_fw_reset_handler(struct fnic *fnic);
diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c
index 50db3e3..54f8d0e 100644
--- a/drivers/scsi/fnic/fnic_fcs.c
+++ b/drivers/scsi/fnic/fnic_fcs.c
@@ -23,6 +23,7 @@
 #include <linux/if_ether.h>
 #include <linux/if_vlan.h>
 #include <linux/workqueue.h>
+#include <scsi/fc/fc_fip.h>
 #include <scsi/fc/fc_els.h>
 #include <scsi/fc/fc_fcoe.h>
 #include <scsi/fc_frame.h>
@@ -34,6 +35,8 @@
 
 struct workqueue_struct *fnic_event_queue;
 
+static void fnic_set_eth_mode(struct fnic *);
+
 void fnic_handle_link(struct work_struct *work)
 {
 	struct fnic *fnic = container_of(work, struct fnic, link_work);
@@ -64,10 +67,10 @@
 				spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 				FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
 					     "link down\n");
-				fc_linkdown(fnic->lport);
+				fcoe_ctlr_link_down(&fnic->ctlr);
 				FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
 					     "link up\n");
-				fc_linkup(fnic->lport);
+				fcoe_ctlr_link_up(&fnic->ctlr);
 			} else
 				/* UP -> UP */
 				spin_unlock_irqrestore(&fnic->fnic_lock, flags);
@@ -76,13 +79,13 @@
 		/* DOWN -> UP */
 		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 		FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link up\n");
-		fc_linkup(fnic->lport);
+		fcoe_ctlr_link_up(&fnic->ctlr);
 	} else {
 		/* UP -> DOWN */
 		fnic->lport->host_stats.link_failure_count++;
 		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 		FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link down\n");
-		fc_linkdown(fnic->lport);
+		fcoe_ctlr_link_down(&fnic->ctlr);
 	}
 
 }
@@ -107,197 +110,179 @@
 			return;
 		}
 		fp = (struct fc_frame *)skb;
-		/* if Flogi resp frame, register the address */
-		if (fr_flags(fp)) {
-			vnic_dev_add_addr(fnic->vdev,
-					  fnic->data_src_addr);
-			fr_flags(fp) = 0;
+
+		/*
+		 * If we're in a transitional state, just re-queue and return.
+		 * The queue will be serviced when we get to a stable state.
+		 */
+		if (fnic->state != FNIC_IN_FC_MODE &&
+		    fnic->state != FNIC_IN_ETH_MODE) {
+			skb_queue_head(&fnic->frame_queue, skb);
+			spin_unlock_irqrestore(&fnic->fnic_lock, flags);
+			return;
 		}
 		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 
 		fc_exch_recv(lp, fp);
 	}
-
 }
 
-static inline void fnic_import_rq_fc_frame(struct sk_buff *skb,
-					   u32 len, u8 sof, u8 eof)
-{
-	struct fc_frame *fp = (struct fc_frame *)skb;
-
-	skb_trim(skb, len);
-	fr_eof(fp) = eof;
-	fr_sof(fp) = sof;
-}
-
-
-static inline int fnic_import_rq_eth_pkt(struct sk_buff *skb, u32 len)
+/**
+ * fnic_import_rq_eth_pkt() - handle received FCoE or FIP frame.
+ * @fnic:	fnic instance.
+ * @skb:	Ethernet Frame.
+ */
+static inline int fnic_import_rq_eth_pkt(struct fnic *fnic, struct sk_buff *skb)
 {
 	struct fc_frame *fp;
 	struct ethhdr *eh;
-	struct vlan_ethhdr *vh;
 	struct fcoe_hdr *fcoe_hdr;
 	struct fcoe_crc_eof *ft;
-	u32    transport_len = 0;
 
+	/*
+	 * Undo VLAN encapsulation if present.
+	 */
 	eh = (struct ethhdr *)skb->data;
-	vh = (struct vlan_ethhdr *)skb->data;
-	if (vh->h_vlan_proto == htons(ETH_P_8021Q) &&
-	    vh->h_vlan_encapsulated_proto == htons(ETH_P_FCOE)) {
-		skb_pull(skb, sizeof(struct vlan_ethhdr));
-		transport_len += sizeof(struct vlan_ethhdr);
-	} else if (eh->h_proto == htons(ETH_P_FCOE)) {
-		transport_len += sizeof(struct ethhdr);
-		skb_pull(skb, sizeof(struct ethhdr));
-	} else
-		return -1;
+	if (eh->h_proto == htons(ETH_P_8021Q)) {
+		memmove((u8 *)eh + VLAN_HLEN, eh, ETH_ALEN * 2);
+		eh = (struct ethhdr *)skb_pull(skb, VLAN_HLEN);
+		skb_reset_mac_header(skb);
+	}
+	if (eh->h_proto == htons(ETH_P_FIP)) {
+		skb_pull(skb, sizeof(*eh));
+		fcoe_ctlr_recv(&fnic->ctlr, skb);
+		return 1;		/* let caller know packet was used */
+	}
+	if (eh->h_proto != htons(ETH_P_FCOE))
+		goto drop;
+	skb_set_network_header(skb, sizeof(*eh));
+	skb_pull(skb, sizeof(*eh));
 
 	fcoe_hdr = (struct fcoe_hdr *)skb->data;
 	if (FC_FCOE_DECAPS_VER(fcoe_hdr) != FC_FCOE_VER)
-		return -1;
+		goto drop;
 
 	fp = (struct fc_frame *)skb;
 	fc_frame_init(fp);
 	fr_sof(fp) = fcoe_hdr->fcoe_sof;
 	skb_pull(skb, sizeof(struct fcoe_hdr));
-	transport_len += sizeof(struct fcoe_hdr);
+	skb_reset_transport_header(skb);
 
-	ft = (struct fcoe_crc_eof *)(skb->data + len -
-				     transport_len - sizeof(*ft));
+	ft = (struct fcoe_crc_eof *)(skb->data + skb->len - sizeof(*ft));
 	fr_eof(fp) = ft->fcoe_eof;
-	skb_trim(skb, len - transport_len - sizeof(*ft));
+	skb_trim(skb, skb->len - sizeof(*ft));
 	return 0;
+drop:
+	dev_kfree_skb_irq(skb);
+	return -1;
 }
 
-static inline int fnic_handle_flogi_resp(struct fnic *fnic,
-					 struct fc_frame *fp)
+/**
+ * fnic_update_mac_locked() - set data MAC address and filters.
+ * @fnic:	fnic instance.
+ * @new:	newly-assigned FCoE MAC address.
+ *
+ * Called with the fnic lock held.
+ */
+void fnic_update_mac_locked(struct fnic *fnic, u8 *new)
 {
-	u8 mac[ETH_ALEN] = FC_FCOE_FLOGI_MAC;
-	struct ethhdr *eth_hdr;
-	struct fc_frame_header *fh;
-	int ret = 0;
-	unsigned long flags;
-	struct fc_frame *old_flogi_resp = NULL;
+	u8 *ctl = fnic->ctlr.ctl_src_addr;
+	u8 *data = fnic->data_src_addr;
 
-	fh = (struct fc_frame_header *)fr_hdr(fp);
+	if (is_zero_ether_addr(new))
+		new = ctl;
+	if (!compare_ether_addr(data, new))
+		return;
+	FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "update_mac %pM\n", new);
+	if (!is_zero_ether_addr(data) && compare_ether_addr(data, ctl))
+		vnic_dev_del_addr(fnic->vdev, data);
+	memcpy(data, new, ETH_ALEN);
+	if (compare_ether_addr(new, ctl))
+		vnic_dev_add_addr(fnic->vdev, new);
+}
 
-	spin_lock_irqsave(&fnic->fnic_lock, flags);
+/**
+ * fnic_update_mac() - set data MAC address and filters.
+ * @lport:	local port.
+ * @new:	newly-assigned FCoE MAC address.
+ */
+void fnic_update_mac(struct fc_lport *lport, u8 *new)
+{
+	struct fnic *fnic = lport_priv(lport);
 
-	if (fnic->state == FNIC_IN_ETH_MODE) {
+	spin_lock_irq(&fnic->fnic_lock);
+	fnic_update_mac_locked(fnic, new);
+	spin_unlock_irq(&fnic->fnic_lock);
+}
 
-		/*
-		 * Check if oxid matches on taking the lock. A new Flogi
-		 * issued by libFC might have changed the fnic cached oxid
-		 */
-		if (fnic->flogi_oxid != ntohs(fh->fh_ox_id)) {
-			FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
-				     "Flogi response oxid not"
-				     " matching cached oxid, dropping frame"
-				     "\n");
-			ret = -1;
-			spin_unlock_irqrestore(&fnic->fnic_lock, flags);
-			dev_kfree_skb_irq(fp_skb(fp));
-			goto handle_flogi_resp_end;
+/**
+ * fnic_set_port_id() - set the port_ID after successful FLOGI.
+ * @lport:	local port.
+ * @port_id:	assigned FC_ID.
+ * @fp:		received frame containing the FLOGI accept or NULL.
+ *
+ * This is called from libfc when a new FC_ID has been assigned.
+ * This causes us to reset the firmware to FC_MODE and setup the new MAC
+ * address and FC_ID.
+ *
+ * It is also called with FC_ID 0 when we're logged off.
+ *
+ * If the FC_ID is due to point-to-point, fp may be NULL.
+ */
+void fnic_set_port_id(struct fc_lport *lport, u32 port_id, struct fc_frame *fp)
+{
+	struct fnic *fnic = lport_priv(lport);
+	u8 *mac;
+	int ret;
+
+	FNIC_FCS_DBG(KERN_DEBUG, lport->host, "set port_id %x fp %p\n",
+		     port_id, fp);
+
+	/*
+	 * If we're clearing the FC_ID, change to use the ctl_src_addr.
+	 * Set ethernet mode to send FLOGI.
+	 */
+	if (!port_id) {
+		fnic_update_mac(lport, fnic->ctlr.ctl_src_addr);
+		fnic_set_eth_mode(fnic);
+		return;
+	}
+
+	if (fp) {
+		mac = fr_cb(fp)->granted_mac;
+		if (is_zero_ether_addr(mac)) {
+			/* non-FIP - FLOGI already accepted - ignore return */
+			fcoe_ctlr_recv_flogi(&fnic->ctlr, lport, fp);
 		}
+		fnic_update_mac(lport, mac);
+	}
 
-		/* Drop older cached flogi response frame, cache this frame */
-		old_flogi_resp = fnic->flogi_resp;
-		fnic->flogi_resp = fp;
-		fnic->flogi_oxid = FC_XID_UNKNOWN;
-
-		/*
-		 * this frame is part of flogi get the src mac addr from this
-		 * frame if the src mac is fcoui based then we mark the
-		 * address mode flag to use fcoui base for dst mac addr
-		 * otherwise we have to store the fcoe gateway addr
-		 */
-		eth_hdr = (struct ethhdr *)skb_mac_header(fp_skb(fp));
-		memcpy(mac, eth_hdr->h_source, ETH_ALEN);
-
-		if (ntoh24(mac) == FC_FCOE_OUI)
-			fnic->fcoui_mode = 1;
-		else {
-			fnic->fcoui_mode = 0;
-			memcpy(fnic->dest_addr, mac, ETH_ALEN);
-		}
-
-		/*
-		 * Except for Flogi frame, all outbound frames from us have the
-		 * Eth Src address as FC_FCOE_OUI"our_sid". Flogi frame uses
-		 * the vnic MAC address as the Eth Src address
-		 */
-		fc_fcoe_set_mac(fnic->data_src_addr, fh->fh_d_id);
-
-		/* We get our s_id from the d_id of the flogi resp frame */
-		fnic->s_id = ntoh24(fh->fh_d_id);
-
-		/* Change state to reflect transition from Eth to FC mode */
+	/* Change state to reflect transition to FC mode */
+	spin_lock_irq(&fnic->fnic_lock);
+	if (fnic->state == FNIC_IN_ETH_MODE || fnic->state == FNIC_IN_FC_MODE)
 		fnic->state = FNIC_IN_ETH_TRANS_FC_MODE;
-
-	} else {
+	else {
 		FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
 			     "Unexpected fnic state %s while"
 			     " processing flogi resp\n",
 			     fnic_state_to_str(fnic->state));
-		ret = -1;
-		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
-		dev_kfree_skb_irq(fp_skb(fp));
-		goto handle_flogi_resp_end;
+		spin_unlock_irq(&fnic->fnic_lock);
+		return;
 	}
-
-	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
-
-	/* Drop older cached frame */
-	if (old_flogi_resp)
-		dev_kfree_skb_irq(fp_skb(old_flogi_resp));
+	spin_unlock_irq(&fnic->fnic_lock);
 
 	/*
-	 * send flogi reg request to firmware, this will put the fnic in
-	 * in FC mode
+	 * Send FLOGI registration to firmware to set up FC mode.
+	 * The new address will be set up when registration completes.
 	 */
-	ret = fnic_flogi_reg_handler(fnic);
+	ret = fnic_flogi_reg_handler(fnic, port_id);
 
 	if (ret < 0) {
-		int free_fp = 1;
-		spin_lock_irqsave(&fnic->fnic_lock, flags);
-		/*
-		 * free the frame is some other thread is not
-		 * pointing to it
-		 */
-		if (fnic->flogi_resp != fp)
-			free_fp = 0;
-		else
-			fnic->flogi_resp = NULL;
-
+		spin_lock_irq(&fnic->fnic_lock);
 		if (fnic->state == FNIC_IN_ETH_TRANS_FC_MODE)
 			fnic->state = FNIC_IN_ETH_MODE;
-		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
-		if (free_fp)
-			dev_kfree_skb_irq(fp_skb(fp));
+		spin_unlock_irq(&fnic->fnic_lock);
 	}
-
- handle_flogi_resp_end:
-	return ret;
-}
-
-/* Returns 1 for a response that matches cached flogi oxid */
-static inline int is_matching_flogi_resp_frame(struct fnic *fnic,
-					       struct fc_frame *fp)
-{
-	struct fc_frame_header *fh;
-	int ret = 0;
-	u32 f_ctl;
-
-	fh = fc_frame_header_get(fp);
-	f_ctl = ntoh24(fh->fh_f_ctl);
-
-	if (fnic->flogi_oxid == ntohs(fh->fh_ox_id) &&
-	    fh->fh_r_ctl == FC_RCTL_ELS_REP &&
-	    (f_ctl & (FC_FC_EX_CTX | FC_FC_SEQ_CTX)) == FC_FC_EX_CTX &&
-	    fh->fh_type == FC_TYPE_ELS)
-		ret = 1;
-
-	return ret;
 }
 
 static void fnic_rq_cmpl_frame_recv(struct vnic_rq *rq, struct cq_desc
@@ -326,6 +311,7 @@
 	pci_unmap_single(fnic->pdev, buf->dma_addr, buf->len,
 			 PCI_DMA_FROMDEVICE);
 	skb = buf->os_buf;
+	fp = (struct fc_frame *)skb;
 	buf->os_buf = NULL;
 
 	cq_desc_dec(cq_desc, &type, &color, &q_number, &completed_index);
@@ -338,6 +324,9 @@
 				   &fcoe_enc_error, &fcs_ok, &vlan_stripped,
 				   &vlan);
 		eth_hdrs_stripped = 1;
+		skb_trim(skb, fcp_bytes_written);
+		fr_sof(fp) = sof;
+		fr_eof(fp) = eof;
 
 	} else if (type == CQ_DESC_TYPE_RQ_ENET) {
 		cq_enet_rq_desc_dec((struct cq_enet_rq_desc *)cq_desc,
@@ -352,6 +341,14 @@
 				    &ipv4_csum_ok, &ipv6, &ipv4,
 				    &ipv4_fragment, &fcs_ok);
 		eth_hdrs_stripped = 0;
+		skb_trim(skb, bytes_written);
+		if (!fcs_ok) {
+			FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
+				     "fcs error.  dropping packet.\n");
+			goto drop;
+		}
+		if (fnic_import_rq_eth_pkt(fnic, skb))
+			return;
 
 	} else {
 		/* wrong CQ type*/
@@ -370,43 +367,11 @@
 		goto drop;
 	}
 
-	if (eth_hdrs_stripped)
-		fnic_import_rq_fc_frame(skb, fcp_bytes_written, sof, eof);
-	else if (fnic_import_rq_eth_pkt(skb, bytes_written))
-		goto drop;
-
-	fp = (struct fc_frame *)skb;
-
-	/*
-	 * If frame is an ELS response that matches the cached FLOGI OX_ID,
-	 * and is accept, issue flogi_reg_request copy wq request to firmware
-	 * to register the S_ID and determine whether FC_OUI mode or GW mode.
-	 */
-	if (is_matching_flogi_resp_frame(fnic, fp)) {
-		if (!eth_hdrs_stripped) {
-			if (fc_frame_payload_op(fp) == ELS_LS_ACC) {
-				fnic_handle_flogi_resp(fnic, fp);
-				return;
-			}
-			/*
-			 * Recd. Flogi reject. No point registering
-			 * with fw, but forward to libFC
-			 */
-			goto forward;
-		}
-		goto drop;
-	}
-	if (!eth_hdrs_stripped)
-		goto drop;
-
-forward:
 	spin_lock_irqsave(&fnic->fnic_lock, flags);
 	if (fnic->stop_rx_link_events) {
 		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 		goto drop;
 	}
-	/* Use fr_flags to indicate whether succ. flogi resp or not */
-	fr_flags(fp) = 0;
 	fr_dev(fp) = fnic->lport;
 	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 
@@ -494,12 +459,49 @@
 	buf->os_buf = NULL;
 }
 
-static inline int is_flogi_frame(struct fc_frame_header *fh)
+/**
+ * fnic_eth_send() - Send Ethernet frame.
+ * @fip:	fcoe_ctlr instance.
+ * @skb:	Ethernet Frame, FIP, without VLAN encapsulation.
+ */
+void fnic_eth_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
 {
-	return fh->fh_r_ctl == FC_RCTL_ELS_REQ && *(u8 *)(fh + 1) == ELS_FLOGI;
+	struct fnic *fnic = fnic_from_ctlr(fip);
+	struct vnic_wq *wq = &fnic->wq[0];
+	dma_addr_t pa;
+	struct ethhdr *eth_hdr;
+	struct vlan_ethhdr *vlan_hdr;
+	unsigned long flags;
+
+	if (!fnic->vlan_hw_insert) {
+		eth_hdr = (struct ethhdr *)skb_mac_header(skb);
+		vlan_hdr = (struct vlan_ethhdr *)skb_push(skb,
+				sizeof(*vlan_hdr) - sizeof(*eth_hdr));
+		memcpy(vlan_hdr, eth_hdr, 2 * ETH_ALEN);
+		vlan_hdr->h_vlan_proto = htons(ETH_P_8021Q);
+		vlan_hdr->h_vlan_encapsulated_proto = eth_hdr->h_proto;
+		vlan_hdr->h_vlan_TCI = htons(fnic->vlan_id);
+	}
+
+	pa = pci_map_single(fnic->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
+
+	spin_lock_irqsave(&fnic->wq_lock[0], flags);
+	if (!vnic_wq_desc_avail(wq)) {
+		pci_unmap_single(fnic->pdev, pa, skb->len, PCI_DMA_TODEVICE);
+		spin_unlock_irqrestore(&fnic->wq_lock[0], flags);
+		kfree_skb(skb);
+		return;
+	}
+
+	fnic_queue_wq_eth_desc(wq, skb, pa, skb->len,
+			       fnic->vlan_hw_insert, fnic->vlan_id, 1);
+	spin_unlock_irqrestore(&fnic->wq_lock[0], flags);
 }
 
-int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp)
+/*
+ * Send FC frame.
+ */
+static int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp)
 {
 	struct vnic_wq *wq = &fnic->wq[0];
 	struct sk_buff *skb;
@@ -515,6 +517,10 @@
 	fh = fc_frame_header_get(fp);
 	skb = fp_skb(fp);
 
+	if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ) &&
+	    fcoe_ctlr_els_send(&fnic->ctlr, fnic->lport, skb))
+		return 0;
+
 	if (!fnic->vlan_hw_insert) {
 		eth_hdr_len = sizeof(*vlan_hdr) + sizeof(*fcoe_hdr);
 		vlan_hdr = (struct vlan_ethhdr *)skb_push(skb, eth_hdr_len);
@@ -530,16 +536,11 @@
 		fcoe_hdr = (struct fcoe_hdr *)(eth_hdr + 1);
 	}
 
-	if (is_flogi_frame(fh)) {
+	if (fnic->ctlr.map_dest)
 		fc_fcoe_set_mac(eth_hdr->h_dest, fh->fh_d_id);
-		memcpy(eth_hdr->h_source, fnic->mac_addr, ETH_ALEN);
-	} else {
-		if (fnic->fcoui_mode)
-			fc_fcoe_set_mac(eth_hdr->h_dest, fh->fh_d_id);
-		else
-			memcpy(eth_hdr->h_dest, fnic->dest_addr, ETH_ALEN);
-		memcpy(eth_hdr->h_source, fnic->data_src_addr, ETH_ALEN);
-	}
+	else
+		memcpy(eth_hdr->h_dest, fnic->ctlr.dest_addr, ETH_ALEN);
+	memcpy(eth_hdr->h_source, fnic->data_src_addr, ETH_ALEN);
 
 	tot_len = skb->len;
 	BUG_ON(tot_len % 4);
@@ -578,109 +579,85 @@
 int fnic_send(struct fc_lport *lp, struct fc_frame *fp)
 {
 	struct fnic *fnic = lport_priv(lp);
-	struct fc_frame_header *fh;
-	int ret = 0;
-	enum fnic_state old_state;
 	unsigned long flags;
-	struct fc_frame *old_flogi = NULL;
-	struct fc_frame *old_flogi_resp = NULL;
 
 	if (fnic->in_remove) {
 		dev_kfree_skb(fp_skb(fp));
-		ret = -1;
-		goto fnic_send_end;
+		return -1;
 	}
 
-	fh = fc_frame_header_get(fp);
-	/* if not an Flogi frame, send it out, this is the common case */
-	if (!is_flogi_frame(fh))
-		return fnic_send_frame(fnic, fp);
+	/*
+	 * Queue frame if in a transitional state.
+	 * This occurs while registering the Port_ID / MAC address after FLOGI.
+	 */
+	spin_lock_irqsave(&fnic->fnic_lock, flags);
+	if (fnic->state != FNIC_IN_FC_MODE && fnic->state != FNIC_IN_ETH_MODE) {
+		skb_queue_tail(&fnic->tx_queue, fp_skb(fp));
+		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
+		return 0;
+	}
+	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 
-	/* Flogi frame, now enter the state machine */
+	return fnic_send_frame(fnic, fp);
+}
+
+/**
+ * fnic_flush_tx() - send queued frames.
+ * @fnic: fnic device
+ *
+ * Send frames that were waiting to go out in FC or Ethernet mode.
+ * Whenever changing modes we purge queued frames, so these frames should
+ * be queued for the stable mode that we're in, either FC or Ethernet.
+ *
+ * Called without fnic_lock held.
+ */
+void fnic_flush_tx(struct fnic *fnic)
+{
+	struct sk_buff *skb;
+	struct fc_frame *fp;
+
+	while ((skb = skb_dequeue(&fnic->frame_queue))) {
+		fp = (struct fc_frame *)skb;
+		fnic_send_frame(fnic, fp);
+	}
+}
+
+/**
+ * fnic_set_eth_mode() - put fnic into ethernet mode.
+ * @fnic: fnic device
+ *
+ * Called without fnic lock held.
+ */
+static void fnic_set_eth_mode(struct fnic *fnic)
+{
+	unsigned long flags;
+	enum fnic_state old_state;
+	int ret;
 
 	spin_lock_irqsave(&fnic->fnic_lock, flags);
 again:
-	/* Get any old cached frames, free them after dropping lock */
-	old_flogi = fnic->flogi;
-	fnic->flogi = NULL;
-	old_flogi_resp = fnic->flogi_resp;
-	fnic->flogi_resp = NULL;
-
-	fnic->flogi_oxid = FC_XID_UNKNOWN;
-
 	old_state = fnic->state;
 	switch (old_state) {
 	case FNIC_IN_FC_MODE:
 	case FNIC_IN_ETH_TRANS_FC_MODE:
 	default:
 		fnic->state = FNIC_IN_FC_TRANS_ETH_MODE;
-		vnic_dev_del_addr(fnic->vdev, fnic->data_src_addr);
 		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 
-		if (old_flogi) {
-			dev_kfree_skb(fp_skb(old_flogi));
-			old_flogi = NULL;
-		}
-		if (old_flogi_resp) {
-			dev_kfree_skb(fp_skb(old_flogi_resp));
-			old_flogi_resp = NULL;
-		}
-
 		ret = fnic_fw_reset_handler(fnic);
 
 		spin_lock_irqsave(&fnic->fnic_lock, flags);
 		if (fnic->state != FNIC_IN_FC_TRANS_ETH_MODE)
 			goto again;
-		if (ret) {
+		if (ret)
 			fnic->state = old_state;
-			spin_unlock_irqrestore(&fnic->fnic_lock, flags);
-			dev_kfree_skb(fp_skb(fp));
-			goto fnic_send_end;
-		}
-		old_flogi = fnic->flogi;
-		fnic->flogi = fp;
-		fnic->flogi_oxid = ntohs(fh->fh_ox_id);
-		old_flogi_resp = fnic->flogi_resp;
-		fnic->flogi_resp = NULL;
-		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 		break;
 
 	case FNIC_IN_FC_TRANS_ETH_MODE:
-		/*
-		 * A reset is pending with the firmware. Store the flogi
-		 * and its oxid. The transition out of this state happens
-		 * only when Firmware completes the reset, either with
-		 * success or failed. If success, transition to
-		 * FNIC_IN_ETH_MODE, if fail, then transition to
-		 * FNIC_IN_FC_MODE
-		 */
-		fnic->flogi = fp;
-		fnic->flogi_oxid = ntohs(fh->fh_ox_id);
-		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
-		break;
-
 	case FNIC_IN_ETH_MODE:
-		/*
-		 * The fw/hw is already in eth mode. Store the oxid,
-		 * and send the flogi frame out. The transition out of this
-		 * state happens only we receive flogi response from the
-		 * network, and the oxid matches the cached oxid when the
-		 * flogi frame was sent out. If they match, then we issue
-		 * a flogi_reg request and transition to state
-		 * FNIC_IN_ETH_TRANS_FC_MODE
-		 */
-		fnic->flogi_oxid = ntohs(fh->fh_ox_id);
-		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
-		ret = fnic_send_frame(fnic, fp);
 		break;
 	}
-
-fnic_send_end:
-	if (old_flogi)
-		dev_kfree_skb(fp_skb(old_flogi));
-	if (old_flogi_resp)
-		dev_kfree_skb(fp_skb(old_flogi_resp));
-	return ret;
+	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 }
 
 static void fnic_wq_complete_frame_send(struct vnic_wq *wq,
diff --git a/drivers/scsi/fnic/fnic_isr.c b/drivers/scsi/fnic/fnic_isr.c
index 2b30648..5c1f223 100644
--- a/drivers/scsi/fnic/fnic_isr.c
+++ b/drivers/scsi/fnic/fnic_isr.c
@@ -48,9 +48,9 @@
 	}
 
 	if (pba & (1 << FNIC_INTX_WQ_RQ_COPYWQ)) {
-		work_done += fnic_wq_copy_cmpl_handler(fnic, 8);
-		work_done += fnic_wq_cmpl_handler(fnic, 4);
-		work_done += fnic_rq_cmpl_handler(fnic, 4);
+		work_done += fnic_wq_copy_cmpl_handler(fnic, -1);
+		work_done += fnic_wq_cmpl_handler(fnic, -1);
+		work_done += fnic_rq_cmpl_handler(fnic, -1);
 
 		vnic_intr_return_credits(&fnic->intr[FNIC_INTX_WQ_RQ_COPYWQ],
 					 work_done,
@@ -66,9 +66,9 @@
 	struct fnic *fnic = data;
 	unsigned long work_done = 0;
 
-	work_done += fnic_wq_copy_cmpl_handler(fnic, 8);
-	work_done += fnic_wq_cmpl_handler(fnic, 4);
-	work_done += fnic_rq_cmpl_handler(fnic, 4);
+	work_done += fnic_wq_copy_cmpl_handler(fnic, -1);
+	work_done += fnic_wq_cmpl_handler(fnic, -1);
+	work_done += fnic_rq_cmpl_handler(fnic, -1);
 
 	vnic_intr_return_credits(&fnic->intr[0],
 				 work_done,
@@ -83,7 +83,7 @@
 	struct fnic *fnic = data;
 	unsigned long rq_work_done = 0;
 
-	rq_work_done = fnic_rq_cmpl_handler(fnic, 4);
+	rq_work_done = fnic_rq_cmpl_handler(fnic, -1);
 	vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_RQ],
 				 rq_work_done,
 				 1 /* unmask intr */,
@@ -97,7 +97,7 @@
 	struct fnic *fnic = data;
 	unsigned long wq_work_done = 0;
 
-	wq_work_done = fnic_wq_cmpl_handler(fnic, 4);
+	wq_work_done = fnic_wq_cmpl_handler(fnic, -1);
 	vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_WQ],
 				 wq_work_done,
 				 1 /* unmask intr */,
@@ -110,7 +110,7 @@
 	struct fnic *fnic = data;
 	unsigned long wq_copy_work_done = 0;
 
-	wq_copy_work_done = fnic_wq_copy_cmpl_handler(fnic, 8);
+	wq_copy_work_done = fnic_wq_copy_cmpl_handler(fnic, -1);
 	vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_WQ_COPY],
 				 wq_copy_work_done,
 				 1 /* unmask intr */,
diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c
index 71c7bbe..fe1b1031 100644
--- a/drivers/scsi/fnic/fnic_main.c
+++ b/drivers/scsi/fnic/fnic_main.c
@@ -25,6 +25,8 @@
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
+#include <linux/if_ether.h>
+#include <scsi/fc/fc_fip.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_transport.h>
 #include <scsi/scsi_transport_fc.h>
@@ -68,6 +70,7 @@
 
 static struct libfc_function_template fnic_transport_template = {
 	.frame_send = fnic_send,
+	.lport_set_port_id = fnic_set_port_id,
 	.fcp_abort_io = fnic_empty_scsi_cleanup,
 	.fcp_cleanup = fnic_empty_scsi_cleanup,
 	.exch_mgr_reset = fnic_exch_mgr_reset
@@ -140,6 +143,7 @@
 	.get_fc_host_stats = fnic_get_stats,
 	.dd_fcrport_size = sizeof(struct fc_rport_libfc_priv),
 	.terminate_rport_io = fnic_terminate_rport_io,
+	.bsg_request = fc_lport_bsg_request,
 };
 
 static void fnic_get_host_speed(struct Scsi_Host *shost)
@@ -324,9 +328,6 @@
 {
 	unsigned int i;
 	int err;
-	unsigned long flags;
-	struct fc_frame *flogi = NULL;
-	struct fc_frame *flogi_resp = NULL;
 
 	vnic_dev_disable(fnic->vdev);
 	for (i = 0; i < fnic->intr_count; i++)
@@ -367,24 +368,6 @@
 	for (i = 0; i < fnic->intr_count; i++)
 		vnic_intr_clean(&fnic->intr[i]);
 
-	/*
-	 * Remove cached flogi and flogi resp frames if any
-	 * These frames are not in any queue, and therefore queue
-	 * cleanup does not clean them. So clean them explicitly
-	 */
-	spin_lock_irqsave(&fnic->fnic_lock, flags);
-	flogi = fnic->flogi;
-	fnic->flogi = NULL;
-	flogi_resp = fnic->flogi_resp;
-	fnic->flogi_resp = NULL;
-	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
-
-	if (flogi)
-		dev_kfree_skb(fp_skb(flogi));
-
-	if (flogi_resp)
-		dev_kfree_skb(fp_skb(flogi_resp));
-
 	mempool_destroy(fnic->io_req_pool);
 	for (i = 0; i < FNIC_SGL_NUM_CACHES; i++)
 		mempool_destroy(fnic->io_sgl_pool[i]);
@@ -409,6 +392,17 @@
 	return kmem_cache_alloc(mem, gfp_mask | GFP_ATOMIC | GFP_DMA);
 }
 
+/**
+ * fnic_get_mac() - get assigned data MAC address for FIP code.
+ * @lport: 	local port.
+ */
+static u8 *fnic_get_mac(struct fc_lport *lport)
+{
+	struct fnic *fnic = lport_priv(lport);
+
+	return fnic->data_src_addr;
+}
+
 static int __devinit fnic_probe(struct pci_dev *pdev,
 				const struct pci_device_id *ent)
 {
@@ -424,17 +418,16 @@
 	 * Allocate SCSI Host and set up association between host,
 	 * local port, and fnic
 	 */
-	host = scsi_host_alloc(&fnic_host_template,
-			       sizeof(struct fc_lport) + sizeof(struct fnic));
-	if (!host) {
-		printk(KERN_ERR PFX "Unable to alloc SCSI host\n");
+	lp = libfc_host_alloc(&fnic_host_template, sizeof(struct fnic));
+	if (!lp) {
+		printk(KERN_ERR PFX "Unable to alloc libfc local port\n");
 		err = -ENOMEM;
 		goto err_out;
 	}
-	lp = shost_priv(host);
-	lp->host = host;
+	host = lp->host;
 	fnic = lport_priv(lp);
 	fnic->lport = lp;
+	fnic->ctlr.lp = lp;
 
 	snprintf(fnic->name, sizeof(fnic->name) - 1, "%s%d", DRV_NAME,
 		 host->host_no);
@@ -543,12 +536,14 @@
 		goto err_out_dev_close;
 	}
 
-	err = vnic_dev_mac_addr(fnic->vdev, fnic->mac_addr);
+	err = vnic_dev_mac_addr(fnic->vdev, fnic->ctlr.ctl_src_addr);
 	if (err) {
 		shost_printk(KERN_ERR, fnic->lport->host,
 			     "vNIC get MAC addr failed \n");
 		goto err_out_dev_close;
 	}
+	/* set data_src for point-to-point mode and to keep it non-zero */
+	memcpy(fnic->data_src_addr, fnic->ctlr.ctl_src_addr, ETH_ALEN);
 
 	/* Get vNIC configuration */
 	err = fnic_get_vnic_config(fnic);
@@ -560,6 +555,7 @@
 	}
 	host->max_lun = fnic->config.luns_per_tgt;
 	host->max_id = FNIC_MAX_FCP_TARGET;
+	host->max_cmd_len = FNIC_MAX_CMD_LEN;
 
 	fnic_get_res_counts(fnic);
 
@@ -571,19 +567,12 @@
 		goto err_out_dev_close;
 	}
 
-	err = fnic_request_intr(fnic);
-	if (err) {
-		shost_printk(KERN_ERR, fnic->lport->host,
-			     "Unable to request irq.\n");
-		goto err_out_clear_intr;
-	}
-
 	err = fnic_alloc_vnic_resources(fnic);
 	if (err) {
 		shost_printk(KERN_ERR, fnic->lport->host,
 			     "Failed to alloc vNIC resources, "
 			     "aborting.\n");
-		goto err_out_free_intr;
+		goto err_out_clear_intr;
 	}
 
 
@@ -623,9 +612,21 @@
 	fnic->vlan_hw_insert = 1;
 	fnic->vlan_id = 0;
 
-	fnic->flogi_oxid = FC_XID_UNKNOWN;
-	fnic->flogi = NULL;
-	fnic->flogi_resp = NULL;
+	/* Initialize the FIP fcoe_ctrl struct */
+	fnic->ctlr.send = fnic_eth_send;
+	fnic->ctlr.update_mac = fnic_update_mac;
+	fnic->ctlr.get_src_addr = fnic_get_mac;
+	fcoe_ctlr_init(&fnic->ctlr);
+	if (fnic->config.flags & VFCF_FIP_CAPABLE) {
+		shost_printk(KERN_INFO, fnic->lport->host,
+			     "firmware supports FIP\n");
+		vnic_dev_add_addr(fnic->vdev, FIP_ALL_ENODE_MACS);
+		vnic_dev_add_addr(fnic->vdev, fnic->ctlr.ctl_src_addr);
+	} else {
+		shost_printk(KERN_INFO, fnic->lport->host,
+			     "firmware uses non-FIP mode\n");
+		fnic->ctlr.mode = FIP_ST_NON_FIP;
+	}
 	fnic->state = FNIC_IN_FC_MODE;
 
 	/* Enable hardware stripping of vlan header on ingress */
@@ -716,6 +717,7 @@
 	INIT_WORK(&fnic->link_work, fnic_handle_link);
 	INIT_WORK(&fnic->frame_work, fnic_handle_frame);
 	skb_queue_head_init(&fnic->frame_queue);
+	skb_queue_head_init(&fnic->tx_queue);
 
 	/* Enable all queues */
 	for (i = 0; i < fnic->raw_wq_count; i++)
@@ -728,6 +730,14 @@
 	fc_fabric_login(lp);
 
 	vnic_dev_enable(fnic->vdev);
+
+	err = fnic_request_intr(fnic);
+	if (err) {
+		shost_printk(KERN_ERR, fnic->lport->host,
+			     "Unable to request irq.\n");
+		goto err_out_free_exch_mgr;
+	}
+
 	for (i = 0; i < fnic->intr_count; i++)
 		vnic_intr_unmask(&fnic->intr[i]);
 
@@ -738,8 +748,8 @@
 err_out_free_exch_mgr:
 	fc_exch_mgr_free(lp);
 err_out_remove_scsi_host:
-	fc_remove_host(fnic->lport->host);
-	scsi_remove_host(fnic->lport->host);
+	fc_remove_host(lp->host);
+	scsi_remove_host(lp->host);
 err_out_free_rq_buf:
 	for (i = 0; i < fnic->rq_count; i++)
 		vnic_rq_clean(&fnic->rq[i], fnic_free_rq_buf);
@@ -752,8 +762,6 @@
 	mempool_destroy(fnic->io_req_pool);
 err_out_free_resources:
 	fnic_free_vnic_resources(fnic);
-err_out_free_intr:
-	fnic_free_intr(fnic);
 err_out_clear_intr:
 	fnic_clear_intr_mode(fnic);
 err_out_dev_close:
@@ -775,6 +783,7 @@
 static void __devexit fnic_remove(struct pci_dev *pdev)
 {
 	struct fnic *fnic = pci_get_drvdata(pdev);
+	struct fc_lport *lp = fnic->lport;
 	unsigned long flags;
 
 	/*
@@ -796,6 +805,7 @@
 	 */
 	flush_workqueue(fnic_event_queue);
 	skb_queue_purge(&fnic->frame_queue);
+	skb_queue_purge(&fnic->tx_queue);
 
 	/*
 	 * Log off the fabric. This stops all remote ports, dns port,
@@ -808,7 +818,8 @@
 	fnic->in_remove = 1;
 	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 
-	fc_lport_destroy(fnic->lport);
+	fcoe_ctlr_destroy(&fnic->ctlr);
+	fc_lport_destroy(lp);
 
 	/*
 	 * This stops the fnic device, masks all interrupts. Completed
@@ -818,6 +829,7 @@
 	fnic_cleanup(fnic);
 
 	BUG_ON(!skb_queue_empty(&fnic->frame_queue));
+	BUG_ON(!skb_queue_empty(&fnic->tx_queue));
 
 	spin_lock_irqsave(&fnic_list_lock, flags);
 	list_del(&fnic->list);
@@ -827,8 +839,8 @@
 	scsi_remove_host(fnic->lport->host);
 	fc_exch_mgr_free(fnic->lport);
 	vnic_dev_notify_unset(fnic->vdev);
-	fnic_free_vnic_resources(fnic);
 	fnic_free_intr(fnic);
+	fnic_free_vnic_resources(fnic);
 	fnic_clear_intr_mode(fnic);
 	vnic_dev_close(fnic->vdev);
 	vnic_dev_unregister(fnic->vdev);
@@ -836,7 +848,7 @@
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
-	scsi_host_put(fnic->lport->host);
+	scsi_host_put(lp->host);
 }
 
 static struct pci_driver fnic_driver = {
diff --git a/drivers/scsi/fnic/fnic_res.c b/drivers/scsi/fnic/fnic_res.c
index 7ba61ec..50488f8 100644
--- a/drivers/scsi/fnic/fnic_res.c
+++ b/drivers/scsi/fnic/fnic_res.c
@@ -144,10 +144,9 @@
 	c->intr_timer_type = c->intr_timer_type;
 
 	shost_printk(KERN_INFO, fnic->lport->host,
-		     "vNIC MAC addr %02x:%02x:%02x:%02x:%02x:%02x "
+		     "vNIC MAC addr %pM "
 		     "wq/wq_copy/rq %d/%d/%d\n",
-		     fnic->mac_addr[0], fnic->mac_addr[1], fnic->mac_addr[2],
-		     fnic->mac_addr[3], fnic->mac_addr[4], fnic->mac_addr[5],
+		     fnic->ctlr.ctl_src_addr,
 		     c->wq_enet_desc_count, c->wq_copy_desc_count,
 		     c->rq_desc_count);
 	shost_printk(KERN_INFO, fnic->lport->host,
diff --git a/drivers/scsi/fnic/fnic_res.h b/drivers/scsi/fnic/fnic_res.h
index b6f3102..ef8aaf2 100644
--- a/drivers/scsi/fnic/fnic_res.h
+++ b/drivers/scsi/fnic/fnic_res.h
@@ -51,6 +51,31 @@
 	vnic_wq_post(wq, os_buf, dma_addr, len, sop, eop);
 }
 
+static inline void fnic_queue_wq_eth_desc(struct vnic_wq *wq,
+				      void *os_buf, dma_addr_t dma_addr,
+				      unsigned int len,
+				      int vlan_tag_insert,
+				      unsigned int vlan_tag,
+				      int cq_entry)
+{
+	struct wq_enet_desc *desc = vnic_wq_next_desc(wq);
+
+	wq_enet_desc_enc(desc,
+			 (u64)dma_addr | VNIC_PADDR_TARGET,
+			 (u16)len,
+			 0, /* mss_or_csum_offset */
+			 0, /* fc_eof */
+			 0, /* offload_mode */
+			 1, /* eop */
+			 (u8)cq_entry,
+			 0, /* fcoe_encap */
+			 (u8)vlan_tag_insert,
+			 (u16)vlan_tag,
+			 0 /* loopback */);
+
+	vnic_wq_post(wq, os_buf, dma_addr, len, 1, 1);
+}
+
 static inline void fnic_queue_wq_copy_desc_icmnd_16(struct vnic_wq_copy *wq,
 						    u32 req_id,
 						    u32 lunmap_id, u8 spl_flags,
@@ -58,6 +83,7 @@
 						    u64 sgl_addr, u64 sns_addr,
 						    u8 crn, u8 pri_ta,
 						    u8 flags, u8 *scsi_cdb,
+						    u8 cdb_len,
 						    u32 data_len, u8 *lun,
 						    u32 d_id, u16 mss,
 						    u32 ratov, u32 edtov)
@@ -82,7 +108,8 @@
 	desc->u.icmnd_16.pri_ta = pri_ta; 	/* SCSI Pri & Task attribute */
 	desc->u.icmnd_16._resvd1 = 0;           /* reserved: should be 0 */
 	desc->u.icmnd_16.flags = flags;         /* command flags */
-	memcpy(desc->u.icmnd_16.scsi_cdb, scsi_cdb, CDB_16);    /* SCSI CDB */
+	memset(desc->u.icmnd_16.scsi_cdb, 0, CDB_16);
+	memcpy(desc->u.icmnd_16.scsi_cdb, scsi_cdb, cdb_len);    /* SCSI CDB */
 	desc->u.icmnd_16.data_len = data_len;   /* length of data expected */
 	memcpy(desc->u.icmnd_16.lun, lun, LUN_ADDRESS);  /* LUN address */
 	desc->u.icmnd_16._resvd2 = 0;          	/* reserved */
@@ -132,12 +159,37 @@
 	desc->hdr.tag.u.req_id = req_id;      /* id for this request */
 
 	desc->u.flogi_reg.format = format;
+	desc->u.flogi_reg._resvd = 0;
 	hton24(desc->u.flogi_reg.s_id, s_id);
 	memcpy(desc->u.flogi_reg.gateway_mac, gw_mac, ETH_ALEN);
 
 	vnic_wq_copy_post(wq);
 }
 
+static inline void fnic_queue_wq_copy_desc_fip_reg(struct vnic_wq_copy *wq,
+						   u32 req_id, u32 s_id,
+						   u8 *fcf_mac, u8 *ha_mac,
+						   u32 r_a_tov, u32 e_d_tov)
+{
+	struct fcpio_host_req *desc = vnic_wq_copy_next_desc(wq);
+
+	desc->hdr.type = FCPIO_FLOGI_FIP_REG; /* enum fcpio_type */
+	desc->hdr.status = 0;                 /* header status entry */
+	desc->hdr._resvd = 0;                 /* reserved */
+	desc->hdr.tag.u.req_id = req_id;      /* id for this request */
+
+	desc->u.flogi_fip_reg._resvd0 = 0;
+	hton24(desc->u.flogi_fip_reg.s_id, s_id);
+	memcpy(desc->u.flogi_fip_reg.fcf_mac, fcf_mac, ETH_ALEN);
+	desc->u.flogi_fip_reg._resvd1 = 0;
+	desc->u.flogi_fip_reg.r_a_tov = r_a_tov;
+	desc->u.flogi_fip_reg.e_d_tov = e_d_tov;
+	memcpy(desc->u.flogi_fip_reg.ha_mac, ha_mac, ETH_ALEN);
+	desc->u.flogi_fip_reg._resvd2 = 0;
+
+	vnic_wq_copy_post(wq);
+}
+
 static inline void fnic_queue_wq_copy_desc_fw_reset(struct vnic_wq_copy *wq,
 						    u32 req_id)
 {
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
index bfc9969..65a39b0 100644
--- a/drivers/scsi/fnic/fnic_scsi.c
+++ b/drivers/scsi/fnic/fnic_scsi.c
@@ -174,6 +174,9 @@
 	int ret = 0;
 	unsigned long flags;
 
+	skb_queue_purge(&fnic->frame_queue);
+	skb_queue_purge(&fnic->tx_queue);
+
 	spin_lock_irqsave(&fnic->wq_copy_lock[0], flags);
 
 	if (vnic_wq_copy_desc_avail(wq) <= fnic->wq_copy_desc_low[0])
@@ -200,9 +203,11 @@
  * fnic_flogi_reg_handler
  * Routine to send flogi register msg to fw
  */
-int fnic_flogi_reg_handler(struct fnic *fnic)
+int fnic_flogi_reg_handler(struct fnic *fnic, u32 fc_id)
 {
 	struct vnic_wq_copy *wq = &fnic->wq_copy[0];
+	enum fcpio_flogi_reg_format_type format;
+	struct fc_lport *lp = fnic->lport;
 	u8 gw_mac[ETH_ALEN];
 	int ret = 0;
 	unsigned long flags;
@@ -217,23 +222,32 @@
 		goto flogi_reg_ioreq_end;
 	}
 
-	if (fnic->fcoui_mode)
+	if (fnic->ctlr.map_dest) {
 		memset(gw_mac, 0xff, ETH_ALEN);
-	else
-		memcpy(gw_mac, fnic->dest_addr, ETH_ALEN);
+		format = FCPIO_FLOGI_REG_DEF_DEST;
+	} else {
+		memcpy(gw_mac, fnic->ctlr.dest_addr, ETH_ALEN);
+		format = FCPIO_FLOGI_REG_GW_DEST;
+	}
 
-	fnic_queue_wq_copy_desc_flogi_reg(wq, SCSI_NO_TAG,
-					  FCPIO_FLOGI_REG_GW_DEST,
-					  fnic->s_id,
-					  gw_mac);
+	if ((fnic->config.flags & VFCF_FIP_CAPABLE) && !fnic->ctlr.map_dest) {
+		fnic_queue_wq_copy_desc_fip_reg(wq, SCSI_NO_TAG,
+						fc_id, gw_mac,
+						fnic->data_src_addr,
+						lp->r_a_tov, lp->e_d_tov);
+		FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
+			      "FLOGI FIP reg issued fcid %x src %pM dest %pM\n",
+			      fc_id, fnic->data_src_addr, gw_mac);
+	} else {
+		fnic_queue_wq_copy_desc_flogi_reg(wq, SCSI_NO_TAG,
+						  format, fc_id, gw_mac);
+		FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
+			      "FLOGI reg issued fcid %x map %d dest %pM\n",
+			      fc_id, fnic->ctlr.map_dest, gw_mac);
+	}
 
 flogi_reg_ioreq_end:
 	spin_unlock_irqrestore(&fnic->wq_copy_lock[0], flags);
-
-	if (!ret)
-		FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
-			      "flog reg issued\n");
-
 	return ret;
 }
 
@@ -319,7 +333,8 @@
 					 0, /* scsi cmd ref, always 0 */
 					 pri_tag, /* scsi pri and tag */
 					 flags,	/* command flags */
-					 sc->cmnd, scsi_bufflen(sc),
+					 sc->cmnd, sc->cmd_len,
+					 scsi_bufflen(sc),
 					 fc_lun.scsi_lun, io_req->port_id,
 					 rport->maxframe_size, rp->r_a_tov,
 					 rp->e_d_tov);
@@ -452,7 +467,6 @@
 	u8 hdr_status;
 	struct fcpio_tag tag;
 	int ret = 0;
-	struct fc_frame *flogi;
 	unsigned long flags;
 
 	fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag);
@@ -462,9 +476,6 @@
 
 	spin_lock_irqsave(&fnic->fnic_lock, flags);
 
-	flogi = fnic->flogi;
-	fnic->flogi = NULL;
-
 	/* fnic should be in FC_TRANS_ETH_MODE */
 	if (fnic->state == FNIC_IN_FC_TRANS_ETH_MODE) {
 		/* Check status of reset completion */
@@ -505,17 +516,14 @@
 	 * free the flogi frame. Else, send it out
 	 */
 	if (fnic->remove_wait || ret) {
-		fnic->flogi_oxid = FC_XID_UNKNOWN;
 		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
-		if (flogi)
-			dev_kfree_skb_irq(fp_skb(flogi));
+		skb_queue_purge(&fnic->tx_queue);
 		goto reset_cmpl_handler_end;
 	}
 
 	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 
-	if (flogi)
-		ret = fnic_send_frame(fnic, flogi);
+	fnic_flush_tx(fnic);
 
  reset_cmpl_handler_end:
 	return ret;
@@ -532,18 +540,13 @@
 	u8 hdr_status;
 	struct fcpio_tag tag;
 	int ret = 0;
-	struct fc_frame *flogi_resp = NULL;
 	unsigned long flags;
-	struct sk_buff *skb;
 
 	fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag);
 
 	/* Update fnic state based on status of flogi reg completion */
 	spin_lock_irqsave(&fnic->fnic_lock, flags);
 
-	flogi_resp = fnic->flogi_resp;
-	fnic->flogi_resp = NULL;
-
 	if (fnic->state == FNIC_IN_ETH_TRANS_FC_MODE) {
 
 		/* Check flogi registration completion status */
@@ -567,25 +570,17 @@
 		ret = -1;
 	}
 
-	/* Successful flogi reg cmpl, pass frame to LibFC */
-	if (!ret && flogi_resp) {
+	if (!ret) {
 		if (fnic->stop_rx_link_events) {
 			spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 			goto reg_cmpl_handler_end;
 		}
-		skb = (struct sk_buff *)flogi_resp;
-		/* Use fr_flags to indicate whether flogi resp or not */
-		fr_flags(flogi_resp) = 1;
-		fr_dev(flogi_resp) = fnic->lport;
 		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 
-		skb_queue_tail(&fnic->frame_queue, skb);
+		fnic_flush_tx(fnic);
 		queue_work(fnic_event_queue, &fnic->frame_work);
-
 	} else {
 		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
-		if (flogi_resp)
-			dev_kfree_skb_irq(fp_skb(flogi_resp));
 	}
 
 reg_cmpl_handler_end:
@@ -907,6 +902,7 @@
 		break;
 
 	case FCPIO_FLOGI_REG_CMPL: /* fw completed flogi_reg */
+	case FCPIO_FLOGI_FIP_REG_CMPL: /* fw completed flogi_fip_reg */
 		ret = fnic_fcpio_flogi_reg_cmpl_handler(fnic, desc);
 		break;
 
@@ -1224,22 +1220,6 @@
 
 }
 
-static void fnic_block_error_handler(struct scsi_cmnd *sc)
-{
-	struct Scsi_Host *shost = sc->device->host;
-	struct fc_rport *rport = starget_to_rport(scsi_target(sc->device));
-	unsigned long flags;
-
-	spin_lock_irqsave(shost->host_lock, flags);
-	while (rport->port_state == FC_PORTSTATE_BLOCKED) {
-		spin_unlock_irqrestore(shost->host_lock, flags);
-		msleep(1000);
-		spin_lock_irqsave(shost->host_lock, flags);
-	}
-	spin_unlock_irqrestore(shost->host_lock, flags);
-
-}
-
 /*
  * This function is exported to SCSI for sending abort cmnds.
  * A SCSI IO is represented by a io_req in the driver.
@@ -1259,7 +1239,7 @@
 	DECLARE_COMPLETION_ONSTACK(tm_done);
 
 	/* Wait for rport to unblock */
-	fnic_block_error_handler(sc);
+	fc_block_scsi_eh(sc);
 
 	/* Get local-port, check ready and link up */
 	lp = shost_priv(sc->device->host);
@@ -1541,7 +1521,7 @@
 	DECLARE_COMPLETION_ONSTACK(tm_done);
 
 	/* Wait for rport to unblock */
-	fnic_block_error_handler(sc);
+	fc_block_scsi_eh(sc);
 
 	/* Get local-port, check ready and link up */
 	lp = shost_priv(sc->device->host);
@@ -1762,7 +1742,7 @@
 	fnic->remove_wait = &remove_wait;
 	old_state = fnic->state;
 	fnic->state = FNIC_IN_FC_TRANS_ETH_MODE;
-	vnic_dev_del_addr(fnic->vdev, fnic->data_src_addr);
+	fnic_update_mac_locked(fnic, fnic->ctlr.ctl_src_addr);
 	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 
 	err = fnic_fw_reset_handler(fnic);
@@ -1802,7 +1782,7 @@
 	spin_lock_irqsave(&fnic->fnic_lock, flags);
 	old_state = fnic->state;
 	fnic->state = FNIC_IN_FC_TRANS_ETH_MODE;
-	vnic_dev_del_addr(fnic->vdev, fnic->data_src_addr);
+	fnic_update_mac_locked(fnic, fnic->ctlr.ctl_src_addr);
 	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 
 	if (fnic_fw_reset_handler(fnic)) {
diff --git a/drivers/scsi/fnic/vnic_scsi.h b/drivers/scsi/fnic/vnic_scsi.h
index 46baa52..fbb5536 100644
--- a/drivers/scsi/fnic/vnic_scsi.h
+++ b/drivers/scsi/fnic/vnic_scsi.h
@@ -95,5 +95,6 @@
 
 #define VFCF_FCP_SEQ_LVL_ERR	0x1	/* Enable FCP-2 Error Recovery */
 #define VFCF_PERBI		0x2	/* persistent binding info available */
+#define VFCF_FIP_CAPABLE	0x4	/* firmware can handle FIP */
 
 #endif /* _VNIC_SCSI_H_ */
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index c968cc3..554626e 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -180,14 +180,20 @@
 EXPORT_SYMBOL(scsi_remove_host);
 
 /**
- * scsi_add_host - add a scsi host
+ * scsi_add_host_with_dma - add a scsi host with dma device
  * @shost:	scsi host pointer to add
  * @dev:	a struct device of type scsi class
+ * @dma_dev:	dma device for the host
+ *
+ * Note: You rarely need to worry about this unless you're in a
+ * virtualised host environments, so use the simpler scsi_add_host()
+ * function instead.
  *
  * Return value: 
  * 	0 on success / != 0 for error
  **/
-int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
+int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
+			   struct device *dma_dev)
 {
 	struct scsi_host_template *sht = shost->hostt;
 	int error = -EINVAL;
@@ -207,6 +213,7 @@
 
 	if (!shost->shost_gendev.parent)
 		shost->shost_gendev.parent = dev ? dev : &platform_bus;
+	shost->dma_dev = dma_dev;
 
 	error = device_add(&shost->shost_gendev);
 	if (error)
@@ -262,7 +269,7 @@
  fail:
 	return error;
 }
-EXPORT_SYMBOL(scsi_add_host);
+EXPORT_SYMBOL(scsi_add_host_with_dma);
 
 static void scsi_host_dev_release(struct device *dev)
 {
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c
index a0e7e71..4f05565 100644
--- a/drivers/scsi/hptiop.c
+++ b/drivers/scsi/hptiop.c
@@ -834,7 +834,7 @@
 			atomic_read(&hba->resetting) == 0, 60 * HZ);
 
 	if (atomic_read(&hba->resetting)) {
-		/* IOP is in unkown state, abort reset */
+		/* IOP is in unknown state, abort reset */
 		printk(KERN_ERR "scsi%d: reset failed\n", hba->host->host_no);
 		return -1;
 	}
@@ -861,10 +861,13 @@
 }
 
 static int hptiop_adjust_disk_queue_depth(struct scsi_device *sdev,
-						int queue_depth)
+					  int queue_depth, int reason)
 {
 	struct hptiop_hba *hba = (struct hptiop_hba *)sdev->host->hostdata;
 
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (queue_depth > hba->max_requests)
 		queue_depth = hba->max_requests;
 	scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index bb2c696..87b536a 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -39,6 +39,7 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsi_transport_fc.h>
+#include <scsi/scsi_bsg_fc.h>
 #include "ibmvfc.h"
 
 static unsigned int init_timeout = IBMVFC_INIT_TIMEOUT;
@@ -558,12 +559,11 @@
 /**
  * ibmvfc_init_host - Start host initialization
  * @vhost:		ibmvfc host struct
- * @relogin:	is this a re-login?
  *
  * Return value:
  *	nothing
  **/
-static void ibmvfc_init_host(struct ibmvfc_host *vhost, int relogin)
+static void ibmvfc_init_host(struct ibmvfc_host *vhost)
 {
 	struct ibmvfc_target *tgt;
 
@@ -577,10 +577,8 @@
 	}
 
 	if (!ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING)) {
-		if (!relogin) {
-			memset(vhost->async_crq.msgs, 0, PAGE_SIZE);
-			vhost->async_crq.cur = 0;
-		}
+		memset(vhost->async_crq.msgs, 0, PAGE_SIZE);
+		vhost->async_crq.cur = 0;
 
 		list_for_each_entry(tgt, &vhost->targets, queue)
 			ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
@@ -1678,6 +1676,276 @@
 }
 
 /**
+ * ibmvfc_bsg_timeout_done - Completion handler for cancelling BSG commands
+ * @evt:	struct ibmvfc_event
+ *
+ **/
+static void ibmvfc_bsg_timeout_done(struct ibmvfc_event *evt)
+{
+	struct ibmvfc_host *vhost = evt->vhost;
+
+	ibmvfc_free_event(evt);
+	vhost->aborting_passthru = 0;
+	dev_info(vhost->dev, "Passthru command cancelled\n");
+}
+
+/**
+ * ibmvfc_bsg_timeout - Handle a BSG timeout
+ * @job:	struct fc_bsg_job that timed out
+ *
+ * Returns:
+ *	0 on success / other on failure
+ **/
+static int ibmvfc_bsg_timeout(struct fc_bsg_job *job)
+{
+	struct ibmvfc_host *vhost = shost_priv(job->shost);
+	unsigned long port_id = (unsigned long)job->dd_data;
+	struct ibmvfc_event *evt;
+	struct ibmvfc_tmf *tmf;
+	unsigned long flags;
+	int rc;
+
+	ENTER;
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+	if (vhost->aborting_passthru || vhost->state != IBMVFC_ACTIVE) {
+		__ibmvfc_reset_host(vhost);
+		spin_unlock_irqrestore(vhost->host->host_lock, flags);
+		return 0;
+	}
+
+	vhost->aborting_passthru = 1;
+	evt = ibmvfc_get_event(vhost);
+	ibmvfc_init_event(evt, ibmvfc_bsg_timeout_done, IBMVFC_MAD_FORMAT);
+
+	tmf = &evt->iu.tmf;
+	memset(tmf, 0, sizeof(*tmf));
+	tmf->common.version = 1;
+	tmf->common.opcode = IBMVFC_TMF_MAD;
+	tmf->common.length = sizeof(*tmf);
+	tmf->scsi_id = port_id;
+	tmf->cancel_key = IBMVFC_PASSTHRU_CANCEL_KEY;
+	tmf->my_cancel_key = IBMVFC_INTERNAL_CANCEL_KEY;
+	rc = ibmvfc_send_event(evt, vhost, default_timeout);
+
+	if (rc != 0) {
+		vhost->aborting_passthru = 0;
+		dev_err(vhost->dev, "Failed to send cancel event. rc=%d\n", rc);
+		rc = -EIO;
+	} else
+		dev_info(vhost->dev, "Cancelling passthru command to port id 0x%lx\n",
+			 port_id);
+
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+
+	LEAVE;
+	return rc;
+}
+
+/**
+ * ibmvfc_bsg_plogi - PLOGI into a target to handle a BSG command
+ * @vhost:		struct ibmvfc_host to send command
+ * @port_id:	port ID to send command
+ *
+ * Returns:
+ *	0 on success / other on failure
+ **/
+static int ibmvfc_bsg_plogi(struct ibmvfc_host *vhost, unsigned int port_id)
+{
+	struct ibmvfc_port_login *plogi;
+	struct ibmvfc_target *tgt;
+	struct ibmvfc_event *evt;
+	union ibmvfc_iu rsp_iu;
+	unsigned long flags;
+	int rc = 0, issue_login = 1;
+
+	ENTER;
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+	list_for_each_entry(tgt, &vhost->targets, queue) {
+		if (tgt->scsi_id == port_id) {
+			issue_login = 0;
+			break;
+		}
+	}
+
+	if (!issue_login)
+		goto unlock_out;
+	if (unlikely((rc = ibmvfc_host_chkready(vhost))))
+		goto unlock_out;
+
+	evt = ibmvfc_get_event(vhost);
+	ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT);
+	plogi = &evt->iu.plogi;
+	memset(plogi, 0, sizeof(*plogi));
+	plogi->common.version = 1;
+	plogi->common.opcode = IBMVFC_PORT_LOGIN;
+	plogi->common.length = sizeof(*plogi);
+	plogi->scsi_id = port_id;
+	evt->sync_iu = &rsp_iu;
+	init_completion(&evt->comp);
+
+	rc = ibmvfc_send_event(evt, vhost, default_timeout);
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+
+	if (rc)
+		return -EIO;
+
+	wait_for_completion(&evt->comp);
+
+	if (rsp_iu.plogi.common.status)
+		rc = -EIO;
+
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+	ibmvfc_free_event(evt);
+unlock_out:
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+	LEAVE;
+	return rc;
+}
+
+/**
+ * ibmvfc_bsg_request - Handle a BSG request
+ * @job:	struct fc_bsg_job to be executed
+ *
+ * Returns:
+ *	0 on success / other on failure
+ **/
+static int ibmvfc_bsg_request(struct fc_bsg_job *job)
+{
+	struct ibmvfc_host *vhost = shost_priv(job->shost);
+	struct fc_rport *rport = job->rport;
+	struct ibmvfc_passthru_mad *mad;
+	struct ibmvfc_event *evt;
+	union ibmvfc_iu rsp_iu;
+	unsigned long flags, port_id = -1;
+	unsigned int code = job->request->msgcode;
+	int rc = 0, req_seg, rsp_seg, issue_login = 0;
+	u32 fc_flags, rsp_len;
+
+	ENTER;
+	job->reply->reply_payload_rcv_len = 0;
+	if (rport)
+		port_id = rport->port_id;
+
+	switch (code) {
+	case FC_BSG_HST_ELS_NOLOGIN:
+		port_id = (job->request->rqst_data.h_els.port_id[0] << 16) |
+			(job->request->rqst_data.h_els.port_id[1] << 8) |
+			job->request->rqst_data.h_els.port_id[2];
+	case FC_BSG_RPT_ELS:
+		fc_flags = IBMVFC_FC_ELS;
+		break;
+	case FC_BSG_HST_CT:
+		issue_login = 1;
+		port_id = (job->request->rqst_data.h_ct.port_id[0] << 16) |
+			(job->request->rqst_data.h_ct.port_id[1] << 8) |
+			job->request->rqst_data.h_ct.port_id[2];
+	case FC_BSG_RPT_CT:
+		fc_flags = IBMVFC_FC_CT_IU;
+		break;
+	default:
+		return -ENOTSUPP;
+	};
+
+	if (port_id == -1)
+		return -EINVAL;
+	if (!mutex_trylock(&vhost->passthru_mutex))
+		return -EBUSY;
+
+	job->dd_data = (void *)port_id;
+	req_seg = dma_map_sg(vhost->dev, job->request_payload.sg_list,
+			     job->request_payload.sg_cnt, DMA_TO_DEVICE);
+
+	if (!req_seg) {
+		mutex_unlock(&vhost->passthru_mutex);
+		return -ENOMEM;
+	}
+
+	rsp_seg = dma_map_sg(vhost->dev, job->reply_payload.sg_list,
+			     job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+
+	if (!rsp_seg) {
+		dma_unmap_sg(vhost->dev, job->request_payload.sg_list,
+			     job->request_payload.sg_cnt, DMA_TO_DEVICE);
+		mutex_unlock(&vhost->passthru_mutex);
+		return -ENOMEM;
+	}
+
+	if (req_seg > 1 || rsp_seg > 1) {
+		rc = -EINVAL;
+		goto out;
+	}
+
+	if (issue_login)
+		rc = ibmvfc_bsg_plogi(vhost, port_id);
+
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+
+	if (unlikely(rc || (rport && (rc = fc_remote_port_chkready(rport)))) ||
+	    unlikely((rc = ibmvfc_host_chkready(vhost)))) {
+		spin_unlock_irqrestore(vhost->host->host_lock, flags);
+		goto out;
+	}
+
+	evt = ibmvfc_get_event(vhost);
+	ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT);
+	mad = &evt->iu.passthru;
+
+	memset(mad, 0, sizeof(*mad));
+	mad->common.version = 1;
+	mad->common.opcode = IBMVFC_PASSTHRU;
+	mad->common.length = sizeof(*mad) - sizeof(mad->fc_iu) - sizeof(mad->iu);
+
+	mad->cmd_ioba.va = (u64)evt->crq.ioba +
+		offsetof(struct ibmvfc_passthru_mad, iu);
+	mad->cmd_ioba.len = sizeof(mad->iu);
+
+	mad->iu.cmd_len = job->request_payload.payload_len;
+	mad->iu.rsp_len = job->reply_payload.payload_len;
+	mad->iu.flags = fc_flags;
+	mad->iu.cancel_key = IBMVFC_PASSTHRU_CANCEL_KEY;
+
+	mad->iu.cmd.va = sg_dma_address(job->request_payload.sg_list);
+	mad->iu.cmd.len = sg_dma_len(job->request_payload.sg_list);
+	mad->iu.rsp.va = sg_dma_address(job->reply_payload.sg_list);
+	mad->iu.rsp.len = sg_dma_len(job->reply_payload.sg_list);
+	mad->iu.scsi_id = port_id;
+	mad->iu.tag = (u64)evt;
+	rsp_len = mad->iu.rsp.len;
+
+	evt->sync_iu = &rsp_iu;
+	init_completion(&evt->comp);
+	rc = ibmvfc_send_event(evt, vhost, 0);
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+
+	if (rc) {
+		rc = -EIO;
+		goto out;
+	}
+
+	wait_for_completion(&evt->comp);
+
+	if (rsp_iu.passthru.common.status)
+		rc = -EIO;
+	else
+		job->reply->reply_payload_rcv_len = rsp_len;
+
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+	ibmvfc_free_event(evt);
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+	job->reply->result = rc;
+	job->job_done(job);
+	rc = 0;
+out:
+	dma_unmap_sg(vhost->dev, job->request_payload.sg_list,
+		     job->request_payload.sg_cnt, DMA_TO_DEVICE);
+	dma_unmap_sg(vhost->dev, job->reply_payload.sg_list,
+		     job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+	mutex_unlock(&vhost->passthru_mutex);
+	LEAVE;
+	return rc;
+}
+
+/**
  * ibmvfc_reset_device - Reset the device with the specified reset type
  * @sdev:	scsi device to reset
  * @type:	reset type
@@ -1731,7 +1999,10 @@
 	sdev_printk(KERN_INFO, sdev, "Resetting %s\n", desc);
 	wait_for_completion(&evt->comp);
 
-	if (rsp_iu.cmd.status) {
+	if (rsp_iu.cmd.status)
+		rsp_code = ibmvfc_get_err_result(&rsp_iu.cmd);
+
+	if (rsp_code) {
 		if (fc_rsp->flags & FCP_RSP_LEN_VALID)
 			rsp_code = fc_rsp->data.info.rsp_code;
 
@@ -1820,7 +2091,10 @@
 	sdev_printk(KERN_INFO, sdev, "Aborting outstanding commands\n");
 	wait_for_completion(&evt->comp);
 
-	if (rsp_iu.cmd.status) {
+	if (rsp_iu.cmd.status)
+		rsp_code = ibmvfc_get_err_result(&rsp_iu.cmd);
+
+	if (rsp_code) {
 		if (fc_rsp->flags & FCP_RSP_LEN_VALID)
 			rsp_code = fc_rsp->data.info.rsp_code;
 
@@ -2061,12 +2335,24 @@
 }
 
 /**
- * ibmvfc_dev_cancel_all - Device iterated cancel all function
+ * ibmvfc_dev_cancel_all_abts - Device iterated cancel all function
  * @sdev:	scsi device struct
  * @data:	return code
  *
  **/
-static void ibmvfc_dev_cancel_all(struct scsi_device *sdev, void *data)
+static void ibmvfc_dev_cancel_all_abts(struct scsi_device *sdev, void *data)
+{
+	unsigned long *rc = data;
+	*rc |= ibmvfc_cancel_all(sdev, IBMVFC_TMF_ABORT_TASK_SET);
+}
+
+/**
+ * ibmvfc_dev_cancel_all_reset - Device iterated cancel all function
+ * @sdev:	scsi device struct
+ * @data:	return code
+ *
+ **/
+static void ibmvfc_dev_cancel_all_reset(struct scsi_device *sdev, void *data)
 {
 	unsigned long *rc = data;
 	*rc |= ibmvfc_cancel_all(sdev, IBMVFC_TMF_TGT_RESET);
@@ -2102,7 +2388,7 @@
 
 	ENTER;
 	ibmvfc_wait_while_resetting(vhost);
-	starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all);
+	starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all_reset);
 	reset_rc = ibmvfc_reset_device(sdev, IBMVFC_TARGET_RESET, "target");
 
 	if (!cancel_rc && !reset_rc)
@@ -2144,7 +2430,7 @@
 	int rc = FAILED;
 
 	ENTER;
-	starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all);
+	starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all_abts);
 	starget_for_each_device(starget, &abort_rc, ibmvfc_dev_abort_all);
 
 	if (!cancel_rc && !abort_rc)
@@ -2297,13 +2583,13 @@
 			/* Send back a response */
 			rc = ibmvfc_send_crq_init_complete(vhost);
 			if (rc == 0)
-				ibmvfc_init_host(vhost, 0);
+				ibmvfc_init_host(vhost);
 			else
 				dev_err(vhost->dev, "Unable to send init rsp. rc=%ld\n", rc);
 			break;
 		case IBMVFC_CRQ_INIT_COMPLETE:
 			dev_info(vhost->dev, "Partner initialization complete\n");
-			ibmvfc_init_host(vhost, 0);
+			ibmvfc_init_host(vhost);
 			break;
 		default:
 			dev_err(vhost->dev, "Unknown crq message type: %d\n", crq->format);
@@ -2478,12 +2764,17 @@
  * ibmvfc_change_queue_depth - Change the device's queue depth
  * @sdev:	scsi device struct
  * @qdepth:	depth to set
+ * @reason:	calling context
  *
  * Return value:
  * 	actual depth set
  **/
-static int ibmvfc_change_queue_depth(struct scsi_device *sdev, int qdepth)
+static int ibmvfc_change_queue_depth(struct scsi_device *sdev, int qdepth,
+				     int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (qdepth > IBMVFC_MAX_CMDS_PER_LUN)
 		qdepth = IBMVFC_MAX_CMDS_PER_LUN;
 
@@ -3725,7 +4016,7 @@
 	case IBMVFC_MAD_SUCCESS:
 		if (list_empty(&vhost->sent) &&
 		    vhost->action == IBMVFC_HOST_ACTION_LOGO_WAIT) {
-			ibmvfc_init_host(vhost, 0);
+			ibmvfc_init_host(vhost);
 			return;
 		}
 		break;
@@ -3903,6 +4194,8 @@
 			rport->supported_classes |= FC_COS_CLASS2;
 		if (tgt->service_parms.class3_parms[0] & 0x80000000)
 			rport->supported_classes |= FC_COS_CLASS3;
+		if (rport->rqst_q)
+			blk_queue_max_hw_segments(rport->rqst_q, 1);
 	} else
 		tgt_dbg(tgt, "rport add failed\n");
 	spin_unlock_irqrestore(vhost->host->host_lock, flags);
@@ -4342,6 +4635,7 @@
 	init_waitqueue_head(&vhost->work_wait_q);
 	init_waitqueue_head(&vhost->init_wait_q);
 	INIT_WORK(&vhost->rport_add_work_q, ibmvfc_rport_add_thread);
+	mutex_init(&vhost->passthru_mutex);
 
 	if ((rc = ibmvfc_alloc_mem(vhost)))
 		goto free_scsi_host;
@@ -4374,6 +4668,8 @@
 		goto remove_shost;
 	}
 
+	if (shost_to_fc_host(shost)->rqst_q)
+		blk_queue_max_hw_segments(shost_to_fc_host(shost)->rqst_q, 1);
 	dev_set_drvdata(dev, vhost);
 	spin_lock(&ibmvfc_driver_lock);
 	list_add_tail(&vhost->queue, &ibmvfc_head);
@@ -4414,7 +4710,11 @@
 
 	ENTER;
 	ibmvfc_remove_trace_file(&vhost->host->shost_dev.kobj, &ibmvfc_trace_attr);
+
+	spin_lock_irqsave(vhost->host->host_lock, flags);
 	ibmvfc_link_down(vhost, IBMVFC_HOST_OFFLINE);
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+
 	ibmvfc_wait_while_resetting(vhost);
 	ibmvfc_release_crq_queue(vhost);
 	kthread_stop(vhost->work_thread);
@@ -4498,6 +4798,9 @@
 
 	.get_starget_port_id = ibmvfc_get_starget_port_id,
 	.show_starget_port_id = 1,
+
+	.bsg_request = ibmvfc_bsg_request,
+	.bsg_timeout = ibmvfc_bsg_timeout,
 };
 
 /**
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h
index 007fa1c9..d25106a 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.h
+++ b/drivers/scsi/ibmvscsi/ibmvfc.h
@@ -29,8 +29,8 @@
 #include "viosrp.h"
 
 #define IBMVFC_NAME	"ibmvfc"
-#define IBMVFC_DRIVER_VERSION		"1.0.6"
-#define IBMVFC_DRIVER_DATE		"(May 28, 2009)"
+#define IBMVFC_DRIVER_VERSION		"1.0.7"
+#define IBMVFC_DRIVER_DATE		"(October 16, 2009)"
 
 #define IBMVFC_DEFAULT_TIMEOUT	60
 #define IBMVFC_ADISC_CANCEL_TIMEOUT	45
@@ -58,9 +58,10 @@
  * 1 for ERP
  * 1 for initialization
  * 1 for NPIV Logout
+ * 2 for BSG passthru
  * 2 for each discovery thread
  */
-#define IBMVFC_NUM_INTERNAL_REQ	(1 + 1 + 1 + (disc_threads * 2))
+#define IBMVFC_NUM_INTERNAL_REQ	(1 + 1 + 1 + 2 + (disc_threads * 2))
 
 #define IBMVFC_MAD_SUCCESS		0x00
 #define IBMVFC_MAD_NOT_SUPPORTED	0xF1
@@ -466,7 +467,10 @@
 	u16 error;
 	u32 flags;
 #define IBMVFC_FC_ELS		0x01
+#define IBMVFC_FC_CT_IU		0x02
 	u32 cancel_key;
+#define IBMVFC_PASSTHRU_CANCEL_KEY	0x80000000
+#define IBMVFC_INTERNAL_CANCEL_KEY	0x80000001
 	u32 reserved;
 	struct srp_direct_buf cmd;
 	struct srp_direct_buf rsp;
@@ -693,6 +697,7 @@
 	int disc_buf_sz;
 	int log_level;
 	struct ibmvfc_discover_targets_buf *disc_buf;
+	struct mutex passthru_mutex;
 	int task_set;
 	int init_retries;
 	int discovery_threads;
@@ -702,6 +707,7 @@
 	int delay_init;
 	int scan_complete;
 	int logged_in;
+	int aborting_passthru;
 	int events_to_log;
 #define IBMVFC_AE_LINKUP	0x0001
 #define IBMVFC_AE_LINKDOWN	0x0002
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index d9b0e9d..e475b79 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -1637,12 +1637,17 @@
  * ibmvscsi_change_queue_depth - Change the device's queue depth
  * @sdev:	scsi device struct
  * @qdepth:	depth to set
+ * @reason:	calling context
  *
  * Return value:
  * 	actual depth set
  **/
-static int ibmvscsi_change_queue_depth(struct scsi_device *sdev, int qdepth)
+static int ibmvscsi_change_queue_depth(struct scsi_device *sdev, int qdepth,
+				       int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (qdepth > IBMVSCSI_MAX_CMDS_PER_LUN)
 		qdepth = IBMVSCSI_MAX_CMDS_PER_LUN;
 
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 76d294f..206c2fa 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -3367,16 +3367,21 @@
  * ipr_change_queue_depth - Change the device's queue depth
  * @sdev:	scsi device struct
  * @qdepth:	depth to set
+ * @reason:	calling context
  *
  * Return value:
  * 	actual depth set
  **/
-static int ipr_change_queue_depth(struct scsi_device *sdev, int qdepth)
+static int ipr_change_queue_depth(struct scsi_device *sdev, int qdepth,
+				  int reason)
 {
 	struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata;
 	struct ipr_resource_entry *res;
 	unsigned long lock_flags = 0;
 
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
 	res = (struct ipr_resource_entry *)sdev->hostdata;
 
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index edc49ca..517da3f 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -903,7 +903,7 @@
 				  ISCSI_USERNAME | ISCSI_PASSWORD |
 				  ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
 				  ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
-				  ISCSI_LU_RESET_TMO |
+				  ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO |
 				  ISCSI_PING_TMO | ISCSI_RECV_TMO |
 				  ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
 	.host_param_mask	= ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS |
diff --git a/drivers/scsi/libfc/Makefile b/drivers/scsi/libfc/Makefile
index 55f982d..4bb23ac 100644
--- a/drivers/scsi/libfc/Makefile
+++ b/drivers/scsi/libfc/Makefile
@@ -3,10 +3,12 @@
 obj-$(CONFIG_LIBFC) += libfc.o
 
 libfc-objs := \
+	fc_libfc.o \
 	fc_disc.o \
 	fc_exch.o \
 	fc_elsct.o \
 	fc_frame.o \
 	fc_lport.o \
 	fc_rport.o \
-	fc_fcp.o
+	fc_fcp.o \
+	fc_npiv.o
diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c
index c48799e..9b0a519 100644
--- a/drivers/scsi/libfc/fc_disc.c
+++ b/drivers/scsi/libfc/fc_disc.c
@@ -40,6 +40,8 @@
 
 #include <scsi/libfc.h>
 
+#include "fc_libfc.h"
+
 #define FC_DISC_RETRY_LIMIT	3	/* max retries */
 #define FC_DISC_RETRY_DELAY	500UL	/* (msecs) delay */
 
@@ -51,8 +53,8 @@
 static void fc_disc_restart(struct fc_disc *);
 
 /**
- * fc_disc_stop_rports() - delete all the remote ports associated with the lport
- * @disc: The discovery job to stop rports on
+ * fc_disc_stop_rports() - Delete all the remote ports associated with the lport
+ * @disc: The discovery job to stop remote ports on
  *
  * Locking Note: This function expects that the lport mutex is locked before
  * calling it.
@@ -72,9 +74,9 @@
 
 /**
  * fc_disc_recv_rscn_req() - Handle Registered State Change Notification (RSCN)
- * @sp: Current sequence of the RSCN exchange
- * @fp: RSCN Frame
- * @lport: Fibre Channel host port instance
+ * @sp:	   The sequence of the RSCN exchange
+ * @fp:	   The RSCN frame
+ * @lport: The local port that the request will be sent on
  *
  * Locking Note: This function expects that the disc_mutex is locked
  *		 before it is called.
@@ -183,9 +185,9 @@
 
 /**
  * fc_disc_recv_req() - Handle incoming requests
- * @sp: Current sequence of the request exchange
- * @fp: The frame
- * @lport: The FC local port
+ * @sp:	   The sequence of the request exchange
+ * @fp:	   The request frame
+ * @lport: The local port receiving the request
  *
  * Locking Note: This function is called from the EM and will lock
  *		 the disc_mutex before calling the handler for the
@@ -213,7 +215,7 @@
 
 /**
  * fc_disc_restart() - Restart discovery
- * @lport: FC discovery context
+ * @disc: The discovery object to be restarted
  *
  * Locking Note: This function expects that the disc mutex
  *		 is already locked.
@@ -240,9 +242,9 @@
 }
 
 /**
- * fc_disc_start() - Fibre Channel Target discovery
- * @lport: FC local port
- * @disc_callback: function to be called when discovery is complete
+ * fc_disc_start() - Start discovery on a local port
+ * @lport:	   The local port to have discovery started on
+ * @disc_callback: Callback function to be called when discovery is complete
  */
 static void fc_disc_start(void (*disc_callback)(struct fc_lport *,
 						enum fc_disc_event),
@@ -263,8 +265,8 @@
 
 /**
  * fc_disc_done() - Discovery has been completed
- * @disc: FC discovery context
- * @event: discovery completion status
+ * @disc:  The discovery context
+ * @event: The discovery completion status
  *
  * Locking Note: This function expects that the disc mutex is locked before
  * it is called. The discovery callback is then made with the lock released,
@@ -284,8 +286,8 @@
 	}
 
 	/*
-	 * Go through all remote ports.  If they were found in the latest
-	 * discovery, reverify or log them in.  Otherwise, log them out.
+	 * Go through all remote ports.	 If they were found in the latest
+	 * discovery, reverify or log them in.	Otherwise, log them out.
 	 * Skip ports which were never discovered.  These are the dNS port
 	 * and ports which were created by PLOGI.
 	 */
@@ -305,8 +307,8 @@
 
 /**
  * fc_disc_error() - Handle error on dNS request
- * @disc: FC discovery context
- * @fp: The frame pointer
+ * @disc: The discovery context
+ * @fp:	  The error code encoded as a frame pointer
  */
 static void fc_disc_error(struct fc_disc *disc, struct fc_frame *fp)
 {
@@ -342,7 +344,7 @@
 
 /**
  * fc_disc_gpn_ft_req() - Send Get Port Names by FC-4 type (GPN_FT) request
- * @lport: FC discovery context
+ * @lport: The discovery context
  *
  * Locking Note: This function expects that the disc_mutex is locked
  *		 before it is called.
@@ -368,17 +370,17 @@
 	if (lport->tt.elsct_send(lport, 0, fp,
 				 FC_NS_GPN_FT,
 				 fc_disc_gpn_ft_resp,
-				 disc, lport->e_d_tov))
+				 disc, 3 * lport->r_a_tov))
 		return;
 err:
-	fc_disc_error(disc, fp);
+	fc_disc_error(disc, NULL);
 }
 
 /**
  * fc_disc_gpn_ft_parse() - Parse the body of the dNS GPN_FT response.
- * @lport: Fibre Channel host port instance
- * @buf: GPN_FT response buffer
- * @len: size of response buffer
+ * @lport: The local port the GPN_FT was received on
+ * @buf:   The GPN_FT response buffer
+ * @len:   The size of response buffer
  *
  * Goes through the list of IDs and names resulting from a request.
  */
@@ -477,10 +479,8 @@
 }
 
 /**
- * fc_disc_timeout() - Retry handler for the disc component
- * @work: Structure holding disc obj that needs retry discovery
- *
- * Handle retry of memory allocation for remote ports.
+ * fc_disc_timeout() - Handler for discovery timeouts
+ * @work: Structure holding discovery context that needs to retry discovery
  */
 static void fc_disc_timeout(struct work_struct *work)
 {
@@ -494,9 +494,9 @@
 
 /**
  * fc_disc_gpn_ft_resp() - Handle a response frame from Get Port Names (GPN_FT)
- * @sp: Current sequence of GPN_FT exchange
- * @fp: response frame
- * @lp_arg: Fibre Channel host port instance
+ * @sp:	    The sequence that the GPN_FT response was received on
+ * @fp:	    The GPN_FT response frame
+ * @lp_arg: The discovery context
  *
  * Locking Note: This function is called without disc mutex held, and
  *		 should do all its processing with the mutex held
@@ -567,9 +567,9 @@
 
 /**
  * fc_disc_gpn_id_resp() - Handle a response frame from Get Port Names (GPN_ID)
- * @sp: exchange sequence
- * @fp: response frame
- * @rdata_arg: remote port private data
+ * @sp:	       The sequence the GPN_ID is on
+ * @fp:	       The response frame
+ * @rdata_arg: The remote port that sent the GPN_ID response
  *
  * Locking Note: This function is called without disc mutex held.
  */
@@ -637,7 +637,7 @@
 
 /**
  * fc_disc_gpn_id_req() - Send Get Port Names by ID (GPN_ID) request
- * @lport: local port
+ * @lport: The local port to initiate discovery on
  * @rdata: remote port private data
  *
  * Locking Note: This function expects that the disc_mutex is locked
@@ -654,7 +654,8 @@
 	if (!fp)
 		return -ENOMEM;
 	if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, FC_NS_GPN_ID,
-				 fc_disc_gpn_id_resp, rdata, lport->e_d_tov))
+				  fc_disc_gpn_id_resp, rdata,
+				  3 * lport->r_a_tov))
 		return -ENOMEM;
 	kref_get(&rdata->kref);
 	return 0;
@@ -662,8 +663,8 @@
 
 /**
  * fc_disc_single() - Discover the directory information for a single target
- * @lport: local port
- * @dp: The port to rediscover
+ * @lport: The local port the remote port is associated with
+ * @dp:	   The port to rediscover
  *
  * Locking Note: This function expects that the disc_mutex is locked
  *		 before it is called.
@@ -681,7 +682,7 @@
 
 /**
  * fc_disc_stop() - Stop discovery for a given lport
- * @lport: The lport that discovery should stop for
+ * @lport: The local port that discovery should stop on
  */
 void fc_disc_stop(struct fc_lport *lport)
 {
@@ -695,7 +696,7 @@
 
 /**
  * fc_disc_stop_final() - Stop discovery for a given lport
- * @lport: The lport that discovery should stop for
+ * @lport: The lport that discovery should stop on
  *
  * This function will block until discovery has been
  * completely stopped and all rports have been deleted.
@@ -707,8 +708,8 @@
 }
 
 /**
- * fc_disc_init() - Initialize the discovery block
- * @lport: FC local port
+ * fc_disc_init() - Initialize the discovery layer for a local port
+ * @lport: The local port that needs the discovery layer to be initialized
  */
 int fc_disc_init(struct fc_lport *lport)
 {
diff --git a/drivers/scsi/libfc/fc_elsct.c b/drivers/scsi/libfc/fc_elsct.c
index 5cfa687..53748724 100644
--- a/drivers/scsi/libfc/fc_elsct.c
+++ b/drivers/scsi/libfc/fc_elsct.c
@@ -28,17 +28,22 @@
 #include <scsi/libfc.h>
 #include <scsi/fc_encode.h>
 
-/*
- * fc_elsct_send - sends ELS/CT frame
+/**
+ * fc_elsct_send() - Send an ELS or CT frame
+ * @lport:	The local port to send the frame on
+ * @did:	The destination ID for the frame
+ * @fp:		The frame to be sent
+ * @op:		The operational code
+ * @resp:	The callback routine when the response is received
+ * @arg:	The argument to pass to the response callback routine
+ * @timer_msec: The timeout period for the frame (in msecs)
  */
-static struct fc_seq *fc_elsct_send(struct fc_lport *lport,
-				    u32 did,
-				    struct fc_frame *fp,
-				    unsigned int op,
-				    void (*resp)(struct fc_seq *,
-						 struct fc_frame *fp,
-						 void *arg),
-				    void *arg, u32 timer_msec)
+struct fc_seq *fc_elsct_send(struct fc_lport *lport, u32 did,
+			     struct fc_frame *fp, unsigned int op,
+			     void (*resp)(struct fc_seq *,
+					  struct fc_frame *,
+					  void *),
+			     void *arg, u32 timer_msec)
 {
 	enum fc_rctl r_ctl;
 	enum fc_fh_type fh_type;
@@ -53,15 +58,22 @@
 		did = FC_FID_DIR_SERV;
 	}
 
-	if (rc)
+	if (rc) {
+		fc_frame_free(fp);
 		return NULL;
+	}
 
 	fc_fill_fc_hdr(fp, r_ctl, did, fc_host_port_id(lport->host), fh_type,
 		       FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
 
 	return lport->tt.exch_seq_send(lport, fp, resp, NULL, arg, timer_msec);
 }
+EXPORT_SYMBOL(fc_elsct_send);
 
+/**
+ * fc_elsct_init() - Initialize the ELS/CT layer
+ * @lport: The local port to initialize the ELS/CT layer for
+ */
 int fc_elsct_init(struct fc_lport *lport)
 {
 	if (!lport->tt.elsct_send)
@@ -72,12 +84,15 @@
 EXPORT_SYMBOL(fc_elsct_init);
 
 /**
- * fc_els_resp_type() - return string describing ELS response for debug.
- * @fp: frame pointer with possible error code.
+ * fc_els_resp_type() - Return a string describing the ELS response
+ * @fp: The frame pointer or possible error code
  */
 const char *fc_els_resp_type(struct fc_frame *fp)
 {
 	const char *msg;
+	struct fc_frame_header *fh;
+	struct fc_ct_hdr *ct;
+
 	if (IS_ERR(fp)) {
 		switch (-PTR_ERR(fp)) {
 		case FC_NO_ERR:
@@ -94,15 +109,41 @@
 			break;
 		}
 	} else {
-		switch (fc_frame_payload_op(fp)) {
-		case ELS_LS_ACC:
-			msg = "accept";
+		fh = fc_frame_header_get(fp);
+		switch (fh->fh_type) {
+		case FC_TYPE_ELS:
+			switch (fc_frame_payload_op(fp)) {
+			case ELS_LS_ACC:
+				msg = "accept";
+				break;
+			case ELS_LS_RJT:
+				msg = "reject";
+				break;
+			default:
+				msg = "response unknown ELS";
+				break;
+			}
 			break;
-		case ELS_LS_RJT:
-			msg = "reject";
+		case FC_TYPE_CT:
+			ct = fc_frame_payload_get(fp, sizeof(*ct));
+			if (ct) {
+				switch (ntohs(ct->ct_cmd)) {
+				case FC_FS_ACC:
+					msg = "CT accept";
+					break;
+				case FC_FS_RJT:
+					msg = "CT reject";
+					break;
+				default:
+					msg = "response unknown CT";
+					break;
+				}
+			} else {
+				msg = "short CT response";
+			}
 			break;
 		default:
-			msg = "response unknown ELS";
+			msg = "response not ELS or CT";
 			break;
 		}
 	}
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index c1c1574..19d711c 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -32,10 +32,13 @@
 #include <scsi/libfc.h>
 #include <scsi/fc_encode.h>
 
+#include "fc_libfc.h"
+
 u16	fc_cpu_mask;		/* cpu mask for possible cpus */
 EXPORT_SYMBOL(fc_cpu_mask);
 static u16	fc_cpu_order;	/* 2's power to represent total possible cpus */
-static struct kmem_cache *fc_em_cachep;        /* cache for exchanges */
+static struct kmem_cache *fc_em_cachep;	       /* cache for exchanges */
+struct workqueue_struct *fc_exch_workqueue;
 
 /*
  * Structure and function definitions for managing Fibre Channel Exchanges
@@ -50,35 +53,46 @@
  * fc_seq holds the state for an individual sequence.
  */
 
-/*
- * Per cpu exchange pool
+/**
+ * struct fc_exch_pool - Per cpu exchange pool
+ * @next_index:	  Next possible free exchange index
+ * @total_exches: Total allocated exchanges
+ * @lock:	  Exch pool lock
+ * @ex_list:	  List of exchanges
  *
  * This structure manages per cpu exchanges in array of exchange pointers.
  * This array is allocated followed by struct fc_exch_pool memory for
  * assigned range of exchanges to per cpu pool.
  */
 struct fc_exch_pool {
-	u16		next_index;	/* next possible free exchange index */
-	u16		total_exches;	/* total allocated exchanges */
-	spinlock_t	lock;		/* exch pool lock */
-	struct list_head	ex_list;	/* allocated exchanges list */
+	u16		 next_index;
+	u16		 total_exches;
+	spinlock_t	 lock;
+	struct list_head ex_list;
 };
 
-/*
- * Exchange manager.
+/**
+ * struct fc_exch_mgr - The Exchange Manager (EM).
+ * @class:	    Default class for new sequences
+ * @kref:	    Reference counter
+ * @min_xid:	    Minimum exchange ID
+ * @max_xid:	    Maximum exchange ID
+ * @ep_pool:	    Reserved exchange pointers
+ * @pool_max_index: Max exch array index in exch pool
+ * @pool:	    Per cpu exch pool
+ * @stats:	    Statistics structure
  *
  * This structure is the center for creating exchanges and sequences.
  * It manages the allocation of exchange IDs.
  */
 struct fc_exch_mgr {
-	enum fc_class	class;		/* default class for sequences */
-	struct kref	kref;		/* exchange mgr reference count */
-	u16		min_xid;	/* min exchange ID */
-	u16		max_xid;	/* max exchange ID */
-	struct list_head	ex_list;	/* allocated exchanges list */
-	mempool_t	*ep_pool;	/* reserve ep's */
-	u16		pool_max_index;	/* max exch array index in exch pool */
-	struct fc_exch_pool *pool;	/* per cpu exch pool */
+	enum fc_class	class;
+	struct kref	kref;
+	u16		min_xid;
+	u16		max_xid;
+	mempool_t	*ep_pool;
+	u16		pool_max_index;
+	struct fc_exch_pool *pool;
 
 	/*
 	 * currently exchange mgr stats are updated but not used.
@@ -96,6 +110,18 @@
 };
 #define	fc_seq_exch(sp) container_of(sp, struct fc_exch, seq)
 
+/**
+ * struct fc_exch_mgr_anchor - primary structure for list of EMs
+ * @ema_list: Exchange Manager Anchor list
+ * @mp:	      Exchange Manager associated with this anchor
+ * @match:    Routine to determine if this anchor's EM should be used
+ *
+ * When walking the list of anchors the match routine will be called
+ * for each anchor to determine if that EM should be used. The last
+ * anchor in the list will always match to handle any exchanges not
+ * handled by other EMs. The non-default EMs would be added to the
+ * anchor list by HW that provides FCoE offloads.
+ */
 struct fc_exch_mgr_anchor {
 	struct list_head ema_list;
 	struct fc_exch_mgr *mp;
@@ -108,7 +134,6 @@
 			  enum fc_els_rjt_explan);
 static void fc_exch_els_rec(struct fc_seq *, struct fc_frame *);
 static void fc_exch_els_rrq(struct fc_seq *, struct fc_frame *);
-static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp);
 
 /*
  * Internal implementation notes.
@@ -196,6 +221,15 @@
 
 #define FC_TABLE_SIZE(x)   (sizeof(x) / sizeof(x[0]))
 
+/**
+ * fc_exch_name_lookup() - Lookup name by opcode
+ * @op:	       Opcode to be looked up
+ * @table:     Opcode/name table
+ * @max_index: Index not to be exceeded
+ *
+ * This routine is used to determine a human-readable string identifying
+ * a R_CTL opcode.
+ */
 static inline const char *fc_exch_name_lookup(unsigned int op, char **table,
 					      unsigned int max_index)
 {
@@ -208,25 +242,34 @@
 	return name;
 }
 
+/**
+ * fc_exch_rctl_name() - Wrapper routine for fc_exch_name_lookup()
+ * @op: The opcode to be looked up
+ */
 static const char *fc_exch_rctl_name(unsigned int op)
 {
 	return fc_exch_name_lookup(op, fc_exch_rctl_names,
 				   FC_TABLE_SIZE(fc_exch_rctl_names));
 }
 
-/*
- * Hold an exchange - keep it from being freed.
+/**
+ * fc_exch_hold() - Increment an exchange's reference count
+ * @ep: Echange to be held
  */
-static void fc_exch_hold(struct fc_exch *ep)
+static inline void fc_exch_hold(struct fc_exch *ep)
 {
 	atomic_inc(&ep->ex_refcnt);
 }
 
-/*
- * setup fc hdr by initializing few more FC header fields and sof/eof.
- * Initialized fields by this func:
- *	- fh_ox_id, fh_rx_id, fh_seq_id, fh_seq_cnt
- *	- sof and eof
+/**
+ * fc_exch_setup_hdr() - Initialize a FC header by initializing some fields
+ *			 and determine SOF and EOF.
+ * @ep:	   The exchange to that will use the header
+ * @fp:	   The frame whose header is to be modified
+ * @f_ctl: F_CTL bits that will be used for the frame header
+ *
+ * The fields initialized by this routine are: fh_ox_id, fh_rx_id,
+ * fh_seq_id, fh_seq_cnt and the SOF and EOF.
  */
 static void fc_exch_setup_hdr(struct fc_exch *ep, struct fc_frame *fp,
 			      u32 f_ctl)
@@ -243,7 +286,7 @@
 		if (fc_sof_needs_ack(ep->class))
 			fr_eof(fp) = FC_EOF_N;
 		/*
-		 * Form f_ctl.
+		 * From F_CTL.
 		 * The number of fill bytes to make the length a 4-byte
 		 * multiple is the low order 2-bits of the f_ctl.
 		 * The fill itself will have been cleared by the frame
@@ -273,10 +316,12 @@
 	fh->fh_seq_cnt = htons(ep->seq.cnt);
 }
 
-
-/*
- * Release a reference to an exchange.
- * If the refcnt goes to zero and the exchange is complete, it is freed.
+/**
+ * fc_exch_release() - Decrement an exchange's reference count
+ * @ep: Exchange to be released
+ *
+ * If the reference count reaches zero and the exchange is complete,
+ * it is freed.
  */
 static void fc_exch_release(struct fc_exch *ep)
 {
@@ -291,6 +336,10 @@
 	}
 }
 
+/**
+ * fc_exch_done_locked() - Complete an exchange with the exchange lock held
+ * @ep: The exchange that is complete
+ */
 static int fc_exch_done_locked(struct fc_exch *ep)
 {
 	int rc = 1;
@@ -315,6 +364,15 @@
 	return rc;
 }
 
+/**
+ * fc_exch_ptr_get() - Return an exchange from an exchange pool
+ * @pool:  Exchange Pool to get an exchange from
+ * @index: Index of the exchange within the pool
+ *
+ * Use the index to get an exchange from within an exchange pool. exches
+ * will point to an array of exchange pointers. The index will select
+ * the exchange within the array.
+ */
 static inline struct fc_exch *fc_exch_ptr_get(struct fc_exch_pool *pool,
 					      u16 index)
 {
@@ -322,12 +380,22 @@
 	return exches[index];
 }
 
+/**
+ * fc_exch_ptr_set() - Assign an exchange to a slot in an exchange pool
+ * @pool:  The pool to assign the exchange to
+ * @index: The index in the pool where the exchange will be assigned
+ * @ep:	   The exchange to assign to the pool
+ */
 static inline void fc_exch_ptr_set(struct fc_exch_pool *pool, u16 index,
 				   struct fc_exch *ep)
 {
 	((struct fc_exch **)(pool + 1))[index] = ep;
 }
 
+/**
+ * fc_exch_delete() - Delete an exchange
+ * @ep: The exchange to be deleted
+ */
 static void fc_exch_delete(struct fc_exch *ep)
 {
 	struct fc_exch_pool *pool;
@@ -343,8 +411,14 @@
 	fc_exch_release(ep);	/* drop hold for exch in mp */
 }
 
-/*
- * Internal version of fc_exch_timer_set - used with lock held.
+/**
+ * fc_exch_timer_set_locked() - Start a timer for an exchange w/ the
+ *				the exchange lock held
+ * @ep:		The exchange whose timer will start
+ * @timer_msec: The timeout period
+ *
+ * Used for upper level protocols to time out the exchange.
+ * The timer is cancelled when it fires or when the exchange completes.
  */
 static inline void fc_exch_timer_set_locked(struct fc_exch *ep,
 					    unsigned int timer_msec)
@@ -354,17 +428,15 @@
 
 	FC_EXCH_DBG(ep, "Exchange timer armed\n");
 
-	if (schedule_delayed_work(&ep->timeout_work,
-				  msecs_to_jiffies(timer_msec)))
+	if (queue_delayed_work(fc_exch_workqueue, &ep->timeout_work,
+			       msecs_to_jiffies(timer_msec)))
 		fc_exch_hold(ep);		/* hold for timer */
 }
 
-/*
- * Set timer for an exchange.
- * The time is a minimum delay in milliseconds until the timer fires.
- * Used for upper level protocols to time out the exchange.
- * The timer is cancelled when it fires or when the exchange completes.
- * Returns non-zero if a timer couldn't be allocated.
+/**
+ * fc_exch_timer_set() - Lock the exchange and set the timer
+ * @ep:		The exchange whose timer will start
+ * @timer_msec: The timeout period
  */
 static void fc_exch_timer_set(struct fc_exch *ep, unsigned int timer_msec)
 {
@@ -373,7 +445,115 @@
 	spin_unlock_bh(&ep->ex_lock);
 }
 
-int fc_seq_exch_abort(const struct fc_seq *req_sp, unsigned int timer_msec)
+/**
+ * fc_seq_send() - Send a frame using existing sequence/exchange pair
+ * @lport: The local port that the exchange will be sent on
+ * @sp:	   The sequence to be sent
+ * @fp:	   The frame to be sent on the exchange
+ */
+static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp,
+		       struct fc_frame *fp)
+{
+	struct fc_exch *ep;
+	struct fc_frame_header *fh = fc_frame_header_get(fp);
+	int error;
+	u32 f_ctl;
+
+	ep = fc_seq_exch(sp);
+	WARN_ON((ep->esb_stat & ESB_ST_SEQ_INIT) != ESB_ST_SEQ_INIT);
+
+	f_ctl = ntoh24(fh->fh_f_ctl);
+	fc_exch_setup_hdr(ep, fp, f_ctl);
+
+	/*
+	 * update sequence count if this frame is carrying
+	 * multiple FC frames when sequence offload is enabled
+	 * by LLD.
+	 */
+	if (fr_max_payload(fp))
+		sp->cnt += DIV_ROUND_UP((fr_len(fp) - sizeof(*fh)),
+					fr_max_payload(fp));
+	else
+		sp->cnt++;
+
+	/*
+	 * Send the frame.
+	 */
+	error = lport->tt.frame_send(lport, fp);
+
+	/*
+	 * Update the exchange and sequence flags,
+	 * assuming all frames for the sequence have been sent.
+	 * We can only be called to send once for each sequence.
+	 */
+	spin_lock_bh(&ep->ex_lock);
+	ep->f_ctl = f_ctl & ~FC_FC_FIRST_SEQ;	/* not first seq */
+	if (f_ctl & (FC_FC_END_SEQ | FC_FC_SEQ_INIT))
+		ep->esb_stat &= ~ESB_ST_SEQ_INIT;
+	spin_unlock_bh(&ep->ex_lock);
+	return error;
+}
+
+/**
+ * fc_seq_alloc() - Allocate a sequence for a given exchange
+ * @ep:	    The exchange to allocate a new sequence for
+ * @seq_id: The sequence ID to be used
+ *
+ * We don't support multiple originated sequences on the same exchange.
+ * By implication, any previously originated sequence on this exchange
+ * is complete, and we reallocate the same sequence.
+ */
+static struct fc_seq *fc_seq_alloc(struct fc_exch *ep, u8 seq_id)
+{
+	struct fc_seq *sp;
+
+	sp = &ep->seq;
+	sp->ssb_stat = 0;
+	sp->cnt = 0;
+	sp->id = seq_id;
+	return sp;
+}
+
+/**
+ * fc_seq_start_next_locked() - Allocate a new sequence on the same
+ *				exchange as the supplied sequence
+ * @sp: The sequence/exchange to get a new sequence for
+ */
+static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp)
+{
+	struct fc_exch *ep = fc_seq_exch(sp);
+
+	sp = fc_seq_alloc(ep, ep->seq_id++);
+	FC_EXCH_DBG(ep, "f_ctl %6x seq %2x\n",
+		    ep->f_ctl, sp->id);
+	return sp;
+}
+
+/**
+ * fc_seq_start_next() - Lock the exchange and get a new sequence
+ *			 for a given sequence/exchange pair
+ * @sp: The sequence/exchange to get a new exchange for
+ */
+static struct fc_seq *fc_seq_start_next(struct fc_seq *sp)
+{
+	struct fc_exch *ep = fc_seq_exch(sp);
+
+	spin_lock_bh(&ep->ex_lock);
+	sp = fc_seq_start_next_locked(sp);
+	spin_unlock_bh(&ep->ex_lock);
+
+	return sp;
+}
+
+/**
+ * fc_seq_exch_abort() - Abort an exchange and sequence
+ * @req_sp:	The sequence to be aborted
+ * @timer_msec: The period of time to wait before aborting
+ *
+ * Generally called because of a timeout or an abort from the upper layer.
+ */
+static int fc_seq_exch_abort(const struct fc_seq *req_sp,
+			     unsigned int timer_msec)
 {
 	struct fc_seq *sp;
 	struct fc_exch *ep;
@@ -422,11 +602,10 @@
 		error = -ENOBUFS;
 	return error;
 }
-EXPORT_SYMBOL(fc_seq_exch_abort);
 
-/*
- * Exchange timeout - handle exchange timer expiration.
- * The timer will have been cancelled before this is called.
+/**
+ * fc_exch_timeout() - Handle exchange timer expiration
+ * @work: The work_struct identifying the exchange that timed out
  */
 static void fc_exch_timeout(struct work_struct *work)
 {
@@ -474,28 +653,10 @@
 	fc_exch_release(ep);
 }
 
-/*
- * Allocate a sequence.
- *
- * We don't support multiple originated sequences on the same exchange.
- * By implication, any previously originated sequence on this exchange
- * is complete, and we reallocate the same sequence.
- */
-static struct fc_seq *fc_seq_alloc(struct fc_exch *ep, u8 seq_id)
-{
-	struct fc_seq *sp;
-
-	sp = &ep->seq;
-	sp->ssb_stat = 0;
-	sp->cnt = 0;
-	sp->id = seq_id;
-	return sp;
-}
-
 /**
- * fc_exch_em_alloc() - allocate an exchange from a specified EM.
- * @lport:	ptr to the local port
- * @mp:		ptr to the exchange manager
+ * fc_exch_em_alloc() - Allocate an exchange from a specified EM.
+ * @lport: The local port that the exchange is for
+ * @mp:	   The exchange manager that will allocate the exchange
  *
  * Returns pointer to allocated fc_exch with exch lock held.
  */
@@ -563,16 +724,18 @@
 }
 
 /**
- * fc_exch_alloc() - allocate an exchange.
- * @lport:	ptr to the local port
- * @fp:		ptr to the FC frame
+ * fc_exch_alloc() - Allocate an exchange from an EM on a
+ *		     local port's list of EMs.
+ * @lport: The local port that will own the exchange
+ * @fp:	   The FC frame that the exchange will be for
  *
- * This function walks the list of the exchange manager(EM)
- * anchors to select a EM for new exchange allocation. The
- * EM is selected having either a NULL match function pointer
- * or call to match function returning true.
+ * This function walks the list of exchange manager(EM)
+ * anchors to select an EM for a new exchange allocation. The
+ * EM is selected when a NULL match function pointer is encountered
+ * or when a call to a match function returns true.
  */
-struct fc_exch *fc_exch_alloc(struct fc_lport *lport, struct fc_frame *fp)
+static struct fc_exch *fc_exch_alloc(struct fc_lport *lport,
+				     struct fc_frame *fp)
 {
 	struct fc_exch_mgr_anchor *ema;
 	struct fc_exch *ep;
@@ -586,10 +749,11 @@
 	}
 	return NULL;
 }
-EXPORT_SYMBOL(fc_exch_alloc);
 
-/*
- * Lookup and hold an exchange.
+/**
+ * fc_exch_find() - Lookup and hold an exchange
+ * @mp:	 The exchange manager to lookup the exchange from
+ * @xid: The XID of the exchange to look up
  */
 static struct fc_exch *fc_exch_find(struct fc_exch_mgr *mp, u16 xid)
 {
@@ -609,7 +773,13 @@
 	return ep;
 }
 
-void fc_exch_done(struct fc_seq *sp)
+
+/**
+ * fc_exch_done() - Indicate that an exchange/sequence tuple is complete and
+ *		    the memory allocated for the related objects may be freed.
+ * @sp: The sequence that has completed
+ */
+static void fc_exch_done(struct fc_seq *sp)
 {
 	struct fc_exch *ep = fc_seq_exch(sp);
 	int rc;
@@ -620,10 +790,13 @@
 	if (!rc)
 		fc_exch_delete(ep);
 }
-EXPORT_SYMBOL(fc_exch_done);
 
-/*
- * Allocate a new exchange as responder.
+/**
+ * fc_exch_resp() - Allocate a new exchange for a response frame
+ * @lport: The local port that the exchange was for
+ * @mp:	   The exchange manager to allocate the exchange from
+ * @fp:	   The response frame
+ *
  * Sets the responder ID in the frame header.
  */
 static struct fc_exch *fc_exch_resp(struct fc_lport *lport,
@@ -664,8 +837,13 @@
 	return ep;
 }
 
-/*
- * Find a sequence for receive where the other end is originating the sequence.
+/**
+ * fc_seq_lookup_recip() - Find a sequence where the other end
+ *			   originated the sequence
+ * @lport: The local port that the frame was sent to
+ * @mp:	   The Exchange Manager to lookup the exchange from
+ * @fp:	   The frame associated with the sequence we're looking for
+ *
  * If fc_pf_rjt_reason is FC_RJT_NONE then this function will have a hold
  * on the ep that should be released by the caller.
  */
@@ -771,10 +949,12 @@
 	return reject;
 }
 
-/*
- * Find the sequence for a frame being received.
- * We originated the sequence, so it should be found.
- * We may or may not have originated the exchange.
+/**
+ * fc_seq_lookup_orig() - Find a sequence where this end
+ *			  originated the sequence
+ * @mp:	   The Exchange Manager to lookup the exchange from
+ * @fp:	   The frame associated with the sequence we're looking for
+ *
  * Does not hold the sequence for the caller.
  */
 static struct fc_seq *fc_seq_lookup_orig(struct fc_exch_mgr *mp,
@@ -806,8 +986,12 @@
 	return sp;
 }
 
-/*
- * Set addresses for an exchange.
+/**
+ * fc_exch_set_addr() - Set the source and destination IDs for an exchange
+ * @ep:	     The exchange to set the addresses for
+ * @orig_id: The originator's ID
+ * @resp_id: The responder's ID
+ *
  * Note this must be done before the first sequence of the exchange is sent.
  */
 static void fc_exch_set_addr(struct fc_exch *ep,
@@ -823,76 +1007,15 @@
 	}
 }
 
-static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp)
-{
-	struct fc_exch *ep = fc_seq_exch(sp);
-
-	sp = fc_seq_alloc(ep, ep->seq_id++);
-	FC_EXCH_DBG(ep, "f_ctl %6x seq %2x\n",
-		    ep->f_ctl, sp->id);
-	return sp;
-}
-/*
- * Allocate a new sequence on the same exchange as the supplied sequence.
- * This will never return NULL.
+/**
+ * fc_seq_els_rsp_send() - Send an ELS response using infomation from
+ *			   the existing sequence/exchange.
+ * @sp:	      The sequence/exchange to get information from
+ * @els_cmd:  The ELS command to be sent
+ * @els_data: The ELS data to be sent
  */
-struct fc_seq *fc_seq_start_next(struct fc_seq *sp)
-{
-	struct fc_exch *ep = fc_seq_exch(sp);
-
-	spin_lock_bh(&ep->ex_lock);
-	sp = fc_seq_start_next_locked(sp);
-	spin_unlock_bh(&ep->ex_lock);
-
-	return sp;
-}
-EXPORT_SYMBOL(fc_seq_start_next);
-
-int fc_seq_send(struct fc_lport *lp, struct fc_seq *sp, struct fc_frame *fp)
-{
-	struct fc_exch *ep;
-	struct fc_frame_header *fh = fc_frame_header_get(fp);
-	int error;
-	u32	f_ctl;
-
-	ep = fc_seq_exch(sp);
-	WARN_ON((ep->esb_stat & ESB_ST_SEQ_INIT) != ESB_ST_SEQ_INIT);
-
-	f_ctl = ntoh24(fh->fh_f_ctl);
-	fc_exch_setup_hdr(ep, fp, f_ctl);
-
-	/*
-	 * update sequence count if this frame is carrying
-	 * multiple FC frames when sequence offload is enabled
-	 * by LLD.
-	 */
-	if (fr_max_payload(fp))
-		sp->cnt += DIV_ROUND_UP((fr_len(fp) - sizeof(*fh)),
-					fr_max_payload(fp));
-	else
-		sp->cnt++;
-
-	/*
-	 * Send the frame.
-	 */
-	error = lp->tt.frame_send(lp, fp);
-
-	/*
-	 * Update the exchange and sequence flags,
-	 * assuming all frames for the sequence have been sent.
-	 * We can only be called to send once for each sequence.
-	 */
-	spin_lock_bh(&ep->ex_lock);
-	ep->f_ctl = f_ctl & ~FC_FC_FIRST_SEQ;	/* not first seq */
-	if (f_ctl & (FC_FC_END_SEQ | FC_FC_SEQ_INIT))
-		ep->esb_stat &= ~ESB_ST_SEQ_INIT;
-	spin_unlock_bh(&ep->ex_lock);
-	return error;
-}
-EXPORT_SYMBOL(fc_seq_send);
-
-void fc_seq_els_rsp_send(struct fc_seq *sp, enum fc_els_cmd els_cmd,
-			 struct fc_seq_els_data *els_data)
+static void fc_seq_els_rsp_send(struct fc_seq *sp, enum fc_els_cmd els_cmd,
+				struct fc_seq_els_data *els_data)
 {
 	switch (els_cmd) {
 	case ELS_LS_RJT:
@@ -911,10 +1034,13 @@
 		FC_EXCH_DBG(fc_seq_exch(sp), "Invalid ELS CMD:%x\n", els_cmd);
 	}
 }
-EXPORT_SYMBOL(fc_seq_els_rsp_send);
 
-/*
- * Send a sequence, which is also the last sequence in the exchange.
+/**
+ * fc_seq_send_last() - Send a sequence that is the last in the exchange
+ * @sp:	     The sequence that is to be sent
+ * @fp:	     The frame that will be sent on the sequence
+ * @rctl:    The R_CTL information to be sent
+ * @fh_type: The frame header type
  */
 static void fc_seq_send_last(struct fc_seq *sp, struct fc_frame *fp,
 			     enum fc_rctl rctl, enum fc_fh_type fh_type)
@@ -928,9 +1054,12 @@
 	fc_seq_send(ep->lp, sp, fp);
 }
 
-/*
+/**
+ * fc_seq_send_ack() - Send an acknowledgement that we've received a frame
+ * @sp:	   The sequence to send the ACK on
+ * @rx_fp: The received frame that is being acknoledged
+ *
  * Send ACK_1 (or equiv.) indicating we received something.
- * The frame we're acking is supplied.
  */
 static void fc_seq_send_ack(struct fc_seq *sp, const struct fc_frame *rx_fp)
 {
@@ -938,14 +1067,14 @@
 	struct fc_frame_header *rx_fh;
 	struct fc_frame_header *fh;
 	struct fc_exch *ep = fc_seq_exch(sp);
-	struct fc_lport *lp = ep->lp;
+	struct fc_lport *lport = ep->lp;
 	unsigned int f_ctl;
 
 	/*
 	 * Don't send ACKs for class 3.
 	 */
 	if (fc_sof_needs_ack(fr_sof(rx_fp))) {
-		fp = fc_frame_alloc(lp, 0);
+		fp = fc_frame_alloc(lport, 0);
 		if (!fp)
 			return;
 
@@ -980,12 +1109,16 @@
 		else
 			fr_eof(fp) = FC_EOF_N;
 
-		(void) lp->tt.frame_send(lp, fp);
+		lport->tt.frame_send(lport, fp);
 	}
 }
 
-/*
- * Send BLS Reject.
+/**
+ * fc_exch_send_ba_rjt() - Send BLS Reject
+ * @rx_fp:  The frame being rejected
+ * @reason: The reason the frame is being rejected
+ * @explan: The explaination for the rejection
+ *
  * This is for rejecting BA_ABTS only.
  */
 static void fc_exch_send_ba_rjt(struct fc_frame *rx_fp,
@@ -996,11 +1129,11 @@
 	struct fc_frame_header *rx_fh;
 	struct fc_frame_header *fh;
 	struct fc_ba_rjt *rp;
-	struct fc_lport *lp;
+	struct fc_lport *lport;
 	unsigned int f_ctl;
 
-	lp = fr_dev(rx_fp);
-	fp = fc_frame_alloc(lp, sizeof(*rp));
+	lport = fr_dev(rx_fp);
+	fp = fc_frame_alloc(lport, sizeof(*rp));
 	if (!fp)
 		return;
 	fh = fc_frame_header_get(fp);
@@ -1045,13 +1178,17 @@
 	if (fc_sof_needs_ack(fr_sof(fp)))
 		fr_eof(fp) = FC_EOF_N;
 
-	(void) lp->tt.frame_send(lp, fp);
+	lport->tt.frame_send(lport, fp);
 }
 
-/*
- * Handle an incoming ABTS.  This would be for target mode usually,
- * but could be due to lost FCP transfer ready, confirm or RRQ.
- * We always handle this as an exchange abort, ignoring the parameter.
+/**
+ * fc_exch_recv_abts() - Handle an incoming ABTS
+ * @ep:	   The exchange the abort was on
+ * @rx_fp: The ABTS frame
+ *
+ * This would be for target mode usually, but could be due to lost
+ * FCP transfer ready, confirm or RRQ. We always handle this as an
+ * exchange abort, ignoring the parameter.
  */
 static void fc_exch_recv_abts(struct fc_exch *ep, struct fc_frame *rx_fp)
 {
@@ -1100,10 +1237,14 @@
 	fc_frame_free(rx_fp);
 }
 
-/*
- * Handle receive where the other end is originating the sequence.
+/**
+ * fc_exch_recv_req() - Handler for an incoming request where is other
+ *			end is originating the sequence
+ * @lport: The local port that received the request
+ * @mp:	   The EM that the exchange is on
+ * @fp:	   The request frame
  */
-static void fc_exch_recv_req(struct fc_lport *lp, struct fc_exch_mgr *mp,
+static void fc_exch_recv_req(struct fc_lport *lport, struct fc_exch_mgr *mp,
 			     struct fc_frame *fp)
 {
 	struct fc_frame_header *fh = fc_frame_header_get(fp);
@@ -1114,8 +1255,17 @@
 	u32 f_ctl;
 	enum fc_pf_rjt_reason reject;
 
+	/* We can have the wrong fc_lport at this point with NPIV, which is a
+	 * problem now that we know a new exchange needs to be allocated
+	 */
+	lport = fc_vport_id_lookup(lport, ntoh24(fh->fh_d_id));
+	if (!lport) {
+		fc_frame_free(fp);
+		return;
+	}
+
 	fr_seq(fp) = NULL;
-	reject = fc_seq_lookup_recip(lp, mp, fp);
+	reject = fc_seq_lookup_recip(lport, mp, fp);
 	if (reject == FC_RJT_NONE) {
 		sp = fr_seq(fp);	/* sequence will be held */
 		ep = fc_seq_exch(sp);
@@ -1138,17 +1288,21 @@
 		if (ep->resp)
 			ep->resp(sp, fp, ep->arg);
 		else
-			lp->tt.lport_recv(lp, sp, fp);
+			lport->tt.lport_recv(lport, sp, fp);
 		fc_exch_release(ep);	/* release from lookup */
 	} else {
-		FC_LPORT_DBG(lp, "exch/seq lookup failed: reject %x\n", reject);
+		FC_LPORT_DBG(lport, "exch/seq lookup failed: reject %x\n",
+			     reject);
 		fc_frame_free(fp);
 	}
 }
 
-/*
- * Handle receive where the other end is originating the sequence in
- * response to our exchange.
+/**
+ * fc_exch_recv_seq_resp() - Handler for an incoming response where the other
+ *			     end is the originator of the sequence that is a
+ *			     response to our initial exchange
+ * @mp: The EM that the exchange is on
+ * @fp: The response frame
  */
 static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
 {
@@ -1239,8 +1393,11 @@
 	fc_frame_free(fp);
 }
 
-/*
- * Handle receive for a sequence where other end is responding to our sequence.
+/**
+ * fc_exch_recv_resp() - Handler for a sequence where other end is
+ *			 responding to our sequence
+ * @mp: The EM that the exchange is on
+ * @fp: The response frame
  */
 static void fc_exch_recv_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
 {
@@ -1256,9 +1413,13 @@
 	fc_frame_free(fp);
 }
 
-/*
- * Handle the response to an ABTS for exchange or sequence.
- * This can be BA_ACC or BA_RJT.
+/**
+ * fc_exch_abts_resp() - Handler for a response to an ABT
+ * @ep: The exchange that the frame is on
+ * @fp: The response frame
+ *
+ * This response would be to an ABTS cancelling an exchange or sequence.
+ * The response can be either BA_ACC or BA_RJT
  */
 static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp)
 {
@@ -1333,9 +1494,12 @@
 
 }
 
-/*
- * Receive BLS sequence.
- * This is always a sequence initiated by the remote side.
+/**
+ * fc_exch_recv_bls() - Handler for a BLS sequence
+ * @mp: The EM that the exchange is on
+ * @fp: The request frame
+ *
+ * The BLS frame is always a sequence initiated by the remote side.
  * We may be either the originator or recipient of the exchange.
  */
 static void fc_exch_recv_bls(struct fc_exch_mgr *mp, struct fc_frame *fp)
@@ -1392,8 +1556,10 @@
 		fc_exch_release(ep);	/* release hold taken by fc_exch_find */
 }
 
-/*
- * Accept sequence with LS_ACC.
+/**
+ * fc_seq_ls_acc() - Accept sequence with LS_ACC
+ * @req_sp: The request sequence
+ *
  * If this fails due to allocation or transmit congestion, assume the
  * originator will repeat the sequence.
  */
@@ -1413,8 +1579,12 @@
 	}
 }
 
-/*
- * Reject sequence with ELS LS_RJT.
+/**
+ * fc_seq_ls_rjt() - Reject a sequence with ELS LS_RJT
+ * @req_sp: The request sequence
+ * @reason: The reason the sequence is being rejected
+ * @explan: The explaination for the rejection
+ *
  * If this fails due to allocation or transmit congestion, assume the
  * originator will repeat the sequence.
  */
@@ -1437,6 +1607,10 @@
 	}
 }
 
+/**
+ * fc_exch_reset() - Reset an exchange
+ * @ep: The exchange to be reset
+ */
 static void fc_exch_reset(struct fc_exch *ep)
 {
 	struct fc_seq *sp;
@@ -1446,12 +1620,6 @@
 
 	spin_lock_bh(&ep->ex_lock);
 	ep->state |= FC_EX_RST_CLEANUP;
-	/*
-	 * we really want to call del_timer_sync, but cannot due
-	 * to the lport calling with the lport lock held (some resp
-	 * functions can also grab the lport lock which could cause
-	 * a deadlock).
-	 */
 	if (cancel_delayed_work(&ep->timeout_work))
 		atomic_dec(&ep->ex_refcnt);	/* drop hold for timer */
 	resp = ep->resp;
@@ -1471,16 +1639,16 @@
 }
 
 /**
- * fc_exch_pool_reset() - Resets an per cpu exches pool.
- * @lport:	ptr to the local port
- * @pool:	ptr to the per cpu exches pool
- * @sid:	source FC ID
- * @did:	destination FC ID
+ * fc_exch_pool_reset() - Reset a per cpu exchange pool
+ * @lport: The local port that the exchange pool is on
+ * @pool:  The exchange pool to be reset
+ * @sid:   The source ID
+ * @did:   The destination ID
  *
- * Resets an per cpu exches pool, releasing its all sequences
- * and exchanges. If sid is non-zero, then reset only exchanges
- * we sourced from that FID. If did is non-zero, reset only
- * exchanges destined to that FID.
+ * Resets a per cpu exches pool, releasing all of its sequences
+ * and exchanges. If sid is non-zero then reset only exchanges
+ * we sourced from the local port's FID. If did is non-zero then
+ * only reset exchanges destined for the local port's FID.
  */
 static void fc_exch_pool_reset(struct fc_lport *lport,
 			       struct fc_exch_pool *pool,
@@ -1514,15 +1682,15 @@
 }
 
 /**
- * fc_exch_mgr_reset() - Resets all EMs of a lport
- * @lport:	ptr to the local port
- * @sid:	source FC ID
- * @did:	destination FC ID
+ * fc_exch_mgr_reset() - Reset all EMs of a local port
+ * @lport: The local port whose EMs are to be reset
+ * @sid:   The source ID
+ * @did:   The destination ID
  *
- * Reset all EMs of a lport, releasing its all sequences and
- * exchanges. If sid is non-zero, then reset only exchanges
- * we sourced from that FID. If did is non-zero, reset only
- * exchanges destined to that FID.
+ * Reset all EMs associated with a given local port. Release all
+ * sequences and exchanges. If sid is non-zero then reset only the
+ * exchanges sent from the local port's FID. If did is non-zero then
+ * reset only exchanges destined for the local port's FID.
  */
 void fc_exch_mgr_reset(struct fc_lport *lport, u32 sid, u32 did)
 {
@@ -1538,8 +1706,11 @@
 }
 EXPORT_SYMBOL(fc_exch_mgr_reset);
 
-/*
- * Handle incoming ELS REC - Read Exchange Concise.
+/**
+ * fc_exch_els_rec() - Handler for ELS REC (Read Exchange Concise) requests
+ * @sp:	 The sequence the REC is on
+ * @rfp: The REC frame
+ *
  * Note that the requesting port may be different than the S_ID in the request.
  */
 static void fc_exch_els_rec(struct fc_seq *sp, struct fc_frame *rfp)
@@ -1621,10 +1792,11 @@
 	fc_frame_free(rfp);
 }
 
-/*
- * Handle response from RRQ.
- * Not much to do here, really.
- * Should report errors.
+/**
+ * fc_exch_rrq_resp() - Handler for RRQ responses
+ * @sp:	 The sequence that the RRQ is on
+ * @fp:	 The RRQ frame
+ * @arg: The exchange that the RRQ is on
  *
  * TODO: fix error handler.
  */
@@ -1664,21 +1836,99 @@
 	fc_exch_release(aborted_ep);
 }
 
-/*
- * Send ELS RRQ - Reinstate Recovery Qualifier.
+
+/**
+ * fc_exch_seq_send() - Send a frame using a new exchange and sequence
+ * @lport:	The local port to send the frame on
+ * @fp:		The frame to be sent
+ * @resp:	The response handler for this request
+ * @destructor: The destructor for the exchange
+ * @arg:	The argument to be passed to the response handler
+ * @timer_msec: The timeout period for the exchange
+ *
+ * The frame pointer with some of the header's fields must be
+ * filled before calling this routine, those fields are:
+ *
+ * - routing control
+ * - FC port did
+ * - FC port sid
+ * - FC header type
+ * - frame control
+ * - parameter or relative offset
+ */
+static struct fc_seq *fc_exch_seq_send(struct fc_lport *lport,
+				       struct fc_frame *fp,
+				       void (*resp)(struct fc_seq *,
+						    struct fc_frame *fp,
+						    void *arg),
+				       void (*destructor)(struct fc_seq *,
+							  void *),
+				       void *arg, u32 timer_msec)
+{
+	struct fc_exch *ep;
+	struct fc_seq *sp = NULL;
+	struct fc_frame_header *fh;
+	int rc = 1;
+
+	ep = fc_exch_alloc(lport, fp);
+	if (!ep) {
+		fc_frame_free(fp);
+		return NULL;
+	}
+	ep->esb_stat |= ESB_ST_SEQ_INIT;
+	fh = fc_frame_header_get(fp);
+	fc_exch_set_addr(ep, ntoh24(fh->fh_s_id), ntoh24(fh->fh_d_id));
+	ep->resp = resp;
+	ep->destructor = destructor;
+	ep->arg = arg;
+	ep->r_a_tov = FC_DEF_R_A_TOV;
+	ep->lp = lport;
+	sp = &ep->seq;
+
+	ep->fh_type = fh->fh_type; /* save for possbile timeout handling */
+	ep->f_ctl = ntoh24(fh->fh_f_ctl);
+	fc_exch_setup_hdr(ep, fp, ep->f_ctl);
+	sp->cnt++;
+
+	if (ep->xid <= lport->lro_xid)
+		fc_fcp_ddp_setup(fr_fsp(fp), ep->xid);
+
+	if (unlikely(lport->tt.frame_send(lport, fp)))
+		goto err;
+
+	if (timer_msec)
+		fc_exch_timer_set_locked(ep, timer_msec);
+	ep->f_ctl &= ~FC_FC_FIRST_SEQ;	/* not first seq */
+
+	if (ep->f_ctl & FC_FC_SEQ_INIT)
+		ep->esb_stat &= ~ESB_ST_SEQ_INIT;
+	spin_unlock_bh(&ep->ex_lock);
+	return sp;
+err:
+	rc = fc_exch_done_locked(ep);
+	spin_unlock_bh(&ep->ex_lock);
+	if (!rc)
+		fc_exch_delete(ep);
+	return NULL;
+}
+
+/**
+ * fc_exch_rrq() - Send an ELS RRQ (Reinstate Recovery Qualifier) command
+ * @ep: The exchange to send the RRQ on
+ *
  * This tells the remote port to stop blocking the use of
  * the exchange and the seq_cnt range.
  */
 static void fc_exch_rrq(struct fc_exch *ep)
 {
-	struct fc_lport *lp;
+	struct fc_lport *lport;
 	struct fc_els_rrq *rrq;
 	struct fc_frame *fp;
 	u32 did;
 
-	lp = ep->lp;
+	lport = ep->lp;
 
-	fp = fc_frame_alloc(lp, sizeof(*rrq));
+	fp = fc_frame_alloc(lport, sizeof(*rrq));
 	if (!fp)
 		goto retry;
 
@@ -1694,10 +1944,11 @@
 		did = ep->sid;
 
 	fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, did,
-		       fc_host_port_id(lp->host), FC_TYPE_ELS,
+		       fc_host_port_id(lport->host), FC_TYPE_ELS,
 		       FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
 
-	if (fc_exch_seq_send(lp, fp, fc_exch_rrq_resp, NULL, ep, lp->e_d_tov))
+	if (fc_exch_seq_send(lport, fp, fc_exch_rrq_resp, NULL, ep,
+			     lport->e_d_tov))
 		return;
 
 retry:
@@ -1714,12 +1965,14 @@
 }
 
 
-/*
- * Handle incoming ELS RRQ - Reset Recovery Qualifier.
+/**
+ * fc_exch_els_rrq() - Handler for ELS RRQ (Reset Recovery Qualifier) requests
+ * @sp: The sequence that the RRQ is on
+ * @fp: The RRQ frame
  */
 static void fc_exch_els_rrq(struct fc_seq *sp, struct fc_frame *fp)
 {
-	struct fc_exch *ep;		/* request or subject exchange */
+	struct fc_exch *ep = NULL;	/* request or subject exchange */
 	struct fc_els_rrq *rp;
 	u32 sid;
 	u16 xid;
@@ -1769,17 +2022,24 @@
 	 * Send LS_ACC.
 	 */
 	fc_seq_ls_acc(sp);
-	fc_frame_free(fp);
-	return;
+	goto out;
 
 unlock_reject:
 	spin_unlock_bh(&ep->ex_lock);
-	fc_exch_release(ep);	/* drop hold from fc_exch_find */
 reject:
 	fc_seq_ls_rjt(sp, ELS_RJT_LOGIC, explan);
+out:
 	fc_frame_free(fp);
+	if (ep)
+		fc_exch_release(ep);	/* drop hold from fc_exch_find */
 }
 
+/**
+ * fc_exch_mgr_add() - Add an exchange manager to a local port's list of EMs
+ * @lport: The local port to add the exchange manager to
+ * @mp:	   The exchange manager to be added to the local port
+ * @match: The match routine that indicates when this EM should be used
+ */
 struct fc_exch_mgr_anchor *fc_exch_mgr_add(struct fc_lport *lport,
 					   struct fc_exch_mgr *mp,
 					   bool (*match)(struct fc_frame *))
@@ -1799,6 +2059,10 @@
 }
 EXPORT_SYMBOL(fc_exch_mgr_add);
 
+/**
+ * fc_exch_mgr_destroy() - Destroy an exchange manager
+ * @kref: The reference to the EM to be destroyed
+ */
 static void fc_exch_mgr_destroy(struct kref *kref)
 {
 	struct fc_exch_mgr *mp = container_of(kref, struct fc_exch_mgr, kref);
@@ -1808,6 +2072,10 @@
 	kfree(mp);
 }
 
+/**
+ * fc_exch_mgr_del() - Delete an EM from a local port's list
+ * @ema: The exchange manager anchor identifying the EM to be deleted
+ */
 void fc_exch_mgr_del(struct fc_exch_mgr_anchor *ema)
 {
 	/* remove EM anchor from EM anchors list */
@@ -1817,7 +2085,35 @@
 }
 EXPORT_SYMBOL(fc_exch_mgr_del);
 
-struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
+/**
+ * fc_exch_mgr_list_clone() - Share all exchange manager objects
+ * @src: Source lport to clone exchange managers from
+ * @dst: New lport that takes references to all the exchange managers
+ */
+int fc_exch_mgr_list_clone(struct fc_lport *src, struct fc_lport *dst)
+{
+	struct fc_exch_mgr_anchor *ema, *tmp;
+
+	list_for_each_entry(ema, &src->ema_list, ema_list) {
+		if (!fc_exch_mgr_add(dst, ema->mp, ema->match))
+			goto err;
+	}
+	return 0;
+err:
+	list_for_each_entry_safe(ema, tmp, &dst->ema_list, ema_list)
+		fc_exch_mgr_del(ema);
+	return -ENOMEM;
+}
+
+/**
+ * fc_exch_mgr_alloc() - Allocate an exchange manager
+ * @lport:   The local port that the new EM will be associated with
+ * @class:   The default FC class for new exchanges
+ * @min_xid: The minimum XID for exchanges from the new EM
+ * @max_xid: The maximum XID for exchanges from the new EM
+ * @match:   The match routine for the new EM
+ */
+struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lport,
 				      enum fc_class class,
 				      u16 min_xid, u16 max_xid,
 				      bool (*match)(struct fc_frame *))
@@ -1830,7 +2126,7 @@
 
 	if (max_xid <= min_xid || max_xid == FC_XID_UNKNOWN ||
 	    (min_xid & fc_cpu_mask) != 0) {
-		FC_LPORT_DBG(lp, "Invalid min_xid 0x:%x and max_xid 0x:%x\n",
+		FC_LPORT_DBG(lport, "Invalid min_xid 0x:%x and max_xid 0x:%x\n",
 			     min_xid, max_xid);
 		return NULL;
 	}
@@ -1873,7 +2169,7 @@
 	}
 
 	kref_init(&mp->kref);
-	if (!fc_exch_mgr_add(lp, mp, match)) {
+	if (!fc_exch_mgr_add(lport, mp, match)) {
 		free_percpu(mp->pool);
 		goto free_mempool;
 	}
@@ -1894,76 +2190,26 @@
 }
 EXPORT_SYMBOL(fc_exch_mgr_alloc);
 
+/**
+ * fc_exch_mgr_free() - Free all exchange managers on a local port
+ * @lport: The local port whose EMs are to be freed
+ */
 void fc_exch_mgr_free(struct fc_lport *lport)
 {
 	struct fc_exch_mgr_anchor *ema, *next;
 
+	flush_workqueue(fc_exch_workqueue);
 	list_for_each_entry_safe(ema, next, &lport->ema_list, ema_list)
 		fc_exch_mgr_del(ema);
 }
 EXPORT_SYMBOL(fc_exch_mgr_free);
 
-
-struct fc_seq *fc_exch_seq_send(struct fc_lport *lp,
-				struct fc_frame *fp,
-				void (*resp)(struct fc_seq *,
-					     struct fc_frame *fp,
-					     void *arg),
-				void (*destructor)(struct fc_seq *, void *),
-				void *arg, u32 timer_msec)
-{
-	struct fc_exch *ep;
-	struct fc_seq *sp = NULL;
-	struct fc_frame_header *fh;
-	int rc = 1;
-
-	ep = fc_exch_alloc(lp, fp);
-	if (!ep) {
-		fc_frame_free(fp);
-		return NULL;
-	}
-	ep->esb_stat |= ESB_ST_SEQ_INIT;
-	fh = fc_frame_header_get(fp);
-	fc_exch_set_addr(ep, ntoh24(fh->fh_s_id), ntoh24(fh->fh_d_id));
-	ep->resp = resp;
-	ep->destructor = destructor;
-	ep->arg = arg;
-	ep->r_a_tov = FC_DEF_R_A_TOV;
-	ep->lp = lp;
-	sp = &ep->seq;
-
-	ep->fh_type = fh->fh_type; /* save for possbile timeout handling */
-	ep->f_ctl = ntoh24(fh->fh_f_ctl);
-	fc_exch_setup_hdr(ep, fp, ep->f_ctl);
-	sp->cnt++;
-
-	if (ep->xid <= lp->lro_xid)
-		fc_fcp_ddp_setup(fr_fsp(fp), ep->xid);
-
-	if (unlikely(lp->tt.frame_send(lp, fp)))
-		goto err;
-
-	if (timer_msec)
-		fc_exch_timer_set_locked(ep, timer_msec);
-	ep->f_ctl &= ~FC_FC_FIRST_SEQ;	/* not first seq */
-
-	if (ep->f_ctl & FC_FC_SEQ_INIT)
-		ep->esb_stat &= ~ESB_ST_SEQ_INIT;
-	spin_unlock_bh(&ep->ex_lock);
-	return sp;
-err:
-	rc = fc_exch_done_locked(ep);
-	spin_unlock_bh(&ep->ex_lock);
-	if (!rc)
-		fc_exch_delete(ep);
-	return NULL;
-}
-EXPORT_SYMBOL(fc_exch_seq_send);
-
-/*
- * Receive a frame
+/**
+ * fc_exch_recv() - Handler for received frames
+ * @lport: The local port the frame was received on
+ * @fp:	   The received frame
  */
-void fc_exch_recv(struct fc_lport *lp, struct fc_frame *fp)
+void fc_exch_recv(struct fc_lport *lport, struct fc_frame *fp)
 {
 	struct fc_frame_header *fh = fc_frame_header_get(fp);
 	struct fc_exch_mgr_anchor *ema;
@@ -1971,8 +2217,8 @@
 	u16 oxid;
 
 	/* lport lock ? */
-	if (!lp || lp->state == LPORT_ST_DISABLED) {
-		FC_LPORT_DBG(lp, "Receiving frames for an lport that "
+	if (!lport || lport->state == LPORT_ST_DISABLED) {
+		FC_LPORT_DBG(lport, "Receiving frames for an lport that "
 			     "has not been initialized correctly\n");
 		fc_frame_free(fp);
 		return;
@@ -1981,7 +2227,7 @@
 	f_ctl = ntoh24(fh->fh_f_ctl);
 	oxid = ntohs(fh->fh_ox_id);
 	if (f_ctl & FC_FC_EX_CTX) {
-		list_for_each_entry(ema, &lp->ema_list, ema_list) {
+		list_for_each_entry(ema, &lport->ema_list, ema_list) {
 			if ((oxid >= ema->mp->min_xid) &&
 			    (oxid <= ema->mp->max_xid)) {
 				found = 1;
@@ -1990,13 +2236,13 @@
 		}
 
 		if (!found) {
-			FC_LPORT_DBG(lp, "Received response for out "
+			FC_LPORT_DBG(lport, "Received response for out "
 				     "of range oxid:%hx\n", oxid);
 			fc_frame_free(fp);
 			return;
 		}
 	} else
-		ema = list_entry(lp->ema_list.prev, typeof(*ema), ema_list);
+		ema = list_entry(lport->ema_list.prev, typeof(*ema), ema_list);
 
 	/*
 	 * If frame is marked invalid, just drop it.
@@ -2015,37 +2261,56 @@
 		else if (f_ctl & FC_FC_SEQ_CTX)
 			fc_exch_recv_resp(ema->mp, fp);
 		else
-			fc_exch_recv_req(lp, ema->mp, fp);
+			fc_exch_recv_req(lport, ema->mp, fp);
 		break;
 	default:
-		FC_LPORT_DBG(lp, "dropping invalid frame (eof %x)", fr_eof(fp));
+		FC_LPORT_DBG(lport, "dropping invalid frame (eof %x)",
+			     fr_eof(fp));
 		fc_frame_free(fp);
 	}
 }
 EXPORT_SYMBOL(fc_exch_recv);
 
-int fc_exch_init(struct fc_lport *lp)
+/**
+ * fc_exch_init() - Initialize the exchange layer for a local port
+ * @lport: The local port to initialize the exchange layer for
+ */
+int fc_exch_init(struct fc_lport *lport)
 {
-	if (!lp->tt.seq_start_next)
-		lp->tt.seq_start_next = fc_seq_start_next;
+	if (!lport->tt.seq_start_next)
+		lport->tt.seq_start_next = fc_seq_start_next;
 
-	if (!lp->tt.exch_seq_send)
-		lp->tt.exch_seq_send = fc_exch_seq_send;
+	if (!lport->tt.exch_seq_send)
+		lport->tt.exch_seq_send = fc_exch_seq_send;
 
-	if (!lp->tt.seq_send)
-		lp->tt.seq_send = fc_seq_send;
+	if (!lport->tt.seq_send)
+		lport->tt.seq_send = fc_seq_send;
 
-	if (!lp->tt.seq_els_rsp_send)
-		lp->tt.seq_els_rsp_send = fc_seq_els_rsp_send;
+	if (!lport->tt.seq_els_rsp_send)
+		lport->tt.seq_els_rsp_send = fc_seq_els_rsp_send;
 
-	if (!lp->tt.exch_done)
-		lp->tt.exch_done = fc_exch_done;
+	if (!lport->tt.exch_done)
+		lport->tt.exch_done = fc_exch_done;
 
-	if (!lp->tt.exch_mgr_reset)
-		lp->tt.exch_mgr_reset = fc_exch_mgr_reset;
+	if (!lport->tt.exch_mgr_reset)
+		lport->tt.exch_mgr_reset = fc_exch_mgr_reset;
 
-	if (!lp->tt.seq_exch_abort)
-		lp->tt.seq_exch_abort = fc_seq_exch_abort;
+	if (!lport->tt.seq_exch_abort)
+		lport->tt.seq_exch_abort = fc_seq_exch_abort;
+
+	return 0;
+}
+EXPORT_SYMBOL(fc_exch_init);
+
+/**
+ * fc_setup_exch_mgr() - Setup an exchange manager
+ */
+int fc_setup_exch_mgr()
+{
+	fc_em_cachep = kmem_cache_create("libfc_em", sizeof(struct fc_exch),
+					 0, SLAB_HWCACHE_ALIGN, NULL);
+	if (!fc_em_cachep)
+		return -ENOMEM;
 
 	/*
 	 * Initialize fc_cpu_mask and fc_cpu_order. The
@@ -2069,20 +2334,17 @@
 	}
 	fc_cpu_mask--;
 
-	return 0;
-}
-EXPORT_SYMBOL(fc_exch_init);
-
-int fc_setup_exch_mgr(void)
-{
-	fc_em_cachep = kmem_cache_create("libfc_em", sizeof(struct fc_exch),
-					 0, SLAB_HWCACHE_ALIGN, NULL);
-	if (!fc_em_cachep)
+	fc_exch_workqueue = create_singlethread_workqueue("fc_exch_workqueue");
+	if (!fc_exch_workqueue)
 		return -ENOMEM;
 	return 0;
 }
 
-void fc_destroy_exch_mgr(void)
+/**
+ * fc_destroy_exch_mgr() - Destroy an exchange manager
+ */
+void fc_destroy_exch_mgr()
 {
+	destroy_workqueue(fc_exch_workqueue);
 	kmem_cache_destroy(fc_em_cachep);
 }
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 59a4408..c4b58d0 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -39,15 +39,9 @@
 #include <scsi/libfc.h>
 #include <scsi/fc_encode.h>
 
-MODULE_AUTHOR("Open-FCoE.org");
-MODULE_DESCRIPTION("libfc");
-MODULE_LICENSE("GPL v2");
+#include "fc_libfc.h"
 
-unsigned int fc_debug_logging;
-module_param_named(debug_logging, fc_debug_logging, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels");
-
-static struct kmem_cache *scsi_pkt_cachep;
+struct kmem_cache *scsi_pkt_cachep;
 
 /* SRB state definitions */
 #define FC_SRB_FREE		0		/* cmd is free */
@@ -58,7 +52,6 @@
 #define FC_SRB_DISCONTIG	(1 << 4)	/* non-sequential data recvd */
 #define FC_SRB_COMPL		(1 << 5)	/* fc_io_compl has been run */
 #define FC_SRB_FCP_PROCESSING_TMO (1 << 6)	/* timer function processing */
-#define FC_SRB_NOMEM		(1 << 7)	/* dropped to out of mem */
 
 #define FC_SRB_READ		(1 << 1)
 #define FC_SRB_WRITE		(1 << 0)
@@ -73,10 +66,20 @@
 #define CMD_SCSI_STATUS(Cmnd)	    ((Cmnd)->SCp.Status)
 #define CMD_RESID_LEN(Cmnd)	    ((Cmnd)->SCp.buffers_residual)
 
+/**
+ * struct fc_fcp_internal - FCP layer internal data
+ * @scsi_pkt_pool:  Memory pool to draw FCP packets from
+ * @scsi_pkt_queue: Current FCP packets
+ * @last_can_queue_ramp_down_time: ramp down time
+ * @last_can_queue_ramp_up_time: ramp up time
+ * @max_can_queue: max can_queue size
+ */
 struct fc_fcp_internal {
-	mempool_t	*scsi_pkt_pool;
+	mempool_t	 *scsi_pkt_pool;
 	struct list_head scsi_pkt_queue;
-	u8		throttled;
+	unsigned long last_can_queue_ramp_down_time;
+	unsigned long last_can_queue_ramp_up_time;
+	int max_can_queue;
 };
 
 #define fc_get_scsi_internal(x)	((struct fc_fcp_internal *)(x)->scsi_priv)
@@ -90,9 +93,9 @@
 static void fc_fcp_resp(struct fc_fcp_pkt *, struct fc_frame *);
 static void fc_fcp_complete_locked(struct fc_fcp_pkt *);
 static void fc_tm_done(struct fc_seq *, struct fc_frame *, void *);
-static void fc_fcp_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp);
+static void fc_fcp_error(struct fc_fcp_pkt *, struct fc_frame *);
 static void fc_timeout_error(struct fc_fcp_pkt *);
-static void fc_fcp_timeout(unsigned long data);
+static void fc_fcp_timeout(unsigned long);
 static void fc_fcp_rec(struct fc_fcp_pkt *);
 static void fc_fcp_rec_error(struct fc_fcp_pkt *, struct fc_frame *);
 static void fc_fcp_rec_resp(struct fc_seq *, struct fc_frame *, void *);
@@ -124,6 +127,7 @@
 #define FC_SCSI_TM_TOV		(10 * HZ)
 #define FC_SCSI_REC_TOV		(2 * HZ)
 #define FC_HOST_RESET_TIMEOUT	(30 * HZ)
+#define FC_CAN_QUEUE_PERIOD	(60 * HZ)
 
 #define FC_MAX_ERROR_CNT	5
 #define FC_MAX_RECOV_RETRY	3
@@ -131,23 +135,22 @@
 #define FC_FCP_DFLT_QUEUE_DEPTH 32
 
 /**
- * fc_fcp_pkt_alloc - allocation routine for scsi_pkt packet
- * @lp:		fc lport struct
- * @gfp:	gfp flags for allocation
+ * fc_fcp_pkt_alloc() - Allocate a fcp_pkt
+ * @lport: The local port that the FCP packet is for
+ * @gfp:   GFP flags for allocation
  *
- * This is used by upper layer scsi driver.
- * Return Value : scsi_pkt structure or null on allocation failure.
- * Context	: call from process context. no locking required.
+ * Return value: fcp_pkt structure or null on allocation failure.
+ * Context:	 Can be called from process context, no lock is required.
  */
-static struct fc_fcp_pkt *fc_fcp_pkt_alloc(struct fc_lport *lp, gfp_t gfp)
+static struct fc_fcp_pkt *fc_fcp_pkt_alloc(struct fc_lport *lport, gfp_t gfp)
 {
-	struct fc_fcp_internal *si = fc_get_scsi_internal(lp);
+	struct fc_fcp_internal *si = fc_get_scsi_internal(lport);
 	struct fc_fcp_pkt *fsp;
 
 	fsp = mempool_alloc(si->scsi_pkt_pool, gfp);
 	if (fsp) {
 		memset(fsp, 0, sizeof(*fsp));
-		fsp->lp = lp;
+		fsp->lp = lport;
 		atomic_set(&fsp->ref_cnt, 1);
 		init_timer(&fsp->timer);
 		INIT_LIST_HEAD(&fsp->list);
@@ -157,12 +160,11 @@
 }
 
 /**
- * fc_fcp_pkt_release() - release hold on scsi_pkt packet
- * @fsp:	fcp packet struct
+ * fc_fcp_pkt_release() - Release hold on a fcp_pkt
+ * @fsp: The FCP packet to be released
  *
- * This is used by upper layer scsi driver.
- * Context	: call from process  and interrupt context.
- *		  no locking required
+ * Context: Can be called from process or interrupt context,
+ *	    no lock is required.
  */
 static void fc_fcp_pkt_release(struct fc_fcp_pkt *fsp)
 {
@@ -173,20 +175,25 @@
 	}
 }
 
+/**
+ * fc_fcp_pkt_hold() - Hold a fcp_pkt
+ * @fsp: The FCP packet to be held
+ */
 static void fc_fcp_pkt_hold(struct fc_fcp_pkt *fsp)
 {
 	atomic_inc(&fsp->ref_cnt);
 }
 
 /**
- * fc_fcp_pkt_destory() - release hold on scsi_pkt packet
- * @seq:		exchange sequence
- * @fsp:	fcp packet struct
+ * fc_fcp_pkt_destory() - Release hold on a fcp_pkt
+ * @seq: The sequence that the FCP packet is on (required by destructor API)
+ * @fsp: The FCP packet to be released
  *
- * Release hold on scsi_pkt packet set to keep scsi_pkt
- * till EM layer exch resource is not freed.
- * Context	: called from from EM layer.
- *		  no locking required
+ * This routine is called by a destructor callback in the exch_seq_send()
+ * routine of the libfc Transport Template. The 'struct fc_seq' is a required
+ * argument even though it is not used by this routine.
+ *
+ * Context: No locking required.
  */
 static void fc_fcp_pkt_destroy(struct fc_seq *seq, void *fsp)
 {
@@ -194,10 +201,10 @@
 }
 
 /**
- * fc_fcp_lock_pkt() - lock a packet and get a ref to it.
- * @fsp:	fcp packet
+ * fc_fcp_lock_pkt() - Lock a fcp_pkt and increase its reference count
+ * @fsp: The FCP packet to be locked and incremented
  *
- * We should only return error if we return a command to scsi-ml before
+ * We should only return error if we return a command to SCSI-ml before
  * getting a response. This can happen in cases where we send a abort, but
  * do not wait for the response and the abort and command can be passing
  * each other on the wire/network-layer.
@@ -222,18 +229,33 @@
 	return 0;
 }
 
+/**
+ * fc_fcp_unlock_pkt() - Release a fcp_pkt's lock and decrement its
+ *			 reference count
+ * @fsp: The FCP packet to be unlocked and decremented
+ */
 static inline void fc_fcp_unlock_pkt(struct fc_fcp_pkt *fsp)
 {
 	spin_unlock_bh(&fsp->scsi_pkt_lock);
 	fc_fcp_pkt_release(fsp);
 }
 
+/**
+ * fc_fcp_timer_set() - Start a timer for a fcp_pkt
+ * @fsp:   The FCP packet to start a timer for
+ * @delay: The timeout period for the timer
+ */
 static void fc_fcp_timer_set(struct fc_fcp_pkt *fsp, unsigned long delay)
 {
 	if (!(fsp->state & FC_SRB_COMPL))
 		mod_timer(&fsp->timer, jiffies + delay);
 }
 
+/**
+ * fc_fcp_send_abort() - Send an abort for exchanges associated with a
+ *			 fcp_pkt
+ * @fsp: The FCP packet to abort exchanges on
+ */
 static int fc_fcp_send_abort(struct fc_fcp_pkt *fsp)
 {
 	if (!fsp->seq_ptr)
@@ -243,9 +265,14 @@
 	return fsp->lp->tt.seq_exch_abort(fsp->seq_ptr, 0);
 }
 
-/*
- * Retry command.
- * An abort isn't needed.
+/**
+ * fc_fcp_retry_cmd() - Retry a fcp_pkt
+ * @fsp: The FCP packet to be retried
+ *
+ * Sets the status code to be FC_ERROR and then calls
+ * fc_fcp_complete_locked() which in turn calls fc_io_compl().
+ * fc_io_compl() will notify the SCSI-ml that the I/O is done.
+ * The SCSI-ml will retry the command.
  */
 static void fc_fcp_retry_cmd(struct fc_fcp_pkt *fsp)
 {
@@ -260,64 +287,146 @@
 	fc_fcp_complete_locked(fsp);
 }
 
-/*
- * fc_fcp_ddp_setup - calls to LLD's ddp_setup to set up DDP
- * transfer for a read I/O indicated by the fc_fcp_pkt.
- * @fsp: ptr to the fc_fcp_pkt
- *
- * This is called in exch_seq_send() when we have a newly allocated
- * exchange with a valid exchange id to setup ddp.
- *
- * returns: none
+/**
+ * fc_fcp_ddp_setup() - Calls a LLD's ddp_setup routine to set up DDP context
+ * @fsp: The FCP packet that will manage the DDP frames
+ * @xid: The XID that will be used for the DDP exchange
  */
 void fc_fcp_ddp_setup(struct fc_fcp_pkt *fsp, u16 xid)
 {
-	struct fc_lport *lp;
+	struct fc_lport *lport;
 
 	if (!fsp)
 		return;
 
-	lp = fsp->lp;
+	lport = fsp->lp;
 	if ((fsp->req_flags & FC_SRB_READ) &&
-	    (lp->lro_enabled) && (lp->tt.ddp_setup)) {
-		if (lp->tt.ddp_setup(lp, xid, scsi_sglist(fsp->cmd),
-				     scsi_sg_count(fsp->cmd)))
+	    (lport->lro_enabled) && (lport->tt.ddp_setup)) {
+		if (lport->tt.ddp_setup(lport, xid, scsi_sglist(fsp->cmd),
+					scsi_sg_count(fsp->cmd)))
 			fsp->xfer_ddp = xid;
 	}
 }
-EXPORT_SYMBOL(fc_fcp_ddp_setup);
 
-/*
- * fc_fcp_ddp_done - calls to LLD's ddp_done to release any
- * DDP related resources for this I/O if it is initialized
- * as a ddp transfer
- * @fsp: ptr to the fc_fcp_pkt
- *
- * returns: none
+/**
+ * fc_fcp_ddp_done() - Calls a LLD's ddp_done routine to release any
+ *		       DDP related resources for a fcp_pkt
+ * @fsp: The FCP packet that DDP had been used on
  */
 static void fc_fcp_ddp_done(struct fc_fcp_pkt *fsp)
 {
-	struct fc_lport *lp;
+	struct fc_lport *lport;
 
 	if (!fsp)
 		return;
 
-	lp = fsp->lp;
-	if (fsp->xfer_ddp && lp->tt.ddp_done) {
-		fsp->xfer_len = lp->tt.ddp_done(lp, fsp->xfer_ddp);
-		fsp->xfer_ddp = 0;
+	if (fsp->xfer_ddp == FC_XID_UNKNOWN)
+		return;
+
+	lport = fsp->lp;
+	if (lport->tt.ddp_done) {
+		fsp->xfer_len = lport->tt.ddp_done(lport, fsp->xfer_ddp);
+		fsp->xfer_ddp = FC_XID_UNKNOWN;
 	}
 }
 
+/**
+ * fc_fcp_can_queue_ramp_up() - increases can_queue
+ * @lport: lport to ramp up can_queue
+ *
+ * Locking notes: Called with Scsi_Host lock held
+ */
+static void fc_fcp_can_queue_ramp_up(struct fc_lport *lport)
+{
+	struct fc_fcp_internal *si = fc_get_scsi_internal(lport);
+	int can_queue;
+
+	if (si->last_can_queue_ramp_up_time &&
+	    (time_before(jiffies, si->last_can_queue_ramp_up_time +
+			 FC_CAN_QUEUE_PERIOD)))
+		return;
+
+	if (time_before(jiffies, si->last_can_queue_ramp_down_time +
+			FC_CAN_QUEUE_PERIOD))
+		return;
+
+	si->last_can_queue_ramp_up_time = jiffies;
+
+	can_queue = lport->host->can_queue << 1;
+	if (can_queue >= si->max_can_queue) {
+		can_queue = si->max_can_queue;
+		si->last_can_queue_ramp_down_time = 0;
+	}
+	lport->host->can_queue = can_queue;
+	shost_printk(KERN_ERR, lport->host, "libfc: increased "
+		     "can_queue to %d.\n", can_queue);
+}
+
+/**
+ * fc_fcp_can_queue_ramp_down() - reduces can_queue
+ * @lport: lport to reduce can_queue
+ *
+ * If we are getting memory allocation failures, then we may
+ * be trying to execute too many commands. We let the running
+ * commands complete or timeout, then try again with a reduced
+ * can_queue. Eventually we will hit the point where we run
+ * on all reserved structs.
+ *
+ * Locking notes: Called with Scsi_Host lock held
+ */
+static void fc_fcp_can_queue_ramp_down(struct fc_lport *lport)
+{
+	struct fc_fcp_internal *si = fc_get_scsi_internal(lport);
+	int can_queue;
+
+	if (si->last_can_queue_ramp_down_time &&
+	    (time_before(jiffies, si->last_can_queue_ramp_down_time +
+			 FC_CAN_QUEUE_PERIOD)))
+		return;
+
+	si->last_can_queue_ramp_down_time = jiffies;
+
+	can_queue = lport->host->can_queue;
+	can_queue >>= 1;
+	if (!can_queue)
+		can_queue = 1;
+	lport->host->can_queue = can_queue;
+	shost_printk(KERN_ERR, lport->host, "libfc: Could not allocate frame.\n"
+		     "Reducing can_queue to %d.\n", can_queue);
+}
 
 /*
- * Receive SCSI data from target.
- * Called after receiving solicited data.
+ * fc_fcp_frame_alloc() -  Allocates fc_frame structure and buffer.
+ * @lport:	fc lport struct
+ * @len:	payload length
+ *
+ * Allocates fc_frame structure and buffer but if fails to allocate
+ * then reduce can_queue.
+ */
+static inline struct fc_frame *fc_fcp_frame_alloc(struct fc_lport *lport,
+						  size_t len)
+{
+	struct fc_frame *fp;
+	unsigned long flags;
+
+	fp = fc_frame_alloc(lport, len);
+	if (!fp) {
+		spin_lock_irqsave(lport->host->host_lock, flags);
+		fc_fcp_can_queue_ramp_down(lport);
+		spin_unlock_irqrestore(lport->host->host_lock, flags);
+	}
+	return fp;
+}
+
+/**
+ * fc_fcp_recv_data() - Handler for receiving SCSI-FCP data from a target
+ * @fsp: The FCP packet the data is on
+ * @fp:	 The data frame
  */
 static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
 {
 	struct scsi_cmnd *sc = fsp->cmd;
-	struct fc_lport *lp = fsp->lp;
+	struct fc_lport *lport = fsp->lp;
 	struct fcoe_dev_stats *stats;
 	struct fc_frame_header *fh;
 	size_t start_offset;
@@ -327,7 +436,7 @@
 	size_t len;
 	void *buf;
 	struct scatterlist *sg;
-	size_t remaining;
+	u32 nents;
 
 	fh = fc_frame_header_get(fp);
 	offset = ntohl(fh->fh_parm_offset);
@@ -351,65 +460,29 @@
 	if (offset != fsp->xfer_len)
 		fsp->state |= FC_SRB_DISCONTIG;
 
-	crc = 0;
-	if (fr_flags(fp) & FCPHF_CRC_UNCHECKED)
-		crc = crc32(~0, (u8 *) fh, sizeof(*fh));
-
 	sg = scsi_sglist(sc);
-	remaining = len;
+	nents = scsi_sg_count(sc);
 
-	while (remaining > 0 && sg) {
-		size_t off;
-		void *page_addr;
-		size_t sg_bytes;
-
-		if (offset >= sg->length) {
-			offset -= sg->length;
-			sg = sg_next(sg);
-			continue;
-		}
-		sg_bytes = min(remaining, sg->length - offset);
-
-		/*
-		 * The scatterlist item may be bigger than PAGE_SIZE,
-		 * but we are limited to mapping PAGE_SIZE at a time.
-		 */
-		off = offset + sg->offset;
-		sg_bytes = min(sg_bytes, (size_t)
-			       (PAGE_SIZE - (off & ~PAGE_MASK)));
-		page_addr = kmap_atomic(sg_page(sg) + (off >> PAGE_SHIFT),
-					KM_SOFTIRQ0);
-		if (!page_addr)
-			break;		/* XXX panic? */
-
-		if (fr_flags(fp) & FCPHF_CRC_UNCHECKED)
-			crc = crc32(crc, buf, sg_bytes);
-		memcpy((char *)page_addr + (off & ~PAGE_MASK), buf,
-		       sg_bytes);
-
-		kunmap_atomic(page_addr, KM_SOFTIRQ0);
-		buf += sg_bytes;
-		offset += sg_bytes;
-		remaining -= sg_bytes;
-		copy_len += sg_bytes;
-	}
-
-	if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) {
+	if (!(fr_flags(fp) & FCPHF_CRC_UNCHECKED)) {
+		copy_len = fc_copy_buffer_to_sglist(buf, len, sg, &nents,
+						    &offset, KM_SOFTIRQ0, NULL);
+	} else {
+		crc = crc32(~0, (u8 *) fh, sizeof(*fh));
+		copy_len = fc_copy_buffer_to_sglist(buf, len, sg, &nents,
+						    &offset, KM_SOFTIRQ0, &crc);
 		buf = fc_frame_payload_get(fp, 0);
-		if (len % 4) {
+		if (len % 4)
 			crc = crc32(crc, buf + len, 4 - (len % 4));
-			len += 4 - (len % 4);
-		}
 
 		if (~crc != le32_to_cpu(fr_crc(fp))) {
 crc_err:
-			stats = fc_lport_get_stats(lp);
+			stats = fc_lport_get_stats(lport);
 			stats->ErrorFrames++;
 			/* FIXME - per cpu count, not total count! */
 			if (stats->InvalidCRCCount++ < 5)
 				printk(KERN_WARNING "libfc: CRC error on data "
 				       "frame for port (%6x)\n",
-				       fc_host_port_id(lp->host));
+				       fc_host_port_id(lport->host));
 			/*
 			 * Assume the frame is total garbage.
 			 * We may have copied it over the good part
@@ -437,18 +510,17 @@
 }
 
 /**
- * fc_fcp_send_data() -  Send SCSI data to target.
- * @fsp: ptr to fc_fcp_pkt
- * @sp: ptr to this sequence
- * @offset: starting offset for this data request
- * @seq_blen: the burst length for this data request
+ * fc_fcp_send_data() - Send SCSI data to a target
+ * @fsp:      The FCP packet the data is on
+ * @sp:	      The sequence the data is to be sent on
+ * @offset:   The starting offset for this data request
+ * @seq_blen: The burst length for this data request
  *
  * Called after receiving a Transfer Ready data descriptor.
- * if LLD is capable of seq offload then send down seq_blen
- * size of data in single frame, otherwise send multiple FC
- * frames of max FC frame payload supported by target port.
- *
- * Returns : 0 for success.
+ * If the LLD is capable of sequence offload then send down the
+ * seq_blen ammount of data in single frame, otherwise send
+ * multiple frames of the maximum frame payload supported by
+ * the target port.
  */
 static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq,
 			    size_t offset, size_t seq_blen)
@@ -457,16 +529,18 @@
 	struct scsi_cmnd *sc;
 	struct scatterlist *sg;
 	struct fc_frame *fp = NULL;
-	struct fc_lport *lp = fsp->lp;
+	struct fc_lport *lport = fsp->lp;
+	struct page *page;
 	size_t remaining;
 	size_t t_blen;
 	size_t tlen;
 	size_t sg_bytes;
 	size_t frame_offset, fh_parm_offset;
+	size_t off;
 	int error;
 	void *data = NULL;
 	void *page_addr;
-	int using_sg = lp->sg_supp;
+	int using_sg = lport->sg_supp;
 	u32 f_ctl;
 
 	WARN_ON(seq_blen <= 0);
@@ -488,10 +562,10 @@
 	 * to max FC frame payload previously set in fsp->max_payload.
 	 */
 	t_blen = fsp->max_payload;
-	if (lp->seq_offload) {
-		t_blen = min(seq_blen, (size_t)lp->lso_max);
+	if (lport->seq_offload) {
+		t_blen = min(seq_blen, (size_t)lport->lso_max);
 		FC_FCP_DBG(fsp, "fsp=%p:lso:blen=%zx lso_max=0x%x t_blen=%zx\n",
-			   fsp, seq_blen, lp->lso_max, t_blen);
+			   fsp, seq_blen, lport->lso_max, t_blen);
 	}
 
 	WARN_ON(t_blen < FC_MIN_MAX_PAYLOAD);
@@ -503,7 +577,7 @@
 	remaining = seq_blen;
 	fh_parm_offset = frame_offset = offset;
 	tlen = 0;
-	seq = lp->tt.seq_start_next(seq);
+	seq = lport->tt.seq_start_next(seq);
 	f_ctl = FC_FC_REL_OFF;
 	WARN_ON(!seq);
 
@@ -525,43 +599,34 @@
 			 */
 			if (tlen % 4)
 				using_sg = 0;
-			if (using_sg) {
-				fp = _fc_frame_alloc(lp, 0);
-				if (!fp)
-					return -ENOMEM;
-			} else {
-				fp = fc_frame_alloc(lp, tlen);
-				if (!fp)
-					return -ENOMEM;
+			fp = fc_frame_alloc(lport, using_sg ? 0 : tlen);
+			if (!fp)
+				return -ENOMEM;
 
-				data = (void *)(fr_hdr(fp)) +
-					sizeof(struct fc_frame_header);
-			}
+			data = fc_frame_header_get(fp) + 1;
 			fh_parm_offset = frame_offset;
 			fr_max_payload(fp) = fsp->max_payload;
 		}
+
+		off = offset + sg->offset;
 		sg_bytes = min(tlen, sg->length - offset);
+		sg_bytes = min(sg_bytes,
+			       (size_t) (PAGE_SIZE - (off & ~PAGE_MASK)));
+		page = sg_page(sg) + (off >> PAGE_SHIFT);
 		if (using_sg) {
-			get_page(sg_page(sg));
+			get_page(page);
 			skb_fill_page_desc(fp_skb(fp),
 					   skb_shinfo(fp_skb(fp))->nr_frags,
-					   sg_page(sg), sg->offset + offset,
-					   sg_bytes);
+					   page, off & ~PAGE_MASK, sg_bytes);
 			fp_skb(fp)->data_len += sg_bytes;
 			fr_len(fp) += sg_bytes;
 			fp_skb(fp)->truesize += PAGE_SIZE;
 		} else {
-			size_t off = offset + sg->offset;
-
 			/*
 			 * The scatterlist item may be bigger than PAGE_SIZE,
 			 * but we must not cross pages inside the kmap.
 			 */
-			sg_bytes = min(sg_bytes, (size_t) (PAGE_SIZE -
-							   (off & ~PAGE_MASK)));
-			page_addr = kmap_atomic(sg_page(sg) +
-						(off >> PAGE_SHIFT),
-						KM_SOFTIRQ0);
+			page_addr = kmap_atomic(page, KM_SOFTIRQ0);
 			memcpy(data, (char *)page_addr + (off & ~PAGE_MASK),
 			       sg_bytes);
 			kunmap_atomic(page_addr, KM_SOFTIRQ0);
@@ -572,7 +637,8 @@
 		tlen -= sg_bytes;
 		remaining -= sg_bytes;
 
-		if (tlen)
+		if ((skb_shinfo(fp_skb(fp))->nr_frags < FC_FRAME_SG_LEN) &&
+		    (tlen))
 			continue;
 
 		/*
@@ -589,7 +655,7 @@
 		/*
 		 * send fragment using for a sequence.
 		 */
-		error = lp->tt.seq_send(lp, seq, fp);
+		error = lport->tt.seq_send(lport, seq, fp);
 		if (error) {
 			WARN_ON(1);		/* send error should be rare */
 			fc_fcp_retry_cmd(fsp);
@@ -601,6 +667,11 @@
 	return 0;
 }
 
+/**
+ * fc_fcp_abts_resp() - Send an ABTS response
+ * @fsp: The FCP packet that is being aborted
+ * @fp:	 The response frame
+ */
 static void fc_fcp_abts_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
 {
 	int ba_done = 1;
@@ -637,46 +708,13 @@
 }
 
 /**
- * fc_fcp_reduce_can_queue() - drop can_queue
- * @lp: lport to drop queueing for
- *
- * If we are getting memory allocation failures, then we may
- * be trying to execute too many commands. We let the running
- * commands complete or timeout, then try again with a reduced
- * can_queue. Eventually we will hit the point where we run
- * on all reserved structs.
- */
-static void fc_fcp_reduce_can_queue(struct fc_lport *lp)
-{
-	struct fc_fcp_internal *si = fc_get_scsi_internal(lp);
-	unsigned long flags;
-	int can_queue;
-
-	spin_lock_irqsave(lp->host->host_lock, flags);
-	if (si->throttled)
-		goto done;
-	si->throttled = 1;
-
-	can_queue = lp->host->can_queue;
-	can_queue >>= 1;
-	if (!can_queue)
-		can_queue = 1;
-	lp->host->can_queue = can_queue;
-	shost_printk(KERN_ERR, lp->host, "libfc: Could not allocate frame.\n"
-		     "Reducing can_queue to %d.\n", can_queue);
-done:
-	spin_unlock_irqrestore(lp->host->host_lock, flags);
-}
-
-/**
- * fc_fcp_recv() - Reveive FCP frames
+ * fc_fcp_recv() - Reveive an FCP frame
  * @seq: The sequence the frame is on
- * @fp: The FC frame
+ * @fp:	 The received frame
  * @arg: The related FCP packet
  *
- * Return   : None
- * Context  : called from Soft IRQ context
- *	      can not called holding list lock
+ * Context: Called from Soft IRQ context. Can not be called
+ *	    holding the FCP packet list lock.
  */
 static void fc_fcp_recv(struct fc_seq *seq, struct fc_frame *fp, void *arg)
 {
@@ -687,8 +725,10 @@
 	u8 r_ctl;
 	int rc = 0;
 
-	if (IS_ERR(fp))
-		goto errout;
+	if (IS_ERR(fp)) {
+		fc_fcp_error(fsp, fp);
+		return;
+	}
 
 	fh = fc_frame_header_get(fp);
 	r_ctl = fh->fh_r_ctl;
@@ -721,8 +761,6 @@
 				      (size_t) ntohl(dd->ft_burst_len));
 		if (!rc)
 			seq->rec_data = fsp->xfer_len;
-		else if (rc == -ENOMEM)
-			fsp->state |= FC_SRB_NOMEM;
 	} else if (r_ctl == FC_RCTL_DD_SOL_DATA) {
 		/*
 		 * received a DATA frame
@@ -742,13 +780,13 @@
 	fc_fcp_unlock_pkt(fsp);
 out:
 	fc_frame_free(fp);
-errout:
-	if (IS_ERR(fp))
-		fc_fcp_error(fsp, fp);
-	else if (rc == -ENOMEM)
-		fc_fcp_reduce_can_queue(lport);
 }
 
+/**
+ * fc_fcp_resp() - Handler for FCP responses
+ * @fsp: The FCP packet the response is for
+ * @fp:	 The response frame
+ */
 static void fc_fcp_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
 {
 	struct fc_frame_header *fh;
@@ -862,15 +900,16 @@
 }
 
 /**
- * fc_fcp_complete_locked() - complete processing of a fcp packet
- * @fsp:	fcp packet
+ * fc_fcp_complete_locked() - Complete processing of a fcp_pkt with the
+ *			      fcp_pkt lock held
+ * @fsp: The FCP packet to be completed
  *
  * This function may sleep if a timer is pending. The packet lock must be
  * held, and the host lock must not be held.
  */
 static void fc_fcp_complete_locked(struct fc_fcp_pkt *fsp)
 {
-	struct fc_lport *lp = fsp->lp;
+	struct fc_lport *lport = fsp->lp;
 	struct fc_seq *seq;
 	struct fc_exch *ep;
 	u32 f_ctl;
@@ -901,8 +940,8 @@
 			struct fc_frame *conf_frame;
 			struct fc_seq *csp;
 
-			csp = lp->tt.seq_start_next(seq);
-			conf_frame = fc_frame_alloc(fsp->lp, 0);
+			csp = lport->tt.seq_start_next(seq);
+			conf_frame = fc_fcp_frame_alloc(fsp->lp, 0);
 			if (conf_frame) {
 				f_ctl = FC_FC_SEQ_INIT;
 				f_ctl |= FC_FC_LAST_SEQ | FC_FC_END_SEQ;
@@ -910,43 +949,48 @@
 				fc_fill_fc_hdr(conf_frame, FC_RCTL_DD_SOL_CTL,
 					       ep->did, ep->sid,
 					       FC_TYPE_FCP, f_ctl, 0);
-				lp->tt.seq_send(lp, csp, conf_frame);
+				lport->tt.seq_send(lport, csp, conf_frame);
 			}
 		}
-		lp->tt.exch_done(seq);
+		lport->tt.exch_done(seq);
 	}
 	fc_io_compl(fsp);
 }
 
+/**
+ * fc_fcp_cleanup_cmd() - Cancel the active exchange on a fcp_pkt
+ * @fsp:   The FCP packet whose exchanges should be canceled
+ * @error: The reason for the cancellation
+ */
 static void fc_fcp_cleanup_cmd(struct fc_fcp_pkt *fsp, int error)
 {
-	struct fc_lport *lp = fsp->lp;
+	struct fc_lport *lport = fsp->lp;
 
 	if (fsp->seq_ptr) {
-		lp->tt.exch_done(fsp->seq_ptr);
+		lport->tt.exch_done(fsp->seq_ptr);
 		fsp->seq_ptr = NULL;
 	}
 	fsp->status_code = error;
 }
 
 /**
- * fc_fcp_cleanup_each_cmd() - Cleanup active commads
- * @lp:		logical port
- * @id:		target id
- * @lun:	lun
- * @error:	fsp status code
+ * fc_fcp_cleanup_each_cmd() - Cancel all exchanges on a local port
+ * @lport: The local port whose exchanges should be canceled
+ * @id:	   The target's ID
+ * @lun:   The LUN
+ * @error: The reason for cancellation
  *
  * If lun or id is -1, they are ignored.
  */
-static void fc_fcp_cleanup_each_cmd(struct fc_lport *lp, unsigned int id,
+static void fc_fcp_cleanup_each_cmd(struct fc_lport *lport, unsigned int id,
 				    unsigned int lun, int error)
 {
-	struct fc_fcp_internal *si = fc_get_scsi_internal(lp);
+	struct fc_fcp_internal *si = fc_get_scsi_internal(lport);
 	struct fc_fcp_pkt *fsp;
 	struct scsi_cmnd *sc_cmd;
 	unsigned long flags;
 
-	spin_lock_irqsave(lp->host->host_lock, flags);
+	spin_lock_irqsave(lport->host->host_lock, flags);
 restart:
 	list_for_each_entry(fsp, &si->scsi_pkt_queue, list) {
 		sc_cmd = fsp->cmd;
@@ -957,7 +1001,7 @@
 			continue;
 
 		fc_fcp_pkt_hold(fsp);
-		spin_unlock_irqrestore(lp->host->host_lock, flags);
+		spin_unlock_irqrestore(lport->host->host_lock, flags);
 
 		if (!fc_fcp_lock_pkt(fsp)) {
 			fc_fcp_cleanup_cmd(fsp, error);
@@ -966,35 +1010,36 @@
 		}
 
 		fc_fcp_pkt_release(fsp);
-		spin_lock_irqsave(lp->host->host_lock, flags);
+		spin_lock_irqsave(lport->host->host_lock, flags);
 		/*
 		 * while we dropped the lock multiple pkts could
 		 * have been released, so we have to start over.
 		 */
 		goto restart;
 	}
-	spin_unlock_irqrestore(lp->host->host_lock, flags);
-}
-
-static void fc_fcp_abort_io(struct fc_lport *lp)
-{
-	fc_fcp_cleanup_each_cmd(lp, -1, -1, FC_HRD_ERROR);
+	spin_unlock_irqrestore(lport->host->host_lock, flags);
 }
 
 /**
- * fc_fcp_pkt_send() - send a fcp packet to the lower level.
- * @lp:		fc lport
- * @fsp:	fc packet.
- *
- * This is called by upper layer protocol.
- * Return   : zero for success and -1 for failure
- * Context  : called from queuecommand which can be called from process
- *	      or scsi soft irq.
- * Locks    : called with the host lock and irqs disabled.
+ * fc_fcp_abort_io() - Abort all FCP-SCSI exchanges on a local port
+ * @lport: The local port whose exchanges are to be aborted
  */
-static int fc_fcp_pkt_send(struct fc_lport *lp, struct fc_fcp_pkt *fsp)
+static void fc_fcp_abort_io(struct fc_lport *lport)
 {
-	struct fc_fcp_internal *si = fc_get_scsi_internal(lp);
+	fc_fcp_cleanup_each_cmd(lport, -1, -1, FC_HRD_ERROR);
+}
+
+/**
+ * fc_fcp_pkt_send() - Send a fcp_pkt
+ * @lport: The local port to send the FCP packet on
+ * @fsp:   The FCP packet to send
+ *
+ * Return:  Zero for success and -1 for failure
+ * Locks:   Called with the host lock and irqs disabled.
+ */
+static int fc_fcp_pkt_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp)
+{
+	struct fc_fcp_internal *si = fc_get_scsi_internal(lport);
 	int rc;
 
 	fsp->cmd->SCp.ptr = (char *)fsp;
@@ -1006,16 +1051,22 @@
 	memcpy(fsp->cdb_cmd.fc_cdb, fsp->cmd->cmnd, fsp->cmd->cmd_len);
 	list_add_tail(&fsp->list, &si->scsi_pkt_queue);
 
-	spin_unlock_irq(lp->host->host_lock);
-	rc = lp->tt.fcp_cmd_send(lp, fsp, fc_fcp_recv);
-	spin_lock_irq(lp->host->host_lock);
+	spin_unlock_irq(lport->host->host_lock);
+	rc = lport->tt.fcp_cmd_send(lport, fsp, fc_fcp_recv);
+	spin_lock_irq(lport->host->host_lock);
 	if (rc)
 		list_del(&fsp->list);
 
 	return rc;
 }
 
-static int fc_fcp_cmd_send(struct fc_lport *lp, struct fc_fcp_pkt *fsp,
+/**
+ * fc_fcp_cmd_send() - Send a FCP command
+ * @lport: The local port to send the command on
+ * @fsp:   The FCP packet the command is on
+ * @resp:  The handler for the response
+ */
+static int fc_fcp_cmd_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp,
 			   void (*resp)(struct fc_seq *,
 					struct fc_frame *fp,
 					void *arg))
@@ -1023,14 +1074,14 @@
 	struct fc_frame *fp;
 	struct fc_seq *seq;
 	struct fc_rport *rport;
-	struct fc_rport_libfc_priv *rp;
+	struct fc_rport_libfc_priv *rpriv;
 	const size_t len = sizeof(fsp->cdb_cmd);
 	int rc = 0;
 
 	if (fc_fcp_lock_pkt(fsp))
 		return 0;
 
-	fp = fc_frame_alloc(lp, sizeof(fsp->cdb_cmd));
+	fp = fc_fcp_frame_alloc(lport, sizeof(fsp->cdb_cmd));
 	if (!fp) {
 		rc = -1;
 		goto unlock;
@@ -1040,15 +1091,15 @@
 	fr_fsp(fp) = fsp;
 	rport = fsp->rport;
 	fsp->max_payload = rport->maxframe_size;
-	rp = rport->dd_data;
+	rpriv = rport->dd_data;
 
 	fc_fill_fc_hdr(fp, FC_RCTL_DD_UNSOL_CMD, rport->port_id,
-		       fc_host_port_id(rp->local_port->host), FC_TYPE_FCP,
+		       fc_host_port_id(rpriv->local_port->host), FC_TYPE_FCP,
 		       FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
 
-	seq = lp->tt.exch_seq_send(lp, fp, resp, fc_fcp_pkt_destroy, fsp, 0);
+	seq = lport->tt.exch_seq_send(lport, fp, resp, fc_fcp_pkt_destroy,
+				      fsp, 0);
 	if (!seq) {
-		fc_frame_free(fp);
 		rc = -1;
 		goto unlock;
 	}
@@ -1065,8 +1116,10 @@
 	return rc;
 }
 
-/*
- * transport error handler
+/**
+ * fc_fcp_error() - Handler for FCP layer errors
+ * @fsp: The FCP packet the error is on
+ * @fp:	 The frame that has errored
  */
 static void fc_fcp_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
 {
@@ -1091,11 +1144,13 @@
 	fc_fcp_unlock_pkt(fsp);
 }
 
-/*
- * Scsi abort handler- calls to send an abort
- * and then wait for abort completion
+/**
+ * fc_fcp_pkt_abort() - Abort a fcp_pkt
+ * @fsp:   The FCP packet to abort on
+ *
+ * Called to send an abort and then wait for abort completion
  */
-static int fc_fcp_pkt_abort(struct fc_lport *lp, struct fc_fcp_pkt *fsp)
+static int fc_fcp_pkt_abort(struct fc_fcp_pkt *fsp)
 {
 	int rc = FAILED;
 
@@ -1122,14 +1177,15 @@
 	return rc;
 }
 
-/*
- * Retry LUN reset after resource allocation failed.
+/**
+ * fc_lun_reset_send() - Send LUN reset command
+ * @data: The FCP packet that identifies the LUN to be reset
  */
 static void fc_lun_reset_send(unsigned long data)
 {
 	struct fc_fcp_pkt *fsp = (struct fc_fcp_pkt *)data;
-	struct fc_lport *lp = fsp->lp;
-	if (lp->tt.fcp_cmd_send(lp, fsp, fc_tm_done)) {
+	struct fc_lport *lport = fsp->lp;
+	if (lport->tt.fcp_cmd_send(lport, fsp, fc_tm_done)) {
 		if (fsp->recov_retry++ >= FC_MAX_RECOV_RETRY)
 			return;
 		if (fc_fcp_lock_pkt(fsp))
@@ -1140,11 +1196,15 @@
 	}
 }
 
-/*
- * Scsi device reset handler- send a LUN RESET to the device
- * and wait for reset reply
+/**
+ * fc_lun_reset() - Send a LUN RESET command to a device
+ *		    and wait for the reply
+ * @lport: The local port to sent the comand on
+ * @fsp:   The FCP packet that identifies the LUN to be reset
+ * @id:	   The SCSI command ID
+ * @lun:   The LUN ID to be reset
  */
-static int fc_lun_reset(struct fc_lport *lp, struct fc_fcp_pkt *fsp,
+static int fc_lun_reset(struct fc_lport *lport, struct fc_fcp_pkt *fsp,
 			unsigned int id, unsigned int lun)
 {
 	int rc;
@@ -1172,14 +1232,14 @@
 
 	spin_lock_bh(&fsp->scsi_pkt_lock);
 	if (fsp->seq_ptr) {
-		lp->tt.exch_done(fsp->seq_ptr);
+		lport->tt.exch_done(fsp->seq_ptr);
 		fsp->seq_ptr = NULL;
 	}
 	fsp->wait_for_comp = 0;
 	spin_unlock_bh(&fsp->scsi_pkt_lock);
 
 	if (!rc) {
-		FC_SCSI_DBG(lp, "lun reset failed\n");
+		FC_SCSI_DBG(lport, "lun reset failed\n");
 		return FAILED;
 	}
 
@@ -1187,13 +1247,16 @@
 	if (fsp->cdb_status != FCP_TMF_CMPL)
 		return FAILED;
 
-	FC_SCSI_DBG(lp, "lun reset to lun %u completed\n", lun);
-	fc_fcp_cleanup_each_cmd(lp, id, lun, FC_CMD_ABORTED);
+	FC_SCSI_DBG(lport, "lun reset to lun %u completed\n", lun);
+	fc_fcp_cleanup_each_cmd(lport, id, lun, FC_CMD_ABORTED);
 	return SUCCESS;
 }
 
-/*
- * Task Managment response handler
+/**
+ * fc_tm_done() - Task Managment response handler
+ * @seq: The sequence that the response is on
+ * @fp:	 The response frame
+ * @arg: The FCP packet the response is for
  */
 static void fc_tm_done(struct fc_seq *seq, struct fc_frame *fp, void *arg)
 {
@@ -1230,34 +1293,31 @@
 	fc_fcp_unlock_pkt(fsp);
 }
 
-static void fc_fcp_cleanup(struct fc_lport *lp)
+/**
+ * fc_fcp_cleanup() - Cleanup all FCP exchanges on a local port
+ * @lport: The local port to be cleaned up
+ */
+static void fc_fcp_cleanup(struct fc_lport *lport)
 {
-	fc_fcp_cleanup_each_cmd(lp, -1, -1, FC_ERROR);
+	fc_fcp_cleanup_each_cmd(lport, -1, -1, FC_ERROR);
 }
 
-/*
- * fc_fcp_timeout: called by OS timer function.
+/**
+ * fc_fcp_timeout() - Handler for fcp_pkt timeouts
+ * @data: The FCP packet that has timed out
  *
- * The timer has been inactivated and must be reactivated if desired
- * using fc_fcp_timer_set().
- *
- * Algorithm:
- *
- * If REC is supported, just issue it, and return.  The REC exchange will
- * complete or time out, and recovery can continue at that point.
- *
- * Otherwise, if the response has been received without all the data,
- * it has been ER_TIMEOUT since the response was received.
- *
- * If the response has not been received,
- * we see if data was received recently.  If it has been, we continue waiting,
- * otherwise, we abort the command.
+ * If REC is supported then just issue it and return. The REC exchange will
+ * complete or time out and recovery can continue at that point. Otherwise,
+ * if the response has been received without all the data it has been
+ * ER_TIMEOUT since the response was received. If the response has not been
+ * received we see if data was received recently. If it has been then we
+ * continue waiting, otherwise, we abort the command.
  */
 static void fc_fcp_timeout(unsigned long data)
 {
 	struct fc_fcp_pkt *fsp = (struct fc_fcp_pkt *)data;
 	struct fc_rport *rport = fsp->rport;
-	struct fc_rport_libfc_priv *rp = rport->dd_data;
+	struct fc_rport_libfc_priv *rpriv = rport->dd_data;
 
 	if (fc_fcp_lock_pkt(fsp))
 		return;
@@ -1267,7 +1327,7 @@
 
 	fsp->state |= FC_SRB_FCP_PROCESSING_TMO;
 
-	if (rp->flags & FC_RP_FLAGS_REC_SUPPORTED)
+	if (rpriv->flags & FC_RP_FLAGS_REC_SUPPORTED)
 		fc_fcp_rec(fsp);
 	else if (time_after_eq(fsp->last_pkt_time + (FC_SCSI_ER_TIMEOUT / 2),
 			       jiffies))
@@ -1281,39 +1341,40 @@
 	fc_fcp_unlock_pkt(fsp);
 }
 
-/*
- * Send a REC ELS request
+/**
+ * fc_fcp_rec() - Send a REC ELS request
+ * @fsp: The FCP packet to send the REC request on
  */
 static void fc_fcp_rec(struct fc_fcp_pkt *fsp)
 {
-	struct fc_lport *lp;
+	struct fc_lport *lport;
 	struct fc_frame *fp;
 	struct fc_rport *rport;
-	struct fc_rport_libfc_priv *rp;
+	struct fc_rport_libfc_priv *rpriv;
 
-	lp = fsp->lp;
+	lport = fsp->lp;
 	rport = fsp->rport;
-	rp = rport->dd_data;
-	if (!fsp->seq_ptr || rp->rp_state != RPORT_ST_READY) {
+	rpriv = rport->dd_data;
+	if (!fsp->seq_ptr || rpriv->rp_state != RPORT_ST_READY) {
 		fsp->status_code = FC_HRD_ERROR;
 		fsp->io_status = 0;
 		fc_fcp_complete_locked(fsp);
 		return;
 	}
-	fp = fc_frame_alloc(lp, sizeof(struct fc_els_rec));
+	fp = fc_fcp_frame_alloc(lport, sizeof(struct fc_els_rec));
 	if (!fp)
 		goto retry;
 
 	fr_seq(fp) = fsp->seq_ptr;
 	fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, rport->port_id,
-		       fc_host_port_id(rp->local_port->host), FC_TYPE_ELS,
+		       fc_host_port_id(rpriv->local_port->host), FC_TYPE_ELS,
 		       FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
-	if (lp->tt.elsct_send(lp, rport->port_id, fp, ELS_REC, fc_fcp_rec_resp,
-			      fsp, jiffies_to_msecs(FC_SCSI_REC_TOV))) {
+	if (lport->tt.elsct_send(lport, rport->port_id, fp, ELS_REC,
+				 fc_fcp_rec_resp, fsp,
+				 jiffies_to_msecs(FC_SCSI_REC_TOV))) {
 		fc_fcp_pkt_hold(fsp);		/* hold while REC outstanding */
 		return;
 	}
-	fc_frame_free(fp);
 retry:
 	if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
 		fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV);
@@ -1321,12 +1382,16 @@
 		fc_timeout_error(fsp);
 }
 
-/*
- * Receive handler for REC ELS frame
- * if it is a reject then let the scsi layer to handle
- * the timeout. if it is a LS_ACC then if the io was not completed
- * then set the timeout and return otherwise complete the exchange
- * and tell the scsi layer to restart the I/O.
+/**
+ * fc_fcp_rec_resp() - Handler for REC ELS responses
+ * @seq: The sequence the response is on
+ * @fp:	 The response frame
+ * @arg: The FCP packet the response is on
+ *
+ * If the response is a reject then the scsi layer will handle
+ * the timeout. If the response is a LS_ACC then if the I/O was not completed
+ * set the timeout and return. If the I/O was completed then complete the
+ * exchange and tell the SCSI layer.
  */
 static void fc_fcp_rec_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
 {
@@ -1338,7 +1403,7 @@
 	u32 offset;
 	enum dma_data_direction data_dir;
 	enum fc_rctl r_ctl;
-	struct fc_rport_libfc_priv *rp;
+	struct fc_rport_libfc_priv *rpriv;
 
 	if (IS_ERR(fp)) {
 		fc_fcp_rec_error(fsp, fp);
@@ -1361,13 +1426,13 @@
 			/* fall through */
 		case ELS_RJT_UNSUP:
 			FC_FCP_DBG(fsp, "device does not support REC\n");
-			rp = fsp->rport->dd_data;
+			rpriv = fsp->rport->dd_data;
 			/*
 			 * if we do not spport RECs or got some bogus
 			 * reason then resetup timer so we check for
 			 * making progress.
 			 */
-			rp->flags &= ~FC_RP_FLAGS_REC_SUPPORTED;
+			rpriv->flags &= ~FC_RP_FLAGS_REC_SUPPORTED;
 			fc_fcp_timer_set(fsp, FC_SCSI_ER_TIMEOUT);
 			break;
 		case ELS_RJT_LOGIC:
@@ -1464,8 +1529,10 @@
 	fc_frame_free(fp);
 }
 
-/*
- * Handle error response or timeout for REC exchange.
+/**
+ * fc_fcp_rec_error() - Handler for REC errors
+ * @fsp: The FCP packet the error is on
+ * @fp:	 The REC frame
  */
 static void fc_fcp_rec_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
 {
@@ -1504,10 +1571,9 @@
 	fc_fcp_pkt_release(fsp);	/* drop hold for outstanding REC */
 }
 
-/*
- * Time out error routine:
- * abort's the I/O close the exchange and
- * send completion notification to scsi layer
+/**
+ * fc_timeout_error() - Handler for fcp_pkt timeouts
+ * @fsp: The FCP packt that has timed out
  */
 static void fc_timeout_error(struct fc_fcp_pkt *fsp)
 {
@@ -1521,16 +1587,18 @@
 	fc_fcp_send_abort(fsp);
 }
 
-/*
- * Sequence retransmission request.
+/**
+ * fc_fcp_srr() - Send a SRR request (Sequence Retransmission Request)
+ * @fsp:   The FCP packet the SRR is to be sent on
+ * @r_ctl: The R_CTL field for the SRR request
  * This is called after receiving status but insufficient data, or
  * when expecting status but the request has timed out.
  */
 static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset)
 {
-	struct fc_lport *lp = fsp->lp;
+	struct fc_lport *lport = fsp->lp;
 	struct fc_rport *rport;
-	struct fc_rport_libfc_priv *rp;
+	struct fc_rport_libfc_priv *rpriv;
 	struct fc_exch *ep = fc_seq_exch(fsp->seq_ptr);
 	struct fc_seq *seq;
 	struct fcp_srr *srr;
@@ -1538,12 +1606,13 @@
 	u8 cdb_op;
 
 	rport = fsp->rport;
-	rp = rport->dd_data;
+	rpriv = rport->dd_data;
 	cdb_op = fsp->cdb_cmd.fc_cdb[0];
 
-	if (!(rp->flags & FC_RP_FLAGS_RETRY) || rp->rp_state != RPORT_ST_READY)
+	if (!(rpriv->flags & FC_RP_FLAGS_RETRY) ||
+	    rpriv->rp_state != RPORT_ST_READY)
 		goto retry;			/* shouldn't happen */
-	fp = fc_frame_alloc(lp, sizeof(*srr));
+	fp = fc_fcp_frame_alloc(lport, sizeof(*srr));
 	if (!fp)
 		goto retry;
 
@@ -1556,15 +1625,14 @@
 	srr->srr_rel_off = htonl(offset);
 
 	fc_fill_fc_hdr(fp, FC_RCTL_ELS4_REQ, rport->port_id,
-		       fc_host_port_id(rp->local_port->host), FC_TYPE_FCP,
+		       fc_host_port_id(rpriv->local_port->host), FC_TYPE_FCP,
 		       FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
 
-	seq = lp->tt.exch_seq_send(lp, fp, fc_fcp_srr_resp, NULL,
-				   fsp, jiffies_to_msecs(FC_SCSI_REC_TOV));
-	if (!seq) {
-		fc_frame_free(fp);
+	seq = lport->tt.exch_seq_send(lport, fp, fc_fcp_srr_resp, NULL,
+				      fsp, jiffies_to_msecs(FC_SCSI_REC_TOV));
+	if (!seq)
 		goto retry;
-	}
+
 	fsp->recov_seq = seq;
 	fsp->xfer_len = offset;
 	fsp->xfer_contig_end = offset;
@@ -1575,8 +1643,11 @@
 	fc_fcp_retry_cmd(fsp);
 }
 
-/*
- * Handle response from SRR.
+/**
+ * fc_fcp_srr_resp() - Handler for SRR response
+ * @seq: The sequence the SRR is on
+ * @fp:	 The SRR frame
+ * @arg: The FCP packet the SRR is on
  */
 static void fc_fcp_srr_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
 {
@@ -1622,6 +1693,11 @@
 	fc_fcp_pkt_release(fsp);	/* drop hold for outstanding SRR */
 }
 
+/**
+ * fc_fcp_srr_error() - Handler for SRR errors
+ * @fsp: The FCP packet that the SRR error is on
+ * @fp:	 The SRR frame
+ */
 static void fc_fcp_srr_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
 {
 	if (fc_fcp_lock_pkt(fsp))
@@ -1646,31 +1722,36 @@
 	fc_fcp_pkt_release(fsp);	/* drop hold for outstanding SRR */
 }
 
-static inline int fc_fcp_lport_queue_ready(struct fc_lport *lp)
+/**
+ * fc_fcp_lport_queue_ready() - Determine if the lport and it's queue is ready
+ * @lport: The local port to be checked
+ */
+static inline int fc_fcp_lport_queue_ready(struct fc_lport *lport)
 {
 	/* lock ? */
-	return (lp->state == LPORT_ST_READY) && lp->link_up && !lp->qfull;
+	return (lport->state == LPORT_ST_READY) &&
+		lport->link_up && !lport->qfull;
 }
 
 /**
- * fc_queuecommand - The queuecommand function of the scsi template
- * @cmd:	struct scsi_cmnd to be executed
- * @done:	Callback function to be called when cmd is completed
+ * fc_queuecommand() - The queuecommand function of the SCSI template
+ * @cmd:   The scsi_cmnd to be executed
+ * @done:  The callback function to be called when the scsi_cmnd is complete
  *
- * this is the i/o strategy routine, called by the scsi layer
- * this routine is called with holding the host_lock.
+ * This is the i/o strategy routine, called by the SCSI layer. This routine
+ * is called with the host_lock held.
  */
 int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *))
 {
-	struct fc_lport *lp;
+	struct fc_lport *lport;
 	struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
 	struct fc_fcp_pkt *fsp;
-	struct fc_rport_libfc_priv *rp;
+	struct fc_rport_libfc_priv *rpriv;
 	int rval;
 	int rc = 0;
 	struct fcoe_dev_stats *stats;
 
-	lp = shost_priv(sc_cmd->device->host);
+	lport = shost_priv(sc_cmd->device->host);
 
 	rval = fc_remote_port_chkready(rport);
 	if (rval) {
@@ -1689,14 +1770,16 @@
 		goto out;
 	}
 
-	rp = rport->dd_data;
+	rpriv = rport->dd_data;
 
-	if (!fc_fcp_lport_queue_ready(lp)) {
+	if (!fc_fcp_lport_queue_ready(lport)) {
+		if (lport->qfull)
+			fc_fcp_can_queue_ramp_down(lport);
 		rc = SCSI_MLQUEUE_HOST_BUSY;
 		goto out;
 	}
 
-	fsp = fc_fcp_pkt_alloc(lp, GFP_ATOMIC);
+	fsp = fc_fcp_pkt_alloc(lport, GFP_ATOMIC);
 	if (fsp == NULL) {
 		rc = SCSI_MLQUEUE_HOST_BUSY;
 		goto out;
@@ -1706,8 +1789,9 @@
 	 * build the libfc request pkt
 	 */
 	fsp->cmd = sc_cmd;	/* save the cmd */
-	fsp->lp = lp;		/* save the softc ptr */
+	fsp->lp = lport;	/* save the softc ptr */
 	fsp->rport = rport;	/* set the remote port ptr */
+	fsp->xfer_ddp = FC_XID_UNKNOWN;
 	sc_cmd->scsi_done = done;
 
 	/*
@@ -1719,7 +1803,7 @@
 	/*
 	 * setup the data direction
 	 */
-	stats = fc_lport_get_stats(lp);
+	stats = fc_lport_get_stats(lport);
 	if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE) {
 		fsp->req_flags = FC_SRB_READ;
 		stats->InputRequests++;
@@ -1733,7 +1817,7 @@
 		stats->ControlRequests++;
 	}
 
-	fsp->tgt_flags = rp->flags;
+	fsp->tgt_flags = rpriv->flags;
 
 	init_timer(&fsp->timer);
 	fsp->timer.data = (unsigned long)fsp;
@@ -1743,7 +1827,7 @@
 	 * if we get -1 return then put the request in the pending
 	 * queue.
 	 */
-	rval = fc_fcp_pkt_send(lp, fsp);
+	rval = fc_fcp_pkt_send(lport, fsp);
 	if (rval != 0) {
 		fsp->state = FC_SRB_FREE;
 		fc_fcp_pkt_release(fsp);
@@ -1755,18 +1839,17 @@
 EXPORT_SYMBOL(fc_queuecommand);
 
 /**
- * fc_io_compl() -  Handle responses for completed commands
- * @fsp:	scsi packet
+ * fc_io_compl() - Handle responses for completed commands
+ * @fsp: The FCP packet that is complete
  *
- * Translates a error to a Linux SCSI error.
- *
+ * Translates fcp_pkt errors to a Linux SCSI errors.
  * The fcp packet lock must be held when calling.
  */
 static void fc_io_compl(struct fc_fcp_pkt *fsp)
 {
 	struct fc_fcp_internal *si;
 	struct scsi_cmnd *sc_cmd;
-	struct fc_lport *lp;
+	struct fc_lport *lport;
 	unsigned long flags;
 
 	/* release outstanding ddp context */
@@ -1779,28 +1862,26 @@
 		spin_lock_bh(&fsp->scsi_pkt_lock);
 	}
 
-	lp = fsp->lp;
-	si = fc_get_scsi_internal(lp);
-	spin_lock_irqsave(lp->host->host_lock, flags);
+	lport = fsp->lp;
+	si = fc_get_scsi_internal(lport);
+	spin_lock_irqsave(lport->host->host_lock, flags);
 	if (!fsp->cmd) {
-		spin_unlock_irqrestore(lp->host->host_lock, flags);
+		spin_unlock_irqrestore(lport->host->host_lock, flags);
 		return;
 	}
 
 	/*
-	 * if a command timed out while we had to try and throttle IO
-	 * and it is now getting cleaned up, then we are about to
-	 * try again so clear the throttled flag incase we get more
-	 * time outs.
+	 * if can_queue ramp down is done then try can_queue ramp up
+	 * since commands are completing now.
 	 */
-	if (si->throttled && fsp->state & FC_SRB_NOMEM)
-		si->throttled = 0;
+	if (si->last_can_queue_ramp_down_time)
+		fc_fcp_can_queue_ramp_up(lport);
 
 	sc_cmd = fsp->cmd;
 	fsp->cmd = NULL;
 
 	if (!sc_cmd->SCp.ptr) {
-		spin_unlock_irqrestore(lp->host->host_lock, flags);
+		spin_unlock_irqrestore(lport->host->host_lock, flags);
 		return;
 	}
 
@@ -1814,21 +1895,6 @@
 			sc_cmd->result = DID_OK << 16;
 			if (fsp->scsi_resid)
 				CMD_RESID_LEN(sc_cmd) = fsp->scsi_resid;
-		} else if (fsp->cdb_status == QUEUE_FULL) {
-			struct scsi_device *tmp_sdev;
-			struct scsi_device *sdev = sc_cmd->device;
-
-			shost_for_each_device(tmp_sdev, sdev->host) {
-				if (tmp_sdev->id != sdev->id)
-					continue;
-
-				if (tmp_sdev->queue_depth > 1) {
-					scsi_track_queue_full(tmp_sdev,
-							      tmp_sdev->
-							      queue_depth - 1);
-				}
-			}
-			sc_cmd->result = (DID_OK << 16) | fsp->cdb_status;
 		} else {
 			/*
 			 * transport level I/O was ok but scsi
@@ -1846,7 +1912,8 @@
 			 * scsi status is good but transport level
 			 * underrun.
 			 */
-			sc_cmd->result = DID_OK << 16;
+			sc_cmd->result = (fsp->state & FC_SRB_RCV_STATUS ?
+					  DID_OK : DID_ERROR) << 16;
 		} else {
 			/*
 			 * scsi got underrun, this is an error
@@ -1881,60 +1948,42 @@
 	list_del(&fsp->list);
 	sc_cmd->SCp.ptr = NULL;
 	sc_cmd->scsi_done(sc_cmd);
-	spin_unlock_irqrestore(lp->host->host_lock, flags);
+	spin_unlock_irqrestore(lport->host->host_lock, flags);
 
 	/* release ref from initial allocation in queue command */
 	fc_fcp_pkt_release(fsp);
 }
 
 /**
- * fc_fcp_complete() - complete processing of a fcp packet
- * @fsp:	fcp packet
- *
- * This function may sleep if a fsp timer is pending.
- * The host lock must not be held by caller.
- */
-void fc_fcp_complete(struct fc_fcp_pkt *fsp)
-{
-	if (fc_fcp_lock_pkt(fsp))
-		return;
-
-	fc_fcp_complete_locked(fsp);
-	fc_fcp_unlock_pkt(fsp);
-}
-EXPORT_SYMBOL(fc_fcp_complete);
-
-/**
  * fc_eh_abort() - Abort a command
- * @sc_cmd:	scsi command to abort
+ * @sc_cmd: The SCSI command to abort
  *
- * From scsi host template.
- * send ABTS to the target device  and wait for the response
- * sc_cmd is the pointer to the command to be aborted.
+ * From SCSI host template.
+ * Send an ABTS to the target device and wait for the response.
  */
 int fc_eh_abort(struct scsi_cmnd *sc_cmd)
 {
 	struct fc_fcp_pkt *fsp;
-	struct fc_lport *lp;
+	struct fc_lport *lport;
 	int rc = FAILED;
 	unsigned long flags;
 
-	lp = shost_priv(sc_cmd->device->host);
-	if (lp->state != LPORT_ST_READY)
+	lport = shost_priv(sc_cmd->device->host);
+	if (lport->state != LPORT_ST_READY)
 		return rc;
-	else if (!lp->link_up)
+	else if (!lport->link_up)
 		return rc;
 
-	spin_lock_irqsave(lp->host->host_lock, flags);
+	spin_lock_irqsave(lport->host->host_lock, flags);
 	fsp = CMD_SP(sc_cmd);
 	if (!fsp) {
 		/* command completed while scsi eh was setting up */
-		spin_unlock_irqrestore(lp->host->host_lock, flags);
+		spin_unlock_irqrestore(lport->host->host_lock, flags);
 		return SUCCESS;
 	}
 	/* grab a ref so the fsp and sc_cmd cannot be relased from under us */
 	fc_fcp_pkt_hold(fsp);
-	spin_unlock_irqrestore(lp->host->host_lock, flags);
+	spin_unlock_irqrestore(lport->host->host_lock, flags);
 
 	if (fc_fcp_lock_pkt(fsp)) {
 		/* completed while we were waiting for timer to be deleted */
@@ -1942,7 +1991,7 @@
 		goto release_pkt;
 	}
 
-	rc = fc_fcp_pkt_abort(lp, fsp);
+	rc = fc_fcp_pkt_abort(fsp);
 	fc_fcp_unlock_pkt(fsp);
 
 release_pkt:
@@ -1952,37 +2001,34 @@
 EXPORT_SYMBOL(fc_eh_abort);
 
 /**
- * fc_eh_device_reset() Reset a single LUN
- * @sc_cmd:	scsi command
+ * fc_eh_device_reset() - Reset a single LUN
+ * @sc_cmd: The SCSI command which identifies the device whose
+ *	    LUN is to be reset
  *
- * Set from scsi host template to send tm cmd to the target and wait for the
- * response.
+ * Set from SCSI host template.
  */
 int fc_eh_device_reset(struct scsi_cmnd *sc_cmd)
 {
-	struct fc_lport *lp;
+	struct fc_lport *lport;
 	struct fc_fcp_pkt *fsp;
 	struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
 	int rc = FAILED;
-	struct fc_rport_libfc_priv *rp;
 	int rval;
 
 	rval = fc_remote_port_chkready(rport);
 	if (rval)
 		goto out;
 
-	rp = rport->dd_data;
-	lp = shost_priv(sc_cmd->device->host);
+	lport = shost_priv(sc_cmd->device->host);
 
-	if (lp->state != LPORT_ST_READY)
+	if (lport->state != LPORT_ST_READY)
 		return rc;
 
-	FC_SCSI_DBG(lp, "Resetting rport (%6x)\n", rport->port_id);
+	FC_SCSI_DBG(lport, "Resetting rport (%6x)\n", rport->port_id);
 
-	fsp = fc_fcp_pkt_alloc(lp, GFP_NOIO);
+	fsp = fc_fcp_pkt_alloc(lport, GFP_NOIO);
 	if (fsp == NULL) {
 		printk(KERN_WARNING "libfc: could not allocate scsi_pkt\n");
-		sc_cmd->result = DID_NO_CONNECT << 16;
 		goto out;
 	}
 
@@ -1991,13 +2037,13 @@
 	 * the sc passed in is not setup for execution like when sent
 	 * through the queuecommand callout.
 	 */
-	fsp->lp = lp;		/* save the softc ptr */
+	fsp->lp = lport;	/* save the softc ptr */
 	fsp->rport = rport;	/* set the remote port ptr */
 
 	/*
 	 * flush outstanding commands
 	 */
-	rc = fc_lun_reset(lp, fsp, scmd_id(sc_cmd), sc_cmd->device->lun);
+	rc = fc_lun_reset(lport, fsp, scmd_id(sc_cmd), sc_cmd->device->lun);
 	fsp->state = FC_SRB_FREE;
 	fc_fcp_pkt_release(fsp);
 
@@ -2007,38 +2053,39 @@
 EXPORT_SYMBOL(fc_eh_device_reset);
 
 /**
- * fc_eh_host_reset() - The reset function will reset the ports on the host.
- * @sc_cmd:	scsi command
+ * fc_eh_host_reset() - Reset a Scsi_Host.
+ * @sc_cmd: The SCSI command that identifies the SCSI host to be reset
  */
 int fc_eh_host_reset(struct scsi_cmnd *sc_cmd)
 {
 	struct Scsi_Host *shost = sc_cmd->device->host;
-	struct fc_lport *lp = shost_priv(shost);
+	struct fc_lport *lport = shost_priv(shost);
 	unsigned long wait_tmo;
 
-	FC_SCSI_DBG(lp, "Resetting host\n");
+	FC_SCSI_DBG(lport, "Resetting host\n");
 
-	lp->tt.lport_reset(lp);
+	lport->tt.lport_reset(lport);
 	wait_tmo = jiffies + FC_HOST_RESET_TIMEOUT;
-	while (!fc_fcp_lport_queue_ready(lp) && time_before(jiffies, wait_tmo))
+	while (!fc_fcp_lport_queue_ready(lport) && time_before(jiffies,
+							       wait_tmo))
 		msleep(1000);
 
-	if (fc_fcp_lport_queue_ready(lp)) {
+	if (fc_fcp_lport_queue_ready(lport)) {
 		shost_printk(KERN_INFO, shost, "libfc: Host reset succeeded "
-			     "on port (%6x)\n", fc_host_port_id(lp->host));
+			     "on port (%6x)\n", fc_host_port_id(lport->host));
 		return SUCCESS;
 	} else {
 		shost_printk(KERN_INFO, shost, "libfc: Host reset failed, "
 			     "port (%6x) is not ready.\n",
-			     fc_host_port_id(lp->host));
+			     fc_host_port_id(lport->host));
 		return FAILED;
 	}
 }
 EXPORT_SYMBOL(fc_eh_host_reset);
 
 /**
- * fc_slave_alloc() - configure queue depth
- * @sdev:	scsi device
+ * fc_slave_alloc() - Configure the queue depth of a Scsi_Host
+ * @sdev: The SCSI device that identifies the SCSI host
  *
  * Configures queue depth based on host's cmd_per_len. If not set
  * then we use the libfc default.
@@ -2046,29 +2093,50 @@
 int fc_slave_alloc(struct scsi_device *sdev)
 {
 	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
-	int queue_depth;
 
 	if (!rport || fc_remote_port_chkready(rport))
 		return -ENXIO;
 
-	if (sdev->tagged_supported) {
-		if (sdev->host->hostt->cmd_per_lun)
-			queue_depth = sdev->host->hostt->cmd_per_lun;
-		else
-			queue_depth = FC_FCP_DFLT_QUEUE_DEPTH;
-		scsi_activate_tcq(sdev, queue_depth);
-	}
+	if (sdev->tagged_supported)
+		scsi_activate_tcq(sdev, FC_FCP_DFLT_QUEUE_DEPTH);
+	else
+		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev),
+					FC_FCP_DFLT_QUEUE_DEPTH);
+
 	return 0;
 }
 EXPORT_SYMBOL(fc_slave_alloc);
 
-int fc_change_queue_depth(struct scsi_device *sdev, int qdepth)
+/**
+ * fc_change_queue_depth() - Change a device's queue depth
+ * @sdev:   The SCSI device whose queue depth is to change
+ * @qdepth: The new queue depth
+ * @reason: The resason for the change
+ */
+int fc_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
 {
-	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+	switch (reason) {
+	case SCSI_QDEPTH_DEFAULT:
+		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+		break;
+	case SCSI_QDEPTH_QFULL:
+		scsi_track_queue_full(sdev, qdepth);
+		break;
+	case SCSI_QDEPTH_RAMP_UP:
+		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
 	return sdev->queue_depth;
 }
 EXPORT_SYMBOL(fc_change_queue_depth);
 
+/**
+ * fc_change_queue_type() - Change a device's queue type
+ * @sdev:     The SCSI device whose queue depth is to change
+ * @tag_type: Identifier for queue type
+ */
 int fc_change_queue_type(struct scsi_device *sdev, int tag_type)
 {
 	if (sdev->tagged_supported) {
@@ -2084,38 +2152,69 @@
 }
 EXPORT_SYMBOL(fc_change_queue_type);
 
-void fc_fcp_destroy(struct fc_lport *lp)
+/**
+ * fc_fcp_destory() - Tear down the FCP layer for a given local port
+ * @lport: The local port that no longer needs the FCP layer
+ */
+void fc_fcp_destroy(struct fc_lport *lport)
 {
-	struct fc_fcp_internal *si = fc_get_scsi_internal(lp);
+	struct fc_fcp_internal *si = fc_get_scsi_internal(lport);
 
 	if (!list_empty(&si->scsi_pkt_queue))
 		printk(KERN_ERR "libfc: Leaked SCSI packets when destroying "
-		       "port (%6x)\n", fc_host_port_id(lp->host));
+		       "port (%6x)\n", fc_host_port_id(lport->host));
 
 	mempool_destroy(si->scsi_pkt_pool);
 	kfree(si);
-	lp->scsi_priv = NULL;
+	lport->scsi_priv = NULL;
 }
 EXPORT_SYMBOL(fc_fcp_destroy);
 
-int fc_fcp_init(struct fc_lport *lp)
+int fc_setup_fcp()
+{
+	int rc = 0;
+
+	scsi_pkt_cachep = kmem_cache_create("libfc_fcp_pkt",
+					    sizeof(struct fc_fcp_pkt),
+					    0, SLAB_HWCACHE_ALIGN, NULL);
+	if (!scsi_pkt_cachep) {
+		printk(KERN_ERR "libfc: Unable to allocate SRB cache, "
+		       "module load failed!");
+		rc = -ENOMEM;
+	}
+
+	return rc;
+}
+
+void fc_destroy_fcp()
+{
+	if (scsi_pkt_cachep)
+		kmem_cache_destroy(scsi_pkt_cachep);
+}
+
+/**
+ * fc_fcp_init() - Initialize the FCP layer for a local port
+ * @lport: The local port to initialize the exchange layer for
+ */
+int fc_fcp_init(struct fc_lport *lport)
 {
 	int rc;
 	struct fc_fcp_internal *si;
 
-	if (!lp->tt.fcp_cmd_send)
-		lp->tt.fcp_cmd_send = fc_fcp_cmd_send;
+	if (!lport->tt.fcp_cmd_send)
+		lport->tt.fcp_cmd_send = fc_fcp_cmd_send;
 
-	if (!lp->tt.fcp_cleanup)
-		lp->tt.fcp_cleanup = fc_fcp_cleanup;
+	if (!lport->tt.fcp_cleanup)
+		lport->tt.fcp_cleanup = fc_fcp_cleanup;
 
-	if (!lp->tt.fcp_abort_io)
-		lp->tt.fcp_abort_io = fc_fcp_abort_io;
+	if (!lport->tt.fcp_abort_io)
+		lport->tt.fcp_abort_io = fc_fcp_abort_io;
 
 	si = kzalloc(sizeof(struct fc_fcp_internal), GFP_KERNEL);
 	if (!si)
 		return -ENOMEM;
-	lp->scsi_priv = si;
+	lport->scsi_priv = si;
+	si->max_can_queue = lport->host->can_queue;
 	INIT_LIST_HEAD(&si->scsi_pkt_queue);
 
 	si->scsi_pkt_pool = mempool_create_slab_pool(2, scsi_pkt_cachep);
@@ -2130,42 +2229,3 @@
 	return rc;
 }
 EXPORT_SYMBOL(fc_fcp_init);
-
-static int __init libfc_init(void)
-{
-	int rc;
-
-	scsi_pkt_cachep = kmem_cache_create("libfc_fcp_pkt",
-					    sizeof(struct fc_fcp_pkt),
-					    0, SLAB_HWCACHE_ALIGN, NULL);
-	if (scsi_pkt_cachep == NULL) {
-		printk(KERN_ERR "libfc: Unable to allocate SRB cache, "
-		       "module load failed!");
-		return -ENOMEM;
-	}
-
-	rc = fc_setup_exch_mgr();
-	if (rc)
-		goto destroy_pkt_cache;
-
-	rc = fc_setup_rport();
-	if (rc)
-		goto destroy_em;
-
-	return rc;
-destroy_em:
-	fc_destroy_exch_mgr();
-destroy_pkt_cache:
-	kmem_cache_destroy(scsi_pkt_cachep);
-	return rc;
-}
-
-static void __exit libfc_exit(void)
-{
-	kmem_cache_destroy(scsi_pkt_cachep);
-	fc_destroy_exch_mgr();
-	fc_destroy_rport();
-}
-
-module_init(libfc_init);
-module_exit(libfc_exit);
diff --git a/drivers/scsi/libfc/fc_frame.c b/drivers/scsi/libfc/fc_frame.c
index 63fe00c..6da01c6 100644
--- a/drivers/scsi/libfc/fc_frame.c
+++ b/drivers/scsi/libfc/fc_frame.c
@@ -51,24 +51,24 @@
  * Allocate a frame intended to be sent via fcoe_xmit.
  * Get an sk_buff for the frame and set the length.
  */
-struct fc_frame *__fc_frame_alloc(size_t len)
+struct fc_frame *_fc_frame_alloc(size_t len)
 {
 	struct fc_frame *fp;
 	struct sk_buff *skb;
 
 	WARN_ON((len % sizeof(u32)) != 0);
 	len += sizeof(struct fc_frame_header);
-	skb = dev_alloc_skb(len + FC_FRAME_HEADROOM + FC_FRAME_TAILROOM);
+	skb = alloc_skb_fclone(len + FC_FRAME_HEADROOM + FC_FRAME_TAILROOM +
+			       NET_SKB_PAD, GFP_ATOMIC);
 	if (!skb)
 		return NULL;
+	skb_reserve(skb, NET_SKB_PAD + FC_FRAME_HEADROOM);
 	fp = (struct fc_frame *) skb;
 	fc_frame_init(fp);
-	skb_reserve(skb, FC_FRAME_HEADROOM);
 	skb_put(skb, len);
 	return fp;
 }
-EXPORT_SYMBOL(__fc_frame_alloc);
-
+EXPORT_SYMBOL(_fc_frame_alloc);
 
 struct fc_frame *fc_frame_alloc_fill(struct fc_lport *lp, size_t payload_len)
 {
@@ -78,7 +78,7 @@
 	fill = payload_len % 4;
 	if (fill != 0)
 		fill = 4 - fill;
-	fp = __fc_frame_alloc(payload_len + fill);
+	fp = _fc_frame_alloc(payload_len + fill);
 	if (fp) {
 		memset((char *) fr_hdr(fp) + payload_len, 0, fill);
 		/* trim is OK, we just allocated it so there are no fragments */
@@ -87,3 +87,4 @@
 	}
 	return fp;
 }
+EXPORT_SYMBOL(fc_frame_alloc_fill);
diff --git a/drivers/scsi/libfc/fc_libfc.c b/drivers/scsi/libfc/fc_libfc.c
new file mode 100644
index 0000000..39f4b6a
--- /dev/null
+++ b/drivers/scsi/libfc/fc_libfc.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright(c) 2009 Intel Corporation. All rights reserved.
+ *
+ * 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Maintained at www.Open-FCoE.org
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/scatterlist.h>
+#include <linux/crc32.h>
+
+#include <scsi/libfc.h>
+
+#include "fc_libfc.h"
+
+MODULE_AUTHOR("Open-FCoE.org");
+MODULE_DESCRIPTION("libfc");
+MODULE_LICENSE("GPL v2");
+
+unsigned int fc_debug_logging;
+module_param_named(debug_logging, fc_debug_logging, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels");
+
+/**
+ * libfc_init() - Initialize libfc.ko
+ */
+static int __init libfc_init(void)
+{
+	int rc = 0;
+
+	rc = fc_setup_fcp();
+	if (rc)
+		return rc;
+
+	rc = fc_setup_exch_mgr();
+	if (rc)
+		goto destroy_pkt_cache;
+
+	rc = fc_setup_rport();
+	if (rc)
+		goto destroy_em;
+
+	return rc;
+destroy_em:
+	fc_destroy_exch_mgr();
+destroy_pkt_cache:
+	fc_destroy_fcp();
+	return rc;
+}
+module_init(libfc_init);
+
+/**
+ * libfc_exit() - Tear down libfc.ko
+ */
+static void __exit libfc_exit(void)
+{
+	fc_destroy_fcp();
+	fc_destroy_exch_mgr();
+	fc_destroy_rport();
+}
+module_exit(libfc_exit);
+
+/**
+ * fc_copy_buffer_to_sglist() - This routine copies the data of a buffer
+ *				into a scatter-gather list (SG list).
+ *
+ * @buf: pointer to the data buffer.
+ * @len: the byte-length of the data buffer.
+ * @sg: pointer to the pointer of the SG list.
+ * @nents: pointer to the remaining number of entries in the SG list.
+ * @offset: pointer to the current offset in the SG list.
+ * @km_type: dedicated page table slot type for kmap_atomic.
+ * @crc: pointer to the 32-bit crc value.
+ *	 If crc is NULL, CRC is not calculated.
+ */
+u32 fc_copy_buffer_to_sglist(void *buf, size_t len,
+			     struct scatterlist *sg,
+			     u32 *nents, size_t *offset,
+			     enum km_type km_type, u32 *crc)
+{
+	size_t remaining = len;
+	u32 copy_len = 0;
+
+	while (remaining > 0 && sg) {
+		size_t off, sg_bytes;
+		void *page_addr;
+
+		if (*offset >= sg->length) {
+			/*
+			 * Check for end and drop resources
+			 * from the last iteration.
+			 */
+			if (!(*nents))
+				break;
+			--(*nents);
+			*offset -= sg->length;
+			sg = sg_next(sg);
+			continue;
+		}
+		sg_bytes = min(remaining, sg->length - *offset);
+
+		/*
+		 * The scatterlist item may be bigger than PAGE_SIZE,
+		 * but we are limited to mapping PAGE_SIZE at a time.
+		 */
+		off = *offset + sg->offset;
+		sg_bytes = min(sg_bytes,
+			       (size_t)(PAGE_SIZE - (off & ~PAGE_MASK)));
+		page_addr = kmap_atomic(sg_page(sg) + (off >> PAGE_SHIFT),
+					km_type);
+		if (crc)
+			*crc = crc32(*crc, buf, sg_bytes);
+		memcpy((char *)page_addr + (off & ~PAGE_MASK), buf, sg_bytes);
+		kunmap_atomic(page_addr, km_type);
+		buf += sg_bytes;
+		*offset += sg_bytes;
+		remaining -= sg_bytes;
+		copy_len += sg_bytes;
+	}
+	return copy_len;
+}
diff --git a/drivers/scsi/libfc/fc_libfc.h b/drivers/scsi/libfc/fc_libfc.h
new file mode 100644
index 0000000..741fd5c
--- /dev/null
+++ b/drivers/scsi/libfc/fc_libfc.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright(c) 2009 Intel Corporation. All rights reserved.
+ *
+ * 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Maintained at www.Open-FCoE.org
+ */
+
+#ifndef _FC_LIBFC_H_
+#define _FC_LIBFC_H_
+
+#define FC_LIBFC_LOGGING 0x01 /* General logging, not categorized */
+#define FC_LPORT_LOGGING 0x02 /* lport layer logging */
+#define FC_DISC_LOGGING	 0x04 /* discovery layer logging */
+#define FC_RPORT_LOGGING 0x08 /* rport layer logging */
+#define FC_FCP_LOGGING	 0x10 /* I/O path logging */
+#define FC_EM_LOGGING	 0x20 /* Exchange Manager logging */
+#define FC_EXCH_LOGGING	 0x40 /* Exchange/Sequence logging */
+#define FC_SCSI_LOGGING	 0x80 /* SCSI logging (mostly error handling) */
+
+extern unsigned int fc_debug_logging;
+
+#define FC_CHECK_LOGGING(LEVEL, CMD)			\
+	do {						\
+		if (unlikely(fc_debug_logging & LEVEL))	\
+			do {				\
+				CMD;			\
+			} while (0);			\
+	} while (0)
+
+#define FC_LIBFC_DBG(fmt, args...)					\
+	FC_CHECK_LOGGING(FC_LIBFC_LOGGING,				\
+			 printk(KERN_INFO "libfc: " fmt, ##args))
+
+#define FC_LPORT_DBG(lport, fmt, args...)				\
+	FC_CHECK_LOGGING(FC_LPORT_LOGGING,				\
+			 printk(KERN_INFO "host%u: lport %6x: " fmt,	\
+				(lport)->host->host_no,			\
+				fc_host_port_id((lport)->host), ##args))
+
+#define FC_DISC_DBG(disc, fmt, args...)				\
+	FC_CHECK_LOGGING(FC_DISC_LOGGING,			\
+			 printk(KERN_INFO "host%u: disc: " fmt,	\
+				(disc)->lport->host->host_no,	\
+				##args))
+
+#define FC_RPORT_ID_DBG(lport, port_id, fmt, args...)			\
+	FC_CHECK_LOGGING(FC_RPORT_LOGGING,				\
+			 printk(KERN_INFO "host%u: rport %6x: " fmt,	\
+				(lport)->host->host_no,			\
+				(port_id), ##args))
+
+#define FC_RPORT_DBG(rdata, fmt, args...)				\
+	FC_RPORT_ID_DBG((rdata)->local_port, (rdata)->ids.port_id, fmt, ##args)
+
+#define FC_FCP_DBG(pkt, fmt, args...)					\
+	FC_CHECK_LOGGING(FC_FCP_LOGGING,				\
+			 printk(KERN_INFO "host%u: fcp: %6x: " fmt,	\
+				(pkt)->lp->host->host_no,		\
+				pkt->rport->port_id, ##args))
+
+#define FC_EXCH_DBG(exch, fmt, args...)					\
+	FC_CHECK_LOGGING(FC_EXCH_LOGGING,				\
+			 printk(KERN_INFO "host%u: xid %4x: " fmt,	\
+				(exch)->lp->host->host_no,		\
+				exch->xid, ##args))
+
+#define FC_SCSI_DBG(lport, fmt, args...)				\
+	FC_CHECK_LOGGING(FC_SCSI_LOGGING,				\
+			 printk(KERN_INFO "host%u: scsi: " fmt,		\
+				(lport)->host->host_no,	##args))
+
+/*
+ * Set up direct-data placement for this I/O request
+ */
+void fc_fcp_ddp_setup(struct fc_fcp_pkt *fsp, u16 xid);
+
+/*
+ * Module setup functions
+ */
+int fc_setup_exch_mgr(void);
+void fc_destroy_exch_mgr(void);
+int fc_setup_rport(void);
+void fc_destroy_rport(void);
+int fc_setup_fcp(void);
+void fc_destroy_fcp(void);
+
+/*
+ * Internal libfc functions
+ */
+const char *fc_els_resp_type(struct fc_frame *);
+
+/*
+ * Copies a buffer into an sg list
+ */
+u32 fc_copy_buffer_to_sglist(void *buf, size_t len,
+			     struct scatterlist *sg,
+			     u32 *nents, size_t *offset,
+			     enum km_type km_type, u32 *crc);
+
+#endif /* _FC_LIBFC_H_ */
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index bd2f771..74338c8 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -56,7 +56,7 @@
  * at the same time.
  *
  * When discovery succeeds or fails a callback is made to the lport as
- * notification. Currently, succesful discovery causes the lport to take no
+ * notification. Currently, successful discovery causes the lport to take no
  * action. A failure will cause the lport to reset. There is likely a circular
  * locking problem with this implementation.
  */
@@ -94,6 +94,9 @@
 
 #include <scsi/libfc.h>
 #include <scsi/fc_encode.h>
+#include <linux/scatterlist.h>
+
+#include "fc_libfc.h"
 
 /* Fabric IDs to use for point-to-point mode, chosen on whims. */
 #define FC_LOCAL_PTP_FID_LO   0x010101
@@ -106,8 +109,7 @@
 static void fc_lport_enter_reset(struct fc_lport *);
 static void fc_lport_enter_flogi(struct fc_lport *);
 static void fc_lport_enter_dns(struct fc_lport *);
-static void fc_lport_enter_rpn_id(struct fc_lport *);
-static void fc_lport_enter_rft_id(struct fc_lport *);
+static void fc_lport_enter_ns(struct fc_lport *, enum fc_lport_state);
 static void fc_lport_enter_scr(struct fc_lport *);
 static void fc_lport_enter_ready(struct fc_lport *);
 static void fc_lport_enter_logo(struct fc_lport *);
@@ -116,14 +118,40 @@
 	[LPORT_ST_DISABLED] = "disabled",
 	[LPORT_ST_FLOGI] =    "FLOGI",
 	[LPORT_ST_DNS] =      "dNS",
-	[LPORT_ST_RPN_ID] =   "RPN_ID",
+	[LPORT_ST_RNN_ID] =   "RNN_ID",
+	[LPORT_ST_RSNN_NN] =  "RSNN_NN",
+	[LPORT_ST_RSPN_ID] =  "RSPN_ID",
 	[LPORT_ST_RFT_ID] =   "RFT_ID",
+	[LPORT_ST_RFF_ID] =   "RFF_ID",
 	[LPORT_ST_SCR] =      "SCR",
 	[LPORT_ST_READY] =    "Ready",
 	[LPORT_ST_LOGO] =     "LOGO",
 	[LPORT_ST_RESET] =    "reset",
 };
 
+/**
+ * struct fc_bsg_info - FC Passthrough managemet structure
+ * @job:      The passthrough job
+ * @lport:    The local port to pass through a command
+ * @rsp_code: The expected response code
+ * @sg:	      job->reply_payload.sg_list
+ * @nents:    job->reply_payload.sg_cnt
+ * @offset:   The offset into the response data
+ */
+struct fc_bsg_info {
+	struct fc_bsg_job *job;
+	struct fc_lport *lport;
+	u16 rsp_code;
+	struct scatterlist *sg;
+	u32 nents;
+	size_t offset;
+};
+
+/**
+ * fc_frame_drop() - Dummy frame handler
+ * @lport: The local port the frame was received on
+ * @fp:	   The received frame
+ */
 static int fc_frame_drop(struct fc_lport *lport, struct fc_frame *fp)
 {
 	fc_frame_free(fp);
@@ -150,8 +178,8 @@
 	switch (event) {
 	case RPORT_EV_READY:
 		if (lport->state == LPORT_ST_DNS) {
-			lport->dns_rp = rdata;
-			fc_lport_enter_rpn_id(lport);
+			lport->dns_rdata = rdata;
+			fc_lport_enter_ns(lport, LPORT_ST_RNN_ID);
 		} else {
 			FC_LPORT_DBG(lport, "Received an READY event "
 				     "on port (%6x) for the directory "
@@ -165,7 +193,7 @@
 	case RPORT_EV_LOGO:
 	case RPORT_EV_FAILED:
 	case RPORT_EV_STOP:
-		lport->dns_rp = NULL;
+		lport->dns_rdata = NULL;
 		break;
 	case RPORT_EV_NONE:
 		break;
@@ -189,8 +217,8 @@
 
 /**
  * fc_lport_ptp_setup() - Create an rport for point-to-point mode
- * @lport: The lport to attach the ptp rport to
- * @fid: The FID of the ptp rport
+ * @lport:	 The lport to attach the ptp rport to
+ * @remote_fid:	 The FID of the ptp rport
  * @remote_wwpn: The WWPN of the ptp rport
  * @remote_wwnn: The WWNN of the ptp rport
  */
@@ -199,18 +227,22 @@
 			       u64 remote_wwnn)
 {
 	mutex_lock(&lport->disc.disc_mutex);
-	if (lport->ptp_rp)
-		lport->tt.rport_logoff(lport->ptp_rp);
-	lport->ptp_rp = lport->tt.rport_create(lport, remote_fid);
-	lport->ptp_rp->ids.port_name = remote_wwpn;
-	lport->ptp_rp->ids.node_name = remote_wwnn;
+	if (lport->ptp_rdata)
+		lport->tt.rport_logoff(lport->ptp_rdata);
+	lport->ptp_rdata = lport->tt.rport_create(lport, remote_fid);
+	lport->ptp_rdata->ids.port_name = remote_wwpn;
+	lport->ptp_rdata->ids.node_name = remote_wwnn;
 	mutex_unlock(&lport->disc.disc_mutex);
 
-	lport->tt.rport_login(lport->ptp_rp);
+	lport->tt.rport_login(lport->ptp_rdata);
 
 	fc_lport_enter_ready(lport);
 }
 
+/**
+ * fc_get_host_port_type() - Return the port type of the given Scsi_Host
+ * @shost: The SCSI host whose port type is to be determined
+ */
 void fc_get_host_port_type(struct Scsi_Host *shost)
 {
 	/* TODO - currently just NPORT */
@@ -218,17 +250,33 @@
 }
 EXPORT_SYMBOL(fc_get_host_port_type);
 
+/**
+ * fc_get_host_port_state() - Return the port state of the given Scsi_Host
+ * @shost:  The SCSI host whose port state is to be determined
+ */
 void fc_get_host_port_state(struct Scsi_Host *shost)
 {
-	struct fc_lport *lp = shost_priv(shost);
+	struct fc_lport *lport = shost_priv(shost);
 
-	if (lp->link_up)
-		fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
+	mutex_lock(&lport->lp_mutex);
+	if (!lport->link_up)
+		fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
 	else
-		fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
+		switch (lport->state) {
+		case LPORT_ST_READY:
+			fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
+			break;
+		default:
+			fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
+		}
+	mutex_unlock(&lport->lp_mutex);
 }
 EXPORT_SYMBOL(fc_get_host_port_state);
 
+/**
+ * fc_get_host_speed() - Return the speed of the given Scsi_Host
+ * @shost: The SCSI host whose port speed is to be determined
+ */
 void fc_get_host_speed(struct Scsi_Host *shost)
 {
 	struct fc_lport *lport = shost_priv(shost);
@@ -237,24 +285,28 @@
 }
 EXPORT_SYMBOL(fc_get_host_speed);
 
+/**
+ * fc_get_host_stats() - Return the Scsi_Host's statistics
+ * @shost: The SCSI host whose statistics are to be returned
+ */
 struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
 {
 	struct fc_host_statistics *fcoe_stats;
-	struct fc_lport *lp = shost_priv(shost);
+	struct fc_lport *lport = shost_priv(shost);
 	struct timespec v0, v1;
 	unsigned int cpu;
 
-	fcoe_stats = &lp->host_stats;
+	fcoe_stats = &lport->host_stats;
 	memset(fcoe_stats, 0, sizeof(struct fc_host_statistics));
 
 	jiffies_to_timespec(jiffies, &v0);
-	jiffies_to_timespec(lp->boot_time, &v1);
+	jiffies_to_timespec(lport->boot_time, &v1);
 	fcoe_stats->seconds_since_last_reset = (v0.tv_sec - v1.tv_sec);
 
 	for_each_possible_cpu(cpu) {
 		struct fcoe_dev_stats *stats;
 
-		stats = per_cpu_ptr(lp->dev_stats, cpu);
+		stats = per_cpu_ptr(lport->dev_stats, cpu);
 
 		fcoe_stats->tx_frames += stats->TxFrames;
 		fcoe_stats->tx_words += stats->TxWords;
@@ -279,12 +331,15 @@
 }
 EXPORT_SYMBOL(fc_get_host_stats);
 
-/*
- * Fill in FLOGI command for request.
+/**
+ * fc_lport_flogi_fill() - Fill in FLOGI command for request
+ * @lport: The local port the FLOGI is for
+ * @flogi: The FLOGI command
+ * @op:	   The opcode
  */
-static void
-fc_lport_flogi_fill(struct fc_lport *lport, struct fc_els_flogi *flogi,
-		    unsigned int op)
+static void fc_lport_flogi_fill(struct fc_lport *lport,
+				struct fc_els_flogi *flogi,
+				unsigned int op)
 {
 	struct fc_els_csp *sp;
 	struct fc_els_cssp *cp;
@@ -312,8 +367,10 @@
 	}
 }
 
-/*
- * Add a supported FC-4 type.
+/**
+ * fc_lport_add_fc4_type() - Add a supported FC-4 type to a local port
+ * @lport: The local port to add a new FC-4 type to
+ * @type:  The new FC-4 type
  */
 static void fc_lport_add_fc4_type(struct fc_lport *lport, enum fc_fh_type type)
 {
@@ -325,11 +382,11 @@
 
 /**
  * fc_lport_recv_rlir_req() - Handle received Registered Link Incident Report.
+ * @sp:	   The sequence in the RLIR exchange
+ * @fp:	   The RLIR request frame
  * @lport: Fibre Channel local port recieving the RLIR
- * @sp: current sequence in the RLIR exchange
- * @fp: RLIR request frame
  *
- * Locking Note: The lport lock is exected to be held before calling
+ * Locking Note: The lport lock is expected to be held before calling
  * this function.
  */
 static void fc_lport_recv_rlir_req(struct fc_seq *sp, struct fc_frame *fp,
@@ -344,11 +401,11 @@
 
 /**
  * fc_lport_recv_echo_req() - Handle received ECHO request
- * @lport: Fibre Channel local port recieving the ECHO
- * @sp: current sequence in the ECHO exchange
- * @fp: ECHO request frame
+ * @sp:	   The sequence in the ECHO exchange
+ * @fp:	   ECHO request frame
+ * @lport: The local port recieving the ECHO
  *
- * Locking Note: The lport lock is exected to be held before calling
+ * Locking Note: The lport lock is expected to be held before calling
  * this function.
  */
 static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
@@ -361,7 +418,7 @@
 	void *dp;
 	u32 f_ctl;
 
-	FC_LPORT_DBG(lport, "Received RLIR request while in state %s\n",
+	FC_LPORT_DBG(lport, "Received ECHO request while in state %s\n",
 		     fc_lport_state(lport));
 
 	len = fr_len(in_fp) - sizeof(struct fc_frame_header);
@@ -374,7 +431,7 @@
 	if (fp) {
 		dp = fc_frame_payload_get(fp, len);
 		memcpy(dp, pp, len);
-		*((u32 *)dp) = htonl(ELS_LS_ACC << 24);
+		*((__be32 *)dp) = htonl(ELS_LS_ACC << 24);
 		sp = lport->tt.seq_start_next(sp);
 		f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ;
 		fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
@@ -385,12 +442,12 @@
 }
 
 /**
- * fc_lport_recv_echo_req() - Handle received Request Node ID data request
- * @lport: Fibre Channel local port recieving the RNID
- * @sp: current sequence in the RNID exchange
- * @fp: RNID request frame
+ * fc_lport_recv_rnid_req() - Handle received Request Node ID data request
+ * @sp:	   The sequence in the RNID exchange
+ * @fp:	   The RNID request frame
+ * @lport: The local port recieving the RNID
  *
- * Locking Note: The lport lock is exected to be held before calling
+ * Locking Note: The lport lock is expected to be held before calling
  * this function.
  */
 static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp,
@@ -453,9 +510,9 @@
 
 /**
  * fc_lport_recv_logo_req() - Handle received fabric LOGO request
- * @lport: Fibre Channel local port recieving the LOGO
- * @sp: current sequence in the LOGO exchange
- * @fp: LOGO request frame
+ * @sp:	   The sequence in the LOGO exchange
+ * @fp:	   The LOGO request frame
+ * @lport: The local port recieving the LOGO
  *
  * Locking Note: The lport lock is exected to be held before calling
  * this function.
@@ -470,7 +527,7 @@
 
 /**
  * fc_fabric_login() - Start the lport state machine
- * @lport: The lport that should log into the fabric
+ * @lport: The local port that should log into the fabric
  *
  * Locking Note: This function should not be called
  *		 with the lport lock held.
@@ -491,47 +548,69 @@
 EXPORT_SYMBOL(fc_fabric_login);
 
 /**
- * fc_linkup() - Handler for transport linkup events
+ * __fc_linkup() - Handler for transport linkup events
  * @lport: The lport whose link is up
+ *
+ * Locking: must be called with the lp_mutex held
  */
-void fc_linkup(struct fc_lport *lport)
+void __fc_linkup(struct fc_lport *lport)
 {
-	printk(KERN_INFO "libfc: Link up on port (%6x)\n",
-	       fc_host_port_id(lport->host));
-
-	mutex_lock(&lport->lp_mutex);
 	if (!lport->link_up) {
 		lport->link_up = 1;
 
 		if (lport->state == LPORT_ST_RESET)
 			fc_lport_enter_flogi(lport);
 	}
+}
+
+/**
+ * fc_linkup() - Handler for transport linkup events
+ * @lport: The local port whose link is up
+ */
+void fc_linkup(struct fc_lport *lport)
+{
+	printk(KERN_INFO "host%d: libfc: Link up on port (%6x)\n",
+	       lport->host->host_no, fc_host_port_id(lport->host));
+
+	mutex_lock(&lport->lp_mutex);
+	__fc_linkup(lport);
 	mutex_unlock(&lport->lp_mutex);
 }
 EXPORT_SYMBOL(fc_linkup);
 
 /**
- * fc_linkdown() - Handler for transport linkdown events
+ * __fc_linkdown() - Handler for transport linkdown events
  * @lport: The lport whose link is down
+ *
+ * Locking: must be called with the lp_mutex held
  */
-void fc_linkdown(struct fc_lport *lport)
+void __fc_linkdown(struct fc_lport *lport)
 {
-	mutex_lock(&lport->lp_mutex);
-	printk(KERN_INFO "libfc: Link down on port (%6x)\n",
-	       fc_host_port_id(lport->host));
-
 	if (lport->link_up) {
 		lport->link_up = 0;
 		fc_lport_enter_reset(lport);
 		lport->tt.fcp_cleanup(lport);
 	}
+}
+
+/**
+ * fc_linkdown() - Handler for transport linkdown events
+ * @lport: The local port whose link is down
+ */
+void fc_linkdown(struct fc_lport *lport)
+{
+	printk(KERN_INFO "host%d: libfc: Link down on port (%6x)\n",
+	       lport->host->host_no, fc_host_port_id(lport->host));
+
+	mutex_lock(&lport->lp_mutex);
+	__fc_linkdown(lport);
 	mutex_unlock(&lport->lp_mutex);
 }
 EXPORT_SYMBOL(fc_linkdown);
 
 /**
  * fc_fabric_logoff() - Logout of the fabric
- * @lport:	      fc_lport pointer to logoff the fabric
+ * @lport: The local port to logoff the fabric
  *
  * Return value:
  *	0 for success, -1 for failure
@@ -540,8 +619,8 @@
 {
 	lport->tt.disc_stop_final(lport);
 	mutex_lock(&lport->lp_mutex);
-	if (lport->dns_rp)
-		lport->tt.rport_logoff(lport->dns_rp);
+	if (lport->dns_rdata)
+		lport->tt.rport_logoff(lport->dns_rdata);
 	mutex_unlock(&lport->lp_mutex);
 	lport->tt.rport_flush_queue();
 	mutex_lock(&lport->lp_mutex);
@@ -553,11 +632,9 @@
 EXPORT_SYMBOL(fc_fabric_logoff);
 
 /**
- * fc_lport_destroy() - unregister a fc_lport
- * @lport:	      fc_lport pointer to unregister
+ * fc_lport_destroy() - Unregister a fc_lport
+ * @lport: The local port to unregister
  *
- * Return value:
- *	None
  * Note:
  * exit routine for fc_lport instance
  * clean-up all the allocated memory
@@ -580,13 +657,9 @@
 EXPORT_SYMBOL(fc_lport_destroy);
 
 /**
- * fc_set_mfs() - sets up the mfs for the corresponding fc_lport
- * @lport: fc_lport pointer to unregister
- * @mfs: the new mfs for fc_lport
- *
- * Set mfs for the given fc_lport to the new mfs.
- *
- * Return: 0 for success
+ * fc_set_mfs() - Set the maximum frame size for a local port
+ * @lport: The local port to set the MFS for
+ * @mfs:   The new MFS
  */
 int fc_set_mfs(struct fc_lport *lport, u32 mfs)
 {
@@ -617,7 +690,7 @@
 
 /**
  * fc_lport_disc_callback() - Callback for discovery events
- * @lport: FC local port
+ * @lport: The local port receiving the event
  * @event: The discovery event
  */
 void fc_lport_disc_callback(struct fc_lport *lport, enum fc_disc_event event)
@@ -627,8 +700,9 @@
 		FC_LPORT_DBG(lport, "Discovery succeeded\n");
 		break;
 	case DISC_EV_FAILED:
-		printk(KERN_ERR "libfc: Discovery failed for port (%6x)\n",
-		       fc_host_port_id(lport->host));
+		printk(KERN_ERR "host%d: libfc: "
+		       "Discovery failed for port (%6x)\n",
+		       lport->host->host_no, fc_host_port_id(lport->host));
 		mutex_lock(&lport->lp_mutex);
 		fc_lport_enter_reset(lport);
 		mutex_unlock(&lport->lp_mutex);
@@ -641,7 +715,7 @@
 
 /**
  * fc_rport_enter_ready() - Enter the ready state and start discovery
- * @lport: Fibre Channel local port that is ready
+ * @lport: The local port that is ready
  *
  * Locking Note: The lport lock is expected to be held before calling
  * this routine.
@@ -652,22 +726,46 @@
 		     fc_lport_state(lport));
 
 	fc_lport_state_enter(lport, LPORT_ST_READY);
+	if (lport->vport)
+		fc_vport_set_state(lport->vport, FC_VPORT_ACTIVE);
+	fc_vports_linkchange(lport);
 
-	if (!lport->ptp_rp)
+	if (!lport->ptp_rdata)
 		lport->tt.disc_start(fc_lport_disc_callback, lport);
 }
 
 /**
+ * fc_lport_set_port_id() - set the local port Port ID
+ * @lport: The local port which will have its Port ID set.
+ * @port_id: The new port ID.
+ * @fp: The frame containing the incoming request, or NULL.
+ *
+ * Locking Note: The lport lock is expected to be held before calling
+ * this function.
+ */
+static void fc_lport_set_port_id(struct fc_lport *lport, u32 port_id,
+				 struct fc_frame *fp)
+{
+	if (port_id)
+		printk(KERN_INFO "host%d: Assigned Port ID %6x\n",
+		       lport->host->host_no, port_id);
+
+	fc_host_port_id(lport->host) = port_id;
+	if (lport->tt.lport_set_port_id)
+		lport->tt.lport_set_port_id(lport, port_id, fp);
+}
+
+/**
  * fc_lport_recv_flogi_req() - Receive a FLOGI request
  * @sp_in: The sequence the FLOGI is on
- * @rx_fp: The frame the FLOGI is in
- * @lport: The lport that recieved the request
+ * @rx_fp: The FLOGI frame
+ * @lport: The local port that recieved the request
  *
  * A received FLOGI request indicates a point-to-point connection.
  * Accept it with the common service parameters indicating our N port.
  * Set up to do a PLOGI if we have the higher-number WWPN.
  *
- * Locking Note: The lport lock is exected to be held before calling
+ * Locking Note: The lport lock is expected to be held before calling
  * this function.
  */
 static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
@@ -695,8 +793,9 @@
 		goto out;
 	remote_wwpn = get_unaligned_be64(&flp->fl_wwpn);
 	if (remote_wwpn == lport->wwpn) {
-		printk(KERN_WARNING "libfc: Received FLOGI from port "
-		       "with same WWPN %llx\n", remote_wwpn);
+		printk(KERN_WARNING "host%d: libfc: Received FLOGI from port "
+		       "with same WWPN %llx\n",
+		       lport->host->host_no, remote_wwpn);
 		goto out;
 	}
 	FC_LPORT_DBG(lport, "FLOGI from port WWPN %llx\n", remote_wwpn);
@@ -715,7 +814,7 @@
 		remote_fid = FC_LOCAL_PTP_FID_HI;
 	}
 
-	fc_host_port_id(lport->host) = local_fid;
+	fc_lport_set_port_id(lport, local_fid, rx_fp);
 
 	fp = fc_frame_alloc(lport, sizeof(*flp));
 	if (fp) {
@@ -747,9 +846,9 @@
 
 /**
  * fc_lport_recv_req() - The generic lport request handler
- * @lport: The lport that received the request
- * @sp: The sequence the request is on
- * @fp: The frame the request is in
+ * @lport: The local port that received the request
+ * @sp:	   The sequence the request is on
+ * @fp:	   The request frame
  *
  * This function will see if the lport handles the request or
  * if an rport should handle the request.
@@ -817,8 +916,8 @@
 }
 
 /**
- * fc_lport_reset() - Reset an lport
- * @lport: The lport which should be reset
+ * fc_lport_reset() - Reset a local port
+ * @lport: The local port which should be reset
  *
  * Locking Note: This functions should not be called with the
  *		 lport lock held.
@@ -834,29 +933,31 @@
 EXPORT_SYMBOL(fc_lport_reset);
 
 /**
- * fc_lport_reset_locked() - Reset the local port
- * @lport: Fibre Channel local port to be reset
+ * fc_lport_reset_locked() - Reset the local port w/ the lport lock held
+ * @lport: The local port to be reset
  *
  * Locking Note: The lport lock is expected to be held before calling
  * this routine.
  */
 static void fc_lport_reset_locked(struct fc_lport *lport)
 {
-	if (lport->dns_rp)
-		lport->tt.rport_logoff(lport->dns_rp);
+	if (lport->dns_rdata)
+		lport->tt.rport_logoff(lport->dns_rdata);
 
-	lport->ptp_rp = NULL;
+	lport->ptp_rdata = NULL;
 
 	lport->tt.disc_stop(lport);
 
 	lport->tt.exch_mgr_reset(lport, 0, 0);
 	fc_host_fabric_name(lport->host) = 0;
-	fc_host_port_id(lport->host) = 0;
+
+	if (fc_host_port_id(lport->host))
+		fc_lport_set_port_id(lport, 0, NULL);
 }
 
 /**
  * fc_lport_enter_reset() - Reset the local port
- * @lport: Fibre Channel local port to be reset
+ * @lport: The local port to be reset
  *
  * Locking Note: The lport lock is expected to be held before calling
  * this routine.
@@ -866,15 +967,22 @@
 	FC_LPORT_DBG(lport, "Entered RESET state from %s state\n",
 		     fc_lport_state(lport));
 
+	if (lport->vport) {
+		if (lport->link_up)
+			fc_vport_set_state(lport->vport, FC_VPORT_INITIALIZING);
+		else
+			fc_vport_set_state(lport->vport, FC_VPORT_LINKDOWN);
+	}
 	fc_lport_state_enter(lport, LPORT_ST_RESET);
+	fc_vports_linkchange(lport);
 	fc_lport_reset_locked(lport);
 	if (lport->link_up)
 		fc_lport_enter_flogi(lport);
 }
 
 /**
- * fc_lport_enter_disabled() - disable the local port
- * @lport: Fibre Channel local port to be reset
+ * fc_lport_enter_disabled() - Disable the local port
+ * @lport: The local port to be reset
  *
  * Locking Note: The lport lock is expected to be held before calling
  * this routine.
@@ -885,13 +993,14 @@
 		     fc_lport_state(lport));
 
 	fc_lport_state_enter(lport, LPORT_ST_DISABLED);
+	fc_vports_linkchange(lport);
 	fc_lport_reset_locked(lport);
 }
 
 /**
  * fc_lport_error() - Handler for any errors
- * @lport: The fc_lport object
- * @fp: The frame pointer
+ * @lport: The local port that the error was on
+ * @fp:	   The error code encoded in a frame pointer
  *
  * If the error was caused by a resource allocation failure
  * then wait for half a second and retry, otherwise retry
@@ -922,8 +1031,11 @@
 			case LPORT_ST_DISABLED:
 			case LPORT_ST_READY:
 			case LPORT_ST_RESET:
-			case LPORT_ST_RPN_ID:
+			case LPORT_ST_RNN_ID:
+			case LPORT_ST_RSNN_NN:
+			case LPORT_ST_RSPN_ID:
 			case LPORT_ST_RFT_ID:
+			case LPORT_ST_RFF_ID:
 			case LPORT_ST_SCR:
 			case LPORT_ST_DNS:
 			case LPORT_ST_FLOGI:
@@ -936,33 +1048,33 @@
 }
 
 /**
- * fc_lport_rft_id_resp() - Handle response to Register Fibre
- *			    Channel Types by ID (RPN_ID) request
- * @sp: current sequence in RPN_ID exchange
- * @fp: response frame
+ * fc_lport_ns_resp() - Handle response to a name server
+ *			registration exchange
+ * @sp:	    current sequence in exchange
+ * @fp:	    response frame
  * @lp_arg: Fibre Channel host port instance
  *
  * Locking Note: This function will be called without the lport lock
- * held, but it will lock, call an _enter_* function or fc_lport_error
+ * held, but it will lock, call an _enter_* function or fc_lport_error()
  * and then unlock the lport.
  */
-static void fc_lport_rft_id_resp(struct fc_seq *sp, struct fc_frame *fp,
-				 void *lp_arg)
+static void fc_lport_ns_resp(struct fc_seq *sp, struct fc_frame *fp,
+			     void *lp_arg)
 {
 	struct fc_lport *lport = lp_arg;
 	struct fc_frame_header *fh;
 	struct fc_ct_hdr *ct;
 
-	FC_LPORT_DBG(lport, "Received a RFT_ID %s\n", fc_els_resp_type(fp));
+	FC_LPORT_DBG(lport, "Received a ns %s\n", fc_els_resp_type(fp));
 
 	if (fp == ERR_PTR(-FC_EX_CLOSED))
 		return;
 
 	mutex_lock(&lport->lp_mutex);
 
-	if (lport->state != LPORT_ST_RFT_ID) {
-		FC_LPORT_DBG(lport, "Received a RFT_ID response, but in state "
-			     "%s\n", fc_lport_state(lport));
+	if (lport->state < LPORT_ST_RNN_ID || lport->state > LPORT_ST_RFF_ID) {
+		FC_LPORT_DBG(lport, "Received a name server response, "
+			     "but in state %s\n", fc_lport_state(lport));
 		if (IS_ERR(fp))
 			goto err;
 		goto out;
@@ -980,7 +1092,26 @@
 	    ct->ct_fs_type == FC_FST_DIR &&
 	    ct->ct_fs_subtype == FC_NS_SUBTYPE &&
 	    ntohs(ct->ct_cmd) == FC_FS_ACC)
-		fc_lport_enter_scr(lport);
+		switch (lport->state) {
+		case LPORT_ST_RNN_ID:
+			fc_lport_enter_ns(lport, LPORT_ST_RSNN_NN);
+			break;
+		case LPORT_ST_RSNN_NN:
+			fc_lport_enter_ns(lport, LPORT_ST_RSPN_ID);
+			break;
+		case LPORT_ST_RSPN_ID:
+			fc_lport_enter_ns(lport, LPORT_ST_RFT_ID);
+			break;
+		case LPORT_ST_RFT_ID:
+			fc_lport_enter_ns(lport, LPORT_ST_RFF_ID);
+			break;
+		case LPORT_ST_RFF_ID:
+			fc_lport_enter_scr(lport);
+			break;
+		default:
+			/* should have already been caught by state checks */
+			break;
+		}
 	else
 		fc_lport_error(lport, fp);
 out:
@@ -990,63 +1121,9 @@
 }
 
 /**
- * fc_lport_rpn_id_resp() - Handle response to Register Port
- *			    Name by ID (RPN_ID) request
- * @sp: current sequence in RPN_ID exchange
- * @fp: response frame
- * @lp_arg: Fibre Channel host port instance
- *
- * Locking Note: This function will be called without the lport lock
- * held, but it will lock, call an _enter_* function or fc_lport_error
- * and then unlock the lport.
- */
-static void fc_lport_rpn_id_resp(struct fc_seq *sp, struct fc_frame *fp,
-				 void *lp_arg)
-{
-	struct fc_lport *lport = lp_arg;
-	struct fc_frame_header *fh;
-	struct fc_ct_hdr *ct;
-
-	FC_LPORT_DBG(lport, "Received a RPN_ID %s\n", fc_els_resp_type(fp));
-
-	if (fp == ERR_PTR(-FC_EX_CLOSED))
-		return;
-
-	mutex_lock(&lport->lp_mutex);
-
-	if (lport->state != LPORT_ST_RPN_ID) {
-		FC_LPORT_DBG(lport, "Received a RPN_ID response, but in state "
-			     "%s\n", fc_lport_state(lport));
-		if (IS_ERR(fp))
-			goto err;
-		goto out;
-	}
-
-	if (IS_ERR(fp)) {
-		fc_lport_error(lport, fp);
-		goto err;
-	}
-
-	fh = fc_frame_header_get(fp);
-	ct = fc_frame_payload_get(fp, sizeof(*ct));
-	if (fh && ct && fh->fh_type == FC_TYPE_CT &&
-	    ct->ct_fs_type == FC_FST_DIR &&
-	    ct->ct_fs_subtype == FC_NS_SUBTYPE &&
-	    ntohs(ct->ct_cmd) == FC_FS_ACC)
-		fc_lport_enter_rft_id(lport);
-	else
-		fc_lport_error(lport, fp);
-
-out:
-	fc_frame_free(fp);
-err:
-	mutex_unlock(&lport->lp_mutex);
-}
-
-/**
  * fc_lport_scr_resp() - Handle response to State Change Register (SCR) request
- * @sp: current sequence in SCR exchange
- * @fp: response frame
+ * @sp:	    current sequence in SCR exchange
+ * @fp:	    response frame
  * @lp_arg: Fibre Channel lport port instance that sent the registration request
  *
  * Locking Note: This function will be called without the lport lock
@@ -1092,8 +1169,8 @@
 }
 
 /**
- * fc_lport_enter_scr() - Send a State Change Register (SCR) request
- * @lport: Fibre Channel local port to register for state changes
+ * fc_lport_enter_scr() - Send a SCR (State Change Register) request
+ * @lport: The local port to register for state changes
  *
  * Locking Note: The lport lock is expected to be held before calling
  * this routine.
@@ -1114,78 +1191,74 @@
 	}
 
 	if (!lport->tt.elsct_send(lport, FC_FID_FCTRL, fp, ELS_SCR,
-				  fc_lport_scr_resp, lport, lport->e_d_tov))
-		fc_lport_error(lport, fp);
+				  fc_lport_scr_resp, lport,
+				  2 * lport->r_a_tov))
+		fc_lport_error(lport, NULL);
 }
 
 /**
- * fc_lport_enter_rft_id() - Register FC4-types with the name server
+ * fc_lport_enter_ns() - register some object with the name server
  * @lport: Fibre Channel local port to register
  *
  * Locking Note: The lport lock is expected to be held before calling
  * this routine.
  */
-static void fc_lport_enter_rft_id(struct fc_lport *lport)
+static void fc_lport_enter_ns(struct fc_lport *lport, enum fc_lport_state state)
 {
 	struct fc_frame *fp;
-	struct fc_ns_fts *lps;
-	int i;
+	enum fc_ns_req cmd;
+	int size = sizeof(struct fc_ct_hdr);
+	size_t len;
 
-	FC_LPORT_DBG(lport, "Entered RFT_ID state from %s state\n",
+	FC_LPORT_DBG(lport, "Entered %s state from %s state\n",
+		     fc_lport_state_names[state],
 		     fc_lport_state(lport));
 
-	fc_lport_state_enter(lport, LPORT_ST_RFT_ID);
+	fc_lport_state_enter(lport, state);
 
-	lps = &lport->fcts;
-	i = sizeof(lps->ff_type_map) / sizeof(lps->ff_type_map[0]);
-	while (--i >= 0)
-		if (ntohl(lps->ff_type_map[i]) != 0)
-			break;
-	if (i < 0) {
-		/* nothing to register, move on to SCR */
-		fc_lport_enter_scr(lport);
+	switch (state) {
+	case LPORT_ST_RNN_ID:
+		cmd = FC_NS_RNN_ID;
+		size += sizeof(struct fc_ns_rn_id);
+		break;
+	case LPORT_ST_RSNN_NN:
+		len = strnlen(fc_host_symbolic_name(lport->host), 255);
+		/* if there is no symbolic name, skip to RFT_ID */
+		if (!len)
+			return fc_lport_enter_ns(lport, LPORT_ST_RFT_ID);
+		cmd = FC_NS_RSNN_NN;
+		size += sizeof(struct fc_ns_rsnn) + len;
+		break;
+	case LPORT_ST_RSPN_ID:
+		len = strnlen(fc_host_symbolic_name(lport->host), 255);
+		/* if there is no symbolic name, skip to RFT_ID */
+		if (!len)
+			return fc_lport_enter_ns(lport, LPORT_ST_RFT_ID);
+		cmd = FC_NS_RSPN_ID;
+		size += sizeof(struct fc_ns_rspn) + len;
+		break;
+	case LPORT_ST_RFT_ID:
+		cmd = FC_NS_RFT_ID;
+		size += sizeof(struct fc_ns_rft);
+		break;
+	case LPORT_ST_RFF_ID:
+		cmd = FC_NS_RFF_ID;
+		size += sizeof(struct fc_ns_rff_id);
+		break;
+	default:
+		fc_lport_error(lport, NULL);
 		return;
 	}
 
-	fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) +
-			    sizeof(struct fc_ns_rft));
+	fp = fc_frame_alloc(lport, size);
 	if (!fp) {
 		fc_lport_error(lport, fp);
 		return;
 	}
 
-	if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, FC_NS_RFT_ID,
-				  fc_lport_rft_id_resp,
-				  lport, lport->e_d_tov))
-		fc_lport_error(lport, fp);
-}
-
-/**
- * fc_rport_enter_rft_id() - Register port name with the name server
- * @lport: Fibre Channel local port to register
- *
- * Locking Note: The lport lock is expected to be held before calling
- * this routine.
- */
-static void fc_lport_enter_rpn_id(struct fc_lport *lport)
-{
-	struct fc_frame *fp;
-
-	FC_LPORT_DBG(lport, "Entered RPN_ID state from %s state\n",
-		     fc_lport_state(lport));
-
-	fc_lport_state_enter(lport, LPORT_ST_RPN_ID);
-
-	fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) +
-			    sizeof(struct fc_ns_rn_id));
-	if (!fp) {
-		fc_lport_error(lport, fp);
-		return;
-	}
-
-	if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, FC_NS_RPN_ID,
-				  fc_lport_rpn_id_resp,
-				  lport, lport->e_d_tov))
+	if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, cmd,
+				  fc_lport_ns_resp,
+				  lport, 3 * lport->r_a_tov))
 		fc_lport_error(lport, fp);
 }
 
@@ -1194,8 +1267,8 @@
 };
 
 /**
- * fc_rport_enter_dns() - Create a rport to the name server
- * @lport: Fibre Channel local port requesting a rport for the name server
+ * fc_rport_enter_dns() - Create a fc_rport for the name server
+ * @lport: The local port requesting a remote port for the name server
  *
  * Locking Note: The lport lock is expected to be held before calling
  * this routine.
@@ -1224,8 +1297,8 @@
 }
 
 /**
- * fc_lport_timeout() - Handler for the retry_work timer.
- * @work: The work struct of the fc_lport
+ * fc_lport_timeout() - Handler for the retry_work timer
+ * @work: The work struct of the local port
  */
 static void fc_lport_timeout(struct work_struct *work)
 {
@@ -1237,21 +1310,25 @@
 
 	switch (lport->state) {
 	case LPORT_ST_DISABLED:
-	case LPORT_ST_READY:
-	case LPORT_ST_RESET:
 		WARN_ON(1);
 		break;
+	case LPORT_ST_READY:
+		WARN_ON(1);
+		break;
+	case LPORT_ST_RESET:
+		break;
 	case LPORT_ST_FLOGI:
 		fc_lport_enter_flogi(lport);
 		break;
 	case LPORT_ST_DNS:
 		fc_lport_enter_dns(lport);
 		break;
-	case LPORT_ST_RPN_ID:
-		fc_lport_enter_rpn_id(lport);
-		break;
+	case LPORT_ST_RNN_ID:
+	case LPORT_ST_RSNN_NN:
+	case LPORT_ST_RSPN_ID:
 	case LPORT_ST_RFT_ID:
-		fc_lport_enter_rft_id(lport);
+	case LPORT_ST_RFF_ID:
+		fc_lport_enter_ns(lport, lport->state);
 		break;
 	case LPORT_ST_SCR:
 		fc_lport_enter_scr(lport);
@@ -1266,16 +1343,16 @@
 
 /**
  * fc_lport_logo_resp() - Handle response to LOGO request
- * @sp: current sequence in LOGO exchange
- * @fp: response frame
- * @lp_arg: Fibre Channel lport port instance that sent the LOGO request
+ * @sp:	    The sequence that the LOGO was on
+ * @fp:	    The LOGO frame
+ * @lp_arg: The lport port that received the LOGO request
  *
  * Locking Note: This function will be called without the lport lock
- * held, but it will lock, call an _enter_* function or fc_lport_error
+ * held, but it will lock, call an _enter_* function or fc_lport_error()
  * and then unlock the lport.
  */
-static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
-			       void *lp_arg)
+void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
+			void *lp_arg)
 {
 	struct fc_lport *lport = lp_arg;
 	u8 op;
@@ -1311,10 +1388,11 @@
 err:
 	mutex_unlock(&lport->lp_mutex);
 }
+EXPORT_SYMBOL(fc_lport_logo_resp);
 
 /**
  * fc_rport_enter_logo() - Logout of the fabric
- * @lport: Fibre Channel local port to be logged out
+ * @lport: The local port to be logged out
  *
  * Locking Note: The lport lock is expected to be held before calling
  * this routine.
@@ -1328,6 +1406,7 @@
 		     fc_lport_state(lport));
 
 	fc_lport_state_enter(lport, LPORT_ST_LOGO);
+	fc_vports_linkchange(lport);
 
 	fp = fc_frame_alloc(lport, sizeof(*logo));
 	if (!fp) {
@@ -1336,22 +1415,23 @@
 	}
 
 	if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_LOGO,
-				  fc_lport_logo_resp, lport, lport->e_d_tov))
-		fc_lport_error(lport, fp);
+				  fc_lport_logo_resp, lport,
+				  2 * lport->r_a_tov))
+		fc_lport_error(lport, NULL);
 }
 
 /**
  * fc_lport_flogi_resp() - Handle response to FLOGI request
- * @sp: current sequence in FLOGI exchange
- * @fp: response frame
- * @lp_arg: Fibre Channel lport port instance that sent the FLOGI request
+ * @sp:	    The sequence that the FLOGI was on
+ * @fp:	    The FLOGI response frame
+ * @lp_arg: The lport port that received the FLOGI response
  *
  * Locking Note: This function will be called without the lport lock
- * held, but it will lock, call an _enter_* function or fc_lport_error
+ * held, but it will lock, call an _enter_* function or fc_lport_error()
  * and then unlock the lport.
  */
-static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
-				void *lp_arg)
+void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
+			 void *lp_arg)
 {
 	struct fc_lport *lport = lp_arg;
 	struct fc_frame_header *fh;
@@ -1385,11 +1465,6 @@
 	fh = fc_frame_header_get(fp);
 	did = ntoh24(fh->fh_d_id);
 	if (fc_frame_payload_op(fp) == ELS_LS_ACC && did != 0) {
-
-		printk(KERN_INFO "libfc: Assigned FID (%6x) in FLOGI response\n",
-		       did);
-		fc_host_port_id(lport->host) = did;
-
 		flp = fc_frame_payload_get(fp, sizeof(*flp));
 		if (flp) {
 			mfs = ntohs(flp->fl_csp.sp_bb_data) &
@@ -1402,12 +1477,18 @@
 			e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov);
 			if (csp_flags & FC_SP_FT_EDTR)
 				e_d_tov /= 1000000;
+
+			lport->npiv_enabled = !!(csp_flags & FC_SP_FT_NPIV_ACC);
+
 			if ((csp_flags & FC_SP_FT_FPORT) == 0) {
 				if (e_d_tov > lport->e_d_tov)
 					lport->e_d_tov = e_d_tov;
 				lport->r_a_tov = 2 * e_d_tov;
-				printk(KERN_INFO "libfc: Port (%6x) entered "
-				       "point to point mode\n", did);
+				fc_lport_set_port_id(lport, did, fp);
+				printk(KERN_INFO "host%d: libfc: "
+				       "Port (%6x) entered "
+				       "point-to-point mode\n",
+				       lport->host->host_no, did);
 				fc_lport_ptp_setup(lport, ntoh24(fh->fh_s_id),
 						   get_unaligned_be64(
 							   &flp->fl_wwpn),
@@ -1418,6 +1499,7 @@
 				lport->r_a_tov = r_a_tov;
 				fc_host_fabric_name(lport->host) =
 					get_unaligned_be64(&flp->fl_wwnn);
+				fc_lport_set_port_id(lport, did, fp);
 				fc_lport_enter_dns(lport);
 			}
 		}
@@ -1430,6 +1512,7 @@
 err:
 	mutex_unlock(&lport->lp_mutex);
 }
+EXPORT_SYMBOL(fc_lport_flogi_resp);
 
 /**
  * fc_rport_enter_flogi() - Send a FLOGI request to the fabric manager
@@ -1451,12 +1534,18 @@
 	if (!fp)
 		return fc_lport_error(lport, fp);
 
-	if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_FLOGI,
-				  fc_lport_flogi_resp, lport, lport->e_d_tov))
-		fc_lport_error(lport, fp);
+	if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp,
+				  lport->vport ? ELS_FDISC : ELS_FLOGI,
+				  fc_lport_flogi_resp, lport,
+				  lport->vport ? 2 * lport->r_a_tov :
+				  lport->e_d_tov))
+		fc_lport_error(lport, NULL);
 }
 
-/* Configure a fc_lport */
+/**
+ * fc_lport_config() - Configure a fc_lport
+ * @lport: The local port to be configured
+ */
 int fc_lport_config(struct fc_lport *lport)
 {
 	INIT_DELAYED_WORK(&lport->retry_work, fc_lport_timeout);
@@ -1471,6 +1560,10 @@
 }
 EXPORT_SYMBOL(fc_lport_config);
 
+/**
+ * fc_lport_init() - Initialize the lport layer for a local port
+ * @lport: The local port to initialize the exchange layer for
+ */
 int fc_lport_init(struct fc_lport *lport)
 {
 	if (!lport->tt.lport_recv)
@@ -1500,7 +1593,253 @@
 	if (lport->link_supported_speeds & FC_PORTSPEED_10GBIT)
 		fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_10GBIT;
 
-	INIT_LIST_HEAD(&lport->ema_list);
 	return 0;
 }
 EXPORT_SYMBOL(fc_lport_init);
+
+/**
+ * fc_lport_bsg_resp() - The common response handler for FC Passthrough requests
+ * @sp:	      The sequence for the FC Passthrough response
+ * @fp:	      The response frame
+ * @info_arg: The BSG info that the response is for
+ */
+static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
+			      void *info_arg)
+{
+	struct fc_bsg_info *info = info_arg;
+	struct fc_bsg_job *job = info->job;
+	struct fc_lport *lport = info->lport;
+	struct fc_frame_header *fh;
+	size_t len;
+	void *buf;
+
+	if (IS_ERR(fp)) {
+		job->reply->result = (PTR_ERR(fp) == -FC_EX_CLOSED) ?
+			-ECONNABORTED : -ETIMEDOUT;
+		job->reply_len = sizeof(uint32_t);
+		job->state_flags |= FC_RQST_STATE_DONE;
+		job->job_done(job);
+		kfree(info);
+		return;
+	}
+
+	mutex_lock(&lport->lp_mutex);
+	fh = fc_frame_header_get(fp);
+	len = fr_len(fp) - sizeof(*fh);
+	buf = fc_frame_payload_get(fp, 0);
+
+	if (fr_sof(fp) == FC_SOF_I3 && !ntohs(fh->fh_seq_cnt)) {
+		/* Get the response code from the first frame payload */
+		unsigned short cmd = (info->rsp_code == FC_FS_ACC) ?
+			ntohs(((struct fc_ct_hdr *)buf)->ct_cmd) :
+			(unsigned short)fc_frame_payload_op(fp);
+
+		/* Save the reply status of the job */
+		job->reply->reply_data.ctels_reply.status =
+			(cmd == info->rsp_code) ?
+			FC_CTELS_STATUS_OK : FC_CTELS_STATUS_REJECT;
+	}
+
+	job->reply->reply_payload_rcv_len +=
+		fc_copy_buffer_to_sglist(buf, len, info->sg, &info->nents,
+					 &info->offset, KM_BIO_SRC_IRQ, NULL);
+
+	if (fr_eof(fp) == FC_EOF_T &&
+	    (ntoh24(fh->fh_f_ctl) & (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) ==
+	    (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) {
+		if (job->reply->reply_payload_rcv_len >
+		    job->reply_payload.payload_len)
+			job->reply->reply_payload_rcv_len =
+				job->reply_payload.payload_len;
+		job->reply->result = 0;
+		job->state_flags |= FC_RQST_STATE_DONE;
+		job->job_done(job);
+		kfree(info);
+	}
+	fc_frame_free(fp);
+	mutex_unlock(&lport->lp_mutex);
+}
+
+/**
+ * fc_lport_els_request() - Send ELS passthrough request
+ * @job:   The BSG Passthrough job
+ * @lport: The local port sending the request
+ * @did:   The destination port id
+ *
+ * Locking Note: The lport lock is expected to be held before calling
+ * this routine.
+ */
+static int fc_lport_els_request(struct fc_bsg_job *job,
+				struct fc_lport *lport,
+				u32 did, u32 tov)
+{
+	struct fc_bsg_info *info;
+	struct fc_frame *fp;
+	struct fc_frame_header *fh;
+	char *pp;
+	int len;
+
+	fp = fc_frame_alloc(lport, job->request_payload.payload_len);
+	if (!fp)
+		return -ENOMEM;
+
+	len = job->request_payload.payload_len;
+	pp = fc_frame_payload_get(fp, len);
+
+	sg_copy_to_buffer(job->request_payload.sg_list,
+			  job->request_payload.sg_cnt,
+			  pp, len);
+
+	fh = fc_frame_header_get(fp);
+	fh->fh_r_ctl = FC_RCTL_ELS_REQ;
+	hton24(fh->fh_d_id, did);
+	hton24(fh->fh_s_id, fc_host_port_id(lport->host));
+	fh->fh_type = FC_TYPE_ELS;
+	hton24(fh->fh_f_ctl, FC_FC_FIRST_SEQ |
+	       FC_FC_END_SEQ | FC_FC_SEQ_INIT);
+	fh->fh_cs_ctl = 0;
+	fh->fh_df_ctl = 0;
+	fh->fh_parm_offset = 0;
+
+	info = kzalloc(sizeof(struct fc_bsg_info), GFP_KERNEL);
+	if (!info) {
+		fc_frame_free(fp);
+		return -ENOMEM;
+	}
+
+	info->job = job;
+	info->lport = lport;
+	info->rsp_code = ELS_LS_ACC;
+	info->nents = job->reply_payload.sg_cnt;
+	info->sg = job->reply_payload.sg_list;
+
+	if (!lport->tt.exch_seq_send(lport, fp, fc_lport_bsg_resp,
+				     NULL, info, tov))
+		return -ECOMM;
+	return 0;
+}
+
+/**
+ * fc_lport_ct_request() - Send CT Passthrough request
+ * @job:   The BSG Passthrough job
+ * @lport: The local port sending the request
+ * @did:   The destination FC-ID
+ * @tov:   The timeout period to wait for the response
+ *
+ * Locking Note: The lport lock is expected to be held before calling
+ * this routine.
+ */
+static int fc_lport_ct_request(struct fc_bsg_job *job,
+			       struct fc_lport *lport, u32 did, u32 tov)
+{
+	struct fc_bsg_info *info;
+	struct fc_frame *fp;
+	struct fc_frame_header *fh;
+	struct fc_ct_req *ct;
+	size_t len;
+
+	fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) +
+			    job->request_payload.payload_len);
+	if (!fp)
+		return -ENOMEM;
+
+	len = job->request_payload.payload_len;
+	ct = fc_frame_payload_get(fp, len);
+
+	sg_copy_to_buffer(job->request_payload.sg_list,
+			  job->request_payload.sg_cnt,
+			  ct, len);
+
+	fh = fc_frame_header_get(fp);
+	fh->fh_r_ctl = FC_RCTL_DD_UNSOL_CTL;
+	hton24(fh->fh_d_id, did);
+	hton24(fh->fh_s_id, fc_host_port_id(lport->host));
+	fh->fh_type = FC_TYPE_CT;
+	hton24(fh->fh_f_ctl, FC_FC_FIRST_SEQ |
+	       FC_FC_END_SEQ | FC_FC_SEQ_INIT);
+	fh->fh_cs_ctl = 0;
+	fh->fh_df_ctl = 0;
+	fh->fh_parm_offset = 0;
+
+	info = kzalloc(sizeof(struct fc_bsg_info), GFP_KERNEL);
+	if (!info) {
+		fc_frame_free(fp);
+		return -ENOMEM;
+	}
+
+	info->job = job;
+	info->lport = lport;
+	info->rsp_code = FC_FS_ACC;
+	info->nents = job->reply_payload.sg_cnt;
+	info->sg = job->reply_payload.sg_list;
+
+	if (!lport->tt.exch_seq_send(lport, fp, fc_lport_bsg_resp,
+				     NULL, info, tov))
+		return -ECOMM;
+	return 0;
+}
+
+/**
+ * fc_lport_bsg_request() - The common entry point for sending
+ *			    FC Passthrough requests
+ * @job: The BSG passthrough job
+ */
+int fc_lport_bsg_request(struct fc_bsg_job *job)
+{
+	struct request *rsp = job->req->next_rq;
+	struct Scsi_Host *shost = job->shost;
+	struct fc_lport *lport = shost_priv(shost);
+	struct fc_rport *rport;
+	struct fc_rport_priv *rdata;
+	int rc = -EINVAL;
+	u32 did;
+
+	job->reply->reply_payload_rcv_len = 0;
+	rsp->resid_len = job->reply_payload.payload_len;
+
+	mutex_lock(&lport->lp_mutex);
+
+	switch (job->request->msgcode) {
+	case FC_BSG_RPT_ELS:
+		rport = job->rport;
+		if (!rport)
+			break;
+
+		rdata = rport->dd_data;
+		rc = fc_lport_els_request(job, lport, rport->port_id,
+					  rdata->e_d_tov);
+		break;
+
+	case FC_BSG_RPT_CT:
+		rport = job->rport;
+		if (!rport)
+			break;
+
+		rdata = rport->dd_data;
+		rc = fc_lport_ct_request(job, lport, rport->port_id,
+					 rdata->e_d_tov);
+		break;
+
+	case FC_BSG_HST_CT:
+		did = ntoh24(job->request->rqst_data.h_ct.port_id);
+		if (did == FC_FID_DIR_SERV)
+			rdata = lport->dns_rdata;
+		else
+			rdata = lport->tt.rport_lookup(lport, did);
+
+		if (!rdata)
+			break;
+
+		rc = fc_lport_ct_request(job, lport, did, rdata->e_d_tov);
+		break;
+
+	case FC_BSG_HST_ELS_NOLOGIN:
+		did = ntoh24(job->request->rqst_data.h_els.port_id);
+		rc = fc_lport_els_request(job, lport, did, lport->e_d_tov);
+		break;
+	}
+
+	mutex_unlock(&lport->lp_mutex);
+	return rc;
+}
+EXPORT_SYMBOL(fc_lport_bsg_request);
diff --git a/drivers/scsi/libfc/fc_npiv.c b/drivers/scsi/libfc/fc_npiv.c
new file mode 100644
index 0000000..c68f6c7
--- /dev/null
+++ b/drivers/scsi/libfc/fc_npiv.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright(c) 2009 Intel Corporation. All rights reserved.
+ *
+ * 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Maintained at www.Open-FCoE.org
+ */
+
+/*
+ * NPIV VN_Port helper functions for libfc
+ */
+
+#include <scsi/libfc.h>
+
+/**
+ * fc_vport_create() - Create a new NPIV vport instance
+ * @vport: fc_vport structure from scsi_transport_fc
+ * @privsize: driver private data size to allocate along with the Scsi_Host
+ */
+
+struct fc_lport *libfc_vport_create(struct fc_vport *vport, int privsize)
+{
+	struct Scsi_Host *shost = vport_to_shost(vport);
+	struct fc_lport *n_port = shost_priv(shost);
+	struct fc_lport *vn_port;
+
+	vn_port = libfc_host_alloc(shost->hostt, privsize);
+	if (!vn_port)
+		goto err_out;
+	if (fc_exch_mgr_list_clone(n_port, vn_port))
+		goto err_put;
+
+	vn_port->vport = vport;
+	vport->dd_data = vn_port;
+
+	mutex_lock(&n_port->lp_mutex);
+	list_add_tail(&vn_port->list, &n_port->vports);
+	mutex_unlock(&n_port->lp_mutex);
+
+	return vn_port;
+
+err_put:
+	scsi_host_put(vn_port->host);
+err_out:
+	return NULL;
+}
+EXPORT_SYMBOL(libfc_vport_create);
+
+/**
+ * fc_vport_id_lookup() - find NPIV lport that matches a given fabric ID
+ * @n_port: Top level N_Port which may have multiple NPIV VN_Ports
+ * @port_id: Fabric ID to find a match for
+ *
+ * Returns: matching lport pointer or NULL if there is no match
+ */
+struct fc_lport *fc_vport_id_lookup(struct fc_lport *n_port, u32 port_id)
+{
+	struct fc_lport *lport = NULL;
+	struct fc_lport *vn_port;
+
+	if (fc_host_port_id(n_port->host) == port_id)
+		return n_port;
+
+	mutex_lock(&n_port->lp_mutex);
+	list_for_each_entry(vn_port, &n_port->vports, list) {
+		if (fc_host_port_id(vn_port->host) == port_id) {
+			lport = vn_port;
+			break;
+		}
+	}
+	mutex_unlock(&n_port->lp_mutex);
+
+	return lport;
+}
+
+/*
+ * When setting the link state of vports during an lport state change, it's
+ * necessary to hold the lp_mutex of both the N_Port and the VN_Port.
+ * This tells the lockdep engine to treat the nested locking of the VN_Port
+ * as a different lock class.
+ */
+enum libfc_lport_mutex_class {
+	LPORT_MUTEX_NORMAL = 0,
+	LPORT_MUTEX_VN_PORT = 1,
+};
+
+/**
+ * __fc_vport_setlink() - update link and status on a VN_Port
+ * @n_port: parent N_Port
+ * @vn_port: VN_Port to update
+ *
+ * Locking: must be called with both the N_Port and VN_Port lp_mutex held
+ */
+static void __fc_vport_setlink(struct fc_lport *n_port,
+			       struct fc_lport *vn_port)
+{
+	struct fc_vport *vport = vn_port->vport;
+
+	if (vn_port->state == LPORT_ST_DISABLED)
+		return;
+
+	if (n_port->state == LPORT_ST_READY) {
+		if (n_port->npiv_enabled) {
+			fc_vport_set_state(vport, FC_VPORT_INITIALIZING);
+			__fc_linkup(vn_port);
+		} else {
+			fc_vport_set_state(vport, FC_VPORT_NO_FABRIC_SUPP);
+			__fc_linkdown(vn_port);
+		}
+	} else {
+		fc_vport_set_state(vport, FC_VPORT_LINKDOWN);
+		__fc_linkdown(vn_port);
+	}
+}
+
+/**
+ * fc_vport_setlink() - update link and status on a VN_Port
+ * @vn_port: virtual port to update
+ */
+void fc_vport_setlink(struct fc_lport *vn_port)
+{
+	struct fc_vport *vport = vn_port->vport;
+	struct Scsi_Host *shost = vport_to_shost(vport);
+	struct fc_lport *n_port = shost_priv(shost);
+
+	mutex_lock(&n_port->lp_mutex);
+	mutex_lock_nested(&vn_port->lp_mutex, LPORT_MUTEX_VN_PORT);
+	__fc_vport_setlink(n_port, vn_port);
+	mutex_unlock(&vn_port->lp_mutex);
+	mutex_unlock(&n_port->lp_mutex);
+}
+EXPORT_SYMBOL(fc_vport_setlink);
+
+/**
+ * fc_vports_linkchange() - change the link state of all vports
+ * @n_port: Parent N_Port that has changed state
+ *
+ * Locking: called with the n_port lp_mutex held
+ */
+void fc_vports_linkchange(struct fc_lport *n_port)
+{
+	struct fc_lport *vn_port;
+
+	list_for_each_entry(vn_port, &n_port->vports, list) {
+		mutex_lock_nested(&vn_port->lp_mutex, LPORT_MUTEX_VN_PORT);
+		__fc_vport_setlink(n_port, vn_port);
+		mutex_unlock(&vn_port->lp_mutex);
+	}
+}
+
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index 03ea674..35ca0e7 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -55,6 +55,8 @@
 #include <scsi/libfc.h>
 #include <scsi/fc_encode.h>
 
+#include "fc_libfc.h"
+
 struct workqueue_struct *rport_event_queue;
 
 static void fc_rport_enter_plogi(struct fc_rport_priv *);
@@ -86,12 +88,13 @@
 	[RPORT_ST_LOGO] = "LOGO",
 	[RPORT_ST_ADISC] = "ADISC",
 	[RPORT_ST_DELETE] = "Delete",
+	[RPORT_ST_RESTART] = "Restart",
 };
 
 /**
- * fc_rport_lookup() - lookup a remote port by port_id
- * @lport: Fibre Channel host port instance
- * @port_id: remote port port_id to match
+ * fc_rport_lookup() - Lookup a remote port by port_id
+ * @lport:   The local port to lookup the remote port on
+ * @port_id: The remote port ID to look up
  */
 static struct fc_rport_priv *fc_rport_lookup(const struct fc_lport *lport,
 					     u32 port_id)
@@ -99,16 +102,17 @@
 	struct fc_rport_priv *rdata;
 
 	list_for_each_entry(rdata, &lport->disc.rports, peers)
-		if (rdata->ids.port_id == port_id &&
-		    rdata->rp_state != RPORT_ST_DELETE)
+		if (rdata->ids.port_id == port_id)
 			return rdata;
 	return NULL;
 }
 
 /**
  * fc_rport_create() - Create a new remote port
- * @lport:   The local port that the new remote port is for
- * @port_id: The port ID for the new remote port
+ * @lport: The local port this remote port will be associated with
+ * @ids:   The identifiers for the new remote port
+ *
+ * The remote port will start in the INIT state.
  *
  * Locking note:  must be called with the disc_mutex held.
  */
@@ -147,8 +151,8 @@
 }
 
 /**
- * fc_rport_destroy() - free a remote port after last reference is released.
- * @kref: pointer to kref inside struct fc_rport_priv
+ * fc_rport_destroy() - Free a remote port after last reference is released
+ * @kref: The remote port's kref
  */
 static void fc_rport_destroy(struct kref *kref)
 {
@@ -159,8 +163,8 @@
 }
 
 /**
- * fc_rport_state() - return a string for the state the rport is in
- * @rdata: remote port private data
+ * fc_rport_state() - Return a string identifying the remote port's state
+ * @rdata: The remote port
  */
 static const char *fc_rport_state(struct fc_rport_priv *rdata)
 {
@@ -173,9 +177,9 @@
 }
 
 /**
- * fc_set_rport_loss_tmo() - Set the remote port loss timeout in seconds.
- * @rport: Pointer to Fibre Channel remote port structure
- * @timeout: timeout in seconds
+ * fc_set_rport_loss_tmo() - Set the remote port loss timeout
+ * @rport:   The remote port that gets a new timeout value
+ * @timeout: The new timeout value (in seconds)
  */
 void fc_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout)
 {
@@ -187,9 +191,11 @@
 EXPORT_SYMBOL(fc_set_rport_loss_tmo);
 
 /**
- * fc_plogi_get_maxframe() - Get max payload from the common service parameters
- * @flp: FLOGI payload structure
- * @maxval: upper limit, may be less than what is in the service parameters
+ * fc_plogi_get_maxframe() - Get the maximum payload from the common service
+ *			     parameters in a FLOGI frame
+ * @flp:    The FLOGI payload
+ * @maxval: The maximum frame size upper limit; this may be less than what
+ *	    is in the service parameters
  */
 static unsigned int fc_plogi_get_maxframe(struct fc_els_flogi *flp,
 					  unsigned int maxval)
@@ -210,9 +216,9 @@
 }
 
 /**
- * fc_rport_state_enter() - Change the rport's state
- * @rdata: The rport whose state should change
- * @new: The new state of the rport
+ * fc_rport_state_enter() - Change the state of a remote port
+ * @rdata: The remote port whose state should change
+ * @new:   The new state
  *
  * Locking Note: Called with the rport lock held
  */
@@ -224,17 +230,22 @@
 	rdata->rp_state = new;
 }
 
+/**
+ * fc_rport_work() - Handler for remote port events in the rport_event_queue
+ * @work: Handle to the remote port being dequeued
+ */
 static void fc_rport_work(struct work_struct *work)
 {
 	u32 port_id;
 	struct fc_rport_priv *rdata =
 		container_of(work, struct fc_rport_priv, event_work);
-	struct fc_rport_libfc_priv *rp;
+	struct fc_rport_libfc_priv *rpriv;
 	enum fc_rport_event event;
 	struct fc_lport *lport = rdata->local_port;
 	struct fc_rport_operations *rport_ops;
 	struct fc_rport_identifiers ids;
 	struct fc_rport *rport;
+	int restart = 0;
 
 	mutex_lock(&rdata->rp_mutex);
 	event = rdata->event;
@@ -265,12 +276,12 @@
 		rport->maxframe_size = rdata->maxframe_size;
 		rport->supported_classes = rdata->supported_classes;
 
-		rp = rport->dd_data;
-		rp->local_port = lport;
-		rp->rp_state = rdata->rp_state;
-		rp->flags = rdata->flags;
-		rp->e_d_tov = rdata->e_d_tov;
-		rp->r_a_tov = rdata->r_a_tov;
+		rpriv = rport->dd_data;
+		rpriv->local_port = lport;
+		rpriv->rp_state = rdata->rp_state;
+		rpriv->flags = rdata->flags;
+		rpriv->e_d_tov = rdata->e_d_tov;
+		rpriv->r_a_tov = rdata->r_a_tov;
 		mutex_unlock(&rdata->rp_mutex);
 
 		if (rport_ops && rport_ops->event_callback) {
@@ -287,8 +298,19 @@
 		mutex_unlock(&rdata->rp_mutex);
 
 		if (port_id != FC_FID_DIR_SERV) {
+			/*
+			 * We must drop rp_mutex before taking disc_mutex.
+			 * Re-evaluate state to allow for restart.
+			 * A transition to RESTART state must only happen
+			 * while disc_mutex is held and rdata is on the list.
+			 */
 			mutex_lock(&lport->disc.disc_mutex);
-			list_del(&rdata->peers);
+			mutex_lock(&rdata->rp_mutex);
+			if (rdata->rp_state == RPORT_ST_RESTART)
+				restart = 1;
+			else
+				list_del(&rdata->peers);
+			mutex_unlock(&rdata->rp_mutex);
 			mutex_unlock(&lport->disc.disc_mutex);
 		}
 
@@ -305,14 +327,20 @@
 		lport->tt.exch_mgr_reset(lport, port_id, 0);
 
 		if (rport) {
-			rp = rport->dd_data;
-			rp->rp_state = RPORT_ST_DELETE;
+			rpriv = rport->dd_data;
+			rpriv->rp_state = RPORT_ST_DELETE;
 			mutex_lock(&rdata->rp_mutex);
 			rdata->rport = NULL;
 			mutex_unlock(&rdata->rp_mutex);
 			fc_remote_port_delete(rport);
 		}
-		kref_put(&rdata->kref, lport->tt.rport_destroy);
+		if (restart) {
+			mutex_lock(&rdata->rp_mutex);
+			FC_RPORT_DBG(rdata, "work restart\n");
+			fc_rport_enter_plogi(rdata);
+			mutex_unlock(&rdata->rp_mutex);
+		} else
+			kref_put(&rdata->kref, lport->tt.rport_destroy);
 		break;
 
 	default:
@@ -323,7 +351,7 @@
 
 /**
  * fc_rport_login() - Start the remote port login state machine
- * @rdata: private remote port
+ * @rdata: The remote port to be logged in to
  *
  * Locking Note: Called without the rport lock held. This
  * function will hold the rport lock, call an _enter_*
@@ -342,6 +370,12 @@
 		FC_RPORT_DBG(rdata, "ADISC port\n");
 		fc_rport_enter_adisc(rdata);
 		break;
+	case RPORT_ST_RESTART:
+		break;
+	case RPORT_ST_DELETE:
+		FC_RPORT_DBG(rdata, "Restart deleted port\n");
+		fc_rport_state_enter(rdata, RPORT_ST_RESTART);
+		break;
 	default:
 		FC_RPORT_DBG(rdata, "Login to port\n");
 		fc_rport_enter_plogi(rdata);
@@ -353,9 +387,9 @@
 }
 
 /**
- * fc_rport_enter_delete() - schedule a remote port to be deleted.
- * @rdata: private remote port
- * @event: event to report as the reason for deletion
+ * fc_rport_enter_delete() - Schedule a remote port to be deleted
+ * @rdata: The remote port to be deleted
+ * @event: The event to report as the reason for deletion
  *
  * Locking Note: Called with the rport lock held.
  *
@@ -382,8 +416,8 @@
 }
 
 /**
- * fc_rport_logoff() - Logoff and remove an rport
- * @rdata: private remote port
+ * fc_rport_logoff() - Logoff and remove a remote port
+ * @rdata: The remote port to be logged off of
  *
  * Locking Note: Called without the rport lock held. This
  * function will hold the rport lock, call an _enter_*
@@ -397,26 +431,27 @@
 
 	if (rdata->rp_state == RPORT_ST_DELETE) {
 		FC_RPORT_DBG(rdata, "Port in Delete state, not removing\n");
-		mutex_unlock(&rdata->rp_mutex);
 		goto out;
 	}
 
-	fc_rport_enter_logo(rdata);
+	if (rdata->rp_state == RPORT_ST_RESTART)
+		FC_RPORT_DBG(rdata, "Port in Restart state, deleting\n");
+	else
+		fc_rport_enter_logo(rdata);
 
 	/*
 	 * Change the state to Delete so that we discard
 	 * the response.
 	 */
 	fc_rport_enter_delete(rdata, RPORT_EV_STOP);
-	mutex_unlock(&rdata->rp_mutex);
-
 out:
+	mutex_unlock(&rdata->rp_mutex);
 	return 0;
 }
 
 /**
- * fc_rport_enter_ready() - The rport is ready
- * @rdata: private remote port
+ * fc_rport_enter_ready() - Transition to the RPORT_ST_READY state
+ * @rdata: The remote port that is ready
  *
  * Locking Note: The rport lock is expected to be held before calling
  * this routine.
@@ -433,8 +468,8 @@
 }
 
 /**
- * fc_rport_timeout() - Handler for the retry_work timer.
- * @work: The work struct of the fc_rport_priv
+ * fc_rport_timeout() - Handler for the retry_work timer
+ * @work: Handle to the remote port that has timed out
  *
  * Locking Note: Called without the rport lock held. This
  * function will hold the rport lock, call an _enter_*
@@ -466,6 +501,7 @@
 	case RPORT_ST_READY:
 	case RPORT_ST_INIT:
 	case RPORT_ST_DELETE:
+	case RPORT_ST_RESTART:
 		break;
 	}
 
@@ -474,8 +510,8 @@
 
 /**
  * fc_rport_error() - Error handler, called once retries have been exhausted
- * @rdata: private remote port
- * @fp: The frame pointer
+ * @rdata: The remote port the error is happened on
+ * @fp:	   The error code encapsulated in a frame pointer
  *
  * Locking Note: The rport lock is expected to be held before
  * calling this routine
@@ -499,6 +535,7 @@
 		fc_rport_enter_logo(rdata);
 		break;
 	case RPORT_ST_DELETE:
+	case RPORT_ST_RESTART:
 	case RPORT_ST_READY:
 	case RPORT_ST_INIT:
 		break;
@@ -506,9 +543,9 @@
 }
 
 /**
- * fc_rport_error_retry() - Error handler when retries are desired
- * @rdata: private remote port data
- * @fp: The frame pointer
+ * fc_rport_error_retry() - Handler for remote port state retries
+ * @rdata: The remote port whose state is to be retried
+ * @fp:	   The error code encapsulated in a frame pointer
  *
  * If the error was an exchange timeout retry immediately,
  * otherwise wait for E_D_TOV.
@@ -540,10 +577,10 @@
 }
 
 /**
- * fc_rport_plogi_recv_resp() - Handle incoming ELS PLOGI response
- * @sp: current sequence in the PLOGI exchange
- * @fp: response frame
- * @rdata_arg: private remote port data
+ * fc_rport_plogi_recv_resp() - Handler for ELS PLOGI responses
+ * @sp:	       The sequence the PLOGI is on
+ * @fp:	       The PLOGI response frame
+ * @rdata_arg: The remote port that sent the PLOGI response
  *
  * Locking Note: This function will be called without the rport lock
  * held, but it will lock, call an _enter_* function or fc_rport_error
@@ -606,8 +643,8 @@
 }
 
 /**
- * fc_rport_enter_plogi() - Send Port Login (PLOGI) request to peer
- * @rdata: private remote port data
+ * fc_rport_enter_plogi() - Send Port Login (PLOGI) request
+ * @rdata: The remote port to send a PLOGI to
  *
  * Locking Note: The rport lock is expected to be held before calling
  * this routine.
@@ -631,17 +668,18 @@
 	rdata->e_d_tov = lport->e_d_tov;
 
 	if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_PLOGI,
-				  fc_rport_plogi_resp, rdata, lport->e_d_tov))
-		fc_rport_error_retry(rdata, fp);
+				  fc_rport_plogi_resp, rdata,
+				  2 * lport->r_a_tov))
+		fc_rport_error_retry(rdata, NULL);
 	else
 		kref_get(&rdata->kref);
 }
 
 /**
  * fc_rport_prli_resp() - Process Login (PRLI) response handler
- * @sp: current sequence in the PRLI exchange
- * @fp: response frame
- * @rdata_arg: private remote port data
+ * @sp:	       The sequence the PRLI response was on
+ * @fp:	       The PRLI response frame
+ * @rdata_arg: The remote port that sent the PRLI response
  *
  * Locking Note: This function will be called without the rport lock
  * held, but it will lock, call an _enter_* function or fc_rport_error
@@ -710,10 +748,10 @@
 }
 
 /**
- * fc_rport_logo_resp() - Logout (LOGO) response handler
- * @sp: current sequence in the LOGO exchange
- * @fp: response frame
- * @rdata_arg: private remote port data
+ * fc_rport_logo_resp() - Handler for logout (LOGO) responses
+ * @sp:	       The sequence the LOGO was on
+ * @fp:	       The LOGO response frame
+ * @rdata_arg: The remote port that sent the LOGO response
  *
  * Locking Note: This function will be called without the rport lock
  * held, but it will lock, call an _enter_* function or fc_rport_error
@@ -756,8 +794,8 @@
 }
 
 /**
- * fc_rport_enter_prli() - Send Process Login (PRLI) request to peer
- * @rdata: private remote port data
+ * fc_rport_enter_prli() - Send Process Login (PRLI) request
+ * @rdata: The remote port to send the PRLI request to
  *
  * Locking Note: The rport lock is expected to be held before calling
  * this routine.
@@ -792,17 +830,18 @@
 	}
 
 	if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_PRLI,
-				  fc_rport_prli_resp, rdata, lport->e_d_tov))
-		fc_rport_error_retry(rdata, fp);
+				  fc_rport_prli_resp, rdata,
+				  2 * lport->r_a_tov))
+		fc_rport_error_retry(rdata, NULL);
 	else
 		kref_get(&rdata->kref);
 }
 
 /**
- * fc_rport_els_rtv_resp() - Request Timeout Value response handler
- * @sp: current sequence in the RTV exchange
- * @fp: response frame
- * @rdata_arg: private remote port data
+ * fc_rport_els_rtv_resp() - Handler for Request Timeout Value (RTV) responses
+ * @sp:	       The sequence the RTV was on
+ * @fp:	       The RTV response frame
+ * @rdata_arg: The remote port that sent the RTV response
  *
  * Many targets don't seem to support this.
  *
@@ -865,8 +904,8 @@
 }
 
 /**
- * fc_rport_enter_rtv() - Send Request Timeout Value (RTV) request to peer
- * @rdata: private remote port data
+ * fc_rport_enter_rtv() - Send Request Timeout Value (RTV) request
+ * @rdata: The remote port to send the RTV request to
  *
  * Locking Note: The rport lock is expected to be held before calling
  * this routine.
@@ -888,15 +927,16 @@
 	}
 
 	if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_RTV,
-				     fc_rport_rtv_resp, rdata, lport->e_d_tov))
-		fc_rport_error_retry(rdata, fp);
+				  fc_rport_rtv_resp, rdata,
+				  2 * lport->r_a_tov))
+		fc_rport_error_retry(rdata, NULL);
 	else
 		kref_get(&rdata->kref);
 }
 
 /**
- * fc_rport_enter_logo() - Send Logout (LOGO) request to peer
- * @rdata: private remote port data
+ * fc_rport_enter_logo() - Send a logout (LOGO) request
+ * @rdata: The remote port to send the LOGO request to
  *
  * Locking Note: The rport lock is expected to be held before calling
  * this routine.
@@ -918,24 +958,25 @@
 	}
 
 	if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_LOGO,
-				  fc_rport_logo_resp, rdata, lport->e_d_tov))
-		fc_rport_error_retry(rdata, fp);
+				  fc_rport_logo_resp, rdata,
+				  2 * lport->r_a_tov))
+		fc_rport_error_retry(rdata, NULL);
 	else
 		kref_get(&rdata->kref);
 }
 
 /**
- * fc_rport_els_adisc_resp() - Address Discovery response handler
- * @sp: current sequence in the ADISC exchange
- * @fp: response frame
- * @rdata_arg: remote port private.
+ * fc_rport_els_adisc_resp() - Handler for Address Discovery (ADISC) responses
+ * @sp:	       The sequence the ADISC response was on
+ * @fp:	       The ADISC response frame
+ * @rdata_arg: The remote port that sent the ADISC response
  *
  * Locking Note: This function will be called without the rport lock
  * held, but it will lock, call an _enter_* function or fc_rport_error
  * and then unlock the rport.
  */
 static void fc_rport_adisc_resp(struct fc_seq *sp, struct fc_frame *fp,
-			      void *rdata_arg)
+				void *rdata_arg)
 {
 	struct fc_rport_priv *rdata = rdata_arg;
 	struct fc_els_adisc *adisc;
@@ -983,8 +1024,8 @@
 }
 
 /**
- * fc_rport_enter_adisc() - Send Address Discover (ADISC) request to peer
- * @rdata: remote port private data
+ * fc_rport_enter_adisc() - Send Address Discover (ADISC) request
+ * @rdata: The remote port to send the ADISC request to
  *
  * Locking Note: The rport lock is expected to be held before calling
  * this routine.
@@ -1005,17 +1046,18 @@
 		return;
 	}
 	if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_ADISC,
-				  fc_rport_adisc_resp, rdata, lport->e_d_tov))
-		fc_rport_error_retry(rdata, fp);
+				  fc_rport_adisc_resp, rdata,
+				  2 * lport->r_a_tov))
+		fc_rport_error_retry(rdata, NULL);
 	else
 		kref_get(&rdata->kref);
 }
 
 /**
- * fc_rport_recv_adisc_req() - Handle incoming Address Discovery (ADISC) Request
- * @rdata: remote port private
- * @sp: current sequence in the ADISC exchange
- * @in_fp: ADISC request frame
+ * fc_rport_recv_adisc_req() - Handler for Address Discovery (ADISC) requests
+ * @rdata: The remote port that sent the ADISC request
+ * @sp:	   The sequence the ADISC request was on
+ * @in_fp: The ADISC request frame
  *
  * Locking Note:  Called with the lport and rport locks held.
  */
@@ -1056,10 +1098,82 @@
 }
 
 /**
- * fc_rport_recv_els_req() - handle a validated ELS request.
- * @lport: Fibre Channel local port
- * @sp: current sequence in the PLOGI exchange
- * @fp: response frame
+ * fc_rport_recv_rls_req() - Handle received Read Link Status request
+ * @rdata: The remote port that sent the RLS request
+ * @sp:	The sequence that the RLS was on
+ * @rx_fp: The PRLI request frame
+ *
+ * Locking Note: The rport lock is expected to be held before calling
+ * this function.
+ */
+static void fc_rport_recv_rls_req(struct fc_rport_priv *rdata,
+				  struct fc_seq *sp, struct fc_frame *rx_fp)
+
+{
+	struct fc_lport *lport = rdata->local_port;
+	struct fc_frame *fp;
+	struct fc_exch *ep = fc_seq_exch(sp);
+	struct fc_els_rls *rls;
+	struct fc_els_rls_resp *rsp;
+	struct fc_els_lesb *lesb;
+	struct fc_seq_els_data rjt_data;
+	struct fc_host_statistics *hst;
+	u32 f_ctl;
+
+	FC_RPORT_DBG(rdata, "Received RLS request while in state %s\n",
+		     fc_rport_state(rdata));
+
+	rls = fc_frame_payload_get(rx_fp, sizeof(*rls));
+	if (!rls) {
+		rjt_data.reason = ELS_RJT_PROT;
+		rjt_data.explan = ELS_EXPL_INV_LEN;
+		goto out_rjt;
+	}
+
+	fp = fc_frame_alloc(lport, sizeof(*rsp));
+	if (!fp) {
+		rjt_data.reason = ELS_RJT_UNAB;
+		rjt_data.explan = ELS_EXPL_INSUF_RES;
+		goto out_rjt;
+	}
+
+	rsp = fc_frame_payload_get(fp, sizeof(*rsp));
+	memset(rsp, 0, sizeof(*rsp));
+	rsp->rls_cmd = ELS_LS_ACC;
+	lesb = &rsp->rls_lesb;
+	if (lport->tt.get_lesb) {
+		/* get LESB from LLD if it supports it */
+		lport->tt.get_lesb(lport, lesb);
+	} else {
+		fc_get_host_stats(lport->host);
+		hst = &lport->host_stats;
+		lesb->lesb_link_fail = htonl(hst->link_failure_count);
+		lesb->lesb_sync_loss = htonl(hst->loss_of_sync_count);
+		lesb->lesb_sig_loss = htonl(hst->loss_of_signal_count);
+		lesb->lesb_prim_err = htonl(hst->prim_seq_protocol_err_count);
+		lesb->lesb_inv_word = htonl(hst->invalid_tx_word_count);
+		lesb->lesb_inv_crc = htonl(hst->invalid_crc_count);
+	}
+
+	sp = lport->tt.seq_start_next(sp);
+	f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ;
+	fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
+		       FC_TYPE_ELS, f_ctl, 0);
+	lport->tt.seq_send(lport, sp, fp);
+	goto out;
+
+out_rjt:
+	rjt_data.fp = NULL;
+	lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
+out:
+	fc_frame_free(rx_fp);
+}
+
+/**
+ * fc_rport_recv_els_req() - Handler for validated ELS requests
+ * @lport: The local port that received the ELS request
+ * @sp:	   The sequence that the ELS request was on
+ * @fp:	   The ELS request frame
  *
  * Handle incoming ELS requests that require port login.
  * The ELS opcode has already been validated by the caller.
@@ -1117,6 +1231,9 @@
 		els_data.fp = fp;
 		lport->tt.seq_els_rsp_send(sp, ELS_REC, &els_data);
 		break;
+	case ELS_RLS:
+		fc_rport_recv_rls_req(rdata, sp, fp);
+		break;
 	default:
 		fc_frame_free(fp);	/* can't happen */
 		break;
@@ -1131,10 +1248,10 @@
 }
 
 /**
- * fc_rport_recv_req() - Handle a received ELS request from a rport
- * @sp: current sequence in the PLOGI exchange
- * @fp: response frame
- * @lport: Fibre Channel local port
+ * fc_rport_recv_req() - Handler for requests
+ * @sp:	   The sequence the request was on
+ * @fp:	   The request frame
+ * @lport: The local port that received the request
  *
  * Locking Note: Called with the lport lock held.
  */
@@ -1161,6 +1278,7 @@
 	case ELS_ADISC:
 	case ELS_RRQ:
 	case ELS_REC:
+	case ELS_RLS:
 		fc_rport_recv_els_req(lport, sp, fp);
 		break;
 	default:
@@ -1174,10 +1292,10 @@
 }
 
 /**
- * fc_rport_recv_plogi_req() - Handle incoming Port Login (PLOGI) request
- * @lport: local port
- * @sp: current sequence in the PLOGI exchange
- * @fp: PLOGI request frame
+ * fc_rport_recv_plogi_req() - Handler for Port Login (PLOGI) requests
+ * @lport: The local port that received the PLOGI request
+ * @sp:	   The sequence that the PLOGI request was on
+ * @rx_fp: The PLOGI request frame
  *
  * Locking Note: The rport lock is held before calling this function.
  */
@@ -1248,6 +1366,7 @@
 		}
 		break;
 	case RPORT_ST_PRLI:
+	case RPORT_ST_RTV:
 	case RPORT_ST_READY:
 	case RPORT_ST_ADISC:
 		FC_RPORT_DBG(rdata, "Received PLOGI in logged-in state %d "
@@ -1255,11 +1374,14 @@
 		/* XXX TBD - should reset */
 		break;
 	case RPORT_ST_DELETE:
-	default:
-		FC_RPORT_DBG(rdata, "Received PLOGI in unexpected state %d\n",
-			     rdata->rp_state);
-		fc_frame_free(rx_fp);
-		goto out;
+	case RPORT_ST_LOGO:
+	case RPORT_ST_RESTART:
+		FC_RPORT_DBG(rdata, "Received PLOGI in state %s - send busy\n",
+			     fc_rport_state(rdata));
+		mutex_unlock(&rdata->rp_mutex);
+		rjt_data.reason = ELS_RJT_BUSY;
+		rjt_data.explan = ELS_EXPL_NONE;
+		goto reject;
 	}
 
 	/*
@@ -1295,10 +1417,10 @@
 }
 
 /**
- * fc_rport_recv_prli_req() - Handle incoming Process Login (PRLI) request
- * @rdata: private remote port data
- * @sp: current sequence in the PRLI exchange
- * @fp: PRLI request frame
+ * fc_rport_recv_prli_req() - Handler for process login (PRLI) requests
+ * @rdata: The remote port that sent the PRLI request
+ * @sp:	   The sequence that the PRLI was on
+ * @rx_fp: The PRLI request frame
  *
  * Locking Note: The rport lock is exected to be held before calling
  * this function.
@@ -1402,7 +1524,7 @@
 				break;
 			case FC_TYPE_FCP:
 				fcp_parm = ntohl(rspp->spp_params);
-				if (fcp_parm * FCP_SPPF_RETRY)
+				if (fcp_parm & FCP_SPPF_RETRY)
 					rdata->flags |= FC_RP_FLAGS_RETRY;
 				rdata->supported_classes = FC_COS_CLASS3;
 				if (fcp_parm & FCP_SPPF_INIT_FCN)
@@ -1452,10 +1574,10 @@
 }
 
 /**
- * fc_rport_recv_prlo_req() - Handle incoming Process Logout (PRLO) request
- * @rdata: private remote port data
- * @sp: current sequence in the PRLO exchange
- * @fp: PRLO request frame
+ * fc_rport_recv_prlo_req() - Handler for process logout (PRLO) requests
+ * @rdata: The remote port that sent the PRLO request
+ * @sp:	   The sequence that the PRLO was on
+ * @fp:	   The PRLO request frame
  *
  * Locking Note: The rport lock is exected to be held before calling
  * this function.
@@ -1482,10 +1604,10 @@
 }
 
 /**
- * fc_rport_recv_logo_req() - Handle incoming Logout (LOGO) request
- * @lport: local port.
- * @sp: current sequence in the LOGO exchange
- * @fp: LOGO request frame
+ * fc_rport_recv_logo_req() - Handler for logout (LOGO) requests
+ * @lport: The local port that received the LOGO request
+ * @sp:	   The sequence that the LOGO request was on
+ * @fp:	   The LOGO request frame
  *
  * Locking Note: The rport lock is exected to be held before calling
  * this function.
@@ -1510,14 +1632,14 @@
 		FC_RPORT_DBG(rdata, "Received LOGO request while in state %s\n",
 			     fc_rport_state(rdata));
 
+		fc_rport_enter_delete(rdata, RPORT_EV_LOGO);
+
 		/*
-		 * If the remote port was created due to discovery,
-		 * log back in.  It may have seen a stale RSCN about us.
+		 * If the remote port was created due to discovery, set state
+		 * to log back in.  It may have seen a stale RSCN about us.
 		 */
-		if (rdata->rp_state != RPORT_ST_DELETE && rdata->disc_id)
-			fc_rport_enter_plogi(rdata);
-		else
-			fc_rport_enter_delete(rdata, RPORT_EV_LOGO);
+		if (rdata->disc_id)
+			fc_rport_state_enter(rdata, RPORT_ST_RESTART);
 		mutex_unlock(&rdata->rp_mutex);
 	} else
 		FC_RPORT_ID_DBG(lport, sid,
@@ -1526,11 +1648,18 @@
 	fc_frame_free(fp);
 }
 
+/**
+ * fc_rport_flush_queue() - Flush the rport_event_queue
+ */
 static void fc_rport_flush_queue(void)
 {
 	flush_workqueue(rport_event_queue);
 }
 
+/**
+ * fc_rport_init() - Initialize the remote port layer for a local port
+ * @lport: The local port to initialize the remote port layer for
+ */
 int fc_rport_init(struct fc_lport *lport)
 {
 	if (!lport->tt.rport_lookup)
@@ -1558,25 +1687,33 @@
 }
 EXPORT_SYMBOL(fc_rport_init);
 
-int fc_setup_rport(void)
+/**
+ * fc_setup_rport() - Initialize the rport_event_queue
+ */
+int fc_setup_rport()
 {
 	rport_event_queue = create_singlethread_workqueue("fc_rport_eq");
 	if (!rport_event_queue)
 		return -ENOMEM;
 	return 0;
 }
-EXPORT_SYMBOL(fc_setup_rport);
 
-void fc_destroy_rport(void)
+/**
+ * fc_destroy_rport() - Destroy the rport_event_queue
+ */
+void fc_destroy_rport()
 {
 	destroy_workqueue(rport_event_queue);
 }
-EXPORT_SYMBOL(fc_destroy_rport);
 
+/**
+ * fc_rport_terminate_io() - Stop all outstanding I/O on a remote port
+ * @rport: The remote port whose I/O should be terminated
+ */
 void fc_rport_terminate_io(struct fc_rport *rport)
 {
-	struct fc_rport_libfc_priv *rp = rport->dd_data;
-	struct fc_lport *lport = rp->local_port;
+	struct fc_rport_libfc_priv *rpriv = rport->dd_data;
+	struct fc_lport *lport = rpriv->local_port;
 
 	lport->tt.exch_mgr_reset(lport, 0, rport->port_id);
 	lport->tt.exch_mgr_reset(lport, rport->port_id, 0);
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index f1a4246..b7689f3 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -266,6 +266,88 @@
 }
 
 /**
+ * iscsi_check_tmf_restrictions - check if a task is affected by TMF
+ * @task: iscsi task
+ * @opcode: opcode to check for
+ *
+ * During TMF a task has to be checked if it's affected.
+ * All unrelated I/O can be passed through, but I/O to the
+ * affected LUN should be restricted.
+ * If 'fast_abort' is set we won't be sending any I/O to the
+ * affected LUN.
+ * Otherwise the target is waiting for all TTTs to be completed,
+ * so we have to send all outstanding Data-Out PDUs to the target.
+ */
+static int iscsi_check_tmf_restrictions(struct iscsi_task *task, int opcode)
+{
+	struct iscsi_conn *conn = task->conn;
+	struct iscsi_tm *tmf = &conn->tmhdr;
+	unsigned int hdr_lun;
+
+	if (conn->tmf_state == TMF_INITIAL)
+		return 0;
+
+	if ((tmf->opcode & ISCSI_OPCODE_MASK) != ISCSI_OP_SCSI_TMFUNC)
+		return 0;
+
+	switch (ISCSI_TM_FUNC_VALUE(tmf)) {
+	case ISCSI_TM_FUNC_LOGICAL_UNIT_RESET:
+		/*
+		 * Allow PDUs for unrelated LUNs
+		 */
+		hdr_lun = scsilun_to_int((struct scsi_lun *)tmf->lun);
+		if (hdr_lun != task->sc->device->lun)
+			return 0;
+		/* fall through */
+	case ISCSI_TM_FUNC_TARGET_WARM_RESET:
+		/*
+		 * Fail all SCSI cmd PDUs
+		 */
+		if (opcode != ISCSI_OP_SCSI_DATA_OUT) {
+			iscsi_conn_printk(KERN_INFO, conn,
+					  "task [op %x/%x itt "
+					  "0x%x/0x%x] "
+					  "rejected.\n",
+					  task->hdr->opcode, opcode,
+					  task->itt, task->hdr_itt);
+			return -EACCES;
+		}
+		/*
+		 * And also all data-out PDUs in response to R2T
+		 * if fast_abort is set.
+		 */
+		if (conn->session->fast_abort) {
+			iscsi_conn_printk(KERN_INFO, conn,
+					  "task [op %x/%x itt "
+					  "0x%x/0x%x] fast abort.\n",
+					  task->hdr->opcode, opcode,
+					  task->itt, task->hdr_itt);
+			return -EACCES;
+		}
+		break;
+	case ISCSI_TM_FUNC_ABORT_TASK:
+		/*
+		 * the caller has already checked if the task
+		 * they want to abort was in the pending queue so if
+		 * we are here the cmd pdu has gone out already, and
+		 * we will only hit this for data-outs
+		 */
+		if (opcode == ISCSI_OP_SCSI_DATA_OUT &&
+		    task->hdr_itt == tmf->rtt) {
+			ISCSI_DBG_SESSION(conn->session,
+					  "Preventing task %x/%x from sending "
+					  "data-out due to abort task in "
+					  "progress\n", task->itt,
+					  task->hdr_itt);
+			return -EACCES;
+		}
+		break;
+	}
+
+	return 0;
+}
+
+/**
  * iscsi_prep_scsi_cmd_pdu - prep iscsi scsi cmd pdu
  * @task: iscsi task
  *
@@ -282,6 +364,10 @@
 	itt_t itt;
 	int rc;
 
+	rc = iscsi_check_tmf_restrictions(task, ISCSI_OP_SCSI_CMD);
+	if (rc)
+		return rc;
+
 	if (conn->session->tt->alloc_pdu) {
 		rc = conn->session->tt->alloc_pdu(task, ISCSI_OP_SCSI_CMD);
 		if (rc)
@@ -577,12 +663,12 @@
 	struct iscsi_session *session = conn->session;
 	struct iscsi_hdr *hdr = task->hdr;
 	struct iscsi_nopout *nop = (struct iscsi_nopout *)hdr;
+	uint8_t opcode = hdr->opcode & ISCSI_OPCODE_MASK;
 
 	if (conn->session->state == ISCSI_STATE_LOGGING_OUT)
 		return -ENOTCONN;
 
-	if (hdr->opcode != (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) &&
-	    hdr->opcode != (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE))
+	if (opcode != ISCSI_OP_LOGIN && opcode != ISCSI_OP_TEXT)
 		nop->exp_statsn = cpu_to_be32(conn->exp_statsn);
 	/*
 	 * pre-format CmdSN for outgoing PDU.
@@ -590,9 +676,12 @@
 	nop->cmdsn = cpu_to_be32(session->cmdsn);
 	if (hdr->itt != RESERVED_ITT) {
 		/*
-		 * TODO: We always use immediate, so we never hit this.
+		 * TODO: We always use immediate for normal session pdus.
 		 * If we start to send tmfs or nops as non-immediate then
 		 * we should start checking the cmdsn numbers for mgmt tasks.
+		 *
+		 * During discovery sessions iscsid sends TEXT as non immediate,
+		 * but we always only send one PDU at a time.
 		 */
 		if (conn->c_stage == ISCSI_CONN_STARTED &&
 		    !(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
@@ -620,22 +709,28 @@
 {
 	struct iscsi_session *session = conn->session;
 	struct iscsi_host *ihost = shost_priv(session->host);
+	uint8_t opcode = hdr->opcode & ISCSI_OPCODE_MASK;
 	struct iscsi_task *task;
 	itt_t itt;
 
 	if (session->state == ISCSI_STATE_TERMINATE)
 		return NULL;
 
-	if (hdr->opcode == (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) ||
-	    hdr->opcode == (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE))
+	if (opcode == ISCSI_OP_LOGIN || opcode == ISCSI_OP_TEXT) {
 		/*
 		 * Login and Text are sent serially, in
 		 * request-followed-by-response sequence.
 		 * Same task can be used. Same ITT must be used.
 		 * Note that login_task is preallocated at conn_create().
 		 */
+		if (conn->login_task->state != ISCSI_TASK_FREE) {
+			iscsi_conn_printk(KERN_ERR, conn, "Login/Text in "
+					  "progress. Cannot start new task.\n");
+			return NULL;
+		}
+
 		task = conn->login_task;
-	else {
+	} else {
 		if (session->state != ISCSI_STATE_LOGGED_IN)
 			return NULL;
 
@@ -1357,6 +1452,7 @@
  **/
 static int iscsi_data_xmit(struct iscsi_conn *conn)
 {
+	struct iscsi_task *task;
 	int rc = 0;
 
 	spin_lock_bh(&conn->session->lock);
@@ -1394,11 +1490,8 @@
 
 	/* process pending command queue */
 	while (!list_empty(&conn->cmdqueue)) {
-		if (conn->tmf_state == TMF_QUEUED)
-			break;
-
-		conn->task = list_entry(conn->cmdqueue.next,
-					 struct iscsi_task, running);
+		conn->task = list_entry(conn->cmdqueue.next, struct iscsi_task,
+					running);
 		list_del_init(&conn->task->running);
 		if (conn->session->state == ISCSI_STATE_LOGGING_OUT) {
 			fail_scsi_task(conn->task, DID_IMM_RETRY);
@@ -1406,7 +1499,7 @@
 		}
 		rc = iscsi_prep_scsi_cmd_pdu(conn->task);
 		if (rc) {
-			if (rc == -ENOMEM) {
+			if (rc == -ENOMEM || rc == -EACCES) {
 				list_add_tail(&conn->task->running,
 					      &conn->cmdqueue);
 				conn->task = NULL;
@@ -1428,17 +1521,18 @@
 	}
 
 	while (!list_empty(&conn->requeue)) {
-		if (conn->session->fast_abort && conn->tmf_state != TMF_INITIAL)
-			break;
-
 		/*
 		 * we always do fastlogout - conn stop code will clean up.
 		 */
 		if (conn->session->state == ISCSI_STATE_LOGGING_OUT)
 			break;
 
-		conn->task = list_entry(conn->requeue.next,
-					 struct iscsi_task, running);
+		task = list_entry(conn->requeue.next, struct iscsi_task,
+				  running);
+		if (iscsi_check_tmf_restrictions(task, ISCSI_OP_SCSI_DATA_OUT))
+			break;
+
+		conn->task = task;
 		list_del_init(&conn->task->running);
 		conn->task->state = ISCSI_TASK_RUNNING;
 		rc = iscsi_xmit_task(conn);
@@ -1591,7 +1685,7 @@
 	if (!ihost->workq) {
 		reason = iscsi_prep_scsi_cmd_pdu(task);
 		if (reason) {
-			if (reason == -ENOMEM) {
+			if (reason == -ENOMEM ||  reason == -EACCES) {
 				reason = FAILURE_OOM;
 				goto prepd_reject;
 			} else {
@@ -1643,9 +1737,21 @@
 }
 EXPORT_SYMBOL_GPL(iscsi_queuecommand);
 
-int iscsi_change_queue_depth(struct scsi_device *sdev, int depth)
+int iscsi_change_queue_depth(struct scsi_device *sdev, int depth, int reason)
 {
-	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
+	switch (reason) {
+	case SCSI_QDEPTH_DEFAULT:
+		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
+		break;
+	case SCSI_QDEPTH_QFULL:
+		scsi_track_queue_full(sdev, depth);
+		break;
+	case SCSI_QDEPTH_RAMP_UP:
+		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
 	return sdev->queue_depth;
 }
 EXPORT_SYMBOL_GPL(iscsi_change_queue_depth);
@@ -1660,72 +1766,6 @@
 }
 EXPORT_SYMBOL_GPL(iscsi_target_alloc);
 
-void iscsi_session_recovery_timedout(struct iscsi_cls_session *cls_session)
-{
-	struct iscsi_session *session = cls_session->dd_data;
-
-	spin_lock_bh(&session->lock);
-	if (session->state != ISCSI_STATE_LOGGED_IN) {
-		session->state = ISCSI_STATE_RECOVERY_FAILED;
-		if (session->leadconn)
-			wake_up(&session->leadconn->ehwait);
-	}
-	spin_unlock_bh(&session->lock);
-}
-EXPORT_SYMBOL_GPL(iscsi_session_recovery_timedout);
-
-int iscsi_eh_target_reset(struct scsi_cmnd *sc)
-{
-	struct iscsi_cls_session *cls_session;
-	struct iscsi_session *session;
-	struct iscsi_conn *conn;
-
-	cls_session = starget_to_session(scsi_target(sc->device));
-	session = cls_session->dd_data;
-	conn = session->leadconn;
-
-	mutex_lock(&session->eh_mutex);
-	spin_lock_bh(&session->lock);
-	if (session->state == ISCSI_STATE_TERMINATE) {
-failed:
-		ISCSI_DBG_EH(session,
-			     "failing target reset: Could not log back into "
-			     "target [age %d]\n",
-			     session->age);
-		spin_unlock_bh(&session->lock);
-		mutex_unlock(&session->eh_mutex);
-		return FAILED;
-	}
-
-	spin_unlock_bh(&session->lock);
-	mutex_unlock(&session->eh_mutex);
-	/*
-	 * we drop the lock here but the leadconn cannot be destoyed while
-	 * we are in the scsi eh
-	 */
-	iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
-
-	ISCSI_DBG_EH(session, "wait for relogin\n");
-	wait_event_interruptible(conn->ehwait,
-				 session->state == ISCSI_STATE_TERMINATE ||
-				 session->state == ISCSI_STATE_LOGGED_IN ||
-				 session->state == ISCSI_STATE_RECOVERY_FAILED);
-	if (signal_pending(current))
-		flush_signals(current);
-
-	mutex_lock(&session->eh_mutex);
-	spin_lock_bh(&session->lock);
-	if (session->state == ISCSI_STATE_LOGGED_IN) {
-		ISCSI_DBG_EH(session,
-			     "target reset succeeded\n");
-	} else
-		goto failed;
-	spin_unlock_bh(&session->lock);
-	mutex_unlock(&session->eh_mutex);
-	return SUCCESS;
-}
-EXPORT_SYMBOL_GPL(iscsi_eh_target_reset);
-
 static void iscsi_tmf_timedout(unsigned long data)
 {
 	struct iscsi_conn *conn = (struct iscsi_conn *)data;
@@ -2108,6 +2148,7 @@
 		spin_lock_bh(&session->lock);
 		fail_scsi_task(task, DID_ABORT);
 		conn->tmf_state = TMF_INITIAL;
+		memset(hdr, 0, sizeof(*hdr));
 		spin_unlock_bh(&session->lock);
 		iscsi_start_tx(conn);
 		goto success_unlocked;
@@ -2118,6 +2159,7 @@
 	case TMF_NOT_FOUND:
 		if (!sc->SCp.ptr) {
 			conn->tmf_state = TMF_INITIAL;
+			memset(hdr, 0, sizeof(*hdr));
 			/* task completed before tmf abort response */
 			ISCSI_DBG_EH(session, "sc completed while abort	in "
 					      "progress\n");
@@ -2212,6 +2254,7 @@
 	iscsi_suspend_tx(conn);
 
 	spin_lock_bh(&session->lock);
+	memset(hdr, 0, sizeof(*hdr));
 	fail_scsi_tasks(conn, sc->device->lun, DID_ERROR);
 	conn->tmf_state = TMF_INITIAL;
 	spin_unlock_bh(&session->lock);
@@ -2229,6 +2272,172 @@
 }
 EXPORT_SYMBOL_GPL(iscsi_eh_device_reset);
 
+void iscsi_session_recovery_timedout(struct iscsi_cls_session *cls_session)
+{
+	struct iscsi_session *session = cls_session->dd_data;
+
+	spin_lock_bh(&session->lock);
+	if (session->state != ISCSI_STATE_LOGGED_IN) {
+		session->state = ISCSI_STATE_RECOVERY_FAILED;
+		if (session->leadconn)
+			wake_up(&session->leadconn->ehwait);
+	}
+	spin_unlock_bh(&session->lock);
+}
+EXPORT_SYMBOL_GPL(iscsi_session_recovery_timedout);
+
+/**
+ * iscsi_eh_session_reset - drop session and attempt relogin
+ * @sc: scsi command
+ *
+ * This function will wait for a relogin, session termination from
+ * userspace, or a recovery/replacement timeout.
+ */
+static int iscsi_eh_session_reset(struct scsi_cmnd *sc)
+{
+	struct iscsi_cls_session *cls_session;
+	struct iscsi_session *session;
+	struct iscsi_conn *conn;
+
+	cls_session = starget_to_session(scsi_target(sc->device));
+	session = cls_session->dd_data;
+	conn = session->leadconn;
+
+	mutex_lock(&session->eh_mutex);
+	spin_lock_bh(&session->lock);
+	if (session->state == ISCSI_STATE_TERMINATE) {
+failed:
+		ISCSI_DBG_EH(session,
+			     "failing session reset: Could not log back into "
+			     "%s, %s [age %d]\n", session->targetname,
+			     conn->persistent_address, session->age);
+		spin_unlock_bh(&session->lock);
+		mutex_unlock(&session->eh_mutex);
+		return FAILED;
+	}
+
+	spin_unlock_bh(&session->lock);
+	mutex_unlock(&session->eh_mutex);
+	/*
+	 * we drop the lock here but the leadconn cannot be destoyed while
+	 * we are in the scsi eh
+	 */
+	iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+
+	ISCSI_DBG_EH(session, "wait for relogin\n");
+	wait_event_interruptible(conn->ehwait,
+				 session->state == ISCSI_STATE_TERMINATE ||
+				 session->state == ISCSI_STATE_LOGGED_IN ||
+				 session->state == ISCSI_STATE_RECOVERY_FAILED);
+	if (signal_pending(current))
+		flush_signals(current);
+
+	mutex_lock(&session->eh_mutex);
+	spin_lock_bh(&session->lock);
+	if (session->state == ISCSI_STATE_LOGGED_IN) {
+		ISCSI_DBG_EH(session,
+			     "session reset succeeded for %s,%s\n",
+			     session->targetname, conn->persistent_address);
+	} else
+		goto failed;
+	spin_unlock_bh(&session->lock);
+	mutex_unlock(&session->eh_mutex);
+	return SUCCESS;
+}
+
+static void iscsi_prep_tgt_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr)
+{
+	memset(hdr, 0, sizeof(*hdr));
+	hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE;
+	hdr->flags = ISCSI_TM_FUNC_TARGET_WARM_RESET & ISCSI_FLAG_TM_FUNC_MASK;
+	hdr->flags |= ISCSI_FLAG_CMD_FINAL;
+	hdr->rtt = RESERVED_ITT;
+}
+
+/**
+ * iscsi_eh_target_reset - reset target
+ * @sc: scsi command
+ *
+ * This will attempt to send a warm target reset. If that fails
+ * then we will drop the session and attempt ERL0 recovery.
+ */
+int iscsi_eh_target_reset(struct scsi_cmnd *sc)
+{
+	struct iscsi_cls_session *cls_session;
+	struct iscsi_session *session;
+	struct iscsi_conn *conn;
+	struct iscsi_tm *hdr;
+	int rc = FAILED;
+
+	cls_session = starget_to_session(scsi_target(sc->device));
+	session = cls_session->dd_data;
+
+	ISCSI_DBG_EH(session, "tgt Reset [sc %p tgt %s]\n", sc,
+		     session->targetname);
+
+	mutex_lock(&session->eh_mutex);
+	spin_lock_bh(&session->lock);
+	/*
+	 * Just check if we are not logged in. We cannot check for
+	 * the phase because the reset could come from a ioctl.
+	 */
+	if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN)
+		goto unlock;
+	conn = session->leadconn;
+
+	/* only have one tmf outstanding at a time */
+	if (conn->tmf_state != TMF_INITIAL)
+		goto unlock;
+	conn->tmf_state = TMF_QUEUED;
+
+	hdr = &conn->tmhdr;
+	iscsi_prep_tgt_reset_pdu(sc, hdr);
+
+	if (iscsi_exec_task_mgmt_fn(conn, hdr, session->age,
+				    session->tgt_reset_timeout)) {
+		rc = FAILED;
+		goto unlock;
+	}
+
+	switch (conn->tmf_state) {
+	case TMF_SUCCESS:
+		break;
+	case TMF_TIMEDOUT:
+		spin_unlock_bh(&session->lock);
+		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+		goto done;
+	default:
+		conn->tmf_state = TMF_INITIAL;
+		goto unlock;
+	}
+
+	rc = SUCCESS;
+	spin_unlock_bh(&session->lock);
+
+	iscsi_suspend_tx(conn);
+
+	spin_lock_bh(&session->lock);
+	memset(hdr, 0, sizeof(*hdr));
+	fail_scsi_tasks(conn, -1, DID_ERROR);
+	conn->tmf_state = TMF_INITIAL;
+	spin_unlock_bh(&session->lock);
+
+	iscsi_start_tx(conn);
+	goto done;
+
+unlock:
+	spin_unlock_bh(&session->lock);
+done:
+	ISCSI_DBG_EH(session, "tgt %s reset result = %s\n", session->targetname,
+		     rc == SUCCESS ? "SUCCESS" : "FAILED");
+	mutex_unlock(&session->eh_mutex);
+
+	if (rc == FAILED)
+		rc = iscsi_eh_session_reset(sc);
+	return rc;
+}
+EXPORT_SYMBOL_GPL(iscsi_eh_target_reset);
+
 /*
  * Pre-allocate a pool of @max items of @item_size. By default, the pool
  * should be accessed via kfifo_{get,put} on q->queue.
@@ -2495,6 +2704,7 @@
 	session->host = shost;
 	session->state = ISCSI_STATE_FREE;
 	session->fast_abort = 1;
+	session->tgt_reset_timeout = 30;
 	session->lu_reset_timeout = 15;
 	session->abort_timeout = 10;
 	session->scsi_cmds_max = scsi_cmds;
@@ -2856,6 +3066,7 @@
 	spin_lock_bh(&session->lock);
 	fail_scsi_tasks(conn, -1, DID_TRANSPORT_DISRUPTED);
 	fail_mgmt_tasks(session, conn);
+	memset(&conn->tmhdr, 0, sizeof(conn->tmhdr));
 	spin_unlock_bh(&session->lock);
 	mutex_unlock(&session->eh_mutex);
 }
@@ -2932,6 +3143,9 @@
 	case ISCSI_PARAM_LU_RESET_TMO:
 		sscanf(buf, "%d", &session->lu_reset_timeout);
 		break;
+	case ISCSI_PARAM_TGT_RESET_TMO:
+		sscanf(buf, "%d", &session->tgt_reset_timeout);
+		break;
 	case ISCSI_PARAM_PING_TMO:
 		sscanf(buf, "%d", &conn->ping_timeout);
 		break;
@@ -3031,6 +3245,9 @@
 	case ISCSI_PARAM_LU_RESET_TMO:
 		len = sprintf(buf, "%d\n", session->lu_reset_timeout);
 		break;
+	case ISCSI_PARAM_TGT_RESET_TMO:
+		len = sprintf(buf, "%d\n", session->tgt_reset_timeout);
+		break;
 	case ISCSI_PARAM_INITIAL_R2T_EN:
 		len = sprintf(buf, "%d\n", session->initial_r2t_en);
 		break;
diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c
index 2e0746d..ca25ee5 100644
--- a/drivers/scsi/libiscsi_tcp.c
+++ b/drivers/scsi/libiscsi_tcp.c
@@ -1004,7 +1004,7 @@
  * iscsi_tcp_task_xmit - xmit normal PDU task
  * @task: iscsi command task
  *
- * We're expected to return 0 when everything was transmitted succesfully,
+ * We're expected to return 0 when everything was transmitted successfully,
  * -EAGAIN if there's still data in the queue, or != 0 for any other kind
  * of error.
  */
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index 1c558d3..14b1319 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -820,10 +820,14 @@
 		ata_port_disable(dev->sata_dev.ap);
 }
 
-int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth)
+int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth,
+			   int reason)
 {
 	int res = min(new_depth, SAS_MAX_QD);
 
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (scsi_dev->tagged_supported)
 		scsi_adjust_queue_depth(scsi_dev, scsi_get_tag_type(scsi_dev),
 					res);
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index aa10f79..1cc23a6 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -109,7 +109,8 @@
 	struct lpfc_dmabuf dbuf;
 	uint32_t size;
 	uint32_t tag;
-	struct lpfc_rcqe rcqe;
+	struct lpfc_cq_event cq_event;
+	unsigned long time_stamp;
 };
 
 /* Priority bit.  Set value to exceed low water mark in lpfc_mem. */
@@ -201,6 +202,7 @@
 	uint32_t elsRcvLIRR;
 	uint32_t elsRcvRPS;
 	uint32_t elsRcvRPL;
+	uint32_t elsRcvRRQ;
 	uint32_t elsXmitFLOGI;
 	uint32_t elsXmitFDISC;
 	uint32_t elsXmitPLOGI;
@@ -289,8 +291,8 @@
 
 	uint16_t vpi;
 	uint16_t vfi;
-	uint8_t vfi_state;
-#define LPFC_VFI_REGISTERED	0x1
+	uint8_t vpi_state;
+#define LPFC_VPI_REGISTERED	0x1
 
 	uint32_t fc_flag;	/* FC flags */
 /* Several of these flags are HBA centric and should be moved to
@@ -405,6 +407,7 @@
 	uint8_t stat_data_enabled;
 	uint8_t stat_data_blocked;
 	struct list_head rcv_buffer_list;
+	unsigned long rcv_buffer_time_stamp;
 	uint32_t vport_flag;
 #define STATIC_VPORT	1
 };
@@ -527,13 +530,16 @@
 #define HBA_ERATT_HANDLED	0x1 /* This flag is set when eratt handled */
 #define DEFER_ERATT		0x2 /* Deferred error attention in progress */
 #define HBA_FCOE_SUPPORT	0x4 /* HBA function supports FCOE */
-#define HBA_RECEIVE_BUFFER	0x8 /* Rcv buffer posted to worker thread */
+#define HBA_SP_QUEUE_EVT	0x8 /* Slow-path qevt posted to worker thread*/
 #define HBA_POST_RECEIVE_BUFFER 0x10 /* Rcv buffers need to be posted */
 #define FCP_XRI_ABORT_EVENT	0x20
 #define ELS_XRI_ABORT_EVENT	0x40
 #define ASYNC_EVENT		0x80
 #define LINK_DISABLED		0x100 /* Link disabled by user */
 #define FCF_DISC_INPROGRESS	0x200 /* FCF discovery in progress */
+#define HBA_FIP_SUPPORT		0x400 /* FIP support in HBA */
+#define HBA_AER_ENABLED		0x800 /* AER enabled with HBA */
+	uint32_t fcp_ring_in_use; /* When polling test if intr-hndlr active*/
 	struct lpfc_dmabuf slim2p;
 
 	MAILBOX_t *mbox;
@@ -551,6 +557,7 @@
 	uint8_t fc_linkspeed;	/* Link speed after last READ_LA */
 
 	uint32_t fc_eventTag;	/* event tag for link attention */
+	uint32_t link_events;
 
 	/* These fields used to be binfo */
 	uint32_t fc_pref_DID;	/* preferred D_ID */
@@ -604,8 +611,8 @@
 	uint32_t cfg_enable_hba_reset;
 	uint32_t cfg_enable_hba_heartbeat;
 	uint32_t cfg_enable_bg;
-	uint32_t cfg_enable_fip;
 	uint32_t cfg_log_verbose;
+	uint32_t cfg_aer_support;
 
 	lpfc_vpd_t vpd;		/* vital product data */
 
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index e1a30a1..91542f7 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -23,12 +23,14 @@
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
+#include <linux/aer.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsi_transport_fc.h>
+#include <scsi/fc/fc_fs.h>
 
 #include "lpfc_hw4.h"
 #include "lpfc_hw.h"
@@ -98,6 +100,28 @@
 	return snprintf(buf, PAGE_SIZE, LPFC_MODULE_DESC "\n");
 }
 
+/**
+ * lpfc_enable_fip_show - Return the fip mode of the HBA
+ * @dev: class unused variable.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the module description text.
+ *
+ * Returns: size of formatted string.
+ **/
+static ssize_t
+lpfc_enable_fip_show(struct device *dev, struct device_attribute *attr,
+		       char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(dev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
+
+	if (phba->hba_flag & HBA_FIP_SUPPORT)
+		return snprintf(buf, PAGE_SIZE, "1\n");
+	else
+		return snprintf(buf, PAGE_SIZE, "0\n");
+}
+
 static ssize_t
 lpfc_bg_info_show(struct device *dev, struct device_attribute *attr,
 		  char *buf)
@@ -654,7 +678,7 @@
  * Notes:
  * Assumes any error from lpfc_selective_reset() will be negative.
  * If lpfc_selective_reset() returns zero then the length of the buffer
- * is returned which indicates succcess
+ * is returned which indicates success
  *
  * Returns:
  * -EINVAL if the buffer does not contain the string "selective"
@@ -762,9 +786,15 @@
 	} else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0)
 		status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
 	else if (strncmp(buf, "warm", sizeof("warm") - 1) == 0)
-		status = lpfc_do_offline(phba, LPFC_EVT_WARM_START);
+		if (phba->sli_rev == LPFC_SLI_REV4)
+			return -EINVAL;
+		else
+			status = lpfc_do_offline(phba, LPFC_EVT_WARM_START);
 	else if (strncmp(buf, "error", sizeof("error") - 1) == 0)
-		status = lpfc_do_offline(phba, LPFC_EVT_KILL);
+		if (phba->sli_rev == LPFC_SLI_REV4)
+			return -EINVAL;
+		else
+			status = lpfc_do_offline(phba, LPFC_EVT_KILL);
 	else
 		return -EINVAL;
 
@@ -1126,6 +1156,9 @@
 	if ((val & 0x3) != val)
 		return -EINVAL;
 
+	if (phba->sli_rev == LPFC_SLI_REV4)
+		val = 0;
+
 	spin_lock_irq(&phba->hbalock);
 
 	old_val = phba->cfg_poll;
@@ -1589,6 +1622,7 @@
 static DEVICE_ATTR(menlo_mgmt_mode, S_IRUGO, lpfc_mlomgmt_show, NULL);
 static DEVICE_ATTR(nport_evt_cnt, S_IRUGO, lpfc_nport_evt_cnt_show, NULL);
 static DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show, NULL);
+static DEVICE_ATTR(lpfc_enable_fip, S_IRUGO, lpfc_enable_fip_show, NULL);
 static DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR,
 		   lpfc_board_mode_show, lpfc_board_mode_store);
 static DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset);
@@ -2759,6 +2793,196 @@
 		lpfc_link_speed_show, lpfc_link_speed_store);
 
 /*
+# lpfc_aer_support: Support PCIe device Advanced Error Reporting (AER)
+#       0  = aer disabled or not supported
+#       1  = aer supported and enabled (default)
+# Value range is [0,1]. Default value is 1.
+*/
+
+/**
+ * lpfc_aer_support_store - Set the adapter for aer support
+ *
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: containing the string "selective".
+ * @count: unused variable.
+ *
+ * Description:
+ * If the val is 1 and currently the device's AER capability was not
+ * enabled, invoke the kernel's enable AER helper routine, trying to
+ * enable the device's AER capability. If the helper routine enabling
+ * AER returns success, update the device's cfg_aer_support flag to
+ * indicate AER is supported by the device; otherwise, if the device
+ * AER capability is already enabled to support AER, then do nothing.
+ *
+ * If the val is 0 and currently the device's AER support was enabled,
+ * invoke the kernel's disable AER helper routine. After that, update
+ * the device's cfg_aer_support flag to indicate AER is not supported
+ * by the device; otherwise, if the device AER capability is already
+ * disabled from supporting AER, then do nothing.
+ *
+ * Returns:
+ * length of the buf on success if val is in range the intended mode
+ * is supported.
+ * -EINVAL if val out of range or intended mode is not supported.
+ **/
+static ssize_t
+lpfc_aer_support_store(struct device *dev, struct device_attribute *attr,
+		       const char *buf, size_t count)
+{
+	struct Scsi_Host *shost = class_to_shost(dev);
+	struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
+	struct lpfc_hba *phba = vport->phba;
+	int val = 0, rc = -EINVAL;
+
+	/* AER not supported on OC devices yet */
+	if (phba->pci_dev_grp == LPFC_PCI_DEV_OC)
+		return -EPERM;
+	if (!isdigit(buf[0]))
+		return -EINVAL;
+	if (sscanf(buf, "%i", &val) != 1)
+		return -EINVAL;
+
+	switch (val) {
+	case 0:
+		if (phba->hba_flag & HBA_AER_ENABLED) {
+			rc = pci_disable_pcie_error_reporting(phba->pcidev);
+			if (!rc) {
+				spin_lock_irq(&phba->hbalock);
+				phba->hba_flag &= ~HBA_AER_ENABLED;
+				spin_unlock_irq(&phba->hbalock);
+				phba->cfg_aer_support = 0;
+				rc = strlen(buf);
+			} else
+				rc = -EPERM;
+		} else {
+			phba->cfg_aer_support = 0;
+			rc = strlen(buf);
+		}
+		break;
+	case 1:
+		if (!(phba->hba_flag & HBA_AER_ENABLED)) {
+			rc = pci_enable_pcie_error_reporting(phba->pcidev);
+			if (!rc) {
+				spin_lock_irq(&phba->hbalock);
+				phba->hba_flag |= HBA_AER_ENABLED;
+				spin_unlock_irq(&phba->hbalock);
+				phba->cfg_aer_support = 1;
+				rc = strlen(buf);
+			} else
+				 rc = -EPERM;
+		} else {
+			phba->cfg_aer_support = 1;
+			rc = strlen(buf);
+		}
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+static int lpfc_aer_support = 1;
+module_param(lpfc_aer_support, int, 1);
+MODULE_PARM_DESC(lpfc_aer_support, "Enable PCIe device AER support");
+lpfc_param_show(aer_support)
+
+/**
+ * lpfc_aer_support_init - Set the initial adapters aer support flag
+ * @phba: lpfc_hba pointer.
+ * @val: link speed value.
+ *
+ * Description:
+ * If val is in a valid range [0,1], then set the adapter's initial
+ * cfg_aer_support field. It will be up to the driver's probe_one
+ * routine to determine whether the device's AER support can be set
+ * or not.
+ *
+ * Notes:
+ * If the value is not in range log a kernel error message, and
+ * choose the default value of setting AER support and return.
+ *
+ * Returns:
+ * zero if val saved.
+ * -EINVAL val out of range
+ **/
+static int
+lpfc_aer_support_init(struct lpfc_hba *phba, int val)
+{
+	/* AER not supported on OC devices yet */
+	if (phba->pci_dev_grp == LPFC_PCI_DEV_OC) {
+		phba->cfg_aer_support = 0;
+		return -EPERM;
+	}
+
+	if (val == 0 || val == 1) {
+		phba->cfg_aer_support = val;
+		return 0;
+	}
+	lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+			"2712 lpfc_aer_support attribute value %d out "
+			"of range, allowed values are 0|1, setting it "
+			"to default value of 1\n", val);
+	/* By default, try to enable AER on a device */
+	phba->cfg_aer_support = 1;
+	return -EINVAL;
+}
+
+static DEVICE_ATTR(lpfc_aer_support, S_IRUGO | S_IWUSR,
+		   lpfc_aer_support_show, lpfc_aer_support_store);
+
+/**
+ * lpfc_aer_cleanup_state - Clean up aer state to the aer enabled device
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: containing the string "selective".
+ * @count: unused variable.
+ *
+ * Description:
+ * If the @buf contains 1 and the device currently has the AER support
+ * enabled, then invokes the kernel AER helper routine
+ * pci_cleanup_aer_uncorrect_error_status to clean up the uncorrectable
+ * error status register.
+ *
+ * Notes:
+ *
+ * Returns:
+ * -EINVAL if the buf does not contain the 1 or the device is not currently
+ * enabled with the AER support.
+ **/
+static ssize_t
+lpfc_aer_cleanup_state(struct device *dev, struct device_attribute *attr,
+		       const char *buf, size_t count)
+{
+	struct Scsi_Host  *shost = class_to_shost(dev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
+	int val, rc = -1;
+
+	/* AER not supported on OC devices yet */
+	if (phba->pci_dev_grp == LPFC_PCI_DEV_OC)
+		return -EPERM;
+	if (!isdigit(buf[0]))
+		return -EINVAL;
+	if (sscanf(buf, "%i", &val) != 1)
+		return -EINVAL;
+	if (val != 1)
+		return -EINVAL;
+
+	if (phba->hba_flag & HBA_AER_ENABLED)
+		rc = pci_cleanup_aer_uncorrect_error_status(phba->pcidev);
+
+	if (rc == 0)
+		return strlen(buf);
+	else
+		return -EPERM;
+}
+
+static DEVICE_ATTR(lpfc_aer_state_cleanup, S_IWUSR, NULL,
+		   lpfc_aer_cleanup_state);
+
+/*
 # lpfc_fcp_class:  Determines FC class to use for the FCP protocol.
 # Value range is [2,3]. Default value is 3.
 */
@@ -2846,7 +3070,7 @@
 # identifies what rctl value to configure the additional ring for.
 # Value range is [1,0xff]. Default value is 4 (Unsolicated Data).
 */
-LPFC_ATTR_R(multi_ring_rctl, FC_UNSOL_DATA, 1,
+LPFC_ATTR_R(multi_ring_rctl, FC_RCTL_DD_UNSOL_DATA, 1,
 	     255, "Identifies RCTL for additional ring configuration");
 
 /*
@@ -2854,7 +3078,7 @@
 # identifies what type value to configure the additional ring for.
 # Value range is [1,0xff]. Default value is 5 (LLC/SNAP).
 */
-LPFC_ATTR_R(multi_ring_type, FC_LLC_SNAP, 1,
+LPFC_ATTR_R(multi_ring_type, FC_TYPE_IP, 1,
 	     255, "Identifies TYPE for additional ring configuration");
 
 /*
@@ -2947,15 +3171,6 @@
 LPFC_ATTR_R(enable_bg, 0, 0, 1, "Enable BlockGuard Support");
 
 /*
-# lpfc_enable_fip: When set, FIP is required to start discovery. If not
-# set, the driver will add an FCF record manually if the port has no
-# FCF records available and start discovery.
-# Value range is [0,1]. Default value is 1 (enabled)
-*/
-LPFC_ATTR_RW(enable_fip, 0, 0, 1, "Enable FIP Discovery");
-
-
-/*
 # lpfc_prot_mask: i
 #	- Bit mask of host protection capabilities used to register with the
 #	  SCSI mid-layer
@@ -3013,6 +3228,7 @@
 	&dev_attr_num_discovered_ports,
 	&dev_attr_menlo_mgmt_mode,
 	&dev_attr_lpfc_drvr_version,
+	&dev_attr_lpfc_enable_fip,
 	&dev_attr_lpfc_temp_sensor,
 	&dev_attr_lpfc_log_verbose,
 	&dev_attr_lpfc_lun_queue_depth,
@@ -3020,7 +3236,6 @@
 	&dev_attr_lpfc_peer_port_login,
 	&dev_attr_lpfc_nodev_tmo,
 	&dev_attr_lpfc_devloss_tmo,
-	&dev_attr_lpfc_enable_fip,
 	&dev_attr_lpfc_fcp_class,
 	&dev_attr_lpfc_use_adisc,
 	&dev_attr_lpfc_ack0,
@@ -3061,6 +3276,8 @@
 	&dev_attr_lpfc_max_scsicmpl_time,
 	&dev_attr_lpfc_stat_data_ctrl,
 	&dev_attr_lpfc_prot_sg_seg_cnt,
+	&dev_attr_lpfc_aer_support,
+	&dev_attr_lpfc_aer_state_cleanup,
 	NULL,
 };
 
@@ -3073,7 +3290,6 @@
 	&dev_attr_lpfc_lun_queue_depth,
 	&dev_attr_lpfc_nodev_tmo,
 	&dev_attr_lpfc_devloss_tmo,
-	&dev_attr_lpfc_enable_fip,
 	&dev_attr_lpfc_hba_queue_depth,
 	&dev_attr_lpfc_peer_port_login,
 	&dev_attr_lpfc_restrict_login,
@@ -3147,7 +3363,7 @@
  * sysfs_ctlreg_read - Read method for reading from ctlreg
  * @kobj: kernel kobject that contains the kernel class device.
  * @bin_attr: kernel attributes passed to us.
- * @buf: if succesful contains the data from the adapter IOREG space.
+ * @buf: if successful contains the data from the adapter IOREG space.
  * @off: offset into buffer to beginning of data.
  * @count: bytes to transfer.
  *
@@ -3815,7 +4031,11 @@
 	hs->invalid_crc_count -= lso->invalid_crc_count;
 	hs->error_frames -= lso->error_frames;
 
-	if (phba->fc_topology == TOPOLOGY_LOOP) {
+	if (phba->hba_flag & HBA_FCOE_SUPPORT) {
+		hs->lip_count = -1;
+		hs->nos_count = (phba->link_events >> 1);
+		hs->nos_count -= lso->link_events;
+	} else if (phba->fc_topology == TOPOLOGY_LOOP) {
 		hs->lip_count = (phba->fc_eventTag >> 1);
 		hs->lip_count -= lso->link_events;
 		hs->nos_count = -1;
@@ -3906,7 +4126,10 @@
 	lso->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord;
 	lso->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
 	lso->error_frames = pmb->un.varRdLnk.crcCnt;
-	lso->link_events = (phba->fc_eventTag >> 1);
+	if (phba->hba_flag & HBA_FCOE_SUPPORT)
+		lso->link_events = (phba->link_events >> 1);
+	else
+		lso->link_events = (phba->fc_eventTag >> 1);
 
 	psli->stats_start = get_seconds();
 
@@ -4222,14 +4445,17 @@
 	lpfc_enable_hba_reset_init(phba, lpfc_enable_hba_reset);
 	lpfc_enable_hba_heartbeat_init(phba, lpfc_enable_hba_heartbeat);
 	lpfc_enable_bg_init(phba, lpfc_enable_bg);
+	if (phba->sli_rev == LPFC_SLI_REV4)
+		phba->cfg_poll = 0;
+	else
 	phba->cfg_poll = lpfc_poll;
 	phba->cfg_soft_wwnn = 0L;
 	phba->cfg_soft_wwpn = 0L;
 	lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt);
 	lpfc_prot_sg_seg_cnt_init(phba, lpfc_prot_sg_seg_cnt);
 	lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth);
-	lpfc_enable_fip_init(phba, lpfc_enable_fip);
 	lpfc_hba_log_verbose_init(phba, lpfc_log_verbose);
+	lpfc_aer_support_init(phba, lpfc_aer_support);
 
 	return;
 }
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index da6bf5a..a5d9048 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -26,6 +26,7 @@
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_transport_fc.h>
 #include <scsi/scsi_bsg_fc.h>
+#include <scsi/fc/fc_fs.h>
 
 #include "lpfc_hw4.h"
 #include "lpfc_hw.h"
@@ -148,8 +149,8 @@
 	cmd->ulpCommand = CMD_GEN_REQUEST64_CR;
 	cmd->un.genreq64.w5.hcsw.Fctl = (SI | LA);
 	cmd->un.genreq64.w5.hcsw.Dfctl = 0;
-	cmd->un.genreq64.w5.hcsw.Rctl = FC_UNSOL_CTL;
-	cmd->un.genreq64.w5.hcsw.Type = FC_COMMON_TRANSPORT_ULP;
+	cmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CTL;
+	cmd->un.genreq64.w5.hcsw.Type = FC_TYPE_CT;
 	cmd->ulpBdeCount = 1;
 	cmd->ulpLe = 1;
 	cmd->ulpClass = CLASS3;
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 0830f37..650494d 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -49,6 +49,8 @@
 void lpfc_request_features(struct lpfc_hba *, struct lpfcMboxq *);
 
 struct lpfc_vport *lpfc_find_vport_by_did(struct lpfc_hba *, uint32_t);
+void lpfc_cleanup_rcv_buffers(struct lpfc_vport *);
+void lpfc_rcv_seq_check_edtov(struct lpfc_vport *);
 void lpfc_cleanup_rpis(struct lpfc_vport *, int);
 int lpfc_linkdown(struct lpfc_hba *);
 void lpfc_linkdown_port(struct lpfc_vport *);
@@ -144,6 +146,8 @@
 
 void lpfc_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
 			 struct lpfc_iocbq *);
+void lpfc_sli4_ct_abort_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
+				    struct lpfc_iocbq *);
 int lpfc_ns_cmd(struct lpfc_vport *, int, uint8_t, uint32_t);
 int lpfc_fdmi_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int);
 void lpfc_fdmi_tmo(unsigned long);
@@ -188,7 +192,7 @@
 void lpfc_init_vfi(struct lpfcMboxq *, struct lpfc_vport *);
 void lpfc_reg_vfi(struct lpfcMboxq *, struct lpfc_vport *, dma_addr_t);
 void lpfc_init_vpi(struct lpfc_hba *, struct lpfcMboxq *, uint16_t);
-void lpfc_unreg_vfi(struct lpfcMboxq *, uint16_t);
+void lpfc_unreg_vfi(struct lpfcMboxq *, struct lpfc_vport *);
 void lpfc_reg_fcfi(struct lpfc_hba *, struct lpfcMboxq *);
 void lpfc_unreg_fcfi(struct lpfcMboxq *, uint16_t);
 void lpfc_resume_rpi(struct lpfcMboxq *, struct lpfc_nodelist *);
@@ -212,7 +216,10 @@
 void lpfc_poll_timeout(unsigned long ptr);
 void lpfc_poll_start_timer(struct lpfc_hba *);
 void lpfc_poll_eratt(unsigned long);
-void lpfc_sli_poll_fcp_ring(struct lpfc_hba *);
+int
+lpfc_sli_handle_fast_ring_event(struct lpfc_hba *,
+			struct lpfc_sli_ring *, uint32_t);
+
 struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *);
 void lpfc_sli_release_iocbq(struct lpfc_hba *, struct lpfc_iocbq *);
 uint16_t lpfc_sli_next_iotag(struct lpfc_hba *, struct lpfc_iocbq *);
@@ -235,7 +242,7 @@
 int lpfc_sli_check_eratt(struct lpfc_hba *);
 void lpfc_sli_handle_slow_ring_event(struct lpfc_hba *,
 				    struct lpfc_sli_ring *, uint32_t);
-int lpfc_sli4_handle_received_buffer(struct lpfc_hba *);
+void lpfc_sli4_handle_received_buffer(struct lpfc_hba *, struct hbq_dmabuf *);
 void lpfc_sli_def_mbox_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
 int lpfc_sli_issue_iocb(struct lpfc_hba *, uint32_t,
 			struct lpfc_iocbq *, uint32_t);
@@ -361,6 +368,7 @@
 void lpfc_parse_fcoe_conf(struct lpfc_hba *, uint8_t *, uint32_t);
 int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int);
 void lpfc_start_fdiscs(struct lpfc_hba *phba);
+struct lpfc_vport *lpfc_find_vport_by_vpid(struct lpfc_hba *, uint16_t);
 
 #define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code)
 #define HBA_EVENT_RSCN                   5
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 9a1bd95..0ebcd9b 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -31,6 +31,7 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_transport_fc.h>
+#include <scsi/fc/fc_fs.h>
 
 #include "lpfc_hw4.h"
 #include "lpfc_hw.h"
@@ -87,7 +88,6 @@
 lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 		    struct lpfc_iocbq *piocbq)
 {
-
 	struct lpfc_dmabuf *mp = NULL;
 	IOCB_t *icmd = &piocbq->iocb;
 	int i;
@@ -160,6 +160,39 @@
 	}
 }
 
+/**
+ * lpfc_sli4_ct_abort_unsol_event - Default handle for sli4 unsol abort
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to the driver internal I/O ring.
+ * @piocbq: Pointer to the IOCBQ.
+ *
+ * This function serves as the default handler for the sli4 unsolicited
+ * abort event. It shall be invoked when there is no application interface
+ * registered unsolicited abort handler. This handler does nothing but
+ * just simply releases the dma buffer used by the unsol abort event.
+ **/
+void
+lpfc_sli4_ct_abort_unsol_event(struct lpfc_hba *phba,
+			       struct lpfc_sli_ring *pring,
+			       struct lpfc_iocbq *piocbq)
+{
+	IOCB_t *icmd = &piocbq->iocb;
+	struct lpfc_dmabuf *bdeBuf;
+	uint32_t size;
+
+	/* Forward abort event to any process registered to receive ct event */
+	lpfc_bsg_ct_unsol_event(phba, pring, piocbq);
+
+	/* If there is no BDE associated with IOCB, there is nothing to do */
+	if (icmd->ulpBdeCount == 0)
+		return;
+	bdeBuf = piocbq->context2;
+	piocbq->context2 = NULL;
+	size  = icmd->un.cont64[0].tus.f.bdeSize;
+	lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf, size);
+	lpfc_in_buf_free(phba, bdeBuf);
+}
+
 static void
 lpfc_free_ct_rsp(struct lpfc_hba *phba, struct lpfc_dmabuf *mlist)
 {
@@ -304,8 +337,8 @@
 	/* Fill in rest of iocb */
 	icmd->un.genreq64.w5.hcsw.Fctl = (SI | LA);
 	icmd->un.genreq64.w5.hcsw.Dfctl = 0;
-	icmd->un.genreq64.w5.hcsw.Rctl = FC_UNSOL_CTL;
-	icmd->un.genreq64.w5.hcsw.Type = FC_COMMON_TRANSPORT_ULP;
+	icmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CTL;
+	icmd->un.genreq64.w5.hcsw.Type = FC_TYPE_CT;
 
 	if (!tmo) {
 		 /* FC spec states we need 3 * ratov for CT requests */
@@ -363,9 +396,14 @@
 	outmp = lpfc_alloc_ct_rsp(phba, cmdcode, bpl, rsp_size, &cnt);
 	if (!outmp)
 		return -ENOMEM;
-
+	/*
+	 * Form the CT IOCB.  The total number of BDEs in this IOCB
+	 * is the single command plus response count from
+	 * lpfc_alloc_ct_rsp.
+	 */
+	cnt += 1;
 	status = lpfc_gen_req(vport, bmp, inmp, outmp, cmpl, ndlp, 0,
-			      cnt+1, 0, retry);
+			      cnt, 0, retry);
 	if (status) {
 		lpfc_free_ct_rsp(phba, outmp);
 		return -ENOMEM;
@@ -501,6 +539,9 @@
 							SLI_CTNS_GFF_ID,
 							0, Did) == 0)
 							vport->num_disc_nodes++;
+						else
+							lpfc_setup_disc_node
+								(vport, Did);
 					}
 					else {
 						lpfc_debugfs_disc_trc(vport,
@@ -1209,7 +1250,7 @@
 		    be16_to_cpu(SLI_CTNS_RFF_ID);
 		CtReq->un.rff.PortId = cpu_to_be32(vport->fc_myDID);
 		CtReq->un.rff.fbits = FC4_FEATURE_INIT;
-		CtReq->un.rff.type_code = FC_FCP_DATA;
+		CtReq->un.rff.type_code = FC_TYPE_FCP;
 		cmpl = lpfc_cmpl_ct_cmd_rff_id;
 		break;
 	}
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 8d0f0de..3915841 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -926,7 +926,7 @@
 		goto out;
 
 	/* Round to page boundry */
-	printk(KERN_ERR "BLKGRD %s: _dump_buf_data=0x%p\n",
+	printk(KERN_ERR "9059 BLKGRD:  %s: _dump_buf_data=0x%p\n",
 			__func__, _dump_buf_data);
 	debug->buffer = _dump_buf_data;
 	if (!debug->buffer) {
@@ -956,8 +956,8 @@
 		goto out;
 
 	/* Round to page boundry */
-	printk(KERN_ERR "BLKGRD %s: _dump_buf_dif=0x%p file=%s\n", __func__,
-	       _dump_buf_dif, file->f_dentry->d_name.name);
+	printk(KERN_ERR	"9060 BLKGRD: %s: _dump_buf_dif=0x%p file=%s\n",
+		__func__, _dump_buf_dif, file->f_dentry->d_name.name);
 	debug->buffer = _dump_buf_dif;
 	if (!debug->buffer) {
 		kfree(debug);
@@ -1377,7 +1377,7 @@
 			debugfs_create_dir(name, phba->hba_debugfs_root);
 		if (!vport->vport_debugfs_root) {
 			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
-					 "0417 Cant create debugfs");
+					 "0417 Cant create debugfs\n");
 			goto debug_failed;
 		}
 		atomic_inc(&phba->debugfs_vport_count);
@@ -1430,7 +1430,7 @@
 				 vport, &lpfc_debugfs_op_nodelist);
 	if (!vport->debug_nodelist) {
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
-				 "0409 Cant create debugfs nodelist");
+				 "0409 Cant create debugfs nodelist\n");
 		goto debug_failed;
 	}
 debug_failed:
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h
index 1142070..2851d75ff 100644
--- a/drivers/scsi/lpfc/lpfc_disc.h
+++ b/drivers/scsi/lpfc/lpfc_disc.h
@@ -19,7 +19,7 @@
  *******************************************************************/
 
 #define FC_MAX_HOLD_RSCN     32	      /* max number of deferred RSCNs */
-#define FC_MAX_NS_RSP        65536    /* max size NameServer rsp */
+#define FC_MAX_NS_RSP        64512    /* max size NameServer rsp */
 #define FC_MAXLOOP           126      /* max devices supported on a fc loop */
 #define LPFC_DISC_FLOGI_TMO  10	      /* Discovery FLOGI ratov */
 
@@ -105,8 +105,6 @@
 	struct lpfc_vport *vport;
 	struct lpfc_work_evt els_retry_evt;
 	struct lpfc_work_evt dev_loss_evt;
-	unsigned long last_ramp_up_time;        /* jiffy of last ramp up */
-	unsigned long last_q_full_time;		/* jiffy of last queue full */
 	struct kref     kref;
 	atomic_t cmd_pending;
 	uint32_t cmd_qdepth;
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 45337cd..ce52270 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -173,13 +173,26 @@
 	 * in FIP mode send FLOGI, FDISC and LOGO as FIP frames.
 	 */
 	if ((did == Fabric_DID) &&
-		bf_get(lpfc_fip_flag, &phba->sli4_hba.sli4_flags) &&
+		(phba->hba_flag & HBA_FIP_SUPPORT) &&
 		((elscmd == ELS_CMD_FLOGI) ||
 		 (elscmd == ELS_CMD_FDISC) ||
 		 (elscmd == ELS_CMD_LOGO)))
-		elsiocb->iocb_flag |= LPFC_FIP_ELS;
+		switch (elscmd) {
+		case ELS_CMD_FLOGI:
+		elsiocb->iocb_flag |= ((ELS_ID_FLOGI << LPFC_FIP_ELS_ID_SHIFT)
+					& LPFC_FIP_ELS_ID_MASK);
+		break;
+		case ELS_CMD_FDISC:
+		elsiocb->iocb_flag |= ((ELS_ID_FDISC << LPFC_FIP_ELS_ID_SHIFT)
+					& LPFC_FIP_ELS_ID_MASK);
+		break;
+		case ELS_CMD_LOGO:
+		elsiocb->iocb_flag |= ((ELS_ID_LOGO << LPFC_FIP_ELS_ID_SHIFT)
+					& LPFC_FIP_ELS_ID_MASK);
+		break;
+		}
 	else
-		elsiocb->iocb_flag &= ~LPFC_FIP_ELS;
+		elsiocb->iocb_flag &= ~LPFC_FIP_ELS_ID_MASK;
 
 	icmd = &elsiocb->iocb;
 
@@ -591,7 +604,7 @@
 	} else {
 		ndlp->nlp_type |= NLP_FABRIC;
 		lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
-		if (vport->vfi_state & LPFC_VFI_REGISTERED) {
+		if (vport->vpi_state & LPFC_VPI_REGISTERED) {
 			lpfc_start_fdiscs(phba);
 			lpfc_do_scr_ns_plogi(phba, vport);
 		} else
@@ -802,7 +815,7 @@
 
 	/* FLOGI completes successfully */
 	lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
-			 "0101 FLOGI completes sucessfully "
+			 "0101 FLOGI completes successfully "
 			 "Data: x%x x%x x%x x%x\n",
 			 irsp->un.ulpWord[4], sp->cmn.e_d_tov,
 			 sp->cmn.w2.r_a_tov, sp->cmn.edtovResolution);
@@ -2452,6 +2465,7 @@
 	 */
 	del_timer_sync(&ndlp->nlp_delayfunc);
 	retry = ndlp->nlp_retry;
+	ndlp->nlp_retry = 0;
 
 	switch (cmd) {
 	case ELS_CMD_FLOGI:
@@ -2711,12 +2725,16 @@
 	    !lpfc_error_lost_link(irsp)) {
 		/* FLOGI retry policy */
 		retry = 1;
-		maxretry = 48;
-		if (cmdiocb->retry >= 32)
+		/* retry forever */
+		maxretry = 0;
+		if (cmdiocb->retry >= 100)
+			delay = 5000;
+		else if (cmdiocb->retry >= 32)
 			delay = 1000;
 	}
 
-	if ((++cmdiocb->retry) >= maxretry) {
+	cmdiocb->retry++;
+	if (maxretry && (cmdiocb->retry >= maxretry)) {
 		phba->fc_stat.elsRetryExceeded++;
 		retry = 0;
 	}
@@ -4133,7 +4151,7 @@
 	/* Indicate we are walking fc_rscn_id_list on this vport */
 	vport->fc_rscn_flush = 1;
 	spin_unlock_irq(shost->host_lock);
-	/* Get the array count after sucessfully have the token */
+	/* Get the array count after successfully have the token */
 	rscn_cnt = vport->fc_rscn_id_cnt;
 	/* If we are already processing an RSCN, save the received
 	 * RSCN payload buffer, cmdiocb->context2 to process later.
@@ -4503,6 +4521,29 @@
 }
 
 /**
+ * lpfc_els_rcv_rrq - Process an unsolicited rrq iocb
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * This routine processes a Reinstate Recovery Qualifier (RRQ) IOCB
+ * received as an ELS unsolicited event. A request to RRQ shall only
+ * be accepted if the Originator Nx_Port N_Port_ID or the Responder
+ * Nx_Port N_Port_ID of the target Exchange is the same as the
+ * N_Port_ID of the Nx_Port that makes the request. If the RRQ is
+ * not accepted, an LS_RJT with reason code "Unable to perform
+ * command request" and reason code explanation "Invalid Originator
+ * S_ID" shall be returned. For now, we just unconditionally accept
+ * RRQ from the target.
+ **/
+static void
+lpfc_els_rcv_rrq(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
+		 struct lpfc_nodelist *ndlp)
+{
+	lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
+}
+
+/**
  * lpfc_els_rsp_rps_acc - Completion callbk func for MBX_READ_LNK_STAT mbox cmd
  * @phba: pointer to lpfc hba data structure.
  * @pmb: pointer to the driver internal queue element for mailbox command.
@@ -5396,7 +5437,7 @@
 	if (lpfc_els_chk_latt(vport))
 		goto dropit;
 
-	/* Ignore traffic recevied during vport shutdown. */
+	/* Ignore traffic received during vport shutdown. */
 	if (vport->load_flag & FC_UNLOADING)
 		goto dropit;
 
@@ -5618,6 +5659,16 @@
 		if (newnode)
 			lpfc_nlp_put(ndlp);
 		break;
+	case ELS_CMD_RRQ:
+		lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
+			"RCV RRQ:         did:x%x/ste:x%x flg:x%x",
+			did, vport->port_state, ndlp->nlp_flag);
+
+		phba->fc_stat.elsRcvRRQ++;
+		lpfc_els_rcv_rrq(vport, elsiocb, ndlp);
+		if (newnode)
+			lpfc_nlp_put(ndlp);
+		break;
 	default:
 		lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
 			"RCV ELS cmd:     cmd:x%x did:x%x/ste:x%x",
@@ -5670,7 +5721,7 @@
  *    NULL - No vport with the matching @vpi found
  *    Otherwise - Address to the vport with the matching @vpi.
  **/
-static struct lpfc_vport *
+struct lpfc_vport *
 lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi)
 {
 	struct lpfc_vport *vport;
@@ -6024,11 +6075,6 @@
 				 irsp->ulpStatus, irsp->un.ulpWord[4]);
 		goto fdisc_failed;
 	}
-		if (vport->fc_vport->vport_state == FC_VPORT_INITIALIZING)
-			lpfc_vport_set_state(vport, FC_VPORT_FAILED);
-		lpfc_nlp_put(ndlp);
-		/* giving up on FDISC. Cancel discovery timer */
-		lpfc_can_disctmo(vport);
 	spin_lock_irq(shost->host_lock);
 	vport->fc_flag |= FC_FABRIC;
 	if (vport->phba->fc_topology == TOPOLOGY_LOOP)
@@ -6107,6 +6153,7 @@
 	int did = ndlp->nlp_DID;
 	int rc;
 
+	vport->port_state = LPFC_FDISC;
 	cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
 	elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did,
 				     ELS_CMD_FDISC);
@@ -6172,7 +6219,6 @@
 		return 1;
 	}
 	lpfc_vport_set_state(vport, FC_VPORT_INITIALIZING);
-	vport->port_state = LPFC_FDISC;
 	return 0;
 }
 
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
old mode 100644
new mode 100755
index e6a47e2..3b94244
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -525,8 +525,6 @@
 			spin_unlock_irq(&phba->hbalock);
 			lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ);
 		}
-		if (phba->hba_flag & HBA_RECEIVE_BUFFER)
-			lpfc_sli4_handle_received_buffer(phba);
 	}
 
 	vports = lpfc_create_vport_work_array(phba);
@@ -568,8 +566,9 @@
 	pring = &phba->sli.ring[LPFC_ELS_RING];
 	status = (ha_copy & (HA_RXMASK  << (4*LPFC_ELS_RING)));
 	status >>= (4*LPFC_ELS_RING);
-	if ((status & HA_RXMASK)
-		|| (pring->flag & LPFC_DEFERRED_RING_EVENT)) {
+	if ((status & HA_RXMASK) ||
+	    (pring->flag & LPFC_DEFERRED_RING_EVENT) ||
+	    (phba->hba_flag & HBA_SP_QUEUE_EVT)) {
 		if (pring->flag & LPFC_STOP_IOCB_EVENT) {
 			pring->flag |= LPFC_DEFERRED_RING_EVENT;
 			/* Set the lpfc data pending flag */
@@ -688,7 +687,8 @@
 			lpfc_unreg_rpi(vport, ndlp);
 
 		/* Leave Fabric nodes alone on link down */
-		if (!remove && ndlp->nlp_type & NLP_FABRIC)
+		if ((phba->sli_rev < LPFC_SLI_REV4) &&
+		    (!remove && ndlp->nlp_type & NLP_FABRIC))
 			continue;
 		rc = lpfc_disc_state_machine(vport, ndlp, NULL,
 					     remove
@@ -706,6 +706,9 @@
 void
 lpfc_port_link_failure(struct lpfc_vport *vport)
 {
+	/* Cleanup any outstanding received buffers */
+	lpfc_cleanup_rcv_buffers(vport);
+
 	/* Cleanup any outstanding RSCN activity */
 	lpfc_els_flush_rscn(vport);
 
@@ -1015,13 +1018,12 @@
 		mempool_free(mboxq, phba->mbox_mem_pool);
 		return;
 	}
-	if (vport->port_state != LPFC_FLOGI) {
-		spin_lock_irqsave(&phba->hbalock, flags);
-		phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE);
-		phba->hba_flag &= ~FCF_DISC_INPROGRESS;
-		spin_unlock_irqrestore(&phba->hbalock, flags);
+	spin_lock_irqsave(&phba->hbalock, flags);
+	phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE);
+	phba->hba_flag &= ~FCF_DISC_INPROGRESS;
+	spin_unlock_irqrestore(&phba->hbalock, flags);
+	if (vport->port_state != LPFC_FLOGI)
 		lpfc_initial_flogi(vport);
-	}
 
 	mempool_free(mboxq, phba->mbox_mem_pool);
 	return;
@@ -1199,6 +1201,7 @@
 
 	/* If the FCF is not availabe do nothing. */
 	if (!(phba->fcf.fcf_flag & FCF_AVAILABLE)) {
+		phba->hba_flag &= ~FCF_DISC_INPROGRESS;
 		spin_unlock_irqrestore(&phba->hbalock, flags);
 		return;
 	}
@@ -1216,15 +1219,23 @@
 
 	fcf_mbxq = mempool_alloc(phba->mbox_mem_pool,
 		GFP_KERNEL);
-	if (!fcf_mbxq)
+	if (!fcf_mbxq) {
+		spin_lock_irqsave(&phba->hbalock, flags);
+		phba->hba_flag &= ~FCF_DISC_INPROGRESS;
+		spin_unlock_irqrestore(&phba->hbalock, flags);
 		return;
+	}
 
 	lpfc_reg_fcfi(phba, fcf_mbxq);
 	fcf_mbxq->vport = phba->pport;
 	fcf_mbxq->mbox_cmpl = lpfc_mbx_cmpl_reg_fcfi;
 	rc = lpfc_sli_issue_mbox(phba, fcf_mbxq, MBX_NOWAIT);
-	if (rc == MBX_NOT_FINISHED)
+	if (rc == MBX_NOT_FINISHED) {
+		spin_lock_irqsave(&phba->hbalock, flags);
+		phba->hba_flag &= ~FCF_DISC_INPROGRESS;
+		spin_unlock_irqrestore(&phba->hbalock, flags);
 		mempool_free(fcf_mbxq, phba->mbox_mem_pool);
+	}
 
 	return;
 }
@@ -1253,13 +1264,27 @@
 			uint16_t *vlan_id)
 {
 	struct lpfc_fcf_conn_entry *conn_entry;
+	int i, j, fcf_vlan_id = 0;
+
+	/* Find the lowest VLAN id in the FCF record */
+	for (i = 0; i < 512; i++) {
+		if (new_fcf_record->vlan_bitmap[i]) {
+			fcf_vlan_id = i * 8;
+			j = 0;
+			while (!((new_fcf_record->vlan_bitmap[i] >> j) & 1)) {
+				j++;
+				fcf_vlan_id++;
+			}
+			break;
+		}
+	}
 
 	/* If FCF not available return 0 */
 	if (!bf_get(lpfc_fcf_record_fcf_avail, new_fcf_record) ||
 		!bf_get(lpfc_fcf_record_fcf_valid, new_fcf_record))
 		return 0;
 
-	if (!phba->cfg_enable_fip) {
+	if (!(phba->hba_flag & HBA_FIP_SUPPORT)) {
 		*boot_flag = 0;
 		*addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov,
 				new_fcf_record);
@@ -1286,7 +1311,11 @@
 		if (*addr_mode & LPFC_FCF_FPMA)
 			*addr_mode = LPFC_FCF_FPMA;
 
-		*vlan_id = 0xFFFF;
+		/* If FCF record report a vlan id use that vlan id */
+		if (fcf_vlan_id)
+			*vlan_id = fcf_vlan_id;
+		else
+			*vlan_id = 0xFFFF;
 		return 1;
 	}
 
@@ -1384,8 +1413,15 @@
 			(*addr_mode & LPFC_FCF_FPMA))
 				*addr_mode = LPFC_FCF_FPMA;
 
+		/* If matching connect list has a vlan id, use it */
 		if (conn_entry->conn_rec.flags & FCFCNCT_VLAN_VALID)
 			*vlan_id = conn_entry->conn_rec.vlan_tag;
+		/*
+		 * If no vlan id is specified in connect list, use the vlan id
+		 * in the FCF record
+		 */
+		else if (fcf_vlan_id)
+			*vlan_id = fcf_vlan_id;
 		else
 			*vlan_id = 0xFFFF;
 
@@ -1423,6 +1459,15 @@
 
 	if (phba->link_state >= LPFC_LINK_UP)
 		lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST);
+	else {
+		/*
+		 * Do not continue FCF discovery and clear FCF_DISC_INPROGRESS
+		 * flag
+		 */
+		spin_lock_irq(&phba->hbalock);
+		phba->hba_flag &= ~FCF_DISC_INPROGRESS;
+		spin_unlock_irq(&phba->hbalock);
+	}
 
 	if (unreg_fcf) {
 		spin_lock_irq(&phba->hbalock);
@@ -1659,9 +1704,8 @@
 		lpfc_initial_fdisc(vport);
 	else {
 		lpfc_vport_set_state(vport, FC_VPORT_NO_FABRIC_SUPP);
-		lpfc_printf_vlog(vport, KERN_ERR,
-			LOG_ELS,
-			"2606 No NPIV Fabric support\n");
+		lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+				 "2606 No NPIV Fabric support\n");
 	}
 	return;
 }
@@ -1756,8 +1800,8 @@
 		lpfc_vport_set_state(vport, FC_VPORT_FAILED);
 		goto fail_free_mem;
 	}
-	/* Mark the vport has registered with its VFI */
-	vport->vfi_state |= LPFC_VFI_REGISTERED;
+	/* The VPI is implicitly registered when the VFI is registered */
+	vport->vpi_state |= LPFC_VPI_REGISTERED;
 
 	if (vport->port_state == LPFC_FABRIC_CFG_LINK) {
 		lpfc_start_fdiscs(phba);
@@ -1861,7 +1905,10 @@
 	if (phba->fc_topology == TOPOLOGY_LOOP) {
 		phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED;
 
-		if (phba->cfg_enable_npiv)
+		/* if npiv is enabled and this adapter supports npiv log
+		 * a message that npiv is not supported in this topology
+		 */
+		if (phba->cfg_enable_npiv && phba->max_vpi)
 			lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
 				"1309 Link Up Event npiv not supported in loop "
 				"topology\n");
@@ -1955,7 +2002,7 @@
 		 * is phase 1 implementation that support FCF index 0 and driver
 		 * defaults.
 		 */
-		if (phba->cfg_enable_fip == 0) {
+		if (!(phba->hba_flag & HBA_FIP_SUPPORT)) {
 			fcf_record = kzalloc(sizeof(struct fcf_record),
 					GFP_KERNEL);
 			if (unlikely(!fcf_record)) {
@@ -2085,6 +2132,7 @@
 	else
 		phba->sli.sli_flag &= ~LPFC_MENLO_MAINT;
 
+	phba->link_events++;
 	if (la->attType == AT_LINK_UP && (!la->mm)) {
 		phba->fc_stat.LinkUp++;
 		if (phba->link_flag & LS_LOOPBACK_MODE) {
@@ -2211,13 +2259,14 @@
 				 mb->mbxStatus);
 		break;
 	}
+	vport->vpi_state &= ~LPFC_VPI_REGISTERED;
 	vport->unreg_vpi_cmpl = VPORT_OK;
 	mempool_free(pmb, phba->mbox_mem_pool);
 	/*
 	 * This shost reference might have been taken at the beginning of
 	 * lpfc_vport_delete()
 	 */
-	if (vport->load_flag & FC_UNLOADING)
+	if ((vport->load_flag & FC_UNLOADING) && (vport != phba->pport))
 		scsi_host_put(shost);
 }
 
@@ -2268,6 +2317,7 @@
 		goto out;
 	}
 
+	vport->vpi_state |= LPFC_VPI_REGISTERED;
 	vport->num_disc_nodes = 0;
 	/* go thru NPR list and issue ELS PLOGIs */
 	if (vport->fc_npr_cnt)
@@ -3077,7 +3127,7 @@
 	struct lpfc_sli *psli;
 	struct lpfc_sli_ring *pring;
 	struct lpfc_iocbq *iocb, *next_iocb;
-	uint32_t rpi, i;
+	uint32_t i;
 
 	lpfc_fabric_abort_nport(ndlp);
 
@@ -3086,7 +3136,6 @@
 	 * by firmware with a no rpi error.
 	 */
 	psli = &phba->sli;
-	rpi = ndlp->nlp_rpi;
 	if (ndlp->nlp_flag & NLP_RPI_VALID) {
 		/* Now process each ring */
 		for (i = 0; i < psli->num_rings; i++) {
@@ -4322,6 +4371,14 @@
 				ret = 1;
 				spin_unlock_irq(shost->host_lock);
 				goto out;
+			} else {
+				lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
+					"2624 RPI %x DID %x flg %x still "
+					"logged in\n",
+					ndlp->nlp_rpi, ndlp->nlp_DID,
+					ndlp->nlp_flag);
+				if (ndlp->nlp_flag & NLP_RPI_VALID)
+					ret = 1;
 			}
 		}
 		spin_unlock_irq(shost->host_lock);
@@ -4400,7 +4457,7 @@
 	 */
 	if (!(phba->hba_flag & HBA_FCOE_SUPPORT) ||
 		!(phba->fcf.fcf_flag & FCF_REGISTERED) ||
-		(phba->cfg_enable_fip == 0)) {
+		(!(phba->hba_flag & HBA_FIP_SUPPORT))) {
 		spin_unlock_irq(&phba->hbalock);
 		return;
 	}
@@ -4409,6 +4466,8 @@
 	if (lpfc_fcf_inuse(phba))
 		return;
 
+	/* At this point, all discovery is aborted */
+	phba->pport->port_state = LPFC_VPORT_UNKNOWN;
 
 	/* Unregister VPIs */
 	vports = lpfc_create_vport_work_array(phba);
@@ -4416,8 +4475,8 @@
 		(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED))
 		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
 			lpfc_mbx_unreg_vpi(vports[i]);
-			vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
-			vports[i]->vfi_state &= ~LPFC_VFI_REGISTERED;
+			vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
+			vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED;
 		}
 	lpfc_destroy_vport_work_array(phba, vports);
 
@@ -4431,7 +4490,7 @@
 		return;
 	}
 
-	lpfc_unreg_vfi(mbox, phba->pport->vfi);
+	lpfc_unreg_vfi(mbox, phba->pport);
 	mbox->vport = phba->pport;
 	mbox->mbox_cmpl = lpfc_unregister_vfi_cmpl;
 
@@ -4512,8 +4571,10 @@
 
 	/* Free the current connect table */
 	list_for_each_entry_safe(conn_entry, next_conn_entry,
-		&phba->fcf_conn_rec_list, list)
+		&phba->fcf_conn_rec_list, list) {
+		list_del_init(&conn_entry->list);
 		kfree(conn_entry);
+	}
 
 	conn_hdr = (struct lpfc_fcf_conn_hdr *) buff;
 	record_count = conn_hdr->length * sizeof(uint32_t)/
@@ -4569,14 +4630,6 @@
 		(fcoe_param_hdr->length != FCOE_PARAM_LENGTH))
 		return;
 
-	if (bf_get(lpfc_fip_param_hdr_fipp_mode, fcoe_param_hdr) ==
-			FIPP_MODE_ON)
-		phba->cfg_enable_fip = 1;
-
-	if (bf_get(lpfc_fip_param_hdr_fipp_mode, fcoe_param_hdr) ==
-		FIPP_MODE_OFF)
-		phba->cfg_enable_fip = 0;
-
 	if (fcoe_param_hdr->parm_flags & FIPP_VLAN_VALID) {
 		phba->valid_vlan = 1;
 		phba->vlan_id = le16_to_cpu(fcoe_param->vlan_tag) &
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index ccb2672..c9faa1d 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -1124,21 +1124,6 @@
 /* Number of 4-byte words in an IOCB. */
 #define IOCB_WORD_SZ    8
 
-/* defines for type field in fc header */
-#define FC_ELS_DATA     0x1
-#define FC_LLC_SNAP     0x5
-#define FC_FCP_DATA     0x8
-#define FC_COMMON_TRANSPORT_ULP 0x20
-
-/* defines for rctl field in fc header */
-#define FC_DEV_DATA     0x0
-#define FC_UNSOL_CTL    0x2
-#define FC_SOL_CTL      0x3
-#define FC_UNSOL_DATA   0x4
-#define FC_FCP_CMND     0x6
-#define FC_ELS_REQ      0x22
-#define FC_ELS_RSP      0x23
-
 /* network headers for Dfctl field */
 #define FC_NET_HDR      0x20
 
@@ -1183,6 +1168,8 @@
 #define PCI_DEVICE_ID_ZEPHYR_DCSP   0xfe12
 #define PCI_VENDOR_ID_SERVERENGINE  0x19a2
 #define PCI_DEVICE_ID_TIGERSHARK    0x0704
+#define PCI_DEVICE_ID_TOMCAT        0x0714
+#define PCI_DEVICE_ID_FALCON        0xf180
 
 #define JEDEC_ID_ADDRESS            0x0080001c
 #define FIREFLY_JEDEC_ID            0x1ACC
@@ -1444,6 +1431,7 @@
 #define CMD_ABORT_MXRI64_CN     0x8C
 #define CMD_RCV_ELS_REQ64_CX    0x8D
 #define CMD_XMIT_ELS_RSP64_CX   0x95
+#define CMD_XMIT_BLS_RSP64_CX   0x97
 #define CMD_FCP_IWRITE64_CR     0x98
 #define CMD_FCP_IWRITE64_CX     0x99
 #define CMD_FCP_IREAD64_CR      0x9A
@@ -2306,8 +2294,7 @@
 	uint32_t rsvd1;
 	uint32_t rsvd2:8;
 	uint32_t sid:24;
-	uint32_t rsvd3;
-	uint32_t rsvd4;
+	uint32_t wwn[2];
 	uint32_t rsvd5;
 	uint16_t vfi;
 	uint16_t vpi;
@@ -2315,8 +2302,7 @@
 	uint32_t rsvd1;
 	uint32_t sid:24;
 	uint32_t rsvd2:8;
-	uint32_t rsvd3;
-	uint32_t rsvd4;
+	uint32_t wwn[2];
 	uint32_t rsvd5;
 	uint16_t vpi;
 	uint16_t vfi;
@@ -2326,7 +2312,13 @@
 /* Structure for MB Command UNREG_VPI (0x97) */
 typedef struct {
 	uint32_t rsvd1;
-	uint32_t rsvd2;
+#ifdef __BIG_ENDIAN_BITFIELD
+	uint16_t rsvd2;
+	uint16_t sli4_vpi;
+#else	/*  __LITTLE_ENDIAN */
+	uint16_t sli4_vpi;
+	uint16_t rsvd2;
+#endif
 	uint32_t rsvd3;
 	uint32_t rsvd4;
 	uint32_t rsvd5;
@@ -3547,7 +3539,7 @@
 		ASYNCSTAT_FIELDS asyncstat; /* async_status iocb */
 		QUE_XRI64_CX_FIELDS quexri64cx; /* que_xri64_cx fields */
 		struct rcv_seq64 rcvseq64;	/* RCV_SEQ64 and RCV_CONT64 */
-
+		struct sli4_bls_acc bls_acc; /* UNSOL ABTS BLS_ACC params */
 		uint32_t ulpWord[IOCB_WORD_SZ - 2];	/* generic 6 'words' */
 	} un;
 	union {
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 3689eee..1585148 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -194,6 +194,26 @@
 #define lpfc_fip_flag_WORD word0
 };
 
+struct sli4_bls_acc {
+	uint32_t word0_rsvd;      /* Word0 must be reserved */
+	uint32_t word1;
+#define lpfc_abts_orig_SHIFT      0
+#define lpfc_abts_orig_MASK       0x00000001
+#define lpfc_abts_orig_WORD       word1
+#define LPFC_ABTS_UNSOL_RSP       1
+#define LPFC_ABTS_UNSOL_INT       0
+	uint32_t word2;
+#define lpfc_abts_rxid_SHIFT      0
+#define lpfc_abts_rxid_MASK       0x0000FFFF
+#define lpfc_abts_rxid_WORD       word2
+#define lpfc_abts_oxid_SHIFT      16
+#define lpfc_abts_oxid_MASK       0x0000FFFF
+#define lpfc_abts_oxid_WORD       word2
+	uint32_t word3;
+	uint32_t word4;
+	uint32_t word5_rsvd;	/* Word5 must be reserved */
+};
+
 /* event queue entry structure */
 struct lpfc_eqe {
 	uint32_t word0;
@@ -425,7 +445,7 @@
 #define lpfc_wqe_gen_status_MASK	0x0000000F
 #define lpfc_wqe_gen_status_WORD	word7
 #define lpfc_wqe_gen_ct_SHIFT		2
-#define lpfc_wqe_gen_ct_MASK		0x00000007
+#define lpfc_wqe_gen_ct_MASK		0x00000003
 #define lpfc_wqe_gen_ct_WORD		word7
 	uint32_t abort_tag;
 	uint32_t word9;
@@ -453,6 +473,13 @@
 #define lpfc_wqe_gen_wqec_SHIFT		7
 #define lpfc_wqe_gen_wqec_MASK		0x00000001
 #define lpfc_wqe_gen_wqec_WORD		word11
+#define ELS_ID_FLOGI 3
+#define ELS_ID_FDISC 2
+#define ELS_ID_LOGO  1
+#define ELS_ID_DEFAULT 0
+#define lpfc_wqe_gen_els_id_SHIFT	4
+#define lpfc_wqe_gen_els_id_MASK	0x00000003
+#define lpfc_wqe_gen_els_id_WORD	word11
 #define lpfc_wqe_gen_cmd_type_SHIFT	0
 #define lpfc_wqe_gen_cmd_type_MASK	0x0000000F
 #define lpfc_wqe_gen_cmd_type_WORD	word11
@@ -487,8 +514,8 @@
 
 #define LPFC_UERR_STATUS_HI		0x00A4
 #define LPFC_UERR_STATUS_LO		0x00A0
-#define LPFC_ONLINE0			0x00B0
-#define LPFC_ONLINE1			0x00B4
+#define LPFC_UE_MASK_HI			0x00AC
+#define LPFC_UE_MASK_LO			0x00A8
 #define LPFC_SCRATCHPAD			0x0058
 
 /* BAR0 Registers */
@@ -760,6 +787,7 @@
 #define LPFC_MBOX_OPCODE_MQ_DESTROY		0x35
 #define LPFC_MBOX_OPCODE_CQ_DESTROY		0x36
 #define LPFC_MBOX_OPCODE_EQ_DESTROY		0x37
+#define LPFC_MBOX_OPCODE_QUERY_FW_CFG		0x3A
 #define LPFC_MBOX_OPCODE_FUNCTION_RESET		0x3D
 
 /* FCoE Opcodes */
@@ -1273,6 +1301,51 @@
 #define lpfc_mbx_del_fcf_tbl_index_WORD		word10
 };
 
+struct lpfc_mbx_query_fw_cfg {
+	struct mbox_header header;
+	uint32_t config_number;
+	uint32_t asic_rev;
+	uint32_t phys_port;
+	uint32_t function_mode;
+/* firmware Function Mode */
+#define lpfc_function_mode_toe_SHIFT		0
+#define lpfc_function_mode_toe_MASK		0x00000001
+#define lpfc_function_mode_toe_WORD		function_mode
+#define lpfc_function_mode_nic_SHIFT		1
+#define lpfc_function_mode_nic_MASK		0x00000001
+#define lpfc_function_mode_nic_WORD		function_mode
+#define lpfc_function_mode_rdma_SHIFT		2
+#define lpfc_function_mode_rdma_MASK		0x00000001
+#define lpfc_function_mode_rdma_WORD		function_mode
+#define lpfc_function_mode_vm_SHIFT		3
+#define lpfc_function_mode_vm_MASK		0x00000001
+#define lpfc_function_mode_vm_WORD		function_mode
+#define lpfc_function_mode_iscsi_i_SHIFT	4
+#define lpfc_function_mode_iscsi_i_MASK		0x00000001
+#define lpfc_function_mode_iscsi_i_WORD		function_mode
+#define lpfc_function_mode_iscsi_t_SHIFT	5
+#define lpfc_function_mode_iscsi_t_MASK		0x00000001
+#define lpfc_function_mode_iscsi_t_WORD		function_mode
+#define lpfc_function_mode_fcoe_i_SHIFT		6
+#define lpfc_function_mode_fcoe_i_MASK		0x00000001
+#define lpfc_function_mode_fcoe_i_WORD		function_mode
+#define lpfc_function_mode_fcoe_t_SHIFT		7
+#define lpfc_function_mode_fcoe_t_MASK		0x00000001
+#define lpfc_function_mode_fcoe_t_WORD		function_mode
+#define lpfc_function_mode_dal_SHIFT		8
+#define lpfc_function_mode_dal_MASK		0x00000001
+#define lpfc_function_mode_dal_WORD		function_mode
+#define lpfc_function_mode_lro_SHIFT		9
+#define lpfc_function_mode_lro_MASK		0x00000001
+#define lpfc_function_mode_lro_WORD		function_mode9
+#define lpfc_function_mode_flex10_SHIFT		10
+#define lpfc_function_mode_flex10_MASK		0x00000001
+#define lpfc_function_mode_flex10_WORD		function_mode
+#define lpfc_function_mode_ncsi_SHIFT		11
+#define lpfc_function_mode_ncsi_MASK		0x00000001
+#define lpfc_function_mode_ncsi_WORD		function_mode
+};
+
 /* Status field for embedded SLI_CONFIG mailbox command */
 #define STATUS_SUCCESS					0x0
 #define STATUS_FAILED 					0x1
@@ -1349,8 +1422,7 @@
 #define lpfc_reg_vfi_fcfi_SHIFT		0
 #define lpfc_reg_vfi_fcfi_MASK		0x0000FFFF
 #define lpfc_reg_vfi_fcfi_WORD		word2
-	uint32_t word3_rsvd;
-	uint32_t word4_rsvd;
+	uint32_t wwn[2];
 	struct ulp_bde64 bde;
 	uint32_t word8_rsvd;
 	uint32_t word9_rsvd;
@@ -1555,6 +1627,11 @@
 #define lpfc_mbx_rd_rev_fcoe_SHIFT		20
 #define lpfc_mbx_rd_rev_fcoe_MASK		0x00000001
 #define lpfc_mbx_rd_rev_fcoe_WORD		word1
+#define lpfc_mbx_rd_rev_cee_ver_SHIFT		21
+#define lpfc_mbx_rd_rev_cee_ver_MASK		0x00000003
+#define lpfc_mbx_rd_rev_cee_ver_WORD		word1
+#define LPFC_PREDCBX_CEE_MODE	0
+#define LPFC_DCBX_CEE_MODE	1
 #define lpfc_mbx_rd_rev_vpd_SHIFT		29
 #define lpfc_mbx_rd_rev_vpd_MASK		0x00000001
 #define lpfc_mbx_rd_rev_vpd_WORD		word1
@@ -1804,6 +1881,7 @@
 		struct lpfc_mbx_read_config rd_config;
 		struct lpfc_mbx_request_features req_ftrs;
 		struct lpfc_mbx_post_hdr_tmpl hdr_tmpl;
+		struct lpfc_mbx_query_fw_cfg query_fw_cfg;
 		struct lpfc_mbx_nop nop;
 	} un;
 };
@@ -1885,7 +1963,7 @@
 };
 
 struct lpfc_acqe_fcoe {
-	uint32_t fcf_index;
+	uint32_t index;
 	uint32_t word1;
 #define lpfc_acqe_fcoe_fcf_count_SHIFT		0
 #define lpfc_acqe_fcoe_fcf_count_MASK		0x0000FFFF
@@ -1896,6 +1974,7 @@
 #define LPFC_FCOE_EVENT_TYPE_NEW_FCF		0x1
 #define LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL	0x2
 #define LPFC_FCOE_EVENT_TYPE_FCF_DEAD		0x3
+#define LPFC_FCOE_EVENT_TYPE_CVL		0x4
 	uint32_t event_tag;
 	uint32_t trailer;
 };
@@ -1921,12 +2000,13 @@
 #define SGL_ALIGN_SZ 64
 #define SGL_PAGE_SIZE 4096
 /* align SGL addr on a size boundary - adjust address up */
-#define NO_XRI ((uint16_t)-1)
+#define NO_XRI  ((uint16_t)-1)
+
 struct wqe_common {
 	uint32_t word6;
-#define wqe_xri_SHIFT         0
-#define wqe_xri_MASK          0x0000FFFF
-#define wqe_xri_WORD          word6
+#define wqe_xri_tag_SHIFT     0
+#define wqe_xri_tag_MASK      0x0000FFFF
+#define wqe_xri_tag_WORD      word6
 #define wqe_ctxt_tag_SHIFT    16
 #define wqe_ctxt_tag_MASK     0x0000FFFF
 #define wqe_ctxt_tag_WORD     word6
@@ -1987,7 +2067,7 @@
 #define wqe_wqec_MASK       0x00000001
 #define wqe_wqec_WORD       word11
 #define wqe_cqid_SHIFT      16
-#define wqe_cqid_MASK       0x000003ff
+#define wqe_cqid_MASK       0x0000ffff
 #define wqe_cqid_WORD       word11
 };
 
@@ -1996,6 +2076,9 @@
 #define wqe_els_did_SHIFT         0
 #define wqe_els_did_MASK          0x00FFFFFF
 #define wqe_els_did_WORD          word5
+#define wqe_xmit_bls_pt_SHIFT         28
+#define wqe_xmit_bls_pt_MASK          0x00000003
+#define wqe_xmit_bls_pt_WORD          word5
 #define wqe_xmit_bls_ar_SHIFT         30
 #define wqe_xmit_bls_ar_MASK          0x00000001
 #define wqe_xmit_bls_ar_WORD          word5
@@ -2044,6 +2127,23 @@
 
 struct xmit_bls_rsp64_wqe {
 	uint32_t payload0;
+/* Payload0 for BA_ACC */
+#define xmit_bls_rsp64_acc_seq_id_SHIFT        16
+#define xmit_bls_rsp64_acc_seq_id_MASK         0x000000ff
+#define xmit_bls_rsp64_acc_seq_id_WORD         payload0
+#define xmit_bls_rsp64_acc_seq_id_vald_SHIFT   24
+#define xmit_bls_rsp64_acc_seq_id_vald_MASK    0x000000ff
+#define xmit_bls_rsp64_acc_seq_id_vald_WORD    payload0
+/* Payload0 for BA_RJT */
+#define xmit_bls_rsp64_rjt_vspec_SHIFT   0
+#define xmit_bls_rsp64_rjt_vspec_MASK    0x000000ff
+#define xmit_bls_rsp64_rjt_vspec_WORD    payload0
+#define xmit_bls_rsp64_rjt_expc_SHIFT    8
+#define xmit_bls_rsp64_rjt_expc_MASK     0x000000ff
+#define xmit_bls_rsp64_rjt_expc_WORD     payload0
+#define xmit_bls_rsp64_rjt_rsnc_SHIFT    16
+#define xmit_bls_rsp64_rjt_rsnc_MASK     0x000000ff
+#define xmit_bls_rsp64_rjt_rsnc_WORD     payload0
 	uint32_t word1;
 #define xmit_bls_rsp64_rxid_SHIFT  0
 #define xmit_bls_rsp64_rxid_MASK   0x0000ffff
@@ -2052,18 +2152,19 @@
 #define xmit_bls_rsp64_oxid_MASK   0x0000ffff
 #define xmit_bls_rsp64_oxid_WORD   word1
 	uint32_t word2;
-#define xmit_bls_rsp64_seqcntlo_SHIFT  0
-#define xmit_bls_rsp64_seqcntlo_MASK   0x0000ffff
-#define xmit_bls_rsp64_seqcntlo_WORD   word2
-#define xmit_bls_rsp64_seqcnthi_SHIFT  16
+#define xmit_bls_rsp64_seqcnthi_SHIFT  0
 #define xmit_bls_rsp64_seqcnthi_MASK   0x0000ffff
 #define xmit_bls_rsp64_seqcnthi_WORD   word2
+#define xmit_bls_rsp64_seqcntlo_SHIFT  16
+#define xmit_bls_rsp64_seqcntlo_MASK   0x0000ffff
+#define xmit_bls_rsp64_seqcntlo_WORD   word2
 	uint32_t rsrvd3;
 	uint32_t rsrvd4;
 	struct wqe_did	wqe_dest;
 	struct wqe_common wqe_com; /* words 6-11 */
 	uint32_t rsvd_12_15[4];
 };
+
 struct wqe_rctl_dfctl {
 	uint32_t word5;
 #define wqe_si_SHIFT 2
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 562d8ce..226920d 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -28,6 +28,7 @@
 #include <linux/pci.h>
 #include <linux/spinlock.h>
 #include <linux/ctype.h>
+#include <linux/aer.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_device.h>
@@ -645,7 +646,7 @@
  * down the SLI Layer.
  *
  * Return codes
- *   0 - sucess.
+ *   0 - success.
  *   Any other value - error.
  **/
 static int
@@ -700,7 +701,7 @@
  * down the SLI Layer.
  *
  * Return codes
- *   0 - sucess.
+ *   0 - success.
  *   Any other value - error.
  **/
 static int
@@ -755,7 +756,7 @@
  * uninitialization after the HBA is reset when bring down the SLI Layer.
  *
  * Return codes
- *   0 - sucess.
+ *   0 - success.
  *   Any other value - error.
  **/
 int
@@ -852,12 +853,19 @@
 void
 lpfc_hb_timeout_handler(struct lpfc_hba *phba)
 {
+	struct lpfc_vport **vports;
 	LPFC_MBOXQ_t *pmboxq;
 	struct lpfc_dmabuf *buf_ptr;
-	int retval;
+	int retval, i;
 	struct lpfc_sli *psli = &phba->sli;
 	LIST_HEAD(completions);
 
+	vports = lpfc_create_vport_work_array(phba);
+	if (vports != NULL)
+		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++)
+			lpfc_rcv_seq_check_edtov(vports[i]);
+	lpfc_destroy_vport_work_array(phba, vports);
+
 	if ((phba->link_state == LPFC_HBA_ERROR) ||
 		(phba->pport->load_flag & FC_UNLOADING) ||
 		(phba->pport->fc_flag & FC_OFFLINE_MODE))
@@ -1254,7 +1262,7 @@
  * routine from the API jump table function pointer from the lpfc_hba struct.
  *
  * Return codes
- *   0 - sucess.
+ *   0 - success.
  *   Any other value - error.
  **/
 void
@@ -1521,10 +1529,10 @@
 	int GE = 0;
 	int oneConnect = 0; /* default is not a oneConnect */
 	struct {
-		char * name;
-		int    max_speed;
-		char * bus;
-	} m = {"<Unknown>", 0, ""};
+		char *name;
+		char *bus;
+		char *function;
+	} m = {"<Unknown>", "", ""};
 
 	if (mdp && mdp[0] != '\0'
 		&& descp && descp[0] != '\0')
@@ -1545,132 +1553,155 @@
 
 	switch (dev_id) {
 	case PCI_DEVICE_ID_FIREFLY:
-		m = (typeof(m)){"LP6000", max_speed, "PCI"};
+		m = (typeof(m)){"LP6000", "PCI", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_SUPERFLY:
 		if (vp->rev.biuRev >= 1 && vp->rev.biuRev <= 3)
-			m = (typeof(m)){"LP7000", max_speed,  "PCI"};
+			m = (typeof(m)){"LP7000", "PCI",
+					"Fibre Channel Adapter"};
 		else
-			m = (typeof(m)){"LP7000E", max_speed, "PCI"};
+			m = (typeof(m)){"LP7000E", "PCI",
+					"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_DRAGONFLY:
-		m = (typeof(m)){"LP8000", max_speed, "PCI"};
+		m = (typeof(m)){"LP8000", "PCI",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_CENTAUR:
 		if (FC_JEDEC_ID(vp->rev.biuRev) == CENTAUR_2G_JEDEC_ID)
-			m = (typeof(m)){"LP9002", max_speed, "PCI"};
+			m = (typeof(m)){"LP9002", "PCI",
+					"Fibre Channel Adapter"};
 		else
-			m = (typeof(m)){"LP9000", max_speed, "PCI"};
+			m = (typeof(m)){"LP9000", "PCI",
+					"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_RFLY:
-		m = (typeof(m)){"LP952", max_speed, "PCI"};
+		m = (typeof(m)){"LP952", "PCI",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_PEGASUS:
-		m = (typeof(m)){"LP9802", max_speed, "PCI-X"};
+		m = (typeof(m)){"LP9802", "PCI-X",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_THOR:
-		m = (typeof(m)){"LP10000", max_speed, "PCI-X"};
+		m = (typeof(m)){"LP10000", "PCI-X",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_VIPER:
-		m = (typeof(m)){"LPX1000", max_speed,  "PCI-X"};
+		m = (typeof(m)){"LPX1000",  "PCI-X",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_PFLY:
-		m = (typeof(m)){"LP982", max_speed, "PCI-X"};
+		m = (typeof(m)){"LP982", "PCI-X",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_TFLY:
-		m = (typeof(m)){"LP1050", max_speed, "PCI-X"};
+		m = (typeof(m)){"LP1050", "PCI-X",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_HELIOS:
-		m = (typeof(m)){"LP11000", max_speed, "PCI-X2"};
+		m = (typeof(m)){"LP11000", "PCI-X2",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_HELIOS_SCSP:
-		m = (typeof(m)){"LP11000-SP", max_speed, "PCI-X2"};
+		m = (typeof(m)){"LP11000-SP", "PCI-X2",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_HELIOS_DCSP:
-		m = (typeof(m)){"LP11002-SP", max_speed, "PCI-X2"};
+		m = (typeof(m)){"LP11002-SP",  "PCI-X2",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_NEPTUNE:
-		m = (typeof(m)){"LPe1000", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe1000", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_NEPTUNE_SCSP:
-		m = (typeof(m)){"LPe1000-SP", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe1000-SP", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_NEPTUNE_DCSP:
-		m = (typeof(m)){"LPe1002-SP", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe1002-SP", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_BMID:
-		m = (typeof(m)){"LP1150", max_speed, "PCI-X2"};
+		m = (typeof(m)){"LP1150", "PCI-X2", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_BSMB:
-		m = (typeof(m)){"LP111", max_speed, "PCI-X2"};
+		m = (typeof(m)){"LP111", "PCI-X2", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_ZEPHYR:
-		m = (typeof(m)){"LPe11000", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe11000", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_ZEPHYR_SCSP:
-		m = (typeof(m)){"LPe11000", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe11000", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_ZEPHYR_DCSP:
-		m = (typeof(m)){"LP2105", max_speed, "PCIe"};
+		m = (typeof(m)){"LP2105", "PCIe", "FCoE Adapter"};
 		GE = 1;
 		break;
 	case PCI_DEVICE_ID_ZMID:
-		m = (typeof(m)){"LPe1150", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe1150", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_ZSMB:
-		m = (typeof(m)){"LPe111", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe111", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_LP101:
-		m = (typeof(m)){"LP101", max_speed, "PCI-X"};
+		m = (typeof(m)){"LP101", "PCI-X", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_LP10000S:
-		m = (typeof(m)){"LP10000-S", max_speed, "PCI"};
+		m = (typeof(m)){"LP10000-S", "PCI", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_LP11000S:
-		m = (typeof(m)){"LP11000-S", max_speed,
-			"PCI-X2"};
+		m = (typeof(m)){"LP11000-S", "PCI-X2", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_LPE11000S:
-		m = (typeof(m)){"LPe11000-S", max_speed,
-			"PCIe"};
+		m = (typeof(m)){"LPe11000-S", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_SAT:
-		m = (typeof(m)){"LPe12000", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe12000", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_SAT_MID:
-		m = (typeof(m)){"LPe1250", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe1250", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_SAT_SMB:
-		m = (typeof(m)){"LPe121", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe121", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_SAT_DCSP:
-		m = (typeof(m)){"LPe12002-SP", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe12002-SP", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_SAT_SCSP:
-		m = (typeof(m)){"LPe12000-SP", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe12000-SP", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_SAT_S:
-		m = (typeof(m)){"LPe12000-S", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe12000-S", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_HORNET:
-		m = (typeof(m)){"LP21000", max_speed, "PCIe"};
+		m = (typeof(m)){"LP21000", "PCIe", "FCoE Adapter"};
 		GE = 1;
 		break;
 	case PCI_DEVICE_ID_PROTEUS_VF:
-		m = (typeof(m)) {"LPev12000", max_speed, "PCIe IOV"};
+		m = (typeof(m)){"LPev12000", "PCIe IOV",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_PROTEUS_PF:
-		m = (typeof(m)) {"LPev12000", max_speed, "PCIe IOV"};
+		m = (typeof(m)){"LPev12000", "PCIe IOV",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_PROTEUS_S:
-		m = (typeof(m)) {"LPemv12002-S", max_speed, "PCIe IOV"};
+		m = (typeof(m)){"LPemv12002-S", "PCIe IOV",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_TIGERSHARK:
 		oneConnect = 1;
-		m = (typeof(m)) {"OCe10100-F", max_speed, "PCIe"};
+		m = (typeof(m)){"OCe10100", "PCIe", "FCoE"};
+		break;
+	case PCI_DEVICE_ID_TOMCAT:
+		oneConnect = 1;
+		m = (typeof(m)){"OCe11100", "PCIe", "FCoE"};
+		break;
+	case PCI_DEVICE_ID_FALCON:
+		m = (typeof(m)){"LPSe12002-ML1-E", "PCIe",
+				"EmulexSecure Fibre"};
 		break;
 	default:
-		m = (typeof(m)){ NULL };
+		m = (typeof(m)){"Unknown", "", ""};
 		break;
 	}
 
@@ -1682,17 +1713,14 @@
 	if (descp && descp[0] == '\0') {
 		if (oneConnect)
 			snprintf(descp, 255,
-				"Emulex OneConnect %s, FCoE Initiator, Port %s",
-				m.name,
+				"Emulex OneConnect %s, %s Initiator, Port %s",
+				m.name, m.function,
 				phba->Port);
 		else
 			snprintf(descp, 255,
 				"Emulex %s %d%s %s %s",
-				m.name, m.max_speed,
-				(GE) ? "GE" : "Gb",
-				m.bus,
-				(GE) ? "FCoE Adapter" :
-					"Fibre Channel Adapter");
+				m.name, max_speed, (GE) ? "GE" : "Gb",
+				m.bus, m.function);
 	}
 }
 
@@ -2217,7 +2245,7 @@
 
 			if (vports[i]->load_flag & FC_UNLOADING)
 				continue;
-			vports[i]->vfi_state &= ~LPFC_VFI_REGISTERED;
+			vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED;
 			shost =	lpfc_shost_from_vport(vports[i]);
 			list_for_each_entry_safe(ndlp, next_ndlp,
 						 &vports[i]->fc_nodes,
@@ -2308,6 +2336,7 @@
 
 	spin_lock_irq(&phba->hbalock);
 	/* Release all the lpfc_scsi_bufs maintained by this host. */
+	spin_lock(&phba->scsi_buf_list_lock);
 	list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list, list) {
 		list_del(&sb->list);
 		pci_pool_free(phba->lpfc_scsi_dma_buf_pool, sb->data,
@@ -2315,6 +2344,7 @@
 		kfree(sb);
 		phba->total_scsi_bufs--;
 	}
+	spin_unlock(&phba->scsi_buf_list_lock);
 
 	/* Release all the lpfc_iocbq entries maintained by this host. */
 	list_for_each_entry_safe(io, io_next, &phba->lpfc_iocb_list, list) {
@@ -2322,9 +2352,7 @@
 		kfree(io);
 		phba->total_iocbq_bufs--;
 	}
-
 	spin_unlock_irq(&phba->hbalock);
-
 	return 0;
 }
 
@@ -2408,7 +2436,7 @@
 	vport->els_tmofunc.function = lpfc_els_timeout;
 	vport->els_tmofunc.data = (unsigned long)vport;
 
-	error = scsi_add_host(shost, dev);
+	error = scsi_add_host_with_dma(shost, dev, &phba->pcidev->dev);
 	if (error)
 		goto out_put_shost;
 
@@ -2699,6 +2727,63 @@
 }
 
 /**
+ * lpfc_sli4_fw_cfg_check - Read the firmware config and verify FCoE support
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This function uses the QUERY_FW_CFG mailbox command to determine if the
+ * firmware loaded supports FCoE. A return of zero indicates that the mailbox
+ * was successful and the firmware supports FCoE. Any other return indicates
+ * a error. It is assumed that this function will be called before interrupts
+ * are enabled.
+ **/
+static int
+lpfc_sli4_fw_cfg_check(struct lpfc_hba *phba)
+{
+	int rc = 0;
+	LPFC_MBOXQ_t *mboxq;
+	struct lpfc_mbx_query_fw_cfg *query_fw_cfg;
+	uint32_t length;
+	uint32_t shdr_status, shdr_add_status;
+
+	mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!mboxq) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+				"2621 Failed to allocate mbox for "
+				"query firmware config cmd\n");
+		return -ENOMEM;
+	}
+	query_fw_cfg = &mboxq->u.mqe.un.query_fw_cfg;
+	length = (sizeof(struct lpfc_mbx_query_fw_cfg) -
+		  sizeof(struct lpfc_sli4_cfg_mhdr));
+	lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON,
+			 LPFC_MBOX_OPCODE_QUERY_FW_CFG,
+			 length, LPFC_SLI4_MBX_EMBED);
+	rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
+	/* The IOCTL status is embedded in the mailbox subheader. */
+	shdr_status = bf_get(lpfc_mbox_hdr_status,
+			     &query_fw_cfg->header.cfg_shdr.response);
+	shdr_add_status = bf_get(lpfc_mbox_hdr_add_status,
+				 &query_fw_cfg->header.cfg_shdr.response);
+	if (shdr_status || shdr_add_status || rc != MBX_SUCCESS) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+				"2622 Query Firmware Config failed "
+				"mbx status x%x, status x%x add_status x%x\n",
+				rc, shdr_status, shdr_add_status);
+		return -EINVAL;
+	}
+	if (!bf_get(lpfc_function_mode_fcoe_i, query_fw_cfg)) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+				"2623 FCoE Function not supported by firmware. "
+				"Function mode = %08x\n",
+				query_fw_cfg->function_mode);
+		return -EINVAL;
+	}
+	if (rc != MBX_TIMEOUT)
+		mempool_free(mboxq, phba->mbox_mem_pool);
+	return 0;
+}
+
+/**
  * lpfc_sli4_parse_latt_fault - Parse sli4 link-attention link fault code
  * @phba: pointer to lpfc hba data structure.
  * @acqe_link: pointer to the async link completion queue entry.
@@ -2918,13 +3003,17 @@
 {
 	uint8_t event_type = bf_get(lpfc_acqe_fcoe_event_type, acqe_fcoe);
 	int rc;
+	struct lpfc_vport *vport;
+	struct lpfc_nodelist *ndlp;
+	struct Scsi_Host  *shost;
 
+	phba->fc_eventTag = acqe_fcoe->event_tag;
 	phba->fcoe_eventtag = acqe_fcoe->event_tag;
 	switch (event_type) {
 	case LPFC_FCOE_EVENT_TYPE_NEW_FCF:
 		lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
 			"2546 New FCF found index 0x%x tag 0x%x\n",
-			acqe_fcoe->fcf_index,
+			acqe_fcoe->index,
 			acqe_fcoe->event_tag);
 		/*
 		 * If the current FCF is in discovered state, or
@@ -2939,12 +3028,11 @@
 		spin_unlock_irq(&phba->hbalock);
 
 		/* Read the FCF table and re-discover SAN. */
-		rc = lpfc_sli4_read_fcf_record(phba,
-			LPFC_FCOE_FCF_GET_FIRST);
+		rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST);
 		if (rc)
 			lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
-				"2547 Read FCF record failed 0x%x\n",
-				rc);
+					"2547 Read FCF record failed 0x%x\n",
+					rc);
 		break;
 
 	case LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL:
@@ -2956,11 +3044,11 @@
 
 	case LPFC_FCOE_EVENT_TYPE_FCF_DEAD:
 		lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
-			"2549 FCF disconnected fron network index 0x%x"
-			" tag 0x%x\n", acqe_fcoe->fcf_index,
+			"2549 FCF disconnected from network index 0x%x"
+			" tag 0x%x\n", acqe_fcoe->index,
 			acqe_fcoe->event_tag);
 		/* If the event is not for currently used fcf do nothing */
-		if (phba->fcf.fcf_indx != acqe_fcoe->fcf_index)
+		if (phba->fcf.fcf_indx != acqe_fcoe->index)
 			break;
 		/*
 		 * Currently, driver support only one FCF - so treat this as
@@ -2970,7 +3058,28 @@
 		/* Unregister FCF if no devices connected to it */
 		lpfc_unregister_unused_fcf(phba);
 		break;
-
+	case LPFC_FCOE_EVENT_TYPE_CVL:
+		lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
+			"2718 Clear Virtual Link Received for VPI 0x%x"
+			" tag 0x%x\n", acqe_fcoe->index, acqe_fcoe->event_tag);
+		vport = lpfc_find_vport_by_vpid(phba,
+				acqe_fcoe->index - phba->vpi_base);
+		if (!vport)
+			break;
+		ndlp = lpfc_findnode_did(vport, Fabric_DID);
+		if (!ndlp)
+			break;
+		shost = lpfc_shost_from_vport(vport);
+		lpfc_linkdown_port(vport);
+		if (vport->port_type != LPFC_NPIV_PORT) {
+			mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
+			spin_lock_irq(shost->host_lock);
+			ndlp->nlp_flag |= NLP_DELAY_TMO;
+			spin_unlock_irq(shost->host_lock);
+			ndlp->nlp_last_elscmd = ELS_CMD_FLOGI;
+			vport->port_state = LPFC_FLOGI;
+		}
+		break;
 	default:
 		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
 			"0288 Unknown FCoE event type 0x%x event tag "
@@ -2990,6 +3099,7 @@
 lpfc_sli4_async_dcbx_evt(struct lpfc_hba *phba,
 			 struct lpfc_acqe_dcbx *acqe_dcbx)
 {
+	phba->fc_eventTag = acqe_dcbx->event_tag;
 	lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
 			"0290 The SLI4 DCBX asynchronous event is not "
 			"handled yet\n");
@@ -3124,7 +3234,7 @@
  * PCI devices.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	other values - error
  **/
 static int
@@ -3220,7 +3330,7 @@
  * support the SLI-3 HBA device it attached to.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	other values - error
  **/
 static int
@@ -3321,7 +3431,7 @@
  * support the SLI-4 HBA device it attached to.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	other values - error
  **/
 static int
@@ -3432,7 +3542,7 @@
 	/* Driver internel slow-path CQ Event pool */
 	INIT_LIST_HEAD(&phba->sli4_hba.sp_cqe_event_pool);
 	/* Response IOCB work queue list */
-	INIT_LIST_HEAD(&phba->sli4_hba.sp_rspiocb_work_queue);
+	INIT_LIST_HEAD(&phba->sli4_hba.sp_queue_event);
 	/* Asynchronous event CQ Event work queue list */
 	INIT_LIST_HEAD(&phba->sli4_hba.sp_asynce_work_queue);
 	/* Fast-path XRI aborted CQ Event work queue list */
@@ -3461,6 +3571,10 @@
 	if (unlikely(rc))
 		goto out_free_bsmbx;
 
+	rc = lpfc_sli4_fw_cfg_check(phba);
+	if (unlikely(rc))
+		goto out_free_bsmbx;
+
 	/* Set up the hba's configuration parameters. */
 	rc = lpfc_sli4_read_config(phba);
 	if (unlikely(rc))
@@ -3594,8 +3708,10 @@
 
 	/* Free the current connect table */
 	list_for_each_entry_safe(conn_entry, next_conn_entry,
-		&phba->fcf_conn_rec_list, list)
+		&phba->fcf_conn_rec_list, list) {
+		list_del_init(&conn_entry->list);
 		kfree(conn_entry);
+	}
 
 	return;
 }
@@ -3642,7 +3758,7 @@
  * device specific resource setup to support the HBA device it attached to.
  *
  * Return codes
- *	0 - sucessful
+ *	0 - successful
  *	other values - error
  **/
 static int
@@ -3688,7 +3804,7 @@
  * device specific resource setup to support the HBA device it attached to.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	other values - error
  **/
 static int
@@ -3753,7 +3869,7 @@
  * list and set up the IOCB tag array accordingly.
  *
  * Return codes
- *	0 - sucessful
+ *	0 - successful
  *	other values - error
  **/
 static int
@@ -3824,7 +3940,7 @@
 	rc = lpfc_sli4_remove_all_sgl_pages(phba);
 	if (rc) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
-			"2005 Unable to deregister pages from HBA: %x", rc);
+			"2005 Unable to deregister pages from HBA: %x\n", rc);
 	}
 	kfree(phba->sli4_hba.lpfc_els_sgl_array);
 }
@@ -3872,7 +3988,7 @@
  * list and set up the sgl xritag tag array accordingly.
  *
  * Return codes
- *	0 - sucessful
+ *	0 - successful
  *	other values - error
  **/
 static int
@@ -3986,7 +4102,7 @@
  * enabled and the driver is reinitializing the device.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	ENOMEM - No availble memory
  *      EIO - The mailbox failed to complete successfully.
  **/
@@ -4146,7 +4262,7 @@
  * PCI device data structure is set.
  *
  * Return codes
- *      pointer to @phba - sucessful
+ *      pointer to @phba - successful
  *      NULL - error
  **/
 static struct lpfc_hba *
@@ -4202,7 +4318,7 @@
  * host with it.
  *
  * Return codes
- *      0 - sucessful
+ *      0 - successful
  *      other values - error
  **/
 static int
@@ -4273,7 +4389,8 @@
 			_dump_buf_data =
 				(char *) __get_free_pages(GFP_KERNEL, pagecnt);
 			if (_dump_buf_data) {
-				printk(KERN_ERR "BLKGRD allocated %d pages for "
+				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+					"9043 BLKGRD: allocated %d pages for "
 				       "_dump_buf_data at 0x%p\n",
 				       (1 << pagecnt), _dump_buf_data);
 				_dump_buf_data_order = pagecnt;
@@ -4284,17 +4401,20 @@
 				--pagecnt;
 		}
 		if (!_dump_buf_data_order)
-			printk(KERN_ERR "BLKGRD ERROR unable to allocate "
+			lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+				"9044 BLKGRD: ERROR unable to allocate "
 			       "memory for hexdump\n");
 	} else
-		printk(KERN_ERR "BLKGRD already allocated _dump_buf_data=0x%p"
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+			"9045 BLKGRD: already allocated _dump_buf_data=0x%p"
 		       "\n", _dump_buf_data);
 	if (!_dump_buf_dif) {
 		while (pagecnt) {
 			_dump_buf_dif =
 				(char *) __get_free_pages(GFP_KERNEL, pagecnt);
 			if (_dump_buf_dif) {
-				printk(KERN_ERR "BLKGRD allocated %d pages for "
+				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+					"9046 BLKGRD: allocated %d pages for "
 				       "_dump_buf_dif at 0x%p\n",
 				       (1 << pagecnt), _dump_buf_dif);
 				_dump_buf_dif_order = pagecnt;
@@ -4305,10 +4425,12 @@
 				--pagecnt;
 		}
 		if (!_dump_buf_dif_order)
-			printk(KERN_ERR "BLKGRD ERROR unable to allocate "
+			lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+			"9047 BLKGRD: ERROR unable to allocate "
 			       "memory for hexdump\n");
 	} else
-		printk(KERN_ERR "BLKGRD already allocated _dump_buf_dif=0x%p\n",
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+			"9048 BLKGRD: already allocated _dump_buf_dif=0x%p\n",
 		       _dump_buf_dif);
 }
 
@@ -4365,7 +4487,7 @@
  * with SLI-3 interface spec.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	other values - error
  **/
 static int
@@ -4512,7 +4634,6 @@
 lpfc_sli4_post_status_check(struct lpfc_hba *phba)
 {
 	struct lpfc_register sta_reg, uerrlo_reg, uerrhi_reg, scratchpad;
-	uint32_t onlnreg0, onlnreg1;
 	int i, port_error = -ENODEV;
 
 	if (!phba->sli4_hba.STAregaddr)
@@ -4556,21 +4677,20 @@
 			bf_get(lpfc_scratchpad_slirev, &scratchpad),
 			bf_get(lpfc_scratchpad_featurelevel1, &scratchpad),
 			bf_get(lpfc_scratchpad_featurelevel2, &scratchpad));
-
+	phba->sli4_hba.ue_mask_lo = readl(phba->sli4_hba.UEMASKLOregaddr);
+	phba->sli4_hba.ue_mask_hi = readl(phba->sli4_hba.UEMASKHIregaddr);
 	/* With uncoverable error, log the error message and return error */
-	onlnreg0 = readl(phba->sli4_hba.ONLINE0regaddr);
-	onlnreg1 = readl(phba->sli4_hba.ONLINE1regaddr);
-	if ((onlnreg0 != LPFC_ONLINE_NERR) || (onlnreg1 != LPFC_ONLINE_NERR)) {
-		uerrlo_reg.word0 = readl(phba->sli4_hba.UERRLOregaddr);
-		uerrhi_reg.word0 = readl(phba->sli4_hba.UERRHIregaddr);
-		if (uerrlo_reg.word0 || uerrhi_reg.word0) {
-			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-					"1422 HBA Unrecoverable error: "
-					"uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, "
-					"online0_reg=0x%x, online1_reg=0x%x\n",
-					uerrlo_reg.word0, uerrhi_reg.word0,
-					onlnreg0, onlnreg1);
-		}
+	uerrlo_reg.word0 = readl(phba->sli4_hba.UERRLOregaddr);
+	uerrhi_reg.word0 = readl(phba->sli4_hba.UERRHIregaddr);
+	if ((~phba->sli4_hba.ue_mask_lo & uerrlo_reg.word0) ||
+	    (~phba->sli4_hba.ue_mask_hi & uerrhi_reg.word0)) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+				"1422 HBA Unrecoverable error: "
+				"uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, "
+				"ue_mask_lo_reg=0x%x, ue_mask_hi_reg=0x%x\n",
+				uerrlo_reg.word0, uerrhi_reg.word0,
+				phba->sli4_hba.ue_mask_lo,
+				phba->sli4_hba.ue_mask_hi);
 		return -ENODEV;
 	}
 
@@ -4591,10 +4711,10 @@
 					LPFC_UERR_STATUS_LO;
 	phba->sli4_hba.UERRHIregaddr = phba->sli4_hba.conf_regs_memmap_p +
 					LPFC_UERR_STATUS_HI;
-	phba->sli4_hba.ONLINE0regaddr = phba->sli4_hba.conf_regs_memmap_p +
-					LPFC_ONLINE0;
-	phba->sli4_hba.ONLINE1regaddr = phba->sli4_hba.conf_regs_memmap_p +
-					LPFC_ONLINE1;
+	phba->sli4_hba.UEMASKLOregaddr = phba->sli4_hba.conf_regs_memmap_p +
+					LPFC_UE_MASK_LO;
+	phba->sli4_hba.UEMASKHIregaddr = phba->sli4_hba.conf_regs_memmap_p +
+					LPFC_UE_MASK_HI;
 	phba->sli4_hba.SCRATCHPADregaddr = phba->sli4_hba.conf_regs_memmap_p +
 					LPFC_SCRATCHPAD;
 }
@@ -4662,7 +4782,7 @@
  * this routine.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	ENOMEM - could not allocated memory.
  **/
 static int
@@ -4761,7 +4881,7 @@
  * allocation for the port.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	ENOMEM - No availble memory
  *      EIO - The mailbox failed to complete successfully.
  **/
@@ -4825,7 +4945,8 @@
 		phba->vpi_base = phba->sli4_hba.max_cfg_param.vpi_base;
 		phba->vfi_base = phba->sli4_hba.max_cfg_param.vfi_base;
 		phba->sli4_hba.next_rpi = phba->sli4_hba.max_cfg_param.rpi_base;
-		phba->max_vpi = phba->sli4_hba.max_cfg_param.max_vpi;
+		phba->max_vpi = (phba->sli4_hba.max_cfg_param.max_vpi > 0) ?
+				(phba->sli4_hba.max_cfg_param.max_vpi - 1) : 0;
 		phba->max_vports = phba->max_vpi;
 		lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
 				"2003 cfg params XRI(B:%d M:%d), "
@@ -4861,7 +4982,7 @@
  * HBA consistent with the SLI-4 interface spec.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	ENOMEM - No availble memory
  *      EIO - The mailbox failed to complete successfully.
  **/
@@ -4910,7 +5031,7 @@
  * we just use some constant number as place holder.
  *
  * Return codes
- *      0 - sucessful
+ *      0 - successful
  *      ENOMEM - No availble memory
  *      EIO - The mailbox failed to complete successfully.
  **/
@@ -4979,10 +5100,9 @@
 	/* It does not make sense to have more EQs than WQs */
 	if (cfg_fcp_eq_count > phba->cfg_fcp_wq_count) {
 		lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
-				"2593 The number of FCP EQs (%d) is more "
-				"than the number of FCP WQs (%d), take "
-				"the number of FCP EQs same as than of "
-				"WQs (%d)\n", cfg_fcp_eq_count,
+				"2593 The FCP EQ count(%d) cannot be greater "
+				"than the FCP WQ count(%d), limiting the "
+				"FCP EQ count to %d\n", cfg_fcp_eq_count,
 				phba->cfg_fcp_wq_count,
 				phba->cfg_fcp_wq_count);
 		cfg_fcp_eq_count = phba->cfg_fcp_wq_count;
@@ -5058,15 +5178,6 @@
 	}
 	phba->sli4_hba.els_cq = qdesc;
 
-	/* Create slow-path Unsolicited Receive Complete Queue */
-	qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.cq_esize,
-				      phba->sli4_hba.cq_ecount);
-	if (!qdesc) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-				"0502 Failed allocate slow-path USOL RX CQ\n");
-		goto out_free_els_cq;
-	}
-	phba->sli4_hba.rxq_cq = qdesc;
 
 	/* Create fast-path FCP Completion Queue(s), one-to-one with EQs */
 	phba->sli4_hba.fcp_cq = kzalloc((sizeof(struct lpfc_queue *) *
@@ -5075,7 +5186,7 @@
 		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 				"2577 Failed allocate memory for fast-path "
 				"CQ record array\n");
-		goto out_free_rxq_cq;
+		goto out_free_els_cq;
 	}
 	for (fcp_cqidx = 0; fcp_cqidx < phba->cfg_fcp_eq_count; fcp_cqidx++) {
 		qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.cq_esize,
@@ -5188,9 +5299,6 @@
 		phba->sli4_hba.fcp_cq[fcp_cqidx] = NULL;
 	}
 	kfree(phba->sli4_hba.fcp_cq);
-out_free_rxq_cq:
-	lpfc_sli4_queue_free(phba->sli4_hba.rxq_cq);
-	phba->sli4_hba.rxq_cq = NULL;
 out_free_els_cq:
 	lpfc_sli4_queue_free(phba->sli4_hba.els_cq);
 	phba->sli4_hba.els_cq = NULL;
@@ -5218,7 +5326,7 @@
  * operation.
  *
  * Return codes
- *      0 - sucessful
+ *      0 - successful
  *      ENOMEM - No availble memory
  *      EIO - The mailbox failed to complete successfully.
  **/
@@ -5247,10 +5355,6 @@
 	lpfc_sli4_queue_free(phba->sli4_hba.dat_rq);
 	phba->sli4_hba.dat_rq = NULL;
 
-	/* Release unsolicited receive complete queue */
-	lpfc_sli4_queue_free(phba->sli4_hba.rxq_cq);
-	phba->sli4_hba.rxq_cq = NULL;
-
 	/* Release ELS complete queue */
 	lpfc_sli4_queue_free(phba->sli4_hba.els_cq);
 	phba->sli4_hba.els_cq = NULL;
@@ -5286,7 +5390,7 @@
  * operation.
  *
  * Return codes
- *      0 - sucessful
+ *      0 - successful
  *      ENOMEM - No availble memory
  *      EIO - The mailbox failed to complete successfully.
  **/
@@ -5383,25 +5487,6 @@
 			phba->sli4_hba.els_cq->queue_id,
 			phba->sli4_hba.sp_eq->queue_id);
 
-	/* Set up slow-path Unsolicited Receive Complete Queue */
-	if (!phba->sli4_hba.rxq_cq) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-				"0532 USOL RX CQ not allocated\n");
-		goto out_destroy_els_cq;
-	}
-	rc = lpfc_cq_create(phba, phba->sli4_hba.rxq_cq, phba->sli4_hba.sp_eq,
-			    LPFC_RCQ, LPFC_USOL);
-	if (rc) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-				"0533 Failed setup of slow-path USOL RX CQ: "
-				"rc = 0x%x\n", rc);
-		goto out_destroy_els_cq;
-	}
-	lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-			"2587 USL CQ setup: cq-id=%d, parent eq-id=%d\n",
-			phba->sli4_hba.rxq_cq->queue_id,
-			phba->sli4_hba.sp_eq->queue_id);
-
 	/* Set up fast-path FCP Response Complete Queue */
 	for (fcp_cqidx = 0; fcp_cqidx < phba->cfg_fcp_eq_count; fcp_cqidx++) {
 		if (!phba->sli4_hba.fcp_cq[fcp_cqidx]) {
@@ -5507,7 +5592,7 @@
 		goto out_destroy_fcp_wq;
 	}
 	rc = lpfc_rq_create(phba, phba->sli4_hba.hdr_rq, phba->sli4_hba.dat_rq,
-			    phba->sli4_hba.rxq_cq, LPFC_USOL);
+			    phba->sli4_hba.els_cq, LPFC_USOL);
 	if (rc) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 				"0541 Failed setup of Receive Queue: "
@@ -5519,7 +5604,7 @@
 			"parent cq-id=%d\n",
 			phba->sli4_hba.hdr_rq->queue_id,
 			phba->sli4_hba.dat_rq->queue_id,
-			phba->sli4_hba.rxq_cq->queue_id);
+			phba->sli4_hba.els_cq->queue_id);
 	return 0;
 
 out_destroy_fcp_wq:
@@ -5531,8 +5616,6 @@
 out_destroy_fcp_cq:
 	for (--fcp_cqidx; fcp_cqidx >= 0; fcp_cqidx--)
 		lpfc_cq_destroy(phba, phba->sli4_hba.fcp_cq[fcp_cqidx]);
-	lpfc_cq_destroy(phba, phba->sli4_hba.rxq_cq);
-out_destroy_els_cq:
 	lpfc_cq_destroy(phba, phba->sli4_hba.els_cq);
 out_destroy_mbx_cq:
 	lpfc_cq_destroy(phba, phba->sli4_hba.mbx_cq);
@@ -5552,7 +5635,7 @@
  * operation.
  *
  * Return codes
- *      0 - sucessful
+ *      0 - successful
  *      ENOMEM - No availble memory
  *      EIO - The mailbox failed to complete successfully.
  **/
@@ -5574,8 +5657,6 @@
 	lpfc_cq_destroy(phba, phba->sli4_hba.mbx_cq);
 	/* Unset ELS complete queue */
 	lpfc_cq_destroy(phba, phba->sli4_hba.els_cq);
-	/* Unset unsolicited receive complete queue */
-	lpfc_cq_destroy(phba, phba->sli4_hba.rxq_cq);
 	/* Unset FCP response complete queue */
 	for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_eq_count; fcp_qidx++)
 		lpfc_cq_destroy(phba, phba->sli4_hba.fcp_cq[fcp_qidx]);
@@ -5599,7 +5680,7 @@
  * Later, this can be used for all the slow-path events.
  *
  * Return codes
- *      0 - sucessful
+ *      0 - successful
  *      -ENOMEM - No availble memory
  **/
 static int
@@ -5760,7 +5841,7 @@
  * all resources assigned to the PCI function which originates this request.
  *
  * Return codes
- *      0 - sucessful
+ *      0 - successful
  *      ENOMEM - No availble memory
  *      EIO - The mailbox failed to complete successfully.
  **/
@@ -5923,7 +6004,7 @@
  * with SLI-4 interface spec.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	other values - error
  **/
 static int
@@ -6052,7 +6133,7 @@
  * will be left with MSI-X enabled and leaks its vectors.
  *
  * Return codes
- *   0 - sucessful
+ *   0 - successful
  *   other values - error
  **/
 static int
@@ -6184,7 +6265,7 @@
  * is done in this function.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	other values - error
  */
 static int
@@ -6243,7 +6324,7 @@
  * MSI-X -> MSI -> IRQ.
  *
  * Return codes
- *   0 - sucessful
+ *   0 - successful
  *   other values - error
  **/
 static uint32_t
@@ -6333,7 +6414,7 @@
  * enabled and leaks its vectors.
  *
  * Return codes
- * 0 - sucessful
+ * 0 - successful
  * other values - error
  **/
 static int
@@ -6443,7 +6524,7 @@
  * which is done in this function.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	other values - error
  **/
 static int
@@ -6508,7 +6589,7 @@
  * MSI-X -> MSI -> IRQ.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	other values - error
  **/
 static uint32_t
@@ -6722,6 +6803,7 @@
 {
 	struct lpfc_hba   *phba;
 	struct lpfc_vport *vport = NULL;
+	struct Scsi_Host  *shost = NULL;
 	int error;
 	uint32_t cfg_mode, intr_mode;
 
@@ -6800,6 +6882,7 @@
 		goto out_destroy_shost;
 	}
 
+	shost = lpfc_shost_from_vport(vport); /* save shost for error cleanup */
 	/* Now, trying to enable interrupt and bring up the device */
 	cfg_mode = phba->cfg_use_msi;
 	while (true) {
@@ -6866,6 +6949,8 @@
 	lpfc_sli_pci_mem_unset(phba);
 out_disable_pci_dev:
 	lpfc_disable_pci_dev(phba);
+	if (shost)
+		scsi_host_put(shost);
 out_free_phba:
 	lpfc_hba_free(phba);
 	return error;
@@ -7036,6 +7121,7 @@
 	/* Restore device state from PCI config space */
 	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
+
 	if (pdev->is_busmaster)
 		pci_set_master(pdev);
 
@@ -7070,6 +7156,75 @@
 }
 
 /**
+ * lpfc_sli_prep_dev_for_recover - Prepare SLI3 device for pci slot recover
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is called to prepare the SLI3 device for PCI slot recover. It
+ * aborts and stops all the on-going I/Os on the pci device.
+ **/
+static void
+lpfc_sli_prep_dev_for_recover(struct lpfc_hba *phba)
+{
+	lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+			"2723 PCI channel I/O abort preparing for recovery\n");
+	/* Prepare for bringing HBA offline */
+	lpfc_offline_prep(phba);
+	/* Clear sli active flag to prevent sysfs access to HBA */
+	spin_lock_irq(&phba->hbalock);
+	phba->sli.sli_flag &= ~LPFC_SLI_ACTIVE;
+	spin_unlock_irq(&phba->hbalock);
+	/* Stop and flush all I/Os and bring HBA offline */
+	lpfc_offline(phba);
+}
+
+/**
+ * lpfc_sli_prep_dev_for_reset - Prepare SLI3 device for pci slot reset
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is called to prepare the SLI3 device for PCI slot reset. It
+ * disables the device interrupt and pci device, and aborts the internal FCP
+ * pending I/Os.
+ **/
+static void
+lpfc_sli_prep_dev_for_reset(struct lpfc_hba *phba)
+{
+	struct lpfc_sli *psli = &phba->sli;
+	struct lpfc_sli_ring  *pring;
+
+	lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+			"2710 PCI channel disable preparing for reset\n");
+	/* Disable interrupt and pci device */
+	lpfc_sli_disable_intr(phba);
+	pci_disable_device(phba->pcidev);
+	/*
+	 * There may be I/Os dropped by the firmware.
+	 * Error iocb (I/O) on txcmplq and let the SCSI layer
+	 * retry it after re-establishing link.
+	 */
+	pring = &psli->ring[psli->fcp_ring];
+	lpfc_sli_abort_iocb_ring(phba, pring);
+}
+
+/**
+ * lpfc_sli_prep_dev_for_perm_failure - Prepare SLI3 dev for pci slot disable
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is called to prepare the SLI3 device for PCI slot permanently
+ * disabling. It blocks the SCSI transport layer traffic and flushes the FCP
+ * pending I/Os.
+ **/
+static void
+lpfc_prep_dev_for_perm_failure(struct lpfc_hba *phba)
+{
+	lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+			"2711 PCI channel permanent disable for failure\n");
+	/* Block all SCSI devices' I/Os on the host */
+	lpfc_scsi_dev_block(phba);
+	/* Clean up all driver's outstanding SCSI I/Os */
+	lpfc_sli_flush_fcp_rings(phba);
+}
+
+/**
  * lpfc_io_error_detected_s3 - Method for handling SLI-3 device PCI I/O error
  * @pdev: pointer to PCI device.
  * @state: the current PCI connection state.
@@ -7083,6 +7238,7 @@
  * as desired.
  *
  * Return codes
+ * 	PCI_ERS_RESULT_CAN_RECOVER - can be recovered with reset_link
  * 	PCI_ERS_RESULT_NEED_RESET - need to reset before recovery
  * 	PCI_ERS_RESULT_DISCONNECT - device could not be recovered
  **/
@@ -7091,33 +7247,27 @@
 {
 	struct Scsi_Host *shost = pci_get_drvdata(pdev);
 	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
-	struct lpfc_sli *psli = &phba->sli;
-	struct lpfc_sli_ring  *pring;
 
-	if (state == pci_channel_io_perm_failure) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-				"0472 PCI channel I/O permanent failure\n");
-		/* Block all SCSI devices' I/Os on the host */
-		lpfc_scsi_dev_block(phba);
-		/* Clean up all driver's outstanding SCSI I/Os */
-		lpfc_sli_flush_fcp_rings(phba);
+	switch (state) {
+	case pci_channel_io_normal:
+		/* Non-fatal error, prepare for recovery */
+		lpfc_sli_prep_dev_for_recover(phba);
+		return PCI_ERS_RESULT_CAN_RECOVER;
+	case pci_channel_io_frozen:
+		/* Fatal error, prepare for slot reset */
+		lpfc_sli_prep_dev_for_reset(phba);
+		return PCI_ERS_RESULT_NEED_RESET;
+	case pci_channel_io_perm_failure:
+		/* Permanent failure, prepare for device down */
+		lpfc_prep_dev_for_perm_failure(phba);
 		return PCI_ERS_RESULT_DISCONNECT;
+	default:
+		/* Unknown state, prepare and request slot reset */
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+				"0472 Unknown PCI error state: x%x\n", state);
+		lpfc_sli_prep_dev_for_reset(phba);
+		return PCI_ERS_RESULT_NEED_RESET;
 	}
-
-	pci_disable_device(pdev);
-	/*
-	 * There may be I/Os dropped by the firmware.
-	 * Error iocb (I/O) on txcmplq and let the SCSI layer
-	 * retry it after re-establishing link.
-	 */
-	pring = &psli->ring[psli->fcp_ring];
-	lpfc_sli_abort_iocb_ring(phba, pring);
-
-	/* Disable interrupt */
-	lpfc_sli_disable_intr(phba);
-
-	/* Request a slot reset. */
-	return PCI_ERS_RESULT_NEED_RESET;
 }
 
 /**
@@ -7197,7 +7347,12 @@
 	struct Scsi_Host *shost = pci_get_drvdata(pdev);
 	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
 
+	/* Bring the device online */
 	lpfc_online(phba);
+
+	/* Clean up Advanced Error Reporting (AER) if needed */
+	if (phba->hba_flag & HBA_AER_ENABLED)
+		pci_cleanup_aer_uncorrect_error_status(pdev);
 }
 
 /**
@@ -7213,15 +7368,15 @@
 
 	if (phba->sli_rev == LPFC_SLI_REV4) {
 		if (max_xri <= 100)
-			return 4;
+			return 10;
 		else if (max_xri <= 256)
-			return 8;
+			return 25;
 		else if (max_xri <= 512)
-			return 16;
+			return 50;
 		else if (max_xri <= 1024)
-			return 32;
+			return 100;
 		else
-			return 48;
+			return 150;
 	} else
 		return 0;
 }
@@ -7249,6 +7404,7 @@
 {
 	struct lpfc_hba   *phba;
 	struct lpfc_vport *vport = NULL;
+	struct Scsi_Host  *shost = NULL;
 	int error;
 	uint32_t cfg_mode, intr_mode;
 	int mcnt;
@@ -7329,6 +7485,7 @@
 		goto out_destroy_shost;
 	}
 
+	shost = lpfc_shost_from_vport(vport); /* save shost for error cleanup */
 	/* Now, trying to enable interrupt and bring up the device */
 	cfg_mode = phba->cfg_use_msi;
 	while (true) {
@@ -7397,6 +7554,8 @@
 	lpfc_sli4_pci_mem_unset(phba);
 out_disable_pci_dev:
 	lpfc_disable_pci_dev(phba);
+	if (shost)
+		scsi_host_put(shost);
 out_free_phba:
 	lpfc_hba_free(phba);
 	return error;
@@ -7971,6 +8130,10 @@
 		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_SERVERENGINE, PCI_DEVICE_ID_TIGERSHARK,
 		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_SERVERENGINE, PCI_DEVICE_ID_TOMCAT,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_FALCON,
+		PCI_ANY_ID, PCI_ANY_ID, },
 	{ 0 }
 };
 
@@ -8053,15 +8216,15 @@
 	if (lpfc_enable_npiv)
 		fc_release_transport(lpfc_vport_transport_template);
 	if (_dump_buf_data) {
-		printk(KERN_ERR "BLKGRD freeing %lu pages for _dump_buf_data "
-				"at 0x%p\n",
+		printk(KERN_ERR	"9062 BLKGRD: freeing %lu pages for "
+				"_dump_buf_data at 0x%p\n",
 				(1L << _dump_buf_data_order), _dump_buf_data);
 		free_pages((unsigned long)_dump_buf_data, _dump_buf_data_order);
 	}
 
 	if (_dump_buf_dif) {
-		printk(KERN_ERR "BLKGRD freeing %lu pages for _dump_buf_dif "
-				"at 0x%p\n",
+		printk(KERN_ERR	"9049 BLKGRD: freeing %lu pages for "
+				"_dump_buf_dif at 0x%p\n",
 				(1L << _dump_buf_dif_order), _dump_buf_dif);
 		free_pages((unsigned long)_dump_buf_dif, _dump_buf_dif_order);
 	}
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index 1ab4059..a9afd8b 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -25,8 +25,8 @@
 
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_transport_fc.h>
-
 #include <scsi/scsi.h>
+#include <scsi/fc/fc_fs.h>
 
 #include "lpfc_hw4.h"
 #include "lpfc_hw.h"
@@ -820,6 +820,10 @@
 	mb->un.varRegVpi.vpi = vport->vpi + vport->phba->vpi_base;
 	mb->un.varRegVpi.sid = vport->fc_myDID;
 	mb->un.varRegVpi.vfi = vport->vfi + vport->phba->vfi_base;
+	memcpy(mb->un.varRegVpi.wwn, &vport->fc_portname,
+	       sizeof(struct lpfc_name));
+	mb->un.varRegVpi.wwn[0] = cpu_to_le32(mb->un.varRegVpi.wwn[0]);
+	mb->un.varRegVpi.wwn[1] = cpu_to_le32(mb->un.varRegVpi.wwn[1]);
 
 	mb->mbxCommand = MBX_REG_VPI;
 	mb->mbxOwner = OWN_HOST;
@@ -849,7 +853,10 @@
 	MAILBOX_t *mb = &pmb->u.mb;
 	memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
-	mb->un.varUnregVpi.vpi = vpi + phba->vpi_base;
+	if (phba->sli_rev < LPFC_SLI_REV4)
+		mb->un.varUnregVpi.vpi = vpi + phba->vpi_base;
+	else
+		mb->un.varUnregVpi.sli4_vpi = vpi + phba->vpi_base;
 
 	mb->mbxCommand = MBX_UNREG_VPI;
 	mb->mbxOwner = OWN_HOST;
@@ -1132,7 +1139,7 @@
 	/* Otherwise we setup specific rctl / type masks for this ring */
 	for (i = 0; i < pring->num_mask; i++) {
 		mb->un.varCfgRing.rrRegs[i].rval = pring->prt[i].rctl;
-		if (mb->un.varCfgRing.rrRegs[i].rval != FC_ELS_REQ)
+		if (mb->un.varCfgRing.rrRegs[i].rval != FC_RCTL_ELS_REQ)
 			mb->un.varCfgRing.rrRegs[i].rmask = 0xff;
 		else
 			mb->un.varCfgRing.rrRegs[i].rmask = 0xfe;
@@ -1654,9 +1661,12 @@
 	/* Allocate record for keeping SGE virtual addresses */
 	mbox->sge_array = kmalloc(sizeof(struct lpfc_mbx_nembed_sge_virt),
 				  GFP_KERNEL);
-	if (!mbox->sge_array)
+	if (!mbox->sge_array) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
+				"2527 Failed to allocate non-embedded SGE "
+				"array.\n");
 		return 0;
-
+	}
 	for (pagen = 0, alloc_len = 0; pagen < pcount; pagen++) {
 		/* The DMA memory is always allocated in the length of a
 		 * page even though the last SGE might not fill up to a
@@ -1753,11 +1763,6 @@
 	/* Set up host requested features. */
 	bf_set(lpfc_mbx_rq_ftr_rq_fcpi, &mboxq->u.mqe.un.req_ftrs, 1);
 
-	if (phba->cfg_enable_fip)
-		bf_set(lpfc_mbx_rq_ftr_rq_ifip, &mboxq->u.mqe.un.req_ftrs, 0);
-	else
-		bf_set(lpfc_mbx_rq_ftr_rq_ifip, &mboxq->u.mqe.un.req_ftrs, 1);
-
 	/* Enable DIF (block guard) only if configured to do so. */
 	if (phba->cfg_enable_bg)
 		bf_set(lpfc_mbx_rq_ftr_rq_dif, &mboxq->u.mqe.un.req_ftrs, 1);
@@ -1817,6 +1822,9 @@
 	bf_set(lpfc_reg_vfi_vfi, reg_vfi, vport->vfi + vport->phba->vfi_base);
 	bf_set(lpfc_reg_vfi_fcfi, reg_vfi, vport->phba->fcf.fcfi);
 	bf_set(lpfc_reg_vfi_vpi, reg_vfi, vport->vpi + vport->phba->vpi_base);
+	memcpy(reg_vfi->wwn, &vport->fc_portname, sizeof(struct lpfc_name));
+	reg_vfi->wwn[0] = cpu_to_le32(reg_vfi->wwn[0]);
+	reg_vfi->wwn[1] = cpu_to_le32(reg_vfi->wwn[1]);
 	reg_vfi->bde.addrHigh = putPaddrHigh(phys);
 	reg_vfi->bde.addrLow = putPaddrLow(phys);
 	reg_vfi->bde.tus.f.bdeSize = sizeof(vport->fc_sparam);
@@ -1850,7 +1858,7 @@
 /**
  * lpfc_unreg_vfi - Initialize the UNREG_VFI mailbox command
  * @mbox: pointer to lpfc mbox command to initialize.
- * @vfi: VFI to be unregistered.
+ * @vport: vport associated with the VF.
  *
  * The UNREG_VFI mailbox command causes the SLI Host to put a virtual fabric
  * (logical NPort) into the inactive state. The SLI Host must have logged out
@@ -1859,11 +1867,12 @@
  * fabric inactive.
  **/
 void
-lpfc_unreg_vfi(struct lpfcMboxq *mbox, uint16_t vfi)
+lpfc_unreg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport)
 {
 	memset(mbox, 0, sizeof(*mbox));
 	bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_UNREG_VFI);
-	bf_set(lpfc_unreg_vfi_vfi, &mbox->u.mqe.un.unreg_vfi, vfi);
+	bf_set(lpfc_unreg_vfi_vfi, &mbox->u.mqe.un.unreg_vfi,
+	       vport->vfi + vport->phba->vfi_base);
 }
 
 /**
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 3e74136..2ed6af1 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -1223,6 +1223,12 @@
 	list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {
 		if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
 		   (ndlp == (struct lpfc_nodelist *) mb->context2)) {
+			if (phba->sli_rev == LPFC_SLI_REV4) {
+				spin_unlock_irq(&phba->hbalock);
+				lpfc_sli4_free_rpi(phba,
+					mb->u.mb.un.varRegLogin.rpi);
+				spin_lock_irq(&phba->hbalock);
+			}
 			mp = (struct lpfc_dmabuf *) (mb->context1);
 			if (mp) {
 				__lpfc_mbuf_free(phba, mp->virt, mp->phys);
@@ -1230,6 +1236,7 @@
 			}
 			lpfc_nlp_put(ndlp);
 			list_del(&mb->list);
+			phba->sli.mboxq_cnt--;
 			mempool_free(mb, phba->mbox_mem_pool);
 		}
 	}
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index c88f59f..a246410 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -59,22 +59,26 @@
 };
 static void
 lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb);
+static void
+lpfc_release_scsi_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb);
 
 static void
-lpfc_debug_save_data(struct scsi_cmnd *cmnd)
+lpfc_debug_save_data(struct lpfc_hba *phba, struct scsi_cmnd *cmnd)
 {
 	void *src, *dst;
 	struct scatterlist *sgde = scsi_sglist(cmnd);
 
 	if (!_dump_buf_data) {
-		printk(KERN_ERR "BLKGRD ERROR %s _dump_buf_data is NULL\n",
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+			"9050 BLKGRD: ERROR %s _dump_buf_data is NULL\n",
 				__func__);
 		return;
 	}
 
 
 	if (!sgde) {
-		printk(KERN_ERR "BLKGRD ERROR: data scatterlist is null\n");
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+			"9051 BLKGRD: ERROR: data scatterlist is null\n");
 		return;
 	}
 
@@ -88,19 +92,21 @@
 }
 
 static void
-lpfc_debug_save_dif(struct scsi_cmnd *cmnd)
+lpfc_debug_save_dif(struct lpfc_hba *phba, struct scsi_cmnd *cmnd)
 {
 	void *src, *dst;
 	struct scatterlist *sgde = scsi_prot_sglist(cmnd);
 
 	if (!_dump_buf_dif) {
-		printk(KERN_ERR "BLKGRD ERROR %s _dump_buf_data is NULL\n",
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+			"9052 BLKGRD: ERROR %s _dump_buf_data is NULL\n",
 				__func__);
 		return;
 	}
 
 	if (!sgde) {
-		printk(KERN_ERR "BLKGRD ERROR: prot scatterlist is null\n");
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+			"9053 BLKGRD: ERROR: prot scatterlist is null\n");
 		return;
 	}
 
@@ -242,6 +248,36 @@
 }
 
 /**
+ * lpfc_change_queue_depth - Alter scsi device queue depth
+ * @sdev: Pointer the scsi device on which to change the queue depth.
+ * @qdepth: New queue depth to set the sdev to.
+ * @reason: The reason for the queue depth change.
+ *
+ * This function is called by the midlayer and the LLD to alter the queue
+ * depth for a scsi device. This function sets the queue depth to the new
+ * value and sends an event out to log the queue depth change.
+ **/
+int
+lpfc_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
+{
+	struct lpfc_vport *vport = (struct lpfc_vport *) sdev->host->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
+	struct lpfc_rport_data *rdata;
+	unsigned long new_queue_depth, old_queue_depth;
+
+	old_queue_depth = sdev->queue_depth;
+	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+	new_queue_depth = sdev->queue_depth;
+	rdata = sdev->hostdata;
+	if (rdata)
+		lpfc_send_sdev_queuedepth_change_event(phba, vport,
+						       rdata->pnode, sdev->lun,
+						       old_queue_depth,
+						       new_queue_depth);
+	return sdev->queue_depth;
+}
+
+/**
  * lpfc_rampdown_queue_depth - Post RAMP_DOWN_QUEUE event to worker thread
  * @phba: The Hba for which this call is being executed.
  *
@@ -305,8 +341,10 @@
 	if (vport->cfg_lun_queue_depth <= queue_depth)
 		return;
 	spin_lock_irqsave(&phba->hbalock, flags);
-	if (((phba->last_ramp_up_time + QUEUE_RAMP_UP_INTERVAL) > jiffies) ||
-	 ((phba->last_rsrc_error_time + QUEUE_RAMP_UP_INTERVAL ) > jiffies)) {
+	if (time_before(jiffies,
+			phba->last_ramp_up_time + QUEUE_RAMP_UP_INTERVAL) ||
+	    time_before(jiffies,
+			phba->last_rsrc_error_time + QUEUE_RAMP_UP_INTERVAL)) {
 		spin_unlock_irqrestore(&phba->hbalock, flags);
 		return;
 	}
@@ -338,10 +376,9 @@
 	struct lpfc_vport **vports;
 	struct Scsi_Host  *shost;
 	struct scsi_device *sdev;
-	unsigned long new_queue_depth, old_queue_depth;
+	unsigned long new_queue_depth;
 	unsigned long num_rsrc_err, num_cmd_success;
 	int i;
-	struct lpfc_rport_data *rdata;
 
 	num_rsrc_err = atomic_read(&phba->num_rsrc_err);
 	num_cmd_success = atomic_read(&phba->num_cmd_success);
@@ -359,22 +396,8 @@
 				else
 					new_queue_depth = sdev->queue_depth -
 								new_queue_depth;
-				old_queue_depth = sdev->queue_depth;
-				if (sdev->ordered_tags)
-					scsi_adjust_queue_depth(sdev,
-							MSG_ORDERED_TAG,
-							new_queue_depth);
-				else
-					scsi_adjust_queue_depth(sdev,
-							MSG_SIMPLE_TAG,
-							new_queue_depth);
-				rdata = sdev->hostdata;
-				if (rdata)
-					lpfc_send_sdev_queuedepth_change_event(
-						phba, vports[i],
-						rdata->pnode,
-						sdev->lun, old_queue_depth,
-						new_queue_depth);
+				lpfc_change_queue_depth(sdev, new_queue_depth,
+							SCSI_QDEPTH_DEFAULT);
 			}
 		}
 	lpfc_destroy_vport_work_array(phba, vports);
@@ -398,7 +421,6 @@
 	struct Scsi_Host  *shost;
 	struct scsi_device *sdev;
 	int i;
-	struct lpfc_rport_data *rdata;
 
 	vports = lpfc_create_vport_work_array(phba);
 	if (vports != NULL)
@@ -408,22 +430,9 @@
 				if (vports[i]->cfg_lun_queue_depth <=
 				    sdev->queue_depth)
 					continue;
-				if (sdev->ordered_tags)
-					scsi_adjust_queue_depth(sdev,
-							MSG_ORDERED_TAG,
-							sdev->queue_depth+1);
-				else
-					scsi_adjust_queue_depth(sdev,
-							MSG_SIMPLE_TAG,
-							sdev->queue_depth+1);
-				rdata = sdev->hostdata;
-				if (rdata)
-					lpfc_send_sdev_queuedepth_change_event(
-						phba, vports[i],
-						rdata->pnode,
-						sdev->lun,
-						sdev->queue_depth - 1,
-						sdev->queue_depth);
+				lpfc_change_queue_depth(sdev,
+							sdev->queue_depth+1,
+							SCSI_QDEPTH_RAMP_UP);
 			}
 		}
 	lpfc_destroy_vport_work_array(phba, vports);
@@ -589,7 +598,7 @@
 		iocb->ulpClass = CLASS3;
 		psb->status = IOSTAT_SUCCESS;
 		/* Put it back into the SCSI buffer list */
-		lpfc_release_scsi_buf_s4(phba, psb);
+		lpfc_release_scsi_buf_s3(phba, psb);
 
 	}
 
@@ -1024,7 +1033,8 @@
 
 		lpfc_cmd->seg_cnt = nseg;
 		if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) {
-			printk(KERN_ERR "%s: Too many sg segments from "
+			lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+				"9064 BLKGRD: %s: Too many sg segments from "
 			       "dma_map_sg.  Config %d, seg_cnt %d\n",
 			       __func__, phba->cfg_sg_seg_cnt,
 			       lpfc_cmd->seg_cnt);
@@ -1112,7 +1122,7 @@
  * with the cmd
  */
 static int
-lpfc_sc_to_sli_prof(struct scsi_cmnd *sc)
+lpfc_sc_to_sli_prof(struct lpfc_hba *phba, struct scsi_cmnd *sc)
 {
 	uint8_t guard_type = scsi_host_get_guard(sc->device->host);
 	uint8_t ret_prof = LPFC_PROF_INVALID;
@@ -1136,7 +1146,8 @@
 
 		case SCSI_PROT_NORMAL:
 		default:
-			printk(KERN_ERR "Bad op/guard:%d/%d combination\n",
+			lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+				"9063 BLKGRD:Bad op/guard:%d/%d combination\n",
 					scsi_get_prot_op(sc), guard_type);
 			break;
 
@@ -1157,7 +1168,8 @@
 		case SCSI_PROT_WRITE_STRIP:
 		case SCSI_PROT_NORMAL:
 		default:
-			printk(KERN_ERR "Bad op/guard:%d/%d combination\n",
+			lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+				"9075 BLKGRD: Bad op/guard:%d/%d combination\n",
 					scsi_get_prot_op(sc), guard_type);
 			break;
 		}
@@ -1259,7 +1271,7 @@
 	uint16_t apptagmask, apptagval;
 
 	pde1 = (struct lpfc_pde *) bpl;
-	prof = lpfc_sc_to_sli_prof(sc);
+	prof = lpfc_sc_to_sli_prof(phba, sc);
 
 	if (prof == LPFC_PROF_INVALID)
 		goto out;
@@ -1359,7 +1371,7 @@
 		return 0;
 	}
 
-	prof = lpfc_sc_to_sli_prof(sc);
+	prof = lpfc_sc_to_sli_prof(phba, sc);
 	if (prof == LPFC_PROF_INVALID)
 		goto out;
 
@@ -1408,7 +1420,8 @@
 		subtotal = 0; /* total bytes processed for current prot grp */
 		while (!pgdone) {
 			if (!sgde) {
-				printk(KERN_ERR "%s Invalid data segment\n",
+				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+					"9065 BLKGRD:%s Invalid data segment\n",
 						__func__);
 				return 0;
 			}
@@ -1462,7 +1475,8 @@
 			reftag += protgrp_blks;
 		} else {
 			/* if we're here, we have a bug */
-			printk(KERN_ERR "BLKGRD: bug in %s\n", __func__);
+			lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+				"9054 BLKGRD: bug in %s\n", __func__);
 		}
 
 	} while (!alldone);
@@ -1544,8 +1558,10 @@
 
 		lpfc_cmd->seg_cnt = datasegcnt;
 		if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) {
-			printk(KERN_ERR "%s: Too many sg segments from "
-					"dma_map_sg.  Config %d, seg_cnt %d\n",
+			lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+					"9067 BLKGRD: %s: Too many sg segments"
+					" from dma_map_sg.  Config %d, seg_cnt"
+					" %d\n",
 					__func__, phba->cfg_sg_seg_cnt,
 					lpfc_cmd->seg_cnt);
 			scsi_dma_unmap(scsi_cmnd);
@@ -1579,8 +1595,9 @@
 			lpfc_cmd->prot_seg_cnt = protsegcnt;
 			if (lpfc_cmd->prot_seg_cnt
 			    > phba->cfg_prot_sg_seg_cnt) {
-				printk(KERN_ERR "%s: Too many prot sg segments "
-						"from dma_map_sg.  Config %d,"
+				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+					"9068 BLKGRD: %s: Too many prot sg "
+					"segments from dma_map_sg.  Config %d,"
 						"prot_seg_cnt %d\n", __func__,
 						phba->cfg_prot_sg_seg_cnt,
 						lpfc_cmd->prot_seg_cnt);
@@ -1671,23 +1688,26 @@
 	uint32_t bgstat = bgf->bgstat;
 	uint64_t failing_sector = 0;
 
-	printk(KERN_ERR "BG ERROR in cmd 0x%x lba 0x%llx blk cnt 0x%x "
+	lpfc_printf_log(phba, KERN_ERR, LOG_BG, "9069 BLKGRD: BG ERROR in cmd"
+			" 0x%x lba 0x%llx blk cnt 0x%x "
 			"bgstat=0x%x bghm=0x%x\n",
 			cmd->cmnd[0], (unsigned long long)scsi_get_lba(cmd),
 			blk_rq_sectors(cmd->request), bgstat, bghm);
 
 	spin_lock(&_dump_buf_lock);
 	if (!_dump_buf_done) {
-		printk(KERN_ERR "Saving Data for %u blocks to debugfs\n",
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,  "9070 BLKGRD: Saving"
+			" Data for %u blocks to debugfs\n",
 				(cmd->cmnd[7] << 8 | cmd->cmnd[8]));
-		lpfc_debug_save_data(cmd);
+		lpfc_debug_save_data(phba, cmd);
 
 		/* If we have a prot sgl, save the DIF buffer */
 		if (lpfc_prot_group_type(phba, cmd) ==
 				LPFC_PG_TYPE_DIF_BUF) {
-			printk(KERN_ERR "Saving DIF for %u blocks to debugfs\n",
-					(cmd->cmnd[7] << 8 | cmd->cmnd[8]));
-			lpfc_debug_save_dif(cmd);
+			lpfc_printf_log(phba, KERN_ERR, LOG_BG, "9071 BLKGRD: "
+				"Saving DIF for %u blocks to debugfs\n",
+				(cmd->cmnd[7] << 8 | cmd->cmnd[8]));
+			lpfc_debug_save_dif(phba, cmd);
 		}
 
 		_dump_buf_done = 1;
@@ -1696,15 +1716,17 @@
 
 	if (lpfc_bgs_get_invalid_prof(bgstat)) {
 		cmd->result = ScsiResult(DID_ERROR, 0);
-		printk(KERN_ERR "Invalid BlockGuard profile. bgstat:0x%x\n",
-				bgstat);
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG, "9072 BLKGRD: Invalid"
+			" BlockGuard profile. bgstat:0x%x\n",
+			bgstat);
 		ret = (-1);
 		goto out;
 	}
 
 	if (lpfc_bgs_get_uninit_dif_block(bgstat)) {
 		cmd->result = ScsiResult(DID_ERROR, 0);
-		printk(KERN_ERR "Invalid BlockGuard DIF Block. bgstat:0x%x\n",
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG, "9073 BLKGRD: "
+				"Invalid BlockGuard DIF Block. bgstat:0x%x\n",
 				bgstat);
 		ret = (-1);
 		goto out;
@@ -1718,7 +1740,8 @@
 		cmd->result = DRIVER_SENSE << 24
 			| ScsiResult(DID_ABORT, SAM_STAT_CHECK_CONDITION);
 		phba->bg_guard_err_cnt++;
-		printk(KERN_ERR "BLKGRD: guard_tag error\n");
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+			"9055 BLKGRD: guard_tag error\n");
 	}
 
 	if (lpfc_bgs_get_reftag_err(bgstat)) {
@@ -1730,7 +1753,8 @@
 			| ScsiResult(DID_ABORT, SAM_STAT_CHECK_CONDITION);
 
 		phba->bg_reftag_err_cnt++;
-		printk(KERN_ERR "BLKGRD: ref_tag error\n");
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+			"9056 BLKGRD: ref_tag error\n");
 	}
 
 	if (lpfc_bgs_get_apptag_err(bgstat)) {
@@ -1742,7 +1766,8 @@
 			| ScsiResult(DID_ABORT, SAM_STAT_CHECK_CONDITION);
 
 		phba->bg_apptag_err_cnt++;
-		printk(KERN_ERR "BLKGRD: app_tag error\n");
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+			"9061 BLKGRD: app_tag error\n");
 	}
 
 	if (lpfc_bgs_get_hi_water_mark_present(bgstat)) {
@@ -1763,7 +1788,8 @@
 	if (!ret) {
 		/* No error was reported - problem in FW? */
 		cmd->result = ScsiResult(DID_ERROR, 0);
-		printk(KERN_ERR "BLKGRD: no errors reported!\n");
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+			"9057 BLKGRD: no errors reported!\n");
 	}
 
 out:
@@ -1822,9 +1848,10 @@
 
 		lpfc_cmd->seg_cnt = nseg;
 		if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) {
-			printk(KERN_ERR "%s: Too many sg segments from "
-			       "dma_map_sg.  Config %d, seg_cnt %d\n",
-			       __func__, phba->cfg_sg_seg_cnt,
+			lpfc_printf_log(phba, KERN_ERR, LOG_BG, "9074 BLKGRD:"
+				" %s: Too many sg segments from "
+				"dma_map_sg.  Config %d, seg_cnt %d\n",
+				__func__, phba->cfg_sg_seg_cnt,
 			       lpfc_cmd->seg_cnt);
 			scsi_dma_unmap(scsi_cmnd);
 			return 1;
@@ -2050,6 +2077,21 @@
 		goto out;
 	}
 
+	if (resp_info & RSP_LEN_VALID) {
+		rsplen = be32_to_cpu(fcprsp->rspRspLen);
+		if ((rsplen != 0 && rsplen != 4 && rsplen != 8) ||
+		    (fcprsp->rspInfo3 != RSP_NO_FAILURE)) {
+			lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
+				 "2719 Invalid response length: "
+				 "tgt x%x lun x%x cmnd x%x rsplen x%x\n",
+				 cmnd->device->id,
+				 cmnd->device->lun, cmnd->cmnd[0],
+				 rsplen);
+			host_status = DID_ERROR;
+			goto out;
+		}
+	}
+
 	if ((resp_info & SNS_LEN_VALID) && fcprsp->rspSnsLen) {
 		uint32_t snslen = be32_to_cpu(fcprsp->rspSnsLen);
 		if (snslen > SCSI_SENSE_BUFFERSIZE)
@@ -2074,15 +2116,6 @@
 			 be32_to_cpu(fcprsp->rspRspLen),
 			 fcprsp->rspInfo3);
 
-	if (resp_info & RSP_LEN_VALID) {
-		rsplen = be32_to_cpu(fcprsp->rspRspLen);
-		if ((rsplen != 0 && rsplen != 4 && rsplen != 8) ||
-		    (fcprsp->rspInfo3 != RSP_NO_FAILURE)) {
-			host_status = DID_ERROR;
-			goto out;
-		}
-	}
-
 	scsi_set_resid(cmnd, 0);
 	if (resp_info & RESID_UNDER) {
 		scsi_set_resid(cmnd, be32_to_cpu(fcprsp->rspResId));
@@ -2180,7 +2213,7 @@
 	struct scsi_cmnd *cmd = lpfc_cmd->pCmd;
 	int result;
 	struct scsi_device *tmp_sdev;
-	int depth = 0;
+	int depth;
 	unsigned long flags;
 	struct lpfc_fast_path_event *fast_path_evt;
 	struct Scsi_Host *shost = cmd->device->host;
@@ -2264,7 +2297,7 @@
 					lpfc_printf_vlog(vport, KERN_WARNING,
 							LOG_BG,
 							"9031 non-zero BGSTAT "
-							"on unprotected cmd");
+							"on unprotected cmd\n");
 				}
 			}
 
@@ -2347,67 +2380,29 @@
 		return;
 	}
 
-
 	if (!result)
 		lpfc_rampup_queue_depth(vport, queue_depth);
 
-	if (!result && pnode && NLP_CHK_NODE_ACT(pnode) &&
-	   ((jiffies - pnode->last_ramp_up_time) >
-		LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
-	   ((jiffies - pnode->last_q_full_time) >
-		LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
-	   (vport->cfg_lun_queue_depth > queue_depth)) {
-		shost_for_each_device(tmp_sdev, shost) {
-			if (vport->cfg_lun_queue_depth > tmp_sdev->queue_depth){
-				if (tmp_sdev->id != scsi_id)
-					continue;
-				if (tmp_sdev->ordered_tags)
-					scsi_adjust_queue_depth(tmp_sdev,
-						MSG_ORDERED_TAG,
-						tmp_sdev->queue_depth+1);
-				else
-					scsi_adjust_queue_depth(tmp_sdev,
-						MSG_SIMPLE_TAG,
-						tmp_sdev->queue_depth+1);
-
-				pnode->last_ramp_up_time = jiffies;
-			}
-		}
-		lpfc_send_sdev_queuedepth_change_event(phba, vport, pnode,
-			0xFFFFFFFF,
-			queue_depth , queue_depth + 1);
-	}
-
 	/*
 	 * Check for queue full.  If the lun is reporting queue full, then
 	 * back off the lun queue depth to prevent target overloads.
 	 */
 	if (result == SAM_STAT_TASK_SET_FULL && pnode &&
 	    NLP_CHK_NODE_ACT(pnode)) {
-		pnode->last_q_full_time = jiffies;
-
 		shost_for_each_device(tmp_sdev, shost) {
 			if (tmp_sdev->id != scsi_id)
 				continue;
 			depth = scsi_track_queue_full(tmp_sdev,
-					tmp_sdev->queue_depth - 1);
-		}
-		/*
-		 * The queue depth cannot be lowered any more.
-		 * Modify the returned error code to store
-		 * the final depth value set by
-		 * scsi_track_queue_full.
-		 */
-		if (depth == -1)
-			depth = shost->cmd_per_lun;
-
-		if (depth) {
+						      tmp_sdev->queue_depth-1);
+			if (depth <= 0)
+				continue;
 			lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
 					 "0711 detected queue full - lun queue "
 					 "depth adjusted to %d.\n", depth);
 			lpfc_send_sdev_queuedepth_change_event(phba, vport,
-				pnode, 0xFFFFFFFF,
-				depth+1, depth);
+							       pnode,
+							       tmp_sdev->lun,
+							       depth+1, depth);
 		}
 	}
 
@@ -2745,7 +2740,9 @@
 	struct lpfc_hba *phba = (struct lpfc_hba *) ptr;
 
 	if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
-		lpfc_sli_poll_fcp_ring (phba);
+		lpfc_sli_handle_fast_ring_event(phba,
+			&phba->sli.ring[LPFC_FCP_RING], HA_R0RE_REQ);
+
 		if (phba->cfg_poll & DISABLE_FCP_RING_INT)
 			lpfc_poll_rearm_timer(phba);
 	}
@@ -2771,7 +2768,7 @@
 	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
 	struct lpfc_hba   *phba = vport->phba;
 	struct lpfc_rport_data *rdata = cmnd->device->hostdata;
-	struct lpfc_nodelist *ndlp = rdata->pnode;
+	struct lpfc_nodelist *ndlp;
 	struct lpfc_scsi_buf *lpfc_cmd;
 	struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
 	int err;
@@ -2781,13 +2778,15 @@
 		cmnd->result = err;
 		goto out_fail_command;
 	}
+	ndlp = rdata->pnode;
 
 	if (!(phba->sli3_options & LPFC_SLI3_BG_ENABLED) &&
 		scsi_get_prot_op(cmnd) != SCSI_PROT_NORMAL) {
 
-		printk(KERN_ERR "BLKGRD ERROR: rcvd protected cmd:%02x op:%02x "
-				"str=%s without registering for BlockGuard - "
-				"Rejecting command\n",
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+				"9058 BLKGRD: ERROR: rcvd protected cmd:%02x"
+				" op:%02x str=%s without registering for"
+				" BlockGuard - Rejecting command\n",
 				cmnd->cmnd[0], scsi_get_prot_op(cmnd),
 				dif_op_str[scsi_get_prot_op(cmnd)]);
 		goto out_fail_command;
@@ -2827,61 +2826,66 @@
 	cmnd->scsi_done = done;
 
 	if (scsi_get_prot_op(cmnd) != SCSI_PROT_NORMAL) {
-		lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
+		if (vport->phba->cfg_enable_bg) {
+			lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
 				"9033 BLKGRD: rcvd protected cmd:%02x op:%02x "
 				"str=%s\n",
 				cmnd->cmnd[0], scsi_get_prot_op(cmnd),
 				dif_op_str[scsi_get_prot_op(cmnd)]);
-		lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
+			lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
 				"9034 BLKGRD: CDB: %02x %02x %02x %02x %02x "
 				"%02x %02x %02x %02x %02x\n",
 				cmnd->cmnd[0], cmnd->cmnd[1], cmnd->cmnd[2],
 				cmnd->cmnd[3], cmnd->cmnd[4], cmnd->cmnd[5],
 				cmnd->cmnd[6], cmnd->cmnd[7], cmnd->cmnd[8],
 				cmnd->cmnd[9]);
-		if (cmnd->cmnd[0] == READ_10)
-			lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
+			if (cmnd->cmnd[0] == READ_10)
+				lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
 					"9035 BLKGRD: READ @ sector %llu, "
 					"count %u\n",
 					(unsigned long long)scsi_get_lba(cmnd),
 					blk_rq_sectors(cmnd->request));
-		else if (cmnd->cmnd[0] == WRITE_10)
-			lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
+			else if (cmnd->cmnd[0] == WRITE_10)
+				lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
 					"9036 BLKGRD: WRITE @ sector %llu, "
 					"count %u cmd=%p\n",
 					(unsigned long long)scsi_get_lba(cmnd),
 					blk_rq_sectors(cmnd->request),
 					cmnd);
+		}
 
 		err = lpfc_bg_scsi_prep_dma_buf(phba, lpfc_cmd);
 	} else {
-		lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
-				"9038 BLKGRD: rcvd unprotected cmd:%02x op:%02x"
-				" str=%s\n",
-				cmnd->cmnd[0], scsi_get_prot_op(cmnd),
-				dif_op_str[scsi_get_prot_op(cmnd)]);
-		lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
-				 "9039 BLKGRD: CDB: %02x %02x %02x %02x %02x "
-				 "%02x %02x %02x %02x %02x\n",
-				 cmnd->cmnd[0], cmnd->cmnd[1], cmnd->cmnd[2],
-				 cmnd->cmnd[3], cmnd->cmnd[4], cmnd->cmnd[5],
-				 cmnd->cmnd[6], cmnd->cmnd[7], cmnd->cmnd[8],
-				 cmnd->cmnd[9]);
-		if (cmnd->cmnd[0] == READ_10)
+		if (vport->phba->cfg_enable_bg) {
 			lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
-					 "9040 dbg: READ @ sector %llu, "
-					 "count %u\n",
-					 (unsigned long long)scsi_get_lba(cmnd),
+					"9038 BLKGRD: rcvd unprotected cmd:"
+					"%02x op:%02x str=%s\n",
+					cmnd->cmnd[0], scsi_get_prot_op(cmnd),
+					dif_op_str[scsi_get_prot_op(cmnd)]);
+				lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
+					"9039 BLKGRD: CDB: %02x %02x %02x "
+					"%02x %02x %02x %02x %02x %02x %02x\n",
+					cmnd->cmnd[0], cmnd->cmnd[1],
+					cmnd->cmnd[2], cmnd->cmnd[3],
+					cmnd->cmnd[4], cmnd->cmnd[5],
+					cmnd->cmnd[6], cmnd->cmnd[7],
+					cmnd->cmnd[8], cmnd->cmnd[9]);
+			if (cmnd->cmnd[0] == READ_10)
+				lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
+					"9040 dbg: READ @ sector %llu, "
+					"count %u\n",
+					(unsigned long long)scsi_get_lba(cmnd),
 					 blk_rq_sectors(cmnd->request));
-		else if (cmnd->cmnd[0] == WRITE_10)
-			lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
+			else if (cmnd->cmnd[0] == WRITE_10)
+				lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
 					 "9041 dbg: WRITE @ sector %llu, "
 					 "count %u cmd=%p\n",
 					 (unsigned long long)scsi_get_lba(cmnd),
 					 blk_rq_sectors(cmnd->request), cmnd);
-		else
-			lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
+			else
+				lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
 					 "9042 dbg: parser not implemented\n");
+		}
 		err = lpfc_scsi_prep_dma_buf(phba, lpfc_cmd);
 	}
 
@@ -2898,7 +2902,11 @@
 		goto out_host_busy_free_buf;
 	}
 	if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
-		lpfc_sli_poll_fcp_ring(phba);
+		spin_unlock(shost->host_lock);
+		lpfc_sli_handle_fast_ring_event(phba,
+			&phba->sli.ring[LPFC_FCP_RING], HA_R0RE_REQ);
+
+		spin_lock(shost->host_lock);
 		if (phba->cfg_poll & DISABLE_FCP_RING_INT)
 			lpfc_poll_rearm_timer(phba);
 	}
@@ -2917,28 +2925,6 @@
 }
 
 /**
- * lpfc_block_error_handler - Routine to block error  handler
- * @cmnd: Pointer to scsi_cmnd data structure.
- *
- *  This routine blocks execution till fc_rport state is not FC_PORSTAT_BLCOEKD.
- **/
-static void
-lpfc_block_error_handler(struct scsi_cmnd *cmnd)
-{
-	struct Scsi_Host *shost = cmnd->device->host;
-	struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
-
-	spin_lock_irq(shost->host_lock);
-	while (rport->port_state == FC_PORTSTATE_BLOCKED) {
-		spin_unlock_irq(shost->host_lock);
-		msleep(1000);
-		spin_lock_irq(shost->host_lock);
-	}
-	spin_unlock_irq(shost->host_lock);
-	return;
-}
-
-/**
  * lpfc_abort_handler - scsi_host_template eh_abort_handler entry point
  * @cmnd: Pointer to scsi_cmnd data structure.
  *
@@ -2961,7 +2947,7 @@
 	int ret = SUCCESS;
 	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq);
 
-	lpfc_block_error_handler(cmnd);
+	fc_block_scsi_eh(cmnd);
 	lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble;
 	BUG_ON(!lpfc_cmd);
 
@@ -3001,6 +2987,10 @@
 
 	icmd->ulpLe = 1;
 	icmd->ulpClass = cmd->ulpClass;
+
+	/* ABTS WQE must go to the same WQ as the WQE to be aborted */
+	abtsiocb->fcp_wqidx = iocb->fcp_wqidx;
+
 	if (lpfc_is_link_up(phba))
 		icmd->ulpCommand = CMD_ABORT_XRI_CN;
 	else
@@ -3016,7 +3006,8 @@
 	}
 
 	if (phba->cfg_poll & DISABLE_FCP_RING_INT)
-		lpfc_sli_poll_fcp_ring (phba);
+		lpfc_sli_handle_fast_ring_event(phba,
+			&phba->sli.ring[LPFC_FCP_RING], HA_R0RE_REQ);
 
 	lpfc_cmd->waitq = &waitq;
 	/* Wait for abort to complete */
@@ -3166,9 +3157,15 @@
 lpfc_chk_tgt_mapped(struct lpfc_vport *vport, struct scsi_cmnd *cmnd)
 {
 	struct lpfc_rport_data *rdata = cmnd->device->hostdata;
-	struct lpfc_nodelist *pnode = rdata->pnode;
+	struct lpfc_nodelist *pnode;
 	unsigned long later;
 
+	if (!rdata) {
+		lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP,
+			"0797 Tgt Map rport failure: rdata x%p\n", rdata);
+		return FAILED;
+	}
+	pnode = rdata->pnode;
 	/*
 	 * If target is not in a MAPPED state, delay until
 	 * target is rediscovered or devloss timeout expires.
@@ -3253,13 +3250,19 @@
 	struct Scsi_Host  *shost = cmnd->device->host;
 	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
 	struct lpfc_rport_data *rdata = cmnd->device->hostdata;
-	struct lpfc_nodelist *pnode = rdata->pnode;
+	struct lpfc_nodelist *pnode;
 	unsigned tgt_id = cmnd->device->id;
 	unsigned int lun_id = cmnd->device->lun;
 	struct lpfc_scsi_event_header scsi_event;
 	int status;
 
-	lpfc_block_error_handler(cmnd);
+	if (!rdata) {
+		lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
+			"0798 Device Reset rport failure: rdata x%p\n", rdata);
+		return FAILED;
+	}
+	pnode = rdata->pnode;
+	fc_block_scsi_eh(cmnd);
 
 	status = lpfc_chk_tgt_mapped(vport, cmnd);
 	if (status == FAILED) {
@@ -3312,13 +3315,19 @@
 	struct Scsi_Host  *shost = cmnd->device->host;
 	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
 	struct lpfc_rport_data *rdata = cmnd->device->hostdata;
-	struct lpfc_nodelist *pnode = rdata->pnode;
+	struct lpfc_nodelist *pnode;
 	unsigned tgt_id = cmnd->device->id;
 	unsigned int lun_id = cmnd->device->lun;
 	struct lpfc_scsi_event_header scsi_event;
 	int status;
 
-	lpfc_block_error_handler(cmnd);
+	if (!rdata) {
+		lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
+			"0799 Target Reset rport failure: rdata x%p\n", rdata);
+		return FAILED;
+	}
+	pnode = rdata->pnode;
+	fc_block_scsi_eh(cmnd);
 
 	status = lpfc_chk_tgt_mapped(vport, cmnd);
 	if (status == FAILED) {
@@ -3384,7 +3393,7 @@
 	fc_host_post_vendor_event(shost, fc_get_event_number(),
 		sizeof(scsi_event), (char *)&scsi_event, LPFC_NL_VENDOR_ID);
 
-	lpfc_block_error_handler(cmnd);
+	fc_block_scsi_eh(cmnd);
 
 	/*
 	 * Since the driver manages a single bus device, reset all
@@ -3498,6 +3507,8 @@
 				 "Allocated %d buffers.\n",
 				 num_to_alloc, num_allocated);
 	}
+	if (num_allocated > 0)
+		phba->total_scsi_bufs += num_allocated;
 	return 0;
 }
 
@@ -3534,7 +3545,8 @@
 	rport->dev_loss_tmo = vport->cfg_devloss_tmo;
 
 	if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
-		lpfc_sli_poll_fcp_ring(phba);
+		lpfc_sli_handle_fast_ring_event(phba,
+			&phba->sli.ring[LPFC_FCP_RING], HA_R0RE_REQ);
 		if (phba->cfg_poll & DISABLE_FCP_RING_INT)
 			lpfc_poll_rearm_timer(phba);
 	}
@@ -3576,6 +3588,7 @@
 	.shost_attrs		= lpfc_hba_attrs,
 	.max_sectors		= 0xFFFF,
 	.vendor_id		= LPFC_NL_VENDOR_ID,
+	.change_queue_depth	= lpfc_change_queue_depth,
 };
 
 struct scsi_host_template lpfc_vport_template = {
@@ -3597,4 +3610,5 @@
 	.use_clustering		= ENABLE_CLUSTERING,
 	.shost_attrs		= lpfc_vport_attrs,
 	.max_sectors		= 0xFFFF,
+	.change_queue_depth	= lpfc_change_queue_depth,
 };
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 43cbe33..7935667 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -30,6 +30,7 @@
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_transport_fc.h>
 #include <scsi/fc/fc_fs.h>
+#include <linux/aer.h>
 
 #include "lpfc_hw4.h"
 #include "lpfc_hw.h"
@@ -58,8 +59,11 @@
 static int lpfc_sli_issue_mbox_s4(struct lpfc_hba *, LPFC_MBOXQ_t *,
 				  uint32_t);
 static int lpfc_sli4_read_rev(struct lpfc_hba *, LPFC_MBOXQ_t *,
-			    uint8_t *, uint32_t *);
-
+			      uint8_t *, uint32_t *);
+static struct lpfc_iocbq *lpfc_sli4_els_wcqe_to_rspiocbq(struct lpfc_hba *,
+							 struct lpfc_iocbq *);
+static void lpfc_sli4_send_seq_to_ulp(struct lpfc_vport *,
+				      struct hbq_dmabuf *);
 static IOCB_t *
 lpfc_get_iocb_from_iocbq(struct lpfc_iocbq *iocbq)
 {
@@ -259,6 +263,9 @@
 	bf_set(lpfc_eqcq_doorbell_qt, &doorbell, LPFC_QUEUE_TYPE_EVENT);
 	bf_set(lpfc_eqcq_doorbell_eqid, &doorbell, q->queue_id);
 	writel(doorbell.word0, q->phba->sli4_hba.EQCQDBregaddr);
+	/* PCI read to flush PCI pipeline on re-arming for INTx mode */
+	if ((q->phba->intr_type == INTx) && (arm == LPFC_QUEUE_REARM))
+		readl(q->phba->sli4_hba.EQCQDBregaddr);
 	return released;
 }
 
@@ -515,6 +522,8 @@
 	struct lpfc_sglq *sglq = NULL;
 	uint16_t adj_xri;
 	list_remove_head(lpfc_sgl_list, sglq, struct lpfc_sglq, list);
+	if (!sglq)
+		return NULL;
 	adj_xri = sglq->sli4_xritag - phba->sli4_hba.max_cfg_param.xri_base;
 	phba->sli4_hba.lpfc_sglq_active_list[adj_xri] = sglq;
 	return sglq;
@@ -572,9 +581,9 @@
 		sglq = __lpfc_clear_active_sglq(phba, iocbq->sli4_xritag);
 	if (sglq)  {
 		if (iocbq->iocb_flag & LPFC_DRIVER_ABORTED
-			|| ((iocbq->iocb.ulpStatus == IOSTAT_LOCAL_REJECT)
+			&& ((iocbq->iocb.ulpStatus == IOSTAT_LOCAL_REJECT)
 			&& (iocbq->iocb.un.ulpWord[4]
-				== IOERR_SLI_ABORTED))) {
+				== IOERR_ABORT_REQUESTED))) {
 			spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock,
 					iflag);
 			list_add(&sglq->list,
@@ -767,6 +776,7 @@
 	case CMD_CLOSE_XRI_CX:
 	case CMD_XRI_ABORTED_CX:
 	case CMD_ABORT_MXRI64_CN:
+	case CMD_XMIT_BLS_RSP64_CX:
 		type = LPFC_ABORT_IOCB;
 		break;
 	case CMD_RCV_SEQUENCE_CX:
@@ -1794,7 +1804,7 @@
 		 */
 		if (lpfc_sli_chk_mbx_command(pmbox->mbxCommand) ==
 		    MBX_SHUTDOWN) {
-			/* Unknow mailbox command compl */
+			/* Unknown mailbox command compl */
 			lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
 					"(%d):0323 Unknown Mailbox command "
 					"x%x (x%x) Cmpl\n",
@@ -2068,8 +2078,8 @@
 	if ((irsp->ulpCommand == CMD_RCV_ELS_REQ64_CX) ||
 	    (irsp->ulpCommand == CMD_RCV_ELS_REQ_CX) ||
 	    (irsp->ulpCommand == CMD_IOCB_RCV_ELS64_CX)) {
-		Rctl = FC_ELS_REQ;
-		Type = FC_ELS_DATA;
+		Rctl = FC_RCTL_ELS_REQ;
+		Type = FC_TYPE_ELS;
 	} else {
 		w5p = (WORD5 *)&(saveq->iocb.un.ulpWord[5]);
 		Rctl = w5p->hcsw.Rctl;
@@ -2079,8 +2089,8 @@
 		if ((Rctl == 0) && (pring->ringno == LPFC_ELS_RING) &&
 			(irsp->ulpCommand == CMD_RCV_SEQUENCE64_CX ||
 			 irsp->ulpCommand == CMD_IOCB_RCV_SEQ64_CX)) {
-			Rctl = FC_ELS_REQ;
-			Type = FC_ELS_DATA;
+			Rctl = FC_RCTL_ELS_REQ;
+			Type = FC_TYPE_ELS;
 			w5p->hcsw.Rctl = Rctl;
 			w5p->hcsw.Type = Type;
 		}
@@ -2324,168 +2334,6 @@
 	return;
 }
 
-/**
- * lpfc_sli_poll_fcp_ring - Handle FCP ring completion in polling mode
- * @phba: Pointer to HBA context object.
- *
- * This function is called from lpfc_queuecommand, lpfc_poll_timeout,
- * lpfc_abort_handler and lpfc_slave_configure when FCP_RING_POLLING
- * is enabled.
- *
- * The caller does not hold any lock.
- * The function processes each response iocb in the response ring until it
- * finds an iocb with LE bit set and chains all the iocbs upto the iocb with
- * LE bit set. The function will call the completion handler of the command iocb
- * if the response iocb indicates a completion for a command iocb or it is
- * an abort completion.
- **/
-void lpfc_sli_poll_fcp_ring(struct lpfc_hba *phba)
-{
-	struct lpfc_sli      *psli  = &phba->sli;
-	struct lpfc_sli_ring *pring = &psli->ring[LPFC_FCP_RING];
-	IOCB_t *irsp = NULL;
-	IOCB_t *entry = NULL;
-	struct lpfc_iocbq *cmdiocbq = NULL;
-	struct lpfc_iocbq rspiocbq;
-	struct lpfc_pgp *pgp = &phba->port_gp[pring->ringno];
-	uint32_t status;
-	uint32_t portRspPut, portRspMax;
-	int type;
-	uint32_t rsp_cmpl = 0;
-	uint32_t ha_copy;
-	unsigned long iflags;
-
-	pring->stats.iocb_event++;
-
-	/*
-	 * The next available response entry should never exceed the maximum
-	 * entries.  If it does, treat it as an adapter hardware error.
-	 */
-	portRspMax = pring->numRiocb;
-	portRspPut = le32_to_cpu(pgp->rspPutInx);
-	if (unlikely(portRspPut >= portRspMax)) {
-		lpfc_sli_rsp_pointers_error(phba, pring);
-		return;
-	}
-
-	rmb();
-	while (pring->rspidx != portRspPut) {
-		entry = lpfc_resp_iocb(phba, pring);
-		if (++pring->rspidx >= portRspMax)
-			pring->rspidx = 0;
-
-		lpfc_sli_pcimem_bcopy((uint32_t *) entry,
-				      (uint32_t *) &rspiocbq.iocb,
-				      phba->iocb_rsp_size);
-		irsp = &rspiocbq.iocb;
-		type = lpfc_sli_iocb_cmd_type(irsp->ulpCommand & CMD_IOCB_MASK);
-		pring->stats.iocb_rsp++;
-		rsp_cmpl++;
-
-		if (unlikely(irsp->ulpStatus)) {
-			/* Rsp ring <ringno> error: IOCB */
-			lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
-					"0326 Rsp Ring %d error: IOCB Data: "
-					"x%x x%x x%x x%x x%x x%x x%x x%x\n",
-					pring->ringno,
-					irsp->un.ulpWord[0],
-					irsp->un.ulpWord[1],
-					irsp->un.ulpWord[2],
-					irsp->un.ulpWord[3],
-					irsp->un.ulpWord[4],
-					irsp->un.ulpWord[5],
-					*(uint32_t *)&irsp->un1,
-					*((uint32_t *)&irsp->un1 + 1));
-		}
-
-		switch (type) {
-		case LPFC_ABORT_IOCB:
-		case LPFC_SOL_IOCB:
-			/*
-			 * Idle exchange closed via ABTS from port.  No iocb
-			 * resources need to be recovered.
-			 */
-			if (unlikely(irsp->ulpCommand == CMD_XRI_ABORTED_CX)) {
-				lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
-						"0314 IOCB cmd 0x%x "
-						"processed. Skipping "
-						"completion",
-						irsp->ulpCommand);
-				break;
-			}
-
-			spin_lock_irqsave(&phba->hbalock, iflags);
-			cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring,
-							 &rspiocbq);
-			spin_unlock_irqrestore(&phba->hbalock, iflags);
-			if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) {
-				(cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
-						      &rspiocbq);
-			}
-			break;
-		default:
-			if (irsp->ulpCommand == CMD_ADAPTER_MSG) {
-				char adaptermsg[LPFC_MAX_ADPTMSG];
-				memset(adaptermsg, 0, LPFC_MAX_ADPTMSG);
-				memcpy(&adaptermsg[0], (uint8_t *) irsp,
-				       MAX_MSG_DATA);
-				dev_warn(&((phba->pcidev)->dev),
-					 "lpfc%d: %s\n",
-					 phba->brd_no, adaptermsg);
-			} else {
-				/* Unknown IOCB command */
-				lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
-						"0321 Unknown IOCB command "
-						"Data: x%x, x%x x%x x%x x%x\n",
-						type, irsp->ulpCommand,
-						irsp->ulpStatus,
-						irsp->ulpIoTag,
-						irsp->ulpContext);
-			}
-			break;
-		}
-
-		/*
-		 * The response IOCB has been processed.  Update the ring
-		 * pointer in SLIM.  If the port response put pointer has not
-		 * been updated, sync the pgp->rspPutInx and fetch the new port
-		 * response put pointer.
-		 */
-		writel(pring->rspidx, &phba->host_gp[pring->ringno].rspGetInx);
-
-		if (pring->rspidx == portRspPut)
-			portRspPut = le32_to_cpu(pgp->rspPutInx);
-	}
-
-	ha_copy = readl(phba->HAregaddr);
-	ha_copy >>= (LPFC_FCP_RING * 4);
-
-	if ((rsp_cmpl > 0) && (ha_copy & HA_R0RE_REQ)) {
-		spin_lock_irqsave(&phba->hbalock, iflags);
-		pring->stats.iocb_rsp_full++;
-		status = ((CA_R0ATT | CA_R0RE_RSP) << (LPFC_FCP_RING * 4));
-		writel(status, phba->CAregaddr);
-		readl(phba->CAregaddr);
-		spin_unlock_irqrestore(&phba->hbalock, iflags);
-	}
-	if ((ha_copy & HA_R0CE_RSP) &&
-	    (pring->flag & LPFC_CALL_RING_AVAILABLE)) {
-		spin_lock_irqsave(&phba->hbalock, iflags);
-		pring->flag &= ~LPFC_CALL_RING_AVAILABLE;
-		pring->stats.iocb_cmd_empty++;
-
-		/* Force update of the local copy of cmdGetInx */
-		pring->local_getidx = le32_to_cpu(pgp->cmdGetInx);
-		lpfc_sli_resume_iocb(phba, pring);
-
-		if ((pring->lpfc_sli_cmd_available))
-			(pring->lpfc_sli_cmd_available) (phba, pring);
-
-		spin_unlock_irqrestore(&phba->hbalock, iflags);
-	}
-
-	return;
-}
 
 /**
  * lpfc_sli_handle_fast_ring_event - Handle ring events on FCP ring
@@ -2502,9 +2350,9 @@
  * an abort completion. The function will call lpfc_sli_process_unsol_iocb
  * function if this is an unsolicited iocb.
  * This routine presumes LPFC_FCP_RING handling and doesn't bother
- * to check it explicitly. This function always returns 1.
- **/
-static int
+ * to check it explicitly.
+ */
+int
 lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba,
 				struct lpfc_sli_ring *pring, uint32_t mask)
 {
@@ -2534,6 +2382,11 @@
 		spin_unlock_irqrestore(&phba->hbalock, iflag);
 		return 1;
 	}
+	if (phba->fcp_ring_in_use) {
+		spin_unlock_irqrestore(&phba->hbalock, iflag);
+		return 1;
+	} else
+		phba->fcp_ring_in_use = 1;
 
 	rmb();
 	while (pring->rspidx != portRspPut) {
@@ -2604,10 +2457,6 @@
 			cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring,
 							 &rspiocbq);
 			if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) {
-				if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
-					(cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
-							      &rspiocbq);
-				} else {
 					spin_unlock_irqrestore(&phba->hbalock,
 							       iflag);
 					(cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
@@ -2615,7 +2464,6 @@
 					spin_lock_irqsave(&phba->hbalock,
 							  iflag);
 				}
-			}
 			break;
 		case LPFC_UNSOL_IOCB:
 			spin_unlock_irqrestore(&phba->hbalock, iflag);
@@ -2675,6 +2523,7 @@
 
 	}
 
+	phba->fcp_ring_in_use = 0;
 	spin_unlock_irqrestore(&phba->hbalock, iflag);
 	return rc;
 }
@@ -3018,16 +2867,39 @@
 				   struct lpfc_sli_ring *pring, uint32_t mask)
 {
 	struct lpfc_iocbq *irspiocbq;
+	struct hbq_dmabuf *dmabuf;
+	struct lpfc_cq_event *cq_event;
 	unsigned long iflag;
 
-	while (!list_empty(&phba->sli4_hba.sp_rspiocb_work_queue)) {
+	spin_lock_irqsave(&phba->hbalock, iflag);
+	phba->hba_flag &= ~HBA_SP_QUEUE_EVT;
+	spin_unlock_irqrestore(&phba->hbalock, iflag);
+	while (!list_empty(&phba->sli4_hba.sp_queue_event)) {
 		/* Get the response iocb from the head of work queue */
 		spin_lock_irqsave(&phba->hbalock, iflag);
-		list_remove_head(&phba->sli4_hba.sp_rspiocb_work_queue,
-				 irspiocbq, struct lpfc_iocbq, list);
+		list_remove_head(&phba->sli4_hba.sp_queue_event,
+				 cq_event, struct lpfc_cq_event, list);
 		spin_unlock_irqrestore(&phba->hbalock, iflag);
-		/* Process the response iocb */
-		lpfc_sli_sp_handle_rspiocb(phba, pring, irspiocbq);
+
+		switch (bf_get(lpfc_wcqe_c_code, &cq_event->cqe.wcqe_cmpl)) {
+		case CQE_CODE_COMPL_WQE:
+			irspiocbq = container_of(cq_event, struct lpfc_iocbq,
+						 cq_event);
+			/* Translate ELS WCQE to response IOCBQ */
+			irspiocbq = lpfc_sli4_els_wcqe_to_rspiocbq(phba,
+								   irspiocbq);
+			if (irspiocbq)
+				lpfc_sli_sp_handle_rspiocb(phba, pring,
+							   irspiocbq);
+			break;
+		case CQE_CODE_RECEIVE:
+			dmabuf = container_of(cq_event, struct hbq_dmabuf,
+					      cq_event);
+			lpfc_sli4_handle_received_buffer(phba, dmabuf);
+			break;
+		default:
+			break;
+		}
 	}
 }
 
@@ -3416,6 +3288,7 @@
 
 	/* perform board reset */
 	phba->fc_eventTag = 0;
+	phba->link_events = 0;
 	phba->pport->fc_myDID = 0;
 	phba->pport->fc_prevDID = 0;
 
@@ -3476,6 +3349,7 @@
 
 	/* perform board reset */
 	phba->fc_eventTag = 0;
+	phba->link_events = 0;
 	phba->pport->fc_myDID = 0;
 	phba->pport->fc_prevDID = 0;
 
@@ -3495,7 +3369,6 @@
 	list_del_init(&phba->sli4_hba.dat_rq->list);
 	list_del_init(&phba->sli4_hba.mbx_cq->list);
 	list_del_init(&phba->sli4_hba.els_cq->list);
-	list_del_init(&phba->sli4_hba.rxq_cq->list);
 	for (qindx = 0; qindx < phba->cfg_fcp_wq_count; qindx++)
 		list_del_init(&phba->sli4_hba.fcp_wq[qindx]->list);
 	for (qindx = 0; qindx < phba->cfg_fcp_eq_count; qindx++)
@@ -3531,9 +3404,13 @@
 	struct lpfc_sli *psli;
 	volatile uint32_t word0;
 	void __iomem *to_slim;
+	uint32_t hba_aer_enabled;
 
 	spin_lock_irq(&phba->hbalock);
 
+	/* Take PCIe device Advanced Error Reporting (AER) state */
+	hba_aer_enabled = phba->hba_flag & HBA_AER_ENABLED;
+
 	psli = &phba->sli;
 
 	/* Restart HBA */
@@ -3573,6 +3450,10 @@
 	/* Give the INITFF and Post time to settle. */
 	mdelay(100);
 
+	/* Reset HBA AER if it was enabled, note hba_flag was reset above */
+	if (hba_aer_enabled)
+		pci_disable_pcie_error_reporting(phba->pcidev);
+
 	lpfc_hba_down_post(phba);
 
 	return 0;
@@ -4042,6 +3923,24 @@
 	if (rc)
 		goto lpfc_sli_hba_setup_error;
 
+	/* Enable PCIe device Advanced Error Reporting (AER) if configured */
+	if (phba->cfg_aer_support == 1 && !(phba->hba_flag & HBA_AER_ENABLED)) {
+		rc = pci_enable_pcie_error_reporting(phba->pcidev);
+		if (!rc) {
+			lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+					"2709 This device supports "
+					"Advanced Error Reporting (AER)\n");
+			spin_lock_irq(&phba->hbalock);
+			phba->hba_flag |= HBA_AER_ENABLED;
+			spin_unlock_irq(&phba->hbalock);
+		} else {
+			lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+					"2708 This device does not support "
+					"Advanced Error Reporting (AER)\n");
+			phba->cfg_aer_support = 0;
+		}
+	}
+
 	if (phba->sli_rev == 3) {
 		phba->iocb_cmd_size = SLI3_IOCB_CMD_SIZE;
 		phba->iocb_rsp_size = SLI3_IOCB_RSP_SIZE;
@@ -4163,7 +4062,7 @@
  * addition, this routine gets the port vpd data.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	ENOMEM - could not allocated memory.
  **/
 static int
@@ -4243,7 +4142,6 @@
 
 	lpfc_sli4_cq_release(phba->sli4_hba.mbx_cq, LPFC_QUEUE_REARM);
 	lpfc_sli4_cq_release(phba->sli4_hba.els_cq, LPFC_QUEUE_REARM);
-	lpfc_sli4_cq_release(phba->sli4_hba.rxq_cq, LPFC_QUEUE_REARM);
 	for (fcp_eqidx = 0; fcp_eqidx < phba->cfg_fcp_eq_count; fcp_eqidx++)
 		lpfc_sli4_cq_release(phba->sli4_hba.fcp_cq[fcp_eqidx],
 				     LPFC_QUEUE_REARM);
@@ -4322,6 +4220,13 @@
 	phba->sli_rev = bf_get(lpfc_mbx_rd_rev_sli_lvl, &mqe->un.read_rev);
 	if (bf_get(lpfc_mbx_rd_rev_fcoe, &mqe->un.read_rev))
 		phba->hba_flag |= HBA_FCOE_SUPPORT;
+
+	if (bf_get(lpfc_mbx_rd_rev_cee_ver, &mqe->un.read_rev) ==
+		LPFC_DCBX_CEE_MODE)
+		phba->hba_flag |= HBA_FIP_SUPPORT;
+	else
+		phba->hba_flag &= ~HBA_FIP_SUPPORT;
+
 	if (phba->sli_rev != LPFC_SLI_REV4 ||
 	    !(phba->hba_flag & HBA_FCOE_SUPPORT)) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
@@ -4468,7 +4373,8 @@
 	rc = lpfc_sli4_post_sgl_list(phba);
 	if (unlikely(rc)) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
-				"0582 Error %d during sgl post operation", rc);
+				"0582 Error %d during sgl post operation\n",
+					rc);
 		rc = -ENODEV;
 		goto out_free_vpd;
 	}
@@ -4477,8 +4383,8 @@
 	rc = lpfc_sli4_repost_scsi_sgl_list(phba);
 	if (unlikely(rc)) {
 		lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_SLI,
-				"0383 Error %d during scsi sgl post opeation",
-				rc);
+				"0383 Error %d during scsi sgl post "
+				"operation\n", rc);
 		/* Some Scsi buffers were moved to the abort scsi list */
 		/* A pci function reset will repost them */
 		rc = -ENODEV;
@@ -4494,10 +4400,6 @@
 		rc = -ENODEV;
 		goto out_free_vpd;
 	}
-	if (phba->cfg_enable_fip)
-		bf_set(lpfc_fip_flag, &phba->sli4_hba.sli4_flags, 1);
-	else
-		bf_set(lpfc_fip_flag, &phba->sli4_hba.sli4_flags, 0);
 
 	/* Set up all the queues to the device */
 	rc = lpfc_sli4_queue_setup(phba);
@@ -5669,7 +5571,7 @@
 		case CMD_GEN_REQUEST64_CX:
 			if (!(phba->sli.sli_flag & LPFC_MENLO_MAINT) ||
 				(piocb->iocb.un.genreq64.w5.hcsw.Rctl !=
-					FC_FCP_CMND) ||
+					FC_RCTL_DD_UNSOL_CMD) ||
 				(piocb->iocb.un.genreq64.w5.hcsw.Type !=
 					MENLO_TRANSPORT_TYPE))
 
@@ -5849,7 +5751,7 @@
 lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
 		union lpfc_wqe *wqe)
 {
-	uint32_t payload_len = 0;
+	uint32_t xmit_len = 0, total_len = 0;
 	uint8_t ct = 0;
 	uint32_t fip;
 	uint32_t abort_tag;
@@ -5857,12 +5759,15 @@
 	uint8_t cmnd;
 	uint16_t xritag;
 	struct ulp_bde64 *bpl = NULL;
+	uint32_t els_id = ELS_ID_DEFAULT;
+	int numBdes, i;
+	struct ulp_bde64 bde;
 
-	fip = bf_get(lpfc_fip_flag, &phba->sli4_hba.sli4_flags);
+	fip = phba->hba_flag & HBA_FIP_SUPPORT;
 	/* The fcp commands will set command type */
 	if (iocbq->iocb_flag &  LPFC_IO_FCP)
 		command_type = FCP_COMMAND;
-	else if (fip && (iocbq->iocb_flag & LPFC_FIP_ELS))
+	else if (fip && (iocbq->iocb_flag & LPFC_FIP_ELS_ID_MASK))
 		command_type = ELS_COMMAND_FIP;
 	else
 		command_type = ELS_COMMAND_NON_FIP;
@@ -5874,6 +5779,8 @@
 	wqe->words[7] = 0; /* The ct field has moved so reset */
 	/* words0-2 bpl convert bde */
 	if (iocbq->iocb.un.genreq64.bdl.bdeFlags == BUFF_TYPE_BLP_64) {
+		numBdes = iocbq->iocb.un.genreq64.bdl.bdeSize /
+				sizeof(struct ulp_bde64);
 		bpl  = (struct ulp_bde64 *)
 			((struct lpfc_dmabuf *)iocbq->context3)->virt;
 		if (!bpl)
@@ -5886,9 +5793,14 @@
 		 * can assign it to the sgl.
 		 */
 		wqe->generic.bde.tus.w  = le32_to_cpu(bpl->tus.w);
-		payload_len = wqe->generic.bde.tus.f.bdeSize;
+		xmit_len = wqe->generic.bde.tus.f.bdeSize;
+		total_len = 0;
+		for (i = 0; i < numBdes; i++) {
+			bde.tus.w  = le32_to_cpu(bpl[i].tus.w);
+			total_len += bde.tus.f.bdeSize;
+		}
 	} else
-		payload_len = iocbq->iocb.un.fcpi64.bdl.bdeSize;
+		xmit_len = iocbq->iocb.un.fcpi64.bdl.bdeSize;
 
 	iocbq->iocb.ulpIoTag = iocbq->iotag;
 	cmnd = iocbq->iocb.ulpCommand;
@@ -5902,7 +5814,7 @@
 				iocbq->iocb.ulpCommand);
 			return IOCB_ERROR;
 		}
-		wqe->els_req.payload_len = payload_len;
+		wqe->els_req.payload_len = xmit_len;
 		/* Els_reguest64 has a TMO */
 		bf_set(wqe_tmo, &wqe->els_req.wqe_com,
 			iocbq->iocb.ulpTimeout);
@@ -5923,7 +5835,23 @@
 		bf_set(lpfc_wqe_gen_ct, &wqe->generic, ct);
 		bf_set(lpfc_wqe_gen_pu, &wqe->generic, 0);
 		/* CCP CCPE PV PRI in word10 were set in the memcpy */
+
+		if (command_type == ELS_COMMAND_FIP) {
+			els_id = ((iocbq->iocb_flag & LPFC_FIP_ELS_ID_MASK)
+					>> LPFC_FIP_ELS_ID_SHIFT);
+		}
+		bf_set(lpfc_wqe_gen_els_id, &wqe->generic, els_id);
+
 	break;
+	case CMD_XMIT_SEQUENCE64_CX:
+		bf_set(lpfc_wqe_gen_context, &wqe->generic,
+					iocbq->iocb.un.ulpWord[3]);
+		wqe->generic.word3 = 0;
+		bf_set(wqe_rcvoxid, &wqe->generic, iocbq->iocb.ulpContext);
+		bf_set(wqe_xc, &wqe->generic, 1);
+		/* The entire sequence is transmitted for this IOCB */
+		xmit_len = total_len;
+		cmnd = CMD_XMIT_SEQUENCE64_CR;
 	case CMD_XMIT_SEQUENCE64_CR:
 		/* word3 iocb=io_tag32 wqe=payload_offset */
 		/* payload offset used for multilpe outstanding
@@ -5933,7 +5861,8 @@
 		/* word4 relative_offset memcpy */
 		/* word5 r_ctl/df_ctl memcpy */
 		bf_set(lpfc_wqe_gen_pu, &wqe->generic, 0);
-		wqe->xmit_sequence.xmit_len = payload_len;
+		wqe->xmit_sequence.xmit_len = xmit_len;
+		command_type = OTHER_COMMAND;
 	break;
 	case CMD_XMIT_BCAST64_CN:
 		/* word3 iocb=iotag32 wqe=payload_len */
@@ -5962,7 +5891,7 @@
 	case CMD_FCP_IREAD64_CR:
 		/* FCP_CMD is always the 1st sgl entry */
 		wqe->fcp_iread.payload_len =
-			payload_len + sizeof(struct fcp_rsp);
+			xmit_len + sizeof(struct fcp_rsp);
 
 		/* word 4 (xfer length) should have been set on the memcpy */
 
@@ -5999,7 +5928,7 @@
 		 * sgl[1] = rsp.
 		 *
 		 */
-		wqe->gen_req.command_len = payload_len;
+		wqe->gen_req.command_len = xmit_len;
 		/* Word4 parameter  copied in the memcpy */
 		/* Word5 [rctl, type, df_ctl, la] copied in memcpy */
 		/* word6 context tag copied in memcpy */
@@ -6066,6 +5995,38 @@
 		command_type = OTHER_COMMAND;
 		xritag = 0;
 	break;
+	case CMD_XMIT_BLS_RSP64_CX:
+		/* As BLS ABTS-ACC WQE is very different from other WQEs,
+		 * we re-construct this WQE here based on information in
+		 * iocbq from scratch.
+		 */
+		memset(wqe, 0, sizeof(union lpfc_wqe));
+		/* OX_ID is invariable to who sent ABTS to CT exchange */
+		bf_set(xmit_bls_rsp64_oxid, &wqe->xmit_bls_rsp,
+		       bf_get(lpfc_abts_oxid, &iocbq->iocb.un.bls_acc));
+		if (bf_get(lpfc_abts_orig, &iocbq->iocb.un.bls_acc) ==
+		    LPFC_ABTS_UNSOL_INT) {
+			/* ABTS sent by initiator to CT exchange, the
+			 * RX_ID field will be filled with the newly
+			 * allocated responder XRI.
+			 */
+			bf_set(xmit_bls_rsp64_rxid, &wqe->xmit_bls_rsp,
+			       iocbq->sli4_xritag);
+		} else {
+			/* ABTS sent by responder to CT exchange, the
+			 * RX_ID field will be filled with the responder
+			 * RX_ID from ABTS.
+			 */
+			bf_set(xmit_bls_rsp64_rxid, &wqe->xmit_bls_rsp,
+			       bf_get(lpfc_abts_rxid, &iocbq->iocb.un.bls_acc));
+		}
+		bf_set(xmit_bls_rsp64_seqcnthi, &wqe->xmit_bls_rsp, 0xffff);
+		bf_set(wqe_xmit_bls_pt, &wqe->xmit_bls_rsp.wqe_dest, 0x1);
+		bf_set(wqe_ctxt_tag, &wqe->xmit_bls_rsp.wqe_com,
+		       iocbq->iocb.ulpContext);
+		/* Overwrite the pre-set comnd type with OTHER_COMMAND */
+		command_type = OTHER_COMMAND;
+	break;
 	case CMD_XRI_ABORTED_CX:
 	case CMD_CREATE_XRI_CR: /* Do we expect to use this? */
 		/* words0-2 are all 0's no bde */
@@ -6120,11 +6081,10 @@
 	uint16_t xritag;
 	union lpfc_wqe wqe;
 	struct lpfc_sli_ring *pring = &phba->sli.ring[ring_number];
-	uint32_t fcp_wqidx;
 
 	if (piocb->sli4_xritag == NO_XRI) {
 		if (piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN ||
-			piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN)
+		    piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN)
 			sglq = NULL;
 		else {
 			sglq = __lpfc_sli_get_sglq(phba);
@@ -6155,8 +6115,17 @@
 		return IOCB_ERROR;
 
 	if (piocb->iocb_flag &  LPFC_IO_FCP) {
-		fcp_wqidx = lpfc_sli4_scmd_to_wqidx_distr(phba);
-		if (lpfc_sli4_wq_put(phba->sli4_hba.fcp_wq[fcp_wqidx], &wqe))
+		/*
+		 * For FCP command IOCB, get a new WQ index to distribute
+		 * WQE across the WQsr. On the other hand, for abort IOCB,
+		 * it carries the same WQ index to the original command
+		 * IOCB.
+		 */
+		if ((piocb->iocb.ulpCommand != CMD_ABORT_XRI_CN) &&
+		    (piocb->iocb.ulpCommand != CMD_CLOSE_XRI_CN))
+			piocb->fcp_wqidx = lpfc_sli4_scmd_to_wqidx_distr(phba);
+		if (lpfc_sli4_wq_put(phba->sli4_hba.fcp_wq[piocb->fcp_wqidx],
+				     &wqe))
 			return IOCB_ERROR;
 	} else {
 		if (lpfc_sli4_wq_put(phba->sli4_hba.els_wq, &wqe))
@@ -6449,31 +6418,37 @@
 			pring->iotag_max = 4096;
 			pring->lpfc_sli_rcv_async_status =
 				lpfc_sli_async_event_handler;
-			pring->num_mask = 4;
+			pring->num_mask = LPFC_MAX_RING_MASK;
 			pring->prt[0].profile = 0;	/* Mask 0 */
-			pring->prt[0].rctl = FC_ELS_REQ;
-			pring->prt[0].type = FC_ELS_DATA;
+			pring->prt[0].rctl = FC_RCTL_ELS_REQ;
+			pring->prt[0].type = FC_TYPE_ELS;
 			pring->prt[0].lpfc_sli_rcv_unsol_event =
 			    lpfc_els_unsol_event;
 			pring->prt[1].profile = 0;	/* Mask 1 */
-			pring->prt[1].rctl = FC_ELS_RSP;
-			pring->prt[1].type = FC_ELS_DATA;
+			pring->prt[1].rctl = FC_RCTL_ELS_REP;
+			pring->prt[1].type = FC_TYPE_ELS;
 			pring->prt[1].lpfc_sli_rcv_unsol_event =
 			    lpfc_els_unsol_event;
 			pring->prt[2].profile = 0;	/* Mask 2 */
 			/* NameServer Inquiry */
-			pring->prt[2].rctl = FC_UNSOL_CTL;
+			pring->prt[2].rctl = FC_RCTL_DD_UNSOL_CTL;
 			/* NameServer */
-			pring->prt[2].type = FC_COMMON_TRANSPORT_ULP;
+			pring->prt[2].type = FC_TYPE_CT;
 			pring->prt[2].lpfc_sli_rcv_unsol_event =
 			    lpfc_ct_unsol_event;
 			pring->prt[3].profile = 0;	/* Mask 3 */
 			/* NameServer response */
-			pring->prt[3].rctl = FC_SOL_CTL;
+			pring->prt[3].rctl = FC_RCTL_DD_SOL_CTL;
 			/* NameServer */
-			pring->prt[3].type = FC_COMMON_TRANSPORT_ULP;
+			pring->prt[3].type = FC_TYPE_CT;
 			pring->prt[3].lpfc_sli_rcv_unsol_event =
 			    lpfc_ct_unsol_event;
+			/* abort unsolicited sequence */
+			pring->prt[4].profile = 0;	/* Mask 4 */
+			pring->prt[4].rctl = FC_RCTL_BA_ABTS;
+			pring->prt[4].type = FC_TYPE_BLS;
+			pring->prt[4].lpfc_sli_rcv_unsol_event =
+			    lpfc_sli4_ct_abort_unsol_event;
 			break;
 		}
 		totiocbsize += (pring->numCiocb * pring->sizeCiocb) +
@@ -6976,8 +6951,18 @@
 		abort_iotag = cmdiocb->iocb.un.acxri.abortIoTag;
 
 		spin_lock_irq(&phba->hbalock);
-		if (abort_iotag != 0 && abort_iotag <= phba->sli.last_iotag)
-			abort_iocb = phba->sli.iocbq_lookup[abort_iotag];
+		if (phba->sli_rev < LPFC_SLI_REV4) {
+			if (abort_iotag != 0 &&
+				abort_iotag <= phba->sli.last_iotag)
+				abort_iocb =
+					phba->sli.iocbq_lookup[abort_iotag];
+		} else
+			/* For sli4 the abort_tag is the XRI,
+			 * so the abort routine puts the iotag  of the iocb
+			 * being aborted in the context field of the abort
+			 * IOCB.
+			 */
+			abort_iocb = phba->sli.iocbq_lookup[abort_context];
 
 		lpfc_printf_log(phba, KERN_INFO, LOG_ELS | LOG_SLI,
 				"0327 Cannot abort els iocb %p "
@@ -6991,9 +6976,18 @@
 		 *  might have completed already. Do not free it again.
 		 */
 		if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
-			spin_unlock_irq(&phba->hbalock);
-			lpfc_sli_release_iocbq(phba, cmdiocb);
-			return;
+			if (irsp->un.ulpWord[4] != IOERR_NO_XRI) {
+				spin_unlock_irq(&phba->hbalock);
+				lpfc_sli_release_iocbq(phba, cmdiocb);
+				return;
+			}
+			/* For SLI4 the ulpContext field for abort IOCB
+			 * holds the iotag of the IOCB being aborted so
+			 * the local abort_context needs to be reset to
+			 * match the aborted IOCBs ulpContext.
+			 */
+			if (abort_iocb && phba->sli_rev == LPFC_SLI_REV4)
+				abort_context = abort_iocb->iocb.ulpContext;
 		}
 		/*
 		 * make sure we have the right iocbq before taking it
@@ -7112,13 +7106,18 @@
 	iabt = &abtsiocbp->iocb;
 	iabt->un.acxri.abortType = ABORT_TYPE_ABTS;
 	iabt->un.acxri.abortContextTag = icmd->ulpContext;
-	if (phba->sli_rev == LPFC_SLI_REV4)
+	if (phba->sli_rev == LPFC_SLI_REV4) {
 		iabt->un.acxri.abortIoTag = cmdiocb->sli4_xritag;
+		iabt->un.acxri.abortContextTag = cmdiocb->iotag;
+	}
 	else
 		iabt->un.acxri.abortIoTag = icmd->ulpIoTag;
 	iabt->ulpLe = 1;
 	iabt->ulpClass = icmd->ulpClass;
 
+	/* ABTS WQE must go to the same WQ as the WQE to be aborted */
+	abtsiocbp->fcp_wqidx = cmdiocb->fcp_wqidx;
+
 	if (phba->link_state >= LPFC_LINK_UP)
 		iabt->ulpCommand = CMD_ABORT_XRI_CN;
 	else
@@ -7322,6 +7321,9 @@
 		abtsiocb->iocb.ulpClass = cmd->ulpClass;
 		abtsiocb->vport = phba->pport;
 
+		/* ABTS WQE must go to the same WQ as the WQE to be aborted */
+		abtsiocb->fcp_wqidx = iocbq->fcp_wqidx;
+
 		if (lpfc_is_link_up(phba))
 			abtsiocb->iocb.ulpCommand = CMD_ABORT_XRI_CN;
 		else
@@ -7687,31 +7689,28 @@
 lpfc_sli4_eratt_read(struct lpfc_hba *phba)
 {
 	uint32_t uerr_sta_hi, uerr_sta_lo;
-	uint32_t onlnreg0, onlnreg1;
 
 	/* For now, use the SLI4 device internal unrecoverable error
 	 * registers for error attention. This can be changed later.
 	 */
-	onlnreg0 = readl(phba->sli4_hba.ONLINE0regaddr);
-	onlnreg1 = readl(phba->sli4_hba.ONLINE1regaddr);
-	if ((onlnreg0 != LPFC_ONLINE_NERR) || (onlnreg1 != LPFC_ONLINE_NERR)) {
-		uerr_sta_lo = readl(phba->sli4_hba.UERRLOregaddr);
-		uerr_sta_hi = readl(phba->sli4_hba.UERRHIregaddr);
-		if (uerr_sta_lo || uerr_sta_hi) {
-			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-					"1423 HBA Unrecoverable error: "
-					"uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, "
-					"online0_reg=0x%x, online1_reg=0x%x\n",
-					uerr_sta_lo, uerr_sta_hi,
-					onlnreg0, onlnreg1);
-			phba->work_status[0] = uerr_sta_lo;
-			phba->work_status[1] = uerr_sta_hi;
-			/* Set the driver HA work bitmap */
-			phba->work_ha |= HA_ERATT;
-			/* Indicate polling handles this ERATT */
-			phba->hba_flag |= HBA_ERATT_HANDLED;
-			return 1;
-		}
+	uerr_sta_lo = readl(phba->sli4_hba.UERRLOregaddr);
+	uerr_sta_hi = readl(phba->sli4_hba.UERRHIregaddr);
+	if ((~phba->sli4_hba.ue_mask_lo & uerr_sta_lo) ||
+	    (~phba->sli4_hba.ue_mask_hi & uerr_sta_hi)) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+				"1423 HBA Unrecoverable error: "
+				"uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, "
+				"ue_mask_lo_reg=0x%x, ue_mask_hi_reg=0x%x\n",
+				uerr_sta_lo, uerr_sta_hi,
+				phba->sli4_hba.ue_mask_lo,
+				phba->sli4_hba.ue_mask_hi);
+		phba->work_status[0] = uerr_sta_lo;
+		phba->work_status[1] = uerr_sta_hi;
+		/* Set the driver HA work bitmap */
+		phba->work_ha |= HA_ERATT;
+		/* Indicate polling handles this ERATT */
+		phba->hba_flag |= HBA_ERATT_HANDLED;
+		return 1;
 	}
 	return 0;
 }
@@ -7834,7 +7833,7 @@
 lpfc_sli_sp_intr_handler(int irq, void *dev_id)
 {
 	struct lpfc_hba  *phba;
-	uint32_t ha_copy;
+	uint32_t ha_copy, hc_copy;
 	uint32_t work_ha_copy;
 	unsigned long status;
 	unsigned long iflag;
@@ -7892,8 +7891,13 @@
 		}
 
 		/* Clear up only attention source related to slow-path */
+		hc_copy = readl(phba->HCregaddr);
+		writel(hc_copy & ~(HC_MBINT_ENA | HC_R2INT_ENA |
+			HC_LAINT_ENA | HC_ERINT_ENA),
+			phba->HCregaddr);
 		writel((ha_copy & (HA_MBATT | HA_R2_CLR_MSK)),
 			phba->HAregaddr);
+		writel(hc_copy, phba->HCregaddr);
 		readl(phba->HAregaddr); /* flush */
 		spin_unlock_irqrestore(&phba->hbalock, iflag);
 	} else
@@ -8049,7 +8053,7 @@
 							KERN_ERR,
 							LOG_MBOX | LOG_SLI,
 							"0350 rc should have"
-							"been MBX_BUSY");
+							"been MBX_BUSY\n");
 						if (rc != MBX_NOT_FINISHED)
 							goto send_current_mbox;
 					}
@@ -8078,7 +8082,7 @@
 			if (rc != MBX_SUCCESS)
 				lpfc_printf_log(phba, KERN_ERR, LOG_MBOX |
 						LOG_SLI, "0349 rc should be "
-						"MBX_SUCCESS");
+						"MBX_SUCCESS\n");
 		}
 
 		spin_lock_irqsave(&phba->hbalock, iflag);
@@ -8203,6 +8207,7 @@
 	struct lpfc_hba  *phba;
 	irqreturn_t sp_irq_rc, fp_irq_rc;
 	unsigned long status1, status2;
+	uint32_t hc_copy;
 
 	/*
 	 * Get the driver's phba structure from the dev_id and
@@ -8240,7 +8245,12 @@
 	}
 
 	/* Clear attention sources except link and error attentions */
+	hc_copy = readl(phba->HCregaddr);
+	writel(hc_copy & ~(HC_MBINT_ENA | HC_R0INT_ENA | HC_R1INT_ENA
+		| HC_R2INT_ENA | HC_LAINT_ENA | HC_ERINT_ENA),
+		phba->HCregaddr);
 	writel((phba->ha_copy & ~(HA_LATT | HA_ERATT)), phba->HAregaddr);
+	writel(hc_copy, phba->HCregaddr);
 	readl(phba->HAregaddr); /* flush */
 	spin_unlock(&phba->hbalock);
 
@@ -8351,8 +8361,6 @@
 
 	memcpy((char *)pIocbIn + offset, (char *)pIocbOut + offset,
 	       sizeof(struct lpfc_iocbq) - offset);
-	memset(&pIocbIn->sli4_info, 0,
-	       sizeof(struct lpfc_sli4_rspiocb_info));
 	/* Map WCQE parameters into irspiocb parameters */
 	pIocbIn->iocb.ulpStatus = bf_get(lpfc_wcqe_c_status, wcqe);
 	if (pIocbOut->iocb_flag & LPFC_IO_FCP)
@@ -8364,16 +8372,49 @@
 			pIocbIn->iocb.un.ulpWord[4] = wcqe->parameter;
 	else
 		pIocbIn->iocb.un.ulpWord[4] = wcqe->parameter;
-	/* Load in additional WCQE parameters */
-	pIocbIn->sli4_info.hw_status = bf_get(lpfc_wcqe_c_hw_status, wcqe);
-	pIocbIn->sli4_info.bfield = 0;
-	if (bf_get(lpfc_wcqe_c_xb, wcqe))
-		pIocbIn->sli4_info.bfield |= LPFC_XB;
-	if (bf_get(lpfc_wcqe_c_pv, wcqe)) {
-		pIocbIn->sli4_info.bfield |= LPFC_PV;
-		pIocbIn->sli4_info.priority =
-					bf_get(lpfc_wcqe_c_priority, wcqe);
+}
+
+/**
+ * lpfc_sli4_els_wcqe_to_rspiocbq - Get response iocbq from els wcqe
+ * @phba: Pointer to HBA context object.
+ * @wcqe: Pointer to work-queue completion queue entry.
+ *
+ * This routine handles an ELS work-queue completion event and construct
+ * a pseudo response ELS IODBQ from the SLI4 ELS WCQE for the common
+ * discovery engine to handle.
+ *
+ * Return: Pointer to the receive IOCBQ, NULL otherwise.
+ **/
+static struct lpfc_iocbq *
+lpfc_sli4_els_wcqe_to_rspiocbq(struct lpfc_hba *phba,
+			       struct lpfc_iocbq *irspiocbq)
+{
+	struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
+	struct lpfc_iocbq *cmdiocbq;
+	struct lpfc_wcqe_complete *wcqe;
+	unsigned long iflags;
+
+	wcqe = &irspiocbq->cq_event.cqe.wcqe_cmpl;
+	spin_lock_irqsave(&phba->hbalock, iflags);
+	pring->stats.iocb_event++;
+	/* Look up the ELS command IOCB and create pseudo response IOCB */
+	cmdiocbq = lpfc_sli_iocbq_lookup_by_tag(phba, pring,
+				bf_get(lpfc_wcqe_c_request_tag, wcqe));
+	spin_unlock_irqrestore(&phba->hbalock, iflags);
+
+	if (unlikely(!cmdiocbq)) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
+				"0386 ELS complete with no corresponding "
+				"cmdiocb: iotag (%d)\n",
+				bf_get(lpfc_wcqe_c_request_tag, wcqe));
+		lpfc_sli_release_iocbq(phba, irspiocbq);
+		return NULL;
 	}
+
+	/* Fake the irspiocbq and copy necessary response information */
+	lpfc_sli4_iocb_param_transfer(irspiocbq, cmdiocbq, wcqe);
+
+	return irspiocbq;
 }
 
 /**
@@ -8566,45 +8607,26 @@
 lpfc_sli4_sp_handle_els_wcqe(struct lpfc_hba *phba,
 			     struct lpfc_wcqe_complete *wcqe)
 {
-	struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
-	struct lpfc_iocbq *cmdiocbq;
 	struct lpfc_iocbq *irspiocbq;
 	unsigned long iflags;
-	bool workposted = false;
 
-	spin_lock_irqsave(&phba->hbalock, iflags);
-	pring->stats.iocb_event++;
-	/* Look up the ELS command IOCB and create pseudo response IOCB */
-	cmdiocbq = lpfc_sli_iocbq_lookup_by_tag(phba, pring,
-				bf_get(lpfc_wcqe_c_request_tag, wcqe));
-	spin_unlock_irqrestore(&phba->hbalock, iflags);
-
-	if (unlikely(!cmdiocbq)) {
-		lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
-				"0386 ELS complete with no corresponding "
-				"cmdiocb: iotag (%d)\n",
-				bf_get(lpfc_wcqe_c_request_tag, wcqe));
-		return workposted;
-	}
-
-	/* Fake the irspiocbq and copy necessary response information */
+	/* Get an irspiocbq for later ELS response processing use */
 	irspiocbq = lpfc_sli_get_iocbq(phba);
 	if (!irspiocbq) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
 				"0387 Failed to allocate an iocbq\n");
-		return workposted;
+		return false;
 	}
-	lpfc_sli4_iocb_param_transfer(irspiocbq, cmdiocbq, wcqe);
 
-	/* Add the irspiocb to the response IOCB work list */
+	/* Save off the slow-path queue event for work thread to process */
+	memcpy(&irspiocbq->cq_event.cqe.wcqe_cmpl, wcqe, sizeof(*wcqe));
 	spin_lock_irqsave(&phba->hbalock, iflags);
-	list_add_tail(&irspiocbq->list, &phba->sli4_hba.sp_rspiocb_work_queue);
-	/* Indicate ELS ring attention */
-	phba->work_ha |= (HA_R0ATT << (4*LPFC_ELS_RING));
+	list_add_tail(&irspiocbq->cq_event.list,
+		      &phba->sli4_hba.sp_queue_event);
+	phba->hba_flag |= HBA_SP_QUEUE_EVT;
 	spin_unlock_irqrestore(&phba->hbalock, iflags);
-	workposted = true;
 
-	return workposted;
+	return true;
 }
 
 /**
@@ -8690,52 +8712,6 @@
 }
 
 /**
- * lpfc_sli4_sp_handle_wcqe - Process a work-queue completion queue entry
- * @phba: Pointer to HBA context object.
- * @cq: Pointer to the completion queue.
- * @wcqe: Pointer to a completion queue entry.
- *
- * This routine process a slow-path work-queue completion queue entry.
- *
- * Return: true if work posted to worker thread, otherwise false.
- **/
-static bool
-lpfc_sli4_sp_handle_wcqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
-			 struct lpfc_cqe *cqe)
-{
-	struct lpfc_wcqe_complete wcqe;
-	bool workposted = false;
-
-	/* Copy the work queue CQE and convert endian order if needed */
-	lpfc_sli_pcimem_bcopy(cqe, &wcqe, sizeof(struct lpfc_cqe));
-
-	/* Check and process for different type of WCQE and dispatch */
-	switch (bf_get(lpfc_wcqe_c_code, &wcqe)) {
-	case CQE_CODE_COMPL_WQE:
-		/* Process the WQ complete event */
-		workposted = lpfc_sli4_sp_handle_els_wcqe(phba,
-					(struct lpfc_wcqe_complete *)&wcqe);
-		break;
-	case CQE_CODE_RELEASE_WQE:
-		/* Process the WQ release event */
-		lpfc_sli4_sp_handle_rel_wcqe(phba,
-					(struct lpfc_wcqe_release *)&wcqe);
-		break;
-	case CQE_CODE_XRI_ABORTED:
-		/* Process the WQ XRI abort event */
-		workposted = lpfc_sli4_sp_handle_abort_xri_wcqe(phba, cq,
-					(struct sli4_wcqe_xri_aborted *)&wcqe);
-		break;
-	default:
-		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
-				"0388 Not a valid WCQE code: x%x\n",
-				bf_get(lpfc_wcqe_c_code, &wcqe));
-		break;
-	}
-	return workposted;
-}
-
-/**
  * lpfc_sli4_sp_handle_rcqe - Process a receive-queue completion queue entry
  * @phba: Pointer to HBA context object.
  * @rcqe: Pointer to receive-queue completion queue entry.
@@ -8745,9 +8721,8 @@
  * Return: true if work posted to worker thread, otherwise false.
  **/
 static bool
-lpfc_sli4_sp_handle_rcqe(struct lpfc_hba *phba, struct lpfc_cqe *cqe)
+lpfc_sli4_sp_handle_rcqe(struct lpfc_hba *phba, struct lpfc_rcqe *rcqe)
 {
-	struct lpfc_rcqe rcqe;
 	bool workposted = false;
 	struct lpfc_queue *hrq = phba->sli4_hba.hdr_rq;
 	struct lpfc_queue *drq = phba->sli4_hba.dat_rq;
@@ -8755,31 +8730,28 @@
 	uint32_t status;
 	unsigned long iflags;
 
-	/* Copy the receive queue CQE and convert endian order if needed */
-	lpfc_sli_pcimem_bcopy(cqe, &rcqe, sizeof(struct lpfc_rcqe));
-	lpfc_sli4_rq_release(hrq, drq);
-	if (bf_get(lpfc_rcqe_code, &rcqe) != CQE_CODE_RECEIVE)
-		goto out;
-	if (bf_get(lpfc_rcqe_rq_id, &rcqe) != hrq->queue_id)
+	if (bf_get(lpfc_rcqe_rq_id, rcqe) != hrq->queue_id)
 		goto out;
 
-	status = bf_get(lpfc_rcqe_status, &rcqe);
+	status = bf_get(lpfc_rcqe_status, rcqe);
 	switch (status) {
 	case FC_STATUS_RQ_BUF_LEN_EXCEEDED:
 		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
 				"2537 Receive Frame Truncated!!\n");
 	case FC_STATUS_RQ_SUCCESS:
+		lpfc_sli4_rq_release(hrq, drq);
 		spin_lock_irqsave(&phba->hbalock, iflags);
 		dma_buf = lpfc_sli_hbqbuf_get(&phba->hbqs[0].hbq_buffer_list);
 		if (!dma_buf) {
 			spin_unlock_irqrestore(&phba->hbalock, iflags);
 			goto out;
 		}
-		memcpy(&dma_buf->rcqe, &rcqe, sizeof(rcqe));
+		memcpy(&dma_buf->cq_event.cqe.rcqe_cmpl, rcqe, sizeof(*rcqe));
 		/* save off the frame for the word thread to process */
-		list_add_tail(&dma_buf->dbuf.list, &phba->rb_pend_list);
+		list_add_tail(&dma_buf->cq_event.list,
+			      &phba->sli4_hba.sp_queue_event);
 		/* Frame received */
-		phba->hba_flag |= HBA_RECEIVE_BUFFER;
+		phba->hba_flag |= HBA_SP_QUEUE_EVT;
 		spin_unlock_irqrestore(&phba->hbalock, iflags);
 		workposted = true;
 		break;
@@ -8794,7 +8766,58 @@
 	}
 out:
 	return workposted;
+}
 
+/**
+ * lpfc_sli4_sp_handle_cqe - Process a slow path completion queue entry
+ * @phba: Pointer to HBA context object.
+ * @cq: Pointer to the completion queue.
+ * @wcqe: Pointer to a completion queue entry.
+ *
+ * This routine process a slow-path work-queue or recieve queue completion queue
+ * entry.
+ *
+ * Return: true if work posted to worker thread, otherwise false.
+ **/
+static bool
+lpfc_sli4_sp_handle_cqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
+			 struct lpfc_cqe *cqe)
+{
+	struct lpfc_cqe cqevt;
+	bool workposted = false;
+
+	/* Copy the work queue CQE and convert endian order if needed */
+	lpfc_sli_pcimem_bcopy(cqe, &cqevt, sizeof(struct lpfc_cqe));
+
+	/* Check and process for different type of WCQE and dispatch */
+	switch (bf_get(lpfc_cqe_code, &cqevt)) {
+	case CQE_CODE_COMPL_WQE:
+		/* Process the WQ/RQ complete event */
+		workposted = lpfc_sli4_sp_handle_els_wcqe(phba,
+				(struct lpfc_wcqe_complete *)&cqevt);
+		break;
+	case CQE_CODE_RELEASE_WQE:
+		/* Process the WQ release event */
+		lpfc_sli4_sp_handle_rel_wcqe(phba,
+				(struct lpfc_wcqe_release *)&cqevt);
+		break;
+	case CQE_CODE_XRI_ABORTED:
+		/* Process the WQ XRI abort event */
+		workposted = lpfc_sli4_sp_handle_abort_xri_wcqe(phba, cq,
+				(struct sli4_wcqe_xri_aborted *)&cqevt);
+		break;
+	case CQE_CODE_RECEIVE:
+		/* Process the RQ event */
+		workposted = lpfc_sli4_sp_handle_rcqe(phba,
+				(struct lpfc_rcqe *)&cqevt);
+		break;
+	default:
+		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+				"0388 Not a valid WCQE code: x%x\n",
+				bf_get(lpfc_cqe_code, &cqevt));
+		break;
+	}
+	return workposted;
 }
 
 /**
@@ -8858,14 +8881,7 @@
 		break;
 	case LPFC_WCQ:
 		while ((cqe = lpfc_sli4_cq_get(cq))) {
-			workposted |= lpfc_sli4_sp_handle_wcqe(phba, cq, cqe);
-			if (!(++ecount % LPFC_GET_QE_REL_INT))
-				lpfc_sli4_cq_release(cq, LPFC_QUEUE_NOARM);
-		}
-		break;
-	case LPFC_RCQ:
-		while ((cqe = lpfc_sli4_cq_get(cq))) {
-			workposted |= lpfc_sli4_sp_handle_rcqe(phba, cqe);
+			workposted |= lpfc_sli4_sp_handle_cqe(phba, cq, cqe);
 			if (!(++ecount % LPFC_GET_QE_REL_INT))
 				lpfc_sli4_cq_release(cq, LPFC_QUEUE_NOARM);
 		}
@@ -10427,8 +10443,7 @@
 		return xritag;
 	}
 	spin_unlock_irq(&phba->hbalock);
-
-	lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+	lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
 			"2004 Failed to allocate XRI.last XRITAG is %d"
 			" Max XRI is %d, Used XRI is %d\n",
 			phba->sli4_hba.next_xri,
@@ -10492,15 +10507,7 @@
 		lpfc_sli4_mbox_cmd_free(phba, mbox);
 		return -ENOMEM;
 	}
-
 	/* Get the first SGE entry from the non-embedded DMA memory */
-	if (unlikely(!mbox->sge_array)) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
-				"2525 Failed to get the non-embedded SGE "
-				"virtual address\n");
-		lpfc_sli4_mbox_cmd_free(phba, mbox);
-		return -ENOMEM;
-	}
 	viraddr = mbox->sge_array->addr[0];
 
 	/* Set up the SGL pages in the non-embedded DMA pages */
@@ -10524,8 +10531,7 @@
 		sgl_pg_pairs++;
 	}
 	bf_set(lpfc_post_sgl_pages_xri, sgl, xritag_start);
-	pg_pairs = (pg_pairs > 0) ? (pg_pairs - 1) : pg_pairs;
-	bf_set(lpfc_post_sgl_pages_xricnt, sgl, pg_pairs);
+	bf_set(lpfc_post_sgl_pages_xricnt, sgl, els_xri_cnt);
 	/* Perform endian conversion if necessary */
 	sgl->word0 = cpu_to_le32(sgl->word0);
 
@@ -10607,15 +10613,7 @@
 		lpfc_sli4_mbox_cmd_free(phba, mbox);
 		return -ENOMEM;
 	}
-
 	/* Get the first SGE entry from the non-embedded DMA memory */
-	if (unlikely(!mbox->sge_array)) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
-				"2565 Failed to get the non-embedded SGE "
-				"virtual address\n");
-		lpfc_sli4_mbox_cmd_free(phba, mbox);
-		return -ENOMEM;
-	}
 	viraddr = mbox->sge_array->addr[0];
 
 	/* Set up the SGL pages in the non-embedded DMA pages */
@@ -10802,6 +10800,105 @@
 }
 
 /**
+ * lpfc_update_rcv_time_stamp - Update vport's rcv seq time stamp
+ * @vport: The vport to work on.
+ *
+ * This function updates the receive sequence time stamp for this vport. The
+ * receive sequence time stamp indicates the time that the last frame of the
+ * the sequence that has been idle for the longest amount of time was received.
+ * the driver uses this time stamp to indicate if any received sequences have
+ * timed out.
+ **/
+void
+lpfc_update_rcv_time_stamp(struct lpfc_vport *vport)
+{
+	struct lpfc_dmabuf *h_buf;
+	struct hbq_dmabuf *dmabuf = NULL;
+
+	/* get the oldest sequence on the rcv list */
+	h_buf = list_get_first(&vport->rcv_buffer_list,
+			       struct lpfc_dmabuf, list);
+	if (!h_buf)
+		return;
+	dmabuf = container_of(h_buf, struct hbq_dmabuf, hbuf);
+	vport->rcv_buffer_time_stamp = dmabuf->time_stamp;
+}
+
+/**
+ * lpfc_cleanup_rcv_buffers - Cleans up all outstanding receive sequences.
+ * @vport: The vport that the received sequences were sent to.
+ *
+ * This function cleans up all outstanding received sequences. This is called
+ * by the driver when a link event or user action invalidates all the received
+ * sequences.
+ **/
+void
+lpfc_cleanup_rcv_buffers(struct lpfc_vport *vport)
+{
+	struct lpfc_dmabuf *h_buf, *hnext;
+	struct lpfc_dmabuf *d_buf, *dnext;
+	struct hbq_dmabuf *dmabuf = NULL;
+
+	/* start with the oldest sequence on the rcv list */
+	list_for_each_entry_safe(h_buf, hnext, &vport->rcv_buffer_list, list) {
+		dmabuf = container_of(h_buf, struct hbq_dmabuf, hbuf);
+		list_del_init(&dmabuf->hbuf.list);
+		list_for_each_entry_safe(d_buf, dnext,
+					 &dmabuf->dbuf.list, list) {
+			list_del_init(&d_buf->list);
+			lpfc_in_buf_free(vport->phba, d_buf);
+		}
+		lpfc_in_buf_free(vport->phba, &dmabuf->dbuf);
+	}
+}
+
+/**
+ * lpfc_rcv_seq_check_edtov - Cleans up timed out receive sequences.
+ * @vport: The vport that the received sequences were sent to.
+ *
+ * This function determines whether any received sequences have timed out by
+ * first checking the vport's rcv_buffer_time_stamp. If this time_stamp
+ * indicates that there is at least one timed out sequence this routine will
+ * go through the received sequences one at a time from most inactive to most
+ * active to determine which ones need to be cleaned up. Once it has determined
+ * that a sequence needs to be cleaned up it will simply free up the resources
+ * without sending an abort.
+ **/
+void
+lpfc_rcv_seq_check_edtov(struct lpfc_vport *vport)
+{
+	struct lpfc_dmabuf *h_buf, *hnext;
+	struct lpfc_dmabuf *d_buf, *dnext;
+	struct hbq_dmabuf *dmabuf = NULL;
+	unsigned long timeout;
+	int abort_count = 0;
+
+	timeout = (msecs_to_jiffies(vport->phba->fc_edtov) +
+		   vport->rcv_buffer_time_stamp);
+	if (list_empty(&vport->rcv_buffer_list) ||
+	    time_before(jiffies, timeout))
+		return;
+	/* start with the oldest sequence on the rcv list */
+	list_for_each_entry_safe(h_buf, hnext, &vport->rcv_buffer_list, list) {
+		dmabuf = container_of(h_buf, struct hbq_dmabuf, hbuf);
+		timeout = (msecs_to_jiffies(vport->phba->fc_edtov) +
+			   dmabuf->time_stamp);
+		if (time_before(jiffies, timeout))
+			break;
+		abort_count++;
+		list_del_init(&dmabuf->hbuf.list);
+		list_for_each_entry_safe(d_buf, dnext,
+					 &dmabuf->dbuf.list, list) {
+			list_del_init(&d_buf->list);
+			lpfc_in_buf_free(vport->phba, d_buf);
+		}
+		lpfc_in_buf_free(vport->phba, &dmabuf->dbuf);
+	}
+	if (abort_count)
+		lpfc_update_rcv_time_stamp(vport);
+}
+
+/**
  * lpfc_fc_frame_add - Adds a frame to the vport's list of received sequences
  * @dmabuf: pointer to a dmabuf that describes the hdr and data of the FC frame
  *
@@ -10823,6 +10920,8 @@
 	struct hbq_dmabuf *seq_dmabuf = NULL;
 	struct hbq_dmabuf *temp_dmabuf = NULL;
 
+	INIT_LIST_HEAD(&dmabuf->dbuf.list);
+	dmabuf->time_stamp = jiffies;
 	new_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt;
 	/* Use the hdr_buf to find the sequence that this frame belongs to */
 	list_for_each_entry(h_buf, &vport->rcv_buffer_list, list) {
@@ -10841,13 +10940,21 @@
 		 * Queue the buffer on the vport's rcv_buffer_list.
 		 */
 		list_add_tail(&dmabuf->hbuf.list, &vport->rcv_buffer_list);
+		lpfc_update_rcv_time_stamp(vport);
 		return dmabuf;
 	}
 	temp_hdr = seq_dmabuf->hbuf.virt;
 	if (new_hdr->fh_seq_cnt < temp_hdr->fh_seq_cnt) {
-		list_add(&seq_dmabuf->dbuf.list, &dmabuf->dbuf.list);
+		list_del_init(&seq_dmabuf->hbuf.list);
+		list_add_tail(&dmabuf->hbuf.list, &vport->rcv_buffer_list);
+		list_add_tail(&dmabuf->dbuf.list, &seq_dmabuf->dbuf.list);
+		lpfc_update_rcv_time_stamp(vport);
 		return dmabuf;
 	}
+	/* move this sequence to the tail to indicate a young sequence */
+	list_move_tail(&seq_dmabuf->hbuf.list, &vport->rcv_buffer_list);
+	seq_dmabuf->time_stamp = jiffies;
+	lpfc_update_rcv_time_stamp(vport);
 	/* find the correct place in the sequence to insert this frame */
 	list_for_each_entry_reverse(d_buf, &seq_dmabuf->dbuf.list, list) {
 		temp_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf);
@@ -10865,6 +10972,210 @@
 }
 
 /**
+ * lpfc_sli4_abort_partial_seq - Abort partially assembled unsol sequence
+ * @vport: pointer to a vitural port
+ * @dmabuf: pointer to a dmabuf that describes the FC sequence
+ *
+ * This function tries to abort from the partially assembed sequence, described
+ * by the information from basic abbort @dmabuf. It checks to see whether such
+ * partially assembled sequence held by the driver. If so, it shall free up all
+ * the frames from the partially assembled sequence.
+ *
+ * Return
+ * true  -- if there is matching partially assembled sequence present and all
+ *          the frames freed with the sequence;
+ * false -- if there is no matching partially assembled sequence present so
+ *          nothing got aborted in the lower layer driver
+ **/
+static bool
+lpfc_sli4_abort_partial_seq(struct lpfc_vport *vport,
+			    struct hbq_dmabuf *dmabuf)
+{
+	struct fc_frame_header *new_hdr;
+	struct fc_frame_header *temp_hdr;
+	struct lpfc_dmabuf *d_buf, *n_buf, *h_buf;
+	struct hbq_dmabuf *seq_dmabuf = NULL;
+
+	/* Use the hdr_buf to find the sequence that matches this frame */
+	INIT_LIST_HEAD(&dmabuf->dbuf.list);
+	INIT_LIST_HEAD(&dmabuf->hbuf.list);
+	new_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt;
+	list_for_each_entry(h_buf, &vport->rcv_buffer_list, list) {
+		temp_hdr = (struct fc_frame_header *)h_buf->virt;
+		if ((temp_hdr->fh_seq_id != new_hdr->fh_seq_id) ||
+		    (temp_hdr->fh_ox_id != new_hdr->fh_ox_id) ||
+		    (memcmp(&temp_hdr->fh_s_id, &new_hdr->fh_s_id, 3)))
+			continue;
+		/* found a pending sequence that matches this frame */
+		seq_dmabuf = container_of(h_buf, struct hbq_dmabuf, hbuf);
+		break;
+	}
+
+	/* Free up all the frames from the partially assembled sequence */
+	if (seq_dmabuf) {
+		list_for_each_entry_safe(d_buf, n_buf,
+					 &seq_dmabuf->dbuf.list, list) {
+			list_del_init(&d_buf->list);
+			lpfc_in_buf_free(vport->phba, d_buf);
+		}
+		return true;
+	}
+	return false;
+}
+
+/**
+ * lpfc_sli4_seq_abort_acc_cmpl - Accept seq abort iocb complete handler
+ * @phba: Pointer to HBA context object.
+ * @cmd_iocbq: pointer to the command iocbq structure.
+ * @rsp_iocbq: pointer to the response iocbq structure.
+ *
+ * This function handles the sequence abort accept iocb command complete
+ * event. It properly releases the memory allocated to the sequence abort
+ * accept iocb.
+ **/
+static void
+lpfc_sli4_seq_abort_acc_cmpl(struct lpfc_hba *phba,
+			     struct lpfc_iocbq *cmd_iocbq,
+			     struct lpfc_iocbq *rsp_iocbq)
+{
+	if (cmd_iocbq)
+		lpfc_sli_release_iocbq(phba, cmd_iocbq);
+}
+
+/**
+ * lpfc_sli4_seq_abort_acc - Accept sequence abort
+ * @phba: Pointer to HBA context object.
+ * @fc_hdr: pointer to a FC frame header.
+ *
+ * This function sends a basic accept to a previous unsol sequence abort
+ * event after aborting the sequence handling.
+ **/
+static void
+lpfc_sli4_seq_abort_acc(struct lpfc_hba *phba,
+			struct fc_frame_header *fc_hdr)
+{
+	struct lpfc_iocbq *ctiocb = NULL;
+	struct lpfc_nodelist *ndlp;
+	uint16_t oxid, rxid;
+	uint32_t sid, fctl;
+	IOCB_t *icmd;
+
+	if (!lpfc_is_link_up(phba))
+		return;
+
+	sid = sli4_sid_from_fc_hdr(fc_hdr);
+	oxid = be16_to_cpu(fc_hdr->fh_ox_id);
+	rxid = be16_to_cpu(fc_hdr->fh_rx_id);
+
+	ndlp = lpfc_findnode_did(phba->pport, sid);
+	if (!ndlp) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_ELS,
+				"1268 Find ndlp returned NULL for oxid:x%x "
+				"SID:x%x\n", oxid, sid);
+		return;
+	}
+
+	/* Allocate buffer for acc iocb */
+	ctiocb = lpfc_sli_get_iocbq(phba);
+	if (!ctiocb)
+		return;
+
+	/* Extract the F_CTL field from FC_HDR */
+	fctl = sli4_fctl_from_fc_hdr(fc_hdr);
+
+	icmd = &ctiocb->iocb;
+	icmd->un.xseq64.bdl.bdeSize = 0;
+	icmd->un.xseq64.bdl.ulpIoTag32 = 0;
+	icmd->un.xseq64.w5.hcsw.Dfctl = 0;
+	icmd->un.xseq64.w5.hcsw.Rctl = FC_RCTL_BA_ACC;
+	icmd->un.xseq64.w5.hcsw.Type = FC_TYPE_BLS;
+
+	/* Fill in the rest of iocb fields */
+	icmd->ulpCommand = CMD_XMIT_BLS_RSP64_CX;
+	icmd->ulpBdeCount = 0;
+	icmd->ulpLe = 1;
+	icmd->ulpClass = CLASS3;
+	icmd->ulpContext = ndlp->nlp_rpi;
+
+	ctiocb->iocb_cmpl = NULL;
+	ctiocb->vport = phba->pport;
+	ctiocb->iocb_cmpl = lpfc_sli4_seq_abort_acc_cmpl;
+
+	if (fctl & FC_FC_EX_CTX) {
+		/* ABTS sent by responder to CT exchange, construction
+		 * of BA_ACC will use OX_ID from ABTS for the XRI_TAG
+		 * field and RX_ID from ABTS for RX_ID field.
+		 */
+		bf_set(lpfc_abts_orig, &icmd->un.bls_acc, LPFC_ABTS_UNSOL_RSP);
+		bf_set(lpfc_abts_rxid, &icmd->un.bls_acc, rxid);
+		ctiocb->sli4_xritag = oxid;
+	} else {
+		/* ABTS sent by initiator to CT exchange, construction
+		 * of BA_ACC will need to allocate a new XRI as for the
+		 * XRI_TAG and RX_ID fields.
+		 */
+		bf_set(lpfc_abts_orig, &icmd->un.bls_acc, LPFC_ABTS_UNSOL_INT);
+		bf_set(lpfc_abts_rxid, &icmd->un.bls_acc, NO_XRI);
+		ctiocb->sli4_xritag = NO_XRI;
+	}
+	bf_set(lpfc_abts_oxid, &icmd->un.bls_acc, oxid);
+
+	/* Xmit CT abts accept on exchange <xid> */
+	lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
+			"1200 Xmit CT ABTS ACC on exchange x%x Data: x%x\n",
+			CMD_XMIT_BLS_RSP64_CX, phba->link_state);
+	lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, ctiocb, 0);
+}
+
+/**
+ * lpfc_sli4_handle_unsol_abort - Handle sli-4 unsolicited abort event
+ * @vport: Pointer to the vport on which this sequence was received
+ * @dmabuf: pointer to a dmabuf that describes the FC sequence
+ *
+ * This function handles an SLI-4 unsolicited abort event. If the unsolicited
+ * receive sequence is only partially assembed by the driver, it shall abort
+ * the partially assembled frames for the sequence. Otherwise, if the
+ * unsolicited receive sequence has been completely assembled and passed to
+ * the Upper Layer Protocol (UPL), it then mark the per oxid status for the
+ * unsolicited sequence has been aborted. After that, it will issue a basic
+ * accept to accept the abort.
+ **/
+void
+lpfc_sli4_handle_unsol_abort(struct lpfc_vport *vport,
+			     struct hbq_dmabuf *dmabuf)
+{
+	struct lpfc_hba *phba = vport->phba;
+	struct fc_frame_header fc_hdr;
+	uint32_t fctl;
+	bool abts_par;
+
+	/* Make a copy of fc_hdr before the dmabuf being released */
+	memcpy(&fc_hdr, dmabuf->hbuf.virt, sizeof(struct fc_frame_header));
+	fctl = sli4_fctl_from_fc_hdr(&fc_hdr);
+
+	if (fctl & FC_FC_EX_CTX) {
+		/*
+		 * ABTS sent by responder to exchange, just free the buffer
+		 */
+		lpfc_in_buf_free(phba, &dmabuf->dbuf);
+	} else {
+		/*
+		 * ABTS sent by initiator to exchange, need to do cleanup
+		 */
+		/* Try to abort partially assembled seq */
+		abts_par = lpfc_sli4_abort_partial_seq(vport, dmabuf);
+
+		/* Send abort to ULP if partially seq abort failed */
+		if (abts_par == false)
+			lpfc_sli4_send_seq_to_ulp(vport, dmabuf);
+		else
+			lpfc_in_buf_free(phba, &dmabuf->dbuf);
+	}
+	/* Send basic accept (BA_ACC) to the abort requester */
+	lpfc_sli4_seq_abort_acc(phba, &fc_hdr);
+}
+
+/**
  * lpfc_seq_complete - Indicates if a sequence is complete
  * @dmabuf: pointer to a dmabuf that describes the FC sequence
  *
@@ -10935,10 +11246,9 @@
 	fc_hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt;
 	/* remove from receive buffer list */
 	list_del_init(&seq_dmabuf->hbuf.list);
+	lpfc_update_rcv_time_stamp(vport);
 	/* get the Remote Port's SID */
-	sid = (fc_hdr->fh_s_id[0] << 16 |
-	       fc_hdr->fh_s_id[1] << 8 |
-	       fc_hdr->fh_s_id[2]);
+	sid = sli4_sid_from_fc_hdr(fc_hdr);
 	/* Get an iocbq struct to fill in. */
 	first_iocbq = lpfc_sli_get_iocbq(vport->phba);
 	if (first_iocbq) {
@@ -10957,7 +11267,8 @@
 							LPFC_DATA_BUF_SIZE;
 		first_iocbq->iocb.un.rcvels.remoteID = sid;
 		first_iocbq->iocb.unsli3.rcvsli3.acc_len +=
-				bf_get(lpfc_rcqe_length, &seq_dmabuf->rcqe);
+				bf_get(lpfc_rcqe_length,
+				       &seq_dmabuf->cq_event.cqe.rcqe_cmpl);
 	}
 	iocbq = first_iocbq;
 	/*
@@ -10975,7 +11286,8 @@
 			iocbq->iocb.unsli3.rcvsli3.bde2.tus.f.bdeSize =
 							LPFC_DATA_BUF_SIZE;
 			first_iocbq->iocb.unsli3.rcvsli3.acc_len +=
-				bf_get(lpfc_rcqe_length, &seq_dmabuf->rcqe);
+				bf_get(lpfc_rcqe_length,
+				       &seq_dmabuf->cq_event.cqe.rcqe_cmpl);
 		} else {
 			iocbq = lpfc_sli_get_iocbq(vport->phba);
 			if (!iocbq) {
@@ -10994,7 +11306,8 @@
 			iocbq->iocb.un.cont64[0].tus.f.bdeSize =
 							LPFC_DATA_BUF_SIZE;
 			first_iocbq->iocb.unsli3.rcvsli3.acc_len +=
-				bf_get(lpfc_rcqe_length, &seq_dmabuf->rcqe);
+				bf_get(lpfc_rcqe_length,
+				       &seq_dmabuf->cq_event.cqe.rcqe_cmpl);
 			iocbq->iocb.un.rcvels.remoteID = sid;
 			list_add_tail(&iocbq->list, &first_iocbq->list);
 		}
@@ -11002,6 +11315,43 @@
 	return first_iocbq;
 }
 
+static void
+lpfc_sli4_send_seq_to_ulp(struct lpfc_vport *vport,
+			  struct hbq_dmabuf *seq_dmabuf)
+{
+	struct fc_frame_header *fc_hdr;
+	struct lpfc_iocbq *iocbq, *curr_iocb, *next_iocb;
+	struct lpfc_hba *phba = vport->phba;
+
+	fc_hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt;
+	iocbq = lpfc_prep_seq(vport, seq_dmabuf);
+	if (!iocbq) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+				"2707 Ring %d handler: Failed to allocate "
+				"iocb Rctl x%x Type x%x received\n",
+				LPFC_ELS_RING,
+				fc_hdr->fh_r_ctl, fc_hdr->fh_type);
+		return;
+	}
+	if (!lpfc_complete_unsol_iocb(phba,
+				      &phba->sli.ring[LPFC_ELS_RING],
+				      iocbq, fc_hdr->fh_r_ctl,
+				      fc_hdr->fh_type))
+		lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
+				"2540 Ring %d handler: unexpected Rctl "
+				"x%x Type x%x received\n",
+				LPFC_ELS_RING,
+				fc_hdr->fh_r_ctl, fc_hdr->fh_type);
+
+	/* Free iocb created in lpfc_prep_seq */
+	list_for_each_entry_safe(curr_iocb, next_iocb,
+		&iocbq->list, list) {
+		list_del_init(&curr_iocb->list);
+		lpfc_sli_release_iocbq(phba, curr_iocb);
+	}
+	lpfc_sli_release_iocbq(phba, iocbq);
+}
+
 /**
  * lpfc_sli4_handle_received_buffer - Handle received buffers from firmware
  * @phba: Pointer to HBA context object.
@@ -11014,67 +11364,54 @@
  * Worker thread calls lpfc_sli4_handle_received_buffer, which will call the
  * appropriate receive function when the final frame in a sequence is received.
  **/
-int
-lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba)
+void
+lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba,
+				 struct hbq_dmabuf *dmabuf)
 {
-	LIST_HEAD(cmplq);
-	struct hbq_dmabuf *dmabuf, *seq_dmabuf;
+	struct hbq_dmabuf *seq_dmabuf;
 	struct fc_frame_header *fc_hdr;
 	struct lpfc_vport *vport;
 	uint32_t fcfi;
-	struct lpfc_iocbq *iocbq;
-
-	/* Clear hba flag and get all received buffers into the cmplq */
-	spin_lock_irq(&phba->hbalock);
-	phba->hba_flag &= ~HBA_RECEIVE_BUFFER;
-	list_splice_init(&phba->rb_pend_list, &cmplq);
-	spin_unlock_irq(&phba->hbalock);
 
 	/* Process each received buffer */
-	while ((dmabuf = lpfc_sli_hbqbuf_get(&cmplq)) != NULL) {
-		fc_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt;
-		/* check to see if this a valid type of frame */
-		if (lpfc_fc_frame_check(phba, fc_hdr)) {
-			lpfc_in_buf_free(phba, &dmabuf->dbuf);
-			continue;
-		}
-		fcfi = bf_get(lpfc_rcqe_fcf_id, &dmabuf->rcqe);
-		vport = lpfc_fc_frame_to_vport(phba, fc_hdr, fcfi);
-		if (!vport) {
-			/* throw out the frame */
-			lpfc_in_buf_free(phba, &dmabuf->dbuf);
-			continue;
-		}
-		/* Link this frame */
-		seq_dmabuf = lpfc_fc_frame_add(vport, dmabuf);
-		if (!seq_dmabuf) {
-			/* unable to add frame to vport - throw it out */
-			lpfc_in_buf_free(phba, &dmabuf->dbuf);
-			continue;
-		}
-		/* If not last frame in sequence continue processing frames. */
-		if (!lpfc_seq_complete(seq_dmabuf)) {
-			/*
-			 * When saving off frames post a new one and mark this
-			 * frame to be freed when it is finished.
-			 **/
-			lpfc_sli_hbqbuf_fill_hbqs(phba, LPFC_ELS_HBQ, 1);
-			dmabuf->tag = -1;
-			continue;
-		}
-		fc_hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt;
-		iocbq = lpfc_prep_seq(vport, seq_dmabuf);
-		if (!lpfc_complete_unsol_iocb(phba,
-					      &phba->sli.ring[LPFC_ELS_RING],
-					      iocbq, fc_hdr->fh_r_ctl,
-					      fc_hdr->fh_type))
-			lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
-					"2540 Ring %d handler: unexpected Rctl "
-					"x%x Type x%x received\n",
-					LPFC_ELS_RING,
-					fc_hdr->fh_r_ctl, fc_hdr->fh_type);
-	};
-	return 0;
+	fc_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt;
+	/* check to see if this a valid type of frame */
+	if (lpfc_fc_frame_check(phba, fc_hdr)) {
+		lpfc_in_buf_free(phba, &dmabuf->dbuf);
+		return;
+	}
+	fcfi = bf_get(lpfc_rcqe_fcf_id, &dmabuf->cq_event.cqe.rcqe_cmpl);
+	vport = lpfc_fc_frame_to_vport(phba, fc_hdr, fcfi);
+	if (!vport || !(vport->vpi_state & LPFC_VPI_REGISTERED)) {
+		/* throw out the frame */
+		lpfc_in_buf_free(phba, &dmabuf->dbuf);
+		return;
+	}
+	/* Handle the basic abort sequence (BA_ABTS) event */
+	if (fc_hdr->fh_r_ctl == FC_RCTL_BA_ABTS) {
+		lpfc_sli4_handle_unsol_abort(vport, dmabuf);
+		return;
+	}
+
+	/* Link this frame */
+	seq_dmabuf = lpfc_fc_frame_add(vport, dmabuf);
+	if (!seq_dmabuf) {
+		/* unable to add frame to vport - throw it out */
+		lpfc_in_buf_free(phba, &dmabuf->dbuf);
+		return;
+	}
+	/* If not last frame in sequence continue processing frames. */
+	if (!lpfc_seq_complete(seq_dmabuf)) {
+		/*
+		 * When saving off frames post a new one and mark this
+		 * frame to be freed when it is finished.
+		 **/
+		lpfc_sli_hbqbuf_fill_hbqs(phba, LPFC_ELS_HBQ, 1);
+		dmabuf->tag = -1;
+		return;
+	}
+	/* Send the complete sequence to the upper layer protocol */
+	lpfc_sli4_send_seq_to_ulp(vport, seq_dmabuf);
 }
 
 /**
@@ -11091,7 +11428,7 @@
  * sequential.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  *      EIO - The mailbox failed to complete successfully.
  * 	When this error occurs, the driver is not guaranteed
  *	to have any rpi regions posted to the device and
@@ -11129,7 +11466,7 @@
  * maps up to 64 rpi context regions.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	ENOMEM - No available memory
  *      EIO - The mailbox failed to complete successfully.
  **/
@@ -11191,7 +11528,7 @@
  * PAGE_SIZE modulo 64 rpi context headers.
  *
  * Returns
- * 	A nonzero rpi defined as rpi_base <= rpi < max_rpi if sucessful
+ * 	A nonzero rpi defined as rpi_base <= rpi < max_rpi if successful
  * 	LPFC_RPI_ALLOC_ERROR if no rpis are available.
  **/
 int
@@ -11334,6 +11671,7 @@
 {
 	LPFC_MBOXQ_t *mboxq;
 	int rc = 0;
+	int retval = MBX_SUCCESS;
 	uint32_t mbox_tmo;
 
 	if (vpi == 0)
@@ -11344,16 +11682,17 @@
 	lpfc_init_vpi(phba, mboxq, vpi);
 	mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_INIT_VPI);
 	rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo);
-	if (rc != MBX_TIMEOUT)
-		mempool_free(mboxq, phba->mbox_mem_pool);
 	if (rc != MBX_SUCCESS) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
 				"2022 INIT VPI Mailbox failed "
 				"status %d, mbxStatus x%x\n", rc,
 				bf_get(lpfc_mqe_status, &mboxq->u.mqe));
-		rc = -EIO;
+		retval = -EIO;
 	}
-	return rc;
+	if (rc != MBX_TIMEOUT)
+		mempool_free(mboxq, phba->mbox_mem_pool);
+
+	return retval;
 }
 
 /**
@@ -11438,13 +11777,6 @@
 	 */
 	lpfc_sli4_mbx_sge_get(mboxq, 0, &sge);
 	phys_addr = getPaddr(sge.pa_hi, sge.pa_lo);
-	if (unlikely(!mboxq->sge_array)) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
-				"2526 Failed to get the non-embedded SGE "
-				"virtual address\n");
-		lpfc_sli4_mbox_cmd_free(phba, mboxq);
-		return -ENOMEM;
-	}
 	virt_addr = mboxq->sge_array->addr[0];
 	/*
 	 * Configure the FCF record for FCFI 0.  This is the driver's
@@ -11542,7 +11874,8 @@
 		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 				"2000 Failed to allocate mbox for "
 				"READ_FCF cmd\n");
-		return -ENOMEM;
+		error = -ENOMEM;
+		goto fail_fcfscan;
 	}
 
 	req_len = sizeof(struct fcf_record) +
@@ -11558,8 +11891,8 @@
 				"0291 Allocated DMA memory size (x%x) is "
 				"less than the requested DMA memory "
 				"size (x%x)\n", alloc_len, req_len);
-		lpfc_sli4_mbox_cmd_free(phba, mboxq);
-		return -ENOMEM;
+		error = -ENOMEM;
+		goto fail_fcfscan;
 	}
 
 	/* Get the first SGE entry from the non-embedded DMA memory. This
@@ -11567,13 +11900,6 @@
 	 */
 	lpfc_sli4_mbx_sge_get(mboxq, 0, &sge);
 	phys_addr = getPaddr(sge.pa_hi, sge.pa_lo);
-	if (unlikely(!mboxq->sge_array)) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
-				"2527 Failed to get the non-embedded SGE "
-				"virtual address\n");
-		lpfc_sli4_mbox_cmd_free(phba, mboxq);
-		return -ENOMEM;
-	}
 	virt_addr = mboxq->sge_array->addr[0];
 	read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr;
 
@@ -11586,7 +11912,6 @@
 	mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_fcf_record;
 	rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
 	if (rc == MBX_NOT_FINISHED) {
-		lpfc_sli4_mbox_cmd_free(phba, mboxq);
 		error = -EIO;
 	} else {
 		spin_lock_irq(&phba->hbalock);
@@ -11594,6 +11919,15 @@
 		spin_unlock_irq(&phba->hbalock);
 		error = 0;
 	}
+fail_fcfscan:
+	if (error) {
+		if (mboxq)
+			lpfc_sli4_mbox_cmd_free(phba, mboxq);
+		/* FCF scan failed, clear FCF_DISC_INPROGRESS flag */
+		spin_lock_irq(&phba->hbalock);
+		phba->hba_flag &= ~FCF_DISC_INPROGRESS;
+		spin_unlock_irq(&phba->hbalock);
+	}
 	return error;
 }
 
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
index 3c53316..ba38de3 100644
--- a/drivers/scsi/lpfc/lpfc_sli.h
+++ b/drivers/scsi/lpfc/lpfc_sli.h
@@ -29,14 +29,17 @@
 	LPFC_CTX_HOST
 } lpfc_ctx_cmd;
 
-/* This structure is used to carry the needed response IOCB states */
-struct lpfc_sli4_rspiocb_info {
-	uint8_t hw_status;
-	uint8_t bfield;
-#define LPFC_XB	0x1
-#define LPFC_PV	0x2
-	uint8_t priority;
-	uint8_t reserved;
+struct lpfc_cq_event {
+	struct list_head list;
+	union {
+		struct lpfc_mcqe		mcqe_cmpl;
+		struct lpfc_acqe_link		acqe_link;
+		struct lpfc_acqe_fcoe		acqe_fcoe;
+		struct lpfc_acqe_dcbx		acqe_dcbx;
+		struct lpfc_rcqe		rcqe_cmpl;
+		struct sli4_wcqe_xri_aborted	wcqe_axri;
+		struct lpfc_wcqe_complete	wcqe_cmpl;
+	} cqe;
 };
 
 /* This structure is used to handle IOCB requests / responses */
@@ -46,6 +49,7 @@
 	struct list_head clist;
 	uint16_t iotag;         /* pre-assigned IO tag */
 	uint16_t sli4_xritag;   /* pre-assigned XRI, (OXID) tag. */
+	struct lpfc_cq_event cq_event;
 
 	IOCB_t iocb;		/* IOCB cmd */
 	uint8_t retry;		/* retry counter for IOCB cmd - if needed */
@@ -56,11 +60,13 @@
 #define LPFC_DRIVER_ABORTED	8	/* driver aborted this request */
 #define LPFC_IO_FABRIC		0x10	/* Iocb send using fabric scheduler */
 #define LPFC_DELAY_MEM_FREE	0x20    /* Defer free'ing of FC data */
-#define LPFC_FIP_ELS		0x40
+#define LPFC_FIP_ELS_ID_MASK	0xc0	/* ELS_ID range 0-3 */
+#define LPFC_FIP_ELS_ID_SHIFT	6
 
 	uint8_t abort_count;
 	uint8_t rsvd2;
 	uint32_t drvrTimeout;	/* driver timeout in seconds */
+	uint32_t fcp_wqidx;	/* index to FCP work queue */
 	struct lpfc_vport *vport;/* virtual port pointer */
 	void *context1;		/* caller context information */
 	void *context2;		/* caller context information */
@@ -76,7 +82,6 @@
 			   struct lpfc_iocbq *);
 	void (*iocb_cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
 			   struct lpfc_iocbq *);
-	struct lpfc_sli4_rspiocb_info sli4_info;
 };
 
 #define SLI_IOCB_RET_IOCB      1	/* Return IOCB if cmd ring full */
@@ -110,7 +115,7 @@
 				   return */
 #define MBX_NOWAIT      2	/* issue command then return immediately */
 
-#define LPFC_MAX_RING_MASK  4	/* max num of rctl/type masks allowed per
+#define LPFC_MAX_RING_MASK  5	/* max num of rctl/type masks allowed per
 				   ring */
 #define LPFC_MAX_RING       4	/* max num of SLI rings used by driver */
 
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
index b5f4ba1..25d66d0 100644
--- a/drivers/scsi/lpfc/lpfc_sli4.h
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
@@ -58,6 +58,16 @@
 #define LPFC_FCOE_FKA_ADV_PER	0
 #define LPFC_FCOE_FIP_PRIORITY	0x80
 
+#define sli4_sid_from_fc_hdr(fc_hdr)  \
+	((fc_hdr)->fh_s_id[0] << 16 | \
+	 (fc_hdr)->fh_s_id[1] <<  8 | \
+	 (fc_hdr)->fh_s_id[2])
+
+#define sli4_fctl_from_fc_hdr(fc_hdr)  \
+	((fc_hdr)->fh_f_ctl[0] << 16 | \
+	 (fc_hdr)->fh_f_ctl[1] <<  8 | \
+	 (fc_hdr)->fh_f_ctl[2])
+
 enum lpfc_sli4_queue_type {
 	LPFC_EQ,
 	LPFC_GCQ,
@@ -110,18 +120,6 @@
 	union sli4_qe qe[1];	/* array to index entries (must be last) */
 };
 
-struct lpfc_cq_event {
-	struct list_head list;
-	union {
-		struct lpfc_mcqe		mcqe_cmpl;
-		struct lpfc_acqe_link		acqe_link;
-		struct lpfc_acqe_fcoe		acqe_fcoe;
-		struct lpfc_acqe_dcbx		acqe_dcbx;
-		struct lpfc_rcqe		rcqe_cmpl;
-		struct sli4_wcqe_xri_aborted	wcqe_axri;
-	} cqe;
-};
-
 struct lpfc_sli4_link {
 	uint8_t speed;
 	uint8_t duplex;
@@ -166,7 +164,7 @@
 #define	lpfc_fip_param_hdr_fipp_mode_SHIFT	6
 #define	lpfc_fip_param_hdr_fipp_mode_MASK	0x3
 #define lpfc_fip_param_hdr_fipp_mode_WORD	parm_flags
-#define	FIPP_MODE_ON				0x2
+#define	FIPP_MODE_ON				0x1
 #define	FIPP_MODE_OFF				0x0
 #define FIPP_VLAN_VALID				0x1
 };
@@ -295,9 +293,8 @@
 	/* BAR0 PCI config space register memory map */
 	void __iomem *UERRLOregaddr; /* Address to UERR_STATUS_LO register */
 	void __iomem *UERRHIregaddr; /* Address to UERR_STATUS_HI register */
-	void __iomem *ONLINE0regaddr; /* Address to components of internal UE */
-	void __iomem *ONLINE1regaddr; /* Address to components of internal UE */
-#define LPFC_ONLINE_NERR	0xFFFFFFFF
+	void __iomem *UEMASKLOregaddr; /* Address to UE_MASK_LO register */
+	void __iomem *UEMASKHIregaddr; /* Address to UE_MASK_HI register */
 	void __iomem *SCRATCHPADregaddr; /* Address to scratchpad register */
 	/* BAR1 FCoE function CSR register memory map */
 	void __iomem *STAregaddr;    /* Address to HST_STATE register */
@@ -311,6 +308,8 @@
 	void __iomem *MQDBregaddr;   /* Address to MQ_DOORBELL register */
 	void __iomem *BMBXregaddr;   /* Address to BootStrap MBX register */
 
+	uint32_t ue_mask_lo;
+	uint32_t ue_mask_hi;
 	struct msix_entry *msix_entries;
 	uint32_t cfg_eqn;
 	struct lpfc_fcp_eq_hdl *fcp_eq_hdl; /* FCP per-WQ handle */
@@ -325,7 +324,6 @@
 	struct lpfc_queue **fcp_cq;/* Fast-path FCP compl queue */
 	struct lpfc_queue *mbx_cq; /* Slow-path mailbox complete queue */
 	struct lpfc_queue *els_cq; /* Slow-path ELS response complete queue */
-	struct lpfc_queue *rxq_cq; /* Slow-path unsolicited complete queue */
 
 	/* Setup information for various queue parameters */
 	int eq_esize;
@@ -360,7 +358,7 @@
 	unsigned long *rpi_bmask;
 	uint16_t rpi_count;
 	struct lpfc_sli4_flags sli4_flags;
-	struct list_head sp_rspiocb_work_queue;
+	struct list_head sp_queue_event;
 	struct list_head sp_cqe_event_pool;
 	struct list_head sp_asynce_work_queue;
 	struct list_head sp_fcp_xri_aborted_work_queue;
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index 9ae20af..c7f3aed 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -18,8 +18,7 @@
  * included with this package.                                     *
  *******************************************************************/
 
-#define LPFC_DRIVER_VERSION "8.3.4"
-
+#define LPFC_DRIVER_VERSION "8.3.6"
 #define LPFC_DRIVER_NAME		"lpfc"
 #define LPFC_SP_DRIVER_HANDLER_NAME	"lpfc:sp"
 #define LPFC_FP_DRIVER_HANDLER_NAME	"lpfc:fp"
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c
index 606efa7..7d6dd83 100644
--- a/drivers/scsi/lpfc/lpfc_vport.c
+++ b/drivers/scsi/lpfc/lpfc_vport.c
@@ -389,7 +389,7 @@
 	 * by the port.
 	 */
 	if ((phba->sli_rev == LPFC_SLI_REV4) &&
-		(pport->vfi_state & LPFC_VFI_REGISTERED)) {
+	    (pport->vpi_state & LPFC_VPI_REGISTERED)) {
 		rc = lpfc_sli4_init_vpi(phba, vpi);
 		if (rc) {
 			lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
@@ -700,6 +700,8 @@
 			}
 			spin_unlock_irq(&phba->ndlp_lock);
 		}
+		if (vport->vpi_state != LPFC_VPI_REGISTERED)
+			goto skip_logo;
 		vport->unreg_vpi_cmpl = VPORT_INVAL;
 		timeout = msecs_to_jiffies(phba->fc_ratov * 2000);
 		if (!lpfc_issue_els_npiv_logo(vport, ndlp))
diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h
index 512c2cc..d310f49 100644
--- a/drivers/scsi/megaraid.h
+++ b/drivers/scsi/megaraid.h
@@ -381,7 +381,7 @@
 	u8	battery_status;	/*
 				 * BIT 0: battery module missing
 				 * BIT 1: VBAD
-				 * BIT 2: temprature high
+				 * BIT 2: temperature high
 				 * BIT 3: battery pack missing
 				 * BIT 4,5:
 				 *   00 - charge complete
diff --git a/drivers/scsi/megaraid/mbox_defs.h b/drivers/scsi/megaraid/mbox_defs.h
index b25b747..ce2487a 100644
--- a/drivers/scsi/megaraid/mbox_defs.h
+++ b/drivers/scsi/megaraid/mbox_defs.h
@@ -497,7 +497,7 @@
  * @inserted_drive		: channel:Id of inserted drive
  * @battery_status		: bit 0: battery module missing
  *				bit 1: VBAD
- *				bit 2: temprature high
+ *				bit 2: temperature high
  *				bit 3: battery pack missing
  *				bit 4,5:
  *					00 - charge complete
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index 234f0b7..7f97796 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -335,12 +335,17 @@
  * megaraid_change_queue_depth - Change the device's queue depth
  * @sdev:	scsi device struct
  * @qdepth:	depth to set
+ * @reason:	calling context
  *
  * Return value:
  * 	actual depth set
  */
-static int megaraid_change_queue_depth(struct scsi_device *sdev, int qdepth)
+static int megaraid_change_queue_depth(struct scsi_device *sdev, int qdepth,
+				       int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (qdepth > MBOX_MAX_SCSI_CMDS)
 		qdepth = MBOX_MAX_SCSI_CMDS;
 	scsi_adjust_queue_depth(sdev, 0, qdepth);
@@ -2704,7 +2709,7 @@
 	}
 	else {
 		con_log(CL_ANN, (KERN_NOTICE
-		"megaraid mbox: reset sequence completed sucessfully\n"));
+		"megaraid mbox: reset sequence completed successfully\n"));
 	}
 
 
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index a39addc..134c63e 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -10,7 +10,7 @@
  *	   2 of the License, or (at your option) any later version.
  *
  * FILE		: megaraid_sas.c
- * Version     : v00.00.04.01-rc1
+ * Version     : v00.00.04.12-rc1
  *
  * Authors:
  *	(email-id : megaraidlinux@lsi.com)
@@ -40,6 +40,7 @@
 #include <linux/compat.h>
 #include <linux/blkdev.h>
 #include <linux/mutex.h>
+#include <linux/poll.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
@@ -75,6 +76,10 @@
 	/* gen2*/
 	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0079GEN2)},
 	/* gen2*/
+	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0073SKINNY)},
+	/* skinny*/
+	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0071SKINNY)},
+	/* skinny*/
 	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)},
 	/* xscale IOP, vega */
 	{PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)},
@@ -89,8 +94,14 @@
 static struct fasync_struct *megasas_async_queue;
 static DEFINE_MUTEX(megasas_async_queue_mutex);
 
+static int megasas_poll_wait_aen;
+static DECLARE_WAIT_QUEUE_HEAD(megasas_poll_wait);
+static u32 support_poll_for_event;
 static u32 megasas_dbg_lvl;
 
+/* define lock for aen poll */
+spinlock_t poll_aen_lock;
+
 static void
 megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
 		     u8 alt_status);
@@ -215,7 +226,10 @@
  * @regs :			MFI register set
  */
 static inline void 
-megasas_fire_cmd_xscale(dma_addr_t frame_phys_addr,u32 frame_count, struct megasas_register_set __iomem *regs)
+megasas_fire_cmd_xscale(struct megasas_instance *instance,
+		dma_addr_t frame_phys_addr,
+		u32 frame_count,
+		struct megasas_register_set __iomem *regs)
 {
 	writel((frame_phys_addr >> 3)|(frame_count),
 	       &(regs)->inbound_queue_port);
@@ -312,7 +326,10 @@
  * @regs :			MFI register set
  */
 static inline void 
-megasas_fire_cmd_ppc(dma_addr_t frame_phys_addr, u32 frame_count, struct megasas_register_set __iomem *regs)
+megasas_fire_cmd_ppc(struct megasas_instance *instance,
+		dma_addr_t frame_phys_addr,
+		u32 frame_count,
+		struct megasas_register_set __iomem *regs)
 {
 	writel((frame_phys_addr | (frame_count<<1))|1, 
 			&(regs)->inbound_queue_port);
@@ -328,6 +345,104 @@
 };
 
 /**
+ * megasas_enable_intr_skinny -	Enables interrupts
+ * @regs:			MFI register set
+ */
+static inline void
+megasas_enable_intr_skinny(struct megasas_register_set __iomem *regs)
+{
+	writel(0xFFFFFFFF, &(regs)->outbound_intr_mask);
+
+	writel(~MFI_SKINNY_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
+
+	/* Dummy readl to force pci flush */
+	readl(&regs->outbound_intr_mask);
+}
+
+/**
+ * megasas_disable_intr_skinny -	Disables interrupt
+ * @regs:			MFI register set
+ */
+static inline void
+megasas_disable_intr_skinny(struct megasas_register_set __iomem *regs)
+{
+	u32 mask = 0xFFFFFFFF;
+	writel(mask, &regs->outbound_intr_mask);
+	/* Dummy readl to force pci flush */
+	readl(&regs->outbound_intr_mask);
+}
+
+/**
+ * megasas_read_fw_status_reg_skinny - returns the current FW status value
+ * @regs:			MFI register set
+ */
+static u32
+megasas_read_fw_status_reg_skinny(struct megasas_register_set __iomem *regs)
+{
+	return readl(&(regs)->outbound_scratch_pad);
+}
+
+/**
+ * megasas_clear_interrupt_skinny -	Check & clear interrupt
+ * @regs:				MFI register set
+ */
+static int
+megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs)
+{
+	u32 status;
+	/*
+	 * Check if it is our interrupt
+	 */
+	status = readl(&regs->outbound_intr_status);
+
+	if (!(status & MFI_SKINNY_ENABLE_INTERRUPT_MASK)) {
+		return 1;
+	}
+
+	/*
+	 * Clear the interrupt by writing back the same value
+	 */
+	writel(status, &regs->outbound_intr_status);
+
+	/*
+	* dummy read to flush PCI
+	*/
+	readl(&regs->outbound_intr_status);
+
+	return 0;
+}
+
+/**
+ * megasas_fire_cmd_skinny -	Sends command to the FW
+ * @frame_phys_addr :		Physical address of cmd
+ * @frame_count :		Number of frames for the command
+ * @regs :			MFI register set
+ */
+static inline void
+megasas_fire_cmd_skinny(struct megasas_instance *instance,
+			dma_addr_t frame_phys_addr,
+			u32 frame_count,
+			struct megasas_register_set __iomem *regs)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&instance->fire_lock, flags);
+	writel(0, &(regs)->inbound_high_queue_port);
+	writel((frame_phys_addr | (frame_count<<1))|1,
+		&(regs)->inbound_low_queue_port);
+	spin_unlock_irqrestore(&instance->fire_lock, flags);
+}
+
+static struct megasas_instance_template megasas_instance_template_skinny = {
+
+	.fire_cmd = megasas_fire_cmd_skinny,
+	.enable_intr = megasas_enable_intr_skinny,
+	.disable_intr = megasas_disable_intr_skinny,
+	.clear_intr = megasas_clear_intr_skinny,
+	.read_fw_status_reg = megasas_read_fw_status_reg_skinny,
+};
+
+
+/**
 *	The following functions are defined for gen2 (deviceid : 0x78 0x79)
 *	controllers
 */
@@ -404,7 +519,9 @@
  * @regs :                     MFI register set
  */
 static inline void
-megasas_fire_cmd_gen2(dma_addr_t frame_phys_addr, u32 frame_count,
+megasas_fire_cmd_gen2(struct megasas_instance *instance,
+			dma_addr_t frame_phys_addr,
+			u32 frame_count,
 			struct megasas_register_set __iomem *regs)
 {
 	writel((frame_phys_addr | (frame_count<<1))|1,
@@ -446,7 +563,8 @@
 	/*
 	 * Issue the frame using inbound queue port
 	 */
-	instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
+	instance->instancet->fire_cmd(instance,
+			cmd->frame_phys_addr, 0, instance->reg_set);
 
 	/*
 	 * Wait for cmd_status to change
@@ -477,7 +595,8 @@
 {
 	cmd->cmd_status = ENODATA;
 
-	instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
+	instance->instancet->fire_cmd(instance,
+			cmd->frame_phys_addr, 0, instance->reg_set);
 
 	wait_event_timeout(instance->int_cmd_wait_q, (cmd->cmd_status != ENODATA),
 		MEGASAS_INTERNAL_CMD_WAIT_TIME*HZ);
@@ -522,7 +641,8 @@
 	cmd->sync_cmd = 1;
 	cmd->cmd_status = 0xFF;
 
-	instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
+	instance->instancet->fire_cmd(instance,
+			cmd->frame_phys_addr, 0, instance->reg_set);
 
 	/*
 	 * Wait for this cmd to complete
@@ -592,6 +712,35 @@
 	return sge_count;
 }
 
+/**
+ * megasas_make_sgl_skinny - Prepares IEEE SGL
+ * @instance:           Adapter soft state
+ * @scp:                SCSI command from the mid-layer
+ * @mfi_sgl:            SGL to be filled in
+ *
+ * If successful, this function returns the number of SG elements. Otherwise,
+ * it returnes -1.
+ */
+static int
+megasas_make_sgl_skinny(struct megasas_instance *instance,
+		struct scsi_cmnd *scp, union megasas_sgl *mfi_sgl)
+{
+	int i;
+	int sge_count;
+	struct scatterlist *os_sgl;
+
+	sge_count = scsi_dma_map(scp);
+
+	if (sge_count) {
+		scsi_for_each_sg(scp, os_sgl, sge_count, i) {
+			mfi_sgl->sge_skinny[i].length = sg_dma_len(os_sgl);
+			mfi_sgl->sge_skinny[i].phys_addr =
+						sg_dma_address(os_sgl);
+		}
+	}
+	return sge_count;
+}
+
  /**
  * megasas_get_frame_count - Computes the number of frames
  * @frame_type		: type of frame- io or pthru frame
@@ -600,7 +749,8 @@
  * Returns the number of frames required for numnber of sge's (sge_count)
  */
 
-static u32 megasas_get_frame_count(u8 sge_count, u8 frame_type)
+static u32 megasas_get_frame_count(struct megasas_instance *instance,
+			u8 sge_count, u8 frame_type)
 {
 	int num_cnt;
 	int sge_bytes;
@@ -610,6 +760,10 @@
 	sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
 	    sizeof(struct megasas_sge32);
 
+	if (instance->flag_ieee) {
+		sge_sz = sizeof(struct megasas_sge_skinny);
+	}
+
 	/*
 	 * Main frame can contain 2 SGEs for 64-bit SGLs and
 	 * 3 SGEs for 32-bit SGLs for ldio &
@@ -617,12 +771,16 @@
 	 * 2 SGEs for 32-bit SGLs for pthru frame
 	 */
 	if (unlikely(frame_type == PTHRU_FRAME)) {
-		if (IS_DMA64)
+		if (instance->flag_ieee == 1) {
+			num_cnt = sge_count - 1;
+		} else if (IS_DMA64)
 			num_cnt = sge_count - 1;
 		else
 			num_cnt = sge_count - 2;
 	} else {
-		if (IS_DMA64)
+		if (instance->flag_ieee == 1) {
+			num_cnt = sge_count - 1;
+		} else if (IS_DMA64)
 			num_cnt = sge_count - 2;
 		else
 			num_cnt = sge_count - 3;
@@ -671,6 +829,10 @@
 	else if (scp->sc_data_direction == PCI_DMA_NONE)
 		flags = MFI_FRAME_DIR_NONE;
 
+	if (instance->flag_ieee == 1) {
+		flags |= MFI_FRAME_IEEE;
+	}
+
 	/*
 	 * Prepare the DCDB frame
 	 */
@@ -687,9 +849,24 @@
 	memcpy(pthru->cdb, scp->cmnd, scp->cmd_len);
 
 	/*
+	* If the command is for the tape device, set the
+	* pthru timeout to the os layer timeout value.
+	*/
+	if (scp->device->type == TYPE_TAPE) {
+		if ((scp->request->timeout / HZ) > 0xFFFF)
+			pthru->timeout = 0xFFFF;
+		else
+			pthru->timeout = scp->request->timeout / HZ;
+	}
+
+	/*
 	 * Construct SGL
 	 */
-	if (IS_DMA64) {
+	if (instance->flag_ieee == 1) {
+		pthru->flags |= MFI_FRAME_SGL64;
+		pthru->sge_count = megasas_make_sgl_skinny(instance, scp,
+						      &pthru->sgl);
+	} else if (IS_DMA64) {
 		pthru->flags |= MFI_FRAME_SGL64;
 		pthru->sge_count = megasas_make_sgl64(instance, scp,
 						      &pthru->sgl);
@@ -708,7 +885,7 @@
 	 * Compute the total number of frames this command consumes. FW uses
 	 * this number to pull sufficient number of frames from host memory.
 	 */
-	cmd->frame_count = megasas_get_frame_count(pthru->sge_count,
+	cmd->frame_count = megasas_get_frame_count(instance, pthru->sge_count,
 							PTHRU_FRAME);
 
 	return cmd->frame_count;
@@ -739,6 +916,10 @@
 	else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
 		flags = MFI_FRAME_DIR_READ;
 
+	if (instance->flag_ieee == 1) {
+		flags |= MFI_FRAME_IEEE;
+	}
+
 	/*
 	 * Prepare the Logical IO frame: 2nd bit is zero for all read cmds
 	 */
@@ -809,7 +990,11 @@
 	/*
 	 * Construct SGL
 	 */
-	if (IS_DMA64) {
+	if (instance->flag_ieee) {
+		ldio->flags |= MFI_FRAME_SGL64;
+		ldio->sge_count = megasas_make_sgl_skinny(instance, scp,
+					      &ldio->sgl);
+	} else if (IS_DMA64) {
 		ldio->flags |= MFI_FRAME_SGL64;
 		ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl);
 	} else
@@ -826,7 +1011,8 @@
 	 * Compute the total number of frames this command consumes. FW uses
 	 * this number to pull sufficient number of frames from host memory.
 	 */
-	cmd->frame_count = megasas_get_frame_count(ldio->sge_count, IO_FRAME);
+	cmd->frame_count = megasas_get_frame_count(instance,
+			ldio->sge_count, IO_FRAME);
 
 	return cmd->frame_count;
 }
@@ -983,7 +1169,8 @@
 	 */
 	atomic_inc(&instance->fw_outstanding);
 
-	instance->instancet->fire_cmd(cmd->frame_phys_addr ,cmd->frame_count-1,instance->reg_set);
+	instance->instancet->fire_cmd(instance, cmd->frame_phys_addr,
+				cmd->frame_count-1, instance->reg_set);
 	/*
 	 * Check if we have pend cmds to be completed
 	 */
@@ -1000,24 +1187,76 @@
 	return 0;
 }
 
+static struct megasas_instance *megasas_lookup_instance(u16 host_no)
+{
+	int i;
+
+	for (i = 0; i < megasas_mgmt_info.max_index; i++) {
+
+		if ((megasas_mgmt_info.instance[i]) &&
+		    (megasas_mgmt_info.instance[i]->host->host_no == host_no))
+			return megasas_mgmt_info.instance[i];
+	}
+
+	return NULL;
+}
+
 static int megasas_slave_configure(struct scsi_device *sdev)
 {
-	/*
-	 * Don't export physical disk devices to the disk driver.
-	 *
-	 * FIXME: Currently we don't export them to the midlayer at all.
-	 * 	  That will be fixed once LSI engineers have audited the
-	 * 	  firmware for possible issues.
-	 */
-	if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && sdev->type == TYPE_DISK)
-		return -ENXIO;
+	u16             pd_index = 0;
+	struct  megasas_instance *instance ;
+
+	instance = megasas_lookup_instance(sdev->host->host_no);
 
 	/*
-	 * The RAID firmware may require extended timeouts.
-	 */
-	if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS)
-		blk_queue_rq_timeout(sdev->request_queue,
-				     MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
+	* Don't export physical disk devices to the disk driver.
+	*
+	* FIXME: Currently we don't export them to the midlayer at all.
+	*        That will be fixed once LSI engineers have audited the
+	*        firmware for possible issues.
+	*/
+	if (sdev->channel < MEGASAS_MAX_PD_CHANNELS &&
+				sdev->type == TYPE_DISK) {
+		pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
+								sdev->id;
+		if (instance->pd_list[pd_index].driveState ==
+						MR_PD_STATE_SYSTEM) {
+			blk_queue_rq_timeout(sdev->request_queue,
+				MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
+			return 0;
+		}
+		return -ENXIO;
+	}
+
+	/*
+	* The RAID firmware may require extended timeouts.
+	*/
+	blk_queue_rq_timeout(sdev->request_queue,
+		MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
+	return 0;
+}
+
+static int megasas_slave_alloc(struct scsi_device *sdev)
+{
+	u16             pd_index = 0;
+	struct megasas_instance *instance ;
+	instance = megasas_lookup_instance(sdev->host->host_no);
+	if ((sdev->channel < MEGASAS_MAX_PD_CHANNELS) &&
+				(sdev->type == TYPE_DISK)) {
+		/*
+		 * Open the OS scan to the SYSTEM PD
+		 */
+		pd_index =
+			(sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
+			sdev->id;
+		if ((instance->pd_list[pd_index].driveState ==
+					MR_PD_STATE_SYSTEM) &&
+			(instance->pd_list[pd_index].driveType ==
+						TYPE_DISK)) {
+			return 0;
+		}
+		return -ENXIO;
+	}
 	return 0;
 }
 
@@ -1072,7 +1311,14 @@
 
 		spin_lock_irqsave(instance->host->host_lock, flags);
 		instance->flag &= ~MEGASAS_FW_BUSY;
-		instance->host->can_queue =
+		if ((instance->pdev->device ==
+			PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+			(instance->pdev->device ==
+			PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+			instance->host->can_queue =
+				instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
+		} else
+			instance->host->can_queue =
 				instance->max_fw_cmds - MEGASAS_INT_CMDS;
 
 		spin_unlock_irqrestore(instance->host->host_lock, flags);
@@ -1117,8 +1363,16 @@
 		* Send signal to FW to stop processing any pending cmds.
 		* The controller will be taken offline by the OS now.
 		*/
-		writel(MFI_STOP_ADP,
+		if ((instance->pdev->device ==
+			PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+			(instance->pdev->device ==
+			PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+			writel(MFI_STOP_ADP,
+				&instance->reg_set->reserved_0[0]);
+		} else {
+			writel(MFI_STOP_ADP,
 				&instance->reg_set->inbound_doorbell);
+		}
 		megasas_dump_pending_frames(instance);
 		instance->hw_crit_error = 1;
 		return FAILED;
@@ -1266,6 +1520,8 @@
 	return 0;
 }
 
+static void megasas_aen_polling(struct work_struct *work);
+
 /**
  * megasas_service_aen -	Processes an event notification
  * @instance:			Adapter soft state
@@ -1281,16 +1537,36 @@
 static void
 megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd)
 {
+	unsigned long flags;
 	/*
 	 * Don't signal app if it is just an aborted previously registered aen
 	 */
-	if (!cmd->abort_aen)
+	if ((!cmd->abort_aen) && (instance->unload == 0)) {
+		spin_lock_irqsave(&poll_aen_lock, flags);
+		megasas_poll_wait_aen = 1;
+		spin_unlock_irqrestore(&poll_aen_lock, flags);
+		wake_up(&megasas_poll_wait);
 		kill_fasync(&megasas_async_queue, SIGIO, POLL_IN);
+	}
 	else
 		cmd->abort_aen = 0;
 
 	instance->aen_cmd = NULL;
 	megasas_return_cmd(instance, cmd);
+
+	if (instance->unload == 0) {
+		struct megasas_aen_event *ev;
+		ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
+		if (!ev) {
+			printk(KERN_ERR "megasas_service_aen: out of memory\n");
+		} else {
+			ev->instance = instance;
+			instance->ev = ev;
+			INIT_WORK(&ev->hotplug_work, megasas_aen_polling);
+			schedule_delayed_work(
+				(struct delayed_work *)&ev->hotplug_work, 0);
+		}
+	}
 }
 
 /*
@@ -1302,6 +1578,7 @@
 	.name = "LSI SAS based MegaRAID driver",
 	.proc_name = "megaraid_sas",
 	.slave_configure = megasas_slave_configure,
+	.slave_alloc = megasas_slave_alloc,
 	.queuecommand = megasas_queue_command,
 	.eh_device_reset_handler = megasas_reset_device,
 	.eh_bus_reset_handler = megasas_reset_bus_host,
@@ -1370,6 +1647,7 @@
 {
 	int exception = 0;
 	struct megasas_header *hdr = &cmd->frame->hdr;
+	unsigned long flags;
 
 	if (cmd->scmd)
 		cmd->scmd->SCp.ptr = NULL;
@@ -1459,6 +1737,12 @@
 	case MFI_CMD_SMP:
 	case MFI_CMD_STP:
 	case MFI_CMD_DCMD:
+		if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET_INFO ||
+			cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET) {
+			spin_lock_irqsave(&poll_aen_lock, flags);
+			megasas_poll_wait_aen = 0;
+			spin_unlock_irqrestore(&poll_aen_lock, flags);
+		}
 
 		/*
 		 * See if got an event notification
@@ -1536,6 +1820,7 @@
 	u8 max_wait;
 	u32 fw_state;
 	u32 cur_state;
+	u32 abs_state, curr_abs_state;
 
 	fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
 
@@ -1545,6 +1830,9 @@
 
 	while (fw_state != MFI_STATE_READY) {
 
+		abs_state =
+		instance->instancet->read_fw_status_reg(instance->reg_set);
+
 		switch (fw_state) {
 
 		case MFI_STATE_FAULT:
@@ -1556,18 +1844,36 @@
 			/*
 			 * Set the CLR bit in inbound doorbell
 			 */
-			writel(MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
-				&instance->reg_set->inbound_doorbell);
+			if ((instance->pdev->device ==
+				PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+				(instance->pdev->device ==
+				PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
 
-			max_wait = 2;
+				writel(
+				  MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
+				  &instance->reg_set->reserved_0[0]);
+			} else {
+				writel(
+				    MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
+					&instance->reg_set->inbound_doorbell);
+			}
+
+			max_wait = MEGASAS_RESET_WAIT_TIME;
 			cur_state = MFI_STATE_WAIT_HANDSHAKE;
 			break;
 
 		case MFI_STATE_BOOT_MESSAGE_PENDING:
-			writel(MFI_INIT_HOTPLUG,
-				&instance->reg_set->inbound_doorbell);
+			if ((instance->pdev->device ==
+				PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+			(instance->pdev->device ==
+				PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+				writel(MFI_INIT_HOTPLUG,
+				&instance->reg_set->reserved_0[0]);
+			} else
+				writel(MFI_INIT_HOTPLUG,
+					&instance->reg_set->inbound_doorbell);
 
-			max_wait = 10;
+			max_wait = MEGASAS_RESET_WAIT_TIME;
 			cur_state = MFI_STATE_BOOT_MESSAGE_PENDING;
 			break;
 
@@ -1576,9 +1882,17 @@
 			 * Bring it to READY state; assuming max wait 10 secs
 			 */
 			instance->instancet->disable_intr(instance->reg_set);
-			writel(MFI_RESET_FLAGS, &instance->reg_set->inbound_doorbell);
+			if ((instance->pdev->device ==
+				PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+				(instance->pdev->device ==
+				PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+				writel(MFI_RESET_FLAGS,
+					&instance->reg_set->reserved_0[0]);
+			} else
+				writel(MFI_RESET_FLAGS,
+					&instance->reg_set->inbound_doorbell);
 
-			max_wait = 60;
+			max_wait = MEGASAS_RESET_WAIT_TIME;
 			cur_state = MFI_STATE_OPERATIONAL;
 			break;
 
@@ -1586,32 +1900,32 @@
 			/*
 			 * This state should not last for more than 2 seconds
 			 */
-			max_wait = 2;
+			max_wait = MEGASAS_RESET_WAIT_TIME;
 			cur_state = MFI_STATE_UNDEFINED;
 			break;
 
 		case MFI_STATE_BB_INIT:
-			max_wait = 2;
+			max_wait = MEGASAS_RESET_WAIT_TIME;
 			cur_state = MFI_STATE_BB_INIT;
 			break;
 
 		case MFI_STATE_FW_INIT:
-			max_wait = 20;
+			max_wait = MEGASAS_RESET_WAIT_TIME;
 			cur_state = MFI_STATE_FW_INIT;
 			break;
 
 		case MFI_STATE_FW_INIT_2:
-			max_wait = 20;
+			max_wait = MEGASAS_RESET_WAIT_TIME;
 			cur_state = MFI_STATE_FW_INIT_2;
 			break;
 
 		case MFI_STATE_DEVICE_SCAN:
-			max_wait = 20;
+			max_wait = MEGASAS_RESET_WAIT_TIME;
 			cur_state = MFI_STATE_DEVICE_SCAN;
 			break;
 
 		case MFI_STATE_FLUSH_CACHE:
-			max_wait = 20;
+			max_wait = MEGASAS_RESET_WAIT_TIME;
 			cur_state = MFI_STATE_FLUSH_CACHE;
 			break;
 
@@ -1627,8 +1941,10 @@
 		for (i = 0; i < (max_wait * 1000); i++) {
 			fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) &  
 					MFI_STATE_MASK ;
+		curr_abs_state =
+		instance->instancet->read_fw_status_reg(instance->reg_set);
 
-			if (fw_state == cur_state) {
+			if (abs_state == curr_abs_state) {
 				msleep(1);
 			} else
 				break;
@@ -1637,7 +1953,7 @@
 		/*
 		 * Return error if fw_state hasn't changed after max_wait
 		 */
-		if (fw_state == cur_state) {
+		if (curr_abs_state == abs_state) {
 			printk(KERN_DEBUG "FW state [%d] hasn't changed "
 			       "in %d secs\n", fw_state, max_wait);
 			return -ENODEV;
@@ -1715,6 +2031,10 @@
 	sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
 	    sizeof(struct megasas_sge32);
 
+	if (instance->flag_ieee) {
+		sge_sz = sizeof(struct megasas_sge_skinny);
+	}
+
 	/*
 	 * Calculated the number of 64byte frames required for SGL
 	 */
@@ -1777,6 +2097,7 @@
 		}
 
 		cmd->frame->io.context = cmd->index;
+		cmd->frame->io.pad_0 = 0;
 	}
 
 	return 0;
@@ -1882,6 +2203,97 @@
 	return 0;
 }
 
+/*
+ * megasas_get_pd_list_info -	Returns FW's pd_list structure
+ * @instance:				Adapter soft state
+ * @pd_list:				pd_list structure
+ *
+ * Issues an internal command (DCMD) to get the FW's controller PD
+ * list structure.  This information is mainly used to find out SYSTEM
+ * supported by the FW.
+ */
+static int
+megasas_get_pd_list(struct megasas_instance *instance)
+{
+	int ret = 0, pd_index = 0;
+	struct megasas_cmd *cmd;
+	struct megasas_dcmd_frame *dcmd;
+	struct MR_PD_LIST *ci;
+	struct MR_PD_ADDRESS *pd_addr;
+	dma_addr_t ci_h = 0;
+
+	cmd = megasas_get_cmd(instance);
+
+	if (!cmd) {
+		printk(KERN_DEBUG "megasas (get_pd_list): Failed to get cmd\n");
+		return -ENOMEM;
+	}
+
+	dcmd = &cmd->frame->dcmd;
+
+	ci = pci_alloc_consistent(instance->pdev,
+		  MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), &ci_h);
+
+	if (!ci) {
+		printk(KERN_DEBUG "Failed to alloc mem for pd_list\n");
+		megasas_return_cmd(instance, cmd);
+		return -ENOMEM;
+	}
+
+	memset(ci, 0, sizeof(*ci));
+	memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+
+	dcmd->mbox.b[0] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST;
+	dcmd->mbox.b[1] = 0;
+	dcmd->cmd = MFI_CMD_DCMD;
+	dcmd->cmd_status = 0xFF;
+	dcmd->sge_count = 1;
+	dcmd->flags = MFI_FRAME_DIR_READ;
+	dcmd->timeout = 0;
+	dcmd->data_xfer_len = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
+	dcmd->opcode = MR_DCMD_PD_LIST_QUERY;
+	dcmd->sgl.sge32[0].phys_addr = ci_h;
+	dcmd->sgl.sge32[0].length = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
+
+	if (!megasas_issue_polled(instance, cmd)) {
+		ret = 0;
+	} else {
+		ret = -1;
+	}
+
+	/*
+	* the following function will get the instance PD LIST.
+	*/
+
+	pd_addr = ci->addr;
+
+	if ( ret == 0 &&
+		(ci->count <
+		  (MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL))) {
+
+		memset(instance->pd_list, 0,
+			MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
+
+		for (pd_index = 0; pd_index < ci->count; pd_index++) {
+
+			instance->pd_list[pd_addr->deviceId].tid	=
+							pd_addr->deviceId;
+			instance->pd_list[pd_addr->deviceId].driveType	=
+							pd_addr->scsiDevType;
+			instance->pd_list[pd_addr->deviceId].driveState	=
+							MR_PD_STATE_SYSTEM;
+			pd_addr++;
+		}
+	}
+
+	pci_free_consistent(instance->pdev,
+				MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST),
+				ci, ci_h);
+	megasas_return_cmd(instance, cmd);
+
+	return ret;
+}
+
 /**
  * megasas_get_controller_info -	Returns FW's controller structure
  * @instance:				Adapter soft state
@@ -2081,6 +2493,8 @@
 	 * Map the message registers
 	 */
 	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1078GEN2) ||
+		(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
+		(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
 		(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0079GEN2)) {
 		instance->base_addr = pci_resource_start(instance->pdev, 1);
 	} else {
@@ -2111,6 +2525,10 @@
 		case PCI_DEVICE_ID_LSI_SAS0079GEN2:
 			instance->instancet = &megasas_instance_template_gen2;
 			break;
+		case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
+		case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
+			instance->instancet = &megasas_instance_template_skinny;
+			break;
 		case PCI_DEVICE_ID_LSI_SAS1064R:
 		case PCI_DEVICE_ID_DELL_PERC5:
 		default:
@@ -2166,6 +2584,10 @@
 	if (megasas_issue_init_mfi(instance))
 		goto fail_fw_init;
 
+	memset(instance->pd_list, 0 ,
+		(MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)));
+	megasas_get_pd_list(instance);
+
 	ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL);
 
 	/*
@@ -2409,6 +2831,11 @@
 	dcmd->sgl.sge32[0].phys_addr = (u32) instance->evt_detail_h;
 	dcmd->sgl.sge32[0].length = sizeof(struct megasas_evt_detail);
 
+	if (instance->aen_cmd != NULL) {
+		megasas_return_cmd(instance, cmd);
+		return 0;
+	}
+
 	/*
 	 * Store reference to the cmd used to register for AEN. When an
 	 * application wants us to register for AEN, we have to abort this
@@ -2419,7 +2846,8 @@
 	/*
 	 * Issue the aen registration frame
 	 */
-	instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
+	instance->instancet->fire_cmd(instance,
+			cmd->frame_phys_addr, 0, instance->reg_set);
 
 	return 0;
 }
@@ -2465,7 +2893,13 @@
 	 */
 	host->irq = instance->pdev->irq;
 	host->unique_id = instance->unique_id;
-	host->can_queue = instance->max_fw_cmds - MEGASAS_INT_CMDS;
+	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+		(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+		host->can_queue =
+			instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
+	} else
+		host->can_queue =
+			instance->max_fw_cmds - MEGASAS_INT_CMDS;
 	host->this_id = instance->init_id;
 	host->sg_tablesize = instance->max_num_sge;
 	host->max_sectors = instance->max_sectors_per_req;
@@ -2572,6 +3006,9 @@
 
 	*instance->producer = 0;
 	*instance->consumer = 0;
+	megasas_poll_wait_aen = 0;
+	instance->flag_ieee = 0;
+	instance->ev = NULL;
 
 	instance->evt_detail = pci_alloc_consistent(pdev,
 						    sizeof(struct
@@ -2595,10 +3032,11 @@
 	init_waitqueue_head(&instance->abort_cmd_wait_q);
 
 	spin_lock_init(&instance->cmd_pool_lock);
+	spin_lock_init(&instance->fire_lock);
 	spin_lock_init(&instance->completion_lock);
+	spin_lock_init(&poll_aen_lock);
 
 	mutex_init(&instance->aen_mutex);
-	sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
 
 	/*
 	 * Initialize PCI related and misc parameters
@@ -2608,8 +3046,16 @@
 	instance->unique_id = pdev->bus->number << 8 | pdev->devfn;
 	instance->init_id = MEGASAS_DEFAULT_INIT_ID;
 
+	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+		(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+		instance->flag_ieee = 1;
+		sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS);
+	} else
+		sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
+
 	megasas_dbg_lvl = 0;
 	instance->flag = 0;
+	instance->unload = 1;
 	instance->last_time = 0;
 
 	/*
@@ -2655,6 +3101,7 @@
 	if (megasas_io_attach(instance))
 		goto fail_io_attach;
 
+	instance->unload = 0;
 	return 0;
 
       fail_start_aen:
@@ -2778,12 +3225,23 @@
 
 	instance = pci_get_drvdata(pdev);
 	host = instance->host;
+	instance->unload = 1;
 
 	if (poll_mode_io)
 		del_timer_sync(&instance->io_completion_timer);
 
 	megasas_flush_cache(instance);
 	megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN);
+
+	/* cancel the delayed work if this work still in queue */
+	if (instance->ev != NULL) {
+		struct megasas_aen_event *ev = instance->ev;
+		cancel_delayed_work(
+			(struct delayed_work *)&ev->hotplug_work);
+		flush_scheduled_work();
+		instance->ev = NULL;
+	}
+
 	tasklet_kill(&instance->isr_tasklet);
 
 	pci_set_drvdata(instance->pdev, instance);
@@ -2873,6 +3331,8 @@
 		megasas_start_timer(instance, &instance->io_completion_timer,
 				megasas_io_completion_timer,
 				MEGASAS_COMPLETION_TIMER_INTERVAL);
+	instance->unload = 0;
+
 	return 0;
 
 fail_irq:
@@ -2913,6 +3373,7 @@
 	struct megasas_instance *instance;
 
 	instance = pci_get_drvdata(pdev);
+	instance->unload = 1;
 	host = instance->host;
 
 	if (poll_mode_io)
@@ -2921,6 +3382,16 @@
 	scsi_remove_host(instance->host);
 	megasas_flush_cache(instance);
 	megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
+
+	/* cancel the delayed work if this work still in queue*/
+	if (instance->ev != NULL) {
+		struct megasas_aen_event *ev = instance->ev;
+		cancel_delayed_work(
+			(struct delayed_work *)&ev->hotplug_work);
+		flush_scheduled_work();
+		instance->ev = NULL;
+	}
+
 	tasklet_kill(&instance->isr_tasklet);
 
 	/*
@@ -2969,6 +3440,7 @@
 static void megasas_shutdown(struct pci_dev *pdev)
 {
 	struct megasas_instance *instance = pci_get_drvdata(pdev);
+	instance->unload = 1;
 	megasas_flush_cache(instance);
 	megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
 }
@@ -3016,6 +3488,23 @@
 }
 
 /**
+ * megasas_mgmt_poll -  char node "poll" entry point
+ * */
+static unsigned int megasas_mgmt_poll(struct file *file, poll_table *wait)
+{
+	unsigned int mask;
+	unsigned long flags;
+	poll_wait(file, &megasas_poll_wait, wait);
+	spin_lock_irqsave(&poll_aen_lock, flags);
+	if (megasas_poll_wait_aen)
+		mask =   (POLLIN | POLLRDNORM);
+	else
+		mask = 0;
+	spin_unlock_irqrestore(&poll_aen_lock, flags);
+	return mask;
+}
+
+/**
  * megasas_mgmt_fw_ioctl -	Issues management ioctls to FW
  * @instance:			Adapter soft state
  * @argp:			User's ioctl packet
@@ -3032,7 +3521,7 @@
 	int error = 0, i;
 	void *sense = NULL;
 	dma_addr_t sense_handle;
-	u32 *sense_ptr;
+	unsigned long *sense_ptr;
 
 	memset(kbuff_arr, 0, sizeof(kbuff_arr));
 
@@ -3056,6 +3545,7 @@
 	 */
 	memcpy(cmd->frame, ioc->frame.raw, 2 * MEGAMFI_FRAME_SIZE);
 	cmd->frame->hdr.context = cmd->index;
+	cmd->frame->hdr.pad_0 = 0;
 
 	/*
 	 * The management interface between applications and the fw uses
@@ -3109,7 +3599,7 @@
 		}
 
 		sense_ptr =
-		    (u32 *) ((unsigned long)cmd->frame + ioc->sense_off);
+		(unsigned long *) ((unsigned long)cmd->frame + ioc->sense_off);
 		*sense_ptr = sense_handle;
 	}
 
@@ -3140,8 +3630,8 @@
 		 * sense_ptr points to the location that has the user
 		 * sense buffer address
 		 */
-		sense_ptr = (u32 *) ((unsigned long)ioc->frame.raw +
-				     ioc->sense_off);
+		sense_ptr = (unsigned long *) ((unsigned long)ioc->frame.raw +
+				ioc->sense_off);
 
 		if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)),
 				 sense, ioc->sense_len)) {
@@ -3177,20 +3667,6 @@
 	return error;
 }
 
-static struct megasas_instance *megasas_lookup_instance(u16 host_no)
-{
-	int i;
-
-	for (i = 0; i < megasas_mgmt_info.max_index; i++) {
-
-		if ((megasas_mgmt_info.instance[i]) &&
-		    (megasas_mgmt_info.instance[i]->host->host_no == host_no))
-			return megasas_mgmt_info.instance[i];
-	}
-
-	return NULL;
-}
-
 static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg)
 {
 	struct megasas_iocpacket __user *user_ioc =
@@ -3214,6 +3690,17 @@
 		goto out_kfree_ioc;
 	}
 
+	if (instance->hw_crit_error == 1) {
+		printk(KERN_DEBUG "Controller in Crit ERROR\n");
+		error = -ENODEV;
+		goto out_kfree_ioc;
+	}
+
+	if (instance->unload == 1) {
+		error = -ENODEV;
+		goto out_kfree_ioc;
+	}
+
 	/*
 	 * We will allow only MEGASAS_INT_CMDS number of parallel ioctl cmds
 	 */
@@ -3249,6 +3736,14 @@
 	if (!instance)
 		return -ENODEV;
 
+	if (instance->hw_crit_error == 1) {
+		error = -ENODEV;
+	}
+
+	if (instance->unload == 1) {
+		return -ENODEV;
+	}
+
 	mutex_lock(&instance->aen_mutex);
 	error = megasas_register_aen(instance, aen.seq_num,
 				     aen.class_locale_word);
@@ -3337,6 +3832,7 @@
 	.open = megasas_mgmt_open,
 	.fasync = megasas_mgmt_fasync,
 	.unlocked_ioctl = megasas_mgmt_ioctl,
+	.poll = megasas_mgmt_poll,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl = megasas_mgmt_compat_ioctl,
 #endif
@@ -3378,6 +3874,15 @@
 		   NULL);
 
 static ssize_t
+megasas_sysfs_show_support_poll_for_event(struct device_driver *dd, char *buf)
+{
+	return sprintf(buf, "%u\n", support_poll_for_event);
+}
+
+static DRIVER_ATTR(support_poll_for_event, S_IRUGO,
+			megasas_sysfs_show_support_poll_for_event, NULL);
+
+static ssize_t
 megasas_sysfs_show_dbg_lvl(struct device_driver *dd, char *buf)
 {
 	return sprintf(buf, "%u\n", megasas_dbg_lvl);
@@ -3451,6 +3956,92 @@
 	return retval;
 }
 
+static void
+megasas_aen_polling(struct work_struct *work)
+{
+	struct megasas_aen_event *ev =
+		container_of(work, struct megasas_aen_event, hotplug_work);
+	struct megasas_instance *instance = ev->instance;
+	union megasas_evt_class_locale class_locale;
+	struct  Scsi_Host *host;
+	struct  scsi_device *sdev1;
+	u16     pd_index = 0;
+	int     i, j, doscan = 0;
+	u32 seq_num;
+	int error;
+
+	if (!instance) {
+		printk(KERN_ERR "invalid instance!\n");
+		kfree(ev);
+		return;
+	}
+	instance->ev = NULL;
+	host = instance->host;
+	if (instance->evt_detail) {
+
+		switch (instance->evt_detail->code) {
+		case MR_EVT_PD_INSERTED:
+		case MR_EVT_PD_REMOVED:
+		case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED:
+			doscan = 1;
+			break;
+		default:
+			doscan = 0;
+			break;
+		}
+	} else {
+		printk(KERN_ERR "invalid evt_detail!\n");
+		kfree(ev);
+		return;
+	}
+
+	if (doscan) {
+		printk(KERN_INFO "scanning ...\n");
+		megasas_get_pd_list(instance);
+		for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
+			for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
+				pd_index = i*MEGASAS_MAX_DEV_PER_CHANNEL + j;
+				sdev1 = scsi_device_lookup(host, i, j, 0);
+				if (instance->pd_list[pd_index].driveState ==
+							MR_PD_STATE_SYSTEM) {
+					if (!sdev1) {
+						scsi_add_device(host, i, j, 0);
+					}
+					if (sdev1)
+						scsi_device_put(sdev1);
+				} else {
+					if (sdev1) {
+						scsi_remove_device(sdev1);
+						scsi_device_put(sdev1);
+					}
+				}
+			}
+		}
+	}
+
+	if ( instance->aen_cmd != NULL ) {
+		kfree(ev);
+		return ;
+	}
+
+	seq_num = instance->evt_detail->seq_num + 1;
+
+	/* Register AEN with FW for latest sequence number plus 1 */
+	class_locale.members.reserved = 0;
+	class_locale.members.locale = MR_EVT_LOCALE_ALL;
+	class_locale.members.class = MR_EVT_CLASS_DEBUG;
+	mutex_lock(&instance->aen_mutex);
+	error = megasas_register_aen(instance, seq_num,
+					class_locale.word);
+	mutex_unlock(&instance->aen_mutex);
+
+	if (error)
+		printk(KERN_ERR "register aen failed error %x\n", error);
+
+	kfree(ev);
+}
+
+
 static DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUGO,
 		megasas_sysfs_show_poll_mode_io,
 		megasas_sysfs_set_poll_mode_io);
@@ -3468,6 +4059,8 @@
 	printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION,
 	       MEGASAS_EXT_VERSION);
 
+	support_poll_for_event = 2;
+
 	memset(&megasas_mgmt_info, 0, sizeof(megasas_mgmt_info));
 
 	/*
@@ -3500,6 +4093,12 @@
 				  &driver_attr_release_date);
 	if (rval)
 		goto err_dcf_rel_date;
+
+	rval = driver_create_file(&megasas_pci_driver.driver,
+				&driver_attr_support_poll_for_event);
+	if (rval)
+		goto err_dcf_support_poll_for_event;
+
 	rval = driver_create_file(&megasas_pci_driver.driver,
 				  &driver_attr_dbg_lvl);
 	if (rval)
@@ -3516,7 +4115,12 @@
 			   &driver_attr_dbg_lvl);
 err_dcf_dbg_lvl:
 	driver_remove_file(&megasas_pci_driver.driver,
+			&driver_attr_support_poll_for_event);
+
+err_dcf_support_poll_for_event:
+	driver_remove_file(&megasas_pci_driver.driver,
 			   &driver_attr_release_date);
+
 err_dcf_rel_date:
 	driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
 err_dcf_attr_ver:
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 0d03324..72b28e4 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -18,9 +18,9 @@
 /*
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION				"00.00.04.01"
-#define MEGASAS_RELDATE				"July 24, 2008"
-#define MEGASAS_EXT_VERSION			"Thu July 24 11:41:51 PST 2008"
+#define MEGASAS_VERSION				"00.00.04.12-rc1"
+#define MEGASAS_RELDATE				"Sep. 17, 2009"
+#define MEGASAS_EXT_VERSION			"Thu Sep. 17 11:41:51 PST 2009"
 
 /*
  * Device IDs
@@ -30,6 +30,8 @@
 #define	PCI_DEVICE_ID_LSI_VERDE_ZCR		0x0413
 #define	PCI_DEVICE_ID_LSI_SAS1078GEN2		0x0078
 #define	PCI_DEVICE_ID_LSI_SAS0079GEN2		0x0079
+#define	PCI_DEVICE_ID_LSI_SAS0073SKINNY		0x0073
+#define	PCI_DEVICE_ID_LSI_SAS0071SKINNY		0x0071
 
 /*
  * =====================================
@@ -94,6 +96,7 @@
 #define MFI_FRAME_DIR_WRITE			0x0008
 #define MFI_FRAME_DIR_READ			0x0010
 #define MFI_FRAME_DIR_BOTH			0x0018
+#define MFI_FRAME_IEEE                          0x0020
 
 /*
  * Definition for cmd_status
@@ -131,6 +134,7 @@
 #define MR_DCMD_CLUSTER				0x08000000
 #define MR_DCMD_CLUSTER_RESET_ALL		0x08010100
 #define MR_DCMD_CLUSTER_RESET_LD		0x08010200
+#define MR_DCMD_PD_LIST_QUERY                   0x02010100
 
 /*
  * MFI command completion codes
@@ -251,10 +255,101 @@
 	MR_EVT_ARGS_STR,
 	MR_EVT_ARGS_TIME,
 	MR_EVT_ARGS_ECC,
-
+	MR_EVT_ARGS_LD_PROP,
+	MR_EVT_ARGS_PD_SPARE,
+	MR_EVT_ARGS_PD_INDEX,
+	MR_EVT_ARGS_DIAG_PASS,
+	MR_EVT_ARGS_DIAG_FAIL,
+	MR_EVT_ARGS_PD_LBA_LBA,
+	MR_EVT_ARGS_PORT_PHY,
+	MR_EVT_ARGS_PD_MISSING,
+	MR_EVT_ARGS_PD_ADDRESS,
+	MR_EVT_ARGS_BITMAP,
+	MR_EVT_ARGS_CONNECTOR,
+	MR_EVT_ARGS_PD_PD,
+	MR_EVT_ARGS_PD_FRU,
+	MR_EVT_ARGS_PD_PATHINFO,
+	MR_EVT_ARGS_PD_POWER_STATE,
+	MR_EVT_ARGS_GENERIC,
 };
 
 /*
+ * define constants for device list query options
+ */
+enum MR_PD_QUERY_TYPE {
+	MR_PD_QUERY_TYPE_ALL                = 0,
+	MR_PD_QUERY_TYPE_STATE              = 1,
+	MR_PD_QUERY_TYPE_POWER_STATE        = 2,
+	MR_PD_QUERY_TYPE_MEDIA_TYPE         = 3,
+	MR_PD_QUERY_TYPE_SPEED              = 4,
+	MR_PD_QUERY_TYPE_EXPOSED_TO_HOST    = 5,
+};
+
+#define MR_EVT_CFG_CLEARED                              0x0004
+#define MR_EVT_LD_STATE_CHANGE                          0x0051
+#define MR_EVT_PD_INSERTED                              0x005b
+#define MR_EVT_PD_REMOVED                               0x0070
+#define MR_EVT_LD_CREATED                               0x008a
+#define MR_EVT_LD_DELETED                               0x008b
+#define MR_EVT_FOREIGN_CFG_IMPORTED                     0x00db
+#define MR_EVT_LD_OFFLINE                               0x00fc
+#define MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED             0x0152
+#define MAX_LOGICAL_DRIVES				64
+
+enum MR_PD_STATE {
+	MR_PD_STATE_UNCONFIGURED_GOOD   = 0x00,
+	MR_PD_STATE_UNCONFIGURED_BAD    = 0x01,
+	MR_PD_STATE_HOT_SPARE           = 0x02,
+	MR_PD_STATE_OFFLINE             = 0x10,
+	MR_PD_STATE_FAILED              = 0x11,
+	MR_PD_STATE_REBUILD             = 0x14,
+	MR_PD_STATE_ONLINE              = 0x18,
+	MR_PD_STATE_COPYBACK            = 0x20,
+	MR_PD_STATE_SYSTEM              = 0x40,
+ };
+
+
+ /*
+ * defines the physical drive address structure
+ */
+struct MR_PD_ADDRESS {
+	u16     deviceId;
+	u16     enclDeviceId;
+
+	union {
+		struct {
+			u8  enclIndex;
+			u8  slotNumber;
+		} mrPdAddress;
+		struct {
+			u8  enclPosition;
+			u8  enclConnectorIndex;
+		} mrEnclAddress;
+	};
+	u8      scsiDevType;
+	union {
+		u8      connectedPortBitmap;
+		u8      connectedPortNumbers;
+	};
+	u64     sasAddr[2];
+} __packed;
+
+/*
+ * defines the physical drive list structure
+ */
+struct MR_PD_LIST {
+	u32             size;
+	u32             count;
+	struct MR_PD_ADDRESS   addr[1];
+} __packed;
+
+struct megasas_pd_list {
+	u16             tid;
+	u8             driveType;
+	u8             driveState;
+} __packed;
+
+/*
  * SAS controller properties
  */
 struct megasas_ctrl_prop {
@@ -282,7 +377,7 @@
 	u8 expose_encl_devices;
 	u8 reserved[38];
 
-} __attribute__ ((packed));
+} __packed;
 
 /*
  * SAS controller information
@@ -525,7 +620,7 @@
 
 	u8 pad[0x800 - 0x6a0];
 
-} __attribute__ ((packed));
+} __packed;
 
 /*
  * ===============================
@@ -540,6 +635,8 @@
 #define MEGASAS_DEFAULT_INIT_ID			-1
 #define MEGASAS_MAX_LUN				8
 #define MEGASAS_MAX_LD				64
+#define MEGASAS_MAX_PD                          (MEGASAS_MAX_PD_CHANNELS * \
+						MEGASAS_MAX_DEV_PER_CHANNEL)
 
 #define MEGASAS_DBG_LVL				1
 
@@ -570,6 +667,7 @@
  * is shown below
  */
 #define MEGASAS_INT_CMDS			32
+#define MEGASAS_SKINNY_INT_CMDS			5
 
 /*
  * FW can accept both 32 and 64 bit SGLs. We want to allocate 32/64 bit
@@ -584,6 +682,8 @@
 #define MFI_REPLY_1078_MESSAGE_INTERRUPT	0x80000000
 #define MFI_REPLY_GEN2_MESSAGE_INTERRUPT	0x00000001
 #define MFI_GEN2_ENABLE_INTERRUPT_MASK		(0x00000001 | 0x00000004)
+#define MFI_REPLY_SKINNY_MESSAGE_INTERRUPT	0x40000000
+#define MFI_SKINNY_ENABLE_INTERRUPT_MASK	(0x00000001)
 
 /*
 * register set for both 1068 and 1078 controllers
@@ -644,10 +744,17 @@
 
 } __attribute__ ((packed));
 
+struct megasas_sge_skinny {
+	u64 phys_addr;
+	u32 length;
+	u32 flag;
+} __packed;
+
 union megasas_sgl {
 
 	struct megasas_sge32 sge32[1];
 	struct megasas_sge64 sge64[1];
+	struct megasas_sge_skinny sge_skinny[1];
 
 } __attribute__ ((packed));
 
@@ -1061,16 +1168,10 @@
 
 } __attribute__ ((packed));
 
- struct megasas_instance_template {
-	void (*fire_cmd)(dma_addr_t ,u32 ,struct megasas_register_set __iomem *);
-
-	void (*enable_intr)(struct megasas_register_set __iomem *) ;
-	void (*disable_intr)(struct megasas_register_set __iomem *);
-
-	int (*clear_intr)(struct megasas_register_set __iomem *);
-
-	u32 (*read_fw_status_reg)(struct megasas_register_set __iomem *);
- };
+struct megasas_aen_event {
+	struct work_struct hotplug_work;
+	struct megasas_instance *instance;
+};
 
 struct megasas_instance {
 
@@ -1085,17 +1186,21 @@
 	unsigned long base_addr;
 	struct megasas_register_set __iomem *reg_set;
 
+	struct megasas_pd_list          pd_list[MEGASAS_MAX_PD];
 	s8 init_id;
 
 	u16 max_num_sge;
 	u16 max_fw_cmds;
 	u32 max_sectors_per_req;
+	struct megasas_aen_event *ev;
 
 	struct megasas_cmd **cmd_list;
 	struct list_head cmd_pool;
 	spinlock_t cmd_pool_lock;
 	/* used to synch producer, consumer ptrs in dpc */
 	spinlock_t completion_lock;
+	/* used to sync fire the cmd to fw */
+	spinlock_t fire_lock;
 	struct dma_pool *frame_dma_pool;
 	struct dma_pool *sense_dma_pool;
 
@@ -1120,11 +1225,25 @@
 	struct tasklet_struct isr_tasklet;
 
 	u8 flag;
+	u8 unload;
+	u8 flag_ieee;
 	unsigned long last_time;
 
 	struct timer_list io_completion_timer;
 };
 
+struct megasas_instance_template {
+	void (*fire_cmd)(struct megasas_instance *, dma_addr_t, \
+		u32, struct megasas_register_set __iomem *);
+
+	void (*enable_intr)(struct megasas_register_set __iomem *) ;
+	void (*disable_intr)(struct megasas_register_set __iomem *);
+
+	int (*clear_intr)(struct megasas_register_set __iomem *);
+
+	u32 (*read_fw_status_reg)(struct megasas_register_set __iomem *);
+};
+
 #define MEGASAS_IS_LOGICAL(scp)						\
 	(scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1
 
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2.h b/drivers/scsi/mpt2sas/mpi/mpi2.h
index f9f6c08..9141681 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2.h
@@ -8,7 +8,7 @@
  *                  scatter/gather formats.
  *  Creation Date:  June 21, 2006
  *
- *  mpi2.h Version:  02.00.12
+ *  mpi2.h Version:  02.00.13
  *
  *  Version History
  *  ---------------
@@ -52,6 +52,7 @@
  *                      MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR and made those
  *                      bytes reserved.
  *                      Added RAID Accelerator functionality.
+ *  07-30-09  02.00.13  Bumped MPI2_HEADER_VERSION_UNIT.
  *  --------------------------------------------------------------------------
  */
 
@@ -77,7 +78,7 @@
 #define MPI2_VERSION_02_00                  (0x0200)
 
 /* versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT            (0x0C)
+#define MPI2_HEADER_VERSION_UNIT            (0x0D)
 #define MPI2_HEADER_VERSION_DEV             (0x00)
 #define MPI2_HEADER_VERSION_UNIT_MASK       (0xFF00)
 #define MPI2_HEADER_VERSION_UNIT_SHIFT      (8)
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
index ab47c46..1611c57 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
@@ -6,7 +6,7 @@
  *          Title:  MPI Configuration messages and pages
  *  Creation Date:  November 10, 2006
  *
- *    mpi2_cnfg.h Version:  02.00.11
+ *    mpi2_cnfg.h Version:  02.00.12
  *
  *  Version History
  *  ---------------
@@ -100,6 +100,13 @@
  *                      Added expander reduced functionality data to SAS
  *                      Expander Page 0.
  *                      Added SAS PHY Page 2 and SAS PHY Page 3.
+ *  07-30-09  02.00.12  Added IO Unit Page 7.
+ *                      Added new device ids.
+ *                      Added SAS IO Unit Page 5.
+ *                      Added partial and slumber power management capable flags
+ *                      to SAS Device Page 0 Flags field.
+ *                      Added PhyInfo defines for power condition.
+ *                      Added Ethernet configuration pages.
  *  --------------------------------------------------------------------------
  */
 
@@ -182,6 +189,7 @@
 #define MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG         (0x16)
 #define MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING      (0x17)
 #define MPI2_CONFIG_EXTPAGETYPE_SAS_PORT            (0x18)
+#define MPI2_CONFIG_EXTPAGETYPE_ETHERNET            (0x19)
 
 
 /*****************************************************************************
@@ -268,6 +276,14 @@
 #define MPI2_DPM_PGAD_START_ENTRY_MASK              (0x0000FFFF)
 
 
+/* Ethernet PageAddress format */
+#define MPI2_ETHERNET_PGAD_FORM_MASK                (0xF0000000)
+#define MPI2_ETHERNET_PGAD_FORM_IF_NUM              (0x00000000)
+
+#define MPI2_ETHERNET_PGAD_IF_NUMBER_MASK           (0x000000FF)
+
+
+
 /****************************************************************************
 *   Configuration messages
 ****************************************************************************/
@@ -349,6 +365,15 @@
 #define MPI2_MFGPAGE_DEVID_SAS2116_1                (0x0064)
 #define MPI2_MFGPAGE_DEVID_SAS2116_2                (0x0065)
 
+#define MPI2_MFGPAGE_DEVID_SAS2208_1                (0x0080)
+#define MPI2_MFGPAGE_DEVID_SAS2208_2                (0x0081)
+#define MPI2_MFGPAGE_DEVID_SAS2208_3                (0x0082)
+#define MPI2_MFGPAGE_DEVID_SAS2208_4                (0x0083)
+#define MPI2_MFGPAGE_DEVID_SAS2208_5                (0x0084)
+#define MPI2_MFGPAGE_DEVID_SAS2208_6                (0x0085)
+#define MPI2_MFGPAGE_DEVID_SAS2208_7                (0x0086)
+#define MPI2_MFGPAGE_DEVID_SAS2208_8                (0x0087)
+
 
 /* Manufacturing Page 0 */
 
@@ -787,6 +812,56 @@
 #define MPI2_IOUNITPAGE6_FLAGS_ENABLE_RAID_ACCELERATOR  (0x0001)
 
 
+/* IO Unit Page 7 */
+
+typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7 {
+    MPI2_CONFIG_PAGE_HEADER Header;                                 /* 0x00 */
+    U16                     Reserved1;                              /* 0x04 */
+    U8                      PCIeWidth;                              /* 0x06 */
+    U8                      PCIeSpeed;                              /* 0x07 */
+    U32                     ProcessorState;                         /* 0x08 */
+    U32                     Reserved2;                              /* 0x0C */
+    U16                     IOCTemperature;                         /* 0x10 */
+    U8                      IOCTemperatureUnits;                    /* 0x12 */
+    U8                      IOCSpeed;                               /* 0x13 */
+    U32                     Reserved3;                              /* 0x14 */
+} MPI2_CONFIG_PAGE_IO_UNIT_7, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_7,
+  Mpi2IOUnitPage7_t, MPI2_POINTER pMpi2IOUnitPage7_t;
+
+#define MPI2_IOUNITPAGE7_PAGEVERSION                    (0x00)
+
+/* defines for IO Unit Page 7 PCIeWidth field */
+#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X1              (0x01)
+#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X2              (0x02)
+#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X4              (0x04)
+#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X8              (0x08)
+
+/* defines for IO Unit Page 7 PCIeSpeed field */
+#define MPI2_IOUNITPAGE7_PCIE_SPEED_2_5_GBPS        (0x00)
+#define MPI2_IOUNITPAGE7_PCIE_SPEED_5_0_GBPS        (0x01)
+#define MPI2_IOUNITPAGE7_PCIE_SPEED_8_0_GBPS        (0x02)
+
+/* defines for IO Unit Page 7 ProcessorState field */
+#define MPI2_IOUNITPAGE7_PSTATE_MASK_SECOND         (0x0000000F)
+#define MPI2_IOUNITPAGE7_PSTATE_SHIFT_SECOND        (0)
+
+#define MPI2_IOUNITPAGE7_PSTATE_NOT_PRESENT         (0x00)
+#define MPI2_IOUNITPAGE7_PSTATE_DISABLED            (0x01)
+#define MPI2_IOUNITPAGE7_PSTATE_ENABLED             (0x02)
+
+/* defines for IO Unit Page 7 IOCTemperatureUnits field */
+#define MPI2_IOUNITPAGE7_IOC_TEMP_NOT_PRESENT       (0x00)
+#define MPI2_IOUNITPAGE7_IOC_TEMP_FAHRENHEIT        (0x01)
+#define MPI2_IOUNITPAGE7_IOC_TEMP_CELSIUS           (0x02)
+
+/* defines for IO Unit Page 7 IOCSpeed field */
+#define MPI2_IOUNITPAGE7_IOC_SPEED_FULL             (0x01)
+#define MPI2_IOUNITPAGE7_IOC_SPEED_HALF             (0x02)
+#define MPI2_IOUNITPAGE7_IOC_SPEED_QUARTER          (0x04)
+#define MPI2_IOUNITPAGE7_IOC_SPEED_EIGHTH           (0x08)
+
+
+
 /****************************************************************************
 *   IOC Config Pages
 ****************************************************************************/
@@ -1470,6 +1545,12 @@
 
 /* values for PhyInfo fields */
 #define MPI2_SAS_PHYINFO_PHY_VACANT                     (0x80000000)
+
+#define MPI2_SAS_PHYINFO_PHY_POWER_CONDITION_MASK       (0x18000000)
+#define MPI2_SAS_PHYINFO_PHY_POWER_ACTIVE               (0x00000000)
+#define MPI2_SAS_PHYINFO_PHY_POWER_PARTIAL              (0x08000000)
+#define MPI2_SAS_PHYINFO_PHY_POWER_SLUMBER              (0x10000000)
+
 #define MPI2_SAS_PHYINFO_CHANGED_REQ_INSIDE_ZPSDS       (0x04000000)
 #define MPI2_SAS_PHYINFO_INSIDE_ZPSDS_PERSISTENT        (0x02000000)
 #define MPI2_SAS_PHYINFO_REQ_INSIDE_ZPSDS               (0x01000000)
@@ -1682,11 +1763,11 @@
 /* values for SAS IO Unit Page 1 PortFlags */
 #define MPI2_SASIOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG                 (0x01)
 
-/* values for SAS IO Unit Page 2 PhyFlags */
+/* values for SAS IO Unit Page 1 PhyFlags */
 #define MPI2_SASIOUNIT1_PHYFLAGS_ZONING_ENABLE                      (0x10)
 #define MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE                        (0x08)
 
-/* values for SAS IO Unit Page 0 MaxMinLinkRate */
+/* values for SAS IO Unit Page 1 MaxMinLinkRate */
 #define MPI2_SASIOUNIT1_MAX_RATE_MASK                               (0xF0)
 #define MPI2_SASIOUNIT1_MAX_RATE_1_5                                (0x80)
 #define MPI2_SASIOUNIT1_MAX_RATE_3_0                                (0x90)
@@ -1745,6 +1826,74 @@
 #define MPI2_SASIOUNIT4_PHY_SPINUP_GROUP_MASK               (0x03)
 
 
+/* SAS IO Unit Page 5 */
+
+typedef struct _MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS {
+    U8          ControlFlags;               /* 0x00 */
+    U8          Reserved1;                  /* 0x01 */
+    U16         InactivityTimerExponent;    /* 0x02 */
+    U8          SATAPartialTimeout;         /* 0x04 */
+    U8          Reserved2;                  /* 0x05 */
+    U8          SATASlumberTimeout;         /* 0x06 */
+    U8          Reserved3;                  /* 0x07 */
+    U8          SASPartialTimeout;          /* 0x08 */
+    U8          Reserved4;                  /* 0x09 */
+    U8          SASSlumberTimeout;          /* 0x0A */
+    U8          Reserved5;                  /* 0x0B */
+} MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS,
+  MPI2_POINTER PTR_MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS,
+  Mpi2SasIOUnit5PhyPmSettings_t, MPI2_POINTER pMpi2SasIOUnit5PhyPmSettings_t;
+
+/* defines for ControlFlags field */
+#define MPI2_SASIOUNIT5_CONTROL_SAS_SLUMBER_ENABLE      (0x08)
+#define MPI2_SASIOUNIT5_CONTROL_SAS_PARTIAL_ENABLE      (0x04)
+#define MPI2_SASIOUNIT5_CONTROL_SATA_SLUMBER_ENABLE     (0x02)
+#define MPI2_SASIOUNIT5_CONTROL_SATA_PARTIAL_ENABLE     (0x01)
+
+/* defines for InactivityTimerExponent field */
+#define MPI2_SASIOUNIT5_ITE_MASK_SAS_SLUMBER            (0x7000)
+#define MPI2_SASIOUNIT5_ITE_SHIFT_SAS_SLUMBER           (12)
+#define MPI2_SASIOUNIT5_ITE_MASK_SAS_PARTIAL            (0x0700)
+#define MPI2_SASIOUNIT5_ITE_SHIFT_SAS_PARTIAL           (8)
+#define MPI2_SASIOUNIT5_ITE_MASK_SATA_SLUMBER           (0x0070)
+#define MPI2_SASIOUNIT5_ITE_SHIFT_SATA_SLUMBER          (4)
+#define MPI2_SASIOUNIT5_ITE_MASK_SATA_PARTIAL           (0x0007)
+#define MPI2_SASIOUNIT5_ITE_SHIFT_SATA_PARTIAL          (0)
+
+#define MPI2_SASIOUNIT5_ITE_TEN_SECONDS                 (7)
+#define MPI2_SASIOUNIT5_ITE_ONE_SECOND                  (6)
+#define MPI2_SASIOUNIT5_ITE_HUNDRED_MILLISECONDS        (5)
+#define MPI2_SASIOUNIT5_ITE_TEN_MILLISECONDS            (4)
+#define MPI2_SASIOUNIT5_ITE_ONE_MILLISECOND             (3)
+#define MPI2_SASIOUNIT5_ITE_HUNDRED_MICROSECONDS        (2)
+#define MPI2_SASIOUNIT5_ITE_TEN_MICROSECONDS            (1)
+#define MPI2_SASIOUNIT5_ITE_ONE_MICROSECOND             (0)
+
+/*
+ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ * one and check Header.ExtPageLength or NumPhys at runtime.
+ */
+#ifndef MPI2_SAS_IOUNIT5_PHY_MAX
+#define MPI2_SAS_IOUNIT5_PHY_MAX        (1)
+#endif
+
+typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_5 {
+    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;		/* 0x00 */
+    U8                                  NumPhys;	/* 0x08 */
+    U8                                  Reserved1;	/* 0x09 */
+    U16                                 Reserved2;	/* 0x0A */
+    U32                                 Reserved3;	/* 0x0C */
+    MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS   SASPhyPowerManagementSettings
+					[MPI2_SAS_IOUNIT5_PHY_MAX];  /* 0x10 */
+} MPI2_CONFIG_PAGE_SASIOUNIT_5,
+  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SASIOUNIT_5,
+  Mpi2SasIOUnitPage5_t, MPI2_POINTER pMpi2SasIOUnitPage5_t;
+
+#define MPI2_SASIOUNITPAGE5_PAGEVERSION     (0x00)
+
+
+
+
 /****************************************************************************
 *   SAS Expander Config Pages
 ****************************************************************************/
@@ -1927,6 +2076,8 @@
 /* see mpi2_sas.h for values for SAS Device Page 0 DeviceInfo values */
 
 /* values for SAS Device Page 0 Flags field */
+#define MPI2_SAS_DEVICE0_FLAGS_SLUMBER_PM_CAPABLE           (0x1000)
+#define MPI2_SAS_DEVICE0_FLAGS_PARTIAL_PM_CAPABLE           (0x0800)
 #define MPI2_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY     (0x0400)
 #define MPI2_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE             (0x0200)
 #define MPI2_SAS_DEVICE0_FLAGS_UNSUPPORTED_DEVICE           (0x0100)
@@ -2343,5 +2494,122 @@
 #define MPI2_DRVMAP0_MAPINFO_MISSING_MASK           (0x000F)
 
 
+/****************************************************************************
+*   Ethernet Config Pages
+****************************************************************************/
+
+/* Ethernet Page 0 */
+
+/* IP address (union of IPv4 and IPv6) */
+typedef union _MPI2_ETHERNET_IP_ADDR {
+    U32     IPv4Addr;
+    U32     IPv6Addr[4];
+} MPI2_ETHERNET_IP_ADDR, MPI2_POINTER PTR_MPI2_ETHERNET_IP_ADDR,
+  Mpi2EthernetIpAddr_t, MPI2_POINTER pMpi2EthernetIpAddr_t;
+
+#define MPI2_ETHERNET_HOST_NAME_LENGTH          (32)
+
+typedef struct _MPI2_CONFIG_PAGE_ETHERNET_0 {
+    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                 /* 0x00 */
+    U8                                  NumInterfaces;          /* 0x08 */
+    U8                                  Reserved0;              /* 0x09 */
+    U16                                 Reserved1;              /* 0x0A */
+    U32                                 Status;                 /* 0x0C */
+    U8                                  MediaState;             /* 0x10 */
+    U8                                  Reserved2;              /* 0x11 */
+    U16                                 Reserved3;              /* 0x12 */
+    U8                                  MacAddress[6];          /* 0x14 */
+    U8                                  Reserved4;              /* 0x1A */
+    U8                                  Reserved5;              /* 0x1B */
+    MPI2_ETHERNET_IP_ADDR               IpAddress;              /* 0x1C */
+    MPI2_ETHERNET_IP_ADDR               SubnetMask;             /* 0x2C */
+    MPI2_ETHERNET_IP_ADDR               GatewayIpAddress;       /* 0x3C */
+    MPI2_ETHERNET_IP_ADDR               DNS1IpAddress;          /* 0x4C */
+    MPI2_ETHERNET_IP_ADDR               DNS2IpAddress;          /* 0x5C */
+    MPI2_ETHERNET_IP_ADDR               DhcpIpAddress;          /* 0x6C */
+    U8                                  HostName
+				[MPI2_ETHERNET_HOST_NAME_LENGTH];/* 0x7C */
+} MPI2_CONFIG_PAGE_ETHERNET_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_ETHERNET_0,
+  Mpi2EthernetPage0_t, MPI2_POINTER pMpi2EthernetPage0_t;
+
+#define MPI2_ETHERNETPAGE0_PAGEVERSION   (0x00)
+
+/* values for Ethernet Page 0 Status field */
+#define MPI2_ETHPG0_STATUS_IPV6_CAPABLE             (0x80000000)
+#define MPI2_ETHPG0_STATUS_IPV4_CAPABLE             (0x40000000)
+#define MPI2_ETHPG0_STATUS_CONSOLE_CONNECTED        (0x20000000)
+#define MPI2_ETHPG0_STATUS_DEFAULT_IF               (0x00000100)
+#define MPI2_ETHPG0_STATUS_FW_DWNLD_ENABLED         (0x00000080)
+#define MPI2_ETHPG0_STATUS_TELNET_ENABLED           (0x00000040)
+#define MPI2_ETHPG0_STATUS_SSH2_ENABLED             (0x00000020)
+#define MPI2_ETHPG0_STATUS_DHCP_CLIENT_ENABLED      (0x00000010)
+#define MPI2_ETHPG0_STATUS_IPV6_ENABLED             (0x00000008)
+#define MPI2_ETHPG0_STATUS_IPV4_ENABLED             (0x00000004)
+#define MPI2_ETHPG0_STATUS_IPV6_ADDRESSES           (0x00000002)
+#define MPI2_ETHPG0_STATUS_ETH_IF_ENABLED           (0x00000001)
+
+/* values for Ethernet Page 0 MediaState field */
+#define MPI2_ETHPG0_MS_DUPLEX_MASK                  (0x80)
+#define MPI2_ETHPG0_MS_HALF_DUPLEX                  (0x00)
+#define MPI2_ETHPG0_MS_FULL_DUPLEX                  (0x80)
+
+#define MPI2_ETHPG0_MS_CONNECT_SPEED_MASK           (0x07)
+#define MPI2_ETHPG0_MS_NOT_CONNECTED                (0x00)
+#define MPI2_ETHPG0_MS_10MBIT                       (0x01)
+#define MPI2_ETHPG0_MS_100MBIT                      (0x02)
+#define MPI2_ETHPG0_MS_1GBIT                        (0x03)
+
+
+/* Ethernet Page 1 */
+
+typedef struct _MPI2_CONFIG_PAGE_ETHERNET_1 {
+    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                 /* 0x00 */
+    U32                                 Reserved0;              /* 0x08 */
+    U32                                 Flags;                  /* 0x0C */
+    U8                                  MediaState;             /* 0x10 */
+    U8                                  Reserved1;              /* 0x11 */
+    U16                                 Reserved2;              /* 0x12 */
+    U8                                  MacAddress[6];          /* 0x14 */
+    U8                                  Reserved3;              /* 0x1A */
+    U8                                  Reserved4;              /* 0x1B */
+    MPI2_ETHERNET_IP_ADDR               StaticIpAddress;        /* 0x1C */
+    MPI2_ETHERNET_IP_ADDR               StaticSubnetMask;       /* 0x2C */
+    MPI2_ETHERNET_IP_ADDR               StaticGatewayIpAddress; /* 0x3C */
+    MPI2_ETHERNET_IP_ADDR               StaticDNS1IpAddress;    /* 0x4C */
+    MPI2_ETHERNET_IP_ADDR               StaticDNS2IpAddress;    /* 0x5C */
+    U32                                 Reserved5;              /* 0x6C */
+    U32                                 Reserved6;              /* 0x70 */
+    U32                                 Reserved7;              /* 0x74 */
+    U32                                 Reserved8;              /* 0x78 */
+    U8                                  HostName
+				[MPI2_ETHERNET_HOST_NAME_LENGTH];/* 0x7C */
+} MPI2_CONFIG_PAGE_ETHERNET_1, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_ETHERNET_1,
+  Mpi2EthernetPage1_t, MPI2_POINTER pMpi2EthernetPage1_t;
+
+#define MPI2_ETHERNETPAGE1_PAGEVERSION   (0x00)
+
+/* values for Ethernet Page 1 Flags field */
+#define MPI2_ETHPG1_FLAG_SET_DEFAULT_IF             (0x00000100)
+#define MPI2_ETHPG1_FLAG_ENABLE_FW_DOWNLOAD         (0x00000080)
+#define MPI2_ETHPG1_FLAG_ENABLE_TELNET              (0x00000040)
+#define MPI2_ETHPG1_FLAG_ENABLE_SSH2                (0x00000020)
+#define MPI2_ETHPG1_FLAG_ENABLE_DHCP_CLIENT         (0x00000010)
+#define MPI2_ETHPG1_FLAG_ENABLE_IPV6                (0x00000008)
+#define MPI2_ETHPG1_FLAG_ENABLE_IPV4                (0x00000004)
+#define MPI2_ETHPG1_FLAG_USE_IPV6_ADDRESSES         (0x00000002)
+#define MPI2_ETHPG1_FLAG_ENABLE_ETH_IF              (0x00000001)
+
+/* values for Ethernet Page 1 MediaState field */
+#define MPI2_ETHPG1_MS_DUPLEX_MASK                  (0x80)
+#define MPI2_ETHPG1_MS_HALF_DUPLEX                  (0x00)
+#define MPI2_ETHPG1_MS_FULL_DUPLEX                  (0x80)
+
+#define MPI2_ETHPG1_MS_DATA_RATE_MASK               (0x07)
+#define MPI2_ETHPG1_MS_DATA_RATE_AUTO               (0x00)
+#define MPI2_ETHPG1_MS_DATA_RATE_10MBIT             (0x01)
+#define MPI2_ETHPG1_MS_DATA_RATE_100MBIT            (0x02)
+#define MPI2_ETHPG1_MS_DATA_RATE_1GBIT              (0x03)
+
+
 #endif
 
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
index c294128..ea51ce8 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
@@ -6,7 +6,7 @@
  *          Title:  MPI IOC, Port, Event, FW Download, and FW Upload messages
  *  Creation Date:  October 11, 2006
  *
- *  mpi2_ioc.h Version:  02.00.11
+ *  mpi2_ioc.h Version:  02.00.12
  *
  *  Version History
  *  ---------------
@@ -84,6 +84,9 @@
  *                      Added two new reason codes for SAS Device Status Change
  *                      Event.
  *                      Added new event: SAS PHY Counter.
+ *  07-30-09  02.00.12  Added GPIO Interrupt event define and structure.
+ *                      Added MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER define.
+ *                      Added new product id family for 2208.
  *  --------------------------------------------------------------------------
  */
 
@@ -274,6 +277,7 @@
 #define MPI2_IOCFACTS_CAPABILITY_MULTICAST              (0x00000100)
 #define MPI2_IOCFACTS_CAPABILITY_BIDIRECTIONAL_TARGET   (0x00000080)
 #define MPI2_IOCFACTS_CAPABILITY_EEDP                   (0x00000040)
+#define MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER        (0x00000020)
 #define MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER        (0x00000010)
 #define MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER      (0x00000008)
 #define MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING (0x00000004)
@@ -448,6 +452,7 @@
 #define MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST     (0x0020)
 #define MPI2_EVENT_LOG_ENTRY_ADDED                  (0x0021)
 #define MPI2_EVENT_SAS_PHY_COUNTER                  (0x0022)
+#define MPI2_EVENT_GPIO_INTERRUPT                   (0x0023)
 
 
 /* Log Entry Added Event data */
@@ -469,6 +474,16 @@
   MPI2_POINTER PTR_MPI2_EVENT_DATA_LOG_ENTRY_ADDED,
   Mpi2EventDataLogEntryAdded_t, MPI2_POINTER pMpi2EventDataLogEntryAdded_t;
 
+/* GPIO Interrupt Event data */
+
+typedef struct _MPI2_EVENT_DATA_GPIO_INTERRUPT {
+    U8          GPIONum;                            /* 0x00 */
+    U8          Reserved1;                          /* 0x01 */
+    U16         Reserved2;                          /* 0x02 */
+} MPI2_EVENT_DATA_GPIO_INTERRUPT,
+  MPI2_POINTER PTR_MPI2_EVENT_DATA_GPIO_INTERRUPT,
+  Mpi2EventDataGpioInterrupt_t, MPI2_POINTER pMpi2EventDataGpioInterrupt_t;
+
 /* Hard Reset Received Event data */
 
 typedef struct _MPI2_EVENT_DATA_HARD_RESET_RECEIVED
@@ -1117,6 +1132,7 @@
 #define MPI2_FW_HEADER_PID_FAMILY_MASK          (0x00FF)
 /* SAS */
 #define MPI2_FW_HEADER_PID_FAMILY_2108_SAS      (0x0010)
+#define MPI2_FW_HEADER_PID_FAMILY_2208_SAS      (0x0011)
 
 /* use MPI2_IOCFACTS_PROTOCOL_ defines for ProtocolFlags field */
 
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_raid.h b/drivers/scsi/mpt2sas/mpi/mpi2_raid.h
index 7134816d..5160c33 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_raid.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_raid.h
@@ -6,7 +6,7 @@
  *          Title:  MPI Integrated RAID messages and structures
  *  Creation Date:  April 26, 2007
  *
- *    mpi2_raid.h Version:  02.00.03
+ *    mpi2_raid.h Version:  02.00.04
  *
  *  Version History
  *  ---------------
@@ -20,6 +20,8 @@
  *  05-21-08  02.00.03  Added MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS so that
  *                      the PhysDisk array in MPI2_RAID_VOLUME_CREATION_STRUCT
  *                      can be sized by the build environment.
+ *  07-30-09  02.00.04  Added proper define for the Use Default Settings bit of
+ *                      VolumeCreationFlags and marked the old one as obsolete.
  *  --------------------------------------------------------------------------
  */
 
@@ -217,10 +219,14 @@
 /* use MPI2_RAID_VOL_TYPE_ defines from mpi2_cnfg.h for VolumeType */
 
 /* defines for the VolumeCreationFlags field */
+#define MPI2_RAID_VOL_CREATION_DEFAULT_SETTINGS     (0x80000000)
+#define MPI2_RAID_VOL_CREATION_BACKGROUND_INIT      (0x00000004)
+#define MPI2_RAID_VOL_CREATION_LOW_LEVEL_INIT       (0x00000002)
+#define MPI2_RAID_VOL_CREATION_MIGRATE_DATA         (0x00000001)
+/* The following is an obsolete define.
+ * It must be shifted left 24 bits in order to set the proper bit.
+ */
 #define MPI2_RAID_VOL_CREATION_USE_DEFAULT_SETTINGS (0x80)
-#define MPI2_RAID_VOL_CREATION_BACKGROUND_INIT      (0x04)
-#define MPI2_RAID_VOL_CREATION_LOW_LEVEL_INIT       (0x02)
-#define MPI2_RAID_VOL_CREATION_MIGRATE_DATA         (0x01)
 
 
 /* RAID Online Capacity Expansion Structure */
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_tool.h b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h
index 007e950..73fcdbf 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_tool.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h
@@ -6,7 +6,7 @@
  *          Title:  MPI diagnostic tool structures and definitions
  *  Creation Date:  March 26, 2007
  *
- *    mpi2_tool.h Version:  02.00.03
+ *    mpi2_tool.h Version:  02.00.04
  *
  *  Version History
  *  ---------------
@@ -18,6 +18,10 @@
  *                      structures and defines.
  *  02-29-08  02.00.02  Modified various names to make them 32-character unique.
  *  05-06-09  02.00.03  Added ISTWI Read Write Tool and Diagnostic CLI Tool.
+ *  07-30-09  02.00.04  Added ExtendedType field to DiagnosticBufferPost request
+ *                      and reply messages.
+ *                      Added MPI2_DIAG_BUF_TYPE_EXTENDED.
+ *                      Incremented MPI2_DIAG_BUF_TYPE_COUNT.
  *  --------------------------------------------------------------------------
  */
 
@@ -282,7 +286,7 @@
 
 typedef struct _MPI2_DIAG_BUFFER_POST_REQUEST
 {
-    U8                      Reserved1;                  /* 0x00 */
+    U8                      ExtendedType;               /* 0x00 */
     U8                      BufferType;                 /* 0x01 */
     U8                      ChainOffset;                /* 0x02 */
     U8                      Function;                   /* 0x03 */
@@ -301,11 +305,15 @@
 } MPI2_DIAG_BUFFER_POST_REQUEST, MPI2_POINTER PTR_MPI2_DIAG_BUFFER_POST_REQUEST,
   Mpi2DiagBufferPostRequest_t, MPI2_POINTER pMpi2DiagBufferPostRequest_t;
 
+/* values for the ExtendedType field */
+#define MPI2_DIAG_EXTENDED_TYPE_UTILIZATION         (0x02)
+
 /* values for the BufferType field */
 #define MPI2_DIAG_BUF_TYPE_TRACE                    (0x00)
 #define MPI2_DIAG_BUF_TYPE_SNAPSHOT                 (0x01)
+#define MPI2_DIAG_BUF_TYPE_EXTENDED                 (0x02)
 /* count of the number of buffer types */
-#define MPI2_DIAG_BUF_TYPE_COUNT                    (0x02)
+#define MPI2_DIAG_BUF_TYPE_COUNT                    (0x03)
 
 
 /****************************************************************************
@@ -314,7 +322,7 @@
 
 typedef struct _MPI2_DIAG_BUFFER_POST_REPLY
 {
-    U8                      Reserved1;                  /* 0x00 */
+    U8                      ExtendedType;               /* 0x00 */
     U8                      BufferType;                 /* 0x01 */
     U8                      MsgLength;                  /* 0x02 */
     U8                      Function;                   /* 0x03 */
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 670241e..6422e25 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -57,6 +57,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/sort.h>
 #include <linux/io.h>
+#include <linux/time.h>
 
 #include "mpt2sas_base.h"
 
@@ -77,6 +78,44 @@
 module_param(msix_disable, int, 0);
 MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)");
 
+/* diag_buffer_enable is bitwise
+ * bit 0 set = TRACE
+ * bit 1 set = SNAPSHOT
+ * bit 2 set = EXTENDED
+ *
+ * Either bit can be set, or both
+ */
+static int diag_buffer_enable;
+module_param(diag_buffer_enable, int, 0);
+MODULE_PARM_DESC(diag_buffer_enable, " post diag buffers "
+    "(TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)");
+
+int mpt2sas_fwfault_debug;
+MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault "
+    "and halt firmware - (default=0)");
+
+/**
+ * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug.
+ *
+ */
+static int
+_scsih_set_fwfault_debug(const char *val, struct kernel_param *kp)
+{
+	int ret = param_set_int(val, kp);
+	struct MPT2SAS_ADAPTER *ioc;
+
+	if (ret)
+		return ret;
+
+	printk(KERN_INFO "setting logging_level(0x%08x)\n",
+				mpt2sas_fwfault_debug);
+	list_for_each_entry(ioc, &mpt2sas_ioc_list, list)
+		ioc->fwfault_debug = mpt2sas_fwfault_debug;
+	return 0;
+}
+module_param_call(mpt2sas_fwfault_debug, _scsih_set_fwfault_debug,
+    param_get_int, &mpt2sas_fwfault_debug, 0644);
+
 /**
  * _base_fault_reset_work - workq handling ioc fault conditions
  * @work: input argument, used to derive ioc
@@ -121,7 +160,7 @@
 
 /**
  * mpt2sas_base_start_watchdog - start the fault_reset_work_q
- * @ioc: pointer to scsi command object
+ * @ioc: per adapter object
  * Context: sleep.
  *
  * Return nothing.
@@ -155,7 +194,7 @@
 
 /**
  * mpt2sas_base_stop_watchdog - stop the fault_reset_work_q
- * @ioc: pointer to scsi command object
+ * @ioc: per adapter object
  * Context: sleep.
  *
  * Return nothing.
@@ -177,10 +216,55 @@
 	}
 }
 
+/**
+ * mpt2sas_base_fault_info - verbose translation of firmware FAULT code
+ * @ioc: per adapter object
+ * @fault_code: fault code
+ *
+ * Return nothing.
+ */
+void
+mpt2sas_base_fault_info(struct MPT2SAS_ADAPTER *ioc , u16 fault_code)
+{
+	printk(MPT2SAS_ERR_FMT "fault_state(0x%04x)!\n",
+	    ioc->name, fault_code);
+}
+
+/**
+ * mpt2sas_halt_firmware - halt's mpt controller firmware
+ * @ioc: per adapter object
+ *
+ * For debugging timeout related issues.  Writing 0xCOFFEE00
+ * to the doorbell register will halt controller firmware. With
+ * the purpose to stop both driver and firmware, the enduser can
+ * obtain a ring buffer from controller UART.
+ */
+void
+mpt2sas_halt_firmware(struct MPT2SAS_ADAPTER *ioc)
+{
+	u32 doorbell;
+
+	if (!ioc->fwfault_debug)
+		return;
+
+	dump_stack();
+
+	doorbell = readl(&ioc->chip->Doorbell);
+	if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT)
+		mpt2sas_base_fault_info(ioc , doorbell);
+	else {
+		writel(0xC0FFEE00, &ioc->chip->Doorbell);
+		printk(MPT2SAS_ERR_FMT "Firmware is halted due to command "
+		    "timeout\n", ioc->name);
+	}
+
+	panic("panic in %s\n", __func__);
+}
+
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
 /**
  * _base_sas_ioc_info - verbose translation of the ioc status
- * @ioc: pointer to scsi command object
+ * @ioc: per adapter object
  * @mpi_reply: reply mf payload returned from firmware
  * @request_hdr: request mf
  *
@@ -394,7 +478,7 @@
 
 /**
  * _base_display_event_data - verbose translation of firmware asyn events
- * @ioc: pointer to scsi command object
+ * @ioc: per adapter object
  * @mpi_reply: reply mf payload returned from firmware
  *
  * Return nothing.
@@ -474,7 +558,7 @@
 
 /**
  * _base_sas_log_info - verbose translation of firmware log info
- * @ioc: pointer to scsi command object
+ * @ioc: per adapter object
  * @log_info: log info
  *
  * Return nothing.
@@ -526,22 +610,8 @@
 }
 
 /**
- * mpt2sas_base_fault_info - verbose translation of firmware FAULT code
- * @ioc: pointer to scsi command object
- * @fault_code: fault code
- *
- * Return nothing.
- */
-void
-mpt2sas_base_fault_info(struct MPT2SAS_ADAPTER *ioc , u16 fault_code)
-{
-	printk(MPT2SAS_ERR_FMT "fault_state(0x%04x)!\n",
-	    ioc->name, fault_code);
-}
-
-/**
  * _base_display_reply_info -
- * @ioc: pointer to scsi command object
+ * @ioc: per adapter object
  * @smid: system request message index
  * @msix_index: MSIX table index supplied by the OS
  * @reply: reply message frame(lower 32bit addr)
@@ -570,7 +640,7 @@
 
 /**
  * mpt2sas_base_done - base internal command completion routine
- * @ioc: pointer to scsi command object
+ * @ioc: per adapter object
  * @smid: system request message index
  * @msix_index: MSIX table index supplied by the OS
  * @reply: reply message frame(lower 32bit addr)
@@ -603,7 +673,7 @@
 
 /**
  * _base_async_event - main callback handler for firmware asyn events
- * @ioc: pointer to scsi command object
+ * @ioc: per adapter object
  * @msix_index: MSIX table index supplied by the OS
  * @reply: reply message frame(lower 32bit addr)
  *
@@ -684,7 +754,7 @@
 
 /**
  * _base_mask_interrupts - disable interrupts
- * @ioc: pointer to scsi command object
+ * @ioc: per adapter object
  *
  * Disabling ResetIRQ, Reply and Doorbell Interrupts
  *
@@ -704,7 +774,7 @@
 
 /**
  * _base_unmask_interrupts - enable interrupts
- * @ioc: pointer to scsi command object
+ * @ioc: per adapter object
  *
  * Enabling only Reply Interrupts
  *
@@ -1258,12 +1328,13 @@
  * @ioc: per adapter object
  * @smid: system request message index
  *
- * Returns phys pointer to sense buffer.
+ * Returns phys pointer to the low 32bit address of the sense buffer.
  */
-dma_addr_t
+__le32
 mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid)
 {
-	return ioc->sense_dma + ((smid - 1) * SCSI_SENSE_BUFFERSIZE);
+	return cpu_to_le32(ioc->sense_dma +
+			((smid - 1) * SCSI_SENSE_BUFFERSIZE));
 }
 
 /**
@@ -1697,6 +1768,12 @@
 	}
 
 	if (ioc->facts.IOCCapabilities &
+	    MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER) {
+		printk(KERN_INFO "%sDiag Extended Buffer", i ? "," : "");
+		i++;
+	}
+
+	if (ioc->facts.IOCCapabilities &
 	    MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING) {
 		printk("%sTask Set Full", i ? "," : "");
 		i++;
@@ -2871,6 +2948,8 @@
 	Mpi2IOCInitRequest_t mpi_request;
 	Mpi2IOCInitReply_t mpi_reply;
 	int r;
+	struct timeval current_time;
+	u16 ioc_status;
 
 	dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
 	    __func__));
@@ -2921,6 +3000,13 @@
 	    cpu_to_le32(ioc->reply_post_free_dma);
 #endif
 
+	/* This time stamp specifies number of milliseconds
+	 * since epoch ~ midnight January 1, 1970.
+	 */
+	do_gettimeofday(&current_time);
+	mpi_request.TimeStamp = (current_time.tv_sec * 1000) +
+	    (current_time.tv_usec >> 3);
+
 	if (ioc->logging_level & MPT_DEBUG_INIT) {
 		u32 *mfp;
 		int i;
@@ -2943,7 +3029,8 @@
 		return r;
 	}
 
-	if (mpi_reply.IOCStatus != MPI2_IOCSTATUS_SUCCESS ||
+	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
+	if (ioc_status != MPI2_IOCSTATUS_SUCCESS ||
 	    mpi_reply.IOCLogInfo) {
 		printk(MPT2SAS_ERR_FMT "%s: failed\n", ioc->name, __func__);
 		r = -EIO;
@@ -3461,11 +3548,11 @@
 		return r;
 
 	pci_set_drvdata(ioc->pdev, ioc->shost);
-	r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET);
+	r = _base_get_ioc_facts(ioc, CAN_SLEEP);
 	if (r)
 		goto out_free_resources;
 
-	r = _base_get_ioc_facts(ioc, CAN_SLEEP);
+	r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET);
 	if (r)
 		goto out_free_resources;
 
@@ -3531,6 +3618,8 @@
 		goto out_free_resources;
 
 	mpt2sas_base_start_watchdog(ioc);
+	if (diag_buffer_enable != 0)
+		mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable);
 	return 0;
 
  out_free_resources:
@@ -3684,6 +3773,9 @@
 	dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name,
 	    __func__));
 
+	if (mpt2sas_fwfault_debug)
+		mpt2sas_halt_firmware(ioc);
+
 	spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
 	if (ioc->shost_recovery) {
 		spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h
index 0cf6bc2..bb4f146 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h
@@ -69,8 +69,8 @@
 #define MPT2SAS_DRIVER_NAME		"mpt2sas"
 #define MPT2SAS_AUTHOR	"LSI Corporation <DL-MPTFusionLinux@lsi.com>"
 #define MPT2SAS_DESCRIPTION	"LSI MPT Fusion SAS 2.0 Device Driver"
-#define MPT2SAS_DRIVER_VERSION		"02.100.03.00"
-#define MPT2SAS_MAJOR_VERSION		02
+#define MPT2SAS_DRIVER_VERSION		"03.100.03.00"
+#define MPT2SAS_MAJOR_VERSION		03
 #define MPT2SAS_MINOR_VERSION		100
 #define MPT2SAS_BUILD_VERSION		03
 #define MPT2SAS_RELEASE_VERSION		00
@@ -278,7 +278,7 @@
  * @sas_address: device sas address
  * @device_name: retrieved from the SAS IDENTIFY frame.
  * @handle: device handle
- * @parent_handle: handle to parent device
+ * @sas_address_parent: sas address of parent expander or sas host
  * @enclosure_handle: enclosure handle
  * @enclosure_logical_id: enclosure logical identifier
  * @volume_handle: volume handle (valid when hidden raid member)
@@ -296,7 +296,7 @@
 	u64	sas_address;
 	u64	device_name;
 	u16	handle;
-	u16	parent_handle;
+	u64	sas_address_parent;
 	u16	enclosure_handle;
 	u64	enclosure_logical_id;
 	u16	volume_handle;
@@ -352,8 +352,6 @@
 /**
  * struct _sas_port - wide/narrow sas port information
  * @port_list: list of ports belonging to expander
- * @handle: device handle for this port
- * @sas_address: sas address of this port
  * @num_phys: number of phys belonging to this port
  * @remote_identify: attached device identification
  * @rphy: sas transport rphy object
@@ -362,8 +360,6 @@
  */
 struct _sas_port {
 	struct list_head port_list;
-	u16	handle;
-	u64	sas_address;
 	u8	num_phys;
 	struct sas_identify remote_identify;
 	struct sas_rphy *rphy;
@@ -398,7 +394,7 @@
  * @num_phys: number phys belonging to this sas_host/expander
  * @sas_address: sas address of this sas_host/expander
  * @handle: handle for this sas_host/expander
- * @parent_handle: parent handle
+ * @sas_address_parent: sas address of parent expander or sas host
  * @enclosure_handle: handle for this a member of an enclosure
  * @device_info: bitwise defining capabilities of this sas_host/expander
  * @responding: used in _scsih_expander_device_mark_responding
@@ -411,7 +407,7 @@
 	u8	num_phys;
 	u64	sas_address;
 	u16	handle;
-	u16	parent_handle;
+	u64	sas_address_parent;
 	u16	enclosure_handle;
 	u64	enclosure_logical_id;
 	u8	responding;
@@ -470,6 +466,7 @@
  * @chip_phys: physical addrss prior to mapping
  * @pio_chip: I/O mapped register space
  * @logging_level: see mpt2sas_debug.h
+ * @fwfault_debug: debuging FW timeouts
  * @ir_firmware: IR firmware present
  * @bars: bitmask of BAR's that must be configured
  * @mask_interrupts: ignore interrupt
@@ -495,12 +492,14 @@
  * @msix_table_backup: backup msix table
  * @scsi_io_cb_idx: shost generated commands
  * @tm_cb_idx: task management commands
+ * @scsih_cb_idx: scsih internal commands
  * @transport_cb_idx: transport internal commands
  * @ctl_cb_idx: clt internal commands
  * @base_cb_idx: base internal commands
  * @config_cb_idx: base internal commands
  * @base_cmds:
  * @transport_cmds:
+ * @scsih_cmds:
  * @tm_cmds:
  * @ctl_cmds:
  * @config_cmds:
@@ -591,6 +590,7 @@
 	unsigned long	chip_phys;
 	unsigned long	pio_chip;
 	int		logging_level;
+	int		fwfault_debug;
 	u8		ir_firmware;
 	int		bars;
 	u8		mask_interrupts;
@@ -626,6 +626,7 @@
 	u8		scsi_io_cb_idx;
 	u8		tm_cb_idx;
 	u8		transport_cb_idx;
+	u8		scsih_cb_idx;
 	u8		ctl_cb_idx;
 	u8		base_cb_idx;
 	u8		config_cb_idx;
@@ -633,6 +634,7 @@
 	u8		tm_sas_control_cb_idx;
 	struct _internal_cmd base_cmds;
 	struct _internal_cmd transport_cmds;
+	struct _internal_cmd scsih_cmds;
 	struct _internal_cmd tm_cmds;
 	struct _internal_cmd ctl_cmds;
 	struct _internal_cmd config_cmds;
@@ -773,7 +775,7 @@
 void *mpt2sas_base_get_msg_frame(struct MPT2SAS_ADAPTER *ioc, u16 smid);
 void *mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid);
 void mpt2sas_base_build_zero_len_sge(struct MPT2SAS_ADAPTER *ioc, void *paddr);
-dma_addr_t mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc,
+__le32 mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc,
     u16 smid);
 
 /* hi-priority queue */
@@ -807,6 +809,8 @@
     Mpi2SepReply_t *mpi_reply, Mpi2SepRequest_t *mpi_request);
 void mpt2sas_base_validate_event_type(struct MPT2SAS_ADAPTER *ioc, u32 *event_type);
 
+void mpt2sas_halt_firmware(struct MPT2SAS_ADAPTER *ioc);
+
 /* scsih shared API */
 u8 mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
     u32 reply);
@@ -886,19 +890,22 @@
 void mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc,
     Mpi2EventNotificationReply_t *mpi_reply);
 
+void mpt2sas_enable_diag_buffer(struct MPT2SAS_ADAPTER *ioc,
+	u8 bits_to_regsiter);
+
 /* transport shared API */
 u8 mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
     u32 reply);
 struct _sas_port *mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc,
-    u16 handle, u16 parent_handle);
+     u16 handle, u64 sas_address);
 void mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
-    u16 parent_handle);
+     u64 sas_address_parent);
 int mpt2sas_transport_add_host_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
     *mpt2sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev);
 int mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
     *mpt2sas_phy, Mpi2ExpanderPage1_t expander_pg1, struct device *parent_dev);
-void mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc, u16 handle,
-   u16 attached_handle, u8 phy_number, u8 link_rate);
+void mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc,
+     u64 sas_address, u16 handle, u8 phy_number, u8 link_rate);
 extern struct sas_function_template mpt2sas_transport_functions;
 extern struct scsi_transport_template *mpt2sas_transport_template;
 extern int scsi_internal_device_block(struct scsi_device *sdev);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
index 57d7246..84a124f 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
@@ -740,7 +740,7 @@
 		Mpi2SCSIIORequest_t *scsiio_request =
 		    (Mpi2SCSIIORequest_t *)mpi_request;
 		scsiio_request->SenseBufferLowAddress =
-		    (u32)mpt2sas_base_get_sense_buffer_dma(ioc, smid);
+		    mpt2sas_base_get_sense_buffer_dma(ioc, smid);
 		priv_sense = mpt2sas_base_get_sense_buffer(ioc, smid);
 		memset(priv_sense, 0, SCSI_SENSE_BUFFERSIZE);
 		mpt2sas_base_put_smid_scsi_io(ioc, smid,
@@ -848,8 +848,9 @@
 		printk(MPT2SAS_DEBUG_FMT "TASK_MGMT: "
 		    "IOCStatus(0x%04x), IOCLogInfo(0x%08x), "
 		    "TerminationCount(0x%08x)\n", ioc->name,
-		    tm_reply->IOCStatus, tm_reply->IOCLogInfo,
-		    tm_reply->TerminationCount);
+		    le16_to_cpu(tm_reply->IOCStatus),
+		    le32_to_cpu(tm_reply->IOCLogInfo),
+		    le32_to_cpu(tm_reply->TerminationCount));
 	}
 #endif
 	/* copy out xdata to user */
@@ -896,6 +897,7 @@
 			printk(MPT2SAS_INFO_FMT "issue target reset: handle "
 			    "= (0x%04x)\n", ioc->name,
 			    mpi_request->FunctionDependent1);
+			mpt2sas_halt_firmware(ioc);
 			mutex_lock(&ioc->tm_cmds.mutex);
 			mpt2sas_scsih_issue_tm(ioc,
 			    mpi_request->FunctionDependent1, 0,
@@ -1229,7 +1231,7 @@
 /**
  * _ctl_diag_capability - return diag buffer capability
  * @ioc: per adapter object
- * @buffer_type: specifies either TRACE or SNAPSHOT
+ * @buffer_type: specifies either TRACE, SNAPSHOT, or EXTENDED
  *
  * returns 1 when diag buffer support is enabled in firmware
  */
@@ -1249,24 +1251,25 @@
 		    MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER)
 			rc = 1;
 		break;
+	case MPI2_DIAG_BUF_TYPE_EXTENDED:
+		if (ioc->facts.IOCCapabilities &
+		    MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER)
+			rc = 1;
 	}
 
 	return rc;
 }
 
 /**
- * _ctl_diag_register - application register with driver
- * @arg - user space buffer containing ioctl content
- * @state - NON_BLOCKING or BLOCKING
+ * _ctl_diag_register_2 - wrapper for registering diag buffer support
+ * @ioc: per adapter object
+ * @diag_register: the diag_register struct passed in from user space
  *
- * This will allow the driver to setup any required buffers that will be
- * needed by firmware to communicate with the driver.
  */
 static long
-_ctl_diag_register(void __user *arg, enum block_state state)
+_ctl_diag_register_2(struct MPT2SAS_ADAPTER *ioc,
+    struct mpt2_diag_register *diag_register)
 {
-	struct mpt2_diag_register karg;
-	struct MPT2SAS_ADAPTER *ioc;
 	int rc, i;
 	void *request_data = NULL;
 	dma_addr_t request_data_dma;
@@ -1279,18 +1282,17 @@
 	u16 ioc_status;
 	u8 issue_reset = 0;
 
-	if (copy_from_user(&karg, arg, sizeof(karg))) {
-		printk(KERN_ERR "failure at %s:%d/%s()!\n",
-		    __FILE__, __LINE__, __func__);
-		return -EFAULT;
-	}
-	if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
-		return -ENODEV;
-
 	dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
 	    __func__));
 
-	buffer_type = karg.buffer_type;
+	if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) {
+		printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n",
+		    ioc->name, __func__);
+		rc = -EAGAIN;
+		goto out;
+	}
+
+	buffer_type = diag_register->buffer_type;
 	if (!_ctl_diag_capability(ioc, buffer_type)) {
 		printk(MPT2SAS_ERR_FMT "%s: doesn't have capability for "
 		    "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
@@ -1305,24 +1307,12 @@
 		return -EINVAL;
 	}
 
-	if (karg.requested_buffer_size % 4)  {
+	if (diag_register->requested_buffer_size % 4)  {
 		printk(MPT2SAS_ERR_FMT "%s: the requested_buffer_size "
 		    "is not 4 byte aligned\n", ioc->name, __func__);
 		return -EINVAL;
 	}
 
-	if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex))
-		return -EAGAIN;
-	else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
-		return -ERESTARTSYS;
-
-	if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) {
-		printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n",
-		    ioc->name, __func__);
-		rc = -EAGAIN;
-		goto out;
-	}
-
 	smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx);
 	if (!smid) {
 		printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
@@ -1338,12 +1328,12 @@
 	ioc->ctl_cmds.smid = smid;
 
 	request_data = ioc->diag_buffer[buffer_type];
-	request_data_sz = karg.requested_buffer_size;
-	ioc->unique_id[buffer_type] = karg.unique_id;
+	request_data_sz = diag_register->requested_buffer_size;
+	ioc->unique_id[buffer_type] = diag_register->unique_id;
 	ioc->diag_buffer_status[buffer_type] = 0;
-	memcpy(ioc->product_specific[buffer_type], karg.product_specific,
-	    MPT2_PRODUCT_SPECIFIC_DWORDS);
-	ioc->diagnostic_flags[buffer_type] = karg.diagnostic_flags;
+	memcpy(ioc->product_specific[buffer_type],
+	    diag_register->product_specific, MPT2_PRODUCT_SPECIFIC_DWORDS);
+	ioc->diagnostic_flags[buffer_type] = diag_register->diagnostic_flags;
 
 	if (request_data) {
 		request_data_dma = ioc->diag_buffer_dma[buffer_type];
@@ -1373,8 +1363,8 @@
 	}
 
 	mpi_request->Function = MPI2_FUNCTION_DIAG_BUFFER_POST;
-	mpi_request->BufferType = karg.buffer_type;
-	mpi_request->Flags = cpu_to_le32(karg.diagnostic_flags);
+	mpi_request->BufferType = diag_register->buffer_type;
+	mpi_request->Flags = cpu_to_le32(diag_register->diagnostic_flags);
 	mpi_request->BufferAddress = cpu_to_le64(request_data_dma);
 	mpi_request->BufferLength = cpu_to_le32(request_data_sz);
 	mpi_request->VF_ID = 0; /* TODO */
@@ -1422,7 +1412,7 @@
 	} else {
 		printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) "
 		    "log_info(0x%08x)\n", ioc->name, __func__,
-		    ioc_status, mpi_reply->IOCLogInfo);
+		    ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo));
 		rc = -EFAULT;
 	}
 
@@ -1438,6 +1428,83 @@
 		    request_data, request_data_dma);
 
 	ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
+	return rc;
+}
+
+/**
+ * mpt2sas_enable_diag_buffer - enabling diag_buffers support driver load time
+ * @ioc: per adapter object
+ * @bits_to_register: bitwise field where trace is bit 0, and snapshot is bit 1
+ *
+ * This is called when command line option diag_buffer_enable is enabled
+ * at driver load time.
+ */
+void
+mpt2sas_enable_diag_buffer(struct MPT2SAS_ADAPTER *ioc, u8 bits_to_register)
+{
+	struct mpt2_diag_register diag_register;
+
+	memset(&diag_register, 0, sizeof(struct mpt2_diag_register));
+
+	if (bits_to_register & 1) {
+		printk(MPT2SAS_INFO_FMT "registering trace buffer support\n",
+		    ioc->name);
+		diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_TRACE;
+		/* register for 1MB buffers  */
+		diag_register.requested_buffer_size = (1024 * 1024);
+		diag_register.unique_id = 0x7075900;
+		_ctl_diag_register_2(ioc,  &diag_register);
+	}
+
+	if (bits_to_register & 2) {
+		printk(MPT2SAS_INFO_FMT "registering snapshot buffer support\n",
+		    ioc->name);
+		diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_SNAPSHOT;
+		/* register for 2MB buffers  */
+		diag_register.requested_buffer_size = 2 * (1024 * 1024);
+		diag_register.unique_id = 0x7075901;
+		_ctl_diag_register_2(ioc,  &diag_register);
+	}
+
+	if (bits_to_register & 4) {
+		printk(MPT2SAS_INFO_FMT "registering extended buffer support\n",
+		    ioc->name);
+		diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_EXTENDED;
+		/* register for 2MB buffers  */
+		diag_register.requested_buffer_size = 2 * (1024 * 1024);
+		diag_register.unique_id = 0x7075901;
+		_ctl_diag_register_2(ioc,  &diag_register);
+	}
+}
+
+/**
+ * _ctl_diag_register - application register with driver
+ * @arg - user space buffer containing ioctl content
+ * @state - NON_BLOCKING or BLOCKING
+ *
+ * This will allow the driver to setup any required buffers that will be
+ * needed by firmware to communicate with the driver.
+ */
+static long
+_ctl_diag_register(void __user *arg, enum block_state state)
+{
+	struct mpt2_diag_register karg;
+	struct MPT2SAS_ADAPTER *ioc;
+	long rc;
+
+	if (copy_from_user(&karg, arg, sizeof(karg))) {
+		printk(KERN_ERR "failure at %s:%d/%s()!\n",
+		    __FILE__, __LINE__, __func__);
+		return -EFAULT;
+	}
+	if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
+		return -ENODEV;
+
+	if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex))
+		return -EAGAIN;
+	else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
+		return -ERESTARTSYS;
+	rc = _ctl_diag_register_2(ioc, &karg);
 	mutex_unlock(&ioc->ctl_cmds.mutex);
 	return rc;
 }
@@ -1600,7 +1667,7 @@
 /**
  * _ctl_send_release - Diag Release Message
  * @ioc: per adapter object
- * @buffer_type - specifies either TRACE or SNAPSHOT
+ * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED
  * @issue_reset - specifies whether host reset is required.
  *
  */
@@ -1690,7 +1757,7 @@
 	} else {
 		printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) "
 		    "log_info(0x%08x)\n", ioc->name, __func__,
-		    ioc_status, mpi_reply->IOCLogInfo);
+		    ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo));
 		rc = -EFAULT;
 	}
 
@@ -1951,7 +2018,7 @@
 	} else {
 		printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) "
 		    "log_info(0x%08x)\n", ioc->name, __func__,
-		    ioc_status, mpi_reply->IOCLogInfo);
+		    ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo));
 		rc = -EFAULT;
 	}
 
@@ -2474,6 +2541,43 @@
 static DEVICE_ATTR(logging_level, S_IRUGO | S_IWUSR,
     _ctl_logging_level_show, _ctl_logging_level_store);
 
+/* device attributes */
+/*
+ * _ctl_fwfault_debug_show - show/store fwfault_debug
+ * @cdev - pointer to embedded class device
+ * @buf - the buffer returned
+ *
+ * mpt2sas_fwfault_debug is command line option
+ * A sysfs 'read/write' shost attribute.
+ */
+static ssize_t
+_ctl_fwfault_debug_show(struct device *cdev,
+    struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", ioc->fwfault_debug);
+}
+static ssize_t
+_ctl_fwfault_debug_store(struct device *cdev,
+    struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
+	int val = 0;
+
+	if (sscanf(buf, "%d", &val) != 1)
+		return -EINVAL;
+
+	ioc->fwfault_debug = val;
+	printk(MPT2SAS_INFO_FMT "fwfault_debug=%d\n", ioc->name,
+	    ioc->fwfault_debug);
+	return strlen(buf);
+}
+static DEVICE_ATTR(fwfault_debug, S_IRUGO | S_IWUSR,
+    _ctl_fwfault_debug_show, _ctl_fwfault_debug_store);
+
 struct device_attribute *mpt2sas_host_attrs[] = {
 	&dev_attr_version_fw,
 	&dev_attr_version_bios,
@@ -2487,13 +2591,12 @@
 	&dev_attr_io_delay,
 	&dev_attr_device_delay,
 	&dev_attr_logging_level,
+	&dev_attr_fwfault_debug,
 	&dev_attr_fw_queue_depth,
 	&dev_attr_host_sas_address,
 	NULL,
 };
 
-/* device attributes */
-
 /**
  * _ctl_device_sas_address_show - sas address
  * @cdev - pointer to embedded class device
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.h b/drivers/scsi/mpt2sas/mpt2sas_ctl.h
index 211f296..8a5eeb1 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.h
@@ -313,7 +313,7 @@
  * struct mpt2_diag_register - application register with driver
  * @hdr - generic header
  * @reserved -
- * @buffer_type - specifies either TRACE or SNAPSHOT
+ * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED
  * @application_flags - misc flags
  * @diagnostic_flags - specifies flags affecting command processing
  * @product_specific - product specific information
@@ -352,7 +352,7 @@
  * struct mpt2_diag_query - query relevant info associated with diag buffers
  * @hdr - generic header
  * @reserved -
- * @buffer_type - specifies either TRACE or SNAPSHOT
+ * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED
  * @application_flags - misc flags
  * @diagnostic_flags - specifies flags affecting command processing
  * @product_specific - product specific information
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 86ab32d..efabea1 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -76,6 +76,7 @@
 static u8 ctl_cb_idx = -1;
 static u8 base_cb_idx = -1;
 static u8 transport_cb_idx = -1;
+static u8 scsih_cb_idx = -1;
 static u8 config_cb_idx = -1;
 static int mpt_ids;
 
@@ -196,10 +197,28 @@
 		PCI_ANY_ID, PCI_ANY_ID },
 	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_3,
 		PCI_ANY_ID, PCI_ANY_ID },
+	/* Meteor ~ 2116 */
 	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_1,
 		PCI_ANY_ID, PCI_ANY_ID },
 	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_2,
 		PCI_ANY_ID, PCI_ANY_ID },
+	/* Thunderbolt ~ 2208 */
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_1,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_2,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_3,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_4,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_5,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_6,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_7,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_8,
+		PCI_ANY_ID, PCI_ANY_ID },
 	{0}	/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(pci, scsih_pci_table);
@@ -317,6 +336,47 @@
 }
 
 /**
+ * _scsih_get_sas_address - set the sas_address for given device handle
+ * @handle: device handle
+ * @sas_address: sas address
+ *
+ * Returns 0 success, non-zero when failure
+ */
+static int
+_scsih_get_sas_address(struct MPT2SAS_ADAPTER *ioc, u16 handle,
+    u64 *sas_address)
+{
+	Mpi2SasDevicePage0_t sas_device_pg0;
+	Mpi2ConfigReply_t mpi_reply;
+	u32 ioc_status;
+
+	if (handle <= ioc->sas_hba.num_phys) {
+		*sas_address = ioc->sas_hba.sas_address;
+		return 0;
+	} else
+		*sas_address = 0;
+
+	if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
+	    MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
+		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+		    ioc->name, __FILE__, __LINE__, __func__);
+		return -ENXIO;
+	}
+
+	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+	    MPI2_IOCSTATUS_MASK;
+	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+		printk(MPT2SAS_ERR_FMT "handle(0x%04x), ioc_status(0x%04x)"
+		    "\nfailure at %s:%d/%s()!\n", ioc->name, handle, ioc_status,
+		     __FILE__, __LINE__, __func__);
+		return -EIO;
+	}
+
+	*sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
+	return 0;
+}
+
+/**
  * _scsih_determine_boot_device - determine boot device.
  * @ioc: per adapter object
  * @device: either sas_device or raid_device object
@@ -510,8 +570,6 @@
     struct _sas_device *sas_device)
 {
 	unsigned long flags;
-	u16 handle, parent_handle;
-	u64 sas_address;
 
 	dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle"
 	    "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__,
@@ -521,10 +579,8 @@
 	list_add_tail(&sas_device->list, &ioc->sas_device_list);
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
-	handle = sas_device->handle;
-	parent_handle = sas_device->parent_handle;
-	sas_address = sas_device->sas_address;
-	if (!mpt2sas_transport_port_add(ioc, handle, parent_handle))
+	if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
+	     sas_device->sas_address_parent))
 		_scsih_sas_device_remove(ioc, sas_device);
 }
 
@@ -553,31 +609,6 @@
 }
 
 /**
- * mpt2sas_scsih_expander_find_by_handle - expander device search
- * @ioc: per adapter object
- * @handle: expander handle (assigned by firmware)
- * Context: Calling function should acquire ioc->sas_device_lock
- *
- * This searches for expander device based on handle, then returns the
- * sas_node object.
- */
-struct _sas_node *
-mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
-{
-	struct _sas_node *sas_expander, *r;
-
-	r = NULL;
-	list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
-		if (sas_expander->handle != handle)
-			continue;
-		r = sas_expander;
-		goto out;
-	}
- out:
-	return r;
-}
-
-/**
  * _scsih_raid_device_find_by_id - raid device search
  * @ioc: per adapter object
  * @id: sas device target id
@@ -699,6 +730,31 @@
 }
 
 /**
+ * mpt2sas_scsih_expander_find_by_handle - expander device search
+ * @ioc: per adapter object
+ * @handle: expander handle (assigned by firmware)
+ * Context: Calling function should acquire ioc->sas_device_lock
+ *
+ * This searches for expander device based on handle, then returns the
+ * sas_node object.
+ */
+struct _sas_node *
+mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
+{
+	struct _sas_node *sas_expander, *r;
+
+	r = NULL;
+	list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
+		if (sas_expander->handle != handle)
+			continue;
+		r = sas_expander;
+		goto out;
+	}
+ out:
+	return r;
+}
+
+/**
  * mpt2sas_scsih_expander_find_by_sas_address - expander device search
  * @ioc: per adapter object
  * @sas_address: sas address
@@ -1043,17 +1099,46 @@
  * _scsih_change_queue_depth - setting device queue depth
  * @sdev: scsi device struct
  * @qdepth: requested queue depth
+ * @reason: calling context
  *
  * Returns queue depth.
  */
 static int
-_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
+_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
 {
 	struct Scsi_Host *shost = sdev->host;
 	int max_depth;
 	int tag_type;
+	struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
+	struct MPT2SAS_DEVICE *sas_device_priv_data;
+	struct MPT2SAS_TARGET *sas_target_priv_data;
+	struct _sas_device *sas_device;
+	unsigned long flags;
+
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
 
 	max_depth = shost->can_queue;
+
+	/* limit max device queue for SATA to 32 */
+	sas_device_priv_data = sdev->hostdata;
+	if (!sas_device_priv_data)
+		goto not_sata;
+	sas_target_priv_data = sas_device_priv_data->sas_target;
+	if (!sas_target_priv_data)
+		goto not_sata;
+	if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME))
+		goto not_sata;
+	spin_lock_irqsave(&ioc->sas_device_lock, flags);
+	sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
+	   sas_device_priv_data->sas_target->sas_address);
+	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+	if (sas_device && sas_device->device_info &
+	    MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
+		max_depth = MPT2SAS_SATA_QUEUE_DEPTH;
+
+ not_sata:
+
 	if (!sdev->tagged_supported)
 		max_depth = 1;
 	if (qdepth > max_depth)
@@ -1488,7 +1573,7 @@
 		    r_level, raid_device->handle,
 		    (unsigned long long)raid_device->wwid,
 		    raid_device->num_pds, ds);
-		_scsih_change_queue_depth(sdev, qdepth);
+		_scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
 		return 0;
 	}
 
@@ -1534,7 +1619,7 @@
 			_scsih_display_sata_capabilities(ioc, sas_device, sdev);
 	}
 
-	_scsih_change_queue_depth(sdev, qdepth);
+	_scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
 
 	if (ssp_target)
 		sas_read_port_mode_page(sdev);
@@ -1874,6 +1959,8 @@
 		goto out;
 	}
 
+	mpt2sas_halt_firmware(ioc);
+
 	mutex_lock(&ioc->tm_cmds.mutex);
 	handle = sas_device_priv_data->sas_target->handle;
 	mpt2sas_scsih_issue_tm(ioc, handle, sas_device_priv_data->lun,
@@ -2297,7 +2384,6 @@
 	u16 handle;
 	u16 reason_code;
 	u8 phy_number;
-	u8 link_rate;
 
 	for (i = 0; i < event_data->NumEntries; i++) {
 		handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
@@ -2308,11 +2394,6 @@
 		    MPI2_EVENT_SAS_TOPO_RC_MASK;
 		if (reason_code == MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING)
 			_scsih_block_io_device(ioc, handle);
-		if (reason_code == MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED) {
-			link_rate = event_data->PHY[i].LinkRate >> 4;
-			if (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)
-				_scsih_ublock_io_device(ioc, handle);
-		}
 	}
 }
 
@@ -2349,16 +2430,10 @@
 
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
 	sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
-	if (!sas_device) {
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-		printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
-		    ioc->name, __func__);
-		return;
-	}
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
 	/* skip is hidden raid component */
-	if (sas_device->hidden_raid_component)
+	if (sas_device && sas_device->hidden_raid_component)
 		return;
 
 	smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx);
@@ -2371,18 +2446,31 @@
 		delayed_tr->state = MPT2SAS_REQ_SAS_CNTRL;
 		list_add_tail(&delayed_tr->list,
 		    &ioc->delayed_tr_list);
-		if (sas_device->starget)
+		if (sas_device && sas_device->starget) {
 			dewtprintk(ioc, starget_printk(KERN_INFO,
 			    sas_device->starget, "DELAYED:tr:handle(0x%04x), "
-			    "(open)\n", sas_device->handle));
+			    "(open)\n", handle));
+		} else {
+			dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
+			    "DELAYED:tr:handle(0x%04x), (open)\n",
+			    ioc->name, handle));
+		}
 		return;
 	}
 
-	if (sas_device->starget && sas_device->starget->hostdata) {
-		sas_target_priv_data = sas_device->starget->hostdata;
-		sas_target_priv_data->tm_busy = 1;
-		dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget,
-		    "tr:handle(0x%04x), (open)\n", sas_device->handle));
+	if (sas_device) {
+		sas_device->state |= MPTSAS_STATE_TR_SEND;
+		sas_device->state |= MPT2SAS_REQ_SAS_CNTRL;
+		if (sas_device->starget && sas_device->starget->hostdata) {
+			sas_target_priv_data = sas_device->starget->hostdata;
+			sas_target_priv_data->tm_busy = 1;
+			dewtprintk(ioc, starget_printk(KERN_INFO,
+			    sas_device->starget, "tr:handle(0x%04x), (open)\n",
+			    handle));
+		}
+	} else {
+		dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
+		    "tr:handle(0x%04x), (open)\n", ioc->name, handle));
 	}
 
 	mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
@@ -2390,8 +2478,6 @@
 	mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
 	mpi_request->DevHandle = cpu_to_le16(handle);
 	mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
-	sas_device->state |= MPTSAS_STATE_TR_SEND;
-	sas_device->state |= MPT2SAS_REQ_SAS_CNTRL;
 	mpt2sas_base_put_smid_hi_priority(ioc, smid);
 }
 
@@ -2426,21 +2512,25 @@
 
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
 	sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
-	if (!sas_device) {
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-		printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
-		    ioc->name, __func__);
-		return 1;
-	}
-	sas_device->state |= MPTSAS_STATE_CNTRL_COMPLETE;
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
-	if (sas_device->starget)
-		dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget,
+	if (sas_device) {
+		sas_device->state |= MPTSAS_STATE_CNTRL_COMPLETE;
+		if (sas_device->starget)
+			dewtprintk(ioc, starget_printk(KERN_INFO,
+			    sas_device->starget,
+			    "sc_complete:handle(0x%04x), "
+			    "ioc_status(0x%04x), loginfo(0x%08x)\n",
+			    handle, le16_to_cpu(mpi_reply->IOCStatus),
+			    le32_to_cpu(mpi_reply->IOCLogInfo)));
+	} else {
+		dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
 		    "sc_complete:handle(0x%04x), "
 		    "ioc_status(0x%04x), loginfo(0x%08x)\n",
-		    handle, le16_to_cpu(mpi_reply->IOCStatus),
+		    ioc->name, handle, le16_to_cpu(mpi_reply->IOCStatus),
 		    le32_to_cpu(mpi_reply->IOCLogInfo)));
+	}
+
 	return 1;
 }
 
@@ -2478,28 +2568,33 @@
 	handle = le16_to_cpu(mpi_reply->DevHandle);
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
 	sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
-	if (!sas_device) {
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-		printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
-		    ioc->name, __func__);
-		return 1;
-	}
-	sas_device->state |= MPTSAS_STATE_TR_COMPLETE;
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
-	if (sas_device->starget)
-		dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget,
-		    "tr_complete:handle(0x%04x), (%s) ioc_status(0x%04x), "
-		    "loginfo(0x%08x), completed(%d)\n",
-		    sas_device->handle, (sas_device->state &
-		    MPT2SAS_REQ_SAS_CNTRL) ? "open" : "active",
-		    le16_to_cpu(mpi_reply->IOCStatus),
+	if (sas_device) {
+		sas_device->state |= MPTSAS_STATE_TR_COMPLETE;
+		if (sas_device->starget) {
+			dewtprintk(ioc, starget_printk(KERN_INFO,
+			    sas_device->starget, "tr_complete:handle(0x%04x), "
+			    "(%s) ioc_status(0x%04x), loginfo(0x%08x), "
+			    "completed(%d)\n", sas_device->handle,
+			    (sas_device->state & MPT2SAS_REQ_SAS_CNTRL) ?
+			    "open" : "active",
+			    le16_to_cpu(mpi_reply->IOCStatus),
+			    le32_to_cpu(mpi_reply->IOCLogInfo),
+			    le32_to_cpu(mpi_reply->TerminationCount)));
+			if (sas_device->starget->hostdata) {
+				sas_target_priv_data =
+				    sas_device->starget->hostdata;
+				sas_target_priv_data->tm_busy = 0;
+			}
+		}
+	} else {
+		dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
+		    "tr_complete:handle(0x%04x), (open) ioc_status(0x%04x), "
+		    "loginfo(0x%08x), completed(%d)\n", ioc->name,
+		    handle, le16_to_cpu(mpi_reply->IOCStatus),
 		    le32_to_cpu(mpi_reply->IOCLogInfo),
 		    le32_to_cpu(mpi_reply->TerminationCount)));
-
-	if (sas_device->starget && sas_device->starget->hostdata) {
-		sas_target_priv_data = sas_device->starget->hostdata;
-		sas_target_priv_data->tm_busy = 0;
 	}
 
 	if (!list_empty(&ioc->delayed_tr_list)) {
@@ -2514,8 +2609,7 @@
 	} else
 		rc = 1;
 
-
-	if (!(sas_device->state & MPT2SAS_REQ_SAS_CNTRL))
+	if (sas_device && !(sas_device->state & MPT2SAS_REQ_SAS_CNTRL))
 		return rc;
 
 	if (ioc->shost_recovery) {
@@ -2531,12 +2625,14 @@
 		return rc;
 	}
 
+	if (sas_device)
+		sas_device->state |= MPTSAS_STATE_CNTRL_SEND;
+
 	mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl);
 	memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
 	mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
 	mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
 	mpi_request->DevHandle = mpi_reply->DevHandle;
-	sas_device->state |= MPTSAS_STATE_CNTRL_SEND;
 	mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl);
 	return rc;
 }
@@ -2678,8 +2774,6 @@
 	else
 		return;
 
-	mpi_request->EEDPBlockSize = scmd->device->sector_size;
-
 	switch (prot_type) {
 	case SCSI_PROT_DIF_TYPE1:
 
@@ -2687,8 +2781,7 @@
 		* enable ref/guard checking
 		* auto increment ref tag
 		*/
-		mpi_request->EEDPFlags = eedp_flags |
-		    MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG |
+		eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG |
 		    MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG |
 		    MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
 		mpi_request->CDB.EEDP32.PrimaryReferenceTag =
@@ -2701,11 +2794,11 @@
 		/*
 		* enable guard checking
 		*/
-		mpi_request->EEDPFlags = eedp_flags |
-		    MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
-
+		eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
 		break;
 	}
+	mpi_request->EEDPBlockSize = cpu_to_le32(scmd->device->sector_size);
+	mpi_request->EEDPFlags = cpu_to_le16(eedp_flags);
 }
 
 /**
@@ -2788,7 +2881,7 @@
 	}
 
 	/* see if we are busy with task managment stuff */
-	if (sas_target_priv_data->tm_busy)
+	if (sas_device_priv_data->block || sas_target_priv_data->tm_busy)
 		return SCSI_MLQUEUE_DEVICE_BUSY;
 	else if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress)
 		return SCSI_MLQUEUE_HOST_BUSY;
@@ -2842,7 +2935,7 @@
 	mpi_request->MsgFlags = MPI2_SCSIIO_MSGFLAGS_SYSTEM_SENSE_ADDR;
 	mpi_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE;
 	mpi_request->SenseBufferLowAddress =
-	    (u32)mpt2sas_base_get_sense_buffer_dma(ioc, smid);
+	    mpt2sas_base_get_sense_buffer_dma(ioc, smid);
 	mpi_request->SGLOffset0 = offsetof(Mpi2SCSIIORequest_t, SGL) / 4;
 	mpi_request->SGLFlags = cpu_to_le16(MPI2_SCSIIO_SGLFLAGS_TYPE_MPI +
 	    MPI2_SCSIIO_SGLFLAGS_SYSTEM_ADDR);
@@ -2894,7 +2987,7 @@
 
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
 /**
- * _scsih_scsi_ioc_info - translated non-succesfull SCSI_IO request
+ * _scsih_scsi_ioc_info - translated non-successfull SCSI_IO request
  * @ioc: per adapter object
  * @scmd: pointer to scsi command object
  * @mpi_reply: reply mf payload returned from firmware
@@ -3059,7 +3152,7 @@
 	if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
 		response_info = le32_to_cpu(mpi_reply->ResponseInfo);
 		response_bytes = (u8 *)&response_info;
-		_scsih_response_code(ioc, response_bytes[3]);
+		_scsih_response_code(ioc, response_bytes[0]);
 	}
 }
 #endif
@@ -3177,7 +3270,7 @@
 	u8 scsi_status;
 	u32 log_info;
 	struct MPT2SAS_DEVICE *sas_device_priv_data;
-	u32 response_code;
+	u32 response_code = 0;
 
 	mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
 	scmd = _scsih_scsi_lookup_get(ioc, smid);
@@ -3199,16 +3292,16 @@
 	}
 
 	/* turning off TLR */
+	scsi_state = mpi_reply->SCSIState;
+	if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID)
+		response_code =
+		    le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF;
 	if (!sas_device_priv_data->tlr_snoop_check) {
 		sas_device_priv_data->tlr_snoop_check++;
-		if (sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) {
-			response_code = (le32_to_cpu(mpi_reply->ResponseInfo)
-			    >> 24);
-			if (response_code ==
-			    MPI2_SCSITASKMGMT_RSP_INVALID_FRAME)
-				sas_device_priv_data->flags &=
-				    ~MPT_DEVICE_TLR_ON;
-		}
+		if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) &&
+		    response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME)
+			sas_device_priv_data->flags &=
+			    ~MPT_DEVICE_TLR_ON;
 	}
 
 	xfer_cnt = le32_to_cpu(mpi_reply->TransferCount);
@@ -3219,7 +3312,6 @@
 	else
 		log_info = 0;
 	ioc_status &= MPI2_IOCSTATUS_MASK;
-	scsi_state = mpi_reply->SCSIState;
 	scsi_status = mpi_reply->SCSIStatus;
 
 	if (ioc_status == MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
@@ -3255,10 +3347,9 @@
 
 	case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
 		if (sas_device_priv_data->block) {
-			scmd->result = (DID_BUS_BUSY << 16);
-			break;
+			scmd->result = DID_TRANSPORT_DISRUPTED << 16;
+			goto out;
 		}
-
 	case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
 	case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
 		scmd->result = DID_RESET << 16;
@@ -3304,8 +3395,10 @@
 	case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR:
 	case MPI2_IOCSTATUS_SUCCESS:
 		scmd->result = (DID_OK << 16) | scsi_status;
-		if (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED |
-		     MPI2_SCSI_STATE_NO_SCSI_STATUS))
+		if (response_code ==
+		    MPI2_SCSITASKMGMT_RSP_INVALID_FRAME ||
+		    (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED |
+		     MPI2_SCSI_STATE_NO_SCSI_STATUS)))
 			scmd->result = DID_SOFT_ERROR << 16;
 		else if (scsi_state & MPI2_SCSI_STATE_TERMINATED)
 			scmd->result = DID_RESET << 16;
@@ -3344,7 +3437,6 @@
 /**
  * _scsih_sas_host_refresh - refreshing sas host object contents
  * @ioc: per adapter object
- * @update: update link information
  * Context: user
  *
  * During port enable, fw will send topology events for every device. Its
@@ -3354,13 +3446,14 @@
  * Return nothing.
  */
 static void
-_scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc, u8 update)
+_scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc)
 {
 	u16 sz;
 	u16 ioc_status;
 	int i;
 	Mpi2ConfigReply_t mpi_reply;
 	Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL;
+	u16 attached_handle;
 
 	dtmprintk(ioc, printk(MPT2SAS_INFO_FMT
 	    "updating handles for sas_host(0x%016llx)\n",
@@ -3374,27 +3467,24 @@
 		    ioc->name, __FILE__, __LINE__, __func__);
 		return;
 	}
-	if (!(mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
-	    sas_iounit_pg0, sz))) {
-		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-		    MPI2_IOCSTATUS_MASK;
-		if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
-			goto out;
-		for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
-			ioc->sas_hba.phy[i].handle =
-			    le16_to_cpu(sas_iounit_pg0->PhyData[i].
-				ControllerDevHandle);
-			if (update)
-				mpt2sas_transport_update_links(
-				    ioc,
-				    ioc->sas_hba.phy[i].handle,
-				    le16_to_cpu(sas_iounit_pg0->PhyData[i].
-				    AttachedDevHandle), i,
-				    sas_iounit_pg0->PhyData[i].
-				    NegotiatedLinkRate >> 4);
-		}
-	}
 
+	if ((mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
+	    sas_iounit_pg0, sz)) != 0)
+		goto out;
+	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
+	if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
+		goto out;
+	for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
+		if (i == 0)
+			ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0->
+			    PhyData[0].ControllerDevHandle);
+		ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle;
+		attached_handle = le16_to_cpu(sas_iounit_pg0->PhyData[i].
+		    AttachedDevHandle);
+		mpt2sas_transport_update_links(ioc, ioc->sas_hba.sas_address,
+		    attached_handle, i, sas_iounit_pg0->PhyData[i].
+		    NegotiatedLinkRate >> 4);
+	}
  out:
 	kfree(sas_iounit_pg0);
 }
@@ -3507,19 +3597,21 @@
 			    ioc->name, __FILE__, __LINE__, __func__);
 			goto out;
 		}
-		ioc->sas_hba.phy[i].handle =
-		    le16_to_cpu(sas_iounit_pg0->PhyData[i].ControllerDevHandle);
+
+		if (i == 0)
+			ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0->
+			    PhyData[0].ControllerDevHandle);
+		ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle;
 		ioc->sas_hba.phy[i].phy_id = i;
 		mpt2sas_transport_add_host_phy(ioc, &ioc->sas_hba.phy[i],
 		    phy_pg0, ioc->sas_hba.parent_dev);
 	}
 	if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
-	    MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, ioc->sas_hba.phy[0].handle))) {
+	    MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, ioc->sas_hba.handle))) {
 		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
 		    ioc->name, __FILE__, __LINE__, __func__);
 		goto out;
 	}
-	ioc->sas_hba.handle = le16_to_cpu(sas_device_pg0.DevHandle);
 	ioc->sas_hba.enclosure_handle =
 	    le16_to_cpu(sas_device_pg0.EnclosureHandle);
 	ioc->sas_hba.sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
@@ -3562,7 +3654,7 @@
 	Mpi2SasEnclosurePage0_t enclosure_pg0;
 	u32 ioc_status;
 	u16 parent_handle;
-	__le64 sas_address;
+	__le64 sas_address, sas_address_parent = 0;
 	int i;
 	unsigned long flags;
 	struct _sas_port *mpt2sas_port = NULL;
@@ -3591,10 +3683,16 @@
 
 	/* handle out of order topology events */
 	parent_handle = le16_to_cpu(expander_pg0.ParentDevHandle);
-	if (parent_handle >= ioc->sas_hba.num_phys) {
+	if (_scsih_get_sas_address(ioc, parent_handle, &sas_address_parent)
+	    != 0) {
+		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+		    ioc->name, __FILE__, __LINE__, __func__);
+		return -1;
+	}
+	if (sas_address_parent != ioc->sas_hba.sas_address) {
 		spin_lock_irqsave(&ioc->sas_node_lock, flags);
-		sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc,
-		    parent_handle);
+		sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
+		    sas_address_parent);
 		spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
 		if (!sas_expander) {
 			rc = _scsih_expander_add(ioc, parent_handle);
@@ -3622,14 +3720,12 @@
 
 	sas_expander->handle = handle;
 	sas_expander->num_phys = expander_pg0.NumPhys;
-	sas_expander->parent_handle = parent_handle;
-	sas_expander->enclosure_handle =
-	    le16_to_cpu(expander_pg0.EnclosureHandle);
+	sas_expander->sas_address_parent = sas_address_parent;
 	sas_expander->sas_address = sas_address;
 
 	printk(MPT2SAS_INFO_FMT "expander_add: handle(0x%04x),"
 	    " parent(0x%04x), sas_addr(0x%016llx), phys(%d)\n", ioc->name,
-	    handle, sas_expander->parent_handle, (unsigned long long)
+	    handle, parent_handle, (unsigned long long)
 	    sas_expander->sas_address, sas_expander->num_phys);
 
 	if (!sas_expander->num_phys)
@@ -3645,7 +3741,7 @@
 
 	INIT_LIST_HEAD(&sas_expander->sas_port_list);
 	mpt2sas_port = mpt2sas_transport_port_add(ioc, handle,
-	    sas_expander->parent_handle);
+	    sas_address_parent);
 	if (!mpt2sas_port) {
 		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
 		    ioc->name, __FILE__, __LINE__, __func__);
@@ -3691,20 +3787,54 @@
 
 	if (mpt2sas_port)
 		mpt2sas_transport_port_remove(ioc, sas_expander->sas_address,
-		    sas_expander->parent_handle);
+		    sas_address_parent);
 	kfree(sas_expander);
 	return rc;
 }
 
 /**
+ * _scsih_done -  scsih callback handler.
+ * @ioc: per adapter object
+ * @smid: system request message index
+ * @msix_index: MSIX table index supplied by the OS
+ * @reply: reply message frame(lower 32bit addr)
+ *
+ * Callback handler when sending internal generated message frames.
+ * The callback index passed is `ioc->scsih_cb_idx`
+ *
+ * Return 1 meaning mf should be freed from _base_interrupt
+ *        0 means the mf is freed from this function.
+ */
+static u8
+_scsih_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
+{
+	MPI2DefaultReply_t *mpi_reply;
+
+	mpi_reply =  mpt2sas_base_get_reply_virt_addr(ioc, reply);
+	if (ioc->scsih_cmds.status == MPT2_CMD_NOT_USED)
+		return 1;
+	if (ioc->scsih_cmds.smid != smid)
+		return 1;
+	ioc->scsih_cmds.status |= MPT2_CMD_COMPLETE;
+	if (mpi_reply) {
+		memcpy(ioc->scsih_cmds.reply, mpi_reply,
+		    mpi_reply->MsgLength*4);
+		ioc->scsih_cmds.status |= MPT2_CMD_REPLY_VALID;
+	}
+	ioc->scsih_cmds.status &= ~MPT2_CMD_PENDING;
+	complete(&ioc->scsih_cmds.done);
+	return 1;
+}
+
+/**
  * _scsih_expander_remove - removing expander object
  * @ioc: per adapter object
- * @handle: expander handle
+ * @sas_address: expander sas_address
  *
  * Return nothing.
  */
 static void
-_scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u16 handle)
+_scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address)
 {
 	struct _sas_node *sas_expander;
 	unsigned long flags;
@@ -3713,7 +3843,8 @@
 		return;
 
 	spin_lock_irqsave(&ioc->sas_node_lock, flags);
-	sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, handle);
+	sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
+	    sas_address);
 	spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
 	_scsih_expander_node_remove(ioc, sas_expander);
 }
@@ -3805,8 +3936,11 @@
 	}
 
 	sas_device->handle = handle;
-	sas_device->parent_handle =
-	    le16_to_cpu(sas_device_pg0.ParentDevHandle);
+	if (_scsih_get_sas_address(ioc, le16_to_cpu
+		(sas_device_pg0.ParentDevHandle),
+		&sas_device->sas_address_parent) != 0)
+		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+		    ioc->name, __FILE__, __LINE__, __func__);
 	sas_device->enclosure_handle =
 	    le16_to_cpu(sas_device_pg0.EnclosureHandle);
 	sas_device->slot =
@@ -3836,43 +3970,39 @@
 /**
  * _scsih_remove_device -  removing sas device object
  * @ioc: per adapter object
- * @handle: sas device handle
+ * @sas_device: the sas_device object
  *
  * Return nothing.
  */
 static void
-_scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
+_scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, struct _sas_device
+    *sas_device)
 {
 	struct MPT2SAS_TARGET *sas_target_priv_data;
-	struct _sas_device *sas_device;
-	unsigned long flags;
 	Mpi2SasIoUnitControlReply_t mpi_reply;
 	Mpi2SasIoUnitControlRequest_t mpi_request;
-	u16 device_handle;
+	u16 device_handle, handle;
 
-	/* lookup sas_device */
-	spin_lock_irqsave(&ioc->sas_device_lock, flags);
-	sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
-	if (!sas_device) {
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+	if (!sas_device)
 		return;
-	}
 
-	dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: handle"
-	    "(0x%04x)\n", ioc->name, __func__, handle));
+	handle = sas_device->handle;
+	dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: handle(0x%04x),"
+	    " sas_addr(0x%016llx)\n", ioc->name, __func__, handle,
+	    (unsigned long long) sas_device->sas_address));
 
 	if (sas_device->starget && sas_device->starget->hostdata) {
 		sas_target_priv_data = sas_device->starget->hostdata;
 		sas_target_priv_data->deleted = 1;
 	}
-	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
-	if (ioc->remove_host)
+	if (ioc->remove_host || ioc->shost_recovery || !handle)
 		goto out;
 
 	if ((sas_device->state & MPTSAS_STATE_TR_COMPLETE)) {
 		dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip "
-		   "target_reset handle(0x%04x)\n", ioc->name, handle));
+		   "target_reset handle(0x%04x)\n", ioc->name,
+		   handle));
 		goto skip_tr;
 	}
 
@@ -3925,10 +4055,10 @@
 	_scsih_ublock_io_device(ioc, handle);
 
 	mpt2sas_transport_port_remove(ioc, sas_device->sas_address,
-	    sas_device->parent_handle);
+	    sas_device->sas_address_parent);
 
 	printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr"
-	    "(0x%016llx)\n", ioc->name, sas_device->handle,
+	    "(0x%016llx)\n", ioc->name, handle,
 	    (unsigned long long) sas_device->sas_address);
 	_scsih_sas_device_remove(ioc, sas_device);
 
@@ -3952,7 +4082,7 @@
 	u16 reason_code;
 	u8 phy_number;
 	char *status_str = NULL;
-	char link_rate[25];
+	u8 link_rate, prev_link_rate;
 
 	switch (event_data->ExpStatus) {
 	case MPI2_EVENT_SAS_TOPO_ES_ADDED:
@@ -3962,6 +4092,7 @@
 		status_str = "remove";
 		break;
 	case MPI2_EVENT_SAS_TOPO_ES_RESPONDING:
+	case 0:
 		status_str =  "responding";
 		break;
 	case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING:
@@ -3987,30 +4118,30 @@
 		    MPI2_EVENT_SAS_TOPO_RC_MASK;
 		switch (reason_code) {
 		case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
-			snprintf(link_rate, 25, ": add, link(0x%02x)",
-			    (event_data->PHY[i].LinkRate >> 4));
-			status_str = link_rate;
+			status_str = "target add";
 			break;
 		case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
-			status_str = ": remove";
+			status_str = "target remove";
 			break;
 		case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING:
-			status_str = ": remove_delay";
+			status_str = "delay target remove";
 			break;
 		case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
-			snprintf(link_rate, 25, ": link(0x%02x)",
-			    (event_data->PHY[i].LinkRate >> 4));
-			status_str = link_rate;
+			status_str = "link rate change";
 			break;
 		case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE:
-			status_str = ": responding";
+			status_str = "target responding";
 			break;
 		default:
-			status_str = ": unknown";
+			status_str = "unknown";
 			break;
 		}
-		printk(KERN_DEBUG "\tphy(%02d), attached_handle(0x%04x)%s\n",
-		    phy_number, handle, status_str);
+		link_rate = event_data->PHY[i].LinkRate >> 4;
+		prev_link_rate = event_data->PHY[i].LinkRate & 0xF;
+		printk(KERN_DEBUG "\tphy(%02d), attached_handle(0x%04x): %s:"
+		    " link rate: new(0x%02x), old(0x%02x)\n", phy_number,
+		    handle, status_str, link_rate, prev_link_rate);
+
 	}
 }
 #endif
@@ -4031,8 +4162,10 @@
 	u16 reason_code;
 	u8 phy_number;
 	struct _sas_node *sas_expander;
+	struct _sas_device *sas_device;
+	u64 sas_address;
 	unsigned long flags;
-	u8 link_rate_;
+	u8 link_rate, prev_link_rate;
 	Mpi2EventDataSasTopologyChangeList_t *event_data = fw_event->event_data;
 
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
@@ -4040,10 +4173,13 @@
 		_scsih_sas_topology_change_event_debug(ioc, event_data);
 #endif
 
+	if (ioc->shost_recovery)
+		return;
+
 	if (!ioc->sas_hba.num_phys)
 		_scsih_sas_host_add(ioc);
 	else
-		_scsih_sas_host_refresh(ioc, 0);
+		_scsih_sas_host_refresh(ioc);
 
 	if (fw_event->ignore) {
 		dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "ignoring expander "
@@ -4058,6 +4194,17 @@
 		if (_scsih_expander_add(ioc, parent_handle) != 0)
 			return;
 
+	spin_lock_irqsave(&ioc->sas_node_lock, flags);
+	sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc,
+	    parent_handle);
+	spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
+	if (sas_expander)
+		sas_address = sas_expander->sas_address;
+	else if (parent_handle < ioc->sas_hba.num_phys)
+		sas_address = ioc->sas_hba.sas_address;
+	else
+		return;
+
 	/* handle siblings events */
 	for (i = 0; i < event_data->NumEntries; i++) {
 		if (fw_event->ignore) {
@@ -4077,48 +4224,47 @@
 		handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
 		if (!handle)
 			continue;
-		link_rate_ = event_data->PHY[i].LinkRate >> 4;
+		link_rate = event_data->PHY[i].LinkRate >> 4;
+		prev_link_rate = event_data->PHY[i].LinkRate & 0xF;
 		switch (reason_code) {
 		case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
+
+			if (link_rate == prev_link_rate)
+				break;
+
+			mpt2sas_transport_update_links(ioc, sas_address,
+			    handle, phy_number, link_rate);
+
+			if (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)
+				_scsih_ublock_io_device(ioc, handle);
+			break;
 		case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
-			if (!parent_handle) {
-				if (phy_number < ioc->sas_hba.num_phys)
-					mpt2sas_transport_update_links(
-					ioc,
-					ioc->sas_hba.phy[phy_number].handle,
-					handle, phy_number, link_rate_);
-			} else {
-				spin_lock_irqsave(&ioc->sas_node_lock, flags);
-				sas_expander =
-				    mpt2sas_scsih_expander_find_by_handle(ioc,
-					parent_handle);
-				spin_unlock_irqrestore(&ioc->sas_node_lock,
-				    flags);
-				if (sas_expander) {
-					if (phy_number < sas_expander->num_phys)
-						mpt2sas_transport_update_links(
-						ioc,
-						sas_expander->
-						phy[phy_number].handle,
-						handle, phy_number,
-						link_rate_);
-				}
-			}
-			if (reason_code == MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED) {
-				if (link_rate_ < MPI2_SAS_NEG_LINK_RATE_1_5)
-					break;
-				_scsih_add_device(ioc, handle, phy_number, 0);
-			}
+
+			mpt2sas_transport_update_links(ioc, sas_address,
+			    handle, phy_number, link_rate);
+
+			_scsih_add_device(ioc, handle, phy_number, 0);
 			break;
 		case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
-			_scsih_remove_device(ioc, handle);
+
+			spin_lock_irqsave(&ioc->sas_device_lock, flags);
+			sas_device = _scsih_sas_device_find_by_handle(ioc,
+			    handle);
+			if (!sas_device) {
+				spin_unlock_irqrestore(&ioc->sas_device_lock,
+				    flags);
+				break;
+			}
+			spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+			_scsih_remove_device(ioc, sas_device);
 			break;
 		}
 	}
 
 	/* handle expander removal */
-	if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING)
-		_scsih_expander_remove(ioc, parent_handle);
+	if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING &&
+	    sas_expander)
+		_scsih_expander_remove(ioc, sas_address);
 
 }
 
@@ -4170,6 +4316,12 @@
 	case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION:
 		reason_str = "internal async notification";
 		break;
+	case MPI2_EVENT_SAS_DEV_STAT_RC_EXPANDER_REDUCED_FUNCTIONALITY:
+		reason_str = "expander reduced functionality";
+		break;
+	case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_EXPANDER_REDUCED_FUNCTIONALITY:
+		reason_str = "expander reduced functionality complete";
+		break;
 	default:
 		reason_str = "unknown reason";
 		break;
@@ -4197,11 +4349,43 @@
 _scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc,
     struct fw_event_work *fw_event)
 {
+	struct MPT2SAS_TARGET *target_priv_data;
+	struct _sas_device *sas_device;
+	__le64 sas_address;
+	unsigned long flags;
+	Mpi2EventDataSasDeviceStatusChange_t *event_data =
+	    fw_event->event_data;
+
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
 	if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
 		_scsih_sas_device_status_change_event_debug(ioc,
-		     fw_event->event_data);
+		     event_data);
 #endif
+
+	if (!(event_data->ReasonCode ==
+	    MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET &&
+	   event_data->ReasonCode ==
+	    MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET))
+		return;
+
+	spin_lock_irqsave(&ioc->sas_device_lock, flags);
+	sas_address = le64_to_cpu(event_data->SASAddress);
+	sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
+	    sas_address);
+	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+
+	if (!sas_device || !sas_device->starget)
+		return;
+
+	target_priv_data = sas_device->starget->hostdata;
+	if (!target_priv_data)
+		return;
+
+	if (event_data->ReasonCode ==
+	    MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET)
+		target_priv_data->tm_busy = 1;
+	else
+		target_priv_data->tm_busy = 0;
 }
 
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
@@ -4281,6 +4465,7 @@
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
 	Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data;
 #endif
+	u16 ioc_status;
 	dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "broadcast primative: "
 	    "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum,
 	    event_data->PortWidth));
@@ -4314,8 +4499,9 @@
 		mpt2sas_scsih_issue_tm(ioc, handle, lun,
 		    MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30);
 		ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
-
-		if ((mpi_reply->IOCStatus == MPI2_IOCSTATUS_SUCCESS) &&
+		ioc_status = le16_to_cpu(mpi_reply->IOCStatus)
+		    & MPI2_IOCSTATUS_MASK;
+		if ((ioc_status == MPI2_IOCSTATUS_SUCCESS) &&
 		    (mpi_reply->ResponseCode ==
 		     MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
 		     mpi_reply->ResponseCode ==
@@ -4570,7 +4756,7 @@
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 	if (!sas_device)
 		return;
-	_scsih_remove_device(ioc, handle);
+	_scsih_remove_device(ioc, sas_device);
 }
 
 /**
@@ -4591,6 +4777,8 @@
 	Mpi2ConfigReply_t mpi_reply;
 	Mpi2SasDevicePage0_t sas_device_pg0;
 	u32 ioc_status;
+	u64 sas_address;
+	u16 parent_handle;
 
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
 	sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
@@ -4615,9 +4803,10 @@
 		return;
 	}
 
-	mpt2sas_transport_update_links(ioc,
-	    le16_to_cpu(sas_device_pg0.ParentDevHandle),
-	    handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
+	parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
+	if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address))
+		mpt2sas_transport_update_links(ioc, sas_address, handle,
+		    sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
 
 	_scsih_add_device(ioc, handle, 0, 1);
 }
@@ -4857,7 +5046,7 @@
 _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
     struct fw_event_work *fw_event)
 {
-	u16 handle;
+	u16 handle, parent_handle;
 	u32 state;
 	struct _sas_device *sas_device;
 	unsigned long flags;
@@ -4865,6 +5054,7 @@
 	Mpi2SasDevicePage0_t sas_device_pg0;
 	u32 ioc_status;
 	Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data;
+	u64 sas_address;
 
 	if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED)
 		return;
@@ -4906,9 +5096,10 @@
 			return;
 		}
 
-		mpt2sas_transport_update_links(ioc,
-		    le16_to_cpu(sas_device_pg0.ParentDevHandle),
-		    handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
+		parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
+		if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address))
+			mpt2sas_transport_update_links(ioc, sas_address, handle,
+			    sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
 
 		_scsih_add_device(ioc, handle, 0, 1);
 
@@ -4948,11 +5139,17 @@
 	case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK:
 		reason_str = "consistency check";
 		break;
-	default:
-		reason_str = "unknown reason";
+	case MPI2_EVENT_IR_RAIDOP_BACKGROUND_INIT:
+		reason_str = "background init";
+		break;
+	case MPI2_EVENT_IR_RAIDOP_MAKE_DATA_CONSISTENT:
+		reason_str = "make data consistent";
 		break;
 	}
 
+	if (!reason_str)
+		return;
+
 	printk(MPT2SAS_INFO_FMT "raid operational status: (%s)"
 	    "\thandle(0x%04x), percent complete(%d)\n",
 	    ioc->name, reason_str,
@@ -5252,18 +5449,23 @@
 {
 	struct _sas_node *sas_expander;
 	unsigned long flags;
+	int i;
 
 	spin_lock_irqsave(&ioc->sas_node_lock, flags);
 	list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
-		if (sas_expander->sas_address == sas_address) {
-			sas_expander->responding = 1;
-			if (sas_expander->handle != handle) {
-				printk(KERN_INFO "old handle(0x%04x)\n",
-				    sas_expander->handle);
-				sas_expander->handle = handle;
-			}
+		if (sas_expander->sas_address != sas_address)
+			continue;
+		sas_expander->responding = 1;
+		if (sas_expander->handle == handle)
 			goto out;
-		}
+		printk(KERN_INFO "\texpander(0x%016llx): handle changed"
+		    " from(0x%04x) to (0x%04x)!!!\n",
+		    (unsigned long long)sas_expander->sas_address,
+		    sas_expander->handle, handle);
+		sas_expander->handle = handle;
+		for (i = 0 ; i < sas_expander->num_phys ; i++)
+			sas_expander->phy[i].handle = handle;
+		goto out;
 	}
  out:
 	spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
@@ -5340,7 +5542,9 @@
 			    (unsigned long long)
 			    sas_device->enclosure_logical_id,
 			    sas_device->slot);
-		_scsih_remove_device(ioc, sas_device->handle);
+		/* invalidate the device handle */
+		sas_device->handle = 0;
+		_scsih_remove_device(ioc, sas_device);
 	}
 
 	list_for_each_entry_safe(raid_device, raid_device_next,
@@ -5366,7 +5570,7 @@
 			sas_expander->responding = 0;
 			continue;
 		}
-		_scsih_expander_remove(ioc, sas_expander->handle);
+		_scsih_expander_remove(ioc, sas_expander->sas_address);
 		goto retry_expander_search;
 	}
 }
@@ -5406,7 +5610,7 @@
 	case MPT2_IOC_DONE_RESET:
 		dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
 		    "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
-		_scsih_sas_host_refresh(ioc, 0);
+		_scsih_sas_host_refresh(ioc);
 		_scsih_search_responding_sas_devices(ioc);
 		_scsih_search_responding_raid_devices(ioc);
 		_scsih_search_responding_expanders(ioc);
@@ -5646,7 +5850,7 @@
 			spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 			if (!sas_device)
 				continue;
-			_scsih_remove_device(ioc, sas_device->handle);
+			_scsih_remove_device(ioc, sas_device);
 			if (ioc->shost_recovery)
 				return;
 			goto retry_device_search;
@@ -5669,7 +5873,8 @@
 			spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
 			if (!expander_sibling)
 				continue;
-			_scsih_expander_remove(ioc, expander_sibling->handle);
+			_scsih_expander_remove(ioc,
+			    expander_sibling->sas_address);
 			if (ioc->shost_recovery)
 				return;
 			goto retry_expander_search;
@@ -5677,7 +5882,7 @@
 	}
 
 	mpt2sas_transport_port_remove(ioc, sas_expander->sas_address,
-	    sas_expander->parent_handle);
+	    sas_expander->sas_address_parent);
 
 	printk(MPT2SAS_INFO_FMT "expander_remove: handle"
 	   "(0x%04x), sas_addr(0x%016llx)\n", ioc->name,
@@ -5690,9 +5895,99 @@
 }
 
 /**
+ * _scsih_ir_shutdown - IR shutdown notification
+ * @ioc: per adapter object
+ *
+ * Sending RAID Action to alert the Integrated RAID subsystem of the IOC that
+ * the host system is shutting down.
+ *
+ * Return nothing.
+ */
+static void
+_scsih_ir_shutdown(struct MPT2SAS_ADAPTER *ioc)
+{
+	Mpi2RaidActionRequest_t *mpi_request;
+	Mpi2RaidActionReply_t *mpi_reply;
+	u16 smid;
+
+	/* is IR firmware build loaded ? */
+	if (!ioc->ir_firmware)
+		return;
+
+	/* are there any volumes ? */
+	if (list_empty(&ioc->raid_device_list))
+		return;
+
+	mutex_lock(&ioc->scsih_cmds.mutex);
+
+	if (ioc->scsih_cmds.status != MPT2_CMD_NOT_USED) {
+		printk(MPT2SAS_ERR_FMT "%s: scsih_cmd in use\n",
+		    ioc->name, __func__);
+		goto out;
+	}
+	ioc->scsih_cmds.status = MPT2_CMD_PENDING;
+
+	smid = mpt2sas_base_get_smid(ioc, ioc->scsih_cb_idx);
+	if (!smid) {
+		printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
+		    ioc->name, __func__);
+		ioc->scsih_cmds.status = MPT2_CMD_NOT_USED;
+		goto out;
+	}
+
+	mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
+	ioc->scsih_cmds.smid = smid;
+	memset(mpi_request, 0, sizeof(Mpi2RaidActionRequest_t));
+
+	mpi_request->Function = MPI2_FUNCTION_RAID_ACTION;
+	mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED;
+
+	printk(MPT2SAS_INFO_FMT "IR shutdown (sending)\n", ioc->name);
+	init_completion(&ioc->scsih_cmds.done);
+	mpt2sas_base_put_smid_default(ioc, smid);
+	wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ);
+
+	if (!(ioc->scsih_cmds.status & MPT2_CMD_COMPLETE)) {
+		printk(MPT2SAS_ERR_FMT "%s: timeout\n",
+		    ioc->name, __func__);
+		goto out;
+	}
+
+	if (ioc->scsih_cmds.status & MPT2_CMD_REPLY_VALID) {
+		mpi_reply = ioc->scsih_cmds.reply;
+
+		printk(MPT2SAS_INFO_FMT "IR shutdown (complete): "
+		    "ioc_status(0x%04x), loginfo(0x%08x)\n",
+		    ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
+		    le32_to_cpu(mpi_reply->IOCLogInfo));
+	}
+
+ out:
+	ioc->scsih_cmds.status = MPT2_CMD_NOT_USED;
+	mutex_unlock(&ioc->scsih_cmds.mutex);
+}
+
+/**
+ * _scsih_shutdown - routine call during system shutdown
+ * @pdev: PCI device struct
+ *
+ * Return nothing.
+ */
+static void
+_scsih_shutdown(struct pci_dev *pdev)
+{
+	struct Scsi_Host *shost = pci_get_drvdata(pdev);
+	struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
+
+	_scsih_ir_shutdown(ioc);
+	mpt2sas_base_detach(ioc);
+}
+
+/**
  * _scsih_remove - detach and remove add host
  * @pdev: PCI device struct
  *
+ * Routine called when unloading the driver.
  * Return nothing.
  */
 static void __devexit
@@ -5726,7 +6021,7 @@
 			    mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
 			   mpt2sas_port->remote_identify.sas_address);
 			if (sas_device) {
-				_scsih_remove_device(ioc, sas_device->handle);
+				_scsih_remove_device(ioc, sas_device);
 				goto retry_again;
 			}
 		} else {
@@ -5735,7 +6030,7 @@
 			    mpt2sas_port->remote_identify.sas_address);
 			if (expander_sibling) {
 				_scsih_expander_remove(ioc,
-				    expander_sibling->handle);
+				    expander_sibling->sas_address);
 				goto retry_again;
 			}
 		}
@@ -5749,7 +6044,7 @@
 	}
 
 	sas_remove_host(shost);
-	mpt2sas_base_detach(ioc);
+	_scsih_shutdown(pdev);
 	list_del(&ioc->list);
 	scsi_remove_host(shost);
 	scsi_host_put(shost);
@@ -5770,7 +6065,8 @@
 	void *device;
 	struct _sas_device *sas_device;
 	struct _raid_device *raid_device;
-	u16 handle, parent_handle;
+	u16 handle;
+	u64 sas_address_parent;
 	u64 sas_address;
 	unsigned long flags;
 	int rc;
@@ -5799,17 +6095,17 @@
 	} else {
 		sas_device = device;
 		handle = sas_device->handle;
-		parent_handle = sas_device->parent_handle;
+		sas_address_parent = sas_device->sas_address_parent;
 		sas_address = sas_device->sas_address;
 		spin_lock_irqsave(&ioc->sas_device_lock, flags);
 		list_move_tail(&sas_device->list, &ioc->sas_device_list);
 		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 		if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
-		    sas_device->parent_handle)) {
+		    sas_device->sas_address_parent)) {
 			_scsih_sas_device_remove(ioc, sas_device);
 		} else if (!sas_device->starget) {
 			mpt2sas_transport_port_remove(ioc, sas_address,
-			    parent_handle);
+			    sas_address_parent);
 			_scsih_sas_device_remove(ioc, sas_device);
 		}
 	}
@@ -5849,8 +6145,6 @@
 {
 	struct _sas_device *sas_device, *next;
 	unsigned long flags;
-	u16 handle, parent_handle;
-	u64 sas_address;
 
 	/* SAS Device List */
 	list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list,
@@ -5859,14 +6153,13 @@
 		list_move_tail(&sas_device->list, &ioc->sas_device_list);
 		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
-		handle = sas_device->handle;
-		parent_handle = sas_device->parent_handle;
-		sas_address = sas_device->sas_address;
-		if (!mpt2sas_transport_port_add(ioc, handle, parent_handle)) {
+		if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
+		    sas_device->sas_address_parent)) {
 			_scsih_sas_device_remove(ioc, sas_device);
 		} else if (!sas_device->starget) {
-			mpt2sas_transport_port_remove(ioc, sas_address,
-			    parent_handle);
+			mpt2sas_transport_port_remove(ioc,
+			    sas_device->sas_address,
+			    sas_device->sas_address_parent);
 			_scsih_sas_device_remove(ioc, sas_device);
 		}
 	}
@@ -5935,6 +6228,7 @@
 	ioc->ctl_cb_idx = ctl_cb_idx;
 	ioc->base_cb_idx = base_cb_idx;
 	ioc->transport_cb_idx = transport_cb_idx;
+	ioc->scsih_cb_idx = scsih_cb_idx;
 	ioc->config_cb_idx = config_cb_idx;
 	ioc->tm_tr_cb_idx = tm_tr_cb_idx;
 	ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx;
@@ -6072,6 +6366,7 @@
 	.id_table	= scsih_pci_table,
 	.probe		= _scsih_probe,
 	.remove		= __devexit_p(_scsih_remove),
+	.shutdown	= _scsih_shutdown,
 #ifdef CONFIG_PM
 	.suspend	= _scsih_suspend,
 	.resume		= _scsih_resume,
@@ -6113,6 +6408,9 @@
 	transport_cb_idx = mpt2sas_base_register_callback_handler(
 	    mpt2sas_transport_done);
 
+	/* scsih internal commands callback handler */
+	scsih_cb_idx = mpt2sas_base_register_callback_handler(_scsih_done);
+
 	/* configuration page API internal commands callback handler */
 	config_cb_idx = mpt2sas_base_register_callback_handler(
 	    mpt2sas_config_done);
@@ -6152,6 +6450,7 @@
 	mpt2sas_base_release_callback_handler(tm_cb_idx);
 	mpt2sas_base_release_callback_handler(base_cb_idx);
 	mpt2sas_base_release_callback_handler(transport_cb_idx);
+	mpt2sas_base_release_callback_handler(scsih_cb_idx);
 	mpt2sas_base_release_callback_handler(config_cb_idx);
 	mpt2sas_base_release_callback_handler(ctl_cb_idx);
 
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c
index eb98188..3a82872 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_transport.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c
@@ -59,24 +59,23 @@
 
 #include "mpt2sas_base.h"
 /**
- * _transport_sas_node_find_by_handle - sas node search
+ * _transport_sas_node_find_by_sas_address - sas node search
  * @ioc: per adapter object
- * @handle: expander or hba handle (assigned by firmware)
+ * @sas_address: sas address of expander or sas host
  * Context: Calling function should acquire ioc->sas_node_lock.
  *
  * Search for either hba phys or expander device based on handle, then returns
  * the sas_node object.
  */
 static struct _sas_node *
-_transport_sas_node_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
+_transport_sas_node_find_by_sas_address(struct MPT2SAS_ADAPTER *ioc,
+    u64 sas_address)
 {
-	int i;
-
-	for (i = 0; i < ioc->sas_hba.num_phys; i++)
-		if (ioc->sas_hba.phy[i].handle == handle)
-			return &ioc->sas_hba;
-
-	return mpt2sas_scsih_expander_find_by_handle(ioc, handle);
+	if (ioc->sas_hba.sas_address == sas_address)
+		return &ioc->sas_hba;
+	else
+		return mpt2sas_scsih_expander_find_by_sas_address(ioc,
+		    sas_address);
 }
 
 /**
@@ -259,8 +258,7 @@
 	u8 response_length;
 	u16 expander_change_count;
 	u8 reserved0[2];
-	u8 sas_format:1;
-	u8 reserved1:7;
+	u8 sas_format;
 	u8 reserved2[3];
 	u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
 	u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
@@ -375,7 +373,8 @@
 	mpi_request->VP_ID = 0;
 	sas_address_le = (u64 *)&mpi_request->SASAddress;
 	*sas_address_le = cpu_to_le64(sas_address);
-	mpi_request->RequestDataLength = sizeof(struct rep_manu_request);
+	mpi_request->RequestDataLength =
+	    cpu_to_le16(sizeof(struct rep_manu_request));
 	psge = &mpi_request->SGL;
 
 	/* WRITE sgel first */
@@ -438,8 +437,8 @@
 		     SAS_EXPANDER_PRODUCT_ID_LEN);
 		strncpy(edev->product_rev, manufacture_reply->product_rev,
 		     SAS_EXPANDER_PRODUCT_REV_LEN);
-		edev->level = manufacture_reply->sas_format;
-		if (manufacture_reply->sas_format) {
+		edev->level = manufacture_reply->sas_format & 1;
+		if (edev->level) {
 			strncpy(edev->component_vendor_id,
 			    manufacture_reply->component_vendor_id,
 			     SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
@@ -469,7 +468,7 @@
  * mpt2sas_transport_port_add - insert port to the list
  * @ioc: per adapter object
  * @handle: handle of attached device
- * @parent_handle: parent handle(either hba or expander)
+ * @sas_address: sas address of parent expander or sas host
  * Context: This function will acquire ioc->sas_node_lock.
  *
  * Adding new port object to the sas_node->sas_port_list.
@@ -478,7 +477,7 @@
  */
 struct _sas_port *
 mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle,
-    u16 parent_handle)
+    u64 sas_address)
 {
 	struct _sas_phy *mpt2sas_phy, *next;
 	struct _sas_port *mpt2sas_port;
@@ -488,9 +487,6 @@
 	int i;
 	struct sas_port *port;
 
-	if (!parent_handle)
-		return NULL;
-
 	mpt2sas_port = kzalloc(sizeof(struct _sas_port),
 	    GFP_KERNEL);
 	if (!mpt2sas_port) {
@@ -502,17 +498,16 @@
 	INIT_LIST_HEAD(&mpt2sas_port->port_list);
 	INIT_LIST_HEAD(&mpt2sas_port->phy_list);
 	spin_lock_irqsave(&ioc->sas_node_lock, flags);
-	sas_node = _transport_sas_node_find_by_handle(ioc, parent_handle);
+	sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address);
 	spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
 
 	if (!sas_node) {
-		printk(MPT2SAS_ERR_FMT "%s: Could not find parent(0x%04x)!\n",
-		    ioc->name, __func__, parent_handle);
+		printk(MPT2SAS_ERR_FMT "%s: Could not find "
+		    "parent sas_address(0x%016llx)!\n", ioc->name,
+		    __func__, (unsigned long long)sas_address);
 		goto out_fail;
 	}
 
-	mpt2sas_port->handle = parent_handle;
-	mpt2sas_port->sas_address = sas_node->sas_address;
 	if ((_transport_set_identify(ioc, handle,
 	    &mpt2sas_port->remote_identify))) {
 		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
@@ -604,7 +599,7 @@
  * mpt2sas_transport_port_remove - remove port from the list
  * @ioc: per adapter object
  * @sas_address: sas address of attached device
- * @parent_handle: handle to the upstream parent(either hba or expander)
+ * @sas_address_parent: sas address of parent expander or sas host
  * Context: This function will acquire ioc->sas_node_lock.
  *
  * Removing object and freeing associated memory from the
@@ -614,7 +609,7 @@
  */
 void
 mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
-    u16 parent_handle)
+    u64 sas_address_parent)
 {
 	int i;
 	unsigned long flags;
@@ -624,7 +619,8 @@
 	struct _sas_phy *mpt2sas_phy, *next_phy;
 
 	spin_lock_irqsave(&ioc->sas_node_lock, flags);
-	sas_node = _transport_sas_node_find_by_handle(ioc, parent_handle);
+	sas_node = _transport_sas_node_find_by_sas_address(ioc,
+	    sas_address_parent);
 	spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
 	if (!sas_node)
 		return;
@@ -650,8 +646,7 @@
 	    &mpt2sas_port->phy_list, port_siblings) {
 		if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
 			dev_printk(KERN_INFO, &mpt2sas_port->port->dev,
-			    "remove: parent_handle(0x%04x), "
-			    "sas_addr(0x%016llx), phy(%d)\n", parent_handle,
+			    "remove: sas_addr(0x%016llx), phy(%d)\n",
 			    (unsigned long long)
 			    mpt2sas_port->remote_identify.sas_address,
 			    mpt2sas_phy->phy_id);
@@ -799,8 +794,8 @@
 /**
  * mpt2sas_transport_update_links - refreshing phy link changes
  * @ioc: per adapter object
- * @handle: handle to sas_host or expander
- * @attached_handle: attached device handle
+ * @sas_address: sas address of parent expander or sas host
+ * @handle: attached device handle
  * @phy_numberv: phy number
  * @link_rate: new link rate
  *
@@ -808,28 +803,25 @@
  */
 void
 mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc,
-    u16 handle, u16 attached_handle, u8 phy_number, u8 link_rate)
+     u64 sas_address, u16 handle, u8 phy_number, u8 link_rate)
 {
 	unsigned long flags;
 	struct _sas_node *sas_node;
 	struct _sas_phy *mpt2sas_phy;
 
-	if (ioc->shost_recovery) {
-		printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
-			__func__, ioc->name);
+	if (ioc->shost_recovery)
 		return;
-	}
 
 	spin_lock_irqsave(&ioc->sas_node_lock, flags);
-	sas_node = _transport_sas_node_find_by_handle(ioc, handle);
+	sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address);
 	spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
 	if (!sas_node)
 		return;
 
 	mpt2sas_phy = &sas_node->phy[phy_number];
-	mpt2sas_phy->attached_handle = attached_handle;
-	if (attached_handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5))
-		_transport_set_identify(ioc, mpt2sas_phy->attached_handle,
+	mpt2sas_phy->attached_handle = handle;
+	if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5))
+		_transport_set_identify(ioc, handle,
 		    &mpt2sas_phy->remote_identify);
 	else
 		memset(&mpt2sas_phy->remote_identify, 0 , sizeof(struct
@@ -841,13 +833,11 @@
 
 	if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
 		dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev,
-		    "refresh: handle(0x%04x), sas_addr(0x%016llx),\n"
+		    "refresh: parent sas_addr(0x%016llx),\n"
 		    "\tlink_rate(0x%02x), phy(%d)\n"
 		    "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
-		    handle, (unsigned long long)
-		    mpt2sas_phy->identify.sas_address, link_rate,
-		    phy_number, attached_handle,
-		    (unsigned long long)
+		    (unsigned long long)sas_address,
+		    link_rate, phy_number, handle, (unsigned long long)
 		    mpt2sas_phy->remote_identify.sas_address);
 }
 
@@ -1126,7 +1116,7 @@
 	dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio),
 		blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL);
 	if (!dma_addr_out) {
-		mpt2sas_base_free_smid(ioc, le16_to_cpu(smid));
+		mpt2sas_base_free_smid(ioc, smid);
 		goto unmap;
 	}
 
@@ -1144,7 +1134,7 @@
 	dma_addr_in = pci_map_single(ioc->pdev, bio_data(rsp->bio),
 				     blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL);
 	if (!dma_addr_in) {
-		mpt2sas_base_free_smid(ioc, le16_to_cpu(smid));
+		mpt2sas_base_free_smid(ioc, smid);
 		goto unmap;
 	}
 
diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c
index e3c482a..a2d5698 100644
--- a/drivers/scsi/ncr53c8xx.c
+++ b/drivers/scsi/ncr53c8xx.c
@@ -6495,7 +6495,7 @@
 	**	we force a SIR_NEGO_PROTO interrupt (it is a hack that avoids 
 	**	bloat for such a should_not_happen situation).
 	**	In all other situation, we reset the BUS.
-	**	Are these assumptions reasonnable ? (Wait and see ...)
+	**	Are these assumptions reasonable ? (Wait and see ...)
 	*/
 unexpected_phase:
 	dsp -= 8;
diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c
index 2be7d5b..2c98a6e 100644
--- a/drivers/scsi/nsp32.c
+++ b/drivers/scsi/nsp32.c
@@ -1419,7 +1419,7 @@
 		nsp32_msg(KERN_ERR, "Received unexpected BMCNTERR IRQ! ");
 		/*
 		 * TODO: To be implemented improving bus master
-		 * transfer reliablity when BMCNTERR is occurred in
+		 * transfer reliability when BMCNTERR is occurred in
 		 * AutoSCSI phase described in specification.
 		 */
 	}
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
index 7a117c1..950202a 100644
--- a/drivers/scsi/osd/osd_initiator.c
+++ b/drivers/scsi/osd/osd_initiator.c
@@ -73,7 +73,8 @@
 
 #define ATTR_DEF_RI(id, len) ATTR_DEF(OSD_APAGE_ROOT_INFORMATION, id, len)
 
-static int _osd_print_system_info(struct osd_dev *od, void *caps)
+static int _osd_get_print_system_info(struct osd_dev *od,
+	void *caps, struct osd_dev_info *odi)
 {
 	struct osd_request *or;
 	struct osd_attr get_attrs[] = {
@@ -137,8 +138,12 @@
 	OSD_INFO("PRODUCT_SERIAL_NUMBER  [%s]\n",
 		(char *)pFirst);
 
-	pFirst = get_attrs[a].val_ptr;
-	OSD_INFO("OSD_NAME               [%s]\n", (char *)pFirst);
+	odi->osdname_len = get_attrs[a].len;
+	/* Avoid NULL for memcmp optimization 0-length is good enough */
+	odi->osdname = kzalloc(odi->osdname_len + 1, GFP_KERNEL);
+	if (odi->osdname_len)
+		memcpy(odi->osdname, get_attrs[a].val_ptr, odi->osdname_len);
+	OSD_INFO("OSD_NAME               [%s]\n", odi->osdname);
 	a++;
 
 	pFirst = get_attrs[a++].val_ptr;
@@ -171,6 +176,14 @@
 				   sid_dump, sizeof(sid_dump), true);
 		OSD_INFO("OSD_SYSTEM_ID(%d)\n"
 			 "        [%s]\n", len, sid_dump);
+
+		if (unlikely(len > sizeof(odi->systemid))) {
+			OSD_ERR("OSD Target error: OSD_SYSTEM_ID too long(%d). "
+				"device idetification might not work\n", len);
+			len = sizeof(odi->systemid);
+		}
+		odi->systemid_len = len;
+		memcpy(odi->systemid, get_attrs[a].val_ptr, len);
 		a++;
 	}
 out:
@@ -178,16 +191,17 @@
 	return ret;
 }
 
-int osd_auto_detect_ver(struct osd_dev *od, void *caps)
+int osd_auto_detect_ver(struct osd_dev *od,
+	void *caps, struct osd_dev_info *odi)
 {
 	int ret;
 
 	/* Auto-detect the osd version */
-	ret = _osd_print_system_info(od, caps);
+	ret = _osd_get_print_system_info(od, caps, odi);
 	if (ret) {
 		osd_dev_set_ver(od, OSD_VER1);
 		OSD_DEBUG("converting to OSD1\n");
-		ret = _osd_print_system_info(od, caps);
+		ret = _osd_get_print_system_info(od, caps, odi);
 	}
 
 	return ret;
@@ -461,7 +475,8 @@
 
 int osd_execute_request(struct osd_request *or)
 {
-	return blk_execute_rq(or->request->q, NULL, or->request, 0);
+	return or->async_error =
+			blk_execute_rq(or->request->q, NULL, or->request, 0);
 }
 EXPORT_SYMBOL(osd_execute_request);
 
@@ -471,8 +486,12 @@
 
 	or->async_error = error;
 
-	if (error)
-		OSD_DEBUG("osd_request_async_done error recieved %d\n", error);
+	if (unlikely(error)) {
+		OSD_DEBUG("osd_request_async_done error recieved %d "
+			  "errors 0x%x\n", error, req->errors);
+		if (!req->errors) /* don't miss out on this one */
+			req->errors = error;
+	}
 
 	if (or->async_done)
 		or->async_done(or, or->async_private);
@@ -1153,6 +1172,7 @@
 				"c=%d r=%d n=%d\n",
 				cur_bytes, returned_bytes, n);
 			oa->val_ptr = NULL;
+			cur_bytes = returned_bytes; /* break the caller loop */
 			break;
 		}
 
@@ -1436,6 +1456,15 @@
 }
 EXPORT_SYMBOL(osd_finalize_request);
 
+static bool _is_osd_security_code(int code)
+{
+	return	(code == osd_security_audit_value_frozen) ||
+		(code == osd_security_working_key_frozen) ||
+		(code == osd_nonce_not_unique) ||
+		(code == osd_nonce_timestamp_out_of_range) ||
+		(code == osd_invalid_dataout_buffer_integrity_check_value);
+}
+
 #define OSD_SENSE_PRINT1(fmt, a...) \
 	do { \
 		if (__cur_sense_need_output) \
@@ -1458,9 +1487,16 @@
 #else
 	bool __cur_sense_need_output = !silent;
 #endif
+	int ret;
 
-	if (!or->request->errors)
+	if (likely(!or->request->errors)) {
+		osi->out_resid = 0;
+		osi->in_resid = 0;
 		return 0;
+	}
+
+	osi = osi ? : &local_osi;
+	memset(osi, 0, sizeof(*osi));
 
 	ssdb = or->request->sense;
 	sense_len = or->request->sense_len;
@@ -1468,17 +1504,15 @@
 		OSD_ERR("Block-layer returned error(0x%x) but "
 			"sense_len(%u) || key(%d) is empty\n",
 			or->request->errors, sense_len, ssdb->sense_key);
-		return -EIO;
+		goto analyze;
 	}
 
 	if ((ssdb->response_code != 0x72) && (ssdb->response_code != 0x73)) {
 		OSD_ERR("Unrecognized scsi sense: rcode=%x length=%d\n",
 			ssdb->response_code, sense_len);
-		return -EIO;
+		goto analyze;
 	}
 
-	osi = osi ? : &local_osi;
-	memset(osi, 0, sizeof(*osi));
 	osi->key = ssdb->sense_key;
 	osi->additional_code = be16_to_cpu(ssdb->additional_sense_code);
 	original_sense_len = ssdb->additional_sense_length + 8;
@@ -1488,9 +1522,10 @@
 		__cur_sense_need_output = (osi->key > scsi_sk_recovered_error);
 #endif
 	OSD_SENSE_PRINT1("Main Sense information key=0x%x length(%d, %d) "
-			"additional_code=0x%x\n",
+			"additional_code=0x%x async_error=%d errors=0x%x\n",
 			osi->key, original_sense_len, sense_len,
-			osi->additional_code);
+			osi->additional_code, or->async_error,
+			or->request->errors);
 
 	if (original_sense_len < sense_len)
 		sense_len = original_sense_len;
@@ -1569,15 +1604,14 @@
 		{
 			struct osd_sense_attributes_data_descriptor
 				*osadd = cur_descriptor;
-			int len = min(cur_len, sense_len);
-			int i = 0;
+			unsigned len = min(cur_len, sense_len);
 			struct osd_sense_attr *pattr = osadd->sense_attrs;
 
-			while (len < 0) {
+			while (len >= sizeof(*pattr)) {
 				u32 attr_page = be32_to_cpu(pattr->attr_page);
 				u32 attr_id = be32_to_cpu(pattr->attr_id);
 
-				if (i++ == 0) {
+				if (!osi->attr.attr_page) {
 					osi->attr.attr_page = attr_page;
 					osi->attr.attr_id = attr_id;
 				}
@@ -1588,6 +1622,8 @@
 					bad_attr_list++;
 					max_attr--;
 				}
+
+				len -= sizeof(*pattr);
 				OSD_SENSE_PRINT2(
 					"osd_sense_attribute_identification"
 					"attr_page=0x%x attr_id=0x%x\n",
@@ -1621,7 +1657,50 @@
 		cur_descriptor += cur_len;
 	}
 
-	return (osi->key > scsi_sk_recovered_error) ? -EIO : 0;
+analyze:
+	if (!osi->key) {
+		/* scsi sense is Empty, the request was never issued to target
+		 * linux return code might tell us what happened.
+		 */
+		if (or->async_error == -ENOMEM)
+			osi->osd_err_pri = OSD_ERR_PRI_RESOURCE;
+		else
+			osi->osd_err_pri = OSD_ERR_PRI_UNREACHABLE;
+		ret = or->async_error;
+	} else if (osi->key <= scsi_sk_recovered_error) {
+		osi->osd_err_pri = 0;
+		ret = 0;
+	} else if (osi->additional_code == scsi_invalid_field_in_cdb) {
+		if (osi->cdb_field_offset == OSD_CFO_STARTING_BYTE) {
+			osi->osd_err_pri = OSD_ERR_PRI_CLEAR_PAGES;
+			ret = -EFAULT; /* caller should recover from this */
+		} else if (osi->cdb_field_offset == OSD_CFO_OBJECT_ID) {
+			osi->osd_err_pri = OSD_ERR_PRI_NOT_FOUND;
+			ret = -ENOENT;
+		} else if (osi->cdb_field_offset == OSD_CFO_PERMISSIONS) {
+			osi->osd_err_pri = OSD_ERR_PRI_NO_ACCESS;
+			ret = -EACCES;
+		} else {
+			osi->osd_err_pri = OSD_ERR_PRI_BAD_CRED;
+			ret = -EINVAL;
+		}
+	} else if (osi->additional_code == osd_quota_error) {
+		osi->osd_err_pri = OSD_ERR_PRI_NO_SPACE;
+		ret = -ENOSPC;
+	} else if (_is_osd_security_code(osi->additional_code)) {
+		osi->osd_err_pri = OSD_ERR_PRI_BAD_CRED;
+		ret = -EINVAL;
+	} else {
+		osi->osd_err_pri = OSD_ERR_PRI_EIO;
+		ret = -EIO;
+	}
+
+	if (or->out.req)
+		osi->out_resid = or->out.req->resid_len ?: or->out.total_bytes;
+	if (or->in.req)
+		osi->in_resid = or->in.req->resid_len ?: or->in.total_bytes;
+
+	return ret;
 }
 EXPORT_SYMBOL(osd_req_decode_sense_full);
 
diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c
index 0bdef33..0a90702 100644
--- a/drivers/scsi/osd/osd_uld.c
+++ b/drivers/scsi/osd/osd_uld.c
@@ -71,8 +71,7 @@
 #define SCSI_OSD_MAX_MINOR 64
 
 static const char osd_name[] = "osd";
-static const char *osd_version_string = "open-osd 0.1.0";
-const char osd_symlink[] = "scsi_osd";
+static const char *osd_version_string = "open-osd 0.2.0";
 
 MODULE_AUTHOR("Boaz Harrosh <bharrosh@panasas.com>");
 MODULE_DESCRIPTION("open-osd Upper-Layer-Driver osd.ko");
@@ -82,15 +81,25 @@
 
 struct osd_uld_device {
 	int minor;
-	struct kref kref;
+	struct device class_dev;
 	struct cdev cdev;
 	struct osd_dev od;
+	struct osd_dev_info odi;
 	struct gendisk *disk;
-	struct device *class_member;
 };
 
-static void __uld_get(struct osd_uld_device *oud);
-static void __uld_put(struct osd_uld_device *oud);
+struct osd_dev_handle {
+	struct osd_dev od;
+	struct file *file;
+	struct osd_uld_device *oud;
+} ;
+
+static DEFINE_IDA(osd_minor_ida);
+
+static struct class osd_uld_class = {
+	.owner		= THIS_MODULE,
+	.name		= "scsi_osd",
+};
 
 /*
  * Char Device operations
@@ -101,7 +110,7 @@
 	struct osd_uld_device *oud = container_of(inode->i_cdev,
 					struct osd_uld_device, cdev);
 
-	__uld_get(oud);
+	get_device(&oud->class_dev);
 	/* cache osd_uld_device on file handle */
 	file->private_data = oud;
 	OSD_DEBUG("osd_uld_open %p\n", oud);
@@ -114,7 +123,7 @@
 
 	OSD_DEBUG("osd_uld_release %p\n", file->private_data);
 	file->private_data = NULL;
-	__uld_put(oud);
+	put_device(&oud->class_dev);
 	return 0;
 }
 
@@ -177,7 +186,7 @@
 struct osd_dev *osduld_path_lookup(const char *name)
 {
 	struct osd_uld_device *oud;
-	struct osd_dev *od;
+	struct osd_dev_handle *odh;
 	struct file *file;
 	int error;
 
@@ -186,8 +195,8 @@
 		return ERR_PTR(-EINVAL);
 	}
 
-	od = kzalloc(sizeof(*od), GFP_KERNEL);
-	if (!od)
+	odh = kzalloc(sizeof(*odh), GFP_KERNEL);
+	if (unlikely(!odh))
 		return ERR_PTR(-ENOMEM);
 
 	file = filp_open(name, O_RDWR, 0);
@@ -203,33 +212,134 @@
 
 	oud = file->private_data;
 
-	*od = oud->od;
-	od->file = file;
+	odh->od = oud->od;
+	odh->file = file;
+	odh->oud = oud;
 
-	return od;
+	return &odh->od;
 
 close_file:
 	fput(file);
 free_od:
-	kfree(od);
+	kfree(odh);
 	return ERR_PTR(error);
 }
 EXPORT_SYMBOL(osduld_path_lookup);
 
+static inline bool _the_same_or_null(const u8 *a1, unsigned a1_len,
+				     const u8 *a2, unsigned a2_len)
+{
+	if (!a2_len) /* User string is Empty means don't care */
+		return true;
+
+	if (a1_len != a2_len)
+		return false;
+
+	return 0 == memcmp(a1, a2, a1_len);
+}
+
+struct find_oud_t {
+	const struct osd_dev_info *odi;
+	struct device *dev;
+	struct osd_uld_device *oud;
+} ;
+
+int _mach_odi(struct device *dev, void *find_data)
+{
+	struct osd_uld_device *oud = container_of(dev, struct osd_uld_device,
+						  class_dev);
+	struct find_oud_t *fot = find_data;
+	const struct osd_dev_info *odi = fot->odi;
+
+	if (_the_same_or_null(oud->odi.systemid, oud->odi.systemid_len,
+			      odi->systemid, odi->systemid_len) &&
+	    _the_same_or_null(oud->odi.osdname, oud->odi.osdname_len,
+			      odi->osdname, odi->osdname_len)) {
+		OSD_DEBUG("found device sysid_len=%d osdname=%d\n",
+			  odi->systemid_len, odi->osdname_len);
+		fot->oud = oud;
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+/* osduld_info_lookup - Loop through all devices, return the requested osd_dev.
+ *
+ * if @odi->systemid_len and/or @odi->osdname_len are zero, they act as a don't
+ * care. .e.g if they're both zero /dev/osd0 is returned.
+ */
+struct osd_dev *osduld_info_lookup(const struct osd_dev_info *odi)
+{
+	struct find_oud_t find = {.odi = odi};
+
+	find.dev = class_find_device(&osd_uld_class, NULL, &find, _mach_odi);
+	if (likely(find.dev)) {
+		struct osd_dev_handle *odh = kzalloc(sizeof(*odh), GFP_KERNEL);
+
+		if (unlikely(!odh)) {
+			put_device(find.dev);
+			return ERR_PTR(-ENOMEM);
+		}
+
+		odh->od = find.oud->od;
+		odh->oud = find.oud;
+
+		return &odh->od;
+	}
+
+	return ERR_PTR(-ENODEV);
+}
+EXPORT_SYMBOL(osduld_info_lookup);
+
 void osduld_put_device(struct osd_dev *od)
 {
-
 	if (od && !IS_ERR(od)) {
-		struct osd_uld_device *oud = od->file->private_data;
+		struct osd_dev_handle *odh =
+				container_of(od, struct osd_dev_handle, od);
+		struct osd_uld_device *oud = odh->oud;
 
 		BUG_ON(od->scsi_device != oud->od.scsi_device);
 
-		fput(od->file);
-		kfree(od);
+		/* If scsi has released the device (logout), and exofs has last
+		 * reference on oud it will be freed by above osd_uld_release
+		 * within fput below. But this will oops in cdev_release which
+		 * is called after the fops->release. A get_/put_ pair makes
+		 * sure we have a cdev for the duration of fput
+		 */
+		if (odh->file) {
+			get_device(&oud->class_dev);
+			fput(odh->file);
+		}
+		put_device(&oud->class_dev);
+		kfree(odh);
 	}
 }
 EXPORT_SYMBOL(osduld_put_device);
 
+const struct osd_dev_info *osduld_device_info(struct osd_dev *od)
+{
+	struct osd_dev_handle *odh =
+				container_of(od, struct osd_dev_handle, od);
+	return &odh->oud->odi;
+}
+EXPORT_SYMBOL(osduld_device_info);
+
+bool osduld_device_same(struct osd_dev *od, const struct osd_dev_info *odi)
+{
+	struct osd_dev_handle *odh =
+				container_of(od, struct osd_dev_handle, od);
+	struct osd_uld_device *oud = odh->oud;
+
+	return (oud->odi.systemid_len == odi->systemid_len) &&
+		_the_same_or_null(oud->odi.systemid, oud->odi.systemid_len,
+				 odi->systemid, odi->systemid_len) &&
+		(oud->odi.osdname_len == odi->osdname_len) &&
+		_the_same_or_null(oud->odi.osdname, oud->odi.osdname_len,
+				  odi->osdname, odi->osdname_len);
+}
+EXPORT_SYMBOL(osduld_device_same);
+
 /*
  * Scsi Device operations
  */
@@ -250,14 +360,35 @@
 		OSD_ERR("warning: scsi_test_unit_ready failed\n");
 
 	osd_sec_init_nosec_doall_caps(caps, &osd_root_object, false, true);
-	if (osd_auto_detect_ver(&oud->od, caps))
+	if (osd_auto_detect_ver(&oud->od, caps, &oud->odi))
 		return -ENODEV;
 
 	return 0;
 }
 
-static struct class *osd_sysfs_class;
-static DEFINE_IDA(osd_minor_ida);
+static void __remove(struct device *dev)
+{
+	struct osd_uld_device *oud = container_of(dev, struct osd_uld_device,
+						  class_dev);
+	struct scsi_device *scsi_device = oud->od.scsi_device;
+
+	kfree(oud->odi.osdname);
+
+	if (oud->cdev.owner)
+		cdev_del(&oud->cdev);
+
+	osd_dev_fini(&oud->od);
+	scsi_device_put(scsi_device);
+
+	OSD_INFO("osd_remove %s\n",
+		 oud->disk ? oud->disk->disk_name : NULL);
+
+	if (oud->disk)
+		put_disk(oud->disk);
+	ida_remove(&osd_minor_ida, oud->minor);
+
+	kfree(oud);
+}
 
 static int osd_probe(struct device *dev)
 {
@@ -289,7 +420,6 @@
 	if (NULL == oud)
 		goto err_retract_minor;
 
-	kref_init(&oud->kref);
 	dev_set_drvdata(dev, oud);
 	oud->minor = minor;
 
@@ -327,18 +457,25 @@
 		OSD_ERR("cdev_add failed\n");
 		goto err_put_disk;
 	}
-	kobject_get(&oud->cdev.kobj); /* 2nd ref see osd_remove() */
 
-	/* class_member */
-	oud->class_member = device_create(osd_sysfs_class, dev,
-		MKDEV(SCSI_OSD_MAJOR, oud->minor), "%s", disk->disk_name);
-	if (IS_ERR(oud->class_member)) {
-		OSD_ERR("class_device_create failed\n");
-		error = PTR_ERR(oud->class_member);
+	/* class device member */
+	oud->class_dev.devt = oud->cdev.dev;
+	oud->class_dev.class = &osd_uld_class;
+	oud->class_dev.parent = dev;
+	oud->class_dev.release = __remove;
+	error = dev_set_name(&oud->class_dev, disk->disk_name);
+	if (error) {
+		OSD_ERR("dev_set_name failed => %d\n", error);
 		goto err_put_cdev;
 	}
 
-	dev_set_drvdata(oud->class_member, oud);
+	error = device_register(&oud->class_dev);
+	if (error) {
+		OSD_ERR("device_register failed => %d\n", error);
+		goto err_put_cdev;
+	}
+
+	get_device(&oud->class_dev);
 
 	OSD_INFO("osd_probe %s\n", disk->disk_name);
 	return 0;
@@ -367,54 +504,12 @@
 			scsi_device);
 	}
 
-	if (oud->class_member)
-		device_destroy(osd_sysfs_class,
-			       MKDEV(SCSI_OSD_MAJOR, oud->minor));
+	device_unregister(&oud->class_dev);
 
-	/* We have 2 references to the cdev. One is released here
-	 * and also takes down the /dev/osdX mapping. The second
-	 * Will be released in __remove() after all users have released
-	 * the osd_uld_device.
-	 */
-	if (oud->cdev.owner)
-		cdev_del(&oud->cdev);
-
-	__uld_put(oud);
+	put_device(&oud->class_dev);
 	return 0;
 }
 
-static void __remove(struct kref *kref)
-{
-	struct osd_uld_device *oud = container_of(kref,
-					struct osd_uld_device, kref);
-	struct scsi_device *scsi_device = oud->od.scsi_device;
-
-	/* now let delete the char_dev */
-	kobject_put(&oud->cdev.kobj);
-
-	osd_dev_fini(&oud->od);
-	scsi_device_put(scsi_device);
-
-	OSD_INFO("osd_remove %s\n",
-		 oud->disk ? oud->disk->disk_name : NULL);
-
-	if (oud->disk)
-		put_disk(oud->disk);
-
-	ida_remove(&osd_minor_ida, oud->minor);
-	kfree(oud);
-}
-
-static void __uld_get(struct osd_uld_device *oud)
-{
-	kref_get(&oud->kref);
-}
-
-static void __uld_put(struct osd_uld_device *oud)
-{
-	kref_put(&oud->kref, __remove);
-}
-
 /*
  * Global driver and scsi registration
  */
@@ -432,11 +527,10 @@
 {
 	int err;
 
-	osd_sysfs_class = class_create(THIS_MODULE, osd_symlink);
-	if (IS_ERR(osd_sysfs_class)) {
-		OSD_ERR("Unable to register sysfs class => %ld\n",
-			PTR_ERR(osd_sysfs_class));
-		return PTR_ERR(osd_sysfs_class);
+	err = class_register(&osd_uld_class);
+	if (err) {
+		OSD_ERR("Unable to register sysfs class => %d\n", err);
+		return err;
 	}
 
 	err = register_chrdev_region(MKDEV(SCSI_OSD_MAJOR, 0),
@@ -459,7 +553,7 @@
 err_out_chrdev:
 	unregister_chrdev_region(MKDEV(SCSI_OSD_MAJOR, 0), SCSI_OSD_MAX_MINOR);
 err_out:
-	class_destroy(osd_sysfs_class);
+	class_unregister(&osd_uld_class);
 	return err;
 }
 
@@ -467,7 +561,7 @@
 {
 	scsi_unregister_driver(&osd_driver.gendrv);
 	unregister_chrdev_region(MKDEV(SCSI_OSD_MAJOR, 0), SCSI_OSD_MAX_MINOR);
-	class_destroy(osd_sysfs_class);
+	class_unregister(&osd_uld_class);
 	OSD_INFO("UNLOADED %s\n", osd_version_string);
 }
 
diff --git a/drivers/scsi/pm8001/Makefile b/drivers/scsi/pm8001/Makefile
new file mode 100644
index 0000000..52f0429
--- /dev/null
+++ b/drivers/scsi/pm8001/Makefile
@@ -0,0 +1,12 @@
+#
+# Kernel configuration file for the PM8001 SAS/SATA 8x6G based HBA driver
+#
+# Copyright (C) 2008-2009  USI Co., Ltd.
+
+
+obj-$(CONFIG_SCSI_PM8001) += pm8001.o
+pm8001-y += pm8001_init.o \
+		pm8001_sas.o  \
+		pm8001_ctl.o  \
+		pm8001_hwi.o
+
diff --git a/drivers/scsi/pm8001/pm8001_chips.h b/drivers/scsi/pm8001/pm8001_chips.h
new file mode 100644
index 0000000..4efa4d0
--- /dev/null
+++ b/drivers/scsi/pm8001/pm8001_chips.h
@@ -0,0 +1,89 @@
+/*
+ * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver
+ *
+ * Copyright (c) 2008-2009 USI Co., Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+#ifndef _PM8001_CHIPS_H_
+#define _PM8001_CHIPS_H_
+
+static inline u32 pm8001_read_32(void *virt_addr)
+{
+	return *((u32 *)virt_addr);
+}
+
+static inline void pm8001_write_32(void *addr, u32 offset, u32 val)
+{
+	*((u32 *)(addr + offset)) = val;
+}
+
+static inline u32 pm8001_cr32(struct pm8001_hba_info *pm8001_ha, u32 bar,
+		u32 offset)
+{
+	return readl(pm8001_ha->io_mem[bar].memvirtaddr + offset);
+}
+
+static inline void pm8001_cw32(struct pm8001_hba_info *pm8001_ha, u32 bar,
+		u32 addr, u32 val)
+{
+	writel(val, pm8001_ha->io_mem[bar].memvirtaddr + addr);
+}
+static inline u32 pm8001_mr32(void __iomem *addr, u32 offset)
+{
+	return readl(addr + offset);
+}
+static inline void pm8001_mw32(void __iomem *addr, u32 offset, u32 val)
+{
+	writel(val, addr + offset);
+}
+static inline u32 get_pci_bar_index(u32 pcibar)
+{
+		switch (pcibar) {
+		case 0x18:
+		case 0x1C:
+			return 1;
+		case 0x20:
+			return 2;
+		case 0x24:
+			return 3;
+		default:
+			return 0;
+	}
+}
+
+#endif  /* _PM8001_CHIPS_H_ */
+
diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
new file mode 100644
index 0000000..14b13ac
--- /dev/null
+++ b/drivers/scsi/pm8001/pm8001_ctl.c
@@ -0,0 +1,573 @@
+/*
+ * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver
+ *
+ * Copyright (c) 2008-2009 USI Co., Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+#include <linux/firmware.h>
+#include "pm8001_sas.h"
+#include "pm8001_ctl.h"
+
+/* scsi host attributes */
+
+/**
+ * pm8001_ctl_mpi_interface_rev_show - MPI interface revision number
+ * @cdev: pointer to embedded class device
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t pm8001_ctl_mpi_interface_rev_show(struct device *cdev,
+	struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+
+	return snprintf(buf, PAGE_SIZE, "%d\n",
+		pm8001_ha->main_cfg_tbl.interface_rev);
+}
+static
+DEVICE_ATTR(interface_rev, S_IRUGO, pm8001_ctl_mpi_interface_rev_show, NULL);
+
+/**
+ * pm8001_ctl_fw_version_show - firmware version
+ * @cdev: pointer to embedded class device
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t pm8001_ctl_fw_version_show(struct device *cdev,
+	struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+
+	return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
+		       (u8)(pm8001_ha->main_cfg_tbl.firmware_rev >> 24),
+		       (u8)(pm8001_ha->main_cfg_tbl.firmware_rev >> 16),
+		       (u8)(pm8001_ha->main_cfg_tbl.firmware_rev >> 8),
+		       (u8)(pm8001_ha->main_cfg_tbl.firmware_rev));
+}
+static DEVICE_ATTR(fw_version, S_IRUGO, pm8001_ctl_fw_version_show, NULL);
+/**
+ * pm8001_ctl_max_out_io_show - max outstanding io supported
+ * @cdev: pointer to embedded class device
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t pm8001_ctl_max_out_io_show(struct device *cdev,
+	struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+
+	return snprintf(buf, PAGE_SIZE, "%d\n",
+			pm8001_ha->main_cfg_tbl.max_out_io);
+}
+static DEVICE_ATTR(max_out_io, S_IRUGO, pm8001_ctl_max_out_io_show, NULL);
+/**
+ * pm8001_ctl_max_devices_show - max devices support
+ * @cdev: pointer to embedded class device
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t pm8001_ctl_max_devices_show(struct device *cdev,
+	struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+
+	return snprintf(buf, PAGE_SIZE, "%04d\n",
+			(u16)(pm8001_ha->main_cfg_tbl.max_sgl >> 16));
+}
+static DEVICE_ATTR(max_devices, S_IRUGO, pm8001_ctl_max_devices_show, NULL);
+/**
+ * pm8001_ctl_max_sg_list_show - max sg list supported iff not 0.0 for no
+ * hardware limitation
+ * @cdev: pointer to embedded class device
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t pm8001_ctl_max_sg_list_show(struct device *cdev,
+	struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+
+	return snprintf(buf, PAGE_SIZE, "%04d\n",
+			pm8001_ha->main_cfg_tbl.max_sgl & 0x0000FFFF);
+}
+static DEVICE_ATTR(max_sg_list, S_IRUGO, pm8001_ctl_max_sg_list_show, NULL);
+
+#define SAS_1_0 0x1
+#define SAS_1_1 0x2
+#define SAS_2_0 0x4
+
+static ssize_t
+show_sas_spec_support_status(unsigned int mode, char *buf)
+{
+	ssize_t len = 0;
+
+	if (mode & SAS_1_1)
+		len = sprintf(buf, "%s", "SAS1.1");
+	if (mode & SAS_2_0)
+		len += sprintf(buf + len, "%s%s", len ? ", " : "", "SAS2.0");
+	len += sprintf(buf + len, "\n");
+
+	return len;
+}
+
+/**
+ * pm8001_ctl_sas_spec_support_show - sas spec supported
+ * @cdev: pointer to embedded class device
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t pm8001_ctl_sas_spec_support_show(struct device *cdev,
+	struct device_attribute *attr, char *buf)
+{
+	unsigned int mode;
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+	mode = (pm8001_ha->main_cfg_tbl.ctrl_cap_flag & 0xfe000000)>>25;
+	return show_sas_spec_support_status(mode, buf);
+}
+static DEVICE_ATTR(sas_spec_support, S_IRUGO,
+		   pm8001_ctl_sas_spec_support_show, NULL);
+
+/**
+ * pm8001_ctl_sas_address_show - sas address
+ * @cdev: pointer to embedded class device
+ * @buf: the buffer returned
+ *
+ * This is the controller sas address
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t pm8001_ctl_host_sas_address_show(struct device *cdev,
+	struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+	return snprintf(buf, PAGE_SIZE, "0x%016llx\n",
+			be64_to_cpu(*(__be64 *)pm8001_ha->sas_addr));
+}
+static DEVICE_ATTR(host_sas_address, S_IRUGO,
+		   pm8001_ctl_host_sas_address_show, NULL);
+
+/**
+ * pm8001_ctl_logging_level_show - logging level
+ * @cdev: pointer to embedded class device
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read/write' shost attribute.
+ */
+static ssize_t pm8001_ctl_logging_level_show(struct device *cdev,
+	struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+
+	return snprintf(buf, PAGE_SIZE, "%08xh\n", pm8001_ha->logging_level);
+}
+static ssize_t pm8001_ctl_logging_level_store(struct device *cdev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+	int val = 0;
+
+	if (sscanf(buf, "%x", &val) != 1)
+		return -EINVAL;
+
+	pm8001_ha->logging_level = val;
+	return strlen(buf);
+}
+
+static DEVICE_ATTR(logging_level, S_IRUGO | S_IWUSR,
+	pm8001_ctl_logging_level_show, pm8001_ctl_logging_level_store);
+/**
+ * pm8001_ctl_aap_log_show - aap1 event log
+ * @cdev: pointer to embedded class device
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t pm8001_ctl_aap_log_show(struct device *cdev,
+	struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+	int i;
+#define AAP1_MEMMAP(r, c) \
+	(*(u32 *)((u8*)pm8001_ha->memoryMap.region[AAP1].virt_ptr + (r) * 32 \
+	+ (c)))
+
+	char *str = buf;
+	int max = 2;
+	for (i = 0; i < max; i++) {
+		str += sprintf(str, "0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x"
+			       "0x%08x 0x%08x\n",
+			       AAP1_MEMMAP(i, 0),
+			       AAP1_MEMMAP(i, 4),
+			       AAP1_MEMMAP(i, 8),
+			       AAP1_MEMMAP(i, 12),
+			       AAP1_MEMMAP(i, 16),
+			       AAP1_MEMMAP(i, 20),
+			       AAP1_MEMMAP(i, 24),
+			       AAP1_MEMMAP(i, 28));
+	}
+
+	return str - buf;
+}
+static DEVICE_ATTR(aap_log, S_IRUGO, pm8001_ctl_aap_log_show, NULL);
+/**
+ * pm8001_ctl_aap_log_show - IOP event log
+ * @cdev: pointer to embedded class device
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t pm8001_ctl_iop_log_show(struct device *cdev,
+	struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+#define IOP_MEMMAP(r, c) \
+	(*(u32 *)((u8*)pm8001_ha->memoryMap.region[IOP].virt_ptr + (r) * 32 \
+	+ (c)))
+	int i;
+	char *str = buf;
+	int max = 2;
+	for (i = 0; i < max; i++) {
+		str += sprintf(str, "0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x"
+			       "0x%08x 0x%08x\n",
+			       IOP_MEMMAP(i, 0),
+			       IOP_MEMMAP(i, 4),
+			       IOP_MEMMAP(i, 8),
+			       IOP_MEMMAP(i, 12),
+			       IOP_MEMMAP(i, 16),
+			       IOP_MEMMAP(i, 20),
+			       IOP_MEMMAP(i, 24),
+			       IOP_MEMMAP(i, 28));
+	}
+
+	return str - buf;
+}
+static DEVICE_ATTR(iop_log, S_IRUGO, pm8001_ctl_iop_log_show, NULL);
+
+#define FLASH_CMD_NONE      0x00
+#define FLASH_CMD_UPDATE    0x01
+#define FLASH_CMD_SET_NVMD    0x02
+
+struct flash_command {
+     u8      command[8];
+     int     code;
+};
+
+static struct flash_command flash_command_table[] =
+{
+     {"set_nvmd",    FLASH_CMD_SET_NVMD},
+     {"update",      FLASH_CMD_UPDATE},
+     {"",            FLASH_CMD_NONE} /* Last entry should be NULL. */
+};
+
+struct error_fw {
+     char    *reason;
+     int     err_code;
+};
+
+static struct error_fw flash_error_table[] =
+{
+     {"Failed to open fw image file",	FAIL_OPEN_BIOS_FILE},
+     {"image header mismatch",		FLASH_UPDATE_HDR_ERR},
+     {"image offset mismatch",		FLASH_UPDATE_OFFSET_ERR},
+     {"image CRC Error",		FLASH_UPDATE_CRC_ERR},
+     {"image length Error.",		FLASH_UPDATE_LENGTH_ERR},
+     {"Failed to program flash chip",	FLASH_UPDATE_HW_ERR},
+     {"Flash chip not supported.",	FLASH_UPDATE_DNLD_NOT_SUPPORTED},
+     {"Flash update disabled.",		FLASH_UPDATE_DISABLED},
+     {"Flash in progress",		FLASH_IN_PROGRESS},
+     {"Image file size Error",		FAIL_FILE_SIZE},
+     {"Input parameter error",		FAIL_PARAMETERS},
+     {"Out of memory",			FAIL_OUT_MEMORY},
+     {"OK", 0}	/* Last entry err_code = 0. */
+};
+
+static int pm8001_set_nvmd(struct pm8001_hba_info *pm8001_ha)
+{
+	struct pm8001_ioctl_payload	*payload;
+	DECLARE_COMPLETION_ONSTACK(completion);
+	u8		*ioctlbuffer = NULL;
+	u32		length = 0;
+	u32		ret = 0;
+
+	length = 1024 * 5 + sizeof(*payload) - 1;
+	ioctlbuffer = kzalloc(length, GFP_KERNEL);
+	if (!ioctlbuffer)
+		return -ENOMEM;
+	if ((pm8001_ha->fw_image->size <= 0) ||
+	    (pm8001_ha->fw_image->size > 4096)) {
+		ret = FAIL_FILE_SIZE;
+		goto out;
+	}
+	payload = (struct pm8001_ioctl_payload *)ioctlbuffer;
+	memcpy((u8 *)payload->func_specific, (u8 *)pm8001_ha->fw_image->data,
+				pm8001_ha->fw_image->size);
+	payload->length = pm8001_ha->fw_image->size;
+	payload->id = 0;
+	pm8001_ha->nvmd_completion = &completion;
+	ret = PM8001_CHIP_DISP->set_nvmd_req(pm8001_ha, payload);
+	wait_for_completion(&completion);
+out:
+	kfree(ioctlbuffer);
+	return ret;
+}
+
+static int pm8001_update_flash(struct pm8001_hba_info *pm8001_ha)
+{
+	struct pm8001_ioctl_payload	*payload;
+	DECLARE_COMPLETION_ONSTACK(completion);
+	u8		*ioctlbuffer = NULL;
+	u32		length = 0;
+	struct fw_control_info	*fwControl;
+	u32		loopNumber, loopcount = 0;
+	u32		sizeRead = 0;
+	u32		partitionSize, partitionSizeTmp;
+	u32		ret = 0;
+	u32		partitionNumber = 0;
+	struct pm8001_fw_image_header *image_hdr;
+
+	length = 1024 * 16 + sizeof(*payload) - 1;
+	ioctlbuffer = kzalloc(length, GFP_KERNEL);
+	image_hdr = (struct pm8001_fw_image_header *)pm8001_ha->fw_image->data;
+	if (!ioctlbuffer)
+		return -ENOMEM;
+	if (pm8001_ha->fw_image->size < 28) {
+		ret = FAIL_FILE_SIZE;
+		goto out;
+	}
+
+	while (sizeRead < pm8001_ha->fw_image->size) {
+		partitionSizeTmp =
+			*(u32 *)((u8 *)&image_hdr->image_length + sizeRead);
+		partitionSize = be32_to_cpu(partitionSizeTmp);
+		loopcount = (partitionSize + HEADER_LEN)/IOCTL_BUF_SIZE;
+		if (loopcount % IOCTL_BUF_SIZE)
+			loopcount++;
+		if (loopcount == 0)
+			loopcount++;
+		for (loopNumber = 0; loopNumber < loopcount; loopNumber++) {
+			payload = (struct pm8001_ioctl_payload *)ioctlbuffer;
+			payload->length = 1024*16;
+			payload->id = 0;
+			fwControl =
+			      (struct fw_control_info *)payload->func_specific;
+			fwControl->len = IOCTL_BUF_SIZE;   /* IN */
+			fwControl->size = partitionSize + HEADER_LEN;/* IN */
+			fwControl->retcode = 0;/* OUT */
+			fwControl->offset = loopNumber * IOCTL_BUF_SIZE;/*OUT */
+
+		/* for the last chunk of data in case file size is not even with
+		4k, load only the rest*/
+		if (((loopcount-loopNumber) == 1) &&
+			((partitionSize + HEADER_LEN) % IOCTL_BUF_SIZE)) {
+			fwControl->len =
+				(partitionSize + HEADER_LEN) % IOCTL_BUF_SIZE;
+			memcpy((u8 *)fwControl->buffer,
+				(u8 *)pm8001_ha->fw_image->data + sizeRead,
+				(partitionSize + HEADER_LEN) % IOCTL_BUF_SIZE);
+			sizeRead +=
+				(partitionSize + HEADER_LEN) % IOCTL_BUF_SIZE;
+		} else {
+			memcpy((u8 *)fwControl->buffer,
+				(u8 *)pm8001_ha->fw_image->data + sizeRead,
+				IOCTL_BUF_SIZE);
+			sizeRead += IOCTL_BUF_SIZE;
+		}
+
+		pm8001_ha->nvmd_completion = &completion;
+		ret = PM8001_CHIP_DISP->fw_flash_update_req(pm8001_ha, payload);
+		wait_for_completion(&completion);
+		if (ret || (fwControl->retcode > FLASH_UPDATE_IN_PROGRESS)) {
+			ret = fwControl->retcode;
+			kfree(ioctlbuffer);
+			ioctlbuffer = NULL;
+			break;
+		}
+	}
+	if (ret)
+		break;
+	partitionNumber++;
+}
+out:
+	kfree(ioctlbuffer);
+	return ret;
+}
+static ssize_t pm8001_store_update_fw(struct device *cdev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t count)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+	char *cmd_ptr, *filename_ptr;
+	int res, i;
+	int flash_command = FLASH_CMD_NONE;
+	int err = 0;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	cmd_ptr = kzalloc(count*2, GFP_KERNEL);
+
+	if (!cmd_ptr) {
+		err = FAIL_OUT_MEMORY;
+		goto out;
+	}
+
+	filename_ptr = cmd_ptr + count;
+	res = sscanf(buf, "%s %s", cmd_ptr, filename_ptr);
+	if (res != 2) {
+		err = FAIL_PARAMETERS;
+		goto out1;
+	}
+
+	for (i = 0; flash_command_table[i].code != FLASH_CMD_NONE; i++) {
+		if (!memcmp(flash_command_table[i].command,
+				 cmd_ptr, strlen(cmd_ptr))) {
+			flash_command = flash_command_table[i].code;
+			break;
+		}
+	}
+	if (flash_command == FLASH_CMD_NONE) {
+		err = FAIL_PARAMETERS;
+		goto out1;
+	}
+
+	if (pm8001_ha->fw_status == FLASH_IN_PROGRESS) {
+		err = FLASH_IN_PROGRESS;
+		goto out1;
+	}
+	err = request_firmware(&pm8001_ha->fw_image,
+			       filename_ptr,
+			       pm8001_ha->dev);
+
+	if (err) {
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("Failed to load firmware image file %s,"
+			" error %d\n", filename_ptr, err));
+		err = FAIL_OPEN_BIOS_FILE;
+		goto out1;
+	}
+
+	switch (flash_command) {
+	case FLASH_CMD_UPDATE:
+		pm8001_ha->fw_status = FLASH_IN_PROGRESS;
+		err = pm8001_update_flash(pm8001_ha);
+		break;
+	case FLASH_CMD_SET_NVMD:
+		pm8001_ha->fw_status = FLASH_IN_PROGRESS;
+		err = pm8001_set_nvmd(pm8001_ha);
+		break;
+	default:
+		pm8001_ha->fw_status = FAIL_PARAMETERS;
+		err = FAIL_PARAMETERS;
+		break;
+	}
+	release_firmware(pm8001_ha->fw_image);
+out1:
+	kfree(cmd_ptr);
+out:
+	pm8001_ha->fw_status = err;
+
+	if (!err)
+		return count;
+	else
+		return -err;
+}
+
+static ssize_t pm8001_show_update_fw(struct device *cdev,
+				     struct device_attribute *attr, char *buf)
+{
+	int i;
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+
+	for (i = 0; flash_error_table[i].err_code != 0; i++) {
+		if (flash_error_table[i].err_code == pm8001_ha->fw_status)
+			break;
+	}
+	if (pm8001_ha->fw_status != FLASH_IN_PROGRESS)
+		pm8001_ha->fw_status = FLASH_OK;
+
+	return snprintf(buf, PAGE_SIZE, "status=%x %s\n",
+			flash_error_table[i].err_code,
+			flash_error_table[i].reason);
+}
+
+static DEVICE_ATTR(update_fw, S_IRUGO|S_IWUGO,
+	pm8001_show_update_fw, pm8001_store_update_fw);
+struct device_attribute *pm8001_host_attrs[] = {
+	&dev_attr_interface_rev,
+	&dev_attr_fw_version,
+	&dev_attr_update_fw,
+	&dev_attr_aap_log,
+	&dev_attr_iop_log,
+	&dev_attr_max_out_io,
+	&dev_attr_max_devices,
+	&dev_attr_max_sg_list,
+	&dev_attr_sas_spec_support,
+	&dev_attr_logging_level,
+	&dev_attr_host_sas_address,
+	NULL,
+};
+
diff --git a/drivers/scsi/pm8001/pm8001_ctl.h b/drivers/scsi/pm8001/pm8001_ctl.h
new file mode 100644
index 0000000..22644de
--- /dev/null
+++ b/drivers/scsi/pm8001/pm8001_ctl.h
@@ -0,0 +1,67 @@
+ /*
+  * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver
+  *
+  * Copyright (c) 2008-2009 USI Co., Ltd.
+  * All rights reserved.
+  *
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions, and the following disclaimer,
+  *    without modification.
+  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+  *    substantially similar to the "NO WARRANTY" disclaimer below
+  *    ("Disclaimer") and any redistribution must be conditioned upon
+  *    including a substantially similar Disclaimer requirement for further
+  *    binary redistribution.
+  * 3. Neither the names of the above-listed copyright holders nor the names
+  *    of any contributors may be used to endorse or promote products derived
+  *    from this software without specific prior written permission.
+  *
+  * Alternatively, this software may be distributed under the terms of the
+  * GNU General Public License ("GPL") version 2 as published by the Free
+  * Software Foundation.
+  *
+  * NO WARRANTY
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGES.
+  *
+  */
+
+#ifndef PM8001_CTL_H_INCLUDED
+#define PM8001_CTL_H_INCLUDED
+
+#define IOCTL_BUF_SIZE		4096
+#define HEADER_LEN			28
+#define SIZE_OFFSET			16
+
+struct pm8001_ioctl_payload {
+	u32	signature;
+	u16	major_function;
+	u16	minor_function;
+	u16	length;
+	u16	status;
+	u16	offset;
+	u16	id;
+	u8	func_specific[1];
+};
+
+#define FLASH_OK                        0x000000
+#define FAIL_OPEN_BIOS_FILE             0x000100
+#define FAIL_FILE_SIZE                  0x000a00
+#define FAIL_PARAMETERS                 0x000b00
+#define FAIL_OUT_MEMORY                 0x000c00
+#define FLASH_IN_PROGRESS               0x001000
+
+#endif /* PM8001_CTL_H_INCLUDED */
+
diff --git a/drivers/scsi/pm8001/pm8001_defs.h b/drivers/scsi/pm8001/pm8001_defs.h
new file mode 100644
index 0000000..944afad
--- /dev/null
+++ b/drivers/scsi/pm8001/pm8001_defs.h
@@ -0,0 +1,112 @@
+/*
+ * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver
+ *
+ * Copyright (c) 2008-2009 USI Co., Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+#ifndef _PM8001_DEFS_H_
+#define _PM8001_DEFS_H_
+
+enum chip_flavors {
+	chip_8001,
+};
+#define USI_MAX_MEMCNT			9
+#define PM8001_MAX_DMA_SG		SG_ALL
+enum phy_speed {
+	PHY_SPEED_15 = 0x01,
+	PHY_SPEED_30 = 0x02,
+	PHY_SPEED_60 = 0x04,
+};
+
+enum data_direction {
+	DATA_DIR_NONE = 0x0,	/* NO TRANSFER */
+	DATA_DIR_IN = 0x01,	/* INBOUND */
+	DATA_DIR_OUT = 0x02,	/* OUTBOUND */
+	DATA_DIR_BYRECIPIENT = 0x04, /* UNSPECIFIED */
+};
+
+enum port_type {
+	PORT_TYPE_SAS = (1L << 1),
+	PORT_TYPE_SATA = (1L << 0),
+};
+
+/* driver compile-time configuration */
+#define	PM8001_MAX_CCB		 512	/* max ccbs supported */
+#define	PM8001_MAX_INB_NUM	 1
+#define	PM8001_MAX_OUTB_NUM	 1
+#define	PM8001_CAN_QUEUE	 128	/* SCSI Queue depth */
+
+/* unchangeable hardware details */
+#define	PM8001_MAX_PHYS		 8	/* max. possible phys */
+#define	PM8001_MAX_PORTS	 8	/* max. possible ports */
+#define	PM8001_MAX_DEVICES	 1024	/* max supported device */
+
+enum memory_region_num {
+	AAP1 = 0x0, /* application acceleration processor */
+	IOP,	    /* IO processor */
+	CI,	    /* consumer index */
+	PI,	    /* producer index */
+	IB,	    /* inbound queue */
+	OB,	    /* outbound queue */
+	NVMD,	    /* NVM device */
+	DEV_MEM,    /* memory for devices */
+	CCB_MEM,    /* memory for command control block */
+};
+#define	PM8001_EVENT_LOG_SIZE	 (128 * 1024)
+
+/*error code*/
+enum mpi_err {
+	MPI_IO_STATUS_SUCCESS = 0x0,
+	MPI_IO_STATUS_BUSY = 0x01,
+	MPI_IO_STATUS_FAIL = 0x02,
+};
+
+/**
+ * Phy Control constants
+ */
+enum phy_control_type {
+	PHY_LINK_RESET = 0x01,
+	PHY_HARD_RESET = 0x02,
+	PHY_NOTIFY_ENABLE_SPINUP = 0x10,
+};
+
+enum pm8001_hba_info_flags {
+	PM8001F_INIT_TIME	= (1U << 0),
+	PM8001F_RUN_TIME	= (1U << 1),
+};
+
+#endif
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
new file mode 100644
index 0000000..a3de306
--- /dev/null
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -0,0 +1,4458 @@
+/*
+ * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver
+ *
+ * Copyright (c) 2008-2009 USI Co., Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+ #include "pm8001_sas.h"
+ #include "pm8001_hwi.h"
+ #include "pm8001_chips.h"
+ #include "pm8001_ctl.h"
+
+/**
+ * read_main_config_table - read the configure table and save it.
+ * @pm8001_ha: our hba card information
+ */
+static void __devinit read_main_config_table(struct pm8001_hba_info *pm8001_ha)
+{
+	void __iomem *address = pm8001_ha->main_cfg_tbl_addr;
+	pm8001_ha->main_cfg_tbl.signature	= pm8001_mr32(address, 0x00);
+	pm8001_ha->main_cfg_tbl.interface_rev	= pm8001_mr32(address, 0x04);
+	pm8001_ha->main_cfg_tbl.firmware_rev	= pm8001_mr32(address, 0x08);
+	pm8001_ha->main_cfg_tbl.max_out_io	= pm8001_mr32(address, 0x0C);
+	pm8001_ha->main_cfg_tbl.max_sgl		= pm8001_mr32(address, 0x10);
+	pm8001_ha->main_cfg_tbl.ctrl_cap_flag	= pm8001_mr32(address, 0x14);
+	pm8001_ha->main_cfg_tbl.gst_offset	= pm8001_mr32(address, 0x18);
+	pm8001_ha->main_cfg_tbl.inbound_queue_offset =
+		pm8001_mr32(address, MAIN_IBQ_OFFSET);
+	pm8001_ha->main_cfg_tbl.outbound_queue_offset =
+		pm8001_mr32(address, MAIN_OBQ_OFFSET);
+	pm8001_ha->main_cfg_tbl.hda_mode_flag	=
+		pm8001_mr32(address, MAIN_HDA_FLAGS_OFFSET);
+
+	/* read analog Setting offset from the configuration table */
+	pm8001_ha->main_cfg_tbl.anolog_setup_table_offset =
+		pm8001_mr32(address, MAIN_ANALOG_SETUP_OFFSET);
+
+	/* read Error Dump Offset and Length */
+	pm8001_ha->main_cfg_tbl.fatal_err_dump_offset0 =
+		pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP0_OFFSET);
+	pm8001_ha->main_cfg_tbl.fatal_err_dump_length0 =
+		pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP0_LENGTH);
+	pm8001_ha->main_cfg_tbl.fatal_err_dump_offset1 =
+		pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP1_OFFSET);
+	pm8001_ha->main_cfg_tbl.fatal_err_dump_length1 =
+		pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP1_LENGTH);
+}
+
+/**
+ * read_general_status_table - read the general status table and save it.
+ * @pm8001_ha: our hba card information
+ */
+static void __devinit
+read_general_status_table(struct pm8001_hba_info *pm8001_ha)
+{
+	void __iomem *address = pm8001_ha->general_stat_tbl_addr;
+	pm8001_ha->gs_tbl.gst_len_mpistate	= pm8001_mr32(address, 0x00);
+	pm8001_ha->gs_tbl.iq_freeze_state0	= pm8001_mr32(address, 0x04);
+	pm8001_ha->gs_tbl.iq_freeze_state1	= pm8001_mr32(address, 0x08);
+	pm8001_ha->gs_tbl.msgu_tcnt		= pm8001_mr32(address, 0x0C);
+	pm8001_ha->gs_tbl.iop_tcnt		= pm8001_mr32(address, 0x10);
+	pm8001_ha->gs_tbl.reserved		= pm8001_mr32(address, 0x14);
+	pm8001_ha->gs_tbl.phy_state[0]	= pm8001_mr32(address, 0x18);
+	pm8001_ha->gs_tbl.phy_state[1]	= pm8001_mr32(address, 0x1C);
+	pm8001_ha->gs_tbl.phy_state[2]	= pm8001_mr32(address, 0x20);
+	pm8001_ha->gs_tbl.phy_state[3]	= pm8001_mr32(address, 0x24);
+	pm8001_ha->gs_tbl.phy_state[4]	= pm8001_mr32(address, 0x28);
+	pm8001_ha->gs_tbl.phy_state[5]	= pm8001_mr32(address, 0x2C);
+	pm8001_ha->gs_tbl.phy_state[6]	= pm8001_mr32(address, 0x30);
+	pm8001_ha->gs_tbl.phy_state[7]	= pm8001_mr32(address, 0x34);
+	pm8001_ha->gs_tbl.reserved1		= pm8001_mr32(address, 0x38);
+	pm8001_ha->gs_tbl.reserved2		= pm8001_mr32(address, 0x3C);
+	pm8001_ha->gs_tbl.reserved3		= pm8001_mr32(address, 0x40);
+	pm8001_ha->gs_tbl.recover_err_info[0]	= pm8001_mr32(address, 0x44);
+	pm8001_ha->gs_tbl.recover_err_info[1]	= pm8001_mr32(address, 0x48);
+	pm8001_ha->gs_tbl.recover_err_info[2]	= pm8001_mr32(address, 0x4C);
+	pm8001_ha->gs_tbl.recover_err_info[3]	= pm8001_mr32(address, 0x50);
+	pm8001_ha->gs_tbl.recover_err_info[4]	= pm8001_mr32(address, 0x54);
+	pm8001_ha->gs_tbl.recover_err_info[5]	= pm8001_mr32(address, 0x58);
+	pm8001_ha->gs_tbl.recover_err_info[6]	= pm8001_mr32(address, 0x5C);
+	pm8001_ha->gs_tbl.recover_err_info[7]	= pm8001_mr32(address, 0x60);
+}
+
+/**
+ * read_inbnd_queue_table - read the inbound queue table and save it.
+ * @pm8001_ha: our hba card information
+ */
+static void __devinit
+read_inbnd_queue_table(struct pm8001_hba_info *pm8001_ha)
+{
+	int inbQ_num = 1;
+	int i;
+	void __iomem *address = pm8001_ha->inbnd_q_tbl_addr;
+	for (i = 0; i < inbQ_num; i++) {
+		u32 offset = i * 0x20;
+		pm8001_ha->inbnd_q_tbl[i].pi_pci_bar =
+		      get_pci_bar_index(pm8001_mr32(address, (offset + 0x14)));
+		pm8001_ha->inbnd_q_tbl[i].pi_offset =
+			pm8001_mr32(address, (offset + 0x18));
+	}
+}
+
+/**
+ * read_outbnd_queue_table - read the outbound queue table and save it.
+ * @pm8001_ha: our hba card information
+ */
+static void __devinit
+read_outbnd_queue_table(struct pm8001_hba_info *pm8001_ha)
+{
+	int outbQ_num = 1;
+	int i;
+	void __iomem *address = pm8001_ha->outbnd_q_tbl_addr;
+	for (i = 0; i < outbQ_num; i++) {
+		u32 offset = i * 0x24;
+		pm8001_ha->outbnd_q_tbl[i].ci_pci_bar =
+		      get_pci_bar_index(pm8001_mr32(address, (offset + 0x14)));
+		pm8001_ha->outbnd_q_tbl[i].ci_offset =
+			pm8001_mr32(address, (offset + 0x18));
+	}
+}
+
+/**
+ * init_default_table_values - init the default table.
+ * @pm8001_ha: our hba card information
+ */
+static void __devinit
+init_default_table_values(struct pm8001_hba_info *pm8001_ha)
+{
+	int qn = 1;
+	int i;
+	u32 offsetib, offsetob;
+	void __iomem *addressib = pm8001_ha->inbnd_q_tbl_addr;
+	void __iomem *addressob = pm8001_ha->outbnd_q_tbl_addr;
+
+	pm8001_ha->main_cfg_tbl.inbound_q_nppd_hppd			= 0;
+	pm8001_ha->main_cfg_tbl.outbound_hw_event_pid0_3 		= 0;
+	pm8001_ha->main_cfg_tbl.outbound_hw_event_pid4_7		= 0;
+	pm8001_ha->main_cfg_tbl.outbound_ncq_event_pid0_3		= 0;
+	pm8001_ha->main_cfg_tbl.outbound_ncq_event_pid4_7		= 0;
+	pm8001_ha->main_cfg_tbl.outbound_tgt_ITNexus_event_pid0_3	= 0;
+	pm8001_ha->main_cfg_tbl.outbound_tgt_ITNexus_event_pid4_7	= 0;
+	pm8001_ha->main_cfg_tbl.outbound_tgt_ssp_event_pid0_3	= 0;
+	pm8001_ha->main_cfg_tbl.outbound_tgt_ssp_event_pid4_7	= 0;
+	pm8001_ha->main_cfg_tbl.outbound_tgt_smp_event_pid0_3	= 0;
+	pm8001_ha->main_cfg_tbl.outbound_tgt_smp_event_pid4_7	= 0;
+
+	pm8001_ha->main_cfg_tbl.upper_event_log_addr		=
+		pm8001_ha->memoryMap.region[AAP1].phys_addr_hi;
+	pm8001_ha->main_cfg_tbl.lower_event_log_addr		=
+		pm8001_ha->memoryMap.region[AAP1].phys_addr_lo;
+	pm8001_ha->main_cfg_tbl.event_log_size	= PM8001_EVENT_LOG_SIZE;
+	pm8001_ha->main_cfg_tbl.event_log_option		= 0x01;
+	pm8001_ha->main_cfg_tbl.upper_iop_event_log_addr	=
+		pm8001_ha->memoryMap.region[IOP].phys_addr_hi;
+	pm8001_ha->main_cfg_tbl.lower_iop_event_log_addr	=
+		pm8001_ha->memoryMap.region[IOP].phys_addr_lo;
+	pm8001_ha->main_cfg_tbl.iop_event_log_size	= PM8001_EVENT_LOG_SIZE;
+	pm8001_ha->main_cfg_tbl.iop_event_log_option		= 0x01;
+	pm8001_ha->main_cfg_tbl.fatal_err_interrupt		= 0x01;
+	for (i = 0; i < qn; i++) {
+		pm8001_ha->inbnd_q_tbl[i].element_pri_size_cnt	=
+			0x00000100 | (0x00000040 << 16) | (0x00<<30);
+		pm8001_ha->inbnd_q_tbl[i].upper_base_addr	=
+			pm8001_ha->memoryMap.region[IB].phys_addr_hi;
+		pm8001_ha->inbnd_q_tbl[i].lower_base_addr	=
+		pm8001_ha->memoryMap.region[IB].phys_addr_lo;
+		pm8001_ha->inbnd_q_tbl[i].base_virt		=
+			(u8 *)pm8001_ha->memoryMap.region[IB].virt_ptr;
+		pm8001_ha->inbnd_q_tbl[i].total_length		=
+			pm8001_ha->memoryMap.region[IB].total_len;
+		pm8001_ha->inbnd_q_tbl[i].ci_upper_base_addr	=
+			pm8001_ha->memoryMap.region[CI].phys_addr_hi;
+		pm8001_ha->inbnd_q_tbl[i].ci_lower_base_addr	=
+			pm8001_ha->memoryMap.region[CI].phys_addr_lo;
+		pm8001_ha->inbnd_q_tbl[i].ci_virt		=
+			pm8001_ha->memoryMap.region[CI].virt_ptr;
+		offsetib = i * 0x20;
+		pm8001_ha->inbnd_q_tbl[i].pi_pci_bar		=
+			get_pci_bar_index(pm8001_mr32(addressib,
+				(offsetib + 0x14)));
+		pm8001_ha->inbnd_q_tbl[i].pi_offset		=
+			pm8001_mr32(addressib, (offsetib + 0x18));
+		pm8001_ha->inbnd_q_tbl[i].producer_idx		= 0;
+		pm8001_ha->inbnd_q_tbl[i].consumer_index	= 0;
+	}
+	for (i = 0; i < qn; i++) {
+		pm8001_ha->outbnd_q_tbl[i].element_size_cnt	=
+			256 | (64 << 16) | (1<<30);
+		pm8001_ha->outbnd_q_tbl[i].upper_base_addr	=
+			pm8001_ha->memoryMap.region[OB].phys_addr_hi;
+		pm8001_ha->outbnd_q_tbl[i].lower_base_addr	=
+			pm8001_ha->memoryMap.region[OB].phys_addr_lo;
+		pm8001_ha->outbnd_q_tbl[i].base_virt		=
+			(u8 *)pm8001_ha->memoryMap.region[OB].virt_ptr;
+		pm8001_ha->outbnd_q_tbl[i].total_length		=
+			pm8001_ha->memoryMap.region[OB].total_len;
+		pm8001_ha->outbnd_q_tbl[i].pi_upper_base_addr	=
+			pm8001_ha->memoryMap.region[PI].phys_addr_hi;
+		pm8001_ha->outbnd_q_tbl[i].pi_lower_base_addr	=
+			pm8001_ha->memoryMap.region[PI].phys_addr_lo;
+		pm8001_ha->outbnd_q_tbl[i].interrup_vec_cnt_delay	=
+			0 | (10 << 16) | (0 << 24);
+		pm8001_ha->outbnd_q_tbl[i].pi_virt		=
+			pm8001_ha->memoryMap.region[PI].virt_ptr;
+		offsetob = i * 0x24;
+		pm8001_ha->outbnd_q_tbl[i].ci_pci_bar		=
+			get_pci_bar_index(pm8001_mr32(addressob,
+			offsetob + 0x14));
+		pm8001_ha->outbnd_q_tbl[i].ci_offset		=
+			pm8001_mr32(addressob, (offsetob + 0x18));
+		pm8001_ha->outbnd_q_tbl[i].consumer_idx		= 0;
+		pm8001_ha->outbnd_q_tbl[i].producer_index	= 0;
+	}
+}
+
+/**
+ * update_main_config_table - update the main default table to the HBA.
+ * @pm8001_ha: our hba card information
+ */
+static void __devinit
+update_main_config_table(struct pm8001_hba_info *pm8001_ha)
+{
+	void __iomem *address = pm8001_ha->main_cfg_tbl_addr;
+	pm8001_mw32(address, 0x24,
+		pm8001_ha->main_cfg_tbl.inbound_q_nppd_hppd);
+	pm8001_mw32(address, 0x28,
+		pm8001_ha->main_cfg_tbl.outbound_hw_event_pid0_3);
+	pm8001_mw32(address, 0x2C,
+		pm8001_ha->main_cfg_tbl.outbound_hw_event_pid4_7);
+	pm8001_mw32(address, 0x30,
+		pm8001_ha->main_cfg_tbl.outbound_ncq_event_pid0_3);
+	pm8001_mw32(address, 0x34,
+		pm8001_ha->main_cfg_tbl.outbound_ncq_event_pid4_7);
+	pm8001_mw32(address, 0x38,
+		pm8001_ha->main_cfg_tbl.outbound_tgt_ITNexus_event_pid0_3);
+	pm8001_mw32(address, 0x3C,
+		pm8001_ha->main_cfg_tbl.outbound_tgt_ITNexus_event_pid4_7);
+	pm8001_mw32(address, 0x40,
+		pm8001_ha->main_cfg_tbl.outbound_tgt_ssp_event_pid0_3);
+	pm8001_mw32(address, 0x44,
+		pm8001_ha->main_cfg_tbl.outbound_tgt_ssp_event_pid4_7);
+	pm8001_mw32(address, 0x48,
+		pm8001_ha->main_cfg_tbl.outbound_tgt_smp_event_pid0_3);
+	pm8001_mw32(address, 0x4C,
+		pm8001_ha->main_cfg_tbl.outbound_tgt_smp_event_pid4_7);
+	pm8001_mw32(address, 0x50,
+		pm8001_ha->main_cfg_tbl.upper_event_log_addr);
+	pm8001_mw32(address, 0x54,
+		pm8001_ha->main_cfg_tbl.lower_event_log_addr);
+	pm8001_mw32(address, 0x58, pm8001_ha->main_cfg_tbl.event_log_size);
+	pm8001_mw32(address, 0x5C, pm8001_ha->main_cfg_tbl.event_log_option);
+	pm8001_mw32(address, 0x60,
+		pm8001_ha->main_cfg_tbl.upper_iop_event_log_addr);
+	pm8001_mw32(address, 0x64,
+		pm8001_ha->main_cfg_tbl.lower_iop_event_log_addr);
+	pm8001_mw32(address, 0x68, pm8001_ha->main_cfg_tbl.iop_event_log_size);
+	pm8001_mw32(address, 0x6C,
+		pm8001_ha->main_cfg_tbl.iop_event_log_option);
+	pm8001_mw32(address, 0x70,
+		pm8001_ha->main_cfg_tbl.fatal_err_interrupt);
+}
+
+/**
+ * update_inbnd_queue_table - update the inbound queue table to the HBA.
+ * @pm8001_ha: our hba card information
+ */
+static void __devinit
+update_inbnd_queue_table(struct pm8001_hba_info *pm8001_ha, int number)
+{
+	void __iomem *address = pm8001_ha->inbnd_q_tbl_addr;
+	u16 offset = number * 0x20;
+	pm8001_mw32(address, offset + 0x00,
+		pm8001_ha->inbnd_q_tbl[number].element_pri_size_cnt);
+	pm8001_mw32(address, offset + 0x04,
+		pm8001_ha->inbnd_q_tbl[number].upper_base_addr);
+	pm8001_mw32(address, offset + 0x08,
+		pm8001_ha->inbnd_q_tbl[number].lower_base_addr);
+	pm8001_mw32(address, offset + 0x0C,
+		pm8001_ha->inbnd_q_tbl[number].ci_upper_base_addr);
+	pm8001_mw32(address, offset + 0x10,
+		pm8001_ha->inbnd_q_tbl[number].ci_lower_base_addr);
+}
+
+/**
+ * update_outbnd_queue_table - update the outbound queue table to the HBA.
+ * @pm8001_ha: our hba card information
+ */
+static void __devinit
+update_outbnd_queue_table(struct pm8001_hba_info *pm8001_ha, int number)
+{
+	void __iomem *address = pm8001_ha->outbnd_q_tbl_addr;
+	u16 offset = number * 0x24;
+	pm8001_mw32(address, offset + 0x00,
+		pm8001_ha->outbnd_q_tbl[number].element_size_cnt);
+	pm8001_mw32(address, offset + 0x04,
+		pm8001_ha->outbnd_q_tbl[number].upper_base_addr);
+	pm8001_mw32(address, offset + 0x08,
+		pm8001_ha->outbnd_q_tbl[number].lower_base_addr);
+	pm8001_mw32(address, offset + 0x0C,
+		pm8001_ha->outbnd_q_tbl[number].pi_upper_base_addr);
+	pm8001_mw32(address, offset + 0x10,
+		pm8001_ha->outbnd_q_tbl[number].pi_lower_base_addr);
+	pm8001_mw32(address, offset + 0x1C,
+		pm8001_ha->outbnd_q_tbl[number].interrup_vec_cnt_delay);
+}
+
+/**
+ * bar4_shift - function is called to shift BAR base address
+ * @pm8001_ha : our hba card infomation
+ * @shiftValue : shifting value in memory bar.
+ */
+static int bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue)
+{
+	u32 regVal;
+	u32 max_wait_count;
+
+	/* program the inbound AXI translation Lower Address */
+	pm8001_cw32(pm8001_ha, 1, SPC_IBW_AXI_TRANSLATION_LOW, shiftValue);
+
+	/* confirm the setting is written */
+	max_wait_count = 1 * 1000 * 1000;  /* 1 sec */
+	do {
+		udelay(1);
+		regVal = pm8001_cr32(pm8001_ha, 1, SPC_IBW_AXI_TRANSLATION_LOW);
+	} while ((regVal != shiftValue) && (--max_wait_count));
+
+	if (!max_wait_count) {
+		PM8001_INIT_DBG(pm8001_ha,
+			pm8001_printk("TIMEOUT:SPC_IBW_AXI_TRANSLATION_LOW"
+			" = 0x%x\n", regVal));
+		return -1;
+	}
+	return 0;
+}
+
+/**
+ * mpi_set_phys_g3_with_ssc
+ * @pm8001_ha: our hba card information
+ * @SSCbit: set SSCbit to 0 to disable all phys ssc; 1 to enable all phys ssc.
+ */
+static void __devinit
+mpi_set_phys_g3_with_ssc(struct pm8001_hba_info *pm8001_ha, u32 SSCbit)
+{
+	u32 offset;
+	u32 value;
+	u32 i, j;
+	u32 bit_cnt;
+
+#define SAS2_SETTINGS_LOCAL_PHY_0_3_SHIFT_ADDR 0x00030000
+#define SAS2_SETTINGS_LOCAL_PHY_4_7_SHIFT_ADDR 0x00040000
+#define SAS2_SETTINGS_LOCAL_PHY_0_3_OFFSET 0x1074
+#define SAS2_SETTINGS_LOCAL_PHY_4_7_OFFSET 0x1074
+#define PHY_G3_WITHOUT_SSC_BIT_SHIFT 12
+#define PHY_G3_WITH_SSC_BIT_SHIFT 13
+#define SNW3_PHY_CAPABILITIES_PARITY 31
+
+   /*
+    * Using shifted destination address 0x3_0000:0x1074 + 0x4000*N (N=0:3)
+    * Using shifted destination address 0x4_0000:0x1074 + 0x4000*(N-4) (N=4:7)
+    */
+	if (-1 == bar4_shift(pm8001_ha, SAS2_SETTINGS_LOCAL_PHY_0_3_SHIFT_ADDR))
+		return;
+	/* set SSC bit of PHY 0 - 3 */
+	for (i = 0; i < 4; i++) {
+		offset = SAS2_SETTINGS_LOCAL_PHY_0_3_OFFSET + 0x4000 * i;
+		value = pm8001_cr32(pm8001_ha, 2, offset);
+		if (SSCbit) {
+			value |= 0x00000001 << PHY_G3_WITH_SSC_BIT_SHIFT;
+			value &= ~(0x00000001 << PHY_G3_WITHOUT_SSC_BIT_SHIFT);
+		} else {
+			value |= 0x00000001 << PHY_G3_WITHOUT_SSC_BIT_SHIFT;
+			value &= ~(0x00000001 << PHY_G3_WITH_SSC_BIT_SHIFT);
+		}
+		bit_cnt = 0;
+		for (j = 0; j < 31; j++)
+			if ((value >> j) & 0x00000001)
+				bit_cnt++;
+		if (bit_cnt % 2)
+			value &= ~(0x00000001 << SNW3_PHY_CAPABILITIES_PARITY);
+		else
+			value |= 0x00000001 << SNW3_PHY_CAPABILITIES_PARITY;
+
+		pm8001_cw32(pm8001_ha, 2, offset, value);
+	}
+
+	/* shift membase 3 for SAS2_SETTINGS_LOCAL_PHY 4 - 7 */
+	if (-1 == bar4_shift(pm8001_ha, SAS2_SETTINGS_LOCAL_PHY_4_7_SHIFT_ADDR))
+		return;
+
+	/* set SSC bit of PHY 4 - 7 */
+	for (i = 4; i < 8; i++) {
+		offset = SAS2_SETTINGS_LOCAL_PHY_4_7_OFFSET + 0x4000 * (i-4);
+		value = pm8001_cr32(pm8001_ha, 2, offset);
+		if (SSCbit) {
+			value |= 0x00000001 << PHY_G3_WITH_SSC_BIT_SHIFT;
+			value &= ~(0x00000001 << PHY_G3_WITHOUT_SSC_BIT_SHIFT);
+		} else {
+			value |= 0x00000001 << PHY_G3_WITHOUT_SSC_BIT_SHIFT;
+			value &= ~(0x00000001 << PHY_G3_WITH_SSC_BIT_SHIFT);
+		}
+		bit_cnt = 0;
+		for (j = 0; j < 31; j++)
+			if ((value >> j) & 0x00000001)
+				bit_cnt++;
+		if (bit_cnt % 2)
+			value &= ~(0x00000001 << SNW3_PHY_CAPABILITIES_PARITY);
+		else
+			value |= 0x00000001 << SNW3_PHY_CAPABILITIES_PARITY;
+
+		pm8001_cw32(pm8001_ha, 2, offset, value);
+	}
+
+	/*set the shifted destination address to 0x0 to avoid error operation */
+	bar4_shift(pm8001_ha, 0x0);
+	return;
+}
+
+/**
+ * mpi_set_open_retry_interval_reg
+ * @pm8001_ha: our hba card information
+ * @interval - interval time for each OPEN_REJECT (RETRY). The units are in 1us.
+ */
+static void __devinit
+mpi_set_open_retry_interval_reg(struct pm8001_hba_info *pm8001_ha,
+				u32 interval)
+{
+	u32 offset;
+	u32 value;
+	u32 i;
+
+#define OPEN_RETRY_INTERVAL_PHY_0_3_SHIFT_ADDR 0x00030000
+#define OPEN_RETRY_INTERVAL_PHY_4_7_SHIFT_ADDR 0x00040000
+#define OPEN_RETRY_INTERVAL_PHY_0_3_OFFSET 0x30B4
+#define OPEN_RETRY_INTERVAL_PHY_4_7_OFFSET 0x30B4
+#define OPEN_RETRY_INTERVAL_REG_MASK 0x0000FFFF
+
+	value = interval & OPEN_RETRY_INTERVAL_REG_MASK;
+	/* shift bar and set the OPEN_REJECT(RETRY) interval time of PHY 0 -3.*/
+	if (-1 == bar4_shift(pm8001_ha,
+			     OPEN_RETRY_INTERVAL_PHY_0_3_SHIFT_ADDR))
+		return;
+	for (i = 0; i < 4; i++) {
+		offset = OPEN_RETRY_INTERVAL_PHY_0_3_OFFSET + 0x4000 * i;
+		pm8001_cw32(pm8001_ha, 2, offset, value);
+	}
+
+	if (-1 == bar4_shift(pm8001_ha,
+			     OPEN_RETRY_INTERVAL_PHY_4_7_SHIFT_ADDR))
+		return;
+	for (i = 4; i < 8; i++) {
+		offset = OPEN_RETRY_INTERVAL_PHY_4_7_OFFSET + 0x4000 * (i-4);
+		pm8001_cw32(pm8001_ha, 2, offset, value);
+	}
+	/*set the shifted destination address to 0x0 to avoid error operation */
+	bar4_shift(pm8001_ha, 0x0);
+	return;
+}
+
+/**
+ * mpi_init_check - check firmware initialization status.
+ * @pm8001_ha: our hba card information
+ */
+static int mpi_init_check(struct pm8001_hba_info *pm8001_ha)
+{
+	u32 max_wait_count;
+	u32 value;
+	u32 gst_len_mpistate;
+	/* Write bit0=1 to Inbound DoorBell Register to tell the SPC FW the
+	table is updated */
+	pm8001_cw32(pm8001_ha, 0, MSGU_IBDB_SET, SPC_MSGU_CFG_TABLE_UPDATE);
+	/* wait until Inbound DoorBell Clear Register toggled */
+	max_wait_count = 1 * 1000 * 1000;/* 1 sec */
+	do {
+		udelay(1);
+		value = pm8001_cr32(pm8001_ha, 0, MSGU_IBDB_SET);
+		value &= SPC_MSGU_CFG_TABLE_UPDATE;
+	} while ((value != 0) && (--max_wait_count));
+
+	if (!max_wait_count)
+		return -1;
+	/* check the MPI-State for initialization */
+	gst_len_mpistate =
+		pm8001_mr32(pm8001_ha->general_stat_tbl_addr,
+		GST_GSTLEN_MPIS_OFFSET);
+	if (GST_MPI_STATE_INIT != (gst_len_mpistate & GST_MPI_STATE_MASK))
+		return -1;
+	/* check MPI Initialization error */
+	gst_len_mpistate = gst_len_mpistate >> 16;
+	if (0x0000 != gst_len_mpistate)
+		return -1;
+	return 0;
+}
+
+/**
+ * check_fw_ready - The LLDD check if the FW is ready, if not, return error.
+ * @pm8001_ha: our hba card information
+ */
+static int check_fw_ready(struct pm8001_hba_info *pm8001_ha)
+{
+	u32 value, value1;
+	u32 max_wait_count;
+	/* check error state */
+	value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
+	value1 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_2);
+	/* check AAP error */
+	if (SCRATCH_PAD1_ERR == (value & SCRATCH_PAD_STATE_MASK)) {
+		/* error state */
+		value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_0);
+		return -1;
+	}
+
+	/* check IOP error */
+	if (SCRATCH_PAD2_ERR == (value1 & SCRATCH_PAD_STATE_MASK)) {
+		/* error state */
+		value1 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3);
+		return -1;
+	}
+
+	/* bit 4-31 of scratch pad1 should be zeros if it is not
+	in error state*/
+	if (value & SCRATCH_PAD1_STATE_MASK) {
+		/* error case */
+		pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_0);
+		return -1;
+	}
+
+	/* bit 2, 4-31 of scratch pad2 should be zeros if it is not
+	in error state */
+	if (value1 & SCRATCH_PAD2_STATE_MASK) {
+		/* error case */
+		return -1;
+	}
+
+	max_wait_count = 1 * 1000 * 1000;/* 1 sec timeout */
+
+	/* wait until scratch pad 1 and 2 registers in ready state  */
+	do {
+		udelay(1);
+		value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1)
+			& SCRATCH_PAD1_RDY;
+		value1 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_2)
+			& SCRATCH_PAD2_RDY;
+		if ((--max_wait_count) == 0)
+			return -1;
+	} while ((value != SCRATCH_PAD1_RDY) || (value1 != SCRATCH_PAD2_RDY));
+	return 0;
+}
+
+static void init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha)
+{
+	void __iomem *base_addr;
+	u32	value;
+	u32	offset;
+	u32	pcibar;
+	u32	pcilogic;
+
+	value = pm8001_cr32(pm8001_ha, 0, 0x44);
+	offset = value & 0x03FFFFFF;
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("Scratchpad 0 Offset: %x \n", offset));
+	pcilogic = (value & 0xFC000000) >> 26;
+	pcibar = get_pci_bar_index(pcilogic);
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("Scratchpad 0 PCI BAR: %d \n", pcibar));
+	pm8001_ha->main_cfg_tbl_addr = base_addr =
+		pm8001_ha->io_mem[pcibar].memvirtaddr + offset;
+	pm8001_ha->general_stat_tbl_addr =
+		base_addr + pm8001_cr32(pm8001_ha, pcibar, offset + 0x18);
+	pm8001_ha->inbnd_q_tbl_addr =
+		base_addr + pm8001_cr32(pm8001_ha, pcibar, offset + 0x1C);
+	pm8001_ha->outbnd_q_tbl_addr =
+		base_addr + pm8001_cr32(pm8001_ha, pcibar, offset + 0x20);
+}
+
+/**
+ * pm8001_chip_init - the main init function that initialize whole PM8001 chip.
+ * @pm8001_ha: our hba card information
+ */
+static int __devinit pm8001_chip_init(struct pm8001_hba_info *pm8001_ha)
+{
+	/* check the firmware status */
+	if (-1 == check_fw_ready(pm8001_ha)) {
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("Firmware is not ready!\n"));
+		return -EBUSY;
+	}
+
+	/* Initialize pci space address eg: mpi offset */
+	init_pci_device_addresses(pm8001_ha);
+	init_default_table_values(pm8001_ha);
+	read_main_config_table(pm8001_ha);
+	read_general_status_table(pm8001_ha);
+	read_inbnd_queue_table(pm8001_ha);
+	read_outbnd_queue_table(pm8001_ha);
+	/* update main config table ,inbound table and outbound table */
+	update_main_config_table(pm8001_ha);
+	update_inbnd_queue_table(pm8001_ha, 0);
+	update_outbnd_queue_table(pm8001_ha, 0);
+	mpi_set_phys_g3_with_ssc(pm8001_ha, 0);
+	mpi_set_open_retry_interval_reg(pm8001_ha, 7);
+	/* notify firmware update finished and check initialization status */
+	if (0 == mpi_init_check(pm8001_ha)) {
+		PM8001_INIT_DBG(pm8001_ha,
+			pm8001_printk("MPI initialize successful!\n"));
+	} else
+		return -EBUSY;
+	/*This register is a 16-bit timer with a resolution of 1us. This is the
+	timer used for interrupt delay/coalescing in the PCIe Application Layer.
+	Zero is not a valid value. A value of 1 in the register will cause the
+	interrupts to be normal. A value greater than 1 will cause coalescing
+	delays.*/
+	pm8001_cw32(pm8001_ha, 1, 0x0033c0, 0x1);
+	pm8001_cw32(pm8001_ha, 1, 0x0033c4, 0x0);
+	return 0;
+}
+
+static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha)
+{
+	u32 max_wait_count;
+	u32 value;
+	u32 gst_len_mpistate;
+	init_pci_device_addresses(pm8001_ha);
+	/* Write bit1=1 to Inbound DoorBell Register to tell the SPC FW the
+	table is stop */
+	pm8001_cw32(pm8001_ha, 0, MSGU_IBDB_SET, SPC_MSGU_CFG_TABLE_RESET);
+
+	/* wait until Inbound DoorBell Clear Register toggled */
+	max_wait_count = 1 * 1000 * 1000;/* 1 sec */
+	do {
+		udelay(1);
+		value = pm8001_cr32(pm8001_ha, 0, MSGU_IBDB_SET);
+		value &= SPC_MSGU_CFG_TABLE_RESET;
+	} while ((value != 0) && (--max_wait_count));
+
+	if (!max_wait_count) {
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("TIMEOUT:IBDB value/=0x%x\n", value));
+		return -1;
+	}
+
+	/* check the MPI-State for termination in progress */
+	/* wait until Inbound DoorBell Clear Register toggled */
+	max_wait_count = 1 * 1000 * 1000;  /* 1 sec */
+	do {
+		udelay(1);
+		gst_len_mpistate =
+			pm8001_mr32(pm8001_ha->general_stat_tbl_addr,
+			GST_GSTLEN_MPIS_OFFSET);
+		if (GST_MPI_STATE_UNINIT ==
+			(gst_len_mpistate & GST_MPI_STATE_MASK))
+			break;
+	} while (--max_wait_count);
+	if (!max_wait_count) {
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk(" TIME OUT MPI State = 0x%x\n",
+				gst_len_mpistate & GST_MPI_STATE_MASK));
+		return -1;
+	}
+	return 0;
+}
+
+/**
+ * soft_reset_ready_check - Function to check FW is ready for soft reset.
+ * @pm8001_ha: our hba card information
+ */
+static u32 soft_reset_ready_check(struct pm8001_hba_info *pm8001_ha)
+{
+	u32 regVal, regVal1, regVal2;
+	if (mpi_uninit_check(pm8001_ha) != 0) {
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("MPI state is not ready\n"));
+		return -1;
+	}
+	/* read the scratch pad 2 register bit 2 */
+	regVal = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_2)
+		& SCRATCH_PAD2_FWRDY_RST;
+	if (regVal == SCRATCH_PAD2_FWRDY_RST) {
+		PM8001_INIT_DBG(pm8001_ha,
+			pm8001_printk("Firmware is ready for reset .\n"));
+	} else {
+	/* Trigger NMI twice via RB6 */
+		if (-1 == bar4_shift(pm8001_ha, RB6_ACCESS_REG)) {
+			PM8001_FAIL_DBG(pm8001_ha,
+				pm8001_printk("Shift Bar4 to 0x%x failed\n",
+					RB6_ACCESS_REG));
+			return -1;
+		}
+		pm8001_cw32(pm8001_ha, 2, SPC_RB6_OFFSET,
+			RB6_MAGIC_NUMBER_RST);
+		pm8001_cw32(pm8001_ha, 2, SPC_RB6_OFFSET, RB6_MAGIC_NUMBER_RST);
+		/* wait for 100 ms */
+		mdelay(100);
+		regVal = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_2) &
+			SCRATCH_PAD2_FWRDY_RST;
+		if (regVal != SCRATCH_PAD2_FWRDY_RST) {
+			regVal1 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
+			regVal2 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_2);
+			PM8001_FAIL_DBG(pm8001_ha,
+				pm8001_printk("TIMEOUT:MSGU_SCRATCH_PAD1"
+				"=0x%x, MSGU_SCRATCH_PAD2=0x%x\n",
+				regVal1, regVal2));
+			PM8001_FAIL_DBG(pm8001_ha,
+				pm8001_printk("SCRATCH_PAD0 value = 0x%x\n",
+				pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_0)));
+			PM8001_FAIL_DBG(pm8001_ha,
+				pm8001_printk("SCRATCH_PAD3 value = 0x%x\n",
+				pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3)));
+			return -1;
+		}
+	}
+	return 0;
+}
+
+/**
+ * pm8001_chip_soft_rst - soft reset the PM8001 chip, so that the clear all
+ * the FW register status to the originated status.
+ * @pm8001_ha: our hba card information
+ * @signature: signature in host scratch pad0 register.
+ */
+static int
+pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
+{
+	u32	regVal, toggleVal;
+	u32	max_wait_count;
+	u32	regVal1, regVal2, regVal3;
+
+	/* step1: Check FW is ready for soft reset */
+	if (soft_reset_ready_check(pm8001_ha) != 0) {
+		PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("FW is not ready\n"));
+		return -1;
+	}
+
+	/* step 2: clear NMI status register on AAP1 and IOP, write the same
+	value to clear */
+	/* map 0x60000 to BAR4(0x20), BAR2(win) */
+	if (-1 == bar4_shift(pm8001_ha, MBIC_AAP1_ADDR_BASE)) {
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("Shift Bar4 to 0x%x failed\n",
+			MBIC_AAP1_ADDR_BASE));
+		return -1;
+	}
+	regVal = pm8001_cr32(pm8001_ha, 2, MBIC_NMI_ENABLE_VPE0_IOP);
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("MBIC - NMI Enable VPE0 (IOP)= 0x%x\n", regVal));
+	pm8001_cw32(pm8001_ha, 2, MBIC_NMI_ENABLE_VPE0_IOP, 0x0);
+	/* map 0x70000 to BAR4(0x20), BAR2(win) */
+	if (-1 == bar4_shift(pm8001_ha, MBIC_IOP_ADDR_BASE)) {
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("Shift Bar4 to 0x%x failed\n",
+			MBIC_IOP_ADDR_BASE));
+		return -1;
+	}
+	regVal = pm8001_cr32(pm8001_ha, 2, MBIC_NMI_ENABLE_VPE0_AAP1);
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("MBIC - NMI Enable VPE0 (AAP1)= 0x%x\n", regVal));
+	pm8001_cw32(pm8001_ha, 2, MBIC_NMI_ENABLE_VPE0_AAP1, 0x0);
+
+	regVal = pm8001_cr32(pm8001_ha, 1, PCIE_EVENT_INTERRUPT_ENABLE);
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("PCIE -Event Interrupt Enable = 0x%x\n", regVal));
+	pm8001_cw32(pm8001_ha, 1, PCIE_EVENT_INTERRUPT_ENABLE, 0x0);
+
+	regVal = pm8001_cr32(pm8001_ha, 1, PCIE_EVENT_INTERRUPT);
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("PCIE - Event Interrupt  = 0x%x\n", regVal));
+	pm8001_cw32(pm8001_ha, 1, PCIE_EVENT_INTERRUPT, regVal);
+
+	regVal = pm8001_cr32(pm8001_ha, 1, PCIE_ERROR_INTERRUPT_ENABLE);
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("PCIE -Error Interrupt Enable = 0x%x\n", regVal));
+	pm8001_cw32(pm8001_ha, 1, PCIE_ERROR_INTERRUPT_ENABLE, 0x0);
+
+	regVal = pm8001_cr32(pm8001_ha, 1, PCIE_ERROR_INTERRUPT);
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("PCIE - Error Interrupt = 0x%x\n", regVal));
+	pm8001_cw32(pm8001_ha, 1, PCIE_ERROR_INTERRUPT, regVal);
+
+	/* read the scratch pad 1 register bit 2 */
+	regVal = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1)
+		& SCRATCH_PAD1_RST;
+	toggleVal = regVal ^ SCRATCH_PAD1_RST;
+
+	/* set signature in host scratch pad0 register to tell SPC that the
+	host performs the soft reset */
+	pm8001_cw32(pm8001_ha, 0, MSGU_HOST_SCRATCH_PAD_0, signature);
+
+	/* read required registers for confirmming */
+	/* map 0x0700000 to BAR4(0x20), BAR2(win) */
+	if (-1 == bar4_shift(pm8001_ha, GSM_ADDR_BASE)) {
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("Shift Bar4 to 0x%x failed\n",
+			GSM_ADDR_BASE));
+		return -1;
+	}
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("GSM 0x0(0x00007b88)-GSM Configuration and"
+		" Reset = 0x%x\n",
+		pm8001_cr32(pm8001_ha, 2, GSM_CONFIG_RESET)));
+
+	/* step 3: host read GSM Configuration and Reset register */
+	regVal = pm8001_cr32(pm8001_ha, 2, GSM_CONFIG_RESET);
+	/* Put those bits to low */
+	/* GSM XCBI offset = 0x70 0000
+	0x00 Bit 13 COM_SLV_SW_RSTB 1
+	0x00 Bit 12 QSSP_SW_RSTB 1
+	0x00 Bit 11 RAAE_SW_RSTB 1
+	0x00 Bit 9 RB_1_SW_RSTB 1
+	0x00 Bit 8 SM_SW_RSTB 1
+	*/
+	regVal &= ~(0x00003b00);
+	/* host write GSM Configuration and Reset register */
+	pm8001_cw32(pm8001_ha, 2, GSM_CONFIG_RESET, regVal);
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("GSM 0x0 (0x00007b88 ==> 0x00004088) - GSM "
+		"Configuration and Reset is set to = 0x%x\n",
+		pm8001_cr32(pm8001_ha, 2, GSM_CONFIG_RESET)));
+
+	/* step 4: */
+	/* disable GSM - Read Address Parity Check */
+	regVal1 = pm8001_cr32(pm8001_ha, 2, GSM_READ_ADDR_PARITY_CHECK);
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("GSM 0x700038 - Read Address Parity Check "
+		"Enable = 0x%x\n", regVal1));
+	pm8001_cw32(pm8001_ha, 2, GSM_READ_ADDR_PARITY_CHECK, 0x0);
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("GSM 0x700038 - Read Address Parity Check Enable"
+		"is set to = 0x%x\n",
+		pm8001_cr32(pm8001_ha, 2, GSM_READ_ADDR_PARITY_CHECK)));
+
+	/* disable GSM - Write Address Parity Check */
+	regVal2 = pm8001_cr32(pm8001_ha, 2, GSM_WRITE_ADDR_PARITY_CHECK);
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("GSM 0x700040 - Write Address Parity Check"
+		" Enable = 0x%x\n", regVal2));
+	pm8001_cw32(pm8001_ha, 2, GSM_WRITE_ADDR_PARITY_CHECK, 0x0);
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("GSM 0x700040 - Write Address Parity Check "
+		"Enable is set to = 0x%x\n",
+		pm8001_cr32(pm8001_ha, 2, GSM_WRITE_ADDR_PARITY_CHECK)));
+
+	/* disable GSM - Write Data Parity Check */
+	regVal3 = pm8001_cr32(pm8001_ha, 2, GSM_WRITE_DATA_PARITY_CHECK);
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("GSM 0x300048 - Write Data Parity Check"
+		" Enable = 0x%x\n", regVal3));
+	pm8001_cw32(pm8001_ha, 2, GSM_WRITE_DATA_PARITY_CHECK, 0x0);
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("GSM 0x300048 - Write Data Parity Check Enable"
+		"is set to = 0x%x\n",
+	pm8001_cr32(pm8001_ha, 2, GSM_WRITE_DATA_PARITY_CHECK)));
+
+	/* step 5: delay 10 usec */
+	udelay(10);
+	/* step 5-b: set GPIO-0 output control to tristate anyway */
+	if (-1 == bar4_shift(pm8001_ha, GPIO_ADDR_BASE)) {
+		PM8001_INIT_DBG(pm8001_ha,
+				pm8001_printk("Shift Bar4 to 0x%x failed\n",
+				GPIO_ADDR_BASE));
+		return -1;
+	}
+	regVal = pm8001_cr32(pm8001_ha, 2, GPIO_GPIO_0_0UTPUT_CTL_OFFSET);
+		PM8001_INIT_DBG(pm8001_ha,
+				pm8001_printk("GPIO Output Control Register:"
+				" = 0x%x\n", regVal));
+	/* set GPIO-0 output control to tri-state */
+	regVal &= 0xFFFFFFFC;
+	pm8001_cw32(pm8001_ha, 2, GPIO_GPIO_0_0UTPUT_CTL_OFFSET, regVal);
+
+	/* Step 6: Reset the IOP and AAP1 */
+	/* map 0x00000 to BAR4(0x20), BAR2(win) */
+	if (-1 == bar4_shift(pm8001_ha, SPC_TOP_LEVEL_ADDR_BASE)) {
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("SPC Shift Bar4 to 0x%x failed\n",
+			SPC_TOP_LEVEL_ADDR_BASE));
+		return -1;
+	}
+	regVal = pm8001_cr32(pm8001_ha, 2, SPC_REG_RESET);
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("Top Register before resetting IOP/AAP1"
+		":= 0x%x\n", regVal));
+	regVal &= ~(SPC_REG_RESET_PCS_IOP_SS | SPC_REG_RESET_PCS_AAP1_SS);
+	pm8001_cw32(pm8001_ha, 2, SPC_REG_RESET, regVal);
+
+	/* step 7: Reset the BDMA/OSSP */
+	regVal = pm8001_cr32(pm8001_ha, 2, SPC_REG_RESET);
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("Top Register before resetting BDMA/OSSP"
+		": = 0x%x\n", regVal));
+	regVal &= ~(SPC_REG_RESET_BDMA_CORE | SPC_REG_RESET_OSSP);
+	pm8001_cw32(pm8001_ha, 2, SPC_REG_RESET, regVal);
+
+	/* step 8: delay 10 usec */
+	udelay(10);
+
+	/* step 9: bring the BDMA and OSSP out of reset */
+	regVal = pm8001_cr32(pm8001_ha, 2, SPC_REG_RESET);
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("Top Register before bringing up BDMA/OSSP"
+		":= 0x%x\n", regVal));
+	regVal |= (SPC_REG_RESET_BDMA_CORE | SPC_REG_RESET_OSSP);
+	pm8001_cw32(pm8001_ha, 2, SPC_REG_RESET, regVal);
+
+	/* step 10: delay 10 usec */
+	udelay(10);
+
+	/* step 11: reads and sets the GSM Configuration and Reset Register */
+	/* map 0x0700000 to BAR4(0x20), BAR2(win) */
+	if (-1 == bar4_shift(pm8001_ha, GSM_ADDR_BASE)) {
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("SPC Shift Bar4 to 0x%x failed\n",
+			GSM_ADDR_BASE));
+		return -1;
+	}
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("GSM 0x0 (0x00007b88)-GSM Configuration and "
+		"Reset = 0x%x\n", pm8001_cr32(pm8001_ha, 2, GSM_CONFIG_RESET)));
+	regVal = pm8001_cr32(pm8001_ha, 2, GSM_CONFIG_RESET);
+	/* Put those bits to high */
+	/* GSM XCBI offset = 0x70 0000
+	0x00 Bit 13 COM_SLV_SW_RSTB 1
+	0x00 Bit 12 QSSP_SW_RSTB 1
+	0x00 Bit 11 RAAE_SW_RSTB 1
+	0x00 Bit 9   RB_1_SW_RSTB 1
+	0x00 Bit 8   SM_SW_RSTB 1
+	*/
+	regVal |= (GSM_CONFIG_RESET_VALUE);
+	pm8001_cw32(pm8001_ha, 2, GSM_CONFIG_RESET, regVal);
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("GSM (0x00004088 ==> 0x00007b88) - GSM"
+		" Configuration and Reset is set to = 0x%x\n",
+		pm8001_cr32(pm8001_ha, 2, GSM_CONFIG_RESET)));
+
+	/* step 12: Restore GSM - Read Address Parity Check */
+	regVal = pm8001_cr32(pm8001_ha, 2, GSM_READ_ADDR_PARITY_CHECK);
+	/* just for debugging */
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("GSM 0x700038 - Read Address Parity Check Enable"
+		" = 0x%x\n", regVal));
+	pm8001_cw32(pm8001_ha, 2, GSM_READ_ADDR_PARITY_CHECK, regVal1);
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("GSM 0x700038 - Read Address Parity"
+		" Check Enable is set to = 0x%x\n",
+		pm8001_cr32(pm8001_ha, 2, GSM_READ_ADDR_PARITY_CHECK)));
+	/* Restore GSM - Write Address Parity Check */
+	regVal = pm8001_cr32(pm8001_ha, 2, GSM_WRITE_ADDR_PARITY_CHECK);
+	pm8001_cw32(pm8001_ha, 2, GSM_WRITE_ADDR_PARITY_CHECK, regVal2);
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("GSM 0x700040 - Write Address Parity Check"
+		" Enable is set to = 0x%x\n",
+		pm8001_cr32(pm8001_ha, 2, GSM_WRITE_ADDR_PARITY_CHECK)));
+	/* Restore GSM - Write Data Parity Check */
+	regVal = pm8001_cr32(pm8001_ha, 2, GSM_WRITE_DATA_PARITY_CHECK);
+	pm8001_cw32(pm8001_ha, 2, GSM_WRITE_DATA_PARITY_CHECK, regVal3);
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("GSM 0x700048 - Write Data Parity Check Enable"
+		"is set to = 0x%x\n",
+		pm8001_cr32(pm8001_ha, 2, GSM_WRITE_DATA_PARITY_CHECK)));
+
+	/* step 13: bring the IOP and AAP1 out of reset */
+	/* map 0x00000 to BAR4(0x20), BAR2(win) */
+	if (-1 == bar4_shift(pm8001_ha, SPC_TOP_LEVEL_ADDR_BASE)) {
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("Shift Bar4 to 0x%x failed\n",
+			SPC_TOP_LEVEL_ADDR_BASE));
+		return -1;
+	}
+	regVal = pm8001_cr32(pm8001_ha, 2, SPC_REG_RESET);
+	regVal |= (SPC_REG_RESET_PCS_IOP_SS | SPC_REG_RESET_PCS_AAP1_SS);
+	pm8001_cw32(pm8001_ha, 2, SPC_REG_RESET, regVal);
+
+	/* step 14: delay 10 usec - Normal Mode */
+	udelay(10);
+	/* check Soft Reset Normal mode or Soft Reset HDA mode */
+	if (signature == SPC_SOFT_RESET_SIGNATURE) {
+		/* step 15 (Normal Mode): wait until scratch pad1 register
+		bit 2 toggled */
+		max_wait_count = 2 * 1000 * 1000;/* 2 sec */
+		do {
+			udelay(1);
+			regVal = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1) &
+				SCRATCH_PAD1_RST;
+		} while ((regVal != toggleVal) && (--max_wait_count));
+
+		if (!max_wait_count) {
+			regVal = pm8001_cr32(pm8001_ha, 0,
+				MSGU_SCRATCH_PAD_1);
+			PM8001_FAIL_DBG(pm8001_ha,
+				pm8001_printk("TIMEOUT : ToggleVal 0x%x,"
+				"MSGU_SCRATCH_PAD1 = 0x%x\n",
+				toggleVal, regVal));
+			PM8001_FAIL_DBG(pm8001_ha,
+				pm8001_printk("SCRATCH_PAD0 value = 0x%x\n",
+				pm8001_cr32(pm8001_ha, 0,
+				MSGU_SCRATCH_PAD_0)));
+			PM8001_FAIL_DBG(pm8001_ha,
+				pm8001_printk("SCRATCH_PAD2 value = 0x%x\n",
+				pm8001_cr32(pm8001_ha, 0,
+				MSGU_SCRATCH_PAD_2)));
+			PM8001_FAIL_DBG(pm8001_ha,
+				pm8001_printk("SCRATCH_PAD3 value = 0x%x\n",
+				pm8001_cr32(pm8001_ha, 0,
+				MSGU_SCRATCH_PAD_3)));
+			return -1;
+		}
+
+		/* step 16 (Normal) - Clear ODMR and ODCR */
+		pm8001_cw32(pm8001_ha, 0, MSGU_ODCR, ODCR_CLEAR_ALL);
+		pm8001_cw32(pm8001_ha, 0, MSGU_ODMR, ODMR_CLEAR_ALL);
+
+		/* step 17 (Normal Mode): wait for the FW and IOP to get
+		ready - 1 sec timeout */
+		/* Wait for the SPC Configuration Table to be ready */
+		if (check_fw_ready(pm8001_ha) == -1) {
+			regVal = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
+			/* return error if MPI Configuration Table not ready */
+			PM8001_INIT_DBG(pm8001_ha,
+				pm8001_printk("FW not ready SCRATCH_PAD1"
+				" = 0x%x\n", regVal));
+			regVal = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_2);
+			/* return error if MPI Configuration Table not ready */
+			PM8001_INIT_DBG(pm8001_ha,
+				pm8001_printk("FW not ready SCRATCH_PAD2"
+				" = 0x%x\n", regVal));
+			PM8001_INIT_DBG(pm8001_ha,
+				pm8001_printk("SCRATCH_PAD0 value = 0x%x\n",
+				pm8001_cr32(pm8001_ha, 0,
+				MSGU_SCRATCH_PAD_0)));
+			PM8001_INIT_DBG(pm8001_ha,
+				pm8001_printk("SCRATCH_PAD3 value = 0x%x\n",
+				pm8001_cr32(pm8001_ha, 0,
+				MSGU_SCRATCH_PAD_3)));
+			return -1;
+		}
+	}
+
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("SPC soft reset Complete\n"));
+	return 0;
+}
+
+static void pm8001_hw_chip_rst(struct pm8001_hba_info *pm8001_ha)
+{
+	u32 i;
+	u32 regVal;
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("chip reset start\n"));
+
+	/* do SPC chip reset. */
+	regVal = pm8001_cr32(pm8001_ha, 1, SPC_REG_RESET);
+	regVal &= ~(SPC_REG_RESET_DEVICE);
+	pm8001_cw32(pm8001_ha, 1, SPC_REG_RESET, regVal);
+
+	/* delay 10 usec */
+	udelay(10);
+
+	/* bring chip reset out of reset */
+	regVal = pm8001_cr32(pm8001_ha, 1, SPC_REG_RESET);
+	regVal |= SPC_REG_RESET_DEVICE;
+	pm8001_cw32(pm8001_ha, 1, SPC_REG_RESET, regVal);
+
+	/* delay 10 usec */
+	udelay(10);
+
+	/* wait for 20 msec until the firmware gets reloaded */
+	i = 20;
+	do {
+		mdelay(1);
+	} while ((--i) != 0);
+
+	PM8001_INIT_DBG(pm8001_ha,
+		pm8001_printk("chip reset finished\n"));
+}
+
+/**
+ * pm8001_chip_iounmap - which maped when initilized.
+ * @pm8001_ha: our hba card information
+ */
+static void pm8001_chip_iounmap(struct pm8001_hba_info *pm8001_ha)
+{
+	s8 bar, logical = 0;
+	for (bar = 0; bar < 6; bar++) {
+		/*
+		** logical BARs for SPC:
+		** bar 0 and 1 - logical BAR0
+		** bar 2 and 3 - logical BAR1
+		** bar4 - logical BAR2
+		** bar5 - logical BAR3
+		** Skip the appropriate assignments:
+		*/
+		if ((bar == 1) || (bar == 3))
+			continue;
+		if (pm8001_ha->io_mem[logical].memvirtaddr) {
+			iounmap(pm8001_ha->io_mem[logical].memvirtaddr);
+			logical++;
+		}
+	}
+}
+
+/**
+ * pm8001_chip_interrupt_enable - enable PM8001 chip interrupt
+ * @pm8001_ha: our hba card information
+ */
+static void
+pm8001_chip_intx_interrupt_enable(struct pm8001_hba_info *pm8001_ha)
+{
+	pm8001_cw32(pm8001_ha, 0, MSGU_ODMR, ODMR_CLEAR_ALL);
+	pm8001_cw32(pm8001_ha, 0, MSGU_ODCR, ODCR_CLEAR_ALL);
+}
+
+ /**
+  * pm8001_chip_intx_interrupt_disable- disable PM8001 chip interrupt
+  * @pm8001_ha: our hba card information
+  */
+static void
+pm8001_chip_intx_interrupt_disable(struct pm8001_hba_info *pm8001_ha)
+{
+	pm8001_cw32(pm8001_ha, 0, MSGU_ODMR, ODMR_MASK_ALL);
+}
+
+/**
+ * pm8001_chip_msix_interrupt_enable - enable PM8001 chip interrupt
+ * @pm8001_ha: our hba card information
+ */
+static void
+pm8001_chip_msix_interrupt_enable(struct pm8001_hba_info *pm8001_ha,
+	u32 int_vec_idx)
+{
+	u32 msi_index;
+	u32 value;
+	msi_index = int_vec_idx * MSIX_TABLE_ELEMENT_SIZE;
+	msi_index += MSIX_TABLE_BASE;
+	pm8001_cw32(pm8001_ha, 0, msi_index, MSIX_INTERRUPT_ENABLE);
+	value = (1 << int_vec_idx);
+	pm8001_cw32(pm8001_ha, 0,  MSGU_ODCR, value);
+
+}
+
+/**
+ * pm8001_chip_msix_interrupt_disable - disable PM8001 chip interrupt
+ * @pm8001_ha: our hba card information
+ */
+static void
+pm8001_chip_msix_interrupt_disable(struct pm8001_hba_info *pm8001_ha,
+	u32 int_vec_idx)
+{
+	u32 msi_index;
+	msi_index = int_vec_idx * MSIX_TABLE_ELEMENT_SIZE;
+	msi_index += MSIX_TABLE_BASE;
+	pm8001_cw32(pm8001_ha, 0,  msi_index, MSIX_INTERRUPT_DISABLE);
+
+}
+/**
+ * pm8001_chip_interrupt_enable - enable PM8001 chip interrupt
+ * @pm8001_ha: our hba card information
+ */
+static void
+pm8001_chip_interrupt_enable(struct pm8001_hba_info *pm8001_ha)
+{
+#ifdef PM8001_USE_MSIX
+	pm8001_chip_msix_interrupt_enable(pm8001_ha, 0);
+	return;
+#endif
+	pm8001_chip_intx_interrupt_enable(pm8001_ha);
+
+}
+
+/**
+ * pm8001_chip_intx_interrupt_disable- disable PM8001 chip interrupt
+ * @pm8001_ha: our hba card information
+ */
+static void
+pm8001_chip_interrupt_disable(struct pm8001_hba_info *pm8001_ha)
+{
+#ifdef PM8001_USE_MSIX
+	pm8001_chip_msix_interrupt_disable(pm8001_ha, 0);
+	return;
+#endif
+	pm8001_chip_intx_interrupt_disable(pm8001_ha);
+
+}
+
+/**
+ * mpi_msg_free_get- get the free message buffer for transfer inbound queue.
+ * @circularQ: the inbound queue  we want to transfer to HBA.
+ * @messageSize: the message size of this transfer, normally it is 64 bytes
+ * @messagePtr: the pointer to message.
+ */
+static int mpi_msg_free_get(struct inbound_queue_table *circularQ,
+			    u16 messageSize, void **messagePtr)
+{
+	u32 offset, consumer_index;
+	struct mpi_msg_hdr *msgHeader;
+	u8 bcCount = 1; /* only support single buffer */
+
+	/* Checks is the requested message size can be allocated in this queue*/
+	if (messageSize > 64) {
+		*messagePtr = NULL;
+		return -1;
+	}
+
+	/* Stores the new consumer index */
+	consumer_index = pm8001_read_32(circularQ->ci_virt);
+	circularQ->consumer_index = cpu_to_le32(consumer_index);
+	if (((circularQ->producer_idx + bcCount) % 256) ==
+		circularQ->consumer_index) {
+		*messagePtr = NULL;
+		return -1;
+	}
+	/* get memory IOMB buffer address */
+	offset = circularQ->producer_idx * 64;
+	/* increment to next bcCount element */
+	circularQ->producer_idx = (circularQ->producer_idx + bcCount) % 256;
+	/* Adds that distance to the base of the region virtual address plus
+	the message header size*/
+	msgHeader = (struct mpi_msg_hdr *)(circularQ->base_virt	+ offset);
+	*messagePtr = ((void *)msgHeader) + sizeof(struct mpi_msg_hdr);
+	return 0;
+}
+
+/**
+ * mpi_build_cmd- build the message queue for transfer, update the PI to FW
+ * to tell the fw to get this message from IOMB.
+ * @pm8001_ha: our hba card information
+ * @circularQ: the inbound queue we want to transfer to HBA.
+ * @opCode: the operation code represents commands which LLDD and fw recognized.
+ * @payload: the command payload of each operation command.
+ */
+static int mpi_build_cmd(struct pm8001_hba_info *pm8001_ha,
+			 struct inbound_queue_table *circularQ,
+			 u32 opCode, void *payload)
+{
+	u32 Header = 0, hpriority = 0, bc = 1, category = 0x02;
+	u32 responseQueue = 0;
+	void *pMessage;
+
+	if (mpi_msg_free_get(circularQ, 64, &pMessage) < 0) {
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("No free mpi buffer \n"));
+		return -1;
+	}
+	BUG_ON(!payload);
+	/*Copy to the payload*/
+	memcpy(pMessage, payload, (64 - sizeof(struct mpi_msg_hdr)));
+
+	/*Build the header*/
+	Header = ((1 << 31) | (hpriority << 30) | ((bc & 0x1f) << 24)
+		| ((responseQueue & 0x3F) << 16)
+		| ((category & 0xF) << 12) | (opCode & 0xFFF));
+
+	pm8001_write_32((pMessage - 4), 0, cpu_to_le32(Header));
+	/*Update the PI to the firmware*/
+	pm8001_cw32(pm8001_ha, circularQ->pi_pci_bar,
+		circularQ->pi_offset, circularQ->producer_idx);
+	PM8001_IO_DBG(pm8001_ha,
+		pm8001_printk("after PI= %d CI= %d \n", circularQ->producer_idx,
+		circularQ->consumer_index));
+	return 0;
+}
+
+static u32 mpi_msg_free_set(struct pm8001_hba_info *pm8001_ha, void *pMsg,
+			    struct outbound_queue_table *circularQ, u8 bc)
+{
+	u32 producer_index;
+	struct mpi_msg_hdr *msgHeader;
+	struct mpi_msg_hdr *pOutBoundMsgHeader;
+
+	msgHeader = (struct mpi_msg_hdr *)(pMsg - sizeof(struct mpi_msg_hdr));
+	pOutBoundMsgHeader = (struct mpi_msg_hdr *)(circularQ->base_virt +
+				circularQ->consumer_idx * 64);
+	if (pOutBoundMsgHeader != msgHeader) {
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("consumer_idx = %d msgHeader = %p\n",
+			circularQ->consumer_idx, msgHeader));
+
+		/* Update the producer index from SPC */
+		producer_index = pm8001_read_32(circularQ->pi_virt);
+		circularQ->producer_index = cpu_to_le32(producer_index);
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("consumer_idx = %d producer_index = %d"
+			"msgHeader = %p\n", circularQ->consumer_idx,
+			circularQ->producer_index, msgHeader));
+		return 0;
+	}
+	/* free the circular queue buffer elements associated with the message*/
+	circularQ->consumer_idx = (circularQ->consumer_idx + bc) % 256;
+	/* update the CI of outbound queue */
+	pm8001_cw32(pm8001_ha, circularQ->ci_pci_bar, circularQ->ci_offset,
+		circularQ->consumer_idx);
+	/* Update the producer index from SPC*/
+	producer_index = pm8001_read_32(circularQ->pi_virt);
+	circularQ->producer_index = cpu_to_le32(producer_index);
+	PM8001_IO_DBG(pm8001_ha,
+		pm8001_printk(" CI=%d PI=%d\n", circularQ->consumer_idx,
+		circularQ->producer_index));
+	return 0;
+}
+
+/**
+ * mpi_msg_consume- get the MPI message from  outbound queue message table.
+ * @pm8001_ha: our hba card information
+ * @circularQ: the outbound queue  table.
+ * @messagePtr1: the message contents of this outbound message.
+ * @pBC: the message size.
+ */
+static u32 mpi_msg_consume(struct pm8001_hba_info *pm8001_ha,
+			   struct outbound_queue_table *circularQ,
+			   void **messagePtr1, u8 *pBC)
+{
+	struct mpi_msg_hdr	*msgHeader;
+	__le32	msgHeader_tmp;
+	u32 header_tmp;
+	do {
+		/* If there are not-yet-delivered messages ... */
+		if (circularQ->producer_index != circularQ->consumer_idx) {
+			/*Get the pointer to the circular queue buffer element*/
+			msgHeader = (struct mpi_msg_hdr *)
+				(circularQ->base_virt +
+				circularQ->consumer_idx * 64);
+			/* read header */
+			header_tmp = pm8001_read_32(msgHeader);
+			msgHeader_tmp = cpu_to_le32(header_tmp);
+			if (0 != (msgHeader_tmp & 0x80000000)) {
+				if (OPC_OUB_SKIP_ENTRY !=
+					(msgHeader_tmp & 0xfff)) {
+					*messagePtr1 =
+						((u8 *)msgHeader) +
+						sizeof(struct mpi_msg_hdr);
+					*pBC = (u8)((msgHeader_tmp >> 24) &
+						0x1f);
+					PM8001_IO_DBG(pm8001_ha,
+						pm8001_printk(": CI=%d PI=%d "
+						"msgHeader=%x\n",
+						circularQ->consumer_idx,
+						circularQ->producer_index,
+						msgHeader_tmp));
+					return MPI_IO_STATUS_SUCCESS;
+				} else {
+					circularQ->consumer_idx =
+						(circularQ->consumer_idx +
+						((msgHeader_tmp >> 24) & 0x1f))
+						% 256;
+					msgHeader_tmp = 0;
+					pm8001_write_32(msgHeader, 0, 0);
+					/* update the CI of outbound queue */
+					pm8001_cw32(pm8001_ha,
+						circularQ->ci_pci_bar,
+						circularQ->ci_offset,
+						circularQ->consumer_idx);
+				}
+			} else {
+				circularQ->consumer_idx =
+					(circularQ->consumer_idx +
+					((msgHeader_tmp >> 24) & 0x1f)) % 256;
+				msgHeader_tmp = 0;
+				pm8001_write_32(msgHeader, 0, 0);
+				/* update the CI of outbound queue */
+				pm8001_cw32(pm8001_ha, circularQ->ci_pci_bar,
+					circularQ->ci_offset,
+					circularQ->consumer_idx);
+				return MPI_IO_STATUS_FAIL;
+			}
+		} else {
+			u32 producer_index;
+			void *pi_virt = circularQ->pi_virt;
+			/* Update the producer index from SPC */
+			producer_index = pm8001_read_32(pi_virt);
+			circularQ->producer_index = cpu_to_le32(producer_index);
+		}
+	} while (circularQ->producer_index != circularQ->consumer_idx);
+	/* while we don't have any more not-yet-delivered message */
+	/* report empty */
+	return MPI_IO_STATUS_BUSY;
+}
+
+static void pm8001_work_queue(struct work_struct *work)
+{
+	struct delayed_work *dw = container_of(work, struct delayed_work, work);
+	struct pm8001_wq *wq = container_of(dw, struct pm8001_wq, work_q);
+	struct pm8001_device *pm8001_dev;
+	struct domain_device	*dev;
+
+	switch (wq->handler) {
+	case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
+		pm8001_dev = wq->data;
+		dev = pm8001_dev->sas_device;
+		pm8001_I_T_nexus_reset(dev);
+		break;
+	case IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY:
+		pm8001_dev = wq->data;
+		dev = pm8001_dev->sas_device;
+		pm8001_I_T_nexus_reset(dev);
+		break;
+	case IO_DS_IN_ERROR:
+		pm8001_dev = wq->data;
+		dev = pm8001_dev->sas_device;
+		pm8001_I_T_nexus_reset(dev);
+		break;
+	case IO_DS_NON_OPERATIONAL:
+		pm8001_dev = wq->data;
+		dev = pm8001_dev->sas_device;
+		pm8001_I_T_nexus_reset(dev);
+		break;
+	}
+	list_del(&wq->entry);
+	kfree(wq);
+}
+
+static int pm8001_handle_event(struct pm8001_hba_info *pm8001_ha, void *data,
+			       int handler)
+{
+	struct pm8001_wq *wq;
+	int ret = 0;
+
+	wq = kmalloc(sizeof(struct pm8001_wq), GFP_ATOMIC);
+	if (wq) {
+		wq->pm8001_ha = pm8001_ha;
+		wq->data = data;
+		wq->handler = handler;
+		INIT_DELAYED_WORK(&wq->work_q, pm8001_work_queue);
+		list_add_tail(&wq->entry, &pm8001_ha->wq_list);
+		schedule_delayed_work(&wq->work_q, 0);
+	} else
+		ret = -ENOMEM;
+
+	return ret;
+}
+
+/**
+ * mpi_ssp_completion- process the event that FW response to the SSP request.
+ * @pm8001_ha: our hba card information
+ * @piomb: the message contents of this outbound message.
+ *
+ * When FW has completed a ssp request for example a IO request, after it has
+ * filled the SG data with the data, it will trigger this event represent
+ * that he has finished the job,please check the coresponding buffer.
+ * So we will tell the caller who maybe waiting the result to tell upper layer
+ * that the task has been finished.
+ */
+static void
+mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb)
+{
+	struct sas_task *t;
+	struct pm8001_ccb_info *ccb;
+	unsigned long flags;
+	u32 status;
+	u32 param;
+	u32 tag;
+	struct ssp_completion_resp *psspPayload;
+	struct task_status_struct *ts;
+	struct ssp_response_iu *iu;
+	struct pm8001_device *pm8001_dev;
+	psspPayload = (struct ssp_completion_resp *)(piomb + 4);
+	status = le32_to_cpu(psspPayload->status);
+	tag = le32_to_cpu(psspPayload->tag);
+	ccb = &pm8001_ha->ccb_info[tag];
+	pm8001_dev = ccb->device;
+	param = le32_to_cpu(psspPayload->param);
+
+	t = ccb->task;
+
+	if (status && status != IO_UNDERFLOW)
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("sas IO status 0x%x\n", status));
+	if (unlikely(!t || !t->lldd_task || !t->dev))
+		return;
+	ts = &t->task_status;
+	switch (status) {
+	case IO_SUCCESS:
+		PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_SUCCESS"
+			",param = %d \n", param));
+		if (param == 0) {
+			ts->resp = SAS_TASK_COMPLETE;
+			ts->stat = SAM_GOOD;
+		} else {
+			ts->resp = SAS_TASK_COMPLETE;
+			ts->stat = SAS_PROTO_RESPONSE;
+			ts->residual = param;
+			iu = &psspPayload->ssp_resp_iu;
+			sas_ssp_task_response(pm8001_ha->dev, t, iu);
+		}
+		if (pm8001_dev)
+			pm8001_dev->running_req--;
+		break;
+	case IO_ABORTED:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_ABORTED IOMB Tag \n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_ABORTED_TASK;
+		break;
+	case IO_UNDERFLOW:
+		/* SSP Completion with error */
+		PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_UNDERFLOW"
+			",param = %d \n", param));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DATA_UNDERRUN;
+		ts->residual = param;
+		if (pm8001_dev)
+			pm8001_dev->running_req--;
+		break;
+	case IO_NO_DEVICE:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_NO_DEVICE\n"));
+		ts->resp = SAS_TASK_UNDELIVERED;
+		ts->stat = SAS_PHY_DOWN;
+		break;
+	case IO_XFER_ERROR_BREAK:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_BREAK\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		break;
+	case IO_XFER_ERROR_PHY_NOT_READY:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
+		break;
+	case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED:
+		PM8001_IO_DBG(pm8001_ha,
+		pm8001_printk("IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_EPROTO;
+		break;
+	case IO_OPEN_CNX_ERROR_ZONE_VIOLATION:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_UNKNOWN;
+		break;
+	case IO_OPEN_CNX_ERROR_BREAK:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
+		break;
+	case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_UNKNOWN;
+		if (!t->uldd_task)
+			pm8001_handle_event(pm8001_ha,
+				pm8001_dev,
+				IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
+		break;
+	case IO_OPEN_CNX_ERROR_BAD_DESTINATION:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_BAD_DEST;
+		break;
+	case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_CONNECTION_RATE_"
+			"NOT_SUPPORTED\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_CONN_RATE;
+		break;
+	case IO_OPEN_CNX_ERROR_WRONG_DESTINATION:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n"));
+		ts->resp = SAS_TASK_UNDELIVERED;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_WRONG_DEST;
+		break;
+	case IO_XFER_ERROR_NAK_RECEIVED:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_NAK_RECEIVED\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
+		break;
+	case IO_XFER_ERROR_ACK_NAK_TIMEOUT:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_ACK_NAK_TIMEOUT\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_NAK_R_ERR;
+		break;
+	case IO_XFER_ERROR_DMA:
+		PM8001_IO_DBG(pm8001_ha,
+		pm8001_printk("IO_XFER_ERROR_DMA\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		break;
+	case IO_XFER_OPEN_RETRY_TIMEOUT:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
+		break;
+	case IO_XFER_ERROR_OFFSET_MISMATCH:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_OFFSET_MISMATCH\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		break;
+	case IO_PORT_IN_RESET:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_PORT_IN_RESET\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		break;
+	case IO_DS_NON_OPERATIONAL:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_DS_NON_OPERATIONAL\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		if (!t->uldd_task)
+			pm8001_handle_event(pm8001_ha,
+				pm8001_dev,
+				IO_DS_NON_OPERATIONAL);
+		break;
+	case IO_DS_IN_RECOVERY:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_DS_IN_RECOVERY\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		break;
+	case IO_TM_TAG_NOT_FOUND:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_TM_TAG_NOT_FOUND\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		break;
+	case IO_SSP_EXT_IU_ZERO_LEN_ERROR:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_SSP_EXT_IU_ZERO_LEN_ERROR\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		break;
+	case IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
+	default:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("Unknown status 0x%x\n", status));
+		/* not allowed case. Therefore, return failed status */
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		break;
+	}
+	PM8001_IO_DBG(pm8001_ha,
+		pm8001_printk("scsi_status = %x \n ",
+		psspPayload->ssp_resp_iu.status));
+	spin_lock_irqsave(&t->task_state_lock, flags);
+	t->task_state_flags &= ~SAS_TASK_STATE_PENDING;
+	t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
+	t->task_state_flags |= SAS_TASK_STATE_DONE;
+	if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) {
+		spin_unlock_irqrestore(&t->task_state_lock, flags);
+		PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("task 0x%p done with"
+			" io_status 0x%x resp 0x%x "
+			"stat 0x%x but aborted by upper layer!\n",
+			t, status, ts->resp, ts->stat));
+		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+	} else {
+		spin_unlock_irqrestore(&t->task_state_lock, flags);
+		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+		mb();/* in order to force CPU ordering */
+		t->task_done(t);
+	}
+}
+
+/*See the comments for mpi_ssp_completion */
+static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
+{
+	struct sas_task *t;
+	unsigned long flags;
+	struct task_status_struct *ts;
+	struct pm8001_ccb_info *ccb;
+	struct pm8001_device *pm8001_dev;
+	struct ssp_event_resp *psspPayload =
+		(struct ssp_event_resp *)(piomb + 4);
+	u32 event = le32_to_cpu(psspPayload->event);
+	u32 tag = le32_to_cpu(psspPayload->tag);
+	u32 port_id = le32_to_cpu(psspPayload->port_id);
+	u32 dev_id = le32_to_cpu(psspPayload->device_id);
+
+	ccb = &pm8001_ha->ccb_info[tag];
+	t = ccb->task;
+	pm8001_dev = ccb->device;
+	if (event)
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("sas IO status 0x%x\n", event));
+	if (unlikely(!t || !t->lldd_task || !t->dev))
+		return;
+	ts = &t->task_status;
+	PM8001_IO_DBG(pm8001_ha,
+		pm8001_printk("port_id = %x,device_id = %x\n",
+		port_id, dev_id));
+	switch (event) {
+	case IO_OVERFLOW:
+		PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_UNDERFLOW\n");)
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DATA_OVERRUN;
+		ts->residual = 0;
+		if (pm8001_dev)
+			pm8001_dev->running_req--;
+		break;
+	case IO_XFER_ERROR_BREAK:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_BREAK\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_INTERRUPTED;
+		break;
+	case IO_XFER_ERROR_PHY_NOT_READY:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
+		break;
+	case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_PROTOCOL_NOT"
+			"_SUPPORTED\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_EPROTO;
+		break;
+	case IO_OPEN_CNX_ERROR_ZONE_VIOLATION:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_UNKNOWN;
+		break;
+	case IO_OPEN_CNX_ERROR_BREAK:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
+		break;
+	case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_UNKNOWN;
+		if (!t->uldd_task)
+			pm8001_handle_event(pm8001_ha,
+				pm8001_dev,
+				IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
+		break;
+	case IO_OPEN_CNX_ERROR_BAD_DESTINATION:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_BAD_DEST;
+		break;
+	case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_CONNECTION_RATE_"
+			"NOT_SUPPORTED\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_CONN_RATE;
+		break;
+	case IO_OPEN_CNX_ERROR_WRONG_DESTINATION:
+		PM8001_IO_DBG(pm8001_ha,
+		       pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_WRONG_DEST;
+		break;
+	case IO_XFER_ERROR_NAK_RECEIVED:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_NAK_RECEIVED\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
+		break;
+	case IO_XFER_ERROR_ACK_NAK_TIMEOUT:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_ACK_NAK_TIMEOUT\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_NAK_R_ERR;
+		break;
+	case IO_XFER_OPEN_RETRY_TIMEOUT:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
+		break;
+	case IO_XFER_ERROR_UNEXPECTED_PHASE:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_UNEXPECTED_PHASE\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DATA_OVERRUN;
+		break;
+	case IO_XFER_ERROR_XFER_RDY_OVERRUN:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_XFER_RDY_OVERRUN\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DATA_OVERRUN;
+		break;
+	case IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED:
+		PM8001_IO_DBG(pm8001_ha,
+		       pm8001_printk("IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DATA_OVERRUN;
+		break;
+	case IO_XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT:
+		PM8001_IO_DBG(pm8001_ha,
+		pm8001_printk("IO_XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DATA_OVERRUN;
+		break;
+	case IO_XFER_ERROR_OFFSET_MISMATCH:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_OFFSET_MISMATCH\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DATA_OVERRUN;
+		break;
+	case IO_XFER_ERROR_XFER_ZERO_DATA_LEN:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_XFER_ZERO_DATA_LEN\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DATA_OVERRUN;
+		break;
+	case IO_XFER_CMD_FRAME_ISSUED:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("  IO_XFER_CMD_FRAME_ISSUED\n"));
+		return;
+	default:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("Unknown status 0x%x\n", event));
+		/* not allowed case. Therefore, return failed status */
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DATA_OVERRUN;
+		break;
+	}
+	spin_lock_irqsave(&t->task_state_lock, flags);
+	t->task_state_flags &= ~SAS_TASK_STATE_PENDING;
+	t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
+	t->task_state_flags |= SAS_TASK_STATE_DONE;
+	if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) {
+		spin_unlock_irqrestore(&t->task_state_lock, flags);
+		PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("task 0x%p done with"
+			" event 0x%x resp 0x%x "
+			"stat 0x%x but aborted by upper layer!\n",
+			t, event, ts->resp, ts->stat));
+		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+	} else {
+		spin_unlock_irqrestore(&t->task_state_lock, flags);
+		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+		mb();/* in order to force CPU ordering */
+		t->task_done(t);
+	}
+}
+
+/*See the comments for mpi_ssp_completion */
+static void
+mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
+{
+	struct sas_task *t;
+	struct pm8001_ccb_info *ccb;
+	unsigned long flags;
+	u32 param;
+	u32 status;
+	u32 tag;
+	struct sata_completion_resp *psataPayload;
+	struct task_status_struct *ts;
+	struct ata_task_resp *resp ;
+	u32 *sata_resp;
+	struct pm8001_device *pm8001_dev;
+
+	psataPayload = (struct sata_completion_resp *)(piomb + 4);
+	status = le32_to_cpu(psataPayload->status);
+	tag = le32_to_cpu(psataPayload->tag);
+
+	ccb = &pm8001_ha->ccb_info[tag];
+	param = le32_to_cpu(psataPayload->param);
+	t = ccb->task;
+	ts = &t->task_status;
+	pm8001_dev = ccb->device;
+	if (status)
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("sata IO status 0x%x\n", status));
+	if (unlikely(!t || !t->lldd_task || !t->dev))
+		return;
+
+	switch (status) {
+	case IO_SUCCESS:
+		PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_SUCCESS\n"));
+		if (param == 0) {
+			ts->resp = SAS_TASK_COMPLETE;
+			ts->stat = SAM_GOOD;
+		} else {
+			u8 len;
+			ts->resp = SAS_TASK_COMPLETE;
+			ts->stat = SAS_PROTO_RESPONSE;
+			ts->residual = param;
+			PM8001_IO_DBG(pm8001_ha,
+				pm8001_printk("SAS_PROTO_RESPONSE len = %d\n",
+				param));
+			sata_resp = &psataPayload->sata_resp[0];
+			resp = (struct ata_task_resp *)ts->buf;
+			if (t->ata_task.dma_xfer == 0 &&
+			t->data_dir == PCI_DMA_FROMDEVICE) {
+				len = sizeof(struct pio_setup_fis);
+				PM8001_IO_DBG(pm8001_ha,
+				pm8001_printk("PIO read len = %d\n", len));
+			} else if (t->ata_task.use_ncq) {
+				len = sizeof(struct set_dev_bits_fis);
+				PM8001_IO_DBG(pm8001_ha,
+					pm8001_printk("FPDMA len = %d\n", len));
+			} else {
+				len = sizeof(struct dev_to_host_fis);
+				PM8001_IO_DBG(pm8001_ha,
+				pm8001_printk("other len = %d\n", len));
+			}
+			if (SAS_STATUS_BUF_SIZE >= sizeof(*resp)) {
+				resp->frame_len = len;
+				memcpy(&resp->ending_fis[0], sata_resp, len);
+				ts->buf_valid_size = sizeof(*resp);
+			} else
+				PM8001_IO_DBG(pm8001_ha,
+					pm8001_printk("response to large \n"));
+		}
+		if (pm8001_dev)
+			pm8001_dev->running_req--;
+		break;
+	case IO_ABORTED:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_ABORTED IOMB Tag \n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_ABORTED_TASK;
+		if (pm8001_dev)
+			pm8001_dev->running_req--;
+		break;
+		/* following cases are to do cases */
+	case IO_UNDERFLOW:
+		/* SATA Completion with error */
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_UNDERFLOW param = %d\n", param));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DATA_UNDERRUN;
+		ts->residual =  param;
+		if (pm8001_dev)
+			pm8001_dev->running_req--;
+		break;
+	case IO_NO_DEVICE:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_NO_DEVICE\n"));
+		ts->resp = SAS_TASK_UNDELIVERED;
+		ts->stat = SAS_PHY_DOWN;
+		break;
+	case IO_XFER_ERROR_BREAK:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_BREAK\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_INTERRUPTED;
+		break;
+	case IO_XFER_ERROR_PHY_NOT_READY:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
+		break;
+	case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_PROTOCOL_NOT"
+			"_SUPPORTED\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_EPROTO;
+		break;
+	case IO_OPEN_CNX_ERROR_ZONE_VIOLATION:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_UNKNOWN;
+		break;
+	case IO_OPEN_CNX_ERROR_BREAK:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_RSVD_CONT0;
+		break;
+	case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DEV_NO_RESPONSE;
+		if (!t->uldd_task) {
+			pm8001_handle_event(pm8001_ha,
+				pm8001_dev,
+				IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
+			ts->resp = SAS_TASK_UNDELIVERED;
+			ts->stat = SAS_QUEUE_FULL;
+			pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+			mb();/*in order to force CPU ordering*/
+			t->task_done(t);
+			return;
+		}
+		break;
+	case IO_OPEN_CNX_ERROR_BAD_DESTINATION:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n"));
+		ts->resp = SAS_TASK_UNDELIVERED;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_BAD_DEST;
+		if (!t->uldd_task) {
+			pm8001_handle_event(pm8001_ha,
+				pm8001_dev,
+				IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
+			ts->resp = SAS_TASK_UNDELIVERED;
+			ts->stat = SAS_QUEUE_FULL;
+			pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+			mb();/*ditto*/
+			t->task_done(t);
+			return;
+		}
+		break;
+	case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_CONNECTION_RATE_"
+			"NOT_SUPPORTED\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_CONN_RATE;
+		break;
+	case IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_STP_RESOURCES"
+			"_BUSY\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DEV_NO_RESPONSE;
+		if (!t->uldd_task) {
+			pm8001_handle_event(pm8001_ha,
+				pm8001_dev,
+				IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY);
+			ts->resp = SAS_TASK_UNDELIVERED;
+			ts->stat = SAS_QUEUE_FULL;
+			pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+			mb();/* ditto*/
+			t->task_done(t);
+			return;
+		}
+		break;
+	case IO_OPEN_CNX_ERROR_WRONG_DESTINATION:
+		PM8001_IO_DBG(pm8001_ha,
+		       pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_WRONG_DEST;
+		break;
+	case IO_XFER_ERROR_NAK_RECEIVED:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_NAK_RECEIVED\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_NAK_R_ERR;
+		break;
+	case IO_XFER_ERROR_ACK_NAK_TIMEOUT:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_ACK_NAK_TIMEOUT\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_NAK_R_ERR;
+		break;
+	case IO_XFER_ERROR_DMA:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_DMA\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_ABORTED_TASK;
+		break;
+	case IO_XFER_ERROR_SATA_LINK_TIMEOUT:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_SATA_LINK_TIMEOUT\n"));
+		ts->resp = SAS_TASK_UNDELIVERED;
+		ts->stat = SAS_DEV_NO_RESPONSE;
+		break;
+	case IO_XFER_ERROR_REJECTED_NCQ_MODE:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_REJECTED_NCQ_MODE\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DATA_UNDERRUN;
+		break;
+	case IO_XFER_OPEN_RETRY_TIMEOUT:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_TO;
+		break;
+	case IO_PORT_IN_RESET:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_PORT_IN_RESET\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DEV_NO_RESPONSE;
+		break;
+	case IO_DS_NON_OPERATIONAL:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_DS_NON_OPERATIONAL\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DEV_NO_RESPONSE;
+		if (!t->uldd_task) {
+			pm8001_handle_event(pm8001_ha, pm8001_dev,
+				    IO_DS_NON_OPERATIONAL);
+			ts->resp = SAS_TASK_UNDELIVERED;
+			ts->stat = SAS_QUEUE_FULL;
+			pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+			mb();/*ditto*/
+			t->task_done(t);
+			return;
+		}
+		break;
+	case IO_DS_IN_RECOVERY:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("  IO_DS_IN_RECOVERY\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DEV_NO_RESPONSE;
+		break;
+	case IO_DS_IN_ERROR:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_DS_IN_ERROR\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DEV_NO_RESPONSE;
+		if (!t->uldd_task) {
+			pm8001_handle_event(pm8001_ha, pm8001_dev,
+				    IO_DS_IN_ERROR);
+			ts->resp = SAS_TASK_UNDELIVERED;
+			ts->stat = SAS_QUEUE_FULL;
+			pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+			mb();/*ditto*/
+			t->task_done(t);
+			return;
+		}
+		break;
+	case IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
+	default:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("Unknown status 0x%x\n", status));
+		/* not allowed case. Therefore, return failed status */
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DEV_NO_RESPONSE;
+		break;
+	}
+	spin_lock_irqsave(&t->task_state_lock, flags);
+	t->task_state_flags &= ~SAS_TASK_STATE_PENDING;
+	t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
+	t->task_state_flags |= SAS_TASK_STATE_DONE;
+	if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) {
+		spin_unlock_irqrestore(&t->task_state_lock, flags);
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("task 0x%p done with io_status 0x%x"
+			" resp 0x%x stat 0x%x but aborted by upper layer!\n",
+			t, status, ts->resp, ts->stat));
+		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+	} else {
+		spin_unlock_irqrestore(&t->task_state_lock, flags);
+		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+		mb();/* ditto */
+		t->task_done(t);
+	}
+}
+
+/*See the comments for mpi_ssp_completion */
+static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
+{
+	struct sas_task *t;
+	unsigned long flags;
+	struct task_status_struct *ts;
+	struct pm8001_ccb_info *ccb;
+	struct pm8001_device *pm8001_dev;
+	struct sata_event_resp *psataPayload =
+		(struct sata_event_resp *)(piomb + 4);
+	u32 event = le32_to_cpu(psataPayload->event);
+	u32 tag = le32_to_cpu(psataPayload->tag);
+	u32 port_id = le32_to_cpu(psataPayload->port_id);
+	u32 dev_id = le32_to_cpu(psataPayload->device_id);
+
+	ccb = &pm8001_ha->ccb_info[tag];
+	t = ccb->task;
+	pm8001_dev = ccb->device;
+	if (event)
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("sata IO status 0x%x\n", event));
+	if (unlikely(!t || !t->lldd_task || !t->dev))
+		return;
+	ts = &t->task_status;
+	PM8001_IO_DBG(pm8001_ha,
+		pm8001_printk("port_id = %x,device_id = %x\n",
+		port_id, dev_id));
+	switch (event) {
+	case IO_OVERFLOW:
+		PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_UNDERFLOW\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DATA_OVERRUN;
+		ts->residual = 0;
+		if (pm8001_dev)
+			pm8001_dev->running_req--;
+		break;
+	case IO_XFER_ERROR_BREAK:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_BREAK\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_INTERRUPTED;
+		break;
+	case IO_XFER_ERROR_PHY_NOT_READY:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
+		break;
+	case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_PROTOCOL_NOT"
+			"_SUPPORTED\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_EPROTO;
+		break;
+	case IO_OPEN_CNX_ERROR_ZONE_VIOLATION:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_UNKNOWN;
+		break;
+	case IO_OPEN_CNX_ERROR_BREAK:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_RSVD_CONT0;
+		break;
+	case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"));
+		ts->resp = SAS_TASK_UNDELIVERED;
+		ts->stat = SAS_DEV_NO_RESPONSE;
+		if (!t->uldd_task) {
+			pm8001_handle_event(pm8001_ha,
+				pm8001_dev,
+				IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
+			ts->resp = SAS_TASK_COMPLETE;
+			ts->stat = SAS_QUEUE_FULL;
+			pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+			mb();/*ditto*/
+			t->task_done(t);
+			return;
+		}
+		break;
+	case IO_OPEN_CNX_ERROR_BAD_DESTINATION:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n"));
+		ts->resp = SAS_TASK_UNDELIVERED;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_BAD_DEST;
+		break;
+	case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_CONNECTION_RATE_"
+			"NOT_SUPPORTED\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_CONN_RATE;
+		break;
+	case IO_OPEN_CNX_ERROR_WRONG_DESTINATION:
+		PM8001_IO_DBG(pm8001_ha,
+		       pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_WRONG_DEST;
+		break;
+	case IO_XFER_ERROR_NAK_RECEIVED:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_NAK_RECEIVED\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_NAK_R_ERR;
+		break;
+	case IO_XFER_ERROR_PEER_ABORTED:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_PEER_ABORTED\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_NAK_R_ERR;
+		break;
+	case IO_XFER_ERROR_REJECTED_NCQ_MODE:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_REJECTED_NCQ_MODE\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DATA_UNDERRUN;
+		break;
+	case IO_XFER_OPEN_RETRY_TIMEOUT:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_TO;
+		break;
+	case IO_XFER_ERROR_UNEXPECTED_PHASE:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_UNEXPECTED_PHASE\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_TO;
+		break;
+	case IO_XFER_ERROR_XFER_RDY_OVERRUN:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_XFER_RDY_OVERRUN\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_TO;
+		break;
+	case IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED:
+		PM8001_IO_DBG(pm8001_ha,
+		       pm8001_printk("IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_TO;
+		break;
+	case IO_XFER_ERROR_OFFSET_MISMATCH:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_OFFSET_MISMATCH\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_TO;
+		break;
+	case IO_XFER_ERROR_XFER_ZERO_DATA_LEN:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_XFER_ZERO_DATA_LEN\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_TO;
+		break;
+	case IO_XFER_CMD_FRAME_ISSUED:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_CMD_FRAME_ISSUED\n"));
+		break;
+	case IO_XFER_PIO_SETUP_ERROR:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_PIO_SETUP_ERROR\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_TO;
+		break;
+	default:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("Unknown status 0x%x\n", event));
+		/* not allowed case. Therefore, return failed status */
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_TO;
+		break;
+	}
+	spin_lock_irqsave(&t->task_state_lock, flags);
+	t->task_state_flags &= ~SAS_TASK_STATE_PENDING;
+	t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
+	t->task_state_flags |= SAS_TASK_STATE_DONE;
+	if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) {
+		spin_unlock_irqrestore(&t->task_state_lock, flags);
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("task 0x%p done with io_status 0x%x"
+			" resp 0x%x stat 0x%x but aborted by upper layer!\n",
+			t, event, ts->resp, ts->stat));
+		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+	} else {
+		spin_unlock_irqrestore(&t->task_state_lock, flags);
+		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+		mb();/* in order to force CPU ordering */
+		t->task_done(t);
+	}
+}
+
+/*See the comments for mpi_ssp_completion */
+static void
+mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
+{
+	u32 param;
+	struct sas_task *t;
+	struct pm8001_ccb_info *ccb;
+	unsigned long flags;
+	u32 status;
+	u32 tag;
+	struct smp_completion_resp *psmpPayload;
+	struct task_status_struct *ts;
+	struct pm8001_device *pm8001_dev;
+
+	psmpPayload = (struct smp_completion_resp *)(piomb + 4);
+	status = le32_to_cpu(psmpPayload->status);
+	tag = le32_to_cpu(psmpPayload->tag);
+
+	ccb = &pm8001_ha->ccb_info[tag];
+	param = le32_to_cpu(psmpPayload->param);
+	t = ccb->task;
+	ts = &t->task_status;
+	pm8001_dev = ccb->device;
+	if (status)
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("smp IO status 0x%x\n", status));
+	if (unlikely(!t || !t->lldd_task || !t->dev))
+		return;
+
+	switch (status) {
+	case IO_SUCCESS:
+		PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_SUCCESS\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAM_GOOD;
+	if (pm8001_dev)
+			pm8001_dev->running_req--;
+		break;
+	case IO_ABORTED:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_ABORTED IOMB\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_ABORTED_TASK;
+		if (pm8001_dev)
+			pm8001_dev->running_req--;
+		break;
+	case IO_OVERFLOW:
+		PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_UNDERFLOW\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DATA_OVERRUN;
+		ts->residual = 0;
+		if (pm8001_dev)
+			pm8001_dev->running_req--;
+		break;
+	case IO_NO_DEVICE:
+		PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_NO_DEVICE\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_PHY_DOWN;
+		break;
+	case IO_ERROR_HW_TIMEOUT:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_ERROR_HW_TIMEOUT\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAM_BUSY;
+		break;
+	case IO_XFER_ERROR_BREAK:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_BREAK\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAM_BUSY;
+		break;
+	case IO_XFER_ERROR_PHY_NOT_READY:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAM_BUSY;
+		break;
+	case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED:
+		PM8001_IO_DBG(pm8001_ha,
+		pm8001_printk("IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_UNKNOWN;
+		break;
+	case IO_OPEN_CNX_ERROR_ZONE_VIOLATION:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_UNKNOWN;
+		break;
+	case IO_OPEN_CNX_ERROR_BREAK:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_RSVD_CONT0;
+		break;
+	case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_UNKNOWN;
+		pm8001_handle_event(pm8001_ha,
+				pm8001_dev,
+				IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
+		break;
+	case IO_OPEN_CNX_ERROR_BAD_DESTINATION:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_BAD_DEST;
+		break;
+	case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_CONNECTION_RATE_"
+			"NOT_SUPPORTED\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_CONN_RATE;
+		break;
+	case IO_OPEN_CNX_ERROR_WRONG_DESTINATION:
+		PM8001_IO_DBG(pm8001_ha,
+		       pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_WRONG_DEST;
+		break;
+	case IO_XFER_ERROR_RX_FRAME:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_ERROR_RX_FRAME\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DEV_NO_RESPONSE;
+		break;
+	case IO_XFER_OPEN_RETRY_TIMEOUT:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
+		break;
+	case IO_ERROR_INTERNAL_SMP_RESOURCE:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_ERROR_INTERNAL_SMP_RESOURCE\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_QUEUE_FULL;
+		break;
+	case IO_PORT_IN_RESET:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_PORT_IN_RESET\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
+		break;
+	case IO_DS_NON_OPERATIONAL:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_DS_NON_OPERATIONAL\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DEV_NO_RESPONSE;
+		break;
+	case IO_DS_IN_RECOVERY:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_DS_IN_RECOVERY\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
+		break;
+	case IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
+		break;
+	default:
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("Unknown status 0x%x\n", status));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAS_DEV_NO_RESPONSE;
+		/* not allowed case. Therefore, return failed status */
+		break;
+	}
+	spin_lock_irqsave(&t->task_state_lock, flags);
+	t->task_state_flags &= ~SAS_TASK_STATE_PENDING;
+	t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
+	t->task_state_flags |= SAS_TASK_STATE_DONE;
+	if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) {
+		spin_unlock_irqrestore(&t->task_state_lock, flags);
+		PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("task 0x%p done with"
+			" io_status 0x%x resp 0x%x "
+			"stat 0x%x but aborted by upper layer!\n",
+			t, status, ts->resp, ts->stat));
+		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+	} else {
+		spin_unlock_irqrestore(&t->task_state_lock, flags);
+		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+		mb();/* in order to force CPU ordering */
+		t->task_done(t);
+	}
+}
+
+static void
+mpi_set_dev_state_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
+{
+	struct set_dev_state_resp *pPayload =
+		(struct set_dev_state_resp *)(piomb + 4);
+	u32 tag = le32_to_cpu(pPayload->tag);
+	struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag];
+	struct pm8001_device *pm8001_dev = ccb->device;
+	u32 status = le32_to_cpu(pPayload->status);
+	u32 device_id = le32_to_cpu(pPayload->device_id);
+	u8 pds = le32_to_cpu(pPayload->pds_nds) | PDS_BITS;
+	u8 nds = le32_to_cpu(pPayload->pds_nds) | NDS_BITS;
+	PM8001_MSG_DBG(pm8001_ha, pm8001_printk("Set device id = 0x%x state "
+		"from 0x%x to 0x%x status = 0x%x!\n",
+		device_id, pds, nds, status));
+	complete(pm8001_dev->setds_completion);
+	ccb->task = NULL;
+	ccb->ccb_tag = 0xFFFFFFFF;
+	pm8001_ccb_free(pm8001_ha, tag);
+}
+
+static void
+mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
+{
+	struct get_nvm_data_resp *pPayload =
+		(struct get_nvm_data_resp *)(piomb + 4);
+	u32 tag = le32_to_cpu(pPayload->tag);
+	struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag];
+	u32 dlen_status = le32_to_cpu(pPayload->dlen_status);
+	complete(pm8001_ha->nvmd_completion);
+	PM8001_MSG_DBG(pm8001_ha, pm8001_printk("Set nvm data complete!\n"));
+	if ((dlen_status & NVMD_STAT) != 0) {
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("Set nvm data error!\n"));
+		return;
+	}
+	ccb->task = NULL;
+	ccb->ccb_tag = 0xFFFFFFFF;
+	pm8001_ccb_free(pm8001_ha, tag);
+}
+
+static void
+mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
+{
+	struct fw_control_ex	*fw_control_context;
+	struct get_nvm_data_resp *pPayload =
+		(struct get_nvm_data_resp *)(piomb + 4);
+	u32 tag = le32_to_cpu(pPayload->tag);
+	struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag];
+	u32 dlen_status = le32_to_cpu(pPayload->dlen_status);
+	u32 ir_tds_bn_dps_das_nvm =
+		le32_to_cpu(pPayload->ir_tda_bn_dps_das_nvm);
+	void *virt_addr = pm8001_ha->memoryMap.region[NVMD].virt_ptr;
+	fw_control_context = ccb->fw_control_context;
+
+	PM8001_MSG_DBG(pm8001_ha, pm8001_printk("Get nvm data complete!\n"));
+	if ((dlen_status & NVMD_STAT) != 0) {
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("Get nvm data error!\n"));
+		complete(pm8001_ha->nvmd_completion);
+		return;
+	}
+
+	if (ir_tds_bn_dps_das_nvm & IPMode) {
+		/* indirect mode - IR bit set */
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("Get NVMD success, IR=1\n"));
+		if ((ir_tds_bn_dps_das_nvm & NVMD_TYPE) == TWI_DEVICE) {
+			if (ir_tds_bn_dps_das_nvm == 0x80a80200) {
+				memcpy(pm8001_ha->sas_addr,
+				      ((u8 *)virt_addr + 4),
+				       SAS_ADDR_SIZE);
+				PM8001_MSG_DBG(pm8001_ha,
+					pm8001_printk("Get SAS address"
+					" from VPD successfully!\n"));
+			}
+		} else if (((ir_tds_bn_dps_das_nvm & NVMD_TYPE) == C_SEEPROM)
+			|| ((ir_tds_bn_dps_das_nvm & NVMD_TYPE) == VPD_FLASH) ||
+			((ir_tds_bn_dps_das_nvm & NVMD_TYPE) == EXPAN_ROM)) {
+				;
+		} else if (((ir_tds_bn_dps_das_nvm & NVMD_TYPE) == AAP1_RDUMP)
+			|| ((ir_tds_bn_dps_das_nvm & NVMD_TYPE) == IOP_RDUMP)) {
+			;
+		} else {
+			/* Should not be happened*/
+			PM8001_MSG_DBG(pm8001_ha,
+				pm8001_printk("(IR=1)Wrong Device type 0x%x\n",
+				ir_tds_bn_dps_das_nvm));
+		}
+	} else /* direct mode */{
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("Get NVMD success, IR=0, dataLen=%d\n",
+			(dlen_status & NVMD_LEN) >> 24));
+	}
+	memcpy(fw_control_context->usrAddr,
+		pm8001_ha->memoryMap.region[NVMD].virt_ptr,
+		fw_control_context->len);
+	complete(pm8001_ha->nvmd_completion);
+	ccb->task = NULL;
+	ccb->ccb_tag = 0xFFFFFFFF;
+	pm8001_ccb_free(pm8001_ha, tag);
+}
+
+static int mpi_local_phy_ctl(struct pm8001_hba_info *pm8001_ha, void *piomb)
+{
+	struct local_phy_ctl_resp *pPayload =
+		(struct local_phy_ctl_resp *)(piomb + 4);
+	u32 status = le32_to_cpu(pPayload->status);
+	u32 phy_id = le32_to_cpu(pPayload->phyop_phyid) & ID_BITS;
+	u32 phy_op = le32_to_cpu(pPayload->phyop_phyid) & OP_BITS;
+	if (status != 0) {
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("%x phy execute %x phy op failed! \n",
+			phy_id, phy_op));
+	} else
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("%x phy execute %x phy op success! \n",
+			phy_id, phy_op));
+	return 0;
+}
+
+/**
+ * pm8001_bytes_dmaed - one of the interface function communication with libsas
+ * @pm8001_ha: our hba card information
+ * @i: which phy that received the event.
+ *
+ * when HBA driver received the identify done event or initiate FIS received
+ * event(for SATA), it will invoke this function to notify the sas layer that
+ * the sas toplogy has formed, please discover the the whole sas domain,
+ * while receive a broadcast(change) primitive just tell the sas
+ * layer to discover the changed domain rather than the whole domain.
+ */
+static void pm8001_bytes_dmaed(struct pm8001_hba_info *pm8001_ha, int i)
+{
+	struct pm8001_phy *phy = &pm8001_ha->phy[i];
+	struct asd_sas_phy *sas_phy = &phy->sas_phy;
+	struct sas_ha_struct *sas_ha;
+	if (!phy->phy_attached)
+		return;
+
+	sas_ha = pm8001_ha->sas;
+	if (sas_phy->phy) {
+		struct sas_phy *sphy = sas_phy->phy;
+		sphy->negotiated_linkrate = sas_phy->linkrate;
+		sphy->minimum_linkrate = phy->minimum_linkrate;
+		sphy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
+		sphy->maximum_linkrate = phy->maximum_linkrate;
+		sphy->maximum_linkrate_hw = phy->maximum_linkrate;
+	}
+
+	if (phy->phy_type & PORT_TYPE_SAS) {
+		struct sas_identify_frame *id;
+		id = (struct sas_identify_frame *)phy->frame_rcvd;
+		id->dev_type = phy->identify.device_type;
+		id->initiator_bits = SAS_PROTOCOL_ALL;
+		id->target_bits = phy->identify.target_port_protocols;
+	} else if (phy->phy_type & PORT_TYPE_SATA) {
+		/*Nothing*/
+	}
+	PM8001_MSG_DBG(pm8001_ha, pm8001_printk("phy %d byte dmaded.\n", i));
+
+	sas_phy->frame_rcvd_size = phy->frame_rcvd_size;
+	pm8001_ha->sas->notify_port_event(sas_phy, PORTE_BYTES_DMAED);
+}
+
+/* Get the link rate speed  */
+static void get_lrate_mode(struct pm8001_phy *phy, u8 link_rate)
+{
+	struct sas_phy *sas_phy = phy->sas_phy.phy;
+
+	switch (link_rate) {
+	case PHY_SPEED_60:
+		phy->sas_phy.linkrate = SAS_LINK_RATE_6_0_GBPS;
+		phy->sas_phy.phy->negotiated_linkrate = SAS_LINK_RATE_6_0_GBPS;
+		break;
+	case PHY_SPEED_30:
+		phy->sas_phy.linkrate = SAS_LINK_RATE_3_0_GBPS;
+		phy->sas_phy.phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
+		break;
+	case PHY_SPEED_15:
+		phy->sas_phy.linkrate = SAS_LINK_RATE_1_5_GBPS;
+		phy->sas_phy.phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
+		break;
+	}
+	sas_phy->negotiated_linkrate = phy->sas_phy.linkrate;
+	sas_phy->maximum_linkrate_hw = SAS_LINK_RATE_6_0_GBPS;
+	sas_phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
+	sas_phy->maximum_linkrate = SAS_LINK_RATE_6_0_GBPS;
+	sas_phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
+}
+
+/**
+ * asd_get_attached_sas_addr -- extract/generate attached SAS address
+ * @phy: pointer to asd_phy
+ * @sas_addr: pointer to buffer where the SAS address is to be written
+ *
+ * This function extracts the SAS address from an IDENTIFY frame
+ * received.  If OOB is SATA, then a SAS address is generated from the
+ * HA tables.
+ *
+ * LOCKING: the frame_rcvd_lock needs to be held since this parses the frame
+ * buffer.
+ */
+static void pm8001_get_attached_sas_addr(struct pm8001_phy *phy,
+	u8 *sas_addr)
+{
+	if (phy->sas_phy.frame_rcvd[0] == 0x34
+		&& phy->sas_phy.oob_mode == SATA_OOB_MODE) {
+		struct pm8001_hba_info *pm8001_ha = phy->sas_phy.ha->lldd_ha;
+		/* FIS device-to-host */
+		u64 addr = be64_to_cpu(*(__be64 *)pm8001_ha->sas_addr);
+		addr += phy->sas_phy.id;
+		*(__be64 *)sas_addr = cpu_to_be64(addr);
+	} else {
+		struct sas_identify_frame *idframe =
+			(void *) phy->sas_phy.frame_rcvd;
+		memcpy(sas_addr, idframe->sas_addr, SAS_ADDR_SIZE);
+	}
+}
+
+/**
+ * pm8001_hw_event_ack_req- For PM8001,some events need to acknowage to FW.
+ * @pm8001_ha: our hba card information
+ * @Qnum: the outbound queue message number.
+ * @SEA: source of event to ack
+ * @port_id: port id.
+ * @phyId: phy id.
+ * @param0: parameter 0.
+ * @param1: parameter 1.
+ */
+static void pm8001_hw_event_ack_req(struct pm8001_hba_info *pm8001_ha,
+	u32 Qnum, u32 SEA, u32 port_id, u32 phyId, u32 param0, u32 param1)
+{
+	struct hw_event_ack_req	 payload;
+	u32 opc = OPC_INB_SAS_HW_EVENT_ACK;
+
+	struct inbound_queue_table *circularQ;
+
+	memset((u8 *)&payload, 0, sizeof(payload));
+	circularQ = &pm8001_ha->inbnd_q_tbl[Qnum];
+	payload.tag = 1;
+	payload.sea_phyid_portid = cpu_to_le32(((SEA & 0xFFFF) << 8) |
+		((phyId & 0x0F) << 4) | (port_id & 0x0F));
+	payload.param0 = cpu_to_le32(param0);
+	payload.param1 = cpu_to_le32(param1);
+	mpi_build_cmd(pm8001_ha, circularQ, opc, &payload);
+}
+
+static int pm8001_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,
+	u32 phyId, u32 phy_op);
+
+/**
+ * hw_event_sas_phy_up -FW tells me a SAS phy up event.
+ * @pm8001_ha: our hba card information
+ * @piomb: IO message buffer
+ */
+static void
+hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)
+{
+	struct hw_event_resp *pPayload =
+		(struct hw_event_resp *)(piomb + 4);
+	u32 lr_evt_status_phyid_portid =
+		le32_to_cpu(pPayload->lr_evt_status_phyid_portid);
+	u8 link_rate =
+		(u8)((lr_evt_status_phyid_portid & 0xF0000000) >> 28);
+	u8 phy_id =
+		(u8)((lr_evt_status_phyid_portid & 0x000000F0) >> 4);
+	struct sas_ha_struct *sas_ha = pm8001_ha->sas;
+	struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];
+	unsigned long flags;
+	u8 deviceType = pPayload->sas_identify.dev_type;
+
+	PM8001_MSG_DBG(pm8001_ha,
+		pm8001_printk("HW_EVENT_SAS_PHY_UP \n"));
+
+	switch (deviceType) {
+	case SAS_PHY_UNUSED:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("device type no device.\n"));
+		break;
+	case SAS_END_DEVICE:
+		PM8001_MSG_DBG(pm8001_ha, pm8001_printk("end device.\n"));
+		pm8001_chip_phy_ctl_req(pm8001_ha, phy_id,
+			PHY_NOTIFY_ENABLE_SPINUP);
+		get_lrate_mode(phy, link_rate);
+		break;
+	case SAS_EDGE_EXPANDER_DEVICE:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("expander device.\n"));
+		get_lrate_mode(phy, link_rate);
+		break;
+	case SAS_FANOUT_EXPANDER_DEVICE:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("fanout expander device.\n"));
+		get_lrate_mode(phy, link_rate);
+		break;
+	default:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("unkown device type(%x)\n", deviceType));
+		break;
+	}
+	phy->phy_type |= PORT_TYPE_SAS;
+	phy->identify.device_type = deviceType;
+	phy->phy_attached = 1;
+	if (phy->identify.device_type == SAS_END_DEV)
+		phy->identify.target_port_protocols = SAS_PROTOCOL_SSP;
+	else if (phy->identify.device_type != NO_DEVICE)
+		phy->identify.target_port_protocols = SAS_PROTOCOL_SMP;
+	phy->sas_phy.oob_mode = SAS_OOB_MODE;
+	sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE);
+	spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags);
+	memcpy(phy->frame_rcvd, &pPayload->sas_identify,
+		sizeof(struct sas_identify_frame)-4);
+	phy->frame_rcvd_size = sizeof(struct sas_identify_frame) - 4;
+	pm8001_get_attached_sas_addr(phy, phy->sas_phy.attached_sas_addr);
+	spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags);
+	if (pm8001_ha->flags == PM8001F_RUN_TIME)
+		mdelay(200);/*delay a moment to wait disk to spinup*/
+	pm8001_bytes_dmaed(pm8001_ha, phy_id);
+}
+
+/**
+ * hw_event_sata_phy_up -FW tells me a SATA phy up event.
+ * @pm8001_ha: our hba card information
+ * @piomb: IO message buffer
+ */
+static void
+hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)
+{
+	struct hw_event_resp *pPayload =
+		(struct hw_event_resp *)(piomb + 4);
+	u32 lr_evt_status_phyid_portid =
+		le32_to_cpu(pPayload->lr_evt_status_phyid_portid);
+	u8 link_rate =
+		(u8)((lr_evt_status_phyid_portid & 0xF0000000) >> 28);
+	u8 phy_id =
+		(u8)((lr_evt_status_phyid_portid & 0x000000F0) >> 4);
+	struct sas_ha_struct *sas_ha = pm8001_ha->sas;
+	struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];
+	unsigned long flags;
+	get_lrate_mode(phy, link_rate);
+	phy->phy_type |= PORT_TYPE_SATA;
+	phy->phy_attached = 1;
+	phy->sas_phy.oob_mode = SATA_OOB_MODE;
+	sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE);
+	spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags);
+	memcpy(phy->frame_rcvd, ((u8 *)&pPayload->sata_fis - 4),
+		sizeof(struct dev_to_host_fis));
+	phy->frame_rcvd_size = sizeof(struct dev_to_host_fis);
+	phy->identify.target_port_protocols = SAS_PROTOCOL_SATA;
+	phy->identify.device_type = SATA_DEV;
+	pm8001_get_attached_sas_addr(phy, phy->sas_phy.attached_sas_addr);
+	spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags);
+	pm8001_bytes_dmaed(pm8001_ha, phy_id);
+}
+
+/**
+ * hw_event_phy_down -we should notify the libsas the phy is down.
+ * @pm8001_ha: our hba card information
+ * @piomb: IO message buffer
+ */
+static void
+hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb)
+{
+	struct hw_event_resp *pPayload =
+		(struct hw_event_resp *)(piomb + 4);
+	u32 lr_evt_status_phyid_portid =
+		le32_to_cpu(pPayload->lr_evt_status_phyid_portid);
+	u8 port_id = (u8)(lr_evt_status_phyid_portid & 0x0000000F);
+	u8 phy_id =
+		(u8)((lr_evt_status_phyid_portid & 0x000000F0) >> 4);
+	u32 npip_portstate = le32_to_cpu(pPayload->npip_portstate);
+	u8 portstate = (u8)(npip_portstate & 0x0000000F);
+
+	switch (portstate) {
+	case PORT_VALID:
+		break;
+	case PORT_INVALID:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk(" PortInvalid portID %d \n", port_id));
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk(" Last phy Down and port invalid\n"));
+		pm8001_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN,
+			port_id, phy_id, 0, 0);
+		break;
+	case PORT_IN_RESET:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk(" PortInReset portID %d \n", port_id));
+		break;
+	case PORT_NOT_ESTABLISHED:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk(" phy Down and PORT_NOT_ESTABLISHED\n"));
+		break;
+	case PORT_LOSTCOMM:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk(" phy Down and PORT_LOSTCOMM\n"));
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk(" Last phy Down and port invalid\n"));
+		pm8001_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN,
+			port_id, phy_id, 0, 0);
+		break;
+	default:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk(" phy Down and(default) = %x\n",
+			portstate));
+		break;
+
+	}
+}
+
+/**
+ * mpi_reg_resp -process register device ID response.
+ * @pm8001_ha: our hba card information
+ * @piomb: IO message buffer
+ *
+ * when sas layer find a device it will notify LLDD, then the driver register
+ * the domain device to FW, this event is the return device ID which the FW
+ * has assigned, from now,inter-communication with FW is no longer using the
+ * SAS address, use device ID which FW assigned.
+ */
+static int mpi_reg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
+{
+	u32 status;
+	u32 device_id;
+	u32 htag;
+	struct pm8001_ccb_info *ccb;
+	struct pm8001_device *pm8001_dev;
+	struct dev_reg_resp *registerRespPayload =
+		(struct dev_reg_resp *)(piomb + 4);
+
+	htag = le32_to_cpu(registerRespPayload->tag);
+	ccb = &pm8001_ha->ccb_info[registerRespPayload->tag];
+	pm8001_dev = ccb->device;
+	status = le32_to_cpu(registerRespPayload->status);
+	device_id = le32_to_cpu(registerRespPayload->device_id);
+	PM8001_MSG_DBG(pm8001_ha,
+		pm8001_printk(" register device is status = %d\n", status));
+	switch (status) {
+	case DEVREG_SUCCESS:
+		PM8001_MSG_DBG(pm8001_ha, pm8001_printk("DEVREG_SUCCESS\n"));
+		pm8001_dev->device_id = device_id;
+		break;
+	case DEVREG_FAILURE_OUT_OF_RESOURCE:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("DEVREG_FAILURE_OUT_OF_RESOURCE\n"));
+		break;
+	case DEVREG_FAILURE_DEVICE_ALREADY_REGISTERED:
+		PM8001_MSG_DBG(pm8001_ha,
+		   pm8001_printk("DEVREG_FAILURE_DEVICE_ALREADY_REGISTERED\n"));
+		break;
+	case DEVREG_FAILURE_INVALID_PHY_ID:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("DEVREG_FAILURE_INVALID_PHY_ID\n"));
+		break;
+	case DEVREG_FAILURE_PHY_ID_ALREADY_REGISTERED:
+		PM8001_MSG_DBG(pm8001_ha,
+		   pm8001_printk("DEVREG_FAILURE_PHY_ID_ALREADY_REGISTERED\n"));
+		break;
+	case DEVREG_FAILURE_PORT_ID_OUT_OF_RANGE:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("DEVREG_FAILURE_PORT_ID_OUT_OF_RANGE\n"));
+		break;
+	case DEVREG_FAILURE_PORT_NOT_VALID_STATE:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("DEVREG_FAILURE_PORT_NOT_VALID_STATE\n"));
+		break;
+	case DEVREG_FAILURE_DEVICE_TYPE_NOT_VALID:
+		PM8001_MSG_DBG(pm8001_ha,
+		       pm8001_printk("DEVREG_FAILURE_DEVICE_TYPE_NOT_VALID\n"));
+		break;
+	default:
+		PM8001_MSG_DBG(pm8001_ha,
+		 pm8001_printk("DEVREG_FAILURE_DEVICE_TYPE_NOT_UNSORPORTED\n"));
+		break;
+	}
+	complete(pm8001_dev->dcompletion);
+	ccb->task = NULL;
+	ccb->ccb_tag = 0xFFFFFFFF;
+	pm8001_ccb_free(pm8001_ha, htag);
+	return 0;
+}
+
+static int mpi_dereg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
+{
+	u32 status;
+	u32 device_id;
+	struct dev_reg_resp *registerRespPayload =
+		(struct dev_reg_resp *)(piomb + 4);
+
+	status = le32_to_cpu(registerRespPayload->status);
+	device_id = le32_to_cpu(registerRespPayload->device_id);
+	if (status != 0)
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk(" deregister device failed ,status = %x"
+			", device_id = %x\n", status, device_id));
+	return 0;
+}
+
+static int
+mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
+{
+	u32 status;
+	struct fw_control_ex	fw_control_context;
+	struct fw_flash_Update_resp *ppayload =
+		(struct fw_flash_Update_resp *)(piomb + 4);
+	u32 tag = le32_to_cpu(ppayload->tag);
+	struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag];
+	status = le32_to_cpu(ppayload->status);
+	memcpy(&fw_control_context,
+		ccb->fw_control_context,
+		sizeof(fw_control_context));
+	switch (status) {
+	case FLASH_UPDATE_COMPLETE_PENDING_REBOOT:
+		PM8001_MSG_DBG(pm8001_ha,
+		pm8001_printk(": FLASH_UPDATE_COMPLETE_PENDING_REBOOT\n"));
+		break;
+	case FLASH_UPDATE_IN_PROGRESS:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk(": FLASH_UPDATE_IN_PROGRESS\n"));
+		break;
+	case FLASH_UPDATE_HDR_ERR:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk(": FLASH_UPDATE_HDR_ERR\n"));
+		break;
+	case FLASH_UPDATE_OFFSET_ERR:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk(": FLASH_UPDATE_OFFSET_ERR\n"));
+		break;
+	case FLASH_UPDATE_CRC_ERR:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk(": FLASH_UPDATE_CRC_ERR\n"));
+		break;
+	case FLASH_UPDATE_LENGTH_ERR:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk(": FLASH_UPDATE_LENGTH_ERR\n"));
+		break;
+	case FLASH_UPDATE_HW_ERR:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk(": FLASH_UPDATE_HW_ERR\n"));
+		break;
+	case FLASH_UPDATE_DNLD_NOT_SUPPORTED:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk(": FLASH_UPDATE_DNLD_NOT_SUPPORTED\n"));
+		break;
+	case FLASH_UPDATE_DISABLED:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk(": FLASH_UPDATE_DISABLED\n"));
+		break;
+	default:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("No matched status = %d\n", status));
+		break;
+	}
+	ccb->fw_control_context->fw_control->retcode = status;
+	pci_free_consistent(pm8001_ha->pdev,
+			fw_control_context.len,
+			fw_control_context.virtAddr,
+			fw_control_context.phys_addr);
+	complete(pm8001_ha->nvmd_completion);
+	ccb->task = NULL;
+	ccb->ccb_tag = 0xFFFFFFFF;
+	pm8001_ccb_free(pm8001_ha, tag);
+	return 0;
+}
+
+static int
+mpi_general_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
+{
+	u32 status;
+	int i;
+	struct general_event_resp *pPayload =
+		(struct general_event_resp *)(piomb + 4);
+	status = le32_to_cpu(pPayload->status);
+	PM8001_MSG_DBG(pm8001_ha,
+		pm8001_printk(" status = 0x%x\n", status));
+	for (i = 0; i < GENERAL_EVENT_PAYLOAD; i++)
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("inb_IOMB_payload[0x%x] 0x%x, \n", i,
+			pPayload->inb_IOMB_payload[i]));
+	return 0;
+}
+
+static int
+mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
+{
+	struct sas_task *t;
+	struct pm8001_ccb_info *ccb;
+	unsigned long flags;
+	u32 status ;
+	u32 tag, scp;
+	struct task_status_struct *ts;
+
+	struct task_abort_resp *pPayload =
+		(struct task_abort_resp *)(piomb + 4);
+	ccb = &pm8001_ha->ccb_info[pPayload->tag];
+	t = ccb->task;
+
+
+	status = le32_to_cpu(pPayload->status);
+	tag = le32_to_cpu(pPayload->tag);
+	scp = le32_to_cpu(pPayload->scp);
+	PM8001_IO_DBG(pm8001_ha,
+		pm8001_printk(" status = 0x%x\n", status));
+	if (t == NULL)
+		return -1;
+	ts = &t->task_status;
+	if (status != 0)
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("task abort failed status 0x%x ,"
+			"tag = 0x%x, scp= 0x%x\n", status, tag, scp));
+	switch (status) {
+	case IO_SUCCESS:
+		PM8001_EH_DBG(pm8001_ha, pm8001_printk("IO_SUCCESS\n"));
+		ts->resp = SAS_TASK_COMPLETE;
+		ts->stat = SAM_GOOD;
+		break;
+	case IO_NOT_VALID:
+		PM8001_EH_DBG(pm8001_ha, pm8001_printk("IO_NOT_VALID\n"));
+		ts->resp = TMF_RESP_FUNC_FAILED;
+		break;
+	}
+	spin_lock_irqsave(&t->task_state_lock, flags);
+	t->task_state_flags &= ~SAS_TASK_STATE_PENDING;
+	t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
+	t->task_state_flags |= SAS_TASK_STATE_DONE;
+	spin_unlock_irqrestore(&t->task_state_lock, flags);
+	pm8001_ccb_task_free(pm8001_ha, t, ccb, pPayload->tag);
+	mb();
+	t->task_done(t);
+	return 0;
+}
+
+/**
+ * mpi_hw_event -The hw event has come.
+ * @pm8001_ha: our hba card information
+ * @piomb: IO message buffer
+ */
+static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb)
+{
+	unsigned long flags;
+	struct hw_event_resp *pPayload =
+		(struct hw_event_resp *)(piomb + 4);
+	u32 lr_evt_status_phyid_portid =
+		le32_to_cpu(pPayload->lr_evt_status_phyid_portid);
+	u8 port_id = (u8)(lr_evt_status_phyid_portid & 0x0000000F);
+	u8 phy_id =
+		(u8)((lr_evt_status_phyid_portid & 0x000000F0) >> 4);
+	u16 eventType =
+		(u16)((lr_evt_status_phyid_portid & 0x00FFFF00) >> 8);
+	u8 status =
+		(u8)((lr_evt_status_phyid_portid & 0x0F000000) >> 24);
+	struct sas_ha_struct *sas_ha = pm8001_ha->sas;
+	struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];
+	struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];
+	PM8001_MSG_DBG(pm8001_ha,
+		pm8001_printk("outbound queue HW event & event type : "));
+	switch (eventType) {
+	case HW_EVENT_PHY_START_STATUS:
+		PM8001_MSG_DBG(pm8001_ha,
+		pm8001_printk("HW_EVENT_PHY_START_STATUS"
+			" status = %x\n", status));
+		if (status == 0) {
+			phy->phy_state = 1;
+			if (pm8001_ha->flags == PM8001F_RUN_TIME)
+				complete(phy->enable_completion);
+		}
+		break;
+	case HW_EVENT_SAS_PHY_UP:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("HW_EVENT_PHY_START_STATUS \n"));
+		hw_event_sas_phy_up(pm8001_ha, piomb);
+		break;
+	case HW_EVENT_SATA_PHY_UP:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("HW_EVENT_SATA_PHY_UP \n"));
+		hw_event_sata_phy_up(pm8001_ha, piomb);
+		break;
+	case HW_EVENT_PHY_STOP_STATUS:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("HW_EVENT_PHY_STOP_STATUS "
+			"status = %x\n", status));
+		if (status == 0)
+			phy->phy_state = 0;
+		break;
+	case HW_EVENT_SATA_SPINUP_HOLD:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("HW_EVENT_SATA_SPINUP_HOLD \n"));
+		sas_ha->notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD);
+		break;
+	case HW_EVENT_PHY_DOWN:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("HW_EVENT_PHY_DOWN \n"));
+		sas_ha->notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL);
+		phy->phy_attached = 0;
+		phy->phy_state = 0;
+		hw_event_phy_down(pm8001_ha, piomb);
+		break;
+	case HW_EVENT_PORT_INVALID:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("HW_EVENT_PORT_INVALID\n"));
+		sas_phy_disconnected(sas_phy);
+		phy->phy_attached = 0;
+		sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
+		break;
+	/* the broadcast change primitive received, tell the LIBSAS this event
+	to revalidate the sas domain*/
+	case HW_EVENT_BROADCAST_CHANGE:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("HW_EVENT_BROADCAST_CHANGE\n"));
+		pm8001_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_BROADCAST_CHANGE,
+			port_id, phy_id, 1, 0);
+		spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
+		sas_phy->sas_prim = HW_EVENT_BROADCAST_CHANGE;
+		spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);
+		sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
+		break;
+	case HW_EVENT_PHY_ERROR:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("HW_EVENT_PHY_ERROR\n"));
+		sas_phy_disconnected(&phy->sas_phy);
+		phy->phy_attached = 0;
+		sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR);
+		break;
+	case HW_EVENT_BROADCAST_EXP:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("HW_EVENT_BROADCAST_EXP\n"));
+		spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
+		sas_phy->sas_prim = HW_EVENT_BROADCAST_EXP;
+		spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);
+		sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
+		break;
+	case HW_EVENT_LINK_ERR_INVALID_DWORD:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("HW_EVENT_LINK_ERR_INVALID_DWORD\n"));
+		pm8001_hw_event_ack_req(pm8001_ha, 0,
+			HW_EVENT_LINK_ERR_INVALID_DWORD, port_id, phy_id, 0, 0);
+		sas_phy_disconnected(sas_phy);
+		phy->phy_attached = 0;
+		sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
+		break;
+	case HW_EVENT_LINK_ERR_DISPARITY_ERROR:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("HW_EVENT_LINK_ERR_DISPARITY_ERROR\n"));
+		pm8001_hw_event_ack_req(pm8001_ha, 0,
+			HW_EVENT_LINK_ERR_DISPARITY_ERROR,
+			port_id, phy_id, 0, 0);
+		sas_phy_disconnected(sas_phy);
+		phy->phy_attached = 0;
+		sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
+		break;
+	case HW_EVENT_LINK_ERR_CODE_VIOLATION:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("HW_EVENT_LINK_ERR_CODE_VIOLATION\n"));
+		pm8001_hw_event_ack_req(pm8001_ha, 0,
+			HW_EVENT_LINK_ERR_CODE_VIOLATION,
+			port_id, phy_id, 0, 0);
+		sas_phy_disconnected(sas_phy);
+		phy->phy_attached = 0;
+		sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
+		break;
+	case HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH:
+		PM8001_MSG_DBG(pm8001_ha,
+		      pm8001_printk("HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH\n"));
+		pm8001_hw_event_ack_req(pm8001_ha, 0,
+			HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH,
+			port_id, phy_id, 0, 0);
+		sas_phy_disconnected(sas_phy);
+		phy->phy_attached = 0;
+		sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
+		break;
+	case HW_EVENT_MALFUNCTION:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("HW_EVENT_MALFUNCTION\n"));
+		break;
+	case HW_EVENT_BROADCAST_SES:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("HW_EVENT_BROADCAST_SES\n"));
+		spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
+		sas_phy->sas_prim = HW_EVENT_BROADCAST_SES;
+		spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);
+		sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
+		break;
+	case HW_EVENT_INBOUND_CRC_ERROR:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("HW_EVENT_INBOUND_CRC_ERROR\n"));
+		pm8001_hw_event_ack_req(pm8001_ha, 0,
+			HW_EVENT_INBOUND_CRC_ERROR,
+			port_id, phy_id, 0, 0);
+		break;
+	case HW_EVENT_HARD_RESET_RECEIVED:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("HW_EVENT_HARD_RESET_RECEIVED\n"));
+		sas_ha->notify_port_event(sas_phy, PORTE_HARD_RESET);
+		break;
+	case HW_EVENT_ID_FRAME_TIMEOUT:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("HW_EVENT_ID_FRAME_TIMEOUT\n"));
+		sas_phy_disconnected(sas_phy);
+		phy->phy_attached = 0;
+		sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
+		break;
+	case HW_EVENT_LINK_ERR_PHY_RESET_FAILED:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("HW_EVENT_LINK_ERR_PHY_RESET_FAILED \n"));
+		pm8001_hw_event_ack_req(pm8001_ha, 0,
+			HW_EVENT_LINK_ERR_PHY_RESET_FAILED,
+			port_id, phy_id, 0, 0);
+		sas_phy_disconnected(sas_phy);
+		phy->phy_attached = 0;
+		sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
+		break;
+	case HW_EVENT_PORT_RESET_TIMER_TMO:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("HW_EVENT_PORT_RESET_TIMER_TMO \n"));
+		sas_phy_disconnected(sas_phy);
+		phy->phy_attached = 0;
+		sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
+		break;
+	case HW_EVENT_PORT_RECOVERY_TIMER_TMO:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("HW_EVENT_PORT_RECOVERY_TIMER_TMO \n"));
+		sas_phy_disconnected(sas_phy);
+		phy->phy_attached = 0;
+		sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
+		break;
+	case HW_EVENT_PORT_RECOVER:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("HW_EVENT_PORT_RECOVER \n"));
+		break;
+	case HW_EVENT_PORT_RESET_COMPLETE:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("HW_EVENT_PORT_RESET_COMPLETE \n"));
+		break;
+	case EVENT_BROADCAST_ASYNCH_EVENT:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("EVENT_BROADCAST_ASYNCH_EVENT\n"));
+		break;
+	default:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("Unknown event type = %x\n", eventType));
+		break;
+	}
+	return 0;
+}
+
+/**
+ * process_one_iomb - process one outbound Queue memory block
+ * @pm8001_ha: our hba card information
+ * @piomb: IO message buffer
+ */
+static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb)
+{
+	u32 pHeader = (u32)*(u32 *)piomb;
+	u8 opc = (u8)((le32_to_cpu(pHeader)) & 0xFFF);
+
+	PM8001_MSG_DBG(pm8001_ha, pm8001_printk("process_one_iomb:"));
+
+	switch (opc) {
+	case OPC_OUB_ECHO:
+		PM8001_MSG_DBG(pm8001_ha, pm8001_printk("OPC_OUB_ECHO \n"));
+		break;
+	case OPC_OUB_HW_EVENT:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_HW_EVENT \n"));
+		mpi_hw_event(pm8001_ha, piomb);
+		break;
+	case OPC_OUB_SSP_COMP:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_SSP_COMP \n"));
+		mpi_ssp_completion(pm8001_ha, piomb);
+		break;
+	case OPC_OUB_SMP_COMP:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_SMP_COMP \n"));
+		mpi_smp_completion(pm8001_ha, piomb);
+		break;
+	case OPC_OUB_LOCAL_PHY_CNTRL:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_LOCAL_PHY_CNTRL\n"));
+		mpi_local_phy_ctl(pm8001_ha, piomb);
+		break;
+	case OPC_OUB_DEV_REGIST:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_DEV_REGIST \n"));
+		mpi_reg_resp(pm8001_ha, piomb);
+		break;
+	case OPC_OUB_DEREG_DEV:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("unresgister the deviece \n"));
+		mpi_dereg_resp(pm8001_ha, piomb);
+		break;
+	case OPC_OUB_GET_DEV_HANDLE:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_GET_DEV_HANDLE \n"));
+		break;
+	case OPC_OUB_SATA_COMP:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_SATA_COMP \n"));
+		mpi_sata_completion(pm8001_ha, piomb);
+		break;
+	case OPC_OUB_SATA_EVENT:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_SATA_EVENT \n"));
+		mpi_sata_event(pm8001_ha, piomb);
+		break;
+	case OPC_OUB_SSP_EVENT:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_SSP_EVENT\n"));
+		mpi_ssp_event(pm8001_ha, piomb);
+		break;
+	case OPC_OUB_DEV_HANDLE_ARRIV:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_DEV_HANDLE_ARRIV\n"));
+		/*This is for target*/
+		break;
+	case OPC_OUB_SSP_RECV_EVENT:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_SSP_RECV_EVENT\n"));
+		/*This is for target*/
+		break;
+	case OPC_OUB_DEV_INFO:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_DEV_INFO\n"));
+		break;
+	case OPC_OUB_FW_FLASH_UPDATE:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_FW_FLASH_UPDATE\n"));
+		mpi_fw_flash_update_resp(pm8001_ha, piomb);
+		break;
+	case OPC_OUB_GPIO_RESPONSE:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_GPIO_RESPONSE\n"));
+		break;
+	case OPC_OUB_GPIO_EVENT:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_GPIO_EVENT\n"));
+		break;
+	case OPC_OUB_GENERAL_EVENT:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_GENERAL_EVENT\n"));
+		mpi_general_event(pm8001_ha, piomb);
+		break;
+	case OPC_OUB_SSP_ABORT_RSP:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_SSP_ABORT_RSP\n"));
+		mpi_task_abort_resp(pm8001_ha, piomb);
+		break;
+	case OPC_OUB_SATA_ABORT_RSP:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_SATA_ABORT_RSP\n"));
+		mpi_task_abort_resp(pm8001_ha, piomb);
+		break;
+	case OPC_OUB_SAS_DIAG_MODE_START_END:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_SAS_DIAG_MODE_START_END\n"));
+		break;
+	case OPC_OUB_SAS_DIAG_EXECUTE:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_SAS_DIAG_EXECUTE\n"));
+		break;
+	case OPC_OUB_GET_TIME_STAMP:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_GET_TIME_STAMP\n"));
+		break;
+	case OPC_OUB_SAS_HW_EVENT_ACK:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_SAS_HW_EVENT_ACK\n"));
+		break;
+	case OPC_OUB_PORT_CONTROL:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_PORT_CONTROL\n"));
+		break;
+	case OPC_OUB_SMP_ABORT_RSP:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_SMP_ABORT_RSP\n"));
+		mpi_task_abort_resp(pm8001_ha, piomb);
+		break;
+	case OPC_OUB_GET_NVMD_DATA:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_GET_NVMD_DATA\n"));
+		mpi_get_nvmd_resp(pm8001_ha, piomb);
+		break;
+	case OPC_OUB_SET_NVMD_DATA:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_SET_NVMD_DATA\n"));
+		mpi_set_nvmd_resp(pm8001_ha, piomb);
+		break;
+	case OPC_OUB_DEVICE_HANDLE_REMOVAL:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_DEVICE_HANDLE_REMOVAL\n"));
+		break;
+	case OPC_OUB_SET_DEVICE_STATE:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_SET_DEVICE_STATE\n"));
+		mpi_set_dev_state_resp(pm8001_ha, piomb);
+		break;
+	case OPC_OUB_GET_DEVICE_STATE:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_GET_DEVICE_STATE\n"));
+		break;
+	case OPC_OUB_SET_DEV_INFO:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_SET_DEV_INFO\n"));
+		break;
+	case OPC_OUB_SAS_RE_INITIALIZE:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("OPC_OUB_SAS_RE_INITIALIZE\n"));
+		break;
+	default:
+		PM8001_MSG_DBG(pm8001_ha,
+			pm8001_printk("Unknown outbound Queue IOMB OPC = %x\n",
+			opc));
+		break;
+	}
+}
+
+static int process_oq(struct pm8001_hba_info *pm8001_ha)
+{
+	struct outbound_queue_table *circularQ;
+	void *pMsg1 = NULL;
+	u8 bc = 0;
+	u32 ret = MPI_IO_STATUS_FAIL;
+
+	circularQ = &pm8001_ha->outbnd_q_tbl[0];
+	do {
+		ret = mpi_msg_consume(pm8001_ha, circularQ, &pMsg1, &bc);
+		if (MPI_IO_STATUS_SUCCESS == ret) {
+			/* process the outbound message */
+			process_one_iomb(pm8001_ha, (void *)(pMsg1 - 4));
+			/* free the message from the outbound circular buffer */
+			mpi_msg_free_set(pm8001_ha, pMsg1, circularQ, bc);
+		}
+		if (MPI_IO_STATUS_BUSY == ret) {
+			u32 producer_idx;
+			/* Update the producer index from SPC */
+			producer_idx = pm8001_read_32(circularQ->pi_virt);
+			circularQ->producer_index = cpu_to_le32(producer_idx);
+			if (circularQ->producer_index ==
+				circularQ->consumer_idx)
+				/* OQ is empty */
+				break;
+		}
+	} while (1);
+	return ret;
+}
+
+/* PCI_DMA_... to our direction translation. */
+static const u8 data_dir_flags[] = {
+	[PCI_DMA_BIDIRECTIONAL] = DATA_DIR_BYRECIPIENT,/* UNSPECIFIED */
+	[PCI_DMA_TODEVICE]	= DATA_DIR_OUT,/* OUTBOUND */
+	[PCI_DMA_FROMDEVICE]	= DATA_DIR_IN,/* INBOUND */
+	[PCI_DMA_NONE]		= DATA_DIR_NONE,/* NO TRANSFER */
+};
+static void
+pm8001_chip_make_sg(struct scatterlist *scatter, int nr, void *prd)
+{
+	int i;
+	struct scatterlist *sg;
+	struct pm8001_prd *buf_prd = prd;
+
+	for_each_sg(scatter, sg, nr, i) {
+		buf_prd->addr = cpu_to_le64(sg_dma_address(sg));
+		buf_prd->im_len.len = cpu_to_le32(sg_dma_len(sg));
+		buf_prd->im_len.e = 0;
+		buf_prd++;
+	}
+}
+
+static void build_smp_cmd(u32 deviceID, u32 hTag, struct smp_req *psmp_cmd)
+{
+	psmp_cmd->tag = cpu_to_le32(hTag);
+	psmp_cmd->device_id = cpu_to_le32(deviceID);
+	psmp_cmd->len_ip_ir = cpu_to_le32(1|(1 << 1));
+}
+
+/**
+ * pm8001_chip_smp_req - send a SMP task to FW
+ * @pm8001_ha: our hba card information.
+ * @ccb: the ccb information this request used.
+ */
+static int pm8001_chip_smp_req(struct pm8001_hba_info *pm8001_ha,
+	struct pm8001_ccb_info *ccb)
+{
+	int elem, rc;
+	struct sas_task *task = ccb->task;
+	struct domain_device *dev = task->dev;
+	struct pm8001_device *pm8001_dev = dev->lldd_dev;
+	struct scatterlist *sg_req, *sg_resp;
+	u32 req_len, resp_len;
+	struct smp_req smp_cmd;
+	u32 opc;
+	struct inbound_queue_table *circularQ;
+
+	memset(&smp_cmd, 0, sizeof(smp_cmd));
+	/*
+	 * DMA-map SMP request, response buffers
+	 */
+	sg_req = &task->smp_task.smp_req;
+	elem = dma_map_sg(pm8001_ha->dev, sg_req, 1, PCI_DMA_TODEVICE);
+	if (!elem)
+		return -ENOMEM;
+	req_len = sg_dma_len(sg_req);
+
+	sg_resp = &task->smp_task.smp_resp;
+	elem = dma_map_sg(pm8001_ha->dev, sg_resp, 1, PCI_DMA_FROMDEVICE);
+	if (!elem) {
+		rc = -ENOMEM;
+		goto err_out;
+	}
+	resp_len = sg_dma_len(sg_resp);
+	/* must be in dwords */
+	if ((req_len & 0x3) || (resp_len & 0x3)) {
+		rc = -EINVAL;
+		goto err_out_2;
+	}
+
+	opc = OPC_INB_SMP_REQUEST;
+	circularQ = &pm8001_ha->inbnd_q_tbl[0];
+	smp_cmd.tag = cpu_to_le32(ccb->ccb_tag);
+	smp_cmd.long_smp_req.long_req_addr =
+		cpu_to_le64((u64)sg_dma_address(&task->smp_task.smp_req));
+	smp_cmd.long_smp_req.long_req_size =
+		cpu_to_le32((u32)sg_dma_len(&task->smp_task.smp_req)-4);
+	smp_cmd.long_smp_req.long_resp_addr =
+		cpu_to_le64((u64)sg_dma_address(&task->smp_task.smp_resp));
+	smp_cmd.long_smp_req.long_resp_size =
+		cpu_to_le32((u32)sg_dma_len(&task->smp_task.smp_resp)-4);
+	build_smp_cmd(pm8001_dev->device_id, smp_cmd.tag, &smp_cmd);
+	mpi_build_cmd(pm8001_ha, circularQ, opc, (u32 *)&smp_cmd);
+	return 0;
+
+err_out_2:
+	dma_unmap_sg(pm8001_ha->dev, &ccb->task->smp_task.smp_resp, 1,
+			PCI_DMA_FROMDEVICE);
+err_out:
+	dma_unmap_sg(pm8001_ha->dev, &ccb->task->smp_task.smp_req, 1,
+			PCI_DMA_TODEVICE);
+	return rc;
+}
+
+/**
+ * pm8001_chip_ssp_io_req - send a SSP task to FW
+ * @pm8001_ha: our hba card information.
+ * @ccb: the ccb information this request used.
+ */
+static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
+	struct pm8001_ccb_info *ccb)
+{
+	struct sas_task *task = ccb->task;
+	struct domain_device *dev = task->dev;
+	struct pm8001_device *pm8001_dev = dev->lldd_dev;
+	struct ssp_ini_io_start_req ssp_cmd;
+	u32 tag = ccb->ccb_tag;
+	int ret;
+	__le64 phys_addr;
+	struct inbound_queue_table *circularQ;
+	u32 opc = OPC_INB_SSPINIIOSTART;
+	memset(&ssp_cmd, 0, sizeof(ssp_cmd));
+	memcpy(ssp_cmd.ssp_iu.lun, task->ssp_task.LUN, 8);
+	ssp_cmd.dir_m_tlr = data_dir_flags[task->data_dir] << 8 | 0x0;/*0 for
+	SAS 1.1 compatible TLR*/
+	ssp_cmd.data_len = cpu_to_le32(task->total_xfer_len);
+	ssp_cmd.device_id = cpu_to_le32(pm8001_dev->device_id);
+	ssp_cmd.tag = cpu_to_le32(tag);
+	if (task->ssp_task.enable_first_burst)
+		ssp_cmd.ssp_iu.efb_prio_attr |= 0x80;
+	ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_prio << 3);
+	ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7);
+	memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cdb, 16);
+	circularQ = &pm8001_ha->inbnd_q_tbl[0];
+
+	/* fill in PRD (scatter/gather) table, if any */
+	if (task->num_scatter > 1) {
+		pm8001_chip_make_sg(task->scatter, ccb->n_elem, ccb->buf_prd);
+		phys_addr = cpu_to_le64(ccb->ccb_dma_handle +
+				offsetof(struct pm8001_ccb_info, buf_prd[0]));
+		ssp_cmd.addr_low = lower_32_bits(phys_addr);
+		ssp_cmd.addr_high = upper_32_bits(phys_addr);
+		ssp_cmd.esgl = cpu_to_le32(1<<31);
+	} else if (task->num_scatter == 1) {
+		__le64 dma_addr = cpu_to_le64(sg_dma_address(task->scatter));
+		ssp_cmd.addr_low = lower_32_bits(dma_addr);
+		ssp_cmd.addr_high = upper_32_bits(dma_addr);
+		ssp_cmd.len = cpu_to_le32(task->total_xfer_len);
+		ssp_cmd.esgl = 0;
+	} else if (task->num_scatter == 0) {
+		ssp_cmd.addr_low = 0;
+		ssp_cmd.addr_high = 0;
+		ssp_cmd.len = cpu_to_le32(task->total_xfer_len);
+		ssp_cmd.esgl = 0;
+	}
+	ret = mpi_build_cmd(pm8001_ha, circularQ, opc, &ssp_cmd);
+	return ret;
+}
+
+static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
+	struct pm8001_ccb_info *ccb)
+{
+	struct sas_task *task = ccb->task;
+	struct domain_device *dev = task->dev;
+	struct pm8001_device *pm8001_ha_dev = dev->lldd_dev;
+	u32 tag = ccb->ccb_tag;
+	int ret;
+	struct sata_start_req sata_cmd;
+	u32 hdr_tag, ncg_tag = 0;
+	__le64 phys_addr;
+	u32 ATAP = 0x0;
+	u32 dir;
+	struct inbound_queue_table *circularQ;
+	u32  opc = OPC_INB_SATA_HOST_OPSTART;
+	memset(&sata_cmd, 0, sizeof(sata_cmd));
+	circularQ = &pm8001_ha->inbnd_q_tbl[0];
+	if (task->data_dir == PCI_DMA_NONE) {
+		ATAP = 0x04;  /* no data*/
+		PM8001_IO_DBG(pm8001_ha, pm8001_printk("no data \n"));
+	} else if (likely(!task->ata_task.device_control_reg_update)) {
+		if (task->ata_task.dma_xfer) {
+			ATAP = 0x06; /* DMA */
+			PM8001_IO_DBG(pm8001_ha, pm8001_printk("DMA \n"));
+		} else {
+			ATAP = 0x05; /* PIO*/
+			PM8001_IO_DBG(pm8001_ha, pm8001_printk("PIO \n"));
+		}
+		if (task->ata_task.use_ncq &&
+			dev->sata_dev.command_set != ATAPI_COMMAND_SET) {
+			ATAP = 0x07; /* FPDMA */
+			PM8001_IO_DBG(pm8001_ha, pm8001_printk("FPDMA \n"));
+		}
+	}
+	if (task->ata_task.use_ncq && pm8001_get_ncq_tag(task, &hdr_tag))
+		ncg_tag = cpu_to_le32(hdr_tag);
+	dir = data_dir_flags[task->data_dir] << 8;
+	sata_cmd.tag = cpu_to_le32(tag);
+	sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
+	sata_cmd.data_len = cpu_to_le32(task->total_xfer_len);
+	sata_cmd.ncqtag_atap_dir_m =
+		cpu_to_le32(((ncg_tag & 0xff)<<16)|((ATAP & 0x3f) << 10) | dir);
+	sata_cmd.sata_fis = task->ata_task.fis;
+	if (likely(!task->ata_task.device_control_reg_update))
+		sata_cmd.sata_fis.flags |= 0x80;/* C=1: update ATA cmd reg */
+	sata_cmd.sata_fis.flags &= 0xF0;/* PM_PORT field shall be 0 */
+	/* fill in PRD (scatter/gather) table, if any */
+	if (task->num_scatter > 1) {
+		pm8001_chip_make_sg(task->scatter, ccb->n_elem, ccb->buf_prd);
+		phys_addr = cpu_to_le64(ccb->ccb_dma_handle +
+				offsetof(struct pm8001_ccb_info, buf_prd[0]));
+		sata_cmd.addr_low = lower_32_bits(phys_addr);
+		sata_cmd.addr_high = upper_32_bits(phys_addr);
+		sata_cmd.esgl = cpu_to_le32(1 << 31);
+	} else if (task->num_scatter == 1) {
+		__le64 dma_addr = cpu_to_le64(sg_dma_address(task->scatter));
+		sata_cmd.addr_low = lower_32_bits(dma_addr);
+		sata_cmd.addr_high = upper_32_bits(dma_addr);
+		sata_cmd.len = cpu_to_le32(task->total_xfer_len);
+		sata_cmd.esgl = 0;
+	} else if (task->num_scatter == 0) {
+		sata_cmd.addr_low = 0;
+		sata_cmd.addr_high = 0;
+		sata_cmd.len = cpu_to_le32(task->total_xfer_len);
+		sata_cmd.esgl = 0;
+	}
+	ret = mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd);
+	return ret;
+}
+
+/**
+ * pm8001_chip_phy_start_req - start phy via PHY_START COMMAND
+ * @pm8001_ha: our hba card information.
+ * @num: the inbound queue number
+ * @phy_id: the phy id which we wanted to start up.
+ */
+static int
+pm8001_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id)
+{
+	struct phy_start_req payload;
+	struct inbound_queue_table *circularQ;
+	int ret;
+	u32 tag = 0x01;
+	u32 opcode = OPC_INB_PHYSTART;
+	circularQ = &pm8001_ha->inbnd_q_tbl[0];
+	memset(&payload, 0, sizeof(payload));
+	payload.tag = cpu_to_le32(tag);
+	/*
+	 ** [0:7]   PHY Identifier
+	 ** [8:11]  link rate 1.5G, 3G, 6G
+	 ** [12:13] link mode 01b SAS mode; 10b SATA mode; 11b both
+	 ** [14]    0b disable spin up hold; 1b enable spin up hold
+	 */
+	payload.ase_sh_lm_slr_phyid = cpu_to_le32(SPINHOLD_DISABLE |
+		LINKMODE_AUTO |	LINKRATE_15 |
+		LINKRATE_30 | LINKRATE_60 | phy_id);
+	payload.sas_identify.dev_type = SAS_END_DEV;
+	payload.sas_identify.initiator_bits = SAS_PROTOCOL_ALL;
+	memcpy(payload.sas_identify.sas_addr,
+		pm8001_ha->sas_addr, SAS_ADDR_SIZE);
+	payload.sas_identify.phy_id = phy_id;
+	ret = mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload);
+	return ret;
+}
+
+/**
+ * pm8001_chip_phy_stop_req - start phy via PHY_STOP COMMAND
+ * @pm8001_ha: our hba card information.
+ * @num: the inbound queue number
+ * @phy_id: the phy id which we wanted to start up.
+ */
+static int pm8001_chip_phy_stop_req(struct pm8001_hba_info *pm8001_ha,
+	u8 phy_id)
+{
+	struct phy_stop_req payload;
+	struct inbound_queue_table *circularQ;
+	int ret;
+	u32 tag = 0x01;
+	u32 opcode = OPC_INB_PHYSTOP;
+	circularQ = &pm8001_ha->inbnd_q_tbl[0];
+	memset(&payload, 0, sizeof(payload));
+	payload.tag = cpu_to_le32(tag);
+	payload.phy_id = cpu_to_le32(phy_id);
+	ret = mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload);
+	return ret;
+}
+
+/**
+ * see comments on mpi_reg_resp.
+ */
+static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
+	struct pm8001_device *pm8001_dev, u32 flag)
+{
+	struct reg_dev_req payload;
+	u32	opc;
+	u32 stp_sspsmp_sata = 0x4;
+	struct inbound_queue_table *circularQ;
+	u32 linkrate, phy_id;
+	int rc, tag = 0xdeadbeef;
+	struct pm8001_ccb_info *ccb;
+	u8 retryFlag = 0x1;
+	u16 firstBurstSize = 0;
+	u16 ITNT = 2000;
+	struct domain_device *dev = pm8001_dev->sas_device;
+	struct domain_device *parent_dev = dev->parent;
+	circularQ = &pm8001_ha->inbnd_q_tbl[0];
+
+	memset(&payload, 0, sizeof(payload));
+	rc = pm8001_tag_alloc(pm8001_ha, &tag);
+	if (rc)
+		return rc;
+	ccb = &pm8001_ha->ccb_info[tag];
+	ccb->device = pm8001_dev;
+	ccb->ccb_tag = tag;
+	payload.tag = cpu_to_le32(tag);
+	if (flag == 1)
+		stp_sspsmp_sata = 0x02; /*direct attached sata */
+	else {
+		if (pm8001_dev->dev_type == SATA_DEV)
+			stp_sspsmp_sata = 0x00; /* stp*/
+		else if (pm8001_dev->dev_type == SAS_END_DEV ||
+			pm8001_dev->dev_type == EDGE_DEV ||
+			pm8001_dev->dev_type == FANOUT_DEV)
+			stp_sspsmp_sata = 0x01; /*ssp or smp*/
+	}
+	if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type))
+		phy_id = parent_dev->ex_dev.ex_phy->phy_id;
+	else
+		phy_id = pm8001_dev->attached_phy;
+	opc = OPC_INB_REG_DEV;
+	linkrate = (pm8001_dev->sas_device->linkrate < dev->port->linkrate) ?
+			pm8001_dev->sas_device->linkrate : dev->port->linkrate;
+	payload.phyid_portid =
+		cpu_to_le32(((pm8001_dev->sas_device->port->id) & 0x0F) |
+		((phy_id & 0x0F) << 4));
+	payload.dtype_dlr_retry = cpu_to_le32((retryFlag & 0x01) |
+		((linkrate & 0x0F) * 0x1000000) |
+		((stp_sspsmp_sata & 0x03) * 0x10000000));
+	payload.firstburstsize_ITNexustimeout =
+		cpu_to_le32(ITNT | (firstBurstSize * 0x10000));
+	memcpy(&payload.sas_addr_hi, pm8001_dev->sas_device->sas_addr,
+		SAS_ADDR_SIZE);
+	rc = mpi_build_cmd(pm8001_ha, circularQ, opc, &payload);
+	return rc;
+}
+
+/**
+ * see comments on mpi_reg_resp.
+ */
+static int pm8001_chip_dereg_dev_req(struct pm8001_hba_info *pm8001_ha,
+	u32 device_id)
+{
+	struct dereg_dev_req payload;
+	u32 opc = OPC_INB_DEREG_DEV_HANDLE;
+	int ret;
+	struct inbound_queue_table *circularQ;
+
+	circularQ = &pm8001_ha->inbnd_q_tbl[0];
+	memset(&payload, 0, sizeof(payload));
+	payload.tag = 1;
+	payload.device_id = cpu_to_le32(device_id);
+	PM8001_MSG_DBG(pm8001_ha,
+		pm8001_printk("unregister device device_id = %d\n", device_id));
+	ret = mpi_build_cmd(pm8001_ha, circularQ, opc, &payload);
+	return ret;
+}
+
+/**
+ * pm8001_chip_phy_ctl_req - support the local phy operation
+ * @pm8001_ha: our hba card information.
+ * @num: the inbound queue number
+ * @phy_id: the phy id which we wanted to operate
+ * @phy_op:
+ */
+static int pm8001_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,
+	u32 phyId, u32 phy_op)
+{
+	struct local_phy_ctl_req payload;
+	struct inbound_queue_table *circularQ;
+	int ret;
+	u32 opc = OPC_INB_LOCAL_PHY_CONTROL;
+	memset((u8 *)&payload, 0, sizeof(payload));
+	circularQ = &pm8001_ha->inbnd_q_tbl[0];
+	payload.tag = 1;
+	payload.phyop_phyid =
+		cpu_to_le32(((phy_op & 0xff) << 8) | (phyId & 0x0F));
+	ret = mpi_build_cmd(pm8001_ha, circularQ, opc, &payload);
+	return ret;
+}
+
+static u32 pm8001_chip_is_our_interupt(struct pm8001_hba_info *pm8001_ha)
+{
+	u32 value;
+#ifdef PM8001_USE_MSIX
+	return 1;
+#endif
+	value = pm8001_cr32(pm8001_ha, 0, MSGU_ODR);
+	if (value)
+		return 1;
+	return 0;
+
+}
+
+/**
+ * pm8001_chip_isr - PM8001 isr handler.
+ * @pm8001_ha: our hba card information.
+ * @irq: irq number.
+ * @stat: stat.
+ */
+static irqreturn_t
+pm8001_chip_isr(struct pm8001_hba_info *pm8001_ha)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&pm8001_ha->lock, flags);
+	pm8001_chip_interrupt_disable(pm8001_ha);
+	process_oq(pm8001_ha);
+	pm8001_chip_interrupt_enable(pm8001_ha);
+	spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+	return IRQ_HANDLED;
+}
+
+static int send_task_abort(struct pm8001_hba_info *pm8001_ha, u32 opc,
+	u32 dev_id, u8 flag, u32 task_tag, u32 cmd_tag)
+{
+	struct task_abort_req task_abort;
+	struct inbound_queue_table *circularQ;
+	int ret;
+	circularQ = &pm8001_ha->inbnd_q_tbl[0];
+	memset(&task_abort, 0, sizeof(task_abort));
+	if (ABORT_SINGLE == (flag & ABORT_MASK)) {
+		task_abort.abort_all = 0;
+		task_abort.device_id = cpu_to_le32(dev_id);
+		task_abort.tag_to_abort = cpu_to_le32(task_tag);
+		task_abort.tag = cpu_to_le32(cmd_tag);
+	} else if (ABORT_ALL == (flag & ABORT_MASK)) {
+		task_abort.abort_all = cpu_to_le32(1);
+		task_abort.device_id = cpu_to_le32(dev_id);
+		task_abort.tag = cpu_to_le32(cmd_tag);
+	}
+	ret = mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort);
+	return ret;
+}
+
+/**
+ * pm8001_chip_abort_task - SAS abort task when error or exception happened.
+ * @task: the task we wanted to aborted.
+ * @flag: the abort flag.
+ */
+static int pm8001_chip_abort_task(struct pm8001_hba_info *pm8001_ha,
+	struct pm8001_device *pm8001_dev, u8 flag, u32 task_tag, u32 cmd_tag)
+{
+	u32 opc, device_id;
+	int rc = TMF_RESP_FUNC_FAILED;
+	PM8001_EH_DBG(pm8001_ha, pm8001_printk("cmd_tag = %x, abort task tag"
+		" = %x", cmd_tag, task_tag));
+	if (pm8001_dev->dev_type == SAS_END_DEV)
+		opc = OPC_INB_SSP_ABORT;
+	else if (pm8001_dev->dev_type == SATA_DEV)
+		opc = OPC_INB_SATA_ABORT;
+	else
+		opc = OPC_INB_SMP_ABORT;/* SMP */
+	device_id = pm8001_dev->device_id;
+	rc = send_task_abort(pm8001_ha, opc, device_id, flag,
+		task_tag, cmd_tag);
+	if (rc != TMF_RESP_FUNC_COMPLETE)
+		PM8001_EH_DBG(pm8001_ha, pm8001_printk("rc= %d\n", rc));
+	return rc;
+}
+
+/**
+ * pm8001_chip_ssp_tm_req - built the task managment command.
+ * @pm8001_ha: our hba card information.
+ * @ccb: the ccb information.
+ * @tmf: task management function.
+ */
+static int pm8001_chip_ssp_tm_req(struct pm8001_hba_info *pm8001_ha,
+	struct pm8001_ccb_info *ccb, struct pm8001_tmf_task *tmf)
+{
+	struct sas_task *task = ccb->task;
+	struct domain_device *dev = task->dev;
+	struct pm8001_device *pm8001_dev = dev->lldd_dev;
+	u32 opc = OPC_INB_SSPINITMSTART;
+	struct inbound_queue_table *circularQ;
+	struct ssp_ini_tm_start_req sspTMCmd;
+	int ret;
+
+	memset(&sspTMCmd, 0, sizeof(sspTMCmd));
+	sspTMCmd.device_id = cpu_to_le32(pm8001_dev->device_id);
+	sspTMCmd.relate_tag = cpu_to_le32(tmf->tag_of_task_to_be_managed);
+	sspTMCmd.tmf = cpu_to_le32(tmf->tmf);
+	memcpy(sspTMCmd.lun, task->ssp_task.LUN, 8);
+	sspTMCmd.tag = cpu_to_le32(ccb->ccb_tag);
+	circularQ = &pm8001_ha->inbnd_q_tbl[0];
+	ret = mpi_build_cmd(pm8001_ha, circularQ, opc, &sspTMCmd);
+	return ret;
+}
+
+static int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
+	void *payload)
+{
+	u32 opc = OPC_INB_GET_NVMD_DATA;
+	u32 nvmd_type;
+	int rc;
+	u32 tag;
+	struct pm8001_ccb_info *ccb;
+	struct inbound_queue_table *circularQ;
+	struct get_nvm_data_req nvmd_req;
+	struct fw_control_ex *fw_control_context;
+	struct pm8001_ioctl_payload *ioctl_payload = payload;
+
+	nvmd_type = ioctl_payload->minor_function;
+	fw_control_context = kzalloc(sizeof(struct fw_control_ex), GFP_KERNEL);
+	fw_control_context->usrAddr = (u8 *)&ioctl_payload->func_specific[0];
+	fw_control_context->len = ioctl_payload->length;
+	circularQ = &pm8001_ha->inbnd_q_tbl[0];
+	memset(&nvmd_req, 0, sizeof(nvmd_req));
+	rc = pm8001_tag_alloc(pm8001_ha, &tag);
+	if (rc)
+		return rc;
+	ccb = &pm8001_ha->ccb_info[tag];
+	ccb->ccb_tag = tag;
+	ccb->fw_control_context = fw_control_context;
+	nvmd_req.tag = cpu_to_le32(tag);
+
+	switch (nvmd_type) {
+	case TWI_DEVICE: {
+		u32 twi_addr, twi_page_size;
+		twi_addr = 0xa8;
+		twi_page_size = 2;
+
+		nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | twi_addr << 16 |
+			twi_page_size << 8 | TWI_DEVICE);
+		nvmd_req.resp_len = cpu_to_le32(ioctl_payload->length);
+		nvmd_req.resp_addr_hi =
+		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);
+		nvmd_req.resp_addr_lo =
+		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo);
+		break;
+	}
+	case C_SEEPROM: {
+		nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | C_SEEPROM);
+		nvmd_req.resp_len = cpu_to_le32(ioctl_payload->length);
+		nvmd_req.resp_addr_hi =
+		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);
+		nvmd_req.resp_addr_lo =
+		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo);
+		break;
+	}
+	case VPD_FLASH: {
+		nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | VPD_FLASH);
+		nvmd_req.resp_len = cpu_to_le32(ioctl_payload->length);
+		nvmd_req.resp_addr_hi =
+		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);
+		nvmd_req.resp_addr_lo =
+		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo);
+		break;
+	}
+	case EXPAN_ROM: {
+		nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | EXPAN_ROM);
+		nvmd_req.resp_len = cpu_to_le32(ioctl_payload->length);
+		nvmd_req.resp_addr_hi =
+		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);
+		nvmd_req.resp_addr_lo =
+		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo);
+		break;
+	}
+	default:
+		break;
+	}
+	rc = mpi_build_cmd(pm8001_ha, circularQ, opc, &nvmd_req);
+	return rc;
+}
+
+static int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,
+	void *payload)
+{
+	u32 opc = OPC_INB_SET_NVMD_DATA;
+	u32 nvmd_type;
+	int rc;
+	u32 tag;
+	struct pm8001_ccb_info *ccb;
+	struct inbound_queue_table *circularQ;
+	struct set_nvm_data_req nvmd_req;
+	struct fw_control_ex *fw_control_context;
+	struct pm8001_ioctl_payload *ioctl_payload = payload;
+
+	nvmd_type = ioctl_payload->minor_function;
+	fw_control_context = kzalloc(sizeof(struct fw_control_ex), GFP_KERNEL);
+	circularQ = &pm8001_ha->inbnd_q_tbl[0];
+	memcpy(pm8001_ha->memoryMap.region[NVMD].virt_ptr,
+		ioctl_payload->func_specific,
+		ioctl_payload->length);
+	memset(&nvmd_req, 0, sizeof(nvmd_req));
+	rc = pm8001_tag_alloc(pm8001_ha, &tag);
+	if (rc)
+		return rc;
+	ccb = &pm8001_ha->ccb_info[tag];
+	ccb->fw_control_context = fw_control_context;
+	ccb->ccb_tag = tag;
+	nvmd_req.tag = cpu_to_le32(tag);
+	switch (nvmd_type) {
+	case TWI_DEVICE: {
+		u32 twi_addr, twi_page_size;
+		twi_addr = 0xa8;
+		twi_page_size = 2;
+		nvmd_req.reserved[0] = cpu_to_le32(0xFEDCBA98);
+		nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | twi_addr << 16 |
+			twi_page_size << 8 | TWI_DEVICE);
+		nvmd_req.resp_len = cpu_to_le32(ioctl_payload->length);
+		nvmd_req.resp_addr_hi =
+		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);
+		nvmd_req.resp_addr_lo =
+		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo);
+		break;
+	}
+	case C_SEEPROM:
+		nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | C_SEEPROM);
+		nvmd_req.resp_len = cpu_to_le32(ioctl_payload->length);
+		nvmd_req.reserved[0] = cpu_to_le32(0xFEDCBA98);
+		nvmd_req.resp_addr_hi =
+		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);
+		nvmd_req.resp_addr_lo =
+		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo);
+		break;
+	case VPD_FLASH:
+		nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | VPD_FLASH);
+		nvmd_req.resp_len = cpu_to_le32(ioctl_payload->length);
+		nvmd_req.reserved[0] = cpu_to_le32(0xFEDCBA98);
+		nvmd_req.resp_addr_hi =
+		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);
+		nvmd_req.resp_addr_lo =
+		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo);
+		break;
+	case EXPAN_ROM:
+		nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | EXPAN_ROM);
+		nvmd_req.resp_len = cpu_to_le32(ioctl_payload->length);
+		nvmd_req.reserved[0] = cpu_to_le32(0xFEDCBA98);
+		nvmd_req.resp_addr_hi =
+		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);
+		nvmd_req.resp_addr_lo =
+		    cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo);
+		break;
+	default:
+		break;
+	}
+	rc = mpi_build_cmd(pm8001_ha, circularQ, opc, &nvmd_req);
+	return rc;
+}
+
+/**
+ * pm8001_chip_fw_flash_update_build - support the firmware update operation
+ * @pm8001_ha: our hba card information.
+ * @fw_flash_updata_info: firmware flash update param
+ */
+static int
+pm8001_chip_fw_flash_update_build(struct pm8001_hba_info *pm8001_ha,
+	void *fw_flash_updata_info, u32 tag)
+{
+	struct fw_flash_Update_req payload;
+	struct fw_flash_updata_info *info;
+	struct inbound_queue_table *circularQ;
+	int ret;
+	u32 opc = OPC_INB_FW_FLASH_UPDATE;
+
+	memset(&payload, 0, sizeof(struct fw_flash_Update_req));
+	circularQ = &pm8001_ha->inbnd_q_tbl[0];
+	info = fw_flash_updata_info;
+	payload.tag = cpu_to_le32(tag);
+	payload.cur_image_len = cpu_to_le32(info->cur_image_len);
+	payload.cur_image_offset = cpu_to_le32(info->cur_image_offset);
+	payload.total_image_len = cpu_to_le32(info->total_image_len);
+	payload.len = info->sgl.im_len.len ;
+	payload.sgl_addr_lo = lower_32_bits(info->sgl.addr);
+	payload.sgl_addr_hi = upper_32_bits(info->sgl.addr);
+	ret = mpi_build_cmd(pm8001_ha, circularQ, opc, &payload);
+	return ret;
+}
+
+static int
+pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,
+	void *payload)
+{
+	struct fw_flash_updata_info flash_update_info;
+	struct fw_control_info *fw_control;
+	struct fw_control_ex *fw_control_context;
+	int rc;
+	u32 tag;
+	struct pm8001_ccb_info *ccb;
+	void *buffer = NULL;
+	dma_addr_t phys_addr;
+	u32 phys_addr_hi;
+	u32 phys_addr_lo;
+	struct pm8001_ioctl_payload *ioctl_payload = payload;
+
+	fw_control_context = kzalloc(sizeof(struct fw_control_ex), GFP_KERNEL);
+	fw_control = (struct fw_control_info *)&ioctl_payload->func_specific[0];
+	if (fw_control->len != 0) {
+		if (pm8001_mem_alloc(pm8001_ha->pdev,
+			(void **)&buffer,
+			&phys_addr,
+			&phys_addr_hi,
+			&phys_addr_lo,
+			fw_control->len, 0) != 0) {
+				PM8001_FAIL_DBG(pm8001_ha,
+					pm8001_printk("Mem alloc failure\n"));
+				return -ENOMEM;
+		}
+	}
+	memset(buffer, 0, fw_control->len);
+	memcpy(buffer, fw_control->buffer, fw_control->len);
+	flash_update_info.sgl.addr = cpu_to_le64(phys_addr);
+	flash_update_info.sgl.im_len.len = cpu_to_le32(fw_control->len);
+	flash_update_info.sgl.im_len.e = 0;
+	flash_update_info.cur_image_offset = fw_control->offset;
+	flash_update_info.cur_image_len = fw_control->len;
+	flash_update_info.total_image_len = fw_control->size;
+	fw_control_context->fw_control = fw_control;
+	fw_control_context->virtAddr = buffer;
+	fw_control_context->len = fw_control->len;
+	rc = pm8001_tag_alloc(pm8001_ha, &tag);
+	if (rc)
+		return rc;
+	ccb = &pm8001_ha->ccb_info[tag];
+	ccb->fw_control_context = fw_control_context;
+	ccb->ccb_tag = tag;
+	rc = pm8001_chip_fw_flash_update_build(pm8001_ha, &flash_update_info,
+		tag);
+	return rc;
+}
+
+static int
+pm8001_chip_set_dev_state_req(struct pm8001_hba_info *pm8001_ha,
+	struct pm8001_device *pm8001_dev, u32 state)
+{
+	struct set_dev_state_req payload;
+	struct inbound_queue_table *circularQ;
+	struct pm8001_ccb_info *ccb;
+	int rc;
+	u32 tag;
+	u32 opc = OPC_INB_SET_DEVICE_STATE;
+	memset(&payload, 0, sizeof(payload));
+	rc = pm8001_tag_alloc(pm8001_ha, &tag);
+	if (rc)
+		return -1;
+	ccb = &pm8001_ha->ccb_info[tag];
+	ccb->ccb_tag = tag;
+	ccb->device = pm8001_dev;
+	circularQ = &pm8001_ha->inbnd_q_tbl[0];
+	payload.tag = cpu_to_le32(tag);
+	payload.device_id = cpu_to_le32(pm8001_dev->device_id);
+	payload.nds = cpu_to_le32(state);
+	rc = mpi_build_cmd(pm8001_ha, circularQ, opc, &payload);
+	return rc;
+
+}
+
+static int
+pm8001_chip_sas_re_initialization(struct pm8001_hba_info *pm8001_ha)
+{
+	struct sas_re_initialization_req payload;
+	struct inbound_queue_table *circularQ;
+	struct pm8001_ccb_info *ccb;
+	int rc;
+	u32 tag;
+	u32 opc = OPC_INB_SAS_RE_INITIALIZE;
+	memset(&payload, 0, sizeof(payload));
+	rc = pm8001_tag_alloc(pm8001_ha, &tag);
+	if (rc)
+		return -1;
+	ccb = &pm8001_ha->ccb_info[tag];
+	ccb->ccb_tag = tag;
+	circularQ = &pm8001_ha->inbnd_q_tbl[0];
+	payload.tag = cpu_to_le32(tag);
+	payload.SSAHOLT = cpu_to_le32(0xd << 25);
+	payload.sata_hol_tmo = cpu_to_le32(80);
+	payload.open_reject_cmdretries_data_retries = cpu_to_le32(0xff00ff);
+	rc = mpi_build_cmd(pm8001_ha, circularQ, opc, &payload);
+	return rc;
+
+}
+
+const struct pm8001_dispatch pm8001_8001_dispatch = {
+	.name			= "pmc8001",
+	.chip_init		= pm8001_chip_init,
+	.chip_soft_rst		= pm8001_chip_soft_rst,
+	.chip_rst		= pm8001_hw_chip_rst,
+	.chip_iounmap		= pm8001_chip_iounmap,
+	.isr			= pm8001_chip_isr,
+	.is_our_interupt	= pm8001_chip_is_our_interupt,
+	.isr_process_oq		= process_oq,
+	.interrupt_enable 	= pm8001_chip_interrupt_enable,
+	.interrupt_disable	= pm8001_chip_interrupt_disable,
+	.make_prd		= pm8001_chip_make_sg,
+	.smp_req		= pm8001_chip_smp_req,
+	.ssp_io_req		= pm8001_chip_ssp_io_req,
+	.sata_req		= pm8001_chip_sata_req,
+	.phy_start_req		= pm8001_chip_phy_start_req,
+	.phy_stop_req		= pm8001_chip_phy_stop_req,
+	.reg_dev_req		= pm8001_chip_reg_dev_req,
+	.dereg_dev_req		= pm8001_chip_dereg_dev_req,
+	.phy_ctl_req		= pm8001_chip_phy_ctl_req,
+	.task_abort		= pm8001_chip_abort_task,
+	.ssp_tm_req		= pm8001_chip_ssp_tm_req,
+	.get_nvmd_req		= pm8001_chip_get_nvmd_req,
+	.set_nvmd_req		= pm8001_chip_set_nvmd_req,
+	.fw_flash_update_req	= pm8001_chip_fw_flash_update_req,
+	.set_dev_state_req	= pm8001_chip_set_dev_state_req,
+	.sas_re_init_req	= pm8001_chip_sas_re_initialization,
+};
+
diff --git a/drivers/scsi/pm8001/pm8001_hwi.h b/drivers/scsi/pm8001/pm8001_hwi.h
new file mode 100644
index 0000000..96e4daa
--- /dev/null
+++ b/drivers/scsi/pm8001/pm8001_hwi.h
@@ -0,0 +1,1030 @@
+/*
+ * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver
+ *
+ * Copyright (c) 2008-2009 USI Co., Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+#ifndef _PMC8001_REG_H_
+#define _PMC8001_REG_H_
+
+#include <linux/types.h>
+#include <scsi/libsas.h>
+
+
+/* for Request Opcode of IOMB */
+#define OPC_INB_ECHO				1	/* 0x000 */
+#define OPC_INB_PHYSTART			4	/* 0x004 */
+#define OPC_INB_PHYSTOP				5	/* 0x005 */
+#define OPC_INB_SSPINIIOSTART			6	/* 0x006 */
+#define OPC_INB_SSPINITMSTART			7	/* 0x007 */
+#define OPC_INB_SSPINIEXTIOSTART		8	/* 0x008 */
+#define OPC_INB_DEV_HANDLE_ACCEPT		9	/* 0x009 */
+#define OPC_INB_SSPTGTIOSTART			10	/* 0x00A */
+#define OPC_INB_SSPTGTRSPSTART			11	/* 0x00B */
+#define OPC_INB_SSPINIEDCIOSTART		12	/* 0x00C */
+#define OPC_INB_SSPINIEXTEDCIOSTART		13	/* 0x00D */
+#define OPC_INB_SSPTGTEDCIOSTART		14	/* 0x00E */
+#define OPC_INB_SSP_ABORT			15	/* 0x00F */
+#define OPC_INB_DEREG_DEV_HANDLE		16	/* 0x010 */
+#define OPC_INB_GET_DEV_HANDLE			17	/* 0x011 */
+#define OPC_INB_SMP_REQUEST			18	/* 0x012 */
+/* SMP_RESPONSE is removed */
+#define OPC_INB_SMP_RESPONSE			19	/* 0x013 */
+#define OPC_INB_SMP_ABORT			20	/* 0x014 */
+#define OPC_INB_REG_DEV				22	/* 0x016 */
+#define OPC_INB_SATA_HOST_OPSTART		23	/* 0x017 */
+#define OPC_INB_SATA_ABORT			24	/* 0x018 */
+#define OPC_INB_LOCAL_PHY_CONTROL		25	/* 0x019 */
+#define OPC_INB_GET_DEV_INFO			26	/* 0x01A */
+#define OPC_INB_FW_FLASH_UPDATE			32	/* 0x020 */
+#define OPC_INB_GPIO				34	/* 0x022 */
+#define OPC_INB_SAS_DIAG_MODE_START_END		35	/* 0x023 */
+#define OPC_INB_SAS_DIAG_EXECUTE		36	/* 0x024 */
+#define OPC_INB_SAS_HW_EVENT_ACK		37	/* 0x025 */
+#define OPC_INB_GET_TIME_STAMP			38	/* 0x026 */
+#define OPC_INB_PORT_CONTROL			39	/* 0x027 */
+#define OPC_INB_GET_NVMD_DATA			40	/* 0x028 */
+#define OPC_INB_SET_NVMD_DATA			41	/* 0x029 */
+#define OPC_INB_SET_DEVICE_STATE		42	/* 0x02A */
+#define OPC_INB_GET_DEVICE_STATE		43	/* 0x02B */
+#define OPC_INB_SET_DEV_INFO			44	/* 0x02C */
+#define OPC_INB_SAS_RE_INITIALIZE		45	/* 0x02D */
+
+/* for Response Opcode of IOMB */
+#define OPC_OUB_ECHO				1	/* 0x001 */
+#define OPC_OUB_HW_EVENT			4	/* 0x004 */
+#define OPC_OUB_SSP_COMP			5	/* 0x005 */
+#define OPC_OUB_SMP_COMP			6	/* 0x006 */
+#define OPC_OUB_LOCAL_PHY_CNTRL			7	/* 0x007 */
+#define OPC_OUB_DEV_REGIST			10	/* 0x00A */
+#define OPC_OUB_DEREG_DEV			11	/* 0x00B */
+#define OPC_OUB_GET_DEV_HANDLE			12	/* 0x00C */
+#define OPC_OUB_SATA_COMP			13	/* 0x00D */
+#define OPC_OUB_SATA_EVENT			14	/* 0x00E */
+#define OPC_OUB_SSP_EVENT			15	/* 0x00F */
+#define OPC_OUB_DEV_HANDLE_ARRIV		16	/* 0x010 */
+/* SMP_RECEIVED Notification is removed */
+#define OPC_OUB_SMP_RECV_EVENT			17	/* 0x011 */
+#define OPC_OUB_SSP_RECV_EVENT			18	/* 0x012 */
+#define OPC_OUB_DEV_INFO			19	/* 0x013 */
+#define OPC_OUB_FW_FLASH_UPDATE			20	/* 0x014 */
+#define OPC_OUB_GPIO_RESPONSE			22	/* 0x016 */
+#define OPC_OUB_GPIO_EVENT			23	/* 0x017 */
+#define OPC_OUB_GENERAL_EVENT			24	/* 0x018 */
+#define OPC_OUB_SSP_ABORT_RSP			26	/* 0x01A */
+#define OPC_OUB_SATA_ABORT_RSP			27	/* 0x01B */
+#define OPC_OUB_SAS_DIAG_MODE_START_END		28	/* 0x01C */
+#define OPC_OUB_SAS_DIAG_EXECUTE		29	/* 0x01D */
+#define OPC_OUB_GET_TIME_STAMP			30	/* 0x01E */
+#define OPC_OUB_SAS_HW_EVENT_ACK		31	/* 0x01F */
+#define OPC_OUB_PORT_CONTROL			32	/* 0x020 */
+#define OPC_OUB_SKIP_ENTRY			33	/* 0x021 */
+#define OPC_OUB_SMP_ABORT_RSP			34	/* 0x022 */
+#define OPC_OUB_GET_NVMD_DATA			35	/* 0x023 */
+#define OPC_OUB_SET_NVMD_DATA			36	/* 0x024 */
+#define OPC_OUB_DEVICE_HANDLE_REMOVAL		37	/* 0x025 */
+#define OPC_OUB_SET_DEVICE_STATE		38	/* 0x026 */
+#define OPC_OUB_GET_DEVICE_STATE		39	/* 0x027 */
+#define OPC_OUB_SET_DEV_INFO			40	/* 0x028 */
+#define OPC_OUB_SAS_RE_INITIALIZE		41	/* 0x029 */
+
+/* for phy start*/
+#define SPINHOLD_DISABLE		(0x00 << 14)
+#define SPINHOLD_ENABLE			(0x01 << 14)
+#define LINKMODE_SAS			(0x01 << 12)
+#define LINKMODE_DSATA			(0x02 << 12)
+#define LINKMODE_AUTO			(0x03 << 12)
+#define LINKRATE_15			(0x01 << 8)
+#define LINKRATE_30			(0x02 << 8)
+#define LINKRATE_60			(0x04 << 8)
+
+struct mpi_msg_hdr{
+	__le32	header;	/* Bits [11:0]  - Message operation code */
+	/* Bits [15:12] - Message Category */
+	/* Bits [21:16] - Outboundqueue ID for the
+	operation completion message */
+	/* Bits [23:22] - Reserved */
+	/* Bits [28:24] - Buffer Count, indicates how
+	many buffer are allocated for the massage */
+	/* Bits [30:29] - Reserved */
+	/* Bits [31] - Message Valid bit */
+} __attribute__((packed, aligned(4)));
+
+
+/*
+ * brief the data structure of PHY Start Command
+ * use to describe enable the phy (64 bytes)
+ */
+struct phy_start_req {
+	__le32	tag;
+	__le32	ase_sh_lm_slr_phyid;
+	struct sas_identify_frame sas_identify;
+	u32	reserved[5];
+} __attribute__((packed, aligned(4)));
+
+
+/*
+ * brief the data structure of PHY Start Command
+ * use to disable the phy (64 bytes)
+ */
+struct phy_stop_req {
+	__le32	tag;
+	__le32	phy_id;
+	u32	reserved[13];
+} __attribute__((packed, aligned(4)));
+
+
+/* set device bits fis - device to host */
+struct  set_dev_bits_fis {
+	u8	fis_type;	/* 0xA1*/
+	u8	n_i_pmport;
+	/* b7 : n Bit. Notification bit. If set device needs attention. */
+	/* b6 : i Bit. Interrupt Bit */
+	/* b5-b4: reserved2 */
+	/* b3-b0: PM Port */
+	u8 	status;
+	u8	error;
+	u32	_r_a;
+} __attribute__ ((packed));
+/* PIO setup FIS - device to host */
+struct  pio_setup_fis {
+	u8	fis_type;	/* 0x5f */
+	u8	i_d_pmPort;
+	/* b7 : reserved */
+	/* b6 : i bit. Interrupt bit */
+	/* b5 : d bit. data transfer direction. set to 1 for device to host
+	xfer */
+	/* b4 : reserved */
+	/* b3-b0: PM Port */
+	u8	status;
+	u8	error;
+	u8	lbal;
+	u8	lbam;
+	u8	lbah;
+	u8	device;
+	u8	lbal_exp;
+	u8	lbam_exp;
+	u8	lbah_exp;
+	u8	_r_a;
+	u8	sector_count;
+	u8	sector_count_exp;
+	u8	_r_b;
+	u8	e_status;
+	u8	_r_c[2];
+	u8	transfer_count;
+} __attribute__ ((packed));
+
+/*
+ * brief the data structure of SATA Completion Response
+ * use to discribe the sata task response (64 bytes)
+ */
+struct sata_completion_resp {
+	__le32	tag;
+	__le32	status;
+	__le32	param;
+	u32	sata_resp[12];
+} __attribute__((packed, aligned(4)));
+
+
+/*
+ * brief the data structure of SAS HW Event Notification
+ * use to alert the host about the hardware event(64 bytes)
+ */
+struct hw_event_resp {
+	__le32	lr_evt_status_phyid_portid;
+	__le32	evt_param;
+	__le32	npip_portstate;
+	struct sas_identify_frame	sas_identify;
+	struct dev_to_host_fis	sata_fis;
+} __attribute__((packed, aligned(4)));
+
+
+/*
+ * brief the data structure of  REGISTER DEVICE Command
+ * use to describe MPI REGISTER DEVICE Command (64 bytes)
+ */
+
+struct reg_dev_req {
+	__le32	tag;
+	__le32	phyid_portid;
+	__le32	dtype_dlr_retry;
+	__le32	firstburstsize_ITNexustimeout;
+	u32	sas_addr_hi;
+	u32	sas_addr_low;
+	__le32	upper_device_id;
+	u32	reserved[8];
+} __attribute__((packed, aligned(4)));
+
+
+/*
+ * brief the data structure of  DEREGISTER DEVICE Command
+ * use to request spc to remove all internal resources associated
+ * with the device id (64 bytes)
+ */
+
+struct dereg_dev_req {
+	__le32	tag;
+	__le32	device_id;
+	u32	reserved[13];
+} __attribute__((packed, aligned(4)));
+
+
+/*
+ * brief the data structure of DEVICE_REGISTRATION Response
+ * use to notify the completion of the device registration  (64 bytes)
+ */
+
+struct dev_reg_resp {
+	__le32	tag;
+	__le32	status;
+	__le32	device_id;
+	u32	reserved[12];
+} __attribute__((packed, aligned(4)));
+
+
+/*
+ * brief the data structure of Local PHY Control Command
+ * use to issue PHY CONTROL to local phy (64 bytes)
+ */
+struct local_phy_ctl_req {
+	__le32	tag;
+	__le32	phyop_phyid;
+	u32	reserved1[13];
+} __attribute__((packed, aligned(4)));
+
+
+/**
+ * brief the data structure of Local Phy Control Response
+ * use to describe MPI Local Phy Control Response (64 bytes)
+ */
+struct local_phy_ctl_resp {
+	__le32	tag;
+	__le32	phyop_phyid;
+	__le32	status;
+	u32	reserved[12];
+} __attribute__((packed, aligned(4)));
+
+
+#define OP_BITS 0x0000FF00
+#define ID_BITS 0x0000000F
+
+/*
+ * brief the data structure of PORT Control Command
+ * use to control port properties (64 bytes)
+ */
+
+struct port_ctl_req {
+	__le32	tag;
+	__le32	portop_portid;
+	__le32	param0;
+	__le32	param1;
+	u32	reserved1[11];
+} __attribute__((packed, aligned(4)));
+
+
+/*
+ * brief the data structure of HW Event Ack Command
+ * use to acknowledge receive HW event (64 bytes)
+ */
+
+struct hw_event_ack_req {
+	__le32	tag;
+	__le32	sea_phyid_portid;
+	__le32	param0;
+	__le32	param1;
+	u32	reserved1[11];
+} __attribute__((packed, aligned(4)));
+
+
+/*
+ * brief the data structure of SSP Completion Response
+ * use to indicate a SSP Completion  (n bytes)
+ */
+struct ssp_completion_resp {
+	__le32	tag;
+	__le32	status;
+	__le32	param;
+	__le32	ssptag_rescv_rescpad;
+	struct ssp_response_iu  ssp_resp_iu;
+	__le32	residual_count;
+} __attribute__((packed, aligned(4)));
+
+
+#define SSP_RESCV_BIT	0x00010000
+
+/*
+ * brief the data structure of SATA EVNET esponse
+ * use to indicate a SATA Completion  (64 bytes)
+ */
+
+struct sata_event_resp {
+	__le32	tag;
+	__le32	event;
+	__le32	port_id;
+	__le32	device_id;
+	u32	reserved[11];
+} __attribute__((packed, aligned(4)));
+
+/*
+ * brief the data structure of SSP EVNET esponse
+ * use to indicate a SSP Completion  (64 bytes)
+ */
+
+struct ssp_event_resp {
+	__le32	tag;
+	__le32	event;
+	__le32	port_id;
+	__le32	device_id;
+	u32	reserved[11];
+} __attribute__((packed, aligned(4)));
+
+/**
+ * brief the data structure of General Event Notification Response
+ * use to describe MPI General Event Notification Response (64 bytes)
+ */
+struct general_event_resp {
+	__le32	status;
+	__le32	inb_IOMB_payload[14];
+} __attribute__((packed, aligned(4)));
+
+
+#define GENERAL_EVENT_PAYLOAD	14
+#define OPCODE_BITS	0x00000fff
+
+/*
+ * brief the data structure of SMP Request Command
+ * use to describe MPI SMP REQUEST Command (64 bytes)
+ */
+struct smp_req {
+	__le32	tag;
+	__le32	device_id;
+	__le32	len_ip_ir;
+	/* Bits [0]  - Indirect response */
+	/* Bits [1] - Indirect Payload */
+	/* Bits [15:2] - Reserved */
+	/* Bits [23:16] - direct payload Len */
+	/* Bits [31:24] - Reserved */
+	u8	smp_req16[16];
+	union {
+		u8	smp_req[32];
+		struct {
+			__le64 long_req_addr;/* sg dma address, LE */
+			__le32 long_req_size;/* LE */
+			u32	_r_a;
+			__le64 long_resp_addr;/* sg dma address, LE */
+			__le32 long_resp_size;/* LE */
+			u32	_r_b;
+			} long_smp_req;/* sequencer extension */
+	};
+} __attribute__((packed, aligned(4)));
+/*
+ * brief the data structure of SMP Completion Response
+ * use to describe MPI SMP Completion Response (64 bytes)
+ */
+struct smp_completion_resp {
+	__le32	tag;
+	__le32	status;
+	__le32	param;
+	__le32	_r_a[12];
+} __attribute__((packed, aligned(4)));
+
+/*
+ *brief the data structure of SSP SMP SATA Abort Command
+ * use to describe MPI SSP SMP & SATA Abort Command (64 bytes)
+ */
+struct task_abort_req {
+	__le32	tag;
+	__le32	device_id;
+	__le32	tag_to_abort;
+	__le32	abort_all;
+	u32	reserved[11];
+} __attribute__((packed, aligned(4)));
+
+/* These flags used for SSP SMP & SATA Abort */
+#define ABORT_MASK		0x3
+#define ABORT_SINGLE		0x0
+#define ABORT_ALL		0x1
+
+/**
+ * brief the data structure of SSP SATA SMP Abort Response
+ * use to describe SSP SMP & SATA Abort Response ( 64 bytes)
+ */
+struct task_abort_resp {
+	__le32	tag;
+	__le32	status;
+	__le32	scp;
+	u32	reserved[12];
+} __attribute__((packed, aligned(4)));
+
+
+/**
+ * brief the data structure of SAS Diagnostic Start/End Command
+ * use to describe MPI SAS Diagnostic Start/End Command (64 bytes)
+ */
+struct sas_diag_start_end_req {
+	__le32	tag;
+	__le32	operation_phyid;
+	u32	reserved[13];
+} __attribute__((packed, aligned(4)));
+
+
+/**
+ * brief the data structure of SAS Diagnostic Execute Command
+ * use to describe MPI SAS Diagnostic Execute Command (64 bytes)
+ */
+struct sas_diag_execute_req{
+	__le32	tag;
+	__le32	cmdtype_cmddesc_phyid;
+	__le32	pat1_pat2;
+	__le32	threshold;
+	__le32	codepat_errmsk;
+	__le32	pmon;
+	__le32	pERF1CTL;
+	u32	reserved[8];
+} __attribute__((packed, aligned(4)));
+
+
+#define SAS_DIAG_PARAM_BYTES 24
+
+/*
+ * brief the data structure of Set Device State Command
+ * use to describe MPI Set Device State Command (64 bytes)
+ */
+struct set_dev_state_req {
+	__le32	tag;
+	__le32	device_id;
+	__le32	nds;
+	u32	reserved[12];
+} __attribute__((packed, aligned(4)));
+
+/*
+ * brief the data structure of sas_re_initialization
+ */
+struct sas_re_initialization_req {
+
+	__le32	tag;
+	__le32	SSAHOLT;/* bit29-set max port;
+			** bit28-set open reject cmd retries.
+			** bit27-set open reject data retries.
+			** bit26-set open reject option, remap:1 or not:0.
+			** bit25-set sata head of line time out.
+			*/
+	__le32 reserved_maxPorts;
+	__le32 open_reject_cmdretries_data_retries;/* cmd retries: 31-bit16;
+						    * data retries: bit15-bit0.
+						    */
+	__le32	sata_hol_tmo;
+	u32	reserved1[10];
+} __attribute__((packed, aligned(4)));
+
+/*
+ * brief the data structure of SATA Start Command
+ * use to describe MPI SATA IO Start Command (64 bytes)
+ */
+
+struct sata_start_req {
+	__le32	tag;
+	__le32	device_id;
+	__le32	data_len;
+	__le32	ncqtag_atap_dir_m;
+	struct host_to_dev_fis	sata_fis;
+	u32	reserved1;
+	u32	reserved2;
+	u32	addr_low;
+	u32	addr_high;
+	__le32	len;
+	__le32	esgl;
+} __attribute__((packed, aligned(4)));
+
+/**
+ * brief the data structure of SSP INI TM Start Command
+ * use to describe MPI SSP INI TM Start Command (64 bytes)
+ */
+struct ssp_ini_tm_start_req {
+	__le32	tag;
+	__le32	device_id;
+	__le32	relate_tag;
+	__le32	tmf;
+	u8	lun[8];
+	__le32	ds_ads_m;
+	u32	reserved[8];
+} __attribute__((packed, aligned(4)));
+
+
+struct ssp_info_unit {
+	u8	lun[8];/* SCSI Logical Unit Number */
+	u8	reserved1;/* reserved */
+	u8	efb_prio_attr;
+	/* B7   : enabledFirstBurst */
+	/* B6-3 : taskPriority */
+	/* B2-0 : taskAttribute */
+	u8	reserved2;	/* reserved */
+	u8	additional_cdb_len;
+	/* B7-2 : additional_cdb_len */
+	/* B1-0 : reserved */
+	u8	cdb[16];/* The SCSI CDB up to 16 bytes length */
+} __attribute__((packed, aligned(4)));
+
+
+/**
+ * brief the data structure of SSP INI IO Start Command
+ * use to describe MPI SSP INI IO Start Command (64 bytes)
+ */
+struct ssp_ini_io_start_req {
+	__le32	tag;
+	__le32	device_id;
+	__le32	data_len;
+	__le32	dir_m_tlr;
+	struct ssp_info_unit	ssp_iu;
+	__le32	addr_low;
+	__le32	addr_high;
+	__le32	len;
+	__le32	esgl;
+} __attribute__((packed, aligned(4)));
+
+
+/**
+ * brief the data structure of Firmware download
+ * use to describe MPI FW DOWNLOAD Command (64 bytes)
+ */
+struct fw_flash_Update_req {
+	__le32	tag;
+	__le32	cur_image_offset;
+	__le32	cur_image_len;
+	__le32	total_image_len;
+	u32	reserved0[7];
+	__le32	sgl_addr_lo;
+	__le32	sgl_addr_hi;
+	__le32	len;
+	__le32	ext_reserved;
+} __attribute__((packed, aligned(4)));
+
+
+#define FWFLASH_IOMB_RESERVED_LEN 0x07
+/**
+ * brief the data structure of FW_FLASH_UPDATE Response
+ * use to describe MPI FW_FLASH_UPDATE Response (64 bytes)
+ *
+ */
+struct fw_flash_Update_resp {
+	dma_addr_t	tag;
+	__le32	status;
+	u32	reserved[13];
+} __attribute__((packed, aligned(4)));
+
+
+/**
+ * brief the data structure of Get NVM Data Command
+ * use to get data from NVM in HBA(64 bytes)
+ */
+struct get_nvm_data_req {
+	__le32	tag;
+	__le32	len_ir_vpdd;
+	__le32	vpd_offset;
+	u32	reserved[8];
+	__le32	resp_addr_lo;
+	__le32	resp_addr_hi;
+	__le32	resp_len;
+	u32	reserved1;
+} __attribute__((packed, aligned(4)));
+
+
+struct set_nvm_data_req {
+	__le32	tag;
+	__le32	len_ir_vpdd;
+	__le32	vpd_offset;
+	u32	reserved[8];
+	__le32	resp_addr_lo;
+	__le32	resp_addr_hi;
+	__le32	resp_len;
+	u32	reserved1;
+} __attribute__((packed, aligned(4)));
+
+
+#define TWI_DEVICE	0x0
+#define C_SEEPROM	0x1
+#define VPD_FLASH	0x4
+#define AAP1_RDUMP	0x5
+#define IOP_RDUMP	0x6
+#define EXPAN_ROM	0x7
+
+#define IPMode		0x80000000
+#define NVMD_TYPE	0x0000000F
+#define NVMD_STAT	0x0000FFFF
+#define NVMD_LEN	0xFF000000
+/**
+ * brief the data structure of Get NVMD Data Response
+ * use to describe MPI Get NVMD Data Response (64 bytes)
+ */
+struct get_nvm_data_resp {
+	__le32		tag;
+	__le32		ir_tda_bn_dps_das_nvm;
+	__le32		dlen_status;
+	__le32		nvm_data[12];
+} __attribute__((packed, aligned(4)));
+
+
+/**
+ * brief the data structure of SAS Diagnostic Start/End Response
+ * use to describe MPI SAS Diagnostic Start/End Response (64 bytes)
+ *
+ */
+struct sas_diag_start_end_resp {
+	__le32		tag;
+	__le32		status;
+	u32		reserved[13];
+} __attribute__((packed, aligned(4)));
+
+
+/**
+ * brief the data structure of SAS Diagnostic Execute Response
+ * use to describe MPI SAS Diagnostic Execute Response (64 bytes)
+ *
+ */
+struct sas_diag_execute_resp {
+	__le32		tag;
+	__le32		cmdtype_cmddesc_phyid;
+	__le32		Status;
+	__le32		ReportData;
+	u32		reserved[11];
+} __attribute__((packed, aligned(4)));
+
+
+/**
+ * brief the data structure of Set Device State Response
+ * use to describe MPI Set Device State Response (64 bytes)
+ *
+ */
+struct set_dev_state_resp {
+	__le32		tag;
+	__le32		status;
+	__le32		device_id;
+	__le32		pds_nds;
+	u32		reserved[11];
+} __attribute__((packed, aligned(4)));
+
+
+#define NDS_BITS 0x0F
+#define PDS_BITS 0xF0
+
+/*
+ * HW Events type
+ */
+
+#define HW_EVENT_RESET_START			0x01
+#define HW_EVENT_CHIP_RESET_COMPLETE		0x02
+#define HW_EVENT_PHY_STOP_STATUS		0x03
+#define HW_EVENT_SAS_PHY_UP			0x04
+#define HW_EVENT_SATA_PHY_UP			0x05
+#define HW_EVENT_SATA_SPINUP_HOLD		0x06
+#define HW_EVENT_PHY_DOWN			0x07
+#define HW_EVENT_PORT_INVALID			0x08
+#define HW_EVENT_BROADCAST_CHANGE		0x09
+#define HW_EVENT_PHY_ERROR			0x0A
+#define HW_EVENT_BROADCAST_SES			0x0B
+#define HW_EVENT_INBOUND_CRC_ERROR		0x0C
+#define HW_EVENT_HARD_RESET_RECEIVED		0x0D
+#define HW_EVENT_MALFUNCTION			0x0E
+#define HW_EVENT_ID_FRAME_TIMEOUT		0x0F
+#define HW_EVENT_BROADCAST_EXP			0x10
+#define HW_EVENT_PHY_START_STATUS		0x11
+#define HW_EVENT_LINK_ERR_INVALID_DWORD		0x12
+#define HW_EVENT_LINK_ERR_DISPARITY_ERROR	0x13
+#define HW_EVENT_LINK_ERR_CODE_VIOLATION	0x14
+#define HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH	0x15
+#define HW_EVENT_LINK_ERR_PHY_RESET_FAILED	0x16
+#define HW_EVENT_PORT_RECOVERY_TIMER_TMO	0x17
+#define HW_EVENT_PORT_RECOVER			0x18
+#define HW_EVENT_PORT_RESET_TIMER_TMO		0x19
+#define HW_EVENT_PORT_RESET_COMPLETE		0x20
+#define EVENT_BROADCAST_ASYNCH_EVENT		0x21
+
+/* port state */
+#define PORT_NOT_ESTABLISHED			0x00
+#define PORT_VALID				0x01
+#define PORT_LOSTCOMM				0x02
+#define PORT_IN_RESET				0x04
+#define PORT_INVALID				0x08
+
+/*
+ * SSP/SMP/SATA IO Completion Status values
+ */
+
+#define IO_SUCCESS				0x00
+#define IO_ABORTED				0x01
+#define IO_OVERFLOW				0x02
+#define IO_UNDERFLOW				0x03
+#define IO_FAILED				0x04
+#define IO_ABORT_RESET				0x05
+#define IO_NOT_VALID				0x06
+#define IO_NO_DEVICE				0x07
+#define IO_ILLEGAL_PARAMETER			0x08
+#define IO_LINK_FAILURE				0x09
+#define IO_PROG_ERROR				0x0A
+#define IO_EDC_IN_ERROR				0x0B
+#define IO_EDC_OUT_ERROR			0x0C
+#define IO_ERROR_HW_TIMEOUT			0x0D
+#define IO_XFER_ERROR_BREAK			0x0E
+#define IO_XFER_ERROR_PHY_NOT_READY		0x0F
+#define IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED	0x10
+#define IO_OPEN_CNX_ERROR_ZONE_VIOLATION		0x11
+#define IO_OPEN_CNX_ERROR_BREAK				0x12
+#define IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS			0x13
+#define IO_OPEN_CNX_ERROR_BAD_DESTINATION		0x14
+#define IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED	0x15
+#define IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY		0x16
+#define IO_OPEN_CNX_ERROR_WRONG_DESTINATION		0x17
+#define IO_OPEN_CNX_ERROR_UNKNOWN_ERROR			0x18
+#define IO_XFER_ERROR_NAK_RECEIVED			0x19
+#define IO_XFER_ERROR_ACK_NAK_TIMEOUT			0x1A
+#define IO_XFER_ERROR_PEER_ABORTED			0x1B
+#define IO_XFER_ERROR_RX_FRAME				0x1C
+#define IO_XFER_ERROR_DMA				0x1D
+#define IO_XFER_ERROR_CREDIT_TIMEOUT			0x1E
+#define IO_XFER_ERROR_SATA_LINK_TIMEOUT			0x1F
+#define IO_XFER_ERROR_SATA				0x20
+#define IO_XFER_ERROR_ABORTED_DUE_TO_SRST		0x22
+#define IO_XFER_ERROR_REJECTED_NCQ_MODE			0x21
+#define IO_XFER_ERROR_ABORTED_NCQ_MODE			0x23
+#define IO_XFER_OPEN_RETRY_TIMEOUT			0x24
+#define IO_XFER_SMP_RESP_CONNECTION_ERROR		0x25
+#define IO_XFER_ERROR_UNEXPECTED_PHASE			0x26
+#define IO_XFER_ERROR_XFER_RDY_OVERRUN			0x27
+#define IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED		0x28
+
+#define IO_XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT		0x30
+#define IO_XFER_ERROR_CMD_ISSUE_BREAK_BEFORE_ACK_NAK	0x31
+#define IO_XFER_ERROR_CMD_ISSUE_PHY_DOWN_BEFORE_ACK_NAK	0x32
+
+#define IO_XFER_ERROR_OFFSET_MISMATCH			0x34
+#define IO_XFER_ERROR_XFER_ZERO_DATA_LEN		0x35
+#define IO_XFER_CMD_FRAME_ISSUED			0x36
+#define IO_ERROR_INTERNAL_SMP_RESOURCE			0x37
+#define IO_PORT_IN_RESET				0x38
+#define IO_DS_NON_OPERATIONAL				0x39
+#define IO_DS_IN_RECOVERY				0x3A
+#define IO_TM_TAG_NOT_FOUND				0x3B
+#define IO_XFER_PIO_SETUP_ERROR				0x3C
+#define IO_SSP_EXT_IU_ZERO_LEN_ERROR			0x3D
+#define IO_DS_IN_ERROR					0x3E
+#define IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY		0x3F
+#define IO_ABORT_IN_PROGRESS				0x40
+#define IO_ABORT_DELAYED				0x41
+#define IO_INVALID_LENGTH				0x42
+
+/* WARNING: This error code must always be the last number.
+ * If you add error code, modify this code also
+ * It is used as an index
+ */
+#define IO_ERROR_UNKNOWN_GENERIC			0x43
+
+/* MSGU CONFIGURATION  TABLE*/
+
+#define SPC_MSGU_CFG_TABLE_UPDATE		0x01/* Inbound doorbell bit0 */
+#define SPC_MSGU_CFG_TABLE_RESET		0x02/* Inbound doorbell bit1 */
+#define SPC_MSGU_CFG_TABLE_FREEZE		0x04/* Inbound doorbell bit2 */
+#define SPC_MSGU_CFG_TABLE_UNFREEZE		0x08/* Inbound doorbell bit4 */
+#define MSGU_IBDB_SET				0x04
+#define MSGU_HOST_INT_STATUS			0x08
+#define MSGU_HOST_INT_MASK			0x0C
+#define MSGU_IOPIB_INT_STATUS			0x18
+#define MSGU_IOPIB_INT_MASK			0x1C
+#define MSGU_IBDB_CLEAR				0x20/* RevB - Host not use */
+#define MSGU_MSGU_CONTROL			0x24
+#define MSGU_ODR				0x3C/* RevB */
+#define MSGU_ODCR				0x40/* RevB */
+#define MSGU_SCRATCH_PAD_0			0x44
+#define MSGU_SCRATCH_PAD_1			0x48
+#define MSGU_SCRATCH_PAD_2			0x4C
+#define MSGU_SCRATCH_PAD_3			0x50
+#define MSGU_HOST_SCRATCH_PAD_0			0x54
+#define MSGU_HOST_SCRATCH_PAD_1			0x58
+#define MSGU_HOST_SCRATCH_PAD_2			0x5C
+#define MSGU_HOST_SCRATCH_PAD_3			0x60
+#define MSGU_HOST_SCRATCH_PAD_4			0x64
+#define MSGU_HOST_SCRATCH_PAD_5			0x68
+#define MSGU_HOST_SCRATCH_PAD_6			0x6C
+#define MSGU_HOST_SCRATCH_PAD_7			0x70
+#define MSGU_ODMR				0x74/* RevB */
+
+/* bit definition for ODMR register */
+#define ODMR_MASK_ALL				0xFFFFFFFF/* mask all
+					interrupt vector */
+#define ODMR_CLEAR_ALL				0/* clear all
+					interrupt vector */
+/* bit definition for ODCR register */
+#define ODCR_CLEAR_ALL		0xFFFFFFFF   /* mask all
+					interrupt vector*/
+/* MSIX Interupts */
+#define MSIX_TABLE_OFFSET		0x2000
+#define MSIX_TABLE_ELEMENT_SIZE		0x10
+#define MSIX_INTERRUPT_CONTROL_OFFSET	0xC
+#define MSIX_TABLE_BASE	  (MSIX_TABLE_OFFSET + MSIX_INTERRUPT_CONTROL_OFFSET)
+#define MSIX_INTERRUPT_DISABLE		0x1
+#define MSIX_INTERRUPT_ENABLE		0x0
+
+
+/* state definition for Scratch Pad1 register */
+#define SCRATCH_PAD1_POR		0x00  /* power on reset state */
+#define SCRATCH_PAD1_SFR		0x01  /* soft reset state */
+#define SCRATCH_PAD1_ERR		0x02  /* error state */
+#define SCRATCH_PAD1_RDY		0x03  /* ready state */
+#define SCRATCH_PAD1_RST		0x04  /* soft reset toggle flag */
+#define SCRATCH_PAD1_AAP1RDY_RST	0x08  /* AAP1 ready for soft reset */
+#define SCRATCH_PAD1_STATE_MASK		0xFFFFFFF0   /* ScratchPad1
+ Mask, bit1-0 State, bit2 Soft Reset, bit3 FW RDY for Soft Reset */
+#define SCRATCH_PAD1_RESERVED		0x000003F8   /* Scratch Pad1
+ Reserved bit 3 to 9 */
+
+ /* state definition for Scratch Pad2 register */
+#define SCRATCH_PAD2_POR		0x00  /* power on state */
+#define SCRATCH_PAD2_SFR		0x01  /* soft reset state */
+#define SCRATCH_PAD2_ERR		0x02  /* error state */
+#define SCRATCH_PAD2_RDY		0x03  /* ready state */
+#define SCRATCH_PAD2_FWRDY_RST		0x04  /* FW ready for soft reset flag*/
+#define SCRATCH_PAD2_IOPRDY_RST		0x08  /* IOP ready for soft reset */
+#define SCRATCH_PAD2_STATE_MASK		0xFFFFFFF4 /* ScratchPad 2
+ Mask, bit1-0 State */
+#define SCRATCH_PAD2_RESERVED		0x000003FC   /* Scratch Pad1
+ Reserved bit 2 to 9 */
+
+#define SCRATCH_PAD_ERROR_MASK		0xFFFFFC00   /* Error mask bits */
+#define SCRATCH_PAD_STATE_MASK		0x00000003   /* State Mask bits */
+
+/* main configuration offset - byte offset */
+#define MAIN_SIGNATURE_OFFSET		0x00/* DWORD 0x00 */
+#define MAIN_INTERFACE_REVISION		0x04/* DWORD 0x01 */
+#define MAIN_FW_REVISION		0x08/* DWORD 0x02 */
+#define MAIN_MAX_OUTSTANDING_IO_OFFSET	0x0C/* DWORD 0x03 */
+#define MAIN_MAX_SGL_OFFSET		0x10/* DWORD 0x04 */
+#define MAIN_CNTRL_CAP_OFFSET		0x14/* DWORD 0x05 */
+#define MAIN_GST_OFFSET			0x18/* DWORD 0x06 */
+#define MAIN_IBQ_OFFSET			0x1C/* DWORD 0x07 */
+#define MAIN_OBQ_OFFSET			0x20/* DWORD 0x08 */
+#define MAIN_IQNPPD_HPPD_OFFSET		0x24/* DWORD 0x09 */
+#define MAIN_OB_HW_EVENT_PID03_OFFSET	0x28/* DWORD 0x0A */
+#define MAIN_OB_HW_EVENT_PID47_OFFSET	0x2C/* DWORD 0x0B */
+#define MAIN_OB_NCQ_EVENT_PID03_OFFSET	0x30/* DWORD 0x0C */
+#define MAIN_OB_NCQ_EVENT_PID47_OFFSET	0x34/* DWORD 0x0D */
+#define MAIN_TITNX_EVENT_PID03_OFFSET	0x38/* DWORD 0x0E */
+#define MAIN_TITNX_EVENT_PID47_OFFSET	0x3C/* DWORD 0x0F */
+#define MAIN_OB_SSP_EVENT_PID03_OFFSET	0x40/* DWORD 0x10 */
+#define MAIN_OB_SSP_EVENT_PID47_OFFSET	0x44/* DWORD 0x11 */
+#define MAIN_OB_SMP_EVENT_PID03_OFFSET	0x48/* DWORD 0x12 */
+#define MAIN_OB_SMP_EVENT_PID47_OFFSET	0x4C/* DWORD 0x13 */
+#define MAIN_EVENT_LOG_ADDR_HI		0x50/* DWORD 0x14 */
+#define MAIN_EVENT_LOG_ADDR_LO		0x54/* DWORD 0x15 */
+#define MAIN_EVENT_LOG_BUFF_SIZE	0x58/* DWORD 0x16 */
+#define MAIN_EVENT_LOG_OPTION		0x5C/* DWORD 0x17 */
+#define MAIN_IOP_EVENT_LOG_ADDR_HI	0x60/* DWORD 0x18 */
+#define MAIN_IOP_EVENT_LOG_ADDR_LO	0x64/* DWORD 0x19 */
+#define MAIN_IOP_EVENT_LOG_BUFF_SIZE	0x68/* DWORD 0x1A */
+#define MAIN_IOP_EVENT_LOG_OPTION	0x6C/* DWORD 0x1B */
+#define MAIN_FATAL_ERROR_INTERRUPT	0x70/* DWORD 0x1C */
+#define MAIN_FATAL_ERROR_RDUMP0_OFFSET	0x74/* DWORD 0x1D */
+#define MAIN_FATAL_ERROR_RDUMP0_LENGTH	0x78/* DWORD 0x1E */
+#define MAIN_FATAL_ERROR_RDUMP1_OFFSET	0x7C/* DWORD 0x1F */
+#define MAIN_FATAL_ERROR_RDUMP1_LENGTH	0x80/* DWORD 0x20 */
+#define MAIN_HDA_FLAGS_OFFSET		0x84/* DWORD 0x21 */
+#define MAIN_ANALOG_SETUP_OFFSET	0x88/* DWORD 0x22 */
+
+/* Gereral Status Table offset - byte offset */
+#define GST_GSTLEN_MPIS_OFFSET		0x00
+#define GST_IQ_FREEZE_STATE0_OFFSET	0x04
+#define GST_IQ_FREEZE_STATE1_OFFSET	0x08
+#define GST_MSGUTCNT_OFFSET		0x0C
+#define GST_IOPTCNT_OFFSET		0x10
+#define GST_PHYSTATE_OFFSET		0x18
+#define GST_PHYSTATE0_OFFSET		0x18
+#define GST_PHYSTATE1_OFFSET		0x1C
+#define GST_PHYSTATE2_OFFSET		0x20
+#define GST_PHYSTATE3_OFFSET		0x24
+#define GST_PHYSTATE4_OFFSET		0x28
+#define GST_PHYSTATE5_OFFSET		0x2C
+#define GST_PHYSTATE6_OFFSET		0x30
+#define GST_PHYSTATE7_OFFSET		0x34
+#define GST_RERRINFO_OFFSET		0x44
+
+/* General Status Table - MPI state */
+#define GST_MPI_STATE_UNINIT		0x00
+#define GST_MPI_STATE_INIT		0x01
+#define GST_MPI_STATE_TERMINATION	0x02
+#define GST_MPI_STATE_ERROR		0x03
+#define GST_MPI_STATE_MASK		0x07
+
+#define MBIC_NMI_ENABLE_VPE0_IOP	0x000418
+#define MBIC_NMI_ENABLE_VPE0_AAP1	0x000418
+/* PCIE registers - BAR2(0x18), BAR1(win) 0x010000 */
+#define PCIE_EVENT_INTERRUPT_ENABLE	0x003040
+#define PCIE_EVENT_INTERRUPT		0x003044
+#define PCIE_ERROR_INTERRUPT_ENABLE	0x003048
+#define PCIE_ERROR_INTERRUPT		0x00304C
+/* signature defintion for host scratch pad0 register */
+#define SPC_SOFT_RESET_SIGNATURE	0x252acbcd
+/* Signature for Soft Reset */
+
+/* SPC Reset register - BAR4(0x20), BAR2(win) (need dynamic mapping) */
+#define SPC_REG_RESET			0x000000/* reset register */
+
+/* bit difination for SPC_RESET register */
+#define   SPC_REG_RESET_OSSP		0x00000001
+#define   SPC_REG_RESET_RAAE		0x00000002
+#define   SPC_REG_RESET_PCS_SPBC	0x00000004
+#define   SPC_REG_RESET_PCS_IOP_SS	0x00000008
+#define   SPC_REG_RESET_PCS_AAP1_SS	0x00000010
+#define   SPC_REG_RESET_PCS_AAP2_SS	0x00000020
+#define   SPC_REG_RESET_PCS_LM		0x00000040
+#define   SPC_REG_RESET_PCS		0x00000080
+#define   SPC_REG_RESET_GSM		0x00000100
+#define   SPC_REG_RESET_DDR2		0x00010000
+#define   SPC_REG_RESET_BDMA_CORE	0x00020000
+#define   SPC_REG_RESET_BDMA_SXCBI	0x00040000
+#define   SPC_REG_RESET_PCIE_AL_SXCBI	0x00080000
+#define   SPC_REG_RESET_PCIE_PWR	0x00100000
+#define   SPC_REG_RESET_PCIE_SFT	0x00200000
+#define   SPC_REG_RESET_PCS_SXCBI	0x00400000
+#define   SPC_REG_RESET_LMS_SXCBI	0x00800000
+#define   SPC_REG_RESET_PMIC_SXCBI	0x01000000
+#define   SPC_REG_RESET_PMIC_CORE	0x02000000
+#define   SPC_REG_RESET_PCIE_PC_SXCBI	0x04000000
+#define   SPC_REG_RESET_DEVICE		0x80000000
+
+/* registers for BAR Shifting - BAR2(0x18), BAR1(win) */
+#define SPC_IBW_AXI_TRANSLATION_LOW	0x003258
+
+#define MBIC_AAP1_ADDR_BASE		0x060000
+#define MBIC_IOP_ADDR_BASE		0x070000
+#define GSM_ADDR_BASE			0x0700000
+/* Dynamic map through Bar4 - 0x00700000 */
+#define GSM_CONFIG_RESET		0x00000000
+#define RAM_ECC_DB_ERR			0x00000018
+#define GSM_READ_ADDR_PARITY_INDIC	0x00000058
+#define GSM_WRITE_ADDR_PARITY_INDIC	0x00000060
+#define GSM_WRITE_DATA_PARITY_INDIC	0x00000068
+#define GSM_READ_ADDR_PARITY_CHECK	0x00000038
+#define GSM_WRITE_ADDR_PARITY_CHECK	0x00000040
+#define GSM_WRITE_DATA_PARITY_CHECK	0x00000048
+
+#define RB6_ACCESS_REG			0x6A0000
+#define HDAC_EXEC_CMD			0x0002
+#define HDA_C_PA			0xcb
+#define HDA_SEQ_ID_BITS			0x00ff0000
+#define HDA_GSM_OFFSET_BITS		0x00FFFFFF
+#define MBIC_AAP1_ADDR_BASE		0x060000
+#define MBIC_IOP_ADDR_BASE		0x070000
+#define GSM_ADDR_BASE			0x0700000
+#define SPC_TOP_LEVEL_ADDR_BASE		0x000000
+#define GSM_CONFIG_RESET_VALUE          0x00003b00
+#define GPIO_ADDR_BASE                  0x00090000
+#define GPIO_GPIO_0_0UTPUT_CTL_OFFSET   0x0000010c
+
+/* RB6 offset */
+#define SPC_RB6_OFFSET			0x80C0
+/* Magic number of  soft reset for RB6 */
+#define RB6_MAGIC_NUMBER_RST		0x1234
+
+/* Device Register status */
+#define DEVREG_SUCCESS					0x00
+#define DEVREG_FAILURE_OUT_OF_RESOURCE			0x01
+#define DEVREG_FAILURE_DEVICE_ALREADY_REGISTERED	0x02
+#define DEVREG_FAILURE_INVALID_PHY_ID			0x03
+#define DEVREG_FAILURE_PHY_ID_ALREADY_REGISTERED	0x04
+#define DEVREG_FAILURE_PORT_ID_OUT_OF_RANGE		0x05
+#define DEVREG_FAILURE_PORT_NOT_VALID_STATE		0x06
+#define DEVREG_FAILURE_DEVICE_TYPE_NOT_VALID		0x07
+
+#endif
+
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
new file mode 100644
index 0000000..42ebe72
--- /dev/null
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -0,0 +1,891 @@
+/*
+ * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver
+ *
+ * Copyright (c) 2008-2009 USI Co., Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+#include "pm8001_sas.h"
+#include "pm8001_chips.h"
+
+static struct scsi_transport_template *pm8001_stt;
+
+static const struct pm8001_chip_info pm8001_chips[] = {
+	[chip_8001] = {  8, &pm8001_8001_dispatch,},
+};
+static int pm8001_id;
+
+LIST_HEAD(hba_list);
+
+/**
+ * The main structure which LLDD must register for scsi core.
+ */
+static struct scsi_host_template pm8001_sht = {
+	.module			= THIS_MODULE,
+	.name			= DRV_NAME,
+	.queuecommand		= sas_queuecommand,
+	.target_alloc		= sas_target_alloc,
+	.slave_configure	= pm8001_slave_configure,
+	.slave_destroy		= sas_slave_destroy,
+	.scan_finished		= pm8001_scan_finished,
+	.scan_start		= pm8001_scan_start,
+	.change_queue_depth	= sas_change_queue_depth,
+	.change_queue_type	= sas_change_queue_type,
+	.bios_param		= sas_bios_param,
+	.can_queue		= 1,
+	.cmd_per_lun		= 1,
+	.this_id		= -1,
+	.sg_tablesize		= SG_ALL,
+	.max_sectors		= SCSI_DEFAULT_MAX_SECTORS,
+	.use_clustering		= ENABLE_CLUSTERING,
+	.eh_device_reset_handler = sas_eh_device_reset_handler,
+	.eh_bus_reset_handler	= sas_eh_bus_reset_handler,
+	.slave_alloc		= pm8001_slave_alloc,
+	.target_destroy		= sas_target_destroy,
+	.ioctl			= sas_ioctl,
+	.shost_attrs		= pm8001_host_attrs,
+};
+
+/**
+ * Sas layer call this function to execute specific task.
+ */
+static struct sas_domain_function_template pm8001_transport_ops = {
+	.lldd_dev_found		= pm8001_dev_found,
+	.lldd_dev_gone		= pm8001_dev_gone,
+
+	.lldd_execute_task	= pm8001_queue_command,
+	.lldd_control_phy	= pm8001_phy_control,
+
+	.lldd_abort_task	= pm8001_abort_task,
+	.lldd_abort_task_set	= pm8001_abort_task_set,
+	.lldd_clear_aca		= pm8001_clear_aca,
+	.lldd_clear_task_set	= pm8001_clear_task_set,
+	.lldd_I_T_nexus_reset   = pm8001_I_T_nexus_reset,
+	.lldd_lu_reset		= pm8001_lu_reset,
+	.lldd_query_task	= pm8001_query_task,
+};
+
+/**
+ *pm8001_phy_init - initiate our adapter phys
+ *@pm8001_ha: our hba structure.
+ *@phy_id: phy id.
+ */
+static void __devinit pm8001_phy_init(struct pm8001_hba_info *pm8001_ha,
+	int phy_id)
+{
+	struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];
+	struct asd_sas_phy *sas_phy = &phy->sas_phy;
+	phy->phy_state = 0;
+	phy->pm8001_ha = pm8001_ha;
+	sas_phy->enabled = (phy_id < pm8001_ha->chip->n_phy) ? 1 : 0;
+	sas_phy->class = SAS;
+	sas_phy->iproto = SAS_PROTOCOL_ALL;
+	sas_phy->tproto = 0;
+	sas_phy->type = PHY_TYPE_PHYSICAL;
+	sas_phy->role = PHY_ROLE_INITIATOR;
+	sas_phy->oob_mode = OOB_NOT_CONNECTED;
+	sas_phy->linkrate = SAS_LINK_RATE_UNKNOWN;
+	sas_phy->id = phy_id;
+	sas_phy->sas_addr = &pm8001_ha->sas_addr[0];
+	sas_phy->frame_rcvd = &phy->frame_rcvd[0];
+	sas_phy->ha = (struct sas_ha_struct *)pm8001_ha->shost->hostdata;
+	sas_phy->lldd_phy = phy;
+}
+
+/**
+ *pm8001_free - free hba
+ *@pm8001_ha:	our hba structure.
+ *
+ */
+static void pm8001_free(struct pm8001_hba_info *pm8001_ha)
+{
+	int i;
+	struct pm8001_wq *wq;
+
+	if (!pm8001_ha)
+		return;
+
+	for (i = 0; i < USI_MAX_MEMCNT; i++) {
+		if (pm8001_ha->memoryMap.region[i].virt_ptr != NULL) {
+			pci_free_consistent(pm8001_ha->pdev,
+				pm8001_ha->memoryMap.region[i].element_size,
+				pm8001_ha->memoryMap.region[i].virt_ptr,
+				pm8001_ha->memoryMap.region[i].phys_addr);
+			}
+	}
+	PM8001_CHIP_DISP->chip_iounmap(pm8001_ha);
+	if (pm8001_ha->shost)
+		scsi_host_put(pm8001_ha->shost);
+	list_for_each_entry(wq, &pm8001_ha->wq_list, entry)
+		cancel_delayed_work(&wq->work_q);
+	kfree(pm8001_ha->tags);
+	kfree(pm8001_ha);
+}
+
+#ifdef PM8001_USE_TASKLET
+static void pm8001_tasklet(unsigned long opaque)
+{
+	struct pm8001_hba_info *pm8001_ha;
+	pm8001_ha = (struct pm8001_hba_info *)opaque;;
+	if (unlikely(!pm8001_ha))
+		BUG_ON(1);
+	PM8001_CHIP_DISP->isr(pm8001_ha);
+}
+#endif
+
+
+ /**
+  * pm8001_interrupt - when HBA originate a interrupt,we should invoke this
+  * dispatcher to handle each case.
+  * @irq: irq number.
+  * @opaque: the passed general host adapter struct
+  */
+static irqreturn_t pm8001_interrupt(int irq, void *opaque)
+{
+	struct pm8001_hba_info *pm8001_ha;
+	irqreturn_t ret = IRQ_HANDLED;
+	struct sas_ha_struct *sha = opaque;
+	pm8001_ha = sha->lldd_ha;
+	if (unlikely(!pm8001_ha))
+		return IRQ_NONE;
+	if (!PM8001_CHIP_DISP->is_our_interupt(pm8001_ha))
+		return IRQ_NONE;
+#ifdef PM8001_USE_TASKLET
+	tasklet_schedule(&pm8001_ha->tasklet);
+#else
+	ret = PM8001_CHIP_DISP->isr(pm8001_ha);
+#endif
+	return ret;
+}
+
+/**
+ * pm8001_alloc - initiate our hba structure and 6 DMAs area.
+ * @pm8001_ha:our hba structure.
+ *
+ */
+static int __devinit pm8001_alloc(struct pm8001_hba_info *pm8001_ha)
+{
+	int i;
+	spin_lock_init(&pm8001_ha->lock);
+	for (i = 0; i < pm8001_ha->chip->n_phy; i++)
+		pm8001_phy_init(pm8001_ha, i);
+
+	pm8001_ha->tags = kzalloc(PM8001_MAX_CCB, GFP_KERNEL);
+	if (!pm8001_ha->tags)
+		goto err_out;
+	/* MPI Memory region 1 for AAP Event Log for fw */
+	pm8001_ha->memoryMap.region[AAP1].num_elements = 1;
+	pm8001_ha->memoryMap.region[AAP1].element_size = PM8001_EVENT_LOG_SIZE;
+	pm8001_ha->memoryMap.region[AAP1].total_len = PM8001_EVENT_LOG_SIZE;
+	pm8001_ha->memoryMap.region[AAP1].alignment = 32;
+
+	/* MPI Memory region 2 for IOP Event Log for fw */
+	pm8001_ha->memoryMap.region[IOP].num_elements = 1;
+	pm8001_ha->memoryMap.region[IOP].element_size = PM8001_EVENT_LOG_SIZE;
+	pm8001_ha->memoryMap.region[IOP].total_len = PM8001_EVENT_LOG_SIZE;
+	pm8001_ha->memoryMap.region[IOP].alignment = 32;
+
+	/* MPI Memory region 3 for consumer Index of inbound queues */
+	pm8001_ha->memoryMap.region[CI].num_elements = 1;
+	pm8001_ha->memoryMap.region[CI].element_size = 4;
+	pm8001_ha->memoryMap.region[CI].total_len = 4;
+	pm8001_ha->memoryMap.region[CI].alignment = 4;
+
+	/* MPI Memory region 4 for producer Index of outbound queues */
+	pm8001_ha->memoryMap.region[PI].num_elements = 1;
+	pm8001_ha->memoryMap.region[PI].element_size = 4;
+	pm8001_ha->memoryMap.region[PI].total_len = 4;
+	pm8001_ha->memoryMap.region[PI].alignment = 4;
+
+	/* MPI Memory region 5 inbound queues */
+	pm8001_ha->memoryMap.region[IB].num_elements = 256;
+	pm8001_ha->memoryMap.region[IB].element_size = 64;
+	pm8001_ha->memoryMap.region[IB].total_len = 256 * 64;
+	pm8001_ha->memoryMap.region[IB].alignment = 64;
+
+	/* MPI Memory region 6 inbound queues */
+	pm8001_ha->memoryMap.region[OB].num_elements = 256;
+	pm8001_ha->memoryMap.region[OB].element_size = 64;
+	pm8001_ha->memoryMap.region[OB].total_len = 256 * 64;
+	pm8001_ha->memoryMap.region[OB].alignment = 64;
+
+	/* Memory region write DMA*/
+	pm8001_ha->memoryMap.region[NVMD].num_elements = 1;
+	pm8001_ha->memoryMap.region[NVMD].element_size = 4096;
+	pm8001_ha->memoryMap.region[NVMD].total_len = 4096;
+	/* Memory region for devices*/
+	pm8001_ha->memoryMap.region[DEV_MEM].num_elements = 1;
+	pm8001_ha->memoryMap.region[DEV_MEM].element_size = PM8001_MAX_DEVICES *
+		sizeof(struct pm8001_device);
+	pm8001_ha->memoryMap.region[DEV_MEM].total_len = PM8001_MAX_DEVICES *
+		sizeof(struct pm8001_device);
+
+	/* Memory region for ccb_info*/
+	pm8001_ha->memoryMap.region[CCB_MEM].num_elements = 1;
+	pm8001_ha->memoryMap.region[CCB_MEM].element_size = PM8001_MAX_CCB *
+		sizeof(struct pm8001_ccb_info);
+	pm8001_ha->memoryMap.region[CCB_MEM].total_len = PM8001_MAX_CCB *
+		sizeof(struct pm8001_ccb_info);
+
+	for (i = 0; i < USI_MAX_MEMCNT; i++) {
+		if (pm8001_mem_alloc(pm8001_ha->pdev,
+			&pm8001_ha->memoryMap.region[i].virt_ptr,
+			&pm8001_ha->memoryMap.region[i].phys_addr,
+			&pm8001_ha->memoryMap.region[i].phys_addr_hi,
+			&pm8001_ha->memoryMap.region[i].phys_addr_lo,
+			pm8001_ha->memoryMap.region[i].total_len,
+			pm8001_ha->memoryMap.region[i].alignment) != 0) {
+				PM8001_FAIL_DBG(pm8001_ha,
+					pm8001_printk("Mem%d alloc failed\n",
+					i));
+				goto err_out;
+		}
+	}
+
+	pm8001_ha->devices = pm8001_ha->memoryMap.region[DEV_MEM].virt_ptr;
+	for (i = 0; i < PM8001_MAX_DEVICES; i++) {
+		pm8001_ha->devices[i].dev_type = NO_DEVICE;
+		pm8001_ha->devices[i].id = i;
+		pm8001_ha->devices[i].device_id = PM8001_MAX_DEVICES;
+		pm8001_ha->devices[i].running_req = 0;
+	}
+	pm8001_ha->ccb_info = pm8001_ha->memoryMap.region[CCB_MEM].virt_ptr;
+	for (i = 0; i < PM8001_MAX_CCB; i++) {
+		pm8001_ha->ccb_info[i].ccb_dma_handle =
+			pm8001_ha->memoryMap.region[CCB_MEM].phys_addr +
+			i * sizeof(struct pm8001_ccb_info);
+		pm8001_ha->ccb_info[i].task = NULL;
+		pm8001_ha->ccb_info[i].ccb_tag = 0xffffffff;
+		pm8001_ha->ccb_info[i].device = NULL;
+		++pm8001_ha->tags_num;
+	}
+	pm8001_ha->flags = PM8001F_INIT_TIME;
+	/* Initialize tags */
+	pm8001_tag_init(pm8001_ha);
+	return 0;
+err_out:
+	return 1;
+}
+
+/**
+ * pm8001_ioremap - remap the pci high physical address to kernal virtual
+ * address so that we can access them.
+ * @pm8001_ha:our hba structure.
+ */
+static int pm8001_ioremap(struct pm8001_hba_info *pm8001_ha)
+{
+	u32 bar;
+	u32 logicalBar = 0;
+	struct pci_dev *pdev;
+
+	pdev = pm8001_ha->pdev;
+	/* map pci mem (PMC pci base 0-3)*/
+	for (bar = 0; bar < 6; bar++) {
+		/*
+		** logical BARs for SPC:
+		** bar 0 and 1 - logical BAR0
+		** bar 2 and 3 - logical BAR1
+		** bar4 - logical BAR2
+		** bar5 - logical BAR3
+		** Skip the appropriate assignments:
+		*/
+		if ((bar == 1) || (bar == 3))
+			continue;
+		if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
+			pm8001_ha->io_mem[logicalBar].membase =
+				pci_resource_start(pdev, bar);
+			pm8001_ha->io_mem[logicalBar].membase &=
+				(u32)PCI_BASE_ADDRESS_MEM_MASK;
+			pm8001_ha->io_mem[logicalBar].memsize =
+				pci_resource_len(pdev, bar);
+			pm8001_ha->io_mem[logicalBar].memvirtaddr =
+				ioremap(pm8001_ha->io_mem[logicalBar].membase,
+				pm8001_ha->io_mem[logicalBar].memsize);
+			PM8001_INIT_DBG(pm8001_ha,
+				pm8001_printk("PCI: bar %d, logicalBar %d "
+				"virt_addr=%lx,len=%d\n", bar, logicalBar,
+				(unsigned long)
+				pm8001_ha->io_mem[logicalBar].memvirtaddr,
+				pm8001_ha->io_mem[logicalBar].memsize));
+		} else {
+			pm8001_ha->io_mem[logicalBar].membase	= 0;
+			pm8001_ha->io_mem[logicalBar].memsize	= 0;
+			pm8001_ha->io_mem[logicalBar].memvirtaddr = 0;
+		}
+		logicalBar++;
+	}
+	return 0;
+}
+
+/**
+ * pm8001_pci_alloc - initialize our ha card structure
+ * @pdev: pci device.
+ * @ent: ent
+ * @shost: scsi host struct which has been initialized before.
+ */
+static struct pm8001_hba_info *__devinit
+pm8001_pci_alloc(struct pci_dev *pdev, u32 chip_id, struct Scsi_Host *shost)
+{
+	struct pm8001_hba_info *pm8001_ha;
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+
+
+	pm8001_ha = sha->lldd_ha;
+	if (!pm8001_ha)
+		return NULL;
+
+	pm8001_ha->pdev = pdev;
+	pm8001_ha->dev = &pdev->dev;
+	pm8001_ha->chip_id = chip_id;
+	pm8001_ha->chip = &pm8001_chips[pm8001_ha->chip_id];
+	pm8001_ha->irq = pdev->irq;
+	pm8001_ha->sas = sha;
+	pm8001_ha->shost = shost;
+	pm8001_ha->id = pm8001_id++;
+	INIT_LIST_HEAD(&pm8001_ha->wq_list);
+	pm8001_ha->logging_level = 0x01;
+	sprintf(pm8001_ha->name, "%s%d", DRV_NAME, pm8001_ha->id);
+#ifdef PM8001_USE_TASKLET
+	tasklet_init(&pm8001_ha->tasklet, pm8001_tasklet,
+		(unsigned long)pm8001_ha);
+#endif
+	pm8001_ioremap(pm8001_ha);
+	if (!pm8001_alloc(pm8001_ha))
+		return pm8001_ha;
+	pm8001_free(pm8001_ha);
+	return NULL;
+}
+
+/**
+ * pci_go_44 - pm8001 specified, its DMA is 44 bit rather than 64 bit
+ * @pdev: pci device.
+ */
+static int pci_go_44(struct pci_dev *pdev)
+{
+	int rc;
+
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(44))) {
+		rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(44));
+		if (rc) {
+			rc = pci_set_consistent_dma_mask(pdev,
+				DMA_BIT_MASK(32));
+			if (rc) {
+				dev_printk(KERN_ERR, &pdev->dev,
+					"44-bit DMA enable failed\n");
+				return rc;
+			}
+		}
+	} else {
+		rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+		if (rc) {
+			dev_printk(KERN_ERR, &pdev->dev,
+				"32-bit DMA enable failed\n");
+			return rc;
+		}
+		rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+		if (rc) {
+			dev_printk(KERN_ERR, &pdev->dev,
+				"32-bit consistent DMA enable failed\n");
+			return rc;
+		}
+	}
+	return rc;
+}
+
+/**
+ * pm8001_prep_sas_ha_init - allocate memory in general hba struct && init them.
+ * @shost: scsi host which has been allocated outside.
+ * @chip_info: our ha struct.
+ */
+static int __devinit pm8001_prep_sas_ha_init(struct Scsi_Host * shost,
+	const struct pm8001_chip_info *chip_info)
+{
+	int phy_nr, port_nr;
+	struct asd_sas_phy **arr_phy;
+	struct asd_sas_port **arr_port;
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+
+	phy_nr = chip_info->n_phy;
+	port_nr = phy_nr;
+	memset(sha, 0x00, sizeof(*sha));
+	arr_phy = kcalloc(phy_nr, sizeof(void *), GFP_KERNEL);
+	if (!arr_phy)
+		goto exit;
+	arr_port = kcalloc(port_nr, sizeof(void *), GFP_KERNEL);
+	if (!arr_port)
+		goto exit_free2;
+
+	sha->sas_phy = arr_phy;
+	sha->sas_port = arr_port;
+	sha->lldd_ha = kzalloc(sizeof(struct pm8001_hba_info), GFP_KERNEL);
+	if (!sha->lldd_ha)
+		goto exit_free1;
+
+	shost->transportt = pm8001_stt;
+	shost->max_id = PM8001_MAX_DEVICES;
+	shost->max_lun = 8;
+	shost->max_channel = 0;
+	shost->unique_id = pm8001_id;
+	shost->max_cmd_len = 16;
+	shost->can_queue = PM8001_CAN_QUEUE;
+	shost->cmd_per_lun = 32;
+	return 0;
+exit_free1:
+	kfree(arr_port);
+exit_free2:
+	kfree(arr_phy);
+exit:
+	return -1;
+}
+
+/**
+ * pm8001_post_sas_ha_init - initialize general hba struct defined in libsas
+ * @shost: scsi host which has been allocated outside
+ * @chip_info: our ha struct.
+ */
+static void  __devinit pm8001_post_sas_ha_init(struct Scsi_Host *shost,
+	const struct pm8001_chip_info *chip_info)
+{
+	int i = 0;
+	struct pm8001_hba_info *pm8001_ha;
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+
+	pm8001_ha = sha->lldd_ha;
+	for (i = 0; i < chip_info->n_phy; i++) {
+		sha->sas_phy[i] = &pm8001_ha->phy[i].sas_phy;
+		sha->sas_port[i] = &pm8001_ha->port[i].sas_port;
+	}
+	sha->sas_ha_name = DRV_NAME;
+	sha->dev = pm8001_ha->dev;
+
+	sha->lldd_module = THIS_MODULE;
+	sha->sas_addr = &pm8001_ha->sas_addr[0];
+	sha->num_phys = chip_info->n_phy;
+	sha->lldd_max_execute_num = 1;
+	sha->lldd_queue_size = PM8001_CAN_QUEUE;
+	sha->core.shost = shost;
+}
+
+/**
+ * pm8001_init_sas_add - initialize sas address
+ * @chip_info: our ha struct.
+ *
+ * Currently we just set the fixed SAS address to our HBA,for manufacture,
+ * it should read from the EEPROM
+ */
+static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
+{
+	u8 i;
+#ifdef PM8001_READ_VPD
+	DECLARE_COMPLETION_ONSTACK(completion);
+	pm8001_ha->nvmd_completion = &completion;
+	PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, 0, 0);
+	wait_for_completion(&completion);
+	for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
+		memcpy(&pm8001_ha->phy[i].dev_sas_addr, pm8001_ha->sas_addr,
+			SAS_ADDR_SIZE);
+		PM8001_INIT_DBG(pm8001_ha,
+			pm8001_printk("phy %d sas_addr = %x \n", i,
+			(u64)pm8001_ha->phy[i].dev_sas_addr));
+	}
+#else
+	for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
+		pm8001_ha->phy[i].dev_sas_addr = 0x500e004010000004ULL;
+		pm8001_ha->phy[i].dev_sas_addr =
+			cpu_to_be64((u64)
+				(*(u64 *)&pm8001_ha->phy[i].dev_sas_addr));
+	}
+	memcpy(pm8001_ha->sas_addr, &pm8001_ha->phy[0].dev_sas_addr,
+		SAS_ADDR_SIZE);
+#endif
+}
+
+#ifdef PM8001_USE_MSIX
+/**
+ * pm8001_setup_msix - enable MSI-X interrupt
+ * @chip_info: our ha struct.
+ * @irq_handler: irq_handler
+ */
+static u32 pm8001_setup_msix(struct pm8001_hba_info *pm8001_ha,
+	irq_handler_t irq_handler)
+{
+	u32 i = 0, j = 0;
+	u32 number_of_intr = 1;
+	int flag = 0;
+	u32 max_entry;
+	int rc;
+	max_entry = sizeof(pm8001_ha->msix_entries) /
+		sizeof(pm8001_ha->msix_entries[0]);
+	flag |= IRQF_DISABLED;
+	for (i = 0; i < max_entry ; i++)
+		pm8001_ha->msix_entries[i].entry = i;
+	rc = pci_enable_msix(pm8001_ha->pdev, pm8001_ha->msix_entries,
+		number_of_intr);
+	pm8001_ha->number_of_intr = number_of_intr;
+	if (!rc) {
+		for (i = 0; i < number_of_intr; i++) {
+			if (request_irq(pm8001_ha->msix_entries[i].vector,
+				irq_handler, flag, DRV_NAME,
+				SHOST_TO_SAS_HA(pm8001_ha->shost))) {
+				for (j = 0; j < i; j++)
+					free_irq(
+					pm8001_ha->msix_entries[j].vector,
+					SHOST_TO_SAS_HA(pm8001_ha->shost));
+				pci_disable_msix(pm8001_ha->pdev);
+				break;
+			}
+		}
+	}
+	return rc;
+}
+#endif
+
+/**
+ * pm8001_request_irq - register interrupt
+ * @chip_info: our ha struct.
+ */
+static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha)
+{
+	struct pci_dev *pdev;
+	irq_handler_t irq_handler = pm8001_interrupt;
+	int rc;
+
+	pdev = pm8001_ha->pdev;
+
+#ifdef PM8001_USE_MSIX
+	if (pci_find_capability(pdev, PCI_CAP_ID_MSIX))
+		return pm8001_setup_msix(pm8001_ha, irq_handler);
+	else
+		goto intx;
+#endif
+
+intx:
+	/* intialize the INT-X interrupt */
+	rc = request_irq(pdev->irq, irq_handler, IRQF_SHARED, DRV_NAME,
+		SHOST_TO_SAS_HA(pm8001_ha->shost));
+	return rc;
+}
+
+/**
+ * pm8001_pci_probe - probe supported device
+ * @pdev: pci device which kernel has been prepared for.
+ * @ent: pci device id
+ *
+ * This function is the main initialization function, when register a new
+ * pci driver it is invoked, all struct an hardware initilization should be done
+ * here, also, register interrupt
+ */
+static int __devinit pm8001_pci_probe(struct pci_dev *pdev,
+	const struct pci_device_id *ent)
+{
+	unsigned int rc;
+	u32	pci_reg;
+	struct pm8001_hba_info *pm8001_ha;
+	struct Scsi_Host *shost = NULL;
+	const struct pm8001_chip_info *chip;
+
+	dev_printk(KERN_INFO, &pdev->dev,
+		"pm8001: driver version %s\n", DRV_VERSION);
+	rc = pci_enable_device(pdev);
+	if (rc)
+		goto err_out_enable;
+	pci_set_master(pdev);
+	/*
+	 * Enable pci slot busmaster by setting pci command register.
+	 * This is required by FW for Cyclone card.
+	 */
+
+	pci_read_config_dword(pdev, PCI_COMMAND, &pci_reg);
+	pci_reg |= 0x157;
+	pci_write_config_dword(pdev, PCI_COMMAND, pci_reg);
+	rc = pci_request_regions(pdev, DRV_NAME);
+	if (rc)
+		goto err_out_disable;
+	rc = pci_go_44(pdev);
+	if (rc)
+		goto err_out_regions;
+
+	shost = scsi_host_alloc(&pm8001_sht, sizeof(void *));
+	if (!shost) {
+		rc = -ENOMEM;
+		goto err_out_regions;
+	}
+	chip = &pm8001_chips[ent->driver_data];
+	SHOST_TO_SAS_HA(shost) =
+		kcalloc(1, sizeof(struct sas_ha_struct), GFP_KERNEL);
+	if (!SHOST_TO_SAS_HA(shost)) {
+		rc = -ENOMEM;
+		goto err_out_free_host;
+	}
+
+	rc = pm8001_prep_sas_ha_init(shost, chip);
+	if (rc) {
+		rc = -ENOMEM;
+		goto err_out_free;
+	}
+	pci_set_drvdata(pdev, SHOST_TO_SAS_HA(shost));
+	pm8001_ha = pm8001_pci_alloc(pdev, chip_8001, shost);
+	if (!pm8001_ha) {
+		rc = -ENOMEM;
+		goto err_out_free;
+	}
+	list_add_tail(&pm8001_ha->list, &hba_list);
+	PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha, 0x252acbcd);
+	rc = PM8001_CHIP_DISP->chip_init(pm8001_ha);
+	if (rc)
+		goto err_out_ha_free;
+
+	rc = scsi_add_host(shost, &pdev->dev);
+	if (rc)
+		goto err_out_ha_free;
+	rc = pm8001_request_irq(pm8001_ha);
+	if (rc)
+		goto err_out_shost;
+
+	PM8001_CHIP_DISP->interrupt_enable(pm8001_ha);
+	pm8001_init_sas_add(pm8001_ha);
+	pm8001_post_sas_ha_init(shost, chip);
+	rc = sas_register_ha(SHOST_TO_SAS_HA(shost));
+	if (rc)
+		goto err_out_shost;
+	scsi_scan_host(pm8001_ha->shost);
+	return 0;
+
+err_out_shost:
+	scsi_remove_host(pm8001_ha->shost);
+err_out_ha_free:
+	pm8001_free(pm8001_ha);
+err_out_free:
+	kfree(SHOST_TO_SAS_HA(shost));
+err_out_free_host:
+	kfree(shost);
+err_out_regions:
+	pci_release_regions(pdev);
+err_out_disable:
+	pci_disable_device(pdev);
+err_out_enable:
+	return rc;
+}
+
+static void __devexit pm8001_pci_remove(struct pci_dev *pdev)
+{
+	struct sas_ha_struct *sha = pci_get_drvdata(pdev);
+	struct pm8001_hba_info *pm8001_ha;
+	int i;
+	pm8001_ha = sha->lldd_ha;
+	pci_set_drvdata(pdev, NULL);
+	sas_unregister_ha(sha);
+	sas_remove_host(pm8001_ha->shost);
+	list_del(&pm8001_ha->list);
+	scsi_remove_host(pm8001_ha->shost);
+	PM8001_CHIP_DISP->interrupt_disable(pm8001_ha);
+	PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha, 0x252acbcd);
+
+#ifdef PM8001_USE_MSIX
+	for (i = 0; i < pm8001_ha->number_of_intr; i++)
+		synchronize_irq(pm8001_ha->msix_entries[i].vector);
+	for (i = 0; i < pm8001_ha->number_of_intr; i++)
+		free_irq(pm8001_ha->msix_entries[i].vector, sha);
+	pci_disable_msix(pdev);
+#else
+	free_irq(pm8001_ha->irq, sha);
+#endif
+#ifdef PM8001_USE_TASKLET
+	tasklet_kill(&pm8001_ha->tasklet);
+#endif
+	pm8001_free(pm8001_ha);
+	kfree(sha->sas_phy);
+	kfree(sha->sas_port);
+	kfree(sha);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+}
+
+/**
+ * pm8001_pci_suspend - power management suspend main entry point
+ * @pdev: PCI device struct
+ * @state: PM state change to (usually PCI_D3)
+ *
+ * Returns 0 success, anything else error.
+ */
+static int pm8001_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct sas_ha_struct *sha = pci_get_drvdata(pdev);
+	struct pm8001_hba_info *pm8001_ha;
+	int i , pos;
+	u32 device_state;
+	pm8001_ha = sha->lldd_ha;
+	flush_scheduled_work();
+	scsi_block_requests(pm8001_ha->shost);
+	pos = pci_find_capability(pdev, PCI_CAP_ID_PM);
+	if (pos == 0) {
+		printk(KERN_ERR " PCI PM not supported\n");
+		return -ENODEV;
+	}
+	PM8001_CHIP_DISP->interrupt_disable(pm8001_ha);
+	PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha, 0x252acbcd);
+#ifdef PM8001_USE_MSIX
+	for (i = 0; i < pm8001_ha->number_of_intr; i++)
+		synchronize_irq(pm8001_ha->msix_entries[i].vector);
+	for (i = 0; i < pm8001_ha->number_of_intr; i++)
+		free_irq(pm8001_ha->msix_entries[i].vector, sha);
+	pci_disable_msix(pdev);
+#else
+	free_irq(pm8001_ha->irq, sha);
+#endif
+#ifdef PM8001_USE_TASKLET
+	tasklet_kill(&pm8001_ha->tasklet);
+#endif
+	device_state = pci_choose_state(pdev, state);
+	pm8001_printk("pdev=0x%p, slot=%s, entering "
+		      "operating state [D%d]\n", pdev,
+		      pm8001_ha->name, device_state);
+	pci_save_state(pdev);
+	pci_disable_device(pdev);
+	pci_set_power_state(pdev, device_state);
+	return 0;
+}
+
+/**
+ * pm8001_pci_resume - power management resume main entry point
+ * @pdev: PCI device struct
+ *
+ * Returns 0 success, anything else error.
+ */
+static int pm8001_pci_resume(struct pci_dev *pdev)
+{
+	struct sas_ha_struct *sha = pci_get_drvdata(pdev);
+	struct pm8001_hba_info *pm8001_ha;
+	int rc;
+	u32 device_state;
+	pm8001_ha = sha->lldd_ha;
+	device_state = pdev->current_state;
+
+	pm8001_printk("pdev=0x%p, slot=%s, resuming from previous "
+		"operating state [D%d]\n", pdev, pm8001_ha->name, device_state);
+
+	pci_set_power_state(pdev, PCI_D0);
+	pci_enable_wake(pdev, PCI_D0, 0);
+	pci_restore_state(pdev);
+	rc = pci_enable_device(pdev);
+	if (rc) {
+		pm8001_printk("slot=%s Enable device failed during resume\n",
+			      pm8001_ha->name);
+		goto err_out_enable;
+	}
+
+	pci_set_master(pdev);
+	rc = pci_go_44(pdev);
+	if (rc)
+		goto err_out_disable;
+
+	PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha, 0x252acbcd);
+	rc = PM8001_CHIP_DISP->chip_init(pm8001_ha);
+	if (rc)
+		goto err_out_disable;
+	PM8001_CHIP_DISP->interrupt_disable(pm8001_ha);
+	rc = pm8001_request_irq(pm8001_ha);
+	if (rc)
+		goto err_out_disable;
+	#ifdef PM8001_USE_TASKLET
+	tasklet_init(&pm8001_ha->tasklet, pm8001_tasklet,
+		    (unsigned long)pm8001_ha);
+	#endif
+	PM8001_CHIP_DISP->interrupt_enable(pm8001_ha);
+	scsi_unblock_requests(pm8001_ha->shost);
+	return 0;
+
+err_out_disable:
+	scsi_remove_host(pm8001_ha->shost);
+	pci_disable_device(pdev);
+err_out_enable:
+	return rc;
+}
+
+static struct pci_device_id __devinitdata pm8001_pci_table[] = {
+	{
+		PCI_VDEVICE(PMC_Sierra, 0x8001), chip_8001
+	},
+	{
+		PCI_DEVICE(0x117c, 0x0042),
+		.driver_data = chip_8001
+	},
+	{} /* terminate list */
+};
+
+static struct pci_driver pm8001_pci_driver = {
+	.name		= DRV_NAME,
+	.id_table	= pm8001_pci_table,
+	.probe		= pm8001_pci_probe,
+	.remove		= __devexit_p(pm8001_pci_remove),
+	.suspend	= pm8001_pci_suspend,
+	.resume		= pm8001_pci_resume,
+};
+
+/**
+ *	pm8001_init - initialize scsi transport template
+ */
+static int __init pm8001_init(void)
+{
+	int rc;
+	pm8001_id = 0;
+	pm8001_stt = sas_domain_attach_transport(&pm8001_transport_ops);
+	if (!pm8001_stt)
+		return -ENOMEM;
+	rc = pci_register_driver(&pm8001_pci_driver);
+	if (rc)
+		goto err_out;
+	return 0;
+err_out:
+	sas_release_transport(pm8001_stt);
+	return rc;
+}
+
+static void __exit pm8001_exit(void)
+{
+	pci_unregister_driver(&pm8001_pci_driver);
+	sas_release_transport(pm8001_stt);
+}
+
+module_init(pm8001_init);
+module_exit(pm8001_exit);
+
+MODULE_AUTHOR("Jack Wang <jack_wang@usish.com>");
+MODULE_DESCRIPTION("PMC-Sierra PM8001 SAS/SATA controller driver");
+MODULE_VERSION(DRV_VERSION);
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, pm8001_pci_table);
+
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
new file mode 100644
index 0000000..1f767a0
--- /dev/null
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -0,0 +1,1103 @@
+/*
+ * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver
+ *
+ * Copyright (c) 2008-2009 USI Co., Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+#include "pm8001_sas.h"
+
+/**
+ * pm8001_find_tag - from sas task to find out  tag that belongs to this task
+ * @task: the task sent to the LLDD
+ * @tag: the found tag associated with the task
+ */
+static int pm8001_find_tag(struct sas_task *task, u32 *tag)
+{
+	if (task->lldd_task) {
+		struct pm8001_ccb_info *ccb;
+		ccb = task->lldd_task;
+		*tag = ccb->ccb_tag;
+		return 1;
+	}
+	return 0;
+}
+
+/**
+  * pm8001_tag_clear - clear the tags bitmap
+  * @pm8001_ha: our hba struct
+  * @tag: the found tag associated with the task
+  */
+static void pm8001_tag_clear(struct pm8001_hba_info *pm8001_ha, u32 tag)
+{
+	void *bitmap = pm8001_ha->tags;
+	clear_bit(tag, bitmap);
+}
+
+static void pm8001_tag_free(struct pm8001_hba_info *pm8001_ha, u32 tag)
+{
+	pm8001_tag_clear(pm8001_ha, tag);
+}
+
+static void pm8001_tag_set(struct pm8001_hba_info *pm8001_ha, u32 tag)
+{
+	void *bitmap = pm8001_ha->tags;
+	set_bit(tag, bitmap);
+}
+
+/**
+  * pm8001_tag_alloc - allocate a empty tag for task used.
+  * @pm8001_ha: our hba struct
+  * @tag_out: the found empty tag .
+  */
+inline int pm8001_tag_alloc(struct pm8001_hba_info *pm8001_ha, u32 *tag_out)
+{
+	unsigned int index, tag;
+	void *bitmap = pm8001_ha->tags;
+
+	index = find_first_zero_bit(bitmap, pm8001_ha->tags_num);
+	tag = index;
+	if (tag >= pm8001_ha->tags_num)
+		return -SAS_QUEUE_FULL;
+	pm8001_tag_set(pm8001_ha, tag);
+	*tag_out = tag;
+	return 0;
+}
+
+void pm8001_tag_init(struct pm8001_hba_info *pm8001_ha)
+{
+	int i;
+	for (i = 0; i < pm8001_ha->tags_num; ++i)
+		pm8001_tag_clear(pm8001_ha, i);
+}
+
+ /**
+  * pm8001_mem_alloc - allocate memory for pm8001.
+  * @pdev: pci device.
+  * @virt_addr: the allocated virtual address
+  * @pphys_addr_hi: the physical address high byte address.
+  * @pphys_addr_lo: the physical address low byte address.
+  * @mem_size: memory size.
+  */
+int pm8001_mem_alloc(struct pci_dev *pdev, void **virt_addr,
+	dma_addr_t *pphys_addr, u32 *pphys_addr_hi,
+	u32 *pphys_addr_lo, u32 mem_size, u32 align)
+{
+	caddr_t mem_virt_alloc;
+	dma_addr_t mem_dma_handle;
+	u64 phys_align;
+	u64 align_offset = 0;
+	if (align)
+		align_offset = (dma_addr_t)align - 1;
+	mem_virt_alloc =
+		pci_alloc_consistent(pdev, mem_size + align, &mem_dma_handle);
+	if (!mem_virt_alloc) {
+		pm8001_printk("memory allocation error\n");
+		return -1;
+	}
+	memset((void *)mem_virt_alloc, 0, mem_size+align);
+	*pphys_addr = mem_dma_handle;
+	phys_align = (*pphys_addr + align_offset) & ~align_offset;
+	*virt_addr = (void *)mem_virt_alloc + phys_align - *pphys_addr;
+	*pphys_addr_hi = upper_32_bits(phys_align);
+	*pphys_addr_lo = lower_32_bits(phys_align);
+	return 0;
+}
+/**
+  * pm8001_find_ha_by_dev - from domain device which come from sas layer to
+  * find out our hba struct.
+  * @dev: the domain device which from sas layer.
+  */
+static
+struct pm8001_hba_info *pm8001_find_ha_by_dev(struct domain_device *dev)
+{
+	struct sas_ha_struct *sha = dev->port->ha;
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+	return pm8001_ha;
+}
+
+/**
+  * pm8001_phy_control - this function should be registered to
+  * sas_domain_function_template to provide libsas used, note: this is just
+  * control the HBA phy rather than other expander phy if you want control
+  * other phy, you should use SMP command.
+  * @sas_phy: which phy in HBA phys.
+  * @func: the operation.
+  * @funcdata: always NULL.
+  */
+int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
+	void *funcdata)
+{
+	int rc = 0, phy_id = sas_phy->id;
+	struct pm8001_hba_info *pm8001_ha = NULL;
+	struct sas_phy_linkrates *rates;
+	DECLARE_COMPLETION_ONSTACK(completion);
+	pm8001_ha = sas_phy->ha->lldd_ha;
+	pm8001_ha->phy[phy_id].enable_completion = &completion;
+	switch (func) {
+	case PHY_FUNC_SET_LINK_RATE:
+		rates = funcdata;
+		if (rates->minimum_linkrate) {
+			pm8001_ha->phy[phy_id].minimum_linkrate =
+				rates->minimum_linkrate;
+		}
+		if (rates->maximum_linkrate) {
+			pm8001_ha->phy[phy_id].maximum_linkrate =
+				rates->maximum_linkrate;
+		}
+		if (pm8001_ha->phy[phy_id].phy_state == 0) {
+			PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id);
+			wait_for_completion(&completion);
+		}
+		PM8001_CHIP_DISP->phy_ctl_req(pm8001_ha, phy_id,
+					      PHY_LINK_RESET);
+		break;
+	case PHY_FUNC_HARD_RESET:
+		if (pm8001_ha->phy[phy_id].phy_state == 0) {
+			PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id);
+			wait_for_completion(&completion);
+		}
+		PM8001_CHIP_DISP->phy_ctl_req(pm8001_ha, phy_id,
+					      PHY_HARD_RESET);
+		break;
+	case PHY_FUNC_LINK_RESET:
+		if (pm8001_ha->phy[phy_id].phy_state == 0) {
+			PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id);
+			wait_for_completion(&completion);
+		}
+		PM8001_CHIP_DISP->phy_ctl_req(pm8001_ha, phy_id,
+					      PHY_LINK_RESET);
+		break;
+	case PHY_FUNC_RELEASE_SPINUP_HOLD:
+		PM8001_CHIP_DISP->phy_ctl_req(pm8001_ha, phy_id,
+					      PHY_LINK_RESET);
+		break;
+	case PHY_FUNC_DISABLE:
+		PM8001_CHIP_DISP->phy_stop_req(pm8001_ha, phy_id);
+		break;
+	default:
+		rc = -EOPNOTSUPP;
+	}
+	msleep(300);
+	return rc;
+}
+
+int pm8001_slave_alloc(struct scsi_device *scsi_dev)
+{
+	struct domain_device *dev = sdev_to_domain_dev(scsi_dev);
+	if (dev_is_sata(dev)) {
+		/* We don't need to rescan targets
+		* if REPORT_LUNS request is failed
+		*/
+		if (scsi_dev->lun > 0)
+			return -ENXIO;
+		scsi_dev->tagged_supported = 1;
+	}
+	return sas_slave_alloc(scsi_dev);
+}
+
+/**
+  * pm8001_scan_start - we should enable all HBA phys by sending the phy_start
+  * command to HBA.
+  * @shost: the scsi host data.
+  */
+void pm8001_scan_start(struct Scsi_Host *shost)
+{
+	int i;
+	struct pm8001_hba_info *pm8001_ha;
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	pm8001_ha = sha->lldd_ha;
+	PM8001_CHIP_DISP->sas_re_init_req(pm8001_ha);
+	for (i = 0; i < pm8001_ha->chip->n_phy; ++i)
+		PM8001_CHIP_DISP->phy_start_req(pm8001_ha, i);
+}
+
+int pm8001_scan_finished(struct Scsi_Host *shost, unsigned long time)
+{
+	/* give the phy enabling interrupt event time to come in (1s
+	* is empirically about all it takes) */
+	if (time < HZ)
+		return 0;
+	/* Wait for discovery to finish */
+	scsi_flush_work(shost);
+	return 1;
+}
+
+/**
+  * pm8001_task_prep_smp - the dispatcher function, prepare data for smp task
+  * @pm8001_ha: our hba card information
+  * @ccb: the ccb which attached to smp task
+  */
+static int pm8001_task_prep_smp(struct pm8001_hba_info *pm8001_ha,
+	struct pm8001_ccb_info *ccb)
+{
+	return PM8001_CHIP_DISP->smp_req(pm8001_ha, ccb);
+}
+
+u32 pm8001_get_ncq_tag(struct sas_task *task, u32 *tag)
+{
+	struct ata_queued_cmd *qc = task->uldd_task;
+	if (qc) {
+		if (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
+			qc->tf.command == ATA_CMD_FPDMA_READ) {
+			*tag = qc->tag;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+/**
+  * pm8001_task_prep_ata - the dispatcher function, prepare data for sata task
+  * @pm8001_ha: our hba card information
+  * @ccb: the ccb which attached to sata task
+  */
+static int pm8001_task_prep_ata(struct pm8001_hba_info *pm8001_ha,
+	struct pm8001_ccb_info *ccb)
+{
+	return PM8001_CHIP_DISP->sata_req(pm8001_ha, ccb);
+}
+
+/**
+  * pm8001_task_prep_ssp_tm - the dispatcher function, prepare task management data
+  * @pm8001_ha: our hba card information
+  * @ccb: the ccb which attached to TM
+  * @tmf: the task management IU
+  */
+static int pm8001_task_prep_ssp_tm(struct pm8001_hba_info *pm8001_ha,
+	struct pm8001_ccb_info *ccb, struct pm8001_tmf_task *tmf)
+{
+	return PM8001_CHIP_DISP->ssp_tm_req(pm8001_ha, ccb, tmf);
+}
+
+/**
+  * pm8001_task_prep_ssp - the dispatcher function,prepare ssp data for ssp task
+  * @pm8001_ha: our hba card information
+  * @ccb: the ccb which attached to ssp task
+  */
+static int pm8001_task_prep_ssp(struct pm8001_hba_info *pm8001_ha,
+	struct pm8001_ccb_info *ccb)
+{
+	return PM8001_CHIP_DISP->ssp_io_req(pm8001_ha, ccb);
+}
+int pm8001_slave_configure(struct scsi_device *sdev)
+{
+	struct domain_device *dev = sdev_to_domain_dev(sdev);
+	int ret = sas_slave_configure(sdev);
+	if (ret)
+		return ret;
+	if (dev_is_sata(dev)) {
+	#ifdef PM8001_DISABLE_NCQ
+		struct ata_port *ap = dev->sata_dev.ap;
+		struct ata_device *adev = ap->link.device;
+		adev->flags |= ATA_DFLAG_NCQ_OFF;
+		scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, 1);
+	#endif
+	}
+	return 0;
+}
+/**
+  * pm8001_task_exec - queue the task(ssp, smp && ata) to the hardware.
+  * @task: the task to be execute.
+  * @num: if can_queue great than 1, the task can be queued up. for SMP task,
+  * we always execute one one time.
+  * @gfp_flags: gfp_flags.
+  * @is_tmf: if it is task management task.
+  * @tmf: the task management IU
+  */
+#define DEV_IS_GONE(pm8001_dev)	\
+	((!pm8001_dev || (pm8001_dev->dev_type == NO_DEVICE)))
+static int pm8001_task_exec(struct sas_task *task, const int num,
+	gfp_t gfp_flags, int is_tmf, struct pm8001_tmf_task *tmf)
+{
+	struct domain_device *dev = task->dev;
+	struct pm8001_hba_info *pm8001_ha;
+	struct pm8001_device *pm8001_dev;
+	struct sas_task *t = task;
+	struct pm8001_ccb_info *ccb;
+	u32 tag = 0xdeadbeef, rc, n_elem = 0;
+	u32 n = num;
+	unsigned long flags = 0;
+
+	if (!dev->port) {
+		struct task_status_struct *tsm = &t->task_status;
+		tsm->resp = SAS_TASK_UNDELIVERED;
+		tsm->stat = SAS_PHY_DOWN;
+		if (dev->dev_type != SATA_DEV)
+			t->task_done(t);
+		return 0;
+	}
+	pm8001_ha = pm8001_find_ha_by_dev(task->dev);
+	PM8001_IO_DBG(pm8001_ha, pm8001_printk("pm8001_task_exec device \n "));
+	spin_lock_irqsave(&pm8001_ha->lock, flags);
+	do {
+		dev = t->dev;
+		pm8001_dev = dev->lldd_dev;
+		if (DEV_IS_GONE(pm8001_dev)) {
+			if (pm8001_dev) {
+				PM8001_IO_DBG(pm8001_ha,
+					pm8001_printk("device %d not ready.\n",
+					pm8001_dev->device_id));
+			} else {
+				PM8001_IO_DBG(pm8001_ha,
+					pm8001_printk("device %016llx not "
+					"ready.\n", SAS_ADDR(dev->sas_addr)));
+			}
+			rc = SAS_PHY_DOWN;
+			goto out_done;
+		}
+		rc = pm8001_tag_alloc(pm8001_ha, &tag);
+		if (rc)
+			goto err_out;
+		ccb = &pm8001_ha->ccb_info[tag];
+
+		if (!sas_protocol_ata(t->task_proto)) {
+			if (t->num_scatter) {
+				n_elem = dma_map_sg(pm8001_ha->dev,
+					t->scatter,
+					t->num_scatter,
+					t->data_dir);
+				if (!n_elem) {
+					rc = -ENOMEM;
+					goto err_out_tag;
+				}
+			}
+		} else {
+			n_elem = t->num_scatter;
+		}
+
+		t->lldd_task = ccb;
+		ccb->n_elem = n_elem;
+		ccb->ccb_tag = tag;
+		ccb->task = t;
+		switch (t->task_proto) {
+		case SAS_PROTOCOL_SMP:
+			rc = pm8001_task_prep_smp(pm8001_ha, ccb);
+			break;
+		case SAS_PROTOCOL_SSP:
+			if (is_tmf)
+				rc = pm8001_task_prep_ssp_tm(pm8001_ha,
+					ccb, tmf);
+			else
+				rc = pm8001_task_prep_ssp(pm8001_ha, ccb);
+			break;
+		case SAS_PROTOCOL_SATA:
+		case SAS_PROTOCOL_STP:
+		case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
+			rc = pm8001_task_prep_ata(pm8001_ha, ccb);
+			break;
+		default:
+			dev_printk(KERN_ERR, pm8001_ha->dev,
+				"unknown sas_task proto: 0x%x\n",
+				t->task_proto);
+			rc = -EINVAL;
+			break;
+		}
+
+		if (rc) {
+			PM8001_IO_DBG(pm8001_ha,
+				pm8001_printk("rc is %x\n", rc));
+			goto err_out_tag;
+		}
+		/* TODO: select normal or high priority */
+		spin_lock(&t->task_state_lock);
+		t->task_state_flags |= SAS_TASK_AT_INITIATOR;
+		spin_unlock(&t->task_state_lock);
+		pm8001_dev->running_req++;
+		if (n > 1)
+			t = list_entry(t->list.next, struct sas_task, list);
+	} while (--n);
+	rc = 0;
+	goto out_done;
+
+err_out_tag:
+	pm8001_tag_free(pm8001_ha, tag);
+err_out:
+	dev_printk(KERN_ERR, pm8001_ha->dev, "pm8001 exec failed[%d]!\n", rc);
+	if (!sas_protocol_ata(t->task_proto))
+		if (n_elem)
+			dma_unmap_sg(pm8001_ha->dev, t->scatter, n_elem,
+				t->data_dir);
+out_done:
+	spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+	return rc;
+}
+
+/**
+  * pm8001_queue_command - register for upper layer used, all IO commands sent
+  * to HBA are from this interface.
+  * @task: the task to be execute.
+  * @num: if can_queue great than 1, the task can be queued up. for SMP task,
+  * we always execute one one time
+  * @gfp_flags: gfp_flags
+  */
+int pm8001_queue_command(struct sas_task *task, const int num,
+		gfp_t gfp_flags)
+{
+	return pm8001_task_exec(task, num, gfp_flags, 0, NULL);
+}
+
+void pm8001_ccb_free(struct pm8001_hba_info *pm8001_ha, u32 ccb_idx)
+{
+	pm8001_tag_clear(pm8001_ha, ccb_idx);
+}
+
+/**
+  * pm8001_ccb_task_free - free the sg for ssp and smp command, free the ccb.
+  * @pm8001_ha: our hba card information
+  * @ccb: the ccb which attached to ssp task
+  * @task: the task to be free.
+  * @ccb_idx: ccb index.
+  */
+void pm8001_ccb_task_free(struct pm8001_hba_info *pm8001_ha,
+	struct sas_task *task, struct pm8001_ccb_info *ccb, u32 ccb_idx)
+{
+	if (!ccb->task)
+		return;
+	if (!sas_protocol_ata(task->task_proto))
+		if (ccb->n_elem)
+			dma_unmap_sg(pm8001_ha->dev, task->scatter,
+				task->num_scatter, task->data_dir);
+
+	switch (task->task_proto) {
+	case SAS_PROTOCOL_SMP:
+		dma_unmap_sg(pm8001_ha->dev, &task->smp_task.smp_resp, 1,
+			PCI_DMA_FROMDEVICE);
+		dma_unmap_sg(pm8001_ha->dev, &task->smp_task.smp_req, 1,
+			PCI_DMA_TODEVICE);
+		break;
+
+	case SAS_PROTOCOL_SATA:
+	case SAS_PROTOCOL_STP:
+	case SAS_PROTOCOL_SSP:
+	default:
+		/* do nothing */
+		break;
+	}
+	task->lldd_task = NULL;
+	ccb->task = NULL;
+	ccb->ccb_tag = 0xFFFFFFFF;
+	pm8001_ccb_free(pm8001_ha, ccb_idx);
+}
+
+ /**
+  * pm8001_alloc_dev - find a empty pm8001_device
+  * @pm8001_ha: our hba card information
+  */
+struct pm8001_device *pm8001_alloc_dev(struct pm8001_hba_info *pm8001_ha)
+{
+	u32 dev;
+	for (dev = 0; dev < PM8001_MAX_DEVICES; dev++) {
+		if (pm8001_ha->devices[dev].dev_type == NO_DEVICE) {
+			pm8001_ha->devices[dev].id = dev;
+			return &pm8001_ha->devices[dev];
+		}
+	}
+	if (dev == PM8001_MAX_DEVICES) {
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("max support %d devices, ignore ..\n",
+			PM8001_MAX_DEVICES));
+	}
+	return NULL;
+}
+
+static void pm8001_free_dev(struct pm8001_device *pm8001_dev)
+{
+	u32 id = pm8001_dev->id;
+	memset(pm8001_dev, 0, sizeof(*pm8001_dev));
+	pm8001_dev->id = id;
+	pm8001_dev->dev_type = NO_DEVICE;
+	pm8001_dev->device_id = PM8001_MAX_DEVICES;
+	pm8001_dev->sas_device = NULL;
+}
+
+/**
+  * pm8001_dev_found_notify - libsas notify a device is found.
+  * @dev: the device structure which sas layer used.
+  *
+  * when libsas find a sas domain device, it should tell the LLDD that
+  * device is found, and then LLDD register this device to HBA firmware
+  * by the command "OPC_INB_REG_DEV", after that the HBA will assign a
+  * device ID(according to device's sas address) and returned it to LLDD. From
+  * now on, we communicate with HBA FW with the device ID which HBA assigned
+  * rather than sas address. it is the neccessary step for our HBA but it is
+  * the optional for other HBA driver.
+  */
+static int pm8001_dev_found_notify(struct domain_device *dev)
+{
+	unsigned long flags = 0;
+	int res = 0;
+	struct pm8001_hba_info *pm8001_ha = NULL;
+	struct domain_device *parent_dev = dev->parent;
+	struct pm8001_device *pm8001_device;
+	DECLARE_COMPLETION_ONSTACK(completion);
+	u32 flag = 0;
+	pm8001_ha = pm8001_find_ha_by_dev(dev);
+	spin_lock_irqsave(&pm8001_ha->lock, flags);
+
+	pm8001_device = pm8001_alloc_dev(pm8001_ha);
+	pm8001_device->sas_device = dev;
+	if (!pm8001_device) {
+		res = -1;
+		goto found_out;
+	}
+	dev->lldd_dev = pm8001_device;
+	pm8001_device->dev_type = dev->dev_type;
+	pm8001_device->dcompletion = &completion;
+	if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type)) {
+		int phy_id;
+		struct ex_phy *phy;
+		for (phy_id = 0; phy_id < parent_dev->ex_dev.num_phys;
+		phy_id++) {
+			phy = &parent_dev->ex_dev.ex_phy[phy_id];
+			if (SAS_ADDR(phy->attached_sas_addr)
+				== SAS_ADDR(dev->sas_addr)) {
+				pm8001_device->attached_phy = phy_id;
+				break;
+			}
+		}
+		if (phy_id == parent_dev->ex_dev.num_phys) {
+			PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("Error: no attached dev:%016llx"
+			" at ex:%016llx.\n", SAS_ADDR(dev->sas_addr),
+				SAS_ADDR(parent_dev->sas_addr)));
+			res = -1;
+		}
+	} else {
+		if (dev->dev_type == SATA_DEV) {
+			pm8001_device->attached_phy =
+				dev->rphy->identify.phy_identifier;
+				flag = 1; /* directly sata*/
+		}
+	} /*register this device to HBA*/
+	PM8001_DISC_DBG(pm8001_ha, pm8001_printk("Found device \n"));
+	PM8001_CHIP_DISP->reg_dev_req(pm8001_ha, pm8001_device, flag);
+	spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+	wait_for_completion(&completion);
+	if (dev->dev_type == SAS_END_DEV)
+		msleep(50);
+	pm8001_ha->flags = PM8001F_RUN_TIME ;
+	return 0;
+found_out:
+	spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+	return res;
+}
+
+int pm8001_dev_found(struct domain_device *dev)
+{
+	return pm8001_dev_found_notify(dev);
+}
+
+/**
+  * pm8001_alloc_task - allocate a task structure for TMF
+  */
+static struct sas_task *pm8001_alloc_task(void)
+{
+	struct sas_task *task = kzalloc(sizeof(*task), GFP_KERNEL);
+	if (task) {
+		INIT_LIST_HEAD(&task->list);
+		spin_lock_init(&task->task_state_lock);
+		task->task_state_flags = SAS_TASK_STATE_PENDING;
+		init_timer(&task->timer);
+		init_completion(&task->completion);
+	}
+	return task;
+}
+
+static void pm8001_free_task(struct sas_task *task)
+{
+	if (task) {
+		BUG_ON(!list_empty(&task->list));
+		kfree(task);
+	}
+}
+
+static void pm8001_task_done(struct sas_task *task)
+{
+	if (!del_timer(&task->timer))
+		return;
+	complete(&task->completion);
+}
+
+static void pm8001_tmf_timedout(unsigned long data)
+{
+	struct sas_task *task = (struct sas_task *)data;
+
+	task->task_state_flags |= SAS_TASK_STATE_ABORTED;
+	complete(&task->completion);
+}
+
+#define PM8001_TASK_TIMEOUT 20
+/**
+  * pm8001_exec_internal_tmf_task - execute some task management commands.
+  * @dev: the wanted device.
+  * @tmf: which task management wanted to be take.
+  * @para_len: para_len.
+  * @parameter: ssp task parameter.
+  *
+  * when errors or exception happened, we may want to do something, for example
+  * abort the issued task which result in this execption, it is done by calling
+  * this function, note it is also with the task execute interface.
+  */
+static int pm8001_exec_internal_tmf_task(struct domain_device *dev,
+	void *parameter, u32 para_len, struct pm8001_tmf_task *tmf)
+{
+	int res, retry;
+	struct sas_task *task = NULL;
+	struct pm8001_hba_info *pm8001_ha = pm8001_find_ha_by_dev(dev);
+
+	for (retry = 0; retry < 3; retry++) {
+		task = pm8001_alloc_task();
+		if (!task)
+			return -ENOMEM;
+
+		task->dev = dev;
+		task->task_proto = dev->tproto;
+		memcpy(&task->ssp_task, parameter, para_len);
+		task->task_done = pm8001_task_done;
+		task->timer.data = (unsigned long)task;
+		task->timer.function = pm8001_tmf_timedout;
+		task->timer.expires = jiffies + PM8001_TASK_TIMEOUT*HZ;
+		add_timer(&task->timer);
+
+		res = pm8001_task_exec(task, 1, GFP_KERNEL, 1, tmf);
+
+		if (res) {
+			del_timer(&task->timer);
+			PM8001_FAIL_DBG(pm8001_ha,
+				pm8001_printk("Executing internal task "
+				"failed\n"));
+			goto ex_err;
+		}
+		wait_for_completion(&task->completion);
+		res = -TMF_RESP_FUNC_FAILED;
+		/* Even TMF timed out, return direct. */
+		if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
+			if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
+				PM8001_FAIL_DBG(pm8001_ha,
+					pm8001_printk("TMF task[%x]timeout.\n",
+					tmf->tmf));
+				goto ex_err;
+			}
+		}
+
+		if (task->task_status.resp == SAS_TASK_COMPLETE &&
+			task->task_status.stat == SAM_GOOD) {
+			res = TMF_RESP_FUNC_COMPLETE;
+			break;
+		}
+
+		if (task->task_status.resp == SAS_TASK_COMPLETE &&
+		task->task_status.stat == SAS_DATA_UNDERRUN) {
+			/* no error, but return the number of bytes of
+			* underrun */
+			res = task->task_status.residual;
+			break;
+		}
+
+		if (task->task_status.resp == SAS_TASK_COMPLETE &&
+			task->task_status.stat == SAS_DATA_OVERRUN) {
+			PM8001_FAIL_DBG(pm8001_ha,
+				pm8001_printk("Blocked task error.\n"));
+			res = -EMSGSIZE;
+			break;
+		} else {
+			PM8001_EH_DBG(pm8001_ha,
+				pm8001_printk(" Task to dev %016llx response:"
+				"0x%x status 0x%x\n",
+				SAS_ADDR(dev->sas_addr),
+				task->task_status.resp,
+				task->task_status.stat));
+			pm8001_free_task(task);
+			task = NULL;
+		}
+	}
+ex_err:
+	BUG_ON(retry == 3 && task != NULL);
+	if (task != NULL)
+		pm8001_free_task(task);
+	return res;
+}
+
+static int
+pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha,
+	struct pm8001_device *pm8001_dev, struct domain_device *dev, u32 flag,
+	u32 task_tag)
+{
+	int res, retry;
+	u32 ccb_tag;
+	struct pm8001_ccb_info *ccb;
+	struct sas_task *task = NULL;
+
+	for (retry = 0; retry < 3; retry++) {
+		task = pm8001_alloc_task();
+		if (!task)
+			return -ENOMEM;
+
+		task->dev = dev;
+		task->task_proto = dev->tproto;
+		task->task_done = pm8001_task_done;
+		task->timer.data = (unsigned long)task;
+		task->timer.function = pm8001_tmf_timedout;
+		task->timer.expires = jiffies + PM8001_TASK_TIMEOUT*HZ;
+		add_timer(&task->timer);
+
+		res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
+		if (res)
+			return res;
+		ccb = &pm8001_ha->ccb_info[ccb_tag];
+		ccb->device = pm8001_dev;
+		ccb->ccb_tag = ccb_tag;
+		ccb->task = task;
+
+		res = PM8001_CHIP_DISP->task_abort(pm8001_ha,
+			pm8001_dev, flag, task_tag, ccb_tag);
+
+		if (res) {
+			del_timer(&task->timer);
+			PM8001_FAIL_DBG(pm8001_ha,
+				pm8001_printk("Executing internal task "
+				"failed\n"));
+			goto ex_err;
+		}
+		wait_for_completion(&task->completion);
+		res = TMF_RESP_FUNC_FAILED;
+		/* Even TMF timed out, return direct. */
+		if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
+			if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
+				PM8001_FAIL_DBG(pm8001_ha,
+					pm8001_printk("TMF task timeout.\n"));
+				goto ex_err;
+			}
+		}
+
+		if (task->task_status.resp == SAS_TASK_COMPLETE &&
+			task->task_status.stat == SAM_GOOD) {
+			res = TMF_RESP_FUNC_COMPLETE;
+			break;
+
+		} else {
+			PM8001_EH_DBG(pm8001_ha,
+				pm8001_printk(" Task to dev %016llx response: "
+					"0x%x status 0x%x\n",
+				SAS_ADDR(dev->sas_addr),
+				task->task_status.resp,
+				task->task_status.stat));
+			pm8001_free_task(task);
+			task = NULL;
+		}
+	}
+ex_err:
+	BUG_ON(retry == 3 && task != NULL);
+	if (task != NULL)
+		pm8001_free_task(task);
+	return res;
+}
+
+/**
+  * pm8001_dev_gone_notify - see the comments for "pm8001_dev_found_notify"
+  * @dev: the device structure which sas layer used.
+  */
+static void pm8001_dev_gone_notify(struct domain_device *dev)
+{
+	unsigned long flags = 0;
+	u32 tag;
+	struct pm8001_hba_info *pm8001_ha;
+	struct pm8001_device *pm8001_dev = dev->lldd_dev;
+	u32 device_id = pm8001_dev->device_id;
+	pm8001_ha = pm8001_find_ha_by_dev(dev);
+	spin_lock_irqsave(&pm8001_ha->lock, flags);
+	pm8001_tag_alloc(pm8001_ha, &tag);
+	if (pm8001_dev) {
+		PM8001_DISC_DBG(pm8001_ha,
+			pm8001_printk("found dev[%d:%x] is gone.\n",
+			pm8001_dev->device_id, pm8001_dev->dev_type));
+		if (pm8001_dev->running_req) {
+			spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+			pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev ,
+				dev, 1, 0);
+			spin_lock_irqsave(&pm8001_ha->lock, flags);
+		}
+		PM8001_CHIP_DISP->dereg_dev_req(pm8001_ha, device_id);
+		pm8001_free_dev(pm8001_dev);
+	} else {
+		PM8001_DISC_DBG(pm8001_ha,
+			pm8001_printk("Found dev has gone.\n"));
+	}
+	dev->lldd_dev = NULL;
+	spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+}
+
+void pm8001_dev_gone(struct domain_device *dev)
+{
+	pm8001_dev_gone_notify(dev);
+}
+
+static int pm8001_issue_ssp_tmf(struct domain_device *dev,
+	u8 *lun, struct pm8001_tmf_task *tmf)
+{
+	struct sas_ssp_task ssp_task;
+	if (!(dev->tproto & SAS_PROTOCOL_SSP))
+		return TMF_RESP_FUNC_ESUPP;
+
+	strncpy((u8 *)&ssp_task.LUN, lun, 8);
+	return pm8001_exec_internal_tmf_task(dev, &ssp_task, sizeof(ssp_task),
+		tmf);
+}
+
+/**
+  * Standard mandates link reset for ATA  (type 0) and hard reset for
+  * SSP (type 1) , only for RECOVERY
+  */
+int pm8001_I_T_nexus_reset(struct domain_device *dev)
+{
+	int rc = TMF_RESP_FUNC_FAILED;
+	struct pm8001_device *pm8001_dev;
+	struct pm8001_hba_info *pm8001_ha;
+	struct sas_phy *phy;
+	if (!dev || !dev->lldd_dev)
+		return -1;
+
+	pm8001_dev = dev->lldd_dev;
+	pm8001_ha = pm8001_find_ha_by_dev(dev);
+	phy = sas_find_local_phy(dev);
+
+	if (dev_is_sata(dev)) {
+		DECLARE_COMPLETION_ONSTACK(completion_setstate);
+		rc = sas_phy_reset(phy, 1);
+		msleep(2000);
+		rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev ,
+			dev, 1, 0);
+		pm8001_dev->setds_completion = &completion_setstate;
+		rc = PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha,
+			pm8001_dev, 0x01);
+		wait_for_completion(&completion_setstate);
+	} else{
+	rc = sas_phy_reset(phy, 1);
+	msleep(2000);
+	}
+	PM8001_EH_DBG(pm8001_ha, pm8001_printk(" for device[%x]:rc=%d\n",
+		pm8001_dev->device_id, rc));
+	return rc;
+}
+
+/* mandatory SAM-3, the task reset the specified LUN*/
+int pm8001_lu_reset(struct domain_device *dev, u8 *lun)
+{
+	int rc = TMF_RESP_FUNC_FAILED;
+	struct pm8001_tmf_task tmf_task;
+	struct pm8001_device *pm8001_dev = dev->lldd_dev;
+	struct pm8001_hba_info *pm8001_ha = pm8001_find_ha_by_dev(dev);
+	if (dev_is_sata(dev)) {
+		struct sas_phy *phy = sas_find_local_phy(dev);
+		rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev ,
+			dev, 1, 0);
+		rc = sas_phy_reset(phy, 1);
+		rc = PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha,
+			pm8001_dev, 0x01);
+		msleep(2000);
+	} else {
+		tmf_task.tmf = TMF_LU_RESET;
+		rc = pm8001_issue_ssp_tmf(dev, lun, &tmf_task);
+	}
+	/* If failed, fall-through I_T_Nexus reset */
+	PM8001_EH_DBG(pm8001_ha, pm8001_printk("for device[%x]:rc=%d\n",
+		pm8001_dev->device_id, rc));
+	return rc;
+}
+
+/* optional SAM-3 */
+int pm8001_query_task(struct sas_task *task)
+{
+	u32 tag = 0xdeadbeef;
+	int i = 0;
+	struct scsi_lun lun;
+	struct pm8001_tmf_task tmf_task;
+	int rc = TMF_RESP_FUNC_FAILED;
+	if (unlikely(!task || !task->lldd_task || !task->dev))
+		return rc;
+
+	if (task->task_proto & SAS_PROTOCOL_SSP) {
+		struct scsi_cmnd *cmnd = task->uldd_task;
+		struct domain_device *dev = task->dev;
+		struct pm8001_hba_info *pm8001_ha =
+			pm8001_find_ha_by_dev(dev);
+
+		int_to_scsilun(cmnd->device->lun, &lun);
+		rc = pm8001_find_tag(task, &tag);
+		if (rc == 0) {
+			rc = TMF_RESP_FUNC_FAILED;
+			return rc;
+		}
+		PM8001_EH_DBG(pm8001_ha, pm8001_printk("Query:["));
+		for (i = 0; i < 16; i++)
+			printk(KERN_INFO "%02x ", cmnd->cmnd[i]);
+		printk(KERN_INFO "]\n");
+		tmf_task.tmf = 	TMF_QUERY_TASK;
+		tmf_task.tag_of_task_to_be_managed = tag;
+
+		rc = pm8001_issue_ssp_tmf(dev, lun.scsi_lun, &tmf_task);
+		switch (rc) {
+		/* The task is still in Lun, release it then */
+		case TMF_RESP_FUNC_SUCC:
+			PM8001_EH_DBG(pm8001_ha,
+				pm8001_printk("The task is still in Lun \n"));
+		/* The task is not in Lun or failed, reset the phy */
+		case TMF_RESP_FUNC_FAILED:
+		case TMF_RESP_FUNC_COMPLETE:
+			PM8001_EH_DBG(pm8001_ha,
+			pm8001_printk("The task is not in Lun or failed,"
+			" reset the phy \n"));
+			break;
+		}
+	}
+	pm8001_printk(":rc= %d\n", rc);
+	return rc;
+}
+
+/*  mandatory SAM-3, still need free task/ccb info, abord the specified task */
+int pm8001_abort_task(struct sas_task *task)
+{
+	unsigned long flags;
+	u32 tag = 0xdeadbeef;
+	u32 device_id;
+	struct domain_device *dev ;
+	struct pm8001_hba_info *pm8001_ha = NULL;
+	struct pm8001_ccb_info *ccb;
+	struct scsi_lun lun;
+	struct pm8001_device *pm8001_dev;
+	struct pm8001_tmf_task tmf_task;
+	int rc = TMF_RESP_FUNC_FAILED;
+	if (unlikely(!task || !task->lldd_task || !task->dev))
+		return rc;
+	spin_lock_irqsave(&task->task_state_lock, flags);
+	if (task->task_state_flags & SAS_TASK_STATE_DONE) {
+		spin_unlock_irqrestore(&task->task_state_lock, flags);
+		rc = TMF_RESP_FUNC_COMPLETE;
+		goto out;
+	}
+	spin_unlock_irqrestore(&task->task_state_lock, flags);
+	if (task->task_proto & SAS_PROTOCOL_SSP) {
+		struct scsi_cmnd *cmnd = task->uldd_task;
+		dev = task->dev;
+		ccb = task->lldd_task;
+		pm8001_dev = dev->lldd_dev;
+		pm8001_ha = pm8001_find_ha_by_dev(dev);
+		int_to_scsilun(cmnd->device->lun, &lun);
+		rc = pm8001_find_tag(task, &tag);
+		if (rc == 0) {
+			printk(KERN_INFO "No such tag in %s\n", __func__);
+			rc = TMF_RESP_FUNC_FAILED;
+			return rc;
+		}
+		device_id = pm8001_dev->device_id;
+		PM8001_EH_DBG(pm8001_ha,
+			pm8001_printk("abort io to deviceid= %d\n", device_id));
+		tmf_task.tmf = TMF_ABORT_TASK;
+		tmf_task.tag_of_task_to_be_managed = tag;
+		rc = pm8001_issue_ssp_tmf(dev, lun.scsi_lun, &tmf_task);
+		pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev,
+			pm8001_dev->sas_device, 0, tag);
+	} else if (task->task_proto & SAS_PROTOCOL_SATA ||
+		task->task_proto & SAS_PROTOCOL_STP) {
+		dev = task->dev;
+		pm8001_dev = dev->lldd_dev;
+		pm8001_ha = pm8001_find_ha_by_dev(dev);
+		rc = pm8001_find_tag(task, &tag);
+		if (rc == 0) {
+			printk(KERN_INFO "No such tag in %s\n", __func__);
+			rc = TMF_RESP_FUNC_FAILED;
+			return rc;
+		}
+		rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev,
+			pm8001_dev->sas_device, 0, tag);
+	} else if (task->task_proto & SAS_PROTOCOL_SMP) {
+		/* SMP */
+		dev = task->dev;
+		pm8001_dev = dev->lldd_dev;
+		pm8001_ha = pm8001_find_ha_by_dev(dev);
+		rc = pm8001_find_tag(task, &tag);
+		if (rc == 0) {
+			printk(KERN_INFO "No such tag in %s\n", __func__);
+			rc = TMF_RESP_FUNC_FAILED;
+			return rc;
+		}
+		rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev,
+			pm8001_dev->sas_device, 0, tag);
+
+	}
+out:
+	if (rc != TMF_RESP_FUNC_COMPLETE)
+		pm8001_printk("rc= %d\n", rc);
+	return rc;
+}
+
+int pm8001_abort_task_set(struct domain_device *dev, u8 *lun)
+{
+	int rc = TMF_RESP_FUNC_FAILED;
+	struct pm8001_tmf_task tmf_task;
+
+	tmf_task.tmf = TMF_ABORT_TASK_SET;
+	rc = pm8001_issue_ssp_tmf(dev, lun, &tmf_task);
+	return rc;
+}
+
+int pm8001_clear_aca(struct domain_device *dev, u8 *lun)
+{
+	int rc = TMF_RESP_FUNC_FAILED;
+	struct pm8001_tmf_task tmf_task;
+
+	tmf_task.tmf = TMF_CLEAR_ACA;
+	rc = pm8001_issue_ssp_tmf(dev, lun, &tmf_task);
+
+	return rc;
+}
+
+int pm8001_clear_task_set(struct domain_device *dev, u8 *lun)
+{
+	int rc = TMF_RESP_FUNC_FAILED;
+	struct pm8001_tmf_task tmf_task;
+	struct pm8001_device *pm8001_dev = dev->lldd_dev;
+	struct pm8001_hba_info *pm8001_ha = pm8001_find_ha_by_dev(dev);
+
+	PM8001_EH_DBG(pm8001_ha,
+		pm8001_printk("I_T_L_Q clear task set[%x]\n",
+		pm8001_dev->device_id));
+	tmf_task.tmf = TMF_CLEAR_TASK_SET;
+	rc = pm8001_issue_ssp_tmf(dev, lun, &tmf_task);
+	return rc;
+}
+
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
new file mode 100644
index 0000000..30f2ede
--- /dev/null
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -0,0 +1,481 @@
+/*
+ * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver
+ *
+ * Copyright (c) 2008-2009 USI Co., Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+#ifndef _PM8001_SAS_H_
+#define _PM8001_SAS_H_
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/ctype.h>
+#include <linux/dma-mapping.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/smp_lock.h>
+#include <scsi/libsas.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/sas_ata.h>
+#include <asm/atomic.h>
+#include "pm8001_defs.h"
+
+#define DRV_NAME		"pm8001"
+#define DRV_VERSION		"0.1.36"
+#define PM8001_FAIL_LOGGING	0x01 /* libsas EH function logging */
+#define PM8001_INIT_LOGGING	0x02 /* driver init logging */
+#define PM8001_DISC_LOGGING	0x04 /* discovery layer logging */
+#define PM8001_IO_LOGGING	0x08 /* I/O path logging */
+#define PM8001_EH_LOGGING	0x10 /* Error message logging */
+#define PM8001_IOCTL_LOGGING	0x20 /* IOCTL message logging */
+#define PM8001_MSG_LOGGING	0x40 /* misc message logging */
+#define pm8001_printk(format, arg...)	printk(KERN_INFO "%s %d:" format,\
+				__func__, __LINE__, ## arg)
+#define PM8001_CHECK_LOGGING(HBA, LEVEL, CMD)	\
+do {						\
+	if (unlikely(HBA->logging_level & LEVEL))	\
+		do {					\
+			CMD;				\
+		} while (0);				\
+} while (0);
+
+#define PM8001_EH_DBG(HBA, CMD)			\
+	PM8001_CHECK_LOGGING(HBA, PM8001_EH_LOGGING, CMD)
+
+#define PM8001_INIT_DBG(HBA, CMD)		\
+	PM8001_CHECK_LOGGING(HBA, PM8001_INIT_LOGGING, CMD)
+
+#define PM8001_DISC_DBG(HBA, CMD)		\
+	PM8001_CHECK_LOGGING(HBA, PM8001_DISC_LOGGING, CMD)
+
+#define PM8001_IO_DBG(HBA, CMD)		\
+	PM8001_CHECK_LOGGING(HBA, PM8001_IO_LOGGING, CMD)
+
+#define PM8001_FAIL_DBG(HBA, CMD)		\
+	PM8001_CHECK_LOGGING(HBA, PM8001_FAIL_LOGGING, CMD)
+
+#define PM8001_IOCTL_DBG(HBA, CMD)		\
+	PM8001_CHECK_LOGGING(HBA, PM8001_IOCTL_LOGGING, CMD)
+
+#define PM8001_MSG_DBG(HBA, CMD)		\
+	PM8001_CHECK_LOGGING(HBA, PM8001_MSG_LOGGING, CMD)
+
+
+#define PM8001_USE_TASKLET
+#define PM8001_USE_MSIX
+
+
+#define DEV_IS_EXPANDER(type)	((type == EDGE_DEV) || (type == FANOUT_DEV))
+
+#define PM8001_NAME_LENGTH		32/* generic length of strings */
+extern struct list_head hba_list;
+extern const struct pm8001_dispatch pm8001_8001_dispatch;
+
+struct pm8001_hba_info;
+struct pm8001_ccb_info;
+struct pm8001_device;
+struct pm8001_tmf_task;
+struct pm8001_dispatch {
+	char *name;
+	int (*chip_init)(struct pm8001_hba_info *pm8001_ha);
+	int (*chip_soft_rst)(struct pm8001_hba_info *pm8001_ha, u32 signature);
+	void (*chip_rst)(struct pm8001_hba_info *pm8001_ha);
+	int (*chip_ioremap)(struct pm8001_hba_info *pm8001_ha);
+	void (*chip_iounmap)(struct pm8001_hba_info *pm8001_ha);
+	irqreturn_t (*isr)(struct pm8001_hba_info *pm8001_ha);
+	u32 (*is_our_interupt)(struct pm8001_hba_info *pm8001_ha);
+	int (*isr_process_oq)(struct pm8001_hba_info *pm8001_ha);
+	void (*interrupt_enable)(struct pm8001_hba_info *pm8001_ha);
+	void (*interrupt_disable)(struct pm8001_hba_info *pm8001_ha);
+	void (*make_prd)(struct scatterlist *scatter, int nr, void *prd);
+	int (*smp_req)(struct pm8001_hba_info *pm8001_ha,
+		struct pm8001_ccb_info *ccb);
+	int (*ssp_io_req)(struct pm8001_hba_info *pm8001_ha,
+		struct pm8001_ccb_info *ccb);
+	int (*sata_req)(struct pm8001_hba_info *pm8001_ha,
+		struct pm8001_ccb_info *ccb);
+	int (*phy_start_req)(struct pm8001_hba_info *pm8001_ha,	u8 phy_id);
+	int (*phy_stop_req)(struct pm8001_hba_info *pm8001_ha, u8 phy_id);
+	int (*reg_dev_req)(struct pm8001_hba_info *pm8001_ha,
+		struct pm8001_device *pm8001_dev, u32 flag);
+	int (*dereg_dev_req)(struct pm8001_hba_info *pm8001_ha, u32 device_id);
+	int (*phy_ctl_req)(struct pm8001_hba_info *pm8001_ha,
+		u32 phy_id, u32 phy_op);
+	int (*task_abort)(struct pm8001_hba_info *pm8001_ha,
+		struct pm8001_device *pm8001_dev, u8 flag, u32 task_tag,
+		u32 cmd_tag);
+	int (*ssp_tm_req)(struct pm8001_hba_info *pm8001_ha,
+		struct pm8001_ccb_info *ccb, struct pm8001_tmf_task *tmf);
+	int (*get_nvmd_req)(struct pm8001_hba_info *pm8001_ha, void *payload);
+	int (*set_nvmd_req)(struct pm8001_hba_info *pm8001_ha, void *payload);
+	int (*fw_flash_update_req)(struct pm8001_hba_info *pm8001_ha,
+		void *payload);
+	int (*set_dev_state_req)(struct pm8001_hba_info *pm8001_ha,
+		struct pm8001_device *pm8001_dev, u32 state);
+	int (*sas_diag_start_end_req)(struct pm8001_hba_info *pm8001_ha,
+		u32 state);
+	int (*sas_diag_execute_req)(struct pm8001_hba_info *pm8001_ha,
+		u32 state);
+	int (*sas_re_init_req)(struct pm8001_hba_info *pm8001_ha);
+};
+
+struct pm8001_chip_info {
+	u32	n_phy;
+	const struct pm8001_dispatch	*dispatch;
+};
+#define PM8001_CHIP_DISP	(pm8001_ha->chip->dispatch)
+
+struct pm8001_port {
+	struct asd_sas_port	sas_port;
+};
+
+struct pm8001_phy {
+	struct pm8001_hba_info	*pm8001_ha;
+	struct pm8001_port	*port;
+	struct asd_sas_phy	sas_phy;
+	struct sas_identify	identify;
+	struct scsi_device	*sdev;
+	u64			dev_sas_addr;
+	u32			phy_type;
+	struct completion	*enable_completion;
+	u32			frame_rcvd_size;
+	u8			frame_rcvd[32];
+	u8			phy_attached;
+	u8			phy_state;
+	enum sas_linkrate	minimum_linkrate;
+	enum sas_linkrate	maximum_linkrate;
+};
+
+struct pm8001_device {
+	enum sas_dev_type	dev_type;
+	struct domain_device	*sas_device;
+	u32			attached_phy;
+	u32			id;
+	struct completion	*dcompletion;
+	struct completion	*setds_completion;
+	u32			device_id;
+	u32			running_req;
+};
+
+struct pm8001_prd_imt {
+	__le32			len;
+	__le32			e;
+};
+
+struct pm8001_prd {
+	__le64			addr;		/* 64-bit buffer address */
+	struct pm8001_prd_imt	im_len;		/* 64-bit length */
+} __attribute__ ((packed));
+/*
+ * CCB(Command Control Block)
+ */
+struct pm8001_ccb_info {
+	struct list_head	entry;
+	struct sas_task		*task;
+	u32			n_elem;
+	u32			ccb_tag;
+	dma_addr_t		ccb_dma_handle;
+	struct pm8001_device	*device;
+	struct pm8001_prd	buf_prd[PM8001_MAX_DMA_SG];
+	struct fw_control_ex	*fw_control_context;
+};
+
+struct mpi_mem {
+	void			*virt_ptr;
+	dma_addr_t		phys_addr;
+	u32			phys_addr_hi;
+	u32			phys_addr_lo;
+	u32			total_len;
+	u32			num_elements;
+	u32			element_size;
+	u32			alignment;
+};
+
+struct mpi_mem_req {
+	/* The number of element in the  mpiMemory array */
+	u32			count;
+	/* The array of structures that define memroy regions*/
+	struct mpi_mem		region[USI_MAX_MEMCNT];
+};
+
+struct main_cfg_table {
+	u32			signature;
+	u32			interface_rev;
+	u32			firmware_rev;
+	u32			max_out_io;
+	u32			max_sgl;
+	u32			ctrl_cap_flag;
+	u32			gst_offset;
+	u32			inbound_queue_offset;
+	u32			outbound_queue_offset;
+	u32			inbound_q_nppd_hppd;
+	u32			outbound_hw_event_pid0_3;
+	u32			outbound_hw_event_pid4_7;
+	u32			outbound_ncq_event_pid0_3;
+	u32			outbound_ncq_event_pid4_7;
+	u32			outbound_tgt_ITNexus_event_pid0_3;
+	u32			outbound_tgt_ITNexus_event_pid4_7;
+	u32			outbound_tgt_ssp_event_pid0_3;
+	u32			outbound_tgt_ssp_event_pid4_7;
+	u32			outbound_tgt_smp_event_pid0_3;
+	u32			outbound_tgt_smp_event_pid4_7;
+	u32			upper_event_log_addr;
+	u32			lower_event_log_addr;
+	u32			event_log_size;
+	u32			event_log_option;
+	u32			upper_iop_event_log_addr;
+	u32			lower_iop_event_log_addr;
+	u32			iop_event_log_size;
+	u32			iop_event_log_option;
+	u32			fatal_err_interrupt;
+	u32			fatal_err_dump_offset0;
+	u32			fatal_err_dump_length0;
+	u32			fatal_err_dump_offset1;
+	u32			fatal_err_dump_length1;
+	u32			hda_mode_flag;
+	u32			anolog_setup_table_offset;
+};
+struct general_status_table {
+	u32			gst_len_mpistate;
+	u32			iq_freeze_state0;
+	u32			iq_freeze_state1;
+	u32			msgu_tcnt;
+	u32			iop_tcnt;
+	u32			reserved;
+	u32			phy_state[8];
+	u32			reserved1;
+	u32			reserved2;
+	u32			reserved3;
+	u32			recover_err_info[8];
+};
+struct inbound_queue_table {
+	u32			element_pri_size_cnt;
+	u32			upper_base_addr;
+	u32			lower_base_addr;
+	u32			ci_upper_base_addr;
+	u32			ci_lower_base_addr;
+	u32			pi_pci_bar;
+	u32			pi_offset;
+	u32			total_length;
+	void			*base_virt;
+	void			*ci_virt;
+	u32			reserved;
+	__le32			consumer_index;
+	u32			producer_idx;
+};
+struct outbound_queue_table {
+	u32			element_size_cnt;
+	u32			upper_base_addr;
+	u32			lower_base_addr;
+	void			*base_virt;
+	u32			pi_upper_base_addr;
+	u32			pi_lower_base_addr;
+	u32			ci_pci_bar;
+	u32			ci_offset;
+	u32			total_length;
+	void			*pi_virt;
+	u32			interrup_vec_cnt_delay;
+	u32			dinterrup_to_pci_offset;
+	__le32			producer_index;
+	u32			consumer_idx;
+};
+struct pm8001_hba_memspace {
+	void __iomem  		*memvirtaddr;
+	u64			membase;
+	u32			memsize;
+};
+struct pm8001_hba_info {
+	char			name[PM8001_NAME_LENGTH];
+	struct list_head	list;
+	unsigned long		flags;
+	spinlock_t		lock;/* host-wide lock */
+	struct pci_dev		*pdev;/* our device */
+	struct device		*dev;
+	struct pm8001_hba_memspace io_mem[6];
+	struct mpi_mem_req	memoryMap;
+	void __iomem	*msg_unit_tbl_addr;/*Message Unit Table Addr*/
+	void __iomem	*main_cfg_tbl_addr;/*Main Config Table Addr*/
+	void __iomem	*general_stat_tbl_addr;/*General Status Table Addr*/
+	void __iomem	*inbnd_q_tbl_addr;/*Inbound Queue Config Table Addr*/
+	void __iomem	*outbnd_q_tbl_addr;/*Outbound Queue Config Table Addr*/
+	struct main_cfg_table	main_cfg_tbl;
+	struct general_status_table	gs_tbl;
+	struct inbound_queue_table	inbnd_q_tbl[PM8001_MAX_INB_NUM];
+	struct outbound_queue_table	outbnd_q_tbl[PM8001_MAX_OUTB_NUM];
+	u8			sas_addr[SAS_ADDR_SIZE];
+	struct sas_ha_struct	*sas;/* SCSI/SAS glue */
+	struct Scsi_Host	*shost;
+	u32			chip_id;
+	const struct pm8001_chip_info	*chip;
+	struct completion	*nvmd_completion;
+	int			tags_num;
+	unsigned long		*tags;
+	struct pm8001_phy	phy[PM8001_MAX_PHYS];
+	struct pm8001_port	port[PM8001_MAX_PHYS];
+	u32			id;
+	u32			irq;
+	struct pm8001_device	*devices;
+	struct pm8001_ccb_info	*ccb_info;
+#ifdef PM8001_USE_MSIX
+	struct msix_entry	msix_entries[16];/*for msi-x interrupt*/
+	int			number_of_intr;/*will be used in remove()*/
+#endif
+#ifdef PM8001_USE_TASKLET
+	struct tasklet_struct	tasklet;
+#endif
+	struct list_head 	wq_list;
+	u32			logging_level;
+	u32			fw_status;
+	const struct firmware 	*fw_image;
+};
+
+struct pm8001_wq {
+	struct delayed_work work_q;
+	struct pm8001_hba_info *pm8001_ha;
+	void *data;
+	int handler;
+	struct list_head entry;
+};
+
+struct pm8001_fw_image_header {
+	u8 vender_id[8];
+	u8 product_id;
+	u8 hardware_rev;
+	u8 dest_partition;
+	u8 reserved;
+	u8 fw_rev[4];
+	__be32  image_length;
+	__be32 image_crc;
+	__be32 startup_entry;
+} __attribute__((packed, aligned(4)));
+
+/* define task management IU */
+struct pm8001_tmf_task {
+	u8	tmf;
+	u32	tag_of_task_to_be_managed;
+};
+/**
+ * FW Flash Update status values
+ */
+#define FLASH_UPDATE_COMPLETE_PENDING_REBOOT	0x00
+#define FLASH_UPDATE_IN_PROGRESS		0x01
+#define FLASH_UPDATE_HDR_ERR			0x02
+#define FLASH_UPDATE_OFFSET_ERR			0x03
+#define FLASH_UPDATE_CRC_ERR			0x04
+#define FLASH_UPDATE_LENGTH_ERR			0x05
+#define FLASH_UPDATE_HW_ERR			0x06
+#define FLASH_UPDATE_DNLD_NOT_SUPPORTED		0x10
+#define FLASH_UPDATE_DISABLED			0x11
+
+/**
+ * brief param structure for firmware flash update.
+ */
+struct fw_flash_updata_info {
+	u32			cur_image_offset;
+	u32			cur_image_len;
+	u32			total_image_len;
+	struct pm8001_prd	sgl;
+};
+
+struct fw_control_info {
+	u32			retcode;/*ret code (status)*/
+	u32			phase;/*ret code phase*/
+	u32			phaseCmplt;/*percent complete for the current
+	update phase */
+	u32			version;/*Hex encoded firmware version number*/
+	u32			offset;/*Used for downloading firmware	*/
+	u32			len; /*len of buffer*/
+	u32			size;/* Used in OS VPD and Trace get size
+	operations.*/
+	u32			reserved;/* padding required for 64 bit
+	alignment */
+	u8			buffer[1];/* Start of buffer */
+};
+struct fw_control_ex {
+	struct fw_control_info *fw_control;
+	void			*buffer;/* keep buffer pointer to be
+	freed when the responce comes*/
+	void			*virtAddr;/* keep virtual address of the data */
+	void			*usrAddr;/* keep virtual address of the
+	user data */
+	dma_addr_t		phys_addr;
+	u32			len; /* len of buffer  */
+	void			*payload; /* pointer to IOCTL Payload */
+	u8			inProgress;/*if 1 - the IOCTL request is in
+	progress */
+	void			*param1;
+	void			*param2;
+	void			*param3;
+};
+
+/******************** function prototype *********************/
+int pm8001_tag_alloc(struct pm8001_hba_info *pm8001_ha, u32 *tag_out);
+void pm8001_tag_init(struct pm8001_hba_info *pm8001_ha);
+u32 pm8001_get_ncq_tag(struct sas_task *task, u32 *tag);
+void pm8001_ccb_free(struct pm8001_hba_info *pm8001_ha, u32 ccb_idx);
+void pm8001_ccb_task_free(struct pm8001_hba_info *pm8001_ha,
+	struct sas_task *task, struct pm8001_ccb_info *ccb, u32 ccb_idx);
+int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
+	void *funcdata);
+int pm8001_slave_alloc(struct scsi_device *scsi_dev);
+int pm8001_slave_configure(struct scsi_device *sdev);
+void pm8001_scan_start(struct Scsi_Host *shost);
+int pm8001_scan_finished(struct Scsi_Host *shost, unsigned long time);
+int pm8001_queue_command(struct sas_task *task, const int num,
+	gfp_t gfp_flags);
+int pm8001_abort_task(struct sas_task *task);
+int pm8001_abort_task_set(struct domain_device *dev, u8 *lun);
+int pm8001_clear_aca(struct domain_device *dev, u8 *lun);
+int pm8001_clear_task_set(struct domain_device *dev, u8 *lun);
+int pm8001_dev_found(struct domain_device *dev);
+void pm8001_dev_gone(struct domain_device *dev);
+int pm8001_lu_reset(struct domain_device *dev, u8 *lun);
+int pm8001_I_T_nexus_reset(struct domain_device *dev);
+int pm8001_query_task(struct sas_task *task);
+int pm8001_mem_alloc(struct pci_dev *pdev, void **virt_addr,
+	dma_addr_t *pphys_addr, u32 *pphys_addr_hi, u32 *pphys_addr_lo,
+	u32 mem_size, u32 align);
+
+
+/* ctl shared API */
+extern struct device_attribute *pm8001_host_attrs[];
+
+#endif
+
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index 0a97bc9..34c6b89 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -278,12 +278,17 @@
  * pmcraid_change_queue_depth - Change the device's queue depth
  * @scsi_dev: scsi device struct
  * @depth: depth to set
+ * @reason: calling context
  *
  * Return value
  * 	actual depth set
  */
-static int pmcraid_change_queue_depth(struct scsi_device *scsi_dev, int depth)
+static int pmcraid_change_queue_depth(struct scsi_device *scsi_dev, int depth,
+				      int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (depth > PMCRAID_MAX_CMD_PER_LUN)
 		depth = PMCRAID_MAX_CMD_PER_LUN;
 
@@ -3342,7 +3347,7 @@
  * @direction : data transfer direction
  *
  * Return value
- *  0 on sucess, non-zero error code on failure
+ *  0 on success, non-zero error code on failure
  */
 static int pmcraid_build_passthrough_ioadls(
 	struct pmcraid_cmd *cmd,
@@ -3401,7 +3406,7 @@
  * @direction: data transfer direction
  *
  * Return value
- *  0 on sucess, non-zero error code on failure
+ *  0 on success, non-zero error code on failure
  */
 static void pmcraid_release_passthrough_ioadls(
 	struct pmcraid_cmd *cmd,
@@ -3429,7 +3434,7 @@
  * @arg: pointer to pmcraid_passthrough_buffer user buffer
  *
  * Return value
- *  0 on sucess, non-zero error code on failure
+ *  0 on success, non-zero error code on failure
  */
 static long pmcraid_ioctl_passthrough(
 	struct pmcraid_instance *pinstance,
diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h
index 3441b3f..2752b56 100644
--- a/drivers/scsi/pmcraid.h
+++ b/drivers/scsi/pmcraid.h
@@ -771,11 +771,11 @@
 	{0x01180600, IOASC_LOG_LEVEL_MUST,
 	 "Recovered Error, soft media error, sector reassignment suggested"},
 	{0x015D0000, IOASC_LOG_LEVEL_MUST,
-	 "Recovered Error, failure prediction thresold exceeded"},
+	 "Recovered Error, failure prediction threshold exceeded"},
 	{0x015D9200, IOASC_LOG_LEVEL_MUST,
-	 "Recovered Error, soft Cache Card Battery error thresold"},
+	 "Recovered Error, soft Cache Card Battery error threshold"},
 	{0x015D9200, IOASC_LOG_LEVEL_MUST,
-	 "Recovered Error, soft Cache Card Battery error thresold"},
+	 "Recovered Error, soft Cache Card Battery error threshold"},
 	{0x02048000, IOASC_LOG_LEVEL_MUST,
 	 "Not Ready, IOA Reset Required"},
 	{0x02408500, IOASC_LOG_LEVEL_MUST,
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index fbcb82a..21e2bc4 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -1654,7 +1654,8 @@
 			fc_vport_set_state(fc_vport, FC_VPORT_LINKDOWN);
 	}
 
-	if (scsi_add_host(vha->host, &fc_vport->dev)) {
+	if (scsi_add_host_with_dma(vha->host, &fc_vport->dev,
+				   &ha->pdev->dev)) {
 		DEBUG15(printk("scsi(%ld): scsi_add_host failure for VP[%d].\n",
 			vha->host_no, vha->vp_idx));
 		goto vport_create_failed_2;
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index cca8e4a..cb2eca4 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -377,6 +377,24 @@
 	return ptr + sizeof(struct qla2xxx_mq_chain);
 }
 
+static void
+qla2xxx_dump_post_process(scsi_qla_host_t *vha, int rval)
+{
+	struct qla_hw_data *ha = vha->hw;
+
+	if (rval != QLA_SUCCESS) {
+		qla_printk(KERN_WARNING, ha,
+		    "Failed to dump firmware (%x)!!!\n", rval);
+		ha->fw_dumped = 0;
+	} else {
+		qla_printk(KERN_INFO, ha,
+		    "Firmware dump saved to temp buffer (%ld/%p).\n",
+		    vha->host_no, ha->fw_dump);
+		ha->fw_dumped = 1;
+		qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
+	}
+}
+
 /**
  * qla2300_fw_dump() - Dumps binary data from the 2300 firmware.
  * @ha: HA context
@@ -530,17 +548,7 @@
 	if (rval == QLA_SUCCESS)
 		qla2xxx_copy_queues(ha, nxt);
 
-	if (rval != QLA_SUCCESS) {
-		qla_printk(KERN_WARNING, ha,
-		    "Failed to dump firmware (%x)!!!\n", rval);
-		ha->fw_dumped = 0;
-
-	} else {
-		qla_printk(KERN_INFO, ha,
-		    "Firmware dump saved to temp buffer (%ld/%p).\n",
-		    base_vha->host_no, ha->fw_dump);
-		ha->fw_dumped = 1;
-	}
+	qla2xxx_dump_post_process(base_vha, rval);
 
 qla2300_fw_dump_failed:
 	if (!hardware_locked)
@@ -737,17 +745,7 @@
 	if (rval == QLA_SUCCESS)
 		qla2xxx_copy_queues(ha, &fw->risc_ram[cnt]);
 
-	if (rval != QLA_SUCCESS) {
-		qla_printk(KERN_WARNING, ha,
-		    "Failed to dump firmware (%x)!!!\n", rval);
-		ha->fw_dumped = 0;
-
-	} else {
-		qla_printk(KERN_INFO, ha,
-		    "Firmware dump saved to temp buffer (%ld/%p).\n",
-		    base_vha->host_no, ha->fw_dump);
-		ha->fw_dumped = 1;
-	}
+	qla2xxx_dump_post_process(base_vha, rval);
 
 qla2100_fw_dump_failed:
 	if (!hardware_locked)
@@ -984,17 +982,7 @@
 	qla24xx_copy_eft(ha, nxt);
 
 qla24xx_fw_dump_failed_0:
-	if (rval != QLA_SUCCESS) {
-		qla_printk(KERN_WARNING, ha,
-		    "Failed to dump firmware (%x)!!!\n", rval);
-		ha->fw_dumped = 0;
-
-	} else {
-		qla_printk(KERN_INFO, ha,
-		    "Firmware dump saved to temp buffer (%ld/%p).\n",
-		    base_vha->host_no, ha->fw_dump);
-		ha->fw_dumped = 1;
-	}
+	qla2xxx_dump_post_process(base_vha, rval);
 
 qla24xx_fw_dump_failed:
 	if (!hardware_locked)
@@ -1305,17 +1293,7 @@
 	}
 
 qla25xx_fw_dump_failed_0:
-	if (rval != QLA_SUCCESS) {
-		qla_printk(KERN_WARNING, ha,
-		    "Failed to dump firmware (%x)!!!\n", rval);
-		ha->fw_dumped = 0;
-
-	} else {
-		qla_printk(KERN_INFO, ha,
-		    "Firmware dump saved to temp buffer (%ld/%p).\n",
-		    base_vha->host_no, ha->fw_dump);
-		ha->fw_dumped = 1;
-	}
+	qla2xxx_dump_post_process(base_vha, rval);
 
 qla25xx_fw_dump_failed:
 	if (!hardware_locked)
@@ -1628,17 +1606,7 @@
 	}
 
 qla81xx_fw_dump_failed_0:
-	if (rval != QLA_SUCCESS) {
-		qla_printk(KERN_WARNING, ha,
-		    "Failed to dump firmware (%x)!!!\n", rval);
-		ha->fw_dumped = 0;
-
-	} else {
-		qla_printk(KERN_INFO, ha,
-		    "Firmware dump saved to temp buffer (%ld/%p).\n",
-		    base_vha->host_no, ha->fw_dump);
-		ha->fw_dumped = 1;
-	}
+	qla2xxx_dump_post_process(base_vha, rval);
 
 qla81xx_fw_dump_failed:
 	if (!hardware_locked)
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 2150618..6b9bf23 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2123,6 +2123,7 @@
 	QLA_EVT_ASYNC_LOGIN_DONE,
 	QLA_EVT_ASYNC_LOGOUT,
 	QLA_EVT_ASYNC_LOGOUT_DONE,
+	QLA_EVT_UEVENT,
 };
 
 
@@ -2146,6 +2147,10 @@
 #define QLA_LOGIO_LOGIN_RETRIED	BIT_0
 			u16 data[2];
 		} logio;
+		struct {
+			u32 code;
+#define QLA_UEVENT_CODE_FW_DUMP	0
+		} uevent;
 	} u;
 };
 
@@ -2435,11 +2440,11 @@
 	dma_addr_t	edc_data_dma;
 	uint16_t	edc_data_len;
 
-#define XGMAC_DATA_SIZE	PAGE_SIZE
+#define XGMAC_DATA_SIZE	4096
 	void		*xgmac_data;
 	dma_addr_t	xgmac_data_dma;
 
-#define DCBX_TLV_DATA_SIZE PAGE_SIZE
+#define DCBX_TLV_DATA_SIZE 4096
 	void		*dcbx_tlv;
 	dma_addr_t	dcbx_tlv_dma;
 
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index f3d1d1a..e218513 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -92,6 +92,7 @@
     uint16_t *);
 extern int qla2x00_post_async_logout_done_work(struct scsi_qla_host *,
     fc_port_t *, uint16_t *);
+extern int qla2x00_post_uevent_work(struct scsi_qla_host *, u32);
 
 extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *);
 
@@ -246,7 +247,7 @@
 
 extern int
 qla2x00_get_resource_cnts(scsi_qla_host_t *, uint16_t *, uint16_t *,
-    uint16_t *, uint16_t *, uint16_t *);
+    uint16_t *, uint16_t *, uint16_t *, uint16_t *);
 
 extern int
 qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map);
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 9e3eaac..b74924b 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -277,7 +277,6 @@
 	vha->marker_needed = 0;
 	ha->isp_abort_cnt = 0;
 	ha->beacon_blink_led = 0;
-	set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
 
 	set_bit(0, ha->req_qid_map);
 	set_bit(0, ha->rsp_qid_map);
@@ -1203,7 +1202,7 @@
 				}
 				qla2x00_get_resource_cnts(vha, NULL,
 				    &ha->fw_xcb_count, NULL, NULL,
-				    &ha->max_npiv_vports);
+				    &ha->max_npiv_vports, NULL);
 
 				if (!fw_major_version && ql2xallocfwdump)
 					qla2x00_alloc_fw_dump(vha);
@@ -3573,6 +3572,15 @@
 			ha->isp_abort_cnt = 0;
 			clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
 
+			if (IS_QLA81XX(ha))
+				qla2x00_get_fw_version(vha,
+				    &ha->fw_major_version,
+				    &ha->fw_minor_version,
+				    &ha->fw_subminor_version,
+				    &ha->fw_attributes, &ha->fw_memory_size,
+				    ha->mpi_version, &ha->mpi_capabilities,
+				    ha->phy_version);
+
 			if (ha->fce) {
 				ha->flags.fce_enabled = 1;
 				memset(ha->fce, 0,
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index b20a716..8049873 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -313,10 +313,11 @@
 	static char	*link_speeds[] = { "1", "2", "?", "4", "8", "10" };
 	char		*link_speed;
 	uint16_t	handle_cnt;
-	uint16_t	cnt;
+	uint16_t	cnt, mbx;
 	uint32_t	handles[5];
 	struct qla_hw_data *ha = vha->hw;
 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+	struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24;
 	uint32_t	rscn_entry, host_pid;
 	uint8_t		rscn_queue_index;
 	unsigned long	flags;
@@ -395,9 +396,10 @@
 		break;
 
 	case MBA_SYSTEM_ERR:		/* System Error */
+		mbx = IS_QLA81XX(ha) ? RD_REG_WORD(&reg24->mailbox7) : 0;
 		qla_printk(KERN_INFO, ha,
-		    "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n",
-		    mb[1], mb[2], mb[3]);
+		    "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh "
+		    "mbx7=%xh.\n", mb[1], mb[2], mb[3], mbx);
 
 		ha->isp_ops->fw_dump(vha, 1);
 
@@ -419,9 +421,10 @@
 		break;
 
 	case MBA_REQ_TRANSFER_ERR:	/* Request Transfer Error */
-		DEBUG2(printk("scsi(%ld): ISP Request Transfer Error.\n",
-		    vha->host_no));
-		qla_printk(KERN_WARNING, ha, "ISP Request Transfer Error.\n");
+		DEBUG2(printk("scsi(%ld): ISP Request Transfer Error (%x).\n",
+		    vha->host_no, mb[1]));
+		qla_printk(KERN_WARNING, ha,
+		    "ISP Request Transfer Error (%x).\n", mb[1]);
 
 		set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
 		break;
@@ -485,10 +488,13 @@
 		break;
 
 	case MBA_LOOP_DOWN:		/* Loop Down Event */
+		mbx = IS_QLA81XX(ha) ? RD_REG_WORD(&reg24->mailbox4) : 0;
 		DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN "
-		    "(%x %x %x).\n", vha->host_no, mb[1], mb[2], mb[3]));
-		qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x %x %x).\n",
-		    mb[1], mb[2], mb[3]);
+		    "(%x %x %x %x).\n", vha->host_no, mb[1], mb[2], mb[3],
+		    mbx));
+		qla_printk(KERN_INFO, ha,
+		    "LOOP DOWN detected (%x %x %x %x).\n", mb[1], mb[2], mb[3],
+		    mbx);
 
 		if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
 			atomic_set(&vha->loop_state, LOOP_DOWN);
@@ -1347,16 +1353,22 @@
 
 	sense_len = rsp_info_len = resid_len = fw_resid_len = 0;
 	if (IS_FWI2_CAPABLE(ha)) {
-		sense_len = le32_to_cpu(sts24->sense_len);
-		rsp_info_len = le32_to_cpu(sts24->rsp_data_len);
-		resid_len = le32_to_cpu(sts24->rsp_residual_count);
-		fw_resid_len = le32_to_cpu(sts24->residual_len);
+		if (scsi_status & SS_SENSE_LEN_VALID)
+			sense_len = le32_to_cpu(sts24->sense_len);
+		if (scsi_status & SS_RESPONSE_INFO_LEN_VALID)
+			rsp_info_len = le32_to_cpu(sts24->rsp_data_len);
+		if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER))
+			resid_len = le32_to_cpu(sts24->rsp_residual_count);
+		if (comp_status == CS_DATA_UNDERRUN)
+			fw_resid_len = le32_to_cpu(sts24->residual_len);
 		rsp_info = sts24->data;
 		sense_data = sts24->data;
 		host_to_fcp_swap(sts24->data, sizeof(sts24->data));
 	} else {
-		sense_len = le16_to_cpu(sts->req_sense_length);
-		rsp_info_len = le16_to_cpu(sts->rsp_info_len);
+		if (scsi_status & SS_SENSE_LEN_VALID)
+			sense_len = le16_to_cpu(sts->req_sense_length);
+		if (scsi_status & SS_RESPONSE_INFO_LEN_VALID)
+			rsp_info_len = le16_to_cpu(sts->rsp_info_len);
 		resid_len = le32_to_cpu(sts->residual_length);
 		rsp_info = sts->rsp_info;
 		sense_data = sts->req_sense_data;
@@ -1443,38 +1455,62 @@
 		break;
 
 	case CS_DATA_UNDERRUN:
-		resid = resid_len;
+		DEBUG2(printk(KERN_INFO
+		    "scsi(%ld:%d:%d) UNDERRUN status detected 0x%x-0x%x. "
+		    "resid=0x%x fw_resid=0x%x cdb=0x%x os_underflow=0x%x\n",
+		    vha->host_no, cp->device->id, cp->device->lun, comp_status,
+		    scsi_status, resid_len, fw_resid_len, cp->cmnd[0],
+		    cp->underflow));
+
 		/* Use F/W calculated residual length. */
-		if (IS_FWI2_CAPABLE(ha)) {
-			if (!(scsi_status & SS_RESIDUAL_UNDER)) {
-				lscsi_status = 0;
-			} else if (resid != fw_resid_len) {
-				scsi_status &= ~SS_RESIDUAL_UNDER;
-				lscsi_status = 0;
-			}
-			resid = fw_resid_len;
-		}
-
+		resid = IS_FWI2_CAPABLE(ha) ? fw_resid_len : resid_len;
+		scsi_set_resid(cp, resid);
 		if (scsi_status & SS_RESIDUAL_UNDER) {
-			scsi_set_resid(cp, resid);
-		} else {
-			DEBUG2(printk(KERN_INFO
-			    "scsi(%ld:%d:%d) UNDERRUN status detected "
-			    "0x%x-0x%x. resid=0x%x fw_resid=0x%x cdb=0x%x "
-			    "os_underflow=0x%x\n", vha->host_no,
-			    cp->device->id, cp->device->lun, comp_status,
-			    scsi_status, resid_len, resid, cp->cmnd[0],
-			    cp->underflow));
+			if (IS_FWI2_CAPABLE(ha) && fw_resid_len != resid_len) {
+				DEBUG2(printk(
+				    "scsi(%ld:%d:%d:%d) Dropped frame(s) "
+				    "detected (%x of %x bytes)...residual "
+				    "length mismatch...retrying command.\n",
+				    vha->host_no, cp->device->channel,
+				    cp->device->id, cp->device->lun, resid,
+				    scsi_bufflen(cp)));
 
+				cp->result = DID_ERROR << 16 | lscsi_status;
+				break;
+			}
+
+			if (!lscsi_status &&
+			    ((unsigned)(scsi_bufflen(cp) - resid) <
+			    cp->underflow)) {
+				qla_printk(KERN_INFO, ha,
+				    "scsi(%ld:%d:%d:%d): Mid-layer underflow "
+				    "detected (%x of %x bytes)...returning "
+				    "error status.\n", vha->host_no,
+				    cp->device->channel, cp->device->id,
+				    cp->device->lun, resid, scsi_bufflen(cp));
+
+				cp->result = DID_ERROR << 16;
+				break;
+			}
+		} else if (!lscsi_status) {
+			DEBUG2(printk(
+			    "scsi(%ld:%d:%d:%d) Dropped frame(s) detected "
+			    "(%x of %x bytes)...firmware reported underrun..."
+			    "retrying command.\n", vha->host_no,
+			    cp->device->channel, cp->device->id,
+			    cp->device->lun, resid, scsi_bufflen(cp)));
+
+			cp->result = DID_ERROR << 16;
+			break;
 		}
 
+		cp->result = DID_OK << 16 | lscsi_status;
+
 		/*
 		 * Check to see if SCSI Status is non zero. If so report SCSI
 		 * Status.
 		 */
 		if (lscsi_status != 0) {
-			cp->result = DID_OK << 16 | lscsi_status;
-
 			if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
 				DEBUG2(printk(KERN_INFO
 				    "scsi(%ld): QUEUE FULL status detected "
@@ -1501,42 +1537,6 @@
 				break;
 
 			qla2x00_handle_sense(sp, sense_data, sense_len, rsp);
-		} else {
-			/*
-			 * If RISC reports underrun and target does not report
-			 * it then we must have a lost frame, so tell upper
-			 * layer to retry it by reporting an error.
-			 */
-			if (!(scsi_status & SS_RESIDUAL_UNDER)) {
-				DEBUG2(printk("scsi(%ld:%d:%d:%d) Dropped "
-					      "frame(s) detected (%x of %x bytes)..."
-					      "retrying command.\n",
-					vha->host_no, cp->device->channel,
-					cp->device->id, cp->device->lun, resid,
-					scsi_bufflen(cp)));
-
-				scsi_set_resid(cp, resid);
-				cp->result = DID_ERROR << 16;
-				break;
-			}
-
-			/* Handle mid-layer underflow */
-			if ((unsigned)(scsi_bufflen(cp) - resid) <
-			    cp->underflow) {
-				qla_printk(KERN_INFO, ha,
-					   "scsi(%ld:%d:%d:%d): Mid-layer underflow "
-					   "detected (%x of %x bytes)...returning "
-					   "error status.\n", vha->host_no,
-					   cp->device->channel, cp->device->id,
-					   cp->device->lun, resid,
-					   scsi_bufflen(cp));
-
-				cp->result = DID_ERROR << 16;
-				break;
-			}
-
-			/* Everybody online, looking good... */
-			cp->result = DID_OK << 16;
 		}
 		break;
 
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index b6202fe..05d595d 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -2006,7 +2006,7 @@
 int
 qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
     uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt,
-    uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports)
+    uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports, uint16_t *max_fcfs)
 {
 	int rval;
 	mbx_cmd_t mc;
@@ -2017,6 +2017,8 @@
 	mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
 	mcp->out_mb = MBX_0;
 	mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
+	if (IS_QLA81XX(vha->hw))
+		mcp->in_mb |= MBX_12;
 	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(vha, mcp);
@@ -2027,9 +2029,10 @@
 		    vha->host_no, mcp->mb[0]));
 	} else {
 		DEBUG11(printk("%s(%ld): done. mb1=%x mb2=%x mb3=%x mb6=%x "
-		    "mb7=%x mb10=%x mb11=%x.\n", __func__, vha->host_no,
-		    mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[6], mcp->mb[7],
-		    mcp->mb[10], mcp->mb[11]));
+		    "mb7=%x mb10=%x mb11=%x mb12=%x.\n", __func__,
+		    vha->host_no, mcp->mb[1], mcp->mb[2], mcp->mb[3],
+		    mcp->mb[6], mcp->mb[7], mcp->mb[10], mcp->mb[11],
+		    mcp->mb[12]));
 
 		if (cur_xchg_cnt)
 			*cur_xchg_cnt = mcp->mb[3];
@@ -2041,6 +2044,8 @@
 			*orig_iocb_cnt = mcp->mb[10];
 		if (vha->hw->flags.npiv_supported && max_npiv_vports)
 			*max_npiv_vports = mcp->mb[11];
+		if (IS_QLA81XX(vha->hw) && max_fcfs)
+			*max_fcfs = mcp->mb[12];
 	}
 
 	return (rval);
@@ -2313,6 +2318,7 @@
 {
 	int		rval, rval2;
 	struct tsk_mgmt_cmd *tsk;
+	struct sts_entry_24xx *sts;
 	dma_addr_t	tsk_dma;
 	scsi_qla_host_t *vha;
 	struct qla_hw_data *ha;
@@ -2352,20 +2358,37 @@
 		    sizeof(tsk->p.tsk.lun));
 	}
 
+	sts = &tsk->p.sts;
 	rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0);
 	if (rval != QLA_SUCCESS) {
 		DEBUG2_3_11(printk("%s(%ld): failed to issue %s Reset IOCB "
 		    "(%x).\n", __func__, vha->host_no, name, rval));
-	} else if (tsk->p.sts.entry_status != 0) {
+	} else if (sts->entry_status != 0) {
 		DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
 		    "-- error status (%x).\n", __func__, vha->host_no,
-		    tsk->p.sts.entry_status));
+		    sts->entry_status));
 		rval = QLA_FUNCTION_FAILED;
-	} else if (tsk->p.sts.comp_status !=
+	} else if (sts->comp_status !=
 	    __constant_cpu_to_le16(CS_COMPLETE)) {
 		DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
 		    "-- completion status (%x).\n", __func__,
-		    vha->host_no, le16_to_cpu(tsk->p.sts.comp_status)));
+		    vha->host_no, le16_to_cpu(sts->comp_status)));
+		rval = QLA_FUNCTION_FAILED;
+	} else if (!(le16_to_cpu(sts->scsi_status) &
+	    SS_RESPONSE_INFO_LEN_VALID)) {
+		DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
+		    "-- no response info (%x).\n", __func__, vha->host_no,
+		    le16_to_cpu(sts->scsi_status)));
+		rval = QLA_FUNCTION_FAILED;
+	} else if (le32_to_cpu(sts->rsp_data_len) < 4) {
+		DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
+		    "-- not enough response info (%d).\n", __func__,
+		    vha->host_no, le32_to_cpu(sts->rsp_data_len)));
+		rval = QLA_FUNCTION_FAILED;
+	} else if (sts->data[3]) {
+		DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
+		    "-- response (%x).\n", __func__,
+		    vha->host_no, sts->data[3]));
 		rval = QLA_FUNCTION_FAILED;
 	}
 
@@ -2759,8 +2782,10 @@
 		    vp_idx, MSB(stat),
 		    rptid_entry->port_id[2], rptid_entry->port_id[1],
 		    rptid_entry->port_id[0]));
-		if (vp_idx == 0)
-			return;
+
+		vp = vha;
+		if (vp_idx == 0 && (MSB(stat) != 1))
+			goto reg_needed;
 
 		if (MSB(stat) == 1) {
 			DEBUG2(printk("scsi(%ld): Could not acquire ID for "
@@ -2783,8 +2808,11 @@
 		 * response queue. Handle it in dpc context.
 		 */
 		set_bit(VP_IDX_ACQUIRED, &vp->vp_flags);
-		set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
 
+reg_needed:
+		set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags);
+		set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags);
+		set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
 		qla2xxx_wake_dpc(vha);
 	}
 }
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index e07b361..a47d343 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -382,8 +382,6 @@
 	vha->mgmt_svr_loop_id = 10 + vha->vp_idx;
 
 	vha->dpc_flags = 0L;
-	set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
-	set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
 
 	/*
 	 * To fix the issue of processing a parent's RSCN for the vport before
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index b79fca7..4166935 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -11,6 +11,7 @@
 #include <linux/delay.h>
 #include <linux/kthread.h>
 #include <linux/mutex.h>
+#include <linux/kobject.h>
 
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsicam.h>
@@ -137,7 +138,7 @@
 static int qla2xxx_eh_bus_reset(struct scsi_cmnd *);
 static int qla2xxx_eh_host_reset(struct scsi_cmnd *);
 
-static int qla2x00_change_queue_depth(struct scsi_device *, int);
+static int qla2x00_change_queue_depth(struct scsi_device *, int, int);
 static int qla2x00_change_queue_type(struct scsi_device *, int);
 
 struct scsi_host_template qla2xxx_driver_template = {
@@ -727,23 +728,6 @@
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 }
 
-static void
-qla2x00_block_error_handler(struct scsi_cmnd *cmnd)
-{
-	struct Scsi_Host *shost = cmnd->device->host;
-	struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
-	unsigned long flags;
-
-	spin_lock_irqsave(shost->host_lock, flags);
-	while (rport->port_state == FC_PORTSTATE_BLOCKED) {
-		spin_unlock_irqrestore(shost->host_lock, flags);
-		msleep(1000);
-		spin_lock_irqsave(shost->host_lock, flags);
-	}
-	spin_unlock_irqrestore(shost->host_lock, flags);
-	return;
-}
-
 /**************************************************************************
 * qla2xxx_eh_abort
 *
@@ -773,7 +757,7 @@
 	struct req_que *req = vha->req;
 	srb_t *spt;
 
-	qla2x00_block_error_handler(cmd);
+	fc_block_scsi_eh(cmd);
 
 	if (!CMD_SP(cmd))
 		return SUCCESS;
@@ -904,7 +888,7 @@
 	fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
 	int err;
 
-	qla2x00_block_error_handler(cmd);
+	fc_block_scsi_eh(cmd);
 
 	if (!fcport)
 		return FAILED;
@@ -984,7 +968,7 @@
 	unsigned long serial;
 	srb_t *sp = (srb_t *) CMD_SP(cmd);
 
-	qla2x00_block_error_handler(cmd);
+	fc_block_scsi_eh(cmd);
 
 	id = cmd->device->id;
 	lun = cmd->device->lun;
@@ -1047,7 +1031,7 @@
 	srb_t *sp = (srb_t *) CMD_SP(cmd);
 	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
 
-	qla2x00_block_error_handler(cmd);
+	fc_block_scsi_eh(cmd);
 
 	id = cmd->device->id;
 	lun = cmd->device->lun;
@@ -1234,8 +1218,11 @@
 }
 
 static int
-qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth)
+qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
 	return sdev->queue_depth;
 }
@@ -2653,6 +2640,37 @@
 qla2x00_post_async_work(logout, QLA_EVT_ASYNC_LOGOUT);
 qla2x00_post_async_work(logout_done, QLA_EVT_ASYNC_LOGOUT_DONE);
 
+int
+qla2x00_post_uevent_work(struct scsi_qla_host *vha, u32 code)
+{
+	struct qla_work_evt *e;
+
+	e = qla2x00_alloc_work(vha, QLA_EVT_UEVENT);
+	if (!e)
+		return QLA_FUNCTION_FAILED;
+
+	e->u.uevent.code = code;
+	return qla2x00_post_work(vha, e);
+}
+
+static void
+qla2x00_uevent_emit(struct scsi_qla_host *vha, u32 code)
+{
+	char event_string[40];
+	char *envp[] = { event_string, NULL };
+
+	switch (code) {
+	case QLA_UEVENT_CODE_FW_DUMP:
+		snprintf(event_string, sizeof(event_string), "FW_DUMP=%ld",
+		    vha->host_no);
+		break;
+	default:
+		/* do nothing */
+		break;
+	}
+	kobject_uevent_env(&vha->hw->pdev->dev.kobj, KOBJ_CHANGE, envp);
+}
+
 void
 qla2x00_do_work(struct scsi_qla_host *vha)
 {
@@ -2690,6 +2708,9 @@
 			qla2x00_async_logout_done(vha, e->u.logio.fcport,
 			    e->u.logio.data);
 			break;
+		case QLA_EVT_UEVENT:
+			qla2x00_uevent_emit(vha, e->u.uevent.code);
+			break;
 		}
 		if (e->flags & QLA_EVT_FLAG_FREE)
 			kfree(e);
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index ac107a2..807e0db 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,7 +7,7 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "8.03.01-k6"
+#define QLA2XXX_VERSION      "8.03.01-k7"
 
 #define QLA_DRIVER_MAJOR_VER	8
 #define QLA_DRIVER_MINOR_VER	3
diff --git a/drivers/scsi/qlogicpti.h b/drivers/scsi/qlogicpti.h
index 9c053bb..e3c74d1 100644
--- a/drivers/scsi/qlogicpti.h
+++ b/drivers/scsi/qlogicpti.h
@@ -43,7 +43,7 @@
  * determined for each queue request anew.
  */
 #define QLOGICPTI_REQ_QUEUE_LEN	255	/* must be power of two - 1 */
-#define QLOGICPTI_MAX_SG(ql)	(4 + ((ql) > 0) ? 7*((ql) - 1) : 0)
+#define QLOGICPTI_MAX_SG(ql)	(4 + (((ql) > 0) ? 7*((ql) - 1) : 0))
 
 /* mailbox command complete status codes */
 #define MBOX_COMMAND_COMPLETE		0x4000
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index dd098ca..a60da55 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -940,10 +940,16 @@
  */
 int scsi_track_queue_full(struct scsi_device *sdev, int depth)
 {
-	if ((jiffies >> 4) == sdev->last_queue_full_time)
+
+	/*
+	 * Don't let QUEUE_FULLs on the same
+	 * jiffies count, they could all be from
+	 * same event.
+	 */
+	if ((jiffies >> 4) == (sdev->last_queue_full_time >> 4))
 		return 0;
 
-	sdev->last_queue_full_time = (jiffies >> 4);
+	sdev->last_queue_full_time = jiffies;
 	if (sdev->last_queue_full_depth != depth) {
 		sdev->last_queue_full_count = 1;
 		sdev->last_queue_full_depth = depth;
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index c4103be..0b575c8 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -44,6 +44,8 @@
 
 #include <net/checksum.h>
 
+#include <asm/unaligned.h>
+
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
@@ -105,6 +107,10 @@
 #define DEF_ATO 1
 #define DEF_PHYSBLK_EXP 0
 #define DEF_LOWEST_ALIGNED 0
+#define DEF_UNMAP_MAX_BLOCKS 0
+#define DEF_UNMAP_MAX_DESC 0
+#define DEF_UNMAP_GRANULARITY 0
+#define DEF_UNMAP_ALIGNMENT 0
 
 /* bit mask values for scsi_debug_opts */
 #define SCSI_DEBUG_OPT_NOISE   1
@@ -162,6 +168,10 @@
 static int scsi_debug_ato = DEF_ATO;
 static int scsi_debug_physblk_exp = DEF_PHYSBLK_EXP;
 static int scsi_debug_lowest_aligned = DEF_LOWEST_ALIGNED;
+static int scsi_debug_unmap_max_desc = DEF_UNMAP_MAX_DESC;
+static int scsi_debug_unmap_max_blocks = DEF_UNMAP_MAX_BLOCKS;
+static int scsi_debug_unmap_granularity = DEF_UNMAP_GRANULARITY;
+static int scsi_debug_unmap_alignment = DEF_UNMAP_ALIGNMENT;
 
 static int scsi_debug_cmnd_count = 0;
 
@@ -223,7 +233,9 @@
 
 static unsigned char * fake_storep;	/* ramdisk storage */
 static unsigned char *dif_storep;	/* protection info */
+static void *map_storep;		/* provisioning map */
 
+static unsigned long map_size;
 static int num_aborts = 0;
 static int num_dev_resets = 0;
 static int num_bus_resets = 0;
@@ -317,6 +329,7 @@
 			(u32)cmd[28] << 24;
 		break;
 
+	case WRITE_SAME_16:
 	case WRITE_16:
 	case READ_16:
 		*lba = (u64)cmd[9] | (u64)cmd[8] << 8 |
@@ -335,6 +348,7 @@
 		*num = (u32)cmd[9] | (u32)cmd[8] << 8 | (u32)cmd[7] << 16 |
 			(u32)cmd[6] << 24;
 		break;
+	case WRITE_SAME:
 	case WRITE_10:
 	case READ_10:
 	case XDWRITEREAD_10:
@@ -671,10 +685,12 @@
 }
 
 
+/* Block limits VPD page (SBC-3) */
 static unsigned char vpdb0_data[] = {
-	/* from 4th byte */ 0,0,0,4,
-	0,0,0x4,0,
-	0,0,0,64,
+	/* from 4th byte */ 0,0,0,4, 0,0,0x4,0, 0,0,0,64,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 };
 
 static int inquiry_evpd_b0(unsigned char * arr)
@@ -691,14 +707,40 @@
 		arr[6] = (sdebug_store_sectors >> 8) & 0xff;
 		arr[7] = sdebug_store_sectors & 0xff;
 	}
+
+	if (scsi_debug_unmap_max_desc) {
+		unsigned int blocks;
+
+		if (scsi_debug_unmap_max_blocks)
+			blocks = scsi_debug_unmap_max_blocks;
+		else
+			blocks = 0xffffffff;
+
+		put_unaligned_be32(blocks, &arr[16]);
+		put_unaligned_be32(scsi_debug_unmap_max_desc, &arr[20]);
+	}
+
+	if (scsi_debug_unmap_alignment) {
+		put_unaligned_be32(scsi_debug_unmap_alignment, &arr[28]);
+		arr[28] |= 0x80; /* UGAVALID */
+	}
+
+	if (scsi_debug_unmap_granularity) {
+		put_unaligned_be32(scsi_debug_unmap_granularity, &arr[24]);
+		return 0x3c; /* Mandatory page length for thin provisioning */
+	}
+
 	return sizeof(vpdb0_data);
 }
 
+/* Block device characteristics VPD page (SBC-3) */
 static int inquiry_evpd_b1(unsigned char *arr)
 {
 	memset(arr, 0, 0x3c);
 	arr[0] = 0;
-	arr[1] = 1;
+	arr[1] = 1;	/* non rotating medium (e.g. solid state) */
+	arr[2] = 0;
+	arr[3] = 5;	/* less than 1.8" */
 
 	return 0x3c;
 }
@@ -974,6 +1016,10 @@
 	arr[11] = scsi_debug_sector_size & 0xff;
 	arr[13] = scsi_debug_physblk_exp & 0xf;
 	arr[14] = (scsi_debug_lowest_aligned >> 8) & 0x3f;
+
+	if (scsi_debug_unmap_granularity)
+		arr[14] |= 0x80; /* TPE */
+
 	arr[15] = scsi_debug_lowest_aligned & 0xff;
 
 	if (scsi_debug_dif) {
@@ -1887,6 +1933,70 @@
 	return ret;
 }
 
+static unsigned int map_state(sector_t lba, unsigned int *num)
+{
+	unsigned int granularity, alignment, mapped;
+	sector_t block, next, end;
+
+	granularity = scsi_debug_unmap_granularity;
+	alignment = granularity - scsi_debug_unmap_alignment;
+	block = lba + alignment;
+	do_div(block, granularity);
+
+	mapped = test_bit(block, map_storep);
+
+	if (mapped)
+		next = find_next_zero_bit(map_storep, map_size, block);
+	else
+		next = find_next_bit(map_storep, map_size, block);
+
+	end = next * granularity - scsi_debug_unmap_alignment;
+	*num = end - lba;
+
+	return mapped;
+}
+
+static void map_region(sector_t lba, unsigned int len)
+{
+	unsigned int granularity, alignment;
+	sector_t end = lba + len;
+
+	granularity = scsi_debug_unmap_granularity;
+	alignment = granularity - scsi_debug_unmap_alignment;
+
+	while (lba < end) {
+		sector_t block, rem;
+
+		block = lba + alignment;
+		rem = do_div(block, granularity);
+
+		set_bit(block, map_storep);
+
+		lba += granularity - rem;
+	}
+}
+
+static void unmap_region(sector_t lba, unsigned int len)
+{
+	unsigned int granularity, alignment;
+	sector_t end = lba + len;
+
+	granularity = scsi_debug_unmap_granularity;
+	alignment = granularity - scsi_debug_unmap_alignment;
+
+	while (lba < end) {
+		sector_t block, rem;
+
+		block = lba + alignment;
+		rem = do_div(block, granularity);
+
+		if (rem == 0 && lba + granularity <= end)
+			clear_bit(block, map_storep);
+
+		lba += granularity - rem;
+	}
+}
+
 static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba,
 		      unsigned int num, struct sdebug_dev_info *devip,
 		      u32 ei_lba)
@@ -1910,6 +2020,8 @@
 
 	write_lock_irqsave(&atomic_rw, iflags);
 	ret = do_device_access(SCpnt, devip, lba, num, 1);
+	if (scsi_debug_unmap_granularity)
+		map_region(lba, num);
 	write_unlock_irqrestore(&atomic_rw, iflags);
 	if (-1 == ret)
 		return (DID_ERROR << 16);
@@ -1917,9 +2029,143 @@
 		 (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts))
 		printk(KERN_INFO "scsi_debug: write: cdb indicated=%u, "
 		       " IO sent=%d bytes\n", num * scsi_debug_sector_size, ret);
+
 	return 0;
 }
 
+static int resp_write_same(struct scsi_cmnd *scmd, unsigned long long lba,
+		      unsigned int num, struct sdebug_dev_info *devip,
+			   u32 ei_lba, unsigned int unmap)
+{
+	unsigned long iflags;
+	unsigned long long i;
+	int ret;
+
+	ret = check_device_access_params(devip, lba, num);
+	if (ret)
+		return ret;
+
+	write_lock_irqsave(&atomic_rw, iflags);
+
+	if (unmap && scsi_debug_unmap_granularity) {
+		unmap_region(lba, num);
+		goto out;
+	}
+
+	/* Else fetch one logical block */
+	ret = fetch_to_dev_buffer(scmd,
+				  fake_storep + (lba * scsi_debug_sector_size),
+				  scsi_debug_sector_size);
+
+	if (-1 == ret) {
+		write_unlock_irqrestore(&atomic_rw, iflags);
+		return (DID_ERROR << 16);
+	} else if ((ret < (num * scsi_debug_sector_size)) &&
+		 (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts))
+		printk(KERN_INFO "scsi_debug: write same: cdb indicated=%u, "
+		       " IO sent=%d bytes\n", num * scsi_debug_sector_size, ret);
+
+	/* Copy first sector to remaining blocks */
+	for (i = 1 ; i < num ; i++)
+		memcpy(fake_storep + ((lba + i) * scsi_debug_sector_size),
+		       fake_storep + (lba * scsi_debug_sector_size),
+		       scsi_debug_sector_size);
+
+	if (scsi_debug_unmap_granularity)
+		map_region(lba, num);
+out:
+	write_unlock_irqrestore(&atomic_rw, iflags);
+
+	return 0;
+}
+
+struct unmap_block_desc {
+	__be64	lba;
+	__be32	blocks;
+	__be32	__reserved;
+};
+
+static int resp_unmap(struct scsi_cmnd * scmd, struct sdebug_dev_info * devip)
+{
+	unsigned char *buf;
+	struct unmap_block_desc *desc;
+	unsigned int i, payload_len, descriptors;
+	int ret;
+
+	ret = check_readiness(scmd, 1, devip);
+	if (ret)
+		return ret;
+
+	payload_len = get_unaligned_be16(&scmd->cmnd[7]);
+	BUG_ON(scsi_bufflen(scmd) != payload_len);
+
+	descriptors = (payload_len - 8) / 16;
+
+	buf = kmalloc(scsi_bufflen(scmd), GFP_ATOMIC);
+	if (!buf)
+		return check_condition_result;
+
+	scsi_sg_copy_to_buffer(scmd, buf, scsi_bufflen(scmd));
+
+	BUG_ON(get_unaligned_be16(&buf[0]) != payload_len - 2);
+	BUG_ON(get_unaligned_be16(&buf[2]) != descriptors * 16);
+
+	desc = (void *)&buf[8];
+
+	for (i = 0 ; i < descriptors ; i++) {
+		unsigned long long lba = get_unaligned_be64(&desc[i].lba);
+		unsigned int num = get_unaligned_be32(&desc[i].blocks);
+
+		ret = check_device_access_params(devip, lba, num);
+		if (ret)
+			goto out;
+
+		unmap_region(lba, num);
+	}
+
+	ret = 0;
+
+out:
+	kfree(buf);
+
+	return ret;
+}
+
+#define SDEBUG_GET_LBA_STATUS_LEN 32
+
+static int resp_get_lba_status(struct scsi_cmnd * scmd,
+			       struct sdebug_dev_info * devip)
+{
+	unsigned long long lba;
+	unsigned int alloc_len, mapped, num;
+	unsigned char arr[SDEBUG_GET_LBA_STATUS_LEN];
+	int ret;
+
+	ret = check_readiness(scmd, 1, devip);
+	if (ret)
+		return ret;
+
+	lba = get_unaligned_be64(&scmd->cmnd[2]);
+	alloc_len = get_unaligned_be32(&scmd->cmnd[10]);
+
+	if (alloc_len < 24)
+		return 0;
+
+	ret = check_device_access_params(devip, lba, 1);
+	if (ret)
+		return ret;
+
+	mapped = map_state(lba, &num);
+
+	memset(arr, 0, SDEBUG_GET_LBA_STATUS_LEN);
+	put_unaligned_be32(16, &arr[0]);	/* Parameter Data Length */
+	put_unaligned_be64(lba, &arr[8]);	/* LBA */
+	put_unaligned_be32(num, &arr[16]);	/* Number of blocks */
+	arr[20] = !mapped;			/* mapped = 0, unmapped = 1 */
+
+	return fill_from_dev_buffer(scmd, arr, SDEBUG_GET_LBA_STATUS_LEN);
+}
+
 #define SDEBUG_RLUN_ARR_SZ 256
 
 static int resp_report_luns(struct scsi_cmnd * scp,
@@ -2430,6 +2676,10 @@
 module_param_named(ato, scsi_debug_ato, int, S_IRUGO);
 module_param_named(physblk_exp, scsi_debug_physblk_exp, int, S_IRUGO);
 module_param_named(lowest_aligned, scsi_debug_lowest_aligned, int, S_IRUGO);
+module_param_named(unmap_max_blocks, scsi_debug_unmap_max_blocks, int, S_IRUGO);
+module_param_named(unmap_max_desc, scsi_debug_unmap_max_desc, int, S_IRUGO);
+module_param_named(unmap_granularity, scsi_debug_unmap_granularity, int, S_IRUGO);
+module_param_named(unmap_alignment, scsi_debug_unmap_alignment, int, S_IRUGO);
 
 MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert");
 MODULE_DESCRIPTION("SCSI debug adapter driver");
@@ -2458,6 +2708,10 @@
 MODULE_PARM_DESC(dif, "data integrity field type: 0-3 (def=0)");
 MODULE_PARM_DESC(guard, "protection checksum: 0=crc, 1=ip (def=0)");
 MODULE_PARM_DESC(ato, "application tag ownership: 0=disk 1=host (def=1)");
+MODULE_PARM_DESC(unmap_max_blocks, "max # of blocks can be unmapped in one cmd (def=0)");
+MODULE_PARM_DESC(unmap_max_desc, "max # of ranges that can be unmapped in one cmd (def=0)");
+MODULE_PARM_DESC(unmap_granularity, "thin provisioning granularity in blocks (def=0)");
+MODULE_PARM_DESC(unmap_alignment, "lowest aligned thin provisioning lba (def=0)");
 
 static char sdebug_info[256];
 
@@ -2816,6 +3070,23 @@
 }
 DRIVER_ATTR(ato, S_IRUGO, sdebug_ato_show, NULL);
 
+static ssize_t sdebug_map_show(struct device_driver *ddp, char *buf)
+{
+	ssize_t count;
+
+	if (scsi_debug_unmap_granularity == 0)
+		return scnprintf(buf, PAGE_SIZE, "0-%u\n",
+				 sdebug_store_sectors);
+
+	count = bitmap_scnlistprintf(buf, PAGE_SIZE, map_storep, map_size);
+
+	buf[count++] = '\n';
+	buf[count++] = 0;
+
+	return count;
+}
+DRIVER_ATTR(map, S_IRUGO, sdebug_map_show, NULL);
+
 
 /* Note: The following function creates attribute files in the
    /sys/bus/pseudo/drivers/scsi_debug directory. The advantage of these
@@ -2847,11 +3118,13 @@
 	ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_dif);
 	ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_guard);
 	ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_ato);
+	ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_map);
 	return ret;
 }
 
 static void do_remove_driverfs_files(void)
 {
+	driver_remove_file(&sdebug_driverfs_driver, &driver_attr_map);
 	driver_remove_file(&sdebug_driverfs_driver, &driver_attr_ato);
 	driver_remove_file(&sdebug_driverfs_driver, &driver_attr_guard);
 	driver_remove_file(&sdebug_driverfs_driver, &driver_attr_dif);
@@ -2989,6 +3262,36 @@
 		memset(dif_storep, 0xff, dif_size);
 	}
 
+	if (scsi_debug_unmap_granularity) {
+		unsigned int map_bytes;
+
+		if (scsi_debug_unmap_granularity < scsi_debug_unmap_alignment) {
+			printk(KERN_ERR
+			       "%s: ERR: unmap_granularity < unmap_alignment\n",
+			       __func__);
+			return -EINVAL;
+		}
+
+		map_size = (sdebug_store_sectors / scsi_debug_unmap_granularity);
+		map_bytes = map_size >> 3;
+		map_storep = vmalloc(map_bytes);
+
+		printk(KERN_INFO "scsi_debug_init: %lu provisioning blocks\n",
+		       map_size);
+
+		if (map_storep == NULL) {
+			printk(KERN_ERR "scsi_debug_init: out of mem. (MAP)\n");
+			ret = -ENOMEM;
+			goto free_vm;
+		}
+
+		memset(map_storep, 0x0, map_bytes);
+
+		/* Map first 1KB for partition table */
+		if (scsi_debug_num_parts)
+			map_region(0, 2);
+	}
+
 	ret = device_register(&pseudo_primary);
 	if (ret < 0) {
 		printk(KERN_WARNING "scsi_debug: device_register error: %d\n",
@@ -3041,6 +3344,8 @@
 dev_unreg:
 	device_unregister(&pseudo_primary);
 free_vm:
+	if (map_storep)
+		vfree(map_storep);
 	if (dif_storep)
 		vfree(dif_storep);
 	vfree(fake_storep);
@@ -3167,6 +3472,7 @@
 	int inj_dif = 0;
 	int inj_dix = 0;
 	int delay_override = 0;
+	int unmap = 0;
 
 	scsi_set_resid(SCpnt, 0);
 	if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmd) {
@@ -3272,13 +3578,21 @@
 		errsts = resp_readcap(SCpnt, devip);
 		break;
 	case SERVICE_ACTION_IN:
-		if (SAI_READ_CAPACITY_16 != cmd[1]) {
+		if (cmd[1] == SAI_READ_CAPACITY_16)
+			errsts = resp_readcap16(SCpnt, devip);
+		else if (cmd[1] == SAI_GET_LBA_STATUS) {
+
+			if (scsi_debug_unmap_max_desc == 0) {
+				mk_sense_buffer(devip, ILLEGAL_REQUEST,
+						INVALID_COMMAND_OPCODE, 0);
+				errsts = check_condition_result;
+			} else
+				errsts = resp_get_lba_status(SCpnt, devip);
+		} else {
 			mk_sense_buffer(devip, ILLEGAL_REQUEST,
 					INVALID_OPCODE, 0);
 			errsts = check_condition_result;
-			break;
 		}
-		errsts = resp_readcap16(SCpnt, devip);
 		break;
 	case MAINTENANCE_IN:
 		if (MI_REPORT_TARGET_PGS != cmd[1]) {
@@ -3378,6 +3692,29 @@
 			errsts = illegal_condition_result;
 		}
 		break;
+	case WRITE_SAME_16:
+		if (cmd[1] & 0x8)
+			unmap = 1;
+		/* fall through */
+	case WRITE_SAME:
+		errsts = check_readiness(SCpnt, 0, devip);
+		if (errsts)
+			break;
+		get_data_transfer_info(cmd, &lba, &num, &ei_lba);
+		errsts = resp_write_same(SCpnt, lba, num, devip, ei_lba, unmap);
+		break;
+	case UNMAP:
+		errsts = check_readiness(SCpnt, 0, devip);
+		if (errsts)
+			break;
+
+		if (scsi_debug_unmap_max_desc == 0) {
+			mk_sense_buffer(devip, ILLEGAL_REQUEST,
+					INVALID_COMMAND_OPCODE, 0);
+			errsts = check_condition_result;
+		} else
+			errsts = resp_unmap(SCpnt, devip);
+		break;
 	case MODE_SENSE:
 	case MODE_SENSE_10:
 		errsts = resp_mode_sense(SCpnt, target, devip);
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
index 93c2622..37af178 100644
--- a/drivers/scsi/scsi_devinfo.c
+++ b/drivers/scsi/scsi_devinfo.c
@@ -168,11 +168,10 @@
 	{"Generic", "USB SD Reader", "1.00", BLIST_FORCELUN | BLIST_INQUIRY_36},
 	{"Generic", "USB Storage-SMC", "0180", BLIST_FORCELUN | BLIST_INQUIRY_36},
 	{"Generic", "USB Storage-SMC", "0207", BLIST_FORCELUN | BLIST_INQUIRY_36},
-	{"HITACHI", "DF400", "*", BLIST_SPARSELUN},
-	{"HITACHI", "DF500", "*", BLIST_SPARSELUN},
-	{"HITACHI", "DF600", "*", BLIST_SPARSELUN},
-	{"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN},
-	{"HITACHI", "OPEN-E", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN},
+	{"HITACHI", "DF400", "*", BLIST_REPORTLUN2},
+	{"HITACHI", "DF500", "*", BLIST_REPORTLUN2},
+	{"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_REPORTLUN2},
+	{"HITACHI", "OPEN-", "*", BLIST_REPORTLUN2},
 	{"HITACHI", "OP-C-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
 	{"HITACHI", "3380-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
 	{"HITACHI", "3390-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
@@ -454,7 +453,7 @@
 
 
 /**
- * get_device_flags_keyed - get device specific flags from the dynamic device list.
+ * scsi_get_device_flags_keyed - get device specific flags from the dynamic device list
  * @sdev:       &scsi_device to get flags for
  * @vendor:	vendor name
  * @model:	model name
@@ -685,7 +684,7 @@
 		 "scsi default device flag integer value");
 
 /**
- * scsi_dev_info_list_delete - called from scsi.c:exit_scsi to remove the scsi_dev_info_list.
+ * scsi_exit_devinfo - remove /proc/scsi/device_info & the scsi_dev_info_list
  **/
 void scsi_exit_devinfo(void)
 {
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 1b0060b..08ed506 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -331,6 +331,64 @@
 	}
 }
 
+static void scsi_handle_queue_ramp_up(struct scsi_device *sdev)
+{
+	struct scsi_host_template *sht = sdev->host->hostt;
+	struct scsi_device *tmp_sdev;
+
+	if (!sht->change_queue_depth ||
+	    sdev->queue_depth >= sdev->max_queue_depth)
+		return;
+
+	if (time_before(jiffies,
+	    sdev->last_queue_ramp_up + sdev->queue_ramp_up_period))
+		return;
+
+	if (time_before(jiffies,
+	    sdev->last_queue_full_time + sdev->queue_ramp_up_period))
+		return;
+
+	/*
+	 * Walk all devices of a target and do
+	 * ramp up on them.
+	 */
+	shost_for_each_device(tmp_sdev, sdev->host) {
+		if (tmp_sdev->channel != sdev->channel ||
+		    tmp_sdev->id != sdev->id ||
+		    tmp_sdev->queue_depth == sdev->max_queue_depth)
+			continue;
+		/*
+		 * call back into LLD to increase queue_depth by one
+		 * with ramp up reason code.
+		 */
+		sht->change_queue_depth(tmp_sdev, tmp_sdev->queue_depth + 1,
+					SCSI_QDEPTH_RAMP_UP);
+		sdev->last_queue_ramp_up = jiffies;
+	}
+}
+
+static void scsi_handle_queue_full(struct scsi_device *sdev)
+{
+	struct scsi_host_template *sht = sdev->host->hostt;
+	struct scsi_device *tmp_sdev;
+
+	if (!sht->change_queue_depth)
+		return;
+
+	shost_for_each_device(tmp_sdev, sdev->host) {
+		if (tmp_sdev->channel != sdev->channel ||
+		    tmp_sdev->id != sdev->id)
+			continue;
+		/*
+		 * We do not know the number of commands that were at
+		 * the device when we got the queue full so we start
+		 * from the highest possible value and work our way down.
+		 */
+		sht->change_queue_depth(tmp_sdev, tmp_sdev->queue_depth - 1,
+					SCSI_QDEPTH_QFULL);
+	}
+}
+
 /**
  * scsi_eh_completed_normally - Disposition a eh cmd on return from LLD.
  * @scmd:	SCSI cmd to examine.
@@ -371,6 +429,7 @@
 	 */
 	switch (status_byte(scmd->result)) {
 	case GOOD:
+		scsi_handle_queue_ramp_up(scmd->device);
 	case COMMAND_TERMINATED:
 		return SUCCESS;
 	case CHECK_CONDITION:
@@ -387,8 +446,10 @@
 		 * let issuer deal with this, it could be just fine
 		 */
 		return SUCCESS;
-	case BUSY:
 	case QUEUE_FULL:
+		scsi_handle_queue_full(scmd->device);
+		/* fall through */
+	case BUSY:
 	default:
 		return FAILED;
 	}
@@ -1387,6 +1448,7 @@
 	 */
 	switch (status_byte(scmd->result)) {
 	case QUEUE_FULL:
+		scsi_handle_queue_full(scmd->device);
 		/*
 		 * the case of trying to send too many commands to a
 		 * tagged queueing device.
@@ -1400,6 +1462,7 @@
 		 */
 		return ADD_TO_MLQUEUE;
 	case GOOD:
+		scsi_handle_queue_ramp_up(scmd->device);
 	case COMMAND_TERMINATED:
 		return SUCCESS;
 	case TASK_ABORTED:
diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
index b98f763..d9564fb 100644
--- a/drivers/scsi/scsi_ioctl.c
+++ b/drivers/scsi/scsi_ioctl.c
@@ -308,6 +308,9 @@
 		case SG_SCSI_RESET_DEVICE:
 			val = SCSI_TRY_RESET_DEVICE;
 			break;
+		case SG_SCSI_RESET_TARGET:
+			val = SCSI_TRY_RESET_TARGET;
+			break;
 		case SG_SCSI_RESET_BUS:
 			val = SCSI_TRY_RESET_BUS;
 			break;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 5987da8..e495d38 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -898,7 +898,7 @@
 				scsi_print_sense("", cmd);
 			scsi_print_command(cmd);
 		}
-		if (blk_end_request_err(req, -EIO))
+		if (blk_end_request_err(req, error))
 			scsi_requeue_command(q, cmd);
 		else
 			scsi_next_command(cmd);
@@ -1359,9 +1359,9 @@
 static void scsi_kill_request(struct request *req, struct request_queue *q)
 {
 	struct scsi_cmnd *cmd = req->special;
-	struct scsi_device *sdev = cmd->device;
-	struct scsi_target *starget = scsi_target(sdev);
-	struct Scsi_Host *shost = sdev->host;
+	struct scsi_device *sdev;
+	struct scsi_target *starget;
+	struct Scsi_Host *shost;
 
 	blk_start_request(req);
 
@@ -1371,6 +1371,9 @@
 		BUG();
 	}
 
+	sdev = cmd->device;
+	starget = scsi_target(sdev);
+	shost = sdev->host;
 	scsi_init_cmd_errh(cmd);
 	cmd->result = DID_NO_CONNECT << 16;
 	atomic_inc(&cmd->device->iorequest_cnt);
diff --git a/drivers/scsi/scsi_lib_dma.c b/drivers/scsi/scsi_lib_dma.c
index ac6855c..dcd1285 100644
--- a/drivers/scsi/scsi_lib_dma.c
+++ b/drivers/scsi/scsi_lib_dma.c
@@ -23,7 +23,7 @@
 	int nseg = 0;
 
 	if (scsi_sg_count(cmd)) {
-		struct device *dev = cmd->device->host->shost_gendev.parent;
+		struct device *dev = cmd->device->host->dma_dev;
 
 		nseg = dma_map_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd),
 				  cmd->sc_data_direction);
@@ -41,7 +41,7 @@
 void scsi_dma_unmap(struct scsi_cmnd *cmd)
 {
 	if (scsi_sg_count(cmd)) {
-		struct device *dev = cmd->device->host->shost_gendev.parent;
+		struct device *dev = cmd->device->host->dma_dev;
 
 		dma_unmap_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd),
 			     cmd->sc_data_direction);
diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c
index 723fdec..0fd6ae6 100644
--- a/drivers/scsi/scsi_netlink.c
+++ b/drivers/scsi/scsi_netlink.c
@@ -613,7 +613,7 @@
  * @data_buf:		pointer to vendor unique data buffer
  *
  * Returns:
- *   0 on succesful return
+ *   0 on successful return
  *   otherwise, failing error code
  *
  * Notes:
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 47291bc..012f73a 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -251,6 +251,7 @@
 	sdev->model = scsi_null_device_strs;
 	sdev->rev = scsi_null_device_strs;
 	sdev->host = shost;
+	sdev->queue_ramp_up_period = SCSI_DEFAULT_RAMP_UP_PERIOD;
 	sdev->id = starget->id;
 	sdev->lun = lun;
 	sdev->channel = starget->channel;
@@ -941,6 +942,8 @@
 		}
 	}
 
+	sdev->max_queue_depth = sdev->queue_depth;
+
 	/*
 	 * Ok, the device is now all set up, we can
 	 * register it and tell the rest of the kernel
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 392d8db..5a06505 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -766,10 +766,13 @@
 	if (depth < 1)
 		return -EINVAL;
 
-	retval = sht->change_queue_depth(sdev, depth);
+	retval = sht->change_queue_depth(sdev, depth,
+					 SCSI_QDEPTH_DEFAULT);
 	if (retval < 0)
 		return retval;
 
+	sdev->max_queue_depth = sdev->queue_depth;
+
 	return count;
 }
 
@@ -778,6 +781,37 @@
 	       sdev_store_queue_depth_rw);
 
 static ssize_t
+sdev_show_queue_ramp_up_period(struct device *dev,
+			       struct device_attribute *attr,
+			       char *buf)
+{
+	struct scsi_device *sdev;
+	sdev = to_scsi_device(dev);
+	return snprintf(buf, 20, "%u\n",
+			jiffies_to_msecs(sdev->queue_ramp_up_period));
+}
+
+static ssize_t
+sdev_store_queue_ramp_up_period(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct scsi_device *sdev = to_scsi_device(dev);
+	unsigned long period;
+
+	if (strict_strtoul(buf, 10, &period))
+		return -EINVAL;
+
+	sdev->queue_ramp_up_period = msecs_to_jiffies(period);
+	return period;
+}
+
+static struct device_attribute sdev_attr_queue_ramp_up_period =
+	__ATTR(queue_ramp_up_period, S_IRUGO | S_IWUSR,
+	       sdev_show_queue_ramp_up_period,
+	       sdev_store_queue_ramp_up_period);
+
+static ssize_t
 sdev_store_queue_type_rw(struct device *dev, struct device_attribute *attr,
 			 const char *buf, size_t count)
 {
@@ -867,8 +901,12 @@
 	sdev->is_visible = 1;
 
 	/* create queue files, which may be writable, depending on the host */
-	if (sdev->host->hostt->change_queue_depth)
-		error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_depth_rw);
+	if (sdev->host->hostt->change_queue_depth) {
+		error = device_create_file(&sdev->sdev_gendev,
+					   &sdev_attr_queue_depth_rw);
+		error = device_create_file(&sdev->sdev_gendev,
+					   &sdev_attr_queue_ramp_up_period);
+	}
 	else
 		error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_depth);
 	if (error)
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index c6f70da..6531c91 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -27,6 +27,7 @@
  */
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/delay.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_transport.h>
@@ -2384,6 +2385,7 @@
 	struct Scsi_Host *shost = rport_to_shost(rport);
 	struct fc_internal *i = to_fc_internal(shost->transportt);
 	unsigned long flags;
+	int do_callback = 0;
 
 	/*
 	 * if a scan is pending, flush the SCSI Host work_q so that
@@ -2422,8 +2424,15 @@
 	 * Avoid this call if we already called it when we preserved the
 	 * rport for the binding.
 	 */
+	spin_lock_irqsave(shost->host_lock, flags);
 	if (!(rport->flags & FC_RPORT_DEVLOSS_CALLBK_DONE) &&
-	    (i->f->dev_loss_tmo_callbk))
+	    (i->f->dev_loss_tmo_callbk)) {
+		rport->flags |= FC_RPORT_DEVLOSS_CALLBK_DONE;
+		do_callback = 1;
+	}
+	spin_unlock_irqrestore(shost->host_lock, flags);
+
+	if (do_callback)
 		i->f->dev_loss_tmo_callbk(rport);
 
 	fc_bsg_remove(rport->rqst_q);
@@ -2970,6 +2979,7 @@
 	struct fc_internal *i = to_fc_internal(shost->transportt);
 	struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
 	unsigned long flags;
+	int do_callback = 0;
 
 	spin_lock_irqsave(shost->host_lock, flags);
 
@@ -3035,7 +3045,6 @@
 	rport->roles = FC_PORT_ROLE_UNKNOWN;
 	rport->port_state = FC_PORTSTATE_NOTPRESENT;
 	rport->flags &= ~FC_RPORT_FAST_FAIL_TIMEDOUT;
-	rport->flags |= FC_RPORT_DEVLOSS_CALLBK_DONE;
 
 	/*
 	 * Pre-emptively kill I/O rather than waiting for the work queue
@@ -3045,32 +3054,40 @@
 	spin_unlock_irqrestore(shost->host_lock, flags);
 	fc_terminate_rport_io(rport);
 
-	BUG_ON(rport->port_state != FC_PORTSTATE_NOTPRESENT);
+	spin_lock_irqsave(shost->host_lock, flags);
 
-	/* remove the identifiers that aren't used in the consisting binding */
-	switch (fc_host->tgtid_bind_type) {
-	case FC_TGTID_BIND_BY_WWPN:
-		rport->node_name = -1;
-		rport->port_id = -1;
-		break;
-	case FC_TGTID_BIND_BY_WWNN:
-		rport->port_name = -1;
-		rport->port_id = -1;
-		break;
-	case FC_TGTID_BIND_BY_ID:
-		rport->node_name = -1;
-		rport->port_name = -1;
-		break;
-	case FC_TGTID_BIND_NONE:	/* to keep compiler happy */
-		break;
+	if (rport->port_state == FC_PORTSTATE_NOTPRESENT) {	/* still missing */
+
+		/* remove the identifiers that aren't used in the consisting binding */
+		switch (fc_host->tgtid_bind_type) {
+		case FC_TGTID_BIND_BY_WWPN:
+			rport->node_name = -1;
+			rport->port_id = -1;
+			break;
+		case FC_TGTID_BIND_BY_WWNN:
+			rport->port_name = -1;
+			rport->port_id = -1;
+			break;
+		case FC_TGTID_BIND_BY_ID:
+			rport->node_name = -1;
+			rport->port_name = -1;
+			break;
+		case FC_TGTID_BIND_NONE:	/* to keep compiler happy */
+			break;
+		}
+
+		/*
+		 * As this only occurs if the remote port (scsi target)
+		 * went away and didn't come back - we'll remove
+		 * all attached scsi devices.
+		 */
+		rport->flags |= FC_RPORT_DEVLOSS_CALLBK_DONE;
+		fc_queue_work(shost, &rport->stgt_delete_work);
+
+		do_callback = 1;
 	}
 
-	/*
-	 * As this only occurs if the remote port (scsi target)
-	 * went away and didn't come back - we'll remove
-	 * all attached scsi devices.
-	 */
-	fc_queue_work(shost, &rport->stgt_delete_work);
+	spin_unlock_irqrestore(shost->host_lock, flags);
 
 	/*
 	 * Notify the driver that the rport is now dead. The LLDD will
@@ -3078,7 +3095,7 @@
 	 *
 	 * Note: we set the CALLBK_DONE flag above to correspond
 	 */
-	if (i->f->dev_loss_tmo_callbk)
+	if (do_callback && i->f->dev_loss_tmo_callbk)
 		i->f->dev_loss_tmo_callbk(rport);
 }
 
@@ -3128,6 +3145,31 @@
 	spin_unlock_irqrestore(shost->host_lock, flags);
 }
 
+/**
+ * fc_block_scsi_eh - Block SCSI eh thread for blocked fc_rport
+ * @cmnd: SCSI command that scsi_eh is trying to recover
+ *
+ * This routine can be called from a FC LLD scsi_eh callback. It
+ * blocks the scsi_eh thread until the fc_rport leaves the
+ * FC_PORTSTATE_BLOCKED. This is necessary to avoid the scsi_eh
+ * failing recovery actions for blocked rports which would lead to
+ * offlined SCSI devices.
+ */
+void fc_block_scsi_eh(struct scsi_cmnd *cmnd)
+{
+	struct Scsi_Host *shost = cmnd->device->host;
+	struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
+	unsigned long flags;
+
+	spin_lock_irqsave(shost->host_lock, flags);
+	while (rport->port_state == FC_PORTSTATE_BLOCKED) {
+		spin_unlock_irqrestore(shost->host_lock, flags);
+		msleep(1000);
+		spin_lock_irqsave(shost->host_lock, flags);
+	}
+	spin_unlock_irqrestore(shost->host_lock, flags);
+}
+EXPORT_SYMBOL(fc_block_scsi_eh);
 
 /**
  * fc_vport_setup - allocates and creates a FC virtual port.
@@ -3769,8 +3811,9 @@
 		return;
 
 	while (!blk_queue_plugged(q)) {
-		if (rport && (rport->port_state == FC_PORTSTATE_BLOCKED))
-				break;
+		if (rport && (rport->port_state == FC_PORTSTATE_BLOCKED) &&
+		    !(rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT))
+			break;
 
 		req = blk_fetch_request(q);
 		if (!req)
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index ad897df..ea3892e 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -30,7 +30,7 @@
 #include <scsi/scsi_transport_iscsi.h>
 #include <scsi/iscsi_if.h>
 
-#define ISCSI_SESSION_ATTRS 21
+#define ISCSI_SESSION_ATTRS 22
 #define ISCSI_CONN_ATTRS 13
 #define ISCSI_HOST_ATTRS 4
 
@@ -627,8 +627,10 @@
 	spin_unlock_irqrestore(&session->lock, flags);
 	scsi_target_block(&session->dev);
 	ISCSI_DBG_TRANS_SESSION(session, "Completed SCSI target blocking\n");
-	queue_delayed_work(iscsi_eh_timer_workq, &session->recovery_work,
-			   session->recovery_tmo * HZ);
+	if (session->recovery_tmo >= 0)
+		queue_delayed_work(iscsi_eh_timer_workq,
+				   &session->recovery_work,
+				   session->recovery_tmo * HZ);
 }
 
 void iscsi_block_session(struct iscsi_cls_session *session)
@@ -1348,8 +1350,7 @@
 	switch (ev->u.set_param.param) {
 	case ISCSI_PARAM_SESS_RECOVERY_TMO:
 		sscanf(data, "%d", &value);
-		if (value != 0)
-			session->recovery_tmo = value;
+		session->recovery_tmo = value;
 		break;
 	default:
 		err = transport->set_param(conn, ev->u.set_param.param,
@@ -1759,6 +1760,7 @@
 iscsi_session_attr(fast_abort, ISCSI_PARAM_FAST_ABORT, 0);
 iscsi_session_attr(abort_tmo, ISCSI_PARAM_ABORT_TMO, 0);
 iscsi_session_attr(lu_reset_tmo, ISCSI_PARAM_LU_RESET_TMO, 0);
+iscsi_session_attr(tgt_reset_tmo, ISCSI_PARAM_TGT_RESET_TMO, 0);
 iscsi_session_attr(ifacename, ISCSI_PARAM_IFACE_NAME, 0);
 iscsi_session_attr(initiatorname, ISCSI_PARAM_INITIATOR_NAME, 0)
 
@@ -2000,6 +2002,7 @@
 	SETUP_SESSION_RD_ATTR(fast_abort, ISCSI_FAST_ABORT);
 	SETUP_SESSION_RD_ATTR(abort_tmo, ISCSI_ABORT_TMO);
 	SETUP_SESSION_RD_ATTR(lu_reset_tmo,ISCSI_LU_RESET_TMO);
+	SETUP_SESSION_RD_ATTR(tgt_reset_tmo,ISCSI_TGT_RESET_TMO);
 	SETUP_SESSION_RD_ATTR(ifacename, ISCSI_IFACE_NAME);
 	SETUP_SESSION_RD_ATTR(initiatorname, ISCSI_INITIATOR_NAME);
 	SETUP_PRIV_SESSION_RD_ATTR(recovery_tmo);
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index fd47cb1..f27e52d 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -666,7 +666,7 @@
  *
  * Note:
  *   This function must only be called on a PHY that has not
- *   sucessfully been added using sas_phy_add().
+ *   successfully been added using sas_phy_add().
  */
 void sas_phy_free(struct sas_phy *phy)
 {
@@ -896,7 +896,7 @@
  *
  * Note:
  *   This function must only be called on a PORT that has not
- *   sucessfully been added using sas_port_add().
+ *   successfully been added using sas_port_add().
  */
 void sas_port_free(struct sas_port *port)
 {
@@ -1476,7 +1476,7 @@
  *
  * Note:
  *   This function must only be called on a remote
- *   PHY that has not sucessfully been added using
+ *   PHY that has not successfully been added using
  *   sas_rphy_add() (or has been sas_rphy_remove()'d)
  */
 void sas_rphy_free(struct sas_rphy *rphy)
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 12d58a7..ad59abb 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -2280,7 +2280,8 @@
 	} else if (code == MT_ST_SET_CLN) {
 		value = (options & ~MT_ST_OPTIONS) & 0xff;
 		if (value != 0 &&
-		    value < EXTENDED_SENSE_START && value >= SCSI_SENSE_BUFFERSIZE)
+			(value < EXTENDED_SENSE_START ||
+				value >= SCSI_SENSE_BUFFERSIZE))
 			return (-EINVAL);
 		STp->cln_mode = value;
 		STp->cln_sense_mask = (options >> 8) & 0xff;
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index 09fa886..3058bb1 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -36,11 +36,11 @@
 #include <scsi/scsi_eh.h>
 
 #define DRV_NAME "stex"
-#define ST_DRIVER_VERSION "4.6.0000.3"
+#define ST_DRIVER_VERSION "4.6.0000.4"
 #define ST_VER_MAJOR		4
 #define ST_VER_MINOR		6
 #define ST_OEM			0
-#define ST_BUILD_VER		3
+#define ST_BUILD_VER		4
 
 enum {
 	/* MU register offset */
@@ -64,24 +64,24 @@
 	YH2I_REQ_HI				= 0xc4,
 
 	/* MU register value */
-	MU_INBOUND_DOORBELL_HANDSHAKE		= 1,
-	MU_INBOUND_DOORBELL_REQHEADCHANGED	= 2,
-	MU_INBOUND_DOORBELL_STATUSTAILCHANGED	= 4,
-	MU_INBOUND_DOORBELL_HMUSTOPPED		= 8,
-	MU_INBOUND_DOORBELL_RESET		= 16,
+	MU_INBOUND_DOORBELL_HANDSHAKE		= (1 << 0),
+	MU_INBOUND_DOORBELL_REQHEADCHANGED	= (1 << 1),
+	MU_INBOUND_DOORBELL_STATUSTAILCHANGED	= (1 << 2),
+	MU_INBOUND_DOORBELL_HMUSTOPPED		= (1 << 3),
+	MU_INBOUND_DOORBELL_RESET		= (1 << 4),
 
-	MU_OUTBOUND_DOORBELL_HANDSHAKE		= 1,
-	MU_OUTBOUND_DOORBELL_REQUESTTAILCHANGED	= 2,
-	MU_OUTBOUND_DOORBELL_STATUSHEADCHANGED	= 4,
-	MU_OUTBOUND_DOORBELL_BUSCHANGE		= 8,
-	MU_OUTBOUND_DOORBELL_HASEVENT		= 16,
+	MU_OUTBOUND_DOORBELL_HANDSHAKE		= (1 << 0),
+	MU_OUTBOUND_DOORBELL_REQUESTTAILCHANGED	= (1 << 1),
+	MU_OUTBOUND_DOORBELL_STATUSHEADCHANGED	= (1 << 2),
+	MU_OUTBOUND_DOORBELL_BUSCHANGE		= (1 << 3),
+	MU_OUTBOUND_DOORBELL_HASEVENT		= (1 << 4),
+	MU_OUTBOUND_DOORBELL_REQUEST_RESET	= (1 << 27),
 
 	/* MU status code */
 	MU_STATE_STARTING			= 1,
-	MU_STATE_FMU_READY_FOR_HANDSHAKE	= 2,
-	MU_STATE_SEND_HANDSHAKE_FRAME		= 3,
-	MU_STATE_STARTED			= 4,
-	MU_STATE_RESETTING			= 5,
+	MU_STATE_STARTED			= 2,
+	MU_STATE_RESETTING			= 3,
+	MU_STATE_FAILED				= 4,
 
 	MU_MAX_DELAY				= 120,
 	MU_HANDSHAKE_SIGNATURE			= 0x55aaaa55,
@@ -111,6 +111,8 @@
 
 	SS_H2I_INT_RESET			= 0x100,
 
+	SS_I2H_REQUEST_RESET			= 0x2000,
+
 	SS_MU_OPERATIONAL			= 0x80000000,
 
 	STEX_CDB_LENGTH				= 16,
@@ -160,6 +162,7 @@
 	INQUIRY_EVPD				= 0x01,
 
 	ST_ADDITIONAL_MEM			= 0x200000,
+	ST_ADDITIONAL_MEM_MIN			= 0x80000,
 };
 
 struct st_sgitem {
@@ -311,6 +314,10 @@
 	struct st_ccb *wait_ccb;
 	__le32 *scratch;
 
+	char work_q_name[20];
+	struct workqueue_struct *work_q;
+	struct work_struct reset_work;
+	wait_queue_head_t reset_waitq;
 	unsigned int mu_status;
 	unsigned int cardtype;
 	int msi_enabled;
@@ -577,6 +584,9 @@
 	lun = cmd->device->lun;
 	hba = (struct st_hba *) &host->hostdata[0];
 
+	if (unlikely(hba->mu_status == MU_STATE_RESETTING))
+		return SCSI_MLQUEUE_HOST_BUSY;
+
 	switch (cmd->cmnd[0]) {
 	case MODE_SENSE_10:
 	{
@@ -841,7 +851,6 @@
 	void __iomem *base = hba->mmio_base;
 	u32 data;
 	unsigned long flags;
-	int handled = 0;
 
 	spin_lock_irqsave(hba->host->host_lock, flags);
 
@@ -852,12 +861,16 @@
 		writel(data, base + ODBL);
 		readl(base + ODBL); /* flush */
 		stex_mu_intr(hba, data);
-		handled = 1;
+		spin_unlock_irqrestore(hba->host->host_lock, flags);
+		if (unlikely(data & MU_OUTBOUND_DOORBELL_REQUEST_RESET &&
+			hba->cardtype == st_shasta))
+			queue_work(hba->work_q, &hba->reset_work);
+		return IRQ_HANDLED;
 	}
 
 	spin_unlock_irqrestore(hba->host->host_lock, flags);
 
-	return IRQ_RETVAL(handled);
+	return IRQ_NONE;
 }
 
 static void stex_ss_mu_intr(struct st_hba *hba)
@@ -939,7 +952,6 @@
 	void __iomem *base = hba->mmio_base;
 	u32 data;
 	unsigned long flags;
-	int handled = 0;
 
 	spin_lock_irqsave(hba->host->host_lock, flags);
 
@@ -948,12 +960,15 @@
 		/* clear the interrupt */
 		writel(data, base + YI2H_INT_C);
 		stex_ss_mu_intr(hba);
-		handled = 1;
+		spin_unlock_irqrestore(hba->host->host_lock, flags);
+		if (unlikely(data & SS_I2H_REQUEST_RESET))
+			queue_work(hba->work_q, &hba->reset_work);
+		return IRQ_HANDLED;
 	}
 
 	spin_unlock_irqrestore(hba->host->host_lock, flags);
 
-	return IRQ_RETVAL(handled);
+	return IRQ_NONE;
 }
 
 static int stex_common_handshake(struct st_hba *hba)
@@ -1001,7 +1016,7 @@
 	h->partner_type = HMU_PARTNER_TYPE;
 	if (hba->extra_offset) {
 		h->extra_offset = cpu_to_le32(hba->extra_offset);
-		h->extra_size = cpu_to_le32(ST_ADDITIONAL_MEM);
+		h->extra_size = cpu_to_le32(hba->dma_size - hba->extra_offset);
 	} else
 		h->extra_offset = h->extra_size = 0;
 
@@ -1046,7 +1061,7 @@
 	struct st_msg_header *msg_h;
 	struct handshake_frame *h;
 	__le32 *scratch;
-	u32 data;
+	u32 data, scratch_size;
 	unsigned long before;
 	int ret = 0;
 
@@ -1074,13 +1089,16 @@
 	stex_gettime(&h->hosttime);
 	h->partner_type = HMU_PARTNER_TYPE;
 	h->extra_offset = h->extra_size = 0;
-	h->scratch_size = cpu_to_le32((hba->sts_count+1)*sizeof(u32));
+	scratch_size = (hba->sts_count+1)*sizeof(u32);
+	h->scratch_size = cpu_to_le32(scratch_size);
 
 	data = readl(base + YINT_EN);
 	data &= ~4;
 	writel(data, base + YINT_EN);
 	writel((hba->dma_handle >> 16) >> 16, base + YH2I_REQ_HI);
+	readl(base + YH2I_REQ_HI);
 	writel(hba->dma_handle, base + YH2I_REQ);
+	readl(base + YH2I_REQ); /* flush */
 
 	scratch = hba->scratch;
 	before = jiffies;
@@ -1096,7 +1114,7 @@
 		msleep(1);
 	}
 
-	*scratch = 0;
+	memset(scratch, 0, scratch_size);
 	msg_h->flag = 0;
 	return ret;
 }
@@ -1105,19 +1123,24 @@
 {
 	int err;
 	unsigned long flags;
+	unsigned int mu_status;
 
 	err = (hba->cardtype == st_yel) ?
 		stex_ss_handshake(hba) : stex_common_handshake(hba);
+	spin_lock_irqsave(hba->host->host_lock, flags);
+	mu_status = hba->mu_status;
 	if (err == 0) {
-		spin_lock_irqsave(hba->host->host_lock, flags);
 		hba->req_head = 0;
 		hba->req_tail = 0;
 		hba->status_head = 0;
 		hba->status_tail = 0;
 		hba->out_req_cnt = 0;
 		hba->mu_status = MU_STATE_STARTED;
-		spin_unlock_irqrestore(hba->host->host_lock, flags);
-	}
+	} else
+		hba->mu_status = MU_STATE_FAILED;
+	if (mu_status == MU_STATE_RESETTING)
+		wake_up_all(&hba->reset_waitq);
+	spin_unlock_irqrestore(hba->host->host_lock, flags);
 	return err;
 }
 
@@ -1137,17 +1160,11 @@
 
 	base = hba->mmio_base;
 	spin_lock_irqsave(host->host_lock, flags);
-	if (tag < host->can_queue && hba->ccb[tag].cmd == cmd)
+	if (tag < host->can_queue &&
+		hba->ccb[tag].req && hba->ccb[tag].cmd == cmd)
 		hba->wait_ccb = &hba->ccb[tag];
-	else {
-		for (tag = 0; tag < host->can_queue; tag++)
-			if (hba->ccb[tag].cmd == cmd) {
-				hba->wait_ccb = &hba->ccb[tag];
-				break;
-			}
-		if (tag >= host->can_queue)
-			goto out;
-	}
+	else
+		goto out;
 
 	if (hba->cardtype == st_yel) {
 		data = readl(base + YI2H_INT);
@@ -1221,6 +1238,37 @@
 			hba->pdev->saved_config_space[i]);
 }
 
+static int stex_yos_reset(struct st_hba *hba)
+{
+	void __iomem *base;
+	unsigned long flags, before;
+	int ret = 0;
+
+	base = hba->mmio_base;
+	writel(MU_INBOUND_DOORBELL_RESET, base + IDBL);
+	readl(base + IDBL); /* flush */
+	before = jiffies;
+	while (hba->out_req_cnt > 0) {
+		if (time_after(jiffies, before + ST_INTERNAL_TIMEOUT * HZ)) {
+			printk(KERN_WARNING DRV_NAME
+				"(%s): reset timeout\n", pci_name(hba->pdev));
+			ret = -1;
+			break;
+		}
+		msleep(1);
+	}
+
+	spin_lock_irqsave(hba->host->host_lock, flags);
+	if (ret == -1)
+		hba->mu_status = MU_STATE_FAILED;
+	else
+		hba->mu_status = MU_STATE_STARTED;
+	wake_up_all(&hba->reset_waitq);
+	spin_unlock_irqrestore(hba->host->host_lock, flags);
+
+	return ret;
+}
+
 static void stex_ss_reset(struct st_hba *hba)
 {
 	writel(SS_H2I_INT_RESET, hba->mmio_base + YH2I_INT);
@@ -1228,11 +1276,71 @@
 	ssleep(5);
 }
 
+static int stex_do_reset(struct st_hba *hba)
+{
+	struct st_ccb *ccb;
+	unsigned long flags;
+	unsigned int mu_status = MU_STATE_RESETTING;
+	u16 tag;
+
+	spin_lock_irqsave(hba->host->host_lock, flags);
+	if (hba->mu_status == MU_STATE_STARTING) {
+		spin_unlock_irqrestore(hba->host->host_lock, flags);
+		printk(KERN_INFO DRV_NAME "(%s): request reset during init\n",
+			pci_name(hba->pdev));
+		return 0;
+	}
+	while (hba->mu_status == MU_STATE_RESETTING) {
+		spin_unlock_irqrestore(hba->host->host_lock, flags);
+		wait_event_timeout(hba->reset_waitq,
+				   hba->mu_status != MU_STATE_RESETTING,
+				   MU_MAX_DELAY * HZ);
+		spin_lock_irqsave(hba->host->host_lock, flags);
+		mu_status = hba->mu_status;
+	}
+
+	if (mu_status != MU_STATE_RESETTING) {
+		spin_unlock_irqrestore(hba->host->host_lock, flags);
+		return (mu_status == MU_STATE_STARTED) ? 0 : -1;
+	}
+
+	hba->mu_status = MU_STATE_RESETTING;
+	spin_unlock_irqrestore(hba->host->host_lock, flags);
+
+	if (hba->cardtype == st_yosemite)
+		return stex_yos_reset(hba);
+
+	if (hba->cardtype == st_shasta)
+		stex_hard_reset(hba);
+	else if (hba->cardtype == st_yel)
+		stex_ss_reset(hba);
+
+	spin_lock_irqsave(hba->host->host_lock, flags);
+	for (tag = 0; tag < hba->host->can_queue; tag++) {
+		ccb = &hba->ccb[tag];
+		if (ccb->req == NULL)
+			continue;
+		ccb->req = NULL;
+		if (ccb->cmd) {
+			scsi_dma_unmap(ccb->cmd);
+			ccb->cmd->result = DID_RESET << 16;
+			ccb->cmd->scsi_done(ccb->cmd);
+			ccb->cmd = NULL;
+		}
+	}
+	spin_unlock_irqrestore(hba->host->host_lock, flags);
+
+	if (stex_handshake(hba) == 0)
+		return 0;
+
+	printk(KERN_WARNING DRV_NAME "(%s): resetting: handshake failed\n",
+		pci_name(hba->pdev));
+	return -1;
+}
+
 static int stex_reset(struct scsi_cmnd *cmd)
 {
 	struct st_hba *hba;
-	void __iomem *base;
-	unsigned long flags, before;
 
 	hba = (struct st_hba *) &cmd->device->host->hostdata[0];
 
@@ -1240,54 +1348,14 @@
 		"(%s): resetting host\n", pci_name(hba->pdev));
 	scsi_print_command(cmd);
 
-	hba->mu_status = MU_STATE_RESETTING;
+	return stex_do_reset(hba) ? FAILED : SUCCESS;
+}
 
-	if (hba->cardtype == st_shasta)
-		stex_hard_reset(hba);
-	else if (hba->cardtype == st_yel)
-		stex_ss_reset(hba);
+static void stex_reset_work(struct work_struct *work)
+{
+	struct st_hba *hba = container_of(work, struct st_hba, reset_work);
 
-	if (hba->cardtype != st_yosemite) {
-		if (stex_handshake(hba)) {
-			printk(KERN_WARNING DRV_NAME
-				"(%s): resetting: handshake failed\n",
-				pci_name(hba->pdev));
-			return FAILED;
-		}
-		return SUCCESS;
-	}
-
-	/* st_yosemite */
-	writel(MU_INBOUND_DOORBELL_RESET, hba->mmio_base + IDBL);
-	readl(hba->mmio_base + IDBL); /* flush */
-	before = jiffies;
-	while (hba->out_req_cnt > 0) {
-		if (time_after(jiffies, before + ST_INTERNAL_TIMEOUT * HZ)) {
-			printk(KERN_WARNING DRV_NAME
-				"(%s): reset timeout\n", pci_name(hba->pdev));
-			return FAILED;
-		}
-		msleep(1);
-	}
-
-	base = hba->mmio_base;
-	writel(0, base + IMR0);
-	readl(base + IMR0);
-	writel(0, base + OMR0);
-	readl(base + OMR0);
-	writel(0, base + IMR1);
-	readl(base + IMR1);
-	writel(0, base + OMR1);
-	readl(base + OMR1); /* flush */
-	spin_lock_irqsave(hba->host->host_lock, flags);
-	hba->req_head = 0;
-	hba->req_tail = 0;
-	hba->status_head = 0;
-	hba->status_tail = 0;
-	hba->out_req_cnt = 0;
-	hba->mu_status = MU_STATE_STARTED;
-	spin_unlock_irqrestore(hba->host->host_lock, flags);
-	return SUCCESS;
+	stex_do_reset(hba);
 }
 
 static int stex_biosparam(struct scsi_device *sdev,
@@ -1420,8 +1488,8 @@
 {
 	int ret;
 
-	if (!pci_set_dma_mask(pdev,  DMA_BIT_MASK(64))
-		&& !pci_set_consistent_dma_mask(pdev,  DMA_BIT_MASK(64)))
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
+		&& !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
 		return 0;
 	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (!ret)
@@ -1528,10 +1596,24 @@
 	hba->dma_mem = dma_alloc_coherent(&pdev->dev,
 		hba->dma_size, &hba->dma_handle, GFP_KERNEL);
 	if (!hba->dma_mem) {
-		err = -ENOMEM;
-		printk(KERN_ERR DRV_NAME "(%s): dma mem alloc failed\n",
-			pci_name(pdev));
-		goto out_iounmap;
+		/* Retry minimum coherent mapping for st_seq and st_vsc */
+		if (hba->cardtype == st_seq ||
+		    (hba->cardtype == st_vsc && (pdev->subsystem_device & 1))) {
+			printk(KERN_WARNING DRV_NAME
+				"(%s): allocating min buffer for controller\n",
+				pci_name(pdev));
+			hba->dma_size = hba->extra_offset
+				+ ST_ADDITIONAL_MEM_MIN;
+			hba->dma_mem = dma_alloc_coherent(&pdev->dev,
+				hba->dma_size, &hba->dma_handle, GFP_KERNEL);
+		}
+
+		if (!hba->dma_mem) {
+			err = -ENOMEM;
+			printk(KERN_ERR DRV_NAME "(%s): dma mem alloc failed\n",
+				pci_name(pdev));
+			goto out_iounmap;
+		}
 	}
 
 	hba->ccb = kcalloc(ci->rq_count, sizeof(struct st_ccb), GFP_KERNEL);
@@ -1568,12 +1650,24 @@
 
 	hba->host = host;
 	hba->pdev = pdev;
+	init_waitqueue_head(&hba->reset_waitq);
+
+	snprintf(hba->work_q_name, sizeof(hba->work_q_name),
+		 "stex_wq_%d", host->host_no);
+	hba->work_q = create_singlethread_workqueue(hba->work_q_name);
+	if (!hba->work_q) {
+		printk(KERN_ERR DRV_NAME "(%s): create workqueue failed\n",
+			pci_name(pdev));
+		err = -ENOMEM;
+		goto out_ccb_free;
+	}
+	INIT_WORK(&hba->reset_work, stex_reset_work);
 
 	err = stex_request_irq(hba);
 	if (err) {
 		printk(KERN_ERR DRV_NAME "(%s): request irq failed\n",
 			pci_name(pdev));
-		goto out_ccb_free;
+		goto out_free_wq;
 	}
 
 	err = stex_handshake(hba);
@@ -1602,6 +1696,8 @@
 
 out_free_irq:
 	stex_free_irq(hba);
+out_free_wq:
+	destroy_workqueue(hba->work_q);
 out_ccb_free:
 	kfree(hba->ccb);
 out_pci_free:
@@ -1669,6 +1765,8 @@
 {
 	stex_free_irq(hba);
 
+	destroy_workqueue(hba->work_q);
+
 	iounmap(hba->mmio_base);
 
 	pci_release_regions(hba->pdev);
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index 45374d6..2b38f6a 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -1864,7 +1864,7 @@
  *
  * This routine is similar to sym_set_workarounds(), except
  * that, at this point, we already know that the device was
- * succesfully intialized at least once before, and so most
+ * successfully intialized at least once before, and so most
  * of the steps taken there are un-needed here.
  */
 static void sym2_reset_workarounds(struct pci_dev *pdev)
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
index 297deb8..a7bc8b7 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.c
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c
@@ -2692,7 +2692,7 @@
 	 *  we force a SIR_NEGO_PROTO interrupt (it is a hack that avoids 
 	 *  bloat for such a should_not_happen situation).
 	 *  In all other situation, we reset the BUS.
-	 *  Are these assumptions reasonnable ? (Wait and see ...)
+	 *  Are these assumptions reasonable ? (Wait and see ...)
 	 */
 unexpected_phase:
 	dsp -= 8;
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.h b/drivers/scsi/sym53c8xx_2/sym_hipd.h
index 053e63c..5a80cba 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.h
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.h
@@ -54,7 +54,7 @@
  *
  *    SYM_OPT_LIMIT_COMMAND_REORDERING
  *        When this option is set, the driver tries to limit tagged 
- *        command reordering to some reasonnable value.
+ *        command reordering to some reasonable value.
  *        (set for Linux)
  */
 #if 0
diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c
new file mode 100644
index 0000000..d2604c8
--- /dev/null
+++ b/drivers/scsi/vmw_pvscsi.c
@@ -0,0 +1,1407 @@
+/*
+ * Linux driver for VMware's para-virtualized SCSI HBA.
+ *
+ * Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
+ *
+ * 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 of the License and no 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, GOOD TITLE or
+ * NON INFRINGEMENT.  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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Maintained by: Alok N Kataria <akataria@vmware.com>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/pci.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+
+#include "vmw_pvscsi.h"
+
+#define PVSCSI_LINUX_DRIVER_DESC "VMware PVSCSI driver"
+
+MODULE_DESCRIPTION(PVSCSI_LINUX_DRIVER_DESC);
+MODULE_AUTHOR("VMware, Inc.");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(PVSCSI_DRIVER_VERSION_STRING);
+
+#define PVSCSI_DEFAULT_NUM_PAGES_PER_RING	8
+#define PVSCSI_DEFAULT_NUM_PAGES_MSG_RING	1
+#define PVSCSI_DEFAULT_QUEUE_DEPTH		64
+#define SGL_SIZE				PAGE_SIZE
+
+struct pvscsi_sg_list {
+	struct PVSCSISGElement sge[PVSCSI_MAX_NUM_SG_ENTRIES_PER_SEGMENT];
+};
+
+struct pvscsi_ctx {
+	/*
+	 * The index of the context in cmd_map serves as the context ID for a
+	 * 1-to-1 mapping completions back to requests.
+	 */
+	struct scsi_cmnd	*cmd;
+	struct pvscsi_sg_list	*sgl;
+	struct list_head	list;
+	dma_addr_t		dataPA;
+	dma_addr_t		sensePA;
+	dma_addr_t		sglPA;
+};
+
+struct pvscsi_adapter {
+	char				*mmioBase;
+	unsigned int			irq;
+	u8				rev;
+	bool				use_msi;
+	bool				use_msix;
+	bool				use_msg;
+
+	spinlock_t			hw_lock;
+
+	struct workqueue_struct		*workqueue;
+	struct work_struct		work;
+
+	struct PVSCSIRingReqDesc	*req_ring;
+	unsigned			req_pages;
+	unsigned			req_depth;
+	dma_addr_t			reqRingPA;
+
+	struct PVSCSIRingCmpDesc	*cmp_ring;
+	unsigned			cmp_pages;
+	dma_addr_t			cmpRingPA;
+
+	struct PVSCSIRingMsgDesc	*msg_ring;
+	unsigned			msg_pages;
+	dma_addr_t			msgRingPA;
+
+	struct PVSCSIRingsState		*rings_state;
+	dma_addr_t			ringStatePA;
+
+	struct pci_dev			*dev;
+	struct Scsi_Host		*host;
+
+	struct list_head		cmd_pool;
+	struct pvscsi_ctx		*cmd_map;
+};
+
+
+/* Command line parameters */
+static int pvscsi_ring_pages     = PVSCSI_DEFAULT_NUM_PAGES_PER_RING;
+static int pvscsi_msg_ring_pages = PVSCSI_DEFAULT_NUM_PAGES_MSG_RING;
+static int pvscsi_cmd_per_lun    = PVSCSI_DEFAULT_QUEUE_DEPTH;
+static bool pvscsi_disable_msi;
+static bool pvscsi_disable_msix;
+static bool pvscsi_use_msg       = true;
+
+#define PVSCSI_RW (S_IRUSR | S_IWUSR)
+
+module_param_named(ring_pages, pvscsi_ring_pages, int, PVSCSI_RW);
+MODULE_PARM_DESC(ring_pages, "Number of pages per req/cmp ring - (default="
+		 __stringify(PVSCSI_DEFAULT_NUM_PAGES_PER_RING) ")");
+
+module_param_named(msg_ring_pages, pvscsi_msg_ring_pages, int, PVSCSI_RW);
+MODULE_PARM_DESC(msg_ring_pages, "Number of pages for the msg ring - (default="
+		 __stringify(PVSCSI_DEFAULT_NUM_PAGES_MSG_RING) ")");
+
+module_param_named(cmd_per_lun, pvscsi_cmd_per_lun, int, PVSCSI_RW);
+MODULE_PARM_DESC(cmd_per_lun, "Maximum commands per lun - (default="
+		 __stringify(PVSCSI_MAX_REQ_QUEUE_DEPTH) ")");
+
+module_param_named(disable_msi, pvscsi_disable_msi, bool, PVSCSI_RW);
+MODULE_PARM_DESC(disable_msi, "Disable MSI use in driver - (default=0)");
+
+module_param_named(disable_msix, pvscsi_disable_msix, bool, PVSCSI_RW);
+MODULE_PARM_DESC(disable_msix, "Disable MSI-X use in driver - (default=0)");
+
+module_param_named(use_msg, pvscsi_use_msg, bool, PVSCSI_RW);
+MODULE_PARM_DESC(use_msg, "Use msg ring when available - (default=1)");
+
+static const struct pci_device_id pvscsi_pci_tbl[] = {
+	{ PCI_VDEVICE(VMWARE, PCI_DEVICE_ID_VMWARE_PVSCSI) },
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, pvscsi_pci_tbl);
+
+static struct device *
+pvscsi_dev(const struct pvscsi_adapter *adapter)
+{
+	return &(adapter->dev->dev);
+}
+
+static struct pvscsi_ctx *
+pvscsi_find_context(const struct pvscsi_adapter *adapter, struct scsi_cmnd *cmd)
+{
+	struct pvscsi_ctx *ctx, *end;
+
+	end = &adapter->cmd_map[adapter->req_depth];
+	for (ctx = adapter->cmd_map; ctx < end; ctx++)
+		if (ctx->cmd == cmd)
+			return ctx;
+
+	return NULL;
+}
+
+static struct pvscsi_ctx *
+pvscsi_acquire_context(struct pvscsi_adapter *adapter, struct scsi_cmnd *cmd)
+{
+	struct pvscsi_ctx *ctx;
+
+	if (list_empty(&adapter->cmd_pool))
+		return NULL;
+
+	ctx = list_first_entry(&adapter->cmd_pool, struct pvscsi_ctx, list);
+	ctx->cmd = cmd;
+	list_del(&ctx->list);
+
+	return ctx;
+}
+
+static void pvscsi_release_context(struct pvscsi_adapter *adapter,
+				   struct pvscsi_ctx *ctx)
+{
+	ctx->cmd = NULL;
+	list_add(&ctx->list, &adapter->cmd_pool);
+}
+
+/*
+ * Map a pvscsi_ctx struct to a context ID field value; we map to a simple
+ * non-zero integer. ctx always points to an entry in cmd_map array, hence
+ * the return value is always >=1.
+ */
+static u64 pvscsi_map_context(const struct pvscsi_adapter *adapter,
+			      const struct pvscsi_ctx *ctx)
+{
+	return ctx - adapter->cmd_map + 1;
+}
+
+static struct pvscsi_ctx *
+pvscsi_get_context(const struct pvscsi_adapter *adapter, u64 context)
+{
+	return &adapter->cmd_map[context - 1];
+}
+
+static void pvscsi_reg_write(const struct pvscsi_adapter *adapter,
+			     u32 offset, u32 val)
+{
+	writel(val, adapter->mmioBase + offset);
+}
+
+static u32 pvscsi_reg_read(const struct pvscsi_adapter *adapter, u32 offset)
+{
+	return readl(adapter->mmioBase + offset);
+}
+
+static u32 pvscsi_read_intr_status(const struct pvscsi_adapter *adapter)
+{
+	return pvscsi_reg_read(adapter, PVSCSI_REG_OFFSET_INTR_STATUS);
+}
+
+static void pvscsi_write_intr_status(const struct pvscsi_adapter *adapter,
+				     u32 val)
+{
+	pvscsi_reg_write(adapter, PVSCSI_REG_OFFSET_INTR_STATUS, val);
+}
+
+static void pvscsi_unmask_intr(const struct pvscsi_adapter *adapter)
+{
+	u32 intr_bits;
+
+	intr_bits = PVSCSI_INTR_CMPL_MASK;
+	if (adapter->use_msg)
+		intr_bits |= PVSCSI_INTR_MSG_MASK;
+
+	pvscsi_reg_write(adapter, PVSCSI_REG_OFFSET_INTR_MASK, intr_bits);
+}
+
+static void pvscsi_mask_intr(const struct pvscsi_adapter *adapter)
+{
+	pvscsi_reg_write(adapter, PVSCSI_REG_OFFSET_INTR_MASK, 0);
+}
+
+static void pvscsi_write_cmd_desc(const struct pvscsi_adapter *adapter,
+				  u32 cmd, const void *desc, size_t len)
+{
+	const u32 *ptr = desc;
+	size_t i;
+
+	len /= sizeof(*ptr);
+	pvscsi_reg_write(adapter, PVSCSI_REG_OFFSET_COMMAND, cmd);
+	for (i = 0; i < len; i++)
+		pvscsi_reg_write(adapter,
+				 PVSCSI_REG_OFFSET_COMMAND_DATA, ptr[i]);
+}
+
+static void pvscsi_abort_cmd(const struct pvscsi_adapter *adapter,
+			     const struct pvscsi_ctx *ctx)
+{
+	struct PVSCSICmdDescAbortCmd cmd = { 0 };
+
+	cmd.target = ctx->cmd->device->id;
+	cmd.context = pvscsi_map_context(adapter, ctx);
+
+	pvscsi_write_cmd_desc(adapter, PVSCSI_CMD_ABORT_CMD, &cmd, sizeof(cmd));
+}
+
+static void pvscsi_kick_rw_io(const struct pvscsi_adapter *adapter)
+{
+	pvscsi_reg_write(adapter, PVSCSI_REG_OFFSET_KICK_RW_IO, 0);
+}
+
+static void pvscsi_process_request_ring(const struct pvscsi_adapter *adapter)
+{
+	pvscsi_reg_write(adapter, PVSCSI_REG_OFFSET_KICK_NON_RW_IO, 0);
+}
+
+static int scsi_is_rw(unsigned char op)
+{
+	return op == READ_6  || op == WRITE_6 ||
+	       op == READ_10 || op == WRITE_10 ||
+	       op == READ_12 || op == WRITE_12 ||
+	       op == READ_16 || op == WRITE_16;
+}
+
+static void pvscsi_kick_io(const struct pvscsi_adapter *adapter,
+			   unsigned char op)
+{
+	if (scsi_is_rw(op))
+		pvscsi_kick_rw_io(adapter);
+	else
+		pvscsi_process_request_ring(adapter);
+}
+
+static void ll_adapter_reset(const struct pvscsi_adapter *adapter)
+{
+	dev_dbg(pvscsi_dev(adapter), "Adapter Reset on %p\n", adapter);
+
+	pvscsi_write_cmd_desc(adapter, PVSCSI_CMD_ADAPTER_RESET, NULL, 0);
+}
+
+static void ll_bus_reset(const struct pvscsi_adapter *adapter)
+{
+	dev_dbg(pvscsi_dev(adapter), "Reseting bus on %p\n", adapter);
+
+	pvscsi_write_cmd_desc(adapter, PVSCSI_CMD_RESET_BUS, NULL, 0);
+}
+
+static void ll_device_reset(const struct pvscsi_adapter *adapter, u32 target)
+{
+	struct PVSCSICmdDescResetDevice cmd = { 0 };
+
+	dev_dbg(pvscsi_dev(adapter), "Reseting device: target=%u\n", target);
+
+	cmd.target = target;
+
+	pvscsi_write_cmd_desc(adapter, PVSCSI_CMD_RESET_DEVICE,
+			      &cmd, sizeof(cmd));
+}
+
+static void pvscsi_create_sg(struct pvscsi_ctx *ctx,
+			     struct scatterlist *sg, unsigned count)
+{
+	unsigned i;
+	struct PVSCSISGElement *sge;
+
+	BUG_ON(count > PVSCSI_MAX_NUM_SG_ENTRIES_PER_SEGMENT);
+
+	sge = &ctx->sgl->sge[0];
+	for (i = 0; i < count; i++, sg++) {
+		sge[i].addr   = sg_dma_address(sg);
+		sge[i].length = sg_dma_len(sg);
+		sge[i].flags  = 0;
+	}
+}
+
+/*
+ * Map all data buffers for a command into PCI space and
+ * setup the scatter/gather list if needed.
+ */
+static void pvscsi_map_buffers(struct pvscsi_adapter *adapter,
+			       struct pvscsi_ctx *ctx, struct scsi_cmnd *cmd,
+			       struct PVSCSIRingReqDesc *e)
+{
+	unsigned count;
+	unsigned bufflen = scsi_bufflen(cmd);
+	struct scatterlist *sg;
+
+	e->dataLen = bufflen;
+	e->dataAddr = 0;
+	if (bufflen == 0)
+		return;
+
+	sg = scsi_sglist(cmd);
+	count = scsi_sg_count(cmd);
+	if (count != 0) {
+		int segs = scsi_dma_map(cmd);
+		if (segs > 1) {
+			pvscsi_create_sg(ctx, sg, segs);
+
+			e->flags |= PVSCSI_FLAG_CMD_WITH_SG_LIST;
+			ctx->sglPA = pci_map_single(adapter->dev, ctx->sgl,
+						    SGL_SIZE, PCI_DMA_TODEVICE);
+			e->dataAddr = ctx->sglPA;
+		} else
+			e->dataAddr = sg_dma_address(sg);
+	} else {
+		/*
+		 * In case there is no S/G list, scsi_sglist points
+		 * directly to the buffer.
+		 */
+		ctx->dataPA = pci_map_single(adapter->dev, sg, bufflen,
+					     cmd->sc_data_direction);
+		e->dataAddr = ctx->dataPA;
+	}
+}
+
+static void pvscsi_unmap_buffers(const struct pvscsi_adapter *adapter,
+				 struct pvscsi_ctx *ctx)
+{
+	struct scsi_cmnd *cmd;
+	unsigned bufflen;
+
+	cmd = ctx->cmd;
+	bufflen = scsi_bufflen(cmd);
+
+	if (bufflen != 0) {
+		unsigned count = scsi_sg_count(cmd);
+
+		if (count != 0) {
+			scsi_dma_unmap(cmd);
+			if (ctx->sglPA) {
+				pci_unmap_single(adapter->dev, ctx->sglPA,
+						 SGL_SIZE, PCI_DMA_TODEVICE);
+				ctx->sglPA = 0;
+			}
+		} else
+			pci_unmap_single(adapter->dev, ctx->dataPA, bufflen,
+					 cmd->sc_data_direction);
+	}
+	if (cmd->sense_buffer)
+		pci_unmap_single(adapter->dev, ctx->sensePA,
+				 SCSI_SENSE_BUFFERSIZE, PCI_DMA_FROMDEVICE);
+}
+
+static int __devinit pvscsi_allocate_rings(struct pvscsi_adapter *adapter)
+{
+	adapter->rings_state = pci_alloc_consistent(adapter->dev, PAGE_SIZE,
+						    &adapter->ringStatePA);
+	if (!adapter->rings_state)
+		return -ENOMEM;
+
+	adapter->req_pages = min(PVSCSI_MAX_NUM_PAGES_REQ_RING,
+				 pvscsi_ring_pages);
+	adapter->req_depth = adapter->req_pages
+					* PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE;
+	adapter->req_ring = pci_alloc_consistent(adapter->dev,
+						 adapter->req_pages * PAGE_SIZE,
+						 &adapter->reqRingPA);
+	if (!adapter->req_ring)
+		return -ENOMEM;
+
+	adapter->cmp_pages = min(PVSCSI_MAX_NUM_PAGES_CMP_RING,
+				 pvscsi_ring_pages);
+	adapter->cmp_ring = pci_alloc_consistent(adapter->dev,
+						 adapter->cmp_pages * PAGE_SIZE,
+						 &adapter->cmpRingPA);
+	if (!adapter->cmp_ring)
+		return -ENOMEM;
+
+	BUG_ON(!IS_ALIGNED(adapter->ringStatePA, PAGE_SIZE));
+	BUG_ON(!IS_ALIGNED(adapter->reqRingPA, PAGE_SIZE));
+	BUG_ON(!IS_ALIGNED(adapter->cmpRingPA, PAGE_SIZE));
+
+	if (!adapter->use_msg)
+		return 0;
+
+	adapter->msg_pages = min(PVSCSI_MAX_NUM_PAGES_MSG_RING,
+				 pvscsi_msg_ring_pages);
+	adapter->msg_ring = pci_alloc_consistent(adapter->dev,
+						 adapter->msg_pages * PAGE_SIZE,
+						 &adapter->msgRingPA);
+	if (!adapter->msg_ring)
+		return -ENOMEM;
+	BUG_ON(!IS_ALIGNED(adapter->msgRingPA, PAGE_SIZE));
+
+	return 0;
+}
+
+static void pvscsi_setup_all_rings(const struct pvscsi_adapter *adapter)
+{
+	struct PVSCSICmdDescSetupRings cmd = { 0 };
+	dma_addr_t base;
+	unsigned i;
+
+	cmd.ringsStatePPN   = adapter->ringStatePA >> PAGE_SHIFT;
+	cmd.reqRingNumPages = adapter->req_pages;
+	cmd.cmpRingNumPages = adapter->cmp_pages;
+
+	base = adapter->reqRingPA;
+	for (i = 0; i < adapter->req_pages; i++) {
+		cmd.reqRingPPNs[i] = base >> PAGE_SHIFT;
+		base += PAGE_SIZE;
+	}
+
+	base = adapter->cmpRingPA;
+	for (i = 0; i < adapter->cmp_pages; i++) {
+		cmd.cmpRingPPNs[i] = base >> PAGE_SHIFT;
+		base += PAGE_SIZE;
+	}
+
+	memset(adapter->rings_state, 0, PAGE_SIZE);
+	memset(adapter->req_ring, 0, adapter->req_pages * PAGE_SIZE);
+	memset(adapter->cmp_ring, 0, adapter->cmp_pages * PAGE_SIZE);
+
+	pvscsi_write_cmd_desc(adapter, PVSCSI_CMD_SETUP_RINGS,
+			      &cmd, sizeof(cmd));
+
+	if (adapter->use_msg) {
+		struct PVSCSICmdDescSetupMsgRing cmd_msg = { 0 };
+
+		cmd_msg.numPages = adapter->msg_pages;
+
+		base = adapter->msgRingPA;
+		for (i = 0; i < adapter->msg_pages; i++) {
+			cmd_msg.ringPPNs[i] = base >> PAGE_SHIFT;
+			base += PAGE_SIZE;
+		}
+		memset(adapter->msg_ring, 0, adapter->msg_pages * PAGE_SIZE);
+
+		pvscsi_write_cmd_desc(adapter, PVSCSI_CMD_SETUP_MSG_RING,
+				      &cmd_msg, sizeof(cmd_msg));
+	}
+}
+
+/*
+ * Pull a completion descriptor off and pass the completion back
+ * to the SCSI mid layer.
+ */
+static void pvscsi_complete_request(struct pvscsi_adapter *adapter,
+				    const struct PVSCSIRingCmpDesc *e)
+{
+	struct pvscsi_ctx *ctx;
+	struct scsi_cmnd *cmd;
+	u32 btstat = e->hostStatus;
+	u32 sdstat = e->scsiStatus;
+
+	ctx = pvscsi_get_context(adapter, e->context);
+	cmd = ctx->cmd;
+	pvscsi_unmap_buffers(adapter, ctx);
+	pvscsi_release_context(adapter, ctx);
+	cmd->result = 0;
+
+	if (sdstat != SAM_STAT_GOOD &&
+	    (btstat == BTSTAT_SUCCESS ||
+	     btstat == BTSTAT_LINKED_COMMAND_COMPLETED ||
+	     btstat == BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG)) {
+		cmd->result = (DID_OK << 16) | sdstat;
+		if (sdstat == SAM_STAT_CHECK_CONDITION && cmd->sense_buffer)
+			cmd->result |= (DRIVER_SENSE << 24);
+	} else
+		switch (btstat) {
+		case BTSTAT_SUCCESS:
+		case BTSTAT_LINKED_COMMAND_COMPLETED:
+		case BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG:
+			/* If everything went fine, let's move on..  */
+			cmd->result = (DID_OK << 16);
+			break;
+
+		case BTSTAT_DATARUN:
+		case BTSTAT_DATA_UNDERRUN:
+			/* Report residual data in underruns */
+			scsi_set_resid(cmd, scsi_bufflen(cmd) - e->dataLen);
+			cmd->result = (DID_ERROR << 16);
+			break;
+
+		case BTSTAT_SELTIMEO:
+			/* Our emulation returns this for non-connected devs */
+			cmd->result = (DID_BAD_TARGET << 16);
+			break;
+
+		case BTSTAT_LUNMISMATCH:
+		case BTSTAT_TAGREJECT:
+		case BTSTAT_BADMSG:
+			cmd->result = (DRIVER_INVALID << 24);
+			/* fall through */
+
+		case BTSTAT_HAHARDWARE:
+		case BTSTAT_INVPHASE:
+		case BTSTAT_HATIMEOUT:
+		case BTSTAT_NORESPONSE:
+		case BTSTAT_DISCONNECT:
+		case BTSTAT_HASOFTWARE:
+		case BTSTAT_BUSFREE:
+		case BTSTAT_SENSFAILED:
+			cmd->result |= (DID_ERROR << 16);
+			break;
+
+		case BTSTAT_SENTRST:
+		case BTSTAT_RECVRST:
+		case BTSTAT_BUSRESET:
+			cmd->result = (DID_RESET << 16);
+			break;
+
+		case BTSTAT_ABORTQUEUE:
+			cmd->result = (DID_ABORT << 16);
+			break;
+
+		case BTSTAT_SCSIPARITY:
+			cmd->result = (DID_PARITY << 16);
+			break;
+
+		default:
+			cmd->result = (DID_ERROR << 16);
+			scmd_printk(KERN_DEBUG, cmd,
+				    "Unknown completion status: 0x%x\n",
+				    btstat);
+	}
+
+	dev_dbg(&cmd->device->sdev_gendev,
+		"cmd=%p %x ctx=%p result=0x%x status=0x%x,%x\n",
+		cmd, cmd->cmnd[0], ctx, cmd->result, btstat, sdstat);
+
+	cmd->scsi_done(cmd);
+}
+
+/*
+ * barrier usage : Since the PVSCSI device is emulated, there could be cases
+ * where we may want to serialize some accesses between the driver and the
+ * emulation layer. We use compiler barriers instead of the more expensive
+ * memory barriers because PVSCSI is only supported on X86 which has strong
+ * memory access ordering.
+ */
+static void pvscsi_process_completion_ring(struct pvscsi_adapter *adapter)
+{
+	struct PVSCSIRingsState *s = adapter->rings_state;
+	struct PVSCSIRingCmpDesc *ring = adapter->cmp_ring;
+	u32 cmp_entries = s->cmpNumEntriesLog2;
+
+	while (s->cmpConsIdx != s->cmpProdIdx) {
+		struct PVSCSIRingCmpDesc *e = ring + (s->cmpConsIdx &
+						      MASK(cmp_entries));
+		/*
+		 * This barrier() ensures that *e is not dereferenced while
+		 * the device emulation still writes data into the slot.
+		 * Since the device emulation advances s->cmpProdIdx only after
+		 * updating the slot we want to check it first.
+		 */
+		barrier();
+		pvscsi_complete_request(adapter, e);
+		/*
+		 * This barrier() ensures that compiler doesn't reorder write
+		 * to s->cmpConsIdx before the read of (*e) inside
+		 * pvscsi_complete_request. Otherwise, device emulation may
+		 * overwrite *e before we had a chance to read it.
+		 */
+		barrier();
+		s->cmpConsIdx++;
+	}
+}
+
+/*
+ * Translate a Linux SCSI request into a request ring entry.
+ */
+static int pvscsi_queue_ring(struct pvscsi_adapter *adapter,
+			     struct pvscsi_ctx *ctx, struct scsi_cmnd *cmd)
+{
+	struct PVSCSIRingsState *s;
+	struct PVSCSIRingReqDesc *e;
+	struct scsi_device *sdev;
+	u32 req_entries;
+
+	s = adapter->rings_state;
+	sdev = cmd->device;
+	req_entries = s->reqNumEntriesLog2;
+
+	/*
+	 * If this condition holds, we might have room on the request ring, but
+	 * we might not have room on the completion ring for the response.
+	 * However, we have already ruled out this possibility - we would not
+	 * have successfully allocated a context if it were true, since we only
+	 * have one context per request entry.  Check for it anyway, since it
+	 * would be a serious bug.
+	 */
+	if (s->reqProdIdx - s->cmpConsIdx >= 1 << req_entries) {
+		scmd_printk(KERN_ERR, cmd, "vmw_pvscsi: "
+			    "ring full: reqProdIdx=%d cmpConsIdx=%d\n",
+			    s->reqProdIdx, s->cmpConsIdx);
+		return -1;
+	}
+
+	e = adapter->req_ring + (s->reqProdIdx & MASK(req_entries));
+
+	e->bus    = sdev->channel;
+	e->target = sdev->id;
+	memset(e->lun, 0, sizeof(e->lun));
+	e->lun[1] = sdev->lun;
+
+	if (cmd->sense_buffer) {
+		ctx->sensePA = pci_map_single(adapter->dev, cmd->sense_buffer,
+					      SCSI_SENSE_BUFFERSIZE,
+					      PCI_DMA_FROMDEVICE);
+		e->senseAddr = ctx->sensePA;
+		e->senseLen = SCSI_SENSE_BUFFERSIZE;
+	} else {
+		e->senseLen  = 0;
+		e->senseAddr = 0;
+	}
+	e->cdbLen   = cmd->cmd_len;
+	e->vcpuHint = smp_processor_id();
+	memcpy(e->cdb, cmd->cmnd, e->cdbLen);
+
+	e->tag = SIMPLE_QUEUE_TAG;
+	if (sdev->tagged_supported &&
+	    (cmd->tag == HEAD_OF_QUEUE_TAG ||
+	     cmd->tag == ORDERED_QUEUE_TAG))
+		e->tag = cmd->tag;
+
+	if (cmd->sc_data_direction == DMA_FROM_DEVICE)
+		e->flags = PVSCSI_FLAG_CMD_DIR_TOHOST;
+	else if (cmd->sc_data_direction == DMA_TO_DEVICE)
+		e->flags = PVSCSI_FLAG_CMD_DIR_TODEVICE;
+	else if (cmd->sc_data_direction == DMA_NONE)
+		e->flags = PVSCSI_FLAG_CMD_DIR_NONE;
+	else
+		e->flags = 0;
+
+	pvscsi_map_buffers(adapter, ctx, cmd, e);
+
+	e->context = pvscsi_map_context(adapter, ctx);
+
+	barrier();
+
+	s->reqProdIdx++;
+
+	return 0;
+}
+
+static int pvscsi_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+{
+	struct Scsi_Host *host = cmd->device->host;
+	struct pvscsi_adapter *adapter = shost_priv(host);
+	struct pvscsi_ctx *ctx;
+	unsigned long flags;
+
+	spin_lock_irqsave(&adapter->hw_lock, flags);
+
+	ctx = pvscsi_acquire_context(adapter, cmd);
+	if (!ctx || pvscsi_queue_ring(adapter, ctx, cmd) != 0) {
+		if (ctx)
+			pvscsi_release_context(adapter, ctx);
+		spin_unlock_irqrestore(&adapter->hw_lock, flags);
+		return SCSI_MLQUEUE_HOST_BUSY;
+	}
+
+	cmd->scsi_done = done;
+
+	dev_dbg(&cmd->device->sdev_gendev,
+		"queued cmd %p, ctx %p, op=%x\n", cmd, ctx, cmd->cmnd[0]);
+
+	spin_unlock_irqrestore(&adapter->hw_lock, flags);
+
+	pvscsi_kick_io(adapter, cmd->cmnd[0]);
+
+	return 0;
+}
+
+static int pvscsi_abort(struct scsi_cmnd *cmd)
+{
+	struct pvscsi_adapter *adapter = shost_priv(cmd->device->host);
+	struct pvscsi_ctx *ctx;
+	unsigned long flags;
+
+	scmd_printk(KERN_DEBUG, cmd, "task abort on host %u, %p\n",
+		    adapter->host->host_no, cmd);
+
+	spin_lock_irqsave(&adapter->hw_lock, flags);
+
+	/*
+	 * Poll the completion ring first - we might be trying to abort
+	 * a command that is waiting to be dispatched in the completion ring.
+	 */
+	pvscsi_process_completion_ring(adapter);
+
+	/*
+	 * If there is no context for the command, it either already succeeded
+	 * or else was never properly issued.  Not our problem.
+	 */
+	ctx = pvscsi_find_context(adapter, cmd);
+	if (!ctx) {
+		scmd_printk(KERN_DEBUG, cmd, "Failed to abort cmd %p\n", cmd);
+		goto out;
+	}
+
+	pvscsi_abort_cmd(adapter, ctx);
+
+	pvscsi_process_completion_ring(adapter);
+
+out:
+	spin_unlock_irqrestore(&adapter->hw_lock, flags);
+	return SUCCESS;
+}
+
+/*
+ * Abort all outstanding requests.  This is only safe to use if the completion
+ * ring will never be walked again or the device has been reset, because it
+ * destroys the 1-1 mapping between context field passed to emulation and our
+ * request structure.
+ */
+static void pvscsi_reset_all(struct pvscsi_adapter *adapter)
+{
+	unsigned i;
+
+	for (i = 0; i < adapter->req_depth; i++) {
+		struct pvscsi_ctx *ctx = &adapter->cmd_map[i];
+		struct scsi_cmnd *cmd = ctx->cmd;
+		if (cmd) {
+			scmd_printk(KERN_ERR, cmd,
+				    "Forced reset on cmd %p\n", cmd);
+			pvscsi_unmap_buffers(adapter, ctx);
+			pvscsi_release_context(adapter, ctx);
+			cmd->result = (DID_RESET << 16);
+			cmd->scsi_done(cmd);
+		}
+	}
+}
+
+static int pvscsi_host_reset(struct scsi_cmnd *cmd)
+{
+	struct Scsi_Host *host = cmd->device->host;
+	struct pvscsi_adapter *adapter = shost_priv(host);
+	unsigned long flags;
+	bool use_msg;
+
+	scmd_printk(KERN_INFO, cmd, "SCSI Host reset\n");
+
+	spin_lock_irqsave(&adapter->hw_lock, flags);
+
+	use_msg = adapter->use_msg;
+
+	if (use_msg) {
+		adapter->use_msg = 0;
+		spin_unlock_irqrestore(&adapter->hw_lock, flags);
+
+		/*
+		 * Now that we know that the ISR won't add more work on the
+		 * workqueue we can safely flush any outstanding work.
+		 */
+		flush_workqueue(adapter->workqueue);
+		spin_lock_irqsave(&adapter->hw_lock, flags);
+	}
+
+	/*
+	 * We're going to tear down the entire ring structure and set it back
+	 * up, so stalling new requests until all completions are flushed and
+	 * the rings are back in place.
+	 */
+
+	pvscsi_process_request_ring(adapter);
+
+	ll_adapter_reset(adapter);
+
+	/*
+	 * Now process any completions.  Note we do this AFTER adapter reset,
+	 * which is strange, but stops races where completions get posted
+	 * between processing the ring and issuing the reset.  The backend will
+	 * not touch the ring memory after reset, so the immediately pre-reset
+	 * completion ring state is still valid.
+	 */
+	pvscsi_process_completion_ring(adapter);
+
+	pvscsi_reset_all(adapter);
+	adapter->use_msg = use_msg;
+	pvscsi_setup_all_rings(adapter);
+	pvscsi_unmask_intr(adapter);
+
+	spin_unlock_irqrestore(&adapter->hw_lock, flags);
+
+	return SUCCESS;
+}
+
+static int pvscsi_bus_reset(struct scsi_cmnd *cmd)
+{
+	struct Scsi_Host *host = cmd->device->host;
+	struct pvscsi_adapter *adapter = shost_priv(host);
+	unsigned long flags;
+
+	scmd_printk(KERN_INFO, cmd, "SCSI Bus reset\n");
+
+	/*
+	 * We don't want to queue new requests for this bus after
+	 * flushing all pending requests to emulation, since new
+	 * requests could then sneak in during this bus reset phase,
+	 * so take the lock now.
+	 */
+	spin_lock_irqsave(&adapter->hw_lock, flags);
+
+	pvscsi_process_request_ring(adapter);
+	ll_bus_reset(adapter);
+	pvscsi_process_completion_ring(adapter);
+
+	spin_unlock_irqrestore(&adapter->hw_lock, flags);
+
+	return SUCCESS;
+}
+
+static int pvscsi_device_reset(struct scsi_cmnd *cmd)
+{
+	struct Scsi_Host *host = cmd->device->host;
+	struct pvscsi_adapter *adapter = shost_priv(host);
+	unsigned long flags;
+
+	scmd_printk(KERN_INFO, cmd, "SCSI device reset on scsi%u:%u\n",
+		    host->host_no, cmd->device->id);
+
+	/*
+	 * We don't want to queue new requests for this device after flushing
+	 * all pending requests to emulation, since new requests could then
+	 * sneak in during this device reset phase, so take the lock now.
+	 */
+	spin_lock_irqsave(&adapter->hw_lock, flags);
+
+	pvscsi_process_request_ring(adapter);
+	ll_device_reset(adapter, cmd->device->id);
+	pvscsi_process_completion_ring(adapter);
+
+	spin_unlock_irqrestore(&adapter->hw_lock, flags);
+
+	return SUCCESS;
+}
+
+static struct scsi_host_template pvscsi_template;
+
+static const char *pvscsi_info(struct Scsi_Host *host)
+{
+	struct pvscsi_adapter *adapter = shost_priv(host);
+	static char buf[256];
+
+	sprintf(buf, "VMware PVSCSI storage adapter rev %d, req/cmp/msg rings: "
+		"%u/%u/%u pages, cmd_per_lun=%u", adapter->rev,
+		adapter->req_pages, adapter->cmp_pages, adapter->msg_pages,
+		pvscsi_template.cmd_per_lun);
+
+	return buf;
+}
+
+static struct scsi_host_template pvscsi_template = {
+	.module				= THIS_MODULE,
+	.name				= "VMware PVSCSI Host Adapter",
+	.proc_name			= "vmw_pvscsi",
+	.info				= pvscsi_info,
+	.queuecommand			= pvscsi_queue,
+	.this_id			= -1,
+	.sg_tablesize			= PVSCSI_MAX_NUM_SG_ENTRIES_PER_SEGMENT,
+	.dma_boundary			= UINT_MAX,
+	.max_sectors			= 0xffff,
+	.use_clustering			= ENABLE_CLUSTERING,
+	.eh_abort_handler		= pvscsi_abort,
+	.eh_device_reset_handler	= pvscsi_device_reset,
+	.eh_bus_reset_handler		= pvscsi_bus_reset,
+	.eh_host_reset_handler		= pvscsi_host_reset,
+};
+
+static void pvscsi_process_msg(const struct pvscsi_adapter *adapter,
+			       const struct PVSCSIRingMsgDesc *e)
+{
+	struct PVSCSIRingsState *s = adapter->rings_state;
+	struct Scsi_Host *host = adapter->host;
+	struct scsi_device *sdev;
+
+	printk(KERN_INFO "vmw_pvscsi: msg type: 0x%x - MSG RING: %u/%u (%u) \n",
+	       e->type, s->msgProdIdx, s->msgConsIdx, s->msgNumEntriesLog2);
+
+	BUILD_BUG_ON(PVSCSI_MSG_LAST != 2);
+
+	if (e->type == PVSCSI_MSG_DEV_ADDED) {
+		struct PVSCSIMsgDescDevStatusChanged *desc;
+		desc = (struct PVSCSIMsgDescDevStatusChanged *)e;
+
+		printk(KERN_INFO
+		       "vmw_pvscsi: msg: device added at scsi%u:%u:%u\n",
+		       desc->bus, desc->target, desc->lun[1]);
+
+		if (!scsi_host_get(host))
+			return;
+
+		sdev = scsi_device_lookup(host, desc->bus, desc->target,
+					  desc->lun[1]);
+		if (sdev) {
+			printk(KERN_INFO "vmw_pvscsi: device already exists\n");
+			scsi_device_put(sdev);
+		} else
+			scsi_add_device(adapter->host, desc->bus,
+					desc->target, desc->lun[1]);
+
+		scsi_host_put(host);
+	} else if (e->type == PVSCSI_MSG_DEV_REMOVED) {
+		struct PVSCSIMsgDescDevStatusChanged *desc;
+		desc = (struct PVSCSIMsgDescDevStatusChanged *)e;
+
+		printk(KERN_INFO
+		       "vmw_pvscsi: msg: device removed at scsi%u:%u:%u\n",
+		       desc->bus, desc->target, desc->lun[1]);
+
+		if (!scsi_host_get(host))
+			return;
+
+		sdev = scsi_device_lookup(host, desc->bus, desc->target,
+					  desc->lun[1]);
+		if (sdev) {
+			scsi_remove_device(sdev);
+			scsi_device_put(sdev);
+		} else
+			printk(KERN_INFO
+			       "vmw_pvscsi: failed to lookup scsi%u:%u:%u\n",
+			       desc->bus, desc->target, desc->lun[1]);
+
+		scsi_host_put(host);
+	}
+}
+
+static int pvscsi_msg_pending(const struct pvscsi_adapter *adapter)
+{
+	struct PVSCSIRingsState *s = adapter->rings_state;
+
+	return s->msgProdIdx != s->msgConsIdx;
+}
+
+static void pvscsi_process_msg_ring(const struct pvscsi_adapter *adapter)
+{
+	struct PVSCSIRingsState *s = adapter->rings_state;
+	struct PVSCSIRingMsgDesc *ring = adapter->msg_ring;
+	u32 msg_entries = s->msgNumEntriesLog2;
+
+	while (pvscsi_msg_pending(adapter)) {
+		struct PVSCSIRingMsgDesc *e = ring + (s->msgConsIdx &
+						      MASK(msg_entries));
+
+		barrier();
+		pvscsi_process_msg(adapter, e);
+		barrier();
+		s->msgConsIdx++;
+	}
+}
+
+static void pvscsi_msg_workqueue_handler(struct work_struct *data)
+{
+	struct pvscsi_adapter *adapter;
+
+	adapter = container_of(data, struct pvscsi_adapter, work);
+
+	pvscsi_process_msg_ring(adapter);
+}
+
+static int pvscsi_setup_msg_workqueue(struct pvscsi_adapter *adapter)
+{
+	char name[32];
+
+	if (!pvscsi_use_msg)
+		return 0;
+
+	pvscsi_reg_write(adapter, PVSCSI_REG_OFFSET_COMMAND,
+			 PVSCSI_CMD_SETUP_MSG_RING);
+
+	if (pvscsi_reg_read(adapter, PVSCSI_REG_OFFSET_COMMAND_STATUS) == -1)
+		return 0;
+
+	snprintf(name, sizeof(name),
+		 "vmw_pvscsi_wq_%u", adapter->host->host_no);
+
+	adapter->workqueue = create_singlethread_workqueue(name);
+	if (!adapter->workqueue) {
+		printk(KERN_ERR "vmw_pvscsi: failed to create work queue\n");
+		return 0;
+	}
+	INIT_WORK(&adapter->work, pvscsi_msg_workqueue_handler);
+
+	return 1;
+}
+
+static irqreturn_t pvscsi_isr(int irq, void *devp)
+{
+	struct pvscsi_adapter *adapter = devp;
+	int handled;
+
+	if (adapter->use_msi || adapter->use_msix)
+		handled = true;
+	else {
+		u32 val = pvscsi_read_intr_status(adapter);
+		handled = (val & PVSCSI_INTR_ALL_SUPPORTED) != 0;
+		if (handled)
+			pvscsi_write_intr_status(devp, val);
+	}
+
+	if (handled) {
+		unsigned long flags;
+
+		spin_lock_irqsave(&adapter->hw_lock, flags);
+
+		pvscsi_process_completion_ring(adapter);
+		if (adapter->use_msg && pvscsi_msg_pending(adapter))
+			queue_work(adapter->workqueue, &adapter->work);
+
+		spin_unlock_irqrestore(&adapter->hw_lock, flags);
+	}
+
+	return IRQ_RETVAL(handled);
+}
+
+static void pvscsi_free_sgls(const struct pvscsi_adapter *adapter)
+{
+	struct pvscsi_ctx *ctx = adapter->cmd_map;
+	unsigned i;
+
+	for (i = 0; i < adapter->req_depth; ++i, ++ctx)
+		free_pages((unsigned long)ctx->sgl, get_order(SGL_SIZE));
+}
+
+static int pvscsi_setup_msix(const struct pvscsi_adapter *adapter, int *irq)
+{
+	struct msix_entry entry = { 0, PVSCSI_VECTOR_COMPLETION };
+	int ret;
+
+	ret = pci_enable_msix(adapter->dev, &entry, 1);
+	if (ret)
+		return ret;
+
+	*irq = entry.vector;
+
+	return 0;
+}
+
+static void pvscsi_shutdown_intr(struct pvscsi_adapter *adapter)
+{
+	if (adapter->irq) {
+		free_irq(adapter->irq, adapter);
+		adapter->irq = 0;
+	}
+	if (adapter->use_msi) {
+		pci_disable_msi(adapter->dev);
+		adapter->use_msi = 0;
+	} else if (adapter->use_msix) {
+		pci_disable_msix(adapter->dev);
+		adapter->use_msix = 0;
+	}
+}
+
+static void pvscsi_release_resources(struct pvscsi_adapter *adapter)
+{
+	pvscsi_shutdown_intr(adapter);
+
+	if (adapter->workqueue)
+		destroy_workqueue(adapter->workqueue);
+
+	if (adapter->mmioBase)
+		pci_iounmap(adapter->dev, adapter->mmioBase);
+
+	pci_release_regions(adapter->dev);
+
+	if (adapter->cmd_map) {
+		pvscsi_free_sgls(adapter);
+		kfree(adapter->cmd_map);
+	}
+
+	if (adapter->rings_state)
+		pci_free_consistent(adapter->dev, PAGE_SIZE,
+				    adapter->rings_state, adapter->ringStatePA);
+
+	if (adapter->req_ring)
+		pci_free_consistent(adapter->dev,
+				    adapter->req_pages * PAGE_SIZE,
+				    adapter->req_ring, adapter->reqRingPA);
+
+	if (adapter->cmp_ring)
+		pci_free_consistent(adapter->dev,
+				    adapter->cmp_pages * PAGE_SIZE,
+				    adapter->cmp_ring, adapter->cmpRingPA);
+
+	if (adapter->msg_ring)
+		pci_free_consistent(adapter->dev,
+				    adapter->msg_pages * PAGE_SIZE,
+				    adapter->msg_ring, adapter->msgRingPA);
+}
+
+/*
+ * Allocate scatter gather lists.
+ *
+ * These are statically allocated.  Trying to be clever was not worth it.
+ *
+ * Dynamic allocation can fail, and we can't go deeep into the memory
+ * allocator, since we're a SCSI driver, and trying too hard to allocate
+ * memory might generate disk I/O.  We also don't want to fail disk I/O
+ * in that case because we can't get an allocation - the I/O could be
+ * trying to swap out data to free memory.  Since that is pathological,
+ * just use a statically allocated scatter list.
+ *
+ */
+static int __devinit pvscsi_allocate_sg(struct pvscsi_adapter *adapter)
+{
+	struct pvscsi_ctx *ctx;
+	int i;
+
+	ctx = adapter->cmd_map;
+	BUILD_BUG_ON(sizeof(struct pvscsi_sg_list) > SGL_SIZE);
+
+	for (i = 0; i < adapter->req_depth; ++i, ++ctx) {
+		ctx->sgl = (void *)__get_free_pages(GFP_KERNEL,
+						    get_order(SGL_SIZE));
+		ctx->sglPA = 0;
+		BUG_ON(!IS_ALIGNED(((unsigned long)ctx->sgl), PAGE_SIZE));
+		if (!ctx->sgl) {
+			for (; i >= 0; --i, --ctx) {
+				free_pages((unsigned long)ctx->sgl,
+					   get_order(SGL_SIZE));
+				ctx->sgl = NULL;
+			}
+			return -ENOMEM;
+		}
+	}
+
+	return 0;
+}
+
+static int __devinit pvscsi_probe(struct pci_dev *pdev,
+				  const struct pci_device_id *id)
+{
+	struct pvscsi_adapter *adapter;
+	struct Scsi_Host *host;
+	unsigned int i;
+	unsigned long flags = 0;
+	int error;
+
+	error = -ENODEV;
+
+	if (pci_enable_device(pdev))
+		return error;
+
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) == 0 &&
+	    pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) == 0) {
+		printk(KERN_INFO "vmw_pvscsi: using 64bit dma\n");
+	} else if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) == 0 &&
+		   pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) == 0) {
+		printk(KERN_INFO "vmw_pvscsi: using 32bit dma\n");
+	} else {
+		printk(KERN_ERR "vmw_pvscsi: failed to set DMA mask\n");
+		goto out_disable_device;
+	}
+
+	pvscsi_template.can_queue =
+		min(PVSCSI_MAX_NUM_PAGES_REQ_RING, pvscsi_ring_pages) *
+		PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE;
+	pvscsi_template.cmd_per_lun =
+		min(pvscsi_template.can_queue, pvscsi_cmd_per_lun);
+	host = scsi_host_alloc(&pvscsi_template, sizeof(struct pvscsi_adapter));
+	if (!host) {
+		printk(KERN_ERR "vmw_pvscsi: failed to allocate host\n");
+		goto out_disable_device;
+	}
+
+	adapter = shost_priv(host);
+	memset(adapter, 0, sizeof(*adapter));
+	adapter->dev  = pdev;
+	adapter->host = host;
+
+	spin_lock_init(&adapter->hw_lock);
+
+	host->max_channel = 0;
+	host->max_id      = 16;
+	host->max_lun     = 1;
+	host->max_cmd_len = 16;
+
+	adapter->rev = pdev->revision;
+
+	if (pci_request_regions(pdev, "vmw_pvscsi")) {
+		printk(KERN_ERR "vmw_pvscsi: pci memory selection failed\n");
+		goto out_free_host;
+	}
+
+	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+		if ((pci_resource_flags(pdev, i) & PCI_BASE_ADDRESS_SPACE_IO))
+			continue;
+
+		if (pci_resource_len(pdev, i) < PVSCSI_MEM_SPACE_SIZE)
+			continue;
+
+		break;
+	}
+
+	if (i == DEVICE_COUNT_RESOURCE) {
+		printk(KERN_ERR
+		       "vmw_pvscsi: adapter has no suitable MMIO region\n");
+		goto out_release_resources;
+	}
+
+	adapter->mmioBase = pci_iomap(pdev, i, PVSCSI_MEM_SPACE_SIZE);
+
+	if (!adapter->mmioBase) {
+		printk(KERN_ERR
+		       "vmw_pvscsi: can't iomap for BAR %d memsize %lu\n",
+		       i, PVSCSI_MEM_SPACE_SIZE);
+		goto out_release_resources;
+	}
+
+	pci_set_master(pdev);
+	pci_set_drvdata(pdev, host);
+
+	ll_adapter_reset(adapter);
+
+	adapter->use_msg = pvscsi_setup_msg_workqueue(adapter);
+
+	error = pvscsi_allocate_rings(adapter);
+	if (error) {
+		printk(KERN_ERR "vmw_pvscsi: unable to allocate ring memory\n");
+		goto out_release_resources;
+	}
+
+	/*
+	 * From this point on we should reset the adapter if anything goes
+	 * wrong.
+	 */
+	pvscsi_setup_all_rings(adapter);
+
+	adapter->cmd_map = kcalloc(adapter->req_depth,
+				   sizeof(struct pvscsi_ctx), GFP_KERNEL);
+	if (!adapter->cmd_map) {
+		printk(KERN_ERR "vmw_pvscsi: failed to allocate memory.\n");
+		error = -ENOMEM;
+		goto out_reset_adapter;
+	}
+
+	INIT_LIST_HEAD(&adapter->cmd_pool);
+	for (i = 0; i < adapter->req_depth; i++) {
+		struct pvscsi_ctx *ctx = adapter->cmd_map + i;
+		list_add(&ctx->list, &adapter->cmd_pool);
+	}
+
+	error = pvscsi_allocate_sg(adapter);
+	if (error) {
+		printk(KERN_ERR "vmw_pvscsi: unable to allocate s/g table\n");
+		goto out_reset_adapter;
+	}
+
+	if (!pvscsi_disable_msix &&
+	    pvscsi_setup_msix(adapter, &adapter->irq) == 0) {
+		printk(KERN_INFO "vmw_pvscsi: using MSI-X\n");
+		adapter->use_msix = 1;
+	} else if (!pvscsi_disable_msi && pci_enable_msi(pdev) == 0) {
+		printk(KERN_INFO "vmw_pvscsi: using MSI\n");
+		adapter->use_msi = 1;
+		adapter->irq = pdev->irq;
+	} else {
+		printk(KERN_INFO "vmw_pvscsi: using INTx\n");
+		adapter->irq = pdev->irq;
+		flags = IRQF_SHARED;
+	}
+
+	error = request_irq(adapter->irq, pvscsi_isr, flags,
+			    "vmw_pvscsi", adapter);
+	if (error) {
+		printk(KERN_ERR
+		       "vmw_pvscsi: unable to request IRQ: %d\n", error);
+		adapter->irq = 0;
+		goto out_reset_adapter;
+	}
+
+	error = scsi_add_host(host, &pdev->dev);
+	if (error) {
+		printk(KERN_ERR
+		       "vmw_pvscsi: scsi_add_host failed: %d\n", error);
+		goto out_reset_adapter;
+	}
+
+	dev_info(&pdev->dev, "VMware PVSCSI rev %d host #%u\n",
+		 adapter->rev, host->host_no);
+
+	pvscsi_unmask_intr(adapter);
+
+	scsi_scan_host(host);
+
+	return 0;
+
+out_reset_adapter:
+	ll_adapter_reset(adapter);
+out_release_resources:
+	pvscsi_release_resources(adapter);
+out_free_host:
+	scsi_host_put(host);
+out_disable_device:
+	pci_set_drvdata(pdev, NULL);
+	pci_disable_device(pdev);
+
+	return error;
+}
+
+static void __pvscsi_shutdown(struct pvscsi_adapter *adapter)
+{
+	pvscsi_mask_intr(adapter);
+
+	if (adapter->workqueue)
+		flush_workqueue(adapter->workqueue);
+
+	pvscsi_shutdown_intr(adapter);
+
+	pvscsi_process_request_ring(adapter);
+	pvscsi_process_completion_ring(adapter);
+	ll_adapter_reset(adapter);
+}
+
+static void pvscsi_shutdown(struct pci_dev *dev)
+{
+	struct Scsi_Host *host = pci_get_drvdata(dev);
+	struct pvscsi_adapter *adapter = shost_priv(host);
+
+	__pvscsi_shutdown(adapter);
+}
+
+static void pvscsi_remove(struct pci_dev *pdev)
+{
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
+	struct pvscsi_adapter *adapter = shost_priv(host);
+
+	scsi_remove_host(host);
+
+	__pvscsi_shutdown(adapter);
+	pvscsi_release_resources(adapter);
+
+	scsi_host_put(host);
+
+	pci_set_drvdata(pdev, NULL);
+	pci_disable_device(pdev);
+}
+
+static struct pci_driver pvscsi_pci_driver = {
+	.name		= "vmw_pvscsi",
+	.id_table	= pvscsi_pci_tbl,
+	.probe		= pvscsi_probe,
+	.remove		= __devexit_p(pvscsi_remove),
+	.shutdown       = pvscsi_shutdown,
+};
+
+static int __init pvscsi_init(void)
+{
+	pr_info("%s - version %s\n",
+		PVSCSI_LINUX_DRIVER_DESC, PVSCSI_DRIVER_VERSION_STRING);
+	return pci_register_driver(&pvscsi_pci_driver);
+}
+
+static void __exit pvscsi_exit(void)
+{
+	pci_unregister_driver(&pvscsi_pci_driver);
+}
+
+module_init(pvscsi_init);
+module_exit(pvscsi_exit);
diff --git a/drivers/scsi/vmw_pvscsi.h b/drivers/scsi/vmw_pvscsi.h
new file mode 100644
index 0000000..62e36e7
--- /dev/null
+++ b/drivers/scsi/vmw_pvscsi.h
@@ -0,0 +1,397 @@
+/*
+ * VMware PVSCSI header file
+ *
+ * Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
+ *
+ * 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 of the License and no 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, GOOD TITLE or
+ * NON INFRINGEMENT.  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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Maintained by: Alok N Kataria <akataria@vmware.com>
+ *
+ */
+
+#ifndef _VMW_PVSCSI_H_
+#define _VMW_PVSCSI_H_
+
+#include <linux/types.h>
+
+#define PVSCSI_DRIVER_VERSION_STRING   "1.0.1.0-k"
+
+#define PVSCSI_MAX_NUM_SG_ENTRIES_PER_SEGMENT 128
+
+#define MASK(n)        ((1 << (n)) - 1)        /* make an n-bit mask */
+
+#define PCI_VENDOR_ID_VMWARE		0x15AD
+#define PCI_DEVICE_ID_VMWARE_PVSCSI	0x07C0
+
+/*
+ * host adapter status/error codes
+ */
+enum HostBusAdapterStatus {
+   BTSTAT_SUCCESS       = 0x00,  /* CCB complete normally with no errors */
+   BTSTAT_LINKED_COMMAND_COMPLETED           = 0x0a,
+   BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG = 0x0b,
+   BTSTAT_DATA_UNDERRUN = 0x0c,
+   BTSTAT_SELTIMEO      = 0x11,  /* SCSI selection timeout */
+   BTSTAT_DATARUN       = 0x12,  /* data overrun/underrun */
+   BTSTAT_BUSFREE       = 0x13,  /* unexpected bus free */
+   BTSTAT_INVPHASE      = 0x14,  /* invalid bus phase or sequence requested by target */
+   BTSTAT_LUNMISMATCH   = 0x17,  /* linked CCB has different LUN from first CCB */
+   BTSTAT_SENSFAILED    = 0x1b,  /* auto request sense failed */
+   BTSTAT_TAGREJECT     = 0x1c,  /* SCSI II tagged queueing message rejected by target */
+   BTSTAT_BADMSG        = 0x1d,  /* unsupported message received by the host adapter */
+   BTSTAT_HAHARDWARE    = 0x20,  /* host adapter hardware failed */
+   BTSTAT_NORESPONSE    = 0x21,  /* target did not respond to SCSI ATN, sent a SCSI RST */
+   BTSTAT_SENTRST       = 0x22,  /* host adapter asserted a SCSI RST */
+   BTSTAT_RECVRST       = 0x23,  /* other SCSI devices asserted a SCSI RST */
+   BTSTAT_DISCONNECT    = 0x24,  /* target device reconnected improperly (w/o tag) */
+   BTSTAT_BUSRESET      = 0x25,  /* host adapter issued BUS device reset */
+   BTSTAT_ABORTQUEUE    = 0x26,  /* abort queue generated */
+   BTSTAT_HASOFTWARE    = 0x27,  /* host adapter software error */
+   BTSTAT_HATIMEOUT     = 0x30,  /* host adapter hardware timeout error */
+   BTSTAT_SCSIPARITY    = 0x34,  /* SCSI parity error detected */
+};
+
+/*
+ * Register offsets.
+ *
+ * These registers are accessible both via i/o space and mm i/o.
+ */
+
+enum PVSCSIRegOffset {
+	PVSCSI_REG_OFFSET_COMMAND        =    0x0,
+	PVSCSI_REG_OFFSET_COMMAND_DATA   =    0x4,
+	PVSCSI_REG_OFFSET_COMMAND_STATUS =    0x8,
+	PVSCSI_REG_OFFSET_LAST_STS_0     =  0x100,
+	PVSCSI_REG_OFFSET_LAST_STS_1     =  0x104,
+	PVSCSI_REG_OFFSET_LAST_STS_2     =  0x108,
+	PVSCSI_REG_OFFSET_LAST_STS_3     =  0x10c,
+	PVSCSI_REG_OFFSET_INTR_STATUS    = 0x100c,
+	PVSCSI_REG_OFFSET_INTR_MASK      = 0x2010,
+	PVSCSI_REG_OFFSET_KICK_NON_RW_IO = 0x3014,
+	PVSCSI_REG_OFFSET_DEBUG          = 0x3018,
+	PVSCSI_REG_OFFSET_KICK_RW_IO     = 0x4018,
+};
+
+/*
+ * Virtual h/w commands.
+ */
+
+enum PVSCSICommands {
+	PVSCSI_CMD_FIRST             = 0, /* has to be first */
+
+	PVSCSI_CMD_ADAPTER_RESET     = 1,
+	PVSCSI_CMD_ISSUE_SCSI        = 2,
+	PVSCSI_CMD_SETUP_RINGS       = 3,
+	PVSCSI_CMD_RESET_BUS         = 4,
+	PVSCSI_CMD_RESET_DEVICE      = 5,
+	PVSCSI_CMD_ABORT_CMD         = 6,
+	PVSCSI_CMD_CONFIG            = 7,
+	PVSCSI_CMD_SETUP_MSG_RING    = 8,
+	PVSCSI_CMD_DEVICE_UNPLUG     = 9,
+
+	PVSCSI_CMD_LAST              = 10  /* has to be last */
+};
+
+/*
+ * Command descriptor for PVSCSI_CMD_RESET_DEVICE --
+ */
+
+struct PVSCSICmdDescResetDevice {
+	u32	target;
+	u8	lun[8];
+} __packed;
+
+/*
+ * Command descriptor for PVSCSI_CMD_ABORT_CMD --
+ *
+ * - currently does not support specifying the LUN.
+ * - _pad should be 0.
+ */
+
+struct PVSCSICmdDescAbortCmd {
+	u64	context;
+	u32	target;
+	u32	_pad;
+} __packed;
+
+/*
+ * Command descriptor for PVSCSI_CMD_SETUP_RINGS --
+ *
+ * Notes:
+ * - reqRingNumPages and cmpRingNumPages need to be power of two.
+ * - reqRingNumPages and cmpRingNumPages need to be different from 0,
+ * - reqRingNumPages and cmpRingNumPages need to be inferior to
+ *   PVSCSI_SETUP_RINGS_MAX_NUM_PAGES.
+ */
+
+#define PVSCSI_SETUP_RINGS_MAX_NUM_PAGES        32
+struct PVSCSICmdDescSetupRings {
+	u32	reqRingNumPages;
+	u32	cmpRingNumPages;
+	u64	ringsStatePPN;
+	u64	reqRingPPNs[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES];
+	u64	cmpRingPPNs[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES];
+} __packed;
+
+/*
+ * Command descriptor for PVSCSI_CMD_SETUP_MSG_RING --
+ *
+ * Notes:
+ * - this command was not supported in the initial revision of the h/w
+ *   interface. Before using it, you need to check that it is supported by
+ *   writing PVSCSI_CMD_SETUP_MSG_RING to the 'command' register, then
+ *   immediately after read the 'command status' register:
+ *       * a value of -1 means that the cmd is NOT supported,
+ *       * a value != -1 means that the cmd IS supported.
+ *   If it's supported the 'command status' register should return:
+ *      sizeof(PVSCSICmdDescSetupMsgRing) / sizeof(u32).
+ * - this command should be issued _after_ the usual SETUP_RINGS so that the
+ *   RingsState page is already setup. If not, the command is a nop.
+ * - numPages needs to be a power of two,
+ * - numPages needs to be different from 0,
+ * - _pad should be zero.
+ */
+
+#define PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES  16
+
+struct PVSCSICmdDescSetupMsgRing {
+	u32	numPages;
+	u32	_pad;
+	u64	ringPPNs[PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES];
+} __packed;
+
+enum PVSCSIMsgType {
+	PVSCSI_MSG_DEV_ADDED          = 0,
+	PVSCSI_MSG_DEV_REMOVED        = 1,
+	PVSCSI_MSG_LAST               = 2,
+};
+
+/*
+ * Msg descriptor.
+ *
+ * sizeof(struct PVSCSIRingMsgDesc) == 128.
+ *
+ * - type is of type enum PVSCSIMsgType.
+ * - the content of args depend on the type of event being delivered.
+ */
+
+struct PVSCSIRingMsgDesc {
+	u32	type;
+	u32	args[31];
+} __packed;
+
+struct PVSCSIMsgDescDevStatusChanged {
+	u32	type;  /* PVSCSI_MSG_DEV _ADDED / _REMOVED */
+	u32	bus;
+	u32	target;
+	u8	lun[8];
+	u32	pad[27];
+} __packed;
+
+/*
+ * Rings state.
+ *
+ * - the fields:
+ *    . msgProdIdx,
+ *    . msgConsIdx,
+ *    . msgNumEntriesLog2,
+ *   .. are only used once the SETUP_MSG_RING cmd has been issued.
+ * - '_pad' helps to ensure that the msg related fields are on their own
+ *   cache-line.
+ */
+
+struct PVSCSIRingsState {
+	u32	reqProdIdx;
+	u32	reqConsIdx;
+	u32	reqNumEntriesLog2;
+
+	u32	cmpProdIdx;
+	u32	cmpConsIdx;
+	u32	cmpNumEntriesLog2;
+
+	u8	_pad[104];
+
+	u32	msgProdIdx;
+	u32	msgConsIdx;
+	u32	msgNumEntriesLog2;
+} __packed;
+
+/*
+ * Request descriptor.
+ *
+ * sizeof(RingReqDesc) = 128
+ *
+ * - context: is a unique identifier of a command. It could normally be any
+ *   64bit value, however we currently store it in the serialNumber variable
+ *   of struct SCSI_Command, so we have the following restrictions due to the
+ *   way this field is handled in the vmkernel storage stack:
+ *    * this value can't be 0,
+ *    * the upper 32bit need to be 0 since serialNumber is as a u32.
+ *   Currently tracked as PR 292060.
+ * - dataLen: contains the total number of bytes that need to be transferred.
+ * - dataAddr:
+ *   * if PVSCSI_FLAG_CMD_WITH_SG_LIST is set: dataAddr is the PA of the first
+ *     s/g table segment, each s/g segment is entirely contained on a single
+ *     page of physical memory,
+ *   * if PVSCSI_FLAG_CMD_WITH_SG_LIST is NOT set, then dataAddr is the PA of
+ *     the buffer used for the DMA transfer,
+ * - flags:
+ *   * PVSCSI_FLAG_CMD_WITH_SG_LIST: see dataAddr above,
+ *   * PVSCSI_FLAG_CMD_DIR_NONE: no DMA involved,
+ *   * PVSCSI_FLAG_CMD_DIR_TOHOST: transfer from device to main memory,
+ *   * PVSCSI_FLAG_CMD_DIR_TODEVICE: transfer from main memory to device,
+ *   * PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB: reserved to handle CDBs larger than
+ *     16bytes. To be specified.
+ * - vcpuHint: vcpuId of the processor that will be most likely waiting for the
+ *   completion of the i/o. For guest OSes that use lowest priority message
+ *   delivery mode (such as windows), we use this "hint" to deliver the
+ *   completion action to the proper vcpu. For now, we can use the vcpuId of
+ *   the processor that initiated the i/o as a likely candidate for the vcpu
+ *   that will be waiting for the completion..
+ * - bus should be 0: we currently only support bus 0 for now.
+ * - unused should be zero'd.
+ */
+
+#define PVSCSI_FLAG_CMD_WITH_SG_LIST        (1 << 0)
+#define PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB     (1 << 1)
+#define PVSCSI_FLAG_CMD_DIR_NONE            (1 << 2)
+#define PVSCSI_FLAG_CMD_DIR_TOHOST          (1 << 3)
+#define PVSCSI_FLAG_CMD_DIR_TODEVICE        (1 << 4)
+
+struct PVSCSIRingReqDesc {
+	u64	context;
+	u64	dataAddr;
+	u64	dataLen;
+	u64	senseAddr;
+	u32	senseLen;
+	u32	flags;
+	u8	cdb[16];
+	u8	cdbLen;
+	u8	lun[8];
+	u8	tag;
+	u8	bus;
+	u8	target;
+	u8	vcpuHint;
+	u8	unused[59];
+} __packed;
+
+/*
+ * Scatter-gather list management.
+ *
+ * As described above, when PVSCSI_FLAG_CMD_WITH_SG_LIST is set in the
+ * RingReqDesc.flags, then RingReqDesc.dataAddr is the PA of the first s/g
+ * table segment.
+ *
+ * - each segment of the s/g table contain a succession of struct
+ *   PVSCSISGElement.
+ * - each segment is entirely contained on a single physical page of memory.
+ * - a "chain" s/g element has the flag PVSCSI_SGE_FLAG_CHAIN_ELEMENT set in
+ *   PVSCSISGElement.flags and in this case:
+ *     * addr is the PA of the next s/g segment,
+ *     * length is undefined, assumed to be 0.
+ */
+
+struct PVSCSISGElement {
+	u64	addr;
+	u32	length;
+	u32	flags;
+} __packed;
+
+/*
+ * Completion descriptor.
+ *
+ * sizeof(RingCmpDesc) = 32
+ *
+ * - context: identifier of the command. The same thing that was specified
+ *   under "context" as part of struct RingReqDesc at initiation time,
+ * - dataLen: number of bytes transferred for the actual i/o operation,
+ * - senseLen: number of bytes written into the sense buffer,
+ * - hostStatus: adapter status,
+ * - scsiStatus: device status,
+ * - _pad should be zero.
+ */
+
+struct PVSCSIRingCmpDesc {
+	u64	context;
+	u64	dataLen;
+	u32	senseLen;
+	u16	hostStatus;
+	u16	scsiStatus;
+	u32	_pad[2];
+} __packed;
+
+/*
+ * Interrupt status / IRQ bits.
+ */
+
+#define PVSCSI_INTR_CMPL_0                 (1 << 0)
+#define PVSCSI_INTR_CMPL_1                 (1 << 1)
+#define PVSCSI_INTR_CMPL_MASK              MASK(2)
+
+#define PVSCSI_INTR_MSG_0                  (1 << 2)
+#define PVSCSI_INTR_MSG_1                  (1 << 3)
+#define PVSCSI_INTR_MSG_MASK               (MASK(2) << 2)
+
+#define PVSCSI_INTR_ALL_SUPPORTED          MASK(4)
+
+/*
+ * Number of MSI-X vectors supported.
+ */
+#define PVSCSI_MAX_INTRS        24
+
+/*
+ * Enumeration of supported MSI-X vectors
+ */
+#define PVSCSI_VECTOR_COMPLETION   0
+
+/*
+ * Misc constants for the rings.
+ */
+
+#define PVSCSI_MAX_NUM_PAGES_REQ_RING   PVSCSI_SETUP_RINGS_MAX_NUM_PAGES
+#define PVSCSI_MAX_NUM_PAGES_CMP_RING   PVSCSI_SETUP_RINGS_MAX_NUM_PAGES
+#define PVSCSI_MAX_NUM_PAGES_MSG_RING   PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES
+
+#define PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE \
+				(PAGE_SIZE / sizeof(struct PVSCSIRingReqDesc))
+
+#define PVSCSI_MAX_REQ_QUEUE_DEPTH \
+	(PVSCSI_MAX_NUM_PAGES_REQ_RING * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE)
+
+#define PVSCSI_MEM_SPACE_COMMAND_NUM_PAGES     1
+#define PVSCSI_MEM_SPACE_INTR_STATUS_NUM_PAGES 1
+#define PVSCSI_MEM_SPACE_MISC_NUM_PAGES        2
+#define PVSCSI_MEM_SPACE_KICK_IO_NUM_PAGES     2
+#define PVSCSI_MEM_SPACE_MSIX_NUM_PAGES        2
+
+enum PVSCSIMemSpace {
+	PVSCSI_MEM_SPACE_COMMAND_PAGE		= 0,
+	PVSCSI_MEM_SPACE_INTR_STATUS_PAGE	= 1,
+	PVSCSI_MEM_SPACE_MISC_PAGE		= 2,
+	PVSCSI_MEM_SPACE_KICK_IO_PAGE		= 4,
+	PVSCSI_MEM_SPACE_MSIX_TABLE_PAGE	= 6,
+	PVSCSI_MEM_SPACE_MSIX_PBA_PAGE		= 7,
+};
+
+#define PVSCSI_MEM_SPACE_NUM_PAGES \
+	(PVSCSI_MEM_SPACE_COMMAND_NUM_PAGES +       \
+	 PVSCSI_MEM_SPACE_INTR_STATUS_NUM_PAGES +   \
+	 PVSCSI_MEM_SPACE_MISC_NUM_PAGES +          \
+	 PVSCSI_MEM_SPACE_KICK_IO_NUM_PAGES +       \
+	 PVSCSI_MEM_SPACE_MSIX_NUM_PAGES)
+
+#define PVSCSI_MEM_SPACE_SIZE        (PVSCSI_MEM_SPACE_NUM_PAGES * PAGE_SIZE)
+
+#endif /* _VMW_PVSCSI_H_ */
diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c
index 093610b..2f6e9d8 100644
--- a/drivers/scsi/wd7000.c
+++ b/drivers/scsi/wd7000.c
@@ -161,7 +161,7 @@
  *
  * 2003/02/12 - Christoph Hellwig <hch@infradead.org>
  *
- * Cleaned up host template defintion
+ * Cleaned up host template definition
  * Removed now obsolete wd7000.h
  */
 
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 737b4c9..c3e37c8e 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -1339,14 +1339,12 @@
 		serial_out(up, UART_IER, up->ier);
 
 		if (up->bugs & UART_BUG_TXEN) {
-			unsigned char lsr, iir;
+			unsigned char lsr;
 			lsr = serial_in(up, UART_LSR);
 			up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
-			iir = serial_in(up, UART_IIR) & 0x0f;
 			if ((up->port.type == PORT_RM9000) ?
-				(lsr & UART_LSR_THRE &&
-				(iir == UART_IIR_NO_INT || iir == UART_IIR_THRI)) :
-				(lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT))
+				(lsr & UART_LSR_THRE) :
+				(lsr & UART_LSR_TEMT))
 				transmit_chars(up);
 		}
 	}
@@ -2646,7 +2644,7 @@
 {
 	struct uart_8250_port *up;
 	static int first = 1;
-	int i;
+	int i, irqflag = 0;
 
 	if (!first)
 		return;
@@ -2670,6 +2668,9 @@
 		up->port.ops = &serial8250_pops;
 	}
 
+	if (share_irqs)
+		irqflag = IRQF_SHARED;
+
 	for (i = 0, up = serial8250_ports;
 	     i < ARRAY_SIZE(old_serial_port) && i < nr_uarts;
 	     i++, up++) {
@@ -2683,8 +2684,7 @@
 		up->port.iotype   = old_serial_port[i].io_type;
 		up->port.regshift = old_serial_port[i].iomem_reg_shift;
 		set_io_from_upio(&up->port);
-		if (share_irqs)
-			up->port.irqflags |= IRQF_SHARED;
+		up->port.irqflags |= irqflag;
 	}
 }
 
@@ -2940,10 +2940,13 @@
 {
 	struct plat_serial8250_port *p = dev->dev.platform_data;
 	struct uart_port port;
-	int ret, i;
+	int ret, i, irqflag = 0;
 
 	memset(&port, 0, sizeof(struct uart_port));
 
+	if (share_irqs)
+		irqflag = IRQF_SHARED;
+
 	for (i = 0; p && p->flags != 0; p++, i++) {
 		port.iobase		= p->iobase;
 		port.membase		= p->membase;
@@ -2960,8 +2963,7 @@
 		port.serial_in		= p->serial_in;
 		port.serial_out		= p->serial_out;
 		port.dev		= &dev->dev;
-		if (share_irqs)
-			port.irqflags |= IRQF_SHARED;
+		port.irqflags		|= irqflag;
 		ret = serial8250_register_port(&port);
 		if (ret < 0) {
 			dev_err(&dev->dev, "unable to register port at index %d "
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index d71dfe3..36ede02 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -361,9 +361,9 @@
 	{	"LTS0001",		0       },
 	/* Rockwell's (PORALiNK) 33600 INT PNP */
 	{	"WCI0003",		0	},
-	/* Unkown PnP modems */
+	/* Unknown PnP modems */
 	{	"PNPCXXX",		UNKNOWN_DEV	},
-	/* More unkown PnP modems */
+	/* More unknown PnP modems */
 	{	"PNPDXXX",		UNKNOWN_DEV	},
 	{	"",			0	}
 };
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 50943ff..9ff47db0 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -996,7 +996,7 @@
 
 config SERIAL_SH_SCI
 	tristate "SuperH SCI(F) serial port support"
-	depends on SUPERH || H8300
+	depends on HAVE_CLK && (SUPERH || H8300)
 	select SERIAL_CORE
 
 config SERIAL_SH_SCI_NR_UARTS
diff --git a/drivers/serial/jsm/jsm.h b/drivers/serial/jsm/jsm.h
index 4e5f3bd..38a509c 100644
--- a/drivers/serial/jsm/jsm.h
+++ b/drivers/serial/jsm/jsm.h
@@ -138,7 +138,6 @@
 	u32		nasync;		/* Number of ports on card */
 
 	u32		irq;		/* Interrupt request number */
-	u64		intr_count;	/* Count of interrupts */
 
 	u64		membase;	/* Start of base memory of the card */
 	u64		membase_end;	/* End of base memory of the card */
@@ -206,8 +205,6 @@
 
 	u64		ch_close_delay;	/* How long we should drop RTS/DTR for */
 
-	u64		ch_cpstime;	/* Time for CPS calculations	*/
-
 	tcflag_t	ch_c_iflag;	/* channel iflags		*/
 	tcflag_t	ch_c_cflag;	/* channel cflags		*/
 	tcflag_t	ch_c_oflag;	/* channel oflags		*/
@@ -215,11 +212,6 @@
 	u8		ch_stopc;	/* Stop character		*/
 	u8		ch_startc;	/* Start character		*/
 
-	u32		ch_old_baud;	/* Cache of the current baud */
-	u32		ch_custom_speed;/* Custom baud, if set */
-
-	u32		ch_wopen;	/* Waiting for open process cnt */
-
 	u8		ch_mostat;	/* FEP output modem status	*/
 	u8		ch_mistat;	/* FEP input modem status	*/
 
diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c
index b3604aa..108c3e0 100644
--- a/drivers/serial/jsm/jsm_driver.c
+++ b/drivers/serial/jsm/jsm_driver.c
@@ -48,6 +48,17 @@
 	.nr		= NR_PORTS,
 };
 
+static pci_ers_result_t jsm_io_error_detected(struct pci_dev *pdev,
+                                       pci_channel_state_t state);
+static pci_ers_result_t jsm_io_slot_reset(struct pci_dev *pdev);
+static void jsm_io_resume(struct pci_dev *pdev);
+
+static struct pci_error_handlers jsm_err_handler = {
+	.error_detected = jsm_io_error_detected,
+	.slot_reset = jsm_io_slot_reset,
+	.resume = jsm_io_resume,
+};
+
 int jsm_debug;
 module_param(jsm_debug, int, 0);
 MODULE_PARM_DESC(jsm_debug, "Driver debugging level");
@@ -123,7 +134,7 @@
 	}
 
 	rc = request_irq(brd->irq, brd->bd_ops->intr,
-			IRQF_DISABLED|IRQF_SHARED, "JSM", brd);
+			IRQF_SHARED, "JSM", brd);
 	if (rc) {
 		printk(KERN_WARNING "Failed to hook IRQ %d\n",brd->irq);
 		goto out_iounmap;
@@ -164,6 +175,7 @@
 	}
 
 	pci_set_drvdata(pdev, brd);
+	pci_save_state(pdev);
 
 	return 0;
  out_free_irq:
@@ -222,8 +234,42 @@
 	.id_table	= jsm_pci_tbl,
 	.probe		= jsm_probe_one,
 	.remove		= __devexit_p(jsm_remove_one),
+	.err_handler    = &jsm_err_handler,
 };
 
+static pci_ers_result_t jsm_io_error_detected(struct pci_dev *pdev,
+					pci_channel_state_t state)
+{
+	struct jsm_board *brd = pci_get_drvdata(pdev);
+
+	jsm_remove_uart_port(brd);
+
+	return PCI_ERS_RESULT_NEED_RESET;
+}
+
+static pci_ers_result_t jsm_io_slot_reset(struct pci_dev *pdev)
+{
+	int rc;
+
+	rc = pci_enable_device(pdev);
+
+	if (rc)
+		return PCI_ERS_RESULT_DISCONNECT;
+
+	pci_set_master(pdev);
+
+	return PCI_ERS_RESULT_RECOVERED;
+}
+
+static void jsm_io_resume(struct pci_dev *pdev)
+{
+	struct jsm_board *brd = pci_get_drvdata(pdev);
+
+	pci_restore_state(pdev);
+
+	jsm_uart_port_init(brd);
+}
+
 static int __init jsm_init_module(void)
 {
 	int rc;
diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c
index b4b124e..7960d96 100644
--- a/drivers/serial/jsm/jsm_neo.c
+++ b/drivers/serial/jsm/jsm_neo.c
@@ -954,13 +954,8 @@
 		ch->ch_flags |= (CH_BAUD0);
 		ch->ch_mostat &= ~(UART_MCR_RTS | UART_MCR_DTR);
 		neo_assert_modem_signals(ch);
-		ch->ch_old_baud = 0;
 		return;
 
-	} else if (ch->ch_custom_speed) {
-			baud = ch->ch_custom_speed;
-			if (ch->ch_flags & CH_BAUD0)
-				ch->ch_flags &= ~(CH_BAUD0);
 	} else {
 		int i;
 		unsigned int cflag;
@@ -1045,7 +1040,6 @@
 	quot = ch->ch_bd->bd_dividend / baud;
 
 	if (quot != 0) {
-		ch->ch_old_baud = baud;
 		writeb(UART_LCR_DLAB, &ch->ch_neo_uart->lcr);
 		writeb((quot & 0xff), &ch->ch_neo_uart->txrx);
 		writeb((quot >> 8), &ch->ch_neo_uart->ier);
@@ -1123,8 +1117,6 @@
 	unsigned long lock_flags2;
 	int outofloop_count = 0;
 
-	brd->intr_count++;
-
 	/* Lock out the slow poller from running on this board. */
 	spin_lock_irqsave(&brd->bd_intr_lock, lock_flags);
 
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index 7439c03..cd95e21 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -296,8 +296,6 @@
 		bd->bd_ops->assert_modem_signals(channel);
 	}
 
-	channel->ch_old_baud = 0;
-
 	/* Turn off UART interrupts for this port */
 	channel->ch_bd->bd_ops->uart_off(channel);
 
@@ -432,7 +430,7 @@
 	return 0;
 }
 
-int __devinit jsm_uart_port_init(struct jsm_board *brd)
+int jsm_uart_port_init(struct jsm_board *brd)
 {
 	int i;
 	unsigned int line;
@@ -472,7 +470,7 @@
 		if (uart_add_one_port (&jsm_uart_driver, &brd->channels[i]->uart_port))
 			printk(KERN_INFO "jsm: add device failed\n");
 		else
-			printk(KERN_INFO "Added device \n");
+			printk(KERN_INFO "jsm: Port %d added\n", i);
 	}
 
 	jsm_printk(INIT, INFO, &brd->pci_dev, "finish\n");
diff --git a/drivers/serial/mcf.c b/drivers/serial/mcf.c
index b443824..7bb5fee 100644
--- a/drivers/serial/mcf.c
+++ b/drivers/serial/mcf.c
@@ -602,7 +602,7 @@
 
 /****************************************************************************/
 
-static int mcf_remove(struct platform_device *pdev)
+static int __devexit mcf_remove(struct platform_device *pdev)
 {
 	struct uart_port *port;
 	int i;
diff --git a/drivers/serial/pmac_zilog.h b/drivers/serial/pmac_zilog.h
index 570b0d9..f6e77f1 100644
--- a/drivers/serial/pmac_zilog.h
+++ b/drivers/serial/pmac_zilog.h
@@ -73,7 +73,7 @@
 }
 
 /*
- * Register acessors. Note that we don't need to enforce a recovery
+ * Register accessors. Note that we don't need to enforce a recovery
  * delay on PCI PowerMac hardware, it's dealt in HW by the MacIO chip,
  * though if we try to use this driver on older machines, we might have
  * to add it back
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index b8629d7..4a82104 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -438,6 +438,7 @@
 	unsigned char cval, fcr = 0;
 	unsigned long flags;
 	unsigned int baud, quot;
+	unsigned int dll;
 
 	switch (termios->c_cflag & CSIZE) {
 	case CS5:
@@ -534,10 +535,18 @@
 	else
 		up->mcr &= ~UART_MCR_AFE;
 
-	serial_out(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
+	serial_out(up, UART_LCR, cval | UART_LCR_DLAB);	/* set DLAB */
 	serial_out(up, UART_DLL, quot & 0xff);		/* LS of divisor */
+
+	/*
+	 * work around Errata #75 according to Intel(R) PXA27x Processor Family
+	 * Specification Update (Nov 2005)
+	 */
+	dll = serial_in(up, UART_DLL);
+	WARN_ON(dll != (quot & 0xff));
+
 	serial_out(up, UART_DLM, quot >> 8);		/* MS of divisor */
-	serial_out(up, UART_LCR, cval);		/* reset DLAB */
+	serial_out(up, UART_LCR, cval);			/* reset DLAB */
 	up->lcr = cval;					/* Save LCR */
 	serial_pxa_set_mctrl(&up->port, up->port.mctrl);
 	serial_out(up, UART_FCR, fcr);
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index dcc7244..047530b 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -342,11 +342,11 @@
 
 	if (flags == UPF_SPD_HI)
 		altbaud = 57600;
-	if (flags == UPF_SPD_VHI)
+	else if (flags == UPF_SPD_VHI)
 		altbaud = 115200;
-	if (flags == UPF_SPD_SHI)
+	else if (flags == UPF_SPD_SHI)
 		altbaud = 230400;
-	if (flags == UPF_SPD_WARP)
+	else if (flags == UPF_SPD_WARP)
 		altbaud = 460800;
 
 	for (try = 0; try < 2; try++) {
@@ -1217,9 +1217,8 @@
 	/* Handle transition to B0 status */
 	if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD))
 		uart_clear_mctrl(state->uart_port, TIOCM_RTS | TIOCM_DTR);
-
 	/* Handle transition away from B0 status */
-	if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
+	else if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
 		unsigned int mask = TIOCM_DTR;
 		if (!(cflag & CRTSCTS) ||
 		    !test_bit(TTY_THROTTLED, &tty->flags))
@@ -1234,9 +1233,8 @@
 		__uart_start(tty);
 		spin_unlock_irqrestore(&state->uart_port->lock, flags);
 	}
-
 	/* Handle turning on CRTSCTS */
-	if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {
+	else if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {
 		spin_lock_irqsave(&state->uart_port->lock, flags);
 		if (!(state->uart_port->ops->get_mctrl(state->uart_port) & TIOCM_CTS)) {
 			tty->hw_stopped = 1;
@@ -2344,7 +2342,7 @@
  */
 int uart_register_driver(struct uart_driver *drv)
 {
-	struct tty_driver *normal = NULL;
+	struct tty_driver *normal;
 	int i, retval;
 
 	BUG_ON(drv->state);
@@ -2354,13 +2352,12 @@
 	 * we have a large number of ports to handle.
 	 */
 	drv->state = kzalloc(sizeof(struct uart_state) * drv->nr, GFP_KERNEL);
-	retval = -ENOMEM;
 	if (!drv->state)
 		goto out;
 
-	normal  = alloc_tty_driver(drv->nr);
+	normal = alloc_tty_driver(drv->nr);
 	if (!normal)
-		goto out;
+		goto out_kfree;
 
 	drv->tty_driver = normal;
 
@@ -2393,12 +2390,14 @@
 	}
 
 	retval = tty_register_driver(normal);
- out:
-	if (retval < 0) {
-		put_tty_driver(normal);
-		kfree(drv->state);
-	}
-	return retval;
+	if (retval >= 0)
+		return retval;
+
+	put_tty_driver(normal);
+out_kfree:
+	kfree(drv->state);
+out:
+	return -ENOMEM;
 }
 
 /**
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 6498bd1..ff38dbd 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -50,7 +50,6 @@
 #include <linux/list.h>
 
 #ifdef CONFIG_SUPERH
-#include <asm/clock.h>
 #include <asm/sh_bios.h>
 #endif
 
@@ -79,22 +78,18 @@
 	struct timer_list	break_timer;
 	int			break_flag;
 
-#ifdef CONFIG_HAVE_CLK
 	/* Interface clock */
 	struct clk		*iclk;
 	/* Data clock */
 	struct clk		*dclk;
-#endif
+
 	struct list_head	node;
 };
 
 struct sh_sci_priv {
 	spinlock_t lock;
 	struct list_head ports;
-
-#ifdef CONFIG_HAVE_CLK
 	struct notifier_block clk_nb;
-#endif
 };
 
 /* Function prototypes */
@@ -156,32 +151,6 @@
 }
 #endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */
 
-#if defined(__H8300S__)
-enum { sci_disable, sci_enable };
-
-static void h8300_sci_config(struct uart_port *port, unsigned int ctrl)
-{
-	volatile unsigned char *mstpcrl = (volatile unsigned char *)MSTPCRL;
-	int ch = (port->mapbase  - SMR0) >> 3;
-	unsigned char mask = 1 << (ch+1);
-
-	if (ctrl == sci_disable)
-		*mstpcrl |= mask;
-	else
-		*mstpcrl &= ~mask;
-}
-
-static void h8300_sci_enable(struct uart_port *port)
-{
-	h8300_sci_config(port, sci_enable);
-}
-
-static void h8300_sci_disable(struct uart_port *port)
-{
-	h8300_sci_config(port, sci_disable);
-}
-#endif
-
 #if defined(__H8300H__) || defined(__H8300S__)
 static void sci_init_pins(struct uart_port *port, unsigned int cflag)
 {
@@ -733,7 +702,6 @@
 	return ret;
 }
 
-#ifdef CONFIG_HAVE_CLK
 /*
  * Here we define a transistion notifier so that we can update all of our
  * ports' baud rate when the peripheral clock changes.
@@ -751,7 +719,6 @@
 		spin_lock_irqsave(&priv->lock, flags);
 		list_for_each_entry(sci_port, &priv->ports, node)
 			sci_port->port.uartclk = clk_get_rate(sci_port->dclk);
-
 		spin_unlock_irqrestore(&priv->lock, flags);
 	}
 
@@ -778,7 +745,6 @@
 
 	clk_disable(sci_port->dclk);
 }
-#endif
 
 static int sci_request_irq(struct sci_port *port)
 {
@@ -833,8 +799,8 @@
 
 static unsigned int sci_tx_empty(struct uart_port *port)
 {
-	/* Can't detect */
-	return TIOCSER_TEMT;
+	unsigned short status = sci_in(port, SCxSR);
+	return status & SCxSR_TEND(port) ? TIOCSER_TEMT : 0;
 }
 
 static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl)
@@ -1077,21 +1043,10 @@
 	sci_port->port.iotype	= UPIO_MEM;
 	sci_port->port.line	= index;
 	sci_port->port.fifosize	= 1;
-
-#if defined(__H8300H__) || defined(__H8300S__)
-#ifdef __H8300S__
-	sci_port->enable	= h8300_sci_enable;
-	sci_port->disable	= h8300_sci_disable;
-#endif
-	sci_port->port.uartclk	= CONFIG_CPU_CLOCK;
-#elif defined(CONFIG_HAVE_CLK)
 	sci_port->iclk		= p->clk ? clk_get(&dev->dev, p->clk) : NULL;
 	sci_port->dclk		= clk_get(&dev->dev, "peripheral_clk");
 	sci_port->enable	= sci_clk_enable;
 	sci_port->disable	= sci_clk_disable;
-#else
-#error "Need a valid uartclk"
-#endif
 
 	sci_port->break_timer.data = (unsigned long)sci_port;
 	sci_port->break_timer.function = sci_break_timer;
@@ -1106,7 +1061,6 @@
 	sci_port->type		= sci_port->port.type = p->type;
 
 	memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs));
-
 }
 
 #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
@@ -1239,14 +1193,11 @@
 	struct sci_port *p;
 	unsigned long flags;
 
-#ifdef CONFIG_HAVE_CLK
 	cpufreq_unregister_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER);
-#endif
 
 	spin_lock_irqsave(&priv->lock, flags);
 	list_for_each_entry(p, &priv->ports, node)
 		uart_remove_one_port(&sci_uart_driver, &p->port);
-
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	kfree(priv);
@@ -1307,10 +1258,8 @@
 	spin_lock_init(&priv->lock);
 	platform_set_drvdata(dev, priv);
 
-#ifdef CONFIG_HAVE_CLK
 	priv->clk_nb.notifier_call = sci_notifier;
 	cpufreq_register_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER);
-#endif
 
 	if (dev->id != -1) {
 		ret = sci_probe_single(dev, dev->id, p, &sci_ports[dev->id]);
@@ -1370,7 +1319,7 @@
 
 static struct platform_driver sci_driver = {
 	.probe		= sci_probe,
-	.remove		= __devexit_p(sci_remove),
+	.remove		= sci_remove,
 	.driver		= {
 		.name	= "sh-sci",
 		.owner	= THIS_MODULE,
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index 3e2fcf9..a32094ee 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -1,5 +1,5 @@
 #include <linux/serial_core.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/gpio.h>
 
 #if defined(CONFIG_H83007) || defined(CONFIG_H83068)
diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c
index 0c08f28..465f2fa 100644
--- a/drivers/serial/ucc_uart.c
+++ b/drivers/serial/ucc_uart.c
@@ -313,7 +313,7 @@
  * This function will attempt to stuff of all the characters from the
  * kernel's transmit buffer into TX BDs.
  *
- * A return value of non-zero indicates that it sucessfully stuffed all
+ * A return value of non-zero indicates that it successfully stuffed all
  * characters from the kernel buffer.
  *
  * A return value of zero indicates that there are still characters in the
@@ -1179,16 +1179,18 @@
 
 	if (firmware->header.length != fw->size) {
 		dev_err(dev, "invalid firmware\n");
-		return;
+		goto out;
 	}
 
 	ret = qe_upload_firmware(firmware);
 	if (ret) {
 		dev_err(dev, "could not load firmware\n");
-		return;
+		goto out;
 	}
 
 	firmware_loaded = 1;
+ out:
+	release_firmware(fw);
 }
 
 static int ucc_uart_probe(struct of_device *ofdev,
@@ -1247,7 +1249,7 @@
 			 */
 			ret = request_firmware_nowait(THIS_MODULE,
 				FW_ACTION_HOTPLUG, filename, &ofdev->dev,
-				&ofdev->dev, uart_firmware_cont);
+				GFP_KERNEL, &ofdev->dev, uart_firmware_cont);
 			if (ret) {
 				dev_err(&ofdev->dev,
 					"could not load firmware %s\n",
diff --git a/drivers/sh/Makefile b/drivers/sh/Makefile
index 6a025ce..4956bf1 100644
--- a/drivers/sh/Makefile
+++ b/drivers/sh/Makefile
@@ -3,4 +3,5 @@
 #
 obj-$(CONFIG_SUPERHYWAY)	+= superhyway/
 obj-$(CONFIG_MAPLE)		+= maple/
+obj-$(CONFIG_GENERIC_GPIO)	+= pfc.o
 obj-y				+= intc.o
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c
index 559b5fe..a7e5c2e 100644
--- a/drivers/sh/intc.c
+++ b/drivers/sh/intc.c
@@ -2,6 +2,7 @@
  * Shared interrupt handling code for IPR and INTC2 types of IRQs.
  *
  * Copyright (C) 2007, 2008 Magnus Damm
+ * Copyright (C) 2009 Paul Mundt
  *
  * Based on intc2.c and ipr.c
  *
@@ -24,6 +25,7 @@
 #include <linux/sysdev.h>
 #include <linux/list.h>
 #include <linux/topology.h>
+#include <linux/bitmap.h>
 
 #define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \
 	((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \
@@ -59,6 +61,20 @@
 
 static LIST_HEAD(intc_list);
 
+/*
+ * The intc_irq_map provides a global map of bound IRQ vectors for a
+ * given platform. Allocation of IRQs are either static through the CPU
+ * vector map, or dynamic in the case of board mux vectors or MSI.
+ *
+ * As this is a central point for all IRQ controllers on the system,
+ * each of the available sources are mapped out here. This combined with
+ * sparseirq makes it quite trivial to keep the vector map tightly packed
+ * when dynamically creating IRQs, as well as tying in to otherwise
+ * unused irq_desc positions in the sparse array.
+ */
+static DECLARE_BITMAP(intc_irq_map, NR_IRQS);
+static DEFINE_SPINLOCK(vector_lock);
+
 #ifdef CONFIG_SMP
 #define IS_SMP(x) x.smp
 #define INTC_REG(d, x, c) (d->reg[(x)] + ((d->smp[(x)] & 0xff) * c))
@@ -70,9 +86,7 @@
 #endif
 
 static unsigned int intc_prio_level[NR_IRQS]; /* for now */
-#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
 static unsigned long ack_handle[NR_IRQS];
-#endif
 
 static inline struct intc_desc_int *get_intc_desc(unsigned int irq)
 {
@@ -250,7 +264,6 @@
 	return 0; /* allow wakeup, but setup hardware in intc_suspend() */
 }
 
-#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
 static void intc_mask_ack(unsigned int irq)
 {
 	struct intc_desc_int *d = get_intc_desc(irq);
@@ -282,7 +295,6 @@
 		}
 	}
 }
-#endif
 
 static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp,
 					     unsigned int nr_hp,
@@ -501,7 +513,6 @@
 	return 0;
 }
 
-#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
 static unsigned int __init intc_ack_data(struct intc_desc *desc,
 					  struct intc_desc_int *d,
 					  intc_enum enum_id)
@@ -533,7 +544,6 @@
 
 	return 0;
 }
-#endif
 
 static unsigned int __init intc_sense_data(struct intc_desc *desc,
 					   struct intc_desc_int *d,
@@ -572,6 +582,11 @@
 	struct intc_handle_int *hp;
 	unsigned int data[2], primary;
 
+	/*
+	 * Register the IRQ position with the global IRQ map
+	 */
+	set_bit(irq, intc_irq_map);
+
 	/* Prefer single interrupt source bitmap over other combinations:
 	 * 1. bitmap, single interrupt source
 	 * 2. priority, single interrupt source
@@ -641,10 +656,8 @@
 	/* irq should be disabled by default */
 	d->chip.mask(irq);
 
-#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
 	if (desc->ack_regs)
 		ack_handle[irq] = intc_ack_data(desc, d, enum_id);
-#endif
 }
 
 static unsigned int __init save_reg(struct intc_desc_int *d,
@@ -681,10 +694,8 @@
 	d->nr_reg = desc->mask_regs ? desc->nr_mask_regs * 2 : 0;
 	d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0;
 	d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0;
-
-#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
 	d->nr_reg += desc->ack_regs ? desc->nr_ack_regs : 0;
-#endif
+
 	d->reg = kzalloc(d->nr_reg * sizeof(*d->reg), GFP_NOWAIT);
 #ifdef CONFIG_SMP
 	d->smp = kzalloc(d->nr_reg * sizeof(*d->smp), GFP_NOWAIT);
@@ -727,14 +738,12 @@
 	d->chip.set_type = intc_set_sense;
 	d->chip.set_wake = intc_set_wake;
 
-#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
 	if (desc->ack_regs) {
 		for (i = 0; i < desc->nr_ack_regs; i++)
 			k += save_reg(d, k, desc->ack_regs[i].set_reg, 0);
 
 		d->chip.mask_ack = intc_mask_ack;
 	}
-#endif
 
 	BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
 
@@ -856,5 +865,91 @@
 
 	return error;
 }
-
 device_initcall(register_intc_sysdevs);
+
+/*
+ * Dynamic IRQ allocation and deallocation
+ */
+static unsigned int create_irq_on_node(unsigned int irq_want, int node)
+{
+	unsigned int irq = 0, new;
+	unsigned long flags;
+	struct irq_desc *desc;
+
+	spin_lock_irqsave(&vector_lock, flags);
+
+	/*
+	 * First try the wanted IRQ, then scan.
+	 */
+	if (test_and_set_bit(irq_want, intc_irq_map)) {
+		new = find_first_zero_bit(intc_irq_map, nr_irqs);
+		if (unlikely(new == nr_irqs))
+			goto out_unlock;
+
+		desc = irq_to_desc_alloc_node(new, node);
+		if (unlikely(!desc)) {
+			pr_info("can't get irq_desc for %d\n", new);
+			goto out_unlock;
+		}
+
+		desc = move_irq_desc(desc, node);
+		__set_bit(new, intc_irq_map);
+		irq = new;
+	}
+
+out_unlock:
+	spin_unlock_irqrestore(&vector_lock, flags);
+
+	if (irq > 0)
+		dynamic_irq_init(irq);
+
+	return irq;
+}
+
+int create_irq(void)
+{
+	int nid = cpu_to_node(smp_processor_id());
+	int irq;
+
+	irq = create_irq_on_node(NR_IRQS_LEGACY, nid);
+	if (irq == 0)
+		irq = -1;
+
+	return irq;
+}
+
+void destroy_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	dynamic_irq_cleanup(irq);
+
+	spin_lock_irqsave(&vector_lock, flags);
+	__clear_bit(irq, intc_irq_map);
+	spin_unlock_irqrestore(&vector_lock, flags);
+}
+
+int reserve_irq_vector(unsigned int irq)
+{
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&vector_lock, flags);
+	if (test_and_set_bit(irq, intc_irq_map))
+		ret = -EBUSY;
+	spin_unlock_irqrestore(&vector_lock, flags);
+
+	return ret;
+}
+
+void reserve_irq_legacy(void)
+{
+	unsigned long flags;
+	int i, j;
+
+	spin_lock_irqsave(&vector_lock, flags);
+	j = find_first_bit(intc_irq_map, nr_irqs);
+	for (i = 0; i < j; i++)
+		__set_bit(i, intc_irq_map);
+	spin_unlock_irqrestore(&vector_lock, flags);
+}
diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c
index 93c20e1..4e8f57d 100644
--- a/drivers/sh/maple/maple.c
+++ b/drivers/sh/maple/maple.c
@@ -106,7 +106,7 @@
 	* max delay is 11
 	*/
 	ctrl_outl(MAPLE_2MBPS | MAPLE_TIMEOUT(0xFFFF), MAPLE_SPEED);
-	ctrl_outl(PHYSADDR(maple_sendbuf), MAPLE_DMAADDR);
+	ctrl_outl(virt_to_phys(maple_sendbuf), MAPLE_DMAADDR);
 	ctrl_outl(1, MAPLE_ENABLE);
 }
 
@@ -258,7 +258,7 @@
 	maple_lastptr = maple_sendptr;
 
 	*maple_sendptr++ = (port << 16) | len | 0x80000000;
-	*maple_sendptr++ = PHYSADDR(mq->recvbuf->buf);
+	*maple_sendptr++ = virt_to_phys(mq->recvbuf->buf);
 	*maple_sendptr++ =
 	    mq->command | (to << 8) | (from << 16) | (len << 24);
 	while (len-- > 0)
diff --git a/drivers/sh/pfc.c b/drivers/sh/pfc.c
new file mode 100644
index 0000000..841ed50
--- /dev/null
+++ b/drivers/sh/pfc.c
@@ -0,0 +1,577 @@
+/*
+ * Pinmuxed GPIO support for SuperH.
+ *
+ * Copyright (C) 2008 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/bitops.h>
+#include <linux/gpio.h>
+
+static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
+{
+	if (enum_id < r->begin)
+		return 0;
+
+	if (enum_id > r->end)
+		return 0;
+
+	return 1;
+}
+
+static unsigned long gpio_read_raw_reg(unsigned long reg,
+				       unsigned long reg_width)
+{
+	switch (reg_width) {
+	case 8:
+		return __raw_readb(reg);
+	case 16:
+		return __raw_readw(reg);
+	case 32:
+		return __raw_readl(reg);
+	}
+
+	BUG();
+	return 0;
+}
+
+static void gpio_write_raw_reg(unsigned long reg,
+			       unsigned long reg_width,
+			       unsigned long data)
+{
+	switch (reg_width) {
+	case 8:
+		__raw_writeb(data, reg);
+		return;
+	case 16:
+		__raw_writew(data, reg);
+		return;
+	case 32:
+		__raw_writel(data, reg);
+		return;
+	}
+
+	BUG();
+}
+
+static void gpio_write_bit(struct pinmux_data_reg *dr,
+			   unsigned long in_pos, unsigned long value)
+{
+	unsigned long pos;
+
+	pos = dr->reg_width - (in_pos + 1);
+
+	pr_debug("write_bit addr = %lx, value = %ld, pos = %ld, "
+		 "r_width = %ld\n",
+		 dr->reg, !!value, pos, dr->reg_width);
+
+	if (value)
+		set_bit(pos, &dr->reg_shadow);
+	else
+		clear_bit(pos, &dr->reg_shadow);
+
+	gpio_write_raw_reg(dr->reg, dr->reg_width, dr->reg_shadow);
+}
+
+static int gpio_read_reg(unsigned long reg, unsigned long reg_width,
+			 unsigned long field_width, unsigned long in_pos)
+{
+	unsigned long data, mask, pos;
+
+	data = 0;
+	mask = (1 << field_width) - 1;
+	pos = reg_width - ((in_pos + 1) * field_width);
+
+	pr_debug("read_reg: addr = %lx, pos = %ld, "
+		 "r_width = %ld, f_width = %ld\n",
+		 reg, pos, reg_width, field_width);
+
+	data = gpio_read_raw_reg(reg, reg_width);
+	return (data >> pos) & mask;
+}
+
+static void gpio_write_reg(unsigned long reg, unsigned long reg_width,
+			   unsigned long field_width, unsigned long in_pos,
+			   unsigned long value)
+{
+	unsigned long mask, pos;
+
+	mask = (1 << field_width) - 1;
+	pos = reg_width - ((in_pos + 1) * field_width);
+
+	pr_debug("write_reg addr = %lx, value = %ld, pos = %ld, "
+		 "r_width = %ld, f_width = %ld\n",
+		 reg, value, pos, reg_width, field_width);
+
+	mask = ~(mask << pos);
+	value = value << pos;
+
+	switch (reg_width) {
+	case 8:
+		__raw_writeb((__raw_readb(reg) & mask) | value, reg);
+		break;
+	case 16:
+		__raw_writew((__raw_readw(reg) & mask) | value, reg);
+		break;
+	case 32:
+		__raw_writel((__raw_readl(reg) & mask) | value, reg);
+		break;
+	}
+}
+
+static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio)
+{
+	struct pinmux_gpio *gpiop = &gpioc->gpios[gpio];
+	struct pinmux_data_reg *data_reg;
+	int k, n;
+
+	if (!enum_in_range(gpiop->enum_id, &gpioc->data))
+		return -1;
+
+	k = 0;
+	while (1) {
+		data_reg = gpioc->data_regs + k;
+
+		if (!data_reg->reg_width)
+			break;
+
+		for (n = 0; n < data_reg->reg_width; n++) {
+			if (data_reg->enum_ids[n] == gpiop->enum_id) {
+				gpiop->flags &= ~PINMUX_FLAG_DREG;
+				gpiop->flags |= (k << PINMUX_FLAG_DREG_SHIFT);
+				gpiop->flags &= ~PINMUX_FLAG_DBIT;
+				gpiop->flags |= (n << PINMUX_FLAG_DBIT_SHIFT);
+				return 0;
+			}
+		}
+		k++;
+	}
+
+	BUG();
+
+	return -1;
+}
+
+static void setup_data_regs(struct pinmux_info *gpioc)
+{
+	struct pinmux_data_reg *drp;
+	int k;
+
+	for (k = gpioc->first_gpio; k <= gpioc->last_gpio; k++)
+		setup_data_reg(gpioc, k);
+
+	k = 0;
+	while (1) {
+		drp = gpioc->data_regs + k;
+
+		if (!drp->reg_width)
+			break;
+
+		drp->reg_shadow = gpio_read_raw_reg(drp->reg, drp->reg_width);
+		k++;
+	}
+}
+
+static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio,
+			struct pinmux_data_reg **drp, int *bitp)
+{
+	struct pinmux_gpio *gpiop = &gpioc->gpios[gpio];
+	int k, n;
+
+	if (!enum_in_range(gpiop->enum_id, &gpioc->data))
+		return -1;
+
+	k = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT;
+	n = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT;
+	*drp = gpioc->data_regs + k;
+	*bitp = n;
+	return 0;
+}
+
+static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id,
+			  struct pinmux_cfg_reg **crp, int *indexp,
+			  unsigned long **cntp)
+{
+	struct pinmux_cfg_reg *config_reg;
+	unsigned long r_width, f_width;
+	int k, n;
+
+	k = 0;
+	while (1) {
+		config_reg = gpioc->cfg_regs + k;
+
+		r_width = config_reg->reg_width;
+		f_width = config_reg->field_width;
+
+		if (!r_width)
+			break;
+		for (n = 0; n < (r_width / f_width) * 1 << f_width; n++) {
+			if (config_reg->enum_ids[n] == enum_id) {
+				*crp = config_reg;
+				*indexp = n;
+				*cntp = &config_reg->cnt[n / (1 << f_width)];
+				return 0;
+			}
+		}
+		k++;
+	}
+
+	return -1;
+}
+
+static int get_gpio_enum_id(struct pinmux_info *gpioc, unsigned gpio,
+			    int pos, pinmux_enum_t *enum_idp)
+{
+	pinmux_enum_t enum_id = gpioc->gpios[gpio].enum_id;
+	pinmux_enum_t *data = gpioc->gpio_data;
+	int k;
+
+	if (!enum_in_range(enum_id, &gpioc->data)) {
+		if (!enum_in_range(enum_id, &gpioc->mark)) {
+			pr_err("non data/mark enum_id for gpio %d\n", gpio);
+			return -1;
+		}
+	}
+
+	if (pos) {
+		*enum_idp = data[pos + 1];
+		return pos + 1;
+	}
+
+	for (k = 0; k < gpioc->gpio_data_size; k++) {
+		if (data[k] == enum_id) {
+			*enum_idp = data[k + 1];
+			return k + 1;
+		}
+	}
+
+	pr_err("cannot locate data/mark enum_id for gpio %d\n", gpio);
+	return -1;
+}
+
+static void write_config_reg(struct pinmux_info *gpioc,
+			     struct pinmux_cfg_reg *crp,
+			     int index)
+{
+	unsigned long ncomb, pos, value;
+
+	ncomb = 1 << crp->field_width;
+	pos = index / ncomb;
+	value = index % ncomb;
+
+	gpio_write_reg(crp->reg, crp->reg_width, crp->field_width, pos, value);
+}
+
+static int check_config_reg(struct pinmux_info *gpioc,
+			    struct pinmux_cfg_reg *crp,
+			    int index)
+{
+	unsigned long ncomb, pos, value;
+
+	ncomb = 1 << crp->field_width;
+	pos = index / ncomb;
+	value = index % ncomb;
+
+	if (gpio_read_reg(crp->reg, crp->reg_width,
+			  crp->field_width, pos) == value)
+		return 0;
+
+	return -1;
+}
+
+enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE };
+
+static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
+			      int pinmux_type, int cfg_mode)
+{
+	struct pinmux_cfg_reg *cr = NULL;
+	pinmux_enum_t enum_id;
+	struct pinmux_range *range;
+	int in_range, pos, index;
+	unsigned long *cntp;
+
+	switch (pinmux_type) {
+
+	case PINMUX_TYPE_FUNCTION:
+		range = NULL;
+		break;
+
+	case PINMUX_TYPE_OUTPUT:
+		range = &gpioc->output;
+		break;
+
+	case PINMUX_TYPE_INPUT:
+		range = &gpioc->input;
+		break;
+
+	case PINMUX_TYPE_INPUT_PULLUP:
+		range = &gpioc->input_pu;
+		break;
+
+	case PINMUX_TYPE_INPUT_PULLDOWN:
+		range = &gpioc->input_pd;
+		break;
+
+	default:
+		goto out_err;
+	}
+
+	pos = 0;
+	enum_id = 0;
+	index = 0;
+	while (1) {
+		pos = get_gpio_enum_id(gpioc, gpio, pos, &enum_id);
+		if (pos <= 0)
+			goto out_err;
+
+		if (!enum_id)
+			break;
+
+		in_range = enum_in_range(enum_id, &gpioc->function);
+		if (!in_range && range) {
+			in_range = enum_in_range(enum_id, range);
+
+			if (in_range && enum_id == range->force)
+				continue;
+		}
+
+		if (!in_range)
+			continue;
+
+		if (get_config_reg(gpioc, enum_id, &cr, &index, &cntp) != 0)
+			goto out_err;
+
+		switch (cfg_mode) {
+		case GPIO_CFG_DRYRUN:
+			if (!*cntp || !check_config_reg(gpioc, cr, index))
+				continue;
+			break;
+
+		case GPIO_CFG_REQ:
+			write_config_reg(gpioc, cr, index);
+			*cntp = *cntp + 1;
+			break;
+
+		case GPIO_CFG_FREE:
+			*cntp = *cntp - 1;
+			break;
+		}
+	}
+
+	return 0;
+ out_err:
+	return -1;
+}
+
+static DEFINE_SPINLOCK(gpio_lock);
+
+static struct pinmux_info *chip_to_pinmux(struct gpio_chip *chip)
+{
+	return container_of(chip, struct pinmux_info, chip);
+}
+
+static int sh_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+	struct pinmux_info *gpioc = chip_to_pinmux(chip);
+	struct pinmux_data_reg *dummy;
+	unsigned long flags;
+	int i, ret, pinmux_type;
+
+	ret = -EINVAL;
+
+	if (!gpioc)
+		goto err_out;
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	if ((gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE)
+		goto err_unlock;
+
+	/* setup pin function here if no data is associated with pin */
+
+	if (get_data_reg(gpioc, offset, &dummy, &i) != 0)
+		pinmux_type = PINMUX_TYPE_FUNCTION;
+	else
+		pinmux_type = PINMUX_TYPE_GPIO;
+
+	if (pinmux_type == PINMUX_TYPE_FUNCTION) {
+		if (pinmux_config_gpio(gpioc, offset,
+				       pinmux_type,
+				       GPIO_CFG_DRYRUN) != 0)
+			goto err_unlock;
+
+		if (pinmux_config_gpio(gpioc, offset,
+				       pinmux_type,
+				       GPIO_CFG_REQ) != 0)
+			BUG();
+	}
+
+	gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
+	gpioc->gpios[offset].flags |= pinmux_type;
+
+	ret = 0;
+ err_unlock:
+	spin_unlock_irqrestore(&gpio_lock, flags);
+ err_out:
+	return ret;
+}
+
+static void sh_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+	struct pinmux_info *gpioc = chip_to_pinmux(chip);
+	unsigned long flags;
+	int pinmux_type;
+
+	if (!gpioc)
+		return;
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	pinmux_type = gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE;
+	pinmux_config_gpio(gpioc, offset, pinmux_type, GPIO_CFG_FREE);
+	gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
+	gpioc->gpios[offset].flags |= PINMUX_TYPE_NONE;
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+}
+
+static int pinmux_direction(struct pinmux_info *gpioc,
+			    unsigned gpio, int new_pinmux_type)
+{
+	int pinmux_type;
+	int ret = -EINVAL;
+
+	if (!gpioc)
+		goto err_out;
+
+	pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE;
+
+	switch (pinmux_type) {
+	case PINMUX_TYPE_GPIO:
+		break;
+	case PINMUX_TYPE_OUTPUT:
+	case PINMUX_TYPE_INPUT:
+	case PINMUX_TYPE_INPUT_PULLUP:
+	case PINMUX_TYPE_INPUT_PULLDOWN:
+		pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE);
+		break;
+	default:
+		goto err_out;
+	}
+
+	if (pinmux_config_gpio(gpioc, gpio,
+			       new_pinmux_type,
+			       GPIO_CFG_DRYRUN) != 0)
+		goto err_out;
+
+	if (pinmux_config_gpio(gpioc, gpio,
+			       new_pinmux_type,
+			       GPIO_CFG_REQ) != 0)
+		BUG();
+
+	gpioc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE;
+	gpioc->gpios[gpio].flags |= new_pinmux_type;
+
+	ret = 0;
+ err_out:
+	return ret;
+}
+
+static int sh_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	struct pinmux_info *gpioc = chip_to_pinmux(chip);
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&gpio_lock, flags);
+	ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_INPUT);
+	spin_unlock_irqrestore(&gpio_lock, flags);
+
+	return ret;
+}
+
+static void sh_gpio_set_value(struct pinmux_info *gpioc,
+			     unsigned gpio, int value)
+{
+	struct pinmux_data_reg *dr = NULL;
+	int bit = 0;
+
+	if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
+		BUG();
+	else
+		gpio_write_bit(dr, bit, value);
+}
+
+static int sh_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+				    int value)
+{
+	struct pinmux_info *gpioc = chip_to_pinmux(chip);
+	unsigned long flags;
+	int ret;
+
+	sh_gpio_set_value(gpioc, offset, value);
+	spin_lock_irqsave(&gpio_lock, flags);
+	ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_OUTPUT);
+	spin_unlock_irqrestore(&gpio_lock, flags);
+
+	return ret;
+}
+
+static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
+{
+	struct pinmux_data_reg *dr = NULL;
+	int bit = 0;
+
+	if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0) {
+		BUG();
+		return 0;
+	}
+
+	return gpio_read_reg(dr->reg, dr->reg_width, 1, bit);
+}
+
+static int sh_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	return sh_gpio_get_value(chip_to_pinmux(chip), offset);
+}
+
+static void sh_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	sh_gpio_set_value(chip_to_pinmux(chip), offset, value);
+}
+
+int register_pinmux(struct pinmux_info *pip)
+{
+	struct gpio_chip *chip = &pip->chip;
+
+	pr_info("sh pinmux: %s handling gpio %d -> %d\n",
+		pip->name, pip->first_gpio, pip->last_gpio);
+
+	setup_data_regs(pip);
+
+	chip->request = sh_gpio_request;
+	chip->free = sh_gpio_free;
+	chip->direction_input = sh_gpio_direction_input;
+	chip->get = sh_gpio_get;
+	chip->direction_output = sh_gpio_direction_output;
+	chip->set = sh_gpio_set;
+
+	WARN_ON(pip->first_gpio != 0); /* needs testing */
+
+	chip->label = pip->name;
+	chip->owner = THIS_MODULE;
+	chip->base = pip->first_gpio;
+	chip->ngpio = (pip->last_gpio - pip->first_gpio) + 1;
+
+	return gpiochip_add(chip);
+}
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index 5d23983..20d7322 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -30,7 +30,6 @@
 #include <linux/errno.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/spidev.h>
@@ -42,7 +41,7 @@
  * This supports acccess to SPI devices using normal userspace I/O calls.
  * Note that while traditional UNIX/POSIX I/O semantics are half duplex,
  * and often mask message boundaries, full SPI support requires full duplex
- * transfers.  There are several kinds of of internal message boundaries to
+ * transfers.  There are several kinds of internal message boundaries to
  * handle chipselect management and other protocol options.
  *
  * SPI has a character major number assigned.  We allocate minor numbers
@@ -477,7 +476,6 @@
 	struct spidev_data	*spidev;
 	int			status = -ENXIO;
 
-	lock_kernel();
 	mutex_lock(&device_list_lock);
 
 	list_for_each_entry(spidev, &device_list, device_entry) {
@@ -503,7 +501,6 @@
 		pr_debug("spidev: nothing for minor %d\n", iminor(inode));
 
 	mutex_unlock(&device_list_lock);
-	unlock_kernel();
 	return status;
 }
 
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index dfcd75c..54e174d2 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -65,8 +65,6 @@
 
 source "drivers/staging/rt2870/Kconfig"
 
-source "drivers/staging/rt3090/Kconfig"
-
 source "drivers/staging/comedi/Kconfig"
 
 source "drivers/staging/asus_oled/Kconfig"
@@ -79,14 +77,14 @@
 
 source "drivers/staging/rtl8192su/Kconfig"
 
+source "drivers/staging/rtl8192u/Kconfig"
+
 source "drivers/staging/rtl8192e/Kconfig"
 
 source "drivers/staging/mimio/Kconfig"
 
 source "drivers/staging/frontier/Kconfig"
 
-source "drivers/staging/android/Kconfig"
-
 source "drivers/staging/dream/Kconfig"
 
 source "drivers/staging/dst/Kconfig"
@@ -103,6 +101,8 @@
 
 source "drivers/gpu/drm/radeon/Kconfig"
 
+source "drivers/gpu/drm/nouveau/Kconfig"
+
 source "drivers/staging/octeon/Kconfig"
 
 source "drivers/staging/serqt_usb2/Kconfig"
@@ -125,6 +125,16 @@
 
 source "drivers/staging/iio/Kconfig"
 
+source "drivers/staging/ramzswap/Kconfig"
+
+source "drivers/staging/wlags49_h2/Kconfig"
+
+source "drivers/staging/wlags49_h25/Kconfig"
+
+source "drivers/staging/batman-adv/Kconfig"
+
+source "drivers/staging/samsung-laptop/Kconfig"
+
 source "drivers/staging/strip/Kconfig"
 
 source "drivers/staging/arlan/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 7719d04..069864f 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -15,18 +15,17 @@
 obj-$(CONFIG_OTUS)		+= otus/
 obj-$(CONFIG_RT2860)		+= rt2860/
 obj-$(CONFIG_RT2870)		+= rt2870/
-obj-$(CONFIG_RT3090)		+= rt3090/
 obj-$(CONFIG_COMEDI)		+= comedi/
 obj-$(CONFIG_ASUS_OLED)		+= asus_oled/
 obj-$(CONFIG_PANEL)		+= panel/
 obj-$(CONFIG_ALTERA_PCIE_CHDMA)	+= altpciechdma/
-obj-$(CONFIG_RTL8187SE)		+= rtl8187se/
+obj-$(CONFIG_R8187SE)		+= rtl8187se/
 obj-$(CONFIG_RTL8192SU)		+= rtl8192su/
+obj-$(CONFIG_RTL8192U)		+= rtl8192u/
 obj-$(CONFIG_RTL8192E)		+= rtl8192e/
 obj-$(CONFIG_INPUT_MIMIO)	+= mimio/
 obj-$(CONFIG_TRANZPORT)		+= frontier/
-obj-$(CONFIG_ANDROID)		+= android/
-obj-$(CONFIG_ANDROID)		+= dream/
+obj-$(CONFIG_DREAM)		+= dream/
 obj-$(CONFIG_DST)		+= dst/
 obj-$(CONFIG_POHMELFS)		+= pohmelfs/
 obj-$(CONFIG_B3DFG)		+= b3dfg/
@@ -44,6 +43,11 @@
 obj-$(CONFIG_RAR_REGISTER)	+= rar/
 obj-$(CONFIG_DX_SEP)		+= sep/
 obj-$(CONFIG_IIO)		+= iio/
+obj-$(CONFIG_RAMZSWAP)		+= ramzswap/
+obj-$(CONFIG_WLAGS49_H2)	+= wlags49_h2/
+obj-$(CONFIG_WLAGS49_H25)	+= wlags49_h25/
+obj-$(CONFIG_BATMAN_ADV)	+= batman-adv/
+obj-$(CONFIG_SAMSUNG_LAPTOP)	+= samsung-laptop/
 obj-$(CONFIG_STRIP)		+= strip/
 obj-$(CONFIG_ARLAN)		+= arlan/
 obj-$(CONFIG_WAVELAN)		+= wavelan/
diff --git a/drivers/staging/altpciechdma/altpciechdma.c b/drivers/staging/altpciechdma/altpciechdma.c
index e0c5ba4..2f07dd4 100644
--- a/drivers/staging/altpciechdma/altpciechdma.c
+++ b/drivers/staging/altpciechdma/altpciechdma.c
@@ -212,7 +212,7 @@
 	int msi_enabled;
 	/* whether this driver could obtain the regions */
 	int got_regions;
-	/* irq line succesfully requested by this driver, -1 otherwise */
+	/* irq line successfully requested by this driver, -1 otherwise */
 	int irq_line;
 	/* board revision */
 	u8 revision;
@@ -336,7 +336,7 @@
 		printk(KERN_DEBUG "BAR[%d] mapped at 0x%p with length %lu(/%lu).\n", i,
 		ape->bar[i], bar_min_len[i], bar_length);
 	}
-	/* succesfully mapped all required BAR regions */
+	/* successfully mapped all required BAR regions */
 	rc = 0;
 	goto success;
 fail:
@@ -911,7 +911,7 @@
 	/* perform DMA engines loop back test */
 	rc = dma_test(ape, dev);
 	(void)rc;
-	/* succesfully took the device */
+	/* successfully took the device */
 	rc = 0;
 	printk(KERN_DEBUG "probe() successful.\n");
 	goto end;
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
deleted file mode 100644
index eb67563..0000000
--- a/drivers/staging/android/Kconfig
+++ /dev/null
@@ -1,96 +0,0 @@
-menu "Android"
-
-config ANDROID
-	bool "Android Drivers"
-	depends on BROKEN
-	default N
-	---help---
-	  Enable support for various drivers needed on the Android platform
-
-if ANDROID
-
-config ANDROID_BINDER_IPC
-	bool "Android Binder IPC Driver"
-	default n
-
-config ANDROID_LOGGER
-	tristate "Android log driver"
-	default n
-
-config ANDROID_RAM_CONSOLE
-	bool "Android RAM buffer console"
-	default n
-
-config ANDROID_RAM_CONSOLE_ENABLE_VERBOSE
-	bool "Enable verbose console messages on Android RAM console"
-	default y
-	depends on ANDROID_RAM_CONSOLE
-
-menuconfig ANDROID_RAM_CONSOLE_ERROR_CORRECTION
-	bool "Android RAM Console Enable error correction"
-	default n
-	depends on ANDROID_RAM_CONSOLE
-	depends on !ANDROID_RAM_CONSOLE_EARLY_INIT
-	select REED_SOLOMON
-	select REED_SOLOMON_ENC8
-	select REED_SOLOMON_DEC8
-
-if ANDROID_RAM_CONSOLE_ERROR_CORRECTION
-
-config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE
-	int "Android RAM Console Data data size"
-	default 128
-	help
-	  Must be a power of 2.
-
-config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE
-	int "Android RAM Console ECC size"
-	default 16
-
-config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE
-	int "Android RAM Console Symbol size"
-	default 8
-
-config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL
-	hex "Android RAM Console Polynomial"
-	default 0x19 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 4)
-	default 0x29 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 5)
-	default 0x61 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 6)
-	default 0x89 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 7)
-	default 0x11d if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 8)
-
-endif # ANDROID_RAM_CONSOLE_ERROR_CORRECTION
-
-config ANDROID_RAM_CONSOLE_EARLY_INIT
-	bool "Start Android RAM console early"
-	default n
-	depends on ANDROID_RAM_CONSOLE
-
-config ANDROID_RAM_CONSOLE_EARLY_ADDR
-	hex "Android RAM console virtual address"
-	default 0
-	depends on ANDROID_RAM_CONSOLE_EARLY_INIT
-
-config ANDROID_RAM_CONSOLE_EARLY_SIZE
-	hex "Android RAM console buffer size"
-	default 0
-	depends on ANDROID_RAM_CONSOLE_EARLY_INIT
-
-config ANDROID_TIMED_OUTPUT
-	bool "Timed output class driver"
-	default y
-
-config ANDROID_TIMED_GPIO
-	tristate "Android timed gpio driver"
-	depends on GENERIC_GPIO && ANDROID_TIMED_OUTPUT
-	default n
-
-config ANDROID_LOW_MEMORY_KILLER
-	bool "Android Low Memory Killer"
-	default N
-	---help---
-	  Register processes to be killed when memory is low
-
-endif # if ANDROID
-
-endmenu
diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile
deleted file mode 100644
index 8e057e6..0000000
--- a/drivers/staging/android/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-obj-$(CONFIG_ANDROID_BINDER_IPC)	+= binder.o
-obj-$(CONFIG_ANDROID_LOGGER)		+= logger.o
-obj-$(CONFIG_ANDROID_RAM_CONSOLE)	+= ram_console.o
-obj-$(CONFIG_ANDROID_TIMED_OUTPUT)	+= timed_output.o
-obj-$(CONFIG_ANDROID_TIMED_GPIO)	+= timed_gpio.o
-obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER)	+= lowmemorykiller.o
diff --git a/drivers/staging/android/TODO b/drivers/staging/android/TODO
deleted file mode 100644
index e59c5be..0000000
--- a/drivers/staging/android/TODO
+++ /dev/null
@@ -1,10 +0,0 @@
-TODO:
-	- checkpatch.pl cleanups
-	- sparse fixes
-	- rename files to be not so "generic"
-	- make sure things build as modules properly
-	- add proper arch dependancies as needed
-	- audit userspace interfaces to make sure they are sane
-
-Please send patches to Greg Kroah-Hartman <greg@kroah.com> and Cc:
-Brian Swetland <swetland@google.com>
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
deleted file mode 100644
index 99010d4..0000000
--- a/drivers/staging/android/binder.c
+++ /dev/null
@@ -1,3767 +0,0 @@
-/* binder.c
- *
- * Android IPC Subsystem
- *
- * Copyright (C) 2007-2008 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <asm/cacheflush.h>
-#include <linux/fdtable.h>
-#include <linux/file.h>
-#include <linux/fs.h>
-#include <linux/list.h>
-#include <linux/miscdevice.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/nsproxy.h>
-#include <linux/poll.h>
-#include <linux/proc_fs.h>
-#include <linux/rbtree.h>
-#include <linux/sched.h>
-#include <linux/uaccess.h>
-#include <linux/vmalloc.h>
-
-#include "binder.h"
-
-static DEFINE_MUTEX(binder_lock);
-static DEFINE_MUTEX(binder_deferred_lock);
-
-static HLIST_HEAD(binder_procs);
-static HLIST_HEAD(binder_deferred_list);
-static HLIST_HEAD(binder_dead_nodes);
-
-static struct proc_dir_entry *binder_proc_dir_entry_root;
-static struct proc_dir_entry *binder_proc_dir_entry_proc;
-static struct binder_node *binder_context_mgr_node;
-static uid_t binder_context_mgr_uid = -1;
-static int binder_last_id;
-
-static int binder_read_proc_proc(char *page, char **start, off_t off,
-				 int count, int *eof, void *data);
-
-/* This is only defined in include/asm-arm/sizes.h */
-#ifndef SZ_1K
-#define SZ_1K                               0x400
-#endif
-
-#ifndef SZ_4M
-#define SZ_4M                               0x400000
-#endif
-
-#define FORBIDDEN_MMAP_FLAGS                (VM_WRITE)
-
-#define BINDER_SMALL_BUF_SIZE (PAGE_SIZE * 64)
-
-enum {
-	BINDER_DEBUG_USER_ERROR             = 1U << 0,
-	BINDER_DEBUG_FAILED_TRANSACTION     = 1U << 1,
-	BINDER_DEBUG_DEAD_TRANSACTION       = 1U << 2,
-	BINDER_DEBUG_OPEN_CLOSE             = 1U << 3,
-	BINDER_DEBUG_DEAD_BINDER            = 1U << 4,
-	BINDER_DEBUG_DEATH_NOTIFICATION     = 1U << 5,
-	BINDER_DEBUG_READ_WRITE             = 1U << 6,
-	BINDER_DEBUG_USER_REFS              = 1U << 7,
-	BINDER_DEBUG_THREADS                = 1U << 8,
-	BINDER_DEBUG_TRANSACTION            = 1U << 9,
-	BINDER_DEBUG_TRANSACTION_COMPLETE   = 1U << 10,
-	BINDER_DEBUG_FREE_BUFFER            = 1U << 11,
-	BINDER_DEBUG_INTERNAL_REFS          = 1U << 12,
-	BINDER_DEBUG_BUFFER_ALLOC           = 1U << 13,
-	BINDER_DEBUG_PRIORITY_CAP           = 1U << 14,
-	BINDER_DEBUG_BUFFER_ALLOC_ASYNC     = 1U << 15,
-};
-static uint32_t binder_debug_mask = BINDER_DEBUG_USER_ERROR |
-	BINDER_DEBUG_FAILED_TRANSACTION | BINDER_DEBUG_DEAD_TRANSACTION;
-module_param_named(debug_mask, binder_debug_mask, uint, S_IWUSR | S_IRUGO);
-
-static int binder_debug_no_lock;
-module_param_named(proc_no_lock, binder_debug_no_lock, bool, S_IWUSR | S_IRUGO);
-
-static DECLARE_WAIT_QUEUE_HEAD(binder_user_error_wait);
-static int binder_stop_on_user_error;
-
-static int binder_set_stop_on_user_error(const char *val,
-					 struct kernel_param *kp)
-{
-	int ret;
-	ret = param_set_int(val, kp);
-	if (binder_stop_on_user_error < 2)
-		wake_up(&binder_user_error_wait);
-	return ret;
-}
-module_param_call(stop_on_user_error, binder_set_stop_on_user_error,
-	param_get_int, &binder_stop_on_user_error, S_IWUSR | S_IRUGO);
-
-#define binder_debug(mask, x...) \
-	do { \
-		if (binder_debug_mask & mask) \
-			printk(KERN_INFO x); \
-	} while (0)
-
-#define binder_user_error(x...) \
-	do { \
-		if (binder_debug_mask & BINDER_DEBUG_USER_ERROR) \
-			printk(KERN_INFO x); \
-		if (binder_stop_on_user_error) \
-			binder_stop_on_user_error = 2; \
-	} while (0)
-
-enum binder_stat_types {
-	BINDER_STAT_PROC,
-	BINDER_STAT_THREAD,
-	BINDER_STAT_NODE,
-	BINDER_STAT_REF,
-	BINDER_STAT_DEATH,
-	BINDER_STAT_TRANSACTION,
-	BINDER_STAT_TRANSACTION_COMPLETE,
-	BINDER_STAT_COUNT
-};
-
-struct binder_stats {
-	int br[_IOC_NR(BR_FAILED_REPLY) + 1];
-	int bc[_IOC_NR(BC_DEAD_BINDER_DONE) + 1];
-	int obj_created[BINDER_STAT_COUNT];
-	int obj_deleted[BINDER_STAT_COUNT];
-};
-
-static struct binder_stats binder_stats;
-
-static inline void binder_stats_deleted(enum binder_stat_types type)
-{
-	binder_stats.obj_deleted[type]++;
-}
-
-static inline void binder_stats_created(enum binder_stat_types type)
-{
-	binder_stats.obj_created[type]++;
-}
-
-struct binder_transaction_log_entry {
-	int debug_id;
-	int call_type;
-	int from_proc;
-	int from_thread;
-	int target_handle;
-	int to_proc;
-	int to_thread;
-	int to_node;
-	int data_size;
-	int offsets_size;
-};
-struct binder_transaction_log {
-	int next;
-	int full;
-	struct binder_transaction_log_entry entry[32];
-};
-static struct binder_transaction_log binder_transaction_log;
-static struct binder_transaction_log binder_transaction_log_failed;
-
-static struct binder_transaction_log_entry *binder_transaction_log_add(
-	struct binder_transaction_log *log)
-{
-	struct binder_transaction_log_entry *e;
-	e = &log->entry[log->next];
-	memset(e, 0, sizeof(*e));
-	log->next++;
-	if (log->next == ARRAY_SIZE(log->entry)) {
-		log->next = 0;
-		log->full = 1;
-	}
-	return e;
-}
-
-struct binder_work {
-	struct list_head entry;
-	enum {
-		BINDER_WORK_TRANSACTION = 1,
-		BINDER_WORK_TRANSACTION_COMPLETE,
-		BINDER_WORK_NODE,
-		BINDER_WORK_DEAD_BINDER,
-		BINDER_WORK_DEAD_BINDER_AND_CLEAR,
-		BINDER_WORK_CLEAR_DEATH_NOTIFICATION,
-	} type;
-};
-
-struct binder_node {
-	int debug_id;
-	struct binder_work work;
-	union {
-		struct rb_node rb_node;
-		struct hlist_node dead_node;
-	};
-	struct binder_proc *proc;
-	struct hlist_head refs;
-	int internal_strong_refs;
-	int local_weak_refs;
-	int local_strong_refs;
-	void __user *ptr;
-	void __user *cookie;
-	unsigned has_strong_ref:1;
-	unsigned pending_strong_ref:1;
-	unsigned has_weak_ref:1;
-	unsigned pending_weak_ref:1;
-	unsigned has_async_transaction:1;
-	unsigned accept_fds:1;
-	unsigned min_priority:8;
-	struct list_head async_todo;
-};
-
-struct binder_ref_death {
-	struct binder_work work;
-	void __user *cookie;
-};
-
-struct binder_ref {
-	/* Lookups needed: */
-	/*   node + proc => ref (transaction) */
-	/*   desc + proc => ref (transaction, inc/dec ref) */
-	/*   node => refs + procs (proc exit) */
-	int debug_id;
-	struct rb_node rb_node_desc;
-	struct rb_node rb_node_node;
-	struct hlist_node node_entry;
-	struct binder_proc *proc;
-	struct binder_node *node;
-	uint32_t desc;
-	int strong;
-	int weak;
-	struct binder_ref_death *death;
-};
-
-struct binder_buffer {
-	struct list_head entry; /* free and allocated entries by addesss */
-	struct rb_node rb_node; /* free entry by size or allocated entry */
-				/* by address */
-	unsigned free:1;
-	unsigned allow_user_free:1;
-	unsigned async_transaction:1;
-	unsigned debug_id:29;
-
-	struct binder_transaction *transaction;
-
-	struct binder_node *target_node;
-	size_t data_size;
-	size_t offsets_size;
-	uint8_t data[0];
-};
-
-enum binder_deferred_state {
-	BINDER_DEFERRED_PUT_FILES    = 0x01,
-	BINDER_DEFERRED_FLUSH        = 0x02,
-	BINDER_DEFERRED_RELEASE      = 0x04,
-};
-
-struct binder_proc {
-	struct hlist_node proc_node;
-	struct rb_root threads;
-	struct rb_root nodes;
-	struct rb_root refs_by_desc;
-	struct rb_root refs_by_node;
-	int pid;
-	struct vm_area_struct *vma;
-	struct task_struct *tsk;
-	struct files_struct *files;
-	struct hlist_node deferred_work_node;
-	int deferred_work;
-	void *buffer;
-	ptrdiff_t user_buffer_offset;
-
-	struct list_head buffers;
-	struct rb_root free_buffers;
-	struct rb_root allocated_buffers;
-	size_t free_async_space;
-
-	struct page **pages;
-	size_t buffer_size;
-	uint32_t buffer_free;
-	struct list_head todo;
-	wait_queue_head_t wait;
-	struct binder_stats stats;
-	struct list_head delivered_death;
-	int max_threads;
-	int requested_threads;
-	int requested_threads_started;
-	int ready_threads;
-	long default_priority;
-};
-
-enum {
-	BINDER_LOOPER_STATE_REGISTERED  = 0x01,
-	BINDER_LOOPER_STATE_ENTERED     = 0x02,
-	BINDER_LOOPER_STATE_EXITED      = 0x04,
-	BINDER_LOOPER_STATE_INVALID     = 0x08,
-	BINDER_LOOPER_STATE_WAITING     = 0x10,
-	BINDER_LOOPER_STATE_NEED_RETURN = 0x20
-};
-
-struct binder_thread {
-	struct binder_proc *proc;
-	struct rb_node rb_node;
-	int pid;
-	int looper;
-	struct binder_transaction *transaction_stack;
-	struct list_head todo;
-	uint32_t return_error; /* Write failed, return error code in read buf */
-	uint32_t return_error2; /* Write failed, return error code in read */
-		/* buffer. Used when sending a reply to a dead process that */
-		/* we are also waiting on */
-	wait_queue_head_t wait;
-	struct binder_stats stats;
-};
-
-struct binder_transaction {
-	int debug_id;
-	struct binder_work work;
-	struct binder_thread *from;
-	struct binder_transaction *from_parent;
-	struct binder_proc *to_proc;
-	struct binder_thread *to_thread;
-	struct binder_transaction *to_parent;
-	unsigned need_reply:1;
-	/* unsigned is_dead:1; */	/* not used at the moment */
-
-	struct binder_buffer *buffer;
-	unsigned int	code;
-	unsigned int	flags;
-	long	priority;
-	long	saved_priority;
-	uid_t	sender_euid;
-};
-
-static void
-binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer);
-
-/*
- * copied from get_unused_fd_flags
- */
-int task_get_unused_fd_flags(struct binder_proc *proc, int flags)
-{
-	struct files_struct *files = proc->files;
-	int fd, error;
-	struct fdtable *fdt;
-	unsigned long rlim_cur;
-	unsigned long irqs;
-
-	if (files == NULL)
-		return -ESRCH;
-
-	error = -EMFILE;
-	spin_lock(&files->file_lock);
-
-repeat:
-	fdt = files_fdtable(files);
-	fd = find_next_zero_bit(fdt->open_fds->fds_bits, fdt->max_fds,
-				files->next_fd);
-
-	/*
-	 * N.B. For clone tasks sharing a files structure, this test
-	 * will limit the total number of files that can be opened.
-	 */
-	rlim_cur = 0;
-	if (lock_task_sighand(proc->tsk, &irqs)) {
-		rlim_cur = proc->tsk->signal->rlim[RLIMIT_NOFILE].rlim_cur;
-		unlock_task_sighand(proc->tsk, &irqs);
-	}
-	if (fd >= rlim_cur)
-		goto out;
-
-	/* Do we need to expand the fd array or fd set?  */
-	error = expand_files(files, fd);
-	if (error < 0)
-		goto out;
-
-	if (error) {
-		/*
-		 * If we needed to expand the fs array we
-		 * might have blocked - try again.
-		 */
-		error = -EMFILE;
-		goto repeat;
-	}
-
-	FD_SET(fd, fdt->open_fds);
-	if (flags & O_CLOEXEC)
-		FD_SET(fd, fdt->close_on_exec);
-	else
-		FD_CLR(fd, fdt->close_on_exec);
-	files->next_fd = fd + 1;
-#if 1
-	/* Sanity check */
-	if (fdt->fd[fd] != NULL) {
-		printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd);
-		fdt->fd[fd] = NULL;
-	}
-#endif
-	error = fd;
-
-out:
-	spin_unlock(&files->file_lock);
-	return error;
-}
-
-/*
- * copied from fd_install
- */
-static void task_fd_install(
-	struct binder_proc *proc, unsigned int fd, struct file *file)
-{
-	struct files_struct *files = proc->files;
-	struct fdtable *fdt;
-
-	if (files == NULL)
-		return;
-
-	spin_lock(&files->file_lock);
-	fdt = files_fdtable(files);
-	BUG_ON(fdt->fd[fd] != NULL);
-	rcu_assign_pointer(fdt->fd[fd], file);
-	spin_unlock(&files->file_lock);
-}
-
-/*
- * copied from __put_unused_fd in open.c
- */
-static void __put_unused_fd(struct files_struct *files, unsigned int fd)
-{
-	struct fdtable *fdt = files_fdtable(files);
-	__FD_CLR(fd, fdt->open_fds);
-	if (fd < files->next_fd)
-		files->next_fd = fd;
-}
-
-/*
- * copied from sys_close
- */
-static long task_close_fd(struct binder_proc *proc, unsigned int fd)
-{
-	struct file *filp;
-	struct files_struct *files = proc->files;
-	struct fdtable *fdt;
-	int retval;
-
-	if (files == NULL)
-		return -ESRCH;
-
-	spin_lock(&files->file_lock);
-	fdt = files_fdtable(files);
-	if (fd >= fdt->max_fds)
-		goto out_unlock;
-	filp = fdt->fd[fd];
-	if (!filp)
-		goto out_unlock;
-	rcu_assign_pointer(fdt->fd[fd], NULL);
-	FD_CLR(fd, fdt->close_on_exec);
-	__put_unused_fd(files, fd);
-	spin_unlock(&files->file_lock);
-	retval = filp_close(filp, files);
-
-	/* can't restart close syscall because file table entry was cleared */
-	if (unlikely(retval == -ERESTARTSYS ||
-		     retval == -ERESTARTNOINTR ||
-		     retval == -ERESTARTNOHAND ||
-		     retval == -ERESTART_RESTARTBLOCK))
-		retval = -EINTR;
-
-	return retval;
-
-out_unlock:
-	spin_unlock(&files->file_lock);
-	return -EBADF;
-}
-
-static void binder_set_nice(long nice)
-{
-	long min_nice;
-	if (can_nice(current, nice)) {
-		set_user_nice(current, nice);
-		return;
-	}
-	min_nice = 20 - current->signal->rlim[RLIMIT_NICE].rlim_cur;
-	binder_debug(BINDER_DEBUG_PRIORITY_CAP,
-		     "binder: %d: nice value %ld not allowed use "
-		     "%ld instead\n", current->pid, nice, min_nice);
-	set_user_nice(current, min_nice);
-	if (min_nice < 20)
-		return;
-	binder_user_error("binder: %d RLIMIT_NICE not set\n", current->pid);
-}
-
-static size_t binder_buffer_size(struct binder_proc *proc,
-				 struct binder_buffer *buffer)
-{
-	if (list_is_last(&buffer->entry, &proc->buffers))
-		return proc->buffer + proc->buffer_size - (void *)buffer->data;
-	else
-		return (size_t)list_entry(buffer->entry.next,
-			struct binder_buffer, entry) - (size_t)buffer->data;
-}
-
-static void binder_insert_free_buffer(struct binder_proc *proc,
-				      struct binder_buffer *new_buffer)
-{
-	struct rb_node **p = &proc->free_buffers.rb_node;
-	struct rb_node *parent = NULL;
-	struct binder_buffer *buffer;
-	size_t buffer_size;
-	size_t new_buffer_size;
-
-	BUG_ON(!new_buffer->free);
-
-	new_buffer_size = binder_buffer_size(proc, new_buffer);
-
-	binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
-		     "binder: %d: add free buffer, size %zd, "
-		     "at %p\n", proc->pid, new_buffer_size, new_buffer);
-
-	while (*p) {
-		parent = *p;
-		buffer = rb_entry(parent, struct binder_buffer, rb_node);
-		BUG_ON(!buffer->free);
-
-		buffer_size = binder_buffer_size(proc, buffer);
-
-		if (new_buffer_size < buffer_size)
-			p = &parent->rb_left;
-		else
-			p = &parent->rb_right;
-	}
-	rb_link_node(&new_buffer->rb_node, parent, p);
-	rb_insert_color(&new_buffer->rb_node, &proc->free_buffers);
-}
-
-static void binder_insert_allocated_buffer(struct binder_proc *proc,
-					   struct binder_buffer *new_buffer)
-{
-	struct rb_node **p = &proc->allocated_buffers.rb_node;
-	struct rb_node *parent = NULL;
-	struct binder_buffer *buffer;
-
-	BUG_ON(new_buffer->free);
-
-	while (*p) {
-		parent = *p;
-		buffer = rb_entry(parent, struct binder_buffer, rb_node);
-		BUG_ON(buffer->free);
-
-		if (new_buffer < buffer)
-			p = &parent->rb_left;
-		else if (new_buffer > buffer)
-			p = &parent->rb_right;
-		else
-			BUG();
-	}
-	rb_link_node(&new_buffer->rb_node, parent, p);
-	rb_insert_color(&new_buffer->rb_node, &proc->allocated_buffers);
-}
-
-static struct binder_buffer *binder_buffer_lookup(struct binder_proc *proc,
-						  void __user *user_ptr)
-{
-	struct rb_node *n = proc->allocated_buffers.rb_node;
-	struct binder_buffer *buffer;
-	struct binder_buffer *kern_ptr;
-
-	kern_ptr = user_ptr - proc->user_buffer_offset
-		- offsetof(struct binder_buffer, data);
-
-	while (n) {
-		buffer = rb_entry(n, struct binder_buffer, rb_node);
-		BUG_ON(buffer->free);
-
-		if (kern_ptr < buffer)
-			n = n->rb_left;
-		else if (kern_ptr > buffer)
-			n = n->rb_right;
-		else
-			return buffer;
-	}
-	return NULL;
-}
-
-static int binder_update_page_range(struct binder_proc *proc, int allocate,
-				    void *start, void *end,
-				    struct vm_area_struct *vma)
-{
-	void *page_addr;
-	unsigned long user_page_addr;
-	struct vm_struct tmp_area;
-	struct page **page;
-	struct mm_struct *mm;
-
-	binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
-		     "binder: %d: %s pages %p-%p\n", proc->pid,
-		     allocate ? "allocate" : "free", start, end);
-
-	if (end <= start)
-		return 0;
-
-	if (vma)
-		mm = NULL;
-	else
-		mm = get_task_mm(proc->tsk);
-
-	if (mm) {
-		down_write(&mm->mmap_sem);
-		vma = proc->vma;
-	}
-
-	if (allocate == 0)
-		goto free_range;
-
-	if (vma == NULL) {
-		printk(KERN_ERR "binder: %d: binder_alloc_buf failed to "
-		       "map pages in userspace, no vma\n", proc->pid);
-		goto err_no_vma;
-	}
-
-	for (page_addr = start; page_addr < end; page_addr += PAGE_SIZE) {
-		int ret;
-		struct page **page_array_ptr;
-		page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE];
-
-		BUG_ON(*page);
-		*page = alloc_page(GFP_KERNEL | __GFP_ZERO);
-		if (*page == NULL) {
-			printk(KERN_ERR "binder: %d: binder_alloc_buf failed "
-			       "for page at %p\n", proc->pid, page_addr);
-			goto err_alloc_page_failed;
-		}
-		tmp_area.addr = page_addr;
-		tmp_area.size = PAGE_SIZE + PAGE_SIZE /* guard page? */;
-		page_array_ptr = page;
-		ret = map_vm_area(&tmp_area, PAGE_KERNEL, &page_array_ptr);
-		if (ret) {
-			printk(KERN_ERR "binder: %d: binder_alloc_buf failed "
-			       "to map page at %p in kernel\n",
-			       proc->pid, page_addr);
-			goto err_map_kernel_failed;
-		}
-		user_page_addr =
-			(uintptr_t)page_addr + proc->user_buffer_offset;
-		ret = vm_insert_page(vma, user_page_addr, page[0]);
-		if (ret) {
-			printk(KERN_ERR "binder: %d: binder_alloc_buf failed "
-			       "to map page at %lx in userspace\n",
-			       proc->pid, user_page_addr);
-			goto err_vm_insert_page_failed;
-		}
-		/* vm_insert_page does not seem to increment the refcount */
-	}
-	if (mm) {
-		up_write(&mm->mmap_sem);
-		mmput(mm);
-	}
-	return 0;
-
-free_range:
-	for (page_addr = end - PAGE_SIZE; page_addr >= start;
-	     page_addr -= PAGE_SIZE) {
-		page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE];
-		if (vma)
-			zap_page_range(vma, (uintptr_t)page_addr +
-				proc->user_buffer_offset, PAGE_SIZE, NULL);
-err_vm_insert_page_failed:
-		unmap_kernel_range((unsigned long)page_addr, PAGE_SIZE);
-err_map_kernel_failed:
-		__free_page(*page);
-		*page = NULL;
-err_alloc_page_failed:
-		;
-	}
-err_no_vma:
-	if (mm) {
-		up_write(&mm->mmap_sem);
-		mmput(mm);
-	}
-	return -ENOMEM;
-}
-
-static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc,
-					      size_t data_size,
-					      size_t offsets_size, int is_async)
-{
-	struct rb_node *n = proc->free_buffers.rb_node;
-	struct binder_buffer *buffer;
-	size_t buffer_size;
-	struct rb_node *best_fit = NULL;
-	void *has_page_addr;
-	void *end_page_addr;
-	size_t size;
-
-	if (proc->vma == NULL) {
-		printk(KERN_ERR "binder: %d: binder_alloc_buf, no vma\n",
-		       proc->pid);
-		return NULL;
-	}
-
-	size = ALIGN(data_size, sizeof(void *)) +
-		ALIGN(offsets_size, sizeof(void *));
-
-	if (size < data_size || size < offsets_size) {
-		binder_user_error("binder: %d: got transaction with invalid "
-			"size %zd-%zd\n", proc->pid, data_size, offsets_size);
-		return NULL;
-	}
-
-	if (is_async &&
-	    proc->free_async_space < size + sizeof(struct binder_buffer)) {
-		binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
-			     "binder: %d: binder_alloc_buf size %zd"
-			     "failed, no async space left\n", proc->pid, size);
-		return NULL;
-	}
-
-	while (n) {
-		buffer = rb_entry(n, struct binder_buffer, rb_node);
-		BUG_ON(!buffer->free);
-		buffer_size = binder_buffer_size(proc, buffer);
-
-		if (size < buffer_size) {
-			best_fit = n;
-			n = n->rb_left;
-		} else if (size > buffer_size)
-			n = n->rb_right;
-		else {
-			best_fit = n;
-			break;
-		}
-	}
-	if (best_fit == NULL) {
-		printk(KERN_ERR "binder: %d: binder_alloc_buf size %zd failed, "
-		       "no address space\n", proc->pid, size);
-		return NULL;
-	}
-	if (n == NULL) {
-		buffer = rb_entry(best_fit, struct binder_buffer, rb_node);
-		buffer_size = binder_buffer_size(proc, buffer);
-	}
-
-	binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
-		     "binder: %d: binder_alloc_buf size %zd got buff"
-		     "er %p size %zd\n", proc->pid, size, buffer, buffer_size);
-
-	has_page_addr =
-		(void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK);
-	if (n == NULL) {
-		if (size + sizeof(struct binder_buffer) + 4 >= buffer_size)
-			buffer_size = size; /* no room for other buffers */
-		else
-			buffer_size = size + sizeof(struct binder_buffer);
-	}
-	end_page_addr =
-		(void *)PAGE_ALIGN((uintptr_t)buffer->data + buffer_size);
-	if (end_page_addr > has_page_addr)
-		end_page_addr = has_page_addr;
-	if (binder_update_page_range(proc, 1,
-	    (void *)PAGE_ALIGN((uintptr_t)buffer->data), end_page_addr, NULL))
-		return NULL;
-
-	rb_erase(best_fit, &proc->free_buffers);
-	buffer->free = 0;
-	binder_insert_allocated_buffer(proc, buffer);
-	if (buffer_size != size) {
-		struct binder_buffer *new_buffer = (void *)buffer->data + size;
-		list_add(&new_buffer->entry, &buffer->entry);
-		new_buffer->free = 1;
-		binder_insert_free_buffer(proc, new_buffer);
-	}
-	binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
-		     "binder: %d: binder_alloc_buf size %zd got "
-		     "%p\n", proc->pid, size, buffer);
-	buffer->data_size = data_size;
-	buffer->offsets_size = offsets_size;
-	buffer->async_transaction = is_async;
-	if (is_async) {
-		proc->free_async_space -= size + sizeof(struct binder_buffer);
-		binder_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC,
-			     "binder: %d: binder_alloc_buf size %zd "
-			     "async free %zd\n", proc->pid, size,
-			     proc->free_async_space);
-	}
-
-	return buffer;
-}
-
-static void *buffer_start_page(struct binder_buffer *buffer)
-{
-	return (void *)((uintptr_t)buffer & PAGE_MASK);
-}
-
-static void *buffer_end_page(struct binder_buffer *buffer)
-{
-	return (void *)(((uintptr_t)(buffer + 1) - 1) & PAGE_MASK);
-}
-
-static void binder_delete_free_buffer(struct binder_proc *proc,
-				      struct binder_buffer *buffer)
-{
-	struct binder_buffer *prev, *next = NULL;
-	int free_page_end = 1;
-	int free_page_start = 1;
-
-	BUG_ON(proc->buffers.next == &buffer->entry);
-	prev = list_entry(buffer->entry.prev, struct binder_buffer, entry);
-	BUG_ON(!prev->free);
-	if (buffer_end_page(prev) == buffer_start_page(buffer)) {
-		free_page_start = 0;
-		if (buffer_end_page(prev) == buffer_end_page(buffer))
-			free_page_end = 0;
-		binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
-			     "binder: %d: merge free, buffer %p "
-			     "share page with %p\n", proc->pid, buffer, prev);
-	}
-
-	if (!list_is_last(&buffer->entry, &proc->buffers)) {
-		next = list_entry(buffer->entry.next,
-				  struct binder_buffer, entry);
-		if (buffer_start_page(next) == buffer_end_page(buffer)) {
-			free_page_end = 0;
-			if (buffer_start_page(next) ==
-			    buffer_start_page(buffer))
-				free_page_start = 0;
-			binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
-				     "binder: %d: merge free, buffer"
-				     " %p share page with %p\n", proc->pid,
-				     buffer, prev);
-		}
-	}
-	list_del(&buffer->entry);
-	if (free_page_start || free_page_end) {
-		binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
-			     "binder: %d: merge free, buffer %p do "
-			     "not share page%s%s with with %p or %p\n",
-			     proc->pid, buffer, free_page_start ? "" : " end",
-			     free_page_end ? "" : " start", prev, next);
-		binder_update_page_range(proc, 0, free_page_start ?
-			buffer_start_page(buffer) : buffer_end_page(buffer),
-			(free_page_end ? buffer_end_page(buffer) :
-			buffer_start_page(buffer)) + PAGE_SIZE, NULL);
-	}
-}
-
-static void binder_free_buf(struct binder_proc *proc,
-			    struct binder_buffer *buffer)
-{
-	size_t size, buffer_size;
-
-	buffer_size = binder_buffer_size(proc, buffer);
-
-	size = ALIGN(buffer->data_size, sizeof(void *)) +
-		ALIGN(buffer->offsets_size, sizeof(void *));
-
-	binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
-		     "binder: %d: binder_free_buf %p size %zd buffer"
-		     "_size %zd\n", proc->pid, buffer, size, buffer_size);
-
-	BUG_ON(buffer->free);
-	BUG_ON(size > buffer_size);
-	BUG_ON(buffer->transaction != NULL);
-	BUG_ON((void *)buffer < proc->buffer);
-	BUG_ON((void *)buffer > proc->buffer + proc->buffer_size);
-
-	if (buffer->async_transaction) {
-		proc->free_async_space += size + sizeof(struct binder_buffer);
-
-		binder_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC,
-			     "binder: %d: binder_free_buf size %zd "
-			     "async free %zd\n", proc->pid, size,
-			     proc->free_async_space);
-	}
-
-	binder_update_page_range(proc, 0,
-		(void *)PAGE_ALIGN((uintptr_t)buffer->data),
-		(void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK),
-		NULL);
-	rb_erase(&buffer->rb_node, &proc->allocated_buffers);
-	buffer->free = 1;
-	if (!list_is_last(&buffer->entry, &proc->buffers)) {
-		struct binder_buffer *next = list_entry(buffer->entry.next,
-						struct binder_buffer, entry);
-		if (next->free) {
-			rb_erase(&next->rb_node, &proc->free_buffers);
-			binder_delete_free_buffer(proc, next);
-		}
-	}
-	if (proc->buffers.next != &buffer->entry) {
-		struct binder_buffer *prev = list_entry(buffer->entry.prev,
-						struct binder_buffer, entry);
-		if (prev->free) {
-			binder_delete_free_buffer(proc, buffer);
-			rb_erase(&prev->rb_node, &proc->free_buffers);
-			buffer = prev;
-		}
-	}
-	binder_insert_free_buffer(proc, buffer);
-}
-
-static struct binder_node *binder_get_node(struct binder_proc *proc,
-					   void __user *ptr)
-{
-	struct rb_node *n = proc->nodes.rb_node;
-	struct binder_node *node;
-
-	while (n) {
-		node = rb_entry(n, struct binder_node, rb_node);
-
-		if (ptr < node->ptr)
-			n = n->rb_left;
-		else if (ptr > node->ptr)
-			n = n->rb_right;
-		else
-			return node;
-	}
-	return NULL;
-}
-
-static struct binder_node *binder_new_node(struct binder_proc *proc,
-					   void __user *ptr,
-					   void __user *cookie)
-{
-	struct rb_node **p = &proc->nodes.rb_node;
-	struct rb_node *parent = NULL;
-	struct binder_node *node;
-
-	while (*p) {
-		parent = *p;
-		node = rb_entry(parent, struct binder_node, rb_node);
-
-		if (ptr < node->ptr)
-			p = &(*p)->rb_left;
-		else if (ptr > node->ptr)
-			p = &(*p)->rb_right;
-		else
-			return NULL;
-	}
-
-	node = kzalloc(sizeof(*node), GFP_KERNEL);
-	if (node == NULL)
-		return NULL;
-	binder_stats_created(BINDER_STAT_NODE);
-	rb_link_node(&node->rb_node, parent, p);
-	rb_insert_color(&node->rb_node, &proc->nodes);
-	node->debug_id = ++binder_last_id;
-	node->proc = proc;
-	node->ptr = ptr;
-	node->cookie = cookie;
-	node->work.type = BINDER_WORK_NODE;
-	INIT_LIST_HEAD(&node->work.entry);
-	INIT_LIST_HEAD(&node->async_todo);
-	binder_debug(BINDER_DEBUG_INTERNAL_REFS,
-		     "binder: %d:%d node %d u%p c%p created\n",
-		     proc->pid, current->pid, node->debug_id,
-		     node->ptr, node->cookie);
-	return node;
-}
-
-static int binder_inc_node(struct binder_node *node, int strong, int internal,
-			   struct list_head *target_list)
-{
-	if (strong) {
-		if (internal) {
-			if (target_list == NULL &&
-			    node->internal_strong_refs == 0 &&
-			    !(node == binder_context_mgr_node &&
-			    node->has_strong_ref)) {
-				printk(KERN_ERR "binder: invalid inc strong "
-					"node for %d\n", node->debug_id);
-				return -EINVAL;
-			}
-			node->internal_strong_refs++;
-		} else
-			node->local_strong_refs++;
-		if (!node->has_strong_ref && target_list) {
-			list_del_init(&node->work.entry);
-			list_add_tail(&node->work.entry, target_list);
-		}
-	} else {
-		if (!internal)
-			node->local_weak_refs++;
-		if (!node->has_weak_ref && list_empty(&node->work.entry)) {
-			if (target_list == NULL) {
-				printk(KERN_ERR "binder: invalid inc weak node "
-					"for %d\n", node->debug_id);
-				return -EINVAL;
-			}
-			list_add_tail(&node->work.entry, target_list);
-		}
-	}
-	return 0;
-}
-
-static int binder_dec_node(struct binder_node *node, int strong, int internal)
-{
-	if (strong) {
-		if (internal)
-			node->internal_strong_refs--;
-		else
-			node->local_strong_refs--;
-		if (node->local_strong_refs || node->internal_strong_refs)
-			return 0;
-	} else {
-		if (!internal)
-			node->local_weak_refs--;
-		if (node->local_weak_refs || !hlist_empty(&node->refs))
-			return 0;
-	}
-	if (node->proc && (node->has_strong_ref || node->has_weak_ref)) {
-		if (list_empty(&node->work.entry)) {
-			list_add_tail(&node->work.entry, &node->proc->todo);
-			wake_up_interruptible(&node->proc->wait);
-		}
-	} else {
-		if (hlist_empty(&node->refs) && !node->local_strong_refs &&
-		    !node->local_weak_refs) {
-			list_del_init(&node->work.entry);
-			if (node->proc) {
-				rb_erase(&node->rb_node, &node->proc->nodes);
-				binder_debug(BINDER_DEBUG_INTERNAL_REFS,
-					     "binder: refless node %d deleted\n",
-					     node->debug_id);
-			} else {
-				hlist_del(&node->dead_node);
-				binder_debug(BINDER_DEBUG_INTERNAL_REFS,
-					     "binder: dead node %d deleted\n",
-					     node->debug_id);
-			}
-			kfree(node);
-			binder_stats_deleted(BINDER_STAT_NODE);
-		}
-	}
-
-	return 0;
-}
-
-
-static struct binder_ref *binder_get_ref(struct binder_proc *proc,
-					 uint32_t desc)
-{
-	struct rb_node *n = proc->refs_by_desc.rb_node;
-	struct binder_ref *ref;
-
-	while (n) {
-		ref = rb_entry(n, struct binder_ref, rb_node_desc);
-
-		if (desc < ref->desc)
-			n = n->rb_left;
-		else if (desc > ref->desc)
-			n = n->rb_right;
-		else
-			return ref;
-	}
-	return NULL;
-}
-
-static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc,
-						  struct binder_node *node)
-{
-	struct rb_node *n;
-	struct rb_node **p = &proc->refs_by_node.rb_node;
-	struct rb_node *parent = NULL;
-	struct binder_ref *ref, *new_ref;
-
-	while (*p) {
-		parent = *p;
-		ref = rb_entry(parent, struct binder_ref, rb_node_node);
-
-		if (node < ref->node)
-			p = &(*p)->rb_left;
-		else if (node > ref->node)
-			p = &(*p)->rb_right;
-		else
-			return ref;
-	}
-	new_ref = kzalloc(sizeof(*ref), GFP_KERNEL);
-	if (new_ref == NULL)
-		return NULL;
-	binder_stats_created(BINDER_STAT_REF);
-	new_ref->debug_id = ++binder_last_id;
-	new_ref->proc = proc;
-	new_ref->node = node;
-	rb_link_node(&new_ref->rb_node_node, parent, p);
-	rb_insert_color(&new_ref->rb_node_node, &proc->refs_by_node);
-
-	new_ref->desc = (node == binder_context_mgr_node) ? 0 : 1;
-	for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) {
-		ref = rb_entry(n, struct binder_ref, rb_node_desc);
-		if (ref->desc > new_ref->desc)
-			break;
-		new_ref->desc = ref->desc + 1;
-	}
-
-	p = &proc->refs_by_desc.rb_node;
-	while (*p) {
-		parent = *p;
-		ref = rb_entry(parent, struct binder_ref, rb_node_desc);
-
-		if (new_ref->desc < ref->desc)
-			p = &(*p)->rb_left;
-		else if (new_ref->desc > ref->desc)
-			p = &(*p)->rb_right;
-		else
-			BUG();
-	}
-	rb_link_node(&new_ref->rb_node_desc, parent, p);
-	rb_insert_color(&new_ref->rb_node_desc, &proc->refs_by_desc);
-	if (node) {
-		hlist_add_head(&new_ref->node_entry, &node->refs);
-
-		binder_debug(BINDER_DEBUG_INTERNAL_REFS,
-			     "binder: %d new ref %d desc %d for "
-			     "node %d\n", proc->pid, new_ref->debug_id,
-			     new_ref->desc, node->debug_id);
-	} else {
-		binder_debug(BINDER_DEBUG_INTERNAL_REFS,
-			     "binder: %d new ref %d desc %d for "
-			     "dead node\n", proc->pid, new_ref->debug_id,
-			      new_ref->desc);
-	}
-	return new_ref;
-}
-
-static void binder_delete_ref(struct binder_ref *ref)
-{
-	binder_debug(BINDER_DEBUG_INTERNAL_REFS,
-		     "binder: %d delete ref %d desc %d for "
-		     "node %d\n", ref->proc->pid, ref->debug_id,
-		     ref->desc, ref->node->debug_id);
-
-	rb_erase(&ref->rb_node_desc, &ref->proc->refs_by_desc);
-	rb_erase(&ref->rb_node_node, &ref->proc->refs_by_node);
-	if (ref->strong)
-		binder_dec_node(ref->node, 1, 1);
-	hlist_del(&ref->node_entry);
-	binder_dec_node(ref->node, 0, 1);
-	if (ref->death) {
-		binder_debug(BINDER_DEBUG_DEAD_BINDER,
-			     "binder: %d delete ref %d desc %d "
-			     "has death notification\n", ref->proc->pid,
-			     ref->debug_id, ref->desc);
-		list_del(&ref->death->work.entry);
-		kfree(ref->death);
-		binder_stats_deleted(BINDER_STAT_DEATH);
-	}
-	kfree(ref);
-	binder_stats_deleted(BINDER_STAT_REF);
-}
-
-static int binder_inc_ref(struct binder_ref *ref, int strong,
-			  struct list_head *target_list)
-{
-	int ret;
-	if (strong) {
-		if (ref->strong == 0) {
-			ret = binder_inc_node(ref->node, 1, 1, target_list);
-			if (ret)
-				return ret;
-		}
-		ref->strong++;
-	} else {
-		if (ref->weak == 0) {
-			ret = binder_inc_node(ref->node, 0, 1, target_list);
-			if (ret)
-				return ret;
-		}
-		ref->weak++;
-	}
-	return 0;
-}
-
-
-static int binder_dec_ref(struct binder_ref *ref, int strong)
-{
-	if (strong) {
-		if (ref->strong == 0) {
-			binder_user_error("binder: %d invalid dec strong, "
-					  "ref %d desc %d s %d w %d\n",
-					  ref->proc->pid, ref->debug_id,
-					  ref->desc, ref->strong, ref->weak);
-			return -EINVAL;
-		}
-		ref->strong--;
-		if (ref->strong == 0) {
-			int ret;
-			ret = binder_dec_node(ref->node, strong, 1);
-			if (ret)
-				return ret;
-		}
-	} else {
-		if (ref->weak == 0) {
-			binder_user_error("binder: %d invalid dec weak, "
-					  "ref %d desc %d s %d w %d\n",
-					  ref->proc->pid, ref->debug_id,
-					  ref->desc, ref->strong, ref->weak);
-			return -EINVAL;
-		}
-		ref->weak--;
-	}
-	if (ref->strong == 0 && ref->weak == 0)
-		binder_delete_ref(ref);
-	return 0;
-}
-
-static void binder_pop_transaction(struct binder_thread *target_thread,
-				   struct binder_transaction *t)
-{
-	if (target_thread) {
-		BUG_ON(target_thread->transaction_stack != t);
-		BUG_ON(target_thread->transaction_stack->from != target_thread);
-		target_thread->transaction_stack =
-			target_thread->transaction_stack->from_parent;
-		t->from = NULL;
-	}
-	t->need_reply = 0;
-	if (t->buffer)
-		t->buffer->transaction = NULL;
-	kfree(t);
-	binder_stats_deleted(BINDER_STAT_TRANSACTION);
-}
-
-static void binder_send_failed_reply(struct binder_transaction *t,
-				     uint32_t error_code)
-{
-	struct binder_thread *target_thread;
-	BUG_ON(t->flags & TF_ONE_WAY);
-	while (1) {
-		target_thread = t->from;
-		if (target_thread) {
-			if (target_thread->return_error != BR_OK &&
-			   target_thread->return_error2 == BR_OK) {
-				target_thread->return_error2 =
-					target_thread->return_error;
-				target_thread->return_error = BR_OK;
-			}
-			if (target_thread->return_error == BR_OK) {
-				binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
-					     "binder: send failed reply for "
-					     "transaction %d to %d:%d\n",
-					      t->debug_id, target_thread->proc->pid,
-					      target_thread->pid);
-
-				binder_pop_transaction(target_thread, t);
-				target_thread->return_error = error_code;
-				wake_up_interruptible(&target_thread->wait);
-			} else {
-				printk(KERN_ERR "binder: reply failed, target "
-					"thread, %d:%d, has error code %d "
-					"already\n", target_thread->proc->pid,
-					target_thread->pid,
-					target_thread->return_error);
-			}
-			return;
-		} else {
-			struct binder_transaction *next = t->from_parent;
-
-			binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
-				     "binder: send failed reply "
-				     "for transaction %d, target dead\n",
-				     t->debug_id);
-
-			binder_pop_transaction(target_thread, t);
-			if (next == NULL) {
-				binder_debug(BINDER_DEBUG_DEAD_BINDER,
-					     "binder: reply failed,"
-					     " no target thread at root\n");
-				return;
-			}
-			t = next;
-			binder_debug(BINDER_DEBUG_DEAD_BINDER,
-				     "binder: reply failed, no target "
-				     "thread -- retry %d\n", t->debug_id);
-		}
-	}
-}
-
-static void binder_transaction_buffer_release(struct binder_proc *proc,
-					      struct binder_buffer *buffer,
-					      size_t *failed_at)
-{
-	size_t *offp, *off_end;
-	int debug_id = buffer->debug_id;
-
-	binder_debug(BINDER_DEBUG_TRANSACTION,
-		     "binder: %d buffer release %d, size %zd-%zd, failed at %p\n",
-		     proc->pid, buffer->debug_id,
-		     buffer->data_size, buffer->offsets_size, failed_at);
-
-	if (buffer->target_node)
-		binder_dec_node(buffer->target_node, 1, 0);
-
-	offp = (size_t *)(buffer->data + ALIGN(buffer->data_size, sizeof(void *)));
-	if (failed_at)
-		off_end = failed_at;
-	else
-		off_end = (void *)offp + buffer->offsets_size;
-	for (; offp < off_end; offp++) {
-		struct flat_binder_object *fp;
-		if (*offp > buffer->data_size - sizeof(*fp) ||
-		    buffer->data_size < sizeof(*fp) ||
-		    !IS_ALIGNED(*offp, sizeof(void *))) {
-			printk(KERN_ERR "binder: transaction release %d bad"
-					"offset %zd, size %zd\n", debug_id,
-					*offp, buffer->data_size);
-			continue;
-		}
-		fp = (struct flat_binder_object *)(buffer->data + *offp);
-		switch (fp->type) {
-		case BINDER_TYPE_BINDER:
-		case BINDER_TYPE_WEAK_BINDER: {
-			struct binder_node *node = binder_get_node(proc, fp->binder);
-			if (node == NULL) {
-				printk(KERN_ERR "binder: transaction release %d"
-				       " bad node %p\n", debug_id, fp->binder);
-				break;
-			}
-			binder_debug(BINDER_DEBUG_TRANSACTION,
-				     "        node %d u%p\n",
-				     node->debug_id, node->ptr);
-			binder_dec_node(node, fp->type == BINDER_TYPE_BINDER, 0);
-		} break;
-		case BINDER_TYPE_HANDLE:
-		case BINDER_TYPE_WEAK_HANDLE: {
-			struct binder_ref *ref = binder_get_ref(proc, fp->handle);
-			if (ref == NULL) {
-				printk(KERN_ERR "binder: transaction release %d"
-				       " bad handle %ld\n", debug_id,
-				       fp->handle);
-				break;
-			}
-			binder_debug(BINDER_DEBUG_TRANSACTION,
-				     "        ref %d desc %d (node %d)\n",
-				     ref->debug_id, ref->desc, ref->node->debug_id);
-			binder_dec_ref(ref, fp->type == BINDER_TYPE_HANDLE);
-		} break;
-
-		case BINDER_TYPE_FD:
-			binder_debug(BINDER_DEBUG_TRANSACTION,
-				     "        fd %ld\n", fp->handle);
-			if (failed_at)
-				task_close_fd(proc, fp->handle);
-			break;
-
-		default:
-			printk(KERN_ERR "binder: transaction release %d bad "
-			       "object type %lx\n", debug_id, fp->type);
-			break;
-		}
-	}
-}
-
-static void binder_transaction(struct binder_proc *proc,
-			       struct binder_thread *thread,
-			       struct binder_transaction_data *tr, int reply)
-{
-	struct binder_transaction *t;
-	struct binder_work *tcomplete;
-	size_t *offp, *off_end;
-	struct binder_proc *target_proc;
-	struct binder_thread *target_thread = NULL;
-	struct binder_node *target_node = NULL;
-	struct list_head *target_list;
-	wait_queue_head_t *target_wait;
-	struct binder_transaction *in_reply_to = NULL;
-	struct binder_transaction_log_entry *e;
-	uint32_t return_error;
-
-	e = binder_transaction_log_add(&binder_transaction_log);
-	e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY);
-	e->from_proc = proc->pid;
-	e->from_thread = thread->pid;
-	e->target_handle = tr->target.handle;
-	e->data_size = tr->data_size;
-	e->offsets_size = tr->offsets_size;
-
-	if (reply) {
-		in_reply_to = thread->transaction_stack;
-		if (in_reply_to == NULL) {
-			binder_user_error("binder: %d:%d got reply transaction "
-					  "with no transaction stack\n",
-					  proc->pid, thread->pid);
-			return_error = BR_FAILED_REPLY;
-			goto err_empty_call_stack;
-		}
-		binder_set_nice(in_reply_to->saved_priority);
-		if (in_reply_to->to_thread != thread) {
-			binder_user_error("binder: %d:%d got reply transaction "
-				"with bad transaction stack,"
-				" transaction %d has target %d:%d\n",
-				proc->pid, thread->pid, in_reply_to->debug_id,
-				in_reply_to->to_proc ?
-				in_reply_to->to_proc->pid : 0,
-				in_reply_to->to_thread ?
-				in_reply_to->to_thread->pid : 0);
-			return_error = BR_FAILED_REPLY;
-			in_reply_to = NULL;
-			goto err_bad_call_stack;
-		}
-		thread->transaction_stack = in_reply_to->to_parent;
-		target_thread = in_reply_to->from;
-		if (target_thread == NULL) {
-			return_error = BR_DEAD_REPLY;
-			goto err_dead_binder;
-		}
-		if (target_thread->transaction_stack != in_reply_to) {
-			binder_user_error("binder: %d:%d got reply transaction "
-				"with bad target transaction stack %d, "
-				"expected %d\n",
-				proc->pid, thread->pid,
-				target_thread->transaction_stack ?
-				target_thread->transaction_stack->debug_id : 0,
-				in_reply_to->debug_id);
-			return_error = BR_FAILED_REPLY;
-			in_reply_to = NULL;
-			target_thread = NULL;
-			goto err_dead_binder;
-		}
-		target_proc = target_thread->proc;
-	} else {
-		if (tr->target.handle) {
-			struct binder_ref *ref;
-			ref = binder_get_ref(proc, tr->target.handle);
-			if (ref == NULL) {
-				binder_user_error("binder: %d:%d got "
-					"transaction to invalid handle\n",
-					proc->pid, thread->pid);
-				return_error = BR_FAILED_REPLY;
-				goto err_invalid_target_handle;
-			}
-			target_node = ref->node;
-		} else {
-			target_node = binder_context_mgr_node;
-			if (target_node == NULL) {
-				return_error = BR_DEAD_REPLY;
-				goto err_no_context_mgr_node;
-			}
-		}
-		e->to_node = target_node->debug_id;
-		target_proc = target_node->proc;
-		if (target_proc == NULL) {
-			return_error = BR_DEAD_REPLY;
-			goto err_dead_binder;
-		}
-		if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) {
-			struct binder_transaction *tmp;
-			tmp = thread->transaction_stack;
-			if (tmp->to_thread != thread) {
-				binder_user_error("binder: %d:%d got new "
-					"transaction with bad transaction stack"
-					", transaction %d has target %d:%d\n",
-					proc->pid, thread->pid, tmp->debug_id,
-					tmp->to_proc ? tmp->to_proc->pid : 0,
-					tmp->to_thread ?
-					tmp->to_thread->pid : 0);
-				return_error = BR_FAILED_REPLY;
-				goto err_bad_call_stack;
-			}
-			while (tmp) {
-				if (tmp->from && tmp->from->proc == target_proc)
-					target_thread = tmp->from;
-				tmp = tmp->from_parent;
-			}
-		}
-	}
-	if (target_thread) {
-		e->to_thread = target_thread->pid;
-		target_list = &target_thread->todo;
-		target_wait = &target_thread->wait;
-	} else {
-		target_list = &target_proc->todo;
-		target_wait = &target_proc->wait;
-	}
-	e->to_proc = target_proc->pid;
-
-	/* TODO: reuse incoming transaction for reply */
-	t = kzalloc(sizeof(*t), GFP_KERNEL);
-	if (t == NULL) {
-		return_error = BR_FAILED_REPLY;
-		goto err_alloc_t_failed;
-	}
-	binder_stats_created(BINDER_STAT_TRANSACTION);
-
-	tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL);
-	if (tcomplete == NULL) {
-		return_error = BR_FAILED_REPLY;
-		goto err_alloc_tcomplete_failed;
-	}
-	binder_stats_created(BINDER_STAT_TRANSACTION_COMPLETE);
-
-	t->debug_id = ++binder_last_id;
-	e->debug_id = t->debug_id;
-
-	if (reply)
-		binder_debug(BINDER_DEBUG_TRANSACTION,
-			     "binder: %d:%d BC_REPLY %d -> %d:%d, "
-			     "data %p-%p size %zd-%zd\n",
-			     proc->pid, thread->pid, t->debug_id,
-			     target_proc->pid, target_thread->pid,
-			     tr->data.ptr.buffer, tr->data.ptr.offsets,
-			     tr->data_size, tr->offsets_size);
-	else
-		binder_debug(BINDER_DEBUG_TRANSACTION,
-			     "binder: %d:%d BC_TRANSACTION %d -> "
-			     "%d - node %d, data %p-%p size %zd-%zd\n",
-			     proc->pid, thread->pid, t->debug_id,
-			     target_proc->pid, target_node->debug_id,
-			     tr->data.ptr.buffer, tr->data.ptr.offsets,
-			     tr->data_size, tr->offsets_size);
-
-	if (!reply && !(tr->flags & TF_ONE_WAY))
-		t->from = thread;
-	else
-		t->from = NULL;
-	t->sender_euid = proc->tsk->cred->euid;
-	t->to_proc = target_proc;
-	t->to_thread = target_thread;
-	t->code = tr->code;
-	t->flags = tr->flags;
-	t->priority = task_nice(current);
-	t->buffer = binder_alloc_buf(target_proc, tr->data_size,
-		tr->offsets_size, !reply && (t->flags & TF_ONE_WAY));
-	if (t->buffer == NULL) {
-		return_error = BR_FAILED_REPLY;
-		goto err_binder_alloc_buf_failed;
-	}
-	t->buffer->allow_user_free = 0;
-	t->buffer->debug_id = t->debug_id;
-	t->buffer->transaction = t;
-	t->buffer->target_node = target_node;
-	if (target_node)
-		binder_inc_node(target_node, 1, 0, NULL);
-
-	offp = (size_t *)(t->buffer->data + ALIGN(tr->data_size, sizeof(void *)));
-
-	if (copy_from_user(t->buffer->data, tr->data.ptr.buffer, tr->data_size)) {
-		binder_user_error("binder: %d:%d got transaction with invalid "
-			"data ptr\n", proc->pid, thread->pid);
-		return_error = BR_FAILED_REPLY;
-		goto err_copy_data_failed;
-	}
-	if (copy_from_user(offp, tr->data.ptr.offsets, tr->offsets_size)) {
-		binder_user_error("binder: %d:%d got transaction with invalid "
-			"offsets ptr\n", proc->pid, thread->pid);
-		return_error = BR_FAILED_REPLY;
-		goto err_copy_data_failed;
-	}
-	if (!IS_ALIGNED(tr->offsets_size, sizeof(size_t))) {
-		binder_user_error("binder: %d:%d got transaction with "
-			"invalid offsets size, %zd\n",
-			proc->pid, thread->pid, tr->offsets_size);
-		return_error = BR_FAILED_REPLY;
-		goto err_bad_offset;
-	}
-	off_end = (void *)offp + tr->offsets_size;
-	for (; offp < off_end; offp++) {
-		struct flat_binder_object *fp;
-		if (*offp > t->buffer->data_size - sizeof(*fp) ||
-		    t->buffer->data_size < sizeof(*fp) ||
-		    !IS_ALIGNED(*offp, sizeof(void *))) {
-			binder_user_error("binder: %d:%d got transaction with "
-				"invalid offset, %zd\n",
-				proc->pid, thread->pid, *offp);
-			return_error = BR_FAILED_REPLY;
-			goto err_bad_offset;
-		}
-		fp = (struct flat_binder_object *)(t->buffer->data + *offp);
-		switch (fp->type) {
-		case BINDER_TYPE_BINDER:
-		case BINDER_TYPE_WEAK_BINDER: {
-			struct binder_ref *ref;
-			struct binder_node *node = binder_get_node(proc, fp->binder);
-			if (node == NULL) {
-				node = binder_new_node(proc, fp->binder, fp->cookie);
-				if (node == NULL) {
-					return_error = BR_FAILED_REPLY;
-					goto err_binder_new_node_failed;
-				}
-				node->min_priority = fp->flags & FLAT_BINDER_FLAG_PRIORITY_MASK;
-				node->accept_fds = !!(fp->flags & FLAT_BINDER_FLAG_ACCEPTS_FDS);
-			}
-			if (fp->cookie != node->cookie) {
-				binder_user_error("binder: %d:%d sending u%p "
-					"node %d, cookie mismatch %p != %p\n",
-					proc->pid, thread->pid,
-					fp->binder, node->debug_id,
-					fp->cookie, node->cookie);
-				goto err_binder_get_ref_for_node_failed;
-			}
-			ref = binder_get_ref_for_node(target_proc, node);
-			if (ref == NULL) {
-				return_error = BR_FAILED_REPLY;
-				goto err_binder_get_ref_for_node_failed;
-			}
-			if (fp->type == BINDER_TYPE_BINDER)
-				fp->type = BINDER_TYPE_HANDLE;
-			else
-				fp->type = BINDER_TYPE_WEAK_HANDLE;
-			fp->handle = ref->desc;
-			binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE,
-				       &thread->todo);
-
-			binder_debug(BINDER_DEBUG_TRANSACTION,
-				     "        node %d u%p -> ref %d desc %d\n",
-				     node->debug_id, node->ptr, ref->debug_id,
-				     ref->desc);
-		} break;
-		case BINDER_TYPE_HANDLE:
-		case BINDER_TYPE_WEAK_HANDLE: {
-			struct binder_ref *ref = binder_get_ref(proc, fp->handle);
-			if (ref == NULL) {
-				binder_user_error("binder: %d:%d got "
-					"transaction with invalid "
-					"handle, %ld\n", proc->pid,
-					thread->pid, fp->handle);
-				return_error = BR_FAILED_REPLY;
-				goto err_binder_get_ref_failed;
-			}
-			if (ref->node->proc == target_proc) {
-				if (fp->type == BINDER_TYPE_HANDLE)
-					fp->type = BINDER_TYPE_BINDER;
-				else
-					fp->type = BINDER_TYPE_WEAK_BINDER;
-				fp->binder = ref->node->ptr;
-				fp->cookie = ref->node->cookie;
-				binder_inc_node(ref->node, fp->type == BINDER_TYPE_BINDER, 0, NULL);
-				binder_debug(BINDER_DEBUG_TRANSACTION,
-					     "        ref %d desc %d -> node %d u%p\n",
-					     ref->debug_id, ref->desc, ref->node->debug_id,
-					     ref->node->ptr);
-			} else {
-				struct binder_ref *new_ref;
-				new_ref = binder_get_ref_for_node(target_proc, ref->node);
-				if (new_ref == NULL) {
-					return_error = BR_FAILED_REPLY;
-					goto err_binder_get_ref_for_node_failed;
-				}
-				fp->handle = new_ref->desc;
-				binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL);
-				binder_debug(BINDER_DEBUG_TRANSACTION,
-					     "        ref %d desc %d -> ref %d desc %d (node %d)\n",
-					     ref->debug_id, ref->desc, new_ref->debug_id,
-					     new_ref->desc, ref->node->debug_id);
-			}
-		} break;
-
-		case BINDER_TYPE_FD: {
-			int target_fd;
-			struct file *file;
-
-			if (reply) {
-				if (!(in_reply_to->flags & TF_ACCEPT_FDS)) {
-					binder_user_error("binder: %d:%d got reply with fd, %ld, but target does not allow fds\n",
-						proc->pid, thread->pid, fp->handle);
-					return_error = BR_FAILED_REPLY;
-					goto err_fd_not_allowed;
-				}
-			} else if (!target_node->accept_fds) {
-				binder_user_error("binder: %d:%d got transaction with fd, %ld, but target does not allow fds\n",
-					proc->pid, thread->pid, fp->handle);
-				return_error = BR_FAILED_REPLY;
-				goto err_fd_not_allowed;
-			}
-
-			file = fget(fp->handle);
-			if (file == NULL) {
-				binder_user_error("binder: %d:%d got transaction with invalid fd, %ld\n",
-					proc->pid, thread->pid, fp->handle);
-				return_error = BR_FAILED_REPLY;
-				goto err_fget_failed;
-			}
-			target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC);
-			if (target_fd < 0) {
-				fput(file);
-				return_error = BR_FAILED_REPLY;
-				goto err_get_unused_fd_failed;
-			}
-			task_fd_install(target_proc, target_fd, file);
-			binder_debug(BINDER_DEBUG_TRANSACTION,
-				     "        fd %ld -> %d\n", fp->handle, target_fd);
-			/* TODO: fput? */
-			fp->handle = target_fd;
-		} break;
-
-		default:
-			binder_user_error("binder: %d:%d got transactio"
-				"n with invalid object type, %lx\n",
-				proc->pid, thread->pid, fp->type);
-			return_error = BR_FAILED_REPLY;
-			goto err_bad_object_type;
-		}
-	}
-	if (reply) {
-		BUG_ON(t->buffer->async_transaction != 0);
-		binder_pop_transaction(target_thread, in_reply_to);
-	} else if (!(t->flags & TF_ONE_WAY)) {
-		BUG_ON(t->buffer->async_transaction != 0);
-		t->need_reply = 1;
-		t->from_parent = thread->transaction_stack;
-		thread->transaction_stack = t;
-	} else {
-		BUG_ON(target_node == NULL);
-		BUG_ON(t->buffer->async_transaction != 1);
-		if (target_node->has_async_transaction) {
-			target_list = &target_node->async_todo;
-			target_wait = NULL;
-		} else
-			target_node->has_async_transaction = 1;
-	}
-	t->work.type = BINDER_WORK_TRANSACTION;
-	list_add_tail(&t->work.entry, target_list);
-	tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;
-	list_add_tail(&tcomplete->entry, &thread->todo);
-	if (target_wait)
-		wake_up_interruptible(target_wait);
-	return;
-
-err_get_unused_fd_failed:
-err_fget_failed:
-err_fd_not_allowed:
-err_binder_get_ref_for_node_failed:
-err_binder_get_ref_failed:
-err_binder_new_node_failed:
-err_bad_object_type:
-err_bad_offset:
-err_copy_data_failed:
-	binder_transaction_buffer_release(target_proc, t->buffer, offp);
-	t->buffer->transaction = NULL;
-	binder_free_buf(target_proc, t->buffer);
-err_binder_alloc_buf_failed:
-	kfree(tcomplete);
-	binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
-err_alloc_tcomplete_failed:
-	kfree(t);
-	binder_stats_deleted(BINDER_STAT_TRANSACTION);
-err_alloc_t_failed:
-err_bad_call_stack:
-err_empty_call_stack:
-err_dead_binder:
-err_invalid_target_handle:
-err_no_context_mgr_node:
-	binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
-		     "binder: %d:%d transaction failed %d, size %zd-%zd\n",
-		     proc->pid, thread->pid, return_error,
-		     tr->data_size, tr->offsets_size);
-
-	{
-		struct binder_transaction_log_entry *fe;
-		fe = binder_transaction_log_add(&binder_transaction_log_failed);
-		*fe = *e;
-	}
-
-	BUG_ON(thread->return_error != BR_OK);
-	if (in_reply_to) {
-		thread->return_error = BR_TRANSACTION_COMPLETE;
-		binder_send_failed_reply(in_reply_to, return_error);
-	} else
-		thread->return_error = return_error;
-}
-
-int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
-			void __user *buffer, int size, signed long *consumed)
-{
-	uint32_t cmd;
-	void __user *ptr = buffer + *consumed;
-	void __user *end = buffer + size;
-
-	while (ptr < end && thread->return_error == BR_OK) {
-		if (get_user(cmd, (uint32_t __user *)ptr))
-			return -EFAULT;
-		ptr += sizeof(uint32_t);
-		if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.bc)) {
-			binder_stats.bc[_IOC_NR(cmd)]++;
-			proc->stats.bc[_IOC_NR(cmd)]++;
-			thread->stats.bc[_IOC_NR(cmd)]++;
-		}
-		switch (cmd) {
-		case BC_INCREFS:
-		case BC_ACQUIRE:
-		case BC_RELEASE:
-		case BC_DECREFS: {
-			uint32_t target;
-			struct binder_ref *ref;
-			const char *debug_string;
-
-			if (get_user(target, (uint32_t __user *)ptr))
-				return -EFAULT;
-			ptr += sizeof(uint32_t);
-			if (target == 0 && binder_context_mgr_node &&
-			    (cmd == BC_INCREFS || cmd == BC_ACQUIRE)) {
-				ref = binder_get_ref_for_node(proc,
-					       binder_context_mgr_node);
-				if (ref->desc != target) {
-					binder_user_error("binder: %d:"
-						"%d tried to acquire "
-						"reference to desc 0, "
-						"got %d instead\n",
-						proc->pid, thread->pid,
-						ref->desc);
-				}
-			} else
-				ref = binder_get_ref(proc, target);
-			if (ref == NULL) {
-				binder_user_error("binder: %d:%d refcou"
-					"nt change on invalid ref %d\n",
-					proc->pid, thread->pid, target);
-				break;
-			}
-			switch (cmd) {
-			case BC_INCREFS:
-				debug_string = "IncRefs";
-				binder_inc_ref(ref, 0, NULL);
-				break;
-			case BC_ACQUIRE:
-				debug_string = "Acquire";
-				binder_inc_ref(ref, 1, NULL);
-				break;
-			case BC_RELEASE:
-				debug_string = "Release";
-				binder_dec_ref(ref, 1);
-				break;
-			case BC_DECREFS:
-			default:
-				debug_string = "DecRefs";
-				binder_dec_ref(ref, 0);
-				break;
-			}
-			binder_debug(BINDER_DEBUG_USER_REFS,
-				     "binder: %d:%d %s ref %d desc %d s %d w %d for node %d\n",
-				     proc->pid, thread->pid, debug_string, ref->debug_id,
-				     ref->desc, ref->strong, ref->weak, ref->node->debug_id);
-			break;
-		}
-		case BC_INCREFS_DONE:
-		case BC_ACQUIRE_DONE: {
-			void __user *node_ptr;
-			void *cookie;
-			struct binder_node *node;
-
-			if (get_user(node_ptr, (void * __user *)ptr))
-				return -EFAULT;
-			ptr += sizeof(void *);
-			if (get_user(cookie, (void * __user *)ptr))
-				return -EFAULT;
-			ptr += sizeof(void *);
-			node = binder_get_node(proc, node_ptr);
-			if (node == NULL) {
-				binder_user_error("binder: %d:%d "
-					"%s u%p no match\n",
-					proc->pid, thread->pid,
-					cmd == BC_INCREFS_DONE ?
-					"BC_INCREFS_DONE" :
-					"BC_ACQUIRE_DONE",
-					node_ptr);
-				break;
-			}
-			if (cookie != node->cookie) {
-				binder_user_error("binder: %d:%d %s u%p node %d"
-					" cookie mismatch %p != %p\n",
-					proc->pid, thread->pid,
-					cmd == BC_INCREFS_DONE ?
-					"BC_INCREFS_DONE" : "BC_ACQUIRE_DONE",
-					node_ptr, node->debug_id,
-					cookie, node->cookie);
-				break;
-			}
-			if (cmd == BC_ACQUIRE_DONE) {
-				if (node->pending_strong_ref == 0) {
-					binder_user_error("binder: %d:%d "
-						"BC_ACQUIRE_DONE node %d has "
-						"no pending acquire request\n",
-						proc->pid, thread->pid,
-						node->debug_id);
-					break;
-				}
-				node->pending_strong_ref = 0;
-			} else {
-				if (node->pending_weak_ref == 0) {
-					binder_user_error("binder: %d:%d "
-						"BC_INCREFS_DONE node %d has "
-						"no pending increfs request\n",
-						proc->pid, thread->pid,
-						node->debug_id);
-					break;
-				}
-				node->pending_weak_ref = 0;
-			}
-			binder_dec_node(node, cmd == BC_ACQUIRE_DONE, 0);
-			binder_debug(BINDER_DEBUG_USER_REFS,
-				     "binder: %d:%d %s node %d ls %d lw %d\n",
-				     proc->pid, thread->pid,
-				     cmd == BC_INCREFS_DONE ? "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE",
-				     node->debug_id, node->local_strong_refs, node->local_weak_refs);
-			break;
-		}
-		case BC_ATTEMPT_ACQUIRE:
-			printk(KERN_ERR "binder: BC_ATTEMPT_ACQUIRE not supported\n");
-			return -EINVAL;
-		case BC_ACQUIRE_RESULT:
-			printk(KERN_ERR "binder: BC_ACQUIRE_RESULT not supported\n");
-			return -EINVAL;
-
-		case BC_FREE_BUFFER: {
-			void __user *data_ptr;
-			struct binder_buffer *buffer;
-
-			if (get_user(data_ptr, (void * __user *)ptr))
-				return -EFAULT;
-			ptr += sizeof(void *);
-
-			buffer = binder_buffer_lookup(proc, data_ptr);
-			if (buffer == NULL) {
-				binder_user_error("binder: %d:%d "
-					"BC_FREE_BUFFER u%p no match\n",
-					proc->pid, thread->pid, data_ptr);
-				break;
-			}
-			if (!buffer->allow_user_free) {
-				binder_user_error("binder: %d:%d "
-					"BC_FREE_BUFFER u%p matched "
-					"unreturned buffer\n",
-					proc->pid, thread->pid, data_ptr);
-				break;
-			}
-			binder_debug(BINDER_DEBUG_FREE_BUFFER,
-				     "binder: %d:%d BC_FREE_BUFFER u%p found buffer %d for %s transaction\n",
-				     proc->pid, thread->pid, data_ptr, buffer->debug_id,
-				     buffer->transaction ? "active" : "finished");
-
-			if (buffer->transaction) {
-				buffer->transaction->buffer = NULL;
-				buffer->transaction = NULL;
-			}
-			if (buffer->async_transaction && buffer->target_node) {
-				BUG_ON(!buffer->target_node->has_async_transaction);
-				if (list_empty(&buffer->target_node->async_todo))
-					buffer->target_node->has_async_transaction = 0;
-				else
-					list_move_tail(buffer->target_node->async_todo.next, &thread->todo);
-			}
-			binder_transaction_buffer_release(proc, buffer, NULL);
-			binder_free_buf(proc, buffer);
-			break;
-		}
-
-		case BC_TRANSACTION:
-		case BC_REPLY: {
-			struct binder_transaction_data tr;
-
-			if (copy_from_user(&tr, ptr, sizeof(tr)))
-				return -EFAULT;
-			ptr += sizeof(tr);
-			binder_transaction(proc, thread, &tr, cmd == BC_REPLY);
-			break;
-		}
-
-		case BC_REGISTER_LOOPER:
-			binder_debug(BINDER_DEBUG_THREADS,
-				     "binder: %d:%d BC_REGISTER_LOOPER\n",
-				     proc->pid, thread->pid);
-			if (thread->looper & BINDER_LOOPER_STATE_ENTERED) {
-				thread->looper |= BINDER_LOOPER_STATE_INVALID;
-				binder_user_error("binder: %d:%d ERROR:"
-					" BC_REGISTER_LOOPER called "
-					"after BC_ENTER_LOOPER\n",
-					proc->pid, thread->pid);
-			} else if (proc->requested_threads == 0) {
-				thread->looper |= BINDER_LOOPER_STATE_INVALID;
-				binder_user_error("binder: %d:%d ERROR:"
-					" BC_REGISTER_LOOPER called "
-					"without request\n",
-					proc->pid, thread->pid);
-			} else {
-				proc->requested_threads--;
-				proc->requested_threads_started++;
-			}
-			thread->looper |= BINDER_LOOPER_STATE_REGISTERED;
-			break;
-		case BC_ENTER_LOOPER:
-			binder_debug(BINDER_DEBUG_THREADS,
-				     "binder: %d:%d BC_ENTER_LOOPER\n",
-				     proc->pid, thread->pid);
-			if (thread->looper & BINDER_LOOPER_STATE_REGISTERED) {
-				thread->looper |= BINDER_LOOPER_STATE_INVALID;
-				binder_user_error("binder: %d:%d ERROR:"
-					" BC_ENTER_LOOPER called after "
-					"BC_REGISTER_LOOPER\n",
-					proc->pid, thread->pid);
-			}
-			thread->looper |= BINDER_LOOPER_STATE_ENTERED;
-			break;
-		case BC_EXIT_LOOPER:
-			binder_debug(BINDER_DEBUG_THREADS,
-				     "binder: %d:%d BC_EXIT_LOOPER\n",
-				     proc->pid, thread->pid);
-			thread->looper |= BINDER_LOOPER_STATE_EXITED;
-			break;
-
-		case BC_REQUEST_DEATH_NOTIFICATION:
-		case BC_CLEAR_DEATH_NOTIFICATION: {
-			uint32_t target;
-			void __user *cookie;
-			struct binder_ref *ref;
-			struct binder_ref_death *death;
-
-			if (get_user(target, (uint32_t __user *)ptr))
-				return -EFAULT;
-			ptr += sizeof(uint32_t);
-			if (get_user(cookie, (void __user * __user *)ptr))
-				return -EFAULT;
-			ptr += sizeof(void *);
-			ref = binder_get_ref(proc, target);
-			if (ref == NULL) {
-				binder_user_error("binder: %d:%d %s "
-					"invalid ref %d\n",
-					proc->pid, thread->pid,
-					cmd == BC_REQUEST_DEATH_NOTIFICATION ?
-					"BC_REQUEST_DEATH_NOTIFICATION" :
-					"BC_CLEAR_DEATH_NOTIFICATION",
-					target);
-				break;
-			}
-
-			binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION,
-				     "binder: %d:%d %s %p ref %d desc %d s %d w %d for node %d\n",
-				     proc->pid, thread->pid,
-				     cmd == BC_REQUEST_DEATH_NOTIFICATION ?
-				     "BC_REQUEST_DEATH_NOTIFICATION" :
-				     "BC_CLEAR_DEATH_NOTIFICATION",
-				     cookie, ref->debug_id, ref->desc,
-				     ref->strong, ref->weak, ref->node->debug_id);
-
-			if (cmd == BC_REQUEST_DEATH_NOTIFICATION) {
-				if (ref->death) {
-					binder_user_error("binder: %d:%"
-						"d BC_REQUEST_DEATH_NOTI"
-						"FICATION death notific"
-						"ation already set\n",
-						proc->pid, thread->pid);
-					break;
-				}
-				death = kzalloc(sizeof(*death), GFP_KERNEL);
-				if (death == NULL) {
-					thread->return_error = BR_ERROR;
-					binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
-						     "binder: %d:%d "
-						     "BC_REQUEST_DEATH_NOTIFICATION failed\n",
-						     proc->pid, thread->pid);
-					break;
-				}
-				binder_stats_created(BINDER_STAT_DEATH);
-				INIT_LIST_HEAD(&death->work.entry);
-				death->cookie = cookie;
-				ref->death = death;
-				if (ref->node->proc == NULL) {
-					ref->death->work.type = BINDER_WORK_DEAD_BINDER;
-					if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) {
-						list_add_tail(&ref->death->work.entry, &thread->todo);
-					} else {
-						list_add_tail(&ref->death->work.entry, &proc->todo);
-						wake_up_interruptible(&proc->wait);
-					}
-				}
-			} else {
-				if (ref->death == NULL) {
-					binder_user_error("binder: %d:%"
-						"d BC_CLEAR_DEATH_NOTIFI"
-						"CATION death notificat"
-						"ion not active\n",
-						proc->pid, thread->pid);
-					break;
-				}
-				death = ref->death;
-				if (death->cookie != cookie) {
-					binder_user_error("binder: %d:%"
-						"d BC_CLEAR_DEATH_NOTIFI"
-						"CATION death notificat"
-						"ion cookie mismatch "
-						"%p != %p\n",
-						proc->pid, thread->pid,
-						death->cookie, cookie);
-					break;
-				}
-				ref->death = NULL;
-				if (list_empty(&death->work.entry)) {
-					death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION;
-					if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) {
-						list_add_tail(&death->work.entry, &thread->todo);
-					} else {
-						list_add_tail(&death->work.entry, &proc->todo);
-						wake_up_interruptible(&proc->wait);
-					}
-				} else {
-					BUG_ON(death->work.type != BINDER_WORK_DEAD_BINDER);
-					death->work.type = BINDER_WORK_DEAD_BINDER_AND_CLEAR;
-				}
-			}
-		} break;
-		case BC_DEAD_BINDER_DONE: {
-			struct binder_work *w;
-			void __user *cookie;
-			struct binder_ref_death *death = NULL;
-			if (get_user(cookie, (void __user * __user *)ptr))
-				return -EFAULT;
-
-			ptr += sizeof(void *);
-			list_for_each_entry(w, &proc->delivered_death, entry) {
-				struct binder_ref_death *tmp_death = container_of(w, struct binder_ref_death, work);
-				if (tmp_death->cookie == cookie) {
-					death = tmp_death;
-					break;
-				}
-			}
-			binder_debug(BINDER_DEBUG_DEAD_BINDER,
-				     "binder: %d:%d BC_DEAD_BINDER_DONE %p found %p\n",
-				     proc->pid, thread->pid, cookie, death);
-			if (death == NULL) {
-				binder_user_error("binder: %d:%d BC_DEAD"
-					"_BINDER_DONE %p not found\n",
-					proc->pid, thread->pid, cookie);
-				break;
-			}
-
-			list_del_init(&death->work.entry);
-			if (death->work.type == BINDER_WORK_DEAD_BINDER_AND_CLEAR) {
-				death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION;
-				if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) {
-					list_add_tail(&death->work.entry, &thread->todo);
-				} else {
-					list_add_tail(&death->work.entry, &proc->todo);
-					wake_up_interruptible(&proc->wait);
-				}
-			}
-		} break;
-
-		default:
-			printk(KERN_ERR "binder: %d:%d unknown command %d\n",
-			       proc->pid, thread->pid, cmd);
-			return -EINVAL;
-		}
-		*consumed = ptr - buffer;
-	}
-	return 0;
-}
-
-void binder_stat_br(struct binder_proc *proc, struct binder_thread *thread,
-		    uint32_t cmd)
-{
-	if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.br)) {
-		binder_stats.br[_IOC_NR(cmd)]++;
-		proc->stats.br[_IOC_NR(cmd)]++;
-		thread->stats.br[_IOC_NR(cmd)]++;
-	}
-}
-
-static int binder_has_proc_work(struct binder_proc *proc,
-				struct binder_thread *thread)
-{
-	return !list_empty(&proc->todo) ||
-		(thread->looper & BINDER_LOOPER_STATE_NEED_RETURN);
-}
-
-static int binder_has_thread_work(struct binder_thread *thread)
-{
-	return !list_empty(&thread->todo) || thread->return_error != BR_OK ||
-		(thread->looper & BINDER_LOOPER_STATE_NEED_RETURN);
-}
-
-static int binder_thread_read(struct binder_proc *proc,
-			      struct binder_thread *thread,
-			      void  __user *buffer, int size,
-			      signed long *consumed, int non_block)
-{
-	void __user *ptr = buffer + *consumed;
-	void __user *end = buffer + size;
-
-	int ret = 0;
-	int wait_for_proc_work;
-
-	if (*consumed == 0) {
-		if (put_user(BR_NOOP, (uint32_t __user *)ptr))
-			return -EFAULT;
-		ptr += sizeof(uint32_t);
-	}
-
-retry:
-	wait_for_proc_work = thread->transaction_stack == NULL &&
-				list_empty(&thread->todo);
-
-	if (thread->return_error != BR_OK && ptr < end) {
-		if (thread->return_error2 != BR_OK) {
-			if (put_user(thread->return_error2, (uint32_t __user *)ptr))
-				return -EFAULT;
-			ptr += sizeof(uint32_t);
-			if (ptr == end)
-				goto done;
-			thread->return_error2 = BR_OK;
-		}
-		if (put_user(thread->return_error, (uint32_t __user *)ptr))
-			return -EFAULT;
-		ptr += sizeof(uint32_t);
-		thread->return_error = BR_OK;
-		goto done;
-	}
-
-
-	thread->looper |= BINDER_LOOPER_STATE_WAITING;
-	if (wait_for_proc_work)
-		proc->ready_threads++;
-	mutex_unlock(&binder_lock);
-	if (wait_for_proc_work) {
-		if (!(thread->looper & (BINDER_LOOPER_STATE_REGISTERED |
-					BINDER_LOOPER_STATE_ENTERED))) {
-			binder_user_error("binder: %d:%d ERROR: Thread waiting "
-				"for process work before calling BC_REGISTER_"
-				"LOOPER or BC_ENTER_LOOPER (state %x)\n",
-				proc->pid, thread->pid, thread->looper);
-			wait_event_interruptible(binder_user_error_wait,
-						 binder_stop_on_user_error < 2);
-		}
-		binder_set_nice(proc->default_priority);
-		if (non_block) {
-			if (!binder_has_proc_work(proc, thread))
-				ret = -EAGAIN;
-		} else
-			ret = wait_event_interruptible_exclusive(proc->wait, binder_has_proc_work(proc, thread));
-	} else {
-		if (non_block) {
-			if (!binder_has_thread_work(thread))
-				ret = -EAGAIN;
-		} else
-			ret = wait_event_interruptible(thread->wait, binder_has_thread_work(thread));
-	}
-	mutex_lock(&binder_lock);
-	if (wait_for_proc_work)
-		proc->ready_threads--;
-	thread->looper &= ~BINDER_LOOPER_STATE_WAITING;
-
-	if (ret)
-		return ret;
-
-	while (1) {
-		uint32_t cmd;
-		struct binder_transaction_data tr;
-		struct binder_work *w;
-		struct binder_transaction *t = NULL;
-
-		if (!list_empty(&thread->todo))
-			w = list_first_entry(&thread->todo, struct binder_work, entry);
-		else if (!list_empty(&proc->todo) && wait_for_proc_work)
-			w = list_first_entry(&proc->todo, struct binder_work, entry);
-		else {
-			if (ptr - buffer == 4 && !(thread->looper & BINDER_LOOPER_STATE_NEED_RETURN)) /* no data added */
-				goto retry;
-			break;
-		}
-
-		if (end - ptr < sizeof(tr) + 4)
-			break;
-
-		switch (w->type) {
-		case BINDER_WORK_TRANSACTION: {
-			t = container_of(w, struct binder_transaction, work);
-		} break;
-		case BINDER_WORK_TRANSACTION_COMPLETE: {
-			cmd = BR_TRANSACTION_COMPLETE;
-			if (put_user(cmd, (uint32_t __user *)ptr))
-				return -EFAULT;
-			ptr += sizeof(uint32_t);
-
-			binder_stat_br(proc, thread, cmd);
-			binder_debug(BINDER_DEBUG_TRANSACTION_COMPLETE,
-				     "binder: %d:%d BR_TRANSACTION_COMPLETE\n",
-				     proc->pid, thread->pid);
-
-			list_del(&w->entry);
-			kfree(w);
-			binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
-		} break;
-		case BINDER_WORK_NODE: {
-			struct binder_node *node = container_of(w, struct binder_node, work);
-			uint32_t cmd = BR_NOOP;
-			const char *cmd_name;
-			int strong = node->internal_strong_refs || node->local_strong_refs;
-			int weak = !hlist_empty(&node->refs) || node->local_weak_refs || strong;
-			if (weak && !node->has_weak_ref) {
-				cmd = BR_INCREFS;
-				cmd_name = "BR_INCREFS";
-				node->has_weak_ref = 1;
-				node->pending_weak_ref = 1;
-				node->local_weak_refs++;
-			} else if (strong && !node->has_strong_ref) {
-				cmd = BR_ACQUIRE;
-				cmd_name = "BR_ACQUIRE";
-				node->has_strong_ref = 1;
-				node->pending_strong_ref = 1;
-				node->local_strong_refs++;
-			} else if (!strong && node->has_strong_ref) {
-				cmd = BR_RELEASE;
-				cmd_name = "BR_RELEASE";
-				node->has_strong_ref = 0;
-			} else if (!weak && node->has_weak_ref) {
-				cmd = BR_DECREFS;
-				cmd_name = "BR_DECREFS";
-				node->has_weak_ref = 0;
-			}
-			if (cmd != BR_NOOP) {
-				if (put_user(cmd, (uint32_t __user *)ptr))
-					return -EFAULT;
-				ptr += sizeof(uint32_t);
-				if (put_user(node->ptr, (void * __user *)ptr))
-					return -EFAULT;
-				ptr += sizeof(void *);
-				if (put_user(node->cookie, (void * __user *)ptr))
-					return -EFAULT;
-				ptr += sizeof(void *);
-
-				binder_stat_br(proc, thread, cmd);
-				binder_debug(BINDER_DEBUG_USER_REFS,
-					     "binder: %d:%d %s %d u%p c%p\n",
-					     proc->pid, thread->pid, cmd_name, node->debug_id, node->ptr, node->cookie);
-			} else {
-				list_del_init(&w->entry);
-				if (!weak && !strong) {
-					binder_debug(BINDER_DEBUG_INTERNAL_REFS,
-						     "binder: %d:%d node %d u%p c%p deleted\n",
-						     proc->pid, thread->pid, node->debug_id,
-						     node->ptr, node->cookie);
-					rb_erase(&node->rb_node, &proc->nodes);
-					kfree(node);
-					binder_stats_deleted(BINDER_STAT_NODE);
-				} else {
-					binder_debug(BINDER_DEBUG_INTERNAL_REFS,
-						     "binder: %d:%d node %d u%p c%p state unchanged\n",
-						     proc->pid, thread->pid, node->debug_id, node->ptr,
-						     node->cookie);
-				}
-			}
-		} break;
-		case BINDER_WORK_DEAD_BINDER:
-		case BINDER_WORK_DEAD_BINDER_AND_CLEAR:
-		case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: {
-			struct binder_ref_death *death;
-			uint32_t cmd;
-
-			death = container_of(w, struct binder_ref_death, work);
-			if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION)
-				cmd = BR_CLEAR_DEATH_NOTIFICATION_DONE;
-			else
-				cmd = BR_DEAD_BINDER;
-			if (put_user(cmd, (uint32_t __user *)ptr))
-				return -EFAULT;
-			ptr += sizeof(uint32_t);
-			if (put_user(death->cookie, (void * __user *)ptr))
-				return -EFAULT;
-			ptr += sizeof(void *);
-			binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION,
-				     "binder: %d:%d %s %p\n",
-				      proc->pid, thread->pid,
-				      cmd == BR_DEAD_BINDER ?
-				      "BR_DEAD_BINDER" :
-				      "BR_CLEAR_DEATH_NOTIFICATION_DONE",
-				      death->cookie);
-
-			if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) {
-				list_del(&w->entry);
-				kfree(death);
-				binder_stats_deleted(BINDER_STAT_DEATH);
-			} else
-				list_move(&w->entry, &proc->delivered_death);
-			if (cmd == BR_DEAD_BINDER)
-				goto done; /* DEAD_BINDER notifications can cause transactions */
-		} break;
-		}
-
-		if (!t)
-			continue;
-
-		BUG_ON(t->buffer == NULL);
-		if (t->buffer->target_node) {
-			struct binder_node *target_node = t->buffer->target_node;
-			tr.target.ptr = target_node->ptr;
-			tr.cookie =  target_node->cookie;
-			t->saved_priority = task_nice(current);
-			if (t->priority < target_node->min_priority &&
-			    !(t->flags & TF_ONE_WAY))
-				binder_set_nice(t->priority);
-			else if (!(t->flags & TF_ONE_WAY) ||
-				 t->saved_priority > target_node->min_priority)
-				binder_set_nice(target_node->min_priority);
-			cmd = BR_TRANSACTION;
-		} else {
-			tr.target.ptr = NULL;
-			tr.cookie = NULL;
-			cmd = BR_REPLY;
-		}
-		tr.code = t->code;
-		tr.flags = t->flags;
-		tr.sender_euid = t->sender_euid;
-
-		if (t->from) {
-			struct task_struct *sender = t->from->proc->tsk;
-			tr.sender_pid = task_tgid_nr_ns(sender,
-							current->nsproxy->pid_ns);
-		} else {
-			tr.sender_pid = 0;
-		}
-
-		tr.data_size = t->buffer->data_size;
-		tr.offsets_size = t->buffer->offsets_size;
-		tr.data.ptr.buffer = (void *)t->buffer->data +
-					proc->user_buffer_offset;
-		tr.data.ptr.offsets = tr.data.ptr.buffer +
-					ALIGN(t->buffer->data_size,
-					    sizeof(void *));
-
-		if (put_user(cmd, (uint32_t __user *)ptr))
-			return -EFAULT;
-		ptr += sizeof(uint32_t);
-		if (copy_to_user(ptr, &tr, sizeof(tr)))
-			return -EFAULT;
-		ptr += sizeof(tr);
-
-		binder_stat_br(proc, thread, cmd);
-		binder_debug(BINDER_DEBUG_TRANSACTION,
-			     "binder: %d:%d %s %d %d:%d, cmd %d"
-			     "size %zd-%zd ptr %p-%p\n",
-			     proc->pid, thread->pid,
-			     (cmd == BR_TRANSACTION) ? "BR_TRANSACTION" :
-			     "BR_REPLY",
-			     t->debug_id, t->from ? t->from->proc->pid : 0,
-			     t->from ? t->from->pid : 0, cmd,
-			     t->buffer->data_size, t->buffer->offsets_size,
-			     tr.data.ptr.buffer, tr.data.ptr.offsets);
-
-		list_del(&t->work.entry);
-		t->buffer->allow_user_free = 1;
-		if (cmd == BR_TRANSACTION && !(t->flags & TF_ONE_WAY)) {
-			t->to_parent = thread->transaction_stack;
-			t->to_thread = thread;
-			thread->transaction_stack = t;
-		} else {
-			t->buffer->transaction = NULL;
-			kfree(t);
-			binder_stats_deleted(BINDER_STAT_TRANSACTION);
-		}
-		break;
-	}
-
-done:
-
-	*consumed = ptr - buffer;
-	if (proc->requested_threads + proc->ready_threads == 0 &&
-	    proc->requested_threads_started < proc->max_threads &&
-	    (thread->looper & (BINDER_LOOPER_STATE_REGISTERED |
-	     BINDER_LOOPER_STATE_ENTERED)) /* the user-space code fails to */
-	     /*spawn a new thread if we leave this out */) {
-		proc->requested_threads++;
-		binder_debug(BINDER_DEBUG_THREADS,
-			     "binder: %d:%d BR_SPAWN_LOOPER\n",
-			     proc->pid, thread->pid);
-		if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer))
-			return -EFAULT;
-	}
-	return 0;
-}
-
-static void binder_release_work(struct list_head *list)
-{
-	struct binder_work *w;
-	while (!list_empty(list)) {
-		w = list_first_entry(list, struct binder_work, entry);
-		list_del_init(&w->entry);
-		switch (w->type) {
-		case BINDER_WORK_TRANSACTION: {
-			struct binder_transaction *t;
-
-			t = container_of(w, struct binder_transaction, work);
-			if (t->buffer->target_node && !(t->flags & TF_ONE_WAY))
-				binder_send_failed_reply(t, BR_DEAD_REPLY);
-		} break;
-		case BINDER_WORK_TRANSACTION_COMPLETE: {
-			kfree(w);
-			binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
-		} break;
-		default:
-			break;
-		}
-	}
-
-}
-
-static struct binder_thread *binder_get_thread(struct binder_proc *proc)
-{
-	struct binder_thread *thread = NULL;
-	struct rb_node *parent = NULL;
-	struct rb_node **p = &proc->threads.rb_node;
-
-	while (*p) {
-		parent = *p;
-		thread = rb_entry(parent, struct binder_thread, rb_node);
-
-		if (current->pid < thread->pid)
-			p = &(*p)->rb_left;
-		else if (current->pid > thread->pid)
-			p = &(*p)->rb_right;
-		else
-			break;
-	}
-	if (*p == NULL) {
-		thread = kzalloc(sizeof(*thread), GFP_KERNEL);
-		if (thread == NULL)
-			return NULL;
-		binder_stats_created(BINDER_STAT_THREAD);
-		thread->proc = proc;
-		thread->pid = current->pid;
-		init_waitqueue_head(&thread->wait);
-		INIT_LIST_HEAD(&thread->todo);
-		rb_link_node(&thread->rb_node, parent, p);
-		rb_insert_color(&thread->rb_node, &proc->threads);
-		thread->looper |= BINDER_LOOPER_STATE_NEED_RETURN;
-		thread->return_error = BR_OK;
-		thread->return_error2 = BR_OK;
-	}
-	return thread;
-}
-
-static int binder_free_thread(struct binder_proc *proc,
-			      struct binder_thread *thread)
-{
-	struct binder_transaction *t;
-	struct binder_transaction *send_reply = NULL;
-	int active_transactions = 0;
-
-	rb_erase(&thread->rb_node, &proc->threads);
-	t = thread->transaction_stack;
-	if (t && t->to_thread == thread)
-		send_reply = t;
-	while (t) {
-		active_transactions++;
-		binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
-			     "binder: release %d:%d transaction %d "
-			     "%s, still active\n", proc->pid, thread->pid,
-			     t->debug_id,
-			     (t->to_thread == thread) ? "in" : "out");
-
-		if (t->to_thread == thread) {
-			t->to_proc = NULL;
-			t->to_thread = NULL;
-			if (t->buffer) {
-				t->buffer->transaction = NULL;
-				t->buffer = NULL;
-			}
-			t = t->to_parent;
-		} else if (t->from == thread) {
-			t->from = NULL;
-			t = t->from_parent;
-		} else
-			BUG();
-	}
-	if (send_reply)
-		binder_send_failed_reply(send_reply, BR_DEAD_REPLY);
-	binder_release_work(&thread->todo);
-	kfree(thread);
-	binder_stats_deleted(BINDER_STAT_THREAD);
-	return active_transactions;
-}
-
-static unsigned int binder_poll(struct file *filp,
-				struct poll_table_struct *wait)
-{
-	struct binder_proc *proc = filp->private_data;
-	struct binder_thread *thread = NULL;
-	int wait_for_proc_work;
-
-	mutex_lock(&binder_lock);
-	thread = binder_get_thread(proc);
-
-	wait_for_proc_work = thread->transaction_stack == NULL &&
-		list_empty(&thread->todo) && thread->return_error == BR_OK;
-	mutex_unlock(&binder_lock);
-
-	if (wait_for_proc_work) {
-		if (binder_has_proc_work(proc, thread))
-			return POLLIN;
-		poll_wait(filp, &proc->wait, wait);
-		if (binder_has_proc_work(proc, thread))
-			return POLLIN;
-	} else {
-		if (binder_has_thread_work(thread))
-			return POLLIN;
-		poll_wait(filp, &thread->wait, wait);
-		if (binder_has_thread_work(thread))
-			return POLLIN;
-	}
-	return 0;
-}
-
-static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
-	int ret;
-	struct binder_proc *proc = filp->private_data;
-	struct binder_thread *thread;
-	unsigned int size = _IOC_SIZE(cmd);
-	void __user *ubuf = (void __user *)arg;
-
-	/*printk(KERN_INFO "binder_ioctl: %d:%d %x %lx\n", proc->pid, current->pid, cmd, arg);*/
-
-	ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
-	if (ret)
-		return ret;
-
-	mutex_lock(&binder_lock);
-	thread = binder_get_thread(proc);
-	if (thread == NULL) {
-		ret = -ENOMEM;
-		goto err;
-	}
-
-	switch (cmd) {
-	case BINDER_WRITE_READ: {
-		struct binder_write_read bwr;
-		if (size != sizeof(struct binder_write_read)) {
-			ret = -EINVAL;
-			goto err;
-		}
-		if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
-			ret = -EFAULT;
-			goto err;
-		}
-		binder_debug(BINDER_DEBUG_READ_WRITE,
-			     "binder: %d:%d write %ld at %08lx, read %ld at %08lx\n",
-			     proc->pid, thread->pid, bwr.write_size, bwr.write_buffer,
-			     bwr.read_size, bwr.read_buffer);
-
-		if (bwr.write_size > 0) {
-			ret = binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed);
-			if (ret < 0) {
-				bwr.read_consumed = 0;
-				if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
-					ret = -EFAULT;
-				goto err;
-			}
-		}
-		if (bwr.read_size > 0) {
-			ret = binder_thread_read(proc, thread, (void __user *)bwr.read_buffer, bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK);
-			if (!list_empty(&proc->todo))
-				wake_up_interruptible(&proc->wait);
-			if (ret < 0) {
-				if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
-					ret = -EFAULT;
-				goto err;
-			}
-		}
-		binder_debug(BINDER_DEBUG_READ_WRITE,
-			     "binder: %d:%d wrote %ld of %ld, read return %ld of %ld\n",
-			     proc->pid, thread->pid, bwr.write_consumed, bwr.write_size,
-			     bwr.read_consumed, bwr.read_size);
-		if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {
-			ret = -EFAULT;
-			goto err;
-		}
-		break;
-	}
-	case BINDER_SET_MAX_THREADS:
-		if (copy_from_user(&proc->max_threads, ubuf, sizeof(proc->max_threads))) {
-			ret = -EINVAL;
-			goto err;
-		}
-		break;
-	case BINDER_SET_CONTEXT_MGR:
-		if (binder_context_mgr_node != NULL) {
-			printk(KERN_ERR "binder: BINDER_SET_CONTEXT_MGR already set\n");
-			ret = -EBUSY;
-			goto err;
-		}
-		if (binder_context_mgr_uid != -1) {
-			if (binder_context_mgr_uid != current->cred->euid) {
-				printk(KERN_ERR "binder: BINDER_SET_"
-				       "CONTEXT_MGR bad uid %d != %d\n",
-				       current->cred->euid,
-				       binder_context_mgr_uid);
-				ret = -EPERM;
-				goto err;
-			}
-		} else
-			binder_context_mgr_uid = current->cred->euid;
-		binder_context_mgr_node = binder_new_node(proc, NULL, NULL);
-		if (binder_context_mgr_node == NULL) {
-			ret = -ENOMEM;
-			goto err;
-		}
-		binder_context_mgr_node->local_weak_refs++;
-		binder_context_mgr_node->local_strong_refs++;
-		binder_context_mgr_node->has_strong_ref = 1;
-		binder_context_mgr_node->has_weak_ref = 1;
-		break;
-	case BINDER_THREAD_EXIT:
-		binder_debug(BINDER_DEBUG_THREADS, "binder: %d:%d exit\n",
-			     proc->pid, thread->pid);
-		binder_free_thread(proc, thread);
-		thread = NULL;
-		break;
-	case BINDER_VERSION:
-		if (size != sizeof(struct binder_version)) {
-			ret = -EINVAL;
-			goto err;
-		}
-		if (put_user(BINDER_CURRENT_PROTOCOL_VERSION, &((struct binder_version *)ubuf)->protocol_version)) {
-			ret = -EINVAL;
-			goto err;
-		}
-		break;
-	default:
-		ret = -EINVAL;
-		goto err;
-	}
-	ret = 0;
-err:
-	if (thread)
-		thread->looper &= ~BINDER_LOOPER_STATE_NEED_RETURN;
-	mutex_unlock(&binder_lock);
-	wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
-	if (ret && ret != -ERESTARTSYS)
-		printk(KERN_INFO "binder: %d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret);
-	return ret;
-}
-
-static void binder_vma_open(struct vm_area_struct *vma)
-{
-	struct binder_proc *proc = vma->vm_private_data;
-	binder_debug(BINDER_DEBUG_OPEN_CLOSE,
-		     "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n",
-		     proc->pid, vma->vm_start, vma->vm_end,
-		     (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
-		     (unsigned long)pgprot_val(vma->vm_page_prot));
-	dump_stack();
-}
-
-static void binder_vma_close(struct vm_area_struct *vma)
-{
-	struct binder_proc *proc = vma->vm_private_data;
-	binder_debug(BINDER_DEBUG_OPEN_CLOSE,
-		     "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n",
-		     proc->pid, vma->vm_start, vma->vm_end,
-		     (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
-		     (unsigned long)pgprot_val(vma->vm_page_prot));
-	proc->vma = NULL;
-	binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES);
-}
-
-static struct vm_operations_struct binder_vm_ops = {
-	.open = binder_vma_open,
-	.close = binder_vma_close,
-};
-
-static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
-{
-	int ret;
-	struct vm_struct *area;
-	struct binder_proc *proc = filp->private_data;
-	const char *failure_string;
-	struct binder_buffer *buffer;
-
-	if ((vma->vm_end - vma->vm_start) > SZ_4M)
-		vma->vm_end = vma->vm_start + SZ_4M;
-
-	binder_debug(BINDER_DEBUG_OPEN_CLOSE,
-		     "binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n",
-		     proc->pid, vma->vm_start, vma->vm_end,
-		     (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
-		     (unsigned long)pgprot_val(vma->vm_page_prot));
-
-	if (vma->vm_flags & FORBIDDEN_MMAP_FLAGS) {
-		ret = -EPERM;
-		failure_string = "bad vm_flags";
-		goto err_bad_arg;
-	}
-	vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE;
-
-	if (proc->buffer) {
-		ret = -EBUSY;
-		failure_string = "already mapped";
-		goto err_already_mapped;
-	}
-
-	area = get_vm_area(vma->vm_end - vma->vm_start, VM_IOREMAP);
-	if (area == NULL) {
-		ret = -ENOMEM;
-		failure_string = "get_vm_area";
-		goto err_get_vm_area_failed;
-	}
-	proc->buffer = area->addr;
-	proc->user_buffer_offset = vma->vm_start - (uintptr_t)proc->buffer;
-
-#ifdef CONFIG_CPU_CACHE_VIPT
-	if (cache_is_vipt_aliasing()) {
-		while (CACHE_COLOUR((vma->vm_start ^ (uint32_t)proc->buffer))) {
-			printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p bad alignment\n", proc->pid, vma->vm_start, vma->vm_end, proc->buffer);
-			vma->vm_start += PAGE_SIZE;
-		}
-	}
-#endif
-	proc->pages = kzalloc(sizeof(proc->pages[0]) * ((vma->vm_end - vma->vm_start) / PAGE_SIZE), GFP_KERNEL);
-	if (proc->pages == NULL) {
-		ret = -ENOMEM;
-		failure_string = "alloc page array";
-		goto err_alloc_pages_failed;
-	}
-	proc->buffer_size = vma->vm_end - vma->vm_start;
-
-	vma->vm_ops = &binder_vm_ops;
-	vma->vm_private_data = proc;
-
-	if (binder_update_page_range(proc, 1, proc->buffer, proc->buffer + PAGE_SIZE, vma)) {
-		ret = -ENOMEM;
-		failure_string = "alloc small buf";
-		goto err_alloc_small_buf_failed;
-	}
-	buffer = proc->buffer;
-	INIT_LIST_HEAD(&proc->buffers);
-	list_add(&buffer->entry, &proc->buffers);
-	buffer->free = 1;
-	binder_insert_free_buffer(proc, buffer);
-	proc->free_async_space = proc->buffer_size / 2;
-	barrier();
-	proc->files = get_files_struct(current);
-	proc->vma = vma;
-
-	/*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n",
-		 proc->pid, vma->vm_start, vma->vm_end, proc->buffer);*/
-	return 0;
-
-err_alloc_small_buf_failed:
-	kfree(proc->pages);
-	proc->pages = NULL;
-err_alloc_pages_failed:
-	vfree(proc->buffer);
-	proc->buffer = NULL;
-err_get_vm_area_failed:
-err_already_mapped:
-err_bad_arg:
-	printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n",
-	       proc->pid, vma->vm_start, vma->vm_end, failure_string, ret);
-	return ret;
-}
-
-static int binder_open(struct inode *nodp, struct file *filp)
-{
-	struct binder_proc *proc;
-
-	binder_debug(BINDER_DEBUG_OPEN_CLOSE, "binder_open: %d:%d\n",
-		     current->group_leader->pid, current->pid);
-
-	proc = kzalloc(sizeof(*proc), GFP_KERNEL);
-	if (proc == NULL)
-		return -ENOMEM;
-	get_task_struct(current);
-	proc->tsk = current;
-	INIT_LIST_HEAD(&proc->todo);
-	init_waitqueue_head(&proc->wait);
-	proc->default_priority = task_nice(current);
-	mutex_lock(&binder_lock);
-	binder_stats_created(BINDER_STAT_PROC);
-	hlist_add_head(&proc->proc_node, &binder_procs);
-	proc->pid = current->group_leader->pid;
-	INIT_LIST_HEAD(&proc->delivered_death);
-	filp->private_data = proc;
-	mutex_unlock(&binder_lock);
-
-	if (binder_proc_dir_entry_proc) {
-		char strbuf[11];
-		snprintf(strbuf, sizeof(strbuf), "%u", proc->pid);
-		remove_proc_entry(strbuf, binder_proc_dir_entry_proc);
-		create_proc_read_entry(strbuf, S_IRUGO,
-				       binder_proc_dir_entry_proc,
-				       binder_read_proc_proc, proc);
-	}
-
-	return 0;
-}
-
-static int binder_flush(struct file *filp, fl_owner_t id)
-{
-	struct binder_proc *proc = filp->private_data;
-
-	binder_defer_work(proc, BINDER_DEFERRED_FLUSH);
-
-	return 0;
-}
-
-static void binder_deferred_flush(struct binder_proc *proc)
-{
-	struct rb_node *n;
-	int wake_count = 0;
-	for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) {
-		struct binder_thread *thread = rb_entry(n, struct binder_thread, rb_node);
-		thread->looper |= BINDER_LOOPER_STATE_NEED_RETURN;
-		if (thread->looper & BINDER_LOOPER_STATE_WAITING) {
-			wake_up_interruptible(&thread->wait);
-			wake_count++;
-		}
-	}
-	wake_up_interruptible_all(&proc->wait);
-
-	binder_debug(BINDER_DEBUG_OPEN_CLOSE,
-		     "binder_flush: %d woke %d threads\n", proc->pid,
-		     wake_count);
-}
-
-static int binder_release(struct inode *nodp, struct file *filp)
-{
-	struct binder_proc *proc = filp->private_data;
-	if (binder_proc_dir_entry_proc) {
-		char strbuf[11];
-		snprintf(strbuf, sizeof(strbuf), "%u", proc->pid);
-		remove_proc_entry(strbuf, binder_proc_dir_entry_proc);
-	}
-
-	binder_defer_work(proc, BINDER_DEFERRED_RELEASE);
-
-	return 0;
-}
-
-static void binder_deferred_release(struct binder_proc *proc)
-{
-	struct hlist_node *pos;
-	struct binder_transaction *t;
-	struct rb_node *n;
-	int threads, nodes, incoming_refs, outgoing_refs, buffers, active_transactions, page_count;
-
-	BUG_ON(proc->vma);
-	BUG_ON(proc->files);
-
-	hlist_del(&proc->proc_node);
-	if (binder_context_mgr_node && binder_context_mgr_node->proc == proc) {
-		binder_debug(BINDER_DEBUG_DEAD_BINDER,
-			     "binder_release: %d context_mgr_node gone\n",
-			     proc->pid);
-		binder_context_mgr_node = NULL;
-	}
-
-	threads = 0;
-	active_transactions = 0;
-	while ((n = rb_first(&proc->threads))) {
-		struct binder_thread *thread = rb_entry(n, struct binder_thread, rb_node);
-		threads++;
-		active_transactions += binder_free_thread(proc, thread);
-	}
-	nodes = 0;
-	incoming_refs = 0;
-	while ((n = rb_first(&proc->nodes))) {
-		struct binder_node *node = rb_entry(n, struct binder_node, rb_node);
-
-		nodes++;
-		rb_erase(&node->rb_node, &proc->nodes);
-		list_del_init(&node->work.entry);
-		if (hlist_empty(&node->refs)) {
-			kfree(node);
-			binder_stats_deleted(BINDER_STAT_NODE);
-		} else {
-			struct binder_ref *ref;
-			int death = 0;
-
-			node->proc = NULL;
-			node->local_strong_refs = 0;
-			node->local_weak_refs = 0;
-			hlist_add_head(&node->dead_node, &binder_dead_nodes);
-
-			hlist_for_each_entry(ref, pos, &node->refs, node_entry) {
-				incoming_refs++;
-				if (ref->death) {
-					death++;
-					if (list_empty(&ref->death->work.entry)) {
-						ref->death->work.type = BINDER_WORK_DEAD_BINDER;
-						list_add_tail(&ref->death->work.entry, &ref->proc->todo);
-						wake_up_interruptible(&ref->proc->wait);
-					} else
-						BUG();
-				}
-			}
-			binder_debug(BINDER_DEBUG_DEAD_BINDER,
-				     "binder: node %d now dead, "
-				     "refs %d, death %d\n", node->debug_id,
-				     incoming_refs, death);
-		}
-	}
-	outgoing_refs = 0;
-	while ((n = rb_first(&proc->refs_by_desc))) {
-		struct binder_ref *ref = rb_entry(n, struct binder_ref,
-						  rb_node_desc);
-		outgoing_refs++;
-		binder_delete_ref(ref);
-	}
-	binder_release_work(&proc->todo);
-	buffers = 0;
-
-	while ((n = rb_first(&proc->allocated_buffers))) {
-		struct binder_buffer *buffer = rb_entry(n, struct binder_buffer,
-							rb_node);
-		t = buffer->transaction;
-		if (t) {
-			t->buffer = NULL;
-			buffer->transaction = NULL;
-			printk(KERN_ERR "binder: release proc %d, "
-			       "transaction %d, not freed\n",
-			       proc->pid, t->debug_id);
-			/*BUG();*/
-		}
-		binder_free_buf(proc, buffer);
-		buffers++;
-	}
-
-	binder_stats_deleted(BINDER_STAT_PROC);
-
-	page_count = 0;
-	if (proc->pages) {
-		int i;
-		for (i = 0; i < proc->buffer_size / PAGE_SIZE; i++) {
-			if (proc->pages[i]) {
-				binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
-					     "binder_release: %d: "
-					     "page %d at %p not freed\n",
-					     proc->pid, i,
-					     proc->buffer + i * PAGE_SIZE);
-				__free_page(proc->pages[i]);
-				page_count++;
-			}
-		}
-		kfree(proc->pages);
-		vfree(proc->buffer);
-	}
-
-	put_task_struct(proc->tsk);
-
-	binder_debug(BINDER_DEBUG_OPEN_CLOSE,
-		     "binder_release: %d threads %d, nodes %d (ref %d), "
-		     "refs %d, active transactions %d, buffers %d, "
-		     "pages %d\n",
-		     proc->pid, threads, nodes, incoming_refs, outgoing_refs,
-		     active_transactions, buffers, page_count);
-
-	kfree(proc);
-}
-
-static void binder_deferred_func(struct work_struct *work)
-{
-	struct binder_proc *proc;
-	struct files_struct *files;
-
-	int defer;
-	do {
-		mutex_lock(&binder_lock);
-		mutex_lock(&binder_deferred_lock);
-		if (!hlist_empty(&binder_deferred_list)) {
-			proc = hlist_entry(binder_deferred_list.first,
-					struct binder_proc, deferred_work_node);
-			hlist_del_init(&proc->deferred_work_node);
-			defer = proc->deferred_work;
-			proc->deferred_work = 0;
-		} else {
-			proc = NULL;
-			defer = 0;
-		}
-		mutex_unlock(&binder_deferred_lock);
-
-		files = NULL;
-		if (defer & BINDER_DEFERRED_PUT_FILES) {
-			files = proc->files;
-			if (files)
-				proc->files = NULL;
-		}
-
-		if (defer & BINDER_DEFERRED_FLUSH)
-			binder_deferred_flush(proc);
-
-		if (defer & BINDER_DEFERRED_RELEASE)
-			binder_deferred_release(proc); /* frees proc */
-
-		mutex_unlock(&binder_lock);
-		if (files)
-			put_files_struct(files);
-	} while (proc);
-}
-static DECLARE_WORK(binder_deferred_work, binder_deferred_func);
-
-static void
-binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer)
-{
-	mutex_lock(&binder_deferred_lock);
-	proc->deferred_work |= defer;
-	if (hlist_unhashed(&proc->deferred_work_node)) {
-		hlist_add_head(&proc->deferred_work_node,
-				&binder_deferred_list);
-		schedule_work(&binder_deferred_work);
-	}
-	mutex_unlock(&binder_deferred_lock);
-}
-
-static char *print_binder_transaction(char *buf, char *end, const char *prefix,
-				      struct binder_transaction *t)
-{
-	buf += snprintf(buf, end - buf,
-			"%s %d: %p from %d:%d to %d:%d code %x "
-			"flags %x pri %ld r%d",
-			prefix, t->debug_id, t,
-			t->from ? t->from->proc->pid : 0,
-			t->from ? t->from->pid : 0,
-			t->to_proc ? t->to_proc->pid : 0,
-			t->to_thread ? t->to_thread->pid : 0,
-			t->code, t->flags, t->priority, t->need_reply);
-	if (buf >= end)
-		return buf;
-	if (t->buffer == NULL) {
-		buf += snprintf(buf, end - buf, " buffer free\n");
-		return buf;
-	}
-	if (t->buffer->target_node) {
-		buf += snprintf(buf, end - buf, " node %d",
-				t->buffer->target_node->debug_id);
-		if (buf >= end)
-			return buf;
-	}
-	buf += snprintf(buf, end - buf, " size %zd:%zd data %p\n",
-			t->buffer->data_size, t->buffer->offsets_size,
-			t->buffer->data);
-	return buf;
-}
-
-static char *print_binder_buffer(char *buf, char *end, const char *prefix,
-				 struct binder_buffer *buffer)
-{
-	buf += snprintf(buf, end - buf, "%s %d: %p size %zd:%zd %s\n",
-			prefix, buffer->debug_id, buffer->data,
-			buffer->data_size, buffer->offsets_size,
-			buffer->transaction ? "active" : "delivered");
-	return buf;
-}
-
-static char *print_binder_work(char *buf, char *end, const char *prefix,
-			       const char *transaction_prefix,
-			       struct binder_work *w)
-{
-	struct binder_node *node;
-	struct binder_transaction *t;
-
-	switch (w->type) {
-	case BINDER_WORK_TRANSACTION:
-		t = container_of(w, struct binder_transaction, work);
-		buf = print_binder_transaction(buf, end, transaction_prefix, t);
-		break;
-	case BINDER_WORK_TRANSACTION_COMPLETE:
-		buf += snprintf(buf, end - buf,
-				"%stransaction complete\n", prefix);
-		break;
-	case BINDER_WORK_NODE:
-		node = container_of(w, struct binder_node, work);
-		buf += snprintf(buf, end - buf, "%snode work %d: u%p c%p\n",
-				prefix, node->debug_id, node->ptr,
-				node->cookie);
-		break;
-	case BINDER_WORK_DEAD_BINDER:
-		buf += snprintf(buf, end - buf, "%shas dead binder\n", prefix);
-		break;
-	case BINDER_WORK_DEAD_BINDER_AND_CLEAR:
-		buf += snprintf(buf, end - buf,
-				"%shas cleared dead binder\n", prefix);
-		break;
-	case BINDER_WORK_CLEAR_DEATH_NOTIFICATION:
-		buf += snprintf(buf, end - buf,
-				"%shas cleared death notification\n", prefix);
-		break;
-	default:
-		buf += snprintf(buf, end - buf, "%sunknown work: type %d\n",
-				prefix, w->type);
-		break;
-	}
-	return buf;
-}
-
-static char *print_binder_thread(char *buf, char *end,
-				 struct binder_thread *thread,
-				 int print_always)
-{
-	struct binder_transaction *t;
-	struct binder_work *w;
-	char *start_buf = buf;
-	char *header_buf;
-
-	buf += snprintf(buf, end - buf, "  thread %d: l %02x\n",
-			thread->pid, thread->looper);
-	header_buf = buf;
-	t = thread->transaction_stack;
-	while (t) {
-		if (buf >= end)
-			break;
-		if (t->from == thread) {
-			buf = print_binder_transaction(buf, end,
-						"    outgoing transaction", t);
-			t = t->from_parent;
-		} else if (t->to_thread == thread) {
-			buf = print_binder_transaction(buf, end,
-						"    incoming transaction", t);
-			t = t->to_parent;
-		} else {
-			buf = print_binder_transaction(buf, end,
-						"    bad transaction", t);
-			t = NULL;
-		}
-	}
-	list_for_each_entry(w, &thread->todo, entry) {
-		if (buf >= end)
-			break;
-		buf = print_binder_work(buf, end, "    ",
-					"    pending transaction", w);
-	}
-	if (!print_always && buf == header_buf)
-		buf = start_buf;
-	return buf;
-}
-
-static char *print_binder_node(char *buf, char *end, struct binder_node *node)
-{
-	struct binder_ref *ref;
-	struct hlist_node *pos;
-	struct binder_work *w;
-	int count;
-
-	count = 0;
-	hlist_for_each_entry(ref, pos, &node->refs, node_entry)
-		count++;
-
-	buf += snprintf(buf, end - buf,
-			"  node %d: u%p c%p hs %d hw %d ls %d lw %d "
-			"is %d iw %d",
-			node->debug_id, node->ptr, node->cookie,
-			node->has_strong_ref, node->has_weak_ref,
-			node->local_strong_refs, node->local_weak_refs,
-			node->internal_strong_refs, count);
-	if (buf >= end)
-		return buf;
-	if (count) {
-		buf += snprintf(buf, end - buf, " proc");
-		if (buf >= end)
-			return buf;
-		hlist_for_each_entry(ref, pos, &node->refs, node_entry) {
-			buf += snprintf(buf, end - buf, " %d", ref->proc->pid);
-			if (buf >= end)
-				return buf;
-		}
-	}
-	buf += snprintf(buf, end - buf, "\n");
-	list_for_each_entry(w, &node->async_todo, entry) {
-		if (buf >= end)
-			break;
-		buf = print_binder_work(buf, end, "    ",
-					"    pending async transaction", w);
-	}
-	return buf;
-}
-
-static char *print_binder_ref(char *buf, char *end, struct binder_ref *ref)
-{
-	buf += snprintf(buf, end - buf,
-			"  ref %d: desc %d %snode %d s %d w %d d %p\n",
-			ref->debug_id, ref->desc,
-			ref->node->proc ? "" : "dead ", ref->node->debug_id,
-			ref->strong, ref->weak, ref->death);
-	return buf;
-}
-
-static char *print_binder_proc(char *buf, char *end,
-			       struct binder_proc *proc, int print_all)
-{
-	struct binder_work *w;
-	struct rb_node *n;
-	char *start_buf = buf;
-	char *header_buf;
-
-	buf += snprintf(buf, end - buf, "proc %d\n", proc->pid);
-	header_buf = buf;
-
-	for (n = rb_first(&proc->threads);
-	     n != NULL && buf < end;
-	     n = rb_next(n))
-		buf = print_binder_thread(buf, end,
-					  rb_entry(n, struct binder_thread,
-						   rb_node), print_all);
-	for (n = rb_first(&proc->nodes);
-	     n != NULL && buf < end;
-	     n = rb_next(n)) {
-		struct binder_node *node = rb_entry(n, struct binder_node,
-						    rb_node);
-		if (print_all || node->has_async_transaction)
-			buf = print_binder_node(buf, end, node);
-	}
-	if (print_all) {
-		for (n = rb_first(&proc->refs_by_desc);
-		     n != NULL && buf < end;
-		     n = rb_next(n))
-			buf = print_binder_ref(buf, end,
-					       rb_entry(n, struct binder_ref,
-							rb_node_desc));
-	}
-	for (n = rb_first(&proc->allocated_buffers);
-	     n != NULL && buf < end;
-	     n = rb_next(n))
-		buf = print_binder_buffer(buf, end, "  buffer",
-					  rb_entry(n, struct binder_buffer,
-						   rb_node));
-	list_for_each_entry(w, &proc->todo, entry) {
-		if (buf >= end)
-			break;
-		buf = print_binder_work(buf, end, "  ",
-					"  pending transaction", w);
-	}
-	list_for_each_entry(w, &proc->delivered_death, entry) {
-		if (buf >= end)
-			break;
-		buf += snprintf(buf, end - buf,
-				"  has delivered dead binder\n");
-		break;
-	}
-	if (!print_all && buf == header_buf)
-		buf = start_buf;
-	return buf;
-}
-
-static const char *binder_return_strings[] = {
-	"BR_ERROR",
-	"BR_OK",
-	"BR_TRANSACTION",
-	"BR_REPLY",
-	"BR_ACQUIRE_RESULT",
-	"BR_DEAD_REPLY",
-	"BR_TRANSACTION_COMPLETE",
-	"BR_INCREFS",
-	"BR_ACQUIRE",
-	"BR_RELEASE",
-	"BR_DECREFS",
-	"BR_ATTEMPT_ACQUIRE",
-	"BR_NOOP",
-	"BR_SPAWN_LOOPER",
-	"BR_FINISHED",
-	"BR_DEAD_BINDER",
-	"BR_CLEAR_DEATH_NOTIFICATION_DONE",
-	"BR_FAILED_REPLY"
-};
-
-static const char *binder_command_strings[] = {
-	"BC_TRANSACTION",
-	"BC_REPLY",
-	"BC_ACQUIRE_RESULT",
-	"BC_FREE_BUFFER",
-	"BC_INCREFS",
-	"BC_ACQUIRE",
-	"BC_RELEASE",
-	"BC_DECREFS",
-	"BC_INCREFS_DONE",
-	"BC_ACQUIRE_DONE",
-	"BC_ATTEMPT_ACQUIRE",
-	"BC_REGISTER_LOOPER",
-	"BC_ENTER_LOOPER",
-	"BC_EXIT_LOOPER",
-	"BC_REQUEST_DEATH_NOTIFICATION",
-	"BC_CLEAR_DEATH_NOTIFICATION",
-	"BC_DEAD_BINDER_DONE"
-};
-
-static const char *binder_objstat_strings[] = {
-	"proc",
-	"thread",
-	"node",
-	"ref",
-	"death",
-	"transaction",
-	"transaction_complete"
-};
-
-static char *print_binder_stats(char *buf, char *end, const char *prefix,
-				struct binder_stats *stats)
-{
-	int i;
-
-	BUILD_BUG_ON(ARRAY_SIZE(stats->bc) !=
-			ARRAY_SIZE(binder_command_strings));
-	for (i = 0; i < ARRAY_SIZE(stats->bc); i++) {
-		if (stats->bc[i])
-			buf += snprintf(buf, end - buf, "%s%s: %d\n", prefix,
-					binder_command_strings[i],
-					stats->bc[i]);
-		if (buf >= end)
-			return buf;
-	}
-
-	BUILD_BUG_ON(ARRAY_SIZE(stats->br) !=
-			ARRAY_SIZE(binder_return_strings));
-	for (i = 0; i < ARRAY_SIZE(stats->br); i++) {
-		if (stats->br[i])
-			buf += snprintf(buf, end - buf, "%s%s: %d\n", prefix,
-					binder_return_strings[i], stats->br[i]);
-		if (buf >= end)
-			return buf;
-	}
-
-	BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) !=
-			ARRAY_SIZE(binder_objstat_strings));
-	BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) !=
-			ARRAY_SIZE(stats->obj_deleted));
-	for (i = 0; i < ARRAY_SIZE(stats->obj_created); i++) {
-		if (stats->obj_created[i] || stats->obj_deleted[i])
-			buf += snprintf(buf, end - buf,
-					"%s%s: active %d total %d\n", prefix,
-					binder_objstat_strings[i],
-					stats->obj_created[i] -
-						stats->obj_deleted[i],
-					stats->obj_created[i]);
-		if (buf >= end)
-			return buf;
-	}
-	return buf;
-}
-
-static char *print_binder_proc_stats(char *buf, char *end,
-				     struct binder_proc *proc)
-{
-	struct binder_work *w;
-	struct rb_node *n;
-	int count, strong, weak;
-
-	buf += snprintf(buf, end - buf, "proc %d\n", proc->pid);
-	if (buf >= end)
-		return buf;
-	count = 0;
-	for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n))
-		count++;
-	buf += snprintf(buf, end - buf, "  threads: %d\n", count);
-	if (buf >= end)
-		return buf;
-	buf += snprintf(buf, end - buf, "  requested threads: %d+%d/%d\n"
-			"  ready threads %d\n"
-			"  free async space %zd\n", proc->requested_threads,
-			proc->requested_threads_started, proc->max_threads,
-			proc->ready_threads, proc->free_async_space);
-	if (buf >= end)
-		return buf;
-	count = 0;
-	for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n))
-		count++;
-	buf += snprintf(buf, end - buf, "  nodes: %d\n", count);
-	if (buf >= end)
-		return buf;
-	count = 0;
-	strong = 0;
-	weak = 0;
-	for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) {
-		struct binder_ref *ref = rb_entry(n, struct binder_ref,
-						  rb_node_desc);
-		count++;
-		strong += ref->strong;
-		weak += ref->weak;
-	}
-	buf += snprintf(buf, end - buf, "  refs: %d s %d w %d\n",
-			count, strong, weak);
-	if (buf >= end)
-		return buf;
-
-	count = 0;
-	for (n = rb_first(&proc->allocated_buffers); n != NULL; n = rb_next(n))
-		count++;
-	buf += snprintf(buf, end - buf, "  buffers: %d\n", count);
-	if (buf >= end)
-		return buf;
-
-	count = 0;
-	list_for_each_entry(w, &proc->todo, entry) {
-		switch (w->type) {
-		case BINDER_WORK_TRANSACTION:
-			count++;
-			break;
-		default:
-			break;
-		}
-	}
-	buf += snprintf(buf, end - buf, "  pending transactions: %d\n", count);
-	if (buf >= end)
-		return buf;
-
-	buf = print_binder_stats(buf, end, "  ", &proc->stats);
-
-	return buf;
-}
-
-
-static int binder_read_proc_state(char *page, char **start, off_t off,
-				  int count, int *eof, void *data)
-{
-	struct binder_proc *proc;
-	struct hlist_node *pos;
-	struct binder_node *node;
-	int len = 0;
-	char *buf = page;
-	char *end = page + PAGE_SIZE;
-	int do_lock = !binder_debug_no_lock;
-
-	if (off)
-		return 0;
-
-	if (do_lock)
-		mutex_lock(&binder_lock);
-
-	buf += snprintf(buf, end - buf, "binder state:\n");
-
-	if (!hlist_empty(&binder_dead_nodes))
-		buf += snprintf(buf, end - buf, "dead nodes:\n");
-	hlist_for_each_entry(node, pos, &binder_dead_nodes, dead_node) {
-		if (buf >= end)
-			break;
-		buf = print_binder_node(buf, end, node);
-	}
-
-	hlist_for_each_entry(proc, pos, &binder_procs, proc_node) {
-		if (buf >= end)
-			break;
-		buf = print_binder_proc(buf, end, proc, 1);
-	}
-	if (do_lock)
-		mutex_unlock(&binder_lock);
-	if (buf > page + PAGE_SIZE)
-		buf = page + PAGE_SIZE;
-
-	*start = page + off;
-
-	len = buf - page;
-	if (len > off)
-		len -= off;
-	else
-		len = 0;
-
-	return len < count ? len  : count;
-}
-
-static int binder_read_proc_stats(char *page, char **start, off_t off,
-				  int count, int *eof, void *data)
-{
-	struct binder_proc *proc;
-	struct hlist_node *pos;
-	int len = 0;
-	char *p = page;
-	int do_lock = !binder_debug_no_lock;
-
-	if (off)
-		return 0;
-
-	if (do_lock)
-		mutex_lock(&binder_lock);
-
-	p += snprintf(p, PAGE_SIZE, "binder stats:\n");
-
-	p = print_binder_stats(p, page + PAGE_SIZE, "", &binder_stats);
-
-	hlist_for_each_entry(proc, pos, &binder_procs, proc_node) {
-		if (p >= page + PAGE_SIZE)
-			break;
-		p = print_binder_proc_stats(p, page + PAGE_SIZE, proc);
-	}
-	if (do_lock)
-		mutex_unlock(&binder_lock);
-	if (p > page + PAGE_SIZE)
-		p = page + PAGE_SIZE;
-
-	*start = page + off;
-
-	len = p - page;
-	if (len > off)
-		len -= off;
-	else
-		len = 0;
-
-	return len < count ? len  : count;
-}
-
-static int binder_read_proc_transactions(char *page, char **start, off_t off,
-					 int count, int *eof, void *data)
-{
-	struct binder_proc *proc;
-	struct hlist_node *pos;
-	int len = 0;
-	char *buf = page;
-	char *end = page + PAGE_SIZE;
-	int do_lock = !binder_debug_no_lock;
-
-	if (off)
-		return 0;
-
-	if (do_lock)
-		mutex_lock(&binder_lock);
-
-	buf += snprintf(buf, end - buf, "binder transactions:\n");
-	hlist_for_each_entry(proc, pos, &binder_procs, proc_node) {
-		if (buf >= end)
-			break;
-		buf = print_binder_proc(buf, end, proc, 0);
-	}
-	if (do_lock)
-		mutex_unlock(&binder_lock);
-	if (buf > page + PAGE_SIZE)
-		buf = page + PAGE_SIZE;
-
-	*start = page + off;
-
-	len = buf - page;
-	if (len > off)
-		len -= off;
-	else
-		len = 0;
-
-	return len < count ? len  : count;
-}
-
-static int binder_read_proc_proc(char *page, char **start, off_t off,
-				 int count, int *eof, void *data)
-{
-	struct binder_proc *proc = data;
-	int len = 0;
-	char *p = page;
-	int do_lock = !binder_debug_no_lock;
-
-	if (off)
-		return 0;
-
-	if (do_lock)
-		mutex_lock(&binder_lock);
-	p += snprintf(p, PAGE_SIZE, "binder proc state:\n");
-	p = print_binder_proc(p, page + PAGE_SIZE, proc, 1);
-	if (do_lock)
-		mutex_unlock(&binder_lock);
-
-	if (p > page + PAGE_SIZE)
-		p = page + PAGE_SIZE;
-	*start = page + off;
-
-	len = p - page;
-	if (len > off)
-		len -= off;
-	else
-		len = 0;
-
-	return len < count ? len  : count;
-}
-
-static char *print_binder_transaction_log_entry(char *buf, char *end,
-					struct binder_transaction_log_entry *e)
-{
-	buf += snprintf(buf, end - buf,
-			"%d: %s from %d:%d to %d:%d node %d handle %d "
-			"size %d:%d\n",
-			e->debug_id, (e->call_type == 2) ? "reply" :
-			((e->call_type == 1) ? "async" : "call "), e->from_proc,
-			e->from_thread, e->to_proc, e->to_thread, e->to_node,
-			e->target_handle, e->data_size, e->offsets_size);
-	return buf;
-}
-
-static int binder_read_proc_transaction_log(
-	char *page, char **start, off_t off, int count, int *eof, void *data)
-{
-	struct binder_transaction_log *log = data;
-	int len = 0;
-	int i;
-	char *buf = page;
-	char *end = page + PAGE_SIZE;
-
-	if (off)
-		return 0;
-
-	if (log->full) {
-		for (i = log->next; i < ARRAY_SIZE(log->entry); i++) {
-			if (buf >= end)
-				break;
-			buf = print_binder_transaction_log_entry(buf, end,
-								&log->entry[i]);
-		}
-	}
-	for (i = 0; i < log->next; i++) {
-		if (buf >= end)
-			break;
-		buf = print_binder_transaction_log_entry(buf, end,
-							 &log->entry[i]);
-	}
-
-	*start = page + off;
-
-	len = buf - page;
-	if (len > off)
-		len -= off;
-	else
-		len = 0;
-
-	return len < count ? len  : count;
-}
-
-static const struct file_operations binder_fops = {
-	.owner = THIS_MODULE,
-	.poll = binder_poll,
-	.unlocked_ioctl = binder_ioctl,
-	.mmap = binder_mmap,
-	.open = binder_open,
-	.flush = binder_flush,
-	.release = binder_release,
-};
-
-static struct miscdevice binder_miscdev = {
-	.minor = MISC_DYNAMIC_MINOR,
-	.name = "binder",
-	.fops = &binder_fops
-};
-
-static int __init binder_init(void)
-{
-	int ret;
-
-	binder_proc_dir_entry_root = proc_mkdir("binder", NULL);
-	if (binder_proc_dir_entry_root)
-		binder_proc_dir_entry_proc = proc_mkdir("proc",
-						binder_proc_dir_entry_root);
-	ret = misc_register(&binder_miscdev);
-	if (binder_proc_dir_entry_root) {
-		create_proc_read_entry("state",
-				       S_IRUGO,
-				       binder_proc_dir_entry_root,
-				       binder_read_proc_state,
-				       NULL);
-		create_proc_read_entry("stats",
-				       S_IRUGO,
-				       binder_proc_dir_entry_root,
-				       binder_read_proc_stats,
-				       NULL);
-		create_proc_read_entry("transactions",
-				       S_IRUGO,
-				       binder_proc_dir_entry_root,
-				       binder_read_proc_transactions,
-				       NULL);
-		create_proc_read_entry("transaction_log",
-				       S_IRUGO,
-				       binder_proc_dir_entry_root,
-				       binder_read_proc_transaction_log,
-				       &binder_transaction_log);
-		create_proc_read_entry("failed_transaction_log",
-				       S_IRUGO,
-				       binder_proc_dir_entry_root,
-				       binder_read_proc_transaction_log,
-				       &binder_transaction_log_failed);
-	}
-	return ret;
-}
-
-device_initcall(binder_init);
-
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/android/binder.h b/drivers/staging/android/binder.h
deleted file mode 100644
index 863ae1a..0000000
--- a/drivers/staging/android/binder.h
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- * Copyright (C) 2008 Google, Inc.
- *
- * Based on, but no longer compatible with, the original
- * OpenBinder.org binder driver interface, which is:
- *
- * Copyright (c) 2005 Palmsource, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#ifndef _LINUX_BINDER_H
-#define _LINUX_BINDER_H
-
-#include <linux/ioctl.h>
-
-#define B_PACK_CHARS(c1, c2, c3, c4) \
-	((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4))
-#define B_TYPE_LARGE 0x85
-
-enum {
-	BINDER_TYPE_BINDER	= B_PACK_CHARS('s', 'b', '*', B_TYPE_LARGE),
-	BINDER_TYPE_WEAK_BINDER	= B_PACK_CHARS('w', 'b', '*', B_TYPE_LARGE),
-	BINDER_TYPE_HANDLE	= B_PACK_CHARS('s', 'h', '*', B_TYPE_LARGE),
-	BINDER_TYPE_WEAK_HANDLE	= B_PACK_CHARS('w', 'h', '*', B_TYPE_LARGE),
-	BINDER_TYPE_FD		= B_PACK_CHARS('f', 'd', '*', B_TYPE_LARGE),
-};
-
-enum {
-	FLAT_BINDER_FLAG_PRIORITY_MASK = 0xff,
-	FLAT_BINDER_FLAG_ACCEPTS_FDS = 0x100,
-};
-
-/*
- * This is the flattened representation of a Binder object for transfer
- * between processes.  The 'offsets' supplied as part of a binder transaction
- * contains offsets into the data where these structures occur.  The Binder
- * driver takes care of re-writing the structure type and data as it moves
- * between processes.
- */
-struct flat_binder_object {
-	/* 8 bytes for large_flat_header. */
-	unsigned long		type;
-	unsigned long		flags;
-
-	/* 8 bytes of data. */
-	union {
-		void		*binder;	/* local object */
-		signed long	handle;		/* remote object */
-	};
-
-	/* extra data associated with local object */
-	void			*cookie;
-};
-
-/*
- * On 64-bit platforms where user code may run in 32-bits the driver must
- * translate the buffer (and local binder) addresses apropriately.
- */
-
-struct binder_write_read {
-	signed long	write_size;	/* bytes to write */
-	signed long	write_consumed;	/* bytes consumed by driver */
-	unsigned long	write_buffer;
-	signed long	read_size;	/* bytes to read */
-	signed long	read_consumed;	/* bytes consumed by driver */
-	unsigned long	read_buffer;
-};
-
-/* Use with BINDER_VERSION, driver fills in fields. */
-struct binder_version {
-	/* driver protocol version -- increment with incompatible change */
-	signed long	protocol_version;
-};
-
-/* This is the current protocol version. */
-#define BINDER_CURRENT_PROTOCOL_VERSION 7
-
-#define BINDER_WRITE_READ   		_IOWR('b', 1, struct binder_write_read)
-#define	BINDER_SET_IDLE_TIMEOUT		_IOW('b', 3, int64_t)
-#define	BINDER_SET_MAX_THREADS		_IOW('b', 5, size_t)
-#define	BINDER_SET_IDLE_PRIORITY	_IOW('b', 6, int)
-#define	BINDER_SET_CONTEXT_MGR		_IOW('b', 7, int)
-#define	BINDER_THREAD_EXIT		_IOW('b', 8, int)
-#define BINDER_VERSION			_IOWR('b', 9, struct binder_version)
-
-/*
- * NOTE: Two special error codes you should check for when calling
- * in to the driver are:
- *
- * EINTR -- The operation has been interupted.  This should be
- * handled by retrying the ioctl() until a different error code
- * is returned.
- *
- * ECONNREFUSED -- The driver is no longer accepting operations
- * from your process.  That is, the process is being destroyed.
- * You should handle this by exiting from your process.  Note
- * that once this error code is returned, all further calls to
- * the driver from any thread will return this same code.
- */
-
-enum transaction_flags {
-	TF_ONE_WAY	= 0x01,	/* this is a one-way call: async, no return */
-	TF_ROOT_OBJECT	= 0x04,	/* contents are the component's root object */
-	TF_STATUS_CODE	= 0x08,	/* contents are a 32-bit status code */
-	TF_ACCEPT_FDS	= 0x10,	/* allow replies with file descriptors */
-};
-
-struct binder_transaction_data {
-	/* The first two are only used for bcTRANSACTION and brTRANSACTION,
-	 * identifying the target and contents of the transaction.
-	 */
-	union {
-		size_t	handle;	/* target descriptor of command transaction */
-		void	*ptr;	/* target descriptor of return transaction */
-	} target;
-	void		*cookie;	/* target object cookie */
-	unsigned int	code;		/* transaction command */
-
-	/* General information about the transaction. */
-	unsigned int	flags;
-	pid_t		sender_pid;
-	uid_t		sender_euid;
-	size_t		data_size;	/* number of bytes of data */
-	size_t		offsets_size;	/* number of bytes of offsets */
-
-	/* If this transaction is inline, the data immediately
-	 * follows here; otherwise, it ends with a pointer to
-	 * the data buffer.
-	 */
-	union {
-		struct {
-			/* transaction data */
-			const void	*buffer;
-			/* offsets from buffer to flat_binder_object structs */
-			const void	*offsets;
-		} ptr;
-		uint8_t	buf[8];
-	} data;
-};
-
-struct binder_ptr_cookie {
-	void *ptr;
-	void *cookie;
-};
-
-struct binder_pri_desc {
-	int priority;
-	int desc;
-};
-
-struct binder_pri_ptr_cookie {
-	int priority;
-	void *ptr;
-	void *cookie;
-};
-
-enum BinderDriverReturnProtocol {
-	BR_ERROR = _IOR('r', 0, int),
-	/*
-	 * int: error code
-	 */
-
-	BR_OK = _IO('r', 1),
-	/* No parameters! */
-
-	BR_TRANSACTION = _IOR('r', 2, struct binder_transaction_data),
-	BR_REPLY = _IOR('r', 3, struct binder_transaction_data),
-	/*
-	 * binder_transaction_data: the received command.
-	 */
-
-	BR_ACQUIRE_RESULT = _IOR('r', 4, int),
-	/*
-	 * not currently supported
-	 * int: 0 if the last bcATTEMPT_ACQUIRE was not successful.
-	 * Else the remote object has acquired a primary reference.
-	 */
-
-	BR_DEAD_REPLY = _IO('r', 5),
-	/*
-	 * The target of the last transaction (either a bcTRANSACTION or
-	 * a bcATTEMPT_ACQUIRE) is no longer with us.  No parameters.
-	 */
-
-	BR_TRANSACTION_COMPLETE = _IO('r', 6),
-	/*
-	 * No parameters... always refers to the last transaction requested
-	 * (including replies).  Note that this will be sent even for
-	 * asynchronous transactions.
-	 */
-
-	BR_INCREFS = _IOR('r', 7, struct binder_ptr_cookie),
-	BR_ACQUIRE = _IOR('r', 8, struct binder_ptr_cookie),
-	BR_RELEASE = _IOR('r', 9, struct binder_ptr_cookie),
-	BR_DECREFS = _IOR('r', 10, struct binder_ptr_cookie),
-	/*
-	 * void *:	ptr to binder
-	 * void *: cookie for binder
-	 */
-
-	BR_ATTEMPT_ACQUIRE = _IOR('r', 11, struct binder_pri_ptr_cookie),
-	/*
-	 * not currently supported
-	 * int:	priority
-	 * void *: ptr to binder
-	 * void *: cookie for binder
-	 */
-
-	BR_NOOP = _IO('r', 12),
-	/*
-	 * No parameters.  Do nothing and examine the next command.  It exists
-	 * primarily so that we can replace it with a BR_SPAWN_LOOPER command.
-	 */
-
-	BR_SPAWN_LOOPER = _IO('r', 13),
-	/*
-	 * No parameters.  The driver has determined that a process has no
-	 * threads waiting to service incomming transactions.  When a process
-	 * receives this command, it must spawn a new service thread and
-	 * register it via bcENTER_LOOPER.
-	 */
-
-	BR_FINISHED = _IO('r', 14),
-	/*
-	 * not currently supported
-	 * stop threadpool thread
-	 */
-
-	BR_DEAD_BINDER = _IOR('r', 15, void *),
-	/*
-	 * void *: cookie
-	 */
-	BR_CLEAR_DEATH_NOTIFICATION_DONE = _IOR('r', 16, void *),
-	/*
-	 * void *: cookie
-	 */
-
-	BR_FAILED_REPLY = _IO('r', 17),
-	/*
-	 * The the last transaction (either a bcTRANSACTION or
-	 * a bcATTEMPT_ACQUIRE) failed (e.g. out of memory).  No parameters.
-	 */
-};
-
-enum BinderDriverCommandProtocol {
-	BC_TRANSACTION = _IOW('c', 0, struct binder_transaction_data),
-	BC_REPLY = _IOW('c', 1, struct binder_transaction_data),
-	/*
-	 * binder_transaction_data: the sent command.
-	 */
-
-	BC_ACQUIRE_RESULT = _IOW('c', 2, int),
-	/*
-	 * not currently supported
-	 * int:  0 if the last BR_ATTEMPT_ACQUIRE was not successful.
-	 * Else you have acquired a primary reference on the object.
-	 */
-
-	BC_FREE_BUFFER = _IOW('c', 3, int),
-	/*
-	 * void *: ptr to transaction data received on a read
-	 */
-
-	BC_INCREFS = _IOW('c', 4, int),
-	BC_ACQUIRE = _IOW('c', 5, int),
-	BC_RELEASE = _IOW('c', 6, int),
-	BC_DECREFS = _IOW('c', 7, int),
-	/*
-	 * int:	descriptor
-	 */
-
-	BC_INCREFS_DONE = _IOW('c', 8, struct binder_ptr_cookie),
-	BC_ACQUIRE_DONE = _IOW('c', 9, struct binder_ptr_cookie),
-	/*
-	 * void *: ptr to binder
-	 * void *: cookie for binder
-	 */
-
-	BC_ATTEMPT_ACQUIRE = _IOW('c', 10, struct binder_pri_desc),
-	/*
-	 * not currently supported
-	 * int: priority
-	 * int: descriptor
-	 */
-
-	BC_REGISTER_LOOPER = _IO('c', 11),
-	/*
-	 * No parameters.
-	 * Register a spawned looper thread with the device.
-	 */
-
-	BC_ENTER_LOOPER = _IO('c', 12),
-	BC_EXIT_LOOPER = _IO('c', 13),
-	/*
-	 * No parameters.
-	 * These two commands are sent as an application-level thread
-	 * enters and exits the binder loop, respectively.  They are
-	 * used so the binder can have an accurate count of the number
-	 * of looping threads it has available.
-	 */
-
-	BC_REQUEST_DEATH_NOTIFICATION = _IOW('c', 14, struct binder_ptr_cookie),
-	/*
-	 * void *: ptr to binder
-	 * void *: cookie
-	 */
-
-	BC_CLEAR_DEATH_NOTIFICATION = _IOW('c', 15, struct binder_ptr_cookie),
-	/*
-	 * void *: ptr to binder
-	 * void *: cookie
-	 */
-
-	BC_DEAD_BINDER_DONE = _IOW('c', 16, void *),
-	/*
-	 * void *: cookie
-	 */
-};
-
-#endif /* _LINUX_BINDER_H */
-
diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c
deleted file mode 100644
index 6c10b45..0000000
--- a/drivers/staging/android/logger.c
+++ /dev/null
@@ -1,607 +0,0 @@
-/*
- * drivers/misc/logger.c
- *
- * A Logging Subsystem
- *
- * Copyright (C) 2007-2008 Google, Inc.
- *
- * Robert Love <rlove@google.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- */
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/miscdevice.h>
-#include <linux/uaccess.h>
-#include <linux/poll.h>
-#include <linux/time.h>
-#include "logger.h"
-
-#include <asm/ioctls.h>
-
-/*
- * struct logger_log - represents a specific log, such as 'main' or 'radio'
- *
- * This structure lives from module insertion until module removal, so it does
- * not need additional reference counting. The structure is protected by the
- * mutex 'mutex'.
- */
-struct logger_log {
-	unsigned char 		*buffer;/* the ring buffer itself */
-	struct miscdevice	misc;	/* misc device representing the log */
-	wait_queue_head_t	wq;	/* wait queue for readers */
-	struct list_head	readers; /* this log's readers */
-	struct mutex		mutex;	/* mutex protecting buffer */
-	size_t			w_off;	/* current write head offset */
-	size_t			head;	/* new readers start here */
-	size_t			size;	/* size of the log */
-};
-
-/*
- * struct logger_reader - a logging device open for reading
- *
- * This object lives from open to release, so we don't need additional
- * reference counting. The structure is protected by log->mutex.
- */
-struct logger_reader {
-	struct logger_log	*log;	/* associated log */
-	struct list_head	list;	/* entry in logger_log's list */
-	size_t			r_off;	/* current read head offset */
-};
-
-/* logger_offset - returns index 'n' into the log via (optimized) modulus */
-#define logger_offset(n)	((n) & (log->size - 1))
-
-/*
- * file_get_log - Given a file structure, return the associated log
- *
- * This isn't aesthetic. We have several goals:
- *
- * 	1) Need to quickly obtain the associated log during an I/O operation
- * 	2) Readers need to maintain state (logger_reader)
- * 	3) Writers need to be very fast (open() should be a near no-op)
- *
- * In the reader case, we can trivially go file->logger_reader->logger_log.
- * For a writer, we don't want to maintain a logger_reader, so we just go
- * file->logger_log. Thus what file->private_data points at depends on whether
- * or not the file was opened for reading. This function hides that dirtiness.
- */
-static inline struct logger_log *file_get_log(struct file *file)
-{
-	if (file->f_mode & FMODE_READ) {
-		struct logger_reader *reader = file->private_data;
-		return reader->log;
-	} else
-		return file->private_data;
-}
-
-/*
- * get_entry_len - Grabs the length of the payload of the next entry starting
- * from 'off'.
- *
- * Caller needs to hold log->mutex.
- */
-static __u32 get_entry_len(struct logger_log *log, size_t off)
-{
-	__u16 val;
-
-	switch (log->size - off) {
-	case 1:
-		memcpy(&val, log->buffer + off, 1);
-		memcpy(((char *) &val) + 1, log->buffer, 1);
-		break;
-	default:
-		memcpy(&val, log->buffer + off, 2);
-	}
-
-	return sizeof(struct logger_entry) + val;
-}
-
-/*
- * do_read_log_to_user - reads exactly 'count' bytes from 'log' into the
- * user-space buffer 'buf'. Returns 'count' on success.
- *
- * Caller must hold log->mutex.
- */
-static ssize_t do_read_log_to_user(struct logger_log *log,
-				   struct logger_reader *reader,
-				   char __user *buf,
-				   size_t count)
-{
-	size_t len;
-
-	/*
-	 * We read from the log in two disjoint operations. First, we read from
-	 * the current read head offset up to 'count' bytes or to the end of
-	 * the log, whichever comes first.
-	 */
-	len = min(count, log->size - reader->r_off);
-	if (copy_to_user(buf, log->buffer + reader->r_off, len))
-		return -EFAULT;
-
-	/*
-	 * Second, we read any remaining bytes, starting back at the head of
-	 * the log.
-	 */
-	if (count != len)
-		if (copy_to_user(buf + len, log->buffer, count - len))
-			return -EFAULT;
-
-	reader->r_off = logger_offset(reader->r_off + count);
-
-	return count;
-}
-
-/*
- * logger_read - our log's read() method
- *
- * Behavior:
- *
- * 	- O_NONBLOCK works
- * 	- If there are no log entries to read, blocks until log is written to
- * 	- Atomically reads exactly one log entry
- *
- * Optimal read size is LOGGER_ENTRY_MAX_LEN. Will set errno to EINVAL if read
- * buffer is insufficient to hold next entry.
- */
-static ssize_t logger_read(struct file *file, char __user *buf,
-			   size_t count, loff_t *pos)
-{
-	struct logger_reader *reader = file->private_data;
-	struct logger_log *log = reader->log;
-	ssize_t ret;
-	DEFINE_WAIT(wait);
-
-start:
-	while (1) {
-		prepare_to_wait(&log->wq, &wait, TASK_INTERRUPTIBLE);
-
-		mutex_lock(&log->mutex);
-		ret = (log->w_off == reader->r_off);
-		mutex_unlock(&log->mutex);
-		if (!ret)
-			break;
-
-		if (file->f_flags & O_NONBLOCK) {
-			ret = -EAGAIN;
-			break;
-		}
-
-		if (signal_pending(current)) {
-			ret = -EINTR;
-			break;
-		}
-
-		schedule();
-	}
-
-	finish_wait(&log->wq, &wait);
-	if (ret)
-		return ret;
-
-	mutex_lock(&log->mutex);
-
-	/* is there still something to read or did we race? */
-	if (unlikely(log->w_off == reader->r_off)) {
-		mutex_unlock(&log->mutex);
-		goto start;
-	}
-
-	/* get the size of the next entry */
-	ret = get_entry_len(log, reader->r_off);
-	if (count < ret) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	/* get exactly one entry from the log */
-	ret = do_read_log_to_user(log, reader, buf, ret);
-
-out:
-	mutex_unlock(&log->mutex);
-
-	return ret;
-}
-
-/*
- * get_next_entry - return the offset of the first valid entry at least 'len'
- * bytes after 'off'.
- *
- * Caller must hold log->mutex.
- */
-static size_t get_next_entry(struct logger_log *log, size_t off, size_t len)
-{
-	size_t count = 0;
-
-	do {
-		size_t nr = get_entry_len(log, off);
-		off = logger_offset(off + nr);
-		count += nr;
-	} while (count < len);
-
-	return off;
-}
-
-/*
- * clock_interval - is a < c < b in mod-space? Put another way, does the line
- * from a to b cross c?
- */
-static inline int clock_interval(size_t a, size_t b, size_t c)
-{
-	if (b < a) {
-		if (a < c || b >= c)
-			return 1;
-	} else {
-		if (a < c && b >= c)
-			return 1;
-	}
-
-	return 0;
-}
-
-/*
- * fix_up_readers - walk the list of all readers and "fix up" any who were
- * lapped by the writer; also do the same for the default "start head".
- * We do this by "pulling forward" the readers and start head to the first
- * entry after the new write head.
- *
- * The caller needs to hold log->mutex.
- */
-static void fix_up_readers(struct logger_log *log, size_t len)
-{
-	size_t old = log->w_off;
-	size_t new = logger_offset(old + len);
-	struct logger_reader *reader;
-
-	if (clock_interval(old, new, log->head))
-		log->head = get_next_entry(log, log->head, len);
-
-	list_for_each_entry(reader, &log->readers, list)
-		if (clock_interval(old, new, reader->r_off))
-			reader->r_off = get_next_entry(log, reader->r_off, len);
-}
-
-/*
- * do_write_log - writes 'len' bytes from 'buf' to 'log'
- *
- * The caller needs to hold log->mutex.
- */
-static void do_write_log(struct logger_log *log, const void *buf, size_t count)
-{
-	size_t len;
-
-	len = min(count, log->size - log->w_off);
-	memcpy(log->buffer + log->w_off, buf, len);
-
-	if (count != len)
-		memcpy(log->buffer, buf + len, count - len);
-
-	log->w_off = logger_offset(log->w_off + count);
-
-}
-
-/*
- * do_write_log_user - writes 'len' bytes from the user-space buffer 'buf' to
- * the log 'log'
- *
- * The caller needs to hold log->mutex.
- *
- * Returns 'count' on success, negative error code on failure.
- */
-static ssize_t do_write_log_from_user(struct logger_log *log,
-				      const void __user *buf, size_t count)
-{
-	size_t len;
-
-	len = min(count, log->size - log->w_off);
-	if (len && copy_from_user(log->buffer + log->w_off, buf, len))
-		return -EFAULT;
-
-	if (count != len)
-		if (copy_from_user(log->buffer, buf + len, count - len))
-			return -EFAULT;
-
-	log->w_off = logger_offset(log->w_off + count);
-
-	return count;
-}
-
-/*
- * logger_aio_write - our write method, implementing support for write(),
- * writev(), and aio_write(). Writes are our fast path, and we try to optimize
- * them above all else.
- */
-ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov,
-			 unsigned long nr_segs, loff_t ppos)
-{
-	struct logger_log *log = file_get_log(iocb->ki_filp);
-	size_t orig = log->w_off;
-	struct logger_entry header;
-	struct timespec now;
-	ssize_t ret = 0;
-
-	now = current_kernel_time();
-
-	header.pid = current->tgid;
-	header.tid = current->pid;
-	header.sec = now.tv_sec;
-	header.nsec = now.tv_nsec;
-	header.len = min_t(size_t, iocb->ki_left, LOGGER_ENTRY_MAX_PAYLOAD);
-
-	/* null writes succeed, return zero */
-	if (unlikely(!header.len))
-		return 0;
-
-	mutex_lock(&log->mutex);
-
-	/*
-	 * Fix up any readers, pulling them forward to the first readable
-	 * entry after (what will be) the new write offset. We do this now
-	 * because if we partially fail, we can end up with clobbered log
-	 * entries that encroach on readable buffer.
-	 */
-	fix_up_readers(log, sizeof(struct logger_entry) + header.len);
-
-	do_write_log(log, &header, sizeof(struct logger_entry));
-
-	while (nr_segs-- > 0) {
-		size_t len;
-		ssize_t nr;
-
-		/* figure out how much of this vector we can keep */
-		len = min_t(size_t, iov->iov_len, header.len - ret);
-
-		/* write out this segment's payload */
-		nr = do_write_log_from_user(log, iov->iov_base, len);
-		if (unlikely(nr < 0)) {
-			log->w_off = orig;
-			mutex_unlock(&log->mutex);
-			return nr;
-		}
-
-		iov++;
-		ret += nr;
-	}
-
-	mutex_unlock(&log->mutex);
-
-	/* wake up any blocked readers */
-	wake_up_interruptible(&log->wq);
-
-	return ret;
-}
-
-static struct logger_log *get_log_from_minor(int);
-
-/*
- * logger_open - the log's open() file operation
- *
- * Note how near a no-op this is in the write-only case. Keep it that way!
- */
-static int logger_open(struct inode *inode, struct file *file)
-{
-	struct logger_log *log;
-	int ret;
-
-	ret = nonseekable_open(inode, file);
-	if (ret)
-		return ret;
-
-	log = get_log_from_minor(MINOR(inode->i_rdev));
-	if (!log)
-		return -ENODEV;
-
-	if (file->f_mode & FMODE_READ) {
-		struct logger_reader *reader;
-
-		reader = kmalloc(sizeof(struct logger_reader), GFP_KERNEL);
-		if (!reader)
-			return -ENOMEM;
-
-		reader->log = log;
-		INIT_LIST_HEAD(&reader->list);
-
-		mutex_lock(&log->mutex);
-		reader->r_off = log->head;
-		list_add_tail(&reader->list, &log->readers);
-		mutex_unlock(&log->mutex);
-
-		file->private_data = reader;
-	} else
-		file->private_data = log;
-
-	return 0;
-}
-
-/*
- * logger_release - the log's release file operation
- *
- * Note this is a total no-op in the write-only case. Keep it that way!
- */
-static int logger_release(struct inode *ignored, struct file *file)
-{
-	if (file->f_mode & FMODE_READ) {
-		struct logger_reader *reader = file->private_data;
-		list_del(&reader->list);
-		kfree(reader);
-	}
-
-	return 0;
-}
-
-/*
- * logger_poll - the log's poll file operation, for poll/select/epoll
- *
- * Note we always return POLLOUT, because you can always write() to the log.
- * Note also that, strictly speaking, a return value of POLLIN does not
- * guarantee that the log is readable without blocking, as there is a small
- * chance that the writer can lap the reader in the interim between poll()
- * returning and the read() request.
- */
-static unsigned int logger_poll(struct file *file, poll_table *wait)
-{
-	struct logger_reader *reader;
-	struct logger_log *log;
-	unsigned int ret = POLLOUT | POLLWRNORM;
-
-	if (!(file->f_mode & FMODE_READ))
-		return ret;
-
-	reader = file->private_data;
-	log = reader->log;
-
-	poll_wait(file, &log->wq, wait);
-
-	mutex_lock(&log->mutex);
-	if (log->w_off != reader->r_off)
-		ret |= POLLIN | POLLRDNORM;
-	mutex_unlock(&log->mutex);
-
-	return ret;
-}
-
-static long logger_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-	struct logger_log *log = file_get_log(file);
-	struct logger_reader *reader;
-	long ret = -ENOTTY;
-
-	mutex_lock(&log->mutex);
-
-	switch (cmd) {
-	case LOGGER_GET_LOG_BUF_SIZE:
-		ret = log->size;
-		break;
-	case LOGGER_GET_LOG_LEN:
-		if (!(file->f_mode & FMODE_READ)) {
-			ret = -EBADF;
-			break;
-		}
-		reader = file->private_data;
-		if (log->w_off >= reader->r_off)
-			ret = log->w_off - reader->r_off;
-		else
-			ret = (log->size - reader->r_off) + log->w_off;
-		break;
-	case LOGGER_GET_NEXT_ENTRY_LEN:
-		if (!(file->f_mode & FMODE_READ)) {
-			ret = -EBADF;
-			break;
-		}
-		reader = file->private_data;
-		if (log->w_off != reader->r_off)
-			ret = get_entry_len(log, reader->r_off);
-		else
-			ret = 0;
-		break;
-	case LOGGER_FLUSH_LOG:
-		if (!(file->f_mode & FMODE_WRITE)) {
-			ret = -EBADF;
-			break;
-		}
-		list_for_each_entry(reader, &log->readers, list)
-			reader->r_off = log->w_off;
-		log->head = log->w_off;
-		ret = 0;
-		break;
-	}
-
-	mutex_unlock(&log->mutex);
-
-	return ret;
-}
-
-static const struct file_operations logger_fops = {
-	.owner = THIS_MODULE,
-	.read = logger_read,
-	.aio_write = logger_aio_write,
-	.poll = logger_poll,
-	.unlocked_ioctl = logger_ioctl,
-	.compat_ioctl = logger_ioctl,
-	.open = logger_open,
-	.release = logger_release,
-};
-
-/*
- * Defines a log structure with name 'NAME' and a size of 'SIZE' bytes, which
- * must be a power of two, greater than LOGGER_ENTRY_MAX_LEN, and less than
- * LONG_MAX minus LOGGER_ENTRY_MAX_LEN.
- */
-#define DEFINE_LOGGER_DEVICE(VAR, NAME, SIZE) \
-static unsigned char _buf_ ## VAR[SIZE]; \
-static struct logger_log VAR = { \
-	.buffer = _buf_ ## VAR, \
-	.misc = { \
-		.minor = MISC_DYNAMIC_MINOR, \
-		.name = NAME, \
-		.fops = &logger_fops, \
-		.parent = NULL, \
-	}, \
-	.wq = __WAIT_QUEUE_HEAD_INITIALIZER(VAR .wq), \
-	.readers = LIST_HEAD_INIT(VAR .readers), \
-	.mutex = __MUTEX_INITIALIZER(VAR .mutex), \
-	.w_off = 0, \
-	.head = 0, \
-	.size = SIZE, \
-};
-
-DEFINE_LOGGER_DEVICE(log_main, LOGGER_LOG_MAIN, 64*1024)
-DEFINE_LOGGER_DEVICE(log_events, LOGGER_LOG_EVENTS, 256*1024)
-DEFINE_LOGGER_DEVICE(log_radio, LOGGER_LOG_RADIO, 64*1024)
-
-static struct logger_log *get_log_from_minor(int minor)
-{
-	if (log_main.misc.minor == minor)
-		return &log_main;
-	if (log_events.misc.minor == minor)
-		return &log_events;
-	if (log_radio.misc.minor == minor)
-		return &log_radio;
-	return NULL;
-}
-
-static int __init init_log(struct logger_log *log)
-{
-	int ret;
-
-	ret = misc_register(&log->misc);
-	if (unlikely(ret)) {
-		printk(KERN_ERR "logger: failed to register misc "
-		       "device for log '%s'!\n", log->misc.name);
-		return ret;
-	}
-
-	printk(KERN_INFO "logger: created %luK log '%s'\n",
-	       (unsigned long) log->size >> 10, log->misc.name);
-
-	return 0;
-}
-
-static int __init logger_init(void)
-{
-	int ret;
-
-	ret = init_log(&log_main);
-	if (unlikely(ret))
-		goto out;
-
-	ret = init_log(&log_events);
-	if (unlikely(ret))
-		goto out;
-
-	ret = init_log(&log_radio);
-	if (unlikely(ret))
-		goto out;
-
-out:
-	return ret;
-}
-device_initcall(logger_init);
diff --git a/drivers/staging/android/logger.h b/drivers/staging/android/logger.h
deleted file mode 100644
index a562434..0000000
--- a/drivers/staging/android/logger.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* include/linux/logger.h
- *
- * Copyright (C) 2007-2008 Google, Inc.
- * Author: Robert Love <rlove@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#ifndef _LINUX_LOGGER_H
-#define _LINUX_LOGGER_H
-
-#include <linux/types.h>
-#include <linux/ioctl.h>
-
-struct logger_entry {
-	__u16		len;	/* length of the payload */
-	__u16		__pad;	/* no matter what, we get 2 bytes of padding */
-	__s32		pid;	/* generating process's pid */
-	__s32		tid;	/* generating process's tid */
-	__s32		sec;	/* seconds since Epoch */
-	__s32		nsec;	/* nanoseconds */
-	char		msg[0];	/* the entry's payload */
-};
-
-#define LOGGER_LOG_RADIO	"log_radio"	/* radio-related messages */
-#define LOGGER_LOG_EVENTS	"log_events"	/* system/hardware events */
-#define LOGGER_LOG_MAIN		"log_main"	/* everything else */
-
-#define LOGGER_ENTRY_MAX_LEN		(4*1024)
-#define LOGGER_ENTRY_MAX_PAYLOAD	\
-	(LOGGER_ENTRY_MAX_LEN - sizeof(struct logger_entry))
-
-#define __LOGGERIO	0xAE
-
-#define LOGGER_GET_LOG_BUF_SIZE		_IO(__LOGGERIO, 1) /* size of log */
-#define LOGGER_GET_LOG_LEN		_IO(__LOGGERIO, 2) /* used log len */
-#define LOGGER_GET_NEXT_ENTRY_LEN	_IO(__LOGGERIO, 3) /* next entry len */
-#define LOGGER_FLUSH_LOG		_IO(__LOGGERIO, 4) /* flush log */
-
-#endif /* _LINUX_LOGGER_H */
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
deleted file mode 100644
index 935d281..0000000
--- a/drivers/staging/android/lowmemorykiller.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/* drivers/misc/lowmemorykiller.c
- *
- * The lowmemorykiller driver lets user-space specify a set of memory thresholds
- * where processes with a range of oom_adj values will get killed. Specify the
- * minimum oom_adj values in /sys/module/lowmemorykiller/parameters/adj and the
- * number of free pages in /sys/module/lowmemorykiller/parameters/minfree. Both
- * files take a comma separated list of numbers in ascending order.
- *
- * For example, write "0,8" to /sys/module/lowmemorykiller/parameters/adj and
- * "1024,4096" to /sys/module/lowmemorykiller/parameters/minfree to kill processes
- * with a oom_adj value of 8 or higher when the free memory drops below 4096 pages
- * and kill processes with a oom_adj value of 0 or higher when the free memory
- * drops below 1024 pages.
- *
- * The driver considers memory used for caches to be free, but if a large
- * percentage of the cached memory is locked this can be very inaccurate
- * and processes may not get killed until the normal oom killer is triggered.
- *
- * Copyright (C) 2007-2008 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/oom.h>
-#include <linux/sched.h>
-
-static uint32_t lowmem_debug_level = 2;
-static int lowmem_adj[6] = {
-	0,
-	1,
-	6,
-	12,
-};
-static int lowmem_adj_size = 4;
-static size_t lowmem_minfree[6] = {
-	3 * 512,	/* 6MB */
-	2 * 1024,	/* 8MB */
-	4 * 1024,	/* 16MB */
-	16 * 1024,	/* 64MB */
-};
-static int lowmem_minfree_size = 4;
-
-#define lowmem_print(level, x...)			\
-	do {						\
-		if (lowmem_debug_level >= (level))	\
-			printk(x);			\
-	} while (0)
-
-static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask)
-{
-	struct task_struct *p;
-	struct task_struct *selected = NULL;
-	int rem = 0;
-	int tasksize;
-	int i;
-	int min_adj = OOM_ADJUST_MAX + 1;
-	int selected_tasksize = 0;
-	int selected_oom_adj;
-	int array_size = ARRAY_SIZE(lowmem_adj);
-	int other_free = global_page_state(NR_FREE_PAGES);
-	int other_file = global_page_state(NR_FILE_PAGES);
-
-	if (lowmem_adj_size < array_size)
-		array_size = lowmem_adj_size;
-	if (lowmem_minfree_size < array_size)
-		array_size = lowmem_minfree_size;
-	for (i = 0; i < array_size; i++) {
-		if (other_free < lowmem_minfree[i] &&
-		    other_file < lowmem_minfree[i]) {
-			min_adj = lowmem_adj[i];
-			break;
-		}
-	}
-	if (nr_to_scan > 0)
-		lowmem_print(3, "lowmem_shrink %d, %x, ofree %d %d, ma %d\n",
-			     nr_to_scan, gfp_mask, other_free, other_file,
-			     min_adj);
-	rem = global_page_state(NR_ACTIVE_ANON) +
-		global_page_state(NR_ACTIVE_FILE) +
-		global_page_state(NR_INACTIVE_ANON) +
-		global_page_state(NR_INACTIVE_FILE);
-	if (nr_to_scan <= 0 || min_adj == OOM_ADJUST_MAX + 1) {
-		lowmem_print(5, "lowmem_shrink %d, %x, return %d\n",
-			     nr_to_scan, gfp_mask, rem);
-		return rem;
-	}
-	selected_oom_adj = min_adj;
-
-	read_lock(&tasklist_lock);
-	for_each_process(p) {
-		struct mm_struct *mm;
-		int oom_adj;
-
-		task_lock(p);
-		mm = p->mm;
-		if (!mm) {
-			task_unlock(p);
-			continue;
-		}
-		oom_adj = mm->oom_adj;
-		if (oom_adj < min_adj) {
-			task_unlock(p);
-			continue;
-		}
-		tasksize = get_mm_rss(mm);
-		task_unlock(p);
-		if (tasksize <= 0)
-			continue;
-		if (selected) {
-			if (oom_adj < selected_oom_adj)
-				continue;
-			if (oom_adj == selected_oom_adj &&
-			    tasksize <= selected_tasksize)
-				continue;
-		}
-		selected = p;
-		selected_tasksize = tasksize;
-		selected_oom_adj = oom_adj;
-		lowmem_print(2, "select %d (%s), adj %d, size %d, to kill\n",
-			     p->pid, p->comm, oom_adj, tasksize);
-	}
-	if (selected) {
-		lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d\n",
-			     selected->pid, selected->comm,
-			     selected_oom_adj, selected_tasksize);
-		force_sig(SIGKILL, selected);
-		rem -= selected_tasksize;
-	}
-	lowmem_print(4, "lowmem_shrink %d, %x, return %d\n",
-		     nr_to_scan, gfp_mask, rem);
-	read_unlock(&tasklist_lock);
-	return rem;
-}
-
-static struct shrinker lowmem_shrinker = {
-	.shrink = lowmem_shrink,
-	.seeks = DEFAULT_SEEKS * 16
-};
-
-static int __init lowmem_init(void)
-{
-	register_shrinker(&lowmem_shrinker);
-	return 0;
-}
-
-static void __exit lowmem_exit(void)
-{
-	unregister_shrinker(&lowmem_shrinker);
-}
-
-module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR);
-module_param_array_named(adj, lowmem_adj, int, &lowmem_adj_size,
-			 S_IRUGO | S_IWUSR);
-module_param_array_named(minfree, lowmem_minfree, uint, &lowmem_minfree_size,
-			 S_IRUGO | S_IWUSR);
-module_param_named(debug_level, lowmem_debug_level, uint, S_IRUGO | S_IWUSR);
-
-module_init(lowmem_init);
-module_exit(lowmem_exit);
-
-MODULE_LICENSE("GPL");
-
diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c
deleted file mode 100644
index 8f18a59..0000000
--- a/drivers/staging/android/ram_console.c
+++ /dev/null
@@ -1,410 +0,0 @@
-/* drivers/android/ram_console.c
- *
- * Copyright (C) 2007-2008 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/console.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/proc_fs.h>
-#include <linux/string.h>
-#include <linux/uaccess.h>
-#include <linux/io.h>
-
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
-#include <linux/rslib.h>
-#endif
-
-struct ram_console_buffer {
-	uint32_t    sig;
-	uint32_t    start;
-	uint32_t    size;
-	uint8_t     data[0];
-};
-
-#define RAM_CONSOLE_SIG (0x43474244) /* DBGC */
-
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT
-static char __initdata
-	ram_console_old_log_init_buffer[CONFIG_ANDROID_RAM_CONSOLE_EARLY_SIZE];
-#endif
-static char *ram_console_old_log;
-static size_t ram_console_old_log_size;
-
-static struct ram_console_buffer *ram_console_buffer;
-static size_t ram_console_buffer_size;
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
-static char *ram_console_par_buffer;
-static struct rs_control *ram_console_rs_decoder;
-static int ram_console_corrected_bytes;
-static int ram_console_bad_blocks;
-#define ECC_BLOCK_SIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE
-#define ECC_SIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE
-#define ECC_SYMSIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE
-#define ECC_POLY CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL
-#endif
-
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
-static void ram_console_encode_rs8(uint8_t *data, size_t len, uint8_t *ecc)
-{
-	int i;
-	uint16_t par[ECC_SIZE];
-	/* Initialize the parity buffer */
-	memset(par, 0, sizeof(par));
-	encode_rs8(ram_console_rs_decoder, data, len, par, 0);
-	for (i = 0; i < ECC_SIZE; i++)
-		ecc[i] = par[i];
-}
-
-static int ram_console_decode_rs8(void *data, size_t len, uint8_t *ecc)
-{
-	int i;
-	uint16_t par[ECC_SIZE];
-	for (i = 0; i < ECC_SIZE; i++)
-		par[i] = ecc[i];
-	return decode_rs8(ram_console_rs_decoder, data, par, len,
-				NULL, 0, NULL, 0, NULL);
-}
-#endif
-
-static void ram_console_update(const char *s, unsigned int count)
-{
-	struct ram_console_buffer *buffer = ram_console_buffer;
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
-	uint8_t *buffer_end = buffer->data + ram_console_buffer_size;
-	uint8_t *block;
-	uint8_t *par;
-	int size = ECC_BLOCK_SIZE;
-#endif
-	memcpy(buffer->data + buffer->start, s, count);
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
-	block = buffer->data + (buffer->start & ~(ECC_BLOCK_SIZE - 1));
-	par = ram_console_par_buffer +
-	      (buffer->start / ECC_BLOCK_SIZE) * ECC_SIZE;
-	do {
-		if (block + ECC_BLOCK_SIZE > buffer_end)
-			size = buffer_end - block;
-		ram_console_encode_rs8(block, size, par);
-		block += ECC_BLOCK_SIZE;
-		par += ECC_SIZE;
-	} while (block < buffer->data + buffer->start + count);
-#endif
-}
-
-static void ram_console_update_header(void)
-{
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
-	struct ram_console_buffer *buffer = ram_console_buffer;
-	uint8_t *par;
-	par = ram_console_par_buffer +
-	      DIV_ROUND_UP(ram_console_buffer_size, ECC_BLOCK_SIZE) * ECC_SIZE;
-	ram_console_encode_rs8((uint8_t *)buffer, sizeof(*buffer), par);
-#endif
-}
-
-static void
-ram_console_write(struct console *console, const char *s, unsigned int count)
-{
-	int rem;
-	struct ram_console_buffer *buffer = ram_console_buffer;
-
-	if (count > ram_console_buffer_size) {
-		s += count - ram_console_buffer_size;
-		count = ram_console_buffer_size;
-	}
-	rem = ram_console_buffer_size - buffer->start;
-	if (rem < count) {
-		ram_console_update(s, rem);
-		s += rem;
-		count -= rem;
-		buffer->start = 0;
-		buffer->size = ram_console_buffer_size;
-	}
-	ram_console_update(s, count);
-
-	buffer->start += count;
-	if (buffer->size < ram_console_buffer_size)
-		buffer->size += count;
-	ram_console_update_header();
-}
-
-static struct console ram_console = {
-	.name	= "ram",
-	.write	= ram_console_write,
-	.flags	= CON_PRINTBUFFER | CON_ENABLED,
-	.index	= -1,
-};
-
-static void __init
-ram_console_save_old(struct ram_console_buffer *buffer, char *dest)
-{
-	size_t old_log_size = buffer->size;
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
-	uint8_t *block;
-	uint8_t *par;
-	char strbuf[80];
-	int strbuf_len;
-
-	block = buffer->data;
-	par = ram_console_par_buffer;
-	while (block < buffer->data + buffer->size) {
-		int numerr;
-		int size = ECC_BLOCK_SIZE;
-		if (block + size > buffer->data + ram_console_buffer_size)
-			size = buffer->data + ram_console_buffer_size - block;
-		numerr = ram_console_decode_rs8(block, size, par);
-		if (numerr > 0) {
-#if 0
-			printk(KERN_INFO "ram_console: error in block %p, %d\n",
-			       block, numerr);
-#endif
-			ram_console_corrected_bytes += numerr;
-		} else if (numerr < 0) {
-#if 0
-			printk(KERN_INFO "ram_console: uncorrectable error in "
-			       "block %p\n", block);
-#endif
-			ram_console_bad_blocks++;
-		}
-		block += ECC_BLOCK_SIZE;
-		par += ECC_SIZE;
-	}
-	if (ram_console_corrected_bytes || ram_console_bad_blocks)
-		strbuf_len = snprintf(strbuf, sizeof(strbuf),
-			"\n%d Corrected bytes, %d unrecoverable blocks\n",
-			ram_console_corrected_bytes, ram_console_bad_blocks);
-	else
-		strbuf_len = snprintf(strbuf, sizeof(strbuf),
-				      "\nNo errors detected\n");
-	if (strbuf_len >= sizeof(strbuf))
-		strbuf_len = sizeof(strbuf) - 1;
-	old_log_size += strbuf_len;
-#endif
-
-	if (dest == NULL) {
-		dest = kmalloc(old_log_size, GFP_KERNEL);
-		if (dest == NULL) {
-			printk(KERN_ERR
-			       "ram_console: failed to allocate buffer\n");
-			return;
-		}
-	}
-
-	ram_console_old_log = dest;
-	ram_console_old_log_size = old_log_size;
-	memcpy(ram_console_old_log,
-	       &buffer->data[buffer->start], buffer->size - buffer->start);
-	memcpy(ram_console_old_log + buffer->size - buffer->start,
-	       &buffer->data[0], buffer->start);
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
-	memcpy(ram_console_old_log + old_log_size - strbuf_len,
-	       strbuf, strbuf_len);
-#endif
-}
-
-static int __init ram_console_init(struct ram_console_buffer *buffer,
-				   size_t buffer_size, char *old_buf)
-{
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
-	int numerr;
-	uint8_t *par;
-#endif
-	ram_console_buffer = buffer;
-	ram_console_buffer_size =
-		buffer_size - sizeof(struct ram_console_buffer);
-
-	if (ram_console_buffer_size > buffer_size) {
-		pr_err("ram_console: buffer %p, invalid size %zu, "
-		       "datasize %zu\n", buffer, buffer_size,
-		       ram_console_buffer_size);
-		return 0;
-	}
-
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
-	ram_console_buffer_size -= (DIV_ROUND_UP(ram_console_buffer_size,
-						ECC_BLOCK_SIZE) + 1) * ECC_SIZE;
-
-	if (ram_console_buffer_size > buffer_size) {
-		pr_err("ram_console: buffer %p, invalid size %zu, "
-		       "non-ecc datasize %zu\n",
-		       buffer, buffer_size, ram_console_buffer_size);
-		return 0;
-	}
-
-	ram_console_par_buffer = buffer->data + ram_console_buffer_size;
-
-
-	/* first consecutive root is 0
-	 * primitive element to generate roots = 1
-	 */
-	ram_console_rs_decoder = init_rs(ECC_SYMSIZE, ECC_POLY, 0, 1, ECC_SIZE);
-	if (ram_console_rs_decoder == NULL) {
-		printk(KERN_INFO "ram_console: init_rs failed\n");
-		return 0;
-	}
-
-	ram_console_corrected_bytes = 0;
-	ram_console_bad_blocks = 0;
-
-	par = ram_console_par_buffer +
-	      DIV_ROUND_UP(ram_console_buffer_size, ECC_BLOCK_SIZE) * ECC_SIZE;
-
-	numerr = ram_console_decode_rs8(buffer, sizeof(*buffer), par);
-	if (numerr > 0) {
-		printk(KERN_INFO "ram_console: error in header, %d\n", numerr);
-		ram_console_corrected_bytes += numerr;
-	} else if (numerr < 0) {
-		printk(KERN_INFO
-		       "ram_console: uncorrectable error in header\n");
-		ram_console_bad_blocks++;
-	}
-#endif
-
-	if (buffer->sig == RAM_CONSOLE_SIG) {
-		if (buffer->size > ram_console_buffer_size
-		    || buffer->start > buffer->size)
-			printk(KERN_INFO "ram_console: found existing invalid "
-			       "buffer, size %d, start %d\n",
-			       buffer->size, buffer->start);
-		else {
-			printk(KERN_INFO "ram_console: found existing buffer, "
-			       "size %d, start %d\n",
-			       buffer->size, buffer->start);
-			ram_console_save_old(buffer, old_buf);
-		}
-	} else {
-		printk(KERN_INFO "ram_console: no valid data in buffer "
-		       "(sig = 0x%08x)\n", buffer->sig);
-	}
-
-	buffer->sig = RAM_CONSOLE_SIG;
-	buffer->start = 0;
-	buffer->size = 0;
-
-	register_console(&ram_console);
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_ENABLE_VERBOSE
-	console_verbose();
-#endif
-	return 0;
-}
-
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT
-static int __init ram_console_early_init(void)
-{
-	return ram_console_init((struct ram_console_buffer *)
-		CONFIG_ANDROID_RAM_CONSOLE_EARLY_ADDR,
-		CONFIG_ANDROID_RAM_CONSOLE_EARLY_SIZE,
-		ram_console_old_log_init_buffer);
-}
-#else
-static int ram_console_driver_probe(struct platform_device *pdev)
-{
-	struct resource *res = pdev->resource;
-	size_t start;
-	size_t buffer_size;
-	void *buffer;
-
-	if (res == NULL || pdev->num_resources != 1 ||
-	    !(res->flags & IORESOURCE_MEM)) {
-		printk(KERN_ERR "ram_console: invalid resource, %p %d flags "
-		       "%lx\n", res, pdev->num_resources, res ? res->flags : 0);
-		return -ENXIO;
-	}
-	buffer_size = res->end - res->start + 1;
-	start = res->start;
-	printk(KERN_INFO "ram_console: got buffer at %zx, size %zx\n",
-	       start, buffer_size);
-	buffer = ioremap(res->start, buffer_size);
-	if (buffer == NULL) {
-		printk(KERN_ERR "ram_console: failed to map memory\n");
-		return -ENOMEM;
-	}
-
-	return ram_console_init(buffer, buffer_size, NULL/* allocate */);
-}
-
-static struct platform_driver ram_console_driver = {
-	.probe = ram_console_driver_probe,
-	.driver		= {
-		.name	= "ram_console",
-	},
-};
-
-static int __init ram_console_module_init(void)
-{
-	int err;
-	err = platform_driver_register(&ram_console_driver);
-	return err;
-}
-#endif
-
-static ssize_t ram_console_read_old(struct file *file, char __user *buf,
-				    size_t len, loff_t *offset)
-{
-	loff_t pos = *offset;
-	ssize_t count;
-
-	if (pos >= ram_console_old_log_size)
-		return 0;
-
-	count = min(len, (size_t)(ram_console_old_log_size - pos));
-	if (copy_to_user(buf, ram_console_old_log + pos, count))
-		return -EFAULT;
-
-	*offset += count;
-	return count;
-}
-
-static const struct file_operations ram_console_file_ops = {
-	.owner = THIS_MODULE,
-	.read = ram_console_read_old,
-};
-
-static int __init ram_console_late_init(void)
-{
-	struct proc_dir_entry *entry;
-
-	if (ram_console_old_log == NULL)
-		return 0;
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT
-	ram_console_old_log = kmalloc(ram_console_old_log_size, GFP_KERNEL);
-	if (ram_console_old_log == NULL) {
-		printk(KERN_ERR
-		       "ram_console: failed to allocate buffer for old log\n");
-		ram_console_old_log_size = 0;
-		return 0;
-	}
-	memcpy(ram_console_old_log,
-	       ram_console_old_log_init_buffer, ram_console_old_log_size);
-#endif
-	entry = create_proc_entry("last_kmsg", S_IFREG | S_IRUGO, NULL);
-	if (!entry) {
-		printk(KERN_ERR "ram_console: failed to create proc entry\n");
-		kfree(ram_console_old_log);
-		ram_console_old_log = NULL;
-		return 0;
-	}
-
-	entry->proc_fops = &ram_console_file_ops;
-	entry->size = ram_console_old_log_size;
-	return 0;
-}
-
-#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT
-console_initcall(ram_console_early_init);
-#else
-module_init(ram_console_module_init);
-#endif
-late_initcall(ram_console_late_init);
-
diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c
deleted file mode 100644
index be7cdaa..0000000
--- a/drivers/staging/android/timed_gpio.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/* drivers/misc/timed_gpio.c
- *
- * Copyright (C) 2008 Google, Inc.
- * Author: Mike Lockwood <lockwood@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/hrtimer.h>
-#include <linux/err.h>
-#include <linux/gpio.h>
-
-#include "timed_output.h"
-#include "timed_gpio.h"
-
-
-struct timed_gpio_data {
-	struct timed_output_dev dev;
-	struct hrtimer timer;
-	spinlock_t lock;
-	unsigned 	gpio;
-	int 		max_timeout;
-	u8 		active_low;
-};
-
-static enum hrtimer_restart gpio_timer_func(struct hrtimer *timer)
-{
-	struct timed_gpio_data *data =
-		container_of(timer, struct timed_gpio_data, timer);
-
-	gpio_direction_output(data->gpio, data->active_low ? 1 : 0);
-	return HRTIMER_NORESTART;
-}
-
-static int gpio_get_time(struct timed_output_dev *dev)
-{
-	struct timed_gpio_data	*data =
-		container_of(dev, struct timed_gpio_data, dev);
-
-	if (hrtimer_active(&data->timer)) {
-		ktime_t r = hrtimer_get_remaining(&data->timer);
-		struct timeval t = ktime_to_timeval(r);
-		return t.tv_sec * 1000 + t.tv_usec / 1000;
-	} else
-		return 0;
-}
-
-static void gpio_enable(struct timed_output_dev *dev, int value)
-{
-	struct timed_gpio_data	*data =
-		container_of(dev, struct timed_gpio_data, dev);
-	unsigned long	flags;
-
-	spin_lock_irqsave(&data->lock, flags);
-
-	/* cancel previous timer and set GPIO according to value */
-	hrtimer_cancel(&data->timer);
-	gpio_direction_output(data->gpio, data->active_low ? !value : !!value);
-
-	if (value > 0) {
-		if (value > data->max_timeout)
-			value = data->max_timeout;
-
-		hrtimer_start(&data->timer,
-			ktime_set(value / 1000, (value % 1000) * 1000000),
-			HRTIMER_MODE_REL);
-	}
-
-	spin_unlock_irqrestore(&data->lock, flags);
-}
-
-static int timed_gpio_probe(struct platform_device *pdev)
-{
-	struct timed_gpio_platform_data *pdata = pdev->dev.platform_data;
-	struct timed_gpio *cur_gpio;
-	struct timed_gpio_data *gpio_data, *gpio_dat;
-	int i, j, ret = 0;
-
-	if (!pdata)
-		return -EBUSY;
-
-	gpio_data = kzalloc(sizeof(struct timed_gpio_data) * pdata->num_gpios,
-			GFP_KERNEL);
-	if (!gpio_data)
-		return -ENOMEM;
-
-	for (i = 0; i < pdata->num_gpios; i++) {
-		cur_gpio = &pdata->gpios[i];
-		gpio_dat = &gpio_data[i];
-
-		hrtimer_init(&gpio_dat->timer, CLOCK_MONOTONIC,
-				HRTIMER_MODE_REL);
-		gpio_dat->timer.function = gpio_timer_func;
-		spin_lock_init(&gpio_dat->lock);
-
-		gpio_dat->dev.name = cur_gpio->name;
-		gpio_dat->dev.get_time = gpio_get_time;
-		gpio_dat->dev.enable = gpio_enable;
-		ret = timed_output_dev_register(&gpio_dat->dev);
-		if (ret < 0) {
-			for (j = 0; j < i; j++)
-				timed_output_dev_unregister(&gpio_data[i].dev);
-			kfree(gpio_data);
-			return ret;
-		}
-
-		gpio_dat->gpio = cur_gpio->gpio;
-		gpio_dat->max_timeout = cur_gpio->max_timeout;
-		gpio_dat->active_low = cur_gpio->active_low;
-		gpio_direction_output(gpio_dat->gpio, gpio_dat->active_low);
-	}
-
-	platform_set_drvdata(pdev, gpio_data);
-
-	return 0;
-}
-
-static int timed_gpio_remove(struct platform_device *pdev)
-{
-	struct timed_gpio_platform_data *pdata = pdev->dev.platform_data;
-	struct timed_gpio_data *gpio_data = platform_get_drvdata(pdev);
-	int i;
-
-	for (i = 0; i < pdata->num_gpios; i++)
-		timed_output_dev_unregister(&gpio_data[i].dev);
-
-	kfree(gpio_data);
-
-	return 0;
-}
-
-static struct platform_driver timed_gpio_driver = {
-	.probe		= timed_gpio_probe,
-	.remove		= timed_gpio_remove,
-	.driver		= {
-		.name		= TIMED_GPIO_NAME,
-		.owner		= THIS_MODULE,
-	},
-};
-
-static int __init timed_gpio_init(void)
-{
-	return platform_driver_register(&timed_gpio_driver);
-}
-
-static void __exit timed_gpio_exit(void)
-{
-	platform_driver_unregister(&timed_gpio_driver);
-}
-
-module_init(timed_gpio_init);
-module_exit(timed_gpio_exit);
-
-MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>");
-MODULE_DESCRIPTION("timed gpio driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/android/timed_gpio.h b/drivers/staging/android/timed_gpio.h
deleted file mode 100644
index a0e15f8..0000000
--- a/drivers/staging/android/timed_gpio.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* include/linux/timed_gpio.h
- *
- * Copyright (C) 2008 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
-*/
-
-#ifndef _LINUX_TIMED_GPIO_H
-#define _LINUX_TIMED_GPIO_H
-
-#define TIMED_GPIO_NAME "timed-gpio"
-
-struct timed_gpio {
-	const char *name;
-	unsigned 	gpio;
-	int		max_timeout;
-	u8 		active_low;
-};
-
-struct timed_gpio_platform_data {
-	int 		num_gpios;
-	struct timed_gpio *gpios;
-};
-
-#endif
diff --git a/drivers/staging/android/timed_output.c b/drivers/staging/android/timed_output.c
deleted file mode 100644
index 62e7918..0000000
--- a/drivers/staging/android/timed_output.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/* drivers/misc/timed_output.c
- *
- * Copyright (C) 2009 Google, Inc.
- * Author: Mike Lockwood <lockwood@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/device.h>
-#include <linux/fs.h>
-#include <linux/err.h>
-
-#include "timed_output.h"
-
-static struct class *timed_output_class;
-static atomic_t device_count;
-
-static ssize_t enable_show(struct device *dev, struct device_attribute *attr,
-		char *buf)
-{
-	struct timed_output_dev *tdev = dev_get_drvdata(dev);
-	int remaining = tdev->get_time(tdev);
-
-	return sprintf(buf, "%d\n", remaining);
-}
-
-static ssize_t enable_store(
-		struct device *dev, struct device_attribute *attr,
-		const char *buf, size_t size)
-{
-	struct timed_output_dev *tdev = dev_get_drvdata(dev);
-	int value;
-
-	sscanf(buf, "%d", &value);
-	tdev->enable(tdev, value);
-
-	return size;
-}
-
-static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store);
-
-static int create_timed_output_class(void)
-{
-	if (!timed_output_class) {
-		timed_output_class = class_create(THIS_MODULE, "timed_output");
-		if (IS_ERR(timed_output_class))
-			return PTR_ERR(timed_output_class);
-		atomic_set(&device_count, 0);
-	}
-
-	return 0;
-}
-
-int timed_output_dev_register(struct timed_output_dev *tdev)
-{
-	int ret;
-
-	if (!tdev || !tdev->name || !tdev->enable || !tdev->get_time)
-		return -EINVAL;
-
-	ret = create_timed_output_class();
-	if (ret < 0)
-		return ret;
-
-	tdev->index = atomic_inc_return(&device_count);
-	tdev->dev = device_create(timed_output_class, NULL,
-		MKDEV(0, tdev->index), NULL, tdev->name);
-	if (IS_ERR(tdev->dev))
-		return PTR_ERR(tdev->dev);
-
-	ret = device_create_file(tdev->dev, &dev_attr_enable);
-	if (ret < 0)
-		goto err_create_file;
-
-	dev_set_drvdata(tdev->dev, tdev);
-	tdev->state = 0;
-	return 0;
-
-err_create_file:
-	device_destroy(timed_output_class, MKDEV(0, tdev->index));
-	printk(KERN_ERR "timed_output: Failed to register driver %s\n",
-			tdev->name);
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(timed_output_dev_register);
-
-void timed_output_dev_unregister(struct timed_output_dev *tdev)
-{
-	device_remove_file(tdev->dev, &dev_attr_enable);
-	device_destroy(timed_output_class, MKDEV(0, tdev->index));
-	dev_set_drvdata(tdev->dev, NULL);
-}
-EXPORT_SYMBOL_GPL(timed_output_dev_unregister);
-
-static int __init timed_output_init(void)
-{
-	return create_timed_output_class();
-}
-
-static void __exit timed_output_exit(void)
-{
-	class_destroy(timed_output_class);
-}
-
-module_init(timed_output_init);
-module_exit(timed_output_exit);
-
-MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>");
-MODULE_DESCRIPTION("timed output class driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/android/timed_output.h b/drivers/staging/android/timed_output.h
deleted file mode 100644
index ec907ab..0000000
--- a/drivers/staging/android/timed_output.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* include/linux/timed_output.h
- *
- * Copyright (C) 2008 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
-*/
-
-#ifndef _LINUX_TIMED_OUTPUT_H
-#define _LINUX_TIMED_OUTPUT_H
-
-struct timed_output_dev {
-	const char	*name;
-
-	/* enable the output and set the timer */
-	void	(*enable)(struct timed_output_dev *sdev, int timeout);
-
-	/* returns the current number of milliseconds remaining on the timer */
-	int		(*get_time)(struct timed_output_dev *sdev);
-
-	/* private data */
-	struct device	*dev;
-	int		index;
-	int		state;
-};
-
-extern int timed_output_dev_register(struct timed_output_dev *dev);
-extern void timed_output_dev_unregister(struct timed_output_dev *dev);
-
-#endif
diff --git a/drivers/staging/b3dfg/b3dfg.c b/drivers/staging/b3dfg/b3dfg.c
index cda26bb4..4a43c51 100644
--- a/drivers/staging/b3dfg/b3dfg.c
+++ b/drivers/staging/b3dfg/b3dfg.c
@@ -468,7 +468,6 @@
 
 static int enable_transmission(struct b3dfg_dev *fgdev)
 {
-	u16 command;
 	unsigned long flags;
 	struct device *dev = &fgdev->pdev->dev;
 
@@ -480,17 +479,6 @@
 		return -EINVAL;
 	}
 
-	/*
-	 * Check we're a bus master.
-	 * TODO: I think we can remove this having added the pci_set_master call
-	 */
-	pci_read_config_word(fgdev->pdev, PCI_COMMAND, &command);
-	if (!(command & PCI_COMMAND_MASTER)) {
-		dev_err(dev, "not a bus master, force-enabling\n");
-		pci_write_config_word(fgdev->pdev, PCI_COMMAND,
-			command | PCI_COMMAND_MASTER);
-	}
-
 	spin_lock_irqsave(&fgdev->buffer_lock, flags);
 
 	/* Handle racing enable_transmission calls. */
diff --git a/drivers/staging/batman-adv/CHANGELOG b/drivers/staging/batman-adv/CHANGELOG
new file mode 100644
index 0000000..8a18163
--- /dev/null
+++ b/drivers/staging/batman-adv/CHANGELOG
@@ -0,0 +1,37 @@
+batman-adv 0.2:
+
+* support latest kernels (2.6.20 - 2.6.31)
+* temporary routing loops / TTL code bug / ghost entries in originator table fixed
+* internal packet queue for packet aggregation & transmission retry (ARQ)
+  for payload broadcasts added
+* interface detection converted to event based handling to avoid timers
+* major linux coding style adjustments applied
+* all kernel version compatibility functions has been moved to compat.h
+* use random ethernet address generator from the kernel
+* /sys/module/batman_adv/version to export kernel module version
+* vis: secondary interface export for dot draw format + JSON output format added
+* many bugs (alignment issues, race conditions, deadlocks, etc) squashed
+
+ -- Sat, 07 Nov 2009 15:44:31 +0100
+
+batman-adv 0.1:
+
+* support latest kernels (2.6.20 - 2.6.28)
+* LOTS of cleanup: locking, stack usage, memory leaks
+* Change Ethertype from 0x0842 to 0x4305
+  unregistered at IEEE, if you want to sponsor an official Ethertype ($2500)
+  please contact us
+
+ -- Sun, 28 Dec 2008 00:44:31 +0100
+
+batman-adv 0.1-beta:
+
+* layer 2 meshing based on BATMAN TQ algorithm in kernelland
+* operates on any ethernet like interface
+* supports IPv4, IPv6, DHCP, etc
+* is controlled via /proc/net/batman-adv/
+* bridging via brctl is supported
+* interface watchdog (interfaces can be (de)activated dynamically)
+* offers integrated vis server which meshes/syncs with other vis servers in range
+
+ -- Mon, 05 May 2008 14:10:04 +0200
diff --git a/drivers/staging/batman-adv/Kconfig b/drivers/staging/batman-adv/Kconfig
new file mode 100644
index 0000000..7632f57
--- /dev/null
+++ b/drivers/staging/batman-adv/Kconfig
@@ -0,0 +1,25 @@
+#
+# B.A.T.M.A.N meshing protocol
+#
+
+config BATMAN_ADV
+	tristate "B.A.T.M.A.N. Advanced Meshing Protocol"
+        default n
+	---help---
+
+        B.A.T.M.A.N. (better approach to mobile ad-hoc networking) is
+        a routing protocol for multi-hop ad-hoc mesh networks. The
+        networks may be wired or wireless. See
+        http://www.open-mesh.org/ for more information and user space
+        tools.
+
+config BATMAN_DEBUG
+	bool "B.A.T.M.A.N. debugging"
+	depends on BATMAN_ADV != n
+	help
+
+	  This is an option for use by developers; most people should
+	  say N here. This enables compilation of support for
+	  outputting debugging information to the kernel log. The
+	  output is controlled via the module parameter debug.
+
diff --git a/drivers/staging/batman-adv/Makefile b/drivers/staging/batman-adv/Makefile
new file mode 100644
index 0000000..02da871
--- /dev/null
+++ b/drivers/staging/batman-adv/Makefile
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+#
+# Marek Lindner, Simon Wunderlich
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA
+#
+
+obj-m += batman-adv.o
+batman-adv-objs := main.o proc.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o log.o
diff --git a/drivers/staging/batman-adv/README b/drivers/staging/batman-adv/README
new file mode 100644
index 0000000..3aaf393
--- /dev/null
+++ b/drivers/staging/batman-adv/README
@@ -0,0 +1,125 @@
+[state: 07-11-2009]
+
+BATMAN-ADV
+----------
+
+Batman-advanced is a new approach to wireless networking which does no longer
+operate on the IP basis. Unlike B.A.T.M.A.N, which exchanges information
+using UDP packets and sets routing tables, batman-advanced operates on ISO/OSI
+Layer 2 only and uses and routes (or better: bridges) Ethernet Frames. It
+emulates a virtual network switch of all nodes participating. Therefore all
+nodes appear to be link local, thus all higher operating protocols won't be
+affected by any changes within the network. You can run almost any protocol
+above B.A.T.M.A.N. Advanced, prominent examples are: IPv4, IPv6, DHCP, IPX.
+
+This is batman-advanced implemented as Linux kernel driver. It does not depend
+on any network (other) driver, and can be used on wifi as well as ethernet,
+vpn, etc ... (anything with ethernet-style layer 2).
+It compiles against and should work with Linux 2.6.20 - 2.6.31. Supporting older
+versions is not planned, but it's probably easy to backport it. If you work on a
+backport, feel free to contact us.  :-)
+
+COMPILE
+-------
+To compile against your currently installed kernel, just type:
+
+# make
+
+if you want to compile against some other kernel, use:
+
+# make KERNELPATH=/path/to/kernel
+
+USAGE
+-----
+
+insmod the batman-adv.ko in your kernel:
+
+# insmod batman-adv.ko
+
+the module is now waiting for activation. You must add some interfaces
+on which batman can operate. Each interface must be added separately:
+
+# echo wlan0 > /proc/net/batman-adv/interfaces
+
+( # echo wlan1 > /proc/net/batman-adv/interfaces )
+( # echo eth0 > /proc/net/batman-adv/interfaces )
+( ... )
+
+Now batman starts broadcasting on this interface.
+You can now view the table of originators (mesh participants) with:
+
+# cat /proc/net/batman-adv/originators
+
+The module will create a new interface "bat0", which can be used as a
+regular interface:
+
+# ifconfig bat0 inet 192.168.0.1 up
+# ping 192.168.0.2
+...
+
+If you want topology visualization, your meshnode must be configured
+as VIS-server:
+
+# echo "server" > /proc/net/batman-adv/vis
+
+Each node is either configured as "server" or as "client" (default:
+"client"). Clients send their topology data to the server next to them,
+and server synchronize with other servers. If there is no server
+configured (default) within the mesh, no topology information will be
+transmitted. With these "synchronizing servers", there can be 1 or
+more vis servers sharing the same (or at least very similar) data.
+
+When configured as server, you can get a topology snapshot of your mesh:
+
+# cat /proc/net/batman-adv/vis
+
+This output format is a graphviz formatted text file which can be
+processed with graphviz-tools like dot.
+The labels are similar/compatible to the ETX metric, 1.0 means perfect
+connection (100%), 2.0 means 50%, 3.0 means 33% and so on.
+
+Alternatively, a JSON output format is available. The format can be set
+using by writing either "dot_draw" or "json" into the vis_format file.
+"dot_draw" is selected by default.
+
+echo "json" > /proc/net/batman-adv/vis_format
+
+In very mobile scenarios, you might want to adjust the originator
+interval to a lower value. This will make the mesh more responsive to
+topology changes, but will also increase the overhead. Please make sure
+that all nodes in your mesh use the same interval. The default value
+is 1000 ms (1 second).
+
+# echo 1000 > /proc/net/batman-adv/orig_interval
+
+To deactivate batman, do:
+
+# echo "" > /proc/net/batman-adv/interfaces
+
+BATCTL
+------
+
+B.A.T.M.A.N.  advanced  operates on layer 2 and thus all hosts partici-
+pating in the virtual switch are completely transparent for all  proto-
+cols above layer 2. Therefore the common diagnosis tools do not work as
+expected. To overcome these problems batctl was created. At the  moment
+the  batctl contains ping, traceroute, tcpdump and interfaces to the
+kernel module settings.
+
+For more information, please see the manpage (man batctl).
+
+batctl is available on http://www.open-mesh.net/
+
+CONTACT
+-------
+
+Please send us comments, experiences, questions, anything :)
+
+IRC:             #batman on irc.freenode.org
+Mailing-list:    b.a.t.m.a.n@open-mesh.net
+(subscription at https://list.open-mesh.net/mm/listinfo/b.a.t.m.a.n )
+
+You can also contact the Authors:
+
+Marek Lindner <lindner_marek@yahoo.de>
+Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
diff --git a/drivers/staging/batman-adv/TODO b/drivers/staging/batman-adv/TODO
new file mode 100644
index 0000000..ea6dcf9
--- /dev/null
+++ b/drivers/staging/batman-adv/TODO
@@ -0,0 +1,51 @@
+=> proc interface
+* implement new interface to add/delete interfaces and setting options
+* /proc/sys/net/batman-adv/ as main folder
+* in interfaces/ list every available interface of the host
+* each interfaces/$iface/ contains the following files:
+-> enable (def: 0) [add/remove this interface to batman-adv]
+-> ogm_interval (def: 1000) [ogm interval of that interface]
+-> context (def: bat0) [later we want to support multiple mesh instances via
+-> bat0/bat1/bat2/..]
+-> status (read-only) [outputs the interface status from batman's
+-> perspective]
+* in mesh/batX/ list every available mesh subnet
+-> vis_server (def: 0) [enable/disable vis server for that mesh]
+-> vis_data (read-only) [outputs the vis data in a raw format]
+-> aggregate_ogm (def: 1) [enable/disable ogm aggregation for that mesh]
+-> originators (read-only) [outputs the originator table]
+-> transtable_global (read-only) [outputs the global translation table]
+-> transtable_local (read-only) [outputs the local translation table]
+
+=> vis "raw" data output
+* the raw format shall replace dot draw / json to offer a neutral that can
+* be converted
+* the format (comma seperated entries):
+-> "mac" -> mac address of an originator (each line begins with it)
+-> "TQ mac value" -> src mac's link quality towards mac address
+-> "HNA mac" -> HNA announced by source mac
+-> "PRIMARY" -> this is a primary interface
+-> "SEC mac" -> secondary mac address of source (requires preceeding
+-> PRIMARY)
+
+=> logging
+* the log level LOG_TYPE_CRIT, LOG_TYPE_WARN & LOG_TYPE_NOTICE will be
+* unified to use printk
+* LOG_TYPE_BATMAN & LOG_TYPE_ROUTES will also use printk but only after the
+* internal debug level has been raised
+* the internal debug level can be modified using a module parameter (debug)
+* or at run time via /sys/module/batman-adv/parameters/debug
+* make use of printk %pM support instead of converting mac addresses
+* manually
+
+=> strip out all backward compatibility support to older kernels
+   (only found in compat.h)
+
+=> fix checkpatch.pl errors
+
+Please send all patches to:
+	Marek Lindner <lindner_marek@yahoo.de>
+	Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
+	Andrew Lunn <andrew@lunn.ch>
+	b.a.t.m.a.n@lists.open-mesh.net
+	Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/drivers/staging/batman-adv/aggregation.c b/drivers/staging/batman-adv/aggregation.c
new file mode 100644
index 0000000..9c6e681
--- /dev/null
+++ b/drivers/staging/batman-adv/aggregation.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "main.h"
+#include "aggregation.h"
+#include "send.h"
+#include "routing.h"
+
+/* calculate the size of the hna information for a given packet */
+static int hna_len(struct batman_packet *batman_packet)
+{
+	return batman_packet->num_hna * ETH_ALEN;
+}
+
+/* return true if new_packet can be aggregated with forw_packet */
+static bool can_aggregate_with(struct batman_packet *new_batman_packet,
+			       int packet_len,
+			       unsigned long send_time,
+			       bool directlink,
+			       struct batman_if *if_incoming,
+			       struct forw_packet *forw_packet)
+{
+	struct batman_packet *batman_packet =
+		(struct batman_packet *)forw_packet->packet_buff;
+	int aggregated_bytes = forw_packet->packet_len + packet_len;
+
+	/**
+	 * we can aggregate the current packet to this aggregated packet
+	 * if:
+	 *
+	 * - the send time is within our MAX_AGGREGATION_MS time
+	 * - the resulting packet wont be bigger than
+	 *   MAX_AGGREGATION_BYTES
+	 */
+
+	if (time_before(send_time, forw_packet->send_time) &&
+	    (aggregated_bytes <= MAX_AGGREGATION_BYTES)) {
+
+		/**
+		 * check aggregation compatibility
+		 * -> direct link packets are broadcasted on
+		 *    their interface only
+		 * -> aggregate packet if the current packet is
+		 *    a "global" packet as well as the base
+		 *    packet
+		 */
+
+		/* packets without direct link flag and high TTL
+		 * are flooded through the net  */
+		if ((!directlink) &&
+		    (!(batman_packet->flags & DIRECTLINK)) &&
+		    (batman_packet->ttl != 1) &&
+
+		    /* own packets originating non-primary
+		     * interfaces leave only that interface */
+		    ((!forw_packet->own) ||
+		     (forw_packet->if_incoming->if_num == 0)))
+			return true;
+
+		/* if the incoming packet is sent via this one
+		 * interface only - we still can aggregate */
+		if ((directlink) &&
+		    (new_batman_packet->ttl == 1) &&
+		    (forw_packet->if_incoming == if_incoming))
+			return true;
+
+	}
+
+	return false;
+}
+
+/* create a new aggregated packet and add this packet to it */
+static void new_aggregated_packet(unsigned char *packet_buff,
+			   int packet_len,
+			   unsigned long send_time,
+			   bool direct_link,
+			   struct batman_if *if_incoming,
+			   int own_packet)
+{
+	struct forw_packet *forw_packet_aggr;
+
+	forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
+	if (!forw_packet_aggr)
+		return;
+
+	forw_packet_aggr->packet_buff = kmalloc(MAX_AGGREGATION_BYTES,
+						GFP_ATOMIC);
+	if (!forw_packet_aggr->packet_buff) {
+		kfree(forw_packet_aggr);
+		return;
+	}
+
+	INIT_HLIST_NODE(&forw_packet_aggr->list);
+
+	forw_packet_aggr->packet_len = packet_len;
+	memcpy(forw_packet_aggr->packet_buff,
+	       packet_buff,
+	       forw_packet_aggr->packet_len);
+
+	forw_packet_aggr->own = own_packet;
+	forw_packet_aggr->if_incoming = if_incoming;
+	forw_packet_aggr->num_packets = 0;
+	forw_packet_aggr->direct_link_flags = 0;
+	forw_packet_aggr->send_time = send_time;
+
+	/* save packet direct link flag status */
+	if (direct_link)
+		forw_packet_aggr->direct_link_flags |= 1;
+
+	/* add new packet to packet list */
+	spin_lock(&forw_bat_list_lock);
+	hlist_add_head(&forw_packet_aggr->list, &forw_bat_list);
+	spin_unlock(&forw_bat_list_lock);
+
+	/* start timer for this packet */
+	INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
+			  send_outstanding_bat_packet);
+	queue_delayed_work(bat_event_workqueue,
+			   &forw_packet_aggr->delayed_work,
+			   send_time - jiffies);
+}
+
+/* aggregate a new packet into the existing aggregation */
+static void aggregate(struct forw_packet *forw_packet_aggr,
+		      unsigned char *packet_buff,
+		      int packet_len,
+		      bool direct_link)
+{
+	memcpy((forw_packet_aggr->packet_buff + forw_packet_aggr->packet_len),
+	       packet_buff, packet_len);
+	forw_packet_aggr->packet_len += packet_len;
+	forw_packet_aggr->num_packets++;
+
+	/* save packet direct link flag status */
+	if (direct_link)
+		forw_packet_aggr->direct_link_flags |=
+			(1 << forw_packet_aggr->num_packets);
+}
+
+void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len,
+			    struct batman_if *if_incoming, char own_packet,
+			    unsigned long send_time)
+{
+	/**
+	 * _aggr -> pointer to the packet we want to aggregate with
+	 * _pos -> pointer to the position in the queue
+	 */
+	struct forw_packet *forw_packet_aggr = NULL, *forw_packet_pos = NULL;
+	struct hlist_node *tmp_node;
+	struct batman_packet *batman_packet =
+		(struct batman_packet *)packet_buff;
+	bool direct_link = batman_packet->flags & DIRECTLINK ? 1 : 0;
+
+	/* find position for the packet in the forward queue */
+	spin_lock(&forw_bat_list_lock);
+	/* own packets are not to be aggregated */
+	if ((atomic_read(&aggregation_enabled)) && (!own_packet)) {
+		hlist_for_each_entry(forw_packet_pos, tmp_node, &forw_bat_list,
+				     list) {
+			if (can_aggregate_with(batman_packet,
+					       packet_len,
+					       send_time,
+					       direct_link,
+					       if_incoming,
+					       forw_packet_pos)) {
+				forw_packet_aggr = forw_packet_pos;
+				break;
+			}
+		}
+	}
+
+	/* nothing to aggregate with - either aggregation disabled or no
+	 * suitable aggregation packet found */
+	if (forw_packet_aggr == NULL) {
+		/* the following section can run without the lock */
+		spin_unlock(&forw_bat_list_lock);
+		new_aggregated_packet(packet_buff, packet_len,
+				      send_time, direct_link,
+				      if_incoming, own_packet);
+	} else {
+		aggregate(forw_packet_aggr,
+			  packet_buff, packet_len,
+			  direct_link);
+		spin_unlock(&forw_bat_list_lock);
+	}
+}
+
+/* unpack the aggregated packets and process them one by one */
+void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
+			     int packet_len, struct batman_if *if_incoming)
+{
+	struct batman_packet *batman_packet;
+	int buff_pos = 0;
+	unsigned char *hna_buff;
+
+	batman_packet = (struct batman_packet *)packet_buff;
+
+	while (aggregated_packet(buff_pos, packet_len,
+				 batman_packet->num_hna)) {
+
+		/* network to host order for our 16bit seqno, and the
+		   orig_interval. */
+		batman_packet->seqno = ntohs(batman_packet->seqno);
+
+		hna_buff = packet_buff + buff_pos + BAT_PACKET_LEN;
+		receive_bat_packet(ethhdr, batman_packet,
+				   hna_buff, hna_len(batman_packet),
+				   if_incoming);
+
+		buff_pos += BAT_PACKET_LEN + hna_len(batman_packet);
+		batman_packet = (struct batman_packet *)
+			(packet_buff + buff_pos);
+	}
+}
diff --git a/drivers/staging/batman-adv/aggregation.h b/drivers/staging/batman-adv/aggregation.h
new file mode 100644
index 0000000..6da8df9
--- /dev/null
+++ b/drivers/staging/batman-adv/aggregation.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "main.h"
+
+/* is there another aggregated packet here? */
+static inline int aggregated_packet(int buff_pos, int packet_len, int num_hna)
+{
+	int next_buff_pos = buff_pos + BAT_PACKET_LEN + (num_hna * ETH_ALEN);
+
+	return (next_buff_pos <= packet_len) &&
+		(next_buff_pos <= MAX_AGGREGATION_BYTES);
+}
+
+void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len,
+			    struct batman_if *if_outgoing, char own_packet,
+			    unsigned long send_time);
+void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
+			     int packet_len, struct batman_if *if_incoming);
diff --git a/drivers/staging/batman-adv/bitarray.c b/drivers/staging/batman-adv/bitarray.c
new file mode 100644
index 0000000..3c67f5f
--- /dev/null
+++ b/drivers/staging/batman-adv/bitarray.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2006-2009 B.A.T.M.A.N. contributors:
+ *
+ * Simon Wunderlich, Marek Lindner
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "main.h"
+#include "bitarray.h"
+#include "log.h"
+
+/* returns true if the corresponding bit in the given seq_bits indicates true
+ * and curr_seqno is within range of last_seqno */
+uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint16_t last_seqno,
+		       uint16_t curr_seqno)
+{
+	int16_t diff, word_offset, word_num;
+
+	diff = last_seqno - curr_seqno;
+	if (diff < 0 || diff >= TQ_LOCAL_WINDOW_SIZE) {
+		return 0;
+	} else {
+		/* which word */
+		word_num = (last_seqno - curr_seqno) / WORD_BIT_SIZE;
+		/* which position in the selected word */
+		word_offset = (last_seqno - curr_seqno) % WORD_BIT_SIZE;
+
+		if (seq_bits[word_num] & 1 << word_offset)
+			return 1;
+		else
+			return 0;
+	}
+}
+
+/* turn corresponding bit on, so we can remember that we got the packet */
+void bit_mark(TYPE_OF_WORD *seq_bits, int32_t n)
+{
+	int32_t word_offset, word_num;
+
+	/* if too old, just drop it */
+	if (n < 0 || n >= TQ_LOCAL_WINDOW_SIZE)
+		return;
+
+	/* which word */
+	word_num = n / WORD_BIT_SIZE;
+	/* which position in the selected word */
+	word_offset = n % WORD_BIT_SIZE;
+
+	seq_bits[word_num] |= 1 << word_offset;	/* turn the position on */
+}
+
+/* shift the packet array by n places. */
+void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n)
+{
+	int32_t word_offset, word_num;
+	int32_t i;
+
+	if (n <= 0)
+		return;
+
+	word_offset = n % WORD_BIT_SIZE;/* shift how much inside each word */
+	word_num = n / WORD_BIT_SIZE;	/* shift over how much (full) words */
+
+	for (i = NUM_WORDS - 1; i > word_num; i--) {
+		/* going from old to new, so we don't overwrite the data we copy
+		 * from.
+		 *
+		 * left is high, right is low: FEDC BA98 7654 3210
+		 *	                                  ^^ ^^
+		 *                             vvvv
+		 * ^^^^ = from, vvvvv =to, we'd have word_num==1 and
+		 * word_offset==WORD_BIT_SIZE/2 ????? in this example.
+		 * (=24 bits)
+		 *
+		 * our desired output would be: 9876 5432 1000 0000
+		 * */
+
+		seq_bits[i] =
+			(seq_bits[i - word_num] << word_offset) +
+			/* take the lower port from the left half, shift it left
+			 * to its final position */
+			(seq_bits[i - word_num - 1] >>
+			 (WORD_BIT_SIZE-word_offset));
+		/* and the upper part of the right half and shift it left to
+		 * it's position */
+		/* for our example that would be: word[0] = 9800 + 0076 =
+		 * 9876 */
+	}
+	/* now for our last word, i==word_num, we only have the it's "left"
+	 * half. that's the 1000 word in our example.*/
+
+	seq_bits[i] = (seq_bits[i - word_num] << word_offset);
+
+	/* pad the rest with 0, if there is anything */
+	i--;
+
+	for (; i >= 0; i--)
+		seq_bits[i] = 0;
+}
+
+
+/* receive and process one packet, returns 1 if received seq_num is considered
+ * new, 0 if old  */
+char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff,
+		    int8_t set_mark)
+{
+	int i;
+
+	/* we already got a sequence number higher than this one, so we just
+	 * mark it. this should wrap around the integer just fine */
+	if ((seq_num_diff < 0) && (seq_num_diff >= -TQ_LOCAL_WINDOW_SIZE)) {
+		if (set_mark)
+			bit_mark(seq_bits, -seq_num_diff);
+		return 0;
+	}
+
+	/* it seems we missed a lot of packets or the other host restarted */
+	if ((seq_num_diff > TQ_LOCAL_WINDOW_SIZE) ||
+	    (seq_num_diff < -TQ_LOCAL_WINDOW_SIZE)) {
+
+		if (seq_num_diff > TQ_LOCAL_WINDOW_SIZE)
+			debug_log(LOG_TYPE_BATMAN,
+				  "We missed a lot of packets (%i) !\n",
+				  seq_num_diff-1);
+
+		if (-seq_num_diff > TQ_LOCAL_WINDOW_SIZE)
+			debug_log(LOG_TYPE_BATMAN,
+				  "Other host probably restarted !\n");
+
+		for (i = 0; i < NUM_WORDS; i++)
+			seq_bits[i] = 0;
+
+		if (set_mark)
+			seq_bits[0] = 1;  /* we only have the latest packet */
+	} else {
+		bit_shift(seq_bits, seq_num_diff);
+
+		if (set_mark)
+			bit_mark(seq_bits, 0);
+	}
+
+	return 1;
+}
+
+/* count the hamming weight, how many good packets did we receive? just count
+ * the 1's. The inner loop uses the Kernighan algorithm, see
+ * http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan
+ */
+int bit_packet_count(TYPE_OF_WORD *seq_bits)
+{
+	int i, hamming = 0;
+	TYPE_OF_WORD word;
+
+	for (i = 0; i < NUM_WORDS; i++) {
+		word = seq_bits[i];
+
+		while (word) {
+			word &= word-1;
+			hamming++;
+		}
+	}
+	return hamming;
+}
diff --git a/drivers/staging/batman-adv/bitarray.h b/drivers/staging/batman-adv/bitarray.h
new file mode 100644
index 0000000..ec72dd7
--- /dev/null
+++ b/drivers/staging/batman-adv/bitarray.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2006-2009 B.A.T.M.A.N. contributors:
+ *
+ * Simon Wunderlich, Marek Lindner
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+
+/* you should choose something big, if you don't want to waste cpu */
+#define TYPE_OF_WORD unsigned long
+#define WORD_BIT_SIZE (sizeof(TYPE_OF_WORD) * 8)
+
+/* returns true if the corresponding bit in the given seq_bits indicates true
+ * and curr_seqno is within range of last_seqno */
+uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint16_t last_seqno,
+					   uint16_t curr_seqno);
+
+/* turn corresponding bit on, so we can remember that we got the packet */
+void bit_mark(TYPE_OF_WORD *seq_bits, int32_t n);
+
+/* shift the packet array by n places. */
+void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n);
+
+
+/* receive and process one packet, returns 1 if received seq_num is considered
+ * new, 0 if old  */
+char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff,
+					int8_t set_mark);
+
+/* count the hamming weight, how many good packets did we receive? */
+int  bit_packet_count(TYPE_OF_WORD *seq_bits);
diff --git a/drivers/staging/batman-adv/compat.h b/drivers/staging/batman-adv/compat.h
new file mode 100644
index 0000000..f4e0a45
--- /dev/null
+++ b/drivers/staging/batman-adv/compat.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ *
+ * This file contains macros for maintaining compatibility with older versions
+ * of the Linux kernel.
+ */
+
+#include <linux/version.h>	/* LINUX_VERSION_CODE */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
+
+#define skb_set_network_header(_skb, _offset) \
+	do { (_skb)->nh.raw = (_skb)->data + (_offset); } while (0)
+
+#define skb_reset_mac_header(_skb) \
+	do { (_skb)->mac.raw = (_skb)->data; } while (0)
+
+#define list_first_entry(ptr, type, member) \
+	list_entry((ptr)->next, type, member)
+
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) */
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
+
+#define device_create(_cls, _parent, _devt, _device, _fmt) \
+	class_device_create(_cls, _parent, _devt, _device, _fmt)
+
+#define device_destroy(_cls, _device) \
+	class_device_destroy(_cls, _device)
+
+#else
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27)
+
+#define device_create(_cls, _parent, _devt, _device, _fmt) \
+	device_create_drvdata(_cls, _parent, _devt, _device, _fmt)
+
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) */
+
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
+
+#define cancel_delayed_work_sync(wq) cancel_rearming_delayed_work(wq)
+
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
+#define strict_strtoul(cp, base, res) \
+	({ \
+	int ret = 0; \
+	char *endp; \
+	*res = simple_strtoul(cp, &endp, base); \
+	if (cp == endp) \
+		ret = -EINVAL; \
+	ret; \
+})
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) */
diff --git a/drivers/staging/batman-adv/device.c b/drivers/staging/batman-adv/device.c
new file mode 100644
index 0000000..1e7d1f8
--- /dev/null
+++ b/drivers/staging/batman-adv/device.c
@@ -0,0 +1,337 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "main.h"
+#include "device.h"
+#include "log.h"
+#include "send.h"
+#include "types.h"
+#include "hash.h"
+
+#include "compat.h"
+
+static struct class *batman_class;
+
+static int Major;	/* Major number assigned to our device driver */
+
+static const struct file_operations fops = {
+	.open = bat_device_open,
+	.release = bat_device_release,
+	.read = bat_device_read,
+	.write = bat_device_write,
+	.poll = bat_device_poll,
+};
+
+static struct device_client *device_client_hash[256];
+
+void bat_device_init(void)
+{
+	int i;
+
+	for (i = 0; i < 256; i++)
+		device_client_hash[i] = NULL;
+}
+
+int bat_device_setup(void)
+{
+	int tmp_major;
+
+	if (Major)
+		return 1;
+
+	/* register our device - kernel assigns a free major number */
+	tmp_major = register_chrdev(0, DRIVER_DEVICE, &fops);
+	if (tmp_major < 0) {
+		debug_log(LOG_TYPE_WARN, "Registering the character device failed with %d\n",
+			  tmp_major);
+		return 0;
+	}
+
+	batman_class = class_create(THIS_MODULE, "batman-adv");
+
+	if (IS_ERR(batman_class)) {
+		debug_log(LOG_TYPE_WARN, "Could not register class 'batman-adv' \n");
+		return 0;
+	}
+
+	device_create(batman_class, NULL, MKDEV(tmp_major, 0), NULL,
+		      "batman-adv");
+
+	Major = tmp_major;
+	return 1;
+}
+
+void bat_device_destroy(void)
+{
+	if (!Major)
+		return;
+
+	device_destroy(batman_class, MKDEV(Major, 0));
+	class_destroy(batman_class);
+
+	/* Unregister the device */
+	unregister_chrdev(Major, DRIVER_DEVICE);
+
+	Major = 0;
+}
+
+int bat_device_open(struct inode *inode, struct file *file)
+{
+	unsigned int i;
+	struct device_client *device_client;
+
+	device_client = kmalloc(sizeof(struct device_client), GFP_KERNEL);
+
+	if (!device_client)
+		return -ENOMEM;
+
+	for (i = 0; i < 256; i++) {
+		if (!device_client_hash[i]) {
+			device_client_hash[i] = device_client;
+			break;
+		}
+	}
+
+	if (device_client_hash[i] != device_client) {
+		debug_log(LOG_TYPE_WARN, "Error - can't add another packet client: maximum number of clients reached \n");
+		kfree(device_client);
+		return -EXFULL;
+	}
+
+	INIT_LIST_HEAD(&device_client->queue_list);
+	device_client->queue_len = 0;
+	device_client->index = i;
+	device_client->lock = __SPIN_LOCK_UNLOCKED(device_client->lock);
+	init_waitqueue_head(&device_client->queue_wait);
+
+	file->private_data = device_client;
+
+	inc_module_count();
+	return 0;
+}
+
+int bat_device_release(struct inode *inode, struct file *file)
+{
+	struct device_client *device_client =
+		(struct device_client *)file->private_data;
+	struct device_packet *device_packet;
+	struct list_head *list_pos, *list_pos_tmp;
+
+	spin_lock(&device_client->lock);
+
+	/* for all packets in the queue ... */
+	list_for_each_safe(list_pos, list_pos_tmp, &device_client->queue_list) {
+		device_packet = list_entry(list_pos,
+					   struct device_packet, list);
+
+		list_del(list_pos);
+		kfree(device_packet);
+	}
+
+	device_client_hash[device_client->index] = NULL;
+	spin_unlock(&device_client->lock);
+
+	kfree(device_client);
+	dec_module_count();
+
+	return 0;
+}
+
+ssize_t bat_device_read(struct file *file, char __user *buf, size_t count,
+			loff_t *ppos)
+{
+	struct device_client *device_client =
+		(struct device_client *)file->private_data;
+	struct device_packet *device_packet;
+	int error;
+
+	if ((file->f_flags & O_NONBLOCK) && (device_client->queue_len == 0))
+		return -EAGAIN;
+
+	if ((!buf) || (count < sizeof(struct icmp_packet)))
+		return -EINVAL;
+
+	if (!access_ok(VERIFY_WRITE, buf, count))
+		return -EFAULT;
+
+	error = wait_event_interruptible(device_client->queue_wait,
+					 device_client->queue_len);
+
+	if (error)
+		return error;
+
+	spin_lock(&device_client->lock);
+
+	device_packet = list_first_entry(&device_client->queue_list,
+					 struct device_packet, list);
+	list_del(&device_packet->list);
+	device_client->queue_len--;
+
+	spin_unlock(&device_client->lock);
+
+	error = __copy_to_user(buf, &device_packet->icmp_packet,
+			       sizeof(struct icmp_packet));
+
+	kfree(device_packet);
+
+	if (error)
+		return error;
+
+	return sizeof(struct icmp_packet);
+}
+
+ssize_t bat_device_write(struct file *file, const char __user *buff,
+			 size_t len, loff_t *off)
+{
+	struct device_client *device_client =
+		(struct device_client *)file->private_data;
+	struct icmp_packet icmp_packet;
+	struct orig_node *orig_node;
+	struct batman_if *batman_if;
+
+	if (len < sizeof(struct icmp_packet)) {
+		debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: invalid packet size\n");
+		return -EINVAL;
+	}
+
+	if (!access_ok(VERIFY_READ, buff, sizeof(struct icmp_packet)))
+		return -EFAULT;
+
+	if (__copy_from_user(&icmp_packet, buff, sizeof(icmp_packet)))
+		return -EFAULT;
+
+	if (icmp_packet.packet_type != BAT_ICMP) {
+		debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n");
+		return -EINVAL;
+	}
+
+	if (icmp_packet.msg_type != ECHO_REQUEST) {
+		debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n");
+		return -EINVAL;
+	}
+
+	icmp_packet.uid = device_client->index;
+
+	if (icmp_packet.version != COMPAT_VERSION) {
+		icmp_packet.msg_type = PARAMETER_PROBLEM;
+		icmp_packet.ttl = COMPAT_VERSION;
+		bat_device_add_packet(device_client, &icmp_packet);
+		goto out;
+	}
+
+	if (atomic_read(&module_state) != MODULE_ACTIVE)
+		goto dst_unreach;
+
+	spin_lock(&orig_hash_lock);
+	orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet.dst));
+
+	if (!orig_node)
+		goto unlock;
+
+	if (!orig_node->router)
+		goto unlock;
+
+	batman_if = orig_node->batman_if;
+
+	if (!batman_if)
+		goto unlock;
+
+	memcpy(icmp_packet.orig,
+	       batman_if->net_dev->dev_addr,
+	       ETH_ALEN);
+
+	send_raw_packet((unsigned char *)&icmp_packet,
+			sizeof(struct icmp_packet),
+			batman_if, orig_node->router->addr);
+
+	spin_unlock(&orig_hash_lock);
+	goto out;
+
+unlock:
+	spin_unlock(&orig_hash_lock);
+dst_unreach:
+	icmp_packet.msg_type = DESTINATION_UNREACHABLE;
+	bat_device_add_packet(device_client, &icmp_packet);
+out:
+	return len;
+}
+
+unsigned int bat_device_poll(struct file *file, poll_table *wait)
+{
+	struct device_client *device_client =
+		(struct device_client *)file->private_data;
+
+	poll_wait(file, &device_client->queue_wait, wait);
+
+	if (device_client->queue_len > 0)
+		return POLLIN | POLLRDNORM;
+
+	return 0;
+}
+
+void bat_device_add_packet(struct device_client *device_client,
+			   struct icmp_packet *icmp_packet)
+{
+	struct device_packet *device_packet;
+
+	device_packet = kmalloc(sizeof(struct device_packet), GFP_KERNEL);
+
+	if (!device_packet)
+		return;
+
+	INIT_LIST_HEAD(&device_packet->list);
+	memcpy(&device_packet->icmp_packet, icmp_packet,
+	       sizeof(struct icmp_packet));
+
+	spin_lock(&device_client->lock);
+
+	/* while waiting for the lock the device_client could have been
+	 * deleted */
+	if (!device_client_hash[icmp_packet->uid]) {
+		spin_unlock(&device_client->lock);
+		kfree(device_packet);
+		return;
+	}
+
+	list_add_tail(&device_packet->list, &device_client->queue_list);
+	device_client->queue_len++;
+
+	if (device_client->queue_len > 100) {
+		device_packet = list_first_entry(&device_client->queue_list,
+						 struct device_packet, list);
+
+		list_del(&device_packet->list);
+		kfree(device_packet);
+		device_client->queue_len--;
+	}
+
+	spin_unlock(&device_client->lock);
+
+	wake_up(&device_client->queue_wait);
+}
+
+void bat_device_receive_packet(struct icmp_packet *icmp_packet)
+{
+	struct device_client *hash = device_client_hash[icmp_packet->uid];
+
+	if (hash)
+		bat_device_add_packet(hash, icmp_packet);
+}
diff --git a/drivers/staging/batman-adv/device.h b/drivers/staging/batman-adv/device.h
new file mode 100644
index 0000000..46c0f44
--- /dev/null
+++ b/drivers/staging/batman-adv/device.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "types.h"
+
+void bat_device_init(void);
+int bat_device_setup(void);
+void bat_device_destroy(void);
+int bat_device_open(struct inode *inode, struct file *file);
+int bat_device_release(struct inode *inode, struct file *file);
+ssize_t bat_device_read(struct file *file, char __user *buf, size_t count,
+			loff_t *ppos);
+ssize_t bat_device_write(struct file *file, const char __user *buff,
+			 size_t len, loff_t *off);
+unsigned int bat_device_poll(struct file *file, poll_table *wait);
+void bat_device_add_packet(struct device_client *device_client,
+			   struct icmp_packet *icmp_packet);
+void bat_device_receive_packet(struct icmp_packet *icmp_packet);
diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c
new file mode 100644
index 0000000..5ea35da
--- /dev/null
+++ b/drivers/staging/batman-adv/hard-interface.c
@@ -0,0 +1,451 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "main.h"
+#include "hard-interface.h"
+#include "log.h"
+#include "soft-interface.h"
+#include "send.h"
+#include "translation-table.h"
+#include "routing.h"
+#include "hash.h"
+#include "compat.h"
+
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
+
+static char avail_ifs;
+static char active_ifs;
+
+static void hardif_free_interface(struct rcu_head *rcu);
+
+static struct batman_if *get_batman_if_by_name(char *name)
+{
+	struct batman_if *batman_if;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(batman_if, &if_list, list) {
+		if (strncmp(batman_if->dev, name, IFNAMSIZ) == 0)
+			goto out;
+	}
+
+	batman_if = NULL;
+
+out:
+	rcu_read_unlock();
+	return batman_if;
+}
+
+int hardif_min_mtu(void)
+{
+	struct batman_if *batman_if;
+	/* allow big frames if all devices are capable to do so
+	 * (have MTU > 1500 + BAT_HEADER_LEN) */
+	int min_mtu = ETH_DATA_LEN;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(batman_if, &if_list, list) {
+		if ((batman_if->if_active == IF_ACTIVE) ||
+		    (batman_if->if_active == IF_TO_BE_ACTIVATED))
+			min_mtu = MIN(batman_if->net_dev->mtu - BAT_HEADER_LEN,
+				      min_mtu);
+	}
+	rcu_read_unlock();
+
+	return min_mtu;
+}
+
+static void check_known_mac_addr(uint8_t *addr)
+{
+	struct batman_if *batman_if;
+	char mac_string[ETH_STR_LEN];
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(batman_if, &if_list, list) {
+		if ((batman_if->if_active != IF_ACTIVE) &&
+		    (batman_if->if_active != IF_TO_BE_ACTIVATED))
+			continue;
+
+		if (!compare_orig(batman_if->net_dev->dev_addr, addr))
+			continue;
+
+		addr_to_string(mac_string, addr);
+		debug_log(LOG_TYPE_WARN, "The newly added mac address (%s) already exists on: %s\n",
+		          mac_string, batman_if->dev);
+		debug_log(LOG_TYPE_WARN, "It is strongly recommended to keep mac addresses unique to avoid problems!\n");
+	}
+	rcu_read_unlock();
+}
+
+/* adjusts the MTU if a new interface with a smaller MTU appeared. */
+void update_min_mtu(void)
+{
+	int min_mtu;
+
+	min_mtu = hardif_min_mtu();
+	if (soft_device->mtu != min_mtu)
+		soft_device->mtu = min_mtu;
+}
+
+/* checks if the interface is up. (returns 1 if it is) */
+static int hardif_is_interface_up(char *dev)
+{
+	struct net_device *net_dev;
+
+	/**
+	 * if we already have an interface in our interface list and
+	 * the current interface is not the primary interface and
+	 * the primary interface is not up and
+	 * the primary interface has never been up - don't activate any
+	 * secondary interface !
+	 */
+
+	rcu_read_lock();
+	if ((!list_empty(&if_list)) &&
+	    strncmp(((struct batman_if *)if_list.next)->dev, dev, IFNAMSIZ) &&
+	    !(((struct batman_if *)if_list.next)->if_active == IF_ACTIVE) &&
+	    !(((struct batman_if *)if_list.next)->if_active == IF_TO_BE_ACTIVATED) &&
+	    (!main_if_was_up())) {
+		rcu_read_unlock();
+		goto end;
+	}
+	rcu_read_unlock();
+
+#ifdef __NET_NET_NAMESPACE_H
+	net_dev = dev_get_by_name(&init_net, dev);
+#else
+	net_dev = dev_get_by_name(dev);
+#endif
+	if (!net_dev)
+		goto end;
+
+	if (!(net_dev->flags & IFF_UP))
+		goto failure;
+
+	dev_put(net_dev);
+	return 1;
+
+failure:
+	dev_put(net_dev);
+end:
+	return 0;
+}
+
+/* deactivates the interface. */
+void hardif_deactivate_interface(struct batman_if *batman_if)
+{
+	if (batman_if->if_active != IF_ACTIVE)
+		return;
+
+	if (batman_if->raw_sock)
+		sock_release(batman_if->raw_sock);
+
+	/**
+	 * batman_if->net_dev has been acquired by dev_get_by_name() in
+	 * proc_interfaces_write() and has to be unreferenced.
+	 */
+
+	if (batman_if->net_dev)
+		dev_put(batman_if->net_dev);
+
+	batman_if->raw_sock = NULL;
+	batman_if->net_dev = NULL;
+
+	batman_if->if_active = IF_INACTIVE;
+	active_ifs--;
+
+	debug_log(LOG_TYPE_NOTICE, "Interface deactivated: %s\n",
+	          batman_if->dev);
+}
+
+/* (re)activate given interface. */
+static void hardif_activate_interface(struct batman_if *batman_if)
+{
+	struct sockaddr_ll bind_addr;
+	int retval;
+
+	if (batman_if->if_active != IF_INACTIVE)
+		return;
+
+#ifdef __NET_NET_NAMESPACE_H
+	batman_if->net_dev = dev_get_by_name(&init_net, batman_if->dev);
+#else
+	batman_if->net_dev = dev_get_by_name(batman_if->dev);
+#endif
+	if (!batman_if->net_dev)
+		goto dev_err;
+
+	retval = sock_create_kern(PF_PACKET, SOCK_RAW,
+				  __constant_htons(ETH_P_BATMAN),
+				  &batman_if->raw_sock);
+
+	if (retval < 0) {
+		debug_log(LOG_TYPE_WARN, "Can't create raw socket: %i\n",
+			  retval);
+		goto sock_err;
+	}
+
+	bind_addr.sll_family = AF_PACKET;
+	bind_addr.sll_ifindex = batman_if->net_dev->ifindex;
+	bind_addr.sll_protocol = 0;	/* is set by the kernel */
+
+	retval = kernel_bind(batman_if->raw_sock,
+			     (struct sockaddr *)&bind_addr, sizeof(bind_addr));
+
+	if (retval < 0) {
+		debug_log(LOG_TYPE_WARN, "Can't create bind raw socket: %i\n",
+			  retval);
+		goto bind_err;
+	}
+
+	check_known_mac_addr(batman_if->net_dev->dev_addr);
+
+	batman_if->raw_sock->sk->sk_user_data =
+		batman_if->raw_sock->sk->sk_data_ready;
+	batman_if->raw_sock->sk->sk_data_ready = batman_data_ready;
+
+	addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr);
+
+	memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig,
+	       batman_if->net_dev->dev_addr, ETH_ALEN);
+	memcpy(((struct batman_packet *)(batman_if->packet_buff))->prev_sender,
+	       batman_if->net_dev->dev_addr, ETH_ALEN);
+
+	batman_if->if_active = IF_TO_BE_ACTIVATED;
+	active_ifs++;
+
+	/* save the mac address if it is our primary interface */
+	if (batman_if->if_num == 0)
+		set_main_if_addr(batman_if->net_dev->dev_addr);
+
+	debug_log(LOG_TYPE_NOTICE, "Interface activated: %s\n",
+	          batman_if->dev);
+
+	return;
+
+bind_err:
+	sock_release(batman_if->raw_sock);
+sock_err:
+	dev_put(batman_if->net_dev);
+dev_err:
+	batman_if->raw_sock = NULL;
+	batman_if->net_dev = NULL;
+}
+
+static void hardif_free_interface(struct rcu_head *rcu)
+{
+	struct batman_if *batman_if = container_of(rcu, struct batman_if, rcu);
+
+	kfree(batman_if->packet_buff);
+	kfree(batman_if->dev);
+	kfree(batman_if);
+}
+
+/**
+ * called by
+ *  - echo '' > /proc/.../interfaces
+ *  - modprobe -r batman-adv-core
+ */
+/* removes and frees all interfaces */
+void hardif_remove_interfaces(void)
+{
+	struct batman_if *batman_if = NULL;
+
+	avail_ifs = 0;
+
+	/* no lock needed - we don't delete somewhere else */
+	list_for_each_entry(batman_if, &if_list, list) {
+
+		list_del_rcu(&batman_if->list);
+
+		/* first deactivate interface */
+		if (batman_if->if_active != IF_INACTIVE)
+			hardif_deactivate_interface(batman_if);
+
+		call_rcu(&batman_if->rcu, hardif_free_interface);
+	}
+}
+
+static int resize_orig(struct orig_node *orig_node, int if_num)
+{
+	void *data_ptr;
+
+	data_ptr = kmalloc((if_num + 1) * sizeof(TYPE_OF_WORD) * NUM_WORDS,
+			   GFP_ATOMIC);
+	if (!data_ptr) {
+		debug_log(LOG_TYPE_WARN, "Can't resize orig: out of memory\n");
+		return -1;
+	}
+
+	memcpy(data_ptr, orig_node->bcast_own,
+	       if_num * sizeof(TYPE_OF_WORD) * NUM_WORDS);
+	kfree(orig_node->bcast_own);
+	orig_node->bcast_own = data_ptr;
+
+	data_ptr = kmalloc((if_num + 1) * sizeof(uint8_t), GFP_ATOMIC);
+	if (!data_ptr) {
+		debug_log(LOG_TYPE_WARN, "Can't resize orig: out of memory\n");
+		return -1;
+	}
+
+	memcpy(data_ptr, orig_node->bcast_own_sum, if_num * sizeof(uint8_t));
+	kfree(orig_node->bcast_own_sum);
+	orig_node->bcast_own_sum = data_ptr;
+
+	return 0;
+}
+
+
+/* adds an interface the interface list and activate it, if possible */
+int hardif_add_interface(char *dev, int if_num)
+{
+	struct batman_if *batman_if;
+	struct batman_packet *batman_packet;
+	struct orig_node *orig_node;
+	struct hash_it_t *hashit = NULL;
+
+	batman_if = kmalloc(sizeof(struct batman_if), GFP_KERNEL);
+
+	if (!batman_if) {
+		debug_log(LOG_TYPE_WARN, "Can't add interface (%s): out of memory\n", dev);
+		return -1;
+	}
+
+	batman_if->raw_sock = NULL;
+	batman_if->net_dev = NULL;
+
+	if ((if_num == 0) && (num_hna > 0))
+		batman_if->packet_len = BAT_PACKET_LEN + num_hna * ETH_ALEN;
+	else
+		batman_if->packet_len = BAT_PACKET_LEN;
+
+	batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_KERNEL);
+
+	if (!batman_if->packet_buff) {
+		debug_log(LOG_TYPE_WARN, "Can't add interface packet (%s): out of memory\n", dev);
+		goto out;
+	}
+
+	batman_if->if_num = if_num;
+	batman_if->dev = dev;
+	batman_if->if_active = IF_INACTIVE;
+	INIT_RCU_HEAD(&batman_if->rcu);
+
+	debug_log(LOG_TYPE_NOTICE, "Adding interface: %s\n", dev);
+	avail_ifs++;
+
+	INIT_LIST_HEAD(&batman_if->list);
+
+	batman_packet = (struct batman_packet *)(batman_if->packet_buff);
+	batman_packet->packet_type = BAT_PACKET;
+	batman_packet->version = COMPAT_VERSION;
+	batman_packet->flags = 0x00;
+	batman_packet->ttl = (batman_if->if_num > 0 ? 2 : TTL);
+	batman_packet->flags = 0;
+	batman_packet->tq = TQ_MAX_VALUE;
+	batman_packet->num_hna = 0;
+
+	if (batman_if->packet_len != BAT_PACKET_LEN) {
+		unsigned char *hna_buff;
+		int hna_len;
+
+		hna_buff = batman_if->packet_buff + BAT_PACKET_LEN;
+		hna_len = batman_if->packet_len - BAT_PACKET_LEN;
+		batman_packet->num_hna = hna_local_fill_buffer(hna_buff,
+							       hna_len);
+	}
+
+	atomic_set(&batman_if->seqno, 1);
+
+	/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
+	 * if_num */
+	spin_lock(&orig_hash_lock);
+
+	while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
+		orig_node = hashit->bucket->data;
+		if (resize_orig(orig_node, if_num) == -1) {
+			spin_unlock(&orig_hash_lock);
+			goto out;
+		}
+	}
+
+	spin_unlock(&orig_hash_lock);
+
+	if (!hardif_is_interface_up(batman_if->dev))
+		debug_log(LOG_TYPE_WARN, "Not using interface %s (retrying later): interface not active\n", batman_if->dev);
+	else
+		hardif_activate_interface(batman_if);
+
+	list_add_tail_rcu(&batman_if->list, &if_list);
+
+	/* begin sending originator messages on that interface */
+	schedule_own_packet(batman_if);
+	return 1;
+
+out:
+	if (batman_if->packet_buff)
+		kfree(batman_if->packet_buff);
+	kfree(batman_if);
+	kfree(dev);
+	return -1;
+}
+
+char hardif_get_active_if_num(void)
+{
+	return active_ifs;
+}
+
+static int hard_if_event(struct notifier_block *this,
+                            unsigned long event, void *ptr)
+{
+	struct net_device *dev = (struct net_device *)ptr;
+	struct batman_if *batman_if = get_batman_if_by_name(dev->name);
+
+	if (!batman_if)
+		goto out;
+
+	switch (event) {
+	case NETDEV_GOING_DOWN:
+	case NETDEV_DOWN:
+	case NETDEV_UNREGISTER:
+		hardif_deactivate_interface(batman_if);
+		break;
+	case NETDEV_UP:
+		hardif_activate_interface(batman_if);
+		if ((atomic_read(&module_state) == MODULE_INACTIVE) &&
+		    (hardif_get_active_if_num() > 0)) {
+			activate_module();
+		}
+		break;
+	/* NETDEV_CHANGEADDR - mac address change - what are we doing here ? */
+	default:
+		/* debug_log(LOG_TYPE_CRIT, "hard_if_event: %s %i\n", dev->name, event); */
+		break;
+	};
+
+	update_min_mtu();
+
+out:
+	return NOTIFY_DONE;
+}
+
+struct notifier_block hard_if_notifier = {
+        .notifier_call = hard_if_event,
+};
diff --git a/drivers/staging/batman-adv/hard-interface.h b/drivers/staging/batman-adv/hard-interface.h
new file mode 100644
index 0000000..742358c
--- /dev/null
+++ b/drivers/staging/batman-adv/hard-interface.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#define IF_INACTIVE 0
+#define IF_ACTIVE 1
+/* #define IF_TO_BE_DEACTIVATED 2 - not needed anymore */
+#define IF_TO_BE_ACTIVATED 3
+
+extern struct notifier_block hard_if_notifier;
+
+void hardif_remove_interfaces(void);
+int hardif_add_interface(char *dev, int if_num);
+void hardif_deactivate_interface(struct batman_if *batman_if);
+char hardif_get_active_if_num(void);
+void hardif_check_interfaces_status(void);
+void hardif_check_interfaces_status_wq(struct work_struct *work);
+int hardif_min_mtu(void);
+void update_min_mtu(void);
diff --git a/drivers/staging/batman-adv/hash.c b/drivers/staging/batman-adv/hash.c
new file mode 100644
index 0000000..61cb4a2
--- /dev/null
+++ b/drivers/staging/batman-adv/hash.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright (C) 2006-2009 B.A.T.M.A.N. contributors:
+ *
+ * Simon Wunderlich, Marek Lindner
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "main.h"
+#include "hash.h"
+
+/* clears the hash */
+void hash_init(struct hashtable_t *hash)
+{
+	int i;
+
+	hash->elements = 0;
+
+	for (i = 0 ; i < hash->size; i++)
+		hash->table[i] = NULL;
+}
+
+/* remove the hash structure. if hashdata_free_cb != NULL, this function will be
+ * called to remove the elements inside of the hash.  if you don't remove the
+ * elements, memory might be leaked. */
+void hash_delete(struct hashtable_t *hash, hashdata_free_cb free_cb)
+{
+	struct element_t *bucket, *last_bucket;
+	int i;
+
+	for (i = 0; i < hash->size; i++) {
+		bucket = hash->table[i];
+
+		while (bucket != NULL) {
+			if (free_cb != NULL)
+				free_cb(bucket->data);
+
+			last_bucket = bucket;
+			bucket = bucket->next;
+			kfree(last_bucket);
+		}
+	}
+
+	hash_destroy(hash);
+}
+
+/* free only the hashtable and the hash itself. */
+void hash_destroy(struct hashtable_t *hash)
+{
+	kfree(hash->table);
+	kfree(hash);
+}
+
+/* iterate though the hash. first element is selected with iter_in NULL.  use
+ * the returned iterator to access the elements until hash_it_t returns NULL. */
+struct hash_it_t *hash_iterate(struct hashtable_t *hash,
+			       struct hash_it_t *iter_in)
+{
+	struct hash_it_t *iter;
+
+	if (!hash)
+		return NULL;
+
+	if (iter_in == NULL) {
+		iter = kmalloc(sizeof(struct hash_it_t), GFP_ATOMIC);
+		iter->index = -1;
+		iter->bucket = NULL;
+		iter->prev_bucket = NULL;
+	} else {
+		iter = iter_in;
+	}
+
+	/* sanity checks first (if our bucket got deleted in the last
+	 * iteration): */
+	if (iter->bucket != NULL) {
+		if (iter->first_bucket != NULL) {
+			/* we're on the first element and it got removed after
+			 * the last iteration. */
+			if ((*iter->first_bucket) != iter->bucket) {
+				/* there are still other elements in the list */
+				if ((*iter->first_bucket) != NULL) {
+					iter->prev_bucket = NULL;
+					iter->bucket = (*iter->first_bucket);
+					iter->first_bucket =
+						&hash->table[iter->index];
+					return iter;
+				} else {
+					iter->bucket = NULL;
+				}
+			}
+		} else if (iter->prev_bucket != NULL) {
+			/*
+			* we're not on the first element, and the bucket got
+			* removed after the last iteration.  the last bucket's
+			* next pointer is not pointing to our actual bucket
+			* anymore.  select the next.
+			*/
+			if (iter->prev_bucket->next != iter->bucket)
+				iter->bucket = iter->prev_bucket;
+		}
+	}
+
+	/* now as we are sane, select the next one if there is some */
+	if (iter->bucket != NULL) {
+		if (iter->bucket->next != NULL) {
+			iter->prev_bucket = iter->bucket;
+			iter->bucket = iter->bucket->next;
+			iter->first_bucket = NULL;
+			return iter;
+		}
+	}
+
+	/* if not returned yet, we've reached the last one on the index and have
+	 * to search forward */
+	iter->index++;
+	/* go through the entries of the hash table */
+	while (iter->index < hash->size) {
+		if ((hash->table[iter->index]) != NULL) {
+			iter->prev_bucket = NULL;
+			iter->bucket = hash->table[iter->index];
+			iter->first_bucket = &hash->table[iter->index];
+			return iter;
+		} else {
+			iter->index++;
+		}
+	}
+
+	/* nothing to iterate over anymore */
+	kfree(iter);
+	return NULL;
+}
+
+/* allocates and clears the hash */
+struct hashtable_t *hash_new(int size, hashdata_compare_cb compare,
+			     hashdata_choose_cb choose)
+{
+	struct hashtable_t *hash;
+
+	hash = kmalloc(sizeof(struct hashtable_t) , GFP_ATOMIC);
+
+	if (hash == NULL)
+		return NULL;
+
+	hash->size = size;
+	hash->table = kmalloc(sizeof(struct element_t *) * size, GFP_ATOMIC);
+
+	if (hash->table == NULL) {
+		kfree(hash);
+		return NULL;
+	}
+
+	hash_init(hash);
+
+	hash->compare = compare;
+	hash->choose = choose;
+
+	return hash;
+}
+
+/* adds data to the hashtable. returns 0 on success, -1 on error */
+int hash_add(struct hashtable_t *hash, void *data)
+{
+	int index;
+	struct element_t *bucket, *prev_bucket = NULL;
+
+	if (!hash)
+		return -1;
+
+	index = hash->choose(data, hash->size);
+	bucket = hash->table[index];
+
+	while (bucket != NULL) {
+		if (hash->compare(bucket->data, data))
+			return -1;
+
+		prev_bucket = bucket;
+		bucket = bucket->next;
+	}
+
+	/* found the tail of the list, add new element */
+	bucket = kmalloc(sizeof(struct element_t), GFP_ATOMIC);
+
+	if (bucket == NULL)
+		return -1;
+
+	bucket->data = data;
+	bucket->next = NULL;
+
+	/* and link it */
+	if (prev_bucket == NULL)
+		hash->table[index] = bucket;
+	else
+		prev_bucket->next = bucket;
+
+	hash->elements++;
+	return 0;
+}
+
+/* finds data, based on the key in keydata. returns the found data on success,
+ * or NULL on error */
+void *hash_find(struct hashtable_t *hash, void *keydata)
+{
+	int index;
+	struct element_t *bucket;
+
+	if (!hash)
+		return NULL;
+
+	index = hash->choose(keydata , hash->size);
+	bucket = hash->table[index];
+
+	while (bucket != NULL) {
+		if (hash->compare(bucket->data, keydata))
+			return bucket->data;
+
+		bucket = bucket->next;
+	}
+
+	return NULL;
+}
+
+/* remove bucket (this might be used in hash_iterate() if you already found the
+ * bucket you want to delete and don't need the overhead to find it again with
+ * hash_remove(). But usually, you don't want to use this function, as it
+ * fiddles with hash-internals. */
+void *hash_remove_bucket(struct hashtable_t *hash, struct hash_it_t *hash_it_t)
+{
+	void *data_save;
+
+	data_save = hash_it_t->bucket->data;
+
+	if (hash_it_t->prev_bucket != NULL)
+		hash_it_t->prev_bucket->next = hash_it_t->bucket->next;
+	else if (hash_it_t->first_bucket != NULL)
+		(*hash_it_t->first_bucket) = hash_it_t->bucket->next;
+
+	kfree(hash_it_t->bucket);
+	hash->elements--;
+
+	return data_save;
+}
+
+/* removes data from hash, if found. returns pointer do data on success, so you
+ * can remove the used structure yourself, or NULL on error .  data could be the
+ * structure you use with just the key filled, we just need the key for
+ * comparing. */
+void *hash_remove(struct hashtable_t *hash, void *data)
+{
+	struct hash_it_t hash_it_t;
+
+	hash_it_t.index = hash->choose(data, hash->size);
+	hash_it_t.bucket = hash->table[hash_it_t.index];
+	hash_it_t.prev_bucket = NULL;
+
+	while (hash_it_t.bucket != NULL) {
+		if (hash->compare(hash_it_t.bucket->data, data)) {
+			hash_it_t.first_bucket =
+				(hash_it_t.bucket ==
+				 hash->table[hash_it_t.index] ?
+				 &hash->table[hash_it_t.index] : NULL);
+			return hash_remove_bucket(hash, &hash_it_t);
+		}
+
+		hash_it_t.prev_bucket = hash_it_t.bucket;
+		hash_it_t.bucket = hash_it_t.bucket->next;
+	}
+
+	return NULL;
+}
+
+/* resize the hash, returns the pointer to the new hash or NULL on
+ * error. removes the old hash on success. */
+struct hashtable_t *hash_resize(struct hashtable_t *hash, int size)
+{
+	struct hashtable_t *new_hash;
+	struct element_t *bucket;
+	int i;
+
+	/* initialize a new hash with the new size */
+	new_hash = hash_new(size, hash->compare, hash->choose);
+
+	if (new_hash == NULL)
+		return NULL;
+
+	/* copy the elements */
+	for (i = 0; i < hash->size; i++) {
+		bucket = hash->table[i];
+
+		while (bucket != NULL) {
+			hash_add(new_hash, bucket->data);
+			bucket = bucket->next;
+		}
+	}
+
+	/* remove hash and eventual overflow buckets but not the content
+	 * itself. */
+	hash_delete(hash, NULL);
+
+	return new_hash;
+}
diff --git a/drivers/staging/batman-adv/hash.h b/drivers/staging/batman-adv/hash.h
new file mode 100644
index 0000000..bb60f08
--- /dev/null
+++ b/drivers/staging/batman-adv/hash.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2006-2009 B.A.T.M.A.N. contributors:
+ *
+ * Simon Wunderlich, Marek Lindner
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#ifndef _BATMAN_HASH_H
+#define _BATMAN_HASH_H
+
+typedef int (*hashdata_compare_cb)(void *, void *);
+typedef int (*hashdata_choose_cb)(void *, int);
+typedef void (*hashdata_free_cb)(void *);
+
+struct element_t {
+	void *data;		/* pointer to the data */
+	struct element_t *next;	/* overflow bucket pointer */
+};
+
+struct hash_it_t {
+	int index;
+	struct element_t *bucket;
+	struct element_t *prev_bucket;
+	struct element_t **first_bucket;
+};
+
+struct hashtable_t {
+	struct element_t **table;   /* the hashtable itself, with the buckets */
+	int elements;		    /* number of elements registered */
+	int size;		    /* size of hashtable */
+	hashdata_compare_cb compare;/* callback to a compare function.  should
+				     * compare 2 element datas for their keys,
+				     * return 0 if same and not 0 if not
+				     * same */
+	hashdata_choose_cb choose;  /* the hashfunction, should return an index
+				     * based on the key in the data of the first
+				     * argument and the size the second */
+};
+
+/* clears the hash */
+void hash_init(struct hashtable_t *hash);
+
+/* allocates and clears the hash */
+struct hashtable_t *hash_new(int size, hashdata_compare_cb compare,
+			     hashdata_choose_cb choose);
+
+/* remove bucket (this might be used in hash_iterate() if you already found the
+ * bucket you want to delete and don't need the overhead to find it again with
+ * hash_remove().  But usually, you don't want to use this function, as it
+ * fiddles with hash-internals. */
+void *hash_remove_bucket(struct hashtable_t *hash, struct hash_it_t *hash_it_t);
+
+/* remove the hash structure. if hashdata_free_cb != NULL, this function will be
+ * called to remove the elements inside of the hash.  if you don't remove the
+ * elements, memory might be leaked. */
+void hash_delete(struct hashtable_t *hash, hashdata_free_cb free_cb);
+
+/* free only the hashtable and the hash itself. */
+void hash_destroy(struct hashtable_t *hash);
+
+/* adds data to the hashtable. returns 0 on success, -1 on error */
+int hash_add(struct hashtable_t *hash, void *data);
+
+/* removes data from hash, if found. returns pointer do data on success, so you
+ * can remove the used structure yourself, or NULL on error .  data could be the
+ * structure you use with just the key filled, we just need the key for
+ * comparing. */
+void *hash_remove(struct hashtable_t *hash, void *data);
+
+/* finds data, based on the key in keydata. returns the found data on success,
+ * or NULL on error */
+void *hash_find(struct hashtable_t *hash, void *keydata);
+
+/* resize the hash, returns the pointer to the new hash or NULL on
+ * error. removes the old hash on success */
+struct hashtable_t *hash_resize(struct hashtable_t *hash, int size);
+
+/* iterate though the hash. first element is selected with iter_in NULL.  use
+ * the returned iterator to access the elements until hash_it_t returns NULL. */
+struct hash_it_t *hash_iterate(struct hashtable_t *hash,
+			       struct hash_it_t *iter_in);
+
+/* print the hash table for debugging */
+void hash_debug(struct hashtable_t *hash);
+#endif
diff --git a/drivers/staging/batman-adv/log.c b/drivers/staging/batman-adv/log.c
new file mode 100644
index 0000000..f37c7f0
--- /dev/null
+++ b/drivers/staging/batman-adv/log.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "main.h"
+#include "log.h"
+
+#define LOG_BUF_MASK (log_buf_len-1)
+#define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK])
+
+static char log_buf[LOG_BUF_LEN];
+static int log_buf_len = LOG_BUF_LEN;
+static unsigned long log_start;
+static unsigned long log_end;
+uint8_t log_level;
+
+static DEFINE_SPINLOCK(logbuf_lock);
+
+const struct file_operations proc_log_operations = {
+	.open           = log_open,
+	.release        = log_release,
+	.read           = log_read,
+	.write          = log_write,
+	.poll           = log_poll,
+};
+
+static DECLARE_WAIT_QUEUE_HEAD(log_wait);
+
+static void emit_log_char(char c)
+{
+	LOG_BUF(log_end) = c;
+	log_end++;
+
+	if (log_end - log_start > log_buf_len)
+		log_start = log_end - log_buf_len;
+}
+
+static int fdebug_log(char *fmt, ...)
+{
+	int printed_len;
+	char *p;
+	va_list args;
+	static char debug_log_buf[256];
+	unsigned long flags;
+
+	spin_lock_irqsave(&logbuf_lock, flags);
+	va_start(args, fmt);
+	printed_len = vscnprintf(debug_log_buf, sizeof(debug_log_buf), fmt,
+				 args);
+	va_end(args);
+
+	for (p = debug_log_buf; *p != 0; p++)
+		emit_log_char(*p);
+
+	spin_unlock_irqrestore(&logbuf_lock, flags);
+
+	wake_up(&log_wait);
+
+	return 0;
+}
+
+int debug_log(int type, char *fmt, ...)
+{
+	va_list args;
+	int retval = 0;
+	char tmp_log_buf[256];
+
+	/* only critical information get into the official kernel log */
+	if (type == LOG_TYPE_CRIT) {
+		va_start(args, fmt);
+		vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args);
+		printk(KERN_ERR "batman-adv: %s", tmp_log_buf);
+		va_end(args);
+	}
+
+	if ((type == LOG_TYPE_CRIT) || (log_level & type)) {
+		va_start(args, fmt);
+		vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args);
+		fdebug_log("[%10u] %s", (jiffies / HZ), tmp_log_buf);
+		va_end(args);
+	}
+
+	return retval;
+}
+
+int log_open(struct inode *inode, struct file *file)
+{
+	inc_module_count();
+	return 0;
+}
+
+int log_release(struct inode *inode, struct file *file)
+{
+	dec_module_count();
+	return 0;
+}
+
+ssize_t log_read(struct file *file, char __user *buf, size_t count,
+		 loff_t *ppos)
+{
+	int error, i = 0;
+	char c;
+	unsigned long flags;
+
+	if ((file->f_flags & O_NONBLOCK) && !(log_end - log_start))
+		return -EAGAIN;
+
+	if ((!buf) || (count < 0))
+		return -EINVAL;
+
+	if (count == 0)
+		return 0;
+
+	if (!access_ok(VERIFY_WRITE, buf, count))
+		return -EFAULT;
+
+	error = wait_event_interruptible(log_wait, (log_start - log_end));
+
+	if (error)
+		return error;
+
+	spin_lock_irqsave(&logbuf_lock, flags);
+
+	while ((!error) && (log_start != log_end) && (i < count)) {
+		c = LOG_BUF(log_start);
+
+		log_start++;
+
+		spin_unlock_irqrestore(&logbuf_lock, flags);
+
+		error = __put_user(c, buf);
+
+		spin_lock_irqsave(&logbuf_lock, flags);
+
+		buf++;
+		i++;
+
+	}
+
+	spin_unlock_irqrestore(&logbuf_lock, flags);
+
+	if (!error)
+		return i;
+
+	return error;
+}
+
+ssize_t log_write(struct file *file, const char __user *buf, size_t count,
+		  loff_t *ppos)
+{
+	return count;
+}
+
+unsigned int log_poll(struct file *file, poll_table *wait)
+{
+	poll_wait(file, &log_wait, wait);
+
+	if (log_end - log_start)
+		return POLLIN | POLLRDNORM;
+
+	return 0;
+}
diff --git a/drivers/staging/batman-adv/log.h b/drivers/staging/batman-adv/log.h
new file mode 100644
index 0000000..780e3ab
--- /dev/null
+++ b/drivers/staging/batman-adv/log.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+extern const struct file_operations proc_log_operations;
+extern uint8_t log_level;
+
+int debug_log(int type, char *fmt, ...);
+int log_open(struct inode *inode, struct file *file);
+int log_release(struct inode *inode, struct file *file);
+ssize_t log_read(struct file *file, char __user *buf, size_t count,
+		 loff_t *ppos);
+ssize_t log_write(struct file *file, const char __user *buf, size_t count,
+		  loff_t *ppos);
+unsigned int log_poll(struct file *file, poll_table *wait);
diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c
new file mode 100644
index 0000000..bb89bfc
--- /dev/null
+++ b/drivers/staging/batman-adv/main.c
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "main.h"
+#include "proc.h"
+#include "log.h"
+#include "routing.h"
+#include "send.h"
+#include "soft-interface.h"
+#include "device.h"
+#include "translation-table.h"
+#include "hard-interface.h"
+#include "types.h"
+#include "vis.h"
+#include "hash.h"
+#include "compat.h"
+
+struct list_head if_list;
+struct hlist_head forw_bat_list;
+struct hlist_head forw_bcast_list;
+struct hashtable_t *orig_hash;
+
+DEFINE_SPINLOCK(orig_hash_lock);
+DEFINE_SPINLOCK(forw_bat_list_lock);
+DEFINE_SPINLOCK(forw_bcast_list_lock);
+
+atomic_t originator_interval;
+atomic_t vis_interval;
+atomic_t aggregation_enabled;
+int16_t num_hna;
+int16_t num_ifs;
+
+struct net_device *soft_device;
+
+static struct task_struct *kthread_task;
+
+unsigned char broadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+atomic_t module_state;
+
+struct workqueue_struct *bat_event_workqueue;
+
+int init_module(void)
+{
+	int retval;
+
+	INIT_LIST_HEAD(&if_list);
+	INIT_HLIST_HEAD(&forw_bat_list);
+	INIT_HLIST_HEAD(&forw_bcast_list);
+
+	atomic_set(&module_state, MODULE_INACTIVE);
+
+	atomic_set(&originator_interval, 1000);
+	atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only
+					 * for debugging now. */
+	atomic_set(&aggregation_enabled, 1);
+
+	/* the name should not be longer than 10 chars - see
+	 * http://lwn.net/Articles/23634/ */
+	bat_event_workqueue = create_singlethread_workqueue("bat_events");
+
+	if (!bat_event_workqueue)
+		return -ENOMEM;
+
+	retval = setup_procfs();
+	if (retval < 0)
+		return retval;
+
+	bat_device_init();
+
+	/* initialize layer 2 interface */
+	soft_device = alloc_netdev(sizeof(struct bat_priv) , "bat%d",
+				   interface_setup);
+
+	if (!soft_device) {
+		debug_log(LOG_TYPE_CRIT, "Unable to allocate the batman interface\n");
+		goto end;
+	}
+
+	retval = register_netdev(soft_device);
+
+	if (retval < 0) {
+		debug_log(LOG_TYPE_CRIT, "Unable to register the batman interface: %i\n", retval);
+		goto free_soft_device;
+	}
+
+	register_netdevice_notifier(&hard_if_notifier);
+
+	debug_log(LOG_TYPE_CRIT, "B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded \n",
+	          SOURCE_VERSION, REVISION_VERSION_STR, COMPAT_VERSION);
+
+	return 0;
+
+free_soft_device:
+	free_netdev(soft_device);
+	soft_device = NULL;
+end:
+	return -ENOMEM;
+}
+
+void cleanup_module(void)
+{
+	shutdown_module();
+
+	if (soft_device) {
+		unregister_netdev(soft_device);
+		soft_device = NULL;
+	}
+
+	unregister_netdevice_notifier(&hard_if_notifier);
+	cleanup_procfs();
+
+	destroy_workqueue(bat_event_workqueue);
+	bat_event_workqueue = NULL;
+}
+
+/* activates the module, creates bat device, starts timer ... */
+void activate_module(void)
+{
+	if (originator_init() < 1)
+		goto err;
+
+	if (hna_local_init() < 1)
+		goto err;
+
+	if (hna_global_init() < 1)
+		goto err;
+
+	hna_local_add(soft_device->dev_addr);
+
+	if (bat_device_setup() < 1)
+		goto end;
+
+	if (vis_init() < 1)
+		goto err;
+
+	/* (re)start kernel thread for packet processing */
+	if (!kthread_task) {
+		kthread_task = kthread_run(packet_recv_thread, NULL, "batman-adv");
+
+		if (IS_ERR(kthread_task)) {
+			debug_log(LOG_TYPE_CRIT, "Unable to start packet receive thread\n");
+			kthread_task = NULL;
+		}
+	}
+
+	update_min_mtu();
+	atomic_set(&module_state, MODULE_ACTIVE);
+	goto end;
+
+err:
+	debug_log(LOG_TYPE_CRIT, "Unable to allocate memory for mesh information structures: out of mem ?\n");
+	shutdown_module();
+end:
+	return;
+}
+
+/* shuts down the whole module.*/
+void shutdown_module(void)
+{
+	atomic_set(&module_state, MODULE_DEACTIVATING);
+
+	purge_outstanding_packets();
+	flush_workqueue(bat_event_workqueue);
+
+	vis_quit();
+
+	/* deactivate kernel thread for packet processing (if running) */
+	if (kthread_task) {
+		atomic_set(&exit_cond, 1);
+		wake_up_interruptible(&thread_wait);
+		kthread_stop(kthread_task);
+
+		kthread_task = NULL;
+	}
+
+	originator_free();
+
+	hna_local_free();
+	hna_global_free();
+
+	synchronize_net();
+	bat_device_destroy();
+
+	hardif_remove_interfaces();
+	synchronize_rcu();
+	atomic_set(&module_state, MODULE_INACTIVE);
+}
+
+void inc_module_count(void)
+{
+	try_module_get(THIS_MODULE);
+}
+
+void dec_module_count(void)
+{
+	module_put(THIS_MODULE);
+}
+
+int addr_to_string(char *buff, uint8_t *addr)
+{
+	return sprintf(buff, "%02x:%02x:%02x:%02x:%02x:%02x",
+		       addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+}
+
+/* returns 1 if they are the same originator */
+
+int compare_orig(void *data1, void *data2)
+{
+	return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
+}
+
+/* hashfunction to choose an entry in a hash table of given size */
+/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */
+int choose_orig(void *data, int32_t size)
+{
+	unsigned char *key = data;
+	uint32_t hash = 0;
+	size_t i;
+
+	for (i = 0; i < 6; i++) {
+		hash += key[i];
+		hash += (hash << 10);
+		hash ^= (hash >> 6);
+	}
+
+	hash += (hash << 3);
+	hash ^= (hash >> 11);
+	hash += (hash << 15);
+
+	return hash % size;
+}
+
+int is_my_mac(uint8_t *addr)
+{
+	struct batman_if *batman_if;
+	rcu_read_lock();
+	list_for_each_entry_rcu(batman_if, &if_list, list) {
+		if ((batman_if->net_dev) &&
+		    (compare_orig(batman_if->net_dev->dev_addr, addr))) {
+			rcu_read_unlock();
+			return 1;
+		}
+	}
+	rcu_read_unlock();
+	return 0;
+
+}
+
+int is_bcast(uint8_t *addr)
+{
+	return (addr[0] == (uint8_t)0xff) && (addr[1] == (uint8_t)0xff);
+}
+
+int is_mcast(uint8_t *addr)
+{
+	return *addr & 0x01;
+}
+
+MODULE_LICENSE("GPL");
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_SUPPORTED_DEVICE(DRIVER_DEVICE);
+#ifdef REVISION_VERSION
+MODULE_VERSION(SOURCE_VERSION "-" REVISION_VERSION);
+#else
+MODULE_VERSION(SOURCE_VERSION);
+#endif
diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h
new file mode 100644
index 0000000..facb6b7
--- /dev/null
+++ b/drivers/staging/batman-adv/main.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+/* Kernel Programming */
+#define LINUX
+
+#define DRIVER_AUTHOR "Marek Lindner <lindner_marek@yahoo.de>, Simon Wunderlich <siwu@hrz.tu-chemnitz.de>"
+#define DRIVER_DESC   "B.A.T.M.A.N. advanced"
+#define DRIVER_DEVICE "batman-adv"
+
+#define SOURCE_VERSION "0.2.1-beta"
+
+
+/* B.A.T.M.A.N. parameters */
+
+#define TQ_MAX_VALUE 255
+#define JITTER 20
+#define TTL 50		          /* Time To Live of broadcast messages */
+#define MAX_ADDR 16	          /* number of interfaces which can be added to
+				   * batman. */
+
+#define PURGE_TIMEOUT 200000      /* purge originators after time in ms if no
+				   * valid packet comes in -> TODO: check
+				   * influence on TQ_LOCAL_WINDOW_SIZE */
+#define LOCAL_HNA_TIMEOUT 3600000
+
+#define TQ_LOCAL_WINDOW_SIZE 64   /* sliding packet range of received originator
+				   * messages in squence numbers (should be a
+				   * multiple of our word size) */
+#define TQ_GLOBAL_WINDOW_SIZE 5
+#define TQ_LOCAL_BIDRECT_SEND_MINIMUM 1
+#define TQ_LOCAL_BIDRECT_RECV_MINIMUM 1
+#define TQ_TOTAL_BIDRECT_LIMIT 1
+
+#define TQ_HOP_PENALTY 10
+
+#define NUM_WORDS (TQ_LOCAL_WINDOW_SIZE / WORD_BIT_SIZE)
+
+#define PACKBUFF_SIZE 2000
+#define LOG_BUF_LEN 8192	  /* has to be a power of 2 */
+#define ETH_STR_LEN 20
+
+#define MAX_AGGREGATION_BYTES 512 /* should not be bigger than 512 bytes or
+				   * change the size of
+				   * forw_packet->direct_link_flags */
+#define MAX_AGGREGATION_MS 100
+
+#define MODULE_INACTIVE 0
+#define MODULE_ACTIVE 1
+#define MODULE_DEACTIVATING 2
+
+
+/*
+ * Logging
+ */
+
+#define LOG_TYPE_CRIT 0		/* highest priority for fatal errors such as
+				 * blocked sockets / failed packet delivery /
+				 * programming errors */
+#define LOG_TYPE_WARN 1		/* warnings for small errors like wrong user
+				 * input / damaged packets / etc */
+#define LOG_TYPE_NOTICE 2	/* notice information for new interfaces /
+				 * changed settings / new originators / etc */
+#define LOG_TYPE_BATMAN 4	/* all messages related to routing / flooding /
+				 * broadcasting / etc */
+#define LOG_TYPE_ROUTES 8	/* route or hna added / changed / deleted */
+#define LOG_TYPE_CRIT_NAME	"critical"
+#define LOG_TYPE_WARN_NAME	"warnings"
+#define LOG_TYPE_NOTICE_NAME	"notices"
+#define LOG_TYPE_BATMAN_NAME	"batman"
+#define LOG_TYPE_ROUTES_NAME	"routes"
+
+/*
+ *  Vis
+ */
+
+/* #define VIS_SUBCLUSTERS_DISABLED */
+
+/*
+ * Kernel headers
+ */
+
+#include <linux/mutex.h>	/* mutex */
+#include <linux/module.h>	/* needed by all modules */
+#include <linux/netdevice.h>	/* netdevice */
+#include <linux/if_ether.h>	/* ethernet header */
+#include <linux/poll.h>		/* poll_table */
+#include <linux/kthread.h>	/* kernel threads */
+#include <linux/pkt_sched.h>	/* schedule types */
+#include <linux/workqueue.h>	/* workqueue */
+#include <net/sock.h>		/* struct sock */
+#include <linux/jiffies.h>
+#include "types.h"
+
+#ifndef REVISION_VERSION
+#define REVISION_VERSION_STR ""
+#else
+#define REVISION_VERSION_STR " "REVISION_VERSION
+#endif
+
+extern struct list_head if_list;
+extern struct hlist_head forw_bat_list;
+extern struct hlist_head forw_bcast_list;
+extern struct hashtable_t *orig_hash;
+
+extern spinlock_t orig_hash_lock;
+extern spinlock_t forw_bat_list_lock;
+extern spinlock_t forw_bcast_list_lock;
+
+extern atomic_t originator_interval;
+extern atomic_t vis_interval;
+extern atomic_t aggregation_enabled;
+extern int16_t num_hna;
+extern int16_t num_ifs;
+
+extern struct net_device *soft_device;
+
+extern unsigned char broadcastAddr[];
+extern atomic_t module_state;
+extern struct workqueue_struct *bat_event_workqueue;
+
+void activate_module(void);
+void shutdown_module(void);
+void inc_module_count(void);
+void dec_module_count(void);
+int addr_to_string(char *buff, uint8_t *addr);
+int compare_orig(void *data1, void *data2);
+int choose_orig(void *data, int32_t size);
+int is_my_mac(uint8_t *addr);
+int is_bcast(uint8_t *addr);
+int is_mcast(uint8_t *addr);
+
+
diff --git a/drivers/staging/batman-adv/packet.h b/drivers/staging/batman-adv/packet.h
new file mode 100644
index 0000000..5627ca3
--- /dev/null
+++ b/drivers/staging/batman-adv/packet.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#define ETH_P_BATMAN  0x4305	/* unofficial/not registered Ethertype */
+
+#define BAT_PACKET    0x01
+#define BAT_ICMP      0x02
+#define BAT_UNICAST   0x03
+#define BAT_BCAST     0x04
+#define BAT_VIS       0x05
+
+/* this file is included by batctl which needs these defines */
+#define COMPAT_VERSION 8
+#define DIRECTLINK 0x40
+#define VIS_SERVER 0x20
+
+/* ICMP message types */
+#define ECHO_REPLY 0
+#define DESTINATION_UNREACHABLE 3
+#define ECHO_REQUEST 8
+#define TTL_EXCEEDED 11
+#define PARAMETER_PROBLEM 12
+
+/* vis defines */
+#define VIS_TYPE_SERVER_SYNC		0
+#define VIS_TYPE_CLIENT_UPDATE		1
+
+struct batman_packet {
+	uint8_t  packet_type;
+	uint8_t  version;  /* batman version field */
+	uint8_t  flags;    /* 0x40: DIRECTLINK flag, 0x20 VIS_SERVER flag... */
+	uint8_t  tq;
+	uint16_t seqno;
+	uint8_t  orig[6];
+	uint8_t  prev_sender[6];
+	uint8_t  ttl;
+	uint8_t  num_hna;
+} __attribute__((packed));
+
+#define BAT_PACKET_LEN sizeof(struct batman_packet)
+
+struct icmp_packet {
+	uint8_t  packet_type;
+	uint8_t  version;  /* batman version field */
+	uint8_t  msg_type; /* see ICMP message types above */
+	uint8_t  ttl;
+	uint8_t  dst[6];
+	uint8_t  orig[6];
+	uint16_t seqno;
+	uint8_t  uid;
+} __attribute__((packed));
+
+struct unicast_packet {
+	uint8_t  packet_type;
+	uint8_t  version;  /* batman version field */
+	uint8_t  dest[6];
+	uint8_t  ttl;
+} __attribute__((packed));
+
+struct bcast_packet {
+	uint8_t  packet_type;
+	uint8_t  version;  /* batman version field */
+	uint8_t  orig[6];
+	uint16_t seqno;
+} __attribute__((packed));
+
+struct vis_packet {
+	uint8_t  packet_type;
+	uint8_t  version;        /* batman version field */
+	uint8_t  vis_type;	 /* which type of vis-participant sent this? */
+	uint8_t  seqno;		 /* sequence number */
+	uint8_t  entries;	 /* number of entries behind this struct */
+	uint8_t  ttl;		 /* TTL */
+	uint8_t  vis_orig[6];	 /* originator that informs about its
+				  * neighbours */
+	uint8_t  target_orig[6]; /* who should receive this packet */
+	uint8_t  sender_orig[6]; /* who sent or rebroadcasted this packet */
+} __attribute__((packed));
diff --git a/drivers/staging/batman-adv/proc.c b/drivers/staging/batman-adv/proc.c
new file mode 100644
index 0000000..aac3df7
--- /dev/null
+++ b/drivers/staging/batman-adv/proc.c
@@ -0,0 +1,950 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "main.h"
+#include "proc.h"
+#include "log.h"
+#include "routing.h"
+#include "translation-table.h"
+#include "hard-interface.h"
+#include "types.h"
+#include "hash.h"
+#include "vis.h"
+#include "compat.h"
+
+static uint8_t vis_format = DOT_DRAW;
+
+static struct proc_dir_entry *proc_batman_dir, *proc_interface_file;
+static struct proc_dir_entry *proc_orig_interval_file, *proc_originators_file;
+static struct proc_dir_entry *proc_log_file, *proc_log_level_file;
+static struct proc_dir_entry *proc_transt_local_file;
+static struct proc_dir_entry *proc_transt_global_file;
+static struct proc_dir_entry *proc_vis_file, *proc_vis_format_file;
+static struct proc_dir_entry *proc_aggr_file;
+
+static int proc_interfaces_read(struct seq_file *seq, void *offset)
+{
+	struct batman_if *batman_if;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(batman_if, &if_list, list) {
+		seq_printf(seq, "[%8s] %s %s \n",
+			   (batman_if->if_active == IF_ACTIVE ?
+			    "active" : "inactive"),
+			   batman_if->dev,
+			   (batman_if->if_active == IF_ACTIVE ?
+			    batman_if->addr_str : " "));
+	}
+	rcu_read_unlock();
+
+	return 0;
+}
+
+static int proc_interfaces_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_interfaces_read, NULL);
+}
+
+static ssize_t proc_interfaces_write(struct file *instance,
+				     const char __user *userbuffer,
+				     size_t count, loff_t *data)
+{
+	char *if_string, *colon_ptr = NULL, *cr_ptr = NULL;
+	int not_copied = 0, if_num = 0;
+	struct batman_if *batman_if = NULL;
+
+	if_string = kmalloc(count, GFP_KERNEL);
+
+	if (!if_string)
+		return -ENOMEM;
+
+	if (count > IFNAMSIZ - 1) {
+		debug_log(LOG_TYPE_WARN,
+			  "Can't add interface: device name is too long\n");
+		goto end;
+	}
+
+	not_copied = copy_from_user(if_string, userbuffer, count);
+	if_string[count - not_copied - 1] = 0;
+
+	colon_ptr = strchr(if_string, ':');
+	if (colon_ptr)
+		*colon_ptr = 0;
+
+	if (!colon_ptr) {
+		cr_ptr = strchr(if_string, '\n');
+		if (cr_ptr)
+			*cr_ptr = 0;
+	}
+
+	if (strlen(if_string) == 0) {
+		shutdown_module();
+		num_ifs = 0;
+		goto end;
+	}
+
+	/* add interface */
+	rcu_read_lock();
+	list_for_each_entry_rcu(batman_if, &if_list, list) {
+		if (strncmp(batman_if->dev, if_string, count) == 0) {
+			debug_log(LOG_TYPE_WARN, "Given interface is already active: %s\n", if_string);
+			rcu_read_unlock();
+			goto end;
+
+		}
+
+		if_num++;
+	}
+	rcu_read_unlock();
+
+	hardif_add_interface(if_string, if_num);
+
+	if ((atomic_read(&module_state) == MODULE_INACTIVE) &&
+	    (hardif_get_active_if_num() > 0))
+		activate_module();
+
+	rcu_read_lock();
+	if (list_empty(&if_list)) {
+		rcu_read_unlock();
+		goto end;
+	}
+	rcu_read_unlock();
+
+	num_ifs = if_num + 1;
+	return count;
+
+end:
+	kfree(if_string);
+	return count;
+}
+
+static int proc_orig_interval_read(struct seq_file *seq, void *offset)
+{
+	seq_printf(seq, "%i\n", atomic_read(&originator_interval));
+
+	return 0;
+}
+
+static ssize_t proc_orig_interval_write(struct file *file,
+					const char __user *buffer,
+					size_t count, loff_t *ppos)
+{
+	char *interval_string;
+	int not_copied = 0;
+	unsigned long originator_interval_tmp;
+	int retval;
+
+	interval_string = kmalloc(count, GFP_KERNEL);
+
+	if (!interval_string)
+		return -ENOMEM;
+
+	not_copied = copy_from_user(interval_string, buffer, count);
+	interval_string[count - not_copied - 1] = 0;
+
+	retval = strict_strtoul(interval_string, 10, &originator_interval_tmp);
+	if (retval) {
+		debug_log(LOG_TYPE_WARN, "New originator interval invalid\n");
+		goto end;
+	}
+
+	if (originator_interval_tmp <= JITTER * 2) {
+		debug_log(LOG_TYPE_WARN,
+			  "New originator interval too small: %i (min: %i)\n",
+			  originator_interval_tmp, JITTER * 2);
+		goto end;
+	}
+
+	debug_log(LOG_TYPE_NOTICE,
+		  "Changing originator interval from: %i to: %i\n",
+		  atomic_read(&originator_interval), originator_interval_tmp);
+
+	atomic_set(&originator_interval, originator_interval_tmp);
+
+end:
+	kfree(interval_string);
+	return count;
+}
+
+static int proc_orig_interval_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_orig_interval_read, NULL);
+}
+
+static int proc_originators_read(struct seq_file *seq, void *offset)
+{
+	struct hash_it_t *hashit = NULL;
+	struct orig_node *orig_node;
+	struct neigh_node *neigh_node;
+	int batman_count = 0;
+	char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN];
+
+	rcu_read_lock();
+	if (list_empty(&if_list)) {
+		rcu_read_unlock();
+		seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it \n");
+		goto end;
+	}
+
+	if (((struct batman_if *)if_list.next)->if_active != IF_ACTIVE) {
+		rcu_read_unlock();
+		seq_printf(seq, "BATMAN disabled - primary interface not active \n");
+		goto end;
+	}
+
+	seq_printf(seq,
+		   "  %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s] \n",
+		   "Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF",
+		   "Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR,
+		   ((struct batman_if *)if_list.next)->dev,
+		   ((struct batman_if *)if_list.next)->addr_str);
+
+	rcu_read_unlock();
+	spin_lock(&orig_hash_lock);
+
+	while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
+
+		orig_node = hashit->bucket->data;
+
+		if (!orig_node->router)
+			continue;
+
+		if (orig_node->router->tq_avg == 0)
+			continue;
+
+		batman_count++;
+
+		addr_to_string(orig_str, orig_node->orig);
+		addr_to_string(router_str, orig_node->router->addr);
+
+		seq_printf(seq, "%-17s  (%3i) %17s [%10s]:",
+			   orig_str, orig_node->router->tq_avg,
+			   router_str, orig_node->router->if_incoming->dev);
+
+		list_for_each_entry(neigh_node, &orig_node->neigh_list, list) {
+			addr_to_string(orig_str, neigh_node->addr);
+			seq_printf(seq, " %17s (%3i)",
+				   orig_str, neigh_node->tq_avg);
+		}
+
+		seq_printf(seq, "\n");
+
+	}
+
+	spin_unlock(&orig_hash_lock);
+
+	if (batman_count == 0)
+		seq_printf(seq, "No batman nodes in range ... \n");
+
+end:
+	return 0;
+}
+
+static int proc_originators_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_originators_read, NULL);
+}
+
+static int proc_log_level_read(struct seq_file *seq, void *offset)
+{
+
+	seq_printf(seq, "[x] %s (%d)\n", LOG_TYPE_CRIT_NAME, LOG_TYPE_CRIT);
+	seq_printf(seq, "[%c] %s (%d)\n",
+		   (LOG_TYPE_WARN & log_level) ? 'x' : ' ',
+		   LOG_TYPE_WARN_NAME, LOG_TYPE_WARN);
+	seq_printf(seq, "[%c] %s (%d)\n",
+		   (LOG_TYPE_NOTICE & log_level) ? 'x' : ' ',
+		   LOG_TYPE_NOTICE_NAME, LOG_TYPE_NOTICE);
+	seq_printf(seq, "[%c] %s (%d)\n",
+		   (LOG_TYPE_BATMAN & log_level) ? 'x' : ' ',
+		   LOG_TYPE_BATMAN_NAME, LOG_TYPE_BATMAN);
+	seq_printf(seq, "[%c] %s (%d)\n",
+		   (LOG_TYPE_ROUTES & log_level) ? 'x' : ' ',
+		   LOG_TYPE_ROUTES_NAME, LOG_TYPE_ROUTES);
+	return 0;
+}
+
+static int proc_log_level_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_log_level_read, NULL);
+}
+
+static ssize_t proc_log_level_write(struct file *instance,
+				    const char __user *userbuffer,
+				    size_t count, loff_t *data)
+{
+	char *log_level_string, *tokptr, *cp;
+	int finished, not_copied = 0;
+	unsigned long log_level_tmp = 0;
+
+	log_level_string = kmalloc(count, GFP_KERNEL);
+
+	if (!log_level_string)
+		return -ENOMEM;
+
+	not_copied = copy_from_user(log_level_string, userbuffer, count);
+	log_level_string[count - not_copied - 1] = 0;
+
+	if (strict_strtoul(log_level_string, 10, &log_level_tmp) < 0) {
+		/* was not a number, doing textual parsing */
+		log_level_tmp = 0;
+		tokptr = log_level_string;
+
+		for (cp = log_level_string, finished = 0; !finished; cp++) {
+			switch (*cp) {
+			case 0:
+				finished = 1;
+			case ' ':
+			case '\n':
+			case '\t':
+				*cp = 0;
+				/* compare */
+				if (strcmp(tokptr, LOG_TYPE_WARN_NAME) == 0)
+					log_level_tmp |= LOG_TYPE_WARN;
+				if (strcmp(tokptr, LOG_TYPE_NOTICE_NAME) == 0)
+					log_level_tmp |= LOG_TYPE_NOTICE;
+				if (strcmp(tokptr, LOG_TYPE_BATMAN_NAME) == 0)
+					log_level_tmp |= LOG_TYPE_BATMAN;
+				if (strcmp(tokptr, LOG_TYPE_ROUTES_NAME) == 0)
+					log_level_tmp |= LOG_TYPE_ROUTES;
+				tokptr = cp + 1;
+				break;
+			default:
+				;
+			}
+		}
+	}
+
+	debug_log(LOG_TYPE_CRIT, "Changing log_level from: %i to: %i\n",
+		  log_level, log_level_tmp);
+	log_level = log_level_tmp;
+
+	kfree(log_level_string);
+	return count;
+}
+
+static int proc_transt_local_read(struct seq_file *seq, void *offset)
+{
+	char *buf;
+
+	buf = kmalloc(4096, GFP_KERNEL);
+	if (!buf)
+		return 0;
+
+	rcu_read_lock();
+	if (list_empty(&if_list)) {
+		rcu_read_unlock();
+		seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it \n");
+		goto end;
+	}
+
+	rcu_read_unlock();
+
+	seq_printf(seq, "Locally retrieved addresses (from %s) announced via HNA:\n", soft_device->name);
+
+	hna_local_fill_buffer_text(buf, 4096);
+	seq_printf(seq, "%s", buf);
+
+end:
+	kfree(buf);
+	return 0;
+}
+
+static int proc_transt_local_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_transt_local_read, NULL);
+}
+
+static int proc_transt_global_read(struct seq_file *seq, void *offset)
+{
+	char *buf;
+
+	buf = kmalloc(4096, GFP_KERNEL);
+	if (!buf)
+		return 0;
+
+	rcu_read_lock();
+	if (list_empty(&if_list)) {
+		rcu_read_unlock();
+		seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it \n");
+		goto end;
+	}
+	rcu_read_unlock();
+
+
+	seq_printf(seq, "Globally announced HNAs received via the mesh (translation table):\n");
+
+	hna_global_fill_buffer_text(buf, 4096);
+	seq_printf(seq, "%s", buf);
+
+end:
+	kfree(buf);
+	return 0;
+}
+
+static int proc_transt_global_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_transt_global_read, NULL);
+}
+
+/* insert interface to the list of interfaces of one originator */
+
+static void proc_vis_insert_interface(const uint8_t *interface,
+				      struct vis_if_list **if_entry,
+				      bool primary)
+{
+	/* Did we get an empty list? (then insert imediately) */
+	if(*if_entry == NULL) {
+		*if_entry = kmalloc(sizeof(struct vis_if_list), GFP_KERNEL);
+		if (*if_entry == NULL)
+			return;
+
+		(*if_entry)->primary = primary;
+		(*if_entry)->next = NULL;
+		memcpy((*if_entry)->addr, interface, ETH_ALEN);
+	} else {
+		struct vis_if_list *head_if_entry = *if_entry;
+		/* Do we already have this interface in our list? */
+		while (!compare_orig((*if_entry)->addr, (void *)interface)) {
+
+			/* Or did we reach the end (then append the interface) */
+			if ((*if_entry)->next == NULL) {
+				(*if_entry)->next = kmalloc(sizeof(struct vis_if_list), GFP_KERNEL);
+				if ((*if_entry)->next == NULL)
+					return;
+
+				memcpy((*if_entry)->next->addr, interface, ETH_ALEN);
+				(*if_entry)->next->primary = primary;
+				(*if_entry)->next->next = NULL;
+				break;
+			}
+			*if_entry = (*if_entry)->next;
+		}
+		/* Rewind the list to its head */
+		*if_entry = head_if_entry;
+	}
+}
+/* read an entry  */
+
+static void proc_vis_read_entry(struct seq_file *seq,
+				struct vis_info_entry *entry,
+				struct vis_if_list **if_entry,
+				uint8_t *vis_orig,
+				uint8_t current_format,
+				uint8_t first_line)
+{
+	char from[40];
+	char to[40];
+	int int_part, frac_part;
+
+	addr_to_string(to, entry->dest);
+	if (entry->quality == 0) {
+#ifndef VIS_SUBCLUSTERS_DISABLED
+		proc_vis_insert_interface(vis_orig, if_entry, true);
+#endif /* VIS_SUBCLUSTERS_DISABLED */
+		addr_to_string(from, vis_orig);
+		if (current_format == DOT_DRAW) {
+			seq_printf(seq, "\t\"%s\" -> \"%s\" [label=\"HNA\"]\n",
+				   from, to);
+		} else {
+			seq_printf(seq,
+				   "%s\t{ router : \"%s\", gateway   : \"%s\", label : \"HNA\" }",
+				   (first_line ? "" : ",\n"), from, to);
+		}
+	} else {
+#ifndef VIS_SUBCLUSTERS_DISABLED
+		proc_vis_insert_interface(entry->src, if_entry, compare_orig(entry->src, vis_orig));
+#endif /* VIS_SUBCLUSTERS_DISABLED */
+		addr_to_string(from, entry->src);
+
+		/* kernel has no printf-support for %f? it'd be better to return
+		 * this in float. */
+
+		int_part = TQ_MAX_VALUE / entry->quality;
+		frac_part = 1000 * TQ_MAX_VALUE / entry->quality - int_part * 1000;
+
+		if (current_format == DOT_DRAW) {
+			seq_printf(seq,
+				   "\t\"%s\" -> \"%s\" [label=\"%d.%d\"]\n",
+				   from, to, int_part, frac_part);
+		} else {
+			seq_printf(seq,
+				   "%s\t{ router : \"%s\", neighbour : \"%s\", label : %d.%d }",
+				   (first_line ? "" : ",\n"), from, to, int_part, frac_part);
+		}
+	}
+}
+
+
+static int proc_vis_read(struct seq_file *seq, void *offset)
+{
+	struct hash_it_t *hashit = NULL;
+	struct vis_info *info;
+	struct vis_info_entry *entries;
+	struct vis_if_list *if_entries = NULL;
+	int i;
+	uint8_t current_format, first_line = 1;
+#ifndef VIS_SUBCLUSTERS_DISABLED
+	char tmp_addr_str[ETH_STR_LEN];
+	struct vis_if_list *tmp_if_next;
+#endif /* VIS_SUBCLUSTERS_DISABLED */
+
+	current_format = vis_format;
+
+	rcu_read_lock();
+	if (list_empty(&if_list) || (!is_vis_server())) {
+		rcu_read_unlock();
+		if (current_format == DOT_DRAW)
+			seq_printf(seq, "digraph {\n}\n");
+		goto end;
+	}
+
+	rcu_read_unlock();
+
+	if (current_format == DOT_DRAW)
+		seq_printf(seq, "digraph {\n");
+
+	spin_lock(&vis_hash_lock);
+	while (NULL != (hashit = hash_iterate(vis_hash, hashit))) {
+		info = hashit->bucket->data;
+		entries = (struct vis_info_entry *)
+			((char *)info + sizeof(struct vis_info));
+
+		for (i = 0; i < info->packet.entries; i++) {
+			proc_vis_read_entry(seq, &entries[i], &if_entries,
+					    info->packet.vis_orig,
+					    current_format, first_line);
+			if (first_line)
+				first_line = 0;
+		}
+
+#ifndef VIS_SUBCLUSTERS_DISABLED
+		/* Generate subgraphs from the collected items */
+		if (current_format == DOT_DRAW) {
+
+			addr_to_string(tmp_addr_str, info->packet.vis_orig);
+			seq_printf(seq, "\tsubgraph \"cluster_%s\" {\n", tmp_addr_str);
+			while (if_entries != NULL) {
+
+				addr_to_string(tmp_addr_str, if_entries->addr);
+				if (if_entries->primary)
+					seq_printf(seq, "\t\t\"%s\" [peripheries=2]\n", tmp_addr_str);
+				else
+					seq_printf(seq, "\t\t\"%s\"\n", tmp_addr_str);
+
+				/* ... and empty the list while doing this */
+				tmp_if_next = if_entries->next;
+				kfree(if_entries);
+				if_entries = tmp_if_next;
+			}
+			seq_printf(seq, "\t}\n");
+		}
+#endif /* VIS_SUBCLUSTERS_DISABLED */
+	}
+	spin_unlock(&vis_hash_lock);
+
+	if (current_format == DOT_DRAW)
+		seq_printf(seq, "}\n");
+	else
+		seq_printf(seq, "\n");
+end:
+	return 0;
+}
+
+/* setting the mode of the vis server by the user */
+static ssize_t proc_vis_write(struct file *file, const char __user * buffer,
+			      size_t count, loff_t *ppos)
+{
+	char *vis_mode_string;
+	int not_copied = 0;
+
+	vis_mode_string = kmalloc(count, GFP_KERNEL);
+
+	if (!vis_mode_string)
+		return -ENOMEM;
+
+	not_copied = copy_from_user(vis_mode_string, buffer, count);
+	vis_mode_string[count - not_copied - 1] = 0;
+
+	if (strcmp(vis_mode_string, "client") == 0) {
+		debug_log(LOG_TYPE_NOTICE, "Setting VIS mode to client\n");
+		vis_set_mode(VIS_TYPE_CLIENT_UPDATE);
+	} else if (strcmp(vis_mode_string, "server") == 0) {
+		debug_log(LOG_TYPE_NOTICE, "Setting VIS mode to server\n");
+		vis_set_mode(VIS_TYPE_SERVER_SYNC);
+	} else
+		debug_log(LOG_TYPE_WARN, "Unknown VIS mode: %s\n",
+			  vis_mode_string);
+
+	kfree(vis_mode_string);
+	return count;
+}
+
+static int proc_vis_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_vis_read, NULL);
+}
+
+static int proc_vis_format_read(struct seq_file *seq, void *offset)
+{
+	uint8_t current_format = vis_format;
+
+	seq_printf(seq, "[%c] %s\n",
+		   (current_format == DOT_DRAW) ? 'x' : ' ',
+		   VIS_FORMAT_DD_NAME);
+	seq_printf(seq, "[%c] %s\n",
+		   (current_format == JSON) ? 'x' : ' ',
+		   VIS_FORMAT_JSON_NAME);
+	return 0;
+}
+
+static int proc_vis_format_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_vis_format_read, NULL);
+}
+
+static ssize_t proc_vis_format_write(struct file *file,
+				     const char __user *buffer,
+				     size_t count, loff_t *ppos)
+{
+	char *vis_format_string;
+	int not_copied = 0;
+
+	vis_format_string = kmalloc(count, GFP_KERNEL);
+
+	if (!vis_format_string)
+		return -ENOMEM;
+
+	not_copied = copy_from_user(vis_format_string, buffer, count);
+	vis_format_string[count - not_copied - 1] = 0;
+
+	if (strcmp(vis_format_string, VIS_FORMAT_DD_NAME) == 0) {
+		debug_log(LOG_TYPE_NOTICE, "Setting VIS output format to: %s\n",
+			  VIS_FORMAT_DD_NAME);
+		vis_format = DOT_DRAW;
+	} else if (strcmp(vis_format_string, VIS_FORMAT_JSON_NAME) == 0) {
+		debug_log(LOG_TYPE_NOTICE, "Setting VIS output format to: %s\n",
+			  VIS_FORMAT_JSON_NAME);
+		vis_format = JSON;
+	} else
+		debug_log(LOG_TYPE_WARN, "Unknown VIS output format: %s\n",
+			  vis_format_string);
+
+	kfree(vis_format_string);
+	return count;
+}
+
+static int proc_aggr_read(struct seq_file *seq, void *offset)
+{
+	seq_printf(seq, "%i\n", atomic_read(&aggregation_enabled));
+
+	return 0;
+}
+
+static ssize_t proc_aggr_write(struct file *file, const char __user *buffer,
+			       size_t count, loff_t *ppos)
+{
+	char *aggr_string;
+	int not_copied = 0;
+	unsigned long aggregation_enabled_tmp;
+
+	aggr_string = kmalloc(count, GFP_KERNEL);
+
+	if (!aggr_string)
+		return -ENOMEM;
+
+	not_copied = copy_from_user(aggr_string, buffer, count);
+	aggr_string[count - not_copied - 1] = 0;
+
+	strict_strtoul(aggr_string, 10, &aggregation_enabled_tmp);
+
+	if ((aggregation_enabled_tmp != 0) && (aggregation_enabled_tmp != 1)) {
+		debug_log(LOG_TYPE_WARN, "Aggregation can only be enabled (1) or disabled (0), given value: %li\n", aggregation_enabled_tmp);
+		goto end;
+	}
+
+	debug_log(LOG_TYPE_NOTICE, "Changing aggregation from: %s (%i) to: %s (%li)\n",
+		  (atomic_read(&aggregation_enabled) == 1 ?
+		   "enabled" : "disabled"),
+		  atomic_read(&aggregation_enabled),
+		  (aggregation_enabled_tmp == 1 ? "enabled" : "disabled"),
+		  aggregation_enabled_tmp);
+
+	atomic_set(&aggregation_enabled, (unsigned)aggregation_enabled_tmp);
+end:
+	kfree(aggr_string);
+	return count;
+}
+
+static int proc_aggr_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_aggr_read, NULL);
+}
+
+/* satisfying different prototypes ... */
+static ssize_t proc_dummy_write(struct file *file, const char __user *buffer,
+				size_t count, loff_t *ppos)
+{
+	return count;
+}
+
+static const struct file_operations proc_aggr_fops = {
+	.owner		= THIS_MODULE,
+	.open		= proc_aggr_open,
+	.read		= seq_read,
+	.write		= proc_aggr_write,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static const struct file_operations proc_vis_format_fops = {
+	.owner		= THIS_MODULE,
+	.open		= proc_vis_format_open,
+	.read		= seq_read,
+	.write		= proc_vis_format_write,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static const struct file_operations proc_vis_fops = {
+	.owner		= THIS_MODULE,
+	.open		= proc_vis_open,
+	.read		= seq_read,
+	.write		= proc_vis_write,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static const struct file_operations proc_originators_fops = {
+	.owner		= THIS_MODULE,
+	.open		= proc_originators_open,
+	.read		= seq_read,
+	.write		= proc_dummy_write,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static const struct file_operations proc_transt_local_fops = {
+	.owner		= THIS_MODULE,
+	.open		= proc_transt_local_open,
+	.read		= seq_read,
+	.write		= proc_dummy_write,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static const struct file_operations proc_transt_global_fops = {
+	.owner		= THIS_MODULE,
+	.open		= proc_transt_global_open,
+	.read		= seq_read,
+	.write		= proc_dummy_write,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static const struct file_operations proc_log_level_fops = {
+	.owner		= THIS_MODULE,
+	.open		= proc_log_level_open,
+	.read		= seq_read,
+	.write		= proc_log_level_write,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static const struct file_operations proc_interfaces_fops = {
+	.owner		= THIS_MODULE,
+	.open		= proc_interfaces_open,
+	.read		= seq_read,
+	.write		= proc_interfaces_write,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static const struct file_operations proc_orig_interval_fops = {
+	.owner		= THIS_MODULE,
+	.open		= proc_orig_interval_open,
+	.read		= seq_read,
+	.write		= proc_orig_interval_write,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+void cleanup_procfs(void)
+{
+	if (proc_transt_global_file)
+		remove_proc_entry(PROC_FILE_TRANST_GLOBAL, proc_batman_dir);
+
+	if (proc_transt_local_file)
+		remove_proc_entry(PROC_FILE_TRANST_LOCAL, proc_batman_dir);
+
+	if (proc_log_file)
+		remove_proc_entry(PROC_FILE_LOG, proc_batman_dir);
+
+	if (proc_log_level_file)
+		remove_proc_entry(PROC_FILE_LOG_LEVEL, proc_batman_dir);
+
+	if (proc_originators_file)
+		remove_proc_entry(PROC_FILE_ORIGINATORS, proc_batman_dir);
+
+	if (proc_orig_interval_file)
+		remove_proc_entry(PROC_FILE_ORIG_INTERVAL, proc_batman_dir);
+
+	if (proc_interface_file)
+		remove_proc_entry(PROC_FILE_INTERFACES, proc_batman_dir);
+
+	if (proc_vis_file)
+		remove_proc_entry(PROC_FILE_VIS, proc_batman_dir);
+
+	if (proc_vis_format_file)
+		remove_proc_entry(PROC_FILE_VIS_FORMAT, proc_batman_dir);
+
+	if (proc_aggr_file)
+		remove_proc_entry(PROC_FILE_AGGR, proc_batman_dir);
+
+	if (proc_batman_dir)
+#ifdef __NET_NET_NAMESPACE_H
+		remove_proc_entry(PROC_ROOT_DIR, init_net.proc_net);
+#else
+		remove_proc_entry(PROC_ROOT_DIR, proc_net);
+#endif
+}
+
+int setup_procfs(void)
+{
+#ifdef __NET_NET_NAMESPACE_H
+	proc_batman_dir = proc_mkdir(PROC_ROOT_DIR, init_net.proc_net);
+#else
+	proc_batman_dir = proc_mkdir(PROC_ROOT_DIR, proc_net);
+#endif
+
+	if (!proc_batman_dir) {
+		printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s' folder failed\n", PROC_ROOT_DIR);
+		return -EFAULT;
+	}
+
+	proc_interface_file = create_proc_entry(PROC_FILE_INTERFACES,
+						S_IWUSR | S_IRUGO,
+						proc_batman_dir);
+	if (proc_interface_file) {
+		proc_interface_file->proc_fops = &proc_interfaces_fops;
+	} else {
+		printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_INTERFACES);
+		cleanup_procfs();
+		return -EFAULT;
+	}
+
+	proc_orig_interval_file = create_proc_entry(PROC_FILE_ORIG_INTERVAL,
+						    S_IWUSR | S_IRUGO,
+						    proc_batman_dir);
+	if (proc_orig_interval_file) {
+		proc_orig_interval_file->proc_fops = &proc_orig_interval_fops;
+	} else {
+		printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_ORIG_INTERVAL);
+		cleanup_procfs();
+		return -EFAULT;
+	}
+
+	proc_log_level_file = create_proc_entry(PROC_FILE_LOG_LEVEL,
+						S_IWUSR | S_IRUGO,
+						proc_batman_dir);
+	if (proc_log_level_file) {
+		proc_log_level_file->proc_fops = &proc_log_level_fops;
+	} else {
+		printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_LOG_LEVEL);
+		cleanup_procfs();
+		return -EFAULT;
+	}
+
+	proc_originators_file = create_proc_entry(PROC_FILE_ORIGINATORS,
+						  S_IRUGO, proc_batman_dir);
+	if (proc_originators_file) {
+		proc_originators_file->proc_fops = &proc_originators_fops;
+	} else {
+		printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_ORIGINATORS);
+		cleanup_procfs();
+		return -EFAULT;
+	}
+
+	proc_log_file = create_proc_entry(PROC_FILE_LOG,
+					  S_IRUGO, proc_batman_dir);
+	if (proc_log_file) {
+		proc_log_file->proc_fops = &proc_log_operations;
+	} else {
+		printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_FILE_LOG, PROC_FILE_GATEWAYS);
+		cleanup_procfs();
+		return -EFAULT;
+	}
+
+	proc_transt_local_file = create_proc_entry(PROC_FILE_TRANST_LOCAL,
+						   S_IRUGO, proc_batman_dir);
+	if (proc_transt_local_file) {
+		proc_transt_local_file->proc_fops = &proc_transt_local_fops;
+	} else {
+		printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_TRANST_LOCAL);
+		cleanup_procfs();
+		return -EFAULT;
+	}
+
+	proc_transt_global_file = create_proc_entry(PROC_FILE_TRANST_GLOBAL,
+						    S_IRUGO, proc_batman_dir);
+	if (proc_transt_global_file) {
+		proc_transt_global_file->proc_fops = &proc_transt_global_fops;
+	} else {
+		printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_TRANST_GLOBAL);
+		cleanup_procfs();
+		return -EFAULT;
+	}
+
+	proc_vis_file = create_proc_entry(PROC_FILE_VIS, S_IWUSR | S_IRUGO,
+					  proc_batman_dir);
+	if (proc_vis_file) {
+		proc_vis_file->proc_fops = &proc_vis_fops;
+	} else {
+		printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS);
+		cleanup_procfs();
+		return -EFAULT;
+	}
+
+	proc_vis_format_file = create_proc_entry(PROC_FILE_VIS_FORMAT,
+						 S_IWUSR | S_IRUGO,
+						 proc_batman_dir);
+	if (proc_vis_format_file) {
+		proc_vis_format_file->proc_fops = &proc_vis_format_fops;
+	} else {
+		printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS_FORMAT);
+		cleanup_procfs();
+		return -EFAULT;
+	}
+
+	proc_aggr_file = create_proc_entry(PROC_FILE_AGGR, S_IWUSR | S_IRUGO,
+					   proc_batman_dir);
+	if (proc_aggr_file) {
+		proc_aggr_file->proc_fops = &proc_aggr_fops;
+	} else {
+		printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_AGGR);
+		cleanup_procfs();
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+
diff --git a/drivers/staging/batman-adv/proc.h b/drivers/staging/batman-adv/proc.h
new file mode 100644
index 0000000..16d3efd
--- /dev/null
+++ b/drivers/staging/batman-adv/proc.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+#define PROC_ROOT_DIR "batman-adv"
+#define PROC_FILE_INTERFACES "interfaces"
+#define PROC_FILE_ORIG_INTERVAL "orig_interval"
+#define PROC_FILE_ORIGINATORS "originators"
+#define PROC_FILE_GATEWAYS "gateways"
+#define PROC_FILE_LOG "log"
+#define PROC_FILE_LOG_LEVEL "log_level"
+#define PROC_FILE_TRANST_LOCAL "transtable_local"
+#define PROC_FILE_TRANST_GLOBAL "transtable_global"
+#define PROC_FILE_VIS "vis"
+#define PROC_FILE_VIS_FORMAT "vis_format"
+#define PROC_FILE_AGGR "aggregate_ogm"
+
+void cleanup_procfs(void);
+int setup_procfs(void);
+
+/* While scanning for vis-entries of a particular vis-originator
+ * this list collects its interfaces to create a subgraph/cluster
+ * out of them later
+ */
+struct vis_if_list {
+	uint8_t addr[ETH_ALEN];
+	bool primary;
+	struct vis_if_list *next;
+};
diff --git a/drivers/staging/batman-adv/ring_buffer.c b/drivers/staging/batman-adv/ring_buffer.c
new file mode 100644
index 0000000..751c899
--- /dev/null
+++ b/drivers/staging/batman-adv/ring_buffer.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "main.h"
+#include "ring_buffer.h"
+
+void ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, uint8_t value)
+{
+	lq_recv[*lq_index] = value;
+	*lq_index = (*lq_index + 1) % TQ_GLOBAL_WINDOW_SIZE;
+}
+
+uint8_t ring_buffer_avg(uint8_t lq_recv[])
+{
+	uint8_t *ptr;
+	uint16_t count = 0, i = 0, sum = 0;
+
+	ptr = lq_recv;
+
+	while (i < TQ_GLOBAL_WINDOW_SIZE) {
+		if (*ptr != 0) {
+			count++;
+			sum += *ptr;
+		}
+
+		i++;
+		ptr++;
+	}
+
+	if (count == 0)
+		return 0;
+
+	return (uint8_t)(sum / count);
+}
diff --git a/drivers/staging/batman-adv/ring_buffer.h b/drivers/staging/batman-adv/ring_buffer.h
new file mode 100644
index 0000000..6839ba9
--- /dev/null
+++ b/drivers/staging/batman-adv/ring_buffer.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+void ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, uint8_t value);
+uint8_t ring_buffer_avg(uint8_t lq_recv[]);
diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c
new file mode 100644
index 0000000..4a14c36
--- /dev/null
+++ b/drivers/staging/batman-adv/routing.c
@@ -0,0 +1,1010 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+
+
+
+
+#include "main.h"
+#include "routing.h"
+#include "log.h"
+#include "send.h"
+#include "soft-interface.h"
+#include "hard-interface.h"
+#include "device.h"
+#include "translation-table.h"
+#include "types.h"
+#include "hash.h"
+#include "ring_buffer.h"
+#include "vis.h"
+#include "aggregation.h"
+#include "compat.h"
+
+
+
+DECLARE_WAIT_QUEUE_HEAD(thread_wait);
+static DECLARE_DELAYED_WORK(purge_orig_wq, purge_orig);
+
+static atomic_t data_ready_cond;
+atomic_t exit_cond;
+
+static void start_purge_timer(void)
+{
+	queue_delayed_work(bat_event_workqueue, &purge_orig_wq, 1 * HZ);
+}
+
+int originator_init(void)
+{
+	if (orig_hash)
+		return 1;
+
+	spin_lock(&orig_hash_lock);
+	orig_hash = hash_new(128, compare_orig, choose_orig);
+
+	if (!orig_hash)
+		goto err;
+
+	spin_unlock(&orig_hash_lock);
+	start_purge_timer();
+	return 1;
+
+err:
+	spin_unlock(&orig_hash_lock);
+	return 0;
+}
+
+void originator_free(void)
+{
+	if (!orig_hash)
+		return;
+
+	cancel_delayed_work_sync(&purge_orig_wq);
+
+	spin_lock(&orig_hash_lock);
+	hash_delete(orig_hash, free_orig_node);
+	orig_hash = NULL;
+	spin_unlock(&orig_hash_lock);
+}
+
+static struct neigh_node *create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, uint8_t *neigh, struct batman_if *if_incoming)
+{
+	struct neigh_node *neigh_node;
+
+	debug_log(LOG_TYPE_BATMAN, "Creating new last-hop neighbour of originator\n");
+
+	neigh_node = kmalloc(sizeof(struct neigh_node), GFP_ATOMIC);
+	memset(neigh_node, 0, sizeof(struct neigh_node));
+	INIT_LIST_HEAD(&neigh_node->list);
+
+	memcpy(neigh_node->addr, neigh, ETH_ALEN);
+	neigh_node->orig_node = orig_neigh_node;
+	neigh_node->if_incoming = if_incoming;
+
+	list_add_tail(&neigh_node->list, &orig_node->neigh_list);
+	return neigh_node;
+}
+
+void free_orig_node(void *data)
+{
+	struct list_head *list_pos, *list_pos_tmp;
+	struct neigh_node *neigh_node;
+	struct orig_node *orig_node = (struct orig_node *)data;
+
+	/* for all neighbours towards this originator ... */
+	list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) {
+		neigh_node = list_entry(list_pos, struct neigh_node, list);
+
+		list_del(list_pos);
+		kfree(neigh_node);
+	}
+
+	hna_global_del_orig(orig_node, "originator timed out");
+
+	kfree(orig_node->bcast_own);
+	kfree(orig_node->bcast_own_sum);
+	kfree(orig_node);
+}
+
+/* this function finds or creates an originator entry for the given address if it does not exits */
+static struct orig_node *get_orig_node(uint8_t *addr)
+{
+	struct orig_node *orig_node;
+	struct hashtable_t *swaphash;
+	char orig_str[ETH_STR_LEN];
+
+	orig_node = ((struct orig_node *)hash_find(orig_hash, addr));
+
+	if (orig_node != NULL)
+		return orig_node;
+
+	addr_to_string(orig_str, addr);
+	debug_log(LOG_TYPE_BATMAN, "Creating new originator: %s \n", orig_str);
+
+	orig_node = kmalloc(sizeof(struct orig_node), GFP_ATOMIC);
+	memset(orig_node, 0, sizeof(struct orig_node));
+	INIT_LIST_HEAD(&orig_node->neigh_list);
+
+	memcpy(orig_node->orig, addr, ETH_ALEN);
+	orig_node->router = NULL;
+	orig_node->batman_if = NULL;
+	orig_node->hna_buff = NULL;
+
+	orig_node->bcast_own = kmalloc(num_ifs * sizeof(TYPE_OF_WORD) * NUM_WORDS, GFP_ATOMIC);
+	memset(orig_node->bcast_own, 0, num_ifs * sizeof(TYPE_OF_WORD) * NUM_WORDS);
+
+	orig_node->bcast_own_sum = kmalloc(num_ifs * sizeof(uint8_t), GFP_ATOMIC);
+	memset(orig_node->bcast_own_sum, 0, num_ifs * sizeof(uint8_t));
+
+	hash_add(orig_hash, orig_node);
+
+	if (orig_hash->elements * 4 > orig_hash->size) {
+		swaphash = hash_resize(orig_hash, orig_hash->size * 2);
+
+		if (swaphash == NULL)
+			debug_log(LOG_TYPE_CRIT, "Couldn't resize orig hash table \n");
+		else
+			orig_hash = swaphash;
+	}
+
+	return orig_node;
+}
+
+void slide_own_bcast_window(struct batman_if *batman_if)
+{
+	struct hash_it_t *hashit = NULL;
+	struct orig_node *orig_node;
+
+	spin_lock(&orig_hash_lock);
+
+	while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
+		orig_node = hashit->bucket->data;
+
+		bit_get_packet((TYPE_OF_WORD *)&(orig_node->bcast_own[batman_if->if_num * NUM_WORDS]), 1, 0);
+		orig_node->bcast_own_sum[batman_if->if_num] = bit_packet_count((TYPE_OF_WORD *)&(orig_node->bcast_own[batman_if->if_num * NUM_WORDS]));
+	}
+
+	spin_unlock(&orig_hash_lock);
+}
+
+static void update_routes(struct orig_node *orig_node, struct neigh_node *neigh_node, unsigned char *hna_buff, int hna_buff_len)
+{
+	char orig_str[ETH_STR_LEN], neigh_str[ETH_STR_LEN], router_str[ETH_STR_LEN];
+
+	if (orig_node == NULL)
+		return;
+
+	if (orig_node->router != neigh_node) {
+		addr_to_string(orig_str, orig_node->orig);
+
+		/* route deleted */
+		if ((orig_node->router != NULL) && (neigh_node == NULL)) {
+
+			debug_log(LOG_TYPE_ROUTES, "Deleting route towards: %s\n", orig_str);
+			hna_global_del_orig(orig_node, "originator timed out");
+
+		/* route added */
+		} else if ((orig_node->router == NULL) && (neigh_node != NULL)) {
+
+			addr_to_string(neigh_str, neigh_node->addr);
+			debug_log(LOG_TYPE_ROUTES, "Adding route towards: %s (via %s)\n", orig_str, neigh_str);
+			hna_global_add_orig(orig_node, hna_buff, hna_buff_len);
+
+		/* route changed */
+		} else {
+
+			addr_to_string(neigh_str, neigh_node->addr);
+			addr_to_string(router_str, orig_node->router->addr);
+			debug_log(LOG_TYPE_ROUTES, "Changing route towards: %s (now via %s - was via %s)\n", orig_str, neigh_str, router_str);
+
+		}
+
+		if (neigh_node != NULL)
+			orig_node->batman_if = neigh_node->if_incoming;
+		else
+			orig_node->batman_if = NULL;
+
+		orig_node->router = neigh_node;
+
+	/* may be just HNA changed */
+	} else {
+
+		if ((hna_buff_len != orig_node->hna_buff_len) || ((hna_buff_len > 0) && (orig_node->hna_buff_len > 0) && (memcmp(orig_node->hna_buff, hna_buff, hna_buff_len) != 0))) {
+
+			if (orig_node->hna_buff_len > 0)
+				hna_global_del_orig(orig_node, "originator changed hna");
+
+			if ((hna_buff_len > 0) && (hna_buff != NULL))
+				hna_global_add_orig(orig_node, hna_buff, hna_buff_len);
+
+		}
+
+	}
+}
+
+static int isBidirectionalNeigh(struct orig_node *orig_node, struct orig_node *orig_neigh_node, struct batman_packet *batman_packet, struct batman_if *if_incoming)
+{
+	struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
+	char orig_str[ETH_STR_LEN], neigh_str[ETH_STR_LEN];
+	unsigned char total_count;
+
+	addr_to_string(orig_str, orig_node->orig);
+	addr_to_string(neigh_str, orig_neigh_node->orig);
+
+	if (orig_node == orig_neigh_node) {
+		list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
+
+			if (compare_orig(tmp_neigh_node->addr, orig_neigh_node->orig) && (tmp_neigh_node->if_incoming == if_incoming))
+				neigh_node = tmp_neigh_node;
+		}
+
+		if (neigh_node == NULL)
+			neigh_node = create_neighbor(orig_node, orig_neigh_node, orig_neigh_node->orig, if_incoming);
+
+		neigh_node->last_valid = jiffies;
+	} else {
+		/* find packet count of corresponding one hop neighbor */
+		list_for_each_entry(tmp_neigh_node, &orig_neigh_node->neigh_list, list) {
+
+			if (compare_orig(tmp_neigh_node->addr, orig_neigh_node->orig) && (tmp_neigh_node->if_incoming == if_incoming))
+				neigh_node = tmp_neigh_node;
+		}
+
+		if (neigh_node == NULL)
+			neigh_node = create_neighbor(orig_neigh_node, orig_neigh_node, orig_neigh_node->orig, if_incoming);
+	}
+
+	orig_node->last_valid = jiffies;
+
+	/* pay attention to not get a value bigger than 100 % */
+	total_count = (orig_neigh_node->bcast_own_sum[if_incoming->if_num] > neigh_node->real_packet_count ? neigh_node->real_packet_count : orig_neigh_node->bcast_own_sum[if_incoming->if_num]);
+
+	/* if we have too few packets (too less data) we set tq_own to zero */
+	/* if we receive too few packets it is not considered bidirectional */
+	if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) || (neigh_node->real_packet_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM))
+		orig_neigh_node->tq_own = 0;
+	else
+		/* neigh_node->real_packet_count is never zero as we only purge old information when getting new information */
+		orig_neigh_node->tq_own = (TQ_MAX_VALUE * total_count) / neigh_node->real_packet_count;
+
+	/*
+	 * 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE
+	 * this does affect the nearly-symmetric links only a little,
+	 * but punishes asymmetric links more.
+	 * this will give a value between 0 and TQ_MAX_VALUE
+	 */
+	orig_neigh_node->tq_asym_penalty = TQ_MAX_VALUE - (TQ_MAX_VALUE *
+			(TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) *
+			(TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) *
+			(TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count)) /
+			(TQ_LOCAL_WINDOW_SIZE * TQ_LOCAL_WINDOW_SIZE * TQ_LOCAL_WINDOW_SIZE);
+
+	batman_packet->tq = ((batman_packet->tq * orig_neigh_node->tq_own * orig_neigh_node->tq_asym_penalty) / (TQ_MAX_VALUE *  TQ_MAX_VALUE));
+
+	debug_log(LOG_TYPE_BATMAN, "bidirectional: orig = %-15s neigh = %-15s => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i \n",
+		  orig_str, neigh_str, total_count, neigh_node->real_packet_count, orig_neigh_node->tq_own, orig_neigh_node->tq_asym_penalty, batman_packet->tq);
+
+	/* if link has the minimum required transmission quality consider it bidirectional */
+	if (batman_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT)
+		return 1;
+
+	return 0;
+}
+
+static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, struct batman_packet *batman_packet, struct batman_if *if_incoming, unsigned char *hna_buff, int hna_buff_len, char is_duplicate)
+{
+	struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
+	int tmp_hna_buff_len;
+
+	debug_log(LOG_TYPE_BATMAN, "update_originator(): Searching and updating originator entry of received packet \n");
+
+	list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
+		if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && (tmp_neigh_node->if_incoming == if_incoming)) {
+			neigh_node = tmp_neigh_node;
+			continue;
+		}
+
+		if (is_duplicate)
+			continue;
+
+		ring_buffer_set(tmp_neigh_node->tq_recv, &tmp_neigh_node->tq_index, 0);
+		tmp_neigh_node->tq_avg = ring_buffer_avg(tmp_neigh_node->tq_recv);
+	}
+
+	if (neigh_node == NULL)
+		neigh_node = create_neighbor(orig_node, get_orig_node(ethhdr->h_source), ethhdr->h_source, if_incoming);
+	else
+		debug_log(LOG_TYPE_BATMAN, "Updating existing last-hop neighbour of originator\n");
+
+	orig_node->flags = batman_packet->flags;
+	neigh_node->last_valid = jiffies;
+
+	ring_buffer_set(neigh_node->tq_recv, &neigh_node->tq_index, batman_packet->tq);
+	neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv);
+
+	if (!is_duplicate) {
+		orig_node->last_ttl = batman_packet->ttl;
+		neigh_node->last_ttl = batman_packet->ttl;
+	}
+
+	tmp_hna_buff_len = (hna_buff_len > batman_packet->num_hna * ETH_ALEN ? batman_packet->num_hna * ETH_ALEN : hna_buff_len);
+
+	/* if this neighbor already is our next hop there is nothing to change */
+	if (orig_node->router == neigh_node)
+		goto update_hna;
+
+	/* if this neighbor does not offer a better TQ we won't consider it */
+	if ((orig_node->router) &&
+	    (orig_node->router->tq_avg > neigh_node->tq_avg))
+		goto update_hna;
+
+	/* if the TQ is the same and the link not more symetric we won't consider it either */
+	if ((orig_node->router) &&
+	     ((neigh_node->tq_avg == orig_node->router->tq_avg) &&
+	     (orig_node->router->orig_node->bcast_own_sum[if_incoming->if_num] >=
+	      neigh_node->orig_node->bcast_own_sum[if_incoming->if_num])))
+		goto update_hna;
+
+	update_routes(orig_node, neigh_node, hna_buff, tmp_hna_buff_len);
+	return;
+
+update_hna:
+	update_routes(orig_node, orig_node->router, hna_buff, tmp_hna_buff_len);
+	return;
+}
+
+static char count_real_packets(struct ethhdr *ethhdr, struct batman_packet *batman_packet, struct batman_if *if_incoming)
+{
+	struct orig_node *orig_node;
+	struct neigh_node *tmp_neigh_node;
+	char is_duplicate = 0;
+
+
+	orig_node = get_orig_node(batman_packet->orig);
+	if (orig_node == NULL)
+		return 0;
+
+
+	list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
+
+		if (!is_duplicate)
+			is_duplicate = get_bit_status(tmp_neigh_node->real_bits, orig_node->last_real_seqno, batman_packet->seqno);
+
+		if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && (tmp_neigh_node->if_incoming == if_incoming))
+			bit_get_packet(tmp_neigh_node->real_bits, batman_packet->seqno - orig_node->last_real_seqno, 1);
+		else
+			bit_get_packet(tmp_neigh_node->real_bits, batman_packet->seqno - orig_node->last_real_seqno, 0);
+
+		tmp_neigh_node->real_packet_count = bit_packet_count(tmp_neigh_node->real_bits);
+	}
+
+	if (!is_duplicate) {
+		debug_log(LOG_TYPE_BATMAN, "updating last_seqno: old %d, new %d \n", orig_node->last_real_seqno, batman_packet->seqno);
+		orig_node->last_real_seqno = batman_packet->seqno;
+	}
+
+	return is_duplicate;
+}
+
+void receive_bat_packet(struct ethhdr *ethhdr, struct batman_packet *batman_packet, unsigned char *hna_buff, int hna_buff_len, struct batman_if *if_incoming)
+{
+	struct batman_if *batman_if;
+	struct orig_node *orig_neigh_node, *orig_node;
+	char orig_str[ETH_STR_LEN], prev_sender_str[ETH_STR_LEN], neigh_str[ETH_STR_LEN];
+	char has_directlink_flag;
+	char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0, is_broadcast = 0, is_bidirectional, is_single_hop_neigh, is_duplicate;
+	unsigned short if_incoming_seqno;
+
+	/* Silently drop when the batman packet is actually not a correct packet.
+	 *
+	 * This might happen if a packet is padded (e.g. Ethernet has a
+	 * minimum frame length of 64 byte) and the aggregation interprets
+	 * it as an additional length.
+	 *
+	 * TODO: A more sane solution would be to have a bit in the batman_packet
+	 * to detect whether the packet is the last packet in an aggregation.
+	 * Here we expect that the padding is always zero (or not 0x01)
+	 */
+	if (batman_packet->packet_type != BAT_PACKET)
+		return;
+
+	/* could be changed by schedule_own_packet() */
+	if_incoming_seqno = atomic_read(&if_incoming->seqno);
+
+	addr_to_string(orig_str, batman_packet->orig);
+	addr_to_string(prev_sender_str, batman_packet->prev_sender);
+	addr_to_string(neigh_str, ethhdr->h_source);
+
+	has_directlink_flag = (batman_packet->flags & DIRECTLINK ? 1 : 0);
+
+	is_single_hop_neigh = (compare_orig(ethhdr->h_source, batman_packet->orig) ? 1 : 0);
+
+	debug_log(LOG_TYPE_BATMAN, "Received BATMAN packet via NB: %s, IF: %s [%s] (from OG: %s, via prev OG: %s, seqno %d, tq %d, TTL %d, V %d, IDF %d) \n", neigh_str, if_incoming->dev, if_incoming->addr_str, orig_str, prev_sender_str, batman_packet->seqno, batman_packet->tq, batman_packet->ttl, batman_packet->version, has_directlink_flag);
+
+	list_for_each_entry_rcu(batman_if, &if_list, list) {
+		if (batman_if->if_active != IF_ACTIVE)
+			continue;
+
+		if (compare_orig(ethhdr->h_source, batman_if->net_dev->dev_addr))
+			is_my_addr = 1;
+
+		if (compare_orig(batman_packet->orig, batman_if->net_dev->dev_addr))
+			is_my_orig = 1;
+
+		if (compare_orig(batman_packet->prev_sender, batman_if->net_dev->dev_addr))
+			is_my_oldorig = 1;
+
+		if (compare_orig(ethhdr->h_source, broadcastAddr))
+			is_broadcast = 1;
+	}
+
+	if (batman_packet->version != COMPAT_VERSION) {
+		debug_log(LOG_TYPE_BATMAN, "Drop packet: incompatible batman version (%i) \n", batman_packet->version);
+		return;
+	}
+
+	if (is_my_addr) {
+		debug_log(LOG_TYPE_BATMAN, "Drop packet: received my own broadcast (sender: %s) \n", neigh_str);
+		return;
+	}
+
+	if (is_broadcast) {
+		debug_log(LOG_TYPE_BATMAN, "Drop packet: ignoring all packets with broadcast source addr (sender: %s) \n", neigh_str);
+		return;
+	}
+
+	if (is_my_orig) {
+		orig_neigh_node = get_orig_node(ethhdr->h_source);
+
+		/* neighbour has to indicate direct link and it has to come via the corresponding interface */
+		/* if received seqno equals last send seqno save new seqno for bidirectional check */
+		if (has_directlink_flag && compare_orig(if_incoming->net_dev->dev_addr, batman_packet->orig) &&
+				  (batman_packet->seqno - if_incoming_seqno + 2 == 0)) {
+			bit_mark((TYPE_OF_WORD *)&(orig_neigh_node->bcast_own[if_incoming->if_num * NUM_WORDS]), 0);
+			orig_neigh_node->bcast_own_sum[if_incoming->if_num] = bit_packet_count((TYPE_OF_WORD *)&(orig_neigh_node->bcast_own[if_incoming->if_num * NUM_WORDS]));
+		}
+
+		debug_log(LOG_TYPE_BATMAN, "Drop packet: originator packet from myself (via neighbour) \n");
+		return;
+	}
+
+	if (batman_packet->tq == 0) {
+		count_real_packets(ethhdr, batman_packet, if_incoming);
+
+		debug_log(LOG_TYPE_BATMAN, "Drop packet: originator packet with tq equal 0 \n");
+		return;
+	}
+
+	if (is_my_oldorig) {
+		debug_log(LOG_TYPE_BATMAN, "Drop packet: ignoring all rebroadcast echos (sender: %s) \n", neigh_str);
+		return;
+	}
+
+	is_duplicate = count_real_packets(ethhdr, batman_packet, if_incoming);
+
+	orig_node = get_orig_node(batman_packet->orig);
+	if (orig_node == NULL)
+		return;
+
+	/* avoid temporary routing loops */
+	if ((orig_node->router) && (orig_node->router->orig_node->router) &&
+	    (compare_orig(orig_node->router->addr, batman_packet->prev_sender)) &&
+	    !(compare_orig(batman_packet->orig, batman_packet->prev_sender)) &&
+	    (compare_orig(orig_node->router->addr, orig_node->router->orig_node->router->addr))) {
+		debug_log(LOG_TYPE_BATMAN, "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %s) \n", neigh_str);
+		return;
+	}
+
+	/* if sender is a direct neighbor the sender mac equals originator mac */
+	orig_neigh_node = (is_single_hop_neigh ? orig_node : get_orig_node(ethhdr->h_source));
+	if (orig_neigh_node == NULL)
+		return;
+
+	/* drop packet if sender is not a direct neighbor and if we don't route towards it */
+	if (!is_single_hop_neigh && (orig_neigh_node->router == NULL)) {
+		debug_log(LOG_TYPE_BATMAN, "Drop packet: OGM via unknown neighbor! \n");
+		return;
+	}
+
+	is_bidirectional = isBidirectionalNeigh(orig_node, orig_neigh_node, batman_packet, if_incoming);
+
+	/* update ranking if it is not a duplicate or has the same seqno and similar ttl as the non-duplicate */
+	if (is_bidirectional && (!is_duplicate ||
+		((orig_node->last_real_seqno == batman_packet->seqno) &&
+			(orig_node->last_ttl - 3 <= batman_packet->ttl))))
+		update_orig(orig_node, ethhdr, batman_packet, if_incoming, hna_buff, hna_buff_len, is_duplicate);
+
+	/* is single hop (direct) neighbour */
+	if (is_single_hop_neigh) {
+
+		/* mark direct link on incoming interface */
+		schedule_forward_packet(orig_node, ethhdr, batman_packet, 1, hna_buff_len, if_incoming);
+
+		debug_log(LOG_TYPE_BATMAN, "Forwarding packet: rebroadcast neighbour packet with direct link flag \n");
+		return;
+	}
+
+	/* multihop originator */
+	if (!is_bidirectional) {
+		debug_log(LOG_TYPE_BATMAN, "Drop packet: not received via bidirectional link\n");
+		return;
+	}
+
+	if (is_duplicate) {
+		debug_log(LOG_TYPE_BATMAN, "Drop packet: duplicate packet received\n");
+		return;
+	}
+
+	debug_log(LOG_TYPE_BATMAN, "Forwarding packet: rebroadcast originator packet \n");
+	schedule_forward_packet(orig_node, ethhdr, batman_packet, 0, hna_buff_len, if_incoming);
+}
+
+void purge_orig(struct work_struct *work)
+{
+	struct list_head *list_pos, *list_pos_tmp;
+	struct hash_it_t *hashit = NULL;
+	struct orig_node *orig_node;
+	struct neigh_node *neigh_node, *best_neigh_node;
+	char orig_str[ETH_STR_LEN], neigh_str[ETH_STR_LEN], neigh_purged;
+
+	spin_lock(&orig_hash_lock);
+
+	/* for all origins... */
+	while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
+
+		orig_node = hashit->bucket->data;
+		addr_to_string(orig_str, orig_node->orig);
+
+		if (time_after(jiffies, orig_node->last_valid + ((2 * PURGE_TIMEOUT * HZ) / 1000))) {
+
+			debug_log(LOG_TYPE_BATMAN, "Originator timeout: originator %s, last_valid %u \n", orig_str, (orig_node->last_valid / HZ));
+
+			hash_remove_bucket(orig_hash, hashit);
+			free_orig_node(orig_node);
+
+		} else {
+
+			best_neigh_node = NULL;
+			neigh_purged = 0;
+
+			/* for all neighbours towards this originator ... */
+			list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) {
+				neigh_node = list_entry(list_pos, struct neigh_node, list);
+
+				if (time_after(jiffies, neigh_node->last_valid + ((PURGE_TIMEOUT * HZ) / 1000))) {
+
+					addr_to_string(neigh_str, neigh_node->addr);
+					debug_log(LOG_TYPE_BATMAN, "Neighbour timeout: originator %s, neighbour: %s, last_valid %u \n", orig_str, neigh_str, (neigh_node->last_valid / HZ));
+
+					neigh_purged = 1;
+					list_del(list_pos);
+					kfree(neigh_node);
+
+				} else {
+
+					if ((best_neigh_node == NULL) || (neigh_node->tq_avg > best_neigh_node->tq_avg))
+						best_neigh_node = neigh_node;
+
+				}
+
+			}
+
+			if (neigh_purged)
+				update_routes(orig_node, best_neigh_node, orig_node->hna_buff, orig_node->hna_buff_len);
+
+		}
+
+	}
+
+	spin_unlock(&orig_hash_lock);
+
+	start_purge_timer();
+}
+
+static int receive_raw_packet(struct socket *raw_sock, unsigned char *packet_buff, int packet_buff_len)
+{
+	struct kvec iov;
+	struct msghdr msg;
+
+	iov.iov_base = packet_buff;
+	iov.iov_len = packet_buff_len;
+
+	msg.msg_flags = MSG_DONTWAIT;	/* non-blocking */
+	msg.msg_name = NULL;
+	msg.msg_namelen = 0;
+	msg.msg_control = NULL;
+
+	return kernel_recvmsg(raw_sock, &msg, &iov, 1, packet_buff_len, MSG_DONTWAIT);
+}
+
+int packet_recv_thread(void *data)
+{
+	struct batman_if *batman_if;
+	struct ethhdr *ethhdr;
+	struct batman_packet *batman_packet;
+	struct unicast_packet *unicast_packet;
+	struct bcast_packet *bcast_packet;
+	struct icmp_packet *icmp_packet;
+	struct vis_packet *vis_packet;
+	struct orig_node *orig_node;
+	unsigned char *packet_buff, src_str[ETH_STR_LEN], dst_str[ETH_STR_LEN];
+	int vis_info_len;
+	int result;
+
+	atomic_set(&data_ready_cond, 0);
+	atomic_set(&exit_cond, 0);
+	packet_buff = kmalloc(PACKBUFF_SIZE, GFP_KERNEL);
+	if (!packet_buff) {
+		debug_log(LOG_TYPE_CRIT, "Could allocate memory for the packet buffer. :(\n");
+		return -1;
+	}
+
+	while ((!kthread_should_stop()) && (!atomic_read(&exit_cond))) {
+
+		wait_event_interruptible(thread_wait, (atomic_read(&data_ready_cond) || atomic_read(&exit_cond)));
+
+		atomic_set(&data_ready_cond, 0);
+
+		if (kthread_should_stop() || atomic_read(&exit_cond))
+			break;
+
+		/* we only want to safely traverse the list, hard-interfaces
+		 * won't be deleted anyway as long as this thread runs. */
+
+		rcu_read_lock();
+		list_for_each_entry_rcu(batman_if, &if_list, list) {
+			rcu_read_unlock();
+
+			result = -1;
+
+			while (1) {
+				if (batman_if->if_active != IF_ACTIVE) {
+					if (batman_if->if_active != IF_TO_BE_ACTIVATED)
+						debug_log(LOG_TYPE_NOTICE,
+						          "Could not read from deactivated interface %s!\n",
+						          batman_if->dev);
+
+					if (batman_if->raw_sock)
+						receive_raw_packet(batman_if->raw_sock, packet_buff, PACKBUFF_SIZE);
+					result = 0;
+					break;
+				}
+
+				result = receive_raw_packet(batman_if->raw_sock, packet_buff, PACKBUFF_SIZE);
+				if (result <= 0)
+					break;
+
+				if (result < sizeof(struct ethhdr) + 2)
+					continue;
+
+				ethhdr = (struct ethhdr *)packet_buff;
+				batman_packet = (struct batman_packet *)(packet_buff + sizeof(struct ethhdr));
+
+				if (batman_packet->version != COMPAT_VERSION) {
+					debug_log(LOG_TYPE_BATMAN, "Drop packet: incompatible batman version (%i) \n", batman_packet->version);
+					continue;
+				}
+
+				switch (batman_packet->packet_type) {
+				/* batman originator packet */
+				case BAT_PACKET:
+					/* packet with broadcast indication but unicast recipient */
+					if (!is_bcast(ethhdr->h_dest))
+						continue;
+
+					/* packet with broadcast sender address */
+					if (is_bcast(ethhdr->h_source))
+						continue;
+
+					/* drop packet if it has not at least one batman packet as payload */
+					if (result < sizeof(struct ethhdr) + sizeof(struct batman_packet))
+						continue;
+
+					spin_lock(&orig_hash_lock);
+					receive_aggr_bat_packet(ethhdr,
+					                        packet_buff + sizeof(struct ethhdr),
+					                        result - sizeof(struct ethhdr),
+					                        batman_if);
+					spin_unlock(&orig_hash_lock);
+
+					break;
+
+				/* batman icmp packet */
+				case BAT_ICMP:
+					/* packet with unicast indication but broadcast recipient */
+					if (is_bcast(ethhdr->h_dest))
+						continue;
+
+					/* packet with broadcast sender address */
+					if (is_bcast(ethhdr->h_source))
+						continue;
+
+					/* not for me */
+					if (!is_my_mac(ethhdr->h_dest))
+						continue;
+
+					/* drop packet if it has not necessary minimum size */
+					if (result < sizeof(struct ethhdr) + sizeof(struct icmp_packet))
+						continue;
+
+					icmp_packet = (struct icmp_packet *)(packet_buff + sizeof(struct ethhdr));
+
+					/* packet for me */
+					if (is_my_mac(icmp_packet->dst)) {
+
+						/* add data to device queue */
+						if (icmp_packet->msg_type != ECHO_REQUEST) {
+							bat_device_receive_packet(icmp_packet);
+							continue;
+						}
+
+						/* answer echo request (ping) */
+						/* get routing information */
+						spin_lock(&orig_hash_lock);
+						orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet->orig));
+
+						if ((orig_node != NULL) && (orig_node->batman_if != NULL) && (orig_node->router != NULL)) {
+
+							memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
+							memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
+							icmp_packet->msg_type = ECHO_REPLY;
+							icmp_packet->ttl = TTL;
+
+							send_raw_packet(packet_buff + sizeof(struct ethhdr),
+							                result - sizeof(struct ethhdr),
+							                orig_node->batman_if,
+							                orig_node->router->addr);
+
+						}
+
+						spin_unlock(&orig_hash_lock);
+						continue;
+
+					}
+
+					/* TTL exceeded */
+					if (icmp_packet->ttl < 2) {
+
+						addr_to_string(src_str, icmp_packet->orig);
+						addr_to_string(dst_str, icmp_packet->dst);
+
+						debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from %s to %s: ttl exceeded\n", src_str, dst_str);
+
+						/* send TTL exceeded if packet is an echo request (traceroute) */
+						if (icmp_packet->msg_type != ECHO_REQUEST)
+							continue;
+
+						/* get routing information */
+						spin_lock(&orig_hash_lock);
+						orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet->orig));
+
+						if ((orig_node != NULL) && (orig_node->batman_if != NULL) && (orig_node->router != NULL)) {
+
+							memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
+							memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
+							icmp_packet->msg_type = TTL_EXCEEDED;
+							icmp_packet->ttl = TTL;
+
+							send_raw_packet(packet_buff + sizeof(struct ethhdr),
+							                result - sizeof(struct ethhdr),
+							                orig_node->batman_if,
+							                orig_node->router->addr);
+
+						}
+
+						spin_unlock(&orig_hash_lock);
+						continue;
+
+					}
+
+					/* get routing information */
+					spin_lock(&orig_hash_lock);
+					orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet->dst));
+
+					if ((orig_node != NULL) && (orig_node->batman_if != NULL) && (orig_node->router != NULL)) {
+
+						/* decrement ttl */
+						icmp_packet->ttl--;
+
+						/* route it */
+						send_raw_packet(packet_buff + sizeof(struct ethhdr),
+						                result - sizeof(struct ethhdr),
+						                orig_node->batman_if,
+						                orig_node->router->addr);
+					}
+
+					spin_unlock(&orig_hash_lock);
+					break;
+
+				/* unicast packet */
+				case BAT_UNICAST:
+					/* packet with unicast indication but broadcast recipient */
+					if (is_bcast(ethhdr->h_dest))
+						continue;
+
+					/* packet with broadcast sender address */
+					if (is_bcast(ethhdr->h_source))
+						continue;
+
+					/* not for me */
+					if (!is_my_mac(ethhdr->h_dest))
+						continue;
+
+					/* drop packet if it has not necessary minimum size */
+					if (result < sizeof(struct ethhdr) + sizeof(struct unicast_packet))
+						continue;
+
+					unicast_packet = (struct unicast_packet *)(packet_buff + sizeof(struct ethhdr));
+
+					/* packet for me */
+					if (is_my_mac(unicast_packet->dest)) {
+
+						interface_rx(soft_device, packet_buff + sizeof(struct ethhdr) + sizeof(struct unicast_packet), result - sizeof(struct ethhdr) - sizeof(struct unicast_packet));
+						continue;
+
+					}
+
+					/* TTL exceeded */
+					if (unicast_packet->ttl < 2) {
+						addr_to_string(src_str, ((struct ethhdr *)(unicast_packet + 1))->h_source);
+						addr_to_string(dst_str, unicast_packet->dest);
+
+						debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from %s to %s: ttl exceeded\n", src_str, dst_str);
+						continue;
+					}
+
+					/* get routing information */
+					spin_lock(&orig_hash_lock);
+					orig_node = ((struct orig_node *)hash_find(orig_hash, unicast_packet->dest));
+
+					if ((orig_node != NULL) && (orig_node->batman_if != NULL) && (orig_node->router != NULL)) {
+						/* decrement ttl */
+						unicast_packet->ttl--;
+
+						/* route it */
+						send_raw_packet(packet_buff + sizeof(struct ethhdr),
+						                result - sizeof(struct ethhdr),
+						                orig_node->batman_if,
+						                orig_node->router->addr);
+					}
+
+					spin_unlock(&orig_hash_lock);
+					break;
+
+				/* broadcast packet */
+				case BAT_BCAST:
+					/* packet with broadcast indication but unicast recipient */
+					if (!is_bcast(ethhdr->h_dest))
+						continue;
+
+					/* packet with broadcast sender address */
+					if (is_bcast(ethhdr->h_source))
+						continue;
+
+					/* drop packet if it has not necessary minimum size */
+					if (result < sizeof(struct ethhdr) + sizeof(struct bcast_packet))
+						continue;
+
+					/* ignore broadcasts sent by myself */
+					if (is_my_mac(ethhdr->h_source))
+						continue;
+
+					bcast_packet = (struct bcast_packet *)(packet_buff + sizeof(struct ethhdr));
+
+					/* ignore broadcasts originated by myself */
+					if (is_my_mac(bcast_packet->orig))
+						continue;
+
+					spin_lock(&orig_hash_lock);
+					orig_node = ((struct orig_node *)hash_find(orig_hash, bcast_packet->orig));
+
+					if (orig_node == NULL) {
+						spin_unlock(&orig_hash_lock);
+						continue;
+					}
+
+					/* check flood history */
+					if (get_bit_status(orig_node->bcast_bits, orig_node->last_bcast_seqno, ntohs(bcast_packet->seqno))) {
+						spin_unlock(&orig_hash_lock);
+						continue;
+					}
+
+					/* mark broadcast in flood history */
+					if (bit_get_packet(orig_node->bcast_bits, ntohs(bcast_packet->seqno) - orig_node->last_bcast_seqno, 1))
+						orig_node->last_bcast_seqno = ntohs(bcast_packet->seqno);
+
+					spin_unlock(&orig_hash_lock);
+
+					/* broadcast for me */
+					interface_rx(soft_device, packet_buff + sizeof(struct ethhdr) + sizeof(struct bcast_packet), result - sizeof(struct ethhdr) - sizeof(struct bcast_packet));
+
+					/* rebroadcast packet */
+					add_bcast_packet_to_list(packet_buff + sizeof(struct ethhdr),
+									result - sizeof(struct ethhdr));
+
+					break;
+
+				/* vis packet */
+				case BAT_VIS:
+					/* drop if too short. */
+					if (result < sizeof(struct ethhdr) + sizeof(struct vis_packet))
+						continue;
+
+					/* not for me */
+					if (!is_my_mac(ethhdr->h_dest))
+						continue;
+
+					vis_packet = (struct vis_packet *)(packet_buff + sizeof(struct ethhdr));
+					vis_info_len = result  - sizeof(struct ethhdr) - sizeof(struct vis_packet);
+
+					/* ignore own packets */
+					if (is_my_mac(vis_packet->vis_orig))
+						continue;
+
+					if (is_my_mac(vis_packet->sender_orig))
+						continue;
+
+					switch (vis_packet->vis_type) {
+					case VIS_TYPE_SERVER_SYNC:
+						receive_server_sync_packet(vis_packet, vis_info_len);
+						break;
+
+					case VIS_TYPE_CLIENT_UPDATE:
+						receive_client_update_packet(vis_packet, vis_info_len);
+						break;
+
+					default:	/* ignore unknown packet */
+						break;
+					}
+
+					break;
+				}
+
+			}
+
+			if ((result < 0) && (result != -EAGAIN))
+				debug_log(LOG_TYPE_CRIT, "Could not receive packet from interface %s: %i\n", batman_if->dev, result);
+
+			/* lock for the next iteration */
+			rcu_read_lock();
+		}
+		rcu_read_unlock();
+
+	}
+	kfree(packet_buff);
+
+	/* do not exit until kthread_stop() is actually called, otherwise it will wait for us
+	 * forever. */
+	while (!kthread_should_stop())
+		schedule();
+
+	return 0;
+}
+
+void batman_data_ready(struct sock *sk, int len)
+{
+	void (*data_ready)(struct sock *, int) = sk->sk_user_data;
+
+	data_ready(sk, len);
+
+	atomic_set(&data_ready_cond, 1);
+	wake_up_interruptible(&thread_wait);
+}
+
diff --git a/drivers/staging/batman-adv/routing.h b/drivers/staging/batman-adv/routing.h
new file mode 100644
index 0000000..0123ea8
--- /dev/null
+++ b/drivers/staging/batman-adv/routing.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "types.h"
+
+extern wait_queue_head_t thread_wait;
+extern atomic_t exit_cond;
+
+int originator_init(void);
+void free_orig_node(void *data);
+void originator_free(void);
+void slide_own_bcast_window(struct batman_if *batman_if);
+void batman_data_ready(struct sock *sk, int len);
+void purge_orig(struct work_struct *work);
+int packet_recv_thread(void *data);
+void receive_bat_packet(struct ethhdr *ethhdr, struct batman_packet *batman_packet, unsigned char *hna_buff, int hna_buff_len, struct batman_if *if_incoming);
diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c
new file mode 100644
index 0000000..d724798
--- /dev/null
+++ b/drivers/staging/batman-adv/send.c
@@ -0,0 +1,473 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "main.h"
+#include "send.h"
+#include "log.h"
+#include "routing.h"
+#include "translation-table.h"
+#include "hard-interface.h"
+#include "types.h"
+#include "vis.h"
+#include "aggregation.h"
+
+#include "compat.h"
+
+/* apply hop penalty for a normal link */
+static uint8_t hop_penalty(const uint8_t tq)
+{
+	return (tq * (TQ_MAX_VALUE - TQ_HOP_PENALTY)) / (TQ_MAX_VALUE);
+}
+
+/* when do we schedule our own packet to be sent */
+static unsigned long own_send_time(void)
+{
+	return jiffies +
+		(((atomic_read(&originator_interval) - JITTER +
+		   (random32() % 2*JITTER)) * HZ) / 1000);
+}
+
+/* when do we schedule a forwarded packet to be sent */
+static unsigned long forward_send_time(void)
+{
+	unsigned long send_time = jiffies; /* Starting now plus... */
+
+	if (atomic_read(&aggregation_enabled))
+		send_time += (((MAX_AGGREGATION_MS - (JITTER/2) +
+				(random32() % JITTER)) * HZ) / 1000);
+	else
+		send_time += (((random32() % (JITTER/2)) * HZ) / 1000);
+
+	return send_time;
+}
+
+/* sends a raw packet. */
+void send_raw_packet(unsigned char *pack_buff, int pack_buff_len,
+		     struct batman_if *batman_if, uint8_t *dst_addr)
+{
+	struct ethhdr *ethhdr;
+	struct sk_buff *skb;
+	int retval;
+	char *data;
+
+	if (batman_if->if_active != IF_ACTIVE)
+		return;
+
+	if (!(batman_if->net_dev->flags & IFF_UP)) {
+		debug_log(LOG_TYPE_WARN,
+		         "Interface %s is not up - can't send packet via that interface (IF_TO_BE_DEACTIVATED was here) !\n",
+		          batman_if->dev);
+		return;
+	}
+
+	skb = dev_alloc_skb(pack_buff_len + sizeof(struct ethhdr));
+	if (!skb)
+		return;
+	data = skb_put(skb, pack_buff_len + sizeof(struct ethhdr));
+
+	memcpy(data + sizeof(struct ethhdr), pack_buff, pack_buff_len);
+
+	ethhdr = (struct ethhdr *) data;
+	memcpy(ethhdr->h_source, batman_if->net_dev->dev_addr, ETH_ALEN);
+	memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN);
+	ethhdr->h_proto = __constant_htons(ETH_P_BATMAN);
+
+	skb_reset_mac_header(skb);
+	skb_set_network_header(skb, ETH_HLEN);
+	skb->priority = TC_PRIO_CONTROL;
+	skb->protocol = __constant_htons(ETH_P_BATMAN);
+	skb->dev = batman_if->net_dev;
+
+	/* dev_queue_xmit() returns a negative result on error.	 However on
+	 * congestion and traffic shaping, it drops and returns NET_XMIT_DROP
+	 * (which is > 0). This will not be treated as an error. */
+	retval = dev_queue_xmit(skb);
+	if (retval < 0)
+		debug_log(LOG_TYPE_CRIT,
+		          "Can't write to raw socket (IF_TO_BE_DEACTIVATED was here): %i\n",
+		          retval);
+}
+
+/* Send a packet to a given interface */
+static void send_packet_to_if(struct forw_packet *forw_packet,
+			      struct batman_if *batman_if)
+{
+	char *fwd_str;
+	uint8_t packet_num;
+	int16_t buff_pos;
+	struct batman_packet *batman_packet;
+	char orig_str[ETH_STR_LEN];
+
+	if (batman_if->if_active != IF_ACTIVE)
+		return;
+
+	packet_num = buff_pos = 0;
+	batman_packet = (struct batman_packet *)
+		(forw_packet->packet_buff);
+
+	/* adjust all flags and log packets */
+	while (aggregated_packet(buff_pos,
+				 forw_packet->packet_len,
+				 batman_packet->num_hna)) {
+
+		/* we might have aggregated direct link packets with an
+		 * ordinary base packet */
+		if ((forw_packet->direct_link_flags & (1 << packet_num)) &&
+		    (forw_packet->if_incoming == batman_if))
+			batman_packet->flags |= DIRECTLINK;
+		else
+			batman_packet->flags &= ~DIRECTLINK;
+
+		addr_to_string(orig_str, batman_packet->orig);
+		fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ?
+							    "Sending own" :
+							    "Forwarding"));
+		debug_log(LOG_TYPE_BATMAN,
+			  "%s %spacket (originator %s, seqno %d, TQ %d, TTL %d, IDF %s) on interface %s [%s]\n",
+			  fwd_str,
+			  (packet_num > 0 ? "aggregated " : ""),
+			  orig_str, ntohs(batman_packet->seqno),
+			  batman_packet->tq, batman_packet->ttl,
+			  (batman_packet->flags & DIRECTLINK ?
+			   "on" : "off"),
+			  batman_if->dev, batman_if->addr_str);
+
+		buff_pos += sizeof(struct batman_packet) +
+			(batman_packet->num_hna * ETH_ALEN);
+		packet_num++;
+		batman_packet = (struct batman_packet *)
+			(forw_packet->packet_buff + buff_pos);
+	}
+
+	send_raw_packet(forw_packet->packet_buff,
+			forw_packet->packet_len,
+			batman_if, broadcastAddr);
+}
+
+/* send a batman packet */
+static void send_packet(struct forw_packet *forw_packet)
+{
+	struct batman_if *batman_if;
+	struct batman_packet *batman_packet =
+		(struct batman_packet *)(forw_packet->packet_buff);
+	char orig_str[ETH_STR_LEN];
+	unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0);
+
+	if (!forw_packet->if_incoming) {
+		debug_log(LOG_TYPE_CRIT,
+			  "Error - can't forward packet: incoming iface not specified\n");
+		return;
+	}
+
+	if (forw_packet->if_incoming->if_active != IF_ACTIVE)
+		return;
+
+	addr_to_string(orig_str, batman_packet->orig);
+
+	/* multihomed peer assumed */
+	/* non-primary OGMs are only broadcasted on their interface */
+	if ((directlink && (batman_packet->ttl == 1)) ||
+	    (forw_packet->own && (forw_packet->if_incoming->if_num > 0))) {
+
+		/* FIXME: what about aggregated packets ? */
+		debug_log(LOG_TYPE_BATMAN,
+			  "%s packet (originator %s, seqno %d, TTL %d) on interface %s [%s]\n",
+			  (forw_packet->own ? "Sending own" : "Forwarding"),
+			  orig_str, ntohs(batman_packet->seqno),
+			  batman_packet->ttl, forw_packet->if_incoming->dev,
+			  forw_packet->if_incoming->addr_str);
+
+		send_raw_packet(forw_packet->packet_buff,
+				forw_packet->packet_len,
+				forw_packet->if_incoming,
+				broadcastAddr);
+		return;
+	}
+
+	/* broadcast on every interface */
+	rcu_read_lock();
+	list_for_each_entry_rcu(batman_if, &if_list, list)
+		send_packet_to_if(forw_packet, batman_if);
+	rcu_read_unlock();
+}
+
+static void rebuild_batman_packet(struct batman_if *batman_if)
+{
+	int new_len;
+	unsigned char *new_buff;
+	struct batman_packet *batman_packet;
+
+	new_len = sizeof(struct batman_packet) + (num_hna * ETH_ALEN);
+	new_buff = kmalloc(new_len, GFP_ATOMIC);
+
+	/* keep old buffer if kmalloc should fail */
+	if (new_buff) {
+		memcpy(new_buff, batman_if->packet_buff,
+		       sizeof(struct batman_packet));
+		batman_packet = (struct batman_packet *)new_buff;
+
+		batman_packet->num_hna = hna_local_fill_buffer(
+			new_buff + sizeof(struct batman_packet),
+			new_len - sizeof(struct batman_packet));
+
+		kfree(batman_if->packet_buff);
+		batman_if->packet_buff = new_buff;
+		batman_if->packet_len = new_len;
+	}
+}
+
+void schedule_own_packet(struct batman_if *batman_if)
+{
+	unsigned long send_time;
+	struct batman_packet *batman_packet;
+
+	/**
+	 * the interface gets activated here to avoid race conditions between
+	 * the moment of activating the interface in
+	 * hardif_activate_interface() where the originator mac is set and
+	 * outdated packets (especially uninitialized mac addresses) in the
+	 * packet queue
+	 */
+	if (batman_if->if_active == IF_TO_BE_ACTIVATED)
+		batman_if->if_active = IF_ACTIVE;
+
+	/* if local hna has changed and interface is a primary interface */
+	if ((atomic_read(&hna_local_changed)) && (batman_if->if_num == 0))
+		rebuild_batman_packet(batman_if);
+
+	/**
+	 * NOTE: packet_buff might just have been re-allocated in
+	 * rebuild_batman_packet()
+	 */
+	batman_packet = (struct batman_packet *)batman_if->packet_buff;
+
+	/* change sequence number to network order */
+	batman_packet->seqno = htons((uint16_t)atomic_read(&batman_if->seqno));
+
+	if (is_vis_server())
+		batman_packet->flags = VIS_SERVER;
+	else
+		batman_packet->flags = 0;
+
+	/* could be read by receive_bat_packet() */
+	atomic_inc(&batman_if->seqno);
+
+	slide_own_bcast_window(batman_if);
+	send_time = own_send_time();
+	add_bat_packet_to_list(batman_if->packet_buff,
+			       batman_if->packet_len, batman_if, 1, send_time);
+}
+
+void schedule_forward_packet(struct orig_node *orig_node,
+			     struct ethhdr *ethhdr,
+			     struct batman_packet *batman_packet,
+			     uint8_t directlink, int hna_buff_len,
+			     struct batman_if *if_incoming)
+{
+	unsigned char in_tq, in_ttl, tq_avg = 0;
+	unsigned long send_time;
+
+	if (batman_packet->ttl <= 1) {
+		debug_log(LOG_TYPE_BATMAN, "ttl exceeded \n");
+		return;
+	}
+
+	in_tq = batman_packet->tq;
+	in_ttl = batman_packet->ttl;
+
+	batman_packet->ttl--;
+	memcpy(batman_packet->prev_sender, ethhdr->h_source, ETH_ALEN);
+
+	/* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast
+	 * of our best tq value */
+	if ((orig_node->router) && (orig_node->router->tq_avg != 0)) {
+
+		/* rebroadcast ogm of best ranking neighbor as is */
+		if (!compare_orig(orig_node->router->addr, ethhdr->h_source)) {
+			batman_packet->tq = orig_node->router->tq_avg;
+
+			if (orig_node->router->last_ttl)
+				batman_packet->ttl = orig_node->router->last_ttl - 1;
+		}
+
+		tq_avg = orig_node->router->tq_avg;
+	}
+
+	/* apply hop penalty */
+	batman_packet->tq = hop_penalty(batman_packet->tq);
+
+	debug_log(LOG_TYPE_BATMAN, "Forwarding packet: tq_orig: %i, tq_avg: %i, tq_forw: %i, ttl_orig: %i, ttl_forw: %i \n",
+		  in_tq, tq_avg, batman_packet->tq, in_ttl - 1,
+		  batman_packet->ttl);
+
+	batman_packet->seqno = htons(batman_packet->seqno);
+
+	if (directlink)
+		batman_packet->flags |= DIRECTLINK;
+	else
+		batman_packet->flags &= ~DIRECTLINK;
+
+	send_time = forward_send_time();
+	add_bat_packet_to_list((unsigned char *)batman_packet,
+			       sizeof(struct batman_packet) + hna_buff_len,
+			       if_incoming, 0, send_time);
+}
+
+static void forw_packet_free(struct forw_packet *forw_packet)
+{
+	kfree(forw_packet->packet_buff);
+	kfree(forw_packet);
+}
+
+static void _add_bcast_packet_to_list(struct forw_packet *forw_packet,
+				      unsigned long send_time)
+{
+	INIT_HLIST_NODE(&forw_packet->list);
+
+	/* add new packet to packet list */
+	spin_lock(&forw_bcast_list_lock);
+	hlist_add_head(&forw_packet->list, &forw_bcast_list);
+	spin_unlock(&forw_bcast_list_lock);
+
+	/* start timer for this packet */
+	INIT_DELAYED_WORK(&forw_packet->delayed_work,
+			  send_outstanding_bcast_packet);
+	queue_delayed_work(bat_event_workqueue, &forw_packet->delayed_work,
+			   send_time);
+}
+
+void add_bcast_packet_to_list(unsigned char *packet_buff, int packet_len)
+{
+	struct forw_packet *forw_packet;
+
+	forw_packet = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
+	if (!forw_packet)
+		return;
+
+	forw_packet->packet_buff = kmalloc(packet_len, GFP_ATOMIC);
+	if (!forw_packet->packet_buff)
+		return;
+
+	forw_packet->packet_len = packet_len;
+	memcpy(forw_packet->packet_buff, packet_buff, forw_packet->packet_len);
+
+	/* how often did we send the bcast packet ? */
+	forw_packet->num_packets = 0;
+
+	_add_bcast_packet_to_list(forw_packet, 1);
+}
+
+void send_outstanding_bcast_packet(struct work_struct *work)
+{
+	struct batman_if *batman_if;
+	struct delayed_work *delayed_work =
+		container_of(work, struct delayed_work, work);
+	struct forw_packet *forw_packet =
+		container_of(delayed_work, struct forw_packet, delayed_work);
+
+	spin_lock(&forw_bcast_list_lock);
+	hlist_del(&forw_packet->list);
+	spin_unlock(&forw_bcast_list_lock);
+
+	/* rebroadcast packet */
+	rcu_read_lock();
+	list_for_each_entry_rcu(batman_if, &if_list, list) {
+		send_raw_packet(forw_packet->packet_buff,
+				forw_packet->packet_len,
+				batman_if, broadcastAddr);
+	}
+	rcu_read_unlock();
+
+	forw_packet->num_packets++;
+
+	/* if we still have some more bcasts to send and we are not shutting
+	 * down */
+	if ((forw_packet->num_packets < 3) &&
+	    (atomic_read(&module_state) != MODULE_DEACTIVATING))
+		_add_bcast_packet_to_list(forw_packet, ((5 * HZ) / 1000));
+	else
+		forw_packet_free(forw_packet);
+}
+
+void send_outstanding_bat_packet(struct work_struct *work)
+{
+	struct delayed_work *delayed_work =
+		container_of(work, struct delayed_work, work);
+	struct forw_packet *forw_packet =
+		container_of(delayed_work, struct forw_packet, delayed_work);
+
+	spin_lock(&forw_bat_list_lock);
+	hlist_del(&forw_packet->list);
+	spin_unlock(&forw_bat_list_lock);
+
+	send_packet(forw_packet);
+
+	/**
+	 * we have to have at least one packet in the queue
+	 * to determine the queues wake up time unless we are
+	 * shutting down
+	 */
+	if ((forw_packet->own) &&
+	    (atomic_read(&module_state) != MODULE_DEACTIVATING))
+		schedule_own_packet(forw_packet->if_incoming);
+
+	forw_packet_free(forw_packet);
+}
+
+void purge_outstanding_packets(void)
+{
+	struct forw_packet *forw_packet;
+	struct hlist_node *tmp_node, *safe_tmp_node;
+
+	debug_log(LOG_TYPE_BATMAN, "purge_outstanding_packets()\n");
+
+	/* free bcast list */
+	spin_lock(&forw_bcast_list_lock);
+	hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
+				  &forw_bcast_list, list) {
+
+		spin_unlock(&forw_bcast_list_lock);
+
+		/**
+		 * send_outstanding_bcast_packet() will lock the list to
+		 * delete the item from the list
+		 */
+		cancel_delayed_work_sync(&forw_packet->delayed_work);
+		spin_lock(&forw_bcast_list_lock);
+	}
+	spin_unlock(&forw_bcast_list_lock);
+
+	/* free batman packet list */
+	spin_lock(&forw_bat_list_lock);
+	hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
+				  &forw_bat_list, list) {
+
+		spin_unlock(&forw_bat_list_lock);
+
+		/**
+		 * send_outstanding_bat_packet() will lock the list to
+		 * delete the item from the list
+		 */
+		cancel_delayed_work_sync(&forw_packet->delayed_work);
+		spin_lock(&forw_bat_list_lock);
+	}
+	spin_unlock(&forw_bat_list_lock);
+}
diff --git a/drivers/staging/batman-adv/send.h b/drivers/staging/batman-adv/send.h
new file mode 100644
index 0000000..59d5009
--- /dev/null
+++ b/drivers/staging/batman-adv/send.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "types.h"
+
+void send_own_packet_work(struct work_struct *work);
+void send_raw_packet(unsigned char *pack_buff, int pack_buff_len,
+		     struct batman_if *batman_if, uint8_t *dst_addr);
+void schedule_own_packet(struct batman_if *batman_if);
+void schedule_forward_packet(struct orig_node *orig_node,
+			     struct ethhdr *ethhdr,
+			     struct batman_packet *batman_packet,
+			     uint8_t directlink, int hna_buff_len,
+			     struct batman_if *if_outgoing);
+void add_bcast_packet_to_list(unsigned char *packet_buff, int packet_len);
+void send_outstanding_bcast_packet(struct work_struct *work);
+void send_outstanding_bat_packet(struct work_struct *work);
+void purge_outstanding_packets(void);
diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c
new file mode 100644
index 0000000..d543f50
--- /dev/null
+++ b/drivers/staging/batman-adv/soft-interface.c
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "main.h"
+#include "soft-interface.h"
+#include "hard-interface.h"
+#include "send.h"
+#include "translation-table.h"
+#include "log.h"
+#include "types.h"
+#include "hash.h"
+#include <linux/ethtool.h>
+#include <linux/etherdevice.h>
+#include "compat.h"
+
+static uint16_t bcast_seqno = 1; /* give own bcast messages seq numbers to avoid
+				  * broadcast storms */
+static int32_t skb_packets;
+static int32_t skb_bad_packets;
+static int32_t lock_dropped;
+
+unsigned char mainIfAddr[ETH_ALEN];
+static unsigned char mainIfAddr_default[ETH_ALEN];
+static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd);
+static void bat_get_drvinfo(struct net_device *dev,
+			    struct ethtool_drvinfo *info);
+static u32 bat_get_msglevel(struct net_device *dev);
+static void bat_set_msglevel(struct net_device *dev, u32 value);
+static u32 bat_get_link(struct net_device *dev);
+static u32 bat_get_rx_csum(struct net_device *dev);
+static int bat_set_rx_csum(struct net_device *dev, u32 data);
+
+static const struct ethtool_ops bat_ethtool_ops = {
+	.get_settings = bat_get_settings,
+	.get_drvinfo = bat_get_drvinfo,
+	.get_msglevel = bat_get_msglevel,
+	.set_msglevel = bat_set_msglevel,
+	.get_link = bat_get_link,
+	.get_rx_csum = bat_get_rx_csum,
+	.set_rx_csum = bat_set_rx_csum
+};
+
+void set_main_if_addr(uint8_t *addr)
+{
+	memcpy(mainIfAddr, addr, ETH_ALEN);
+}
+
+int main_if_was_up(void)
+{
+	return (memcmp(mainIfAddr, mainIfAddr_default, ETH_ALEN) != 0 ? 1 : 0);
+}
+
+static int my_skb_push(struct sk_buff *skb, unsigned int len)
+{
+	int result = 0;
+
+	skb_packets++;
+	if (skb->data - len < skb->head) {
+		skb_bad_packets++;
+		result = pskb_expand_head(skb, len, 0, GFP_ATOMIC);
+
+		if (result < 0)
+			return result;
+	}
+
+	skb_push(skb, len);
+	return 0;
+}
+
+#ifdef HAVE_NET_DEVICE_OPS
+static const struct net_device_ops bat_netdev_ops = {
+	.ndo_open = interface_open,
+	.ndo_stop = interface_release,
+	.ndo_get_stats = interface_stats,
+	.ndo_set_mac_address = interface_set_mac_addr,
+	.ndo_change_mtu = interface_change_mtu,
+	.ndo_start_xmit = interface_tx,
+	.ndo_validate_addr = eth_validate_addr
+};
+#endif
+
+void interface_setup(struct net_device *dev)
+{
+	struct bat_priv *priv = netdev_priv(dev);
+	char dev_addr[ETH_ALEN];
+
+	ether_setup(dev);
+
+#ifdef HAVE_NET_DEVICE_OPS
+	dev->netdev_ops = &bat_netdev_ops;
+#else
+	dev->open = interface_open;
+	dev->stop = interface_release;
+	dev->get_stats = interface_stats;
+	dev->set_mac_address = interface_set_mac_addr;
+	dev->change_mtu = interface_change_mtu;
+	dev->hard_start_xmit = interface_tx;
+#endif
+	dev->destructor = free_netdev;
+
+	dev->mtu = hardif_min_mtu();
+	dev->hard_header_len = BAT_HEADER_LEN; /* reserve more space in the
+						* skbuff for our header */
+
+	/* generate random address */
+	random_ether_addr(dev_addr);
+	memcpy(dev->dev_addr, dev_addr, sizeof(dev->dev_addr));
+
+	SET_ETHTOOL_OPS(dev, &bat_ethtool_ops);
+
+	memset(priv, 0, sizeof(struct bat_priv));
+}
+
+int interface_open(struct net_device *dev)
+{
+	netif_start_queue(dev);
+	return 0;
+}
+
+int interface_release(struct net_device *dev)
+{
+	netif_stop_queue(dev);
+	return 0;
+}
+
+struct net_device_stats *interface_stats(struct net_device *dev)
+{
+	struct bat_priv *priv = netdev_priv(dev);
+	return &priv->stats;
+}
+
+int interface_set_mac_addr(struct net_device *dev, void *addr)
+{
+	return -EBUSY;
+}
+
+int interface_change_mtu(struct net_device *dev, int new_mtu)
+{
+	/* check ranges */
+	if ((new_mtu < 68) || (new_mtu > hardif_min_mtu()))
+		return -EINVAL;
+
+	dev->mtu = new_mtu;
+
+	return 0;
+}
+
+int interface_tx(struct sk_buff *skb, struct net_device *dev)
+{
+	struct unicast_packet *unicast_packet;
+	struct bcast_packet *bcast_packet;
+	struct orig_node *orig_node;
+	struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
+	struct bat_priv *priv = netdev_priv(dev);
+	int data_len = skb->len;
+
+	if (atomic_read(&module_state) != MODULE_ACTIVE)
+		goto dropped;
+
+	dev->trans_start = jiffies;
+	/* TODO: check this for locks */
+	hna_local_add(ethhdr->h_source);
+
+	/* ethernet packet should be broadcasted */
+	if (is_bcast(ethhdr->h_dest) || is_mcast(ethhdr->h_dest)) {
+
+		if (my_skb_push(skb, sizeof(struct bcast_packet)) < 0)
+			goto dropped;
+
+		bcast_packet = (struct bcast_packet *)skb->data;
+
+		bcast_packet->version = COMPAT_VERSION;
+
+		/* batman packet type: broadcast */
+		bcast_packet->packet_type = BAT_BCAST;
+
+		/* hw address of first interface is the orig mac because only
+		 * this mac is known throughout the mesh */
+		memcpy(bcast_packet->orig, mainIfAddr, ETH_ALEN);
+		/* set broadcast sequence number */
+		bcast_packet->seqno = htons(bcast_seqno);
+
+		bcast_seqno++;
+
+		/* broadcast packet */
+		add_bcast_packet_to_list(skb->data, skb->len);
+
+	/* unicast packet */
+	} else {
+
+		/* simply spin_lock()ing can deadlock when the lock is already
+		 * hold. */
+		/* TODO: defer the work in a working queue instead of
+		 * dropping */
+		if (!spin_trylock(&orig_hash_lock)) {
+			lock_dropped++;
+			debug_log(LOG_TYPE_NOTICE, "%d packets dropped because lock was hold\n", lock_dropped);
+			goto dropped;
+		}
+
+		/* get routing information */
+		orig_node = ((struct orig_node *)hash_find(orig_hash,
+							   ethhdr->h_dest));
+
+		/* check for hna host */
+		if (!orig_node)
+			orig_node = transtable_search(ethhdr->h_dest);
+
+		if ((orig_node) &&
+		    (orig_node->batman_if) &&
+		    (orig_node->router)) {
+			if (my_skb_push(skb, sizeof(struct unicast_packet)) < 0)
+				goto unlock;
+
+			unicast_packet = (struct unicast_packet *)skb->data;
+
+			unicast_packet->version = COMPAT_VERSION;
+			/* batman packet type: unicast */
+			unicast_packet->packet_type = BAT_UNICAST;
+			/* set unicast ttl */
+			unicast_packet->ttl = TTL;
+			/* copy the destination for faster routing */
+			memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
+
+			/* net_dev won't be available when not active */
+			if (orig_node->batman_if->if_active != IF_ACTIVE)
+				goto unlock;
+
+			send_raw_packet(skb->data, skb->len,
+					orig_node->batman_if,
+					orig_node->router->addr);
+		} else {
+			goto unlock;
+		}
+
+		spin_unlock(&orig_hash_lock);
+	}
+
+	priv->stats.tx_packets++;
+	priv->stats.tx_bytes += data_len;
+	goto end;
+
+unlock:
+	spin_unlock(&orig_hash_lock);
+dropped:
+	priv->stats.tx_dropped++;
+end:
+	kfree_skb(skb);
+	return 0;
+}
+
+void interface_rx(struct net_device *dev, void *packet, int packet_len)
+{
+	struct sk_buff *skb;
+	struct bat_priv *priv = netdev_priv(dev);
+
+	skb = dev_alloc_skb(packet_len);
+
+	if (!skb) {
+		priv->stats.rx_dropped++;
+		goto out;
+	}
+
+	memcpy(skb_put(skb, packet_len), packet, packet_len);
+
+	/* Write metadata, and then pass to the receive level */
+	skb->dev = dev;
+	skb->protocol = eth_type_trans(skb, dev);
+	skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+	priv->stats.rx_packets++;
+	priv->stats.rx_bytes += packet_len;
+
+	dev->last_rx = jiffies;
+
+	netif_rx(skb);
+
+out:
+	return;
+}
+
+/* ethtool */
+static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	cmd->supported = 0;
+	cmd->advertising = 0;
+	cmd->speed = SPEED_10;
+	cmd->duplex = DUPLEX_FULL;
+	cmd->port = PORT_TP;
+	cmd->phy_address = 0;
+	cmd->transceiver = XCVR_INTERNAL;
+	cmd->autoneg = AUTONEG_DISABLE;
+	cmd->maxtxpkt = 0;
+	cmd->maxrxpkt = 0;
+
+	return 0;
+}
+
+static void bat_get_drvinfo(struct net_device *dev,
+			    struct ethtool_drvinfo *info)
+{
+	strcpy(info->driver, "B.A.T.M.A.N. advanced");
+	strcpy(info->version, SOURCE_VERSION);
+	strcpy(info->fw_version, "N/A");
+	strcpy(info->bus_info, "batman");
+}
+
+static u32 bat_get_msglevel(struct net_device *dev)
+{
+	return -EOPNOTSUPP;
+}
+
+static void bat_set_msglevel(struct net_device *dev, u32 value)
+{
+	return;
+}
+
+static u32 bat_get_link(struct net_device *dev)
+{
+	return 1;
+}
+
+static u32 bat_get_rx_csum(struct net_device *dev)
+{
+	return 0;
+}
+
+static int bat_set_rx_csum(struct net_device *dev, u32 data)
+{
+	return -EOPNOTSUPP;
+}
diff --git a/drivers/staging/batman-adv/soft-interface.h b/drivers/staging/batman-adv/soft-interface.h
new file mode 100644
index 0000000..515e276
--- /dev/null
+++ b/drivers/staging/batman-adv/soft-interface.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+void set_main_if_addr(uint8_t *addr);
+int main_if_was_up(void);
+void interface_setup(struct net_device *dev);
+int interface_open(struct net_device *dev);
+int interface_release(struct net_device *dev);
+struct net_device_stats *interface_stats(struct net_device *dev);
+int interface_set_mac_addr(struct net_device *dev, void *addr);
+int interface_change_mtu(struct net_device *dev, int new_mtu);
+int interface_tx(struct sk_buff *skb, struct net_device *dev);
+void interface_rx(struct net_device *dev, void *packet, int packet_len);
+
+extern unsigned char mainIfAddr[];
diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c
new file mode 100644
index 0000000..c2190e1
--- /dev/null
+++ b/drivers/staging/batman-adv/translation-table.c
@@ -0,0 +1,454 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "main.h"
+#include "translation-table.h"
+#include "log.h"
+#include "soft-interface.h"
+#include "types.h"
+#include "hash.h"
+#include "compat.h"
+
+struct hashtable_t *hna_local_hash;
+static struct hashtable_t *hna_global_hash;
+atomic_t hna_local_changed;
+
+DEFINE_SPINLOCK(hna_local_hash_lock);
+static DEFINE_SPINLOCK(hna_global_hash_lock);
+
+static DECLARE_DELAYED_WORK(hna_local_purge_wq, hna_local_purge);
+
+static void hna_local_start_timer(void)
+{
+	queue_delayed_work(bat_event_workqueue, &hna_local_purge_wq, 10 * HZ);
+}
+
+int hna_local_init(void)
+{
+	if (hna_local_hash)
+		return 1;
+
+	hna_local_hash = hash_new(128, compare_orig, choose_orig);
+
+	if (!hna_local_hash)
+		return 0;
+
+	atomic_set(&hna_local_changed, 0);
+	hna_local_start_timer();
+
+	return 1;
+}
+
+void hna_local_add(uint8_t *addr)
+{
+	struct hna_local_entry *hna_local_entry;
+	struct hna_global_entry *hna_global_entry;
+	struct hashtable_t *swaphash;
+	char hna_str[ETH_STR_LEN];
+	unsigned long flags;
+
+	spin_lock_irqsave(&hna_local_hash_lock, flags);
+	hna_local_entry =
+		((struct hna_local_entry *)hash_find(hna_local_hash, addr));
+	spin_unlock_irqrestore(&hna_local_hash_lock, flags);
+
+	if (hna_local_entry != NULL) {
+		hna_local_entry->last_seen = jiffies;
+		return;
+	}
+
+	addr_to_string(hna_str, addr);
+
+	/* only announce as many hosts as possible in the batman-packet and
+	   space in batman_packet->num_hna That also should give a limit to
+	   MAC-flooding. */
+	if ((num_hna + 1 > (ETH_DATA_LEN - BAT_PACKET_LEN) / ETH_ALEN) ||
+	    (num_hna + 1 > 255)) {
+		debug_log(LOG_TYPE_ROUTES, "Can't add new local hna entry (%s): number of local hna entries exceeds packet size \n", hna_str);
+		return;
+	}
+
+	debug_log(LOG_TYPE_ROUTES, "Creating new local hna entry: %s \n",
+		  hna_str);
+
+	hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC);
+	if (!hna_local_entry)
+		return;
+
+	memcpy(hna_local_entry->addr, addr, ETH_ALEN);
+	hna_local_entry->last_seen = jiffies;
+
+	/* the batman interface mac address should never be purged */
+	if (compare_orig(addr, soft_device->dev_addr))
+		hna_local_entry->never_purge = 1;
+	else
+		hna_local_entry->never_purge = 0;
+
+	spin_lock_irqsave(&hna_local_hash_lock, flags);
+
+	hash_add(hna_local_hash, hna_local_entry);
+	num_hna++;
+	atomic_set(&hna_local_changed, 1);
+
+	if (hna_local_hash->elements * 4 > hna_local_hash->size) {
+		swaphash = hash_resize(hna_local_hash,
+				       hna_local_hash->size * 2);
+
+		if (swaphash == NULL)
+			debug_log(LOG_TYPE_CRIT, "Couldn't resize local hna hash table \n");
+		else
+			hna_local_hash = swaphash;
+	}
+
+	spin_unlock_irqrestore(&hna_local_hash_lock, flags);
+
+	/* remove address from global hash if present */
+	spin_lock_irqsave(&hna_global_hash_lock, flags);
+
+	hna_global_entry =
+		((struct hna_global_entry *)hash_find(hna_global_hash, addr));
+
+	if (hna_global_entry != NULL)
+		_hna_global_del_orig(hna_global_entry, "local hna received");
+
+	spin_unlock_irqrestore(&hna_global_hash_lock, flags);
+}
+
+int hna_local_fill_buffer(unsigned char *buff, int buff_len)
+{
+	struct hna_local_entry *hna_local_entry;
+	struct hash_it_t *hashit = NULL;
+	int i = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&hna_local_hash_lock, flags);
+
+	while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {
+
+		if (buff_len < (i + 1) * ETH_ALEN)
+			break;
+
+		hna_local_entry = hashit->bucket->data;
+		memcpy(buff + (i * ETH_ALEN), hna_local_entry->addr, ETH_ALEN);
+
+		i++;
+	}
+
+	/* if we did not get all new local hnas see you next time  ;-) */
+	if (i == num_hna)
+		atomic_set(&hna_local_changed, 0);
+
+	spin_unlock_irqrestore(&hna_local_hash_lock, flags);
+
+	return i;
+}
+
+int hna_local_fill_buffer_text(unsigned char *buff, int buff_len)
+{
+	struct hna_local_entry *hna_local_entry;
+	struct hash_it_t *hashit = NULL;
+	int bytes_written = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&hna_local_hash_lock, flags);
+
+	while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {
+
+		if (buff_len < bytes_written + ETH_STR_LEN + 4)
+			break;
+
+		hna_local_entry = hashit->bucket->data;
+
+		bytes_written += snprintf(buff + bytes_written, ETH_STR_LEN + 4,
+					  " * %02x:%02x:%02x:%02x:%02x:%02x\n",
+					  hna_local_entry->addr[0],
+					  hna_local_entry->addr[1],
+					  hna_local_entry->addr[2],
+					  hna_local_entry->addr[3],
+					  hna_local_entry->addr[4],
+					  hna_local_entry->addr[5]);
+	}
+
+	spin_unlock_irqrestore(&hna_local_hash_lock, flags);
+
+	return bytes_written;
+}
+
+static void _hna_local_del(void *data)
+{
+	kfree(data);
+	num_hna--;
+	atomic_set(&hna_local_changed, 1);
+}
+
+static void hna_local_del(struct hna_local_entry *hna_local_entry,
+			  char *message)
+{
+	char hna_str[ETH_STR_LEN];
+
+	addr_to_string(hna_str, hna_local_entry->addr);
+	debug_log(LOG_TYPE_ROUTES, "Deleting local hna entry (%s): %s \n",
+		  hna_str, message);
+
+	hash_remove(hna_local_hash, hna_local_entry->addr);
+	_hna_local_del(hna_local_entry);
+}
+
+void hna_local_purge(struct work_struct *work)
+{
+	struct hna_local_entry *hna_local_entry;
+	struct hash_it_t *hashit = NULL;
+	unsigned long flags;
+	unsigned long timeout;
+
+	spin_lock_irqsave(&hna_local_hash_lock, flags);
+
+	while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {
+		hna_local_entry = hashit->bucket->data;
+
+		timeout = hna_local_entry->last_seen +
+			((LOCAL_HNA_TIMEOUT / 1000) * HZ);
+		if ((!hna_local_entry->never_purge) &&
+		    time_after(jiffies, timeout))
+			hna_local_del(hna_local_entry, "address timed out");
+	}
+
+	spin_unlock_irqrestore(&hna_local_hash_lock, flags);
+	hna_local_start_timer();
+}
+
+void hna_local_free(void)
+{
+	if (!hna_local_hash)
+		return;
+
+	cancel_delayed_work_sync(&hna_local_purge_wq);
+	hash_delete(hna_local_hash, _hna_local_del);
+	hna_local_hash = NULL;
+}
+
+int hna_global_init(void)
+{
+	if (hna_global_hash)
+		return 1;
+
+	hna_global_hash = hash_new(128, compare_orig, choose_orig);
+
+	if (!hna_global_hash)
+		return 0;
+
+	return 1;
+}
+
+void hna_global_add_orig(struct orig_node *orig_node,
+			 unsigned char *hna_buff, int hna_buff_len)
+{
+	struct hna_global_entry *hna_global_entry;
+	struct hna_local_entry *hna_local_entry;
+	struct hashtable_t *swaphash;
+	char hna_str[ETH_STR_LEN], orig_str[ETH_STR_LEN];
+	int hna_buff_count = 0;
+	unsigned long flags;
+	unsigned char *hna_ptr;
+
+	addr_to_string(orig_str, orig_node->orig);
+
+	while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) {
+		spin_lock_irqsave(&hna_global_hash_lock, flags);
+
+		hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN);
+		hna_global_entry = (struct hna_global_entry *)
+			hash_find(hna_global_hash, hna_ptr);
+
+		if (hna_global_entry == NULL) {
+			spin_unlock_irqrestore(&hna_global_hash_lock, flags);
+
+			hna_global_entry =
+				kmalloc(sizeof(struct hna_global_entry),
+					GFP_ATOMIC);
+
+			if (!hna_global_entry)
+				break;
+
+			memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN);
+
+			addr_to_string(hna_str, hna_global_entry->addr);
+			debug_log(LOG_TYPE_ROUTES, "Creating new global hna entry: %s (via %s)\n", hna_str, orig_str);
+
+			spin_lock_irqsave(&hna_global_hash_lock, flags);
+			hash_add(hna_global_hash, hna_global_entry);
+
+		}
+
+		hna_global_entry->orig_node = orig_node;
+		spin_unlock_irqrestore(&hna_global_hash_lock, flags);
+
+		/* remove address from local hash if present */
+		spin_lock_irqsave(&hna_local_hash_lock, flags);
+
+		hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN);
+		hna_local_entry = (struct hna_local_entry *)
+			hash_find(hna_local_hash, hna_ptr);
+
+		if (hna_local_entry != NULL)
+			hna_local_del(hna_local_entry, "global hna received");
+
+		spin_unlock_irqrestore(&hna_local_hash_lock, flags);
+
+		hna_buff_count++;
+	}
+
+	orig_node->hna_buff_len = hna_buff_len;
+
+	if (orig_node->hna_buff_len > 0) {
+		orig_node->hna_buff = kmalloc(orig_node->hna_buff_len,
+					      GFP_ATOMIC);
+		memcpy(orig_node->hna_buff, hna_buff, orig_node->hna_buff_len);
+	} else {
+		orig_node->hna_buff = NULL;
+	}
+
+	spin_lock_irqsave(&hna_global_hash_lock, flags);
+
+	if (hna_global_hash->elements * 4 > hna_global_hash->size) {
+		swaphash = hash_resize(hna_global_hash,
+				       hna_global_hash->size * 2);
+
+		if (swaphash == NULL)
+			debug_log(LOG_TYPE_CRIT, "Couldn't resize global hna hash table \n");
+		else
+			hna_global_hash = swaphash;
+	}
+
+	spin_unlock_irqrestore(&hna_global_hash_lock, flags);
+}
+
+int hna_global_fill_buffer_text(unsigned char *buff, int buff_len)
+{
+	struct hna_global_entry *hna_global_entry;
+	struct hash_it_t *hashit = NULL;
+	int bytes_written = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&hna_global_hash_lock, flags);
+
+	while (NULL != (hashit = hash_iterate(hna_global_hash, hashit))) {
+		if (buff_len < bytes_written + (2 * ETH_STR_LEN) + 10)
+			break;
+
+		hna_global_entry = hashit->bucket->data;
+
+		bytes_written += snprintf(buff + bytes_written,
+					  (2 * ETH_STR_LEN) + 10,
+					  " * %02x:%02x:%02x:%02x:%02x:%02x via %02x:%02x:%02x:%02x:%02x:%02x \n",
+					  hna_global_entry->addr[0],
+					  hna_global_entry->addr[1],
+					  hna_global_entry->addr[2],
+					  hna_global_entry->addr[3],
+					  hna_global_entry->addr[4],
+					  hna_global_entry->addr[5],
+					  hna_global_entry->orig_node->orig[0],
+					  hna_global_entry->orig_node->orig[1],
+					  hna_global_entry->orig_node->orig[2],
+					  hna_global_entry->orig_node->orig[3],
+					  hna_global_entry->orig_node->orig[4],
+					  hna_global_entry->orig_node->orig[5]);
+	}
+
+	spin_unlock_irqrestore(&hna_global_hash_lock, flags);
+
+	return bytes_written;
+}
+
+void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
+			  char *message)
+{
+	char hna_str[ETH_STR_LEN], orig_str[ETH_STR_LEN];
+
+	addr_to_string(orig_str, hna_global_entry->orig_node->orig);
+	addr_to_string(hna_str, hna_global_entry->addr);
+
+	debug_log(LOG_TYPE_ROUTES, "Deleting global hna entry %s (via %s): %s \n", hna_str, orig_str, message);
+
+	hash_remove(hna_global_hash, hna_global_entry->addr);
+	kfree(hna_global_entry);
+}
+
+void hna_global_del_orig(struct orig_node *orig_node, char *message)
+{
+	struct hna_global_entry *hna_global_entry;
+	int hna_buff_count = 0;
+	unsigned long flags;
+	unsigned char *hna_ptr;
+
+	if (orig_node->hna_buff_len == 0)
+		return;
+
+	spin_lock_irqsave(&hna_global_hash_lock, flags);
+
+	while ((hna_buff_count + 1) * ETH_ALEN <= orig_node->hna_buff_len) {
+		hna_ptr = orig_node->hna_buff + (hna_buff_count * ETH_ALEN);
+		hna_global_entry = (struct hna_global_entry *)
+			hash_find(hna_global_hash, hna_ptr);
+
+		if ((hna_global_entry != NULL) &&
+		    (hna_global_entry->orig_node == orig_node))
+			_hna_global_del_orig(hna_global_entry, message);
+
+		hna_buff_count++;
+	}
+
+	spin_unlock_irqrestore(&hna_global_hash_lock, flags);
+
+	orig_node->hna_buff_len = 0;
+	kfree(orig_node->hna_buff);
+	orig_node->hna_buff = NULL;
+}
+
+static void hna_global_del(void *data)
+{
+	kfree(data);
+}
+
+void hna_global_free(void)
+{
+	if (!hna_global_hash)
+		return;
+
+	hash_delete(hna_global_hash, hna_global_del);
+	hna_global_hash = NULL;
+}
+
+struct orig_node *transtable_search(uint8_t *addr)
+{
+	struct hna_global_entry *hna_global_entry;
+	unsigned long flags;
+
+	spin_lock_irqsave(&hna_global_hash_lock, flags);
+	hna_global_entry = (struct hna_global_entry *)
+		hash_find(hna_global_hash, addr);
+	spin_unlock_irqrestore(&hna_global_hash_lock, flags);
+
+	if (hna_global_entry == NULL)
+		return NULL;
+
+	return hna_global_entry->orig_node;
+}
diff --git a/drivers/staging/batman-adv/translation-table.h b/drivers/staging/batman-adv/translation-table.h
new file mode 100644
index 0000000..f7da811
--- /dev/null
+++ b/drivers/staging/batman-adv/translation-table.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "types.h"
+
+int hna_local_init(void);
+void hna_local_add(uint8_t *addr);
+int hna_local_fill_buffer(unsigned char *buff, int buff_len);
+int hna_local_fill_buffer_text(unsigned char *buff, int buff_len);
+void hna_local_purge(struct work_struct *work);
+void hna_local_free(void);
+int hna_global_init(void);
+void hna_global_add_orig(struct orig_node *orig_node, unsigned char *hna_buff,
+			 int hna_buff_len);
+int hna_global_fill_buffer_text(unsigned char *buff, int buff_len);
+void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
+			  char *orig_str);
+void hna_global_del_orig(struct orig_node *orig_node, char *message);
+void hna_global_free(void);
+struct orig_node *transtable_search(uint8_t *addr);
+
+extern spinlock_t hna_local_hash_lock;
+extern struct hashtable_t *hna_local_hash;
+extern atomic_t hna_local_changed;
diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h
new file mode 100644
index 0000000..3a0ef0c
--- /dev/null
+++ b/drivers/staging/batman-adv/types.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+
+
+
+
+#ifndef TYPES_H
+#define TYPES_H
+
+#include "packet.h"
+#include "bitarray.h"
+
+#define BAT_HEADER_LEN (sizeof(struct ethhdr) + ((sizeof(struct unicast_packet) > sizeof(struct bcast_packet) ? sizeof(struct unicast_packet) : sizeof(struct bcast_packet))))
+
+
+struct batman_if {
+	struct list_head list;
+	int16_t if_num;
+	char *dev;
+	char if_active;
+	char addr_str[ETH_STR_LEN];
+	struct net_device *net_dev;
+	struct socket *raw_sock;
+	atomic_t seqno;
+	unsigned char *packet_buff;
+	int packet_len;
+	struct rcu_head rcu;
+
+};
+
+struct orig_node {               /* structure for orig_list maintaining nodes of mesh */
+	uint8_t orig[ETH_ALEN];
+	struct neigh_node *router;
+	struct batman_if *batman_if;
+	TYPE_OF_WORD *bcast_own;
+	uint8_t *bcast_own_sum;
+	uint8_t tq_own;
+	int tq_asym_penalty;
+	unsigned long last_valid;        /* when last packet from this node was received */
+/*	uint8_t  gwflags;      * flags related to gateway functions: gateway class */
+	uint8_t  flags;    		/* for now only VIS_SERVER flag. */
+	unsigned char *hna_buff;
+	int16_t  hna_buff_len;
+	uint16_t last_real_seqno;   /* last and best known squence number */
+	uint8_t last_ttl;         /* ttl of last received packet */
+	TYPE_OF_WORD bcast_bits[NUM_WORDS];
+	uint16_t last_bcast_seqno;  /* last broadcast sequence number received by this host */
+	struct list_head neigh_list;
+};
+
+struct neigh_node {
+	struct list_head list;
+	uint8_t addr[ETH_ALEN];
+	uint8_t real_packet_count;
+	uint8_t tq_recv[TQ_GLOBAL_WINDOW_SIZE];
+	uint8_t tq_index;
+	uint8_t tq_avg;
+	uint8_t last_ttl;
+	unsigned long last_valid;            /* when last packet via this neighbour was received */
+	TYPE_OF_WORD real_bits[NUM_WORDS];
+	struct orig_node *orig_node;
+	struct batman_if *if_incoming;
+};
+
+struct bat_priv {
+	struct net_device_stats stats;
+};
+
+struct device_client {
+	struct list_head queue_list;
+	unsigned int queue_len;
+	unsigned char index;
+	spinlock_t lock;
+	wait_queue_head_t queue_wait;
+};
+
+struct device_packet {
+	struct list_head list;
+	struct icmp_packet icmp_packet;
+};
+
+struct hna_local_entry {
+	uint8_t addr[ETH_ALEN];
+	unsigned long last_seen;
+	char never_purge;
+};
+
+struct hna_global_entry {
+	uint8_t addr[ETH_ALEN];
+	struct orig_node *orig_node;
+};
+
+struct forw_packet {               /* structure for forw_list maintaining packets to be send/forwarded */
+	struct hlist_node list;
+	unsigned long send_time;
+	uint8_t own;
+	unsigned char *packet_buff;
+	uint16_t packet_len;
+	uint32_t direct_link_flags;
+	uint8_t num_packets;
+	struct delayed_work delayed_work;
+	struct batman_if *if_incoming;
+};
+
+#endif
diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c
new file mode 100644
index 0000000..f6c9acb
--- /dev/null
+++ b/drivers/staging/batman-adv/vis.c
@@ -0,0 +1,564 @@
+/*
+ * Copyright (C) 2008-2009 B.A.T.M.A.N. contributors:
+ *
+ * Simon Wunderlich
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "main.h"
+#include "send.h"
+#include "translation-table.h"
+#include "vis.h"
+#include "log.h"
+#include "soft-interface.h"
+#include "hard-interface.h"
+#include "hash.h"
+#include "compat.h"
+
+struct hashtable_t *vis_hash;
+DEFINE_SPINLOCK(vis_hash_lock);
+static struct vis_info *my_vis_info;
+static struct list_head send_list;	/* always locked with vis_hash_lock */
+
+static void start_vis_timer(void);
+
+/* free the info */
+static void free_info(void *data)
+{
+	struct vis_info *info = data;
+	struct recvlist_node *entry, *tmp;
+
+	list_del_init(&info->send_list);
+	list_for_each_entry_safe(entry, tmp, &info->recv_list, list) {
+		list_del(&entry->list);
+		kfree(entry);
+	}
+	kfree(info);
+}
+
+/* set the mode of the visualization to client or server */
+void vis_set_mode(int mode)
+{
+	spin_lock(&vis_hash_lock);
+
+	if (my_vis_info != NULL)
+		my_vis_info->packet.vis_type = mode;
+
+	spin_unlock(&vis_hash_lock);
+}
+
+/* is_vis_server(), locked outside */
+static int is_vis_server_locked(void)
+{
+	if (my_vis_info != NULL)
+		if (my_vis_info->packet.vis_type == VIS_TYPE_SERVER_SYNC)
+			return 1;
+
+	return 0;
+}
+
+/* get the current set mode */
+int is_vis_server(void)
+{
+	int ret = 0;
+
+	spin_lock(&vis_hash_lock);
+	ret = is_vis_server_locked();
+	spin_unlock(&vis_hash_lock);
+
+	return ret;
+}
+
+/* Compare two vis packets, used by the hashing algorithm */
+static int vis_info_cmp(void *data1, void *data2)
+{
+	struct vis_info *d1, *d2;
+	d1 = data1;
+	d2 = data2;
+	return compare_orig(d1->packet.vis_orig, d2->packet.vis_orig);
+}
+
+/* hash function to choose an entry in a hash table of given size */
+/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */
+static int vis_info_choose(void *data, int size)
+{
+	struct vis_info *vis_info = data;
+	unsigned char *key;
+	uint32_t hash = 0;
+	size_t i;
+
+	key = vis_info->packet.vis_orig;
+	for (i = 0; i < ETH_ALEN; i++) {
+		hash += key[i];
+		hash += (hash << 10);
+		hash ^= (hash >> 6);
+	}
+
+	hash += (hash << 3);
+	hash ^= (hash >> 11);
+	hash += (hash << 15);
+
+	return hash % size;
+}
+
+/* tries to add one entry to the receive list. */
+static void recv_list_add(struct list_head *recv_list, char *mac)
+{
+	struct recvlist_node *entry;
+	entry = kmalloc(sizeof(struct recvlist_node), GFP_ATOMIC);
+	if (!entry)
+		return;
+
+	memcpy(entry->mac, mac, ETH_ALEN);
+	list_add_tail(&entry->list, recv_list);
+}
+
+/* returns 1 if this mac is in the recv_list */
+static int recv_list_is_in(struct list_head *recv_list, char *mac)
+{
+	struct recvlist_node *entry;
+
+	list_for_each_entry(entry, recv_list, list) {
+		if (memcmp(entry->mac, mac, ETH_ALEN) == 0)
+			return 1;
+	}
+
+	return 0;
+}
+
+/* try to add the packet to the vis_hash. return NULL if invalid (e.g. too old,
+ * broken.. ).  vis hash must be locked outside.  is_new is set when the packet
+ * is newer than old entries in the hash. */
+static struct vis_info *add_packet(struct vis_packet *vis_packet,
+				   int vis_info_len, int *is_new)
+{
+	struct vis_info *info, *old_info;
+	struct vis_info search_elem;
+
+	*is_new = 0;
+	/* sanity check */
+	if (vis_hash == NULL)
+		return NULL;
+
+	/* see if the packet is already in vis_hash */
+	memcpy(search_elem.packet.vis_orig, vis_packet->vis_orig, ETH_ALEN);
+	old_info = hash_find(vis_hash, &search_elem);
+
+	if (old_info != NULL) {
+		if (vis_packet->seqno - old_info->packet.seqno <= 0) {
+			if (old_info->packet.seqno == vis_packet->seqno) {
+				recv_list_add(&old_info->recv_list,
+					      vis_packet->sender_orig);
+				return old_info;
+			} else {
+				/* newer packet is already in hash. */
+				return NULL;
+			}
+		}
+		/* remove old entry */
+		hash_remove(vis_hash, old_info);
+		free_info(old_info);
+	}
+
+	info = kmalloc(sizeof(struct vis_info) + vis_info_len, GFP_ATOMIC);
+	if (info == NULL)
+		return NULL;
+
+	INIT_LIST_HEAD(&info->send_list);
+	INIT_LIST_HEAD(&info->recv_list);
+	info->first_seen = jiffies;
+	memcpy(&info->packet, vis_packet,
+	       sizeof(struct vis_packet) + vis_info_len);
+
+	/* initialize and add new packet. */
+	*is_new = 1;
+
+	/* repair if entries is longer than packet. */
+	if (info->packet.entries * sizeof(struct vis_info_entry) > vis_info_len)
+		info->packet.entries = vis_info_len / sizeof(struct vis_info_entry);
+
+	recv_list_add(&info->recv_list, info->packet.sender_orig);
+
+	/* try to add it */
+	if (hash_add(vis_hash, info) < 0) {
+		/* did not work (for some reason) */
+		free_info(info);
+		info = NULL;
+	}
+
+	return info;
+}
+
+/* handle the server sync packet, forward if needed. */
+void receive_server_sync_packet(struct vis_packet *vis_packet, int vis_info_len)
+{
+	struct vis_info *info;
+	int is_new;
+
+	spin_lock(&vis_hash_lock);
+	info = add_packet(vis_packet, vis_info_len, &is_new);
+	if (info == NULL)
+		goto end;
+
+	/* only if we are server ourselves and packet is newer than the one in
+	 * hash.*/
+	if (is_vis_server_locked() && is_new) {
+		memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
+		if (list_empty(&info->send_list))
+			list_add_tail(&info->send_list, &send_list);
+	}
+end:
+	spin_unlock(&vis_hash_lock);
+}
+
+/* handle an incoming client update packet and schedule forward if needed. */
+void receive_client_update_packet(struct vis_packet *vis_packet,
+				  int vis_info_len)
+{
+	struct vis_info *info;
+	int is_new;
+
+	/* clients shall not broadcast. */
+	if (is_bcast(vis_packet->target_orig))
+		return;
+
+	spin_lock(&vis_hash_lock);
+	info = add_packet(vis_packet, vis_info_len, &is_new);
+	if (info == NULL)
+		goto end;
+	/* note that outdated packets will be dropped at this point. */
+
+
+	/* send only if we're the target server or ... */
+	if (is_vis_server_locked() &&
+	    is_my_mac(info->packet.target_orig) &&
+	    is_new) {
+		info->packet.vis_type = VIS_TYPE_SERVER_SYNC;	/* upgrade! */
+		memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
+		if (list_empty(&info->send_list))
+			list_add_tail(&info->send_list, &send_list);
+
+		/* ... we're not the recipient (and thus need to forward). */
+	} else if (!is_my_mac(info->packet.target_orig)) {
+		if (list_empty(&info->send_list))
+			list_add_tail(&info->send_list, &send_list);
+	}
+end:
+	spin_unlock(&vis_hash_lock);
+}
+
+/* Walk the originators and find the VIS server with the best tq. Set the packet
+ * address to its address and return the best_tq.
+ *
+ * Must be called with the originator hash locked */
+static int find_best_vis_server(struct vis_info *info)
+{
+	struct hash_it_t *hashit = NULL;
+	struct orig_node *orig_node;
+	int best_tq = -1;
+
+	while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
+		orig_node = hashit->bucket->data;
+		if ((orig_node != NULL) &&
+		    (orig_node->router != NULL) &&
+		    (orig_node->flags & VIS_SERVER) &&
+		    (orig_node->router->tq_avg > best_tq)) {
+			best_tq = orig_node->router->tq_avg;
+			memcpy(info->packet.target_orig, orig_node->orig,
+			       ETH_ALEN);
+		}
+	}
+	return best_tq;
+}
+
+/* Return true if the vis packet is full. */
+static bool vis_packet_full(struct vis_info *info)
+{
+	if (info->packet.entries + 1 >
+	    (1000 - sizeof(struct vis_info)) / sizeof(struct vis_info_entry))
+		return true;
+	return false;
+}
+
+/* generates a packet of own vis data,
+ * returns 0 on success, -1 if no packet could be generated */
+static int generate_vis_packet(void)
+{
+	struct hash_it_t *hashit = NULL;
+	struct orig_node *orig_node;
+	struct vis_info *info = (struct vis_info *)my_vis_info;
+	struct vis_info_entry *entry, *entry_array;
+	struct hna_local_entry *hna_local_entry;
+	int best_tq = -1;
+	unsigned long flags;
+
+	info->first_seen = jiffies;
+
+	spin_lock(&orig_hash_lock);
+	memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
+	info->packet.ttl = TTL;
+	info->packet.seqno++;
+	info->packet.entries = 0;
+
+	if (!is_vis_server_locked()) {
+		best_tq = find_best_vis_server(info);
+		if (best_tq < 0) {
+			spin_unlock(&orig_hash_lock);
+			return -1;
+		}
+	}
+	hashit = NULL;
+
+	entry_array = (struct vis_info_entry *)
+		((char *)info + sizeof(struct vis_info));
+
+	while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
+		orig_node = hashit->bucket->data;
+		if (orig_node->router != NULL
+			&& compare_orig(orig_node->router->addr, orig_node->orig)
+			&& orig_node->batman_if
+			&& (orig_node->batman_if->if_active == IF_ACTIVE)
+		    && orig_node->router->tq_avg > 0) {
+
+			/* fill one entry into buffer. */
+			entry = &entry_array[info->packet.entries];
+			memcpy(entry->src, orig_node->batman_if->net_dev->dev_addr, ETH_ALEN);
+			memcpy(entry->dest, orig_node->orig, ETH_ALEN);
+			entry->quality = orig_node->router->tq_avg;
+			info->packet.entries++;
+
+			if (vis_packet_full(info)) {
+				spin_unlock(&orig_hash_lock);
+				return 0;
+			}
+		}
+	}
+
+	spin_unlock(&orig_hash_lock);
+
+	hashit = NULL;
+	spin_lock_irqsave(&hna_local_hash_lock, flags);
+	while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {
+		hna_local_entry = hashit->bucket->data;
+		entry = &entry_array[info->packet.entries];
+		memset(entry->src, 0, ETH_ALEN);
+		memcpy(entry->dest, hna_local_entry->addr, ETH_ALEN);
+		entry->quality = 0; /* 0 means HNA */
+		info->packet.entries++;
+
+		if (vis_packet_full(info)) {
+			spin_unlock_irqrestore(&hna_local_hash_lock, flags);
+			return 0;
+		}
+	}
+	spin_unlock_irqrestore(&hna_local_hash_lock, flags);
+	return 0;
+}
+
+static void purge_vis_packets(void)
+{
+	struct hash_it_t *hashit = NULL;
+	struct vis_info *info;
+
+	while (NULL != (hashit = hash_iterate(vis_hash, hashit))) {
+		info = hashit->bucket->data;
+		if (info == my_vis_info)	/* never purge own data. */
+			continue;
+		if (time_after(jiffies,
+			       info->first_seen + (VIS_TIMEOUT/1000)*HZ)) {
+			hash_remove_bucket(vis_hash, hashit);
+			free_info(info);
+		}
+	}
+}
+
+static void broadcast_vis_packet(struct vis_info *info, int packet_length)
+{
+	struct hash_it_t *hashit = NULL;
+	struct orig_node *orig_node;
+
+	spin_lock(&orig_hash_lock);
+
+	/* send to all routers in range. */
+	while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
+		orig_node = hashit->bucket->data;
+
+		/* if it's a vis server and reachable, send it. */
+		if (orig_node &&
+		    (orig_node->flags & VIS_SERVER) &&
+		    orig_node->batman_if &&
+		    orig_node->router) {
+
+			/* don't send it if we already received the packet from
+			 * this node. */
+			if (recv_list_is_in(&info->recv_list, orig_node->orig))
+				continue;
+
+			memcpy(info->packet.target_orig,
+			       orig_node->orig, ETH_ALEN);
+
+			send_raw_packet((unsigned char *) &info->packet,
+					packet_length,
+					orig_node->batman_if,
+					orig_node->router->addr);
+		}
+	}
+	memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
+	spin_unlock(&orig_hash_lock);
+}
+
+static void unicast_vis_packet(struct vis_info *info, int packet_length)
+{
+	struct orig_node *orig_node;
+
+	spin_lock(&orig_hash_lock);
+	orig_node = ((struct orig_node *)
+		     hash_find(orig_hash, info->packet.target_orig));
+
+	if ((orig_node != NULL) &&
+	    (orig_node->batman_if != NULL) &&
+	    (orig_node->router != NULL)) {
+		send_raw_packet((unsigned char *) &info->packet, packet_length,
+				orig_node->batman_if,
+				orig_node->router->addr);
+	}
+	spin_unlock(&orig_hash_lock);
+}
+
+/* only send one vis packet. called from send_vis_packets() */
+static void send_vis_packet(struct vis_info *info)
+{
+	int packet_length;
+
+	if (info->packet.ttl < 2) {
+		debug_log(LOG_TYPE_NOTICE,
+			  "Error - can't send vis packet: ttl exceeded\n");
+		return;
+	}
+
+	memcpy(info->packet.sender_orig, mainIfAddr, ETH_ALEN);
+	info->packet.ttl--;
+
+	packet_length = sizeof(struct vis_packet) +
+		info->packet.entries * sizeof(struct vis_info_entry);
+
+	if (is_bcast(info->packet.target_orig))
+		broadcast_vis_packet(info, packet_length);
+	else
+		unicast_vis_packet(info, packet_length);
+	info->packet.ttl++; /* restore TTL */
+}
+
+/* called from timer; send (and maybe generate) vis packet. */
+static void send_vis_packets(struct work_struct *work)
+{
+	struct vis_info *info, *temp;
+
+	spin_lock(&vis_hash_lock);
+	purge_vis_packets();
+
+	if (generate_vis_packet() == 0)
+		/* schedule if generation was successful */
+		list_add_tail(&my_vis_info->send_list, &send_list);
+
+	list_for_each_entry_safe(info, temp, &send_list, send_list) {
+		list_del_init(&info->send_list);
+		send_vis_packet(info);
+	}
+	spin_unlock(&vis_hash_lock);
+	start_vis_timer();
+}
+static DECLARE_DELAYED_WORK(vis_timer_wq, send_vis_packets);
+
+/* init the vis server. this may only be called when if_list is already
+ * initialized (e.g. bat0 is initialized, interfaces have been added) */
+int vis_init(void)
+{
+	if (vis_hash)
+		return 1;
+
+	spin_lock(&vis_hash_lock);
+
+	vis_hash = hash_new(256, vis_info_cmp, vis_info_choose);
+	if (!vis_hash) {
+		debug_log(LOG_TYPE_CRIT, "Can't initialize vis_hash\n");
+		goto err;
+	}
+
+	my_vis_info = kmalloc(1000, GFP_ATOMIC);
+	if (!my_vis_info) {
+		debug_log(LOG_TYPE_CRIT, "Can't initialize vis packet\n");
+		goto err;
+	}
+
+	/* prefill the vis info */
+	my_vis_info->first_seen = jiffies - atomic_read(&vis_interval);
+	INIT_LIST_HEAD(&my_vis_info->recv_list);
+	INIT_LIST_HEAD(&my_vis_info->send_list);
+	my_vis_info->packet.version = COMPAT_VERSION;
+	my_vis_info->packet.packet_type = BAT_VIS;
+	my_vis_info->packet.vis_type = VIS_TYPE_CLIENT_UPDATE;
+	my_vis_info->packet.ttl = TTL;
+	my_vis_info->packet.seqno = 0;
+	my_vis_info->packet.entries = 0;
+
+	INIT_LIST_HEAD(&send_list);
+
+	memcpy(my_vis_info->packet.vis_orig, mainIfAddr, ETH_ALEN);
+	memcpy(my_vis_info->packet.sender_orig, mainIfAddr, ETH_ALEN);
+
+	if (hash_add(vis_hash, my_vis_info) < 0) {
+		debug_log(LOG_TYPE_CRIT,
+			  "Can't add own vis packet into hash\n");
+		free_info(my_vis_info);	/* not in hash, need to remove it
+					 * manually. */
+		goto err;
+	}
+
+	spin_unlock(&vis_hash_lock);
+	start_vis_timer();
+	return 1;
+
+err:
+	spin_unlock(&vis_hash_lock);
+	vis_quit();
+	return 0;
+}
+
+/* shutdown vis-server */
+void vis_quit(void)
+{
+	if (!vis_hash)
+		return;
+
+	cancel_delayed_work_sync(&vis_timer_wq);
+
+	spin_lock(&vis_hash_lock);
+	/* properly remove, kill timers ... */
+	hash_delete(vis_hash, free_info);
+	vis_hash = NULL;
+	my_vis_info = NULL;
+	spin_unlock(&vis_hash_lock);
+}
+
+/* schedule packets for (re)transmission */
+static void start_vis_timer(void)
+{
+	queue_delayed_work(bat_event_workqueue, &vis_timer_wq,
+			   (atomic_read(&vis_interval)/1000) * HZ);
+}
+
diff --git a/drivers/staging/batman-adv/vis.h b/drivers/staging/batman-adv/vis.h
new file mode 100644
index 0000000..276faba
--- /dev/null
+++ b/drivers/staging/batman-adv/vis.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008-2009 B.A.T.M.A.N. contributors:
+ *
+ * Simon Wunderlich, Marek Lindner
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#define VIS_TIMEOUT		200000
+#define VIS_FORMAT_DD_NAME	"dot_draw"
+#define VIS_FORMAT_JSON_NAME	"json"
+
+struct vis_info {
+	unsigned long       first_seen;
+	struct list_head    recv_list;
+			    /* list of server-neighbors we received a vis-packet
+			     * from.  we should not reply to them. */
+	struct list_head send_list;
+	/* this packet might be part of the vis send queue. */
+	struct vis_packet packet;
+	/* vis_info may follow here*/
+} __attribute__((packed));
+
+struct vis_info_entry {
+	uint8_t  src[ETH_ALEN];
+	uint8_t  dest[ETH_ALEN];
+	uint8_t  quality;	/* quality = 0 means HNA */
+} __attribute__((packed));
+
+struct recvlist_node {
+	struct list_head list;
+	uint8_t mac[ETH_ALEN];
+};
+
+enum vis_formats {
+	DOT_DRAW,
+	JSON,
+};
+
+extern struct hashtable_t *vis_hash;
+extern spinlock_t vis_hash_lock;
+
+void vis_set_mode(int mode);
+int is_vis_server(void);
+void receive_server_sync_packet(struct vis_packet *vis_packet,
+				int vis_info_len);
+void receive_client_update_packet(struct vis_packet *vis_packet,
+				  int vis_info_len);
+int vis_init(void);
+void vis_quit(void);
diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h
index 957b640..ccc5cdc 100644
--- a/drivers/staging/comedi/comedi.h
+++ b/drivers/staging/comedi/comedi.h
@@ -24,10 +24,6 @@
 #ifndef _COMEDI_H
 #define _COMEDI_H
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #define COMEDI_MAJORVERSION	0
 #define COMEDI_MINORVERSION	7
 #define COMEDI_MICROVERSION	76
@@ -871,8 +867,4 @@
 		AMPLC_DIO_GAT_RESERVED7
 	};
 
-#ifdef __cplusplus
-}
-#endif
-
 #endif /* _COMEDI_H */
diff --git a/drivers/staging/comedi/comedi_compat32.c b/drivers/staging/comedi/comedi_compat32.c
index 9810e37..a9fdcda 100644
--- a/drivers/staging/comedi/comedi_compat32.c
+++ b/drivers/staging/comedi/comedi_compat32.c
@@ -27,16 +27,12 @@
 #define __NO_VERSION__
 #include "comedi.h"
 #include <linux/smp_lock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 #include "comedi_compat32.h"
 
 #ifdef CONFIG_COMPAT
 
-#ifndef HAVE_COMPAT_IOCTL
-#include <linux/ioctl32.h>	/* for (un)register_ioctl32_conversion */
-#endif
-
 #define COMEDI32_CHANINFO _IOR(CIO, 3, struct comedi32_chaninfo_struct)
 #define COMEDI32_RANGEINFO _IOR(CIO, 8, struct comedi32_rangeinfo_struct)
 /* N.B. COMEDI32_CMD and COMEDI_CMD ought to use _IOWR, not _IOR.
@@ -101,22 +97,9 @@
 	if (!file->f_op)
 		return -ENOTTY;
 
-#ifdef HAVE_UNLOCKED_IOCTL
-	if (file->f_op->unlocked_ioctl) {
-		int rc = (int)(*file->f_op->unlocked_ioctl) (file, cmd, arg);
-		if (rc == -ENOIOCTLCMD)
-			rc = -ENOTTY;
-		return rc;
-	}
-#endif
-	if (file->f_op->ioctl) {
-		int rc;
-		lock_kernel();
-		rc = (*file->f_op->ioctl) (file->f_dentry->d_inode,
-					   file, cmd, arg);
-		unlock_kernel();
-		return rc;
-	}
+	if (file->f_op->unlocked_ioctl)
+		return file->f_op->unlocked_ioctl(file, cmd, arg);
+
 	return -ENOTTY;
 }
 
@@ -186,8 +169,8 @@
 }
 
 /* Copy 32-bit cmd structure to native cmd structure. */
-static int get_compat_cmd(struct comedi_cmd __user * cmd,
-			  struct comedi32_cmd_struct __user * cmd32)
+static int get_compat_cmd(struct comedi_cmd __user *cmd,
+			  struct comedi32_cmd_struct __user *cmd32)
 {
 	int err;
 	union {
@@ -237,8 +220,8 @@
 }
 
 /* Copy native cmd structure to 32-bit cmd structure. */
-static int put_compat_cmd(struct comedi32_cmd_struct __user * cmd32,
-			  struct comedi_cmd __user * cmd)
+static int put_compat_cmd(struct comedi32_cmd_struct __user *cmd32,
+			  struct comedi_cmd __user *cmd)
 {
 	int err;
 	unsigned int temp;
@@ -328,8 +311,8 @@
 }
 
 /* Copy 32-bit insn structure to native insn structure. */
-static int get_compat_insn(struct comedi_insn __user * insn,
-			   struct comedi32_insn_struct __user * insn32)
+static int get_compat_insn(struct comedi_insn __user *insn,
+			   struct comedi32_insn_struct __user *insn32)
 {
 	int err;
 	union {
@@ -372,9 +355,9 @@
 	insnlist32 = compat_ptr(arg);
 
 	/* Get 32-bit insnlist structure.  */
-	if (!access_ok(VERIFY_READ, insnlist32, sizeof(*insnlist32))) {
+	if (!access_ok(VERIFY_READ, insnlist32, sizeof(*insnlist32)))
 		return -EFAULT;
-	}
+
 	err = 0;
 	err |= __get_user(n_insns, &insnlist32->n_insns);
 	err |= __get_user(uptr, &insnlist32->insns);
@@ -387,9 +370,9 @@
 					     insn[n_insns]));
 
 	/* Set native insnlist structure. */
-	if (!access_ok(VERIFY_WRITE, &s->insnlist, sizeof(s->insnlist))) {
+	if (!access_ok(VERIFY_WRITE, &s->insnlist, sizeof(s->insnlist)))
 		return -EFAULT;
-	}
+
 	err |= __put_user(n_insns, &s->insnlist.n_insns);
 	err |= __put_user(&s->insn[0], &s->insnlist.insns);
 	if (err)
@@ -472,8 +455,6 @@
 	return rc;
 }
 
-#ifdef HAVE_COMPAT_IOCTL	/* defined in <linux/fs.h> 2.6.11 onwards */
-
 /* compat_ioctl file operation. */
 /* Returns -ENOIOCTLCMD for unrecognised ioctl codes. */
 long comedi_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
@@ -481,106 +462,4 @@
 	return raw_ioctl(file, cmd, arg);
 }
 
-#else /* HAVE_COMPAT_IOCTL */
-
-/*
- * Brain-dead ioctl compatibility for 2.6.10 and earlier.
- *
- * It's brain-dead because cmd numbers need to be unique system-wide!
- * The comedi driver could end up attempting to execute ioctls for non-Comedi
- * devices because it registered the system-wide cmd code first.  Similarly,
- * another driver could end up attempting to execute ioctls for a Comedi
- * device because it registered the cmd code first.  Chaos ensues.
- */
-
-/* Handler for all 32-bit ioctl codes registered by this driver. */
-static int mapped_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg,
-			struct file *file)
-{
-	int rc;
-
-	/* Make sure we are dealing with a Comedi device. */
-	if (imajor(file->f_dentry->d_inode) != COMEDI_MAJOR)
-		return -ENOTTY;
-
-	rc = raw_ioctl(file, cmd, arg);
-	/* Do not return -ENOIOCTLCMD. */
-	if (rc == -ENOIOCTLCMD)
-		rc = -ENOTTY;
-
-	return rc;
-}
-
-struct ioctl32_map {
-	unsigned int cmd;
-	int (*handler) (unsigned int, unsigned int, unsigned long,
-			struct file *);
-	int registered;
-};
-
-static struct ioctl32_map comedi_ioctl32_map[] = {
-	{COMEDI_DEVCONFIG, mapped_ioctl, 0},
-	{COMEDI_DEVINFO, mapped_ioctl, 0},
-	{COMEDI_SUBDINFO, mapped_ioctl, 0},
-	{COMEDI_BUFCONFIG, mapped_ioctl, 0},
-	{COMEDI_BUFINFO, mapped_ioctl, 0},
-	{COMEDI_LOCK, mapped_ioctl, 0},
-	{COMEDI_UNLOCK, mapped_ioctl, 0},
-	{COMEDI_CANCEL, mapped_ioctl, 0},
-	{COMEDI_POLL, mapped_ioctl, 0},
-	{COMEDI32_CHANINFO, mapped_ioctl, 0},
-	{COMEDI32_RANGEINFO, mapped_ioctl, 0},
-	{COMEDI32_CMD, mapped_ioctl, 0},
-	{COMEDI32_CMDTEST, mapped_ioctl, 0},
-	{COMEDI32_INSNLIST, mapped_ioctl, 0},
-	{COMEDI32_INSN, mapped_ioctl, 0},
-};
-
-#define NUM_IOCTL32_MAPS ARRAY_SIZE(comedi_ioctl32_map)
-
-/* Register system-wide 32-bit ioctl handlers. */
-void comedi_register_ioctl32(void)
-{
-	int n, rc;
-
-	for (n = 0; n < NUM_IOCTL32_MAPS; n++) {
-		rc = register_ioctl32_conversion(comedi_ioctl32_map[n].cmd,
-						 comedi_ioctl32_map[n].handler);
-		if (rc) {
-			printk(KERN_WARNING
-			       "comedi: failed to register 32-bit "
-			       "compatible ioctl handler for 0x%X - "
-			       "expect bad things to happen!\n",
-			       comedi_ioctl32_map[n].cmd);
-		}
-		comedi_ioctl32_map[n].registered = !rc;
-	}
-}
-
-/* Unregister system-wide 32-bit ioctl translations. */
-void comedi_unregister_ioctl32(void)
-{
-	int n, rc;
-
-	for (n = 0; n < NUM_IOCTL32_MAPS; n++) {
-		if (comedi_ioctl32_map[n].registered) {
-			rc = unregister_ioctl32_conversion(comedi_ioctl32_map
-							   [n].cmd,
-							   comedi_ioctl32_map
-							   [n].handler);
-			if (rc) {
-				printk(KERN_ERR
-				       "comedi: failed to unregister 32-bit "
-				       "compatible ioctl handler for 0x%X - "
-				       "expect kernel Oops!\n",
-				       comedi_ioctl32_map[n].cmd);
-			} else {
-				comedi_ioctl32_map[n].registered = 0;
-			}
-		}
-	}
-}
-
-#endif /* HAVE_COMPAT_IOCTL */
-
 #endif /* CONFIG_COMPAT */
diff --git a/drivers/staging/comedi/comedi_compat32.h b/drivers/staging/comedi/comedi_compat32.h
index fd0f8a3..0340a89 100644
--- a/drivers/staging/comedi/comedi_compat32.h
+++ b/drivers/staging/comedi/comedi_compat32.h
@@ -28,30 +28,16 @@
 #define _COMEDI_COMPAT32_H
 
 #include <linux/compat.h>
-#include <linux/fs.h>		/* For HAVE_COMPAT_IOCTL and HAVE_UNLOCKED_IOCTL */
+#include <linux/fs.h>
 
 #ifdef CONFIG_COMPAT
 
-#ifdef HAVE_COMPAT_IOCTL
-
 extern long comedi_compat_ioctl(struct file *file, unsigned int cmd,
 				unsigned long arg);
-#define comedi_register_ioctl32() do {} while (0)
-#define comedi_unregister_ioctl32() do {} while (0)
-
-#else /* HAVE_COMPAT_IOCTL */
-
-#define comedi_compat_ioctl 0	/* NULL */
-extern void comedi_register_ioctl32(void);
-extern void comedi_unregister_ioctl32(void);
-
-#endif /* HAVE_COMPAT_IOCTL */
 
 #else /* CONFIG_COMPAT */
 
 #define comedi_compat_ioctl 0	/* NULL */
-#define comedi_register_ioctl32() do {} while (0)
-#define comedi_unregister_ioctl32() do {} while (0)
 
 #endif /* CONFIG_COMPAT */
 
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index aaad76e..8117748 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -110,13 +110,8 @@
 static struct device_attribute dev_attr_max_write_buffer_kb;
 static struct device_attribute dev_attr_write_buffer_kb;
 
-#ifdef HAVE_UNLOCKED_IOCTL
 static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
 				  unsigned long arg)
-#else
-static int comedi_ioctl(struct inode *inode, struct file *file,
-			unsigned int cmd, unsigned long arg)
-#endif
 {
 	const unsigned minor = iminor(file->f_dentry->d_inode);
 	struct comedi_device_file_info *dev_file_info =
@@ -1867,14 +1862,8 @@
 
 const struct file_operations comedi_fops = {
 	.owner = THIS_MODULE,
-#ifdef HAVE_UNLOCKED_IOCTL
 	.unlocked_ioctl = comedi_unlocked_ioctl,
-#else
-	.ioctl = comedi_ioctl,
-#endif
-#ifdef HAVE_COMPAT_IOCTL
 	.compat_ioctl = comedi_compat_ioctl,
-#endif
 	.open = comedi_open,
 	.release = comedi_close,
 	.read = comedi_read,
@@ -1959,8 +1948,6 @@
 		}
 	}
 
-	comedi_register_ioctl32();
-
 	return 0;
 }
 
@@ -1977,8 +1964,6 @@
 	unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS);
 
 	comedi_proc_cleanup();
-
-	comedi_unregister_ioctl32();
 }
 
 module_init(comedi_init);
diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h
index e8a5f7d..ebdccfd 100644
--- a/drivers/staging/comedi/comedidev.h
+++ b/drivers/staging/comedi/comedidev.h
@@ -49,7 +49,8 @@
 } while (0)
 
 #define COMEDI_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
-#define COMEDI_VERSION_CODE COMEDI_VERSION(COMEDI_MAJORVERSION, COMEDI_MINORVERSION, COMEDI_MICROVERSION)
+#define COMEDI_VERSION_CODE COMEDI_VERSION(COMEDI_MAJORVERSION, \
+	COMEDI_MINORVERSION, COMEDI_MICROVERSION)
 #define COMEDI_RELEASE VERSION
 
 #define COMEDI_INITCLEANUP_NOMODULE(x)					\
@@ -58,12 +59,12 @@
 	static void __exit x ## _cleanup_module(void)			\
 		{comedi_driver_unregister(&(x)); } 			\
 	module_init(x ## _init_module);					\
-	module_exit(x ## _cleanup_module);					\
+	module_exit(x ## _cleanup_module);
 
 #define COMEDI_MODULE_MACROS						\
 	MODULE_AUTHOR("Comedi http://www.comedi.org");		\
 	MODULE_DESCRIPTION("Comedi low-level driver");			\
-	MODULE_LICENSE("GPL");						\
+	MODULE_LICENSE("GPL");
 
 #define COMEDI_INITCLEANUP(x)						\
 	COMEDI_MODULE_MACROS		\
@@ -75,7 +76,8 @@
 	{ \
 		return comedi_pci_auto_config(dev, comedi_driver.driver_name); \
 	} \
-	static void __devexit comedi_driver ## _pci_remove(struct pci_dev *dev) \
+	static void __devexit comedi_driver ## _pci_remove(\
+		struct pci_dev *dev) \
 	{ \
 		comedi_pci_auto_unconfig(dev); \
 	} \
@@ -91,7 +93,8 @@
 		retval = comedi_driver_register(&comedi_driver); \
 		if (retval < 0) \
 			return retval; \
-		comedi_driver ## _pci_driver.name = (char *)comedi_driver.driver_name; \
+			comedi_driver ## _pci_driver.name = \
+				(char *)comedi_driver.driver_name; \
 		return pci_register_driver(&comedi_driver ## _pci_driver); \
 	} \
 	static void __exit comedi_driver ## _cleanup_module(void) \
@@ -170,14 +173,15 @@
 			   struct comedi_cmd *);
 	int (*poll) (struct comedi_device *, struct comedi_subdevice *);
 	int (*cancel) (struct comedi_device *, struct comedi_subdevice *);
-	/* int (*do_lock)(struct comedi_device *,struct comedi_subdevice *); */
-	/* int (*do_unlock)(struct comedi_device *,struct comedi_subdevice *); */
+	/* int (*do_lock)(struct comedi_device *, struct comedi_subdevice *); */
+	/* int (*do_unlock)(struct comedi_device *, \
+			struct comedi_subdevice *); */
 
 	/* called when the buffer changes */
-	int (*buf_change) (struct comedi_device * dev,
-			   struct comedi_subdevice * s, unsigned long new_size);
+	int (*buf_change) (struct comedi_device *dev,
+			   struct comedi_subdevice *s, unsigned long new_size);
 
-	void (*munge) (struct comedi_device * dev, struct comedi_subdevice * s,
+	void (*munge) (struct comedi_device *dev, struct comedi_subdevice *s,
 		       void *data, unsigned int num_bytes,
 		       unsigned int start_chan_index);
 	enum dma_data_direction async_dma_dir;
@@ -198,16 +202,22 @@
 
 	void *prealloc_buf;	/* pre-allocated buffer */
 	unsigned int prealloc_bufsz;	/* buffer size, in bytes */
-	struct comedi_buf_page *buf_page_list;	/* virtual and dma address of each page */
+	/* virtual and dma address of each page */
+	struct comedi_buf_page *buf_page_list;
 	unsigned n_buf_pages;	/* num elements in buf_page_list */
 
 	unsigned int max_bufsize;	/* maximum buffer size, bytes */
-	unsigned int mmap_count;	/* current number of mmaps of prealloc_buf */
+	/* current number of mmaps of prealloc_buf */
+	unsigned int mmap_count;
 
-	unsigned int buf_write_count;	/* byte count for writer (write completed) */
-	unsigned int buf_write_alloc_count;	/* byte count for writer (allocated for writing) */
-	unsigned int buf_read_count;	/* byte count for reader (read completed) */
-	unsigned int buf_read_alloc_count;	/* byte count for reader (allocated for reading) */
+	/* byte count for writer (write completed) */
+	unsigned int buf_write_count;
+	/* byte count for writer (allocated for writing) */
+	unsigned int buf_write_alloc_count;
+	/* byte count for reader (read completed) */
+	unsigned int buf_read_count;
+	/* byte count for reader (allocated for reading) */
+	unsigned int buf_read_alloc_count;
 
 	unsigned int buf_write_ptr;	/* buffer marker for writer */
 	unsigned int buf_read_ptr;	/* buffer marker for reader */
@@ -233,7 +243,7 @@
 	int (*cb_func) (unsigned int flags, void *);
 	void *cb_arg;
 
-	int (*inttrig) (struct comedi_device * dev, struct comedi_subdevice * s,
+	int (*inttrig) (struct comedi_device *dev, struct comedi_subdevice *s,
 			unsigned int x);
 };
 
@@ -283,8 +293,8 @@
 
 	struct fasync_struct *async_queue;
 
-	void (*open) (struct comedi_device * dev);
-	void (*close) (struct comedi_device * dev);
+	void (*open) (struct comedi_device *dev);
+	void (*close) (struct comedi_device *dev);
 };
 
 struct comedi_device_file_info {
@@ -318,9 +328,8 @@
 
 struct comedi_device_file_info *comedi_get_device_file_info(unsigned minor);
 
-static inline struct comedi_subdevice *comedi_get_read_subdevice(const struct
-								 comedi_device_file_info
-								 *info)
+static inline struct comedi_subdevice *comedi_get_read_subdevice(
+	const struct comedi_device_file_info *info)
 {
 	if (info->read_subdevice)
 		return info->read_subdevice;
@@ -329,9 +338,8 @@
 	return info->device->read_subdev;
 }
 
-static inline struct comedi_subdevice *comedi_get_write_subdevice(const struct
-								  comedi_device_file_info
-								  *info)
+static inline struct comedi_subdevice *comedi_get_write_subdevice(
+	const struct comedi_device_file_info *info)
 {
 	if (info->write_subdevice)
 		return info->write_subdevice;
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c
index dc53aee..c2a632d 100644
--- a/drivers/staging/comedi/drivers.c
+++ b/drivers/staging/comedi/drivers.c
@@ -387,7 +387,7 @@
 	return 1;
 }
 
-static inline unsigned long uvirt_to_kva(pgd_t * pgd, unsigned long adr)
+static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
 {
 	unsigned long ret = 0UL;
 	pmd_t *pmd;
diff --git a/drivers/staging/comedi/drivers/8253.h b/drivers/staging/comedi/drivers/8253.h
index c2ea2d9..0bb35db 100644
--- a/drivers/staging/comedi/drivers/8253.h
+++ b/drivers/staging/comedi/drivers/8253.h
@@ -206,7 +206,8 @@
 	}
 
 	*nanosec = div1 * div2 * i8253_osc_base;
-	*d1 = div1 & 0xffff;	/*  masking is done since counter maps zero to 0x10000 */
+	/*  masking is done since counter maps zero to 0x10000 */
+	*d1 = div1 & 0xffff;
 	*d2 = div2 & 0xffff;
 	return;
 }
diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c
index 0a50864..10f488f 100644
--- a/drivers/staging/comedi/drivers/8255.c
+++ b/drivers/staging/comedi/drivers/8255.c
@@ -132,6 +132,7 @@
 
 	comedi_event(dev, s);
 }
+EXPORT_SYMBOL(subdev_8255_interrupt);
 
 static int subdev_8255_cb(int dir, int port, int data, unsigned long arg)
 {
@@ -179,15 +180,14 @@
 	unsigned int bits;
 
 	mask = 1 << CR_CHAN(insn->chanspec);
-	if (mask & 0x0000ff) {
+	if (mask & 0x0000ff)
 		bits = 0x0000ff;
-	} else if (mask & 0x00ff00) {
+	else if (mask & 0x00ff00)
 		bits = 0x00ff00;
-	} else if (mask & 0x0f0000) {
+	else if (mask & 0x0f0000)
 		bits = 0x0f0000;
-	} else {
+	else
 		bits = 0xf00000;
-	}
 
 	switch (data[0]) {
 	case INSN_CONFIG_DIO_INPUT:
@@ -333,11 +333,10 @@
 		return -ENOMEM;
 
 	CALLBACK_ARG = arg;
-	if (cb == NULL) {
+	if (cb == NULL)
 		CALLBACK_FUNC = subdev_8255_cb;
-	} else {
+	else
 		CALLBACK_FUNC = cb;
-	}
 	s->insn_bits = subdev_8255_insn;
 	s->insn_config = subdev_8255_insn_config;
 
@@ -347,6 +346,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(subdev_8255_init);
 
 int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s,
 			 int (*cb) (int, int, int, unsigned long),
@@ -366,6 +366,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(subdev_8255_init_irq);
 
 void subdev_8255_cleanup(struct comedi_device *dev, struct comedi_subdevice *s)
 {
@@ -378,6 +379,7 @@
 		kfree(s->private);
 	}
 }
+EXPORT_SYMBOL(subdev_8255_cleanup);
 
 /*
 
@@ -448,8 +450,3 @@
 
 	return 0;
 }
-
-EXPORT_SYMBOL(subdev_8255_init);
-EXPORT_SYMBOL(subdev_8255_init_irq);
-EXPORT_SYMBOL(subdev_8255_cleanup);
-EXPORT_SYMBOL(subdev_8255_interrupt);
diff --git a/drivers/staging/comedi/drivers/acl7225b.c b/drivers/staging/comedi/drivers/acl7225b.c
index c3652ef..e20c354 100644
--- a/drivers/staging/comedi/drivers/acl7225b.c
+++ b/drivers/staging/comedi/drivers/acl7225b.c
@@ -94,10 +94,11 @@
 
 	iobase = it->options[0];
 	iorange = this_board->io_range;
-	printk("comedi%d: acl7225b: board=%s 0x%04x ", dev->minor,
+	printk(KERN_INFO "comedi%d: acl7225b: board=%s 0x%04x\n", dev->minor,
 	       this_board->name, iobase);
 	if (!request_region(iobase, iorange, "acl7225b")) {
-		printk("I/O port conflict\n");
+		printk(KERN_ERR "comedi%d: request_region failed - I/O port conflict\n",
+			dev->minor);
 		return -EIO;
 	}
 	dev->board_name = this_board->name;
@@ -137,14 +138,12 @@
 	s->range_table = &range_digital;
 	s->private = (void *)ACL7225_DI_LO;
 
-	printk("\n");
-
 	return 0;
 }
 
 static int acl7225b_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: acl7225b: remove\n", dev->minor);
+	printk(KERN_INFO "comedi%d: acl7225b: remove\n", dev->minor);
 
 	if (dev->iobase)
 		release_region(dev->iobase, this_board->io_range);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c
index ccb109a..0af12fd2 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c
@@ -1386,8 +1386,7 @@
 				/* Test the timout parameter */
 		 /*****************************/
 
-				if ((ui_TimeOut >= 0)
-					&& (ui_TimeOut <= 65535UL)) {
+				if (ui_TimeOut <= 65535UL) {
 
 					for (;;) {
 			  /*******************/
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c
index 6c092ef..a15c952 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c
@@ -3807,7 +3807,7 @@
 			s_ModuleInfo[b_ModulNbr].
 			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
 	      /********************************************/
-			/* Test if frequency mesurement initialised */
+			/* Test if frequency measurement initialised */
 	      /********************************************/
 
 			if (devpriv->
@@ -3953,7 +3953,7 @@
 			s_ModuleInfo[b_ModulNbr].
 			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
 	      /********************************************/
-			/* Test if frequency mesurement initialised */
+			/* Test if frequency measurement initialised */
 	      /********************************************/
 
 			if (devpriv->
@@ -5166,7 +5166,7 @@
 			s_ModuleInfo[b_ModulNbr].
 			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
 	      /********************************************/
-			/* Test if frequency mesurement initialised */
+			/* Test if frequency measurement initialised */
 	      /********************************************/
 
 			if (devpriv->
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c
index 43198aa..7e12544 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c
@@ -1808,7 +1808,7 @@
 									2) {
 									if (dw_Status & 4) {
 				/************************/
-										/* Tor counter owerflow */
+										/* Tor counter overflow */
 				/************************/
 
 										*pb_TorCounterStatus
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h
index edd657b..3ab27cf 100644
--- a/drivers/staging/comedi/drivers/addi-data/addi_common.h
+++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h
@@ -82,7 +82,7 @@
 
 	int i_NbrDiChannel;	/*  Number of DI channels */
 	int i_NbrDoChannel;	/*  Number of DO channels */
-	int i_DoMaxdata;	/*  data to set all chanels high */
+	int i_DoMaxdata;	/*  data to set all channels high */
 
 	int i_NbrTTLChannel;	/*  Number of TTL channels */
 	const struct comedi_lrange *pr_TTLRangelist;	/* rangelist for TTL */
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c
index e9021cd..723a97b 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c
@@ -150,7 +150,7 @@
 	unsigned int ui_TmpValue = 0;
 	unsigned int ui_Channel;
 	ui_Channel = CR_CHAN(insn->chanspec);
-	if (ui_Channel >= 0 && ui_Channel <= 31) {
+	if (ui_Channel <= 31) {
 		ui_TmpValue = (unsigned int) inl(devpriv->iobase + APCI1032_DIGITAL_IP);
 /*
 * since only 1 channel reqd to bring it to last bit it is rotated 8
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
index 236b8a3..36b929f 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
@@ -968,7 +968,7 @@
 
 	switch (data[0]) {
 	case 0:
-		if (ui_Channel >= 0 && ui_Channel <= 15) {
+		if (ui_Channel <= 15) {
 			ui_TmpValue =
 				(unsigned int) inw(devpriv->i_IobaseAddon +
 				APCI1500_DIGITAL_IP);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c
index 3841635..866eb8d 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c
@@ -79,7 +79,7 @@
 	unsigned int ui_TmpValue = 0;
 	unsigned int ui_Channel;
 	ui_Channel = CR_CHAN(insn->chanspec);
-	if (ui_Channel >= 0 && ui_Channel <= 7) {
+	if (ui_Channel <= 7) {
 		ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI1516_DIGITAL_IP);
 		/*   since only 1 channel reqd  to bring it to last bit it is rotated */
 		/*   8 +(chan - 1) times then ANDed with 1 for last bit. */
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
index 3a47c30..3ae663b 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
@@ -154,7 +154,7 @@
 	unsigned int ui_Channel;
 
 	ui_Channel = CR_CHAN(insn->chanspec);
-	if (ui_Channel >= 0 && ui_Channel <= 31) {
+	if (ui_Channel <= 31) {
 		ui_TmpValue =
 			(unsigned int) inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP);
 /*
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c
index 457917f..d348cd5 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c
@@ -117,7 +117,7 @@
 	unsigned int ui_NoOfChannel;
 	unsigned int ui_Temp, ui_Temp1;
 	ui_NoOfChannel = CR_CHAN(insn->chanspec);
-	if ((ui_NoOfChannel < 0) || (ui_NoOfChannel > 15)) {
+	if (ui_NoOfChannel > 15) {
 		comedi_error(dev,
 			"Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n");
 		return -EINVAL;
@@ -272,7 +272,7 @@
 	unsigned int ui_Temp;
 	unsigned int ui_NoOfChannel;
 	ui_NoOfChannel = CR_CHAN(insn->chanspec);
-	if ((ui_NoOfChannel < 0) || (ui_NoOfChannel > 15)) {
+	if (ui_NoOfChannel > 15) {
 		comedi_error(dev,
 			"Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n");
 		return -EINVAL;
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c
index a853c62..aa159dc 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c
@@ -79,7 +79,7 @@
 	unsigned int ui_TmpValue = 0;
 	unsigned int ui_Channel;
 	ui_Channel = CR_CHAN(insn->chanspec);
-	if (ui_Channel >= 0 && ui_Channel <= 7) {
+	if (ui_Channel <= 7) {
 		ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI2200_DIGITAL_IP);
 		*data = (ui_TmpValue >> ui_Channel) & 0x1;
 	}			/* if(ui_Channel >= 0 && ui_Channel <=7) */
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
index 169cee4..172fba8 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
@@ -1468,7 +1468,7 @@
 	int_amcc = inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR);	/*  get AMCC int register */
 
 	if ((!int_daq) && (!(int_amcc & ANY_S593X_INT))) {
-		comedi_error(dev, "IRQ from unknow source");
+		comedi_error(dev, "IRQ from unknown source");
 		return;
 	}
 
@@ -2350,7 +2350,7 @@
 	ui_Chan = CR_CHAN(insn->chanspec);	/*  channel specified */
 
 	/* this_board->i_hwdrv_InsnReadDigitalInput(dev,ui_Chan,data); */
-	if (ui_Chan >= 0 && ui_Chan <= 3) {
+	if (ui_Chan <= 3) {
 		ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI3120_RD_STATUS);
 
 /*
@@ -2539,8 +2539,7 @@
 			"Not a valid Data !!! ,Data should be 1 or 0\n");
 		return -EINVAL;
 	}
-	if ((ui_NoOfChannel > (this_board->i_NbrDoChannel - 1))
-		|| (ui_NoOfChannel < 0)) {
+	if (ui_NoOfChannel > this_board->i_NbrDoChannel - 1) {
 		comedi_error(dev,
 			"This board doesn't have specified channel !!! \n");
 		return -EINVAL;
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
index 010697f..98c2387 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
@@ -461,7 +461,7 @@
 	if (s_BoardInfos[dev->minor].i_ConnectionType == 1) {
 		/* if diff */
 
-		if ((ui_Channel_num >= 0) && (ui_Channel_num <= 1))
+		if (ui_Channel_num <= 1)
 			i_DiffChannel = ui_Channel_num, i_Module = 0;
 		else if ((ui_Channel_num >= 2) && (ui_Channel_num <= 3))
 			i_DiffChannel = ui_Channel_num - 2, i_Module = 1;
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
index ef21f03..7b38d17 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
@@ -724,7 +724,7 @@
 		APCI3501_TCW_IRQ) & 0x1;
 
 	if ((!ui_Timer_AOWatchdog)) {
-		comedi_error(dev, "IRQ from unknow source");
+		comedi_error(dev, "IRQ from unknown source");
 		return;
 	}
 
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
index 3387278..1d1e5fc 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
@@ -148,7 +148,7 @@
 			/* Test the convert time value */
 	      /*******************************/
 
-			if ((dw_ReloadValue >= 0) && (dw_ReloadValue <= 65535)) {
+			if (dw_ReloadValue <= 65535) {
 				dw_TestReloadValue = dw_ReloadValue;
 
 				if (b_TimeBase == 1) {
diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c
index 8e1befc..6925faa 100644
--- a/drivers/staging/comedi/drivers/adl_pci6208.c
+++ b/drivers/staging/comedi/drivers/adl_pci6208.c
@@ -133,9 +133,11 @@
 static int pci6208_ao_rinsn(struct comedi_device *dev,
 			    struct comedi_subdevice *s,
 			    struct comedi_insn *insn, unsigned int *data);
-/* static int pci6208_dio_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s, */
+/* static int pci6208_dio_insn_bits (struct comedi_device *dev,
+ * 					struct comedi_subdevice *s, */
 /* struct comedi_insn *insn,unsigned int *data); */
-/* static int pci6208_dio_insn_config(struct comedi_device *dev,struct comedi_subdevice *s, */
+/* static int pci6208_dio_insn_config(struct comedi_device *dev,
+ * 					struct comedi_subdevice *s, */
 /* struct comedi_insn *insn,unsigned int *data); */
 
 /*
@@ -151,7 +153,7 @@
 	int retval;
 	unsigned long io_base;
 
-	printk("comedi%d: pci6208: ", dev->minor);
+	printk(KERN_INFO "comedi%d: pci6208: ", dev->minor);
 
 	retval = alloc_private(dev, sizeof(struct pci6208_private));
 	if (retval < 0)
@@ -195,7 +197,7 @@
 	/* s->insn_bits = pci6208_dio_insn_bits; */
 	/* s->insn_config = pci6208_dio_insn_config; */
 
-	printk("attached\n");
+	printk(KERN_INFO "attached\n");
 
 	return 1;
 }
@@ -210,12 +212,11 @@
  */
 static int pci6208_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: pci6208: remove\n", dev->minor);
+	printk(KERN_INFO "comedi%d: pci6208: remove\n", dev->minor);
 
 	if (devpriv && devpriv->pci_dev) {
-		if (dev->iobase) {
+		if (dev->iobase)
 			comedi_pci_disable(devpriv->pci_dev);
-		}
 		pci_dev_put(devpriv->pci_dev);
 	}
 
@@ -266,7 +267,8 @@
  * useful to applications if you implement the insn_bits interface.
  * This allows packed reading/writing of the DIO channels.  The
  * comedi core can convert between insn_bits and insn_read/write */
-/* static int pci6208_dio_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s, */
+/* static int pci6208_dio_insn_bits(struct comedi_device *dev,
+ * 					struct comedi_subdevice *s, */
 /* struct comedi_insn *insn,unsigned int *data) */
 /* { */
 /* if(insn->n!=2)return -EINVAL; */
@@ -290,7 +292,8 @@
 /* return 2; */
 /* } */
 
-/* static int pci6208_dio_insn_config(struct comedi_device *dev,struct comedi_subdevice *s, */
+/* static int pci6208_dio_insn_config(struct comedi_device *dev,
+ * 					struct comedi_subdevice *s, */
 /* struct comedi_insn *insn,unsigned int *data) */
 /* { */
 /* int chan=CR_CHAN(insn->chanspec); */
@@ -320,10 +323,16 @@
 	     pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) {
 		if (pci_dev->vendor == PCI_VENDOR_ID_ADLINK) {
 			for (i = 0; i < ARRAY_SIZE(pci6208_boards); i++) {
-				if (pci6208_boards[i].dev_id == pci_dev->device) {
-					/*  was a particular bus/slot requested? */
+				if (pci6208_boards[i].dev_id ==
+					pci_dev->device) {
+					/*
+					 * was a particular bus/slot requested?
+					*/
 					if ((bus != 0) || (slot != 0)) {
-						/*  are we on the wrong bus/slot? */
+						/*
+						 * are we on the
+						 * wrong bus/slot?
+						*/
 						if (pci_dev->bus->number
 						    != bus ||
 						    PCI_SLOT(pci_dev->devfn)
@@ -338,8 +347,9 @@
 		}
 	}
 
-	printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
-	       dev->minor, bus, slot);
+	printk(KERN_ERR "comedi%d: no supported board found! "
+			"(req. bus/slot : %d/%d)\n",
+			dev->minor, bus, slot);
 	return -EIO;
 
 found:
@@ -368,17 +378,20 @@
 
 	/*  Enable PCI device and request regions */
 	if (comedi_pci_enable(pci_dev, PCI6208_DRIVER_NAME) < 0) {
-		printk
-		    ("comedi%d: Failed to enable PCI device and request regions\n",
-		     dev_minor);
+		printk(KERN_ERR "comedi%d: Failed to enable PCI device "
+			"and request regions\n",
+			dev_minor);
 		return -EIO;
 	}
-	/*  Read local configuration register base address [PCI_BASE_ADDRESS #1]. */
+	/* Read local configuration register
+	 * base address [PCI_BASE_ADDRESS #1].
+	 */
 	lcr_io_base = pci_resource_start(pci_dev, 1);
 	lcr_io_range = pci_resource_len(pci_dev, 1);
 
-	printk("comedi%d: local config registers at address 0x%4lx [0x%4lx]\n",
-	       dev_minor, lcr_io_base, lcr_io_range);
+	printk(KERN_INFO "comedi%d: local config registers at address"
+			" 0x%4lx [0x%4lx]\n",
+			dev_minor, lcr_io_base, lcr_io_range);
 
 	/*  Read PCI6208 register base address [PCI_BASE_ADDRESS #2]. */
 	io_base = pci_resource_start(pci_dev, 2);
diff --git a/drivers/staging/comedi/drivers/adl_pci7296.c b/drivers/staging/comedi/drivers/adl_pci7296.c
index 4de6fad..8602865 100644
--- a/drivers/staging/comedi/drivers/adl_pci7296.c
+++ b/drivers/staging/comedi/drivers/adl_pci7296.c
@@ -82,8 +82,7 @@
 	int bus, slot;
 	int ret;
 
-	printk("comedi: attempt to attach...\n");
-	printk("comedi%d: adl_pci7432\n", dev->minor);
+	printk(KERN_INFO "comedi%d: attach adl_pci7432\n", dev->minor);
 
 	dev->board_name = "pci7432";
 	bus = it->options[0];
@@ -110,14 +109,14 @@
 			}
 			devpriv->pci_dev = pcidev;
 			if (comedi_pci_enable(pcidev, "adl_pci7296") < 0) {
-				printk
-				    ("comedi%d: Failed to enable PCI device and request regions\n",
+				printk(KERN_ERR "comedi%d: Failed to enable PCI device and request regions\n",
 				     dev->minor);
 				return -EIO;
 			}
 
 			dev->iobase = pci_resource_start(pcidev, 2);
-			printk("comedi: base addr %4lx\n", dev->iobase);
+			printk(KERN_INFO "comedi: base addr %4lx\n",
+				dev->iobase);
 
 			/*  four 8255 digital io subdevices */
 			s = dev->subdevices + 0;
@@ -145,25 +144,25 @@
 			if (ret < 0)
 				return ret;
 
-			printk("attached\n");
+			printk(KERN_DEBUG "comedi%d: adl_pci7432 attached\n",
+				dev->minor);
 
 			return 1;
 		}
 	}
 
-	printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
+	printk(KERN_ERR "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
 	       dev->minor, bus, slot);
 	return -EIO;
 }
 
 static int adl_pci7296_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: pci7432: remove\n", dev->minor);
+	printk(KERN_INFO "comedi%d: pci7432: remove\n", dev->minor);
 
 	if (devpriv && devpriv->pci_dev) {
-		if (dev->iobase) {
+		if (dev->iobase)
 			comedi_pci_disable(devpriv->pci_dev);
-		}
 		pci_dev_put(devpriv->pci_dev);
 	}
 	/*  detach four 8255 digital io subdevices */
diff --git a/drivers/staging/comedi/drivers/adl_pci7432.c b/drivers/staging/comedi/drivers/adl_pci7432.c
index e0844c6..b5a9499 100644
--- a/drivers/staging/comedi/drivers/adl_pci7432.c
+++ b/drivers/staging/comedi/drivers/adl_pci7432.c
@@ -90,8 +90,7 @@
 	struct comedi_subdevice *s;
 	int bus, slot;
 
-	printk("comedi: attempt to attach...\n");
-	printk("comedi%d: adl_pci7432\n", dev->minor);
+	printk(KERN_INFO "comedi%d: attach adl_pci7432\n", dev->minor);
 
 	dev->board_name = "pci7432";
 	bus = it->options[0];
@@ -118,13 +117,13 @@
 			}
 			devpriv->pci_dev = pcidev;
 			if (comedi_pci_enable(pcidev, "adl_pci7432") < 0) {
-				printk
-				    ("comedi%d: Failed to enable PCI device and request regions\n",
+				printk(KERN_ERR "comedi%d: Failed to enable PCI device and request regions\n",
 				     dev->minor);
 				return -EIO;
 			}
 			dev->iobase = pci_resource_start(pcidev, 2);
-			printk("comedi: base addr %4lx\n", dev->iobase);
+			printk(KERN_INFO "comedi: base addr %4lx\n",
+				dev->iobase);
 
 			s = dev->subdevices + 0;
 			s->type = COMEDI_SUBD_DI;
@@ -148,25 +147,24 @@
 			s->range_table = &range_digital;
 			s->insn_bits = adl_pci7432_do_insn_bits;
 
-			printk("comedi: attached\n");
-
+			printk(KERN_DEBUG "comedi%d: adl_pci7432 attached\n",
+				dev->minor);
 			return 1;
 		}
 	}
 
-	printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
+	printk(KERN_ERR "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
 	       dev->minor, bus, slot);
 	return -EIO;
 }
 
 static int adl_pci7432_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: pci7432: remove\n", dev->minor);
+	printk(KERN_INFO "comedi%d: pci7432: remove\n", dev->minor);
 
 	if (devpriv && devpriv->pci_dev) {
-		if (dev->iobase) {
+		if (dev->iobase)
 			comedi_pci_disable(devpriv->pci_dev);
-		}
 		pci_dev_put(devpriv->pci_dev);
 	}
 
@@ -178,8 +176,8 @@
 				    struct comedi_insn *insn,
 				    unsigned int *data)
 {
-	printk("comedi: pci7432_do_insn_bits called\n");
-	printk("comedi: data0: %8x data1: %8x\n", data[0], data[1]);
+	printk(KERN_DEBUG "comedi: pci7432_do_insn_bits called\n");
+	printk(KERN_DEBUG "comedi: data0: %8x data1: %8x\n", data[0], data[1]);
 
 	if (insn->n != 2)
 		return -EINVAL;
@@ -188,7 +186,7 @@
 		s->state &= ~data[0];
 		s->state |= (data[0] & data[1]);
 
-		printk("comedi: out: %8x on iobase %4lx\n", s->state,
+		printk(KERN_DEBUG "comedi: out: %8x on iobase %4lx\n", s->state,
 		       dev->iobase + PCI7432_DO);
 		outl(s->state & 0xffffffff, dev->iobase + PCI7432_DO);
 	}
@@ -200,14 +198,14 @@
 				    struct comedi_insn *insn,
 				    unsigned int *data)
 {
-	printk("comedi: pci7432_di_insn_bits called\n");
-	printk("comedi: data0: %8x data1: %8x\n", data[0], data[1]);
+	printk(KERN_DEBUG "comedi: pci7432_di_insn_bits called\n");
+	printk(KERN_DEBUG "comedi: data0: %8x data1: %8x\n", data[0], data[1]);
 
 	if (insn->n != 2)
 		return -EINVAL;
 
 	data[1] = inl(dev->iobase + PCI7432_DI) & 0xffffffff;
-	printk("comedi: data1 %8x\n", data[1]);
+	printk(KERN_DEBUG "comedi: data1 %8x\n", data[1]);
 
 	return 2;
 }
diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c
index 43745ec..da256a1 100644
--- a/drivers/staging/comedi/drivers/adl_pci8164.c
+++ b/drivers/staging/comedi/drivers/adl_pci8164.c
@@ -35,6 +35,7 @@
 */
 
 #include "../comedidev.h"
+#include <linux/kernel.h>
 #include <linux/delay.h>
 #include "comedi_fc.h"
 #include "comedi_pci.h"
@@ -128,8 +129,8 @@
 	struct comedi_subdevice *s;
 	int bus, slot;
 
-	printk("comedi: attempt to attach...\n");
-	printk("comedi%d: adl_pci8164\n", dev->minor);
+	printk(KERN_INFO "comedi: attempt to attach...\n");
+	printk(KERN_INFO "comedi%d: adl_pci8164\n", dev->minor);
 
 	dev->board_name = "pci8164";
 	bus = it->options[0];
@@ -150,19 +151,18 @@
 			if (bus || slot) {
 				/* requested particular bus/slot */
 				if (pcidev->bus->number != bus
-				    || PCI_SLOT(pcidev->devfn) != slot) {
+					|| PCI_SLOT(pcidev->devfn) != slot)
 					continue;
-				}
 			}
 			devpriv->pci_dev = pcidev;
 			if (comedi_pci_enable(pcidev, "adl_pci8164") < 0) {
-				printk
-				    ("comedi%d: Failed to enable PCI device and request regions\n",
-				     dev->minor);
+				printk(KERN_ERR "comedi%d: Failed to enable "
+				"PCI device and request regions\n", dev->minor);
 				return -EIO;
 			}
 			dev->iobase = pci_resource_start(pcidev, 2);
-			printk("comedi: base addr %4lx\n", dev->iobase);
+			printk(KERN_DEBUG "comedi: base addr %4lx\n",
+				   dev->iobase);
 
 			s = dev->subdevices + 0;
 			s->type = COMEDI_SUBD_PROC;
@@ -204,25 +204,24 @@
 			s->insn_read = adl_pci8164_insn_read_buf1;
 			s->insn_write = adl_pci8164_insn_write_buf1;
 
-			printk("comedi: attached\n");
+			printk(KERN_INFO "comedi: attached\n");
 
 			return 1;
 		}
 	}
 
-	printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
-	       dev->minor, bus, slot);
+	printk(KERN_ERR "comedi%d: no supported board found!"
+		   "(req. bus/slot : %d/%d)\n", dev->minor, bus, slot);
 	return -EIO;
 }
 
 static int adl_pci8164_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: pci8164: remove\n", dev->minor);
+	printk(KERN_INFO "comedi%d: pci8164: remove\n", dev->minor);
 
 	if (devpriv && devpriv->pci_dev) {
-		if (dev->iobase) {
+		if (dev->iobase)
 			comedi_pci_disable(devpriv->pci_dev);
-		}
 		pci_dev_put(devpriv->pci_dev);
 	}
 
@@ -267,8 +266,9 @@
 	}
 
 	data[0] = inw(dev->iobase + axis_reg + offset);
-	printk("comedi: pci8164 %s read -> %04X:%04X on axis %s\n", action,
-	       data[0], data[1], axisname);
+	printk(KERN_DEBUG "comedi: pci8164 %s read -> "
+						  "%04X:%04X on axis %s\n",
+				action, data[0], data[1], axisname);
 }
 
 static int adl_pci8164_insn_read_msts(struct comedi_device *dev,
@@ -347,8 +347,9 @@
 
 	outw(data[0], dev->iobase + axis_reg + offset);
 
-	printk("comedi: pci8164 %s write -> %04X:%04X on axis %s\n", action,
-	       data[0], data[1], axisname);
+	printk(KERN_DEBUG "comedi: pci8164 %s write -> "
+						"%04X:%04X on axis %s\n",
+				action, data[0], data[1], axisname);
 
 }
 
diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c
index 1ee4b6a..791ea83 100644
--- a/drivers/staging/comedi/drivers/adl_pci9118.c
+++ b/drivers/staging/comedi/drivers/adl_pci9118.c
@@ -780,7 +780,7 @@
 			      struct comedi_cmd *cmd)
 {
 	int err = 0;
-	int tmp, divisor1, divisor2;
+	int tmp, divisor1 = 0, divisor2 = 0;
 
 	/* step 1: make sure trigger sources are trivially valid */
 
diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c
index f0ae4c0..951e579 100644
--- a/drivers/staging/comedi/drivers/adv_pci1710.c
+++ b/drivers/staging/comedi/drivers/adv_pci1710.c
@@ -830,7 +830,7 @@
 static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev,
 				     struct comedi_subdevice *s)
 {
-	unsigned int divisor1, divisor2;
+	unsigned int divisor1 = 0, divisor2 = 0;
 	unsigned int seglen;
 
 	DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_docmd_and_mode(%d,...)\n",
@@ -934,7 +934,7 @@
 			      struct comedi_cmd *cmd)
 {
 	int err = 0;
-	int tmp, divisor1, divisor2;
+	int tmp, divisor1 = 0, divisor2 = 0;
 
 	DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...)\n");
 #ifdef PCI171X_EXTDEBUG
diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c
index c62a7e1..15808e9 100644
--- a/drivers/staging/comedi/drivers/amplc_pc263.c
+++ b/drivers/staging/comedi/drivers/amplc_pc263.c
@@ -117,7 +117,8 @@
 
 /* this structure is for data unique to this hardware driver.  If
    several hardware drivers keep similar information in this structure,
-   feel free to suggest moving the variable to the struct comedi_device struct.  */
+   feel free to suggest moving the variable to the struct comedi_device struct.
+*/
 #ifdef CONFIG_COMEDI_PCI
 struct pc263_private {
 	/* PCI device. */
@@ -281,7 +282,8 @@
 		ret = comedi_pci_enable(pci_dev, PC263_DRIVER_NAME);
 		if (ret < 0) {
 			printk(KERN_ERR
-			       "comedi%d: error! cannot enable PCI device and request regions!\n",
+			       "comedi%d: error! cannot enable PCI device and "
+				"request regions!\n",
 			       dev->minor);
 			return ret;
 		}
@@ -290,9 +292,8 @@
 #endif
 	{
 		ret = pc263_request_region(dev->minor, iobase, PC263_IO_SIZE);
-		if (ret < 0) {
+		if (ret < 0)
 			return ret;
-		}
 	}
 	dev->iobase = iobase;
 
@@ -350,21 +351,18 @@
 	       PC263_DRIVER_NAME);
 
 #ifdef CONFIG_COMEDI_PCI
-	if (devpriv)
+	if (devpriv) {
 #endif
-	{
 #ifdef CONFIG_COMEDI_PCI
 		if (devpriv->pci_dev) {
-			if (dev->iobase) {
+			if (dev->iobase)
 				comedi_pci_disable(devpriv->pci_dev);
-			}
 			pci_dev_put(devpriv->pci_dev);
 		} else
 #endif
 		{
-			if (dev->iobase) {
+			if (dev->iobase)
 				release_region(dev->iobase, PC263_IO_SIZE);
-			}
 		}
 	}
 	if (dev->board_name) {
diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c
index 39923cb..bc375e7 100644
--- a/drivers/staging/comedi/drivers/cb_das16_cs.c
+++ b/drivers/staging/comedi/drivers/cb_das16_cs.c
@@ -372,7 +372,7 @@
 
 	/* step 2: make sure trigger sources are unique and mutually compatible */
 
-	/* note that mutual compatiblity is not an issue here */
+	/* note that mutual compatibility is not an issue here */
 	if (cmd->scan_begin_src != TRIG_TIMER &&
 	    cmd->scan_begin_src != TRIG_EXT)
 		err++;
@@ -452,7 +452,7 @@
 	/* step 4: fix up any arguments */
 
 	if (cmd->scan_begin_src == TRIG_TIMER) {
-		unsigned int div1, div2;
+		unsigned int div1 = 0, div2 = 0;
 
 		tmp = cmd->scan_begin_arg;
 		i8253_cascade_ns_to_timer(100, &div1, &div2,
@@ -462,7 +462,7 @@
 			err++;
 	}
 	if (cmd->convert_src == TRIG_TIMER) {
-		unsigned int div1, div2;
+		unsigned int div1 = 0, div2 = 0;
 
 		tmp = cmd->convert_arg;
 		i8253_cascade_ns_to_timer(100, &div1, &div2,
diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c
index 7a5d46e..7823577 100644
--- a/drivers/staging/comedi/drivers/cb_pcidda.c
+++ b/drivers/staging/comedi/drivers/cb_pcidda.c
@@ -497,7 +497,7 @@
 
 	/* step 2: make sure trigger sources are unique and mutually compatible */
 
-	/* note that mutual compatiblity is not an issue here */
+	/* note that mutual compatibility is not an issue here */
 	if (cmd->scan_begin_src != TRIG_TIMER
 	    && cmd->scan_begin_src != TRIG_EXT)
 		err++;
diff --git a/drivers/staging/comedi/drivers/cb_pcidio.c b/drivers/staging/comedi/drivers/cb_pcidio.c
index 09e6e3b..7daad0a 100644
--- a/drivers/staging/comedi/drivers/cb_pcidio.c
+++ b/drivers/staging/comedi/drivers/cb_pcidio.c
@@ -109,12 +109,12 @@
    several hardware drivers keep similar information in this structure,
    feel free to suggest moving the variable to the struct comedi_device struct.  */
 struct pcidio_private {
-	int data;		/*  curently unused */
+	int data;		/*  currently unused */
 
 	/* would be useful for a PCI device */
 	struct pci_dev *pci_dev;
 
-	/* used for DO readback, curently unused */
+	/* used for DO readback, currently unused */
 	unsigned int do_readback[4];	/* up to 4 unsigned int suffice to hold 96 bits for PCI-DIO96 */
 
 	unsigned long dio_reg_base;	/*  address of port A of the first 8255 chip on board */
diff --git a/drivers/staging/comedi/drivers/comedi_fc.c b/drivers/staging/comedi/drivers/comedi_fc.c
index f781154..63be619 100644
--- a/drivers/staging/comedi/drivers/comedi_fc.c
+++ b/drivers/staging/comedi/drivers/comedi_fc.c
@@ -53,7 +53,7 @@
 
 	retval = comedi_buf_write_alloc(async, num_bytes);
 	if (retval != num_bytes) {
-		printk("comedi: buffer overrun\n");
+		printk(KERN_WARNING "comedi: buffer overrun\n");
 		async->events |= COMEDI_CB_OVERFLOW;
 		return 0;
 	}
@@ -65,7 +65,6 @@
 
 	return num_bytes;
 }
-
 EXPORT_SYMBOL(cfc_write_array_to_buffer);
 
 unsigned int cfc_read_array_from_buffer(struct comedi_subdevice *subd,
@@ -84,7 +83,6 @@
 
 	return num_bytes;
 }
-
 EXPORT_SYMBOL(cfc_read_array_from_buffer);
 
 unsigned int cfc_handle_events(struct comedi_device *dev,
@@ -102,7 +100,6 @@
 
 	return events;
 }
-
 EXPORT_SYMBOL(cfc_handle_events);
 
 MODULE_AUTHOR("Frank Mori Hess <fmhess@users.sourceforge.net>");
diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c
index aeec1ee..9db9a46 100644
--- a/drivers/staging/comedi/drivers/dmm32at.c
+++ b/drivers/staging/comedi/drivers/dmm32at.c
@@ -629,7 +629,7 @@
 
 	/* step 2: make sure trigger sources are unique and mutually compatible */
 
-	/* note that mutual compatiblity is not an issue here */
+	/* note that mutual compatibility is not an issue here */
 	if (cmd->scan_begin_src != TRIG_TIMER &&
 	    cmd->scan_begin_src != TRIG_EXT)
 		err++;
diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c
index 0364bbf..e1b7375 100644
--- a/drivers/staging/comedi/drivers/dt2814.c
+++ b/drivers/staging/comedi/drivers/dt2814.c
@@ -175,7 +175,7 @@
 
 	/* step 2: make sure trigger sources are unique and mutually compatible */
 
-	/* note that mutual compatiblity is not an issue here */
+	/* note that mutual compatibility is not an issue here */
 	if (cmd->stop_src != TRIG_TIMER && cmd->stop_src != TRIG_EXT)
 		err++;
 
diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c
index a4c96c0..99ca294 100644
--- a/drivers/staging/comedi/drivers/dt282x.c
+++ b/drivers/staging/comedi/drivers/dt282x.c
@@ -777,7 +777,7 @@
 
 	/* step 2: make sure trigger sources are unique and mutually compatible */
 
-	/* note that mutual compatiblity is not an issue here */
+	/* note that mutual compatibility is not an issue here */
 	if (cmd->scan_begin_src != TRIG_FOLLOW &&
 	    cmd->scan_begin_src != TRIG_EXT)
 		err++;
@@ -1050,7 +1050,7 @@
 
 	/* step 2: make sure trigger sources are unique and mutually compatible */
 
-	/* note that mutual compatiblity is not an issue here */
+	/* note that mutual compatibility is not an issue here */
 	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
 		err++;
 
diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c
index 0bb3016..51f12bf 100644
--- a/drivers/staging/comedi/drivers/gsc_hpdi.c
+++ b/drivers/staging/comedi/drivers/gsc_hpdi.c
@@ -55,7 +55,7 @@
 
 static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it);
 static int hpdi_detach(struct comedi_device *dev);
-void abort_dma(struct comedi_device *dev, unsigned int channel);
+static void abort_dma(struct comedi_device *dev, unsigned int channel);
 static int hpdi_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
 static int hpdi_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
 			 struct comedi_cmd *cmd);
@@ -110,7 +110,8 @@
 int command_channel_valid(unsigned int channel)
 {
 	if (channel == 0 || channel > 6) {
-		printk("gsc_hpdi: bug! invalid cable command channel\n");
+		printk(KERN_WARNING
+		       "gsc_hpdi: bug! invalid cable command channel\n");
 		return 0;
 	}
 	return 1;
@@ -142,7 +143,8 @@
 	RX_FIFO_RESET_BIT = 0x4,
 	TX_ENABLE_BIT = 0x10,
 	RX_ENABLE_BIT = 0x20,
-	DEMAND_DMA_DIRECTION_TX_BIT = 0x40,	/* for channel 0, channel 1 can only transmit (when present) */
+	DEMAND_DMA_DIRECTION_TX_BIT = 0x40,
+		/* for ch 0, ch 1 can only transmit (when present) */
 	LINE_VALID_ON_STATUS_VALID_BIT = 0x80,
 	START_TX_BIT = 0x10,
 	CABLE_THROTTLE_ENABLE_BIT = 0x20,
@@ -420,9 +422,11 @@
 	bits |= PLX_DMA_EN_READYIN_BIT;
 	/*  enable dma chaining */
 	bits |= PLX_EN_CHAIN_BIT;
-	/*  enable interrupt on dma done (probably don't need this, since chain never finishes) */
+	/*  enable interrupt on dma done
+	 *  (probably don't need this, since chain never finishes) */
 	bits |= PLX_EN_DMA_DONE_INTR_BIT;
-	/*  don't increment local address during transfers (we are transferring from a fixed fifo register) */
+	/*  don't increment local address during transfers
+	 *  (we are transferring from a fixed fifo register) */
 	bits |= PLX_LOCAL_ADDR_CONST_BIT;
 	/*  route dma interrupt to pci bus */
 	bits |= PLX_DMA_INTR_PCI_BIT;
@@ -560,7 +564,7 @@
 	int i;
 	int retval;
 
-	printk("comedi%d: gsc_hpdi\n", dev->minor);
+	printk(KERN_WARNING "comedi%d: gsc_hpdi\n", dev->minor);
 
 	if (alloc_private(dev, sizeof(struct hpdi_private)) < 0)
 		return -ENOMEM;
@@ -588,11 +592,12 @@
 		} while (pcidev != NULL);
 	}
 	if (dev->board_ptr == NULL) {
-		printk("gsc_hpdi: no hpdi card found\n");
+		printk(KERN_WARNING "gsc_hpdi: no hpdi card found\n");
 		return -EIO;
 	}
 
-	printk("gsc_hpdi: found %s on bus %i, slot %i\n", board(dev)->name,
+	printk(KERN_WARNING
+	       "gsc_hpdi: found %s on bus %i, slot %i\n", board(dev)->name,
 	       pcidev->bus->number, PCI_SLOT(pcidev->devfn));
 
 	if (comedi_pci_enable(pcidev, driver_hpdi.driver_name)) {
@@ -618,7 +623,7 @@
 	    ioremap(priv(dev)->hpdi_phys_iobase,
 		    pci_resource_len(pcidev, HPDI_BADDRINDEX));
 	if (!priv(dev)->plx9080_iobase || !priv(dev)->hpdi_iobase) {
-		printk(" failed to remap io memory\n");
+		printk(KERN_WARNING " failed to remap io memory\n");
 		return -ENOMEM;
 	}
 
@@ -630,12 +635,13 @@
 	/*  get irq */
 	if (request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED,
 			driver_hpdi.driver_name, dev)) {
-		printk(" unable to allocate irq %u\n", pcidev->irq);
+		printk(KERN_WARNING
+		       " unable to allocate irq %u\n", pcidev->irq);
 		return -EINVAL;
 	}
 	dev->irq = pcidev->irq;
 
-	printk(" irq %u\n", dev->irq);
+	printk(KERN_WARNING " irq %u\n", dev->irq);
 
 	/*  alocate pci dma buffers */
 	for (i = 0; i < NUM_DMA_BUFFERS; i++) {
@@ -653,7 +659,8 @@
 						   &priv(dev)->
 						   dma_desc_phys_addr);
 	if (priv(dev)->dma_desc_phys_addr & 0xf) {
-		printk(" dma descriptors not quad-word aligned (bug)\n");
+		printk(KERN_WARNING
+		       " dma descriptors not quad-word aligned (bug)\n");
 		return -EIO;
 	}
 
@@ -672,42 +679,39 @@
 {
 	unsigned int i;
 
-	printk("comedi%d: gsc_hpdi: remove\n", dev->minor);
+	printk(KERN_WARNING "comedi%d: gsc_hpdi: remove\n", dev->minor);
 
 	if (dev->irq)
 		free_irq(dev->irq, dev);
-	if (priv(dev)) {
-		if (priv(dev)->hw_dev) {
-			if (priv(dev)->plx9080_iobase) {
-				disable_plx_interrupts(dev);
-				iounmap((void *)priv(dev)->plx9080_iobase);
-			}
-			if (priv(dev)->hpdi_iobase)
-				iounmap((void *)priv(dev)->hpdi_iobase);
-			/*  free pci dma buffers */
-			for (i = 0; i < NUM_DMA_BUFFERS; i++) {
-				if (priv(dev)->dio_buffer[i])
-					pci_free_consistent(priv(dev)->hw_dev,
-							    DMA_BUFFER_SIZE,
-							    priv(dev)->
-							    dio_buffer[i],
-							    priv
-							    (dev)->dio_buffer_phys_addr
-							    [i]);
-			}
-			/*  free dma descriptors */
-			if (priv(dev)->dma_desc)
-				pci_free_consistent(priv(dev)->hw_dev,
-						    sizeof(struct plx_dma_desc)
-						    * NUM_DMA_DESCRIPTORS,
-						    priv(dev)->dma_desc,
-						    priv(dev)->
-						    dma_desc_phys_addr);
-			if (priv(dev)->hpdi_phys_iobase) {
-				comedi_pci_disable(priv(dev)->hw_dev);
-			}
-			pci_dev_put(priv(dev)->hw_dev);
+	if ((priv(dev)) && (priv(dev)->hw_dev)) {
+		if (priv(dev)->plx9080_iobase) {
+			disable_plx_interrupts(dev);
+			iounmap((void *)priv(dev)->plx9080_iobase);
 		}
+		if (priv(dev)->hpdi_iobase)
+			iounmap((void *)priv(dev)->hpdi_iobase);
+		/*  free pci dma buffers */
+		for (i = 0; i < NUM_DMA_BUFFERS; i++) {
+			if (priv(dev)->dio_buffer[i])
+				pci_free_consistent(priv(dev)->hw_dev,
+						    DMA_BUFFER_SIZE,
+						    priv(dev)->
+						    dio_buffer[i],
+						    priv
+						    (dev)->dio_buffer_phys_addr
+						    [i]);
+		}
+		/*  free dma descriptors */
+		if (priv(dev)->dma_desc)
+			pci_free_consistent(priv(dev)->hw_dev,
+					    sizeof(struct plx_dma_desc)
+					    * NUM_DMA_DESCRIPTORS,
+					    priv(dev)->dma_desc,
+					    priv(dev)->
+					    dma_desc_phys_addr);
+		if (priv(dev)->hpdi_phys_iobase)
+			comedi_pci_disable(priv(dev)->hw_dev);
+		pci_dev_put(priv(dev)->hw_dev);
 	}
 	return 0;
 }
@@ -810,15 +814,16 @@
 	if (err)
 		return 4;
 
-	if (cmd->chanlist) {
-		for (i = 1; i < cmd->chanlist_len; i++) {
-			if (CR_CHAN(cmd->chanlist[i]) != i) {
-				/*  XXX could support 8 channels or 16 channels */
-				comedi_error(dev,
-					     "chanlist must be channels 0 to 31 in order");
-				err++;
-				break;
-			}
+	if (!cmd->chanlist)
+		return 0;
+
+	for (i = 1; i < cmd->chanlist_len; i++) {
+		if (CR_CHAN(cmd->chanlist[i]) != i) {
+			/*  XXX could support 8 or 16 channels */
+			comedi_error(dev,
+				     "chanlist must be ch 0 to 31 in order");
+			err++;
+			break;
 		}
 	}
 
@@ -831,9 +836,9 @@
 static int hpdi_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
 			 struct comedi_cmd *cmd)
 {
-	if (priv(dev)->dio_config_output) {
+	if (priv(dev)->dio_config_output)
 		return -EINVAL;
-	} else
+	else
 		return di_cmd_test(dev, s, cmd);
 }
 
@@ -899,9 +904,9 @@
 
 static int hpdi_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
-	if (priv(dev)->dio_config_output) {
+	if (priv(dev)->dio_config_output)
 		return -EINVAL;
-	} else
+	else
 		return di_cmd(dev, s);
 }
 
@@ -963,14 +968,12 @@
 	uint8_t dma0_status, dma1_status;
 	unsigned long flags;
 
-	if (!dev->attached) {
+	if (!dev->attached)
 		return IRQ_NONE;
-	}
 
 	plx_status = readl(priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
-	if ((plx_status & (ICS_DMA0_A | ICS_DMA1_A | ICS_LIA)) == 0) {
+	if ((plx_status & (ICS_DMA0_A | ICS_DMA1_A | ICS_LIA)) == 0)
 		return IRQ_NONE;
-	}
 
 	hpdi_intr_status = readl(priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG);
 	hpdi_board_status = readl(priv(dev)->hpdi_iobase + BOARD_STATUS_REG);
@@ -990,9 +993,8 @@
 		       priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
 
 		DEBUG_PRINT("dma0 status 0x%x\n", dma0_status);
-		if (dma0_status & PLX_DMA_EN_BIT) {
+		if (dma0_status & PLX_DMA_EN_BIT)
 			drain_dma_buffers(dev, 0);
-		}
 		DEBUG_PRINT(" cleared dma ch0 interrupt\n");
 	}
 	spin_unlock_irqrestore(&dev->spinlock, flags);
@@ -1042,7 +1044,7 @@
 	return IRQ_HANDLED;
 }
 
-void abort_dma(struct comedi_device *dev, unsigned int channel)
+static void abort_dma(struct comedi_device *dev, unsigned int channel)
 {
 	unsigned long flags;
 
diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c
index 7a67fff..fa0e481 100644
--- a/drivers/staging/comedi/drivers/icp_multi.c
+++ b/drivers/staging/comedi/drivers/icp_multi.c
@@ -46,7 +46,7 @@
 
 Options:
  [0] - PCI bus number - if bus number and slot number are 0,
-                        then driver search for first unused card
+			then driver search for first unused card
  [1] - PCI slot number
 */
 
@@ -133,7 +133,7 @@
 	Data & Structure declarations
 ==============================================================================
 */
-static unsigned short pci_list_builded = 0;	/*>0 list of card is known */
+static unsigned short pci_list_builded;	/*>0 list of card is known */
 
 struct boardtype {
 	const char *name;	/*  driver name */
@@ -176,13 +176,13 @@
 #define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype))
 
 static struct comedi_driver driver_icp_multi = {
-driver_name:"icp_multi",
-module:THIS_MODULE,
-attach:icp_multi_attach,
-detach:icp_multi_detach,
-num_names:n_boardtypes,
-board_name:&boardtypes[0].name,
-offset:sizeof(struct boardtype),
+driver_name: "icp_multi",
+module : THIS_MODULE,
+attach : icp_multi_attach,
+detach : icp_multi_detach,
+num_names : n_boardtypes,
+board_name : &boardtypes[0].name,
+offset : sizeof(struct boardtype),
 };
 
 COMEDI_INITCLEANUP(driver_icp_multi);
@@ -234,18 +234,18 @@
 /*
 ==============================================================================
 
-	Name:	icp_multi_insn_read_ai
+Name:	icp_multi_insn_read_ai
 
-	Description:
-		This function reads a single analogue input.
+Description:
+	This function reads a single analogue input.
 
-	Parameters:
-		struct comedi_device *dev	Pointer to current device structure
-		struct comedi_subdevice *s	Pointer to current subdevice structure
-		struct comedi_insn *insn	Pointer to current comedi instruction
-		unsigned int *data		Pointer to analogue input data
+Parameters:
+	struct comedi_device *dev	Pointer to current device structure
+	struct comedi_subdevice *s	Pointer to current subdevice structure
+	struct comedi_insn *insn	Pointer to current comedi instruction
+	unsigned int *data		Pointer to analogue input data
 
-	Returns:int			Nmuber of instructions executed
+Returns:int			Nmuber of instructions executed
 
 ==============================================================================
 */
@@ -256,7 +256,7 @@
 	int n, timeout;
 
 #ifdef ICP_MULTI_EXTDEBUG
-	printk("icp multi EDBG: BGN: icp_multi_insn_read_ai(...)\n");
+	printk(KERN_DEBUG "icp multi EDBG: BGN: icp_multi_insn_read_ai(...)\n");
 #endif
 	/*  Disable A/D conversion ready interrupt */
 	devpriv->IntEnable &= ~ADC_READY;
@@ -266,11 +266,11 @@
 	devpriv->IntStatus |= ADC_READY;
 	writew(devpriv->IntStatus, devpriv->io_addr + ICP_MULTI_INT_STAT);
 
-	/*  Set up appropriate channel, mode and range data, for specified channel */
+	/*  Set up appropriate channel, mode and range data, for specified ch */
 	setup_channel_list(dev, s, &insn->chanspec, 1);
 
 #ifdef ICP_MULTI_EXTDEBUG
-	printk("icp_multi A ST=%4x IO=%p\n",
+	printk(KERN_DEBUG "icp_multi A ST=%4x IO=%p\n",
 	       readw(devpriv->io_addr + ICP_MULTI_ADC_CSR),
 	       devpriv->io_addr + ICP_MULTI_ADC_CSR);
 #endif
@@ -283,14 +283,14 @@
 		devpriv->AdcCmdStatus &= ~ADC_ST;
 
 #ifdef ICP_MULTI_EXTDEBUG
-		printk("icp multi B n=%d ST=%4x\n", n,
+		printk(KERN_DEBUG "icp multi B n=%d ST=%4x\n", n,
 		       readw(devpriv->io_addr + ICP_MULTI_ADC_CSR));
 #endif
 
 		udelay(1);
 
 #ifdef ICP_MULTI_EXTDEBUG
-		printk("icp multi C n=%d ST=%4x\n", n,
+		printk(KERN_DEBUG "icp multi C n=%d ST=%4x\n", n,
 		       readw(devpriv->io_addr + ICP_MULTI_ADC_CSR));
 #endif
 
@@ -303,7 +303,8 @@
 
 #ifdef ICP_MULTI_EXTDEBUG
 			if (!(timeout % 10))
-				printk("icp multi D n=%d tm=%d ST=%4x\n", n,
+				printk(KERN_DEBUG
+				       "icp multi D n=%d tm=%d ST=%4x\n", n,
 				       timeout,
 				       readw(devpriv->io_addr +
 					     ICP_MULTI_ADC_CSR));
@@ -328,9 +329,9 @@
 		data[n] = 0;
 
 #ifdef ICP_MULTI_EXTDEBUG
-		printk
-		    ("icp multi EDBG: END: icp_multi_insn_read_ai(...) n=%d\n",
-		     n);
+		printk(KERN_DEBUG
+		      "icp multi EDBG: END: icp_multi_insn_read_ai(...) n=%d\n",
+		      n);
 #endif
 		return -ETIME;
 
@@ -348,7 +349,8 @@
 	writew(devpriv->IntStatus, devpriv->io_addr + ICP_MULTI_INT_STAT);
 
 #ifdef ICP_MULTI_EXTDEBUG
-	printk("icp multi EDBG: END: icp_multi_insn_read_ai(...) n=%d\n", n);
+	printk(KERN_DEBUG
+	       "icp multi EDBG: END: icp_multi_insn_read_ai(...) n=%d\n", n);
 #endif
 	return n;
 }
@@ -356,18 +358,18 @@
 /*
 ==============================================================================
 
-	Name:	icp_multi_insn_write_ao
+Name:	icp_multi_insn_write_ao
 
-	Description:
-		This function writes a single analogue output.
+Description:
+	This function writes a single analogue output.
 
-	Parameters:
-		struct comedi_device *dev	Pointer to current device structure
-		struct comedi_subdevice *s	Pointer to current subdevice structure
-		struct comedi_insn *insn	Pointer to current comedi instruction
-		unsigned int *data		Pointer to analogue output data
+Parameters:
+	struct comedi_device *dev	Pointer to current device structure
+	struct comedi_subdevice *s	Pointer to current subdevice structure
+	struct comedi_insn *insn	Pointer to current comedi instruction
+	unsigned int *data		Pointer to analogue output data
 
-	Returns:int			Nmuber of instructions executed
+Returns:int			Nmuber of instructions executed
 
 ==============================================================================
 */
@@ -378,7 +380,8 @@
 	int n, chan, range, timeout;
 
 #ifdef ICP_MULTI_EXTDEBUG
-	printk("icp multi EDBG: BGN: icp_multi_insn_write_ao(...)\n");
+	printk(KERN_DEBUG
+	       "icp multi EDBG: BGN: icp_multi_insn_write_ao(...)\n");
 #endif
 	/*  Disable D/A conversion ready interrupt */
 	devpriv->IntEnable &= ~DAC_READY;
@@ -404,7 +407,8 @@
 	writew(devpriv->DacCmdStatus, devpriv->io_addr + ICP_MULTI_DAC_CSR);
 
 	for (n = 0; n < insn->n; n++) {
-		/*  Wait for analogue output data register to be ready for new data, or get fed up waiting */
+		/*  Wait for analogue output data register to be
+		 *  ready for new data, or get fed up waiting */
 		timeout = 100;
 		while (timeout--) {
 			if (!(readw(devpriv->io_addr +
@@ -413,7 +417,8 @@
 
 #ifdef ICP_MULTI_EXTDEBUG
 			if (!(timeout % 10))
-				printk("icp multi A n=%d tm=%d ST=%4x\n", n,
+				printk(KERN_DEBUG
+				       "icp multi A n=%d tm=%d ST=%4x\n", n,
 				       timeout,
 				       readw(devpriv->io_addr +
 					     ICP_MULTI_DAC_CSR));
@@ -438,8 +443,8 @@
 		devpriv->ao_data[chan] = 0;
 
 #ifdef ICP_MULTI_EXTDEBUG
-		printk
-		    ("icp multi EDBG: END: icp_multi_insn_write_ao(...) n=%d\n",
+		printk(KERN_DEBUG
+		     "icp multi EDBG: END: icp_multi_insn_write_ao(...) n=%d\n",
 		     n);
 #endif
 		return -ETIME;
@@ -459,7 +464,8 @@
 	}
 
 #ifdef ICP_MULTI_EXTDEBUG
-	printk("icp multi EDBG: END: icp_multi_insn_write_ao(...) n=%d\n", n);
+	printk(KERN_DEBUG
+	       "icp multi EDBG: END: icp_multi_insn_write_ao(...) n=%d\n", n);
 #endif
 	return n;
 }
@@ -467,18 +473,18 @@
 /*
 ==============================================================================
 
-	Name:	icp_multi_insn_read_ao
+Name:	icp_multi_insn_read_ao
 
-	Description:
-		This function reads a single analogue output.
+Description:
+	This function reads a single analogue output.
 
-	Parameters:
-		struct comedi_device *dev	Pointer to current device structure
-		struct comedi_subdevice *s	Pointer to current subdevice structure
-		struct comedi_insn *insn	Pointer to current comedi instruction
-		unsigned int *data		Pointer to analogue output data
+Parameters:
+	struct comedi_device *dev	Pointer to current device structure
+	struct comedi_subdevice *s	Pointer to current subdevice structure
+	struct comedi_insn *insn	Pointer to current comedi instruction
+	unsigned int *data		Pointer to analogue output data
 
-	Returns:int			Nmuber of instructions executed
+Returns:int			Nmuber of instructions executed
 
 ==============================================================================
 */
@@ -501,18 +507,18 @@
 /*
 ==============================================================================
 
-	Name:	icp_multi_insn_bits_di
+Name:	icp_multi_insn_bits_di
 
-	Description:
-		This function reads the digital inputs.
+Description:
+	This function reads the digital inputs.
 
-	Parameters:
-		struct comedi_device *dev	Pointer to current device structure
-		struct comedi_subdevice *s	Pointer to current subdevice structure
-		struct comedi_insn *insn	Pointer to current comedi instruction
-		unsigned int *data		Pointer to analogue output data
+Parameters:
+	struct comedi_device *dev	Pointer to current device structure
+	struct comedi_subdevice *s	Pointer to current subdevice structure
+	struct comedi_insn *insn	Pointer to current comedi instruction
+	unsigned int *data		Pointer to analogue output data
 
-	Returns:int			Nmuber of instructions executed
+Returns:int			Nmuber of instructions executed
 
 ==============================================================================
 */
@@ -528,18 +534,18 @@
 /*
 ==============================================================================
 
-	Name:	icp_multi_insn_bits_do
+Name:	icp_multi_insn_bits_do
 
-	Description:
-		This function writes the appropriate digital outputs.
+Description:
+	This function writes the appropriate digital outputs.
 
-	Parameters:
-		struct comedi_device *dev	Pointer to current device structure
-		struct comedi_subdevice *s	Pointer to current subdevice structure
-		struct comedi_insn *insn	Pointer to current comedi instruction
-		unsigned int *data		Pointer to analogue output data
+Parameters:
+	struct comedi_device *dev	Pointer to current device structure
+	struct comedi_subdevice *s	Pointer to current subdevice structure
+	struct comedi_insn *insn	Pointer to current comedi instruction
+	unsigned int *data		Pointer to analogue output data
 
-	Returns:int			Nmuber of instructions executed
+Returns:int			Nmuber of instructions executed
 
 ==============================================================================
 */
@@ -548,14 +554,14 @@
 				  struct comedi_insn *insn, unsigned int *data)
 {
 #ifdef ICP_MULTI_EXTDEBUG
-	printk("icp multi EDBG: BGN: icp_multi_insn_bits_do(...)\n");
+	printk(KERN_DEBUG "icp multi EDBG: BGN: icp_multi_insn_bits_do(...)\n");
 #endif
 
 	if (data[0]) {
 		s->state &= ~data[0];
 		s->state |= (data[0] & data[1]);
 
-		printk("Digital outputs = %4x \n", s->state);
+		printk(KERN_DEBUG "Digital outputs = %4x \n", s->state);
 
 		writew(s->state, devpriv->io_addr + ICP_MULTI_DO);
 	}
@@ -563,7 +569,7 @@
 	data[1] = readw(devpriv->io_addr + ICP_MULTI_DI);
 
 #ifdef ICP_MULTI_EXTDEBUG
-	printk("icp multi EDBG: END: icp_multi_insn_bits_do(...)\n");
+	printk(KERN_DEBUG "icp multi EDBG: END: icp_multi_insn_bits_do(...)\n");
 #endif
 	return 2;
 }
@@ -571,18 +577,18 @@
 /*
 ==============================================================================
 
-	Name:	icp_multi_insn_read_ctr
+Name:	icp_multi_insn_read_ctr
 
-	Description:
-		This function reads the specified counter.
+Description:
+	This function reads the specified counter.
 
-	Parameters:
-		struct comedi_device *dev	Pointer to current device structure
-		struct comedi_subdevice *s	Pointer to current subdevice structure
-		struct comedi_insn *insn	Pointer to current comedi instruction
-		unsigned int *data		Pointer to counter data
+Parameters:
+	struct comedi_device *dev	Pointer to current device structure
+	struct comedi_subdevice *s	Pointer to current subdevice structure
+	struct comedi_insn *insn	Pointer to current comedi instruction
+	unsigned int *data		Pointer to counter data
 
-	Returns:int			Nmuber of instructions executed
+Returns:int			Nmuber of instructions executed
 
 ==============================================================================
 */
@@ -596,18 +602,18 @@
 /*
 ==============================================================================
 
-	Name:	icp_multi_insn_write_ctr
+Name:	icp_multi_insn_write_ctr
 
-	Description:
-		This function write to the specified counter.
+Description:
+	This function write to the specified counter.
 
-	Parameters:
-		struct comedi_device *dev	Pointer to current device structure
-		struct comedi_subdevice *s	Pointer to current subdevice structure
-		struct comedi_insn *insn	Pointer to current comedi instruction
-		unsigned int *data		Pointer to counter data
+Parameters:
+	struct comedi_device *dev	Pointer to current device structure
+	struct comedi_subdevice *s	Pointer to current subdevice structure
+	struct comedi_insn *insn	Pointer to current comedi instruction
+	unsigned int *data		Pointer to counter data
 
-	Returns:int			Nmuber of instructions executed
+Returns:int			Nmuber of instructions executed
 
 ==============================================================================
 */
@@ -622,15 +628,15 @@
 /*
 ==============================================================================
 
-	Name:	interrupt_service_icp_multi
+Name:	interrupt_service_icp_multi
 
-	Description:
-		This function is the interrupt service routine for all
-		interrupts generated by the icp multi board.
+Description:
+	This function is the interrupt service routine for all
+	interrupts generated by the icp multi board.
 
-	Parameters:
-		int irq
-		void *d			Pointer to current device
+Parameters:
+	int irq
+	void *d			Pointer to current device
 
 ==============================================================================
 */
@@ -640,7 +646,8 @@
 	int int_no;
 
 #ifdef ICP_MULTI_EXTDEBUG
-	printk("icp multi EDBG: BGN: interrupt_service_icp_multi(%d,...)\n",
+	printk(KERN_DEBUG
+	       "icp multi EDBG: BGN: interrupt_service_icp_multi(%d,...)\n",
 	       irq);
 #endif
 
@@ -651,7 +658,8 @@
 		return IRQ_NONE;
 
 #ifdef ICP_MULTI_EXTDEBUG
-	printk("icp multi EDBG: interrupt_service_icp_multi() ST: %4x\n",
+	printk(KERN_DEBUG
+	       "icp multi EDBG: interrupt_service_icp_multi() ST: %4x\n",
 	       readw(devpriv->io_addr + ICP_MULTI_INT_STAT));
 #endif
 
@@ -679,7 +687,8 @@
 	}
 
 #ifdef ICP_MULTI_EXTDEBUG
-	printk("icp multi EDBG: END: interrupt_service_icp_multi(...)\n");
+	printk(KERN_DEBUG
+	       "icp multi EDBG: END: interrupt_service_icp_multi(...)\n");
 #endif
 	return IRQ_HANDLED;
 }
@@ -688,20 +697,20 @@
 /*
 ==============================================================================
 
-	Name:	check_channel_list
+Name:	check_channel_list
 
-	Description:
-		This function checks if the channel list, provided by user
-		is built correctly
+Description:
+	This function checks if the channel list, provided by user
+	is built correctly
 
-	Parameters:
-		struct comedi_device *dev	Pointer to current sevice structure
-		struct comedi_subdevice *s	Pointer to current subdevice structure
-		unsigned int *chanlist	Pointer to packed channel list
-		unsigned int n_chan	Number of channels to scan
+Parameters:
+	struct comedi_device *dev	Pointer to current sevice structure
+	struct comedi_subdevice *s	Pointer to current subdevice structure
+	unsigned int *chanlist	Pointer to packed channel list
+	unsigned int n_chan	Number of channels to scan
 
-	Returns:int 0 = failure
-		    1 = success
+Returns:int 0 = failure
+	    1 = success
 
 ==============================================================================
 */
@@ -712,7 +721,8 @@
 	unsigned int i;
 
 #ifdef ICP_MULTI_EXTDEBUG
-	printk("icp multi EDBG:  check_channel_list(...,%d)\n", n_chan);
+	printk(KERN_DEBUG
+	       "icp multi EDBG:  check_channel_list(...,%d)\n", n_chan);
 #endif
 	/*  Check that we at least have one channel to check */
 	if (n_chan < 1) {
@@ -725,7 +735,7 @@
 		if (CR_AREF(chanlist[i]) == AREF_DIFF) {
 			if (CR_CHAN(chanlist[i]) > this_board->n_aichand) {
 				comedi_error(dev,
-					     "Incorrect differential ai channel number");
+					     "Incorrect differential ai ch-nr");
 				return 0;
 			}
 		} else {
@@ -743,20 +753,20 @@
 /*
 ==============================================================================
 
-	Name:	setup_channel_list
+Name:	setup_channel_list
 
-	Description:
-		This function sets the appropriate channel selection,
-		differential input mode and range bits in the ADC Command/
-		Status register.
+Description:
+	This function sets the appropriate channel selection,
+	differential input mode and range bits in the ADC Command/
+	Status register.
 
-	Parameters:
-		struct comedi_device *dev	Pointer to current sevice structure
-		struct comedi_subdevice *s	Pointer to current subdevice structure
-		unsigned int *chanlist	Pointer to packed channel list
-		unsigned int n_chan	Number of channels to scan
+Parameters:
+	struct comedi_device *dev	Pointer to current sevice structure
+	struct comedi_subdevice *s	Pointer to current subdevice structure
+	unsigned int *chanlist	Pointer to packed channel list
+	unsigned int n_chan	Number of channels to scan
 
-	Returns:Void
+Returns:Void
 
 ==============================================================================
 */
@@ -768,7 +778,8 @@
 	unsigned int diff;
 
 #ifdef ICP_MULTI_EXTDEBUG
-	printk("icp multi EDBG:  setup_channel_list(...,%d)\n", n_chan);
+	printk(KERN_DEBUG
+	       "icp multi EDBG:  setup_channel_list(...,%d)\n", n_chan);
 #endif
 	devpriv->act_chanlist_len = n_chan;
 	devpriv->act_chanlist_pos = 0;
@@ -786,7 +797,8 @@
 			chanprog &= 0x000f;
 		}
 
-		/*  Clear channel, range and input mode bits in A/D command/status register */
+		/*  Clear channel, range and input mode bits
+		 *  in A/D command/status register */
 		devpriv->AdcCmdStatus &= 0xf00f;
 
 		/*  Set channel number and differential mode status bit */
@@ -808,7 +820,8 @@
 		       devpriv->io_addr + ICP_MULTI_ADC_CSR);
 
 #ifdef ICP_MULTI_EXTDEBUG
-		printk("GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range,
+		printk(KERN_DEBUG
+		       "GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range,
 		       devpriv->act_chanlist[i]);
 #endif
 	}
@@ -818,15 +831,15 @@
 /*
 ==============================================================================
 
-	Name:	icp_multi_reset
+Name:	icp_multi_reset
 
-	Description:
-		This function resets the icp multi device to a 'safe' state
+Description:
+	This function resets the icp multi device to a 'safe' state
 
-	Parameters:
-		struct comedi_device *dev	Pointer to current sevice structure
+Parameters:
+	struct comedi_device *dev	Pointer to current sevice structure
 
-	Returns:int	0 = success
+Returns:int	0 = success
 
 ==============================================================================
 */
@@ -835,7 +848,8 @@
 	unsigned int i;
 
 #ifdef ICP_MULTI_EXTDEBUG
-	printk("icp_multi EDBG: BGN: icp_multi_reset(...)\n");
+	printk(KERN_DEBUG
+	       "icp_multi EDBG: BGN: icp_multi_reset(...)\n");
 #endif
 	/*  Clear INT enables and requests */
 	writew(0, devpriv->io_addr + ICP_MULTI_INT_EN);
@@ -866,7 +880,8 @@
 	writew(0, devpriv->io_addr + ICP_MULTI_DO);
 
 #ifdef ICP_MULTI_EXTDEBUG
-	printk("icp multi EDBG: END: icp_multi_reset(...)\n");
+	printk(KERN_DEBUG
+	       "icp multi EDBG: END: icp_multi_reset(...)\n");
 #endif
 	return 0;
 }
@@ -874,17 +889,17 @@
 /*
 ==============================================================================
 
-	Name:	icp_multi_attach
+Name:	icp_multi_attach
 
-	Description:
-		This function sets up all the appropriate data for the current
-		device.
+Description:
+	This function sets up all the appropriate data for the current
+	device.
 
-	Parameters:
-		struct comedi_device *dev	Pointer to current device structure
-		struct comedi_devconfig *it	Pointer to current device configuration
+Parameters:
+	struct comedi_device *dev	Pointer to current device structure
+	struct comedi_devconfig *it	Pointer to current device configuration
 
-	Returns:int	0 = success
+Returns:int	0 = success
 
 ==============================================================================
 */
@@ -898,7 +913,8 @@
 	resource_size_t io_addr[5], iobase;
 	unsigned char pci_bus, pci_slot, pci_func;
 
-	printk("icp_multi EDBG: BGN: icp_multi_attach(...)\n");
+	printk(KERN_WARNING
+	       "icp_multi EDBG: BGN: icp_multi_attach(...)\n");
 
 	/*  Alocate private data storage space */
 	ret = alloc_private(dev, sizeof(struct icp_multi_private));
@@ -916,7 +932,8 @@
 		    );
 	}
 
-	printk("Anne's comedi%d: icp_multi: board=%s", dev->minor,
+	printk(KERN_WARNING
+	       "Anne's comedi%d: icp_multi: board=%s", dev->minor,
 	       this_board->name);
 
 	card = select_and_alloc_pci_card(PCI_VENDOR_ID_ICP,
@@ -930,24 +947,26 @@
 
 	if ((pci_card_data(card, &pci_bus, &pci_slot, &pci_func, &io_addr[0],
 			   &irq)) < 0) {
-		printk(" - Can't get configuration data!\n");
+		printk(KERN_WARNING " - Can't get configuration data!\n");
 		return -EIO;
 	}
 
 	iobase = io_addr[2];
 	devpriv->phys_iobase = iobase;
 
-	printk(", b:s:f=%d:%d:%d, io=0x%8llx \n", pci_bus, pci_slot, pci_func,
+	printk(KERN_WARNING
+	       ", b:s:f=%d:%d:%d, io=0x%8llx \n", pci_bus, pci_slot, pci_func,
 	       (unsigned long long)iobase);
 
 	devpriv->io_addr = ioremap(iobase, ICP_MULTI_SIZE);
 
 	if (devpriv->io_addr == NULL) {
-		printk("ioremap failed.\n");
+		printk(KERN_WARNING "ioremap failed.\n");
 		return -ENOMEM;
 	}
 #ifdef ICP_MULTI_EXTDEBUG
-	printk("0x%08llx mapped to %p, ", (unsigned long long)iobase,
+	printk(KERN_DEBUG
+	       "0x%08llx mapped to %p, ", (unsigned long long)iobase,
 	       devpriv->io_addr);
 #endif
 
@@ -975,20 +994,20 @@
 		if (irq) {
 			if (request_irq(irq, interrupt_service_icp_multi,
 					IRQF_SHARED, "Inova Icp Multi", dev)) {
-				printk
-				    (", unable to allocate IRQ %u, DISABLING IT",
+				printk(KERN_WARNING
+				    "unable to allocate IRQ %u, DISABLING IT",
 				     irq);
 				irq = 0;	/* Can't use IRQ */
 			} else
-				printk(", irq=%u", irq);
+				printk(KERN_WARNING ", irq=%u", irq);
 		} else
-			printk(", IRQ disabled");
+			printk(KERN_WARNING ", IRQ disabled");
 	} else
 		irq = 0;
 
 	dev->irq = irq;
 
-	printk(".\n");
+	printk(KERN_WARNING ".\n");
 
 	subdev = 0;
 
@@ -1063,7 +1082,7 @@
 	devpriv->valid = 1;
 
 #ifdef ICP_MULTI_EXTDEBUG
-	printk("icp multi EDBG: END: icp_multi_attach(...)\n");
+	printk(KERN_DEBUG "icp multi EDBG: END: icp_multi_attach(...)\n");
 #endif
 
 	return 0;
@@ -1072,16 +1091,16 @@
 /*
 ==============================================================================
 
-	Name:	icp_multi_detach
+Name:	icp_multi_detach
 
-	Description:
-		This function releases all the resources used by the current
-		device.
+Description:
+	This function releases all the resources used by the current
+	device.
 
-	Parameters:
-		struct comedi_device *dev	Pointer to current device structure
+Parameters:
+	struct comedi_device *dev	Pointer to current device structure
 
-	Returns:int	0 = success
+Returns:int	0 = success
 
 ==============================================================================
 */
diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c
index 24df245..e26c1b8 100644
--- a/drivers/staging/comedi/drivers/ii_pci20kc.c
+++ b/drivers/staging/comedi/drivers/ii_pci20kc.c
@@ -23,7 +23,8 @@
  *	no extern trigger implemented
  *
  *	NOT WORKING (but soon) only 4 on-board differential channels supported
- *	NOT WORKING (but soon) only ONE di-port and ONE do-port supported instead of 4 digital ports
+ *	NOT WORKING (but soon) only ONE di-port and ONE do-port supported
+ *			       instead of 4 digital ports
  *	di-port == Port 0
  *	do-port == Port 1
  *
@@ -63,17 +64,17 @@
 
 options for PCI-20006M:
   first:   Analog output channel 0 range configuration
-             0  bipolar 10  (-10V -- +10V)
-             1  unipolar 10  (0V -- +10V)
-             2  bipolar 5  (-5V -- 5V)
+	     0  bipolar 10  (-10V -- +10V)
+	     1  unipolar 10  (0V -- +10V)
+	     2  bipolar 5  (-5V -- 5V)
   second:  Analog output channel 1 range configuration
 
 options for PCI-20341M:
   first:   Analog input gain configuration
-             0  1
-             1  10
-             2  100
-             3  200
+	     0  1
+	     1  10
+	     2  100
+	     3  200
 */
 
 /* XXX needs to use ioremap() for compatibility with 2.4 kernels.  Should also
@@ -95,12 +96,12 @@
 #define PCI20000_DIO_3			0xc1
 #define PCI20000_DIO_CONTROL_01		0x83	/* port 0, 1 control */
 #define PCI20000_DIO_CONTROL_23		0xc3	/* port 2, 3 control */
-#define PCI20000_DIO_BUFFER		0x82	/* buffer direction and enable */
+#define PCI20000_DIO_BUFFER		0x82	/* buffer direction & enable */
 #define PCI20000_DIO_EOC		0xef	/* even port, control output */
 #define PCI20000_DIO_OOC		0xfd	/* odd port, control output */
 #define PCI20000_DIO_EIC		0x90	/* even port, control input */
 #define PCI20000_DIO_OIC		0x82	/* odd port, control input */
-#define DIO_CAND			0x12	/* and bit 1, bit 4 of control */
+#define DIO_CAND			0x12	/* and bit 1 & 4 of control */
 #define DIO_BE				0x01	/* buffer: port enable */
 #define DIO_BO				0x04	/* buffer: output */
 #define DIO_BI				0x05	/* buffer: input */
@@ -137,7 +138,8 @@
 	void *iobase;
 	struct {
 		void *iobase;
-		const struct comedi_lrange *ao_range_list[2];	/* range of channels of ao module */
+		const struct comedi_lrange *ao_range_list[2];
+					/* range of channels of ao module */
 		unsigned int last_data[2];
 	} pci20006;
 	struct {
@@ -224,14 +226,13 @@
 
 	/* Check PCI-20001 C-2A Carrier Board ID */
 	if ((readb(devpriv->ioaddr) & PCI20000_ID) != PCI20000_ID) {
-		printk("comedi%d: ii_pci20kc", dev->minor);
-		printk
-		    (" PCI-20001 C-2A Carrier Board at base=0x%p not found !\n",
-		     devpriv->ioaddr);
+		printk(KERN_WARNING "comedi%d: ii_pci20kc PCI-20001"
+		       " C-2A Carrier Board at base=0x%p not found !\n",
+		       dev->minor, devpriv->ioaddr);
 		return -EINVAL;
 	}
-	printk("comedi%d:\n", dev->minor);
-	printk("ii_pci20kc: PCI-20001 C-2A at base=0x%p\n", devpriv->ioaddr);
+	printk(KERN_INFO "comedi%d: ii_pci20kc: PCI-20001 C-2A at base=0x%p\n",
+	       dev->minor, devpriv->ioaddr);
 
 	for (i = 0; i < PCI20000_MODULES; i++) {
 		s = dev->subdevices + i;
@@ -244,21 +245,23 @@
 			    devpriv->ioaddr + (i + 1) * PCI20000_OFFSET;
 			pci20006_init(dev, s, it->options[2 * i + 2],
 				      it->options[2 * i + 3]);
-			printk("comedi%d: ii_pci20kc", dev->minor);
-			printk(" PCI-20006 module in slot %d \n", i + 1);
+			printk(KERN_INFO "comedi%d: "
+			       "ii_pci20kc PCI-20006 module in slot %d \n",
+			       dev->minor, i + 1);
 			break;
 		case PCI20341_ID:
 			sdp->pci20341.iobase =
 			    devpriv->ioaddr + (i + 1) * PCI20000_OFFSET;
 			pci20341_init(dev, s, it->options[2 * i + 2],
 				      it->options[2 * i + 3]);
-			printk("comedi%d: ii_pci20kc", dev->minor);
-			printk(" PCI-20341 module in slot %d \n", i + 1);
+			printk(KERN_INFO "comedi%d: "
+			       "ii_pci20kc PCI-20341 module in slot %d \n",
+			       dev->minor, i + 1);
 			break;
 		default:
-			printk
-			    ("ii_pci20kc: unknown module code 0x%02x in slot %d: module disabled\n",
-			     id, i);
+			printk(KERN_WARNING "ii_pci20kc: unknown module "
+			       "code 0x%02x in slot %d: module disabled\n",
+			       id, i); /* XXX this looks like a bug! i + 1 ?? */
 			/* fall through */
 		case PCI20xxx_EMPTY_ID:
 			s->type = COMEDI_SUBD_UNUSED;
@@ -274,7 +277,7 @@
 
 static int pci20xxx_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: pci20xxx: remove\n", dev->minor);
+	printk(KERN_INFO "comedi%d: pci20xxx: remove\n", dev->minor);
 
 	return 0;
 }
@@ -339,7 +342,8 @@
 	unsigned int boarddata;
 
 	sdp->pci20006.last_data[CR_CHAN(insn->chanspec)] = data[0];
-	boarddata = (((unsigned int)data[0] + 0x8000) & 0xffff);	/* comedi-data -> board-data */
+	boarddata = (((unsigned int)data[0] + 0x8000) & 0xffff);
+						/* comedi-data -> board-data */
 	lo = (boarddata & 0xff);
 	hi = ((boarddata >> 8) & 0xff);
 
@@ -355,7 +359,8 @@
 		writeb(0x00, sdp->iobase + PCI20006_STROBE1);
 		break;
 	default:
-		printk(" comedi%d: pci20xxx: ao channel Error!\n", dev->minor);
+		printk(KERN_WARNING
+		       " comedi%d: pci20xxx: ao channel Error!\n", dev->minor);
 		return -EINVAL;
 	}
 
@@ -373,8 +378,7 @@
 
 static const struct comedi_lrange range_bipolar0_5 = { 1, {BIP_RANGE(0.5)} };
 static const struct comedi_lrange range_bipolar0_05 = { 1, {BIP_RANGE(0.05)} };
-static const struct comedi_lrange range_bipolar0_025 =
-    { 1, {BIP_RANGE(0.025)} };
+static const struct comedi_lrange range_bipolar0_025 = { 1, {BIP_RANGE(0.025)} };
 
 static const struct comedi_lrange *const pci20341_ranges[] = {
 	&range_bipolar5,
@@ -447,9 +451,10 @@
 			eoc = readb(sdp->iobase + PCI20341_STATUS_REG);
 		}
 		if (j >= 100) {
-			printk
-			    ("comedi%d:  pci20xxx: AI interrupt channel %i polling exit !\n",
-			     dev->minor, i);
+			printk(KERN_WARNING
+			       "comedi%d:  pci20xxx: "
+			       "AI interrupt channel %i polling exit !\n",
+			       dev->minor, i);
 			return -EINVAL;
 		}
 		lo = readb(sdp->iobase + PCI20341_LDATA);
@@ -502,20 +507,18 @@
 	int mask, bits;
 
 	mask = 1 << CR_CHAN(insn->chanspec);
-	if (mask & 0x000000ff) {
+	if (mask & 0x000000ff)
 		bits = 0x000000ff;
-	} else if (mask & 0x0000ff00) {
+	else if (mask & 0x0000ff00)
 		bits = 0x0000ff00;
-	} else if (mask & 0x00ff0000) {
+	else if (mask & 0x00ff0000)
 		bits = 0x00ff0000;
-	} else {
+	else
 		bits = 0xff000000;
-	}
-	if (data[0]) {
+	if (data[0])
 		s->io_bits |= bits;
-	} else {
+	else
 		s->io_bits &= ~bits;
-	}
 	pci20xxx_dio_config(dev, s);
 
 	return 1;
diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c
index c145e82..73b0445 100644
--- a/drivers/staging/comedi/drivers/ke_counter.c
+++ b/drivers/staging/comedi/drivers/ke_counter.c
@@ -192,12 +192,14 @@
 			}
 		}
 	}
-	printk("comedi%d: no supported board found! (req. bus/slot: %d/%d)\n",
+	printk(KERN_WARNING
+	       "comedi%d: no supported board found! (req. bus/slot: %d/%d)\n",
 	       dev->minor, it->options[0], it->options[1]);
 	return -EIO;
 
 found:
-	printk("comedi%d: found %s at PCI bus %d, slot %d\n", dev->minor,
+	printk(KERN_INFO
+	       "comedi%d: found %s at PCI bus %d, slot %d\n", dev->minor,
 	       board->name, pci_device->bus->number,
 	       PCI_SLOT(pci_device->devfn));
 	devpriv->pcidev = pci_device;
@@ -206,9 +208,9 @@
 	/* enable PCI device and request regions */
 	error = comedi_pci_enable(pci_device, CNT_DRIVER_NAME);
 	if (error < 0) {
-		printk
-		    ("comedi%d: failed to enable PCI device and request regions!\n",
-		     dev->minor);
+		printk(KERN_WARNING "comedi%d: "
+		       "failed to enable PCI device and request regions!\n",
+		       dev->minor);
 		return error;
 	}
 
@@ -239,7 +241,8 @@
 	outb(0, dev->iobase + 0x20);
 	outb(0, dev->iobase + 0x40);
 
-	printk("comedi%d: " CNT_DRIVER_NAME " attached.\n", dev->minor);
+	printk(KERN_INFO "comedi%d: " CNT_DRIVER_NAME " attached.\n",
+	       dev->minor);
 	return 0;
 }
 
@@ -248,11 +251,11 @@
 static int cnt_detach(struct comedi_device *dev)
 {
 	if (devpriv && devpriv->pcidev) {
-		if (dev->iobase) {
+		if (dev->iobase)
 			comedi_pci_disable(devpriv->pcidev);
-		}
 		pci_dev_put(devpriv->pcidev);
 	}
-	printk("comedi%d: " CNT_DRIVER_NAME " remove\n", dev->minor);
+	printk(KERN_INFO "comedi%d: " CNT_DRIVER_NAME " remove\n",
+	       dev->minor);
 	return 0;
 }
diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c
index 6079913..8b9fa0f 100644
--- a/drivers/staging/comedi/drivers/me4000.c
+++ b/drivers/staging/comedi/drivers/me4000.c
@@ -840,7 +840,7 @@
 		       "comedi%d: me4000: xilinx_download(): DONE flag is not set\n",
 		       dev->minor);
 		printk(KERN_ERR
-		       "comedi%d: me4000: xilinx_download(): Download not succesful\n",
+		       "comedi%d: me4000: xilinx_download(): Download not successful\n",
 		       dev->minor);
 		return -EIO;
 	}
diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c
index e652f3b..188f580 100644
--- a/drivers/staging/comedi/drivers/mite.c
+++ b/drivers/staging/comedi/drivers/mite.c
@@ -64,6 +64,7 @@
 MODULE_LICENSE("GPL");
 
 struct mite_struct *mite_devices;
+EXPORT_SYMBOL(mite_devices);
 
 #define TOP_OF_PAGE(x) ((x)|(~(PAGE_MASK)))
 
@@ -80,7 +81,7 @@
 
 			mite = kzalloc(sizeof(*mite), GFP_KERNEL);
 			if (!mite) {
-				printk("mite: allocation failed\n");
+				printk(KERN_ERR "mite: allocation failed\n");
 				pci_dev_put(pcidev);
 				return;
 			}
@@ -99,14 +100,14 @@
 
 static void dump_chip_signature(u32 csigr_bits)
 {
-	printk
-	    ("mite: version = %i, type = %i, mite mode = %i, interface mode = %i\n",
-	     mite_csigr_version(csigr_bits), mite_csigr_type(csigr_bits),
-	     mite_csigr_mmode(csigr_bits), mite_csigr_imode(csigr_bits));
-	printk
-	    ("mite: num channels = %i, write post fifo depth = %i, wins = %i, iowins = %i\n",
-	     mite_csigr_dmac(csigr_bits), mite_csigr_wpdep(csigr_bits),
-	     mite_csigr_wins(csigr_bits), mite_csigr_iowins(csigr_bits));
+	printk(KERN_INFO "mite: version = %i, type = %i, mite mode = %i,"
+	       "interface mode = %i\n",
+	       mite_csigr_version(csigr_bits), mite_csigr_type(csigr_bits),
+	       mite_csigr_mmode(csigr_bits), mite_csigr_imode(csigr_bits));
+	printk(KERN_INFO "mite: num channels = %i, write post fifo depth = %i,"
+	       "wins = %i, iowins = %i\n",
+	       mite_csigr_dmac(csigr_bits), mite_csigr_wpdep(csigr_bits),
+	       mite_csigr_wins(csigr_bits), mite_csigr_iowins(csigr_bits));
 }
 
 unsigned mite_fifo_size(struct mite_struct *mite, unsigned channel)
@@ -126,7 +127,7 @@
 	unsigned unknown_dma_burst_bits;
 
 	if (comedi_pci_enable(mite->pcidev, "mite")) {
-		printk("error enabling mite and requesting io regions\n");
+		printk(KERN_ERR "error enabling mite and requesting io regions\n");
 		return -EIO;
 	}
 	pci_set_master(mite->pcidev);
@@ -135,27 +136,30 @@
 	mite->mite_phys_addr = addr;
 	mite->mite_io_addr = ioremap(addr, PCI_MITE_SIZE);
 	if (!mite->mite_io_addr) {
-		printk("failed to remap mite io memory address\n");
+		printk(KERN_ERR "Failed to remap mite io memory address\n");
 		return -ENOMEM;
 	}
-	printk("MITE:0x%08llx mapped to %p ",
+	printk(KERN_INFO "MITE:0x%08llx mapped to %p ",
 	       (unsigned long long)mite->mite_phys_addr, mite->mite_io_addr);
 
 	addr = pci_resource_start(mite->pcidev, 1);
 	mite->daq_phys_addr = addr;
 	length = pci_resource_len(mite->pcidev, 1);
-	/*  In case of a 660x board, DAQ size is 8k instead of 4k (see as shown by lspci output) */
+	/*
+	 * In case of a 660x board, DAQ size is 8k instead of 4k
+	 * (see as shown by lspci output)
+	 */
 	mite->daq_io_addr = ioremap(mite->daq_phys_addr, length);
 	if (!mite->daq_io_addr) {
-		printk("failed to remap daq io memory address\n");
+		printk(KERN_ERR "Failed to remap daq io memory address\n");
 		return -ENOMEM;
 	}
-	printk("DAQ:0x%08llx mapped to %p\n",
+	printk(KERN_INFO "DAQ:0x%08llx mapped to %p\n",
 	       (unsigned long long)mite->daq_phys_addr, mite->daq_io_addr);
 
 	if (use_iodwbsr_1) {
 		writel(0, mite->mite_io_addr + MITE_IODWBSR);
-		printk("mite: using I/O Window Base Size register 1\n");
+		printk(KERN_INFO "mite: using I/O Window Base Size register 1\n");
 		writel(mite->daq_phys_addr | WENAB |
 		       MITE_IODWBSR_1_WSIZE_bits(length),
 		       mite->mite_io_addr + MITE_IODWBSR_1);
@@ -164,11 +168,12 @@
 		writel(mite->daq_phys_addr | WENAB,
 		       mite->mite_io_addr + MITE_IODWBSR);
 	}
-	/* make sure dma bursts work.  I got this from running a bus analyzer
-	   on a pxi-6281 and a pxi-6713.  6713 powered up with register value
-	   of 0x61f and bursts worked.  6281 powered up with register value of
-	   0x1f and bursts didn't work.  The NI windows driver reads the register,
-	   then does a bitwise-or of 0x600 with it and writes it back.
+	/*
+	 * make sure dma bursts work. I got this from running a bus analyzer
+	 * on a pxi-6281 and a pxi-6713. 6713 powered up with register value
+	 * of 0x61f and bursts worked. 6281 powered up with register value of
+	 * 0x1f and bursts didn't work. The NI windows driver reads the
+	 * register, then does a bitwise-or of 0x600 with it and writes it back.
 	 */
 	unknown_dma_burst_bits =
 	    readl(mite->mite_io_addr + MITE_UNKNOWN_DMA_BURST_REG);
@@ -179,9 +184,9 @@
 	csigr_bits = readl(mite->mite_io_addr + MITE_CSIGR);
 	mite->num_channels = mite_csigr_dmac(csigr_bits);
 	if (mite->num_channels > MAX_MITE_DMA_CHANNELS) {
-		printk
-		    ("mite: bug? chip claims to have %i dma channels.  Setting to %i.\n",
-		     mite->num_channels, MAX_MITE_DMA_CHANNELS);
+		printk(KERN_WARNING "mite: bug? chip claims to have %i dma "
+		       "channels. Setting to %i.\n",
+		       mite->num_channels, MAX_MITE_DMA_CHANNELS);
 		mite->num_channels = MAX_MITE_DMA_CHANNELS;
 	}
 	dump_chip_signature(csigr_bits);
@@ -194,16 +199,18 @@
 		       mite->mite_io_addr + MITE_CHCR(i));
 	}
 	mite->fifo_size = mite_fifo_size(mite, 0);
-	printk("mite: fifo size is %i.\n", mite->fifo_size);
+	printk(KERN_INFO "mite: fifo size is %i.\n", mite->fifo_size);
 	mite->used = 1;
 
 	return 0;
 }
+EXPORT_SYMBOL(mite_setup2);
 
 int mite_setup(struct mite_struct *mite)
 {
 	return mite_setup2(mite, 0);
 }
+EXPORT_SYMBOL(mite_setup);
 
 void mite_cleanup(void)
 {
@@ -238,22 +245,23 @@
 
 	mite->used = 0;
 }
+EXPORT_SYMBOL(mite_unsetup);
 
 void mite_list_devices(void)
 {
 	struct mite_struct *mite, *next;
 
-	printk("Available NI device IDs:");
+	printk(KERN_INFO "Available NI device IDs:");
 	if (mite_devices)
 		for (mite = mite_devices; mite; mite = next) {
 			next = mite->next;
-			printk(" 0x%04x", mite_device_id(mite));
+			printk(KERN_INFO " 0x%04x", mite_device_id(mite));
 			if (mite->used)
-				printk("(used)");
+				printk(KERN_INFO "(used)");
 		}
-	printk("\n");
-
+	printk(KERN_INFO "\n");
 }
+EXPORT_SYMBOL(mite_list_devices);
 
 struct mite_channel *mite_request_channel_in_range(struct mite_struct *mite,
 						   struct
@@ -265,7 +273,9 @@
 	unsigned long flags;
 	struct mite_channel *channel = NULL;
 
-	/*  spin lock so mite_release_channel can be called safely from interrupts */
+	/* spin lock so mite_release_channel can be called safely
+	 * from interrupts
+	 */
 	spin_lock_irqsave(&mite->lock, flags);
 	for (i = min_channel; i <= max_channel; ++i) {
 		if (mite->channel_allocated[i] == 0) {
@@ -278,6 +288,7 @@
 	spin_unlock_irqrestore(&mite->lock, flags);
 	return channel;
 }
+EXPORT_SYMBOL(mite_request_channel_in_range);
 
 void mite_release_channel(struct mite_channel *mite_chan)
 {
@@ -289,8 +300,10 @@
 	if (mite->channel_allocated[mite_chan->channel]) {
 		mite_dma_disarm(mite_chan);
 		mite_dma_reset(mite_chan);
-/* disable all channel's interrupts (do it after disarm/reset so
-MITE_CHCR reg isn't changed while dma is still active!) */
+	/*
+	 * disable all channel's interrupts (do it after disarm/reset so
+	 * MITE_CHCR reg isn't changed while dma is still active!)
+	 */
 		writel(CHCR_CLR_DMA_IE | CHCR_CLR_LINKP_IE |
 		       CHCR_CLR_SAR_IE | CHCR_CLR_DONE_IE |
 		       CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE |
@@ -302,6 +315,7 @@
 	}
 	spin_unlock_irqrestore(&mite->lock, flags);
 }
+EXPORT_SYMBOL(mite_release_channel);
 
 void mite_dma_arm(struct mite_channel *mite_chan)
 {
@@ -310,8 +324,10 @@
 	unsigned long flags;
 
 	MDPRINTK("mite_dma_arm ch%i\n", channel);
-	/* memory barrier is intended to insure any twiddling with the buffer
-	   is done before writing to the mite to arm dma transfer */
+	/*
+	 * memory barrier is intended to insure any twiddling with the buffer
+	 * is done before writing to the mite to arm dma transfer
+	 */
 	smp_mb();
 	/* arm */
 	chor = CHOR_START;
@@ -322,6 +338,7 @@
 	spin_unlock_irqrestore(&mite->lock, flags);
 /*       mite_dma_tcr(mite, channel); */
 }
+EXPORT_SYMBOL(mite_dma_arm);
 
 /**************************************/
 
@@ -354,7 +371,7 @@
 			       n_links * sizeof(struct mite_dma_descriptor),
 			       &ring->descriptors_dma_addr, GFP_KERNEL);
 	if (!ring->descriptors) {
-		printk("mite: ring buffer allocation failed\n");
+		printk(KERN_ERR "mite: ring buffer allocation failed\n");
 		return -ENOMEM;
 	}
 	ring->n_links = n_links;
@@ -370,11 +387,14 @@
 	}
 	ring->descriptors[n_links - 1].next =
 	    cpu_to_le32(ring->descriptors_dma_addr);
-	/* barrier is meant to insure that all the writes to the dma descriptors
-	   have completed before the dma controller is commanded to read them */
+	/*
+	 * barrier is meant to insure that all the writes to the dma descriptors
+	 * have completed before the dma controller is commanded to read them
+	 */
 	smp_wmb();
 	return 0;
 }
+EXPORT_SYMBOL(mite_buf_change);
 
 void mite_prep_dma(struct mite_channel *mite_chan,
 		   unsigned int num_device_bits, unsigned int num_memory_bits)
@@ -395,16 +415,19 @@
 	 * Link Complete Interrupt: interrupt every time a link
 	 * in MITE_RING is completed. This can generate a lot of
 	 * extra interrupts, but right now we update the values
-	 * of buf_int_ptr and buf_int_count at each interrupt.  A
+	 * of buf_int_ptr and buf_int_count at each interrupt. A
 	 * better method is to poll the MITE before each user
 	 * "read()" to calculate the number of bytes available.
 	 */
 	chcr |= CHCR_SET_LC_IE;
 	if (num_memory_bits == 32 && num_device_bits == 16) {
-		/* Doing a combined 32 and 16 bit byteswap gets the 16 bit samples into the fifo in the right order.
-		   Tested doing 32 bit memory to 16 bit device transfers to the analog out of a pxi-6281,
-		   which has mite version = 1, type = 4.  This also works for dma reads from the counters
-		   on e-series boards.  */
+		/*
+		 * Doing a combined 32 and 16 bit byteswap gets the 16 bit
+		 * samples into the fifo in the right order. Tested doing 32 bit
+		 * memory to 16 bit device transfers to the analog out of a
+		 * pxi-6281, which has mite version = 1, type = 4. This also
+		 * works for dma reads from the counters on e-series boards.
+		 */
 		chcr |= CHCR_BYTE_SWAP_DEVICE | CHCR_BYTE_SWAP_MEMORY;
 	}
 	if (mite_chan->dir == COMEDI_INPUT)
@@ -425,7 +448,8 @@
 		mcr |= CR_PSIZE32;
 		break;
 	default:
-		printk("mite: bug! invalid mem bit width for dma transfer\n");
+		printk(KERN_WARNING "mite: bug! invalid mem bit width for dma "
+		       "transfer\n");
 		break;
 	}
 	writel(mcr, mite->mite_io_addr + MITE_MCR(mite_chan->channel));
@@ -444,7 +468,8 @@
 		dcr |= CR_PSIZE32;
 		break;
 	default:
-		printk("mite: bug! invalid dev bit width for dma transfer\n");
+		printk(KERN_WARNING "mite: bug! invalid dev bit width for dma "
+		       "transfer\n");
 		break;
 	}
 	writel(dcr, mite->mite_io_addr + MITE_DCR(mite_chan->channel));
@@ -462,6 +487,7 @@
 
 	MDPRINTK("exit mite_prep_dma\n");
 }
+EXPORT_SYMBOL(mite_prep_dma);
 
 u32 mite_device_bytes_transferred(struct mite_channel *mite_chan)
 {
@@ -469,48 +495,53 @@
 	return readl(mite->mite_io_addr + MITE_DAR(mite_chan->channel));
 }
 
-u32 mite_bytes_in_transit(struct mite_channel * mite_chan)
+u32 mite_bytes_in_transit(struct mite_channel *mite_chan)
 {
 	struct mite_struct *mite = mite_chan->mite;
 	return readl(mite->mite_io_addr +
 		     MITE_FCR(mite_chan->channel)) & 0x000000FF;
 }
+EXPORT_SYMBOL(mite_bytes_in_transit);
 
-/*  returns lower bound for number of bytes transferred from device to memory */
-u32 mite_bytes_written_to_memory_lb(struct mite_channel * mite_chan)
+/* returns lower bound for number of bytes transferred from device to memory */
+u32 mite_bytes_written_to_memory_lb(struct mite_channel *mite_chan)
 {
 	u32 device_byte_count;
 
 	device_byte_count = mite_device_bytes_transferred(mite_chan);
 	return device_byte_count - mite_bytes_in_transit(mite_chan);
 }
+EXPORT_SYMBOL(mite_bytes_written_to_memory_lb);
 
-/*  returns upper bound for number of bytes transferred from device to memory */
-u32 mite_bytes_written_to_memory_ub(struct mite_channel * mite_chan)
+/* returns upper bound for number of bytes transferred from device to memory */
+u32 mite_bytes_written_to_memory_ub(struct mite_channel *mite_chan)
 {
 	u32 in_transit_count;
 
 	in_transit_count = mite_bytes_in_transit(mite_chan);
 	return mite_device_bytes_transferred(mite_chan) - in_transit_count;
 }
+EXPORT_SYMBOL(mite_bytes_written_to_memory_ub);
 
-/*  returns lower bound for number of bytes read from memory for transfer to device */
-u32 mite_bytes_read_from_memory_lb(struct mite_channel * mite_chan)
+/* returns lower bound for number of bytes read from memory to device */
+u32 mite_bytes_read_from_memory_lb(struct mite_channel *mite_chan)
 {
 	u32 device_byte_count;
 
 	device_byte_count = mite_device_bytes_transferred(mite_chan);
 	return device_byte_count + mite_bytes_in_transit(mite_chan);
 }
+EXPORT_SYMBOL(mite_bytes_read_from_memory_lb);
 
-/*  returns upper bound for number of bytes read from memory for transfer to device */
-u32 mite_bytes_read_from_memory_ub(struct mite_channel * mite_chan)
+/* returns upper bound for number of bytes read from memory to device */
+u32 mite_bytes_read_from_memory_ub(struct mite_channel *mite_chan)
 {
 	u32 in_transit_count;
 
 	in_transit_count = mite_bytes_in_transit(mite_chan);
 	return mite_device_bytes_transferred(mite_chan) + in_transit_count;
 }
+EXPORT_SYMBOL(mite_bytes_read_from_memory_ub);
 
 unsigned mite_dma_tcr(struct mite_channel *mite_chan)
 {
@@ -525,6 +556,7 @@
 
 	return tcr;
 }
+EXPORT_SYMBOL(mite_dma_tcr);
 
 void mite_dma_disarm(struct mite_channel *mite_chan)
 {
@@ -535,6 +567,7 @@
 	chor = CHOR_ABORT;
 	writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
 }
+EXPORT_SYMBOL(mite_dma_disarm);
 
 int mite_sync_input_dma(struct mite_channel *mite_chan,
 			struct comedi_async *async)
@@ -544,7 +577,7 @@
 	const unsigned bytes_per_scan = cfc_bytes_per_scan(async->subdevice);
 
 	old_alloc_count = async->buf_write_alloc_count;
-	/*  write alloc as much as we can */
+	/* write alloc as much as we can */
 	comedi_buf_write_alloc(async, async->prealloc_bufsz);
 
 	nbytes = mite_bytes_written_to_memory_lb(mite_chan);
@@ -571,6 +604,7 @@
 	async->events |= COMEDI_CB_BLOCK;
 	return 0;
 }
+EXPORT_SYMBOL(mite_sync_input_dma);
 
 int mite_sync_output_dma(struct mite_channel *mite_chan,
 			 struct comedi_async *async)
@@ -593,7 +627,7 @@
 	    (int)(nbytes_ub - stop_count) > 0)
 		nbytes_ub = stop_count;
 	if ((int)(nbytes_ub - old_alloc_count) > 0) {
-		printk("mite: DMA underrun\n");
+		printk(KERN_ERR "mite: DMA underrun\n");
 		async->events |= COMEDI_CB_OVERFLOW;
 		return -1;
 	}
@@ -607,6 +641,7 @@
 	}
 	return 0;
 }
+EXPORT_SYMBOL(mite_sync_output_dma);
 
 unsigned mite_get_status(struct mite_channel *mite_chan)
 {
@@ -625,6 +660,7 @@
 	spin_unlock_irqrestore(&mite->lock, flags);
 	return status;
 }
+EXPORT_SYMBOL(mite_get_status);
 
 int mite_done(struct mite_channel *mite_chan)
 {
@@ -638,6 +674,7 @@
 	spin_unlock_irqrestore(&mite->lock, flags);
 	return done;
 }
+EXPORT_SYMBOL(mite_done);
 
 #ifdef DEBUG_MITE
 
@@ -719,46 +756,51 @@
 	unsigned long addr = 0;
 	unsigned long temp = 0;
 
-	printk("mite_dump_regs ch%i\n", mite_chan->channel);
-	printk("mite address is  =0x%08lx\n", mite_io_addr);
+	printk(KERN_DEBUG "mite_dump_regs ch%i\n", mite_chan->channel);
+	printk(KERN_DEBUG "mite address is  =0x%08lx\n", mite_io_addr);
 
 	addr = mite_io_addr + MITE_CHOR(channel);
-	printk("mite status[CHOR]at 0x%08lx =0x%08lx\n", addr, temp =
-	       readl(addr));
+	printk(KERN_DEBUG "mite status[CHOR]at 0x%08lx =0x%08lx\n", addr,
+	       temp = readl(addr));
 	mite_decode(mite_CHOR_strings, temp);
 	addr = mite_io_addr + MITE_CHCR(channel);
-	printk("mite status[CHCR]at 0x%08lx =0x%08lx\n", addr, temp =
-	       readl(addr));
+	printk(KERN_DEBUG "mite status[CHCR]at 0x%08lx =0x%08lx\n", addr,
+	       temp = readl(addr));
 	mite_decode(mite_CHCR_strings, temp);
 	addr = mite_io_addr + MITE_TCR(channel);
-	printk("mite status[TCR] at 0x%08lx =0x%08x\n", addr, readl(addr));
-	addr = mite_io_addr + MITE_MCR(channel);
-	printk("mite status[MCR] at 0x%08lx =0x%08lx\n", addr, temp =
+	printk(KERN_DEBUG "mite status[TCR] at 0x%08lx =0x%08x\n", addr,
 	       readl(addr));
+	addr = mite_io_addr + MITE_MCR(channel);
+	printk(KERN_DEBUG "mite status[MCR] at 0x%08lx =0x%08lx\n", addr,
+	       temp = readl(addr));
 	mite_decode(mite_MCR_strings, temp);
 
 	addr = mite_io_addr + MITE_MAR(channel);
-	printk("mite status[MAR] at 0x%08lx =0x%08x\n", addr, readl(addr));
-	addr = mite_io_addr + MITE_DCR(channel);
-	printk("mite status[DCR] at 0x%08lx =0x%08lx\n", addr, temp =
+	printk(KERN_DEBUG "mite status[MAR] at 0x%08lx =0x%08x\n", addr,
 	       readl(addr));
+	addr = mite_io_addr + MITE_DCR(channel);
+	printk(KERN_DEBUG "mite status[DCR] at 0x%08lx =0x%08lx\n", addr,
+	       temp = readl(addr));
 	mite_decode(mite_DCR_strings, temp);
 	addr = mite_io_addr + MITE_DAR(channel);
-	printk("mite status[DAR] at 0x%08lx =0x%08x\n", addr, readl(addr));
-	addr = mite_io_addr + MITE_LKCR(channel);
-	printk("mite status[LKCR]at 0x%08lx =0x%08lx\n", addr, temp =
+	printk(KERN_DEBUG "mite status[DAR] at 0x%08lx =0x%08x\n", addr,
 	       readl(addr));
+	addr = mite_io_addr + MITE_LKCR(channel);
+	printk(KERN_DEBUG "mite status[LKCR]at 0x%08lx =0x%08lx\n", addr,
+	       temp = readl(addr));
 	mite_decode(mite_LKCR_strings, temp);
 	addr = mite_io_addr + MITE_LKAR(channel);
-	printk("mite status[LKAR]at 0x%08lx =0x%08x\n", addr, readl(addr));
-
-	addr = mite_io_addr + MITE_CHSR(channel);
-	printk("mite status[CHSR]at 0x%08lx =0x%08lx\n", addr, temp =
+	printk(KERN_DEBUG "mite status[LKAR]at 0x%08lx =0x%08x\n", addr,
 	       readl(addr));
+	addr = mite_io_addr + MITE_CHSR(channel);
+	printk(KERN_DEBUG "mite status[CHSR]at 0x%08lx =0x%08lx\n", addr,
+	       temp = readl(addr));
 	mite_decode(mite_CHSR_strings, temp);
 	addr = mite_io_addr + MITE_FCR(channel);
-	printk("mite status[FCR] at 0x%08lx =0x%08x\n\n", addr, readl(addr));
+	printk(KERN_DEBUG "mite status[FCR] at 0x%08lx =0x%08x\n\n", addr,
+	       readl(addr));
 }
+EXPORT_SYMBOL(mite_dump_regs);
 
 static void mite_decode(char **bit_str, unsigned int bits)
 {
@@ -766,10 +808,11 @@
 
 	for (i = 31; i >= 0; i--) {
 		if (bits & (1 << i))
-			printk(" %s", bit_str[i]);
+			printk(KERN_DEBUG " %s", bit_str[i]);
 	}
-	printk("\n");
+	printk(KERN_DEBUG "\n");
 }
+EXPORT_SYMBOL(mite_decode);
 #endif
 
 #ifdef MODULE
@@ -785,36 +828,4 @@
 {
 	mite_cleanup();
 }
-
-EXPORT_SYMBOL(mite_dma_tcr);
-EXPORT_SYMBOL(mite_dma_arm);
-EXPORT_SYMBOL(mite_dma_disarm);
-EXPORT_SYMBOL(mite_sync_input_dma);
-EXPORT_SYMBOL(mite_sync_output_dma);
-EXPORT_SYMBOL(mite_setup);
-EXPORT_SYMBOL(mite_setup2);
-EXPORT_SYMBOL(mite_unsetup);
-#if 0
-EXPORT_SYMBOL(mite_kvmem_segment_load);
-EXPORT_SYMBOL(mite_ll_from_kvmem);
-EXPORT_SYMBOL(mite_setregs);
-#endif
-EXPORT_SYMBOL(mite_devices);
-EXPORT_SYMBOL(mite_list_devices);
-EXPORT_SYMBOL(mite_request_channel_in_range);
-EXPORT_SYMBOL(mite_release_channel);
-EXPORT_SYMBOL(mite_prep_dma);
-EXPORT_SYMBOL(mite_buf_change);
-EXPORT_SYMBOL(mite_bytes_written_to_memory_lb);
-EXPORT_SYMBOL(mite_bytes_written_to_memory_ub);
-EXPORT_SYMBOL(mite_bytes_read_from_memory_lb);
-EXPORT_SYMBOL(mite_bytes_read_from_memory_ub);
-EXPORT_SYMBOL(mite_bytes_in_transit);
-EXPORT_SYMBOL(mite_get_status);
-EXPORT_SYMBOL(mite_done);
-#ifdef DEBUG_MITE
-EXPORT_SYMBOL(mite_decode);
-EXPORT_SYMBOL(mite_dump_regs);
-#endif
-
 #endif
diff --git a/drivers/staging/comedi/drivers/mite.h b/drivers/staging/comedi/drivers/mite.h
index 0518fad..9d5049f 100644
--- a/drivers/staging/comedi/drivers/mite.h
+++ b/drivers/staging/comedi/drivers/mite.h
@@ -163,13 +163,6 @@
 unsigned mite_get_status(struct mite_channel *mite_chan);
 int mite_done(struct mite_channel *mite_chan);
 
-#if 0
-unsigned long mite_ll_from_kvmem(struct mite_struct *mite,
-				 struct comedi_async *async, int len);
-void mite_setregs(struct mite_struct *mite, unsigned long ll_start, int chan,
-		  int dir);
-#endif
-
 void mite_prep_dma(struct mite_channel *mite_chan,
 		   unsigned int num_device_bits, unsigned int num_memory_bits);
 int mite_buf_change(struct mite_dma_descriptor_ring *ring,
diff --git a/drivers/staging/comedi/drivers/multiq3.c b/drivers/staging/comedi/drivers/multiq3.c
index 5d6af9c..6b22f0f 100644
--- a/drivers/staging/comedi/drivers/multiq3.c
+++ b/drivers/staging/comedi/drivers/multiq3.c
@@ -144,9 +144,8 @@
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
 
-	for (i = 0; i < insn->n; i++) {
+	for (i = 0; i < insn->n; i++)
 		data[i] = devpriv->ao_readback[chan];
-	}
 
 	return i;
 }
@@ -253,20 +252,20 @@
 	struct comedi_subdevice *s;
 
 	iobase = it->options[0];
-	printk("comedi%d: multiq3: 0x%04lx ", dev->minor, iobase);
+	printk(KERN_INFO "comedi%d: multiq3: 0x%04lx ", dev->minor, iobase);
 	if (!request_region(iobase, MULTIQ3_SIZE, "multiq3")) {
-		printk("comedi%d: I/O port conflict\n", dev->minor);
+		printk(KERN_ERR "comedi%d: I/O port conflict\n", dev->minor);
 		return -EIO;
 	}
 
 	dev->iobase = iobase;
 
 	irq = it->options[1];
-	if (irq) {
-		printk("comedi%d: irq = %u ignored\n", dev->minor, irq);
-	} else {
-		printk("comedi%d: no irq\n", dev->minor);
-	}
+	if (irq)
+		printk(KERN_WARNING "comedi%d: irq = %u ignored\n",
+			dev->minor, irq);
+	else
+		printk(KERN_WARNING "comedi%d: no irq\n", dev->minor);
 	dev->board_name = "multiq3";
 	result = alloc_subdevices(dev, 5);
 	if (result < 0)
@@ -330,14 +329,12 @@
 
 static int multiq3_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: multiq3: remove\n", dev->minor);
+	printk(KERN_INFO "comedi%d: multiq3: remove\n", dev->minor);
 
-	if (dev->iobase) {
+	if (dev->iobase)
 		release_region(dev->iobase, MULTIQ3_SIZE);
-	}
-	if (dev->irq) {
+	if (dev->irq)
 		free_irq(dev->irq, dev);
-	}
 
 	return 0;
 }
diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c
index b37ef37..653b4c8 100644
--- a/drivers/staging/comedi/drivers/ni_6527.c
+++ b/drivers/staging/comedi/drivers/ni_6527.c
@@ -273,7 +273,8 @@
 	if (err)
 		return 1;
 
-	/* step 2: make sure trigger sources are unique and mutually compatible */
+	/* step 2: make sure trigger sources are unique and */
+	/*         are mutually compatible */
 
 	if (err)
 		return 2;
@@ -377,7 +378,7 @@
 	struct comedi_subdevice *s;
 	int ret;
 
-	printk("comedi%d: ni6527:", dev->minor);
+	printk(KERN_INFO "comedi%d: ni6527\n", dev->minor);
 
 	ret = alloc_private(dev, sizeof(struct ni6527_private));
 	if (ret < 0)
@@ -389,14 +390,13 @@
 
 	ret = mite_setup(devpriv->mite);
 	if (ret < 0) {
-		printk("error setting up mite\n");
+		printk(KERN_ERR "comedi: error setting up mite\n");
 		return ret;
 	}
 
 	dev->board_name = this_board->name;
-	printk(" %s", dev->board_name);
-
-	printk(" ID=0x%02x", readb(devpriv->mite->daq_io_addr + ID_Register));
+	printk(KERN_INFO "comedi board: %s, ID=0x%02x\n", dev->board_name,
+		readb(devpriv->mite->daq_io_addr + ID_Register));
 
 	ret = alloc_subdevices(dev, 3);
 	if (ret < 0)
@@ -415,7 +415,7 @@
 	s->type = COMEDI_SUBD_DO;
 	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
 	s->n_chan = 24;
-	s->range_table = &range_unknown;	/* FIXME: actually conductance */
+	s->range_table = &range_unknown;  /* FIXME: actually conductance */
 	s->maxdata = 1;
 	s->insn_bits = ni6527_do_insn_bits;
 
@@ -442,30 +442,25 @@
 
 	ret = request_irq(mite_irq(devpriv->mite), ni6527_interrupt,
 			  IRQF_SHARED, "ni6527", dev);
-	if (ret < 0) {
-		printk(" irq not available");
-	} else
+	if (ret < 0)
+		printk(KERN_WARNING "comedi i6527 irq not available\n");
+	else
 		dev->irq = mite_irq(devpriv->mite);
 
-	printk("\n");
-
 	return 0;
 }
 
 static int ni6527_detach(struct comedi_device *dev)
 {
-	if (devpriv && devpriv->mite && devpriv->mite->daq_io_addr) {
+	if (devpriv && devpriv->mite && devpriv->mite->daq_io_addr)
 		writeb(0x00,
 		       devpriv->mite->daq_io_addr + Master_Interrupt_Control);
-	}
 
-	if (dev->irq) {
+	if (dev->irq)
 		free_irq(dev->irq, dev);
-	}
 
-	if (devpriv && devpriv->mite) {
+	if (devpriv && devpriv->mite)
 		mite_unsetup(devpriv->mite);
-	}
 
 	return 0;
 }
@@ -491,7 +486,7 @@
 			}
 		}
 	}
-	printk("no device found\n");
+	printk(KERN_ERR "comedi 6527: no device found\n");
 	mite_list_devices();
 	return -EIO;
 }
diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c
index 8adb237..3778565 100644
--- a/drivers/staging/comedi/drivers/ni_at_ao.c
+++ b/drivers/staging/comedi/drivers/ni_at_ao.c
@@ -32,7 +32,8 @@
   [0] - I/O port base address
   [1] - IRQ (unused)
   [2] - DMA (unused)
-  [3] - analog output range, set by jumpers on hardware (0 for -10 to 10V bipolar, 1 for 0V to 10V unipolar)
+  [3] - analog output range, set by jumpers on hardware (0 for -10 to 10V
+	bipolar, 1 for 0V to 10V unipolar)
 
 */
 /*
@@ -431,9 +432,8 @@
 				struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
-	for (i = 0; i < insn->n; i++) {
+	for (i = 0; i < insn->n; i++)
 		data[i] = 0;	/* XXX */
-	}
 	return insn->n;
 }
 
diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c
index 901833d..cf4f241 100644
--- a/drivers/staging/comedi/drivers/ni_atmio16d.c
+++ b/drivers/staging/comedi/drivers/ni_atmio16d.c
@@ -200,8 +200,8 @@
 	enum { dac_2comp, dac_straight } dac0_coding, dac1_coding;
 	const struct comedi_lrange *ao_range_type_list[2];
 	unsigned int ao_readback[2];
-	unsigned int com_reg_1_state;	/* current state of command register 1 */
-	unsigned int com_reg_2_state;	/* current state of command register 2 */
+	unsigned int com_reg_1_state; /* current state of command register 1 */
+	unsigned int com_reg_2_state; /* current state of command register 2 */
 };
 
 static void reset_counters(struct comedi_device *dev)
@@ -279,7 +279,9 @@
 	struct comedi_device *dev = d;
 	struct comedi_subdevice *s = dev->subdevices + 0;
 
-/* printk("atmio16d_interrupt!\n"); */
+#ifdef DEBUG1
+	printk(KERN_DEBUG "atmio16d_interrupt!\n");
+#endif
 
 	comedi_buf_put(s->async, inw(dev->iobase + AD_FIFO_REG));
 
@@ -293,7 +295,7 @@
 {
 	int err = 0, tmp;
 #ifdef DEBUG1
-	printk("atmio16d_ai_cmdtest\n");
+	printk(KERN_DEBUG "atmio16d_ai_cmdtest\n");
 #endif
 	/* make sure triggers are valid */
 	tmp = cmd->start_src;
@@ -324,8 +326,8 @@
 	if (err)
 		return 1;
 
-	/* step 2: make sure trigger sources are unique and mutually compatible */
-	/* note that mutual compatiblity is not an issue here */
+	/* step 2: make sure trigger sources are unique & mutually compatible */
+	/* note that mutual compatibility is not an issue here */
 	if (cmd->scan_begin_src != TRIG_FOLLOW &&
 	    cmd->scan_begin_src != TRIG_EXT &&
 	    cmd->scan_begin_src != TRIG_TIMER)
@@ -397,7 +399,7 @@
 	unsigned int sample_count, tmp, chan, gain;
 	int i;
 #ifdef DEBUG1
-	printk("atmio16d_ai_cmd\n");
+	printk(KERN_DEBUG "atmio16d_ai_cmd\n");
 #endif
 	/* This is slowly becoming a working command interface. *
 	 * It is still uber-experimental */
@@ -436,10 +438,10 @@
 	} else if (cmd->convert_arg < 655360000) {
 		base_clock = CLOCK_100_KHZ;
 		timer = cmd->convert_arg / 10000;
-	} else if (cmd->convert_arg <= 0xffffffff /* 6553600000 */ ) {
+	} else if (cmd->convert_arg <= 0xffffffff /* 6553600000 */) {
 		base_clock = CLOCK_10_KHZ;
 		timer = cmd->convert_arg / 100000;
-	} else if (cmd->convert_arg <= 0xffffffff /* 65536000000 */ ) {
+	} else if (cmd->convert_arg <= 0xffffffff /* 65536000000 */) {
 		base_clock = CLOCK_1_KHZ;
 		timer = cmd->convert_arg / 1000000;
 	}
@@ -504,10 +506,10 @@
 		} else if (cmd->scan_begin_arg < 655360000) {
 			base_clock = CLOCK_100_KHZ;
 			timer = cmd->scan_begin_arg / 10000;
-		} else if (cmd->scan_begin_arg < 0xffffffff /* 6553600000 */ ) {
+		} else if (cmd->scan_begin_arg < 0xffffffff /* 6553600000 */) {
 			base_clock = CLOCK_10_KHZ;
 			timer = cmd->scan_begin_arg / 100000;
-		} else if (cmd->scan_begin_arg < 0xffffffff /* 65536000000 */ ) {
+		} else if (cmd->scan_begin_arg < 0xffffffff /* 65536000000 */) {
 			base_clock = CLOCK_1_KHZ;
 			timer = cmd->scan_begin_arg / 1000000;
 		}
@@ -559,7 +561,7 @@
 	int status;
 
 #ifdef DEBUG1
-	printk("atmio16d_ai_insn_read\n");
+	printk(KERN_DEBUG "atmio16d_ai_insn_read\n");
 #endif
 	chan = CR_CHAN(insn->chanspec);
 	gain = CR_RANGE(insn->chanspec);
@@ -580,19 +582,18 @@
 			/* check conversion status */
 			status = inw(dev->iobase + STAT_REG);
 #ifdef DEBUG1
-			printk("status=%x\n", status);
+			printk(KERN_DEBUG "status=%x\n", status);
 #endif
 			if (status & STAT_AD_CONVAVAIL) {
 				/* read the data now */
 				data[i] = inw(dev->iobase + AD_FIFO_REG);
 				/* change to two's complement if need be */
-				if (devpriv->adc_coding == adc_2comp) {
+				if (devpriv->adc_coding == adc_2comp)
 					data[i] ^= 0x800;
-				}
 				break;
 			}
 			if (status & STAT_AD_OVERFLOW) {
-				printk("atmio16d: a/d FIFO overflow\n");
+				printk(KERN_INFO "atmio16d: a/d FIFO overflow\n");
 				outw(0, dev->iobase + AD_CLEAR_REG);
 
 				return -ETIME;
@@ -600,7 +601,7 @@
 		}
 		/* end waiting, now check if it timed out */
 		if (t == ATMIO16D_TIMEOUT) {
-			printk("atmio16d: timeout\n");
+			printk(KERN_INFO "atmio16d: timeout\n");
 
 			return -ETIME;
 		}
@@ -615,13 +616,11 @@
 {
 	int i;
 #ifdef DEBUG1
-	printk("atmio16d_ao_insn_read\n");
+	printk(KERN_DEBUG "atmio16d_ao_insn_read\n");
 #endif
 
-	for (i = 0; i < insn->n; i++) {
+	for (i = 0; i < insn->n; i++)
 		data[i] = devpriv->ao_readback[CR_CHAN(insn->chanspec)];
-	}
-
 	return i;
 }
 
@@ -633,7 +632,7 @@
 	int chan;
 	int d;
 #ifdef DEBUG1
-	printk("atmio16d_ao_insn_write\n");
+	printk(KERN_DEBUG "atmio16d_ao_insn_write\n");
 #endif
 
 	chan = CR_CHAN(insn->chanspec);
@@ -642,15 +641,13 @@
 		d = data[i];
 		switch (chan) {
 		case 0:
-			if (devpriv->dac0_coding == dac_2comp) {
+			if (devpriv->dac0_coding == dac_2comp)
 				d ^= 0x800;
-			}
 			outw(d, dev->iobase + DAC0_REG);
 			break;
 		case 1:
-			if (devpriv->dac1_coding == dac_2comp) {
+			if (devpriv->dac1_coding == dac_2comp)
 				d ^= 0x800;
-			}
 			outw(d, dev->iobase + DAC1_REG);
 			break;
 		default:
@@ -705,29 +702,29 @@
 /*
    options[0] - I/O port
    options[1] - MIO irq
-                0 == no irq
-                N == irq N {3,4,5,6,7,9,10,11,12,14,15}
+		0 == no irq
+		N == irq N {3,4,5,6,7,9,10,11,12,14,15}
    options[2] - DIO irq
-                0 == no irq
-                N == irq N {3,4,5,6,7,9}
+		0 == no irq
+		N == irq N {3,4,5,6,7,9}
    options[3] - DMA1 channel
-                0 == no DMA
-                N == DMA N {5,6,7}
+		0 == no DMA
+		N == DMA N {5,6,7}
    options[4] - DMA2 channel
-                0 == no DMA
-                N == DMA N {5,6,7}
+		0 == no DMA
+		N == DMA N {5,6,7}
 
    options[5] - a/d mux
-   	0=differential, 1=single
+	0=differential, 1=single
    options[6] - a/d range
-   	0=bipolar10, 1=bipolar5, 2=unipolar10
+	0=bipolar10, 1=bipolar5, 2=unipolar10
 
    options[7] - dac0 range
-   	0=bipolar, 1=unipolar
+	0=bipolar, 1=unipolar
    options[8] - dac0 reference
-    0=internal, 1=external
+	0=internal, 1=external
    options[9] - dac0 coding
-   	0=2's comp, 1=straight binary
+	0=2's comp, 1=straight binary
 
    options[10] - dac1 range
    options[11] - dac1 reference
@@ -745,7 +742,7 @@
 
 	/* make sure the address range is free and allocate it */
 	iobase = it->options[0];
-	printk("comedi%d: atmio16d: 0x%04lx ", dev->minor, iobase);
+	printk(KERN_INFO "comedi%d: atmio16d: 0x%04lx ", dev->minor, iobase);
 	if (!request_region(iobase, ATMIO16D_SIZE, "ni_atmio16d")) {
 		printk("I/O port conflict\n");
 		return -EIO;
@@ -772,13 +769,13 @@
 
 		ret = request_irq(irq, atmio16d_interrupt, 0, "atmio16d", dev);
 		if (ret < 0) {
-			printk("failed to allocate irq %u\n", irq);
+			printk(KERN_INFO "failed to allocate irq %u\n", irq);
 			return ret;
 		}
 		dev->irq = irq;
-		printk("( irq = %u )\n", irq);
+		printk(KERN_INFO "( irq = %u )\n", irq);
 	} else {
-		printk("( no irq )");
+		printk(KERN_INFO "( no irq )");
 	}
 
 	/* set device options */
@@ -855,11 +852,10 @@
 
 	/* 8255 subdevice */
 	s++;
-	if (boardtype->has_8255) {
+	if (boardtype->has_8255)
 		subdev_8255_init(dev, s, NULL, dev->iobase);
-	} else {
+	else
 		s->type = COMEDI_SUBD_UNUSED;
-	}
 
 /* don't yet know how to deal with counter/timers */
 #if 0
@@ -876,7 +872,7 @@
 
 static int atmio16d_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: atmio16d: remove\n", dev->minor);
+	printk(KERN_INFO "comedi%d: atmio16d: remove\n", dev->minor);
 
 	if (dev->subdevices && boardtype->has_8255)
 		subdev_8255_cleanup(dev, dev->subdevices + 3);
diff --git a/drivers/staging/comedi/drivers/ni_labpc.h b/drivers/staging/comedi/drivers/ni_labpc.h
index 8259634..422cee5 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.h
+++ b/drivers/staging/comedi/drivers/ni_labpc.h
@@ -38,19 +38,27 @@
 	int device_id;		/*  device id for pci and pcmcia boards */
 	int ai_speed;		/*  maximum input speed in nanoseconds */
 	enum labpc_bustype bustype;	/*  ISA/PCI/etc. */
-	enum labpc_register_layout register_layout;	/*  1200 has extra registers compared to pc+ */
+
+	/*  1200 has extra registers compared to pc+ */
+	enum labpc_register_layout register_layout;
 	int has_ao;		/*  has analog output true/false */
 	const struct comedi_lrange *ai_range_table;
 	const int *ai_range_code;
 	const int *ai_range_is_unipolar;
-	unsigned ai_scan_up:1;	/*  board can auto scan up in ai channels, not just down */
-	unsigned memory_mapped_io:1;	/* uses memory mapped io instead of ioports */
+
+	/*  board can auto scan up in ai channels, not just down */
+	unsigned ai_scan_up:1;
+
+	/* uses memory mapped io instead of ioports */
+	unsigned memory_mapped_io:1;
 };
 
 struct labpc_private {
 	struct mite_struct *mite;	/*  for mite chip on pci-1200 */
-	volatile unsigned long long count;	/* number of data points left to be taken */
-	unsigned int ao_value[NUM_AO_CHAN];	/*  software copy of analog output values */
+	/*  number of data points left to be taken */
+	volatile unsigned long long count;
+	/*  software copy of analog output values */
+	unsigned int ao_value[NUM_AO_CHAN];
 	/*  software copys of bits written to command registers */
 	volatile unsigned int command1_bits;
 	volatile unsigned int command2_bits;
@@ -61,16 +69,34 @@
 	/*  store last read of board status registers */
 	volatile unsigned int status1_bits;
 	volatile unsigned int status2_bits;
-	unsigned int divisor_a0;	/* value to load into board's counter a0 (conversion pacing) for timed conversions */
-	unsigned int divisor_b0;	/* value to load into board's counter b0 (master) for timed conversions */
-	unsigned int divisor_b1;	/* value to load into board's counter b1 (scan pacing) for timed conversions */
+	/*
+	 * value to load into board's counter a0 (conversion pacing) for timed
+	 * conversions
+	 */
+	unsigned int divisor_a0;
+	/*
+	 * value to load into board's counter b0 (master) for timed conversions
+	 */
+	unsigned int divisor_b0;
+	/*
+	 * value to load into board's counter b1 (scan pacing) for timed
+	 * conversions
+	 */
+	unsigned int divisor_b1;
 	unsigned int dma_chan;	/*  dma channel to use */
 	u16 *dma_buffer;	/*  buffer ai will dma into */
-	unsigned int dma_transfer_size;	/*  transfer size in bytes for current transfer */
-	enum transfer_type current_transfer;	/*  we are using dma/fifo-half-full/etc. */
-	unsigned int eeprom_data[EEPROM_SIZE];	/*  stores contents of board's eeprom */
-	unsigned int caldac[16];	/*  stores settings of calibration dacs */
-	/*  function pointers so we can use inb/outb or readb/writeb as appropriate */
+	/* transfer size in bytes for current transfer */
+	unsigned int dma_transfer_size;
+	/* we are using dma/fifo-half-full/etc. */
+	enum transfer_type current_transfer;
+	/* stores contents of board's eeprom */
+	unsigned int eeprom_data[EEPROM_SIZE];
+	/* stores settings of calibration dacs */
+	unsigned int caldac[16];
+	/*
+	 * function pointers so we can use inb/outb or readb/writeb as
+	 * appropriate
+	 */
 	unsigned int (*read_byte) (unsigned long address);
 	void (*write_byte) (unsigned int byte, unsigned long address);
 };
diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c
index 7d514b3..0b963bb 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_cs.c
+++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c
@@ -59,8 +59,7 @@
 
 */
 
-#undef LABPC_DEBUG
-			    /* #define LABPC_DEBUG *//*  enable debugging messages */
+#undef LABPC_DEBUG  /* debugging messages */
 
 #include "../comedidev.h"
 
@@ -77,14 +76,15 @@
 #include <pcmcia/cisreg.h>
 #include <pcmcia/ds.h>
 
-static struct pcmcia_device *pcmcia_cur_dev = NULL;
+static struct pcmcia_device *pcmcia_cur_dev;
 
 static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it);
 
 static const struct labpc_board_struct labpc_cs_boards[] = {
 	{
 	 .name = "daqcard-1200",
-	 .device_id = 0x103,	/*  0x10b is manufacturer id, 0x103 is device id */
+	 .device_id = 0x103,	/* 0x10b is manufacturer id,
+				   0x103 is device id */
 	 .ai_speed = 10000,
 	 .bustype = pcmcia_bustype,
 	 .register_layout = labpc_1200_layout,
@@ -273,9 +273,8 @@
 		labpc_release(link);
 	}
 
-	/* This points to the parent local_info_t struct */
-	if (link->priv)
-		kfree(link->priv);
+	/* This points to the parent local_info_t struct (may be null) */
+	kfree(link->priv);
 
 }				/* labpc_cs_detach */
 
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c
index 753ee05..d6d49c3 100644
--- a/drivers/staging/comedi/drivers/ni_mio_common.c
+++ b/drivers/staging/comedi/drivers/ni_mio_common.c
@@ -2207,7 +2207,7 @@
 
 	/* step 2: make sure trigger sources are unique and mutually compatible */
 
-	/* note that mutual compatiblity is not an issue here */
+	/* note that mutual compatibility is not an issue here */
 	if (cmd->start_src != TRIG_NOW &&
 	    cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT)
 		err++;
diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c
index d692f4b..dc4849a 100644
--- a/drivers/staging/comedi/drivers/ni_mio_cs.c
+++ b/drivers/staging/comedi/drivers/ni_mio_cs.c
@@ -250,9 +250,8 @@
 
 	/* PCMCIA layer frees the IO region */
 
-	if (dev->irq) {
+	if (dev->irq)
 		free_irq(dev->irq, dev);
-	}
 
 	return 0;
 }
@@ -293,9 +292,8 @@
 {
 	DPRINTK("cs_detach(link=%p)\n", link);
 
-	if (link->dev_node) {
+	if (link->dev_node)
 		cs_release(link);
-	}
 }
 
 static int mio_cs_suspend(struct pcmcia_device *link)
@@ -387,9 +385,8 @@
 		}
 		printk("\n");
 		printk(" board fingerprint (windowed):");
-		for (i = 0; i < 10; i++) {
+		for (i = 0; i < 10; i++)
 			printk(" 0x%04x", win_in(i));
-		}
 		printk("\n");
 	}
 #endif
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c
index d544698..2d88a5b 100644
--- a/drivers/staging/comedi/drivers/ni_pcidio.c
+++ b/drivers/staging/comedi/drivers/ni_pcidio.c
@@ -795,7 +795,7 @@
 
 	/* step 2: make sure trigger sources are unique and mutually compatible */
 
-	/* note that mutual compatiblity is not an issue here */
+	/* note that mutual compatibility is not an issue here */
 	if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_INT)
 		err++;
 	if (cmd->scan_begin_src != TRIG_TIMER &&
diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c
index dd9db06..4914784 100644
--- a/drivers/staging/comedi/drivers/pcl711.c
+++ b/drivers/staging/comedi/drivers/pcl711.c
@@ -407,6 +407,7 @@
 		 *  0xb4 = Select Counter 2 | LSB/MSB | Mode=2 | Binary
 		 */
 
+		timer1 = timer2 = 0;
 		i8253_cascade_ns_to_timer(i8253_osc_base, &timer1, &timer2,
 					  &cmd->scan_begin_arg,
 					  TRIG_ROUND_NEAREST);
diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c
index ccadd09..6a1a979 100644
--- a/drivers/staging/comedi/drivers/pcl726.c
+++ b/drivers/staging/comedi/drivers/pcl726.c
@@ -39,27 +39,27 @@
     Options for PCL-726:
      [0] - IO Base
      [2]...[7] - D/A output range for channel 1-6:
-               0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
-	       4: 4-20mA, 5: unknown (external reference)
+		0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
+		4: 4-20mA, 5: unknown (external reference)
 
     Options for PCL-727:
      [0] - IO Base
      [2]...[13] - D/A output range for channel 1-12:
-               0: 0-5V, 1: 0-10V, 2: +/-5V,
-	       3: 4-20mA
+		0: 0-5V, 1: 0-10V, 2: +/-5V,
+		3: 4-20mA
 
     Options for PCL-728 and ACL-6128:
      [0] - IO Base
      [2], [3] - D/A output range for channel 1 and 2:
-               0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
-	       4: 4-20mA, 5: 0-20mA
+		0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
+		4: 4-20mA, 5: 0-20mA
 
     Options for ACL-6126:
      [0] - IO Base
      [1] - IRQ (0=disable, 3, 5, 6, 7, 9, 10, 11, 12, 15) (currently ignored)
      [2]...[7] - D/A output range for channel 1-6:
-               0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
-	       4: 4-20mA
+		0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
+		4: 4-20mA
 */
 
 /*
@@ -127,7 +127,8 @@
 	int di_lo;
 	int do_hi;
 	int do_lo;
-	const struct comedi_lrange *const *range_type_list;	/*  list of supported ranges */
+	const struct comedi_lrange *const *range_type_list;
+	/*  list of supported ranges */
 };
 
 static const struct pcl726_board boardtypes[] = {
@@ -204,9 +205,8 @@
 	int chan = CR_CHAN(insn->chanspec);
 	int n;
 
-	for (n = 0; n < insn->n; n++) {
+	for (n = 0; n < insn->n; n++)
 		data[n] = devpriv->ao_readback[chan];
-	}
 	return n;
 }
 
@@ -256,10 +256,10 @@
 
 	iobase = it->options[0];
 	iorange = this_board->io_range;
-	printk("comedi%d: pcl726: board=%s, 0x%03lx ", dev->minor,
+	printk(KERN_WARNING "comedi%d: pcl726: board=%s, 0x%03lx ", dev->minor,
 	       this_board->name, iobase);
 	if (!request_region(iobase, iorange, "pcl726")) {
-		printk("I/O port conflict\n");
+		printk(KERN_WARNING "I/O port conflict\n");
 		return -EIO;
 	}
 
@@ -283,16 +283,16 @@
 		devpriv->first_chan = 2;
 		if (irq) {	/* we want to use IRQ */
 			if (((1 << irq) & boardtypes[board].IRQbits) == 0) {
-				printk
-				    (", IRQ %d is out of allowed range, DISABLING IT",
-				     irq);
+				printk(KERN_WARNING
+					", IRQ %d is out of allowed range,"
+					" DISABLING IT", irq);
 				irq = 0;	/* Bad IRQ */
 			} else {
 				if (request_irq(irq, interrupt_pcl818, 0,
 						"pcl726", dev)) {
-					printk
-					    (", unable to allocate IRQ %d, DISABLING IT",
-					     irq);
+					printk(KERN_WARNING
+						", unable to allocate IRQ %d,"
+						" DISABLING IT", irq);
 					irq = 0;	/* Can't use IRQ */
 				} else {
 					printk(", irq=%d", irq);
@@ -372,9 +372,8 @@
 /* printk("comedi%d: pcl726: remove\n",dev->minor); */
 
 #ifdef ACL6126_IRQ
-	if (dev->irq) {
+	if (dev->irq)
 		free_irq(dev->irq, dev);
-	}
 #endif
 
 	if (dev->iobase)
diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c
index 0b51a48..0a5bc3d 100644
--- a/drivers/staging/comedi/drivers/pcl812.c
+++ b/drivers/staging/comedi/drivers/pcl812.c
@@ -51,7 +51,7 @@
         5=A/D input range is +/-0.3125V
   [5] - 0=D/A outputs 0-5V  (internal reference -5V)
         1=D/A outputs 0-10V (internal reference -10V)
-        2=D/A outputs unknow (external reference)
+        2=D/A outputs unknown (external reference)
 
 Options for PCL-812PG, ACL-8112PG:
   [0] - IO Base
@@ -63,7 +63,7 @@
         1=A/D have max +/-10V input
   [5] - 0=D/A outputs 0-5V  (internal reference -5V)
         1=D/A outputs 0-10V (internal reference -10V)
-        2=D/A outputs unknow (external reference)
+        2=D/A outputs unknown (external reference)
 
 Options for ACL-8112DG/HG, A-822PGL/PGH, A-823PGL/PGH, ACL-8216, A-826PG:
   [0] - IO Base
@@ -75,7 +75,7 @@
         1=A/D channels are DIFF
   [5] - 0=D/A outputs 0-5V  (internal reference -5V)
         1=D/A outputs 0-10V (internal reference -10V)
-        2=D/A outputs unknow (external reference)
+        2=D/A outputs unknown (external reference)
 
 Options for A-821PGL/PGH:
   [0] - IO Base
diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c
index fa24145..852fe24 100644
--- a/drivers/staging/comedi/drivers/pcl816.c
+++ b/drivers/staging/comedi/drivers/pcl816.c
@@ -112,7 +112,7 @@
 	int n_dichan;		/*  num of DI chans */
 	int n_dochan;		/*  num of DO chans */
 	const struct comedi_lrange *ai_range_type;	/*  default A/D rangelist */
-	const struct comedi_lrange *ao_range_type;	/*  dafault D/A rangelist */
+	const struct comedi_lrange *ao_range_type;	/*  default D/A rangelist */
 	unsigned int io_range;	/*  len of IO space */
 	unsigned int IRQbits;	/*  allowed interrupts */
 	unsigned int DMAbits;	/*  allowed DMA chans */
@@ -445,7 +445,7 @@
 		comedi_error(dev, "bad IRQ!");
 		return IRQ_NONE;
 	}
-	comedi_error(dev, "IRQ from unknow source!");
+	comedi_error(dev, "IRQ from unknown source!");
 	return IRQ_NONE;
 }
 
@@ -472,7 +472,7 @@
 			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	int err = 0;
-	int tmp, divisor1, divisor2;
+	int tmp, divisor1 = 0, divisor2 = 0;
 
 	DEBUG(printk("pcl816 pcl812_ai_cmdtest\n"); pcl816_cmdtest_out(-1, cmd);
 	    );
@@ -488,7 +488,9 @@
 	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
 		err++;
 
-	if (!(cmd->convert_src & (TRIG_EXT | TRIG_TIMER)))
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_EXT | TRIG_TIMER;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
 		err++;
 
 	tmp = cmd->scan_end_src;
diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c
index e95229b..d048101 100644
--- a/drivers/staging/comedi/drivers/pcl818.c
+++ b/drivers/staging/comedi/drivers/pcl818.c
@@ -50,7 +50,7 @@
           1, 10=A/D input -10V..+10V
     [5] - 0,  5=D/A output 0-5V  (internal reference -5V)
           1, 10=D/A output 0-10V (internal reference -10V)
-	  2    =D/A output unknow (external reference)
+	  2    =D/A output unknown (external reference)
 
    Options for PCL-818, PCL-818H:
     [0] - IO Base
@@ -60,7 +60,7 @@
               1= 1MHz clock for 8254
     [4] - 0,  5=D/A output 0-5V  (internal reference -5V)
           1, 10=D/A output 0-10V (internal reference -10V)
-	  2    =D/A output unknow (external reference)
+	  2    =D/A output unknown (external reference)
 
    Options for PCL-818HD, PCL-818HG:
     [0] - IO Base
@@ -71,7 +71,7 @@
               1= 1MHz clock for 8254
     [4] - 0,  5=D/A output 0-5V  (internal reference -5V)
           1, 10=D/A output 0-10V (internal reference -10V)
-   	  2    =D/A output unknow (external reference)
+   	  2    =D/A output unknown (external reference)
 
    Options for PCL-718:
     [0] - IO Base
@@ -92,7 +92,7 @@
 	     10=	     user defined unipolar
     [5] - 0,  5=D/A outputs 0-5V  (internal reference -5V)
           1, 10=D/A outputs 0-10V (internal reference -10V)
-	      2=D/A outputs unknow (external reference)
+	      2=D/A outputs unknown (external reference)
     [6] - 0, 60=max  60kHz A/D sampling
           1,100=max 100kHz A/D sampling (PCL-718 with Option 001 installed)
 
@@ -876,7 +876,7 @@
 		return IRQ_NONE;
 	}
 
-	comedi_error(dev, "IRQ from unknow source!");
+	comedi_error(dev, "IRQ from unknown source!");
 	return IRQ_NONE;
 }
 
@@ -970,7 +970,7 @@
 			      struct comedi_subdevice *s)
 {
 	struct comedi_cmd *cmd = &s->async->cmd;
-	int divisor1, divisor2;
+	int divisor1 = 0, divisor2 = 0;
 	unsigned int seglen;
 
 	printk("pcl818_ai_cmd_mode()\n");
@@ -1089,7 +1089,7 @@
 static int pcl818_ao_mode13(int mode, struct comedi_device *dev,
 			    struct comedi_subdevice *s, comedi_trig * it)
 {
-	int divisor1, divisor2;
+	int divisor1 = 0, divisor2 = 0;
 
 	if (!dev->irq) {
 		comedi_error(dev, "IRQ not defined!");
@@ -1287,7 +1287,7 @@
 		      struct comedi_cmd *cmd)
 {
 	int err = 0;
-	int tmp, divisor1, divisor2;
+	int tmp, divisor1 = 0, divisor2 = 0;
 
 	/* step 1: make sure trigger sources are trivially valid */
 
diff --git a/drivers/staging/comedi/drivers/pcm_common.c b/drivers/staging/comedi/drivers/pcm_common.c
index ebd9838..52c2a669 100644
--- a/drivers/staging/comedi/drivers/pcm_common.c
+++ b/drivers/staging/comedi/drivers/pcm_common.c
@@ -41,7 +41,8 @@
 	if (err)
 		return 1;
 
-	/* step 2: make sure trigger sources are unique and mutually compatible */
+	/* step 2: make sure trigger sources are unique and
+	 * mutually compatible */
 
 	/* these tests are true if more than one _src bit is set */
 	if ((cmd->start_src & (cmd->start_src - 1)) != 0)
@@ -107,5 +108,4 @@
 
 	return 0;
 }
-
 EXPORT_SYMBOL(comedi_pcm_cmdtest);
diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c
index d812c2c..35ba939 100644
--- a/drivers/staging/comedi/drivers/pcmmio.c
+++ b/drivers/staging/comedi/drivers/pcmmio.c
@@ -32,8 +32,10 @@
 four subdevices:
   subdevice 0 - 16 channels of 16-bit AI
   subdevice 1 - 8 channels of 16-bit AO
-  subdevice 2 - first 24 channels of the 48 channel of DIO (with edge-triggered interrupt support)
-  subdevice 3 - last 24 channels of the 48 channel DIO (no interrupt support for this bank of channels)
+  subdevice 2 - first 24 channels of the 48 channel of DIO
+	(with edge-triggered interrupt support)
+  subdevice 3 - last 24 channels of the 48 channel DIO
+	(no interrupt support for this bank of channels)
 
   Some notes:
 
@@ -70,7 +72,8 @@
 
 Configuration Options:
   [0] - I/O port base address
-  [1] - IRQ (optional -- for edge-detect interrupt support only, leave out if you don't need this feature)
+  [1] - IRQ (optional -- for edge-detect interrupt support only,
+	leave out if you don't need this feature)
 */
 
 #include <linux/interrupt.h>
@@ -115,9 +118,11 @@
 #define REG_PORT4 0x4
 #define REG_PORT5 0x5
 #define REG_INT_PENDING 0x6
-#define REG_PAGELOCK 0x7	/* page selector register, upper 2 bits select a page
-				   and bits 0-5 are used to 'lock down' a particular
-				   port above to make it readonly.  */
+#define REG_PAGELOCK 0x7	/*
+				 * page selector register, upper 2 bits select
+				 * a page and bits 0-5 are used to 'lock down'
+				 * a particular port above to make it readonly.
+				 */
 #define REG_POL0 0x8
 #define REG_POL1 0x9
 #define REG_POL2 0xA
@@ -134,7 +139,7 @@
 #define REG_PAGE_BITOFFSET 6
 #define REG_LOCK_BITOFFSET 0
 #define REG_PAGE_MASK (~((0x1<<REG_PAGE_BITOFFSET)-1))
-#define REG_LOCK_MASK ~(REG_PAGE_MASK)
+#define REG_LOCK_MASK (~(REG_PAGE_MASK))
 #define PAGE_POL 1
 #define PAGE_ENAB 2
 #define PAGE_INT_ID 3
@@ -168,13 +173,12 @@
 	comedi_insn_fn_t ai_rinsn, ao_rinsn, ao_winsn;
 };
 
-static const struct comedi_lrange ranges_ai =
-    { 4, {RANGE(-5., 5.), RANGE(-10., 10.), RANGE(0., 5.), RANGE(0.,
-								 10.)}
+static const struct comedi_lrange ranges_ai = {
+	4, {RANGE(-5., 5.), RANGE(-10., 10.), RANGE(0., 5.), RANGE(0., 10.)}
 };
 
-static const struct comedi_lrange ranges_ao =
-    { 6, {RANGE(0., 5.), RANGE(0., 10.), RANGE(-5., 5.), RANGE(-10., 10.),
+static const struct comedi_lrange ranges_ao = {
+	6, {RANGE(0., 5.), RANGE(0., 10.), RANGE(-5., 5.), RANGE(-10., 10.),
 	  RANGE(-2.5, 2.5), RANGE(-2.5, 7.5)}
 };
 
@@ -204,7 +208,8 @@
 struct pcmmio_subdev_private {
 
 	union {
-		/* for DIO: mapping of halfwords (bytes) in port/chanarray to iobase */
+		/* for DIO: mapping of halfwords (bytes)
+		   in port/chanarray to iobase */
 		unsigned long iobases[PORTS_PER_SUBDEV];
 
 		/* for AI/AO */
@@ -215,15 +220,31 @@
 
 			/* The below is only used for intr subdevices */
 			struct {
-				int asic;	/* if non-negative, this subdev has an interrupt asic */
-				int first_chan;	/* if nonnegative, the first channel id for
-						   interrupts. */
-				int num_asic_chans;	/* the number of asic channels in this subdev
-							   that have interrutps */
-				int asic_chan;	/* if nonnegative, the first channel id with
-						   respect to the asic that has interrupts */
-				int enabled_mask;	/* subdev-relative channel mask for channels
-							   we are interested in */
+				/*
+				 * if non-negative, this subdev has an
+				 * interrupt asic
+				 */
+				int asic;
+				/*
+				 * if nonnegative, the first channel id for
+				 * interrupts.
+				 */
+				int first_chan;
+				/*
+				 * the number of asic channels in this subdev
+				 * that have interrutps
+				 */
+				int num_asic_chans;
+				/*
+				 * if nonnegative, the first channel id with
+				 * respect to the asic that has interrupts
+				 */
+				int asic_chan;
+				/*
+				 * subdev-relative channel mask for channels
+				 * we are interested in
+				 */
+				int enabled_mask;
 				int active;
 				int stop_count;
 				int continuous;
@@ -231,20 +252,25 @@
 			} intr;
 		} dio;
 		struct {
-			unsigned int shadow_samples[8];	/* the last unsigned int data written */
+			/* the last unsigned int data written */
+			unsigned int shadow_samples[8];
 		} ao;
 	};
 };
 
-/* this structure is for data unique to this hardware driver.  If
-   several hardware drivers keep similar information in this structure,
-   feel free to suggest moving the variable to the struct comedi_device struct.  */
+/*
+ * this structure is for data unique to this hardware driver.  If
+ * several hardware drivers keep similar information in this structure,
+ * feel free to suggest moving the variable to the struct comedi_device struct.
+ */
 struct pcmmio_private {
 	/* stuff for DIO */
 	struct {
 		unsigned char pagelock;	/* current page and lock */
-		unsigned char pol[NUM_PAGED_REGS];	/* shadow of POLx registers */
-		unsigned char enab[NUM_PAGED_REGS];	/* shadow of ENABx registers */
+		/* shadow of POLx registers */
+		unsigned char pol[NUM_PAGED_REGS];
+		/* shadow of ENABx registers */
+		unsigned char enab[NUM_PAGED_REGS];
 		int num;
 		unsigned long iobase;
 		unsigned int irq;
@@ -312,7 +338,8 @@
 			  struct comedi_cmd *cmd);
 
 /* some helper functions to deal with specifics of this device's registers */
-static void init_asics(struct comedi_device *dev);	/* sets up/clears ASIC chips to defaults */
+/* sets up/clears ASIC chips to defaults */
+static void init_asics(struct comedi_device *dev);
 static void switch_page(struct comedi_device *dev, int asic, int page);
 #ifdef notused
 static void lock_port(struct comedi_device *dev, int asic, int port);
@@ -367,9 +394,11 @@
 		devpriv->asics[asic].num = asic;
 		devpriv->asics[asic].iobase =
 		    dev->iobase + 16 + asic * ASIC_IOSIZE;
-		devpriv->asics[asic].irq = 0;	/* this gets actually set at the end of
-						   this function when we
-						   request_irqs */
+		/*
+		 * this gets actually set at the end of this function when we
+		 * request_irqs
+		 */
+		devpriv->asics[asic].irq = 0;
 		spin_lock_init(&devpriv->asics[asic].spinlock);
 	}
 
@@ -463,7 +492,10 @@
 			if (thisasic_chanct <
 			    CHANS_PER_PORT * INTR_PORTS_PER_ASIC
 			    && subpriv->dio.intr.asic < 0) {
-				/* this is an interrupt subdevice, so setup the struct */
+				/*
+				 * this is an interrupt subdevice,
+				 * so setup the struct
+				 */
 				subpriv->dio.intr.asic = asic;
 				subpriv->dio.intr.active = 0;
 				subpriv->dio.intr.stop_count = 0;
@@ -484,7 +516,11 @@
 		chans_left -= s->n_chan;
 
 		if (!chans_left) {
-			asic = 0;	/* reset the asic to our first asic, to do intr subdevs */
+			/*
+			 * reset the asic to our first asic,
+			 * to do intr subdevs
+			 */
+			asic = 0;
 			port = 0;
 		}
 
@@ -507,8 +543,10 @@
 		devpriv->asics[asic].irq = irq[asic];
 	}
 
-	dev->irq = irq[0];	/* grr.. wish comedi dev struct supported multiple
-				   irqs.. */
+	dev->irq = irq[0];	/*
+				 * grr.. wish comedi dev struct supported
+				 * multiple irqs..
+				 */
 
 	if (irq[0]) {
 		printk("irq: %u ", irq[0]);
@@ -604,9 +642,14 @@
 #endif
 
 		if (write_mask_byte) {
-			/* this byte has some write_bits -- so set the output lines */
-			byte &= ~write_mask_byte;	/* clear bits for write mask */
-			byte |= ~data_byte & write_mask_byte;	/* set to inverted data_byte */
+			/*
+			 * this byte has some write_bits
+			 * -- so set the output lines
+			 */
+			/* clear bits for write mask */
+			byte &= ~write_mask_byte;
+			/* set to inverted data_byte */
+			byte |= ~data_byte & write_mask_byte;
 			/* Write out the new digital output state */
 			outb(byte, ioaddr);
 		}
@@ -670,9 +713,11 @@
 		byte &= ~(1 << bit_no);
 				/**< set input channel to '0' */
 
-		/* write out byte -- this is the only time we actually affect the
-		   hardware as all channels are implicitly output -- but input
-		   channels are set to float-high */
+		/*
+		 * write out byte -- this is the only time we actually affect
+		 * the hardware as all channels are implicitly output
+		 * -- but input channels are set to float-high
+		 */
 		outb(byte, ioaddr);
 
 		/* save to io_bits */
@@ -726,8 +771,8 @@
 		   outb(0xff, baseaddr + REG_ENAB0); */
 		/* END DEBUG */
 
-		switch_page(dev, asic, 0);	/* switch back to default page 0 */
-
+		/* switch back to default page 0 */
+		switch_page(dev, asic, 0);
 	}
 }
 
@@ -806,7 +851,10 @@
 							REG_INT_ID0 + port);
 
 						if (io_lines_with_edges)
-							/* clear pending interrupt */
+							/*
+							 * clear pending
+							 * interrupt
+							 */
 							outb(0, iobase +
 							     REG_INT_ID0 +
 							     port);
@@ -825,14 +873,21 @@
 
 			if (triggered) {
 				struct comedi_subdevice *s;
-				/* TODO here: dispatch io lines to subdevs with commands.. */
+				/*
+				 * TODO here: dispatch io lines to subdevs
+				 * with commands..
+				 */
 				printk
 				    ("PCMMIO DEBUG: got edge detect interrupt %d asic %d which_chans: %06x\n",
 				     irq, asic, triggered);
 				for (s = dev->subdevices + 2;
 				     s < dev->subdevices + dev->n_subdevices;
 				     ++s) {
-					if (subpriv->dio.intr.asic == asic) {	/* this is an interrupt subdev, and it matches this asic! */
+					/*
+					 * this is an interrupt subdev,
+					 * and it matches this asic!
+					 */
+					if (subpriv->dio.intr.asic == asic) {
 						unsigned long flags;
 						unsigned oldevents;
 
@@ -867,9 +922,8 @@
 								     n < len;
 								     n++) {
 									ch = CR_CHAN(s->async->cmd.chanlist[n]);
-									if (mytrig & (1U << ch)) {
+									if (mytrig & (1U << ch))
 										val |= (1U << n);
-									}
 								}
 								/* Write the scan to the buffer. */
 								if (comedi_buf_put(s->async, ((short *)&val)[0])
@@ -877,8 +931,7 @@
 								    comedi_buf_put
 								    (s->async,
 								     ((short *)
-								      &val)[1]))
-								{
+								      &val)[1])) {
 									s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
 								} else {
 									/* Overflow! Stop acquisition!! */
@@ -981,9 +1034,16 @@
 			 1) << subpriv->dio.intr.first_chan;
 		subpriv->dio.intr.enabled_mask = bits;
 
-		{		/* the below code configures the board to use a specific IRQ from 0-15. */
+		{
+			/*
+			 * the below code configures the board
+			 * to use a specific IRQ from 0-15.
+			 */
 			unsigned char b;
-			/* set resource enable register to enable IRQ operation */
+			/*
+			 * set resource enable register
+			 * to enable IRQ operation
+			 */
 			outb(1 << 4, dev->iobase + 3);
 			/* set bits 0-3 of b to the irq number from 0-15 */
 			b = dev->irq & ((1 << 4) - 1);
@@ -1037,14 +1097,12 @@
 
 	spin_lock_irqsave(&subpriv->dio.intr.spinlock, flags);
 	s->async->inttrig = 0;
-	if (subpriv->dio.intr.active) {
+	if (subpriv->dio.intr.active)
 		event = pcmmio_start_intr(dev, s);
-	}
 	spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags);
 
-	if (event) {
+	if (event)
 		comedi_event(dev, s);
-	}
 
 	return 1;
 }
@@ -1086,9 +1144,8 @@
 	}
 	spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags);
 
-	if (event) {
+	if (event)
 		comedi_event(dev, s);
-	}
 
 	return 0;
 }
@@ -1136,17 +1193,32 @@
 		short sample, adc_adjust = 0;
 
 		if (chan > 7)
-			chan -= 8, iooffset = 4;	/* use the second dword for channels > 7 */
+			chan -= 8, iooffset = 4;	/*
+							 * use the second dword
+							 * for channels > 7
+							 */
 
 		if (aref != AREF_DIFF) {
 			aref = AREF_GROUND;
-			command_byte |= 1 << 7;	/* set bit 7 to indicate single-ended */
+			command_byte |= 1 << 7;	/*
+						 * set bit 7 to indicate
+						 * single-ended
+						 */
 		}
 		if (range < 2)
-			adc_adjust = 0x8000;	/* bipolar ranges (-5,5 .. -10,10 need to be adjusted -- that is.. they need to wrap around by adding 0x8000 */
+			adc_adjust = 0x8000;	/*
+						 * bipolar ranges
+						 * (-5,5 .. -10,10 need to be
+						 * adjusted -- that is.. they
+						 * need to wrap around by
+						 * adding 0x8000
+						 */
 
 		if (chan % 2) {
-			command_byte |= 1 << 6;	/* odd-numbered channels have bit 6 set */
+			command_byte |= 1 << 6;	/*
+						 * odd-numbered channels
+						 * have bit 6 set
+						 */
 		}
 
 		/* select the channel, bits 4-5 == chan/2 */
@@ -1156,16 +1228,22 @@
 		command_byte |= (range & 0x3) << 2;
 
 		/* need to do this twice to make sure mux settled */
-		outb(command_byte, iobase + iooffset + 2);	/* chan/range/aref select */
+		/* chan/range/aref select */
+		outb(command_byte, iobase + iooffset + 2);
 
-		adc_wait_ready(iobase + iooffset);	/* wait for the adc to say it finised the conversion */
+		/* wait for the adc to say it finised the conversion */
+		adc_wait_ready(iobase + iooffset);
 
-		outb(command_byte, iobase + iooffset + 2);	/* select the chan/range/aref AGAIN */
+		/* select the chan/range/aref AGAIN */
+		outb(command_byte, iobase + iooffset + 2);
 
 		adc_wait_ready(iobase + iooffset);
 
-		sample = inb(iobase + iooffset + 0);	/* read data lo byte */
-		sample |= inb(iobase + iooffset + 1) << 8;	/* read data hi byte */
+		/* read data lo byte */
+		sample = inb(iobase + iooffset + 0);
+
+		/* read data hi byte */
+		sample |= inb(iobase + iooffset + 1) << 8;
 		sample += adc_adjust;	/* adjustment .. munge data */
 		data[n] = sample;
 	}
@@ -1227,15 +1305,24 @@
 
 			wait_dac_ready(iobase + iooffset);
 
-			outb(data[n] & 0xff, iobase + iooffset + 0);	/* low order byte */
-			outb((data[n] >> 8) & 0xff, iobase + iooffset + 1);	/* high order byte */
-			command_byte = 0x70 | (chan << 1);	/* set bit 4 of command byte to indicate data is loaded and trigger conversion */
+			/* low order byte */
+			outb(data[n] & 0xff, iobase + iooffset + 0);
+
+			/* high order byte */
+			outb((data[n] >> 8) & 0xff, iobase + iooffset + 1);
+
+			/*
+			 * set bit 4 of command byte to indicate
+			 * data is loaded and trigger conversion
+			 */
+			command_byte = 0x70 | (chan << 1);
 			/* trigger converion */
 			outb(command_byte, iobase + iooffset + 2);
 
 			wait_dac_ready(iobase + iooffset);
 
-			subpriv->ao.shadow_samples[chan] = data[n];	/* save to shadow register for ao_rinsn */
+			/* save to shadow register for ao_rinsn */
+			subpriv->ao.shadow_samples[chan] = data[n];
 		}
 	}
 	return n;
diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
index 5256fd9..3325f24 100644
--- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c
+++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
@@ -489,7 +489,7 @@
 
 	/* step 2: make sure trigger sources are unique and mutually compatible */
 
-	/* note that mutual compatiblity is not an issue here */
+	/* note that mutual compatibility is not an issue here */
 	if (cmd->scan_begin_src != TRIG_TIMER &&
 	    cmd->scan_begin_src != TRIG_FOLLOW)
 		err++;
diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c
index f35cce5..8626658 100644
--- a/drivers/staging/comedi/drivers/rtd520.c
+++ b/drivers/staging/comedi/drivers/rtd520.c
@@ -1768,7 +1768,7 @@
 
 	/* step 2: make sure trigger sources are unique
 	   and mutually compatible */
-	/* note that mutual compatiblity is not an issue here */
+	/* note that mutual compatibility is not an issue here */
 	if (cmd->scan_begin_src != TRIG_TIMER &&
 	    cmd->scan_begin_src != TRIG_EXT) {
 		err++;
diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c
index 80d2787..fdd7ab9 100644
--- a/drivers/staging/comedi/drivers/s626.c
+++ b/drivers/staging/comedi/drivers/s626.c
@@ -1926,7 +1926,7 @@
 	/* step 2: make sure trigger sources are unique and mutually
 	   compatible */
 
-	/* note that mutual compatiblity is not an issue here */
+	/* note that mutual compatibility is not an issue here */
 	if (cmd->scan_begin_src != TRIG_TIMER &&
 	    cmd->scan_begin_src != TRIG_EXT
 	    && cmd->scan_begin_src != TRIG_FOLLOW)
diff --git a/drivers/staging/comedi/drivers/s626.h b/drivers/staging/comedi/drivers/s626.h
index 1d04922..d02742a 100644
--- a/drivers/staging/comedi/drivers/s626.h
+++ b/drivers/staging/comedi/drivers/s626.h
@@ -76,14 +76,6 @@
 #define FALSE   (0)
 #endif
 
-#if !defined(EXTERN)
-#if defined(__cplusplus)
-#define EXTERN extern "C"
-#else
-#define EXTERN extern
-#endif
-#endif
-
 #if !defined(INLINE)
 #define INLINE static __inline
 #endif
diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c
index 82aa86e..db37dcd 100644
--- a/drivers/staging/comedi/drivers/serial2002.c
+++ b/drivers/staging/comedi/drivers/serial2002.c
@@ -125,14 +125,9 @@
 
 static long tty_ioctl(struct file *f, unsigned op, unsigned long param)
 {
-#ifdef HAVE_UNLOCKED_IOCTL
-	if (f->f_op->unlocked_ioctl) {
+	if (f->f_op->unlocked_ioctl)
 		return f->f_op->unlocked_ioctl(f, op, param);
-	}
-#endif
-	if (f->f_op->ioctl) {
-		return f->f_op->ioctl(f->f_dentry->d_inode, f, op, param);
-	}
+
 	return -ENOSYS;
 }
 
@@ -409,8 +404,8 @@
 	} else {
 		struct config_t {
 
-			int kind;
-			int bits;
+			short int kind;
+			short int bits;
 			int min;
 			int max;
 		};
diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c
index 3dee62a..aba57d9 100644
--- a/drivers/staging/comedi/drivers/skel.c
+++ b/drivers/staging/comedi/drivers/skel.c
@@ -399,7 +399,7 @@
 
 	/* step 2: make sure trigger sources are unique and mutually compatible */
 
-	/* note that mutual compatiblity is not an issue here */
+	/* note that mutual compatibility is not an issue here */
 	if (cmd->scan_begin_src != TRIG_TIMER &&
 	    cmd->scan_begin_src != TRIG_EXT)
 		err++;
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
index cca4e86..06c0204 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -1,4 +1,4 @@
-#define DRIVER_VERSION "v2.2"
+#define DRIVER_VERSION "v2.3"
 #define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com"
 #define DRIVER_DESC "Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com"
 /*
@@ -80,6 +80,7 @@
  * 2.0:  PWM seems to be stable and is not interfering with the other functions
  * 2.1:  changed PWM API
  * 2.2:  added firmware kernel request to fix an udev problem
+ * 2.3:  corrected a bug in bulk timeouts which were far too short
  *
  */
 
@@ -101,8 +102,8 @@
 
 #define BOARDNAME "usbdux"
 
-/* timeout for the USB-transfer */
-#define EZTIMEOUT 30
+/* timeout for the USB-transfer in ms*/
+#define BULK_TIMEOUT 1000
 
 /* constants for "firmware" upload and download */
 #define USBDUXSUB_FIRMWARE 0xA0
@@ -750,7 +751,7 @@
 				  /* Length */
 				  1,
 				  /* Timeout */
-				  EZTIMEOUT);
+				  BULK_TIMEOUT);
 	if (errcode < 0) {
 		dev_err(&usbduxsub->interface->dev,
 			"comedi_: control msg failed (start)\n");
@@ -780,7 +781,7 @@
 				  /* Length */
 				  1,
 				  /* Timeout */
-				  EZTIMEOUT);
+				  BULK_TIMEOUT);
 	if (errcode < 0) {
 		dev_err(&usbduxsub->interface->dev,
 			"comedi_: control msg failed (stop)\n");
@@ -810,7 +811,7 @@
 				  /* length */
 				  len,
 				  /* timeout */
-				  EZTIMEOUT);
+				  BULK_TIMEOUT);
 	dev_dbg(&usbduxsub->interface->dev, "comedi_: result=%d\n", errcode);
 	if (errcode < 0) {
 		dev_err(&usbduxsub->interface->dev, "comedi_: upload failed\n");
@@ -979,7 +980,7 @@
 
 	/*
 	 * step 2: make sure trigger sources are unique and mutually compatible
-	 * note that mutual compatiblity is not an issue here
+	 * note that mutual compatibility is not an issue here
 	 */
 	if (cmd->scan_begin_src != TRIG_FOLLOW &&
 	    cmd->scan_begin_src != TRIG_EXT &&
@@ -1110,7 +1111,7 @@
 			      usb_sndbulkpipe(this_usbduxsub->usbdev,
 					      COMMAND_OUT_EP),
 			      this_usbduxsub->dux_commands, SIZEOFDUXBUFFER,
-			      &nsent, 10);
+			      &nsent, BULK_TIMEOUT);
 	if (result < 0)
 		dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
 			"could not transmit dux_command to the usb-device, "
@@ -1130,7 +1131,7 @@
 				      usb_rcvbulkpipe(this_usbduxsub->usbdev,
 						      COMMAND_IN_EP),
 				      this_usbduxsub->insnBuffer, SIZEINSNBUF,
-				      &nrec, 1);
+				      &nrec, BULK_TIMEOUT);
 		if (result < 0) {
 			dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
 				"insn: USB error %d while receiving DUX command"
@@ -1557,7 +1558,7 @@
 
 	/*
 	 * step 2: make sure trigger sources are unique and mutually compatible
-	 * note that mutual compatiblity is not an issue here
+	 * note that mutual compatibility is not an issue here
 	 */
 	if (cmd->scan_begin_src != TRIG_FOLLOW &&
 	    cmd->scan_begin_src != TRIG_EXT &&
@@ -2327,9 +2328,11 @@
 	if (ret) {
 		dev_err(&usbdev->dev,
 			"Could not upload firmware (err=%d)\n", ret);
-		return;
+		goto out;
 	}
 	comedi_usb_auto_config(usbdev, BOARDNAME);
+ out:
+	release_firmware(fw);
 }
 
 /* allocate memory for the urbs and initialise them */
@@ -2580,6 +2583,7 @@
 				      FW_ACTION_HOTPLUG,
 				      "usbdux_firmware.bin",
 				      &udev->dev,
+				      GFP_KERNEL,
 				      usbduxsub + index,
 				      usbdux_firmware_request_complete_handler);
 
diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c
index d143222..2e675cc 100644
--- a/drivers/staging/comedi/drivers/usbduxfast.c
+++ b/drivers/staging/comedi/drivers/usbduxfast.c
@@ -1451,10 +1451,12 @@
 	if (ret) {
 		dev_err(&usbdev->dev,
 			"Could not upload firmware (err=%d)\n", ret);
-		return;
+		goto out;
 	}
 
 	comedi_usb_auto_config(usbdev, BOARDNAME);
+ out:
+	release_firmware(fw);
 }
 
 /*
@@ -1569,6 +1571,7 @@
 				      FW_ACTION_HOTPLUG,
 				      "usbduxfast_firmware.bin",
 				      &udev->dev,
+				      GFP_KERNEL,
 				      usbduxfastsub + index,
 				      usbduxfast_firmware_request_complete_handler);
 
diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c
index c335040..c34a0b9 100644
--- a/drivers/staging/comedi/drivers/vmk80xx.c
+++ b/drivers/staging/comedi/drivers/vmk80xx.c
@@ -76,18 +76,18 @@
 };
 
 static struct usb_device_id vmk80xx_id_table[] = {
-	{USB_DEVICE(0x10cf, 0x5500),.driver_info = DEVICE_VMK8055},
-	{USB_DEVICE(0x10cf, 0x5501),.driver_info = DEVICE_VMK8055},
-	{USB_DEVICE(0x10cf, 0x5502),.driver_info = DEVICE_VMK8055},
-	{USB_DEVICE(0x10cf, 0x5503),.driver_info = DEVICE_VMK8055},
-	{USB_DEVICE(0x10cf, 0x8061),.driver_info = DEVICE_VMK8061},
-	{USB_DEVICE(0x10cf, 0x8062),.driver_info = DEVICE_VMK8061},
-	{USB_DEVICE(0x10cf, 0x8063),.driver_info = DEVICE_VMK8061},
-	{USB_DEVICE(0x10cf, 0x8064),.driver_info = DEVICE_VMK8061},
-	{USB_DEVICE(0x10cf, 0x8065),.driver_info = DEVICE_VMK8061},
-	{USB_DEVICE(0x10cf, 0x8066),.driver_info = DEVICE_VMK8061},
-	{USB_DEVICE(0x10cf, 0x8067),.driver_info = DEVICE_VMK8061},
-	{USB_DEVICE(0x10cf, 0x8068),.driver_info = DEVICE_VMK8061},
+	{USB_DEVICE(0x10cf, 0x5500), .driver_info = DEVICE_VMK8055},
+	{USB_DEVICE(0x10cf, 0x5501), .driver_info = DEVICE_VMK8055},
+	{USB_DEVICE(0x10cf, 0x5502), .driver_info = DEVICE_VMK8055},
+	{USB_DEVICE(0x10cf, 0x5503), .driver_info = DEVICE_VMK8055},
+	{USB_DEVICE(0x10cf, 0x8061), .driver_info = DEVICE_VMK8061},
+	{USB_DEVICE(0x10cf, 0x8062), .driver_info = DEVICE_VMK8061},
+	{USB_DEVICE(0x10cf, 0x8063), .driver_info = DEVICE_VMK8061},
+	{USB_DEVICE(0x10cf, 0x8064), .driver_info = DEVICE_VMK8061},
+	{USB_DEVICE(0x10cf, 0x8065), .driver_info = DEVICE_VMK8061},
+	{USB_DEVICE(0x10cf, 0x8066), .driver_info = DEVICE_VMK8061},
+	{USB_DEVICE(0x10cf, 0x8067), .driver_info = DEVICE_VMK8061},
+	{USB_DEVICE(0x10cf, 0x8068), .driver_info = DEVICE_VMK8061},
 	{}			/* terminating entry */
 };
 
diff --git a/drivers/staging/cx25821/cx25821-core.c b/drivers/staging/cx25821/cx25821-core.c
index 8aceae5..67f689d 100644
--- a/drivers/staging/cx25821/cx25821-core.c
+++ b/drivers/staging/cx25821/cx25821-core.c
@@ -1521,7 +1521,7 @@
 	.resume = NULL,
 };
 
-static int cx25821_init(void)
+static int __init cx25821_init(void)
 {
 	INIT_LIST_HEAD(&cx25821_devlist);
 	printk(KERN_INFO "cx25821 driver version %d.%d.%d loaded\n",
@@ -1530,7 +1530,7 @@
 	return pci_register_driver(&cx25821_pci_driver);
 }
 
-static void cx25821_fini(void)
+static void __exit cx25821_fini(void)
 {
 	pci_unregister_driver(&cx25821_pci_driver);
 }
diff --git a/drivers/staging/dream/Kconfig b/drivers/staging/dream/Kconfig
index 52bd187..4afa081 100644
--- a/drivers/staging/dream/Kconfig
+++ b/drivers/staging/dream/Kconfig
@@ -1,3 +1,7 @@
+config DREAM
+       tristate "HTC Dream support"
+       depends on BROKEN
+
 source "drivers/staging/dream/smd/Kconfig"
 
 source "drivers/staging/dream/camera/Kconfig"
diff --git a/drivers/staging/dream/TODO b/drivers/staging/dream/TODO
new file mode 100644
index 0000000..c07c880
--- /dev/null
+++ b/drivers/staging/dream/TODO
@@ -0,0 +1,14 @@
+* remove support for wakelocks since those are not in mainline
+
+* camera driver uses old V4L API
+
+* coding style in some places is lacking
+
+* gpio_input.c has some features matrix_keypad lacks. They should be
+merged to gpio_input, with gpio_input.c removed
+
+* pmem provides interface for userspace. Needs to be reviewed at least.
+
+* it is probably possible to simplify touchscreen driver using threaded_irq's.
+
+* touchscreen driver should be switched to oficial multitouch API
diff --git a/drivers/staging/dream/camera/msm_camera.c b/drivers/staging/dream/camera/msm_camera.c
index 8816599..7d93877 100644
--- a/drivers/staging/dream/camera/msm_camera.c
+++ b/drivers/staging/dream/camera/msm_camera.c
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/sched.h>
 #include <mach/board.h>
 
 #include <linux/fs.h>
@@ -1597,7 +1598,6 @@
 		MSM_DRAIN_QUEUE(sync, pict_frame_q);
 
 		sync->sctrl.s_release();
-		wake_unlock(&sync->wake_lock);
 
 		sync->apps_id = NULL;
 		CDBG("msm_release completed!\n");
@@ -1806,7 +1806,6 @@
 	sync->apps_id = apps_id;
 
 	if (!sync->opencnt) {
-		wake_lock(&sync->wake_lock);
 
 		msm_camvfe_fn_init(&sync->vfefn, sync);
 		if (sync->vfefn.vfe_init) {
@@ -2044,8 +2043,6 @@
 	INIT_LIST_HEAD(&sync->pict_frame_q);
 	init_waitqueue_head(&sync->pict_frame_wait);
 
-	wake_lock_init(&sync->wake_lock, WAKE_LOCK_IDLE, "msm_camera");
-
 	rc = msm_camio_probe_on(pdev);
 	if (rc < 0)
 		return rc;
@@ -2058,7 +2055,6 @@
 	if (rc < 0) {
 		pr_err("msm_camera: failed to initialize %s\n",
 			sync->sdata->sensor_name);
-		wake_lock_destroy(&sync->wake_lock);
 		return rc;
 	}
 
@@ -2070,7 +2066,6 @@
 
 static int msm_sync_destroy(struct msm_sync *sync)
 {
-	wake_lock_destroy(&sync->wake_lock);
 	return 0;
 }
 
diff --git a/drivers/staging/dream/camera/msm_vfe7x.c b/drivers/staging/dream/camera/msm_vfe7x.c
index 5de96c5..33ab3ac 100644
--- a/drivers/staging/dream/camera/msm_vfe7x.c
+++ b/drivers/staging/dream/camera/msm_vfe7x.c
@@ -5,6 +5,7 @@
 #include <linux/msm_adsp.h>
 #include <linux/uaccess.h>
 #include <linux/fs.h>
+#include <linux/sched.h>
 #include <linux/android_pmem.h>
 #include <mach/msm_adsp.h>
 #include <linux/delay.h>
diff --git a/drivers/staging/dream/generic_gpio.c b/drivers/staging/dream/generic_gpio.c
new file mode 100644
index 0000000..fe24d38
--- /dev/null
+++ b/drivers/staging/dream/generic_gpio.c
@@ -0,0 +1,274 @@
+/* arch/arm/mach-msm/generic_gpio.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <asm/gpio.h>
+#include "gpio_chip.h"
+
+#define GPIO_NUM_TO_CHIP_INDEX(gpio) ((gpio)>>5)
+
+struct gpio_state {
+	unsigned long flags;
+	int refcount;
+};
+
+static DEFINE_SPINLOCK(gpio_chips_lock);
+static LIST_HEAD(gpio_chip_list);
+static struct gpio_chip **gpio_chip_array;
+static unsigned long gpio_chip_array_size;
+
+int register_gpio_chip(struct gpio_chip *new_gpio_chip)
+{
+	int err = 0;
+	struct gpio_chip *gpio_chip;
+	int i;
+	unsigned long irq_flags;
+	unsigned int chip_array_start_index, chip_array_end_index;
+
+	new_gpio_chip->state = kzalloc((new_gpio_chip->end + 1 - new_gpio_chip->start) * sizeof(new_gpio_chip->state[0]), GFP_KERNEL);
+	if (new_gpio_chip->state == NULL) {
+		printk(KERN_ERR "register_gpio_chip: failed to allocate state\n");
+		return -ENOMEM;
+	}
+
+	spin_lock_irqsave(&gpio_chips_lock, irq_flags);
+	chip_array_start_index = GPIO_NUM_TO_CHIP_INDEX(new_gpio_chip->start);
+	chip_array_end_index = GPIO_NUM_TO_CHIP_INDEX(new_gpio_chip->end);
+	if (chip_array_end_index >= gpio_chip_array_size) {
+		struct gpio_chip **new_gpio_chip_array;
+		unsigned long new_gpio_chip_array_size = chip_array_end_index + 1;
+
+		new_gpio_chip_array = kmalloc(new_gpio_chip_array_size * sizeof(new_gpio_chip_array[0]), GFP_ATOMIC);
+		if (new_gpio_chip_array == NULL) {
+			printk(KERN_ERR "register_gpio_chip: failed to allocate array\n");
+			err = -ENOMEM;
+			goto failed;
+		}
+		for (i = 0; i < gpio_chip_array_size; i++)
+			new_gpio_chip_array[i] = gpio_chip_array[i];
+		for (i = gpio_chip_array_size; i < new_gpio_chip_array_size; i++)
+			new_gpio_chip_array[i] = NULL;
+		gpio_chip_array = new_gpio_chip_array;
+		gpio_chip_array_size = new_gpio_chip_array_size;
+	}
+	list_for_each_entry(gpio_chip, &gpio_chip_list, list) {
+		if (gpio_chip->start > new_gpio_chip->end) {
+			list_add_tail(&new_gpio_chip->list, &gpio_chip->list);
+			goto added;
+		}
+		if (gpio_chip->end >= new_gpio_chip->start) {
+			printk(KERN_ERR "register_gpio_source %u-%u overlaps with %u-%u\n",
+			       new_gpio_chip->start, new_gpio_chip->end,
+			       gpio_chip->start, gpio_chip->end);
+			err = -EBUSY;
+			goto failed;
+		}
+	}
+	list_add_tail(&new_gpio_chip->list, &gpio_chip_list);
+added:
+	for (i = chip_array_start_index; i <= chip_array_end_index; i++) {
+		if (gpio_chip_array[i] == NULL || gpio_chip_array[i]->start > new_gpio_chip->start)
+			gpio_chip_array[i] = new_gpio_chip;
+	}
+failed:
+	spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
+	if (err)
+		kfree(new_gpio_chip->state);
+	return err;
+}
+
+static struct gpio_chip *get_gpio_chip_locked(unsigned int gpio)
+{
+	unsigned long i;
+	struct gpio_chip *chip;
+
+	i = GPIO_NUM_TO_CHIP_INDEX(gpio);
+	if (i >= gpio_chip_array_size)
+		return NULL;
+	chip = gpio_chip_array[i];
+	if (chip == NULL)
+		return NULL;
+	list_for_each_entry_from(chip, &gpio_chip_list, list) {
+		if (gpio < chip->start)
+			return NULL;
+		if (gpio <= chip->end)
+			return chip;
+	}
+	return NULL;
+}
+
+static int request_gpio(unsigned int gpio, unsigned long flags)
+{
+	int err = 0;
+	struct gpio_chip *chip;
+	unsigned long irq_flags;
+	unsigned long chip_index;
+
+	spin_lock_irqsave(&gpio_chips_lock, irq_flags);
+	chip = get_gpio_chip_locked(gpio);
+	if (chip == NULL) {
+		err = -EINVAL;
+		goto err;
+	}
+	chip_index = gpio - chip->start;
+	if (chip->state[chip_index].refcount == 0) {
+		chip->configure(chip, gpio, flags);
+		chip->state[chip_index].flags = flags;
+		chip->state[chip_index].refcount++;
+	} else if ((flags & IRQF_SHARED) && (chip->state[chip_index].flags & IRQF_SHARED))
+		chip->state[chip_index].refcount++;
+	else
+		err = -EBUSY;
+err:
+	spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
+	return err;
+}
+
+int gpio_request(unsigned gpio, const char *label)
+{
+	return request_gpio(gpio, 0);
+}
+EXPORT_SYMBOL(gpio_request);
+
+void gpio_free(unsigned gpio)
+{
+	struct gpio_chip *chip;
+	unsigned long irq_flags;
+	unsigned long chip_index;
+
+	spin_lock_irqsave(&gpio_chips_lock, irq_flags);
+	chip = get_gpio_chip_locked(gpio);
+	if (chip) {
+		chip_index = gpio - chip->start;
+		chip->state[chip_index].refcount--;
+	}
+	spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
+}
+EXPORT_SYMBOL(gpio_free);
+
+static int gpio_get_irq_num(unsigned int gpio, unsigned int *irqp, unsigned long *irqnumflagsp)
+{
+	int ret = -ENOTSUPP;
+	struct gpio_chip *chip;
+	unsigned long irq_flags;
+
+	spin_lock_irqsave(&gpio_chips_lock, irq_flags);
+	chip = get_gpio_chip_locked(gpio);
+	if (chip && chip->get_irq_num)
+		ret = chip->get_irq_num(chip, gpio, irqp, irqnumflagsp);
+	spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
+	return ret;
+}
+
+int gpio_to_irq(unsigned gpio)
+{
+	int ret, irq;
+	ret = gpio_get_irq_num(gpio, &irq, NULL);
+	if (ret)
+		return ret;
+	return irq;
+}
+EXPORT_SYMBOL(gpio_to_irq);
+
+int gpio_configure(unsigned int gpio, unsigned long flags)
+{
+	int ret = -ENOTSUPP;
+	struct gpio_chip *chip;
+	unsigned long irq_flags;
+
+	spin_lock_irqsave(&gpio_chips_lock, irq_flags);
+	chip = get_gpio_chip_locked(gpio);
+	if (chip)
+		ret = chip->configure(chip, gpio, flags);
+	spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
+	return ret;
+}
+EXPORT_SYMBOL(gpio_configure);
+
+int gpio_direction_input(unsigned gpio)
+{
+	return gpio_configure(gpio, GPIOF_INPUT);
+}
+EXPORT_SYMBOL(gpio_direction_input);
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+	gpio_set_value(gpio, value);
+	return gpio_configure(gpio, GPIOF_DRIVE_OUTPUT);
+}
+EXPORT_SYMBOL(gpio_direction_output);
+
+int gpio_get_value(unsigned gpio)
+{
+	int ret = -ENOTSUPP;
+	struct gpio_chip *chip;
+	unsigned long irq_flags;
+
+	spin_lock_irqsave(&gpio_chips_lock, irq_flags);
+	chip = get_gpio_chip_locked(gpio);
+	if (chip && chip->read)
+		ret = chip->read(chip, gpio);
+	spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
+	return ret;
+}
+EXPORT_SYMBOL(gpio_get_value);
+
+void gpio_set_value(unsigned gpio, int on)
+{
+	int ret = -ENOTSUPP;
+	struct gpio_chip *chip;
+	unsigned long irq_flags;
+
+	spin_lock_irqsave(&gpio_chips_lock, irq_flags);
+	chip = get_gpio_chip_locked(gpio);
+	if (chip && chip->write)
+		ret = chip->write(chip, gpio, on);
+	spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
+}
+EXPORT_SYMBOL(gpio_set_value);
+
+int gpio_read_detect_status(unsigned int gpio)
+{
+	int ret = -ENOTSUPP;
+	struct gpio_chip *chip;
+	unsigned long irq_flags;
+
+	spin_lock_irqsave(&gpio_chips_lock, irq_flags);
+	chip = get_gpio_chip_locked(gpio);
+	if (chip && chip->read_detect_status)
+		ret = chip->read_detect_status(chip, gpio);
+	spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
+	return ret;
+}
+EXPORT_SYMBOL(gpio_read_detect_status);
+
+int gpio_clear_detect_status(unsigned int gpio)
+{
+	int ret = -ENOTSUPP;
+	struct gpio_chip *chip;
+	unsigned long irq_flags;
+
+	spin_lock_irqsave(&gpio_chips_lock, irq_flags);
+	chip = get_gpio_chip_locked(gpio);
+	if (chip && chip->clear_detect_status)
+		ret = chip->clear_detect_status(chip, gpio);
+	spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
+	return ret;
+}
+EXPORT_SYMBOL(gpio_clear_detect_status);
diff --git a/drivers/staging/dream/gpio_event.c b/drivers/staging/dream/gpio_event.c
index 8b64c1e..e60e2c0 100644
--- a/drivers/staging/dream/gpio_event.c
+++ b/drivers/staging/dream/gpio_event.c
@@ -13,7 +13,7 @@
  *
  */
 
-#include <linux/earlysuspend.h>
+
 #include <linux/module.h>
 #include <linux/input.h>
 #include <linux/gpio_event.h>
@@ -23,7 +23,6 @@
 struct gpio_event {
 	struct input_dev *input_dev;
 	const struct gpio_event_platform_data *info;
-	struct early_suspend early_suspend;
 	void *state[0];
 };
 
diff --git a/drivers/staging/dream/gpio_input.c b/drivers/staging/dream/gpio_input.c
index 7e307f2..0638ec4 100644
--- a/drivers/staging/dream/gpio_input.c
+++ b/drivers/staging/dream/gpio_input.c
@@ -19,7 +19,6 @@
 #include <linux/hrtimer.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
-#include <linux/wakelock.h>
 
 enum {
 	DEBOUNCE_UNSTABLE     = BIT(0),	/* Got irq, while debouncing */
@@ -44,7 +43,6 @@
 	int use_irq;
 	int debounce_count;
 	spinlock_t irq_lock;
-	struct wake_lock wake_lock;
 	struct gpio_key_state key_state[0];
 };
 
@@ -143,8 +141,6 @@
 		hrtimer_start(timer, ds->info->debounce_time, HRTIMER_MODE_REL);
 	else if (!ds->use_irq)
 		hrtimer_start(timer, ds->info->poll_time, HRTIMER_MODE_REL);
-	else
-		wake_unlock(&ds->wake_lock);
 
 	spin_unlock_irqrestore(&ds->irq_lock, irqflags);
 
@@ -170,7 +166,6 @@
 		if (ks->debounce & DEBOUNCE_WAIT_IRQ) {
 			ks->debounce = DEBOUNCE_UNKNOWN;
 			if (ds->debounce_count++ == 0) {
-				wake_lock(&ds->wake_lock);
 				hrtimer_start(
 					&ds->timer, ds->info->debounce_time,
 					HRTIMER_MODE_REL);
@@ -277,7 +272,6 @@
 		ds->debounce_count = di->keymap_size;
 		ds->input_dev = input_dev;
 		ds->info = di;
-		wake_lock_init(&ds->wake_lock, WAKE_LOCK_SUSPEND, "gpio_input");
 		spin_lock_init(&ds->irq_lock);
 
 		for (i = 0; i < di->keymap_size; i++) {
@@ -336,7 +330,6 @@
 err_gpio_request_failed:
 		;
 	}
-	wake_lock_destroy(&ds->wake_lock);
 	kfree(ds);
 err_ds_alloc_failed:
 	return ret;
diff --git a/drivers/staging/dream/gpio_matrix.c b/drivers/staging/dream/gpio_matrix.c
index c1f4765..796de4f 100644
--- a/drivers/staging/dream/gpio_matrix.c
+++ b/drivers/staging/dream/gpio_matrix.c
@@ -18,13 +18,11 @@
 #include <linux/gpio_event.h>
 #include <linux/hrtimer.h>
 #include <linux/interrupt.h>
-#include <linux/wakelock.h>
 
 struct gpio_kp {
 	struct input_dev *input_dev;
 	struct gpio_event_matrix_info *keypad_info;
 	struct hrtimer timer;
-	struct wake_lock wake_lock;
 	int current_output;
 	unsigned int use_irq:1;
 	unsigned int key_state_changed:1;
@@ -199,7 +197,6 @@
 	}
 	for (in = 0; in < mi->ninputs; in++)
 		enable_irq(gpio_to_irq(mi->input_gpios[in]));
-	wake_unlock(&kp->wake_lock);
 	return HRTIMER_NORESTART;
 }
 
@@ -222,7 +219,6 @@
 		else
 			gpio_direction_input(mi->output_gpios[i]);
 	}
-	wake_lock(&kp->wake_lock);
 	hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
 	return IRQ_HANDLED;
 }
@@ -363,7 +359,6 @@
 
 		hrtimer_init(&kp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
 		kp->timer.function = gpio_keypad_timer_func;
-		wake_lock_init(&kp->wake_lock, WAKE_LOCK_SUSPEND, "gpio_kp");
 		err = gpio_keypad_request_irqs(kp);
 		kp->use_irq = err == 0;
 
@@ -371,8 +366,6 @@
 			"in %s mode\n", input_dev->name,
 			kp->use_irq ? "interrupt" : "polling");
 
-		if (kp->use_irq)
-			wake_lock(&kp->wake_lock);
 		hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
 
 		return 0;
@@ -386,7 +379,6 @@
 			free_irq(gpio_to_irq(mi->input_gpios[i]), kp);
 
 	hrtimer_cancel(&kp->timer);
-	wake_lock_destroy(&kp->wake_lock);
 	for (i = mi->noutputs - 1; i >= 0; i--) {
 err_gpio_direction_input_failed:
 		gpio_free(mi->input_gpios[i]);
diff --git a/drivers/staging/dream/pmem.c b/drivers/staging/dream/pmem.c
new file mode 100644
index 0000000..def6468
--- /dev/null
+++ b/drivers/staging/dream/pmem.c
@@ -0,0 +1,1335 @@
+/* drivers/android/pmem.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/mm.h>
+#include <linux/list.h>
+#include <linux/debugfs.h>
+#include <linux/android_pmem.h>
+#include <linux/mempolicy.h>
+#include <linux/sched.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/cacheflush.h>
+
+#define PMEM_MAX_DEVICES 10
+#define PMEM_MAX_ORDER 128
+#define PMEM_MIN_ALLOC PAGE_SIZE
+
+#define PMEM_DEBUG 1
+
+/* indicates that a refernce to this file has been taken via get_pmem_file,
+ * the file should not be released until put_pmem_file is called */
+#define PMEM_FLAGS_BUSY 0x1
+/* indicates that this is a suballocation of a larger master range */
+#define PMEM_FLAGS_CONNECTED 0x1 << 1
+/* indicates this is a master and not a sub allocation and that it is mmaped */
+#define PMEM_FLAGS_MASTERMAP 0x1 << 2
+/* submap and unsubmap flags indicate:
+ * 00: subregion has never been mmaped
+ * 10: subregion has been mmaped, reference to the mm was taken
+ * 11: subretion has ben released, refernece to the mm still held
+ * 01: subretion has been released, reference to the mm has been released
+ */
+#define PMEM_FLAGS_SUBMAP 0x1 << 3
+#define PMEM_FLAGS_UNSUBMAP 0x1 << 4
+
+
+struct pmem_data {
+	/* in alloc mode: an index into the bitmap
+	 * in no_alloc mode: the size of the allocation */
+	int index;
+	/* see flags above for descriptions */
+	unsigned int flags;
+	/* protects this data field, if the mm_mmap sem will be held at the
+	 * same time as this sem, the mm sem must be taken first (as this is
+	 * the order for vma_open and vma_close ops */
+	struct rw_semaphore sem;
+	/* info about the mmaping process */
+	struct vm_area_struct *vma;
+	/* task struct of the mapping process */
+	struct task_struct *task;
+	/* process id of teh mapping process */
+	pid_t pid;
+	/* file descriptor of the master */
+	int master_fd;
+	/* file struct of the master */
+	struct file *master_file;
+	/* a list of currently available regions if this is a suballocation */
+	struct list_head region_list;
+	/* a linked list of data so we can access them for debugging */
+	struct list_head list;
+#if PMEM_DEBUG
+	int ref;
+#endif
+};
+
+struct pmem_bits {
+	unsigned allocated:1;		/* 1 if allocated, 0 if free */
+	unsigned order:7;		/* size of the region in pmem space */
+};
+
+struct pmem_region_node {
+	struct pmem_region region;
+	struct list_head list;
+};
+
+#define PMEM_DEBUG_MSGS 0
+#if PMEM_DEBUG_MSGS
+#define DLOG(fmt,args...) \
+	do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \
+		    ##args); } \
+	while (0)
+#else
+#define DLOG(x...) do {} while (0)
+#endif
+
+struct pmem_info {
+	struct miscdevice dev;
+	/* physical start address of the remaped pmem space */
+	unsigned long base;
+	/* vitual start address of the remaped pmem space */
+	unsigned char __iomem *vbase;
+	/* total size of the pmem space */
+	unsigned long size;
+	/* number of entries in the pmem space */
+	unsigned long num_entries;
+	/* pfn of the garbage page in memory */
+	unsigned long garbage_pfn;
+	/* index of the garbage page in the pmem space */
+	int garbage_index;
+	/* the bitmap for the region indicating which entries are allocated
+	 * and which are free */
+	struct pmem_bits *bitmap;
+	/* indicates the region should not be managed with an allocator */
+	unsigned no_allocator;
+	/* indicates maps of this region should be cached, if a mix of
+	 * cached and uncached is desired, set this and open the device with
+	 * O_SYNC to get an uncached region */
+	unsigned cached;
+	unsigned buffered;
+	/* in no_allocator mode the first mapper gets the whole space and sets
+	 * this flag */
+	unsigned allocated;
+	/* for debugging, creates a list of pmem file structs, the
+	 * data_list_sem should be taken before pmem_data->sem if both are
+	 * needed */
+	struct semaphore data_list_sem;
+	struct list_head data_list;
+	/* pmem_sem protects the bitmap array
+	 * a write lock should be held when modifying entries in bitmap
+	 * a read lock should be held when reading data from bits or
+	 * dereferencing a pointer into bitmap
+	 *
+	 * pmem_data->sem protects the pmem data of a particular file
+	 * Many of the function that require the pmem_data->sem have a non-
+	 * locking version for when the caller is already holding that sem.
+	 *
+	 * IF YOU TAKE BOTH LOCKS TAKE THEM IN THIS ORDER:
+	 * down(pmem_data->sem) => down(bitmap_sem)
+	 */
+	struct rw_semaphore bitmap_sem;
+
+	long (*ioctl)(struct file *, unsigned int, unsigned long);
+	int (*release)(struct inode *, struct file *);
+};
+
+static struct pmem_info pmem[PMEM_MAX_DEVICES];
+static int id_count;
+
+#define PMEM_IS_FREE(id, index) !(pmem[id].bitmap[index].allocated)
+#define PMEM_ORDER(id, index) pmem[id].bitmap[index].order
+#define PMEM_BUDDY_INDEX(id, index) (index ^ (1 << PMEM_ORDER(id, index)))
+#define PMEM_NEXT_INDEX(id, index) (index + (1 << PMEM_ORDER(id, index)))
+#define PMEM_OFFSET(index) (index * PMEM_MIN_ALLOC)
+#define PMEM_START_ADDR(id, index) (PMEM_OFFSET(index) + pmem[id].base)
+#define PMEM_LEN(id, index) ((1 << PMEM_ORDER(id, index)) * PMEM_MIN_ALLOC)
+#define PMEM_END_ADDR(id, index) (PMEM_START_ADDR(id, index) + \
+	PMEM_LEN(id, index))
+#define PMEM_START_VADDR(id, index) (PMEM_OFFSET(id, index) + pmem[id].vbase)
+#define PMEM_END_VADDR(id, index) (PMEM_START_VADDR(id, index) + \
+	PMEM_LEN(id, index))
+#define PMEM_REVOKED(data) (data->flags & PMEM_FLAGS_REVOKED)
+#define PMEM_IS_PAGE_ALIGNED(addr) (!((addr) & (~PAGE_MASK)))
+#define PMEM_IS_SUBMAP(data) ((data->flags & PMEM_FLAGS_SUBMAP) && \
+	(!(data->flags & PMEM_FLAGS_UNSUBMAP)))
+
+static int pmem_release(struct inode *, struct file *);
+static int pmem_mmap(struct file *, struct vm_area_struct *);
+static int pmem_open(struct inode *, struct file *);
+static long pmem_ioctl(struct file *, unsigned int, unsigned long);
+
+struct file_operations pmem_fops = {
+	.release = pmem_release,
+	.mmap = pmem_mmap,
+	.open = pmem_open,
+	.unlocked_ioctl = pmem_ioctl,
+};
+
+static int get_id(struct file *file)
+{
+	return MINOR(file->f_dentry->d_inode->i_rdev);
+}
+
+static int is_pmem_file(struct file *file)
+{
+	int id;
+
+	if (unlikely(!file || !file->f_dentry || !file->f_dentry->d_inode))
+		return 0;
+	id = get_id(file);
+	if (unlikely(id >= PMEM_MAX_DEVICES))
+		return 0;
+	if (unlikely(file->f_dentry->d_inode->i_rdev !=
+	     MKDEV(MISC_MAJOR, pmem[id].dev.minor)))
+		return 0;
+	return 1;
+}
+
+static int has_allocation(struct file *file)
+{
+	struct pmem_data *data;
+	/* check is_pmem_file first if not accessed via pmem_file_ops */
+
+	if (unlikely(!file->private_data))
+		return 0;
+	data = (struct pmem_data *)file->private_data;
+	if (unlikely(data->index < 0))
+		return 0;
+	return 1;
+}
+
+static int is_master_owner(struct file *file)
+{
+	struct file *master_file;
+	struct pmem_data *data;
+	int put_needed, ret = 0;
+
+	if (!is_pmem_file(file) || !has_allocation(file))
+		return 0;
+	data = (struct pmem_data *)file->private_data;
+	if (PMEM_FLAGS_MASTERMAP & data->flags)
+		return 1;
+	master_file = fget_light(data->master_fd, &put_needed);
+	if (master_file && data->master_file == master_file)
+		ret = 1;
+	fput_light(master_file, put_needed);
+	return ret;
+}
+
+static int pmem_free(int id, int index)
+{
+	/* caller should hold the write lock on pmem_sem! */
+	int buddy, curr = index;
+	DLOG("index %d\n", index);
+
+	if (pmem[id].no_allocator) {
+		pmem[id].allocated = 0;
+		return 0;
+	}
+	/* clean up the bitmap, merging any buddies */
+	pmem[id].bitmap[curr].allocated = 0;
+	/* find a slots buddy Buddy# = Slot# ^ (1 << order)
+	 * if the buddy is also free merge them
+	 * repeat until the buddy is not free or end of the bitmap is reached
+	 */
+	do {
+		buddy = PMEM_BUDDY_INDEX(id, curr);
+		if (PMEM_IS_FREE(id, buddy) &&
+				PMEM_ORDER(id, buddy) == PMEM_ORDER(id, curr)) {
+			PMEM_ORDER(id, buddy)++;
+			PMEM_ORDER(id, curr)++;
+			curr = min(buddy, curr);
+		} else {
+			break;
+		}
+	} while (curr < pmem[id].num_entries);
+
+	return 0;
+}
+
+static void pmem_revoke(struct file *file, struct pmem_data *data);
+
+static int pmem_release(struct inode *inode, struct file *file)
+{
+	struct pmem_data *data = (struct pmem_data *)file->private_data;
+	struct pmem_region_node *region_node;
+	struct list_head *elt, *elt2;
+	int id = get_id(file), ret = 0;
+
+
+	down(&pmem[id].data_list_sem);
+	/* if this file is a master, revoke all the memory in the connected
+	 *  files */
+	if (PMEM_FLAGS_MASTERMAP & data->flags) {
+		struct pmem_data *sub_data;
+		list_for_each(elt, &pmem[id].data_list) {
+			sub_data = list_entry(elt, struct pmem_data, list);
+			down_read(&sub_data->sem);
+			if (PMEM_IS_SUBMAP(sub_data) &&
+			    file == sub_data->master_file) {
+				up_read(&sub_data->sem);
+				pmem_revoke(file, sub_data);
+			}  else
+				up_read(&sub_data->sem);
+		}
+	}
+	list_del(&data->list);
+	up(&pmem[id].data_list_sem);
+
+
+	down_write(&data->sem);
+
+	/* if its not a conencted file and it has an allocation, free it */
+	if (!(PMEM_FLAGS_CONNECTED & data->flags) && has_allocation(file)) {
+		down_write(&pmem[id].bitmap_sem);
+		ret = pmem_free(id, data->index);
+		up_write(&pmem[id].bitmap_sem);
+	}
+
+	/* if this file is a submap (mapped, connected file), downref the
+	 * task struct */
+	if (PMEM_FLAGS_SUBMAP & data->flags)
+		if (data->task) {
+			put_task_struct(data->task);
+			data->task = NULL;
+		}
+
+	file->private_data = NULL;
+
+	list_for_each_safe(elt, elt2, &data->region_list) {
+		region_node = list_entry(elt, struct pmem_region_node, list);
+		list_del(elt);
+		kfree(region_node);
+	}
+	BUG_ON(!list_empty(&data->region_list));
+
+	up_write(&data->sem);
+	kfree(data);
+	if (pmem[id].release)
+		ret = pmem[id].release(inode, file);
+
+	return ret;
+}
+
+static int pmem_open(struct inode *inode, struct file *file)
+{
+	struct pmem_data *data;
+	int id = get_id(file);
+	int ret = 0;
+
+	DLOG("current %u file %p(%d)\n", current->pid, file, file_count(file));
+	/* setup file->private_data to indicate its unmapped */
+	/*  you can only open a pmem device one time */
+	if (file->private_data != NULL)
+		return -1;
+	data = kmalloc(sizeof(struct pmem_data), GFP_KERNEL);
+	if (!data) {
+		printk("pmem: unable to allocate memory for pmem metadata.");
+		return -1;
+	}
+	data->flags = 0;
+	data->index = -1;
+	data->task = NULL;
+	data->vma = NULL;
+	data->pid = 0;
+	data->master_file = NULL;
+#if PMEM_DEBUG
+	data->ref = 0;
+#endif
+	INIT_LIST_HEAD(&data->region_list);
+	init_rwsem(&data->sem);
+
+	file->private_data = data;
+	INIT_LIST_HEAD(&data->list);
+
+	down(&pmem[id].data_list_sem);
+	list_add(&data->list, &pmem[id].data_list);
+	up(&pmem[id].data_list_sem);
+	return ret;
+}
+
+static unsigned long pmem_order(unsigned long len)
+{
+	int i;
+
+	len = (len + PMEM_MIN_ALLOC - 1)/PMEM_MIN_ALLOC;
+	len--;
+	for (i = 0; i < sizeof(len)*8; i++)
+		if (len >> i == 0)
+			break;
+	return i;
+}
+
+static int pmem_allocate(int id, unsigned long len)
+{
+	/* caller should hold the write lock on pmem_sem! */
+	/* return the corresponding pdata[] entry */
+	int curr = 0;
+	int end = pmem[id].num_entries;
+	int best_fit = -1;
+	unsigned long order = pmem_order(len);
+
+	if (pmem[id].no_allocator) {
+		DLOG("no allocator");
+		if ((len > pmem[id].size) || pmem[id].allocated)
+			return -1;
+		pmem[id].allocated = 1;
+		return len;
+	}
+
+	if (order > PMEM_MAX_ORDER)
+		return -1;
+	DLOG("order %lx\n", order);
+
+	/* look through the bitmap:
+	 * 	if you find a free slot of the correct order use it
+	 * 	otherwise, use the best fit (smallest with size > order) slot
+	 */
+	while (curr < end) {
+		if (PMEM_IS_FREE(id, curr)) {
+			if (PMEM_ORDER(id, curr) == (unsigned char)order) {
+				/* set the not free bit and clear others */
+				best_fit = curr;
+				break;
+			}
+			if (PMEM_ORDER(id, curr) > (unsigned char)order &&
+			    (best_fit < 0 ||
+			     PMEM_ORDER(id, curr) < PMEM_ORDER(id, best_fit)))
+				best_fit = curr;
+		}
+		curr = PMEM_NEXT_INDEX(id, curr);
+	}
+
+	/* if best_fit < 0, there are no suitable slots,
+	 * return an error
+	 */
+	if (best_fit < 0) {
+		printk("pmem: no space left to allocate!\n");
+		return -1;
+	}
+
+	/* now partition the best fit:
+	 * 	split the slot into 2 buddies of order - 1
+	 * 	repeat until the slot is of the correct order
+	 */
+	while (PMEM_ORDER(id, best_fit) > (unsigned char)order) {
+		int buddy;
+		PMEM_ORDER(id, best_fit) -= 1;
+		buddy = PMEM_BUDDY_INDEX(id, best_fit);
+		PMEM_ORDER(id, buddy) = PMEM_ORDER(id, best_fit);
+	}
+	pmem[id].bitmap[best_fit].allocated = 1;
+	return best_fit;
+}
+
+static pgprot_t phys_mem_access_prot(struct file *file, pgprot_t vma_prot)
+{
+	int id = get_id(file);
+#ifdef pgprot_noncached
+	if (pmem[id].cached == 0 || file->f_flags & O_SYNC)
+		return pgprot_noncached(vma_prot);
+#endif
+#ifdef pgprot_ext_buffered
+	else if (pmem[id].buffered)
+		return pgprot_ext_buffered(vma_prot);
+#endif
+	return vma_prot;
+}
+
+static unsigned long pmem_start_addr(int id, struct pmem_data *data)
+{
+	if (pmem[id].no_allocator)
+		return PMEM_START_ADDR(id, 0);
+	else
+		return PMEM_START_ADDR(id, data->index);
+
+}
+
+static void *pmem_start_vaddr(int id, struct pmem_data *data)
+{
+	return pmem_start_addr(id, data) - pmem[id].base + pmem[id].vbase;
+}
+
+static unsigned long pmem_len(int id, struct pmem_data *data)
+{
+	if (pmem[id].no_allocator)
+		return data->index;
+	else
+		return PMEM_LEN(id, data->index);
+}
+
+static int pmem_map_garbage(int id, struct vm_area_struct *vma,
+			    struct pmem_data *data, unsigned long offset,
+			    unsigned long len)
+{
+	int i, garbage_pages = len >> PAGE_SHIFT;
+
+	vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP | VM_SHARED | VM_WRITE;
+	for (i = 0; i < garbage_pages; i++) {
+		if (vm_insert_pfn(vma, vma->vm_start + offset + (i * PAGE_SIZE),
+		    pmem[id].garbage_pfn))
+			return -EAGAIN;
+	}
+	return 0;
+}
+
+static int pmem_unmap_pfn_range(int id, struct vm_area_struct *vma,
+				struct pmem_data *data, unsigned long offset,
+				unsigned long len)
+{
+	int garbage_pages;
+	DLOG("unmap offset %lx len %lx\n", offset, len);
+
+	BUG_ON(!PMEM_IS_PAGE_ALIGNED(len));
+
+	garbage_pages = len >> PAGE_SHIFT;
+	zap_page_range(vma, vma->vm_start + offset, len, NULL);
+	pmem_map_garbage(id, vma, data, offset, len);
+	return 0;
+}
+
+static int pmem_map_pfn_range(int id, struct vm_area_struct *vma,
+			      struct pmem_data *data, unsigned long offset,
+			      unsigned long len)
+{
+	DLOG("map offset %lx len %lx\n", offset, len);
+	BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_start));
+	BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_end));
+	BUG_ON(!PMEM_IS_PAGE_ALIGNED(len));
+	BUG_ON(!PMEM_IS_PAGE_ALIGNED(offset));
+
+	if (io_remap_pfn_range(vma, vma->vm_start + offset,
+		(pmem_start_addr(id, data) + offset) >> PAGE_SHIFT,
+		len, vma->vm_page_prot)) {
+		return -EAGAIN;
+	}
+	return 0;
+}
+
+static int pmem_remap_pfn_range(int id, struct vm_area_struct *vma,
+			      struct pmem_data *data, unsigned long offset,
+			      unsigned long len)
+{
+	/* hold the mm semp for the vma you are modifying when you call this */
+	BUG_ON(!vma);
+	zap_page_range(vma, vma->vm_start + offset, len, NULL);
+	return pmem_map_pfn_range(id, vma, data, offset, len);
+}
+
+static void pmem_vma_open(struct vm_area_struct *vma)
+{
+	struct file *file = vma->vm_file;
+	struct pmem_data *data = file->private_data;
+	int id = get_id(file);
+	/* this should never be called as we don't support copying pmem
+	 * ranges via fork */
+	BUG_ON(!has_allocation(file));
+	down_write(&data->sem);
+	/* remap the garbage pages, forkers don't get access to the data */
+	pmem_unmap_pfn_range(id, vma, data, 0, vma->vm_start - vma->vm_end);
+	up_write(&data->sem);
+}
+
+static void pmem_vma_close(struct vm_area_struct *vma)
+{
+	struct file *file = vma->vm_file;
+	struct pmem_data *data = file->private_data;
+
+	DLOG("current %u ppid %u file %p count %d\n", current->pid,
+	     current->parent->pid, file, file_count(file));
+	if (unlikely(!is_pmem_file(file) || !has_allocation(file))) {
+		printk(KERN_WARNING "pmem: something is very wrong, you are "
+		       "closing a vm backing an allocation that doesn't "
+		       "exist!\n");
+		return;
+	}
+	down_write(&data->sem);
+	if (data->vma == vma) {
+		data->vma = NULL;
+		if ((data->flags & PMEM_FLAGS_CONNECTED) &&
+		    (data->flags & PMEM_FLAGS_SUBMAP))
+			data->flags |= PMEM_FLAGS_UNSUBMAP;
+	}
+	/* the kernel is going to free this vma now anyway */
+	up_write(&data->sem);
+}
+
+static struct vm_operations_struct vm_ops = {
+	.open = pmem_vma_open,
+	.close = pmem_vma_close,
+};
+
+static int pmem_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct pmem_data *data;
+	int index;
+	unsigned long vma_size =  vma->vm_end - vma->vm_start;
+	int ret = 0, id = get_id(file);
+
+	if (vma->vm_pgoff || !PMEM_IS_PAGE_ALIGNED(vma_size)) {
+#if PMEM_DEBUG
+		printk(KERN_ERR "pmem: mmaps must be at offset zero, aligned"
+				" and a multiple of pages_size.\n");
+#endif
+		return -EINVAL;
+	}
+
+	data = (struct pmem_data *)file->private_data;
+	down_write(&data->sem);
+	/* check this file isn't already mmaped, for submaps check this file
+	 * has never been mmaped */
+	if ((data->flags & PMEM_FLAGS_MASTERMAP) ||
+	    (data->flags & PMEM_FLAGS_SUBMAP) ||
+	    (data->flags & PMEM_FLAGS_UNSUBMAP)) {
+#if PMEM_DEBUG
+		printk(KERN_ERR "pmem: you can only mmap a pmem file once, "
+		       "this file is already mmaped. %x\n", data->flags);
+#endif
+		ret = -EINVAL;
+		goto error;
+	}
+	/* if file->private_data == unalloced, alloc*/
+	if (data && data->index == -1) {
+		down_write(&pmem[id].bitmap_sem);
+		index = pmem_allocate(id, vma->vm_end - vma->vm_start);
+		up_write(&pmem[id].bitmap_sem);
+		data->index = index;
+	}
+	/* either no space was available or an error occured */
+	if (!has_allocation(file)) {
+		ret = -EINVAL;
+		printk("pmem: could not find allocation for map.\n");
+		goto error;
+	}
+
+	if (pmem_len(id, data) < vma_size) {
+#if PMEM_DEBUG
+		printk(KERN_WARNING "pmem: mmap size [%lu] does not match"
+		       "size of backing region [%lu].\n", vma_size,
+		       pmem_len(id, data));
+#endif
+		ret = -EINVAL;
+		goto error;
+	}
+
+	vma->vm_pgoff = pmem_start_addr(id, data) >> PAGE_SHIFT;
+	vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_page_prot);
+
+	if (data->flags & PMEM_FLAGS_CONNECTED) {
+		struct pmem_region_node *region_node;
+		struct list_head *elt;
+		if (pmem_map_garbage(id, vma, data, 0, vma_size)) {
+			printk("pmem: mmap failed in kernel!\n");
+			ret = -EAGAIN;
+			goto error;
+		}
+		list_for_each(elt, &data->region_list) {
+			region_node = list_entry(elt, struct pmem_region_node,
+						 list);
+			DLOG("remapping file: %p %lx %lx\n", file,
+				region_node->region.offset,
+				region_node->region.len);
+			if (pmem_remap_pfn_range(id, vma, data,
+						 region_node->region.offset,
+						 region_node->region.len)) {
+				ret = -EAGAIN;
+				goto error;
+			}
+		}
+		data->flags |= PMEM_FLAGS_SUBMAP;
+		get_task_struct(current->group_leader);
+		data->task = current->group_leader;
+		data->vma = vma;
+#if PMEM_DEBUG
+		data->pid = current->pid;
+#endif
+		DLOG("submmapped file %p vma %p pid %u\n", file, vma,
+		     current->pid);
+	} else {
+		if (pmem_map_pfn_range(id, vma, data, 0, vma_size)) {
+			printk(KERN_INFO "pmem: mmap failed in kernel!\n");
+			ret = -EAGAIN;
+			goto error;
+		}
+		data->flags |= PMEM_FLAGS_MASTERMAP;
+		data->pid = current->pid;
+	}
+	vma->vm_ops = &vm_ops;
+error:
+	up_write(&data->sem);
+	return ret;
+}
+
+/* the following are the api for accessing pmem regions by other drivers
+ * from inside the kernel */
+int get_pmem_user_addr(struct file *file, unsigned long *start,
+		   unsigned long *len)
+{
+	struct pmem_data *data;
+	if (!is_pmem_file(file) || !has_allocation(file)) {
+#if PMEM_DEBUG
+		printk(KERN_INFO "pmem: requested pmem data from invalid"
+				  "file.\n");
+#endif
+		return -1;
+	}
+	data = (struct pmem_data *)file->private_data;
+	down_read(&data->sem);
+	if (data->vma) {
+		*start = data->vma->vm_start;
+		*len = data->vma->vm_end - data->vma->vm_start;
+	} else {
+		*start = 0;
+		*len = 0;
+	}
+	up_read(&data->sem);
+	return 0;
+}
+
+int get_pmem_addr(struct file *file, unsigned long *start,
+		  unsigned long *vstart, unsigned long *len)
+{
+	struct pmem_data *data;
+	int id;
+
+	if (!is_pmem_file(file) || !has_allocation(file)) {
+		return -1;
+	}
+
+	data = (struct pmem_data *)file->private_data;
+	if (data->index == -1) {
+#if PMEM_DEBUG
+		printk(KERN_INFO "pmem: requested pmem data from file with no "
+		       "allocation.\n");
+		return -1;
+#endif
+	}
+	id = get_id(file);
+
+	down_read(&data->sem);
+	*start = pmem_start_addr(id, data);
+	*len = pmem_len(id, data);
+	*vstart = (unsigned long)pmem_start_vaddr(id, data);
+	up_read(&data->sem);
+#if PMEM_DEBUG
+	down_write(&data->sem);
+	data->ref++;
+	up_write(&data->sem);
+#endif
+	return 0;
+}
+
+int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart,
+		  unsigned long *len, struct file **filp)
+{
+	struct file *file;
+
+	file = fget(fd);
+	if (unlikely(file == NULL)) {
+		printk(KERN_INFO "pmem: requested data from file descriptor "
+		       "that doesn't exist.");
+		return -1;
+	}
+
+	if (get_pmem_addr(file, start, vstart, len))
+		goto end;
+
+	if (filp)
+		*filp = file;
+	return 0;
+end:
+	fput(file);
+	return -1;
+}
+
+void put_pmem_file(struct file *file)
+{
+	struct pmem_data *data;
+	int id;
+
+	if (!is_pmem_file(file))
+		return;
+	id = get_id(file);
+	data = (struct pmem_data *)file->private_data;
+#if PMEM_DEBUG
+	down_write(&data->sem);
+	if (data->ref == 0) {
+		printk("pmem: pmem_put > pmem_get %s (pid %d)\n",
+		       pmem[id].dev.name, data->pid);
+		BUG();
+	}
+	data->ref--;
+	up_write(&data->sem);
+#endif
+	fput(file);
+}
+
+void flush_pmem_file(struct file *file, unsigned long offset, unsigned long len)
+{
+	struct pmem_data *data;
+	int id;
+	void *vaddr;
+	struct pmem_region_node *region_node;
+	struct list_head *elt;
+	void *flush_start, *flush_end;
+
+	if (!is_pmem_file(file) || !has_allocation(file)) {
+		return;
+	}
+
+	id = get_id(file);
+	data = (struct pmem_data *)file->private_data;
+	if (!pmem[id].cached)
+		return;
+
+	down_read(&data->sem);
+	vaddr = pmem_start_vaddr(id, data);
+	/* if this isn't a submmapped file, flush the whole thing */
+	if (unlikely(!(data->flags & PMEM_FLAGS_CONNECTED))) {
+		dmac_flush_range(vaddr, vaddr + pmem_len(id, data));
+		goto end;
+	}
+	/* otherwise, flush the region of the file we are drawing */
+	list_for_each(elt, &data->region_list) {
+		region_node = list_entry(elt, struct pmem_region_node, list);
+		if ((offset >= region_node->region.offset) &&
+		    ((offset + len) <= (region_node->region.offset +
+			region_node->region.len))) {
+			flush_start = vaddr + region_node->region.offset;
+			flush_end = flush_start + region_node->region.len;
+			dmac_flush_range(flush_start, flush_end);
+			break;
+		}
+	}
+end:
+	up_read(&data->sem);
+}
+
+static int pmem_connect(unsigned long connect, struct file *file)
+{
+	struct pmem_data *data = (struct pmem_data *)file->private_data;
+	struct pmem_data *src_data;
+	struct file *src_file;
+	int ret = 0, put_needed;
+
+	down_write(&data->sem);
+	/* retrieve the src file and check it is a pmem file with an alloc */
+	src_file = fget_light(connect, &put_needed);
+	DLOG("connect %p to %p\n", file, src_file);
+	if (!src_file) {
+		printk("pmem: src file not found!\n");
+		ret = -EINVAL;
+		goto err_no_file;
+	}
+	if (unlikely(!is_pmem_file(src_file) || !has_allocation(src_file))) {
+		printk(KERN_INFO "pmem: src file is not a pmem file or has no "
+		       "alloc!\n");
+		ret = -EINVAL;
+		goto err_bad_file;
+	}
+	src_data = (struct pmem_data *)src_file->private_data;
+
+	if (has_allocation(file) && (data->index != src_data->index)) {
+		printk("pmem: file is already mapped but doesn't match this"
+		       " src_file!\n");
+		ret = -EINVAL;
+		goto err_bad_file;
+	}
+	data->index = src_data->index;
+	data->flags |= PMEM_FLAGS_CONNECTED;
+	data->master_fd = connect;
+	data->master_file = src_file;
+
+err_bad_file:
+	fput_light(src_file, put_needed);
+err_no_file:
+	up_write(&data->sem);
+	return ret;
+}
+
+static void pmem_unlock_data_and_mm(struct pmem_data *data,
+				    struct mm_struct *mm)
+{
+	up_write(&data->sem);
+	if (mm != NULL) {
+		up_write(&mm->mmap_sem);
+		mmput(mm);
+	}
+}
+
+static int pmem_lock_data_and_mm(struct file *file, struct pmem_data *data,
+				 struct mm_struct **locked_mm)
+{
+	int ret = 0;
+	struct mm_struct *mm = NULL;
+	*locked_mm = NULL;
+lock_mm:
+	down_read(&data->sem);
+	if (PMEM_IS_SUBMAP(data)) {
+		mm = get_task_mm(data->task);
+		if (!mm) {
+#if PMEM_DEBUG
+			printk("pmem: can't remap task is gone!\n");
+#endif
+			up_read(&data->sem);
+			return -1;
+		}
+	}
+	up_read(&data->sem);
+
+	if (mm)
+		down_write(&mm->mmap_sem);
+
+	down_write(&data->sem);
+	/* check that the file didn't get mmaped before we could take the
+	 * data sem, this should be safe b/c you can only submap each file
+	 * once */
+	if (PMEM_IS_SUBMAP(data) && !mm) {
+		pmem_unlock_data_and_mm(data, mm);
+		up_write(&data->sem);
+		goto lock_mm;
+	}
+	/* now check that vma.mm is still there, it could have been
+	 * deleted by vma_close before we could get the data->sem */
+	if ((data->flags & PMEM_FLAGS_UNSUBMAP) && (mm != NULL)) {
+		/* might as well release this */
+		if (data->flags & PMEM_FLAGS_SUBMAP) {
+			put_task_struct(data->task);
+			data->task = NULL;
+			/* lower the submap flag to show the mm is gone */
+			data->flags &= ~(PMEM_FLAGS_SUBMAP);
+		}
+		pmem_unlock_data_and_mm(data, mm);
+		return -1;
+	}
+	*locked_mm = mm;
+	return ret;
+}
+
+int pmem_remap(struct pmem_region *region, struct file *file,
+		      unsigned operation)
+{
+	int ret;
+	struct pmem_region_node *region_node;
+	struct mm_struct *mm = NULL;
+	struct list_head *elt, *elt2;
+	int id = get_id(file);
+	struct pmem_data *data = (struct pmem_data *)file->private_data;
+
+	/* pmem region must be aligned on a page boundry */
+	if (unlikely(!PMEM_IS_PAGE_ALIGNED(region->offset) ||
+		 !PMEM_IS_PAGE_ALIGNED(region->len))) {
+#if PMEM_DEBUG
+		printk("pmem: request for unaligned pmem suballocation "
+		       "%lx %lx\n", region->offset, region->len);
+#endif
+		return -EINVAL;
+	}
+
+	/* if userspace requests a region of len 0, there's nothing to do */
+	if (region->len == 0)
+		return 0;
+
+	/* lock the mm and data */
+	ret = pmem_lock_data_and_mm(file, data, &mm);
+	if (ret)
+		return 0;
+
+	/* only the owner of the master file can remap the client fds
+	 * that back in it */
+	if (!is_master_owner(file)) {
+#if PMEM_DEBUG
+		printk("pmem: remap requested from non-master process\n");
+#endif
+		ret = -EINVAL;
+		goto err;
+	}
+
+	/* check that the requested range is within the src allocation */
+	if (unlikely((region->offset > pmem_len(id, data)) ||
+		     (region->len > pmem_len(id, data)) ||
+		     (region->offset + region->len > pmem_len(id, data)))) {
+#if PMEM_DEBUG
+		printk(KERN_INFO "pmem: suballoc doesn't fit in src_file!\n");
+#endif
+		ret = -EINVAL;
+		goto err;
+	}
+
+	if (operation == PMEM_MAP) {
+		region_node = kmalloc(sizeof(struct pmem_region_node),
+			      GFP_KERNEL);
+		if (!region_node) {
+			ret = -ENOMEM;
+#if PMEM_DEBUG
+			printk(KERN_INFO "No space to allocate metadata!");
+#endif
+			goto err;
+		}
+		region_node->region = *region;
+		list_add(&region_node->list, &data->region_list);
+	} else if (operation == PMEM_UNMAP) {
+		int found = 0;
+		list_for_each_safe(elt, elt2, &data->region_list) {
+			region_node = list_entry(elt, struct pmem_region_node,
+				      list);
+			if (region->len == 0 ||
+			    (region_node->region.offset == region->offset &&
+			    region_node->region.len == region->len)) {
+				list_del(elt);
+				kfree(region_node);
+				found = 1;
+			}
+		}
+		if (!found) {
+#if PMEM_DEBUG
+			printk("pmem: Unmap region does not map any mapped "
+				"region!");
+#endif
+			ret = -EINVAL;
+			goto err;
+		}
+	}
+
+	if (data->vma && PMEM_IS_SUBMAP(data)) {
+		if (operation == PMEM_MAP)
+			ret = pmem_remap_pfn_range(id, data->vma, data,
+						   region->offset, region->len);
+		else if (operation == PMEM_UNMAP)
+			ret = pmem_unmap_pfn_range(id, data->vma, data,
+						   region->offset, region->len);
+	}
+
+err:
+	pmem_unlock_data_and_mm(data, mm);
+	return ret;
+}
+
+static void pmem_revoke(struct file *file, struct pmem_data *data)
+{
+	struct pmem_region_node *region_node;
+	struct list_head *elt, *elt2;
+	struct mm_struct *mm = NULL;
+	int id = get_id(file);
+	int ret = 0;
+
+	data->master_file = NULL;
+	ret = pmem_lock_data_and_mm(file, data, &mm);
+	/* if lock_data_and_mm fails either the task that mapped the fd, or
+	 * the vma that mapped it have already gone away, nothing more
+	 * needs to be done */
+	if (ret)
+		return;
+	/* unmap everything */
+	/* delete the regions and region list nothing is mapped any more */
+	if (data->vma)
+		list_for_each_safe(elt, elt2, &data->region_list) {
+			region_node = list_entry(elt, struct pmem_region_node,
+						 list);
+			pmem_unmap_pfn_range(id, data->vma, data,
+					     region_node->region.offset,
+					     region_node->region.len);
+			list_del(elt);
+			kfree(region_node);
+	}
+	/* delete the master file */
+	pmem_unlock_data_and_mm(data, mm);
+}
+
+static void pmem_get_size(struct pmem_region *region, struct file *file)
+{
+	struct pmem_data *data = (struct pmem_data *)file->private_data;
+	int id = get_id(file);
+
+	if (!has_allocation(file)) {
+		region->offset = 0;
+		region->len = 0;
+		return;
+	} else {
+		region->offset = pmem_start_addr(id, data);
+		region->len = pmem_len(id, data);
+	}
+	DLOG("offset %lx len %lx\n", region->offset, region->len);
+}
+
+
+static long pmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct pmem_data *data;
+	int id = get_id(file);
+
+	switch (cmd) {
+	case PMEM_GET_PHYS:
+		{
+			struct pmem_region region;
+			DLOG("get_phys\n");
+			if (!has_allocation(file)) {
+				region.offset = 0;
+				region.len = 0;
+			} else {
+				data = (struct pmem_data *)file->private_data;
+				region.offset = pmem_start_addr(id, data);
+				region.len = pmem_len(id, data);
+			}
+			printk(KERN_INFO "pmem: request for physical address of pmem region "
+					"from process %d.\n", current->pid);
+			if (copy_to_user((void __user *)arg, &region,
+						sizeof(struct pmem_region)))
+				return -EFAULT;
+			break;
+		}
+	case PMEM_MAP:
+		{
+			struct pmem_region region;
+			if (copy_from_user(&region, (void __user *)arg,
+						sizeof(struct pmem_region)))
+				return -EFAULT;
+			data = (struct pmem_data *)file->private_data;
+			return pmem_remap(&region, file, PMEM_MAP);
+		}
+		break;
+	case PMEM_UNMAP:
+		{
+			struct pmem_region region;
+			if (copy_from_user(&region, (void __user *)arg,
+						sizeof(struct pmem_region)))
+				return -EFAULT;
+			data = (struct pmem_data *)file->private_data;
+			return pmem_remap(&region, file, PMEM_UNMAP);
+			break;
+		}
+	case PMEM_GET_SIZE:
+		{
+			struct pmem_region region;
+			DLOG("get_size\n");
+			pmem_get_size(&region, file);
+			if (copy_to_user((void __user *)arg, &region,
+						sizeof(struct pmem_region)))
+				return -EFAULT;
+			break;
+		}
+	case PMEM_GET_TOTAL_SIZE:
+		{
+			struct pmem_region region;
+			DLOG("get total size\n");
+			region.offset = 0;
+			get_id(file);
+			region.len = pmem[id].size;
+			if (copy_to_user((void __user *)arg, &region,
+						sizeof(struct pmem_region)))
+				return -EFAULT;
+			break;
+		}
+	case PMEM_ALLOCATE:
+		{
+			if (has_allocation(file))
+				return -EINVAL;
+			data = (struct pmem_data *)file->private_data;
+			data->index = pmem_allocate(id, arg);
+			break;
+		}
+	case PMEM_CONNECT:
+		DLOG("connect\n");
+		return pmem_connect(arg, file);
+		break;
+	default:
+		if (pmem[id].ioctl)
+			return pmem[id].ioctl(file, cmd, arg);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+#if PMEM_DEBUG
+static ssize_t debug_open(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+static ssize_t debug_read(struct file *file, char __user *buf, size_t count,
+			  loff_t *ppos)
+{
+	struct list_head *elt, *elt2;
+	struct pmem_data *data;
+	struct pmem_region_node *region_node;
+	int id = (int)file->private_data;
+	const int debug_bufmax = 4096;
+	static char buffer[4096];
+	int n = 0;
+
+	DLOG("debug open\n");
+	n = scnprintf(buffer, debug_bufmax,
+		      "pid #: mapped regions (offset, len) (offset,len)...\n");
+
+	down(&pmem[id].data_list_sem);
+	list_for_each(elt, &pmem[id].data_list) {
+		data = list_entry(elt, struct pmem_data, list);
+		down_read(&data->sem);
+		n += scnprintf(buffer + n, debug_bufmax - n, "pid %u:",
+				data->pid);
+		list_for_each(elt2, &data->region_list) {
+			region_node = list_entry(elt2, struct pmem_region_node,
+				      list);
+			n += scnprintf(buffer + n, debug_bufmax - n,
+					"(%lx,%lx) ",
+					region_node->region.offset,
+					region_node->region.len);
+		}
+		n += scnprintf(buffer + n, debug_bufmax - n, "\n");
+		up_read(&data->sem);
+	}
+	up(&pmem[id].data_list_sem);
+
+	n++;
+	buffer[n] = 0;
+	return simple_read_from_buffer(buf, count, ppos, buffer, n);
+}
+
+static struct file_operations debug_fops = {
+	.read = debug_read,
+	.open = debug_open,
+};
+#endif
+
+#if 0
+static struct miscdevice pmem_dev = {
+	.name = "pmem",
+	.fops = &pmem_fops,
+};
+#endif
+
+int pmem_setup(struct android_pmem_platform_data *pdata,
+	       long (*ioctl)(struct file *, unsigned int, unsigned long),
+	       int (*release)(struct inode *, struct file *))
+{
+	int err = 0;
+	int i, index = 0;
+	int id = id_count;
+	id_count++;
+
+	pmem[id].no_allocator = pdata->no_allocator;
+	pmem[id].cached = pdata->cached;
+	pmem[id].buffered = pdata->buffered;
+	pmem[id].base = pdata->start;
+	pmem[id].size = pdata->size;
+	pmem[id].ioctl = ioctl;
+	pmem[id].release = release;
+	init_rwsem(&pmem[id].bitmap_sem);
+	init_MUTEX(&pmem[id].data_list_sem);
+	INIT_LIST_HEAD(&pmem[id].data_list);
+	pmem[id].dev.name = pdata->name;
+	pmem[id].dev.minor = id;
+	pmem[id].dev.fops = &pmem_fops;
+	printk(KERN_INFO "%s: %d init\n", pdata->name, pdata->cached);
+
+	err = misc_register(&pmem[id].dev);
+	if (err) {
+		printk(KERN_ALERT "Unable to register pmem driver!\n");
+		goto err_cant_register_device;
+	}
+	pmem[id].num_entries = pmem[id].size / PMEM_MIN_ALLOC;
+
+	pmem[id].bitmap = kmalloc(pmem[id].num_entries *
+				  sizeof(struct pmem_bits), GFP_KERNEL);
+	if (!pmem[id].bitmap)
+		goto err_no_mem_for_metadata;
+
+	memset(pmem[id].bitmap, 0, sizeof(struct pmem_bits) *
+					  pmem[id].num_entries);
+
+	for (i = sizeof(pmem[id].num_entries) * 8 - 1; i >= 0; i--) {
+		if ((pmem[id].num_entries) &  1<<i) {
+			PMEM_ORDER(id, index) = i;
+			index = PMEM_NEXT_INDEX(id, index);
+		}
+	}
+
+	if (pmem[id].cached)
+		pmem[id].vbase = ioremap_cached(pmem[id].base,
+						pmem[id].size);
+#ifdef ioremap_ext_buffered
+	else if (pmem[id].buffered)
+		pmem[id].vbase = ioremap_ext_buffered(pmem[id].base,
+						      pmem[id].size);
+#endif
+	else
+		pmem[id].vbase = ioremap(pmem[id].base, pmem[id].size);
+
+	if (pmem[id].vbase == 0)
+		goto error_cant_remap;
+
+	pmem[id].garbage_pfn = page_to_pfn(alloc_page(GFP_KERNEL));
+	if (pmem[id].no_allocator)
+		pmem[id].allocated = 0;
+
+#if PMEM_DEBUG
+	debugfs_create_file(pdata->name, S_IFREG | S_IRUGO, NULL, (void *)id,
+			    &debug_fops);
+#endif
+	return 0;
+error_cant_remap:
+	kfree(pmem[id].bitmap);
+err_no_mem_for_metadata:
+	misc_deregister(&pmem[id].dev);
+err_cant_register_device:
+	return -1;
+}
+
+static int pmem_probe(struct platform_device *pdev)
+{
+	struct android_pmem_platform_data *pdata;
+
+	if (!pdev || !pdev->dev.platform_data) {
+		printk(KERN_ALERT "Unable to probe pmem!\n");
+		return -1;
+	}
+	pdata = pdev->dev.platform_data;
+	return pmem_setup(pdata, NULL, NULL);
+}
+
+
+static int pmem_remove(struct platform_device *pdev)
+{
+	int id = pdev->id;
+	__free_page(pfn_to_page(pmem[id].garbage_pfn));
+	misc_deregister(&pmem[id].dev);
+	return 0;
+}
+
+static struct platform_driver pmem_driver = {
+	.probe = pmem_probe,
+	.remove = pmem_remove,
+	.driver = { .name = "android_pmem" }
+};
+
+
+static int __init pmem_init(void)
+{
+	return platform_driver_register(&pmem_driver);
+}
+
+static void __exit pmem_exit(void)
+{
+	platform_driver_unregister(&pmem_driver);
+}
+
+module_init(pmem_init);
+module_exit(pmem_exit);
+
diff --git a/drivers/staging/dream/qdsp5/adsp.c b/drivers/staging/dream/qdsp5/adsp.c
index d096456..9069535 100644
--- a/drivers/staging/dream/qdsp5/adsp.c
+++ b/drivers/staging/dream/qdsp5/adsp.c
@@ -32,16 +32,12 @@
 #include <linux/module.h>
 #include <linux/uaccess.h>
 #include <linux/wait.h>
-#include <linux/wakelock.h>
 
-static struct wake_lock adsp_wake_lock;
 static inline void prevent_suspend(void)
 {
-	wake_lock(&adsp_wake_lock);
 }
 static inline void allow_suspend(void)
 {
-	wake_unlock(&adsp_wake_lock);
 }
 
 #include <linux/io.h>
@@ -1046,7 +1042,6 @@
 
 	pr_info("adsp: probe\n");
 
-	wake_lock_init(&adsp_wake_lock, WAKE_LOCK_SUSPEND, "adsp");
 #if CONFIG_MSM_AMSS_VERSION >= 6350
 	adsp_info.init_info_ptr = kzalloc(
 		(sizeof(struct adsp_rtos_mp_mtoa_init_info_type)), GFP_KERNEL);
diff --git a/drivers/staging/dream/qdsp5/audio_out.c b/drivers/staging/dream/qdsp5/audio_out.c
index d1adcf6..df87ca3 100644
--- a/drivers/staging/dream/qdsp5/audio_out.c
+++ b/drivers/staging/dream/qdsp5/audio_out.c
@@ -38,8 +38,6 @@
 #include <mach/qdsp5/qdsp5audppcmdi.h>
 #include <mach/qdsp5/qdsp5audppmsg.h>
 
-#include <mach/htc_pwrsink.h>
-
 #include "evlog.h"
 
 #define LOG_AUDIO_EVENTS 1
@@ -260,7 +258,6 @@
 	}
 
 	audio->enabled = 1;
-	htc_pwrsink_set(PWRSINK_AUDIO, 100);
 	return 0;
 }
 
@@ -695,7 +692,6 @@
 	audio_flush(audio);
 	audio->opened = 0;
 	mutex_unlock(&audio->lock);
-	htc_pwrsink_set(PWRSINK_AUDIO, 0);
 	return 0;
 }
 
diff --git a/drivers/staging/dream/smd/smd_qmi.c b/drivers/staging/dream/smd/smd_qmi.c
index d4e7d88..687db14 100644
--- a/drivers/staging/dream/smd/smd_qmi.c
+++ b/drivers/staging/dream/smd/smd_qmi.c
@@ -24,7 +24,6 @@
 #include <linux/wait.h>
 #include <linux/miscdevice.h>
 #include <linux/workqueue.h>
-#include <linux/wakelock.h>
 
 #include <asm/uaccess.h>
 #include <mach/msm_smd.h>
@@ -74,7 +73,6 @@
 
 	smd_channel_t *ch;
 	const char *ch_name;
-	struct wake_lock wake_lock;
 
 	struct work_struct open_work;
 	struct work_struct read_work;
@@ -90,7 +88,6 @@
 	mutex_init(&ctxt->lock);
 	INIT_WORK(&ctxt->read_work, qmi_read_work);
 	INIT_WORK(&ctxt->open_work, qmi_open_work);
-	wake_lock_init(&ctxt->wake_lock, WAKE_LOCK_SUSPEND, ctxt->misc.name);
 	ctxt->ctl_txn_id = 1;
 	ctxt->wds_txn_id = 1;
 	ctxt->wds_busy = 1;
@@ -454,7 +451,6 @@
 		break;
 	}
 	mutex_unlock(&ctxt->lock);
-
 	wake_up(&qmi_wait_queue);
 }
 
@@ -509,7 +505,6 @@
 		int sz;
 		sz = smd_cur_packet_size(ctxt->ch);
 		if ((sz > 0) && (sz <= smd_read_avail(ctxt->ch))) {
-			wake_lock_timeout(&ctxt->wake_lock, HZ / 2);
 			queue_work(qmi_wq, &ctxt->read_work);
 		}
 		break;
diff --git a/drivers/staging/dream/smd/smd_rpcrouter.c b/drivers/staging/dream/smd/smd_rpcrouter.c
index d4a4a88..5ac2cd4 100644
--- a/drivers/staging/dream/smd/smd_rpcrouter.c
+++ b/drivers/staging/dream/smd/smd_rpcrouter.c
@@ -33,7 +33,6 @@
 #include <linux/err.h>
 #include <linux/sched.h>
 #include <linux/poll.h>
-#include <linux/wakelock.h>
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
 #include <linux/platform_device.h>
@@ -96,7 +95,6 @@
 static DEFINE_SPINLOCK(smd_lock);
 
 static struct workqueue_struct *rpcrouter_workqueue;
-static struct wake_lock rpcrouter_wake_lock;
 static int rpcrouter_need_len;
 
 static atomic_t next_xid = ATOMIC_INIT(1);
@@ -290,7 +288,6 @@
 	init_waitqueue_head(&ept->wait_q);
 	INIT_LIST_HEAD(&ept->read_q);
 	spin_lock_init(&ept->read_q_lock);
-	wake_lock_init(&ept->read_q_wake_lock, WAKE_LOCK_SUSPEND, "rpc_read");
 	INIT_LIST_HEAD(&ept->incomplete);
 
 	spin_lock_irqsave(&local_endpoints_lock, flags);
@@ -313,7 +310,6 @@
 	if (rc < 0)
 		return rc;
 
-	wake_lock_destroy(&ept->read_q_wake_lock);
 	list_del(&ept->list);
 	kfree(ept);
 	return 0;
@@ -540,8 +536,6 @@
 	if (event != SMD_EVENT_DATA)
 		return;
 
-	if (smd_read_avail(smd_channel) >= rpcrouter_need_len)
-		wake_lock(&rpcrouter_wake_lock);
 	wake_up(&smd_wait);
 }
 
@@ -576,7 +570,6 @@
 				return -EIO;
 		}
 		rpcrouter_need_len = len;
-		wake_unlock(&rpcrouter_wake_lock);
 		spin_unlock_irqrestore(&smd_lock, flags);
 
 //		printk("rr_read: waiting (%d)\n", len);
@@ -676,7 +669,6 @@
 
 packet_complete:
 	spin_lock_irqsave(&ept->read_q_lock, flags);
-	wake_lock(&ept->read_q_wake_lock);
 	list_add_tail(&pkt->list, &ept->read_q);
 	wake_up(&ept->wait_q);
 	spin_unlock_irqrestore(&ept->read_q_lock, flags);
@@ -699,7 +691,6 @@
 fail_io:
 fail_data:
 	printk(KERN_ERR "rpc_router has died\n");
-	wake_unlock(&rpcrouter_wake_lock);
 }
 
 void msm_rpc_setup_req(struct rpc_request_hdr *hdr, uint32_t prog,
@@ -1061,8 +1052,6 @@
 		return -ETOOSMALL;
 	}
 	list_del(&pkt->list);
-	if (list_empty(&ept->read_q))
-		wake_unlock(&ept->read_q_wake_lock);
 	spin_unlock_irqrestore(&ept->read_q_lock, flags);
 
 	rc = pkt->length;
@@ -1229,7 +1218,6 @@
 
 	init_waitqueue_head(&newserver_wait);
 	init_waitqueue_head(&smd_wait);
-	wake_lock_init(&rpcrouter_wake_lock, WAKE_LOCK_SUSPEND, "SMD_RPCCALL");
 
 	rpcrouter_workqueue = create_singlethread_workqueue("rpcrouter");
 	if (!rpcrouter_workqueue)
diff --git a/drivers/staging/dream/smd/smd_rpcrouter.h b/drivers/staging/dream/smd/smd_rpcrouter.h
index a7416a2..86ab997 100644
--- a/drivers/staging/dream/smd/smd_rpcrouter.h
+++ b/drivers/staging/dream/smd/smd_rpcrouter.h
@@ -22,7 +22,6 @@
 #include <linux/list.h>
 #include <linux/cdev.h>
 #include <linux/platform_device.h>
-#include <linux/wakelock.h>
 
 #include <mach/msm_smd.h>
 #include <mach/msm_rpcrouter.h>
@@ -144,7 +143,6 @@
 	/* complete packets waiting to be read */
 	struct list_head read_q;
 	spinlock_t read_q_lock;
-	struct wake_lock read_q_wake_lock;
 	wait_queue_head_t wait_q;
 	unsigned flags;
 
diff --git a/drivers/staging/dream/smd/smd_tty.c b/drivers/staging/dream/smd/smd_tty.c
index 2edd9d1..f409449 100644
--- a/drivers/staging/dream/smd/smd_tty.c
+++ b/drivers/staging/dream/smd/smd_tty.c
@@ -19,7 +19,6 @@
 #include <linux/cdev.h>
 #include <linux/device.h>
 #include <linux/wait.h>
-#include <linux/wakelock.h>
 
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
@@ -34,7 +33,6 @@
 struct smd_tty_info {
 	smd_channel_t *ch;
 	struct tty_struct *tty;
-	struct wake_lock wake_lock;
 	int open_count;
 };
 
@@ -69,7 +67,6 @@
 			printk(KERN_ERR "OOPS - smd_tty_buffer mismatch?!");
 		}
 
-		wake_lock_timeout(&info->wake_lock, HZ / 2);
 		tty_flip_buffer_push(tty);
 	}
 
@@ -95,7 +92,6 @@
 	info = smd_tty + n;
 
 	mutex_lock(&smd_tty_lock);
-	wake_lock_init(&info->wake_lock, WAKE_LOCK_SUSPEND, name);
 	tty->driver_data = info;
 
 	if (info->open_count++ == 0) {
@@ -122,7 +118,6 @@
 	if (--info->open_count == 0) {
 		info->tty = 0;
 		tty->driver_data = 0;
-		wake_lock_destroy(&info->wake_lock);
 		if (info->ch) {
 			smd_close(info->ch);
 			info->ch = 0;
diff --git a/drivers/staging/dream/synaptics_i2c_rmi.c b/drivers/staging/dream/synaptics_i2c_rmi.c
index ae696d3..4de6bc9 100644
--- a/drivers/staging/dream/synaptics_i2c_rmi.c
+++ b/drivers/staging/dream/synaptics_i2c_rmi.c
@@ -379,6 +379,12 @@
 		goto err_check_functionality_failed;
 	}
 
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
+		pr_err("synaptics_ts_probe: need I2C_FUNC_SMBUS_WORD_DATA\n");
+		ret = -ENODEV;
+		goto err_check_functionality_failed;
+	}
+
 	ts = kzalloc(sizeof(*ts), GFP_KERNEL);
 	if (ts == NULL) {
 		ret = -ENOMEM;
diff --git a/drivers/staging/dst/crypto.c b/drivers/staging/dst/crypto.c
index 7250f90..351295c 100644
--- a/drivers/staging/dst/crypto.c
+++ b/drivers/staging/dst/crypto.c
@@ -64,7 +64,8 @@
 	return ERR_PTR(err);
 }
 
-static struct crypto_ablkcipher *dst_init_cipher(struct dst_crypto_ctl *ctl, u8 *key)
+static struct crypto_ablkcipher *dst_init_cipher(struct dst_crypto_ctl *ctl,
+		u8 *key)
 {
 	int err = -EINVAL;
 	struct crypto_ablkcipher *cipher;
@@ -105,7 +106,7 @@
 {
 	unsigned int i;
 
-	for (i=0; i<e->page_num; ++i)
+	for (i = 0; i < e->page_num; ++i)
 		__free_page(e->pages[i]);
 	kfree(e->pages);
 }
@@ -118,7 +119,7 @@
 	if (!e->pages)
 		return -ENOMEM;
 
-	for (i=0; i<num; ++i) {
+	for (i = 0; i < num; ++i) {
 		e->pages[i] = alloc_page(GFP_KERNEL);
 		if (!e->pages[i])
 			goto err_out_free_pages;
@@ -139,7 +140,8 @@
  * Initialize crypto engine for given node.
  * Setup cipher/hash, keys, pool of threads and private data.
  */
-static int dst_crypto_engine_init(struct dst_crypto_engine *e, struct dst_node *n)
+static int dst_crypto_engine_init(struct dst_crypto_engine *e,
+		struct dst_node *n)
 {
 	int err;
 	struct dst_crypto_ctl *ctl = &n->crypto;
@@ -198,8 +200,7 @@
 /*
  * Waiting for cipher processing to be completed.
  */
-struct dst_crypto_completion
-{
+struct dst_crypto_completion {
 	struct completion		complete;
 	int				error;
 };
@@ -237,17 +238,17 @@
 		err = crypto_ablkcipher_decrypt(req);
 
 	switch (err) {
-		case -EINPROGRESS:
-		case -EBUSY:
-			err = wait_for_completion_interruptible_timeout(&c.complete,
-					timeout);
-			if (!err)
-				err = -ETIMEDOUT;
-			else
-				err = c.error;
-			break;
-		default:
-			break;
+	case -EINPROGRESS:
+	case -EBUSY:
+		err = wait_for_completion_interruptible_timeout(&c.complete,
+				timeout);
+		if (!err)
+			err = -ETIMEDOUT;
+		else
+			err = c.error;
+		break;
+	default:
+		break;
 	}
 
 	return err;
@@ -263,7 +264,7 @@
  * temporary storage, which is then being sent to the remote peer.
  */
 static int dst_trans_iter_out(struct bio *bio, struct dst_crypto_engine *e,
-		int (* iterator) (struct dst_crypto_engine *e,
+		int (*iterator) (struct dst_crypto_engine *e,
 				  struct scatterlist *dst,
 				  struct scatterlist *src))
 {
@@ -286,7 +287,7 @@
 }
 
 static int dst_trans_iter_in(struct bio *bio, struct dst_crypto_engine *e,
-		int (* iterator) (struct dst_crypto_engine *e,
+		int (*iterator) (struct dst_crypto_engine *e,
 				  struct scatterlist *dst,
 				  struct scatterlist *src))
 {
@@ -411,9 +412,9 @@
  * Initialize crypto engine for given node: store keys, create pool
  * of threads, initialize each one.
  *
- * Each thread has unique ID, but 0 and 1 are reserved for receiving and accepting
- * threads (if export node), so IDs could start from 2, but starting them
- * from 10 allows easily understand what this thread is for.
+ * Each thread has unique ID, but 0 and 1 are reserved for receiving and
+ * accepting threads (if export node), so IDs could start from 2, but starting
+ * them from 10 allows easily understand what this thread is for.
  */
 int dst_node_crypto_init(struct dst_node *n, struct dst_crypto_ctl *ctl)
 {
@@ -436,10 +437,10 @@
 	}
 	memcpy(&n->crypto, ctl, sizeof(struct dst_crypto_ctl));
 
-	for (i=0; i<ctl->thread_num; ++i) {
+	for (i = 0; i < ctl->thread_num; ++i) {
 		snprintf(name, sizeof(name), "%s-crypto-%d", n->name, i);
 		/* Unique ids... */
-		err = thread_pool_add_worker(n->pool, name, i+10,
+		err = thread_pool_add_worker(n->pool, name, i + 10,
 			dst_crypto_thread_init, dst_crypto_thread_cleanup, n);
 		if (err)
 			goto err_out_free_threads;
@@ -496,8 +497,8 @@
 				bv->bv_len, bv->bv_offset);
 
 		p = kmap(bv->bv_page) + bv->bv_offset;
-		for (i=0; i<bv->bv_len; ++i)
-			printk("%02x ", p[i]);
+		for (i = 0; i < bv->bv_len; ++i)
+			printk(KERN_DEBUG "%02x ", p[i]);
 		kunmap(bv->bv_page);
 		printk("\n");
 	}
@@ -532,7 +533,7 @@
 			printk(KERN_DEBUG "%s: bio: %llu/%u, rw: %lu, hash: ",
 				__func__, (u64)bio->bi_sector,
 				bio->bi_size, bio_data_dir(bio));
-			for (i=0; i<crypto_hash_digestsize(e->hash); ++i)
+			for (i = 0; i < crypto_hash_digestsize(e->hash); ++i)
 					printk("%02x ", hash[i]);
 			printk("\n");
 		}
@@ -572,9 +573,9 @@
 			unsigned int i;
 
 			printk(", recv/calc: ");
-			for (i=0; i<crypto_hash_digestsize(e->hash); ++i) {
+			for (i = 0; i < crypto_hash_digestsize(e->hash); ++i)
 				printk("%02x/%02x ", recv_hash[i], hash[i]);
-			}
+
 		}
 		printk("\n");
 #endif
@@ -680,8 +681,9 @@
 	struct dst_export_priv *p = bio->bi_private;
 	int err;
 
-	dprintk("%s: e: %p, data: %p, bio: %llu/%u, dir: %lu.\n", __func__,
-		e, e->data, (u64)bio->bi_sector, bio->bi_size, bio_data_dir(bio));
+	dprintk("%s: e: %p, data: %p, bio: %llu/%u, dir: %lu.\n",
+			__func__, e, e->data, (u64)bio->bi_sector,
+			bio->bi_size, bio_data_dir(bio));
 
 	e->enc = (bio_data_dir(bio) == READ);
 	e->iv = p->cmd.id;
diff --git a/drivers/staging/dst/dcore.c b/drivers/staging/dst/dcore.c
index c24e4e0..fd5bd0e 100644
--- a/drivers/staging/dst/dcore.c
+++ b/drivers/staging/dst/dcore.c
@@ -116,7 +116,7 @@
 		 * bio_rw_flagged(bio, BIO_RW_DISCARD) only, which does not
 		 * work in this case.
 		 */
-		//err = -EOPNOTSUPP;
+		/* err = -EOPNOTSUPP; */
 		err = 0;
 		goto end_io;
 	}
@@ -197,7 +197,8 @@
 	n->disk->fops = &dst_blk_ops;
 	n->disk->queue = n->queue;
 	n->disk->private_data = n;
-	snprintf(n->disk->disk_name, sizeof(n->disk->disk_name), "dst-%s", n->name);
+	snprintf(n->disk->disk_name, sizeof(n->disk->disk_name),
+			"dst-%s", n->name);
 
 	return 0;
 
@@ -246,7 +247,8 @@
 		return sprintf(buf, "%u.%u.%u.%u:%d\n",
 			NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
 	} else if (family == AF_INET6) {
-		struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&info->net.addr;
+		struct sockaddr_in6 *sin = (struct sockaddr_in6 *)
+				&info->net.addr;
 		return sprintf(buf,
 			"%pi6:%d\n",
 			&sin->sin6_addr, ntohs(sin->sin6_port));
@@ -261,7 +263,7 @@
 		sz -= size;
 		buf += size;
 
-		for (i=0; i<addrlen; ++i) {
+		for (i = 0; i < addrlen; ++i) {
 			if (sz < 3)
 				break;
 
@@ -286,7 +288,7 @@
 {
 	int err, i;
 
-	for (i=0; i<ARRAY_SIZE(dst_node_attrs); ++i) {
+	for (i = 0; i < ARRAY_SIZE(dst_node_attrs); ++i) {
 		err = device_create_file(&n->info->device,
 				&dst_node_attrs[i]);
 		if (err)
@@ -306,7 +308,7 @@
 {
 	int i;
 
-	for (i=0; i<ARRAY_SIZE(dst_node_attrs); ++i)
+	for (i = 0; i < ARRAY_SIZE(dst_node_attrs); ++i)
 		device_remove_file(&n->info->device,
 				&dst_node_attrs[i]);
 }
@@ -358,7 +360,7 @@
  */
 static inline unsigned int dst_hash(char *str, unsigned int size)
 {
-	return (jhash(str, size, 0) % dst_hashtable_size);
+	return jhash(str, size, 0) % dst_hashtable_size;
 }
 
 static void dst_node_remove(struct dst_node *n)
@@ -641,7 +643,8 @@
 	dst_node_set_size(n);
 	add_disk(n->disk);
 
-	dprintk("DST: started remote node '%s', minor: %d.\n", n->name, n->disk->first_minor);
+	dprintk("DST: started remote node '%s', minor: %d.\n",
+			n->name, n->disk->first_minor);
 
 	return 0;
 }
@@ -740,7 +743,8 @@
 	 * counter will be equal to 1),
 	 * and subsequent dst_node_put() calls will free the node.
 	 */
-	dprintk("%s: going to sleep with %d refcnt.\n", __func__, atomic_read(&n->refcnt));
+	dprintk("%s: going to sleep with %d refcnt.\n",
+			__func__, atomic_read(&n->refcnt));
 	wait_event(n->wait, atomic_read(&n->refcnt) <= 2);
 
 	dst_node_put(n);
@@ -921,7 +925,7 @@
 	if (!dst_hashtable)
 		return -ENOMEM;
 
-	for (i=0; i<dst_hashtable_size; ++i)
+	for (i = 0; i < dst_hashtable_size; ++i)
 		INIT_LIST_HEAD(&dst_hashtable[i]);
 
 	return 0;
@@ -932,7 +936,7 @@
 	unsigned int i;
 	struct dst_node *n, *tmp;
 
-	for (i=0; i<dst_hashtable_size; ++i) {
+	for (i = 0; i < dst_hashtable_size; ++i) {
 		list_for_each_entry_safe(n, tmp, &dst_hashtable[i], node_entry) {
 			dst_node_remove_unload(n);
 		}
diff --git a/drivers/staging/dst/export.c b/drivers/staging/dst/export.c
index 4fbd848..c324230 100644
--- a/drivers/staging/dst/export.c
+++ b/drivers/staging/dst/export.c
@@ -53,7 +53,8 @@
  * its permissions are checked in a security attributes and sent
  * back.
  */
-static unsigned int dst_check_permissions(struct dst_state *main, struct dst_state *st)
+static unsigned int dst_check_permissions(struct dst_state *main,
+		struct dst_state *st)
 {
 	struct dst_node *n = main->node;
 	struct dst_secure *sentry;
@@ -73,9 +74,9 @@
 
 		/*
 		 * This '2' below is a port field. This may be very wrong to do
-		 * in atalk for example though. If there will be any need to extent
-		 * protocol to something else, I can create per-family helpers and
-		 * use them instead of this memcmp.
+		 * in atalk for example though. If there will be any need
+		 * to extent protocol to something else, I can create
+		 * per-family helpers and use them instead of this memcmp.
 		 */
 		if (memcmp(s->addr.sa_data + 2, sa->sa_data + 2,
 					sa->sa_data_len - 2))
@@ -125,8 +126,8 @@
 				 * Magic HZ? Polling check above is not safe in
 				 * all cases (like socket reset in BH context),
 				 * so it is simpler just to postpone it to the
-				 * process context instead of implementing special
-				 * locking there.
+				 * process context instead of implementing
+				 * special locking there.
 				 */
 				schedule_timeout(HZ);
 			}
@@ -202,7 +203,7 @@
  * so to play good with all cases we just queue BIO into the queue
  * and wake up processing thread, which gets completed request and
  * send (encrypting if needed) it back to the client (if it was a read
- * request), or sends back reply that writing succesfully completed.
+ * request), or sends back reply that writing successfully completed.
  */
 static int dst_export_process_request_queue(struct dst_state *st)
 {
@@ -272,8 +273,8 @@
 			if (p)
 				bio_put(p->bio);
 
-			dprintk("%s: st: %p, refcnt: %d, list_empty: %d, p: %p.\n",
-				__func__, st, atomic_read(&st->refcnt),
+			dprintk("%s: st: %p, refcnt: %d, list_empty: %d, p: "
+				"%p.\n", __func__, st, atomic_read(&st->refcnt),
 				list_empty(&st->request_list), p);
 		}
 	}
@@ -303,9 +304,9 @@
 		if (!err) {
 			while (n->trans_scan_timeout) {
 				err = wait_event_interruptible_timeout(st->thread_wait,
-						!list_empty(&st->request_list) ||
-						!n->trans_scan_timeout ||
-						st->need_exit,
+					!list_empty(&st->request_list) ||
+					!n->trans_scan_timeout ||
+					st->need_exit,
 					HZ);
 
 				if (!n->trans_scan_timeout || st->need_exit)
@@ -341,8 +342,9 @@
 int dst_start_export(struct dst_node *n)
 {
 	if (list_empty(&n->security_list)) {
-		printk(KERN_ERR "You are trying to export node '%s' without security attributes.\n"
-				"No clients will be allowed to connect. Exiting.\n", n->name);
+		printk(KERN_ERR "You are trying to export node '%s' "
+				"without security attributes.\nNo clients will "
+				"be allowed to connect. Exiting.\n", n->name);
 		return -EINVAL;
 	}
 	return dst_node_trans_init(n, sizeof(struct dst_export_priv));
@@ -552,7 +554,8 @@
 	if (!bio)
 		goto err_out_exit;
 
-	priv = (struct dst_export_priv *)(((void *)bio) - sizeof (struct dst_export_priv));
+	priv = (struct dst_export_priv *)(((void *)bio) -
+			sizeof (struct dst_export_priv));
 
 	priv->state = dst_state_get(st);
 	priv->bio = bio;
diff --git a/drivers/staging/dst/state.c b/drivers/staging/dst/state.c
index d057e52..02a05e6 100644
--- a/drivers/staging/dst/state.c
+++ b/drivers/staging/dst/state.c
@@ -30,13 +30,13 @@
  * Polling machinery.
  */
 
-struct dst_poll_helper
-{
-	poll_table 		pt;
+struct dst_poll_helper {
+	poll_table		pt;
 	struct dst_state	*st;
 };
 
-static int dst_queue_wake(wait_queue_t *wait, unsigned mode, int sync, void *key)
+static int dst_queue_wake(wait_queue_t *wait, unsigned mode,
+		int sync, void *key)
 {
 	struct dst_state *st = container_of(wait, struct dst_state, wait);
 
@@ -92,7 +92,7 @@
 	msg.msg_namelen = 0;
 	msg.msg_control = NULL;
 	msg.msg_controllen = 0;
-	msg.msg_flags = (block)?MSG_WAITALL:MSG_DONTWAIT;
+	msg.msg_flags = (block) ? MSG_WAITALL : MSG_DONTWAIT;
 
 	err = kernel_recvmsg(sock, &msg, &iov, 1, iov.iov_len,
 			msg.msg_flags);
@@ -121,7 +121,7 @@
 	msg.msg_namelen = 0;
 	msg.msg_control = NULL;
 	msg.msg_controllen = 0;
-	msg.msg_flags = MSG_WAITALL | (more)?MSG_MORE:0;
+	msg.msg_flags = MSG_WAITALL | (more ? MSG_MORE : 0);
 
 	err = kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len);
 	if (err != size) {
@@ -217,8 +217,8 @@
 {
 	if (sk->ops->family == AF_INET) {
 		struct sockaddr_in *sin = (struct sockaddr_in *)sa;
-		printk(KERN_INFO "%s %u.%u.%u.%u:%d.\n",
-			str, NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+		printk(KERN_INFO "%s %u.%u.%u.%u:%d.\n", str,
+			NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
 	} else if (sk->ops->family == AF_INET6) {
 		struct sockaddr_in6 *sin = (struct sockaddr_in6 *)sa;
 		printk(KERN_INFO "%s %pi6:%d",
@@ -271,13 +271,13 @@
  * State reset is used to reconnect to the remote peer.
  * May fail, but who cares, we will try again later.
  */
-static void inline dst_state_reset_nolock(struct dst_state *st)
+static inline void dst_state_reset_nolock(struct dst_state *st)
 {
 	dst_state_exit_connected(st);
 	dst_state_init_connected(st);
 }
 
-static void inline dst_state_reset(struct dst_state *st)
+static inline void dst_state_reset(struct dst_state *st)
 {
 	dst_state_lock(st);
 	dst_state_reset_nolock(st);
@@ -335,9 +335,11 @@
 
 		cmd->cmd = __cpu_to_be32(DST_PING);
 
-		err = dst_data_send_header(st->socket, cmd, sizeof(struct dst_cmd), 0);
+		err = dst_data_send_header(st->socket, cmd,
+				sizeof(struct dst_cmd), 0);
 	}
-	dprintk("%s: st: %p, socket: %p, err: %d.\n", __func__, st, st->socket, err);
+	dprintk("%s: st: %p, socket: %p, err: %d.\n", __func__,
+			st, st->socket, err);
 	dst_state_unlock(st);
 
 	return err;
@@ -390,8 +392,7 @@
 		err = -ECONNRESET;
 		dst_state_lock(st);
 
-		if (		st->socket &&
-				(st->read_socket == st->socket) &&
+		if (st->socket && (st->read_socket == st->socket) &&
 				(revents & POLLIN)) {
 			err = dst_data_recv_raw(st, data, size);
 			if (err > 0) {
@@ -402,8 +403,9 @@
 		}
 
 		if (revents & err_mask || !st->socket) {
-			dprintk("%s: revents: %x, socket: %p, size: %u, err: %d.\n",
-					__func__, revents, st->socket, size, err);
+			dprintk("%s: revents: %x, socket: %p, size: %u, "
+					"err: %d.\n", __func__, revents,
+					st->socket, size, err);
 			err = -ECONNRESET;
 		}
 
@@ -440,7 +442,8 @@
 /*
  * Receive block IO from the network.
  */
-static int dst_recv_bio(struct dst_state *st, struct bio *bio, unsigned int total_size)
+static int dst_recv_bio(struct dst_state *st, struct bio *bio,
+		unsigned int total_size)
 {
 	struct bio_vec *bv;
 	int i, err;
@@ -450,9 +453,10 @@
 	bio_for_each_segment(bv, bio, i) {
 		sz = min(total_size, bv->bv_len);
 
-		dprintk("%s: bio: %llu/%u, total: %u, len: %u, sz: %u, off: %u.\n",
-			__func__, (u64)bio->bi_sector, bio->bi_size, total_size,
-			bv->bv_len, sz, bv->bv_offset);
+		dprintk("%s: bio: %llu/%u, total: %u, len: %u, sz: %u, "
+				"off: %u.\n", __func__, (u64)bio->bi_sector,
+				bio->bi_size, total_size, bv->bv_len, sz,
+				bv->bv_offset);
 
 		data = kmap(bv->bv_page) + bv->bv_offset;
 		err = dst_data_recv(st, data, sz);
@@ -590,7 +594,8 @@
 			cmd->flags, cmd->rw);
 
 	/*
-	 * This should catch protocol breakage and random garbage instead of commands.
+	 * This should catch protocol breakage and random garbage
+	 * instead of commands.
 	 */
 	if (unlikely(cmd->csize > st->size - sizeof(struct dst_cmd))) {
 		err = -EBADMSG;
@@ -599,20 +604,20 @@
 
 	err = -EPROTO;
 	switch (cmd->cmd) {
-		case DST_IO_RESPONSE:
-			err = dst_process_io_response(st);
-			break;
-		case DST_IO:
-			err = dst_process_io(st);
-			break;
-		case DST_CFG:
-			err = dst_process_cfg(st);
-			break;
-		case DST_PING:
-			err = 0;
-			break;
-		default:
-			break;
+	case DST_IO_RESPONSE:
+		err = dst_process_io_response(st);
+		break;
+	case DST_IO:
+		err = dst_process_io(st);
+		break;
+	case DST_CFG:
+		err = dst_process_cfg(st);
+		break;
+	case DST_PING:
+		err = 0;
+		break;
+	default:
+		break;
 	}
 
 out_exit:
diff --git a/drivers/staging/dst/thread_pool.c b/drivers/staging/dst/thread_pool.c
index 7bed4e8..29a82b2 100644
--- a/drivers/staging/dst/thread_pool.c
+++ b/drivers/staging/dst/thread_pool.c
@@ -30,8 +30,7 @@
  * When action is being performed, thread can not be used by other users,
  * instead they will sleep until there is free thread to pick their work.
  */
-struct thread_pool_worker
-{
+struct thread_pool_worker {
 	struct list_head	worker_entry;
 
 	struct task_struct	*thread;
@@ -48,8 +47,8 @@
 	void			*private;
 	void			*schedule_data;
 
-	int			(* action)(void *private, void *schedule_data);
-	void			(* cleanup)(void *private);
+	int			(*action)(void *private, void *schedule_data);
+	void			(*cleanup)(void *private);
 };
 
 static void thread_pool_exit_worker(struct thread_pool_worker *w)
@@ -116,10 +115,12 @@
 	struct thread_pool_worker *w = NULL;
 
 	while (!w && p->thread_num) {
-		wait_event(p->wait, !list_empty(&p->ready_list) || !p->thread_num);
+		wait_event(p->wait, !list_empty(&p->ready_list) ||
+				!p->thread_num);
 
 		dprintk("%s: locking list_empty: %d, thread_num: %d.\n",
-				__func__, list_empty(&p->ready_list), p->thread_num);
+				__func__, list_empty(&p->ready_list),
+				p->thread_num);
 
 		mutex_lock(&p->thread_lock);
 		if (!list_empty(&p->ready_list)) {
@@ -127,8 +128,9 @@
 					struct thread_pool_worker,
 					worker_entry);
 
-			dprintk("%s: deleting w: %p, thread_num: %d, list: %p [%p.%p].\n",
-					__func__, w, p->thread_num, &p->ready_list,
+			dprintk("%s: deleting w: %p, thread_num: %d, "
+					"list: %p [%p.%p].\n", __func__,
+					w, p->thread_num, &p->ready_list,
 					p->ready_list.prev, p->ready_list.next);
 
 			p->thread_num--;
@@ -182,8 +184,8 @@
 int thread_pool_add_worker(struct thread_pool *p,
 		char *name,
 		unsigned int id,
-		void *(* init)(void *private),
-		void (* cleanup)(void *private),
+		void *(*init)(void *private),
+		void (*cleanup)(void *private),
 		void *private)
 {
 	struct thread_pool_worker *w;
@@ -243,8 +245,8 @@
  * They will have sequential IDs started from zero.
  */
 struct thread_pool *thread_pool_create(int num, char *name,
-		void *(* init)(void *private),
-		void (* cleanup)(void *private),
+		void *(*init)(void *private),
+		void (*cleanup)(void *private),
 		void *private)
 {
 	struct thread_pool_worker *w, *tmp;
@@ -262,7 +264,7 @@
 	INIT_LIST_HEAD(&p->active_list);
 	p->thread_num = 0;
 
-	for (i=0; i<num; ++i) {
+	for (i = 0; i < num; ++i) {
 		err = thread_pool_add_worker(p, name, i, init,
 				cleanup, private);
 		if (err)
@@ -287,8 +289,8 @@
  * private data.
  */
 int thread_pool_schedule_private(struct thread_pool *p,
-		int (* setup)(void *private, void *data),
-		int (* action)(void *private, void *data),
+		int (*setup)(void *private, void *data),
+		int (*action)(void *private, void *data),
 		void *data, long timeout, void *id)
 {
 	struct thread_pool_worker *w, *tmp, *worker = NULL;
@@ -321,7 +323,8 @@
 				w->has_data = 1;
 				wake_up(&w->wait);
 			} else {
-				list_move_tail(&w->worker_entry, &p->ready_list);
+				list_move_tail(&w->worker_entry,
+						&p->ready_list);
 			}
 
 			break;
@@ -336,8 +339,8 @@
  * Schedule execution on arbitrary thread from the pool.
  */
 int thread_pool_schedule(struct thread_pool *p,
-		int (* setup)(void *private, void *data),
-		int (* action)(void *private, void *data),
+		int (*setup)(void *private, void *data),
+		int (*action)(void *private, void *data),
 		void *data, long timeout)
 {
 	return thread_pool_schedule_private(p, setup,
diff --git a/drivers/staging/dst/trans.c b/drivers/staging/dst/trans.c
index 557d372..1c36a6b 100644
--- a/drivers/staging/dst/trans.c
+++ b/drivers/staging/dst/trans.c
@@ -58,7 +58,7 @@
 	}
 
 	dprintk("%s: %s transaction: id: %llu.\n", __func__,
-			(ret)?"found":"not found", gen);
+			(ret) ? "found" : "not found", gen);
 
 	return ret;
 }
@@ -88,9 +88,9 @@
 
 	new->send_time = jiffies;
 	if (ret) {
-		printk("%s: exist: old: gen: %llu, bio: %llu/%u, send_time: %lu, "
-				"new: gen: %llu, bio: %llu/%u, send_time: %lu.\n",
-			__func__,
+		printk(KERN_DEBUG "%s: exist: old: gen: %llu, bio: %llu/%u, "
+			"send_time: %lu, new: gen: %llu, bio: %llu/%u, "
+			"send_time: %lu.\n", __func__,
 			ret->gen, (u64)ret->bio->bi_sector,
 			ret->bio->bi_size, ret->send_time,
 			new->gen, (u64)new->bio->bi_sector,
@@ -206,7 +206,8 @@
  */
 static void dst_trans_scan(struct work_struct *work)
 {
-	struct dst_node *n = container_of(work, struct dst_node, trans_work.work);
+	struct dst_node *n = container_of(work, struct dst_node,
+			trans_work.work);
 	struct rb_node *rb_node;
 	struct dst_trans *t;
 	unsigned long timeout = n->trans_scan_timeout;
@@ -246,8 +247,8 @@
 	mutex_unlock(&n->trans_lock);
 
 	/*
-	 * If no timeout specified then system is in the middle of exiting process,
-	 * so no need to reschedule scanning process again.
+	 * If no timeout specified then system is in the middle of exiting
+	 * process, so no need to reschedule scanning process again.
 	 */
 	if (timeout) {
 		if (!num)
@@ -313,7 +314,8 @@
 	if (!n->trans_cache)
 		goto err_out_exit;
 
-	n->trans_pool = mempool_create_slab_pool(dst_mempool_num, n->trans_cache);
+	n->trans_pool = mempool_create_slab_pool(dst_mempool_num,
+			n->trans_cache);
 	if (!n->trans_pool)
 		goto err_out_cache_destroy;
 
diff --git a/drivers/staging/et131x/et1310_address_map.h b/drivers/staging/et131x/et1310_address_map.h
index 2c3d65a..6da843c 100644
--- a/drivers/staging/et131x/et1310_address_map.h
+++ b/drivers/staging/et131x/et1310_address_map.h
@@ -198,20 +198,10 @@
 /*
  * structure for txdma packet ring number of descriptor reg in txdma address
  * map.  Located at address 0x100C
+ *
+ * 31-10: unused
+ * 9-0: pr ndes
  */
-typedef union _TXDMA_PR_NUM_DES_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:22;	/* bits 10-31 */
-		u32 pr_ndes:10;	/* bits 0-9 */
-#else
-		u32 pr_ndes:10;	/* bits 0-9 */
-		u32 unused:22;	/* bits 10-31 */
-#endif
-	} bits;
-} TXDMA_PR_NUM_DES_t, *PTXDMA_PR_NUM_DES_t;
-
 
 #define ET_DMA10_MASK		0x3FF	/* 10 bit mask for DMA10W types */
 #define ET_DMA10_WRAP		0x400
@@ -261,7 +251,7 @@
 	u32 csr;			/*  0x1000 */
 	u32 pr_base_hi;			/*  0x1004 */
 	u32 pr_base_lo;			/*  0x1008 */
-	TXDMA_PR_NUM_DES_t pr_num_des;	/*  0x100C */
+	u32 pr_num_des;			/*  0x100C */
 	u32 txq_wr_addr;		/*  0x1010 */
 	u32 txq_wr_addr_ext;		/*  0x1014 */
 	u32 txq_rd_addr;		/*  0x1018 */
@@ -349,36 +339,18 @@
 /*
  * structure for number of packets done reg in rxdma address map
  * located at address 0x200C
+ *
+ * 31-8: unused
+ * 7-0: num done
  */
-typedef union _RXDMA_NUM_PKT_DONE_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:24;	/* bits 8-31 */
-		u32 num_done:8;	/* bits 0-7 */
-#else
-		u32 num_done:8;	/* bits 0-7 */
-		u32 unused:24;	/* bits 8-31 */
-#endif
-	} bits;
-} RXDMA_NUM_PKT_DONE_t, *PRXDMA_NUM_PKT_DONE_t;
 
 /*
  * structure for max packet time reg in rxdma address map
  * located at address 0x2010
+ *
+ * 31-18: unused
+ * 17-0: time done
  */
-typedef union _RXDMA_MAX_PKT_TIME_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:14;		/* bits 18-31 */
-		u32 time_done:18;	/* bits 0-17 */
-#else
-		u32 time_done:18;	/* bits 0-17 */
-		u32 unused:14;		/* bits 18-31 */
-#endif
-	} bits;
-} RXDMA_MAX_PKT_TIME_t, *PRXDMA_MAX_PKT_TIME_t;
 
 /*
  * structure for rx queue read address reg in rxdma address map
@@ -413,91 +385,44 @@
 /*
  * structure for packet status ring number of descriptors reg in rxdma address
  * map.  Located at address 0x2028
+ *
+ * 31-12: unused
+ * 11-0: psr ndes
  */
-typedef union _RXDMA_PSR_NUM_DES_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:20;		/* bits 12-31 */
-		u32 psr_ndes:12;	/* bit 0-11 */
-#else
-		u32 psr_ndes:12;	/* bit 0-11 */
-		u32 unused:20;		/* bits 12-31 */
-#endif
-	} bits;
-} RXDMA_PSR_NUM_DES_t, *PRXDMA_PSR_NUM_DES_t;
 
 /*
  * structure for packet status ring available offset reg in rxdma address map
  * located at address 0x202C
+ *
+ * 31-13: unused
+ * 12: psr avail wrap
+ * 11-0: psr avail
  */
-typedef union _RXDMA_PSR_AVAIL_OFFSET_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:19;		/* bits 13-31 */
-		u32 psr_avail_wrap:1;	/* bit 12 */
-		u32 psr_avail:12;	/* bit 0-11 */
-#else
-		u32 psr_avail:12;	/* bit 0-11 */
-		u32 psr_avail_wrap:1;	/* bit 12 */
-		u32 unused:19;		/* bits 13-31 */
-#endif
-	} bits;
-} RXDMA_PSR_AVAIL_OFFSET_t, *PRXDMA_PSR_AVAIL_OFFSET_t;
 
 /*
  * structure for packet status ring full offset reg in rxdma address map
  * located at address 0x2030
+ *
+ * 31-13: unused
+ * 12: psr full wrap
+ * 11-0: psr full
  */
-typedef union _RXDMA_PSR_FULL_OFFSET_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:19;		/* bits 13-31 */
-		u32 psr_full_wrap:1;	/* bit 12 */
-		u32 psr_full:12;	/* bit 0-11 */
-#else
-		u32 psr_full:12;	/* bit 0-11 */
-		u32 psr_full_wrap:1;	/* bit 12 */
-		u32 unused:19;		/* bits 13-31 */
-#endif
-	} bits;
-} RXDMA_PSR_FULL_OFFSET_t, *PRXDMA_PSR_FULL_OFFSET_t;
 
 /*
  * structure for packet status ring access index reg in rxdma address map
  * located at address 0x2034
+ *
+ * 31-5: unused
+ * 4-0: psr_ai
  */
-typedef union _RXDMA_PSR_ACCESS_INDEX_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:27;	/* bits 5-31 */
-		u32 psr_ai:5;	/* bits 0-4 */
-#else
-		u32 psr_ai:5;	/* bits 0-4 */
-		u32 unused:27;	/* bits 5-31 */
-#endif
-	} bits;
-} RXDMA_PSR_ACCESS_INDEX_t, *PRXDMA_PSR_ACCESS_INDEX_t;
 
 /*
  * structure for packet status ring minimum descriptors reg in rxdma address
  * map.  Located at address 0x2038
+ *
+ * 31-12: unused
+ * 11-0: psr_min
  */
-typedef union _RXDMA_PSR_MIN_DES_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:20;	/* bits 12-31 */
-		u32 psr_min:12;	/* bits 0-11 */
-#else
-		u32 psr_min:12;	/* bits 0-11 */
-		u32 unused:20;	/* bits 12-31 */
-#endif
-	} bits;
-} RXDMA_PSR_MIN_DES_t, *PRXDMA_PSR_MIN_DES_t;
 
 /*
  * structure for free buffer ring base lo address reg in rxdma address map
@@ -514,6 +439,9 @@
 /*
  * structure for free buffer ring number of descriptors reg in rxdma address
  * map.  Located at address 0x2044
+ *
+ * 31-10: unused
+ * 9-0: fbr ndesc
  */
 typedef union _RXDMA_FBR_NUM_DES_t {
 	u32 value;
@@ -543,36 +471,18 @@
 /*
  * structure for free buffer cache 0 full offset reg in rxdma address map
  * located at address 0x2050
+ *
+ * 31-5: unused
+ * 4-0: fbc rdi
  */
-typedef union _RXDMA_FBC_RD_INDEX_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:27;	/* bits 5-31 */
-		u32 fbc_rdi:5;	/* bit 0-4 */
-#else
-		u32 fbc_rdi:5;	/* bit 0-4 */
-		u32 unused:27;	/* bits 5-31 */
-#endif
-	} bits;
-} RXDMA_FBC_RD_INDEX_t, *PRXDMA_FBC_RD_INDEX_t;
 
 /*
  * structure for free buffer ring 0 minimum descriptor reg in rxdma address map
  * located at address 0x2054
+ *
+ * 31-10: unused
+ * 9-0: fbr min
  */
-typedef union _RXDMA_FBR_MIN_DES_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:22;	/* bits 10-31 */
-		u32 fbr_min:10;	/* bits 0-9 */
-#else
-		u32 fbr_min:10;	/* bits 0-9 */
-		u32 unused:22;	/* bits 10-31 */
-#endif
-	} bits;
-} RXDMA_FBR_MIN_DES_t, *PRXDMA_FBR_MIN_DES_t;
 
 /*
  * structure for free buffer ring 1 base address lo reg in rxdma address map
@@ -618,32 +528,32 @@
 	RXDMA_CSR_t csr;				/*  0x2000 */
 	u32 dma_wb_base_lo;				/*  0x2004 */
 	u32 dma_wb_base_hi;				/*  0x2008 */
-	RXDMA_NUM_PKT_DONE_t num_pkt_done;		/*  0x200C */
-	RXDMA_MAX_PKT_TIME_t max_pkt_time;		/*  0x2010 */
+	u32 num_pkt_done;				/*  0x200C */
+	u32 max_pkt_time;				/*  0x2010 */
 	u32 rxq_rd_addr;				/*  0x2014 */
-	u32 rxq_rd_addr_ext;			/*  0x2018 */
+	u32 rxq_rd_addr_ext;				/*  0x2018 */
 	u32 rxq_wr_addr;				/*  0x201C */
 	u32 psr_base_lo;				/*  0x2020 */
 	u32 psr_base_hi;				/*  0x2024 */
-	RXDMA_PSR_NUM_DES_t psr_num_des;		/*  0x2028 */
-	RXDMA_PSR_AVAIL_OFFSET_t psr_avail_offset;	/*  0x202C */
-	RXDMA_PSR_FULL_OFFSET_t psr_full_offset;	/*  0x2030 */
-	RXDMA_PSR_ACCESS_INDEX_t psr_access_index;	/*  0x2034 */
-	RXDMA_PSR_MIN_DES_t psr_min_des;		/*  0x2038 */
+	u32 psr_num_des;				/*  0x2028 */
+	u32 psr_avail_offset;				/*  0x202C */
+	u32 psr_full_offset;				/*  0x2030 */
+	u32 psr_access_index;				/*  0x2034 */
+	u32 psr_min_des;				/*  0x2038 */
 	u32 fbr0_base_lo;				/*  0x203C */
 	u32 fbr0_base_hi;				/*  0x2040 */
-	RXDMA_FBR_NUM_DES_t fbr0_num_des;		/*  0x2044 */
-	u32 fbr0_avail_offset;			/*  0x2048 */
-	u32 fbr0_full_offset;			/*  0x204C */
-	RXDMA_FBC_RD_INDEX_t fbr0_rd_index;		/*  0x2050 */
-	RXDMA_FBR_MIN_DES_t fbr0_min_des;		/*  0x2054 */
+	u32 fbr0_num_des;				/*  0x2044 */
+	u32 fbr0_avail_offset;				/*  0x2048 */
+	u32 fbr0_full_offset;				/*  0x204C */
+	u32 fbr0_rd_index;				/*  0x2050 */
+	u32 fbr0_min_des;				/*  0x2054 */
 	u32 fbr1_base_lo;				/*  0x2058 */
 	u32 fbr1_base_hi;				/*  0x205C */
-	RXDMA_FBR_NUM_DES_t fbr1_num_des;		/*  0x2060 */
-	u32 fbr1_avail_offset;			/*  0x2064 */
-	u32 fbr1_full_offset;			/*  0x2068 */
-	RXDMA_FBC_RD_INDEX_t fbr1_rd_index;		/*  0x206C */
-	RXDMA_FBR_MIN_DES_t fbr1_min_des;		/*  0x2070 */
+	u32 fbr1_num_des;				/*  0x2060 */
+	u32 fbr1_avail_offset;				/*  0x2064 */
+	u32 fbr1_full_offset;				/*  0x2068 */
+	u32 fbr1_rd_index;				/*  0x206C */
+	u32 fbr1_min_des;				/*  0x2070 */
 } RXDMA_t, *PRXDMA_t;
 
 /* END OF RXDMA REGISTER ADDRESS MAP */
@@ -685,23 +595,11 @@
 /*
  * structure for shadow pointer reg in txmac address map
  * located at address 0x3004
+ * 31-27: reserved
+ * 26-16: txq rd ptr
+ * 15-11: reserved
+ * 10-0: txq wr ptr
  */
-typedef union _TXMAC_SHADOW_PTR_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 reserved2:5;	/* bits 27-31 */
-		u32 txq_rd_ptr:11;	/* bits 16-26 */
-		u32 reserved:5;		/* bits 11-15 */
-		u32 txq_wr_ptr:11;	/* bits 0-10 */
-#else
-		u32 txq_wr_ptr:11;	/* bits 0-10 */
-		u32 reserved:5;		/* bits 11-15 */
-		u32 txq_rd_ptr:11;	/* bits 16-26 */
-		u32 reserved2:5;	/* bits 27-31 */
-#endif
-	} bits;
-} TXMAC_SHADOW_PTR_t, *PTXMAC_SHADOW_PTR_t;
 
 /*
  * structure for error count reg in txmac address map
@@ -727,59 +625,26 @@
 /*
  * structure for max fill reg in txmac address map
  * located at address 0x300C
+ * 31-12: unused
+ * 11-0: max fill
  */
-typedef union _TXMAC_MAX_FILL_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:20;		/* bits 12-31 */
-		u32 max_fill:12;	/* bits 0-11 */
-#else
-		u32 max_fill:12;	/* bits 0-11 */
-		u32 unused:20;		/* bits 12-31 */
-#endif
-	} bits;
-} TXMAC_MAX_FILL_t, *PTXMAC_MAX_FILL_t;
 
 /*
  * structure for cf parameter reg in txmac address map
  * located at address 0x3010
+ * 31-16: cfep
+ * 15-0: cfpt
  */
-typedef union _TXMAC_CF_PARAM_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 cfep:16;	/* bits 16-31 */
-		u32 cfpt:16;	/* bits 0-15 */
-#else
-		u32 cfpt:16;	/* bits 0-15 */
-		u32 cfep:16;	/* bits 16-31 */
-#endif
-	} bits;
-} TXMAC_CF_PARAM_t, *PTXMAC_CF_PARAM_t;
 
 /*
  * structure for tx test reg in txmac address map
  * located at address 0x3014
+ * 31-17: unused
+ * 16: reserved1
+ * 15: txtest_en
+ * 14-11: unused
+ * 10-0: txq test pointer
  */
-typedef union _TXMAC_TXTEST_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused2:15;		/* bits 17-31 */
-		u32 reserved1:1;	/* bit 16 */
-		u32 txtest_en:1;	/* bit 15 */
-		u32 unused1:4;		/* bits 11-14 */
-		u32 txqtest_ptr:11;	/* bits 0-11 */
-#else
-		u32 txqtest_ptr:11;	/* bits 0-10 */
-		u32 unused1:4;		/* bits 11-14 */
-		u32 txtest_en:1;	/* bit 15 */
-		u32 reserved1:1;	/* bit 16 */
-		u32 unused2:15;		/* bits 17-31 */
-#endif
-	} bits;
-} TXMAC_TXTEST_t, *PTXMAC_TXTEST_t;
 
 /*
  * structure for error reg in txmac address map
@@ -846,35 +711,25 @@
 /*
  * structure for error interrupt reg in txmac address map
  * located at address 0x3020
+ *
+ * 31-2: unused
+ * 1: bp_req
+ * 0: bp_xonxoff
  */
-typedef union _TXMAC_CP_CTRL_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:30;		/* bits 2-31 */
-		u32 bp_req:1;		/* bit 1 */
-		u32 bp_xonxoff:1;	/* bit 0 */
-#else
-		u32 bp_xonxoff:1;	/* bit 0 */
-		u32 bp_req:1;		/* bit 1 */
-		u32 unused:30;		/* bits 2-31 */
-#endif
-	} bits;
-} TXMAC_BP_CTRL_t, *PTXMAC_BP_CTRL_t;
 
 /*
  * Tx MAC Module of JAGCore Address Mapping
  */
 typedef struct _TXMAC_t {		/* Location: */
 	TXMAC_CTL_t ctl;		/*  0x3000 */
-	TXMAC_SHADOW_PTR_t shadow_ptr;	/*  0x3004 */
+	u32 shadow_ptr;			/*  0x3004 */
 	TXMAC_ERR_CNT_t err_cnt;	/*  0x3008 */
-	TXMAC_MAX_FILL_t max_fill;	/*  0x300C */
-	TXMAC_CF_PARAM_t cf_param;	/*  0x3010 */
-	TXMAC_TXTEST_t tx_test;		/*  0x3014 */
+	u32 max_fill;			/*  0x300C */
+	u32 cf_param;			/*  0x3010 */
+	u32 tx_test;			/*  0x3014 */
 	TXMAC_ERR_t err;		/*  0x3018 */
 	TXMAC_ERR_INT_t err_int;	/*  0x301C */
-	TXMAC_BP_CTRL_t bp_ctrl;	/*  0x3020 */
+	u32 bp_ctrl;			/*  0x3020 */
 } TXMAC_t, *PTXMAC_t;
 
 /* END OF TXMAC REGISTER ADDRESS MAP */
@@ -1308,157 +1163,77 @@
 /*
  * structure for configuration #1 reg in mac address map.
  * located at address 0x5000
+ *
+ * 31: soft reset
+ * 30: sim reset
+ * 29-20: reserved
+ * 19: reset rx mc
+ * 18: reset tx mc
+ * 17: reset rx func
+ * 16: reset tx fnc
+ * 15-9: reserved
+ * 8: loopback
+ * 7-6: reserved
+ * 5: rx flow
+ * 4: tx flow
+ * 3: syncd rx en
+ * 2: rx enable
+ * 1: syncd tx en
+ * 0: tx enable
  */
-typedef union _MAC_CFG1_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 soft_reset:1;		/* bit 31 */
-		u32 sim_reset:1;		/* bit 30 */
-		u32 reserved3:10;		/* bits 20-29 */
-		u32 reset_rx_mc:1;		/* bit 19 */
-		u32 reset_tx_mc:1;		/* bit 18 */
-		u32 reset_rx_fun:1;	/* bit 17 */
-		u32 reset_tx_fun:1;	/* bit 16 */
-		u32 reserved2:7;		/* bits 9-15 */
-		u32 loop_back:1;		/* bit 8 */
-		u32 reserved1:2;		/* bits 6-7 */
-		u32 rx_flow:1;		/* bit 5 */
-		u32 tx_flow:1;		/* bit 4 */
-		u32 syncd_rx_en:1;		/* bit 3 */
-		u32 rx_enable:1;		/* bit 2 */
-		u32 syncd_tx_en:1;		/* bit 1 */
-		u32 tx_enable:1;		/* bit 0 */
-#else
-		u32 tx_enable:1;		/* bit 0 */
-		u32 syncd_tx_en:1;		/* bit 1 */
-		u32 rx_enable:1;		/* bit 2 */
-		u32 syncd_rx_en:1;		/* bit 3 */
-		u32 tx_flow:1;		/* bit 4 */
-		u32 rx_flow:1;		/* bit 5 */
-		u32 reserved1:2;		/* bits 6-7 */
-		u32 loop_back:1;		/* bit 8 */
-		u32 reserved2:7;		/* bits 9-15 */
-		u32 reset_tx_fun:1;	/* bit 16 */
-		u32 reset_rx_fun:1;	/* bit 17 */
-		u32 reset_tx_mc:1;		/* bit 18 */
-		u32 reset_rx_mc:1;		/* bit 19 */
-		u32 reserved3:10;		/* bits 20-29 */
-		u32 sim_reset:1;		/* bit 30 */
-		u32 soft_reset:1;		/* bit 31 */
-#endif
-	} bits;
-} MAC_CFG1_t, *PMAC_CFG1_t;
+
+#define CFG1_LOOPBACK	0x00000100
+#define CFG1_RX_FLOW	0x00000020
+#define CFG1_TX_FLOW	0x00000010
+#define CFG1_RX_ENABLE	0x00000004
+#define CFG1_TX_ENABLE	0x00000001
+#define CFG1_WAIT	0x0000000A	/* RX & TX syncd */
 
 /*
  * structure for configuration #2 reg in mac address map.
  * located at address 0x5004
+ * 31-16: reserved
+ * 15-12: preamble
+ * 11-10: reserved
+ * 9-8: if mode
+ * 7-6: reserved
+ * 5: huge frame
+ * 4: length check
+ * 3: undefined
+ * 2: pad crc
+ * 1: crc enable
+ * 0: full duplex
  */
-typedef union _MAC_CFG2_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 reserved3:16;		/* bits 16-31 */
-		u32 preamble_len:4;	/* bits 12-15 */
-		u32 reserved2:2;		/* bits 10-11 */
-		u32 if_mode:2;		/* bits 8-9 */
-		u32 reserved1:2;		/* bits 6-7 */
-		u32 huge_frame:1;		/* bit 5 */
-		u32 len_check:1;		/* bit 4 */
-		u32 undefined:1;		/* bit 3 */
-		u32 pad_crc:1;		/* bit 2 */
-		u32 crc_enable:1;		/* bit 1 */
-		u32 full_duplex:1;		/* bit 0 */
-#else
-		u32 full_duplex:1;		/* bit 0 */
-		u32 crc_enable:1;		/* bit 1 */
-		u32 pad_crc:1;		/* bit 2 */
-		u32 undefined:1;		/* bit 3 */
-		u32 len_check:1;		/* bit 4 */
-		u32 huge_frame:1;		/* bit 5 */
-		u32 reserved1:2;		/* bits 6-7 */
-		u32 if_mode:2;		/* bits 8-9 */
-		u32 reserved2:2;		/* bits 10-11 */
-		u32 preamble_len:4;	/* bits 12-15 */
-		u32 reserved3:16;		/* bits 16-31 */
-#endif
-	} bits;
-} MAC_CFG2_t, *PMAC_CFG2_t;
+
 
 /*
  * structure for Interpacket gap reg in mac address map.
  * located at address 0x5008
- */
-typedef union _MAC_IPG_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 reserved:1;		/* bit 31 */
-		u32 non_B2B_ipg_1:7;	/* bits 24-30 */
-		u32 undefined2:1;		/* bit 23 */
-		u32 non_B2B_ipg_2:7;	/* bits 16-22 */
-		u32 min_ifg_enforce:8;	/* bits 8-15 */
-		u32 undefined1:1;		/* bit 7 */
-		u32 B2B_ipg:7;		/* bits 0-6 */
-#else
-		u32 B2B_ipg:7;		/* bits 0-6 */
-		u32 undefined1:1;		/* bit 7 */
-		u32 min_ifg_enforce:8;	/* bits 8-15 */
-		u32 non_B2B_ipg_2:7;	/* bits 16-22 */
-		u32 undefined2:1;		/* bit 23 */
-		u32 non_B2B_ipg_1:7;	/* bits 24-30 */
-		u32 reserved:1;		/* bit 31 */
-#endif
-	} bits;
-} MAC_IPG_t, *PMAC_IPG_t;
-
-/*
+ *
+ * 31: reserved
+ * 30-24: non B2B ipg 1
+ * 23: undefined
+ * 22-16: non B2B ipg 2
+ * 15-8: Min ifg enforce
+ * 7-0: B2B ipg
+ *
  * structure for half duplex reg in mac address map.
  * located at address 0x500C
+ * 31-24: reserved
+ * 23-20: Alt BEB trunc
+ * 19: Alt BEB enable
+ * 18: BP no backoff
+ * 17: no backoff
+ * 16: excess defer
+ * 15-12: re-xmit max
+ * 11-10: reserved
+ * 9-0: collision window
  */
-typedef union _MAC_HFDP_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 reserved2:8;		/* bits 24-31 */
-		u32 alt_beb_trunc:4;	/* bits 23-20 */
-		u32 alt_beb_enable:1;	/* bit 19 */
-		u32 bp_no_backoff:1;	/* bit 18 */
-		u32 no_backoff:1;		/* bit 17 */
-		u32 excess_defer:1;	/* bit 16 */
-		u32 rexmit_max:4;		/* bits 12-15 */
-		u32 reserved1:2;		/* bits 10-11 */
-		u32 coll_window:10;	/* bits 0-9 */
-#else
-		u32 coll_window:10;	/* bits 0-9 */
-		u32 reserved1:2;		/* bits 10-11 */
-		u32 rexmit_max:4;		/* bits 12-15 */
-		u32 excess_defer:1;	/* bit 16 */
-		u32 no_backoff:1;		/* bit 17 */
-		u32 bp_no_backoff:1;	/* bit 18 */
-		u32 alt_beb_enable:1;	/* bit 19 */
-		u32 alt_beb_trunc:4;	/* bits 23-20 */
-		u32 reserved2:8;		/* bits 24-31 */
-#endif
-	} bits;
-} MAC_HFDP_t, *PMAC_HFDP_t;
 
 /*
  * structure for Maximum Frame Length reg in mac address map.
- * located at address 0x5010
+ * located at address 0x5010: bits 0-15 hold the length.
  */
-typedef union _MAC_MAX_FM_LEN_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 reserved:16;	/* bits 16-31 */
-		u32 max_len:16;	/* bits 0-15 */
-#else
-		u32 max_len:16;	/* bits 0-15 */
-		u32 reserved:16;	/* bits 16-31 */
-#endif
-	} bits;
-} MAC_MAX_FM_LEN_t, *PMAC_MAX_FM_LEN_t;
 
 /*
  * structure for Reserve 1 reg in mac address map.
@@ -1469,186 +1244,87 @@
 /*
  * structure for Test reg in mac address map.
  * located at address 0x501C
+ * test: bits 0-2, rest unused
  */
-typedef union _MAC_TEST_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:29;	/* bits 3-31 */
-		u32 mac_test:3;	/* bits 0-2 */
-#else
-		u32 mac_test:3;	/* bits 0-2 */
-		u32 unused:29;	/* bits 3-31 */
-#endif
-	} bits;
-} MAC_TEST_t, *PMAC_TEST_t;
 
 /*
  * structure for MII Management Configuration reg in mac address map.
  * located at address 0x5020
+ *
+ * 31: reset MII mgmt
+ * 30-6: unused
+ * 5: scan auto increment
+ * 4: preamble supress
+ * 3: undefined
+ * 2-0: mgmt clock reset
  */
-typedef union _MII_MGMT_CFG_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 reset_mii_mgmt:1;	/* bit 31 */
-		u32 reserved:25;		/* bits 6-30 */
-		u32 scan_auto_incremt:1;	/* bit 5 */
-		u32 preamble_suppress:1;	/* bit 4 */
-		u32 undefined:1;		/* bit 3 */
-		u32 mgmt_clk_reset:3;	/* bits 0-2 */
-#else
-		u32 mgmt_clk_reset:3;	/* bits 0-2 */
-		u32 undefined:1;		/* bit 3 */
-		u32 preamble_suppress:1;	/* bit 4 */
-		u32 scan_auto_incremt:1;	/* bit 5 */
-		u32 reserved:25;		/* bits 6-30 */
-		u32 reset_mii_mgmt:1;	/* bit 31 */
-#endif
-	} bits;
-} MII_MGMT_CFG_t, *PMII_MGMT_CFG_t;
 
 /*
  * structure for MII Management Command reg in mac address map.
  * located at address 0x5024
+ * bit 1: scan cycle
+ * bit 0: read cycle
  */
-typedef union _MII_MGMT_CMD_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 reserved:30;	/* bits 2-31 */
-		u32 scan_cycle:1;	/* bit 1 */
-		u32 read_cycle:1;	/* bit 0 */
-#else
-		u32 read_cycle:1;	/* bit 0 */
-		u32 scan_cycle:1;	/* bit 1 */
-		u32 reserved:30;	/* bits 2-31 */
-#endif
-	} bits;
-} MII_MGMT_CMD_t, *PMII_MGMT_CMD_t;
 
 /*
  * structure for MII Management Address reg in mac address map.
  * located at address 0x5028
+ * 31-13: reserved
+ * 12-8: phy addr
+ * 7-5: reserved
+ * 4-0: register
  */
-typedef union _MII_MGMT_ADDR_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 reserved2:19;	/* bit 13-31 */
-		u32 phy_addr:5;	/* bits 8-12 */
-		u32 reserved1:3;	/* bits 5-7 */
-		u32 reg_addr:5;	/* bits 0-4 */
-#else
-		u32 reg_addr:5;	/* bits 0-4 */
-		u32 reserved1:3;	/* bits 5-7 */
-		u32 phy_addr:5;	/* bits 8-12 */
-		u32 reserved2:19;	/* bit 13-31 */
-#endif
-	} bits;
-} MII_MGMT_ADDR_t, *PMII_MGMT_ADDR_t;
+
+#define MII_ADDR(phy,reg)	((phy) << 8 | (reg))
 
 /*
  * structure for MII Management Control reg in mac address map.
  * located at address 0x502C
+ * 31-16: reserved
+ * 15-0: phy control
  */
-typedef union _MII_MGMT_CTRL_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 reserved:16;	/* bits 16-31 */
-		u32 phy_ctrl:16;	/* bits 0-15 */
-#else
-		u32 phy_ctrl:16;	/* bits 0-15 */
-		u32 reserved:16;	/* bits 16-31 */
-#endif
-	} bits;
-} MII_MGMT_CTRL_t, *PMII_MGMT_CTRL_t;
 
 /*
  * structure for MII Management Status reg in mac address map.
  * located at address 0x5030
+ * 31-16: reserved
+ * 15-0: phy control
  */
-typedef union _MII_MGMT_STAT_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 reserved:16;	/* bits 16-31 */
-		u32 phy_stat:16;	/* bits 0-15 */
-#else
-		u32 phy_stat:16;	/* bits 0-15 */
-		u32 reserved:16;	/* bits 16-31 */
-#endif
-	} bits;
-} MII_MGMT_STAT_t, *PMII_MGMT_STAT_t;
 
 /*
  * structure for MII Management Indicators reg in mac address map.
  * located at address 0x5034
+ * 31-3: reserved
+ * 2: not valid
+ * 1: scanning
+ * 0: busy
  */
-typedef union _MII_MGMT_INDICATOR_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 reserved:29;	/* bits 3-31 */
-		u32 not_valid:1;	/* bit 2 */
-		u32 scanning:1;	/* bit 1 */
-		u32 busy:1;	/* bit 0 */
-#else
-		u32 busy:1;	/* bit 0 */
-		u32 scanning:1;	/* bit 1 */
-		u32 not_valid:1;	/* bit 2 */
-		u32 reserved:29;	/* bits 3-31 */
-#endif
-	} bits;
-} MII_MGMT_INDICATOR_t, *PMII_MGMT_INDICATOR_t;
+
+#define MGMT_BUSY	0x00000001	/* busy */
+#define MGMT_WAIT	0x00000005	/* busy | not valid */
 
 /*
  * structure for Interface Control reg in mac address map.
  * located at address 0x5038
+ *
+ * 31: reset if module
+ * 30-28: reserved
+ * 27: tbi mode
+ * 26: ghd mode
+ * 25: lhd mode
+ * 24: phy mode
+ * 23: reset per mii
+ * 22-17: reserved
+ * 16: speed
+ * 15: reset pe100x
+ * 14-11: reserved
+ * 10: force quiet
+ * 9: no cipher
+ * 8: disable link fail
+ * 7: reset gpsi
+ * 6-1: reserved
+ * 0: enable jabber protection
  */
-typedef union _MAC_IF_CTRL_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 reset_if_module:1;	/* bit 31 */
-		u32 reserved4:3;		/* bit 28-30 */
-		u32 tbi_mode:1;		/* bit 27 */
-		u32 ghd_mode:1;		/* bit 26 */
-		u32 lhd_mode:1;		/* bit 25 */
-		u32 phy_mode:1;		/* bit 24 */
-		u32 reset_per_mii:1;	/* bit 23 */
-		u32 reserved3:6;		/* bits 17-22 */
-		u32 speed:1;		/* bit 16 */
-		u32 reset_pe100x:1;	/* bit 15 */
-		u32 reserved2:4;		/* bits 11-14 */
-		u32 force_quiet:1;		/* bit 10 */
-		u32 no_cipher:1;		/* bit 9 */
-		u32 disable_link_fail:1;	/* bit 8 */
-		u32 reset_gpsi:1;		/* bit 7 */
-		u32 reserved1:6;		/* bits 1-6 */
-		u32 enab_jab_protect:1;	/* bit 0 */
-#else
-		u32 enab_jab_protect:1;	/* bit 0 */
-		u32 reserved1:6;		/* bits 1-6 */
-		u32 reset_gpsi:1;		/* bit 7 */
-		u32 disable_link_fail:1;	/* bit 8 */
-		u32 no_cipher:1;		/* bit 9 */
-		u32 force_quiet:1;		/* bit 10 */
-		u32 reserved2:4;		/* bits 11-14 */
-		u32 reset_pe100x:1;	/* bit 15 */
-		u32 speed:1;		/* bit 16 */
-		u32 reserved3:6;		/* bits 17-22 */
-		u32 reset_per_mii:1;	/* bit 23 */
-		u32 phy_mode:1;		/* bit 24 */
-		u32 lhd_mode:1;		/* bit 25 */
-		u32 ghd_mode:1;		/* bit 26 */
-		u32 tbi_mode:1;		/* bit 27 */
-		u32 reserved4:3;		/* bit 28-30 */
-		u32 reset_if_module:1;	/* bit 31 */
-#endif
-	} bits;
-} MAC_IF_CTRL_t, *PMAC_IF_CTRL_t;
 
 /*
  * structure for Interface Status reg in mac address map.
@@ -1729,21 +1405,21 @@
  * MAC Module of JAGCore Address Mapping
  */
 typedef struct _MAC_t {					/* Location: */
-	MAC_CFG1_t cfg1;				/*  0x5000 */
-	MAC_CFG2_t cfg2;				/*  0x5004 */
-	MAC_IPG_t ipg;					/*  0x5008 */
-	MAC_HFDP_t hfdp;				/*  0x500C */
-	MAC_MAX_FM_LEN_t max_fm_len;			/*  0x5010 */
+	u32 cfg1;					/*  0x5000 */
+	u32 cfg2;					/*  0x5004 */
+	u32 ipg;					/*  0x5008 */
+	u32 hfdp;					/*  0x500C */
+	u32 max_fm_len;					/*  0x5010 */
 	u32 rsv1;					/*  0x5014 */
 	u32 rsv2;					/*  0x5018 */
-	MAC_TEST_t mac_test;				/*  0x501C */
-	MII_MGMT_CFG_t mii_mgmt_cfg;			/*  0x5020 */
-	MII_MGMT_CMD_t mii_mgmt_cmd;			/*  0x5024 */
-	MII_MGMT_ADDR_t mii_mgmt_addr;			/*  0x5028 */
-	MII_MGMT_CTRL_t mii_mgmt_ctrl;			/*  0x502C */
-	MII_MGMT_STAT_t mii_mgmt_stat;			/*  0x5030 */
-	MII_MGMT_INDICATOR_t mii_mgmt_indicator;	/*  0x5034 */
-	MAC_IF_CTRL_t if_ctrl;				/*  0x5038 */
+	u32 mac_test;					/*  0x501C */
+	u32 mii_mgmt_cfg;				/*  0x5020 */
+	u32 mii_mgmt_cmd;				/*  0x5024 */
+	u32 mii_mgmt_addr;				/*  0x5028 */
+	u32 mii_mgmt_ctrl;				/*  0x502C */
+	u32 mii_mgmt_stat;				/*  0x5030 */
+	u32 mii_mgmt_indicator;				/*  0x5034 */
+	u32 if_ctrl;					/*  0x5038 */
 	MAC_IF_STAT_t if_stat;				/*  0x503C */
 	MAC_STATION_ADDR1_t station_addr_1;		/*  0x5040 */
 	MAC_STATION_ADDR2_t station_addr_2;		/*  0x5044 */
@@ -1756,120 +1432,60 @@
 /*
  * structure for Carry Register One and it's Mask Register reg located in mac
  * stat address map address 0x6130 and 0x6138.
+ *
+ * 31: tr64
+ * 30: tr127
+ * 29: tr255
+ * 28: tr511
+ * 27: tr1k
+ * 26: trmax
+ * 25: trmgv
+ * 24-17: unused
+ * 16: rbyt
+ * 15: rpkt
+ * 14: rfcs
+ * 13: rmca
+ * 12: rbca
+ * 11: rxcf
+ * 10: rxpf
+ * 9: rxuo
+ * 8: raln
+ * 7: rflr
+ * 6: rcde
+ * 5: rcse
+ * 4: rund
+ * 3: rovr
+ * 2: rfrg
+ * 1: rjbr
+ * 0: rdrp
  */
-typedef union _MAC_STAT_REG_1_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 tr64:1;	/* bit 31 */
-		u32 tr127:1;	/* bit 30 */
-		u32 tr255:1;	/* bit 29 */
-		u32 tr511:1;	/* bit 28 */
-		u32 tr1k:1;	/* bit 27 */
-		u32 trmax:1;	/* bit 26 */
-		u32 trmgv:1;	/* bit 25 */
-		u32 unused:8;	/* bits 17-24 */
-		u32 rbyt:1;	/* bit 16 */
-		u32 rpkt:1;	/* bit 15 */
-		u32 rfcs:1;	/* bit 14 */
-		u32 rmca:1;	/* bit 13 */
-		u32 rbca:1;	/* bit 12 */
-		u32 rxcf:1;	/* bit 11 */
-		u32 rxpf:1;	/* bit 10 */
-		u32 rxuo:1;	/* bit 9 */
-		u32 raln:1;	/* bit 8 */
-		u32 rflr:1;	/* bit 7 */
-		u32 rcde:1;	/* bit 6 */
-		u32 rcse:1;	/* bit 5 */
-		u32 rund:1;	/* bit 4 */
-		u32 rovr:1;	/* bit 3 */
-		u32 rfrg:1;	/* bit 2 */
-		u32 rjbr:1;	/* bit 1 */
-		u32 rdrp:1;	/* bit 0 */
-#else
-		u32 rdrp:1;	/* bit 0 */
-		u32 rjbr:1;	/* bit 1 */
-		u32 rfrg:1;	/* bit 2 */
-		u32 rovr:1;	/* bit 3 */
-		u32 rund:1;	/* bit 4 */
-		u32 rcse:1;	/* bit 5 */
-		u32 rcde:1;	/* bit 6 */
-		u32 rflr:1;	/* bit 7 */
-		u32 raln:1;	/* bit 8 */
-		u32 rxuo:1;	/* bit 9 */
-		u32 rxpf:1;	/* bit 10 */
-		u32 rxcf:1;	/* bit 11 */
-		u32 rbca:1;	/* bit 12 */
-		u32 rmca:1;	/* bit 13 */
-		u32 rfcs:1;	/* bit 14 */
-		u32 rpkt:1;	/* bit 15 */
-		u32 rbyt:1;	/* bit 16 */
-		u32 unused:8;	/* bits 17-24 */
-		u32 trmgv:1;	/* bit 25 */
-		u32 trmax:1;	/* bit 26 */
-		u32 tr1k:1;	/* bit 27 */
-		u32 tr511:1;	/* bit 28 */
-		u32 tr255:1;	/* bit 29 */
-		u32 tr127:1;	/* bit 30 */
-		u32 tr64:1;	/* bit 31 */
-#endif
-	} bits;
-} MAC_STAT_REG_1_t, *PMAC_STAT_REG_1_t;
 
 /*
  * structure for Carry Register Two Mask Register reg in mac stat address map.
  * located at address 0x613C
+ *
+ * 31-20: unused
+ * 19: tjbr
+ * 18: tfcs
+ * 17: txcf
+ * 16: tovr
+ * 15: tund
+ * 14: trfg
+ * 13: tbyt
+ * 12: tpkt
+ * 11: tmca
+ * 10: tbca
+ * 9: txpf
+ * 8: tdfr
+ * 7: tedf
+ * 6: tscl
+ * 5: tmcl
+ * 4: tlcl
+ * 3: txcl
+ * 2: tncl
+ * 1: tpfh
+ * 0: tdrp
  */
-typedef union _MAC_STAT_REG_2_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:12;	/* bit 20-31 */
-		u32 tjbr:1;	/* bit 19 */
-		u32 tfcs:1;	/* bit 18 */
-		u32 txcf:1;	/* bit 17 */
-		u32 tovr:1;	/* bit 16 */
-		u32 tund:1;	/* bit 15 */
-		u32 tfrg:1;	/* bit 14 */
-		u32 tbyt:1;	/* bit 13 */
-		u32 tpkt:1;	/* bit 12 */
-		u32 tmca:1;	/* bit 11 */
-		u32 tbca:1;	/* bit 10 */
-		u32 txpf:1;	/* bit 9 */
-		u32 tdfr:1;	/* bit 8 */
-		u32 tedf:1;	/* bit 7 */
-		u32 tscl:1;	/* bit 6 */
-		u32 tmcl:1;	/* bit 5 */
-		u32 tlcl:1;	/* bit 4 */
-		u32 txcl:1;	/* bit 3 */
-		u32 tncl:1;	/* bit 2 */
-		u32 tpfh:1;	/* bit 1 */
-		u32 tdrp:1;	/* bit 0 */
-#else
-		u32 tdrp:1;	/* bit 0 */
-		u32 tpfh:1;	/* bit 1 */
-		u32 tncl:1;	/* bit 2 */
-		u32 txcl:1;	/* bit 3 */
-		u32 tlcl:1;	/* bit 4 */
-		u32 tmcl:1;	/* bit 5 */
-		u32 tscl:1;	/* bit 6 */
-		u32 tedf:1;	/* bit 7 */
-		u32 tdfr:1;	/* bit 8 */
-		u32 txpf:1;	/* bit 9 */
-		u32 tbca:1;	/* bit 10 */
-		u32 tmca:1;	/* bit 11 */
-		u32 tpkt:1;	/* bit 12 */
-		u32 tbyt:1;	/* bit 13 */
-		u32 tfrg:1;	/* bit 14 */
-		u32 tund:1;	/* bit 15 */
-		u32 tovr:1;	/* bit 16 */
-		u32 txcf:1;	/* bit 17 */
-		u32 tfcs:1;	/* bit 18 */
-		u32 tjbr:1;	/* bit 19 */
-		u32 unused:12;	/* bit 20-31 */
-#endif
-	} bits;
-} MAC_STAT_REG_2_t, *PMAC_STAT_REG_2_t;
 
 /*
  * MAC STATS Module of JAGCore Address Mapping
@@ -2010,16 +1626,16 @@
 	u32 TFrg;			/*  0x612C */
 
 	/* Carry Register One Register */
-	MAC_STAT_REG_1_t Carry1;	/*  0x6130 */
+	u32 Carry1;			/*  0x6130 */
 
 	/* Carry Register Two Register */
-	MAC_STAT_REG_2_t Carry2;	/*  0x6134 */
+	u32 Carry2;			/*  0x6134 */
 
 	/* Carry Register One Mask Register */
-	MAC_STAT_REG_1_t Carry1M;	/*  0x6138 */
+	u32 Carry1M;			/*  0x6138 */
 
 	/* Carry Register Two Mask Register */
-	MAC_STAT_REG_2_t Carry2M;	/*  0x613C */
+	u32 Carry2M;			/*  0x613C */
 } MAC_STAT_t, *PMAC_STAT_t;
 
 /* END OF MAC STAT REGISTER ADDRESS MAP */
diff --git a/drivers/staging/et131x/et1310_eeprom.c b/drivers/staging/et131x/et1310_eeprom.c
index c853a2c..bcca1f8 100644
--- a/drivers/staging/et131x/et1310_eeprom.c
+++ b/drivers/staging/et131x/et1310_eeprom.c
@@ -95,198 +95,120 @@
 #include "et1310_tx.h"
 
 
-/*
- * EEPROM Defines
- */
 
-/* LBCIF Register Groups (addressed via 32-bit offsets) */
-#define LBCIF_DWORD0_GROUP_OFFSET       0xAC
-#define LBCIF_DWORD1_GROUP_OFFSET       0xB0
+static int eeprom_wait_ready(struct pci_dev *pdev, u32 *status)
+{
+	u32 reg;
+	int i;
 
-/* LBCIF Registers (addressed via 8-bit offsets) */
-#define LBCIF_ADDRESS_REGISTER_OFFSET   0xAC
-#define LBCIF_DATA_REGISTER_OFFSET      0xB0
-#define LBCIF_CONTROL_REGISTER_OFFSET   0xB1
-#define LBCIF_STATUS_REGISTER_OFFSET    0xB2
+	/*
+	 * 1. Check LBCIF Status Register for bits 6 & 3:2 all equal to 0 and
+	 *    bits 7,1:0 both equal to 1, at least once after reset.
+	 *    Subsequent operations need only to check that bits 1:0 are equal
+	 *    to 1 prior to starting a single byte read/write
+	 */
 
-/* LBCIF Control Register Bits */
-#define LBCIF_CONTROL_SEQUENTIAL_READ   0x01
-#define LBCIF_CONTROL_PAGE_WRITE        0x02
-#define LBCIF_CONTROL_UNUSED1           0x04
-#define LBCIF_CONTROL_EEPROM_RELOAD     0x08
-#define LBCIF_CONTROL_UNUSED2           0x10
-#define LBCIF_CONTROL_TWO_BYTE_ADDR     0x20
-#define LBCIF_CONTROL_I2C_WRITE         0x40
-#define LBCIF_CONTROL_LBCIF_ENABLE      0x80
+	for (i = 0; i < MAX_NUM_REGISTER_POLLS; i++) {
+		/* Read registers grouped in DWORD1 */
+		if (pci_read_config_dword(pdev, LBCIF_DWORD1_GROUP, &reg))
+			return -EIO;
 
-/* LBCIF Status Register Bits */
-#define LBCIF_STATUS_PHY_QUEUE_AVAIL    0x01
-#define LBCIF_STATUS_I2C_IDLE           0x02
-#define LBCIF_STATUS_ACK_ERROR          0x04
-#define LBCIF_STATUS_GENERAL_ERROR      0x08
-#define LBCIF_STATUS_UNUSED             0x30
-#define LBCIF_STATUS_CHECKSUM_ERROR     0x40
-#define LBCIF_STATUS_EEPROM_PRESENT     0x80
+		/* I2C idle and Phy Queue Avail both true */
+		if ((reg & 0x3000) == 0x3000) {
+			if (status)
+				*status = reg;
+			return reg & 0xFF;
+		}
+	}
+	return -ETIMEDOUT;
+}
 
-/* Miscellaneous Constraints */
-#define MAX_NUM_REGISTER_POLLS          1000
-#define MAX_NUM_WRITE_RETRIES           2
-
-/*
- * Define macros that allow individual register values to be extracted from a
- * DWORD1 register grouping
- */
-#define EXTRACT_DATA_REGISTER(x)    (u8)(x & 0xFF)
-#define EXTRACT_STATUS_REGISTER(x)  (u8)((x >> 16) & 0xFF)
-#define EXTRACT_CONTROL_REG(x)      (u8)((x >> 8) & 0xFF)
 
 /**
- * EepromWriteByte - Write a byte to the ET1310's EEPROM
+ * eeprom_write - Write a byte to the ET1310's EEPROM
  * @etdev: pointer to our private adapter structure
  * @addr: the address to write
  * @data: the value to write
  *
- * Returns SUCCESS or FAILURE
+ * Returns 1 for a successful write.
  */
-int EepromWriteByte(struct et131x_adapter *etdev, u32 addr, u8 data)
+static int eeprom_write(struct et131x_adapter *etdev, u32 addr, u8 data)
 {
 	struct pci_dev *pdev = etdev->pdev;
-	int index;
+	int index = 0;
 	int retries;
 	int err = 0;
 	int i2c_wack = 0;
 	int writeok = 0;
-	u8 control;
-	u8 status = 0;
-	u32 dword1 = 0;
+	u32 status;
 	u32 val = 0;
 
 	/*
-	 * The following excerpt is from "Serial EEPROM HW Design
-	 * Specification" Version 0.92 (9/20/2004):
-	 *
-	 * Single Byte Writes
-	 *
 	 * For an EEPROM, an I2C single byte write is defined as a START
 	 * condition followed by the device address, EEPROM address, one byte
 	 * of data and a STOP condition.  The STOP condition will trigger the
 	 * EEPROM's internally timed write cycle to the nonvolatile memory.
 	 * All inputs are disabled during this write cycle and the EEPROM will
 	 * not respond to any access until the internal write is complete.
-	 * The steps to execute a single byte write are as follows:
-	 *
-	 * 1. Check LBCIF Status Register for bits 6 & 3:2 all equal to 0 and
-	 *    bits 7,1:0 both equal to 1, at least once after reset.
-	 *    Subsequent operations need only to check that bits 1:0 are
-	 *    equal to 1 prior to starting a single byte write.
-	 *
+	 */
+
+	err = eeprom_wait_ready(pdev, NULL);
+	if (err)
+		return err;
+
+	 /*
 	 * 2. Write to the LBCIF Control Register:  bit 7=1, bit 6=1, bit 3=0,
 	 *    and bits 1:0 both =0.  Bit 5 should be set according to the
 	 *    type of EEPROM being accessed (1=two byte addressing, 0=one
 	 *    byte addressing).
-	 *
-	 * 3. Write the address to the LBCIF Address Register.
-	 *
-	 * 4. Write the data to the LBCIF Data Register (the I2C write will
-	 *    begin).
-	 *
-	 * 5. Monitor bit 1:0 of the LBCIF Status Register.  When bits 1:0 are
-	 *    both equal to 1, the I2C write has completed and the internal
-	 *    write cycle of the EEPROM is about to start. (bits 1:0 = 01 is
-	 *    a legal state while waiting from both equal to 1, but bits
-	 *    1:0 = 10 is invalid and implies that something is broken).
-	 *
-	 * 6. Check bit 3 of the LBCIF Status Register.  If  equal to 1, an
-	 *    error has occurred.
-	 *
-	 * 7. Check bit 2 of the LBCIF Status Register.  If equal to 1 an ACK
-	 *    error has occurred on the address phase of the write.  This
-	 *    could be due to an actual hardware failure or the EEPROM may
-	 *    still be in its internal write cycle from a previous write.
-	 *    This write operation was ignored and must be repeated later.
-	 *
-	 * 8. Set bit 6 of the LBCIF Control Register = 0. If another write is
-	 *    required, go to step 1.
 	 */
-
-	/* Step 1: */
-	for (index = 0; index < MAX_NUM_REGISTER_POLLS; index++) {
-		/* Read registers grouped in DWORD1 */
-		if (pci_read_config_dword(pdev, LBCIF_DWORD1_GROUP_OFFSET,
-					  &dword1)) {
-			err = 1;
-			break;
-		}
-
-		status = EXTRACT_STATUS_REGISTER(dword1);
-
-		if (status & LBCIF_STATUS_PHY_QUEUE_AVAIL &&
-			status & LBCIF_STATUS_I2C_IDLE)
-			/* bits 1:0 are equal to 1 */
-			break;
-	}
-
-	if (err || (index >= MAX_NUM_REGISTER_POLLS))
-		return FAILURE;
-
-	/* Step 2: */
-	control = 0;
-	control |= LBCIF_CONTROL_LBCIF_ENABLE | LBCIF_CONTROL_I2C_WRITE;
-
-	if (pci_write_config_byte(pdev, LBCIF_CONTROL_REGISTER_OFFSET,
-				  control)) {
-		return FAILURE;
-	}
+	if (pci_write_config_byte(pdev, LBCIF_CONTROL_REGISTER,
+			LBCIF_CONTROL_LBCIF_ENABLE | LBCIF_CONTROL_I2C_WRITE))
+		return -EIO;
 
 	i2c_wack = 1;
 
 	/* Prepare EEPROM address for Step 3 */
 
 	for (retries = 0; retries < MAX_NUM_WRITE_RETRIES; retries++) {
-		/* Step 3:*/
-		if (pci_write_config_dword(pdev, LBCIF_ADDRESS_REGISTER_OFFSET,
-					   addr)) {
+		/* Write the address to the LBCIF Address Register */
+		if (pci_write_config_dword(pdev, LBCIF_ADDRESS_REGISTER, addr))
 			break;
-		}
-
-		/* Step 4: */
-		if (pci_write_config_byte(pdev, LBCIF_DATA_REGISTER_OFFSET,
-					  data)) {
+		/*
+		 * Write the data to the LBCIF Data Register (the I2C write
+		 * will begin).
+		 */
+		if (pci_write_config_byte(pdev, LBCIF_DATA_REGISTER, data))
 			break;
-		}
+		/*
+		 * Monitor bit 1:0 of the LBCIF Status Register.  When bits
+		 * 1:0 are both equal to 1, the I2C write has completed and the
+		 * internal write cycle of the EEPROM is about to start.
+		 * (bits 1:0 = 01 is a legal state while waiting from both
+		 * equal to 1, but bits 1:0 = 10 is invalid and implies that
+		 * something is broken).
+		 */
+		err = eeprom_wait_ready(pdev, &status);
+		if (err < 0)
+			return 0;
 
-		/* Step 5: */
-		for (index = 0; index < MAX_NUM_REGISTER_POLLS; index++) {
-			/* Read registers grouped in DWORD1 */
-			if (pci_read_config_dword(pdev,
-						  LBCIF_DWORD1_GROUP_OFFSET,
-						  &dword1)) {
-				err = 1;
-				break;
-			}
-
-			status = EXTRACT_STATUS_REGISTER(dword1);
-
-			if (status & LBCIF_STATUS_PHY_QUEUE_AVAIL &&
-				status & LBCIF_STATUS_I2C_IDLE) {
-				/* I2C write complete */
-				break;
-			}
-		}
-
-		if (err || (index >= MAX_NUM_REGISTER_POLLS))
+		/*
+		 * Check bit 3 of the LBCIF Status Register.  If  equal to 1,
+		 * an error has occurred.Don't break here if we are revision
+		 * 1, this is so we do a blind write for load bug.
+		 */
+		if ((status & LBCIF_STATUS_GENERAL_ERROR)
+			&& etdev->pdev->revision == 0)
 			break;
 
 		/*
-		 * Step 6: Don't break here if we are revision 1, this is
-		 *	   so we do a blind write for load bug.
+		 * Check bit 2 of the LBCIF Status Register.  If equal to 1 an
+		 * ACK error has occurred on the address phase of the write.
+		 * This could be due to an actual hardware failure or the
+		 * EEPROM may still be in its internal write cycle from a
+		 * previous write. This write operation was ignored and must be
+		  *repeated later.
 		 */
-		if (status & LBCIF_STATUS_GENERAL_ERROR
-		    && etdev->pdev->revision == 0) {
-			break;
-		}
-
-		/* Step 7 */
 		if (status & LBCIF_STATUS_ACK_ERROR) {
 			/*
 			 * This could be due to an actual hardware failure
@@ -302,154 +224,160 @@
 		break;
 	}
 
-	/* Step 8: */
+	/*
+	 * Set bit 6 of the LBCIF Control Register = 0.
+	 */
 	udelay(10);
-	index = 0;
-	while (i2c_wack) {
-		control &= ~LBCIF_CONTROL_I2C_WRITE;
 
-		if (pci_write_config_byte(pdev, LBCIF_CONTROL_REGISTER_OFFSET,
-					  control)) {
+	while (i2c_wack) {
+		if (pci_write_config_byte(pdev, LBCIF_CONTROL_REGISTER,
+			LBCIF_CONTROL_LBCIF_ENABLE))
 			writeok = 0;
-		}
 
 		/* Do read until internal ACK_ERROR goes away meaning write
 		 * completed
 		 */
 		do {
 			pci_write_config_dword(pdev,
-					       LBCIF_ADDRESS_REGISTER_OFFSET,
+					       LBCIF_ADDRESS_REGISTER,
 					       addr);
 			do {
 				pci_read_config_dword(pdev,
-					LBCIF_DATA_REGISTER_OFFSET, &val);
+					LBCIF_DATA_REGISTER, &val);
 			} while ((val & 0x00010000) == 0);
 		} while (val & 0x00040000);
 
-		control = EXTRACT_CONTROL_REG(val);
-
-		if (control != 0xC0 || index == 10000)
+		if ((val & 0xFF00) != 0xC000 || index == 10000)
 			break;
-
 		index++;
 	}
-
-	return writeok ? SUCCESS : FAILURE;
+	return writeok ? 0 : -EIO;
 }
 
 /**
- * EepromReadByte - Read a byte from the ET1310's EEPROM
+ * eeprom_read - Read a byte from the ET1310's EEPROM
  * @etdev: pointer to our private adapter structure
  * @addr: the address from which to read
  * @pdata: a pointer to a byte in which to store the value of the read
  * @eeprom_id: the ID of the EEPROM
  * @addrmode: how the EEPROM is to be accessed
  *
- * Returns SUCCESS or FAILURE
+ * Returns 1 for a successful read
  */
-int EepromReadByte(struct et131x_adapter *etdev, u32 addr, u8 *pdata)
+static int eeprom_read(struct et131x_adapter *etdev, u32 addr, u8 *pdata)
 {
 	struct pci_dev *pdev = etdev->pdev;
-	int index;
-	int err = 0;
-	u8 control;
-	u8 status = 0;
-	u32 dword1 = 0;
+	int err;
+	u32 status;
 
 	/*
-	 * The following excerpt is from "Serial EEPROM HW Design
-	 * Specification" Version 0.92 (9/20/2004):
-	 *
-	 * Single Byte Reads
-	 *
 	 * A single byte read is similar to the single byte write, with the
 	 * exception of the data flow:
-	 *
-	 * 1. Check LBCIF Status Register for bits 6 & 3:2 all equal to 0 and
-	 *    bits 7,1:0 both equal to 1, at least once after reset.
-	 *    Subsequent operations need only to check that bits 1:0 are equal
-	 *    to 1 prior to starting a single byte read.
-	 *
-	 * 2. Write to the LBCIF Control Register:  bit 7=1, bit 6=0, bit 3=0,
-	 *    and bits 1:0 both =0.  Bit 5 should be set according to the type
-	 *    of EEPROM being accessed (1=two byte addressing, 0=one byte
-	 *    addressing).
-	 *
-	 * 3. Write the address to the LBCIF Address Register (I2C read will
-	 *    begin).
-	 *
-	 * 4. Monitor bit 0 of the LBCIF Status Register.  When =1, I2C read
-	 *    is complete. (if bit 1 =1 and bit 0 stays =0, a hardware failure
-	 *    has occurred).
-	 *
-	 * 5. Check bit 2 of the LBCIF Status Register.  If =1, then an error
-	 *    has occurred.  The data that has been returned from the PHY may
-	 *    be invalid.
-	 *
-	 * 6. Regardless of error status, read data byte from LBCIF Data
-	 *    Register.  If another byte is required, go to step 1.
 	 */
 
-	/* Step 1: */
-	for (index = 0; index < MAX_NUM_REGISTER_POLLS; index++) {
-		/* Read registers grouped in DWORD1 */
-		if (pci_read_config_dword(pdev, LBCIF_DWORD1_GROUP_OFFSET,
-					  &dword1)) {
-			err = 1;
-			break;
-		}
+	err = eeprom_wait_ready(pdev, NULL);
+	if (err)
+		return err;
+ 	/*
+	 * Write to the LBCIF Control Register:  bit 7=1, bit 6=0, bit 3=0,
+	 * and bits 1:0 both =0.  Bit 5 should be set according to the type
+	 * of EEPROM being accessed (1=two byte addressing, 0=one byte
+	 * addressing).
+	 */
+	if (pci_write_config_byte(pdev, LBCIF_CONTROL_REGISTER,
+				  LBCIF_CONTROL_LBCIF_ENABLE))
+		return -EIO;
+	/*
+	 * Write the address to the LBCIF Address Register (I2C read will
+	 * begin).
+	 */
+	if (pci_write_config_dword(pdev, LBCIF_ADDRESS_REGISTER, addr))
+		return -EIO;
+	/*
+	 * Monitor bit 0 of the LBCIF Status Register.  When = 1, I2C read
+	 * is complete. (if bit 1 =1 and bit 0 stays = 0, a hardware failure
+	 * has occurred).
+	 */
+	err = eeprom_wait_ready(pdev, &status);
+	if (err < 0)
+		return err;
+	/*
+	 * Regardless of error status, read data byte from LBCIF Data
+	 * Register.
+	 */
+	*pdata = err;
+	/*
+	 * Check bit 2 of the LBCIF Status Register.  If = 1,
+	 * then an error has occurred.
+	 */
+	return (status & LBCIF_STATUS_ACK_ERROR) ? -EIO : 0;
+}
 
-		status = EXTRACT_STATUS_REGISTER(dword1);
+int et131x_init_eeprom(struct et131x_adapter *etdev)
+{
+	struct pci_dev *pdev = etdev->pdev;
+	u8 eestatus;
 
-		if (status & LBCIF_STATUS_PHY_QUEUE_AVAIL &&
-		    status & LBCIF_STATUS_I2C_IDLE) {
-			/* bits 1:0 are equal to 1 */
-			break;
-		}
+	/* We first need to check the EEPROM Status code located at offset
+	 * 0xB2 of config space
+	 */
+	pci_read_config_byte(pdev, ET1310_PCI_EEPROM_STATUS,
+				      &eestatus);
+
+	/* THIS IS A WORKAROUND:
+	 * I need to call this function twice to get my card in a
+	 * LG M1 Express Dual running. I tried also a msleep before this
+	 * function, because I thougth there could be some time condidions
+	 * but it didn't work. Call the whole function twice also work.
+	 */
+	if (pci_read_config_byte(pdev, ET1310_PCI_EEPROM_STATUS, &eestatus)) {
+		dev_err(&pdev->dev,
+		       "Could not read PCI config space for EEPROM Status\n");
+		return -EIO;
 	}
 
-	if (err || (index >= MAX_NUM_REGISTER_POLLS))
-		return FAILURE;
+	/* Determine if the error(s) we care about are present. If they are
+	 * present we need to fail.
+	 */
+	if (eestatus & 0x4C) {
+		int write_failed = 0;
+		if (pdev->revision == 0x01) {
+			int	i;
+			static const u8 eedata[4] = { 0xFE, 0x13, 0x10, 0xFF };
 
-	/* Step 2: */
-	control = 0;
-	control |= LBCIF_CONTROL_LBCIF_ENABLE;
-
-	if (pci_write_config_byte(pdev, LBCIF_CONTROL_REGISTER_OFFSET,
-				  control)) {
-		return FAILURE;
-	}
-
-	/* Step 3: */
-
-	if (pci_write_config_dword(pdev, LBCIF_ADDRESS_REGISTER_OFFSET,
-				   addr)) {
-		return FAILURE;
-	}
-
-	/* Step 4: */
-	for (index = 0; index < MAX_NUM_REGISTER_POLLS; index++) {
-		/* Read registers grouped in DWORD1 */
-		if (pci_read_config_dword(pdev, LBCIF_DWORD1_GROUP_OFFSET,
-					  &dword1)) {
-			err = 1;
-			break;
+			/* Re-write the first 4 bytes if we have an eeprom
+			 * present and the revision id is 1, this fixes the
+			 * corruption seen with 1310 B Silicon
+			 */
+			for (i = 0; i < 3; i++)
+				if (eeprom_write(etdev, i, eedata[i]) < 0)
+					write_failed = 1;
 		}
+		if (pdev->revision  != 0x01 || write_failed) {
+			dev_err(&pdev->dev,
+			    "Fatal EEPROM Status Error - 0x%04x\n", eestatus);
 
-		status = EXTRACT_STATUS_REGISTER(dword1);
-
-		if (status & LBCIF_STATUS_PHY_QUEUE_AVAIL
-		    && status & LBCIF_STATUS_I2C_IDLE) {
-			/* I2C read complete */
-			break;
+			/* This error could mean that there was an error
+			 * reading the eeprom or that the eeprom doesn't exist.
+			 * We will treat each case the same and not try to gather
+			 * additional information that normally would come from the
+			 * eeprom, like MAC Address
+			 */
+			etdev->has_eeprom = 0;
+			return -EIO;
 		}
 	}
+	etdev->has_eeprom = 1;
 
-	if (err || (index >= MAX_NUM_REGISTER_POLLS))
-		return FAILURE;
+	/* Read the EEPROM for information regarding LED behavior. Refer to
+	 * ET1310_phy.c, et131x_xcvr_init(), for its use.
+	 */
+	eeprom_read(etdev, 0x70, &etdev->eepromData[0]);
+	eeprom_read(etdev, 0x71, &etdev->eepromData[1]);
 
-	/* Step 6: */
-	*pdata = EXTRACT_DATA_REGISTER(dword1);
+	if (etdev->eepromData[0] != 0xcd)
+		/* Disable all optional features */
+		etdev->eepromData[1] = 0x00;
 
-	return (status & LBCIF_STATUS_ACK_ERROR) ? FAILURE : SUCCESS;
+	return 0;
 }
diff --git a/drivers/staging/et131x/et1310_eeprom.h b/drivers/staging/et131x/et1310_eeprom.h
index d8ac9a0..6a6c6a6 100644
--- a/drivers/staging/et131x/et1310_eeprom.h
+++ b/drivers/staging/et131x/et1310_eeprom.h
@@ -61,17 +61,43 @@
 
 #include "et1310_address_map.h"
 
-#ifndef SUCCESS
-#define SUCCESS		0
-#define FAILURE		1
-#endif
+/*
+ * EEPROM Defines
+ */
+
+/* LBCIF Register Groups (addressed via 32-bit offsets) */
+#define LBCIF_DWORD0_GROUP       0xAC
+#define LBCIF_DWORD1_GROUP       0xB0
+
+/* LBCIF Registers (addressed via 8-bit offsets) */
+#define LBCIF_ADDRESS_REGISTER   0xAC
+#define LBCIF_DATA_REGISTER      0xB0
+#define LBCIF_CONTROL_REGISTER   0xB1
+#define LBCIF_STATUS_REGISTER    0xB2
+
+/* LBCIF Control Register Bits */
+#define LBCIF_CONTROL_SEQUENTIAL_READ   0x01
+#define LBCIF_CONTROL_PAGE_WRITE        0x02
+#define LBCIF_CONTROL_EEPROM_RELOAD     0x08
+#define LBCIF_CONTROL_TWO_BYTE_ADDR     0x20
+#define LBCIF_CONTROL_I2C_WRITE         0x40
+#define LBCIF_CONTROL_LBCIF_ENABLE      0x80
+
+/* LBCIF Status Register Bits */
+#define LBCIF_STATUS_PHY_QUEUE_AVAIL    0x01
+#define LBCIF_STATUS_I2C_IDLE           0x02
+#define LBCIF_STATUS_ACK_ERROR          0x04
+#define LBCIF_STATUS_GENERAL_ERROR      0x08
+#define LBCIF_STATUS_CHECKSUM_ERROR     0x40
+#define LBCIF_STATUS_EEPROM_PRESENT     0x80
+
+/* Miscellaneous Constraints */
+#define MAX_NUM_REGISTER_POLLS          1000
+#define MAX_NUM_WRITE_RETRIES           2
 
 /* Forward declaration of the private adapter structure */
 struct et131x_adapter;
 
-int32_t EepromWriteByte(struct et131x_adapter *adapter, u32 unAddress,
-			u8 bData);
-int32_t EepromReadByte(struct et131x_adapter *adapter, u32 unAddress,
-			u8 *pbData);
+int et131x_init_eeprom(struct et131x_adapter *etdev);
 
 #endif /* _ET1310_EEPROM_H_ */
diff --git a/drivers/staging/et131x/et1310_mac.c b/drivers/staging/et131x/et1310_mac.c
index f81e1cb..b8a1f20 100644
--- a/drivers/staging/et131x/et1310_mac.c
+++ b/drivers/staging/et131x/et1310_mac.c
@@ -101,41 +101,27 @@
 	struct _MAC_t __iomem *pMac = &etdev->regs->mac;
 	MAC_STATION_ADDR1_t station1;
 	MAC_STATION_ADDR2_t station2;
-	MAC_IPG_t ipg;
-	MAC_HFDP_t hfdp;
-	MII_MGMT_CFG_t mii_mgmt_cfg;
+	u32 ipg;
 
 	/* First we need to reset everything.  Write to MAC configuration
 	 * register 1 to perform reset.
 	 */
-	writel(0xC00F0000, &pMac->cfg1.value);
+	writel(0xC00F0000, &pMac->cfg1);
 
 	/* Next lets configure the MAC Inter-packet gap register */
-	ipg.bits.non_B2B_ipg_1 = 0x38;		/* 58d */
-	ipg.bits.non_B2B_ipg_2 = 0x58;		/* 88d */
-	ipg.bits.min_ifg_enforce = 0x50;	/* 80d */
-	ipg.bits.B2B_ipg = 0x60;		/* 96d */
-	writel(ipg.value, &pMac->ipg.value);
+	ipg = 0x38005860;		/* IPG1 0x38 IPG2 0x58 B2B 0x60 */
+	ipg |= 0x50 << 8;		/* ifg enforce 0x50 */
+	writel(ipg, &pMac->ipg);
 
 	/* Next lets configure the MAC Half Duplex register */
-	hfdp.bits.alt_beb_trunc = 0xA;
-	hfdp.bits.alt_beb_enable = 0x0;
-	hfdp.bits.bp_no_backoff = 0x0;
-	hfdp.bits.no_backoff = 0x0;
-	hfdp.bits.excess_defer = 0x1;
-	hfdp.bits.rexmit_max = 0xF;
-	hfdp.bits.coll_window = 0x37;		/* 55d */
-	writel(hfdp.value, &pMac->hfdp.value);
+	/* BEB trunc 0xA, Ex Defer, Rexmit 0xF Coll 0x37 */
+	writel(0x00A1F037, &pMac->hfdp);
 
 	/* Next lets configure the MAC Interface Control register */
-	writel(0, &pMac->if_ctrl.value);
+	writel(0, &pMac->if_ctrl);
 
 	/* Let's move on to setting up the mii management configuration */
-	mii_mgmt_cfg.bits.reset_mii_mgmt = 0;
-	mii_mgmt_cfg.bits.scan_auto_incremt = 0;
-	mii_mgmt_cfg.bits.preamble_suppress = 0;
-	mii_mgmt_cfg.bits.mgmt_clk_reset = 0x7;
-	writel(mii_mgmt_cfg.value, &pMac->mii_mgmt_cfg.value);
+	writel(0x07, &pMac->mii_mgmt_cfg);	/* Clock reset 0x7 */
 
 	/* Next lets configure the MAC Station Address register.  These
 	 * values are read from the EEPROM during initialization and stored
@@ -160,10 +146,10 @@
 	 * Packets larger than (RegistryJumboPacket) that do not contain a
 	 * VLAN ID will be dropped by the Rx function.
 	 */
-	writel(etdev->RegistryJumboPacket + 4, &pMac->max_fm_len.value);
+	writel(etdev->RegistryJumboPacket + 4, &pMac->max_fm_len);
 
 	/* clear out MAC config reset */
-	writel(0, &pMac->cfg1.value);
+	writel(0, &pMac->cfg1);
 }
 
 /**
@@ -174,79 +160,62 @@
 {
 	int32_t delay = 0;
 	struct _MAC_t __iomem *pMac = &etdev->regs->mac;
-	MAC_CFG1_t cfg1;
-	MAC_CFG2_t cfg2;
-	MAC_IF_CTRL_t ifctrl;
+	u32 cfg1;
+	u32 cfg2;
+	u32 ifctrl;
 	TXMAC_CTL_t ctl;
 
 	ctl.value = readl(&etdev->regs->txmac.ctl.value);
-	cfg1.value = readl(&pMac->cfg1.value);
-	cfg2.value = readl(&pMac->cfg2.value);
-	ifctrl.value = readl(&pMac->if_ctrl.value);
+	cfg1 = readl(&pMac->cfg1);
+	cfg2 = readl(&pMac->cfg2);
+	ifctrl = readl(&pMac->if_ctrl);
 
+	/* Set up the if mode bits */
+	cfg2 &= ~0x300;
 	if (etdev->linkspeed == TRUEPHY_SPEED_1000MBPS) {
-		cfg2.bits.if_mode = 0x2;
-		ifctrl.bits.phy_mode = 0x0;
+		cfg2 |= 0x200;
+		/* Phy mode bit */
+		ifctrl &= ~(1 << 24);
 	} else {
-		cfg2.bits.if_mode = 0x1;
-		ifctrl.bits.phy_mode = 0x1;
+		cfg2 |= 0x100;
+		ifctrl |= (1 << 24);
 	}
 
 	/* We need to enable Rx/Tx */
-	cfg1.bits.rx_enable = 0x1;
-	cfg1.bits.tx_enable = 0x1;
-
-	/* Set up flow control */
-	cfg1.bits.tx_flow = 0x1;
-
-	if ((etdev->FlowControl == RxOnly) ||
-	    (etdev->FlowControl == Both)) {
-		cfg1.bits.rx_flow = 0x1;
-	} else {
-		cfg1.bits.rx_flow = 0x0;
-	}
-
+	cfg1 |= CFG1_RX_ENABLE|CFG1_TX_ENABLE|CFG1_TX_FLOW;
 	/* Initialize loop back to off */
-	cfg1.bits.loop_back = 0;
-
-	writel(cfg1.value, &pMac->cfg1.value);
+	cfg1 &= ~(CFG1_LOOPBACK|CFG1_RX_FLOW);
+	if (etdev->FlowControl == RxOnly || etdev->FlowControl == Both)
+		cfg1 |= CFG1_RX_FLOW;
+	writel(cfg1, &pMac->cfg1);
 
 	/* Now we need to initialize the MAC Configuration 2 register */
-	cfg2.bits.preamble_len = 0x7;
-	cfg2.bits.huge_frame = 0x0;
-	/* LENGTH FIELD CHECKING bit4: Set this bit to cause the MAC to check
-	 * the frame's length field to ensure it matches the actual data
-	 * field length. Clear this bit if no length field checking is
-	 * desired. Its default is 0.
-	 */
-	cfg2.bits.len_check = 0x1;
+	/* preamble 7, check length, huge frame off, pad crc, crc enable
+	   full duplex off */
+	cfg2 |= 0x7016;
+	cfg2 &= ~0x0021;
 
-	if (etdev->RegistryPhyLoopbk == false) {
-		cfg2.bits.pad_crc = 0x1;
-		cfg2.bits.crc_enable = 0x1;
-	} else {
-		cfg2.bits.pad_crc = 0;
-		cfg2.bits.crc_enable = 0;
-	}
+	/* Turn on duplex if needed */
+	if (etdev->duplex_mode)
+		cfg2 |= 0x01;
 
-	/* 1 - full duplex, 0 - half-duplex */
-	cfg2.bits.full_duplex = etdev->duplex_mode;
-	ifctrl.bits.ghd_mode = !etdev->duplex_mode;
+	ifctrl &= ~(1 << 26);
+	if (!etdev->duplex_mode)
+		ifctrl |= (1<<26);	/* Enable ghd */
 
-	writel(ifctrl.value, &pMac->if_ctrl.value);
-	writel(cfg2.value, &pMac->cfg2.value);
+	writel(ifctrl, &pMac->if_ctrl);
+	writel(cfg2, &pMac->cfg2);
 
 	do {
 		udelay(10);
 		delay++;
-		cfg1.value = readl(&pMac->cfg1.value);
-	} while ((!cfg1.bits.syncd_rx_en || !cfg1.bits.syncd_tx_en) &&
-								 delay < 100);
+		cfg1 = readl(&pMac->cfg1);
+	} while ((cfg1 & CFG1_WAIT) != CFG1_WAIT && delay < 100);
 
 	if (delay == 100) {
 		dev_warn(&etdev->pdev->dev,
 		    "Syncd bits did not respond correctly cfg1 word 0x%08x\n",
-			cfg1.value);
+			cfg1);
 	}
 
 	/* Enable TXMAC */
@@ -402,106 +371,47 @@
 void ConfigTxMacRegs(struct et131x_adapter *etdev)
 {
 	struct _TXMAC_t __iomem *pTxMac = &etdev->regs->txmac;
-	TXMAC_CF_PARAM_t Local;
 
 	/* We need to update the Control Frame Parameters
 	 * cfpt - control frame pause timer set to 64 (0x40)
 	 * cfep - control frame extended pause timer set to 0x0
 	 */
-	if (etdev->FlowControl == None) {
-		writel(0, &pTxMac->cf_param.value);
-	} else {
-		Local.bits.cfpt = 0x40;
-		Local.bits.cfep = 0x0;
-		writel(Local.value, &pTxMac->cf_param.value);
-	}
+	if (etdev->FlowControl == None)
+		writel(0, &pTxMac->cf_param);
+	else
+		writel(0x40, &pTxMac->cf_param);
 }
 
 void ConfigMacStatRegs(struct et131x_adapter *etdev)
 {
-	struct _MAC_STAT_t __iomem *pDevMacStat =
+	struct _MAC_STAT_t __iomem *macstat =
 		&etdev->regs->macStat;
 
 	/* Next we need to initialize all the MAC_STAT registers to zero on
 	 * the device.
 	 */
-	writel(0, &pDevMacStat->RFcs);
-	writel(0, &pDevMacStat->RAln);
-	writel(0, &pDevMacStat->RFlr);
-	writel(0, &pDevMacStat->RDrp);
-	writel(0, &pDevMacStat->RCde);
-	writel(0, &pDevMacStat->ROvr);
-	writel(0, &pDevMacStat->RFrg);
+	writel(0, &macstat->RFcs);
+	writel(0, &macstat->RAln);
+	writel(0, &macstat->RFlr);
+	writel(0, &macstat->RDrp);
+	writel(0, &macstat->RCde);
+	writel(0, &macstat->ROvr);
+	writel(0, &macstat->RFrg);
 
-	writel(0, &pDevMacStat->TScl);
-	writel(0, &pDevMacStat->TDfr);
-	writel(0, &pDevMacStat->TMcl);
-	writel(0, &pDevMacStat->TLcl);
-	writel(0, &pDevMacStat->TNcl);
-	writel(0, &pDevMacStat->TOvr);
-	writel(0, &pDevMacStat->TUnd);
+	writel(0, &macstat->TScl);
+	writel(0, &macstat->TDfr);
+	writel(0, &macstat->TMcl);
+	writel(0, &macstat->TLcl);
+	writel(0, &macstat->TNcl);
+	writel(0, &macstat->TOvr);
+	writel(0, &macstat->TUnd);
 
 	/* Unmask any counters that we want to track the overflow of.
 	 * Initially this will be all counters.  It may become clear later
 	 * that we do not need to track all counters.
 	 */
-	{
-		MAC_STAT_REG_1_t Carry1M = { 0xffffffff };
-
-		Carry1M.bits.rdrp = 0;
-		Carry1M.bits.rjbr = 1;
-		Carry1M.bits.rfrg = 0;
-		Carry1M.bits.rovr = 0;
-		Carry1M.bits.rund = 1;
-		Carry1M.bits.rcse = 1;
-		Carry1M.bits.rcde = 0;
-		Carry1M.bits.rflr = 0;
-		Carry1M.bits.raln = 0;
-		Carry1M.bits.rxuo = 1;
-		Carry1M.bits.rxpf = 1;
-		Carry1M.bits.rxcf = 1;
-		Carry1M.bits.rbca = 1;
-		Carry1M.bits.rmca = 1;
-		Carry1M.bits.rfcs = 0;
-		Carry1M.bits.rpkt = 1;
-		Carry1M.bits.rbyt = 1;
-		Carry1M.bits.trmgv = 1;
-		Carry1M.bits.trmax = 1;
-		Carry1M.bits.tr1k = 1;
-		Carry1M.bits.tr511 = 1;
-		Carry1M.bits.tr255 = 1;
-		Carry1M.bits.tr127 = 1;
-		Carry1M.bits.tr64 = 1;
-
-		writel(Carry1M.value, &pDevMacStat->Carry1M.value);
-	}
-
-	{
-		MAC_STAT_REG_2_t Carry2M = { 0xffffffff };
-
-		Carry2M.bits.tdrp = 1;
-		Carry2M.bits.tpfh = 1;
-		Carry2M.bits.tncl = 0;
-		Carry2M.bits.txcl = 1;
-		Carry2M.bits.tlcl = 0;
-		Carry2M.bits.tmcl = 0;
-		Carry2M.bits.tscl = 0;
-		Carry2M.bits.tedf = 1;
-		Carry2M.bits.tdfr = 0;
-		Carry2M.bits.txpf = 1;
-		Carry2M.bits.tbca = 1;
-		Carry2M.bits.tmca = 1;
-		Carry2M.bits.tpkt = 1;
-		Carry2M.bits.tbyt = 1;
-		Carry2M.bits.tfrg = 1;
-		Carry2M.bits.tund = 0;
-		Carry2M.bits.tovr = 0;
-		Carry2M.bits.txcf = 1;
-		Carry2M.bits.tfcs = 1;
-		Carry2M.bits.tjbr = 1;
-
-		writel(Carry2M.value, &pDevMacStat->Carry2M.value);
-	}
+	writel(0xFFFFBE32, &macstat->Carry1M);
+	writel(0xFFFE7E8B, &macstat->Carry2M);
 }
 
 void ConfigFlowControl(struct et131x_adapter *etdev)
@@ -509,28 +419,28 @@
 	if (etdev->duplex_mode == 0) {
 		etdev->FlowControl = None;
 	} else {
-		char RemotePause, RemoteAsyncPause;
+		char remote_pause, remote_async_pause;
 
 		ET1310_PhyAccessMiBit(etdev,
-				      TRUEPHY_BIT_READ, 5, 10, &RemotePause);
+				      TRUEPHY_BIT_READ, 5, 10, &remote_pause);
 		ET1310_PhyAccessMiBit(etdev,
 				      TRUEPHY_BIT_READ, 5, 11,
-				      &RemoteAsyncPause);
+				      &remote_async_pause);
 
-		if ((RemotePause == TRUEPHY_BIT_SET) &&
-		    (RemoteAsyncPause == TRUEPHY_BIT_SET)) {
+		if ((remote_pause == TRUEPHY_BIT_SET) &&
+		    (remote_async_pause == TRUEPHY_BIT_SET)) {
 			etdev->FlowControl = etdev->RegistryFlowControl;
-		} else if ((RemotePause == TRUEPHY_BIT_SET) &&
-			   (RemoteAsyncPause == TRUEPHY_BIT_CLEAR)) {
+		} else if ((remote_pause == TRUEPHY_BIT_SET) &&
+			   (remote_async_pause == TRUEPHY_BIT_CLEAR)) {
 			if (etdev->RegistryFlowControl == Both)
 				etdev->FlowControl = Both;
 			else
 				etdev->FlowControl = None;
-		} else if ((RemotePause == TRUEPHY_BIT_CLEAR) &&
-			   (RemoteAsyncPause == TRUEPHY_BIT_CLEAR)) {
+		} else if ((remote_pause == TRUEPHY_BIT_CLEAR) &&
+			   (remote_async_pause == TRUEPHY_BIT_CLEAR)) {
 			etdev->FlowControl = None;
-		} else {/* if (RemotePause == TRUEPHY_CLEAR_BIT &&
-			       RemoteAsyncPause == TRUEPHY_SET_BIT) */
+		} else {/* if (remote_pause == TRUEPHY_CLEAR_BIT &&
+			       remote_async_pause == TRUEPHY_SET_BIT) */
 			if (etdev->RegistryFlowControl == Both)
 				etdev->FlowControl = RxOnly;
 			else
@@ -546,25 +456,25 @@
 void UpdateMacStatHostCounters(struct et131x_adapter *etdev)
 {
 	struct _ce_stats_t *stats = &etdev->Stats;
-	struct _MAC_STAT_t __iomem *pDevMacStat =
+	struct _MAC_STAT_t __iomem *macstat =
 		&etdev->regs->macStat;
 
-	stats->collisions += readl(&pDevMacStat->TNcl);
-	stats->first_collision += readl(&pDevMacStat->TScl);
-	stats->tx_deferred += readl(&pDevMacStat->TDfr);
-	stats->excessive_collisions += readl(&pDevMacStat->TMcl);
-	stats->late_collisions += readl(&pDevMacStat->TLcl);
-	stats->tx_uflo += readl(&pDevMacStat->TUnd);
-	stats->max_pkt_error += readl(&pDevMacStat->TOvr);
+	stats->collisions += readl(&macstat->TNcl);
+	stats->first_collision += readl(&macstat->TScl);
+	stats->tx_deferred += readl(&macstat->TDfr);
+	stats->excessive_collisions += readl(&macstat->TMcl);
+	stats->late_collisions += readl(&macstat->TLcl);
+	stats->tx_uflo += readl(&macstat->TUnd);
+	stats->max_pkt_error += readl(&macstat->TOvr);
 
-	stats->alignment_err += readl(&pDevMacStat->RAln);
-	stats->crc_err += readl(&pDevMacStat->RCde);
-	stats->norcvbuf += readl(&pDevMacStat->RDrp);
-	stats->rx_ov_flow += readl(&pDevMacStat->ROvr);
-	stats->code_violations += readl(&pDevMacStat->RFcs);
-	stats->length_err += readl(&pDevMacStat->RFlr);
+	stats->alignment_err += readl(&macstat->RAln);
+	stats->crc_err += readl(&macstat->RCde);
+	stats->norcvbuf += readl(&macstat->RDrp);
+	stats->rx_ov_flow += readl(&macstat->ROvr);
+	stats->code_violations += readl(&macstat->RFcs);
+	stats->length_err += readl(&macstat->RFlr);
 
-	stats->other_errors += readl(&pDevMacStat->RFrg);
+	stats->other_errors += readl(&macstat->RFrg);
 }
 
 /**
@@ -577,17 +487,17 @@
  */
 void HandleMacStatInterrupt(struct et131x_adapter *etdev)
 {
-	MAC_STAT_REG_1_t Carry1;
-	MAC_STAT_REG_2_t Carry2;
+	u32 Carry1;
+	u32 Carry2;
 
 	/* Read the interrupt bits from the register(s).  These are Clear On
 	 * Write.
 	 */
-	Carry1.value = readl(&etdev->regs->macStat.Carry1.value);
-	Carry2.value = readl(&etdev->regs->macStat.Carry2.value);
+	Carry1 = readl(&etdev->regs->macStat.Carry1);
+	Carry2 = readl(&etdev->regs->macStat.Carry2);
 
-	writel(Carry1.value, &etdev->regs->macStat.Carry1.value);
-	writel(Carry2.value, &etdev->regs->macStat.Carry2.value);
+	writel(Carry1, &etdev->regs->macStat.Carry1);
+	writel(Carry2, &etdev->regs->macStat.Carry2);
 
 	/* We need to do update the host copy of all the MAC_STAT counters.
 	 * For each counter, check it's overflow bit.  If the overflow bit is
@@ -595,33 +505,33 @@
 	 * revolution of the counter.  This routine is called when the counter
 	 * block indicates that one of the counters has wrapped.
 	 */
-	if (Carry1.bits.rfcs)
+	if (Carry1 & (1 << 14))
 		etdev->Stats.code_violations += COUNTER_WRAP_16_BIT;
-	if (Carry1.bits.raln)
+	if (Carry1 & (1 << 8))
 		etdev->Stats.alignment_err += COUNTER_WRAP_12_BIT;
-	if (Carry1.bits.rflr)
+	if (Carry1 & (1 << 7))
 		etdev->Stats.length_err += COUNTER_WRAP_16_BIT;
-	if (Carry1.bits.rfrg)
+	if (Carry1 & (1 << 2))
 		etdev->Stats.other_errors += COUNTER_WRAP_16_BIT;
-	if (Carry1.bits.rcde)
+	if (Carry1 & (1 << 6))
 		etdev->Stats.crc_err += COUNTER_WRAP_16_BIT;
-	if (Carry1.bits.rovr)
+	if (Carry1 & (1 << 3))
 		etdev->Stats.rx_ov_flow += COUNTER_WRAP_16_BIT;
-	if (Carry1.bits.rdrp)
+	if (Carry1 & (1 << 0))
 		etdev->Stats.norcvbuf += COUNTER_WRAP_16_BIT;
-	if (Carry2.bits.tovr)
+	if (Carry2 & (1 << 16))
 		etdev->Stats.max_pkt_error += COUNTER_WRAP_12_BIT;
-	if (Carry2.bits.tund)
+	if (Carry2 & (1 << 15))
 		etdev->Stats.tx_uflo += COUNTER_WRAP_12_BIT;
-	if (Carry2.bits.tscl)
+	if (Carry2 & (1 << 6))
 		etdev->Stats.first_collision += COUNTER_WRAP_12_BIT;
-	if (Carry2.bits.tdfr)
+	if (Carry2 & (1 << 8))
 		etdev->Stats.tx_deferred += COUNTER_WRAP_12_BIT;
-	if (Carry2.bits.tmcl)
+	if (Carry2 & (1 << 5))
 		etdev->Stats.excessive_collisions += COUNTER_WRAP_12_BIT;
-	if (Carry2.bits.tlcl)
+	if (Carry2 & (1 << 4))
 		etdev->Stats.late_collisions += COUNTER_WRAP_12_BIT;
-	if (Carry2.bits.tncl)
+	if (Carry2 & (1 << 2))
 		etdev->Stats.collisions += COUNTER_WRAP_12_BIT;
 }
 
diff --git a/drivers/staging/et131x/et1310_phy.c b/drivers/staging/et131x/et1310_phy.c
index dd199bd..6ecad61 100644
--- a/drivers/staging/et131x/et1310_phy.c
+++ b/drivers/staging/et131x/et1310_phy.c
@@ -98,238 +98,498 @@
 #include "et1310_mac.h"
 
 /* Prototypes for functions with local scope */
-static int et131x_xcvr_init(struct et131x_adapter *adapter);
+static void et131x_xcvr_init(struct et131x_adapter *etdev);
 
 /**
  * PhyMiRead - Read from the PHY through the MII Interface on the MAC
- * @adapter: pointer to our private adapter structure
+ * @etdev: pointer to our private adapter structure
  * @xcvrAddr: the address of the transciever
  * @xcvrReg: the register to read
  * @value: pointer to a 16-bit value in which the value will be stored
  *
  * Returns 0 on success, errno on failure (as defined in errno.h)
  */
-int PhyMiRead(struct et131x_adapter *adapter, uint8_t xcvrAddr,
-	      uint8_t xcvrReg, uint16_t *value)
+int PhyMiRead(struct et131x_adapter *etdev, u8 xcvrAddr,
+	      u8 xcvrReg, u16 *value)
 {
-	struct _MAC_t __iomem *mac = &adapter->regs->mac;
+	struct _MAC_t __iomem *mac = &etdev->regs->mac;
 	int status = 0;
-	uint32_t delay;
-	MII_MGMT_ADDR_t miiAddr;
-	MII_MGMT_CMD_t miiCmd;
-	MII_MGMT_INDICATOR_t miiIndicator;
+	u32 delay;
+	u32 miiAddr;
+	u32 miiCmd;
+	u32 miiIndicator;
 
 	/* Save a local copy of the registers we are dealing with so we can
 	 * set them back
 	 */
-	miiAddr.value = readl(&mac->mii_mgmt_addr.value);
-	miiCmd.value = readl(&mac->mii_mgmt_cmd.value);
+	miiAddr = readl(&mac->mii_mgmt_addr);
+	miiCmd = readl(&mac->mii_mgmt_cmd);
 
 	/* Stop the current operation */
-	writel(0, &mac->mii_mgmt_cmd.value);
+	writel(0, &mac->mii_mgmt_cmd);
 
 	/* Set up the register we need to read from on the correct PHY */
-	{
-		MII_MGMT_ADDR_t mii_mgmt_addr = { 0 };
-
-		mii_mgmt_addr.bits.phy_addr = xcvrAddr;
-		mii_mgmt_addr.bits.reg_addr = xcvrReg;
-		writel(mii_mgmt_addr.value, &mac->mii_mgmt_addr.value);
-	}
+	writel(MII_ADDR(xcvrAddr, xcvrReg), &mac->mii_mgmt_addr);
 
 	/* Kick the read cycle off */
 	delay = 0;
 
-	writel(0x1, &mac->mii_mgmt_cmd.value);
+	writel(0x1, &mac->mii_mgmt_cmd);
 
 	do {
 		udelay(50);
 		delay++;
-		miiIndicator.value = readl(&mac->mii_mgmt_indicator.value);
-	} while ((miiIndicator.bits.not_valid || miiIndicator.bits.busy) &&
-		 delay < 50);
+		miiIndicator = readl(&mac->mii_mgmt_indicator);
+	} while ((miiIndicator & MGMT_WAIT) && delay < 50);
 
 	/* If we hit the max delay, we could not read the register */
-	if (delay >= 50) {
-		dev_warn(&adapter->pdev->dev,
+	if (delay == 50) {
+		dev_warn(&etdev->pdev->dev,
 			    "xcvrReg 0x%08x could not be read\n", xcvrReg);
-		dev_warn(&adapter->pdev->dev, "status is  0x%08x\n",
-			    miiIndicator.value);
+		dev_warn(&etdev->pdev->dev, "status is  0x%08x\n",
+			    miiIndicator);
 
 		status = -EIO;
 	}
 
 	/* If we hit here we were able to read the register and we need to
-	 * return the value to the caller
-	 */
-	/* TODO: make this stuff a simple readw()?! */
-	{
-		MII_MGMT_STAT_t mii_mgmt_stat;
-
-		mii_mgmt_stat.value = readl(&mac->mii_mgmt_stat.value);
-		*value = (uint16_t) mii_mgmt_stat.bits.phy_stat;
-	}
+	 * return the value to the caller */
+	*value = readl(&mac->mii_mgmt_stat) & 0xFFFF;
 
 	/* Stop the read operation */
-	writel(0, &mac->mii_mgmt_cmd.value);
+	writel(0, &mac->mii_mgmt_cmd);
 
 	/* set the registers we touched back to the state at which we entered
 	 * this function
 	 */
-	writel(miiAddr.value, &mac->mii_mgmt_addr.value);
-	writel(miiCmd.value, &mac->mii_mgmt_cmd.value);
+	writel(miiAddr, &mac->mii_mgmt_addr);
+	writel(miiCmd, &mac->mii_mgmt_cmd);
 
 	return status;
 }
 
 /**
  * MiWrite - Write to a PHY register through the MII interface of the MAC
- * @adapter: pointer to our private adapter structure
+ * @etdev: pointer to our private adapter structure
  * @xcvrReg: the register to read
  * @value: 16-bit value to write
  *
+ * FIXME: one caller in netdev still
+ *
  * Return 0 on success, errno on failure (as defined in errno.h)
  */
-int MiWrite(struct et131x_adapter *adapter, uint8_t xcvrReg, uint16_t value)
+int MiWrite(struct et131x_adapter *etdev, u8 xcvrReg, u16 value)
 {
-	struct _MAC_t __iomem *mac = &adapter->regs->mac;
+	struct _MAC_t __iomem *mac = &etdev->regs->mac;
 	int status = 0;
-	uint8_t xcvrAddr = adapter->Stats.xcvr_addr;
-	uint32_t delay;
-	MII_MGMT_ADDR_t miiAddr;
-	MII_MGMT_CMD_t miiCmd;
-	MII_MGMT_INDICATOR_t miiIndicator;
+	u8 xcvrAddr = etdev->Stats.xcvr_addr;
+	u32 delay;
+	u32 miiAddr;
+	u32 miiCmd;
+	u32 miiIndicator;
 
 	/* Save a local copy of the registers we are dealing with so we can
 	 * set them back
 	 */
-	miiAddr.value = readl(&mac->mii_mgmt_addr.value);
-	miiCmd.value = readl(&mac->mii_mgmt_cmd.value);
+	miiAddr = readl(&mac->mii_mgmt_addr);
+	miiCmd = readl(&mac->mii_mgmt_cmd);
 
 	/* Stop the current operation */
-	writel(0, &mac->mii_mgmt_cmd.value);
+	writel(0, &mac->mii_mgmt_cmd);
 
 	/* Set up the register we need to write to on the correct PHY */
-	{
-		MII_MGMT_ADDR_t mii_mgmt_addr;
-
-		mii_mgmt_addr.bits.phy_addr = xcvrAddr;
-		mii_mgmt_addr.bits.reg_addr = xcvrReg;
-		writel(mii_mgmt_addr.value, &mac->mii_mgmt_addr.value);
-	}
+	writel(MII_ADDR(xcvrAddr, xcvrReg), &mac->mii_mgmt_addr);
 
 	/* Add the value to write to the registers to the mac */
-	writel(value, &mac->mii_mgmt_ctrl.value);
+	writel(value, &mac->mii_mgmt_ctrl);
 	delay = 0;
 
 	do {
 		udelay(50);
 		delay++;
-		miiIndicator.value = readl(&mac->mii_mgmt_indicator.value);
-	} while (miiIndicator.bits.busy && delay < 100);
+		miiIndicator = readl(&mac->mii_mgmt_indicator);
+	} while ((miiIndicator & MGMT_BUSY) && delay < 100);
 
 	/* If we hit the max delay, we could not write the register */
 	if (delay == 100) {
-		uint16_t TempValue;
+		u16 TempValue;
 
-		dev_warn(&adapter->pdev->dev,
+		dev_warn(&etdev->pdev->dev,
 		    "xcvrReg 0x%08x could not be written", xcvrReg);
-		dev_warn(&adapter->pdev->dev, "status is  0x%08x\n",
-			    miiIndicator.value);
-		dev_warn(&adapter->pdev->dev, "command is  0x%08x\n",
-			    readl(&mac->mii_mgmt_cmd.value));
+		dev_warn(&etdev->pdev->dev, "status is  0x%08x\n",
+			    miiIndicator);
+		dev_warn(&etdev->pdev->dev, "command is  0x%08x\n",
+			    readl(&mac->mii_mgmt_cmd));
 
-		MiRead(adapter, xcvrReg, &TempValue);
+		MiRead(etdev, xcvrReg, &TempValue);
 
 		status = -EIO;
 	}
-
 	/* Stop the write operation */
-	writel(0, &mac->mii_mgmt_cmd.value);
+	writel(0, &mac->mii_mgmt_cmd);
 
 	/* set the registers we touched back to the state at which we entered
 	 * this function
 	 */
-	writel(miiAddr.value, &mac->mii_mgmt_addr.value);
-	writel(miiCmd.value, &mac->mii_mgmt_cmd.value);
+	writel(miiAddr, &mac->mii_mgmt_addr);
+	writel(miiCmd, &mac->mii_mgmt_cmd);
 
 	return status;
 }
 
 /**
  * et131x_xcvr_find - Find the PHY ID
- * @adapter: pointer to our private adapter structure
+ * @etdev: pointer to our private adapter structure
  *
  * Returns 0 on success, errno on failure (as defined in errno.h)
  */
-int et131x_xcvr_find(struct et131x_adapter *adapter)
+int et131x_xcvr_find(struct et131x_adapter *etdev)
 {
-	int status = -ENODEV;
-	uint8_t xcvr_addr;
+	u8 xcvr_addr;
 	MI_IDR1_t idr1;
 	MI_IDR2_t idr2;
-	uint32_t xcvr_id;
+	u32 xcvr_id;
 
 	/* We need to get xcvr id and address we just get the first one */
 	for (xcvr_addr = 0; xcvr_addr < 32; xcvr_addr++) {
 		/* Read the ID from the PHY */
-		PhyMiRead(adapter, xcvr_addr,
-			  (uint8_t) offsetof(MI_REGS_t, idr1),
+		PhyMiRead(etdev, xcvr_addr,
+			  (u8) offsetof(MI_REGS_t, idr1),
 			  &idr1.value);
-		PhyMiRead(adapter, xcvr_addr,
-			  (uint8_t) offsetof(MI_REGS_t, idr2),
+		PhyMiRead(etdev, xcvr_addr,
+			  (u8) offsetof(MI_REGS_t, idr2),
 			  &idr2.value);
 
-		xcvr_id = (uint32_t) ((idr1.value << 16) | idr2.value);
+		xcvr_id = (u32) ((idr1.value << 16) | idr2.value);
 
-		if ((idr1.value != 0) && (idr1.value != 0xffff)) {
-			adapter->Stats.xcvr_id = xcvr_id;
-			adapter->Stats.xcvr_addr = xcvr_addr;
-
-			status = 0;
-			break;
+		if (idr1.value != 0 && idr1.value != 0xffff) {
+			etdev->Stats.xcvr_id = xcvr_id;
+			etdev->Stats.xcvr_addr = xcvr_addr;
+			return 0;
 		}
 	}
-	return status;
+	return -ENODEV;
+}
+
+void ET1310_PhyReset(struct et131x_adapter *etdev)
+{
+	MiWrite(etdev, PHY_CONTROL, 0x8000);
+}
+
+/**
+ *	ET1310_PhyPowerDown	-	PHY power control
+ *	@etdev: device to control
+ *	@down: true for off/false for back on
+ *
+ *	one hundred, ten, one thousand megs
+ *	How would you like to have your LAN accessed
+ *	Can't you see that this code processed
+ *	Phy power, phy power..
+ */
+
+void ET1310_PhyPowerDown(struct et131x_adapter *etdev, bool down)
+{
+	u16 data;
+
+	MiRead(etdev, PHY_CONTROL, &data);
+	data &= ~0x0800;	/* Power UP */
+	if (down) /* Power DOWN */
+		data |= 0x0800;
+	MiWrite(etdev, PHY_CONTROL, data);
+}
+
+/**
+ *	ET130_PhyAutoNEg	-	autonegotiate control
+ *	@etdev: device to control
+ *	@enabe: autoneg on/off
+ *
+ *	Set up the autonegotiation state according to whether we will be
+ *	negotiating the state or forcing a speed.
+ */
+
+static void ET1310_PhyAutoNeg(struct et131x_adapter *etdev, bool enable)
+{
+	u16 data;
+
+	MiRead(etdev, PHY_CONTROL, &data);
+	data &= ~0x1000;	/* Autonegotiation OFF */
+	if (enable)
+		data |= 0x1000;		/* Autonegotiation ON */
+	MiWrite(etdev, PHY_CONTROL, data);
+}
+
+/**
+ *	ET130_PhyDuplexMode	-	duplex control
+ *	@etdev: device to control
+ *	@duplex: duplex on/off
+ *
+ *	Set up the duplex state on the PHY
+ */
+
+static void ET1310_PhyDuplexMode(struct et131x_adapter *etdev, u16 duplex)
+{
+	u16 data;
+
+	MiRead(etdev, PHY_CONTROL, &data);
+	data &= ~0x100;		/* Set Half Duplex */
+	if (duplex == TRUEPHY_DUPLEX_FULL)
+		data |= 0x100;	/* Set Full Duplex */
+	MiWrite(etdev, PHY_CONTROL, data);
+}
+
+/**
+ *	ET130_PhySpeedSelect	-	speed control
+ *	@etdev: device to control
+ *	@duplex: duplex on/off
+ *
+ *	Set the speed of our PHY.
+ */
+
+static void ET1310_PhySpeedSelect(struct et131x_adapter *etdev, u16 speed)
+{
+	u16 data;
+	static const u16 bits[3]={0x0000, 0x2000, 0x0040};
+
+	/* Read the PHY control register */
+	MiRead(etdev, PHY_CONTROL, &data);
+	/* Clear all Speed settings (Bits 6, 13) */
+	data &= ~0x2040;
+	/* Write back the new speed */
+	MiWrite(etdev, PHY_CONTROL, data | bits[speed]);
+}
+
+/**
+ *	ET1310_PhyLinkStatus	-	read link state
+ *	@etdev: device to read
+ *	@link_status: reported link state
+ *	@autoneg: reported autonegotiation state (complete/incomplete/disabled)
+ *	@linkspeed: returnedlink speed in use
+ *	@duplex_mode: reported half/full duplex state
+ *	@mdi_mdix: not yet working
+ *	@masterslave: report whether we are master or slave
+ *	@polarity: link polarity
+ *
+ *	I can read your lan like a magazine
+ *	I see if your up
+ *	I know your link speed
+ *	I see all the setting that you'd rather keep
+ */
+
+static void ET1310_PhyLinkStatus(struct et131x_adapter *etdev,
+			  u8 *link_status,
+			  u32 *autoneg,
+			  u32 *linkspeed,
+			  u32 *duplex_mode,
+			  u32 *mdi_mdix,
+			  u32 *masterslave, u32 *polarity)
+{
+	u16 mistatus = 0;
+	u16 is1000BaseT = 0;
+	u16 vmi_phystatus = 0;
+	u16 control = 0;
+
+	MiRead(etdev, PHY_STATUS, &mistatus);
+	MiRead(etdev, PHY_1000_STATUS, &is1000BaseT);
+	MiRead(etdev, PHY_PHY_STATUS, &vmi_phystatus);
+	MiRead(etdev, PHY_CONTROL, &control);
+
+	*link_status = (vmi_phystatus & 0x0040) ? 1 : 0;
+	*autoneg = (control & 0x1000) ? ((vmi_phystatus & 0x0020) ?
+					    TRUEPHY_ANEG_COMPLETE :
+					    TRUEPHY_ANEG_NOT_COMPLETE) :
+		    TRUEPHY_ANEG_DISABLED;
+	*linkspeed = (vmi_phystatus & 0x0300) >> 8;
+	*duplex_mode = (vmi_phystatus & 0x0080) >> 7;
+	/* NOTE: Need to complete this */
+	*mdi_mdix = 0;
+
+	*masterslave = (is1000BaseT & 0x4000) ?
+			TRUEPHY_CFG_MASTER : TRUEPHY_CFG_SLAVE;
+	*polarity = (vmi_phystatus & 0x0400) ?
+			TRUEPHY_POLARITY_INVERTED : TRUEPHY_POLARITY_NORMAL;
+}
+
+static void ET1310_PhyAndOrReg(struct et131x_adapter *etdev,
+			u16 regnum, u16 andMask, u16 orMask)
+{
+	u16 reg;
+
+	MiRead(etdev, regnum, &reg);
+	reg &= andMask;
+	reg |= orMask;
+	MiWrite(etdev, regnum, reg);
+}
+
+/* Still used from _mac  for BIT_READ */
+void ET1310_PhyAccessMiBit(struct et131x_adapter *etdev, u16 action,
+			   u16 regnum, u16 bitnum, u8 *value)
+{
+	u16 reg;
+	u16 mask = 0x0001 << bitnum;
+
+	/* Read the requested register */
+	MiRead(etdev, regnum, &reg);
+
+	switch (action) {
+	case TRUEPHY_BIT_READ:
+		*value = (reg & mask) >> bitnum;
+		break;
+
+	case TRUEPHY_BIT_SET:
+		MiWrite(etdev, regnum, reg | mask);
+		break;
+
+	case TRUEPHY_BIT_CLEAR:
+		MiWrite(etdev, regnum, reg & ~mask);
+		break;
+
+	default:
+		break;
+	}
+}
+
+void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *etdev,
+				  u16 duplex)
+{
+	u16 data;
+
+	/* Read the PHY 1000 Base-T Control Register */
+	MiRead(etdev, PHY_1000_CONTROL, &data);
+
+	/* Clear Bits 8,9 */
+	data &= ~0x0300;
+
+	switch (duplex) {
+	case TRUEPHY_ADV_DUPLEX_NONE:
+		/* Duplex already cleared, do nothing */
+		break;
+
+	case TRUEPHY_ADV_DUPLEX_FULL:
+		/* Set Bit 9 */
+		data |= 0x0200;
+		break;
+
+	case TRUEPHY_ADV_DUPLEX_HALF:
+		/* Set Bit 8 */
+		data |= 0x0100;
+		break;
+
+	case TRUEPHY_ADV_DUPLEX_BOTH:
+	default:
+		data |= 0x0300;
+		break;
+	}
+
+	/* Write back advertisement */
+	MiWrite(etdev, PHY_1000_CONTROL, data);
+}
+
+static void ET1310_PhyAdvertise100BaseT(struct et131x_adapter *etdev,
+				 u16 duplex)
+{
+	u16 data;
+
+	/* Read the Autonegotiation Register (10/100) */
+	MiRead(etdev, PHY_AUTO_ADVERTISEMENT, &data);
+
+	/* Clear bits 7,8 */
+	data &= ~0x0180;
+
+	switch (duplex) {
+	case TRUEPHY_ADV_DUPLEX_NONE:
+		/* Duplex already cleared, do nothing */
+		break;
+
+	case TRUEPHY_ADV_DUPLEX_FULL:
+		/* Set Bit 8 */
+		data |= 0x0100;
+		break;
+
+	case TRUEPHY_ADV_DUPLEX_HALF:
+		/* Set Bit 7 */
+		data |= 0x0080;
+		break;
+
+	case TRUEPHY_ADV_DUPLEX_BOTH:
+	default:
+		/* Set Bits 7,8 */
+		data |= 0x0180;
+		break;
+	}
+
+	/* Write back advertisement */
+	MiWrite(etdev, PHY_AUTO_ADVERTISEMENT, data);
+}
+
+static void ET1310_PhyAdvertise10BaseT(struct et131x_adapter *etdev,
+				u16 duplex)
+{
+	u16 data;
+
+	/* Read the Autonegotiation Register (10/100) */
+	MiRead(etdev, PHY_AUTO_ADVERTISEMENT, &data);
+
+	/* Clear bits 5,6 */
+	data &= ~0x0060;
+
+	switch (duplex) {
+	case TRUEPHY_ADV_DUPLEX_NONE:
+		/* Duplex already cleared, do nothing */
+		break;
+
+	case TRUEPHY_ADV_DUPLEX_FULL:
+		/* Set Bit 6 */
+		data |= 0x0040;
+		break;
+
+	case TRUEPHY_ADV_DUPLEX_HALF:
+		/* Set Bit 5 */
+		data |= 0x0020;
+		break;
+
+	case TRUEPHY_ADV_DUPLEX_BOTH:
+	default:
+		/* Set Bits 5,6 */
+		data |= 0x0060;
+		break;
+	}
+
+	/* Write back advertisement */
+	MiWrite(etdev, PHY_AUTO_ADVERTISEMENT, data);
 }
 
 /**
  * et131x_setphy_normal - Set PHY for normal operation.
- * @adapter: pointer to our private adapter structure
+ * @etdev: pointer to our private adapter structure
  *
  * Used by Power Management to force the PHY into 10 Base T half-duplex mode,
  * when going to D3 in WOL mode. Also used during initialization to set the
  * PHY for normal operation.
  */
-int et131x_setphy_normal(struct et131x_adapter *adapter)
+void et131x_setphy_normal(struct et131x_adapter *etdev)
 {
-	int status;
-
 	/* Make sure the PHY is powered up */
-	ET1310_PhyPowerDown(adapter, 0);
-	status = et131x_xcvr_init(adapter);
-	return status;
+	ET1310_PhyPowerDown(etdev, 0);
+	et131x_xcvr_init(etdev);
 }
 
+
 /**
  * et131x_xcvr_init - Init the phy if we are setting it into force mode
- * @adapter: pointer to our private adapter structure
+ * @etdev: pointer to our private adapter structure
  *
- * Returns 0 on success, errno on failure (as defined in errno.h)
  */
-static int et131x_xcvr_init(struct et131x_adapter *adapter)
+static void et131x_xcvr_init(struct et131x_adapter *etdev)
 {
-	int status = 0;
 	MI_IMR_t imr;
 	MI_ISR_t isr;
 	MI_LCR2_t lcr2;
 
 	/* Zero out the adapter structure variable representing BMSR */
-	adapter->Bmsr.value = 0;
+	etdev->Bmsr.value = 0;
 
-	MiRead(adapter, (uint8_t) offsetof(MI_REGS_t, isr), &isr.value);
-
-	MiRead(adapter, (uint8_t) offsetof(MI_REGS_t, imr), &imr.value);
+	MiRead(etdev, (u8) offsetof(MI_REGS_t, isr), &isr.value);
+	MiRead(etdev, (u8) offsetof(MI_REGS_t, imr), &imr.value);
 
 	/* Set the link status interrupt only.  Bad behavior when link status
 	 * and auto neg are set, we run into a nested interrupt problem
@@ -338,7 +598,7 @@
 	imr.bits.link_status = 0x1;
 	imr.bits.autoneg_status = 0x1;
 
-	MiWrite(adapter, (uint8_t) offsetof(MI_REGS_t, imr), imr.value);
+	MiWrite(etdev, (u8) offsetof(MI_REGS_t, imr), imr.value);
 
 	/* Set the LED behavior such that LED 1 indicates speed (off =
 	 * 10Mbits, blink = 100Mbits, on = 1000Mbits) and LED 2 indicates
@@ -348,111 +608,138 @@
 	 * vendors; The LED behavior is now determined by vendor data in the
 	 * EEPROM. However, the above description is the default.
 	 */
-	if ((adapter->eepromData[1] & 0x4) == 0) {
-		MiRead(adapter, (uint8_t) offsetof(MI_REGS_t, lcr2),
+	if ((etdev->eepromData[1] & 0x4) == 0) {
+		MiRead(etdev, (u8) offsetof(MI_REGS_t, lcr2),
 		       &lcr2.value);
-		if ((adapter->eepromData[1] & 0x8) == 0)
+		if ((etdev->eepromData[1] & 0x8) == 0)
 			lcr2.bits.led_tx_rx = 0x3;
 		else
 			lcr2.bits.led_tx_rx = 0x4;
 		lcr2.bits.led_link = 0xa;
-		MiWrite(adapter, (uint8_t) offsetof(MI_REGS_t, lcr2),
+		MiWrite(etdev, (u8) offsetof(MI_REGS_t, lcr2),
 			lcr2.value);
 	}
 
 	/* Determine if we need to go into a force mode and set it */
-	if (adapter->AiForceSpeed == 0 && adapter->AiForceDpx == 0) {
-		if ((adapter->RegistryFlowControl == TxOnly) ||
-		    (adapter->RegistryFlowControl == Both)) {
-			ET1310_PhyAccessMiBit(adapter,
+	if (etdev->AiForceSpeed == 0 && etdev->AiForceDpx == 0) {
+		if (etdev->RegistryFlowControl == TxOnly ||
+		    etdev->RegistryFlowControl == Both)
+			ET1310_PhyAccessMiBit(etdev,
 					      TRUEPHY_BIT_SET, 4, 11, NULL);
-		} else {
-			ET1310_PhyAccessMiBit(adapter,
+		else
+			ET1310_PhyAccessMiBit(etdev,
 					      TRUEPHY_BIT_CLEAR, 4, 11, NULL);
-		}
 
-		if (adapter->RegistryFlowControl == Both) {
-			ET1310_PhyAccessMiBit(adapter,
+		if (etdev->RegistryFlowControl == Both)
+			ET1310_PhyAccessMiBit(etdev,
 					      TRUEPHY_BIT_SET, 4, 10, NULL);
-		} else {
-			ET1310_PhyAccessMiBit(adapter,
+		else
+			ET1310_PhyAccessMiBit(etdev,
 					      TRUEPHY_BIT_CLEAR, 4, 10, NULL);
-		}
 
 		/* Set the phy to autonegotiation */
-		ET1310_PhyAutoNeg(adapter, true);
+		ET1310_PhyAutoNeg(etdev, true);
 
 		/* NOTE - Do we need this? */
-		ET1310_PhyAccessMiBit(adapter, TRUEPHY_BIT_SET, 0, 9, NULL);
-		return status;
-	} else {
-		ET1310_PhyAutoNeg(adapter, false);
-
-		/* Set to the correct force mode. */
-		if (adapter->AiForceDpx != 1) {
-			if ((adapter->RegistryFlowControl == TxOnly) ||
-			    (adapter->RegistryFlowControl == Both)) {
-				ET1310_PhyAccessMiBit(adapter,
-						      TRUEPHY_BIT_SET, 4, 11,
-						      NULL);
-			} else {
-				ET1310_PhyAccessMiBit(adapter,
-						      TRUEPHY_BIT_CLEAR, 4, 11,
-						      NULL);
-			}
-
-			if (adapter->RegistryFlowControl == Both) {
-				ET1310_PhyAccessMiBit(adapter,
-						      TRUEPHY_BIT_SET, 4, 10,
-						      NULL);
-			} else {
-				ET1310_PhyAccessMiBit(adapter,
-						      TRUEPHY_BIT_CLEAR, 4, 10,
-						      NULL);
-			}
-		} else {
-			ET1310_PhyAccessMiBit(adapter,
-					      TRUEPHY_BIT_CLEAR, 4, 10, NULL);
-			ET1310_PhyAccessMiBit(adapter,
-					      TRUEPHY_BIT_CLEAR, 4, 11, NULL);
-		}
-
-		switch (adapter->AiForceSpeed) {
-		case 10:
-			if (adapter->AiForceDpx == 1)
-				TPAL_SetPhy10HalfDuplex(adapter);
-			else if (adapter->AiForceDpx == 2)
-				TPAL_SetPhy10FullDuplex(adapter);
-			else
-				TPAL_SetPhy10Force(adapter);
-			break;
-		case 100:
-			if (adapter->AiForceDpx == 1)
-				TPAL_SetPhy100HalfDuplex(adapter);
-			else if (adapter->AiForceDpx == 2)
-				TPAL_SetPhy100FullDuplex(adapter);
-			else
-				TPAL_SetPhy100Force(adapter);
-			break;
-		case 1000:
-			TPAL_SetPhy1000FullDuplex(adapter);
-			break;
-		}
-
-		return status;
+		ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_SET, 0, 9, NULL);
+		return;
 	}
+
+	ET1310_PhyAutoNeg(etdev, false);
+
+	/* Set to the correct force mode. */
+	if (etdev->AiForceDpx != 1) {
+		if (etdev->RegistryFlowControl == TxOnly ||
+		    etdev->RegistryFlowControl == Both)
+			ET1310_PhyAccessMiBit(etdev,
+				      TRUEPHY_BIT_SET, 4, 11, NULL);
+		else
+			ET1310_PhyAccessMiBit(etdev,
+					      TRUEPHY_BIT_CLEAR, 4, 11, NULL);
+
+		if (etdev->RegistryFlowControl == Both)
+			ET1310_PhyAccessMiBit(etdev,
+					      TRUEPHY_BIT_SET, 4, 10, NULL);
+		else
+			ET1310_PhyAccessMiBit(etdev,
+					      TRUEPHY_BIT_CLEAR, 4, 10, NULL);
+	} else {
+		ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_CLEAR, 4, 10, NULL);
+		ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_CLEAR, 4, 11, NULL);
+	}
+	ET1310_PhyPowerDown(etdev, 1);
+	switch (etdev->AiForceSpeed) {
+	case 10:
+		/* First we need to turn off all other advertisement */
+		ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
+		ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
+		if (etdev->AiForceDpx == 1) {
+			/* Set our advertise values accordingly */
+			ET1310_PhyAdvertise10BaseT(etdev,
+						TRUEPHY_ADV_DUPLEX_HALF);
+		} else if (etdev->AiForceDpx == 2) {
+			/* Set our advertise values accordingly */
+			ET1310_PhyAdvertise10BaseT(etdev,
+						TRUEPHY_ADV_DUPLEX_FULL);
+		} else {
+			/* Disable autoneg */
+			ET1310_PhyAutoNeg(etdev, false);
+			/* Disable rest of the advertisements */
+			ET1310_PhyAdvertise10BaseT(etdev,
+					TRUEPHY_ADV_DUPLEX_NONE);
+			/* Force 10 Mbps */
+			ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_10MBPS);
+			/* Force Full duplex */
+			ET1310_PhyDuplexMode(etdev, TRUEPHY_DUPLEX_FULL);
+		}
+		break;
+	case 100:
+		/* first we need to turn off all other advertisement */
+		ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
+		ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
+		if (etdev->AiForceDpx == 1) {
+			/* Set our advertise values accordingly */
+			ET1310_PhyAdvertise100BaseT(etdev,
+						TRUEPHY_ADV_DUPLEX_HALF);
+			/* Set speed */
+			ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_100MBPS);
+		} else if (etdev->AiForceDpx == 2) {
+			/* Set our advertise values accordingly */
+			ET1310_PhyAdvertise100BaseT(etdev,
+						TRUEPHY_ADV_DUPLEX_FULL);
+		} else {
+			/* Disable autoneg */
+			ET1310_PhyAutoNeg(etdev, false);
+			/* Disable other advertisement */
+			ET1310_PhyAdvertise100BaseT(etdev,
+						TRUEPHY_ADV_DUPLEX_NONE);
+			/* Force 100 Mbps */
+			ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_100MBPS);
+			/* Force Full duplex */
+			ET1310_PhyDuplexMode(etdev, TRUEPHY_DUPLEX_FULL);
+		}
+		break;
+	case 1000:
+		/* first we need to turn off all other advertisement */
+		ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
+		ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
+		/* set our advertise values accordingly */
+		ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL);
+		break;
+	}
+	ET1310_PhyPowerDown(etdev, 0);
 }
 
 void et131x_Mii_check(struct et131x_adapter *etdev,
 		      MI_BMSR_t bmsr, MI_BMSR_t bmsr_ints)
 {
-	uint8_t link_status;
-	uint32_t autoneg_status;
-	uint32_t speed;
-	uint32_t duplex;
-	uint32_t mdi_mdix;
-	uint32_t masterslave;
-	uint32_t polarity;
+	u8 link_status;
+	u32 autoneg_status;
+	u32 speed;
+	u32 duplex;
+	u32 mdi_mdix;
+	u32 masterslave;
+	u32 polarity;
 	unsigned long flags;
 
 	if (bmsr_ints.bits.link_status) {
@@ -469,9 +756,7 @@
 
 			spin_unlock_irqrestore(&etdev->Lock, flags);
 
-			/* Don't indicate state if we're in loopback mode */
-			if (etdev->RegistryPhyLoopbk == false)
-				netif_carrier_on(etdev->netdev);
+			netif_carrier_on(etdev->netdev);
 		} else {
 			dev_warn(&etdev->pdev->dev,
 			    "Link down - cable problem ?\n");
@@ -481,7 +766,7 @@
 				 * TruePHY?
 				 * && TRU_QueryCoreType(etdev->hTruePhy, 0) == EMI_TRUEPHY_A13O) {
 				 */
-				uint16_t Register18;
+				u16 Register18;
 
 				MiRead(etdev, 0x12, &Register18);
 				MiWrite(etdev, 0x12, Register18 | 0x4);
@@ -504,11 +789,7 @@
 				spin_unlock_irqrestore(&etdev->Lock,
 						       flags);
 
-				/* Only indicate state if we're in loopback
-				 * mode
-				 */
-				if (etdev->RegistryPhyLoopbk == false)
-					netif_carrier_off(etdev->netdev);
+				netif_carrier_off(etdev->netdev);
 			}
 
 			etdev->linkspeed = 0;
@@ -561,7 +842,7 @@
 				 * TruePHY?
 				 * && TRU_QueryCoreType(etdev->hTruePhy, 0)== EMI_TRUEPHY_A13O) {
 				 */
-				uint16_t Register18;
+				u16 Register18;
 
 				MiRead(etdev, 0x12, &Register18);
 				MiWrite(etdev, 0x12, Register18 | 0x4);
@@ -583,212 +864,13 @@
 	}
 }
 
-/**
- * TPAL_SetPhy10HalfDuplex - Force the phy into 10 Base T Half Duplex mode.
- * @etdev: pointer to the adapter structure
- *
- * Also sets the MAC so it is syncd up properly
- */
-void TPAL_SetPhy10HalfDuplex(struct et131x_adapter *etdev)
-{
-	/* Power down PHY */
-	ET1310_PhyPowerDown(etdev, 1);
-
-	/* First we need to turn off all other advertisement */
-	ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
-
-	ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
-
-	/* Set our advertise values accordingly */
-	ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_HALF);
-
-	/* Power up PHY */
-	ET1310_PhyPowerDown(etdev, 0);
-}
-
-/**
- * TPAL_SetPhy10FullDuplex - Force the phy into 10 Base T Full Duplex mode.
- * @etdev: pointer to the adapter structure
- *
- * Also sets the MAC so it is syncd up properly
- */
-void TPAL_SetPhy10FullDuplex(struct et131x_adapter *etdev)
-{
-	/* Power down PHY */
-	ET1310_PhyPowerDown(etdev, 1);
-
-	/* First we need to turn off all other advertisement */
-	ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
-
-	ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
-
-	/* Set our advertise values accordingly */
-	ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL);
-
-	/* Power up PHY */
-	ET1310_PhyPowerDown(etdev, 0);
-}
-
-/**
- * TPAL_SetPhy10Force - Force Base-T FD mode WITHOUT using autonegotiation
- * @etdev: pointer to the adapter structure
- */
-void TPAL_SetPhy10Force(struct et131x_adapter *etdev)
-{
-	/* Power down PHY */
-	ET1310_PhyPowerDown(etdev, 1);
-
-	/* Disable autoneg */
-	ET1310_PhyAutoNeg(etdev, false);
-
-	/* Disable all advertisement */
-	ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
-	ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
-	ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
-
-	/* Force 10 Mbps */
-	ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_10MBPS);
-
-	/* Force Full duplex */
-	ET1310_PhyDuplexMode(etdev, TRUEPHY_DUPLEX_FULL);
-
-	/* Power up PHY */
-	ET1310_PhyPowerDown(etdev, 0);
-}
-
-/**
- * TPAL_SetPhy100HalfDuplex - Force 100 Base T Half Duplex mode.
- * @etdev: pointer to the adapter structure
- *
- * Also sets the MAC so it is syncd up properly.
- */
-void TPAL_SetPhy100HalfDuplex(struct et131x_adapter *etdev)
-{
-	/* Power down PHY */
-	ET1310_PhyPowerDown(etdev, 1);
-
-	/* first we need to turn off all other advertisement */
-	ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
-
-	ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
-
-	/* Set our advertise values accordingly */
-	ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_HALF);
-
-	/* Set speed */
-	ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_100MBPS);
-
-	/* Power up PHY */
-	ET1310_PhyPowerDown(etdev, 0);
-}
-
-/**
- * TPAL_SetPhy100FullDuplex - Force 100 Base T Full Duplex mode.
- * @etdev: pointer to the adapter structure
- *
- * Also sets the MAC so it is syncd up properly
- */
-void TPAL_SetPhy100FullDuplex(struct et131x_adapter *etdev)
-{
-	/* Power down PHY */
-	ET1310_PhyPowerDown(etdev, 1);
-
-	/* First we need to turn off all other advertisement */
-	ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
-
-	ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
-
-	/* Set our advertise values accordingly */
-	ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL);
-
-	/* Power up PHY */
-	ET1310_PhyPowerDown(etdev, 0);
-}
-
-/**
- * TPAL_SetPhy100Force - Force 100 BaseT FD mode WITHOUT using autonegotiation
- * @etdev: pointer to the adapter structure
- */
-void TPAL_SetPhy100Force(struct et131x_adapter *etdev)
-{
-	/* Power down PHY */
-	ET1310_PhyPowerDown(etdev, 1);
-
-	/* Disable autoneg */
-	ET1310_PhyAutoNeg(etdev, false);
-
-	/* Disable all advertisement */
-	ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
-	ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
-	ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
-
-	/* Force 100 Mbps */
-	ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_100MBPS);
-
-	/* Force Full duplex */
-	ET1310_PhyDuplexMode(etdev, TRUEPHY_DUPLEX_FULL);
-
-	/* Power up PHY */
-	ET1310_PhyPowerDown(etdev, 0);
-}
-
-/**
- * TPAL_SetPhy1000FullDuplex - Force 1000 Base T Full Duplex mode
- * @etdev: pointer to the adapter structure
- *
- * Also sets the MAC so it is syncd up properly.
- */
-void TPAL_SetPhy1000FullDuplex(struct et131x_adapter *etdev)
-{
-	/* Power down PHY */
-	ET1310_PhyPowerDown(etdev, 1);
-
-	/* first we need to turn off all other advertisement */
-	ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
-
-	ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
-
-	/* set our advertise values accordingly */
-	ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL);
-
-	/* power up PHY */
-	ET1310_PhyPowerDown(etdev, 0);
-}
-
-/**
- * TPAL_SetPhyAutoNeg - Set phy to autonegotiation mode.
- * @etdev: pointer to the adapter structure
- */
-void TPAL_SetPhyAutoNeg(struct et131x_adapter *etdev)
-{
-	/* Power down PHY */
-	ET1310_PhyPowerDown(etdev, 1);
-
-	/* Turn on advertisement of all capabilities */
-	ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_BOTH);
-
-	ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_BOTH);
-
-	if (etdev->pdev->device != ET131X_PCI_DEVICE_ID_FAST)
-		ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL);
-	else
-		ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
-
-	/* Make sure auto-neg is ON (it is disabled in FORCE modes) */
-	ET1310_PhyAutoNeg(etdev, true);
-
-	/* Power up PHY */
-	ET1310_PhyPowerDown(etdev, 0);
-}
-
-
 /*
  * The routines which follow provide low-level access to the PHY, and are used
  * primarily by the routines above (although there are a few places elsewhere
  * in the driver where this level of access is required).
  */
 
-static const uint16_t ConfigPhy[25][2] = {
+static const u16 ConfigPhy[25][2] = {
 	/* Reg      Value      Register */
 	/* Addr                         */
 	{0x880B, 0x0926},	/* AfeIfCreg4B1000Msbs */
@@ -831,7 +913,7 @@
 /* condensed version of the phy initialization routine */
 void ET1310_PhyInit(struct et131x_adapter *etdev)
 {
-	uint16_t data, index;
+	u16 data, index;
 
 	if (etdev == NULL)
 		return;
@@ -896,304 +978,3 @@
 	MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0002);
 }
 
-void ET1310_PhyReset(struct et131x_adapter *etdev)
-{
-	MiWrite(etdev, PHY_CONTROL, 0x8000);
-}
-
-void ET1310_PhyPowerDown(struct et131x_adapter *etdev, bool down)
-{
-	uint16_t data;
-
-	MiRead(etdev, PHY_CONTROL, &data);
-
-	if (down == false) {
-		/* Power UP */
-		data &= ~0x0800;
-		MiWrite(etdev, PHY_CONTROL, data);
-	} else {
-		/* Power DOWN */
-		data |= 0x0800;
-		MiWrite(etdev, PHY_CONTROL, data);
-	}
-}
-
-void ET1310_PhyAutoNeg(struct et131x_adapter *etdev, bool enable)
-{
-	uint16_t data;
-
-	MiRead(etdev, PHY_CONTROL, &data);
-
-	if (enable == true) {
-		/* Autonegotiation ON */
-		data |= 0x1000;
-		MiWrite(etdev, PHY_CONTROL, data);
-	} else {
-		/* Autonegotiation OFF */
-		data &= ~0x1000;
-		MiWrite(etdev, PHY_CONTROL, data);
-	}
-}
-
-void ET1310_PhyDuplexMode(struct et131x_adapter *etdev, uint16_t duplex)
-{
-	uint16_t data;
-
-	MiRead(etdev, PHY_CONTROL, &data);
-
-	if (duplex == TRUEPHY_DUPLEX_FULL) {
-		/* Set Full Duplex */
-		data |= 0x100;
-		MiWrite(etdev, PHY_CONTROL, data);
-	} else {
-		/* Set Half Duplex */
-		data &= ~0x100;
-		MiWrite(etdev, PHY_CONTROL, data);
-	}
-}
-
-void ET1310_PhySpeedSelect(struct et131x_adapter *etdev, uint16_t speed)
-{
-	uint16_t data;
-
-	/* Read the PHY control register */
-	MiRead(etdev, PHY_CONTROL, &data);
-
-	/* Clear all Speed settings (Bits 6, 13) */
-	data &= ~0x2040;
-
-	/* Reset the speed bits based on user selection */
-	switch (speed) {
-	case TRUEPHY_SPEED_10MBPS:
-		/* Bits already cleared above, do nothing */
-		break;
-
-	case TRUEPHY_SPEED_100MBPS:
-		/* 100M == Set bit 13 */
-		data |= 0x2000;
-		break;
-
-	case TRUEPHY_SPEED_1000MBPS:
-	default:
-		data |= 0x0040;
-		break;
-	}
-
-	/* Write back the new speed */
-	MiWrite(etdev, PHY_CONTROL, data);
-}
-
-void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *etdev,
-				  uint16_t duplex)
-{
-	uint16_t data;
-
-	/* Read the PHY 1000 Base-T Control Register */
-	MiRead(etdev, PHY_1000_CONTROL, &data);
-
-	/* Clear Bits 8,9 */
-	data &= ~0x0300;
-
-	switch (duplex) {
-	case TRUEPHY_ADV_DUPLEX_NONE:
-		/* Duplex already cleared, do nothing */
-		break;
-
-	case TRUEPHY_ADV_DUPLEX_FULL:
-		/* Set Bit 9 */
-		data |= 0x0200;
-		break;
-
-	case TRUEPHY_ADV_DUPLEX_HALF:
-		/* Set Bit 8 */
-		data |= 0x0100;
-		break;
-
-	case TRUEPHY_ADV_DUPLEX_BOTH:
-	default:
-		data |= 0x0300;
-		break;
-	}
-
-	/* Write back advertisement */
-	MiWrite(etdev, PHY_1000_CONTROL, data);
-}
-
-void ET1310_PhyAdvertise100BaseT(struct et131x_adapter *etdev,
-				 uint16_t duplex)
-{
-	uint16_t data;
-
-	/* Read the Autonegotiation Register (10/100) */
-	MiRead(etdev, PHY_AUTO_ADVERTISEMENT, &data);
-
-	/* Clear bits 7,8 */
-	data &= ~0x0180;
-
-	switch (duplex) {
-	case TRUEPHY_ADV_DUPLEX_NONE:
-		/* Duplex already cleared, do nothing */
-		break;
-
-	case TRUEPHY_ADV_DUPLEX_FULL:
-		/* Set Bit 8 */
-		data |= 0x0100;
-		break;
-
-	case TRUEPHY_ADV_DUPLEX_HALF:
-		/* Set Bit 7 */
-		data |= 0x0080;
-		break;
-
-	case TRUEPHY_ADV_DUPLEX_BOTH:
-	default:
-		/* Set Bits 7,8 */
-		data |= 0x0180;
-		break;
-	}
-
-	/* Write back advertisement */
-	MiWrite(etdev, PHY_AUTO_ADVERTISEMENT, data);
-}
-
-void ET1310_PhyAdvertise10BaseT(struct et131x_adapter *etdev,
-				uint16_t duplex)
-{
-	uint16_t data;
-
-	/* Read the Autonegotiation Register (10/100) */
-	MiRead(etdev, PHY_AUTO_ADVERTISEMENT, &data);
-
-	/* Clear bits 5,6 */
-	data &= ~0x0060;
-
-	switch (duplex) {
-	case TRUEPHY_ADV_DUPLEX_NONE:
-		/* Duplex already cleared, do nothing */
-		break;
-
-	case TRUEPHY_ADV_DUPLEX_FULL:
-		/* Set Bit 6 */
-		data |= 0x0040;
-		break;
-
-	case TRUEPHY_ADV_DUPLEX_HALF:
-		/* Set Bit 5 */
-		data |= 0x0020;
-		break;
-
-	case TRUEPHY_ADV_DUPLEX_BOTH:
-	default:
-		/* Set Bits 5,6 */
-		data |= 0x0060;
-		break;
-	}
-
-	/* Write back advertisement */
-	MiWrite(etdev, PHY_AUTO_ADVERTISEMENT, data);
-}
-
-void ET1310_PhyLinkStatus(struct et131x_adapter *etdev,
-			  uint8_t *link_status,
-			  uint32_t *autoneg,
-			  uint32_t *linkspeed,
-			  uint32_t *duplex_mode,
-			  uint32_t *mdi_mdix,
-			  uint32_t *masterslave, uint32_t *polarity)
-{
-	uint16_t mistatus = 0;
-	uint16_t is1000BaseT = 0;
-	uint16_t vmi_phystatus = 0;
-	uint16_t control = 0;
-
-	MiRead(etdev, PHY_STATUS, &mistatus);
-	MiRead(etdev, PHY_1000_STATUS, &is1000BaseT);
-	MiRead(etdev, PHY_PHY_STATUS, &vmi_phystatus);
-	MiRead(etdev, PHY_CONTROL, &control);
-
-	if (link_status) {
-		*link_status =
-		    (unsigned char)((vmi_phystatus & 0x0040) ? 1 : 0);
-	}
-
-	if (autoneg) {
-		*autoneg =
-		    (control & 0x1000) ? ((vmi_phystatus & 0x0020) ?
-					    TRUEPHY_ANEG_COMPLETE :
-					    TRUEPHY_ANEG_NOT_COMPLETE) :
-		    TRUEPHY_ANEG_DISABLED;
-	}
-
-	if (linkspeed)
-		*linkspeed = (vmi_phystatus & 0x0300) >> 8;
-
-	if (duplex_mode)
-		*duplex_mode = (vmi_phystatus & 0x0080) >> 7;
-
-	if (mdi_mdix)
-		/* NOTE: Need to complete this */
-		*mdi_mdix = 0;
-
-	if (masterslave) {
-		*masterslave =
-		    (is1000BaseT & 0x4000) ? TRUEPHY_CFG_MASTER :
-		    TRUEPHY_CFG_SLAVE;
-	}
-
-	if (polarity) {
-		*polarity =
-		    (vmi_phystatus & 0x0400) ? TRUEPHY_POLARITY_INVERTED :
-		    TRUEPHY_POLARITY_NORMAL;
-	}
-}
-
-void ET1310_PhyAndOrReg(struct et131x_adapter *etdev,
-			uint16_t regnum, uint16_t andMask, uint16_t orMask)
-{
-	uint16_t reg;
-
-	/* Read the requested register */
-	MiRead(etdev, regnum, &reg);
-
-	/* Apply the AND mask */
-	reg &= andMask;
-
-	/* Apply the OR mask */
-	reg |= orMask;
-
-	/* Write the value back to the register */
-	MiWrite(etdev, regnum, reg);
-}
-
-void ET1310_PhyAccessMiBit(struct et131x_adapter *etdev, uint16_t action,
-			   uint16_t regnum, uint16_t bitnum, uint8_t *value)
-{
-	uint16_t reg;
-	uint16_t mask = 0;
-
-	/* Create a mask to isolate the requested bit */
-	mask = 0x0001 << bitnum;
-
-	/* Read the requested register */
-	MiRead(etdev, regnum, &reg);
-
-	switch (action) {
-	case TRUEPHY_BIT_READ:
-		if (value != NULL)
-			*value = (reg & mask) >> bitnum;
-		break;
-
-	case TRUEPHY_BIT_SET:
-		reg |= mask;
-		MiWrite(etdev, regnum, reg);
-		break;
-
-	case TRUEPHY_BIT_CLEAR:
-		reg &= ~mask;
-		MiWrite(etdev, regnum, reg);
-		break;
-
-	default:
-		break;
-	}
-}
diff --git a/drivers/staging/et131x/et1310_phy.h b/drivers/staging/et131x/et1310_phy.h
index 080656c..758b9b2 100644
--- a/drivers/staging/et131x/et1310_phy.h
+++ b/drivers/staging/et131x/et1310_phy.h
@@ -61,9 +61,6 @@
 
 #include "et1310_address_map.h"
 
-#define TRUEPHY_SUCCESS 0
-#define TRUEPHY_FAILURE 1
-
 /* MI Register Addresses */
 #define MI_CONTROL_REG                      0
 #define MI_STATUS_REG                       1
@@ -742,25 +739,15 @@
 /* Forward declaration of the private adapter structure */
 struct et131x_adapter;
 
-/* OS Specific Functions*/
-void TPAL_SetPhy10HalfDuplex(struct et131x_adapter *adapter);
-void TPAL_SetPhy10FullDuplex(struct et131x_adapter *adapter);
-void TPAL_SetPhy10Force(struct et131x_adapter *pAdapter);
-void TPAL_SetPhy100HalfDuplex(struct et131x_adapter *adapter);
-void TPAL_SetPhy100FullDuplex(struct et131x_adapter *adapter);
-void TPAL_SetPhy100Force(struct et131x_adapter *pAdapter);
-void TPAL_SetPhy1000FullDuplex(struct et131x_adapter *adapter);
-void TPAL_SetPhyAutoNeg(struct et131x_adapter *adapter);
-
 /* Prototypes for ET1310_phy.c */
 int et131x_xcvr_find(struct et131x_adapter *adapter);
-int et131x_setphy_normal(struct et131x_adapter *adapter);
-int32_t PhyMiRead(struct et131x_adapter *adapter,
-	       u8 xcvrAddr, u8 xcvrReg, u16 *value);
+void et131x_setphy_normal(struct et131x_adapter *adapter);
 
 /* static inline function does not work because et131x_adapter is not always
  * defined
  */
+int PhyMiRead(struct et131x_adapter *adapter, u8 xcvrAddr,
+	      u8 xcvrReg, u16 *value);
 #define MiRead(adapter, xcvrReg, value) \
 	PhyMiRead((adapter), (adapter)->Stats.xcvr_addr, (xcvrReg), (value))
 
@@ -860,24 +847,8 @@
 void ET1310_PhyInit(struct et131x_adapter *adapter);
 void ET1310_PhyReset(struct et131x_adapter *adapter);
 void ET1310_PhyPowerDown(struct et131x_adapter *adapter, bool down);
-void ET1310_PhyAutoNeg(struct et131x_adapter *adapter, bool enable);
-void ET1310_PhyDuplexMode(struct et131x_adapter *adapter, u16 duplex);
-void ET1310_PhySpeedSelect(struct et131x_adapter *adapter, u16 speed);
 void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *adapter,
 				  u16 duplex);
-void ET1310_PhyAdvertise100BaseT(struct et131x_adapter *adapter,
-				 u16 duplex);
-void ET1310_PhyAdvertise10BaseT(struct et131x_adapter *adapter,
-				u16 duplex);
-void ET1310_PhyLinkStatus(struct et131x_adapter *adapter,
-			  u8 *Link_status,
-			  u32 *autoneg,
-			  u32 *linkspeed,
-			  u32 *duplex_mode,
-			  u32 *mdi_mdix,
-			  u32 *masterslave, u32 *polarity);
-void ET1310_PhyAndOrReg(struct et131x_adapter *adapter,
-			u16 regnum, u16 andMask, u16 orMask);
 void ET1310_PhyAccessMiBit(struct et131x_adapter *adapter,
 			   u16 action,
 			   u16 regnum, u16 bitnum, u8 *value);
diff --git a/drivers/staging/et131x/et1310_rx.c b/drivers/staging/et131x/et1310_rx.c
index 10e21db..3ddc9b1 100644
--- a/drivers/staging/et131x/et1310_rx.c
+++ b/drivers/staging/et131x/et1310_rx.c
@@ -106,9 +106,9 @@
  */
 int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
 {
-	uint32_t OuterLoop, InnerLoop;
-	uint32_t bufsize;
-	uint32_t pktStatRingSize, FBRChunkSize;
+	u32 i, j;
+	u32 bufsize;
+	u32 pktStatRingSize, FBRChunkSize;
 	RX_RING_t *rx_ring;
 
 	/* Setup some convenience pointers */
@@ -227,11 +227,11 @@
 					rx_ring->Fbr0offset);
 #endif
 
-	for (OuterLoop = 0; OuterLoop < (rx_ring->Fbr1NumEntries / FBR_CHUNKS);
-	     OuterLoop++) {
-		uint64_t Fbr1Offset;
-		uint64_t Fbr1TempPa;
-		uint32_t Fbr1Align;
+	for (i = 0; i < (rx_ring->Fbr1NumEntries / FBR_CHUNKS);
+	     i++) {
+		u64 Fbr1Offset;
+		u64 Fbr1TempPa;
+		u32 Fbr1Align;
 
 		/* This code allocates an area of memory big enough for N
 		 * free buffers + (buffer_size - 1) so that the buffers can
@@ -247,39 +247,39 @@
 
 		FBRChunkSize =
 		    (FBR_CHUNKS * rx_ring->Fbr1BufferSize) + Fbr1Align - 1;
-		rx_ring->Fbr1MemVa[OuterLoop] =
+		rx_ring->Fbr1MemVa[i] =
 		    pci_alloc_consistent(adapter->pdev, FBRChunkSize,
-					 &rx_ring->Fbr1MemPa[OuterLoop]);
+					 &rx_ring->Fbr1MemPa[i]);
 
-		if (!rx_ring->Fbr1MemVa[OuterLoop]) {
+		if (!rx_ring->Fbr1MemVa[i]) {
 		dev_err(&adapter->pdev->dev,
 				"Could not alloc memory\n");
 			return -ENOMEM;
 		}
 
 		/* See NOTE in "Save Physical Address" comment above */
-		Fbr1TempPa = rx_ring->Fbr1MemPa[OuterLoop];
+		Fbr1TempPa = rx_ring->Fbr1MemPa[i];
 
 		et131x_align_allocated_memory(adapter,
 					      &Fbr1TempPa,
 					      &Fbr1Offset, (Fbr1Align - 1));
 
-		for (InnerLoop = 0; InnerLoop < FBR_CHUNKS; InnerLoop++) {
-			uint32_t index = (OuterLoop * FBR_CHUNKS) + InnerLoop;
+		for (j = 0; j < FBR_CHUNKS; j++) {
+			u32 index = (i * FBR_CHUNKS) + j;
 
 			/* Save the Virtual address of this index for quick
 			 * access later
 			 */
 			rx_ring->Fbr[1]->Va[index] =
-			    (uint8_t *) rx_ring->Fbr1MemVa[OuterLoop] +
-			    (InnerLoop * rx_ring->Fbr1BufferSize) + Fbr1Offset;
+			    (uint8_t *) rx_ring->Fbr1MemVa[i] +
+			    (j * rx_ring->Fbr1BufferSize) + Fbr1Offset;
 
 			/* now store the physical address in the descriptor
 			 * so the device can access it
 			 */
 			rx_ring->Fbr[1]->PAHigh[index] =
-			    (uint32_t) (Fbr1TempPa >> 32);
-			rx_ring->Fbr[1]->PALow[index] = (uint32_t) Fbr1TempPa;
+			    (u32) (Fbr1TempPa >> 32);
+			rx_ring->Fbr[1]->PALow[index] = (u32) Fbr1TempPa;
 
 			Fbr1TempPa += rx_ring->Fbr1BufferSize;
 
@@ -292,40 +292,40 @@
 
 #ifdef USE_FBR0
 	/* Same for FBR0 (if in use) */
-	for (OuterLoop = 0; OuterLoop < (rx_ring->Fbr0NumEntries / FBR_CHUNKS);
-	     OuterLoop++) {
-		uint64_t Fbr0Offset;
-		uint64_t Fbr0TempPa;
+	for (i = 0; i < (rx_ring->Fbr0NumEntries / FBR_CHUNKS);
+	     i++) {
+		u64 Fbr0Offset;
+		u64 Fbr0TempPa;
 
 		FBRChunkSize = ((FBR_CHUNKS + 1) * rx_ring->Fbr0BufferSize) - 1;
-		rx_ring->Fbr0MemVa[OuterLoop] =
+		rx_ring->Fbr0MemVa[i] =
 		    pci_alloc_consistent(adapter->pdev, FBRChunkSize,
-					 &rx_ring->Fbr0MemPa[OuterLoop]);
+					 &rx_ring->Fbr0MemPa[i]);
 
-		if (!rx_ring->Fbr0MemVa[OuterLoop]) {
+		if (!rx_ring->Fbr0MemVa[i]) {
 			dev_err(&adapter->pdev->dev,
 				"Could not alloc memory\n");
 			return -ENOMEM;
 		}
 
 		/* See NOTE in "Save Physical Address" comment above */
-		Fbr0TempPa = rx_ring->Fbr0MemPa[OuterLoop];
+		Fbr0TempPa = rx_ring->Fbr0MemPa[i];
 
 		et131x_align_allocated_memory(adapter,
 					      &Fbr0TempPa,
 					      &Fbr0Offset,
 					      rx_ring->Fbr0BufferSize - 1);
 
-		for (InnerLoop = 0; InnerLoop < FBR_CHUNKS; InnerLoop++) {
-			uint32_t index = (OuterLoop * FBR_CHUNKS) + InnerLoop;
+		for (j = 0; j < FBR_CHUNKS; j++) {
+			u32 index = (i * FBR_CHUNKS) + j;
 
 			rx_ring->Fbr[0]->Va[index] =
-			    (uint8_t *) rx_ring->Fbr0MemVa[OuterLoop] +
-			    (InnerLoop * rx_ring->Fbr0BufferSize) + Fbr0Offset;
+			    (uint8_t *) rx_ring->Fbr0MemVa[i] +
+			    (j * rx_ring->Fbr0BufferSize) + Fbr0Offset;
 
 			rx_ring->Fbr[0]->PAHigh[index] =
-			    (uint32_t) (Fbr0TempPa >> 32);
-			rx_ring->Fbr[0]->PALow[index] = (uint32_t) Fbr0TempPa;
+			    (u32) (Fbr0TempPa >> 32);
+			rx_ring->Fbr[0]->PALow[index] = (u32) Fbr0TempPa;
 
 			Fbr0TempPa += rx_ring->Fbr0BufferSize;
 
@@ -342,7 +342,7 @@
 	    sizeof(PKT_STAT_DESC_t) * adapter->RxRing.PsrNumEntries;
 
 	rx_ring->pPSRingVa = pci_alloc_consistent(adapter->pdev,
-						  pktStatRingSize + 0x0fff,
+						  pktStatRingSize,
 						  &rx_ring->pPSRingPa);
 
 	if (!rx_ring->pPSRingVa) {
@@ -350,45 +350,26 @@
 			  "Cannot alloc memory for Packet Status Ring\n");
 		return -ENOMEM;
 	}
+	printk("PSR %lx\n", (unsigned long) rx_ring->pPSRingPa);
 
-	/* Save physical address
-	 *
+	/*
 	 * NOTE : pci_alloc_consistent(), used above to alloc DMA regions,
 	 * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses
 	 * are ever returned, make sure the high part is retrieved here before
 	 * storing the adjusted address.
 	 */
-	rx_ring->pPSRingRealPa = rx_ring->pPSRingPa;
-
-	/* Align Packet Status Ring on a 4K boundary */
-	et131x_align_allocated_memory(adapter,
-				      &rx_ring->pPSRingRealPa,
-				      &rx_ring->pPSRingOffset, 0x0FFF);
-
-	rx_ring->pPSRingVa = (void *)((uint8_t *) rx_ring->pPSRingVa +
-				      rx_ring->pPSRingOffset);
 
 	/* Allocate an area of memory for writeback of status information */
 	rx_ring->pRxStatusVa = pci_alloc_consistent(adapter->pdev,
-						    sizeof(RX_STATUS_BLOCK_t) +
-						    0x7, &rx_ring->pRxStatusPa);
+						    sizeof(RX_STATUS_BLOCK_t),
+						    &rx_ring->pRxStatusPa);
 	if (!rx_ring->pRxStatusVa) {
 		dev_err(&adapter->pdev->dev,
 			  "Cannot alloc memory for Status Block\n");
 		return -ENOMEM;
 	}
-
-	/* Save physical address */
-	rx_ring->RxStatusRealPA = rx_ring->pRxStatusPa;
-
-	/* Align write back on an 8 byte boundary */
-	et131x_align_allocated_memory(adapter,
-				      &rx_ring->RxStatusRealPA,
-				      &rx_ring->RxStatusOffset, 0x07);
-
-	rx_ring->pRxStatusVa = (void *)((uint8_t *) rx_ring->pRxStatusVa +
-					rx_ring->RxStatusOffset);
 	rx_ring->NumRfd = NIC_DEFAULT_NUM_RFD;
+	printk("PRS %lx\n", (unsigned long)rx_ring->pRxStatusPa);
 
 	/* Recv
 	 * pci_pool_create initializes a lookaside list. After successful
@@ -409,7 +390,6 @@
 	 * lists now.
 	 */
 	INIT_LIST_HEAD(&rx_ring->RecvList);
-	INIT_LIST_HEAD(&rx_ring->RecvPendingList);
 	return 0;
 }
 
@@ -419,10 +399,10 @@
  */
 void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
 {
-	uint32_t index;
-	uint32_t bufsize;
-	uint32_t pktStatRingSize;
-	PMP_RFD pMpRfd;
+	u32 index;
+	u32 bufsize;
+	u32 pktStatRingSize;
+	PMP_RFD rfd;
 	RX_RING_t *rx_ring;
 
 	/* Setup some convenience pointers */
@@ -432,18 +412,12 @@
 	WARN_ON(rx_ring->nReadyRecv != rx_ring->NumRfd);
 
 	while (!list_empty(&rx_ring->RecvList)) {
-		pMpRfd = (MP_RFD *) list_entry(rx_ring->RecvList.next,
+		rfd = (MP_RFD *) list_entry(rx_ring->RecvList.next,
 					       MP_RFD, list_node);
 
-		list_del(&pMpRfd->list_node);
-		et131x_rfd_resources_free(adapter, pMpRfd);
-	}
-
-	while (!list_empty(&rx_ring->RecvPendingList)) {
-		pMpRfd = (MP_RFD *) list_entry(rx_ring->RecvPendingList.next,
-					       MP_RFD, list_node);
-		list_del(&pMpRfd->list_node);
-		et131x_rfd_resources_free(adapter, pMpRfd);
+		list_del(&rfd->list_node);
+		rfd->Packet = NULL;
+		kmem_cache_free(adapter->RxRing.RecvLookaside, rfd);
 	}
 
 	/* Free Free Buffer Ring 1 */
@@ -452,7 +426,7 @@
 		for (index = 0; index <
 		     (rx_ring->Fbr1NumEntries / FBR_CHUNKS); index++) {
 			if (rx_ring->Fbr1MemVa[index]) {
-				uint32_t Fbr1Align;
+				u32 Fbr1Align;
 
 				if (rx_ring->Fbr1BufferSize > 4096)
 					Fbr1Align = 4096;
@@ -523,14 +497,10 @@
 
 	/* Free Packet Status Ring */
 	if (rx_ring->pPSRingVa) {
-		rx_ring->pPSRingVa = (void *)((uint8_t *) rx_ring->pPSRingVa -
-					      rx_ring->pPSRingOffset);
-
 		pktStatRingSize =
 		    sizeof(PKT_STAT_DESC_t) * adapter->RxRing.PsrNumEntries;
 
-		pci_free_consistent(adapter->pdev,
-				    pktStatRingSize + 0x0fff,
+		pci_free_consistent(adapter->pdev, pktStatRingSize,
 				    rx_ring->pPSRingVa, rx_ring->pPSRingPa);
 
 		rx_ring->pPSRingVa = NULL;
@@ -538,11 +508,8 @@
 
 	/* Free area of memory for the writeback of status information */
 	if (rx_ring->pRxStatusVa) {
-		rx_ring->pRxStatusVa = (void *)((uint8_t *)
-				rx_ring->pRxStatusVa - rx_ring->RxStatusOffset);
-
 		pci_free_consistent(adapter->pdev,
-				sizeof(RX_STATUS_BLOCK_t) + 0x7,
+				sizeof(RX_STATUS_BLOCK_t),
 				rx_ring->pRxStatusVa, rx_ring->pRxStatusPa);
 
 		rx_ring->pRxStatusVa = NULL;
@@ -578,49 +545,43 @@
 int et131x_init_recv(struct et131x_adapter *adapter)
 {
 	int status = -ENOMEM;
-	PMP_RFD pMpRfd = NULL;
-	uint32_t RfdCount;
-	uint32_t TotalNumRfd = 0;
+	PMP_RFD rfd = NULL;
+	u32 rfdct;
+	u32 numrfd = 0;
 	RX_RING_t *rx_ring = NULL;
 
 	/* Setup some convenience pointers */
 	rx_ring = (RX_RING_t *) &adapter->RxRing;
 
 	/* Setup each RFD */
-	for (RfdCount = 0; RfdCount < rx_ring->NumRfd; RfdCount++) {
-		pMpRfd = (MP_RFD *) kmem_cache_alloc(rx_ring->RecvLookaside,
+	for (rfdct = 0; rfdct < rx_ring->NumRfd; rfdct++) {
+		rfd = (MP_RFD *) kmem_cache_alloc(rx_ring->RecvLookaside,
 						     GFP_ATOMIC | GFP_DMA);
 
-		if (!pMpRfd) {
+		if (!rfd) {
 			dev_err(&adapter->pdev->dev,
 				  "Couldn't alloc RFD out of kmem_cache\n");
 			status = -ENOMEM;
 			continue;
 		}
 
-		status = et131x_rfd_resources_alloc(adapter, pMpRfd);
-		if (status != 0) {
-			dev_err(&adapter->pdev->dev,
-				  "Couldn't alloc packet for RFD\n");
-			kmem_cache_free(rx_ring->RecvLookaside, pMpRfd);
-			continue;
-		}
+		rfd->Packet = NULL;
 
 		/* Add this RFD to the RecvList */
-		list_add_tail(&pMpRfd->list_node, &rx_ring->RecvList);
+		list_add_tail(&rfd->list_node, &rx_ring->RecvList);
 
 		/* Increment both the available RFD's, and the total RFD's. */
 		rx_ring->nReadyRecv++;
-		TotalNumRfd++;
+		numrfd++;
 	}
 
-	if (TotalNumRfd > NIC_MIN_NUM_RFD)
+	if (numrfd > NIC_MIN_NUM_RFD)
 		status = 0;
 
-	rx_ring->NumRfd = TotalNumRfd;
+	rx_ring->NumRfd = numrfd;
 
 	if (status != 0) {
-		kmem_cache_free(rx_ring->RecvLookaside, pMpRfd);
+		kmem_cache_free(rx_ring->RecvLookaside, rfd);
 		dev_err(&adapter->pdev->dev,
 			  "Allocation problems in et131x_init_recv\n");
 	}
@@ -628,41 +589,16 @@
 }
 
 /**
- * et131x_rfd_resources_alloc
- * @adapter: pointer to our private adapter structure
- * @pMpRfd: pointer to a RFD
- *
- * Returns 0 on success and errno on failure (as defined in errno.h)
- */
-int et131x_rfd_resources_alloc(struct et131x_adapter *adapter, MP_RFD *pMpRfd)
-{
-	pMpRfd->Packet = NULL;
-
-	return 0;
-}
-
-/**
- * et131x_rfd_resources_free - Free the packet allocated for the given RFD
- * @adapter: pointer to our private adapter structure
- * @pMpRfd: pointer to a RFD
- */
-void et131x_rfd_resources_free(struct et131x_adapter *adapter, MP_RFD *pMpRfd)
-{
-	pMpRfd->Packet = NULL;
-	kmem_cache_free(adapter->RxRing.RecvLookaside, pMpRfd);
-}
-
-/**
  * ConfigRxDmaRegs - Start of Rx_DMA init sequence
  * @etdev: pointer to our adapter structure
  */
 void ConfigRxDmaRegs(struct et131x_adapter *etdev)
 {
 	struct _RXDMA_t __iomem *rx_dma = &etdev->regs->rxdma;
-	struct _rx_ring_t *pRxLocal = &etdev->RxRing;
+	struct _rx_ring_t *rx_local = &etdev->RxRing;
 	PFBR_DESC_t fbr_entry;
-	uint32_t entry;
-	RXDMA_PSR_NUM_DES_t psr_num_des;
+	u32 entry;
+	u32 psr_num_des;
 	unsigned long flags;
 
 	/* Halt RXDMA to perform the reconfigure.  */
@@ -675,36 +611,35 @@
 	 * are ever returned, make sure the high part is retrieved here
 	 * before storing the adjusted address.
 	 */
-	writel((uint32_t) (pRxLocal->RxStatusRealPA >> 32),
+	writel((u32) ((u64)rx_local->pRxStatusPa >> 32),
 	       &rx_dma->dma_wb_base_hi);
-	writel((uint32_t) pRxLocal->RxStatusRealPA, &rx_dma->dma_wb_base_lo);
+	writel((u32) rx_local->pRxStatusPa, &rx_dma->dma_wb_base_lo);
 
-	memset(pRxLocal->pRxStatusVa, 0, sizeof(RX_STATUS_BLOCK_t));
+	memset(rx_local->pRxStatusVa, 0, sizeof(RX_STATUS_BLOCK_t));
 
 	/* Set the address and parameters of the packet status ring into the
 	 * 1310's registers
 	 */
-	writel((uint32_t) (pRxLocal->pPSRingRealPa >> 32),
+	writel((u32) ((u64)rx_local->pPSRingPa >> 32),
 	       &rx_dma->psr_base_hi);
-	writel((uint32_t) pRxLocal->pPSRingRealPa, &rx_dma->psr_base_lo);
-	writel(pRxLocal->PsrNumEntries - 1, &rx_dma->psr_num_des.value);
-	writel(0, &rx_dma->psr_full_offset.value);
+	writel((u32) rx_local->pPSRingPa, &rx_dma->psr_base_lo);
+	writel(rx_local->PsrNumEntries - 1, &rx_dma->psr_num_des);
+	writel(0, &rx_dma->psr_full_offset);
 
-	psr_num_des.value = readl(&rx_dma->psr_num_des.value);
-	writel((psr_num_des.bits.psr_ndes * LO_MARK_PERCENT_FOR_PSR) / 100,
-	       &rx_dma->psr_min_des.value);
+	psr_num_des = readl(&rx_dma->psr_num_des) & 0xFFF;
+	writel((psr_num_des * LO_MARK_PERCENT_FOR_PSR) / 100,
+	       &rx_dma->psr_min_des);
 
 	spin_lock_irqsave(&etdev->RcvLock, flags);
 
 	/* These local variables track the PSR in the adapter structure */
-	pRxLocal->local_psr_full.bits.psr_full = 0;
-	pRxLocal->local_psr_full.bits.psr_full_wrap = 0;
+	rx_local->local_psr_full = 0;
 
 	/* Now's the best time to initialize FBR1 contents */
-	fbr_entry = (PFBR_DESC_t) pRxLocal->pFbr1RingVa;
-	for (entry = 0; entry < pRxLocal->Fbr1NumEntries; entry++) {
-		fbr_entry->addr_hi = pRxLocal->Fbr[1]->PAHigh[entry];
-		fbr_entry->addr_lo = pRxLocal->Fbr[1]->PALow[entry];
+	fbr_entry = (PFBR_DESC_t) rx_local->pFbr1RingVa;
+	for (entry = 0; entry < rx_local->Fbr1NumEntries; entry++) {
+		fbr_entry->addr_hi = rx_local->Fbr[1]->PAHigh[entry];
+		fbr_entry->addr_lo = rx_local->Fbr[1]->PALow[entry];
 		fbr_entry->word2.bits.bi = entry;
 		fbr_entry++;
 	}
@@ -712,39 +647,39 @@
 	/* Set the address and parameters of Free buffer ring 1 (and 0 if
 	 * required) into the 1310's registers
 	 */
-	writel((uint32_t) (pRxLocal->Fbr1Realpa >> 32), &rx_dma->fbr1_base_hi);
-	writel((uint32_t) pRxLocal->Fbr1Realpa, &rx_dma->fbr1_base_lo);
-	writel(pRxLocal->Fbr1NumEntries - 1, &rx_dma->fbr1_num_des.value);
+	writel((u32) (rx_local->Fbr1Realpa >> 32), &rx_dma->fbr1_base_hi);
+	writel((u32) rx_local->Fbr1Realpa, &rx_dma->fbr1_base_lo);
+	writel(rx_local->Fbr1NumEntries - 1, &rx_dma->fbr1_num_des);
 	writel(ET_DMA10_WRAP, &rx_dma->fbr1_full_offset);
 
 	/* This variable tracks the free buffer ring 1 full position, so it
 	 * has to match the above.
 	 */
-	pRxLocal->local_Fbr1_full = ET_DMA10_WRAP;
-	writel(((pRxLocal->Fbr1NumEntries * LO_MARK_PERCENT_FOR_RX) / 100) - 1,
-	       &rx_dma->fbr1_min_des.value);
+	rx_local->local_Fbr1_full = ET_DMA10_WRAP;
+	writel(((rx_local->Fbr1NumEntries * LO_MARK_PERCENT_FOR_RX) / 100) - 1,
+	       &rx_dma->fbr1_min_des);
 
 #ifdef USE_FBR0
 	/* Now's the best time to initialize FBR0 contents */
-	fbr_entry = (PFBR_DESC_t) pRxLocal->pFbr0RingVa;
-	for (entry = 0; entry < pRxLocal->Fbr0NumEntries; entry++) {
-		fbr_entry->addr_hi = pRxLocal->Fbr[0]->PAHigh[entry];
-		fbr_entry->addr_lo = pRxLocal->Fbr[0]->PALow[entry];
+	fbr_entry = (PFBR_DESC_t) rx_local->pFbr0RingVa;
+	for (entry = 0; entry < rx_local->Fbr0NumEntries; entry++) {
+		fbr_entry->addr_hi = rx_local->Fbr[0]->PAHigh[entry];
+		fbr_entry->addr_lo = rx_local->Fbr[0]->PALow[entry];
 		fbr_entry->word2.bits.bi = entry;
 		fbr_entry++;
 	}
 
-	writel((uint32_t) (pRxLocal->Fbr0Realpa >> 32), &rx_dma->fbr0_base_hi);
-	writel((uint32_t) pRxLocal->Fbr0Realpa, &rx_dma->fbr0_base_lo);
-	writel(pRxLocal->Fbr0NumEntries - 1, &rx_dma->fbr0_num_des.value);
+	writel((u32) (rx_local->Fbr0Realpa >> 32), &rx_dma->fbr0_base_hi);
+	writel((u32) rx_local->Fbr0Realpa, &rx_dma->fbr0_base_lo);
+	writel(rx_local->Fbr0NumEntries - 1, &rx_dma->fbr0_num_des);
 	writel(ET_DMA10_WRAP, &rx_dma->fbr0_full_offset);
 
 	/* This variable tracks the free buffer ring 0 full position, so it
 	 * has to match the above.
 	 */
-	pRxLocal->local_Fbr0_full = ET_DMA10_WRAP;
-	writel(((pRxLocal->Fbr0NumEntries * LO_MARK_PERCENT_FOR_RX) / 100) - 1,
-	       &rx_dma->fbr0_min_des.value);
+	rx_local->local_Fbr0_full = ET_DMA10_WRAP;
+	writel(((rx_local->Fbr0NumEntries * LO_MARK_PERCENT_FOR_RX) / 100) - 1,
+	       &rx_dma->fbr0_min_des);
 #endif
 
 	/* Program the number of packets we will receive before generating an
@@ -752,14 +687,14 @@
 	 * For version B silicon, this value gets updated once autoneg is
 	 *complete.
 	 */
-	writel(PARM_RX_NUM_BUFS_DEF, &rx_dma->num_pkt_done.value);
+	writel(PARM_RX_NUM_BUFS_DEF, &rx_dma->num_pkt_done);
 
 	/* The "time_done" is not working correctly to coalesce interrupts
 	 * after a given time period, but rather is giving us an interrupt
 	 * regardless of whether we have received packets.
 	 * This value gets updated once autoneg is complete.
 	 */
-	writel(PARM_RX_TIME_INT_DEF, &rx_dma->max_pkt_time.value);
+	writel(PARM_RX_TIME_INT_DEF, &rx_dma->max_pkt_time);
 
 	spin_unlock_irqrestore(&etdev->RcvLock, flags);
 }
@@ -775,8 +710,8 @@
 	 */
 	if ((etdev->linkspeed == TRUEPHY_SPEED_100MBPS) ||
 	    (etdev->linkspeed == TRUEPHY_SPEED_10MBPS)) {
-		writel(0, &etdev->regs->rxdma.max_pkt_time.value);
-		writel(1, &etdev->regs->rxdma.num_pkt_done.value);
+		writel(0, &etdev->regs->rxdma.max_pkt_time);
+		writel(1, &etdev->regs->rxdma.num_pkt_done);
 	}
 }
 
@@ -807,40 +742,35 @@
  */
 void et131x_rx_dma_enable(struct et131x_adapter *etdev)
 {
-	if (etdev->RegistryPhyLoopbk)
-		/* RxDMA is disabled for loopback operation. */
-		writel(0x1, &etdev->regs->rxdma.csr.value);
-	else {
 	/* Setup the receive dma configuration register for normal operation */
-		RXDMA_CSR_t csr = { 0 };
+	RXDMA_CSR_t csr = { 0 };
 
-		csr.bits.fbr1_enable = 1;
-		if (etdev->RxRing.Fbr1BufferSize == 4096)
-			csr.bits.fbr1_size = 1;
-		else if (etdev->RxRing.Fbr1BufferSize == 8192)
-			csr.bits.fbr1_size = 2;
-		else if (etdev->RxRing.Fbr1BufferSize == 16384)
-			csr.bits.fbr1_size = 3;
+	csr.bits.fbr1_enable = 1;
+	if (etdev->RxRing.Fbr1BufferSize == 4096)
+		csr.bits.fbr1_size = 1;
+	else if (etdev->RxRing.Fbr1BufferSize == 8192)
+		csr.bits.fbr1_size = 2;
+	else if (etdev->RxRing.Fbr1BufferSize == 16384)
+		csr.bits.fbr1_size = 3;
 #ifdef USE_FBR0
-		csr.bits.fbr0_enable = 1;
-		if (etdev->RxRing.Fbr0BufferSize == 256)
-			csr.bits.fbr0_size = 1;
-		else if (etdev->RxRing.Fbr0BufferSize == 512)
-			csr.bits.fbr0_size = 2;
-		else if (etdev->RxRing.Fbr0BufferSize == 1024)
-			csr.bits.fbr0_size = 3;
+	csr.bits.fbr0_enable = 1;
+	if (etdev->RxRing.Fbr0BufferSize == 256)
+		csr.bits.fbr0_size = 1;
+	else if (etdev->RxRing.Fbr0BufferSize == 512)
+		csr.bits.fbr0_size = 2;
+	else if (etdev->RxRing.Fbr0BufferSize == 1024)
+		csr.bits.fbr0_size = 3;
 #endif
-		writel(csr.value, &etdev->regs->rxdma.csr.value);
+	writel(csr.value, &etdev->regs->rxdma.csr.value);
 
+	csr.value = readl(&etdev->regs->rxdma.csr.value);
+	if (csr.bits.halt_status != 0) {
+		udelay(5);
 		csr.value = readl(&etdev->regs->rxdma.csr.value);
 		if (csr.bits.halt_status != 0) {
-			udelay(5);
-			csr.value = readl(&etdev->regs->rxdma.csr.value);
-			if (csr.bits.halt_status != 0) {
-				dev_err(&etdev->pdev->dev,
-					"RX Dma failed to exit halt state.  CSR 0x%08x\n",
-					csr.value);
-			}
+			dev_err(&etdev->pdev->dev,
+			    "RX Dma failed to exit halt state.  CSR 0x%08x\n",
+				csr.value);
 		}
 	}
 }
@@ -849,7 +779,7 @@
  * nic_rx_pkts - Checks the hardware for available packets
  * @etdev: pointer to our adapter
  *
- * Returns pMpRfd, a pointer to our MPRFD.
+ * Returns rfd, a pointer to our MPRFD.
  *
  * Checks the hardware for available packets, using completion ring
  * If packets are available, it gets an RFD from the RecvList, attaches
@@ -858,119 +788,122 @@
  */
 PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev)
 {
-	struct _rx_ring_t *pRxLocal = &etdev->RxRing;
-	PRX_STATUS_BLOCK_t pRxStatusBlock;
-	PPKT_STAT_DESC_t pPSREntry;
-	PMP_RFD pMpRfd;
-	uint32_t nIndex;
-	uint8_t *pBufVa;
+	struct _rx_ring_t *rx_local = &etdev->RxRing;
+	PRX_STATUS_BLOCK_t status;
+	PPKT_STAT_DESC_t psr;
+	PMP_RFD rfd;
+	u32 i;
+	uint8_t *buf;
 	unsigned long flags;
 	struct list_head *element;
-	uint8_t ringIndex;
-	uint16_t bufferIndex;
-	uint32_t localLen;
+	uint8_t rindex;
+	uint16_t bindex;
+	u32 len;
 	PKT_STAT_DESC_WORD0_t Word0;
 
 	/* RX Status block is written by the DMA engine prior to every
 	 * interrupt. It contains the next to be used entry in the Packet
 	 * Status Ring, and also the two Free Buffer rings.
 	 */
-	pRxStatusBlock = (PRX_STATUS_BLOCK_t) pRxLocal->pRxStatusVa;
+	status = (PRX_STATUS_BLOCK_t) rx_local->pRxStatusVa;
 
-	if (pRxStatusBlock->Word1.bits.PSRoffset ==
-			pRxLocal->local_psr_full.bits.psr_full &&
-			pRxStatusBlock->Word1.bits.PSRwrap ==
-			pRxLocal->local_psr_full.bits.psr_full_wrap) {
+	/* FIXME: tidy later when conversions complete */
+	if (status->Word1.bits.PSRoffset ==
+			(rx_local->local_psr_full & 0xFFF) &&
+			status->Word1.bits.PSRwrap ==
+			((rx_local->local_psr_full >> 12) & 1)) {
 		/* Looks like this ring is not updated yet */
 		return NULL;
 	}
 
 	/* The packet status ring indicates that data is available. */
-	pPSREntry = (PPKT_STAT_DESC_t) (pRxLocal->pPSRingVa) +
-			pRxLocal->local_psr_full.bits.psr_full;
+	psr = (PPKT_STAT_DESC_t) (rx_local->pPSRingVa) +
+			(rx_local->local_psr_full & 0xFFF);
 
 	/* Grab any information that is required once the PSR is
 	 * advanced, since we can no longer rely on the memory being
 	 * accurate
 	 */
-	localLen = pPSREntry->word1.bits.length;
-	ringIndex = (uint8_t) pPSREntry->word1.bits.ri;
-	bufferIndex = (uint16_t) pPSREntry->word1.bits.bi;
-	Word0 = pPSREntry->word0;
+	len = psr->word1.bits.length;
+	rindex = (uint8_t) psr->word1.bits.ri;
+	bindex = (uint16_t) psr->word1.bits.bi;
+	Word0 = psr->word0;
 
 	/* Indicate that we have used this PSR entry. */
-	if (++pRxLocal->local_psr_full.bits.psr_full >
-	    pRxLocal->PsrNumEntries - 1) {
-		pRxLocal->local_psr_full.bits.psr_full = 0;
-		pRxLocal->local_psr_full.bits.psr_full_wrap ^= 1;
+	/* FIXME wrap 12 */
+	rx_local->local_psr_full = (rx_local->local_psr_full + 1) & 0xFFF;
+	if (rx_local->local_psr_full  > rx_local->PsrNumEntries - 1) {
+		/* Clear psr full and toggle the wrap bit */
+		rx_local->local_psr_full &=  0xFFF;
+		rx_local->local_psr_full ^= 0x1000;
 	}
 
-	writel(pRxLocal->local_psr_full.value,
-	       &etdev->regs->rxdma.psr_full_offset.value);
+	writel(rx_local->local_psr_full,
+	       &etdev->regs->rxdma.psr_full_offset);
 
 #ifndef USE_FBR0
-	if (ringIndex != 1) {
+	if (rindex != 1) {
 		return NULL;
 	}
 #endif
 
 #ifdef USE_FBR0
-	if (ringIndex > 1 ||
-		(ringIndex == 0 &&
-		bufferIndex > pRxLocal->Fbr0NumEntries - 1) ||
-		(ringIndex == 1 &&
-		bufferIndex > pRxLocal->Fbr1NumEntries - 1))
+	if (rindex > 1 ||
+		(rindex == 0 &&
+		bindex > rx_local->Fbr0NumEntries - 1) ||
+		(rindex == 1 &&
+		bindex > rx_local->Fbr1NumEntries - 1))
 #else
-	if (ringIndex != 1 ||
-		bufferIndex > pRxLocal->Fbr1NumEntries - 1)
+	if (rindex != 1 ||
+		bindex > rx_local->Fbr1NumEntries - 1)
 #endif
 	{
 		/* Illegal buffer or ring index cannot be used by S/W*/
 		dev_err(&etdev->pdev->dev,
 			  "NICRxPkts PSR Entry %d indicates "
 			  "length of %d and/or bad bi(%d)\n",
-			  pRxLocal->local_psr_full.bits.psr_full,
-			  localLen, bufferIndex);
+			  rx_local->local_psr_full & 0xFFF,
+			  len, bindex);
 		return NULL;
 	}
 
 	/* Get and fill the RFD. */
 	spin_lock_irqsave(&etdev->RcvLock, flags);
 
-	pMpRfd = NULL;
-	element = pRxLocal->RecvList.next;
-	pMpRfd = (PMP_RFD) list_entry(element, MP_RFD, list_node);
+	rfd = NULL;
+	element = rx_local->RecvList.next;
+	rfd = (PMP_RFD) list_entry(element, MP_RFD, list_node);
 
-	if (pMpRfd == NULL) {
+	if (rfd == NULL) {
 		spin_unlock_irqrestore(&etdev->RcvLock, flags);
 		return NULL;
 	}
 
-	list_del(&pMpRfd->list_node);
-	pRxLocal->nReadyRecv--;
+	list_del(&rfd->list_node);
+	rx_local->nReadyRecv--;
 
 	spin_unlock_irqrestore(&etdev->RcvLock, flags);
 
-	pMpRfd->bufferindex = bufferIndex;
-	pMpRfd->ringindex = ringIndex;
+	rfd->bufferindex = bindex;
+	rfd->ringindex = rindex;
 
 	/* In V1 silicon, there is a bug which screws up filtering of
 	 * runt packets.  Therefore runt packet filtering is disabled
 	 * in the MAC and the packets are dropped here.  They are
 	 * also counted here.
 	 */
-	if (localLen < (NIC_MIN_PACKET_SIZE + 4)) {
+	if (len < (NIC_MIN_PACKET_SIZE + 4)) {
 		etdev->Stats.other_errors++;
-		localLen = 0;
+		len = 0;
 	}
 
-	if (localLen) {
+	if (len) {
 		if (etdev->ReplicaPhyLoopbk == 1) {
-			pBufVa = pRxLocal->Fbr[ringIndex]->Va[bufferIndex];
+			buf = rx_local->Fbr[rindex]->Va[bindex];
 
-			if (memcmp(&pBufVa[6], &etdev->CurrentAddress[0],
+			if (memcmp(&buf[6], &etdev->CurrentAddress[0],
 				   ETH_ALEN) == 0) {
-				if (memcmp(&pBufVa[42], "Replica packet",
+				if (memcmp(&buf[42], "Replica packet",
 					   ETH_HLEN)) {
 					etdev->ReplicaPhyLoopbkPF = 1;
 				}
@@ -990,28 +923,28 @@
 			if ((etdev->PacketFilter & ET131X_PACKET_TYPE_MULTICAST)
 			    && !(etdev->PacketFilter & ET131X_PACKET_TYPE_PROMISCUOUS)
 			    && !(etdev->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST)) {
-				pBufVa = pRxLocal->Fbr[ringIndex]->
-						Va[bufferIndex];
+				buf = rx_local->Fbr[rindex]->
+						Va[bindex];
 
 				/* Loop through our list to see if the
 				 * destination address of this packet
 				 * matches one in our list.
 				 */
-				for (nIndex = 0;
-				     nIndex < etdev->MCAddressCount;
-				     nIndex++) {
-					if (pBufVa[0] ==
-					    etdev->MCList[nIndex][0]
-					    && pBufVa[1] ==
-					    etdev->MCList[nIndex][1]
-					    && pBufVa[2] ==
-					    etdev->MCList[nIndex][2]
-					    && pBufVa[3] ==
-					    etdev->MCList[nIndex][3]
-					    && pBufVa[4] ==
-					    etdev->MCList[nIndex][4]
-					    && pBufVa[5] ==
-					    etdev->MCList[nIndex][5]) {
+				for (i = 0;
+				     i < etdev->MCAddressCount;
+				     i++) {
+					if (buf[0] ==
+					    etdev->MCList[i][0]
+					    && buf[1] ==
+					    etdev->MCList[i][1]
+					    && buf[2] ==
+					    etdev->MCList[i][2]
+					    && buf[3] ==
+					    etdev->MCList[i][3]
+					    && buf[4] ==
+					    etdev->MCList[i][4]
+					    && buf[5] ==
+					    etdev->MCList[i][5]) {
 						break;
 					}
 				}
@@ -1024,11 +957,11 @@
 				 * so we free our RFD when we return
 				 * from this function.
 				 */
-				if (nIndex == etdev->MCAddressCount)
-					localLen = 0;
+				if (i == etdev->MCAddressCount)
+					len = 0;
 			}
 
-			if (localLen > 0)
+			if (len > 0)
 				etdev->Stats.multircv++;
 		} else if (Word0.value & ALCATEL_BROADCAST_PKT)
 			etdev->Stats.brdcstrcv++;
@@ -1041,24 +974,24 @@
 			etdev->Stats.unircv++;
 	}
 
-	if (localLen > 0) {
+	if (len > 0) {
 		struct sk_buff *skb = NULL;
 
-		/* pMpRfd->PacketSize = localLen - 4; */
-		pMpRfd->PacketSize = localLen;
+		/* rfd->PacketSize = len - 4; */
+		rfd->PacketSize = len;
 
-		skb = dev_alloc_skb(pMpRfd->PacketSize + 2);
+		skb = dev_alloc_skb(rfd->PacketSize + 2);
 		if (!skb) {
 			dev_err(&etdev->pdev->dev,
 				  "Couldn't alloc an SKB for Rx\n");
 			return NULL;
 		}
 
-		etdev->net_stats.rx_bytes += pMpRfd->PacketSize;
+		etdev->net_stats.rx_bytes += rfd->PacketSize;
 
-		memcpy(skb_put(skb, pMpRfd->PacketSize),
-		       pRxLocal->Fbr[ringIndex]->Va[bufferIndex],
-		       pMpRfd->PacketSize);
+		memcpy(skb_put(skb, rfd->PacketSize),
+		       rx_local->Fbr[rindex]->Va[bindex],
+		       rfd->PacketSize);
 
 		skb->dev = etdev->netdev;
 		skb->protocol = eth_type_trans(skb, etdev->netdev);
@@ -1066,11 +999,11 @@
 
 		netif_rx(skb);
 	} else {
-		pMpRfd->PacketSize = 0;
+		rfd->PacketSize = 0;
 	}
 
-	nic_return_rfd(etdev, pMpRfd);
-	return pMpRfd;
+	nic_return_rfd(etdev, rfd);
+	return rfd;
 }
 
 /**
@@ -1081,21 +1014,8 @@
  */
 void et131x_reset_recv(struct et131x_adapter *etdev)
 {
-	PMP_RFD pMpRfd;
-	struct list_head *element;
-
 	WARN_ON(list_empty(&etdev->RxRing.RecvList));
 
-	/* Take all the RFD's from the pending list, and stick them on the
-	 * RecvList.
-	 */
-	while (!list_empty(&etdev->RxRing.RecvPendingList)) {
-		element = etdev->RxRing.RecvPendingList.next;
-
-		pMpRfd = (PMP_RFD) list_entry(element, MP_RFD, list_node);
-
-		list_move_tail(&pMpRfd->list_node, &etdev->RxRing.RecvList);
-	}
 }
 
 /**
@@ -1106,27 +1026,21 @@
  */
 void et131x_handle_recv_interrupt(struct et131x_adapter *etdev)
 {
-	PMP_RFD pMpRfd = NULL;
-	struct sk_buff *PacketArray[NUM_PACKETS_HANDLED];
-	PMP_RFD RFDFreeArray[NUM_PACKETS_HANDLED];
-	uint32_t PacketArrayCount = 0;
-	uint32_t PacketsToHandle;
-	uint32_t PacketFreeCount = 0;
-	bool TempUnfinishedRec = false;
-
-	PacketsToHandle = NUM_PACKETS_HANDLED;
+	PMP_RFD rfd = NULL;
+	u32 count = 0;
+	bool done = true;
 
 	/* Process up to available RFD's */
-	while (PacketArrayCount < PacketsToHandle) {
+	while (count < NUM_PACKETS_HANDLED) {
 		if (list_empty(&etdev->RxRing.RecvList)) {
 			WARN_ON(etdev->RxRing.nReadyRecv != 0);
-			TempUnfinishedRec = true;
+			done = false;
 			break;
 		}
 
-		pMpRfd = nic_rx_pkts(etdev);
+		rfd = nic_rx_pkts(etdev);
 
-		if (pMpRfd == NULL)
+		if (rfd == NULL)
 			break;
 
 		/* Do not receive any packets until a filter has been set.
@@ -1136,7 +1050,7 @@
 		 */
 		if (!etdev->PacketFilter ||
 		    !(etdev->Flags & fMP_ADAPTER_LINK_DETECTION) ||
-		    pMpRfd->PacketSize == 0) {
+		    rfd->PacketSize == 0) {
 			continue;
 		}
 
@@ -1144,35 +1058,20 @@
 		etdev->Stats.ipackets++;
 
 		/* Set the status on the packet, either resources or success */
-		if (etdev->RxRing.nReadyRecv >= RFD_LOW_WATER_MARK) {
-			/* Put this RFD on the pending list
-			 *
-			 * NOTE: nic_rx_pkts() above is already returning the
-			 * RFD to the RecvList, so don't additionally do that
-			 * here.
-			 * Besides, we don't really need (at this point) the
-			 * pending list anyway.
-			 */
-		} else {
-			RFDFreeArray[PacketFreeCount] = pMpRfd;
-			PacketFreeCount++;
-
+		if (etdev->RxRing.nReadyRecv < RFD_LOW_WATER_MARK) {
 			dev_warn(&etdev->pdev->dev,
 				    "RFD's are running out\n");
 		}
-
-		PacketArray[PacketArrayCount] = pMpRfd->Packet;
-		PacketArrayCount++;
+		count++;
 	}
 
-	if ((PacketArrayCount == NUM_PACKETS_HANDLED) || TempUnfinishedRec) {
+	if (count == NUM_PACKETS_HANDLED || !done) {
 		etdev->RxRing.UnfinishedReceives = true;
 		writel(PARM_TX_TIME_INT_DEF * NANO_IN_A_MICRO,
 		       &etdev->regs->global.watchdog_timer);
-	} else {
+	} else
 		/* Watchdog timer will disable itself if appropriate. */
 		etdev->RxRing.UnfinishedReceives = false;
-	}
 }
 
 static inline u32 bump_fbr(u32 *fbr, u32 limit)
@@ -1196,14 +1095,14 @@
 /**
  * NICReturnRFD - Recycle a RFD and put it back onto the receive list
  * @etdev: pointer to our adapter
- * @pMpRfd: pointer to the RFD
+ * @rfd: pointer to the RFD
  */
-void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD pMpRfd)
+void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD rfd)
 {
 	struct _rx_ring_t *rx_local = &etdev->RxRing;
 	struct _RXDMA_t __iomem *rx_dma = &etdev->regs->rxdma;
-	uint16_t bi = pMpRfd->bufferindex;
-	uint8_t ri = pMpRfd->ringindex;
+	uint16_t bi = rfd->bufferindex;
+	uint8_t ri = rfd->ringindex;
 	unsigned long flags;
 
 	/* We don't use any of the OOB data besides status. Otherwise, we
@@ -1217,7 +1116,7 @@
 		spin_lock_irqsave(&etdev->FbrLock, flags);
 
 		if (ri == 1) {
-			PFBR_DESC_t pNextDesc =
+			PFBR_DESC_t next =
 			    (PFBR_DESC_t) (rx_local->pFbr1RingVa) +
 			    INDEX10(rx_local->local_Fbr1_full);
 
@@ -1225,9 +1124,9 @@
 			 * the PA / Buffer Index for the returned buffer into
 			 * the oldest (next to be freed)FBR entry
 			 */
-			pNextDesc->addr_hi = rx_local->Fbr[1]->PAHigh[bi];
-			pNextDesc->addr_lo = rx_local->Fbr[1]->PALow[bi];
-			pNextDesc->word2.value = bi;
+			next->addr_hi = rx_local->Fbr[1]->PAHigh[bi];
+			next->addr_lo = rx_local->Fbr[1]->PALow[bi];
+			next->word2.value = bi;
 
 			writel(bump_fbr(&rx_local->local_Fbr1_full,
 				rx_local->Fbr1NumEntries - 1),
@@ -1235,7 +1134,7 @@
 		}
 #ifdef USE_FBR0
 		else {
-			PFBR_DESC_t pNextDesc =
+			PFBR_DESC_t next =
 			    (PFBR_DESC_t) rx_local->pFbr0RingVa +
 			    INDEX10(rx_local->local_Fbr0_full);
 
@@ -1243,9 +1142,9 @@
 			 * the PA / Buffer Index for the returned buffer into
 			 * the oldest (next to be freed) FBR entry
 			 */
-			pNextDesc->addr_hi = rx_local->Fbr[0]->PAHigh[bi];
-			pNextDesc->addr_lo = rx_local->Fbr[0]->PALow[bi];
-			pNextDesc->word2.value = bi;
+			next->addr_hi = rx_local->Fbr[0]->PAHigh[bi];
+			next->addr_lo = rx_local->Fbr[0]->PALow[bi];
+			next->word2.value = bi;
 
 			writel(bump_fbr(&rx_local->local_Fbr0_full,
 					rx_local->Fbr0NumEntries - 1),
@@ -1262,7 +1161,7 @@
 	 * our list
 	 */
 	spin_lock_irqsave(&etdev->RcvLock, flags);
-	list_add_tail(&pMpRfd->list_node, &rx_local->RecvList);
+	list_add_tail(&rfd->list_node, &rx_local->RecvList);
 	rx_local->nReadyRecv++;
 	spin_unlock_irqrestore(&etdev->RcvLock, flags);
 
diff --git a/drivers/staging/et131x/et1310_rx.h b/drivers/staging/et131x/et1310_rx.h
index 72a5229..6951459 100644
--- a/drivers/staging/et131x/et1310_rx.h
+++ b/drivers/staging/et131x/et1310_rx.h
@@ -209,36 +209,26 @@
 /* Typedefs for the RX DMA status word */
 
 /*
- * RXSTAT_WORD0_t structure holds part of the status bits of the Rx DMA engine
+ * rx status word 0 holds part of the status bits of the Rx DMA engine
  * that get copied out to memory by the ET-1310.  Word 0 is a 32 bit word
- * whichcontains Free Buffer ring 0 and 1 available offset.
+ * which contains the Free Buffer ring 0 and 1 available offset.
+ *
+ * bit 0-9 FBR1 offset
+ * bit 10 Wrap flag for FBR1
+ * bit 16-25 FBR0 offset
+ * bit 26 Wrap flag for FBR0
  */
-typedef union _rxstat_word0_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 FBR1unused:5;	/* bits 27-31 */
-		u32 FBR1wrap:1;	/* bit 26 */
-		u32 FBR1offset:10;	/* bits 16-25 */
-		u32 FBR0unused:5;	/* bits 11-15 */
-		u32 FBR0wrap:1;	/* bit 10 */
-		u32 FBR0offset:10;	/* bits 0-9 */
-#else
-		u32 FBR0offset:10;	/* bits 0-9 */
-		u32 FBR0wrap:1;	/* bit 10 */
-		u32 FBR0unused:5;	/* bits 11-15 */
-		u32 FBR1offset:10;	/* bits 16-25 */
-		u32 FBR1wrap:1;	/* bit 26 */
-		u32 FBR1unused:5;	/* bits 27-31 */
-#endif
-	} bits;
-} RXSTAT_WORD0_t, *PRXSTAT_WORD0_t;
 
 /*
  * RXSTAT_WORD1_t structure holds part of the status bits of the Rx DMA engine
  * that get copied out to memory by the ET-1310.  Word 3 is a 32 bit word
  * which contains the Packet Status Ring available offset.
  */
+
+#define RXSTAT1_OFFSET	16
+#define RXSTAT1_MASK	0xFFF
+#define RXSTAT1_WRAP	0x10000000
+
 typedef union _rxstat_word1_t {
 	u32 value;
 	struct {
@@ -261,7 +251,7 @@
  * it sits in free memory, and is pointed to by 0x101c / 0x1020
  */
 typedef struct _rx_status_block_t {
-	RXSTAT_WORD0_t Word0;
+	u32 Word0;
 	RXSTAT_WORD1_t Word1;
 } RX_STATUS_BLOCK_t, *PRX_STATUS_BLOCK_t;
 
@@ -282,15 +272,6 @@
 } eRX_INTERRUPT_STATE_t, *PeRX_INTERRUPT_STATE_t;
 
 /*
- * Structure to hold the skb's in a list
- */
-typedef struct rx_skb_list_elem {
-	struct list_head skb_list_elem;
-	dma_addr_t dma_addr;
-	struct sk_buff *skb;
-} RX_SKB_LIST_ELEM, *PRX_SKB_LIST_ELEM;
-
-/*
  * RX_RING_t is sructure representing the adaptor's local reference(s) to the
  * rings
  */
@@ -319,21 +300,16 @@
 
 	void *pPSRingVa;
 	dma_addr_t pPSRingPa;
-	uint64_t pPSRingRealPa;
-	uint64_t pPSRingOffset;
-	RXDMA_PSR_FULL_OFFSET_t local_psr_full;
+	u32 local_psr_full;
 	u32 PsrNumEntries;
 
 	void *pRxStatusVa;
 	dma_addr_t pRxStatusPa;
-	uint64_t RxStatusRealPA;
-	uint64_t RxStatusOffset;
 
 	struct list_head RecvBufferPool;
 
 	/* RECV */
 	struct list_head RecvList;
-	struct list_head RecvPendingList;
 	u32 nReadyRecv;
 
 	u32 NumRfd;
diff --git a/drivers/staging/et131x/et1310_tx.c b/drivers/staging/et131x/et1310_tx.c
index 94f7752..977e8b3 100644
--- a/drivers/staging/et131x/et1310_tx.c
+++ b/drivers/staging/et131x/et1310_tx.c
@@ -94,13 +94,11 @@
 #include "et1310_tx.h"
 
 
-static void et131x_update_tcb_list(struct et131x_adapter *etdev);
-static void et131x_check_send_wait_list(struct et131x_adapter *etdev);
 static inline void et131x_free_send_packet(struct et131x_adapter *etdev,
-					   PMP_TCB pMpTcb);
+					   struct tcb *tcb);
 static int et131x_send_packet(struct sk_buff *skb,
 			      struct et131x_adapter *etdev);
-static int nic_send_packet(struct et131x_adapter *etdev, PMP_TCB pMpTcb);
+static int nic_send_packet(struct et131x_adapter *etdev, struct tcb *tcb);
 
 /**
  * et131x_tx_dma_memory_alloc
@@ -117,12 +115,12 @@
 int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter)
 {
 	int desc_size = 0;
-	TX_RING_t *tx_ring = &adapter->TxRing;
+	struct tx_ring *tx_ring = &adapter->tx_ring;
 
 	/* Allocate memory for the TCB's (Transmit Control Block) */
-	adapter->TxRing.MpTcbMem = (MP_TCB *)kcalloc(NUM_TCB, sizeof(MP_TCB),
-						      GFP_ATOMIC | GFP_DMA);
-	if (!adapter->TxRing.MpTcbMem) {
+	adapter->tx_ring.tcb_ring = (struct tcb *)
+		kcalloc(NUM_TCB, sizeof(struct tcb), GFP_ATOMIC | GFP_DMA);
+	if (!adapter->tx_ring.tcb_ring) {
 		dev_err(&adapter->pdev->dev, "Cannot alloc memory for TCBs\n");
 		return -ENOMEM;
 	}
@@ -130,12 +128,13 @@
 	/* Allocate enough memory for the Tx descriptor ring, and allocate
 	 * some extra so that the ring can be aligned on a 4k boundary.
 	 */
-	desc_size = (sizeof(TX_DESC_ENTRY_t) * NUM_DESC_PER_RING_TX) + 4096 - 1;
-	tx_ring->pTxDescRingVa =
-	    (PTX_DESC_ENTRY_t) pci_alloc_consistent(adapter->pdev, desc_size,
-						    &tx_ring->pTxDescRingPa);
-	if (!adapter->TxRing.pTxDescRingVa) {
-		dev_err(&adapter->pdev->dev, "Cannot alloc memory for Tx Ring\n");
+	desc_size = (sizeof(struct tx_desc) * NUM_DESC_PER_RING_TX) + 4096 - 1;
+	tx_ring->tx_desc_ring =
+	    (struct tx_desc *) pci_alloc_consistent(adapter->pdev, desc_size,
+						    &tx_ring->tx_desc_ring_pa);
+	if (!adapter->tx_ring.tx_desc_ring) {
+		dev_err(&adapter->pdev->dev,
+					"Cannot alloc memory for Tx Ring\n");
 		return -ENOMEM;
 	}
 
@@ -146,35 +145,15 @@
 	 * are ever returned, make sure the high part is retrieved here before
 	 * storing the adjusted address.
 	 */
-	tx_ring->pTxDescRingAdjustedPa = tx_ring->pTxDescRingPa;
-
-	/* Align Tx Descriptor Ring on a 4k (0x1000) byte boundary */
-	et131x_align_allocated_memory(adapter,
-				      &tx_ring->pTxDescRingAdjustedPa,
-				      &tx_ring->TxDescOffset, 0x0FFF);
-
-	tx_ring->pTxDescRingVa += tx_ring->TxDescOffset;
-
 	/* Allocate memory for the Tx status block */
-	tx_ring->pTxStatusVa = pci_alloc_consistent(adapter->pdev,
-						    sizeof(TX_STATUS_BLOCK_t),
-						    &tx_ring->pTxStatusPa);
-	if (!adapter->TxRing.pTxStatusPa) {
+	tx_ring->tx_status = pci_alloc_consistent(adapter->pdev,
+						    sizeof(u32),
+						    &tx_ring->tx_status_pa);
+	if (!adapter->tx_ring.tx_status_pa) {
 		dev_err(&adapter->pdev->dev,
 				  "Cannot alloc memory for Tx status block\n");
 		return -ENOMEM;
 	}
-
-	/* Allocate memory for a dummy buffer */
-	tx_ring->pTxDummyBlkVa = pci_alloc_consistent(adapter->pdev,
-						      NIC_MIN_PACKET_SIZE,
-						      &tx_ring->pTxDummyBlkPa);
-	if (!adapter->TxRing.pTxDummyBlkPa) {
-		dev_err(&adapter->pdev->dev,
-			"Cannot alloc memory for Tx dummy buffer\n");
-		return -ENOMEM;
-	}
-
 	return 0;
 }
 
@@ -188,76 +167,59 @@
 {
 	int desc_size = 0;
 
-	if (adapter->TxRing.pTxDescRingVa) {
+	if (adapter->tx_ring.tx_desc_ring) {
 		/* Free memory relating to Tx rings here */
-		adapter->TxRing.pTxDescRingVa -= adapter->TxRing.TxDescOffset;
-
-		desc_size =
-		    (sizeof(TX_DESC_ENTRY_t) * NUM_DESC_PER_RING_TX) + 4096 - 1;
-
+		desc_size = (sizeof(struct tx_desc) * NUM_DESC_PER_RING_TX)
+								+ 4096 - 1;
 		pci_free_consistent(adapter->pdev,
 				    desc_size,
-				    adapter->TxRing.pTxDescRingVa,
-				    adapter->TxRing.pTxDescRingPa);
-
-		adapter->TxRing.pTxDescRingVa = NULL;
+				    adapter->tx_ring.tx_desc_ring,
+				    adapter->tx_ring.tx_desc_ring_pa);
+		adapter->tx_ring.tx_desc_ring = NULL;
 	}
 
 	/* Free memory for the Tx status block */
-	if (adapter->TxRing.pTxStatusVa) {
+	if (adapter->tx_ring.tx_status) {
 		pci_free_consistent(adapter->pdev,
-				    sizeof(TX_STATUS_BLOCK_t),
-				    adapter->TxRing.pTxStatusVa,
-				    adapter->TxRing.pTxStatusPa);
+				    sizeof(u32),
+				    adapter->tx_ring.tx_status,
+				    adapter->tx_ring.tx_status_pa);
 
-		adapter->TxRing.pTxStatusVa = NULL;
+		adapter->tx_ring.tx_status = NULL;
 	}
-
-	/* Free memory for the dummy buffer */
-	if (adapter->TxRing.pTxDummyBlkVa) {
-		pci_free_consistent(adapter->pdev,
-				    NIC_MIN_PACKET_SIZE,
-				    adapter->TxRing.pTxDummyBlkVa,
-				    adapter->TxRing.pTxDummyBlkPa);
-
-		adapter->TxRing.pTxDummyBlkVa = NULL;
-	}
-
-	/* Free the memory for MP_TCB structures */
-	kfree(adapter->TxRing.MpTcbMem);
+	/* Free the memory for the tcb structures */
+	kfree(adapter->tx_ring.tcb_ring);
 }
 
 /**
  * ConfigTxDmaRegs - Set up the tx dma section of the JAGCore.
  * @etdev: pointer to our private adapter structure
+ *
+ * Configure the transmit engine with the ring buffers we have created
+ * and prepare it for use.
  */
 void ConfigTxDmaRegs(struct et131x_adapter *etdev)
 {
 	struct _TXDMA_t __iomem *txdma = &etdev->regs->txdma;
 
 	/* Load the hardware with the start of the transmit descriptor ring. */
-	writel((uint32_t) (etdev->TxRing.pTxDescRingAdjustedPa >> 32),
+	writel((u32) ((u64)etdev->tx_ring.tx_desc_ring_pa >> 32),
 	       &txdma->pr_base_hi);
-	writel((uint32_t) etdev->TxRing.pTxDescRingAdjustedPa,
+	writel((u32) etdev->tx_ring.tx_desc_ring_pa,
 	       &txdma->pr_base_lo);
 
 	/* Initialise the transmit DMA engine */
-	writel(NUM_DESC_PER_RING_TX - 1, &txdma->pr_num_des.value);
+	writel(NUM_DESC_PER_RING_TX - 1, &txdma->pr_num_des);
 
-	/* Load the completion writeback physical address
-	 *
-	 * NOTE: pci_alloc_consistent(), used above to alloc DMA regions,
-	 * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses
-	 * are ever returned, make sure the high part is retrieved here before
-	 * storing the adjusted address.
-	 */
-	writel(0, &txdma->dma_wb_base_hi);
-	writel(etdev->TxRing.pTxStatusPa, &txdma->dma_wb_base_lo);
+	/* Load the completion writeback physical address */
+	writel((u32)((u64)etdev->tx_ring.tx_status_pa >> 32),
+						&txdma->dma_wb_base_hi);
+	writel((u32)etdev->tx_ring.tx_status_pa, &txdma->dma_wb_base_lo);
 
-	memset(etdev->TxRing.pTxStatusVa, 0, sizeof(TX_STATUS_BLOCK_t));
+	*etdev->tx_ring.tx_status = 0;
 
 	writel(0, &txdma->service_request);
-	etdev->TxRing.txDmaReadyToSend = 0;
+	etdev->tx_ring.send_idx = 0;
 }
 
 /**
@@ -279,16 +241,11 @@
  */
 void et131x_tx_dma_enable(struct et131x_adapter *etdev)
 {
-	u32 csr = ET_TXDMA_SNGL_EPKT;
-	if (etdev->RegistryPhyLoopbk)
-		/* TxDMA is disabled for loopback operation. */
-		csr |= ET_TXDMA_CSR_HALT;
-	else
-		/* Setup the transmit dma configuration register for normal
-		 * operation
-		 */
-		csr |= PARM_DMA_CACHE_DEF << ET_TXDMA_CACHE_SHIFT;
-	writel(csr, &etdev->regs->txdma.csr);
+	/* Setup the transmit dma configuration register for normal
+	 * operation
+	 */
+	writel(ET_TXDMA_SNGL_EPKT|(PARM_DMA_CACHE_DEF << ET_TXDMA_CACHE_SHIFT),
+					&etdev->regs->txdma.csr);
 }
 
 /**
@@ -297,39 +254,32 @@
  */
 void et131x_init_send(struct et131x_adapter *adapter)
 {
-	PMP_TCB pMpTcb;
-	uint32_t TcbCount;
-	TX_RING_t *tx_ring;
+	struct tcb *tcb;
+	u32 ct;
+	struct tx_ring *tx_ring;
 
 	/* Setup some convenience pointers */
-	tx_ring = &adapter->TxRing;
-	pMpTcb = adapter->TxRing.MpTcbMem;
+	tx_ring = &adapter->tx_ring;
+	tcb = adapter->tx_ring.tcb_ring;
 
-	tx_ring->TCBReadyQueueHead = pMpTcb;
+	tx_ring->tcb_qhead = tcb;
+
+	memset(tcb, 0, sizeof(struct tcb) * NUM_TCB);
 
 	/* Go through and set up each TCB */
-	for (TcbCount = 0; TcbCount < NUM_TCB; TcbCount++) {
-		memset(pMpTcb, 0, sizeof(MP_TCB));
-
+	for (ct = 0; ct++ < NUM_TCB; tcb++)
 		/* Set the link pointer in HW TCB to the next TCB in the
-		 * chain.  If this is the last TCB in the chain, also set the
-		 * tail pointer.
+		 * chain
 		 */
-		if (TcbCount < NUM_TCB - 1) {
-			pMpTcb->Next = pMpTcb + 1;
-		} else {
-			tx_ring->TCBReadyQueueTail = pMpTcb;
-			pMpTcb->Next = (PMP_TCB) NULL;
-		}
+		tcb->next = tcb + 1;
 
-		pMpTcb++;
-	}
-
+	/* Set the  tail pointer */
+	tcb--;
+	tx_ring->tcb_qtail = tcb;
+	tcb->next = NULL;
 	/* Curr send queue should now be empty */
-	tx_ring->CurrSendHead = (PMP_TCB) NULL;
-	tx_ring->CurrSendTail = (PMP_TCB) NULL;
-
-	INIT_LIST_HEAD(&adapter->TxRing.SendWaitQueue);
+	tx_ring->send_head = NULL;
+	tx_ring->send_tail = NULL;
 }
 
 /**
@@ -352,9 +302,8 @@
 	 * to Tx, so the PacketCount and it's array used makes no sense here
 	 */
 
-	/* Queue is not empty or TCB is not available */
-	if (!list_empty(&etdev->TxRing.SendWaitQueue) ||
-	    MP_TCB_RESOURCES_NOT_AVAILABLE(etdev)) {
+	/* TCB is not available */
+	if (etdev->tx_ring.used >= NUM_TCB) {
 		/* NOTE: If there's an error on send, no need to queue the
 		 * packet under Linux; if we just send an error up to the
 		 * netif layer, it will resend the skb to us.
@@ -364,27 +313,15 @@
 		/* We need to see if the link is up; if it's not, make the
 		 * netif layer think we're good and drop the packet
 		 */
-		/*
-		 * if( MP_SHOULD_FAIL_SEND( etdev ) ||
-		 *  etdev->DriverNoPhyAccess )
-		 */
-		if (MP_SHOULD_FAIL_SEND(etdev) || etdev->DriverNoPhyAccess
-		    || !netif_carrier_ok(netdev)) {
+		if ((etdev->Flags & fMP_ADAPTER_FAIL_SEND_MASK) ||
+					!netif_carrier_ok(netdev)) {
 			dev_kfree_skb_any(skb);
 			skb = NULL;
 
 			etdev->net_stats.tx_dropped++;
 		} else {
 			status = et131x_send_packet(skb, etdev);
-
-			if (status == -ENOMEM) {
-
-				/* NOTE: If there's an error on send, no need
-				 * to queue the packet under Linux; if we just
-				 * send an error up to the netif layer, it
-				 * will resend the skb to us.
-				 */
-			} else if (status != 0) {
+			if (status != 0 && status != -ENOMEM) {
 				/* On any other error, make netif think we're
 				 * OK and drop the packet
 				 */
@@ -409,87 +346,83 @@
 static int et131x_send_packet(struct sk_buff *skb,
 			      struct et131x_adapter *etdev)
 {
-	int status = 0;
-	PMP_TCB pMpTcb = NULL;
-	uint16_t *shbufva;
+	int status;
+	struct tcb *tcb = NULL;
+	u16 *shbufva;
 	unsigned long flags;
 
 	/* All packets must have at least a MAC address and a protocol type */
-	if (skb->len < ETH_HLEN) {
+	if (skb->len < ETH_HLEN)
 		return -EIO;
-	}
 
 	/* Get a TCB for this packet */
 	spin_lock_irqsave(&etdev->TCBReadyQLock, flags);
 
-	pMpTcb = etdev->TxRing.TCBReadyQueueHead;
+	tcb = etdev->tx_ring.tcb_qhead;
 
-	if (pMpTcb == NULL) {
+	if (tcb == NULL) {
 		spin_unlock_irqrestore(&etdev->TCBReadyQLock, flags);
 		return -ENOMEM;
 	}
 
-	etdev->TxRing.TCBReadyQueueHead = pMpTcb->Next;
+	etdev->tx_ring.tcb_qhead = tcb->next;
 
-	if (etdev->TxRing.TCBReadyQueueHead == NULL)
-		etdev->TxRing.TCBReadyQueueTail = NULL;
+	if (etdev->tx_ring.tcb_qhead == NULL)
+		etdev->tx_ring.tcb_qtail = NULL;
 
 	spin_unlock_irqrestore(&etdev->TCBReadyQLock, flags);
 
-	pMpTcb->PacketLength = skb->len;
-	pMpTcb->Packet = skb;
+	tcb->skb = skb;
 
-	if ((skb->data != NULL) && ((skb->len - skb->data_len) >= 6)) {
-		shbufva = (uint16_t *) skb->data;
+	if (skb->data != NULL && skb->len - skb->data_len >= 6) {
+		shbufva = (u16 *) skb->data;
 
 		if ((shbufva[0] == 0xffff) &&
 		    (shbufva[1] == 0xffff) && (shbufva[2] == 0xffff)) {
-			pMpTcb->Flags |= fMP_DEST_BROAD;
+			tcb->flags |= fMP_DEST_BROAD;
 		} else if ((shbufva[0] & 0x3) == 0x0001) {
-			pMpTcb->Flags |=  fMP_DEST_MULTI;
+			tcb->flags |=  fMP_DEST_MULTI;
 		}
 	}
 
-	pMpTcb->Next = NULL;
+	tcb->next = NULL;
 
 	/* Call the NIC specific send handler. */
-	if (status == 0)
-		status = nic_send_packet(etdev, pMpTcb);
+	status = nic_send_packet(etdev, tcb);
 
 	if (status != 0) {
 		spin_lock_irqsave(&etdev->TCBReadyQLock, flags);
 
-		if (etdev->TxRing.TCBReadyQueueTail) {
-			etdev->TxRing.TCBReadyQueueTail->Next = pMpTcb;
-		} else {
+		if (etdev->tx_ring.tcb_qtail)
+			etdev->tx_ring.tcb_qtail->next = tcb;
+		else
 			/* Apparently ready Q is empty. */
-			etdev->TxRing.TCBReadyQueueHead = pMpTcb;
-		}
+			etdev->tx_ring.tcb_qhead = tcb;
 
-		etdev->TxRing.TCBReadyQueueTail = pMpTcb;
+		etdev->tx_ring.tcb_qtail = tcb;
 		spin_unlock_irqrestore(&etdev->TCBReadyQLock, flags);
 		return status;
 	}
-	WARN_ON(etdev->TxRing.nBusySend > NUM_TCB);
+	WARN_ON(etdev->tx_ring.used > NUM_TCB);
 	return 0;
 }
 
 /**
  * nic_send_packet - NIC specific send handler for version B silicon.
  * @etdev: pointer to our adapter
- * @pMpTcb: pointer to MP_TCB
+ * @tcb: pointer to struct tcb
  *
  * Returns 0 or errno.
  */
-static int nic_send_packet(struct et131x_adapter *etdev, PMP_TCB pMpTcb)
+static int nic_send_packet(struct et131x_adapter *etdev, struct tcb *tcb)
 {
-	uint32_t loopIndex;
-	TX_DESC_ENTRY_t CurDesc[24];
-	uint32_t FragmentNumber = 0;
-	uint32_t thiscopy, remainder;
-	struct sk_buff *pPacket = pMpTcb->Packet;
-	uint32_t FragListCount = skb_shinfo(pPacket)->nr_frags + 1;
-	struct skb_frag_struct *pFragList = &skb_shinfo(pPacket)->frags[0];
+	u32 i;
+	struct tx_desc desc[24];	/* 24 x 16 byte */
+	u32 frag = 0;
+	u32 thiscopy, remainder;
+	struct sk_buff *skb = tcb->skb;
+	u32 nr_frags = skb_shinfo(skb)->nr_frags + 1;
+	struct skb_frag_struct *frags = &skb_shinfo(skb)->frags[0];
 	unsigned long flags;
 
 	/* Part of the optimizations of this send routine restrict us to
@@ -500,17 +433,16 @@
 	 * number of fragments. If needed, we can call this function,
 	 * although it is less efficient.
 	 */
-	if (FragListCount > 23) {
+	if (nr_frags > 23)
 		return -EIO;
-	}
 
-	memset(CurDesc, 0, sizeof(TX_DESC_ENTRY_t) * (FragListCount + 1));
+	memset(desc, 0, sizeof(struct tx_desc) * (nr_frags + 1));
 
-	for (loopIndex = 0; loopIndex < FragListCount; loopIndex++) {
+	for (i = 0; i < nr_frags; i++) {
 		/* If there is something in this element, lets get a
 		 * descriptor from the ring and get the necessary data
 		 */
-		if (loopIndex == 0) {
+		if (i == 0) {
 			/* If the fragments are smaller than a standard MTU,
 			 * then map them to a single descriptor in the Tx
 			 * Desc ring. However, if they're larger, as is
@@ -520,166 +452,164 @@
 			 * This will work until we determine why the hardware
 			 * doesn't seem to like large fragments.
 			 */
-			if ((pPacket->len - pPacket->data_len) <= 1514) {
-				CurDesc[FragmentNumber].DataBufferPtrHigh = 0;
-				CurDesc[FragmentNumber].word2.bits.
-				    length_in_bytes =
-				    pPacket->len - pPacket->data_len;
+			if ((skb->len - skb->data_len) <= 1514) {
+				desc[frag].addr_hi = 0;
+				/* Low 16bits are length, high is vlan and
+				   unused currently so zero */
+				desc[frag].len_vlan =
+					skb->len - skb->data_len;
 
 				/* NOTE: Here, the dma_addr_t returned from
 				 * pci_map_single() is implicitly cast as a
-				 * uint32_t. Although dma_addr_t can be
+				 * u32. Although dma_addr_t can be
 				 * 64-bit, the address returned by
 				 * pci_map_single() is always 32-bit
 				 * addressable (as defined by the pci/dma
 				 * subsystem)
 				 */
-				CurDesc[FragmentNumber++].DataBufferPtrLow =
+				desc[frag++].addr_lo =
 				    pci_map_single(etdev->pdev,
-						   pPacket->data,
-						   pPacket->len -
-						   pPacket->data_len,
+						   skb->data,
+						   skb->len -
+						   skb->data_len,
 						   PCI_DMA_TODEVICE);
 			} else {
-				CurDesc[FragmentNumber].DataBufferPtrHigh = 0;
-				CurDesc[FragmentNumber].word2.bits.
-				    length_in_bytes =
-				    ((pPacket->len - pPacket->data_len) / 2);
+				desc[frag].addr_hi = 0;
+				desc[frag].len_vlan =
+				    (skb->len - skb->data_len) / 2;
 
 				/* NOTE: Here, the dma_addr_t returned from
 				 * pci_map_single() is implicitly cast as a
-				 * uint32_t. Although dma_addr_t can be
+				 * u32. Although dma_addr_t can be
 				 * 64-bit, the address returned by
 				 * pci_map_single() is always 32-bit
 				 * addressable (as defined by the pci/dma
 				 * subsystem)
 				 */
-				CurDesc[FragmentNumber++].DataBufferPtrLow =
+				desc[frag++].addr_lo =
 				    pci_map_single(etdev->pdev,
-						   pPacket->data,
-						   ((pPacket->len -
-						     pPacket->data_len) / 2),
+						   skb->data,
+						   ((skb->len -
+						     skb->data_len) / 2),
 						   PCI_DMA_TODEVICE);
-				CurDesc[FragmentNumber].DataBufferPtrHigh = 0;
+				desc[frag].addr_hi = 0;
 
-				CurDesc[FragmentNumber].word2.bits.
-				    length_in_bytes =
-				    ((pPacket->len - pPacket->data_len) / 2);
+				desc[frag].len_vlan =
+				    (skb->len - skb->data_len) / 2;
 
 				/* NOTE: Here, the dma_addr_t returned from
 				 * pci_map_single() is implicitly cast as a
-				 * uint32_t. Although dma_addr_t can be
+				 * u32. Although dma_addr_t can be
 				 * 64-bit, the address returned by
 				 * pci_map_single() is always 32-bit
 				 * addressable (as defined by the pci/dma
 				 * subsystem)
 				 */
-				CurDesc[FragmentNumber++].DataBufferPtrLow =
+				desc[frag++].addr_lo =
 				    pci_map_single(etdev->pdev,
-						   pPacket->data +
-						   ((pPacket->len -
-						     pPacket->data_len) / 2),
-						   ((pPacket->len -
-						     pPacket->data_len) / 2),
+						   skb->data +
+						   ((skb->len -
+						     skb->data_len) / 2),
+						   ((skb->len -
+						     skb->data_len) / 2),
 						   PCI_DMA_TODEVICE);
 			}
 		} else {
-			CurDesc[FragmentNumber].DataBufferPtrHigh = 0;
-			CurDesc[FragmentNumber].word2.bits.length_in_bytes =
-			    pFragList[loopIndex - 1].size;
+			desc[frag].addr_hi = 0;
+			desc[frag].len_vlan =
+					frags[i - 1].size;
 
 			/* NOTE: Here, the dma_addr_t returned from
-			 * pci_map_page() is implicitly cast as a uint32_t.
+			 * pci_map_page() is implicitly cast as a u32.
 			 * Although dma_addr_t can be 64-bit, the address
 			 * returned by pci_map_page() is always 32-bit
 			 * addressable (as defined by the pci/dma subsystem)
 			 */
-			CurDesc[FragmentNumber++].DataBufferPtrLow =
+			desc[frag++].addr_lo =
 			    pci_map_page(etdev->pdev,
-					 pFragList[loopIndex - 1].page,
-					 pFragList[loopIndex - 1].page_offset,
-					 pFragList[loopIndex - 1].size,
+					 frags[i - 1].page,
+					 frags[i - 1].page_offset,
+					 frags[i - 1].size,
 					 PCI_DMA_TODEVICE);
 		}
 	}
 
-	if (FragmentNumber == 0)
+	if (frag == 0)
 		return -EIO;
 
 	if (etdev->linkspeed == TRUEPHY_SPEED_1000MBPS) {
-		if (++etdev->TxRing.TxPacketsSinceLastinterrupt ==
-		    PARM_TX_NUM_BUFS_DEF) {
-			CurDesc[FragmentNumber - 1].word3.value = 0x5;
-			etdev->TxRing.TxPacketsSinceLastinterrupt = 0;
-		} else {
-			CurDesc[FragmentNumber - 1].word3.value = 0x1;
+		if (++etdev->tx_ring.since_irq == PARM_TX_NUM_BUFS_DEF) {
+			/* Last element & Interrupt flag */
+			desc[frag - 1].flags = 0x5;
+			etdev->tx_ring.since_irq = 0;
+		} else { /* Last element */
+			desc[frag - 1].flags = 0x1;
 		}
-	} else {
-		CurDesc[FragmentNumber - 1].word3.value = 0x5;
-	}
+	} else
+		desc[frag - 1].flags = 0x5;
 
-	CurDesc[0].word3.bits.f = 1;
+	desc[0].flags |= 2;	/* First element flag */
 
-	pMpTcb->WrIndexStart = etdev->TxRing.txDmaReadyToSend;
-	pMpTcb->PacketStaleCount = 0;
+	tcb->index_start = etdev->tx_ring.send_idx;
+	tcb->stale = 0;
 
 	spin_lock_irqsave(&etdev->SendHWLock, flags);
 
 	thiscopy = NUM_DESC_PER_RING_TX -
-				INDEX10(etdev->TxRing.txDmaReadyToSend);
+				INDEX10(etdev->tx_ring.send_idx);
 
-	if (thiscopy >= FragmentNumber) {
+	if (thiscopy >= frag) {
 		remainder = 0;
-		thiscopy = FragmentNumber;
+		thiscopy = frag;
 	} else {
-		remainder = FragmentNumber - thiscopy;
+		remainder = frag - thiscopy;
 	}
 
-	memcpy(etdev->TxRing.pTxDescRingVa +
-	       INDEX10(etdev->TxRing.txDmaReadyToSend), CurDesc,
-	       sizeof(TX_DESC_ENTRY_t) * thiscopy);
+	memcpy(etdev->tx_ring.tx_desc_ring +
+	       INDEX10(etdev->tx_ring.send_idx), desc,
+	       sizeof(struct tx_desc) * thiscopy);
 
-	add_10bit(&etdev->TxRing.txDmaReadyToSend, thiscopy);
+	add_10bit(&etdev->tx_ring.send_idx, thiscopy);
 
-	if (INDEX10(etdev->TxRing.txDmaReadyToSend)== 0 ||
-	    INDEX10(etdev->TxRing.txDmaReadyToSend) == NUM_DESC_PER_RING_TX) {
-	     	etdev->TxRing.txDmaReadyToSend &= ~ET_DMA10_MASK;
-	     	etdev->TxRing.txDmaReadyToSend ^= ET_DMA10_WRAP;
+	if (INDEX10(etdev->tx_ring.send_idx) == 0 ||
+		    INDEX10(etdev->tx_ring.send_idx) == NUM_DESC_PER_RING_TX) {
+		etdev->tx_ring.send_idx &= ~ET_DMA10_MASK;
+		etdev->tx_ring.send_idx ^= ET_DMA10_WRAP;
 	}
 
 	if (remainder) {
-		memcpy(etdev->TxRing.pTxDescRingVa,
-		       CurDesc + thiscopy,
-		       sizeof(TX_DESC_ENTRY_t) * remainder);
+		memcpy(etdev->tx_ring.tx_desc_ring,
+		       desc + thiscopy,
+		       sizeof(struct tx_desc) * remainder);
 
-		add_10bit(&etdev->TxRing.txDmaReadyToSend, remainder);
+		add_10bit(&etdev->tx_ring.send_idx, remainder);
 	}
 
-	if (INDEX10(etdev->TxRing.txDmaReadyToSend) == 0) {
-		if (etdev->TxRing.txDmaReadyToSend)
-			pMpTcb->WrIndex = NUM_DESC_PER_RING_TX - 1;
+	if (INDEX10(etdev->tx_ring.send_idx) == 0) {
+		if (etdev->tx_ring.send_idx)
+			tcb->index = NUM_DESC_PER_RING_TX - 1;
 		else
-			pMpTcb->WrIndex= ET_DMA10_WRAP | (NUM_DESC_PER_RING_TX - 1);
+			tcb->index = ET_DMA10_WRAP|(NUM_DESC_PER_RING_TX - 1);
 	} else
-		pMpTcb->WrIndex = etdev->TxRing.txDmaReadyToSend - 1;
+		tcb->index = etdev->tx_ring.send_idx - 1;
 
 	spin_lock(&etdev->TCBSendQLock);
 
-	if (etdev->TxRing.CurrSendTail)
-		etdev->TxRing.CurrSendTail->Next = pMpTcb;
+	if (etdev->tx_ring.send_tail)
+		etdev->tx_ring.send_tail->next = tcb;
 	else
-		etdev->TxRing.CurrSendHead = pMpTcb;
+		etdev->tx_ring.send_head = tcb;
 
-	etdev->TxRing.CurrSendTail = pMpTcb;
+	etdev->tx_ring.send_tail = tcb;
 
-	WARN_ON(pMpTcb->Next != NULL);
+	WARN_ON(tcb->next != NULL);
 
-	etdev->TxRing.nBusySend++;
+	etdev->tx_ring.used++;
 
 	spin_unlock(&etdev->TCBSendQLock);
 
 	/* Write the new write pointer back to the device. */
-	writel(etdev->TxRing.txDmaReadyToSend,
+	writel(etdev->tx_ring.send_idx,
 	       &etdev->regs->txdma.service_request);
 
 	/* For Gig only, we use Tx Interrupt coalescing.  Enable the software
@@ -696,72 +626,71 @@
 
 
 /**
- * et131x_free_send_packet - Recycle a MP_TCB, complete the packet if necessary
+ * et131x_free_send_packet - Recycle a struct tcb
  * @etdev: pointer to our adapter
- * @pMpTcb: pointer to MP_TCB
+ * @tcb: pointer to struct tcb
  *
+ * Complete the packet if necessary
  * Assumption - Send spinlock has been acquired
  */
 inline void et131x_free_send_packet(struct et131x_adapter *etdev,
-							PMP_TCB pMpTcb)
+						struct tcb *tcb)
 {
 	unsigned long flags;
-	TX_DESC_ENTRY_t *desc = NULL;
+	struct tx_desc *desc = NULL;
 	struct net_device_stats *stats = &etdev->net_stats;
 
-	if (pMpTcb->Flags & fMP_DEST_BROAD)
+	if (tcb->flags & fMP_DEST_BROAD)
 		atomic_inc(&etdev->Stats.brdcstxmt);
-	else if (pMpTcb->Flags & fMP_DEST_MULTI)
+	else if (tcb->flags & fMP_DEST_MULTI)
 		atomic_inc(&etdev->Stats.multixmt);
 	else
 		atomic_inc(&etdev->Stats.unixmt);
 
-	if (pMpTcb->Packet) {
-		stats->tx_bytes += pMpTcb->Packet->len;
+	if (tcb->skb) {
+		stats->tx_bytes += tcb->skb->len;
 
 		/* Iterate through the TX descriptors on the ring
 		 * corresponding to this packet and umap the fragments
 		 * they point to
 		 */
 		do {
-			desc =
-			    (TX_DESC_ENTRY_t *) (etdev->TxRing.pTxDescRingVa +
-			    	INDEX10(pMpTcb->WrIndexStart));
+			desc = (struct tx_desc *)(etdev->tx_ring.tx_desc_ring +
+						INDEX10(tcb->index_start));
 
 			pci_unmap_single(etdev->pdev,
-					 desc->DataBufferPtrLow,
-					 desc->word2.value, PCI_DMA_TODEVICE);
+					 desc->addr_lo,
+					 desc->len_vlan, PCI_DMA_TODEVICE);
 
-			add_10bit(&pMpTcb->WrIndexStart, 1);
-			if (INDEX10(pMpTcb->WrIndexStart) >=
-			    NUM_DESC_PER_RING_TX) {
-			    	pMpTcb->WrIndexStart &= ~ET_DMA10_MASK;
-			    	pMpTcb->WrIndexStart ^= ET_DMA10_WRAP;
+			add_10bit(&tcb->index_start, 1);
+			if (INDEX10(tcb->index_start) >=
+							NUM_DESC_PER_RING_TX) {
+				tcb->index_start &= ~ET_DMA10_MASK;
+				tcb->index_start ^= ET_DMA10_WRAP;
 			}
-		} while (desc != (etdev->TxRing.pTxDescRingVa +
-				INDEX10(pMpTcb->WrIndex)));
+		} while (desc != (etdev->tx_ring.tx_desc_ring +
+				INDEX10(tcb->index)));
 
-		dev_kfree_skb_any(pMpTcb->Packet);
+		dev_kfree_skb_any(tcb->skb);
 	}
 
-	memset(pMpTcb, 0, sizeof(MP_TCB));
+	memset(tcb, 0, sizeof(struct tcb));
 
 	/* Add the TCB to the Ready Q */
 	spin_lock_irqsave(&etdev->TCBReadyQLock, flags);
 
 	etdev->Stats.opackets++;
 
-	if (etdev->TxRing.TCBReadyQueueTail) {
-		etdev->TxRing.TCBReadyQueueTail->Next = pMpTcb;
-	} else {
+	if (etdev->tx_ring.tcb_qtail)
+		etdev->tx_ring.tcb_qtail->next = tcb;
+	else
 		/* Apparently ready Q is empty. */
-		etdev->TxRing.TCBReadyQueueHead = pMpTcb;
-	}
+		etdev->tx_ring.tcb_qhead = tcb;
 
-	etdev->TxRing.TCBReadyQueueTail = pMpTcb;
+	etdev->tx_ring.tcb_qtail = tcb;
 
 	spin_unlock_irqrestore(&etdev->TCBReadyQLock, flags);
-	WARN_ON(etdev->TxRing.nBusySend < 0);
+	WARN_ON(etdev->tx_ring.used < 0);
 }
 
 /**
@@ -772,52 +701,40 @@
  */
 void et131x_free_busy_send_packets(struct et131x_adapter *etdev)
 {
-	PMP_TCB pMpTcb;
-	struct list_head *entry;
+	struct tcb *tcb;
 	unsigned long flags;
-	uint32_t FreeCounter = 0;
-
-	while (!list_empty(&etdev->TxRing.SendWaitQueue)) {
-		spin_lock_irqsave(&etdev->SendWaitLock, flags);
-
-		etdev->TxRing.nWaitSend--;
-		spin_unlock_irqrestore(&etdev->SendWaitLock, flags);
-
-		entry = etdev->TxRing.SendWaitQueue.next;
-	}
-
-	etdev->TxRing.nWaitSend = 0;
+	u32 freed = 0;
 
 	/* Any packets being sent? Check the first TCB on the send list */
 	spin_lock_irqsave(&etdev->TCBSendQLock, flags);
 
-	pMpTcb = etdev->TxRing.CurrSendHead;
+	tcb = etdev->tx_ring.send_head;
 
-	while ((pMpTcb != NULL) && (FreeCounter < NUM_TCB)) {
-		PMP_TCB pNext = pMpTcb->Next;
+	while (tcb != NULL && freed < NUM_TCB) {
+		struct tcb *next = tcb->next;
 
-		etdev->TxRing.CurrSendHead = pNext;
+		etdev->tx_ring.send_head = next;
 
-		if (pNext == NULL)
-			etdev->TxRing.CurrSendTail = NULL;
+		if (next == NULL)
+			etdev->tx_ring.send_tail = NULL;
 
-		etdev->TxRing.nBusySend--;
+		etdev->tx_ring.used--;
 
 		spin_unlock_irqrestore(&etdev->TCBSendQLock, flags);
 
-		FreeCounter++;
-		et131x_free_send_packet(etdev, pMpTcb);
+		freed++;
+		et131x_free_send_packet(etdev, tcb);
 
 		spin_lock_irqsave(&etdev->TCBSendQLock, flags);
 
-		pMpTcb = etdev->TxRing.CurrSendHead;
+		tcb = etdev->tx_ring.send_head;
 	}
 
-	WARN_ON(FreeCounter == NUM_TCB);
+	WARN_ON(freed == NUM_TCB);
 
 	spin_unlock_irqrestore(&etdev->TCBSendQLock, flags);
 
-	etdev->TxRing.nBusySend = 0;
+	etdev->tx_ring.used = 0;
 }
 
 /**
@@ -831,99 +748,56 @@
  */
 void et131x_handle_send_interrupt(struct et131x_adapter *etdev)
 {
-	/* Mark as completed any packets which have been sent by the device. */
-	et131x_update_tcb_list(etdev);
-
-	/* If we queued any transmits because we didn't have any TCBs earlier,
-	 * dequeue and send those packets now, as long as we have free TCBs.
-	 */
-	et131x_check_send_wait_list(etdev);
-}
-
-/**
- * et131x_update_tcb_list - Helper routine for Send Interrupt handler
- * @etdev: pointer to our adapter
- *
- * Re-claims the send resources and completes sends.  Can also be called as
- * part of the NIC send routine when the "ServiceComplete" indication has
- * wrapped.
- */
-static void et131x_update_tcb_list(struct et131x_adapter *etdev)
-{
 	unsigned long flags;
-	u32 ServiceComplete;
-	PMP_TCB pMpTcb;
+	u32 serviced;
+	struct tcb *tcb;
 	u32 index;
 
-	ServiceComplete = readl(&etdev->regs->txdma.NewServiceComplete);
-	index = INDEX10(ServiceComplete);
+	serviced = readl(&etdev->regs->txdma.NewServiceComplete);
+	index = INDEX10(serviced);
 
 	/* Has the ring wrapped?  Process any descriptors that do not have
 	 * the same "wrap" indicator as the current completion indicator
 	 */
 	spin_lock_irqsave(&etdev->TCBSendQLock, flags);
 
-	pMpTcb = etdev->TxRing.CurrSendHead;
+	tcb = etdev->tx_ring.send_head;
 
-	while (pMpTcb &&
-	       ((ServiceComplete ^ pMpTcb->WrIndex) & ET_DMA10_WRAP) &&
-	       index < INDEX10(pMpTcb->WrIndex)) {
-		etdev->TxRing.nBusySend--;
-		etdev->TxRing.CurrSendHead = pMpTcb->Next;
-		if (pMpTcb->Next == NULL)
-			etdev->TxRing.CurrSendTail = NULL;
+	while (tcb &&
+	       ((serviced ^ tcb->index) & ET_DMA10_WRAP) &&
+	       index < INDEX10(tcb->index)) {
+		etdev->tx_ring.used--;
+		etdev->tx_ring.send_head = tcb->next;
+		if (tcb->next == NULL)
+			etdev->tx_ring.send_tail = NULL;
 
 		spin_unlock_irqrestore(&etdev->TCBSendQLock, flags);
-		et131x_free_send_packet(etdev, pMpTcb);
+		et131x_free_send_packet(etdev, tcb);
 		spin_lock_irqsave(&etdev->TCBSendQLock, flags);
 
 		/* Goto the next packet */
-		pMpTcb = etdev->TxRing.CurrSendHead;
+		tcb = etdev->tx_ring.send_head;
 	}
-	while (pMpTcb &&
-	       !((ServiceComplete ^ pMpTcb->WrIndex) & ET_DMA10_WRAP)
-	       && index > (pMpTcb->WrIndex & ET_DMA10_MASK)) {
-		etdev->TxRing.nBusySend--;
-		etdev->TxRing.CurrSendHead = pMpTcb->Next;
-		if (pMpTcb->Next == NULL)
-			etdev->TxRing.CurrSendTail = NULL;
+	while (tcb &&
+	       !((serviced ^ tcb->index) & ET_DMA10_WRAP)
+	       && index > (tcb->index & ET_DMA10_MASK)) {
+		etdev->tx_ring.used--;
+		etdev->tx_ring.send_head = tcb->next;
+		if (tcb->next == NULL)
+			etdev->tx_ring.send_tail = NULL;
 
 		spin_unlock_irqrestore(&etdev->TCBSendQLock, flags);
-		et131x_free_send_packet(etdev, pMpTcb);
+		et131x_free_send_packet(etdev, tcb);
 		spin_lock_irqsave(&etdev->TCBSendQLock, flags);
 
 		/* Goto the next packet */
-		pMpTcb = etdev->TxRing.CurrSendHead;
+		tcb = etdev->tx_ring.send_head;
 	}
 
 	/* Wake up the queue when we hit a low-water mark */
-	if (etdev->TxRing.nBusySend <= (NUM_TCB / 3))
+	if (etdev->tx_ring.used <= NUM_TCB / 3)
 		netif_wake_queue(etdev->netdev);
 
 	spin_unlock_irqrestore(&etdev->TCBSendQLock, flags);
 }
 
-/**
- * et131x_check_send_wait_list - Helper routine for the interrupt handler
- * @etdev: pointer to our adapter
- *
- * Takes packets from the send wait queue and posts them to the device (if
- * room available).
- */
-static void et131x_check_send_wait_list(struct et131x_adapter *etdev)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&etdev->SendWaitLock, flags);
-
-	while (!list_empty(&etdev->TxRing.SendWaitQueue) &&
-				MP_TCB_RESOURCES_AVAILABLE(etdev)) {
-		struct list_head *entry;
-
-		entry = etdev->TxRing.SendWaitQueue.next;
-
-		etdev->TxRing.nWaitSend--;
-	}
-
-	spin_unlock_irqrestore(&etdev->SendWaitLock, flags);
-}
diff --git a/drivers/staging/et131x/et1310_tx.h b/drivers/staging/et131x/et1310_tx.h
index ad03721..4f0ea81 100644
--- a/drivers/staging/et131x/et1310_tx.h
+++ b/drivers/staging/et131x/et1310_tx.h
@@ -63,167 +63,89 @@
 /* Typedefs for Tx Descriptor Ring */
 
 /*
- * TXDESC_WORD2_t structure holds part of the control bits in the Tx Descriptor
- * ring for the ET-1310
+ * word 2 of the control bits in the Tx Descriptor ring for the ET-1310
+ *
+ * 0-15: length of packet
+ * 16-27: VLAN tag
+ * 28: VLAN CFI
+ * 29-31: VLAN priority
+ *
+ * word 3 of the control bits in the Tx Descriptor ring for the ET-1310
+ *
+ * 0: last packet in the sequence
+ * 1: first packet in the sequence
+ * 2: interrupt the processor when this pkt sent
+ * 3: Control word - no packet data
+ * 4: Issue half-duplex backpressure : XON/XOFF
+ * 5: send pause frame
+ * 6: Tx frame has error
+ * 7: append CRC
+ * 8: MAC override
+ * 9: pad packet
+ * 10: Packet is a Huge packet
+ * 11: append VLAN tag
+ * 12: IP checksum assist
+ * 13: TCP checksum assist
+ * 14: UDP checksum assist
  */
-typedef union _txdesc_word2_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 vlan_prio:3;		/* bits 29-31(VLAN priority) */
-		u32 vlan_cfi:1;		/* bit 28(cfi) */
-		u32 vlan_tag:12;		/* bits 16-27(VLAN tag) */
-		u32 length_in_bytes:16;	/* bits  0-15(packet length) */
-#else
-		u32 length_in_bytes:16;	/* bits  0-15(packet length) */
-		u32 vlan_tag:12;		/* bits 16-27(VLAN tag) */
-		u32 vlan_cfi:1;		/* bit 28(cfi) */
-		u32 vlan_prio:3;		/* bits 29-31(VLAN priority) */
-#endif	/* _BIT_FIELDS_HTOL */
-	} bits;
-} TXDESC_WORD2_t, *PTXDESC_WORD2_t;
+
+/* struct tx_desc represents each descriptor on the ring */
+struct tx_desc {
+	u32 addr_hi;
+	u32 addr_lo;
+	u32 len_vlan;	/* control words how to xmit the */
+	u32 flags;	/* data (detailed above) */
+};
 
 /*
- * TXDESC_WORD3_t structure holds part of the control bits in the Tx Descriptor
- * ring for the ET-1310
+ * The status of the Tx DMA engine it sits in free memory, and is pointed to
+ * by 0x101c / 0x1020. This is a DMA10 type
  */
-typedef union _txdesc_word3_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:17;	/* bits 15-31 */
-		u32 udpa:1;	/* bit 14(UDP checksum assist) */
-		u32 tcpa:1;	/* bit 13(TCP checksum assist) */
-		u32 ipa:1;		/* bit 12(IP checksum assist) */
-		u32 vlan:1;	/* bit 11(append VLAN tag) */
-		u32 hp:1;		/* bit 10(Packet is a Huge packet) */
-		u32 pp:1;		/* bit  9(pad packet) */
-		u32 mac:1;		/* bit  8(MAC override) */
-		u32 crc:1;		/* bit  7(append CRC) */
-		u32 e:1;		/* bit  6(Tx frame has error) */
-		u32 pf:1;		/* bit  5(send pause frame) */
-		u32 bp:1;		/* bit  4(Issue half-duplex backpressure (XON/XOFF) */
-		u32 cw:1;		/* bit  3(Control word - no packet data) */
-		u32 ir:1;		/* bit  2(interrupt the processor when this pkt sent) */
-		u32 f:1;		/* bit  1(first packet in the sequence) */
-		u32 l:1;		/* bit  0(last packet in the sequence) */
-#else
-		u32 l:1;		/* bit  0(last packet in the sequence) */
-		u32 f:1;		/* bit  1(first packet in the sequence) */
-		u32 ir:1;		/* bit  2(interrupt the processor when this pkt sent) */
-		u32 cw:1;		/* bit  3(Control word - no packet data) */
-		u32 bp:1;		/* bit  4(Issue half-duplex backpressure (XON/XOFF) */
-		u32 pf:1;		/* bit  5(send pause frame) */
-		u32 e:1;		/* bit  6(Tx frame has error) */
-		u32 crc:1;		/* bit  7(append CRC) */
-		u32 mac:1;		/* bit  8(MAC override) */
-		u32 pp:1;		/* bit  9(pad packet) */
-		u32 hp:1;		/* bit 10(Packet is a Huge packet) */
-		u32 vlan:1;	/* bit 11(append VLAN tag) */
-		u32 ipa:1;		/* bit 12(IP checksum assist) */
-		u32 tcpa:1;	/* bit 13(TCP checksum assist) */
-		u32 udpa:1;	/* bit 14(UDP checksum assist) */
-		u32 unused:17;	/* bits 15-31 */
-#endif	/* _BIT_FIELDS_HTOL */
-	} bits;
-} TXDESC_WORD3_t, *PTXDESC_WORD3_t;
 
-/* TX_DESC_ENTRY_t is sructure representing each descriptor on the ring */
-typedef struct _tx_desc_entry_t {
-	u32 DataBufferPtrHigh;
-	u32 DataBufferPtrLow;
-	TXDESC_WORD2_t word2;	/* control words how to xmit the */
-	TXDESC_WORD3_t word3;	/* data (detailed above) */
-} TX_DESC_ENTRY_t, *PTX_DESC_ENTRY_t;
+/* TCB (Transmit Control Block: Host Side) */
+struct tcb {
+	struct tcb *next;	/* Next entry in ring */
+	u32 flags;		/* Our flags for the packet */
+	u32 count;		/* Used to spot stuck/lost packets */
+	u32 stale;		/* Used to spot stuck/lost packets */
+	struct sk_buff *skb;	/* Network skb we are tied to */
+	u32 index;		/* Ring indexes */
+	u32 index_start;
+};
 
-
-/* Typedefs for Tx DMA engine status writeback */
-
-/*
- * TX_STATUS_BLOCK_t is sructure representing the status of the Tx DMA engine
- * it sits in free memory, and is pointed to by 0x101c / 0x1020
- */
-typedef union _tx_status_block_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:21;		/* bits 11-31 */
-		u32 serv_cpl_wrap:1;	/* bit 10 */
-		u32 serv_cpl:10;		/* bits 0-9 */
-#else
-		u32 serv_cpl:10;		/* bits 0-9 */
-		u32 serv_cpl_wrap:1;	/* bit 10 */
-		u32 unused:21;		/* bits 11-31 */
-#endif
-	} bits;
-} TX_STATUS_BLOCK_t, *PTX_STATUS_BLOCK_t;
-
-/* TCB (Transmit Control Block) */
-typedef struct _MP_TCB {
-	struct _MP_TCB *Next;
-	u32 Flags;
-	u32 Count;
-	u32 PacketStaleCount;
-	struct sk_buff *Packet;
-	u32 PacketLength;
-	u32 WrIndex;
-	u32 WrIndexStart;
-} MP_TCB, *PMP_TCB;
-
-/* Structure to hold the skb's in a list */
-typedef struct tx_skb_list_elem {
-	struct list_head skb_list_elem;
-	struct sk_buff *skb;
-} TX_SKB_LIST_ELEM, *PTX_SKB_LIST_ELEM;
-
-/* TX_RING_t is sructure representing our local reference(s) to the ring */
-typedef struct _tx_ring_t {
+/* Structure representing our local reference(s) to the ring */
+struct tx_ring {
 	/* TCB (Transmit Control Block) memory and lists */
-	PMP_TCB MpTcbMem;
+	struct tcb *tcb_ring;
 
 	/* List of TCBs that are ready to be used */
-	PMP_TCB TCBReadyQueueHead;
-	PMP_TCB TCBReadyQueueTail;
+	struct tcb *tcb_qhead;
+	struct tcb *tcb_qtail;
 
 	/* list of TCBs that are currently being sent.  NOTE that access to all
-	 * three of these (including nBusySend) are controlled via the
+	 * three of these (including used) are controlled via the
 	 * TCBSendQLock.  This lock should be secured prior to incementing /
-	 * decrementing nBusySend, or any queue manipulation on CurrSendHead /
-	 * Tail
+	 * decrementing used, or any queue manipulation on send_head /
+	 * tail
 	 */
-	PMP_TCB CurrSendHead;
-	PMP_TCB CurrSendTail;
-	int32_t nBusySend;
-
-	/* List of packets (not TCBs) that were queued for lack of resources */
-	struct list_head SendWaitQueue;
-	int32_t nWaitSend;
+	struct tcb *send_head;
+	struct tcb *send_tail;
+	int used;
 
 	/* The actual descriptor ring */
-	PTX_DESC_ENTRY_t pTxDescRingVa;
-	dma_addr_t pTxDescRingPa;
-	uint64_t pTxDescRingAdjustedPa;
-	uint64_t TxDescOffset;
+	struct tx_desc *tx_desc_ring;
+	dma_addr_t tx_desc_ring_pa;
 
-	/* ReadyToSend indicates where we last wrote to in the descriptor ring. */
-	u32 txDmaReadyToSend;
+	/* send_idx indicates where we last wrote to in the descriptor ring. */
+	u32 send_idx;
 
 	/* The location of the write-back status block */
-	PTX_STATUS_BLOCK_t pTxStatusVa;
-	dma_addr_t pTxStatusPa;
+	u32 *tx_status;
+	dma_addr_t tx_status_pa;
 
-	/* A Block of zeroes used to pad packets that are less than 60 bytes */
-	void *pTxDummyBlkVa;
-	dma_addr_t pTxDummyBlkPa;
-
-	TXMAC_ERR_t TxMacErr;
-
-	/* Variables to track the Tx interrupt coalescing features */
-	int32_t TxPacketsSinceLastinterrupt;
-} TX_RING_t, *PTX_RING_t;
-
-/* Forward declaration of the frag-list for the following prototypes */
-typedef struct _MP_FRAG_LIST MP_FRAG_LIST, *PMP_FRAG_LIST;
+	/* Packets since the last IRQ: used for interrupt coalescing */
+	int since_irq;
+};
 
 /* Forward declaration of the private adapter structure */
 struct et131x_adapter;
@@ -231,12 +153,12 @@
 /* PROTOTYPES for et1310_tx.c */
 int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter);
 void et131x_tx_dma_memory_free(struct et131x_adapter *adapter);
-void ConfigTxDmaRegs(struct et131x_adapter *pAdapter);
+void ConfigTxDmaRegs(struct et131x_adapter *adapter);
 void et131x_init_send(struct et131x_adapter *adapter);
-void et131x_tx_dma_disable(struct et131x_adapter *pAdapter);
-void et131x_tx_dma_enable(struct et131x_adapter *pAdapter);
-void et131x_handle_send_interrupt(struct et131x_adapter *pAdapter);
-void et131x_free_busy_send_packets(struct et131x_adapter *pAdapter);
+void et131x_tx_dma_disable(struct et131x_adapter *adapter);
+void et131x_tx_dma_enable(struct et131x_adapter *adapter);
+void et131x_handle_send_interrupt(struct et131x_adapter *adapter);
+void et131x_free_busy_send_packets(struct et131x_adapter *adapter);
 int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev);
 
 #endif /* __ET1310_TX_H__ */
diff --git a/drivers/staging/et131x/et131x_adapter.h b/drivers/staging/et131x/et131x_adapter.h
index 1dfe06f..3f7f37a 100644
--- a/drivers/staging/et131x/et131x_adapter.h
+++ b/drivers/staging/et131x/et131x_adapter.h
@@ -100,12 +100,6 @@
 #define LO_MARK_PERCENT_FOR_PSR     15
 #define LO_MARK_PERCENT_FOR_RX      15
 
-/* Macros specific to the private adapter structure */
-#define MP_TCB_RESOURCES_AVAILABLE(_M) ((_M)->TxRing.nBusySend < NUM_TCB)
-#define MP_TCB_RESOURCES_NOT_AVAILABLE(_M) ((_M)->TxRing.nBusySend >= NUM_TCB)
-
-#define MP_SHOULD_FAIL_SEND(_M)   ((_M)->Flags & fMP_ADAPTER_FAIL_SEND_MASK)
-
 /* Counters for error rate monitoring */
 typedef struct _MP_ERR_COUNTERS {
 	u32 PktCountTxPackets;
@@ -168,7 +162,7 @@
 	u32 tx_deferred;
 
 	/* Rx Statistics. */
-	u32 rx_ov_flow;	/* Rx Over Flow */
+	u32 rx_ov_flow;	/* Rx Overflow */
 
 	u32 length_err;
 	u32 alignment_err;
@@ -203,7 +197,6 @@
 	spinlock_t TCBSendQLock;
 	spinlock_t TCBReadyQLock;
 	spinlock_t SendHWLock;
-	spinlock_t SendWaitLock;
 
 	spinlock_t RcvLock;
 	spinlock_t RcvPendLock;
@@ -220,9 +213,6 @@
 	u32 MCAddressCount;
 	u8 MCList[NIC_MAX_MCAST_LIST][ETH_ALEN];
 
-	/* MAC test */
-	TXMAC_TXTEST_t TxMacTest;
-
 	/* Pointer to the device's PCI register space */
 	ADDRESS_MAP_t __iomem *regs;
 
@@ -234,9 +224,6 @@
 	u32 RegistryRxMemEnd;	/* Size of internal rx memory */
 	u32 RegistryJumboPacket;	/* Max supported ethernet packet size */
 
-	/* Validation helpers */
-	u8 RegistryNMIDisable;
-	u8 RegistryPhyLoopbk;	/* Enable Phy loopback */
 
 	/* Derived from the registry: */
 	u8 AiForceDpx;		/* duplex setting */
@@ -248,7 +235,6 @@
 		NETIF_STATUS_MEDIA_DISCONNECT,
 		NETIF_STATUS_MAX
 	} MediaState;
-	u8 DriverNoPhyAccess;
 
 	/* Minimize init-time */
 	struct timer_list ErrorTimer;
@@ -259,7 +245,7 @@
 	MI_BMSR_t Bmsr;
 
 	/* Tx Memory Variables */
-	TX_RING_t TxRing;
+	struct tx_ring tx_ring;
 
 	/* Rx Memory Variables */
 	RX_RING_t RxRing;
diff --git a/drivers/staging/et131x/et131x_defs.h b/drivers/staging/et131x/et131x_defs.h
index f98dca5..d81fc77 100644
--- a/drivers/staging/et131x/et131x_defs.h
+++ b/drivers/staging/et131x/et131x_defs.h
@@ -102,7 +102,6 @@
 
 /* Some offsets in PCI config space that are actually used. */
 #define ET1310_PCI_MAX_PYLD		0x4C
-#define ET1310_NMI_DISABLE		0x61
 #define ET1310_PCI_MAC_ADDRESS		0xA4
 #define ET1310_PCI_EEPROM_STATUS	0xB2
 #define ET1310_PCI_ACK_NACK		0xC0
diff --git a/drivers/staging/et131x/et131x_initpci.c b/drivers/staging/et131x/et131x_initpci.c
index 9db2056..0892b6a 100644
--- a/drivers/staging/et131x/et131x_initpci.c
+++ b/drivers/staging/et131x/et131x_initpci.c
@@ -106,17 +106,6 @@
 #define PARM_SPEED_DUPLEX_MIN   0
 #define PARM_SPEED_DUPLEX_MAX   5
 
-/* Module parameter for disabling NMI
- * et131x_nmi_disable :
- * Disable NMI (0-2) [0]
- *  0 :
- *  1 :
- *  2 :
- */
-static u32 et131x_nmi_disable;	/* 0-2 */
-module_param(et131x_nmi_disable, uint, 0);
-MODULE_PARM_DESC(et131x_nmi_disable, "Disable NMI (0-2) [0]");
-
 /* Module parameter for manual speed setting
  * Set Link speed and dublex manually (0-5)  [0]
  *  1 : 10Mb   Half-Duplex
@@ -132,128 +121,88 @@
 		"Set Link speed and dublex manually (0-5)  [0] \n  1 : 10Mb   Half-Duplex \n  2 : 10Mb   Full-Duplex \n  3 : 100Mb  Half-Duplex \n  4 : 100Mb  Full-Duplex \n  5 : 1000Mb Full-Duplex \n 0 : Auto Speed Auto Dublex");
 
 /**
- * et131x_find_adapter - Find the adapter and get all the assigned resources
+ * et131x_hwaddr_init - set up the MAC Address on the ET1310
  * @adapter: pointer to our private adapter structure
- *
- * Returns 0 on success, errno on failure (as defined in errno.h)
  */
-int et131x_find_adapter(struct et131x_adapter *adapter, struct pci_dev *pdev)
+void et131x_hwaddr_init(struct et131x_adapter *adapter)
 {
-	int result;
-	uint8_t eepromStat;
-	uint8_t maxPayload = 0;
-	uint8_t read_size_reg;
-	u8 rev;
-
-	/* Allow disabling of Non-Maskable Interrupts in I/O space, to
-	 * support validation.
+	/* If have our default mac from init and no mac address from
+	 * EEPROM then we need to generate the last octet and set it on the
+	 * device
 	 */
-	if (adapter->RegistryNMIDisable) {
-		uint8_t RegisterVal;
-
-		RegisterVal = inb(ET1310_NMI_DISABLE);
-		RegisterVal &= 0xf3;
-
-		if (adapter->RegistryNMIDisable == 2)
-			RegisterVal |= 0xc;
-
-		outb(ET1310_NMI_DISABLE, RegisterVal);
-	}
-
-	/* We first need to check the EEPROM Status code located at offset
-	 * 0xB2 of config space
-	 */
-	result = pci_read_config_byte(pdev, ET1310_PCI_EEPROM_STATUS,
-				      &eepromStat);
-
-	/* THIS IS A WORKAROUND:
-	 * I need to call this function twice to get my card in a
-	 * LG M1 Express Dual running. I tried also a msleep before this
-	 * function, because I thougth there could be some time condidions
-	 * but it didn't work. Call the whole function twice also work.
-	 */
-	result = pci_read_config_byte(pdev, ET1310_PCI_EEPROM_STATUS,
-				      &eepromStat);
-	if (result != PCIBIOS_SUCCESSFUL) {
-		dev_err(&pdev->dev, "Could not read PCI config space for "
-			  "EEPROM Status\n");
-		return -EIO;
-	}
-
-	/* Determine if the error(s) we care about are present.  If they are
-	 * present, we need to fail.
-	 */
-	if (eepromStat & 0x4C) {
-		result = pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
-		if (result != PCIBIOS_SUCCESSFUL) {
-			dev_err(&pdev->dev,
-				  "Could not read PCI config space for "
-				  "Revision ID\n");
-			return -EIO;
-		} else if (rev == 0x01) {
-			int32_t nLoop;
-			uint8_t temp[4] = { 0xFE, 0x13, 0x10, 0xFF };
-
-			/* Re-write the first 4 bytes if we have an eeprom
-			 * present and the revision id is 1, this fixes the
-			 * corruption seen with 1310 B Silicon
-			 */
-			for (nLoop = 0; nLoop < 3; nLoop++) {
-				EepromWriteByte(adapter, nLoop, temp[nLoop]);
-			}
-		}
-
-		dev_err(&pdev->dev, "Fatal EEPROM Status Error - 0x%04x\n", eepromStat);
-
-		/* This error could mean that there was an error reading the
-		 * eeprom or that the eeprom doesn't exist.  We will treat
-		 * each case the same and not try to gather additional
-		 * information that normally would come from the eeprom, like
-		 * MAC Address
+	if (adapter->PermanentAddress[0] == 0x00 &&
+	    adapter->PermanentAddress[1] == 0x00 &&
+	    adapter->PermanentAddress[2] == 0x00 &&
+	    adapter->PermanentAddress[3] == 0x00 &&
+	    adapter->PermanentAddress[4] == 0x00 &&
+	    adapter->PermanentAddress[5] == 0x00) {
+		/*
+		 * We need to randomly generate the last octet so we
+		 * decrease our chances of setting the mac address to
+		 * same as another one of our cards in the system
 		 */
-		adapter->has_eeprom = 0;
+		get_random_bytes(&adapter->CurrentAddress[5], 1);
+		/*
+		 * We have the default value in the register we are
+		 * working with so we need to copy the current
+		 * address into the permanent address
+		 */
+		memcpy(adapter->PermanentAddress,
+			adapter->CurrentAddress, ETH_ALEN);
+	} else {
+		/* We do not have an override address, so set the
+		 * current address to the permanent address and add
+		 * it to the device
+		 */
+		memcpy(adapter->CurrentAddress,
+		       adapter->PermanentAddress, ETH_ALEN);
+	}
+}
+
+
+/**
+ * et131x_pci_init	 - initial PCI setup
+ * @adapter: pointer to our private adapter structure
+ * @pdev: our PCI device
+ *
+ * Perform the initial setup of PCI registers and if possible initialise
+ * the MAC address. At this point the I/O registers have yet to be mapped
+ */
+
+static int et131x_pci_init(struct et131x_adapter *adapter,
+						struct pci_dev *pdev)
+{
+	int i;
+	u8 max_payload;
+	u8 read_size_reg;
+
+	if (et131x_init_eeprom(adapter) < 0)
 		return -EIO;
-	} else
-		adapter->has_eeprom = 1;
-
-	/* Read the EEPROM for information regarding LED behavior. Refer to
-	 * ET1310_phy.c, et131x_xcvr_init(), for its use.
-	 */
-	EepromReadByte(adapter, 0x70, &adapter->eepromData[0]);
-	EepromReadByte(adapter, 0x71, &adapter->eepromData[1]);
-
-	if (adapter->eepromData[0] != 0xcd)
-		/* Disable all optional features */
-		adapter->eepromData[1] = 0x00;
 
 	/* Let's set up the PORT LOGIC Register.  First we need to know what
 	 * the max_payload_size is
 	 */
-	result = pci_read_config_byte(pdev, ET1310_PCI_MAX_PYLD, &maxPayload);
-	if (result != PCIBIOS_SUCCESSFUL) {
+	if (pci_read_config_byte(pdev, ET1310_PCI_MAX_PYLD, &max_payload)) {
 		dev_err(&pdev->dev,
 		    "Could not read PCI config space for Max Payload Size\n");
 		return -EIO;
 	}
 
 	/* Program the Ack/Nak latency and replay timers */
-	maxPayload &= 0x07;	/* Only the lower 3 bits are valid */
+	max_payload &= 0x07;	/* Only the lower 3 bits are valid */
 
-	if (maxPayload < 2) {
-		const uint16_t AckNak[2] = { 0x76, 0xD0 };
-		const uint16_t Replay[2] = { 0x1E0, 0x2ED };
+	if (max_payload < 2) {
+		static const u16 AckNak[2] = { 0x76, 0xD0 };
+		static const u16 Replay[2] = { 0x1E0, 0x2ED };
 
-		result = pci_write_config_word(pdev, ET1310_PCI_ACK_NACK,
-					       AckNak[maxPayload]);
-		if (result != PCIBIOS_SUCCESSFUL) {
+		if (pci_write_config_word(pdev, ET1310_PCI_ACK_NACK,
+					       AckNak[max_payload])) {
 			dev_err(&pdev->dev,
 			  "Could not write PCI config space for ACK/NAK\n");
 			return -EIO;
 		}
-
-		result = pci_write_config_word(pdev, ET1310_PCI_REPLAY,
-					       Replay[maxPayload]);
-		if (result != PCIBIOS_SUCCESSFUL) {
+		if (pci_write_config_word(pdev, ET1310_PCI_REPLAY,
+					       Replay[max_payload])) {
 			dev_err(&pdev->dev,
 			  "Could not write PCI config space for Replay Timer\n");
 			return -EIO;
@@ -263,16 +212,14 @@
 	/* l0s and l1 latency timers.  We are using default values.
 	 * Representing 001 for L0s and 010 for L1
 	 */
-	result = pci_write_config_byte(pdev, ET1310_PCI_L0L1LATENCY, 0x11);
-	if (result != PCIBIOS_SUCCESSFUL) {
+	if (pci_write_config_byte(pdev, ET1310_PCI_L0L1LATENCY, 0x11)) {
 		dev_err(&pdev->dev,
 		  "Could not write PCI config space for Latency Timers\n");
 		return -EIO;
 	}
 
 	/* Change the max read size to 2k */
-	result = pci_read_config_byte(pdev, 0x51, &read_size_reg);
-	if (result != PCIBIOS_SUCCESSFUL) {
+	if (pci_read_config_byte(pdev, 0x51, &read_size_reg)) {
 		dev_err(&pdev->dev,
 			"Could not read PCI config space for Max read size\n");
 		return -EIO;
@@ -281,8 +228,7 @@
 	read_size_reg &= 0x8f;
 	read_size_reg |= 0x40;
 
-	result = pci_write_config_byte(pdev, 0x51, read_size_reg);
-	if (result != PCIBIOS_SUCCESSFUL) {
+	if (pci_write_config_byte(pdev, 0x51, read_size_reg)) {
 		dev_err(&pdev->dev,
 		      "Could not write PCI config space for Max read size\n");
 		return -EIO;
@@ -291,19 +237,19 @@
 	/* Get MAC address from config space if an eeprom exists, otherwise
 	 * the MAC address there will not be valid
 	 */
-	if (adapter->has_eeprom) {
-		int i;
+	if (!adapter->has_eeprom) {
+		et131x_hwaddr_init(adapter);
+		return 0;
+	}
 
-		for (i = 0; i < ETH_ALEN; i++) {
-			result = pci_read_config_byte(
-					pdev, ET1310_PCI_MAC_ADDRESS + i,
-					adapter->PermanentAddress + i);
-			if (result != PCIBIOS_SUCCESSFUL) {
-				dev_err(&pdev->dev, ";Could not read PCI config space for MAC address\n");
-				return -EIO;
-			}
+	for (i = 0; i < ETH_ALEN; i++) {
+		if (pci_read_config_byte(pdev, ET1310_PCI_MAC_ADDRESS + i,
+					adapter->PermanentAddress + i)) {
+			dev_err(&pdev->dev, "Could not read PCI config space for MAC address\n");
+			return -EIO;
 		}
 	}
+	memcpy(adapter->CurrentAddress, adapter->PermanentAddress, ETH_ALEN);
 	return 0;
 }
 
@@ -383,52 +329,34 @@
 {
 	struct _GLOBAL_t __iomem *regs = &etdev->regs->global;
 
-	if (etdev->RegistryPhyLoopbk == false) {
-		if (etdev->RegistryJumboPacket < 2048) {
-			/* Tx / RxDMA and Tx/Rx MAC interfaces have a 1k word
-			 * block of RAM that the driver can split between Tx
-			 * and Rx as it desires.  Our default is to split it
-			 * 50/50:
-			 */
-			writel(0, &regs->rxq_start_addr);
-			writel(PARM_RX_MEM_END_DEF, &regs->rxq_end_addr);
-			writel(PARM_RX_MEM_END_DEF + 1, &regs->txq_start_addr);
-			writel(INTERNAL_MEM_SIZE - 1, &regs->txq_end_addr);
-		} else if (etdev->RegistryJumboPacket < 8192) {
-			/* For jumbo packets > 2k but < 8k, split 50-50. */
-			writel(0, &regs->rxq_start_addr);
-			writel(INTERNAL_MEM_RX_OFFSET, &regs->rxq_end_addr);
-			writel(INTERNAL_MEM_RX_OFFSET + 1, &regs->txq_start_addr);
-			writel(INTERNAL_MEM_SIZE - 1, &regs->txq_end_addr);
-		} else {
-			/* 9216 is the only packet size greater than 8k that
-			 * is available. The Tx buffer has to be big enough
-			 * for one whole packet on the Tx side. We'll make
-			 * the Tx 9408, and give the rest to Rx
-			 */
-			writel(0x0000, &regs->rxq_start_addr);
-			writel(0x01b3, &regs->rxq_end_addr);
-			writel(0x01b4, &regs->txq_start_addr);
-			writel(INTERNAL_MEM_SIZE - 1,&regs->txq_end_addr);
-		}
+	writel(0, &regs->rxq_start_addr);
+	writel(INTERNAL_MEM_SIZE - 1, &regs->txq_end_addr);
 
-		/* Initialize the loopback register. Disable all loopbacks. */
-		writel(0, &regs->loopback);
-	} else {
-		/* For PHY Line loopback, the memory is configured as if Tx
-		 * and Rx both have all the memory.  This is because the
-		 * RxMAC will write data into the space, and the TxMAC will
-		 * read it out.
+	if (etdev->RegistryJumboPacket < 2048) {
+		/* Tx / RxDMA and Tx/Rx MAC interfaces have a 1k word
+		 * block of RAM that the driver can split between Tx
+		 * and Rx as it desires.  Our default is to split it
+		 * 50/50:
 		 */
-		writel(0, &regs->rxq_start_addr);
-		writel(INTERNAL_MEM_SIZE - 1, &regs->rxq_end_addr);
-		writel(0, &regs->txq_start_addr);
-		writel(INTERNAL_MEM_SIZE - 1, &regs->txq_end_addr);
-
-		/* Initialize the loopback register (MAC loopback). */
-		writel(ET_LOOP_MAC, &regs->loopback);
+		writel(PARM_RX_MEM_END_DEF, &regs->rxq_end_addr);
+		writel(PARM_RX_MEM_END_DEF + 1, &regs->txq_start_addr);
+	} else if (etdev->RegistryJumboPacket < 8192) {
+		/* For jumbo packets > 2k but < 8k, split 50-50. */
+		writel(INTERNAL_MEM_RX_OFFSET, &regs->rxq_end_addr);
+		writel(INTERNAL_MEM_RX_OFFSET + 1, &regs->txq_start_addr);
+	} else {
+		/* 9216 is the only packet size greater than 8k that
+		 * is available. The Tx buffer has to be big enough
+		 * for one whole packet on the Tx side. We'll make
+		 * the Tx 9408, and give the rest to Rx
+		 */
+		writel(0x01b3, &regs->rxq_end_addr);
+		writel(0x01b4, &regs->txq_start_addr);
 	}
 
+	/* Initialize the loopback register. Disable all loopbacks. */
+	writel(0, &regs->loopback);
+
 	/* MSI Register */
 	writel(0, &regs->msi_config);
 
@@ -498,57 +426,18 @@
 }
 
 /**
- * et131x_setup_hardware_properties - set up the MAC Address on the ET1310
- * @adapter: pointer to our private adapter structure
- */
-void et131x_setup_hardware_properties(struct et131x_adapter *adapter)
-{
-	/* If have our default mac from registry and no mac address from
-	 * EEPROM then we need to generate the last octet and set it on the
-	 * device
-	 */
-	if (adapter->PermanentAddress[0] == 0x00 &&
-	    adapter->PermanentAddress[1] == 0x00 &&
-	    adapter->PermanentAddress[2] == 0x00 &&
-	    adapter->PermanentAddress[3] == 0x00 &&
-	    adapter->PermanentAddress[4] == 0x00 &&
-	    adapter->PermanentAddress[5] == 0x00) {
-		/*
-		 * We need to randomly generate the last octet so we
-		 * decrease our chances of setting the mac address to
-		 * same as another one of our cards in the system
-		 */
-		get_random_bytes(&adapter->CurrentAddress[5], 1);
-		/*
-		 * We have the default value in the register we are
-		 * working with so we need to copy the current
-		 * address into the permanent address
-		 */
-		memcpy(adapter->PermanentAddress,
-			adapter->CurrentAddress, ETH_ALEN);
-	} else {
-		/* We do not have an override address, so set the
-		 * current address to the permanent address and add
-		 * it to the device
-		 */
-		memcpy(adapter->CurrentAddress,
-		       adapter->PermanentAddress, ETH_ALEN);
-	}
-}
-
-/**
  * et131x_soft_reset - Issue a soft reset to the hardware, complete for ET1310
  * @adapter: pointer to our private adapter structure
  */
 void et131x_soft_reset(struct et131x_adapter *adapter)
 {
 	/* Disable MAC Core */
-	writel(0xc00f0000, &adapter->regs->mac.cfg1.value);
+	writel(0xc00f0000, &adapter->regs->mac.cfg1);
 
 	/* Set everything to a reset value */
 	writel(0x7F, &adapter->regs->global.sw_reset);
-	writel(0x000f0000, &adapter->regs->mac.cfg1.value);
-	writel(0x00000000, &adapter->regs->mac.cfg1.value);
+	writel(0x000f0000, &adapter->regs->mac.cfg1);
+	writel(0x00000000, &adapter->regs->mac.cfg1);
 }
 
 /**
@@ -588,36 +477,32 @@
  */
 int et131x_adapter_memory_alloc(struct et131x_adapter *adapter)
 {
-	int status = 0;
+	int status;
 
-	do {
-		/* Allocate memory for the Tx Ring */
-		status = et131x_tx_dma_memory_alloc(adapter);
-		if (status != 0) {
-			dev_err(&adapter->pdev->dev,
-				  "et131x_tx_dma_memory_alloc FAILED\n");
-			break;
-		}
+	/* Allocate memory for the Tx Ring */
+	status = et131x_tx_dma_memory_alloc(adapter);
+	if (status != 0) {
+		dev_err(&adapter->pdev->dev,
+			  "et131x_tx_dma_memory_alloc FAILED\n");
+		return status;
+	}
+	/* Receive buffer memory allocation */
+	status = et131x_rx_dma_memory_alloc(adapter);
+	if (status != 0) {
+		dev_err(&adapter->pdev->dev,
+			  "et131x_rx_dma_memory_alloc FAILED\n");
+		et131x_tx_dma_memory_free(adapter);
+		return status;
+	}
 
-		/* Receive buffer memory allocation */
-		status = et131x_rx_dma_memory_alloc(adapter);
-		if (status != 0) {
-			dev_err(&adapter->pdev->dev,
-				  "et131x_rx_dma_memory_alloc FAILED\n");
-			et131x_tx_dma_memory_free(adapter);
-			break;
-		}
-
-		/* Init receive data structures */
-		status = et131x_init_recv(adapter);
-		if (status != 0) {
-			dev_err(&adapter->pdev->dev,
-				"et131x_init_recv FAILED\n");
-			et131x_tx_dma_memory_free(adapter);
-			et131x_rx_dma_memory_free(adapter);
-			break;
-		}
-	} while (0);
+	/* Init receive data structures */
+	status = et131x_init_recv(adapter);
+	if (status != 0) {
+		dev_err(&adapter->pdev->dev,
+			"et131x_init_recv FAILED\n");
+		et131x_tx_dma_memory_free(adapter);
+		et131x_rx_dma_memory_free(adapter);
+	}
 	return status;
 }
 
@@ -632,22 +517,50 @@
 	et131x_rx_dma_memory_free(adapter);
 }
 
+
+
 /**
- * et131x_config_parse
+ * et131x_adapter_init
  * @etdev: pointer to the private adapter struct
+ * @pdev: pointer to the PCI device
  *
- * Parses a configuration from some location (module parameters, for example)
- * into the private adapter struct. This really has no sensible analogy in
- * Linux as sysfs parameters are dynamic. Several things that were hee could
- * go into sysfs, but other stuff like speed handling is part of the mii
- * interfaces/ethtool.
+ * Initialize the data structures for the et131x_adapter object and link
+ * them together with the platform provided device structures.
  */
-void et131x_config_parse(struct et131x_adapter *etdev)
+
+
+static struct et131x_adapter *et131x_adapter_init(struct net_device *netdev,
+		struct pci_dev *pdev)
 {
 	static const u8 default_mac[] = { 0x00, 0x05, 0x3d, 0x00, 0x02, 0x00 };
 	static const u8 duplex[] = { 0, 1, 2, 1, 2, 2 };
 	static const u16 speed[] = { 0, 10, 10, 100, 100, 1000 };
 
+	struct et131x_adapter *etdev;
+
+	/* Setup the fundamental net_device and private adapter structure elements  */
+	SET_NETDEV_DEV(netdev, &pdev->dev);
+
+	/* Allocate private adapter struct and copy in relevant information */
+	etdev = netdev_priv(netdev);
+	etdev->pdev = pci_dev_get(pdev);
+	etdev->netdev = netdev;
+
+	/* Do the same for the netdev struct */
+	netdev->irq = pdev->irq;
+	netdev->base_addr = pci_resource_start(pdev, 0);
+
+	/* Initialize spinlocks here */
+	spin_lock_init(&etdev->Lock);
+	spin_lock_init(&etdev->TCBSendQLock);
+	spin_lock_init(&etdev->TCBReadyQLock);
+	spin_lock_init(&etdev->SendHWLock);
+	spin_lock_init(&etdev->RcvLock);
+	spin_lock_init(&etdev->RcvPendLock);
+	spin_lock_init(&etdev->FbrLock);
+	spin_lock_init(&etdev->PHYLock);
+
+	/* Parse configuration parameters into the private adapter struct */
 	if (et131x_speed_set)
 		dev_info(&etdev->pdev->dev,
 			"Speed set manually to : %d \n", et131x_speed_set);
@@ -655,8 +568,6 @@
 	etdev->SpeedDuplex = et131x_speed_set;
 	etdev->RegistryJumboPacket = 1514;	/* 1514-9216 */
 
-	etdev->RegistryNMIDisable = et131x_nmi_disable;
-
 	/* Set the MAC address to a default */
 	memcpy(etdev->CurrentAddress, default_mac, ETH_ALEN);
 
@@ -674,40 +585,10 @@
 
 	etdev->AiForceSpeed = speed[etdev->SpeedDuplex];
 	etdev->AiForceDpx = duplex[etdev->SpeedDuplex];	/* Auto FDX */
+
+	return etdev;
 }
 
-
-/**
- * et131x_pci_remove
- * @pdev: a pointer to the device's pci_dev structure
- *
- * Registered in the pci_driver structure, this function is called when the
- * PCI subsystem detects that a PCI device which matches the information
- * contained in the pci_device_id table has been removed.
- */
-
-void __devexit et131x_pci_remove(struct pci_dev *pdev)
-{
-	struct net_device *netdev;
-	struct et131x_adapter *adapter;
-
-	/* Retrieve the net_device pointer from the pci_dev struct, as well
-	 * as the private adapter struct
-	 */
-	netdev = (struct net_device *) pci_get_drvdata(pdev);
-	adapter = netdev_priv(netdev);
-
-	/* Perform device cleanup */
-	unregister_netdev(netdev);
-	et131x_adapter_memory_free(adapter);
-	iounmap(adapter->regs);
-	pci_dev_put(adapter->pdev);
-	free_netdev(netdev);
-	pci_release_regions(pdev);
-	pci_disable_device(pdev);
-}
-
-
 /**
  * et131x_pci_setup - Perform device initialization
  * @pdev: a pointer to the device's pci_dev structure
@@ -721,34 +602,31 @@
  * a device insertion routine.
  */
 
-int __devinit et131x_pci_setup(struct pci_dev *pdev,
+static int __devinit et131x_pci_setup(struct pci_dev *pdev,
 			       const struct pci_device_id *ent)
 {
-	int result = 0;
+	int result = -EBUSY;
 	int pm_cap;
 	bool pci_using_dac;
-	struct net_device *netdev = NULL;
-	struct et131x_adapter *adapter = NULL;
+	struct net_device *netdev;
+	struct et131x_adapter *adapter;
 
 	/* Enable the device via the PCI subsystem */
-	result = pci_enable_device(pdev);
-	if (result != 0) {
-		dev_err(&adapter->pdev->dev,
+	if (pci_enable_device(pdev) != 0) {
+		dev_err(&pdev->dev,
 			"pci_enable_device() failed\n");
-		goto out;
+		return -EIO;
 	}
 
 	/* Perform some basic PCI checks */
 	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
-		dev_err(&adapter->pdev->dev,
+		dev_err(&pdev->dev,
 			  "Can't find PCI device's base address\n");
-		result = -ENODEV;
-		goto out;
+		goto err_disable;
 	}
 
-	result = pci_request_regions(pdev, DRIVER_NAME);
-	if (result != 0) {
-		dev_err(&adapter->pdev->dev,
+	if (pci_request_regions(pdev, DRIVER_NAME)) {
+		dev_err(&pdev->dev,
 			"Can't get PCI resources\n");
 		goto err_disable;
 	}
@@ -763,27 +641,26 @@
 	 */
 	pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
 	if (pm_cap == 0) {
-		dev_err(&adapter->pdev->dev,
+		dev_err(&pdev->dev,
 			  "Cannot find Power Management capabilities\n");
 		result = -EIO;
 		goto err_release_res;
 	}
 
 	/* Check the DMA addressing support of this device */
-	if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) {
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
 		pci_using_dac = true;
 
-		result =
-		    pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL);
+		result = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
 		if (result != 0) {
 			dev_err(&pdev->dev,
 				  "Unable to obtain 64 bit DMA for consistent allocations\n");
 			goto err_release_res;
 		}
-	} else if (!pci_set_dma_mask(pdev, 0xffffffffULL)) {
+	} else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
 		pci_using_dac = false;
 	} else {
-		dev_err(&adapter->pdev->dev,
+		dev_err(&pdev->dev,
 			"No usable DMA addressing method\n");
 		result = -EIO;
 		goto err_release_res;
@@ -792,87 +669,22 @@
 	/* Allocate netdev and private adapter structs */
 	netdev = et131x_device_alloc();
 	if (netdev == NULL) {
-		dev_err(&adapter->pdev->dev,
-			"Couldn't alloc netdev struct\n");
+		dev_err(&pdev->dev, "Couldn't alloc netdev struct\n");
 		result = -ENOMEM;
 		goto err_release_res;
 	}
-
-	/* Setup the fundamental net_device and private adapter structure elements  */
-	SET_NETDEV_DEV(netdev, &pdev->dev);
-	/*
-	if (pci_using_dac) {
-		netdev->features |= NETIF_F_HIGHDMA;
-	}
-	*/
-
-	/*
-	 * NOTE - Turn this on when we're ready to deal with SG-DMA
-	 *
-	 * NOTE: According to "Linux Device Drivers", 3rd ed, Rubini et al,
-	 * if checksumming is not performed in HW, then the kernel will not
-	 * use SG.
-	 * From pp 510-511:
-	 *
-	 * "Note that the kernel does not perform scatter/gather I/O to your
-	 * device if it does not also provide some form of checksumming as
-	 * well. The reason is that, if the kernel has to make a pass over a
-	 * fragmented ("nonlinear") packet to calculate the checksum, it
-	 * might as well copy the data and coalesce the packet at the same
-	 * time."
-	 *
-	 * This has been verified by setting the flags below and still not
-	 * receiving a scattered buffer from the network stack, so leave it
-	 * off until checksums are calculated in HW.
-	 */
-	/* netdev->features |= NETIF_F_SG; */
-	/* netdev->features |= NETIF_F_NO_CSUM; */
-	/* netdev->features |= NETIF_F_LLTX; */
-
-	/* Allocate private adapter struct and copy in relevant information */
-	adapter = netdev_priv(netdev);
-	adapter->pdev = pci_dev_get(pdev);
-	adapter->netdev = netdev;
-
-	/* Do the same for the netdev struct */
-	netdev->irq = pdev->irq;
-	netdev->base_addr = pdev->resource[0].start;
-
-	/* Initialize spinlocks here */
-	spin_lock_init(&adapter->Lock);
-	spin_lock_init(&adapter->TCBSendQLock);
-	spin_lock_init(&adapter->TCBReadyQLock);
-	spin_lock_init(&adapter->SendHWLock);
-	spin_lock_init(&adapter->SendWaitLock);
-	spin_lock_init(&adapter->RcvLock);
-	spin_lock_init(&adapter->RcvPendLock);
-	spin_lock_init(&adapter->FbrLock);
-	spin_lock_init(&adapter->PHYLock);
-
-	/* Parse configuration parameters into the private adapter struct */
-	et131x_config_parse(adapter);
-
-	/* Find the physical adapter
-	 *
-	 * NOTE: This is the equivalent of the MpFindAdapter() routine; can we
-	 *       lump it's init with the device specific init below into a
-	 *       single init function?
-	 */
-	/* while (et131x_find_adapter(adapter, pdev) != 0); */
-	et131x_find_adapter(adapter, pdev);
+	adapter = et131x_adapter_init(netdev, pdev);
+	/* Initialise the PCI setup for the device */
+	et131x_pci_init(adapter, pdev);
 
 	/* Map the bus-relative registers to system virtual memory */
-
-	adapter->regs = ioremap_nocache(pci_resource_start(pdev, 0),
-					      pci_resource_len(pdev, 0));
+	adapter->regs = pci_ioremap_bar(pdev, 0);
 	if (adapter->regs == NULL) {
 		dev_err(&pdev->dev, "Cannot map device registers\n");
 		result = -ENOMEM;
 		goto err_free_dev;
 	}
 
-	/* Perform device-specific initialization here (See code below) */
-
 	/* If Phy COMA mode was enabled when we went down, disable it here. */
 	writel(ET_PMCSR_INIT,  &adapter->regs->global.pm_csr);
 
@@ -892,20 +704,12 @@
 	/* Init send data structures */
 	et131x_init_send(adapter);
 
-	/* Register the interrupt
-	 *
-	 * NOTE - This is being done in the open routine, where most other
-	 *         Linux drivers setup IRQ handlers. Make sure device
-	 *         interrupts are not turned on before the IRQ is registered!!
-	 *
-	 *         What we will do here is setup the task structure for the
-	 *         ISR's deferred handler
+	/*
+	 * Set up the task structure for the ISR's deferred handler
 	 */
 	INIT_WORK(&adapter->task, et131x_isr_handler);
 
-	/* Determine MAC Address, and copy into the net_device struct */
-	et131x_setup_hardware_properties(adapter);
-
+	/* Copy address into the net_device struct */
 	memcpy(netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN);
 
 	/* Setup et1310 as per the documentation */
@@ -944,10 +748,7 @@
 	 * been initialized, just in case it needs to be quickly restored.
 	 */
 	pci_set_drvdata(pdev, netdev);
-
 	pci_save_state(adapter->pdev);
-
-out:
 	return result;
 
 err_mem_free:
@@ -961,7 +762,37 @@
 	pci_release_regions(pdev);
 err_disable:
 	pci_disable_device(pdev);
-	goto out;
+	return result;
+}
+
+/**
+ * et131x_pci_remove
+ * @pdev: a pointer to the device's pci_dev structure
+ *
+ * Registered in the pci_driver structure, this function is called when the
+ * PCI subsystem detects that a PCI device which matches the information
+ * contained in the pci_device_id table has been removed.
+ */
+
+static void __devexit et131x_pci_remove(struct pci_dev *pdev)
+{
+	struct net_device *netdev;
+	struct et131x_adapter *adapter;
+
+	/* Retrieve the net_device pointer from the pci_dev struct, as well
+	 * as the private adapter struct
+	 */
+	netdev = (struct net_device *) pci_get_drvdata(pdev);
+	adapter = netdev_priv(netdev);
+
+	/* Perform device cleanup */
+	unregister_netdev(netdev);
+	et131x_adapter_memory_free(adapter);
+	iounmap(adapter->regs);
+	pci_dev_put(adapter->pdev);
+	free_netdev(netdev);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
 }
 
 static struct pci_device_id et131x_pci_table[] __devinitdata = {
@@ -989,7 +820,7 @@
  *
  * Returns 0 on success, errno on failure (as defined in errno.h)
  */
-static int et131x_init_module(void)
+static int __init et131x_init_module(void)
 {
 	if (et131x_speed_set < PARM_SPEED_DUPLEX_MIN ||
 	    et131x_speed_set > PARM_SPEED_DUPLEX_MAX) {
@@ -1002,7 +833,7 @@
 /**
  * et131x_cleanup_module - The entry point called on driver cleanup
  */
-static void et131x_cleanup_module(void)
+static void __exit et131x_cleanup_module(void)
 {
 	pci_unregister_driver(&et131x_driver);
 }
@@ -1010,7 +841,6 @@
 module_init(et131x_init_module);
 module_exit(et131x_cleanup_module);
 
-
 /* Modinfo parameters (filled out using defines from et131x_version.h) */
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_INFO);
diff --git a/drivers/staging/et131x/et131x_initpci.h b/drivers/staging/et131x/et131x_initpci.h
index 8131d6a..7269569 100644
--- a/drivers/staging/et131x/et131x_initpci.h
+++ b/drivers/staging/et131x/et131x_initpci.h
@@ -67,7 +67,7 @@
 int et131x_adapter_setup(struct et131x_adapter *adapter);
 int et131x_adapter_memory_alloc(struct et131x_adapter *adapter);
 void et131x_adapter_memory_free(struct et131x_adapter *adapter);
-void et131x_setup_hardware_properties(struct et131x_adapter *adapter);
+void et131x_hwaddr_init(struct et131x_adapter *adapter);
 void et131x_soft_reset(struct et131x_adapter *adapter);
 
 #endif /* __ET131X_INITPCI_H__ */
diff --git a/drivers/staging/et131x/et131x_isr.c b/drivers/staging/et131x/et131x_isr.c
index f80189d..f6d452d 100644
--- a/drivers/staging/et131x/et131x_isr.c
+++ b/drivers/staging/et131x/et131x_isr.c
@@ -109,9 +109,6 @@
 	else
 		mask = INT_MASK_ENABLE_NO_FLOW;
 
-	if (adapter->DriverNoPhyAccess)
-		mask |= ET_INTR_PHY;
-
 	adapter->CachedMaskValue = mask;
 	writel(mask, &adapter->regs->global.int_mask);
 }
@@ -182,15 +179,15 @@
 	/* This is our interrupt, so process accordingly */
 
 	if (status & ET_INTR_WATCHDOG) {
-		PMP_TCB pMpTcb = adapter->TxRing.CurrSendHead;
+		struct tcb *tcb = adapter->tx_ring.send_head;
 
-		if (pMpTcb)
-			if (++pMpTcb->PacketStaleCount > 1)
+		if (tcb)
+			if (++tcb->stale > 1)
 				status |= ET_INTR_TXDMA_ISR;
 
 		if (adapter->RxRing.UnfinishedReceives)
 			status |= ET_INTR_RXDMA_XFR_DONE;
-		else if (pMpTcb == NULL)
+		else if (tcb == NULL)
 			writel(0, &adapter->regs->global.watchdog_timer);
 
 		status &= ~ET_INTR_WATCHDOG;
@@ -290,17 +287,12 @@
 				u32 pm_csr;
 
 				/* Tell the device to send a pause packet via
-				 * the back pressure register
+				 * the back pressure register (bp req  and
+				 * bp xon/xoff)
 				 */
 				pm_csr = readl(&iomem->global.pm_csr);
-				if ((pm_csr & ET_PM_PHY_SW_COMA) == 0) {
-					TXMAC_BP_CTRL_t bp_ctrl = { 0 };
-
-					bp_ctrl.bits.bp_req = 1;
-					bp_ctrl.bits.bp_xonxoff = 1;
-					writel(bp_ctrl.value,
-					       &iomem->txmac.bp_ctrl.value);
-				}
+				if ((pm_csr & ET_PM_PHY_SW_COMA) == 0)
+					writel(3, &iomem->txmac.bp_ctrl);
 			}
 		}
 
@@ -340,11 +332,9 @@
 			 */
 			/* TRAP();*/
 
-			etdev->TxMacTest.value =
-				readl(&iomem->txmac.tx_test.value);
 			dev_warn(&etdev->pdev->dev,
 				    "RxDMA_ERR interrupt, error %x\n",
-				    etdev->TxMacTest.value);
+				    readl(&iomem->txmac.tx_test));
 		}
 
 		/* Handle the Wake on LAN Event */
@@ -400,8 +390,7 @@
 
 		/* Let's move on to the TxMac */
 		if (status & ET_INTR_TXMAC) {
-			etdev->TxRing.TxMacErr.value =
-				readl(&iomem->txmac.err.value);
+			u32 err = readl(&iomem->txmac.err.value);
 
 			/*
 			 * When any of the errors occur and TXMAC generates
@@ -415,7 +404,7 @@
 			 */
 			dev_warn(&etdev->pdev->dev,
 				    "TXMAC interrupt, error 0x%08x\n",
-				    etdev->TxRing.TxMacErr.value);
+				    err);
 
 			/* If we are debugging, we want to see this error,
 			 * otherwise we just want the device to be reset and
diff --git a/drivers/staging/et131x/et131x_netdev.c b/drivers/staging/et131x/et131x_netdev.c
index 8c7612f..24d97b4 100644
--- a/drivers/staging/et131x/et131x_netdev.c
+++ b/drivers/staging/et131x/et131x_netdev.c
@@ -519,7 +519,7 @@
 void et131x_tx_timeout(struct net_device *netdev)
 {
 	struct et131x_adapter *etdev = netdev_priv(netdev);
-	PMP_TCB pMpTcb;
+	struct tcb *tcb;
 	unsigned long flags;
 
 	/* Just skip this part if the adapter is doing link detection */
@@ -541,28 +541,19 @@
 	/* Is send stuck? */
 	spin_lock_irqsave(&etdev->TCBSendQLock, flags);
 
-	pMpTcb = etdev->TxRing.CurrSendHead;
+	tcb = etdev->tx_ring.send_head;
 
-	if (pMpTcb != NULL) {
-		pMpTcb->Count++;
+	if (tcb != NULL) {
+		tcb->count++;
 
-		if (pMpTcb->Count > NIC_SEND_HANG_THRESHOLD) {
-			TX_DESC_ENTRY_t StuckDescriptors[10];
-
-			if (INDEX10(pMpTcb->WrIndex) > 7) {
-				memcpy(StuckDescriptors,
-				       etdev->TxRing.pTxDescRingVa +
-				       INDEX10(pMpTcb->WrIndex) - 6,
-				       sizeof(TX_DESC_ENTRY_t) * 10);
-			}
-
+		if (tcb->count > NIC_SEND_HANG_THRESHOLD) {
 			spin_unlock_irqrestore(&etdev->TCBSendQLock,
 					       flags);
 
 			dev_warn(&etdev->pdev->dev,
-				"Send stuck - reset.  pMpTcb->WrIndex %x, Flags 0x%08x\n",
-				pMpTcb->WrIndex,
-				pMpTcb->Flags);
+				"Send stuck - reset.  tcb->WrIndex %x, Flags 0x%08x\n",
+				tcb->index,
+				tcb->flags);
 
 			et131x_close(netdev);
 			et131x_open(netdev);
@@ -622,7 +613,7 @@
 
 	et131x_init_send(adapter);
 
-	et131x_setup_hardware_properties(adapter);
+	et131x_hwaddr_init(adapter);
 	memcpy(netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN);
 
 	/* Init the device with the new settings */
@@ -709,9 +700,7 @@
 
 	et131x_init_send(adapter);
 
-	et131x_setup_hardware_properties(adapter);
-	/* memcpy( netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN ); */
-	/* blux: no, do not override our nice address */
+	et131x_hwaddr_init(adapter);
 
 	/* Init the device with the new settings */
 	et131x_adapter_setup(adapter);
diff --git a/drivers/staging/go7007/Makefile b/drivers/staging/go7007/Makefile
index 1301caa..d37b7ed 100644
--- a/drivers/staging/go7007/Makefile
+++ b/drivers/staging/go7007/Makefile
@@ -5,7 +5,7 @@
 
 obj-$(CONFIG_VIDEO_GO7007) += go7007.o
 obj-$(CONFIG_VIDEO_GO7007_USB) += go7007-usb.o
-obj-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD) += s2250.o
+obj-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD) += s2250.o s2250-loader.o
 obj-$(CONFIG_VIDEO_GO7007_SAA7113) += wis-saa7113.o
 obj-$(CONFIG_VIDEO_GO7007_OV7640) += wis-ov7640.o
 obj-$(CONFIG_VIDEO_GO7007_SAA7115) += wis-saa7115.o
@@ -17,7 +17,7 @@
 go7007-objs += go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o \
 		snd-go7007.o
 
-s2250-objs += s2250-board.o s2250-loader.o
+s2250-objs += s2250-board.o
 
 # Uncomment when the saa7134 patches get into upstream
 #ifneq ($(CONFIG_VIDEO_SAA7134),)
diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/go7007/go7007-driver.c
index 472f4bb..fb1345f 100644
--- a/drivers/staging/go7007/go7007-driver.c
+++ b/drivers/staging/go7007/go7007-driver.c
@@ -49,7 +49,7 @@
 	go->hpi_ops->read_interrupt(go);
 	if (wait_event_timeout(go->interrupt_waitq,
 				go->interrupt_available, 5*HZ) < 0) {
-		v4l2_err(go->video_dev, "timeout waiting for read interrupt\n");
+		v4l2_err(&go->v4l2_dev, "timeout waiting for read interrupt\n");
 		return -1;
 	}
 	if (!go->interrupt_available)
@@ -193,7 +193,8 @@
 static int init_i2c_module(struct i2c_adapter *adapter, const char *type,
 			   int id, int addr)
 {
-	struct i2c_board_info info;
+	struct go7007 *go = i2c_get_adapdata(adapter);
+	struct v4l2_device *v4l2_dev = &go->v4l2_dev;
 	char *modname;
 
 	switch (id) {
@@ -219,20 +220,16 @@
 		modname = "wis-ov7640";
 		break;
 	case I2C_DRIVERID_S2250:
-		modname = "s2250-board";
+		modname = "s2250";
 		break;
 	default:
 		modname = NULL;
 		break;
 	}
-	if (modname != NULL)
-		request_module(modname);
 
-	memset(&info, 0, sizeof(struct i2c_board_info));
-	info.addr = addr;
-	strlcpy(info.type, type, I2C_NAME_SIZE);
-	if (!i2c_new_device(adapter, &info))
+	if (v4l2_i2c_new_subdev(v4l2_dev, adapter, modname, type, addr, NULL))
 		return 0;
+
 	if (modname != NULL)
 		printk(KERN_INFO
 			"go7007: probing for module %s failed\n", modname);
@@ -262,6 +259,11 @@
 	if (ret < 0)
 		return -1;
 
+	/* v4l2 init must happen before i2c subdevs */
+	ret = go7007_v4l2_init(go);
+	if (ret < 0)
+		return ret;
+
 	if (!go->i2c_adapter_online &&
 			go->board_info->flags & GO7007_BOARD_USE_ONBOARD_I2C) {
 		if (go7007_i2c_init(go) < 0)
@@ -282,7 +284,7 @@
 		go->audio_enabled = 1;
 		go7007_snd_init(go);
 	}
-	return go7007_v4l2_init(go);
+	return 0;
 }
 EXPORT_SYMBOL(go7007_register_encoder);
 
@@ -315,7 +317,7 @@
 
 	if (go7007_send_firmware(go, fw, fw_len) < 0 ||
 			go7007_read_interrupt(go, &intr_val, &intr_data) < 0) {
-		v4l2_err(go->video_dev, "error transferring firmware\n");
+		v4l2_err(&go->v4l2_dev, "error transferring firmware\n");
 		rv = -1;
 		goto start_error;
 	}
@@ -324,7 +326,7 @@
 	go->parse_length = 0;
 	go->seen_frame = 0;
 	if (go7007_stream_start(go) < 0) {
-		v4l2_err(go->video_dev, "error starting stream transfer\n");
+		v4l2_err(&go->v4l2_dev, "error starting stream transfer\n");
 		rv = -1;
 		goto start_error;
 	}
@@ -420,7 +422,7 @@
 	for (i = 0; i < length; ++i) {
 		if (go->active_buf != NULL &&
 			    go->active_buf->bytesused >= GO7007_BUF_SIZE - 3) {
-			v4l2_info(go->video_dev, "dropping oversized frame\n");
+			v4l2_info(&go->v4l2_dev, "dropping oversized frame\n");
 			go->active_buf->offset -= go->active_buf->bytesused;
 			go->active_buf->bytesused = 0;
 			go->active_buf->modet_active = 0;
@@ -668,7 +670,7 @@
 		if (i2c_del_adapter(&go->i2c_adapter) == 0)
 			go->i2c_adapter_online = 0;
 		else
-			v4l2_err(go->video_dev,
+			v4l2_err(&go->v4l2_dev,
 				"error removing I2C adapter!\n");
 	}
 
diff --git a/drivers/staging/go7007/go7007-priv.h b/drivers/staging/go7007/go7007-priv.h
index ce9307e..b58c394 100644
--- a/drivers/staging/go7007/go7007-priv.h
+++ b/drivers/staging/go7007/go7007-priv.h
@@ -21,6 +21,8 @@
  * user-space applications.
  */
 
+#include <media/v4l2-device.h>
+
 struct go7007;
 
 /* IDs to activate board-specific support code */
@@ -167,6 +169,7 @@
 	int channel_number; /* for multi-channel boards like Adlink PCI-MPG24 */
 	char name[64];
 	struct video_device *video_dev;
+	struct v4l2_device v4l2_dev;
 	int ref_count;
 	enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status;
 	spinlock_t spinlock;
@@ -240,6 +243,11 @@
 	unsigned short interrupt_data;
 };
 
+static inline struct go7007 *to_go7007(struct v4l2_device *v4l2_dev)
+{
+	return container_of(v4l2_dev, struct go7007, v4l2_dev);
+}
+
 /* All of these must be called with the hpi_lock mutex held! */
 #define go7007_interface_reset(go) \
 			((go)->hpi_ops->interface_reset(go))
diff --git a/drivers/staging/go7007/go7007-usb.c b/drivers/staging/go7007/go7007-usb.c
index ecaa3c9..1e89dc0 100644
--- a/drivers/staging/go7007/go7007-usb.c
+++ b/drivers/staging/go7007/go7007-usb.c
@@ -425,7 +425,7 @@
 		.num_i2c_devs	 = 1,
 		.i2c_devs	 = {
 			{
-				.type	= "s2250_board",
+				.type	= "s2250",
 				.id	= I2C_DRIVERID_S2250,
 				.addr	= 0x43,
 			},
@@ -1057,7 +1057,7 @@
 			usb_rcvintpipe(usb->usbdev, 4),
 			usb->intr_urb->transfer_buffer, 2*sizeof(u16),
 			go7007_usb_readinterrupt_complete, go, 8);
-	usb_set_intfdata(intf, go);
+	usb_set_intfdata(intf, &go->v4l2_dev);
 
 	/* Boot the GO7007 */
 	if (go7007_boot_encoder(go, go->board_info->flags &
@@ -1233,7 +1233,7 @@
 
 static void go7007_usb_disconnect(struct usb_interface *intf)
 {
-	struct go7007 *go = usb_get_intfdata(intf);
+	struct go7007 *go = to_go7007(usb_get_intfdata(intf));
 	struct go7007_usb *usb = go->hpi_context;
 	struct urb *vurb, *aurb;
 	int i;
diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/go7007/go7007-v4l2.c
index 4bd353a..b18d8e2 100644
--- a/drivers/staging/go7007/go7007-v4l2.c
+++ b/drivers/staging/go7007/go7007-v4l2.c
@@ -29,6 +29,7 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-subdev.h>
 #include <linux/i2c.h>
 #include <linux/mutex.h>
 #include <linux/uaccess.h>
@@ -46,6 +47,9 @@
 #define	V4L2_MPEG_VIDEO_ENCODING_MPEG_4   3
 #endif
 
+#define call_all(dev, o, f, args...) \
+	v4l2_device_call_until_err(dev, 0, o, f, ##args)
+
 static void deactivate_buffer(struct go7007_buffer *gobuf)
 {
 	int i;
@@ -247,19 +251,23 @@
 		go->modet_map[i] = 0;
 
 	if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
-		struct video_decoder_resolution res;
+		struct v4l2_format res;
 
-		res.width = width;
+		if (fmt != NULL) {
+			res = *fmt;
+		} else {
+			res.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+			res.fmt.pix.width = width;
+		}
+
 		if (height > sensor_height / 2) {
-			res.height = height / 2;
+			res.fmt.pix.height = height / 2;
 			go->encoder_v_halve = 0;
 		} else {
-			res.height = height;
+			res.fmt.pix.height = height;
 			go->encoder_v_halve = 1;
 		}
-		if (go->i2c_adapter_online)
-			i2c_clients_command(&go->i2c_adapter,
-					DECODER_SET_RESOLUTION, &res);
+		call_all(&go->v4l2_dev, video, s_fmt, &res);
 	} else {
 		if (width <= sensor_width / 4) {
 			go->encoder_h_halve = 1;
@@ -385,7 +393,7 @@
 }
 #endif
 
-static int mpeg_queryctrl(struct v4l2_queryctrl *ctrl)
+static int mpeg_query_ctrl(struct v4l2_queryctrl *ctrl)
 {
 	static const u32 mpeg_ctrls[] = {
 		V4L2_CID_MPEG_CLASS,
@@ -973,51 +981,35 @@
 			   struct v4l2_queryctrl *query)
 {
 	struct go7007 *go = ((struct go7007_file *) priv)->go;
+	int id = query->id;
 
-	if (!go->i2c_adapter_online)
-		return -EIO;
+	if (0 == call_all(&go->v4l2_dev, core, queryctrl, query))
+		return 0;
 
-	i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, query);
-
-	return (!query->name[0]) ? mpeg_queryctrl(query) : 0;
+	query->id = id;
+	return mpeg_query_ctrl(query);
 }
 
 static int vidioc_g_ctrl(struct file *file, void *priv,
 				struct v4l2_control *ctrl)
 {
 	struct go7007 *go = ((struct go7007_file *) priv)->go;
-	struct v4l2_queryctrl query;
 
-	if (!go->i2c_adapter_online)
-		return -EIO;
+	if (0 == call_all(&go->v4l2_dev, core, g_ctrl, ctrl))
+		return 0;
 
-	memset(&query, 0, sizeof(query));
-	query.id = ctrl->id;
-	i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
-	if (query.name[0] == 0)
-		return mpeg_g_ctrl(ctrl, go);
-	i2c_clients_command(&go->i2c_adapter, VIDIOC_G_CTRL, ctrl);
-
-	return 0;
+	return mpeg_g_ctrl(ctrl, go);
 }
 
 static int vidioc_s_ctrl(struct file *file, void *priv,
 				struct v4l2_control *ctrl)
 {
 	struct go7007 *go = ((struct go7007_file *) priv)->go;
-	struct v4l2_queryctrl query;
 
-	if (!go->i2c_adapter_online)
-		return -EIO;
+	if (0 == call_all(&go->v4l2_dev, core, s_ctrl, ctrl))
+		return 0;
 
-	memset(&query, 0, sizeof(query));
-	query.id = ctrl->id;
-	i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
-	if (query.name[0] == 0)
-		return mpeg_s_ctrl(ctrl, go);
-	i2c_clients_command(&go->i2c_adapter, VIDIOC_S_CTRL, ctrl);
-
-	return 0;
+	return mpeg_s_ctrl(ctrl, go);
 }
 
 static int vidioc_g_parm(struct file *filp, void *priv,
@@ -1135,8 +1127,7 @@
 	if (go->streaming)
 		return -EBUSY;
 
-	if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV) &&
-			*std != 0)
+	if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV) && *std != 0)
 		return -EINVAL;
 
 	if (*std == 0)
@@ -1146,9 +1137,7 @@
 			go->input == go->board_info->num_inputs - 1) {
 		if (!go->i2c_adapter_online)
 			return -EIO;
-		i2c_clients_command(&go->i2c_adapter,
-					VIDIOC_S_STD, std);
-		if (!*std) /* hack to indicate EINVAL from tuner */
+		if (call_all(&go->v4l2_dev, core, s_std, *std) < 0)
 			return -EINVAL;
 	}
 
@@ -1164,9 +1153,7 @@
 	} else
 		return -EINVAL;
 
-	if (go->i2c_adapter_online)
-		i2c_clients_command(&go->i2c_adapter,
-					VIDIOC_S_STD, std);
+	call_all(&go->v4l2_dev, core, s_std, *std);
 	set_capture_size(go, NULL, 0);
 
 	return 0;
@@ -1180,7 +1167,7 @@
 			go->input == go->board_info->num_inputs - 1) {
 		if (!go->i2c_adapter_online)
 			return -EIO;
-		i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYSTD, std);
+		return call_all(&go->v4l2_dev, video, querystd, std);
 	} else if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
 		*std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
 	else
@@ -1238,14 +1225,8 @@
 		return -EBUSY;
 
 	go->input = input;
-	if (go->i2c_adapter_online) {
-		i2c_clients_command(&go->i2c_adapter, VIDIOC_S_INPUT,
-			&go->board_info->inputs[input].video_input);
-		i2c_clients_command(&go->i2c_adapter, VIDIOC_S_AUDIO,
-			&go->board_info->inputs[input].audio_input);
-	}
 
-	return 0;
+	return call_all(&go->v4l2_dev, video, s_routing, input, 0, 0);
 }
 
 static int vidioc_g_tuner(struct file *file, void *priv,
@@ -1260,10 +1241,7 @@
 	if (!go->i2c_adapter_online)
 		return -EIO;
 
-	i2c_clients_command(&go->i2c_adapter, VIDIOC_G_TUNER, t);
-
-	t->index = 0;
-	return 0;
+	return call_all(&go->v4l2_dev, tuner, g_tuner, t);
 }
 
 static int vidioc_s_tuner(struct file *file, void *priv,
@@ -1287,9 +1265,7 @@
 		break;
 	}
 
-	i2c_clients_command(&go->i2c_adapter, VIDIOC_S_TUNER, t);
-
-	return 0;
+	return call_all(&go->v4l2_dev, tuner, s_tuner, t);
 }
 
 static int vidioc_g_frequency(struct file *file, void *priv,
@@ -1303,8 +1279,8 @@
 		return -EIO;
 
 	f->type = V4L2_TUNER_ANALOG_TV;
-	i2c_clients_command(&go->i2c_adapter, VIDIOC_G_FREQUENCY, f);
-	return 0;
+
+	return call_all(&go->v4l2_dev, tuner, g_frequency, f);
 }
 
 static int vidioc_s_frequency(struct file *file, void *priv,
@@ -1317,9 +1293,7 @@
 	if (!go->i2c_adapter_online)
 		return -EIO;
 
-	i2c_clients_command(&go->i2c_adapter, VIDIOC_S_FREQUENCY, f);
-
-	return 0;
+	return call_all(&go->v4l2_dev, tuner, s_frequency, f);
 }
 
 static int vidioc_cropcap(struct file *file, void *priv,
@@ -1827,7 +1801,7 @@
 	go->video_dev = video_device_alloc();
 	if (go->video_dev == NULL)
 		return -ENOMEM;
-	memcpy(go->video_dev, &go7007_template, sizeof(go7007_template));
+	*go->video_dev = go7007_template;
 	go->video_dev->parent = go->dev;
 	rv = video_register_device(go->video_dev, VFL_TYPE_GRABBER, -1);
 	if (rv < 0) {
@@ -1835,6 +1809,12 @@
 		go->video_dev = NULL;
 		return rv;
 	}
+	rv = v4l2_device_register(go->dev, &go->v4l2_dev);
+	if (rv < 0) {
+		video_device_release(go->video_dev);
+		go->video_dev = NULL;
+		return rv;
+	}
 	video_set_drvdata(go->video_dev, go);
 	++go->ref_count;
 	printk(KERN_INFO "%s: registered device video%d [v4l2]\n",
@@ -1858,4 +1838,5 @@
 	mutex_unlock(&go->hw_lock);
 	if (go->video_dev)
 		video_unregister_device(go->video_dev);
+	v4l2_device_unregister(&go->v4l2_dev);
 }
diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/go7007/s2250-board.c
index f4a6541..8cf7f27 100644
--- a/drivers/staging/go7007/s2250-board.c
+++ b/drivers/staging/go7007/s2250-board.c
@@ -20,10 +20,14 @@
 #include <linux/usb.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
+#include <media/v4l2-device.h>
 #include <media/v4l2-common.h>
-#include "s2250-loader.h"
+#include <media/v4l2-i2c-drv.h>
+#include <media/v4l2-subdev.h>
 #include "go7007-priv.h"
-#include "wis-i2c.h"
+
+MODULE_DESCRIPTION("Sensoray 2250/2251 i2c v4l2 subdev driver");
+MODULE_LICENSE("GPL v2");
 
 #define TLV320_ADDRESS      0x34
 #define VPX322_ADDR_ANALOGCONTROL1	0x02
@@ -112,6 +116,7 @@
 };
 
 struct s2250 {
+	struct v4l2_subdev sd;
 	v4l2_std_id std;
 	int input;
 	int brightness;
@@ -123,6 +128,11 @@
 	struct i2c_client *audio;
 };
 
+static inline struct s2250 *to_state(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct s2250, sd);
+}
+
 /* from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/
 static int go7007_usb_vendor_request(struct go7007 *go, u16 request,
 	u16 value, u16 index, void *transfer_buffer, int length, int in)
@@ -306,253 +316,262 @@
 }
 
 
-static int s2250_command(struct i2c_client *client,
-			 unsigned int cmd, void *arg)
+/* ------------------------------------------------------------------------- */
+
+static int s2250_s_video_routing(struct v4l2_subdev *sd, u32 input, u32 output,
+				 u32 config)
 {
-	struct s2250 *dec = i2c_get_clientdata(client);
+	struct s2250 *state = to_state(sd);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int vidsys;
 
-	switch (cmd) {
-	case VIDIOC_S_INPUT:
-	{
-		int vidsys;
-		int *input = arg;
+	vidsys = (state->std == V4L2_STD_NTSC) ? 0x01 : 0x00;
+	if (input == 0) {
+		/* composite */
+		write_reg_fp(client, 0x20, 0x020 | vidsys);
+		write_reg_fp(client, 0x21, 0x662);
+		write_reg_fp(client, 0x140, 0x060);
+	} else if (input == 1) {
+		/* S-Video */
+		write_reg_fp(client, 0x20, 0x040 | vidsys);
+		write_reg_fp(client, 0x21, 0x666);
+		write_reg_fp(client, 0x140, 0x060);
+	} else {
+		return -EINVAL;
+	}
+	state->input = input;
+	return 0;
+}
 
-		vidsys = (dec->std == V4L2_STD_NTSC) ? 0x01 : 0x00;
-		if (*input == 0) {
-			/* composite */
-			write_reg_fp(client, 0x20, 0x020 | vidsys);
-			write_reg_fp(client, 0x21, 0x662);
-			write_reg_fp(client, 0x140, 0x060);
-		} else {
-			/* S-Video */
-			write_reg_fp(client, 0x20, 0x040 | vidsys);
-			write_reg_fp(client, 0x21, 0x666);
-			write_reg_fp(client, 0x140, 0x060);
-		}
-		dec->input = *input;
+static int s2250_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
+{
+	struct s2250 *state = to_state(sd);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	u16 vidsource;
+
+	vidsource = (state->input == 1) ? 0x040 : 0x020;
+	switch (norm) {
+	case V4L2_STD_NTSC:
+		write_regs_fp(client, vid_regs_fp);
+		write_reg_fp(client, 0x20, vidsource | 1);
 		break;
-	}
-	case VIDIOC_S_STD:
-	{
-		v4l2_std_id *std = arg;
-		u16 vidsource;
-
-		vidsource = (dec->input == 1) ? 0x040 : 0x020;
-		dec->std = *std;
-		switch (dec->std) {
-		case V4L2_STD_NTSC:
-			write_regs_fp(client, vid_regs_fp);
-			write_reg_fp(client, 0x20, vidsource | 1);
-			break;
-		case V4L2_STD_PAL:
-			write_regs_fp(client, vid_regs_fp);
-			write_regs_fp(client, vid_regs_fp_pal);
-			write_reg_fp(client, 0x20, vidsource);
-			break;
-		default:
-			return -EINVAL;
-		}
+	case V4L2_STD_PAL:
+		write_regs_fp(client, vid_regs_fp);
+		write_regs_fp(client, vid_regs_fp_pal);
+		write_reg_fp(client, 0x20, vidsource);
 		break;
-	}
-	case VIDIOC_QUERYCTRL:
-	{
-		struct v4l2_queryctrl *ctrl = arg;
-		static const u32 user_ctrls[] = {
-			V4L2_CID_BRIGHTNESS,
-			V4L2_CID_CONTRAST,
-			V4L2_CID_SATURATION,
-			V4L2_CID_HUE,
-			0
-		};
-		static const u32 *ctrl_classes[] = {
-			user_ctrls,
-			NULL
-		};
-
-		ctrl->id = v4l2_ctrl_next(ctrl_classes, ctrl->id);
-		switch (ctrl->id) {
-		case V4L2_CID_BRIGHTNESS:
-			v4l2_ctrl_query_fill(ctrl, 0, 100, 1, 50);
-			break;
-		case V4L2_CID_CONTRAST:
-			v4l2_ctrl_query_fill(ctrl, 0, 100, 1, 50);
-			break;
-		case V4L2_CID_SATURATION:
-			v4l2_ctrl_query_fill(ctrl, 0, 100, 1, 50);
-			break;
-		case V4L2_CID_HUE:
-			v4l2_ctrl_query_fill(ctrl, -50, 50, 1, 0);
-			break;
-		default:
-			ctrl->name[0] = '\0';
-			return -EINVAL;
-		}
-		break;
-	}
-	case VIDIOC_S_CTRL:
-	{
-		struct v4l2_control *ctrl = arg;
-		int value1;
-		u16 oldvalue;
-
-		switch (ctrl->id) {
-		case V4L2_CID_BRIGHTNESS:
-			if (ctrl->value > 100)
-				dec->brightness = 100;
-			else if (ctrl->value < 0)
-				dec->brightness = 0;
-			else
-				dec->brightness = ctrl->value;
-			value1 = (dec->brightness - 50) * 255 / 100;
-			read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue);
-			write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0,
-				     value1 | (oldvalue & ~0xff));
-			read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue);
-			write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1,
-				     value1 | (oldvalue & ~0xff));
-			write_reg_fp(client, 0x140, 0x60);
-			break;
-		case V4L2_CID_CONTRAST:
-			if (ctrl->value > 100)
-				dec->contrast = 100;
-			else if (ctrl->value < 0)
-				dec->contrast = 0;
-			else
-				dec->contrast = ctrl->value;
-			value1 = dec->contrast * 0x40 / 100;
-			if (value1 > 0x3f)
-				value1 = 0x3f; /* max */
-			read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue);
-			write_reg_fp(client, VPX322_ADDR_CONTRAST0,
-				     value1 | (oldvalue & ~0x3f));
-			read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue);
-			write_reg_fp(client, VPX322_ADDR_CONTRAST1,
-				     value1 | (oldvalue & ~0x3f));
-			write_reg_fp(client, 0x140, 0x60);
-			break;
-		case V4L2_CID_SATURATION:
-			if (ctrl->value > 127)
-				dec->saturation = 127;
-			else if (ctrl->value < 0)
-				dec->saturation = 0;
-			else
-				dec->saturation = ctrl->value;
-
-			value1 = dec->saturation * 4140 / 100;
-			if (value1 > 4094)
-				value1 = 4094;
-			write_reg_fp(client, VPX322_ADDR_SAT, value1);
-			break;
-		case V4L2_CID_HUE:
-			if (ctrl->value > 50)
-				dec->hue = 50;
-			else if (ctrl->value < -50)
-				dec->hue = -50;
-			else
-				dec->hue = ctrl->value;
-			/* clamp the hue range */
-			value1 = dec->hue * 280 / 50;
-			write_reg_fp(client, VPX322_ADDR_HUE, value1);
-			break;
-		}
-		break;
-	}
-	case VIDIOC_G_CTRL:
-	{
-		struct v4l2_control *ctrl = arg;
-
-		switch (ctrl->id) {
-		case V4L2_CID_BRIGHTNESS:
-			ctrl->value = dec->brightness;
-			break;
-		case V4L2_CID_CONTRAST:
-			ctrl->value = dec->contrast;
-			break;
-		case V4L2_CID_SATURATION:
-			ctrl->value = dec->saturation;
-			break;
-		case V4L2_CID_HUE:
-			ctrl->value = dec->hue;
-			break;
-		}
-		break;
-	}
-	case VIDIOC_S_FMT:
-	{
-		struct v4l2_format *fmt = arg;
-		if (fmt->fmt.pix.height < 640) {
-			write_reg_fp(client, 0x12b, dec->reg12b_val | 0x400);
-			write_reg_fp(client, 0x140, 0x060);
-		} else {
-			write_reg_fp(client, 0x12b, dec->reg12b_val & ~0x400);
-			write_reg_fp(client, 0x140, 0x060);
-		}
-		return 0;
-	}
-	case VIDIOC_G_AUDIO:
-	{
-		struct v4l2_audio *audio = arg;
-
-		memset(audio, 0, sizeof(*audio));
-		audio->index = dec->audio_input;
-		/* fall through */
-	}
-	case VIDIOC_ENUMAUDIO:
-	{
-		struct v4l2_audio *audio = arg;
-
-		switch (audio->index) {
-		case 0:
-			strcpy(audio->name, "Line In");
-			break;
-		case 1:
-			strcpy(audio->name, "Mic");
-			break;
-		case 2:
-			strcpy(audio->name, "Mic Boost");
-			break;
-		default:
-			audio->name[0] = '\0';
-			return 0;
-		}
-		audio->capability = V4L2_AUDCAP_STEREO;
-		audio->mode = 0;
-		return 0;
-	}
-	case VIDIOC_S_AUDIO:
-	{
-		struct v4l2_audio *audio = arg;
-
-		switch (audio->index) {
-		case 0:
-			write_reg(dec->audio, 0x08, 0x02); /* Line In */
-			break;
-		case 1:
-			write_reg(dec->audio, 0x08, 0x04); /* Mic */
-			break;
-		case 2:
-			write_reg(dec->audio, 0x08, 0x05); /* Mic Boost */
-			break;
-		default:
-			return -EINVAL;
-		}
-		dec->audio_input = audio->index;
-		return 0;
-	}
-
 	default:
-		printk(KERN_INFO "s2250: unknown command 0x%x\n", cmd);
-		break;
+		return -EINVAL;
+	}
+	state->std = norm;
+	return 0;
+}
+
+static int s2250_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *query)
+{
+	switch (query->id) {
+	case V4L2_CID_BRIGHTNESS:
+		return v4l2_ctrl_query_fill(query, 0, 100, 1, 50);
+	case V4L2_CID_CONTRAST:
+		return v4l2_ctrl_query_fill(query, 0, 100, 1, 50);
+	case V4L2_CID_SATURATION:
+		return v4l2_ctrl_query_fill(query, 0, 100, 1, 50);
+	case V4L2_CID_HUE:
+		return v4l2_ctrl_query_fill(query, -50, 50, 1, 0);
+	default:
+		return -EINVAL;
 	}
 	return 0;
 }
 
+static int s2250_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct s2250 *state = to_state(sd);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int value1;
+	u16 oldvalue;
+
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		if (ctrl->value > 100)
+			state->brightness = 100;
+		else if (ctrl->value < 0)
+			state->brightness = 0;
+		else
+			state->brightness = ctrl->value;
+		value1 = (state->brightness - 50) * 255 / 100;
+		read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue);
+		write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0,
+			     value1 | (oldvalue & ~0xff));
+		read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue);
+		write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1,
+			     value1 | (oldvalue & ~0xff));
+		write_reg_fp(client, 0x140, 0x60);
+		break;
+	case V4L2_CID_CONTRAST:
+		if (ctrl->value > 100)
+			state->contrast = 100;
+		else if (ctrl->value < 0)
+			state->contrast = 0;
+		else
+			state->contrast = ctrl->value;
+		value1 = state->contrast * 0x40 / 100;
+		if (value1 > 0x3f)
+			value1 = 0x3f; /* max */
+		read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue);
+		write_reg_fp(client, VPX322_ADDR_CONTRAST0,
+			     value1 | (oldvalue & ~0x3f));
+		read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue);
+		write_reg_fp(client, VPX322_ADDR_CONTRAST1,
+			     value1 | (oldvalue & ~0x3f));
+		write_reg_fp(client, 0x140, 0x60);
+		break;
+	case V4L2_CID_SATURATION:
+		if (ctrl->value > 100)
+			state->saturation = 100;
+		else if (ctrl->value < 0)
+			state->saturation = 0;
+		else
+			state->saturation = ctrl->value;
+		value1 = state->saturation * 4140 / 100;
+		if (value1 > 4094)
+			value1 = 4094;
+		write_reg_fp(client, VPX322_ADDR_SAT, value1);
+		break;
+	case V4L2_CID_HUE:
+		if (ctrl->value > 50)
+			state->hue = 50;
+		else if (ctrl->value < -50)
+			state->hue = -50;
+		else
+			state->hue = ctrl->value;
+		/* clamp the hue range */
+		value1 = state->hue * 280 / 50;
+		write_reg_fp(client, VPX322_ADDR_HUE, value1);
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int s2250_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct s2250 *state = to_state(sd);
+
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		ctrl->value = state->brightness;
+		break;
+	case V4L2_CID_CONTRAST:
+		ctrl->value = state->contrast;
+		break;
+	case V4L2_CID_SATURATION:
+		ctrl->value = state->saturation;
+		break;
+	case V4L2_CID_HUE:
+		ctrl->value = state->hue;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int s2250_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+	struct s2250 *state = to_state(sd);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	if (fmt->fmt.pix.height < 640) {
+		write_reg_fp(client, 0x12b, state->reg12b_val | 0x400);
+		write_reg_fp(client, 0x140, 0x060);
+	} else {
+		write_reg_fp(client, 0x12b, state->reg12b_val & ~0x400);
+		write_reg_fp(client, 0x140, 0x060);
+	}
+	return 0;
+}
+
+static int s2250_s_audio_routing(struct v4l2_subdev *sd, u32 input, u32 output,
+				 u32 config)
+{
+	struct s2250 *state = to_state(sd);
+
+	switch (input) {
+	case 0:
+		write_reg(state->audio, 0x08, 0x02); /* Line In */
+		break;
+	case 1:
+		write_reg(state->audio, 0x08, 0x04); /* Mic */
+		break;
+	case 2:
+		write_reg(state->audio, 0x08, 0x05); /* Mic Boost */
+		break;
+	default:
+		return -EINVAL;
+	}
+	state->audio_input = input;
+	return 0;
+}
+
+
+static int s2250_log_status(struct v4l2_subdev *sd)
+{
+	struct s2250 *state = to_state(sd);
+
+	v4l2_info(sd, "Standard: %s\n", state->std == V4L2_STD_NTSC ? "NTSC" :
+					state->std == V4L2_STD_PAL ? "PAL" :
+					state->std == V4L2_STD_SECAM ? "SECAM" :
+					"unknown");
+	v4l2_info(sd, "Input: %s\n", state->input == 0 ? "Composite" :
+					state->input == 1 ? "S-video" :
+					"error");
+	v4l2_info(sd, "Brightness: %d\n", state->brightness);
+	v4l2_info(sd, "Contrast: %d\n", state->contrast);
+	v4l2_info(sd, "Saturation: %d\n", state->saturation);
+	v4l2_info(sd, "Hue: %d\n", state->hue);	return 0;
+	v4l2_info(sd, "Audio input: %s\n", state->audio_input == 0 ? "Line In" :
+					state->audio_input == 1 ? "Mic" :
+					state->audio_input == 2 ? "Mic Boost" :
+					"error");
+	return 0;
+}
+
+/* --------------------------------------------------------------------------*/
+
+static const struct v4l2_subdev_core_ops s2250_core_ops = {
+	.log_status = s2250_log_status,
+	.g_ctrl = s2250_g_ctrl,
+	.s_ctrl = s2250_s_ctrl,
+	.queryctrl = s2250_queryctrl,
+	.s_std = s2250_s_std,
+};
+
+static const struct v4l2_subdev_audio_ops s2250_audio_ops = {
+	.s_routing = s2250_s_audio_routing,
+};
+
+static const struct v4l2_subdev_video_ops s2250_video_ops = {
+	.s_routing = s2250_s_video_routing,
+	.s_fmt = s2250_s_fmt,
+};
+
+static const struct v4l2_subdev_ops s2250_ops = {
+	.core = &s2250_core_ops,
+	.audio = &s2250_audio_ops,
+	.video = &s2250_video_ops,
+};
+
+/* --------------------------------------------------------------------------*/
+
 static int s2250_probe(struct i2c_client *client,
 		       const struct i2c_device_id *id)
 {
 	struct i2c_client *audio;
 	struct i2c_adapter *adapter = client->adapter;
-	struct s2250 *dec;
+	struct s2250 *state;
+	struct v4l2_subdev *sd;
 	u8 *data;
 	struct go7007 *go = i2c_get_adapdata(adapter);
 	struct go7007_usb *usb = go->hpi_context;
@@ -561,30 +580,31 @@
 	if (audio == NULL)
 		return -ENOMEM;
 
-	dec = kmalloc(sizeof(struct s2250), GFP_KERNEL);
-	if (dec == NULL) {
+	state = kmalloc(sizeof(struct s2250), GFP_KERNEL);
+	if (state == NULL) {
 		i2c_unregister_device(audio);
 		return -ENOMEM;
 	}
 
-	dec->std = V4L2_STD_NTSC;
-	dec->brightness = 50;
-	dec->contrast = 50;
-	dec->saturation = 50;
-	dec->hue = 0;
-	dec->audio = audio;
-	i2c_set_clientdata(client, dec);
+	sd = &state->sd;
+	v4l2_i2c_subdev_init(sd, client, &s2250_ops);
 
-	printk(KERN_DEBUG
-	       "s2250: initializing video decoder on %s\n",
-	       adapter->name);
+	v4l2_info(sd, "initializing %s at address 0x%x on %s\n",
+	       "Sensoray 2250/2251", client->addr, client->adapter->name);
+
+	state->std = V4L2_STD_NTSC;
+	state->brightness = 50;
+	state->contrast = 50;
+	state->saturation = 50;
+	state->hue = 0;
+	state->audio = audio;
 
 	/* initialize the audio */
 	if (write_regs(audio, aud_regs) < 0) {
 		printk(KERN_ERR
 		       "s2250: error initializing audio\n");
 		i2c_unregister_device(audio);
-		kfree(dec);
+		kfree(state);
 		return 0;
 	}
 
@@ -592,14 +612,14 @@
 		printk(KERN_ERR
 		       "s2250: error initializing decoder\n");
 		i2c_unregister_device(audio);
-		kfree(dec);
+		kfree(state);
 		return 0;
 	}
 	if (write_regs_fp(client, vid_regs_fp) < 0) {
 		printk(KERN_ERR
 		       "s2250: error initializing decoder\n");
 		i2c_unregister_device(audio);
-		kfree(dec);
+		kfree(state);
 		return 0;
 	}
 	/* set default channel */
@@ -609,7 +629,7 @@
 	write_reg_fp(client, 0x140, 0x060);
 
 	/* set default audio input */
-	dec->audio_input = 0;
+	state->audio_input = 0;
 	write_reg(client, 0x08, 0x02); /* Line In */
 
 	if (mutex_lock_interruptible(&usb->i2c_lock) == 0) {
@@ -634,60 +654,28 @@
 		mutex_unlock(&usb->i2c_lock);
 	}
 
-	printk("s2250: initialized successfully\n");
+	v4l2_info(sd, "initialized successfully\n");
 	return 0;
 }
 
 static int s2250_remove(struct i2c_client *client)
 {
-	struct s2250 *dec = i2c_get_clientdata(client);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
-	i2c_set_clientdata(client, NULL);
-	i2c_unregister_device(dec->audio);
-	kfree(dec);
+	v4l2_device_unregister_subdev(sd);
+	kfree(to_state(sd));
 	return 0;
 }
 
 static struct i2c_device_id s2250_id[] = {
-	{ "s2250_board", 0 },
+	{ "s2250", 0 },
 	{ }
 };
+MODULE_DEVICE_TABLE(i2c, s2250_id);
 
-static struct i2c_driver s2250_driver = {
-	.driver = {
-		.name	= "Sensoray 2250 board driver",
-	},
-	.probe		= s2250_probe,
-	.remove		= s2250_remove,
-	.command	= s2250_command,
-	.id_table	= s2250_id,
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+	.name = "s2250",
+	.probe = s2250_probe,
+	.remove = s2250_remove,
+	.id_table = s2250_id,
 };
-
-static int __init s2250_init(void)
-{
-	int r;
-
-	r = s2250loader_init();
-	if (r < 0)
-		return r;
-
-	r = i2c_add_driver(&s2250_driver);
-	if (r < 0)
-		s2250loader_cleanup();
-
-	return r;
-}
-
-static void __exit s2250_cleanup(void)
-{
-	i2c_del_driver(&s2250_driver);
-
-	s2250loader_cleanup();
-}
-
-module_init(s2250_init);
-module_exit(s2250_cleanup);
-
-MODULE_AUTHOR("");
-MODULE_DESCRIPTION("Board driver for Sensoryray 2250");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/go7007/s2250-loader.c b/drivers/staging/go7007/s2250-loader.c
index d7bf829..c152ab9 100644
--- a/drivers/staging/go7007/s2250-loader.c
+++ b/drivers/staging/go7007/s2250-loader.c
@@ -162,7 +162,7 @@
 	.id_table	= s2250loader_ids,
 };
 
-int s2250loader_init(void)
+static int __init s2250loader_init(void)
 {
 	int r;
 	unsigned i = 0;
@@ -179,11 +179,15 @@
 	printk(KERN_INFO "s2250loader_init: driver registered\n");
 	return 0;
 }
-EXPORT_SYMBOL(s2250loader_init);
+module_init(s2250loader_init);
 
-void s2250loader_cleanup(void)
+static void __exit s2250loader_cleanup(void)
 {
 	printk(KERN_INFO "s2250loader_cleanup\n");
 	usb_deregister(&s2250loader_driver);
 }
-EXPORT_SYMBOL(s2250loader_cleanup);
+module_exit(s2250loader_cleanup);
+
+MODULE_AUTHOR("");
+MODULE_DESCRIPTION("firmware loader for Sensoray 2250/2251");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/hv/hv_api.h b/drivers/staging/hv/hv_api.h
index 251e2d1..9eb818e 100644
--- a/drivers/staging/hv/hv_api.h
+++ b/drivers/staging/hv/hv_api.h
@@ -316,13 +316,13 @@
 
 /*
  * HV_STATUS_VMX_INSTRUCTION_FAILED
- * The requested VMX instruction failed to complete succesfully.
+ * The requested VMX instruction failed to complete successfully.
  */
 #define HV_STATUS_VMX_INSTRUCTION_FAILED		((u16)0x1011)
 
 /*
  * HV_STATUS_VMX_INSTRUCTION_FAILED_WITH_STATUS
- * The requested VMX instruction failed to complete succesfully indicating
+ * The requested VMX instruction failed to complete successfully indicating
  * status.
  */
 #define HV_STATUS_VMX_INSTRUCTION_FAILED_WITH_STATUS	((u16)0x1012)
diff --git a/drivers/staging/iio/Documentation/device.txt b/drivers/staging/iio/Documentation/device.txt
index 6916cd3..69d9570 100644
--- a/drivers/staging/iio/Documentation/device.txt
+++ b/drivers/staging/iio/Documentation/device.txt
@@ -10,7 +10,7 @@
 
 struct iio_dev *indio_dev = iio_allocate_device();
 
-The fill in the following.
+Then fill in the following:
 
 indio_dev->dev.parent
   the struct device associated with the underlying hardware.
@@ -45,5 +45,5 @@
 be registered afterwards (otherwise the whole parentage of devices
 gets confused)
 
-On remove iio_device_unregister(indio_dev) will remove the device from
+On remove, iio_device_unregister(indio_dev) will remove the device from
 the core, and iio_free_device will clean up.
diff --git a/drivers/staging/iio/Documentation/overview.txt b/drivers/staging/iio/Documentation/overview.txt
index 64584ad..e39dfc1 100644
--- a/drivers/staging/iio/Documentation/overview.txt
+++ b/drivers/staging/iio/Documentation/overview.txt
@@ -24,11 +24,12 @@
 * Event chrdevs.  These are similar to input in that they provide a
 route to user space for hardware triggered events. Such events include
 threshold detectors, free-fall detectors and more complex action
-detection.  They events themselves are currently very simple with
+detection.  The events themselves are currently very simple with
 merely an event code and a timestamp.  Any data associated with the
-event must be accessed via polling. Note a given device may have one
-or more event channel.  These events are turned on or off (if possible)
-via sysfs interfaces.
+event must be accessed via polling.
+
+Note: A given device may have one or more event channel.  These events are
+turned on or off (if possible) via sysfs interfaces.
 
 * Hardware ring buffer support.  Some recent sensors have included
 fifo / ring buffers on the sensor chip.  These greatly reduce the load
diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig
index 4586650..ace99f6 100644
--- a/drivers/staging/iio/Kconfig
+++ b/drivers/staging/iio/Kconfig
@@ -8,7 +8,7 @@
 	---help---
 	  The industrial I/O subsystem provides a unified framework for
 	  drivers for many different types of embedded sensors using a
-	  number of different physical interfaces (i2c, spi etc). See
+	  number of different physical interfaces (i2c, spi, etc). See
 	  Documentation/industrialio for more information.
 if IIO
 
@@ -23,10 +23,10 @@
 config IIO_SW_RING
 	tristate "Industrial I/O lock free software ring"
 	help
-	example software ring buffer implementation.  The design aim
-	of this particular realization was to minize write locking
-	with the intention that some devices would be able to write
-	in interrupt context.
+	  Example software ring buffer implementation.  The design aim
+	  of this particular realization was to minimize write locking
+	  with the intention that some devices would be able to write
+	  in interrupt context.
 
 endif # IIO_RINGBUFFER
 
diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig
index fef3da4..3d3c333 100644
--- a/drivers/staging/iio/accel/Kconfig
+++ b/drivers/staging/iio/accel/Kconfig
@@ -13,6 +13,8 @@
 config LIS3L02DQ
 	tristate "ST Microelectronics LIS3L02DQ Accelerometer Driver"
 	depends on SPI
+	select IIO_TRIGGER if IIO_RING_BUFFER
+	select IIO_SW_RING if IIO_RING_BUFFER
 	help
 	  Say yes here to build SPI support for the ST microelectronics
 	  accelerometer. The driver supplies direct access via sysfs files
diff --git a/drivers/staging/iio/accel/accel.h b/drivers/staging/iio/accel/accel.h
index 811fa05..d7fc7f9 100644
--- a/drivers/staging/iio/accel/accel.h
+++ b/drivers/staging/iio/accel/accel.h
@@ -31,13 +31,13 @@
 	IIO_DEVICE_ATTR(accel_z, S_IRUGO, _show, NULL, _addr)
 
 /* Thresholds are somewhat chip dependent - may need quite a few defs here */
-/* For unified thesholds (shared across all directions */
+/* For unified thresholds (shared across all directions */
 
 /**
  * IIO_DEV_ATTR_ACCEL_THRESH: unified threshold
  * @_mode: read/write
  * @_show: read detector threshold value
- * @_store: write detector theshold value
+ * @_store: write detector threshold value
  * @_addr: driver specific data, typically a register address
  *
  * This one is for cases where as single threshold covers all directions
@@ -48,7 +48,7 @@
 /**
  * IIO_DEV_ATTR_ACCEL_THRESH_X: independant direction threshold, x axis
  * @_mode: readable / writable
- * @_show: read x axis detector theshold value
+ * @_show: read x axis detector threshold value
  * @_store: write x axis detector threshold value
  * @_addr: device driver dependant, typically a register address
  **/
diff --git a/drivers/staging/iio/accel/sca3000.h b/drivers/staging/iio/accel/sca3000.h
index 29e11da..da7d3cb 100644
--- a/drivers/staging/iio/accel/sca3000.h
+++ b/drivers/staging/iio/accel/sca3000.h
@@ -74,7 +74,7 @@
 #define SCA3000_MEAS_MODE_OP_2			0x02
 
 /* In motion detection mode the accelerations are band pass filtered
- * (aprox 1 - 25Hz) and then a programmable theshold used to trigger
+ * (aprox 1 - 25Hz) and then a programmable threshold used to trigger
  * and interrupt.
  */
 #define SCA3000_MEAS_MODE_MOT_DET		0x03
@@ -139,7 +139,7 @@
 /* Values of mulipexed registers (write to ctrl_data after select) */
 #define SCA3000_REG_ADDR_CTRL_DATA		0x22
 
-/* Measurment modes available on some sca3000 series chips. Code assumes others
+/* Measurement modes available on some sca3000 series chips. Code assumes others
  * may become available in the future.
  *
  * Bypass - Bypass the low-pass filter in the signal channel so as to increase
diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
index e27e3b7..cedcaa2 100644
--- a/drivers/staging/iio/accel/sca3000_core.c
+++ b/drivers/staging/iio/accel/sca3000_core.c
@@ -720,7 +720,7 @@
 static IIO_DEV_ATTR_TEMP(sca3000_read_temp);
 
 /**
- * sca3000_show_thresh() sysfs query of a theshold
+ * sca3000_show_thresh() sysfs query of a threshold
  **/
 static ssize_t sca3000_show_thresh(struct device *dev,
 				   struct device_attribute *attr,
diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig
index b8c2858..3989c0c 100644
--- a/drivers/staging/iio/adc/Kconfig
+++ b/drivers/staging/iio/adc/Kconfig
@@ -6,8 +6,18 @@
 config MAX1363
 	tristate "MAXIM max1363 ADC driver"
 	depends on I2C
+	select IIO_TRIGGER if IIO_RING_BUFFER
 	help
 	  Say yes here to build support for many MAXIM i2c analog to digital
 	  convertors (ADC). (max1361, max1362, max1363, max1364, max1136,
 	  max1136, max1137, max1138, max1139, max1236, max1237, max11238,
 	  max1239) Provides direct access via sysfs.
+
+config MAX1363_RING_BUFFER
+	bool "MAXIM max1363: use ring buffer"
+	depends on MAX1363
+	select IIO_RING_BUFFER
+	select IIO_SW_RING
+	help
+	  Say yes here to include ring buffer support in the MAX1363
+	  ADC driver.
diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile
index 0c2b6f3..08cee5c2 100644
--- a/drivers/staging/iio/adc/Makefile
+++ b/drivers/staging/iio/adc/Makefile
@@ -3,6 +3,6 @@
 #
 
 max1363-y := max1363_core.o
-max1363-$(CONFIG_IIO_RING_BUFFER) += max1363_ring.o
+max1363-$(CONFIG_MAX1363_RING_BUFFER) += max1363_ring.o
 
 obj-$(CONFIG_MAX1363) += max1363.o
diff --git a/drivers/staging/iio/adc/max1363.h b/drivers/staging/iio/adc/max1363.h
index 8aca81f..c112fbe 100644
--- a/drivers/staging/iio/adc/max1363.h
+++ b/drivers/staging/iio/adc/max1363.h
@@ -228,7 +228,7 @@
 	struct iio_trigger		*trig;
 	struct regulator		*reg;
 };
-#ifdef CONFIG_IIO_RING_BUFFER
+#ifdef CONFIG_MAX1363_RING_BUFFER
 
 ssize_t max1363_scan_from_ring(struct device *dev,
 			       struct device_attribute *attr,
@@ -239,7 +239,7 @@
 int max1363_initialize_ring(struct iio_ring_buffer *ring);
 void max1363_uninitialize_ring(struct iio_ring_buffer *ring);
 
-#else /* CONFIG_IIO_RING_BUFFER */
+#else /* CONFIG_MAX1363_RING_BUFFER */
 
 static inline void max1363_uninitialize_ring(struct iio_ring_buffer *ring)
 {
@@ -265,5 +265,5 @@
 };
 
 static inline void max1363_ring_cleanup(struct iio_dev *indio_dev) {};
-#endif /* CONFIG_IIO_RING_BUFFER */
+#endif /* CONFIG_MAX1363_RING_BUFFER */
 #endif /* _MAX1363_H_ */
diff --git a/drivers/staging/iio/chrdev.h b/drivers/staging/iio/chrdev.h
index 8bc64bf..f42bafb 100644
--- a/drivers/staging/iio/chrdev.h
+++ b/drivers/staging/iio/chrdev.h
@@ -75,10 +75,12 @@
  * @current_events:	number of events in detected list
  * @id:			indentifier to allow the event interface to know which
  *			physical line it corresponds to
+ * @attr:		this chrdev's minor number sysfs attribute
  * @owner:		ensure the driver module owns the file, not iio
  * @private:		driver specific data
  * @_name:		used internally to store the sysfs name for minor id
  *			attribute
+ * @_attrname:		the event interface's attribute name
  */
 struct iio_event_interface {
 	struct device				dev;
@@ -105,7 +107,7 @@
  * @handler:		event handler function - called on event if this
  *			event_handler is enabled.
  *
- * Each device has one list of these per interrupt line
+ * Each device has one list of these per interrupt line.
  **/
 struct iio_event_handler_list {
 	struct list_head	list;
diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index 25ccb80..71dbfe1 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -166,7 +166,7 @@
  * @bit: which number scan element is this
  **/
 static inline int iio_scan_mask_count_to_right(struct iio_dev *dev_info,
-int bit)
+						int bit)
 {
 	int count = 0;
 	int mask = (1 << bit);
@@ -239,7 +239,7 @@
  * @dev_info:		IIO device structure
  * @ev_line:		Which event line (hardware interrupt)
  * @ev_code:		What event
- * @timestamp:		When the event occured
+ * @timestamp:		When the event occurred
  **/
 int iio_push_event(struct iio_dev *dev_info,
 		  int ev_line,
@@ -248,11 +248,11 @@
 
 /**
  * struct iio_work_cont - container for when singleton handler case matters
- * @ws:			[DEVICE]work_struct when not only possible event
- * @ws_nocheck:		[DEVICE]work_struct when only possible event
- * @address:		[DEVICE]associated register address
- * @mask:		[DEVICE]associated mask for identifying event source
- * @st:			[DEVICE]device specific state information
+ * @ws:			[DEVICE] work_struct when not only possible event
+ * @ws_nocheck:		[DEVICE] work_struct when only possible event
+ * @address:		[DEVICE] associated register address
+ * @mask:		[DEVICE] associated mask for identifying event source
+ * @st:			[DEVICE] device specific state information
  **/
 struct iio_work_cont {
 	struct work_struct	ws;
@@ -273,9 +273,9 @@
  * @cont: the work container
  * @_checkfunc: function called when there are multiple possible int sources
  * @_nocheckfunc: function for when there is only one int source
- * @_add: driver dependant, typically a register address
- * @_mask: driver dependant, typically a bit mask for a register
- * @_st: driver dependant, typically pointer to a device state structure
+ * @_add: driver dependent, typically a register address
+ * @_mask: driver dependent, typically a bit mask for a register
+ * @_st: driver dependent, typically pointer to a device state structure
  **/
 static inline void
 iio_init_work_cont(struct iio_work_cont *cont,
@@ -290,7 +290,7 @@
 	cont->st = _st;
 }
 /**
- * __iio_push_event() tries to add an event to the list associated with a chrdev
+ * __iio_push_event() - tries to add an event to the list associated with a chrdev
  * @ev_int:		the event interface to which we are pushing the event
  * @ev_code:		the outgoing event code
  * @timestamp:		timestamp of the event
@@ -302,8 +302,8 @@
 		    struct iio_shared_ev_pointer*
 		    shared_pointer_p);
 /**
- * __iio_change_event() change an event code in case of event escallation
- * @ev:			the evnet to be changed
+ * __iio_change_event() - change an event code in case of event escalation
+ * @ev:			the event to be changed
  * @ev_code:		new event code
  * @timestamp:		new timestamp
  **/
@@ -312,7 +312,7 @@
 			s64 timestamp);
 
 /**
- * iio_setup_ev_int() Configure an event interface (chrdev)
+ * iio_setup_ev_int() - configure an event interface (chrdev)
  * @name:		name used for resulting sysfs directory etc.
  * @ev_int:		interface we are configuring
  * @owner:		module that is responsible for registering this ev_int
@@ -343,7 +343,7 @@
 extern struct class iio_class;
 
 /**
- * iio_put_device() - reference counted deallocated of struct device
+ * iio_put_device() - reference counted deallocation of struct device
  * @dev: the iio_device containing the device
  **/
 static inline void iio_put_device(struct iio_dev *dev)
@@ -353,7 +353,7 @@
 };
 
 /**
- * to_iio_dev() - get iio_dev for which we have have the struct device
+ * to_iio_dev() - get iio_dev for which we have the struct device
  * @d: the struct device
  **/
 static inline struct iio_dev *to_iio_dev(struct device *d)
@@ -377,6 +377,7 @@
 
 /**
  * iio_free_device() - free an iio_dev from a driver
+ * @dev: the iio_dev associated with the device
  **/
 void iio_free_device(struct iio_dev *dev);
 
@@ -395,7 +396,8 @@
 void iio_device_free_chrdev_minor(int val);
 
 /**
- * iio_ring_enabled() helper function to test if any form of ring enabled
+ * iio_ring_enabled() - helper function to test if any form of ring is enabled
+ * @dev_info:		IIO device info structure for device
  **/
 static inline bool iio_ring_enabled(struct iio_dev *dev_info)
 {
diff --git a/drivers/staging/iio/light/Kconfig b/drivers/staging/iio/light/Kconfig
index 12af0c4..80cb6e5 100644
--- a/drivers/staging/iio/light/Kconfig
+++ b/drivers/staging/iio/light/Kconfig
@@ -3,11 +3,13 @@
 #
 comment "Light sensors"
 
-config TSL2561
-       tristate "TAOS TSL2561 light-to-digital convertor"
-       depends on I2C
-       help
-	Say yes bere to build support for the TAOS light to digital
-	convertor.  This chip has two light sensors. One is broadband
-	including infrared whilst the other measures only infrared.
-	Provides direct access via sysfs.
+config SENSORS_TSL2563
+	tristate "TAOS TSL256[0-3] ambient light sensor"
+	depends on I2C
+	help
+	 If you say yes here you get support for the Taos TSL2560,
+	 TSL2561, TSL2562 and TSL2563 ambient light sensors.
+
+	 This driver can also be built as a module.  If so, the module
+	 will be called tsl2563.
+
diff --git a/drivers/staging/iio/light/Makefile b/drivers/staging/iio/light/Makefile
index ccff151..30f3300 100644
--- a/drivers/staging/iio/light/Makefile
+++ b/drivers/staging/iio/light/Makefile
@@ -2,4 +2,4 @@
 # Makefile for industrial I/O Light sensors
 #
 
-obj-$(CONFIG_TSL2561)   += tsl2561.o
+obj-$(CONFIG_SENSORS_TSL2563)	+= tsl2563.o
diff --git a/drivers/staging/iio/light/tsl2561.c b/drivers/staging/iio/light/tsl2561.c
deleted file mode 100644
index fc2107f..0000000
--- a/drivers/staging/iio/light/tsl2561.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- *  tsl2561.c - Linux kernel modules for light to digital convertor
- *
- *  Copyright (C) 2008-2009 Jonathan Cameron <jic23@cam.ac.uk>
- *
- *  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.
- *
- *  Some portions based upon the tsl2550 driver.
- *
- *  This driver could probably be adapted easily to talk to the tsl2560 (smbus)
- *
- *  Needs some work to support the events this can generate.
- *  Todo: Implement interrupt handling.  Currently a hardware bug means
- *  this isn't available on my test board.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include "../iio.h"
-#include "../sysfs.h"
-#include "light.h"
-
-#define TSL2561_CONTROL_REGISTER 0x00
-#define TSL2561_TIMING_REGISTER 0x01
-#define TSL2561_THRESHLOW_LOW_REGISTER 0x02
-#define TSL2561_THRESHLOW_HIGH_REGISTER 0x03
-#define TSL2561_THRESHHIGH_LOW_REGISTER 0x04
-#define TSL2561_THRESHHIGH_HIGH_REGISTER 0x05
-#define TSL2561_INT_CONTROL_REGISTER 0x06
-
-#define TSL2561_INT_REG_INT_OFF 0x00
-#define TSL2561_INT_REG_INT_LEVEL 0x08
-#define TSL2561_INT_REG_INT_SMBUS 0x10
-#define TSL2561_INT_REG_INT_TEST 0x18
-
-#define TSL2561_ID_REGISTER 0x0A
-
-#define TSL2561_DATA_0_LOW 0x0C
-#define TSL2561_DATA_1_LOW 0x0E
-
-/* Control Register Values */
-#define TSL2561_CONT_REG_PWR_ON 0x03
-#define TSL2561_CONT_REG_PWR_OFF 0x00
-
-/**
- * struct tsl2561_state - device specific state
- * @indio_dev:		the industrialio I/O info structure
- * @client:		i2c client
- * @command_buf:	single command buffer used for all operations
- * @command_buf_lock:	ensure unique access to command_buf
- */
-struct tsl2561_state {
-	struct iio_dev		*indio_dev;
-	struct i2c_client	*client;
-	struct tsl2561_command	*command_buf;
-	struct mutex		command_buf_lock;
-};
-
-/**
- * struct tsl2561_command - command byte for smbus
- * @address:	register address
- * @block:	is this a block r/w
- * @word:	is this a word r/w
- * @clear:	set to 1 to clear pending interrupt
- * @cmd:	select the command register - always 1.
- */
-struct tsl2561_command {
-	unsigned int address:4;
-	unsigned int block:1;
-	unsigned int word:1;
-	unsigned int clear:1;
-	unsigned int cmd:1;
-};
-
-static inline void tsl2561_init_command_buf(struct tsl2561_command *buf)
-{
-	buf->address = 0;
-	buf->block = 0;
-	buf->word = 0;
-	buf->clear = 0;
-	buf->cmd = 1;
-}
-
-static ssize_t tsl2561_read_val(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	int ret = 0, data;
-	ssize_t len = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct tsl2561_state *st = indio_dev->dev_data;
-
-	mutex_lock(&st->command_buf_lock);
-	st->command_buf->cmd = 1;
-	st->command_buf->word = 1;
-	st->command_buf->address = this_attr->address;
-
-	data = i2c_smbus_read_word_data(st->client, *(char *)(st->command_buf));
-	if (data < 0) {
-		ret = data;
-		goto error_ret;
-	}
-	len = sprintf(buf, "%u\n", data);
-
-error_ret:
-	mutex_unlock(&st->command_buf_lock);
-
-	return ret ? ret : len;
-}
-
-static IIO_DEV_ATTR_LIGHT_INFRARED(0, tsl2561_read_val, TSL2561_DATA_0_LOW);
-static IIO_DEV_ATTR_LIGHT_BROAD(0, tsl2561_read_val, TSL2561_DATA_1_LOW);
-
-static struct attribute *tsl2561_attributes[] = {
-	&iio_dev_attr_light_infrared0.dev_attr.attr,
-	&iio_dev_attr_light_broadspectrum0.dev_attr.attr,
-	NULL,
-};
-
-static const struct attribute_group tsl2561_attribute_group = {
-	.attrs = tsl2561_attributes,
-};
-
-static int tsl2561_initialize(struct tsl2561_state *st)
-{
-	int err;
-
-	mutex_lock(&st->command_buf_lock);
-	st->command_buf->word = 0;
-	st->command_buf->block = 0;
-	st->command_buf->address = TSL2561_CONTROL_REGISTER;
-	err = i2c_smbus_write_byte_data(st->client, *(char *)(st->command_buf),
-					TSL2561_CONT_REG_PWR_ON);
-	if (err)
-		goto error_ret;
-
-	st->command_buf->address = TSL2561_INT_CONTROL_REGISTER;
-	err = i2c_smbus_write_byte_data(st->client, *(char *)(st->command_buf),
-					TSL2561_INT_REG_INT_TEST);
-
-error_ret:
-	mutex_unlock(&st->command_buf_lock);
-
-	return err;
-}
-
-static int tsl2561_powerdown(struct i2c_client *client)
-{
-	int err;
-	struct tsl2561_command Command = {
-		.cmd =  1,
-		.clear = 0,
-		.word = 0,
-		.block = 0,
-		.address = TSL2561_CONTROL_REGISTER,
-	};
-
-	err = i2c_smbus_write_byte_data(client, *(char *)(&Command),
-					TSL2561_CONT_REG_PWR_OFF);
-	return (err < 0) ? err : 0;
-}
-static int __devinit tsl2561_probe(struct i2c_client *client,
-				   const struct i2c_device_id *id)
-{
-	int ret = 0, regdone = 0;
-	struct tsl2561_state *st = kzalloc(sizeof(*st), GFP_KERNEL);
-
-	if (st == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-	i2c_set_clientdata(client, st);
-	st->client = client;
-	mutex_init(&st->command_buf_lock);
-
-	st->command_buf = kmalloc(sizeof(*st->command_buf), GFP_KERNEL);
-	if (st->command_buf == NULL) {
-		ret = -ENOMEM;
-		goto error_free_state;
-	}
-	tsl2561_init_command_buf(st->command_buf);
-
-	st->indio_dev = iio_allocate_device();
-	if (st->indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_free_command_buf;
-	}
-	st->indio_dev->attrs = &tsl2561_attribute_group;
-	st->indio_dev->dev.parent = &client->dev;
-	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
-	st->indio_dev->modes = INDIO_DIRECT_MODE;
-	ret = iio_device_register(st->indio_dev);
-	if (ret)
-		goto error_free_iiodev;
-	regdone = 1;
-	/* Intialize the chip */
-	ret = tsl2561_initialize(st);
-	if (ret)
-		goto error_unregister_iiodev;
-
-	return 0;
-error_unregister_iiodev:
-error_free_iiodev:
-	if (regdone)
-		iio_device_unregister(st->indio_dev);
-	else
-		iio_free_device(st->indio_dev);
-error_free_command_buf:
-	kfree(st->command_buf);
-error_free_state:
-	kfree(st);
-error_ret:
-	return ret;
-
-}
-
-static int __devexit tsl2561_remove(struct i2c_client *client)
-{
-	struct tsl2561_state *st =  i2c_get_clientdata(client);
-
-	iio_device_unregister(st->indio_dev);
-	kfree(st);
-
-	return tsl2561_powerdown(client);
-}
-
-static const struct i2c_device_id tsl2561_id[] = {
-	{ "tsl2561", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, tsl2561_id);
-
-
-static struct i2c_driver tsl2561_driver = {
-	.driver = {
-		.name = "tsl2561",
-	},
-	.probe = tsl2561_probe,
-	.remove = __devexit_p(tsl2561_remove),
-	.id_table  = tsl2561_id,
-};
-
-static __init int tsl2561_init(void)
-{
-	return i2c_add_driver(&tsl2561_driver);
-}
-module_init(tsl2561_init);
-
-static __exit void tsl2561_exit(void)
-{
-	i2c_del_driver(&tsl2561_driver);
-}
-module_exit(tsl2561_exit);
-
-MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
-MODULE_DESCRIPTION("TSL2561 light sensor driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c
new file mode 100644
index 0000000..78b9432
--- /dev/null
+++ b/drivers/staging/iio/light/tsl2563.c
@@ -0,0 +1,773 @@
+/*
+ * drivers/i2c/chips/tsl2563.c
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Written by Timo O. Karjalainen <timo.o.karjalainen@nokia.com>
+ * Contact: Amit Kucheria <amit.kucheria@verdurent.com>
+ *
+ * Converted to IIO driver
+ * Amit Kucheria <amit.kucheria@verdurent.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.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/hwmon.h>
+#include <linux/err.h>
+
+#include "../iio.h"
+#include "tsl2563.h"
+
+/* Use this many bits for fraction part. */
+#define ADC_FRAC_BITS		(14)
+
+/* Given number of 1/10000's in ADC_FRAC_BITS precision. */
+#define FRAC10K(f)		(((f) * (1L << (ADC_FRAC_BITS))) / (10000))
+
+/* Bits used for fraction in calibration coefficients.*/
+#define CALIB_FRAC_BITS		(10)
+/* 0.5 in CALIB_FRAC_BITS precision */
+#define CALIB_FRAC_HALF		(1 << (CALIB_FRAC_BITS - 1))
+/* Make a fraction from a number n that was multiplied with b. */
+#define CALIB_FRAC(n, b)	(((n) << CALIB_FRAC_BITS) / (b))
+/* Decimal 10^(digits in sysfs presentation) */
+#define CALIB_BASE_SYSFS	(1000)
+
+#define TSL2563_CMD		(0x80)
+#define TSL2563_CLEARINT	(0x40)
+
+#define TSL2563_REG_CTRL	(0x00)
+#define TSL2563_REG_TIMING	(0x01)
+#define TSL2563_REG_LOWLOW	(0x02) /* data0 low threshold, 2 bytes */
+#define TSL2563_REG_LOWHIGH	(0x03)
+#define TSL2563_REG_HIGHLOW	(0x04) /* data0 high threshold, 2 bytes */
+#define TSL2563_REG_HIGHHIGH	(0x05)
+#define TSL2563_REG_INT		(0x06)
+#define TSL2563_REG_ID		(0x0a)
+#define TSL2563_REG_DATA0LOW	(0x0c) /* broadband sensor value, 2 bytes */
+#define TSL2563_REG_DATA0HIGH	(0x0d)
+#define TSL2563_REG_DATA1LOW	(0x0e) /* infrared sensor value, 2 bytes */
+#define TSL2563_REG_DATA1HIGH	(0x0f)
+
+#define TSL2563_CMD_POWER_ON	(0x03)
+#define TSL2563_CMD_POWER_OFF	(0x00)
+#define TSL2563_CTRL_POWER_MASK	(0x03)
+
+#define TSL2563_TIMING_13MS	(0x00)
+#define TSL2563_TIMING_100MS	(0x01)
+#define TSL2563_TIMING_400MS	(0x02)
+#define TSL2563_TIMING_MASK	(0x03)
+#define TSL2563_TIMING_GAIN16	(0x10)
+#define TSL2563_TIMING_GAIN1	(0x00)
+
+#define TSL2563_INT_DISBLED	(0x00)
+#define TSL2563_INT_LEVEL	(0x10)
+#define TSL2563_INT_PERSIST(n)	((n) & 0x0F)
+
+struct tsl2563_gainlevel_coeff {
+	u8 gaintime;
+	u16 min;
+	u16 max;
+};
+
+static struct tsl2563_gainlevel_coeff tsl2563_gainlevel_table[] = {
+	{
+		.gaintime	= TSL2563_TIMING_400MS | TSL2563_TIMING_GAIN16,
+		.min		= 0,
+		.max		= 65534,
+	}, {
+		.gaintime	= TSL2563_TIMING_400MS | TSL2563_TIMING_GAIN1,
+		.min		= 2048,
+		.max		= 65534,
+	}, {
+		.gaintime	= TSL2563_TIMING_100MS | TSL2563_TIMING_GAIN1,
+		.min		= 4095,
+		.max		= 37177,
+	}, {
+		.gaintime	= TSL2563_TIMING_13MS | TSL2563_TIMING_GAIN1,
+		.min		= 3000,
+		.max		= 65535,
+	},
+};
+
+struct tsl2563_chip {
+	struct mutex		lock;
+	struct i2c_client	*client;
+	struct iio_dev		*indio_dev;
+	struct delayed_work	poweroff_work;
+
+	/* Remember state for suspend and resume functions */
+	pm_message_t		state;
+
+	struct tsl2563_gainlevel_coeff *gainlevel;
+
+	/* Thresholds are in lux */
+	u16			low_thres;
+	u16			high_thres;
+	u8			intr;
+
+	/* Calibration coefficients */
+	u32			calib0;
+	u32			calib1;
+	int			cover_comp_gain;
+
+	/* Cache current values, to be returned while suspended */
+	u32			data0;
+	u32			data1;
+};
+
+static int tsl2563_write(struct i2c_client *client, u8 reg, u8 value)
+{
+	int ret;
+	u8 buf[2];
+
+	buf[0] = TSL2563_CMD | reg;
+	buf[1] = value;
+
+	ret = i2c_master_send(client, buf, sizeof(buf));
+	return (ret == sizeof(buf)) ? 0 : ret;
+}
+
+static int tsl2563_read(struct i2c_client *client, u8 reg, void *buf, int len)
+{
+	int ret;
+	u8 cmd = TSL2563_CMD | reg;
+
+	ret = i2c_master_send(client, &cmd, sizeof(cmd));
+	if (ret != sizeof(cmd))
+		return ret;
+
+	return i2c_master_recv(client, buf, len);
+}
+
+static int tsl2563_set_power(struct tsl2563_chip *chip, int on)
+{
+	struct i2c_client *client = chip->client;
+	u8 cmd;
+
+	cmd = on ? TSL2563_CMD_POWER_ON : TSL2563_CMD_POWER_OFF;
+	return tsl2563_write(client, TSL2563_REG_CTRL, cmd);
+}
+
+/*
+ * Return value is 0 for off, 1 for on, or a negative error
+ * code if reading failed.
+ */
+static int tsl2563_get_power(struct tsl2563_chip *chip)
+{
+	struct i2c_client *client = chip->client;
+	int ret;
+	u8 val;
+
+	ret = tsl2563_read(client, TSL2563_REG_CTRL, &val, sizeof(val));
+	if (ret != sizeof(val))
+		return ret;
+
+	return (val & TSL2563_CTRL_POWER_MASK) == TSL2563_CMD_POWER_ON;
+}
+
+static int tsl2563_configure(struct tsl2563_chip *chip)
+{
+	struct i2c_client *client = chip->client;
+	int ret;
+
+	ret = tsl2563_write(client, TSL2563_REG_TIMING,
+			chip->gainlevel->gaintime);
+	if (ret)
+		goto out;
+
+	ret = tsl2563_write(client, TSL2563_REG_INT, chip->intr);
+
+out:
+	return ret;
+}
+
+static void tsl2563_poweroff_work(struct work_struct *work)
+{
+	struct tsl2563_chip *chip =
+		container_of(work, struct tsl2563_chip, poweroff_work.work);
+	tsl2563_set_power(chip, 0);
+}
+
+static int tsl2563_detect(struct tsl2563_chip *chip)
+{
+	int ret;
+
+	ret = tsl2563_set_power(chip, 1);
+	if (ret)
+		return ret;
+
+	ret = tsl2563_get_power(chip);
+	if (ret < 0)
+		return ret;
+
+	return ret ? 0 : -ENODEV;
+}
+
+static int tsl2563_read_id(struct tsl2563_chip *chip, u8 *id)
+{
+	struct i2c_client *client = chip->client;
+	int ret;
+
+	ret = tsl2563_read(client, TSL2563_REG_ID, id, sizeof(*id));
+	if (ret != sizeof(*id))
+		return ret;
+
+	return 0;
+}
+
+/*
+ * "Normalized" ADC value is one obtained with 400ms of integration time and
+ * 16x gain. This function returns the number of bits of shift needed to
+ * convert between normalized values and HW values obtained using given
+ * timing and gain settings.
+ */
+static int adc_shiftbits(u8 timing)
+{
+	int shift = 0;
+
+	switch (timing & TSL2563_TIMING_MASK) {
+	case TSL2563_TIMING_13MS:
+		shift += 5;
+		break;
+	case TSL2563_TIMING_100MS:
+		shift += 2;
+		break;
+	case TSL2563_TIMING_400MS:
+		/* no-op */
+		break;
+	}
+
+	if (!(timing & TSL2563_TIMING_GAIN16))
+		shift += 4;
+
+	return shift;
+}
+
+/* Convert a HW ADC value to normalized scale. */
+static u32 normalize_adc(u16 adc, u8 timing)
+{
+	return adc << adc_shiftbits(timing);
+}
+
+static void tsl2563_wait_adc(struct tsl2563_chip *chip)
+{
+	unsigned int delay;
+
+	switch (chip->gainlevel->gaintime & TSL2563_TIMING_MASK) {
+	case TSL2563_TIMING_13MS:
+		delay = 14;
+		break;
+	case TSL2563_TIMING_100MS:
+		delay = 101;
+		break;
+	default:
+		delay = 402;
+	}
+	/*
+	 * TODO: Make sure that we wait at least required delay but why we
+	 * have to extend it one tick more?
+	 */
+	schedule_timeout_interruptible(msecs_to_jiffies(delay) + 2);
+}
+
+static int tsl2563_adjust_gainlevel(struct tsl2563_chip *chip, u16 adc)
+{
+	struct i2c_client *client = chip->client;
+
+	if (adc > chip->gainlevel->max || adc < chip->gainlevel->min) {
+
+		(adc > chip->gainlevel->max) ?
+			chip->gainlevel++ : chip->gainlevel--;
+
+		tsl2563_write(client, TSL2563_REG_TIMING,
+			      chip->gainlevel->gaintime);
+
+		tsl2563_wait_adc(chip);
+		tsl2563_wait_adc(chip);
+
+		return 1;
+	} else
+		return 0;
+}
+
+static int tsl2563_get_adc(struct tsl2563_chip *chip)
+{
+	struct i2c_client *client = chip->client;
+	u8 buf0[2], buf1[2];
+	u16 adc0, adc1;
+	int retry = 1;
+	int ret = 0;
+
+	if (chip->state.event != PM_EVENT_ON)
+		goto out;
+
+	cancel_delayed_work(&chip->poweroff_work);
+
+	if (!tsl2563_get_power(chip)) {
+		ret = tsl2563_set_power(chip, 1);
+		if (ret)
+			goto out;
+		ret = tsl2563_configure(chip);
+		if (ret)
+			goto out;
+		tsl2563_wait_adc(chip);
+	}
+
+	while (retry) {
+		ret = tsl2563_read(client,
+				   TSL2563_REG_DATA0LOW | TSL2563_CLEARINT,
+				   buf0, sizeof(buf0));
+		if (ret != sizeof(buf0))
+			goto out;
+
+		ret = tsl2563_read(client, TSL2563_REG_DATA1LOW,
+				   buf1, sizeof(buf1));
+		if (ret != sizeof(buf1))
+			goto out;
+
+		adc0 = (buf0[1] << 8) + buf0[0];
+		adc1 = (buf1[1] << 8) + buf1[0];
+
+		retry = tsl2563_adjust_gainlevel(chip, adc0);
+	}
+
+	chip->data0 = normalize_adc(adc0, chip->gainlevel->gaintime);
+	chip->data1 = normalize_adc(adc1, chip->gainlevel->gaintime);
+
+	schedule_delayed_work(&chip->poweroff_work, 5 * HZ);
+
+	ret = 0;
+out:
+	return ret;
+}
+
+static inline int calib_to_sysfs(u32 calib)
+{
+	return (int) (((calib * CALIB_BASE_SYSFS) +
+		       CALIB_FRAC_HALF) >> CALIB_FRAC_BITS);
+}
+
+static inline u32 calib_from_sysfs(int value)
+{
+	return (((u32) value) << CALIB_FRAC_BITS) / CALIB_BASE_SYSFS;
+}
+
+/*
+ * Conversions between lux and ADC values.
+ *
+ * The basic formula is lux = c0 * adc0 - c1 * adc1, where c0 and c1 are
+ * appropriate constants. Different constants are needed for different
+ * kinds of light, determined by the ratio adc1/adc0 (basically the ratio
+ * of the intensities in infrared and visible wavelengths). lux_table below
+ * lists the upper threshold of the adc1/adc0 ratio and the corresponding
+ * constants.
+ */
+
+struct tsl2563_lux_coeff {
+	unsigned long ch_ratio;
+	unsigned long ch0_coeff;
+	unsigned long ch1_coeff;
+};
+
+static const struct tsl2563_lux_coeff lux_table[] = {
+	{
+		.ch_ratio	= FRAC10K(1300),
+		.ch0_coeff	= FRAC10K(315),
+		.ch1_coeff	= FRAC10K(262),
+	}, {
+		.ch_ratio	= FRAC10K(2600),
+		.ch0_coeff	= FRAC10K(337),
+		.ch1_coeff	= FRAC10K(430),
+	}, {
+		.ch_ratio	= FRAC10K(3900),
+		.ch0_coeff	= FRAC10K(363),
+		.ch1_coeff	= FRAC10K(529),
+	}, {
+		.ch_ratio	= FRAC10K(5200),
+		.ch0_coeff	= FRAC10K(392),
+		.ch1_coeff	= FRAC10K(605),
+	}, {
+		.ch_ratio	= FRAC10K(6500),
+		.ch0_coeff	= FRAC10K(229),
+		.ch1_coeff	= FRAC10K(291),
+	}, {
+		.ch_ratio	= FRAC10K(8000),
+		.ch0_coeff	= FRAC10K(157),
+		.ch1_coeff	= FRAC10K(180),
+	}, {
+		.ch_ratio	= FRAC10K(13000),
+		.ch0_coeff	= FRAC10K(34),
+		.ch1_coeff	= FRAC10K(26),
+	}, {
+		.ch_ratio	= ULONG_MAX,
+		.ch0_coeff	= 0,
+		.ch1_coeff	= 0,
+	},
+};
+
+/*
+ * Convert normalized, scaled ADC values to lux.
+ */
+static unsigned int adc_to_lux(u32 adc0, u32 adc1)
+{
+	const struct tsl2563_lux_coeff *lp = lux_table;
+	unsigned long ratio, lux, ch0 = adc0, ch1 = adc1;
+
+	ratio = ch0 ? ((ch1 << ADC_FRAC_BITS) / ch0) : ULONG_MAX;
+
+	while (lp->ch_ratio < ratio)
+		lp++;
+
+	lux = ch0 * lp->ch0_coeff - ch1 * lp->ch1_coeff;
+
+	return (unsigned int) (lux >> ADC_FRAC_BITS);
+}
+
+/*--------------------------------------------------------------*/
+/*                      Sysfs interface                         */
+/*--------------------------------------------------------------*/
+
+static ssize_t tsl2563_adc0_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct tsl2563_chip *chip = indio_dev->dev_data;
+	int ret;
+
+	mutex_lock(&chip->lock);
+
+	ret = tsl2563_get_adc(chip);
+	if (ret)
+		goto out;
+
+	ret = snprintf(buf, PAGE_SIZE, "%d\n", chip->data0);
+out:
+	mutex_unlock(&chip->lock);
+	return ret;
+}
+
+static ssize_t tsl2563_adc1_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct tsl2563_chip *chip = indio_dev->dev_data;
+	int ret;
+
+	mutex_lock(&chip->lock);
+
+	ret = tsl2563_get_adc(chip);
+	if (ret)
+		goto out;
+
+	ret = snprintf(buf, PAGE_SIZE, "%d\n", chip->data1);
+out:
+	mutex_unlock(&chip->lock);
+	return ret;
+}
+
+/* Apply calibration coefficient to ADC count. */
+static u32 calib_adc(u32 adc, u32 calib)
+{
+	unsigned long scaled = adc;
+
+	scaled *= calib;
+	scaled >>= CALIB_FRAC_BITS;
+
+	return (u32) scaled;
+}
+
+static ssize_t tsl2563_lux_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct tsl2563_chip *chip = indio_dev->dev_data;
+	u32 calib0, calib1;
+	int ret;
+
+	mutex_lock(&chip->lock);
+
+	ret = tsl2563_get_adc(chip);
+	if (ret)
+		goto out;
+
+	calib0 = calib_adc(chip->data0, chip->calib0) * chip->cover_comp_gain;
+	calib1 = calib_adc(chip->data1, chip->calib1) * chip->cover_comp_gain;
+
+	ret = snprintf(buf, PAGE_SIZE, "%d\n", adc_to_lux(calib0, calib1));
+
+out:
+	mutex_unlock(&chip->lock);
+	return ret;
+}
+
+static ssize_t format_calib(char *buf, int len, u32 calib)
+{
+	return snprintf(buf, PAGE_SIZE, "%d\n", calib_to_sysfs(calib));
+}
+
+static ssize_t tsl2563_calib0_show(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct tsl2563_chip *chip = indio_dev->dev_data;
+	int ret;
+
+	mutex_lock(&chip->lock);
+	ret = format_calib(buf, PAGE_SIZE, chip->calib0);
+	mutex_unlock(&chip->lock);
+	return ret;
+}
+
+static ssize_t tsl2563_calib1_show(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct tsl2563_chip *chip = indio_dev->dev_data;
+	int ret;
+
+	mutex_lock(&chip->lock);
+	ret = format_calib(buf, PAGE_SIZE, chip->calib1);
+	mutex_unlock(&chip->lock);
+	return ret;
+}
+
+static int do_calib_store(struct device *dev, const char *buf, size_t len,
+			  int ch)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct tsl2563_chip *chip = indio_dev->dev_data;
+	int value;
+	u32 calib;
+
+	if (1 != sscanf(buf, "%d", &value))
+		return -EINVAL;
+
+	calib = calib_from_sysfs(value);
+
+	if (ch)
+		chip->calib1 = calib;
+	else
+		chip->calib0 = calib;
+
+	return len;
+}
+
+static ssize_t tsl2563_calib0_store(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t len)
+{
+	return do_calib_store(dev, buf, len, 0);
+}
+
+static ssize_t tsl2563_calib1_store(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t len)
+{
+	return do_calib_store(dev, buf, len, 1);
+}
+
+/* AmitXXXX: Convert to IIO_DEV_ATTR_LIGHT* as in tsl2561
+ * once I understand what they mean */
+static DEVICE_ATTR(adc0, S_IRUGO, tsl2563_adc0_show, NULL);
+static DEVICE_ATTR(adc1, S_IRUGO, tsl2563_adc1_show, NULL);
+static DEVICE_ATTR(lux, S_IRUGO, tsl2563_lux_show, NULL);
+static DEVICE_ATTR(calib0, S_IRUGO | S_IWUSR,
+		   tsl2563_calib0_show, tsl2563_calib0_store);
+static DEVICE_ATTR(calib1, S_IRUGO | S_IWUSR,
+		   tsl2563_calib1_show, tsl2563_calib1_store);
+
+static struct attribute *tsl2563_attributes[] = {
+	&dev_attr_adc0.attr,
+	&dev_attr_adc1.attr,
+	&dev_attr_lux.attr,
+	&dev_attr_calib0.attr,
+	&dev_attr_calib1.attr,
+	NULL
+};
+
+static const struct attribute_group tsl2563_group = {
+	.attrs = tsl2563_attributes,
+};
+
+/*--------------------------------------------------------------*/
+/*                      Probe, Attach, Remove                   */
+/*--------------------------------------------------------------*/
+static struct i2c_driver tsl2563_i2c_driver;
+
+static int __devinit tsl2563_probe(struct i2c_client *client,
+				const struct i2c_device_id *device_id)
+{
+	struct tsl2563_chip *chip;
+	struct tsl2563_platform_data *pdata = client->dev.platform_data;
+	int err = 0;
+	int ret;
+	u8 id;
+
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, chip);
+	chip->client = client;
+
+	err = tsl2563_detect(chip);
+	if (err) {
+		dev_err(&client->dev, "device not found, error %d \n", -err);
+		goto fail1;
+	}
+
+	err = tsl2563_read_id(chip, &id);
+	if (err)
+		goto fail1;
+
+	mutex_init(&chip->lock);
+
+	/* Default values used until userspace says otherwise */
+	chip->low_thres = 0x0;
+	chip->high_thres = 0xffff;
+	chip->gainlevel = tsl2563_gainlevel_table;
+	chip->intr = TSL2563_INT_PERSIST(4);
+	chip->calib0 = calib_from_sysfs(CALIB_BASE_SYSFS);
+	chip->calib1 = calib_from_sysfs(CALIB_BASE_SYSFS);
+
+	if (pdata)
+		chip->cover_comp_gain = pdata->cover_comp_gain;
+	else
+		chip->cover_comp_gain = 1;
+
+	dev_info(&client->dev, "model %d, rev. %d\n", id >> 4, id & 0x0f);
+
+	chip->indio_dev = iio_allocate_device();
+	if (!chip->indio_dev)
+		goto fail1;
+	chip->indio_dev->attrs = &tsl2563_group;
+	chip->indio_dev->dev.parent = &client->dev;
+	chip->indio_dev->dev_data = (void *)(chip);
+	chip->indio_dev->driver_module = THIS_MODULE;
+	chip->indio_dev->modes = INDIO_DIRECT_MODE;
+	ret = iio_device_register(chip->indio_dev);
+	if (ret)
+		goto fail1;
+
+	err = tsl2563_configure(chip);
+	if (err)
+		goto fail2;
+
+	INIT_DELAYED_WORK(&chip->poweroff_work, tsl2563_poweroff_work);
+	schedule_delayed_work(&chip->poweroff_work, 5 * HZ);
+
+	return 0;
+fail2:
+	iio_device_unregister(chip->indio_dev);
+fail1:
+	kfree(chip);
+	return err;
+}
+
+static int tsl2563_remove(struct i2c_client *client)
+{
+	struct tsl2563_chip *chip = i2c_get_clientdata(client);
+
+	iio_device_unregister(chip->indio_dev);
+
+	kfree(chip);
+	return 0;
+}
+
+static int tsl2563_suspend(struct i2c_client *client, pm_message_t state)
+{
+	struct tsl2563_chip *chip = i2c_get_clientdata(client);
+	int ret;
+
+	mutex_lock(&chip->lock);
+
+	ret = tsl2563_set_power(chip, 0);
+	if (ret)
+		goto out;
+
+	chip->state = state;
+
+out:
+	mutex_unlock(&chip->lock);
+	return ret;
+}
+
+static int tsl2563_resume(struct i2c_client *client)
+{
+	struct tsl2563_chip *chip = i2c_get_clientdata(client);
+	int ret;
+
+	mutex_lock(&chip->lock);
+
+	ret = tsl2563_set_power(chip, 1);
+	if (ret)
+		goto out;
+
+	ret = tsl2563_configure(chip);
+	if (ret)
+		goto out;
+
+	chip->state.event = PM_EVENT_ON;
+
+out:
+	mutex_unlock(&chip->lock);
+	return ret;
+}
+
+static const struct i2c_device_id tsl2563_id[] = {
+	{ "tsl2560", 0 },
+	{ "tsl2561", 1 },
+	{ "tsl2562", 2 },
+	{ "tsl2563", 3 },
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, tsl2563_id);
+
+static struct i2c_driver tsl2563_i2c_driver = {
+	.driver = {
+		.name	 = "tsl2563",
+	},
+	.suspend	= tsl2563_suspend,
+	.resume		= tsl2563_resume,
+	.probe		= tsl2563_probe,
+	.remove		= __devexit_p(tsl2563_remove),
+	.id_table	= tsl2563_id,
+};
+
+static int __init tsl2563_init(void)
+{
+	return i2c_add_driver(&tsl2563_i2c_driver);
+}
+
+static void __exit tsl2563_exit(void)
+{
+	i2c_del_driver(&tsl2563_i2c_driver);
+}
+
+MODULE_AUTHOR("Nokia Corporation");
+MODULE_DESCRIPTION("tsl2563 light sensor driver");
+MODULE_LICENSE("GPL");
+
+module_init(tsl2563_init);
+module_exit(tsl2563_exit);
diff --git a/drivers/staging/iio/light/tsl2563.h b/drivers/staging/iio/light/tsl2563.h
new file mode 100644
index 0000000..b97368b
--- /dev/null
+++ b/drivers/staging/iio/light/tsl2563.h
@@ -0,0 +1,9 @@
+#ifndef __LINUX_TSL2563_H
+#define __LINUX_TSL2563_H
+
+struct tsl2563_platform_data {
+	int cover_comp_gain;
+};
+
+#endif /* __LINUX_TSL2563_H */
+
diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h
index d926189..93b91b2 100644
--- a/drivers/staging/iio/ring_generic.h
+++ b/drivers/staging/iio/ring_generic.h
@@ -25,9 +25,12 @@
 			int event_code,
 			s64 timestamp);
 /**
- * iio_push_or_escallate_ring_event() -	escallate or add as appropriate
+ * iio_push_or_escallate_ring_event() -	escalate or add as appropriate
+ * @ring_buf:		ring buffer that is the event source
+ * @event_code:		event indentification code
+ * @timestamp:		time of event
  *
- * Typical usecase is to escallate a 50% ring full to 75% full if noone has yet
+ * Typical usecase is to escalate a 50% ring full to 75% full if noone has yet
  * read the first event. Clearly the 50% full is no longer of interest in
  * typical use case.
  **/
@@ -37,10 +40,6 @@
 
 /**
  * struct iio_ring_access_funcs - access functions for ring buffers.
- * @create:		perform allocation
- * @init:		get ring buffer ready for use
- * @_exit:		reverse steps in init
- * @_free:		deallocate ring buffer
  * @mark_in_use:	reference counting, typically to prevent module removal
  * @unmark_in_use:	reduce reference count when no longer using ring buffer
  * @store_to:		actually store stuff to the ring buffer
@@ -60,7 +59,7 @@
  *
  * The purpose of this structure is to make the ring buffer element
  * modular as event for a given driver, different usecases may require
- * different ring designs (space efficiency vs speed for example.
+ * different ring designs (space efficiency vs speed for example).
  *
  * It is worth noting that a given ring implementation may only support a small
  * proportion of these functions.  The core code 'should' cope fine with any of
@@ -91,23 +90,25 @@
 
 /**
  * struct iio_ring_buffer - general ring buffer structure
- * @length:		[DEVICE]number of datums in ring
- * @bpd:		[DEVICE]size of individual datum including timestamp
- * @loopcount:		[INTERN]number of times the ring has looped
- * @access_minor_name:	[INTERN]store of name of the access chrdev minor number
- *			sysfs attribute
- * @access_handler:	[INTERN]chrdev access handling
- * @event_minor_name:	[INTERN]store of name of the event chrdev minor number
- *			sysfs attribute
- * @ev_int:		[INTERN]chrdev interface for the event chrdev
- * @shared_ev_pointer:	[INTERN]the shared event pointer to allow escalation of
+ * @dev:		ring buffer device struct
+ * @access_dev:		system device struct for the chrdev
+ * @indio_dev:		industrial I/O device structure
+ * @owner:		module that owns the ring buffer (for ref counting)
+ * @id:			unique id number
+ * @access_id:		device id number
+ * @length:		[DEVICE] number of datums in ring
+ * @bpd:		[DEVICE] size of individual datum including timestamp
+ * @loopcount:		[INTERN] number of times the ring has looped
+ * @access_handler:	[INTERN] chrdev access handling
+ * @ev_int:		[INTERN] chrdev interface for the event chrdev
+ * @shared_ev_pointer:	[INTERN] the shared event pointer to allow escalation of
  *			events
- * @ring_access:	[DRIVER]ring access functions associated with the
+ * @access:		[DRIVER] ring access functions associated with the
  *			implementation.
- * @ring_prenable:	[DRIVER] function to run prior to marking ring enabled
- * @ring_postenable:	[DRIVER] function to run after marking ring enabled
- * @ring_predisable:	[DRIVER] function to run prior to marking ring disabled
- * @ring_postdisable:	[DRIVER] function to run after marking ring disabled
+ * @preenable:		[DRIVER] function to run prior to marking ring enabled
+ * @postenable:		[DRIVER] function to run after marking ring enabled
+ * @predisable:		[DRIVER] function to run prior to marking ring disabled
+ * @postdisable:	[DRIVER] function to run after marking ring disabled
   **/
 struct iio_ring_buffer {
 	struct device dev;
@@ -133,7 +134,10 @@
 			  struct iio_dev *dev_info);
 
 /**
- * __iio_init_ring_buffer() - initialize common elements of ring buffers.
+ * __iio_init_ring_buffer() - initialize common elements of ring buffers
+ * @ring:		ring buffer that is the event source
+ * @bytes_per_datum:	size of individual datum including timestamp
+ * @length:		number of datums in ring
  **/
 static inline void __iio_init_ring_buffer(struct iio_ring_buffer *ring,
 				 int bytes_per_datum, int length)
@@ -171,7 +175,11 @@
 	container_of(_dev_attr, struct iio_scan_el, dev_attr);
 
 /**
- * iio_scan_el_store() - sysfs scan element selection interface.
+ * iio_scan_el_store() - sysfs scan element selection interface
+ * @dev: the target device
+ * @attr: the device attribute that is being processed
+ * @buf: input from userspace
+ * @len: length of input
  *
  * A generic function used to enable various scan elements.  In some
  * devices explicit read commands for each channel mean this is merely
@@ -184,12 +192,15 @@
 			  const char *buf, size_t len);
 /**
  * iio_scal_el_show() -	sysfs interface to query whether a scan element is
- *			is enabled or not.
+ *			is enabled or not
+ * @dev: the target device
+ * @attr: the device attribute that is being processed
+ * @buf: output buffer
  **/
 ssize_t iio_scan_el_show(struct device *dev, struct device_attribute *attr,
 			 char *buf);
 /**
- * IIO_SCAN_EL: - declare and initialize a scan element without control func
+ * IIO_SCAN_EL - declare and initialize a scan element without control func
  * @_name:	identifying name. Resulting struct is iio_scan_el_##_name,
  *		sysfs element, scan_en_##_name.
  * @_number:	unique id number for the scan element.
@@ -214,8 +225,14 @@
 ssize_t iio_scan_el_ts_show(struct device *dev, struct device_attribute *attr,
 			    char *buf);
 /**
- * IIO_SCAN_EL_C: - declare and initialize a scan element with a control func
+ * IIO_SCAN_EL_C - declare and initialize a scan element with a control func
  *
+ * @_name:	identifying name. Resulting struct is iio_scan_el_##_name,
+ *		sysfs element, scan_en_##_name.
+ * @_number:	unique id number for the scan element.
+ * @_bits:	number of bits in the scan element result (used in mixed bit
+ *		length devices).
+ * @_label:	indentification variable used by drivers.  Often a reg address.
  * @_controlfunc: function used to notify hardware of whether state changes
  **/
 #define IIO_SCAN_EL_C(_name, _number, _bits, _label, _controlfunc)	\
@@ -230,7 +247,7 @@
 		.set_state = _controlfunc,				\
 	}
 /**
- * IIO_SCAN_EL_TIMESTAMP: - declare a special scan element for timestamps
+ * IIO_SCAN_EL_TIMESTAMP - declare a special scan element for timestamps
  *
  * Odd one out. Handled slightly differently from other scan elements.
  **/
diff --git a/drivers/staging/iio/ring_sw.h b/drivers/staging/iio/ring_sw.h
index ae70ee0..f0b86f0 100644
--- a/drivers/staging/iio/ring_sw.h
+++ b/drivers/staging/iio/ring_sw.h
@@ -36,52 +36,65 @@
 #if defined CONFIG_IIO_SW_RING || defined CONFIG_IIO_SW_RING_MODULE
 
 /**
- * iio_create_sw_rb() software ring buffer allocation
+ * iio_create_sw_rb() - software ring buffer allocation
  * @r:		pointer to ring buffer pointer
  **/
 int iio_create_sw_rb(struct iio_ring_buffer **r);
 
 /**
- * iio_init_sw_rb() initialize the software ring buffer
+ * iio_init_sw_rb() - initialize the software ring buffer
  * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call.
+ *		iio_create_sw_rb call
+ * @indio_dev:		industrial I/O device structure
  **/
 int iio_init_sw_rb(struct iio_ring_buffer *r, struct iio_dev *indio_dev);
+
 /**
- * iio_exit_sw_rb() reverse what was done in iio_init_sw_rb
+ * iio_exit_sw_rb() - reverse what was done in iio_init_sw_rb
+ * @r:		pointer to a software ring buffer created by an
+ *		iio_create_sw_rb call
  **/
 void iio_exit_sw_rb(struct iio_ring_buffer *r);
 
 /**
- * iio_free_sw_rb() free memory occupied by the core ring buffer struct
+ * iio_free_sw_rb() - free memory occupied by the core ring buffer struct
+ * @r:		pointer to a software ring buffer created by an
+ *		iio_create_sw_rb call
  **/
 void iio_free_sw_rb(struct iio_ring_buffer *r);
 
 /**
- * iio_mark_sw_rb_in_use() reference counting to prevent incorrect chances
+ * iio_mark_sw_rb_in_use() - reference counting to prevent incorrect chances
+ * @r:		pointer to a software ring buffer created by an
+ *		iio_create_sw_rb call
  **/
 void iio_mark_sw_rb_in_use(struct iio_ring_buffer *r);
 
 /**
- *  iio_unmark_sw_rb_in_use() notify the ring buffer that we don't care anymore
+ *  iio_unmark_sw_rb_in_use() - notify the ring buffer that we don't care anymore
+ * @r:		pointer to a software ring buffer created by an
+ *		iio_create_sw_rb call
  **/
 void iio_unmark_sw_rb_in_use(struct iio_ring_buffer *r);
 
 /**
- * iio_read_last_from_sw_rb() attempt to read the last stored datum from the rb
+ * iio_read_last_from_sw_rb() - attempt to read the last stored datum from the rb
+ * @r:		pointer to a software ring buffer created by an
+ *		iio_create_sw_rb call
+ * @data:	where to store the last datum
  **/
 int iio_read_last_from_sw_rb(struct iio_ring_buffer *r, u8 *data);
 
 /**
- * iio_store_to_sw_rb() store a new datum to the ring buffer
- * @rb:	pointer to ring buffer instance
- * @data:	the datum to be stored including timestamp if relevant.
- * @timestamp:	timestamp which will be attached to buffer events if relevant.
+ * iio_store_to_sw_rb() - store a new datum to the ring buffer
+ * @r:		pointer to ring buffer instance
+ * @data:	the datum to be stored including timestamp if relevant
+ * @timestamp:	timestamp which will be attached to buffer events if relevant
  **/
 int iio_store_to_sw_rb(struct iio_ring_buffer *r, u8 *data, s64 timestamp);
 
 /**
- * iio_rip_sw_rb() attempt to read data from the ring buffer
+ * iio_rip_sw_rb() - attempt to read data from the ring buffer
  * @r:			ring buffer instance
  * @count:		number of datum's to try and read
  * @data:		where the data will be stored.
@@ -94,38 +107,53 @@
 		  int *dead_offset);
 
 /**
- * iio_request_update_sw_rb() update params if update needed
+ * iio_request_update_sw_rb() - update params if update needed
+ * @r:		pointer to a software ring buffer created by an
+ *		iio_create_sw_rb call
  **/
 int iio_request_update_sw_rb(struct iio_ring_buffer *r);
 
 /**
- * iio_mark_update_needed_sw_rb() tell the ring buffer it needs a param update
+ * iio_mark_update_needed_sw_rb() - tell the ring buffer it needs a param update
+ * @r:		pointer to a software ring buffer created by an
+ *		iio_create_sw_rb call
  **/
 int iio_mark_update_needed_sw_rb(struct iio_ring_buffer *r);
 
 
 /**
- * iio_get_bpd_sw_rb() get the datum size in bytes
+ * iio_get_bpd_sw_rb() - get the datum size in bytes
+ * @r:		pointer to a software ring buffer created by an
+ *		iio_create_sw_rb call
  **/
 int iio_get_bpd_sw_rb(struct iio_ring_buffer *r);
 
 /**
- * iio_set_bpd_sw_rb() set the datum size in bytes
+ * iio_set_bpd_sw_rb() - set the datum size in bytes
+ * @r:		pointer to a software ring buffer created by an
+ *		iio_create_sw_rb call
+ * @bpd:	bytes per datum value
  **/
 int iio_set_bpd_sw_rb(struct iio_ring_buffer *r, size_t bpd);
 
 /**
- * iio_get_length_sw_rb() get how many datums the rb may contain
+ * iio_get_length_sw_rb() - get how many datums the rb may contain
+ * @r:		pointer to a software ring buffer created by an
+ *		iio_create_sw_rb call
  **/
 int iio_get_length_sw_rb(struct iio_ring_buffer *r);
 
 /**
- * iio_set_length_sw_rb() set how many datums the rb may contain
+ * iio_set_length_sw_rb() - set how many datums the rb may contain
+ * @r:		pointer to a software ring buffer created by an
+ *		iio_create_sw_rb call
+ * @length:	max number of data items for the ring buffer
  **/
 int iio_set_length_sw_rb(struct iio_ring_buffer *r, int length);
 
 /**
- * iio_ring_sw_register_funcs() helper function to set up rb access
+ * iio_ring_sw_register_funcs() - helper function to set up rb access
+ * @ra:		pointer to @iio_ring_access_funcs
  **/
 static inline void iio_ring_sw_register_funcs(struct iio_ring_access_funcs *ra)
 {
diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h
index bfe4055..e501e13 100644
--- a/drivers/staging/iio/sysfs.h
+++ b/drivers/staging/iio/sysfs.h
@@ -15,7 +15,7 @@
 #include "iio.h"
 
 /**
- * struct iio_event_attribute - event control attribute
+ * struct iio_event_attr - event control attribute
  * @dev_attr:	underlying device attribute
  * @mask:	mask for the event when detecting
  * @listel:	list header to allow addition to list of event handlers
@@ -54,6 +54,7 @@
  * struct iio_dev_attr - iio specific device attribute
  * @dev_attr:	underlying device attribute
  * @address:	associated register address
+ * @val2:	secondary attribute value
  */
 struct iio_dev_attr {
 	struct device_attribute dev_attr;
@@ -71,6 +72,8 @@
 /**
  * struct iio_const_attr - constant device specific attribute
  *                         often used for things like available modes
+ * @string:	attribute string
+ * @dev_attr:	underlying device attribute
  */
 struct iio_const_attr {
 	const char *string;
@@ -80,7 +83,7 @@
 #define to_iio_const_attr(_dev_attr) \
 	container_of(_dev_attr, struct iio_const_attr, dev_attr)
 
-/* Some attributes will be hard coded (device dependant) and not require an
+/* Some attributes will be hard coded (device dependent) and not require an
    address, in these cases pass a negative */
 #define IIO_ATTR(_name, _mode, _show, _store, _addr)		\
 	{ .dev_attr = __ATTR(_name, _mode, _show, _store),	\
@@ -108,102 +111,130 @@
 /* Generic attributes of onetype or another */
 
 /**
- * IIO_DEV_ATTR_REG: revision number for the device
+ * IIO_DEV_ATTR_REV - revision number for the device
+ * @_show: output method for the attribute
  *
  * Very much device dependent.
  **/
 #define IIO_DEV_ATTR_REV(_show)			\
 	IIO_DEVICE_ATTR(revision, S_IRUGO, _show, NULL, 0)
+
 /**
- * IIO_DEV_ATTR_NAME: chip type dependant identifier
+ * IIO_DEV_ATTR_NAME - chip type dependent identifier
+ * @_show: output method for the attribute
  **/
 #define IIO_DEV_ATTR_NAME(_show)				\
 	IIO_DEVICE_ATTR(name, S_IRUGO, _show, NULL, 0)
 
 /**
- * IIO_DEV_ATTR_SAMP_FREQ: sets any internal clock frequency
+ * IIO_DEV_ATTR_SAMP_FREQ - sets any internal clock frequency
+ * @_mode: sysfs file mode/permissions
+ * @_show: output method for the attribute
+ * @_store: input method for the attribute
  **/
 #define IIO_DEV_ATTR_SAMP_FREQ(_mode, _show, _store)			\
 	IIO_DEVICE_ATTR(sampling_frequency, _mode, _show, _store, 0)
 
 /**
- * IIO_DEV_ATTR_AVAIL_SAMP_FREQ: list available sampling frequencies.
+ * IIO_DEV_ATTR_AVAIL_SAMP_FREQ - list available sampling frequencies
+ * @_show: output method for the attribute
  *
- * May be mode dependant on some devices
+ * May be mode dependent on some devices
  **/
 #define IIO_DEV_ATTR_AVAIL_SAMP_FREQ(_show)				\
 	IIO_DEVICE_ATTR(available_sampling_frequency, S_IRUGO, _show, NULL, 0)
 
 /**
- * IIO_DEV_ATTR_CONST_AVAIL_SAMP_FREQ: list available sampling frequencies.
+ * IIO_CONST_ATTR_AVAIL_SAMP_FREQ - list available sampling frequencies
+ * @_string: frequency string for the attribute
  *
  * Constant version
  **/
 #define IIO_CONST_ATTR_AVAIL_SAMP_FREQ(_string)	\
 	IIO_CONST_ATTR(available_sampling_frequency, _string)
+
 /**
- * IIO_DEV_ATTR_SCAN_MODE: select a scan mode
+ * IIO_DEV_ATTR_SCAN_MODE - select a scan mode
+ * @_mode: sysfs file mode/permissions
+ * @_show: output method for the attribute
+ * @_store: input method for the attribute
  *
  * This is used when only certain combinations of inputs may be read in one
  * scan.
  **/
 #define IIO_DEV_ATTR_SCAN_MODE(_mode, _show, _store)		\
 	IIO_DEVICE_ATTR(scan_mode, _mode, _show, _store, 0)
+
 /**
- * IIO_DEV_ATTR_AVAIL_SCAN_MODES: list available scan modes
+ * IIO_DEV_ATTR_AVAIL_SCAN_MODES - list available scan modes
+ * @_show: output method for the attribute
  **/
 #define IIO_DEV_ATTR_AVAIL_SCAN_MODES(_show)				\
 	IIO_DEVICE_ATTR(available_scan_modes, S_IRUGO, _show, NULL, 0)
 
 /**
- * IIO_DEV_ATTR_SCAN: result of scan of multiple channels
+ * IIO_DEV_ATTR_SCAN - result of scan of multiple channels
+ * @_show: output method for the attribute
  **/
 #define IIO_DEV_ATTR_SCAN(_show)		\
 	IIO_DEVICE_ATTR(scan, S_IRUGO, _show, NULL, 0);
 
 /**
- * IIO_DEV_ATTR_INPUT: direct read of a single input channel
+ * IIO_DEV_ATTR_INPUT - direct read of a single input channel
+ * @_number: input channel number
+ * @_show: output method for the attribute
  **/
 #define IIO_DEV_ATTR_INPUT(_number, _show)				\
 	IIO_DEVICE_ATTR(in##_number, S_IRUGO, _show, NULL, _number)
 
-
 /**
- * IIO_DEV_ATTR_SW_RING_ENABLE: enable software ring buffer
+ * IIO_DEV_ATTR_SW_RING_ENABLE - enable software ring buffer
+ * @_show: output method for the attribute
+ * @_store: input method for the attribute
  *
- * Success may be dependant on attachment of trigger previously
+ * Success may be dependent on attachment of trigger previously.
  **/
 #define IIO_DEV_ATTR_SW_RING_ENABLE(_show, _store)			\
 	IIO_DEVICE_ATTR(sw_ring_enable, S_IRUGO | S_IWUSR, _show, _store, 0)
 
 /**
- * IIO_DEV_ATTR_HW_RING_ENABLE: enable hardware ring buffer
+ * IIO_DEV_ATTR_HW_RING_ENABLE - enable hardware ring buffer
+ * @_show: output method for the attribute
+ * @_store: input method for the attribute
  *
- * This is a different attribute from the software one as one can invision
+ * This is a different attribute from the software one as one can envision
  * schemes where a combination of the two may be used.
  **/
 #define IIO_DEV_ATTR_HW_RING_ENABLE(_show, _store)			\
 	IIO_DEVICE_ATTR(hw_ring_enable, S_IRUGO | S_IWUSR, _show, _store, 0)
 
 /**
- * IIO_DEV_ATTR_BPSE: set number of bits per scan element
+ * IIO_DEV_ATTR_BPSE - set number of bits per scan element
+ * @_mode: sysfs file mode/permissions
+ * @_show: output method for the attribute
+ * @_store: input method for the attribute
  **/
 #define IIO_DEV_ATTR_BPSE(_mode, _show, _store)		\
 	IIO_DEVICE_ATTR(bpse, _mode, _show, _store, 0)
 
 /**
- * IIO_DEV_ATTR_BPSE_AVAILABLE: no of bits per scan element supported
+ * IIO_DEV_ATTR_BPSE_AVAILABLE - number of bits per scan element supported
+ * @_show: output method for the attribute
  **/
 #define IIO_DEV_ATTR_BPSE_AVAILABLE(_show)				\
 	IIO_DEVICE_ATTR(bpse_available, S_IRUGO, _show, NULL, 0)
 
 /**
- * IIO_DEV_ATTR_TEMP: many sensors have auxiliary temperature sensors
+ * IIO_DEV_ATTR_TEMP - many sensors have auxiliary temperature sensors
+ * @_show: output method for the attribute
  **/
 #define IIO_DEV_ATTR_TEMP(_show)			\
 	IIO_DEVICE_ATTR(temp, S_IRUGO, _show, NULL, 0)
+
 /**
- * IIO_EVENT_SH: generic shared event handler
+ * IIO_EVENT_SH - generic shared event handler
+ * @_name: event name
+ * @_handler: handler function to be called
  *
  * This is used in cases where more than one event may result from a single
  * handler.  Often the case that some alarm register must be read and multiple
@@ -221,8 +252,14 @@
 			.prev = &iio_event_##_name.list,		\
 		},							\
 	};
+
 /**
- * IIO_EVENT_ATTR_SH: generic shared event attribute
+ * IIO_EVENT_ATTR_SH - generic shared event attribute
+ * @_name: event name
+ * @_ev_list: event handler list
+ * @_show: output method for the attribute
+ * @_store: input method for the attribute
+ * @_mask: mask used when detecting the event
  *
  * An attribute with an associated IIO_EVENT_SH
  **/
@@ -235,7 +272,12 @@
 	    .listel = &_ev_list };
 
 /**
- * IIO_EVENT_ATTR: non shared event attribute
+ * IIO_EVENT_ATTR - non-shared event attribute
+ * @_name: event name
+ * @_show: output method for the attribute
+ * @_store: input method for the attribute
+ * @_mask: mask used when detecting the event
+ * @_handler: handler function to be called
  **/
 #define IIO_EVENT_ATTR(_name, _show, _store, _mask, _handler)		\
 	static struct iio_event_handler_list				\
@@ -251,10 +293,14 @@
 	    .listel = &iio_event_##_name };				\
 
 /**
- * IIO_EVENT_ATTR_DATA_RDY: event driven by data ready signal
+ * IIO_EVENT_ATTR_DATA_RDY - event driven by data ready signal
+ * @_show: output method for the attribute
+ * @_store: input method for the attribute
+ * @_mask: mask used when detecting the event
+ * @_handler: handler function to be called
  *
  * Not typically implemented in devices where full triggering support
- * has been implemented
+ * has been implemented.
  **/
 #define IIO_EVENT_ATTR_DATA_RDY(_show, _store, _mask, _handler) \
 	IIO_EVENT_ATTR(data_rdy, _show, _store, _mask, _handler)
@@ -269,19 +315,31 @@
 #define IIO_EVENT_CODE_DEVICE_SPECIFIC	1000
 
 /**
- * IIO_EVENT_ATTR_RING_50_FULL: ring buffer event to indicate 50% full
+ * IIO_EVENT_ATTR_RING_50_FULL - ring buffer event to indicate 50% full
+ * @_show: output method for the attribute
+ * @_store: input method for the attribute
+ * @_mask: mask used when detecting the event
+ * @_handler: handler function to be called
  **/
 #define IIO_EVENT_ATTR_RING_50_FULL(_show, _store, _mask, _handler)	\
 	IIO_EVENT_ATTR(ring_50_full, _show, _store, _mask, _handler)
 
 /**
- * IIO_EVENT_ATTR_RING_50_FULL_SH: shared ring event to indicate 50% full
+ * IIO_EVENT_ATTR_RING_50_FULL_SH - shared ring event to indicate 50% full
+ * @_evlist: event handler list
+ * @_show: output method for the attribute
+ * @_store: input method for the attribute
+ * @_mask: mask used when detecting the event
  **/
 #define IIO_EVENT_ATTR_RING_50_FULL_SH(_evlist, _show, _store, _mask)	\
 	IIO_EVENT_ATTR_SH(ring_50_full, _evlist, _show, _store, _mask)
 
 /**
- * IIO_EVENT_ATTR_RING_75_FULL_SH: shared ring event to indicate 75% full
+ * IIO_EVENT_ATTR_RING_75_FULL_SH - shared ring event to indicate 75% full
+ * @_evlist: event handler list
+ * @_show: output method for the attribute
+ * @_store: input method for the attribute
+ * @_mask: mask used when detecting the event
  **/
 #define IIO_EVENT_ATTR_RING_75_FULL_SH(_evlist, _show, _store, _mask)	\
 	IIO_EVENT_ATTR_SH(ring_75_full, _evlist, _show, _store, _mask)
diff --git a/drivers/staging/iio/trigger.h b/drivers/staging/iio/trigger.h
index 8284098..784e7b6 100644
--- a/drivers/staging/iio/trigger.h
+++ b/drivers/staging/iio/trigger.h
@@ -19,16 +19,18 @@
  * @id:			[INTERN] unique id number
  * @name:		[DRIVER] unique name
  * @dev:		[DRIVER] associated device (if relevant)
- * @sysfs_dev:		[INTERN] sysfs relevant device
  * @private_data:	[DRIVER] device specific data
  * @list:		[INTERN] used in maintenance of global trigger list
  * @alloc_list:		[DRIVER] used for driver specific trigger list
- * @poll_func_list_lock:[INTERN] protection of the polling function list
+ * @pollfunc_list_lock:	[INTERN] protection of the polling function list
  * @pollfunc_list:	[INTERN] list of functions to run on trigger.
  * @control_attrs:	[DRIVER] sysfs attributes relevant to trigger type
- * @set_trigger_state:	[DRIVER] switch on/off the trigger on demand
  * @timestamp:		[INTERN] timestamp usesd by some trigs (e.g. datardy)
  * @owner:		[DRIVER] used to monitor usage count of the trigger.
+ * @use_count:		use count for the trigger
+ * @set_trigger_state:	[DRIVER] switch on/off the trigger on demand
+ * @try_reenable:	function to reenable the trigger when the
+ *			use count is zero (may be NULL)
  **/
 struct iio_trigger {
 	int				id;
@@ -68,6 +70,9 @@
 
 /**
  * iio_trigger_read_name() - sysfs access function to get the trigger name
+ * @dev: the system device
+ * @attr: device attributes for the device
+ * @buf: output buffer to store the trigger name
  **/
 ssize_t iio_trigger_read_name(struct device *dev,
 			      struct device_attribute *attr,
@@ -79,6 +84,8 @@
 
 /**
  * iio_trigger_find_by_name() - search global trigger list
+ * @name: trigger name to search for
+ * @len: trigger name string length to compare
  **/
 struct iio_trigger *iio_trigger_find_by_name(const char *name, size_t len);
 
@@ -90,32 +97,35 @@
 
 /**
  * iio_trigger_unregister() - unregister a trigger from the core
+ * @trig_info:	trigger to be unregistered
  **/
 void iio_trigger_unregister(struct iio_trigger *trig_info);
 
 /**
  * iio_trigger_attach_poll_func() - add a function pair to be run on trigger
  * @trig:	trigger to which the function pair are being added
- * @pf:	poll function pair
+ * @pf:		poll function pair
  **/
 int iio_trigger_attach_poll_func(struct iio_trigger *trig,
 				 struct iio_poll_func *pf);
 
 /**
  * iio_trigger_dettach_poll_func() -	remove function pair from those to be
- *					run on trigger.
- * @trig:	trigger from which the function is being removed.
+ *					run on trigger
+ * @trig:	trigger from which the function is being removed
  * @pf:		poll function pair
  **/
 int iio_trigger_dettach_poll_func(struct iio_trigger *trig,
 				  struct iio_poll_func *pf);
 
 /**
- * iio_trigger_poll() - called on a trigger occuring
+ * iio_trigger_poll() - called on a trigger occurring
+ * @trig: trigger which occurred
+ *
  * Typically called in relevant hardware interrupt handler.
  **/
-void iio_trigger_poll(struct iio_trigger *);
-void iio_trigger_notify_done(struct iio_trigger *);
+void iio_trigger_poll(struct iio_trigger *trig);
+void iio_trigger_notify_done(struct iio_trigger *trig);
 
 /**
  * struct iio_poll_func - poll function pair
@@ -127,11 +137,10 @@
  *				control on sensor supporting it.
  * @poll_func_main:		function in here is run after all immediates.
  *				Reading from sensor etc typically involves
- *				scheduling
- *				from here.
+ *				scheduling from here.
  *
- * The two stage approach used here only important when multiple sensors are
- * being triggered by a single trigger. This really comes into it's own with
+ * The two stage approach used here is only important when multiple sensors are
+ * being triggered by a single trigger. This really comes into its own with
  * simultaneous sampling devices where a simple latch command can be used to
  * make the device store the values on all inputs.
  **/
diff --git a/drivers/staging/iio/trigger/Kconfig b/drivers/staging/iio/trigger/Kconfig
index fdd9301..d842a58 100644
--- a/drivers/staging/iio/trigger/Kconfig
+++ b/drivers/staging/iio/trigger/Kconfig
@@ -9,13 +9,13 @@
 	tristate "Periodic RTC triggers"
 	depends on RTC_CLASS
 	help
-	    Provides support for using periodic capable real time
-	    clocks as IIO triggers.
+	  Provides support for using periodic capable real time
+	  clocks as IIO triggers.
 
 config IIO_GPIO_TRIGGER
 	tristate "GPIO trigger"
 	depends on GENERIC_GPIO
 	help
-	    Provides support for using GPIO pins as IIO triggers.
+	  Provides support for using GPIO pins as IIO triggers.
 
 endif # IIO_TRIGGER
diff --git a/drivers/staging/iio/trigger_consumer.h b/drivers/staging/iio/trigger_consumer.h
index 4c7f527..a02d70b 100644
--- a/drivers/staging/iio/trigger_consumer.h
+++ b/drivers/staging/iio/trigger_consumer.h
@@ -10,12 +10,13 @@
 
 #ifdef CONFIG_IIO_TRIGGER
 /**
- * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers.
+ * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers
  * @dev_info: iio_dev associated with the device that will consume the trigger
  **/
 int iio_device_register_trigger_consumer(struct iio_dev *dev_info);
+
 /**
- * iio_device_unregister_trigger_consumer() - reverse the registration process.
+ * iio_device_unregister_trigger_consumer() - reverse the registration process
  * @dev_info: iio_dev associated with the device that consumed the trigger
  **/
 int iio_device_unregister_trigger_consumer(struct iio_dev *dev_info);
@@ -23,13 +24,14 @@
 #else
 
 /**
- * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers.
+ * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers
  * @dev_info: iio_dev associated with the device that will consume the trigger
  **/
 int iio_device_register_trigger_consumer(struct iio_dev *dev_info)
 {
 	return 0;
 };
+
 /**
  * iio_device_unregister_trigger_consumer() - reverse the registration process
  * @dev_info: iio_dev associated with the device that consumed the trigger
diff --git a/drivers/staging/line6/capture.c b/drivers/staging/line6/capture.c
index ea2060b..fd4890d 100644
--- a/drivers/staging/line6/capture.c
+++ b/drivers/staging/line6/capture.c
@@ -20,7 +20,6 @@
 #include "pod.h"
 #include "capture.h"
 
-
 /*
 	Find a free URB and submit it.
 */
@@ -33,7 +32,8 @@
 	struct urb *urb_in;
 
 	spin_lock_irqsave(&line6pcm->lock_audio_in, flags);
-	index = find_first_zero_bit(&line6pcm->active_urb_in, LINE6_ISO_BUFFERS);
+	index =
+	    find_first_zero_bit(&line6pcm->active_urb_in, LINE6_ISO_BUFFERS);
 
 	if (index >= LINE6_ISO_BUFFERS) {
 		spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
@@ -45,20 +45,24 @@
 	urb_size = 0;
 
 	for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
-		struct usb_iso_packet_descriptor *fin = &urb_in->iso_frame_desc[i];
+		struct usb_iso_packet_descriptor *fin =
+		    &urb_in->iso_frame_desc[i];
 		fin->offset = urb_size;
 		fin->length = line6pcm->max_packet_size;
 		urb_size += line6pcm->max_packet_size;
 	}
 
-	urb_in->transfer_buffer = line6pcm->buffer_in + index * LINE6_ISO_PACKETS * line6pcm->max_packet_size;
+	urb_in->transfer_buffer =
+	    line6pcm->buffer_in +
+	    index * LINE6_ISO_PACKETS * line6pcm->max_packet_size;
 	urb_in->transfer_buffer_length = urb_size;
 	urb_in->context = substream;
 
 	if (usb_submit_urb(urb_in, GFP_ATOMIC) == 0)
 		set_bit(index, &line6pcm->active_urb_in);
 	else
-		dev_err(s2m(substream), "URB in #%d submission failed\n", index);
+		dev_err(s2m(substream), "URB in #%d submission failed\n",
+			index);
 
 	spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
 	return 0;
@@ -143,7 +147,8 @@
 	int frames;
 	unsigned long flags;
 
-	struct snd_pcm_substream *substream = (struct snd_pcm_substream *)urb->context;
+	struct snd_pcm_substream *substream =
+	    (struct snd_pcm_substream *)urb->context;
 	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
 	const int bytes_per_frame = line6pcm->properties->bytes_per_frame;
 	struct snd_pcm_runtime *runtime = substream->runtime;
@@ -155,8 +160,11 @@
 
 #if DO_DUMP_PCM_RECEIVE
 	for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
-		struct usb_iso_packet_descriptor *fout = &urb->iso_frame_desc[i];
-		line6_write_hexdump(line6pcm->line6, 'C', urb->transfer_buffer + fout->offset, fout->length);
+		struct usb_iso_packet_descriptor *fout =
+		    &urb->iso_frame_desc[i];
+		line6_write_hexdump(line6pcm->line6, 'C',
+				    urb->transfer_buffer + fout->offset,
+				    fout->length);
 	}
 #endif
 
@@ -179,25 +187,40 @@
 		if (fsize > 0) {
 			frames = fsize / bytes_per_frame;
 
-			if (line6pcm->pos_in_done + frames > runtime->buffer_size) {
+			if (line6pcm->pos_in_done + frames >
+			    runtime->buffer_size) {
 				/*
-					The transferred area goes over buffer boundary,
-					copy two separate chunks.
-				*/
+				   The transferred area goes over buffer
+				   boundary, copy two separate chunks.
+				 */
 				int len;
-				len = runtime->buffer_size - line6pcm->pos_in_done;
+				len =
+				    runtime->buffer_size -
+				    line6pcm->pos_in_done;
 
 				if (len > 0) {
-					memcpy(runtime->dma_area + line6pcm->pos_in_done * bytes_per_frame, fbuf, len * bytes_per_frame);
-					memcpy(runtime->dma_area, fbuf + len * bytes_per_frame, (frames - len) * bytes_per_frame);
-				} else
-					dev_err(s2m(substream), "driver bug: len = %d\n", len);  /* this is somewhat paranoid */
+					memcpy(runtime->dma_area +
+					       line6pcm->pos_in_done *
+					       bytes_per_frame, fbuf,
+					       len * bytes_per_frame);
+					memcpy(runtime->dma_area,
+					       fbuf + len * bytes_per_frame,
+					       (frames -
+						len) * bytes_per_frame);
+				} else {
+					/* this is somewhat paranoid */
+					dev_err(s2m(substream),
+						"driver bug: len = %d\n", len);
+				}
 			} else {
 				/* copy single chunk */
-				memcpy(runtime->dma_area + line6pcm->pos_in_done * bytes_per_frame, fbuf, fsize * bytes_per_frame);
+				memcpy(runtime->dma_area +
+				       line6pcm->pos_in_done * bytes_per_frame,
+				       fbuf, fsize * bytes_per_frame);
 			}
 
-			if ((line6pcm->pos_in_done += frames) >= runtime->buffer_size)
+			line6pcm->pos_in_done += frames;
+			if (line6pcm->pos_in_done >= runtime->buffer_size)
 				line6pcm->pos_in_done -= runtime->buffer_size;
 		}
 	}
@@ -212,7 +235,8 @@
 	if (!shutdown) {
 		submit_audio_in_urb(substream);
 
-		if ((line6pcm->bytes_in += length) >= line6pcm->period_in) {
+		line6pcm->bytes_in += length;
+		if (line6pcm->bytes_in >= line6pcm->period_in) {
 			line6pcm->bytes_in -= line6pcm->period_in;
 			snd_pcm_period_elapsed(substream);
 		}
@@ -228,7 +252,8 @@
 
 	err = snd_pcm_hw_constraint_ratdens(runtime, 0,
 					    SNDRV_PCM_HW_PARAM_RATE,
-					    (&line6pcm->properties->snd_line6_rates));
+					    (&line6pcm->properties->
+					     snd_line6_rates));
 	if (err < 0)
 		return err;
 
@@ -267,7 +292,9 @@
 		return ret;
 
 	line6pcm->period_in = params_period_bytes(hw_params);
-	line6pcm->buffer_in = kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * LINE6_ISO_PACKET_SIZE_MAX, GFP_KERNEL);
+	line6pcm->buffer_in =
+	    kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
+		    LINE6_ISO_PACKET_SIZE_MAX, GFP_KERNEL);
 
 	if (!line6pcm->buffer_in) {
 		dev_err(s2m(substream), "cannot malloc buffer_in\n");
@@ -302,7 +329,8 @@
 			err = submit_audio_in_all_urbs(substream);
 
 			if (err < 0) {
-				clear_bit(BIT_RUNNING_CAPTURE, &line6pcm->flags);
+				clear_bit(BIT_RUNNING_CAPTURE,
+					  &line6pcm->flags);
 				return err;
 			}
 		}
@@ -332,14 +360,14 @@
 
 /* capture operators */
 struct snd_pcm_ops snd_line6_capture_ops = {
-	.open =        snd_line6_capture_open,
-	.close =       snd_line6_capture_close,
-	.ioctl =       snd_pcm_lib_ioctl,
-	.hw_params =   snd_line6_capture_hw_params,
-	.hw_free =     snd_line6_capture_hw_free,
-	.prepare =     snd_line6_prepare,
-	.trigger =     snd_line6_trigger,
-	.pointer =     snd_line6_capture_pointer,
+	.open = snd_line6_capture_open,
+	.close = snd_line6_capture_close,
+	.ioctl = snd_pcm_lib_ioctl,
+	.hw_params = snd_line6_capture_hw_params,
+	.hw_free = snd_line6_capture_hw_free,
+	.prepare = snd_line6_prepare,
+	.trigger = snd_line6_trigger,
+	.pointer = snd_line6_capture_pointer,
 };
 
 int create_audio_in_urbs(struct snd_line6_pcm *line6pcm)
@@ -351,7 +379,8 @@
 		struct urb *urb;
 
 		/* URB for audio in: */
-		urb = line6pcm->urb_audio_in[i] = usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
+		urb = line6pcm->urb_audio_in[i] =
+		    usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
 
 		if (urb == NULL) {
 			dev_err(line6pcm->line6->ifcdev, "Out of memory\n");
@@ -359,7 +388,10 @@
 		}
 
 		urb->dev = line6pcm->line6->usbdev;
-		urb->pipe = usb_rcvisocpipe(line6pcm->line6->usbdev, line6pcm->ep_audio_read & USB_ENDPOINT_NUMBER_MASK);
+		urb->pipe =
+		    usb_rcvisocpipe(line6pcm->line6->usbdev,
+				    line6pcm->
+				    ep_audio_read & USB_ENDPOINT_NUMBER_MASK);
 		urb->transfer_flags = URB_ISO_ASAP;
 		urb->start_frame = -1;
 		urb->number_of_packets = LINE6_ISO_PACKETS;
diff --git a/drivers/staging/line6/control.c b/drivers/staging/line6/control.c
index 23ad08e..0b59852 100644
--- a/drivers/staging/line6/control.c
+++ b/drivers/staging/line6/control.c
@@ -22,18 +22,18 @@
 struct device_attribute dev_attr_##_name1 = __ATTR(_name2, _mode, _show, _store)
 
 #define LINE6_PARAM_R(PREFIX, prefix, type, param) \
-static ssize_t prefix ## _get_ ## param(struct device *dev, \
+static ssize_t prefix##_get_##param(struct device *dev, \
 			struct device_attribute *attr, char *buf) \
 { \
-	return prefix ## _get_param_ ## type(dev, buf, PREFIX ## _ ## param); \
+	return prefix##_get_param_##type(dev, buf, PREFIX##_##param); \
 }
 
 #define LINE6_PARAM_RW(PREFIX, prefix, type, param) \
 LINE6_PARAM_R(PREFIX, prefix, type, param); \
-static ssize_t prefix ## _set_ ## param(struct device *dev, \
+static ssize_t prefix##_set_##param(struct device *dev, \
 		struct device_attribute *attr, const char *buf, size_t count) \
 { \
-	return prefix ## _set_param_ ## type(dev, buf, count, PREFIX ## _ ## param); \
+	return prefix##_set_param_##type(dev, buf, count, PREFIX##_##param); \
 }
 
 #define POD_PARAM_R(type, param) LINE6_PARAM_R(POD, pod, type, param)
@@ -41,7 +41,6 @@
 #define VARIAX_PARAM_R(type, param) LINE6_PARAM_R(VARIAX, variax, type, param)
 #define VARIAX_PARAM_RW(type, param) LINE6_PARAM_RW(VARIAX, variax, type, param)
 
-
 static ssize_t pod_get_param_int(struct device *dev, char *buf, int param)
 {
 	struct usb_interface *interface = to_usb_interface(dev);
@@ -52,11 +51,18 @@
 	return sprintf(buf, "%d\n", pod->prog_data.control[param]);
 }
 
-static ssize_t pod_set_param_int(struct device *dev, const char *buf, size_t count, int param)
+static ssize_t pod_set_param_int(struct device *dev, const char *buf,
+				 size_t count, int param)
 {
 	struct usb_interface *interface = to_usb_interface(dev);
 	struct usb_line6_pod *pod = usb_get_intfdata(interface);
-	int value = simple_strtoul(buf, NULL, 10);
+	unsigned long value;
+	int retval;
+
+	retval = strict_strtoul(buf, 10, &value);
+	if (retval)
+		return retval;
+
 	pod_transmit_parameter(pod, param, value);
 	return count;
 }
@@ -74,13 +80,13 @@
 static ssize_t variax_get_param_float(struct device *dev, char *buf, int param)
 {
 	/*
-		We do our own floating point handling here since floats in the
-		kernel are problematic for at least two reasons: - many distros
-		are still shipped with binary kernels optimized for the ancient
-		80386 without FPU
-		- there isn't a printf("%f")
-		  (see http://www.kernelthread.com/publications/faq/335.html)
-	*/
+	   We do our own floating point handling here since floats in the
+	   kernel are problematic for at least two reasons: - many distros
+	   are still shipped with binary kernels optimized for the ancient
+	   80386 without FPU
+	   - there isn't a printf("%f")
+	   (see http://www.kernelthread.com/publications/faq/335.html)
+	 */
 
 	static const int BIAS = 0x7f;
 	static const int OFFSET = 0xf;
@@ -110,10 +116,13 @@
 			part_frac = (mantissa << (32 + exponent)) & 0xffffffff;
 		}
 
-		part_frac = (part_frac / ((1UL << 31) / (PRECISION / 2 * 10)) + 5) / 10;
+		part_frac =
+		    (part_frac / ((1UL << 31) / (PRECISION / 2 * 10)) + 5) / 10;
 	}
 
-	len += sprintf(buf + len, "%s%d.%03d\n", ((p[0] & 0x80) ? "-" : ""), part_int, part_frac);
+	len +=
+	    sprintf(buf + len, "%s%d.%03d\n", ((p[0] & 0x80) ? "-" : ""),
+		    part_int, part_frac);
 	return len;
 }
 
@@ -260,127 +269,246 @@
 VARIAX_PARAM_R(int, pickup_wiring);
 
 static DEVICE_ATTR(tweak, S_IWUGO | S_IRUGO, pod_get_tweak, pod_set_tweak);
-static DEVICE_ATTR(wah_position, S_IWUGO | S_IRUGO, pod_get_wah_position, pod_set_wah_position);
-static DEVICE_ATTR(compression_gain, S_IWUGO | S_IRUGO, pod_get_compression_gain, pod_set_compression_gain);
-static DEVICE_ATTR(vol_pedal_position, S_IWUGO | S_IRUGO, pod_get_vol_pedal_position, pod_set_vol_pedal_position);
-static DEVICE_ATTR(compression_threshold, S_IWUGO | S_IRUGO, pod_get_compression_threshold, pod_set_compression_threshold);
+static DEVICE_ATTR(wah_position, S_IWUGO | S_IRUGO, pod_get_wah_position,
+		   pod_set_wah_position);
+static DEVICE_ATTR(compression_gain, S_IWUGO | S_IRUGO,
+		   pod_get_compression_gain, pod_set_compression_gain);
+static DEVICE_ATTR(vol_pedal_position, S_IWUGO | S_IRUGO,
+		   pod_get_vol_pedal_position, pod_set_vol_pedal_position);
+static DEVICE_ATTR(compression_threshold, S_IWUGO | S_IRUGO,
+		   pod_get_compression_threshold,
+		   pod_set_compression_threshold);
 static DEVICE_ATTR(pan, S_IWUGO | S_IRUGO, pod_get_pan, pod_set_pan);
-static DEVICE_ATTR(amp_model_setup, S_IWUGO | S_IRUGO, pod_get_amp_model_setup, pod_set_amp_model_setup);
-static DEVICE_ATTR(amp_model, S_IWUGO | S_IRUGO, pod_get_amp_model, pod_set_amp_model);
+static DEVICE_ATTR(amp_model_setup, S_IWUGO | S_IRUGO, pod_get_amp_model_setup,
+		   pod_set_amp_model_setup);
+static DEVICE_ATTR(amp_model, S_IWUGO | S_IRUGO, pod_get_amp_model,
+		   pod_set_amp_model);
 static DEVICE_ATTR(drive, S_IWUGO | S_IRUGO, pod_get_drive, pod_set_drive);
 static DEVICE_ATTR(bass, S_IWUGO | S_IRUGO, pod_get_bass, pod_set_bass);
 static DEVICE_ATTR(mid, S_IWUGO | S_IRUGO, pod_get_mid, pod_set_mid);
 static DEVICE_ATTR(lowmid, S_IWUGO | S_IRUGO, pod_get_lowmid, pod_set_lowmid);
 static DEVICE_ATTR(treble, S_IWUGO | S_IRUGO, pod_get_treble, pod_set_treble);
-static DEVICE_ATTR(highmid, S_IWUGO | S_IRUGO, pod_get_highmid, pod_set_highmid);
-static DEVICE_ATTR(chan_vol, S_IWUGO | S_IRUGO, pod_get_chan_vol, pod_set_chan_vol);
-static DEVICE_ATTR(reverb_mix, S_IWUGO | S_IRUGO, pod_get_reverb_mix, pod_set_reverb_mix);
-static DEVICE_ATTR(effect_setup, S_IWUGO | S_IRUGO, pod_get_effect_setup, pod_set_effect_setup);
-static DEVICE_ATTR(band_1_frequency, S_IWUGO | S_IRUGO, pod_get_band_1_frequency, pod_set_band_1_frequency);
-static DEVICE_ATTR(presence, S_IWUGO | S_IRUGO, pod_get_presence, pod_set_presence);
-static DEVICE_ATTR2(treble__bass, treble, S_IWUGO | S_IRUGO, pod_get_treble__bass, pod_set_treble__bass);
-static DEVICE_ATTR(noise_gate_enable, S_IWUGO | S_IRUGO, pod_get_noise_gate_enable, pod_set_noise_gate_enable);
-static DEVICE_ATTR(gate_threshold, S_IWUGO | S_IRUGO, pod_get_gate_threshold, pod_set_gate_threshold);
-static DEVICE_ATTR(gate_decay_time, S_IWUGO | S_IRUGO, pod_get_gate_decay_time, pod_set_gate_decay_time);
-static DEVICE_ATTR(stomp_enable, S_IWUGO | S_IRUGO, pod_get_stomp_enable, pod_set_stomp_enable);
-static DEVICE_ATTR(comp_enable, S_IWUGO | S_IRUGO, pod_get_comp_enable, pod_set_comp_enable);
-static DEVICE_ATTR(stomp_time, S_IWUGO | S_IRUGO, pod_get_stomp_time, pod_set_stomp_time);
-static DEVICE_ATTR(delay_enable, S_IWUGO | S_IRUGO, pod_get_delay_enable, pod_set_delay_enable);
-static DEVICE_ATTR(mod_param_1, S_IWUGO | S_IRUGO, pod_get_mod_param_1, pod_set_mod_param_1);
-static DEVICE_ATTR(delay_param_1, S_IWUGO | S_IRUGO, pod_get_delay_param_1, pod_set_delay_param_1);
-static DEVICE_ATTR(delay_param_1_note_value, S_IWUGO | S_IRUGO, pod_get_delay_param_1_note_value, pod_set_delay_param_1_note_value);
-static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IWUGO | S_IRUGO, pod_get_band_2_frequency__bass, pod_set_band_2_frequency__bass);
-static DEVICE_ATTR(delay_param_2, S_IWUGO | S_IRUGO, pod_get_delay_param_2, pod_set_delay_param_2);
-static DEVICE_ATTR(delay_volume_mix, S_IWUGO | S_IRUGO, pod_get_delay_volume_mix, pod_set_delay_volume_mix);
-static DEVICE_ATTR(delay_param_3, S_IWUGO | S_IRUGO, pod_get_delay_param_3, pod_set_delay_param_3);
-static DEVICE_ATTR(reverb_enable, S_IWUGO | S_IRUGO, pod_get_reverb_enable, pod_set_reverb_enable);
-static DEVICE_ATTR(reverb_type, S_IWUGO | S_IRUGO, pod_get_reverb_type, pod_set_reverb_type);
-static DEVICE_ATTR(reverb_decay, S_IWUGO | S_IRUGO, pod_get_reverb_decay, pod_set_reverb_decay);
-static DEVICE_ATTR(reverb_tone, S_IWUGO | S_IRUGO, pod_get_reverb_tone, pod_set_reverb_tone);
-static DEVICE_ATTR(reverb_pre_delay, S_IWUGO | S_IRUGO, pod_get_reverb_pre_delay, pod_set_reverb_pre_delay);
-static DEVICE_ATTR(reverb_pre_post, S_IWUGO | S_IRUGO, pod_get_reverb_pre_post, pod_set_reverb_pre_post);
-static DEVICE_ATTR(band_2_frequency, S_IWUGO | S_IRUGO, pod_get_band_2_frequency, pod_set_band_2_frequency);
-static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUGO | S_IRUGO, pod_get_band_3_frequency__bass, pod_set_band_3_frequency__bass);
-static DEVICE_ATTR(wah_enable, S_IWUGO | S_IRUGO, pod_get_wah_enable, pod_set_wah_enable);
-static DEVICE_ATTR(modulation_lo_cut, S_IWUGO | S_IRUGO, pod_get_modulation_lo_cut, pod_set_modulation_lo_cut);
-static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUGO | S_IRUGO, pod_get_delay_reverb_lo_cut, pod_set_delay_reverb_lo_cut);
-static DEVICE_ATTR(volume_pedal_minimum, S_IWUGO | S_IRUGO, pod_get_volume_pedal_minimum, pod_set_volume_pedal_minimum);
-static DEVICE_ATTR(eq_pre_post, S_IWUGO | S_IRUGO, pod_get_eq_pre_post, pod_set_eq_pre_post);
-static DEVICE_ATTR(volume_pre_post, S_IWUGO | S_IRUGO, pod_get_volume_pre_post, pod_set_volume_pre_post);
-static DEVICE_ATTR(di_model, S_IWUGO | S_IRUGO, pod_get_di_model, pod_set_di_model);
-static DEVICE_ATTR(di_delay, S_IWUGO | S_IRUGO, pod_get_di_delay, pod_set_di_delay);
-static DEVICE_ATTR(mod_enable, S_IWUGO | S_IRUGO, pod_get_mod_enable, pod_set_mod_enable);
-static DEVICE_ATTR(mod_param_1_note_value, S_IWUGO | S_IRUGO, pod_get_mod_param_1_note_value, pod_set_mod_param_1_note_value);
-static DEVICE_ATTR(mod_param_2, S_IWUGO | S_IRUGO, pod_get_mod_param_2, pod_set_mod_param_2);
-static DEVICE_ATTR(mod_param_3, S_IWUGO | S_IRUGO, pod_get_mod_param_3, pod_set_mod_param_3);
-static DEVICE_ATTR(mod_param_4, S_IWUGO | S_IRUGO, pod_get_mod_param_4, pod_set_mod_param_4);
-static DEVICE_ATTR(mod_param_5, S_IWUGO | S_IRUGO, pod_get_mod_param_5, pod_set_mod_param_5);
-static DEVICE_ATTR(mod_volume_mix, S_IWUGO | S_IRUGO, pod_get_mod_volume_mix, pod_set_mod_volume_mix);
-static DEVICE_ATTR(mod_pre_post, S_IWUGO | S_IRUGO, pod_get_mod_pre_post, pod_set_mod_pre_post);
-static DEVICE_ATTR(modulation_model, S_IWUGO | S_IRUGO, pod_get_modulation_model, pod_set_modulation_model);
-static DEVICE_ATTR(band_3_frequency, S_IWUGO | S_IRUGO, pod_get_band_3_frequency, pod_set_band_3_frequency);
-static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUGO | S_IRUGO, pod_get_band_4_frequency__bass, pod_set_band_4_frequency__bass);
-static DEVICE_ATTR(mod_param_1_double_precision, S_IWUGO | S_IRUGO, pod_get_mod_param_1_double_precision, pod_set_mod_param_1_double_precision);
-static DEVICE_ATTR(delay_param_1_double_precision, S_IWUGO | S_IRUGO, pod_get_delay_param_1_double_precision, pod_set_delay_param_1_double_precision);
-static DEVICE_ATTR(eq_enable, S_IWUGO | S_IRUGO, pod_get_eq_enable, pod_set_eq_enable);
+static DEVICE_ATTR(highmid, S_IWUGO | S_IRUGO, pod_get_highmid,
+		   pod_set_highmid);
+static DEVICE_ATTR(chan_vol, S_IWUGO | S_IRUGO, pod_get_chan_vol,
+		   pod_set_chan_vol);
+static DEVICE_ATTR(reverb_mix, S_IWUGO | S_IRUGO, pod_get_reverb_mix,
+		   pod_set_reverb_mix);
+static DEVICE_ATTR(effect_setup, S_IWUGO | S_IRUGO, pod_get_effect_setup,
+		   pod_set_effect_setup);
+static DEVICE_ATTR(band_1_frequency, S_IWUGO | S_IRUGO,
+		   pod_get_band_1_frequency, pod_set_band_1_frequency);
+static DEVICE_ATTR(presence, S_IWUGO | S_IRUGO, pod_get_presence,
+		   pod_set_presence);
+static DEVICE_ATTR2(treble__bass, treble, S_IWUGO | S_IRUGO,
+		    pod_get_treble__bass, pod_set_treble__bass);
+static DEVICE_ATTR(noise_gate_enable, S_IWUGO | S_IRUGO,
+		   pod_get_noise_gate_enable, pod_set_noise_gate_enable);
+static DEVICE_ATTR(gate_threshold, S_IWUGO | S_IRUGO, pod_get_gate_threshold,
+		   pod_set_gate_threshold);
+static DEVICE_ATTR(gate_decay_time, S_IWUGO | S_IRUGO, pod_get_gate_decay_time,
+		   pod_set_gate_decay_time);
+static DEVICE_ATTR(stomp_enable, S_IWUGO | S_IRUGO, pod_get_stomp_enable,
+		   pod_set_stomp_enable);
+static DEVICE_ATTR(comp_enable, S_IWUGO | S_IRUGO, pod_get_comp_enable,
+		   pod_set_comp_enable);
+static DEVICE_ATTR(stomp_time, S_IWUGO | S_IRUGO, pod_get_stomp_time,
+		   pod_set_stomp_time);
+static DEVICE_ATTR(delay_enable, S_IWUGO | S_IRUGO, pod_get_delay_enable,
+		   pod_set_delay_enable);
+static DEVICE_ATTR(mod_param_1, S_IWUGO | S_IRUGO, pod_get_mod_param_1,
+		   pod_set_mod_param_1);
+static DEVICE_ATTR(delay_param_1, S_IWUGO | S_IRUGO, pod_get_delay_param_1,
+		   pod_set_delay_param_1);
+static DEVICE_ATTR(delay_param_1_note_value, S_IWUGO | S_IRUGO,
+		   pod_get_delay_param_1_note_value,
+		   pod_set_delay_param_1_note_value);
+static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IWUGO | S_IRUGO,
+		    pod_get_band_2_frequency__bass,
+		    pod_set_band_2_frequency__bass);
+static DEVICE_ATTR(delay_param_2, S_IWUGO | S_IRUGO, pod_get_delay_param_2,
+		   pod_set_delay_param_2);
+static DEVICE_ATTR(delay_volume_mix, S_IWUGO | S_IRUGO,
+		   pod_get_delay_volume_mix, pod_set_delay_volume_mix);
+static DEVICE_ATTR(delay_param_3, S_IWUGO | S_IRUGO, pod_get_delay_param_3,
+		   pod_set_delay_param_3);
+static DEVICE_ATTR(reverb_enable, S_IWUGO | S_IRUGO, pod_get_reverb_enable,
+		   pod_set_reverb_enable);
+static DEVICE_ATTR(reverb_type, S_IWUGO | S_IRUGO, pod_get_reverb_type,
+		   pod_set_reverb_type);
+static DEVICE_ATTR(reverb_decay, S_IWUGO | S_IRUGO, pod_get_reverb_decay,
+		   pod_set_reverb_decay);
+static DEVICE_ATTR(reverb_tone, S_IWUGO | S_IRUGO, pod_get_reverb_tone,
+		   pod_set_reverb_tone);
+static DEVICE_ATTR(reverb_pre_delay, S_IWUGO | S_IRUGO,
+		   pod_get_reverb_pre_delay, pod_set_reverb_pre_delay);
+static DEVICE_ATTR(reverb_pre_post, S_IWUGO | S_IRUGO, pod_get_reverb_pre_post,
+		   pod_set_reverb_pre_post);
+static DEVICE_ATTR(band_2_frequency, S_IWUGO | S_IRUGO,
+		   pod_get_band_2_frequency, pod_set_band_2_frequency);
+static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUGO | S_IRUGO,
+		    pod_get_band_3_frequency__bass,
+		    pod_set_band_3_frequency__bass);
+static DEVICE_ATTR(wah_enable, S_IWUGO | S_IRUGO, pod_get_wah_enable,
+		   pod_set_wah_enable);
+static DEVICE_ATTR(modulation_lo_cut, S_IWUGO | S_IRUGO,
+		   pod_get_modulation_lo_cut, pod_set_modulation_lo_cut);
+static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUGO | S_IRUGO,
+		   pod_get_delay_reverb_lo_cut, pod_set_delay_reverb_lo_cut);
+static DEVICE_ATTR(volume_pedal_minimum, S_IWUGO | S_IRUGO,
+		   pod_get_volume_pedal_minimum, pod_set_volume_pedal_minimum);
+static DEVICE_ATTR(eq_pre_post, S_IWUGO | S_IRUGO, pod_get_eq_pre_post,
+		   pod_set_eq_pre_post);
+static DEVICE_ATTR(volume_pre_post, S_IWUGO | S_IRUGO, pod_get_volume_pre_post,
+		   pod_set_volume_pre_post);
+static DEVICE_ATTR(di_model, S_IWUGO | S_IRUGO, pod_get_di_model,
+		   pod_set_di_model);
+static DEVICE_ATTR(di_delay, S_IWUGO | S_IRUGO, pod_get_di_delay,
+		   pod_set_di_delay);
+static DEVICE_ATTR(mod_enable, S_IWUGO | S_IRUGO, pod_get_mod_enable,
+		   pod_set_mod_enable);
+static DEVICE_ATTR(mod_param_1_note_value, S_IWUGO | S_IRUGO,
+		   pod_get_mod_param_1_note_value,
+		   pod_set_mod_param_1_note_value);
+static DEVICE_ATTR(mod_param_2, S_IWUGO | S_IRUGO, pod_get_mod_param_2,
+		   pod_set_mod_param_2);
+static DEVICE_ATTR(mod_param_3, S_IWUGO | S_IRUGO, pod_get_mod_param_3,
+		   pod_set_mod_param_3);
+static DEVICE_ATTR(mod_param_4, S_IWUGO | S_IRUGO, pod_get_mod_param_4,
+		   pod_set_mod_param_4);
+static DEVICE_ATTR(mod_param_5, S_IWUGO | S_IRUGO, pod_get_mod_param_5,
+		   pod_set_mod_param_5);
+static DEVICE_ATTR(mod_volume_mix, S_IWUGO | S_IRUGO, pod_get_mod_volume_mix,
+		   pod_set_mod_volume_mix);
+static DEVICE_ATTR(mod_pre_post, S_IWUGO | S_IRUGO, pod_get_mod_pre_post,
+		   pod_set_mod_pre_post);
+static DEVICE_ATTR(modulation_model, S_IWUGO | S_IRUGO,
+		   pod_get_modulation_model, pod_set_modulation_model);
+static DEVICE_ATTR(band_3_frequency, S_IWUGO | S_IRUGO,
+		   pod_get_band_3_frequency, pod_set_band_3_frequency);
+static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUGO | S_IRUGO,
+		    pod_get_band_4_frequency__bass,
+		    pod_set_band_4_frequency__bass);
+static DEVICE_ATTR(mod_param_1_double_precision, S_IWUGO | S_IRUGO,
+		   pod_get_mod_param_1_double_precision,
+		   pod_set_mod_param_1_double_precision);
+static DEVICE_ATTR(delay_param_1_double_precision, S_IWUGO | S_IRUGO,
+		   pod_get_delay_param_1_double_precision,
+		   pod_set_delay_param_1_double_precision);
+static DEVICE_ATTR(eq_enable, S_IWUGO | S_IRUGO, pod_get_eq_enable,
+		   pod_set_eq_enable);
 static DEVICE_ATTR(tap, S_IWUGO | S_IRUGO, pod_get_tap, pod_set_tap);
-static DEVICE_ATTR(volume_tweak_pedal_assign, S_IWUGO | S_IRUGO, pod_get_volume_tweak_pedal_assign, pod_set_volume_tweak_pedal_assign);
-static DEVICE_ATTR(band_5_frequency, S_IWUGO | S_IRUGO, pod_get_band_5_frequency, pod_set_band_5_frequency);
+static DEVICE_ATTR(volume_tweak_pedal_assign, S_IWUGO | S_IRUGO,
+		   pod_get_volume_tweak_pedal_assign,
+		   pod_set_volume_tweak_pedal_assign);
+static DEVICE_ATTR(band_5_frequency, S_IWUGO | S_IRUGO,
+		   pod_get_band_5_frequency, pod_set_band_5_frequency);
 static DEVICE_ATTR(tuner, S_IWUGO | S_IRUGO, pod_get_tuner, pod_set_tuner);
-static DEVICE_ATTR(mic_selection, S_IWUGO | S_IRUGO, pod_get_mic_selection, pod_set_mic_selection);
-static DEVICE_ATTR(cabinet_model, S_IWUGO | S_IRUGO, pod_get_cabinet_model, pod_set_cabinet_model);
-static DEVICE_ATTR(stomp_model, S_IWUGO | S_IRUGO, pod_get_stomp_model, pod_set_stomp_model);
-static DEVICE_ATTR(roomlevel, S_IWUGO | S_IRUGO, pod_get_roomlevel, pod_set_roomlevel);
-static DEVICE_ATTR(band_4_frequency, S_IWUGO | S_IRUGO, pod_get_band_4_frequency, pod_set_band_4_frequency);
-static DEVICE_ATTR(band_6_frequency, S_IWUGO | S_IRUGO, pod_get_band_6_frequency, pod_set_band_6_frequency);
-static DEVICE_ATTR(stomp_param_1_note_value, S_IWUGO | S_IRUGO, pod_get_stomp_param_1_note_value, pod_set_stomp_param_1_note_value);
-static DEVICE_ATTR(stomp_param_2, S_IWUGO | S_IRUGO, pod_get_stomp_param_2, pod_set_stomp_param_2);
-static DEVICE_ATTR(stomp_param_3, S_IWUGO | S_IRUGO, pod_get_stomp_param_3, pod_set_stomp_param_3);
-static DEVICE_ATTR(stomp_param_4, S_IWUGO | S_IRUGO, pod_get_stomp_param_4, pod_set_stomp_param_4);
-static DEVICE_ATTR(stomp_param_5, S_IWUGO | S_IRUGO, pod_get_stomp_param_5, pod_set_stomp_param_5);
-static DEVICE_ATTR(stomp_param_6, S_IWUGO | S_IRUGO, pod_get_stomp_param_6, pod_set_stomp_param_6);
-static DEVICE_ATTR(amp_switch_select, S_IWUGO | S_IRUGO, pod_get_amp_switch_select, pod_set_amp_switch_select);
-static DEVICE_ATTR(delay_param_4, S_IWUGO | S_IRUGO, pod_get_delay_param_4, pod_set_delay_param_4);
-static DEVICE_ATTR(delay_param_5, S_IWUGO | S_IRUGO, pod_get_delay_param_5, pod_set_delay_param_5);
-static DEVICE_ATTR(delay_pre_post, S_IWUGO | S_IRUGO, pod_get_delay_pre_post, pod_set_delay_pre_post);
-static DEVICE_ATTR(delay_model, S_IWUGO | S_IRUGO, pod_get_delay_model, pod_set_delay_model);
-static DEVICE_ATTR(delay_verb_model, S_IWUGO | S_IRUGO, pod_get_delay_verb_model, pod_set_delay_verb_model);
-static DEVICE_ATTR(tempo_msb, S_IWUGO | S_IRUGO, pod_get_tempo_msb, pod_set_tempo_msb);
-static DEVICE_ATTR(tempo_lsb, S_IWUGO | S_IRUGO, pod_get_tempo_lsb, pod_set_tempo_lsb);
-static DEVICE_ATTR(wah_model, S_IWUGO | S_IRUGO, pod_get_wah_model, pod_set_wah_model);
-static DEVICE_ATTR(bypass_volume, S_IWUGO | S_IRUGO, pod_get_bypass_volume, pod_set_bypass_volume);
-static DEVICE_ATTR(fx_loop_on_off, S_IWUGO | S_IRUGO, pod_get_fx_loop_on_off, pod_set_fx_loop_on_off);
-static DEVICE_ATTR(tweak_param_select, S_IWUGO | S_IRUGO, pod_get_tweak_param_select, pod_set_tweak_param_select);
-static DEVICE_ATTR(amp1_engage, S_IWUGO | S_IRUGO, pod_get_amp1_engage, pod_set_amp1_engage);
-static DEVICE_ATTR(band_1_gain, S_IWUGO | S_IRUGO, pod_get_band_1_gain, pod_set_band_1_gain);
-static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUGO | S_IRUGO, pod_get_band_2_gain__bass, pod_set_band_2_gain__bass);
-static DEVICE_ATTR(band_2_gain, S_IWUGO | S_IRUGO, pod_get_band_2_gain, pod_set_band_2_gain);
-static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUGO | S_IRUGO, pod_get_band_3_gain__bass, pod_set_band_3_gain__bass);
-static DEVICE_ATTR(band_3_gain, S_IWUGO | S_IRUGO, pod_get_band_3_gain, pod_set_band_3_gain);
-static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUGO | S_IRUGO, pod_get_band_4_gain__bass, pod_set_band_4_gain__bass);
-static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IWUGO | S_IRUGO, pod_get_band_5_gain__bass, pod_set_band_5_gain__bass);
-static DEVICE_ATTR(band_4_gain, S_IWUGO | S_IRUGO, pod_get_band_4_gain, pod_set_band_4_gain);
-static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUGO | S_IRUGO, pod_get_band_6_gain__bass, pod_set_band_6_gain__bass);
+static DEVICE_ATTR(mic_selection, S_IWUGO | S_IRUGO, pod_get_mic_selection,
+		   pod_set_mic_selection);
+static DEVICE_ATTR(cabinet_model, S_IWUGO | S_IRUGO, pod_get_cabinet_model,
+		   pod_set_cabinet_model);
+static DEVICE_ATTR(stomp_model, S_IWUGO | S_IRUGO, pod_get_stomp_model,
+		   pod_set_stomp_model);
+static DEVICE_ATTR(roomlevel, S_IWUGO | S_IRUGO, pod_get_roomlevel,
+		   pod_set_roomlevel);
+static DEVICE_ATTR(band_4_frequency, S_IWUGO | S_IRUGO,
+		   pod_get_band_4_frequency, pod_set_band_4_frequency);
+static DEVICE_ATTR(band_6_frequency, S_IWUGO | S_IRUGO,
+		   pod_get_band_6_frequency, pod_set_band_6_frequency);
+static DEVICE_ATTR(stomp_param_1_note_value, S_IWUGO | S_IRUGO,
+		   pod_get_stomp_param_1_note_value,
+		   pod_set_stomp_param_1_note_value);
+static DEVICE_ATTR(stomp_param_2, S_IWUGO | S_IRUGO, pod_get_stomp_param_2,
+		   pod_set_stomp_param_2);
+static DEVICE_ATTR(stomp_param_3, S_IWUGO | S_IRUGO, pod_get_stomp_param_3,
+		   pod_set_stomp_param_3);
+static DEVICE_ATTR(stomp_param_4, S_IWUGO | S_IRUGO, pod_get_stomp_param_4,
+		   pod_set_stomp_param_4);
+static DEVICE_ATTR(stomp_param_5, S_IWUGO | S_IRUGO, pod_get_stomp_param_5,
+		   pod_set_stomp_param_5);
+static DEVICE_ATTR(stomp_param_6, S_IWUGO | S_IRUGO, pod_get_stomp_param_6,
+		   pod_set_stomp_param_6);
+static DEVICE_ATTR(amp_switch_select, S_IWUGO | S_IRUGO,
+		   pod_get_amp_switch_select, pod_set_amp_switch_select);
+static DEVICE_ATTR(delay_param_4, S_IWUGO | S_IRUGO, pod_get_delay_param_4,
+		   pod_set_delay_param_4);
+static DEVICE_ATTR(delay_param_5, S_IWUGO | S_IRUGO, pod_get_delay_param_5,
+		   pod_set_delay_param_5);
+static DEVICE_ATTR(delay_pre_post, S_IWUGO | S_IRUGO, pod_get_delay_pre_post,
+		   pod_set_delay_pre_post);
+static DEVICE_ATTR(delay_model, S_IWUGO | S_IRUGO, pod_get_delay_model,
+		   pod_set_delay_model);
+static DEVICE_ATTR(delay_verb_model, S_IWUGO | S_IRUGO,
+		   pod_get_delay_verb_model, pod_set_delay_verb_model);
+static DEVICE_ATTR(tempo_msb, S_IWUGO | S_IRUGO, pod_get_tempo_msb,
+		   pod_set_tempo_msb);
+static DEVICE_ATTR(tempo_lsb, S_IWUGO | S_IRUGO, pod_get_tempo_lsb,
+		   pod_set_tempo_lsb);
+static DEVICE_ATTR(wah_model, S_IWUGO | S_IRUGO, pod_get_wah_model,
+		   pod_set_wah_model);
+static DEVICE_ATTR(bypass_volume, S_IWUGO | S_IRUGO, pod_get_bypass_volume,
+		   pod_set_bypass_volume);
+static DEVICE_ATTR(fx_loop_on_off, S_IWUGO | S_IRUGO, pod_get_fx_loop_on_off,
+		   pod_set_fx_loop_on_off);
+static DEVICE_ATTR(tweak_param_select, S_IWUGO | S_IRUGO,
+		   pod_get_tweak_param_select, pod_set_tweak_param_select);
+static DEVICE_ATTR(amp1_engage, S_IWUGO | S_IRUGO, pod_get_amp1_engage,
+		   pod_set_amp1_engage);
+static DEVICE_ATTR(band_1_gain, S_IWUGO | S_IRUGO, pod_get_band_1_gain,
+		   pod_set_band_1_gain);
+static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUGO | S_IRUGO,
+		    pod_get_band_2_gain__bass, pod_set_band_2_gain__bass);
+static DEVICE_ATTR(band_2_gain, S_IWUGO | S_IRUGO, pod_get_band_2_gain,
+		   pod_set_band_2_gain);
+static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUGO | S_IRUGO,
+		    pod_get_band_3_gain__bass, pod_set_band_3_gain__bass);
+static DEVICE_ATTR(band_3_gain, S_IWUGO | S_IRUGO, pod_get_band_3_gain,
+		   pod_set_band_3_gain);
+static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUGO | S_IRUGO,
+		    pod_get_band_4_gain__bass, pod_set_band_4_gain__bass);
+static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IWUGO | S_IRUGO,
+		    pod_get_band_5_gain__bass, pod_set_band_5_gain__bass);
+static DEVICE_ATTR(band_4_gain, S_IWUGO | S_IRUGO, pod_get_band_4_gain,
+		   pod_set_band_4_gain);
+static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUGO | S_IRUGO,
+		    pod_get_band_6_gain__bass, pod_set_band_6_gain__bass);
 static DEVICE_ATTR(body, S_IRUGO, variax_get_body, line6_nop_write);
-static DEVICE_ATTR(pickup1_enable, S_IRUGO, variax_get_pickup1_enable, line6_nop_write);
-static DEVICE_ATTR(pickup1_type, S_IRUGO, variax_get_pickup1_type, line6_nop_write);
-static DEVICE_ATTR(pickup1_position, S_IRUGO, variax_get_pickup1_position, line6_nop_write);
-static DEVICE_ATTR(pickup1_angle, S_IRUGO, variax_get_pickup1_angle, line6_nop_write);
-static DEVICE_ATTR(pickup1_level, S_IRUGO, variax_get_pickup1_level, line6_nop_write);
-static DEVICE_ATTR(pickup2_enable, S_IRUGO, variax_get_pickup2_enable, line6_nop_write);
-static DEVICE_ATTR(pickup2_type, S_IRUGO, variax_get_pickup2_type, line6_nop_write);
-static DEVICE_ATTR(pickup2_position, S_IRUGO, variax_get_pickup2_position, line6_nop_write);
-static DEVICE_ATTR(pickup2_angle, S_IRUGO, variax_get_pickup2_angle, line6_nop_write);
-static DEVICE_ATTR(pickup2_level, S_IRUGO, variax_get_pickup2_level, line6_nop_write);
-static DEVICE_ATTR(pickup_phase, S_IRUGO, variax_get_pickup_phase, line6_nop_write);
-static DEVICE_ATTR(capacitance, S_IRUGO, variax_get_capacitance, line6_nop_write);
-static DEVICE_ATTR(tone_resistance, S_IRUGO, variax_get_tone_resistance, line6_nop_write);
-static DEVICE_ATTR(volume_resistance, S_IRUGO, variax_get_volume_resistance, line6_nop_write);
+static DEVICE_ATTR(pickup1_enable, S_IRUGO, variax_get_pickup1_enable,
+		   line6_nop_write);
+static DEVICE_ATTR(pickup1_type, S_IRUGO, variax_get_pickup1_type,
+		   line6_nop_write);
+static DEVICE_ATTR(pickup1_position, S_IRUGO, variax_get_pickup1_position,
+		   line6_nop_write);
+static DEVICE_ATTR(pickup1_angle, S_IRUGO, variax_get_pickup1_angle,
+		   line6_nop_write);
+static DEVICE_ATTR(pickup1_level, S_IRUGO, variax_get_pickup1_level,
+		   line6_nop_write);
+static DEVICE_ATTR(pickup2_enable, S_IRUGO, variax_get_pickup2_enable,
+		   line6_nop_write);
+static DEVICE_ATTR(pickup2_type, S_IRUGO, variax_get_pickup2_type,
+		   line6_nop_write);
+static DEVICE_ATTR(pickup2_position, S_IRUGO, variax_get_pickup2_position,
+		   line6_nop_write);
+static DEVICE_ATTR(pickup2_angle, S_IRUGO, variax_get_pickup2_angle,
+		   line6_nop_write);
+static DEVICE_ATTR(pickup2_level, S_IRUGO, variax_get_pickup2_level,
+		   line6_nop_write);
+static DEVICE_ATTR(pickup_phase, S_IRUGO, variax_get_pickup_phase,
+		   line6_nop_write);
+static DEVICE_ATTR(capacitance, S_IRUGO, variax_get_capacitance,
+		   line6_nop_write);
+static DEVICE_ATTR(tone_resistance, S_IRUGO, variax_get_tone_resistance,
+		   line6_nop_write);
+static DEVICE_ATTR(volume_resistance, S_IRUGO, variax_get_volume_resistance,
+		   line6_nop_write);
 static DEVICE_ATTR(taper, S_IRUGO, variax_get_taper, line6_nop_write);
 static DEVICE_ATTR(tone_dump, S_IRUGO, variax_get_tone_dump, line6_nop_write);
 static DEVICE_ATTR(save_tone, S_IRUGO, variax_get_save_tone, line6_nop_write);
-static DEVICE_ATTR(volume_dump, S_IRUGO, variax_get_volume_dump, line6_nop_write);
-static DEVICE_ATTR(tuning_enable, S_IRUGO, variax_get_tuning_enable, line6_nop_write);
+static DEVICE_ATTR(volume_dump, S_IRUGO, variax_get_volume_dump,
+		   line6_nop_write);
+static DEVICE_ATTR(tuning_enable, S_IRUGO, variax_get_tuning_enable,
+		   line6_nop_write);
 static DEVICE_ATTR(tuning6, S_IRUGO, variax_get_tuning6, line6_nop_write);
 static DEVICE_ATTR(tuning5, S_IRUGO, variax_get_tuning5, line6_nop_write);
 static DEVICE_ATTR(tuning4, S_IRUGO, variax_get_tuning4, line6_nop_write);
@@ -399,7 +527,8 @@
 static DEVICE_ATTR(mix3, S_IRUGO, variax_get_mix3, line6_nop_write);
 static DEVICE_ATTR(mix2, S_IRUGO, variax_get_mix2, line6_nop_write);
 static DEVICE_ATTR(mix1, S_IRUGO, variax_get_mix1, line6_nop_write);
-static DEVICE_ATTR(pickup_wiring, S_IRUGO, variax_get_pickup_wiring, line6_nop_write);
+static DEVICE_ATTR(pickup_wiring, S_IRUGO, variax_get_pickup_wiring,
+		   line6_nop_write);
 
 int pod_create_files(int firmware, int type, struct device *dev)
 {
@@ -407,7 +536,8 @@
 	CHECK_RETURN(device_create_file(dev, &dev_attr_tweak));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_wah_position));
 	if ((type & (LINE6_BITS_PODXTALL)) != 0)
-		CHECK_RETURN(device_create_file(dev, &dev_attr_compression_gain));
+		CHECK_RETURN(device_create_file
+			     (dev, &dev_attr_compression_gain));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_vol_pedal_position));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_compression_threshold));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_pan));
@@ -429,7 +559,8 @@
 		CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_mix));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_effect_setup));
 	if (firmware >= 200)
-		CHECK_RETURN(device_create_file(dev, &dev_attr_band_1_frequency));
+		CHECK_RETURN(device_create_file
+			     (dev, &dev_attr_band_1_frequency));
 	if ((type & (LINE6_BITS_PODXTALL)) != 0)
 		CHECK_RETURN(device_create_file(dev, &dev_attr_presence));
 	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
@@ -443,10 +574,12 @@
 	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_enable));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_1));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_1));
-	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_1_note_value));
+	CHECK_RETURN(device_create_file
+		     (dev, &dev_attr_delay_param_1_note_value));
 	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
 		if (firmware >= 200)
-			CHECK_RETURN(device_create_file(dev, &dev_attr_band_2_frequency__bass));
+			CHECK_RETURN(device_create_file
+				     (dev, &dev_attr_band_2_frequency__bass));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_2));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_volume_mix));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_3));
@@ -459,26 +592,34 @@
 	if ((type & (LINE6_BITS_PODXTALL)) != 0)
 		CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_tone));
 	if ((type & (LINE6_BITS_PODXTALL)) != 0)
-		CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_pre_delay));
+		CHECK_RETURN(device_create_file
+			     (dev, &dev_attr_reverb_pre_delay));
 	if ((type & (LINE6_BITS_PODXTALL)) != 0)
-		CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_pre_post));
+		CHECK_RETURN(device_create_file
+			     (dev, &dev_attr_reverb_pre_post));
 	if ((type & (LINE6_BITS_PODXTALL)) != 0)
 		if (firmware >= 200)
-			CHECK_RETURN(device_create_file(dev, &dev_attr_band_2_frequency));
+			CHECK_RETURN(device_create_file
+				     (dev, &dev_attr_band_2_frequency));
 	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
 		if (firmware >= 200)
-			CHECK_RETURN(device_create_file(dev, &dev_attr_band_3_frequency__bass));
+			CHECK_RETURN(device_create_file
+				     (dev, &dev_attr_band_3_frequency__bass));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_wah_enable));
 	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
-		CHECK_RETURN(device_create_file(dev, &dev_attr_modulation_lo_cut));
+		CHECK_RETURN(device_create_file
+			     (dev, &dev_attr_modulation_lo_cut));
 	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
-		CHECK_RETURN(device_create_file(dev, &dev_attr_delay_reverb_lo_cut));
+		CHECK_RETURN(device_create_file
+			     (dev, &dev_attr_delay_reverb_lo_cut));
 	if ((type & (LINE6_BITS_PODXTALL)) != 0)
 		if (firmware >= 200)
-			CHECK_RETURN(device_create_file(dev, &dev_attr_volume_pedal_minimum));
+			CHECK_RETURN(device_create_file
+				     (dev, &dev_attr_volume_pedal_minimum));
 	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
 		if (firmware >= 200)
-			CHECK_RETURN(device_create_file(dev, &dev_attr_eq_pre_post));
+			CHECK_RETURN(device_create_file
+				     (dev, &dev_attr_eq_pre_post));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_volume_pre_post));
 	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
 		CHECK_RETURN(device_create_file(dev, &dev_attr_di_model));
@@ -496,19 +637,25 @@
 	CHECK_RETURN(device_create_file(dev, &dev_attr_modulation_model));
 	if ((type & (LINE6_BITS_PODXTALL)) != 0)
 		if (firmware >= 200)
-			CHECK_RETURN(device_create_file(dev, &dev_attr_band_3_frequency));
+			CHECK_RETURN(device_create_file
+				     (dev, &dev_attr_band_3_frequency));
 	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
 		if (firmware >= 200)
-			CHECK_RETURN(device_create_file(dev, &dev_attr_band_4_frequency__bass));
-	CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_1_double_precision));
-	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_1_double_precision));
+			CHECK_RETURN(device_create_file
+				     (dev, &dev_attr_band_4_frequency__bass));
+	CHECK_RETURN(device_create_file
+		     (dev, &dev_attr_mod_param_1_double_precision));
+	CHECK_RETURN(device_create_file
+		     (dev, &dev_attr_delay_param_1_double_precision));
 	if (firmware >= 200)
 		CHECK_RETURN(device_create_file(dev, &dev_attr_eq_enable));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_tap));
-	CHECK_RETURN(device_create_file(dev, &dev_attr_volume_tweak_pedal_assign));
+	CHECK_RETURN(device_create_file
+		     (dev, &dev_attr_volume_tweak_pedal_assign));
 	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
 		if (firmware >= 200)
-			CHECK_RETURN(device_create_file(dev, &dev_attr_band_5_frequency));
+			CHECK_RETURN(device_create_file
+				     (dev, &dev_attr_band_5_frequency));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_tuner));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_mic_selection));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_cabinet_model));
@@ -516,25 +663,30 @@
 	CHECK_RETURN(device_create_file(dev, &dev_attr_roomlevel));
 	if ((type & (LINE6_BITS_PODXTALL)) != 0)
 		if (firmware >= 200)
-			CHECK_RETURN(device_create_file(dev, &dev_attr_band_4_frequency));
+			CHECK_RETURN(device_create_file
+				     (dev, &dev_attr_band_4_frequency));
 	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
 		if (firmware >= 200)
-			CHECK_RETURN(device_create_file(dev, &dev_attr_band_6_frequency));
-	CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_1_note_value));
+			CHECK_RETURN(device_create_file
+				     (dev, &dev_attr_band_6_frequency));
+	CHECK_RETURN(device_create_file
+		     (dev, &dev_attr_stomp_param_1_note_value));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_2));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_3));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_4));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_5));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_6));
 	if ((type & (LINE6_BITS_LIVE)) != 0)
-		CHECK_RETURN(device_create_file(dev, &dev_attr_amp_switch_select));
+		CHECK_RETURN(device_create_file
+			     (dev, &dev_attr_amp_switch_select));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_4));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_5));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_pre_post));
 	if ((type & (LINE6_BITS_PODXTALL)) != 0)
 		CHECK_RETURN(device_create_file(dev, &dev_attr_delay_model));
 	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
-		CHECK_RETURN(device_create_file(dev, &dev_attr_delay_verb_model));
+		CHECK_RETURN(device_create_file
+			     (dev, &dev_attr_delay_verb_model));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_tempo_msb));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_tempo_lsb));
 	if (firmware >= 300)
@@ -549,30 +701,39 @@
 		CHECK_RETURN(device_create_file(dev, &dev_attr_band_1_gain));
 	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
 		if (firmware >= 200)
-			CHECK_RETURN(device_create_file(dev, &dev_attr_band_2_gain__bass));
+			CHECK_RETURN(device_create_file
+				     (dev, &dev_attr_band_2_gain__bass));
 	if ((type & (LINE6_BITS_PODXTALL)) != 0)
 		if (firmware >= 200)
-			CHECK_RETURN(device_create_file(dev, &dev_attr_band_2_gain));
+			CHECK_RETURN(device_create_file
+				     (dev, &dev_attr_band_2_gain));
 	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
 		if (firmware >= 200)
-			CHECK_RETURN(device_create_file(dev, &dev_attr_band_3_gain__bass));
+			CHECK_RETURN(device_create_file
+				     (dev, &dev_attr_band_3_gain__bass));
 	if ((type & (LINE6_BITS_PODXTALL)) != 0)
 		if (firmware >= 200)
-			CHECK_RETURN(device_create_file(dev, &dev_attr_band_3_gain));
+			CHECK_RETURN(device_create_file
+				     (dev, &dev_attr_band_3_gain));
 	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
 		if (firmware >= 200)
-			CHECK_RETURN(device_create_file(dev, &dev_attr_band_4_gain__bass));
+			CHECK_RETURN(device_create_file
+				     (dev, &dev_attr_band_4_gain__bass));
 	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
 		if (firmware >= 200)
-			CHECK_RETURN(device_create_file(dev, &dev_attr_band_5_gain__bass));
+			CHECK_RETURN(device_create_file
+				     (dev, &dev_attr_band_5_gain__bass));
 	if ((type & (LINE6_BITS_PODXTALL)) != 0)
 		if (firmware >= 200)
-			CHECK_RETURN(device_create_file(dev, &dev_attr_band_4_gain));
+			CHECK_RETURN(device_create_file
+				     (dev, &dev_attr_band_4_gain));
 	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
 		if (firmware >= 200)
-			CHECK_RETURN(device_create_file(dev, &dev_attr_band_6_gain__bass));
-  return 0;
+			CHECK_RETURN(device_create_file
+				     (dev, &dev_attr_band_6_gain__bass));
+	return 0;
 }
+EXPORT_SYMBOL(pod_create_files);
 
 void pod_remove_files(int firmware, int type, struct device *dev)
 {
@@ -618,7 +779,8 @@
 	device_remove_file(dev, &dev_attr_delay_param_1_note_value);
 	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
 		if (firmware >= 200)
-			device_remove_file(dev, &dev_attr_band_2_frequency__bass);
+			device_remove_file(dev,
+					   &dev_attr_band_2_frequency__bass);
 	device_remove_file(dev, &dev_attr_delay_param_2);
 	device_remove_file(dev, &dev_attr_delay_volume_mix);
 	device_remove_file(dev, &dev_attr_delay_param_3);
@@ -639,7 +801,8 @@
 			device_remove_file(dev, &dev_attr_band_2_frequency);
 	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
 		if (firmware >= 200)
-			device_remove_file(dev, &dev_attr_band_3_frequency__bass);
+			device_remove_file(dev,
+					   &dev_attr_band_3_frequency__bass);
 	device_remove_file(dev, &dev_attr_wah_enable);
 	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
 		device_remove_file(dev, &dev_attr_modulation_lo_cut);
@@ -671,7 +834,8 @@
 			device_remove_file(dev, &dev_attr_band_3_frequency);
 	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
 		if (firmware >= 200)
-			device_remove_file(dev, &dev_attr_band_4_frequency__bass);
+			device_remove_file(dev,
+					   &dev_attr_band_4_frequency__bass);
 	device_remove_file(dev, &dev_attr_mod_param_1_double_precision);
 	device_remove_file(dev, &dev_attr_delay_param_1_double_precision);
 	if (firmware >= 200)
@@ -744,8 +908,6 @@
 		if (firmware >= 200)
 			device_remove_file(dev, &dev_attr_band_6_gain__bass);
 }
-
-EXPORT_SYMBOL(pod_create_files);
 EXPORT_SYMBOL(pod_remove_files);
 
 int variax_create_files(int firmware, int type, struct device *dev)
@@ -790,8 +952,9 @@
 	CHECK_RETURN(device_create_file(dev, &dev_attr_mix2));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_mix1));
 	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup_wiring));
-  return 0;
+	return 0;
 }
+EXPORT_SYMBOL(variax_create_files);
 
 void variax_remove_files(int firmware, int type, struct device *dev)
 {
@@ -835,6 +998,4 @@
 	device_remove_file(dev, &dev_attr_mix1);
 	device_remove_file(dev, &dev_attr_pickup_wiring);
 }
-
-EXPORT_SYMBOL(variax_create_files);
 EXPORT_SYMBOL(variax_remove_files);
diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c
index f188ece..e4078a9 100644
--- a/drivers/staging/line6/driver.c
+++ b/drivers/staging/line6/driver.c
@@ -168,19 +168,19 @@
 #endif
 
 /*
-	Send raw message in pieces of wMaxPacketSize bytes.
+	Send raw message in pieces of max_packet_size bytes.
 */
 int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
 			   int size)
 {
 	int i, done = 0;
+	int actual_size;
 
 #if DO_DUMP_URB_SEND
 	line6_write_hexdump(line6, 'S', buffer, size);
 #endif
 
-	for (i = 0; i < size; i += line6->max_packet_size) {
-		int partial;
+	for (i = 0; i < size; i += actual_size) {
 		const char *frag_buf = buffer + i;
 		int frag_size = min(line6->max_packet_size, size - i);
 		int retval;
@@ -189,7 +189,7 @@
 					   usb_sndintpipe(line6->usbdev,
 							  line6->ep_control_write),
 					   (char *)frag_buf, frag_size,
-					   &partial, LINE6_TIMEOUT * HZ);
+					   &actual_size, LINE6_TIMEOUT * HZ);
 
 		if (retval) {
 			dev_err(line6->ifcdev,
@@ -197,7 +197,7 @@
 			break;
 		}
 
-		done += frag_size;
+		done += actual_size;
 	}
 
 	return done;
@@ -395,17 +395,44 @@
 	line6_start_listen(line6);
 }
 
+static int line6_send(struct usb_line6 *line6, unsigned char *buf, size_t len)
+{
+	int retval;
+	unsigned int partial;
+
+#if DO_DUMP_URB_SEND
+	line6_write_hexdump(line6, 'S', buf, len);
+#endif
+
+	retval = usb_interrupt_msg(line6->usbdev,
+				   usb_sndintpipe(line6->usbdev,
+						  line6->ep_control_write),
+				   buf, len, &partial,
+				   LINE6_TIMEOUT * HZ);
+
+	if (retval) {
+		dev_err(line6->ifcdev,
+			"usb_interrupt_msg failed (%d)\n", retval);
+	}
+
+	if (partial != len) {
+		dev_err(line6->ifcdev,
+			"usb_interrupt_msg sent partial message (%d)\n",
+			 retval);
+	}
+
+	return retval;
+}
+
 /*
 	Send channel number (i.e., switch to a different sound).
 */
 int line6_send_program(struct usb_line6 *line6, int value)
 {
-	int retval;
 	unsigned char *buffer;
-	unsigned int partial;
+	size_t len = 2;
 
-	buffer = kmalloc(2, GFP_KERNEL);
-
+	buffer = kmalloc(len, GFP_KERNEL);
 	if (!buffer) {
 		dev_err(line6->ifcdev, "out of memory\n");
 		return -ENOMEM;
@@ -414,20 +441,7 @@
 	buffer[0] = LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST;
 	buffer[1] = value;
 
-#if DO_DUMP_URB_SEND
-	line6_write_hexdump(line6, 'S', buffer, 2);
-#endif
-
-	retval = usb_interrupt_msg(line6->usbdev,
-				   usb_sndintpipe(line6->usbdev,
-						  line6->ep_control_write),
-				   buffer, 2, &partial, LINE6_TIMEOUT * HZ);
-
-	if (retval)
-		dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", retval);
-
-	kfree(buffer);
-	return retval;
+	return line6_send(line6, buffer, len);
 }
 
 /*
@@ -435,12 +449,10 @@
 */
 int line6_transmit_parameter(struct usb_line6 *line6, int param, int value)
 {
-	int retval;
 	unsigned char *buffer;
-	unsigned int partial;
+	size_t len = 3;
 
-	buffer = kmalloc(3, GFP_KERNEL);
-
+	buffer = kmalloc(len, GFP_KERNEL);
 	if (!buffer) {
 		dev_err(line6->ifcdev, "out of memory\n");
 		return -ENOMEM;
@@ -450,19 +462,7 @@
 	buffer[1] = param;
 	buffer[2] = value;
 
-#if DO_DUMP_URB_SEND
-	line6_write_hexdump(line6, 'S', buffer, 3);
-#endif
-
-	retval = usb_interrupt_msg(line6->usbdev,
-														 usb_sndintpipe(line6->usbdev, line6->ep_control_write),
-														 buffer, 3, &partial, LINE6_TIMEOUT * HZ);
-
-	if (retval)
-		dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", retval);
-
-	kfree(buffer);
-	return retval;
+	return line6_send(line6, buffer, len);
 }
 
 /*
@@ -476,8 +476,10 @@
 
 	/* query the serial number: */
 	ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
-												USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
-												(datalen << 8) | 0x21, address, NULL, 0, LINE6_TIMEOUT * HZ);
+				      USB_TYPE_VENDOR | USB_RECIP_DEVICE
+				      | USB_DIR_OUT,
+				      (datalen << 8) | 0x21, address,
+				      NULL, 0, LINE6_TIMEOUT * HZ);
 
 	if (ret < 0) {
 		dev_err(line6->ifcdev, "read request failed (error %d)\n", ret);
@@ -496,9 +498,7 @@
 				"receive length failed (error %d)\n", ret);
 			return ret;
 		}
-	}
-	while (len == 0xff)
-		;
+	} while (len == 0xff);
 
 	if (len != datalen) {
 		/* should be equal or something went wrong */
@@ -682,10 +682,14 @@
 		return -ENODEV;
 
 	/* check vendor and product id */
-	for (devtype = ARRAY_SIZE(line6_id_table) - 1; devtype--;)
-		if ((le16_to_cpu(usbdev->descriptor.idVendor) == line6_id_table[devtype].idVendor) &&
-			 (le16_to_cpu(usbdev->descriptor.idProduct) == line6_id_table[devtype].idProduct))
+	for (devtype = ARRAY_SIZE(line6_id_table) - 1; devtype--;) {
+		u16 vendor = le16_to_cpu(usbdev->descriptor.idVendor);
+		u16 product = le16_to_cpu(usbdev->descriptor.idProduct);
+
+		if (vendor == line6_id_table[devtype].idVendor
+		     && product == line6_id_table[devtype].idProduct)
 			break;
+	}
 
 	if (devtype < 0)
 		return -ENODEV;
@@ -1036,9 +1040,10 @@
 
 		dev_info(&interface->dev, "Line6 %s now disconnected\n", line6->properties->name);
 
-		for (i = LINE6_MAX_DEVICES; i--;)
+		for (i = LINE6_MAX_DEVICES; i--;) {
 			if (line6_devices[i] == line6)
 				line6_devices[i] = NULL;
+		}
 	}
 
 	line6_destruct(interface);
diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c
index 89a2b17..6ef4455 100644
--- a/drivers/staging/line6/midi.c
+++ b/drivers/staging/line6/midi.c
@@ -318,7 +318,13 @@
 {
 	struct usb_interface *interface = to_usb_interface(dev);
 	struct usb_line6 *line6 = usb_get_intfdata(interface);
-	int value = simple_strtoul(buf, NULL, 10);
+	unsigned long value;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &value);
+	if (ret)
+		return ret;
+
 	line6->line6midi->midi_mask_transmit = value;
 	return count;
 }
@@ -344,7 +350,13 @@
 {
 	struct usb_interface *interface = to_usb_interface(dev);
 	struct usb_line6 *line6 = usb_get_intfdata(interface);
-	int value = simple_strtoul(buf, NULL, 10);
+	unsigned long value;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &value);
+	if (ret)
+		return ret;
+
 	line6->line6midi->midi_mask_receive = value;
 	return count;
 }
diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c
index fc4113f..dd98121 100644
--- a/drivers/staging/line6/pcm.c
+++ b/drivers/staging/line6/pcm.c
@@ -156,7 +156,8 @@
 	strcpy(pcm->name, line6pcm->line6->properties->name);
 
 	/* set operators */
-	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_line6_playback_ops);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+			&snd_line6_playback_ops);
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_line6_capture_ops);
 
 	/* pre-allocation of buffers */
diff --git a/drivers/staging/line6/playback.c b/drivers/staging/line6/playback.c
index acb0612..3431f5c 100644
--- a/drivers/staging/line6/playback.c
+++ b/drivers/staging/line6/playback.c
@@ -20,7 +20,6 @@
 #include "pod.h"
 #include "playback.h"
 
-
 /*
 	Software stereo volume control.
 */
@@ -30,7 +29,7 @@
 	int chn = 0;
 
 	if (volume[0] == 256 && volume[1] == 256)
-		return;  /* maximum volume - no change */
+		return;		/* maximum volume - no change */
 
 	if (bytes_per_frame == 4) {
 		short *p, *buf_end;
@@ -68,13 +67,17 @@
 	int i, urb_size, urb_frames;
 	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
 	const int bytes_per_frame = line6pcm->properties->bytes_per_frame;
-	const int frame_increment = line6pcm->properties->snd_line6_rates.rats[0].num_min;
-	const int frame_factor = line6pcm->properties->snd_line6_rates.rats[0].den * (USB_INTERVALS_PER_SECOND / LINE6_ISO_INTERVAL);
+	const int frame_increment =
+	    line6pcm->properties->snd_line6_rates.rats[0].num_min;
+	const int frame_factor =
+	    line6pcm->properties->snd_line6_rates.rats[0].den *
+	    (USB_INTERVALS_PER_SECOND / LINE6_ISO_INTERVAL);
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct urb *urb_out;
 
 	spin_lock_irqsave(&line6pcm->lock_audio_out, flags);
-	index = find_first_zero_bit(&line6pcm->active_urb_out, LINE6_ISO_BUFFERS);
+	index =
+	    find_first_zero_bit(&line6pcm->active_urb_out, LINE6_ISO_BUFFERS);
 
 	if (index < 0 || index >= LINE6_ISO_BUFFERS) {
 		spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
@@ -88,7 +91,8 @@
 	for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
 		/* compute frame size for given sampling rate */
 		int n, fs;
-		struct usb_iso_packet_descriptor *fout = &urb_out->iso_frame_desc[i];
+		struct usb_iso_packet_descriptor *fout =
+		    &urb_out->iso_frame_desc[i];
 		line6pcm->count_out += frame_increment;
 		n = line6pcm->count_out / frame_factor;
 		line6pcm->count_out -= n * frame_factor;
@@ -106,25 +110,36 @@
 	} else {
 		if (line6pcm->pos_out + urb_frames > runtime->buffer_size) {
 			/*
-				The transferred area goes over buffer boundary,
-				copy the data to the temp buffer.
-			*/
+			   The transferred area goes over buffer boundary,
+			   copy the data to the temp buffer.
+			 */
 			int len;
 			len = runtime->buffer_size - line6pcm->pos_out;
 			urb_out->transfer_buffer = line6pcm->wrap_out;
 
 			if (len > 0) {
-				memcpy(line6pcm->wrap_out, runtime->dma_area + line6pcm->pos_out * bytes_per_frame, len * bytes_per_frame);
-				memcpy(line6pcm->wrap_out + len * bytes_per_frame, runtime->dma_area, (urb_frames - len) * bytes_per_frame);
-			} else
-				dev_err(s2m(substream), "driver bug: len = %d\n", len);  /* this is somewhat paranoid */
+				memcpy(line6pcm->wrap_out,
+				       runtime->dma_area +
+				       line6pcm->pos_out * bytes_per_frame,
+				       len * bytes_per_frame);
+				memcpy(line6pcm->wrap_out +
+				       len * bytes_per_frame, runtime->dma_area,
+				       (urb_frames - len) * bytes_per_frame);
+			} else {
+				/* this is somewhat paranoid */
+				dev_err(s2m(substream),
+					"driver bug: len = %d\n", len);
+			}
 		} else {
 			/* set the buffer pointer */
-			urb_out->transfer_buffer = runtime->dma_area + line6pcm->pos_out * bytes_per_frame;
+			urb_out->transfer_buffer =
+			    runtime->dma_area +
+			    line6pcm->pos_out * bytes_per_frame;
 		}
 	}
 
-	if ((line6pcm->pos_out += urb_frames) >= runtime->buffer_size)
+	line6pcm->pos_out += urb_frames;
+	if (line6pcm->pos_out >= runtime->buffer_size)
 		line6pcm->pos_out -= runtime->buffer_size;
 
 	urb_out->transfer_buffer_length = urb_size;
@@ -133,15 +148,19 @@
 
 #if DO_DUMP_PCM_SEND
 	for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
-		struct usb_iso_packet_descriptor *fout = &urb_out->iso_frame_desc[i];
-		line6_write_hexdump(line6pcm->line6, 'P', urb_out->transfer_buffer + fout->offset, fout->length);
+		struct usb_iso_packet_descriptor *fout =
+		    &urb_out->iso_frame_desc[i];
+		line6_write_hexdump(line6pcm->line6, 'P',
+				    urb_out->transfer_buffer + fout->offset,
+				    fout->length);
 	}
 #endif
 
 	if (usb_submit_urb(urb_out, GFP_ATOMIC) == 0)
 		set_bit(index, &line6pcm->active_urb_out);
 	else
-		dev_err(s2m(substream), "URB out #%d submission failed\n", index);
+		dev_err(s2m(substream), "URB out #%d submission failed\n",
+			index);
 
 	spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
 	return 0;
@@ -181,7 +200,7 @@
 }
 
 /*
-	Wait until unlinking of all currently active playback URBs has been finished.
+   Wait until unlinking of all currently active playback URBs has been finished.
 */
 static void wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
 {
@@ -224,7 +243,8 @@
 	int i, index, length = 0, shutdown = 0;
 	unsigned long flags;
 
-	struct snd_pcm_substream *substream = (struct snd_pcm_substream *)urb->context;
+	struct snd_pcm_substream *substream =
+	    (struct snd_pcm_substream *)urb->context;
 	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
 	struct snd_pcm_runtime *runtime = substream->runtime;
 
@@ -234,13 +254,14 @@
 			break;
 
 	if (index < 0)
-		return;  /* URB has been unlinked asynchronously */
+		return;		/* URB has been unlinked asynchronously */
 
 	for (i = LINE6_ISO_PACKETS; i--;)
 		length += urb->iso_frame_desc[i].length;
 
 	spin_lock_irqsave(&line6pcm->lock_audio_out, flags);
-	line6pcm->pos_out_done += length / line6pcm->properties->bytes_per_frame;
+	line6pcm->pos_out_done +=
+	    length / line6pcm->properties->bytes_per_frame;
 
 	if (line6pcm->pos_out_done >= runtime->buffer_size)
 		line6pcm->pos_out_done -= runtime->buffer_size;
@@ -261,7 +282,8 @@
 	if (!shutdown) {
 		submit_audio_out_urb(substream);
 
-		if ((line6pcm->bytes_out += length) >= line6pcm->period_out) {
+		line6pcm->bytes_out += length;
+		if (line6pcm->bytes_out >= line6pcm->period_out) {
 			line6pcm->bytes_out -= line6pcm->period_out;
 			snd_pcm_period_elapsed(substream);
 		}
@@ -276,7 +298,8 @@
 	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
 
 	err = snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
-					    (&line6pcm->properties->snd_line6_rates));
+					    (&line6pcm->properties->
+					     snd_line6_rates));
 	if (err < 0)
 		return err;
 
@@ -291,7 +314,8 @@
 }
 
 /* hw_params playback callback */
-static int snd_line6_playback_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params)
+static int snd_line6_playback_hw_params(struct snd_pcm_substream *substream,
+					struct snd_pcm_hw_params *hw_params)
 {
 	int ret;
 	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
@@ -349,7 +373,8 @@
 			err = submit_audio_out_all_urbs(substream);
 
 			if (err < 0) {
-				clear_bit(BIT_RUNNING_PLAYBACK, &line6pcm->flags);
+				clear_bit(BIT_RUNNING_PLAYBACK,
+					  &line6pcm->flags);
 				return err;
 			}
 		}
@@ -387,14 +412,14 @@
 
 /* playback operators */
 struct snd_pcm_ops snd_line6_playback_ops = {
-	.open =        snd_line6_playback_open,
-	.close =       snd_line6_playback_close,
-	.ioctl =       snd_pcm_lib_ioctl,
-	.hw_params =   snd_line6_playback_hw_params,
-	.hw_free =     snd_line6_playback_hw_free,
-	.prepare =     snd_line6_prepare,
-	.trigger =     snd_line6_trigger,
-	.pointer =     snd_line6_playback_pointer,
+	.open = snd_line6_playback_open,
+	.close = snd_line6_playback_close,
+	.ioctl = snd_pcm_lib_ioctl,
+	.hw_params = snd_line6_playback_hw_params,
+	.hw_free = snd_line6_playback_hw_free,
+	.prepare = snd_line6_prepare,
+	.trigger = snd_line6_trigger,
+	.pointer = snd_line6_playback_pointer,
 };
 
 int create_audio_out_urbs(struct snd_line6_pcm *line6pcm)
@@ -406,7 +431,8 @@
 		struct urb *urb;
 
 		/* URB for audio out: */
-		urb = line6pcm->urb_audio_out[i] = usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
+		urb = line6pcm->urb_audio_out[i] =
+		    usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
 
 		if (urb == NULL) {
 			dev_err(line6pcm->line6->ifcdev, "Out of memory\n");
@@ -414,7 +440,10 @@
 		}
 
 		urb->dev = line6pcm->line6->usbdev;
-		urb->pipe = usb_sndisocpipe(line6pcm->line6->usbdev, line6pcm->ep_audio_write & USB_ENDPOINT_NUMBER_MASK);
+		urb->pipe =
+		    usb_sndisocpipe(line6pcm->line6->usbdev,
+				    line6pcm->
+				    ep_audio_write & USB_ENDPOINT_NUMBER_MASK);
 		urb->transfer_flags = URB_ISO_ASAP;
 		urb->start_frame = -1;
 		urb->number_of_packets = LINE6_ISO_PACKETS;
diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c
index 4c5b9d5..685c529 100644
--- a/drivers/staging/line6/pod.c
+++ b/drivers/staging/line6/pod.c
@@ -422,13 +422,21 @@
 /*
 	Resolve value to memory location.
 */
-static void pod_resolve(const char *buf, short block0, short block1, unsigned char *location)
+static int pod_resolve(const char *buf, short block0, short block1, unsigned char *location)
 {
-	int value = simple_strtoul(buf, NULL, 10);
-	short block = (value < 0x40) ? block0 : block1;
+	unsigned long value;
+	short block;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &value);
+	if (ret)
+		return ret;
+
+	block = (value < 0x40) ? block0 : block1;
 	value &= 0x3f;
 	location[0] = block >> 7;
 	location[1] = value | (block & 0x7f);
+	return 0;
 }
 
 /*
@@ -438,14 +446,20 @@
 {
 	struct usb_interface *interface = to_usb_interface(dev);
 	struct usb_line6_pod *pod = usb_get_intfdata(interface);
-
+	int ret;
 	int size = 3 + sizeof(pod->prog_data_buf);
 	char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_STORE, size);
+
 	if (!sysex)
 		return 0;
 
 	sysex[SYSEX_DATA_OFS] = 5;  /* see pod_dump() */
-	pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS + 1);
+	ret = pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS + 1);
+	if (ret) {
+		kfree(sysex);
+		return ret;
+	}
+
 	memcpy(sysex + SYSEX_DATA_OFS + 3, &pod->prog_data_buf, sizeof(pod->prog_data_buf));
 
 	line6_send_sysex_message(&pod->line6, sysex, size);
@@ -461,13 +475,18 @@
 {
 	struct usb_interface *interface = to_usb_interface(dev);
 	struct usb_line6_pod *pod = usb_get_intfdata(interface);
+	int ret;
 	int size = 4;
 	char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_DUMPMEM, size);
 
 	if (!sysex)
 		return 0;
 
-	pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS);
+	ret = pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS);
+	if (ret) {
+		kfree(sysex);
+		return ret;
+	}
 	sysex[SYSEX_DATA_OFS + 2] = 0;
 	sysex[SYSEX_DATA_OFS + 3] = 0;
 	line6_dump_started(&pod->dumpreq, POD_DUMP_MEMORY);
@@ -526,7 +545,13 @@
 {
 	struct usb_interface *interface = to_usb_interface(dev);
 	struct usb_line6_pod *pod = usb_get_intfdata(interface);
-	int value = simple_strtoul(buf, NULL, 10);
+	unsigned long value;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &value);
+	if (ret)
+		return ret;
+
 	pod_send_channel(pod, value);
 	return count;
 }
@@ -579,7 +604,7 @@
 
 	if (count != sizeof(pod->prog_data)) {
 		dev_err(pod->line6.ifcdev,
-			"data block must be exactly %d bytes\n",
+			"data block must be exactly %zu bytes\n",
 			sizeof(pod->prog_data));
 		return -EINVAL;
 	}
@@ -645,6 +670,8 @@
 	char *sysex;
 	static const int size = 5;
 	unsigned short value;
+	unsigned long result;
+	int ret;
 
 	if (((pod->prog_data.control[POD_tuner] & 0x40) == 0) && tuner)
 		return -EINVAL;
@@ -653,7 +680,12 @@
 	sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
 	if (!sysex)
 		return 0;
-	value = simple_strtoul(buf, NULL, 10) & mask;
+
+	ret = strict_strtoul(buf, 10, &result);
+	if (ret)
+		return ret;
+
+	value = result & mask;
 	sysex[SYSEX_DATA_OFS] = code;
 	sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
 	sysex[SYSEX_DATA_OFS + 2] = (value >>  8) & 0x0f;
@@ -691,7 +723,7 @@
 
 	if (count != sizeof(pod->prog_data)) {
 		dev_err(pod->line6.ifcdev,
-						"data block must be exactly %d bytes\n",
+						"data block must be exactly %zu bytes\n",
 						sizeof(pod->prog_data));
 		return -EINVAL;
 	}
@@ -812,7 +844,13 @@
 {
 	struct usb_interface *interface = to_usb_interface(dev);
 	struct usb_line6_pod *pod = usb_get_intfdata(interface);
-	int value = simple_strtoul(buf, NULL, 10);
+	unsigned long value;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &value);
+	if (ret)
+		return ret;
+
 	pod->midi_postprocess = value ? 1 : 0;
 	return count;
 }
diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c
index eaa1229..e6770ea 100644
--- a/drivers/staging/line6/toneport.c
+++ b/drivers/staging/line6/toneport.c
@@ -17,10 +17,8 @@
 #include "playback.h"
 #include "toneport.h"
 
-
 static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2);
 
-
 static struct snd_ratden toneport_ratden = {
 	.num_min = 44100,
 	.num_max = 44100,
@@ -29,47 +27,44 @@
 };
 
 static struct line6_pcm_properties toneport_pcm_properties = {
-  .snd_line6_playback_hw = {
-		.info = (SNDRV_PCM_INFO_MMAP |
-						 SNDRV_PCM_INFO_INTERLEAVED |
-						 SNDRV_PCM_INFO_BLOCK_TRANSFER |
-						 SNDRV_PCM_INFO_MMAP_VALID |
-						 SNDRV_PCM_INFO_PAUSE |
-						 SNDRV_PCM_INFO_SYNC_START),
-		.formats =          SNDRV_PCM_FMTBIT_S16_LE,
-		.rates =            SNDRV_PCM_RATE_KNOT,
-		.rate_min =         44100,
-		.rate_max =         44100,
-		.channels_min =     2,
-		.channels_max =     2,
-		.buffer_bytes_max = 60000,
-		.period_bytes_min = 180 * 4,
-		.period_bytes_max = 8192,
-		.periods_min =      1,
-		.periods_max =      1024
-	},
-  .snd_line6_capture_hw = {
-		.info = (SNDRV_PCM_INFO_MMAP |
-						 SNDRV_PCM_INFO_INTERLEAVED |
-						 SNDRV_PCM_INFO_BLOCK_TRANSFER |
-						 SNDRV_PCM_INFO_MMAP_VALID |
-						 SNDRV_PCM_INFO_SYNC_START),
-		.formats =          SNDRV_PCM_FMTBIT_S16_LE,
-		.rates =            SNDRV_PCM_RATE_KNOT,
-		.rate_min =         44100,
-		.rate_max =         44100,
-		.channels_min =     2,
-		.channels_max =     2,
-		.buffer_bytes_max = 60000,
-		.period_bytes_min = 188 * 4,
-		.period_bytes_max = 8192,
-		.periods_min =      1,
-		.periods_max =      1024
-	},
+	.snd_line6_playback_hw = {
+				  .info = (SNDRV_PCM_INFO_MMAP |
+					   SNDRV_PCM_INFO_INTERLEAVED |
+					   SNDRV_PCM_INFO_BLOCK_TRANSFER |
+					   SNDRV_PCM_INFO_MMAP_VALID |
+					   SNDRV_PCM_INFO_PAUSE |
+					   SNDRV_PCM_INFO_SYNC_START),
+				  .formats = SNDRV_PCM_FMTBIT_S16_LE,
+				  .rates = SNDRV_PCM_RATE_KNOT,
+				  .rate_min = 44100,
+				  .rate_max = 44100,
+				  .channels_min = 2,
+				  .channels_max = 2,
+				  .buffer_bytes_max = 60000,
+				  .period_bytes_min = 180 * 4,
+				  .period_bytes_max = 8192,
+				  .periods_min = 1,
+				  .periods_max = 1024},
+	.snd_line6_capture_hw = {
+				 .info = (SNDRV_PCM_INFO_MMAP |
+					  SNDRV_PCM_INFO_INTERLEAVED |
+					  SNDRV_PCM_INFO_BLOCK_TRANSFER |
+					  SNDRV_PCM_INFO_MMAP_VALID |
+					  SNDRV_PCM_INFO_SYNC_START),
+				 .formats = SNDRV_PCM_FMTBIT_S16_LE,
+				 .rates = SNDRV_PCM_RATE_KNOT,
+				 .rate_min = 44100,
+				 .rate_max = 44100,
+				 .channels_min = 2,
+				 .channels_max = 2,
+				 .buffer_bytes_max = 60000,
+				 .period_bytes_min = 188 * 4,
+				 .period_bytes_max = 8192,
+				 .periods_min = 1,
+				 .periods_max = 1024},
 	.snd_line6_rates = {
-		.nrats = 1,
-		.rats = &toneport_ratden
-	},
+			    .nrats = 1,
+			    .rats = &toneport_ratden},
 	.bytes_per_frame = 4
 };
 
@@ -101,8 +96,14 @@
 				    struct device_attribute *attr,
 				    const char *buf, size_t count)
 {
-	char *c;
-	led_red = simple_strtol(buf, &c, 10);
+	int retval;
+	long value;
+
+	retval = strict_strtol(buf, 10, &value);
+	if (retval)
+		return retval;
+
+	led_red = value;
 	toneport_update_led(dev);
 	return count;
 }
@@ -111,15 +112,22 @@
 				      struct device_attribute *attr,
 				      const char *buf, size_t count)
 {
-	char *c;
-	led_green = simple_strtol(buf, &c, 10);
+	int retval;
+	long value;
+
+	retval = strict_strtol(buf, 10, &value);
+	if (retval)
+		return retval;
+
+	led_green = value;
 	toneport_update_led(dev);
 	return count;
 }
 
-static DEVICE_ATTR(led_red, S_IWUGO | S_IRUGO, line6_nop_read, toneport_set_led_red);
-static DEVICE_ATTR(led_green, S_IWUGO | S_IRUGO, line6_nop_read, toneport_set_led_green);
-
+static DEVICE_ATTR(led_red, S_IWUGO | S_IRUGO, line6_nop_read,
+		   toneport_set_led_red);
+static DEVICE_ATTR(led_green, S_IWUGO | S_IRUGO, line6_nop_read,
+		   toneport_set_led_green);
 
 static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2)
 {
@@ -196,16 +204,18 @@
 	line6_write_data(line6, 0x80c6, &ticks, 4);
 
 	/*
-	seems to work without the first two...
-	*/
+	   seems to work without the first two...
+	 */
 	/* toneport_send_cmd(usbdev, 0x0201, 0x0002); */
 	/* toneport_send_cmd(usbdev, 0x0801, 0x0000); */
 	/* only one that works for me; on GP, TP might be different? */
 	toneport_send_cmd(usbdev, 0x0301, 0x0000);
 
 	if (usbdev->descriptor.idProduct != LINE6_DEVID_GUITARPORT) {
-		CHECK_RETURN(device_create_file(&interface->dev, &dev_attr_led_red));
-		CHECK_RETURN(device_create_file(&interface->dev, &dev_attr_led_green));
+		CHECK_RETURN(device_create_file
+			     (&interface->dev, &dev_attr_led_red));
+		CHECK_RETURN(device_create_file
+			     (&interface->dev, &dev_attr_led_green));
 		toneport_update_led(&usbdev->dev);
 	}
 
@@ -223,7 +233,8 @@
 		return;
 	toneport = usb_get_intfdata(interface);
 
-	if (toneport->line6.usbdev->descriptor.idProduct != LINE6_DEVID_GUITARPORT) {
+	if (toneport->line6.usbdev->descriptor.idProduct !=
+	    LINE6_DEVID_GUITARPORT) {
 		device_remove_file(&interface->dev, &dev_attr_led_red);
 		device_remove_file(&interface->dev, &dev_attr_led_green);
 	}
diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c
index f9d9698..48d834b 100644
--- a/drivers/staging/line6/variax.c
+++ b/drivers/staging/line6/variax.c
@@ -184,7 +184,12 @@
 				 const char *buf, size_t count)
 {
 	struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
-	int value = simple_strtoul(buf, NULL, 10);
+	unsigned long value;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &value);
+	if (ret)
+		return ret;
 
 	if (line6_transmit_parameter(&variax->line6, VARIAXMIDI_volume,
 				     value) == 0)
@@ -211,7 +216,12 @@
 				const char *buf, size_t count)
 {
 	struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
-	int value = simple_strtoul(buf, NULL, 10);
+	unsigned long value;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &value);
+	if (ret)
+		return ret;
 
 	if (line6_send_program(&variax->line6, value) == 0)
 		variax->model = value;
@@ -237,8 +247,14 @@
 				 const char *buf, size_t count)
 {
 	struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
-	int value = simple_strtoul(buf, NULL, 10) ? 1 : 0;
-	variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = value;
+	unsigned long value;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &value);
+	if (ret)
+		return ret;
+
+	variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = value ? 1: 0;
 	line6_send_raw_message_async(&variax->line6, variax->buffer_activate,
 				     sizeof(variax_activate));
 	return count;
@@ -262,7 +278,12 @@
 			       const char *buf, size_t count)
 {
 	struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
-	int value = simple_strtoul(buf, NULL, 10);
+	unsigned long value;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &value);
+	if (ret)
+		return ret;
 
 	if (line6_transmit_parameter(&variax->line6, VARIAXMIDI_tone,
 				     value) == 0)
diff --git a/drivers/staging/octeon/cvmx-pow.h b/drivers/staging/octeon/cvmx-pow.h
index c5d66f2..bf9e069 100644
--- a/drivers/staging/octeon/cvmx-pow.h
+++ b/drivers/staging/octeon/cvmx-pow.h
@@ -1959,7 +1959,7 @@
  * @buffer_size:
  *               The size of the supplied buffer
  *
- * Returns Zero on sucess, negative on failure
+ * Returns Zero on success, negative on failure
  */
 extern int cvmx_pow_capture(void *buffer, int buffer_size);
 
diff --git a/drivers/staging/octeon/ethernet-rgmii.c b/drivers/staging/octeon/ethernet-rgmii.c
index 8704133..fbaa465 100644
--- a/drivers/staging/octeon/ethernet-rgmii.c
+++ b/drivers/staging/octeon/ethernet-rgmii.c
@@ -308,7 +308,7 @@
 
 	/*
 	 * Due to GMX errata in CN3XXX series chips, it is necessary
-	 * to take the link down immediately whne the PHY changes
+	 * to take the link down immediately when the PHY changes
 	 * state. In order to do this we call the poll function every
 	 * time the RGMII inband status changes.  This may cause
 	 * problems if the PHY doesn't implement inband status
@@ -317,6 +317,8 @@
 	if (number_rgmii_ports == 0) {
 		r = request_irq(OCTEON_IRQ_RML, cvm_oct_rgmii_rml_interrupt,
 				IRQF_SHARED, "RGMII", &number_rgmii_ports);
+		if (r != 0)
+			return r;
 	}
 	number_rgmii_ports++;
 
diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c
index 81a8513..5352941 100644
--- a/drivers/staging/octeon/ethernet-tx.c
+++ b/drivers/staging/octeon/ethernet-tx.c
@@ -624,7 +624,7 @@
 EXPORT_SYMBOL(cvm_oct_transmit_qos);
 
 /**
- * This function frees all skb that are currenty queued for TX.
+ * This function frees all skb that are currently queued for TX.
  *
  * @dev:    Device being shutdown
  */
diff --git a/drivers/staging/otus/80211core/ccmd.c b/drivers/staging/otus/80211core/ccmd.c
index 83dd8ba..8da28ee 100644
--- a/drivers/staging/otus/80211core/ccmd.c
+++ b/drivers/staging/otus/80211core/ccmd.c
@@ -899,7 +899,7 @@
 		zfStaDisableSWEncryption(dev);
 	}
 
-	/* Improve WEP/TKIP performace with HT AP,
+	/* Improve WEP/TKIP performance with HT AP,
 	detail information please look bug#32495 */
 	/* zfHpSetTTSIFSTime(dev, 0x8); */
 
@@ -1407,7 +1407,7 @@
 		zfStaDisableSWEncryption(dev);
 	}
 
-	/* 	Improve WEP/TKIP performace with HT AP,
+	/* 	Improve WEP/TKIP performance with HT AP,
 		detail information please look bug#32495
 	*/
 	/* zfHpSetTTSIFSTime(dev, 0x8); */
diff --git a/drivers/staging/otus/80211core/cmm.c b/drivers/staging/otus/80211core/cmm.c
index bed16b5..a6c1b41 100644
--- a/drivers/staging/otus/80211core/cmm.c
+++ b/drivers/staging/otus/80211core/cmm.c
@@ -1428,7 +1428,7 @@
         {
                 /* Beacon */
             case ZM_WLAN_FRAME_TYPE_BEACON :
-                /* if enable 802.11h and current chanel is silent but receive beacon from other AP */
+                /* if enable 802.11h and current channel is silent but receive beacon from other AP */
                 if (((wd->regulationTable.allowChannel[wd->regulationTable.CurChIndex].channelFlags
                         & ZM_REG_FLAG_CHANNEL_CSA) != 0) && wd->sta.DFSEnable)
                 {
@@ -1469,7 +1469,7 @@
                 break;
                 /* Probe response */
             case ZM_WLAN_FRAME_TYPE_PROBERSP :
-                /* if enable 802.11h and current chanel is silent but receive probe response from other AP */
+                /* if enable 802.11h and current channel is silent but receive probe response from other AP */
                 if (((wd->regulationTable.allowChannel[wd->regulationTable.CurChIndex].channelFlags
                         & ZM_REG_FLAG_CHANNEL_CSA) != 0) && wd->sta.DFSEnable)
                 {
diff --git a/drivers/staging/otus/80211core/cmmsta.c b/drivers/staging/otus/80211core/cmmsta.c
index b28a4e2..a11d559 100644
--- a/drivers/staging/otus/80211core/cmmsta.c
+++ b/drivers/staging/otus/80211core/cmmsta.c
@@ -216,7 +216,7 @@
     /* Change internal state */
     zfChangeAdapterState(dev, ZM_STA_STATE_DISCONNECT);
 
-    /* Improve WEP/TKIP performace with HT AP, detail information please look bug#32495 */
+    /* Improve WEP/TKIP performance with HT AP, detail information please look bug#32495 */
     //zfHpSetTTSIFSTime(dev, 0x8);
 
     /* Notify wrapper of connection status changes */
@@ -4148,7 +4148,7 @@
             wd->sta.bIsSharedKey = 0;
         }
 
-        /* Improve WEP/TKIP performace with HT AP, detail information please look bug#32495 */
+        /* Improve WEP/TKIP performance with HT AP, detail information please look bug#32495 */
         /*
         if ( (pBssInfo->broadcomHTAp == 1)
              && (wd->sta.SWEncryptEnable != 0) )
diff --git a/drivers/staging/otus/80211core/ctxrx.c b/drivers/staging/otus/80211core/ctxrx.c
index e258a7d..ac54d5a 100644
--- a/drivers/staging/otus/80211core/ctxrx.c
+++ b/drivers/staging/otus/80211core/ctxrx.c
@@ -3093,7 +3093,7 @@
 
     frameType = zmw_rx_buf_readh(dev, buf, offset);
 
-    // Don't divide 2^4 because we don't want the fragementation pkt to be treated as
+    // Don't divide 2^4 because we don't want the fragmentation pkt to be treated as
     // duplicated frames
     seq = zmw_rx_buf_readh(dev, buf, offset+22);
     dst0 = zmw_rx_buf_readh(dev, buf, offset+4);
diff --git a/drivers/staging/otus/80211core/pub_zfi.h b/drivers/staging/otus/80211core/pub_zfi.h
index a35bd5d..b7b7f45 100644
--- a/drivers/staging/otus/80211core/pub_zfi.h
+++ b/drivers/staging/otus/80211core/pub_zfi.h
@@ -20,7 +20,7 @@
 #include "../oal_dt.h"
 
 /***** Section 1 : Tunable Parameters *****/
-/* The defintions in this section are tunabel parameters */
+/* The definitions in this section are tunabel parameters */
 
 /* Maximum number of BSS that could be scaned */
 #define ZM_MAX_BSS                          128
@@ -782,7 +782,7 @@
 
 /***** End of section 2 *****/
 
-/***** section 3 performace evaluation *****/
+/***** section 3 performance evaluation *****/
 #ifdef ZM_ENABLE_PERFORMANCE_EVALUATION
 extern void zfiTxPerformanceMSDU(zdev_t* dev, u32_t tick);
 extern void zfiRxPerformanceMPDU(zdev_t* dev, zbuf_t* buf);
diff --git a/drivers/staging/otus/apdbg.c b/drivers/staging/otus/apdbg.c
index d3e2f62..0eb93f1 100644
--- a/drivers/staging/otus/apdbg.c
+++ b/drivers/staging/otus/apdbg.c
@@ -38,39 +38,39 @@
 
 #include <linux/sockios.h>
 
-#define ZM_IOCTL_REG_READ           0x01
-#define ZM_IOCTL_REG_WRITE          0x02
-#define ZM_IOCTL_MEM_DUMP           0x03
-#define ZM_IOCTL_REG_DUMP           0x05
-#define ZM_IOCTL_TXD_DUMP           0x06
-#define ZM_IOCTL_RXD_DUMP           0x07
-#define ZM_IOCTL_MEM_READ           0x0B
-#define ZM_IOCTL_MEM_WRITE          0x0C
-#define ZM_IOCTL_DMA_TEST           0x10
-#define ZM_IOCTL_REG_TEST           0x11
-#define ZM_IOCTL_TEST               0x80
-#define ZM_IOCTL_TALLY              0x81 //CWYang(+)
-#define ZM_IOCTL_RTS                0xA0
-#define ZM_IOCTL_MIX_MODE           0xA1
-#define ZM_IOCTL_FRAG               0xA2
-#define ZM_IOCTL_SCAN               0xA3
-#define ZM_IOCTL_KEY                0xA4
-#define ZM_IOCTL_RATE               0xA5
-#define ZM_IOCTL_ENCRYPTION_MODE    0xA6
-#define ZM_IOCTL_GET_TXCNT          0xA7
-#define ZM_IOCTL_GET_DEAGG_CNT      0xA8
-#define ZM_IOCTL_DURATION_MODE      0xA9
-#define ZM_IOCTL_SET_AES_KEY        0xAA
-#define ZM_IOCTL_SET_AES_MODE       0xAB
-#define ZM_IOCTL_SIGNAL_STRENGTH    0xAC //CWYang(+)
-#define ZM_IOCTL_SIGNAL_QUALITY     0xAD //CWYang(+)
-#define ZM_IOCTL_SET_PIBSS_MODE     0xAE
-#define	ZDAPIOCTL                   SIOCDEVPRIVATE
+#define ZM_IOCTL_REG_READ			0x01
+#define ZM_IOCTL_REG_WRITE			0x02
+#define ZM_IOCTL_MEM_DUMP			0x03
+#define ZM_IOCTL_REG_DUMP			0x05
+#define ZM_IOCTL_TXD_DUMP			0x06
+#define ZM_IOCTL_RXD_DUMP			0x07
+#define ZM_IOCTL_MEM_READ			0x0B
+#define ZM_IOCTL_MEM_WRITE			0x0C
+#define ZM_IOCTL_DMA_TEST			0x10
+#define ZM_IOCTL_REG_TEST			0x11
+#define ZM_IOCTL_TEST				0x80
+#define ZM_IOCTL_TALLY				0x81 /* CWYang(+) */
+#define ZM_IOCTL_RTS				0xA0
+#define ZM_IOCTL_MIX_MODE			0xA1
+#define ZM_IOCTL_FRAG				0xA2
+#define ZM_IOCTL_SCAN				0xA3
+#define ZM_IOCTL_KEY				0xA4
+#define ZM_IOCTL_RATE				0xA5
+#define ZM_IOCTL_ENCRYPTION_MODE		0xA6
+#define ZM_IOCTL_GET_TXCNT			0xA7
+#define ZM_IOCTL_GET_DEAGG_CNT			0xA8
+#define ZM_IOCTL_DURATION_MODE			0xA9
+#define ZM_IOCTL_SET_AES_KEY			0xAA
+#define ZM_IOCTL_SET_AES_MODE			0xAB
+#define ZM_IOCTL_SIGNAL_STRENGTH		0xAC /* CWYang(+) */
+#define ZM_IOCTL_SIGNAL_QUALITY			0xAD /* CWYang(+) */
+#define ZM_IOCTL_SET_PIBSS_MODE			0xAE
+#define	ZDAPIOCTL				SIOCDEVPRIVATE
 
 struct zdap_ioctl {
-	unsigned short cmd;                /* Command to run */
-	unsigned int   addr;                /* Length of the data buffer */
-	unsigned int   value;               /* Pointer to the data buffer */
+	unsigned short cmd;			/* Command to run */
+	unsigned int   addr;			/* Length of the data buffer */
+	unsigned int   value;			/* Pointer to the data buffer */
 	unsigned char data[0x100];
 };
 
@@ -79,13 +79,13 @@
 #if 0
 
 #define SKIP_ELEM { \
-    while(isxdigit(*p)) \
-        p++; \
+	while (isxdigit(*p)) \
+		p++; \
 }
 
 #define SKIP_DELIMETER { \
-    if(*p == ':' || *p == ' ') \
-        p++; \
+	if (*p == ':' || *p == ' ') \
+		p++; \
 }
 
 #endif
@@ -97,361 +97,308 @@
 
 int set_ioctl(int sock, struct ifreq *req)
 {
-    if (ioctl(sock, ZDAPIOCTL, req) < 0) {
-        fprintf(stderr, "%s: ioctl(SIOCGIFMAP): %s\n",
-                prgname, strerror(errno));
-        return -1;
-    }
+	if (ioctl(sock, ZDAPIOCTL, req) < 0) {
+		fprintf(stderr, "%s: ioctl(SIOCGIFMAP): %s\n",
+			prgname, strerror(errno));
+		return -1;
+	}
 
-    return 0;
+	return 0;
 }
 
 
 int read_reg(int sock, struct ifreq *req)
 {
-    struct zdap_ioctl *zdreq = 0;
+	struct zdap_ioctl *zdreq = 0;
 
-    if (!set_ioctl(sock, req))
-        return -1;
+	if (!set_ioctl(sock, req))
+			return -1;
 
-    //zdreq = (struct zdap_ioctl *)req->ifr_data;
-    //printf( "reg = %4x, value = %4x\n", zdreq->addr, zdreq->value);
+	/*
+	 * zdreq = (struct zdap_ioctl *)req->ifr_data;
+	 * printf( "reg = %4x, value = %4x\n", zdreq->addr, zdreq->value);
+	 */
 
-    return 0;
+	return 0;
 }
 
 
 int read_mem(int sock, struct ifreq *req)
 {
-    struct zdap_ioctl *zdreq = 0;
-    int i;
+	struct zdap_ioctl *zdreq = 0;
+	int i;
 
-    if (!set_ioctl(sock, req))
-        return -1;
+	if (!set_ioctl(sock, req))
+		return -1;
 
-    /*zdreq = (struct zdap_ioctl *)req->ifr_data;
-    printf( "dump mem from %x, length = %x\n", zdreq->addr, zdreq->value);
+	/*
+	 * zdreq = (struct zdap_ioctl *)req->ifr_data;
+	 * printf("dump mem from %x, length = %x\n", zdreq->addr, zdreq->value);
+	 *
+	 * for (i=0; i<zdreq->value; i++) {
+	 *	printf("%02x", zdreq->data[i]);
+	 *	printf(" ");
+	 *
+	 *	if ((i>0) && ((i+1)%16 == 0))
+	 *		printf("\n");
+	 * }
+	 */
 
-    for (i=0; i<zdreq->value; i++) {
-        printf("%02x", zdreq->data[i]);
-        printf(" ");
-
-        if ((i>0) && ((i+1)%16 == 0))
-            printf("\n");
-    }*/
-
-    return 0;
+	return 0;
 }
 
 
 int main(int argc, char **argv)
 {
-    int sock;
-    int addr, value;
-    struct ifreq req;
-    char *action = NULL;
-    struct zdap_ioctl zdreq;
+	int sock;
+	int addr, value;
+	struct ifreq req;
+	char *action = NULL;
+	struct zdap_ioctl zdreq;
 
-    prgname = argv[0];
+	prgname = argv[0];
 
-    if (argc < 3) {
-        fprintf(stderr,"%s: usage is \"%s <ifname> <operation> [<address>] [<value>]\"\n",
-                prgname, prgname);
-        fprintf(stderr,"valid operation: read, write, mem, reg,\n");
-        fprintf(stderr,"               : txd, rxd, rmem, wmem\n");
-        fprintf(stderr,"               : dmat, regt, test\n");
+	if (argc < 3) {
+		fprintf(stderr, "%s: usage is \"%s <ifname> <operation>"
+				"[<address>] [<value>]\"\n", prgname, prgname);
+		fprintf(stderr, "valid operation : read, write, mem, reg, \n");
+		fprintf(stderr, "		: txd, rxd, rmem, wmem\n");
+		fprintf(stderr, "		: dmat, regt, test\n");
 
-        fprintf(stderr,"    scan, Channel Scan\n");
-        fprintf(stderr,"    rts <decimal>, Set RTS Threshold\n");
-        fprintf(stderr,"    frag <decimal>, Set Fragment Threshold\n");
-        fprintf(stderr,"    rate <0-28>, 0:AUTO, 1-4:CCK, 5-12:OFDM, 13-28:HT\n");
-        fprintf(stderr,"    TBD mix <0 or 1>, Set 1 to enable mixed mode\n");
-        fprintf(stderr,"    enc, <0-3>, 0=>OPEN, 1=>WEP64, 2=>WEP128, 3=>WEP256\n");
-        fprintf(stderr,"    skey <key>, Set WEP key\n");
-        fprintf(stderr,"    txcnt, Get TxQ Cnt\n");
-        fprintf(stderr,"    dagcnt, Get Deaggregate Cnt\n");
-        fprintf(stderr,"    durmode <mode>, Set Duration Mode 0=>HW, 1=>SW\n");
-        fprintf(stderr,"    aeskey <user> <key>\n");
-        fprintf(stderr,"    aesmode <mode>\n");
-        fprintf(stderr,"    wlanmode <0,1> 0:Station mode, 1:PIBSS mode\n");
-        fprintf(stderr,"    tal <0,1>, Get Current Tally Info, 0=>read, 1=>read and reset\n");
+		fprintf(stderr, "	scan, Channel Scan\n");
+		fprintf(stderr, "	rts <decimal>, Set RTS Threshold\n");
+		fprintf(stderr, "	frag <decimal>, Set Fragment"
+			" Threshold\n");
+		fprintf(stderr, "	rate <0-28>, 0:AUTO, 1-4:CCK,"
+			" 5-12:OFDM, 13-28:HT\n");
+		fprintf(stderr, "	TBD mix <0 or 1>, Set 1 to enable"
+			" mixed mode\n");
+		fprintf(stderr, "	enc, <0-3>, 0=>OPEN, 1=>WEP64, "
+			"2=>WEP128, 3=>WEP256\n");
+		fprintf(stderr, "	skey <key>, Set WEP key\n");
+		fprintf(stderr, "	txcnt, Get TxQ Cnt\n");
+		fprintf(stderr, "	dagcnt, Get Deaggregate Cnt\n");
+		fprintf(stderr, "	durmode <mode>, Set Duration Mode "
+			"0=>HW, 1=>SW\n");
+		fprintf(stderr, "	aeskey <user> <key>\n");
+		fprintf(stderr, "	aesmode <mode>\n");
+		fprintf(stderr, "	wlanmode <0,1> 0:Station mode, "
+			"1:PIBSS mode\n");
+		fprintf(stderr, "	tal <0,1>, Get Current Tally Info, "
+			"0=>read, 1=>read and reset\n");
 
-        exit(1);
-    }
+		exit(1);
+	}
 
-    strcpy(req.ifr_name, argv[1]);
-    zdreq.addr = 0;
-    zdreq.value = 0;
+	strcpy(req.ifr_name, argv[1]);
+	zdreq.addr = 0;
+	zdreq.value = 0;
 
-    /* a silly raw socket just for ioctl()ling it */
-    sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
-    if (sock < 0) {
-        fprintf(stderr, "%s: socket(): %s\n", argv[0], strerror(errno));
-        exit(1);
-    }
+	/* a silly raw socket just for ioctl()ling it */
+	sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
+	if (sock < 0) {
+		fprintf(stderr, "%s: socket(): %s\n", argv[0], strerror(errno));
+		exit(1);
+	}
 
-    if (argc >= 4)
-    {
-        sscanf(argv[3], "%x", &addr);
-    }
+	if (argc >= 4)
+		sscanf(argv[3], "%x", &addr);
 
-    if (argc >= 5)
-    {
-        sscanf(argv[4], "%x", &value);
-    }
+	if (argc >= 5)
+		sscanf(argv[4], "%x", &value);
 
-    zdreq.addr = addr;
-    zdreq.value = value;
+	zdreq.addr = addr;
+	zdreq.value = value;
 
-    if (!strcmp(argv[2], "read"))
-    {
-        zdreq.cmd = ZM_IOCTL_REG_READ;
-    }
-    else if (!strcmp(argv[2], "mem"))
-    {
-        zdreq.cmd = ZM_IOCTL_MEM_DUMP;
-    }
-    else if (!strcmp(argv[2], "write"))
-    {
-        zdreq.cmd = ZM_IOCTL_REG_WRITE;
-    }
-    else if (!strcmp(argv[2], "reg"))
-    {
-        zdreq.cmd = ZM_IOCTL_REG_DUMP;
-    }
-    else if (!strcmp(argv[2], "txd"))
-    {
-        zdreq.cmd = ZM_IOCTL_TXD_DUMP;
-    }
-    else if (!strcmp(argv[2], "rxd"))
-    {
-        zdreq.cmd = ZM_IOCTL_RXD_DUMP;
-    }
-    else if (!strcmp(argv[2], "rmem"))
-    {
-        zdreq.cmd = ZM_IOCTL_MEM_READ;
-    }
-    else if (!strcmp(argv[2], "wmem"))
-    {
-        zdreq.cmd = ZM_IOCTL_MEM_WRITE;
-    }
-    else if (!strcmp(argv[2], "dmat"))
-    {
-        zdreq.cmd = ZM_IOCTL_DMA_TEST;
-    }
-    else if (!strcmp(argv[2], "regt"))
-    {
-        zdreq.cmd = ZM_IOCTL_REG_TEST;
-    }
-    else if (!strcmp(argv[2], "test"))
-    {
-        zdreq.cmd = ZM_IOCTL_TEST;
-    }
-    else if (!strcmp(argv[2], "tal"))
-    {
-        sscanf(argv[3], "%d", &addr);
-        zdreq.addr = addr;
-        zdreq.cmd = ZM_IOCTL_TALLY;
-    }
-    else if (!strcmp(argv[2], "rts"))
-    {
-        sscanf(argv[3], "%d", &addr);
-        zdreq.addr = addr;
-        zdreq.cmd = ZM_IOCTL_RTS;
-    }
-    else if (!strcmp(argv[2], "mix"))
-    {
-        zdreq.cmd = ZM_IOCTL_MIX_MODE;
-    }
-    else if (!strcmp(argv[2], "frag"))
-    {
-        sscanf(argv[3], "%d", &addr);
-        zdreq.addr = addr;
-        zdreq.cmd = ZM_IOCTL_FRAG;
-    }
-    else if (!strcmp(argv[2], "scan"))
-    {
-        zdreq.cmd = ZM_IOCTL_SCAN;
-    }
-    else if (!strcmp(argv[2], "skey"))
-    {
-        zdreq.cmd = ZM_IOCTL_KEY;
+	if (!strcmp(argv[2], "read"))
+		zdreq.cmd = ZM_IOCTL_REG_READ;
+	else if (!strcmp(argv[2], "mem"))
+		zdreq.cmd = ZM_IOCTL_MEM_DUMP;
+	else if (!strcmp(argv[2], "write"))
+		zdreq.cmd = ZM_IOCTL_REG_WRITE;
+	else if (!strcmp(argv[2], "reg"))
+		zdreq.cmd = ZM_IOCTL_REG_DUMP;
+	else if (!strcmp(argv[2], "txd"))
+		zdreq.cmd = ZM_IOCTL_TXD_DUMP;
+	else if (!strcmp(argv[2], "rxd"))
+		zdreq.cmd = ZM_IOCTL_RXD_DUMP;
+	else if (!strcmp(argv[2], "rmem"))
+		zdreq.cmd = ZM_IOCTL_MEM_READ;
+	else if (!strcmp(argv[2], "wmem"))
+		zdreq.cmd = ZM_IOCTL_MEM_WRITE;
+	else if (!strcmp(argv[2], "dmat"))
+		zdreq.cmd = ZM_IOCTL_DMA_TEST;
+	else if (!strcmp(argv[2], "regt"))
+		zdreq.cmd = ZM_IOCTL_REG_TEST;
+	else if (!strcmp(argv[2], "test"))
+		zdreq.cmd = ZM_IOCTL_TEST;
+	else if (!strcmp(argv[2], "tal")) {
+		sscanf(argv[3], "%d", &addr);
+		zdreq.addr = addr;
+		zdreq.cmd = ZM_IOCTL_TALLY;
+	} else if (!strcmp(argv[2], "rts")) {
+		sscanf(argv[3], "%d", &addr);
+		zdreq.addr = addr;
+		zdreq.cmd = ZM_IOCTL_RTS;
+	} else if (!strcmp(argv[2], "mix")) {
+		zdreq.cmd = ZM_IOCTL_MIX_MODE;
+	} else if (!strcmp(argv[2], "frag")) {
+		sscanf(argv[3], "%d", &addr);
+		zdreq.addr = addr;
+		zdreq.cmd = ZM_IOCTL_FRAG;
+	} else if (!strcmp(argv[2], "scan")) {
+		zdreq.cmd = ZM_IOCTL_SCAN;
+	} else if (!strcmp(argv[2], "skey")) {
+		zdreq.cmd = ZM_IOCTL_KEY;
 
-        if (argc >= 4)
-        {
-            unsigned char temp[29];
-            int i;
-            int keyLen;
-            int encType;
+		if (argc >= 4) {
+			unsigned char temp[29];
+			int i;
+			int keyLen;
+			int encType;
 
-            keyLen = strlen(argv[3]);
+			keyLen = strlen(argv[3]);
 
-            if (keyLen == 10)
-            {
-                sscanf(argv[3], "%02x%02x%02x%02x%02x", &temp[0], &temp[1],
-                        &temp[2], &temp[3], &temp[4]);
-            }
-            else if (keyLen == 26)
-            {
-                sscanf(argv[3], "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
-                        &temp[0], &temp[1], &temp[2], &temp[3], &temp[4],
-                        &temp[5], &temp[6], &temp[7], &temp[8], &temp[9],
-                         &temp[10], &temp[11], &temp[12]);
-            }
-            else if (keyLen == 58)
-            {
-                sscanf(argv[3], "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
-                        &temp[0], &temp[1], &temp[2], &temp[3], &temp[4],
-                        &temp[5], &temp[6], &temp[7], &temp[8], &temp[9],
-                        &temp[10], &temp[11], &temp[12], &temp[13], &temp[14],
-                        &temp[15], &temp[16], &temp[17], &temp[18], &temp[19],
-                        &temp[20], &temp[21], &temp[22], &temp[23], &temp[24],
-                        &temp[25], &temp[26], &temp[27], &temp[28]);
-            }
-            else
-            {
-                fprintf(stderr, "Invalid key length\n");
-                exit(1);
-            }
-            zdreq.addr = keyLen/2;
+			if (keyLen == 10)
+				sscanf(argv[3], "%02x%02x%02x%02x%02x",
+					&temp[0], &temp[1], &temp[2], &temp[3],
+					&temp[4]);
+			else if (keyLen == 26)
+				sscanf(argv[3], "%02x%02x%02x%02x%02x%02x"
+					"%02x%02x%02x%02x%02x%02x%02x",
+					&temp[0], &temp[1], &temp[2], &temp[3],
+					&temp[4], &temp[5], &temp[6], &temp[7],
+					&temp[8], &temp[9], &temp[10],
+					&temp[11], &temp[12]);
+			else if (keyLen == 58)
+				sscanf(argv[3], "%02x%02x%02x%02x%02x%02x"
+					"%02x%02x%02x%02x%02x%02x%02x%02x%02x"
+					"%02x%02x%02x%02x%02x%02x%02x%02x%02x"
+					"%02x%02x%02x%02x%02x",
+					&temp[0], &temp[1], &temp[2], &temp[3],
+					&temp[4], &temp[5], &temp[6], &temp[7],
+					&temp[8], &temp[9], &temp[10],
+					&temp[11], &temp[12], &temp[13],
+					&temp[14], &temp[15], &temp[16],
+					&temp[17], &temp[18], &temp[19],
+					&temp[20], &temp[21], &temp[22],
+					&temp[23], &temp[24], &temp[25],
+					&temp[26], &temp[27], &temp[28]);
+			else {
+				fprintf(stderr, "Invalid key length\n");
+				exit(1);
+			}
+			zdreq.addr = keyLen/2;
 
-            for(i=0; i<zdreq.addr; i++)
-            {
-                zdreq.data[i] = temp[i];
-            }
-        }
-        else
-        {
-            printf("Error : Key required!\n");
-        }
-    }
-    else if (!strcmp(argv[2], "rate"))
-    {
-        sscanf(argv[3], "%d", &addr);
+			for (i = 0; i < zdreq.addr; i++)
+				zdreq.data[i] = temp[i];
+		} else {
+			printf("Error : Key required!\n");
+		}
+	} else if (!strcmp(argv[2], "rate")) {
+		sscanf(argv[3], "%d", &addr);
 
-        if (addr > 28)
-        {
-            fprintf(stderr, "Invalid rate, range:0~28\n");
-            exit(1);
-        }
-        zdreq.addr = addr;
-        zdreq.cmd = ZM_IOCTL_RATE;
-    }
-    else if (!strcmp(argv[2], "enc"))
-    {
-        sscanf(argv[3], "%d", &addr);
+		if (addr > 28) {
+			fprintf(stderr, "Invalid rate, range:0~28\n");
+			exit(1);
+		}
+		zdreq.addr = addr;
+		zdreq.cmd = ZM_IOCTL_RATE;
+	} else if (!strcmp(argv[2], "enc")) {
+		sscanf(argv[3], "%d", &addr);
 
-        if (addr > 3)
-        {
-            fprintf(stderr, "Invalid encryption mode, range:0~3\n");
-            exit(1);
-        }
+		if (addr > 3) {
+			fprintf(stderr, "Invalid encryption mode, range:0~3\n");
+			exit(1);
+		}
 
-        if (addr == 2)
-        {
-            addr = 5;
-        }
-        else if (addr == 3)
-        {
-            addr = 6;
-        }
+		if (addr == 2)
+			addr = 5;
+		else if (addr == 3)
+			addr = 6;
 
-        zdreq.addr = addr;
-        zdreq.cmd = ZM_IOCTL_ENCRYPTION_MODE;
-    }
-    else if (!strcmp(argv[2], "txcnt"))
-    {
-        zdreq.cmd = ZM_IOCTL_GET_TXCNT;
-    }
-    else if (!strcmp(argv[2], "dagcnt"))
-    {
-        sscanf(argv[3], "%d", &addr);
+		zdreq.addr = addr;
+		zdreq.cmd = ZM_IOCTL_ENCRYPTION_MODE;
+	} else if (!strcmp(argv[2], "txcnt")) {
+		zdreq.cmd = ZM_IOCTL_GET_TXCNT;
+	} else if (!strcmp(argv[2], "dagcnt")) {
+		sscanf(argv[3], "%d", &addr);
 
-        if (addr != 0 && addr != 1)
-        {
-            fprintf(stderr, "The value should be 0 or 1\n");
-            exit(0);
-        }
+		if (addr != 0 && addr != 1) {
+			fprintf(stderr, "The value should be 0 or 1\n");
+			exit(0);
+		}
 
-        zdreq.addr = addr;
-        zdreq.cmd = ZM_IOCTL_GET_DEAGG_CNT;
-    }
-    else if (!strcmp(argv[2], "durmode"))
-    {
-        sscanf(argv[3], "%d", &addr);
+		zdreq.addr = addr;
+		zdreq.cmd = ZM_IOCTL_GET_DEAGG_CNT;
+	} else if (!strcmp(argv[2], "durmode"))	{
+		sscanf(argv[3], "%d", &addr);
 
-        if (addr != 0 && addr != 1)
-        {
-            fprintf(stderr, "The Duration mode should be 0 or 1\n");
-            exit(0);
-        }
+		if (addr != 0 && addr != 1) {
+			fprintf(stderr, "The Duration mode should be 0 or 1\n");
+			exit(0);
+		}
 
-        zdreq.addr = addr;
-        zdreq.cmd = ZM_IOCTL_DURATION_MODE;
-    }
-    else if (!strcmp(argv[2], "aeskey"))
-    {
-        unsigned char temp[16];
-        int i;
+		zdreq.addr = addr;
+		zdreq.cmd = ZM_IOCTL_DURATION_MODE;
+	} else if (!strcmp(argv[2], "aeskey")) {
+		unsigned char temp[16];
+		int i;
 
-        sscanf(argv[3], "%d", &addr);
+		sscanf(argv[3], "%d", &addr);
 
-        sscanf(argv[4], "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", &temp[0], &temp[1], &temp[2], &temp[3], &temp[4], &temp[5], &temp[6], &temp[7], &temp[8], &temp[9], &temp[10], &temp[11], &temp[12], &temp[13], &temp[14], &temp[15]);
+		sscanf(argv[4], "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
+			"%02x%02x%02x%02x%02x%02x", &temp[0], &temp[1],
+			&temp[2], &temp[3], &temp[4], &temp[5], &temp[6],
+			&temp[7], &temp[8], &temp[9], &temp[10], &temp[11],
+			&temp[12], &temp[13], &temp[14], &temp[15]);
 
-        for(i = 0; i < 16; i++)
-        {
-            zdreq.data[i] = temp[i];
-        }
+		for (i = 0; i < 16; i++)
+			zdreq.data[i] = temp[i];
 
-        zdreq.addr = addr;
-        zdreq.cmd = ZM_IOCTL_SET_AES_KEY;
-    }
-    else if (!strcmp(argv[2], "aesmode"))
-    {
-        sscanf(argv[3], "%d", &addr);
+		zdreq.addr = addr;
+		zdreq.cmd = ZM_IOCTL_SET_AES_KEY;
+	} else if (!strcmp(argv[2], "aesmode")) {
+		sscanf(argv[3], "%d", &addr);
 
-        zdreq.addr = addr;
-        zdreq.cmd = ZM_IOCTL_SET_AES_MODE;
-    }
-    else if (!strcmp(argv[2], "wlanmode"))
-    {
-        sscanf(argv[3], "%d", &addr);
+		zdreq.addr = addr;
+		zdreq.cmd = ZM_IOCTL_SET_AES_MODE;
+	} else if (!strcmp(argv[2], "wlanmode")) {
+		sscanf(argv[3], "%d", &addr);
 
-        zdreq.addr = addr;
-        zdreq.cmd = ZM_IOCTL_SET_PIBSS_MODE;
-    }
-    else
-    {
-	    fprintf(stderr, "error action\n");
-        exit(1);
-    }
+		zdreq.addr = addr;
+		zdreq.cmd = ZM_IOCTL_SET_PIBSS_MODE;
+	} else 	{
+		fprintf(stderr, "error action\n");
+		exit(1);
+	}
 
-    req.ifr_data = (char *)&zdreq;
-    set_ioctl(sock, &req);
+	req.ifr_data = (char *)&zdreq;
+	set_ioctl(sock, &req);
 
 fail:
-    exit(0);
+	exit(0);
 }
 
 unsigned char asctohex(char *str)
 {
-    unsigned char value;
+	unsigned char value;
 
-    value = hex(*str) & 0x0f;
-    value = value << 4;
-    str++;
-    value |= hex(*str) & 0x0f;
+	value = hex(*str) & 0x0f;
+	value = value << 4;
+	str++;
+	value |= hex(*str) & 0x0f;
 
-    return value;
+	return value;
 }
 
 char hex(char v)
 {
-    if(isdigit(v))
-        return v - '0';
-    else if(isxdigit(v))
-        return (tolower(v) - 'a' + 10);
-    else
-        return 0;
+	if (isdigit(v))
+		return v - '0';
+	else if (isxdigit(v))
+		return tolower(v) - 'a' + 10;
+	else
+		return 0;
 }
 
diff --git a/drivers/staging/otus/athr_common.h b/drivers/staging/otus/athr_common.h
index 620f78a..3e32f5b 100644
--- a/drivers/staging/otus/athr_common.h
+++ b/drivers/staging/otus/athr_common.h
@@ -68,7 +68,7 @@
 
 #define ZM_WAPI_KEY_SIZE                32
 #define ZM_WAPI_IV_LEN                  16
-#endif //ZM_ENALBE_WAPI
+#endif /* ZM_ENALBE_WAPI */
 /* structure definition */
 
 struct athr_wlan_param {
@@ -123,7 +123,7 @@
 			u8 key[ZM_WAPI_KEY_SIZE];
 		} crypt;
 		struct {
-                        u8 wapi_policy;
+			u8 wapi_policy;
 		} info;
 	} u;
 };
@@ -132,10 +132,10 @@
 {
 	u16	msg_type;
 	u16	datalen;
-    	u8	sta_mac[ETH_ALEN];
+	u8	sta_mac[ETH_ALEN];
 	u8	reserve_data[2];
-    	u8	gsn[ZM_WAPI_IV_LEN];
+	u8	gsn[ZM_WAPI_IV_LEN];
 	u8	wie[256];
 };
-#endif //ZM_ENALBE_WAPI
+#endif /* ZM_ENALBE_WAPI */
 #endif
diff --git a/drivers/staging/otus/oal_dt.h b/drivers/staging/otus/oal_dt.h
index e82b977..fb6d11a 100644
--- a/drivers/staging/otus/oal_dt.h
+++ b/drivers/staging/otus/oal_dt.h
@@ -39,15 +39,15 @@
 typedef     short               s16_t;
 typedef     char                s8_t;
 
-#ifndef     TRUE
-#define     TRUE                (1==1)
+#ifndef TRUE
+#define     TRUE                (1 == 1)
 #endif
 
-#ifndef     FALSE
-#define     FALSE               (1==0)
+#ifndef FALSE
+#define     FALSE               (1 == 0)
 #endif
 
-#ifndef     NULL
+#ifndef	NULL
 #define     NULL                0
 #endif
 
diff --git a/drivers/staging/otus/oal_marc.h b/drivers/staging/otus/oal_marc.h
index 2061116..e7a9081 100644
--- a/drivers/staging/otus/oal_marc.h
+++ b/drivers/staging/otus/oal_marc.h
@@ -34,17 +34,19 @@
 /***** Critical section *****/
 /* Declare for critical section */
 #ifndef ZM_HALPLUS_LOCK
-#define zmw_get_wlan_dev(dev)    struct zsWlanDev *wd = (struct zsWlanDev*) ((((struct usbdrv_private*)dev->priv)->wd))
+#define zmw_get_wlan_dev(dev) struct zsWlanDev *wd = (struct zsWlanDev *) \
+	((((struct usbdrv_private *)dev->priv)->wd))
 
 #define zmw_declare_for_critical_section() unsigned long irqFlag;
 
 /* Enter critical section */
-#define zmw_enter_critical_section(dev) \
-        spin_lock_irqsave(&(((struct usbdrv_private *)(dev->priv))->cs_lock), irqFlag);
+#define zmw_enter_critical_section(dev) spin_lock_irqsave(	\
+	&(((struct usbdrv_private *)(dev->priv))->cs_lock), irqFlag);
 
 /* leave critical section */
 #define zmw_leave_critical_section(dev) \
-        spin_unlock_irqrestore(&(((struct usbdrv_private *)(dev->priv))->cs_lock), irqFlag);
+	spin_unlock_irqrestore(&(((struct usbdrv_private *)	\
+			(dev->priv))->cs_lock), irqFlag);
 #else
 #define zmw_get_wlan_dev(dev)    struct zsWlanDev *wd = zfwGetWlanDev(dev);
 
@@ -52,31 +54,29 @@
 #define zmw_declare_for_critical_section()
 
 /* Enter critical section */
-#define zmw_enter_critical_section(dev) \
-        zfwEnterCriticalSection(dev);
+#define zmw_enter_critical_section(dev) zfwEnterCriticalSection(dev);
 
 /* leave critical section */
-#define zmw_leave_critical_section(dev) \
-        zfwLeaveCriticalSection(dev);
+#define zmw_leave_critical_section(dev) zfwLeaveCriticalSection(dev);
 #endif
 
 /***** Byte order converting *****/
 #ifdef ZM_CONFIG_BIG_ENDIAN
-#define zmw_cpu_to_le32(v)    (((v & 0xff000000) >> 24) | \
-                               ((v & 0x00ff0000) >> 8)  | \
-                               ((v & 0x0000ff00) << 8)  | \
-                               ((v & 0x000000ff) << 24))
+#define zmw_cpu_to_le32(v)    	(((v & 0xff000000) >> 24) | 	\
+				((v & 0x00ff0000) >> 8)  | 	\
+				((v & 0x0000ff00) << 8)  | 	\
+				((v & 0x000000ff) << 24))
 
-#define zmw_le32_to_cpu(v)    (((v & 0xff000000) >> 24) | \
-                               ((v & 0x00ff0000) >> 8)  | \
-                               ((v & 0x0000ff00) << 8)  | \
-                               ((v & 0x000000ff) << 24))
+#define zmw_le32_to_cpu(v)    (((v & 0xff000000) >> 24) | 	\
+				((v & 0x00ff0000) >> 8) | 	\
+				((v & 0x0000ff00) << 8) | 	\
+				((v & 0x000000ff) << 24))
 
 #define zmw_cpu_to_le16(v)    (((v & 0xff00) >> 8) | \
-                               ((v & 0x00ff) << 8))
+				((v & 0x00ff) << 8))
 
 #define zmw_le16_to_cpu(v)    (((v & 0xff00) >> 8) | \
-                               ((v & 0x00ff) << 8))
+				((v & 0x00ff) << 8))
 #else
 #define zmw_cpu_to_le32(v)    (v)
 #define zmw_le32_to_cpu(v)    (v)
@@ -88,33 +88,41 @@
 /* Called to read/write buffer */
 #ifndef ZM_HALPLUS_LOCK
 
-#define zmw_buf_readb(dev, buf, offset) *(u8_t*)((u8_t*)buf->data+offset)
-#define zmw_buf_readh(dev, buf, offset) zmw_cpu_to_le16(*(u16_t*)((u8_t*)buf->data+offset))
-#define zmw_buf_writeb(dev, buf, offset, value) *(u8_t*)((u8_t*)buf->data+offset) = value
-#define zmw_buf_writeh(dev, buf, offset, value) *(u16_t*)((u8_t*)buf->data+offset) = zmw_cpu_to_le16(value)
-#define zmw_buf_get_buffer(dev, buf) (u8_t*)(buf->data)
+#define zmw_buf_readb(dev, buf, offset) (*(u8_t *)((u8_t *)buf->data+offset))
+#define zmw_buf_readh(dev, buf, offset) zmw_cpu_to_le16(*(u16_t *)	\
+					((u8_t *)buf->data+offset))
+#define zmw_buf_writeb(dev, buf, offset, value) (*(u8_t *)		\
+					((u8_t *)buf->data+offset) = value)
+#define zmw_buf_writeh(dev, buf, offset, value) (*(u16_t *)		\
+			((u8_t *)buf->data+offset) = zmw_cpu_to_le16(value))
+#define zmw_buf_get_buffer(dev, buf) (u8_t *)(buf->data)
 
 #else
 
 #define zmw_buf_readb(dev, buf, offset) zfwBufReadByte(dev, buf, offset)
 #define zmw_buf_readh(dev, buf, offset) zfwBufReadHalfWord(dev, buf, offset)
-#define zmw_buf_writeb(dev, buf, offset, value) zfwBufWriteByte(dev, buf, offset, value)
-#define zmw_buf_writeh(dev, buf, offset, value) zfwBufWriteHalfWord(dev, buf, offset, value)
+#define zmw_buf_writeb(dev, buf, offset, value) 			\
+			zfwBufWriteByte(dev, buf, offset, value)
+#define zmw_buf_writeh(dev, buf, offset, value)				\
+			zfwBufWriteHalfWord(dev, buf, offset, value)
 #define zmw_buf_get_buffer(dev, buf) zfwGetBuffer(dev, buf)
 
 #endif
 
 /***** Debug message *****/
 #if 0
-#define zm_debug_msg0(msg) printk("%s:%s\n", __func__, msg);
-#define zm_debug_msg1(msg, val) printk("%s:%s%ld\n", __func__, \
-        msg, (u32_t)val);
-#define zm_debug_msg2(msg, val) printk("%s:%s%lxh\n", __func__, \
-        msg, (u32_t)val);
-#define zm_debug_msg_s(msg, val) printk("%s:%s%s\n", __func__, \
-        msg, val);
-#define zm_debug_msg_p(msg, val1, val2) printk("%s:%s%01ld.%02ld\n", __func__, \
-        msg, (val1/val2), (((val1*100)/val2)%100));
+#define zm_debug_msg0(msg) printk(KERN_DEBUG "%s:%s\n", __func__, msg);
+#define zm_debug_msg1(msg, val) printk(KERN_DEBUG "%s:%s%ld\n", __func__, \
+	msg, (u32_t)val);
+#define zm_debug_msg2(msg, val) printk(KERN_DEBUG "%s:%s%lxh\n", __func__, \
+	msg, (u32_t)val);
+#define zm_debug_msg_s(msg, val) printk(KERN_DEBUG "%s:%s%s\n", __func__, \
+	msg, val);
+#define zm_debug_msg_p(msg, val1, val2) do { 			\
+			printk(KERN_DEBUG "%s:%s%01ld.%02ld\n",	\
+						__func__, 	\
+			msg, (val1/val2), (((val1*100)/val2)%100));
+			} while (0)
 #define zm_dbg(S) printk S
 #else
 #define zm_debug_msg0(msg)
@@ -125,10 +133,10 @@
 #define zm_dbg(S)
 #endif
 
-#define zm_assert(expr) if(!(expr)) {                           \
-        printk( "Atheors Assertion failed! %s,%s,%s,line=%d\n",   \
-        #expr,__FILE__,__func__,__LINE__);                  \
-        }
+#define zm_assert(expr) if (!(expr)) {					 \
+	printk(KERN_ERR "Atheors Assertion failed! %s, %s, %s,line=%d\n",\
+		#expr, __FILE__, __func__, __LINE__);			 \
+	}
 
 #define DbgPrint printk
 
diff --git a/drivers/staging/otus/usbdrv.c b/drivers/staging/otus/usbdrv.c
index 48aa30a..b0adbc8 100644
--- a/drivers/staging/otus/usbdrv.c
+++ b/drivers/staging/otus/usbdrv.c
@@ -111,7 +111,7 @@
 
 /* Definition of Wireless Extension */
 
-//wireless extension helper functions
+/* wireless extension helper functions */
 extern int usbdrv_ioctl_setessid(struct net_device *dev, struct iw_point *erq);
 extern int usbdrv_ioctl_setrts(struct net_device *dev, struct iw_param *rrq);
 /* Wireless Extension Handler functions */
@@ -282,8 +282,8 @@
 };
 
 /* WDS */
-//struct zsWdsStruct wds[ZM_WDS_PORT_NUMBER];
-//void zfInitWdsStruct(void);
+/* struct zsWdsStruct wds[ZM_WDS_PORT_NUMBER]; */
+/* void zfInitWdsStruct(void);	*/
 
 /* VAP */
 struct zsVapStruct vap[ZM_VAP_PORT_NUMBER];
@@ -314,13 +314,11 @@
         return IRQ_NONE;
 
     /* the device is closed, don't continue or else bad things may happen. */
-    if (!netif_running(dev)) {
+    if (!netif_running(dev))
         return IRQ_NONE;
-    }
 
-    if (macp->driver_isolated) {
+    if (macp->driver_isolated)
         return IRQ_NONE;
-    }
 
 #if (WLAN_HOSTIF == WLAN_PCI)
     //zfiIsrPci(dev);
@@ -340,9 +338,11 @@
 
     printk("Enter open()\n");
 
-//#ifndef CONFIG_SMP
-//    read_lock(&(macp->isolate_lock));
-//#endif
+/*
+ * #ifndef CONFIG_SMP
+ *   read_lock(&(macp->isolate_lock));
+ * #endif
+ */
     if (macp->driver_isolated) {
         rc = -EBUSY;
         goto exit;
@@ -393,11 +393,11 @@
     dev->dev_addr[4] = addr[4];
     dev->dev_addr[5] = addr[5];
 #endif
-    //zfwMacAddressNotify() will be called to setup dev->dev_addr[]
+    /* zfwMacAddressNotify() will be called to setup dev->dev_addr[] */
 
     zfLnxCreateThread(dev);
 
-    mod_timer(&(macp->hbTimer10ms), jiffies + (1*HZ)/100);   //10 ms
+    mod_timer(&(macp->hbTimer10ms), jiffies + (1*HZ)/100);   /* 10 ms */
 
     netif_carrier_on(dev);
 
@@ -425,15 +425,15 @@
 
     #if ZM_SHARE_AUTH == 1
     zfiWlanSetAuthenticationMode(dev, 1);
-    #endif //#if ZM_SHARE_AUTH == 1
-  #endif //#if ZM_WEP_MOME == 1
+    #endif /* #if ZM_SHARE_AUTH == 1 */
+  #endif /* #if ZM_WEP_MOME == 1 */
 
 #elif ZM_PIBSS_MODE == 1
     zfiWlanSetWlanMode(dev, ZM_MODE_PSEUDO);
 #else
     zfiWlanSetWlanMode(dev, ZM_MODE_INFRASTRUCTURE);
 #endif
-    //zfiWlanSetChannel(dev, ZM_CHANNEL, FALSE);
+    /* zfiWlanSetChannel(dev, ZM_CHANNEL, FALSE); */
     zfiWlanSetFrequency(dev, 2462000, FALSE);
     zfiWlanSetRtsThreshold(dev, 32767);
     zfiWlanSetFragThreshold(dev, 0);
@@ -720,7 +720,7 @@
 {
     u16_t i;
 
-    for (i=0; i<ZM_VAP_PORT_NUMBER; i++)
+    for (i = 0; i < ZM_VAP_PORT_NUMBER; i++)
     {
         vap[i].dev = NULL;
         vap[i].openFlag = 0;
@@ -1128,8 +1128,7 @@
 
     printk(KERN_ERR "TxQCnt: %d\n", TxQCnt);
 
-    for(ii = 0; ii < TxQCnt; ii++)
-    {
+    for (ii = 0; ii < TxQCnt; ii++) {
         UsbTxQ_t *TxQ = zfLnxGetUsbTxBuffer(dev);
 
         printk(KERN_ERR "dev_kfree_skb_any\n");
diff --git a/drivers/staging/otus/usbdrv.h b/drivers/staging/otus/usbdrv.h
index 7800406..330d1b9 100644
--- a/drivers/staging/otus/usbdrv.h
+++ b/drivers/staging/otus/usbdrv.h
@@ -45,7 +45,7 @@
 #include "oal_dt.h"
 #include "oal_marc.h"
 #include "80211core/pub_zfi.h"
-//#include "pub_zfw.h"
+/* #include "pub_zfw.h"	*/
 #include "80211core/pub_usb.h"
 
 #include <linux/usb.h>
@@ -86,8 +86,7 @@
 #define ZM_MAX_RX_URB_NUM                   16
 #define ZM_MAX_TX_BUF_NUM                   128
 
-typedef struct UsbTxQ
-{
+typedef struct UsbTxQ {
     zbuf_t *buf;
     u8_t hdr[80];
     u16_t hdrlen;
@@ -100,17 +99,16 @@
 
 
 struct zdap_ioctl {
-	u16_t cmd;                /* Command to run */
-	u32_t addr;                /* Length of the data buffer */
-	u32_t value;              /* Pointer to the data buffer */
+	u16_t cmd;		  /* Command to run */
+	u32_t addr;		  /* Length of the data buffer */
+	u32_t value;		/* Pointer to the data buffer */
 	u8_t	data[0x100];
 };
 
 #define ZM_OAL_MAX_STA_SUPPORT 16
 
-struct usbdrv_private
-{
-	//linux used
+struct usbdrv_private {
+	/* linux used */
 	struct net_device 	*device;
 #if (WLAN_HOSTIF == WLAN_PCI)
 	struct pci_dev 		*pdev;
@@ -121,7 +119,7 @@
 #endif
 	struct driver_stats drv_stats;
 	char ifname[IFNAMSIZ];
-	int	                using_dac;
+	int			  using_dac;
 	u8_t			rev_id;		/* adapter PCI revision ID */
 	rwlock_t 		isolate_lock;
     spinlock_t      cs_lock;
@@ -130,78 +128,76 @@
 	void			*regp;
 #endif
 
-        /* timer for heart beat */
+	 /* timer for heart beat */
 	struct timer_list hbTimer10ms;
 
 	/* For driver core */
-	void* wd;
+	void *wd;
 
 #if (WLAN_HOSTIF == WLAN_USB)
-	u8_t                    txUsbBuf[ZM_MAX_TX_URB_NUM][ZM_USB_TX_BUF_SIZE];
-	u8_t                    regUsbReadBuf[ZM_USB_REG_MAX_BUF_SIZE];
-	u8_t                    regUsbWriteBuf[ZM_USB_REG_MAX_BUF_SIZE];
+	u8_t		      txUsbBuf[ZM_MAX_TX_URB_NUM][ZM_USB_TX_BUF_SIZE];
+	u8_t		      regUsbReadBuf[ZM_USB_REG_MAX_BUF_SIZE];
+	u8_t		      regUsbWriteBuf[ZM_USB_REG_MAX_BUF_SIZE];
 	urb_t			*WlanTxDataUrb[ZM_MAX_TX_URB_NUM];
 	urb_t			*WlanRxDataUrb[ZM_MAX_RX_URB_NUM];
 	urb_t			*RegOutUrb;
 	urb_t			*RegInUrb;
-	UsbTxQ_t                UsbTxBufQ[ZM_MAX_TX_BUF_NUM];
-	zbuf_t                  *UsbRxBufQ[ZM_MAX_RX_URB_NUM];
-        u16_t                   TxBufHead;
-        u16_t                   TxBufTail;
-        u16_t                   TxBufCnt;
-        u16_t                   TxUrbHead;
-        u16_t                   TxUrbTail;
-        u16_t                   TxUrbCnt;
-        u16_t                   RxBufHead;
-        u16_t                   RxBufTail;
-        u16_t                   RxBufCnt;
+	UsbTxQ_t		  UsbTxBufQ[ZM_MAX_TX_BUF_NUM];
+	zbuf_t		    *UsbRxBufQ[ZM_MAX_RX_URB_NUM];
+	 u16_t		     TxBufHead;
+	 u16_t		     TxBufTail;
+	 u16_t		     TxBufCnt;
+	 u16_t		     TxUrbHead;
+	 u16_t		     TxUrbTail;
+	 u16_t		     TxUrbCnt;
+	 u16_t		     RxBufHead;
+	 u16_t		     RxBufTail;
+	 u16_t		     RxBufCnt;
 #endif
 
 #if ZM_USB_STREAM_MODE == 1
-        zbuf_t                  *reamin_buf;
+	 zbuf_t		    *reamin_buf;
 #endif
 
 #ifdef ZM_HOSTAPD_SUPPORT
-        struct athr_wlan_param  athr_wpa_req;
+	 struct athr_wlan_param  athr_wpa_req;
 #endif
-        struct sock             *netlink_sk;
-        u8_t            DeviceOpened; //CWYang(+)
-        u8_t            supIe[50];
-        u8_t            supLen;
-        struct ieee80211req_wpaie stawpaie[ZM_OAL_MAX_STA_SUPPORT];
-        u8_t            forwardMgmt;
+	 struct sock	      *netlink_sk;
+	 u8_t	     DeviceOpened; /* CWYang(+) */
+	 u8_t	     supIe[50];
+	 u8_t	     supLen;
+	 struct ieee80211req_wpaie stawpaie[ZM_OAL_MAX_STA_SUPPORT];
+	 u8_t	     forwardMgmt;
 
-        struct zfCbUsbFuncTbl usbCbFunctions;
+	 struct zfCbUsbFuncTbl usbCbFunctions;
 
-        /* For keventd */
-        u32_t                   flags;
-        unsigned long           kevent_flags;
-        u16_t                   kevent_ready;
+	 /* For keventd */
+	 u32_t		     flags;
+	 unsigned long	    kevent_flags;
+	 u16_t		     kevent_ready;
 
-        struct semaphore        ioctl_sem;
-        struct work_struct      kevent;
-        wait_queue_head_t       wait_queue_event;
+	 struct semaphore	 ioctl_sem;
+	 struct work_struct      kevent;
+	 wait_queue_head_t	wait_queue_event;
 #ifdef ZM_HALPLUS_LOCK
-        unsigned long           hal_irqFlag;
+	 unsigned long	    hal_irqFlag;
 #endif
-        u16_t                   adapterState;
+	 u16_t		     adapterState;
 };
 
 /* WDS */
 #define ZM_WDS_PORT_NUMBER  6
 
-struct zsWdsStruct
-{
-    struct net_device* dev;
+struct zsWdsStruct {
+    struct net_device *dev;
     u16_t openFlag;
 };
 
 /* VAP */
 #define ZM_VAP_PORT_NUMBER  7
 
-struct zsVapStruct
-{
-    struct net_device* dev;
+struct zsVapStruct {
+    struct net_device *dev;
     u16_t openFlag;
 };
 
@@ -215,25 +211,25 @@
 #define ZM_IOCTL_RXD_DUMP 			0x07
 #define ZM_IOCTL_MEM_READ			0x0B
 #define ZM_IOCTL_MEM_WRITE			0x0C
-#define ZM_IOCTL_DMA_TEST           0x10
-#define ZM_IOCTL_REG_TEST           0x11
-#define ZM_IOCTL_TEST               0x80
-#define ZM_IOCTL_TALLY              0x81 //CWYang(+)
-#define ZM_IOCTL_RTS                0xA0
-#define ZM_IOCTL_MIX_MODE           0xA1
-#define ZM_IOCTL_FRAG               0xA2
-#define ZM_IOCTL_SCAN               0xA3
-#define ZM_IOCTL_KEY                0xA4
-#define ZM_IOCTL_RATE               0xA5
-#define ZM_IOCTL_ENCRYPTION_MODE    0xA6
-#define ZM_IOCTL_GET_TXCNT          0xA7
-#define ZM_IOCTL_GET_DEAGG_CNT      0xA8
-#define ZM_IOCTL_DURATION_MODE      0xA9
-#define ZM_IOCTL_SET_AES_KEY        0xAA
-#define ZM_IOCTL_SET_AES_MODE       0xAB
-#define ZM_IOCTL_SIGNAL_STRENGTH    0xAC //CWYang(+)
-#define ZM_IOCTL_SIGNAL_QUALITY     0xAD //CWYang(+)
-#define ZM_IOCTL_SET_PIBSS_MODE     0xAE
+#define ZM_IOCTL_DMA_TEST	    		0x10
+#define ZM_IOCTL_REG_TEST	    		0x11
+#define ZM_IOCTL_TEST		 		0x80
+#define ZM_IOCTL_TALLY				0x81 /* CWYang(+) */
+#define ZM_IOCTL_RTS				0xA0
+#define ZM_IOCTL_MIX_MODE			0xA1
+#define ZM_IOCTL_FRAG				0xA2
+#define ZM_IOCTL_SCAN				0xA3
+#define ZM_IOCTL_KEY				0xA4
+#define ZM_IOCTL_RATE				0xA5
+#define ZM_IOCTL_ENCRYPTION_MODE		0xA6
+#define ZM_IOCTL_GET_TXCNT			0xA7
+#define ZM_IOCTL_GET_DEAGG_CNT    		0xA8
+#define ZM_IOCTL_DURATION_MODE			0xA9
+#define ZM_IOCTL_SET_AES_KEY			0xAA
+#define ZM_IOCTL_SET_AES_MODE			0xAB
+#define ZM_IOCTL_SIGNAL_STRENGTH		0xAC /* CWYang(+) */
+#define ZM_IOCTL_SIGNAL_QUALITY			0xAD /* CWYang(+) */
+#define ZM_IOCTL_SET_PIBSS_MODE			0xAE
 
 #define	ZDAPIOCTL				SIOCDEVPRIVATE
 
diff --git a/drivers/staging/otus/wrap_buf.c b/drivers/staging/otus/wrap_buf.c
index a0f677a..d7ee0b4 100644
--- a/drivers/staging/otus/wrap_buf.c
+++ b/drivers/staging/otus/wrap_buf.c
@@ -34,9 +34,9 @@
 
 
 /* Called to allocate buffer, must return a continue buffer space */
-zbuf_t* zfwBufAllocate(zdev_t* dev, u16_t len)
+zbuf_t *zfwBufAllocate(zdev_t *dev, u16_t len)
 {
-    zbuf_t* buf;
+    zbuf_t *buf;
 
     /* Allocate SKB for packet*/
     buf = dev_alloc_skb(len);
@@ -46,15 +46,15 @@
 
 
 /* Called to free buffer, replace below 3 functions */
-void zfwBufFree(zdev_t* dev, zbuf_t* buf, u16_t status)
+void zfwBufFree(zdev_t *dev, zbuf_t *buf, u16_t status)
 {
     dev_kfree_skb_any(buf);
 }
 
 /* Called to adjust buffer size and head pointer */
-u16_t zfwBufRemoveHead(zdev_t* dev, zbuf_t* buf, u16_t size)
+u16_t zfwBufRemoveHead(zdev_t *dev, zbuf_t *buf, u16_t size)
 {
-    //zm_assert(buf->len > size);
+    /* zm_assert(buf->len > size); */
 
     buf->data += size;
     buf->len -= size;
@@ -68,7 +68,7 @@
 /* Used to chain Rx buffer to form a frame. if the prepared Rx buffer  */
 /* is greater than an ethernet frame(1518+32 byte), then this function    */
 /* will only be called with head=NULL.                                 */
-u16_t zfwBufChain(zdev_t* dev, zbuf_t** head, zbuf_t* tail)
+u16_t zfwBufChain(zdev_t *dev, zbuf_t **head, zbuf_t *tail)
 {
 
     *head = tail;
@@ -77,7 +77,7 @@
 
 
 /* Called when doing infra-bss forwarding */
-u16_t zfwBufCopy(zdev_t* dev, zbuf_t* dst, zbuf_t* src)
+u16_t zfwBufCopy(zdev_t *dev, zbuf_t *dst, zbuf_t *src)
 {
     memcpy(dst->data, src->data, src->len);
     dst->tail = dst->data;
@@ -87,7 +87,7 @@
 
 
 /* Called to adjust buffer size and tail pointer */
-u16_t zfwBufSetSize(zdev_t* dev, zbuf_t* buf, u16_t size)
+u16_t zfwBufSetSize(zdev_t *dev, zbuf_t *buf, u16_t size)
 {
 #ifdef NET_SKBUFF_DATA_USES_OFFSET
     buf->tail = 0;
@@ -101,11 +101,11 @@
     return 0;
 }
 
-u16_t zfwBufGetSize(zdev_t* dev, zbuf_t* buf)
+u16_t zfwBufGetSize(zdev_t *dev, zbuf_t *buf)
 {
     return buf->len;
 }
 
-void zfwCopyBufContext(zdev_t* dev, zbuf_t* source, zbuf_t* dst)
+void zfwCopyBufContext(zdev_t *dev, zbuf_t *source, zbuf_t *dst)
 {
 }
diff --git a/drivers/staging/otus/wrap_dbg.c b/drivers/staging/otus/wrap_dbg.c
index d47e9ab..ee0ee15 100644
--- a/drivers/staging/otus/wrap_dbg.c
+++ b/drivers/staging/otus/wrap_dbg.c
@@ -29,70 +29,67 @@
 #include <linux/netlink.h>
 #include <net/iw_handler.h>
 
-void zfwDumpBuf(zdev_t* dev, zbuf_t* buf)
+void zfwDumpBuf(zdev_t *dev, zbuf_t *buf)
 {
-    u16_t i;
+	u16_t i;
 
-    for (i=0; i<buf->len; i++)
-    {
-        printk("%02x ", *(((u8_t*)buf->data)+i));
-        if ((i&0xf)==0xf)
-        {
-            printk("\n");
-        }
-    }
-    printk("\n");
+	for (i = 0; i < buf->len; i++) {
+		printk(KERN_DEBUG "%02x ", *(((u8_t *)buf->data)+i));
+		if ((i & 0xf) == 0xf)
+			printk(KERN_DEBUG "\n");
+	}
+	printk(KERN_DEBUG "\n");
 }
 
 
-void zfwDbgReadRegDone(zdev_t* dev, u32_t addr, u32_t val)
+void zfwDbgReadRegDone(zdev_t *dev, u32_t addr, u32_t val)
 {
-    printk("Read addr:%x = %x\n", addr, val);
+	printk(KERN_DEBUG "Read addr:%x = %x\n", addr, val);
 }
 
-void zfwDbgWriteRegDone(zdev_t* dev, u32_t addr, u32_t val)
+void zfwDbgWriteRegDone(zdev_t *dev, u32_t addr, u32_t val)
 {
-    printk("Write addr:%x = %x\n", addr, val);
+	printk(KERN_DEBUG "Write addr:%x = %x\n", addr, val);
 }
 
-void zfwDbgReadTallyDone(zdev_t* dev)
+void zfwDbgReadTallyDone(zdev_t *dev)
 {
-    //printk("Read Tall Done\n");
+	/* printk(KERN_DEBUG "Read Tall Done\n"); */
 }
 
-void zfwDbgWriteEepromDone(zdev_t* dev, u32_t addr, u32_t val)
+void zfwDbgWriteEepromDone(zdev_t *dev, u32_t addr, u32_t val)
 {
 }
 
-void zfwDbgQueryHwTxBusyDone(zdev_t* dev, u32_t val)
+void zfwDbgQueryHwTxBusyDone(zdev_t *dev, u32_t val)
 {
 }
 
-//For Evl ++
-void zfwDbgReadFlashDone(zdev_t* dev, u32_t addr, u32_t* rspdata, u32_t datalen)
+/* For Evl ++ */
+void zfwDbgReadFlashDone(zdev_t *dev, u32_t addr, u32_t *rspdata, u32_t datalen)
 {
-    printk("Read Flash addr:%x length:%x\n", addr, datalen);
+	printk(KERN_DEBUG "Read Flash addr:%x length:%x\n", addr, datalen);
 }
 
-void zfwDbgProgrameFlashDone(zdev_t* dev)
+void zfwDbgProgrameFlashDone(zdev_t *dev)
 {
-    printk("Program Flash Done\n");
+	printk(KERN_DEBUG "Program Flash Done\n");
 }
 
-void zfwDbgProgrameFlashChkDone(zdev_t* dev)
+void zfwDbgProgrameFlashChkDone(zdev_t *dev)
 {
-    printk("Program Flash Done\n");
+	printk(KERN_DEBUG "Program Flash Done\n");
 }
 
-void zfwDbgGetFlashChkSumDone(zdev_t* dev, u32_t* rspdata)
+void zfwDbgGetFlashChkSumDone(zdev_t *dev, u32_t *rspdata)
 {
-    printk("Get Flash ChkSum Done\n");
+	printk(KERN_DEBUG "Get Flash ChkSum Done\n");
 }
 
-void zfwDbgDownloadFwInitDone(zdev_t* dev)
+void zfwDbgDownloadFwInitDone(zdev_t *dev)
 {
-    printk("Download FW Init Done\n");
+	printk(KERN_DEBUG "Download FW Init Done\n");
 }
-//For Evl --
+/* For Evl -- */
 
 /* Leave an empty line below to remove warning message on some compiler */
diff --git a/drivers/staging/otus/wrap_ev.c b/drivers/staging/otus/wrap_ev.c
index bcda0b9..29f5603 100644
--- a/drivers/staging/otus/wrap_ev.c
+++ b/drivers/staging/otus/wrap_ev.c
@@ -32,202 +32,214 @@
 
 
 /***** Management *****/
-u16_t zfLnxAuthNotify(zdev_t* dev, u16_t* macAddr)
+u16_t zfLnxAuthNotify(zdev_t *dev, u16_t *macAddr)
 {
-    return 0;
+	return 0;
 }
 
-u16_t zfLnxAsocNotify(zdev_t* dev, u16_t* macAddr, u8_t* body, u16_t bodySize, u16_t port)
+u16_t zfLnxAsocNotify(zdev_t *dev, u16_t *macAddr, u8_t *body, u16_t bodySize,
+			 u16_t port)
 {
-//#ifdef ZM_HOSTAPD_SUPPORT
-    struct usbdrv_private *macp = dev->ml_priv;
-    union iwreq_data wreq;
-    u8_t *addr = (u8_t *) macAddr;
-    u16_t i, j;
+/* #ifdef ZM_HOSTAPD_SUPPORT	*/
+	struct usbdrv_private *macp = dev->ml_priv;
+	union iwreq_data wreq;
+	u8_t *addr = (u8_t *) macAddr;
+	u16_t i, j;
 
-    memset(&wreq, 0, sizeof(wreq));
-    memcpy(wreq.addr.sa_data, macAddr, ETH_ALEN);
-    wreq.addr.sa_family = ARPHRD_ETHER;
-    printk(KERN_DEBUG "join_event of MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
-            addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+	memset(&wreq, 0, sizeof(wreq));
+	memcpy(wreq.addr.sa_data, macAddr, ETH_ALEN);
+	wreq.addr.sa_family = ARPHRD_ETHER;
+	printk(KERN_DEBUG "join_event of MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
+			addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
 
-    for(i = 0; i < ZM_OAL_MAX_STA_SUPPORT; i++)
-    {
-        for(j = 0; j < IEEE80211_ADDR_LEN; j++)
-        {
-            if ((macp->stawpaie[i].wpa_macaddr[j] != 0) &&
-                (macp->stawpaie[i].wpa_macaddr[j] != addr[j]))
-                break;
-        }
-        if (j == 6)
-            break;
-    }
-    if (i < ZM_OAL_MAX_STA_SUPPORT)
-    {
-        //printk("zfwAsocNotify - store wpa ie in macp, index = %d\n", i);
-        memcpy(macp->stawpaie[i].wpa_macaddr, macAddr, IEEE80211_ADDR_LEN);
-        memcpy(macp->stawpaie[i].wpa_ie, body, bodySize);
-    }
-    //if(macp->cardSetting.BssType == INFRASTRUCTURE_BSS) {
-    //            //wireless_send_event(macp->device, SIOCGIWSCAN, &wreq, NULL);
-    //    wireless_send_event(macp->device, SIOCGIWAP, &wreq, NULL);
-    //}
-    //else if(macp->cardSetting.BssType == AP_BSS) {
-//        if (port == 0)
-//        {
-            wireless_send_event(dev, IWEVREGISTERED, &wreq, NULL);
-//        }
-//        else
-//        {
-//            /* Check whether the VAP device is valid */
-//            if (vap[port].dev != NULL)
-//            {
-//                wireless_send_event(vap[port].dev, IWEVREGISTERED, &wreq, NULL);
-//            }
-//            else
-//            {
-//                printk(KERN_ERR "Can' find a valid VAP device, port: %d\n", port);
-//            }
-//        }
-    //}
-//#endif
+	for (i = 0; i < ZM_OAL_MAX_STA_SUPPORT; i++) {
+		for (j = 0; j < IEEE80211_ADDR_LEN; j++) {
+			if ((macp->stawpaie[i].wpa_macaddr[j] != 0) &&
+				(macp->stawpaie[i].wpa_macaddr[j] != addr[j]))
+				break;
+		}
+		if (j == 6)
+			break;
+	}
+	if (i < ZM_OAL_MAX_STA_SUPPORT) {
+		/*
+		 * printk("zfwAsocNotify - store wpa ie in macp,
+		 * 	index = %d\n", i);
+		 */
+		memcpy(macp->stawpaie[i].wpa_macaddr, macAddr,
+			IEEE80211_ADDR_LEN);
+		memcpy(macp->stawpaie[i].wpa_ie, body, bodySize);
+	}
+	/*
+	 * if(macp->cardSetting.BssType == INFRASTRUCTURE_BSS) {
+	 * wireless_send_event(macp->device, SIOCGIWSCAN, &wreq, NULL);
+	 *	wireless_send_event(macp->device, SIOCGIWAP, &wreq, NULL);
+	 * }
+	 * else if(macp->cardSetting.BssType == AP_BSS) {
+	 *	if (port == 0)
+	 *	{
+	 */
+			wireless_send_event(dev, IWEVREGISTERED, &wreq, NULL);
+	/*
+	 *	}
+	 *	else
+	 *	{
+	 *		 Check whether the VAP device is valid
+	 *		if (vap[port].dev != NULL)
+	 *		{
+	 *			wireless_send_event(vap[port].dev,
+	 *					IWEVREGISTERED, &wreq, NULL);
+	 *		}
+	 *		else
+	 *		{
+	 *			printk(KERN_ERR "Can' find a valid VAP device,
+	 *				 port: %d\n", port);
+	 *		}
+	 *	}
+	 * }
+	 */
+/* #endif	*/
 
-    return 0;
+	return 0;
 }
 
 
 /* Notification that a STA is disassociated from AP */
 /* AP mode only */
-u16_t zfLnxDisAsocNotify(zdev_t* dev, u8_t* macAddr, u16_t port)
+u16_t zfLnxDisAsocNotify(zdev_t *dev, u8_t *macAddr, u16_t port)
 {
-    union iwreq_data wreq;
-    u8_t *addr = (u8_t *) macAddr;
+	union iwreq_data wreq;
+	u8_t *addr = (u8_t *) macAddr;
 
-    memset(&wreq, 0, sizeof(wreq));
-    memcpy(wreq.addr.sa_data, macAddr, ETH_ALEN);
-    wreq.addr.sa_family = ARPHRD_ETHER;
-    printk(KERN_DEBUG "zfwDisAsocNotify(), MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
-            addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+	memset(&wreq, 0, sizeof(wreq));
+	memcpy(wreq.addr.sa_data, macAddr, ETH_ALEN);
+	wreq.addr.sa_family = ARPHRD_ETHER;
+	printk(KERN_DEBUG "zfwDisAsocNotify(), MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
+			addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
 
 
-    return 0;
+	return 0;
 }
 
 /* Notification that a STA is connect to AP */
 /* AP mode only */
-u16_t zfLnxApConnectNotify(zdev_t* dev, u8_t* macAddr, u16_t port)
+u16_t zfLnxApConnectNotify(zdev_t *dev, u8_t *macAddr, u16_t port)
 {
-    union iwreq_data wreq;
-    u8_t *addr = (u8_t *) macAddr;
+	union iwreq_data wreq;
+	u8_t *addr = (u8_t *) macAddr;
 
-    memset(&wreq, 0, sizeof(wreq));
-    memcpy(wreq.addr.sa_data, macAddr, ETH_ALEN);
-    wreq.addr.sa_family = ARPHRD_ETHER;
-    printk(KERN_DEBUG "zfwApConnectNotify(), MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
-            addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+	memset(&wreq, 0, sizeof(wreq));
+	memcpy(wreq.addr.sa_data, macAddr, ETH_ALEN);
+	wreq.addr.sa_family = ARPHRD_ETHER;
+	printk(KERN_DEBUG "zfwApConnectNotify(), MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
+			addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
 
 
-    return 0;
+	return 0;
 }
 
 
 
-void zfLnxConnectNotify(zdev_t* dev, u16_t status, u16_t* bssid)
+void zfLnxConnectNotify(zdev_t *dev, u16_t status, u16_t *bssid)
 {
-    union iwreq_data wreq;
-    u8_t *addr = (u8_t *) bssid;
-    struct usbdrv_private *macp = dev->ml_priv;
+	union iwreq_data wreq;
+	u8_t *addr = (u8_t *) bssid;
+	struct usbdrv_private *macp = dev->ml_priv;
 
-    if (bssid != NULL)
-    {
-        memset(&wreq, 0, sizeof(wreq));
-        if (status == ZM_STATUS_MEDIA_CONNECT)
-            memcpy(wreq.addr.sa_data, bssid, ETH_ALEN);
-        wreq.addr.sa_family = ARPHRD_ETHER;
+	if (bssid != NULL) {
+		memset(&wreq, 0, sizeof(wreq));
+		if (status == ZM_STATUS_MEDIA_CONNECT)
+			memcpy(wreq.addr.sa_data, bssid, ETH_ALEN);
+		wreq.addr.sa_family = ARPHRD_ETHER;
 
-        if (status == ZM_STATUS_MEDIA_CONNECT)
-        {
+		if (status == ZM_STATUS_MEDIA_CONNECT) {
 #ifdef ZM_CONFIG_BIG_ENDIAN
-            printk(KERN_DEBUG "Connected to AP, MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
-                    addr[1], addr[0], addr[3], addr[2], addr[5], addr[4]);
+			printk(KERN_DEBUG "Connected to AP, MAC:"
+				"%02x:%02x:%02x:%02x:%02x:%02x\n",
+				addr[1], addr[0], addr[3], addr[2],
+				addr[5], addr[4]);
 #else
-            printk(KERN_DEBUG "Connected to AP, MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
-                    addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+			printk(KERN_DEBUG "Connected to AP, MAC:"
+				 "%02x:%02x:%02x:%02x:%02x:%02x\n",
+				addr[0], addr[1], addr[2], addr[3],
+				addr[4], addr[5]);
 #endif
 
-            netif_start_queue(dev);
-        }
-        else if ((status == ZM_STATUS_MEDIA_DISCONNECT) ||
-                 (status == ZM_STATUS_MEDIA_DISABLED) ||
-                 (status == ZM_STATUS_MEDIA_CONNECTION_DISABLED) ||
-	         (status == ZM_STATUS_MEDIA_CONNECTION_RESET) ||
-	         (status == ZM_STATUS_MEDIA_RESET) ||
-	         (status == ZM_STATUS_MEDIA_DISCONNECT_DEAUTH) ||
-	         (status == ZM_STATUS_MEDIA_DISCONNECT_DISASOC) ||
-	         (status == ZM_STATUS_MEDIA_DISCONNECT_BEACON_MISS) ||
-                 (status == ZM_STATUS_MEDIA_DISCONNECT_NOT_FOUND) ||
-	         (status == ZM_STATUS_MEDIA_DISCONNECT_TIMEOUT))
-        {
-            printk(KERN_DEBUG "Disconnection Notify\n");
+			netif_start_queue(dev);
+		} else if ((status == ZM_STATUS_MEDIA_DISCONNECT) ||
+			    (status == ZM_STATUS_MEDIA_DISABLED) ||
+			    (status == ZM_STATUS_MEDIA_CONNECTION_DISABLED) ||
+			    (status == ZM_STATUS_MEDIA_CONNECTION_RESET) ||
+			    (status == ZM_STATUS_MEDIA_RESET) ||
+			    (status == ZM_STATUS_MEDIA_DISCONNECT_DEAUTH) ||
+			    (status == ZM_STATUS_MEDIA_DISCONNECT_DISASOC) ||
+			   (status == ZM_STATUS_MEDIA_DISCONNECT_BEACON_MISS) ||
+			    (status == ZM_STATUS_MEDIA_DISCONNECT_NOT_FOUND) ||
+			    (status == ZM_STATUS_MEDIA_DISCONNECT_TIMEOUT)) {
+			printk(KERN_DEBUG "Disconnection Notify\n");
 
-            netif_stop_queue(dev);
-        }
+			netif_stop_queue(dev);
+		}
 
 	/* Save the connected status */
 	macp->adapterState = status;
 
-        if(zfiWlanQueryWlanMode(dev) == ZM_MODE_INFRASTRUCTURE) {
-        //            //wireless_send_event(dev, SIOCGIWSCAN, &wreq, NULL);
-            wireless_send_event(dev, SIOCGIWAP, &wreq, NULL);
-        }
-        else if(zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) {
-            //if (port == 0)
-            //{
-                wireless_send_event(dev, IWEVREGISTERED, &wreq, NULL);
-            //}
-            //else
-            //{
-            //    /* Check whether the VAP device is valid */
-            //    if (vap[port].dev != NULL)
-            //    {
-            //        wireless_send_event(vap[port].dev, IWEVREGISTERED, &wreq, NULL);
-            //    }
-            //    else
-            //    {
-            //        printk(KERN_ERR "Can' find a valid VAP device, port: %d\n", port);
-            //    }
-            //}
-        }
-    }
-    //return 0;
+		if (zfiWlanQueryWlanMode(dev) == ZM_MODE_INFRASTRUCTURE) {
+			/*wireless_send_event(dev, SIOCGIWSCAN, &wreq, NULL);*/
+			wireless_send_event(dev, SIOCGIWAP, &wreq, NULL);
+		} else if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) {
+			/*
+			 * if (port == 0)
+			 * {
+			 *	wireless_send_event(dev, IWEVREGISTERED,
+			 *				 &wreq, NULL);
+			 * }
+			 * else
+			 * {
+			 *	Check whether the VAP device is valid
+			 *	if (vap[port].dev != NULL)
+			 *	{
+			 *		wireless_send_event(vap[port].dev,
+		 *				 IWEVREGISTERED, &wreq, NULL);
+			 *	}
+			 *	else
+			 *	{
+			 *		printk(KERN_ERR "Can' find a valid VAP"
+			 *			" device, port: %d\n", port);
+			 *	}
+			 * }
+			*/
+		}
+	}
+	/* return 0;	*/
 }
 
-void zfLnxScanNotify(zdev_t* dev, struct zsScanResult* result)
+void zfLnxScanNotify(zdev_t *dev, struct zsScanResult *result)
 {
-    return;
+	return;
 }
 
-void zfLnxStatisticsNotify(zdev_t* dev, struct zsStastics* result)
+void zfLnxStatisticsNotify(zdev_t *dev, struct zsStastics *result)
 {
-    return;
+	return;
 }
 
-//void zfwMicFailureNotify(zdev_t* dev, u8_t* message, u16_t event)
-void zfLnxMicFailureNotify(zdev_t* dev, u16_t* addr, u16_t status)
+/* void zfwMicFailureNotify(zdev_t *dev, u8_t *message, u16_t event) */
+void zfLnxMicFailureNotify(zdev_t *dev, u16_t *addr, u16_t status)
 {
 	static const char *tag = "MLME-MICHAELMICFAILURE.indication";
 	union iwreq_data wrqu;
 	char buf[128];
 
 	/* TODO: needed parameters: count, type, src address */
-	//snprintf(buf, sizeof(buf), "%s(%scast addr=%s)", tag,
-	//    (status == ZM_MIC_GROUP_ERROR) ?  "broad" : "uni",
-	//    ether_sprintf((u8_t *)addr));
+	/*
+	 * snprintf(buf, sizeof(buf), "%s(%scast addr=%s)", tag,
+	 *	(status == ZM_MIC_GROUP_ERROR) ?  "broad" : "uni",
+	 *	ether_sprintf((u8_t *)addr));
+	 */
 
 	if (zfiWlanQueryWlanMode(dev) == ZM_MODE_INFRASTRUCTURE)
-	{
 		strcpy(buf, tag);
-	}
 
 	memset(&wrqu, 0, sizeof(wrqu));
 	wrqu.data.length = strlen(buf);
@@ -235,42 +247,46 @@
 }
 
 
-void zfLnxApMicFailureNotify(zdev_t* dev, u8_t* addr, zbuf_t* buf)
+void zfLnxApMicFailureNotify(zdev_t *dev, u8_t *addr, zbuf_t *buf)
 {
-    union iwreq_data wreq;
+	union iwreq_data wreq;
 
-    memset(&wreq, 0, sizeof(wreq));
-    memcpy(wreq.addr.sa_data, addr, ETH_ALEN);
-    wreq.addr.sa_family = ARPHRD_ETHER;
-    printk(KERN_DEBUG "zfwApMicFailureNotify(), MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
-            addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+	memset(&wreq, 0, sizeof(wreq));
+	memcpy(wreq.addr.sa_data, addr, ETH_ALEN);
+	wreq.addr.sa_family = ARPHRD_ETHER;
+	printk(KERN_DEBUG "zfwApMicFailureNotify(), "
+			"MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
+			addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
 
-    return;
+	return;
 }
-
-// status = 0  => partner lost
-//        = 1  => partner alive
-//void zfwIbssPartnerNotify(zdev_t* dev, u8_t status)
-void zfLnxIbssPartnerNotify(zdev_t* dev, u16_t status, struct zsPartnerNotifyEvent *event)
+/*
+ * status = 0  => partner lost
+ *		= 1  => partner alive
+ * void zfwIbssPartnerNotify(zdev_t* dev, u8_t status)
+ */
+void zfLnxIbssPartnerNotify(zdev_t *dev, u16_t status,
+				struct zsPartnerNotifyEvent *event)
 {
 }
 
-void zfLnxMacAddressNotify(zdev_t* dev, u8_t* addr)
+void zfLnxMacAddressNotify(zdev_t *dev, u8_t *addr)
 {
-    dev->dev_addr[0] = addr[0];
-    dev->dev_addr[1] = addr[1];
-    dev->dev_addr[2] = addr[2];
-    dev->dev_addr[3] = addr[3];
-    dev->dev_addr[4] = addr[4];
-    dev->dev_addr[5] = addr[5];
+	dev->dev_addr[0] = addr[0];
+	dev->dev_addr[1] = addr[1];
+	dev->dev_addr[2] = addr[2];
+	dev->dev_addr[3] = addr[3];
+	dev->dev_addr[4] = addr[4];
+	dev->dev_addr[5] = addr[5];
 }
 
-void zfLnxSendCompleteIndication(zdev_t* dev, zbuf_t* buf)
+void zfLnxSendCompleteIndication(zdev_t *dev, zbuf_t *buf)
 {
 }
 
 
-void zfLnxRestoreBufData(zdev_t* dev, zbuf_t* buf) {
+void zfLnxRestoreBufData(zdev_t *dev, zbuf_t *buf)
+{
 
 }
 /* Leave an empty line below to remove warning message on some compiler */
diff --git a/drivers/staging/otus/wrap_mem.c b/drivers/staging/otus/wrap_mem.c
index 32416d7..47cbce1 100644
--- a/drivers/staging/otus/wrap_mem.c
+++ b/drivers/staging/otus/wrap_mem.c
@@ -30,69 +30,75 @@
 #include <net/iw_handler.h>
 
 /* Memory management */
-/* Called to allocate uncached memory, allocated memory must    */
-/* in 4-byte boundary                                           */
-void* zfwMemAllocate(zdev_t* dev, u32_t size)
+/* Called to allocate uncached memory, allocated memory must	*/
+/* in 4-byte boundary						*/
+void *zfwMemAllocate(zdev_t *dev, u32_t size)
 {
-    void* mem = NULL;
-    mem = kmalloc(size, GFP_ATOMIC);
-    return mem;
+	void *mem = NULL;
+	mem = kmalloc(size, GFP_ATOMIC);
+	return mem;
 }
 
 
 /* Called to free allocated memory */
-void zfwMemFree(zdev_t* dev, void* mem, u32_t size)
+void zfwMemFree(zdev_t *dev, void *mem, u32_t size)
 {
-    kfree(mem);
-    return;
+	kfree(mem);
+	return;
 }
 
-void zfwMemoryCopy(u8_t* dst, u8_t* src, u16_t length)
+void zfwMemoryCopy(u8_t *dst, u8_t *src, u16_t length)
 {
-    //u16_t i;
+	/* u16_t i; */
 
-    memcpy(dst, src, length);
-    //for(i=0; i<length; i++)
-    //{
-    //    dst[i] = src[i];
-    //}
-    return;
+	memcpy(dst, src, length);
+	/*
+	 * for(i=0; i<length; i++)
+	 * {
+	 *	dst[i] = src[i];
+	 * }
+	 */
+	return;
 }
 
-void zfwZeroMemory(u8_t* va, u16_t length)
+void zfwZeroMemory(u8_t *va, u16_t length)
 {
-    //u16_t i;
-    memset(va, 0, length);
-    //for(i=0; i<length; i++)
-    //{
-    //    va[i] = 0;
-    //}
-    return;
+	/* u16_t i; */
+	memset(va, 0, length);
+	/*
+	 * for(i=0; i<length; i++)
+	 * {
+	 *	va[i] = 0;
+	 * }
+	 */
+	return;
 }
 
-void zfwMemoryMove(u8_t* dst, u8_t* src, u16_t length)
+void zfwMemoryMove(u8_t *dst, u8_t *src, u16_t length)
 {
-    memcpy(dst, src, length);
-    return;
+	memcpy(dst, src, length);
+	return;
 }
 
-u8_t zfwMemoryIsEqual(u8_t* m1, u8_t* m2, u16_t length)
+u8_t zfwMemoryIsEqual(u8_t *m1, u8_t *m2, u16_t length)
 {
-    //u16_t i;
-    int ret;
+	/* u16_t i; */
+	int ret;
 
-    ret = memcmp(m1, m2, length);
+	ret = memcmp(m1, m2, length);
 
-    return ((ret==0)?TRUE:FALSE);
-    //for(i=0; i<length; i++)
-    //{
-    //    if ( m1[i] != m2[i] )
-    //    {
-    //        return FALSE;
-    //    }
-    //}
-
-    //return TRUE;
+	return ((ret == 0) ? TRUE : FALSE);
+	/*
+	 * for(i=0; i<length; i++)
+	 *{
+	 *	 if ( m1[i] != m2[i] )
+	 *	{
+	 *		return FALSE;
+	 *	}
+	 *}
+	 *
+	 * return TRUE;
+	 */
 }
 
 /* Leave an empty line below to remove warning message on some compiler */
diff --git a/drivers/staging/otus/wrap_mis.c b/drivers/staging/otus/wrap_mis.c
index ea2199f..26f49b7 100644
--- a/drivers/staging/otus/wrap_mis.c
+++ b/drivers/staging/otus/wrap_mis.c
@@ -30,76 +30,73 @@
 #include <linux/netlink.h>
 #include <net/iw_handler.h>
 
-//extern struct zsWdsStruct wds[ZM_WDS_PORT_NUMBER];
+/* extern struct zsWdsStruct wds[ZM_WDS_PORT_NUMBER];	*/
 extern struct zsVapStruct vap[ZM_VAP_PORT_NUMBER];
-extern u16_t zfLnxGetVapId(zdev_t* dev);
+extern u16_t zfLnxGetVapId(zdev_t *dev);
 
 /* Simply return 0xffff if VAP function is not supported */
-u16_t zfwGetVapId(zdev_t* dev)
+u16_t zfwGetVapId(zdev_t *dev)
 {
-    return zfLnxGetVapId(dev);
+	return zfLnxGetVapId(dev);
 }
 
-void zfwSleep(zdev_t* dev, u32_t ms)
+void zfwSleep(zdev_t *dev, u32_t ms)
 {
-    if (in_interrupt() == 0)
-    {
-        mdelay(ms);
-    }
-    else
-    {
-        int ii;
-        int iter = 100000 * ms;
+	if (in_interrupt() == 0)
+		mdelay(ms);
+	else {
+		int ii;
+		int iter = 100000 * ms;
 
-        for (ii = 0; ii < iter; ii++)
-        {
-
-        }
-    }
+		for (ii = 0; ii < iter; ii++) {
+		}
+	}
 }
 
 #ifdef ZM_HALPLUS_LOCK
-asmlinkage struct zsWlanDev *zfwGetWlanDev(zdev_t* dev)
+asmlinkage struct zsWlanDev *zfwGetWlanDev(zdev_t *dev)
 {
 	struct usbdrv_private *macp = dev->ml_priv;
 	return macp->wd;
 }
 
-asmlinkage void zfwEnterCriticalSection(zdev_t* dev)
+asmlinkage void zfwEnterCriticalSection(zdev_t *dev)
 {
 	struct usbdrv_private *macp = dev->ml_priv;
 	spin_lock_irqsave(&macp->cs_lock, macp->hal_irqFlag);
 }
 
-asmlinkage void zfwLeaveCriticalSection(zdev_t* dev)
+asmlinkage void zfwLeaveCriticalSection(zdev_t *dev)
 {
 	struct usbdrv_private *macp = dev->ml_priv;
 	spin_unlock_irqrestore(&macp->cs_lock, macp->hal_irqFlag);
 }
 
-asmlinkage u8_t zfwBufReadByte(zdev_t* dev, zbuf_t* buf, u16_t offset)
+asmlinkage u8_t zfwBufReadByte(zdev_t *dev, zbuf_t *buf, u16_t offset)
 {
-    return *(u8_t*)((u8_t*)buf->data+offset);
+	return *(u8_t *)((u8_t *)buf->data+offset);
 }
 
-asmlinkage u16_t zfwBufReadHalfWord(zdev_t* dev, zbuf_t* buf, u16_t offset)
+asmlinkage u16_t zfwBufReadHalfWord(zdev_t *dev, zbuf_t *buf, u16_t offset)
 {
-    return zmw_cpu_to_le16(*(u16_t*)((u8_t*)buf->data+offset));
+	return zmw_cpu_to_le16(*(u16_t *)((u8_t *)buf->data+offset));
 }
 
-asmlinkage void zfwBufWriteByte(zdev_t* dev, zbuf_t* buf, u16_t offset, u8_t value)
+asmlinkage void zfwBufWriteByte(zdev_t *dev, zbuf_t *buf, u16_t offset,
+				u8_t value)
 {
-    *(u8_t*)((u8_t*)buf->data+offset) = value;
+	*(u8_t *)((u8_t *)buf->data+offset) = value;
 }
 
-asmlinkage void zfwBufWriteHalfWord(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t value)
+asmlinkage void zfwBufWriteHalfWord(zdev_t *dev, zbuf_t *buf, u16_t offset,
+					u16_t value)
 {
-    *(u16_t*)((u8_t*)buf->data+offset) = zmw_cpu_to_le16(value);
+	*(u16_t *)((u8_t *)buf->data+offset) = zmw_cpu_to_le16(value);
 }
 
-asmlinkage u8_t *zfwGetBuffer(zdev_t* dev, zbuf_t* buf)
+asmlinkage u8_t *zfwGetBuffer(zdev_t *dev, zbuf_t *buf)
 {
-    return (u8_t*)(buf->data);
+	return (u8_t *)(buf->data);
 }
 #endif
 
diff --git a/drivers/staging/otus/wrap_pkt.c b/drivers/staging/otus/wrap_pkt.c
index 0d5920f..75bb952 100644
--- a/drivers/staging/otus/wrap_pkt.c
+++ b/drivers/staging/otus/wrap_pkt.c
@@ -31,136 +31,122 @@
 #include <net/iw_handler.h>
 
 
-//extern struct zsWdsStruct wds[ZM_WDS_PORT_NUMBER];
+/* extern struct zsWdsStruct wds[ZM_WDS_PORT_NUMBER]; 	*/
 extern struct zsVapStruct vap[ZM_VAP_PORT_NUMBER];
 
 
 /***** Rx *****/
-void zfLnxRecv80211(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo)
+void zfLnxRecv80211(zdev_t *dev, zbuf_t *buf, struct zsAdditionInfo *addInfo)
 {
-    u16_t frameType;
-    u16_t frameCtrl;
-    u16_t frameSubtype;
-    zbuf_t *skb1;
-    struct usbdrv_private *macp = dev->ml_priv;
+	u16_t frameType;
+	u16_t frameCtrl;
+	u16_t frameSubtype;
+	zbuf_t *skb1;
+	struct usbdrv_private *macp = dev->ml_priv;
 
-    //frameCtrl = zmw_buf_readb(dev, buf, 0);
-    frameCtrl = *(u8_t*)((u8_t*)buf->data);
-    frameType = frameCtrl & 0xf;
-    frameSubtype = frameCtrl & 0xf0;
+	/* frameCtrl = zmw_buf_readb(dev, buf, 0);	*/
+	frameCtrl = *(u8_t *)((u8_t *)buf->data);
+	frameType = frameCtrl & 0xf;
+	frameSubtype = frameCtrl & 0xf0;
 
-    if ((frameType == 0x0) && (macp->forwardMgmt))
-    {
-        switch (frameSubtype)
-        {
-                /* Beacon */
-            case 0x80 :
-                /* Probe response */
-            case 0x50 :
-                skb1 = skb_copy(buf, GFP_ATOMIC);
-                if(skb1 != NULL)
-                {
-                    skb1->dev = dev;
-                    skb1->mac_header = skb1->data;
-	            skb1->ip_summed = CHECKSUM_NONE;
-	            skb1->pkt_type = PACKET_OTHERHOST;
-	            skb1->protocol = __constant_htons(0x0019);  /* ETH_P_80211_RAW */
-    	            netif_rx(skb1);
-	            }
-                break;
-            default:
-                break;
-        }
-    }
+	if ((frameType == 0x0) && (macp->forwardMgmt)) {
+		switch (frameSubtype) {
+			/* Beacon */
+		case 0x80:
+			/* Probe response */
+		case 0x50:
+			skb1 = skb_copy(buf, GFP_ATOMIC);
+			if (skb1 != NULL) {
+				skb1->dev = dev;
+				skb1->mac_header = skb1->data;
+				skb1->ip_summed = CHECKSUM_NONE;
+				skb1->pkt_type = PACKET_OTHERHOST;
+				/* ETH_P_80211_RAW */
+				skb1->protocol = __constant_htons(0x0019);
+				netif_rx(skb1);
+			}
+			break;
+		default:
+			break;
+		}
+	}
 
-    zfiRecv80211(dev, buf, addInfo);
-    return;
+	zfiRecv80211(dev, buf, addInfo);
+	return;
 }
 
 #define ZM_AVOID_UDP_LARGE_PACKET_FAIL
-void zfLnxRecvEth(zdev_t* dev, zbuf_t* buf, u16_t port)
+void zfLnxRecvEth(zdev_t *dev, zbuf_t *buf, u16_t port)
 {
-    struct usbdrv_private *macp = dev->ml_priv;
+	struct usbdrv_private *macp = dev->ml_priv;
 #ifdef ZM_AVOID_UDP_LARGE_PACKET_FAIL
-    zbuf_t *new_buf;
+	zbuf_t *new_buf;
 
-    //new_buf = dev_alloc_skb(2048);
-    new_buf = dev_alloc_skb(buf->len);
+	/* new_buf = dev_alloc_skb(2048);	*/
+	new_buf = dev_alloc_skb(buf->len);
 
 #ifdef NET_SKBUFF_DATA_USES_OFFSET
-    new_buf->tail = 0;
-    new_buf->len = 0;
+	new_buf->tail = 0;
+	new_buf->len = 0;
 #else
-    new_buf->tail = new_buf->data;
-    new_buf->len = 0;
+	new_buf->tail = new_buf->data;
+	new_buf->len = 0;
 #endif
 
-    skb_put(new_buf, buf->len);
-    memcpy(new_buf->data, buf->data, buf->len);
+	skb_put(new_buf, buf->len);
+	memcpy(new_buf->data, buf->data, buf->len);
 
-    /* Free buffer */
-    dev_kfree_skb_any(buf);
+	/* Free buffer */
+	dev_kfree_skb_any(buf);
 
-    if (port == 0)
-    {
-        new_buf->dev = dev;
-        new_buf->protocol = eth_type_trans(new_buf, dev);
-    }
-    else
-    {
-        /* VAP */
-        if (vap[0].dev != NULL)
-        {
-            new_buf->dev = vap[0].dev;
-            new_buf->protocol = eth_type_trans(new_buf, vap[0].dev);
-        }
-        else
-        {
-            new_buf->dev = dev;
-            new_buf->protocol = eth_type_trans(new_buf, dev);
-        }
-    }
+	if (port == 0) {
+		new_buf->dev = dev;
+		new_buf->protocol = eth_type_trans(new_buf, dev);
+	} else {
+		/* VAP */
+		if (vap[0].dev != NULL) {
+			new_buf->dev = vap[0].dev;
+			new_buf->protocol = eth_type_trans(new_buf, vap[0].dev);
+		} else {
+			new_buf->dev = dev;
+			new_buf->protocol = eth_type_trans(new_buf, dev);
+		}
+	}
 
-    new_buf->ip_summed = CHECKSUM_NONE;
-    dev->last_rx = jiffies;
+	new_buf->ip_summed = CHECKSUM_NONE;
+	dev->last_rx = jiffies;
 
-    switch(netif_rx(new_buf))
+	switch (netif_rx(new_buf))
 #else
-    if (port == 0)
-    {
-        buf->dev = dev;
-        buf->protocol = eth_type_trans(buf, dev);
-    }
-    else
-    {
-        /* VAP */
-        if (vap[0].dev != NULL)
-        {
-            buf->dev = vap[0].dev;
-            buf->protocol = eth_type_trans(buf, vap[0].dev);
-        }
-        else
-        {
-            buf->dev = dev;
-            buf->protocol = eth_type_trans(buf, dev);
-        }
-    }
+	if (port == 0) {
+		buf->dev = dev;
+		buf->protocol = eth_type_trans(buf, dev);
+	} else {
+		/* VAP */
+		if (vap[0].dev != NULL) {
+			buf->dev = vap[0].dev;
+			buf->protocol = eth_type_trans(buf, vap[0].dev);
+		} else {
+			buf->dev = dev;
+			buf->protocol = eth_type_trans(buf, dev);
+		}
+	}
 
-    buf->ip_summed = CHECKSUM_NONE;
-    dev->last_rx = jiffies;
+	buf->ip_summed = CHECKSUM_NONE;
+	dev->last_rx = jiffies;
 
-    switch(netif_rx(buf))
+	switch (netif_rx(buf))
 #endif
-    {
-    case NET_RX_DROP:
-        break;
-    default:
-            macp->drv_stats.net_stats.rx_packets++;
-            macp->drv_stats.net_stats.rx_bytes += buf->len;
-        break;
-    }
+	{
+	case NET_RX_DROP:
+		break;
+	default:
+			macp->drv_stats.net_stats.rx_packets++;
+			macp->drv_stats.net_stats.rx_bytes += buf->len;
+		break;
+	}
 
-    return;
+	return;
 }
 
 /* Leave an empty line below to remove warning message on some compiler */
diff --git a/drivers/staging/otus/wrap_sec.c b/drivers/staging/otus/wrap_sec.c
index 0f780ba..0b238e9 100644
--- a/drivers/staging/otus/wrap_sec.c
+++ b/drivers/staging/otus/wrap_sec.c
@@ -33,92 +33,93 @@
 #ifdef ZM_ENABLE_CENC
 extern int zfLnxCencSendMsg(struct sock *netlink_sk, u_int8_t *msg, int len);
 
-u16_t zfLnxCencAsocNotify(zdev_t* dev, u16_t* macAddr, u8_t* body, u16_t bodySize, u16_t port)
+u16_t zfLnxCencAsocNotify(zdev_t *dev, u16_t *macAddr, u8_t *body,
+				u16_t bodySize, u16_t port)
 {
-    struct usbdrv_private *macp = (struct usbdrv_private *)dev->priv;
-    struct zydas_cenc_sta_info cenc_info;
-    //struct sock *netlink_sk;
-    u8_t ie_len;
-    int ii;
+	struct usbdrv_private *macp = (struct usbdrv_private *)dev->priv;
+	struct zydas_cenc_sta_info cenc_info;
+	/* struct sock *netlink_sk;	*/
+	u8_t ie_len;
+	int ii;
 
-    /* Create NETLINK socket */
-    //netlink_sk = netlink_kernel_create(NETLINK_USERSOCK, NULL);
+	/* Create NETLINK socket */
+	/*netlink_sk = netlink_kernel_create(NETLINK_USERSOCK, NULL);	*/
 
-    if (macp->netlink_sk == NULL)
-    {
-        printk(KERN_ERR "NETLINK Socket is NULL\n");
-        return -1;
-    }
+	if (macp->netlink_sk == NULL) {
+		printk(KERN_ERR "NETLINK Socket is NULL\n");
+		return -1;
+	}
 
-    memset(&cenc_info, 0, sizeof(cenc_info));
+	memset(&cenc_info, 0, sizeof(cenc_info));
 
-    //memcpy(cenc_info.gsn, vap->iv_cencmsk_keys.wk_txiv, ZM_CENC_IV_LEN);
-    zfiWlanQueryGSN(dev, cenc_info.gsn, port);
-    cenc_info.datalen += ZM_CENC_IV_LEN;
-    ie_len = body[1] + 2;
-    memcpy(cenc_info.wie, body, ie_len);
-    cenc_info.datalen += ie_len;
+	/* memcpy(cenc_info.gsn, vap->iv_cencmsk_keys.wk_txiv,
+	 *  	ZM_CENC_IV_LEN);
+	 */
+	zfiWlanQueryGSN(dev, cenc_info.gsn, port);
+	cenc_info.datalen += ZM_CENC_IV_LEN;
+	ie_len = body[1] + 2;
+	memcpy(cenc_info.wie, body, ie_len);
+	cenc_info.datalen += ie_len;
 
-    memcpy(cenc_info.sta_mac, macAddr, 6);
-    cenc_info.msg_type = ZM_CENC_WAI_REQUEST;
-    cenc_info.datalen += 6 + 2;
+	memcpy(cenc_info.sta_mac, macAddr, 6);
+	cenc_info.msg_type = ZM_CENC_WAI_REQUEST;
+	cenc_info.datalen += 6 + 2;
 
-    printk(KERN_ERR "===== zfwCencSendMsg, bodySize: %d =====\n", bodySize);
+	printk(KERN_ERR "===== zfwCencSendMsg, bodySize: %d =====\n", bodySize);
 
-    for(ii = 0; ii < bodySize; ii++)
-    {
-        printk(KERN_ERR "%02x ", body[ii]);
+	for (ii = 0; ii < bodySize; ii++) {
+		printk(KERN_ERR "%02x ", body[ii]);
 
-        if ((ii & 0xf) == 0xf)
-        {
-            printk(KERN_ERR "\n");
-        }
-    }
+		if ((ii & 0xf) == 0xf)
+			printk(KERN_ERR "\n");
+	}
 
-    zfLnxCencSendMsg(macp->netlink_sk, (u8_t *)&cenc_info, cenc_info.datalen+4);
+	zfLnxCencSendMsg(macp->netlink_sk, (u8_t *)&cenc_info,
+			 cenc_info.datalen+4);
 
-    /* Close NETLINK socket */
-    //sock_release(netlink_sk);
+	/* Close NETLINK socket */
+	/* sock_release(netlink_sk);	*/
 
-    return 0;
+	return 0;
 }
-#endif //ZM_ENABLE_CENC
+#endif /* ZM_ENABLE_CENC	*/
 
-u8_t zfwCencHandleBeaconProbrespon(zdev_t* dev, u8_t *pWIEc,
-        u8_t *pPeerSSIDc, u8_t *pPeerAddrc)
+u8_t zfwCencHandleBeaconProbrespon(zdev_t *dev, u8_t *pWIEc,
+		u8_t *pPeerSSIDc, u8_t *pPeerAddrc)
 {
-    return 0;
+	return 0;
 }
 
-u8_t zfwGetPktEncExemptionActionType(zdev_t* dev, zbuf_t* buf)
+u8_t zfwGetPktEncExemptionActionType(zdev_t *dev, zbuf_t *buf)
 {
-    return ZM_ENCRYPTION_EXEMPT_NO_EXEMPTION;
+	return ZM_ENCRYPTION_EXEMPT_NO_EXEMPTION;
 }
 
-void copyToIntTxBuffer(zdev_t* dev, zbuf_t* buf, u8_t* src,
-                         u16_t offset, u16_t length)
+void copyToIntTxBuffer(zdev_t *dev, zbuf_t *buf, u8_t *src,
+						 u16_t offset, u16_t length)
 {
-    u16_t i;
+	u16_t i;
 
-    for(i=0; i<length;i++)
-    {
-        //zmw_tx_buf_writeb(dev, buf, offset+i, src[i]);
-        *(u8_t*)((u8_t*)buf->data+offset+i) = src[i];
-    }
+	for (i = 0; i < length; i++) {
+		/* zmw_tx_buf_writeb(dev, buf, offset+i, src[i]);	*/
+		*(u8_t *)((u8_t *)buf->data+offset+i) = src[i];
+	}
 }
 
-u16_t zfwStaAddIeWpaRsn(zdev_t* dev, zbuf_t* buf, u16_t offset, u8_t frameType)
+u16_t zfwStaAddIeWpaRsn(zdev_t *dev, zbuf_t *buf, u16_t offset, u8_t frameType)
 {
-    struct usbdrv_private *macp = dev->ml_priv;
-    //zm_msg1_mm(ZM_LV_0, "CWY - add wpaie content Length : ", macp->supIe[1]);
-    if (macp->supIe[1] != 0)
-    {
-        copyToIntTxBuffer(dev, buf, macp->supIe, offset, macp->supIe[1]+2);
-        //memcpy(buf->data[offset], macp->supIe, macp->supIe[1]+2);
-        offset += (macp->supIe[1]+2);
-    }
+	struct usbdrv_private *macp = dev->ml_priv;
+	/* zm_msg1_mm(ZM_LV_0, "CWY - add wpaie content Length : "
+	 * 		, macp->supIe[1]);
+	 */
+	if (macp->supIe[1] != 0) {
+		copyToIntTxBuffer(dev, buf, macp->supIe, offset,
+					 macp->supIe[1]+2);
+		/* memcpy(buf->data[offset], macp->supIe, macp->supIe[1]+2);*/
+		offset += (macp->supIe[1]+2);
+	}
 
-    return offset;
+	return offset;
 }
 
 /* Leave an empty line below to remove warning message on some compiler */
diff --git a/drivers/staging/otus/wrap_usb.c b/drivers/staging/otus/wrap_usb.c
index 70fd410..6b336ed 100644
--- a/drivers/staging/otus/wrap_usb.c
+++ b/drivers/staging/otus/wrap_usb.c
@@ -30,159 +30,152 @@
 #include <linux/netlink.h>
 #include <net/iw_handler.h>
 
-extern void zfLnxInitUsbTxQ(zdev_t* dev);
-extern void zfLnxInitUsbRxQ(zdev_t* dev);
+extern void zfLnxInitUsbTxQ(zdev_t *dev);
+extern void zfLnxInitUsbRxQ(zdev_t *dev);
 extern u32_t zfLnxSubmitRegInUrb(zdev_t *dev);
-u32_t zfLnxUsbOut(zdev_t* dev, u8_t *hdr, u16_t hdrlen, u8_t *snap, u16_t snapLen,
-        u8_t *tail, u16_t tailLen, zbuf_t *buf, u16_t offset);
-u32_t zfLnxUsbWriteReg(zdev_t* dev, u32_t* cmd, u16_t cmdLen);
+u32_t zfLnxUsbOut(zdev_t *dev, u8_t *hdr, u16_t hdrlen, u8_t *snap,
+		u16_t snapLen, u8_t *tail, u16_t tailLen, zbuf_t *buf,
+		u16_t offset);
+u32_t zfLnxUsbWriteReg(zdev_t *dev, u32_t *cmd, u16_t cmdLen);
 
-void zfwUsbRegisterCallBack(zdev_t* dev, struct zfCbUsbFuncTbl *zfUsbFunc) {
-    struct usbdrv_private *macp = dev->ml_priv;
+void zfwUsbRegisterCallBack(zdev_t *dev, struct zfCbUsbFuncTbl *zfUsbFunc)
+{
+	struct usbdrv_private *macp = dev->ml_priv;
 
-    macp->usbCbFunctions.zfcbUsbRecv = zfUsbFunc->zfcbUsbRecv;
-    macp->usbCbFunctions.zfcbUsbRegIn = zfUsbFunc->zfcbUsbRegIn;
-    macp->usbCbFunctions.zfcbUsbOutComplete = zfUsbFunc->zfcbUsbOutComplete;
+	macp->usbCbFunctions.zfcbUsbRecv = zfUsbFunc->zfcbUsbRecv;
+	macp->usbCbFunctions.zfcbUsbRegIn = zfUsbFunc->zfcbUsbRegIn;
+	macp->usbCbFunctions.zfcbUsbOutComplete = zfUsbFunc->zfcbUsbOutComplete;
 
-    return;
+	return;
 }
 
-u32_t zfwUsbGetFreeTxQSize(zdev_t* dev)
+u32_t zfwUsbGetFreeTxQSize(zdev_t *dev)
 {
-    struct usbdrv_private *macp = dev->ml_priv;
-    u32_t        freeTxQSize;
-    unsigned long irqFlag;
-    //zmw_declare_for_critical_section();
+	struct usbdrv_private *macp = dev->ml_priv;
+	u32_t		freeTxQSize;
+	unsigned long irqFlag;
+	/* zmw_declare_for_critical_section();	*/
 
-    //zmw_enter_critical_section(dev);
-    spin_lock_irqsave(&macp->cs_lock, irqFlag);
+	/* zmw_enter_critical_section(dev);	*/
+	spin_lock_irqsave(&macp->cs_lock, irqFlag);
 
-    freeTxQSize = ZM_MAX_TX_BUF_NUM - macp->TxBufCnt;
+	freeTxQSize = ZM_MAX_TX_BUF_NUM - macp->TxBufCnt;
 
-    //zmw_leave_critical_section(dev);
-    spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
+	/* zmw_leave_critical_section(dev);	*/
+	spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
 
-    return freeTxQSize;
+	return freeTxQSize;
 }
 
-u32_t zfwUsbGetMaxTxQSize(zdev_t* dev)
+u32_t zfwUsbGetMaxTxQSize(zdev_t *dev)
 {
-    return ZM_MAX_TX_BUF_NUM;
+	return ZM_MAX_TX_BUF_NUM;
 }
 
 u32_t zfwUsbEnableIntEpt(zdev_t *dev, u8_t endpt)
 {
-    /* Initialize USB TxQ */
-    zfLnxInitUsbTxQ(dev);
+	/* Initialize USB TxQ */
+	zfLnxInitUsbTxQ(dev);
 
-    /* Initialize USB RxQ */
-    zfLnxInitUsbRxQ(dev);
+	/* Initialize USB RxQ */
+	zfLnxInitUsbRxQ(dev);
 
-    /* Initialize USB Register In URB */
-    //zfwUsbSubmitRegIn(dev);
-    /* Initialize USB Register In URB */
-    zfLnxSubmitRegInUrb(dev);
+	/* Initialize USB Register In URB */
+	/* zfwUsbSubmitRegIn(dev);	*/
+	/* Initialize USB Register In URB */
+	zfLnxSubmitRegInUrb(dev);
 
-    return 0;
+	return 0;
 }
 
-int zfwUsbEnableRxEpt(zdev_t* dev, u8_t endpt)
+int zfwUsbEnableRxEpt(zdev_t *dev, u8_t endpt)
 {
-    return 0;
+	return 0;
 }
 
-u32_t zfwUsbSubmitControl(zdev_t* dev, u8_t req, u16_t value, u16_t index, void *data, u32_t size)
+u32_t zfwUsbSubmitControl(zdev_t *dev, u8_t req, u16_t value, u16_t index,
+			 void *data, u32_t size)
 {
-    int result = 0;
-    u32_t ret = 0;
-    struct usbdrv_private *macp = dev->ml_priv;
-    u8_t* buf;
+	int result = 0;
+	u32_t ret = 0;
+	struct usbdrv_private *macp = dev->ml_priv;
+	u8_t *buf;
 
-    if (size > 0)
-    {
-        buf = kmalloc(size, GFP_KERNEL);
-        memcpy(buf, (u8_t*)data, size);
-    }
-    else
-    {
-        buf = NULL;
-    }
+	if (size > 0) {
+		buf = kmalloc(size, GFP_KERNEL);
+		memcpy(buf, (u8_t *)data, size);
+	} else
+		buf = NULL;
 
 #if 0
-    printk(KERN_ERR "req = 0x%02x\n", req);
-    printk(KERN_ERR "value = 0x%04x\n", value);
-    printk(KERN_ERR "index = 0x%04x\n", index);
-    printk(KERN_ERR "data = 0x%lx\n", (u32_t) data);
-    printk(KERN_ERR "size = %ld\n", size);
+	printk(KERN_ERR "req = 0x%02x\n", req);
+	printk(KERN_ERR "value = 0x%04x\n", value);
+	printk(KERN_ERR "index = 0x%04x\n", index);
+	printk(KERN_ERR "data = 0x%lx\n", (u32_t) data);
+	printk(KERN_ERR "size = %ld\n", size);
 #endif
 
-    result = usb_control_msg(macp->udev, usb_sndctrlpipe(macp->udev, 0),
-            req, USB_DIR_OUT | 0x40, value, index, buf, size, HZ);
+	result = usb_control_msg(macp->udev, usb_sndctrlpipe(macp->udev, 0),
+			req, USB_DIR_OUT | 0x40, value, index, buf, size, HZ);
 
-    if (result < 0)
-    {
-        printk("zfwUsbSubmitControl() failed, result=0x%x\n", result);
-        ret = 1;
-    }
-    kfree(buf);
+	if (result < 0) {
+		printk(KERN_ERR "zfwUsbSubmitControl() failed, result = 0x%x\n",
+			result);
+		ret = 1;
+	}
+	kfree(buf);
 
-    return ret;
+	return ret;
 }
 
-void zfwUsbCmd(zdev_t* dev, u8_t endpt, u32_t* cmd, u16_t cmdLen)
+void zfwUsbCmd(zdev_t *dev, u8_t endpt, u32_t *cmd, u16_t cmdLen)
 {
-    struct usbdrv_private *macp = dev->ml_priv;
-    u32_t ret;
+	struct usbdrv_private *macp = dev->ml_priv;
+	u32_t ret;
 
-    //MPUsbCommand(dev, endpt, cmd, cmdLen);
-    ret = zfLnxUsbWriteReg(dev, cmd, cmdLen);
+	/* MPUsbCommand(dev, endpt, cmd, cmdLen);	*/
+	ret = zfLnxUsbWriteReg(dev, cmd, cmdLen);
 
-    /* if zfLnxUsbWriteReg() return error, free and allocate urb, resend again */
-    if (ret != 0)
-    {
-        usb_free_urb(macp->RegOutUrb);
-        macp->RegOutUrb = usb_alloc_urb(0, GFP_ATOMIC);
-        ret = zfLnxUsbWriteReg(dev, cmd, cmdLen);
-    }
+	/*
+	 * if zfLnxUsbWriteReg() return error, free and allocate urb,
+	 * resend again
+	 */
+	if (ret != 0) {
+		usb_free_urb(macp->RegOutUrb);
+		macp->RegOutUrb = usb_alloc_urb(0, GFP_ATOMIC);
+		ret = zfLnxUsbWriteReg(dev, cmd, cmdLen);
+	}
 }
 
-u32_t zfwUsbSend(zdev_t* dev, u8_t endpt, u8_t *hdr, u16_t hdrlen, u8_t *snap, u16_t snapLen,
-                u8_t *tail, u16_t tailLen, zbuf_t *buf, u16_t offset)
+u32_t zfwUsbSend(zdev_t *dev, u8_t endpt, u8_t *hdr, u16_t hdrlen, u8_t *snap,
+			u16_t snapLen,	u8_t *tail, u16_t tailLen,
+			zbuf_t *buf, u16_t offset)
 {
-    u32_t status;
+	u32_t status;
 
 #ifdef ZM_CONFIG_BIG_ENDIAN
-    u32_t ii = 0;
-    u16_t *pc = NULL;
+	u32_t ii = 0;
+	u16_t *pc = NULL;
 
-    pc = (u16_t *)hdr;
-    for(ii=0; ii<(hdrlen>>1); ii++)
-    {
-        pc[ii] = cpu_to_le16(pc[ii]);
-    }
+	pc = (u16_t *)hdr;
+	for (ii = 0; ii < (hdrlen >> 1); ii++)
+		pc[ii] = cpu_to_le16(pc[ii]);
 
-    pc = (u16_t *)snap;
-    for(ii=0; ii<(snapLen>>1); ii++)
-    {
-        pc[ii] = cpu_to_le16(pc[ii]);
-    }
+	pc = (u16_t *)snap;
+	for (ii = 0; ii < (snapLen >> 1); ii++)
+		pc[ii] = cpu_to_le16(pc[ii]);
 
-    pc = (u16_t *)tail;
-    for(ii=0; ii<(tailLen>>1); ii++)
-    {
-        pc[ii] = cpu_to_le16(pc[ii]);
-    }
+	pc = (u16_t *)tail;
+	for (ii = 0; ii < (tailLen>>1); ii++)
+		pc[ii] = cpu_to_le16(pc[ii]);
 #endif
 
-    status = zfLnxUsbOut(dev, hdr, hdrlen, snap, snapLen, tail, tailLen, buf, offset);
-    if ( status == 0 )
-    {
-        return 0;
-    }
-    else
-    {
-        return 1;
-    }
+	status = zfLnxUsbOut(dev, hdr, hdrlen, snap, snapLen, tail, tailLen,
+				buf, offset);
+	if (status == 0)
+		return 0;
+	else
+		return 1;
 }
 
 /* Leave an empty line below to remove warning message on some compiler */
diff --git a/drivers/staging/otus/zdcompat.h b/drivers/staging/otus/zdcompat.h
index 84ac433..cdcaef5 100644
--- a/drivers/staging/otus/zdcompat.h
+++ b/drivers/staging/otus/zdcompat.h
@@ -17,7 +17,7 @@
 /*  Module Name : zdcompat.h                                            */
 /*                                                                      */
 /*  Abstract                                                            */
-/*     This module contains function defintion for compatibility.       */
+/*     This module contains function definition for compatibility.      */
 /*                                                                      */
 /*  NOTES                                                               */
 /*     Platform dependent.                                              */
diff --git a/drivers/staging/otus/zdusb.h b/drivers/staging/otus/zdusb.h
index 9f8ab2e..97e4ef0 100644
--- a/drivers/staging/otus/zdusb.h
+++ b/drivers/staging/otus/zdusb.h
@@ -34,10 +34,10 @@
 #define VERSIONID               "0.0.0.999"
 
 /* Define these values to match your device */
-#define VENDOR_ATHR             0x0CF3  //Atheros
+#define VENDOR_ATHR             0x0CF3  /* Atheros */
 #define PRODUCT_AR9170          0x9170
 
-#define VENDOR_DLINK            0x07D1  //Dlink
+#define VENDOR_DLINK            0x07D1  /* Dlink */
 #define PRODUCT_DWA160A         0x3C10
 
 #define	VENDOR_NETGEAR		0x0846	/* NetGear */
diff --git a/drivers/staging/p9auth/p9auth.c b/drivers/staging/p9auth/p9auth.c
index 8ccfff7..db79626 100644
--- a/drivers/staging/p9auth/p9auth.c
+++ b/drivers/staging/p9auth/p9auth.c
@@ -334,6 +334,7 @@
 	.release = cap_release,
 };
 
+/* no __exit here because it can be called by the init function */
 static void cap_cleanup_module(void)
 {
 	int i;
@@ -360,7 +361,7 @@
 		printk(KERN_NOTICE "Error %d adding cap%d", err, index);
 }
 
-static int cap_init_module(void)
+static int __init cap_init_module(void)
 {
 	int result, i;
 	dev_t dev = 0;
diff --git a/drivers/staging/phison/phison.c b/drivers/staging/phison/phison.c
index 270ebcb..3817d74 100644
--- a/drivers/staging/phison/phison.c
+++ b/drivers/staging/phison/phison.c
@@ -87,12 +87,12 @@
 #endif
 };
 
-static int phison_ide_init(void)
+static int __init phison_ide_init(void)
 {
 	return pci_register_driver(&phison_pci_driver);
 }
 
-static void phison_ide_exit(void)
+static void __exit phison_ide_exit(void)
 {
 	pci_unregister_driver(&phison_pci_driver);
 }
diff --git a/drivers/staging/poch/README b/drivers/staging/poch/README
index 842afd4..ac76ff9 100644
--- a/drivers/staging/poch/README
+++ b/drivers/staging/poch/README
@@ -1,7 +1,6 @@
 TODO:
 	- Rx block size is limited to < 2048, hardware bug?
 	- Group size is limited to < page size, kernel alloc/mmap API issues
-	- fix/workaround cache issues in circular buffer header
 	- test whether Tx is transmitting data from provided buffers
 	- handle device unplug case
 	- handle temperature above threshold
@@ -10,5 +9,128 @@
 	- audit userspace interfaces
 	- get reserved major/minor if needed
 
+Sample Code:
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <poll.h>
+#include <stdio.h>
+#include <error.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+
+#include <sysfs/libsysfs.h>
+
+#include <poch.h>
+
+struct pconsume {
+	uint32_t * offsets;
+	uint32_t nfetch;
+	uint32_t nflush;
+};
+
+uint32_t offsets[10];
+
+void process_group(unsigned char *buf, uint32_t size)
+{
+	uint16_t *buf16 = (uint16_t *)buf;
+
+	printf("RX: %p %u %04x %04x %04x %04x %04x %04x\n", buf, size,
+	       buf16[0], buf16[1], buf16[2], buf16[3], buf16[4], buf16[5]);
+}
+
+int main()
+{
+	struct sysfs_attribute *attr;
+	char *path;
+	int ret;
+	unsigned long mmap_size;
+	int fd;
+	unsigned char *cbuf;
+
+	uint32_t nflush;
+	struct pollfd poll_fds;
+	int count = 0;
+	int i;
+
+	path = "/sys/class/pocketchange/poch0/ch0/block_size";
+	attr = sysfs_open_attribute(path);
+	ret = sysfs_write_attribute(attr, "256", strlen("256"));
+	if (ret == -1)
+		error(1, errno, "error writing attribute %s", path);
+	sysfs_close_attribute(attr);
+
+	path = "/sys/class/pocketchange/poch0/ch0/group_size";
+	attr = sysfs_open_attribute(path);
+	ret = sysfs_write_attribute(attr, "4096", strlen("4096"));
+	if (ret == -1)
+		error(1, errno, "error writing attribute %s", path);
+	sysfs_close_attribute(attr);
+
+	path = "/sys/class/pocketchange/poch0/ch0/group_count";
+	attr = sysfs_open_attribute(path);
+	ret = sysfs_write_attribute(attr, "64", strlen("64"));
+	if (ret == -1)
+		error(1, errno, "error writing attribute %s", path);
+	sysfs_close_attribute(attr);
+
+	fd = open("/dev/ch0", O_RDWR);
+	if (fd == -1)
+		error(1, errno, "error opening device node");
+
+	path = "/sys/class/pocketchange/poch0/ch0/mmap_size";
+	attr = sysfs_open_attribute(path);
+	ret = sysfs_read_attribute(attr);
+	if (ret == -1)
+		error(1, errno, "error reading attribute %s", path);
+	printf("%s", attr->value);
+	sscanf(attr->value, "%lu", &mmap_size);
+	sysfs_close_attribute(attr);
+
+	cbuf = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE,
+		    MAP_PRIVATE, fd, 0);
+	if (cbuf == MAP_FAILED)
+		error(1, errno, "error mapping DMA buffers");
+
+	ret = ioctl(fd, POCH_IOC_TRANSFER_START, 0);
+	if (ret == -1)
+		error(1, errno, "error starting transfer");
+
+	nflush = 0;
+	while (1) {
+		struct pconsume consume;
+
+		consume.offsets = offsets;
+		consume.nfetch = 10;
+		consume.nflush = nflush;
+
+		ret = ioctl(fd, POCH_IOC_CONSUME, &consume);
+		if (ret == -1)
+			error(1, errno, "error consuming groups");
+
+		nflush = consume.nfetch;
+
+		for (i = 0; i < nflush; i++) {
+			process_group(cbuf + consume.offsets[i], 4096);
+
+			count++;
+			if (count == 1000)
+				break;
+		}
+
+		if (count == 1000)
+			break;
+	}
+
+	ret = ioctl(fd, POCH_IOC_TRANSFER_STOP, 0);
+	if (ret == -1)
+		error(1, errno, "error starting transfer");
+
+	return 0;
+}
+
 Please send patches to Greg Kroah-Hartman <greg@kroah.com> and
 Vijay Kumar <vijaykumar@bravegnu.org> and Jaya Kumar <jayakumar.lkml@gmail.com>
diff --git a/drivers/staging/poch/poch.c b/drivers/staging/poch/poch.c
index 2eb8e3d..9095158 100644
--- a/drivers/staging/poch/poch.c
+++ b/drivers/staging/poch/poch.c
@@ -197,10 +197,9 @@
 
 	/* Contains the header and circular buffer exported to userspace. */
 	spinlock_t group_offsets_lock;
-	struct poch_cbuf_header *header;
-	struct page *header_pg;
-	unsigned long header_size;
 
+	/* Last group consumed by user space. */
+	unsigned int consumed;
 	/* Last group indicated as 'complete' to user space. */
 	unsigned int transfer;
 
@@ -245,6 +244,16 @@
 	struct device *dev;
 };
 
+static int synth_rx;
+module_param(synth_rx, bool, 0600);
+MODULE_PARM_DESC(synth_rx,
+		"Synthesize received values using a counter. Default: No");
+
+static int loopback;
+module_param(loopback, bool, 0600);
+MODULE_PARM_DESC(loopback,
+		"Enable hardware loopback of trasnmitted data. Default: No");
+
 static dev_t poch_first_dev;
 static struct class *poch_cls;
 static DEFINE_IDR(poch_ids);
@@ -317,14 +326,12 @@
 	int len;
 	unsigned long mmap_size;
 	unsigned long group_pages;
-	unsigned long header_pages;
 	unsigned long total_group_pages;
 
 	group_pages = npages(channel->group_size);
-	header_pages = npages(channel->header_size);
 	total_group_pages = group_pages * channel->group_count;
 
-	mmap_size = (header_pages + total_group_pages) * PAGE_SIZE;
+	mmap_size = total_group_pages * PAGE_SIZE;
 	len = sprintf(buf, "%lu\n", mmap_size);
 	return len;
 }
@@ -357,10 +364,8 @@
 {
 	unsigned long i;
 	unsigned long group_pages;
-	unsigned long header_pages;
 
 	group_pages = npages(channel->group_size);
-	header_pages = npages(channel->header_size);
 
 	for (i = 0; i < channel->group_count; i++) {
 		struct poch_group_info *group;
@@ -390,8 +395,7 @@
 		 * this?
 		 */
 		group->dma_addr = page_to_pfn(group->pg) * PAGE_SIZE;
-		group->user_offset =
-			(header_pages + (i * group_pages)) * PAGE_SIZE;
+		group->user_offset = (i * group_pages) * PAGE_SIZE;
 
 		printk(KERN_INFO PFX "%ld: user_offset: 0x%lx\n", i,
 		       group->user_offset);
@@ -476,7 +480,7 @@
 		  fpga + block_count_reg);
 	iowrite32(channel->group_count, fpga + group_count_reg);
 	/* FIXME: Hardcoded groups per int. Get it from sysfs? */
-	iowrite32(1, fpga + groups_per_int_reg);
+	iowrite32(16, fpga + groups_per_int_reg);
 
 	/* Unlock PCI address? Not defined in the data sheet, but used
 	 * in the reference code by Redrapids.
@@ -513,56 +517,6 @@
 
 }
 
-static int poch_channel_alloc_header(struct channel_info *channel)
-{
-	struct poch_cbuf_header *header = channel->header;
-	unsigned long group_offset_size;
-	unsigned long tot_group_offsets_size;
-
-	/* Allocate memory to hold header exported userspace */
-	group_offset_size = sizeof(header->group_offsets[0]);
-	tot_group_offsets_size = group_offset_size * channel->group_count;
-	channel->header_size = sizeof(*header) + tot_group_offsets_size;
-	channel->header_pg = alloc_pages(GFP_KERNEL | __GFP_ZERO,
-					 get_order(channel->header_size));
-	if (!channel->header_pg)
-		return -ENOMEM;
-
-	channel->header = page_address(channel->header_pg);
-
-	return 0;
-}
-
-static void poch_channel_free_header(struct channel_info *channel)
-{
-	unsigned int order;
-
-	order = get_order(channel->header_size);
-	__free_pages(channel->header_pg, order);
-}
-
-static void poch_channel_init_header(struct channel_info *channel)
-{
-	int i;
-	struct poch_group_info *groups;
-	s32 *group_offsets;
-
-	channel->header->group_size_bytes = channel->group_size;
-	channel->header->group_count = channel->group_count;
-
-	spin_lock_init(&channel->group_offsets_lock);
-
-	group_offsets = channel->header->group_offsets;
-	groups = channel->groups;
-
-	for (i = 0; i < channel->group_count; i++) {
-		if (channel->dir == CHANNEL_DIR_RX)
-			group_offsets[i] = -1;
-		else
-			group_offsets[i] = groups[i].user_offset;
-	}
-}
-
 static void __poch_channel_clear_counters(struct channel_info *channel)
 {
 	channel->counters.pll_unlock = 0;
@@ -584,6 +538,7 @@
 	if (ret != 0)
 		goto out;
 
+	channel->consumed = 0;
 	channel->transfer = 0;
 
 	/* Allocate memory to hold group information. */
@@ -604,12 +559,6 @@
 		goto out_free_group_info;
 	}
 
-	ret = poch_channel_alloc_header(channel);
-	if (ret) {
-		dev_err(dev, "error allocating user space header\n");
-		goto out_free_groups;
-	}
-
 	channel->fpga_iomem = poch_dev->fpga_iomem;
 	channel->bridge_iomem = poch_dev->bridge_iomem;
 	channel->iomem_lock = &poch_dev->iomem_lock;
@@ -617,14 +566,8 @@
 
 	__poch_channel_clear_counters(channel);
 
-	printk(KERN_WARNING "poch_channel_init_header\n");
-
-	poch_channel_init_header(channel);
-
 	return 0;
 
- out_free_groups:
-	poch_channel_free_groups(channel);
  out_free_group_info:
 	kfree(channel->groups);
  out:
@@ -822,14 +765,21 @@
 
 	if (channel->dir == CHANNEL_DIR_TX) {
 		/* Flush TX FIFO and output data from cardbus. */
-		iowrite32(FPGA_TX_CTL_FIFO_FLUSH
-			  | FPGA_TX_CTL_OUTPUT_CARDBUS,
-			  fpga + FPGA_TX_CTL_REG);
+		u32 ctl_val = 0;
+
+		ctl_val |= FPGA_TX_CTL_FIFO_FLUSH;
+		ctl_val |= FPGA_TX_CTL_OUTPUT_CARDBUS;
+		if (loopback)
+			ctl_val |= FPGA_TX_CTL_LOOPBACK;
+
+		iowrite32(ctl_val, fpga + FPGA_TX_CTL_REG);
 	} else {
 		/* Flush RX FIFO and output data to cardbus. */
-		iowrite32(FPGA_RX_CTL_CONT_CAP
-			  | FPGA_RX_CTL_FIFO_FLUSH,
-			  fpga + FPGA_RX_CTL_REG);
+		u32 ctl_val = FPGA_RX_CTL_CONT_CAP | FPGA_RX_CTL_FIFO_FLUSH;
+		if (synth_rx)
+			ctl_val |= FPGA_RX_CTL_SYNTH_DATA;
+
+		iowrite32(ctl_val, fpga + FPGA_RX_CTL_REG);
 	}
 
 	atomic_inc(&channel->inited);
@@ -861,7 +811,6 @@
 	}
 
 	atomic_dec(&channel->inited);
-	poch_channel_free_header(channel);
 	poch_channel_free_groups(channel);
 	kfree(channel->groups);
 	atomic_inc(&channel->free);
@@ -870,7 +819,7 @@
 }
 
 /*
- * Map the header and the group buffers, to user space.
+ * Map the the group buffers, to user space.
  */
 static int poch_mmap(struct file *filp, struct vm_area_struct *vma)
 {
@@ -880,7 +829,6 @@
 	unsigned long size;
 
 	unsigned long group_pages;
-	unsigned long header_pages;
 	unsigned long total_group_pages;
 
 	int pg_num;
@@ -897,30 +845,16 @@
 	}
 
 	group_pages = npages(channel->group_size);
-	header_pages = npages(channel->header_size);
 	total_group_pages = group_pages * channel->group_count;
 
 	size = vma->vm_end - vma->vm_start;
-	if (size != (header_pages + total_group_pages) * PAGE_SIZE) {
+	if (size != total_group_pages * PAGE_SIZE) {
 		printk(KERN_WARNING PFX "required %lu bytes\n", size);
 		return -EINVAL;
 	}
 
 	start = vma->vm_start;
 
-	/* FIXME: Cleanup required on failure? */
-	pg = channel->header_pg;
-	for (pg_num = 0; pg_num < header_pages; pg_num++, pg++) {
-		printk(KERN_DEBUG PFX "page_count: %d\n", page_count(pg));
-		printk(KERN_DEBUG PFX "%d: header: 0x%lx\n", pg_num, start);
-		ret = vm_insert_page(vma, start, pg);
-		if (ret) {
-			printk(KERN_DEBUG "vm_insert 1 failed at %lx\n", start);
-			return ret;
-		}
-		start += PAGE_SIZE;
-	}
-
 	for (i = 0; i < channel->group_count; i++) {
 		pg = channel->groups[i].pg;
 		for (pg_num = 0; pg_num < group_pages; pg_num++, pg++) {
@@ -947,20 +881,16 @@
  */
 static int poch_channel_available(struct channel_info *channel)
 {
-	int i;
+	int available = 0;
 
 	spin_lock_irq(&channel->group_offsets_lock);
 
-	for (i = 0; i < channel->group_count; i++) {
-		if (channel->header->group_offsets[i] != -1) {
-			spin_unlock_irq(&channel->group_offsets_lock);
-			return 1;
-		}
-	}
+	if (channel->consumed != channel->transfer)
+		available = 1;
 
 	spin_unlock_irq(&channel->group_offsets_lock);
 
-	return 0;
+	return available;
 }
 
 static unsigned int poch_poll(struct file *filp, poll_table *pt)
@@ -1026,6 +956,51 @@
 			break;
 		}
 		break;
+	case POCH_IOC_CONSUME:
+	{
+		int available;
+		int nfetch;
+		unsigned int from;
+		unsigned int count;
+		unsigned int i, j;
+		struct poch_consume consume;
+		struct poch_consume *uconsume;
+
+		uconsume = argp;
+		ret = copy_from_user(&consume, uconsume, sizeof(consume));
+		if (ret)
+			return ret;
+
+		spin_lock_irq(&channel->group_offsets_lock);
+
+		channel->consumed += consume.nflush;
+		channel->consumed %= channel->group_count;
+
+		available = channel->transfer - channel->consumed;
+		if (available < 0)
+			available += channel->group_count;
+
+		from = channel->consumed;
+
+		spin_unlock_irq(&channel->group_offsets_lock);
+
+		nfetch = consume.nfetch;
+		count = min(available, nfetch);
+
+		for (i = 0; i < count; i++) {
+			j = (from + i) % channel->group_count;
+			ret = put_user(channel->groups[j].user_offset,
+				       &consume.offsets[i]);
+			if (ret)
+				return -EFAULT;
+		}
+
+		ret = put_user(count, &uconsume->nfetch);
+		if (ret)
+			return -EFAULT;
+
+		break;
+	}
 	case POCH_IOC_GET_COUNTERS:
 		if (!access_ok(VERIFY_WRITE, argp, sizeof(struct poch_counters)))
 			return -EFAULT;
@@ -1073,7 +1048,6 @@
 	long groups_done;
 	unsigned long i, j;
 	struct poch_group_info *groups;
-	s32 *group_offsets;
 	u32 curr_group_reg;
 
 	if (!atomic_read(&channel->inited))
@@ -1093,20 +1067,24 @@
 	if (groups_done <= 0)
 		groups_done += channel->group_count;
 
-	group_offsets = channel->header->group_offsets;
 	groups = channel->groups;
 
 	spin_lock(&channel->group_offsets_lock);
 
 	for (i = 0; i < groups_done; i++) {
 		j = (prev_transfer + i) % channel->group_count;
-		group_offsets[j] = groups[j].user_offset;
+
+		channel->transfer += 1;
+		channel->transfer %= channel->group_count;
+
+		if (channel->transfer == channel->consumed) {
+			channel->consumed += 1;
+			channel->consumed %= channel->group_count;
+		}
 	}
 
 	spin_unlock(&channel->group_offsets_lock);
 
-	channel->transfer = curr_transfer;
-
 	wake_up_interruptible(&channel->wq);
 }
 
diff --git a/drivers/staging/poch/poch.h b/drivers/staging/poch/poch.h
index 51a2d14..8b08385 100644
--- a/drivers/staging/poch/poch.h
+++ b/drivers/staging/poch/poch.h
@@ -7,11 +7,8 @@
  * include/linux for final version.
  *
  */
-struct poch_cbuf_header {
-	__s32 group_size_bytes;
-	__s32 group_count;
-	__s32 group_offsets[0];
-};
+
+#include <linux/types.h>
 
 struct poch_counters {
 	__u32 fifo_empty;
@@ -19,6 +16,12 @@
 	__u32 pll_unlock;
 };
 
+struct poch_consume {
+	__u32 __user *offsets;
+	__u32 nfetch;
+	__u32 nflush;
+};
+
 #define POCH_IOC_NUM			'9'
 
 #define POCH_IOC_TRANSFER_START		_IO(POCH_IOC_NUM, 0)
@@ -27,3 +30,6 @@
 					     struct poch_counters)
 #define POCH_IOC_SYNC_GROUP_FOR_USER	_IO(POCH_IOC_NUM, 3)
 #define POCH_IOC_SYNC_GROUP_FOR_DEVICE	_IO(POCH_IOC_NUM, 4)
+
+#define POCH_IOC_CONSUME		_IOWR(POCH_IOC_NUM, 5, \
+					      struct poch_consume)
diff --git a/drivers/staging/quatech_usb2/quatech_usb2.c b/drivers/staging/quatech_usb2/quatech_usb2.c
index 2acef94..f7726f1 100644
--- a/drivers/staging/quatech_usb2/quatech_usb2.c
+++ b/drivers/staging/quatech_usb2/quatech_usb2.c
@@ -1670,7 +1670,7 @@
 		dbg("%s(): failed resubmitting read urb, error %d",
 			__func__, result);
 	} else {
-		dbg("%s() sucessfully resumitted read urb", __func__);
+		dbg("%s() successfully resubmitted read urb", __func__);
 		if (tty_st && RxCount) {
 			/* if some inbound data was processed, then
 			 * we need to push that through the tty layer
diff --git a/drivers/staging/ramzswap/Kconfig b/drivers/staging/ramzswap/Kconfig
new file mode 100644
index 0000000..24e2569
--- /dev/null
+++ b/drivers/staging/ramzswap/Kconfig
@@ -0,0 +1,21 @@
+config RAMZSWAP
+	tristate "Compressed in-memory swap device (ramzswap)"
+	depends on SWAP
+	select LZO_COMPRESS
+	select LZO_DECOMPRESS
+	default n
+	help
+	  Creates virtual block devices which can be used (only) as a swap
+	  disks. Pages swapped to these disks are compressed and stored in
+	  memory itself.
+
+	  See ramzswap.txt for more information.
+	  Project home: http://compcache.googlecode.com/
+
+config RAMZSWAP_STATS
+	bool "Enable ramzswap stats"
+	depends on RAMZSWAP
+	default y
+	help
+	  Enable statistics collection for ramzswap. This adds only a minimal
+	  overhead. In unsure, say Y.
diff --git a/drivers/staging/ramzswap/Makefile b/drivers/staging/ramzswap/Makefile
new file mode 100644
index 0000000..507d7dc
--- /dev/null
+++ b/drivers/staging/ramzswap/Makefile
@@ -0,0 +1,3 @@
+ramzswap-objs	:=	ramzswap_drv.o xvmalloc.o
+
+obj-$(CONFIG_RAMZSWAP)	+=	ramzswap.o
diff --git a/drivers/staging/ramzswap/TODO b/drivers/staging/ramzswap/TODO
new file mode 100644
index 0000000..bac40d6
--- /dev/null
+++ b/drivers/staging/ramzswap/TODO
@@ -0,0 +1,6 @@
+TODO:
+	- Add support for swap notifiers
+	- Remove CONFIG_ARM hack
+
+Please send patches to Greg Kroah-Hartman <greg@kroah.com> and
+Nitin Gupta <ngupta@vflare.org>
diff --git a/drivers/staging/ramzswap/ramzswap.txt b/drivers/staging/ramzswap/ramzswap.txt
new file mode 100644
index 0000000..e9f1619
--- /dev/null
+++ b/drivers/staging/ramzswap/ramzswap.txt
@@ -0,0 +1,51 @@
+ramzswap: Compressed RAM based swap device
+-------------------------------------------
+
+Project home: http://compcache.googlecode.com/
+
+* Introduction
+
+It creates RAM based block devices which can be used (only) as swap disks.
+Pages swapped to these devices are compressed and stored in memory itself.
+See project home for use cases, performance numbers and a lot more.
+
+Individual ramzswap devices are configured and initialized using rzscontrol
+userspace utility as shown in examples below. See rzscontrol man page for more
+details.
+
+* Usage
+
+Following shows a typical sequence of steps for using ramzswap.
+
+1) Load Modules:
+	modprobe ramzswap num_devices=4
+	This creates 4 (uninitialized) devices: /dev/ramzswap{0,1,2,3}
+	(num_devices parameter is optional. Default: 1)
+
+2) Initialize:
+	Use rzscontrol utility to configure and initialize individual
+	ramzswap devices. Example:
+	rzscontrol /dev/ramzswap2 --init # uses default value of disksize_kb
+
+	*See rzscontrol man page for more details and examples*
+
+3) Activate:
+	swapon /dev/ramzswap2 # or any other initialized ramzswap device
+
+4) Stats:
+	rzscontrol /dev/ramzswap2 --stats
+
+5) Deactivate:
+	swapoff /dev/ramzswap2
+
+6) Reset:
+	rzscontrol /dev/ramzswap2 --reset
+	(This frees all the memory allocated for this device).
+
+
+Please report any problems at:
+ - Mailing list: linux-mm-cc at laptop dot org
+ - Issue tracker: http://code.google.com/p/compcache/issues/list
+
+Nitin Gupta
+ngupta@vflare.org
diff --git a/drivers/staging/ramzswap/ramzswap_drv.c b/drivers/staging/ramzswap/ramzswap_drv.c
new file mode 100644
index 0000000..b839f05
--- /dev/null
+++ b/drivers/staging/ramzswap/ramzswap_drv.c
@@ -0,0 +1,1435 @@
+/*
+ * Compressed RAM based swap device
+ *
+ * Copyright (C) 2008, 2009  Nitin Gupta
+ *
+ * This code is released using a dual license strategy: BSD/GPL
+ * You can choose the licence that better fits your requirements.
+ *
+ * Released under the terms of 3-clause BSD License
+ * Released under the terms of GNU General Public License Version 2.0
+ *
+ * Project home: http://compcache.googlecode.com
+ */
+
+#define KMSG_COMPONENT "ramzswap"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/blkdev.h>
+#include <linux/buffer_head.h>
+#include <linux/device.h>
+#include <linux/genhd.h>
+#include <linux/highmem.h>
+#include <linux/lzo.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+#include <linux/swap.h>
+#include <linux/swapops.h>
+#include <linux/vmalloc.h>
+#include <linux/version.h>
+
+#include "ramzswap_drv.h"
+
+/* Globals */
+static int ramzswap_major;
+static struct ramzswap *devices;
+
+/*
+ * Pages that compress to larger than this size are
+ * forwarded to backing swap, if present or stored
+ * uncompressed in memory otherwise.
+ */
+static unsigned int max_zpage_size;
+
+/* Module params (documentation at end) */
+static unsigned int num_devices;
+
+static int rzs_test_flag(struct ramzswap *rzs, u32 index,
+			enum rzs_pageflags flag)
+{
+	return rzs->table[index].flags & BIT(flag);
+}
+
+static void rzs_set_flag(struct ramzswap *rzs, u32 index,
+			enum rzs_pageflags flag)
+{
+	rzs->table[index].flags |= BIT(flag);
+}
+
+static void rzs_clear_flag(struct ramzswap *rzs, u32 index,
+			enum rzs_pageflags flag)
+{
+	rzs->table[index].flags &= ~BIT(flag);
+}
+
+static int page_zero_filled(void *ptr)
+{
+	unsigned int pos;
+	unsigned long *page;
+
+	page = (unsigned long *)ptr;
+
+	for (pos = 0; pos != PAGE_SIZE / sizeof(*page); pos++) {
+		if (page[pos])
+			return 0;
+	}
+
+	return 1;
+}
+
+/*
+ * memlimit cannot be greater than backing disk size.
+ */
+static void ramzswap_set_memlimit(struct ramzswap *rzs, size_t totalram_bytes)
+{
+	int memlimit_valid = 1;
+
+	if (!rzs->memlimit) {
+		pr_info("Memory limit not set.\n");
+		memlimit_valid = 0;
+	}
+
+	if (rzs->memlimit > rzs->disksize) {
+		pr_info("Memory limit cannot be greater than "
+			"disksize: limit=%zu, disksize=%zu\n",
+			rzs->memlimit, rzs->disksize);
+		memlimit_valid = 0;
+	}
+
+	if (!memlimit_valid) {
+		size_t mempart, disksize;
+		pr_info("Using default: smaller of (%u%% of RAM) and "
+			"(backing disk size).\n",
+			default_memlimit_perc_ram);
+		mempart = default_memlimit_perc_ram * (totalram_bytes / 100);
+		disksize = rzs->disksize;
+		rzs->memlimit = mempart > disksize ? disksize : mempart;
+	}
+
+	if (rzs->memlimit > totalram_bytes / 2) {
+		pr_info(
+		"Its not advisable setting limit more than half of "
+		"size of memory since we expect a 2:1 compression ratio. "
+		"Limit represents amount of *compressed* data we can keep "
+		"in memory!\n"
+		"\tMemory Size: %zu kB\n"
+		"\tLimit you selected: %zu kB\n"
+		"Continuing anyway ...\n",
+		totalram_bytes >> 10, rzs->memlimit >> 10
+		);
+	}
+
+	rzs->memlimit &= PAGE_MASK;
+	BUG_ON(!rzs->memlimit);
+}
+
+static void ramzswap_set_disksize(struct ramzswap *rzs, size_t totalram_bytes)
+{
+	if (!rzs->disksize) {
+		pr_info(
+		"disk size not provided. You can use disksize_kb module "
+		"param to specify size.\nUsing default: (%u%% of RAM).\n",
+		default_disksize_perc_ram
+		);
+		rzs->disksize = default_disksize_perc_ram *
+					(totalram_bytes / 100);
+	}
+
+	if (rzs->disksize > 2 * (totalram_bytes)) {
+		pr_info(
+		"There is little point creating a ramzswap of greater than "
+		"twice the size of memory since we expect a 2:1 compression "
+		"ratio. Note that ramzswap uses about 0.1%% of the size of "
+		"the swap device when not in use so a huge ramzswap is "
+		"wasteful.\n"
+		"\tMemory Size: %zu kB\n"
+		"\tSize you selected: %zu kB\n"
+		"Continuing anyway ...\n",
+		totalram_bytes >> 10, rzs->disksize
+		);
+	}
+
+	rzs->disksize &= PAGE_MASK;
+}
+
+/*
+ * Swap header (1st page of swap device) contains information
+ * to indentify it as a swap partition. Prepare such a header
+ * for ramzswap device (ramzswap0) so that swapon can identify
+ * it as swap partition. In case backing swap device is provided,
+ * copy its swap header.
+ */
+static int setup_swap_header(struct ramzswap *rzs, union swap_header *s)
+{
+	int ret = 0;
+	struct page *page;
+	struct address_space *mapping;
+	union swap_header *backing_swap_header;
+
+	/*
+	 * There is no backing swap device. Create a swap header
+	 * that is acceptable by swapon.
+	 */
+	if (!rzs->backing_swap) {
+		s->info.version = 1;
+		s->info.last_page = (rzs->disksize >> PAGE_SHIFT) - 1;
+		s->info.nr_badpages = 0;
+		memcpy(s->magic.magic, "SWAPSPACE2", 10);
+		return 0;
+	}
+
+	/*
+	 * We have a backing swap device. Copy its swap header
+	 * to ramzswap device header. If this header contains
+	 * invalid information (backing device not a swap
+	 * partition, etc.), swapon will fail for ramzswap
+	 * which is correct behavior - we don't want to swap
+	 * over filesystem partition!
+	 */
+
+	/* Read the backing swap header (code from sys_swapon) */
+	mapping = rzs->swap_file->f_mapping;
+	if (!mapping->a_ops->readpage) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	page = read_mapping_page(mapping, 0, rzs->swap_file);
+	if (IS_ERR(page)) {
+		ret = PTR_ERR(page);
+		goto out;
+	}
+
+	backing_swap_header = kmap(page);
+	memcpy(s, backing_swap_header, sizeof(*s));
+	if (s->info.nr_badpages) {
+		pr_info("Cannot use backing swap with bad pages (%u)\n",
+			s->info.nr_badpages);
+		ret = -EINVAL;
+	}
+	/*
+	 * ramzswap disksize equals number of usable pages in backing
+	 * swap. Set last_page in swap header to match this disksize
+	 * ('last_page' means 0-based index of last usable swap page).
+	 */
+	s->info.last_page = (rzs->disksize >> PAGE_SHIFT) - 1;
+	kunmap(page);
+
+out:
+	return ret;
+}
+
+static void ramzswap_flush_dcache_page(struct page *page)
+{
+#ifdef CONFIG_ARM
+	int flag = 0;
+	/*
+	 * Ugly hack to get flush_dcache_page() work on ARM.
+	 * page_mapping(page) == NULL after clearing this swap cache flag.
+	 * Without clearing this flag, flush_dcache_page() will simply set
+	 * "PG_dcache_dirty" bit and return.
+	 */
+	if (PageSwapCache(page)) {
+		flag = 1;
+		ClearPageSwapCache(page);
+	}
+#endif
+	flush_dcache_page(page);
+#ifdef CONFIG_ARM
+	if (flag)
+		SetPageSwapCache(page);
+#endif
+}
+
+void ramzswap_ioctl_get_stats(struct ramzswap *rzs,
+			struct ramzswap_ioctl_stats *s)
+{
+	strncpy(s->backing_swap_name, rzs->backing_swap_name,
+		MAX_SWAP_NAME_LEN - 1);
+	s->backing_swap_name[MAX_SWAP_NAME_LEN - 1] = '\0';
+
+	s->disksize = rzs->disksize;
+	s->memlimit = rzs->memlimit;
+
+#if defined(CONFIG_RAMZSWAP_STATS)
+	{
+	struct ramzswap_stats *rs = &rzs->stats;
+	size_t succ_writes, mem_used;
+	unsigned int good_compress_perc = 0, no_compress_perc = 0;
+
+	mem_used = xv_get_total_size_bytes(rzs->mem_pool)
+			+ (rs->pages_expand << PAGE_SHIFT);
+	succ_writes = rs->num_writes - rs->failed_writes;
+
+	if (succ_writes && rs->pages_stored) {
+		good_compress_perc = rs->good_compress * 100
+					/ rs->pages_stored;
+		no_compress_perc = rs->pages_expand * 100
+					/ rs->pages_stored;
+	}
+
+	s->num_reads = rs->num_reads;
+	s->num_writes = rs->num_writes;
+	s->failed_reads = rs->failed_reads;
+	s->failed_writes = rs->failed_writes;
+	s->invalid_io = rs->invalid_io;
+	s->pages_zero = rs->pages_zero;
+
+	s->good_compress_pct = good_compress_perc;
+	s->pages_expand_pct = no_compress_perc;
+
+	s->pages_stored = rs->pages_stored;
+	s->pages_used = mem_used >> PAGE_SHIFT;
+	s->orig_data_size = rs->pages_stored << PAGE_SHIFT;
+	s->compr_data_size = rs->compr_size;
+	s->mem_used_total = mem_used;
+
+	s->bdev_num_reads = rs->bdev_num_reads;
+	s->bdev_num_writes = rs->bdev_num_writes;
+	}
+#endif /* CONFIG_RAMZSWAP_STATS */
+}
+
+static int add_backing_swap_extent(struct ramzswap *rzs,
+				pgoff_t phy_pagenum,
+				pgoff_t num_pages)
+{
+	unsigned int idx;
+	struct list_head *head;
+	struct page *curr_page, *new_page;
+	unsigned int extents_per_page = PAGE_SIZE /
+				sizeof(struct ramzswap_backing_extent);
+
+	idx = rzs->num_extents % extents_per_page;
+	if (!idx) {
+		new_page = alloc_page(__GFP_ZERO);
+		if (!new_page)
+			return -ENOMEM;
+
+		if (rzs->num_extents) {
+			curr_page = virt_to_page(rzs->curr_extent);
+			head = &curr_page->lru;
+		} else {
+			head = &rzs->backing_swap_extent_list;
+		}
+
+		list_add(&new_page->lru, head);
+		rzs->curr_extent = page_address(new_page);
+	}
+
+	rzs->curr_extent->phy_pagenum = phy_pagenum;
+	rzs->curr_extent->num_pages = num_pages;
+
+	pr_debug("add_extent: idx=%u, phy_pgnum=%lu, num_pgs=%lu, "
+		"pg_last=%lu, curr_ext=%p\n", idx, phy_pagenum, num_pages,
+		phy_pagenum + num_pages - 1, rzs->curr_extent);
+
+	if (idx != extents_per_page - 1)
+		rzs->curr_extent++;
+
+	return 0;
+}
+
+static int setup_backing_swap_extents(struct ramzswap *rzs,
+				struct inode *inode, unsigned long *num_pages)
+{
+	int ret = 0;
+	unsigned blkbits;
+	unsigned blocks_per_page;
+	pgoff_t contig_pages = 0, total_pages = 0;
+	pgoff_t pagenum = 0, prev_pagenum = 0;
+	sector_t probe_block = 0;
+	sector_t last_block;
+
+	blkbits = inode->i_blkbits;
+	blocks_per_page = PAGE_SIZE >> blkbits;
+
+	last_block = i_size_read(inode) >> blkbits;
+	while (probe_block + blocks_per_page <= last_block) {
+		unsigned block_in_page;
+		sector_t first_block;
+
+		first_block = bmap(inode, probe_block);
+		if (first_block == 0)
+			goto bad_bmap;
+
+		/* It must be PAGE_SIZE aligned on-disk */
+		if (first_block & (blocks_per_page - 1)) {
+			probe_block++;
+			goto probe_next;
+		}
+
+		/* All blocks within this page must be contiguous on disk */
+		for (block_in_page = 1; block_in_page < blocks_per_page;
+					block_in_page++) {
+			sector_t block;
+
+			block = bmap(inode, probe_block + block_in_page);
+			if (block == 0)
+				goto bad_bmap;
+			if (block != first_block + block_in_page) {
+				/* Discontiguity */
+				probe_block++;
+				goto probe_next;
+			}
+		}
+
+		/*
+		 * We found a PAGE_SIZE length, PAGE_SIZE aligned
+		 * run of blocks.
+		 */
+		pagenum = first_block >> (PAGE_SHIFT - blkbits);
+
+		if (total_pages && (pagenum != prev_pagenum + 1)) {
+			ret = add_backing_swap_extent(rzs, prev_pagenum -
+					(contig_pages - 1), contig_pages);
+			if (ret < 0)
+				goto out;
+			rzs->num_extents++;
+			contig_pages = 0;
+		}
+		total_pages++;
+		contig_pages++;
+		prev_pagenum = pagenum;
+		probe_block += blocks_per_page;
+
+probe_next:
+		continue;
+	}
+
+	if (contig_pages) {
+		pr_debug("adding last extent: pagenum=%lu, "
+			"contig_pages=%lu\n", pagenum, contig_pages);
+		ret = add_backing_swap_extent(rzs,
+			prev_pagenum - (contig_pages - 1), contig_pages);
+		if (ret < 0)
+			goto out;
+		rzs->num_extents++;
+	}
+	if (!rzs->num_extents) {
+		pr_err("No swap extents found!\n");
+		ret = -EINVAL;
+	}
+
+	if (!ret) {
+		*num_pages = total_pages;
+		pr_info("Found %lu extents containing %luk\n",
+			rzs->num_extents, *num_pages << (PAGE_SHIFT - 10));
+	}
+	goto out;
+
+bad_bmap:
+	pr_err("Backing swapfile has holes\n");
+	ret = -EINVAL;
+out:
+	while (ret && !list_empty(&rzs->backing_swap_extent_list)) {
+		struct page *page;
+		struct list_head *entry = rzs->backing_swap_extent_list.next;
+		page = list_entry(entry, struct page, lru);
+		list_del(entry);
+		__free_page(page);
+	}
+	return ret;
+}
+
+static void map_backing_swap_extents(struct ramzswap *rzs)
+{
+	struct ramzswap_backing_extent *se;
+	struct page *table_page, *se_page;
+	unsigned long num_pages, num_table_pages, entry;
+	unsigned long se_idx, span;
+	unsigned entries_per_page = PAGE_SIZE / sizeof(*rzs->table);
+	unsigned extents_per_page = PAGE_SIZE / sizeof(*se);
+
+	/* True for block device */
+	if (!rzs->num_extents)
+		return;
+
+	se_page = list_entry(rzs->backing_swap_extent_list.next,
+					struct page, lru);
+	se = page_address(se_page);
+	span = se->num_pages;
+	num_pages = rzs->disksize >> PAGE_SHIFT;
+	num_table_pages = DIV_ROUND_UP(num_pages * sizeof(*rzs->table),
+							PAGE_SIZE);
+
+	entry = 0;
+	se_idx = 0;
+	while (num_table_pages--) {
+		table_page = vmalloc_to_page(&rzs->table[entry]);
+		while (span <= entry) {
+			se_idx++;
+			if (se_idx == rzs->num_extents)
+				BUG();
+
+			if (!(se_idx % extents_per_page)) {
+				se_page = list_entry(se_page->lru.next,
+						struct page, lru);
+				se = page_address(se_page);
+			} else
+				se++;
+
+			span += se->num_pages;
+		}
+		table_page->mapping = (struct address_space *)se;
+		table_page->private = se->num_pages - (span - entry);
+		pr_debug("map_table: entry=%lu, span=%lu, map=%p, priv=%lu\n",
+			entry, span, table_page->mapping, table_page->private);
+		entry += entries_per_page;
+	}
+}
+
+/*
+ * Check if value of backing_swap module param is sane.
+ * Claim this device and set ramzswap size equal to
+ * size of this block device.
+ */
+static int setup_backing_swap(struct ramzswap *rzs)
+{
+	int ret = 0;
+	size_t disksize;
+	unsigned long num_pages = 0;
+	struct inode *inode;
+	struct file *swap_file;
+	struct address_space *mapping;
+	struct block_device *bdev = NULL;
+
+	if (!rzs->backing_swap_name[0]) {
+		pr_debug("backing_swap param not given\n");
+		goto out;
+	}
+
+	pr_info("Using backing swap device: %s\n", rzs->backing_swap_name);
+
+	swap_file = filp_open(rzs->backing_swap_name,
+				O_RDWR | O_LARGEFILE, 0);
+	if (IS_ERR(swap_file)) {
+		pr_err("Error opening backing device: %s\n",
+			rzs->backing_swap_name);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	mapping = swap_file->f_mapping;
+	inode = mapping->host;
+
+	if (S_ISBLK(inode->i_mode)) {
+		bdev = I_BDEV(inode);
+		ret = bd_claim(bdev, setup_backing_swap);
+		if (ret < 0) {
+			bdev = NULL;
+			goto bad_param;
+		}
+		disksize = i_size_read(inode);
+	} else if (S_ISREG(inode->i_mode)) {
+		bdev = inode->i_sb->s_bdev;
+		if (IS_SWAPFILE(inode)) {
+			ret = -EBUSY;
+			goto bad_param;
+		}
+		ret = setup_backing_swap_extents(rzs, inode, &num_pages);
+		if (ret < 0)
+			goto bad_param;
+		disksize = num_pages << PAGE_SHIFT;
+	} else {
+		goto bad_param;
+	}
+
+	rzs->swap_file = swap_file;
+	rzs->backing_swap = bdev;
+	rzs->disksize = disksize;
+	BUG_ON(!rzs->disksize);
+
+	return 0;
+
+bad_param:
+	if (bdev)
+		bd_release(bdev);
+	filp_close(swap_file, NULL);
+
+out:
+	rzs->backing_swap = NULL;
+	return ret;
+}
+
+/*
+ * Map logical page number 'pagenum' to physical page number
+ * on backing swap device. For block device, this is a nop.
+ */
+u32 map_backing_swap_page(struct ramzswap *rzs, u32 pagenum)
+{
+	u32 skip_pages, entries_per_page;
+	size_t delta, se_offset, skipped;
+	struct page *table_page, *se_page;
+	struct ramzswap_backing_extent *se;
+
+	if (!rzs->num_extents)
+		return pagenum;
+
+	entries_per_page = PAGE_SIZE / sizeof(*rzs->table);
+
+	table_page = vmalloc_to_page(&rzs->table[pagenum]);
+	se = (struct ramzswap_backing_extent *)table_page->mapping;
+	se_page = virt_to_page(se);
+
+	skip_pages = pagenum - (pagenum / entries_per_page * entries_per_page);
+	se_offset = table_page->private + skip_pages;
+
+	if (se_offset < se->num_pages)
+		return se->phy_pagenum + se_offset;
+
+	skipped = se->num_pages - table_page->private;
+	do {
+		struct ramzswap_backing_extent *se_base;
+		u32 se_entries_per_page = PAGE_SIZE / sizeof(*se);
+
+		/* Get next swap extent */
+		se_base = (struct ramzswap_backing_extent *)
+						page_address(se_page);
+		if (se - se_base == se_entries_per_page - 1) {
+			se_page = list_entry(se_page->lru.next,
+						struct page, lru);
+			se = page_address(se_page);
+		} else {
+			se++;
+		}
+
+		skipped += se->num_pages;
+	} while (skipped < skip_pages);
+
+	delta = skipped - skip_pages;
+	se_offset = se->num_pages - delta;
+
+	return se->phy_pagenum + se_offset;
+}
+
+static void ramzswap_free_page(struct ramzswap *rzs, size_t index)
+{
+	u32 clen;
+	void *obj;
+
+	struct page *page = rzs->table[index].page;
+	u32 offset = rzs->table[index].offset;
+
+	if (unlikely(!page)) {
+		if (rzs_test_flag(rzs, index, RZS_ZERO)) {
+			rzs_clear_flag(rzs, index, RZS_ZERO);
+			stat_dec(rzs->stats.pages_zero);
+		}
+		return;
+	}
+
+	if (unlikely(rzs_test_flag(rzs, index, RZS_UNCOMPRESSED))) {
+		clen = PAGE_SIZE;
+		__free_page(page);
+		rzs_clear_flag(rzs, index, RZS_UNCOMPRESSED);
+		stat_dec(rzs->stats.pages_expand);
+		goto out;
+	}
+
+	obj = kmap_atomic(page, KM_USER0) + offset;
+	clen = xv_get_object_size(obj) - sizeof(struct zobj_header);
+	kunmap_atomic(obj, KM_USER0);
+
+	xv_free(rzs->mem_pool, page, offset);
+	if (clen <= PAGE_SIZE / 2)
+		stat_dec(rzs->stats.good_compress);
+
+out:
+	rzs->stats.compr_size -= clen;
+	stat_dec(rzs->stats.pages_stored);
+
+	rzs->table[index].page = NULL;
+	rzs->table[index].offset = 0;
+}
+
+static int handle_zero_page(struct bio *bio)
+{
+	void *user_mem;
+	struct page *page = bio->bi_io_vec[0].bv_page;
+
+	user_mem = kmap_atomic(page, KM_USER0);
+	memset(user_mem, 0, PAGE_SIZE);
+	kunmap_atomic(user_mem, KM_USER0);
+
+	ramzswap_flush_dcache_page(page);
+
+	set_bit(BIO_UPTODATE, &bio->bi_flags);
+	bio_endio(bio, 0);
+	return 0;
+}
+
+static int handle_uncompressed_page(struct ramzswap *rzs, struct bio *bio)
+{
+	u32 index;
+	struct page *page;
+	unsigned char *user_mem, *cmem;
+
+	page = bio->bi_io_vec[0].bv_page;
+	index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT;
+
+	user_mem = kmap_atomic(page, KM_USER0);
+	cmem = kmap_atomic(rzs->table[index].page, KM_USER1) +
+			rzs->table[index].offset;
+
+	memcpy(user_mem, cmem, PAGE_SIZE);
+	kunmap_atomic(user_mem, KM_USER0);
+	kunmap_atomic(cmem, KM_USER1);
+
+	ramzswap_flush_dcache_page(page);
+
+	set_bit(BIO_UPTODATE, &bio->bi_flags);
+	bio_endio(bio, 0);
+	return 0;
+}
+
+
+/*
+ * Called when request page is not present in ramzswap.
+ * Its either in backing swap device (if present) or
+ * this is an attempt to read before any previous write
+ * to this location - this happens due to readahead when
+ * swap device is read from user-space (e.g. during swapon)
+ */
+static int handle_ramzswap_fault(struct ramzswap *rzs, struct bio *bio)
+{
+	/*
+	 * Always forward such requests to backing swap
+	 * device (if present)
+	 */
+	if (rzs->backing_swap) {
+		u32 pagenum;
+		stat_dec(rzs->stats.num_reads);
+		stat_inc(rzs->stats.bdev_num_reads);
+		bio->bi_bdev = rzs->backing_swap;
+
+		/*
+		 * In case backing swap is a file, find the right offset within
+		 * the file corresponding to logical position 'index'. For block
+		 * device, this is a nop.
+		 */
+		pagenum = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT;
+		bio->bi_sector = map_backing_swap_page(rzs, pagenum)
+					<< SECTORS_PER_PAGE_SHIFT;
+		return 1;
+	}
+
+	/*
+	 * Its unlikely event in case backing dev is
+	 * not present
+	 */
+	pr_debug("Read before write on swap device: "
+		"sector=%lu, size=%u, offset=%u\n",
+		(ulong)(bio->bi_sector), bio->bi_size,
+		bio->bi_io_vec[0].bv_offset);
+
+	/* Do nothing. Just return success */
+	set_bit(BIO_UPTODATE, &bio->bi_flags);
+	bio_endio(bio, 0);
+	return 0;
+}
+
+static int ramzswap_read(struct ramzswap *rzs, struct bio *bio)
+{
+	int ret;
+	u32 index;
+	size_t clen;
+	struct page *page;
+	struct zobj_header *zheader;
+	unsigned char *user_mem, *cmem;
+
+	stat_inc(rzs->stats.num_reads);
+
+	page = bio->bi_io_vec[0].bv_page;
+	index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT;
+
+	if (rzs_test_flag(rzs, index, RZS_ZERO))
+		return handle_zero_page(bio);
+
+	/* Requested page is not present in compressed area */
+	if (!rzs->table[index].page)
+		return handle_ramzswap_fault(rzs, bio);
+
+	/* Page is stored uncompressed since its incompressible */
+	if (unlikely(rzs_test_flag(rzs, index, RZS_UNCOMPRESSED)))
+		return handle_uncompressed_page(rzs, bio);
+
+	user_mem = kmap_atomic(page, KM_USER0);
+	clen = PAGE_SIZE;
+
+	cmem = kmap_atomic(rzs->table[index].page, KM_USER1) +
+			rzs->table[index].offset;
+
+	ret = lzo1x_decompress_safe(
+		cmem + sizeof(*zheader),
+		xv_get_object_size(cmem) - sizeof(*zheader),
+		user_mem, &clen);
+
+	kunmap_atomic(user_mem, KM_USER0);
+	kunmap_atomic(cmem, KM_USER1);
+
+	/* should NEVER happen */
+	if (unlikely(ret != LZO_E_OK)) {
+		pr_err("Decompression failed! err=%d, page=%u\n",
+			ret, index);
+		stat_inc(rzs->stats.failed_reads);
+		goto out;
+	}
+
+	ramzswap_flush_dcache_page(page);
+
+	set_bit(BIO_UPTODATE, &bio->bi_flags);
+	bio_endio(bio, 0);
+	return 0;
+
+out:
+	bio_io_error(bio);
+	return 0;
+}
+
+static int ramzswap_write(struct ramzswap *rzs, struct bio *bio)
+{
+	int ret, fwd_write_request = 0;
+	u32 offset, index;
+	size_t clen;
+	struct zobj_header *zheader;
+	struct page *page, *page_store;
+	unsigned char *user_mem, *cmem, *src;
+
+	stat_inc(rzs->stats.num_writes);
+
+	page = bio->bi_io_vec[0].bv_page;
+	index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT;
+
+	src = rzs->compress_buffer;
+
+	/*
+	 * System swaps to same sector again when the stored page
+	 * is no longer referenced by any process. So, its now safe
+	 * to free the memory that was allocated for this page.
+	 */
+	if (rzs->table[index].page)
+		ramzswap_free_page(rzs, index);
+
+	/*
+	 * No memory ia allocated for zero filled pages.
+	 * Simply clear zero page flag.
+	 */
+	if (rzs_test_flag(rzs, index, RZS_ZERO)) {
+		stat_dec(rzs->stats.pages_zero);
+		rzs_clear_flag(rzs, index, RZS_ZERO);
+	}
+
+	mutex_lock(&rzs->lock);
+
+	user_mem = kmap_atomic(page, KM_USER0);
+	if (page_zero_filled(user_mem)) {
+		kunmap_atomic(user_mem, KM_USER0);
+		mutex_unlock(&rzs->lock);
+		stat_inc(rzs->stats.pages_zero);
+		rzs_set_flag(rzs, index, RZS_ZERO);
+
+		set_bit(BIO_UPTODATE, &bio->bi_flags);
+		bio_endio(bio, 0);
+		return 0;
+	}
+
+	if (rzs->backing_swap &&
+		(rzs->stats.compr_size > rzs->memlimit - PAGE_SIZE)) {
+		kunmap_atomic(user_mem, KM_USER0);
+		mutex_unlock(&rzs->lock);
+		fwd_write_request = 1;
+		goto out;
+	}
+
+	ret = lzo1x_1_compress(user_mem, PAGE_SIZE, src, &clen,
+				rzs->compress_workmem);
+
+	kunmap_atomic(user_mem, KM_USER0);
+
+	if (unlikely(ret != LZO_E_OK)) {
+		mutex_unlock(&rzs->lock);
+		pr_err("Compression failed! err=%d\n", ret);
+		stat_inc(rzs->stats.failed_writes);
+		goto out;
+	}
+
+	/*
+	 * Page is incompressible. Forward it to backing swap
+	 * if present. Otherwise, store it as-is (uncompressed)
+	 * since we do not want to return too many swap write
+	 * errors which has side effect of hanging the system.
+	 */
+	if (unlikely(clen > max_zpage_size)) {
+		if (rzs->backing_swap) {
+			mutex_unlock(&rzs->lock);
+			fwd_write_request = 1;
+			goto out;
+		}
+
+		clen = PAGE_SIZE;
+		page_store = alloc_page(GFP_NOIO | __GFP_HIGHMEM);
+		if (unlikely(!page_store)) {
+			mutex_unlock(&rzs->lock);
+			pr_info("Error allocating memory for incompressible "
+				"page: %u\n", index);
+			stat_inc(rzs->stats.failed_writes);
+			goto out;
+		}
+
+		offset = 0;
+		rzs_set_flag(rzs, index, RZS_UNCOMPRESSED);
+		stat_inc(rzs->stats.pages_expand);
+		rzs->table[index].page = page_store;
+		src = kmap_atomic(page, KM_USER0);
+		goto memstore;
+	}
+
+	if (xv_malloc(rzs->mem_pool, clen + sizeof(*zheader),
+			&rzs->table[index].page, &offset,
+			GFP_NOIO | __GFP_HIGHMEM)) {
+		mutex_unlock(&rzs->lock);
+		pr_info("Error allocating memory for compressed "
+			"page: %u, size=%zu\n", index, clen);
+		stat_inc(rzs->stats.failed_writes);
+		if (rzs->backing_swap)
+			fwd_write_request = 1;
+		goto out;
+	}
+
+memstore:
+	rzs->table[index].offset = offset;
+
+	cmem = kmap_atomic(rzs->table[index].page, KM_USER1) +
+			rzs->table[index].offset;
+
+#if 0
+	/* Back-reference needed for memory defragmentation */
+	if (!rzs_test_flag(rzs, index, RZS_UNCOMPRESSED)) {
+		zheader = (struct zobj_header *)cmem;
+		zheader->table_idx = index;
+		cmem += sizeof(*zheader);
+	}
+#endif
+
+	memcpy(cmem, src, clen);
+
+	kunmap_atomic(cmem, KM_USER1);
+	if (unlikely(rzs_test_flag(rzs, index, RZS_UNCOMPRESSED)))
+		kunmap_atomic(src, KM_USER0);
+
+	/* Update stats */
+	rzs->stats.compr_size += clen;
+	stat_inc(rzs->stats.pages_stored);
+	if (clen <= PAGE_SIZE / 2)
+		stat_inc(rzs->stats.good_compress);
+
+	mutex_unlock(&rzs->lock);
+
+	set_bit(BIO_UPTODATE, &bio->bi_flags);
+	bio_endio(bio, 0);
+	return 0;
+
+out:
+	if (fwd_write_request) {
+		stat_inc(rzs->stats.bdev_num_writes);
+		bio->bi_bdev = rzs->backing_swap;
+#if 0
+		/*
+		 * TODO: We currently have linear mapping of ramzswap and
+		 * backing swap sectors. This is not desired since we want
+		 * to optimize writes to backing swap to minimize disk seeks
+		 * or have effective wear leveling (for SSDs). Also, a
+		 * non-linear mapping is required to implement compressed
+		 * on-disk swapping.
+		 */
+		 bio->bi_sector = get_backing_swap_page()
+					<< SECTORS_PER_PAGE_SHIFT;
+#endif
+		/*
+		 * In case backing swap is a file, find the right offset within
+		 * the file corresponding to logical position 'index'. For block
+		 * device, this is a nop.
+		 */
+		bio->bi_sector = map_backing_swap_page(rzs, index)
+					<< SECTORS_PER_PAGE_SHIFT;
+		return 1;
+	}
+
+	bio_io_error(bio);
+	return 0;
+}
+
+
+/*
+ * Check if request is within bounds and page aligned.
+ */
+static inline int valid_swap_request(struct ramzswap *rzs, struct bio *bio)
+{
+	if (unlikely(
+		(bio->bi_sector >= (rzs->disksize >> SECTOR_SHIFT)) ||
+		(bio->bi_sector & (SECTORS_PER_PAGE - 1)) ||
+		(bio->bi_vcnt != 1) ||
+		(bio->bi_size != PAGE_SIZE) ||
+		(bio->bi_io_vec[0].bv_offset != 0))) {
+
+		return 0;
+	}
+
+	/* swap request is valid */
+	return 1;
+}
+
+/*
+ * Handler function for all ramzswap I/O requests.
+ */
+static int ramzswap_make_request(struct request_queue *queue, struct bio *bio)
+{
+	int ret = 0;
+	struct ramzswap *rzs = queue->queuedata;
+
+	if (unlikely(!rzs->init_done)) {
+		bio_io_error(bio);
+		return 0;
+	}
+
+	if (!valid_swap_request(rzs, bio)) {
+		stat_inc(rzs->stats.invalid_io);
+		bio_io_error(bio);
+		return 0;
+	}
+
+	switch (bio_data_dir(bio)) {
+	case READ:
+		ret = ramzswap_read(rzs, bio);
+		break;
+
+	case WRITE:
+		ret = ramzswap_write(rzs, bio);
+		break;
+	}
+
+	return ret;
+}
+
+static void reset_device(struct ramzswap *rzs)
+{
+	int is_backing_blkdev = 0;
+	size_t index, num_pages;
+	unsigned entries_per_page;
+	unsigned long num_table_pages, entry = 0;
+
+	if (rzs->backing_swap && !rzs->num_extents)
+		is_backing_blkdev = 1;
+
+	num_pages = rzs->disksize >> PAGE_SHIFT;
+
+	/* Free various per-device buffers */
+	kfree(rzs->compress_workmem);
+	free_pages((unsigned long)rzs->compress_buffer, 1);
+
+	rzs->compress_workmem = NULL;
+	rzs->compress_buffer = NULL;
+
+	/* Free all pages that are still in this ramzswap device */
+	for (index = 0; index < num_pages; index++) {
+		struct page *page;
+		u16 offset;
+
+		page = rzs->table[index].page;
+		offset = rzs->table[index].offset;
+
+		if (!page)
+			continue;
+
+		if (unlikely(rzs_test_flag(rzs, index, RZS_UNCOMPRESSED)))
+			__free_page(page);
+		else
+			xv_free(rzs->mem_pool, page, offset);
+	}
+
+	entries_per_page = PAGE_SIZE / sizeof(*rzs->table);
+	num_table_pages = DIV_ROUND_UP(num_pages * sizeof(*rzs->table),
+					PAGE_SIZE);
+	/*
+	 * Set page->mapping to NULL for every table page.
+	 * Otherwise, we will hit bad_page() during free.
+	 */
+	while (rzs->num_extents && num_table_pages--) {
+		struct page *page;
+		page = vmalloc_to_page(&rzs->table[entry]);
+		page->mapping = NULL;
+		entry += entries_per_page;
+	}
+	vfree(rzs->table);
+	rzs->table = NULL;
+
+	xv_destroy_pool(rzs->mem_pool);
+	rzs->mem_pool = NULL;
+
+	/* Free all swap extent pages */
+	while (!list_empty(&rzs->backing_swap_extent_list)) {
+		struct page *page;
+		struct list_head *entry;
+		entry = rzs->backing_swap_extent_list.next;
+		page = list_entry(entry, struct page, lru);
+		list_del(entry);
+		__free_page(page);
+	}
+	INIT_LIST_HEAD(&rzs->backing_swap_extent_list);
+	rzs->num_extents = 0;
+
+	/* Close backing swap device, if present */
+	if (rzs->backing_swap) {
+		if (is_backing_blkdev)
+			bd_release(rzs->backing_swap);
+		filp_close(rzs->swap_file, NULL);
+		rzs->backing_swap = NULL;
+	}
+
+	/* Reset stats */
+	memset(&rzs->stats, 0, sizeof(rzs->stats));
+
+	rzs->disksize = 0;
+	rzs->memlimit = 0;
+
+	/* Back to uninitialized state */
+	rzs->init_done = 0;
+}
+
+static int ramzswap_ioctl_init_device(struct ramzswap *rzs)
+{
+	int ret;
+	size_t num_pages;
+	struct page *page;
+	union swap_header *swap_header;
+
+	if (rzs->init_done) {
+		pr_info("Device already initialized!\n");
+		return -EBUSY;
+	}
+
+	ret = setup_backing_swap(rzs);
+	if (ret)
+		goto fail;
+
+	if (rzs->backing_swap)
+		ramzswap_set_memlimit(rzs, totalram_pages << PAGE_SHIFT);
+	else
+		ramzswap_set_disksize(rzs, totalram_pages << PAGE_SHIFT);
+
+	rzs->compress_workmem = kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
+	if (!rzs->compress_workmem) {
+		pr_err("Error allocating compressor working memory!\n");
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	rzs->compress_buffer = (void *)__get_free_pages(__GFP_ZERO, 1);
+	if (!rzs->compress_buffer) {
+		pr_err("Error allocating compressor buffer space\n");
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	num_pages = rzs->disksize >> PAGE_SHIFT;
+	rzs->table = vmalloc(num_pages * sizeof(*rzs->table));
+	if (!rzs->table) {
+		pr_err("Error allocating ramzswap address table\n");
+		/* To prevent accessing table entries during cleanup */
+		rzs->disksize = 0;
+		ret = -ENOMEM;
+		goto fail;
+	}
+	memset(rzs->table, 0, num_pages * sizeof(*rzs->table));
+
+	map_backing_swap_extents(rzs);
+
+	page = alloc_page(__GFP_ZERO);
+	if (!page) {
+		pr_err("Error allocating swap header page\n");
+		ret = -ENOMEM;
+		goto fail;
+	}
+	rzs->table[0].page = page;
+	rzs_set_flag(rzs, 0, RZS_UNCOMPRESSED);
+
+	swap_header = kmap(page);
+	ret = setup_swap_header(rzs, swap_header);
+	kunmap(page);
+	if (ret) {
+		pr_err("Error setting swap header\n");
+		goto fail;
+	}
+
+	set_capacity(rzs->disk, rzs->disksize >> SECTOR_SHIFT);
+
+	/*
+	 * We have ident mapping of sectors for ramzswap and
+	 * and the backing swap device. So, this queue flag
+	 * should be according to backing dev.
+	 */
+	if (!rzs->backing_swap ||
+			blk_queue_nonrot(rzs->backing_swap->bd_disk->queue))
+		queue_flag_set_unlocked(QUEUE_FLAG_NONROT, rzs->disk->queue);
+
+	rzs->mem_pool = xv_create_pool();
+	if (!rzs->mem_pool) {
+		pr_err("Error creating memory pool\n");
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	/*
+	 * Pages that compress to size greater than this are forwarded
+	 * to physical swap disk (if backing dev is provided)
+	 * TODO: make this configurable
+	 */
+	if (rzs->backing_swap)
+		max_zpage_size = max_zpage_size_bdev;
+	else
+		max_zpage_size = max_zpage_size_nobdev;
+	pr_debug("Max compressed page size: %u bytes\n", max_zpage_size);
+
+	rzs->init_done = 1;
+
+	pr_debug("Initialization done!\n");
+	return 0;
+
+fail:
+	reset_device(rzs);
+
+	pr_err("Initialization failed: err=%d\n", ret);
+	return ret;
+}
+
+static int ramzswap_ioctl_reset_device(struct ramzswap *rzs)
+{
+	if (rzs->init_done)
+		reset_device(rzs);
+
+	return 0;
+}
+
+static int ramzswap_ioctl(struct block_device *bdev, fmode_t mode,
+			unsigned int cmd, unsigned long arg)
+{
+	int ret = 0;
+	size_t disksize_kb, memlimit_kb;
+
+	struct ramzswap *rzs = bdev->bd_disk->private_data;
+
+	switch (cmd) {
+	case RZSIO_SET_DISKSIZE_KB:
+		if (rzs->init_done) {
+			ret = -EBUSY;
+			goto out;
+		}
+		if (copy_from_user(&disksize_kb, (void *)arg,
+						_IOC_SIZE(cmd))) {
+			ret = -EFAULT;
+			goto out;
+		}
+		rzs->disksize = disksize_kb << 10;
+		pr_info("Disk size set to %zu kB\n", disksize_kb);
+		break;
+
+	case RZSIO_SET_MEMLIMIT_KB:
+		if (rzs->init_done) {
+			/* TODO: allow changing memlimit */
+			ret = -EBUSY;
+			goto out;
+		}
+		if (copy_from_user(&memlimit_kb, (void *)arg,
+						_IOC_SIZE(cmd))) {
+			ret = -EFAULT;
+			goto out;
+		}
+		rzs->memlimit = memlimit_kb << 10;
+		pr_info("Memory limit set to %zu kB\n", memlimit_kb);
+		break;
+
+	case RZSIO_SET_BACKING_SWAP:
+		if (rzs->init_done) {
+			ret = -EBUSY;
+			goto out;
+		}
+
+		if (copy_from_user(&rzs->backing_swap_name, (void *)arg,
+						_IOC_SIZE(cmd))) {
+			ret = -EFAULT;
+			goto out;
+		}
+		rzs->backing_swap_name[MAX_SWAP_NAME_LEN - 1] = '\0';
+		pr_info("Backing swap set to %s\n", rzs->backing_swap_name);
+		break;
+
+	case RZSIO_GET_STATS:
+	{
+		struct ramzswap_ioctl_stats *stats;
+		if (!rzs->init_done) {
+			ret = -ENOTTY;
+			goto out;
+		}
+		stats = kzalloc(sizeof(*stats), GFP_KERNEL);
+		if (!stats) {
+			ret = -ENOMEM;
+			goto out;
+		}
+		ramzswap_ioctl_get_stats(rzs, stats);
+		if (copy_to_user((void *)arg, stats, sizeof(*stats))) {
+			kfree(stats);
+			ret = -EFAULT;
+			goto out;
+		}
+		kfree(stats);
+		break;
+	}
+	case RZSIO_INIT:
+		ret = ramzswap_ioctl_init_device(rzs);
+		break;
+
+	case RZSIO_RESET:
+		/* Do not reset an active device! */
+		if (bdev->bd_holders) {
+			ret = -EBUSY;
+			goto out;
+		}
+		ret = ramzswap_ioctl_reset_device(rzs);
+		break;
+
+	default:
+		pr_info("Invalid ioctl %u\n", cmd);
+		ret = -ENOTTY;
+	}
+
+out:
+	return ret;
+}
+
+static struct block_device_operations ramzswap_devops = {
+	.ioctl = ramzswap_ioctl,
+	.owner = THIS_MODULE,
+};
+
+static void create_device(struct ramzswap *rzs, int device_id)
+{
+	mutex_init(&rzs->lock);
+	INIT_LIST_HEAD(&rzs->backing_swap_extent_list);
+
+	rzs->queue = blk_alloc_queue(GFP_KERNEL);
+	if (!rzs->queue) {
+		pr_err("Error allocating disk queue for device %d\n",
+			device_id);
+		return;
+	}
+
+	blk_queue_make_request(rzs->queue, ramzswap_make_request);
+	rzs->queue->queuedata = rzs;
+
+	 /* gendisk structure */
+	rzs->disk = alloc_disk(1);
+	if (!rzs->disk) {
+		blk_cleanup_queue(rzs->queue);
+		pr_warning("Error allocating disk structure for device %d\n",
+			device_id);
+		return;
+	}
+
+	rzs->disk->major = ramzswap_major;
+	rzs->disk->first_minor = device_id;
+	rzs->disk->fops = &ramzswap_devops;
+	rzs->disk->queue = rzs->queue;
+	rzs->disk->private_data = rzs;
+	snprintf(rzs->disk->disk_name, 16, "ramzswap%d", device_id);
+
+	/*
+	 * Actual capacity set using RZSIO_SET_DISKSIZE_KB ioctl
+	 * or set equal to backing swap device (if provided)
+	 */
+	set_capacity(rzs->disk, 0);
+	add_disk(rzs->disk);
+
+	rzs->init_done = 0;
+}
+
+static void destroy_device(struct ramzswap *rzs)
+{
+	if (rzs->disk) {
+		del_gendisk(rzs->disk);
+		put_disk(rzs->disk);
+	}
+
+	if (rzs->queue)
+		blk_cleanup_queue(rzs->queue);
+}
+
+static int __init ramzswap_init(void)
+{
+	int i, ret;
+
+	if (num_devices > max_num_devices) {
+		pr_warning("Invalid value for num_devices: %u\n",
+				num_devices);
+		return -EINVAL;
+	}
+
+	ramzswap_major = register_blkdev(0, "ramzswap");
+	if (ramzswap_major <= 0) {
+		pr_warning("Unable to get major number\n");
+		return -EBUSY;
+	}
+
+	if (!num_devices) {
+		pr_info("num_devices not specified. Using default: 1\n");
+		num_devices = 1;
+	}
+
+	/* Allocate the device array and initialize each one */
+	pr_info("Creating %u devices ...\n", num_devices);
+	devices = kzalloc(num_devices * sizeof(struct ramzswap), GFP_KERNEL);
+	if (!devices) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	for (i = 0; i < num_devices; i++)
+		create_device(&devices[i], i);
+
+	return 0;
+out:
+	unregister_blkdev(ramzswap_major, "ramzswap");
+	return ret;
+}
+
+static void __exit ramzswap_exit(void)
+{
+	int i;
+	struct ramzswap *rzs;
+
+	for (i = 0; i < num_devices; i++) {
+		rzs = &devices[i];
+
+		destroy_device(rzs);
+		if (rzs->init_done)
+			reset_device(rzs);
+	}
+
+	unregister_blkdev(ramzswap_major, "ramzswap");
+
+	kfree(devices);
+	pr_debug("Cleanup done!\n");
+}
+
+module_param(num_devices, uint, 0);
+MODULE_PARM_DESC(num_devices, "Number of ramzswap devices");
+
+module_init(ramzswap_init);
+module_exit(ramzswap_exit);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Nitin Gupta <ngupta@vflare.org>");
+MODULE_DESCRIPTION("Compressed RAM Based Swap Device");
diff --git a/drivers/staging/ramzswap/ramzswap_drv.h b/drivers/staging/ramzswap/ramzswap_drv.h
new file mode 100644
index 0000000..a6ea240
--- /dev/null
+++ b/drivers/staging/ramzswap/ramzswap_drv.h
@@ -0,0 +1,171 @@
+/*
+ * Compressed RAM based swap device
+ *
+ * Copyright (C) 2008, 2009  Nitin Gupta
+ *
+ * This code is released using a dual license strategy: BSD/GPL
+ * You can choose the licence that better fits your requirements.
+ *
+ * Released under the terms of 3-clause BSD License
+ * Released under the terms of GNU General Public License Version 2.0
+ *
+ * Project home: http://compcache.googlecode.com
+ */
+
+#ifndef _RAMZSWAP_DRV_H_
+#define _RAMZSWAP_DRV_H_
+
+#include "ramzswap_ioctl.h"
+#include "xvmalloc.h"
+
+/*
+ * Some arbitrary value. This is just to catch
+ * invalid value for num_devices module parameter.
+ */
+static const unsigned max_num_devices = 32;
+
+/*
+ * Stored at beginning of each compressed object.
+ *
+ * It stores back-reference to table entry which points to this
+ * object. This is required to support memory defragmentation or
+ * migrating compressed pages to backing swap disk.
+ */
+struct zobj_header {
+#if 0
+	u32 table_idx;
+#endif
+};
+
+/*-- Configurable parameters */
+
+/* Default ramzswap disk size: 25% of total RAM */
+static const unsigned default_disksize_perc_ram = 25;
+static const unsigned default_memlimit_perc_ram = 15;
+
+/*
+ * Max compressed page size when backing device is provided.
+ * Pages that compress to size greater than this are sent to
+ * physical swap disk.
+ */
+static const unsigned max_zpage_size_bdev = PAGE_SIZE / 2;
+
+/*
+ * Max compressed page size when there is no backing dev.
+ * Pages that compress to size greater than this are stored
+ * uncompressed in memory.
+ */
+static const unsigned max_zpage_size_nobdev = PAGE_SIZE / 4 * 3;
+
+/*
+ * NOTE: max_zpage_size_{bdev,nobdev} sizes must be
+ * less than or equal to:
+ *   XV_MAX_ALLOC_SIZE - sizeof(struct zobj_header)
+ * since otherwise xv_malloc would always return failure.
+ */
+
+/*-- End of configurable params */
+
+#define SECTOR_SHIFT		9
+#define SECTOR_SIZE		(1 << SECTOR_SHIFT)
+#define SECTORS_PER_PAGE_SHIFT	(PAGE_SHIFT - SECTOR_SHIFT)
+#define SECTORS_PER_PAGE	(1 << SECTORS_PER_PAGE_SHIFT)
+
+/* Debugging and Stats */
+#if defined(CONFIG_RAMZSWAP_STATS)
+#define stat_inc(stat)	((stat)++)
+#define stat_dec(stat)	((stat)--)
+#else
+#define stat_inc(x)
+#define stat_dec(x)
+#endif
+
+/* Flags for ramzswap pages (table[page_no].flags) */
+enum rzs_pageflags {
+	/* Page is stored uncompressed */
+	RZS_UNCOMPRESSED,
+
+	/* Page consists entirely of zeros */
+	RZS_ZERO,
+
+	__NR_RZS_PAGEFLAGS,
+};
+
+/*-- Data structures */
+
+/*
+ * Allocated for each swap slot, indexed by page no.
+ * These table entries must fit exactly in a page.
+ */
+struct table {
+	struct page *page;
+	u16 offset;
+	u8 count;	/* object ref count (not yet used) */
+	u8 flags;
+} __attribute__((aligned(4)));;
+
+/*
+ * Swap extent information in case backing swap is a regular
+ * file. These extent entries must fit exactly in a page.
+ */
+struct ramzswap_backing_extent {
+	pgoff_t phy_pagenum;
+	pgoff_t num_pages;
+} __attribute__((aligned(4)));
+
+struct ramzswap_stats {
+	/* basic stats */
+	size_t compr_size;	/* compressed size of pages stored -
+				 * needed to enforce memlimit */
+	/* more stats */
+#if defined(CONFIG_RAMZSWAP_STATS)
+	u64 num_reads;		/* failed + successful */
+	u64 num_writes;		/* --do-- */
+	u64 failed_reads;	/* can happen when memory is too low */
+	u64 failed_writes;	/* should NEVER! happen */
+	u64 invalid_io;		/* non-swap I/O requests */
+	u32 pages_zero;		/* no. of zero filled pages */
+	u32 pages_stored;	/* no. of pages currently stored */
+	u32 good_compress;	/* % of pages with compression ratio<=50% */
+	u32 pages_expand;	/* % of incompressible pages */
+	u64 bdev_num_reads;	/* no. of reads on backing dev */
+	u64 bdev_num_writes;	/* no. of writes on backing dev */
+#endif
+};
+
+struct ramzswap {
+	struct xv_pool *mem_pool;
+	void *compress_workmem;
+	void *compress_buffer;
+	struct table *table;
+	struct mutex lock;
+	struct request_queue *queue;
+	struct gendisk *disk;
+	int init_done;
+	/*
+	 * This is limit on compressed data size (stats.compr_size)
+	 * Its applicable only when backing swap device is present.
+	 */
+	size_t memlimit;	/* bytes */
+	/*
+	 * This is limit on amount of *uncompressed* worth of data
+	 * we can hold. When backing swap device is provided, it is
+	 * set equal to device size.
+	 */
+	size_t disksize;	/* bytes */
+
+	struct ramzswap_stats stats;
+
+	/* backing swap device info */
+	struct ramzswap_backing_extent *curr_extent;
+	struct list_head backing_swap_extent_list;
+	unsigned long num_extents;
+	char backing_swap_name[MAX_SWAP_NAME_LEN];
+	struct block_device *backing_swap;
+	struct file *swap_file;
+};
+
+/*-- */
+
+#endif
+
diff --git a/drivers/staging/ramzswap/ramzswap_ioctl.h b/drivers/staging/ramzswap/ramzswap_ioctl.h
new file mode 100644
index 0000000..c713a09
--- /dev/null
+++ b/drivers/staging/ramzswap/ramzswap_ioctl.h
@@ -0,0 +1,49 @@
+/*
+ * Compressed RAM based swap device
+ *
+ * Copyright (C) 2008, 2009  Nitin Gupta
+ *
+ * This code is released using a dual license strategy: BSD/GPL
+ * You can choose the licence that better fits your requirements.
+ *
+ * Released under the terms of 3-clause BSD License
+ * Released under the terms of GNU General Public License Version 2.0
+ *
+ * Project home: http://compcache.googlecode.com
+ */
+
+#ifndef _RAMZSWAP_IOCTL_H_
+#define _RAMZSWAP_IOCTL_H_
+
+#define MAX_SWAP_NAME_LEN 128
+
+struct ramzswap_ioctl_stats {
+	char backing_swap_name[MAX_SWAP_NAME_LEN];
+	u64 memlimit;		/* only applicable if backing swap present */
+	u64 disksize;		/* user specified or equal to backing swap
+				 * size (if present) */
+	u64 num_reads;		/* failed + successful */
+	u64 num_writes;		/* --do-- */
+	u64 failed_reads;	/* can happen when memory is too low */
+	u64 failed_writes;	/* should NEVER! happen */
+	u64 invalid_io;		/* non-swap I/O requests */
+	u32 pages_zero;		/* no. of zero filled pages */
+	u32 good_compress_pct;	/* no. of pages with compression ratio<=50% */
+	u32 pages_expand_pct;	/* no. of incompressible pages */
+	u32 pages_stored;
+	u32 pages_used;
+	u64 orig_data_size;
+	u64 compr_data_size;
+	u64 mem_used_total;
+	u64 bdev_num_reads;	/* no. of reads on backing dev */
+	u64 bdev_num_writes;	/* no. of writes on backing dev */
+} __attribute__ ((packed, aligned(4)));
+
+#define RZSIO_SET_DISKSIZE_KB	_IOW('z', 0, size_t)
+#define RZSIO_SET_MEMLIMIT_KB	_IOW('z', 1, size_t)
+#define RZSIO_SET_BACKING_SWAP	_IOW('z', 2, unsigned char[MAX_SWAP_NAME_LEN])
+#define RZSIO_GET_STATS		_IOR('z', 3, struct ramzswap_ioctl_stats)
+#define RZSIO_INIT		_IO('z', 4)
+#define RZSIO_RESET		_IO('z', 5)
+
+#endif
diff --git a/drivers/staging/ramzswap/xvmalloc.c b/drivers/staging/ramzswap/xvmalloc.c
new file mode 100644
index 0000000..b3e986c
--- /dev/null
+++ b/drivers/staging/ramzswap/xvmalloc.c
@@ -0,0 +1,507 @@
+/*
+ * xvmalloc memory allocator
+ *
+ * Copyright (C) 2008, 2009  Nitin Gupta
+ *
+ * This code is released using a dual license strategy: BSD/GPL
+ * You can choose the licence that better fits your requirements.
+ *
+ * Released under the terms of 3-clause BSD License
+ * Released under the terms of GNU General Public License Version 2.0
+ */
+
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/highmem.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "xvmalloc.h"
+#include "xvmalloc_int.h"
+
+static void stat_inc(u64 *value)
+{
+	*value = *value + 1;
+}
+
+static void stat_dec(u64 *value)
+{
+	*value = *value - 1;
+}
+
+static int test_flag(struct block_header *block, enum blockflags flag)
+{
+	return block->prev & BIT(flag);
+}
+
+static void set_flag(struct block_header *block, enum blockflags flag)
+{
+	block->prev |= BIT(flag);
+}
+
+static void clear_flag(struct block_header *block, enum blockflags flag)
+{
+	block->prev &= ~BIT(flag);
+}
+
+/*
+ * Given <page, offset> pair, provide a derefrencable pointer.
+ * This is called from xv_malloc/xv_free path, so it
+ * needs to be fast.
+ */
+static void *get_ptr_atomic(struct page *page, u16 offset, enum km_type type)
+{
+	unsigned char *base;
+
+	base = kmap_atomic(page, type);
+	return base + offset;
+}
+
+static void put_ptr_atomic(void *ptr, enum km_type type)
+{
+	kunmap_atomic(ptr, type);
+}
+
+static u32 get_blockprev(struct block_header *block)
+{
+	return block->prev & PREV_MASK;
+}
+
+static void set_blockprev(struct block_header *block, u16 new_offset)
+{
+	block->prev = new_offset | (block->prev & FLAGS_MASK);
+}
+
+static struct block_header *BLOCK_NEXT(struct block_header *block)
+{
+	return (struct block_header *)
+		((char *)block + block->size + XV_ALIGN);
+}
+
+/*
+ * Get index of free list containing blocks of maximum size
+ * which is less than or equal to given size.
+ */
+static u32 get_index_for_insert(u32 size)
+{
+	if (unlikely(size > XV_MAX_ALLOC_SIZE))
+		size = XV_MAX_ALLOC_SIZE;
+	size &= ~FL_DELTA_MASK;
+	return (size - XV_MIN_ALLOC_SIZE) >> FL_DELTA_SHIFT;
+}
+
+/*
+ * Get index of free list having blocks of size greater than
+ * or equal to requested size.
+ */
+static u32 get_index(u32 size)
+{
+	if (unlikely(size < XV_MIN_ALLOC_SIZE))
+		size = XV_MIN_ALLOC_SIZE;
+	size = ALIGN(size, FL_DELTA);
+	return (size - XV_MIN_ALLOC_SIZE) >> FL_DELTA_SHIFT;
+}
+
+/**
+ * find_block - find block of at least given size
+ * @pool: memory pool to search from
+ * @size: size of block required
+ * @page: page containing required block
+ * @offset: offset within the page where block is located.
+ *
+ * Searches two level bitmap to locate block of at least
+ * the given size. If such a block is found, it provides
+ * <page, offset> to identify this block and returns index
+ * in freelist where we found this block.
+ * Otherwise, returns 0 and <page, offset> params are not touched.
+ */
+static u32 find_block(struct xv_pool *pool, u32 size,
+			struct page **page, u32 *offset)
+{
+	ulong flbitmap, slbitmap;
+	u32 flindex, slindex, slbitstart;
+
+	/* There are no free blocks in this pool */
+	if (!pool->flbitmap)
+		return 0;
+
+	/* Get freelist index correspoding to this size */
+	slindex = get_index(size);
+	slbitmap = pool->slbitmap[slindex / BITS_PER_LONG];
+	slbitstart = slindex % BITS_PER_LONG;
+
+	/*
+	 * If freelist is not empty at this index, we found the
+	 * block - head of this list. This is approximate best-fit match.
+	 */
+	if (test_bit(slbitstart, &slbitmap)) {
+		*page = pool->freelist[slindex].page;
+		*offset = pool->freelist[slindex].offset;
+		return slindex;
+	}
+
+	/*
+	 * No best-fit found. Search a bit further in bitmap for a free block.
+	 * Second level bitmap consists of series of 32-bit chunks. Search
+	 * further in the chunk where we expected a best-fit, starting from
+	 * index location found above.
+	 */
+	slbitstart++;
+	slbitmap >>= slbitstart;
+
+	/* Skip this search if we were already at end of this bitmap chunk */
+	if ((slbitstart != BITS_PER_LONG) && slbitmap) {
+		slindex += __ffs(slbitmap) + 1;
+		*page = pool->freelist[slindex].page;
+		*offset = pool->freelist[slindex].offset;
+		return slindex;
+	}
+
+	/* Now do a full two-level bitmap search to find next nearest fit */
+	flindex = slindex / BITS_PER_LONG;
+
+	flbitmap = (pool->flbitmap) >> (flindex + 1);
+	if (!flbitmap)
+		return 0;
+
+	flindex += __ffs(flbitmap) + 1;
+	slbitmap = pool->slbitmap[flindex];
+	slindex = (flindex * BITS_PER_LONG) + __ffs(slbitmap);
+	*page = pool->freelist[slindex].page;
+	*offset = pool->freelist[slindex].offset;
+
+	return slindex;
+}
+
+/*
+ * Insert block at <page, offset> in freelist of given pool.
+ * freelist used depends on block size.
+ */
+static void insert_block(struct xv_pool *pool, struct page *page, u32 offset,
+			struct block_header *block)
+{
+	u32 flindex, slindex;
+	struct block_header *nextblock;
+
+	slindex = get_index_for_insert(block->size);
+	flindex = slindex / BITS_PER_LONG;
+
+	block->link.prev_page = 0;
+	block->link.prev_offset = 0;
+	block->link.next_page = pool->freelist[slindex].page;
+	block->link.next_offset = pool->freelist[slindex].offset;
+	pool->freelist[slindex].page = page;
+	pool->freelist[slindex].offset = offset;
+
+	if (block->link.next_page) {
+		nextblock = get_ptr_atomic(block->link.next_page,
+					block->link.next_offset, KM_USER1);
+		nextblock->link.prev_page = page;
+		nextblock->link.prev_offset = offset;
+		put_ptr_atomic(nextblock, KM_USER1);
+	}
+
+	__set_bit(slindex % BITS_PER_LONG, &pool->slbitmap[flindex]);
+	__set_bit(flindex, &pool->flbitmap);
+}
+
+/*
+ * Remove block from head of freelist. Index 'slindex' identifies the freelist.
+ */
+static void remove_block_head(struct xv_pool *pool,
+			struct block_header *block, u32 slindex)
+{
+	struct block_header *tmpblock;
+	u32 flindex = slindex / BITS_PER_LONG;
+
+	pool->freelist[slindex].page = block->link.next_page;
+	pool->freelist[slindex].offset = block->link.next_offset;
+	block->link.prev_page = 0;
+	block->link.prev_offset = 0;
+
+	if (!pool->freelist[slindex].page) {
+		__clear_bit(slindex % BITS_PER_LONG, &pool->slbitmap[flindex]);
+		if (!pool->slbitmap[flindex])
+			__clear_bit(flindex, &pool->flbitmap);
+	} else {
+		/*
+		 * DEBUG ONLY: We need not reinitialize freelist head previous
+		 * pointer to 0 - we never depend on its value. But just for
+		 * sanity, lets do it.
+		 */
+		tmpblock = get_ptr_atomic(pool->freelist[slindex].page,
+				pool->freelist[slindex].offset, KM_USER1);
+		tmpblock->link.prev_page = 0;
+		tmpblock->link.prev_offset = 0;
+		put_ptr_atomic(tmpblock, KM_USER1);
+	}
+}
+
+/*
+ * Remove block from freelist. Index 'slindex' identifies the freelist.
+ */
+static void remove_block(struct xv_pool *pool, struct page *page, u32 offset,
+			struct block_header *block, u32 slindex)
+{
+	u32 flindex;
+	struct block_header *tmpblock;
+
+	if (pool->freelist[slindex].page == page
+	   && pool->freelist[slindex].offset == offset) {
+		remove_block_head(pool, block, slindex);
+		return;
+	}
+
+	flindex = slindex / BITS_PER_LONG;
+
+	if (block->link.prev_page) {
+		tmpblock = get_ptr_atomic(block->link.prev_page,
+				block->link.prev_offset, KM_USER1);
+		tmpblock->link.next_page = block->link.next_page;
+		tmpblock->link.next_offset = block->link.next_offset;
+		put_ptr_atomic(tmpblock, KM_USER1);
+	}
+
+	if (block->link.next_page) {
+		tmpblock = get_ptr_atomic(block->link.next_page,
+				block->link.next_offset, KM_USER1);
+		tmpblock->link.prev_page = block->link.prev_page;
+		tmpblock->link.prev_offset = block->link.prev_offset;
+		put_ptr_atomic(tmpblock, KM_USER1);
+	}
+}
+
+/*
+ * Allocate a page and add it freelist of given pool.
+ */
+static int grow_pool(struct xv_pool *pool, gfp_t flags)
+{
+	struct page *page;
+	struct block_header *block;
+
+	page = alloc_page(flags);
+	if (unlikely(!page))
+		return -ENOMEM;
+
+	stat_inc(&pool->total_pages);
+
+	spin_lock(&pool->lock);
+	block = get_ptr_atomic(page, 0, KM_USER0);
+
+	block->size = PAGE_SIZE - XV_ALIGN;
+	set_flag(block, BLOCK_FREE);
+	clear_flag(block, PREV_FREE);
+	set_blockprev(block, 0);
+
+	insert_block(pool, page, 0, block);
+
+	put_ptr_atomic(block, KM_USER0);
+	spin_unlock(&pool->lock);
+
+	return 0;
+}
+
+/*
+ * Create a memory pool. Allocates freelist, bitmaps and other
+ * per-pool metadata.
+ */
+struct xv_pool *xv_create_pool(void)
+{
+	u32 ovhd_size;
+	struct xv_pool *pool;
+
+	ovhd_size = roundup(sizeof(*pool), PAGE_SIZE);
+	pool = kzalloc(ovhd_size, GFP_KERNEL);
+	if (!pool)
+		return NULL;
+
+	spin_lock_init(&pool->lock);
+
+	return pool;
+}
+
+void xv_destroy_pool(struct xv_pool *pool)
+{
+	kfree(pool);
+}
+
+/**
+ * xv_malloc - Allocate block of given size from pool.
+ * @pool: pool to allocate from
+ * @size: size of block to allocate
+ * @page: page no. that holds the object
+ * @offset: location of object within page
+ *
+ * On success, <page, offset> identifies block allocated
+ * and 0 is returned. On failure, <page, offset> is set to
+ * 0 and -ENOMEM is returned.
+ *
+ * Allocation requests with size > XV_MAX_ALLOC_SIZE will fail.
+ */
+int xv_malloc(struct xv_pool *pool, u32 size, struct page **page,
+		u32 *offset, gfp_t flags)
+{
+	int error;
+	u32 index, tmpsize, origsize, tmpoffset;
+	struct block_header *block, *tmpblock;
+
+	*page = NULL;
+	*offset = 0;
+	origsize = size;
+
+	if (unlikely(!size || size > XV_MAX_ALLOC_SIZE))
+		return -ENOMEM;
+
+	size = ALIGN(size, XV_ALIGN);
+
+	spin_lock(&pool->lock);
+
+	index = find_block(pool, size, page, offset);
+
+	if (!*page) {
+		spin_unlock(&pool->lock);
+		if (flags & GFP_NOWAIT)
+			return -ENOMEM;
+		error = grow_pool(pool, flags);
+		if (unlikely(error))
+			return error;
+
+		spin_lock(&pool->lock);
+		index = find_block(pool, size, page, offset);
+	}
+
+	if (!*page) {
+		spin_unlock(&pool->lock);
+		return -ENOMEM;
+	}
+
+	block = get_ptr_atomic(*page, *offset, KM_USER0);
+
+	remove_block_head(pool, block, index);
+
+	/* Split the block if required */
+	tmpoffset = *offset + size + XV_ALIGN;
+	tmpsize = block->size - size;
+	tmpblock = (struct block_header *)((char *)block + size + XV_ALIGN);
+	if (tmpsize) {
+		tmpblock->size = tmpsize - XV_ALIGN;
+		set_flag(tmpblock, BLOCK_FREE);
+		clear_flag(tmpblock, PREV_FREE);
+
+		set_blockprev(tmpblock, *offset);
+		if (tmpblock->size >= XV_MIN_ALLOC_SIZE)
+			insert_block(pool, *page, tmpoffset, tmpblock);
+
+		if (tmpoffset + XV_ALIGN + tmpblock->size != PAGE_SIZE) {
+			tmpblock = BLOCK_NEXT(tmpblock);
+			set_blockprev(tmpblock, tmpoffset);
+		}
+	} else {
+		/* This block is exact fit */
+		if (tmpoffset != PAGE_SIZE)
+			clear_flag(tmpblock, PREV_FREE);
+	}
+
+	block->size = origsize;
+	clear_flag(block, BLOCK_FREE);
+
+	put_ptr_atomic(block, KM_USER0);
+	spin_unlock(&pool->lock);
+
+	*offset += XV_ALIGN;
+
+	return 0;
+}
+
+/*
+ * Free block identified with <page, offset>
+ */
+void xv_free(struct xv_pool *pool, struct page *page, u32 offset)
+{
+	void *page_start;
+	struct block_header *block, *tmpblock;
+
+	offset -= XV_ALIGN;
+
+	spin_lock(&pool->lock);
+
+	page_start = get_ptr_atomic(page, 0, KM_USER0);
+	block = (struct block_header *)((char *)page_start + offset);
+
+	/* Catch double free bugs */
+	BUG_ON(test_flag(block, BLOCK_FREE));
+
+	block->size = ALIGN(block->size, XV_ALIGN);
+
+	tmpblock = BLOCK_NEXT(block);
+	if (offset + block->size + XV_ALIGN == PAGE_SIZE)
+		tmpblock = NULL;
+
+	/* Merge next block if its free */
+	if (tmpblock && test_flag(tmpblock, BLOCK_FREE)) {
+		/*
+		 * Blocks smaller than XV_MIN_ALLOC_SIZE
+		 * are not inserted in any free list.
+		 */
+		if (tmpblock->size >= XV_MIN_ALLOC_SIZE) {
+			remove_block(pool, page,
+				    offset + block->size + XV_ALIGN, tmpblock,
+				    get_index_for_insert(tmpblock->size));
+		}
+		block->size += tmpblock->size + XV_ALIGN;
+	}
+
+	/* Merge previous block if its free */
+	if (test_flag(block, PREV_FREE)) {
+		tmpblock = (struct block_header *)((char *)(page_start) +
+						get_blockprev(block));
+		offset = offset - tmpblock->size - XV_ALIGN;
+
+		if (tmpblock->size >= XV_MIN_ALLOC_SIZE)
+			remove_block(pool, page, offset, tmpblock,
+				    get_index_for_insert(tmpblock->size));
+
+		tmpblock->size += block->size + XV_ALIGN;
+		block = tmpblock;
+	}
+
+	/* No used objects in this page. Free it. */
+	if (block->size == PAGE_SIZE - XV_ALIGN) {
+		put_ptr_atomic(page_start, KM_USER0);
+		spin_unlock(&pool->lock);
+
+		__free_page(page);
+		stat_dec(&pool->total_pages);
+		return;
+	}
+
+	set_flag(block, BLOCK_FREE);
+	if (block->size >= XV_MIN_ALLOC_SIZE)
+		insert_block(pool, page, offset, block);
+
+	if (offset + block->size + XV_ALIGN != PAGE_SIZE) {
+		tmpblock = BLOCK_NEXT(block);
+		set_flag(tmpblock, PREV_FREE);
+		set_blockprev(tmpblock, offset);
+	}
+
+	put_ptr_atomic(page_start, KM_USER0);
+	spin_unlock(&pool->lock);
+}
+
+u32 xv_get_object_size(void *obj)
+{
+	struct block_header *blk;
+
+	blk = (struct block_header *)((char *)(obj) - XV_ALIGN);
+	return blk->size;
+}
+
+/*
+ * Returns total memory used by allocator (userdata + metadata)
+ */
+u64 xv_get_total_size_bytes(struct xv_pool *pool)
+{
+	return pool->total_pages << PAGE_SHIFT;
+}
diff --git a/drivers/staging/ramzswap/xvmalloc.h b/drivers/staging/ramzswap/xvmalloc.h
new file mode 100644
index 0000000..010c6fe
--- /dev/null
+++ b/drivers/staging/ramzswap/xvmalloc.h
@@ -0,0 +1,30 @@
+/*
+ * xvmalloc memory allocator
+ *
+ * Copyright (C) 2008, 2009  Nitin Gupta
+ *
+ * This code is released using a dual license strategy: BSD/GPL
+ * You can choose the licence that better fits your requirements.
+ *
+ * Released under the terms of 3-clause BSD License
+ * Released under the terms of GNU General Public License Version 2.0
+ */
+
+#ifndef _XV_MALLOC_H_
+#define _XV_MALLOC_H_
+
+#include <linux/types.h>
+
+struct xv_pool;
+
+struct xv_pool *xv_create_pool(void);
+void xv_destroy_pool(struct xv_pool *pool);
+
+int xv_malloc(struct xv_pool *pool, u32 size, struct page **page,
+			u32 *offset, gfp_t flags);
+void xv_free(struct xv_pool *pool, struct page *page, u32 offset);
+
+u32 xv_get_object_size(void *obj);
+u64 xv_get_total_size_bytes(struct xv_pool *pool);
+
+#endif
diff --git a/drivers/staging/ramzswap/xvmalloc_int.h b/drivers/staging/ramzswap/xvmalloc_int.h
new file mode 100644
index 0000000..03c1a65
--- /dev/null
+++ b/drivers/staging/ramzswap/xvmalloc_int.h
@@ -0,0 +1,86 @@
+/*
+ * xvmalloc memory allocator
+ *
+ * Copyright (C) 2008, 2009  Nitin Gupta
+ *
+ * This code is released using a dual license strategy: BSD/GPL
+ * You can choose the licence that better fits your requirements.
+ *
+ * Released under the terms of 3-clause BSD License
+ * Released under the terms of GNU General Public License Version 2.0
+ */
+
+#ifndef _XV_MALLOC_INT_H_
+#define _XV_MALLOC_INT_H_
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+/* User configurable params */
+
+/* Must be power of two */
+#define XV_ALIGN_SHIFT	2
+#define XV_ALIGN	(1 << XV_ALIGN_SHIFT)
+#define XV_ALIGN_MASK	(XV_ALIGN - 1)
+
+/* This must be greater than sizeof(link_free) */
+#define XV_MIN_ALLOC_SIZE	32
+#define XV_MAX_ALLOC_SIZE	(PAGE_SIZE - XV_ALIGN)
+
+/* Free lists are separated by FL_DELTA bytes */
+#define FL_DELTA_SHIFT	3
+#define FL_DELTA	(1 << FL_DELTA_SHIFT)
+#define FL_DELTA_MASK	(FL_DELTA - 1)
+#define NUM_FREE_LISTS	((XV_MAX_ALLOC_SIZE - XV_MIN_ALLOC_SIZE) \
+				/ FL_DELTA + 1)
+
+#define MAX_FLI		DIV_ROUND_UP(NUM_FREE_LISTS, BITS_PER_LONG)
+
+/* End of user params */
+
+enum blockflags {
+	BLOCK_FREE,
+	PREV_FREE,
+	__NR_BLOCKFLAGS,
+};
+
+#define FLAGS_MASK	XV_ALIGN_MASK
+#define PREV_MASK	(~FLAGS_MASK)
+
+struct freelist_entry {
+	struct page *page;
+	u16 offset;
+	u16 pad;
+};
+
+struct link_free {
+	struct page *prev_page;
+	struct page *next_page;
+	u16 prev_offset;
+	u16 next_offset;
+};
+
+struct block_header {
+	union {
+		/* This common header must be ALIGN bytes */
+		u8 common[XV_ALIGN];
+		struct {
+			u16 size;
+			u16 prev;
+		};
+	};
+	struct link_free link;
+};
+
+struct xv_pool {
+	ulong flbitmap;
+	ulong slbitmap[MAX_FLI];
+	spinlock_t lock;
+
+	struct freelist_entry freelist[NUM_FREE_LISTS];
+
+	/* stats */
+	u64 total_pages;
+};
+
+#endif
diff --git a/drivers/staging/rar/rar_driver.c b/drivers/staging/rar/rar_driver.c
index 9805d74..d85d189 100644
--- a/drivers/staging/rar/rar_driver.c
+++ b/drivers/staging/rar/rar_driver.c
@@ -66,7 +66,7 @@
 static void __exit rar_exit_handler(void);
 
 /*
-  function that is activated on the succesfull probe of the RAR device
+  function that is activated on the successfull probe of the RAR device
 */
 static int __devinit rar_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
 
@@ -319,7 +319,7 @@
 }
 
 /*
-  function that is activaed on the succesfull probe of the RAR device
+  function that is activated on the successfull probe of the RAR device
 */
 static int __devinit rar_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
diff --git a/drivers/staging/rt2860/2860_main_dev.c b/drivers/staging/rt2860/2860_main_dev.c
deleted file mode 100644
index c2f0296..0000000
--- a/drivers/staging/rt2860/2860_main_dev.c
+++ /dev/null
@@ -1,1319 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    2870_main_dev.c
-
-    Abstract:
-    Create and register network interface.
-
-    Revision History:
-    Who         When            What
-    --------    ----------      ----------------------------------------------
-*/
-
-#include "rt_config.h"
-
-extern INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
-									IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
-
-static void rx_done_tasklet(unsigned long data);
-static void mgmt_dma_done_tasklet(unsigned long data);
-static void ac0_dma_done_tasklet(unsigned long data);
-static void ac1_dma_done_tasklet(unsigned long data);
-static void ac2_dma_done_tasklet(unsigned long data);
-static void ac3_dma_done_tasklet(unsigned long data);
-static void hcca_dma_done_tasklet(unsigned long data);
-static void fifo_statistic_full_tasklet(unsigned long data);
-
-
-/*---------------------------------------------------------------------*/
-/* Symbol & Macro Definitions                                          */
-/*---------------------------------------------------------------------*/
-#define RT2860_INT_RX_DLY				(1<<0)		// bit 0
-#define RT2860_INT_TX_DLY				(1<<1)		// bit 1
-#define RT2860_INT_RX_DONE				(1<<2)		// bit 2
-#define RT2860_INT_AC0_DMA_DONE			(1<<3)		// bit 3
-#define RT2860_INT_AC1_DMA_DONE			(1<<4)		// bit 4
-#define RT2860_INT_AC2_DMA_DONE			(1<<5)		// bit 5
-#define RT2860_INT_AC3_DMA_DONE			(1<<6)		// bit 6
-#define RT2860_INT_HCCA_DMA_DONE		(1<<7)		// bit 7
-#define RT2860_INT_MGMT_DONE			(1<<8)		// bit 8
-
-#define INT_RX			RT2860_INT_RX_DONE
-
-#define INT_AC0_DLY		(RT2860_INT_AC0_DMA_DONE) //| RT2860_INT_TX_DLY)
-#define INT_AC1_DLY		(RT2860_INT_AC1_DMA_DONE) //| RT2860_INT_TX_DLY)
-#define INT_AC2_DLY		(RT2860_INT_AC2_DMA_DONE) //| RT2860_INT_TX_DLY)
-#define INT_AC3_DLY		(RT2860_INT_AC3_DMA_DONE) //| RT2860_INT_TX_DLY)
-#define INT_HCCA_DLY 	(RT2860_INT_HCCA_DMA_DONE) //| RT2860_INT_TX_DLY)
-#define INT_MGMT_DLY	RT2860_INT_MGMT_DONE
-
-/*---------------------------------------------------------------------*/
-/* Prototypes of Functions Used                                        */
-/*---------------------------------------------------------------------*/
-/* function declarations */
-static INT __devinit rt2860_init_one (struct pci_dev *pci_dev, const struct pci_device_id  *ent);
-static VOID __devexit rt2860_remove_one(struct pci_dev *pci_dev);
-static INT __devinit rt2860_probe(struct pci_dev *pci_dev, const struct pci_device_id  *ent);
-void init_thread_task(PRTMP_ADAPTER pAd);
-static void __exit rt2860_cleanup_module(void);
-static int __init rt2860_init_module(void);
-
-#ifdef CONFIG_PM
-static int rt2860_suspend(struct pci_dev *pci_dev, pm_message_t state);
-static int rt2860_resume(struct pci_dev *pci_dev);
-#endif // CONFIG_PM //
-
-
-//
-// Ralink PCI device table, include all supported chipsets
-//
-static struct pci_device_id rt2860_pci_tbl[] __devinitdata =
-{
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2860_PCI_DEVICE_ID)},		//RT28602.4G
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2860_PCIe_DEVICE_ID)},
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2760_PCI_DEVICE_ID)},
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2790_PCIe_DEVICE_ID)},
-	{PCI_DEVICE(VEN_AWT_PCI_VENDOR_ID, VEN_AWT_PCIe_DEVICE_ID)},
-	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7708)},
-	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7728)},
-	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7758)},
-	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7727)},
-	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7738)},
-	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7748)},
-	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7768)},
-    {0,}		// terminate list
-};
-
-MODULE_DEVICE_TABLE(pci, rt2860_pci_tbl);
-MODULE_LICENSE("GPL");
-#ifdef MODULE_VERSION
-MODULE_VERSION(STA_DRIVER_VERSION);
-#endif
-
-//
-// Our PCI driver structure
-//
-static struct pci_driver rt2860_driver =
-{
-    name:       "rt2860",
-    id_table:   rt2860_pci_tbl,
-    probe:      rt2860_init_one,
-    remove:     __devexit_p(rt2860_remove_one),
-
-#ifdef CONFIG_PM
-	suspend:	rt2860_suspend,
-	resume:		rt2860_resume,
-#endif
-};
-
-
-#ifdef CONFIG_PM
-
-VOID RT2860RejectPendingPackets(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	// clear PS packets
-	// clear TxSw packets
-}
-
-static int rt2860_suspend(
-	struct pci_dev *pci_dev,
-	pm_message_t state)
-{
-	struct net_device *net_dev = pci_get_drvdata(pci_dev);
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL;
-	INT32 retval;
-
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_suspend()\n"));
-
-	if (net_dev == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n"));
-	}
-	else
-	{
-		pAd = net_dev->ml_priv;
-
-		/* we can not use IFF_UP because ra0 down but ra1 up */
-		/* and 1 suspend/resume function for 1 module, not for each interface */
-		/* so Linux will call suspend/resume function once */
-		if (VIRTUAL_IF_NUM(pAd) > 0)
-		{
-			// avoid users do suspend after interface is down
-
-			// stop interface
-			netif_carrier_off(net_dev);
-			netif_stop_queue(net_dev);
-
-			// mark device as removed from system and therefore no longer available
-			netif_device_detach(net_dev);
-
-			// mark halt flag
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-			// take down the device
-			rt28xx_close((PNET_DEV)net_dev);
-
-			RT_MOD_DEC_USE_COUNT();
-		}
-	}
-
-	// reference to http://vovo2000.com/type-lab/linux/kernel-api/linux-kernel-api.html
-	// enable device to generate PME# when suspended
-	// pci_choose_state(): Choose the power state of a PCI device to be suspended
-	retval = pci_enable_wake(pci_dev, pci_choose_state(pci_dev, state), 1);
-	// save the PCI configuration space of a device before suspending
-	pci_save_state(pci_dev);
-	// disable PCI device after use
-	pci_disable_device(pci_dev);
-
-	retval = pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_suspend()\n"));
-	return retval;
-}
-
-static int rt2860_resume(
-	struct pci_dev *pci_dev)
-{
-	struct net_device *net_dev = pci_get_drvdata(pci_dev);
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL;
-	INT32 retval;
-
-
-	// set the power state of a PCI device
-	// PCI has 4 power states, DO (normal) ~ D3(less power)
-	// in include/linux/pci.h, you can find that
-	// #define PCI_D0          ((pci_power_t __force) 0)
-	// #define PCI_D1          ((pci_power_t __force) 1)
-	// #define PCI_D2          ((pci_power_t __force) 2)
-	// #define PCI_D3hot       ((pci_power_t __force) 3)
-	// #define PCI_D3cold      ((pci_power_t __force) 4)
-	// #define PCI_UNKNOWN     ((pci_power_t __force) 5)
-	// #define PCI_POWER_ERROR ((pci_power_t __force) -1)
-	retval = pci_set_power_state(pci_dev, PCI_D0);
-
-	// restore the saved state of a PCI device
-	pci_restore_state(pci_dev);
-
-	// initialize device before it's used by a driver
-	if (pci_enable_device(pci_dev))
-	{
-		printk("pci enable fail!\n");
-		return 0;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_resume()\n"));
-
-	if (net_dev == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n"));
-	}
-	else
-		pAd = net_dev->ml_priv;
-
-	if (pAd != NULL)
-	{
-		/* we can not use IFF_UP because ra0 down but ra1 up */
-		/* and 1 suspend/resume function for 1 module, not for each interface */
-		/* so Linux will call suspend/resume function once */
-		if (VIRTUAL_IF_NUM(pAd) > 0)
-		{
-			// mark device as attached from system and restart if needed
-			netif_device_attach(net_dev);
-
-			if (rt28xx_open((PNET_DEV)net_dev) != 0)
-			{
-				// open fail
-				DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_resume()\n"));
-				return 0;
-			}
-
-			// increase MODULE use count
-			RT_MOD_INC_USE_COUNT();
-
-			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-			netif_start_queue(net_dev);
-			netif_carrier_on(net_dev);
-			netif_wake_queue(net_dev);
-		}
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_resume()\n"));
-	return 0;
-}
-#endif // CONFIG_PM //
-
-
-static INT __init rt2860_init_module(VOID)
-{
-	return pci_register_driver(&rt2860_driver);
-}
-
-
-//
-// Driver module unload function
-//
-static VOID __exit rt2860_cleanup_module(VOID)
-{
-    pci_unregister_driver(&rt2860_driver);
-}
-
-module_init(rt2860_init_module);
-module_exit(rt2860_cleanup_module);
-
-
-static INT __devinit rt2860_init_one (
-    IN  struct pci_dev              *pci_dev,
-    IN  const struct pci_device_id  *ent)
-{
-    INT rc;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_init_one\n"));
-
-    // wake up and enable device
-    if (pci_enable_device (pci_dev))
-    {
-        rc = -EIO;
-    }
-    else
-    {
-        rc = rt2860_probe(pci_dev, ent);
-    }
-
-    DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_init_one\n"));
-    return rc;
-}
-
-
-static VOID __devexit rt2860_remove_one(
-    IN  struct pci_dev  *pci_dev)
-{
-    struct net_device   *net_dev = pci_get_drvdata(pci_dev);
-    RTMP_ADAPTER        *pAd = net_dev->ml_priv;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_remove_one\n"));
-
-	if (pAd != NULL)
-	{
-		// Unregister network device
-		unregister_netdev(net_dev);
-
-		// Unmap CSR base address
-		iounmap((char *)(net_dev->base_addr));
-
-		RTMPFreeAdapter(pAd);
-
-		// release memory region
-		release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
-	}
-	else
-	{
-		// Unregister network device
-		unregister_netdev(net_dev);
-
-		// Unmap CSR base address
-		iounmap((char *)(net_dev->base_addr));
-
-		// release memory region
-		release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
-	}
-
-	// Free pre-allocated net_device memory
-	free_netdev(net_dev);
-}
-
-//
-// PCI device probe & initialization function
-//
-static INT __devinit   rt2860_probe(
-    IN  struct pci_dev              *pci_dev,
-    IN  const struct pci_device_id  *ent)
-{
-	PRTMP_ADAPTER pAd;
-    INT rv = 0;
-
-    rv = (INT)rt28xx_probe((void *)pci_dev, (void *)ent, 0, &pAd);
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE);
-	return rv;
-}
-
-
-void init_thread_task(IN PRTMP_ADAPTER pAd)
-{
-	POS_COOKIE pObj;
-
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->mgmt_dma_done_task, mgmt_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->ac0_dma_done_task, ac0_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->ac1_dma_done_task, ac1_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->ac2_dma_done_task, ac2_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->ac3_dma_done_task, ac3_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->hcca_dma_done_task, hcca_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->fifo_statistic_full_task, fifo_statistic_full_tasklet, (unsigned long)pAd);
-}
-
-void kill_thread_task(IN PRTMP_ADAPTER pAd)
-{
-	POS_COOKIE pObj;
-
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	tasklet_kill(&pObj->rx_done_task);
-	tasklet_kill(&pObj->mgmt_dma_done_task);
-	tasklet_kill(&pObj->ac0_dma_done_task);
-	tasklet_kill(&pObj->ac1_dma_done_task);
-	tasklet_kill(&pObj->ac2_dma_done_task);
-	tasklet_kill(&pObj->ac3_dma_done_task);
-	tasklet_kill(&pObj->hcca_dma_done_task);
-	tasklet_kill(&pObj->tbtt_task);
-	tasklet_kill(&pObj->fifo_statistic_full_task);
-}
-
-
-static void rt2860_int_enable(PRTMP_ADAPTER pAd, unsigned int mode)
-{
-	u32 regValue;
-
-	pAd->int_disable_mask &= ~(mode);
-	regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask);
-	RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue);     // 1:enable
-
-	if (regValue != 0)
-		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
-}
-
-
-static void rt2860_int_disable(PRTMP_ADAPTER pAd, unsigned int mode)
-{
-	u32 regValue;
-
-	pAd->int_disable_mask |= mode;
-	regValue = 	pAd->int_enable_reg & ~(pAd->int_disable_mask);
-	RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue);     // 0: disable
-
-	if (regValue == 0)
-	{
-		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
-	}
-}
-
-static void mgmt_dma_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
-    INT_SOURCE_CSR_STRUC	IntSource;
-	POS_COOKIE pObj;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-    pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	IntSource.word = 0;
-	IntSource.field.MgmtDmaDone = 1;
-	pAd->int_pending &= ~INT_MGMT_DLY;
-
-	RTMPHandleMgmtRingDmaDoneInterrupt(pAd);
-
-	// if you use RTMP_SEM_LOCK, sometimes kernel will hang up, no any
-	// bug report output
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid lose of interrupts
-	 */
-	if (pAd->int_pending & INT_MGMT_DLY)
-	{
-		tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable TxDataInt again */
-	rt2860_int_enable(pAd, INT_MGMT_DLY);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-}
-
-static void rx_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
-	BOOLEAN	bReschedule = 0;
-	POS_COOKIE pObj;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-    pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	pAd->int_pending &= ~(INT_RX);
-
-	bReschedule = STARxDoneInterruptHandle(pAd, 0);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid rotting packet
-	 */
-	if (pAd->int_pending & INT_RX || bReschedule)
-	{
-		tasklet_hi_schedule(&pObj->rx_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable RxINT again */
-	rt2860_int_enable(pAd, INT_RX);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-
-}
-
-void fifo_statistic_full_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
-	POS_COOKIE pObj;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-    pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	pAd->int_pending &= ~(FifoStaFullInt);
-	NICUpdateFifoStaCounters(pAd);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid rotting packet
-	 */
-	if (pAd->int_pending & FifoStaFullInt)
-	{
-		tasklet_hi_schedule(&pObj->fifo_statistic_full_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable RxINT again */
-
-	rt2860_int_enable(pAd, FifoStaFullInt);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-
-}
-
-static void hcca_dma_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
-    INT_SOURCE_CSR_STRUC	IntSource;
-	POS_COOKIE pObj;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-    pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-
-	IntSource.word = 0;
-	IntSource.field.HccaDmaDone = 1;
-	pAd->int_pending &= ~INT_HCCA_DLY;
-
-	RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid lose of interrupts
-	 */
-	if (pAd->int_pending & INT_HCCA_DLY)
-	{
-		tasklet_hi_schedule(&pObj->hcca_dma_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable TxDataInt again */
-	rt2860_int_enable(pAd, INT_HCCA_DLY);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-}
-
-static void ac3_dma_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
-    INT_SOURCE_CSR_STRUC	IntSource;
-	POS_COOKIE pObj;
-	BOOLEAN bReschedule = 0;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-    pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	IntSource.word = 0;
-	IntSource.field.Ac3DmaDone = 1;
-	pAd->int_pending &= ~INT_AC3_DLY;
-
-	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid lose of interrupts
-	 */
-	if ((pAd->int_pending & INT_AC3_DLY) || bReschedule)
-	{
-		tasklet_hi_schedule(&pObj->ac3_dma_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable TxDataInt again */
-	rt2860_int_enable(pAd, INT_AC3_DLY);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-}
-
-static void ac2_dma_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
-    INT_SOURCE_CSR_STRUC	IntSource;
-	POS_COOKIE pObj;
-	BOOLEAN bReschedule = 0;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-    pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	IntSource.word = 0;
-	IntSource.field.Ac2DmaDone = 1;
-	pAd->int_pending &= ~INT_AC2_DLY;
-
-	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-
-	/*
-	 * double check to avoid lose of interrupts
-	 */
-	if ((pAd->int_pending & INT_AC2_DLY) || bReschedule)
-	{
-		tasklet_hi_schedule(&pObj->ac2_dma_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable TxDataInt again */
-	rt2860_int_enable(pAd, INT_AC2_DLY);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-}
-
-static void ac1_dma_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
-    INT_SOURCE_CSR_STRUC	IntSource;
-	POS_COOKIE pObj;
-	BOOLEAN bReschedule = 0;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-    pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	IntSource.word = 0;
-	IntSource.field.Ac1DmaDone = 1;
-	pAd->int_pending &= ~INT_AC1_DLY;
-
-	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid lose of interrupts
-	 */
-	if ((pAd->int_pending & INT_AC1_DLY) || bReschedule)
-	{
-		tasklet_hi_schedule(&pObj->ac1_dma_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable TxDataInt again */
-	rt2860_int_enable(pAd, INT_AC1_DLY);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-}
-
-static void ac0_dma_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
-    INT_SOURCE_CSR_STRUC	IntSource;
-	POS_COOKIE pObj;
-	BOOLEAN bReschedule = 0;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-    pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	IntSource.word = 0;
-	IntSource.field.Ac0DmaDone = 1;
-	pAd->int_pending &= ~INT_AC0_DLY;
-
-	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid lose of interrupts
-	 */
-	if ((pAd->int_pending & INT_AC0_DLY) || bReschedule)
-	{
-		tasklet_hi_schedule(&pObj->ac0_dma_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable TxDataInt again */
-	rt2860_int_enable(pAd, INT_AC0_DLY);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-}
-
-
-int print_int_count;
-
-IRQ_HANDLE_TYPE
-rt2860_interrupt(int irq, void *dev_instance)
-{
-	struct net_device *net_dev = (struct net_device *) dev_instance;
-	PRTMP_ADAPTER pAd = net_dev->ml_priv;
-	INT_SOURCE_CSR_STRUC	IntSource;
-	POS_COOKIE pObj;
-	BOOLEAN	bOldValue;
-
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-
-	/* Note 03312008: we can not return here before
-		RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
-		RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word);
-		Or kernel will panic after ifconfig ra0 down sometimes */
-
-
-	//
-	// Inital the Interrupt source.
-	//
-	IntSource.word = 0x00000000L;
-//	McuIntSource.word = 0x00000000L;
-
-	//
-	// Get the interrupt sources & saved to local variable
-	//
-	//RTMP_IO_READ32(pAd, where, &McuIntSource.word);
-	//RTMP_IO_WRITE32(pAd, , McuIntSource.word);
-
-	//
-	// Flag fOP_STATUS_DOZE On, means ASIC put to sleep, elase means ASICK WakeUp
-	// And at the same time, clock maybe turned off that say there is no DMA service.
-	// when ASIC get to sleep.
-	// To prevent system hang on power saving.
-	// We need to check it before handle the INT_SOURCE_CSR, ASIC must be wake up.
-	//
-	// RT2661 => when ASIC is sleeping, MAC register cannot be read and written.
-	// RT2860 => when ASIC is sleeping, MAC register can be read and written.
-
-	bOldValue = pAd->bPCIclkOff;
-	pAd->bPCIclkOff = FALSE;
-	{
-		RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
-		RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word); // write 1 to clear
-	}
-	pAd->bPCIclkOff = bOldValue;
-
-	// Do nothing if Reset in progress
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
-		RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
-	{
-		return IRQ_HANDLED;
-	}
-
-	//
-	// Handle interrupt, walk through all bits
-	// Should start from highest priority interrupt
-	// The priority can be adjust by altering processing if statement
-	//
-
-	// If required spinlock, each interrupt service routine has to acquire
-	// and release itself.
-	//
-
-	// Do nothing if NIC doesn't exist
-	if (IntSource.word == 0xffffffff)
-	{
-		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS);
-		printk("snowpin - IntSource.word == 0xffffffff\n");
-		return IRQ_HANDLED;
-	}
-
-	if (IntSource.word & TxCoherent)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, (">>>TxCoherent<<<\n"));
-		RTMPHandleRxCoherentInterrupt(pAd);
-	}
-
-	if (IntSource.word & RxCoherent)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, (">>>RxCoherent<<<\n"));
-		RTMPHandleRxCoherentInterrupt(pAd);
-	}
-
-	if (IntSource.word & FifoStaFullInt)
-	{
-#if 1
-		if ((pAd->int_disable_mask & FifoStaFullInt) == 0)
-		{
-			/* mask FifoStaFullInt */
-			rt2860_int_disable(pAd, FifoStaFullInt);
-			tasklet_hi_schedule(&pObj->fifo_statistic_full_task);
-		}
-		pAd->int_pending |= FifoStaFullInt;
-#else
-		NICUpdateFifoStaCounters(pAd);
-#endif
-	}
-
-	if (IntSource.word & INT_MGMT_DLY)
-	{
-		if ((pAd->int_disable_mask & INT_MGMT_DLY) ==0 )
-		{
-			rt2860_int_disable(pAd, INT_MGMT_DLY);
-			tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
-		}
-		pAd->int_pending |= INT_MGMT_DLY ;
-	}
-
-	if (IntSource.word & INT_RX)
-	{
-		if ((pAd->int_disable_mask & INT_RX) == 0)
-		{
-			/* mask RxINT */
-			rt2860_int_disable(pAd, INT_RX);
-			tasklet_hi_schedule(&pObj->rx_done_task);
-		}
-		pAd->int_pending |= INT_RX;
-	}
-
-	if (IntSource.word & INT_HCCA_DLY)
-	{
-
-		if ((pAd->int_disable_mask & INT_HCCA_DLY) == 0)
-		{
-			/* mask TxDataInt */
-			rt2860_int_disable(pAd, INT_HCCA_DLY);
-			tasklet_hi_schedule(&pObj->hcca_dma_done_task);
-		}
-		pAd->int_pending |= INT_HCCA_DLY;
-	}
-
-	if (IntSource.word & INT_AC3_DLY)
-	{
-
-		if ((pAd->int_disable_mask & INT_AC3_DLY) == 0)
-		{
-			/* mask TxDataInt */
-			rt2860_int_disable(pAd, INT_AC3_DLY);
-			tasklet_hi_schedule(&pObj->ac3_dma_done_task);
-		}
-		pAd->int_pending |= INT_AC3_DLY;
-	}
-
-	if (IntSource.word & INT_AC2_DLY)
-	{
-
-		if ((pAd->int_disable_mask & INT_AC2_DLY) == 0)
-		{
-			/* mask TxDataInt */
-			rt2860_int_disable(pAd, INT_AC2_DLY);
-			tasklet_hi_schedule(&pObj->ac2_dma_done_task);
-		}
-		pAd->int_pending |= INT_AC2_DLY;
-	}
-
-	if (IntSource.word & INT_AC1_DLY)
-	{
-
-		pAd->int_pending |= INT_AC1_DLY;
-
-		if ((pAd->int_disable_mask & INT_AC1_DLY) == 0)
-		{
-			/* mask TxDataInt */
-			rt2860_int_disable(pAd, INT_AC1_DLY);
-			tasklet_hi_schedule(&pObj->ac1_dma_done_task);
-		}
-
-	}
-
-	if (IntSource.word & INT_AC0_DLY)
-	{
-		pAd->int_pending |= INT_AC0_DLY;
-
-		if ((pAd->int_disable_mask & INT_AC0_DLY) == 0)
-		{
-			/* mask TxDataInt */
-			rt2860_int_disable(pAd, INT_AC0_DLY);
-			tasklet_hi_schedule(&pObj->ac0_dma_done_task);
-		}
-
-	}
-
-    if (IntSource.word & PreTBTTInt)
-	{
-		RTMPHandlePreTBTTInterrupt(pAd);
-	}
-
-	if (IntSource.word & TBTTInt)
-	{
-		RTMPHandleTBTTInterrupt(pAd);
-	}
-
-	if (IntSource.word & AutoWakeupInt)
-		RTMPHandleTwakeupInterrupt(pAd);
-
-    return  IRQ_HANDLED;
-}
-
-/*
-========================================================================
-Routine Description:
-    Check the chipset vendor/product ID.
-
-Arguments:
-    _dev_p				Point to the PCI or USB device
-
-Return Value:
-    TRUE				Check ok
-	FALSE				Check fail
-
-Note:
-========================================================================
-*/
-BOOLEAN RT28XXChipsetCheck(
-	IN void *_dev_p)
-{
-	/* always TRUE */
-	return TRUE;
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Init net device structure.
-
-Arguments:
-    _dev_p				Point to the PCI or USB device
-    *net_dev			Point to the net device
-	*pAd				the raxx interface data pointer
-
-Return Value:
-    TRUE				Init ok
-	FALSE				Init fail
-
-Note:
-========================================================================
-*/
-BOOLEAN RT28XXNetDevInit(
-	IN void 				*_dev_p,
-	IN struct  net_device	*net_dev,
-	IN RTMP_ADAPTER 		*pAd)
-{
-	struct pci_dev *pci_dev = (struct pci_dev *)_dev_p;
-    const CHAR	*print_name;
-    ULONG	csr_addr;
-
-
-	print_name = pci_dev ? pci_name(pci_dev) : "rt2860";
-
-	net_dev->base_addr = 0;
-	net_dev->irq = 0;
-
-    if (pci_request_regions(pci_dev, print_name))
-        goto err_out_free_netdev;
-
-    // interrupt IRQ number
-    net_dev->irq = pci_dev->irq;
-
-    // map physical address to virtual address for accessing register
-    csr_addr = (unsigned long) ioremap(pci_resource_start(pci_dev, 0),
-										pci_resource_len(pci_dev, 0));
-
-    if (!csr_addr)
-    {
-        DBGPRINT(RT_DEBUG_ERROR,
-				("ioremap failed for device %s, region 0x%lX @ 0x%lX\n",
-				print_name, (ULONG)pci_resource_len(pci_dev, 0),
-				(ULONG)pci_resource_start(pci_dev, 0)));
-        goto err_out_free_res;
-    }
-
-    // Save CSR virtual address and irq to device structure
-    net_dev->base_addr = csr_addr;
-    pAd->CSRBaseAddress = (PUCHAR)net_dev->base_addr;
-
-    // Set DMA master
-    pci_set_master(pci_dev);
-
-    net_dev->priv_flags = INT_MAIN;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("%s: at 0x%lx, VA 0x%lx, IRQ %d. \n",
-        	net_dev->name, (ULONG)pci_resource_start(pci_dev, 0),
-			(ULONG)csr_addr, pci_dev->irq));
-	return TRUE;
-
-
-	/* --------------------------- ERROR HANDLE --------------------------- */
-err_out_free_res:
-    pci_release_regions(pci_dev);
-err_out_free_netdev:
-	/* free netdev in caller, not here */
-	return FALSE;
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Init net device structure.
-
-Arguments:
-    _dev_p				Point to the PCI or USB device
-	*pAd				the raxx interface data pointer
-
-Return Value:
-    TRUE				Config ok
-	FALSE				Config fail
-
-Note:
-========================================================================
-*/
-BOOLEAN RT28XXProbePostConfig(
-	IN void 				*_dev_p,
-	IN RTMP_ADAPTER 		*pAd,
-	IN INT32				argc)
-{
-	/* no use */
-	return TRUE;
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Disable DMA.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-VOID RT28XXDMADisable(
-	IN RTMP_ADAPTER 		*pAd)
-{
-	WPDMA_GLO_CFG_STRUC     GloCfg;
-
-
-	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-	GloCfg.word &= 0xff0;
-	GloCfg.field.EnTXWriteBackDDONE =1;
-	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Enable DMA.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-VOID RT28XXDMAEnable(
-	IN RTMP_ADAPTER 		*pAd)
-{
-	WPDMA_GLO_CFG_STRUC	GloCfg;
-	int i = 0;
-
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
-	do
-	{
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-		if ((GloCfg.field.TxDMABusy == 0)  && (GloCfg.field.RxDMABusy == 0))
-			break;
-
-		DBGPRINT(RT_DEBUG_TRACE, ("==>  DMABusy\n"));
-		RTMPusecDelay(1000);
-		i++;
-	}while ( i <200);
-
-	RTMPusecDelay(50);
-
-	GloCfg.field.EnTXWriteBackDDONE = 1;
-	GloCfg.field.WPDMABurstSIZE = 2;
-	GloCfg.field.EnableRxDMA = 1;
-	GloCfg.field.EnableTxDMA = 1;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
-	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
-
-}
-
-/*
-========================================================================
-Routine Description:
-    Write Beacon buffer to Asic.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-VOID RT28xx_UpdateBeaconToAsic(
-	IN RTMP_ADAPTER		*pAd,
-	IN INT				apidx,
-	IN ULONG			FrameLen,
-	IN ULONG			UpdatePos)
-{
-	ULONG				CapInfoPos = 0;
-	UCHAR  			*ptr, *ptr_update, *ptr_capinfo;
-	UINT  			i;
-	BOOLEAN			bBcnReq = FALSE;
-	UCHAR			bcn_idx = 0;
-
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s() : No valid Interface be found.\n", __func__));
-		return;
-	}
-
-	if (bBcnReq == FALSE)
-	{
-		/* when the ra interface is down, do not send its beacon frame */
-		/* clear all zero */
-		for(i=0; i<TXWI_SIZE; i+=4)
-			RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, 0x00);
-	}
-	else
-	{
-		ptr = (PUCHAR)&pAd->BeaconTxWI;
-
-		for (i=0; i<TXWI_SIZE; i+=4)  // 16-byte TXWI field
-		{
-			UINT32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
-			RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longptr);
-			ptr += 4;
-		}
-
-		// Update CapabilityInfo in Beacon
-		for (i = CapInfoPos; i < (CapInfoPos+2); i++)
-		{
-			RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, *ptr_capinfo);
-			ptr_capinfo ++;
-		}
-
-		if (FrameLen > UpdatePos)
-		{
-			for (i= UpdatePos; i< (FrameLen); i++)
-			{
-				RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, *ptr_update);
-				ptr_update ++;
-			}
-		}
-
-	}
-
-}
-
-VOID RTMPInitPCIeLinkCtrlValue(
-	IN	PRTMP_ADAPTER	pAd)
-{
-}
-
-VOID RTMPFindHostPCIDev(
-    IN	PRTMP_ADAPTER	pAd)
-{
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-		Level = RESTORE_HALT : Restore PCI host and Ralink PCIe Link Control field to its default value.
-		Level = Other Value : Restore from dot11 power save or radio off status. And force PCI host Link Control fields to 0x1
-
-	========================================================================
-*/
-VOID RTMPPCIeLinkCtrlValueRestore(
-	IN	PRTMP_ADAPTER	pAd,
-	IN   UCHAR		Level)
-{
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-		Max : limit Host PCI and Ralink PCIe device's LINK CONTROL field's value.
-		Because now frequently set our device to mode 1 or mode 3 will cause problem.
-
-	========================================================================
-*/
-VOID RTMPPCIeLinkCtrlSetting(
-	IN	PRTMP_ADAPTER	pAd,
-	IN 	USHORT		Max)
-{
-}
-
-VOID rt2860_stop(struct net_device *net_dev)
-{
-    PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL;
-    if (net_dev == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n"));
-	}
-	else
-		pAd = net_dev->ml_priv;
-
-	if (pAd != NULL)
-	{
-	    // stop interface
-		netif_carrier_off(net_dev);
-		netif_stop_queue(net_dev);
-
-		// mark device as removed from system and therefore no longer available
-		netif_device_detach(net_dev);
-
-		// mark halt flag
-		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-		// take down the device
-		rt28xx_close((PNET_DEV)net_dev);
-		RT_MOD_DEC_USE_COUNT();
-	}
-    return;
-}
-
-/*
- * invaild or writeback cache
- * and convert virtual address to physical address
- */
-dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, int sd_idx, int direction)
-{
-	PRTMP_ADAPTER pAd;
-	POS_COOKIE pObj;
-
-	/*
-		------ Porting Information ------
-		> For Tx Alloc:
-			mgmt packets => sd_idx = 0
-			SwIdx: pAd->MgmtRing.TxCpuIdx
-			pTxD : pAd->MgmtRing.Cell[SwIdx].AllocVa;
-
-			data packets => sd_idx = 1
-	 		TxIdx : pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx
-	 		QueIdx: pTxBlk->QueIdx
-	 		pTxD  : pAd->TxRing[pTxBlk->QueIdx].Cell[TxIdx].AllocVa;
-
-	 	> For Rx Alloc:
-	 		sd_idx = -1
-	*/
-
-	pAd = (PRTMP_ADAPTER)handle;
-	pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	if (sd_idx == 1)
-	{
-		PTX_BLK		pTxBlk;
-		pTxBlk = (PTX_BLK)ptr;
-		return pci_map_single(pObj->pci_dev, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, direction);
-	}
-	else
-	{
-		return pci_map_single(pObj->pci_dev, ptr, size, direction);
-	}
-
-}
-
-void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, int direction)
-{
-	PRTMP_ADAPTER pAd;
-	POS_COOKIE pObj;
-
-	pAd=(PRTMP_ADAPTER)handle;
-	pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	pci_unmap_single(pObj->pci_dev, dma_addr, size, direction);
-
-}
-
diff --git a/drivers/staging/rt2860/Kconfig b/drivers/staging/rt2860/Kconfig
index efe38e2..f9962b6 100644
--- a/drivers/staging/rt2860/Kconfig
+++ b/drivers/staging/rt2860/Kconfig
@@ -1,5 +1,8 @@
 config RT2860
-	tristate "Ralink 2860 wireless support"
+	tristate "Ralink 2860/3090 wireless support"
 	depends on PCI && X86 && WLAN
+	select WIRELESS_EXT
+	select WEXT_PRIV
 	---help---
-	  This is an experimental driver for the Ralink 2860 wireless chip.
+	  This is an experimental driver for the Ralink 2860 and 3090
+	  wireless chips.
diff --git a/drivers/staging/rt2860/Makefile b/drivers/staging/rt2860/Makefile
index c9fe925..23ae07f 100644
--- a/drivers/staging/rt2860/Makefile
+++ b/drivers/staging/rt2860/Makefile
@@ -2,26 +2,33 @@
 
 # TODO: all of these should be removed
 EXTRA_CFLAGS += -DLINUX -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT
-EXTRA_CFLAGS += -DRT2860
+EXTRA_CFLAGS += -DRTMP_MAC_PCI -DRTMP_PCI_SUPPORT -DRT2860
+EXTRA_CFLAGS += -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DRT30xx -DRT3090
 EXTRA_CFLAGS += -DDBG
 
 rt2860sta-objs :=	\
-	common/md5.o		\
+	common/crypt_md5.o	\
+	common/crypt_sha2.o	\
+	common/crypt_hmac.o	\
 	common/mlme.o		\
-	common/rtmp_wep.o	\
+	common/cmm_wep.o	\
 	common/action.o		\
 	common/cmm_data.o	\
 	common/rtmp_init.o	\
-	common/rtmp_tkip.o	\
+	common/cmm_tkip.o	\
+	common/cmm_aes.o	\
 	common/cmm_sync.o	\
 	common/eeprom.o		\
 	common/cmm_sanity.o	\
 	common/cmm_info.o	\
+	common/cmm_cfg.o	\
 	common/cmm_wpa.o	\
 	common/dfs.o		\
 	common/spectrum.o	\
+	common/rtmp_timer.o	\
+	common/rt_channel.o	\
+	common/cmm_asic.o	\
 	sta/assoc.o		\
-	sta/aironet.o		\
 	sta/auth.o		\
 	sta/auth_rsp.o		\
 	sta/sync.o		\
@@ -30,10 +37,16 @@
 	sta/connect.o		\
 	sta/wpa.o		\
 	rt_linux.o		\
-	rt_profile.o		\
 	rt_main_dev.o		\
 	sta_ioctl.o		\
 	common/ba_action.o	\
-	common/2860_rtmp_init.o	\
-	2860_main_dev.o		\
-	common/cmm_data_2860.o
+	pci_main_dev.o		\
+	rt_pci_rbus.o		\
+	common/cmm_mac_pci.o	\
+	common/cmm_data_pci.o	\
+	common/ee_prom.o	\
+	common/rtmp_mcu.o	\
+	common/ee_efuse.o	\
+	chips/rt30xx.o		\
+	common/rt_rf.o		\
+	chips/rt3090.o
diff --git a/drivers/staging/rt2860/TODO b/drivers/staging/rt2860/TODO
index 6158dc2..8e2f6ee 100644
--- a/drivers/staging/rt2860/TODO
+++ b/drivers/staging/rt2860/TODO
@@ -9,7 +9,6 @@
 	- checkpatch.pl clean
 	- sparse clean
 	- port to in-kernel 80211 stack and common rt2x00 infrastructure
-	- remove reading from /etc/ config files
 	- review by the wireless developer community
 
 Please send any patches or complaints about this driver to Greg
diff --git a/drivers/staging/rt2860/aironet.h b/drivers/staging/rt2860/aironet.h
deleted file mode 100644
index 1e07b19..0000000
--- a/drivers/staging/rt2860/aironet.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	aironet.h
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Name		Date			Modification logs
-	Paul Lin	04-06-15		Initial
-*/
-
-#ifndef	__AIRONET_H__
-#define	__AIRONET_H__
-
-// Measurement Type definition
-#define	MSRN_TYPE_UNUSED				0
-#define	MSRN_TYPE_CHANNEL_LOAD_REQ		1
-#define	MSRN_TYPE_NOISE_HIST_REQ		2
-#define	MSRN_TYPE_BEACON_REQ			3
-#define	MSRN_TYPE_FRAME_REQ				4
-
-// Scan Mode in Beacon Request
-#define	MSRN_SCAN_MODE_PASSIVE			0
-#define	MSRN_SCAN_MODE_ACTIVE			1
-#define	MSRN_SCAN_MODE_BEACON_TABLE		2
-
-// PHY type definition for Aironet beacon report, CCX 2 table 36-9
-#define	PHY_FH							1
-#define	PHY_DSS							2
-#define	PHY_UNUSED						3
-#define	PHY_OFDM						4
-#define	PHY_HR_DSS						5
-#define	PHY_ERP							6
-
-// RPI table in dBm
-#define	RPI_0			0			//	Power <= -87
-#define	RPI_1			1			//	-87 < Power <= -82
-#define	RPI_2			2			//	-82 < Power <= -77
-#define	RPI_3			3			//	-77 < Power <= -72
-#define	RPI_4			4			//	-72 < Power <= -67
-#define	RPI_5			5			//	-67 < Power <= -62
-#define	RPI_6			6			//	-62 < Power <= -57
-#define	RPI_7			7			//	-57 < Power
-
-// Cisco Aironet IAPP definetions
-#define	AIRONET_IAPP_TYPE					0x32
-#define	AIRONET_IAPP_SUBTYPE_REQUEST		0x01
-#define	AIRONET_IAPP_SUBTYPE_REPORT			0x81
-
-// Measurement Request detail format
-typedef	struct	_MEASUREMENT_REQUEST	{
-	UCHAR	Channel;
-	UCHAR	ScanMode;			// Use only in beacon request, other requests did not use this field
-	USHORT	Duration;
-}	MEASUREMENT_REQUEST, *PMEASUREMENT_REQUEST;
-
-// Beacon Measurement Report
-// All these field might change to UCHAR, because we didn't do anything to these report.
-// We copy all these beacons and report to CCX 2 AP.
-typedef	struct	_BEACON_REPORT	{
-	UCHAR	Channel;
-	UCHAR	Spare;
-	USHORT	Duration;
-	UCHAR	PhyType;			// Definiation is listed above table 36-9
-	UCHAR	RxPower;
-	UCHAR	BSSID[6];
-	UCHAR	ParentTSF[4];
-	UCHAR	TargetTSF[8];
-	USHORT	BeaconInterval;
-	USHORT	CapabilityInfo;
-}	BEACON_REPORT, *PBEACON_REPORT;
-
-// Frame Measurement Report (Optional)
-typedef	struct	_FRAME_REPORT	{
-	UCHAR	Channel;
-	UCHAR	Spare;
-	USHORT	Duration;
-	UCHAR	TA;
-	UCHAR	BSSID[6];
-	UCHAR	RSSI;
-	UCHAR	Count;
-}	FRAME_REPORT, *PFRAME_REPORT;
-
-#pragma pack(1)
-// Channel Load Report
-typedef	struct	_CHANNEL_LOAD_REPORT	{
-	UCHAR	Channel;
-	UCHAR	Spare;
-	USHORT	Duration;
-	UCHAR	CCABusy;
-}	CHANNEL_LOAD_REPORT, *PCHANNEL_LOAD_REPORT;
-#pragma pack()
-
-// Nosie Histogram Report
-typedef	struct	_NOISE_HIST_REPORT	{
-	UCHAR	Channel;
-	UCHAR	Spare;
-	USHORT	Duration;
-	UCHAR	Density[8];
-}	NOISE_HIST_REPORT, *PNOISE_HIST_REPORT;
-
-// Radio Management Capability element
-typedef	struct	_RADIO_MANAGEMENT_CAPABILITY	{
-	UCHAR	Eid;				// TODO: Why the Eid is 1 byte, not normal 2 bytes???
-	UCHAR	Length;
-	UCHAR	AironetOui[3];		// AIronet OUI (00 40 96)
-	UCHAR	Type;				// Type / Version
-	USHORT	Status;				// swap16 required
-}	RADIO_MANAGEMENT_CAPABILITY, *PRADIO_MANAGEMENT_CAPABILITY;
-
-// Measurement Mode Bit definition
-typedef	struct	_MEASUREMENT_MODE	{
-	UCHAR	Rsvd:4;
-	UCHAR	Report:1;
-	UCHAR	NotUsed:1;
-	UCHAR	Enable:1;
-	UCHAR	Parallel:1;
-}	MEASUREMENT_MODE, *PMEASUREMENT_MODE;
-
-// Measurement Request element, This is little endian mode
-typedef	struct	_MEASUREMENT_REQUEST_ELEMENT	{
-	USHORT				Eid;
-	USHORT				Length;				// swap16 required
-	USHORT				Token;				// non-zero unique token
-	UCHAR				Mode;				// Measurement Mode
-	UCHAR				Type;				// Measurement type
-}	MEASUREMENT_REQUEST_ELEMENT, *PMEASUREMENT_REQUEST_ELEMENT;
-
-// Measurement Report element, This is little endian mode
-typedef	struct	_MEASUREMENT_REPORT_ELEMENT	{
-	USHORT				Eid;
-	USHORT				Length;				// swap16 required
-	USHORT				Token;				// non-zero unique token
-	UCHAR				Mode;				// Measurement Mode
-	UCHAR				Type;				// Measurement type
-}	MEASUREMENT_REPORT_ELEMENT, *PMEASUREMENT_REPORT_ELEMENT;
-
-// Cisco Aironet IAPP Frame Header, Network byte order used
-typedef	struct	_AIRONET_IAPP_HEADER {
-	UCHAR	CiscoSnapHeader[8];	// 8 bytes Cisco snap header
-	USHORT	Length;				// IAPP ID & length, remember to swap16 in LE system
-	UCHAR	Type;				// IAPP type
-	UCHAR	SubType;			// IAPP subtype
-	UCHAR	DA[6];				// Destination MAC address
-	UCHAR	SA[6];				// Source MAC address
-	USHORT	Token;				// Dialog token, no need to swap16 since it is for yoken usage only
-}	AIRONET_IAPP_HEADER, *PAIRONET_IAPP_HEADER;
-
-// Radio Measurement Request frame
-typedef	struct	_AIRONET_RM_REQUEST_FRAME	{
-    AIRONET_IAPP_HEADER	IAPP;			// Common header
-	UCHAR				Delay;			// Activation Delay
-	UCHAR				Offset;			// Measurement offset
-}	AIRONET_RM_REQUEST_FRAME, *PAIRONET_RM_REQUEST_FRAME;
-
-// Radio Measurement Report frame
-typedef	struct	_AIRONET_RM_REPORT_FRAME	{
-    AIRONET_IAPP_HEADER	IAPP;			// Common header
-}	AIRONET_RM_REPORT_FRAME, *PAIRONET_RM_REPORT_FRAME;
-
-// Saved element request actions which will saved in StaCfg.
-typedef	struct	_RM_REQUEST_ACTION	{
-	MEASUREMENT_REQUEST_ELEMENT	ReqElem;		// Saved request element
-	MEASUREMENT_REQUEST			Measurement;	// Saved measurement within the request element
-}	RM_REQUEST_ACTION, *PRM_REQUEST_ACTION;
-
-// CCX administration control
-typedef	union	_CCX_CONTROL	{
-	struct	{
-		UINT32		Enable:1;			// Enable CCX2
-		UINT32		LeapEnable:1;		// Enable LEAP at CCX2
-		UINT32		RMEnable:1;			// Radio Measurement Enable
-		UINT32		DCRMEnable:1;		// Non serving channel Radio Measurement enable
-		UINT32		QOSEnable:1;		// Enable QOS for CCX 2.0 support
-		UINT32		FastRoamEnable:1;	// Enable fast roaming
-		UINT32		Rsvd:2;				// Not used
-		UINT32		dBmToRoam:8;		// the condition to roam when receiving Rssi less than this value. It's negative value.
-		UINT32		TuLimit:16;			// Limit for different channel scan
-	}	field;
-	UINT32			word;
-}	CCX_CONTROL, *PCCX_CONTROL;
-
-#endif	// __AIRONET_H__
diff --git a/drivers/staging/rt2860/ap.h b/drivers/staging/rt2860/ap.h
index fcdb358..3f744a5 100644
--- a/drivers/staging/rt2860/ap.h
+++ b/drivers/staging/rt2860/ap.h
@@ -40,39 +40,27 @@
 #ifndef __AP_H__
 #define __AP_H__
 
-// ap_mlme.c
+/* ap_wpa.c */
+void WpaStateMachineInit(struct rt_rtmp_adapter *pAd,
+			 struct rt_state_machine *Sm, OUT STATE_MACHINE_FUNC Trans[]);
 
-#ifdef RT2870
-VOID BeaconUpdateExec(
-    IN PVOID SystemSpecific1,
-    IN PVOID FunctionContext,
-    IN PVOID SystemSpecific2,
-    IN PVOID SystemSpecific3);
-#endif // RT2870 //
+#ifdef RTMP_MAC_USB
+void BeaconUpdateExec(void *SystemSpecific1,
+		      void *FunctionContext,
+		      void *SystemSpecific2, void *SystemSpecific3);
+#endif /* RTMP_MAC_USB // */
 
-VOID RTMPSetPiggyBack(
-	IN PRTMP_ADAPTER	pAd,
-	IN BOOLEAN			bPiggyBack);
+void RTMPSetPiggyBack(struct rt_rtmp_adapter *pAd, IN BOOLEAN bPiggyBack);
 
-// ap.c
+void MacTableReset(struct rt_rtmp_adapter *pAd);
 
-VOID MacTableReset(
-    IN  PRTMP_ADAPTER   pAd);
+struct rt_mac_table_entry *MacTableInsertEntry(struct rt_rtmp_adapter *pAd,
+				     u8 *pAddr,
+				     u8 apidx, IN BOOLEAN CleanAll);
 
-MAC_TABLE_ENTRY *MacTableInsertEntry(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PUCHAR          pAddr,
-	IN	UCHAR			apidx,
-	IN BOOLEAN	CleanAll);
+BOOLEAN MacTableDeleteEntry(struct rt_rtmp_adapter *pAd,
+			    u16 wcid, u8 *pAddr);
 
-BOOLEAN MacTableDeleteEntry(
-    IN  PRTMP_ADAPTER   pAd,
-	IN USHORT wcid,
-    IN  PUCHAR          pAddr);
+struct rt_mac_table_entry *MacTableLookup(struct rt_rtmp_adapter *pAd, u8 *pAddr);
 
-MAC_TABLE_ENTRY *MacTableLookup(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PUCHAR          pAddr);
-
-#endif  // __AP_H__
-
+#endif /* __AP_H__ */
diff --git a/drivers/staging/rt2860/chip/mac_pci.h b/drivers/staging/rt2860/chip/mac_pci.h
new file mode 100644
index 0000000..bc704ac
--- /dev/null
+++ b/drivers/staging/rt2860/chip/mac_pci.h
@@ -0,0 +1,355 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+	mac_pci.h
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#ifndef __MAC_PCI_H__
+#define __MAC_PCI_H__
+
+#include "../rtmp_type.h"
+#include "rtmp_mac.h"
+#include "rtmp_phy.h"
+#include "../rtmp_iface.h"
+#include "../rtmp_dot11.h"
+
+/* */
+/* Device ID & Vendor ID related definitions, */
+/* NOTE: you should not add the new VendorID/DeviceID here unless you not sure it belongs to what chip. */
+/* */
+#define NIC_PCI_VENDOR_ID		0x1814
+#define PCIBUS_INTEL_VENDOR	0x8086
+
+#if !defined(PCI_CAP_ID_EXP)
+#define PCI_CAP_ID_EXP			    0x10
+#endif
+#if !defined(PCI_EXP_LNKCTL)
+#define PCI_EXP_LNKCTL			    0x10
+#endif
+#if !defined(PCI_CLASS_BRIDGE_PCI)
+#define PCI_CLASS_BRIDGE_PCI		0x0604
+#endif
+
+#define TXINFO_SIZE						0
+#define RTMP_PKT_TAIL_PADDING			0
+#define fRTMP_ADAPTER_NEED_STOP_TX	0
+
+#define AUX_CTRL           0x10c
+
+/* */
+/* TX descriptor format, Tx     ring, Mgmt Ring */
+/* */
+struct PACKED rt_txd {
+	/* Word 0 */
+	u32 SDPtr0;
+	/* Word 1 */
+	u32 SDLen1:14;
+	u32 LastSec1:1;
+	u32 Burst:1;
+	u32 SDLen0:14;
+	u32 LastSec0:1;
+	u32 DMADONE:1;
+	/*Word2 */
+	u32 SDPtr1;
+	/*Word3 */
+	u32 rsv2:24;
+	u32 WIV:1;		/* Wireless Info Valid. 1 if Driver already fill WI,  o if DMA needs to copy WI to correctposition */
+	u32 QSEL:2;		/* select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA */
+	u32 rsv:2;
+	u32 TCO:1;		/* */
+	u32 UCO:1;		/* */
+	u32 ICO:1;		/* */
+};
+
+/* */
+/* Rx descriptor format, Rx Ring */
+/* */
+typedef struct PACKED rt_rxd {
+	/* Word 0 */
+	u32 SDP0;
+	/* Word 1 */
+	u32 SDL1:14;
+	u32 Rsv:2;
+	u32 SDL0:14;
+	u32 LS0:1;
+	u32 DDONE:1;
+	/* Word 2 */
+	u32 SDP1;
+	/* Word 3 */
+	u32 BA:1;
+	u32 DATA:1;
+	u32 NULLDATA:1;
+	u32 FRAG:1;
+	u32 U2M:1;		/* 1: this RX frame is unicast to me */
+	u32 Mcast:1;		/* 1: this is a multicast frame */
+	u32 Bcast:1;		/* 1: this is a broadcast frame */
+	u32 MyBss:1;		/* 1: this frame belongs to the same BSSID */
+	u32 Crc:1;		/* 1: CRC error */
+	u32 CipherErr:2;	/* 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid */
+	u32 AMSDU:1;		/* rx with 802.3 header, not 802.11 header. */
+	u32 HTC:1;
+	u32 RSSI:1;
+	u32 L2PAD:1;
+	u32 AMPDU:1;
+	u32 Decrypted:1;	/* this frame is being decrypted. */
+	u32 PlcpSignal:1;	/* To be moved */
+	u32 PlcpRssil:1;	/* To be moved */
+	u32 Rsv1:13;
+} RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
+
+typedef union _TX_ATTENUATION_CTRL_STRUC {
+	struct {
+		unsigned long RF_ISOLATION_ENABLE:1;
+		unsigned long Reserve2:7;
+		unsigned long PCIE_PHY_TX_ATTEN_VALUE:3;
+		unsigned long PCIE_PHY_TX_ATTEN_EN:1;
+		unsigned long Reserve1:20;
+	} field;
+
+	unsigned long word;
+} TX_ATTENUATION_CTRL_STRUC, *PTX_ATTENUATION_CTRL_STRUC;
+
+/* ----------------- EEPROM Related MACRO ----------------- */
+
+/* 8051 firmware image for RT2860 - base address = 0x4000 */
+#define FIRMWARE_IMAGE_BASE     0x2000
+#define MAX_FIRMWARE_IMAGE_SIZE 0x2000	/* 8kbyte */
+
+/* ----------------- Frimware Related MACRO ----------------- */
+#define RTMP_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen)			\
+	do{								\
+		unsigned long	_i, _firm;					\
+		RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x10000);		\
+									\
+		for(_i=0; _i<_FwLen; _i+=4)				\
+		{							\
+			_firm = _pFwImage[_i] +				\
+			   (_pFwImage[_i+3] << 24) +			\
+			   (_pFwImage[_i+2] << 16) +			\
+			   (_pFwImage[_i+1] << 8);			\
+			RTMP_IO_WRITE32(_pAd, FIRMWARE_IMAGE_BASE + _i, _firm);	\
+		}							\
+		RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x00000);		\
+		RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x00001);		\
+									\
+		/* initialize BBP R/W access agent */			\
+		RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, 0);		\
+		RTMP_IO_WRITE32(_pAd, H2M_MAILBOX_CSR, 0);		\
+	}while(0)
+
+/* ----------------- TX Related MACRO ----------------- */
+#define RTMP_START_DEQUEUE(pAd, QueIdx, irqFlags)		do{}while(0)
+#define RTMP_STOP_DEQUEUE(pAd, QueIdx, irqFlags)		do{}while(0)
+
+#define RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \
+		((freeNum) >= (unsigned long)(pTxBlk->TotalFragNum + RTMP_GET_PACKET_FRAGMENTS(pPacket) + 3))	/* rough estimate we will use 3 more descriptor. */
+#define RTMP_RELEASE_DESC_RESOURCE(pAd, QueIdx)	\
+		do{}while(0)
+
+#define NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, freeNum, _TxFrameType) \
+		(((freeNum != (TX_RING_SIZE-1)) && (pAd->TxSwQueue[QueIdx].Number == 0)) || (freeNum<3))
+
+#define HAL_KickOutMgmtTx(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen)	\
+			RtmpPCIMgmtKickOut(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen)
+
+#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)	\
+				/* RtmpPCI_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) */
+
+#define HAL_WriteTxResource(pAd, pTxBlk,bIsLast, pFreeNumber)	\
+			RtmpPCI_WriteSingleTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)
+
+#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \
+			RtmpPCI_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber)
+
+#define HAL_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber)	\
+			RtmpPCI_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber)
+
+#define HAL_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx)	\
+			RtmpPCI_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx)
+
+#define HAL_LastTxIdx(_pAd, _QueIdx,_LastTxIdx) \
+				/*RtmpPCIDataLastTxIdx(_pAd, _QueIdx,_LastTxIdx) */
+
+#define HAL_KickOutTx(_pAd, _pTxBlk, _QueIdx)	\
+			RTMP_IO_WRITE32((_pAd), TX_CTX_IDX0+((_QueIdx)*0x10), (_pAd)->TxRing[(_QueIdx)].TxCpuIdx)
+/*			RtmpPCIDataKickOut(_pAd, _pTxBlk, _QueIdx)*/
+
+#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen)	\
+			MiniportMMRequest(_pAd, _QueIdx, _pNullFrame, _frameLen)
+
+#define GET_TXRING_FREENO(_pAd, _QueIdx) \
+	(_pAd->TxRing[_QueIdx].TxSwFreeIdx > _pAd->TxRing[_QueIdx].TxCpuIdx)	? \
+			(_pAd->TxRing[_QueIdx].TxSwFreeIdx - _pAd->TxRing[_QueIdx].TxCpuIdx - 1) \
+			 :	\
+			(_pAd->TxRing[_QueIdx].TxSwFreeIdx + TX_RING_SIZE - _pAd->TxRing[_QueIdx].TxCpuIdx - 1);
+
+#define GET_MGMTRING_FREENO(_pAd) \
+	(_pAd->MgmtRing.TxSwFreeIdx > _pAd->MgmtRing.TxCpuIdx)	? \
+			(_pAd->MgmtRing.TxSwFreeIdx - _pAd->MgmtRing.TxCpuIdx - 1) \
+			 :	\
+			(_pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE - _pAd->MgmtRing.TxCpuIdx - 1);
+
+/* ----------------- RX Related MACRO ----------------- */
+
+/* ----------------- ASIC Related MACRO ----------------- */
+/* reset MAC of a station entry to 0x000000000000 */
+#define RTMP_STA_ENTRY_MAC_RESET(pAd, Wcid)	\
+	AsicDelWcidTab(pAd, Wcid);
+
+/* add this entry into ASIC RX WCID search table */
+#define RTMP_STA_ENTRY_ADD(pAd, pEntry)		\
+	AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr);
+
+/* add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet */
+/* Set MAC register value according operation mode */
+#define RTMP_UPDATE_PROTECT(pAd)	\
+	AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0);
+/* end johnli */
+
+/* remove Pair-wise key material from ASIC */
+#define RTMP_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid)	\
+	AsicRemovePairwiseKeyEntry(pAd, BssIdx, (u8)Wcid);
+
+/* add Client security information into ASIC WCID table and IVEIV table */
+#define RTMP_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry)		\
+	RTMPAddWcidAttributeEntry(pAd, apidx, KeyID,			\
+							pAd->SharedKey[apidx][KeyID].CipherAlg, pEntry);
+
+#define RTMP_SECURITY_KEY_ADD(pAd, apidx, KeyID, pEntry)		\
+	{	/* update pairwise key information to ASIC Shared Key Table */	\
+		AsicAddSharedKeyEntry(pAd, apidx, KeyID,					\
+						  pAd->SharedKey[apidx][KeyID].CipherAlg,		\
+						  pAd->SharedKey[apidx][KeyID].Key,				\
+						  pAd->SharedKey[apidx][KeyID].TxMic,			\
+						  pAd->SharedKey[apidx][KeyID].RxMic);			\
+		/* update ASIC WCID attribute table and IVEIV table */			\
+		RTMPAddWcidAttributeEntry(pAd, apidx, KeyID,					\
+						  pAd->SharedKey[apidx][KeyID].CipherAlg,		\
+						  pEntry); }
+
+/* Insert the BA bitmap to ASIC for the Wcid entry */
+#define RTMP_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID)	\
+		do{					\
+			u32 _Value = 0, _Offset;					\
+			_Offset = MAC_WCID_BASE + (_Aid) * HW_WCID_ENTRY_SIZE + 4;	\
+			RTMP_IO_READ32((_pAd), _Offset, &_Value);\
+			_Value |= (0x10000<<(_TID));	\
+			RTMP_IO_WRITE32((_pAd), _Offset, _Value);\
+		}while(0)
+
+/* Remove the BA bitmap from ASIC for the Wcid entry */
+/*              bitmap field starts at 0x10000 in ASIC WCID table */
+#define RTMP_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID)				\
+		do{								\
+			u32 _Value = 0, _Offset;				\
+			_Offset = MAC_WCID_BASE + (_Wcid) * HW_WCID_ENTRY_SIZE + 4;	\
+			RTMP_IO_READ32((_pAd), _Offset, &_Value);			\
+			_Value &= (~(0x10000 << (_TID)));				\
+			RTMP_IO_WRITE32((_pAd), _Offset, _Value);			\
+		}while(0)
+
+/* ----------------- Interface Related MACRO ----------------- */
+
+/* */
+/* Enable & Disable NIC interrupt via writing interrupt mask register */
+/* Since it use ADAPTER structure, it have to be put after structure definition. */
+/* */
+#define RTMP_ASIC_INTERRUPT_DISABLE(_pAd)		\
+	do{			\
+		RTMP_IO_WRITE32((_pAd), INT_MASK_CSR, 0x0);     /* 0: disable */	\
+		RTMP_CLEAR_FLAG((_pAd), fRTMP_ADAPTER_INTERRUPT_ACTIVE);		\
+	}while(0)
+
+#define RTMP_ASIC_INTERRUPT_ENABLE(_pAd)\
+	do{				\
+		RTMP_IO_WRITE32((_pAd), INT_MASK_CSR, (_pAd)->int_enable_reg /*DELAYINTMASK*/);     /* 1:enable */	\
+		RTMP_SET_FLAG((_pAd), fRTMP_ADAPTER_INTERRUPT_ACTIVE);	\
+	}while(0)
+
+#define RTMP_IRQ_INIT(pAd)	\
+	{	pAd->int_enable_reg = ((DELAYINTMASK) |		\
+					(RxINT|TxDataInt|TxMgmtInt)) & ~(0x03);	\
+		pAd->int_disable_mask = 0;						\
+		pAd->int_pending = 0; }
+
+#define RTMP_IRQ_ENABLE(pAd)					\
+	{	/* clear garbage ints */			\
+		RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, 0xffffffff);\
+		RTMP_ASIC_INTERRUPT_ENABLE(pAd); }
+
+/* ----------------- MLME Related MACRO ----------------- */
+#define RTMP_MLME_HANDLER(pAd)			MlmeHandler(pAd)
+
+#define RTMP_MLME_PRE_SANITY_CHECK(pAd)
+
+#define RTMP_MLME_STA_QUICK_RSP_WAKE_UP(pAd)	\
+		RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
+
+#define RTMP_MLME_RESET_STATE_MACHINE(pAd)	\
+		MlmeRestartStateMachine(pAd)
+
+#define RTMP_HANDLE_COUNTER_MEASURE(_pAd, _pEntry)\
+		HandleCounterMeasure(_pAd, _pEntry)
+
+/* ----------------- Power Save Related MACRO ----------------- */
+#define RTMP_PS_POLL_ENQUEUE(pAd)				EnqueuePsPoll(pAd)
+
+/* For RTMPPCIePowerLinkCtrlRestore () function */
+#define RESTORE_HALT		1
+#define RESTORE_WAKEUP		2
+#define RESTORE_CLOSE           3
+
+#define PowerSafeCID		1
+#define PowerRadioOffCID	2
+#define PowerWakeCID		3
+#define CID0MASK		0x000000ff
+#define CID1MASK		0x0000ff00
+#define CID2MASK		0x00ff0000
+#define CID3MASK		0xff000000
+
+#define RTMP_STA_FORCE_WAKEUP(pAd, bFromTx) \
+    RT28xxPciStaAsicForceWakeup(pAd, bFromTx);
+
+#define RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \
+    RT28xxPciStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
+
+#define RTMP_SET_PSM_BIT(_pAd, _val) \
+	MlmeSetPsmBit(_pAd, _val);
+
+#define RTMP_MLME_RADIO_ON(pAd) \
+    RT28xxPciMlmeRadioOn(pAd);
+
+#define RTMP_MLME_RADIO_OFF(pAd) \
+    RT28xxPciMlmeRadioOFF(pAd);
+
+#endif /*__MAC_PCI_H__ // */
diff --git a/drivers/staging/rt2860/chip/mac_usb.h b/drivers/staging/rt2860/chip/mac_usb.h
new file mode 100644
index 0000000..0b67c0b
--- /dev/null
+++ b/drivers/staging/rt2860/chip/mac_usb.h
@@ -0,0 +1,347 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+        mac_usb.h
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#ifndef __MAC_USB_H__
+#define __MAC_USB_H__
+
+#include "../rtmp_type.h"
+#include "rtmp_mac.h"
+#include "rtmp_phy.h"
+#include "../rtmp_iface.h"
+#include "../rtmp_dot11.h"
+
+#define USB_CYC_CFG				0x02a4
+
+#define BEACON_RING_SIZE		2
+#define MGMTPIPEIDX				0	/* EP6 is highest priority */
+
+#define RTMP_PKT_TAIL_PADDING	11	/* 3(max 4 byte padding) + 4 (last packet padding) + 4 (MaxBulkOutsize align padding) */
+
+#define fRTMP_ADAPTER_NEED_STOP_TX		\
+		(fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS |	\
+		 fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_BULKOUT_RESET | \
+		 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
+
+/* */
+/* RXINFO appends at the end of each rx packet. */
+/* */
+#define RXINFO_SIZE				4
+#define RT2870_RXDMALEN_FIELD_SIZE	4
+
+typedef struct PACKED rt_rxinfo {
+	u32 BA:1;
+	u32 DATA:1;
+	u32 NULLDATA:1;
+	u32 FRAG:1;
+	u32 U2M:1;		/* 1: this RX frame is unicast to me */
+	u32 Mcast:1;		/* 1: this is a multicast frame */
+	u32 Bcast:1;		/* 1: this is a broadcast frame */
+	u32 MyBss:1;		/* 1: this frame belongs to the same BSSID */
+	u32 Crc:1;		/* 1: CRC error */
+	u32 CipherErr:2;	/* 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid */
+	u32 AMSDU:1;		/* rx with 802.3 header, not 802.11 header. */
+	u32 HTC:1;
+	u32 RSSI:1;
+	u32 L2PAD:1;
+	u32 AMPDU:1;		/* To be moved */
+	u32 Decrypted:1;
+	u32 PlcpRssil:1;
+	u32 CipherAlg:1;
+	u32 LastAMSDU:1;
+	u32 PlcpSignal:12;
+} RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
+
+/* */
+/* TXINFO */
+/* */
+#define TXINFO_SIZE				4
+
+struct rt_txinfo {
+	/* Word 0 */
+	u32 USBDMATxPktLen:16;	/*used ONLY in USB bulk Aggregation,  Total byte counts of all sub-frame. */
+	u32 rsv:8;
+	u32 WIV:1;		/* Wireless Info Valid. 1 if Driver already fill WI,  o if DMA needs to copy WI to correctposition */
+	u32 QSEL:2;		/* select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA */
+	u32 SwUseLastRound:1;	/* Software use. */
+	u32 rsv2:2;		/* Software use. */
+	u32 USBDMANextVLD:1;	/*used ONLY in USB bulk Aggregation, NextValid */
+	u32 USBDMATxburst:1;	/*used ONLY in USB bulk Aggre. Force USB DMA transmit frame from current selected endpoint */
+};
+
+/* */
+/* Management ring buffer format */
+/* */
+struct rt_mgmt {
+	BOOLEAN Valid;
+	u8 *pBuffer;
+	unsigned long Length;
+};
+
+/*////////////////////////////////////////////////////////////////////////// */
+/* The struct rt_tx_buffer structure forms the transmitted USB packet to the device */
+/*////////////////////////////////////////////////////////////////////////// */
+struct rt_tx_buffer {
+	union {
+		u8 WirelessPacket[TX_BUFFER_NORMSIZE];
+		struct rt_header_802_11 NullFrame;
+		struct rt_pspoll_frame PsPollPacket;
+		struct rt_rts_frame RTSFrame;
+	} field;
+	u8 Aggregation[4];	/*Buffer for save Aggregation size. */
+};
+
+struct rt_httx_buffer {
+	union {
+		u8 WirelessPacket[MAX_TXBULK_SIZE];
+		struct rt_header_802_11 NullFrame;
+		struct rt_pspoll_frame PsPollPacket;
+		struct rt_rts_frame RTSFrame;
+	} field;
+	u8 Aggregation[4];	/*Buffer for save Aggregation size. */
+};
+
+/* used to track driver-generated write irps */
+struct rt_tx_context {
+	void *pAd;		/*Initialized in MiniportInitialize */
+	PURB pUrb;		/*Initialized in MiniportInitialize */
+	PIRP pIrp;		/*used to cancel pending bulk out. */
+	/*Initialized in MiniportInitialize */
+	struct rt_tx_buffer *TransferBuffer;	/*Initialized in MiniportInitialize */
+	unsigned long BulkOutSize;
+	u8 BulkOutPipeId;
+	u8 SelfIdx;
+	BOOLEAN InUse;
+	BOOLEAN bWaitingBulkOut;	/* at least one packet is in this TxContext, ready for making IRP anytime. */
+	BOOLEAN bFullForBulkOut;	/* all tx buffer are full , so waiting for tx bulkout. */
+	BOOLEAN IRPPending;
+	BOOLEAN LastOne;
+	BOOLEAN bAggregatible;
+	u8 Header_802_3[LENGTH_802_3];
+	u8 Rsv[2];
+	unsigned long DataOffset;
+	u32 TxRate;
+	dma_addr_t data_dma;	/* urb dma on linux */
+
+};
+
+/* used to track driver-generated write irps */
+struct rt_ht_tx_context {
+	void *pAd;		/*Initialized in MiniportInitialize */
+	PURB pUrb;		/*Initialized in MiniportInitialize */
+	PIRP pIrp;		/*used to cancel pending bulk out. */
+	/*Initialized in MiniportInitialize */
+	struct rt_httx_buffer *TransferBuffer;	/*Initialized in MiniportInitialize */
+	unsigned long BulkOutSize;	/* Indicate the total bulk-out size in bytes in one bulk-transmission */
+	u8 BulkOutPipeId;
+	BOOLEAN IRPPending;
+	BOOLEAN LastOne;
+	BOOLEAN bCurWriting;
+	BOOLEAN bRingEmpty;
+	BOOLEAN bCopySavePad;
+	u8 SavedPad[8];
+	u8 Header_802_3[LENGTH_802_3];
+	unsigned long CurWritePosition;	/* Indicate the buffer offset which packet will be inserted start from. */
+	unsigned long CurWriteRealPos;	/* Indicate the buffer offset which packet now are writing to. */
+	unsigned long NextBulkOutPosition;	/* Indicate the buffer start offset of a bulk-transmission */
+	unsigned long ENextBulkOutPosition;	/* Indicate the buffer end offset of a bulk-transmission */
+	u32 TxRate;
+	dma_addr_t data_dma;	/* urb dma on linux */
+};
+
+/* */
+/* Structure to keep track of receive packets and buffers to indicate */
+/* receive data to the protocol. */
+/* */
+struct rt_rx_context {
+	u8 *TransferBuffer;
+	void *pAd;
+	PIRP pIrp;		/*used to cancel pending bulk in. */
+	PURB pUrb;
+	/*These 2 Boolean shouldn't both be 1 at the same time. */
+	unsigned long BulkInOffset;	/* number of packets waiting for reordering . */
+/*      BOOLEAN                         ReorderInUse;   // At least one packet in this buffer are in reordering buffer and wait for receive indication */
+	BOOLEAN bRxHandling;	/* Notify this packet is being process now. */
+	BOOLEAN InUse;		/* USB Hardware Occupied. Wait for USB HW to put packet. */
+	BOOLEAN Readable;	/* Receive Complete back. OK for driver to indicate receiving packet. */
+	BOOLEAN IRPPending;	/* TODO: To be removed */
+	atomic_t IrpLock;
+	spinlock_t RxContextLock;
+	dma_addr_t data_dma;	/* urb dma on linux */
+};
+
+/******************************************************************************
+
+	USB Frimware Related MACRO
+
+******************************************************************************/
+/* 8051 firmware image for usb - use last-half base address = 0x3000 */
+#define FIRMWARE_IMAGE_BASE			0x3000
+#define MAX_FIRMWARE_IMAGE_SIZE		0x1000	/* 4kbyte */
+
+#define RTMP_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen)		\
+	RTUSBFirmwareWrite(_pAd, _pFwImage, _FwLen)
+
+/******************************************************************************
+
+	USB TX Related MACRO
+
+******************************************************************************/
+#define RTMP_START_DEQUEUE(pAd, QueIdx, irqFlags)				\
+			do{													\
+				RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags);		\
+				if (pAd->DeQueueRunning[QueIdx])						\
+				{														\
+					RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\
+					DBGPRINT(RT_DEBUG_OFF, ("DeQueueRunning[%d]= TRUE!\n", QueIdx));		\
+					continue;											\
+				}														\
+				else													\
+				{														\
+					pAd->DeQueueRunning[QueIdx] = TRUE;					\
+					RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\
+				}														\
+			}while(0)
+
+#define RTMP_STOP_DEQUEUE(pAd, QueIdx, irqFlags)						\
+			do{															\
+				RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags);		\
+				pAd->DeQueueRunning[QueIdx] = FALSE;					\
+				RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);	\
+			}while(0)
+
+#define	RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \
+		(RTUSBFreeDescriptorRequest(pAd, pTxBlk->QueIdx, (pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))) == NDIS_STATUS_SUCCESS)
+
+#define RTMP_RELEASE_DESC_RESOURCE(pAd, QueIdx)			\
+		do{}while(0)
+
+#define NEED_QUEUE_BACK_FOR_AGG(_pAd, _QueIdx, _freeNum, _TxFrameType)		\
+		((_TxFrameType == TX_RALINK_FRAME) && (RTUSBNeedQueueBackForAgg(_pAd, _QueIdx)))
+
+#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)	\
+			RtmpUSB_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)
+
+#define HAL_WriteTxResource(pAd, pTxBlk,bIsLast, pFreeNumber)	\
+			RtmpUSB_WriteSingleTxResource(pAd, pTxBlk,bIsLast, pFreeNumber)
+
+#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \
+			RtmpUSB_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber)
+
+#define HAL_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber)	\
+			RtmpUSB_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber)
+
+#define HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx)	\
+			RtmpUSB_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx)
+
+#define HAL_LastTxIdx(pAd, QueIdx,TxIdx) \
+				/*RtmpUSBDataLastTxIdx(pAd, QueIdx,TxIdx) */
+
+#define HAL_KickOutTx(pAd, pTxBlk, QueIdx)	\
+			RtmpUSBDataKickOut(pAd, pTxBlk, QueIdx)
+
+#define HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen)	\
+			RtmpUSBMgmtKickOut(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen)
+
+#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen)	\
+			RtmpUSBNullFrameKickOut(_pAd, _QueIdx, _pNullFrame, _frameLen)
+
+#define GET_TXRING_FREENO(_pAd, _QueIdx)	(_QueIdx)	/*(_pAd->TxRing[_QueIdx].TxSwFreeIdx) */
+#define GET_MGMTRING_FREENO(_pAd)			(_pAd->MgmtRing.TxSwFreeIdx)
+
+/* ----------------- RX Related MACRO ----------------- */
+
+/*
+  *	Device Hardware Interface Related MACRO
+  */
+#define RTMP_IRQ_INIT(pAd)				do{}while(0)
+#define RTMP_IRQ_ENABLE(pAd)			do{}while(0)
+
+/*
+  *	MLME Related MACRO
+  */
+#define RTMP_MLME_HANDLER(pAd)			RTUSBMlmeUp(pAd)
+
+#define RTMP_MLME_PRE_SANITY_CHECK(pAd)								\
+	{	if ((pAd->CommonCfg.bHardwareRadio == TRUE) &&					\
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&		\
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) {	\
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_CHECK_GPIO, NULL, 0); } }
+
+#define RTMP_MLME_STA_QUICK_RSP_WAKE_UP(pAd)	\
+	{	RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_QKERIODIC_EXECUT, NULL, 0);	\
+		RTUSBMlmeUp(pAd); }
+
+#define RTMP_MLME_RESET_STATE_MACHINE(pAd)	\
+		        MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_RESET_CONF, 0, NULL);	\
+		        RTUSBMlmeUp(pAd);
+
+#define RTMP_HANDLE_COUNTER_MEASURE(_pAd, _pEntry)		\
+	{	RTUSBEnqueueInternalCmd(_pAd, CMDTHREAD_802_11_COUNTER_MEASURE, _pEntry, sizeof(struct rt_mac_table_entry));	\
+		RTUSBMlmeUp(_pAd);									\
+	}
+
+/*
+  *	Power Save Related MACRO
+  */
+#define RTMP_PS_POLL_ENQUEUE(pAd)						\
+	{	RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);	\
+		RTUSBKickBulkOut(pAd); }
+
+#define RTMP_STA_FORCE_WAKEUP(_pAd, bFromTx) \
+	RT28xxUsbStaAsicForceWakeup(_pAd, bFromTx);
+
+#define RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \
+    RT28xxUsbStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
+
+#define RTMP_SET_PSM_BIT(_pAd, _val) \
+	{\
+		if ((_pAd)->StaCfg.WindowsPowerMode == Ndis802_11PowerModeFast_PSP) \
+			MlmeSetPsmBit(_pAd, _val);\
+		else \
+		{ \
+			u16 _psm_val; \
+			_psm_val = _val; \
+			RTUSBEnqueueInternalCmd(_pAd, CMDTHREAD_SET_PSM_BIT, &(_psm_val), sizeof(u16)); \
+		}\
+	}
+
+#define RTMP_MLME_RADIO_ON(pAd) \
+    RT28xxUsbMlmeRadioOn(pAd);
+
+#define RTMP_MLME_RADIO_OFF(pAd) \
+    RT28xxUsbMlmeRadioOFF(pAd);
+
+#endif /*__MAC_USB_H__ // */
diff --git a/drivers/staging/rt2860/chip/rt2860.h b/drivers/staging/rt2860/chip/rt2860.h
new file mode 100644
index 0000000..f30b808
--- /dev/null
+++ b/drivers/staging/rt2860/chip/rt2860.h
@@ -0,0 +1,54 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+ */
+
+#ifndef __RT2860_H__
+#define __RT2860_H__
+
+#include "mac_pci.h"
+
+#ifndef RTMP_PCI_SUPPORT
+#error "For RT2860, you should define the compile flag -DRTMP_PCI_SUPPORT"
+#endif
+
+#ifndef RTMP_MAC_PCI
+#error "For RT2880, you should define the compile flag -DRTMP_MAC_PCI"
+#endif
+
+/* */
+/* Device ID & Vendor ID, these values should match EEPROM value */
+/* */
+#define NIC2860_PCI_DEVICE_ID	0x0601
+#define NIC2860_PCIe_DEVICE_ID	0x0681
+#define NIC2760_PCI_DEVICE_ID	0x0701	/* 1T/2R Cardbus ??? */
+#define NIC2790_PCIe_DEVICE_ID  0x0781	/* 1T/2R miniCard */
+
+#define VEN_AWT_PCIe_DEVICE_ID	0x1059
+#define VEN_AWT_PCI_VENDOR_ID		0x1A3B
+
+#define EDIMAX_PCI_VENDOR_ID		0x1432
+
+#endif /*__RT2860_H__ // */
diff --git a/drivers/staging/rt2860/chip/rt2870.h b/drivers/staging/rt2860/chip/rt2870.h
new file mode 100644
index 0000000..8263f1b
--- /dev/null
+++ b/drivers/staging/rt2860/chip/rt2870.h
@@ -0,0 +1,46 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+ */
+#ifndef __RT2870_H__
+#define __RT2870_H__
+
+#ifdef RT2870
+
+#ifndef RTMP_USB_SUPPORT
+#error "For RT2870, you should define the compile flag -DRTMP_USB_SUPPORT"
+#endif
+
+#ifndef RTMP_MAC_USB
+#error "For RT2870, you should define the compile flag -DRTMP_MAC_USB"
+#endif
+
+#include "../rtmp_type.h"
+#include "mac_usb.h"
+
+/*#define RTMP_CHIP_NAME                "RT2870" */
+
+#endif /* RT2870 // */
+#endif /*__RT2870_H__ // */
diff --git a/drivers/staging/rt2860/chip/rt3070.h b/drivers/staging/rt2860/chip/rt3070.h
new file mode 100644
index 0000000..172ce70
--- /dev/null
+++ b/drivers/staging/rt2860/chip/rt3070.h
@@ -0,0 +1,67 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+	rt3070.h
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#ifndef __RT3070_H__
+#define __RT3070_H__
+
+#ifdef RT3070
+
+#ifndef RTMP_USB_SUPPORT
+#error "For RT3070, you should define the compile flag -DRTMP_USB_SUPPORT"
+#endif
+
+#ifndef RTMP_MAC_USB
+#error "For RT3070, you should define the compile flag -DRTMP_MAC_USB"
+#endif
+
+#ifndef RTMP_RF_RW_SUPPORT
+#error "For RT3070, you should define the compile flag -DRTMP_RF_RW_SUPPORT"
+#endif
+
+#ifndef RT30xx
+#error "For RT3070, you should define the compile flag -DRT30xx"
+#endif
+
+#include "mac_usb.h"
+#include "rt30xx.h"
+
+/* */
+/* Device ID & Vendor ID, these values should match EEPROM value */
+/* */
+
+#endif /* RT3070 // */
+
+#endif /*__RT3070_H__ // */
diff --git a/drivers/staging/rt2860/chip/rt3090.h b/drivers/staging/rt2860/chip/rt3090.h
new file mode 100644
index 0000000..102b938
--- /dev/null
+++ b/drivers/staging/rt2860/chip/rt3090.h
@@ -0,0 +1,72 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+	rt3090.h
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#ifndef __RT3090_H__
+#define __RT3090_H__
+
+#ifdef RT3090
+
+#ifndef RTMP_PCI_SUPPORT
+#error "For RT3090, you should define the compile flag -DRTMP_PCI_SUPPORT"
+#endif
+
+#ifndef RTMP_MAC_PCI
+#error "For RT3090, you should define the compile flag -DRTMP_MAC_PCI"
+#endif
+
+#ifndef RTMP_RF_RW_SUPPORT
+#error "For RT3090, you should define the compile flag -DRTMP_RF_RW_SUPPORT"
+#endif
+
+#ifndef RT30xx
+#error "For RT3090, you should define the compile flag -DRT30xx"
+#endif
+
+#define PCIE_PS_SUPPORT
+
+#include "mac_pci.h"
+#include "rt30xx.h"
+
+/* */
+/* Device ID & Vendor ID, these values should match EEPROM value */
+/* */
+#define NIC3090_PCIe_DEVICE_ID  0x3090	/* 1T/1R miniCard */
+#define NIC3091_PCIe_DEVICE_ID  0x3091	/* 1T/2R miniCard */
+#define NIC3092_PCIe_DEVICE_ID  0x3092	/* 2T/2R miniCard */
+
+#endif /* RT3090 // */
+
+#endif /*__RT3090_H__ // */
diff --git a/drivers/staging/rt2860/chip/rt30xx.h b/drivers/staging/rt2860/chip/rt30xx.h
new file mode 100644
index 0000000..02e1d72
--- /dev/null
+++ b/drivers/staging/rt2860/chip/rt30xx.h
@@ -0,0 +1,47 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+	rt30xx.h
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#ifndef __RT30XX_H__
+#define __RT30XX_H__
+
+#ifdef RT30xx
+
+extern struct rt_reg_pair RT30xx_RFRegTable[];
+extern u8 NUM_RF_REG_PARMS;
+
+#endif /* RT30xx // */
+
+#endif /*__RT30XX_H__ // */
diff --git a/drivers/staging/rt2860/chip/rtmp_mac.h b/drivers/staging/rt2860/chip/rtmp_mac.h
new file mode 100644
index 0000000..f6a7258
--- /dev/null
+++ b/drivers/staging/rt2860/chip/rtmp_mac.h
@@ -0,0 +1,1307 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rtmp_mac.h
+
+	Abstract:
+	Ralink Wireless Chip MAC related definition & structures
+
+	Revision History:
+	Who			When		  What
+	--------	----------	  ----------------------------------------------
+*/
+
+#ifndef __RTMP_MAC_H__
+#define __RTMP_MAC_H__
+
+/* ================================================================================= */
+/* TX / RX ring descriptor format */
+/* ================================================================================= */
+
+/* the first 24-byte in TXD is called TXINFO and will be DMAed to MAC block through TXFIFO. */
+/* MAC block use this TXINFO to control the transmission behavior of this frame. */
+#define FIFO_MGMT                 0
+#define FIFO_HCCA                 1
+#define FIFO_EDCA                 2
+
+/* */
+/* TXD Wireless Information format for Tx ring and Mgmt Ring */
+/* */
+/*txop : for txop mode */
+/* 0:txop for the MPDU frame will be handles by ASIC by register */
+/* 1/2/3:the MPDU frame is send after PIFS/backoff/SIFS */
+struct PACKED rt_txwi {
+	/* Word 0 */
+	/* ex: 00 03 00 40 means txop = 3, PHYMODE = 1 */
+	u32 FRAG:1;		/* 1 to inform TKIP engine this is a fragment. */
+	u32 MIMOps:1;	/* the remote peer is in dynamic MIMO-PS mode */
+	u32 CFACK:1;
+	u32 TS:1;
+
+	u32 AMPDU:1;
+	u32 MpduDensity:3;
+	u32 txop:2;		/*FOR "THIS" frame. 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs only when previous frame exchange is successful. */
+	u32 rsv:6;
+
+	u32 MCS:7;
+	u32 BW:1;		/*channel bandwidth 20MHz or 40 MHz */
+	u32 ShortGI:1;
+	u32 STBC:2;		/* 1: STBC support MCS =0-7,   2,3 : RESERVE */
+	u32 Ifs:1;		/* */
+/*      u32          rsv2:2; //channel bandwidth 20MHz or 40 MHz */
+	u32 rsv2:1;
+	u32 TxBF:1;		/* 3*3 */
+	u32 PHYMODE:2;
+	/* Word1 */
+	/* ex:  1c ff 38 00 means ACK=0, BAWinSize=7, MPDUtotalByteCount = 0x38 */
+	u32 ACK:1;
+	u32 NSEQ:1;
+	u32 BAWinSize:6;
+	u32 WirelessCliID:8;
+	u32 MPDUtotalByteCount:12;
+	u32 PacketId:4;
+	/*Word2 */
+	u32 IV;
+	/*Word3 */
+	u32 EIV;
+};
+
+/* */
+/* RXWI wireless information format, in PBF. invisible in driver. */
+/* */
+struct PACKED rt_rxwi {
+	/* Word 0 */
+	u32 WirelessCliID:8;
+	u32 KeyIndex:2;
+	u32 BSSID:3;
+	u32 UDF:3;
+	u32 MPDUtotalByteCount:12;
+	u32 TID:4;
+	/* Word 1 */
+	u32 FRAG:4;
+	u32 SEQUENCE:12;
+	u32 MCS:7;
+	u32 BW:1;
+	u32 ShortGI:1;
+	u32 STBC:2;
+	u32 rsv:3;
+	u32 PHYMODE:2;	/* 1: this RX frame is unicast to me */
+	/*Word2 */
+	u32 RSSI0:8;
+	u32 RSSI1:8;
+	u32 RSSI2:8;
+	u32 rsv1:8;
+	/*Word3 */
+	u32 SNR0:8;
+	u32 SNR1:8;
+	u32 FOFFSET:8;	/* RT35xx */
+	u32 rsv2:8;
+	/*u32                rsv2:16; */
+};
+
+/* ================================================================================= */
+/* Register format */
+/* ================================================================================= */
+
+/* */
+/* SCH/DMA registers - base address 0x0200 */
+/* */
+/* INT_SOURCE_CSR: Interrupt source register. Write one to clear corresponding bit */
+/* */
+#define DMA_CSR0		0x200
+#define INT_SOURCE_CSR		0x200
+typedef union _INT_SOURCE_CSR_STRUC {
+	struct {
+		u32 RxDelayINT:1;
+		u32 TxDelayINT:1;
+		u32 RxDone:1;
+		u32 Ac0DmaDone:1;	/*4 */
+		u32 Ac1DmaDone:1;
+		u32 Ac2DmaDone:1;
+		u32 Ac3DmaDone:1;
+		u32 HccaDmaDone:1;	/* bit7 */
+		u32 MgmtDmaDone:1;
+		u32 MCUCommandINT:1;	/*bit 9 */
+		u32 RxTxCoherent:1;
+		u32 TBTTInt:1;
+		u32 PreTBTT:1;
+		u32 TXFifoStatusInt:1;	/*FIFO Statistics is full, sw should read 0x171c */
+		u32 AutoWakeup:1;	/*bit14 */
+		u32 GPTimer:1;
+		u32 RxCoherent:1;	/*bit16 */
+		u32 TxCoherent:1;
+		u32 : 14;
+	} field;
+	u32 word;
+} INT_SOURCE_CSR_STRUC, *PINT_SOURCE_CSR_STRUC;
+
+/* */
+/* INT_MASK_CSR:   Interrupt MASK register.   1: the interrupt is mask OFF */
+/* */
+#define INT_MASK_CSR        0x204
+typedef union _INT_MASK_CSR_STRUC {
+	struct {
+		u32 RXDelay_INT_MSK:1;
+		u32 TxDelay:1;
+		u32 RxDone:1;
+		u32 Ac0DmaDone:1;
+		u32 Ac1DmaDone:1;
+		u32 Ac2DmaDone:1;
+		u32 Ac3DmaDone:1;
+		u32 HccaDmaDone:1;
+		u32 MgmtDmaDone:1;
+		u32 MCUCommandINT:1;
+		u32 : 20;
+		u32 RxCoherent:1;
+		u32 TxCoherent:1;
+	} field;
+	u32 word;
+} INT_MASK_CSR_STRUC, *PINT_MASK_CSR_STRUC;
+
+#define WPDMA_GLO_CFG	0x208
+typedef union _WPDMA_GLO_CFG_STRUC {
+	struct {
+		u32 EnableTxDMA:1;
+		u32 TxDMABusy:1;
+		u32 EnableRxDMA:1;
+		u32 RxDMABusy:1;
+		u32 WPDMABurstSIZE:2;
+		u32 EnTXWriteBackDDONE:1;
+		u32 BigEndian:1;
+		u32 RXHdrScater:8;
+		u32 HDR_SEG_LEN:16;
+	} field;
+	u32 word;
+} WPDMA_GLO_CFG_STRUC, *PWPDMA_GLO_CFG_STRUC;
+
+#define WPDMA_RST_IDX	0x20c
+typedef union _WPDMA_RST_IDX_STRUC {
+	struct {
+		u32 RST_DTX_IDX0:1;
+		u32 RST_DTX_IDX1:1;
+		u32 RST_DTX_IDX2:1;
+		u32 RST_DTX_IDX3:1;
+		u32 RST_DTX_IDX4:1;
+		u32 RST_DTX_IDX5:1;
+		u32 rsv:10;
+		u32 RST_DRX_IDX0:1;
+		u32 : 15;
+	} field;
+	u32 word;
+} WPDMA_RST_IDX_STRUC, *PWPDMA_RST_IDX_STRUC;
+#define DELAY_INT_CFG  0x0210
+typedef union _DELAY_INT_CFG_STRUC {
+	struct {
+		u32 RXMAX_PTIME:8;
+		u32 RXMAX_PINT:7;
+		u32 RXDLY_INT_EN:1;
+		u32 TXMAX_PTIME:8;
+		u32 TXMAX_PINT:7;
+		u32 TXDLY_INT_EN:1;
+	} field;
+	u32 word;
+} DELAY_INT_CFG_STRUC, *PDELAY_INT_CFG_STRUC;
+#define WMM_AIFSN_CFG   0x0214
+typedef union _AIFSN_CSR_STRUC {
+	struct {
+		u32 Aifsn0:4;	/* for AC_BE */
+		u32 Aifsn1:4;	/* for AC_BK */
+		u32 Aifsn2:4;	/* for AC_VI */
+		u32 Aifsn3:4;	/* for AC_VO */
+		u32 Rsv:16;
+	} field;
+	u32 word;
+} AIFSN_CSR_STRUC, *PAIFSN_CSR_STRUC;
+/* */
+/* CWMIN_CSR: CWmin for each EDCA AC */
+/* */
+#define WMM_CWMIN_CFG   0x0218
+typedef union _CWMIN_CSR_STRUC {
+	struct {
+		u32 Cwmin0:4;	/* for AC_BE */
+		u32 Cwmin1:4;	/* for AC_BK */
+		u32 Cwmin2:4;	/* for AC_VI */
+		u32 Cwmin3:4;	/* for AC_VO */
+		u32 Rsv:16;
+	} field;
+	u32 word;
+} CWMIN_CSR_STRUC, *PCWMIN_CSR_STRUC;
+
+/* */
+/* CWMAX_CSR: CWmin for each EDCA AC */
+/* */
+#define WMM_CWMAX_CFG   0x021c
+typedef union _CWMAX_CSR_STRUC {
+	struct {
+		u32 Cwmax0:4;	/* for AC_BE */
+		u32 Cwmax1:4;	/* for AC_BK */
+		u32 Cwmax2:4;	/* for AC_VI */
+		u32 Cwmax3:4;	/* for AC_VO */
+		u32 Rsv:16;
+	} field;
+	u32 word;
+} CWMAX_CSR_STRUC, *PCWMAX_CSR_STRUC;
+
+/* */
+/* AC_TXOP_CSR0: AC_BK/AC_BE TXOP register */
+/* */
+#define WMM_TXOP0_CFG    0x0220
+typedef union _AC_TXOP_CSR0_STRUC {
+	struct {
+		u16 Ac0Txop;	/* for AC_BK, in unit of 32us */
+		u16 Ac1Txop;	/* for AC_BE, in unit of 32us */
+	} field;
+	u32 word;
+} AC_TXOP_CSR0_STRUC, *PAC_TXOP_CSR0_STRUC;
+
+/* */
+/* AC_TXOP_CSR1: AC_VO/AC_VI TXOP register */
+/* */
+#define WMM_TXOP1_CFG    0x0224
+typedef union _AC_TXOP_CSR1_STRUC {
+	struct {
+		u16 Ac2Txop;	/* for AC_VI, in unit of 32us */
+		u16 Ac3Txop;	/* for AC_VO, in unit of 32us */
+	} field;
+	u32 word;
+} AC_TXOP_CSR1_STRUC, *PAC_TXOP_CSR1_STRUC;
+
+#define RINGREG_DIFF			0x10
+#define GPIO_CTRL_CFG    0x0228	/*MAC_CSR13 */
+#define MCU_CMD_CFG    0x022c
+#define TX_BASE_PTR0     0x0230	/*AC_BK base address */
+#define TX_MAX_CNT0      0x0234
+#define TX_CTX_IDX0       0x0238
+#define TX_DTX_IDX0      0x023c
+#define TX_BASE_PTR1     0x0240	/*AC_BE base address */
+#define TX_MAX_CNT1      0x0244
+#define TX_CTX_IDX1       0x0248
+#define TX_DTX_IDX1      0x024c
+#define TX_BASE_PTR2     0x0250	/*AC_VI base address */
+#define TX_MAX_CNT2      0x0254
+#define TX_CTX_IDX2       0x0258
+#define TX_DTX_IDX2      0x025c
+#define TX_BASE_PTR3     0x0260	/*AC_VO base address */
+#define TX_MAX_CNT3      0x0264
+#define TX_CTX_IDX3       0x0268
+#define TX_DTX_IDX3      0x026c
+#define TX_BASE_PTR4     0x0270	/*HCCA base address */
+#define TX_MAX_CNT4      0x0274
+#define TX_CTX_IDX4       0x0278
+#define TX_DTX_IDX4      0x027c
+#define TX_BASE_PTR5     0x0280	/*MGMT base address */
+#define  TX_MAX_CNT5     0x0284
+#define TX_CTX_IDX5       0x0288
+#define TX_DTX_IDX5      0x028c
+#define TX_MGMTMAX_CNT      TX_MAX_CNT5
+#define TX_MGMTCTX_IDX       TX_CTX_IDX5
+#define TX_MGMTDTX_IDX      TX_DTX_IDX5
+#define RX_BASE_PTR     0x0290	/*RX base address */
+#define RX_MAX_CNT      0x0294
+#define RX_CRX_IDX       0x0298
+#define RX_DRX_IDX      0x029c
+
+#define USB_DMA_CFG      0x02a0
+typedef union _USB_DMA_CFG_STRUC {
+	struct {
+		u32 RxBulkAggTOut:8;	/*Rx Bulk Aggregation TimeOut  in unit of 33ns */
+		u32 RxBulkAggLmt:8;	/*Rx Bulk Aggregation Limit  in unit of 256 bytes */
+		u32 phyclear:1;	/*phy watch dog enable. write 1 */
+		u32 rsv:2;
+		u32 TxClear:1;	/*Clear USB DMA TX path */
+		u32 TxopHalt:1;	/*Halt TXOP count down when TX buffer is full. */
+		u32 RxBulkAggEn:1;	/*Enable Rx Bulk Aggregation */
+		u32 RxBulkEn:1;	/*Enable USB DMA Rx */
+		u32 TxBulkEn:1;	/*Enable USB DMA Tx */
+		u32 EpoutValid:6;	/*OUT endpoint data valid */
+		u32 RxBusy:1;	/*USB DMA RX FSM busy */
+		u32 TxBusy:1;	/*USB DMA TX FSM busy */
+	} field;
+	u32 word;
+} USB_DMA_CFG_STRUC, *PUSB_DMA_CFG_STRUC;
+
+/* */
+/*  3  PBF  registers */
+/* */
+/* */
+/* Most are for debug. Driver doesn't touch PBF register. */
+#define PBF_SYS_CTRL	 0x0400
+#define PBF_CFG                 0x0408
+#define PBF_MAX_PCNT	 0x040C
+#define PBF_CTRL		0x0410
+#define PBF_INT_STA	 0x0414
+#define PBF_INT_ENA	 0x0418
+#define TXRXQ_PCNT	 0x0438
+#define PBF_DBG			 0x043c
+#define PBF_CAP_CTRL     0x0440
+
+#ifdef RT30xx
+#ifdef RTMP_EFUSE_SUPPORT
+/* eFuse registers */
+#define EFUSE_CTRL				0x0580
+#define EFUSE_DATA0				0x0590
+#define EFUSE_DATA1				0x0594
+#define EFUSE_DATA2				0x0598
+#define EFUSE_DATA3				0x059c
+#endif /* RTMP_EFUSE_SUPPORT // */
+#endif /* RT30xx // */
+
+#define OSC_CTRL		0x5a4
+#define PCIE_PHY_TX_ATTENUATION_CTRL	0x05C8
+#define LDO_CFG0				0x05d4
+#define GPIO_SWITCH				0x05dc
+
+/* */
+/*  4  MAC  registers */
+/* */
+/* */
+/*  4.1 MAC SYSTEM  configuration registers (offset:0x1000) */
+/* */
+#define MAC_CSR0            0x1000
+typedef union _ASIC_VER_ID_STRUC {
+	struct {
+		u16 ASICRev;	/* reversion  : 0 */
+		u16 ASICVer;	/* version : 2860 */
+	} field;
+	u32 word;
+} ASIC_VER_ID_STRUC, *PASIC_VER_ID_STRUC;
+#define MAC_SYS_CTRL            0x1004	/*MAC_CSR1 */
+#define MAC_ADDR_DW0				0x1008	/* MAC ADDR DW0 */
+#define MAC_ADDR_DW1			 0x100c	/* MAC ADDR DW1 */
+/* */
+/* MAC_CSR2: STA MAC register 0 */
+/* */
+typedef union _MAC_DW0_STRUC {
+	struct {
+		u8 Byte0;	/* MAC address byte 0 */
+		u8 Byte1;	/* MAC address byte 1 */
+		u8 Byte2;	/* MAC address byte 2 */
+		u8 Byte3;	/* MAC address byte 3 */
+	} field;
+	u32 word;
+} MAC_DW0_STRUC, *PMAC_DW0_STRUC;
+
+/* */
+/* MAC_CSR3: STA MAC register 1 */
+/* */
+typedef union _MAC_DW1_STRUC {
+	struct {
+		u8 Byte4;	/* MAC address byte 4 */
+		u8 Byte5;	/* MAC address byte 5 */
+		u8 U2MeMask;
+		u8 Rsvd1;
+	} field;
+	u32 word;
+} MAC_DW1_STRUC, *PMAC_DW1_STRUC;
+
+#define MAC_BSSID_DW0				0x1010	/* MAC BSSID DW0 */
+#define MAC_BSSID_DW1				0x1014	/* MAC BSSID DW1 */
+
+/* */
+/* MAC_CSR5: BSSID register 1 */
+/* */
+typedef union _MAC_CSR5_STRUC {
+	struct {
+		u8 Byte4;	/* BSSID byte 4 */
+		u8 Byte5;	/* BSSID byte 5 */
+		u16 BssIdMask:2;	/* 0: one BSSID, 10: 4 BSSID,  01: 2 BSSID , 11: 8BSSID */
+		u16 MBssBcnNum:3;
+		u16 Rsvd:11;
+	} field;
+	u32 word;
+} MAC_CSR5_STRUC, *PMAC_CSR5_STRUC;
+
+#define MAX_LEN_CFG              0x1018	/* rt2860b max 16k bytes. bit12:13 Maximum PSDU length (power factor) 0:2^13, 1:2^14, 2:2^15, 3:2^16 */
+#define BBP_CSR_CFG			0x101c	/* */
+/* */
+/* BBP_CSR_CFG: BBP serial control register */
+/* */
+typedef union _BBP_CSR_CFG_STRUC {
+	struct {
+		u32 Value:8;	/* Register     value to program into BBP */
+		u32 RegNum:8;	/* Selected     BBP     register */
+		u32 fRead:1;	/* 0: Write BBP, 1: Read BBP */
+		u32 Busy:1;	/* 1: ASIC is busy execute BBP programming. */
+		u32 BBP_PAR_DUR:1;	/* 0: 4 MAC clock cycles  1: 8 MAC clock cycles */
+		u32 BBP_RW_MODE:1;	/* 0: use serial mode  1:parallel */
+		u32 : 12;
+	} field;
+	u32 word;
+} BBP_CSR_CFG_STRUC, *PBBP_CSR_CFG_STRUC;
+#define RF_CSR_CFG0			0x1020
+/* */
+/* RF_CSR_CFG: RF control register */
+/* */
+typedef union _RF_CSR_CFG0_STRUC {
+	struct {
+		u32 RegIdAndContent:24;	/* Register     value to program into BBP */
+		u32 bitwidth:5;	/* Selected     BBP     register */
+		u32 StandbyMode:1;	/* 0: high when stand by 1: low when standby */
+		u32 Sel:1;	/* 0:RF_LE0 activate  1:RF_LE1 activate */
+		u32 Busy:1;	/* 0: idle 1: 8busy */
+	} field;
+	u32 word;
+} RF_CSR_CFG0_STRUC, *PRF_CSR_CFG0_STRUC;
+#define RF_CSR_CFG1			0x1024
+typedef union _RF_CSR_CFG1_STRUC {
+	struct {
+		u32 RegIdAndContent:24;	/* Register     value to program into BBP */
+		u32 RFGap:5;	/* Gap between BB_CONTROL_RF and RF_LE. 0: 3 system clock cycle (37.5usec) 1: 5 system clock cycle (62.5usec) */
+		u32 rsv:7;	/* 0: idle 1: 8busy */
+	} field;
+	u32 word;
+} RF_CSR_CFG1_STRUC, *PRF_CSR_CFG1_STRUC;
+#define RF_CSR_CFG2			0x1028	/* */
+typedef union _RF_CSR_CFG2_STRUC {
+	struct {
+		u32 RegIdAndContent:24;	/* Register     value to program into BBP */
+		u32 rsv:8;	/* 0: idle 1: 8busy */
+	} field;
+	u32 word;
+} RF_CSR_CFG2_STRUC, *PRF_CSR_CFG2_STRUC;
+#define LED_CFG				0x102c	/*  MAC_CSR14 */
+typedef union _LED_CFG_STRUC {
+	struct {
+		u32 OnPeriod:8;	/* blinking on period unit 1ms */
+		u32 OffPeriod:8;	/* blinking off period unit 1ms */
+		u32 SlowBlinkPeriod:6;	/* slow blinking period. unit:1ms */
+		u32 rsv:2;
+		u32 RLedMode:2;	/* red Led Mode    0: off1: blinking upon TX2: periodic slow blinking3: always on */
+		u32 GLedMode:2;	/* green Led Mode */
+		u32 YLedMode:2;	/* yellow Led Mode */
+		u32 LedPolar:1;	/* Led Polarity.  0: active low1: active high */
+		u32 : 1;
+	} field;
+	u32 word;
+} LED_CFG_STRUC, *PLED_CFG_STRUC;
+/* */
+/*  4.2 MAC TIMING  configuration registers (offset:0x1100) */
+/* */
+#define XIFS_TIME_CFG             0x1100	/* MAC_CSR8  MAC_CSR9 */
+typedef union _IFS_SLOT_CFG_STRUC {
+	struct {
+		u32 CckmSifsTime:8;	/*  unit 1us. Applied after CCK RX/TX */
+		u32 OfdmSifsTime:8;	/*  unit 1us. Applied after OFDM RX/TX */
+		u32 OfdmXifsTime:4;	/*OFDM SIFS. unit 1us. Applied after OFDM RX when MAC doesn't reference BBP signal BBRXEND */
+		u32 EIFS:9;	/*  unit 1us */
+		u32 BBRxendEnable:1;	/*  reference RXEND signal to begin XIFS defer */
+		u32 rsv:2;
+	} field;
+	u32 word;
+} IFS_SLOT_CFG_STRUC, *PIFS_SLOT_CFG_STRUC;
+
+#define BKOFF_SLOT_CFG             0x1104	/*  mac_csr9 last 8 bits */
+#define NAV_TIME_CFG             0x1108	/* NAV  (MAC_CSR15) */
+#define CH_TIME_CFG             0x110C	/* Count as channel busy */
+#define PBF_LIFE_TIMER             0x1110	/*TX/RX MPDU timestamp timer (free run)Unit: 1us */
+#define BCN_TIME_CFG             0x1114	/* TXRX_CSR9 */
+
+#define BCN_OFFSET0				0x042C
+#define BCN_OFFSET1				0x0430
+
+/* */
+/* BCN_TIME_CFG : Synchronization control register */
+/* */
+typedef union _BCN_TIME_CFG_STRUC {
+	struct {
+		u32 BeaconInterval:16;	/* in unit of 1/16 TU */
+		u32 bTsfTicking:1;	/* Enable TSF auto counting */
+		u32 TsfSyncMode:2;	/* Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode */
+		u32 bTBTTEnable:1;
+		u32 bBeaconGen:1;	/* Enable beacon generator */
+		u32 : 3;
+		u32 TxTimestampCompensate:8;
+	} field;
+	u32 word;
+} BCN_TIME_CFG_STRUC, *PBCN_TIME_CFG_STRUC;
+#define TBTT_SYNC_CFG            0x1118	/* txrx_csr10 */
+#define TSF_TIMER_DW0             0x111C	/* Local TSF timer lsb 32 bits. Read-only */
+#define TSF_TIMER_DW1             0x1120	/* msb 32 bits. Read-only. */
+#define TBTT_TIMER		0x1124	/* TImer remains till next TBTT. Read-only.  TXRX_CSR14 */
+#define INT_TIMER_CFG			0x1128	/* */
+#define INT_TIMER_EN			0x112c	/*  GP-timer and pre-tbtt Int enable */
+#define CH_IDLE_STA			0x1130	/*  channel idle time */
+#define CH_BUSY_STA			0x1134	/*  channle busy time */
+/* */
+/*  4.2 MAC POWER  configuration registers (offset:0x1200) */
+/* */
+#define MAC_STATUS_CFG             0x1200	/* old MAC_CSR12 */
+#define PWR_PIN_CFG             0x1204	/* old MAC_CSR12 */
+#define AUTO_WAKEUP_CFG             0x1208	/* old MAC_CSR10 */
+/* */
+/* AUTO_WAKEUP_CFG: Manual power control / status register */
+/* */
+typedef union _AUTO_WAKEUP_STRUC {
+	struct {
+		u32 AutoLeadTime:8;
+		u32 NumofSleepingTbtt:7;	/* ForceWake has high privilege than PutToSleep when both set */
+		u32 EnableAutoWakeup:1;	/* 0:sleep, 1:awake */
+		u32 : 16;
+	} field;
+	u32 word;
+} AUTO_WAKEUP_STRUC, *PAUTO_WAKEUP_STRUC;
+/* */
+/*  4.3 MAC TX  configuration registers (offset:0x1300) */
+/* */
+
+#define EDCA_AC0_CFG	0x1300	/*AC_TXOP_CSR0 0x3474 */
+#define EDCA_AC1_CFG	0x1304
+#define EDCA_AC2_CFG	0x1308
+#define EDCA_AC3_CFG	0x130c
+typedef union _EDCA_AC_CFG_STRUC {
+	struct {
+		u32 AcTxop:8;	/*  in unit of 32us */
+		u32 Aifsn:4;	/* # of slot time */
+		u32 Cwmin:4;	/* */
+		u32 Cwmax:4;	/*unit power of 2 */
+		u32 : 12;	/* */
+	} field;
+	u32 word;
+} EDCA_AC_CFG_STRUC, *PEDCA_AC_CFG_STRUC;
+
+#define EDCA_TID_AC_MAP	0x1310
+#define TX_PWR_CFG_0	0x1314
+#define TX_PWR_CFG_1	0x1318
+#define TX_PWR_CFG_2	0x131C
+#define TX_PWR_CFG_3	0x1320
+#define TX_PWR_CFG_4	0x1324
+#define TX_PIN_CFG		0x1328
+#define TX_BAND_CFG	0x132c	/* 0x1 use upper 20MHz. 0 juse lower 20MHz */
+#define TX_SW_CFG0		0x1330
+#define TX_SW_CFG1		0x1334
+#define TX_SW_CFG2		0x1338
+#define TXOP_THRES_CFG		0x133c
+#define TXOP_CTRL_CFG		0x1340
+#define TX_RTS_CFG		0x1344
+
+typedef union _TX_RTS_CFG_STRUC {
+	struct {
+		u32 AutoRtsRetryLimit:8;
+		u32 RtsThres:16;	/* unit:byte */
+		u32 RtsFbkEn:1;	/* enable rts rate fallback */
+		u32 rsv:7;	/* 1: HT non-STBC control frame enable */
+	} field;
+	u32 word;
+} TX_RTS_CFG_STRUC, *PTX_RTS_CFG_STRUC;
+#define TX_TIMEOUT_CFG	0x1348
+typedef union _TX_TIMEOUT_CFG_STRUC {
+	struct {
+		u32 rsv:4;
+		u32 MpduLifeTime:4;	/*  expiration time = 2^(9+MPDU LIFE TIME)  us */
+		u32 RxAckTimeout:8;	/* unit:slot. Used for TX precedure */
+		u32 TxopTimeout:8;	/*TXOP timeout value for TXOP truncation.  It is recommended that (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT) */
+		u32 rsv2:8;	/* 1: HT non-STBC control frame enable */
+	} field;
+	u32 word;
+} TX_TIMEOUT_CFG_STRUC, *PTX_TIMEOUT_CFG_STRUC;
+#define TX_RTY_CFG	0x134c
+typedef union PACKED _TX_RTY_CFG_STRUC {
+	struct {
+		u32 ShortRtyLimit:8;	/*  short retry limit */
+		u32 LongRtyLimit:8;	/*long retry limit */
+		u32 LongRtyThre:12;	/* Long retry threshoold */
+		u32 NonAggRtyMode:1;	/* Non-Aggregate MPDU retry mode.  0:expired by retry limit, 1: expired by mpdu life timer */
+		u32 AggRtyMode:1;	/* Aggregate MPDU retry mode.  0:expired by retry limit, 1: expired by mpdu life timer */
+		u32 TxautoFBEnable:1;	/* Tx retry PHY rate auto fallback enable */
+		u32 rsv:1;	/* 1: HT non-STBC control frame enable */
+	} field;
+	u32 word;
+} TX_RTY_CFG_STRUC, *PTX_RTY_CFG_STRUC;
+#define TX_LINK_CFG	0x1350
+typedef union PACKED _TX_LINK_CFG_STRUC {
+	struct PACKED {
+		u32 RemoteMFBLifeTime:8;	/*remote MFB life time. unit : 32us */
+		u32 MFBEnable:1;	/*  TX apply remote MFB 1:enable */
+		u32 RemoteUMFSEnable:1;	/*  remote unsolicit  MFB enable.  0: not apply remote remote unsolicit (MFS=7) */
+		u32 TxMRQEn:1;	/*  MCS request TX enable */
+		u32 TxRDGEn:1;	/* RDG TX enable */
+		u32 TxCFAckEn:1;	/*   Piggyback CF-ACK enable */
+		u32 rsv:3;	/* */
+		u32 RemotMFB:8;	/*  remote MCS feedback */
+		u32 RemotMFS:8;	/*remote MCS feedback sequence number */
+	} field;
+	u32 word;
+} TX_LINK_CFG_STRUC, *PTX_LINK_CFG_STRUC;
+#define HT_FBK_CFG0	0x1354
+typedef union PACKED _HT_FBK_CFG0_STRUC {
+	struct {
+		u32 HTMCS0FBK:4;
+		u32 HTMCS1FBK:4;
+		u32 HTMCS2FBK:4;
+		u32 HTMCS3FBK:4;
+		u32 HTMCS4FBK:4;
+		u32 HTMCS5FBK:4;
+		u32 HTMCS6FBK:4;
+		u32 HTMCS7FBK:4;
+	} field;
+	u32 word;
+} HT_FBK_CFG0_STRUC, *PHT_FBK_CFG0_STRUC;
+#define HT_FBK_CFG1	0x1358
+typedef union _HT_FBK_CFG1_STRUC {
+	struct {
+		u32 HTMCS8FBK:4;
+		u32 HTMCS9FBK:4;
+		u32 HTMCS10FBK:4;
+		u32 HTMCS11FBK:4;
+		u32 HTMCS12FBK:4;
+		u32 HTMCS13FBK:4;
+		u32 HTMCS14FBK:4;
+		u32 HTMCS15FBK:4;
+	} field;
+	u32 word;
+} HT_FBK_CFG1_STRUC, *PHT_FBK_CFG1_STRUC;
+#define LG_FBK_CFG0	0x135c
+typedef union _LG_FBK_CFG0_STRUC {
+	struct {
+		u32 OFDMMCS0FBK:4;	/*initial value is 0 */
+		u32 OFDMMCS1FBK:4;	/*initial value is 0 */
+		u32 OFDMMCS2FBK:4;	/*initial value is 1 */
+		u32 OFDMMCS3FBK:4;	/*initial value is 2 */
+		u32 OFDMMCS4FBK:4;	/*initial value is 3 */
+		u32 OFDMMCS5FBK:4;	/*initial value is 4 */
+		u32 OFDMMCS6FBK:4;	/*initial value is 5 */
+		u32 OFDMMCS7FBK:4;	/*initial value is 6 */
+	} field;
+	u32 word;
+} LG_FBK_CFG0_STRUC, *PLG_FBK_CFG0_STRUC;
+#define LG_FBK_CFG1		0x1360
+typedef union _LG_FBK_CFG1_STRUC {
+	struct {
+		u32 CCKMCS0FBK:4;	/*initial value is 0 */
+		u32 CCKMCS1FBK:4;	/*initial value is 0 */
+		u32 CCKMCS2FBK:4;	/*initial value is 1 */
+		u32 CCKMCS3FBK:4;	/*initial value is 2 */
+		u32 rsv:16;
+	} field;
+	u32 word;
+} LG_FBK_CFG1_STRUC, *PLG_FBK_CFG1_STRUC;
+
+/*======================================================= */
+/*================ Protection Paramater================================ */
+/*======================================================= */
+#define CCK_PROT_CFG	0x1364	/*CCK Protection */
+#define ASIC_SHORTNAV		1
+#define ASIC_longNAV		2
+#define ASIC_RTS		1
+#define ASIC_CTS		2
+typedef union _PROT_CFG_STRUC {
+	struct {
+		u32 ProtectRate:16;	/*Protection control frame rate for CCK TX(RTS/CTS/CFEnd). */
+		u32 ProtectCtrl:2;	/*Protection control frame type for CCK TX. 1:RTS/CTS, 2:CTS-to-self, 0:None, 3:rsv */
+		u32 ProtectNav:2;	/*TXOP protection type for CCK TX. 0:None, 1:ShortNAVprotect,  2:LongNAVProtect, 3:rsv */
+		u32 TxopAllowCck:1;	/*CCK TXOP allowance.0:disallow. */
+		u32 TxopAllowOfdm:1;	/*CCK TXOP allowance.0:disallow. */
+		u32 TxopAllowMM20:1;	/*CCK TXOP allowance. 0:disallow. */
+		u32 TxopAllowMM40:1;	/*CCK TXOP allowance.0:disallow. */
+		u32 TxopAllowGF20:1;	/*CCK TXOP allowance.0:disallow. */
+		u32 TxopAllowGF40:1;	/*CCK TXOP allowance.0:disallow. */
+		u32 RTSThEn:1;	/*RTS threshold enable on CCK TX */
+		u32 rsv:5;
+	} field;
+	u32 word;
+} PROT_CFG_STRUC, *PPROT_CFG_STRUC;
+
+#define OFDM_PROT_CFG	0x1368	/*OFDM Protection */
+#define MM20_PROT_CFG	0x136C	/*MM20 Protection */
+#define MM40_PROT_CFG	0x1370	/*MM40 Protection */
+#define GF20_PROT_CFG	0x1374	/*GF20 Protection */
+#define GF40_PROT_CFG	0x1378	/*GR40 Protection */
+#define EXP_CTS_TIME	0x137C	/* */
+#define EXP_ACK_TIME	0x1380	/* */
+
+/* */
+/*  4.4 MAC RX configuration registers (offset:0x1400) */
+/* */
+#define RX_FILTR_CFG	0x1400	/*TXRX_CSR0 */
+#define AUTO_RSP_CFG	0x1404	/*TXRX_CSR4 */
+/* */
+/* TXRX_CSR4: Auto-Responder/ */
+/* */
+typedef union _AUTO_RSP_CFG_STRUC {
+	struct {
+		u32 AutoResponderEnable:1;
+		u32 BACAckPolicyEnable:1;	/* 0:long, 1:short preamble */
+		u32 CTS40MMode:1;	/* Response CTS 40MHz duplicate mode */
+		u32 CTS40MRef:1;	/* Response CTS 40MHz duplicate mode */
+		u32 AutoResponderPreamble:1;	/* 0:long, 1:short preamble */
+		u32 rsv:1;	/* Power bit value in conrtrol frame */
+		u32 DualCTSEn:1;	/* Power bit value in conrtrol frame */
+		u32 AckCtsPsmBit:1;	/* Power bit value in conrtrol frame */
+		u32 : 24;
+	} field;
+	u32 word;
+} AUTO_RSP_CFG_STRUC, *PAUTO_RSP_CFG_STRUC;
+
+#define LEGACY_BASIC_RATE	0x1408	/*  TXRX_CSR5           0x3054 */
+#define HT_BASIC_RATE		0x140c
+#define HT_CTRL_CFG		0x1410
+#define SIFS_COST_CFG		0x1414
+#define RX_PARSER_CFG		0x1418	/*Set NAV for all received frames */
+
+/* */
+/*  4.5 MAC Security configuration (offset:0x1500) */
+/* */
+#define TX_SEC_CNT0		0x1500	/* */
+#define RX_SEC_CNT0		0x1504	/* */
+#define CCMP_FC_MUTE		0x1508	/* */
+/* */
+/*  4.6 HCCA/PSMP (offset:0x1600) */
+/* */
+#define TXOP_HLDR_ADDR0		0x1600
+#define TXOP_HLDR_ADDR1		0x1604
+#define TXOP_HLDR_ET		0x1608
+#define QOS_CFPOLL_RA_DW0		0x160c
+#define QOS_CFPOLL_A1_DW1		0x1610
+#define QOS_CFPOLL_QC		0x1614
+/* */
+/*  4.7 MAC Statistis registers (offset:0x1700) */
+/* */
+#define RX_STA_CNT0		0x1700	/* */
+#define RX_STA_CNT1		0x1704	/* */
+#define RX_STA_CNT2		0x1708	/* */
+
+/* */
+/* RX_STA_CNT0_STRUC: RX PLCP error count & RX CRC error count */
+/* */
+typedef union _RX_STA_CNT0_STRUC {
+	struct {
+		u16 CrcErr;
+		u16 PhyErr;
+	} field;
+	u32 word;
+} RX_STA_CNT0_STRUC, *PRX_STA_CNT0_STRUC;
+
+/* */
+/* RX_STA_CNT1_STRUC: RX False CCA count & RX long frame count */
+/* */
+typedef union _RX_STA_CNT1_STRUC {
+	struct {
+		u16 FalseCca;
+		u16 PlcpErr;
+	} field;
+	u32 word;
+} RX_STA_CNT1_STRUC, *PRX_STA_CNT1_STRUC;
+
+/* */
+/* RX_STA_CNT2_STRUC: */
+/* */
+typedef union _RX_STA_CNT2_STRUC {
+	struct {
+		u16 RxDupliCount;
+		u16 RxFifoOverflowCount;
+	} field;
+	u32 word;
+} RX_STA_CNT2_STRUC, *PRX_STA_CNT2_STRUC;
+#define TX_STA_CNT0		0x170C	/* */
+/* */
+/* STA_CSR3: TX Beacon count */
+/* */
+typedef union _TX_STA_CNT0_STRUC {
+	struct {
+		u16 TxFailCount;
+		u16 TxBeaconCount;
+	} field;
+	u32 word;
+} TX_STA_CNT0_STRUC, *PTX_STA_CNT0_STRUC;
+#define TX_STA_CNT1		0x1710	/* */
+/* */
+/* TX_STA_CNT1: TX tx count */
+/* */
+typedef union _TX_STA_CNT1_STRUC {
+	struct {
+		u16 TxSuccess;
+		u16 TxRetransmit;
+	} field;
+	u32 word;
+} TX_STA_CNT1_STRUC, *PTX_STA_CNT1_STRUC;
+#define TX_STA_CNT2		0x1714	/* */
+/* */
+/* TX_STA_CNT2: TX tx count */
+/* */
+typedef union _TX_STA_CNT2_STRUC {
+	struct {
+		u16 TxZeroLenCount;
+		u16 TxUnderFlowCount;
+	} field;
+	u32 word;
+} TX_STA_CNT2_STRUC, *PTX_STA_CNT2_STRUC;
+#define TX_STA_FIFO		0x1718	/* */
+/* */
+/* TX_STA_FIFO_STRUC: TX Result for specific PID status fifo register */
+/* */
+typedef union PACKED _TX_STA_FIFO_STRUC {
+	struct {
+		u32 bValid:1;	/* 1:This register contains a valid TX result */
+		u32 PidType:4;
+		u32 TxSuccess:1;	/* Tx No retry success */
+		u32 TxAggre:1;	/* Tx Retry Success */
+		u32 TxAckRequired:1;	/* Tx fail */
+		u32 wcid:8;	/*wireless client index */
+/*              u32          SuccessRate:16; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16. */
+		u32 SuccessRate:13;	/*include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16. */
+		u32 TxBF:1;
+		u32 Reserve:2;
+	} field;
+	u32 word;
+} TX_STA_FIFO_STRUC, *PTX_STA_FIFO_STRUC;
+/* Debug counter */
+#define TX_AGG_CNT	0x171c
+typedef union _TX_AGG_CNT_STRUC {
+	struct {
+		u16 NonAggTxCount;
+		u16 AggTxCount;
+	} field;
+	u32 word;
+} TX_AGG_CNT_STRUC, *PTX_AGG_CNT_STRUC;
+/* Debug counter */
+#define TX_AGG_CNT0	0x1720
+typedef union _TX_AGG_CNT0_STRUC {
+	struct {
+		u16 AggSize1Count;
+		u16 AggSize2Count;
+	} field;
+	u32 word;
+} TX_AGG_CNT0_STRUC, *PTX_AGG_CNT0_STRUC;
+/* Debug counter */
+#define TX_AGG_CNT1	0x1724
+typedef union _TX_AGG_CNT1_STRUC {
+	struct {
+		u16 AggSize3Count;
+		u16 AggSize4Count;
+	} field;
+	u32 word;
+} TX_AGG_CNT1_STRUC, *PTX_AGG_CNT1_STRUC;
+#define TX_AGG_CNT2	0x1728
+typedef union _TX_AGG_CNT2_STRUC {
+	struct {
+		u16 AggSize5Count;
+		u16 AggSize6Count;
+	} field;
+	u32 word;
+} TX_AGG_CNT2_STRUC, *PTX_AGG_CNT2_STRUC;
+/* Debug counter */
+#define TX_AGG_CNT3	0x172c
+typedef union _TX_AGG_CNT3_STRUC {
+	struct {
+		u16 AggSize7Count;
+		u16 AggSize8Count;
+	} field;
+	u32 word;
+} TX_AGG_CNT3_STRUC, *PTX_AGG_CNT3_STRUC;
+/* Debug counter */
+#define TX_AGG_CNT4	0x1730
+typedef union _TX_AGG_CNT4_STRUC {
+	struct {
+		u16 AggSize9Count;
+		u16 AggSize10Count;
+	} field;
+	u32 word;
+} TX_AGG_CNT4_STRUC, *PTX_AGG_CNT4_STRUC;
+#define TX_AGG_CNT5	0x1734
+typedef union _TX_AGG_CNT5_STRUC {
+	struct {
+		u16 AggSize11Count;
+		u16 AggSize12Count;
+	} field;
+	u32 word;
+} TX_AGG_CNT5_STRUC, *PTX_AGG_CNT5_STRUC;
+#define TX_AGG_CNT6		0x1738
+typedef union _TX_AGG_CNT6_STRUC {
+	struct {
+		u16 AggSize13Count;
+		u16 AggSize14Count;
+	} field;
+	u32 word;
+} TX_AGG_CNT6_STRUC, *PTX_AGG_CNT6_STRUC;
+#define TX_AGG_CNT7		0x173c
+typedef union _TX_AGG_CNT7_STRUC {
+	struct {
+		u16 AggSize15Count;
+		u16 AggSize16Count;
+	} field;
+	u32 word;
+} TX_AGG_CNT7_STRUC, *PTX_AGG_CNT7_STRUC;
+#define MPDU_DENSITY_CNT		0x1740
+typedef union _MPDU_DEN_CNT_STRUC {
+	struct {
+		u16 TXZeroDelCount;	/*TX zero length delimiter count */
+		u16 RXZeroDelCount;	/*RX zero length delimiter count */
+	} field;
+	u32 word;
+} MPDU_DEN_CNT_STRUC, *PMPDU_DEN_CNT_STRUC;
+/* */
+/* TXRX control registers - base address 0x3000 */
+/* */
+/* rt2860b  UNKNOWN reg use R/O Reg Addr 0x77d0 first.. */
+#define TXRX_CSR1           0x77d0
+
+/* */
+/* Security key table memory, base address = 0x1000 */
+/* */
+#define MAC_WCID_BASE		0x1800	/*8-bytes(use only 6-bytes) * 256 entry = */
+#define HW_WCID_ENTRY_SIZE   8
+#define PAIRWISE_KEY_TABLE_BASE     0x4000	/* 32-byte * 256-entry =  -byte */
+#define HW_KEY_ENTRY_SIZE           0x20
+#define PAIRWISE_IVEIV_TABLE_BASE     0x6000	/* 8-byte * 256-entry =  -byte */
+#define MAC_IVEIV_TABLE_BASE     0x6000	/* 8-byte * 256-entry =  -byte */
+#define HW_IVEIV_ENTRY_SIZE   8
+#define MAC_WCID_ATTRIBUTE_BASE     0x6800	/* 4-byte * 256-entry =  -byte */
+#define HW_WCID_ATTRI_SIZE   4
+#define WCID_RESERVED			0x6bfc
+#define SHARED_KEY_TABLE_BASE       0x6c00	/* 32-byte * 16-entry = 512-byte */
+#define SHARED_KEY_MODE_BASE       0x7000	/* 32-byte * 16-entry = 512-byte */
+#define HW_SHARED_KEY_MODE_SIZE   4
+#define SHAREDKEYTABLE			0
+#define PAIRWISEKEYTABLE			1
+
+typedef union _SHAREDKEY_MODE_STRUC {
+	struct {
+		u32 Bss0Key0CipherAlg:3;
+		u32 : 1;
+		u32 Bss0Key1CipherAlg:3;
+		u32 : 1;
+		u32 Bss0Key2CipherAlg:3;
+		u32 : 1;
+		u32 Bss0Key3CipherAlg:3;
+		u32 : 1;
+		u32 Bss1Key0CipherAlg:3;
+		u32 : 1;
+		u32 Bss1Key1CipherAlg:3;
+		u32 : 1;
+		u32 Bss1Key2CipherAlg:3;
+		u32 : 1;
+		u32 Bss1Key3CipherAlg:3;
+		u32 : 1;
+	} field;
+	u32 word;
+} SHAREDKEY_MODE_STRUC, *PSHAREDKEY_MODE_STRUC;
+
+/* 8-byte per entry, 64-entry for pairwise key table */
+struct rt_hw_wcid_entry {
+	u8 Address[6];
+	u8 Rsv[2];
+};
+
+/* ================================================================================= */
+/* WCID  format */
+/* ================================================================================= */
+/*7.1   WCID  ENTRY  format  : 8bytes */
+struct rt_wcid_entry {
+	u8 RXBABitmap7;	/* bit0 for TID8, bit7 for TID 15 */
+	u8 RXBABitmap0;	/* bit0 for TID0, bit7 for TID 7 */
+	u8 MAC[6];		/* 0 for shared key table.  1 for pairwise key table */
+};
+
+/*8.1.1 SECURITY  KEY  format  : 8DW */
+/* 32-byte per entry, total 16-entry for shared key table, 64-entry for pairwise key table */
+struct rt_hw_key_entry {
+	u8 Key[16];
+	u8 TxMic[8];
+	u8 RxMic[8];
+};
+
+/*8.1.2 IV/EIV  format  : 2DW */
+
+/*8.1.3 RX attribute entry format  : 1DW */
+struct rt_mac_attribute {
+	u32 KeyTab:1;	/* 0 for shared key table.  1 for pairwise key table */
+	u32 PairKeyMode:3;
+	u32 BSSIDIdx:3;	/*multipleBSS index for the WCID */
+	u32 RXWIUDF:3;
+	u32 rsv:22;
+};
+
+/* ================================================================================= */
+/* HOST-MCU communication data structure */
+/* ================================================================================= */
+
+/* */
+/* H2M_MAILBOX_CSR: Host-to-MCU Mailbox */
+/* */
+typedef union _H2M_MAILBOX_STRUC {
+	struct {
+		u32 LowByte:8;
+		u32 HighByte:8;
+		u32 CmdToken:8;
+		u32 Owner:8;
+	} field;
+	u32 word;
+} H2M_MAILBOX_STRUC, *PH2M_MAILBOX_STRUC;
+
+/* */
+/* M2H_CMD_DONE_CSR: MCU-to-Host command complete indication */
+/* */
+typedef union _M2H_CMD_DONE_STRUC {
+	struct {
+		u32 CmdToken0;
+		u32 CmdToken1;
+		u32 CmdToken2;
+		u32 CmdToken3;
+	} field;
+	u32 word;
+} M2H_CMD_DONE_STRUC, *PM2H_CMD_DONE_STRUC;
+
+/*NAV_TIME_CFG :NAV */
+typedef union _NAV_TIME_CFG_STRUC {
+	struct {
+		u8 Sifs;	/* in unit of 1-us */
+		u8 SlotTime;	/* in unit of 1-us */
+		u16 Eifs:9;	/* in unit of 1-us */
+		u16 ZeroSifs:1;	/* Applied zero SIFS timer after OFDM RX 0: disable */
+		u16 rsv:6;
+	} field;
+	u32 word;
+} NAV_TIME_CFG_STRUC, *PNAV_TIME_CFG_STRUC;
+
+/* */
+/* RX_FILTR_CFG:  /RX configuration register */
+/* */
+typedef union _RX_FILTR_CFG_STRUC {
+	struct {
+		u32 DropCRCErr:1;	/* Drop CRC error */
+		u32 DropPhyErr:1;	/* Drop physical error */
+		u32 DropNotToMe:1;	/* Drop not to me unicast frame */
+		u32 DropNotMyBSSID:1;	/* Drop fram ToDs bit is true */
+
+		u32 DropVerErr:1;	/* Drop version error frame */
+		u32 DropMcast:1;	/* Drop multicast frames */
+		u32 DropBcast:1;	/* Drop broadcast frames */
+		u32 DropDuplicate:1;	/* Drop duplicate frame */
+
+		u32 DropCFEndAck:1;	/* Drop Ps-Poll */
+		u32 DropCFEnd:1;	/* Drop Ps-Poll */
+		u32 DropAck:1;	/* Drop Ps-Poll */
+		u32 DropCts:1;	/* Drop Ps-Poll */
+
+		u32 DropRts:1;	/* Drop Ps-Poll */
+		u32 DropPsPoll:1;	/* Drop Ps-Poll */
+		u32 DropBA:1;	/* */
+		u32 DropBAR:1;	/* */
+
+		u32 DropRsvCntlType:1;
+		u32 : 15;
+	} field;
+	u32 word;
+} RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC;
+
+/* */
+/* PHY_CSR4: RF serial control register */
+/* */
+typedef union _PHY_CSR4_STRUC {
+	struct {
+		u32 RFRegValue:24;	/* Register     value (include register id)     serial out to RF/IF     chip. */
+		u32 NumberOfBits:5;	/* Number of bits used in RFRegValue (I:20,     RFMD:22) */
+		u32 IFSelect:1;	/* 1: select IF to program,     0: select RF to program */
+		u32 PLL_LD:1;	/* RF PLL_LD status */
+		u32 Busy:1;	/* 1: ASIC is busy execute RF programming. */
+	} field;
+	u32 word;
+} PHY_CSR4_STRUC, *PPHY_CSR4_STRUC;
+
+/* */
+/* SEC_CSR5: shared key table security mode register */
+/* */
+typedef union _SEC_CSR5_STRUC {
+	struct {
+		u32 Bss2Key0CipherAlg:3;
+		u32 : 1;
+		u32 Bss2Key1CipherAlg:3;
+		u32 : 1;
+		u32 Bss2Key2CipherAlg:3;
+		u32 : 1;
+		u32 Bss2Key3CipherAlg:3;
+		u32 : 1;
+		u32 Bss3Key0CipherAlg:3;
+		u32 : 1;
+		u32 Bss3Key1CipherAlg:3;
+		u32 : 1;
+		u32 Bss3Key2CipherAlg:3;
+		u32 : 1;
+		u32 Bss3Key3CipherAlg:3;
+		u32 : 1;
+	} field;
+	u32 word;
+} SEC_CSR5_STRUC, *PSEC_CSR5_STRUC;
+
+/* */
+/* HOST_CMD_CSR: For HOST to interrupt embedded processor */
+/* */
+typedef union _HOST_CMD_CSR_STRUC {
+	struct {
+		u32 HostCommand:8;
+		u32 Rsv:24;
+	} field;
+	u32 word;
+} HOST_CMD_CSR_STRUC, *PHOST_CMD_CSR_STRUC;
+
+/* */
+/* AIFSN_CSR: AIFSN for each EDCA AC */
+/* */
+
+/* */
+/* E2PROM_CSR: EEPROM control register */
+/* */
+typedef union _E2PROM_CSR_STRUC {
+	struct {
+		u32 Reload:1;	/* Reload EEPROM content, write one to reload, self-cleared. */
+		u32 EepromSK:1;
+		u32 EepromCS:1;
+		u32 EepromDI:1;
+		u32 EepromDO:1;
+		u32 Type:1;	/* 1: 93C46, 0:93C66 */
+		u32 LoadStatus:1;	/* 1:loading, 0:done */
+		u32 Rsvd:25;
+	} field;
+	u32 word;
+} E2PROM_CSR_STRUC, *PE2PROM_CSR_STRUC;
+
+/* */
+/* QOS_CSR0: TXOP holder address0 register */
+/* */
+typedef union _QOS_CSR0_STRUC {
+	struct {
+		u8 Byte0;	/* MAC address byte 0 */
+		u8 Byte1;	/* MAC address byte 1 */
+		u8 Byte2;	/* MAC address byte 2 */
+		u8 Byte3;	/* MAC address byte 3 */
+	} field;
+	u32 word;
+} QOS_CSR0_STRUC, *PQOS_CSR0_STRUC;
+
+/* */
+/* QOS_CSR1: TXOP holder address1 register */
+/* */
+typedef union _QOS_CSR1_STRUC {
+	struct {
+		u8 Byte4;	/* MAC address byte 4 */
+		u8 Byte5;	/* MAC address byte 5 */
+		u8 Rsvd0;
+		u8 Rsvd1;
+	} field;
+	u32 word;
+} QOS_CSR1_STRUC, *PQOS_CSR1_STRUC;
+
+#define	RF_CSR_CFG	0x500
+typedef union _RF_CSR_CFG_STRUC {
+	struct {
+		u32 RF_CSR_DATA:8;	/* DATA */
+		u32 TESTCSR_RFACC_REGNUM:5;	/* RF register ID */
+		u32 Rsvd2:3;	/* Reserved */
+		u32 RF_CSR_WR:1;	/* 0: read  1: write */
+		u32 RF_CSR_KICK:1;	/* kick RF register read/write */
+		u32 Rsvd1:14;	/* Reserved */
+	} field;
+	u32 word;
+} RF_CSR_CFG_STRUC, *PRF_CSR_CFG_STRUC;
+
+/* */
+/* Other on-chip shared memory space, base = 0x2000 */
+/* */
+
+/* CIS space - base address = 0x2000 */
+#define HW_CIS_BASE             0x2000
+
+/* Carrier-sense CTS frame base address. It's where mac stores carrier-sense frame for carrier-sense function. */
+#define HW_CS_CTS_BASE			0x7700
+/* DFS CTS frame base address. It's where mac stores CTS frame for DFS. */
+#define HW_DFS_CTS_BASE			0x7780
+#define HW_CTS_FRAME_SIZE		0x80
+
+/* 2004-11-08 john - since NULL frame won't be that long (256 byte). We steal 16 tail bytes */
+/* to save debugging settings */
+#define HW_DEBUG_SETTING_BASE   0x77f0	/* 0x77f0~0x77ff total 16 bytes */
+#define HW_DEBUG_SETTING_BASE2   0x7770	/* 0x77f0~0x77ff total 16 bytes */
+
+/* In order to support maximum 8 MBSS and its maximum length is 512 for each beacon */
+/* Three section discontinue memory segments will be used. */
+/* 1. The original region for BCN 0~3 */
+/* 2. Extract memory from FCE table for BCN 4~5 */
+/* 3. Extract memory from Pair-wise key table for BCN 6~7 */
+/*        It occupied those memory of wcid 238~253 for BCN 6 */
+/*                                                    and wcid 222~237 for BCN 7 */
+#define HW_BEACON_MAX_SIZE      0x1000	/* unit: byte */
+#define HW_BEACON_BASE0         0x7800
+#define HW_BEACON_BASE1         0x7A00
+#define HW_BEACON_BASE2         0x7C00
+#define HW_BEACON_BASE3         0x7E00
+#define HW_BEACON_BASE4         0x7200
+#define HW_BEACON_BASE5         0x7400
+#define HW_BEACON_BASE6         0x5DC0
+#define HW_BEACON_BASE7         0x5BC0
+
+#define HW_BEACON_MAX_COUNT     8
+#define HW_BEACON_OFFSET		0x0200
+#define HW_BEACON_CONTENT_LEN	(HW_BEACON_OFFSET - TXWI_SIZE)
+
+/* HOST-MCU shared memory - base address = 0x2100 */
+#define HOST_CMD_CSR		0x404
+#define H2M_MAILBOX_CSR         0x7010
+#define H2M_MAILBOX_CID         0x7014
+#define H2M_MAILBOX_STATUS      0x701c
+#define H2M_INT_SRC             0x7024
+#define H2M_BBP_AGENT           0x7028
+#define M2H_CMD_DONE_CSR        0x000c
+#define MCU_TXOP_ARRAY_BASE     0x000c	/* TODO: to be provided by Albert */
+#define MCU_TXOP_ENTRY_SIZE     32	/* TODO: to be provided by Albert */
+#define MAX_NUM_OF_TXOP_ENTRY   16	/* TODO: must be same with 8051 firmware */
+#define MCU_MBOX_VERSION        0x01	/* TODO: to be confirmed by Albert */
+#define MCU_MBOX_VERSION_OFFSET 5	/* TODO: to be provided by Albert */
+
+/* */
+/* Host DMA registers - base address 0x200 .  TX0-3=EDCAQid0-3, TX4=HCCA, TX5=MGMT, */
+/* */
+/* */
+/*  DMA RING DESCRIPTOR */
+/* */
+#define E2PROM_CSR          0x0004
+#define IO_CNTL_CSR         0x77d0
+
+/* ================================================================ */
+/* Tx / Rx / Mgmt ring descriptor definition */
+/* ================================================================ */
+
+/* the following PID values are used to mark outgoing frame type in TXD->PID so that */
+/* proper TX statistics can be collected based on these categories */
+/* b3-2 of PID field - */
+#define PID_MGMT			0x05
+#define PID_BEACON			0x0c
+#define PID_DATA_NORMALUCAST		0x02
+#define PID_DATA_AMPDU		0x04
+#define PID_DATA_NO_ACK		0x08
+#define PID_DATA_NOT_NORM_ACK		0x03
+/* value domain of pTxD->HostQId (4-bit: 0~15) */
+#define QID_AC_BK               1	/* meet ACI definition in 802.11e */
+#define QID_AC_BE               0	/* meet ACI definition in 802.11e */
+#define QID_AC_VI               2
+#define QID_AC_VO               3
+#define QID_HCCA                4
+#define NUM_OF_TX_RING          4
+#define QID_MGMT                13
+#define QID_RX                  14
+#define QID_OTHER               15
+
+#endif /* __RTMP_MAC_H__ // */
diff --git a/drivers/staging/rt2860/chip/rtmp_phy.h b/drivers/staging/rt2860/chip/rtmp_phy.h
new file mode 100644
index 0000000..8b8b0f4
--- /dev/null
+++ b/drivers/staging/rt2860/chip/rtmp_phy.h
@@ -0,0 +1,556 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rtmp_phy.h
+
+	Abstract:
+	Ralink Wireless Chip PHY(BBP/RF) related definition & structures
+
+	Revision History:
+	Who			When		  What
+	--------	----------	  ----------------------------------------------
+*/
+
+#ifndef __RTMP_PHY_H__
+#define __RTMP_PHY_H__
+
+/*
+	RF sections
+*/
+#define RF_R00			0
+#define RF_R01			1
+#define RF_R02			2
+#define RF_R03			3
+#define RF_R04			4
+#define RF_R05			5
+#define RF_R06			6
+#define RF_R07			7
+#define RF_R08			8
+#define RF_R09			9
+#define RF_R10			10
+#define RF_R11			11
+#define RF_R12			12
+#define RF_R13			13
+#define RF_R14			14
+#define RF_R15			15
+#define RF_R16			16
+#define RF_R17			17
+#define RF_R18			18
+#define RF_R19			19
+#define RF_R20			20
+#define RF_R21			21
+#define RF_R22			22
+#define RF_R23			23
+#define RF_R24			24
+#define RF_R25			25
+#define RF_R26			26
+#define RF_R27			27
+#define RF_R28			28
+#define RF_R29			29
+#define RF_R30			30
+#define RF_R31			31
+
+/* value domain of pAd->RfIcType */
+#define RFIC_2820                   1	/* 2.4G 2T3R */
+#define RFIC_2850                   2	/* 2.4G/5G 2T3R */
+#define RFIC_2720                   3	/* 2.4G 1T2R */
+#define RFIC_2750                   4	/* 2.4G/5G 1T2R */
+#define RFIC_3020                   5	/* 2.4G 1T1R */
+#define RFIC_2020                   6	/* 2.4G B/G */
+#define RFIC_3021                   7	/* 2.4G 1T2R */
+#define RFIC_3022                   8	/* 2.4G 2T2R */
+#define RFIC_3052                   9	/* 2.4G/5G 2T2R */
+
+/*
+	BBP sections
+*/
+#define BBP_R0			0	/* version */
+#define BBP_R1			1	/* TSSI */
+#define BBP_R2			2	/* TX configure */
+#define BBP_R3			3
+#define BBP_R4			4
+#define BBP_R5			5
+#define BBP_R6			6
+#define BBP_R14			14	/* RX configure */
+#define BBP_R16			16
+#define BBP_R17			17	/* RX sensibility */
+#define BBP_R18			18
+#define BBP_R21			21
+#define BBP_R22			22
+#define BBP_R24			24
+#define BBP_R25			25
+#define BBP_R26			26
+#define BBP_R27			27
+#define BBP_R31			31
+#define BBP_R49			49	/*TSSI */
+#define BBP_R50			50
+#define BBP_R51			51
+#define BBP_R52			52
+#define BBP_R55			55
+#define BBP_R62			62	/* Rx SQ0 Threshold HIGH */
+#define BBP_R63			63
+#define BBP_R64			64
+#define BBP_R65			65
+#define BBP_R66			66
+#define BBP_R67			67
+#define BBP_R68			68
+#define BBP_R69			69
+#define BBP_R70			70	/* Rx AGC SQ CCK Xcorr threshold */
+#define BBP_R73			73
+#define BBP_R75			75
+#define BBP_R77			77
+#define BBP_R78			78
+#define BBP_R79			79
+#define BBP_R80			80
+#define BBP_R81			81
+#define BBP_R82			82
+#define BBP_R83			83
+#define BBP_R84			84
+#define BBP_R86			86
+#define BBP_R91			91
+#define BBP_R92			92
+#define BBP_R94			94	/* Tx Gain Control */
+#define BBP_R103		103
+#define BBP_R105		105
+#define BBP_R106		106
+#define BBP_R113		113
+#define BBP_R114		114
+#define BBP_R115		115
+#define BBP_R116		116
+#define BBP_R117		117
+#define BBP_R118		118
+#define BBP_R119		119
+#define BBP_R120		120
+#define BBP_R121		121
+#define BBP_R122		122
+#define BBP_R123		123
+#ifdef RT30xx
+#define BBP_R138		138	/* add by johnli, RF power sequence setup, ADC dynamic on/off control */
+#endif /* RT30xx // */
+
+#define BBPR94_DEFAULT	0x06	/* Add 1 value will gain 1db */
+
+/* */
+/* BBP & RF are using indirect access. Before write any value into it. */
+/* We have to make sure there is no outstanding command pending via checking busy bit. */
+/* */
+#define MAX_BUSY_COUNT  100	/* Number of retry before failing access BBP & RF indirect register */
+
+/*#define PHY_TR_SWITCH_TIME          5  // usec */
+
+/*#define BBP_R17_LOW_SENSIBILITY     0x50 */
+/*#define BBP_R17_MID_SENSIBILITY     0x41 */
+/*#define BBP_R17_DYNAMIC_UP_BOUND    0x40 */
+
+#define RSSI_FOR_VERY_LOW_SENSIBILITY   -35
+#define RSSI_FOR_LOW_SENSIBILITY		-58
+#define RSSI_FOR_MID_LOW_SENSIBILITY	-80
+#define RSSI_FOR_MID_SENSIBILITY		-90
+
+/*****************************************************************************
+	RF register Read/Write marco definition
+ *****************************************************************************/
+#ifdef RTMP_MAC_PCI
+#define RTMP_RF_IO_WRITE32(_A, _V)                  \
+{											\
+	if ((_A)->bPCIclkOff == FALSE)	                \
+	{												\
+		PHY_CSR4_STRUC  _value;                          \
+		unsigned long           _busyCnt = 0;                    \
+											\
+		do {                                            \
+			RTMP_IO_READ32((_A), RF_CSR_CFG0, &_value.word);  \
+			if (_value.field.Busy == IDLE)               \
+				break;                                  \
+			_busyCnt++;                                  \
+		}while (_busyCnt < MAX_BUSY_COUNT);			\
+		if(_busyCnt < MAX_BUSY_COUNT)                   \
+		{                                               \
+			RTMP_IO_WRITE32((_A), RF_CSR_CFG0, (_V));          \
+		}                                               \
+	}								\
+}
+#endif /* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
+#define RTMP_RF_IO_WRITE32(_A, _V)                 RTUSBWriteRFRegister(_A, _V)
+#endif /* RTMP_MAC_USB // */
+
+#ifdef RT30xx
+#define RTMP_RF_IO_READ8_BY_REG_ID(_A, _I, _pV)    RT30xxReadRFRegister(_A, _I, _pV)
+#define RTMP_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V)    RT30xxWriteRFRegister(_A, _I, _V)
+#endif /* RT30xx // */
+
+/*****************************************************************************
+	BBP register Read/Write marco definitions.
+	we read/write the bbp value by register's ID.
+	Generate PER to test BA
+ *****************************************************************************/
+#ifdef RTMP_MAC_PCI
+/*
+	basic marco for BBP read operation.
+	_pAd: the data structure pointer of struct rt_rtmp_adapter
+	_bbpID : the bbp register ID
+	_pV: data pointer used to save the value of queried bbp register.
+	_bViaMCU: if we need access the bbp via the MCU.
+*/
+#define RTMP_BBP_IO_READ8(_pAd, _bbpID, _pV, _bViaMCU)			\
+	do{															\
+		BBP_CSR_CFG_STRUC  BbpCsr;								\
+		int   _busyCnt, _secCnt, _regID;						\
+																\
+		_regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG);	\
+		for (_busyCnt=0; _busyCnt<MAX_BUSY_COUNT; _busyCnt++)      \
+		{													\
+			RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word);		\
+			if (BbpCsr.field.Busy == BUSY)                  \
+				continue;                                               \
+			BbpCsr.word = 0;                                \
+			BbpCsr.field.fRead = 1;                         \
+			BbpCsr.field.BBP_RW_MODE = 1;                         \
+			BbpCsr.field.Busy = 1;                          \
+			BbpCsr.field.RegNum = _bbpID;                       \
+			RTMP_IO_WRITE32(_pAd, _regID, BbpCsr.word);     \
+			if ((_bViaMCU) == TRUE)							\
+			{													\
+				AsicSendCommandToMcu(_pAd, 0x80, 0xff, 0x0, 0x0); \
+				RTMPusecDelay(1000);	\
+			}							\
+			for (_secCnt=0; _secCnt<MAX_BUSY_COUNT; _secCnt++)       \
+			{                                               \
+				RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word); \
+				if (BbpCsr.field.Busy == IDLE)              \
+					break;                                  \
+			}                                               \
+			if ((BbpCsr.field.Busy == IDLE) &&              \
+				(BbpCsr.field.RegNum == _bbpID))                \
+			{                                               \
+				*(_pV) = (u8)BbpCsr.field.Value;         \
+				break;                                      \
+			}                                               \
+		}                                                   \
+		if (BbpCsr.field.Busy == BUSY)                      \
+		{                                                   \
+			DBGPRINT_ERR(("BBP(viaMCU=%d) read R%d fail\n", (_bViaMCU), _bbpID));      \
+			*(_pV) = (_pAd)->BbpWriteLatch[_bbpID];               \
+			if ((_bViaMCU) == TRUE)				\
+			{									\
+				RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word);				\
+				BbpCsr.field.Busy = 0;                          \
+				RTMP_IO_WRITE32(_pAd, _regID, BbpCsr.word);				\
+			}				\
+		}													\
+	}while(0)
+
+/*
+	This marco used for the BBP read operation which didn't need via MCU.
+*/
+#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)			\
+	RTMP_BBP_IO_READ8((_A), (_I), (_pV), FALSE)
+
+/*
+	This marco used for the BBP read operation which need via MCU.
+	But for some chipset which didn't have mcu (e.g., RBUS based chipset), we
+	will use this function too and didn't access the bbp register via the MCU.
+*/
+/* Read BBP register by register's ID. Generate PER to test BA */
+#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)						\
+{																		\
+	BBP_CSR_CFG_STRUC	BbpCsr;											\
+	int					i, k;			\
+	BOOLEAN					brc;			\
+	BbpCsr.field.Busy = IDLE;			\
+	if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3)	\
+		&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE)	\
+		&& ((_A)->bPCIclkOff == FALSE)	\
+		&& ((_A)->brt30xxBanMcuCmd == FALSE))	\
+	{																	\
+		for (i=0; i<MAX_BUSY_COUNT; i++)									\
+		{																	\
+			RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);				\
+			if (BbpCsr.field.Busy == BUSY)									\
+			{																\
+				continue;													\
+			}																\
+			BbpCsr.word = 0;												\
+			BbpCsr.field.fRead = 1;											\
+			BbpCsr.field.BBP_RW_MODE = 1;									\
+			BbpCsr.field.Busy = 1;											\
+			BbpCsr.field.RegNum = _I;										\
+			RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
+			brc = AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0);					\
+			if (brc == TRUE)																\
+			{																\
+				for (k=0; k<MAX_BUSY_COUNT; k++)								\
+				{																\
+					RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);			\
+					if (BbpCsr.field.Busy == IDLE)								\
+						break;													\
+				}																\
+				if ((BbpCsr.field.Busy == IDLE) &&								\
+					(BbpCsr.field.RegNum == _I))								\
+				{																\
+					*(_pV) = (u8)BbpCsr.field.Value;							\
+					break;														\
+				}																\
+			}																\
+			else																\
+			{																\
+				BbpCsr.field.Busy = 0;											\
+				RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
+			}																\
+		}																	\
+	}	\
+	else if (!((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3)	\
+		&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE))	\
+		&& ((_A)->bPCIclkOff == FALSE))	\
+	{																	\
+		for (i=0; i<MAX_BUSY_COUNT; i++)									\
+		{																	\
+			RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);				\
+			if (BbpCsr.field.Busy == BUSY)									\
+			{																\
+				continue;													\
+			}																\
+			BbpCsr.word = 0;												\
+			BbpCsr.field.fRead = 1;											\
+			BbpCsr.field.BBP_RW_MODE = 1;									\
+			BbpCsr.field.Busy = 1;											\
+			BbpCsr.field.RegNum = _I;										\
+			RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
+			AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0);					\
+			for (k=0; k<MAX_BUSY_COUNT; k++)								\
+			{																\
+				RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);			\
+				if (BbpCsr.field.Busy == IDLE)								\
+					break;													\
+			}																\
+			if ((BbpCsr.field.Busy == IDLE) &&								\
+				(BbpCsr.field.RegNum == _I))								\
+			{																\
+				*(_pV) = (u8)BbpCsr.field.Value;							\
+				break;														\
+			}																\
+		}																	\
+	}																	\
+	else										\
+	{																	\
+		DBGPRINT_ERR((" , brt30xxBanMcuCmd = %d, Read BBP %d \n", (_A)->brt30xxBanMcuCmd, (_I)));	\
+		*(_pV) = (_A)->BbpWriteLatch[_I];								\
+	}																	\
+	if ((BbpCsr.field.Busy == BUSY) || ((_A)->bPCIclkOff == TRUE))										\
+	{																	\
+		DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", _I, BbpCsr.word));	\
+		*(_pV) = (_A)->BbpWriteLatch[_I];								\
+	}																	\
+}
+
+/*
+	basic marco for BBP write operation.
+	_pAd: the data structure pointer of struct rt_rtmp_adapter
+	_bbpID : the bbp register ID
+	_pV: data used to save the value of queried bbp register.
+	_bViaMCU: if we need access the bbp via the MCU.
+*/
+#define RTMP_BBP_IO_WRITE8(_pAd, _bbpID, _pV, _bViaMCU)			\
+	do{															\
+		BBP_CSR_CFG_STRUC  BbpCsr;                             \
+		int             _busyCnt, _regID;							\
+																\
+		_regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG);	\
+		for (_busyCnt=0; _busyCnt<MAX_BUSY_COUNT; _busyCnt++)  \
+		{                                                   \
+			RTMP_IO_READ32((_pAd), BBP_CSR_CFG, &BbpCsr.word);     \
+			if (BbpCsr.field.Busy == BUSY)                  \
+				continue;                                   \
+			BbpCsr.word = 0;                                \
+			BbpCsr.field.fRead = 0;                         \
+			BbpCsr.field.BBP_RW_MODE = 1;                         \
+			BbpCsr.field.Busy = 1;                          \
+			BbpCsr.field.Value = _pV;                        \
+			BbpCsr.field.RegNum = _bbpID;                       \
+			RTMP_IO_WRITE32((_pAd), BBP_CSR_CFG, BbpCsr.word);     \
+			if ((_bViaMCU) == TRUE)									\
+			{														\
+				AsicSendCommandToMcu(_pAd, 0x80, 0xff, 0x0, 0x0);		\
+				if ((_pAd)->OpMode == OPMODE_AP)						\
+					RTMPusecDelay(1000);							\
+			}														\
+			(_pAd)->BbpWriteLatch[_bbpID] = _pV;					\
+			break;													\
+		}														\
+		if (_busyCnt == MAX_BUSY_COUNT)								\
+		{														\
+			DBGPRINT_ERR(("BBP write R%d fail\n", _bbpID));				\
+			if((_bViaMCU) == TRUE)									\
+			{														\
+				RTMP_IO_READ32(_pAd, H2M_BBP_AGENT, &BbpCsr.word);	\
+				BbpCsr.field.Busy = 0;									\
+				RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, BbpCsr.word);	\
+			}														\
+		}														\
+	}while(0)
+
+/*
+	This marco used for the BBP write operation which didn't need via MCU.
+*/
+#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _pV)			\
+	RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), FALSE)
+
+/*
+	This marco used for the BBP write operation which need via MCU.
+	But for some chipset which didn't have mcu (e.g., RBUS based chipset), we
+	will use this function too and didn't access the bbp register via the MCU.
+*/
+/* Write BBP register by register's ID & value */
+#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)						\
+{																		\
+	BBP_CSR_CFG_STRUC	BbpCsr;											\
+	int					BusyCnt = 0;										\
+	BOOLEAN					brc;			\
+	if (_I < MAX_NUM_OF_BBP_LATCH)										\
+	{																	\
+		if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3)	\
+			&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE)	\
+			&& ((_A)->bPCIclkOff == FALSE)	\
+			&& ((_A)->brt30xxBanMcuCmd == FALSE))	\
+		{																	\
+			if (_A->AccessBBPFailCount > 20)									\
+			{																	\
+				AsicResetBBPAgent(_A);				\
+				_A->AccessBBPFailCount = 0;											\
+			}																	\
+			for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++)					\
+			{																	\
+				RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);				\
+				if (BbpCsr.field.Busy == BUSY)									\
+					continue;													\
+				BbpCsr.word = 0;												\
+				BbpCsr.field.fRead = 0;											\
+				BbpCsr.field.BBP_RW_MODE = 1;									\
+				BbpCsr.field.Busy = 1;											\
+				BbpCsr.field.Value = _V;										\
+				BbpCsr.field.RegNum = _I;										\
+				RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
+				brc = AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0);					\
+				if (brc == TRUE)																\
+				{																\
+					(_A)->BbpWriteLatch[_I] = _V;									\
+				}																\
+				else																\
+				{																\
+					BbpCsr.field.Busy = 0;											\
+					RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
+				}																\
+				break;															\
+			}																	\
+		}																	\
+		else if (!((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3)	\
+			&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE))	\
+			&& ((_A)->bPCIclkOff == FALSE))	\
+		{																	\
+			if (_A->AccessBBPFailCount > 20)									\
+			{																	\
+				AsicResetBBPAgent(_A);				\
+				_A->AccessBBPFailCount = 0;											\
+			}																	\
+			for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++)					\
+			{																	\
+				RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);				\
+				if (BbpCsr.field.Busy == BUSY)									\
+					continue;													\
+				BbpCsr.word = 0;												\
+				BbpCsr.field.fRead = 0;											\
+				BbpCsr.field.BBP_RW_MODE = 1;									\
+				BbpCsr.field.Busy = 1;											\
+				BbpCsr.field.Value = _V;										\
+				BbpCsr.field.RegNum = _I;										\
+				RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
+				AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0);					\
+				(_A)->BbpWriteLatch[_I] = _V;									\
+				break;															\
+			}																	\
+		}																	\
+		else										\
+		{																	\
+			DBGPRINT_ERR(("  brt30xxBanMcuCmd = %d. Write BBP %d \n",  (_A)->brt30xxBanMcuCmd, (_I)));	\
+		}																	\
+		if ((BusyCnt == MAX_BUSY_COUNT) || ((_A)->bPCIclkOff == TRUE))			\
+		{																	\
+			if (BusyCnt == MAX_BUSY_COUNT)					\
+				(_A)->AccessBBPFailCount++;					\
+			DBGPRINT_ERR(("BBP write R%d=0x%x fail. BusyCnt= %d.bPCIclkOff = %d. \n", _I, BbpCsr.word, BusyCnt, (_A)->bPCIclkOff ));	\
+		}																	\
+	}																		\
+	else																		\
+	{																		\
+		DBGPRINT_ERR(("****** BBP_Write_Latch Buffer exceeds max boundry ****** \n"));	\
+	}																		\
+}
+#endif /* RTMP_MAC_PCI // */
+
+#ifdef RTMP_MAC_USB
+#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)   RTUSBReadBBPRegister(_A, _I, _pV)
+#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)   RTUSBWriteBBPRegister(_A, _I, _V)
+
+#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)			RTUSBWriteBBPRegister(_A, _I, _V)
+#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)		RTUSBReadBBPRegister(_A, _I, _pV)
+#endif /* RTMP_MAC_USB // */
+
+#ifdef RT30xx
+#define RTMP_ASIC_MMPS_DISABLE(_pAd)							\
+	do{															\
+		u32 _macData; \
+		u8 _bbpData = 0; \
+		/* disable MMPS BBP control register */						\
+		RTMP_BBP_IO_READ8_BY_REG_ID(_pAd, BBP_R3, &_bbpData);	\
+		_bbpData &= ~(0x04);	/*bit 2*/								\
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData);	\
+																\
+		/* disable MMPS MAC control register */						\
+		RTMP_IO_READ32(_pAd, 0x1210, &_macData);				\
+		_macData &= ~(0x09);	/*bit 0, 3*/							\
+		RTMP_IO_WRITE32(_pAd, 0x1210, _macData);				\
+	}while(0)
+
+#define RTMP_ASIC_MMPS_ENABLE(_pAd)							\
+	do{															\
+		u32 _macData; \
+		u8 _bbpData = 0; \
+		/* enable MMPS BBP control register */						\
+		RTMP_BBP_IO_READ8_BY_REG_ID(_pAd, BBP_R3, &_bbpData);	\
+		_bbpData |= (0x04);	/*bit 2*/								\
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData);	\
+																\
+		/* enable MMPS MAC control register */						\
+		RTMP_IO_READ32(_pAd, 0x1210, &_macData);				\
+		_macData |= (0x09);	/*bit 0, 3*/							\
+		RTMP_IO_WRITE32(_pAd, 0x1210, _macData);				\
+	}while(0)
+
+#endif /* RT30xx // */
+
+#endif /* __RTMP_PHY_H__ // */
diff --git a/drivers/staging/rt2860/chips/rt3070.c b/drivers/staging/rt2860/chips/rt3070.c
new file mode 100644
index 0000000..627bad9
--- /dev/null
+++ b/drivers/staging/rt2860/chips/rt3070.c
@@ -0,0 +1,169 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rt3070.c
+
+	Abstract:
+	Specific funcitons and variables for RT3070
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+#ifdef RT3070
+
+#include "../rt_config.h"
+
+#ifndef RTMP_RF_RW_SUPPORT
+#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip"
+#endif /* RTMP_RF_RW_SUPPORT // */
+
+void NICInitRT3070RFRegisters(struct rt_rtmp_adapter *pAd)
+{
+	int i;
+	u8 RFValue;
+
+	/* Driver must read EEPROM to get RfIcType before initial RF registers */
+	/* Initialize RF register to default value */
+	if (IS_RT3070(pAd) || IS_RT3071(pAd)) {
+		/* Init RF calibration */
+		/* Driver should toggle RF R30 bit7 before init RF registers */
+		u32 RfReg = 0;
+		u32 data;
+
+		RT30xxReadRFRegister(pAd, RF_R30, (u8 *)& RfReg);
+		RfReg |= 0x80;
+		RT30xxWriteRFRegister(pAd, RF_R30, (u8)RfReg);
+		RTMPusecDelay(1000);
+		RfReg &= 0x7F;
+		RT30xxWriteRFRegister(pAd, RF_R30, (u8)RfReg);
+
+		/* Initialize RF register to default value */
+		for (i = 0; i < NUM_RF_REG_PARMS; i++) {
+			RT30xxWriteRFRegister(pAd,
+					      RT30xx_RFRegTable[i].Register,
+					      RT30xx_RFRegTable[i].Value);
+		}
+
+		/* add by johnli */
+		if (IS_RT3070(pAd)) {
+			/* */
+			/* The DAC issue(LDO_CFG0) has been fixed in RT3070(F). */
+			/* The voltage raising patch is no longer needed for RT3070(F) */
+			/* */
+			if ((pAd->MACVersion & 0xffff) < 0x0201) {
+				/*  Update MAC 0x05D4 from 01xxxxxx to 0Dxxxxxx (voltage 1.2V to 1.35V) for RT3070 to improve yield rate */
+				RTUSBReadMACRegister(pAd, LDO_CFG0, &data);
+				data = ((data & 0xF0FFFFFF) | 0x0D000000);
+				RTUSBWriteMACRegister(pAd, LDO_CFG0, data);
+			}
+		} else if (IS_RT3071(pAd)) {
+			/* Driver should set RF R6 bit6 on before init RF registers */
+			RT30xxReadRFRegister(pAd, RF_R06, (u8 *)& RfReg);
+			RfReg |= 0x40;
+			RT30xxWriteRFRegister(pAd, RF_R06, (u8)RfReg);
+
+			/* init R31 */
+			RT30xxWriteRFRegister(pAd, RF_R31, 0x14);
+
+			/* RT3071 version E has fixed this issue */
+			if ((pAd->NicConfig2.field.DACTestBit == 1)
+			    && ((pAd->MACVersion & 0xffff) < 0x0211)) {
+				/* patch tx EVM issue temporarily */
+				RTUSBReadMACRegister(pAd, LDO_CFG0, &data);
+				data = ((data & 0xE0FFFFFF) | 0x0D000000);
+				RTUSBWriteMACRegister(pAd, LDO_CFG0, data);
+			} else {
+				RTMP_IO_READ32(pAd, LDO_CFG0, &data);
+				data = ((data & 0xE0FFFFFF) | 0x01000000);
+				RTMP_IO_WRITE32(pAd, LDO_CFG0, data);
+			}
+
+			/* patch LNA_PE_G1 failed issue */
+			RTUSBReadMACRegister(pAd, GPIO_SWITCH, &data);
+			data &= ~(0x20);
+			RTUSBWriteMACRegister(pAd, GPIO_SWITCH, data);
+		}
+		/*For RF filter Calibration */
+		RTMPFilterCalibration(pAd);
+
+		/* Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration() */
+		/* */
+		/* TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F). */
+		/* Raising RF voltage is no longer needed for RT3070(F) */
+		/* */
+		if ((IS_RT3070(pAd)) && ((pAd->MACVersion & 0xffff) < 0x0201)) {
+			RT30xxWriteRFRegister(pAd, RF_R27, 0x3);
+		} else if ((IS_RT3071(pAd))
+			   && ((pAd->MACVersion & 0xffff) < 0x0211)) {
+			RT30xxWriteRFRegister(pAd, RF_R27, 0x3);
+		}
+		/* set led open drain enable */
+		RTUSBReadMACRegister(pAd, OPT_14, &data);
+		data |= 0x01;
+		RTUSBWriteMACRegister(pAd, OPT_14, data);
+
+		/* move from RT30xxLoadRFNormalModeSetup because it's needed for both RT3070 and RT3071 */
+		/* TX_LO1_en, RF R17 register Bit 3 to 0 */
+		RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
+		RFValue &= (~0x08);
+		/* to fix rx long range issue */
+		if (pAd->NicConfig2.field.ExternalLNAForG == 0) {
+			if ((IS_RT3071(pAd)
+			     && ((pAd->MACVersion & 0xffff) >= 0x0211))
+			    || IS_RT3070(pAd)) {
+				RFValue |= 0x20;
+			}
+		}
+		/* set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h */
+		if (pAd->TxMixerGain24G >= 1) {
+			RFValue &= (~0x7);	/* clean bit [2:0] */
+			RFValue |= pAd->TxMixerGain24G;
+		}
+		RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
+
+		if (IS_RT3071(pAd)) {
+			/* add by johnli, RF power sequence setup, load RF normal operation-mode setup */
+			RT30xxLoadRFNormalModeSetup(pAd);
+		} else if (IS_RT3070(pAd)) {
+			/* add by johnli, reset RF_R27 when interface down & up to fix throughput problem */
+			/* LDORF_VC, RF R27 register Bit 2 to 0 */
+			RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
+			/* TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F). */
+			/* Raising RF voltage is no longer needed for RT3070(F) */
+			if ((pAd->MACVersion & 0xffff) < 0x0201)
+				RFValue = (RFValue & (~0x77)) | 0x3;
+			else
+				RFValue = (RFValue & (~0x77));
+			RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
+			/* end johnli */
+		}
+	}
+
+}
+#endif /* RT3070 // */
diff --git a/drivers/staging/rt2860/chips/rt3090.c b/drivers/staging/rt2860/chips/rt3090.c
new file mode 100644
index 0000000..5927ba4
--- /dev/null
+++ b/drivers/staging/rt2860/chips/rt3090.c
@@ -0,0 +1,119 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rt3090.c
+
+	Abstract:
+	Specific funcitons and variables for RT3070
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+#ifdef RT3090
+
+#include "../rt_config.h"
+
+#ifndef RTMP_RF_RW_SUPPORT
+#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip"
+#endif /* RTMP_RF_RW_SUPPORT // */
+
+void NICInitRT3090RFRegisters(struct rt_rtmp_adapter *pAd)
+{
+	int i;
+	/* Driver must read EEPROM to get RfIcType before initial RF registers */
+	/* Initialize RF register to default value */
+	if (IS_RT3090(pAd)) {
+		/* Init RF calibration */
+		/* Driver should toggle RF R30 bit7 before init RF registers */
+		u32 RfReg = 0, data;
+
+		RT30xxReadRFRegister(pAd, RF_R30, (u8 *)& RfReg);
+		RfReg |= 0x80;
+		RT30xxWriteRFRegister(pAd, RF_R30, (u8)RfReg);
+		RTMPusecDelay(1000);
+		RfReg &= 0x7F;
+		RT30xxWriteRFRegister(pAd, RF_R30, (u8)RfReg);
+
+		/* init R24, R31 */
+		RT30xxWriteRFRegister(pAd, RF_R24, 0x0F);
+		RT30xxWriteRFRegister(pAd, RF_R31, 0x0F);
+
+		/* RT309x version E has fixed this issue */
+		if ((pAd->NicConfig2.field.DACTestBit == 1)
+		    && ((pAd->MACVersion & 0xffff) < 0x0211)) {
+			/* patch tx EVM issue temporarily */
+			RTMP_IO_READ32(pAd, LDO_CFG0, &data);
+			data = ((data & 0xE0FFFFFF) | 0x0D000000);
+			RTMP_IO_WRITE32(pAd, LDO_CFG0, data);
+		} else {
+			RTMP_IO_READ32(pAd, LDO_CFG0, &data);
+			data = ((data & 0xE0FFFFFF) | 0x01000000);
+			RTMP_IO_WRITE32(pAd, LDO_CFG0, data);
+		}
+
+		/* patch LNA_PE_G1 failed issue */
+		RTMP_IO_READ32(pAd, GPIO_SWITCH, &data);
+		data &= ~(0x20);
+		RTMP_IO_WRITE32(pAd, GPIO_SWITCH, data);
+
+		/* Initialize RF register to default value */
+		for (i = 0; i < NUM_RF_REG_PARMS; i++) {
+			RT30xxWriteRFRegister(pAd,
+					      RT30xx_RFRegTable[i].Register,
+					      RT30xx_RFRegTable[i].Value);
+		}
+
+		/* Driver should set RF R6 bit6 on before calibration */
+		RT30xxReadRFRegister(pAd, RF_R06, (u8 *)& RfReg);
+		RfReg |= 0x40;
+		RT30xxWriteRFRegister(pAd, RF_R06, (u8)RfReg);
+
+		/*For RF filter Calibration */
+		RTMPFilterCalibration(pAd);
+
+		/* Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration() */
+		if ((pAd->MACVersion & 0xffff) < 0x0211)
+			RT30xxWriteRFRegister(pAd, RF_R27, 0x3);
+
+		/* set led open drain enable */
+		RTMP_IO_READ32(pAd, OPT_14, &data);
+		data |= 0x01;
+		RTMP_IO_WRITE32(pAd, OPT_14, data);
+
+		/* set default antenna as main */
+		if (pAd->RfIcType == RFIC_3020)
+			AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
+
+		/* add by johnli, RF power sequence setup, load RF normal operation-mode setup */
+		RT30xxLoadRFNormalModeSetup(pAd);
+	}
+
+}
+
+#endif /* RT3090 // */
diff --git a/drivers/staging/rt2860/chips/rt30xx.c b/drivers/staging/rt2860/chips/rt30xx.c
new file mode 100644
index 0000000..6e684a3
--- /dev/null
+++ b/drivers/staging/rt2860/chips/rt30xx.c
@@ -0,0 +1,518 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rt30xx.c
+
+	Abstract:
+	Specific funcitons and variables for RT30xx.
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+#ifdef RT30xx
+
+#ifndef RTMP_RF_RW_SUPPORT
+#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip"
+#endif /* RTMP_RF_RW_SUPPORT // */
+
+#include "../rt_config.h"
+
+/* */
+/* RF register initialization set */
+/* */
+struct rt_reg_pair RT30xx_RFRegTable[] = {
+	{RF_R04, 0x40}
+	,
+	{RF_R05, 0x03}
+	,
+	{RF_R06, 0x02}
+	,
+	{RF_R07, 0x70}
+	,
+	{RF_R09, 0x0F}
+	,
+	{RF_R10, 0x41}
+	,
+	{RF_R11, 0x21}
+	,
+	{RF_R12, 0x7B}
+	,
+	{RF_R14, 0x90}
+	,
+	{RF_R15, 0x58}
+	,
+	{RF_R16, 0xB3}
+	,
+	{RF_R17, 0x92}
+	,
+	{RF_R18, 0x2C}
+	,
+	{RF_R19, 0x02}
+	,
+	{RF_R20, 0xBA}
+	,
+	{RF_R21, 0xDB}
+	,
+	{RF_R24, 0x16}
+	,
+	{RF_R25, 0x01}
+	,
+	{RF_R29, 0x1F}
+	,
+};
+
+u8 NUM_RF_REG_PARMS = (sizeof(RT30xx_RFRegTable) / sizeof(struct rt_reg_pair));
+
+/* Antenna divesity use GPIO3 and EESK pin for control */
+/* Antenna and EEPROM access are both using EESK pin, */
+/* Therefor we should avoid accessing EESK at the same time */
+/* Then restore antenna after EEPROM access */
+/* The original name of this function is AsicSetRxAnt(), now change to */
+/*void AsicSetRxAnt( */
+void RT30xxSetRxAnt(struct rt_rtmp_adapter *pAd, u8 Ant)
+{
+	u32 Value;
+#ifdef RTMP_MAC_PCI
+	u32 x;
+#endif
+
+	if ((pAd->EepromAccess) ||
+	    (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) ||
+	    (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) ||
+	    (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) ||
+	    (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) {
+		return;
+	}
+	/* the antenna selection is through firmware and MAC register(GPIO3) */
+	if (Ant == 0) {
+		/* Main antenna */
+#ifdef RTMP_MAC_PCI
+		RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+		x |= (EESK);
+		RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+#else
+		AsicSendCommandToMcu(pAd, 0x73, 0xFF, 0x1, 0x0);
+#endif /* RTMP_MAC_PCI // */
+
+		RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
+		Value &= ~(0x0808);
+		RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
+		DBGPRINT_RAW(RT_DEBUG_TRACE,
+			     ("AsicSetRxAnt, switch to main antenna\n"));
+	} else {
+		/* Aux antenna */
+#ifdef RTMP_MAC_PCI
+		RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+		x &= ~(EESK);
+		RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+#else
+		AsicSendCommandToMcu(pAd, 0x73, 0xFF, 0x0, 0x0);
+#endif /* RTMP_MAC_PCI // */
+		RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
+		Value &= ~(0x0808);
+		Value |= 0x08;
+		RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
+		DBGPRINT_RAW(RT_DEBUG_TRACE,
+			     ("AsicSetRxAnt, switch to aux antenna\n"));
+	}
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		For RF filter calibration purpose
+
+	Arguments:
+		pAd                          Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+
+	========================================================================
+*/
+void RTMPFilterCalibration(struct rt_rtmp_adapter *pAd)
+{
+	u8 R55x = 0, value, FilterTarget = 0x1E, BBPValue = 0;
+	u32 loop = 0, count = 0, loopcnt = 0, ReTry = 0;
+	u8 RF_R24_Value = 0;
+
+	/* Give bbp filter initial value */
+	pAd->Mlme.CaliBW20RfR24 = 0x1F;
+	pAd->Mlme.CaliBW40RfR24 = 0x2F;	/*Bit[5] must be 1 for BW 40 */
+
+	do {
+		if (loop == 1)	/*BandWidth = 40 MHz */
+		{
+			/* Write 0x27 to RF_R24 to program filter */
+			RF_R24_Value = 0x27;
+			RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
+			if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
+				FilterTarget = 0x15;
+			else
+				FilterTarget = 0x19;
+
+			/* when calibrate BW40, BBP mask must set to BW40. */
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+			BBPValue &= (~0x18);
+			BBPValue |= (0x10);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+
+			/* set to BW40 */
+			RT30xxReadRFRegister(pAd, RF_R31, &value);
+			value |= 0x20;
+			RT30xxWriteRFRegister(pAd, RF_R31, value);
+		} else		/*BandWidth = 20 MHz */
+		{
+			/* Write 0x07 to RF_R24 to program filter */
+			RF_R24_Value = 0x07;
+			RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
+			if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
+				FilterTarget = 0x13;
+			else
+				FilterTarget = 0x16;
+
+			/* set to BW20 */
+			RT30xxReadRFRegister(pAd, RF_R31, &value);
+			value &= (~0x20);
+			RT30xxWriteRFRegister(pAd, RF_R31, value);
+		}
+
+		/* Write 0x01 to RF_R22 to enable baseband loopback mode */
+		RT30xxReadRFRegister(pAd, RF_R22, &value);
+		value |= 0x01;
+		RT30xxWriteRFRegister(pAd, RF_R22, value);
+
+		/* Write 0x00 to BBP_R24 to set power & frequency of passband test tone */
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
+
+		do {
+			/* Write 0x90 to BBP_R25 to transmit test tone */
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
+
+			RTMPusecDelay(1000);
+			/* Read BBP_R55[6:0] for received power, set R55x = BBP_R55[6:0] */
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
+			R55x = value & 0xFF;
+
+		} while ((ReTry++ < 100) && (R55x == 0));
+
+		/* Write 0x06 to BBP_R24 to set power & frequency of stopband test tone */
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0x06);
+
+		while (TRUE) {
+			/* Write 0x90 to BBP_R25 to transmit test tone */
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
+
+			/*We need to wait for calibration */
+			RTMPusecDelay(1000);
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
+			value &= 0xFF;
+			if ((R55x - value) < FilterTarget) {
+				RF_R24_Value++;
+			} else if ((R55x - value) == FilterTarget) {
+				RF_R24_Value++;
+				count++;
+			} else {
+				break;
+			}
+
+			/* prevent infinite loop cause driver hang. */
+			if (loopcnt++ > 100) {
+				DBGPRINT(RT_DEBUG_ERROR,
+					 ("RTMPFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating",
+					  loopcnt));
+				break;
+			}
+			/* Write RF_R24 to program filter */
+			RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
+		}
+
+		if (count > 0) {
+			RF_R24_Value = RF_R24_Value - ((count) ? (1) : (0));
+		}
+		/* Store for future usage */
+		if (loopcnt < 100) {
+			if (loop++ == 0) {
+				/*BandWidth = 20 MHz */
+				pAd->Mlme.CaliBW20RfR24 = (u8)RF_R24_Value;
+			} else {
+				/*BandWidth = 40 MHz */
+				pAd->Mlme.CaliBW40RfR24 = (u8)RF_R24_Value;
+				break;
+			}
+		} else
+			break;
+
+		RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
+
+		/* reset count */
+		count = 0;
+	} while (TRUE);
+
+	/* */
+	/* Set back to initial state */
+	/* */
+	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
+
+	RT30xxReadRFRegister(pAd, RF_R22, &value);
+	value &= ~(0x01);
+	RT30xxWriteRFRegister(pAd, RF_R22, value);
+
+	/* set BBP back to BW20 */
+	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+	BBPValue &= (~0x18);
+	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("RTMPFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n",
+		  pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24));
+}
+
+/* add by johnli, RF power sequence setup */
+/*
+	==========================================================================
+	Description:
+
+	Load RF normal operation-mode setup
+
+	==========================================================================
+ */
+void RT30xxLoadRFNormalModeSetup(struct rt_rtmp_adapter *pAd)
+{
+	u8 RFValue;
+
+	/* RX0_PD & TX0_PD, RF R1 register Bit 2 & Bit 3 to 0 and RF_BLOCK_en,RX1_PD & TX1_PD, Bit0, Bit 4 & Bit5 to 1 */
+	RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
+	RFValue = (RFValue & (~0x0C)) | 0x31;
+	RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
+
+	/* TX_LO2_en, RF R15 register Bit 3 to 0 */
+	RT30xxReadRFRegister(pAd, RF_R15, &RFValue);
+	RFValue &= (~0x08);
+	RT30xxWriteRFRegister(pAd, RF_R15, RFValue);
+
+	/* move to NICInitRT30xxRFRegisters
+	   // TX_LO1_en, RF R17 register Bit 3 to 0
+	   RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
+	   RFValue &= (~0x08);
+	   // to fix rx long range issue
+	   if (((pAd->MACVersion & 0xffff) >= 0x0211) && (pAd->NicConfig2.field.ExternalLNAForG == 0))
+	   {
+	   RFValue |= 0x20;
+	   }
+	   // set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h
+	   if (pAd->TxMixerGain24G >= 2)
+	   {
+	   RFValue &= (~0x7);  // clean bit [2:0]
+	   RFValue |= pAd->TxMixerGain24G;
+	   }
+	   RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
+	 */
+
+	/* RX_LO1_en, RF R20 register Bit 3 to 0 */
+	RT30xxReadRFRegister(pAd, RF_R20, &RFValue);
+	RFValue &= (~0x08);
+	RT30xxWriteRFRegister(pAd, RF_R20, RFValue);
+
+	/* RX_LO2_en, RF R21 register Bit 3 to 0 */
+	RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
+	RFValue &= (~0x08);
+	RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
+
+	/* add by johnli, reset RF_R27 when interface down & up to fix throughput problem */
+	/* LDORF_VC, RF R27 register Bit 2 to 0 */
+	RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
+	/* TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F). */
+	/* Raising RF voltage is no longer needed for RT3070(F) */
+	if (IS_RT3090(pAd))	/* RT309x and RT3071/72 */
+	{
+		if ((pAd->MACVersion & 0xffff) < 0x0211)
+			RFValue = (RFValue & (~0x77)) | 0x3;
+		else
+			RFValue = (RFValue & (~0x77));
+		RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
+	}
+	/* end johnli */
+}
+
+/*
+	==========================================================================
+	Description:
+
+	Load RF sleep-mode setup
+
+	==========================================================================
+ */
+void RT30xxLoadRFSleepModeSetup(struct rt_rtmp_adapter *pAd)
+{
+	u8 RFValue;
+	u32 MACValue;
+
+#ifdef RTMP_MAC_USB
+	if (!IS_RT3572(pAd))
+#endif /* RTMP_MAC_USB // */
+	{
+		/* RF_BLOCK_en. RF R1 register Bit 0 to 0 */
+		RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
+		RFValue &= (~0x01);
+		RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
+
+		/* VCO_IC, RF R7 register Bit 4 & Bit 5 to 0 */
+		RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
+		RFValue &= (~0x30);
+		RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
+
+		/* Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 0 */
+		RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
+		RFValue &= (~0x0E);
+		RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
+
+		/* RX_CTB_en, RF R21 register Bit 7 to 0 */
+		RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
+		RFValue &= (~0x80);
+		RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
+	}
+
+	if (IS_RT3090(pAd) ||	/* IS_RT3090 including RT309x and RT3071/72 */
+	    IS_RT3572(pAd) ||
+	    (IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201))) {
+#ifdef RTMP_MAC_USB
+		if (!IS_RT3572(pAd))
+#endif /* RTMP_MAC_USB // */
+		{
+			RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
+			RFValue |= 0x77;
+			RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
+		}
+
+		RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
+		MACValue |= 0x1D000000;
+		RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
+	}
+}
+
+/*
+	==========================================================================
+	Description:
+
+	Reverse RF sleep-mode setup
+
+	==========================================================================
+ */
+void RT30xxReverseRFSleepModeSetup(struct rt_rtmp_adapter *pAd)
+{
+	u8 RFValue;
+	u32 MACValue;
+
+#ifdef RTMP_MAC_USB
+	if (!IS_RT3572(pAd))
+#endif /* RTMP_MAC_USB // */
+	{
+		/* RF_BLOCK_en, RF R1 register Bit 0 to 1 */
+		RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
+		RFValue |= 0x01;
+		RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
+
+		/* VCO_IC, RF R7 register Bit 4 & Bit 5 to 1 */
+		RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
+		RFValue |= 0x30;
+		RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
+
+		/* Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1 */
+		RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
+		RFValue |= 0x0E;
+		RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
+
+		/* RX_CTB_en, RF R21 register Bit 7 to 1 */
+		RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
+		RFValue |= 0x80;
+		RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
+	}
+
+	if (IS_RT3090(pAd) ||	/* IS_RT3090 including RT309x and RT3071/72 */
+	    IS_RT3572(pAd) ||
+	    IS_RT3390(pAd) ||
+	    (IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201))) {
+#ifdef RTMP_MAC_USB
+		if (!IS_RT3572(pAd))
+#endif /* RTMP_MAC_USB // */
+		{
+			RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
+			if ((pAd->MACVersion & 0xffff) < 0x0211)
+				RFValue = (RFValue & (~0x77)) | 0x3;
+			else
+				RFValue = (RFValue & (~0x77));
+			RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
+		}
+		/* RT3071 version E has fixed this issue */
+		if ((pAd->NicConfig2.field.DACTestBit == 1)
+		    && ((pAd->MACVersion & 0xffff) < 0x0211)) {
+			/* patch tx EVM issue temporarily */
+			RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
+			MACValue = ((MACValue & 0xE0FFFFFF) | 0x0D000000);
+			RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
+		} else {
+			RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
+			MACValue = ((MACValue & 0xE0FFFFFF) | 0x01000000);
+			RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
+		}
+	}
+
+	if (IS_RT3572(pAd))
+		RT30xxWriteRFRegister(pAd, RF_R08, 0x80);
+}
+
+/* end johnli */
+
+void RT30xxHaltAction(struct rt_rtmp_adapter *pAd)
+{
+	u32 TxPinCfg = 0x00050F0F;
+
+	/* */
+	/* Turn off LNA_PE or TRSW_POL */
+	/* */
+	if (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3572(pAd)) {
+		if ((IS_RT3071(pAd) || IS_RT3572(pAd))
+#ifdef RTMP_EFUSE_SUPPORT
+		    && (pAd->bUseEfuse)
+#endif /* RTMP_EFUSE_SUPPORT // */
+		    ) {
+			TxPinCfg &= 0xFFFBF0F0;	/* bit18 off */
+		} else {
+			TxPinCfg &= 0xFFFFF0F0;
+		}
+
+		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+	}
+}
+
+#endif /* RT30xx // */
diff --git a/drivers/staging/rt2860/chlist.h b/drivers/staging/rt2860/chlist.h
index f49a35c..ada65e5 100644
--- a/drivers/staging/rt2860/chlist.h
+++ b/drivers/staging/rt2860/chlist.h
@@ -41,7 +41,6 @@
 #include "rtmp_type.h"
 #include "rtmp_def.h"
 
-
 #define ODOR			0
 #define IDOR			1
 #define BOTH			2
@@ -50,1196 +49,69 @@
 #define BAND_24G        1
 #define BAND_BOTH       2
 
-typedef struct _CH_DESP {
-	UCHAR FirstChannel;
-	UCHAR NumOfCh;
-	CHAR MaxTxPwr;			// dBm
-	UCHAR Geography;			// 0:out door, 1:in door, 2:both
-	BOOLEAN DfsReq;			// Dfs require, 0: No, 1: yes.
-} CH_DESP, *PCH_DESP;
-
-typedef struct _CH_REGION {
-	UCHAR CountReg[3];
-	UCHAR DfsType;			// 0: CE, 1: FCC, 2: JAP, 3:JAP_W53, JAP_W56
-	CH_DESP ChDesp[10];
-} CH_REGION, *PCH_REGION;
-
-static CH_REGION ChRegion[] =
-{
-		{	// Antigua and Berbuda
-			"AG",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  23, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Argentina
-			"AR",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149, 4,  30, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Aruba
-			"AW",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  23, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Australia
-			"AU",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149, 5,  30, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Austria
-			"AT",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, IDOR, TRUE},		// 5G, ch 36~48
-				{ 52,  4,  23, IDOR, TRUE},		// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, TRUE},		// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Bahamas
-			"BS",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149, 5,  30, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Barbados
-			"BB",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Bermuda
-			"BM",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Brazil
-			"BR",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11, 24, BOTH, FALSE},	// 5G, ch 100~140
-				{ 149, 5,  30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Belgium
-			"BE",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  18, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  18, IDOR, FALSE},	// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// Bulgaria
-			"BG",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11, 30, ODOR, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Canada
-			"CA",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  23, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149, 5,  30, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Cayman IsLands
-			"KY",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Chile
-			"CL",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  20, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  20, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149, 5,  20, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// China
-			"CN",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 149, 4,  27, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Colombia
-			"CO",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  17, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 149, 5,  30, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Costa Rica
-			"CR",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  17, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149, 4,  30, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Cyprus
-			"CY",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, IDOR, TRUE},		// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, TRUE},		// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Czech_Republic
-			"CZ",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  23, IDOR, TRUE},		// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// Denmark
-			"DK",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  23, IDOR, TRUE},		// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, TRUE},		// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Dominican Republic
-			"DO",
-			CE,
-			{
-				{ 1,   0,  20, BOTH, FALSE},	// 2.4 G, ch 0
-				{ 149, 4,  20, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Equador
-			"EC",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 100, 11,  27, BOTH, FALSE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// El Salvador
-			"SV",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,   23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   30, BOTH, TRUE},	// 5G, ch 52~64
-				{ 149, 4,   36, BOTH, TRUE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Finland
-			"FI",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,   23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// France
-			"FR",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,   23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// Germany
-			"DE",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,   23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Greece
-			"GR",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,   23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, ODOR, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Guam
-			"GU",
-			CE,
-			{
-				{ 1,   11,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 36,  4,   17, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 149,  5,  30, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Guatemala
-			"GT",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,   17, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149,  4,  30, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Haiti
-			"HT",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,   17, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149,  4,  30, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Honduras
-			"HN",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 149,  4,  27, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Hong Kong
-			"HK",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, FALSE},	// 5G, ch 52~64
-				{ 149,  4,  30, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Hungary
-			"HU",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// Iceland
-			"IS",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// India
-			"IN",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 149, 	4,  24, IDOR, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Indonesia
-			"ID",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 149, 	4,  27, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Ireland
-			"IE",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52, 	4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, ODOR, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Israel
-			"IL",
-			CE,
-			{
-				{ 1,    3,  20, IDOR, FALSE},	// 2.4 G, ch 1~3
-				{ 4, 	6,  20, BOTH, FALSE},	// 2.4 G, ch 4~9
-				{ 10, 	4,  20, IDOR, FALSE},	// 2.4 G, ch 10~13
-				{ 0},							// end
-			}
-		},
-
-		{	// Italy
-			"IT",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52, 	4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, ODOR, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Japan
-			"JP",
-			JAP,
-			{
-				{ 1,   14,  20, BOTH, FALSE},	// 2.4 G, ch 1~14
-				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 0},							// end
-			}
-		},
-
-		{	// Jordan
-			"JO",
-			CE,
-			{
-				{ 1,   13,  20, IDOR, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 149, 	4,  23, IDOR, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Latvia
-			"LV",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52, 	4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Liechtenstein
-			"LI",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 52, 	4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Lithuania
-			"LT",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52, 	4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Luxemburg
-			"LU",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52, 	4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Malaysia
-			"MY",
-			CE,
-			{
-				{ 36, 	4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52, 	4,  23, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149,  5,  20, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Malta
-			"MT",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52, 	4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Marocco
-			"MA",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  24, IDOR, FALSE},	// 5G, ch 36~48
-				{ 0},							// end
-			}
-		},
-
-		{	// Mexico
-			"MX",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52, 	4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149,  5,  30, IDOR, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Netherlands
-			"NL",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52, 	4,  24, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// New Zealand
-			"NZ",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  24, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52, 	4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149,  4,  30, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Norway
-			"NO",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  24, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52, 	4,  24, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Peru
-			"PE",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 149,  4,  27, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Portugal
-			"PT",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Poland
-			"PL",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Romania
-			"RO",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Russia
-			"RU",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 149,  4,  20, IDOR, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Saudi Arabia
-			"SA",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149,  4,  23, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Serbia_and_Montenegro
-			"CS",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 0},							// end
-			}
-		},
-
-		{	// Singapore
-			"SG",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149,  4,  20, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Slovakia
-			"SK",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Slovenia
-			"SI",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// South Africa
-			"ZA",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, FALSE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 149,  4,  30, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// South Korea
-			"KR",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  20, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  20, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100,  8,  20, BOTH, FALSE},	// 5G, ch 100~128
-				{ 149,  4,  20, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Spain
-			"ES",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  17, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Sweden
-			"SE",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Switzerland
-			"CH",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, TRUE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// Taiwan
-			"TW",
-			CE,
-			{
-				{ 1,   11,  30, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 52,   4,  23, IDOR, FALSE},	// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// Turkey
-			"TR",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 36,   4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, BOTH, FALSE},	// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// UK
-			"GB",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 52~64
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Ukraine
-			"UA",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 0},							// end
-			}
-		},
-
-		{	// United_Arab_Emirates
-			"AE",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 0},							// end
-			}
-		},
-
-		{	// United_States
-			"US",
-			CE,
-			{
-				{ 1,   11,  30, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 36,   4,  17, IDOR, FALSE},	// 5G, ch 52~64
-				{ 52,   4,  24, BOTH, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 149,  5,  30, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Venezuela
-			"VE",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 149,  4,  27, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Default
-			"",
-			CE,
-			{
-				{ 1,   11,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 36,   4,  20, BOTH, FALSE},	// 5G, ch 52~64
-				{ 52,   4,  20, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11,  20, BOTH, FALSE},	// 5G, ch 100~140
-				{ 149,  5,  20, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
+struct rt_ch_desp {
+	u8 FirstChannel;
+	u8 NumOfCh;
+	char MaxTxPwr;		/* dBm */
+	u8 Geography;	/* 0:out door, 1:in door, 2:both */
+	BOOLEAN DfsReq;		/* Dfs require, 0: No, 1: yes. */
 };
 
-static inline PCH_REGION GetChRegion(
-	IN PUCHAR CntryCode)
-{
-	INT loop = 0;
-	PCH_REGION pChRegion = NULL;
+struct rt_ch_region {
+	u8 CountReg[3];
+	u8 DfsType;		/* 0: CE, 1: FCC, 2: JAP, 3:JAP_W53, JAP_W56 */
+	struct rt_ch_desp ChDesp[10];
+};
 
-	while (strcmp(ChRegion[loop].CountReg, "") != 0)
-	{
-		if (strncmp(ChRegion[loop].CountReg, CntryCode, 2) == 0)
-		{
-			pChRegion = &ChRegion[loop];
-			break;
-		}
-		loop++;
-	}
+extern struct rt_ch_region ChRegion[];
 
-	if (pChRegion == NULL)
-		pChRegion = &ChRegion[loop];
-	return pChRegion;
-}
+struct rt_ch_freq_map {
+	u16 channel;
+	u16 freqKHz;
+};
 
-static inline VOID ChBandCheck(
-	IN UCHAR PhyMode,
-	OUT PUCHAR pChType)
-{
-	switch(PhyMode)
-	{
-		case PHY_11A:
-		case PHY_11AN_MIXED:
-			*pChType = BAND_5G;
-			break;
-		case PHY_11ABG_MIXED:
-		case PHY_11AGN_MIXED:
-		case PHY_11ABGN_MIXED:
-			*pChType = BAND_BOTH;
-			break;
+extern struct rt_ch_freq_map CH_HZ_ID_MAP[];
+extern int CH_HZ_ID_MAP_NUM;
 
-		default:
-			*pChType = BAND_24G;
-			break;
-	}
-}
+#define     MAP_CHANNEL_ID_TO_KHZ(_ch, _khz)					\
+		do{													\
+			int _chIdx;											\
+			for (_chIdx = 0; _chIdx < CH_HZ_ID_MAP_NUM; _chIdx++)\
+			{													\
+				if ((_ch) == CH_HZ_ID_MAP[_chIdx].channel)			\
+				{												\
+					(_khz) = CH_HZ_ID_MAP[_chIdx].freqKHz * 1000;	\
+					break;										\
+				}												\
+			}													\
+			if (_chIdx == CH_HZ_ID_MAP_NUM)					\
+				(_khz) = 2412000;									\
+            }while(0)
 
-static inline UCHAR FillChList(
-	IN PRTMP_ADAPTER pAd,
-	IN PCH_DESP pChDesp,
-	IN UCHAR Offset,
-	IN UCHAR increment)
-{
-	INT i, j, l;
-	UCHAR channel;
+#define     MAP_KHZ_TO_CHANNEL_ID(_khz, _ch)                 \
+		do{													\
+			int _chIdx;											\
+			for (_chIdx = 0; _chIdx < CH_HZ_ID_MAP_NUM; _chIdx++)\
+			{													\
+				if ((_khz) == CH_HZ_ID_MAP[_chIdx].freqKHz)			\
+				{												\
+					(_ch) = CH_HZ_ID_MAP[_chIdx].channel;			\
+					break;										\
+				}												\
+			}													\
+			if (_chIdx == CH_HZ_ID_MAP_NUM)					\
+				(_ch) = 1;											\
+		}while(0)
 
-	j = Offset;
-	for (i = 0; i < pChDesp->NumOfCh; i++)
-	{
-		channel = pChDesp->FirstChannel + i * increment;
-		for (l=0; l<MAX_NUM_OF_CHANNELS; l++)
-		{
-			if (channel == pAd->TxPower[l].Channel)
-			{
-				pAd->ChannelList[j].Power = pAd->TxPower[l].Power;
-				pAd->ChannelList[j].Power2 = pAd->TxPower[l].Power2;
-				break;
-			}
-		}
-		if (l == MAX_NUM_OF_CHANNELS)
-			continue;
+void BuildChannelListEx(struct rt_rtmp_adapter *pAd);
 
-		pAd->ChannelList[j].Channel = pChDesp->FirstChannel + i * increment;
-		pAd->ChannelList[j].MaxTxPwr = pChDesp->MaxTxPwr;
-		pAd->ChannelList[j].DfsReq = pChDesp->DfsReq;
-		j++;
-	}
-	pAd->ChannelListNum = j;
+void BuildBeaconChList(struct rt_rtmp_adapter *pAd,
+		       u8 *pBuf, unsigned long *pBufLen);
 
-	return j;
-}
+void N_ChannelCheck(struct rt_rtmp_adapter *pAd);
 
-static inline VOID CreateChList(
-	IN PRTMP_ADAPTER pAd,
-	IN PCH_REGION pChRegion,
-	IN UCHAR Geography)
-{
-	INT i;
-	UCHAR offset = 0;
-	PCH_DESP pChDesp;
-	UCHAR ChType;
-	UCHAR increment;
+void N_SetCenCh(struct rt_rtmp_adapter *pAd);
 
-	if (pChRegion == NULL)
-		return;
+u8 GetCuntryMaxTxPwr(struct rt_rtmp_adapter *pAd, u8 channel);
 
-	ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
-
-	for (i=0; i<10; i++)
-	{
-		pChDesp = &pChRegion->ChDesp[i];
-		if (pChDesp->FirstChannel == 0)
-			break;
-
-		if (ChType == BAND_5G)
-		{
-			if (pChDesp->FirstChannel <= 14)
-				continue;
-		}
-		else if (ChType == BAND_24G)
-		{
-			if (pChDesp->FirstChannel > 14)
-				continue;
-		}
-
-		if ((pChDesp->Geography == BOTH)
-			|| (pChDesp->Geography == Geography))
-        {
-			if (pChDesp->FirstChannel > 14)
-                increment = 4;
-            else
-                increment = 1;
-			offset = FillChList(pAd, pChDesp, offset, increment);
-        }
-	}
-}
-
-static inline VOID BuildChannelListEx(
-	IN PRTMP_ADAPTER pAd)
-{
-	PCH_REGION pChReg;
-
-	pChReg = GetChRegion(pAd->CommonCfg.CountryCode);
-	CreateChList(pAd, pChReg, pAd->CommonCfg.Geography);
-}
-
-static inline VOID BuildBeaconChList(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pBuf,
-	OUT	PULONG pBufLen)
-{
-	INT i;
-	ULONG TmpLen;
-	PCH_REGION pChRegion;
-	PCH_DESP pChDesp;
-	UCHAR ChType;
-
-	pChRegion = GetChRegion(pAd->CommonCfg.CountryCode);
-
-	if (pChRegion == NULL)
-		return;
-
-	ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
-	*pBufLen = 0;
-
-	for (i=0; i<10; i++)
-	{
-		pChDesp = &pChRegion->ChDesp[i];
-		if (pChDesp->FirstChannel == 0)
-			break;
-
-		if (ChType == BAND_5G)
-		{
-			if (pChDesp->FirstChannel <= 14)
-				continue;
-		}
-		else if (ChType == BAND_24G)
-		{
-			if (pChDesp->FirstChannel > 14)
-				continue;
-		}
-
-		if ((pChDesp->Geography == BOTH)
-			|| (pChDesp->Geography == pAd->CommonCfg.Geography))
-		{
-			MakeOutgoingFrame(pBuf + *pBufLen,		&TmpLen,
-								1,                 	&pChDesp->FirstChannel,
-								1,                 	&pChDesp->NumOfCh,
-								1,                 	&pChDesp->MaxTxPwr,
-								END_OF_ARGS);
-			*pBufLen += TmpLen;
-		}
-	}
-}
-
-static inline BOOLEAN IsValidChannel(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR channel)
-
-{
-	INT i;
-
-	for (i = 0; i < pAd->ChannelListNum; i++)
-	{
-		if (pAd->ChannelList[i].Channel == channel)
-			break;
-	}
-
-	if (i == pAd->ChannelListNum)
-		return FALSE;
-	else
-		return TRUE;
-}
-
-
-static inline UCHAR GetExtCh(
-	IN UCHAR Channel,
-	IN UCHAR Direction)
-{
-	CHAR ExtCh;
-
-	if (Direction == EXTCHA_ABOVE)
-		ExtCh = Channel + 4;
-	else
-		ExtCh = (Channel - 4) > 0 ? (Channel - 4) : 0;
-
-	return ExtCh;
-}
-
-
-static inline VOID N_ChannelCheck(
-	IN PRTMP_ADAPTER pAd)
-{
-	//UCHAR ChannelNum = pAd->ChannelListNum;
-	UCHAR Channel = pAd->CommonCfg.Channel;
-
-	if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->CommonCfg.RegTransmitSetting.field.BW  == BW_40))
-	{
-		if (Channel > 14)
-		{
-			if ((Channel == 36) || (Channel == 44) || (Channel == 52) || (Channel == 60) || (Channel == 100) || (Channel == 108) ||
-			    (Channel == 116) || (Channel == 124) || (Channel == 132) || (Channel == 149) || (Channel == 157))
-			{
-				pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
-			}
-			else if ((Channel == 40) || (Channel == 48) || (Channel == 56) || (Channel == 64) || (Channel == 104) || (Channel == 112) ||
-					(Channel == 120) || (Channel == 128) || (Channel == 136) || (Channel == 153) || (Channel == 161))
-			{
-				pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
-			}
-			else
-			{
-				pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_20;
-			}
-		}
-		else
-		{
-			do
-			{
-				UCHAR ExtCh;
-				UCHAR Dir = pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
-				ExtCh = GetExtCh(Channel, Dir);
-				if (IsValidChannel(pAd, ExtCh))
-					break;
-
-				Dir = (Dir == EXTCHA_ABOVE) ? EXTCHA_BELOW : EXTCHA_ABOVE;
-				ExtCh = GetExtCh(Channel, Dir);
-				if (IsValidChannel(pAd, ExtCh))
-				{
-					pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = Dir;
-					break;
-				}
-				pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_20;
-			} while(FALSE);
-
-			if (Channel == 14)
-			{
-				pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_20;
-				//pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_NONE;	// We didn't set the ExtCh as NONE due to it'll set in RTMPSetHT()
-			}
-		}
-	}
-
-
-}
-
-
-static inline VOID N_SetCenCh(
-	IN PRTMP_ADAPTER pAd)
-{
-	if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
-	{
-		if (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
-		{
-			pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
-		}
-		else
-		{
-			if (pAd->CommonCfg.Channel == 14)
-				pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 1;
-			else
-				pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
-		}
-	}
-	else
-	{
-		pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
-	}
-}
-
-static inline UINT8 GetCuntryMaxTxPwr(
-	IN PRTMP_ADAPTER pAd,
-	IN UINT8 channel)
-{
-	int i;
-	for (i = 0; i < pAd->ChannelListNum; i++)
-	{
-		if (pAd->ChannelList[i].Channel == channel)
-			break;
-	}
-
-	if (i == pAd->ChannelListNum)
-		return 0xff;
-	else
-		return pAd->ChannelList[i].MaxTxPwr;
-}
-#endif // __CHLIST_H__
-
+#endif /* __CHLIST_H__ */
diff --git a/drivers/staging/rt2860/common/2860_rtmp_init.c b/drivers/staging/rt2860/common/2860_rtmp_init.c
deleted file mode 100644
index 0bc0fb9..0000000
--- a/drivers/staging/rt2860/common/2860_rtmp_init.c
+++ /dev/null
@@ -1,897 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	2860_rtmp_init.c
-
-	Abstract:
-	Miniport generic portion header file
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-	Paul Lin    2002-08-01    created
-    John Chang  2004-08-20    RT2561/2661 use scatter-gather scheme
-    Jan Lee  2006-09-15    RT2860. Change for 802.11n , EEPROM, Led, BA, HT.
-*/
-#include "../rt_config.h"
-
-
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Allocate DMA memory blocks for send, receive
-
-	Arguments:
-		Adapter		Pointer to our adapter
-
-	Return Value:
-		NDIS_STATUS_SUCCESS
-		NDIS_STATUS_FAILURE
-		NDIS_STATUS_RESOURCES
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-NDIS_STATUS	RTMPAllocTxRxRingMemory(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	NDIS_STATUS		Status = NDIS_STATUS_SUCCESS;
-	ULONG			RingBasePaHigh;
-	ULONG			RingBasePaLow;
-	PVOID			RingBaseVa;
-	INT				index, num;
-	PTXD_STRUC		pTxD;
-	PRXD_STRUC		pRxD;
-	ULONG			ErrorValue = 0;
-	PRTMP_TX_RING	pTxRing;
-	PRTMP_DMABUF	pDmaBuf;
-	PNDIS_PACKET	pPacket;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
-	do
-	{
-		//
-		// Allocate all ring descriptors, include TxD, RxD, MgmtD.
-		// Although each size is different, to prevent cacheline and alignment
-		// issue, I intentional set them all to 64 bytes.
-		//
-		for (num=0; num<NUM_OF_TX_RING; num++)
-		{
-			ULONG  BufBasePaHigh;
-			ULONG  BufBasePaLow;
-			PVOID  BufBaseVa;
-
-			//
-			// Allocate Tx ring descriptor's memory (5 TX rings = 4 ACs + 1 HCCA)
-			//
-			pAd->TxDescRing[num].AllocSize = TX_RING_SIZE * TXD_SIZE;
-			RTMP_AllocateTxDescMemory(
-				pAd,
-				num,
-				pAd->TxDescRing[num].AllocSize,
-				FALSE,
-				&pAd->TxDescRing[num].AllocVa,
-				&pAd->TxDescRing[num].AllocPa);
-
-			if (pAd->TxDescRing[num].AllocVa == NULL)
-			{
-				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
-				DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
-				Status = NDIS_STATUS_RESOURCES;
-				break;
-			}
-
-			// Zero init this memory block
-			NdisZeroMemory(pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocSize);
-
-			// Save PA & VA for further operation
-			RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxDescRing[num].AllocPa);
-			RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->TxDescRing[num].AllocPa);
-			RingBaseVa     = pAd->TxDescRing[num].AllocVa;
-
-			//
-			// Allocate all 1st TXBuf's memory for this TxRing
-			//
-			pAd->TxBufSpace[num].AllocSize = TX_RING_SIZE * TX_DMA_1ST_BUFFER_SIZE;
-			RTMP_AllocateFirstTxBuffer(
-				pAd,
-				num,
-				pAd->TxBufSpace[num].AllocSize,
-				FALSE,
-				&pAd->TxBufSpace[num].AllocVa,
-				&pAd->TxBufSpace[num].AllocPa);
-
-			if (pAd->TxBufSpace[num].AllocVa == NULL)
-			{
-				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
-				DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
-				Status = NDIS_STATUS_RESOURCES;
-				break;
-			}
-
-			// Zero init this memory block
-			NdisZeroMemory(pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocSize);
-
-			// Save PA & VA for further operation
-			BufBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxBufSpace[num].AllocPa);
-			BufBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->TxBufSpace[num].AllocPa);
-			BufBaseVa     = pAd->TxBufSpace[num].AllocVa;
-
-			//
-			// Initialize Tx Ring Descriptor and associated buffer memory
-			//
-			pTxRing = &pAd->TxRing[num];
-			for (index = 0; index < TX_RING_SIZE; index++)
-			{
-				pTxRing->Cell[index].pNdisPacket = NULL;
-				pTxRing->Cell[index].pNextNdisPacket = NULL;
-				// Init Tx Ring Size, Va, Pa variables
-				pTxRing->Cell[index].AllocSize = TXD_SIZE;
-				pTxRing->Cell[index].AllocVa = RingBaseVa;
-				RTMP_SetPhysicalAddressHigh(pTxRing->Cell[index].AllocPa, RingBasePaHigh);
-				RTMP_SetPhysicalAddressLow (pTxRing->Cell[index].AllocPa, RingBasePaLow);
-
-				// Setup Tx Buffer size & address. only 802.11 header will store in this space
-				pDmaBuf = &pTxRing->Cell[index].DmaBuf;
-				pDmaBuf->AllocSize = TX_DMA_1ST_BUFFER_SIZE;
-				pDmaBuf->AllocVa = BufBaseVa;
-				RTMP_SetPhysicalAddressHigh(pDmaBuf->AllocPa, BufBasePaHigh);
-				RTMP_SetPhysicalAddressLow(pDmaBuf->AllocPa, BufBasePaLow);
-
-				// link the pre-allocated TxBuf to TXD
-				pTxD = (PTXD_STRUC) pTxRing->Cell[index].AllocVa;
-				pTxD->SDPtr0 = BufBasePaLow;
-				// advance to next ring descriptor address
-				pTxD->DMADONE = 1;
-				RingBasePaLow += TXD_SIZE;
-				RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE;
-
-				// advance to next TxBuf address
-				BufBasePaLow += TX_DMA_1ST_BUFFER_SIZE;
-				BufBaseVa = (PUCHAR) BufBaseVa + TX_DMA_1ST_BUFFER_SIZE;
-			}
-			DBGPRINT(RT_DEBUG_TRACE, ("TxRing[%d]: total %d entry allocated\n", num, index));
-		}
-		if (Status == NDIS_STATUS_RESOURCES)
-			break;
-
-		//
-		// Allocate MGMT ring descriptor's memory except Tx ring which allocated eariler
-		//
-		pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * TXD_SIZE;
-		RTMP_AllocateMgmtDescMemory(
-			pAd,
-			pAd->MgmtDescRing.AllocSize,
-			FALSE,
-			&pAd->MgmtDescRing.AllocVa,
-			&pAd->MgmtDescRing.AllocPa);
-
-		if (pAd->MgmtDescRing.AllocVa == NULL)
-		{
-			ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
-			DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
-			Status = NDIS_STATUS_RESOURCES;
-			break;
-		}
-
-		// Zero init this memory block
-		NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
-
-		// Save PA & VA for further operation
-		RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->MgmtDescRing.AllocPa);
-		RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->MgmtDescRing.AllocPa);
-		RingBaseVa     = pAd->MgmtDescRing.AllocVa;
-
-		//
-		// Initialize MGMT Ring and associated buffer memory
-		//
-		for (index = 0; index < MGMT_RING_SIZE; index++)
-		{
-			pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
-			pAd->MgmtRing.Cell[index].pNextNdisPacket = NULL;
-			// Init MGMT Ring Size, Va, Pa variables
-			pAd->MgmtRing.Cell[index].AllocSize = TXD_SIZE;
-			pAd->MgmtRing.Cell[index].AllocVa = RingBaseVa;
-			RTMP_SetPhysicalAddressHigh(pAd->MgmtRing.Cell[index].AllocPa, RingBasePaHigh);
-			RTMP_SetPhysicalAddressLow (pAd->MgmtRing.Cell[index].AllocPa, RingBasePaLow);
-
-			// Offset to next ring descriptor address
-			RingBasePaLow += TXD_SIZE;
-			RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE;
-
-			// link the pre-allocated TxBuf to TXD
-			pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[index].AllocVa;
-			pTxD->DMADONE = 1;
-
-			// no pre-allocated buffer required in MgmtRing for scatter-gather case
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", index));
-
-		//
-		// Allocate RX ring descriptor's memory except Tx ring which allocated eariler
-		//
-		pAd->RxDescRing.AllocSize = RX_RING_SIZE * RXD_SIZE;
-		RTMP_AllocateRxDescMemory(
-			pAd,
-			pAd->RxDescRing.AllocSize,
-			FALSE,
-			&pAd->RxDescRing.AllocVa,
-			&pAd->RxDescRing.AllocPa);
-
-		if (pAd->RxDescRing.AllocVa == NULL)
-		{
-			ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
-			DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
-			Status = NDIS_STATUS_RESOURCES;
-			break;
-		}
-
-		// Zero init this memory block
-		NdisZeroMemory(pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize);
-
-
-		printk("RX DESC %p  size = %ld\n", pAd->RxDescRing.AllocVa,
-					pAd->RxDescRing.AllocSize);
-
-		// Save PA & VA for further operation
-		RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->RxDescRing.AllocPa);
-		RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->RxDescRing.AllocPa);
-		RingBaseVa     = pAd->RxDescRing.AllocVa;
-
-		//
-		// Initialize Rx Ring and associated buffer memory
-		//
-		for (index = 0; index < RX_RING_SIZE; index++)
-		{
-			// Init RX Ring Size, Va, Pa variables
-			pAd->RxRing.Cell[index].AllocSize = RXD_SIZE;
-			pAd->RxRing.Cell[index].AllocVa = RingBaseVa;
-			RTMP_SetPhysicalAddressHigh(pAd->RxRing.Cell[index].AllocPa, RingBasePaHigh);
-			RTMP_SetPhysicalAddressLow (pAd->RxRing.Cell[index].AllocPa, RingBasePaLow);
-
-			// Offset to next ring descriptor address
-			RingBasePaLow += RXD_SIZE;
-			RingBaseVa = (PUCHAR) RingBaseVa + RXD_SIZE;
-
-			// Setup Rx associated Buffer size & allocate share memory
-			pDmaBuf = &pAd->RxRing.Cell[index].DmaBuf;
-			pDmaBuf->AllocSize = RX_BUFFER_AGGRESIZE;
-			pPacket = RTMP_AllocateRxPacketBuffer(
-				pAd,
-				pDmaBuf->AllocSize,
-				FALSE,
-				&pDmaBuf->AllocVa,
-				&pDmaBuf->AllocPa);
-
-			/* keep allocated rx packet */
-			pAd->RxRing.Cell[index].pNdisPacket = pPacket;
-
-			// Error handling
-			if (pDmaBuf->AllocVa == NULL)
-			{
-				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
-				DBGPRINT_ERR(("Failed to allocate RxRing's 1st buffer\n"));
-				Status = NDIS_STATUS_RESOURCES;
-				break;
-			}
-
-			// Zero init this memory block
-			NdisZeroMemory(pDmaBuf->AllocVa, pDmaBuf->AllocSize);
-
-			// Write RxD buffer address & allocated buffer length
-			pRxD = (PRXD_STRUC) pAd->RxRing.Cell[index].AllocVa;
-			pRxD->SDP0 = RTMP_GetPhysicalAddressLow(pDmaBuf->AllocPa);
-			pRxD->DDONE = 0;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("Rx Ring: total %d entry allocated\n", index));
-
-	}	while (FALSE);
-
-
-	NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));
-	pAd->FragFrame.pFragPacket =  RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
-
-	if (pAd->FragFrame.pFragPacket == NULL)
-	{
-		Status = NDIS_STATUS_RESOURCES;
-	}
-
-	if (Status != NDIS_STATUS_SUCCESS)
-	{
-		// Log error inforamtion
-		NdisWriteErrorLogEntry(
-			pAd->AdapterHandle,
-			NDIS_ERROR_CODE_OUT_OF_RESOURCES,
-			1,
-			ErrorValue);
-	}
-
-	DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
-	return Status;
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Initialize transmit data structures
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-		Initialize all transmit releated private buffer, include those define
-		in RTMP_ADAPTER structure and all private data structures.
-
-	========================================================================
-*/
-VOID	NICInitTxRxRingAndBacklogQueue(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	//WPDMA_GLO_CFG_STRUC	GloCfg;
-	int i;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<--> NICInitTxRxRingAndBacklogQueue\n"));
-
-	// Initialize all transmit related software queues
-	InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_BE]);
-	InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_BK]);
-	InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_VI]);
-	InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_VO]);
-	InitializeQueueHeader(&pAd->TxSwQueue[QID_HCCA]);
-
-	// Init RX Ring index pointer
-	pAd->RxRing.RxSwReadIdx = 0;
-	pAd->RxRing.RxCpuIdx = RX_RING_SIZE - 1;
-
-	// Init TX rings index pointer
-		for (i=0; i<NUM_OF_TX_RING; i++)
-		{
-			pAd->TxRing[i].TxSwFreeIdx = 0;
-			pAd->TxRing[i].TxCpuIdx = 0;
-		}
-
-	// init MGMT ring index pointer
-	pAd->MgmtRing.TxSwFreeIdx = 0;
-	pAd->MgmtRing.TxCpuIdx = 0;
-
-	pAd->PrivateInfo.TxRingFullCnt       = 0;
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Reset NIC Asics. Call after rest DMA. So reset TX_CTX_IDX to zero.
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-		Reset NIC to initial state AS IS system boot up time.
-
-	========================================================================
-*/
-VOID	RTMPRingCleanUp(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			RingType)
-{
-	PTXD_STRUC		pTxD;
-	PRXD_STRUC		pRxD;
-	PQUEUE_ENTRY	pEntry;
-	PNDIS_PACKET	pPacket;
-	int				i;
-	PRTMP_TX_RING	pTxRing;
-	unsigned long	IrqFlags;
-
-	DBGPRINT(RT_DEBUG_TRACE,("RTMPRingCleanUp(RingIdx=%d, Pending-NDIS=%ld)\n", RingType, pAd->RalinkCounters.PendingNdisPacketCount));
-	switch (RingType)
-	{
-		case QID_AC_BK:
-		case QID_AC_BE:
-		case QID_AC_VI:
-		case QID_AC_VO:
-		case QID_HCCA:
-			RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-			pTxRing = &pAd->TxRing[RingType];
-
-			// We have to clean all descriptors in case some error happened with reset
-			for (i=0; i<TX_RING_SIZE; i++) // We have to scan all TX ring
-			{
-				pTxD  = (PTXD_STRUC) pTxRing->Cell[i].AllocVa;
-
-				pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNdisPacket;
-				// release scatter-and-gather NDIS_PACKET
-				if (pPacket)
-				{
-					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-					pTxRing->Cell[i].pNdisPacket = NULL;
-				}
-
-				pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNextNdisPacket;
-				// release scatter-and-gather NDIS_PACKET
-				if (pPacket)
-				{
-					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-					pTxRing->Cell[i].pNextNdisPacket = NULL;
-				}
-			}
-
-			RTMP_IO_READ32(pAd, TX_DTX_IDX0 + RingType * 0x10, &pTxRing->TxDmaIdx);
-			pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx;
-			pTxRing->TxCpuIdx = pTxRing->TxDmaIdx;
-			RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + RingType * 0x10, pTxRing->TxCpuIdx);
-
-			RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-			RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-			while (pAd->TxSwQueue[RingType].Head != NULL)
-			{
-				pEntry = RemoveHeadQueue(&pAd->TxSwQueue[RingType]);
-				pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
-				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-				DBGPRINT(RT_DEBUG_TRACE,("Release 1 NDIS packet from s/w backlog queue\n"));
-			}
-			RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-			break;
-
-		case QID_MGMT:
-			// We have to clean all descriptors in case some error happened with reset
-			NdisAcquireSpinLock(&pAd->MgmtRingLock);
-
-			for (i=0; i<MGMT_RING_SIZE; i++)
-			{
-				pTxD  = (PTXD_STRUC) pAd->MgmtRing.Cell[i].AllocVa;
-
-				pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNdisPacket;
-				// rlease scatter-and-gather NDIS_PACKET
-				if (pPacket)
-				{
-					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
-					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-				}
-				pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
-
-				pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNextNdisPacket;
-				// release scatter-and-gather NDIS_PACKET
-				if (pPacket)
-				{
-					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
-					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-				}
-				pAd->MgmtRing.Cell[i].pNextNdisPacket = NULL;
-
-			}
-
-			RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pAd->MgmtRing.TxDmaIdx);
-			pAd->MgmtRing.TxSwFreeIdx = pAd->MgmtRing.TxDmaIdx;
-			pAd->MgmtRing.TxCpuIdx = pAd->MgmtRing.TxDmaIdx;
-			RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
-
-			NdisReleaseSpinLock(&pAd->MgmtRingLock);
-			pAd->RalinkCounters.MgmtRingFullCount = 0;
-			break;
-
-		case QID_RX:
-			// We have to clean all descriptors in case some error happened with reset
-			NdisAcquireSpinLock(&pAd->RxRingLock);
-
-			for (i=0; i<RX_RING_SIZE; i++)
-			{
-				pRxD  = (PRXD_STRUC) pAd->RxRing.Cell[i].AllocVa;
-				pRxD->DDONE = 0 ;
-			}
-
-			RTMP_IO_READ32(pAd, RX_DRX_IDX, &pAd->RxRing.RxDmaIdx);
-			pAd->RxRing.RxSwReadIdx = pAd->RxRing.RxDmaIdx;
-			pAd->RxRing.RxCpuIdx = ((pAd->RxRing.RxDmaIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxDmaIdx-1));
-			RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
-
-			NdisReleaseSpinLock(&pAd->RxRingLock);
-			break;
-
-		default:
-			break;
-	}
-}
-
-
-NDIS_STATUS AdapterBlockAllocateMemory(
-	IN PVOID	handle,
-	OUT	PVOID	*ppAd)
-{
-	PPCI_DEV pci_dev;
-	dma_addr_t	*phy_addr;
-	POS_COOKIE pObj = (POS_COOKIE) handle;
-
-	pci_dev = pObj->pci_dev;
-	phy_addr = &pObj->pAd_pa;
-
-	*ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER)); //pci_alloc_consistent(pci_dev, sizeof(RTMP_ADAPTER), phy_addr);
-
-	if (*ppAd)
-	{
-		NdisZeroMemory(*ppAd, sizeof(RTMP_ADAPTER));
-		((PRTMP_ADAPTER)*ppAd)->OS_Cookie = handle;
-		return (NDIS_STATUS_SUCCESS);
-	} else {
-		return (NDIS_STATUS_FAILURE);
-	}
-}
-
-
-void RTMP_AllocateTxDescMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	UINT	Index,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
-{
-	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	*VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
-
-}
-
-void RTMP_AllocateMgmtDescMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
-{
-	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	*VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
-
-}
-
-void RTMP_AllocateRxDescMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
-{
-	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	*VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
-
-}
-
-void RTMP_FreeRxDescMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	PVOID	VirtualAddress,
-	IN	NDIS_PHYSICAL_ADDRESS PhysicalAddress)
-{
-	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	PCI_FREE_CONSISTENT(pObj->pci_dev, Length, VirtualAddress, PhysicalAddress);
-}
-
-
-void RTMP_AllocateFirstTxBuffer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	UINT	Index,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
-{
-	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	*VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
-}
-
-/*
- * FUNCTION: Allocate a common buffer for DMA
- * ARGUMENTS:
- *     AdapterHandle:  AdapterHandle
- *     Length:  Number of bytes to allocate
- *     Cached:  Whether or not the memory can be cached
- *     VirtualAddress:  Pointer to memory is returned here
- *     PhysicalAddress:  Physical address corresponding to virtual address
- */
-
-void RTMP_AllocateSharedMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
-{
-	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	*VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
-}
-
-VOID RTMPFreeTxRxRingMemory(
-    IN  PRTMP_ADAPTER   pAd)
-{
-	int index, num , j;
-	PRTMP_TX_RING pTxRing;
-	PTXD_STRUC	  pTxD;
-	PNDIS_PACKET  pPacket;
-	unsigned int  IrqFlags;
-
-	POS_COOKIE pObj =(POS_COOKIE) pAd->OS_Cookie;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPFreeTxRxRingMemory\n"));
-
-	// Free TxSwQueue Packet
-	for (index=0; index <NUM_OF_TX_RING; index++)
-	{
-		PQUEUE_ENTRY pEntry;
-		PNDIS_PACKET pPacket;
-		PQUEUE_HEADER   pQueue;
-
-		RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-		pQueue = &pAd->TxSwQueue[index];
-		while (pQueue->Head)
-		{
-			pEntry = RemoveHeadQueue(pQueue);
-			pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
-			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-		}
-		RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-	}
-
-	// Free Tx Ring Packet
-	for (index=0;index< NUM_OF_TX_RING;index++)
-	{
-		pTxRing = &pAd->TxRing[index];
-
-		for (j=0; j< TX_RING_SIZE; j++)
-		{
-			pTxD = (PTXD_STRUC) (pTxRing->Cell[j].AllocVa);
-			pPacket = pTxRing->Cell[j].pNdisPacket;
-
-			if (pPacket)
-			{
-            	PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-			}
-			//Always assign pNdisPacket as NULL after clear
-			pTxRing->Cell[j].pNdisPacket = NULL;
-
-			pPacket = pTxRing->Cell[j].pNextNdisPacket;
-
-			if (pPacket)
-			{
-            	PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-			}
-			//Always assign pNextNdisPacket as NULL after clear
-			pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL;
-
-		}
-	}
-
-	for (index = RX_RING_SIZE - 1 ; index >= 0; index--)
-	{
-		if ((pAd->RxRing.Cell[index].DmaBuf.AllocVa) && (pAd->RxRing.Cell[index].pNdisPacket))
-		{
-			PCI_UNMAP_SINGLE(pObj->pci_dev, pAd->RxRing.Cell[index].DmaBuf.AllocPa, pAd->RxRing.Cell[index].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
-			RELEASE_NDIS_PACKET(pAd, pAd->RxRing.Cell[index].pNdisPacket, NDIS_STATUS_SUCCESS);
-		}
-	}
-	NdisZeroMemory(pAd->RxRing.Cell, RX_RING_SIZE * sizeof(RTMP_DMACB));
-
-	if (pAd->RxDescRing.AllocVa)
-    {
-    	PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->RxDescRing.AllocSize, pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocPa);
-    }
-    NdisZeroMemory(&pAd->RxDescRing, sizeof(RTMP_DMABUF));
-
-	if (pAd->MgmtDescRing.AllocVa)
-	{
-		PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->MgmtDescRing.AllocSize,	pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocPa);
-	}
-	NdisZeroMemory(&pAd->MgmtDescRing, sizeof(RTMP_DMABUF));
-
-	for (num = 0; num < NUM_OF_TX_RING; num++)
-	{
-    	if (pAd->TxBufSpace[num].AllocVa)
-	    {
-	    	PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->TxBufSpace[num].AllocSize, pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocPa);
-	    }
-	    NdisZeroMemory(&pAd->TxBufSpace[num], sizeof(RTMP_DMABUF));
-
-    	if (pAd->TxDescRing[num].AllocVa)
-	    {
-	    	PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->TxDescRing[num].AllocSize, pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocPa);
-	    }
-	    NdisZeroMemory(&pAd->TxDescRing[num], sizeof(RTMP_DMABUF));
-	}
-
-	if (pAd->FragFrame.pFragPacket)
-		RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- RTMPFreeTxRxRingMemory\n"));
-}
-
-
-/*
- * FUNCTION: Allocate a packet buffer for DMA
- * ARGUMENTS:
- *     AdapterHandle:  AdapterHandle
- *     Length:  Number of bytes to allocate
- *     Cached:  Whether or not the memory can be cached
- *     VirtualAddress:  Pointer to memory is returned here
- *     PhysicalAddress:  Physical address corresponding to virtual address
- * Notes:
- *     Cached is ignored: always cached memory
- */
-PNDIS_PACKET RTMP_AllocateRxPacketBuffer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
-{
-	PNDIS_PACKET pkt;
-
-	pkt = RTPKT_TO_OSPKT(DEV_ALLOC_SKB(Length));
-
-	if (pkt == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR, ("can't allocate rx %ld size packet\n",Length));
-	}
-
-	if (pkt) {
-		RTMP_SET_PACKET_SOURCE(pkt, PKTSRC_NDIS);
-		*VirtualAddress = (PVOID) RTPKT_TO_OSPKT(pkt)->data;
-		*PhysicalAddress = PCI_MAP_SINGLE(pAd, *VirtualAddress, Length, -1, PCI_DMA_FROMDEVICE);
-	} else {
-		*VirtualAddress = (PVOID) NULL;
-		*PhysicalAddress = (NDIS_PHYSICAL_ADDRESS) NULL;
-	}
-
-	return (PNDIS_PACKET) pkt;
-}
-
-
-VOID Invalid_Remaining_Packet(
-	IN	PRTMP_ADAPTER pAd,
-	IN	 ULONG VirtualAddress)
-{
-	NDIS_PHYSICAL_ADDRESS PhysicalAddress;
-
-	PhysicalAddress = PCI_MAP_SINGLE(pAd, (void *)(VirtualAddress+1600), RX_BUFFER_NORMSIZE-1600, -1, PCI_DMA_FROMDEVICE);
-}
-
-PNDIS_PACKET GetPacketFromRxRing(
-	IN		PRTMP_ADAPTER	pAd,
-	OUT		PRT28XX_RXD_STRUC	pSaveRxD,
-	OUT		BOOLEAN			*pbReschedule,
-	IN OUT	UINT32			*pRxPending)
-{
-	PRXD_STRUC				pRxD;
-	PNDIS_PACKET			pRxPacket = NULL;
-	PNDIS_PACKET			pNewPacket;
-	PVOID					AllocVa;
-	NDIS_PHYSICAL_ADDRESS	AllocPa;
-	BOOLEAN					bReschedule = FALSE;
-
-	RTMP_SEM_LOCK(&pAd->RxRingLock);
-
-	if (*pRxPending == 0)
-	{
-		// Get how may packets had been received
-		RTMP_IO_READ32(pAd, RX_DRX_IDX , &pAd->RxRing.RxDmaIdx);
-
-		if (pAd->RxRing.RxSwReadIdx == pAd->RxRing.RxDmaIdx)
-		{
-			// no more rx packets
-			bReschedule = FALSE;
-			goto done;
-		}
-
-		// get rx pending count
-		if (pAd->RxRing.RxDmaIdx > pAd->RxRing.RxSwReadIdx)
-			*pRxPending = pAd->RxRing.RxDmaIdx - pAd->RxRing.RxSwReadIdx;
-		else
-			*pRxPending	= pAd->RxRing.RxDmaIdx + RX_RING_SIZE - pAd->RxRing.RxSwReadIdx;
-
-	}
-
-	// Point to Rx indexed rx ring descriptor
-	pRxD = (PRXD_STRUC) pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].AllocVa;
-
-	if (pRxD->DDONE == 0)
-	{
-		*pRxPending = 0;
-		// DMAIndx had done but DDONE bit not ready
-		bReschedule = TRUE;
-		goto done;
-	}
-
-
-	// return rx descriptor
-	NdisMoveMemory(pSaveRxD, pRxD, RXD_SIZE);
-
-	pNewPacket = RTMP_AllocateRxPacketBuffer(pAd, RX_BUFFER_AGGRESIZE, FALSE, &AllocVa, &AllocPa);
-
-	if (pNewPacket)
-	{
-		// unmap the rx buffer
-		PCI_UNMAP_SINGLE(pAd, pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocPa,
-					 pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
-		pRxPacket = pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].pNdisPacket;
-
-		pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocSize	= RX_BUFFER_AGGRESIZE;
-		pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].pNdisPacket		= (PNDIS_PACKET) pNewPacket;
-		pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocVa	= AllocVa;
-		pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocPa	= AllocPa;
-		/* update SDP0 to new buffer of rx packet */
-		pRxD->SDP0 = AllocPa;
-	}
-	else
-	{
-		//printk("No Rx Buffer\n");
-		pRxPacket = NULL;
-		bReschedule = TRUE;
-	}
-
-	pRxD->DDONE = 0;
-
-	// had handled one rx packet
-	*pRxPending = *pRxPending - 1;
-
-	// update rx descriptor and kick rx
-	INC_RING_INDEX(pAd->RxRing.RxSwReadIdx, RX_RING_SIZE);
-
-	pAd->RxRing.RxCpuIdx = (pAd->RxRing.RxSwReadIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxSwReadIdx-1);
-	RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
-
-done:
-	RTMP_SEM_UNLOCK(&pAd->RxRingLock);
-	*pbReschedule = bReschedule;
-	return pRxPacket;
-}
-/* End of 2860_rtmp_init.c */
-
diff --git a/drivers/staging/rt2860/common/action.c b/drivers/staging/rt2860/common/action.c
index 256cb67..56ad236 100644
--- a/drivers/staging/rt2860/common/action.c
+++ b/drivers/staging/rt2860/common/action.c
@@ -39,10 +39,7 @@
 #include "../rt_config.h"
 #include "action.h"
 
-
-static VOID ReservedAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
+static void ReservedAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
 /*
     ==========================================================================
@@ -61,75 +58,89 @@
         MT2_CLS3ERR              cls3err_action
     ==========================================================================
  */
-VOID ActionStateMachineInit(
-    IN	PRTMP_ADAPTER	pAd,
-    IN  STATE_MACHINE *S,
-    OUT STATE_MACHINE_FUNC Trans[])
+void ActionStateMachineInit(struct rt_rtmp_adapter *pAd,
+			    struct rt_state_machine *S,
+			    OUT STATE_MACHINE_FUNC Trans[])
 {
-	StateMachineInit(S, (STATE_MACHINE_FUNC *)Trans, MAX_ACT_STATE, MAX_ACT_MSG, (STATE_MACHINE_FUNC)Drop, ACT_IDLE, ACT_MACHINE_BASE);
+	StateMachineInit(S, (STATE_MACHINE_FUNC *) Trans, MAX_ACT_STATE,
+			 MAX_ACT_MSG, (STATE_MACHINE_FUNC) Drop, ACT_IDLE,
+			 ACT_MACHINE_BASE);
 
-	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_SPECTRUM_CATE, (STATE_MACHINE_FUNC)PeerSpectrumAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_QOS_CATE, (STATE_MACHINE_FUNC)PeerQOSAction);
+	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_SPECTRUM_CATE,
+			      (STATE_MACHINE_FUNC) PeerSpectrumAction);
+	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_QOS_CATE,
+			      (STATE_MACHINE_FUNC) PeerQOSAction);
 
-	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE, (STATE_MACHINE_FUNC)ReservedAction);
+	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE,
+			      (STATE_MACHINE_FUNC) ReservedAction);
 
-	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_BA_CATE, (STATE_MACHINE_FUNC)PeerBAAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_HT_CATE, (STATE_MACHINE_FUNC)PeerHTAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ADD_BA_CATE, (STATE_MACHINE_FUNC)MlmeADDBAAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ORI_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_REC_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction);
+	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_BA_CATE,
+			      (STATE_MACHINE_FUNC) PeerBAAction);
+	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_HT_CATE,
+			      (STATE_MACHINE_FUNC) PeerHTAction);
+	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ADD_BA_CATE,
+			      (STATE_MACHINE_FUNC) MlmeADDBAAction);
+	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ORI_DELBA_CATE,
+			      (STATE_MACHINE_FUNC) MlmeDELBAAction);
+	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_REC_DELBA_CATE,
+			      (STATE_MACHINE_FUNC) MlmeDELBAAction);
 
-	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_PUBLIC_CATE, (STATE_MACHINE_FUNC)PeerPublicAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_RM_CATE, (STATE_MACHINE_FUNC)PeerRMAction);
+	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_PUBLIC_CATE,
+			      (STATE_MACHINE_FUNC) PeerPublicAction);
+	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_RM_CATE,
+			      (STATE_MACHINE_FUNC) PeerRMAction);
 
-	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_QOS_CATE, (STATE_MACHINE_FUNC)MlmeQOSAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_DLS_CATE, (STATE_MACHINE_FUNC)MlmeDLSAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_ACT_INVALID, (STATE_MACHINE_FUNC)MlmeInvalidAction);
+	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_QOS_CATE,
+			      (STATE_MACHINE_FUNC) MlmeQOSAction);
+	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_DLS_CATE,
+			      (STATE_MACHINE_FUNC) MlmeDLSAction);
+	StateMachineSetAction(S, ACT_IDLE, MT2_ACT_INVALID,
+			      (STATE_MACHINE_FUNC) MlmeInvalidAction);
 }
 
-VOID MlmeADDBAAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
-
+void MlmeADDBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	MLME_ADDBA_REQ_STRUCT *pInfo;
-	UCHAR           Addr[6];
-	PUCHAR         pOutBuffer = NULL;
-	NDIS_STATUS     NStatus;
-	ULONG		Idx;
-	FRAME_ADDBA_REQ  Frame;
-	ULONG		FrameLen;
-	BA_ORI_ENTRY			*pBAEntry = NULL;
+	struct rt_mlme_addba_req *pInfo;
+	u8 Addr[6];
+	u8 *pOutBuffer = NULL;
+	int NStatus;
+	unsigned long Idx;
+	struct rt_frame_addba_req Frame;
+	unsigned long FrameLen;
+	struct rt_ba_ori_entry *pBAEntry = NULL;
 
-	pInfo = (MLME_ADDBA_REQ_STRUCT *)Elem->Msg;
-	NdisZeroMemory(&Frame, sizeof(FRAME_ADDBA_REQ));
+	pInfo = (struct rt_mlme_addba_req *)Elem->Msg;
+	NdisZeroMemory(&Frame, sizeof(struct rt_frame_addba_req));
 
-	if(MlmeAddBAReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr))
-	{
-		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-		if(NStatus != NDIS_STATUS_SUCCESS)
-		{
-			DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeADDBAAction() allocate memory failed \n"));
+	if (MlmeAddBAReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr)) {
+		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
+		if (NStatus != NDIS_STATUS_SUCCESS) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("BA - MlmeADDBAAction() allocate memory failed \n"));
 			return;
 		}
-		// 1. find entry
-		Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
-		if (Idx == 0)
-		{
+		/* 1. find entry */
+		Idx =
+		    pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
+		if (Idx == 0) {
 			MlmeFreeMemory(pAd, pOutBuffer);
-			DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() can't find BAOriEntry \n"));
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("BA - MlmeADDBAAction() can't find BAOriEntry \n"));
 			return;
-		}
-		else
-		{
-			pBAEntry =&pAd->BATable.BAOriEntry[Idx];
+		} else {
+			pBAEntry = &pAd->BATable.BAOriEntry[Idx];
 		}
 
 		{
 			if (ADHOC_ON(pAd))
-				ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+				ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr,
+					      pAd->CurrentAddress,
+					      pAd->CommonCfg.Bssid);
 			else
-				ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pInfo->pAddr);
+				ActHeaderInit(pAd, &Frame.Hdr,
+					      pAd->CommonCfg.Bssid,
+					      pAd->CurrentAddress,
+					      pInfo->pAddr);
 		}
 
 		Frame.Category = CATEGORY_BA;
@@ -141,20 +152,29 @@
 		Frame.Token = pInfo->Token;
 		Frame.TimeOutValue = pInfo->TimeOutValue;
 		Frame.BaStartSeq.field.FragNum = 0;
-		Frame.BaStartSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID];
+		Frame.BaStartSeq.field.StartSeq =
+		    pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID];
 
-		*(USHORT *)(&Frame.BaParm) = cpu2le16(*(USHORT *)(&Frame.BaParm));
+		*(u16 *) (&Frame.BaParm) =
+		    cpu2le16(*(u16 *) (&Frame.BaParm));
 		Frame.TimeOutValue = cpu2le16(Frame.TimeOutValue);
 		Frame.BaStartSeq.word = cpu2le16(Frame.BaStartSeq.word);
 
-		MakeOutgoingFrame(pOutBuffer,		   &FrameLen,
-		              sizeof(FRAME_ADDBA_REQ), &Frame,
-		              END_OF_ARGS);
-		MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+		MakeOutgoingFrame(pOutBuffer, &FrameLen,
+				  sizeof(struct rt_frame_addba_req), &Frame, END_OF_ARGS);
+
+		MiniportMMRequest(pAd,
+				  (MGMT_USE_QUEUE_FLAG |
+				   MapUserPriorityToAccessCategory[pInfo->TID]),
+				  pOutBuffer, FrameLen);
+
 		MlmeFreeMemory(pAd, pOutBuffer);
 
-		DBGPRINT(RT_DEBUG_TRACE, ("BA - Send ADDBA request. StartSeq = %x,  FrameLen = %ld. BufSize = %d\n", Frame.BaStartSeq.field.StartSeq, FrameLen, Frame.BaParm.BufSize));
-    }
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("BA - Send ADDBA request. StartSeq = %x,  FrameLen = %ld. BufSize = %d\n",
+			  Frame.BaStartSeq.field.StartSeq, FrameLen,
+			  Frame.BaParm.BufSize));
+	}
 }
 
 /*
@@ -162,288 +182,277 @@
     Description:
         send DELBA and delete BaEntry if any
     Parametrs:
-        Elem - MLME message MLME_DELBA_REQ_STRUCT
+        Elem - MLME message struct rt_mlme_delba_req
 
 	IRQL = DISPATCH_LEVEL
 
     ==========================================================================
  */
-VOID MlmeDELBAAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
+void MlmeDELBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	MLME_DELBA_REQ_STRUCT *pInfo;
-	PUCHAR         pOutBuffer = NULL;
-	PUCHAR		   pOutBuffer2 = NULL;
-	NDIS_STATUS     NStatus;
-	ULONG		Idx;
-	FRAME_DELBA_REQ  Frame;
-	ULONG		FrameLen;
-	FRAME_BAR	FrameBar;
+	struct rt_mlme_delba_req *pInfo;
+	u8 *pOutBuffer = NULL;
+	u8 *pOutBuffer2 = NULL;
+	int NStatus;
+	unsigned long Idx;
+	struct rt_frame_delba_req Frame;
+	unsigned long FrameLen;
+	struct rt_frame_bar FrameBar;
 
-	pInfo = (MLME_DELBA_REQ_STRUCT *)Elem->Msg;
-	// must send back DELBA
-	NdisZeroMemory(&Frame, sizeof(FRAME_DELBA_REQ));
-	DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo->Initiator));
+	pInfo = (struct rt_mlme_delba_req *)Elem->Msg;
+	/* must send back DELBA */
+	NdisZeroMemory(&Frame, sizeof(struct rt_frame_delba_req));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo->Initiator));
 
-	if(MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen))
-	{
-		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-		if(NStatus != NDIS_STATUS_SUCCESS)
-		{
-			DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeDELBAAction() allocate memory failed 1. \n"));
+	if (MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen)) {
+		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
+		if (NStatus != NDIS_STATUS_SUCCESS) {
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("BA - MlmeDELBAAction() allocate memory failed 1. \n"));
 			return;
 		}
 
-		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2);  //Get an unused nonpaged memory
-		if(NStatus != NDIS_STATUS_SUCCESS)
-		{
+		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2);	/*Get an unused nonpaged memory */
+		if (NStatus != NDIS_STATUS_SUCCESS) {
 			MlmeFreeMemory(pAd, pOutBuffer);
-			DBGPRINT(RT_DEBUG_ERROR, ("BA - MlmeDELBAAction() allocate memory failed 2. \n"));
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("BA - MlmeDELBAAction() allocate memory failed 2. \n"));
 			return;
 		}
+		/* SEND BAR (Send BAR to refresh peer reordering buffer.) */
+		Idx =
+		    pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
 
-		// SEND BAR (Send BAR to refresh peer reordering buffer.)
-		Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
+		BarHeaderInit(pAd, &FrameBar,
+			      pAd->MacTab.Content[pInfo->Wcid].Addr,
+			      pAd->CurrentAddress);
 
-		BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress);
+		FrameBar.StartingSeq.field.FragNum = 0;	/* make sure sequence not clear in DEL funciton. */
+		FrameBar.StartingSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID];	/* make sure sequence not clear in DEL funciton. */
+		FrameBar.BarControl.TID = pInfo->TID;	/* make sure sequence not clear in DEL funciton. */
+		FrameBar.BarControl.ACKPolicy = IMMED_BA;	/* make sure sequence not clear in DEL funciton. */
+		FrameBar.BarControl.Compressed = 1;	/* make sure sequence not clear in DEL funciton. */
+		FrameBar.BarControl.MTID = 0;	/* make sure sequence not clear in DEL funciton. */
 
-		FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL funciton.
-		FrameBar.StartingSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; // make sure sequence not clear in DEL funciton.
-		FrameBar.BarControl.TID = pInfo->TID; // make sure sequence not clear in DEL funciton.
-		FrameBar.BarControl.ACKPolicy = IMMED_BA; // make sure sequence not clear in DEL funciton.
-		FrameBar.BarControl.Compressed = 1; // make sure sequence not clear in DEL funciton.
-		FrameBar.BarControl.MTID = 0; // make sure sequence not clear in DEL funciton.
-
-		MakeOutgoingFrame(pOutBuffer2,				&FrameLen,
-					  sizeof(FRAME_BAR),	  &FrameBar,
-					  END_OF_ARGS);
+		MakeOutgoingFrame(pOutBuffer2, &FrameLen,
+				  sizeof(struct rt_frame_bar), &FrameBar, END_OF_ARGS);
 		MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
 		MlmeFreeMemory(pAd, pOutBuffer2);
-		DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n"));
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n"));
 
-		// SEND DELBA FRAME
+		/* SEND DELBA FRAME */
 		FrameLen = 0;
 
 		{
 			if (ADHOC_ON(pAd))
-				ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+				ActHeaderInit(pAd, &Frame.Hdr,
+					      pAd->MacTab.Content[pInfo->Wcid].
+					      Addr, pAd->CurrentAddress,
+					      pAd->CommonCfg.Bssid);
 			else
-				ActHeaderInit(pAd, &Frame.Hdr,  pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[pInfo->Wcid].Addr);
+				ActHeaderInit(pAd, &Frame.Hdr,
+					      pAd->CommonCfg.Bssid,
+					      pAd->CurrentAddress,
+					      pAd->MacTab.Content[pInfo->Wcid].
+					      Addr);
 		}
 
 		Frame.Category = CATEGORY_BA;
 		Frame.Action = DELBA;
 		Frame.DelbaParm.Initiator = pInfo->Initiator;
 		Frame.DelbaParm.TID = pInfo->TID;
-		Frame.ReasonCode = 39; // Time Out
-		*(USHORT *)(&Frame.DelbaParm) = cpu2le16(*(USHORT *)(&Frame.DelbaParm));
+		Frame.ReasonCode = 39;	/* Time Out */
+		*(u16 *) (&Frame.DelbaParm) =
+		    cpu2le16(*(u16 *) (&Frame.DelbaParm));
 		Frame.ReasonCode = cpu2le16(Frame.ReasonCode);
 
-		MakeOutgoingFrame(pOutBuffer,               &FrameLen,
-		              sizeof(FRAME_DELBA_REQ),    &Frame,
-		              END_OF_ARGS);
+		MakeOutgoingFrame(pOutBuffer, &FrameLen,
+				  sizeof(struct rt_frame_delba_req), &Frame, END_OF_ARGS);
 		MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
 		MlmeFreeMemory(pAd, pOutBuffer);
-		DBGPRINT(RT_DEBUG_TRACE, ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n", pInfo->Initiator));
-    	}
-}
-
-VOID MlmeQOSAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
-{
-}
-
-VOID MlmeDLSAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
-{
-}
-
-VOID MlmeInvalidAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
-{
-	//PUCHAR		   pOutBuffer = NULL;
-	//Return the receiving frame except the MSB of category filed set to 1.  7.3.1.11
-}
-
-VOID PeerQOSAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-}
-
-VOID PeerBAAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	UCHAR	Action = Elem->Msg[LENGTH_802_11+1];
-
-	switch(Action)
-	{
-		case ADDBA_REQ:
-			PeerAddBAReqAction(pAd,Elem);
-			break;
-		case ADDBA_RESP:
-			PeerAddBARspAction(pAd,Elem);
-			break;
-		case DELBA:
-			PeerDelBAAction(pAd,Elem);
-			break;
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n",
+			  pInfo->Initiator));
 	}
 }
 
-VOID PeerPublicAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void MlmeQOSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
+{
+}
+
+void MlmeDLSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
+{
+}
+
+void MlmeInvalidAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
+{
+	/*u8 *                  pOutBuffer = NULL; */
+	/*Return the receiving frame except the MSB of category filed set to 1.  7.3.1.11 */
+}
+
+void PeerQOSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
+{
+}
+
+void PeerBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
+{
+	u8 Action = Elem->Msg[LENGTH_802_11 + 1];
+
+	switch (Action) {
+	case ADDBA_REQ:
+		PeerAddBAReqAction(pAd, Elem);
+		break;
+	case ADDBA_RESP:
+		PeerAddBARspAction(pAd, Elem);
+		break;
+	case DELBA:
+		PeerDelBAAction(pAd, Elem);
+		break;
+	}
+}
+
+void PeerPublicAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
 	if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
 		return;
 }
 
-
-static VOID ReservedAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+static void ReservedAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	UCHAR Category;
+	u8 Category;
 
-	if (Elem->MsgLen <= LENGTH_802_11)
-	{
+	if (Elem->MsgLen <= LENGTH_802_11) {
 		return;
 	}
 
 	Category = Elem->Msg[LENGTH_802_11];
-	DBGPRINT(RT_DEBUG_TRACE,("Rcv reserved category(%d) Action Frame\n", Category));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("Rcv reserved category(%d) Action Frame\n", Category));
 	hex_dump("Reserved Action Frame", &Elem->Msg[0], Elem->MsgLen);
 }
 
-VOID PeerRMAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-
+void PeerRMAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
 	return;
 }
 
-static VOID respond_ht_information_exchange_action(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+static void respond_ht_information_exchange_action(struct rt_rtmp_adapter *pAd,
+						   struct rt_mlme_queue_elem *Elem)
 {
-	PUCHAR			pOutBuffer = NULL;
-	NDIS_STATUS		NStatus;
-	ULONG			FrameLen;
-	FRAME_HT_INFO	HTINFOframe, *pFrame;
-	UCHAR   		*pAddr;
+	u8 *pOutBuffer = NULL;
+	int NStatus;
+	unsigned long FrameLen;
+	struct rt_frame_ht_info HTINFOframe, *pFrame;
+	u8 *pAddr;
 
+	/* 2. Always send back ADDBA Response */
+	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
 
-	// 2. Always send back ADDBA Response
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	 //Get an unused nonpaged memory
-
-	if (NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("ACTION - respond_ht_information_exchange_action() allocate memory failed \n"));
+	if (NStatus != NDIS_STATUS_SUCCESS) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("ACTION - respond_ht_information_exchange_action() allocate memory failed \n"));
 		return;
 	}
-
-	// get RA
-	pFrame = (FRAME_HT_INFO *) &Elem->Msg[0];
+	/* get RA */
+	pFrame = (struct rt_frame_ht_info *) & Elem->Msg[0];
 	pAddr = pFrame->Hdr.Addr2;
 
-	NdisZeroMemory(&HTINFOframe, sizeof(FRAME_HT_INFO));
-	// 2-1. Prepare ADDBA Response frame.
+	NdisZeroMemory(&HTINFOframe, sizeof(struct rt_frame_ht_info));
+	/* 2-1. Prepare ADDBA Response frame. */
 	{
 		if (ADHOC_ON(pAd))
-			ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+			ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr,
+				      pAd->CurrentAddress,
+				      pAd->CommonCfg.Bssid);
 		else
-			ActHeaderInit(pAd, &HTINFOframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
+			ActHeaderInit(pAd, &HTINFOframe.Hdr,
+				      pAd->CommonCfg.Bssid, pAd->CurrentAddress,
+				      pAddr);
 	}
 
 	HTINFOframe.Category = CATEGORY_HT;
 	HTINFOframe.Action = HT_INFO_EXCHANGE;
 	HTINFOframe.HT_Info.Request = 0;
-	HTINFOframe.HT_Info.Forty_MHz_Intolerant = pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant;
-	HTINFOframe.HT_Info.STA_Channel_Width	 = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
+	HTINFOframe.HT_Info.Forty_MHz_Intolerant =
+	    pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant;
+	HTINFOframe.HT_Info.STA_Channel_Width =
+	    pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
 
-	MakeOutgoingFrame(pOutBuffer,					&FrameLen,
-					  sizeof(FRAME_HT_INFO),	&HTINFOframe,
-					  END_OF_ARGS);
+	MakeOutgoingFrame(pOutBuffer, &FrameLen,
+			  sizeof(struct rt_frame_ht_info), &HTINFOframe, END_OF_ARGS);
 
 	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
 	MlmeFreeMemory(pAd, pOutBuffer);
 }
 
-VOID PeerHTAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void PeerHTAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	UCHAR	Action = Elem->Msg[LENGTH_802_11+1];
+	u8 Action = Elem->Msg[LENGTH_802_11 + 1];
 
 	if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
 		return;
 
-	switch(Action)
-	{
-		case NOTIFY_BW_ACTION:
-			DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Notify Channel bandwidth action----> \n"));
+	switch (Action) {
+	case NOTIFY_BW_ACTION:
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("ACTION - HT Notify Channel bandwidth action----> \n"));
 
-			if(pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
-			{
-				// Note, this is to patch DIR-1353 AP. When the AP set to Wep, it will use legacy mode. But AP still keeps
-				// sending BW_Notify Action frame, and cause us to linkup and linkdown.
-				// In legacy mode, don't need to parse HT action frame.
-				DBGPRINT(RT_DEBUG_TRACE,("ACTION -Ignore HT Notify Channel BW when link as legacy mode. BW = %d---> \n",
-								Elem->Msg[LENGTH_802_11+2] ));
-				break;
-			}
-
-			if (Elem->Msg[LENGTH_802_11+2] == 0)	// 7.4.8.2. if value is 1, keep the same as supported channel bandwidth.
-				pAd->MacTab.Content[Elem->Wcid].HTPhyMode.field.BW = 0;
-
+		if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) {
+			/* Note, this is to patch DIR-1353 AP. When the AP set to Wep, it will use legacy mode. But AP still keeps */
+			/* sending BW_Notify Action frame, and cause us to linkup and linkdown. */
+			/* In legacy mode, don't need to parse HT action frame. */
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("ACTION -Ignore HT Notify Channel BW when link as legacy mode. BW = %d---> \n",
+				  Elem->Msg[LENGTH_802_11 + 2]));
 			break;
-		case SMPS_ACTION:
-			// 7.3.1.25
- 			DBGPRINT(RT_DEBUG_TRACE,("ACTION - SMPS action----> \n"));
-			if (((Elem->Msg[LENGTH_802_11+2]&0x1) == 0))
-			{
-				pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_ENABLE;
-			}
-			else if (((Elem->Msg[LENGTH_802_11+2]&0x2) == 0))
-			{
-				pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_STATIC;
-			}
-			else
-			{
-				pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_DYNAMIC;
-			}
+		}
 
-			DBGPRINT(RT_DEBUG_TRACE,("Aid(%d) MIMO PS = %d\n", Elem->Wcid, pAd->MacTab.Content[Elem->Wcid].MmpsMode));
-			// rt2860c : add something for smps change.
-			break;
+		if (Elem->Msg[LENGTH_802_11 + 2] == 0)	/* 7.4.8.2. if value is 1, keep the same as supported channel bandwidth. */
+			pAd->MacTab.Content[Elem->Wcid].HTPhyMode.field.BW = 0;
 
-		case SETPCO_ACTION:
-			break;
-		case MIMO_CHA_MEASURE_ACTION:
-			break;
-		case HT_INFO_EXCHANGE:
-			{
-				HT_INFORMATION_OCTET	*pHT_info;
+		break;
+	case SMPS_ACTION:
+		/* 7.3.1.25 */
+		DBGPRINT(RT_DEBUG_TRACE, ("ACTION - SMPS action----> \n"));
+		if (((Elem->Msg[LENGTH_802_11 + 2] & 0x1) == 0)) {
+			pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_ENABLE;
+		} else if (((Elem->Msg[LENGTH_802_11 + 2] & 0x2) == 0)) {
+			pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_STATIC;
+		} else {
+			pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_DYNAMIC;
+		}
 
-				pHT_info = (HT_INFORMATION_OCTET *) &Elem->Msg[LENGTH_802_11+2];
-    				// 7.4.8.10
-    				DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Information Exchange action----> \n"));
-    				if (pHT_info->Request)
-    				{
-    					respond_ht_information_exchange_action(pAd, Elem);
-    				}
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Aid(%d) MIMO PS = %d\n", Elem->Wcid,
+			  pAd->MacTab.Content[Elem->Wcid].MmpsMode));
+		/* rt2860c : add something for smps change. */
+		break;
+
+	case SETPCO_ACTION:
+		break;
+	case MIMO_CHA_MEASURE_ACTION:
+		break;
+	case HT_INFO_EXCHANGE:
+		{
+			struct rt_ht_information_octet *pHT_info;
+
+			pHT_info =
+			    (struct rt_ht_information_octet *) & Elem->Msg[LENGTH_802_11 +
+								 2];
+			/* 7.4.8.10 */
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("ACTION - HT Information Exchange action----> \n"));
+			if (pHT_info->Request) {
+				respond_ht_information_exchange_action(pAd,
+								       Elem);
 			}
-    			break;
+		}
+		break;
 	}
 }
 
-
 /*
 	==========================================================================
 	Description:
@@ -458,120 +467,116 @@
 				FALSE , then continue indicaterx at this moment.
 	==========================================================================
  */
-VOID ORIBATimerTimeout(
-	IN	PRTMP_ADAPTER	pAd)
+void ORIBATimerTimeout(struct rt_rtmp_adapter *pAd)
 {
-	MAC_TABLE_ENTRY	*pEntry;
-	INT			i, total;
-	UCHAR			TID;
+	struct rt_mac_table_entry *pEntry;
+	int i, total;
+	u8 TID;
 
 	total = pAd->MacTab.Size * NUM_OF_TID;
 
-	for (i = 1; ((i <MAX_LEN_OF_BA_ORI_TABLE) && (total > 0)) ; i++)
-	{
-		if  (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done)
-		{
-			pEntry = &pAd->MacTab.Content[pAd->BATable.BAOriEntry[i].Wcid];
+	for (i = 1; ((i < MAX_LEN_OF_BA_ORI_TABLE) && (total > 0)); i++) {
+		if (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done) {
+			pEntry =
+			    &pAd->MacTab.Content[pAd->BATable.BAOriEntry[i].
+						 Wcid];
 			TID = pAd->BATable.BAOriEntry[i].TID;
 
-			ASSERT(pAd->BATable.BAOriEntry[i].Wcid < MAX_LEN_OF_MAC_TABLE);
+			ASSERT(pAd->BATable.BAOriEntry[i].Wcid <
+			       MAX_LEN_OF_MAC_TABLE);
 		}
-		total --;
+		total--;
 	}
 }
 
-
-VOID SendRefreshBAR(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MAC_TABLE_ENTRY	*pEntry)
+void SendRefreshBAR(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry)
 {
-	FRAME_BAR		FrameBar;
-	ULONG			FrameLen;
-	NDIS_STATUS 	NStatus;
-	PUCHAR			pOutBuffer = NULL;
-	USHORT			Sequence;
-	UCHAR			i, TID;
-	USHORT			idx;
-	BA_ORI_ENTRY	*pBAEntry;
+	struct rt_frame_bar FrameBar;
+	unsigned long FrameLen;
+	int NStatus;
+	u8 *pOutBuffer = NULL;
+	u16 Sequence;
+	u8 i, TID;
+	u16 idx;
+	struct rt_ba_ori_entry *pBAEntry;
 
-	for (i = 0; i <NUM_OF_TID; i++)
-	{
+	for (i = 0; i < NUM_OF_TID; i++) {
 		idx = pEntry->BAOriWcidArray[i];
-		if (idx == 0)
-		{
+		if (idx == 0) {
 			continue;
 		}
 		pBAEntry = &pAd->BATable.BAOriEntry[idx];
 
-		if  (pBAEntry->ORI_BA_Status == Originator_Done)
-		{
+		if (pBAEntry->ORI_BA_Status == Originator_Done) {
 			TID = pBAEntry->TID;
 
 			ASSERT(pBAEntry->Wcid < MAX_LEN_OF_MAC_TABLE);
 
-			NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-			if(NStatus != NDIS_STATUS_SUCCESS)
-			{
-				DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));
+			NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
+			if (NStatus != NDIS_STATUS_SUCCESS) {
+				DBGPRINT(RT_DEBUG_ERROR,
+					 ("BA - MlmeADDBAAction() allocate memory failed \n"));
 				return;
 			}
 
 			Sequence = pEntry->TxSeq[TID];
 
-			BarHeaderInit(pAd, &FrameBar, pEntry->Addr, pAd->CurrentAddress);
+			BarHeaderInit(pAd, &FrameBar, pEntry->Addr,
+				      pAd->CurrentAddress);
 
-			FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL function.
-			FrameBar.StartingSeq.field.StartSeq = Sequence; // make sure sequence not clear in DEL funciton.
-			FrameBar.BarControl.TID = TID; // make sure sequence not clear in DEL funciton.
+			FrameBar.StartingSeq.field.FragNum = 0;	/* make sure sequence not clear in DEL function. */
+			FrameBar.StartingSeq.field.StartSeq = Sequence;	/* make sure sequence not clear in DEL funciton. */
+			FrameBar.BarControl.TID = TID;	/* make sure sequence not clear in DEL funciton. */
 
-			MakeOutgoingFrame(pOutBuffer,				&FrameLen,
-							  sizeof(FRAME_BAR),	  &FrameBar,
-							  END_OF_ARGS);
+			MakeOutgoingFrame(pOutBuffer, &FrameLen,
+					  sizeof(struct rt_frame_bar), &FrameBar,
+					  END_OF_ARGS);
+			/*if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET))) */
+			if (1)	/* Now we always send BAR. */
+			{
+				/*MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen); */
+				MiniportMMRequest(pAd,
+						  (MGMT_USE_QUEUE_FLAG |
+						   MapUserPriorityToAccessCategory
+						   [TID]), pOutBuffer,
+						  FrameLen);
 
-			MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-
+			}
 			MlmeFreeMemory(pAd, pOutBuffer);
 		}
 	}
 }
 
-VOID ActHeaderInit(
-    IN	PRTMP_ADAPTER	pAd,
-    IN OUT PHEADER_802_11 pHdr80211,
-    IN PUCHAR Addr1,
-    IN PUCHAR Addr2,
-    IN PUCHAR Addr3)
+void ActHeaderInit(struct rt_rtmp_adapter *pAd,
+		   struct rt_header_802_11 * pHdr80211,
+		   u8 *Addr1, u8 *Addr2, u8 *Addr3)
 {
-    NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
-    pHdr80211->FC.Type = BTYPE_MGMT;
-    pHdr80211->FC.SubType = SUBTYPE_ACTION;
+	NdisZeroMemory(pHdr80211, sizeof(struct rt_header_802_11));
+	pHdr80211->FC.Type = BTYPE_MGMT;
+	pHdr80211->FC.SubType = SUBTYPE_ACTION;
 
-    COPY_MAC_ADDR(pHdr80211->Addr1, Addr1);
+	COPY_MAC_ADDR(pHdr80211->Addr1, Addr1);
 	COPY_MAC_ADDR(pHdr80211->Addr2, Addr2);
-    COPY_MAC_ADDR(pHdr80211->Addr3, Addr3);
+	COPY_MAC_ADDR(pHdr80211->Addr3, Addr3);
 }
 
-VOID BarHeaderInit(
-	IN	PRTMP_ADAPTER	pAd,
-	IN OUT PFRAME_BAR pCntlBar,
-	IN PUCHAR pDA,
-	IN PUCHAR pSA)
+void BarHeaderInit(struct rt_rtmp_adapter *pAd,
+		   struct rt_frame_bar * pCntlBar, u8 *pDA, u8 *pSA)
 {
-	NdisZeroMemory(pCntlBar, sizeof(FRAME_BAR));
+	NdisZeroMemory(pCntlBar, sizeof(struct rt_frame_bar));
 	pCntlBar->FC.Type = BTYPE_CNTL;
 	pCntlBar->FC.SubType = SUBTYPE_BLOCK_ACK_REQ;
-   	pCntlBar->BarControl.MTID = 0;
+	pCntlBar->BarControl.MTID = 0;
 	pCntlBar->BarControl.Compressed = 1;
 	pCntlBar->BarControl.ACKPolicy = 0;
 
-
-	pCntlBar->Duration = 16 + RTMPCalcDuration(pAd, RATE_1, sizeof(FRAME_BA));
+	pCntlBar->Duration =
+	    16 + RTMPCalcDuration(pAd, RATE_1, sizeof(struct rt_frame_ba));
 
 	COPY_MAC_ADDR(pCntlBar->Addr1, pDA);
 	COPY_MAC_ADDR(pCntlBar->Addr2, pSA);
 }
 
-
 /*
 	==========================================================================
 	Description:
@@ -586,19 +591,14 @@
 	Return	: None.
 	==========================================================================
  */
-VOID InsertActField(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pFrameBuf,
-	OUT PULONG pFrameLen,
-	IN UINT8 Category,
-	IN UINT8 ActCode)
+void InsertActField(struct rt_rtmp_adapter *pAd,
+		    u8 *pFrameBuf,
+		    unsigned long *pFrameLen, u8 Category, u8 ActCode)
 {
-	ULONG TempLen;
+	unsigned long TempLen;
 
-	MakeOutgoingFrame(	pFrameBuf,		&TempLen,
-						1,				&Category,
-						1,				&ActCode,
-						END_OF_ARGS);
+	MakeOutgoingFrame(pFrameBuf, &TempLen,
+			  1, &Category, 1, &ActCode, END_OF_ARGS);
 
 	*pFrameLen = *pFrameLen + TempLen;
 
diff --git a/drivers/staging/rt2860/common/action.h b/drivers/staging/rt2860/common/action.h
index cfc2a5f..974f8b8 100644
--- a/drivers/staging/rt2860/common/action.h
+++ b/drivers/staging/rt2860/common/action.h
@@ -39,23 +39,18 @@
 #ifndef	__ACTION_H__
 #define	__ACTION_H__
 
-typedef struct PACKED __HT_INFO_OCTET
-{
-	UCHAR	Request:1;
-	UCHAR	Forty_MHz_Intolerant:1;
-	UCHAR 	STA_Channel_Width:1;
-	UCHAR	Reserved:5;
-} HT_INFORMATION_OCTET;
+struct PACKED rt_ht_information_octet {
+	u8 Request:1;
+	u8 Forty_MHz_Intolerant:1;
+	u8 STA_Channel_Width:1;
+	u8 Reserved:5;
+};
 
-
-typedef struct PACKED __FRAME_HT_INFO
-{
-	HEADER_802_11   		Hdr;
-	UCHAR					Category;
-	UCHAR					Action;
-	HT_INFORMATION_OCTET	HT_Info;
-}   FRAME_HT_INFO, *PFRAME_HT_INFO;
+struct PACKED rt_frame_ht_info {
+	struct rt_header_802_11 Hdr;
+	u8 Category;
+	u8 Action;
+	struct rt_ht_information_octet HT_Info;
+};
 
 #endif /* __ACTION_H__ */
-
-
diff --git a/drivers/staging/rt2860/common/ba_action.c b/drivers/staging/rt2860/common/ba_action.c
index b7bbe99..174f2a73 100644
--- a/drivers/staging/rt2860/common/ba_action.c
+++ b/drivers/staging/rt2860/common/ba_action.c
@@ -27,42 +27,33 @@
 
 #include "../rt_config.h"
 
-
-
-#define BA_ORI_INIT_SEQ		(pEntry->TxSeq[TID]) //1			// inital sequence number of BA session
+#define BA_ORI_INIT_SEQ		(pEntry->TxSeq[TID])	/*1                        // inital sequence number of BA session */
 
 #define ORI_SESSION_MAX_RETRY	8
-#define ORI_BA_SESSION_TIMEOUT	(2000)	// ms
-#define REC_BA_SESSION_IDLE_TIMEOUT	(1000)	// ms
+#define ORI_BA_SESSION_TIMEOUT	(2000)	/* ms */
+#define REC_BA_SESSION_IDLE_TIMEOUT	(1000)	/* ms */
 
-#define REORDERING_PACKET_TIMEOUT		((100 * HZ)/1000)	// system ticks -- 100 ms
-#define MAX_REORDERING_PACKET_TIMEOUT	((3000 * HZ)/1000)	// system ticks -- 100 ms
+#define REORDERING_PACKET_TIMEOUT		((100 * OS_HZ)/1000)	/* system ticks -- 100 ms */
+#define MAX_REORDERING_PACKET_TIMEOUT	((3000 * OS_HZ)/1000)	/* system ticks -- 100 ms */
 
 #define RESET_RCV_SEQ		(0xFFFF)
 
-static void ba_mpdu_blk_free(PRTMP_ADAPTER pAd, struct reordering_mpdu *mpdu_blk);
+static void ba_mpdu_blk_free(struct rt_rtmp_adapter *pAd,
+			     struct reordering_mpdu *mpdu_blk);
 
+struct rt_ba_ori_entry *BATableAllocOriEntry(struct rt_rtmp_adapter *pAd, u16 * Idx);
 
-BA_ORI_ENTRY *BATableAllocOriEntry(
-								  IN  PRTMP_ADAPTER   pAd,
-								  OUT USHORT          *Idx);
+struct rt_ba_rec_entry *BATableAllocRecEntry(struct rt_rtmp_adapter *pAd, u16 * Idx);
 
-BA_REC_ENTRY *BATableAllocRecEntry(
-								  IN  PRTMP_ADAPTER   pAd,
-								  OUT USHORT          *Idx);
+void BAOriSessionSetupTimeout(void *SystemSpecific1,
+			      void *FunctionContext,
+			      void *SystemSpecific2,
+			      void *SystemSpecific3);
 
-VOID BAOriSessionSetupTimeout(
-    IN PVOID SystemSpecific1,
-    IN PVOID FunctionContext,
-    IN PVOID SystemSpecific2,
-    IN PVOID SystemSpecific3);
-
-VOID BARecSessionIdleTimeout(
-    IN PVOID SystemSpecific1,
-    IN PVOID FunctionContext,
-    IN PVOID SystemSpecific2,
-    IN PVOID SystemSpecific3);
-
+void BARecSessionIdleTimeout(void *SystemSpecific1,
+			     void *FunctionContext,
+			     void *SystemSpecific2,
+			     void *SystemSpecific3);
 
 BUILD_TIMER_FUNCTION(BAOriSessionSetupTimeout);
 BUILD_TIMER_FUNCTION(BARecSessionIdleTimeout);
@@ -70,91 +61,78 @@
 #define ANNOUNCE_REORDERING_PACKET(_pAd, _mpdu_blk)	\
 			Announce_Reordering_Packet(_pAd, _mpdu_blk);
 
-VOID BA_MaxWinSizeReasign(
-	IN PRTMP_ADAPTER	pAd,
-	IN MAC_TABLE_ENTRY  *pEntryPeer,
-	OUT UCHAR			*pWinSize)
+void BA_MaxWinSizeReasign(struct rt_rtmp_adapter *pAd,
+			  struct rt_mac_table_entry *pEntryPeer, u8 * pWinSize)
 {
-	UCHAR MaxSize;
+	u8 MaxSize;
 
-
-	if (pAd->MACVersion >= RALINK_2883_VERSION) // 3*3
+	if (pAd->MACVersion >= RALINK_2883_VERSION)	/* 3*3 */
 	{
-		if (pAd->MACVersion >= RALINK_3070_VERSION)
-		{
-			if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled)
-				MaxSize = 7; // for non-open mode
+		if (pAd->MACVersion >= RALINK_3070_VERSION) {
+			if (pEntryPeer->WepStatus !=
+			    Ndis802_11EncryptionDisabled)
+				MaxSize = 7;	/* for non-open mode */
 			else
 				MaxSize = 13;
-		}
-		else
+		} else
 			MaxSize = 31;
-	}
-	else if (pAd->MACVersion >= RALINK_2880E_VERSION) // 2880 e
+	} else if (pAd->MACVersion >= RALINK_2880E_VERSION)	/* 2880 e */
 	{
 		if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled)
-			MaxSize = 7; // for non-open mode
+			MaxSize = 7;	/* for non-open mode */
 		else
 			MaxSize = 13;
-	}
-	else
+	} else
 		MaxSize = 7;
 
 	DBGPRINT(RT_DEBUG_TRACE, ("ba> Win Size = %d, Max Size = %d\n",
-			*pWinSize, MaxSize));
+				  *pWinSize, MaxSize));
 
-	if ((*pWinSize) > MaxSize)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("ba> reassign max win size from %d to %d\n",
-				*pWinSize, MaxSize));
+	if ((*pWinSize) > MaxSize) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("ba> reassign max win size from %d to %d\n",
+			  *pWinSize, MaxSize));
 
 		*pWinSize = MaxSize;
 	}
 }
 
-void Announce_Reordering_Packet(IN PRTMP_ADAPTER			pAd,
-								IN struct reordering_mpdu	*mpdu)
+void Announce_Reordering_Packet(struct rt_rtmp_adapter *pAd,
+				IN struct reordering_mpdu *mpdu)
 {
-	PNDIS_PACKET    pPacket;
+	void *pPacket;
 
 	pPacket = mpdu->pPacket;
 
-	if (mpdu->bAMSDU)
-	{
+	if (mpdu->bAMSDU) {
 		ASSERT(0);
 		BA_Reorder_AMSDU_Annnounce(pAd, pPacket);
-	}
-	else
-	{
-		//
-		// pass this 802.3 packet to upper layer or forward this packet to WM directly
-		//
+	} else {
+		/* */
+		/* pass this 802.3 packet to upper layer or forward this packet to WM directly */
+		/* */
 
-		ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket, RTMP_GET_PACKET_IF(pPacket));
+		ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket,
+						 RTMP_GET_PACKET_IF(pPacket));
 	}
 }
 
 /*
  * Insert a reordering mpdu into sorted linked list by sequence no.
  */
-BOOLEAN ba_reordering_mpdu_insertsorted(struct reordering_list *list, struct reordering_mpdu *mpdu)
+BOOLEAN ba_reordering_mpdu_insertsorted(struct reordering_list *list,
+					struct reordering_mpdu *mpdu)
 {
 
 	struct reordering_mpdu **ppScan = &list->next;
 
-	while (*ppScan != NULL)
-	{
-		if (SEQ_SMALLER((*ppScan)->Sequence, mpdu->Sequence, MAXSEQ))
-		{
+	while (*ppScan != NULL) {
+		if (SEQ_SMALLER((*ppScan)->Sequence, mpdu->Sequence, MAXSEQ)) {
 			ppScan = &(*ppScan)->next;
-		}
-		else if ((*ppScan)->Sequence == mpdu->Sequence)
-		{
+		} else if ((*ppScan)->Sequence == mpdu->Sequence) {
 			/* give up this duplicated frame */
-			return(FALSE);
-		}
-		else
-		{
+			return (FALSE);
+		} else {
 			/* find position */
 			break;
 		}
@@ -166,11 +144,11 @@
 	return TRUE;
 }
 
-
 /*
  * caller lock critical section if necessary
  */
-static inline void ba_enqueue(struct reordering_list *list, struct reordering_mpdu *mpdu_blk)
+static inline void ba_enqueue(struct reordering_list *list,
+			      struct reordering_mpdu *mpdu_blk)
 {
 	list->qlen++;
 	mpdu_blk->next = list->next;
@@ -180,47 +158,46 @@
 /*
  * caller lock critical section if necessary
  */
-static inline struct reordering_mpdu * ba_dequeue(struct reordering_list *list)
+static inline struct reordering_mpdu *ba_dequeue(struct reordering_list *list)
 {
 	struct reordering_mpdu *mpdu_blk = NULL;
 
 	ASSERT(list);
 
-		if (list->qlen)
-		{
-			list->qlen--;
-			mpdu_blk = list->next;
-			if (mpdu_blk)
-			{
-				list->next = mpdu_blk->next;
-				mpdu_blk->next = NULL;
-			}
+	if (list->qlen) {
+		list->qlen--;
+		mpdu_blk = list->next;
+		if (mpdu_blk) {
+			list->next = mpdu_blk->next;
+			mpdu_blk->next = NULL;
 		}
+	}
 	return mpdu_blk;
 }
 
-
-static inline struct reordering_mpdu  *ba_reordering_mpdu_dequeue(struct reordering_list *list)
+static inline struct reordering_mpdu *ba_reordering_mpdu_dequeue(struct
+								 reordering_list
+								 *list)
 {
-	return(ba_dequeue(list));
+	return (ba_dequeue(list));
 }
 
-
-static inline struct reordering_mpdu  *ba_reordering_mpdu_probe(struct reordering_list *list)
-	{
+static inline struct reordering_mpdu *ba_reordering_mpdu_probe(struct
+							       reordering_list
+							       *list)
+{
 	ASSERT(list);
 
-		return(list->next);
-	}
-
+	return (list->next);
+}
 
 /*
  * free all resource for reordering mechanism
  */
-void ba_reordering_resource_release(PRTMP_ADAPTER pAd)
+void ba_reordering_resource_release(struct rt_rtmp_adapter *pAd)
 {
-	BA_TABLE        *Tab;
-	PBA_REC_ENTRY   pBAEntry;
+	struct rt_ba_table *Tab;
+	struct rt_ba_rec_entry *pBAEntry;
 	struct reordering_mpdu *mpdu_blk;
 	int i;
 
@@ -228,15 +205,14 @@
 
 	/* I.  release all pending reordering packet */
 	NdisAcquireSpinLock(&pAd->BATabLock);
-	for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
-	{
+	for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++) {
 		pBAEntry = &Tab->BARecEntry[i];
-		if (pBAEntry->REC_BA_Status != Recipient_NONE)
-		{
-			while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list)))
-			{
+		if (pBAEntry->REC_BA_Status != Recipient_NONE) {
+			while ((mpdu_blk =
+				ba_reordering_mpdu_dequeue(&pBAEntry->list))) {
 				ASSERT(mpdu_blk->pPacket);
-				RELEASE_NDIS_PACKET(pAd, mpdu_blk->pPacket, NDIS_STATUS_FAILURE);
+				RELEASE_NDIS_PACKET(pAd, mpdu_blk->pPacket,
+						    NDIS_STATUS_FAILURE);
 				ba_mpdu_blk_free(pAd, mpdu_blk);
 			}
 		}
@@ -250,15 +226,13 @@
 	NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
 }
 
-
-
 /*
  * Allocate all resource for reordering mechanism
  */
-BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num)
+BOOLEAN ba_reordering_resource_init(struct rt_rtmp_adapter *pAd, int num)
 {
-	int     i;
-	PUCHAR  mem;
+	int i;
+	u8 *mem;
 	struct reordering_mpdu *mpdu_blk;
 	struct reordering_list *freelist;
 
@@ -270,24 +244,26 @@
 	freelist->next = NULL;
 	freelist->qlen = 0;
 
-	DBGPRINT(RT_DEBUG_TRACE, ("Allocate %d memory for BA reordering\n", (UINT32)(num*sizeof(struct reordering_mpdu))));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("Allocate %d memory for BA reordering\n",
+		  (u32)(num * sizeof(struct reordering_mpdu))));
 
 	/* allocate number of mpdu_blk memory */
-	os_alloc_mem(pAd, (PUCHAR *)&mem, (num*sizeof(struct reordering_mpdu)));
+	os_alloc_mem(pAd, (u8 **) & mem,
+		     (num * sizeof(struct reordering_mpdu)));
 
 	pAd->mpdu_blk_pool.mem = mem;
 
-	if (mem == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Can't Allocate Memory for BA Reordering\n"));
-		return(FALSE);
+	if (mem == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("Can't Allocate Memory for BA Reordering\n"));
+		return (FALSE);
 	}
 
 	/* build mpdu_blk free list */
-	for (i=0; i<num; i++)
-	{
+	for (i = 0; i < num; i++) {
 		/* get mpdu_blk */
-		mpdu_blk = (struct reordering_mpdu *) mem;
+		mpdu_blk = (struct reordering_mpdu *)mem;
 		/* initial mpdu_blk */
 		NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu));
 		/* next mpdu_blk */
@@ -296,20 +272,19 @@
 		ba_enqueue(freelist, mpdu_blk);
 	}
 
-	return(TRUE);
+	return (TRUE);
 }
 
-//static int blk_count=0; // sample take off, no use
+/*static int blk_count=0; // sample take off, no use */
 
-static struct reordering_mpdu *ba_mpdu_blk_alloc(PRTMP_ADAPTER pAd)
+static struct reordering_mpdu *ba_mpdu_blk_alloc(struct rt_rtmp_adapter *pAd)
 {
 	struct reordering_mpdu *mpdu_blk;
 
 	NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
 	mpdu_blk = ba_dequeue(&pAd->mpdu_blk_pool.freelist);
-	if (mpdu_blk)
-	{
-//		blk_count++;
+	if (mpdu_blk) {
+/*              blk_count++; */
 		/* reset mpdu_blk */
 		NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu));
 	}
@@ -317,43 +292,40 @@
 	return mpdu_blk;
 }
 
-static void ba_mpdu_blk_free(PRTMP_ADAPTER pAd, struct reordering_mpdu *mpdu_blk)
+static void ba_mpdu_blk_free(struct rt_rtmp_adapter *pAd,
+			     struct reordering_mpdu *mpdu_blk)
 {
 	ASSERT(mpdu_blk);
 
 	NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
-//	blk_count--;
+/*      blk_count--; */
 	ba_enqueue(&pAd->mpdu_blk_pool.freelist, mpdu_blk);
 	NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
 }
 
-
-static USHORT ba_indicate_reordering_mpdus_in_order(
-												   IN PRTMP_ADAPTER    pAd,
-												   IN PBA_REC_ENTRY    pBAEntry,
-												   IN USHORT           StartSeq)
+static u16 ba_indicate_reordering_mpdus_in_order(struct rt_rtmp_adapter *pAd,
+						    struct rt_ba_rec_entry *pBAEntry,
+						    u16 StartSeq)
 {
 	struct reordering_mpdu *mpdu_blk;
-	USHORT  LastIndSeq = RESET_RCV_SEQ;
+	u16 LastIndSeq = RESET_RCV_SEQ;
 
 	NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
 
-	while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list)))
-		{
-			/* find in-order frame */
-		if (!SEQ_STEPONE(mpdu_blk->Sequence, StartSeq, MAXSEQ))
-			{
-				break;
-			}
-			/* dequeue in-order frame from reodering list */
-			mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
-			/* pass this frame up */
+	while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list))) {
+		/* find in-order frame */
+		if (!SEQ_STEPONE(mpdu_blk->Sequence, StartSeq, MAXSEQ)) {
+			break;
+		}
+		/* dequeue in-order frame from reodering list */
+		mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
+		/* pass this frame up */
 		ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
 		/* move to next sequence */
-			StartSeq = mpdu_blk->Sequence;
+		StartSeq = mpdu_blk->Sequence;
 		LastIndSeq = StartSeq;
 		/* free mpdu_blk */
-			ba_mpdu_blk_free(pAd, mpdu_blk);
+		ba_mpdu_blk_free(pAd, mpdu_blk);
 	}
 
 	NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
@@ -362,51 +334,44 @@
 	return LastIndSeq;
 }
 
-static void ba_indicate_reordering_mpdus_le_seq(
-											   IN PRTMP_ADAPTER    pAd,
-											   IN PBA_REC_ENTRY    pBAEntry,
-											   IN USHORT           Sequence)
+static void ba_indicate_reordering_mpdus_le_seq(struct rt_rtmp_adapter *pAd,
+						struct rt_ba_rec_entry *pBAEntry,
+						u16 Sequence)
 {
 	struct reordering_mpdu *mpdu_blk;
 
 	NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
-	while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list)))
-		{
-			/* find in-order frame */
-		if ((mpdu_blk->Sequence == Sequence) || SEQ_SMALLER(mpdu_blk->Sequence, Sequence, MAXSEQ))
-		{
+	while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list))) {
+		/* find in-order frame */
+		if ((mpdu_blk->Sequence == Sequence)
+		    || SEQ_SMALLER(mpdu_blk->Sequence, Sequence, MAXSEQ)) {
 			/* dequeue in-order frame from reodering list */
 			mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
 			/* pass this frame up */
 			ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
 			/* free mpdu_blk */
 			ba_mpdu_blk_free(pAd, mpdu_blk);
+		} else {
+			break;
 		}
-		else
-			{
-				break;
-			}
 	}
 	NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
 }
 
-
-static void ba_refresh_reordering_mpdus(
-									   IN PRTMP_ADAPTER    pAd,
-									   PBA_REC_ENTRY       pBAEntry)
+static void ba_refresh_reordering_mpdus(struct rt_rtmp_adapter *pAd,
+					struct rt_ba_rec_entry *pBAEntry)
 {
 	struct reordering_mpdu *mpdu_blk;
 
 	NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
 
-			/* dequeue in-order frame from reodering list */
-	while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list)))
-	{
-			/* pass this frame up */
+	/* dequeue in-order frame from reodering list */
+	while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list))) {
+		/* pass this frame up */
 		ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
 
 		pBAEntry->LastIndSeq = mpdu_blk->Sequence;
-			ba_mpdu_blk_free(pAd, mpdu_blk);
+		ba_mpdu_blk_free(pAd, mpdu_blk);
 
 		/* update last indicated sequence */
 	}
@@ -415,248 +380,240 @@
 	NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
 }
 
-
-//static
-void ba_flush_reordering_timeout_mpdus(
-									IN PRTMP_ADAPTER    pAd,
-									IN PBA_REC_ENTRY    pBAEntry,
-									IN ULONG            Now32)
-
+/*static */
+void ba_flush_reordering_timeout_mpdus(struct rt_rtmp_adapter *pAd,
+				       struct rt_ba_rec_entry *pBAEntry,
+				       unsigned long Now32)
 {
-	USHORT Sequence;
+	u16 Sequence;
 
-//	if ((RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+REORDERING_PACKET_TIMEOUT)) &&
-//		 (pBAEntry->list.qlen > ((pBAEntry->BAWinSize*7)/8))) //||
-//		(RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(10*REORDERING_PACKET_TIMEOUT))) &&
-//		 (pBAEntry->list.qlen > (pBAEntry->BAWinSize/8)))
-	if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(MAX_REORDERING_PACKET_TIMEOUT/6)))
-		 &&(pBAEntry->list.qlen > 1)
-		)
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("timeout[%d] (%08lx-%08lx = %d > %d): %x, flush all!\n ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer),
-			   (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), MAX_REORDERING_PACKET_TIMEOUT,
-			   pBAEntry->LastIndSeq));
+/*      if ((RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+REORDERING_PACKET_TIMEOUT)) && */
+/*               (pBAEntry->list.qlen > ((pBAEntry->BAWinSize*7)/8))) //|| */
+/*              (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(10*REORDERING_PACKET_TIMEOUT))) && */
+/*               (pBAEntry->list.qlen > (pBAEntry->BAWinSize/8))) */
+	if (RTMP_TIME_AFTER
+	    ((unsigned long)Now32,
+	     (unsigned long)(pBAEntry->LastIndSeqAtTimer +
+			     (MAX_REORDERING_PACKET_TIMEOUT / 6)))
+	    && (pBAEntry->list.qlen > 1)
+	    ) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("timeout[%d] (%08lx-%08lx = %d > %d): %x, flush all!\n ",
+			  pBAEntry->list.qlen, Now32,
+			  (pBAEntry->LastIndSeqAtTimer),
+			  (int)((long)Now32 -
+				(long)(pBAEntry->LastIndSeqAtTimer)),
+			  MAX_REORDERING_PACKET_TIMEOUT, pBAEntry->LastIndSeq));
 		ba_refresh_reordering_mpdus(pAd, pBAEntry);
 		pBAEntry->LastIndSeqAtTimer = Now32;
-	}
-	else
-	if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
+	} else
+	    if (RTMP_TIME_AFTER
+		((unsigned long)Now32,
+		 (unsigned long)(pBAEntry->LastIndSeqAtTimer +
+				 (REORDERING_PACKET_TIMEOUT)))
 		&& (pBAEntry->list.qlen > 0)
-	   )
-		{
-    		//
-		// force LastIndSeq to shift to LastIndSeq+1
-    		//
-    		Sequence = (pBAEntry->LastIndSeq+1) & MAXSEQ;
-    		ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
-    		pBAEntry->LastIndSeqAtTimer = Now32;
+	    ) {
+		/* */
+		/* force LastIndSeq to shift to LastIndSeq+1 */
+		/* */
+		Sequence = (pBAEntry->LastIndSeq + 1) & MAXSEQ;
+		ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
+		pBAEntry->LastIndSeqAtTimer = Now32;
+		pBAEntry->LastIndSeq = Sequence;
+		/* */
+		/* indicate in-order mpdus */
+		/* */
+		Sequence =
+		    ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry,
+							  Sequence);
+		if (Sequence != RESET_RCV_SEQ) {
 			pBAEntry->LastIndSeq = Sequence;
-    		//
-    		// indicate in-order mpdus
-    		//
-    		Sequence = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, Sequence);
-    		if (Sequence != RESET_RCV_SEQ)
-    		{
-    			pBAEntry->LastIndSeq = Sequence;
-    		}
+		}
+
+		DBGPRINT(RT_DEBUG_OFF,
+			 ("%x, flush one!\n", pBAEntry->LastIndSeq));
 
 	}
 }
 
-
 /*
  * generate ADDBA request to
  * set up BA agreement
  */
-VOID BAOriSessionSetUp(
-					  IN PRTMP_ADAPTER    pAd,
-					  IN MAC_TABLE_ENTRY  *pEntry,
-					  IN UCHAR            TID,
-					  IN USHORT           TimeOut,
-					  IN ULONG            DelayTime,
-					  IN BOOLEAN          isForced)
-
+void BAOriSessionSetUp(struct rt_rtmp_adapter *pAd,
+		       struct rt_mac_table_entry *pEntry,
+		       u8 TID,
+		       u16 TimeOut,
+		       unsigned long DelayTime, IN BOOLEAN isForced)
 {
-	//MLME_ADDBA_REQ_STRUCT	AddbaReq;
-	BA_ORI_ENTRY            *pBAEntry = NULL;
-	USHORT                  Idx;
-	BOOLEAN                 Cancelled;
+	/*struct rt_mlme_addba_req AddbaReq; */
+	struct rt_ba_ori_entry *pBAEntry = NULL;
+	u16 Idx;
+	BOOLEAN Cancelled;
 
-	if ((pAd->CommonCfg.BACapability.field.AutoBA != TRUE)  &&  (isForced == FALSE))
+	if ((pAd->CommonCfg.BACapability.field.AutoBA != TRUE)
+	    && (isForced == FALSE))
 		return;
 
-	// if this entry is limited to use legacy tx mode, it doesn't generate BA.
+	/* if this entry is limited to use legacy tx mode, it doesn't generate BA. */
 	if (RTMPStaFixedTxMode(pAd, pEntry) != FIXED_TXMODE_HT)
 		return;
 
-	if ((pEntry->BADeclineBitmap & (1<<TID)) && (isForced == FALSE))
-	{
-		// try again after 3 secs
+	if ((pEntry->BADeclineBitmap & (1 << TID)) && (isForced == FALSE)) {
+		/* try again after 3 secs */
 		DelayTime = 3000;
-//		printk("DeCline BA from Peer\n");
-//		return;
+/*              DBGPRINT(RT_DEBUG_TRACE, ("DeCline BA from Peer\n")); */
+/*              return; */
 	}
 
-
 	Idx = pEntry->BAOriWcidArray[TID];
-	if (Idx == 0)
-	{
-		// allocate a BA session
+	if (Idx == 0) {
+		/* allocate a BA session */
 		pBAEntry = BATableAllocOriEntry(pAd, &Idx);
-		if (pBAEntry == NULL)
-		{
-			DBGPRINT(RT_DEBUG_TRACE,("ADDBA - MlmeADDBAAction() allocate BA session failed \n"));
+		if (pBAEntry == NULL) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("ADDBA - MlmeADDBAAction() allocate BA session failed \n"));
 			return;
 		}
-	}
-	else
-	{
-		pBAEntry =&pAd->BATable.BAOriEntry[Idx];
+	} else {
+		pBAEntry = &pAd->BATable.BAOriEntry[Idx];
 	}
 
-	if (pBAEntry->ORI_BA_Status >= Originator_WaitRes)
-	{
+	if (pBAEntry->ORI_BA_Status >= Originator_WaitRes) {
 		return;
 	}
 
 	pEntry->BAOriWcidArray[TID] = Idx;
 
-	// Initialize BA session
+	/* Initialize BA session */
 	pBAEntry->ORI_BA_Status = Originator_WaitRes;
 	pBAEntry->Wcid = pEntry->Aid;
 	pBAEntry->BAWinSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit;
 	pBAEntry->Sequence = BA_ORI_INIT_SEQ;
-	pBAEntry->Token = 1;	// (2008-01-21) Jan Lee recommends it - this token can't be 0
+	pBAEntry->Token = 1;	/* (2008-01-21) Jan Lee recommends it - this token can't be 0 */
 	pBAEntry->TID = TID;
 	pBAEntry->TimeOutValue = TimeOut;
 	pBAEntry->pAdapter = pAd;
 
-	DBGPRINT(RT_DEBUG_TRACE,("Send AddBA to %02x:%02x:%02x:%02x:%02x:%02x Tid:%d isForced:%d Wcid:%d\n"
-		,pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2]
-		,pEntry->Addr[3],pEntry->Addr[4],pEntry->Addr[5]
-		,TID,isForced,pEntry->Aid));
-
-	if (!(pEntry->TXBAbitmap & (1<<TID)))
-	{
-		RTMPInitTimer(pAd, &pBAEntry->ORIBATimer, GET_TIMER_FUNCTION(BAOriSessionSetupTimeout), pBAEntry, FALSE);
-	}
-	else
+	if (!(pEntry->TXBAbitmap & (1 << TID))) {
+		RTMPInitTimer(pAd, &pBAEntry->ORIBATimer,
+			      GET_TIMER_FUNCTION(BAOriSessionSetupTimeout),
+			      pBAEntry, FALSE);
+	} else
 		RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
 
-	// set timer to send ADDBA request
+	/* set timer to send ADDBA request */
 	RTMPSetTimer(&pBAEntry->ORIBATimer, DelayTime);
 }
 
-VOID BAOriSessionAdd(
-			IN PRTMP_ADAPTER    pAd,
-					IN MAC_TABLE_ENTRY  *pEntry,
-			IN PFRAME_ADDBA_RSP pFrame)
+void BAOriSessionAdd(struct rt_rtmp_adapter *pAd,
+		     struct rt_mac_table_entry *pEntry, struct rt_frame_addba_rsp * pFrame)
 {
-	BA_ORI_ENTRY  *pBAEntry = NULL;
-	BOOLEAN       Cancelled;
-	UCHAR         TID;
-	USHORT        Idx;
-	PUCHAR          pOutBuffer2 = NULL;
-	NDIS_STATUS     NStatus;
-	ULONG           FrameLen;
-	FRAME_BAR       FrameBar;
+	struct rt_ba_ori_entry *pBAEntry = NULL;
+	BOOLEAN Cancelled;
+	u8 TID;
+	u16 Idx;
+	u8 *pOutBuffer2 = NULL;
+	int NStatus;
+	unsigned long FrameLen;
+	struct rt_frame_bar FrameBar;
 
 	TID = pFrame->BaParm.TID;
 	Idx = pEntry->BAOriWcidArray[TID];
-	pBAEntry =&pAd->BATable.BAOriEntry[Idx];
+	pBAEntry = &pAd->BATable.BAOriEntry[Idx];
 
-	// Start fill in parameters.
-	if ((Idx !=0) && (pBAEntry->TID == TID) && (pBAEntry->ORI_BA_Status == Originator_WaitRes))
-	{
-		pBAEntry->BAWinSize = min(pBAEntry->BAWinSize, ((UCHAR)pFrame->BaParm.BufSize));
+	/* Start fill in parameters. */
+	if ((Idx != 0) && (pBAEntry->TID == TID)
+	    && (pBAEntry->ORI_BA_Status == Originator_WaitRes)) {
+		pBAEntry->BAWinSize =
+		    min(pBAEntry->BAWinSize, ((u8)pFrame->BaParm.BufSize));
 		BA_MaxWinSizeReasign(pAd, pEntry, &pBAEntry->BAWinSize);
 
 		pBAEntry->TimeOutValue = pFrame->TimeOutValue;
 		pBAEntry->ORI_BA_Status = Originator_Done;
-		// reset sequence number
+		pAd->BATable.numDoneOriginator++;
+
+		/* reset sequence number */
 		pBAEntry->Sequence = BA_ORI_INIT_SEQ;
-		// Set Bitmap flag.
-		pEntry->TXBAbitmap |= (1<<TID);
-				RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
+		/* Set Bitmap flag. */
+		pEntry->TXBAbitmap |= (1 << TID);
+		RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
 
-		pBAEntry->ORIBATimer.TimerValue = 0;	//pFrame->TimeOutValue;
+		pBAEntry->ORIBATimer.TimerValue = 0;	/*pFrame->TimeOutValue; */
 
-		DBGPRINT(RT_DEBUG_TRACE,("%s : TXBAbitmap = %x, BAWinSize = %d, TimeOut = %ld\n", __func__, pEntry->TXBAbitmap,
-								 pBAEntry->BAWinSize, pBAEntry->ORIBATimer.TimerValue));
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("%s : TXBAbitmap = %x, BAWinSize = %d, TimeOut = %ld\n",
+			  __func__, pEntry->TXBAbitmap, pBAEntry->BAWinSize,
+			  pBAEntry->ORIBATimer.TimerValue));
 
-		// SEND BAR ;
-		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2);  //Get an unused nonpaged memory
-		if (NStatus != NDIS_STATUS_SUCCESS)
-		{
-			DBGPRINT(RT_DEBUG_TRACE,("BA - BAOriSessionAdd() allocate memory failed \n"));
+		/* SEND BAR ; */
+		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2);	/*Get an unused nonpaged memory */
+		if (NStatus != NDIS_STATUS_SUCCESS) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("BA - BAOriSessionAdd() allocate memory failed \n"));
 			return;
 		}
 
-		BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pBAEntry->Wcid].Addr, pAd->CurrentAddress);
+		BarHeaderInit(pAd, &FrameBar,
+			      pAd->MacTab.Content[pBAEntry->Wcid].Addr,
+			      pAd->CurrentAddress);
 
-		FrameBar.StartingSeq.field.FragNum = 0;	// make sure sequence not clear in DEL function.
-		FrameBar.StartingSeq.field.StartSeq = pBAEntry->Sequence; // make sure sequence not clear in DEL funciton.
-		FrameBar.BarControl.TID = pBAEntry->TID; // make sure sequence not clear in DEL funciton.
-		MakeOutgoingFrame(pOutBuffer2,              &FrameLen,
-						  sizeof(FRAME_BAR),      &FrameBar,
-					  END_OF_ARGS);
+		FrameBar.StartingSeq.field.FragNum = 0;	/* make sure sequence not clear in DEL function. */
+		FrameBar.StartingSeq.field.StartSeq = pBAEntry->Sequence;	/* make sure sequence not clear in DEL funciton. */
+		FrameBar.BarControl.TID = pBAEntry->TID;	/* make sure sequence not clear in DEL funciton. */
+		MakeOutgoingFrame(pOutBuffer2, &FrameLen,
+				  sizeof(struct rt_frame_bar), &FrameBar, END_OF_ARGS);
 		MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
 		MlmeFreeMemory(pAd, pOutBuffer2);
 
-
 		if (pBAEntry->ORIBATimer.TimerValue)
-			RTMPSetTimer(&pBAEntry->ORIBATimer, pBAEntry->ORIBATimer.TimerValue); // in mSec
+			RTMPSetTimer(&pBAEntry->ORIBATimer, pBAEntry->ORIBATimer.TimerValue);	/* in mSec */
 	}
 }
 
-BOOLEAN BARecSessionAdd(
-					   IN PRTMP_ADAPTER    pAd,
-					   IN MAC_TABLE_ENTRY  *pEntry,
-					   IN PFRAME_ADDBA_REQ pFrame)
+BOOLEAN BARecSessionAdd(struct rt_rtmp_adapter *pAd,
+			struct rt_mac_table_entry *pEntry, struct rt_frame_addba_req * pFrame)
 {
-	BA_REC_ENTRY            *pBAEntry = NULL;
-	BOOLEAN                 Status = TRUE;
-	BOOLEAN                 Cancelled;
-	USHORT                  Idx;
-	UCHAR                   TID;
-	UCHAR                   BAWinSize;
-	//UINT32                  Value;
-	//UINT                    offset;
-
+	struct rt_ba_rec_entry *pBAEntry = NULL;
+	BOOLEAN Status = TRUE;
+	BOOLEAN Cancelled;
+	u16 Idx;
+	u8 TID;
+	u8 BAWinSize;
+	/*u32                  Value; */
+	/*u32                    offset; */
 
 	ASSERT(pEntry);
 
-	// find TID
+	/* find TID */
 	TID = pFrame->BaParm.TID;
 
-	BAWinSize = min(((UCHAR)pFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
+	BAWinSize =
+	    min(((u8)pFrame->BaParm.BufSize),
+		(u8)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
 
-	// Intel patch
-	if (BAWinSize == 0)
-	{
+	/* Intel patch */
+	if (BAWinSize == 0) {
 		BAWinSize = 64;
 	}
 
 	Idx = pEntry->BARecWcidArray[TID];
 
-
-	if (Idx == 0)
-	{
+	if (Idx == 0) {
 		pBAEntry = BATableAllocRecEntry(pAd, &Idx);
-	}
-	else
-	{
+	} else {
 		pBAEntry = &pAd->BATable.BARecEntry[Idx];
-		// flush all pending reordering mpdus
+		/* flush all pending reordering mpdus */
 		ba_refresh_reordering_mpdus(pAd, pBAEntry);
 	}
 
-	DBGPRINT(RT_DEBUG_TRACE,("%s(%ld): Idx = %d, BAWinSize(req %d) = %d\n", __func__, pAd->BATable.numAsRecipient, Idx,
-							 pFrame->BaParm.BufSize, BAWinSize));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("%s(%ld): Idx = %d, BAWinSize(req %d) = %d\n", __func__,
+		  pAd->BATable.numAsRecipient, Idx, pFrame->BaParm.BufSize,
+		  BAWinSize));
 
-	// Start fill in parameters.
-	if (pBAEntry != NULL)
-	{
+	/* Start fill in parameters. */
+	if (pBAEntry != NULL) {
 		ASSERT(pBAEntry->list.qlen == 0);
 
 		pBAEntry->REC_BA_Status = Recipient_HandleRes;
@@ -665,66 +622,62 @@
 		pBAEntry->TID = TID;
 		pBAEntry->TimeOutValue = pFrame->TimeOutValue;
 		pBAEntry->REC_BA_Status = Recipient_Accept;
-		// initial sequence number
-		pBAEntry->LastIndSeq = RESET_RCV_SEQ; //pFrame->BaStartSeq.field.StartSeq;
+		/* initial sequence number */
+		pBAEntry->LastIndSeq = RESET_RCV_SEQ;	/*pFrame->BaStartSeq.field.StartSeq; */
 
-		printk("Start Seq = %08x\n",  pFrame->BaStartSeq.field.StartSeq);
+		DBGPRINT(RT_DEBUG_OFF,
+			 ("Start Seq = %08x\n",
+			  pFrame->BaStartSeq.field.StartSeq));
 
-		if (pEntry->RXBAbitmap & (1<<TID))
-		{
+		if (pEntry->RXBAbitmap & (1 << TID)) {
 			RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
-		}
-		else
-		{
-			RTMPInitTimer(pAd, &pBAEntry->RECBATimer, GET_TIMER_FUNCTION(BARecSessionIdleTimeout), pBAEntry, TRUE);
+		} else {
+			RTMPInitTimer(pAd, &pBAEntry->RECBATimer,
+				      GET_TIMER_FUNCTION
+				      (BARecSessionIdleTimeout), pBAEntry,
+				      TRUE);
 		}
 
-		// Set Bitmap flag.
-		pEntry->RXBAbitmap |= (1<<TID);
+		/* Set Bitmap flag. */
+		pEntry->RXBAbitmap |= (1 << TID);
 		pEntry->BARecWcidArray[TID] = Idx;
 
-		pEntry->BADeclineBitmap &= ~(1<<TID);
+		pEntry->BADeclineBitmap &= ~(1 << TID);
 
-		// Set BA session mask in WCID table.
-		RT28XX_ADD_BA_SESSION_TO_ASIC(pAd, pEntry->Aid, TID);
+		/* Set BA session mask in WCID table. */
+		RTMP_ADD_BA_SESSION_TO_ASIC(pAd, pEntry->Aid, TID);
 
-		DBGPRINT(RT_DEBUG_TRACE,("MACEntry[%d]RXBAbitmap = 0x%x. BARecWcidArray=%d\n",
-				pEntry->Aid, pEntry->RXBAbitmap, pEntry->BARecWcidArray[TID]));
-	}
-	else
-	{
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("MACEntry[%d]RXBAbitmap = 0x%x. BARecWcidArray=%d\n",
+			  pEntry->Aid, pEntry->RXBAbitmap,
+			  pEntry->BARecWcidArray[TID]));
+	} else {
 		Status = FALSE;
-		DBGPRINT(RT_DEBUG_TRACE,("Can't Accept ADDBA for %02x:%02x:%02x:%02x:%02x:%02x TID = %d\n",
-				PRINT_MAC(pEntry->Addr), TID));
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Can't Accept ADDBA for %02x:%02x:%02x:%02x:%02x:%02x TID = %d\n",
+			  PRINT_MAC(pEntry->Addr), TID));
 	}
-	return(Status);
+	return (Status);
 }
 
-
-BA_REC_ENTRY *BATableAllocRecEntry(
-								  IN  PRTMP_ADAPTER   pAd,
-								  OUT USHORT          *Idx)
+struct rt_ba_rec_entry *BATableAllocRecEntry(struct rt_rtmp_adapter *pAd, u16 * Idx)
 {
-	int             i;
-	BA_REC_ENTRY    *pBAEntry = NULL;
-
+	int i;
+	struct rt_ba_rec_entry *pBAEntry = NULL;
 
 	NdisAcquireSpinLock(&pAd->BATabLock);
 
-	if (pAd->BATable.numAsRecipient >= MAX_BARECI_SESSION)
-	{
-		printk("BA Recipeint Session (%ld) > %d\n", pAd->BATable.numAsRecipient,
-			MAX_BARECI_SESSION);
+	if (pAd->BATable.numAsRecipient >= MAX_BARECI_SESSION) {
+		DBGPRINT(RT_DEBUG_OFF, ("BA Recipeint Session (%ld) > %d\n",
+					pAd->BATable.numAsRecipient,
+					MAX_BARECI_SESSION));
 		goto done;
 	}
-
-	// reserve idx 0 to identify BAWcidArray[TID] as empty
-	for (i=1; i < MAX_LEN_OF_BA_REC_TABLE; i++)
-	{
-		pBAEntry =&pAd->BATable.BARecEntry[i];
-		if ((pBAEntry->REC_BA_Status == Recipient_NONE))
-		{
-			// get one
+	/* reserve idx 0 to identify BAWcidArray[TID] as empty */
+	for (i = 1; i < MAX_LEN_OF_BA_REC_TABLE; i++) {
+		pBAEntry = &pAd->BATable.BARecEntry[i];
+		if ((pBAEntry->REC_BA_Status == Recipient_NONE)) {
+			/* get one */
 			pAd->BATable.numAsRecipient++;
 			pBAEntry->REC_BA_Status = Recipient_USED;
 			*Idx = i;
@@ -737,27 +690,21 @@
 	return pBAEntry;
 }
 
-BA_ORI_ENTRY *BATableAllocOriEntry(
-								  IN  PRTMP_ADAPTER   pAd,
-								  OUT USHORT          *Idx)
+struct rt_ba_ori_entry *BATableAllocOriEntry(struct rt_rtmp_adapter *pAd, u16 * Idx)
 {
-	int             i;
-	BA_ORI_ENTRY    *pBAEntry = NULL;
+	int i;
+	struct rt_ba_ori_entry *pBAEntry = NULL;
 
 	NdisAcquireSpinLock(&pAd->BATabLock);
 
-	if (pAd->BATable.numAsOriginator >= (MAX_LEN_OF_BA_ORI_TABLE))
-	{
+	if (pAd->BATable.numAsOriginator >= (MAX_LEN_OF_BA_ORI_TABLE)) {
 		goto done;
 	}
-
-	// reserve idx 0 to identify BAWcidArray[TID] as empty
-	for (i=1; i<MAX_LEN_OF_BA_ORI_TABLE; i++)
-	{
-		pBAEntry =&pAd->BATable.BAOriEntry[i];
-		if ((pBAEntry->ORI_BA_Status == Originator_NONE))
-		{
-			// get one
+	/* reserve idx 0 to identify BAWcidArray[TID] as empty */
+	for (i = 1; i < MAX_LEN_OF_BA_ORI_TABLE; i++) {
+		pBAEntry = &pAd->BATable.BAOriEntry[i];
+		if ((pBAEntry->ORI_BA_Status == Originator_NONE)) {
+			/* get one */
 			pAd->BATable.numAsOriginator++;
 			pBAEntry->ORI_BA_Status = Originator_USED;
 			pBAEntry->pAdapter = pAd;
@@ -771,32 +718,28 @@
 	return pBAEntry;
 }
 
-
-VOID BATableFreeOriEntry(
-						IN  PRTMP_ADAPTER   pAd,
-						IN  ULONG           Idx)
+void BATableFreeOriEntry(struct rt_rtmp_adapter *pAd, unsigned long Idx)
 {
-	BA_ORI_ENTRY    *pBAEntry = NULL;
-	MAC_TABLE_ENTRY *pEntry;
-
+	struct rt_ba_ori_entry *pBAEntry = NULL;
+	struct rt_mac_table_entry *pEntry;
 
 	if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE))
 		return;
 
-	pBAEntry =&pAd->BATable.BAOriEntry[Idx];
+	pBAEntry = &pAd->BATable.BAOriEntry[Idx];
 
-	if (pBAEntry->ORI_BA_Status != Originator_NONE)
-	{
+	if (pBAEntry->ORI_BA_Status != Originator_NONE) {
 		pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
 		pEntry->BAOriWcidArray[pBAEntry->TID] = 0;
 
-
 		NdisAcquireSpinLock(&pAd->BATabLock);
-		if (pBAEntry->ORI_BA_Status == Originator_Done)
-		{
-		 	pEntry->TXBAbitmap &= (~(1<<(pBAEntry->TID) ));
-			DBGPRINT(RT_DEBUG_TRACE, ("BATableFreeOriEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
-			// Erase Bitmap flag.
+		if (pBAEntry->ORI_BA_Status == Originator_Done) {
+			pAd->BATable.numDoneOriginator -= 1;
+			pEntry->TXBAbitmap &= (~(1 << (pBAEntry->TID)));
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("BATableFreeOriEntry numAsOriginator= %ld\n",
+				  pAd->BATable.numAsRecipient));
+			/* Erase Bitmap flag. */
 		}
 
 		ASSERT(pAd->BATable.numAsOriginator != 0);
@@ -809,22 +752,17 @@
 	}
 }
 
-
-VOID BATableFreeRecEntry(
-						IN  PRTMP_ADAPTER   pAd,
-						IN  ULONG           Idx)
+void BATableFreeRecEntry(struct rt_rtmp_adapter *pAd, unsigned long Idx)
 {
-	BA_REC_ENTRY    *pBAEntry = NULL;
-	MAC_TABLE_ENTRY *pEntry;
-
+	struct rt_ba_rec_entry *pBAEntry = NULL;
+	struct rt_mac_table_entry *pEntry;
 
 	if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_REC_TABLE))
 		return;
 
-	pBAEntry =&pAd->BATable.BARecEntry[Idx];
+	pBAEntry = &pAd->BATable.BARecEntry[Idx];
 
-	if (pBAEntry->REC_BA_Status != Recipient_NONE)
-	{
+	if (pBAEntry->REC_BA_Status != Recipient_NONE) {
 		pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
 		pEntry->BARecWcidArray[pBAEntry->TID] = 0;
 
@@ -839,177 +777,177 @@
 	}
 }
 
-
-VOID BAOriSessionTearDown(
-						 IN OUT  PRTMP_ADAPTER   pAd,
-						 IN      UCHAR           Wcid,
-						 IN      UCHAR           TID,
-						 IN      BOOLEAN         bPassive,
-						 IN      BOOLEAN         bForceSend)
+void BAOriSessionTearDown(struct rt_rtmp_adapter *pAd,
+			  u8 Wcid,
+			  u8 TID,
+			  IN BOOLEAN bPassive, IN BOOLEAN bForceSend)
 {
-	ULONG           Idx = 0;
-	BA_ORI_ENTRY    *pBAEntry;
-	BOOLEAN         Cancelled;
+	unsigned long Idx = 0;
+	struct rt_ba_ori_entry *pBAEntry;
+	BOOLEAN Cancelled;
 
-	if (Wcid >= MAX_LEN_OF_MAC_TABLE)
-	{
+	if (Wcid >= MAX_LEN_OF_MAC_TABLE) {
 		return;
 	}
-
-	//
-	// Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID).
-	//
+	/* */
+	/* Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID). */
+	/* */
 	Idx = pAd->MacTab.Content[Wcid].BAOriWcidArray[TID];
-	if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE))
-	{
-		if (bForceSend == TRUE)
-		{
-			// force send specified TID DelBA
-			MLME_DELBA_REQ_STRUCT   DelbaReq;
-			MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
-			if (Elem == NULL)
-				return;
+	if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE)) {
+		if (bForceSend == TRUE) {
+			/* force send specified TID DelBA */
+			struct rt_mlme_delba_req DelbaReq;
+			struct rt_mlme_queue_elem *Elem =
+			    (struct rt_mlme_queue_elem *)kmalloc(sizeof(struct rt_mlme_queue_elem),
+							MEM_ALLOC_FLAG);
+			if (Elem != NULL) {
+				NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
+				NdisZeroMemory(Elem, sizeof(struct rt_mlme_queue_elem));
 
-			NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
-			NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
-
-			COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
-			DelbaReq.Wcid = Wcid;
-			DelbaReq.TID = TID;
-			DelbaReq.Initiator = ORIGINATOR;
-#if 1
-			Elem->MsgLen  = sizeof(DelbaReq);
-			NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
-			MlmeDELBAAction(pAd, Elem);
-			kfree(Elem);
-#else
-			MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
-			RT28XX_MLME_HANDLER(pAd);
-#endif
+				COPY_MAC_ADDR(DelbaReq.Addr,
+					      pAd->MacTab.Content[Wcid].Addr);
+				DelbaReq.Wcid = Wcid;
+				DelbaReq.TID = TID;
+				DelbaReq.Initiator = ORIGINATOR;
+				Elem->MsgLen = sizeof(DelbaReq);
+				NdisMoveMemory(Elem->Msg, &DelbaReq,
+					       sizeof(DelbaReq));
+				MlmeDELBAAction(pAd, Elem);
+				kfree(Elem);
+			} else {
+				DBGPRINT(RT_DEBUG_ERROR,
+					 ("%s(bForceSend):alloc memory failed!\n",
+					  __func__));
+			}
 		}
 
 		return;
 	}
 
-	DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __func__, Wcid, TID));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("%s===>Wcid=%d.TID=%d \n", __func__, Wcid, TID));
 
 	pBAEntry = &pAd->BATable.BAOriEntry[Idx];
-	DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, ORI_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->ORI_BA_Status));
-	//
-	// Prepare DelBA action frame and send to the peer.
-	//
-	if ((bPassive == FALSE) && (TID == pBAEntry->TID) && (pBAEntry->ORI_BA_Status == Originator_Done))
-	{
-		MLME_DELBA_REQ_STRUCT   DelbaReq;
-		MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
-		if (Elem == NULL)
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("\t===>Idx = %ld, Wcid=%d.TID=%d, ORI_BA_Status = %d \n", Idx,
+		  Wcid, TID, pBAEntry->ORI_BA_Status));
+	/* */
+	/* Prepare DelBA action frame and send to the peer. */
+	/* */
+	if ((bPassive == FALSE) && (TID == pBAEntry->TID)
+	    && (pBAEntry->ORI_BA_Status == Originator_Done)) {
+		struct rt_mlme_delba_req DelbaReq;
+		struct rt_mlme_queue_elem *Elem =
+		    (struct rt_mlme_queue_elem *)kmalloc(sizeof(struct rt_mlme_queue_elem),
+						MEM_ALLOC_FLAG);
+		if (Elem != NULL) {
+			NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
+			NdisZeroMemory(Elem, sizeof(struct rt_mlme_queue_elem));
+
+			COPY_MAC_ADDR(DelbaReq.Addr,
+				      pAd->MacTab.Content[Wcid].Addr);
+			DelbaReq.Wcid = Wcid;
+			DelbaReq.TID = pBAEntry->TID;
+			DelbaReq.Initiator = ORIGINATOR;
+			Elem->MsgLen = sizeof(DelbaReq);
+			NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
+			MlmeDELBAAction(pAd, Elem);
+			kfree(Elem);
+		} else {
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("%s():alloc memory failed!\n", __func__));
 			return;
-
-		NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
-		NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
-
-		COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
-		DelbaReq.Wcid = Wcid;
-		DelbaReq.TID = pBAEntry->TID;
-		DelbaReq.Initiator = ORIGINATOR;
-#if 1
-		Elem->MsgLen  = sizeof(DelbaReq);
-		NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
-		MlmeDELBAAction(pAd, Elem);
-		kfree(Elem);
-#else
-		MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
-		RT28XX_MLME_HANDLER(pAd);
-#endif
+		}
 	}
 	RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
 	BATableFreeOriEntry(pAd, Idx);
 
-	if (bPassive)
-	{
-		//BAOriSessionSetUp(pAd, &pAd->MacTab.Content[Wcid], TID, 0, 10000, TRUE);
+	if (bPassive) {
+		/*BAOriSessionSetUp(pAd, &pAd->MacTab.Content[Wcid], TID, 0, 10000, TRUE); */
 	}
 }
 
-VOID BARecSessionTearDown(
-						 IN OUT  PRTMP_ADAPTER   pAd,
-						 IN      UCHAR           Wcid,
-						 IN      UCHAR           TID,
-						 IN      BOOLEAN         bPassive)
+void BARecSessionTearDown(struct rt_rtmp_adapter *pAd,
+			  u8 Wcid, u8 TID, IN BOOLEAN bPassive)
 {
-	ULONG           Idx = 0;
-	BA_REC_ENTRY    *pBAEntry;
+	unsigned long Idx = 0;
+	struct rt_ba_rec_entry *pBAEntry;
 
-	if (Wcid >= MAX_LEN_OF_MAC_TABLE)
-	{
+	if (Wcid >= MAX_LEN_OF_MAC_TABLE) {
 		return;
 	}
-
-	//
-	//  Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID).
-	//
+	/* */
+	/*  Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID). */
+	/* */
 	Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
 	if (Idx == 0)
 		return;
 
-	DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __func__, Wcid, TID));
-
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("%s===>Wcid=%d.TID=%d \n", __func__, Wcid, TID));
 
 	pBAEntry = &pAd->BATable.BARecEntry[Idx];
-	DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, REC_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->REC_BA_Status));
-	//
-	// Prepare DelBA action frame and send to the peer.
-	//
-	if ((TID == pBAEntry->TID) && (pBAEntry->REC_BA_Status == Recipient_Accept))
-	{
-		MLME_DELBA_REQ_STRUCT   DelbaReq;
-		BOOLEAN 				Cancelled;
-		MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
-		//ULONG   offset;
-		//UINT32  VALUE;
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("\t===>Idx = %ld, Wcid=%d.TID=%d, REC_BA_Status = %d \n", Idx,
+		  Wcid, TID, pBAEntry->REC_BA_Status));
+	/* */
+	/* Prepare DelBA action frame and send to the peer. */
+	/* */
+	if ((TID == pBAEntry->TID)
+	    && (pBAEntry->REC_BA_Status == Recipient_Accept)) {
+		struct rt_mlme_delba_req DelbaReq;
+		BOOLEAN Cancelled;
+		/*unsigned long   offset; */
+		/*u32  VALUE; */
 
 		RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
 
-		//
-		// 1. Send DELBA Action Frame
-		//
-		if (bPassive == FALSE)
-		{
-			NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
-			NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
+		/* */
+		/* 1. Send DELBA Action Frame */
+		/* */
+		if (bPassive == FALSE) {
+			struct rt_mlme_queue_elem *Elem =
+			    (struct rt_mlme_queue_elem *)kmalloc(sizeof(struct rt_mlme_queue_elem),
+							MEM_ALLOC_FLAG);
+			if (Elem != NULL) {
+				NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
+				NdisZeroMemory(Elem, sizeof(struct rt_mlme_queue_elem));
 
-			COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
-			DelbaReq.Wcid = Wcid;
-			DelbaReq.TID = TID;
-			DelbaReq.Initiator = RECIPIENT;
-#if 1
-			Elem->MsgLen  = sizeof(DelbaReq);
-			NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
-			MlmeDELBAAction(pAd, Elem);
-			kfree(Elem);
-#else
-			MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
-			RT28XX_MLME_HANDLER(pAd);
-#endif
+				COPY_MAC_ADDR(DelbaReq.Addr,
+					      pAd->MacTab.Content[Wcid].Addr);
+				DelbaReq.Wcid = Wcid;
+				DelbaReq.TID = TID;
+				DelbaReq.Initiator = RECIPIENT;
+				Elem->MsgLen = sizeof(DelbaReq);
+				NdisMoveMemory(Elem->Msg, &DelbaReq,
+					       sizeof(DelbaReq));
+				MlmeDELBAAction(pAd, Elem);
+				kfree(Elem);
+			} else {
+				DBGPRINT(RT_DEBUG_ERROR,
+					 ("%s():alloc memory failed!\n",
+					  __func__));
+				return;
+			}
 		}
 
-
-		//
-		// 2. Free resource of BA session
-		//
-		// flush all pending reordering mpdus
+		/* */
+		/* 2. Free resource of BA session */
+		/* */
+		/* flush all pending reordering mpdus */
 		ba_refresh_reordering_mpdus(pAd, pBAEntry);
 
 		NdisAcquireSpinLock(&pAd->BATabLock);
 
-		// Erase Bitmap flag.
+		/* Erase Bitmap flag. */
 		pBAEntry->LastIndSeq = RESET_RCV_SEQ;
 		pBAEntry->BAWinSize = 0;
-		// Erase Bitmap flag at software mactable
-		pAd->MacTab.Content[Wcid].RXBAbitmap &= (~(1<<(pBAEntry->TID)));
+		/* Erase Bitmap flag at software mactable */
+		pAd->MacTab.Content[Wcid].RXBAbitmap &=
+		    (~(1 << (pBAEntry->TID)));
 		pAd->MacTab.Content[Wcid].BARecWcidArray[TID] = 0;
 
-		RT28XX_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID);
+		RTMP_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID);
 
 		NdisReleaseSpinLock(&pAd->BATabLock);
 
@@ -1018,20 +956,16 @@
 	BATableFreeRecEntry(pAd, Idx);
 }
 
-VOID BASessionTearDownALL(
-						 IN OUT  PRTMP_ADAPTER pAd,
-						 IN      UCHAR Wcid)
+void BASessionTearDownALL(struct rt_rtmp_adapter *pAd, u8 Wcid)
 {
 	int i;
 
-	for (i=0; i<NUM_OF_TID; i++)
-	{
+	for (i = 0; i < NUM_OF_TID; i++) {
 		BAOriSessionTearDown(pAd, Wcid, i, FALSE, FALSE);
 		BARecSessionTearDown(pAd, Wcid, i, FALSE);
 	}
 }
 
-
 /*
 	==========================================================================
 	Description:
@@ -1046,50 +980,50 @@
 				FALSE , then continue indicaterx at this moment.
 	==========================================================================
  */
-VOID BAOriSessionSetupTimeout(
-    IN PVOID SystemSpecific1,
-    IN PVOID FunctionContext,
-    IN PVOID SystemSpecific2,
-    IN PVOID SystemSpecific3)
+void BAOriSessionSetupTimeout(void *SystemSpecific1,
+			      void *FunctionContext,
+			      void *SystemSpecific2,
+			      void *SystemSpecific3)
 {
-	BA_ORI_ENTRY    *pBAEntry = (BA_ORI_ENTRY *)FunctionContext;
-	MAC_TABLE_ENTRY *pEntry;
-	PRTMP_ADAPTER   pAd;
+	struct rt_ba_ori_entry *pBAEntry = (struct rt_ba_ori_entry *)FunctionContext;
+	struct rt_mac_table_entry *pEntry;
+	struct rt_rtmp_adapter *pAd;
 
 	if (pBAEntry == NULL)
 		return;
 
 	pAd = pBAEntry->pAdapter;
 
-	// Do nothing if monitor mode is on
-	if (MONITOR_ON(pAd))
-		return;
+	{
+		/* Do nothing if monitor mode is on */
+		if (MONITOR_ON(pAd))
+			return;
+	}
 
 	pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
 
-	if ((pBAEntry->ORI_BA_Status == Originator_WaitRes) && (pBAEntry->Token < ORI_SESSION_MAX_RETRY))
-	{
-		MLME_ADDBA_REQ_STRUCT    AddbaReq;
+	if ((pBAEntry->ORI_BA_Status == Originator_WaitRes)
+	    && (pBAEntry->Token < ORI_SESSION_MAX_RETRY)) {
+		struct rt_mlme_addba_req AddbaReq;
 
 		NdisZeroMemory(&AddbaReq, sizeof(AddbaReq));
 		COPY_MAC_ADDR(AddbaReq.pAddr, pEntry->Addr);
-		AddbaReq.Wcid = (UCHAR)(pEntry->Aid);
+		AddbaReq.Wcid = (u8)(pEntry->Aid);
 		AddbaReq.TID = pBAEntry->TID;
-		AddbaReq.BaBufSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit;
+		AddbaReq.BaBufSize =
+		    pAd->CommonCfg.BACapability.field.RxBAWinLimit;
 		AddbaReq.TimeOutValue = 0;
 		AddbaReq.Token = pBAEntry->Token;
-		MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ADD_BA_CATE, sizeof(MLME_ADDBA_REQ_STRUCT), (PVOID)&AddbaReq);
-		RT28XX_MLME_HANDLER(pAd);
-		DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) to %02x:%02x:%02x:%02x:%02x:%02x Tid:%d Wcid:%d\n"
-		,pBAEntry->Token
-		,pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2]
-		,pEntry->Addr[3],pEntry->Addr[4],pEntry->Addr[5]
-		,pBAEntry->TID,pEntry->Aid));
+		MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ADD_BA_CATE,
+			    sizeof(struct rt_mlme_addba_req), (void *)& AddbaReq);
+		RTMP_MLME_HANDLER(pAd);
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("BA Ori Session Timeout(%d) : Send ADD BA again\n",
+			  pBAEntry->Token));
+
 		pBAEntry->Token++;
 		RTMPSetTimer(&pBAEntry->ORIBATimer, ORI_BA_SESSION_TIMEOUT);
-	}
-	else
-	{
+	} else {
 		BATableFreeOriEntry(pAd, pEntry->BAOriWcidArray[pBAEntry->TID]);
 	}
 }
@@ -1108,419 +1042,383 @@
 				FALSE , then continue indicaterx at this moment.
 	==========================================================================
  */
-VOID BARecSessionIdleTimeout(
-    IN PVOID SystemSpecific1,
-    IN PVOID FunctionContext,
-    IN PVOID SystemSpecific2,
-    IN PVOID SystemSpecific3)
+void BARecSessionIdleTimeout(void *SystemSpecific1,
+			     void *FunctionContext,
+			     void *SystemSpecific2, void *SystemSpecific3)
 {
 
-	BA_REC_ENTRY    *pBAEntry = (BA_REC_ENTRY *)FunctionContext;
-	PRTMP_ADAPTER   pAd;
-	ULONG           Now32;
+	struct rt_ba_rec_entry *pBAEntry = (struct rt_ba_rec_entry *)FunctionContext;
+	struct rt_rtmp_adapter *pAd;
+	unsigned long Now32;
 
 	if (pBAEntry == NULL)
 		return;
 
-	if ((pBAEntry->REC_BA_Status == Recipient_Accept))
-	{
+	if ((pBAEntry->REC_BA_Status == Recipient_Accept)) {
 		NdisGetSystemUpTime(&Now32);
 
-		if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer + REC_BA_SESSION_IDLE_TIMEOUT)))
-		{
+		if (RTMP_TIME_AFTER
+		    ((unsigned long)Now32,
+		     (unsigned long)(pBAEntry->LastIndSeqAtTimer +
+				     REC_BA_SESSION_IDLE_TIMEOUT))) {
 			pAd = pBAEntry->pAdapter;
-			// flush all pending reordering mpdus
+			/* flush all pending reordering mpdus */
 			ba_refresh_reordering_mpdus(pAd, pBAEntry);
-			printk("%ld: REC BA session Timeout\n", Now32);
+			DBGPRINT(RT_DEBUG_OFF,
+				 ("%ld: REC BA session Timeout\n", Now32));
 		}
 	}
 }
 
-
-VOID PeerAddBAReqAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-
+void PeerAddBAReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	//	7.4.4.1
-	//ULONG	Idx;
-	UCHAR   Status = 1;
-	UCHAR   pAddr[6];
-	FRAME_ADDBA_RSP ADDframe;
-	PUCHAR         pOutBuffer = NULL;
-	NDIS_STATUS     NStatus;
-	PFRAME_ADDBA_REQ  pAddreqFrame = NULL;
-	//UCHAR		BufSize;
-	ULONG       FrameLen;
-	PULONG      ptemp;
-	PMAC_TABLE_ENTRY	pMacEntry;
+	/*      7.4.4.1 */
+	/*unsigned long Idx; */
+	u8 Status = 1;
+	u8 pAddr[6];
+	struct rt_frame_addba_rsp ADDframe;
+	u8 *pOutBuffer = NULL;
+	int NStatus;
+	struct rt_frame_addba_req * pAddreqFrame = NULL;
+	/*u8         BufSize; */
+	unsigned long FrameLen;
+	unsigned long *ptemp;
+	struct rt_mac_table_entry *pMacEntry;
 
-	DBGPRINT(RT_DEBUG_TRACE, ("%s ==> (Wcid = %d)\n", __func__, Elem->Wcid));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("%s ==> (Wcid = %d)\n", __func__, Elem->Wcid));
 
-	//hex_dump("AddBAReq", Elem->Msg, Elem->MsgLen);
+	/*hex_dump("AddBAReq", Elem->Msg, Elem->MsgLen); */
 
-	//ADDBA Request from unknown peer, ignore this.
+	/*ADDBA Request from unknown peer, ignore this. */
 	if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
 		return;
 
 	pMacEntry = &pAd->MacTab.Content[Elem->Wcid];
-	DBGPRINT(RT_DEBUG_TRACE,("BA - PeerAddBAReqAction----> \n"));
-	ptemp = (PULONG)Elem->Msg;
-	//DBGPRINT_RAW(RT_DEBUG_EMU, ("%08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x\n", *(ptemp), *(ptemp+1), *(ptemp+2), *(ptemp+3), *(ptemp+4), *(ptemp+5), *(ptemp+6), *(ptemp+7), *(ptemp+8)));
+	DBGPRINT(RT_DEBUG_TRACE, ("BA - PeerAddBAReqAction----> \n"));
+	ptemp = (unsigned long *)Elem->Msg;
+	/*DBGPRINT_RAW(RT_DEBUG_EMU, ("%08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x\n", *(ptemp), *(ptemp+1), *(ptemp+2), *(ptemp+3), *(ptemp+4), *(ptemp+5), *(ptemp+6), *(ptemp+7), *(ptemp+8))); */
 
-	if (PeerAddBAReqActionSanity(pAd, Elem->Msg, Elem->MsgLen, pAddr))
-	{
+	if (PeerAddBAReqActionSanity(pAd, Elem->Msg, Elem->MsgLen, pAddr)) {
 
-		if ((pAd->CommonCfg.bBADecline == FALSE) && IS_HT_STA(pMacEntry))
-		{
-			pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]);
-			printk("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid);
-			if (BARecSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pAddreqFrame))
+		if ((pAd->CommonCfg.bBADecline == FALSE)
+		    && IS_HT_STA(pMacEntry)) {
+			pAddreqFrame = (struct rt_frame_addba_req *) (&Elem->Msg[0]);
+			DBGPRINT(RT_DEBUG_OFF,
+				 ("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid));
+			if (BARecSessionAdd
+			    (pAd, &pAd->MacTab.Content[Elem->Wcid],
+			     pAddreqFrame))
 				Status = 0;
 			else
-				Status = 38; // more parameters have invalid values
-		}
-		else
-		{
-			Status = 37; // the request has been declined.
+				Status = 38;	/* more parameters have invalid values */
+		} else {
+			Status = 37;	/* the request has been declined. */
 		}
 	}
 
 	if (pAd->MacTab.Content[Elem->Wcid].ValidAsCLI)
 		ASSERT(pAd->MacTab.Content[Elem->Wcid].Sst == SST_ASSOC);
 
-	pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]);
-	// 2. Always send back ADDBA Response
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	 //Get an unused nonpaged memory
-	if (NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("ACTION - PeerBAAction() allocate memory failed \n"));
+	pAddreqFrame = (struct rt_frame_addba_req *) (&Elem->Msg[0]);
+	/* 2. Always send back ADDBA Response */
+	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
+	if (NStatus != NDIS_STATUS_SUCCESS) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("ACTION - PeerBAAction() allocate memory failed \n"));
 		return;
 	}
 
-	NdisZeroMemory(&ADDframe, sizeof(FRAME_ADDBA_RSP));
+	NdisZeroMemory(&ADDframe, sizeof(struct rt_frame_addba_rsp));
 
-	// 2-1. Prepare ADDBA Response frame.
+	/* 2-1. Prepare ADDBA Response frame. */
 	{
 		if (ADHOC_ON(pAd))
-			ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+			ActHeaderInit(pAd, &ADDframe.Hdr, pAddr,
+				      pAd->CurrentAddress,
+				      pAd->CommonCfg.Bssid);
 		else
-			ActHeaderInit(pAd, &ADDframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
+			ActHeaderInit(pAd, &ADDframe.Hdr, pAd->CommonCfg.Bssid,
+				      pAd->CurrentAddress, pAddr);
 	}
 
 	ADDframe.Category = CATEGORY_BA;
 	ADDframe.Action = ADDBA_RESP;
 	ADDframe.Token = pAddreqFrame->Token;
-	// What is the Status code??  need to check.
+	/* What is the Status code??  need to check. */
 	ADDframe.StatusCode = Status;
 	ADDframe.BaParm.BAPolicy = IMMED_BA;
 	ADDframe.BaParm.AMSDUSupported = 0;
 	ADDframe.BaParm.TID = pAddreqFrame->BaParm.TID;
-	ADDframe.BaParm.BufSize = min(((UCHAR)pAddreqFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
-	if (ADDframe.BaParm.BufSize == 0)
-	{
+	ADDframe.BaParm.BufSize =
+	    min(((u8)pAddreqFrame->BaParm.BufSize),
+		(u8)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
+	if (ADDframe.BaParm.BufSize == 0) {
 		ADDframe.BaParm.BufSize = 64;
 	}
-	ADDframe.TimeOutValue = 0; //pAddreqFrame->TimeOutValue;
+	ADDframe.TimeOutValue = 0;	/*pAddreqFrame->TimeOutValue; */
 
-	*(USHORT *)(&ADDframe.BaParm) = cpu2le16(*(USHORT *)(&ADDframe.BaParm));
+	*(u16 *) (&ADDframe.BaParm) =
+	    cpu2le16(*(u16 *) (&ADDframe.BaParm));
 	ADDframe.StatusCode = cpu2le16(ADDframe.StatusCode);
 	ADDframe.TimeOutValue = cpu2le16(ADDframe.TimeOutValue);
 
-	MakeOutgoingFrame(pOutBuffer,               &FrameLen,
-					  sizeof(FRAME_ADDBA_RSP),  &ADDframe,
-			  END_OF_ARGS);
+	MakeOutgoingFrame(pOutBuffer, &FrameLen,
+			  sizeof(struct rt_frame_addba_rsp), &ADDframe, END_OF_ARGS);
 	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
 	MlmeFreeMemory(pAd, pOutBuffer);
 
-	DBGPRINT(RT_DEBUG_TRACE, ("%s(%d): TID(%d), BufSize(%d) <== \n", __func__, Elem->Wcid, ADDframe.BaParm.TID,
-							  ADDframe.BaParm.BufSize));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("%s(%d): TID(%d), BufSize(%d) <== \n", __func__, Elem->Wcid,
+		  ADDframe.BaParm.TID, ADDframe.BaParm.BufSize));
 }
 
-
-VOID PeerAddBARspAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-
+void PeerAddBARspAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	//UCHAR		Idx, i;
-	//PUCHAR		   pOutBuffer = NULL;
-	PFRAME_ADDBA_RSP    pFrame = NULL;
-	//PBA_ORI_ENTRY		pBAEntry;
+	/*u8         Idx, i; */
+	/*u8 *                  pOutBuffer = NULL; */
+	struct rt_frame_addba_rsp * pFrame = NULL;
+	/*struct rt_ba_ori_entry *pBAEntry; */
 
-	//ADDBA Response from unknown peer, ignore this.
+	/*ADDBA Response from unknown peer, ignore this. */
 	if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
 		return;
 
 	DBGPRINT(RT_DEBUG_TRACE, ("%s ==> Wcid(%d)\n", __func__, Elem->Wcid));
 
-	//hex_dump("PeerAddBARspAction()", Elem->Msg, Elem->MsgLen);
+	/*hex_dump("PeerAddBARspAction()", Elem->Msg, Elem->MsgLen); */
 
-	if (PeerAddBARspActionSanity(pAd, Elem->Msg, Elem->MsgLen))
-	{
-		pFrame = (PFRAME_ADDBA_RSP)(&Elem->Msg[0]);
+	if (PeerAddBARspActionSanity(pAd, Elem->Msg, Elem->MsgLen)) {
+		pFrame = (struct rt_frame_addba_rsp *) (&Elem->Msg[0]);
 
-		DBGPRINT(RT_DEBUG_TRACE, ("\t\t StatusCode = %d\n", pFrame->StatusCode));
-		switch (pFrame->StatusCode)
-		{
-			case 0:
-				// I want a BAsession with this peer as an originator.
-				BAOriSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pFrame);
-				break;
-			default:
-				// check status == USED ???
-				BAOriSessionTearDown(pAd, Elem->Wcid, pFrame->BaParm.TID, TRUE, FALSE);
-				break;
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("\t\t StatusCode = %d\n", pFrame->StatusCode));
+		switch (pFrame->StatusCode) {
+		case 0:
+			/* I want a BAsession with this peer as an originator. */
+			BAOriSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid],
+					pFrame);
+			break;
+		default:
+			/* check status == USED ??? */
+			BAOriSessionTearDown(pAd, Elem->Wcid,
+					     pFrame->BaParm.TID, TRUE, FALSE);
+			break;
 		}
-		// Rcv Decline StatusCode
+		/* Rcv Decline StatusCode */
 		if ((pFrame->StatusCode == 37)
-            || ((pAd->OpMode == OPMODE_STA) && STA_TGN_WIFI_ON(pAd) && (pFrame->StatusCode != 0))
-            )
-		{
-			pAd->MacTab.Content[Elem->Wcid].BADeclineBitmap |= 1<<pFrame->BaParm.TID;
+		    || ((pAd->OpMode == OPMODE_STA) && STA_TGN_WIFI_ON(pAd)
+			&& (pFrame->StatusCode != 0))
+		    ) {
+			pAd->MacTab.Content[Elem->Wcid].BADeclineBitmap |=
+			    1 << pFrame->BaParm.TID;
 		}
 	}
 }
 
-VOID PeerDelBAAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-
+void PeerDelBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	//UCHAR				Idx;
-	//PUCHAR				pOutBuffer = NULL;
-	PFRAME_DELBA_REQ    pDelFrame = NULL;
+	/*u8                         Idx; */
+	/*u8 *                               pOutBuffer = NULL; */
+	struct rt_frame_delba_req * pDelFrame = NULL;
 
-	DBGPRINT(RT_DEBUG_TRACE,("%s ==>\n", __func__));
-	//DELBA Request from unknown peer, ignore this.
-	if (PeerDelBAActionSanity(pAd, Elem->Wcid, Elem->Msg, Elem->MsgLen))
-	{
-		pDelFrame = (PFRAME_DELBA_REQ)(&Elem->Msg[0]);
-		if (pDelFrame->DelbaParm.Initiator == ORIGINATOR)
-		{
-			DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> ORIGINATOR\n"));
-			BARecSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE);
-		}
-		else
-		{
-			DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> RECIPIENT, Reason = %d\n",  pDelFrame->ReasonCode));
-			//hex_dump("DelBA Frame", pDelFrame, Elem->MsgLen);
-			BAOriSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE, FALSE);
+	DBGPRINT(RT_DEBUG_TRACE, ("%s ==>\n", __func__));
+	/*DELBA Request from unknown peer, ignore this. */
+	if (PeerDelBAActionSanity(pAd, Elem->Wcid, Elem->Msg, Elem->MsgLen)) {
+		pDelFrame = (struct rt_frame_delba_req *) (&Elem->Msg[0]);
+		if (pDelFrame->DelbaParm.Initiator == ORIGINATOR) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("BA - PeerDelBAAction----> ORIGINATOR\n"));
+			BARecSessionTearDown(pAd, Elem->Wcid,
+					     pDelFrame->DelbaParm.TID, TRUE);
+		} else {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("BA - PeerDelBAAction----> RECIPIENT, Reason = %d\n",
+				  pDelFrame->ReasonCode));
+			/*hex_dump("DelBA Frame", pDelFrame, Elem->MsgLen); */
+			BAOriSessionTearDown(pAd, Elem->Wcid,
+					     pDelFrame->DelbaParm.TID, TRUE,
+					     FALSE);
 		}
 	}
 }
 
-
-BOOLEAN CntlEnqueueForRecv(
-						  IN PRTMP_ADAPTER		pAd,
-						  IN ULONG				Wcid,
-						  IN ULONG				MsgLen,
-						  IN PFRAME_BA_REQ		pMsg)
+BOOLEAN CntlEnqueueForRecv(struct rt_rtmp_adapter *pAd,
+			   unsigned long Wcid,
+			   unsigned long MsgLen, struct rt_frame_ba_req * pMsg)
 {
-	PFRAME_BA_REQ   pFrame = pMsg;
-	//PRTMP_REORDERBUF	pBuffer;
-	//PRTMP_REORDERBUF	pDmaBuf;
-	PBA_REC_ENTRY pBAEntry;
-	//BOOLEAN 	Result;
-	ULONG   Idx;
-	//UCHAR	NumRxPkt;
-	UCHAR	TID;//, i;
+	struct rt_frame_ba_req * pFrame = pMsg;
+	/*PRTMP_REORDERBUF      pBuffer; */
+	/*PRTMP_REORDERBUF      pDmaBuf; */
+	struct rt_ba_rec_entry *pBAEntry;
+	/*BOOLEAN       Result; */
+	unsigned long Idx;
+	/*u8 NumRxPkt; */
+	u8 TID;		/*, i; */
 
-	TID = (UCHAR)pFrame->BARControl.TID;
+	TID = (u8)pFrame->BARControl.TID;
 
-	DBGPRINT(RT_DEBUG_TRACE, ("%s(): BAR-Wcid(%ld), Tid (%d)\n", __func__, Wcid, TID));
-	//hex_dump("BAR", (PCHAR) pFrame, MsgLen);
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("%s(): BAR-Wcid(%ld), Tid (%d)\n", __func__, Wcid, TID));
+	/*hex_dump("BAR", (char *)pFrame, MsgLen); */
+	/* Do nothing if the driver is starting halt state. */
+	/* This might happen when timer already been fired before cancel timer with mlmehalt */
+	if (RTMP_TEST_FLAG
+	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
 		return FALSE;
 
-	// First check the size, it MUST not exceed the mlme queue size
-	if (MsgLen > MGMT_DMA_BUFFER_SIZE)
-	{
+	/* First check the size, it MUST not exceed the mlme queue size */
+	if (MsgLen > MGMT_DMA_BUFFER_SIZE) {
 		DBGPRINT_ERR(("CntlEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
 		return FALSE;
-	}
-	else if (MsgLen != sizeof(FRAME_BA_REQ))
-	{
+	} else if (MsgLen != sizeof(struct rt_frame_ba_req)) {
 		DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen));
 		return FALSE;
-	}
-	else if (MsgLen != sizeof(FRAME_BA_REQ))
-	{
+	} else if (MsgLen != sizeof(struct rt_frame_ba_req)) {
 		DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen));
 		return FALSE;
 	}
 
-	if ((Wcid < MAX_LEN_OF_MAC_TABLE) && (TID < 8))
-		{
-		// if this receiving packet is from SA that is in our OriEntry. Since WCID <9 has direct mapping. no need search.
+	if ((Wcid < MAX_LEN_OF_MAC_TABLE) && (TID < 8)) {
+		/* if this receiving packet is from SA that is in our OriEntry. Since WCID <9 has direct mapping. no need search. */
 		Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
 		pBAEntry = &pAd->BATable.BARecEntry[Idx];
-		}
-		else
-		{
+	} else {
 		return FALSE;
 	}
 
-	DBGPRINT(RT_DEBUG_TRACE, ("BAR(%ld) : Tid (%d) - %04x:%04x\n", Wcid, TID, pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq ));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("BAR(%ld) : Tid (%d) - %04x:%04x\n", Wcid, TID,
+		  pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq));
 
-	if (SEQ_SMALLER(pBAEntry->LastIndSeq, pFrame->BAStartingSeq.field.StartSeq, MAXSEQ))
-	{
-		//printk("BAR Seq = %x, LastIndSeq = %x\n", pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq);
-		ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, pFrame->BAStartingSeq.field.StartSeq);
-		pBAEntry->LastIndSeq = (pFrame->BAStartingSeq.field.StartSeq == 0) ? MAXSEQ :(pFrame->BAStartingSeq.field.StartSeq -1);
+	if (SEQ_SMALLER
+	    (pBAEntry->LastIndSeq, pFrame->BAStartingSeq.field.StartSeq,
+	     MAXSEQ)) {
+		/*DBGPRINT(RT_DEBUG_TRACE, ("BAR Seq = %x, LastIndSeq = %x\n", pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq)); */
+		ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry,
+						    pFrame->BAStartingSeq.field.
+						    StartSeq);
+		pBAEntry->LastIndSeq =
+		    (pFrame->BAStartingSeq.field.StartSeq ==
+		     0) ? MAXSEQ : (pFrame->BAStartingSeq.field.StartSeq - 1);
 	}
-	//ba_refresh_reordering_mpdus(pAd, pBAEntry);
+	/*ba_refresh_reordering_mpdus(pAd, pBAEntry); */
 	return TRUE;
 }
 
 /*
 Description : Send PSMP Action frame If PSMP mode switches.
 */
-VOID SendPSMPAction(
-				   IN PRTMP_ADAPTER		pAd,
-				   IN UCHAR				Wcid,
-				   IN UCHAR				Psmp)
+void SendPSMPAction(struct rt_rtmp_adapter *pAd, u8 Wcid, u8 Psmp)
 {
-	PUCHAR          pOutBuffer = NULL;
-	NDIS_STATUS     NStatus;
-	//ULONG           Idx;
-	FRAME_PSMP_ACTION   Frame;
-	ULONG           FrameLen;
-	UCHAR			bbpdata=0;
-	UINT32			macdata;
+	u8 *pOutBuffer = NULL;
+	int NStatus;
+	/*unsigned long           Idx; */
+	struct rt_frame_psmp_action Frame;
+	unsigned long FrameLen;
 
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	 //Get an unused nonpaged memory
-	if (NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));
+	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
+	if (NStatus != NDIS_STATUS_SUCCESS) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("BA - MlmeADDBAAction() allocate memory failed \n"));
 		return;
 	}
 
-	ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[Wcid].Addr);
+	ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid,
+		      pAd->CurrentAddress, pAd->MacTab.Content[Wcid].Addr);
 
 	Frame.Category = CATEGORY_HT;
 	Frame.Action = SMPS_ACTION;
-	switch (Psmp)
-	{
-		case MMPS_ENABLE:
-			if (IS_RT3090(pAd))
-			{
-				// disable MMPS BBP control register
-				RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
-				bbpdata &= ~(0x04);	//bit 2
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
-
-				// disable MMPS MAC control register
-				RTMP_IO_READ32(pAd, 0x1210, &macdata);
-				macdata &= ~(0x09);	//bit 0, 3
-				RTMP_IO_WRITE32(pAd, 0x1210, macdata);
-			}
-			Frame.Psmp = 0;
-			break;
-		case MMPS_DYNAMIC:
-			if (IS_RT3090(pAd))
-			{
-				// enable MMPS BBP control register
-				RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
-				bbpdata |= 0x04;	//bit 2
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
-
-				// enable MMPS MAC control register
-				RTMP_IO_READ32(pAd, 0x1210, &macdata);
-				macdata |= 0x09;	//bit 0, 3
-				RTMP_IO_WRITE32(pAd, 0x1210, macdata);
-			}
-			Frame.Psmp = 3;
-			break;
-		case MMPS_STATIC:
-			if (IS_RT3090(pAd))
-			{
-				// enable MMPS BBP control register
-				RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
-				bbpdata |= 0x04;	//bit 2
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
-
-				// enable MMPS MAC control register
-				RTMP_IO_READ32(pAd, 0x1210, &macdata);
-				macdata |= 0x09;	//bit 0, 3
-				RTMP_IO_WRITE32(pAd, 0x1210, macdata);
-			}
-			Frame.Psmp = 1;
-			break;
+	switch (Psmp) {
+	case MMPS_ENABLE:
+#ifdef RT30xx
+		if (IS_RT30xx(pAd)
+		    && (pAd->Antenna.field.RxPath > 1
+			|| pAd->Antenna.field.TxPath > 1)) {
+			RTMP_ASIC_MMPS_DISABLE(pAd);
+		}
+#endif /* RT30xx // */
+		Frame.Psmp = 0;
+		break;
+	case MMPS_DYNAMIC:
+		Frame.Psmp = 3;
+		break;
+	case MMPS_STATIC:
+#ifdef RT30xx
+		if (IS_RT30xx(pAd)
+		    && (pAd->Antenna.field.RxPath > 1
+			|| pAd->Antenna.field.TxPath > 1)) {
+			RTMP_ASIC_MMPS_ENABLE(pAd);
+		}
+#endif /* RT30xx // */
+		Frame.Psmp = 1;
+		break;
 	}
-	MakeOutgoingFrame(pOutBuffer,               &FrameLen,
-					  sizeof(FRAME_PSMP_ACTION),      &Frame,
-					  END_OF_ARGS);
+	MakeOutgoingFrame(pOutBuffer, &FrameLen,
+			  sizeof(struct rt_frame_psmp_action), &Frame, END_OF_ARGS);
 	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
 	MlmeFreeMemory(pAd, pOutBuffer);
-	DBGPRINT(RT_DEBUG_ERROR,("HT - SendPSMPAction( %d )  \n", Frame.Psmp));
+	DBGPRINT(RT_DEBUG_ERROR, ("HT - SendPSMPAction( %d )  \n", Frame.Psmp));
 }
 
-
 #define RADIO_MEASUREMENT_REQUEST_ACTION	0
 
-typedef struct PACKED
+struct PACKED rt_beacon_request {
+	u8 RegulatoryClass;
+	u8 ChannelNumber;
+	u16 RandomInterval;
+	u16 MeasurementDuration;
+	u8 MeasurementMode;
+	u8 BSSID[MAC_ADDR_LEN];
+	u8 ReportingCondition;
+	u8 Threshold;
+	u8 SSIDIE[2];	/* 2 byte */
+};
+
+struct PACKED rt_measurement_req {
+	u8 ID;
+	u8 Length;
+	u8 Token;
+	u8 RequestMode;
+	u8 Type;
+};
+
+void convert_reordering_packet_to_preAMSDU_or_802_3_packet(struct rt_rtmp_adapter *pAd,
+							   struct rt_rx_blk *pRxBlk,
+							   u8
+							   FromWhichBSSID)
 {
-	UCHAR	RegulatoryClass;
-	UCHAR	ChannelNumber;
-	USHORT	RandomInterval;
-	USHORT	MeasurementDuration;
-	UCHAR	MeasurementMode;
-	UCHAR   BSSID[MAC_ADDR_LEN];
-	UCHAR	ReportingCondition;
-	UCHAR	Threshold;
-	UCHAR   SSIDIE[2];			// 2 byte
-} BEACON_REQUEST;
+	void *pRxPkt;
+	u8 Header802_3[LENGTH_802_3];
 
-typedef struct PACKED
-{
-	UCHAR	ID;
-	UCHAR	Length;
-	UCHAR	Token;
-	UCHAR	RequestMode;
-	UCHAR	Type;
-} MEASUREMENT_REQ;
-
-
-
-
-void convert_reordering_packet_to_preAMSDU_or_802_3_packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN  UCHAR			FromWhichBSSID)
-{
-	PNDIS_PACKET	pRxPkt;
-	UCHAR			Header802_3[LENGTH_802_3];
-
-	// 1. get 802.3 Header
-	// 2. remove LLC
-	// 		a. pointer pRxBlk->pData to payload
-	//      b. modify pRxBlk->DataSize
+	/* 1. get 802.3 Header */
+	/* 2. remove LLC */
+	/*              a. pointer pRxBlk->pData to payload */
+	/*      b. modify pRxBlk->DataSize */
 
 	RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
 
 	ASSERT(pRxBlk->pRxPacket);
 	pRxPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
 
-	RTPKT_TO_OSPKT(pRxPkt)->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
-	RTPKT_TO_OSPKT(pRxPkt)->data = pRxBlk->pData;
-	RTPKT_TO_OSPKT(pRxPkt)->len = pRxBlk->DataSize;
-	RTPKT_TO_OSPKT(pRxPkt)->tail = RTPKT_TO_OSPKT(pRxPkt)->data + RTPKT_TO_OSPKT(pRxPkt)->len;
+	SET_OS_PKT_NETDEV(pRxPkt, get_netdev_from_bssid(pAd, FromWhichBSSID));
+	SET_OS_PKT_DATAPTR(pRxPkt, pRxBlk->pData);
+	SET_OS_PKT_LEN(pRxPkt, pRxBlk->DataSize);
+	SET_OS_PKT_DATATAIL(pRxPkt, pRxBlk->pData, pRxBlk->DataSize);
 
-	//
-	// copy 802.3 header, if necessary
-	//
-	if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
-	{
+	/* */
+	/* copy 802.3 header, if necessary */
+	/* */
+	if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU)) {
+		{
 #ifdef LINUX
-		NdisMoveMemory(skb_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3);
+			NdisMoveMemory(skb_push(pRxPkt, LENGTH_802_3),
+				       Header802_3, LENGTH_802_3);
 #endif
+		}
 	}
 }
 
-
 #define INDICATE_LEGACY_OR_AMSDU(_pAd, _pRxBlk, _fromWhichBSSID)		\
 	do																	\
 	{																	\
@@ -1538,61 +1436,60 @@
     	}																\
 	} while (0);
 
-
-
-static VOID ba_enqueue_reordering_packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PBA_REC_ENTRY	pBAEntry,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID)
+static void ba_enqueue_reordering_packet(struct rt_rtmp_adapter *pAd,
+					 struct rt_ba_rec_entry *pBAEntry,
+					 struct rt_rx_blk *pRxBlk,
+					 u8 FromWhichBSSID)
 {
 	struct reordering_mpdu *mpdu_blk;
-	UINT16	Sequence = (UINT16) pRxBlk->pHeader->Sequence;
+	u16 Sequence = (u16)pRxBlk->pHeader->Sequence;
 
 	mpdu_blk = ba_mpdu_blk_alloc(pAd);
-	if (mpdu_blk != NULL)
-	{
-		// Write RxD buffer address & allocated buffer length
+	if ((mpdu_blk != NULL) && (!RX_BLK_TEST_FLAG(pRxBlk, fRX_EAP))) {
+		/* Write RxD buffer address & allocated buffer length */
 		NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
 
 		mpdu_blk->Sequence = Sequence;
 
 		mpdu_blk->bAMSDU = RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU);
 
-		convert_reordering_packet_to_preAMSDU_or_802_3_packet(pAd, pRxBlk, FromWhichBSSID);
+		convert_reordering_packet_to_preAMSDU_or_802_3_packet(pAd,
+								      pRxBlk,
+								      FromWhichBSSID);
 
 		STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
 
-        //
-		// it is necessary for reordering packet to record
-		// which BSS it come from
-		//
+		/* */
+		/* it is necessary for reordering packet to record */
+		/* which BSS it come from */
+		/* */
 		RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
 
 		mpdu_blk->pPacket = pRxBlk->pRxPacket;
 
-		if (ba_reordering_mpdu_insertsorted(&pBAEntry->list, mpdu_blk) == FALSE)
-		{
-			// had been already within reordering list
-			// don't indicate
-			RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_SUCCESS);
+		if (ba_reordering_mpdu_insertsorted(&pBAEntry->list, mpdu_blk)
+		    == FALSE) {
+			/* had been already within reordering list */
+			/* don't indicate */
+			RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
+					    NDIS_STATUS_SUCCESS);
 			ba_mpdu_blk_free(pAd, mpdu_blk);
 		}
 
-		ASSERT((0<= pBAEntry->list.qlen)  && (pBAEntry->list.qlen <= pBAEntry->BAWinSize));
+		ASSERT((0 <= pBAEntry->list.qlen)
+		       && (pBAEntry->list.qlen <= pBAEntry->BAWinSize));
 		NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_ERROR,  ("!!! (%d) Can't allocate reordering mpdu blk\n",
-								   pBAEntry->list.qlen));
+	} else {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 (" (%d) Can't allocate reordering mpdu blk\n",
+			  pBAEntry->list.qlen));
 
 		/*
 		 * flush all pending reordering mpdus
 		 * and receving mpdu to upper layer
 		 * make tcp/ip to take care reordering mechanism
 		 */
-		//ba_refresh_reordering_mpdus(pAd, pBAEntry);
+		/*ba_refresh_reordering_mpdus(pAd, pBAEntry); */
 		ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
 
 		pBAEntry->LastIndSeq = Sequence;
@@ -1600,7 +1497,6 @@
 	}
 }
 
-
 /*
 	==========================================================================
 	Description:
@@ -1619,139 +1515,134 @@
 	==========================================================================
  */
 
-VOID Indicate_AMPDU_Packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID)
+void Indicate_AMPDU_Packet(struct rt_rtmp_adapter *pAd,
+			   struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
 {
-	USHORT				Idx;
-	PBA_REC_ENTRY		pBAEntry = NULL;
-	UINT16				Sequence = pRxBlk->pHeader->Sequence;
-	ULONG				Now32;
-	UCHAR				Wcid = pRxBlk->pRxWI->WirelessCliID;
-	UCHAR				TID = pRxBlk->pRxWI->TID;
+	u16 Idx;
+	struct rt_ba_rec_entry *pBAEntry = NULL;
+	u16 Sequence = pRxBlk->pHeader->Sequence;
+	unsigned long Now32;
+	u8 Wcid = pRxBlk->pRxWI->WirelessCliID;
+	u8 TID = pRxBlk->pRxWI->TID;
 
-
-	if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU) &&  (pRxBlk->DataSize > MAX_RX_PKT_LEN))
-	{
-		// release packet
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+	if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU)
+	    && (pRxBlk->DataSize > MAX_RX_PKT_LEN)) {
+		/* release packet */
+		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
+				    NDIS_STATUS_FAILURE);
 		return;
 	}
 
-	if (Wcid < MAX_LEN_OF_MAC_TABLE)
-	{
+	if (Wcid < MAX_LEN_OF_MAC_TABLE) {
 		Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
-		if (Idx == 0)
-		{
+		if (Idx == 0) {
 			/* Rec BA Session had been torn down */
 			INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
 			return;
 		}
 		pBAEntry = &pAd->BATable.BARecEntry[Idx];
-	}
-	else
-	{
-		// impossible !!!
+	} else {
+		/* impossible ! */
 		ASSERT(0);
-		// release packet
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+		/* release packet */
+		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
+				    NDIS_STATUS_FAILURE);
 		return;
 	}
 
 	ASSERT(pBAEntry);
 
-	// update last rx time
+	/* update last rx time */
 	NdisGetSystemUpTime(&Now32);
 
 	pBAEntry->rcvSeq = Sequence;
 
-
 	ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
 	pBAEntry->LastIndSeqAtTimer = Now32;
 
-	//
-	// Reset Last Indicate Sequence
-	//
-	if (pBAEntry->LastIndSeq == RESET_RCV_SEQ)
-	{
-		ASSERT((pBAEntry->list.qlen == 0) && (pBAEntry->list.next == NULL));
+	/* */
+	/* Reset Last Indicate Sequence */
+	/* */
+	if (pBAEntry->LastIndSeq == RESET_RCV_SEQ) {
+		ASSERT((pBAEntry->list.qlen == 0)
+		       && (pBAEntry->list.next == NULL));
 
-		// reset rcv sequence of BA session
+		/* reset rcv sequence of BA session */
 		pBAEntry->LastIndSeq = Sequence;
 		pBAEntry->LastIndSeqAtTimer = Now32;
 		INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
 		return;
 	}
 
-
-	//
-	// I. Check if in order.
-	//
-	if (SEQ_STEPONE(Sequence, pBAEntry->LastIndSeq, MAXSEQ))
-	{
-		USHORT  LastIndSeq;
+	/* */
+	/* I. Check if in order. */
+	/* */
+	if (SEQ_STEPONE(Sequence, pBAEntry->LastIndSeq, MAXSEQ)) {
+		u16 LastIndSeq;
 
 		pBAEntry->LastIndSeq = Sequence;
 		INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
- 		LastIndSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq);
-		if (LastIndSeq != RESET_RCV_SEQ)
-		{
+		LastIndSeq =
+		    ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry,
+							  pBAEntry->LastIndSeq);
+		if (LastIndSeq != RESET_RCV_SEQ) {
 			pBAEntry->LastIndSeq = LastIndSeq;
 		}
 		pBAEntry->LastIndSeqAtTimer = Now32;
 	}
-	//
-	// II. Drop Duplicated Packet
-	//
-	else if (Sequence == pBAEntry->LastIndSeq)
-	{
+	/* */
+	/* II. Drop Duplicated Packet */
+	/* */
+	else if (Sequence == pBAEntry->LastIndSeq) {
 
-		// drop and release packet
+		/* drop and release packet */
 		pBAEntry->nDropPacket++;
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
+				    NDIS_STATUS_FAILURE);
 	}
-	//
-	// III. Drop Old Received Packet
-	//
-	else if (SEQ_SMALLER(Sequence, pBAEntry->LastIndSeq, MAXSEQ))
-	{
+	/* */
+	/* III. Drop Old Received Packet */
+	/* */
+	else if (SEQ_SMALLER(Sequence, pBAEntry->LastIndSeq, MAXSEQ)) {
 
-		// drop and release packet
+		/* drop and release packet */
 		pBAEntry->nDropPacket++;
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
+				    NDIS_STATUS_FAILURE);
 	}
-	//
-	// IV. Receive Sequence within Window Size
-	//
-	else if (SEQ_SMALLER(Sequence, (((pBAEntry->LastIndSeq+pBAEntry->BAWinSize+1)) & MAXSEQ), MAXSEQ))
-	{
-		ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID);
+	/* */
+	/* IV. Receive Sequence within Window Size */
+	/* */
+	else if (SEQ_SMALLER
+		 (Sequence,
+		  (((pBAEntry->LastIndSeq + pBAEntry->BAWinSize + 1)) & MAXSEQ),
+		  MAXSEQ)) {
+		ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk,
+					     FromWhichBSSID);
 	}
-	//
-	// V. Receive seq surpasses Win(lastseq + nMSDU). So refresh all reorder buffer
-	//
-	else
-	{
-		LONG WinStartSeq, TmpSeq;
+	/* */
+	/* V. Receive seq surpasses Win(lastseq + nMSDU). So refresh all reorder buffer */
+	/* */
+	else {
+		long WinStartSeq, TmpSeq;
 
-
-		TmpSeq = Sequence - (pBAEntry->BAWinSize) -1;
-		if (TmpSeq < 0)
-		{
-			TmpSeq = (MAXSEQ+1) + TmpSeq;
+		TmpSeq = Sequence - (pBAEntry->BAWinSize) - 1;
+		if (TmpSeq < 0) {
+			TmpSeq = (MAXSEQ + 1) + TmpSeq;
 		}
-		WinStartSeq = (TmpSeq+1) & MAXSEQ;
+		WinStartSeq = (TmpSeq + 1) & MAXSEQ;
 		ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, WinStartSeq);
-		pBAEntry->LastIndSeq = WinStartSeq; //TmpSeq;
+		pBAEntry->LastIndSeq = WinStartSeq;	/*TmpSeq; */
 
 		pBAEntry->LastIndSeqAtTimer = Now32;
 
-		ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID);
+		ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk,
+					     FromWhichBSSID);
 
-		TmpSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq);
-		if (TmpSeq != RESET_RCV_SEQ)
-		{
+		TmpSeq =
+		    ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry,
+							  pBAEntry->LastIndSeq);
+		if (TmpSeq != RESET_RCV_SEQ) {
 			pBAEntry->LastIndSeq = TmpSeq;
 		}
 	}
diff --git a/drivers/staging/rt2860/common/cmm_aes.c b/drivers/staging/rt2860/common/cmm_aes.c
new file mode 100644
index 0000000..250357c
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_aes.c
@@ -0,0 +1,1313 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	cmm_aes.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	Paul Wu		02-25-02		Initial
+*/
+
+#include	"../rt_config.h"
+
+struct aes_context {
+	u32 erk[64];		/* encryption round keys */
+	u32 drk[64];		/* decryption round keys */
+	int nr;			/* number of rounds */
+};
+
+/*****************************/
+/******** SBOX Table *********/
+/*****************************/
+
+u8 SboxTable[256] = {
+	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
+	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
+	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
+	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
+	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
+	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
+	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
+	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
+	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
+	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
+	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
+	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
+	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
+	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
+	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
+	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
+	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+};
+
+void xor_32(u8 *a, u8 *b, u8 *out)
+{
+	int i;
+
+	for (i = 0; i < 4; i++) {
+		out[i] = a[i] ^ b[i];
+	}
+}
+
+void xor_128(u8 *a, u8 *b, u8 *out)
+{
+	int i;
+
+	for (i = 0; i < 16; i++) {
+		out[i] = a[i] ^ b[i];
+	}
+}
+
+u8 RTMPCkipSbox(u8 a)
+{
+	return SboxTable[(int)a];
+}
+
+void next_key(u8 *key, int round)
+{
+	u8 rcon;
+	u8 sbox_key[4];
+	u8 rcon_table[12] = {
+		0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
+		0x1b, 0x36, 0x36, 0x36
+	};
+
+	sbox_key[0] = RTMPCkipSbox(key[13]);
+	sbox_key[1] = RTMPCkipSbox(key[14]);
+	sbox_key[2] = RTMPCkipSbox(key[15]);
+	sbox_key[3] = RTMPCkipSbox(key[12]);
+
+	rcon = rcon_table[round];
+
+	xor_32(&key[0], sbox_key, &key[0]);
+	key[0] = key[0] ^ rcon;
+
+	xor_32(&key[4], &key[0], &key[4]);
+	xor_32(&key[8], &key[4], &key[8]);
+	xor_32(&key[12], &key[8], &key[12]);
+}
+
+void byte_sub(u8 *in, u8 *out)
+{
+	int i;
+
+	for (i = 0; i < 16; i++) {
+		out[i] = RTMPCkipSbox(in[i]);
+	}
+}
+
+/************************************/
+/* bitwise_xor()                    */
+/* A 128 bit, bitwise exclusive or  */
+/************************************/
+
+void bitwise_xor(unsigned char *ina, unsigned char *inb, unsigned char *out)
+{
+	int i;
+	for (i = 0; i < 16; i++) {
+		out[i] = ina[i] ^ inb[i];
+	}
+}
+
+void shift_row(u8 *in, u8 *out)
+{
+	out[0] = in[0];
+	out[1] = in[5];
+	out[2] = in[10];
+	out[3] = in[15];
+	out[4] = in[4];
+	out[5] = in[9];
+	out[6] = in[14];
+	out[7] = in[3];
+	out[8] = in[8];
+	out[9] = in[13];
+	out[10] = in[2];
+	out[11] = in[7];
+	out[12] = in[12];
+	out[13] = in[1];
+	out[14] = in[6];
+	out[15] = in[11];
+}
+
+void mix_column(u8 *in, u8 *out)
+{
+	int i;
+	u8 add1b[4];
+	u8 add1bf7[4];
+	u8 rotl[4];
+	u8 swap_halfs[4];
+	u8 andf7[4];
+	u8 rotr[4];
+	u8 temp[4];
+	u8 tempb[4];
+
+	for (i = 0; i < 4; i++) {
+		if ((in[i] & 0x80) == 0x80)
+			add1b[i] = 0x1b;
+		else
+			add1b[i] = 0x00;
+	}
+
+	swap_halfs[0] = in[2];	/* Swap halfs */
+	swap_halfs[1] = in[3];
+	swap_halfs[2] = in[0];
+	swap_halfs[3] = in[1];
+
+	rotl[0] = in[3];	/* Rotate left 8 bits */
+	rotl[1] = in[0];
+	rotl[2] = in[1];
+	rotl[3] = in[2];
+
+	andf7[0] = in[0] & 0x7f;
+	andf7[1] = in[1] & 0x7f;
+	andf7[2] = in[2] & 0x7f;
+	andf7[3] = in[3] & 0x7f;
+
+	for (i = 3; i > 0; i--) {	/* logical shift left 1 bit */
+		andf7[i] = andf7[i] << 1;
+		if ((andf7[i - 1] & 0x80) == 0x80) {
+			andf7[i] = (andf7[i] | 0x01);
+		}
+	}
+	andf7[0] = andf7[0] << 1;
+	andf7[0] = andf7[0] & 0xfe;
+
+	xor_32(add1b, andf7, add1bf7);
+
+	xor_32(in, add1bf7, rotr);
+
+	temp[0] = rotr[0];	/* Rotate right 8 bits */
+	rotr[0] = rotr[1];
+	rotr[1] = rotr[2];
+	rotr[2] = rotr[3];
+	rotr[3] = temp[0];
+
+	xor_32(add1bf7, rotr, temp);
+	xor_32(swap_halfs, rotl, tempb);
+	xor_32(temp, tempb, out);
+}
+
+/************************************************/
+/* construct_mic_header1()                      */
+/* Builds the first MIC header block from       */
+/* header fields.                               */
+/************************************************/
+
+void construct_mic_header1(unsigned char *mic_header1,
+			   int header_length, unsigned char *mpdu)
+{
+	mic_header1[0] = (unsigned char)((header_length - 2) / 256);
+	mic_header1[1] = (unsigned char)((header_length - 2) % 256);
+	mic_header1[2] = mpdu[0] & 0xcf;	/* Mute CF poll & CF ack bits */
+	mic_header1[3] = mpdu[1] & 0xc7;	/* Mute retry, more data and pwr mgt bits */
+	mic_header1[4] = mpdu[4];	/* A1 */
+	mic_header1[5] = mpdu[5];
+	mic_header1[6] = mpdu[6];
+	mic_header1[7] = mpdu[7];
+	mic_header1[8] = mpdu[8];
+	mic_header1[9] = mpdu[9];
+	mic_header1[10] = mpdu[10];	/* A2 */
+	mic_header1[11] = mpdu[11];
+	mic_header1[12] = mpdu[12];
+	mic_header1[13] = mpdu[13];
+	mic_header1[14] = mpdu[14];
+	mic_header1[15] = mpdu[15];
+}
+
+/************************************************/
+/* construct_mic_header2()                      */
+/* Builds the last MIC header block from        */
+/* header fields.                               */
+/************************************************/
+
+void construct_mic_header2(unsigned char *mic_header2,
+			   unsigned char *mpdu, int a4_exists, int qc_exists)
+{
+	int i;
+
+	for (i = 0; i < 16; i++)
+		mic_header2[i] = 0x00;
+
+	mic_header2[0] = mpdu[16];	/* A3 */
+	mic_header2[1] = mpdu[17];
+	mic_header2[2] = mpdu[18];
+	mic_header2[3] = mpdu[19];
+	mic_header2[4] = mpdu[20];
+	mic_header2[5] = mpdu[21];
+
+	/* In Sequence Control field, mute sequence numer bits (12-bit) */
+	mic_header2[6] = mpdu[22] & 0x0f;	/* SC */
+	mic_header2[7] = 0x00;	/* mpdu[23]; */
+
+	if ((!qc_exists) & a4_exists) {
+		for (i = 0; i < 6; i++)
+			mic_header2[8 + i] = mpdu[24 + i];	/* A4 */
+
+	}
+
+	if (qc_exists && (!a4_exists)) {
+		mic_header2[8] = mpdu[24] & 0x0f;	/* mute bits 15 - 4 */
+		mic_header2[9] = mpdu[25] & 0x00;
+	}
+
+	if (qc_exists && a4_exists) {
+		for (i = 0; i < 6; i++)
+			mic_header2[8 + i] = mpdu[24 + i];	/* A4 */
+
+		mic_header2[14] = mpdu[30] & 0x0f;
+		mic_header2[15] = mpdu[31] & 0x00;
+	}
+}
+
+/************************************************/
+/* construct_mic_iv()                           */
+/* Builds the MIC IV from header fields and PN  */
+/************************************************/
+
+void construct_mic_iv(unsigned char *mic_iv,
+		      int qc_exists,
+		      int a4_exists,
+		      unsigned char *mpdu,
+		      unsigned int payload_length, unsigned char *pn_vector)
+{
+	int i;
+
+	mic_iv[0] = 0x59;
+	if (qc_exists && a4_exists)
+		mic_iv[1] = mpdu[30] & 0x0f;	/* QoS_TC           */
+	if (qc_exists && !a4_exists)
+		mic_iv[1] = mpdu[24] & 0x0f;	/* mute bits 7-4    */
+	if (!qc_exists)
+		mic_iv[1] = 0x00;
+	for (i = 2; i < 8; i++)
+		mic_iv[i] = mpdu[i + 8];	/* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
+#ifdef CONSISTENT_PN_ORDER
+	for (i = 8; i < 14; i++)
+		mic_iv[i] = pn_vector[i - 8];	/* mic_iv[8:13] = PN[0:5] */
+#else
+	for (i = 8; i < 14; i++)
+		mic_iv[i] = pn_vector[13 - i];	/* mic_iv[8:13] = PN[5:0] */
+#endif
+	i = (payload_length / 256);
+	i = (payload_length % 256);
+	mic_iv[14] = (unsigned char)(payload_length / 256);
+	mic_iv[15] = (unsigned char)(payload_length % 256);
+
+}
+
+/****************************************/
+/* aes128k128d()                        */
+/* Performs a 128 bit AES encrypt with  */
+/* 128 bit data.                        */
+/****************************************/
+void aes128k128d(unsigned char *key, unsigned char *data,
+		 unsigned char *ciphertext)
+{
+	int round;
+	int i;
+	unsigned char intermediatea[16];
+	unsigned char intermediateb[16];
+	unsigned char round_key[16];
+
+	for (i = 0; i < 16; i++)
+		round_key[i] = key[i];
+
+	for (round = 0; round < 11; round++) {
+		if (round == 0) {
+			xor_128(round_key, data, ciphertext);
+			next_key(round_key, round);
+		} else if (round == 10) {
+			byte_sub(ciphertext, intermediatea);
+			shift_row(intermediatea, intermediateb);
+			xor_128(intermediateb, round_key, ciphertext);
+		} else {	/* 1 - 9 */
+
+			byte_sub(ciphertext, intermediatea);
+			shift_row(intermediatea, intermediateb);
+			mix_column(&intermediateb[0], &intermediatea[0]);
+			mix_column(&intermediateb[4], &intermediatea[4]);
+			mix_column(&intermediateb[8], &intermediatea[8]);
+			mix_column(&intermediateb[12], &intermediatea[12]);
+			xor_128(intermediatea, round_key, ciphertext);
+			next_key(round_key, round);
+		}
+	}
+
+}
+
+void construct_ctr_preload(unsigned char *ctr_preload,
+			   int a4_exists,
+			   int qc_exists,
+			   unsigned char *mpdu, unsigned char *pn_vector, int c)
+{
+
+	int i = 0;
+	for (i = 0; i < 16; i++)
+		ctr_preload[i] = 0x00;
+	i = 0;
+
+	ctr_preload[0] = 0x01;	/* flag */
+	if (qc_exists && a4_exists)
+		ctr_preload[1] = mpdu[30] & 0x0f;	/* QoC_Control  */
+	if (qc_exists && !a4_exists)
+		ctr_preload[1] = mpdu[24] & 0x0f;
+
+	for (i = 2; i < 8; i++)
+		ctr_preload[i] = mpdu[i + 8];	/* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
+#ifdef CONSISTENT_PN_ORDER
+	for (i = 8; i < 14; i++)
+		ctr_preload[i] = pn_vector[i - 8];	/* ctr_preload[8:13] = PN[0:5] */
+#else
+	for (i = 8; i < 14; i++)
+		ctr_preload[i] = pn_vector[13 - i];	/* ctr_preload[8:13] = PN[5:0] */
+#endif
+	ctr_preload[14] = (unsigned char)(c / 256);	/* Ctr */
+	ctr_preload[15] = (unsigned char)(c % 256);
+
+}
+
+BOOLEAN RTMPSoftDecryptAES(struct rt_rtmp_adapter *pAd,
+			   u8 *pData,
+			   unsigned long DataByteCnt, struct rt_cipher_key *pWpaKey)
+{
+	u8 KeyID;
+	u32 HeaderLen;
+	u8 PN[6];
+	u32 payload_len;
+	u32 num_blocks;
+	u32 payload_remainder;
+	u16 fc;
+	u8 fc0;
+	u8 fc1;
+	u32 frame_type;
+	u32 frame_subtype;
+	u32 from_ds;
+	u32 to_ds;
+	int a4_exists;
+	int qc_exists;
+	u8 aes_out[16];
+	int payload_index;
+	u32 i;
+	u8 ctr_preload[16];
+	u8 chain_buffer[16];
+	u8 padded_buffer[16];
+	u8 mic_iv[16];
+	u8 mic_header1[16];
+	u8 mic_header2[16];
+	u8 MIC[8];
+	u8 TrailMIC[8];
+
+	fc0 = *pData;
+	fc1 = *(pData + 1);
+
+	fc = *((u16 *)pData);
+
+	frame_type = ((fc0 >> 2) & 0x03);
+	frame_subtype = ((fc0 >> 4) & 0x0f);
+
+	from_ds = (fc1 & 0x2) >> 1;
+	to_ds = (fc1 & 0x1);
+
+	a4_exists = (from_ds & to_ds);
+	qc_exists = ((frame_subtype == 0x08) ||	/* Assumed QoS subtypes */
+		     (frame_subtype == 0x09) ||	/* Likely to change.    */
+		     (frame_subtype == 0x0a) || (frame_subtype == 0x0b)
+	    );
+
+	HeaderLen = 24;
+	if (a4_exists)
+		HeaderLen += 6;
+
+	KeyID = *((u8 *)(pData + HeaderLen + 3));
+	KeyID = KeyID >> 6;
+
+	if (pWpaKey[KeyID].KeyLen == 0) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("RTMPSoftDecryptAES failed!(KeyID[%d] Length can not be 0)\n",
+			  KeyID));
+		return FALSE;
+	}
+
+	PN[0] = *(pData + HeaderLen);
+	PN[1] = *(pData + HeaderLen + 1);
+	PN[2] = *(pData + HeaderLen + 4);
+	PN[3] = *(pData + HeaderLen + 5);
+	PN[4] = *(pData + HeaderLen + 6);
+	PN[5] = *(pData + HeaderLen + 7);
+
+	payload_len = DataByteCnt - HeaderLen - 8 - 8;	/* 8 bytes for CCMP header , 8 bytes for MIC */
+	payload_remainder = (payload_len) % 16;
+	num_blocks = (payload_len) / 16;
+
+	/* Find start of payload */
+	payload_index = HeaderLen + 8;	/*IV+EIV */
+
+	for (i = 0; i < num_blocks; i++) {
+		construct_ctr_preload(ctr_preload,
+				      a4_exists, qc_exists, pData, PN, i + 1);
+
+		aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
+
+		bitwise_xor(aes_out, pData + payload_index, chain_buffer);
+		NdisMoveMemory(pData + payload_index - 8, chain_buffer, 16);
+		payload_index += 16;
+	}
+
+	/* */
+	/* If there is a short final block, then pad it */
+	/* encrypt it and copy the unpadded part back */
+	/* */
+	if (payload_remainder > 0) {
+		construct_ctr_preload(ctr_preload,
+				      a4_exists,
+				      qc_exists, pData, PN, num_blocks + 1);
+
+		NdisZeroMemory(padded_buffer, 16);
+		NdisMoveMemory(padded_buffer, pData + payload_index,
+			       payload_remainder);
+
+		aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
+
+		bitwise_xor(aes_out, padded_buffer, chain_buffer);
+		NdisMoveMemory(pData + payload_index - 8, chain_buffer,
+			       payload_remainder);
+		payload_index += payload_remainder;
+	}
+	/* */
+	/* Descrypt the MIC */
+	/* */
+	construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pData, PN, 0);
+	NdisZeroMemory(padded_buffer, 16);
+	NdisMoveMemory(padded_buffer, pData + payload_index, 8);
+
+	aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
+
+	bitwise_xor(aes_out, padded_buffer, chain_buffer);
+
+	NdisMoveMemory(TrailMIC, chain_buffer, 8);
+
+	/* */
+	/* Calculate MIC */
+	/* */
+
+	/*Force the protected frame bit on */
+	*(pData + 1) = *(pData + 1) | 0x40;
+
+	/* Find start of payload */
+	/* Because the CCMP header has been removed */
+	payload_index = HeaderLen;
+
+	construct_mic_iv(mic_iv, qc_exists, a4_exists, pData, payload_len, PN);
+
+	construct_mic_header1(mic_header1, HeaderLen, pData);
+
+	construct_mic_header2(mic_header2, pData, a4_exists, qc_exists);
+
+	aes128k128d(pWpaKey[KeyID].Key, mic_iv, aes_out);
+	bitwise_xor(aes_out, mic_header1, chain_buffer);
+	aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
+	bitwise_xor(aes_out, mic_header2, chain_buffer);
+	aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
+
+	/* iterate through each 16 byte payload block */
+	for (i = 0; i < num_blocks; i++) {
+		bitwise_xor(aes_out, pData + payload_index, chain_buffer);
+		payload_index += 16;
+		aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
+	}
+
+	/* Add on the final payload block if it needs padding */
+	if (payload_remainder > 0) {
+		NdisZeroMemory(padded_buffer, 16);
+		NdisMoveMemory(padded_buffer, pData + payload_index,
+			       payload_remainder);
+
+		bitwise_xor(aes_out, padded_buffer, chain_buffer);
+		aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
+	}
+	/* aes_out contains padded mic, discard most significant */
+	/* 8 bytes to generate 64 bit MIC */
+	for (i = 0; i < 8; i++)
+		MIC[i] = aes_out[i];
+
+	if (!NdisEqualMemory(MIC, TrailMIC, 8)) {
+		DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptAES, MIC Error !\n"));	/*MIC error. */
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+/* =========================  AES En/Decryption ========================== */
+#ifndef	uint8
+#define	uint8  unsigned	char
+#endif
+
+#ifndef	uint32
+#define	uint32 unsigned	int
+#endif
+
+/* forward S-box */
+static uint32 FSb[256] = {
+	0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
+	0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
+	0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
+	0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
+	0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
+	0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
+	0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
+	0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
+	0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
+	0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
+	0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
+	0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
+	0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
+	0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
+	0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
+	0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
+	0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
+	0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
+	0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
+	0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
+	0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
+	0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
+	0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
+	0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
+	0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
+	0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
+	0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
+	0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
+	0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
+	0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
+	0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
+	0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
+};
+
+/* forward table */
+#define	FT \
+\
+	V(C6,63,63,A5),	V(F8,7C,7C,84),	V(EE,77,77,99),	V(F6,7B,7B,8D),	\
+	V(FF,F2,F2,0D),	V(D6,6B,6B,BD),	V(DE,6F,6F,B1),	V(91,C5,C5,54),	\
+	V(60,30,30,50),	V(02,01,01,03),	V(CE,67,67,A9),	V(56,2B,2B,7D),	\
+	V(E7,FE,FE,19),	V(B5,D7,D7,62),	V(4D,AB,AB,E6),	V(EC,76,76,9A),	\
+	V(8F,CA,CA,45),	V(1F,82,82,9D),	V(89,C9,C9,40),	V(FA,7D,7D,87),	\
+	V(EF,FA,FA,15),	V(B2,59,59,EB),	V(8E,47,47,C9),	V(FB,F0,F0,0B),	\
+	V(41,AD,AD,EC),	V(B3,D4,D4,67),	V(5F,A2,A2,FD),	V(45,AF,AF,EA),	\
+	V(23,9C,9C,BF),	V(53,A4,A4,F7),	V(E4,72,72,96),	V(9B,C0,C0,5B),	\
+	V(75,B7,B7,C2),	V(E1,FD,FD,1C),	V(3D,93,93,AE),	V(4C,26,26,6A),	\
+	V(6C,36,36,5A),	V(7E,3F,3F,41),	V(F5,F7,F7,02),	V(83,CC,CC,4F),	\
+	V(68,34,34,5C),	V(51,A5,A5,F4),	V(D1,E5,E5,34),	V(F9,F1,F1,08),	\
+	V(E2,71,71,93),	V(AB,D8,D8,73),	V(62,31,31,53),	V(2A,15,15,3F),	\
+	V(08,04,04,0C),	V(95,C7,C7,52),	V(46,23,23,65),	V(9D,C3,C3,5E),	\
+	V(30,18,18,28),	V(37,96,96,A1),	V(0A,05,05,0F),	V(2F,9A,9A,B5),	\
+	V(0E,07,07,09),	V(24,12,12,36),	V(1B,80,80,9B),	V(DF,E2,E2,3D),	\
+	V(CD,EB,EB,26),	V(4E,27,27,69),	V(7F,B2,B2,CD),	V(EA,75,75,9F),	\
+	V(12,09,09,1B),	V(1D,83,83,9E),	V(58,2C,2C,74),	V(34,1A,1A,2E),	\
+	V(36,1B,1B,2D),	V(DC,6E,6E,B2),	V(B4,5A,5A,EE),	V(5B,A0,A0,FB),	\
+	V(A4,52,52,F6),	V(76,3B,3B,4D),	V(B7,D6,D6,61),	V(7D,B3,B3,CE),	\
+	V(52,29,29,7B),	V(DD,E3,E3,3E),	V(5E,2F,2F,71),	V(13,84,84,97),	\
+	V(A6,53,53,F5),	V(B9,D1,D1,68),	V(00,00,00,00),	V(C1,ED,ED,2C),	\
+	V(40,20,20,60),	V(E3,FC,FC,1F),	V(79,B1,B1,C8),	V(B6,5B,5B,ED),	\
+	V(D4,6A,6A,BE),	V(8D,CB,CB,46),	V(67,BE,BE,D9),	V(72,39,39,4B),	\
+	V(94,4A,4A,DE),	V(98,4C,4C,D4),	V(B0,58,58,E8),	V(85,CF,CF,4A),	\
+	V(BB,D0,D0,6B),	V(C5,EF,EF,2A),	V(4F,AA,AA,E5),	V(ED,FB,FB,16),	\
+	V(86,43,43,C5),	V(9A,4D,4D,D7),	V(66,33,33,55),	V(11,85,85,94),	\
+	V(8A,45,45,CF),	V(E9,F9,F9,10),	V(04,02,02,06),	V(FE,7F,7F,81),	\
+	V(A0,50,50,F0),	V(78,3C,3C,44),	V(25,9F,9F,BA),	V(4B,A8,A8,E3),	\
+	V(A2,51,51,F3),	V(5D,A3,A3,FE),	V(80,40,40,C0),	V(05,8F,8F,8A),	\
+	V(3F,92,92,AD),	V(21,9D,9D,BC),	V(70,38,38,48),	V(F1,F5,F5,04),	\
+	V(63,BC,BC,DF),	V(77,B6,B6,C1),	V(AF,DA,DA,75),	V(42,21,21,63),	\
+	V(20,10,10,30),	V(E5,FF,FF,1A),	V(FD,F3,F3,0E),	V(BF,D2,D2,6D),	\
+	V(81,CD,CD,4C),	V(18,0C,0C,14),	V(26,13,13,35),	V(C3,EC,EC,2F),	\
+	V(BE,5F,5F,E1),	V(35,97,97,A2),	V(88,44,44,CC),	V(2E,17,17,39),	\
+	V(93,C4,C4,57),	V(55,A7,A7,F2),	V(FC,7E,7E,82),	V(7A,3D,3D,47),	\
+	V(C8,64,64,AC),	V(BA,5D,5D,E7),	V(32,19,19,2B),	V(E6,73,73,95),	\
+	V(C0,60,60,A0),	V(19,81,81,98),	V(9E,4F,4F,D1),	V(A3,DC,DC,7F),	\
+	V(44,22,22,66),	V(54,2A,2A,7E),	V(3B,90,90,AB),	V(0B,88,88,83),	\
+	V(8C,46,46,CA),	V(C7,EE,EE,29),	V(6B,B8,B8,D3),	V(28,14,14,3C),	\
+	V(A7,DE,DE,79),	V(BC,5E,5E,E2),	V(16,0B,0B,1D),	V(AD,DB,DB,76),	\
+	V(DB,E0,E0,3B),	V(64,32,32,56),	V(74,3A,3A,4E),	V(14,0A,0A,1E),	\
+	V(92,49,49,DB),	V(0C,06,06,0A),	V(48,24,24,6C),	V(B8,5C,5C,E4),	\
+	V(9F,C2,C2,5D),	V(BD,D3,D3,6E),	V(43,AC,AC,EF),	V(C4,62,62,A6),	\
+	V(39,91,91,A8),	V(31,95,95,A4),	V(D3,E4,E4,37),	V(F2,79,79,8B),	\
+	V(D5,E7,E7,32),	V(8B,C8,C8,43),	V(6E,37,37,59),	V(DA,6D,6D,B7),	\
+	V(01,8D,8D,8C),	V(B1,D5,D5,64),	V(9C,4E,4E,D2),	V(49,A9,A9,E0),	\
+	V(D8,6C,6C,B4),	V(AC,56,56,FA),	V(F3,F4,F4,07),	V(CF,EA,EA,25),	\
+	V(CA,65,65,AF),	V(F4,7A,7A,8E),	V(47,AE,AE,E9),	V(10,08,08,18),	\
+	V(6F,BA,BA,D5),	V(F0,78,78,88),	V(4A,25,25,6F),	V(5C,2E,2E,72),	\
+	V(38,1C,1C,24),	V(57,A6,A6,F1),	V(73,B4,B4,C7),	V(97,C6,C6,51),	\
+	V(CB,E8,E8,23),	V(A1,DD,DD,7C),	V(E8,74,74,9C),	V(3E,1F,1F,21),	\
+	V(96,4B,4B,DD),	V(61,BD,BD,DC),	V(0D,8B,8B,86),	V(0F,8A,8A,85),	\
+	V(E0,70,70,90),	V(7C,3E,3E,42),	V(71,B5,B5,C4),	V(CC,66,66,AA),	\
+	V(90,48,48,D8),	V(06,03,03,05),	V(F7,F6,F6,01),	V(1C,0E,0E,12),	\
+	V(C2,61,61,A3),	V(6A,35,35,5F),	V(AE,57,57,F9),	V(69,B9,B9,D0),	\
+	V(17,86,86,91),	V(99,C1,C1,58),	V(3A,1D,1D,27),	V(27,9E,9E,B9),	\
+	V(D9,E1,E1,38),	V(EB,F8,F8,13),	V(2B,98,98,B3),	V(22,11,11,33),	\
+	V(D2,69,69,BB),	V(A9,D9,D9,70),	V(07,8E,8E,89),	V(33,94,94,A7),	\
+	V(2D,9B,9B,B6),	V(3C,1E,1E,22),	V(15,87,87,92),	V(C9,E9,E9,20),	\
+	V(87,CE,CE,49),	V(AA,55,55,FF),	V(50,28,28,78),	V(A5,DF,DF,7A),	\
+	V(03,8C,8C,8F),	V(59,A1,A1,F8),	V(09,89,89,80),	V(1A,0D,0D,17),	\
+	V(65,BF,BF,DA),	V(D7,E6,E6,31),	V(84,42,42,C6),	V(D0,68,68,B8),	\
+	V(82,41,41,C3),	V(29,99,99,B0),	V(5A,2D,2D,77),	V(1E,0F,0F,11),	\
+	V(7B,B0,B0,CB),	V(A8,54,54,FC),	V(6D,BB,BB,D6),	V(2C,16,16,3A)
+
+#define	V(a,b,c,d) 0x##a##b##c##d
+static uint32 FT0[256] = { FT };
+
+#undef V
+
+#define	V(a,b,c,d) 0x##d##a##b##c
+static uint32 FT1[256] = { FT };
+
+#undef V
+
+#define	V(a,b,c,d) 0x##c##d##a##b
+static uint32 FT2[256] = { FT };
+
+#undef V
+
+#define	V(a,b,c,d) 0x##b##c##d##a
+static uint32 FT3[256] = { FT };
+
+#undef V
+
+#undef FT
+
+/* reverse S-box */
+
+static uint32 RSb[256] = {
+	0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
+	0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
+	0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
+	0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
+	0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
+	0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
+	0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
+	0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
+	0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
+	0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
+	0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
+	0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
+	0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
+	0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
+	0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
+	0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
+	0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
+	0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
+	0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
+	0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
+	0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
+	0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
+	0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
+	0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
+	0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
+	0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
+	0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
+	0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
+	0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
+	0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
+	0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
+	0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
+};
+
+/* reverse table */
+
+#define	RT \
+\
+	V(51,F4,A7,50),	V(7E,41,65,53),	V(1A,17,A4,C3),	V(3A,27,5E,96),	\
+	V(3B,AB,6B,CB),	V(1F,9D,45,F1),	V(AC,FA,58,AB),	V(4B,E3,03,93),	\
+	V(20,30,FA,55),	V(AD,76,6D,F6),	V(88,CC,76,91),	V(F5,02,4C,25),	\
+	V(4F,E5,D7,FC),	V(C5,2A,CB,D7),	V(26,35,44,80),	V(B5,62,A3,8F),	\
+	V(DE,B1,5A,49),	V(25,BA,1B,67),	V(45,EA,0E,98),	V(5D,FE,C0,E1),	\
+	V(C3,2F,75,02),	V(81,4C,F0,12),	V(8D,46,97,A3),	V(6B,D3,F9,C6),	\
+	V(03,8F,5F,E7),	V(15,92,9C,95),	V(BF,6D,7A,EB),	V(95,52,59,DA),	\
+	V(D4,BE,83,2D),	V(58,74,21,D3),	V(49,E0,69,29),	V(8E,C9,C8,44),	\
+	V(75,C2,89,6A),	V(F4,8E,79,78),	V(99,58,3E,6B),	V(27,B9,71,DD),	\
+	V(BE,E1,4F,B6),	V(F0,88,AD,17),	V(C9,20,AC,66),	V(7D,CE,3A,B4),	\
+	V(63,DF,4A,18),	V(E5,1A,31,82),	V(97,51,33,60),	V(62,53,7F,45),	\
+	V(B1,64,77,E0),	V(BB,6B,AE,84),	V(FE,81,A0,1C),	V(F9,08,2B,94),	\
+	V(70,48,68,58),	V(8F,45,FD,19),	V(94,DE,6C,87),	V(52,7B,F8,B7),	\
+	V(AB,73,D3,23),	V(72,4B,02,E2),	V(E3,1F,8F,57),	V(66,55,AB,2A),	\
+	V(B2,EB,28,07),	V(2F,B5,C2,03),	V(86,C5,7B,9A),	V(D3,37,08,A5),	\
+	V(30,28,87,F2),	V(23,BF,A5,B2),	V(02,03,6A,BA),	V(ED,16,82,5C),	\
+	V(8A,CF,1C,2B),	V(A7,79,B4,92),	V(F3,07,F2,F0),	V(4E,69,E2,A1),	\
+	V(65,DA,F4,CD),	V(06,05,BE,D5),	V(D1,34,62,1F),	V(C4,A6,FE,8A),	\
+	V(34,2E,53,9D),	V(A2,F3,55,A0),	V(05,8A,E1,32),	V(A4,F6,EB,75),	\
+	V(0B,83,EC,39),	V(40,60,EF,AA),	V(5E,71,9F,06),	V(BD,6E,10,51),	\
+	V(3E,21,8A,F9),	V(96,DD,06,3D),	V(DD,3E,05,AE),	V(4D,E6,BD,46),	\
+	V(91,54,8D,B5),	V(71,C4,5D,05),	V(04,06,D4,6F),	V(60,50,15,FF),	\
+	V(19,98,FB,24),	V(D6,BD,E9,97),	V(89,40,43,CC),	V(67,D9,9E,77),	\
+	V(B0,E8,42,BD),	V(07,89,8B,88),	V(E7,19,5B,38),	V(79,C8,EE,DB),	\
+	V(A1,7C,0A,47),	V(7C,42,0F,E9),	V(F8,84,1E,C9),	V(00,00,00,00),	\
+	V(09,80,86,83),	V(32,2B,ED,48),	V(1E,11,70,AC),	V(6C,5A,72,4E),	\
+	V(FD,0E,FF,FB),	V(0F,85,38,56),	V(3D,AE,D5,1E),	V(36,2D,39,27),	\
+	V(0A,0F,D9,64),	V(68,5C,A6,21),	V(9B,5B,54,D1),	V(24,36,2E,3A),	\
+	V(0C,0A,67,B1),	V(93,57,E7,0F),	V(B4,EE,96,D2),	V(1B,9B,91,9E),	\
+	V(80,C0,C5,4F),	V(61,DC,20,A2),	V(5A,77,4B,69),	V(1C,12,1A,16),	\
+	V(E2,93,BA,0A),	V(C0,A0,2A,E5),	V(3C,22,E0,43),	V(12,1B,17,1D),	\
+	V(0E,09,0D,0B),	V(F2,8B,C7,AD),	V(2D,B6,A8,B9),	V(14,1E,A9,C8),	\
+	V(57,F1,19,85),	V(AF,75,07,4C),	V(EE,99,DD,BB),	V(A3,7F,60,FD),	\
+	V(F7,01,26,9F),	V(5C,72,F5,BC),	V(44,66,3B,C5),	V(5B,FB,7E,34),	\
+	V(8B,43,29,76),	V(CB,23,C6,DC),	V(B6,ED,FC,68),	V(B8,E4,F1,63),	\
+	V(D7,31,DC,CA),	V(42,63,85,10),	V(13,97,22,40),	V(84,C6,11,20),	\
+	V(85,4A,24,7D),	V(D2,BB,3D,F8),	V(AE,F9,32,11),	V(C7,29,A1,6D),	\
+	V(1D,9E,2F,4B),	V(DC,B2,30,F3),	V(0D,86,52,EC),	V(77,C1,E3,D0),	\
+	V(2B,B3,16,6C),	V(A9,70,B9,99),	V(11,94,48,FA),	V(47,E9,64,22),	\
+	V(A8,FC,8C,C4),	V(A0,F0,3F,1A),	V(56,7D,2C,D8),	V(22,33,90,EF),	\
+	V(87,49,4E,C7),	V(D9,38,D1,C1),	V(8C,CA,A2,FE),	V(98,D4,0B,36),	\
+	V(A6,F5,81,CF),	V(A5,7A,DE,28),	V(DA,B7,8E,26),	V(3F,AD,BF,A4),	\
+	V(2C,3A,9D,E4),	V(50,78,92,0D),	V(6A,5F,CC,9B),	V(54,7E,46,62),	\
+	V(F6,8D,13,C2),	V(90,D8,B8,E8),	V(2E,39,F7,5E),	V(82,C3,AF,F5),	\
+	V(9F,5D,80,BE),	V(69,D0,93,7C),	V(6F,D5,2D,A9),	V(CF,25,12,B3),	\
+	V(C8,AC,99,3B),	V(10,18,7D,A7),	V(E8,9C,63,6E),	V(DB,3B,BB,7B),	\
+	V(CD,26,78,09),	V(6E,59,18,F4),	V(EC,9A,B7,01),	V(83,4F,9A,A8),	\
+	V(E6,95,6E,65),	V(AA,FF,E6,7E),	V(21,BC,CF,08),	V(EF,15,E8,E6),	\
+	V(BA,E7,9B,D9),	V(4A,6F,36,CE),	V(EA,9F,09,D4),	V(29,B0,7C,D6),	\
+	V(31,A4,B2,AF),	V(2A,3F,23,31),	V(C6,A5,94,30),	V(35,A2,66,C0),	\
+	V(74,4E,BC,37),	V(FC,82,CA,A6),	V(E0,90,D0,B0),	V(33,A7,D8,15),	\
+	V(F1,04,98,4A),	V(41,EC,DA,F7),	V(7F,CD,50,0E),	V(17,91,F6,2F),	\
+	V(76,4D,D6,8D),	V(43,EF,B0,4D),	V(CC,AA,4D,54),	V(E4,96,04,DF),	\
+	V(9E,D1,B5,E3),	V(4C,6A,88,1B),	V(C1,2C,1F,B8),	V(46,65,51,7F),	\
+	V(9D,5E,EA,04),	V(01,8C,35,5D),	V(FA,87,74,73),	V(FB,0B,41,2E),	\
+	V(B3,67,1D,5A),	V(92,DB,D2,52),	V(E9,10,56,33),	V(6D,D6,47,13),	\
+	V(9A,D7,61,8C),	V(37,A1,0C,7A),	V(59,F8,14,8E),	V(EB,13,3C,89),	\
+	V(CE,A9,27,EE),	V(B7,61,C9,35),	V(E1,1C,E5,ED),	V(7A,47,B1,3C),	\
+	V(9C,D2,DF,59),	V(55,F2,73,3F),	V(18,14,CE,79),	V(73,C7,37,BF),	\
+	V(53,F7,CD,EA),	V(5F,FD,AA,5B),	V(DF,3D,6F,14),	V(78,44,DB,86),	\
+	V(CA,AF,F3,81),	V(B9,68,C4,3E),	V(38,24,34,2C),	V(C2,A3,40,5F),	\
+	V(16,1D,C3,72),	V(BC,E2,25,0C),	V(28,3C,49,8B),	V(FF,0D,95,41),	\
+	V(39,A8,01,71),	V(08,0C,B3,DE),	V(D8,B4,E4,9C),	V(64,56,C1,90),	\
+	V(7B,CB,84,61),	V(D5,32,B6,70),	V(48,6C,5C,74),	V(D0,B8,57,42)
+
+#define	V(a,b,c,d) 0x##a##b##c##d
+static uint32 RT0[256] = { RT };
+
+#undef V
+
+#define	V(a,b,c,d) 0x##d##a##b##c
+static uint32 RT1[256] = { RT };
+
+#undef V
+
+#define	V(a,b,c,d) 0x##c##d##a##b
+static uint32 RT2[256] = { RT };
+
+#undef V
+
+#define	V(a,b,c,d) 0x##b##c##d##a
+static uint32 RT3[256] = { RT };
+
+#undef V
+
+#undef RT
+
+/* round constants */
+
+static uint32 RCON[10] = {
+	0x01000000, 0x02000000, 0x04000000, 0x08000000,
+	0x10000000, 0x20000000, 0x40000000, 0x80000000,
+	0x1B000000, 0x36000000
+};
+
+/* key schedule	tables */
+
+static int KT_init = 1;
+
+static uint32 KT0[256];
+static uint32 KT1[256];
+static uint32 KT2[256];
+static uint32 KT3[256];
+
+/* platform-independant	32-bit integer manipulation	macros */
+
+#define	GET_UINT32(n,b,i)						\
+{												\
+	(n)	= (	(uint32) (b)[(i)	] << 24	)		\
+		| (	(uint32) (b)[(i) + 1] << 16	)		\
+		| (	(uint32) (b)[(i) + 2] <<  8	)		\
+		| (	(uint32) (b)[(i) + 3]		);		\
+}
+
+#define	PUT_UINT32(n,b,i)						\
+{												\
+	(b)[(i)	   ] = (uint8) ( (n) >>	24 );		\
+	(b)[(i)	+ 1] = (uint8) ( (n) >>	16 );		\
+	(b)[(i)	+ 2] = (uint8) ( (n) >>	 8 );		\
+	(b)[(i)	+ 3] = (uint8) ( (n)	   );		\
+}
+
+int rt_aes_set_key(struct aes_context * ctx, uint8 * key, int nbits)
+{
+	int i;
+	uint32 *RK, *SK;
+
+	switch (nbits) {
+	case 128:
+		ctx->nr = 10;
+		break;
+	case 192:
+		ctx->nr = 12;
+		break;
+	case 256:
+		ctx->nr = 14;
+		break;
+	default:
+		return (1);
+	}
+
+	RK = (uint32 *) ctx->erk;
+
+	for (i = 0; i < (nbits >> 5); i++) {
+		GET_UINT32(RK[i], key, i * 4);
+	}
+
+	/* setup encryption     round keys */
+
+	switch (nbits) {
+	case 128:
+
+		for (i = 0; i < 10; i++, RK += 4) {
+			RK[4] = RK[0] ^ RCON[i] ^
+			    (FSb[(uint8) (RK[3] >> 16)] << 24) ^
+			    (FSb[(uint8) (RK[3] >> 8)] << 16) ^
+			    (FSb[(uint8) (RK[3])] << 8) ^
+			    (FSb[(uint8) (RK[3] >> 24)]);
+
+			RK[5] = RK[1] ^ RK[4];
+			RK[6] = RK[2] ^ RK[5];
+			RK[7] = RK[3] ^ RK[6];
+		}
+		break;
+
+	case 192:
+
+		for (i = 0; i < 8; i++, RK += 6) {
+			RK[6] = RK[0] ^ RCON[i] ^
+			    (FSb[(uint8) (RK[5] >> 16)] << 24) ^
+			    (FSb[(uint8) (RK[5] >> 8)] << 16) ^
+			    (FSb[(uint8) (RK[5])] << 8) ^
+			    (FSb[(uint8) (RK[5] >> 24)]);
+
+			RK[7] = RK[1] ^ RK[6];
+			RK[8] = RK[2] ^ RK[7];
+			RK[9] = RK[3] ^ RK[8];
+			RK[10] = RK[4] ^ RK[9];
+			RK[11] = RK[5] ^ RK[10];
+		}
+		break;
+
+	case 256:
+
+		for (i = 0; i < 7; i++, RK += 8) {
+			RK[8] = RK[0] ^ RCON[i] ^
+			    (FSb[(uint8) (RK[7] >> 16)] << 24) ^
+			    (FSb[(uint8) (RK[7] >> 8)] << 16) ^
+			    (FSb[(uint8) (RK[7])] << 8) ^
+			    (FSb[(uint8) (RK[7] >> 24)]);
+
+			RK[9] = RK[1] ^ RK[8];
+			RK[10] = RK[2] ^ RK[9];
+			RK[11] = RK[3] ^ RK[10];
+
+			RK[12] = RK[4] ^
+			    (FSb[(uint8) (RK[11] >> 24)] << 24) ^
+			    (FSb[(uint8) (RK[11] >> 16)] << 16) ^
+			    (FSb[(uint8) (RK[11] >> 8)] << 8) ^
+			    (FSb[(uint8) (RK[11])]);
+
+			RK[13] = RK[5] ^ RK[12];
+			RK[14] = RK[6] ^ RK[13];
+			RK[15] = RK[7] ^ RK[14];
+		}
+		break;
+	}
+
+	/* setup decryption     round keys */
+
+	if (KT_init) {
+		for (i = 0; i < 256; i++) {
+			KT0[i] = RT0[FSb[i]];
+			KT1[i] = RT1[FSb[i]];
+			KT2[i] = RT2[FSb[i]];
+			KT3[i] = RT3[FSb[i]];
+		}
+
+		KT_init = 0;
+	}
+
+	SK = (uint32 *) ctx->drk;
+
+	*SK++ = *RK++;
+	*SK++ = *RK++;
+	*SK++ = *RK++;
+	*SK++ = *RK++;
+
+	for (i = 1; i < ctx->nr; i++) {
+		RK -= 8;
+
+		*SK++ = KT0[(uint8) (*RK >> 24)] ^
+		    KT1[(uint8) (*RK >> 16)] ^
+		    KT2[(uint8) (*RK >> 8)] ^ KT3[(uint8) (*RK)];
+		RK++;
+
+		*SK++ = KT0[(uint8) (*RK >> 24)] ^
+		    KT1[(uint8) (*RK >> 16)] ^
+		    KT2[(uint8) (*RK >> 8)] ^ KT3[(uint8) (*RK)];
+		RK++;
+
+		*SK++ = KT0[(uint8) (*RK >> 24)] ^
+		    KT1[(uint8) (*RK >> 16)] ^
+		    KT2[(uint8) (*RK >> 8)] ^ KT3[(uint8) (*RK)];
+		RK++;
+
+		*SK++ = KT0[(uint8) (*RK >> 24)] ^
+		    KT1[(uint8) (*RK >> 16)] ^
+		    KT2[(uint8) (*RK >> 8)] ^ KT3[(uint8) (*RK)];
+		RK++;
+	}
+
+	RK -= 8;
+
+	*SK++ = *RK++;
+	*SK++ = *RK++;
+	*SK++ = *RK++;
+	*SK++ = *RK++;
+
+	return (0);
+}
+
+/* AES 128-bit block encryption	routine	*/
+
+void rt_aes_encrypt(struct aes_context * ctx, uint8 input[16], uint8 output[16])
+{
+	uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
+
+	RK = (uint32 *) ctx->erk;
+	GET_UINT32(X0, input, 0);
+	X0 ^= RK[0];
+	GET_UINT32(X1, input, 4);
+	X1 ^= RK[1];
+	GET_UINT32(X2, input, 8);
+	X2 ^= RK[2];
+	GET_UINT32(X3, input, 12);
+	X3 ^= RK[3];
+
+#define	AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)		\
+{												\
+	RK += 4;									\
+												\
+	X0 = RK[0] ^ FT0[ (uint8) (	Y0 >> 24 ) ] ^	\
+				 FT1[ (uint8) (	Y1 >> 16 ) ] ^	\
+				 FT2[ (uint8) (	Y2 >>  8 ) ] ^	\
+				 FT3[ (uint8) (	Y3		 ) ];	\
+												\
+	X1 = RK[1] ^ FT0[ (uint8) (	Y1 >> 24 ) ] ^	\
+				 FT1[ (uint8) (	Y2 >> 16 ) ] ^	\
+				 FT2[ (uint8) (	Y3 >>  8 ) ] ^	\
+				 FT3[ (uint8) (	Y0		 ) ];	\
+												\
+	X2 = RK[2] ^ FT0[ (uint8) (	Y2 >> 24 ) ] ^	\
+				 FT1[ (uint8) (	Y3 >> 16 ) ] ^	\
+				 FT2[ (uint8) (	Y0 >>  8 ) ] ^	\
+				 FT3[ (uint8) (	Y1		 ) ];	\
+												\
+	X3 = RK[3] ^ FT0[ (uint8) (	Y3 >> 24 ) ] ^	\
+				 FT1[ (uint8) (	Y0 >> 16 ) ] ^	\
+				 FT2[ (uint8) (	Y1 >>  8 ) ] ^	\
+				 FT3[ (uint8) (	Y2		 ) ];	\
+}
+
+	AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 1 */
+	AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 2 */
+	AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 3 */
+	AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 4 */
+	AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 5 */
+	AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 6 */
+	AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 7 */
+	AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 8 */
+	AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 9 */
+
+	if (ctx->nr > 10) {
+		AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 10     */
+		AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 11     */
+	}
+
+	if (ctx->nr > 12) {
+		AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 12     */
+		AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 13     */
+	}
+
+	/* last round */
+
+	RK += 4;
+
+	X0 = RK[0] ^ (FSb[(uint8) (Y0 >> 24)] << 24) ^
+	    (FSb[(uint8) (Y1 >> 16)] << 16) ^
+	    (FSb[(uint8) (Y2 >> 8)] << 8) ^ (FSb[(uint8) (Y3)]);
+
+	X1 = RK[1] ^ (FSb[(uint8) (Y1 >> 24)] << 24) ^
+	    (FSb[(uint8) (Y2 >> 16)] << 16) ^
+	    (FSb[(uint8) (Y3 >> 8)] << 8) ^ (FSb[(uint8) (Y0)]);
+
+	X2 = RK[2] ^ (FSb[(uint8) (Y2 >> 24)] << 24) ^
+	    (FSb[(uint8) (Y3 >> 16)] << 16) ^
+	    (FSb[(uint8) (Y0 >> 8)] << 8) ^ (FSb[(uint8) (Y1)]);
+
+	X3 = RK[3] ^ (FSb[(uint8) (Y3 >> 24)] << 24) ^
+	    (FSb[(uint8) (Y0 >> 16)] << 16) ^
+	    (FSb[(uint8) (Y1 >> 8)] << 8) ^ (FSb[(uint8) (Y2)]);
+
+	PUT_UINT32(X0, output, 0);
+	PUT_UINT32(X1, output, 4);
+	PUT_UINT32(X2, output, 8);
+	PUT_UINT32(X3, output, 12);
+}
+
+/* AES 128-bit block decryption	routine	*/
+
+void rt_aes_decrypt(struct aes_context * ctx, uint8 input[16], uint8 output[16])
+{
+	uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
+
+	RK = (uint32 *) ctx->drk;
+
+	GET_UINT32(X0, input, 0);
+	X0 ^= RK[0];
+	GET_UINT32(X1, input, 4);
+	X1 ^= RK[1];
+	GET_UINT32(X2, input, 8);
+	X2 ^= RK[2];
+	GET_UINT32(X3, input, 12);
+	X3 ^= RK[3];
+
+#define	AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)		\
+{												\
+	RK += 4;									\
+												\
+	X0 = RK[0] ^ RT0[ (uint8) (	Y0 >> 24 ) ] ^	\
+				 RT1[ (uint8) (	Y3 >> 16 ) ] ^	\
+				 RT2[ (uint8) (	Y2 >>  8 ) ] ^	\
+				 RT3[ (uint8) (	Y1		 ) ];	\
+												\
+	X1 = RK[1] ^ RT0[ (uint8) (	Y1 >> 24 ) ] ^	\
+				 RT1[ (uint8) (	Y0 >> 16 ) ] ^	\
+				 RT2[ (uint8) (	Y3 >>  8 ) ] ^	\
+				 RT3[ (uint8) (	Y2		 ) ];	\
+												\
+	X2 = RK[2] ^ RT0[ (uint8) (	Y2 >> 24 ) ] ^	\
+				 RT1[ (uint8) (	Y1 >> 16 ) ] ^	\
+				 RT2[ (uint8) (	Y0 >>  8 ) ] ^	\
+				 RT3[ (uint8) (	Y3		 ) ];	\
+												\
+	X3 = RK[3] ^ RT0[ (uint8) (	Y3 >> 24 ) ] ^	\
+				 RT1[ (uint8) (	Y2 >> 16 ) ] ^	\
+				 RT2[ (uint8) (	Y1 >>  8 ) ] ^	\
+				 RT3[ (uint8) (	Y0		 ) ];	\
+}
+
+	AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 1 */
+	AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 2 */
+	AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 3 */
+	AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 4 */
+	AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 5 */
+	AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 6 */
+	AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 7 */
+	AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 8 */
+	AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 9 */
+
+	if (ctx->nr > 10) {
+		AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 10     */
+		AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 11     */
+	}
+
+	if (ctx->nr > 12) {
+		AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 12     */
+		AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 13     */
+	}
+
+	/* last round */
+
+	RK += 4;
+
+	X0 = RK[0] ^ (RSb[(uint8) (Y0 >> 24)] << 24) ^
+	    (RSb[(uint8) (Y3 >> 16)] << 16) ^
+	    (RSb[(uint8) (Y2 >> 8)] << 8) ^ (RSb[(uint8) (Y1)]);
+
+	X1 = RK[1] ^ (RSb[(uint8) (Y1 >> 24)] << 24) ^
+	    (RSb[(uint8) (Y0 >> 16)] << 16) ^
+	    (RSb[(uint8) (Y3 >> 8)] << 8) ^ (RSb[(uint8) (Y2)]);
+
+	X2 = RK[2] ^ (RSb[(uint8) (Y2 >> 24)] << 24) ^
+	    (RSb[(uint8) (Y1 >> 16)] << 16) ^
+	    (RSb[(uint8) (Y0 >> 8)] << 8) ^ (RSb[(uint8) (Y3)]);
+
+	X3 = RK[3] ^ (RSb[(uint8) (Y3 >> 24)] << 24) ^
+	    (RSb[(uint8) (Y2 >> 16)] << 16) ^
+	    (RSb[(uint8) (Y1 >> 8)] << 8) ^ (RSb[(uint8) (Y0)]);
+
+	PUT_UINT32(X0, output, 0);
+	PUT_UINT32(X1, output, 4);
+	PUT_UINT32(X2, output, 8);
+	PUT_UINT32(X3, output, 12);
+}
+
+/*
+    ==========================================================================
+    Description:
+        ENCRYPT AES GTK before sending in EAPOL frame.
+        AES GTK length = 128 bit,  so fix blocks for aes-key-wrap as 2 in this function.
+        This function references to RFC 3394 for aes key wrap algorithm.
+    Return:
+    ==========================================================================
+*/
+void AES_GTK_KEY_WRAP(u8 * key,
+		      u8 * plaintext,
+		      u32 p_len, u8 * ciphertext)
+{
+	u8 A[8], BIN[16], BOUT[16];
+	u8 R[512];
+	int num_blocks = p_len / 8;	/* unit:64bits */
+	int i, j;
+	struct aes_context aesctx;
+	u8 xor;
+
+	rt_aes_set_key(&aesctx, key, 128);
+
+	/* Init IA */
+	for (i = 0; i < 8; i++)
+		A[i] = 0xa6;
+
+	/*Input plaintext */
+	for (i = 0; i < num_blocks; i++) {
+		for (j = 0; j < 8; j++)
+			R[8 * (i + 1) + j] = plaintext[8 * i + j];
+	}
+
+	/* Key Mix */
+	for (j = 0; j < 6; j++) {
+		for (i = 1; i <= num_blocks; i++) {
+			/*phase 1 */
+			NdisMoveMemory(BIN, A, 8);
+			NdisMoveMemory(&BIN[8], &R[8 * i], 8);
+			rt_aes_encrypt(&aesctx, BIN, BOUT);
+
+			NdisMoveMemory(A, &BOUT[0], 8);
+			xor = num_blocks * j + i;
+			A[7] = BOUT[7] ^ xor;
+			NdisMoveMemory(&R[8 * i], &BOUT[8], 8);
+		}
+	}
+
+	/* Output ciphertext */
+	NdisMoveMemory(ciphertext, A, 8);
+
+	for (i = 1; i <= num_blocks; i++) {
+		for (j = 0; j < 8; j++)
+			ciphertext[8 * i + j] = R[8 * i + j];
+	}
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Misc function to decrypt AES body
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+		This function references to	RFC	3394 for aes key unwrap algorithm.
+
+	========================================================================
+*/
+void AES_GTK_KEY_UNWRAP(u8 * key,
+			u8 * plaintext,
+			u32 c_len, u8 * ciphertext)
+{
+	u8 A[8], BIN[16], BOUT[16];
+	u8 xor;
+	int i, j;
+	struct aes_context aesctx;
+	u8 *R;
+	int num_blocks = c_len / 8;	/* unit:64bits */
+
+	os_alloc_mem(NULL, (u8 **) & R, 512);
+
+	if (R == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("AES_GTK_KEY_UNWRAP: no memory!\n"));
+		return;
+	}
+	/* End of if */
+	/* Initialize */
+	NdisMoveMemory(A, ciphertext, 8);
+	/*Input plaintext */
+	for (i = 0; i < (c_len - 8); i++) {
+		R[i] = ciphertext[i + 8];
+	}
+
+	rt_aes_set_key(&aesctx, key, 128);
+
+	for (j = 5; j >= 0; j--) {
+		for (i = (num_blocks - 1); i > 0; i--) {
+			xor = (num_blocks - 1) * j + i;
+			NdisMoveMemory(BIN, A, 8);
+			BIN[7] = A[7] ^ xor;
+			NdisMoveMemory(&BIN[8], &R[(i - 1) * 8], 8);
+			rt_aes_decrypt(&aesctx, BIN, BOUT);
+			NdisMoveMemory(A, &BOUT[0], 8);
+			NdisMoveMemory(&R[(i - 1) * 8], &BOUT[8], 8);
+		}
+	}
+
+	/* OUTPUT */
+	for (i = 0; i < c_len; i++) {
+		plaintext[i] = R[i];
+	}
+
+	os_free_mem(NULL, R);
+}
diff --git a/drivers/staging/rt2860/common/cmm_asic.c b/drivers/staging/rt2860/common/cmm_asic.c
new file mode 100644
index 0000000..4d77e83
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_asic.c
@@ -0,0 +1,2565 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	cmm_asic.c
+
+	Abstract:
+	Functions used to communicate with ASIC
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+*/
+
+#include "../rt_config.h"
+
+/* Reset the RFIC setting to new series */
+struct rt_rtmp_rf_regs RF2850RegTable[] = {
+/*              ch       R1              R2              R3(TX0~4=0) R4 */
+	{1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b}
+	,
+	{2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f}
+	,
+	{3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b}
+	,
+	{4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f}
+	,
+	{5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b}
+	,
+	{6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f}
+	,
+	{7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b}
+	,
+	{8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f}
+	,
+	{9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b}
+	,
+	{10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f}
+	,
+	{11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b}
+	,
+	{12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f}
+	,
+	{13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b}
+	,
+	{14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193}
+	,
+
+	/* 802.11 UNI / HyperLan 2 */
+	{36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3}
+	,
+	{38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193}
+	,
+	{40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183}
+	,
+	{44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3}
+	,
+	{46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b}
+	,
+	{48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b}
+	,
+	{52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193}
+	,
+	{54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3}
+	,
+	{56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b}
+	,
+	{60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183}
+	,
+	{62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193}
+	,
+	{64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}
+	,			/* Plugfest#4, Day4, change RFR3 left4th 9->5. */
+
+	/* 802.11 HyperLan 2 */
+	{100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783}
+	,
+
+	/* 2008.04.30 modified */
+	/* The system team has AN to improve the EVM value */
+	/* for channel 102 to 108 for the RT2850/RT2750 dual band solution. */
+	{102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793}
+	,
+	{104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3}
+	,
+	{108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193}
+	,
+
+	{110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183}
+	,
+	{112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b}
+	,
+	{116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3}
+	,
+	{118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193}
+	,
+	{120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183}
+	,
+	{124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193}
+	,
+	{126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}
+	,			/* 0x980ed1bb->0x980ed15b required by Rory 20070927 */
+	{128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3}
+	,
+	{132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b}
+	,
+	{134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193}
+	,
+	{136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b}
+	,
+	{140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183}
+	,
+
+	/* 802.11 UNII */
+	{149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7}
+	,
+	{151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187}
+	,
+	{153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f}
+	,
+	{157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f}
+	,
+	{159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7}
+	,
+	{161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187}
+	,
+	{165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197}
+	,
+	{167, 0x98402ec4, 0x984c03d2, 0x98179855, 0x9815531f}
+	,
+	{169, 0x98402ec4, 0x984c03d2, 0x98179855, 0x98155327}
+	,
+	{171, 0x98402ec4, 0x984c03d6, 0x98179855, 0x98155307}
+	,
+	{173, 0x98402ec4, 0x984c03d6, 0x98179855, 0x9815530f}
+	,
+
+	/* Japan */
+	{184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b}
+	,
+	{188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13}
+	,
+	{192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b}
+	,
+	{196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23}
+	,
+	{208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13}
+	,
+	{212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b}
+	,
+	{216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23}
+	,
+
+	/* still lack of MMAC(Japan) ch 34,38,42,46 */
+};
+
+u8 NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(struct rt_rtmp_rf_regs));
+
+struct rt_frequency_item FreqItems3020[] = {
+	/**************************************************/
+	/* ISM : 2.4 to 2.483 GHz                         // */
+	/**************************************************/
+	/* 11g */
+	/**************************************************/
+	/*-CH---N-------R---K----------- */
+	{1, 241, 2, 2}
+	,
+	{2, 241, 2, 7}
+	,
+	{3, 242, 2, 2}
+	,
+	{4, 242, 2, 7}
+	,
+	{5, 243, 2, 2}
+	,
+	{6, 243, 2, 7}
+	,
+	{7, 244, 2, 2}
+	,
+	{8, 244, 2, 7}
+	,
+	{9, 245, 2, 2}
+	,
+	{10, 245, 2, 7}
+	,
+	{11, 246, 2, 2}
+	,
+	{12, 246, 2, 7}
+	,
+	{13, 247, 2, 2}
+	,
+	{14, 248, 2, 4}
+	,
+};
+
+u8 NUM_OF_3020_CHNL = (sizeof(FreqItems3020) / sizeof(struct rt_frequency_item));
+
+void AsicUpdateAutoFallBackTable(struct rt_rtmp_adapter *pAd, u8 *pRateTable)
+{
+	u8 i;
+	HT_FBK_CFG0_STRUC HtCfg0;
+	HT_FBK_CFG1_STRUC HtCfg1;
+	LG_FBK_CFG0_STRUC LgCfg0;
+	LG_FBK_CFG1_STRUC LgCfg1;
+	struct rt_rtmp_tx_rate_switch *pCurrTxRate, *pNextTxRate;
+
+	/* set to initial value */
+	HtCfg0.word = 0x65432100;
+	HtCfg1.word = 0xedcba988;
+	LgCfg0.word = 0xedcba988;
+	LgCfg1.word = 0x00002100;
+
+	pNextTxRate = (struct rt_rtmp_tx_rate_switch *) pRateTable + 1;
+	for (i = 1; i < *((u8 *)pRateTable); i++) {
+		pCurrTxRate = (struct rt_rtmp_tx_rate_switch *) pRateTable + 1 + i;
+		switch (pCurrTxRate->Mode) {
+		case 0:	/*CCK */
+			break;
+		case 1:	/*OFDM */
+			{
+				switch (pCurrTxRate->CurrMCS) {
+				case 0:
+					LgCfg0.field.OFDMMCS0FBK =
+					    (pNextTxRate->Mode ==
+					     MODE_OFDM) ? (pNextTxRate->
+							   CurrMCS +
+							   8) : pNextTxRate->
+					    CurrMCS;
+					break;
+				case 1:
+					LgCfg0.field.OFDMMCS1FBK =
+					    (pNextTxRate->Mode ==
+					     MODE_OFDM) ? (pNextTxRate->
+							   CurrMCS +
+							   8) : pNextTxRate->
+					    CurrMCS;
+					break;
+				case 2:
+					LgCfg0.field.OFDMMCS2FBK =
+					    (pNextTxRate->Mode ==
+					     MODE_OFDM) ? (pNextTxRate->
+							   CurrMCS +
+							   8) : pNextTxRate->
+					    CurrMCS;
+					break;
+				case 3:
+					LgCfg0.field.OFDMMCS3FBK =
+					    (pNextTxRate->Mode ==
+					     MODE_OFDM) ? (pNextTxRate->
+							   CurrMCS +
+							   8) : pNextTxRate->
+					    CurrMCS;
+					break;
+				case 4:
+					LgCfg0.field.OFDMMCS4FBK =
+					    (pNextTxRate->Mode ==
+					     MODE_OFDM) ? (pNextTxRate->
+							   CurrMCS +
+							   8) : pNextTxRate->
+					    CurrMCS;
+					break;
+				case 5:
+					LgCfg0.field.OFDMMCS5FBK =
+					    (pNextTxRate->Mode ==
+					     MODE_OFDM) ? (pNextTxRate->
+							   CurrMCS +
+							   8) : pNextTxRate->
+					    CurrMCS;
+					break;
+				case 6:
+					LgCfg0.field.OFDMMCS6FBK =
+					    (pNextTxRate->Mode ==
+					     MODE_OFDM) ? (pNextTxRate->
+							   CurrMCS +
+							   8) : pNextTxRate->
+					    CurrMCS;
+					break;
+				case 7:
+					LgCfg0.field.OFDMMCS7FBK =
+					    (pNextTxRate->Mode ==
+					     MODE_OFDM) ? (pNextTxRate->
+							   CurrMCS +
+							   8) : pNextTxRate->
+					    CurrMCS;
+					break;
+				}
+			}
+			break;
+		case 2:	/*HT-MIX */
+		case 3:	/*HT-GF */
+			{
+				if ((pNextTxRate->Mode >= MODE_HTMIX)
+				    && (pCurrTxRate->CurrMCS !=
+					pNextTxRate->CurrMCS)) {
+					switch (pCurrTxRate->CurrMCS) {
+					case 0:
+						HtCfg0.field.HTMCS0FBK =
+						    pNextTxRate->CurrMCS;
+						break;
+					case 1:
+						HtCfg0.field.HTMCS1FBK =
+						    pNextTxRate->CurrMCS;
+						break;
+					case 2:
+						HtCfg0.field.HTMCS2FBK =
+						    pNextTxRate->CurrMCS;
+						break;
+					case 3:
+						HtCfg0.field.HTMCS3FBK =
+						    pNextTxRate->CurrMCS;
+						break;
+					case 4:
+						HtCfg0.field.HTMCS4FBK =
+						    pNextTxRate->CurrMCS;
+						break;
+					case 5:
+						HtCfg0.field.HTMCS5FBK =
+						    pNextTxRate->CurrMCS;
+						break;
+					case 6:
+						HtCfg0.field.HTMCS6FBK =
+						    pNextTxRate->CurrMCS;
+						break;
+					case 7:
+						HtCfg0.field.HTMCS7FBK =
+						    pNextTxRate->CurrMCS;
+						break;
+					case 8:
+						HtCfg1.field.HTMCS8FBK =
+						    pNextTxRate->CurrMCS;
+						break;
+					case 9:
+						HtCfg1.field.HTMCS9FBK =
+						    pNextTxRate->CurrMCS;
+						break;
+					case 10:
+						HtCfg1.field.HTMCS10FBK =
+						    pNextTxRate->CurrMCS;
+						break;
+					case 11:
+						HtCfg1.field.HTMCS11FBK =
+						    pNextTxRate->CurrMCS;
+						break;
+					case 12:
+						HtCfg1.field.HTMCS12FBK =
+						    pNextTxRate->CurrMCS;
+						break;
+					case 13:
+						HtCfg1.field.HTMCS13FBK =
+						    pNextTxRate->CurrMCS;
+						break;
+					case 14:
+						HtCfg1.field.HTMCS14FBK =
+						    pNextTxRate->CurrMCS;
+						break;
+					case 15:
+						HtCfg1.field.HTMCS15FBK =
+						    pNextTxRate->CurrMCS;
+						break;
+					default:
+						DBGPRINT(RT_DEBUG_ERROR,
+							 ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n",
+							  pCurrTxRate->
+							  CurrMCS));
+					}
+				}
+			}
+			break;
+		}
+
+		pNextTxRate = pCurrTxRate;
+	}
+
+	RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word);
+	RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word);
+	RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word);
+	RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word);
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Set MAC register value according operation mode.
+		OperationMode AND bNonGFExist are for MM and GF Proteciton.
+		If MM or GF mask is not set, those passing argument doesn't not take effect.
+
+		Operation mode meaning:
+		= 0 : Pure HT, no preotection.
+		= 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
+		= 0x10: No Transmission in 40M is protected.
+		= 0x11: Transmission in both 40M and 20M shall be protected
+		if (bNonGFExist)
+			we should choose not to use GF. But still set correct ASIC registers.
+	========================================================================
+*/
+void AsicUpdateProtect(struct rt_rtmp_adapter *pAd,
+		       u16 OperationMode,
+		       u8 SetMask,
+		       IN BOOLEAN bDisableBGProtect, IN BOOLEAN bNonGFExist)
+{
+	PROT_CFG_STRUC ProtCfg, ProtCfg4;
+	u32 Protect[6];
+	u16 offset;
+	u8 i;
+	u32 MacReg = 0;
+
+	if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8)) {
+		return;
+	}
+
+	if (pAd->BATable.numDoneOriginator) {
+		/* */
+		/* enable the RTS/CTS to avoid channel collision */
+		/* */
+		SetMask = ALLN_SETPROTECT;
+		OperationMode = 8;
+	}
+	/* Config ASIC RTS threshold register */
+	RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
+	MacReg &= 0xFF0000FF;
+	/* If the user want disable RtsThreshold and enable Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096 */
+	if (((pAd->CommonCfg.BACapability.field.AmsduEnable) ||
+	     (pAd->CommonCfg.bAggregationCapable == TRUE))
+	    && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD) {
+		MacReg |= (0x1000 << 8);
+	} else {
+		MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
+	}
+
+	RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
+
+	/* Initial common protection settings */
+	RTMPZeroMemory(Protect, sizeof(Protect));
+	ProtCfg4.word = 0;
+	ProtCfg.word = 0;
+	ProtCfg.field.TxopAllowGF40 = 1;
+	ProtCfg.field.TxopAllowGF20 = 1;
+	ProtCfg.field.TxopAllowMM40 = 1;
+	ProtCfg.field.TxopAllowMM20 = 1;
+	ProtCfg.field.TxopAllowOfdm = 1;
+	ProtCfg.field.TxopAllowCck = 1;
+	ProtCfg.field.RTSThEn = 1;
+	ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+
+	/* update PHY mode and rate */
+	if (pAd->CommonCfg.Channel > 14)
+		ProtCfg.field.ProtectRate = 0x4000;
+	ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate;
+
+	/* Handle legacy(B/G) protection */
+	if (bDisableBGProtect) {
+		/*ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate; */
+		ProtCfg.field.ProtectCtrl = 0;
+		Protect[0] = ProtCfg.word;
+		Protect[1] = ProtCfg.word;
+		pAd->FlgCtsEnabled = 0;	/* CTS-self is not used */
+	} else {
+		/*ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate; */
+		ProtCfg.field.ProtectCtrl = 0;	/* CCK do not need to be protected */
+		Protect[0] = ProtCfg.word;
+		ProtCfg.field.ProtectCtrl = ASIC_CTS;	/* OFDM needs using CCK to protect */
+		Protect[1] = ProtCfg.word;
+		pAd->FlgCtsEnabled = 1;	/* CTS-self is used */
+	}
+
+	/* Decide HT frame protection. */
+	if ((SetMask & ALLN_SETPROTECT) != 0) {
+		switch (OperationMode) {
+		case 0x0:
+			/* NO PROTECT */
+			/* 1.All STAs in the BSS are 20/40 MHz HT */
+			/* 2. in ai 20/40MHz BSS */
+			/* 3. all STAs are 20MHz in a 20MHz BSS */
+			/* Pure HT. no protection. */
+
+			/* MM20_PROT_CFG */
+			/*      Reserved (31:27) */
+			/*      PROT_TXOP(25:20) -- 010111 */
+			/*      PROT_NAV(19:18)  -- 01 (Short NAV protection) */
+			/*  PROT_CTRL(17:16) -- 00 (None) */
+			/*      PROT_RATE(15:0)  -- 0x4004 (OFDM 24M) */
+			Protect[2] = 0x01744004;
+
+			/* MM40_PROT_CFG */
+			/*      Reserved (31:27) */
+			/*      PROT_TXOP(25:20) -- 111111 */
+			/*      PROT_NAV(19:18)  -- 01 (Short NAV protection) */
+			/*  PROT_CTRL(17:16) -- 00 (None) */
+			/*      PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M) */
+			Protect[3] = 0x03f44084;
+
+			/* CF20_PROT_CFG */
+			/*      Reserved (31:27) */
+			/*      PROT_TXOP(25:20) -- 010111 */
+			/*      PROT_NAV(19:18)  -- 01 (Short NAV protection) */
+			/*  PROT_CTRL(17:16) -- 00 (None) */
+			/*      PROT_RATE(15:0)  -- 0x4004 (OFDM 24M) */
+			Protect[4] = 0x01744004;
+
+			/* CF40_PROT_CFG */
+			/*      Reserved (31:27) */
+			/*      PROT_TXOP(25:20) -- 111111 */
+			/*      PROT_NAV(19:18)  -- 01 (Short NAV protection) */
+			/*  PROT_CTRL(17:16) -- 00 (None) */
+			/*      PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M) */
+			Protect[5] = 0x03f44084;
+
+			if (bNonGFExist) {
+				/* PROT_NAV(19:18)  -- 01 (Short NAV protectiion) */
+				/* PROT_CTRL(17:16) -- 01 (RTS/CTS) */
+				Protect[4] = 0x01754004;
+				Protect[5] = 0x03f54084;
+			}
+			pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
+			break;
+
+		case 1:
+			/* This is "HT non-member protection mode." */
+			/* If there may be non-HT STAs my BSS */
+			ProtCfg.word = 0x01744004;	/* PROT_CTRL(17:16) : 0 (None) */
+			ProtCfg4.word = 0x03f44084;	/* duplicaet legacy 24M. BW set 1. */
+			if (OPSTATUS_TEST_FLAG
+			    (pAd, fOP_STATUS_BG_PROTECTION_INUSED)) {
+				ProtCfg.word = 0x01740003;	/*ERP use Protection bit is set, use protection rate at Clause 18.. */
+				ProtCfg4.word = 0x03f40003;	/* Don't duplicate RTS/CTS in CCK mode. 0x03f40083; */
+			}
+			/*Assign Protection method for 20&40 MHz packets */
+			ProtCfg.field.ProtectCtrl = ASIC_RTS;
+			ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+			ProtCfg4.field.ProtectCtrl = ASIC_RTS;
+			ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
+			Protect[2] = ProtCfg.word;
+			Protect[3] = ProtCfg4.word;
+			Protect[4] = ProtCfg.word;
+			Protect[5] = ProtCfg4.word;
+			pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
+			break;
+
+		case 2:
+			/* If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets */
+			ProtCfg.word = 0x01744004;	/* PROT_CTRL(17:16) : 0 (None) */
+			ProtCfg4.word = 0x03f44084;	/* duplicaet legacy 24M. BW set 1. */
+
+			/*Assign Protection method for 40MHz packets */
+			ProtCfg4.field.ProtectCtrl = ASIC_RTS;
+			ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
+			Protect[2] = ProtCfg.word;
+			Protect[3] = ProtCfg4.word;
+			if (bNonGFExist) {
+				ProtCfg.field.ProtectCtrl = ASIC_RTS;
+				ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+			}
+			Protect[4] = ProtCfg.word;
+			Protect[5] = ProtCfg4.word;
+
+			pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
+			break;
+
+		case 3:
+			/* HT mixed mode.        PROTECT ALL! */
+			/* Assign Rate */
+			ProtCfg.word = 0x01744004;	/*duplicaet legacy 24M. BW set 1. */
+			ProtCfg4.word = 0x03f44084;
+			/* both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the */
+			if (OPSTATUS_TEST_FLAG
+			    (pAd, fOP_STATUS_BG_PROTECTION_INUSED)) {
+				ProtCfg.word = 0x01740003;	/*ERP use Protection bit is set, use protection rate at Clause 18.. */
+				ProtCfg4.word = 0x03f40003;	/* Don't duplicate RTS/CTS in CCK mode. 0x03f40083 */
+			}
+			/*Assign Protection method for 20&40 MHz packets */
+			ProtCfg.field.ProtectCtrl = ASIC_RTS;
+			ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+			ProtCfg4.field.ProtectCtrl = ASIC_RTS;
+			ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
+			Protect[2] = ProtCfg.word;
+			Protect[3] = ProtCfg4.word;
+			Protect[4] = ProtCfg.word;
+			Protect[5] = ProtCfg4.word;
+			pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
+			break;
+
+		case 8:
+			/* Special on for Atheros problem n chip. */
+			Protect[2] = 0x01754004;
+			Protect[3] = 0x03f54084;
+			Protect[4] = 0x01754004;
+			Protect[5] = 0x03f54084;
+			pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
+			break;
+		}
+	}
+
+	offset = CCK_PROT_CFG;
+	for (i = 0; i < 6; i++) {
+		if ((SetMask & (1 << i))) {
+			RTMP_IO_WRITE32(pAd, offset + i * 4, Protect[i]);
+		}
+	}
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+void AsicSwitchChannel(struct rt_rtmp_adapter *pAd, u8 Channel, IN BOOLEAN bScan)
+{
+	unsigned long R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0;
+	char TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER;	/*Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER; */
+	u8 index;
+	u32 Value = 0;	/*BbpReg, Value; */
+	struct rt_rtmp_rf_regs *RFRegTable;
+	u8 RFValue;
+
+	RFValue = 0;
+	/* Search Tx power value */
+	/* We can't use ChannelList to search channel, since some central channl's txpowr doesn't list */
+	/* in ChannelList, so use TxPower array instead. */
+	/* */
+	for (index = 0; index < MAX_NUM_OF_CHANNELS; index++) {
+		if (Channel == pAd->TxPower[index].Channel) {
+			TxPwer = pAd->TxPower[index].Power;
+			TxPwer2 = pAd->TxPower[index].Power2;
+			break;
+		}
+	}
+
+	if (index == MAX_NUM_OF_CHANNELS) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("AsicSwitchChannel: Can't find the Channel#%d \n",
+			  Channel));
+	}
+#ifdef RT30xx
+	/* The RF programming sequence is difference between 3xxx and 2xxx */
+	if ((IS_RT3070(pAd) || IS_RT3090(pAd) || IS_RT3390(pAd))
+	    && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020)
+		|| (pAd->RfIcType == RFIC_3021)
+		|| (pAd->RfIcType == RFIC_3022))) {
+		/* modify by WY for Read RF Reg. error */
+
+		for (index = 0; index < NUM_OF_3020_CHNL; index++) {
+			if (Channel == FreqItems3020[index].Channel) {
+				/* Programming channel parameters */
+				RT30xxWriteRFRegister(pAd, RF_R02,
+						      FreqItems3020[index].N);
+				RT30xxWriteRFRegister(pAd, RF_R03,
+						      FreqItems3020[index].K);
+				RT30xxReadRFRegister(pAd, RF_R06, &RFValue);
+				RFValue =
+				    (RFValue & 0xFC) | FreqItems3020[index].R;
+				RT30xxWriteRFRegister(pAd, RF_R06, RFValue);
+
+				/* Set Tx0 Power */
+				RT30xxReadRFRegister(pAd, RF_R12, &RFValue);
+				RFValue = (RFValue & 0xE0) | TxPwer;
+				RT30xxWriteRFRegister(pAd, RF_R12, RFValue);
+
+				/* Set Tx1 Power */
+				RT30xxReadRFRegister(pAd, RF_R13, &RFValue);
+				RFValue = (RFValue & 0xE0) | TxPwer2;
+				RT30xxWriteRFRegister(pAd, RF_R13, RFValue);
+
+				/* Tx/Rx Stream setting */
+				RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
+				/*if (IS_RT3090(pAd)) */
+				/*      RFValue |= 0x01; // Enable RF block. */
+				RFValue &= 0x03;	/*clear bit[7~2] */
+				if (pAd->Antenna.field.TxPath == 1)
+					RFValue |= 0xA0;
+				else if (pAd->Antenna.field.TxPath == 2)
+					RFValue |= 0x80;
+				if (pAd->Antenna.field.RxPath == 1)
+					RFValue |= 0x50;
+				else if (pAd->Antenna.field.RxPath == 2)
+					RFValue |= 0x40;
+				RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
+
+				/* Set RF offset */
+				RT30xxReadRFRegister(pAd, RF_R23, &RFValue);
+				RFValue = (RFValue & 0x80) | pAd->RfFreqOffset;
+				RT30xxWriteRFRegister(pAd, RF_R23, RFValue);
+
+				/* Set BW */
+				if (!bScan
+				    && (pAd->CommonCfg.BBPCurrentBW == BW_40)) {
+					RFValue = pAd->Mlme.CaliBW40RfR24;
+					/*DISABLE_11N_CHECK(pAd); */
+				} else {
+					RFValue = pAd->Mlme.CaliBW20RfR24;
+				}
+				RT30xxWriteRFRegister(pAd, RF_R24, RFValue);
+				RT30xxWriteRFRegister(pAd, RF_R31, RFValue);
+
+				/* Enable RF tuning */
+				RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
+				RFValue = RFValue | 0x1;
+				RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
+
+				/* latch channel for future usage. */
+				pAd->LatchRfRegs.Channel = Channel;
+
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
+					  Channel, pAd->RfIcType, TxPwer,
+					  TxPwer2, pAd->Antenna.field.TxPath,
+					  FreqItems3020[index].N,
+					  FreqItems3020[index].K,
+					  FreqItems3020[index].R));
+
+				break;
+			}
+		}
+	} else
+#endif /* RT30xx // */
+	{
+		RFRegTable = RF2850RegTable;
+		switch (pAd->RfIcType) {
+		case RFIC_2820:
+		case RFIC_2850:
+		case RFIC_2720:
+		case RFIC_2750:
+
+			for (index = 0; index < NUM_OF_2850_CHNL; index++) {
+				if (Channel == RFRegTable[index].Channel) {
+					R2 = RFRegTable[index].R2;
+					if (pAd->Antenna.field.TxPath == 1) {
+						R2 |= 0x4000;	/* If TXpath is 1, bit 14 = 1; */
+					}
+
+					if (pAd->Antenna.field.RxPath == 2) {
+						R2 |= 0x40;	/* write 1 to off Rxpath. */
+					} else if (pAd->Antenna.field.RxPath ==
+						   1) {
+						R2 |= 0x20040;	/* write 1 to off RxPath */
+					}
+
+					if (Channel > 14) {
+						/* initialize R3, R4 */
+						R3 = (RFRegTable[index].
+						      R3 & 0xffffc1ff);
+						R4 = (RFRegTable[index].
+						      R4 & (~0x001f87c0)) |
+						    (pAd->RfFreqOffset << 15);
+
+						/* 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB */
+						/* R3 */
+						if ((TxPwer >= -7)
+						    && (TxPwer < 0)) {
+							TxPwer = (7 + TxPwer);
+							TxPwer =
+							    (TxPwer >
+							     0xF) ? (0xF)
+							    : (TxPwer);
+							R3 |= (TxPwer << 10);
+							DBGPRINT(RT_DEBUG_ERROR,
+								 ("AsicSwitchChannel: TxPwer=%d \n",
+								  TxPwer));
+						} else {
+							TxPwer =
+							    (TxPwer >
+							     0xF) ? (0xF)
+							    : (TxPwer);
+							R3 |=
+							    (TxPwer << 10) | (1
+									      <<
+									      9);
+						}
+
+						/* R4 */
+						if ((TxPwer2 >= -7)
+						    && (TxPwer2 < 0)) {
+							TxPwer2 = (7 + TxPwer2);
+							TxPwer2 =
+							    (TxPwer2 >
+							     0xF) ? (0xF)
+							    : (TxPwer2);
+							R4 |= (TxPwer2 << 7);
+							DBGPRINT(RT_DEBUG_ERROR,
+								 ("AsicSwitchChannel: TxPwer2=%d \n",
+								  TxPwer2));
+						} else {
+							TxPwer2 =
+							    (TxPwer2 >
+							     0xF) ? (0xF)
+							    : (TxPwer2);
+							R4 |=
+							    (TxPwer2 << 7) | (1
+									      <<
+									      6);
+						}
+					} else {
+						R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9);	/* set TX power0 */
+						R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 << 6);	/* Set freq Offset & TxPwr1 */
+					}
+
+					/* Based on BBP current mode before changing RF channel. */
+					if (!bScan
+					    && (pAd->CommonCfg.BBPCurrentBW ==
+						BW_40)) {
+						R4 |= 0x200000;
+					}
+					/* Update variables */
+					pAd->LatchRfRegs.Channel = Channel;
+					pAd->LatchRfRegs.R1 =
+					    RFRegTable[index].R1;
+					pAd->LatchRfRegs.R2 = R2;
+					pAd->LatchRfRegs.R3 = R3;
+					pAd->LatchRfRegs.R4 = R4;
+
+					/* Set RF value 1's set R3[bit2] = [0] */
+					RTMP_RF_IO_WRITE32(pAd,
+							   pAd->LatchRfRegs.R1);
+					RTMP_RF_IO_WRITE32(pAd,
+							   pAd->LatchRfRegs.R2);
+					RTMP_RF_IO_WRITE32(pAd,
+							   (pAd->LatchRfRegs.
+							    R3 & (~0x04)));
+					RTMP_RF_IO_WRITE32(pAd,
+							   pAd->LatchRfRegs.R4);
+
+					RTMPusecDelay(200);
+
+					/* Set RF value 2's set R3[bit2] = [1] */
+					RTMP_RF_IO_WRITE32(pAd,
+							   pAd->LatchRfRegs.R1);
+					RTMP_RF_IO_WRITE32(pAd,
+							   pAd->LatchRfRegs.R2);
+					RTMP_RF_IO_WRITE32(pAd,
+							   (pAd->LatchRfRegs.
+							    R3 | 0x04));
+					RTMP_RF_IO_WRITE32(pAd,
+							   pAd->LatchRfRegs.R4);
+
+					RTMPusecDelay(200);
+
+					/* Set RF value 3's set R3[bit2] = [0] */
+					RTMP_RF_IO_WRITE32(pAd,
+							   pAd->LatchRfRegs.R1);
+					RTMP_RF_IO_WRITE32(pAd,
+							   pAd->LatchRfRegs.R2);
+					RTMP_RF_IO_WRITE32(pAd,
+							   (pAd->LatchRfRegs.
+							    R3 & (~0x04)));
+					RTMP_RF_IO_WRITE32(pAd,
+							   pAd->LatchRfRegs.R4);
+
+					break;
+				}
+			}
+			break;
+
+		default:
+			break;
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("SwitchChannel#%d(RF=%d, Pwr0=%lu, Pwr1=%lu, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
+			  Channel, pAd->RfIcType, (R3 & 0x00003e00) >> 9,
+			  (R4 & 0x000007c0) >> 6, pAd->Antenna.field.TxPath,
+			  pAd->LatchRfRegs.R1, pAd->LatchRfRegs.R2,
+			  pAd->LatchRfRegs.R3, pAd->LatchRfRegs.R4));
+	}
+
+	/* Change BBP setting during siwtch from a->g, g->a */
+	if (Channel <= 14) {
+		unsigned long TxPinCfg = 0x00050F0A;	/*Gary 2007/08/09 0x050A0A */
+
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62,
+					     (0x37 - GET_LNA_GAIN(pAd)));
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63,
+					     (0x37 - GET_LNA_GAIN(pAd)));
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64,
+					     (0x37 - GET_LNA_GAIN(pAd)));
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);	/*(0x44 - GET_LNA_GAIN(pAd)));    // According the Rory's suggestion to solve the middle range issue. */
+		/*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62); */
+
+		/* Rx High power VGA offset for LNA select */
+		if (pAd->NicConfig2.field.ExternalLNAForG) {
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
+		} else {
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
+		}
+
+		/* 5G band selection PIN, bit1 and bit2 are complement */
+		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
+		Value &= (~0x6);
+		Value |= (0x04);
+		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+
+		/* Turn off unused PA or LNA when only 1T or 1R */
+		if (pAd->Antenna.field.TxPath == 1) {
+			TxPinCfg &= 0xFFFFFFF3;
+		}
+		if (pAd->Antenna.field.RxPath == 1) {
+			TxPinCfg &= 0xFFFFF3FF;
+		}
+
+		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+
+#if defined(RT3090) || defined(RT3390)
+		/* PCIe PHY Transmit attenuation adjustment */
+		if (IS_RT3090A(pAd) || IS_RT3390(pAd)) {
+			TX_ATTENUATION_CTRL_STRUC TxAttenuationCtrl = {
+			.word = 0};
+
+			RTMP_IO_READ32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL,
+				       &TxAttenuationCtrl.word);
+
+			if (Channel == 14)	/* Channel #14 */
+			{
+				TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 1;	/* Enable PCIe PHY Tx attenuation */
+				TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 4;	/* 9/16 full drive level */
+			} else	/* Channel #1~#13 */
+			{
+				TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 0;	/* Disable PCIe PHY Tx attenuation */
+				TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 0;	/* n/a */
+			}
+
+			RTMP_IO_WRITE32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL,
+					TxAttenuationCtrl.word);
+		}
+#endif
+	} else {
+		unsigned long TxPinCfg = 0x00050F05;	/*Gary 2007/8/9 0x050505 */
+
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62,
+					     (0x37 - GET_LNA_GAIN(pAd)));
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63,
+					     (0x37 - GET_LNA_GAIN(pAd)));
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64,
+					     (0x37 - GET_LNA_GAIN(pAd)));
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);	/*(0x44 - GET_LNA_GAIN(pAd)));   // According the Rory's suggestion to solve the middle range issue. */
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
+
+		/* Rx High power VGA offset for LNA select */
+		if (pAd->NicConfig2.field.ExternalLNAForA) {
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
+		} else {
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
+		}
+
+		/* 5G band selection PIN, bit1 and bit2 are complement */
+		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
+		Value &= (~0x6);
+		Value |= (0x02);
+		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+
+		/* Turn off unused PA or LNA when only 1T or 1R */
+		if (pAd->Antenna.field.TxPath == 1) {
+			TxPinCfg &= 0xFFFFFFF3;
+		}
+		if (pAd->Antenna.field.RxPath == 1) {
+			TxPinCfg &= 0xFFFFF3FF;
+		}
+
+		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+
+	}
+
+	/* R66 should be set according to Channel and use 20MHz when scanning */
+	/*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd))); */
+	if (bScan)
+		RTMPSetAGCInitValue(pAd, BW_20);
+	else
+		RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
+
+	/* */
+	/* On 11A, We should delay and wait RF/BBP to be stable */
+	/* and the appropriate time should be 1000 micro seconds */
+	/* 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL. */
+	/* */
+	RTMPusecDelay(1000);
+}
+
+void AsicResetBBPAgent(struct rt_rtmp_adapter *pAd)
+{
+	BBP_CSR_CFG_STRUC BbpCsr;
+	DBGPRINT(RT_DEBUG_ERROR, ("Reset BBP Agent busy bit!\n"));
+	/* Still need to find why BBP agent keeps busy, but in fact, hardware still function ok. Now clear busy first. */
+	RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word);
+	BbpCsr.field.Busy = 0;
+	RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word);
+}
+
+/*
+	==========================================================================
+	Description:
+		This function is required for 2421 only, and should not be used during
+		site survey. It's only required after NIC decided to stay at a channel
+		for a longer period.
+		When this function is called, it's always after AsicSwitchChannel().
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+void AsicLockChannel(struct rt_rtmp_adapter *pAd, u8 Channel)
+{
+}
+
+void AsicRfTuningExec(void *SystemSpecific1,
+		      void *FunctionContext,
+		      void *SystemSpecific2, void *SystemSpecific3)
+{
+}
+
+/*
+	==========================================================================
+	Description:
+		Gives CCK TX rate 2 more dB TX power.
+		This routine works only in LINK UP in INFRASTRUCTURE mode.
+
+		calculate desired Tx power in RF R3.Tx0~5,	should consider -
+		0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
+		1. TxPowerPercentage
+		2. auto calibration based on TSSI feedback
+		3. extra 2 db for CCK
+		4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
+
+	NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
+		it should be called AFTER MlmeDynamicTxRatSwitching()
+	==========================================================================
+ */
+void AsicAdjustTxPower(struct rt_rtmp_adapter *pAd)
+{
+	int i, j;
+	char DeltaPwr = 0;
+	BOOLEAN bAutoTxAgc = FALSE;
+	u8 TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
+	u8 BbpR1 = 0, BbpR49 = 0, idx;
+	char *pTxAgcCompensate;
+	unsigned long TxPwr[5];
+	char Value;
+	char Rssi = -127;
+
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
+#ifdef RTMP_MAC_PCI
+	    (pAd->bPCIclkOff == TRUE) ||
+#endif /* RTMP_MAC_PCI // */
+	    RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF) ||
+	    RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+		return;
+
+	Rssi = RTMPMaxRssi(pAd,
+			   pAd->StaCfg.RssiSample.AvgRssi0,
+			   pAd->StaCfg.RssiSample.AvgRssi1,
+			   pAd->StaCfg.RssiSample.AvgRssi2);
+
+	if (pAd->CommonCfg.BBPCurrentBW == BW_40) {
+		if (pAd->CommonCfg.CentralChannel > 14) {
+			TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
+			TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
+			TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
+			TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
+			TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
+		} else {
+			TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
+			TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
+			TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
+			TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
+			TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
+		}
+	} else {
+		if (pAd->CommonCfg.Channel > 14) {
+			TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
+			TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
+			TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
+			TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
+			TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
+		} else {
+			TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
+			TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
+			TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
+			TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
+			TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
+		}
+	}
+
+	/* TX power compensation for temperature variation based on TSSI. try every 4 second */
+	if (pAd->Mlme.OneSecPeriodicRound % 4 == 0) {
+		if (pAd->CommonCfg.Channel <= 14) {
+			/* bg channel */
+			bAutoTxAgc = pAd->bAutoTxAgcG;
+			TssiRef = pAd->TssiRefG;
+			pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
+			pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0];
+			TxAgcStep = pAd->TxAgcStepG;
+			pTxAgcCompensate = &pAd->TxAgcCompensateG;
+		} else {
+			/* a channel */
+			bAutoTxAgc = pAd->bAutoTxAgcA;
+			TssiRef = pAd->TssiRefA;
+			pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
+			pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0];
+			TxAgcStep = pAd->TxAgcStepA;
+			pTxAgcCompensate = &pAd->TxAgcCompensateA;
+		}
+
+		if (bAutoTxAgc) {
+			/* BbpR1 is unsigned char */
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
+
+			/* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
+			/* compensate: +4     +3   +2   +1    0   -1   -2   -3   -4 * steps */
+			/* step value is defined in pAd->TxAgcStepG for tx power value */
+
+			/* [4]+1+[4]   p4     p3   p2   p1   o1   m1   m2   m3   m4 */
+			/* ex:         0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
+			   above value are examined in mass factory production */
+			/*             [4]    [3]  [2]  [1]  [0]  [1]  [2]  [3]  [4] */
+
+			/* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
+			/* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
+			/* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
+
+			if (BbpR49 > pTssiMinusBoundary[1]) {
+				/* Reading is larger than the reference value */
+				/* check for how large we need to decrease the Tx power */
+				for (idx = 1; idx < 5; idx++) {
+					if (BbpR49 <= pTssiMinusBoundary[idx])	/* Found the range */
+						break;
+				}
+				/* The index is the step we should decrease, idx = 0 means there is nothing to compensate */
+/*                              if (R3 > (unsigned long)(TxAgcStep * (idx-1))) */
+				*pTxAgcCompensate = -(TxAgcStep * (idx - 1));
+/*                              else */
+/*                                      *pTxAgcCompensate = -((u8)R3); */
+
+				DeltaPwr += (*pTxAgcCompensate);
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
+					  BbpR49, TssiRef, TxAgcStep, idx - 1));
+			} else if (BbpR49 < pTssiPlusBoundary[1]) {
+				/* Reading is smaller than the reference value */
+				/* check for how large we need to increase the Tx power */
+				for (idx = 1; idx < 5; idx++) {
+					if (BbpR49 >= pTssiPlusBoundary[idx])	/* Found the range */
+						break;
+				}
+				/* The index is the step we should increase, idx = 0 means there is nothing to compensate */
+				*pTxAgcCompensate = TxAgcStep * (idx - 1);
+				DeltaPwr += (*pTxAgcCompensate);
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
+					  BbpR49, TssiRef, TxAgcStep, idx - 1));
+			} else {
+				*pTxAgcCompensate = 0;
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("   Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
+					  BbpR49, TssiRef, TxAgcStep, 0));
+			}
+		}
+	} else {
+		if (pAd->CommonCfg.Channel <= 14) {
+			bAutoTxAgc = pAd->bAutoTxAgcG;
+			pTxAgcCompensate = &pAd->TxAgcCompensateG;
+		} else {
+			bAutoTxAgc = pAd->bAutoTxAgcA;
+			pTxAgcCompensate = &pAd->TxAgcCompensateA;
+		}
+
+		if (bAutoTxAgc)
+			DeltaPwr += (*pTxAgcCompensate);
+	}
+
+	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1);
+	BbpR1 &= 0xFC;
+
+	/* calculate delta power based on the percentage specified from UI */
+	/* E2PROM setting is calibrated for maximum TX power (i.e. 100%) */
+	/* We lower TX power here according to the percentage specified from UI */
+	if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff)	/* AUTO TX POWER control */
+	{
+		{
+			/* to patch high power issue with some APs, like Belkin N1. */
+			if (Rssi > -35) {
+				BbpR1 |= 0x02;	/* DeltaPwr -= 12; */
+			} else if (Rssi > -40) {
+				BbpR1 |= 0x01;	/* DeltaPwr -= 6; */
+			} else;
+		}
+	} else if (pAd->CommonCfg.TxPowerPercentage > 90)	/* 91 ~ 100% & AUTO, treat as 100% in terms of mW */
+		;
+	else if (pAd->CommonCfg.TxPowerPercentage > 60)	/* 61 ~ 90%, treat as 75% in terms of mW               // DeltaPwr -= 1; */
+	{
+		DeltaPwr -= 1;
+	} else if (pAd->CommonCfg.TxPowerPercentage > 30)	/* 31 ~ 60%, treat as 50% in terms of mW               // DeltaPwr -= 3; */
+	{
+		DeltaPwr -= 3;
+	} else if (pAd->CommonCfg.TxPowerPercentage > 15)	/* 16 ~ 30%, treat as 25% in terms of mW               // DeltaPwr -= 6; */
+	{
+		BbpR1 |= 0x01;
+	} else if (pAd->CommonCfg.TxPowerPercentage > 9)	/* 10 ~ 15%, treat as 12.5% in terms of mW             // DeltaPwr -= 9; */
+	{
+		BbpR1 |= 0x01;
+		DeltaPwr -= 3;
+	} else			/* 0 ~ 9 %, treat as MIN(~3%) in terms of mW             // DeltaPwr -= 12; */
+	{
+		BbpR1 |= 0x02;
+	}
+
+	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
+
+	/* reset different new tx power for different TX rate */
+	for (i = 0; i < 5; i++) {
+		if (TxPwr[i] != 0xffffffff) {
+			for (j = 0; j < 8; j++) {
+				Value = (char)((TxPwr[i] >> j * 4) & 0x0F);	/* 0 ~ 15 */
+
+				if ((Value + DeltaPwr) < 0) {
+					Value = 0;	/* min */
+				} else if ((Value + DeltaPwr) > 0xF) {
+					Value = 0xF;	/* max */
+				} else {
+					Value += DeltaPwr;	/* temperature compensation */
+				}
+
+				/* fill new value to CSR offset */
+				TxPwr[i] =
+				    (TxPwr[i] & ~(0x0000000F << j * 4)) | (Value
+									   << j
+									   * 4);
+			}
+
+			/* write tx power value to CSR */
+			/* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
+			   TX power for OFDM 6M/9M
+			   TX power for CCK5.5M/11M
+			   TX power for CCK1M/2M */
+			/* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
+			RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i * 4, TxPwr[i]);
+		}
+	}
+
+}
+
+/*
+	==========================================================================
+	Description:
+		put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup
+		automatically. Instead, MCU will issue a TwakeUpInterrupt to host after
+		the wakeup timer timeout. Driver has to issue a separate command to wake
+		PHY up.
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+void AsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd,
+			     u16 TbttNumToNextWakeUp)
+{
+	RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp);
+}
+
+/*
+	==========================================================================
+	Description:
+		AsicForceWakeup() is used whenever manual wakeup is required
+		AsicForceSleep() should only be used when not in INFRA BSS. When
+		in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead.
+	==========================================================================
+ */
+void AsicForceSleep(struct rt_rtmp_adapter *pAd)
+{
+
+}
+
+/*
+	==========================================================================
+	Description:
+		AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
+		expired.
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+	==========================================================================
+ */
+void AsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx)
+{
+	DBGPRINT(RT_DEBUG_INFO, ("--> AsicForceWakeup \n"));
+	RTMP_STA_FORCE_WAKEUP(pAd, bFromTx);
+}
+
+/*
+	==========================================================================
+	Description:
+		Set My BSSID
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+void AsicSetBssid(struct rt_rtmp_adapter *pAd, u8 *pBssid)
+{
+	unsigned long Addr4;
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n", pBssid[0],
+		  pBssid[1], pBssid[2], pBssid[3], pBssid[4], pBssid[5]));
+
+	Addr4 = (unsigned long)(pBssid[0]) |
+	    (unsigned long)(pBssid[1] << 8) |
+	    (unsigned long)(pBssid[2] << 16) | (unsigned long)(pBssid[3] << 24);
+	RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
+
+	Addr4 = 0;
+	/* always one BSSID in STA mode */
+	Addr4 = (unsigned long)(pBssid[4]) | (unsigned long)(pBssid[5] << 8);
+
+	RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
+}
+
+void AsicSetMcastWC(struct rt_rtmp_adapter *pAd)
+{
+	struct rt_mac_table_entry *pEntry = &pAd->MacTab.Content[MCAST_WCID];
+	u16 offset;
+
+	pEntry->Sst = SST_ASSOC;
+	pEntry->Aid = MCAST_WCID;	/* Softap supports 1 BSSID and use WCID=0 as multicast Wcid index */
+	pEntry->PsMode = PWR_ACTIVE;
+	pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate;
+	offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE;
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+void AsicDelWcidTab(struct rt_rtmp_adapter *pAd, u8 Wcid)
+{
+	unsigned long Addr0 = 0x0, Addr1 = 0x0;
+	unsigned long offset;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n", Wcid));
+	offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE;
+	RTMP_IO_WRITE32(pAd, offset, Addr0);
+	offset += 4;
+	RTMP_IO_WRITE32(pAd, offset, Addr1);
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+void AsicEnableRDG(struct rt_rtmp_adapter *pAd)
+{
+	TX_LINK_CFG_STRUC TxLinkCfg;
+	u32 Data = 0;
+
+	RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
+	TxLinkCfg.field.TxRDGEn = 1;
+	RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
+
+	RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+	Data &= 0xFFFFFF00;
+	Data |= 0x80;
+	RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+
+	/*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED); */
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+void AsicDisableRDG(struct rt_rtmp_adapter *pAd)
+{
+	TX_LINK_CFG_STRUC TxLinkCfg;
+	u32 Data = 0;
+
+	RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
+	TxLinkCfg.field.TxRDGEn = 0;
+	RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
+
+	RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+
+	Data &= 0xFFFFFF00;
+	/*Data  |= 0x20; */
+#ifndef WIFI_TEST
+	/*if ( pAd->CommonCfg.bEnableTxBurst ) */
+	/*      Data |= 0x60; // for performance issue not set the TXOP to 0 */
+#endif
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)
+	    && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE)
+	    ) {
+		/* For CWC test, change txop from 0x30 to 0x20 in TxBurst mode */
+		if (pAd->CommonCfg.bEnableTxBurst)
+			Data |= 0x20;
+	}
+	RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+void AsicDisableSync(struct rt_rtmp_adapter *pAd)
+{
+	BCN_TIME_CFG_STRUC csr;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n"));
+
+	/* 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect */
+	/*                        that NIC will never wakes up because TSF stops and no more */
+	/*                        TBTT interrupts */
+	pAd->TbttTickCount = 0;
+	RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
+	csr.field.bBeaconGen = 0;
+	csr.field.bTBTTEnable = 0;
+	csr.field.TsfSyncMode = 0;
+	csr.field.bTsfTicking = 0;
+	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
+
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+void AsicEnableBssSync(struct rt_rtmp_adapter *pAd)
+{
+	BCN_TIME_CFG_STRUC csr;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n"));
+
+	RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
+/*      RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, 0x00000000); */
+	{
+		csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4;	/* ASIC register in units of 1/16 TU */
+		csr.field.bTsfTicking = 1;
+		csr.field.TsfSyncMode = 1;	/* sync TSF in INFRASTRUCTURE mode */
+		csr.field.bBeaconGen = 0;	/* do NOT generate BEACON */
+		csr.field.bTBTTEnable = 1;
+	}
+	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
+}
+
+/*
+	==========================================================================
+	Description:
+	Note:
+		BEACON frame in shared memory should be built ok before this routine
+		can be called. Otherwise, a garbage frame maybe transmitted out every
+		Beacon period.
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+void AsicEnableIbssSync(struct rt_rtmp_adapter *pAd)
+{
+	BCN_TIME_CFG_STRUC csr9;
+	u8 *ptr;
+	u32 i;
+
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n",
+		  pAd->BeaconTxWI.MPDUtotalByteCount));
+
+	RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
+	csr9.field.bBeaconGen = 0;
+	csr9.field.bTBTTEnable = 0;
+	csr9.field.bTsfTicking = 0;
+	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
+
+#ifdef RTMP_MAC_PCI
+	/* move BEACON TXD and frame content to on-chip memory */
+	ptr = (u8 *)& pAd->BeaconTxWI;
+	for (i = 0; i < TXWI_SIZE; i += 4)	/* 16-byte TXWI field */
+	{
+		u32 longptr =
+		    *ptr + (*(ptr + 1) << 8) + (*(ptr + 2) << 16) +
+		    (*(ptr + 3) << 24);
+		RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
+		ptr += 4;
+	}
+
+	/* start right after the 16-byte TXWI field */
+	ptr = pAd->BeaconBuf;
+	for (i = 0; i < pAd->BeaconTxWI.MPDUtotalByteCount; i += 4) {
+		u32 longptr =
+		    *ptr + (*(ptr + 1) << 8) + (*(ptr + 2) << 16) +
+		    (*(ptr + 3) << 24);
+		RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
+		ptr += 4;
+	}
+#endif /* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
+	/* move BEACON TXD and frame content to on-chip memory */
+	ptr = (u8 *)& pAd->BeaconTxWI;
+	for (i = 0; i < TXWI_SIZE; i += 2)	/* 16-byte TXWI field */
+	{
+		/*u32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24); */
+		/*RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr); */
+		RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + i, ptr, 2);
+		ptr += 2;
+	}
+
+	/* start right after the 16-byte TXWI field */
+	ptr = pAd->BeaconBuf;
+	for (i = 0; i < pAd->BeaconTxWI.MPDUtotalByteCount; i += 2) {
+		/*u32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24); */
+		/*RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr); */
+		RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, ptr, 2);
+		ptr += 2;
+	}
+#endif /* RTMP_MAC_USB // */
+
+	/* */
+	/* For Wi-Fi faily generated beacons between participating stations. */
+	/* Set TBTT phase adaptive adjustment step to 8us (default 16us) */
+	/* don't change settings 2006-5- by Jerry */
+	/*RTMP_IO_WRITE32(pAd, TBTT_SYNC_CFG, 0x00001010); */
+
+	/* start sending BEACON */
+	csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4;	/* ASIC register in units of 1/16 TU */
+	csr9.field.bTsfTicking = 1;
+	csr9.field.TsfSyncMode = 2;	/* sync TSF in IBSS mode */
+	csr9.field.bTBTTEnable = 1;
+	csr9.field.bBeaconGen = 1;
+	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+void AsicSetEdcaParm(struct rt_rtmp_adapter *pAd, struct rt_edca_parm *pEdcaParm)
+{
+	EDCA_AC_CFG_STRUC Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg;
+	AC_TXOP_CSR0_STRUC csr0;
+	AC_TXOP_CSR1_STRUC csr1;
+	AIFSN_CSR_STRUC AifsnCsr;
+	CWMIN_CSR_STRUC CwminCsr;
+	CWMAX_CSR_STRUC CwmaxCsr;
+	int i;
+
+	Ac0Cfg.word = 0;
+	Ac1Cfg.word = 0;
+	Ac2Cfg.word = 0;
+	Ac3Cfg.word = 0;
+	if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE)) {
+		DBGPRINT(RT_DEBUG_TRACE, ("AsicSetEdcaParm\n"));
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED);
+		for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++) {
+			if (pAd->MacTab.Content[i].ValidAsCLI
+			    || pAd->MacTab.Content[i].ValidAsApCli)
+				CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.
+							 Content[i],
+							 fCLIENT_STATUS_WMM_CAPABLE);
+		}
+
+		/*======================================================== */
+		/*      MAC Register has a copy . */
+		/*======================================================== */
+/*#ifndef WIFI_TEST */
+		if (pAd->CommonCfg.bEnableTxBurst) {
+			/* For CWC test, change txop from 0x30 to 0x20 in TxBurst mode */
+			Ac0Cfg.field.AcTxop = 0x20;	/* Suggest by John for TxBurst in HT Mode */
+		} else
+			Ac0Cfg.field.AcTxop = 0;	/* QID_AC_BE */
+/*#else */
+/*              Ac0Cfg.field.AcTxop = 0;        // QID_AC_BE */
+/*#endif */
+		Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS;
+		Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS;
+		Ac0Cfg.field.Aifsn = 2;
+		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
+
+		Ac1Cfg.field.AcTxop = 0;	/* QID_AC_BK */
+		Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS;
+		Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS;
+		Ac1Cfg.field.Aifsn = 2;
+		RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
+
+		if (pAd->CommonCfg.PhyMode == PHY_11B) {
+			Ac2Cfg.field.AcTxop = 192;	/* AC_VI: 192*32us ~= 6ms */
+			Ac3Cfg.field.AcTxop = 96;	/* AC_VO: 96*32us  ~= 3ms */
+		} else {
+			Ac2Cfg.field.AcTxop = 96;	/* AC_VI: 96*32us ~= 3ms */
+			Ac3Cfg.field.AcTxop = 48;	/* AC_VO: 48*32us ~= 1.5ms */
+		}
+		Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS;
+		Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS;
+		Ac2Cfg.field.Aifsn = 2;
+		RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
+		Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS;
+		Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS;
+		Ac3Cfg.field.Aifsn = 2;
+		RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
+
+		/*======================================================== */
+		/*      DMA Register has a copy too. */
+		/*======================================================== */
+		csr0.field.Ac0Txop = 0;	/* QID_AC_BE */
+		csr0.field.Ac1Txop = 0;	/* QID_AC_BK */
+		RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
+		if (pAd->CommonCfg.PhyMode == PHY_11B) {
+			csr1.field.Ac2Txop = 192;	/* AC_VI: 192*32us ~= 6ms */
+			csr1.field.Ac3Txop = 96;	/* AC_VO: 96*32us  ~= 3ms */
+		} else {
+			csr1.field.Ac2Txop = 96;	/* AC_VI: 96*32us ~= 3ms */
+			csr1.field.Ac3Txop = 48;	/* AC_VO: 48*32us ~= 1.5ms */
+		}
+		RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
+
+		CwminCsr.word = 0;
+		CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS;
+		CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS;
+		CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS;
+		CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS;
+		RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
+
+		CwmaxCsr.word = 0;
+		CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS;
+		CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS;
+		CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS;
+		CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS;
+		RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
+
+		RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222);
+
+		NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(struct rt_edca_parm));
+	} else {
+		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED);
+		/*======================================================== */
+		/*      MAC Register has a copy. */
+		/*======================================================== */
+		/* */
+		/* Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27 */
+		/* To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue. */
+		/* */
+		/*pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this */
+
+		Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE];
+		Ac0Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BE];
+		Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE];
+		Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE];	/*+1; */
+
+		Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
+		Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK];	/*+2; */
+		Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK];
+		Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK];	/*+1; */
+
+		Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10;
+		if (pAd->Antenna.field.TxPath == 1) {
+			Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI] + 1;
+			Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI] + 1;
+		} else {
+			Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI];
+			Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI];
+		}
+		Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 1;
+#ifdef RTMP_MAC_USB
+		Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 3;
+#endif /* RTMP_MAC_USB // */
+
+		{
+			/* Tuning for Wi-Fi WMM S06 */
+			if (pAd->CommonCfg.bWiFiTest &&
+			    pEdcaParm->Aifsn[QID_AC_VI] == 10)
+				Ac2Cfg.field.Aifsn -= 1;
+
+			/* Tuning for TGn Wi-Fi 5.2.32 */
+			/* STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta */
+			if (STA_TGN_WIFI_ON(pAd) &&
+			    pEdcaParm->Aifsn[QID_AC_VI] == 10) {
+				Ac0Cfg.field.Aifsn = 3;
+				Ac2Cfg.field.AcTxop = 5;
+			}
+#ifdef RT30xx
+			if (pAd->RfIcType == RFIC_3020
+			    || pAd->RfIcType == RFIC_2020) {
+				/* Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta. */
+				Ac2Cfg.field.Aifsn = 5;
+			}
+#endif /* RT30xx // */
+		}
+
+		Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO];
+		Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO];
+		Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO];
+		Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO];
+
+/*#ifdef WIFI_TEST */
+		if (pAd->CommonCfg.bWiFiTest) {
+			if (Ac3Cfg.field.AcTxop == 102) {
+				Ac0Cfg.field.AcTxop =
+				    pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->
+				    Txop[QID_AC_BE] : 10;
+				Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE] - 1;	/* AIFSN must >= 1 */
+				Ac1Cfg.field.AcTxop =
+				    pEdcaParm->Txop[QID_AC_BK];
+				Ac1Cfg.field.Aifsn =
+				    pEdcaParm->Aifsn[QID_AC_BK];
+				Ac2Cfg.field.AcTxop =
+				    pEdcaParm->Txop[QID_AC_VI];
+			}	/* End of if */
+		}
+/*#endif // WIFI_TEST // */
+
+		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
+		RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
+		RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
+		RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
+
+		/*======================================================== */
+		/*      DMA Register has a copy too. */
+		/*======================================================== */
+		csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop;
+		csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop;
+		RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
+
+		csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop;
+		csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop;
+		RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
+
+		CwminCsr.word = 0;
+		CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE];
+		CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK];
+		CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI];
+		CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1;	/*for TGn wifi test */
+		RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
+
+		CwmaxCsr.word = 0;
+		CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE];
+		CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK];
+		CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI];
+		CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO];
+		RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
+
+		AifsnCsr.word = 0;
+		AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn;	/*pEdcaParm->Aifsn[QID_AC_BE]; */
+		AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn;	/*pEdcaParm->Aifsn[QID_AC_BK]; */
+		AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn;	/*pEdcaParm->Aifsn[QID_AC_VI]; */
+
+		{
+			/* Tuning for Wi-Fi WMM S06 */
+			if (pAd->CommonCfg.bWiFiTest &&
+			    pEdcaParm->Aifsn[QID_AC_VI] == 10)
+				AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4;
+
+			/* Tuning for TGn Wi-Fi 5.2.32 */
+			/* STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta */
+			if (STA_TGN_WIFI_ON(pAd) &&
+			    pEdcaParm->Aifsn[QID_AC_VI] == 10) {
+				AifsnCsr.field.Aifsn0 = 3;
+				AifsnCsr.field.Aifsn2 = 7;
+			}
+
+			if (INFRA_ON(pAd))
+				CLIENT_STATUS_SET_FLAG(&pAd->MacTab.
+						       Content[BSSID_WCID],
+						       fCLIENT_STATUS_WMM_CAPABLE);
+		}
+
+		{
+			AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1;	/*pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test */
+#ifdef RT30xx
+			/* TODO: Shiang, this modification also suitable for RT3052/RT3050 ??? */
+			if (pAd->RfIcType == RFIC_3020
+			    || pAd->RfIcType == RFIC_2020) {
+				AifsnCsr.field.Aifsn2 = 0x2;	/*pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04. */
+			}
+#endif /* RT30xx // */
+		}
+		RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
+
+		NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm,
+			       sizeof(struct rt_edca_parm));
+		if (!ADHOC_ON(pAd)) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("EDCA [#%d]: AIFSN CWmin CWmax  TXOP(us)  ACM\n",
+				  pEdcaParm->EdcaUpdateCount));
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("     AC_BE      %2d     %2d     %2d      %4d     %d\n",
+				  pEdcaParm->Aifsn[0], pEdcaParm->Cwmin[0],
+				  pEdcaParm->Cwmax[0], pEdcaParm->Txop[0] << 5,
+				  pEdcaParm->bACM[0]));
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("     AC_BK      %2d     %2d     %2d      %4d     %d\n",
+				  pEdcaParm->Aifsn[1], pEdcaParm->Cwmin[1],
+				  pEdcaParm->Cwmax[1], pEdcaParm->Txop[1] << 5,
+				  pEdcaParm->bACM[1]));
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("     AC_VI      %2d     %2d     %2d      %4d     %d\n",
+				  pEdcaParm->Aifsn[2], pEdcaParm->Cwmin[2],
+				  pEdcaParm->Cwmax[2], pEdcaParm->Txop[2] << 5,
+				  pEdcaParm->bACM[2]));
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("     AC_VO      %2d     %2d     %2d      %4d     %d\n",
+				  pEdcaParm->Aifsn[3], pEdcaParm->Cwmin[3],
+				  pEdcaParm->Cwmax[3], pEdcaParm->Txop[3] << 5,
+				  pEdcaParm->bACM[3]));
+		}
+	}
+
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+void AsicSetSlotTime(struct rt_rtmp_adapter *pAd, IN BOOLEAN bUseShortSlotTime)
+{
+	unsigned long SlotTime;
+	u32 RegValue = 0;
+
+	if (pAd->CommonCfg.Channel > 14)
+		bUseShortSlotTime = TRUE;
+
+	if (bUseShortSlotTime
+	    && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))
+		return;
+	else if ((!bUseShortSlotTime)
+		 && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED)))
+		return;
+
+	if (bUseShortSlotTime)
+		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
+	else
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
+
+	SlotTime = (bUseShortSlotTime) ? 9 : 20;
+
+	{
+		/* force using short SLOT time for FAE to demo performance when TxBurst is ON */
+		if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
+		     && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
+		    || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE)
+			&& (pAd->CommonCfg.BACapability.field.Policy ==
+			    BA_NOTUSE))
+		    ) {
+			/* In this case, we will think it is doing Wi-Fi test */
+			/* And we will not set to short slot when bEnableTxBurst is TRUE. */
+		} else if (pAd->CommonCfg.bEnableTxBurst) {
+			OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
+			SlotTime = 9;
+		}
+	}
+
+	/* */
+	/* For some reasons, always set it to short slot time. */
+	/* */
+	/* ToDo: Should consider capability with 11B */
+	/* */
+	{
+		if (pAd->StaCfg.BssType == BSS_ADHOC) {
+			OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
+			SlotTime = 20;
+		}
+	}
+
+	RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
+	RegValue = RegValue & 0xFFFFFF00;
+
+	RegValue |= SlotTime;
+
+	RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue);
+}
+
+/*
+	========================================================================
+	Description:
+		Add Shared key information into ASIC.
+		Update shared key, TxMic and RxMic to Asic Shared key table
+		Update its cipherAlg to Asic Shared key Mode.
+
+    Return:
+	========================================================================
+*/
+void AsicAddSharedKeyEntry(struct rt_rtmp_adapter *pAd,
+			   u8 BssIndex,
+			   u8 KeyIdx,
+			   u8 CipherAlg,
+			   u8 *pKey, u8 *pTxMic, u8 *pRxMic)
+{
+	unsigned long offset;		/*, csr0; */
+	SHAREDKEY_MODE_STRUC csr1;
+#ifdef RTMP_MAC_PCI
+	int i;
+#endif /* RTMP_MAC_PCI // */
+
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,
+		  KeyIdx));
+/*============================================================================================ */
+
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg],
+		  BssIndex * 4 + KeyIdx));
+	DBGPRINT_RAW(RT_DEBUG_TRACE,
+		     ("		Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+		      pKey[0], pKey[1], pKey[2], pKey[3], pKey[4],
+		      pKey[5], pKey[6], pKey[7], pKey[8], pKey[9],
+		      pKey[10], pKey[11], pKey[12], pKey[13], pKey[14],
+		      pKey[15]));
+	if (pRxMic) {
+		DBGPRINT_RAW(RT_DEBUG_TRACE,
+			     ("		Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+			      pRxMic[0], pRxMic[1], pRxMic[2], pRxMic[3],
+			      pRxMic[4], pRxMic[5], pRxMic[6], pRxMic[7]));
+	}
+	if (pTxMic) {
+		DBGPRINT_RAW(RT_DEBUG_TRACE,
+			     ("		Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+			      pTxMic[0], pTxMic[1], pTxMic[2], pTxMic[3],
+			      pTxMic[4], pTxMic[5], pTxMic[6], pTxMic[7]));
+	}
+/*============================================================================================ */
+	/* */
+	/* fill key material - key + TX MIC + RX MIC */
+	/* */
+#ifdef RTMP_MAC_PCI
+	offset =
+	    SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE;
+	for (i = 0; i < MAX_LEN_OF_SHARE_KEY; i++) {
+		RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
+	}
+
+	offset += MAX_LEN_OF_SHARE_KEY;
+	if (pTxMic) {
+		for (i = 0; i < 8; i++) {
+			RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
+		}
+	}
+
+	offset += 8;
+	if (pRxMic) {
+		for (i = 0; i < 8; i++) {
+			RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
+		}
+	}
+#endif /* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
+	{
+		offset =
+		    SHARED_KEY_TABLE_BASE + (4 * BssIndex +
+					     KeyIdx) * HW_KEY_ENTRY_SIZE;
+		RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_SHARE_KEY);
+
+		offset += MAX_LEN_OF_SHARE_KEY;
+		if (pTxMic) {
+			RTUSBMultiWrite(pAd, offset, pTxMic, 8);
+		}
+
+		offset += 8;
+		if (pRxMic) {
+			RTUSBMultiWrite(pAd, offset, pRxMic, 8);
+		}
+	}
+#endif /* RTMP_MAC_USB // */
+
+	/* */
+	/* Update cipher algorithm. WSTA always use BSS0 */
+	/* */
+	RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
+		       &csr1.word);
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n",
+		  BssIndex, KeyIdx, csr1.word));
+	if ((BssIndex % 2) == 0) {
+		if (KeyIdx == 0)
+			csr1.field.Bss0Key0CipherAlg = CipherAlg;
+		else if (KeyIdx == 1)
+			csr1.field.Bss0Key1CipherAlg = CipherAlg;
+		else if (KeyIdx == 2)
+			csr1.field.Bss0Key2CipherAlg = CipherAlg;
+		else
+			csr1.field.Bss0Key3CipherAlg = CipherAlg;
+	} else {
+		if (KeyIdx == 0)
+			csr1.field.Bss1Key0CipherAlg = CipherAlg;
+		else if (KeyIdx == 1)
+			csr1.field.Bss1Key1CipherAlg = CipherAlg;
+		else if (KeyIdx == 2)
+			csr1.field.Bss1Key2CipherAlg = CipherAlg;
+		else
+			csr1.field.Bss1Key3CipherAlg = CipherAlg;
+	}
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n",
+		  BssIndex, csr1.word));
+	RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
+			csr1.word);
+
+}
+
+/*      IRQL = DISPATCH_LEVEL */
+void AsicRemoveSharedKeyEntry(struct rt_rtmp_adapter *pAd,
+			      u8 BssIndex, u8 KeyIdx)
+{
+	/*unsigned long SecCsr0; */
+	SHAREDKEY_MODE_STRUC csr1;
+
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("AsicRemoveSharedKeyEntry: #%d \n", BssIndex * 4 + KeyIdx));
+
+	RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
+		       &csr1.word);
+	if ((BssIndex % 2) == 0) {
+		if (KeyIdx == 0)
+			csr1.field.Bss0Key0CipherAlg = 0;
+		else if (KeyIdx == 1)
+			csr1.field.Bss0Key1CipherAlg = 0;
+		else if (KeyIdx == 2)
+			csr1.field.Bss0Key2CipherAlg = 0;
+		else
+			csr1.field.Bss0Key3CipherAlg = 0;
+	} else {
+		if (KeyIdx == 0)
+			csr1.field.Bss1Key0CipherAlg = 0;
+		else if (KeyIdx == 1)
+			csr1.field.Bss1Key1CipherAlg = 0;
+		else if (KeyIdx == 2)
+			csr1.field.Bss1Key2CipherAlg = 0;
+		else
+			csr1.field.Bss1Key3CipherAlg = 0;
+	}
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n",
+		  BssIndex, csr1.word));
+	RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
+			csr1.word);
+	ASSERT(BssIndex < 4);
+	ASSERT(KeyIdx < 4);
+
+}
+
+void AsicUpdateWCIDAttribute(struct rt_rtmp_adapter *pAd,
+			     u16 WCID,
+			     u8 BssIndex,
+			     u8 CipherAlg,
+			     IN BOOLEAN bUsePairewiseKeyTable)
+{
+	unsigned long WCIDAttri = 0, offset;
+
+	/* */
+	/* Update WCID attribute. */
+	/* Only TxKey could update WCID attribute. */
+	/* */
+	offset = MAC_WCID_ATTRIBUTE_BASE + (WCID * HW_WCID_ATTRI_SIZE);
+	WCIDAttri =
+	    (BssIndex << 4) | (CipherAlg << 1) | (bUsePairewiseKeyTable);
+	RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
+}
+
+void AsicUpdateWCIDIVEIV(struct rt_rtmp_adapter *pAd,
+			 u16 WCID, unsigned long uIV, unsigned long uEIV)
+{
+	unsigned long offset;
+
+	offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
+
+	RTMP_IO_WRITE32(pAd, offset, uIV);
+	RTMP_IO_WRITE32(pAd, offset + 4, uEIV);
+}
+
+void AsicUpdateRxWCIDTable(struct rt_rtmp_adapter *pAd,
+			   u16 WCID, u8 *pAddr)
+{
+	unsigned long offset;
+	unsigned long Addr;
+
+	offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE);
+	Addr = pAddr[0] + (pAddr[1] << 8) + (pAddr[2] << 16) + (pAddr[3] << 24);
+	RTMP_IO_WRITE32(pAd, offset, Addr);
+	Addr = pAddr[4] + (pAddr[5] << 8);
+	RTMP_IO_WRITE32(pAd, offset + 4, Addr);
+}
+
+/*
+    ========================================================================
+
+    Routine Description:
+        Set Cipher Key, Cipher algorithm, IV/EIV to Asic
+
+    Arguments:
+        pAd                     Pointer to our adapter
+        WCID                    WCID Entry number.
+        BssIndex                BSSID index, station or none multiple BSSID support
+                                this value should be 0.
+        KeyIdx                  This KeyIdx will set to IV's KeyID if bTxKey enabled
+        pCipherKey              Pointer to Cipher Key.
+        bUsePairewiseKeyTable   TRUE means saved the key in SharedKey table,
+                                otherwise PairewiseKey table
+        bTxKey                  This is the transmit key if enabled.
+
+    Return Value:
+        None
+
+    Note:
+        This routine will set the relative key stuff to Asic including WCID attribute,
+        Cipher Key, Cipher algorithm and IV/EIV.
+
+        IV/EIV will be update if this CipherKey is the transmission key because
+        ASIC will base on IV's KeyID value to select Cipher Key.
+
+        If bTxKey sets to FALSE, this is not the TX key, but it could be
+        RX key
+
+	For AP mode bTxKey must be always set to TRUE.
+    ========================================================================
+*/
+void AsicAddKeyEntry(struct rt_rtmp_adapter *pAd,
+		     u16 WCID,
+		     u8 BssIndex,
+		     u8 KeyIdx,
+		     struct rt_cipher_key *pCipherKey,
+		     IN BOOLEAN bUsePairewiseKeyTable, IN BOOLEAN bTxKey)
+{
+	unsigned long offset;
+/*      unsigned long   WCIDAttri = 0; */
+	u8 IV4 = 0;
+	u8 *pKey = pCipherKey->Key;
+/*      unsigned long           KeyLen = pCipherKey->KeyLen; */
+	u8 *pTxMic = pCipherKey->TxMic;
+	u8 *pRxMic = pCipherKey->RxMic;
+	u8 *pTxtsc = pCipherKey->TxTsc;
+	u8 CipherAlg = pCipherKey->CipherAlg;
+	SHAREDKEY_MODE_STRUC csr1;
+#ifdef RTMP_MAC_PCI
+	u8 i;
+#endif /* RTMP_MAC_PCI // */
+
+/*      ASSERT(KeyLen <= MAX_LEN_OF_PEER_KEY); */
+
+	DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
+	/* */
+	/* 1.) decide key table offset */
+	/* */
+	if (bUsePairewiseKeyTable)
+		offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
+	else
+		offset =
+		    SHARED_KEY_TABLE_BASE + (4 * BssIndex +
+					     KeyIdx) * HW_KEY_ENTRY_SIZE;
+
+	/* */
+	/* 2.) Set Key to Asic */
+	/* */
+	/*for (i = 0; i < KeyLen; i++) */
+#ifdef RTMP_MAC_PCI
+	for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++) {
+		RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
+	}
+	offset += MAX_LEN_OF_PEER_KEY;
+
+	/* */
+	/* 3.) Set MIC key if available */
+	/* */
+	if (pTxMic) {
+		for (i = 0; i < 8; i++) {
+			RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
+		}
+	}
+	offset += LEN_TKIP_TXMICK;
+
+	if (pRxMic) {
+		for (i = 0; i < 8; i++) {
+			RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
+		}
+	}
+#endif /* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
+	RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_PEER_KEY);
+	offset += MAX_LEN_OF_PEER_KEY;
+
+	/* */
+	/* 3.) Set MIC key if available */
+	/* */
+	if (pTxMic) {
+		RTUSBMultiWrite(pAd, offset, pTxMic, 8);
+	}
+	offset += LEN_TKIP_TXMICK;
+
+	if (pRxMic) {
+		RTUSBMultiWrite(pAd, offset, pRxMic, 8);
+	}
+#endif /* RTMP_MAC_USB // */
+
+	/* */
+	/* 4.) Modify IV/EIV if needs */
+	/*     This will force Asic to use this key ID by setting IV. */
+	/* */
+	if (bTxKey) {
+#ifdef RTMP_MAC_PCI
+		offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
+		/* */
+		/* Write IV */
+		/* */
+		RTMP_IO_WRITE8(pAd, offset, pTxtsc[1]);
+		RTMP_IO_WRITE8(pAd, offset + 1, ((pTxtsc[1] | 0x20) & 0x7f));
+		RTMP_IO_WRITE8(pAd, offset + 2, pTxtsc[0]);
+
+		IV4 = (KeyIdx << 6);
+		if ((CipherAlg == CIPHER_TKIP)
+		    || (CipherAlg == CIPHER_TKIP_NO_MIC)
+		    || (CipherAlg == CIPHER_AES))
+			IV4 |= 0x20;	/* turn on extension bit means EIV existence */
+
+		RTMP_IO_WRITE8(pAd, offset + 3, IV4);
+
+		/* */
+		/* Write EIV */
+		/* */
+		offset += 4;
+		for (i = 0; i < 4; i++) {
+			RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]);
+		}
+#endif /* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
+		u32 tmpVal;
+
+		/* */
+		/* Write IV */
+		/* */
+		IV4 = (KeyIdx << 6);
+		if ((CipherAlg == CIPHER_TKIP)
+		    || (CipherAlg == CIPHER_TKIP_NO_MIC)
+		    || (CipherAlg == CIPHER_AES))
+			IV4 |= 0x20;	/* turn on extension bit means EIV existence */
+
+		tmpVal =
+		    pTxtsc[1] + (((pTxtsc[1] | 0x20) & 0x7f) << 8) +
+		    (pTxtsc[0] << 16) + (IV4 << 24);
+		RTMP_IO_WRITE32(pAd, offset, tmpVal);
+
+		/* */
+		/* Write EIV */
+		/* */
+		offset += 4;
+		RTMP_IO_WRITE32(pAd, offset, *(u32 *)& pCipherKey->TxTsc[2]);
+#endif /* RTMP_MAC_USB // */
+
+		AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg,
+					bUsePairewiseKeyTable);
+	}
+
+	if (!bUsePairewiseKeyTable) {
+		/* */
+		/* Only update the shared key security mode */
+		/* */
+		RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
+			       &csr1.word);
+		if ((BssIndex % 2) == 0) {
+			if (KeyIdx == 0)
+				csr1.field.Bss0Key0CipherAlg = CipherAlg;
+			else if (KeyIdx == 1)
+				csr1.field.Bss0Key1CipherAlg = CipherAlg;
+			else if (KeyIdx == 2)
+				csr1.field.Bss0Key2CipherAlg = CipherAlg;
+			else
+				csr1.field.Bss0Key3CipherAlg = CipherAlg;
+		} else {
+			if (KeyIdx == 0)
+				csr1.field.Bss1Key0CipherAlg = CipherAlg;
+			else if (KeyIdx == 1)
+				csr1.field.Bss1Key1CipherAlg = CipherAlg;
+			else if (KeyIdx == 2)
+				csr1.field.Bss1Key2CipherAlg = CipherAlg;
+			else
+				csr1.field.Bss1Key3CipherAlg = CipherAlg;
+		}
+		RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
+				csr1.word);
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n"));
+}
+
+/*
+	========================================================================
+	Description:
+		Add Pair-wise key material into ASIC.
+		Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
+
+    Return:
+	========================================================================
+*/
+void AsicAddPairwiseKeyEntry(struct rt_rtmp_adapter *pAd,
+			     u8 *pAddr,
+			     u8 WCID, struct rt_cipher_key *pCipherKey)
+{
+	int i;
+	unsigned long offset;
+	u8 *pKey = pCipherKey->Key;
+	u8 *pTxMic = pCipherKey->TxMic;
+	u8 *pRxMic = pCipherKey->RxMic;
+#ifdef DBG
+	u8 CipherAlg = pCipherKey->CipherAlg;
+#endif /* DBG // */
+
+	/* EKEY */
+	offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
+#ifdef RTMP_MAC_PCI
+	for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++) {
+		RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
+	}
+#endif /* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
+	RTUSBMultiWrite(pAd, offset, &pCipherKey->Key[0], MAX_LEN_OF_PEER_KEY);
+#endif /* RTMP_MAC_USB // */
+	for (i = 0; i < MAX_LEN_OF_PEER_KEY; i += 4) {
+		u32 Value;
+		RTMP_IO_READ32(pAd, offset + i, &Value);
+	}
+
+	offset += MAX_LEN_OF_PEER_KEY;
+
+	/*  MIC KEY */
+	if (pTxMic) {
+#ifdef RTMP_MAC_PCI
+		for (i = 0; i < 8; i++) {
+			RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
+		}
+#endif /* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
+		RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8);
+#endif /* RTMP_MAC_USB // */
+	}
+	offset += 8;
+	if (pRxMic) {
+#ifdef RTMP_MAC_PCI
+		for (i = 0; i < 8; i++) {
+			RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
+		}
+#endif /* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
+		RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8);
+#endif /* RTMP_MAC_USB // */
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n", WCID,
+		  CipherName[CipherAlg]));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("	Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+		  pKey[0], pKey[1], pKey[2], pKey[3], pKey[4], pKey[5],
+		  pKey[6], pKey[7], pKey[8], pKey[9], pKey[10], pKey[11],
+		  pKey[12], pKey[13], pKey[14], pKey[15]));
+	if (pRxMic) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("	Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+			  pRxMic[0], pRxMic[1], pRxMic[2], pRxMic[3],
+			  pRxMic[4], pRxMic[5], pRxMic[6], pRxMic[7]));
+	}
+	if (pTxMic) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("	Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+			  pTxMic[0], pTxMic[1], pTxMic[2], pTxMic[3],
+			  pTxMic[4], pTxMic[5], pTxMic[6], pTxMic[7]));
+	}
+}
+
+/*
+	========================================================================
+	Description:
+		Remove Pair-wise key material from ASIC.
+
+    Return:
+	========================================================================
+*/
+void AsicRemovePairwiseKeyEntry(struct rt_rtmp_adapter *pAd,
+				u8 BssIdx, u8 Wcid)
+{
+	unsigned long WCIDAttri;
+	u16 offset;
+
+	/* re-set the entry's WCID attribute as OPEN-NONE. */
+	offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
+	WCIDAttri = (BssIdx << 4) | PAIRWISEKEYTABLE;
+	RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
+}
+
+BOOLEAN AsicSendCommandToMcu(struct rt_rtmp_adapter *pAd,
+			     u8 Command,
+			     u8 Token, u8 Arg0, u8 Arg1)
+{
+
+	if (pAd->chipOps.sendCommandToMcu)
+		pAd->chipOps.sendCommandToMcu(pAd, Command, Token, Arg0, Arg1);
+
+	return TRUE;
+}
+
+void AsicSetRxAnt(struct rt_rtmp_adapter *pAd, u8 Ant)
+{
+#ifdef RT30xx
+	/* RT3572 ATE need not to do this. */
+	RT30xxSetRxAnt(pAd, Ant);
+#endif /* RT30xx // */
+}
+
+void AsicTurnOffRFClk(struct rt_rtmp_adapter *pAd, u8 Channel)
+{
+	if (pAd->chipOps.AsicRfTurnOff) {
+		pAd->chipOps.AsicRfTurnOff(pAd);
+	} else {
+		/* RF R2 bit 18 = 0 */
+		u32 R1 = 0, R2 = 0, R3 = 0;
+		u8 index;
+		struct rt_rtmp_rf_regs *RFRegTable;
+
+		RFRegTable = RF2850RegTable;
+
+		switch (pAd->RfIcType) {
+		case RFIC_2820:
+		case RFIC_2850:
+		case RFIC_2720:
+		case RFIC_2750:
+
+			for (index = 0; index < NUM_OF_2850_CHNL; index++) {
+				if (Channel == RFRegTable[index].Channel) {
+					R1 = RFRegTable[index].R1 & 0xffffdfff;
+					R2 = RFRegTable[index].R2 & 0xfffbffff;
+					R3 = RFRegTable[index].R3 & 0xfff3ffff;
+
+					RTMP_RF_IO_WRITE32(pAd, R1);
+					RTMP_RF_IO_WRITE32(pAd, R2);
+
+					/* Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0. */
+					/* Set RF R2 bit18=0, R3 bit[18:19]=0 */
+					/*if (pAd->StaCfg.bRadio == FALSE) */
+					if (1) {
+						RTMP_RF_IO_WRITE32(pAd, R3);
+
+						DBGPRINT(RT_DEBUG_TRACE,
+							 ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x,  R3 = 0x%08x \n",
+							  Channel,
+							  pAd->RfIcType, R2,
+							  R3));
+					} else
+						DBGPRINT(RT_DEBUG_TRACE,
+							 ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
+							  Channel,
+							  pAd->RfIcType, R2));
+					break;
+				}
+			}
+			break;
+
+		default:
+			break;
+		}
+	}
+}
+
+void AsicTurnOnRFClk(struct rt_rtmp_adapter *pAd, u8 Channel)
+{
+	/* RF R2 bit 18 = 0 */
+	u32 R1 = 0, R2 = 0, R3 = 0;
+	u8 index;
+	struct rt_rtmp_rf_regs *RFRegTable;
+
+#ifdef PCIE_PS_SUPPORT
+	/* The RF programming sequence is difference between 3xxx and 2xxx */
+	if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) {
+		return;
+	}
+#endif /* PCIE_PS_SUPPORT // */
+
+	RFRegTable = RF2850RegTable;
+
+	switch (pAd->RfIcType) {
+	case RFIC_2820:
+	case RFIC_2850:
+	case RFIC_2720:
+	case RFIC_2750:
+
+		for (index = 0; index < NUM_OF_2850_CHNL; index++) {
+			if (Channel == RFRegTable[index].Channel) {
+				R3 = pAd->LatchRfRegs.R3;
+				R3 &= 0xfff3ffff;
+				R3 |= 0x00080000;
+				RTMP_RF_IO_WRITE32(pAd, R3);
+
+				R1 = RFRegTable[index].R1;
+				RTMP_RF_IO_WRITE32(pAd, R1);
+
+				R2 = RFRegTable[index].R2;
+				if (pAd->Antenna.field.TxPath == 1) {
+					R2 |= 0x4000;	/* If TXpath is 1, bit 14 = 1; */
+				}
+
+				if (pAd->Antenna.field.RxPath == 2) {
+					R2 |= 0x40;	/* write 1 to off Rxpath. */
+				} else if (pAd->Antenna.field.RxPath == 1) {
+					R2 |= 0x20040;	/* write 1 to off RxPath */
+				}
+				RTMP_RF_IO_WRITE32(pAd, R2);
+
+				break;
+			}
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n",
+				  Channel, pAd->RfIcType, R2));
+}
diff --git a/drivers/staging/rt2860/common/cmm_cfg.c b/drivers/staging/rt2860/common/cmm_cfg.c
new file mode 100644
index 0000000..24f4393
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_cfg.c
@@ -0,0 +1,258 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+	cmm_cfg.c
+
+    Abstract:
+    Ralink WiFi Driver configuration related subroutines
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+*/
+
+#include "../rt_config.h"
+
+char *GetPhyMode(int Mode)
+{
+	switch (Mode) {
+	case MODE_CCK:
+		return "CCK";
+
+	case MODE_OFDM:
+		return "OFDM";
+	case MODE_HTMIX:
+		return "HTMIX";
+
+	case MODE_HTGREENFIELD:
+		return "GREEN";
+	default:
+		return "N/A";
+	}
+}
+
+char *GetBW(int BW)
+{
+	switch (BW) {
+	case BW_10:
+		return "10M";
+
+	case BW_20:
+		return "20M";
+	case BW_40:
+		return "40M";
+	default:
+		return "N/A";
+	}
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set Country Region to pAd->CommonCfg.CountryRegion.
+        This command will not work, if the field of CountryRegion in eeprom is programmed.
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+int RT_CfgSetCountryRegion(struct rt_rtmp_adapter *pAd, char *arg, int band)
+{
+	long region, regionMax;
+	u8 *pCountryRegion;
+
+	region = simple_strtol(arg, 0, 10);
+
+	if (band == BAND_24G) {
+		pCountryRegion = &pAd->CommonCfg.CountryRegion;
+		regionMax = REGION_MAXIMUM_BG_BAND;
+	} else {
+		pCountryRegion = &pAd->CommonCfg.CountryRegionForABand;
+		regionMax = REGION_MAXIMUM_A_BAND;
+	}
+
+	/* TODO: Is it neccesay for following check??? */
+	/* Country can be set only when EEPROM not programmed */
+	if (*pCountryRegion & 0x80) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("CfgSetCountryRegion():CountryRegion in eeprom was programmed\n"));
+		return FALSE;
+	}
+
+	if ((region >= 0) && (region <= REGION_MAXIMUM_BG_BAND)) {
+		*pCountryRegion = (u8)region;
+	} else if ((region == REGION_31_BG_BAND) && (band == BAND_24G)) {
+		*pCountryRegion = (u8)region;
+	} else {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("CfgSetCountryRegion():region(%ld) out of range!\n",
+			  region));
+		return FALSE;
+	}
+
+	return TRUE;
+
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set Wireless Mode
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+int RT_CfgSetWirelessMode(struct rt_rtmp_adapter *pAd, char *arg)
+{
+	int MaxPhyMode = PHY_11G;
+	long WirelessMode;
+
+	MaxPhyMode = PHY_11N_5G;
+
+	WirelessMode = simple_strtol(arg, 0, 10);
+	if (WirelessMode <= MaxPhyMode) {
+		pAd->CommonCfg.PhyMode = WirelessMode;
+		return TRUE;
+	}
+
+	return FALSE;
+
+}
+
+int RT_CfgSetShortSlot(struct rt_rtmp_adapter *pAd, char *arg)
+{
+	long ShortSlot;
+
+	ShortSlot = simple_strtol(arg, 0, 10);
+
+	if (ShortSlot == 1)
+		pAd->CommonCfg.bUseShortSlotTime = TRUE;
+	else if (ShortSlot == 0)
+		pAd->CommonCfg.bUseShortSlotTime = FALSE;
+	else
+		return FALSE;	/*Invalid argument */
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set WEP KEY base on KeyIdx
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+int RT_CfgSetWepKey(struct rt_rtmp_adapter *pAd,
+		    char *keyString,
+		    struct rt_cipher_key *pSharedKey, int keyIdx)
+{
+	int KeyLen;
+	int i;
+	u8 CipherAlg = CIPHER_NONE;
+	BOOLEAN bKeyIsHex = FALSE;
+
+	/* TODO: Shall we do memset for the original key info?? */
+	memset(pSharedKey, 0, sizeof(struct rt_cipher_key));
+	KeyLen = strlen(keyString);
+	switch (KeyLen) {
+	case 5:		/*wep 40 Ascii type */
+	case 13:		/*wep 104 Ascii type */
+		bKeyIsHex = FALSE;
+		pSharedKey->KeyLen = KeyLen;
+		NdisMoveMemory(pSharedKey->Key, keyString, KeyLen);
+		break;
+
+	case 10:		/*wep 40 Hex type */
+	case 26:		/*wep 104 Hex type */
+		for (i = 0; i < KeyLen; i++) {
+			if (!isxdigit(*(keyString + i)))
+				return FALSE;	/*Not Hex value; */
+		}
+		bKeyIsHex = TRUE;
+		pSharedKey->KeyLen = KeyLen / 2;
+		AtoH(keyString, pSharedKey->Key, pSharedKey->KeyLen);
+		break;
+
+	default:		/*Invalid argument */
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("RT_CfgSetWepKey(keyIdx=%d):Invalid argument (arg=%s)\n",
+			  keyIdx, keyString));
+		return FALSE;
+	}
+
+	pSharedKey->CipherAlg = ((KeyLen % 5) ? CIPHER_WEP128 : CIPHER_WEP64);
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("RT_CfgSetWepKey:(KeyIdx=%d,type=%s, Alg=%s)\n", keyIdx,
+		  (bKeyIsHex == FALSE ? "Ascii" : "Hex"),
+		  CipherName[CipherAlg]));
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set WPA PSK key
+
+    Arguments:
+        pAdapter	Pointer to our adapter
+        keyString	WPA pre-shared key string
+        pHashStr	String used for password hash function
+        hashStrLen	Lenght of the hash string
+        pPMKBuf		Output buffer of WPAPSK key
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+int RT_CfgSetWPAPSKKey(struct rt_rtmp_adapter *pAd,
+		       char *keyString,
+		       u8 * pHashStr,
+		       int hashStrLen, u8 *pPMKBuf)
+{
+	int keyLen;
+	u8 keyMaterial[40];
+
+	keyLen = strlen(keyString);
+	if ((keyLen < 8) || (keyLen > 64)) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("WPAPSK Key length(%d) error, required 8 ~ 64 characters!(keyStr=%s)\n",
+			  keyLen, keyString));
+		return FALSE;
+	}
+
+	memset(pPMKBuf, 0, 32);
+	if (keyLen == 64) {
+		AtoH(keyString, pPMKBuf, 32);
+	} else {
+		PasswordHash(keyString, pHashStr, hashStrLen, keyMaterial);
+		NdisMoveMemory(pPMKBuf, keyMaterial, 32);
+	}
+
+	return TRUE;
+}
diff --git a/drivers/staging/rt2860/common/cmm_data.c b/drivers/staging/rt2860/common/cmm_data.c
index 774fabb..68263ce 100644
--- a/drivers/staging/rt2860/common/cmm_data.c
+++ b/drivers/staging/rt2860/common/cmm_data.c
@@ -27,50 +27,58 @@
 
 #include "../rt_config.h"
 
-#define MAX_TX_IN_TBTT		(16)
+u8 SNAP_802_1H[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
+u8 SNAP_BRIDGE_TUNNEL[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
 
+/* Add Cisco Aironet SNAP heade for CCX2 support */
+u8 SNAP_AIRONET[] = { 0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x00 };
+u8 CKIP_LLC_SNAP[] = { 0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02 };
+u8 EAPOL_LLC_SNAP[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e };
+u8 EAPOL[] = { 0x88, 0x8e };
+u8 TPID[] = { 0x81, 0x00 };	/* VLAN related */
 
-UCHAR	SNAP_802_1H[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
-UCHAR	SNAP_BRIDGE_TUNNEL[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};
-// Add Cisco Aironet SNAP heade for CCX2 support
-UCHAR	SNAP_AIRONET[] = {0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x00};
-UCHAR	CKIP_LLC_SNAP[] = {0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02};
-UCHAR	EAPOL_LLC_SNAP[]= {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e};
-UCHAR	EAPOL[] = {0x88, 0x8e};
-UCHAR   TPID[] = {0x81, 0x00}; /* VLAN related */
+u8 IPX[] = { 0x81, 0x37 };
+u8 APPLE_TALK[] = { 0x80, 0xf3 };
 
-UCHAR	IPX[] = {0x81, 0x37};
-UCHAR	APPLE_TALK[] = {0x80, 0xf3};
-UCHAR	RateIdToPlcpSignal[12] = {
-	 0, /* RATE_1 */	1, /* RATE_2 */ 	2, /* RATE_5_5 */	3, /* RATE_11 */	// see BBP spec
-	11, /* RATE_6 */   15, /* RATE_9 */    10, /* RATE_12 */   14, /* RATE_18 */	// see IEEE802.11a-1999 p.14
-	 9, /* RATE_24 */  13, /* RATE_36 */	8, /* RATE_48 */   12  /* RATE_54 */ }; // see IEEE802.11a-1999 p.14
+u8 RateIdToPlcpSignal[12] = {
+	0, /* RATE_1 */ 1, /* RATE_2 */ 2, /* RATE_5_5 */ 3,	/* RATE_11 *//* see BBP spec */
+	11, /* RATE_6 */ 15, /* RATE_9 */ 10, /* RATE_12 */ 14,	/* RATE_18 *//* see IEEE802.11a-1999 p.14 */
+	9, /* RATE_24 */ 13, /* RATE_36 */ 8, /* RATE_48 */ 12 /* RATE_54 */
+};				/* see IEEE802.11a-1999 p.14 */
 
-UCHAR	 OfdmSignalToRateId[16] = {
-	RATE_54,  RATE_54,	RATE_54,  RATE_54,	// OFDM PLCP Signal = 0,  1,  2,  3 respectively
-	RATE_54,  RATE_54,	RATE_54,  RATE_54,	// OFDM PLCP Signal = 4,  5,  6,  7 respectively
-	RATE_48,  RATE_24,	RATE_12,  RATE_6,	// OFDM PLCP Signal = 8,  9,  10, 11 respectively
-	RATE_54,  RATE_36,	RATE_18,  RATE_9,	// OFDM PLCP Signal = 12, 13, 14, 15 respectively
+u8 OfdmSignalToRateId[16] = {
+	RATE_54, RATE_54, RATE_54, RATE_54,	/* OFDM PLCP Signal = 0,  1,  2,  3 respectively */
+	RATE_54, RATE_54, RATE_54, RATE_54,	/* OFDM PLCP Signal = 4,  5,  6,  7 respectively */
+	RATE_48, RATE_24, RATE_12, RATE_6,	/* OFDM PLCP Signal = 8,  9,  10, 11 respectively */
+	RATE_54, RATE_36, RATE_18, RATE_9,	/* OFDM PLCP Signal = 12, 13, 14, 15 respectively */
 };
 
-UCHAR	 OfdmRateToRxwiMCS[12] = {
-	0,  0,	0,  0,
-	0,  1,	2,  3,	// OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3
-	4,  5,	6,  7,	// OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7
-};
-UCHAR	 RxwiMCSToOfdmRate[12] = {
-	RATE_6,  RATE_9,	RATE_12,  RATE_18,
-	RATE_24,  RATE_36,	RATE_48,  RATE_54,	// OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3
-	4,  5,	6,  7,	// OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7
+u8 OfdmRateToRxwiMCS[12] = {
+	0, 0, 0, 0,
+	0, 1, 2, 3,		/* OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3 */
+	4, 5, 6, 7,		/* OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7 */
 };
 
-char*   MCSToMbps[] = {"1Mbps","2Mbps","5.5Mbps","11Mbps","06Mbps","09Mbps","12Mbps","18Mbps","24Mbps","36Mbps","48Mbps","54Mbps","MM-0","MM-1","MM-2","MM-3","MM-4","MM-5","MM-6","MM-7","MM-8","MM-9","MM-10","MM-11","MM-12","MM-13","MM-14","MM-15","MM-32","ee1","ee2","ee3"};
+u8 RxwiMCSToOfdmRate[12] = {
+	RATE_6, RATE_9, RATE_12, RATE_18,
+	RATE_24, RATE_36, RATE_48, RATE_54,	/* OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3 */
+	4, 5, 6, 7,		/* OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7 */
+};
 
-UCHAR default_cwmin[]={CW_MIN_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1, CW_MIN_IN_BITS-2};
-UCHAR default_sta_aifsn[]={3,7,2,2};
+char *MCSToMbps[] =
+    { "1Mbps", "2Mbps", "5.5Mbps", "11Mbps", "06Mbps", "09Mbps", "12Mbps",
+"18Mbps", "24Mbps", "36Mbps", "48Mbps", "54Mbps", "MM-0", "MM-1", "MM-2", "MM-3",
+"MM-4", "MM-5", "MM-6", "MM-7", "MM-8", "MM-9", "MM-10", "MM-11", "MM-12", "MM-13",
+"MM-14", "MM-15", "MM-32", "ee1", "ee2", "ee3" };
 
-UCHAR MapUserPriorityToAccessCategory[8] = {QID_AC_BE, QID_AC_BK, QID_AC_BK, QID_AC_BE, QID_AC_VI, QID_AC_VI, QID_AC_VO, QID_AC_VO};
+u8 default_cwmin[] =
+    { CW_MIN_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS - 1, CW_MIN_IN_BITS - 2 };
+/*u8 default_cwmax[]={CW_MAX_IN_BITS, CW_MAX_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1}; */
+u8 default_sta_aifsn[] = { 3, 7, 2, 2 };
 
+u8 MapUserPriorityToAccessCategory[8] =
+    { QID_AC_BE, QID_AC_BK, QID_AC_BK, QID_AC_BE, QID_AC_VI, QID_AC_VI,
+QID_AC_VO, QID_AC_VO };
 
 /*
 	========================================================================
@@ -96,162 +104,119 @@
 
 	========================================================================
 */
-NDIS_STATUS MiniportMMRequest(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			QueIdx,
-	IN	PUCHAR			pData,
-	IN	UINT			Length)
+int MiniportMMRequest(struct rt_rtmp_adapter *pAd,
+			      u8 QueIdx, u8 *pData, u32 Length)
 {
-	PNDIS_PACKET	pPacket;
-	NDIS_STATUS  	Status = NDIS_STATUS_SUCCESS;
-	ULONG	 		FreeNum;
-#ifdef RT2860
-	unsigned long	IrqFlags = 0;
-#endif
-	UCHAR			IrqState;
-	UCHAR			rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
+	void *pPacket;
+	int Status = NDIS_STATUS_SUCCESS;
+	unsigned long FreeNum;
+	u8 rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE];	/*RTMP_HW_HDR_LEN]; */
+#ifdef RTMP_MAC_PCI
+	unsigned long IrqFlags = 0;
+	u8 IrqState;
+#endif /* RTMP_MAC_PCI // */
+	BOOLEAN bUseDataQ = FALSE;
+	int retryCnt = 0;
 
 	ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
 
-	QueIdx=3;
-
-	// 2860C use Tx Ring
-
+	if ((QueIdx & MGMT_USE_QUEUE_FLAG) == MGMT_USE_QUEUE_FLAG) {
+		bUseDataQ = TRUE;
+		QueIdx &= (~MGMT_USE_QUEUE_FLAG);
+	}
+#ifdef RTMP_MAC_PCI
+	/* 2860C use Tx Ring */
 	IrqState = pAd->irq_disabled;
-
-#ifdef RT2860
-	if ((pAd->MACVersion == 0x28600100) && (!IrqState))
+	if (pAd->MACVersion == 0x28600100) {
+		QueIdx = (bUseDataQ == TRUE ? QueIdx : 3);
+		bUseDataQ = TRUE;
+	}
+	if (bUseDataQ && (!IrqState))
 		RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-#endif
-	do
-	{
-		// Reset is in progress, stop immediately
-		if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
-			 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
-			 !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
-		{
+#endif /* RTMP_MAC_PCI // */
+
+	do {
+		/* Reset is in progress, stop immediately */
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
+		    RTMP_TEST_FLAG(pAd,
+				   fRTMP_ADAPTER_HALT_IN_PROGRESS |
+				   fRTMP_ADAPTER_NIC_NOT_EXIST)
+		    || !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) {
 			Status = NDIS_STATUS_FAILURE;
 			break;
 		}
-
-		// Check Free priority queue
-		// Since we use PBF Queue2 for management frame.  Its corresponding DMA ring should be using TxRing.
-
-		// 2860C use Tx Ring
-		if (pAd->MACVersion == 0x28600100)
-		{
+		/* Check Free priority queue */
+		/* Since we use PBF Queue2 for management frame.  Its corresponding DMA ring should be using TxRing. */
+#ifdef RTMP_MAC_PCI
+		if (bUseDataQ) {
+			retryCnt = MAX_DATAMM_RETRY;
+			/* free Tx(QueIdx) resources */
+			RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);
 			FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
-		}
-		else
+		} else
+#endif /* RTMP_MAC_PCI // */
 		{
 			FreeNum = GET_MGMTRING_FREENO(pAd);
 		}
 
-		if ((FreeNum > 0))
-		{
-			// We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870
+		if ((FreeNum > 0)) {
+			/* We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870 */
 			NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE));
-			Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE), pData, Length);
-			if (Status != NDIS_STATUS_SUCCESS)
-			{
-				DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
+			Status =
+			    RTMPAllocateNdisPacket(pAd, &pPacket,
+						   (u8 *)& rtmpHwHdr,
+						   (TXINFO_SIZE + TXWI_SIZE),
+						   pData, Length);
+			if (Status != NDIS_STATUS_SUCCESS) {
+				DBGPRINT(RT_DEBUG_WARN,
+					 ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
 				break;
 			}
+			/*pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK; */
+			/*pAd->CommonCfg.MlmeRate = RATE_2; */
 
-			//pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
-			//pAd->CommonCfg.MlmeRate = RATE_2;
-
-
-			Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
-			if (Status != NDIS_STATUS_SUCCESS)
+#ifdef RTMP_MAC_PCI
+			if (bUseDataQ) {
+				Status =
+				    MlmeDataHardTransmit(pAd, QueIdx, pPacket);
+				retryCnt--;
+			} else
+#endif /* RTMP_MAC_PCI // */
+				Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
+			if (Status == NDIS_STATUS_SUCCESS)
+				retryCnt = 0;
+			else
 				RTMPFreeNdisPacket(pAd, pPacket);
-		}
-		else
-		{
+		} else {
 			pAd->RalinkCounters.MgmtRingFullCount++;
-			DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n",
-										QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
+#ifdef RTMP_MAC_PCI
+			if (bUseDataQ) {
+				retryCnt--;
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("retryCnt %d\n", retryCnt));
+				if (retryCnt == 0) {
+					DBGPRINT(RT_DEBUG_ERROR,
+						 ("Qidx(%d), not enough space in DataRing, MgmtRingFullCount=%ld!\n",
+						  QueIdx,
+						  pAd->RalinkCounters.
+						  MgmtRingFullCount));
+				}
+			}
+#endif /* RTMP_MAC_PCI // */
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n",
+				  QueIdx,
+				  pAd->RalinkCounters.MgmtRingFullCount));
 		}
+	} while (retryCnt > 0);
 
-	} while (FALSE);
-
-#ifdef RT2860
-	// 2860C use Tx Ring
-	if ((pAd->MACVersion == 0x28600100) && (!IrqState))
+#ifdef RTMP_MAC_PCI
+	if (bUseDataQ && (!IrqState))
 		RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-#endif
-	return Status;
-}
-
-#ifdef RT2860
-NDIS_STATUS MiniportMMRequestUnlock(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			QueIdx,
-	IN	PUCHAR			pData,
-	IN	UINT			Length)
-{
-	PNDIS_PACKET	pPacket;
-	NDIS_STATUS  Status = NDIS_STATUS_SUCCESS;
-	ULONG	 FreeNum;
-	TXWI_STRUC		TXWI;
-	ULONG	SW_TX_IDX;
-	PTXD_STRUC		pTxD;
-
-	QueIdx = 3;
-	ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
-
-	do
-	{
-		// Reset is in progress, stop immediately
-		if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
-			 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
-			 !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
-		{
-			Status = NDIS_STATUS_FAILURE;
-			break;
-		}
-
-		// Check Free priority queue
-		// Since we use PBF Queue2 for management frame.  Its corresponding DMA ring should be using TxRing.
-		// 2860C use Tx Ring
-		if (pAd->MACVersion == 0x28600100)
-		{
-			FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
-			SW_TX_IDX = pAd->TxRing[QueIdx].TxCpuIdx;
-			pTxD  = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SW_TX_IDX].AllocVa;
-		}
-		else
-		{
-			FreeNum = GET_MGMTRING_FREENO(pAd);
-			SW_TX_IDX = pAd->MgmtRing.TxCpuIdx;
-			pTxD  = (PTXD_STRUC) pAd->MgmtRing.Cell[SW_TX_IDX].AllocVa;
-		}
-		if ((FreeNum > 0))
-		{
-			NdisZeroMemory(&TXWI, TXWI_SIZE);
-			Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&TXWI, TXWI_SIZE, pData, Length);
-			if (Status != NDIS_STATUS_SUCCESS)
-			{
-				DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
-				break;
-			}
-
-			Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
-			if (Status != NDIS_STATUS_SUCCESS)
-				RTMPFreeNdisPacket(pAd, pPacket);
-		}
-		else
-		{
-			pAd->RalinkCounters.MgmtRingFullCount++;
-			DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing\n", QueIdx));
-		}
-
-	} while (FALSE);
-
+#endif /* RTMP_MAC_PCI // */
 
 	return Status;
 }
-#endif
 
 /*
 	========================================================================
@@ -277,270 +242,85 @@
 
 	========================================================================
 */
-NDIS_STATUS MlmeHardTransmit(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			QueIdx,
-	IN	PNDIS_PACKET	pPacket)
+int MlmeHardTransmit(struct rt_rtmp_adapter *pAd,
+			     u8 QueIdx, void *pPacket)
 {
-	if (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
-	{
+	struct rt_packet_info PacketInfo;
+	u8 *pSrcBufVA;
+	u32 SrcBufLen;
+	struct rt_header_802_11 * pHeader_802_11;
+
+	if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
+	    ) {
 		return NDIS_STATUS_FAILURE;
 	}
 
-#ifdef RT2860
-	if ( pAd->MACVersion == 0x28600100 )
-		return MlmeHardTransmitTxRing(pAd,QueIdx,pPacket);
+	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
+	if (pSrcBufVA == NULL)
+		return NDIS_STATUS_FAILURE;
+
+	pHeader_802_11 = (struct rt_header_802_11 *) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE);
+
+#ifdef RTMP_MAC_PCI
+	if (pAd->MACVersion == 0x28600100)
+		return MlmeHardTransmitTxRing(pAd, QueIdx, pPacket);
 	else
-#endif
-		return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
+#endif /* RTMP_MAC_PCI // */
+		return MlmeHardTransmitMgmtRing(pAd, QueIdx, pPacket);
 
 }
 
-#ifdef RT2860
-NDIS_STATUS MlmeHardTransmitTxRing(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR	QueIdx,
-	IN	PNDIS_PACKET	pPacket)
+int MlmeHardTransmitMgmtRing(struct rt_rtmp_adapter *pAd,
+				     u8 QueIdx, void *pPacket)
 {
-	PACKET_INFO 	PacketInfo;
-	PUCHAR			pSrcBufVA;
-	UINT			SrcBufLen;
-	PTXD_STRUC		pTxD;
-	PHEADER_802_11	pHeader_802_11;
-	BOOLEAN 		bAckRequired, bInsertTimestamp;
-	ULONG			SrcBufPA;
-	UCHAR			MlmeRate;
-	ULONG			SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
-	PTXWI_STRUC 	pFirstTxWI;
-	ULONG	 FreeNum;
-	MAC_TABLE_ENTRY	*pMacEntry = NULL;
-
+	struct rt_packet_info PacketInfo;
+	u8 *pSrcBufVA;
+	u32 SrcBufLen;
+	struct rt_header_802_11 * pHeader_802_11;
+	BOOLEAN bAckRequired, bInsertTimestamp;
+	u8 MlmeRate;
+	struct rt_txwi * pFirstTxWI;
+	struct rt_mac_table_entry *pMacEntry = NULL;
+	u8 PID;
 
 	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
 
-	if (pSrcBufVA == NULL)
-	{
-		// The buffer shouldn't be NULL
-		return NDIS_STATUS_FAILURE;
-	}
-
-	// Make sure MGMT ring resource won't be used by other threads
-	//NdisAcquireSpinLock(&pAd->TxRingLock);
-
-	FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
-
-	if (FreeNum == 0)
-	{
-		//NdisReleaseSpinLock(&pAd->TxRingLock);
-		return NDIS_STATUS_FAILURE;
-	}
-
-	SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
-
-	pTxD  = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa;
-
-	if (pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket)
-	{
-		printk("MlmeHardTransmit Error\n");
-		return NDIS_STATUS_FAILURE;
-	}
-
-	// outgoing frame always wakeup PHY to prevent frame lost
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-		AsicForceWakeup(pAd, FROM_TX);
-
-	pFirstTxWI	=(PTXWI_STRUC)pSrcBufVA;
-
-	pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXWI_SIZE);
-	if (pHeader_802_11->Addr1[0] & 0x01)
-	{
-		MlmeRate = pAd->CommonCfg.BasicMlmeRate;
-	}
-	else
-	{
-		MlmeRate = pAd->CommonCfg.MlmeRate;
-	}
-
-	if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
-		(pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
-	{
-		pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
-	}
-
-	// Verify Mlme rate for a / g bands.
-	if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
-		MlmeRate = RATE_6;
-
-	//
-	// Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
-	// Snice it's been set to 0 while on MgtMacHeaderInit
-	// By the way this will cause frame to be send on PWR_SAVE failed.
-	//
-	//
-	// In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
-
-    // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
-	if (pHeader_802_11->FC.Type != BTYPE_DATA)
-    {
-    	if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) || !(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
-    	{
-    		pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
-    	}
-    	else
-    	{
-    		pHeader_802_11->FC.PwrMgmt = pAd->CommonCfg.bAPSDForcePowerSave;
-    	}
-    }
-
-	bInsertTimestamp = FALSE;
-	if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
-	{
-		bAckRequired = FALSE;
-	}
-	else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
-	{
-		if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
-		{
-			bAckRequired = FALSE;
-			pHeader_802_11->Duration = 0;
-		}
-		else
-		{
-			bAckRequired = TRUE;
-			pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
-			if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
-			{
-				bInsertTimestamp = TRUE;
-			}
-		}
-	}
-	pHeader_802_11->Sequence = pAd->Sequence++;
-	if (pAd->Sequence > 0xfff)
-		pAd->Sequence = 0;
-	// Before radar detection done, mgmt frame can not be sent but probe req
-	// Because we need to use probe req to trigger driver to send probe req in passive scan
-	if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
-		&& (pAd->CommonCfg.bIEEE80211H == 1)
-		&& (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
-		return (NDIS_STATUS_FAILURE);
-	}
-
-	//
-	// fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
-	// should always has only one ohysical buffer, and the whole frame size equals
-	// to the first scatter buffer size
-	//
-
-	// Initialize TX Descriptor
-	// For inter-frame gap, the number is for this frame and next frame
-	// For MLME rate, we will fix as 2Mb to match other vendor's implement
-
-// management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
-	// Only beacon use Nseq=TRUE. So here we use Nseq=FALSE.
-	if (pMacEntry == NULL)
-	{
-		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
-		0, RESERVED_WCID, (SrcBufLen - TXWI_SIZE), PID_MGMT, 0,  (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
-	}
-	else
-	{
-		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
-					bInsertTimestamp, FALSE, bAckRequired, FALSE,
-					0, pMacEntry->Aid, (SrcBufLen - TXWI_SIZE),
-					pMacEntry->MaxHTPhyMode.field.MCS, 0,
-					(UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
-					IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
-	}
-
-	pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket;
-	pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL;
-
-	SrcBufPA = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
-
-
-	RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_EDCA);
-	pTxD->LastSec0 = 1;
-	pTxD->LastSec1 = 1;
-	pTxD->SDLen0 = SrcBufLen;
-	pTxD->SDLen1 = 0;
-	pTxD->SDPtr0 = SrcBufPA;
-	pTxD->DMADONE = 0;
-
-	pAd->RalinkCounters.KickTxCount++;
-	pAd->RalinkCounters.OneSecTxDoneCount++;
-
-   	// Increase TX_CTX_IDX, but write to register later.
-	INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE);
-
-	RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx*0x10,  pAd->TxRing[QueIdx].TxCpuIdx);
-
-	return NDIS_STATUS_SUCCESS;
-}
-#endif /* RT2860 */
-
-NDIS_STATUS MlmeHardTransmitMgmtRing(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR	QueIdx,
-	IN	PNDIS_PACKET	pPacket)
-{
-	PACKET_INFO 	PacketInfo;
-	PUCHAR			pSrcBufVA;
-	UINT			SrcBufLen;
-	PHEADER_802_11	pHeader_802_11;
-	BOOLEAN 		bAckRequired, bInsertTimestamp;
-	UCHAR			MlmeRate;
-	PTXWI_STRUC 	pFirstTxWI;
-	MAC_TABLE_ENTRY	*pMacEntry = NULL;
-
-	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
-		RTMP_SEM_LOCK(&pAd->MgmtRingLock);
-
-
-	if (pSrcBufVA == NULL)
-	{
+	/* Make sure MGMT ring resource won't be used by other threads */
+	RTMP_SEM_LOCK(&pAd->MgmtRingLock);
+	if (pSrcBufVA == NULL) {
+		/* The buffer shouldn't be NULL */
 		RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
 		return NDIS_STATUS_FAILURE;
 	}
 
-	// outgoing frame always wakeup PHY to prevent frame lost
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-#ifdef RT2860
-		AsicForceWakeup(pAd, FROM_TX);
-#endif
-#ifdef RT2870
-		AsicForceWakeup(pAd, TRUE);
-#endif
-
-	pFirstTxWI = (PTXWI_STRUC)(pSrcBufVA +  TXINFO_SIZE);
-	pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); //TXWI_SIZE);
-
-	if (pHeader_802_11->Addr1[0] & 0x01)
 	{
-		MlmeRate = pAd->CommonCfg.BasicMlmeRate;
+		/* outgoing frame always wakeup PHY to prevent frame lost */
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+			AsicForceWakeup(pAd, TRUE);
 	}
-	else
-	{
+
+	pFirstTxWI = (struct rt_txwi *) (pSrcBufVA + TXINFO_SIZE);
+	pHeader_802_11 = (struct rt_header_802_11 *) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE);	/*TXWI_SIZE); */
+
+	if (pHeader_802_11->Addr1[0] & 0x01) {
+		MlmeRate = pAd->CommonCfg.BasicMlmeRate;
+	} else {
 		MlmeRate = pAd->CommonCfg.MlmeRate;
 	}
 
-	// Verify Mlme rate for a / g bands.
-	if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
+	/* Verify Mlme rate for a / g bands. */
+	if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6))	/* 11A band */
 		MlmeRate = RATE_6;
 
 	if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
-		(pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
-	{
+	    (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL)) {
 		pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
 	}
 
 	{
-		// Fixed W52 with Activity scan issue in ABG_MIXED and ABGN_MIXED mode.
+		/* Fixed W52 with Activity scan issue in ABG_MIXED and ABGN_MIXED mode. */
 		if (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED
-			|| pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED
-		)
-		{
+		    || pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) {
 			if (pAd->LatchRfRegs.Channel > 14)
 				pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
 			else
@@ -548,103 +328,121 @@
 		}
 	}
 
-	//
-	// Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
-	// Snice it's been set to 0 while on MgtMacHeaderInit
-	// By the way this will cause frame to be send on PWR_SAVE failed.
-	//
-	// pHeader_802_11->FC.PwrMgmt = 0; // (pAd->StaCfg.Psm == PWR_SAVE);
-	//
-	// In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
+	/* */
+	/* Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE) */
+	/* Snice it's been set to 0 while on MgtMacHeaderInit */
+	/* By the way this will cause frame to be send on PWR_SAVE failed. */
+	/* */
+	pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;	/* (pAd->StaCfg.Psm == PWR_SAVE); */
 
-    // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
-	if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL))
+	/* */
+	/* In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame */
+	/* Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD */
+/*      if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL)) */
 	{
-		if ((pAd->StaCfg.Psm == PWR_SAVE) &&
-			(pHeader_802_11->FC.SubType == SUBTYPE_ACTION))
-			pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
-		else
-			pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
+		if ((pHeader_802_11->FC.SubType == SUBTYPE_ACTION) ||
+		    ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
+		     ((pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL) ||
+		      (pHeader_802_11->FC.SubType == SUBTYPE_NULL_FUNC)))) {
+			if (pAd->StaCfg.Psm == PWR_SAVE)
+				pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
+			else
+				pHeader_802_11->FC.PwrMgmt =
+				    pAd->CommonCfg.bAPSDForcePowerSave;
+		}
 	}
 
 	bInsertTimestamp = FALSE;
-	if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
+	if (pHeader_802_11->FC.Type == BTYPE_CNTL)	/* must be PS-POLL */
 	{
-		//Set PM bit in ps-poll, to fix WLK 1.2  PowerSaveMode_ext failure issue.
-		if ((pAd->OpMode == OPMODE_STA) && (pHeader_802_11->FC.SubType == SUBTYPE_PS_POLL))
-		{
+		/*Set PM bit in ps-poll, to fix WLK 1.2  PowerSaveMode_ext failure issue. */
+		if ((pAd->OpMode == OPMODE_STA)
+		    && (pHeader_802_11->FC.SubType == SUBTYPE_PS_POLL)) {
 			pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
 		}
 		bAckRequired = FALSE;
-	}
-	else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
+	} else			/* BTYPE_MGMT or BTYPE_DATA(must be NULL frame) */
 	{
-		if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
+		/*pAd->Sequence++; */
+		/*pHeader_802_11->Sequence = pAd->Sequence; */
+
+		if (pHeader_802_11->Addr1[0] & 0x01)	/* MULTICAST, BROADCAST */
 		{
 			bAckRequired = FALSE;
 			pHeader_802_11->Duration = 0;
-		}
-		else
-		{
+		} else {
 			bAckRequired = TRUE;
-			pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
-			if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
-			{
+			pHeader_802_11->Duration =
+			    RTMPCalcDuration(pAd, MlmeRate, 14);
+			if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
+			    && (pHeader_802_11->FC.Type == BTYPE_MGMT)) {
 				bInsertTimestamp = TRUE;
+				bAckRequired = FALSE;	/* Disable ACK to prevent retry 0x1f for Probe Response */
+			} else
+			    if ((pHeader_802_11->FC.SubType ==
+				 SUBTYPE_PROBE_REQ)
+				&& (pHeader_802_11->FC.Type == BTYPE_MGMT)) {
+				bAckRequired = FALSE;	/* Disable ACK to prevent retry 0x1f for Probe Request */
 			}
 		}
 	}
 
 	pHeader_802_11->Sequence = pAd->Sequence++;
-	if (pAd->Sequence >0xfff)
+	if (pAd->Sequence > 0xfff)
 		pAd->Sequence = 0;
 
-	// Before radar detection done, mgmt frame can not be sent but probe req
-	// Because we need to use probe req to trigger driver to send probe req in passive scan
+	/* Before radar detection done, mgmt frame can not be sent but probe req */
+	/* Because we need to use probe req to trigger driver to send probe req in passive scan */
 	if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
-		&& (pAd->CommonCfg.bIEEE80211H == 1)
-		&& (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
+	    && (pAd->CommonCfg.bIEEE80211H == 1)
+	    && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("MlmeHardTransmit --> radar detect not in normal mode!\n"));
+/*              if (!IrqState) */
 		RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
 		return (NDIS_STATUS_FAILURE);
 	}
 
-	//
-	// fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
-	// should always has only one ohysical buffer, and the whole frame size equals
-	// to the first scatter buffer size
-	//
+	/* */
+	/* fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET */
+	/* should always has only one physical buffer, and the whole frame size equals */
+	/* to the first scatter buffer size */
+	/* */
 
-	// Initialize TX Descriptor
-	// For inter-frame gap, the number is for this frame and next frame
-	// For MLME rate, we will fix as 2Mb to match other vendor's implement
+	/* Initialize TX Descriptor */
+	/* For inter-frame gap, the number is for this frame and next frame */
+	/* For MLME rate, we will fix as 2Mb to match other vendor's implement */
+/*      pAd->CommonCfg.MlmeTransmit.field.MODE = 1; */
 
-// management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
-	if (pMacEntry == NULL)
-	{
-		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
-		0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID_MGMT, 0,  (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
-	}
-	else
-	{
+/* management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not. */
+	PID = PID_MGMT;
+
+	if (pMacEntry == NULL) {
+		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp,
+			      FALSE, bAckRequired, FALSE, 0, RESERVED_WCID,
+			      (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID, 0,
+			      (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
+			      IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
+	} else {
+		/* dont use low rate to send QoS Null data frame */
 		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
-					bInsertTimestamp, FALSE, bAckRequired, FALSE,
-					0, pMacEntry->Aid, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE),
-					pMacEntry->MaxHTPhyMode.field.MCS, 0,
-					(UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
-					IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
+			      bInsertTimestamp, FALSE, bAckRequired, FALSE,
+			      0, pMacEntry->Aid,
+			      (SrcBufLen - TXINFO_SIZE - TXWI_SIZE),
+			      pMacEntry->MaxHTPhyMode.field.MCS, 0,
+			      (u8)pMacEntry->MaxHTPhyMode.field.MCS,
+			      IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
 	}
 
-	// Now do hardware-depened kick out.
+	/* Now do hardware-depened kick out. */
 	HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen);
 
-	// Make sure to release MGMT ring resource
+	/* Make sure to release MGMT ring resource */
+/*      if (!IrqState) */
 	RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
 	return NDIS_STATUS_SUCCESS;
 }
 
-
 /********************************************************************************
 
 	New DeQueue Procedures.
@@ -708,178 +506,153 @@
 								(2).Normal
 	========================================================================
 */
-static UCHAR TxPktClassification(
-	IN RTMP_ADAPTER *pAd,
-	IN PNDIS_PACKET  pPacket)
+static u8 TxPktClassification(struct rt_rtmp_adapter *pAd, void *pPacket)
 {
-	UCHAR			TxFrameType = TX_UNKOWN_FRAME;
-	UCHAR			Wcid;
-	MAC_TABLE_ENTRY	*pMacEntry = NULL;
-	BOOLEAN			bHTRate = FALSE;
+	u8 TxFrameType = TX_UNKOWN_FRAME;
+	u8 Wcid;
+	struct rt_mac_table_entry *pMacEntry = NULL;
+	BOOLEAN bHTRate = FALSE;
 
 	Wcid = RTMP_GET_PACKET_WCID(pPacket);
-	if (Wcid == MCAST_WCID)
-	{	// Handle for RA is Broadcast/Multicast Address.
+	if (Wcid == MCAST_WCID) {	/* Handle for RA is Broadcast/Multicast Address. */
 		return TX_MCAST_FRAME;
 	}
-
-	// Handle for unicast packets
+	/* Handle for unicast packets */
 	pMacEntry = &pAd->MacTab.Content[Wcid];
-	if (RTMP_GET_PACKET_LOWRATE(pPacket))
-	{	// It's a specific packet need to force low rate, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame
+	if (RTMP_GET_PACKET_LOWRATE(pPacket)) {	/* It's a specific packet need to force low rate, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame */
 		TxFrameType = TX_LEGACY_FRAME;
-	}
-	else if (IS_HT_RATE(pMacEntry))
-	{	// it's a 11n capable packet
+	} else if (IS_HT_RATE(pMacEntry)) {	/* it's a 11n capable packet */
 
-		// Depends on HTPhyMode to check if the peer support the HTRate transmission.
-		// 	Currently didn't support A-MSDU embedded in A-MPDU
+		/* Depends on HTPhyMode to check if the peer support the HTRate transmission. */
+		/*      Currently didn't support A-MSDU embedded in A-MPDU */
 		bHTRate = TRUE;
-		if (RTMP_GET_PACKET_MOREDATA(pPacket) || (pMacEntry->PsMode == PWR_SAVE))
+		if (RTMP_GET_PACKET_MOREDATA(pPacket)
+		    || (pMacEntry->PsMode == PWR_SAVE))
 			TxFrameType = TX_LEGACY_FRAME;
-#ifdef UAPSD_AP_SUPPORT
-		else if (RTMP_GET_PACKET_EOSP(pPacket))
-			TxFrameType = TX_LEGACY_FRAME;
-#endif // UAPSD_AP_SUPPORT //
-		else if((pMacEntry->TXBAbitmap & (1<<(RTMP_GET_PACKET_UP(pPacket)))) != 0)
+		else if ((pMacEntry->
+			  TXBAbitmap & (1 << (RTMP_GET_PACKET_UP(pPacket)))) !=
+			 0)
 			return TX_AMPDU_FRAME;
-		else if(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AMSDU_INUSED))
+		else if (CLIENT_STATUS_TEST_FLAG
+			 (pMacEntry, fCLIENT_STATUS_AMSDU_INUSED))
 			return TX_AMSDU_FRAME;
 		else
 			TxFrameType = TX_LEGACY_FRAME;
-	}
-	else
-	{	// it's a legacy b/g packet.
-		if ((CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE) && pAd->CommonCfg.bAggregationCapable) &&
-			(RTMP_GET_PACKET_TXRATE(pPacket) >= RATE_6) &&
-			(!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
-		{	// if peer support Ralink Aggregation, we use it.
+	} else {		/* it's a legacy b/g packet. */
+		if ((CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE) && pAd->CommonCfg.bAggregationCapable) && (RTMP_GET_PACKET_TXRATE(pPacket) >= RATE_6) && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE)))) {	/* if peer support Ralink Aggregation, we use it. */
 			TxFrameType = TX_RALINK_FRAME;
-		}
-		else
-		{
+		} else {
 			TxFrameType = TX_LEGACY_FRAME;
 		}
 	}
 
-	// Currently, our fragment only support when a unicast packet send as NOT-ARALINK, NOT-AMSDU and NOT-AMPDU.
-	if ((RTMP_GET_PACKET_FRAGMENTS(pPacket) > 1) && (TxFrameType == TX_LEGACY_FRAME))
+	/* Currently, our fragment only support when a unicast packet send as NOT-ARALINK, NOT-AMSDU and NOT-AMPDU. */
+	if ((RTMP_GET_PACKET_FRAGMENTS(pPacket) > 1)
+	    && (TxFrameType == TX_LEGACY_FRAME))
 		TxFrameType = TX_FRAG_FRAME;
 
 	return TxFrameType;
 }
 
-
-BOOLEAN RTMP_FillTxBlkInfo(
-	IN RTMP_ADAPTER *pAd,
-	IN TX_BLK *pTxBlk)
+BOOLEAN RTMP_FillTxBlkInfo(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
 {
-	PACKET_INFO			PacketInfo;
-	PNDIS_PACKET		pPacket;
-	PMAC_TABLE_ENTRY	pMacEntry = NULL;
+	struct rt_packet_info PacketInfo;
+	void *pPacket;
+	struct rt_mac_table_entry *pMacEntry = NULL;
 
 	pPacket = pTxBlk->pPacket;
-	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
+	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader,
+			     &pTxBlk->SrcBufLen);
 
-	pTxBlk->Wcid	 	 		= RTMP_GET_PACKET_WCID(pPacket);
-	pTxBlk->apidx		 		= RTMP_GET_PACKET_IF(pPacket);
-	pTxBlk->UserPriority 		= RTMP_GET_PACKET_UP(pPacket);
-	pTxBlk->FrameGap = IFS_HTTXOP;		// ASIC determine Frame Gap
+	pTxBlk->Wcid = RTMP_GET_PACKET_WCID(pPacket);
+	pTxBlk->apidx = RTMP_GET_PACKET_IF(pPacket);
+	pTxBlk->UserPriority = RTMP_GET_PACKET_UP(pPacket);
+	pTxBlk->FrameGap = IFS_HTTXOP;	/* ASIC determine Frame Gap */
 
 	if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pTxBlk->pPacket))
 		TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame);
 	else
 		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bClearEAPFrame);
 
-	// Default to clear this flag
+	/* Default to clear this flag */
 	TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bForceNonQoS);
 
-
-	if (pTxBlk->Wcid == MCAST_WCID)
-	{
+	if (pTxBlk->Wcid == MCAST_WCID) {
 		pTxBlk->pMacEntry = NULL;
 		{
-#ifdef MCAST_RATE_SPECIFIC
-			PUCHAR pDA = GET_OS_PKT_DATAPTR(pPacket);
-			if (((*pDA & 0x01) == 0x01) && (*pDA != 0xff))
-				pTxBlk->pTransmit = &pAd->CommonCfg.MCastPhyMode;
-			else
-#endif // MCAST_RATE_SPECIFIC //
-				pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
+			pTxBlk->pTransmit =
+			    &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
 		}
 
-		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);	// AckRequired = FALSE, when broadcast packet in Adhoc mode.
-		//TX_BLK_SET_FLAG(pTxBlk, fTX_bForceLowRate);
+		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);	/* AckRequired = FALSE, when broadcast packet in Adhoc mode. */
+		/*TX_BLK_SET_FLAG(pTxBlk, fTX_bForceLowRate); */
 		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAllowFrag);
 		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
-		if (RTMP_GET_PACKET_MOREDATA(pPacket))
-		{
+		if (RTMP_GET_PACKET_MOREDATA(pPacket)) {
 			TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
 		}
 
-	}
-	else
-	{
+	} else {
 		pTxBlk->pMacEntry = &pAd->MacTab.Content[pTxBlk->Wcid];
 		pTxBlk->pTransmit = &pTxBlk->pMacEntry->HTPhyMode;
 
 		pMacEntry = pTxBlk->pMacEntry;
 
-
-		// For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK.
+		/* For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK. */
 		if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx] != NORMAL_ACK)
 			TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
 		else
 			TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired);
 
-		{
-			// If support WMM, enable it.
-#ifdef RT2860
-			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
-#endif
-#ifdef RT2870
-			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
-				CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))
-#endif
-				TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM);
+		if ((pAd->OpMode == OPMODE_STA) &&
+		    (ADHOC_ON(pAd)) &&
+		    (RX_FILTER_TEST_FLAG(pAd, fRX_FILTER_ACCEPT_PROMISCUOUS))) {
+			if (pAd->CommonCfg.PSPXlink)
+				TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
 		}
 
-		if (pTxBlk->TxFrameType == TX_LEGACY_FRAME)
 		{
-			if ( (RTMP_GET_PACKET_LOWRATE(pPacket)) ||
-                ((pAd->OpMode == OPMODE_AP) && (pMacEntry->MaxHTPhyMode.field.MODE == MODE_CCK) && (pMacEntry->MaxHTPhyMode.field.MCS == RATE_1)))
-			{	// Specific packet, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame, need force low rate.
-				pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
+			{
 
-				// Modify the WMM bit for ICV issue. If we have a packet with EOSP field need to set as 1, how to handle it???
+				/* If support WMM, enable it. */
+				if (OPSTATUS_TEST_FLAG
+				    (pAd, fOP_STATUS_WMM_INUSED)
+				    && CLIENT_STATUS_TEST_FLAG(pMacEntry,
+							       fCLIENT_STATUS_WMM_CAPABLE))
+					TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM);
+
+/*                              if (pAd->StaCfg.bAutoTxRateSwitch) */
+/*                                      TX_BLK_SET_FLAG(pTxBlk, fTX_AutoRateSwitch); */
+			}
+		}
+
+		if (pTxBlk->TxFrameType == TX_LEGACY_FRAME) {
+			if ((RTMP_GET_PACKET_LOWRATE(pPacket)) || ((pAd->OpMode == OPMODE_AP) && (pMacEntry->MaxHTPhyMode.field.MODE == MODE_CCK) && (pMacEntry->MaxHTPhyMode.field.MCS == RATE_1))) {	/* Specific packet, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame, need force low rate. */
+				pTxBlk->pTransmit =
+				    &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
+
+				/* Modify the WMM bit for ICV issue. If we have a packet with EOSP field need to set as 1, how to handle it??? */
 				if (IS_HT_STA(pTxBlk->pMacEntry) &&
-					(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET)) &&
-					((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RDG_CAPABLE)))
+				    (CLIENT_STATUS_TEST_FLAG
+				     (pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET))
+				    && ((pAd->CommonCfg.bRdg == TRUE)
+					&& CLIENT_STATUS_TEST_FLAG(pMacEntry,
+								   fCLIENT_STATUS_RDG_CAPABLE)))
 				{
 					TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
-					TX_BLK_SET_FLAG(pTxBlk, fTX_bForceNonQoS);
+					TX_BLK_SET_FLAG(pTxBlk,
+							fTX_bForceNonQoS);
 				}
 			}
 
-			if ( (IS_HT_RATE(pMacEntry) == FALSE) &&
-				(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE)))
-			{	// Currently piggy-back only support when peer is operate in b/g mode.
+			if ((IS_HT_RATE(pMacEntry) == FALSE) && (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE))) {	/* Currently piggy-back only support when peer is operate in b/g mode. */
 				TX_BLK_SET_FLAG(pTxBlk, fTX_bPiggyBack);
 			}
 
-			if (RTMP_GET_PACKET_MOREDATA(pPacket))
-			{
+			if (RTMP_GET_PACKET_MOREDATA(pPacket)) {
 				TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
 			}
-#ifdef UAPSD_AP_SUPPORT
-			if (RTMP_GET_PACKET_EOSP(pPacket))
-			{
-				TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP);
-			}
-#endif // UAPSD_AP_SUPPORT //
-		}
-		else if (pTxBlk->TxFrameType == TX_FRAG_FRAME)
-		{
+		} else if (pTxBlk->TxFrameType == TX_FRAG_FRAME) {
 			TX_BLK_SET_FLAG(pTxBlk, fTX_bAllowFrag);
 		}
 
@@ -889,41 +662,33 @@
 	return TRUE;
 }
 
-
-BOOLEAN CanDoAggregateTransmit(
-	IN RTMP_ADAPTER *pAd,
-	IN NDIS_PACKET *pPacket,
-	IN TX_BLK		*pTxBlk)
+BOOLEAN CanDoAggregateTransmit(struct rt_rtmp_adapter *pAd,
+			       char * pPacket, struct rt_tx_blk *pTxBlk)
 {
 
-	//printk("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType);
+	/*DBGPRINT(RT_DEBUG_TRACE, ("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType)); */
 
 	if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID)
 		return FALSE;
 
 	if (RTMP_GET_PACKET_DHCP(pPacket) ||
-		RTMP_GET_PACKET_EAPOL(pPacket) ||
-		RTMP_GET_PACKET_WAI(pPacket))
+	    RTMP_GET_PACKET_EAPOL(pPacket) || RTMP_GET_PACKET_WAI(pPacket))
 		return FALSE;
 
-	if ((pTxBlk->TxFrameType == TX_AMSDU_FRAME) &&
-		((pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))> (RX_BUFFER_AGGRESIZE - 100)))
-	{	// For AMSDU, allow the packets with total length < max-amsdu size
+	if ((pTxBlk->TxFrameType == TX_AMSDU_FRAME) && ((pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket)) > (RX_BUFFER_AGGRESIZE - 100))) {	/* For AMSDU, allow the packets with total length < max-amsdu size */
 		return FALSE;
 	}
 
-	if ((pTxBlk->TxFrameType == TX_RALINK_FRAME) &&
-		(pTxBlk->TxPacketList.Number == 2))
-	{	// For RALINK-Aggregation, allow two frames in one batch.
+	if ((pTxBlk->TxFrameType == TX_RALINK_FRAME) && (pTxBlk->TxPacketList.Number == 2)) {	/* For RALINK-Aggregation, allow two frames in one batch. */
 		return FALSE;
 	}
 
-	if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) // must be unicast to AP
+	if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))	/* must be unicast to AP */
 		return TRUE;
 	else
 		return FALSE;
-}
 
+}
 
 /*
 	========================================================================
@@ -947,53 +712,42 @@
 
 	========================================================================
 */
-VOID RTMPDeQueuePacket(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  BOOLEAN         bIntContext,
-	IN  UCHAR			QIdx, /* BulkOutPipeId */
-	IN  UCHAR           Max_Tx_Packets)
+void RTMPDeQueuePacket(struct rt_rtmp_adapter *pAd, IN BOOLEAN bIntContext, u8 QIdx,	/* BulkOutPipeId */
+		       u8 Max_Tx_Packets)
 {
-	PQUEUE_ENTRY    pEntry = NULL;
-	PNDIS_PACKET 	pPacket;
-	NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;
-	UCHAR           Count=0;
-	PQUEUE_HEADER   pQueue;
-	ULONG           FreeNumber[NUM_OF_TX_RING];
-	UCHAR			QueIdx, sQIdx, eQIdx;
-	unsigned long	IrqFlags = 0;
-	BOOLEAN			hasTxDesc = FALSE;
-	TX_BLK			TxBlk;
-	TX_BLK			*pTxBlk;
+	struct rt_queue_entry *pEntry = NULL;
+	void *pPacket;
+	int Status = NDIS_STATUS_SUCCESS;
+	u8 Count = 0;
+	struct rt_queue_header *pQueue;
+	unsigned long FreeNumber[NUM_OF_TX_RING];
+	u8 QueIdx, sQIdx, eQIdx;
+	unsigned long IrqFlags = 0;
+	BOOLEAN hasTxDesc = FALSE;
+	struct rt_tx_blk TxBlk;
+	struct rt_tx_blk *pTxBlk;
 
-
-
-	if (QIdx == NUM_OF_TX_RING)
-	{
+	if (QIdx == NUM_OF_TX_RING) {
 		sQIdx = 0;
-//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
-		eQIdx = 3;	// 4 ACs, start from 0.
-	}
-	else
-	{
+		eQIdx = 3;	/* 4 ACs, start from 0. */
+	} else {
 		sQIdx = eQIdx = QIdx;
 	}
 
-	for (QueIdx=sQIdx; QueIdx <= eQIdx; QueIdx++)
-	{
-		Count=0;
+	for (QueIdx = sQIdx; QueIdx <= eQIdx; QueIdx++) {
+		Count = 0;
 
-		RT28XX_START_DEQUEUE(pAd, QueIdx, IrqFlags);
+		RTMP_START_DEQUEUE(pAd, QueIdx, IrqFlags);
 
-
-		while (1)
-		{
-			if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS |
-										fRTMP_ADAPTER_RADIO_OFF |
-										fRTMP_ADAPTER_RESET_IN_PROGRESS |
-										fRTMP_ADAPTER_HALT_IN_PROGRESS |
-										fRTMP_ADAPTER_NIC_NOT_EXIST))))
-			{
-				RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
+		while (1) {
+			if ((RTMP_TEST_FLAG
+			     (pAd,
+			      (fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS |
+			       fRTMP_ADAPTER_RADIO_OFF |
+			       fRTMP_ADAPTER_RESET_IN_PROGRESS |
+			       fRTMP_ADAPTER_HALT_IN_PROGRESS |
+			       fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
+				RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
 				return;
 			}
 
@@ -1001,43 +755,47 @@
 				break;
 
 			DEQUEUE_LOCK(&pAd->irq_lock, bIntContext, IrqFlags);
-			if (&pAd->TxSwQueue[QueIdx] == NULL)
-			{
-				DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+			if (&pAd->TxSwQueue[QueIdx] == NULL) {
+				DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext,
+					       IrqFlags);
 				break;
 			}
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
 			FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
 
-
-			if (FreeNumber[QueIdx] <= 5)
-			{
-				// free Tx(QueIdx) resources
+			if (FreeNumber[QueIdx] <= 5) {
+				/* free Tx(QueIdx) resources */
 				RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);
-				FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
+				FreeNumber[QueIdx] =
+				    GET_TXRING_FREENO(pAd, QueIdx);
 			}
-#endif /* RT2860 */
-			// probe the Queue Head
+#endif /* RTMP_MAC_PCI // */
+
+			/* probe the Queue Head */
 			pQueue = &pAd->TxSwQueue[QueIdx];
-			if ((pEntry = pQueue->Head) == NULL)
-			{
-				DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+			if ((pEntry = pQueue->Head) == NULL) {
+				DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext,
+					       IrqFlags);
 				break;
 			}
 
 			pTxBlk = &TxBlk;
-			NdisZeroMemory((PUCHAR)pTxBlk, sizeof(TX_BLK));
+			NdisZeroMemory((u8 *)pTxBlk, sizeof(struct rt_tx_blk));
+			/*InitializeQueueHeader(&pTxBlk->TxPacketList);         // Didn't need it because we already memzero it. */
 			pTxBlk->QueIdx = QueIdx;
 
-			pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
+			pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
 
-			// Early check to make sure we have enoguh Tx Resource.
-			hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
-			if (!hasTxDesc)
-			{
+			/* Early check to make sure we have enoguh Tx Resource. */
+			hasTxDesc =
+			    RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk,
+						      FreeNumber[QueIdx],
+						      pPacket);
+			if (!hasTxDesc) {
 				pAd->PrivateInfo.TxRingFullCnt++;
 
-				DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+				DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext,
+					       IrqFlags);
 
 				break;
 			}
@@ -1045,74 +803,89 @@
 			pTxBlk->TxFrameType = TxPktClassification(pAd, pPacket);
 			pEntry = RemoveHeadQueue(pQueue);
 			pTxBlk->TotalFrameNum++;
-			pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket);	// The real fragment number maybe vary
+			pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket);	/* The real fragment number maybe vary */
 			pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
 			pTxBlk->pPacket = pPacket;
-			InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
+			InsertTailQueue(&pTxBlk->TxPacketList,
+					PACKET_TO_QUEUE_ENTRY(pPacket));
 
-			if (pTxBlk->TxFrameType == TX_RALINK_FRAME || pTxBlk->TxFrameType == TX_AMSDU_FRAME)
-			{
-				// Enhance SW Aggregation Mechanism
-				if (NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, FreeNumber[QueIdx], pTxBlk->TxFrameType))
-				{
-					InsertHeadQueue(pQueue, PACKET_TO_QUEUE_ENTRY(pPacket));
-					DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+			if (pTxBlk->TxFrameType == TX_RALINK_FRAME
+			    || pTxBlk->TxFrameType == TX_AMSDU_FRAME) {
+				/* Enhance SW Aggregation Mechanism */
+				if (NEED_QUEUE_BACK_FOR_AGG
+				    (pAd, QueIdx, FreeNumber[QueIdx],
+				     pTxBlk->TxFrameType)) {
+					InsertHeadQueue(pQueue,
+							PACKET_TO_QUEUE_ENTRY
+							(pPacket));
+					DEQUEUE_UNLOCK(&pAd->irq_lock,
+						       bIntContext, IrqFlags);
 					break;
 				}
 
-				do{
-					if((pEntry = pQueue->Head) == NULL)
+				do {
+					if ((pEntry = pQueue->Head) == NULL)
 						break;
 
-					// For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation.
-					pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
-					FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
-					hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
-					if ((hasTxDesc == FALSE) || (CanDoAggregateTransmit(pAd, pPacket, pTxBlk) == FALSE))
+					/* For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation. */
+					pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
+					FreeNumber[QueIdx] =
+					    GET_TXRING_FREENO(pAd, QueIdx);
+					hasTxDesc =
+					    RTMP_HAS_ENOUGH_FREE_DESC(pAd,
+								      pTxBlk,
+								      FreeNumber
+								      [QueIdx],
+								      pPacket);
+					if ((hasTxDesc == FALSE)
+					    ||
+					    (CanDoAggregateTransmit
+					     (pAd, pPacket, pTxBlk) == FALSE))
 						break;
 
-					//Remove the packet from the TxSwQueue and insert into pTxBlk
+					/*Remove the packet from the TxSwQueue and insert into pTxBlk */
 					pEntry = RemoveHeadQueue(pQueue);
 					ASSERT(pEntry);
-					pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
+					pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
 					pTxBlk->TotalFrameNum++;
-					pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket);	// The real fragment number maybe vary
-					pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
-					InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
-				}while(1);
+					pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket);	/* The real fragment number maybe vary */
+					pTxBlk->TotalFrameLen +=
+					    GET_OS_PKT_LEN(pPacket);
+					InsertTailQueue(&pTxBlk->TxPacketList,
+							PACKET_TO_QUEUE_ENTRY
+							(pPacket));
+				} while (1);
 
 				if (pTxBlk->TxPacketList.Number == 1)
 					pTxBlk->TxFrameType = TX_LEGACY_FRAME;
 			}
-
-#ifdef RT2870
+#ifdef RTMP_MAC_USB
 			DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
-#endif // RT2870 //
-
+#endif /* RTMP_MAC_USB // */
 			Count += pTxBlk->TxPacketList.Number;
 
-			// Do HardTransmit now.
+			/* Do HardTransmit now. */
 			Status = STAHardTransmit(pAd, pTxBlk, QueIdx);
 
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
 			DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
-			// static rate also need NICUpdateFifoStaCounters() function.
-			//if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
-				NICUpdateFifoStaCounters(pAd);
-#endif
+			/* static rate also need NICUpdateFifoStaCounters() function. */
+			/*if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */
+			NICUpdateFifoStaCounters(pAd);
+#endif /* RTMP_MAC_PCI // */
+
 		}
 
-		RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
+		RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
 
-#ifdef RT2870
+#ifdef RTMP_MAC_USB
 		if (!hasTxDesc)
 			RTUSBKickBulkOut(pAd);
-#endif // RT2870 //
+#endif /* RTMP_MAC_USB // */
 	}
 
 }
 
-
 /*
 	========================================================================
 
@@ -1135,40 +908,37 @@
 
 	========================================================================
 */
-USHORT	RTMPCalcDuration(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Rate,
-	IN	ULONG			Size)
+u16 RTMPCalcDuration(struct rt_rtmp_adapter *pAd, u8 Rate, unsigned long Size)
 {
-	ULONG	Duration = 0;
+	unsigned long Duration = 0;
 
-	if (Rate < RATE_FIRST_OFDM_RATE) // CCK
+	if (Rate < RATE_FIRST_OFDM_RATE)	/* CCK */
 	{
-		if ((Rate > RATE_1) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED))
-			Duration = 96;	// 72+24 preamble+plcp
+		if ((Rate > RATE_1)
+		    && OPSTATUS_TEST_FLAG(pAd,
+					  fOP_STATUS_SHORT_PREAMBLE_INUSED))
+			Duration = 96;	/* 72+24 preamble+plcp */
 		else
-			Duration = 192; // 144+48 preamble+plcp
+			Duration = 192;	/* 144+48 preamble+plcp */
 
-		Duration += (USHORT)((Size << 4) / RateIdTo500Kbps[Rate]);
+		Duration += (u16)((Size << 4) / RateIdTo500Kbps[Rate]);
 		if ((Size << 4) % RateIdTo500Kbps[Rate])
-			Duration ++;
-	}
-	else if (Rate <= RATE_LAST_OFDM_RATE)// OFDM rates
+			Duration++;
+	} else if (Rate <= RATE_LAST_OFDM_RATE)	/* OFDM rates */
 	{
-		Duration = 20 + 6;		// 16+4 preamble+plcp + Signal Extension
-		Duration += 4 * (USHORT)((11 + Size * 4) / RateIdTo500Kbps[Rate]);
+		Duration = 20 + 6;	/* 16+4 preamble+plcp + Signal Extension */
+		Duration +=
+		    4 * (u16)((11 + Size * 4) / RateIdTo500Kbps[Rate]);
 		if ((11 + Size * 4) % RateIdTo500Kbps[Rate])
 			Duration += 4;
-	}
-	else	//mimo rate
+	} else			/*mimo rate */
 	{
-		Duration = 20 + 6;		// 16+4 preamble+plcp + Signal Extension
+		Duration = 20 + 6;	/* 16+4 preamble+plcp + Signal Extension */
 	}
 
-	return (USHORT)Duration;
+	return (u16)Duration;
 }
 
-
 /*
 	========================================================================
 
@@ -1194,58 +964,53 @@
 	IRQL = PASSIVE_LEVEL
 	IRQL = DISPATCH_LEVEL
 
-    See also : BASmartHardTransmit()    !!!
+    See also : BASmartHardTransmit()    !
 
 	========================================================================
 */
-VOID RTMPWriteTxWI(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PTXWI_STRUC 	pOutTxWI,
-	IN	BOOLEAN			FRAG,
-	IN	BOOLEAN			CFACK,
-	IN	BOOLEAN			InsTimestamp,
-	IN	BOOLEAN 		AMPDU,
-	IN	BOOLEAN 		Ack,
-	IN	BOOLEAN 		NSeq,		// HW new a sequence.
-	IN	UCHAR			BASize,
-	IN	UCHAR			WCID,
-	IN	ULONG			Length,
-	IN	UCHAR 			PID,
-	IN	UCHAR			TID,
-	IN	UCHAR			TxRate,
-	IN	UCHAR			Txopmode,
-	IN	BOOLEAN			CfAck,
-	IN	HTTRANSMIT_SETTING	*pTransmit)
+void RTMPWriteTxWI(struct rt_rtmp_adapter *pAd, struct rt_txwi * pOutTxWI, IN BOOLEAN FRAG, IN BOOLEAN CFACK, IN BOOLEAN InsTimestamp, IN BOOLEAN AMPDU, IN BOOLEAN Ack, IN BOOLEAN NSeq,	/* HW new a sequence. */
+		   u8 BASize,
+		   u8 WCID,
+		   unsigned long Length,
+		   u8 PID,
+		   u8 TID,
+		   u8 TxRate,
+		   u8 Txopmode,
+		   IN BOOLEAN CfAck, IN HTTRANSMIT_SETTING * pTransmit)
 {
-	PMAC_TABLE_ENTRY	pMac = NULL;
-	TXWI_STRUC 		TxWI;
-	PTXWI_STRUC 	pTxWI;
+	struct rt_mac_table_entry *pMac = NULL;
+	struct rt_txwi TxWI;
+	struct rt_txwi * pTxWI;
 
 	if (WCID < MAX_LEN_OF_MAC_TABLE)
 		pMac = &pAd->MacTab.Content[WCID];
 
-	//
-	// Always use Long preamble before verifiation short preamble functionality works well.
-	// Todo: remove the following line if short preamble functionality works
-	//
+	/* */
+	/* Always use Long preamble before verifiation short preamble functionality works well. */
+	/* Todo: remove the following line if short preamble functionality works */
+	/* */
 	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
 	NdisZeroMemory(&TxWI, TXWI_SIZE);
 	pTxWI = &TxWI;
 
-	pTxWI->FRAG= FRAG;
+	pTxWI->FRAG = FRAG;
 
 	pTxWI->CFACK = CFACK;
-	pTxWI->TS= InsTimestamp;
+	pTxWI->TS = InsTimestamp;
 	pTxWI->AMPDU = AMPDU;
 	pTxWI->ACK = Ack;
-	pTxWI->txop= Txopmode;
+	pTxWI->txop = Txopmode;
 
 	pTxWI->NSEQ = NSeq;
-	// John tune the performace with Intel Client in 20 MHz performance
+	/* John tune the performace with Intel Client in 20 MHz performance */
 	BASize = pAd->CommonCfg.TxBASize;
-
-	if( BASize >7 )
-		BASize =7;
+	if (pAd->MACVersion == 0x28720200) {
+		if (BASize > 13)
+			BASize = 13;
+	} else {
+		if (BASize > 7)
+			BASize = 7;
+	}
 	pTxWI->BAWinSize = BASize;
 	pTxWI->ShortGI = pTransmit->field.ShortGI;
 	pTxWI->STBC = pTransmit->field.STBC;
@@ -1254,90 +1019,84 @@
 	pTxWI->MPDUtotalByteCount = Length;
 	pTxWI->PacketId = PID;
 
-	// If CCK or OFDM, BW must be 20
-	pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
+	/* If CCK or OFDM, BW must be 20 */
+	pTxWI->BW =
+	    (pTransmit->field.MODE <=
+	     MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
 
 	pTxWI->MCS = pTransmit->field.MCS;
 	pTxWI->PHYMODE = pTransmit->field.MODE;
 	pTxWI->CFACK = CfAck;
 
-	if (pMac)
-	{
-		if (pAd->CommonCfg.bMIMOPSEnable)
-		{
-			if ((pMac->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
-			{
-				// Dynamic MIMO Power Save Mode
+	if (pMac) {
+		if (pAd->CommonCfg.bMIMOPSEnable) {
+			if ((pMac->MmpsMode == MMPS_DYNAMIC)
+			    && (pTransmit->field.MCS > 7)) {
+				/* Dynamic MIMO Power Save Mode */
 				pTxWI->MIMOps = 1;
-			}
-			else if (pMac->MmpsMode == MMPS_STATIC)
-			{
-				// Static MIMO Power Save Mode
-				if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
-				{
+			} else if (pMac->MmpsMode == MMPS_STATIC) {
+				/* Static MIMO Power Save Mode */
+				if (pTransmit->field.MODE >= MODE_HTMIX
+				    && pTransmit->field.MCS > 7) {
 					pTxWI->MCS = 7;
 					pTxWI->MIMOps = 0;
 				}
 			}
 		}
-		//pTxWI->MIMOps = (pMac->PsMode == PWR_MMPS)? 1:0;
-		if (pMac->bIAmBadAtheros && (pMac->WepStatus != Ndis802_11WEPDisabled))
-		{
+		/*pTxWI->MIMOps = (pMac->PsMode == PWR_MMPS)? 1:0; */
+		if (pMac->bIAmBadAtheros
+		    && (pMac->WepStatus != Ndis802_11WEPDisabled)) {
 			pTxWI->MpduDensity = 7;
-		}
-		else
-		{
+		} else {
 			pTxWI->MpduDensity = pMac->MpduDensity;
 		}
 	}
 
 	pTxWI->PacketId = pTxWI->MCS;
-	NdisMoveMemory(pOutTxWI, &TxWI, sizeof(TXWI_STRUC));
+	NdisMoveMemory(pOutTxWI, &TxWI, sizeof(struct rt_txwi));
 }
 
-
-VOID RTMPWriteTxWI_Data(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	OUT PTXWI_STRUC		pTxWI,
-	IN	TX_BLK				*pTxBlk)
+void RTMPWriteTxWI_Data(struct rt_rtmp_adapter *pAd,
+			struct rt_txwi * pTxWI, struct rt_tx_blk *pTxBlk)
 {
-	HTTRANSMIT_SETTING	*pTransmit;
-	PMAC_TABLE_ENTRY	pMacEntry;
-	UCHAR				BASize;
+	HTTRANSMIT_SETTING *pTransmit;
+	struct rt_mac_table_entry *pMacEntry;
+	u8 BASize;
 
 	ASSERT(pTxWI);
 
 	pTransmit = pTxBlk->pTransmit;
 	pMacEntry = pTxBlk->pMacEntry;
 
-
-	//
-	// Always use Long preamble before verifiation short preamble functionality works well.
-	// Todo: remove the following line if short preamble functionality works
-	//
+	/* */
+	/* Always use Long preamble before verifiation short preamble functionality works well. */
+	/* Todo: remove the following line if short preamble functionality works */
+	/* */
 	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
 	NdisZeroMemory(pTxWI, TXWI_SIZE);
 
-	pTxWI->FRAG		= TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag);
-	pTxWI->ACK		= TX_BLK_TEST_FLAG(pTxBlk, fTX_bAckRequired);
-	pTxWI->txop		= pTxBlk->FrameGap;
+	pTxWI->FRAG = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag);
+	pTxWI->ACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAckRequired);
+	pTxWI->txop = pTxBlk->FrameGap;
 
-		pTxWI->WirelessCliID		= pTxBlk->Wcid;
+	pTxWI->WirelessCliID = pTxBlk->Wcid;
 
-	pTxWI->MPDUtotalByteCount	= pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
-	pTxWI->CFACK				= TX_BLK_TEST_FLAG(pTxBlk, fTX_bPiggyBack);
+	pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
+	pTxWI->CFACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bPiggyBack);
 
-	// If CCK or OFDM, BW must be 20
-	pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
-	pTxWI->AMPDU	= ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) ? TRUE : FALSE);
+	/* If CCK or OFDM, BW must be 20 */
+	pTxWI->BW =
+	    (pTransmit->field.MODE <=
+	     MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
+	pTxWI->AMPDU = ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) ? TRUE : FALSE);
 
-	// John tune the performace with Intel Client in 20 MHz performance
+	/* John tune the performace with Intel Client in 20 MHz performance */
 	BASize = pAd->CommonCfg.TxBASize;
-	if((pTxBlk->TxFrameType == TX_AMPDU_FRAME) && (pMacEntry))
-	{
-		UCHAR		RABAOriIdx = 0;	//The RA's BA Originator table index.
+	if ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) && (pMacEntry)) {
+		u8 RABAOriIdx = 0;	/*The RA's BA Originator table index. */
 
-		RABAOriIdx = pTxBlk->pMacEntry->BAOriWcidArray[pTxBlk->UserPriority];
+		RABAOriIdx =
+		    pTxBlk->pMacEntry->BAOriWcidArray[pTxBlk->UserPriority];
 		BASize = pAd->BATable.BAOriEntry[RABAOriIdx].BAWinSize;
 	}
 
@@ -1349,172 +1108,112 @@
 	pTxWI->MCS = pTransmit->field.MCS;
 	pTxWI->PHYMODE = pTransmit->field.MODE;
 
-	if (pMacEntry)
-	{
-		if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
-		{
-			// Dynamic MIMO Power Save Mode
+	if (pMacEntry) {
+		if ((pMacEntry->MmpsMode == MMPS_DYNAMIC)
+		    && (pTransmit->field.MCS > 7)) {
+			/* Dynamic MIMO Power Save Mode */
 			pTxWI->MIMOps = 1;
-		}
-		else if (pMacEntry->MmpsMode == MMPS_STATIC)
-		{
-			// Static MIMO Power Save Mode
-			if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
-			{
+		} else if (pMacEntry->MmpsMode == MMPS_STATIC) {
+			/* Static MIMO Power Save Mode */
+			if (pTransmit->field.MODE >= MODE_HTMIX
+			    && pTransmit->field.MCS > 7) {
 				pTxWI->MCS = 7;
 				pTxWI->MIMOps = 0;
 			}
 		}
 
-		if (pMacEntry->bIAmBadAtheros && (pMacEntry->WepStatus != Ndis802_11WEPDisabled))
-		{
+		if (pMacEntry->bIAmBadAtheros
+		    && (pMacEntry->WepStatus != Ndis802_11WEPDisabled)) {
 			pTxWI->MpduDensity = 7;
-		}
-		else
-		{
+		} else {
 			pTxWI->MpduDensity = pMacEntry->MpduDensity;
 		}
 	}
 
-
-	// for rate adapation
+	/* for rate adapation */
 	pTxWI->PacketId = pTxWI->MCS;
 }
 
-
-VOID RTMPWriteTxWI_Cache(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	OUT PTXWI_STRUC		pTxWI,
-	IN	TX_BLK				*pTxBlk)
+void RTMPWriteTxWI_Cache(struct rt_rtmp_adapter *pAd,
+			 struct rt_txwi * pTxWI, struct rt_tx_blk *pTxBlk)
 {
-	PHTTRANSMIT_SETTING	pTransmit;
-	PMAC_TABLE_ENTRY	pMacEntry;
+	PHTTRANSMIT_SETTING /*pTxHTPhyMode, */ pTransmit;
+	struct rt_mac_table_entry *pMacEntry;
 
-	//
-	// update TXWI
-	//
+	/* */
+	/* update TXWI */
+	/* */
 	pMacEntry = pTxBlk->pMacEntry;
 	pTransmit = pTxBlk->pTransmit;
 
-	if (pMacEntry->bAutoTxRateSwitch)
-	{
+	/*if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */
+	/*if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pMacEntry)) */
+	/*if (TX_BLK_TEST_FLAG(pTxBlk, fTX_AutoRateSwitch)) */
+	if (pMacEntry->bAutoTxRateSwitch) {
 		pTxWI->txop = IFS_HTTXOP;
 
-		// If CCK or OFDM, BW must be 20
-		pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
+		/* If CCK or OFDM, BW must be 20 */
+		pTxWI->BW =
+		    (pTransmit->field.MODE <=
+		     MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
 		pTxWI->ShortGI = pTransmit->field.ShortGI;
 		pTxWI->STBC = pTransmit->field.STBC;
 
 		pTxWI->MCS = pTransmit->field.MCS;
 		pTxWI->PHYMODE = pTransmit->field.MODE;
 
-		// set PID for TxRateSwitching
+		/* set PID for TxRateSwitching */
 		pTxWI->PacketId = pTransmit->field.MCS;
 	}
 
-	pTxWI->AMPDU = ((pMacEntry->NoBADataCountDown == 0) ? TRUE: FALSE);
+	pTxWI->AMPDU = ((pMacEntry->NoBADataCountDown == 0) ? TRUE : FALSE);
 	pTxWI->MIMOps = 0;
 
-	if (pAd->CommonCfg.bMIMOPSEnable)
-	{
-		// MIMO Power Save Mode
-		if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
-		{
-			// Dynamic MIMO Power Save Mode
+	if (pAd->CommonCfg.bMIMOPSEnable) {
+		/* MIMO Power Save Mode */
+		if ((pMacEntry->MmpsMode == MMPS_DYNAMIC)
+		    && (pTransmit->field.MCS > 7)) {
+			/* Dynamic MIMO Power Save Mode */
 			pTxWI->MIMOps = 1;
-		}
-		else if (pMacEntry->MmpsMode == MMPS_STATIC)
-		{
-			// Static MIMO Power Save Mode
-			if ((pTransmit->field.MODE >= MODE_HTMIX) && (pTransmit->field.MCS > 7))
-			{
+		} else if (pMacEntry->MmpsMode == MMPS_STATIC) {
+			/* Static MIMO Power Save Mode */
+			if ((pTransmit->field.MODE >= MODE_HTMIX)
+			    && (pTransmit->field.MCS > 7)) {
 				pTxWI->MCS = 7;
 				pTxWI->MIMOps = 0;
 			}
 		}
 	}
 
-
 	pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
 
 }
 
-
-/*
-	========================================================================
-
-	Routine Description:
-		Calculates the duration which is required to transmit out frames
-	with given size and specified rate.
-
-	Arguments:
-		pTxD		Pointer to transmit descriptor
-		Ack 		Setting for Ack requirement bit
-		Fragment	Setting for Fragment bit
-		RetryMode	Setting for retry mode
-		Ifs 		Setting for IFS gap
-		Rate		Setting for transmit rate
-		Service 	Setting for service
-		Length		Frame length
-		TxPreamble	Short or Long preamble when using CCK rates
-		QueIdx - 0-3, according to 802.11e/d4.4 June/2003
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-VOID RTMPWriteTxDescriptor(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PTXD_STRUC		pTxD,
-	IN	BOOLEAN 		bWIV,
-	IN	UCHAR			QueueSEL)
-{
-	//
-	// Always use Long preamble before verifiation short preamble functionality works well.
-	// Todo: remove the following line if short preamble functionality works
-	//
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
-
-	pTxD->WIV	= (bWIV) ? 1: 0;
-	pTxD->QSEL= (QueueSEL);
-	if (pAd->bGenOneHCCA == TRUE)
-		pTxD->QSEL= FIFO_HCCA;
-	pTxD->DMADONE = 0;
-}
-
-
-// should be called only when -
-// 1. MEADIA_CONNECTED
-// 2. AGGREGATION_IN_USED
-// 3. Fragmentation not in used
-// 4. either no previous frame (pPrevAddr1=NULL) .OR. previoud frame is aggregatible
-BOOLEAN TxFrameIsAggregatible(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pPrevAddr1,
-	IN	PUCHAR			p8023hdr)
+/* should be called only when - */
+/* 1. MEADIA_CONNECTED */
+/* 2. AGGREGATION_IN_USED */
+/* 3. Fragmentation not in used */
+/* 4. either no previous frame (pPrevAddr1=NULL) .OR. previoud frame is aggregatible */
+BOOLEAN TxFrameIsAggregatible(struct rt_rtmp_adapter *pAd,
+			      u8 *pPrevAddr1, u8 *p8023hdr)
 {
 
-	// can't aggregate EAPOL (802.1x) frame
+	/* can't aggregate EAPOL (802.1x) frame */
 	if ((p8023hdr[12] == 0x88) && (p8023hdr[13] == 0x8e))
 		return FALSE;
 
-	// can't aggregate multicast/broadcast frame
+	/* can't aggregate multicast/broadcast frame */
 	if (p8023hdr[0] & 0x01)
 		return FALSE;
 
-	if (INFRA_ON(pAd)) // must be unicast to AP
+	if (INFRA_ON(pAd))	/* must be unicast to AP */
 		return TRUE;
-	else if ((pPrevAddr1 == NULL) || MAC_ADDR_EQUAL(pPrevAddr1, p8023hdr)) // unicast to same STA
+	else if ((pPrevAddr1 == NULL) || MAC_ADDR_EQUAL(pPrevAddr1, p8023hdr))	/* unicast to same STA */
 		return TRUE;
 	else
 		return FALSE;
 }
 
-
 /*
 	========================================================================
 
@@ -1531,33 +1230,27 @@
 
 	========================================================================
 */
-BOOLEAN PeerIsAggreOn(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	ULONG		   TxRate,
-	IN	PMAC_TABLE_ENTRY pMacEntry)
+BOOLEAN PeerIsAggreOn(struct rt_rtmp_adapter *pAd,
+		      unsigned long TxRate, struct rt_mac_table_entry *pMacEntry)
 {
-	ULONG	AFlags = (fCLIENT_STATUS_AMSDU_INUSED | fCLIENT_STATUS_AGGREGATION_CAPABLE);
+	unsigned long AFlags =
+	    (fCLIENT_STATUS_AMSDU_INUSED | fCLIENT_STATUS_AGGREGATION_CAPABLE);
 
-	if (pMacEntry != NULL && CLIENT_STATUS_TEST_FLAG(pMacEntry, AFlags))
-	{
-		if (pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
-		{
+	if (pMacEntry != NULL && CLIENT_STATUS_TEST_FLAG(pMacEntry, AFlags)) {
+		if (pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX) {
 			return TRUE;
 		}
-
 #ifdef AGGREGATION_SUPPORT
-		if (TxRate >= RATE_6 && pAd->CommonCfg.bAggregationCapable && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
-		{	// legacy  Ralink Aggregation support
+		if (TxRate >= RATE_6 && pAd->CommonCfg.bAggregationCapable && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE)))) {	/* legacy  Ralink Aggregation support */
 			return TRUE;
 		}
-#endif // AGGREGATION_SUPPORT //
+#endif /* AGGREGATION_SUPPORT // */
 	}
 
 	return FALSE;
 
 }
 
-
 /*
 	========================================================================
 
@@ -1576,323 +1269,38 @@
 
 	========================================================================
 */
-PQUEUE_HEADER	RTMPCheckTxSwQueue(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT PUCHAR			pQueIdx)
+struct rt_queue_header *RTMPCheckTxSwQueue(struct rt_rtmp_adapter *pAd, u8 *pQueIdx)
 {
 
-	ULONG	Number;
+	unsigned long Number;
+	/* 2004-11-15 to be removed. test aggregation only */
+/*      if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)) && (*pNumber < 2)) */
+/*               return NULL; */
 
 	Number = pAd->TxSwQueue[QID_AC_BK].Number
-			 + pAd->TxSwQueue[QID_AC_BE].Number
-			 + pAd->TxSwQueue[QID_AC_VI].Number
-			 + pAd->TxSwQueue[QID_AC_VO].Number
-			 + pAd->TxSwQueue[QID_HCCA].Number;
+	    + pAd->TxSwQueue[QID_AC_BE].Number
+	    + pAd->TxSwQueue[QID_AC_VI].Number
+	    + pAd->TxSwQueue[QID_AC_VO].Number;
 
-	if (pAd->TxSwQueue[QID_AC_VO].Head != NULL)
-	{
+	if (pAd->TxSwQueue[QID_AC_VO].Head != NULL) {
 		*pQueIdx = QID_AC_VO;
 		return (&pAd->TxSwQueue[QID_AC_VO]);
-	}
-	else if (pAd->TxSwQueue[QID_AC_VI].Head != NULL)
-	{
+	} else if (pAd->TxSwQueue[QID_AC_VI].Head != NULL) {
 		*pQueIdx = QID_AC_VI;
 		return (&pAd->TxSwQueue[QID_AC_VI]);
-	}
-	else if (pAd->TxSwQueue[QID_AC_BE].Head != NULL)
-	{
+	} else if (pAd->TxSwQueue[QID_AC_BE].Head != NULL) {
 		*pQueIdx = QID_AC_BE;
 		return (&pAd->TxSwQueue[QID_AC_BE]);
-	}
-	else if (pAd->TxSwQueue[QID_AC_BK].Head != NULL)
-	{
+	} else if (pAd->TxSwQueue[QID_AC_BK].Head != NULL) {
 		*pQueIdx = QID_AC_BK;
 		return (&pAd->TxSwQueue[QID_AC_BK]);
 	}
-	else if (pAd->TxSwQueue[QID_HCCA].Head != NULL)
-	{
-		*pQueIdx = QID_HCCA;
-		return (&pAd->TxSwQueue[QID_HCCA]);
-	}
-
-	// No packet pending in Tx Sw queue
+	/* No packet pending in Tx Sw queue */
 	*pQueIdx = QID_AC_BK;
 
 	return (NULL);
 }
 
-#ifdef RT2860
-BOOLEAN  RTMPFreeTXDUponTxDmaDone(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			QueIdx)
-{
-	PRTMP_TX_RING pTxRing;
-	PTXD_STRUC	  pTxD;
-	PNDIS_PACKET  pPacket;
-	UCHAR	FREE = 0;
-	TXD_STRUC	TxD, *pOriTxD;
-	//ULONG		IrqFlags;
-	BOOLEAN			bReschedule = FALSE;
-
-
-	ASSERT(QueIdx < NUM_OF_TX_RING);
-	pTxRing = &pAd->TxRing[QueIdx];
-
-	RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF, &pTxRing->TxDmaIdx);
-	while (pTxRing->TxSwFreeIdx != pTxRing->TxDmaIdx)
-	{
-		// static rate also need NICUpdateFifoStaCounters() function.
-		//if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
-			NICUpdateFifoStaCounters(pAd);
-
-		/* Note : If (pAd->ate.bQATxStart == TRUE), we will never reach here. */
-		FREE++;
-                pTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
-		pOriTxD = pTxD;
-                NdisMoveMemory(&TxD, pTxD, sizeof(TXD_STRUC));
-		pTxD = &TxD;
-
-		pTxD->DMADONE = 0;
-
-/*====================================================================*/
-		{
-			pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket;
-			if (pPacket)
-			{
-#ifdef CONFIG_5VT_ENHANCE
-				if (RTMP_GET_PACKET_5VT(pPacket))
-					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE);
-				else
-#endif // CONFIG_5VT_ENHANCE //
-					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-			}
-			//Always assign pNdisPacket as NULL after clear
-			pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket = NULL;
-
-			pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket;
-
-			ASSERT(pPacket == NULL);
-			if (pPacket)
-			{
-#ifdef CONFIG_5VT_ENHANCE
-				if (RTMP_GET_PACKET_5VT(pPacket))
-					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE);
-				else
-#endif // CONFIG_5VT_ENHANCE //
-					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-			}
-			//Always assign pNextNdisPacket as NULL after clear
-			pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL;
-		}
-/*====================================================================*/
-
-		pAd->RalinkCounters.TransmittedByteCount +=  (pTxD->SDLen1 + pTxD->SDLen0);
-		pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx] ++;
-		INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
-		/* get tx_tdx_idx again */
-		RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF ,  &pTxRing->TxDmaIdx);
-
-        NdisMoveMemory(pOriTxD, pTxD, sizeof(TXD_STRUC));
-	}
-
-
-	return  bReschedule;
-
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Process TX Rings DMA Done interrupt, running in DPC level
-
-	Arguments:
-		Adapter 	Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-BOOLEAN	RTMPHandleTxRingDmaDoneInterrupt(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	INT_SOURCE_CSR_STRUC TxRingBitmap)
-{
-    unsigned long	IrqFlags;
-	BOOLEAN			bReschedule = FALSE;
-
-	// Make sure Tx ring resource won't be used by other threads
-
-	RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-
-	if (TxRingBitmap.field.Ac0DmaDone)
-		bReschedule = RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BE);
-
-	if (TxRingBitmap.field.HccaDmaDone)
-		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_HCCA);
-
-	if (TxRingBitmap.field.Ac3DmaDone)
-		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VO);
-
-	if (TxRingBitmap.field.Ac2DmaDone)
-		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VI);
-
-	if (TxRingBitmap.field.Ac1DmaDone)
-		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BK);
-
-	// Make sure to release Tx ring resource
-	RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-
-	// Dequeue outgoing frames from TxSwQueue[] and process it
-	RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
-
-	return  bReschedule;
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Process MGMT ring DMA done interrupt, running in DPC level
-
-	Arguments:
-		pAd 	Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPHandleMgmtRingDmaDoneInterrupt(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	PTXD_STRUC	 pTxD;
-	PNDIS_PACKET pPacket;
-	UCHAR	FREE = 0;
-	PRTMP_MGMT_RING pMgmtRing = &pAd->MgmtRing;
-
-	NdisAcquireSpinLock(&pAd->MgmtRingLock);
-
-	RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx);
-	while (pMgmtRing->TxSwFreeIdx!= pMgmtRing->TxDmaIdx)
-	{
-		FREE++;
-		pTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa);
-		pTxD->DMADONE = 0;
-		pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket;
-
-
-		if (pPacket)
-		{
-			PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
-			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-		}
-		pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL;
-
-		pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket;
-		if (pPacket)
-		{
-			PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
-			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-		}
-		pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket = NULL;
-		INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE);
-	}
-	NdisReleaseSpinLock(&pAd->MgmtRingLock);
-
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-	Arguments:
-		Adapter 	Pointer to our adapter. Dequeue all power safe delayed braodcast frames after beacon.
-
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-VOID	RTMPHandleTBTTInterrupt(
-	IN PRTMP_ADAPTER pAd)
-{
-	{
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-		{
-		}
-	}
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-	Arguments:
-		Adapter 	Pointer to our adapter. Rewrite beacon content before next send-out.
-
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-VOID	RTMPHandlePreTBTTInterrupt(
-	IN PRTMP_ADAPTER pAd)
-{
-	{
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("RTMPHandlePreTBTTInterrupt...\n"));
-		}
-	}
-
-
-}
-
-VOID	RTMPHandleRxCoherentInterrupt(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	WPDMA_GLO_CFG_STRUC	GloCfg;
-
-	if (pAd == NULL)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("====> pAd is NULL, return.\n"));
-		return;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleRxCoherentInterrupt \n"));
-
-	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG , &GloCfg.word);
-
-	GloCfg.field.EnTXWriteBackDDONE = 0;
-	GloCfg.field.EnableRxDMA = 0;
-	GloCfg.field.EnableTxDMA = 0;
-	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
-
-	RTMPRingCleanUp(pAd, QID_AC_BE);
-	RTMPRingCleanUp(pAd, QID_AC_BK);
-	RTMPRingCleanUp(pAd, QID_AC_VI);
-	RTMPRingCleanUp(pAd, QID_AC_VO);
-	RTMPRingCleanUp(pAd, QID_HCCA);
-	RTMPRingCleanUp(pAd, QID_MGMT);
-	RTMPRingCleanUp(pAd, QID_RX);
-
-	RTMPEnableRxTx(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleRxCoherentInterrupt \n"));
-}
-#endif /* RT2860 */
-
 /*
 	========================================================================
 
@@ -1909,25 +1317,25 @@
 
 	========================================================================
 */
-VOID	RTMPSuspendMsduTransmission(
-	IN	PRTMP_ADAPTER	pAd)
+void RTMPSuspendMsduTransmission(struct rt_rtmp_adapter *pAd)
 {
-	DBGPRINT(RT_DEBUG_TRACE,("SCANNING, suspend MSDU transmission ...\n"));
+	DBGPRINT(RT_DEBUG_TRACE, ("SCANNING, suspend MSDU transmission ...\n"));
 
+	/* */
+	/* Before BSS_SCAN_IN_PROGRESS, we need to keep Current R66 value and */
+	/* use Lowbound as R66 value on ScanNextChannel(...) */
+	/* */
+	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66,
+				    &pAd->BbpTuning.R66CurrentValue);
 
-	//
-	// Before BSS_SCAN_IN_PROGRESS, we need to keep Current R66 value and
-	// use Lowbound as R66 value on ScanNextChannel(...)
-	//
-	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
-
-	// set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning)
+	/* set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning) */
+	/*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd))); */
 	RTMPSetAGCInitValue(pAd, BW_20);
 
 	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+	/*RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x000f0000);                // abort all TX rings */
 }
 
-
 /*
 	========================================================================
 
@@ -1946,141 +1354,145 @@
 
 	========================================================================
 */
-VOID RTMPResumeMsduTransmission(
-	IN	PRTMP_ADAPTER	pAd)
+void RTMPResumeMsduTransmission(struct rt_rtmp_adapter *pAd)
 {
-	DBGPRINT(RT_DEBUG_TRACE,("SCAN done, resume MSDU transmission ...\n"));
+/*    u8                     IrqState; */
 
-	// After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value
-	// R66 should not be 0
-	if (pAd->BbpTuning.R66CurrentValue == 0)
-	{
+	DBGPRINT(RT_DEBUG_TRACE, ("SCAN done, resume MSDU transmission ...\n"));
+
+	/* After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value */
+	/* R66 should not be 0 */
+	if (pAd->BbpTuning.R66CurrentValue == 0) {
 		pAd->BbpTuning.R66CurrentValue = 0x38;
 		DBGPRINT_ERR(("RTMPResumeMsduTransmission, R66CurrentValue=0...\n"));
 	}
 
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, pAd->BbpTuning.R66CurrentValue);
+	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66,
+				     pAd->BbpTuning.R66CurrentValue);
 
 	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+/* sample, for IRQ LOCK to SEM LOCK */
+/*    IrqState = pAd->irq_disabled; */
+/*      if (IrqState) */
+/*              RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS); */
+/*    else */
 	RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
 }
 
-
-UINT deaggregate_AMSDU_announce(
-	IN	PRTMP_ADAPTER	pAd,
-	PNDIS_PACKET		pPacket,
-	IN	PUCHAR			pData,
-	IN	ULONG			DataSize)
+u32 deaggregate_AMSDU_announce(struct rt_rtmp_adapter *pAd,
+				void *pPacket,
+				u8 *pData, unsigned long DataSize)
 {
-	USHORT 			PayloadSize;
-	USHORT 			SubFrameSize;
-	PHEADER_802_3 	pAMSDUsubheader;
-	UINT			nMSDU;
-    UCHAR			Header802_3[14];
+	u16 PayloadSize;
+	u16 SubFrameSize;
+	struct rt_header_802_3 * pAMSDUsubheader;
+	u32 nMSDU;
+	u8 Header802_3[14];
 
-	PUCHAR			pPayload, pDA, pSA, pRemovedLLCSNAP;
-	PNDIS_PACKET	pClonePacket;
-
-
+	u8 *pPayload, *pDA, *pSA, *pRemovedLLCSNAP;
+	void *pClonePacket;
 
 	nMSDU = 0;
 
-	while (DataSize > LENGTH_802_3)
-	{
+	while (DataSize > LENGTH_802_3) {
 
 		nMSDU++;
 
-		pAMSDUsubheader = (PHEADER_802_3)pData;
-		PayloadSize = pAMSDUsubheader->Octet[1] + (pAMSDUsubheader->Octet[0]<<8);
+		/*hex_dump("subheader", pData, 64); */
+		pAMSDUsubheader = (struct rt_header_802_3 *) pData;
+		/*pData += LENGTH_802_3; */
+		PayloadSize =
+		    pAMSDUsubheader->Octet[1] +
+		    (pAMSDUsubheader->Octet[0] << 8);
 		SubFrameSize = PayloadSize + LENGTH_802_3;
 
-
-		if ((DataSize < SubFrameSize) || (PayloadSize > 1518 ))
-		{
+		if ((DataSize < SubFrameSize) || (PayloadSize > 1518)) {
 			break;
 		}
+		/*DBGPRINT(RT_DEBUG_TRACE,("%d subframe: Size = %d\n",  nMSDU, PayloadSize)); */
 
 		pPayload = pData + LENGTH_802_3;
 		pDA = pData;
 		pSA = pData + MAC_ADDR_LEN;
 
-		// convert to 802.3 header
-        CONVERT_TO_802_3(Header802_3, pDA, pSA, pPayload, PayloadSize, pRemovedLLCSNAP);
+		/* convert to 802.3 header */
+		CONVERT_TO_802_3(Header802_3, pDA, pSA, pPayload, PayloadSize,
+				 pRemovedLLCSNAP);
 
-		if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E) )
-		{
-		    // avoid local heap overflow, use dyanamic allocation
-		   MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
-		   if (Elem == NULL)
-			return;
-		   memmove(Elem->Msg+(LENGTH_802_11 + LENGTH_802_1_H), pPayload, PayloadSize);
-		   Elem->MsgLen = LENGTH_802_11 + LENGTH_802_1_H + PayloadSize;
-		   WpaEAPOLKeyAction(pAd, Elem);
-		   kfree(Elem);
+		if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E)) {
+			/* avoid local heap overflow, use dyanamic allocation */
+			struct rt_mlme_queue_elem *Elem =
+			    (struct rt_mlme_queue_elem *)kmalloc(sizeof(struct rt_mlme_queue_elem),
+							MEM_ALLOC_FLAG);
+			if (Elem != NULL) {
+				memmove(Elem->Msg +
+					(LENGTH_802_11 + LENGTH_802_1_H),
+					pPayload, PayloadSize);
+				Elem->MsgLen =
+				    LENGTH_802_11 + LENGTH_802_1_H +
+				    PayloadSize;
+				/*WpaEAPOLKeyAction(pAd, Elem); */
+				REPORT_MGMT_FRAME_TO_MLME(pAd, BSSID_WCID,
+							  Elem->Msg,
+							  Elem->MsgLen, 0, 0, 0,
+							  0);
+				kfree(Elem);
+			}
 		}
 
 		{
-	        	if (pRemovedLLCSNAP)
-	        	{
-	    			pPayload -= LENGTH_802_3;
-	    			PayloadSize += LENGTH_802_3;
-	    			NdisMoveMemory(pPayload, &Header802_3[0], LENGTH_802_3);
-	        	}
+			if (pRemovedLLCSNAP) {
+				pPayload -= LENGTH_802_3;
+				PayloadSize += LENGTH_802_3;
+				NdisMoveMemory(pPayload, &Header802_3[0],
+					       LENGTH_802_3);
+			}
 		}
 
 		pClonePacket = ClonePacket(pAd, pPacket, pPayload, PayloadSize);
-		if (pClonePacket)
-		{
-			ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pClonePacket, RTMP_GET_PACKET_IF(pPacket));
+		if (pClonePacket) {
+			ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pClonePacket,
+							 RTMP_GET_PACKET_IF
+							 (pPacket));
 		}
 
+		/* A-MSDU has padding to multiple of 4 including subframe header. */
+		/* align SubFrameSize up to multiple of 4 */
+		SubFrameSize = (SubFrameSize + 3) & (~0x3);
 
-		// A-MSDU has padding to multiple of 4 including subframe header.
-		// align SubFrameSize up to multiple of 4
-		SubFrameSize = (SubFrameSize+3)&(~0x3);
-
-
-		if (SubFrameSize > 1528 || SubFrameSize < 32)
-		{
+		if (SubFrameSize > 1528 || SubFrameSize < 32) {
 			break;
 		}
 
-		if (DataSize > SubFrameSize)
-		{
+		if (DataSize > SubFrameSize) {
 			pData += SubFrameSize;
 			DataSize -= SubFrameSize;
-		}
-		else
-		{
-			// end of A-MSDU
+		} else {
+			/* end of A-MSDU */
 			DataSize = 0;
 		}
 	}
 
-	// finally release original rx packet
+	/* finally release original rx packet */
 	RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
 
 	return nMSDU;
 }
 
-
-UINT BA_Reorder_AMSDU_Annnounce(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket)
+u32 BA_Reorder_AMSDU_Annnounce(struct rt_rtmp_adapter *pAd, void *pPacket)
 {
-	PUCHAR			pData;
-	USHORT			DataSize;
-	UINT			nMSDU = 0;
+	u8 *pData;
+	u16 DataSize;
+	u32 nMSDU = 0;
 
-	pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
-	DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
+	pData = (u8 *)GET_OS_PKT_DATAPTR(pPacket);
+	DataSize = (u16)GET_OS_PKT_LEN(pPacket);
 
 	nMSDU = deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
 
 	return nMSDU;
 }
 
-
 /*
 	==========================================================================
 	Description:
@@ -2089,40 +1501,37 @@
 		pEntry - pointer to the MAC entry; NULL is not found
 	==========================================================================
 */
-MAC_TABLE_ENTRY *MacTableLookup(
-	IN PRTMP_ADAPTER pAd,
-	PUCHAR pAddr)
+struct rt_mac_table_entry *MacTableLookup(struct rt_rtmp_adapter *pAd, u8 *pAddr)
 {
-	ULONG HashIdx;
-	MAC_TABLE_ENTRY *pEntry = NULL;
+	unsigned long HashIdx;
+	struct rt_mac_table_entry *pEntry = NULL;
 
 	HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
 	pEntry = pAd->MacTab.Hash[HashIdx];
 
-	while (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsWDS || pEntry->ValidAsApCli || pEntry->ValidAsMesh))
-	{
-		if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
-		{
+	while (pEntry
+	       && (pEntry->ValidAsCLI || pEntry->ValidAsWDS
+		   || pEntry->ValidAsApCli || pEntry->ValidAsMesh)) {
+		if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr)) {
 			break;
-		}
-		else
+		} else
 			pEntry = pEntry->pNext;
 	}
 
 	return pEntry;
 }
 
-MAC_TABLE_ENTRY *MacTableInsertEntry(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR			pAddr,
-	IN	UCHAR			apidx,
-	IN BOOLEAN	CleanAll)
+struct rt_mac_table_entry *MacTableInsertEntry(struct rt_rtmp_adapter *pAd,
+				     u8 *pAddr,
+				     u8 apidx, IN BOOLEAN CleanAll)
 {
-	UCHAR HashIdx;
+	u8 HashIdx;
 	int i, FirstWcid;
-	MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
+	struct rt_mac_table_entry *pEntry = NULL, *pCurrEntry;
+/*      u16  offset; */
+/*      unsigned long   addr; */
 
-	// if FULL, return
+	/* if FULL, return */
 	if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
 		return NULL;
 
@@ -2131,23 +1540,21 @@
 	if (pAd->StaCfg.BssType == BSS_INFRA)
 		FirstWcid = 2;
 
-	// allocate one MAC entry
+	/* allocate one MAC entry */
 	NdisAcquireSpinLock(&pAd->MacTabLock);
-	for (i = FirstWcid; i< MAX_LEN_OF_MAC_TABLE; i++)   // skip entry#0 so that "entry index == AID" for fast lookup
+	for (i = FirstWcid; i < MAX_LEN_OF_MAC_TABLE; i++)	/* skip entry#0 so that "entry index == AID" for fast lookup */
 	{
-		// pick up the first available vacancy
+		/* pick up the first available vacancy */
 		if ((pAd->MacTab.Content[i].ValidAsCLI == FALSE) &&
-			(pAd->MacTab.Content[i].ValidAsWDS == FALSE) &&
-			(pAd->MacTab.Content[i].ValidAsApCli== FALSE) &&
-			(pAd->MacTab.Content[i].ValidAsMesh == FALSE)
-			)
-		{
+		    (pAd->MacTab.Content[i].ValidAsWDS == FALSE) &&
+		    (pAd->MacTab.Content[i].ValidAsApCli == FALSE) &&
+		    (pAd->MacTab.Content[i].ValidAsMesh == FALSE)
+		    ) {
 			pEntry = &pAd->MacTab.Content[i];
-			if (CleanAll == TRUE)
-			{
+			if (CleanAll == TRUE) {
 				pEntry->MaxSupportedRate = RATE_11;
 				pEntry->CurrTxRate = RATE_11;
-				NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
+				NdisZeroMemory(pEntry, sizeof(struct rt_mac_table_entry));
 				pEntry->PairwiseKey.KeyLen = 0;
 				pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
 			}
@@ -2164,77 +1571,76 @@
 			pEntry->bIAmBadAtheros = FALSE;
 			pEntry->pAd = pAd;
 			pEntry->CMTimerRunning = FALSE;
-			pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
+			pEntry->EnqueueEapolStartTimerRunning =
+			    EAPOL_START_DISABLE;
 			pEntry->RSNIE_Len = 0;
-			NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter));
+			NdisZeroMemory(pEntry->R_Counter,
+				       sizeof(pEntry->R_Counter));
 			pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
 
 			if (pEntry->ValidAsMesh)
-				pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_MESH);
+				pEntry->apidx =
+				    (apidx - MIN_NET_DEVICE_FOR_MESH);
 			else if (pEntry->ValidAsApCli)
-				pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_APCLI);
+				pEntry->apidx =
+				    (apidx - MIN_NET_DEVICE_FOR_APCLI);
 			else if (pEntry->ValidAsWDS)
-				pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_WDS);
+				pEntry->apidx =
+				    (apidx - MIN_NET_DEVICE_FOR_WDS);
 			else
 				pEntry->apidx = apidx;
 
 			{
 				{
 					pEntry->AuthMode = pAd->StaCfg.AuthMode;
-					pEntry->WepStatus = pAd->StaCfg.WepStatus;
-					pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
-#ifdef RT2860
-					AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)i);
-#endif
+					pEntry->WepStatus =
+					    pAd->StaCfg.WepStatus;
+					pEntry->PrivacyFilter =
+					    Ndis802_11PrivFilterAcceptAll;
+#ifdef RTMP_MAC_PCI
+					AsicRemovePairwiseKeyEntry(pAd,
+								   pEntry->
+								   apidx,
+								   (u8)i);
+#endif /* RTMP_MAC_PCI // */
 				}
 			}
 
 			pEntry->GTKState = REKEY_NEGOTIATING;
 			pEntry->PairwiseKey.KeyLen = 0;
 			pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
-
-#ifdef RT2860
-			if ((pAd->OpMode == OPMODE_STA) &&
-				(pAd->StaCfg.BssType == BSS_ADHOC))
-				pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
-			else
-#endif
 			pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
 
 			pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
 			COPY_MAC_ADDR(pEntry->Addr, pAddr);
 			pEntry->Sst = SST_NOT_AUTH;
 			pEntry->AuthState = AS_NOT_AUTH;
-			pEntry->Aid = (USHORT)i;  //0;
+			pEntry->Aid = (u16)i;	/*0; */
 			pEntry->CapabilityInfo = 0;
 			pEntry->PsMode = PWR_ACTIVE;
 			pEntry->PsQIdleCount = 0;
 			pEntry->NoDataIdleCount = 0;
+			pEntry->AssocDeadLine = MAC_TABLE_ASSOC_TIMEOUT;
 			pEntry->ContinueTxFailCnt = 0;
 			InitializeQueueHeader(&pEntry->PsQueue);
 
+			pAd->MacTab.Size++;
+			/* Add this entry into ASIC RX WCID search table */
+			RTMP_STA_ENTRY_ADD(pAd, pEntry);
 
-			pAd->MacTab.Size ++;
-			// Add this entry into ASIC RX WCID search table
-			RT28XX_STA_ENTRY_ADD(pAd, pEntry);
-
-
-
-			DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertEntry - allocate entry #%d, Total= %d\n",i, pAd->MacTab.Size));
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("MacTableInsertEntry - allocate entry #%d, Total= %d\n",
+				  i, pAd->MacTab.Size));
 			break;
 		}
 	}
 
-	// add this MAC entry into HASH table
-	if (pEntry)
-	{
+	/* add this MAC entry into HASH table */
+	if (pEntry) {
 		HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
-		if (pAd->MacTab.Hash[HashIdx] == NULL)
-		{
+		if (pAd->MacTab.Hash[HashIdx] == NULL) {
 			pAd->MacTab.Hash[HashIdx] = pEntry;
-		}
-		else
-		{
+		} else {
 			pCurrEntry = pAd->MacTab.Hash[HashIdx];
 			while (pCurrEntry->pNext != NULL)
 				pCurrEntry = pCurrEntry->pNext;
@@ -2252,14 +1658,14 @@
 		Delete a specified client from MAC table
 	==========================================================================
  */
-BOOLEAN MacTableDeleteEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT wcid,
-	IN PUCHAR pAddr)
+BOOLEAN MacTableDeleteEntry(struct rt_rtmp_adapter *pAd,
+			    u16 wcid, u8 *pAddr)
 {
-	USHORT HashIdx;
-	MAC_TABLE_ENTRY *pEntry, *pPrevEntry, *pProbeEntry;
+	u16 HashIdx;
+	struct rt_mac_table_entry *pEntry, *pPrevEntry, *pProbeEntry;
 	BOOLEAN Cancelled;
+	/*u16        offset; // unused variable */
+	/*u8 j;                      // unused variable */
 
 	if (wcid >= MAX_LEN_OF_MAC_TABLE)
 		return FALSE;
@@ -2267,36 +1673,33 @@
 	NdisAcquireSpinLock(&pAd->MacTabLock);
 
 	HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
+	/*pEntry = pAd->MacTab.Hash[HashIdx]; */
 	pEntry = &pAd->MacTab.Content[wcid];
 
-	if (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS || pEntry->ValidAsMesh
-		))
-	{
-		if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
-		{
+	if (pEntry
+	    && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS
+		|| pEntry->ValidAsMesh)) {
+		if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr)) {
 
-			// Delete this entry from ASIC on-chip WCID Table
-			RT28XX_STA_ENTRY_MAC_RESET(pAd, wcid);
+			/* Delete this entry from ASIC on-chip WCID Table */
+			RTMP_STA_ENTRY_MAC_RESET(pAd, wcid);
 
-			// free resources of BA
+			/* free resources of BA */
 			BASessionTearDownALL(pAd, pEntry->Aid);
 
 			pPrevEntry = NULL;
 			pProbeEntry = pAd->MacTab.Hash[HashIdx];
 			ASSERT(pProbeEntry);
 
-			// update Hash list
-			do
-			{
-				if (pProbeEntry == pEntry)
-				{
-					if (pPrevEntry == NULL)
-					{
-						pAd->MacTab.Hash[HashIdx] = pEntry->pNext;
-					}
-					else
-					{
-						pPrevEntry->pNext = pEntry->pNext;
+			/* update Hash list */
+			do {
+				if (pProbeEntry == pEntry) {
+					if (pPrevEntry == NULL) {
+						pAd->MacTab.Hash[HashIdx] =
+						    pEntry->pNext;
+					} else {
+						pPrevEntry->pNext =
+						    pEntry->pNext;
 					}
 					break;
 				}
@@ -2305,48 +1708,43 @@
 				pProbeEntry = pProbeEntry->pNext;
 			} while (pProbeEntry);
 
-			// not found !!!
+			/* not found ! */
 			ASSERT(pProbeEntry != NULL);
 
-			RT28XX_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid);
+			RTMP_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid);
 
+			if (pEntry->EnqueueEapolStartTimerRunning !=
+			    EAPOL_START_DISABLE) {
+				RTMPCancelTimer(&pEntry->
+						EnqueueStartForPSKTimer,
+						&Cancelled);
+				pEntry->EnqueueEapolStartTimerRunning =
+				    EAPOL_START_DISABLE;
+			}
 
-		if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
-		{
-			RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
-			pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
-		}
-
-
-   			NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
-			pAd->MacTab.Size --;
-			DBGPRINT(RT_DEBUG_TRACE, ("MacTableDeleteEntry1 - Total= %d\n", pAd->MacTab.Size));
-		}
-		else
-		{
-			printk("\n%s: Impossible Wcid = %d !!!!!\n", __func__, wcid);
+			NdisZeroMemory(pEntry, sizeof(struct rt_mac_table_entry));
+			pAd->MacTab.Size--;
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("MacTableDeleteEntry1 - Total= %d\n",
+				  pAd->MacTab.Size));
+		} else {
+			DBGPRINT(RT_DEBUG_OFF,
+				 ("\n%s: Impossible Wcid = %d !\n",
+				  __func__, wcid));
 		}
 	}
 
 	NdisReleaseSpinLock(&pAd->MacTabLock);
 
-	//Reset operating mode when no Sta.
-	if (pAd->MacTab.Size == 0)
-	{
+	/*Reset operating mode when no Sta. */
+	if (pAd->MacTab.Size == 0) {
 		pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0;
-#ifdef RT2860
-		AsicUpdateProtect(pAd, 0 /*pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode*/, (ALLN_SETPROTECT), TRUE, 0 /*pAd->MacTab.fAnyStationNonGF*/);
-#else
-		// edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
-		// Set MAC register value according operation mode
-		RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_UPDATE_PROTECT, NULL, 0);
-#endif
+		RTMP_UPDATE_PROTECT(pAd);	/* edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet */
 	}
 
 	return TRUE;
 }
 
-
 /*
 	==========================================================================
 	Description:
@@ -2354,34 +1752,30 @@
 		the power-saving queues are freed here.
 	==========================================================================
  */
-VOID MacTableReset(
-	IN  PRTMP_ADAPTER  pAd)
+void MacTableReset(struct rt_rtmp_adapter *pAd)
 {
-	int         i;
+	int i;
 
 	DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n"));
-	//NdisAcquireSpinLock(&pAd->MacTabLock);
+	/*NdisAcquireSpinLock(&pAd->MacTabLock); */
 
-	for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
-	{
-#ifdef RT2860
-		RT28XX_STA_ENTRY_MAC_RESET(pAd, i);
-#endif
-		if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
-	   {
-			// free resources of BA
+	for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) {
+#ifdef RTMP_MAC_PCI
+		RTMP_STA_ENTRY_MAC_RESET(pAd, i);
+#endif /* RTMP_MAC_PCI // */
+		if (pAd->MacTab.Content[i].ValidAsCLI == TRUE) {
+
+			/* free resources of BA */
 			BASessionTearDownALL(pAd, i);
 
 			pAd->MacTab.Content[i].ValidAsCLI = FALSE;
 
-
-
-#ifdef RT2870
+#ifdef RTMP_MAC_USB
 			NdisZeroMemory(pAd->MacTab.Content[i].Addr, 6);
-			RT28XX_STA_ENTRY_MAC_RESET(pAd, i);
-#endif // RT2870 //
+			RTMP_STA_ENTRY_MAC_RESET(pAd, i);
+#endif /* RTMP_MAC_USB // */
 
-			//AsicDelWcidTab(pAd, i);
+			/*AsicDelWcidTab(pAd, i); */
 		}
 	}
 
@@ -2396,22 +1790,19 @@
 
 	==========================================================================
 */
-VOID AssocParmFill(
-	IN PRTMP_ADAPTER pAd,
-	IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
-	IN PUCHAR                     pAddr,
-	IN USHORT                     CapabilityInfo,
-	IN ULONG                      Timeout,
-	IN USHORT                     ListenIntv)
+void AssocParmFill(struct rt_rtmp_adapter *pAd,
+		   struct rt_mlme_assoc_req *AssocReq,
+		   u8 *pAddr,
+		   u16 CapabilityInfo,
+		   unsigned long Timeout, u16 ListenIntv)
 {
 	COPY_MAC_ADDR(AssocReq->Addr, pAddr);
-	// Add mask to support 802.11b mode only
-	AssocReq->CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; // not cf-pollable, not cf-poll-request
+	/* Add mask to support 802.11b mode only */
+	AssocReq->CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;	/* not cf-pollable, not cf-poll-request */
 	AssocReq->Timeout = Timeout;
 	AssocReq->ListenIntv = ListenIntv;
 }
 
-
 /*
 	==========================================================================
 	Description:
@@ -2420,17 +1811,14 @@
 
 	==========================================================================
 */
-VOID DisassocParmFill(
-	IN PRTMP_ADAPTER pAd,
-	IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
-	IN PUCHAR pAddr,
-	IN USHORT Reason)
+void DisassocParmFill(struct rt_rtmp_adapter *pAd,
+		      struct rt_mlme_disassoc_req *DisassocReq,
+		      u8 *pAddr, u16 Reason)
 {
 	COPY_MAC_ADDR(DisassocReq->Addr, pAddr);
 	DisassocReq->Reason = Reason;
 }
 
-
 /*
 	========================================================================
 
@@ -2465,76 +1853,69 @@
 	========================================================================
 */
 
-BOOLEAN RTMPCheckDHCPFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket)
+BOOLEAN RTMPCheckDHCPFrame(struct rt_rtmp_adapter *pAd, void *pPacket)
 {
-	PACKET_INFO 	PacketInfo;
-	ULONG			NumberOfBytesRead = 0;
-	ULONG			CurrentOffset = 0;
-	PVOID			pVirtualAddress = NULL;
-	UINT			NdisBufferLength;
-	PUCHAR			pSrc;
-	USHORT			Protocol;
-	UCHAR			ByteOffset36 = 0;
-	UCHAR			ByteOffset38 = 0;
-	BOOLEAN 		ReadFirstParm = TRUE;
+	struct rt_packet_info PacketInfo;
+	unsigned long NumberOfBytesRead = 0;
+	unsigned long CurrentOffset = 0;
+	void *pVirtualAddress = NULL;
+	u32 NdisBufferLength;
+	u8 *pSrc;
+	u16 Protocol;
+	u8 ByteOffset36 = 0;
+	u8 ByteOffset38 = 0;
+	BOOLEAN ReadFirstParm = TRUE;
 
-	RTMP_QueryPacketInfo(pPacket, &PacketInfo, (PUCHAR *)&pVirtualAddress, &NdisBufferLength);
+	RTMP_QueryPacketInfo(pPacket, &PacketInfo, (u8 **) & pVirtualAddress,
+			     &NdisBufferLength);
 
 	NumberOfBytesRead += NdisBufferLength;
-	pSrc = (PUCHAR) pVirtualAddress;
+	pSrc = (u8 *)pVirtualAddress;
 	Protocol = *(pSrc + 12) * 256 + *(pSrc + 13);
 
-	//
-	// Check DHCP & BOOTP protocol
-	//
-	while (NumberOfBytesRead <= PacketInfo.TotalPacketLength)
-	{
-		if ((NumberOfBytesRead >= 35) && (ReadFirstParm == TRUE))
-		{
-			CurrentOffset = 35 - (NumberOfBytesRead - NdisBufferLength);
+	/* */
+	/* Check DHCP & BOOTP protocol */
+	/* */
+	while (NumberOfBytesRead <= PacketInfo.TotalPacketLength) {
+		if ((NumberOfBytesRead >= 35) && (ReadFirstParm == TRUE)) {
+			CurrentOffset =
+			    35 - (NumberOfBytesRead - NdisBufferLength);
 			ByteOffset36 = *(pSrc + CurrentOffset);
 			ReadFirstParm = FALSE;
 		}
 
-		if (NumberOfBytesRead >= 37)
-		{
-			CurrentOffset = 37 - (NumberOfBytesRead - NdisBufferLength);
+		if (NumberOfBytesRead >= 37) {
+			CurrentOffset =
+			    37 - (NumberOfBytesRead - NdisBufferLength);
 			ByteOffset38 = *(pSrc + CurrentOffset);
-			//End of Read
+			/*End of Read */
 			break;
 		}
 		return FALSE;
 	}
 
-	// Check for DHCP & BOOTP protocol
-	if ((ByteOffset36 != 0x44) || (ByteOffset38 != 0x43))
-		{
-		//
-		// 2054 (hex 0806) for ARP datagrams
-		// if this packet is not ARP datagrams, then do nothing
-		// ARP datagrams will also be duplicate at 1mb broadcast frames
-		//
-		if (Protocol != 0x0806 )
+	/* Check for DHCP & BOOTP protocol */
+	if ((ByteOffset36 != 0x44) || (ByteOffset38 != 0x43)) {
+		/* */
+		/* 2054 (hex 0806) for ARP datagrams */
+		/* if this packet is not ARP datagrams, then do nothing */
+		/* ARP datagrams will also be duplicate at 1mb broadcast frames */
+		/* */
+		if (Protocol != 0x0806)
 			return FALSE;
-		}
+	}
 
 	return TRUE;
 }
 
-
-BOOLEAN RTMPCheckEtherType(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket)
+BOOLEAN RTMPCheckEtherType(struct rt_rtmp_adapter *pAd, void *pPacket)
 {
-	USHORT	TypeLen;
-	UCHAR	Byte0, Byte1;
-	PUCHAR	pSrcBuf;
-	UINT32	pktLen;
-	UINT16 	srcPort, dstPort;
-	BOOLEAN	status = TRUE;
-
+	u16 TypeLen;
+	u8 Byte0, Byte1;
+	u8 *pSrcBuf;
+	u32 pktLen;
+	u16 srcPort, dstPort;
+	BOOLEAN status = TRUE;
 
 	pSrcBuf = GET_OS_PKT_DATAPTR(pPacket);
 	pktLen = GET_OS_PKT_LEN(pPacket);
@@ -2543,35 +1924,31 @@
 
 	RTMP_SET_PACKET_SPECIFIC(pPacket, 0);
 
-	// get Ethernet protocol field
-	TypeLen = (pSrcBuf[12] << 8) + pSrcBuf[13];
+	/* get Ethernet protocol field */
+	TypeLen = (pSrcBuf[12] << 8) | pSrcBuf[13];
 
-	pSrcBuf += LENGTH_802_3;	// Skip the Ethernet Header.
+	pSrcBuf += LENGTH_802_3;	/* Skip the Ethernet Header. */
 
-	if (TypeLen <= 1500)
-	{	// 802.3, 802.3 LLC
+	if (TypeLen <= 1500) {	/* 802.3, 802.3 LLC */
 		/*
-			DestMAC(6) + SrcMAC(6) + Lenght(2) +
-			DSAP(1) + SSAP(1) + Control(1) +
-			if the DSAP = 0xAA, SSAP=0xAA, Contorl = 0x03, it has a 5-bytes SNAP header.
-				=> + SNAP (5, OriginationID(3) + etherType(2))
-		*/
-		if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA && pSrcBuf[2] == 0x03)
-		{
-			Sniff2BytesFromNdisBuffer(pSrcBuf, 6, &Byte0, &Byte1);
+		   DestMAC(6) + SrcMAC(6) + Lenght(2) +
+		   DSAP(1) + SSAP(1) + Control(1) +
+		   if the DSAP = 0xAA, SSAP=0xAA, Contorl = 0x03, it has a 5-bytes SNAP header.
+		   => + SNAP (5, OriginationID(3) + etherType(2))
+		 */
+		if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA
+		    && pSrcBuf[2] == 0x03) {
+			Sniff2BytesFromNdisBuffer((char *)pSrcBuf, 6,
+						  &Byte0, &Byte1);
 			RTMP_SET_PACKET_LLCSNAP(pPacket, 1);
-			TypeLen = (USHORT)((Byte0 << 8) + Byte1);
-			pSrcBuf += 8; // Skip this LLC/SNAP header
-		}
-		else
-		{
-			//It just has 3-byte LLC header, maybe a legacy ether type frame. we didn't handle it.
+			TypeLen = (u16)((Byte0 << 8) + Byte1);
+			pSrcBuf += 8;	/* Skip this LLC/SNAP header */
+		} else {
+			/*It just has 3-byte LLC header, maybe a legacy ether type frame. we didn't handle it. */
 		}
 	}
-
-	// If it's a VLAN packet, get the real Type/Length field.
-	if (TypeLen == 0x8100)
-	{
+	/* If it's a VLAN packet, get the real Type/Length field. */
+	if (TypeLen == 0x8100) {
 		/* 0x8100 means VLAN packets */
 
 		/* Dest. MAC Address (6-bytes) +
@@ -2584,243 +1961,229 @@
 		   Frame Check Sequence (4-bytes) */
 
 		RTMP_SET_PACKET_VLAN(pPacket, 1);
-		Sniff2BytesFromNdisBuffer(pSrcBuf, 2, &Byte0, &Byte1);
-		TypeLen = (USHORT)((Byte0 << 8) + Byte1);
+		Sniff2BytesFromNdisBuffer((char *)pSrcBuf, 2, &Byte0,
+					  &Byte1);
+		TypeLen = (u16)((Byte0 << 8) + Byte1);
 
-		pSrcBuf += 4; // Skip the VLAN Header.
+		pSrcBuf += 4;	/* Skip the VLAN Header. */
 	}
 
-	switch (TypeLen)
-	{
-		case 0x0800:
-			{
-				ASSERT((pktLen > 34));
-				if (*(pSrcBuf + 9) == 0x11)
-				{	// udp packet
-					ASSERT((pktLen > 34));	// 14 for ethernet header, 20 for IP header
+	switch (TypeLen) {
+	case 0x0800:
+		{
+			ASSERT((pktLen > 34));
+			if (*(pSrcBuf + 9) == 0x11) {	/* udp packet */
+				ASSERT((pktLen > 34));	/* 14 for ethernet header, 20 for IP header */
 
-					pSrcBuf += 20;	// Skip the IP header
-					srcPort = OS_NTOHS(*((UINT16 *)pSrcBuf));
-					dstPort = OS_NTOHS(*((UINT16 *)(pSrcBuf +2)));
+				pSrcBuf += 20;	/* Skip the IP header */
+				srcPort =
+				    OS_NTOHS(get_unaligned
+					     ((u16 *)(pSrcBuf)));
+				dstPort =
+				    OS_NTOHS(get_unaligned
+					     ((u16 *)(pSrcBuf + 2)));
 
-					if ((srcPort==0x44 && dstPort==0x43) || (srcPort==0x43 && dstPort==0x44))
-					{	//It's a BOOTP/DHCP packet
-						RTMP_SET_PACKET_DHCP(pPacket, 1);
-					}
+				if ((srcPort == 0x44 && dstPort == 0x43) || (srcPort == 0x43 && dstPort == 0x44)) {	/*It's a BOOTP/DHCP packet */
+					RTMP_SET_PACKET_DHCP(pPacket, 1);
 				}
 			}
-			break;
-		case 0x0806:
-			{
-				//ARP Packet.
-				RTMP_SET_PACKET_DHCP(pPacket, 1);
-			}
-			break;
-		case 0x888e:
-			{
-				// EAPOL Packet.
-				RTMP_SET_PACKET_EAPOL(pPacket, 1);
-			}
-			break;
-		default:
-			status = FALSE;
-			break;
+		}
+		break;
+	case 0x0806:
+		{
+			/*ARP Packet. */
+			RTMP_SET_PACKET_DHCP(pPacket, 1);
+		}
+		break;
+	case 0x888e:
+		{
+			/* EAPOL Packet. */
+			RTMP_SET_PACKET_EAPOL(pPacket, 1);
+		}
+		break;
+	default:
+		status = FALSE;
+		break;
 	}
 
 	return status;
 
 }
 
+void Update_Rssi_Sample(struct rt_rtmp_adapter *pAd,
+			struct rt_rssi_sample *pRssi, struct rt_rxwi * pRxWI)
+{
+	char rssi0 = pRxWI->RSSI0;
+	char rssi1 = pRxWI->RSSI1;
+	char rssi2 = pRxWI->RSSI2;
 
-
-VOID Update_Rssi_Sample(
-	IN PRTMP_ADAPTER	pAd,
-	IN RSSI_SAMPLE		*pRssi,
-	IN PRXWI_STRUC		pRxWI)
-		{
-	CHAR	rssi0 = pRxWI->RSSI0;
-	CHAR	rssi1 = pRxWI->RSSI1;
-	CHAR	rssi2 = pRxWI->RSSI2;
-
-	if (rssi0 != 0)
-	{
-		pRssi->LastRssi0	= ConvertToRssi(pAd, (CHAR)rssi0, RSSI_0);
-		pRssi->AvgRssi0X8	= (pRssi->AvgRssi0X8 - pRssi->AvgRssi0) + pRssi->LastRssi0;
-		pRssi->AvgRssi0	= pRssi->AvgRssi0X8 >> 3;
+	if (rssi0 != 0) {
+		pRssi->LastRssi0 = ConvertToRssi(pAd, (char)rssi0, RSSI_0);
+		pRssi->AvgRssi0X8 =
+		    (pRssi->AvgRssi0X8 - pRssi->AvgRssi0) + pRssi->LastRssi0;
+		pRssi->AvgRssi0 = pRssi->AvgRssi0X8 >> 3;
 	}
 
-	if (rssi1 != 0)
-	{
-		pRssi->LastRssi1	= ConvertToRssi(pAd, (CHAR)rssi1, RSSI_1);
-		pRssi->AvgRssi1X8	= (pRssi->AvgRssi1X8 - pRssi->AvgRssi1) + pRssi->LastRssi1;
-		pRssi->AvgRssi1	= pRssi->AvgRssi1X8 >> 3;
+	if (rssi1 != 0) {
+		pRssi->LastRssi1 = ConvertToRssi(pAd, (char)rssi1, RSSI_1);
+		pRssi->AvgRssi1X8 =
+		    (pRssi->AvgRssi1X8 - pRssi->AvgRssi1) + pRssi->LastRssi1;
+		pRssi->AvgRssi1 = pRssi->AvgRssi1X8 >> 3;
 	}
 
-	if (rssi2 != 0)
-	{
-		pRssi->LastRssi2	= ConvertToRssi(pAd, (CHAR)rssi2, RSSI_2);
-		pRssi->AvgRssi2X8  = (pRssi->AvgRssi2X8 - pRssi->AvgRssi2) + pRssi->LastRssi2;
+	if (rssi2 != 0) {
+		pRssi->LastRssi2 = ConvertToRssi(pAd, (char)rssi2, RSSI_2);
+		pRssi->AvgRssi2X8 =
+		    (pRssi->AvgRssi2X8 - pRssi->AvgRssi2) + pRssi->LastRssi2;
 		pRssi->AvgRssi2 = pRssi->AvgRssi2X8 >> 3;
 	}
 }
 
-
-
-// Normal legacy Rx packet indication
-VOID Indicate_Legacy_Packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID)
+/* Normal legacy Rx packet indication */
+void Indicate_Legacy_Packet(struct rt_rtmp_adapter *pAd,
+			    struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
 {
-	PNDIS_PACKET	pRxPacket = pRxBlk->pRxPacket;
-	UCHAR			Header802_3[LENGTH_802_3];
+	void *pRxPacket = pRxBlk->pRxPacket;
+	u8 Header802_3[LENGTH_802_3];
 
-	// 1. get 802.3 Header
-	// 2. remove LLC
-	// 		a. pointer pRxBlk->pData to payload
-	//      b. modify pRxBlk->DataSize
+	/* 1. get 802.3 Header */
+	/* 2. remove LLC */
+	/*              a. pointer pRxBlk->pData to payload */
+	/*      b. modify pRxBlk->DataSize */
 	RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
 
-	if (pRxBlk->DataSize > MAX_RX_PKT_LEN)
-	{
+	if (pRxBlk->DataSize > MAX_RX_PKT_LEN) {
 
-		// release packet
+		/* release packet */
 		RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
 		return;
 	}
 
-
 	STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
 
-#ifdef RT2870
-	if (pAd->CommonCfg.bDisableReordering == 0)
-	{
-		PBA_REC_ENTRY		pBAEntry;
-		ULONG				Now32;
-		UCHAR				Wcid = pRxBlk->pRxWI->WirelessCliID;
-		UCHAR				TID = pRxBlk->pRxWI->TID;
-		USHORT				Idx;
+#ifdef RTMP_MAC_USB
+	if (pAd->CommonCfg.bDisableReordering == 0) {
+		struct rt_ba_rec_entry *pBAEntry;
+		unsigned long Now32;
+		u8 Wcid = pRxBlk->pRxWI->WirelessCliID;
+		u8 TID = pRxBlk->pRxWI->TID;
+		u16 Idx;
 
-#define REORDERING_PACKET_TIMEOUT		((100 * HZ)/1000)	// system ticks -- 100 ms
+#define REORDERING_PACKET_TIMEOUT		((100 * OS_HZ)/1000)	/* system ticks -- 100 ms */
 
-		if (Wcid < MAX_LEN_OF_MAC_TABLE)
-		{
+		if (Wcid < MAX_LEN_OF_MAC_TABLE) {
 			Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
-			if (Idx != 0)
-			{
+			if (Idx != 0) {
 				pBAEntry = &pAd->BATable.BARecEntry[Idx];
-				// update last rx time
+				/* update last rx time */
 				NdisGetSystemUpTime(&Now32);
 				if ((pBAEntry->list.qlen > 0) &&
-					 RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
-	   				)
-				{
-					printk("Indicate_Legacy_Packet():flush reordering_timeout_mpdus! RxWI->Flags=%d, pRxWI.TID=%d, RxD->AMPDU=%d!\n", pRxBlk->Flags, pRxBlk->pRxWI->TID, pRxBlk->RxD.AMPDU);
-					hex_dump("Dump the legacy Packet:", GET_OS_PKT_DATAPTR(pRxBlk->pRxPacket), 64);
-					ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
+				    RTMP_TIME_AFTER((unsigned long)Now32,
+						    (unsigned long)(pBAEntry->
+								    LastIndSeqAtTimer
+								    +
+								    (REORDERING_PACKET_TIMEOUT)))
+				    ) {
+					DBGPRINT(RT_DEBUG_OFF,
+						 ("Indicate_Legacy_Packet():flush reordering_timeout_mpdus! RxWI->Flags=%d, pRxWI.TID=%d, RxD->AMPDU=%d!\n",
+						  pRxBlk->Flags,
+						  pRxBlk->pRxWI->TID,
+						  pRxBlk->RxD.AMPDU));
+					hex_dump("Dump the legacy Packet:",
+						 GET_OS_PKT_DATAPTR(pRxBlk->
+								    pRxPacket),
+						 64);
+					ba_flush_reordering_timeout_mpdus(pAd,
+									  pBAEntry,
+									  Now32);
 				}
 			}
 		}
 	}
-#endif // RT2870 //
+#endif /* RTMP_MAC_USB // */
 
 	wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
 
-	//
-	// pass this 802.3 packet to upper layer or forward this packet to WM directly
-	//
+	/* */
+	/* pass this 802.3 packet to upper layer or forward this packet to WM directly */
+	/* */
 	ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxPacket, FromWhichBSSID);
 }
 
-
-// Normal, AMPDU or AMSDU
-VOID CmmRxnonRalinkFrameIndicate(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID)
+/* Normal, AMPDU or AMSDU */
+void CmmRxnonRalinkFrameIndicate(struct rt_rtmp_adapter *pAd,
+				 struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
 {
-	if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
-	{
+	if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU)
+	    && (pAd->CommonCfg.bDisableReordering == 0)) {
 		Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
-	}
-	else
-	{
-		if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
-		{
-			// handle A-MSDU
+	} else {
+		if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU)) {
+			/* handle A-MSDU */
 			Indicate_AMSDU_Packet(pAd, pRxBlk, FromWhichBSSID);
-		}
-		else
-		{
+		} else {
 			Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
 		}
 	}
 }
 
-
-VOID CmmRxRalinkFrameIndicate(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MAC_TABLE_ENTRY	*pEntry,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID)
+void CmmRxRalinkFrameIndicate(struct rt_rtmp_adapter *pAd,
+			      struct rt_mac_table_entry *pEntry,
+			      struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
 {
-	UCHAR			Header802_3[LENGTH_802_3];
-	UINT16			Msdu2Size;
-	UINT16 			Payload1Size, Payload2Size;
-	PUCHAR 			pData2;
-	PNDIS_PACKET	pPacket2 = NULL;
+	u8 Header802_3[LENGTH_802_3];
+	u16 Msdu2Size;
+	u16 Payload1Size, Payload2Size;
+	u8 *pData2;
+	void *pPacket2 = NULL;
 
+	Msdu2Size = *(pRxBlk->pData) + (*(pRxBlk->pData + 1) << 8);
 
-
-	Msdu2Size = *(pRxBlk->pData) + (*(pRxBlk->pData+1) << 8);
-
-	if ((Msdu2Size <= 1536) && (Msdu2Size < pRxBlk->DataSize))
-	{
+	if ((Msdu2Size <= 1536) && (Msdu2Size < pRxBlk->DataSize)) {
 		/* skip two byte MSDU2 len */
 		pRxBlk->pData += 2;
 		pRxBlk->DataSize -= 2;
-	}
-	else
-	{
-		// release packet
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+	} else {
+		/* release packet */
+		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
+				    NDIS_STATUS_FAILURE);
 		return;
 	}
 
-	// get 802.3 Header and  remove LLC
+	/* get 802.3 Header and  remove LLC */
 	RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
 
 	ASSERT(pRxBlk->pRxPacket);
 
-	// Ralink Aggregation frame
-	pAd->RalinkCounters.OneSecRxAggregationCount ++;
+	/* Ralink Aggregation frame */
+	pAd->RalinkCounters.OneSecRxAggregationCount++;
 	Payload1Size = pRxBlk->DataSize - Msdu2Size;
 	Payload2Size = Msdu2Size - LENGTH_802_3;
 
 	pData2 = pRxBlk->pData + Payload1Size + LENGTH_802_3;
 
-	pPacket2 = duplicate_pkt(pAd, (pData2-LENGTH_802_3), LENGTH_802_3, pData2, Payload2Size, FromWhichBSSID);
+	pPacket2 =
+	    duplicate_pkt(pAd, (pData2 - LENGTH_802_3), LENGTH_802_3, pData2,
+			  Payload2Size, FromWhichBSSID);
 
-	if (!pPacket2)
-	{
-		// release packet
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+	if (!pPacket2) {
+		/* release packet */
+		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
+				    NDIS_STATUS_FAILURE);
 		return;
 	}
-
-	// update payload size of 1st packet
+	/* update payload size of 1st packet */
 	pRxBlk->DataSize = Payload1Size;
 	wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
 
-	ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxBlk->pRxPacket, FromWhichBSSID);
+	ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxBlk->pRxPacket,
+					 FromWhichBSSID);
 
-	if (pPacket2)
-	{
+	if (pPacket2) {
 		ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket2, FromWhichBSSID);
 	}
 }
 
-
 #define RESET_FRAGFRAME(_fragFrame) \
 	{								\
 		_fragFrame.RxSize = 0;		\
@@ -2829,109 +2192,102 @@
 		_fragFrame.Flags = 0;		\
 	}
 
-
-PNDIS_PACKET RTMPDeFragmentDataFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk)
+void *RTMPDeFragmentDataFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
 {
-	PHEADER_802_11	pHeader = pRxBlk->pHeader;
-	PNDIS_PACKET	pRxPacket = pRxBlk->pRxPacket;
-	UCHAR			*pData = pRxBlk->pData;
-	USHORT			DataSize = pRxBlk->DataSize;
-	PNDIS_PACKET	pRetPacket = NULL;
-	UCHAR			*pFragBuffer = NULL;
-	BOOLEAN 		bReassDone = FALSE;
-	UCHAR			HeaderRoom = 0;
-
+	struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
+	void *pRxPacket = pRxBlk->pRxPacket;
+	u8 *pData = pRxBlk->pData;
+	u16 DataSize = pRxBlk->DataSize;
+	void *pRetPacket = NULL;
+	u8 *pFragBuffer = NULL;
+	BOOLEAN bReassDone = FALSE;
+	u8 HeaderRoom = 0;
 
 	ASSERT(pHeader);
 
-	HeaderRoom = pData - (UCHAR *)pHeader;
+	HeaderRoom = pData - (u8 *) pHeader;
 
-	// Re-assemble the fragmented packets
-	if (pHeader->Frag == 0)		// Frag. Number is 0 : First frag or only one pkt
+	/* Re-assemble the fragmented packets */
+	if (pHeader->Frag == 0)	/* Frag. Number is 0 : First frag or only one pkt */
 	{
-		// the first pkt of fragment, record it.
-		if (pHeader->FC.MoreFrag)
-		{
+		/* the first pkt of fragment, record it. */
+		if (pHeader->FC.MoreFrag) {
 			ASSERT(pAd->FragFrame.pFragPacket);
-			pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
-			pAd->FragFrame.RxSize   = DataSize + HeaderRoom;
-			NdisMoveMemory(pFragBuffer,	 pHeader, pAd->FragFrame.RxSize);
+			pFragBuffer =
+			    GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
+			pAd->FragFrame.RxSize = DataSize + HeaderRoom;
+			NdisMoveMemory(pFragBuffer, pHeader,
+				       pAd->FragFrame.RxSize);
 			pAd->FragFrame.Sequence = pHeader->Sequence;
-			pAd->FragFrame.LastFrag = pHeader->Frag;	   // Should be 0
+			pAd->FragFrame.LastFrag = pHeader->Frag;	/* Should be 0 */
 			ASSERT(pAd->FragFrame.LastFrag == 0);
-			goto done;	// end of processing this frame
+			goto done;	/* end of processing this frame */
 		}
-	}
-	else	//Middle & End of fragment
+	} else			/*Middle & End of fragment */
 	{
 		if ((pHeader->Sequence != pAd->FragFrame.Sequence) ||
-			(pHeader->Frag != (pAd->FragFrame.LastFrag + 1)))
-		{
-			// Fragment is not the same sequence or out of fragment number order
-			// Reset Fragment control blk
+		    (pHeader->Frag != (pAd->FragFrame.LastFrag + 1))) {
+			/* Fragment is not the same sequence or out of fragment number order */
+			/* Reset Fragment control blk */
 			RESET_FRAGFRAME(pAd->FragFrame);
-			DBGPRINT(RT_DEBUG_ERROR, ("Fragment is not the same sequence or out of fragment number order.\n"));
-			goto done; // give up this frame
-		}
-		else if ((pAd->FragFrame.RxSize + DataSize) > MAX_FRAME_SIZE)
-		{
-			// Fragment frame is too large, it exeeds the maximum frame size.
-			// Reset Fragment control blk
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("Fragment is not the same sequence or out of fragment number order.\n"));
+			goto done;	/* give up this frame */
+		} else if ((pAd->FragFrame.RxSize + DataSize) > MAX_FRAME_SIZE) {
+			/* Fragment frame is too large, it exeeds the maximum frame size. */
+			/* Reset Fragment control blk */
 			RESET_FRAGFRAME(pAd->FragFrame);
-			DBGPRINT(RT_DEBUG_ERROR, ("Fragment frame is too large, it exeeds the maximum frame size.\n"));
-			goto done; // give up this frame
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("Fragment frame is too large, it exeeds the maximum frame size.\n"));
+			goto done;	/* give up this frame */
 		}
-
-        //
-		// Broadcom AP(BCM94704AGR) will send out LLC in fragment's packet, LLC only can accpet at first fragment.
-		// In this case, we will dropt it.
-		//
-		if (NdisEqualMemory(pData, SNAP_802_1H, sizeof(SNAP_802_1H)))
-		{
-			DBGPRINT(RT_DEBUG_ERROR, ("Find another LLC at Middle or End fragment(SN=%d, Frag=%d)\n", pHeader->Sequence, pHeader->Frag));
-			goto done; // give up this frame
+		/* */
+		/* Broadcom AP(BCM94704AGR) will send out LLC in fragment's packet, LLC only can accpet at first fragment. */
+		/* In this case, we will dropt it. */
+		/* */
+		if (NdisEqualMemory(pData, SNAP_802_1H, sizeof(SNAP_802_1H))) {
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("Find another LLC at Middle or End fragment(SN=%d, Frag=%d)\n",
+				  pHeader->Sequence, pHeader->Frag));
+			goto done;	/* give up this frame */
 		}
 
 		pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
 
-		// concatenate this fragment into the re-assembly buffer
-		NdisMoveMemory((pFragBuffer + pAd->FragFrame.RxSize), pData, DataSize);
-		pAd->FragFrame.RxSize  += DataSize;
-		pAd->FragFrame.LastFrag = pHeader->Frag;	   // Update fragment number
+		/* concatenate this fragment into the re-assembly buffer */
+		NdisMoveMemory((pFragBuffer + pAd->FragFrame.RxSize), pData,
+			       DataSize);
+		pAd->FragFrame.RxSize += DataSize;
+		pAd->FragFrame.LastFrag = pHeader->Frag;	/* Update fragment number */
 
-		// Last fragment
-		if (pHeader->FC.MoreFrag == FALSE)
-		{
+		/* Last fragment */
+		if (pHeader->FC.MoreFrag == FALSE) {
 			bReassDone = TRUE;
 		}
 	}
 
 done:
-	// always release rx fragmented packet
+	/* always release rx fragmented packet */
 	RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
 
-	// return defragmented packet if packet is reassembled completely
-	// otherwise return NULL
-	if (bReassDone)
-	{
-		PNDIS_PACKET pNewFragPacket;
+	/* return defragmented packet if packet is reassembled completely */
+	/* otherwise return NULL */
+	if (bReassDone) {
+		void *pNewFragPacket;
 
-		// allocate a new packet buffer for fragment
-		pNewFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
-		if (pNewFragPacket)
-		{
-			// update RxBlk
+		/* allocate a new packet buffer for fragment */
+		pNewFragPacket =
+		    RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
+		if (pNewFragPacket) {
+			/* update RxBlk */
 			pRetPacket = pAd->FragFrame.pFragPacket;
 			pAd->FragFrame.pFragPacket = pNewFragPacket;
-			pRxBlk->pHeader = (PHEADER_802_11) GET_OS_PKT_DATAPTR(pRetPacket);
-			pRxBlk->pData = (UCHAR *)pRxBlk->pHeader + HeaderRoom;
+			pRxBlk->pHeader =
+			    (struct rt_header_802_11 *) GET_OS_PKT_DATAPTR(pRetPacket);
+			pRxBlk->pData = (u8 *) pRxBlk->pHeader + HeaderRoom;
 			pRxBlk->DataSize = pAd->FragFrame.RxSize - HeaderRoom;
 			pRxBlk->pRxPacket = pRetPacket;
-		}
-		else
-		{
+		} else {
 			RESET_FRAGFRAME(pAd->FragFrame);
 		}
 	}
@@ -2939,25 +2295,22 @@
 	return pRetPacket;
 }
 
-
-VOID Indicate_AMSDU_Packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID)
+void Indicate_AMSDU_Packet(struct rt_rtmp_adapter *pAd,
+			   struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
 {
-	UINT			nMSDU;
+	u32 nMSDU;
 
 	update_os_packet_info(pAd, pRxBlk, FromWhichBSSID);
 	RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
-	nMSDU = deaggregate_AMSDU_announce(pAd, pRxBlk->pRxPacket, pRxBlk->pData, pRxBlk->DataSize);
+	nMSDU =
+	    deaggregate_AMSDU_announce(pAd, pRxBlk->pRxPacket, pRxBlk->pData,
+				       pRxBlk->DataSize);
 }
 
-VOID Indicate_EAPOL_Packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID)
+void Indicate_EAPOL_Packet(struct rt_rtmp_adapter *pAd,
+			   struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
 {
-	MAC_TABLE_ENTRY *pEntry = NULL;
+	struct rt_mac_table_entry *pEntry = NULL;
 
 	{
 		pEntry = &pAd->MacTab.Content[BSSID_WCID];
@@ -2965,48 +2318,42 @@
 		return;
 	}
 
-	if (pEntry == NULL)
-	{
-		DBGPRINT(RT_DEBUG_WARN, ("Indicate_EAPOL_Packet: drop and release the invalid packet.\n"));
-		// release packet
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+	if (pEntry == NULL) {
+		DBGPRINT(RT_DEBUG_WARN,
+			 ("Indicate_EAPOL_Packet: drop and release the invalid packet.\n"));
+		/* release packet */
+		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
+				    NDIS_STATUS_FAILURE);
 		return;
 	}
 }
 
-#define BCN_TBTT_OFFSET		64	//defer 64 us
-VOID ReSyncBeaconTime(
-	IN  PRTMP_ADAPTER   pAd)
+#define BCN_TBTT_OFFSET		64	/*defer 64 us */
+void ReSyncBeaconTime(struct rt_rtmp_adapter *pAd)
 {
 
-	UINT32  Offset;
-
+	u32 Offset;
 
 	Offset = (pAd->TbttTickCount) % (BCN_TBTT_OFFSET);
 
 	pAd->TbttTickCount++;
 
-	//
-	// The updated BeaconInterval Value will affect Beacon Interval after two TBTT
-	// beacasue the original BeaconInterval had been loaded into next TBTT_TIMER
-	//
-	if (Offset == (BCN_TBTT_OFFSET-2))
-	{
+	/* */
+	/* The updated BeaconInterval Value will affect Beacon Interval after two TBTT */
+	/* beacasue the original BeaconInterval had been loaded into next TBTT_TIMER */
+	/* */
+	if (Offset == (BCN_TBTT_OFFSET - 2)) {
 		BCN_TIME_CFG_STRUC csr;
 		RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
-		csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod << 4) - 1 ;	// ASIC register in units of 1/16 TU = 64us
+		csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod << 4) - 1;	/* ASIC register in units of 1/16 TU = 64us */
 		RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
-	}
-	else
-	{
-		if (Offset == (BCN_TBTT_OFFSET-1))
-		{
+	} else {
+		if (Offset == (BCN_TBTT_OFFSET - 1)) {
 			BCN_TIME_CFG_STRUC csr;
 
 			RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
-			csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod) << 4; // ASIC register in units of 1/16 TU
+			csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod) << 4;	/* ASIC register in units of 1/16 TU */
 			RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
 		}
 	}
 }
-
diff --git a/drivers/staging/rt2860/common/cmm_data_2860.c b/drivers/staging/rt2860/common/cmm_data_2860.c
deleted file mode 100644
index 857ff45..0000000
--- a/drivers/staging/rt2860/common/cmm_data_2860.c
+++ /dev/null
@@ -1,1199 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-*/
-
-/*
-   All functions in this file must be PCI-depended, or you should out your function
-	in other files.
-
-*/
-#include "../rt_config.h"
-
-extern RTMP_RF_REGS RF2850RegTable[];
-extern UCHAR	NUM_OF_2850_CHNL;
-
-USHORT RtmpPCI_WriteTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	BOOLEAN			bIsLast,
-	OUT	USHORT			*FreeNumber)
-{
-
-	UCHAR			*pDMAHeaderBufVA;
-	USHORT			TxIdx, RetTxIdx;
-	PTXD_STRUC		pTxD;
-	UINT32			BufBasePaLow;
-	PRTMP_TX_RING	pTxRing;
-	USHORT			hwHeaderLen;
-
-	//
-	// get Tx Ring Resource
-	//
-	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
-	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
-	pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
-	BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
-
-	// copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
-	if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
-	{
-		hwHeaderLen = pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
-	}
-	else
-	{
-		hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
-	}
-	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
-
-	pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
-	pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
-
-	//
-	// build Tx Descriptor
-	//
-
-	pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
-	NdisZeroMemory(pTxD, TXD_SIZE);
-
-	pTxD->SDPtr0 = BufBasePaLow;
-	pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; // include padding
-	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);;
-	pTxD->SDLen1 = pTxBlk->SrcBufLen;
-	pTxD->LastSec0 = 0;
-	pTxD->LastSec1 = (bIsLast) ? 1 : 0;
-
-	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
-
-	RetTxIdx = TxIdx;
-	//
-	// Update Tx index
-	//
-	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
-	pTxRing->TxCpuIdx = TxIdx;
-
-	*FreeNumber -= 1;
-
-	return RetTxIdx;
-}
-
-
-USHORT RtmpPCI_WriteSingleTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	BOOLEAN			bIsLast,
-	OUT	USHORT			*FreeNumber)
-{
-
-	UCHAR			*pDMAHeaderBufVA;
-	USHORT			TxIdx, RetTxIdx;
-	PTXD_STRUC		pTxD;
-	UINT32			BufBasePaLow;
-	PRTMP_TX_RING	pTxRing;
-	USHORT			hwHeaderLen;
-
-	//
-	// get Tx Ring Resource
-	//
-	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
-	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
-	pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
-	BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
-
-	// copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
-	hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
-
-	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
-
-	pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
-	pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
-
-	//
-	// build Tx Descriptor
-	//
-	pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
-
-	NdisZeroMemory(pTxD, TXD_SIZE);
-
-	pTxD->SDPtr0 = BufBasePaLow;
-	pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; // include padding
-	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);;
-	pTxD->SDLen1 = pTxBlk->SrcBufLen;
-	pTxD->LastSec0 = 0;
-	pTxD->LastSec1 = (bIsLast) ? 1 : 0;
-
-	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
-
-	RetTxIdx = TxIdx;
-	//
-	// Update Tx index
-	//
-	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
-	pTxRing->TxCpuIdx = TxIdx;
-
-	*FreeNumber -= 1;
-
-	return RetTxIdx;
-}
-
-
-USHORT RtmpPCI_WriteMultiTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	UCHAR			frameNum,
-	OUT	USHORT			*FreeNumber)
-{
-	BOOLEAN bIsLast;
-	UCHAR			*pDMAHeaderBufVA;
-	USHORT			TxIdx, RetTxIdx;
-	PTXD_STRUC		pTxD;
-	UINT32			BufBasePaLow;
-	PRTMP_TX_RING	pTxRing;
-	USHORT			hwHdrLen;
-	UINT32			firstDMALen;
-
-	bIsLast = ((frameNum == (pTxBlk->TotalFrameNum - 1)) ? 1 : 0);
-
-	//
-	// get Tx Ring Resource
-	//
-	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
-	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
-	pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
-	BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
-
-	if (frameNum == 0)
-	{
-		// copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
-		if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
-			//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD;
-			hwHdrLen = pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
-		else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
-			//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD;
-			hwHdrLen = pTxBlk->MpduHeaderLen - LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + LENGTH_ARALINK_HEADER_FIELD;
-		else
-			//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
-			hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
-
-		firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
-	}
-	else
-	{
-		firstDMALen = pTxBlk->MpduHeaderLen;
-	}
-
-	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen);
-
-	pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
-	pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
-
-	//
-	// build Tx Descriptor
-	//
-	pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
-
-	NdisZeroMemory(pTxD, TXD_SIZE);
-
-	pTxD->SDPtr0 = BufBasePaLow;
-	pTxD->SDLen0 = firstDMALen; // include padding
-	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);;
-	pTxD->SDLen1 = pTxBlk->SrcBufLen;
-	pTxD->LastSec0 = 0;
-	pTxD->LastSec1 = (bIsLast) ? 1 : 0;
-
-	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
-
-	RetTxIdx = TxIdx;
-	//
-	// Update Tx index
-	//
-	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
-	pTxRing->TxCpuIdx = TxIdx;
-
-	*FreeNumber -= 1;
-
-	return RetTxIdx;
-
-}
-
-
-VOID RtmpPCI_FinalWriteTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	USHORT			totalMPDUSize,
-	IN	USHORT			FirstTxIdx)
-{
-
-	PTXWI_STRUC		pTxWI;
-	PRTMP_TX_RING	pTxRing;
-
-	//
-	// get Tx Ring Resource
-	//
-	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
-	pTxWI = (PTXWI_STRUC) pTxRing->Cell[FirstTxIdx].DmaBuf.AllocVa;
-	pTxWI->MPDUtotalByteCount = totalMPDUSize;
-}
-
-
-VOID RtmpPCIDataLastTxIdx(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			QueIdx,
-	IN	USHORT			LastTxIdx)
-{
-	PTXD_STRUC		pTxD;
-	PRTMP_TX_RING	pTxRing;
-
-	//
-	// get Tx Ring Resource
-	//
-	pTxRing = &pAd->TxRing[QueIdx];
-
-	//
-	// build Tx Descriptor
-	//
-	pTxD = (PTXD_STRUC) pTxRing->Cell[LastTxIdx].AllocVa;
-
-	pTxD->LastSec1 = 1;
-}
-
-
-USHORT	RtmpPCI_WriteFragTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	UCHAR			fragNum,
-	OUT	USHORT			*FreeNumber)
-{
-	UCHAR			*pDMAHeaderBufVA;
-	USHORT			TxIdx, RetTxIdx;
-	PTXD_STRUC		pTxD;
-	UINT32			BufBasePaLow;
-	PRTMP_TX_RING	pTxRing;
-	USHORT			hwHeaderLen;
-	UINT32			firstDMALen;
-
-	//
-	// Get Tx Ring Resource
-	//
-	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
-	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
-	pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
-	BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
-
-	//
-	// Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
-	//
-	hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
-
-	firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen;
-	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen);
-
-
-	//
-	// Build Tx Descriptor
-	//
-	pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
-
-	NdisZeroMemory(pTxD, TXD_SIZE);
-
-	if (fragNum == pTxBlk->TotalFragNum)
-	{
-		pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
-		pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
-	}
-
-	pTxD->SDPtr0 = BufBasePaLow;
-	pTxD->SDLen0 = firstDMALen; // include padding
-	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
-	pTxD->SDLen1 = pTxBlk->SrcBufLen;
-	pTxD->LastSec0 = 0;
-	pTxD->LastSec1 = 1;
-
-	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
-
-	RetTxIdx = TxIdx;
-	pTxBlk->Priv += pTxBlk->SrcBufLen;
-
-	//
-	// Update Tx index
-	//
-	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
-	pTxRing->TxCpuIdx = TxIdx;
-
-	*FreeNumber -= 1;
-
-	return RetTxIdx;
-
-}
-
-/*
-	Must be run in Interrupt context
-	This function handle PCI specific TxDesc and cpu index update and kick the packet out.
- */
-int RtmpPCIMgmtKickOut(
-	IN RTMP_ADAPTER 	*pAd,
-	IN UCHAR 			QueIdx,
-	IN PNDIS_PACKET		pPacket,
-	IN PUCHAR			pSrcBufVA,
-	IN UINT 			SrcBufLen)
-{
-	PTXD_STRUC		pTxD;
-	ULONG			SwIdx = pAd->MgmtRing.TxCpuIdx;
-
-	pTxD  = (PTXD_STRUC) pAd->MgmtRing.Cell[SwIdx].AllocVa;
-	if (!pTxD)
-		return 0;
-
-	pAd->MgmtRing.Cell[SwIdx].pNdisPacket = pPacket;
-	pAd->MgmtRing.Cell[SwIdx].pNextNdisPacket = NULL;
-
-	RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_MGMT);
-	pTxD->LastSec0 = 1;
-	pTxD->LastSec1 = 1;
-	pTxD->DMADONE = 0;
-	pTxD->SDLen1 = 0;
-	pTxD->SDPtr0 = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);;
-	pTxD->SDLen0 = SrcBufLen;
-
-	pAd->RalinkCounters.KickTxCount++;
-	pAd->RalinkCounters.OneSecTxDoneCount++;
-
-	// Increase TX_CTX_IDX, but write to register later.
-	INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
-
-	RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX,  pAd->MgmtRing.TxCpuIdx);
-
-	return 0;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
-
-	Arguments:
-		pRxD		Pointer to the Rx descriptor
-
-	Return Value:
-		NDIS_STATUS_SUCCESS 	No err
-		NDIS_STATUS_FAILURE 	Error
-
-	Note:
-
-	========================================================================
-*/
-NDIS_STATUS RTMPCheckRxError(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	PHEADER_802_11		pHeader,
-	IN	PRXWI_STRUC 		pRxWI,
-	IN  PRT28XX_RXD_STRUC 	pRxD)
-{
-	PCIPHER_KEY pWpaKey;
-	INT dBm;
-
-	// Phy errors & CRC errors
-	if (/*(pRxD->PhyErr) ||*/ (pRxD->Crc))
-	{
-		// Check RSSI for Noise Hist statistic collection.
-		dBm = (INT) (pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
-		if (dBm <= -87)
-			pAd->StaCfg.RPIDensity[0] += 1;
-		else if (dBm <= -82)
-			pAd->StaCfg.RPIDensity[1] += 1;
-		else if (dBm <= -77)
-			pAd->StaCfg.RPIDensity[2] += 1;
-		else if (dBm <= -72)
-			pAd->StaCfg.RPIDensity[3] += 1;
-		else if (dBm <= -67)
-			pAd->StaCfg.RPIDensity[4] += 1;
-		else if (dBm <= -62)
-			pAd->StaCfg.RPIDensity[5] += 1;
-		else if (dBm <= -57)
-			pAd->StaCfg.RPIDensity[6] += 1;
-		else if (dBm > -57)
-			pAd->StaCfg.RPIDensity[7] += 1;
-
-		return(NDIS_STATUS_FAILURE);
-	}
-
-	// Add Rx size to channel load counter, we should ignore error counts
-	pAd->StaCfg.CLBusyBytes += (pRxD->SDL0 + 14);
-
-	// Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics
-	if (pHeader != NULL)
-	{
-		if (pHeader->FC.ToDs)
-		{
-			return(NDIS_STATUS_FAILURE);
-		}
-	}
-
-	// Drop not U2M frames, cant's drop here because we will drop beacon in this case
-	// I am kind of doubting the U2M bit operation
-	// if (pRxD->U2M == 0)
-	//	return(NDIS_STATUS_FAILURE);
-
-	// drop decyption fail frame
-	if (pRxD->CipherErr)
-	{
-		if (pRxD->CipherErr == 2)
-			{DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: ICV ok but MICErr "));}
-		else if (pRxD->CipherErr == 1)
-			{DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: ICV Err "));}
-		else if (pRxD->CipherErr == 3)
-			DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: Key not valid "));
-
-        if (((pRxD->CipherErr & 1) == 1) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
-            RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-
-		DBGPRINT_RAW(RT_DEBUG_TRACE,(" %d (len=%d, Mcast=%d, MyBss=%d, Wcid=%d, KeyId=%d)\n",
-			pRxD->CipherErr,
-			pRxD->SDL0,
-			pRxD->Mcast | pRxD->Bcast,
-			pRxD->MyBss,
-			pRxWI->WirelessCliID,
-			pRxWI->KeyIndex));
-
-		//
-		// MIC Error
-		//
-		if (pRxD->CipherErr == 2)
-		{
-			pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
-
-            if (pAd->StaCfg.WpaSupplicantUP)
-                WpaSendMicFailureToWpaSupplicant(pAd,
-                                   (pWpaKey->Type == PAIRWISEKEY) ? TRUE:FALSE);
-            else
-			    RTMPReportMicError(pAd, pWpaKey);
-
-            if (((pRxD->CipherErr & 2) == 2) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
-                RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-
-			DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n"));
-		}
-
-		if (pHeader == NULL)
-			return(NDIS_STATUS_SUCCESS);
-
-		return(NDIS_STATUS_FAILURE);
-	}
-
-	return(NDIS_STATUS_SUCCESS);
-}
-
-/*
-	==========================================================================
-	Description:
-		This routine sends command to firmware and turn our chip to power save mode.
-		Both RadioOff and .11 power save function needs to call this routine.
-	Input:
-		Level = GUIRADIO_OFF  : GUI Radio Off mode
-		Level = DOT11POWERSAVE  : 802.11 power save mode
-		Level = RTMP_HALT  : When Disable device.
-
-	==========================================================================
- */
-VOID RT28xxPciAsicRadioOff(
-	IN PRTMP_ADAPTER    pAd,
-	IN UCHAR            Level,
-	IN USHORT           TbttNumToNextWakeUp)
-{
-	WPDMA_GLO_CFG_STRUC	DmaCfg;
-	UCHAR		i, tempBBP_R3 = 0;
-	BOOLEAN		brc = FALSE, Cancelled;
-    UINT32		TbTTTime = 0;
-	UINT32		PsPollTime = 0, MACValue;
-    ULONG		BeaconPeriodTime;
-    UINT32		RxDmaIdx, RxCpuIdx;
-	DBGPRINT(RT_DEBUG_TRACE, ("AsicRadioOff ===> TxCpuIdx = %d, TxDmaIdx = %d. RxCpuIdx = %d, RxDmaIdx = %d.\n", pAd->TxRing[0].TxCpuIdx, pAd->TxRing[0].TxDmaIdx, pAd->RxRing.RxCpuIdx, pAd->RxRing.RxDmaIdx));
-
-    // Check Rx DMA busy status, if more than half is occupied, give up this radio off.
-	RTMP_IO_READ32(pAd, RX_DRX_IDX , &RxDmaIdx);
-	RTMP_IO_READ32(pAd, RX_CRX_IDX , &RxCpuIdx);
-	if ((RxDmaIdx > RxCpuIdx) && ((RxDmaIdx - RxCpuIdx) > RX_RING_SIZE/3))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("AsicRadioOff ===> return1. RxDmaIdx = %d ,  RxCpuIdx = %d. \n", RxDmaIdx, RxCpuIdx));
-		return;
-	}
-	else if ((RxCpuIdx >= RxDmaIdx) && ((RxCpuIdx - RxDmaIdx) < RX_RING_SIZE/3))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("AsicRadioOff ===> return2.  RxCpuIdx = %d. RxDmaIdx = %d ,  \n", RxCpuIdx, RxDmaIdx));
-		return;
-	}
-
-    // Once go into this function, disable tx because don't want too many packets in queue to prevent HW stops.
-	RTMP_SET_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
-
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
-	{
-	    RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer,	&Cancelled);
-	    RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
-
-	    if (Level == DOT11POWERSAVE)
-		{
-			RTMP_IO_READ32(pAd, TBTT_TIMER, &TbTTTime);
-			TbTTTime &= 0x1ffff;
-			// 00. check if need to do sleep in this DTIM period.   If next beacon will arrive within 30ms , ...doesn't necessarily sleep.
-			// TbTTTime uint = 64us, LEAD_TIME unit = 1024us, PsPollTime unit = 1ms
-	        if  (((64*TbTTTime) <((LEAD_TIME*1024) + 40000)) && (TbttNumToNextWakeUp == 0))
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("TbTTTime = 0x%x , give up this sleep. \n", TbTTTime));
-	            OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-				RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
-				return;
-			}
-			else
-			{
-				PsPollTime = (64*TbTTTime- LEAD_TIME*1024)/1000;
-				PsPollTime -= 3;
-
-	            BeaconPeriodTime = pAd->CommonCfg.BeaconPeriod*102/100;
-				if (TbttNumToNextWakeUp > 0)
-					PsPollTime += ((TbttNumToNextWakeUp -1) * BeaconPeriodTime);
-
-	            pAd->Mlme.bPsPollTimerRunning = TRUE;
-				RTMPSetTimer(&pAd->Mlme.PsPollTimer, PsPollTime);
-			}
-		}
-	}
-
-    // 0. Disable Tx DMA.
-	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
-	DmaCfg.field.EnableTxDMA = 0;
-	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
-
-	// 1. Wait DMA not busy
-	i = 0;
-	do
-	{
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
-		if ((DmaCfg.field.TxDMABusy == 0) && (DmaCfg.field.RxDMABusy == 0))
-			break;
-		RTMPusecDelay(20);
-		i++;
-	}while(i < 50);
-
-	if (i >= 50)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("DMA keeps busy.  return on RT28xxPciAsicRadioOff ()\n"));
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
-		DmaCfg.field.EnableTxDMA = 1;
-		RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
-		pAd->CheckDmaBusyCount++;
-		return;
-	}
-	else
-	{
-		pAd->CheckDmaBusyCount = 0;
-	}
-
-    RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
-
-    // Set to 1R.
-	if (pAd->Antenna.field.RxPath > 1)
-	{
-		tempBBP_R3 = (pAd->StaCfg.BBPR3 & 0xE7);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, tempBBP_R3);
-	}
-
-	// In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
-	if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
-		&& (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
-	{
-		// Must using 40MHz.
-		AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
-	}
-	else
-	{
-		// Must using 20MHz.
-		AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
-	}
-
-	if (Level != RTMP_HALT)
-	{
-		// Change Interrupt bitmask.
-		RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt);
-	}
-	else
-	{
-		NICDisableInterrupt(pAd);
-	}
-
-    RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
-	// Disable MAC Rx
-	RTMP_IO_READ32(pAd, MAC_SYS_CTRL , &MACValue);
-	MACValue &= 0xf7;
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL , MACValue);
-
-	//  2. Send Sleep command
-	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
-	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
-	// send POWER-SAVE command to MCU. high-byte = 1 save power as much as possible. high byte = 0 save less power
-	AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x1);
-	//  2-1. Wait command success
-	// Status = 1 : success, Status = 2, already sleep, Status = 3, Maybe MAC is busy so can't finish this task.
-	brc = AsicCheckCommanOk(pAd, PowerSafeCID);
-
-    if (brc == FALSE)
-    {
-        // try again
-    	AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x01);   // send POWER-SAVE command to MCU. Timeout unit:40us.
-    	//RTMPusecDelay(200);
-    	brc = AsicCheckCommanOk(pAd, PowerSafeCID);
-    }
-
-	//  3. After 0x30 command is ok, send radio off command. lowbyte = 0 for power safe.
-	// If 0x30 command is not ok this time, we can ignore 0x35 command. It will make sure not cause firmware'r problem.
-	if ((Level == DOT11POWERSAVE) && (brc == TRUE))
-	{
-		AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 0, 0x00);	// lowbyte = 0 means to do power safe, NOT turn off radio.
-	 	//  3-1. Wait command success
-	 	AsicCheckCommanOk(pAd, PowerRadioOffCID);
-	}
-	else if (brc == TRUE)
-	{
-		AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 1, 0x00);	// lowbyte = 0 means to do power safe, NOT turn off radio.
-	 	//  3-1. Wait command success
-	 	AsicCheckCommanOk(pAd, PowerRadioOffCID);
-	}
-
-    // Wait DMA not busy
-	i = 0;
-	do
-	{
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
-		if ((DmaCfg.field.RxDMABusy == 0) && (DmaCfg.field.TxDMABusy == 0))
-			break;
-		RTMPusecDelay(20);
-		i++;
-	}while(i < 50);
-
-	if (i >= 50)
-	{
-		pAd->CheckDmaBusyCount++;
-		DBGPRINT(RT_DEBUG_TRACE, ("DMA Rx keeps busy.  on RT28xxPciAsicRadioOff ()\n"));
-	}
-	else
-	{
-		pAd->CheckDmaBusyCount = 0;
-	}
-
-	if (Level == DOT11POWERSAVE)
-	{
-		AUTO_WAKEUP_STRUC	AutoWakeupCfg;
-		//RTMPSetTimer(&pAd->Mlme.PsPollTimer, 90);
-
-		// we have decided to SLEEP, so at least do it for a BEACON period.
-		if (TbttNumToNextWakeUp == 0)
-			TbttNumToNextWakeUp = 1;
-
-		AutoWakeupCfg.word = 0;
-		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-
-		// 1. Set auto wake up timer.
-		AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
-		AutoWakeupCfg.field.EnableAutoWakeup = 1;
-		AutoWakeupCfg.field.AutoLeadTime = LEAD_TIME;
-		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-	}
-
-	//  4-1. If it's to disable our device. Need to restore PCI Configuration Space to its original value.
-	if (Level == RTMP_HALT)
-	{
-		if ((brc == TRUE) && (i < 50))
-			RTMPPCIeLinkCtrlSetting(pAd, 0);
-	}
-	//  4. Set PCI configuration Space Link Comtrol fields.  Only Radio Off needs to call this function
-	else
-	{
-		if ((brc == TRUE) && (i < 50))
-			RTMPPCIeLinkCtrlSetting(pAd, 3);
-	}
-
-	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
-}
-
-
-/*
-	==========================================================================
-	Description:
-		This routine sends command to firmware and turn our chip to wake up mode from power save mode.
-		Both RadioOn and .11 power save function needs to call this routine.
-	Input:
-		Level = GUIRADIO_OFF : call this function is from Radio Off to Radio On.  Need to restore PCI host value.
-		Level = other value : normal wake up function.
-
-	==========================================================================
- */
-BOOLEAN RT28xxPciAsicRadioOn(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR     Level)
-{
-    WPDMA_GLO_CFG_STRUC	DmaCfg;
-	BOOLEAN				Cancelled, brv = TRUE;
-    UINT32			    MACValue;
-
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
-	{
-	    pAd->Mlme.bPsPollTimerRunning = FALSE;
-		RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
-		if ((Level == GUIRADIO_OFF) || (Level == GUI_IDLE_POWER_SAVE)
-		|| (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND)))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("RT28xxPciAsicRadioOn ()\n"));
-			// 1. Set PCI Link Control in Configuration Space.
-			RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
-			RTMPusecDelay(6000);
-		}
-	}
-
-    pAd->bPCIclkOff = FALSE;
-	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x3a80);
-	// 2. Send wake up command.
-	AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02);
-
-	// 2-1. wait command ok.
-	brv = AsicCheckCommanOk(pAd, PowerWakeCID);
-    if (brv)
-    {
-    	NICEnableInterrupt(pAd);
-
-    	// 3. Enable Tx DMA.
-    	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
-    	DmaCfg.field.EnableTxDMA = 1;
-        DmaCfg.field.EnableRxDMA = 1;
-    	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
-
-        // Eable MAC Rx
-    	RTMP_IO_READ32(pAd, MAC_SYS_CTRL , &MACValue);
-    	MACValue |= 0x8;
-    	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL , MACValue);
-
-    	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
-    	if (Level == GUI_IDLE_POWER_SAVE)
-    	{
-    		// In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
-    		if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
-    			&& (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
-    		{
-    			// Must using 40MHz.
-    			AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
-    			AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
-    		}
-    		else
-    		{
-    			// Must using 20MHz.
-    			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-    			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-    		}
-    	}
-        return TRUE;
-    }
-    else
-        return FALSE;
-}
-
-VOID RT28xxPciStaAsicForceWakeup(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR    	 Level)
-{
-    AUTO_WAKEUP_STRUC	AutoWakeupCfg;
-
-    if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW))
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n"));
-        return;
-    }
-
-    OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
-	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
-
-    if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
-    {
-        // Support PCIe Advance Power Save
-    	if (((Level == FROM_TX) && (pAd->Mlme.bPsPollTimerRunning == TRUE)) ||
-			(Level == RTMP_HALT))
-    	{
-            pAd->Mlme.bPsPollTimerRunning = FALSE;
-    		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
-    		RTMPusecDelay(5000);
-            DBGPRINT(RT_DEBUG_TRACE, ("=======AsicForceWakeup===bFromTx\n"));
-    	}
-
-		AutoWakeupCfg.word = 0;
-		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-
-		// If this is called from Halt. ALWAYS force wakeup!!!
-		if (Level == RTMP_HALT)
-		{
-			RT28xxPciAsicRadioOn(pAd, RTMP_HALT);
-		}
-		else
-		{
-			if (RT28xxPciAsicRadioOn(pAd, DOT11POWERSAVE))
-			{
-				// In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
-				if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
-					&& (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
-				{
-					// Must using 40MHz.
-					AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
-					AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
-				}
-				else
-				{
-					// Must using 20MHz.
-					AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-					AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-				}
-			}
-		}
-    }
-    else
-    {
-        // PCI, 2860-PCIe
-        AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x00);
-		AutoWakeupCfg.word = 0;
-		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-    }
-
-    OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-    OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
-    DBGPRINT(RT_DEBUG_TRACE, ("<=======RT28xxPciStaAsicForceWakeup\n"));
-}
-
-VOID RT28xxPciStaAsicSleepThenAutoWakeup(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT TbttNumToNextWakeUp)
-{
-    if (pAd->StaCfg.bRadio == FALSE)
-	{
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-		return;
-	}
-    if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
-    {
-    	ULONG	Now = 0;
-        if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW))
-        {
-            DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n"));
-            OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-            return;
-        }
-
-		NdisGetSystemUpTime(&Now);
-		// If last send NULL fram time is too close to this receiving beacon (within 8ms), don't go to sleep for this DTM.
-		// Because Some AP can't queuing outgoing frames immediately.
-		if (((pAd->Mlme.LastSendNULLpsmTime + 8) >= Now) && (pAd->Mlme.LastSendNULLpsmTime <= Now))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("Now = %lu, LastSendNULLpsmTime=%lu :  RxCountSinceLastNULL = %lu. \n", Now, pAd->Mlme.LastSendNULLpsmTime, pAd->RalinkCounters.RxCountSinceLastNULL));
-			return;
-		}
-		else if ((pAd->RalinkCounters.RxCountSinceLastNULL > 0) && ((pAd->Mlme.LastSendNULLpsmTime + pAd->CommonCfg.BeaconPeriod) >= Now))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("Now = %lu, LastSendNULLpsmTime=%lu: RxCountSinceLastNULL = %lu > 0 \n", Now, pAd->Mlme.LastSendNULLpsmTime,  pAd->RalinkCounters.RxCountSinceLastNULL));
-			return;
-		}
-
-        RT28xxPciAsicRadioOff(pAd, DOT11POWERSAVE, TbttNumToNextWakeUp);
-    }
-    else
-    {
-        AUTO_WAKEUP_STRUC	AutoWakeupCfg;
-        // we have decided to SLEEP, so at least do it for a BEACON period.
-        if (TbttNumToNextWakeUp == 0)
-            TbttNumToNextWakeUp = 1;
-
-        AutoWakeupCfg.word = 0;
-        RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-        AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
-        AutoWakeupCfg.field.EnableAutoWakeup = 1;
-        AutoWakeupCfg.field.AutoLeadTime = 5;
-        RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-        AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x00);   // send POWER-SAVE command to MCU. Timeout 40us.
-        DBGPRINT(RT_DEBUG_TRACE, ("<-- %s, TbttNumToNextWakeUp=%d \n", __func__, TbttNumToNextWakeUp));
-    }
-    OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
-}
-
-VOID PsPollWakeExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3)
-{
-	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
-	unsigned long flags;
-
-    DBGPRINT(RT_DEBUG_TRACE,("-->PsPollWakeExec \n"));
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-    if (pAd->Mlme.bPsPollTimerRunning)
-    {
-	    RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
-    }
-    pAd->Mlme.bPsPollTimerRunning = FALSE;
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-}
-
-VOID  RadioOnExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3)
-{
-	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
-	WPDMA_GLO_CFG_STRUC	DmaCfg;
-	BOOLEAN				Cancelled;
-
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("-->RadioOnExec() return on fOP_STATUS_DOZE == TRUE; \n"));
-		RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
-		return;
-	}
-
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("-->RadioOnExec() return on SCAN_IN_PROGRESS; \n"));
-		RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
-		return;
-	}
-    pAd->Mlme.bPsPollTimerRunning = FALSE;
-	RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
-	if (pAd->StaCfg.bRadio == TRUE)
-	{
-		pAd->bPCIclkOff = FALSE;
-        RTMPRingCleanUp(pAd, QID_AC_BK);
-		RTMPRingCleanUp(pAd, QID_AC_BE);
-		RTMPRingCleanUp(pAd, QID_AC_VI);
-		RTMPRingCleanUp(pAd, QID_AC_VO);
-		RTMPRingCleanUp(pAd, QID_HCCA);
-		RTMPRingCleanUp(pAd, QID_MGMT);
-		RTMPRingCleanUp(pAd, QID_RX);
-
-		// 2. Send wake up command.
-		AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02);
-		// 2-1. wait command ok.
-		AsicCheckCommanOk(pAd, PowerWakeCID);
-
-		// When PCI clock is off, don't want to service interrupt. So when back to clock on, enable interrupt.
-		NICEnableInterrupt(pAd);
-
-		// 3. Enable Tx DMA.
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
-		DmaCfg.field.EnableTxDMA = 1;
-		RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
-
-		// In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
-		if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
-			&& (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
-		{
-			// Must using 40MHz.
-			AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
-			AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
-		}
-		else
-		{
-			// Must using 20MHz.
-			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-		}
-
-		// Clear Radio off flag
-		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-		// Set LED
-		RTMPSetLED(pAd, LED_RADIO_ON);
-
-        if (pAd->StaCfg.Psm == PWR_ACTIVE)
-        {
-    		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
-        }
-	}
-	else
-	{
-		RT28xxPciAsicRadioOff(pAd, GUIRADIO_OFF, 0);
-	}
-}
-
-VOID RT28xxPciMlmeRadioOn(
-	IN PRTMP_ADAPTER pAd)
-{
-    if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
-   		return;
-
-    DBGPRINT(RT_DEBUG_TRACE,("%s===>\n", __func__));
-
-    if ((pAd->OpMode == OPMODE_AP) ||
-        ((pAd->OpMode == OPMODE_STA) && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))))
-    {
-    	NICResetFromError(pAd);
-
-    	/*
-    	RTMPRingCleanUp(pAd, QID_AC_BK);
-    	RTMPRingCleanUp(pAd, QID_AC_BE);
-    	RTMPRingCleanUp(pAd, QID_AC_VI);
-    	RTMPRingCleanUp(pAd, QID_AC_VO);
-    	RTMPRingCleanUp(pAd, QID_HCCA);
-    	RTMPRingCleanUp(pAd, QID_MGMT);
-    	RTMPRingCleanUp(pAd, QID_RX);
-		*/
-
-    	// Enable Tx/Rx
-    	RTMPEnableRxTx(pAd);
-
-    	// Clear Radio off flag
-    	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-	    // Set LED
-	    RTMPSetLED(pAd, LED_RADIO_ON);
-    }
-
-    if ((pAd->OpMode == OPMODE_STA) &&
-        (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)))
-    {
-        BOOLEAN		Cancelled;
-
-    	RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
-
-        pAd->Mlme.bPsPollTimerRunning = FALSE;
-    	RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
-    	RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer,	&Cancelled);
-    	RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
-    }
-}
-
-VOID RT28xxPciMlmeRadioOFF(
-	IN PRTMP_ADAPTER pAd)
-{
-    WPDMA_GLO_CFG_STRUC	GloCfg;
-	UINT32	i;
-
-	if (pAd->StaCfg.bRadio == TRUE)
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("-->MlmeRadioOff() return on bRadio == TRUE; \n"));
-		return;
-	}
-
-    if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
-    	return;
-
-    DBGPRINT(RT_DEBUG_TRACE,("%s===>\n", __func__));
-
-	// Set LED
-	RTMPSetLED(pAd, LED_RADIO_OFF);
-
-    {
-    	BOOLEAN		Cancelled;
-
-    	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-    	{
-			RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
-			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
-    	}
-
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
-        {
-            BOOLEAN Cancelled;
-
-			// Always radio on since the NIC needs to set the MCU command (LED_RADIO_OFF).

-			if ((pAd->OpMode == OPMODE_STA) && 

-			     (IDLE_ON(pAd)) && 

-			     (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))

-			{

-				RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);

-			}
-
-            pAd->Mlme.bPsPollTimerRunning = FALSE;
-            RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
-	        RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer,	&Cancelled);
-        }
-
-        // Link down first if any association exists
-        if (INFRA_ON(pAd) || ADHOC_ON(pAd))
-            LinkDown(pAd, FALSE);
-        RTMPusecDelay(10000);
-        //==========================================
-        // Clean up old bss table
-        BssTableInit(&pAd->ScanTab);
-
-		RTMPRingCleanUp(pAd, QID_AC_BK);
-    	RTMPRingCleanUp(pAd, QID_AC_BE);
-    	RTMPRingCleanUp(pAd, QID_AC_VI);
-    	RTMPRingCleanUp(pAd, QID_AC_VO);
-    	RTMPRingCleanUp(pAd, QID_HCCA);
-    	RTMPRingCleanUp(pAd, QID_MGMT);
-    	RTMPRingCleanUp(pAd, QID_RX);
-
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
-		{
-			RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 500);
-			return;
-		}
-    }
-
-	// Set Radio off flag
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-	// Disable Tx/Rx DMA
-	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);	   // disable DMA
-	GloCfg.field.EnableTxDMA = 0;
-	GloCfg.field.EnableRxDMA = 0;
-	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);	   // abort all TX rings
-
-
-	// MAC_SYS_CTRL => value = 0x0 => 40mA
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0);
-
-	// PWR_PIN_CFG => value = 0x0 => 40mA
-	RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0);
-
-	// TX_PIN_CFG => value = 0x0 => 20mA
-	RTMP_IO_WRITE32(pAd, TX_PIN_CFG, 0);
-
-	if (pAd->CommonCfg.BBPCurrentBW == BW_40)
-	{
-		// Must using 40MHz.
-		AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
-	}
-	else
-	{
-		// Must using 20MHz.
-		AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
-	}
-
-	// Waiting for DMA idle
-	i = 0;
-	do
-	{
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-		if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
-			break;
-
-		RTMPusecDelay(1000);
-	}while (i++ < 100);
-}
diff --git a/drivers/staging/rt2860/common/cmm_data_pci.c b/drivers/staging/rt2860/common/cmm_data_pci.c
new file mode 100644
index 0000000..43d73a0
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_data_pci.c
@@ -0,0 +1,1096 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+ */
+
+/*
+   All functions in this file must be PCI-depended, or you should out your function
+	in other files.
+
+*/
+#include	"../rt_config.h"
+
+u16 RtmpPCI_WriteTxResource(struct rt_rtmp_adapter *pAd,
+			       struct rt_tx_blk *pTxBlk,
+			       IN BOOLEAN bIsLast, u16 * FreeNumber)
+{
+
+	u8 *pDMAHeaderBufVA;
+	u16 TxIdx, RetTxIdx;
+	struct rt_txd * pTxD;
+	u32 BufBasePaLow;
+	struct rt_rtmp_tx_ring *pTxRing;
+	u16 hwHeaderLen;
+
+	/* */
+	/* get Tx Ring Resource */
+	/* */
+	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
+	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
+	pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
+	BufBasePaLow =
+	    RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
+
+	/* copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
+	if (pTxBlk->TxFrameType == TX_AMSDU_FRAME) {
+		/*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; */
+		hwHeaderLen =
+		    pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD +
+		    pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
+	} else {
+		/*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
+		hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+	}
+	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf,
+		       TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
+
+	pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
+	pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
+
+	/* */
+	/* build Tx Descriptor */
+	/* */
+
+	pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa;
+	NdisZeroMemory(pTxD, TXD_SIZE);
+
+	pTxD->SDPtr0 = BufBasePaLow;
+	pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen;	/* include padding */
+	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
+	pTxD->SDLen1 = pTxBlk->SrcBufLen;
+	pTxD->LastSec0 = 0;
+	pTxD->LastSec1 = (bIsLast) ? 1 : 0;
+
+	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
+
+	RetTxIdx = TxIdx;
+	/* */
+	/* Update Tx index */
+	/* */
+	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
+	pTxRing->TxCpuIdx = TxIdx;
+
+	*FreeNumber -= 1;
+
+	return RetTxIdx;
+}
+
+u16 RtmpPCI_WriteSingleTxResource(struct rt_rtmp_adapter *pAd,
+				     struct rt_tx_blk *pTxBlk,
+				     IN BOOLEAN bIsLast,
+				     u16 * FreeNumber)
+{
+
+	u8 *pDMAHeaderBufVA;
+	u16 TxIdx, RetTxIdx;
+	struct rt_txd * pTxD;
+	u32 BufBasePaLow;
+	struct rt_rtmp_tx_ring *pTxRing;
+	u16 hwHeaderLen;
+
+	/* */
+	/* get Tx Ring Resource */
+	/* */
+	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
+	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
+	pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
+	BufBasePaLow =
+	    RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
+
+	/* copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
+	/*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
+	hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+
+	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf,
+		       TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
+
+	pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
+	pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
+
+	/* */
+	/* build Tx Descriptor */
+	/* */
+	pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa;
+	NdisZeroMemory(pTxD, TXD_SIZE);
+
+	pTxD->SDPtr0 = BufBasePaLow;
+	pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen;	/* include padding */
+	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);;
+	pTxD->SDLen1 = pTxBlk->SrcBufLen;
+	pTxD->LastSec0 = 0;
+	pTxD->LastSec1 = (bIsLast) ? 1 : 0;
+
+	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
+
+	RetTxIdx = TxIdx;
+	/* */
+	/* Update Tx index */
+	/* */
+	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
+	pTxRing->TxCpuIdx = TxIdx;
+
+	*FreeNumber -= 1;
+
+	return RetTxIdx;
+}
+
+u16 RtmpPCI_WriteMultiTxResource(struct rt_rtmp_adapter *pAd,
+				    struct rt_tx_blk *pTxBlk,
+				    u8 frameNum, u16 * FreeNumber)
+{
+	BOOLEAN bIsLast;
+	u8 *pDMAHeaderBufVA;
+	u16 TxIdx, RetTxIdx;
+	struct rt_txd * pTxD;
+	u32 BufBasePaLow;
+	struct rt_rtmp_tx_ring *pTxRing;
+	u16 hwHdrLen;
+	u32 firstDMALen;
+
+	bIsLast = ((frameNum == (pTxBlk->TotalFrameNum - 1)) ? 1 : 0);
+
+	/* */
+	/* get Tx Ring Resource */
+	/* */
+	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
+	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
+	pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
+	BufBasePaLow =
+	    RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
+
+	if (frameNum == 0) {
+		/* copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
+		if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
+			/*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; */
+			hwHdrLen =
+			    pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD +
+			    pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
+		else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
+			/*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD; */
+			hwHdrLen =
+			    pTxBlk->MpduHeaderLen -
+			    LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen +
+			    LENGTH_ARALINK_HEADER_FIELD;
+		else
+			/*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
+			hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+
+		firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
+	} else {
+		firstDMALen = pTxBlk->MpduHeaderLen;
+	}
+
+	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen);
+
+	pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
+	pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
+
+	/* */
+	/* build Tx Descriptor */
+	/* */
+	pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa;
+	NdisZeroMemory(pTxD, TXD_SIZE);
+
+	pTxD->SDPtr0 = BufBasePaLow;
+	pTxD->SDLen0 = firstDMALen;	/* include padding */
+	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);;
+	pTxD->SDLen1 = pTxBlk->SrcBufLen;
+	pTxD->LastSec0 = 0;
+	pTxD->LastSec1 = (bIsLast) ? 1 : 0;
+
+	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
+
+	RetTxIdx = TxIdx;
+	/* */
+	/* Update Tx index */
+	/* */
+	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
+	pTxRing->TxCpuIdx = TxIdx;
+
+	*FreeNumber -= 1;
+
+	return RetTxIdx;
+
+}
+
+void RtmpPCI_FinalWriteTxResource(struct rt_rtmp_adapter *pAd,
+				  struct rt_tx_blk *pTxBlk,
+				  u16 totalMPDUSize, u16 FirstTxIdx)
+{
+
+	struct rt_txwi * pTxWI;
+	struct rt_rtmp_tx_ring *pTxRing;
+
+	/* */
+	/* get Tx Ring Resource */
+	/* */
+	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
+	pTxWI = (struct rt_txwi *) pTxRing->Cell[FirstTxIdx].DmaBuf.AllocVa;
+	pTxWI->MPDUtotalByteCount = totalMPDUSize;
+
+}
+
+void RtmpPCIDataLastTxIdx(struct rt_rtmp_adapter *pAd,
+			  u8 QueIdx, u16 LastTxIdx)
+{
+	struct rt_txd * pTxD;
+	struct rt_rtmp_tx_ring *pTxRing;
+
+	/* */
+	/* get Tx Ring Resource */
+	/* */
+	pTxRing = &pAd->TxRing[QueIdx];
+
+	/* */
+	/* build Tx Descriptor */
+	/* */
+	pTxD = (struct rt_txd *) pTxRing->Cell[LastTxIdx].AllocVa;
+
+	pTxD->LastSec1 = 1;
+
+}
+
+u16 RtmpPCI_WriteFragTxResource(struct rt_rtmp_adapter *pAd,
+				   struct rt_tx_blk *pTxBlk,
+				   u8 fragNum, u16 * FreeNumber)
+{
+	u8 *pDMAHeaderBufVA;
+	u16 TxIdx, RetTxIdx;
+	struct rt_txd * pTxD;
+	u32 BufBasePaLow;
+	struct rt_rtmp_tx_ring *pTxRing;
+	u16 hwHeaderLen;
+	u32 firstDMALen;
+
+	/* */
+	/* Get Tx Ring Resource */
+	/* */
+	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
+	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
+	pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
+	BufBasePaLow =
+	    RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
+
+	/* */
+	/* Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
+	/* */
+	/*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
+	hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+
+	firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen;
+	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen);
+
+	/* */
+	/* Build Tx Descriptor */
+	/* */
+	pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa;
+	NdisZeroMemory(pTxD, TXD_SIZE);
+
+	if (fragNum == pTxBlk->TotalFragNum) {
+		pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
+		pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
+	}
+
+	pTxD->SDPtr0 = BufBasePaLow;
+	pTxD->SDLen0 = firstDMALen;	/* include padding */
+	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
+	pTxD->SDLen1 = pTxBlk->SrcBufLen;
+	pTxD->LastSec0 = 0;
+	pTxD->LastSec1 = 1;
+
+	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
+
+	RetTxIdx = TxIdx;
+	pTxBlk->Priv += pTxBlk->SrcBufLen;
+
+	/* */
+	/* Update Tx index */
+	/* */
+	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
+	pTxRing->TxCpuIdx = TxIdx;
+
+	*FreeNumber -= 1;
+
+	return RetTxIdx;
+
+}
+
+/*
+	Must be run in Interrupt context
+	This function handle PCI specific TxDesc and cpu index update and kick the packet out.
+ */
+int RtmpPCIMgmtKickOut(struct rt_rtmp_adapter *pAd,
+		       u8 QueIdx,
+		       void *pPacket,
+		       u8 *pSrcBufVA, u32 SrcBufLen)
+{
+	struct rt_txd * pTxD;
+	unsigned long SwIdx = pAd->MgmtRing.TxCpuIdx;
+
+	pTxD = (struct rt_txd *) pAd->MgmtRing.Cell[SwIdx].AllocVa;
+
+	pAd->MgmtRing.Cell[SwIdx].pNdisPacket = pPacket;
+	pAd->MgmtRing.Cell[SwIdx].pNextNdisPacket = NULL;
+
+	RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_MGMT);
+	pTxD->LastSec0 = 1;
+	pTxD->LastSec1 = 1;
+	pTxD->DMADONE = 0;
+	pTxD->SDLen1 = 0;
+	pTxD->SDPtr0 =
+	    PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
+	pTxD->SDLen0 = SrcBufLen;
+
+/*================================================================== */
+/*	DBGPRINT_RAW(RT_DEBUG_TRACE, ("MLMEHardTransmit\n"));
+	for (i = 0; i < (TXWI_SIZE+24); i++)
+	{
+
+		DBGPRINT_RAW(RT_DEBUG_TRACE, ("%x:", *(pSrcBufVA+i)));
+		if ( i%4 == 3)
+			DBGPRINT_RAW(RT_DEBUG_TRACE, (" :: "));
+		if ( i%16 == 15)
+			DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n      "));
+	}
+	DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n      "));*/
+/*======================================================================= */
+
+	pAd->RalinkCounters.KickTxCount++;
+	pAd->RalinkCounters.OneSecTxDoneCount++;
+
+	/* Increase TX_CTX_IDX, but write to register later. */
+	INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
+
+	RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
+
+	return 0;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
+
+	Arguments:
+		pRxD		Pointer to the Rx descriptor
+
+	Return Value:
+		NDIS_STATUS_SUCCESS	No err
+		NDIS_STATUS_FAILURE	Error
+
+	Note:
+
+	========================================================================
+*/
+int RTMPCheckRxError(struct rt_rtmp_adapter *pAd,
+			     struct rt_header_802_11 * pHeader,
+			     struct rt_rxwi * pRxWI, IN PRT28XX_RXD_STRUC pRxD)
+{
+	struct rt_cipher_key *pWpaKey;
+	int dBm;
+
+	/* Phy errors & CRC errors */
+	if ( /*(pRxD->PhyErr) || */ (pRxD->Crc)) {
+		/* Check RSSI for Noise Hist statistic collection. */
+		dBm = (int)(pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
+		if (dBm <= -87)
+			pAd->StaCfg.RPIDensity[0] += 1;
+		else if (dBm <= -82)
+			pAd->StaCfg.RPIDensity[1] += 1;
+		else if (dBm <= -77)
+			pAd->StaCfg.RPIDensity[2] += 1;
+		else if (dBm <= -72)
+			pAd->StaCfg.RPIDensity[3] += 1;
+		else if (dBm <= -67)
+			pAd->StaCfg.RPIDensity[4] += 1;
+		else if (dBm <= -62)
+			pAd->StaCfg.RPIDensity[5] += 1;
+		else if (dBm <= -57)
+			pAd->StaCfg.RPIDensity[6] += 1;
+		else if (dBm > -57)
+			pAd->StaCfg.RPIDensity[7] += 1;
+
+		return (NDIS_STATUS_FAILURE);
+	}
+	/* Add Rx size to channel load counter, we should ignore error counts */
+	pAd->StaCfg.CLBusyBytes += (pRxD->SDL0 + 14);
+
+	/* Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics */
+	if (pHeader != NULL) {
+		if (pHeader->FC.ToDs) {
+			return (NDIS_STATUS_FAILURE);
+		}
+	}
+	/* Drop not U2M frames, cant's drop here because we will drop beacon in this case */
+	/* I am kind of doubting the U2M bit operation */
+	/* if (pRxD->U2M == 0) */
+	/*      return(NDIS_STATUS_FAILURE); */
+
+	/* drop decyption fail frame */
+	if (pRxD->CipherErr) {
+		if (pRxD->CipherErr == 2) {
+			DBGPRINT_RAW(RT_DEBUG_TRACE,
+				     ("pRxD ERROR: ICV ok but MICErr "));
+		} else if (pRxD->CipherErr == 1) {
+			DBGPRINT_RAW(RT_DEBUG_TRACE, ("pRxD ERROR: ICV Err "));
+		} else if (pRxD->CipherErr == 3)
+			DBGPRINT_RAW(RT_DEBUG_TRACE,
+				     ("pRxD ERROR: Key not valid "));
+
+		if (((pRxD->CipherErr & 1) == 1)
+		    && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
+			RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG,
+					      pAd->MacTab.Content[BSSID_WCID].
+					      Addr, BSS0, 0);
+
+		DBGPRINT_RAW(RT_DEBUG_TRACE,
+			     (" %d (len=%d, Mcast=%d, MyBss=%d, Wcid=%d, KeyId=%d)\n",
+			      pRxD->CipherErr, pRxD->SDL0,
+			      pRxD->Mcast | pRxD->Bcast, pRxD->MyBss,
+			      pRxWI->WirelessCliID,
+/*                      CipherName[pRxD->CipherAlg], */
+			      pRxWI->KeyIndex));
+
+		/* */
+		/* MIC Error */
+		/* */
+		if (pRxD->CipherErr == 2) {
+			pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
+			if (pAd->StaCfg.WpaSupplicantUP)
+				WpaSendMicFailureToWpaSupplicant(pAd,
+								 (pWpaKey->
+								  Type ==
+								  PAIRWISEKEY) ?
+								 TRUE : FALSE);
+			else
+				RTMPReportMicError(pAd, pWpaKey);
+
+			if (((pRxD->CipherErr & 2) == 2)
+			    && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
+				RTMPSendWirelessEvent(pAd,
+						      IW_MIC_ERROR_EVENT_FLAG,
+						      pAd->MacTab.
+						      Content[BSSID_WCID].Addr,
+						      BSS0, 0);
+
+			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Rx MIC Value error\n"));
+		}
+
+		if (pHeader == NULL)
+			return (NDIS_STATUS_SUCCESS);
+		/*if ((pRxD->CipherAlg == CIPHER_AES) &&
+		   (pHeader->Sequence == pAd->FragFrame.Sequence))
+		   {
+		   //
+		   // Acceptable since the First FragFrame no CipherErr problem.
+		   //
+		   return(NDIS_STATUS_SUCCESS);
+		   } */
+
+		return (NDIS_STATUS_FAILURE);
+	}
+
+	return (NDIS_STATUS_SUCCESS);
+}
+
+BOOLEAN RTMPFreeTXDUponTxDmaDone(struct rt_rtmp_adapter *pAd, u8 QueIdx)
+{
+	struct rt_rtmp_tx_ring *pTxRing;
+	struct rt_txd * pTxD;
+	void *pPacket;
+	u8 FREE = 0;
+	struct rt_txd TxD, *pOriTxD;
+	/*unsigned long         IrqFlags; */
+	BOOLEAN bReschedule = FALSE;
+
+	ASSERT(QueIdx < NUM_OF_TX_RING);
+	pTxRing = &pAd->TxRing[QueIdx];
+
+	RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF,
+		       &pTxRing->TxDmaIdx);
+	while (pTxRing->TxSwFreeIdx != pTxRing->TxDmaIdx) {
+/*              RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); */
+
+		/* static rate also need NICUpdateFifoStaCounters() function. */
+		/*if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */
+		NICUpdateFifoStaCounters(pAd);
+
+		/* Note : If (pAd->ate.bQATxStart == TRUE), we will never reach here. */
+		FREE++;
+		pTxD =
+		    (struct rt_txd *) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
+		pOriTxD = pTxD;
+		NdisMoveMemory(&TxD, pTxD, sizeof(struct rt_txd));
+		pTxD = &TxD;
+
+		pTxD->DMADONE = 0;
+
+		{
+			pPacket =
+			    pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket;
+			if (pPacket) {
+				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1,
+						 pTxD->SDLen1,
+						 PCI_DMA_TODEVICE);
+				RELEASE_NDIS_PACKET(pAd, pPacket,
+						    NDIS_STATUS_SUCCESS);
+			}
+			/*Always assign pNdisPacket as NULL after clear */
+			pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket = NULL;
+
+			pPacket =
+			    pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket;
+
+			ASSERT(pPacket == NULL);
+			if (pPacket) {
+				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1,
+						 pTxD->SDLen1,
+						 PCI_DMA_TODEVICE);
+				RELEASE_NDIS_PACKET(pAd, pPacket,
+						    NDIS_STATUS_SUCCESS);
+			}
+			/*Always assign pNextNdisPacket as NULL after clear */
+			pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket =
+			    NULL;
+		}
+
+		pAd->RalinkCounters.TransmittedByteCount +=
+		    (pTxD->SDLen1 + pTxD->SDLen0);
+		pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx]++;
+		INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
+		/* get tx_tdx_idx again */
+		RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF,
+			       &pTxRing->TxDmaIdx);
+		NdisMoveMemory(pOriTxD, pTxD, sizeof(struct rt_txd));
+
+/*         RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); */
+	}
+
+	return bReschedule;
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Process TX Rings DMA Done interrupt, running in DPC level
+
+	Arguments:
+		Adapter		Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	========================================================================
+*/
+BOOLEAN RTMPHandleTxRingDmaDoneInterrupt(struct rt_rtmp_adapter *pAd,
+					 INT_SOURCE_CSR_STRUC TxRingBitmap)
+{
+/*      u8                   Count = 0; */
+	unsigned long IrqFlags;
+	BOOLEAN bReschedule = FALSE;
+
+	/* Make sure Tx ring resource won't be used by other threads */
+	/*NdisAcquireSpinLock(&pAd->TxRingLock); */
+
+	RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+
+	if (TxRingBitmap.field.Ac0DmaDone)
+		bReschedule = RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BE);
+
+	if (TxRingBitmap.field.Ac3DmaDone)
+		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VO);
+
+	if (TxRingBitmap.field.Ac2DmaDone)
+		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VI);
+
+	if (TxRingBitmap.field.Ac1DmaDone)
+		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BK);
+
+	/* Make sure to release Tx ring resource */
+	/*NdisReleaseSpinLock(&pAd->TxRingLock); */
+	RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+
+	/* Dequeue outgoing frames from TxSwQueue[] and process it */
+	RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+
+	return bReschedule;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Process MGMT ring DMA done interrupt, running in DPC level
+
+	Arguments:
+		pAd	Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+void RTMPHandleMgmtRingDmaDoneInterrupt(struct rt_rtmp_adapter *pAd)
+{
+	struct rt_txd * pTxD;
+	void *pPacket;
+/*      int              i; */
+	u8 FREE = 0;
+	struct rt_rtmp_mgmt_ring *pMgmtRing = &pAd->MgmtRing;
+
+	NdisAcquireSpinLock(&pAd->MgmtRingLock);
+
+	RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx);
+	while (pMgmtRing->TxSwFreeIdx != pMgmtRing->TxDmaIdx) {
+		FREE++;
+		pTxD =
+		    (struct rt_txd *) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].
+				  AllocVa);
+		pTxD->DMADONE = 0;
+		pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket;
+
+		if (pPacket) {
+			PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0,
+					 PCI_DMA_TODEVICE);
+			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+		}
+		pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL;
+
+		pPacket =
+		    pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket;
+		if (pPacket) {
+			PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1,
+					 PCI_DMA_TODEVICE);
+			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+		}
+		pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket = NULL;
+		INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE);
+
+	}
+	NdisReleaseSpinLock(&pAd->MgmtRingLock);
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+	Arguments:
+		Adapter		Pointer to our adapter. Dequeue all power safe delayed braodcast frames after beacon.
+
+	IRQL = DISPATCH_LEVEL
+
+	========================================================================
+*/
+void RTMPHandleTBTTInterrupt(struct rt_rtmp_adapter *pAd)
+{
+	{
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
+		}
+	}
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+	Arguments:
+		pAd		Pointer to our adapter. Rewrite beacon content before next send-out.
+
+	IRQL = DISPATCH_LEVEL
+
+	========================================================================
+*/
+void RTMPHandlePreTBTTInterrupt(struct rt_rtmp_adapter *pAd)
+{
+	{
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("RTMPHandlePreTBTTInterrupt...\n"));
+		}
+	}
+
+}
+
+void RTMPHandleRxCoherentInterrupt(struct rt_rtmp_adapter *pAd)
+{
+	WPDMA_GLO_CFG_STRUC GloCfg;
+
+	if (pAd == NULL) {
+		DBGPRINT(RT_DEBUG_TRACE, ("====> pAd is NULL, return.\n"));
+		return;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleRxCoherentInterrupt \n"));
+
+	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
+
+	GloCfg.field.EnTXWriteBackDDONE = 0;
+	GloCfg.field.EnableRxDMA = 0;
+	GloCfg.field.EnableTxDMA = 0;
+	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
+
+	RTMPRingCleanUp(pAd, QID_AC_BE);
+	RTMPRingCleanUp(pAd, QID_AC_BK);
+	RTMPRingCleanUp(pAd, QID_AC_VI);
+	RTMPRingCleanUp(pAd, QID_AC_VO);
+	RTMPRingCleanUp(pAd, QID_MGMT);
+	RTMPRingCleanUp(pAd, QID_RX);
+
+	RTMPEnableRxTx(pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleRxCoherentInterrupt \n"));
+}
+
+void *GetPacketFromRxRing(struct rt_rtmp_adapter *pAd,
+				 OUT PRT28XX_RXD_STRUC pSaveRxD,
+				 OUT BOOLEAN * pbReschedule,
+				 IN u32 * pRxPending)
+{
+	struct rt_rxd * pRxD;
+	void *pRxPacket = NULL;
+	void *pNewPacket;
+	void *AllocVa;
+	dma_addr_t AllocPa;
+	BOOLEAN bReschedule = FALSE;
+	struct rt_rtmp_dmacb *pRxCell;
+
+	RTMP_SEM_LOCK(&pAd->RxRingLock);
+
+	if (*pRxPending == 0) {
+		/* Get how may packets had been received */
+		RTMP_IO_READ32(pAd, RX_DRX_IDX, &pAd->RxRing.RxDmaIdx);
+
+		if (pAd->RxRing.RxSwReadIdx == pAd->RxRing.RxDmaIdx) {
+			/* no more rx packets */
+			bReschedule = FALSE;
+			goto done;
+		}
+		/* get rx pending count */
+		if (pAd->RxRing.RxDmaIdx > pAd->RxRing.RxSwReadIdx)
+			*pRxPending =
+			    pAd->RxRing.RxDmaIdx - pAd->RxRing.RxSwReadIdx;
+		else
+			*pRxPending =
+			    pAd->RxRing.RxDmaIdx + RX_RING_SIZE -
+			    pAd->RxRing.RxSwReadIdx;
+
+	}
+
+	pRxCell = &pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx];
+
+	/* Point to Rx indexed rx ring descriptor */
+	pRxD = (struct rt_rxd *) pRxCell->AllocVa;
+
+	if (pRxD->DDONE == 0) {
+		*pRxPending = 0;
+		/* DMAIndx had done but DDONE bit not ready */
+		bReschedule = TRUE;
+		goto done;
+	}
+
+	/* return rx descriptor */
+	NdisMoveMemory(pSaveRxD, pRxD, RXD_SIZE);
+
+	pNewPacket =
+	    RTMP_AllocateRxPacketBuffer(pAd, RX_BUFFER_AGGRESIZE, FALSE,
+					&AllocVa, &AllocPa);
+
+	if (pNewPacket) {
+		/* unmap the rx buffer */
+		PCI_UNMAP_SINGLE(pAd, pRxCell->DmaBuf.AllocPa,
+				 pRxCell->DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
+		pRxPacket = pRxCell->pNdisPacket;
+
+		pRxCell->DmaBuf.AllocSize = RX_BUFFER_AGGRESIZE;
+		pRxCell->pNdisPacket = (void *)pNewPacket;
+		pRxCell->DmaBuf.AllocVa = AllocVa;
+		pRxCell->DmaBuf.AllocPa = AllocPa;
+		/* update SDP0 to new buffer of rx packet */
+		pRxD->SDP0 = AllocPa;
+	} else {
+		/*DBGPRINT(RT_DEBUG_TRACE,("No Rx Buffer\n")); */
+		pRxPacket = NULL;
+		bReschedule = TRUE;
+	}
+
+	pRxD->DDONE = 0;
+
+	/* had handled one rx packet */
+	*pRxPending = *pRxPending - 1;
+
+	/* update rx descriptor and kick rx */
+	INC_RING_INDEX(pAd->RxRing.RxSwReadIdx, RX_RING_SIZE);
+
+	pAd->RxRing.RxCpuIdx =
+	    (pAd->RxRing.RxSwReadIdx ==
+	     0) ? (RX_RING_SIZE - 1) : (pAd->RxRing.RxSwReadIdx - 1);
+	RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
+
+done:
+	RTMP_SEM_UNLOCK(&pAd->RxRingLock);
+	*pbReschedule = bReschedule;
+	return pRxPacket;
+}
+
+int MlmeHardTransmitTxRing(struct rt_rtmp_adapter *pAd,
+				   u8 QueIdx, void *pPacket)
+{
+	struct rt_packet_info PacketInfo;
+	u8 *pSrcBufVA;
+	u32 SrcBufLen;
+	struct rt_txd * pTxD;
+	struct rt_header_802_11 * pHeader_802_11;
+	BOOLEAN bAckRequired, bInsertTimestamp;
+	unsigned long SrcBufPA;
+	/*u8                 TxBufIdx; */
+	u8 MlmeRate;
+	unsigned long SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
+	struct rt_txwi * pFirstTxWI;
+	/*unsigned long i; */
+	/*HTTRANSMIT_SETTING    MlmeTransmit;   //Rate for this MGMT frame. */
+	unsigned long FreeNum;
+	struct rt_mac_table_entry *pMacEntry = NULL;
+
+	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
+
+	if (pSrcBufVA == NULL) {
+		/* The buffer shouldn't be NULL */
+		return NDIS_STATUS_FAILURE;
+	}
+	/* Make sure MGMT ring resource won't be used by other threads */
+	/*NdisAcquireSpinLock(&pAd->TxRingLock); */
+
+	FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
+
+	if (FreeNum == 0) {
+		/*NdisReleaseSpinLock(&pAd->TxRingLock); */
+		return NDIS_STATUS_FAILURE;
+	}
+
+	SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
+
+	pTxD = (struct rt_txd *) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa;
+
+	if (pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket) {
+		DBGPRINT(RT_DEBUG_OFF, ("MlmeHardTransmit Error\n"));
+		/*NdisReleaseSpinLock(&pAd->TxRingLock); */
+		return NDIS_STATUS_FAILURE;
+	}
+
+	{
+		/* outgoing frame always wakeup PHY to prevent frame lost */
+		/* if (pAd->StaCfg.Psm == PWR_SAVE) */
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+			AsicForceWakeup(pAd, TRUE);
+	}
+	pFirstTxWI = (struct rt_txwi *) pSrcBufVA;
+
+	pHeader_802_11 = (struct rt_header_802_11 *) (pSrcBufVA + TXWI_SIZE);
+	if (pHeader_802_11->Addr1[0] & 0x01) {
+		MlmeRate = pAd->CommonCfg.BasicMlmeRate;
+	} else {
+		MlmeRate = pAd->CommonCfg.MlmeRate;
+	}
+
+	if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
+	    (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL)) {
+		pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
+	}
+	/* Verify Mlme rate for a / g bands. */
+	if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6))	/* 11A band */
+		MlmeRate = RATE_6;
+
+	/* */
+	/* Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE) */
+	/* Snice it's been set to 0 while on MgtMacHeaderInit */
+	/* By the way this will cause frame to be send on PWR_SAVE failed. */
+	/* */
+	/* */
+	/* In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame */
+	/* Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD */
+	if (pHeader_802_11->FC.Type != BTYPE_DATA) {
+		if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ)
+		    || !(pAd->CommonCfg.bAPSDCapable
+			 && pAd->CommonCfg.APEdcaParm.bAPSDCapable)) {
+			pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
+		} else {
+			pHeader_802_11->FC.PwrMgmt =
+			    pAd->CommonCfg.bAPSDForcePowerSave;
+		}
+	}
+
+	bInsertTimestamp = FALSE;
+	if (pHeader_802_11->FC.Type == BTYPE_CNTL)	/* must be PS-POLL */
+	{
+		bAckRequired = FALSE;
+	} else			/* BTYPE_MGMT or BTYPE_DATA(must be NULL frame) */
+	{
+		if (pHeader_802_11->Addr1[0] & 0x01)	/* MULTICAST, BROADCAST */
+		{
+			bAckRequired = FALSE;
+			pHeader_802_11->Duration = 0;
+		} else {
+			bAckRequired = TRUE;
+			pHeader_802_11->Duration =
+			    RTMPCalcDuration(pAd, MlmeRate, 14);
+			if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP) {
+				bInsertTimestamp = TRUE;
+			}
+		}
+	}
+	pHeader_802_11->Sequence = pAd->Sequence++;
+	if (pAd->Sequence > 0xfff)
+		pAd->Sequence = 0;
+	/* Before radar detection done, mgmt frame can not be sent but probe req */
+	/* Because we need to use probe req to trigger driver to send probe req in passive scan */
+	if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
+	    && (pAd->CommonCfg.bIEEE80211H == 1)
+	    && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("MlmeHardTransmit --> radar detect not in normal mode!\n"));
+		/*NdisReleaseSpinLock(&pAd->TxRingLock); */
+		return (NDIS_STATUS_FAILURE);
+	}
+	/* */
+	/* fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET */
+	/* should always has only one ohysical buffer, and the whole frame size equals */
+	/* to the first scatter buffer size */
+	/* */
+
+	/* Initialize TX Descriptor */
+	/* For inter-frame gap, the number is for this frame and next frame */
+	/* For MLME rate, we will fix as 2Mb to match other vendor's implement */
+/*      pAd->CommonCfg.MlmeTransmit.field.MODE = 1; */
+
+/* management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not. */
+	/* Only beacon use Nseq=TRUE. So here we use Nseq=FALSE. */
+	if (pMacEntry == NULL) {
+		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp,
+			      FALSE, bAckRequired, FALSE, 0, RESERVED_WCID,
+			      (SrcBufLen - TXWI_SIZE), PID_MGMT, 0,
+			      (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
+			      IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
+	} else {
+		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
+			      bInsertTimestamp, FALSE, bAckRequired, FALSE,
+			      0, pMacEntry->Aid, (SrcBufLen - TXWI_SIZE),
+			      pMacEntry->MaxHTPhyMode.field.MCS, 0,
+			      (u8)pMacEntry->MaxHTPhyMode.field.MCS,
+			      IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
+	}
+
+	pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket;
+	pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL;
+/*      pFirstTxWI->MPDUtotalByteCount = SrcBufLen - TXWI_SIZE; */
+	SrcBufPA =
+	    PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
+
+	RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_EDCA);
+	pTxD->LastSec0 = 1;
+	pTxD->LastSec1 = 1;
+	pTxD->SDLen0 = SrcBufLen;
+	pTxD->SDLen1 = 0;
+	pTxD->SDPtr0 = SrcBufPA;
+	pTxD->DMADONE = 0;
+
+	pAd->RalinkCounters.KickTxCount++;
+	pAd->RalinkCounters.OneSecTxDoneCount++;
+
+	/* Increase TX_CTX_IDX, but write to register later. */
+	INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE);
+
+	RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx * 0x10,
+			pAd->TxRing[QueIdx].TxCpuIdx);
+
+	/* Make sure to release MGMT ring resource */
+/*      NdisReleaseSpinLock(&pAd->TxRingLock); */
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+int MlmeDataHardTransmit(struct rt_rtmp_adapter *pAd,
+				 u8 QueIdx, void *pPacket)
+{
+	if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
+	    ) {
+		return NDIS_STATUS_FAILURE;
+	}
+
+	return MlmeHardTransmitTxRing(pAd, QueIdx, pPacket);
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Calculates the duration which is required to transmit out frames
+	with given size and specified rate.
+
+	Arguments:
+		pTxD		Pointer to transmit descriptor
+		Ack		Setting for Ack requirement bit
+		Fragment	Setting for Fragment bit
+		RetryMode	Setting for retry mode
+		Ifs		Setting for IFS gap
+		Rate		Setting for transmit rate
+		Service		Setting for service
+		Length		Frame length
+		TxPreamble	Short or Long preamble when using CCK rates
+		QueIdx - 0-3, according to 802.11e/d4.4 June/2003
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	========================================================================
+*/
+void RTMPWriteTxDescriptor(struct rt_rtmp_adapter *pAd,
+			   struct rt_txd * pTxD,
+			   IN BOOLEAN bWIV, u8 QueueSEL)
+{
+	/* */
+	/* Always use Long preamble before verifiation short preamble functionality works well. */
+	/* Todo: remove the following line if short preamble functionality works */
+	/* */
+	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+
+	pTxD->WIV = (bWIV) ? 1 : 0;
+	pTxD->QSEL = (QueueSEL);
+	/*RT2860c??  fixed using EDCA queue for test...  We doubt Queue1 has problem.  2006-09-26 Jan */
+	/*pTxD->QSEL= FIFO_EDCA; */
+	pTxD->DMADONE = 0;
+}
diff --git a/drivers/staging/rt2860/common/cmm_data_usb.c b/drivers/staging/rt2860/common/cmm_data_usb.c
new file mode 100644
index 0000000..7c56c2f
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_data_usb.c
@@ -0,0 +1,951 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+*/
+
+/*
+   All functions in this file must be USB-depended, or you should out your function
+	in other files.
+
+*/
+
+#ifdef RTMP_MAC_USB
+
+#include	"../rt_config.h"
+
+/*
+	We can do copy the frame into pTxContext when match following conditions.
+		=>
+		=>
+		=>
+*/
+static inline int RtmpUSBCanDoWrite(struct rt_rtmp_adapter *pAd,
+					    u8 QueIdx,
+					    struct rt_ht_tx_context *pHTTXContext)
+{
+	int canWrite = NDIS_STATUS_RESOURCES;
+
+	if (((pHTTXContext->CurWritePosition) <
+	     pHTTXContext->NextBulkOutPosition)
+	    && (pHTTXContext->CurWritePosition + LOCAL_TXBUF_SIZE) >
+	    pHTTXContext->NextBulkOutPosition) {
+		DBGPRINT(RT_DEBUG_ERROR, ("RtmpUSBCanDoWrite c1!\n"));
+		RTUSB_SET_BULK_FLAG(pAd,
+				    (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
+	} else if ((pHTTXContext->CurWritePosition == 8)
+		   && (pHTTXContext->NextBulkOutPosition < LOCAL_TXBUF_SIZE)) {
+		DBGPRINT(RT_DEBUG_ERROR, ("RtmpUSBCanDoWrite c2!\n"));
+		RTUSB_SET_BULK_FLAG(pAd,
+				    (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
+	} else if (pHTTXContext->bCurWriting == TRUE) {
+		DBGPRINT(RT_DEBUG_ERROR, ("RtmpUSBCanDoWrite c3!\n"));
+	} else {
+		canWrite = NDIS_STATUS_SUCCESS;
+	}
+
+	return canWrite;
+}
+
+u16 RtmpUSB_WriteSubTxResource(struct rt_rtmp_adapter *pAd,
+				  struct rt_tx_blk *pTxBlk,
+				  IN BOOLEAN bIsLast, u16 * FreeNumber)
+{
+
+	/* Dummy function. Should be removed in the future. */
+	return 0;
+
+}
+
+u16 RtmpUSB_WriteFragTxResource(struct rt_rtmp_adapter *pAd,
+				   struct rt_tx_blk *pTxBlk,
+				   u8 fragNum, u16 * FreeNumber)
+{
+	struct rt_ht_tx_context *pHTTXContext;
+	u16 hwHdrLen;	/* The hwHdrLen consist of 802.11 header length plus the header padding length. */
+	u32 fillOffset;
+	struct rt_txinfo *pTxInfo;
+	struct rt_txwi *pTxWI;
+	u8 *pWirelessPacket = NULL;
+	u8 QueIdx;
+	int Status;
+	unsigned long IrqFlags;
+	u32 USBDMApktLen = 0, DMAHdrLen, padding;
+	BOOLEAN TxQLastRound = FALSE;
+
+	/* */
+	/* get Tx Ring Resource & Dma Buffer address */
+	/* */
+	QueIdx = pTxBlk->QueIdx;
+	pHTTXContext = &pAd->TxContext[QueIdx];
+
+	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+	pHTTXContext = &pAd->TxContext[QueIdx];
+	fillOffset = pHTTXContext->CurWritePosition;
+
+	if (fragNum == 0) {
+		/* Check if we have enough space for this bulk-out batch. */
+		Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
+		if (Status == NDIS_STATUS_SUCCESS) {
+			pHTTXContext->bCurWriting = TRUE;
+
+			/* Reserve space for 8 bytes padding. */
+			if ((pHTTXContext->ENextBulkOutPosition ==
+			     pHTTXContext->CurWritePosition)) {
+				pHTTXContext->ENextBulkOutPosition += 8;
+				pHTTXContext->CurWritePosition += 8;
+				fillOffset += 8;
+			}
+			pTxBlk->Priv = 0;
+			pHTTXContext->CurWriteRealPos =
+			    pHTTXContext->CurWritePosition;
+		} else {
+			RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx],
+					IrqFlags);
+
+			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket,
+					    NDIS_STATUS_FAILURE);
+			return (Status);
+		}
+	} else {
+		/* For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer. */
+		Status =
+		    ((pHTTXContext->bCurWriting ==
+		      TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
+		if (Status == NDIS_STATUS_SUCCESS) {
+			fillOffset += pTxBlk->Priv;
+		} else {
+			RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx],
+					IrqFlags);
+
+			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket,
+					    NDIS_STATUS_FAILURE);
+			return (Status);
+		}
+	}
+
+	NdisZeroMemory((u8 *)(&pTxBlk->HeaderBuf[0]), TXINFO_SIZE);
+	pTxInfo = (struct rt_txinfo *)(&pTxBlk->HeaderBuf[0]);
+	pTxWI = (struct rt_txwi *) (&pTxBlk->HeaderBuf[TXINFO_SIZE]);
+
+	pWirelessPacket =
+	    &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
+
+	/* copy TXWI + WLAN Header + LLC into DMA Header Buffer */
+	/*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
+	hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+
+	/* Build our URB for USBD */
+	DMAHdrLen = TXWI_SIZE + hwHdrLen;
+	USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
+	padding = (4 - (USBDMApktLen % 4)) & 0x03;	/* round up to 4 byte alignment */
+	USBDMApktLen += padding;
+
+	pTxBlk->Priv += (TXINFO_SIZE + USBDMApktLen);
+
+	/* For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload */
+	RTMPWriteTxInfo(pAd, pTxInfo, (u16)(USBDMApktLen), FALSE, FIFO_EDCA,
+			FALSE /*NextValid */ , FALSE);
+
+	if (fragNum == pTxBlk->TotalFragNum) {
+		pTxInfo->USBDMATxburst = 0;
+		if ((pHTTXContext->CurWritePosition + pTxBlk->Priv + 3906) >
+		    MAX_TXBULK_LIMIT) {
+			pTxInfo->SwUseLastRound = 1;
+			TxQLastRound = TRUE;
+		}
+	} else {
+		pTxInfo->USBDMATxburst = 1;
+	}
+
+	NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf,
+		       TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+	pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+	pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+
+	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+	NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
+
+	/*      Zero the last padding. */
+	pWirelessPacket += pTxBlk->SrcBufLen;
+	NdisZeroMemory(pWirelessPacket, padding + 8);
+
+	if (fragNum == pTxBlk->TotalFragNum) {
+		RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+		/* Update the pHTTXContext->CurWritePosition. 3906 used to prevent the NextBulkOut is a A-RALINK/A-MSDU Frame. */
+		pHTTXContext->CurWritePosition += pTxBlk->Priv;
+		if (TxQLastRound == TRUE)
+			pHTTXContext->CurWritePosition = 8;
+		pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+		/* Finally, set bCurWriting as FALSE */
+		pHTTXContext->bCurWriting = FALSE;
+
+		RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+		/* succeed and release the skb buffer */
+		RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
+	}
+
+	return (Status);
+
+}
+
+u16 RtmpUSB_WriteSingleTxResource(struct rt_rtmp_adapter *pAd,
+				     struct rt_tx_blk *pTxBlk,
+				     IN BOOLEAN bIsLast,
+				     u16 * FreeNumber)
+{
+	struct rt_ht_tx_context *pHTTXContext;
+	u16 hwHdrLen;
+	u32 fillOffset;
+	struct rt_txinfo *pTxInfo;
+	struct rt_txwi *pTxWI;
+	u8 *pWirelessPacket;
+	u8 QueIdx;
+	unsigned long IrqFlags;
+	int Status;
+	u32 USBDMApktLen = 0, DMAHdrLen, padding;
+	BOOLEAN bTxQLastRound = FALSE;
+
+	/* For USB, didn't need PCI_MAP_SINGLE() */
+	/*SrcBufPA = PCI_MAP_SINGLE(pAd, (char *) pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, PCI_DMA_TODEVICE); */
+
+	/* */
+	/* get Tx Ring Resource & Dma Buffer address */
+	/* */
+	QueIdx = pTxBlk->QueIdx;
+
+	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+	pHTTXContext = &pAd->TxContext[QueIdx];
+	fillOffset = pHTTXContext->CurWritePosition;
+
+	/* Check ring full. */
+	Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
+	if (Status == NDIS_STATUS_SUCCESS) {
+		pHTTXContext->bCurWriting = TRUE;
+
+		pTxInfo = (struct rt_txinfo *)(&pTxBlk->HeaderBuf[0]);
+		pTxWI = (struct rt_txwi *) (&pTxBlk->HeaderBuf[TXINFO_SIZE]);
+
+		/* Reserve space for 8 bytes padding. */
+		if ((pHTTXContext->ENextBulkOutPosition ==
+		     pHTTXContext->CurWritePosition)) {
+			pHTTXContext->ENextBulkOutPosition += 8;
+			pHTTXContext->CurWritePosition += 8;
+			fillOffset += 8;
+		}
+		pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+		pWirelessPacket =
+		    &pHTTXContext->TransferBuffer->field.
+		    WirelessPacket[fillOffset];
+
+		/* copy TXWI + WLAN Header + LLC into DMA Header Buffer */
+		/*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
+		hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+
+		/* Build our URB for USBD */
+		DMAHdrLen = TXWI_SIZE + hwHdrLen;
+		USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
+		padding = (4 - (USBDMApktLen % 4)) & 0x03;	/* round up to 4 byte alignment */
+		USBDMApktLen += padding;
+
+		pTxBlk->Priv = (TXINFO_SIZE + USBDMApktLen);
+
+		/* For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload */
+		RTMPWriteTxInfo(pAd, pTxInfo, (u16)(USBDMApktLen), FALSE,
+				FIFO_EDCA, FALSE /*NextValid */ , FALSE);
+
+		if ((pHTTXContext->CurWritePosition + 3906 + pTxBlk->Priv) >
+		    MAX_TXBULK_LIMIT) {
+			pTxInfo->SwUseLastRound = 1;
+			bTxQLastRound = TRUE;
+		}
+		NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf,
+			       TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+		pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+
+		/* We unlock it here to prevent the first 8 bytes maybe over-writed issue. */
+		/*      1. First we got CurWritePosition but the first 8 bytes still not write to the pTxcontext. */
+		/*      2. An interrupt break our routine and handle bulk-out complete. */
+		/*      3. In the bulk-out compllete, it need to do another bulk-out, */
+		/*                      if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition, */
+		/*                      but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE. */
+		/*      4. Interrupt complete. */
+		/*  5. Our interrupted routine go back and fill the first 8 bytes to pTxContext. */
+		/*      6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition. */
+		/*              and the packet will wrong. */
+		pHTTXContext->CurWriteRealPos +=
+		    (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+		RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+		NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData,
+			       pTxBlk->SrcBufLen);
+		pWirelessPacket += pTxBlk->SrcBufLen;
+		NdisZeroMemory(pWirelessPacket, padding + 8);
+
+		RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+		pHTTXContext->CurWritePosition += pTxBlk->Priv;
+		if (bTxQLastRound)
+			pHTTXContext->CurWritePosition = 8;
+		pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+		pHTTXContext->bCurWriting = FALSE;
+	}
+
+	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+	/* succeed and release the skb buffer */
+	RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
+
+	return (Status);
+
+}
+
+u16 RtmpUSB_WriteMultiTxResource(struct rt_rtmp_adapter *pAd,
+				    struct rt_tx_blk *pTxBlk,
+				    u8 frameNum, u16 * FreeNumber)
+{
+	struct rt_ht_tx_context *pHTTXContext;
+	u16 hwHdrLen;	/* The hwHdrLen consist of 802.11 header length plus the header padding length. */
+	u32 fillOffset;
+	struct rt_txinfo *pTxInfo;
+	struct rt_txwi *pTxWI;
+	u8 *pWirelessPacket = NULL;
+	u8 QueIdx;
+	int Status;
+	unsigned long IrqFlags;
+	/*u32                        USBDMApktLen = 0, DMAHdrLen, padding; */
+
+	/* */
+	/* get Tx Ring Resource & Dma Buffer address */
+	/* */
+	QueIdx = pTxBlk->QueIdx;
+	pHTTXContext = &pAd->TxContext[QueIdx];
+
+	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+	if (frameNum == 0) {
+		/* Check if we have enough space for this bulk-out batch. */
+		Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
+		if (Status == NDIS_STATUS_SUCCESS) {
+			pHTTXContext->bCurWriting = TRUE;
+
+			pTxInfo = (struct rt_txinfo *)(&pTxBlk->HeaderBuf[0]);
+			pTxWI = (struct rt_txwi *) (&pTxBlk->HeaderBuf[TXINFO_SIZE]);
+
+			/* Reserve space for 8 bytes padding. */
+			if ((pHTTXContext->ENextBulkOutPosition ==
+			     pHTTXContext->CurWritePosition)) {
+
+				pHTTXContext->CurWritePosition += 8;
+				pHTTXContext->ENextBulkOutPosition += 8;
+			}
+			fillOffset = pHTTXContext->CurWritePosition;
+			pHTTXContext->CurWriteRealPos =
+			    pHTTXContext->CurWritePosition;
+
+			pWirelessPacket =
+			    &pHTTXContext->TransferBuffer->field.
+			    WirelessPacket[fillOffset];
+
+			/* */
+			/* Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
+			/* */
+			if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
+				/*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; */
+				hwHdrLen =
+				    pTxBlk->MpduHeaderLen -
+				    LENGTH_AMSDU_SUBFRAMEHEAD +
+				    pTxBlk->HdrPadLen +
+				    LENGTH_AMSDU_SUBFRAMEHEAD;
+			else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
+				/*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD; */
+				hwHdrLen =
+				    pTxBlk->MpduHeaderLen -
+				    LENGTH_ARALINK_HEADER_FIELD +
+				    pTxBlk->HdrPadLen +
+				    LENGTH_ARALINK_HEADER_FIELD;
+			else
+				/*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
+				hwHdrLen =
+				    pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+
+			/* Update the pTxBlk->Priv. */
+			pTxBlk->Priv = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
+
+			/*      pTxInfo->USBDMApktLen now just a temp value and will to correct latter. */
+			RTMPWriteTxInfo(pAd, pTxInfo, (u16)(pTxBlk->Priv),
+					FALSE, FIFO_EDCA, FALSE /*NextValid */ ,
+					FALSE);
+
+			/* Copy it. */
+			NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf,
+				       pTxBlk->Priv);
+			pHTTXContext->CurWriteRealPos += pTxBlk->Priv;
+			pWirelessPacket += pTxBlk->Priv;
+		}
+	} else {		/* For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer. */
+
+		Status =
+		    ((pHTTXContext->bCurWriting ==
+		      TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
+		if (Status == NDIS_STATUS_SUCCESS) {
+			fillOffset =
+			    (pHTTXContext->CurWritePosition + pTxBlk->Priv);
+			pWirelessPacket =
+			    &pHTTXContext->TransferBuffer->field.
+			    WirelessPacket[fillOffset];
+
+			/*hwHdrLen = pTxBlk->MpduHeaderLen; */
+			NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf,
+				       pTxBlk->MpduHeaderLen);
+			pWirelessPacket += (pTxBlk->MpduHeaderLen);
+			pTxBlk->Priv += pTxBlk->MpduHeaderLen;
+		} else {	/* It should not happened now unless we are going to shutdown. */
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("WriteMultiTxResource():bCurWriting is FALSE when handle sub-sequent frames.\n"));
+			Status = NDIS_STATUS_FAILURE;
+		}
+	}
+
+	/* We unlock it here to prevent the first 8 bytes maybe over-write issue. */
+	/*      1. First we got CurWritePosition but the first 8 bytes still not write to the pTxContext. */
+	/*      2. An interrupt break our routine and handle bulk-out complete. */
+	/*      3. In the bulk-out compllete, it need to do another bulk-out, */
+	/*                      if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition, */
+	/*                      but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE. */
+	/*      4. Interrupt complete. */
+	/*  5. Our interrupted routine go back and fill the first 8 bytes to pTxContext. */
+	/*      6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition. */
+	/*              and the packet will wrong. */
+	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+	if (Status != NDIS_STATUS_SUCCESS) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("WriteMultiTxResource: CWPos = %ld, NBOutPos = %ld.\n",
+			  pHTTXContext->CurWritePosition,
+			  pHTTXContext->NextBulkOutPosition));
+		goto done;
+	}
+	/* Copy the frame content into DMA buffer and update the pTxBlk->Priv */
+	NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
+	pWirelessPacket += pTxBlk->SrcBufLen;
+	pTxBlk->Priv += pTxBlk->SrcBufLen;
+
+done:
+	/* Release the skb buffer here */
+	RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
+
+	return (Status);
+
+}
+
+void RtmpUSB_FinalWriteTxResource(struct rt_rtmp_adapter *pAd,
+				  struct rt_tx_blk *pTxBlk,
+				  u16 totalMPDUSize, u16 TxIdx)
+{
+	u8 QueIdx;
+	struct rt_ht_tx_context *pHTTXContext;
+	u32 fillOffset;
+	struct rt_txinfo *pTxInfo;
+	struct rt_txwi *pTxWI;
+	u32 USBDMApktLen, padding;
+	unsigned long IrqFlags;
+	u8 *pWirelessPacket;
+
+	QueIdx = pTxBlk->QueIdx;
+	pHTTXContext = &pAd->TxContext[QueIdx];
+
+	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+	if (pHTTXContext->bCurWriting == TRUE) {
+		fillOffset = pHTTXContext->CurWritePosition;
+		if (((pHTTXContext->ENextBulkOutPosition ==
+		      pHTTXContext->CurWritePosition)
+		     || ((pHTTXContext->ENextBulkOutPosition - 8) ==
+			 pHTTXContext->CurWritePosition))
+		    && (pHTTXContext->bCopySavePad == TRUE))
+			pWirelessPacket = (u8 *)(&pHTTXContext->SavedPad[0]);
+		else
+			pWirelessPacket =
+			    (u8 *)(&pHTTXContext->TransferBuffer->field.
+				      WirelessPacket[fillOffset]);
+
+		/* */
+		/* Update TxInfo->USBDMApktLen , */
+		/*              the length = TXWI_SIZE + 802.11_hdr + 802.11_hdr_pad + payload_of_all_batch_frames + Bulk-Out-padding */
+		/* */
+		pTxInfo = (struct rt_txinfo *)(pWirelessPacket);
+
+		/* Calculate the bulk-out padding */
+		USBDMApktLen = pTxBlk->Priv - TXINFO_SIZE;
+		padding = (4 - (USBDMApktLen % 4)) & 0x03;	/* round up to 4 byte alignment */
+		USBDMApktLen += padding;
+
+		pTxInfo->USBDMATxPktLen = USBDMApktLen;
+
+		/* */
+		/* Update TXWI->MPDUtotalByteCount , */
+		/*              the length = 802.11 header + payload_of_all_batch_frames */
+		pTxWI = (struct rt_txwi *) (pWirelessPacket + TXINFO_SIZE);
+		pTxWI->MPDUtotalByteCount = totalMPDUSize;
+
+		/* */
+		/* Update the pHTTXContext->CurWritePosition */
+		/* */
+		pHTTXContext->CurWritePosition += (TXINFO_SIZE + USBDMApktLen);
+		if ((pHTTXContext->CurWritePosition + 3906) > MAX_TXBULK_LIMIT) {	/* Add 3906 for prevent the NextBulkOut packet size is a A-RALINK/A-MSDU Frame. */
+			pHTTXContext->CurWritePosition = 8;
+			pTxInfo->SwUseLastRound = 1;
+		}
+		pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+		/* */
+		/*      Zero the last padding. */
+		/* */
+		pWirelessPacket =
+		    (&pHTTXContext->TransferBuffer->field.
+		     WirelessPacket[fillOffset + pTxBlk->Priv]);
+		NdisZeroMemory(pWirelessPacket, padding + 8);
+
+		/* Finally, set bCurWriting as FALSE */
+		pHTTXContext->bCurWriting = FALSE;
+
+	} else {		/* It should not happened now unless we are going to shutdown. */
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("FinalWriteTxResource():bCurWriting is FALSE when handle last frames.\n"));
+	}
+
+	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+}
+
+void RtmpUSBDataLastTxIdx(struct rt_rtmp_adapter *pAd,
+			  u8 QueIdx, u16 TxIdx)
+{
+	/* DO nothing for USB. */
+}
+
+/*
+	When can do bulk-out:
+		1. TxSwFreeIdx < TX_RING_SIZE;
+			It means has at least one Ring entity is ready for bulk-out, kick it out.
+		2. If TxSwFreeIdx == TX_RING_SIZE
+			Check if the CurWriting flag is FALSE, if it's FALSE, we can do kick out.
+
+*/
+void RtmpUSBDataKickOut(struct rt_rtmp_adapter *pAd,
+			struct rt_tx_blk *pTxBlk, u8 QueIdx)
+{
+	RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
+	RTUSBKickBulkOut(pAd);
+
+}
+
+/*
+	Must be run in Interrupt context
+	This function handle RT2870 specific TxDesc and cpu index update and kick the packet out.
+ */
+int RtmpUSBMgmtKickOut(struct rt_rtmp_adapter *pAd,
+		       u8 QueIdx,
+		       void *pPacket,
+		       u8 *pSrcBufVA, u32 SrcBufLen)
+{
+	struct rt_txinfo *pTxInfo;
+	unsigned long BulkOutSize;
+	u8 padLen;
+	u8 *pDest;
+	unsigned long SwIdx = pAd->MgmtRing.TxCpuIdx;
+	struct rt_tx_context *pMLMEContext =
+	    (struct rt_tx_context *)pAd->MgmtRing.Cell[SwIdx].AllocVa;
+	unsigned long IrqFlags;
+
+	pTxInfo = (struct rt_txinfo *)(pSrcBufVA);
+
+	/* Build our URB for USBD */
+	BulkOutSize = SrcBufLen;
+	BulkOutSize = (BulkOutSize + 3) & (~3);
+	RTMPWriteTxInfo(pAd, pTxInfo, (u16)(BulkOutSize - TXINFO_SIZE),
+			TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
+
+	BulkOutSize += 4;	/* Always add 4 extra bytes at every packet. */
+
+	/* If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again. */
+	if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0)
+		BulkOutSize += 4;
+
+	padLen = BulkOutSize - SrcBufLen;
+	ASSERT((padLen <= RTMP_PKT_TAIL_PADDING));
+
+	/* Now memzero all extra padding bytes. */
+	pDest = (u8 *)(pSrcBufVA + SrcBufLen);
+	skb_put(GET_OS_PKT_TYPE(pPacket), padLen);
+	NdisZeroMemory(pDest, padLen);
+
+	RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
+
+	pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket;
+	pMLMEContext->TransferBuffer =
+	    (struct rt_tx_buffer *)(GET_OS_PKT_DATAPTR(pPacket));
+
+	/* Length in TxInfo should be 8 less than bulkout size. */
+	pMLMEContext->BulkOutSize = BulkOutSize;
+	pMLMEContext->InUse = TRUE;
+	pMLMEContext->bWaitingBulkOut = TRUE;
+
+	/*for debug */
+	/*hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize)); */
+
+	/*pAd->RalinkCounters.KickTxCount++; */
+	/*pAd->RalinkCounters.OneSecTxDoneCount++; */
+
+	/*if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE) */
+	/*      needKickOut = TRUE; */
+
+	/* Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX */
+	pAd->MgmtRing.TxSwFreeIdx--;
+	INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
+
+	RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
+
+	RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
+	/*if (needKickOut) */
+	RTUSBKickBulkOut(pAd);
+
+	return 0;
+}
+
+void RtmpUSBNullFrameKickOut(struct rt_rtmp_adapter *pAd,
+			     u8 QueIdx,
+			     u8 * pNullFrame, u32 frameLen)
+{
+	if (pAd->NullContext.InUse == FALSE) {
+		struct rt_tx_context *pNullContext;
+		struct rt_txinfo *pTxInfo;
+		struct rt_txwi * pTxWI;
+		u8 *pWirelessPkt;
+
+		pNullContext = &(pAd->NullContext);
+
+		/* Set the in use bit */
+		pNullContext->InUse = TRUE;
+		pWirelessPkt =
+		    (u8 *)& pNullContext->TransferBuffer->field.
+		    WirelessPacket[0];
+
+		RTMPZeroMemory(&pWirelessPkt[0], 100);
+		pTxInfo = (struct rt_txinfo *)& pWirelessPkt[0];
+		RTMPWriteTxInfo(pAd, pTxInfo,
+				(u16)(sizeof(struct rt_header_802_11) + TXWI_SIZE),
+				TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
+		pTxInfo->QSEL = FIFO_EDCA;
+		pTxWI = (struct rt_txwi *) & pWirelessPkt[TXINFO_SIZE];
+		RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE,
+			      FALSE, 0, BSSID_WCID, (sizeof(struct rt_header_802_11)), 0,
+			      0, (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
+			      IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
+
+		RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE + TXINFO_SIZE],
+			       &pAd->NullFrame, sizeof(struct rt_header_802_11));
+		pAd->NullContext.BulkOutSize =
+		    TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
+
+		/* Fill out frame length information for global Bulk out arbitor */
+		/*pNullContext->BulkOutSize = TransferBufferLength; */
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("SYNC - send NULL Frame @%d Mbps...\n",
+			  RateIdToMbps[pAd->CommonCfg.TxRate]));
+		RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
+
+		/* Kick bulk out */
+		RTUSBKickBulkOut(pAd);
+	}
+
+}
+
+/*
+========================================================================
+Routine Description:
+    Get a received packet.
+
+Arguments:
+	pAd					device control block
+	pSaveRxD			receive descriptor information
+	*pbReschedule		need reschedule flag
+	*pRxPending			pending received packet flag
+
+Return Value:
+    the recieved packet
+
+Note:
+========================================================================
+*/
+void *GetPacketFromRxRing(struct rt_rtmp_adapter *pAd,
+				 OUT PRT28XX_RXD_STRUC pSaveRxD,
+				 OUT BOOLEAN * pbReschedule,
+				 IN u32 * pRxPending)
+{
+	struct rt_rx_context *pRxContext;
+	void *pSkb;
+	u8 *pData;
+	unsigned long ThisFrameLen;
+	unsigned long RxBufferLength;
+	struct rt_rxwi * pRxWI;
+
+	pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex];
+	if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE))
+		return NULL;
+
+	RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition;
+	if (RxBufferLength <
+	    (RT2870_RXDMALEN_FIELD_SIZE + sizeof(struct rt_rxwi) +
+	     sizeof(struct rt_rxinfo))) {
+		goto label_null;
+	}
+
+	pData = &pRxContext->TransferBuffer[pAd->ReadPosition];	/* 4KB */
+	/* The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding) */
+	ThisFrameLen = *pData + (*(pData + 1) << 8);
+	if (ThisFrameLen == 0) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n",
+			  pAd->NextRxBulkInReadIndex, ThisFrameLen,
+			  pRxContext->BulkInOffset));
+		goto label_null;
+	}
+	if ((ThisFrameLen & 0x3) != 0) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n",
+			  pAd->NextRxBulkInReadIndex, ThisFrameLen,
+			  pRxContext->BulkInOffset));
+		goto label_null;
+	}
+
+	if ((ThisFrameLen + 8) > RxBufferLength)	/* 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(struct rt_rxinfo)) */
+	{
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n",
+			  pAd->NextRxBulkInReadIndex, ThisFrameLen,
+			  pRxContext->BulkInOffset, RxBufferLength,
+			  pAd->ReadPosition));
+
+		/* error frame. finish this loop */
+		goto label_null;
+	}
+	/* skip USB frame length field */
+	pData += RT2870_RXDMALEN_FIELD_SIZE;
+	pRxWI = (struct rt_rxwi *) pData;
+	if (pRxWI->MPDUtotalByteCount > ThisFrameLen) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n",
+			  __FUNCTION__, pRxWI->MPDUtotalByteCount,
+			  ThisFrameLen));
+		goto label_null;
+	}
+	/* allocate a rx packet */
+	pSkb = dev_alloc_skb(ThisFrameLen);
+	if (pSkb == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n",
+			  __FUNCTION__));
+		goto label_null;
+	}
+	/* copy the rx packet */
+	memcpy(skb_put(pSkb, ThisFrameLen), pData, ThisFrameLen);
+	RTPKT_TO_OSPKT(pSkb)->dev = get_netdev_from_bssid(pAd, BSS0);
+	RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pSkb), PKTSRC_NDIS);
+
+	/* copy RxD */
+	*pSaveRxD = *(struct rt_rxinfo *) (pData + ThisFrameLen);
+
+	/* update next packet read position. */
+	pAd->ReadPosition += (ThisFrameLen + RT2870_RXDMALEN_FIELD_SIZE + RXINFO_SIZE);	/* 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(struct rt_rxinfo)) */
+
+	return pSkb;
+
+label_null:
+
+	return NULL;
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
+
+	Arguments:
+		pRxD		Pointer	to the Rx descriptor
+
+	Return Value:
+		NDIS_STATUS_SUCCESS		No err
+		NDIS_STATUS_FAILURE		Error
+
+	Note:
+
+	========================================================================
+*/
+int RTMPCheckRxError(struct rt_rtmp_adapter *pAd,
+			     struct rt_header_802_11 * pHeader,
+			     struct rt_rxwi * pRxWI, IN PRT28XX_RXD_STRUC pRxINFO)
+{
+	struct rt_cipher_key *pWpaKey;
+	int dBm;
+
+	if (pAd->bPromiscuous == TRUE)
+		return (NDIS_STATUS_SUCCESS);
+	if (pRxINFO == NULL)
+		return (NDIS_STATUS_FAILURE);
+
+	/* Phy errors & CRC errors */
+	if (pRxINFO->Crc) {
+		/* Check RSSI for Noise Hist statistic collection. */
+		dBm = (int)(pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
+		if (dBm <= -87)
+			pAd->StaCfg.RPIDensity[0] += 1;
+		else if (dBm <= -82)
+			pAd->StaCfg.RPIDensity[1] += 1;
+		else if (dBm <= -77)
+			pAd->StaCfg.RPIDensity[2] += 1;
+		else if (dBm <= -72)
+			pAd->StaCfg.RPIDensity[3] += 1;
+		else if (dBm <= -67)
+			pAd->StaCfg.RPIDensity[4] += 1;
+		else if (dBm <= -62)
+			pAd->StaCfg.RPIDensity[5] += 1;
+		else if (dBm <= -57)
+			pAd->StaCfg.RPIDensity[6] += 1;
+		else if (dBm > -57)
+			pAd->StaCfg.RPIDensity[7] += 1;
+
+		return (NDIS_STATUS_FAILURE);
+	}
+	/* Add Rx size to channel load counter, we should ignore error counts */
+	pAd->StaCfg.CLBusyBytes += (pRxWI->MPDUtotalByteCount + 14);
+
+	/* Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics */
+	if (pHeader->FC.ToDs) {
+		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Err;FC.ToDs\n"));
+		return NDIS_STATUS_FAILURE;
+	}
+	/* Paul 04-03 for OFDM Rx length issue */
+	if (pRxWI->MPDUtotalByteCount > MAX_AGGREGATION_SIZE) {
+		DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n"));
+		return NDIS_STATUS_FAILURE;
+	}
+	/* Drop not U2M frames, cant's drop here because we will drop beacon in this case */
+	/* I am kind of doubting the U2M bit operation */
+	/* if (pRxD->U2M == 0) */
+	/*      return(NDIS_STATUS_FAILURE); */
+
+	/* drop decyption fail frame */
+	if (pRxINFO->Decrypted && pRxINFO->CipherErr) {
+
+		if (((pRxINFO->CipherErr & 1) == 1)
+		    && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
+			RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG,
+					      pAd->MacTab.Content[BSSID_WCID].
+					      Addr, BSS0, 0);
+
+		if (((pRxINFO->CipherErr & 2) == 2)
+		    && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
+			RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG,
+					      pAd->MacTab.Content[BSSID_WCID].
+					      Addr, BSS0, 0);
+		/* */
+		/* MIC Error */
+		/* */
+		if ((pRxINFO->CipherErr == 2) && pRxINFO->MyBss) {
+			pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
+			RTMPReportMicError(pAd, pWpaKey);
+			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Rx MIC Value error\n"));
+		}
+
+		if (pRxINFO->Decrypted &&
+		    (pAd->SharedKey[BSS0][pRxWI->KeyIndex].CipherAlg ==
+		     CIPHER_AES)
+		    && (pHeader->Sequence == pAd->FragFrame.Sequence)) {
+			/* */
+			/* Acceptable since the First FragFrame no CipherErr problem. */
+			/* */
+			return (NDIS_STATUS_SUCCESS);
+		}
+
+		return (NDIS_STATUS_FAILURE);
+	}
+
+	return (NDIS_STATUS_SUCCESS);
+}
+
+void RtmpUsbStaAsicForceWakeupTimeout(void *SystemSpecific1,
+				      void *FunctionContext,
+				      void *SystemSpecific2,
+				      void *SystemSpecific3)
+{
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
+
+	if (pAd && pAd->Mlme.AutoWakeupTimerRunning) {
+		AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
+
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+		pAd->Mlme.AutoWakeupTimerRunning = FALSE;
+	}
+}
+
+void RT28xxUsbStaAsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx)
+{
+	BOOLEAN Canceled;
+
+	if (pAd->Mlme.AutoWakeupTimerRunning)
+		RTMPCancelTimer(&pAd->Mlme.AutoWakeupTimer, &Canceled);
+
+	AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
+
+	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+}
+
+void RT28xxUsbStaAsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd,
+					 u16 TbttNumToNextWakeUp)
+{
+
+	/* we have decided to SLEEP, so at least do it for a BEACON period. */
+	if (TbttNumToNextWakeUp == 0)
+		TbttNumToNextWakeUp = 1;
+
+	RTMPSetTimer(&pAd->Mlme.AutoWakeupTimer, AUTO_WAKEUP_TIMEOUT);
+	pAd->Mlme.AutoWakeupTimerRunning = TRUE;
+
+	AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);	/* send POWER-SAVE command to MCU. Timeout 40us. */
+
+	OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
+
+}
+
+#endif /* RTMP_MAC_USB // */
diff --git a/drivers/staging/rt2860/common/cmm_info.c b/drivers/staging/rt2860/common/cmm_info.c
index 019cc44..25302e8 100644
--- a/drivers/staging/rt2860/common/cmm_info.c
+++ b/drivers/staging/rt2860/common/cmm_info.c
@@ -23,826 +23,11 @@
  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  *                                                                       *
  *************************************************************************
-*/
+ */
 
 #include <linux/sched.h>
 #include "../rt_config.h"
 
-INT	Show_SSID_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_WirelessMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_TxBurst_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_TxPreamble_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_TxPower_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_Channel_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_BGProtection_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_RTSThreshold_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_FragThreshold_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_HtBw_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_HtMcs_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_HtGi_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_HtOpMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_HtExtcha_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_HtMpduDensity_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_HtBaWinSize_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_HtRdg_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_HtAmsdu_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_HtAutoBa_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_CountryRegion_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_CountryRegionABand_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_CountryCode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-#ifdef AGGREGATION_SUPPORT
-INT	Show_PktAggregate_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-#endif // AGGREGATION_SUPPORT //
-
-#ifdef WMM_SUPPORT
-INT	Show_WmmCapable_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-#endif // WMM_SUPPORT //
-
-INT	Show_IEEE80211H_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_NetworkType_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_AuthMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_EncrypType_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_DefaultKeyID_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_Key1_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_Key2_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_Key3_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_Key4_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-INT	Show_WPAPSK_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
-
-static struct {
-	CHAR *name;
-	INT (*show_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg);
-} *PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC, RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC[] = {
-	{"SSID",					Show_SSID_Proc},
-	{"WirelessMode",			Show_WirelessMode_Proc},
-	{"TxBurst",					Show_TxBurst_Proc},
-	{"TxPreamble",				Show_TxPreamble_Proc},
-	{"TxPower",					Show_TxPower_Proc},
-	{"Channel",					Show_Channel_Proc},
-	{"BGProtection",			Show_BGProtection_Proc},
-	{"RTSThreshold",			Show_RTSThreshold_Proc},
-	{"FragThreshold",			Show_FragThreshold_Proc},
-	{"HtBw",					Show_HtBw_Proc},
-	{"HtMcs",					Show_HtMcs_Proc},
-	{"HtGi",					Show_HtGi_Proc},
-	{"HtOpMode",				Show_HtOpMode_Proc},
-	{"HtExtcha",				Show_HtExtcha_Proc},
-	{"HtMpduDensity",			Show_HtMpduDensity_Proc},
-	{"HtBaWinSize",		        Show_HtBaWinSize_Proc},
-	{"HtRdg",		        	Show_HtRdg_Proc},
-	{"HtAmsdu",		        	Show_HtAmsdu_Proc},
-	{"HtAutoBa",		        Show_HtAutoBa_Proc},
-	{"CountryRegion",			Show_CountryRegion_Proc},
-	{"CountryRegionABand",		Show_CountryRegionABand_Proc},
-	{"CountryCode",				Show_CountryCode_Proc},
-#ifdef AGGREGATION_SUPPORT
-	{"PktAggregate",			Show_PktAggregate_Proc},
-#endif
-
-#ifdef WMM_SUPPORT
-	{"WmmCapable",				Show_WmmCapable_Proc},
-#endif
-	{"IEEE80211H",				Show_IEEE80211H_Proc},
-    {"NetworkType",				Show_NetworkType_Proc},
-	{"AuthMode",				Show_AuthMode_Proc},
-	{"EncrypType",				Show_EncrypType_Proc},
-	{"DefaultKeyID",			Show_DefaultKeyID_Proc},
-	{"Key1",					Show_Key1_Proc},
-	{"Key2",					Show_Key2_Proc},
-	{"Key3",					Show_Key3_Proc},
-	{"Key4",					Show_Key4_Proc},
-	{"WPAPSK",					Show_WPAPSK_Proc},
-	{NULL, NULL}
-};
-
-/*
-    ==========================================================================
-    Description:
-        Get Driver version.
-
-    Return:
-    ==========================================================================
-*/
-INT Set_DriverVersion_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	DBGPRINT(RT_DEBUG_TRACE, ("Driver version-%s\n", STA_DRIVER_VERSION));
-
-    return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set Country Region.
-        This command will not work, if the field of CountryRegion in eeprom is programmed.
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_CountryRegion_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	ULONG region;
-
-	region = simple_strtol(arg, 0, 10);
-
-	// Country can be set only when EEPROM not programmed
-	if (pAd->CommonCfg.CountryRegion & 0x80)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegion_Proc::parameter of CountryRegion in eeprom is programmed \n"));
-		return FALSE;
-	}
-
-	if((region >= 0) && (region <= REGION_MAXIMUM_BG_BAND))
-	{
-		pAd->CommonCfg.CountryRegion = (UCHAR) region;
-	}
-	else if (region == REGION_31_BG_BAND)
-	{
-		pAd->CommonCfg.CountryRegion = (UCHAR) region;
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegion_Proc::parameters out of range\n"));
-		return FALSE;
-	}
-
-	// if set country region, driver needs to be reset
-	BuildChannelList(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_CountryRegion_Proc::(CountryRegion=%d)\n", pAd->CommonCfg.CountryRegion));
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set Country Region for A band.
-        This command will not work, if the field of CountryRegion in eeprom is programmed.
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_CountryRegionABand_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	ULONG region;
-
-	region = simple_strtol(arg, 0, 10);
-
-	// Country can be set only when EEPROM not programmed
-	if (pAd->CommonCfg.CountryRegionForABand & 0x80)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegionABand_Proc::parameter of CountryRegion in eeprom is programmed \n"));
-		return FALSE;
-	}
-
-	if((region >= 0) && (region <= REGION_MAXIMUM_A_BAND))
-	{
-		pAd->CommonCfg.CountryRegionForABand = (UCHAR) region;
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegionABand_Proc::parameters out of range\n"));
-		return FALSE;
-	}
-
-	// if set country region, driver needs to be reset
-	BuildChannelList(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_CountryRegionABand_Proc::(CountryRegion=%d)\n", pAd->CommonCfg.CountryRegionForABand));
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set Wireless Mode
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_WirelessMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	ULONG	WirelessMode;
-	INT		success = TRUE;
-
-	WirelessMode = simple_strtol(arg, 0, 10);
-
-	{
-		INT MaxPhyMode = PHY_11G;
-
-		MaxPhyMode = PHY_11N_5G;
-
-		if (WirelessMode <= MaxPhyMode)
-		{
-			RTMPSetPhyMode(pAd, WirelessMode);
-
-			if (WirelessMode >= PHY_11ABGN_MIXED)
-			{
-				pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
-				pAd->CommonCfg.REGBACapability.field.AutoBA = TRUE;
-			}
-			else
-			{
-				pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
-				pAd->CommonCfg.REGBACapability.field.AutoBA = FALSE;
-			}
-
-			// Set AdhocMode rates
-			if (pAd->StaCfg.BssType == BSS_ADHOC)
-			{
-				MlmeUpdateTxRates(pAd, FALSE, 0);
-				MakeIbssBeacon(pAd);           // re-build BEACON frame
-				AsicEnableIbssSync(pAd);       // copy to on-chip memory
-			}
-		}
-		else
-		{
-			success = FALSE;
-		}
-	}
-
-	// it is needed to set SSID to take effect
-	if (success == TRUE)
-	{
-		SetCommonHT(pAd);
-		DBGPRINT(RT_DEBUG_TRACE, ("Set_WirelessMode_Proc::(=%ld)\n", WirelessMode));
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Set_WirelessMode_Proc::parameters out of range\n"));
-	}
-
-	return success;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set Channel
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_Channel_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
- 	INT		success = TRUE;
-	UCHAR	Channel;
-
-	Channel = (UCHAR) simple_strtol(arg, 0, 10);
-
-	// check if this channel is valid
-	if (ChannelSanity(pAd, Channel) == TRUE)
-	{
-		{
-			pAd->CommonCfg.Channel = Channel;
-
-			if (MONITOR_ON(pAd))
-			{
-				N_ChannelCheck(pAd);
-				if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
-					pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
-				{
-					N_SetCenCh(pAd);
-					AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
-					AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
-					DBGPRINT(RT_DEBUG_TRACE, ("BW_40, control_channel(%d), CentralChannel(%d) \n",
-								pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
-				}
-				else
-				{
-					AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-					AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-					DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAd->CommonCfg.Channel));
-				}
-			}
-		}
-		success = TRUE;
-	}
-	else
-	{
-		success = FALSE;
-	}
-
-
-	if (success == TRUE)
-		DBGPRINT(RT_DEBUG_TRACE, ("Set_Channel_Proc::(Channel=%d)\n", pAd->CommonCfg.Channel));
-
-	return success;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set Short Slot Time Enable or Disable
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_ShortSlot_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	ULONG ShortSlot;
-
-	ShortSlot = simple_strtol(arg, 0, 10);
-
-	if (ShortSlot == 1)
-		pAd->CommonCfg.bUseShortSlotTime = TRUE;
-	else if (ShortSlot == 0)
-		pAd->CommonCfg.bUseShortSlotTime = FALSE;
-	else
-		return FALSE;  //Invalid argument
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_ShortSlot_Proc::(ShortSlot=%d)\n", pAd->CommonCfg.bUseShortSlotTime));
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set Tx power
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_TxPower_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	ULONG TxPower;
-	INT   success = FALSE;
-
-	TxPower = (ULONG) simple_strtol(arg, 0, 10);
-	if (TxPower <= 100)
-	{
-		{
-			pAd->CommonCfg.TxPowerDefault = TxPower;
-			pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
-		}
-		success = TRUE;
-	}
-	else
-		success = FALSE;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_TxPower_Proc::(TxPowerPercentage=%ld)\n", pAd->CommonCfg.TxPowerPercentage));
-
-	return success;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set 11B/11G Protection
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_BGProtection_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	switch (simple_strtol(arg, 0, 10))
-	{
-		case 0: //AUTO
-			pAd->CommonCfg.UseBGProtection = 0;
-			break;
-		case 1: //Always On
-			pAd->CommonCfg.UseBGProtection = 1;
-			break;
-		case 2: //Always OFF
-			pAd->CommonCfg.UseBGProtection = 2;
-			break;
-		default:  //Invalid argument
-			return FALSE;
-	}
-
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_BGProtection_Proc::(BGProtection=%ld)\n", pAd->CommonCfg.UseBGProtection));
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set TxPreamble
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_TxPreamble_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	RT_802_11_PREAMBLE	Preamble;
-
-	Preamble = simple_strtol(arg, 0, 10);
-
-
-	switch (Preamble)
-	{
-		case Rt802_11PreambleShort:
-			pAd->CommonCfg.TxPreamble = Preamble;
-
-			MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
-			break;
-		case Rt802_11PreambleLong:
-		case Rt802_11PreambleAuto:
-			// if user wants AUTO, initialize to LONG here, then change according to AP's
-			// capability upon association.
-			pAd->CommonCfg.TxPreamble = Preamble;
-
-			MlmeSetTxPreamble(pAd, Rt802_11PreambleLong);
-			break;
-		default: //Invalid argument
-			return FALSE;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_TxPreamble_Proc::(TxPreamble=%ld)\n", pAd->CommonCfg.TxPreamble));
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set RTS Threshold
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_RTSThreshold_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	 NDIS_802_11_RTS_THRESHOLD           RtsThresh;
-
-	RtsThresh = simple_strtol(arg, 0, 10);
-
-	if((RtsThresh > 0) && (RtsThresh <= MAX_RTS_THRESHOLD))
-		pAd->CommonCfg.RtsThreshold  = (USHORT)RtsThresh;
-	else if (RtsThresh == 0)
-		pAd->CommonCfg.RtsThreshold = MAX_RTS_THRESHOLD;
-	else
-		return FALSE; //Invalid argument
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_RTSThreshold_Proc::(RTSThreshold=%d)\n", pAd->CommonCfg.RtsThreshold));
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set Fragment Threshold
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_FragThreshold_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	 NDIS_802_11_FRAGMENTATION_THRESHOLD     FragThresh;
-
-	FragThresh = simple_strtol(arg, 0, 10);
-
-	if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
-	{
-		//Illegal FragThresh so we set it to default
-		pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
-	}
-	else if (FragThresh % 2 == 1)
-	{
-		// The length of each fragment shall always be an even number of octets, except for the last fragment
-		// of an MSDU or MMPDU, which may be either an even or an odd number of octets.
-		pAd->CommonCfg.FragmentThreshold = (USHORT)(FragThresh - 1);
-	}
-	else
-	{
-		pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
-	}
-
-	{
-		if (pAd->CommonCfg.FragmentThreshold == MAX_FRAG_THRESHOLD)
-			pAd->CommonCfg.bUseZeroToDisableFragment = TRUE;
-		else
-			pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_FragThreshold_Proc::(FragThreshold=%d)\n", pAd->CommonCfg.FragmentThreshold));
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set TxBurst
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_TxBurst_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	ULONG TxBurst;
-
-	TxBurst = simple_strtol(arg, 0, 10);
-	if (TxBurst == 1)
-		pAd->CommonCfg.bEnableTxBurst = TRUE;
-	else if (TxBurst == 0)
-		pAd->CommonCfg.bEnableTxBurst = FALSE;
-	else
-		return FALSE;  //Invalid argument
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_TxBurst_Proc::(TxBurst=%d)\n", pAd->CommonCfg.bEnableTxBurst));
-
-	return TRUE;
-}
-
-#ifdef AGGREGATION_SUPPORT
-/*
-    ==========================================================================
-    Description:
-        Set TxBurst
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_PktAggregate_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	ULONG aggre;
-
-	aggre = simple_strtol(arg, 0, 10);
-
-	if (aggre == 1)
-		pAd->CommonCfg.bAggregationCapable = TRUE;
-	else if (aggre == 0)
-		pAd->CommonCfg.bAggregationCapable = FALSE;
-	else
-		return FALSE;  //Invalid argument
-
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_PktAggregate_Proc::(AGGRE=%d)\n", pAd->CommonCfg.bAggregationCapable));
-
-	return TRUE;
-}
-#endif
-
-/*
-    ==========================================================================
-    Description:
-        Set IEEE80211H.
-        This parameter is 1 when needs radar detection, otherwise 0
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_IEEE80211H_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-    ULONG ieee80211h;
-
-	ieee80211h = simple_strtol(arg, 0, 10);
-
-	if (ieee80211h == 1)
-		pAd->CommonCfg.bIEEE80211H = TRUE;
-	else if (ieee80211h == 0)
-		pAd->CommonCfg.bIEEE80211H = FALSE;
-	else
-		return FALSE;  //Invalid argument
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_IEEE80211H_Proc::(IEEE80211H=%d)\n", pAd->CommonCfg.bIEEE80211H));
-
-	return TRUE;
-}
-
-
-#ifdef DBG
-/*
-    ==========================================================================
-    Description:
-        For Debug information
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_Debug_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	DBGPRINT(RT_DEBUG_TRACE, ("==> Set_Debug_Proc *******************\n"));
-
-    if(simple_strtol(arg, 0, 10) <= RT_DEBUG_LOUD)
-        RTDebugLevel = simple_strtol(arg, 0, 10);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<== Set_Debug_Proc(RTDebugLevel = %ld)\n", RTDebugLevel));
-
-	return TRUE;
-}
-#endif
-
-INT	Show_DescInfo_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-#ifdef RT2860
-	INT i, QueIdx=0;
-	PRT28XX_RXD_STRUC pRxD;
-    PTXD_STRUC pTxD;
-	PRTMP_TX_RING	pTxRing = &pAd->TxRing[QueIdx];
-	PRTMP_MGMT_RING	pMgmtRing = &pAd->MgmtRing;
-	PRTMP_RX_RING	pRxRing = &pAd->RxRing;
-
-	for(i=0;i<TX_RING_SIZE;i++)
-	{
-	    pTxD = (PTXD_STRUC) pTxRing->Cell[i].AllocVa;
-	    printk("Desc #%d\n",i);
-	    hex_dump("Tx Descriptor", (char *)pTxD, 16);
-	    printk("pTxD->DMADONE = %x\n", pTxD->DMADONE);
-	}
-	printk("---------------------------------------------------\n");
-	for(i=0;i<MGMT_RING_SIZE;i++)
-	{
-	    pTxD = (PTXD_STRUC) pMgmtRing->Cell[i].AllocVa;
-	    printk("Desc #%d\n",i);
-	    hex_dump("Mgmt Descriptor", (char *)pTxD, 16);
-	    printk("pMgmt->DMADONE = %x\n", pTxD->DMADONE);
-	}
-	printk("---------------------------------------------------\n");
-	for(i=0;i<RX_RING_SIZE;i++)
-	{
-	    pRxD = (PRT28XX_RXD_STRUC) pRxRing->Cell[i].AllocVa;
-	    printk("Desc #%d\n",i);
-	    hex_dump("Rx Descriptor", (char *)pRxD, 16);
-		printk("pRxD->DDONE = %x\n", pRxD->DDONE);
-	}
-#endif /* RT2860 */
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Reset statistics counter
-
-    Arguments:
-        pAdapter            Pointer to our adapter
-        arg
-
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_ResetStatCounter_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	DBGPRINT(RT_DEBUG_TRACE, ("==>Set_ResetStatCounter_Proc\n"));
-
-	// add the most up-to-date h/w raw counters into software counters
-	NICUpdateRawCounters(pAd);
-
-	NdisZeroMemory(&pAd->WlanCounters, sizeof(COUNTER_802_11));
-	NdisZeroMemory(&pAd->Counters8023, sizeof(COUNTER_802_3));
-	NdisZeroMemory(&pAd->RalinkCounters, sizeof(COUNTER_RALINK));
-
-	return TRUE;
-}
-
-BOOLEAN RTMPCheckStrPrintAble(
-    IN  CHAR *pInPutStr,
-    IN  UCHAR strLen)
-{
-    UCHAR i=0;
-
-    for (i=0; i<strLen; i++)
-    {
-        if ((pInPutStr[i] < 0x21) ||
-            (pInPutStr[i] > 0x7E))
-            return FALSE;
-    }
-
-    return TRUE;
-}
-
 /*
 	========================================================================
 
@@ -862,217 +47,174 @@
 
 	========================================================================
 */
-VOID    RTMPSetDesiredRates(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  LONG            Rates)
+void RTMPSetDesiredRates(struct rt_rtmp_adapter *pAdapter, long Rates)
 {
-    NDIS_802_11_RATES aryRates;
+	NDIS_802_11_RATES aryRates;
 
-    memset(&aryRates, 0x00, sizeof(NDIS_802_11_RATES));
-    switch (pAdapter->CommonCfg.PhyMode)
-    {
-        case PHY_11A: // A only
-            switch (Rates)
-            {
-                case 6000000: //6M
-                    aryRates[0] = 0x0c; // 6M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
-                    break;
-                case 9000000: //9M
-                    aryRates[0] = 0x12; // 9M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
-                    break;
-                case 12000000: //12M
-                    aryRates[0] = 0x18; // 12M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
-                    break;
-                case 18000000: //18M
-                    aryRates[0] = 0x24; // 18M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
-                    break;
-                case 24000000: //24M
-                    aryRates[0] = 0x30; // 24M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_4;
-                    break;
-                case 36000000: //36M
-                    aryRates[0] = 0x48; // 36M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_5;
-                    break;
-                case 48000000: //48M
-                    aryRates[0] = 0x60; // 48M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_6;
-                    break;
-                case 54000000: //54M
-                    aryRates[0] = 0x6c; // 54M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_7;
-                    break;
-                case -1: //Auto
-                default:
-                    aryRates[0] = 0x6c; // 54Mbps
-                    aryRates[1] = 0x60; // 48Mbps
-                    aryRates[2] = 0x48; // 36Mbps
-                    aryRates[3] = 0x30; // 24Mbps
-                    aryRates[4] = 0x24; // 18M
-                    aryRates[5] = 0x18; // 12M
-                    aryRates[6] = 0x12; // 9M
-                    aryRates[7] = 0x0c; // 6M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
-                    break;
-            }
-            break;
-        case PHY_11BG_MIXED: // B/G Mixed
-        case PHY_11B: // B only
-        case PHY_11ABG_MIXED: // A/B/G Mixed
-        default:
-            switch (Rates)
-            {
-                case 1000000: //1M
-                    aryRates[0] = 0x02;
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
-                    break;
-                case 2000000: //2M
-                    aryRates[0] = 0x04;
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
-                    break;
-                case 5000000: //5.5M
-                    aryRates[0] = 0x0b; // 5.5M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
-                    break;
-                case 11000000: //11M
-                    aryRates[0] = 0x16; // 11M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
-                    break;
-                case 6000000: //6M
-                    aryRates[0] = 0x0c; // 6M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
-                    break;
-                case 9000000: //9M
-                    aryRates[0] = 0x12; // 9M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
-                    break;
-                case 12000000: //12M
-                    aryRates[0] = 0x18; // 12M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
-                    break;
-                case 18000000: //18M
-                    aryRates[0] = 0x24; // 18M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
-                    break;
-                case 24000000: //24M
-                    aryRates[0] = 0x30; // 24M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_4;
-                    break;
-                case 36000000: //36M
-                    aryRates[0] = 0x48; // 36M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_5;
-                    break;
-                case 48000000: //48M
-                    aryRates[0] = 0x60; // 48M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_6;
-                    break;
-                case 54000000: //54M
-                    aryRates[0] = 0x6c; // 54M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_7;
-                    break;
-                case -1: //Auto
-                default:
-                    if (pAdapter->CommonCfg.PhyMode == PHY_11B)
-                    { //B Only
-                        aryRates[0] = 0x16; // 11Mbps
-                        aryRates[1] = 0x0b; // 5.5Mbps
-                        aryRates[2] = 0x04; // 2Mbps
-                        aryRates[3] = 0x02; // 1Mbps
-                    }
-                    else
-                    { //(B/G) Mixed or (A/B/G) Mixed
-                        aryRates[0] = 0x6c; // 54Mbps
-                        aryRates[1] = 0x60; // 48Mbps
-                        aryRates[2] = 0x48; // 36Mbps
-                        aryRates[3] = 0x30; // 24Mbps
-                        aryRates[4] = 0x16; // 11Mbps
-                        aryRates[5] = 0x0b; // 5.5Mbps
-                        aryRates[6] = 0x04; // 2Mbps
-                        aryRates[7] = 0x02; // 1Mbps
-                    }
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
-                    break;
-            }
-            break;
-    }
-
-    NdisZeroMemory(pAdapter->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
-    NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES));
-    DBGPRINT(RT_DEBUG_TRACE, (" RTMPSetDesiredRates (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
-        pAdapter->CommonCfg.DesireRate[0],pAdapter->CommonCfg.DesireRate[1],
-        pAdapter->CommonCfg.DesireRate[2],pAdapter->CommonCfg.DesireRate[3],
-        pAdapter->CommonCfg.DesireRate[4],pAdapter->CommonCfg.DesireRate[5],
-        pAdapter->CommonCfg.DesireRate[6],pAdapter->CommonCfg.DesireRate[7] ));
-    // Changing DesiredRate may affect the MAX TX rate we used to TX frames out
-    MlmeUpdateTxRates(pAdapter, FALSE, 0);
-}
-
-NDIS_STATUS RTMPWPARemoveKeyProc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PVOID			pBuf)
-{
-	PNDIS_802_11_REMOVE_KEY pKey;
-	ULONG					KeyIdx;
-	NDIS_STATUS 			Status = NDIS_STATUS_FAILURE;
-	BOOLEAN 	bTxKey; 		// Set the key as transmit key
-	BOOLEAN 	bPairwise;		// Indicate the key is pairwise key
-	BOOLEAN 	bKeyRSC;		// indicate the receive  SC set by KeyRSC value.
-								// Otherwise, it will set by the NIC.
-	BOOLEAN 	bAuthenticator; // indicate key is set by authenticator.
-	INT 		i;
-
-	DBGPRINT(RT_DEBUG_TRACE,("---> RTMPWPARemoveKeyProc\n"));
-
-	pKey = (PNDIS_802_11_REMOVE_KEY) pBuf;
-	KeyIdx = pKey->KeyIndex & 0xff;
-	// Bit 31 of Add-key, Tx Key
-	bTxKey		   = (pKey->KeyIndex & 0x80000000) ? TRUE : FALSE;
-	// Bit 30 of Add-key PairwiseKey
-	bPairwise	   = (pKey->KeyIndex & 0x40000000) ? TRUE : FALSE;
-	// Bit 29 of Add-key KeyRSC
-	bKeyRSC 	   = (pKey->KeyIndex & 0x20000000) ? TRUE : FALSE;
-	// Bit 28 of Add-key Authenticator
-	bAuthenticator = (pKey->KeyIndex & 0x10000000) ? TRUE : FALSE;
-
-	// 1. If bTx is TRUE, return failure information
-	if (bTxKey == TRUE)
-		return(NDIS_STATUS_INVALID_DATA);
-
-	// 2. Check Pairwise Key
-	if (bPairwise)
-	{
-		// a. If BSSID is broadcast, remove all pairwise keys.
-		// b. If not broadcast, remove the pairwise specified by BSSID
-		for (i = 0; i < SHARE_KEY_NUM; i++)
-		{
-			if (MAC_ADDR_EQUAL(pAd->SharedKey[BSS0][i].BssId, pKey->BSSID))
-			{
-				DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveKeyProc(KeyIdx=%d)\n", i));
-				pAd->SharedKey[BSS0][i].KeyLen = 0;
-				pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_NONE;
-				AsicRemoveSharedKeyEntry(pAd, BSS0, (UCHAR)i);
-				Status = NDIS_STATUS_SUCCESS;
-				break;
-			}
+	memset(&aryRates, 0x00, sizeof(NDIS_802_11_RATES));
+	switch (pAdapter->CommonCfg.PhyMode) {
+	case PHY_11A:		/* A only */
+		switch (Rates) {
+		case 6000000:	/*6M */
+			aryRates[0] = 0x0c;	/* 6M */
+			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
+			    MCS_0;
+			break;
+		case 9000000:	/*9M */
+			aryRates[0] = 0x12;	/* 9M */
+			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
+			    MCS_1;
+			break;
+		case 12000000:	/*12M */
+			aryRates[0] = 0x18;	/* 12M */
+			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
+			    MCS_2;
+			break;
+		case 18000000:	/*18M */
+			aryRates[0] = 0x24;	/* 18M */
+			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
+			    MCS_3;
+			break;
+		case 24000000:	/*24M */
+			aryRates[0] = 0x30;	/* 24M */
+			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
+			    MCS_4;
+			break;
+		case 36000000:	/*36M */
+			aryRates[0] = 0x48;	/* 36M */
+			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
+			    MCS_5;
+			break;
+		case 48000000:	/*48M */
+			aryRates[0] = 0x60;	/* 48M */
+			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
+			    MCS_6;
+			break;
+		case 54000000:	/*54M */
+			aryRates[0] = 0x6c;	/* 54M */
+			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
+			    MCS_7;
+			break;
+		case -1:	/*Auto */
+		default:
+			aryRates[0] = 0x6c;	/* 54Mbps */
+			aryRates[1] = 0x60;	/* 48Mbps */
+			aryRates[2] = 0x48;	/* 36Mbps */
+			aryRates[3] = 0x30;	/* 24Mbps */
+			aryRates[4] = 0x24;	/* 18M */
+			aryRates[5] = 0x18;	/* 12M */
+			aryRates[6] = 0x12;	/* 9M */
+			aryRates[7] = 0x0c;	/* 6M */
+			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
+			    MCS_AUTO;
+			break;
 		}
-	}
-	// 3. Group Key
-	else
-	{
-		// a. If BSSID is broadcast, remove all group keys indexed
-		// b. If BSSID matched, delete the group key indexed.
-		DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveKeyProc(KeyIdx=%ld)\n", KeyIdx));
-		pAd->SharedKey[BSS0][KeyIdx].KeyLen = 0;
-		pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
-		AsicRemoveSharedKeyEntry(pAd, BSS0, (UCHAR)KeyIdx);
-		Status = NDIS_STATUS_SUCCESS;
+		break;
+	case PHY_11BG_MIXED:	/* B/G Mixed */
+	case PHY_11B:		/* B only */
+	case PHY_11ABG_MIXED:	/* A/B/G Mixed */
+	default:
+		switch (Rates) {
+		case 1000000:	/*1M */
+			aryRates[0] = 0x02;
+			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
+			    MCS_0;
+			break;
+		case 2000000:	/*2M */
+			aryRates[0] = 0x04;
+			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
+			    MCS_1;
+			break;
+		case 5000000:	/*5.5M */
+			aryRates[0] = 0x0b;	/* 5.5M */
+			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
+			    MCS_2;
+			break;
+		case 11000000:	/*11M */
+			aryRates[0] = 0x16;	/* 11M */
+			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
+			    MCS_3;
+			break;
+		case 6000000:	/*6M */
+			aryRates[0] = 0x0c;	/* 6M */
+			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
+			    MCS_0;
+			break;
+		case 9000000:	/*9M */
+			aryRates[0] = 0x12;	/* 9M */
+			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
+			    MCS_1;
+			break;
+		case 12000000:	/*12M */
+			aryRates[0] = 0x18;	/* 12M */
+			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
+			    MCS_2;
+			break;
+		case 18000000:	/*18M */
+			aryRates[0] = 0x24;	/* 18M */
+			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
+			    MCS_3;
+			break;
+		case 24000000:	/*24M */
+			aryRates[0] = 0x30;	/* 24M */
+			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
+			    MCS_4;
+			break;
+		case 36000000:	/*36M */
+			aryRates[0] = 0x48;	/* 36M */
+			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
+			    MCS_5;
+			break;
+		case 48000000:	/*48M */
+			aryRates[0] = 0x60;	/* 48M */
+			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
+			    MCS_6;
+			break;
+		case 54000000:	/*54M */
+			aryRates[0] = 0x6c;	/* 54M */
+			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
+			    MCS_7;
+			break;
+		case -1:	/*Auto */
+		default:
+			if (pAdapter->CommonCfg.PhyMode == PHY_11B) {	/*B Only */
+				aryRates[0] = 0x16;	/* 11Mbps */
+				aryRates[1] = 0x0b;	/* 5.5Mbps */
+				aryRates[2] = 0x04;	/* 2Mbps */
+				aryRates[3] = 0x02;	/* 1Mbps */
+			} else {	/*(B/G) Mixed or (A/B/G) Mixed */
+				aryRates[0] = 0x6c;	/* 54Mbps */
+				aryRates[1] = 0x60;	/* 48Mbps */
+				aryRates[2] = 0x48;	/* 36Mbps */
+				aryRates[3] = 0x30;	/* 24Mbps */
+				aryRates[4] = 0x16;	/* 11Mbps */
+				aryRates[5] = 0x0b;	/* 5.5Mbps */
+				aryRates[6] = 0x04;	/* 2Mbps */
+				aryRates[7] = 0x02;	/* 1Mbps */
+			}
+			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
+			    MCS_AUTO;
+			break;
+		}
+		break;
 	}
 
-	return (Status);
+	NdisZeroMemory(pAdapter->CommonCfg.DesireRate,
+		       MAX_LEN_OF_SUPPORTED_RATES);
+	NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates,
+		       sizeof(NDIS_802_11_RATES));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 (" RTMPSetDesiredRates (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
+		  pAdapter->CommonCfg.DesireRate[0],
+		  pAdapter->CommonCfg.DesireRate[1],
+		  pAdapter->CommonCfg.DesireRate[2],
+		  pAdapter->CommonCfg.DesireRate[3],
+		  pAdapter->CommonCfg.DesireRate[4],
+		  pAdapter->CommonCfg.DesireRate[5],
+		  pAdapter->CommonCfg.DesireRate[6],
+		  pAdapter->CommonCfg.DesireRate[7]));
+	/* Changing DesiredRate may affect the MAX TX rate we used to TX frames out */
+	MlmeUpdateTxRates(pAdapter, FALSE, 0);
 }
 
 /*
@@ -1093,40 +235,65 @@
 
 	========================================================================
 */
-VOID	RTMPWPARemoveAllKeys(
-	IN	PRTMP_ADAPTER	pAd)
+void RTMPWPARemoveAllKeys(struct rt_rtmp_adapter *pAd)
 {
 
-	UCHAR 	i;
+	u8 i;
 
-	DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveAllKeys(AuthMode=%d, WepStatus=%d)\n", pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus));
-
-	// For WEP/CKIP, there is no need to remove it, since WinXP won't set it again after
-	// Link up. And it will be replaced if user changed it.
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("RTMPWPARemoveAllKeys(AuthMode=%d, WepStatus=%d)\n",
+		  pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus));
+	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+	/* For WEP/CKIP, there is no need to remove it, since WinXP won't set it again after */
+	/* Link up. And it will be replaced if user changed it. */
 	if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
 		return;
 
-	// For WPA-None, there is no need to remove it, since WinXP won't set it again after
-	// Link up. And it will be replaced if user changed it.
+	/* For WPA-None, there is no need to remove it, since WinXP won't set it again after */
+	/* Link up. And it will be replaced if user changed it. */
 	if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
 		return;
 
-	// set BSSID wcid entry of the Pair-wise Key table as no-security mode
+	/* set BSSID wcid entry of the Pair-wise Key table as no-security mode */
 	AsicRemovePairwiseKeyEntry(pAd, BSS0, BSSID_WCID);
 
-	// set all shared key mode as no-security.
-	for (i = 0; i < SHARE_KEY_NUM; i++)
-    {
-		DBGPRINT(RT_DEBUG_TRACE,("remove %s key #%d\n", CipherName[pAd->SharedKey[BSS0][i].CipherAlg], i));
-		NdisZeroMemory(&pAd->SharedKey[BSS0][i], sizeof(CIPHER_KEY));
+	/* set all shared key mode as no-security. */
+	for (i = 0; i < SHARE_KEY_NUM; i++) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("remove %s key #%d\n",
+			  CipherName[pAd->SharedKey[BSS0][i].CipherAlg], i));
+		NdisZeroMemory(&pAd->SharedKey[BSS0][i], sizeof(struct rt_cipher_key));
 
 		AsicRemoveSharedKeyEntry(pAd, BSS0, i);
 	}
-
+	RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
 }
 
 /*
 	========================================================================
+
+	Routine Description:
+		As STA's BSSID is a WC too, it uses shared key table.
+		This function write correct unicast TX key to ASIC WCID.
+		And we still make a copy in our MacTab.Content[BSSID_WCID].PairwiseKey.
+		Caller guarantee TKIP/AES always has keyidx = 0. (pairwise key)
+		Caller guarantee WEP calls this function when set Txkey,  default key index=0~3.
+
+	Arguments:
+		pAd					Pointer to our adapter
+		pKey							Pointer to the where the key stored
+
+	Return Value:
+		NDIS_SUCCESS					Add key successfully
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+/*
+	========================================================================
 	Routine Description:
 		Change NIC PHY mode. Re-association may be necessary. possible settings
 		include - PHY_11B, PHY_11BG_MIXED, PHY_11A, and PHY_11ABG_MIXED
@@ -1140,115 +307,119 @@
 
 	========================================================================
 */
-VOID	RTMPSetPhyMode(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	ULONG phymode)
+void RTMPSetPhyMode(struct rt_rtmp_adapter *pAd, unsigned long phymode)
 {
-	INT i;
-	// the selected phymode must be supported by the RF IC encoded in E2PROM
+	int i;
+	/* the selected phymode must be supported by the RF IC encoded in E2PROM */
 
-	pAd->CommonCfg.PhyMode = (UCHAR)phymode;
+	/* if no change, do nothing */
+	/* bug fix
+	   if (pAd->CommonCfg.PhyMode == phymode)
+	   return;
+	 */
+	pAd->CommonCfg.PhyMode = (u8)phymode;
 
-	DBGPRINT(RT_DEBUG_TRACE,("RTMPSetPhyMode : PhyMode=%d, channel=%d \n", pAd->CommonCfg.PhyMode, pAd->CommonCfg.Channel));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("RTMPSetPhyMode : PhyMode=%d, channel=%d \n",
+		  pAd->CommonCfg.PhyMode, pAd->CommonCfg.Channel));
 
 	BuildChannelList(pAd);
 
-	// sanity check user setting
-	for (i = 0; i < pAd->ChannelListNum; i++)
-	{
+	/* sanity check user setting */
+	for (i = 0; i < pAd->ChannelListNum; i++) {
 		if (pAd->CommonCfg.Channel == pAd->ChannelList[i].Channel)
 			break;
 	}
 
-	if (i == pAd->ChannelListNum)
-	{
+	if (i == pAd->ChannelListNum) {
 		pAd->CommonCfg.Channel = FirstChannel(pAd);
-		DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetPhyMode: channel is out of range, use first channel=%d \n", pAd->CommonCfg.Channel));
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("RTMPSetPhyMode: channel is out of range, use first channel=%d \n",
+			  pAd->CommonCfg.Channel));
 	}
 
 	NdisZeroMemory(pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
 	NdisZeroMemory(pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
 	NdisZeroMemory(pAd->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
 	switch (phymode) {
-		case PHY_11B:
-			pAd->CommonCfg.SupRate[0]  = 0x82;	  // 1 mbps, in units of 0.5 Mbps, basic rate
-			pAd->CommonCfg.SupRate[1]  = 0x84;	  // 2 mbps, in units of 0.5 Mbps, basic rate
-			pAd->CommonCfg.SupRate[2]  = 0x8B;	  // 5.5 mbps, in units of 0.5 Mbps, basic rate
-			pAd->CommonCfg.SupRate[3]  = 0x96;	  // 11 mbps, in units of 0.5 Mbps, basic rate
-			pAd->CommonCfg.SupRateLen  = 4;
-			pAd->CommonCfg.ExtRateLen  = 0;
-			pAd->CommonCfg.DesireRate[0]  = 2;	   // 1 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[1]  = 4;	   // 2 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[2]  = 11;    // 5.5 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[3]  = 22;    // 11 mbps, in units of 0.5 Mbps
-			//pAd->CommonCfg.HTPhyMode.field.MODE = MODE_CCK; // This MODE is only FYI. not use
-			break;
+	case PHY_11B:
+		pAd->CommonCfg.SupRate[0] = 0x82;	/* 1 mbps, in units of 0.5 Mbps, basic rate */
+		pAd->CommonCfg.SupRate[1] = 0x84;	/* 2 mbps, in units of 0.5 Mbps, basic rate */
+		pAd->CommonCfg.SupRate[2] = 0x8B;	/* 5.5 mbps, in units of 0.5 Mbps, basic rate */
+		pAd->CommonCfg.SupRate[3] = 0x96;	/* 11 mbps, in units of 0.5 Mbps, basic rate */
+		pAd->CommonCfg.SupRateLen = 4;
+		pAd->CommonCfg.ExtRateLen = 0;
+		pAd->CommonCfg.DesireRate[0] = 2;	/* 1 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.DesireRate[1] = 4;	/* 2 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.DesireRate[2] = 11;	/* 5.5 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.DesireRate[3] = 22;	/* 11 mbps, in units of 0.5 Mbps */
+		/*pAd->CommonCfg.HTPhyMode.field.MODE = MODE_CCK; // This MODE is only FYI. not use */
+		break;
 
-		case PHY_11G:
-		case PHY_11BG_MIXED:
-		case PHY_11ABG_MIXED:
-		case PHY_11N_2_4G:
-		case PHY_11ABGN_MIXED:
-		case PHY_11BGN_MIXED:
-		case PHY_11GN_MIXED:
-			pAd->CommonCfg.SupRate[0]  = 0x82;	  // 1 mbps, in units of 0.5 Mbps, basic rate
-			pAd->CommonCfg.SupRate[1]  = 0x84;	  // 2 mbps, in units of 0.5 Mbps, basic rate
-			pAd->CommonCfg.SupRate[2]  = 0x8B;	  // 5.5 mbps, in units of 0.5 Mbps, basic rate
-			pAd->CommonCfg.SupRate[3]  = 0x96;	  // 11 mbps, in units of 0.5 Mbps, basic rate
-			pAd->CommonCfg.SupRate[4]  = 0x12;	  // 9 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.SupRate[5]  = 0x24;	  // 18 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.SupRate[6]  = 0x48;	  // 36 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.SupRate[7]  = 0x6c;	  // 54 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.SupRateLen  = 8;
-			pAd->CommonCfg.ExtRate[0]  = 0x0C;	  // 6 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.ExtRate[1]  = 0x18;	  // 12 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.ExtRate[2]  = 0x30;	  // 24 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.ExtRate[3]  = 0x60;	  // 48 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.ExtRateLen  = 4;
-			pAd->CommonCfg.DesireRate[0]  = 2;	   // 1 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[1]  = 4;	   // 2 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[2]  = 11;    // 5.5 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[3]  = 22;    // 11 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[4]  = 12;    // 6 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[5]  = 18;    // 9 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[6]  = 24;    // 12 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[7]  = 36;    // 18 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[8]  = 48;    // 24 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[9]  = 72;    // 36 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[10] = 96;    // 48 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[11] = 108;   // 54 mbps, in units of 0.5 Mbps
-			break;
+	case PHY_11G:
+	case PHY_11BG_MIXED:
+	case PHY_11ABG_MIXED:
+	case PHY_11N_2_4G:
+	case PHY_11ABGN_MIXED:
+	case PHY_11BGN_MIXED:
+	case PHY_11GN_MIXED:
+		pAd->CommonCfg.SupRate[0] = 0x82;	/* 1 mbps, in units of 0.5 Mbps, basic rate */
+		pAd->CommonCfg.SupRate[1] = 0x84;	/* 2 mbps, in units of 0.5 Mbps, basic rate */
+		pAd->CommonCfg.SupRate[2] = 0x8B;	/* 5.5 mbps, in units of 0.5 Mbps, basic rate */
+		pAd->CommonCfg.SupRate[3] = 0x96;	/* 11 mbps, in units of 0.5 Mbps, basic rate */
+		pAd->CommonCfg.SupRate[4] = 0x12;	/* 9 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.SupRate[5] = 0x24;	/* 18 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.SupRate[6] = 0x48;	/* 36 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.SupRate[7] = 0x6c;	/* 54 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.SupRateLen = 8;
+		pAd->CommonCfg.ExtRate[0] = 0x0C;	/* 6 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.ExtRate[1] = 0x18;	/* 12 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.ExtRate[2] = 0x30;	/* 24 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.ExtRate[3] = 0x60;	/* 48 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.ExtRateLen = 4;
+		pAd->CommonCfg.DesireRate[0] = 2;	/* 1 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.DesireRate[1] = 4;	/* 2 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.DesireRate[2] = 11;	/* 5.5 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.DesireRate[3] = 22;	/* 11 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.DesireRate[4] = 12;	/* 6 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.DesireRate[5] = 18;	/* 9 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.DesireRate[6] = 24;	/* 12 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.DesireRate[7] = 36;	/* 18 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.DesireRate[8] = 48;	/* 24 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.DesireRate[9] = 72;	/* 36 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.DesireRate[10] = 96;	/* 48 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.DesireRate[11] = 108;	/* 54 mbps, in units of 0.5 Mbps */
+		break;
 
-		case PHY_11A:
-		case PHY_11AN_MIXED:
-		case PHY_11AGN_MIXED:
-		case PHY_11N_5G:
-			pAd->CommonCfg.SupRate[0]  = 0x8C;	  // 6 mbps, in units of 0.5 Mbps, basic rate
-			pAd->CommonCfg.SupRate[1]  = 0x12;	  // 9 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.SupRate[2]  = 0x98;	  // 12 mbps, in units of 0.5 Mbps, basic rate
-			pAd->CommonCfg.SupRate[3]  = 0x24;	  // 18 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.SupRate[4]  = 0xb0;	  // 24 mbps, in units of 0.5 Mbps, basic rate
-			pAd->CommonCfg.SupRate[5]  = 0x48;	  // 36 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.SupRate[6]  = 0x60;	  // 48 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.SupRate[7]  = 0x6c;	  // 54 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.SupRateLen  = 8;
-			pAd->CommonCfg.ExtRateLen  = 0;
-			pAd->CommonCfg.DesireRate[0]  = 12;    // 6 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[1]  = 18;    // 9 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[2]  = 24;    // 12 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[3]  = 36;    // 18 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[4]  = 48;    // 24 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[5]  = 72;    // 36 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[6]  = 96;    // 48 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[7]  = 108;   // 54 mbps, in units of 0.5 Mbps
-			//pAd->CommonCfg.HTPhyMode.field.MODE = MODE_OFDM; // This MODE is only FYI. not use
-			break;
+	case PHY_11A:
+	case PHY_11AN_MIXED:
+	case PHY_11AGN_MIXED:
+	case PHY_11N_5G:
+		pAd->CommonCfg.SupRate[0] = 0x8C;	/* 6 mbps, in units of 0.5 Mbps, basic rate */
+		pAd->CommonCfg.SupRate[1] = 0x12;	/* 9 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.SupRate[2] = 0x98;	/* 12 mbps, in units of 0.5 Mbps, basic rate */
+		pAd->CommonCfg.SupRate[3] = 0x24;	/* 18 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.SupRate[4] = 0xb0;	/* 24 mbps, in units of 0.5 Mbps, basic rate */
+		pAd->CommonCfg.SupRate[5] = 0x48;	/* 36 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.SupRate[6] = 0x60;	/* 48 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.SupRate[7] = 0x6c;	/* 54 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.SupRateLen = 8;
+		pAd->CommonCfg.ExtRateLen = 0;
+		pAd->CommonCfg.DesireRate[0] = 12;	/* 6 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.DesireRate[1] = 18;	/* 9 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.DesireRate[2] = 24;	/* 12 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.DesireRate[3] = 36;	/* 18 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.DesireRate[4] = 48;	/* 24 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.DesireRate[5] = 72;	/* 36 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.DesireRate[6] = 96;	/* 48 mbps, in units of 0.5 Mbps */
+		pAd->CommonCfg.DesireRate[7] = 108;	/* 54 mbps, in units of 0.5 Mbps */
+		/*pAd->CommonCfg.HTPhyMode.field.MODE = MODE_OFDM; // This MODE is only FYI. not use */
+		break;
 
-		default:
-			break;
+	default:
+		break;
 	}
 
-
 	pAd->CommonCfg.BandState = UNKNOWN_BAND;
 }
 
@@ -1264,34 +435,33 @@
 
 	========================================================================
 */
-VOID	RTMPSetHT(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	OID_SET_HT_PHYMODE *pHTPhyMode)
+void RTMPSetHT(struct rt_rtmp_adapter *pAd, struct rt_oid_set_ht_phymode *pHTPhyMode)
 {
-	//ULONG	*pmcs;
-	UINT32	Value = 0;
-	UCHAR	BBPValue = 0;
-	UCHAR	BBP3Value = 0;
-	UCHAR	RxStream = pAd->CommonCfg.RxStream;
+	/*unsigned long *pmcs; */
+	u32 Value = 0;
+	u8 BBPValue = 0;
+	u8 BBP3Value = 0;
+	u8 RxStream = pAd->CommonCfg.RxStream;
 
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : HT_mode(%d), ExtOffset(%d), MCS(%d), BW(%d), STBC(%d), SHORTGI(%d)\n",
-										pHTPhyMode->HtMode, pHTPhyMode->ExtOffset,
-										pHTPhyMode->MCS, pHTPhyMode->BW,
-										pHTPhyMode->STBC, pHTPhyMode->SHORTGI));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("RTMPSetHT : HT_mode(%d), ExtOffset(%d), MCS(%d), BW(%d), STBC(%d), SHORTGI(%d)\n",
+		  pHTPhyMode->HtMode, pHTPhyMode->ExtOffset, pHTPhyMode->MCS,
+		  pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->SHORTGI));
 
-	// Don't zero supportedHyPhy structure.
-	RTMPZeroMemory(&pAd->CommonCfg.HtCapability, sizeof(pAd->CommonCfg.HtCapability));
-	RTMPZeroMemory(&pAd->CommonCfg.AddHTInfo, sizeof(pAd->CommonCfg.AddHTInfo));
-	RTMPZeroMemory(&pAd->CommonCfg.NewExtChanOffset, sizeof(pAd->CommonCfg.NewExtChanOffset));
-	RTMPZeroMemory(&pAd->CommonCfg.DesiredHtPhy, sizeof(pAd->CommonCfg.DesiredHtPhy));
+	/* Don't zero supportedHyPhy structure. */
+	RTMPZeroMemory(&pAd->CommonCfg.HtCapability,
+		       sizeof(pAd->CommonCfg.HtCapability));
+	RTMPZeroMemory(&pAd->CommonCfg.AddHTInfo,
+		       sizeof(pAd->CommonCfg.AddHTInfo));
+	RTMPZeroMemory(&pAd->CommonCfg.NewExtChanOffset,
+		       sizeof(pAd->CommonCfg.NewExtChanOffset));
+	RTMPZeroMemory(&pAd->CommonCfg.DesiredHtPhy,
+		       sizeof(pAd->CommonCfg.DesiredHtPhy));
 
-   	if (pAd->CommonCfg.bRdg)
-	{
+	if (pAd->CommonCfg.bRdg) {
 		pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 1;
 		pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 1;
-	}
-	else
-	{
+	} else {
 		pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 0;
 		pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 0;
 	}
@@ -1299,89 +469,92 @@
 	pAd->CommonCfg.HtCapability.HtCapParm.MaxRAmpduFactor = 3;
 	pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor = 3;
 
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : RxBAWinLimit = %d\n", pAd->CommonCfg.BACapability.field.RxBAWinLimit));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("RTMPSetHT : RxBAWinLimit = %d\n",
+		  pAd->CommonCfg.BACapability.field.RxBAWinLimit));
 
-	// Mimo power save, A-MSDU size,
-	pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable;
-	pAd->CommonCfg.DesiredHtPhy.AmsduSize = (UCHAR)pAd->CommonCfg.BACapability.field.AmsduSize;
-	pAd->CommonCfg.DesiredHtPhy.MimoPs = (UCHAR)pAd->CommonCfg.BACapability.field.MMPSmode;
-	pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
+	/* Mimo power save, A-MSDU size, */
+	pAd->CommonCfg.DesiredHtPhy.AmsduEnable =
+	    (u16)pAd->CommonCfg.BACapability.field.AmsduEnable;
+	pAd->CommonCfg.DesiredHtPhy.AmsduSize =
+	    (u8)pAd->CommonCfg.BACapability.field.AmsduSize;
+	pAd->CommonCfg.DesiredHtPhy.MimoPs =
+	    (u8)pAd->CommonCfg.BACapability.field.MMPSmode;
+	pAd->CommonCfg.DesiredHtPhy.MpduDensity =
+	    (u8)pAd->CommonCfg.BACapability.field.MpduDensity;
 
-	pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
-	pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
-	pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
+	pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize =
+	    (u16)pAd->CommonCfg.BACapability.field.AmsduSize;
+	pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs =
+	    (u16)pAd->CommonCfg.BACapability.field.MMPSmode;
+	pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity =
+	    (u8)pAd->CommonCfg.BACapability.field.MpduDensity;
 
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : AMsduSize = %d, MimoPs = %d, MpduDensity = %d, MaxRAmpduFactor = %d\n",
-													pAd->CommonCfg.DesiredHtPhy.AmsduSize,
-													pAd->CommonCfg.DesiredHtPhy.MimoPs,
-													pAd->CommonCfg.DesiredHtPhy.MpduDensity,
-													pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("RTMPSetHT : AMsduSize = %d, MimoPs = %d, MpduDensity = %d, MaxRAmpduFactor = %d\n",
+		  pAd->CommonCfg.DesiredHtPhy.AmsduSize,
+		  pAd->CommonCfg.DesiredHtPhy.MimoPs,
+		  pAd->CommonCfg.DesiredHtPhy.MpduDensity,
+		  pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor));
 
-	if(pHTPhyMode->HtMode == HTMODE_GF)
-	{
+	if (pHTPhyMode->HtMode == HTMODE_GF) {
 		pAd->CommonCfg.HtCapability.HtCapInfo.GF = 1;
 		pAd->CommonCfg.DesiredHtPhy.GF = 1;
-	}
-	else
+	} else
 		pAd->CommonCfg.DesiredHtPhy.GF = 0;
 
-	// Decide Rx MCSSet
-	switch (RxStream)
-	{
-		case 1:
-			pAd->CommonCfg.HtCapability.MCSSet[0] =  0xff;
-			pAd->CommonCfg.HtCapability.MCSSet[1] =  0x00;
-			break;
+	/* Decide Rx MCSSet */
+	switch (RxStream) {
+	case 1:
+		pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
+		pAd->CommonCfg.HtCapability.MCSSet[1] = 0x00;
+		break;
 
-		case 2:
-			pAd->CommonCfg.HtCapability.MCSSet[0] =  0xff;
-			pAd->CommonCfg.HtCapability.MCSSet[1] =  0xff;
-			break;
+	case 2:
+		pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
+		pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff;
+		break;
 
-		case 3: // 3*3
-			pAd->CommonCfg.HtCapability.MCSSet[0] =  0xff;
-			pAd->CommonCfg.HtCapability.MCSSet[1] =  0xff;
-			pAd->CommonCfg.HtCapability.MCSSet[2] =  0xff;
-			break;
+	case 3:		/* 3*3 */
+		pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
+		pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff;
+		pAd->CommonCfg.HtCapability.MCSSet[2] = 0xff;
+		break;
 	}
 
-	if (pAd->CommonCfg.bForty_Mhz_Intolerant && (pAd->CommonCfg.Channel <= 14) && (pHTPhyMode->BW == BW_40) )
-	{
+	if (pAd->CommonCfg.bForty_Mhz_Intolerant
+	    && (pAd->CommonCfg.Channel <= 14) && (pHTPhyMode->BW == BW_40)) {
 		pHTPhyMode->BW = BW_20;
 		pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant = 1;
 	}
 
-	if(pHTPhyMode->BW == BW_40)
-	{
-		pAd->CommonCfg.HtCapability.MCSSet[4] = 0x1; // MCS 32
+	if (pHTPhyMode->BW == BW_40) {
+		pAd->CommonCfg.HtCapability.MCSSet[4] = 0x1;	/* MCS 32 */
 		pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 1;
 		if (pAd->CommonCfg.Channel <= 14)
 			pAd->CommonCfg.HtCapability.HtCapInfo.CCKmodein40 = 1;
 
 		pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 1;
 		pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 1;
-		pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = (pHTPhyMode->ExtOffset == EXTCHA_BELOW)? (EXTCHA_BELOW): EXTCHA_ABOVE;
-		// Set Regsiter for extension channel position.
+		pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset =
+		    (pHTPhyMode->ExtOffset ==
+		     EXTCHA_BELOW) ? (EXTCHA_BELOW) : EXTCHA_ABOVE;
+		/* Set Regsiter for extension channel position. */
 		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
 		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBP3Value);
-		if ((pHTPhyMode->ExtOffset == EXTCHA_BELOW))
-		{
+		if ((pHTPhyMode->ExtOffset == EXTCHA_BELOW)) {
 			Value |= 0x1;
 			BBP3Value |= (0x20);
 			RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
-		}
-		else if ((pHTPhyMode->ExtOffset == EXTCHA_ABOVE))
-		{
+		} else if ((pHTPhyMode->ExtOffset == EXTCHA_ABOVE)) {
 			Value &= 0xfe;
 			BBP3Value &= (~0x20);
 			RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
 		}
-
-		// Turn on BBP 40MHz mode now only as AP .
-		// Sta can turn on BBP 40MHz after connection with 40MHz AP. Sta only broadcast 40MHz capability before connection.
+		/* Turn on BBP 40MHz mode now only as AP . */
+		/* Sta can turn on BBP 40MHz after connection with 40MHz AP. Sta only broadcast 40MHz capability before connection. */
 		if ((pAd->OpMode == OPMODE_AP) || INFRA_ON(pAd) || ADHOC_ON(pAd)
-			)
-		{
+		    ) {
 			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
 			BBPValue &= (~0x18);
 			BBPValue |= 0x10;
@@ -1390,15 +563,13 @@
 			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBP3Value);
 			pAd->CommonCfg.BBPCurrentBW = BW_40;
 		}
-	}
-	else
-	{
+	} else {
 		pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 0;
 		pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 0;
 		pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0;
 		pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = EXTCHA_NONE;
 		pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
-		// Turn on BBP 20MHz mode by request here.
+		/* Turn on BBP 20MHz mode by request here. */
 		{
 			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
 			BBPValue &= (~0x18);
@@ -1407,42 +578,35 @@
 		}
 	}
 
-	if(pHTPhyMode->STBC == STBC_USE)
-	{
+	if (pHTPhyMode->STBC == STBC_USE) {
 		pAd->CommonCfg.HtCapability.HtCapInfo.TxSTBC = 1;
 		pAd->CommonCfg.DesiredHtPhy.TxSTBC = 1;
 		pAd->CommonCfg.HtCapability.HtCapInfo.RxSTBC = 1;
 		pAd->CommonCfg.DesiredHtPhy.RxSTBC = 1;
-	}
-	else
-	{
+	} else {
 		pAd->CommonCfg.DesiredHtPhy.TxSTBC = 0;
 		pAd->CommonCfg.DesiredHtPhy.RxSTBC = 0;
 	}
 
-	if(pHTPhyMode->SHORTGI == GI_400)
-	{
+	if (pHTPhyMode->SHORTGI == GI_400) {
 		pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 1;
 		pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 1;
 		pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 1;
 		pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 1;
-	}
-	else
-	{
+	} else {
 		pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 0;
 		pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 0;
 		pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 0;
 		pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 0;
 	}
 
-	// We support link adaptation for unsolicit MCS feedback, set to 2.
-	pAd->CommonCfg.HtCapability.ExtHtCapInfo.MCSFeedback = MCSFBK_NONE; //MCSFBK_UNSOLICIT;
+	/* We support link adaptation for unsolicit MCS feedback, set to 2. */
+	pAd->CommonCfg.HtCapability.ExtHtCapInfo.MCSFeedback = MCSFBK_NONE;	/*MCSFBK_UNSOLICIT; */
 	pAd->CommonCfg.AddHTInfo.ControlChan = pAd->CommonCfg.Channel;
-	// 1, the extension channel above the control channel.
+	/* 1, the extension channel above the control channel. */
 
-	// EDCA parameters used for AP's own transmission
-	if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
-	{
+	/* EDCA parameters used for AP's own transmission */
+	if (pAd->CommonCfg.APEdcaParm.bValid == FALSE) {
 		pAd->CommonCfg.APEdcaParm.bValid = TRUE;
 		pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
 		pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
@@ -1459,14 +623,17 @@
 		pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
 		pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
 
-		pAd->CommonCfg.APEdcaParm.Txop[0]  = 0;
-		pAd->CommonCfg.APEdcaParm.Txop[1]  = 0;
-		pAd->CommonCfg.APEdcaParm.Txop[2]  = 94;
-		pAd->CommonCfg.APEdcaParm.Txop[3]  = 47;
+		pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
+		pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
+		pAd->CommonCfg.APEdcaParm.Txop[2] = 94;
+		pAd->CommonCfg.APEdcaParm.Txop[3] = 47;
 	}
 	AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
 
-	RTMPSetIndividualHT(pAd, 0);
+	{
+		RTMPSetIndividualHT(pAd, 0);
+	}
+
 }
 
 /*
@@ -1481,112 +648,103 @@
 
 	========================================================================
 */
-VOID	RTMPSetIndividualHT(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	UCHAR				apidx)
+void RTMPSetIndividualHT(struct rt_rtmp_adapter *pAd, u8 apidx)
 {
-	PRT_HT_PHY_INFO		pDesired_ht_phy = NULL;
-	UCHAR	TxStream = pAd->CommonCfg.TxStream;
-	UCHAR	DesiredMcs	= MCS_AUTO;
+	struct rt_ht_phy_info *pDesired_ht_phy = NULL;
+	u8 TxStream = pAd->CommonCfg.TxStream;
+	u8 DesiredMcs = MCS_AUTO;
 
-	do
-	{
+	do {
 		{
 			pDesired_ht_phy = &pAd->StaCfg.DesiredHtPhyInfo;
-			DesiredMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
-			//pAd->StaCfg.bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE;
-				break;
+			DesiredMcs =
+			    pAd->StaCfg.DesiredTransmitSetting.field.MCS;
+			/*pAd->StaCfg.bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE; */
+			break;
 		}
 	} while (FALSE);
 
-	if (pDesired_ht_phy == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx));
+	if (pDesired_ht_phy == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx));
 		return;
 	}
-	RTMPZeroMemory(pDesired_ht_phy, sizeof(RT_HT_PHY_INFO));
+	RTMPZeroMemory(pDesired_ht_phy, sizeof(struct rt_ht_phy_info));
 
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetIndividualHT : Desired MCS = %d\n", DesiredMcs));
-	// Check the validity of MCS
-	if ((TxStream == 1) && ((DesiredMcs >= MCS_8) && (DesiredMcs <= MCS_15)))
-	{
-		DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS(%d) is invalid in 1S, reset it as MCS_7\n", DesiredMcs));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("RTMPSetIndividualHT : Desired MCS = %d\n", DesiredMcs));
+	/* Check the validity of MCS */
+	if ((TxStream == 1)
+	    && ((DesiredMcs >= MCS_8) && (DesiredMcs <= MCS_15))) {
+		DBGPRINT(RT_DEBUG_WARN,
+			 ("RTMPSetIndividualHT: MCS(%d) is invalid in 1S, reset it as MCS_7\n",
+			  DesiredMcs));
 		DesiredMcs = MCS_7;
 	}
 
-	if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_20) && (DesiredMcs == MCS_32))
-	{
-		DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS_32 is only supported in 40-MHz, reset it as MCS_0\n"));
+	if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_20)
+	    && (DesiredMcs == MCS_32)) {
+		DBGPRINT(RT_DEBUG_WARN,
+			 ("RTMPSetIndividualHT: MCS_32 is only supported in 40-MHz, reset it as MCS_0\n"));
 		DesiredMcs = MCS_0;
 	}
 
 	pDesired_ht_phy->bHtEnable = TRUE;
 
-	// Decide desired Tx MCS
-	switch (TxStream)
-	{
-		case 1:
-			if (DesiredMcs == MCS_AUTO)
-			{
-				pDesired_ht_phy->MCSSet[0]= 0xff;
-				pDesired_ht_phy->MCSSet[1]= 0x00;
-			}
-			else if (DesiredMcs <= MCS_7)
-			{
-				pDesired_ht_phy->MCSSet[0]= 1<<DesiredMcs;
-				pDesired_ht_phy->MCSSet[1]= 0x00;
-			}
-			break;
+	/* Decide desired Tx MCS */
+	switch (TxStream) {
+	case 1:
+		if (DesiredMcs == MCS_AUTO) {
+			pDesired_ht_phy->MCSSet[0] = 0xff;
+			pDesired_ht_phy->MCSSet[1] = 0x00;
+		} else if (DesiredMcs <= MCS_7) {
+			pDesired_ht_phy->MCSSet[0] = 1 << DesiredMcs;
+			pDesired_ht_phy->MCSSet[1] = 0x00;
+		}
+		break;
 
-		case 2:
-			if (DesiredMcs == MCS_AUTO)
-			{
-				pDesired_ht_phy->MCSSet[0]= 0xff;
-				pDesired_ht_phy->MCSSet[1]= 0xff;
-			}
-			else if (DesiredMcs <= MCS_15)
-			{
-				ULONG mode;
+	case 2:
+		if (DesiredMcs == MCS_AUTO) {
+			pDesired_ht_phy->MCSSet[0] = 0xff;
+			pDesired_ht_phy->MCSSet[1] = 0xff;
+		} else if (DesiredMcs <= MCS_15) {
+			unsigned long mode;
 
-				mode = DesiredMcs / 8;
-				if (mode < 2)
-					pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8));
-			}
-			break;
+			mode = DesiredMcs / 8;
+			if (mode < 2)
+				pDesired_ht_phy->MCSSet[mode] =
+				    (1 << (DesiredMcs - mode * 8));
+		}
+		break;
 
-		case 3: // 3*3
-			if (DesiredMcs == MCS_AUTO)
-			{
-				/* MCS0 ~ MCS23, 3 bytes */
-				pDesired_ht_phy->MCSSet[0]= 0xff;
-				pDesired_ht_phy->MCSSet[1]= 0xff;
-				pDesired_ht_phy->MCSSet[2]= 0xff;
-			}
-			else if (DesiredMcs <= MCS_23)
-			{
-				ULONG mode;
+	case 3:		/* 3*3 */
+		if (DesiredMcs == MCS_AUTO) {
+			/* MCS0 ~ MCS23, 3 bytes */
+			pDesired_ht_phy->MCSSet[0] = 0xff;
+			pDesired_ht_phy->MCSSet[1] = 0xff;
+			pDesired_ht_phy->MCSSet[2] = 0xff;
+		} else if (DesiredMcs <= MCS_23) {
+			unsigned long mode;
 
-				mode = DesiredMcs / 8;
-				if (mode < 3)
-					pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8));
-			}
-			break;
+			mode = DesiredMcs / 8;
+			if (mode < 3)
+				pDesired_ht_phy->MCSSet[mode] =
+				    (1 << (DesiredMcs - mode * 8));
+		}
+		break;
 	}
 
-	if(pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_40)
-	{
+	if (pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_40) {
 		if (DesiredMcs == MCS_AUTO || DesiredMcs == MCS_32)
 			pDesired_ht_phy->MCSSet[4] = 0x1;
 	}
-
-	// update HT Rate setting
-    if (pAd->OpMode == OPMODE_STA)
-        MlmeUpdateHtTxRates(pAd, BSS0);
-    else
-	    MlmeUpdateHtTxRates(pAd, apidx);
+	/* update HT Rate setting */
+	if (pAd->OpMode == OPMODE_STA)
+		MlmeUpdateHtTxRates(pAd, BSS0);
+	else
+		MlmeUpdateHtTxRates(pAd, apidx);
 }
 
-
 /*
 	========================================================================
 	Routine Description:
@@ -1595,36 +753,34 @@
 	Arguments:
 		Send all HT IE in beacon/probe rsp/assoc rsp/action frame.
 
-
 	========================================================================
 */
-VOID	RTMPUpdateHTIE(
-	IN	RT_HT_CAPABILITY	*pRtHt,
-	IN		UCHAR				*pMcsSet,
-	OUT		HT_CAPABILITY_IE *pHtCapability,
-	OUT		ADD_HT_INFO_IE		*pAddHtInfo)
+void RTMPUpdateHTIE(struct rt_ht_capability *pRtHt,
+		    u8 * pMcsSet,
+		    struct rt_ht_capability_ie * pHtCapability,
+		    struct rt_add_ht_info_ie * pAddHtInfo)
 {
-	RTMPZeroMemory(pHtCapability, sizeof(HT_CAPABILITY_IE));
-	RTMPZeroMemory(pAddHtInfo, sizeof(ADD_HT_INFO_IE));
+	RTMPZeroMemory(pHtCapability, sizeof(struct rt_ht_capability_ie));
+	RTMPZeroMemory(pAddHtInfo, sizeof(struct rt_add_ht_info_ie));
 
-		pHtCapability->HtCapInfo.ChannelWidth = pRtHt->ChannelWidth;
-		pHtCapability->HtCapInfo.MimoPs = pRtHt->MimoPs;
-		pHtCapability->HtCapInfo.GF = pRtHt->GF;
-		pHtCapability->HtCapInfo.ShortGIfor20 = pRtHt->ShortGIfor20;
-		pHtCapability->HtCapInfo.ShortGIfor40 = pRtHt->ShortGIfor40;
-		pHtCapability->HtCapInfo.TxSTBC = pRtHt->TxSTBC;
-		pHtCapability->HtCapInfo.RxSTBC = pRtHt->RxSTBC;
-		pHtCapability->HtCapInfo.AMsduSize = pRtHt->AmsduSize;
-		pHtCapability->HtCapParm.MaxRAmpduFactor = pRtHt->MaxRAmpduFactor;
-		pHtCapability->HtCapParm.MpduDensity = pRtHt->MpduDensity;
+	pHtCapability->HtCapInfo.ChannelWidth = pRtHt->ChannelWidth;
+	pHtCapability->HtCapInfo.MimoPs = pRtHt->MimoPs;
+	pHtCapability->HtCapInfo.GF = pRtHt->GF;
+	pHtCapability->HtCapInfo.ShortGIfor20 = pRtHt->ShortGIfor20;
+	pHtCapability->HtCapInfo.ShortGIfor40 = pRtHt->ShortGIfor40;
+	pHtCapability->HtCapInfo.TxSTBC = pRtHt->TxSTBC;
+	pHtCapability->HtCapInfo.RxSTBC = pRtHt->RxSTBC;
+	pHtCapability->HtCapInfo.AMsduSize = pRtHt->AmsduSize;
+	pHtCapability->HtCapParm.MaxRAmpduFactor = pRtHt->MaxRAmpduFactor;
+	pHtCapability->HtCapParm.MpduDensity = pRtHt->MpduDensity;
 
-		pAddHtInfo->AddHtInfo.ExtChanOffset = pRtHt->ExtChanOffset ;
-		pAddHtInfo->AddHtInfo.RecomWidth = pRtHt->RecomWidth;
-		pAddHtInfo->AddHtInfo2.OperaionMode = pRtHt->OperaionMode;
-		pAddHtInfo->AddHtInfo2.NonGfPresent = pRtHt->NonGfPresent;
-		RTMPMoveMemory(pAddHtInfo->MCSSet, /*pRtHt->MCSSet*/pMcsSet, 4); // rt2860 only support MCS max=32, no need to copy all 16 uchar.
+	pAddHtInfo->AddHtInfo.ExtChanOffset = pRtHt->ExtChanOffset;
+	pAddHtInfo->AddHtInfo.RecomWidth = pRtHt->RecomWidth;
+	pAddHtInfo->AddHtInfo2.OperaionMode = pRtHt->OperaionMode;
+	pAddHtInfo->AddHtInfo2.NonGfPresent = pRtHt->NonGfPresent;
+	RTMPMoveMemory(pAddHtInfo->MCSSet, /*pRtHt->MCSSet */ pMcsSet, 4);	/* rt2860 only support MCS max=32, no need to copy all 16 uchar. */
 
-        DBGPRINT(RT_DEBUG_TRACE,("RTMPUpdateHTIE <== \n"));
+	DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateHTIE <== \n"));
 }
 
 /*
@@ -1634,78 +790,71 @@
     Return:
 	========================================================================
 */
-VOID	RTMPAddWcidAttributeEntry(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			BssIdx,
-	IN 	UCHAR		 	KeyIdx,
-	IN 	UCHAR		 	CipherAlg,
-	IN 	MAC_TABLE_ENTRY *pEntry)
+void RTMPAddWcidAttributeEntry(struct rt_rtmp_adapter *pAd,
+			       u8 BssIdx,
+			       u8 KeyIdx,
+			       u8 CipherAlg, struct rt_mac_table_entry *pEntry)
 {
-	UINT32		WCIDAttri = 0;
-	USHORT		offset;
-	UCHAR		IVEIV = 0;
-	USHORT		Wcid = 0;
+	u32 WCIDAttri = 0;
+	u16 offset;
+	u8 IVEIV = 0;
+	u16 Wcid = 0;
 
 	{
 		{
-			if (BssIdx > BSS0)
-			{
-				DBGPRINT(RT_DEBUG_ERROR, ("RTMPAddWcidAttributeEntry: The BSS-index(%d) is out of range for Infra link. \n", BssIdx));
+			if (BssIdx > BSS0) {
+				DBGPRINT(RT_DEBUG_ERROR,
+					 ("RTMPAddWcidAttributeEntry: The BSS-index(%d) is out of range for Infra link. \n",
+					  BssIdx));
 				return;
 			}
-
-			// 1.	In ADHOC mode, the AID is wcid number. And NO mesh link exists.
-			// 2.	In Infra mode, the AID:1 MUST be wcid of infra STA.
-			//					   the AID:2~ assign to mesh link entry.
-			if (pEntry && ADHOC_ON(pAd))
+			/* 1.   In ADHOC mode, the AID is wcid number. And NO mesh link exists. */
+			/* 2.   In Infra mode, the AID:1 MUST be wcid of infra STA. */
+			/*                                         the AID:2~ assign to mesh link entry. */
+			if (pEntry)
 				Wcid = pEntry->Aid;
-			else if (pEntry && INFRA_ON(pAd))
-			{
-				Wcid = BSSID_WCID;
-			}
 			else
 				Wcid = MCAST_WCID;
 		}
 	}
 
-	// Update WCID attribute table
+	/* Update WCID attribute table */
 	offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
 
 	{
 		if (pEntry && pEntry->ValidAsMesh)
-			WCIDAttri = (CipherAlg<<1) | PAIRWISEKEYTABLE;
+			WCIDAttri = (CipherAlg << 1) | PAIRWISEKEYTABLE;
 		else
-			WCIDAttri = (CipherAlg<<1) | SHAREDKEYTABLE;
+			WCIDAttri = (CipherAlg << 1) | SHAREDKEYTABLE;
 	}
 
 	RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
 
-
-	// Update IV/EIV table
+	/* Update IV/EIV table */
 	offset = MAC_IVEIV_TABLE_BASE + (Wcid * HW_IVEIV_ENTRY_SIZE);
 
-	// WPA mode
-	if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) || (CipherAlg == CIPHER_AES))
-	{
-		// Eiv bit on. keyid always is 0 for pairwise key
-		IVEIV = (KeyIdx <<6) | 0x20;
-	}
-	else
-	{
-		// WEP KeyIdx is default tx key.
+	/* WPA mode */
+	if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC)
+	    || (CipherAlg == CIPHER_AES)) {
+		/* Eiv bit on. keyid always is 0 for pairwise key */
+		IVEIV = (KeyIdx << 6) | 0x20;
+	} else {
+		/* WEP KeyIdx is default tx key. */
 		IVEIV = (KeyIdx << 6);
 	}
 
-	// For key index and ext IV bit, so only need to update the position(offset+3).
-#ifdef RT2860
-	RTMP_IO_WRITE8(pAd, offset+3, IVEIV);
-#endif
-#ifdef RT2870
-	RTUSBMultiWrite_OneByte(pAd, offset+3, &IVEIV);
-#endif // RT2870 //
+	/* For key index and ext IV bit, so only need to update the position(offset+3). */
+#ifdef RTMP_MAC_PCI
+	RTMP_IO_WRITE8(pAd, offset + 3, IVEIV);
+#endif /* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
+	RTUSBMultiWrite_OneByte(pAd, offset + 3, &IVEIV);
+#endif /* RTMP_MAC_USB // */
 
-	DBGPRINT(RT_DEBUG_TRACE,("RTMPAddWcidAttributeEntry: WCID #%d, KeyIndex #%d, Alg=%s\n",Wcid, KeyIdx, CipherName[CipherAlg]));
-	DBGPRINT(RT_DEBUG_TRACE,("	WCIDAttri = 0x%x \n",  WCIDAttri));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("RTMPAddWcidAttributeEntry: WCID #%d, KeyIndex #%d, Alg=%s\n",
+		  Wcid, KeyIdx, CipherName[CipherAlg]));
+	DBGPRINT(RT_DEBUG_TRACE, ("	WCIDAttri = 0x%x \n", WCIDAttri));
 
 }
 
@@ -1723,1524 +872,84 @@
     Note:
     ==========================================================================
 */
-CHAR *GetEncryptType(CHAR enc)
+char *GetEncryptType(char enc)
 {
-    if(enc == Ndis802_11WEPDisabled)
-        return "NONE";
-    if(enc == Ndis802_11WEPEnabled)
-    	return "WEP";
-    if(enc == Ndis802_11Encryption2Enabled)
-    	return "TKIP";
-    if(enc == Ndis802_11Encryption3Enabled)
-    	return "AES";
-	if(enc == Ndis802_11Encryption4Enabled)
-    	return "TKIPAES";
-    else
-    	return "UNKNOW";
-}
-
-CHAR *GetAuthMode(CHAR auth)
-{
-    if(auth == Ndis802_11AuthModeOpen)
-    	return "OPEN";
-    if(auth == Ndis802_11AuthModeShared)
-    	return "SHARED";
-	if(auth == Ndis802_11AuthModeAutoSwitch)
-    	return "AUTOWEP";
-    if(auth == Ndis802_11AuthModeWPA)
-    	return "WPA";
-    if(auth == Ndis802_11AuthModeWPAPSK)
-    	return "WPAPSK";
-    if(auth == Ndis802_11AuthModeWPANone)
-    	return "WPANONE";
-    if(auth == Ndis802_11AuthModeWPA2)
-    	return "WPA2";
-    if(auth == Ndis802_11AuthModeWPA2PSK)
-    	return "WPA2PSK";
-	if(auth == Ndis802_11AuthModeWPA1WPA2)
-    	return "WPA1WPA2";
-	if(auth == Ndis802_11AuthModeWPA1PSKWPA2PSK)
-    	return "WPA1PSKWPA2PSK";
-
-    	return "UNKNOW";
-}
-
-/*
-    ==========================================================================
-    Description:
-        Get site survey results
-	Arguments:
-	    pAdapter                    Pointer to our adapter
-	    wrq                         Pointer to the ioctl argument
-
-    Return Value:
-        None
-
-    Note:
-        Usage:
-        		1.) UI needs to wait 4 seconds after issue a site survey command
-        		2.) iwpriv ra0 get_site_survey
-        		3.) UI needs to prepare at least 4096bytes to get the results
-    ==========================================================================
-*/
-#define	LINE_LEN	(4+33+20+8+10+9+7+3)	// Channel+SSID+Bssid+WepStatus+AuthMode+Signal+WiressMode+NetworkType
-VOID RTMPIoctlGetSiteSurvey(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq)
-{
-	CHAR		*msg;
-	INT 		i=0;
-	INT			WaitCnt;
-	INT 		Status=0;
-	CHAR		Ssid[MAX_LEN_OF_SSID +1];
-    INT         Rssi = 0, max_len = LINE_LEN;
-	UINT        Rssi_Quality = 0;
-	NDIS_802_11_NETWORK_TYPE    wireless_mode;
-
-	os_alloc_mem(NULL, (PUCHAR *)&msg, sizeof(CHAR)*((MAX_LEN_OF_BSS_TABLE)*max_len));
-
-	if (msg == NULL)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - msg memory alloc fail.\n"));
-		return;
-	}
-
-	memset(msg, 0 ,(MAX_LEN_OF_BSS_TABLE)*max_len );
-	memset(Ssid, 0 ,(MAX_LEN_OF_SSID +1));
-	sprintf(msg,"%s","\n");
-	sprintf(msg+strlen(msg),"%-4s%-33s%-20s%-8s%-10s%-9s%-7s%-3s\n",
-	    "Ch", "SSID", "BSSID", "Enc", "Auth", "Siganl(%)", "W-Mode", " NT");
-
-	WaitCnt = 0;
-	pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
-
-	while ((ScanRunning(pAdapter) == TRUE) && (WaitCnt++ < 200))
-		OS_WAIT(500);
-
-	for(i=0; i<pAdapter->ScanTab.BssNr ;i++)
-	{
-		if( pAdapter->ScanTab.BssEntry[i].Channel==0)
-			break;
-
-		if((strlen(msg)+max_len ) >= IW_SCAN_MAX_DATA)
-			break;
-
-		//Channel
-		sprintf(msg+strlen(msg),"%-4d", pAdapter->ScanTab.BssEntry[i].Channel);
-		//SSID
-		memcpy(Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
-		Ssid[pAdapter->ScanTab.BssEntry[i].SsidLen] = '\0';
-		sprintf(msg+strlen(msg),"%-33s", Ssid);
-		//BSSID
-		sprintf(msg+strlen(msg),"%02x:%02x:%02x:%02x:%02x:%02x   ",
-			pAdapter->ScanTab.BssEntry[i].Bssid[0],
-			pAdapter->ScanTab.BssEntry[i].Bssid[1],
-			pAdapter->ScanTab.BssEntry[i].Bssid[2],
-			pAdapter->ScanTab.BssEntry[i].Bssid[3],
-			pAdapter->ScanTab.BssEntry[i].Bssid[4],
-			pAdapter->ScanTab.BssEntry[i].Bssid[5]);
-		//Encryption Type
-		sprintf(msg+strlen(msg),"%-8s",GetEncryptType(pAdapter->ScanTab.BssEntry[i].WepStatus));
-		//Authentication Mode
-		if (pAdapter->ScanTab.BssEntry[i].WepStatus == Ndis802_11WEPEnabled)
-			sprintf(msg+strlen(msg),"%-10s", "UNKNOW");
-		else
-			sprintf(msg+strlen(msg),"%-10s",GetAuthMode(pAdapter->ScanTab.BssEntry[i].AuthMode));
-		// Rssi
-		Rssi = (INT)pAdapter->ScanTab.BssEntry[i].Rssi;
-		if (Rssi >= -50)
-			Rssi_Quality = 100;
-		else if (Rssi >= -80)    // between -50 ~ -80dbm
-			Rssi_Quality = (UINT)(24 + ((Rssi + 80) * 26)/10);
-		else if (Rssi >= -90)   // between -80 ~ -90dbm
-			Rssi_Quality = (UINT)(((Rssi + 90) * 26)/10);
-		else    // < -84 dbm
-			Rssi_Quality = 0;
-		sprintf(msg+strlen(msg),"%-9d", Rssi_Quality);
-		// Wireless Mode
-		wireless_mode = NetworkTypeInUseSanity(&pAdapter->ScanTab.BssEntry[i]);
-		if (wireless_mode == Ndis802_11FH ||
-			wireless_mode == Ndis802_11DS)
-			sprintf(msg+strlen(msg),"%-7s", "11b");
-		else if (wireless_mode == Ndis802_11OFDM5)
-			sprintf(msg+strlen(msg),"%-7s", "11a");
-		else if (wireless_mode == Ndis802_11OFDM5_N)
-			sprintf(msg+strlen(msg),"%-7s", "11a/n");
-		else if (wireless_mode == Ndis802_11OFDM24)
-			sprintf(msg+strlen(msg),"%-7s", "11b/g");
-		else if (wireless_mode == Ndis802_11OFDM24_N)
-			sprintf(msg+strlen(msg),"%-7s", "11b/g/n");
-		else
-			sprintf(msg+strlen(msg),"%-7s", "unknow");
-		//Network Type
-		if (pAdapter->ScanTab.BssEntry[i].BssType == BSS_ADHOC)
-			sprintf(msg+strlen(msg),"%-3s", " Ad");
-		else
-			sprintf(msg+strlen(msg),"%-3s", " In");
-
-        sprintf(msg+strlen(msg),"\n");
-	}
-
-	pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
-	wrq->u.data.length = strlen(msg);
-	Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - wrq->u.data.length = %d\n", wrq->u.data.length));
-	os_free_mem(NULL, (PUCHAR)msg);
-}
-
-
-#define	MAC_LINE_LEN	(14+4+4+10+10+10+6+6)	// Addr+aid+psm+datatime+rxbyte+txbyte+current tx rate+last tx rate
-VOID RTMPIoctlGetMacTable(
-	IN PRTMP_ADAPTER pAd,
-	IN struct iwreq *wrq)
-{
-	INT i;
-	RT_802_11_MAC_TABLE MacTab;
-	char *msg;
-
-	MacTab.Num = 0;
-	for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
-	{
-		if (pAd->MacTab.Content[i].ValidAsCLI && (pAd->MacTab.Content[i].Sst == SST_ASSOC))
-		{
-			COPY_MAC_ADDR(MacTab.Entry[MacTab.Num].Addr, &pAd->MacTab.Content[i].Addr);
-			MacTab.Entry[MacTab.Num].Aid = (UCHAR)pAd->MacTab.Content[i].Aid;
-			MacTab.Entry[MacTab.Num].Psm = pAd->MacTab.Content[i].PsMode;
-			MacTab.Entry[MacTab.Num].MimoPs = pAd->MacTab.Content[i].MmpsMode;
-
-			// Fill in RSSI per entry
-			MacTab.Entry[MacTab.Num].AvgRssi0 = pAd->MacTab.Content[i].RssiSample.AvgRssi0;
-			MacTab.Entry[MacTab.Num].AvgRssi1 = pAd->MacTab.Content[i].RssiSample.AvgRssi1;
-			MacTab.Entry[MacTab.Num].AvgRssi2 = pAd->MacTab.Content[i].RssiSample.AvgRssi2;
-
-			// the connected time per entry
-			MacTab.Entry[MacTab.Num].ConnectedTime = pAd->MacTab.Content[i].StaConnectTime;
-			MacTab.Entry[MacTab.Num].TxRate.field.MCS = pAd->MacTab.Content[i].HTPhyMode.field.MCS;
-			MacTab.Entry[MacTab.Num].TxRate.field.BW = pAd->MacTab.Content[i].HTPhyMode.field.BW;
-			MacTab.Entry[MacTab.Num].TxRate.field.ShortGI = pAd->MacTab.Content[i].HTPhyMode.field.ShortGI;
-			MacTab.Entry[MacTab.Num].TxRate.field.STBC = pAd->MacTab.Content[i].HTPhyMode.field.STBC;
-			MacTab.Entry[MacTab.Num].TxRate.field.rsv = pAd->MacTab.Content[i].HTPhyMode.field.rsv;
-			MacTab.Entry[MacTab.Num].TxRate.field.MODE = pAd->MacTab.Content[i].HTPhyMode.field.MODE;
-			MacTab.Entry[MacTab.Num].TxRate.word = pAd->MacTab.Content[i].HTPhyMode.word;
-
-			MacTab.Num += 1;
-		}
-	}
-	wrq->u.data.length = sizeof(RT_802_11_MAC_TABLE);
-	if (copy_to_user(wrq->u.data.pointer, &MacTab, wrq->u.data.length))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __func__));
-	}
-
-	msg = (CHAR *) kmalloc(sizeof(CHAR)*(MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN), MEM_ALLOC_FLAG);
-	memset(msg, 0 ,MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN );
-	sprintf(msg,"%s","\n");
-	sprintf(msg+strlen(msg),"%-14s%-4s%-4s%-10s%-10s%-10s%-6s%-6s\n",
-		"MAC", "AID", "PSM", "LDT", "RxB", "TxB","CTxR", "LTxR");
-
-	for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
-	{
-		PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
-		if (pEntry->ValidAsCLI && (pEntry->Sst == SST_ASSOC))
-		{
-			if((strlen(msg)+MAC_LINE_LEN ) >= (MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN) )
-				break;
-			sprintf(msg+strlen(msg),"%02x%02x%02x%02x%02x%02x  ",
-				pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
-				pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
-			sprintf(msg+strlen(msg),"%-4d", (int)pEntry->Aid);
-			sprintf(msg+strlen(msg),"%-4d", (int)pEntry->PsMode);
-			sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.LastDataPacketTime*/); // ToDo
-			sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.TotalRxByteCount*/); // ToDo
-			sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.TotalTxByteCount*/); // ToDo
-			sprintf(msg+strlen(msg),"%-6d",RateIdToMbps[pAd->MacTab.Content[i].CurrTxRate]);
-			sprintf(msg+strlen(msg),"%-6d\n",0/*RateIdToMbps[pAd->MacTab.Content[i].LastTxRate]*/); // ToDo
-		}
-	}
-	// for compatible with old API just do the printk to console
-	//wrq->u.data.length = strlen(msg);
-	//if (copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("%s", msg));
-	}
-
-	kfree(msg);
-}
-
-INT	Set_BASetup_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-    UCHAR mac[6], tid;
-	char *token, sepValue[] = ":", DASH = '-';
-	INT i;
-    MAC_TABLE_ENTRY *pEntry;
-
-/*
-	The BASetup inupt string format should be xx:xx:xx:xx:xx:xx-d,
-		=>The six 2 digit hex-decimal number previous are the Mac address,
-		=>The seventh decimal number is the tid value.
-*/
-
-	if(strlen(arg) < 19)  //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
-		return FALSE;
-
-	token = strchr(arg, DASH);
-	if ((token != NULL) && (strlen(token)>1))
-	{
-		tid = simple_strtol((token+1), 0, 10);
-		if (tid > 15)
-			return FALSE;
-
-		*token = '\0';
-		for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
-		{
-			if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
-				return FALSE;
-			AtoH(token, (PUCHAR)(&mac[i]), 1);
-		}
-		if(i != 6)
-			return FALSE;
-
-		printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x\n", mac[0], mac[1],
-				mac[2], mac[3], mac[4], mac[5], tid);
-
-	    pEntry = MacTableLookup(pAd, mac);
-
-    	if (pEntry) {
-        	printk("\nSetup BA Session: Tid = %d\n", tid);
-	        BAOriSessionSetUp(pAd, pEntry, tid, 0, 100, TRUE);
-    	}
-
-		return TRUE;
-	}
-
-	return FALSE;
-
-}
-
-INT	Set_BADecline_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	ULONG bBADecline;
-
-	bBADecline = simple_strtol(arg, 0, 10);
-
-	if (bBADecline == 0)
-	{
-		pAd->CommonCfg.bBADecline = FALSE;
-	}
-	else if (bBADecline == 1)
-	{
-		pAd->CommonCfg.bBADecline = TRUE;
-	}
+	if (enc == Ndis802_11WEPDisabled)
+		return "NONE";
+	if (enc == Ndis802_11WEPEnabled)
+		return "WEP";
+	if (enc == Ndis802_11Encryption2Enabled)
+		return "TKIP";
+	if (enc == Ndis802_11Encryption3Enabled)
+		return "AES";
+	if (enc == Ndis802_11Encryption4Enabled)
+		return "TKIPAES";
 	else
-	{
-		return FALSE; //Invalid argument
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_BADecline_Proc::(BADecline=%d)\n", pAd->CommonCfg.bBADecline));
-
-	return TRUE;
+		return "UNKNOW";
 }
 
-INT	Set_BAOriTearDown_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+char *GetAuthMode(char auth)
 {
-    UCHAR mac[6], tid;
-	char *token, sepValue[] = ":", DASH = '-';
-	INT i;
-    MAC_TABLE_ENTRY *pEntry;
+	if (auth == Ndis802_11AuthModeOpen)
+		return "OPEN";
+	if (auth == Ndis802_11AuthModeShared)
+		return "SHARED";
+	if (auth == Ndis802_11AuthModeAutoSwitch)
+		return "AUTOWEP";
+	if (auth == Ndis802_11AuthModeWPA)
+		return "WPA";
+	if (auth == Ndis802_11AuthModeWPAPSK)
+		return "WPAPSK";
+	if (auth == Ndis802_11AuthModeWPANone)
+		return "WPANONE";
+	if (auth == Ndis802_11AuthModeWPA2)
+		return "WPA2";
+	if (auth == Ndis802_11AuthModeWPA2PSK)
+		return "WPA2PSK";
+	if (auth == Ndis802_11AuthModeWPA1WPA2)
+		return "WPA1WPA2";
+	if (auth == Ndis802_11AuthModeWPA1PSKWPA2PSK)
+		return "WPA1PSKWPA2PSK";
 
-/*
-	The BAOriTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
-		=>The six 2 digit hex-decimal number previous are the Mac address,
-		=>The seventh decimal number is the tid value.
-*/
-    if(strlen(arg) < 19)  //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
-		return FALSE;
-
-	token = strchr(arg, DASH);
-	if ((token != NULL) && (strlen(token)>1))
-	{
-		tid = simple_strtol((token+1), 0, 10);
-		if (tid > NUM_OF_TID)
-			return FALSE;
-
-		*token = '\0';
-		for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
-		{
-			if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
-				return FALSE;
-			AtoH(token, (PUCHAR)(&mac[i]), 1);
-		}
-		if(i != 6)
-			return FALSE;
-
-	    printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
-	           mac[2], mac[3], mac[4], mac[5], tid);
-
-	    pEntry = MacTableLookup(pAd, mac);
-
-	    if (pEntry) {
-	        printk("\nTear down Ori BA Session: Tid = %d\n", tid);
-        BAOriSessionTearDown(pAd, pEntry->Aid, tid, FALSE, TRUE);
-	    }
-
-		return TRUE;
-	}
-
-	return FALSE;
-
+	return "UNKNOW";
 }
 
-INT	Set_BARecTearDown_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+int SetCommonHT(struct rt_rtmp_adapter *pAd)
 {
-    UCHAR mac[6], tid;
-	char *token, sepValue[] = ":", DASH = '-';
-	INT i;
-    MAC_TABLE_ENTRY *pEntry;
-
-    //printk("\n%s\n", arg);
-/*
-	The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
-		=>The six 2 digit hex-decimal number previous are the Mac address,
-		=>The seventh decimal number is the tid value.
-*/
-    if(strlen(arg) < 19)  //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
-		return FALSE;
-
-	token = strchr(arg, DASH);
-	if ((token != NULL) && (strlen(token)>1))
-	{
-		tid = simple_strtol((token+1), 0, 10);
-		if (tid > NUM_OF_TID)
-			return FALSE;
-
-		*token = '\0';
-		for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
-		{
-			if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
-				return FALSE;
-			AtoH(token, (PUCHAR)(&mac[i]), 1);
-		}
-		if(i != 6)
-			return FALSE;
-
-		printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
-		       mac[2], mac[3], mac[4], mac[5], tid);
-
-		pEntry = MacTableLookup(pAd, mac);
-
-		if (pEntry) {
-		    printk("\nTear down Rec BA Session: Tid = %d\n", tid);
-		    BARecSessionTearDown(pAd, pEntry->Aid, tid, FALSE);
-		}
-
-		return TRUE;
-	}
-
-	return FALSE;
-
-}
-
-INT	Set_HtBw_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	ULONG HtBw;
-
-	HtBw = simple_strtol(arg, 0, 10);
-	if (HtBw == BW_40)
-		pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_40;
-	else if (HtBw == BW_20)
-		pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_20;
-	else
-		return FALSE;  //Invalid argument
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtBw_Proc::(HtBw=%d)\n", pAd->CommonCfg.RegTransmitSetting.field.BW));
-
-	return TRUE;
-}
-
-INT	Set_HtMcs_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	ULONG HtMcs, Mcs_tmp;
-    BOOLEAN bAutoRate = FALSE;
-
-	Mcs_tmp = simple_strtol(arg, 0, 10);
-
-	if (Mcs_tmp <= 15 || Mcs_tmp == 32)
-		HtMcs = Mcs_tmp;
-	else
-		HtMcs = MCS_AUTO;
-
-	{
-		pAd->StaCfg.DesiredTransmitSetting.field.MCS = HtMcs;
-		pAd->StaCfg.bAutoTxRateSwitch = (HtMcs == MCS_AUTO) ? TRUE:FALSE;
-		DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMcs_Proc::(HtMcs=%d, bAutoTxRateSwitch = %d)\n",
-						pAd->StaCfg.DesiredTransmitSetting.field.MCS, pAd->StaCfg.bAutoTxRateSwitch));
-
-		if ((pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED) ||
-			(pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE < MODE_HTMIX))
-		{
-	        if ((pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) &&
-				(HtMcs >= 0 && HtMcs <= 3) &&
-	            (pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode == FIXED_TXMODE_CCK))
-			{
-				RTMPSetDesiredRates(pAd, (LONG) (RateIdToMbps[HtMcs] * 1000000));
-			}
-	        else if ((pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) &&
-					(HtMcs >= 0 && HtMcs <= 7) &&
-	            	(pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode == FIXED_TXMODE_OFDM))
-			{
-				RTMPSetDesiredRates(pAd, (LONG) (RateIdToMbps[HtMcs+4] * 1000000));
-			}
-			else
-				bAutoRate = TRUE;
-
-			if (bAutoRate)
-			{
-	            pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
-				RTMPSetDesiredRates(pAd, -1);
-			}
-	        DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMcs_Proc::(FixedTxMode=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode));
-		}
-        if (ADHOC_ON(pAd))
-            return TRUE;
-	}
-
-	SetCommonHT(pAd);
-
-	return TRUE;
-}
-
-INT	Set_HtGi_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	ULONG HtGi;
-
-	HtGi = simple_strtol(arg, 0, 10);
-
-	if ( HtGi == GI_400)
-		pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400;
-	else if ( HtGi == GI_800 )
-		pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800;
-	else
-		return FALSE; //Invalid argument
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtGi_Proc::(ShortGI=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.ShortGI));
-
-	return TRUE;
-}
-
-
-INT	Set_HtTxBASize_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	UCHAR Size;
-
-	Size = simple_strtol(arg, 0, 10);
-
-	if (Size <=0 || Size >=64)
-	{
-		Size = 8;
-	}
-	pAd->CommonCfg.TxBASize = Size-1;
-	DBGPRINT(RT_DEBUG_ERROR, ("Set_HtTxBASize ::(TxBASize= %d)\n", Size));
-
-	return TRUE;
-}
-
-
-INT	Set_HtOpMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-
-	if (Value == HTMODE_GF)
-		pAd->CommonCfg.RegTransmitSetting.field.HTMODE  = HTMODE_GF;
-	else if ( Value == HTMODE_MM )
-		pAd->CommonCfg.RegTransmitSetting.field.HTMODE  = HTMODE_MM;
-	else
-		return FALSE; //Invalid argument
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtOpMode_Proc::(HtOpMode=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.HTMODE));
-
-	return TRUE;
-
-}
-
-INT	Set_HtStbc_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-
-	if (Value == STBC_USE)
-		pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE;
-	else if ( Value == STBC_NONE )
-		pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE;
-	else
-		return FALSE; //Invalid argument
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_Stbc_Proc::(HtStbc=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.STBC));
-
-	return TRUE;
-}
-
-INT	Set_HtHtc_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-	if (Value == 0)
-		pAd->HTCEnable = FALSE;
-	else if ( Value ==1 )
-        	pAd->HTCEnable = TRUE;
-	else
-		return FALSE; //Invalid argument
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtHtc_Proc::(HtHtc=%d)\n",pAd->HTCEnable));
-
-	return TRUE;
-}
-
-INT	Set_HtExtcha_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-
-	if (Value == 0)
-		pAd->CommonCfg.RegTransmitSetting.field.EXTCHA  = EXTCHA_BELOW;
-	else if ( Value ==1 )
-        pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
-	else
-		return FALSE; //Invalid argument
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtExtcha_Proc::(HtExtcha=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.EXTCHA));
-
-	return TRUE;
-}
-
-INT	Set_HtMpduDensity_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-
-	if (Value <=7 && Value >= 0)
-		pAd->CommonCfg.BACapability.field.MpduDensity = Value;
-	else
-		pAd->CommonCfg.BACapability.field.MpduDensity = 4;
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMpduDensity_Proc::(HtMpduDensity=%d)\n",pAd->CommonCfg.BACapability.field.MpduDensity));
-
-	return TRUE;
-}
-
-INT	Set_HtBaWinSize_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-
-
-	if (Value >=1 && Value <= 64)
-	{
-		pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value;
-		pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value;
-	}
-	else
-	{
-        pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64;
-		pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;
-	}
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtBaWinSize_Proc::(HtBaWinSize=%d)\n",pAd->CommonCfg.BACapability.field.RxBAWinLimit));
-
-	return TRUE;
-}
-
-INT	Set_HtRdg_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-
-	if (Value == 0)
-		pAd->CommonCfg.bRdg = FALSE;
-	else if ( Value ==1 )
-	{
-		pAd->HTCEnable = TRUE;
-        	pAd->CommonCfg.bRdg = TRUE;
-	}
-	else
-		return FALSE; //Invalid argument
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtRdg_Proc::(HtRdg=%d)\n",pAd->CommonCfg.bRdg));
-
-	return TRUE;
-}
-
-INT	Set_HtLinkAdapt_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-	if (Value == 0)
-		pAd->bLinkAdapt = FALSE;
-	else if ( Value ==1 )
-	{
-			pAd->HTCEnable = TRUE;
-			pAd->bLinkAdapt = TRUE;
-	}
-	else
-		return FALSE; //Invalid argument
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtLinkAdapt_Proc::(HtLinkAdapt=%d)\n",pAd->bLinkAdapt));
-
-	return TRUE;
-}
-
-INT	Set_HtAmsdu_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-	if (Value == 0)
-		pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE;
-	else if ( Value == 1 )
-        pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE;
-	else
-		return FALSE; //Invalid argument
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtAmsdu_Proc::(HtAmsdu=%d)\n",pAd->CommonCfg.BACapability.field.AmsduEnable));
-
-	return TRUE;
-}
-
-INT	Set_HtAutoBa_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-	if (Value == 0)
-	{
-		pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
-		pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
-	}
-    else if (Value == 1)
-	{
-		pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
-		pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
-	}
-	else
-		return FALSE; //Invalid argument
-
-    pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
-    pAd->CommonCfg.REGBACapability.field.Policy = pAd->CommonCfg.BACapability.field.Policy;
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtAutoBa_Proc::(HtAutoBa=%d)\n",pAd->CommonCfg.BACapability.field.AutoBA));
-
-	return TRUE;
-
-}
-
-INT	Set_HtProtect_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-	if (Value == 0)
-		pAd->CommonCfg.bHTProtect = FALSE;
-    else if (Value == 1)
-		pAd->CommonCfg.bHTProtect = TRUE;
-	else
-		return FALSE; //Invalid argument
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtProtect_Proc::(HtProtect=%d)\n",pAd->CommonCfg.bHTProtect));
-
-	return TRUE;
-}
-
-INT	Set_SendPSMPAction_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-    UCHAR mac[6], mode;
-	char *token, sepValue[] = ":", DASH = '-';
-	INT i;
-    MAC_TABLE_ENTRY *pEntry;
-
-    //printk("\n%s\n", arg);
-/*
-	The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
-		=>The six 2 digit hex-decimal number previous are the Mac address,
-		=>The seventh decimal number is the mode value.
-*/
-    if(strlen(arg) < 19)  //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and mode value in decimal format.
-		return FALSE;
-
-   	token = strchr(arg, DASH);
-	if ((token != NULL) && (strlen(token)>1))
-	{
-		mode = simple_strtol((token+1), 0, 10);
-		if (mode > MMPS_ENABLE)
-			return FALSE;
-
-		*token = '\0';
-		for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
-		{
-			if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
-				return FALSE;
-			AtoH(token, (PUCHAR)(&mac[i]), 1);
-		}
-		if(i != 6)
-			return FALSE;
-
-		printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
-		       mac[2], mac[3], mac[4], mac[5], mode);
-
-		pEntry = MacTableLookup(pAd, mac);
-
-		if (pEntry) {
-		    printk("\nSendPSMPAction MIPS mode = %d\n", mode);
-		    SendPSMPAction(pAd, pEntry->Aid, mode);
-		}
-
-		return TRUE;
-	}
-
-	return FALSE;
-
-
-}
-
-INT	Set_HtMIMOPSmode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-
-	if (Value <=3 && Value >= 0)
-		pAd->CommonCfg.BACapability.field.MMPSmode = Value;
-	else
-		pAd->CommonCfg.BACapability.field.MMPSmode = 3;
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMIMOPSmode_Proc::(MIMOPS mode=%d)\n",pAd->CommonCfg.BACapability.field.MMPSmode));
-
-	return TRUE;
-}
-
-
-INT	Set_ForceShortGI_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-	if (Value == 0)
-		pAd->WIFItestbed.bShortGI = FALSE;
-	else if (Value == 1)
-		pAd->WIFItestbed.bShortGI = TRUE;
-	else
-		return FALSE; //Invalid argument
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_ForceShortGI_Proc::(ForceShortGI=%d)\n", pAd->WIFItestbed.bShortGI));
-
-	return TRUE;
-}
-
-
-
-INT	Set_ForceGF_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-	if (Value == 0)
-		pAd->WIFItestbed.bGreenField = FALSE;
-	else if (Value == 1)
-		pAd->WIFItestbed.bGreenField = TRUE;
-	else
-		return FALSE; //Invalid argument
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_ForceGF_Proc::(ForceGF=%d)\n", pAd->WIFItestbed.bGreenField));
-
-	return TRUE;
-}
-
-INT	Set_HtMimoPs_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-	if (Value == 0)
-		pAd->CommonCfg.bMIMOPSEnable = FALSE;
-	else if (Value == 1)
-		pAd->CommonCfg.bMIMOPSEnable = TRUE;
-	else
-		return FALSE; //Invalid argument
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMimoPs_Proc::(HtMimoPs=%d)\n",pAd->CommonCfg.bMIMOPSEnable));
-
-	return TRUE;
-}
-
-INT	SetCommonHT(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	OID_SET_HT_PHYMODE		SetHT;
+	struct rt_oid_set_ht_phymode SetHT;
 
 	if (pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED)
 		return FALSE;
 
 	SetHT.PhyMode = pAd->CommonCfg.PhyMode;
-	SetHT.TransmitNo = ((UCHAR)pAd->Antenna.field.TxPath);
-	SetHT.HtMode = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.HTMODE;
-	SetHT.ExtOffset = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
+	SetHT.TransmitNo = ((u8)pAd->Antenna.field.TxPath);
+	SetHT.HtMode = (u8)pAd->CommonCfg.RegTransmitSetting.field.HTMODE;
+	SetHT.ExtOffset =
+	    (u8)pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
 	SetHT.MCS = MCS_AUTO;
-	SetHT.BW = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.BW;
-	SetHT.STBC = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.STBC;
-	SetHT.SHORTGI = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.ShortGI;
+	SetHT.BW = (u8)pAd->CommonCfg.RegTransmitSetting.field.BW;
+	SetHT.STBC = (u8)pAd->CommonCfg.RegTransmitSetting.field.STBC;
+	SetHT.SHORTGI = (u8)pAd->CommonCfg.RegTransmitSetting.field.ShortGI;
 
 	RTMPSetHT(pAd, &SetHT);
 
 	return TRUE;
 }
 
-INT	Set_FixedTxMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+char *RTMPGetRalinkEncryModeStr(u16 encryMode)
 {
-	UCHAR	fix_tx_mode = FIXED_TXMODE_HT;
-
-	if (strcmp(arg, "OFDM") == 0 || strcmp(arg, "ofdm") == 0)
-	{
-		fix_tx_mode = FIXED_TXMODE_OFDM;
-	}
-	else if (strcmp(arg, "CCK") == 0 || strcmp(arg, "cck") == 0)
-	{
-        fix_tx_mode = FIXED_TXMODE_CCK;
-	}
-
-	pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_FixedTxMode_Proc::(FixedTxMode=%d)\n", fix_tx_mode));
-
-	return TRUE;
-}
-
-/////////////////////////////////////////////////////////////////////////
-PCHAR   RTMPGetRalinkAuthModeStr(
-    IN  NDIS_802_11_AUTHENTICATION_MODE authMode)
-{
-	switch(authMode)
-	{
-		case Ndis802_11AuthModeOpen:
-			return "OPEN";
-		case Ndis802_11AuthModeWPAPSK:
-			return "WPAPSK";
-		case Ndis802_11AuthModeShared:
-			return "SHARED";
-		case Ndis802_11AuthModeWPA:
-			return "WPA";
-		case Ndis802_11AuthModeWPA2:
-			return "WPA2";
-		case Ndis802_11AuthModeWPA2PSK:
-			return "WPA2PSK";
-        case Ndis802_11AuthModeWPA1PSKWPA2PSK:
-			return "WPAPSKWPA2PSK";
-        case Ndis802_11AuthModeWPA1WPA2:
-			return "WPA1WPA2";
-		case Ndis802_11AuthModeWPANone:
-			return "WPANONE";
-		default:
-			return "UNKNOW";
+	switch (encryMode) {
+	case Ndis802_11WEPDisabled:
+		return "NONE";
+	case Ndis802_11WEPEnabled:
+		return "WEP";
+	case Ndis802_11Encryption2Enabled:
+		return "TKIP";
+	case Ndis802_11Encryption3Enabled:
+		return "AES";
+	case Ndis802_11Encryption4Enabled:
+		return "TKIPAES";
+	default:
+		return "UNKNOW";
 	}
 }
-
-PCHAR   RTMPGetRalinkEncryModeStr(
-    IN  USHORT encryMode)
-{
-	switch(encryMode)
-	{
-#if defined(RT2860) || defined(RT30xx)
-	    default:
-#endif
-		case Ndis802_11WEPDisabled:
-			return "NONE";
-		case Ndis802_11WEPEnabled:
-			return "WEP";
-		case Ndis802_11Encryption2Enabled:
-			return "TKIP";
-		case Ndis802_11Encryption3Enabled:
-			return "AES";
-        case Ndis802_11Encryption4Enabled:
-			return "TKIPAES";
-#if !defined(RT2860) && !defined(RT30xx)
-		default:
-			return "UNKNOW";
-#endif
-	}
-}
-
-INT RTMPShowCfgValue(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pName,
-	IN	PUCHAR			pBuf)
-{
-	INT	Status = 0;
-
-	for (PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC = RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC++)
-	{
-		if (!strcmp(pName, PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name))
-		{
-			if(PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->show_proc(pAd, pBuf))
-				Status = -EINVAL;
-			break;  //Exit for loop.
-		}
-	}
-
-	if(PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name == NULL)
-	{
-		sprintf(pBuf, "\n");
-		for (PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC = RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC++)
-			sprintf(pBuf + strlen(pBuf), "%s\n", PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name);
-	}
-
-	return Status;
-}
-
-INT	Show_SSID_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	sprintf(pBuf, "\t%s", pAd->CommonCfg.Ssid);
-	return 0;
-}
-
-INT	Show_WirelessMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	switch(pAd->CommonCfg.PhyMode)
-	{
-		case PHY_11BG_MIXED:
-			sprintf(pBuf, "\t11B/G");
-			break;
-		case PHY_11B:
-			sprintf(pBuf, "\t11B");
-			break;
-		case PHY_11A:
-			sprintf(pBuf, "\t11A");
-			break;
-		case PHY_11ABG_MIXED:
-			sprintf(pBuf, "\t11A/B/G");
-			break;
-		case PHY_11G:
-			sprintf(pBuf, "\t11G");
-			break;
-		case PHY_11ABGN_MIXED:
-			sprintf(pBuf, "\t11A/B/G/N");
-			break;
-		case PHY_11N_2_4G:
-			sprintf(pBuf, "\t11N only with 2.4G");
-			break;
-		case PHY_11GN_MIXED:
-			sprintf(pBuf, "\t11G/N");
-			break;
-		case PHY_11AN_MIXED:
-			sprintf(pBuf, "\t11A/N");
-			break;
-		case PHY_11BGN_MIXED:
-			sprintf(pBuf, "\t11B/G/N");
-			break;
-		case PHY_11AGN_MIXED:
-			sprintf(pBuf, "\t11A/G/N");
-			break;
-		case PHY_11N_5G:
-			sprintf(pBuf, "\t11N only with 5G");
-			break;
-		default:
-			sprintf(pBuf, "\tUnknow Value(%d)", pAd->CommonCfg.PhyMode);
-			break;
-	}
-	return 0;
-}
-
-
-INT	Show_TxBurst_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	sprintf(pBuf, "\t%s", pAd->CommonCfg.bEnableTxBurst ? "TRUE":"FALSE");
-	return 0;
-}
-
-INT	Show_TxPreamble_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	switch(pAd->CommonCfg.TxPreamble)
-	{
-		case Rt802_11PreambleShort:
-			sprintf(pBuf, "\tShort");
-			break;
-		case Rt802_11PreambleLong:
-			sprintf(pBuf, "\tLong");
-			break;
-		case Rt802_11PreambleAuto:
-			sprintf(pBuf, "\tAuto");
-			break;
-		default:
-			sprintf(pBuf, "\tUnknow Value(%lu)", pAd->CommonCfg.TxPreamble);
-			break;
-	}
-
-	return 0;
-}
-
-INT	Show_TxPower_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	sprintf(pBuf, "\t%lu", pAd->CommonCfg.TxPowerPercentage);
-	return 0;
-}
-
-INT	Show_Channel_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	sprintf(pBuf, "\t%d", pAd->CommonCfg.Channel);
-	return 0;
-}
-
-INT	Show_BGProtection_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	switch(pAd->CommonCfg.UseBGProtection)
-	{
-		case 1: //Always On
-			sprintf(pBuf, "\tON");
-			break;
-		case 2: //Always OFF
-			sprintf(pBuf, "\tOFF");
-			break;
-		case 0: //AUTO
-			sprintf(pBuf, "\tAuto");
-			break;
-		default:
-			sprintf(pBuf, "\tUnknow Value(%lu)", pAd->CommonCfg.UseBGProtection);
-			break;
-	}
-	return 0;
-}
-
-INT	Show_RTSThreshold_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	sprintf(pBuf, "\t%u", pAd->CommonCfg.RtsThreshold);
-	return 0;
-}
-
-INT	Show_FragThreshold_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	sprintf(pBuf, "\t%u", pAd->CommonCfg.FragmentThreshold);
-	return 0;
-}
-
-INT	Show_HtBw_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
-	{
-		sprintf(pBuf, "\t40 MHz");
-	}
-	else
-	{
-        sprintf(pBuf, "\t20 MHz");
-	}
-	return 0;
-}
-
-INT	Show_HtMcs_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	sprintf(pBuf, "\t%u", pAd->StaCfg.DesiredTransmitSetting.field.MCS);
-	return 0;
-}
-
-INT	Show_HtGi_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	switch(pAd->CommonCfg.RegTransmitSetting.field.ShortGI)
-	{
-		case GI_400:
-			sprintf(pBuf, "\tGI_400");
-			break;
-		case GI_800:
-			sprintf(pBuf, "\tGI_800");
-			break;
-		default:
-			sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.ShortGI);
-			break;
-	}
-	return 0;
-}
-
-INT	Show_HtOpMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	switch(pAd->CommonCfg.RegTransmitSetting.field.HTMODE)
-	{
-		case HTMODE_GF:
-			sprintf(pBuf, "\tGF");
-			break;
-		case HTMODE_MM:
-			sprintf(pBuf, "\tMM");
-			break;
-		default:
-			sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.HTMODE);
-			break;
-	}
-	return 0;
-}
-
-INT	Show_HtExtcha_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	switch(pAd->CommonCfg.RegTransmitSetting.field.EXTCHA)
-	{
-		case EXTCHA_BELOW:
-			sprintf(pBuf, "\tBelow");
-			break;
-		case EXTCHA_ABOVE:
-			sprintf(pBuf, "\tAbove");
-			break;
-		default:
-			sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.EXTCHA);
-			break;
-	}
-	return 0;
-}
-
-
-INT	Show_HtMpduDensity_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.MpduDensity);
-	return 0;
-}
-
-INT	Show_HtBaWinSize_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.RxBAWinLimit);
-	return 0;
-}
-
-INT	Show_HtRdg_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	sprintf(pBuf, "\t%s", pAd->CommonCfg.bRdg ? "TRUE":"FALSE");
-	return 0;
-}
-
-INT	Show_HtAmsdu_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AmsduEnable ? "TRUE":"FALSE");
-	return 0;
-}
-
-INT	Show_HtAutoBa_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AutoBA ? "TRUE":"FALSE");
-	return 0;
-}
-
-INT	Show_CountryRegion_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegion);
-	return 0;
-}
-
-INT	Show_CountryRegionABand_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegionForABand);
-	return 0;
-}
-
-INT	Show_CountryCode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	sprintf(pBuf, "\t%s", pAd->CommonCfg.CountryCode);
-	return 0;
-}
-
-#ifdef AGGREGATION_SUPPORT
-INT	Show_PktAggregate_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	sprintf(pBuf, "\t%s", pAd->CommonCfg.bAggregationCapable ? "TRUE":"FALSE");
-	return 0;
-}
-#endif // AGGREGATION_SUPPORT //
-
-#ifdef WMM_SUPPORT
-INT	Show_WmmCapable_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	sprintf(pBuf, "\t%s", pAd->CommonCfg.bWmmCapable ? "TRUE":"FALSE");
-
-	return 0;
-}
-#endif // WMM_SUPPORT //
-
-INT	Show_IEEE80211H_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	sprintf(pBuf, "\t%s", pAd->CommonCfg.bIEEE80211H ? "TRUE":"FALSE");
-	return 0;
-}
-
-INT	Show_NetworkType_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	switch(pAd->StaCfg.BssType)
-	{
-		case BSS_ADHOC:
-			sprintf(pBuf, "\tAdhoc");
-			break;
-		case BSS_INFRA:
-			sprintf(pBuf, "\tInfra");
-			break;
-		case BSS_ANY:
-			sprintf(pBuf, "\tAny");
-			break;
-		case BSS_MONITOR:
-			sprintf(pBuf, "\tMonitor");
-			break;
-		default:
-			sprintf(pBuf, "\tUnknow Value(%d)", pAd->StaCfg.BssType);
-			break;
-	}
-	return 0;
-}
-
-INT	Show_AuthMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	NDIS_802_11_AUTHENTICATION_MODE	AuthMode = Ndis802_11AuthModeOpen;
-
-	AuthMode = pAd->StaCfg.AuthMode;
-
-	if ((AuthMode >= Ndis802_11AuthModeOpen) &&
-		(AuthMode <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
-		sprintf(pBuf, "\t%s", RTMPGetRalinkAuthModeStr(AuthMode));
-	else
-		sprintf(pBuf, "\tUnknow Value(%d)", AuthMode);
-
-	return 0;
-}
-
-INT	Show_EncrypType_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	NDIS_802_11_WEP_STATUS	WepStatus = Ndis802_11WEPDisabled;
-
-	WepStatus = pAd->StaCfg.WepStatus;
-
-	if ((WepStatus >= Ndis802_11WEPEnabled) &&
-		(WepStatus <= Ndis802_11Encryption4KeyAbsent))
-		sprintf(pBuf, "\t%s", RTMPGetRalinkEncryModeStr(WepStatus));
-	else
-		sprintf(pBuf, "\tUnknow Value(%d)", WepStatus);
-
-	return 0;
-}
-
-INT	Show_DefaultKeyID_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	UCHAR DefaultKeyId = 0;
-
-	DefaultKeyId = pAd->StaCfg.DefaultKeyId;
-
-	sprintf(pBuf, "\t%d", DefaultKeyId);
-
-	return 0;
-}
-
-INT	Show_WepKey_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN  INT				KeyIdx,
-	OUT	PUCHAR			pBuf)
-{
-	UCHAR   Key[16] = {0}, KeyLength = 0;
-	INT		index = BSS0;
-
-	KeyLength = pAd->SharedKey[index][KeyIdx].KeyLen;
-	NdisMoveMemory(Key, pAd->SharedKey[index][KeyIdx].Key, KeyLength);
-
-	//check key string is ASCII or not
-    if (RTMPCheckStrPrintAble(Key, KeyLength))
-        sprintf(pBuf, "\t%s", Key);
-    else
-    {
-        int idx;
-        sprintf(pBuf, "\t");
-        for (idx = 0; idx < KeyLength; idx++)
-            sprintf(pBuf+strlen(pBuf), "%02X", Key[idx]);
-    }
-	return 0;
-}
-
-INT	Show_Key1_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	Show_WepKey_Proc(pAd, 0, pBuf);
-	return 0;
-}
-
-INT	Show_Key2_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	Show_WepKey_Proc(pAd, 1, pBuf);
-	return 0;
-}
-
-INT	Show_Key3_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	Show_WepKey_Proc(pAd, 2, pBuf);
-	return 0;
-}
-
-INT	Show_Key4_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	Show_WepKey_Proc(pAd, 3, pBuf);
-	return 0;
-}
-
-INT	Show_WPAPSK_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
-{
-	INT 	idx;
-	UCHAR	PMK[32] = {0};
-
-	NdisMoveMemory(PMK, pAd->StaCfg.PMK, 32);
-
-    sprintf(pBuf, "\tPMK = ");
-    for (idx = 0; idx < 32; idx++)
-        sprintf(pBuf+strlen(pBuf), "%02X", PMK[idx]);
-
-	return 0;
-}
-
diff --git a/drivers/staging/rt2860/common/cmm_mac_pci.c b/drivers/staging/rt2860/common/cmm_mac_pci.c
new file mode 100644
index 0000000..560ebd3
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_mac_pci.c
@@ -0,0 +1,1661 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+*/
+
+#ifdef RTMP_MAC_PCI
+#include	"../rt_config.h"
+
+/*
+	========================================================================
+
+	Routine Description:
+		Allocate DMA memory blocks for send, receive
+
+	Arguments:
+		Adapter		Pointer to our adapter
+
+	Return Value:
+		NDIS_STATUS_SUCCESS
+		NDIS_STATUS_FAILURE
+		NDIS_STATUS_RESOURCES
+
+	IRQL = PASSIVE_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+int RTMPAllocTxRxRingMemory(struct rt_rtmp_adapter *pAd)
+{
+	int Status = NDIS_STATUS_SUCCESS;
+	unsigned long RingBasePaHigh;
+	unsigned long RingBasePaLow;
+	void *RingBaseVa;
+	int index, num;
+	struct rt_txd * pTxD;
+	struct rt_rxd * pRxD;
+	unsigned long ErrorValue = 0;
+	struct rt_rtmp_tx_ring *pTxRing;
+	struct rt_rtmp_dmabuf *pDmaBuf;
+	void *pPacket;
+/*      PRTMP_REORDERBUF        pReorderBuf; */
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
+	do {
+		/* */
+		/* Allocate all ring descriptors, include TxD, RxD, MgmtD. */
+		/* Although each size is different, to prevent cacheline and alignment */
+		/* issue, I intentional set them all to 64 bytes. */
+		/* */
+		for (num = 0; num < NUM_OF_TX_RING; num++) {
+			unsigned long BufBasePaHigh;
+			unsigned long BufBasePaLow;
+			void *BufBaseVa;
+
+			/* */
+			/* Allocate Tx ring descriptor's memory (5 TX rings = 4 ACs + 1 HCCA) */
+			/* */
+			pAd->TxDescRing[num].AllocSize =
+			    TX_RING_SIZE * TXD_SIZE;
+			RTMP_AllocateTxDescMemory(pAd, num,
+						  pAd->TxDescRing[num].
+						  AllocSize, FALSE,
+						  &pAd->TxDescRing[num].AllocVa,
+						  &pAd->TxDescRing[num].
+						  AllocPa);
+
+			if (pAd->TxDescRing[num].AllocVa == NULL) {
+				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
+				DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
+				Status = NDIS_STATUS_RESOURCES;
+				break;
+			}
+			/* Zero init this memory block */
+			NdisZeroMemory(pAd->TxDescRing[num].AllocVa,
+				       pAd->TxDescRing[num].AllocSize);
+
+			/* Save PA & VA for further operation */
+			RingBasePaHigh =
+			    RTMP_GetPhysicalAddressHigh(pAd->TxDescRing[num].
+							AllocPa);
+			RingBasePaLow =
+			    RTMP_GetPhysicalAddressLow(pAd->TxDescRing[num].
+						       AllocPa);
+			RingBaseVa = pAd->TxDescRing[num].AllocVa;
+
+			/* */
+			/* Allocate all 1st TXBuf's memory for this TxRing */
+			/* */
+			pAd->TxBufSpace[num].AllocSize =
+			    TX_RING_SIZE * TX_DMA_1ST_BUFFER_SIZE;
+			RTMP_AllocateFirstTxBuffer(pAd, num,
+						   pAd->TxBufSpace[num].
+						   AllocSize, FALSE,
+						   &pAd->TxBufSpace[num].
+						   AllocVa,
+						   &pAd->TxBufSpace[num].
+						   AllocPa);
+
+			if (pAd->TxBufSpace[num].AllocVa == NULL) {
+				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
+				DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
+				Status = NDIS_STATUS_RESOURCES;
+				break;
+			}
+			/* Zero init this memory block */
+			NdisZeroMemory(pAd->TxBufSpace[num].AllocVa,
+				       pAd->TxBufSpace[num].AllocSize);
+
+			/* Save PA & VA for further operation */
+			BufBasePaHigh =
+			    RTMP_GetPhysicalAddressHigh(pAd->TxBufSpace[num].
+							AllocPa);
+			BufBasePaLow =
+			    RTMP_GetPhysicalAddressLow(pAd->TxBufSpace[num].
+						       AllocPa);
+			BufBaseVa = pAd->TxBufSpace[num].AllocVa;
+
+			/* */
+			/* Initialize Tx Ring Descriptor and associated buffer memory */
+			/* */
+			pTxRing = &pAd->TxRing[num];
+			for (index = 0; index < TX_RING_SIZE; index++) {
+				pTxRing->Cell[index].pNdisPacket = NULL;
+				pTxRing->Cell[index].pNextNdisPacket = NULL;
+				/* Init Tx Ring Size, Va, Pa variables */
+				pTxRing->Cell[index].AllocSize = TXD_SIZE;
+				pTxRing->Cell[index].AllocVa = RingBaseVa;
+				RTMP_SetPhysicalAddressHigh(pTxRing->
+							    Cell[index].AllocPa,
+							    RingBasePaHigh);
+				RTMP_SetPhysicalAddressLow(pTxRing->Cell[index].
+							   AllocPa,
+							   RingBasePaLow);
+
+				/* Setup Tx Buffer size & address. only 802.11 header will store in this space */
+				pDmaBuf = &pTxRing->Cell[index].DmaBuf;
+				pDmaBuf->AllocSize = TX_DMA_1ST_BUFFER_SIZE;
+				pDmaBuf->AllocVa = BufBaseVa;
+				RTMP_SetPhysicalAddressHigh(pDmaBuf->AllocPa,
+							    BufBasePaHigh);
+				RTMP_SetPhysicalAddressLow(pDmaBuf->AllocPa,
+							   BufBasePaLow);
+
+				/* link the pre-allocated TxBuf to TXD */
+				pTxD =
+				    (struct rt_txd *) pTxRing->Cell[index].AllocVa;
+				pTxD->SDPtr0 = BufBasePaLow;
+				/* advance to next ring descriptor address */
+				pTxD->DMADONE = 1;
+				RingBasePaLow += TXD_SIZE;
+				RingBaseVa = (u8 *)RingBaseVa + TXD_SIZE;
+
+				/* advance to next TxBuf address */
+				BufBasePaLow += TX_DMA_1ST_BUFFER_SIZE;
+				BufBaseVa =
+				    (u8 *)BufBaseVa + TX_DMA_1ST_BUFFER_SIZE;
+			}
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("TxRing[%d]: total %d entry allocated\n", num,
+				  index));
+		}
+		if (Status == NDIS_STATUS_RESOURCES)
+			break;
+
+		/* */
+		/* Allocate MGMT ring descriptor's memory except Tx ring which allocated eariler */
+		/* */
+		pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * TXD_SIZE;
+		RTMP_AllocateMgmtDescMemory(pAd,
+					    pAd->MgmtDescRing.AllocSize,
+					    FALSE,
+					    &pAd->MgmtDescRing.AllocVa,
+					    &pAd->MgmtDescRing.AllocPa);
+
+		if (pAd->MgmtDescRing.AllocVa == NULL) {
+			ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
+			DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
+			Status = NDIS_STATUS_RESOURCES;
+			break;
+		}
+		/* Zero init this memory block */
+		NdisZeroMemory(pAd->MgmtDescRing.AllocVa,
+			       pAd->MgmtDescRing.AllocSize);
+
+		/* Save PA & VA for further operation */
+		RingBasePaHigh =
+		    RTMP_GetPhysicalAddressHigh(pAd->MgmtDescRing.AllocPa);
+		RingBasePaLow =
+		    RTMP_GetPhysicalAddressLow(pAd->MgmtDescRing.AllocPa);
+		RingBaseVa = pAd->MgmtDescRing.AllocVa;
+
+		/* */
+		/* Initialize MGMT Ring and associated buffer memory */
+		/* */
+		for (index = 0; index < MGMT_RING_SIZE; index++) {
+			pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
+			pAd->MgmtRing.Cell[index].pNextNdisPacket = NULL;
+			/* Init MGMT Ring Size, Va, Pa variables */
+			pAd->MgmtRing.Cell[index].AllocSize = TXD_SIZE;
+			pAd->MgmtRing.Cell[index].AllocVa = RingBaseVa;
+			RTMP_SetPhysicalAddressHigh(pAd->MgmtRing.Cell[index].
+						    AllocPa, RingBasePaHigh);
+			RTMP_SetPhysicalAddressLow(pAd->MgmtRing.Cell[index].
+						   AllocPa, RingBasePaLow);
+
+			/* Offset to next ring descriptor address */
+			RingBasePaLow += TXD_SIZE;
+			RingBaseVa = (u8 *)RingBaseVa + TXD_SIZE;
+
+			/* link the pre-allocated TxBuf to TXD */
+			pTxD = (struct rt_txd *) pAd->MgmtRing.Cell[index].AllocVa;
+			pTxD->DMADONE = 1;
+
+			/* no pre-allocated buffer required in MgmtRing for scatter-gather case */
+		}
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("MGMT Ring: total %d entry allocated\n", index));
+
+		/* */
+		/* Allocate RX ring descriptor's memory except Tx ring which allocated eariler */
+		/* */
+		pAd->RxDescRing.AllocSize = RX_RING_SIZE * RXD_SIZE;
+		RTMP_AllocateRxDescMemory(pAd,
+					  pAd->RxDescRing.AllocSize,
+					  FALSE,
+					  &pAd->RxDescRing.AllocVa,
+					  &pAd->RxDescRing.AllocPa);
+
+		if (pAd->RxDescRing.AllocVa == NULL) {
+			ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
+			DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
+			Status = NDIS_STATUS_RESOURCES;
+			break;
+		}
+		/* Zero init this memory block */
+		NdisZeroMemory(pAd->RxDescRing.AllocVa,
+			       pAd->RxDescRing.AllocSize);
+
+		DBGPRINT(RT_DEBUG_OFF,
+			 ("RX DESC %p  size = %ld\n", pAd->RxDescRing.AllocVa,
+			  pAd->RxDescRing.AllocSize));
+
+		/* Save PA & VA for further operation */
+		RingBasePaHigh =
+		    RTMP_GetPhysicalAddressHigh(pAd->RxDescRing.AllocPa);
+		RingBasePaLow =
+		    RTMP_GetPhysicalAddressLow(pAd->RxDescRing.AllocPa);
+		RingBaseVa = pAd->RxDescRing.AllocVa;
+
+		/* */
+		/* Initialize Rx Ring and associated buffer memory */
+		/* */
+		for (index = 0; index < RX_RING_SIZE; index++) {
+			/* Init RX Ring Size, Va, Pa variables */
+			pAd->RxRing.Cell[index].AllocSize = RXD_SIZE;
+			pAd->RxRing.Cell[index].AllocVa = RingBaseVa;
+			RTMP_SetPhysicalAddressHigh(pAd->RxRing.Cell[index].
+						    AllocPa, RingBasePaHigh);
+			RTMP_SetPhysicalAddressLow(pAd->RxRing.Cell[index].
+						   AllocPa, RingBasePaLow);
+
+			/*NdisZeroMemory(RingBaseVa, RXD_SIZE); */
+
+			/* Offset to next ring descriptor address */
+			RingBasePaLow += RXD_SIZE;
+			RingBaseVa = (u8 *)RingBaseVa + RXD_SIZE;
+
+			/* Setup Rx associated Buffer size & allocate share memory */
+			pDmaBuf = &pAd->RxRing.Cell[index].DmaBuf;
+			pDmaBuf->AllocSize = RX_BUFFER_AGGRESIZE;
+			pPacket = RTMP_AllocateRxPacketBuffer(pAd,
+							      pDmaBuf->
+							      AllocSize, FALSE,
+							      &pDmaBuf->AllocVa,
+							      &pDmaBuf->
+							      AllocPa);
+
+			/* keep allocated rx packet */
+			pAd->RxRing.Cell[index].pNdisPacket = pPacket;
+
+			/* Error handling */
+			if (pDmaBuf->AllocVa == NULL) {
+				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
+				DBGPRINT_ERR(("Failed to allocate RxRing's 1st buffer\n"));
+				Status = NDIS_STATUS_RESOURCES;
+				break;
+			}
+			/* Zero init this memory block */
+			NdisZeroMemory(pDmaBuf->AllocVa, pDmaBuf->AllocSize);
+
+			/* Write RxD buffer address & allocated buffer length */
+			pRxD = (struct rt_rxd *) pAd->RxRing.Cell[index].AllocVa;
+			pRxD->SDP0 =
+			    RTMP_GetPhysicalAddressLow(pDmaBuf->AllocPa);
+			pRxD->DDONE = 0;
+
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Rx Ring: total %d entry allocated\n", index));
+
+	} while (FALSE);
+
+	NdisZeroMemory(&pAd->FragFrame, sizeof(struct rt_fragment_frame));
+	pAd->FragFrame.pFragPacket =
+	    RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
+
+	if (pAd->FragFrame.pFragPacket == NULL) {
+		Status = NDIS_STATUS_RESOURCES;
+	}
+
+	if (Status != NDIS_STATUS_SUCCESS) {
+		/* Log error inforamtion */
+		NdisWriteErrorLogEntry(pAd->AdapterHandle,
+				       NDIS_ERROR_CODE_OUT_OF_RESOURCES,
+				       1, ErrorValue);
+	}
+	/* Following code segment get from original func:NICInitTxRxRingAndBacklogQueue(), now should integrate it to here. */
+	{
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("--> NICInitTxRxRingAndBacklogQueue\n"));
+
+/*
+		// Disable DMA.
+		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
+		GloCfg.word &= 0xff0;
+		GloCfg.field.EnTXWriteBackDDONE =1;
+		RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
+*/
+
+		/* Initialize all transmit related software queues */
+		for (index = 0; index < NUM_OF_TX_RING; index++) {
+			InitializeQueueHeader(&pAd->TxSwQueue[index]);
+			/* Init TX rings index pointer */
+			pAd->TxRing[index].TxSwFreeIdx = 0;
+			pAd->TxRing[index].TxCpuIdx = 0;
+			/*RTMP_IO_WRITE32(pAd, (TX_CTX_IDX0 + i * 0x10) ,  pAd->TxRing[i].TX_CTX_IDX); */
+		}
+
+		/* Init RX Ring index pointer */
+		pAd->RxRing.RxSwReadIdx = 0;
+		pAd->RxRing.RxCpuIdx = RX_RING_SIZE - 1;
+		/*RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RX_CRX_IDX0); */
+
+		/* init MGMT ring index pointer */
+		pAd->MgmtRing.TxSwFreeIdx = 0;
+		pAd->MgmtRing.TxCpuIdx = 0;
+
+		pAd->PrivateInfo.TxRingFullCnt = 0;
+
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("<-- NICInitTxRxRingAndBacklogQueue\n"));
+	}
+
+	DBGPRINT_S(Status,
+		   ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
+	return Status;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Reset NIC Asics. Call after rest DMA. So reset TX_CTX_IDX to zero.
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+		Reset NIC to initial state AS IS system boot up time.
+
+	========================================================================
+*/
+void RTMPRingCleanUp(struct rt_rtmp_adapter *pAd, u8 RingType)
+{
+	struct rt_txd * pTxD;
+	struct rt_rxd * pRxD;
+	struct rt_queue_entry *pEntry;
+	void *pPacket;
+	int i;
+	struct rt_rtmp_tx_ring *pTxRing;
+	unsigned long IrqFlags;
+	/*u32                        RxSwReadIdx; */
+
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("RTMPRingCleanUp(RingIdx=%d, Pending-NDIS=%ld)\n", RingType,
+		  pAd->RalinkCounters.PendingNdisPacketCount));
+	switch (RingType) {
+	case QID_AC_BK:
+	case QID_AC_BE:
+	case QID_AC_VI:
+	case QID_AC_VO:
+
+		pTxRing = &pAd->TxRing[RingType];
+
+		RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+		/* We have to clean all descriptors in case some error happened with reset */
+		for (i = 0; i < TX_RING_SIZE; i++)	/* We have to scan all TX ring */
+		{
+			pTxD = (struct rt_txd *) pTxRing->Cell[i].AllocVa;
+
+			pPacket = (void *)pTxRing->Cell[i].pNdisPacket;
+			/* release scatter-and-gather char */
+			if (pPacket) {
+				RELEASE_NDIS_PACKET(pAd, pPacket,
+						    NDIS_STATUS_FAILURE);
+				pTxRing->Cell[i].pNdisPacket = NULL;
+			}
+
+			pPacket =
+			    (void *)pTxRing->Cell[i].pNextNdisPacket;
+			/* release scatter-and-gather char */
+			if (pPacket) {
+				RELEASE_NDIS_PACKET(pAd, pPacket,
+						    NDIS_STATUS_FAILURE);
+				pTxRing->Cell[i].pNextNdisPacket = NULL;
+			}
+		}
+
+		RTMP_IO_READ32(pAd, TX_DTX_IDX0 + RingType * 0x10,
+			       &pTxRing->TxDmaIdx);
+		pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx;
+		pTxRing->TxCpuIdx = pTxRing->TxDmaIdx;
+		RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + RingType * 0x10,
+				pTxRing->TxCpuIdx);
+
+		RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+
+		RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+		while (pAd->TxSwQueue[RingType].Head != NULL) {
+			pEntry = RemoveHeadQueue(&pAd->TxSwQueue[RingType]);
+			pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
+			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("Release 1 NDIS packet from s/w backlog queue\n"));
+		}
+		RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+		break;
+
+	case QID_MGMT:
+		/* We have to clean all descriptors in case some error happened with reset */
+		NdisAcquireSpinLock(&pAd->MgmtRingLock);
+
+		for (i = 0; i < MGMT_RING_SIZE; i++) {
+			pTxD = (struct rt_txd *) pAd->MgmtRing.Cell[i].AllocVa;
+
+			pPacket =
+			    (void *)pAd->MgmtRing.Cell[i].pNdisPacket;
+			/* rlease scatter-and-gather char */
+			if (pPacket) {
+				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0,
+						 pTxD->SDLen0,
+						 PCI_DMA_TODEVICE);
+				RELEASE_NDIS_PACKET(pAd, pPacket,
+						    NDIS_STATUS_FAILURE);
+			}
+			pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
+
+			pPacket =
+			    (void *)pAd->MgmtRing.Cell[i].
+			    pNextNdisPacket;
+			/* release scatter-and-gather char */
+			if (pPacket) {
+				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1,
+						 pTxD->SDLen1,
+						 PCI_DMA_TODEVICE);
+				RELEASE_NDIS_PACKET(pAd, pPacket,
+						    NDIS_STATUS_FAILURE);
+			}
+			pAd->MgmtRing.Cell[i].pNextNdisPacket = NULL;
+
+		}
+
+		RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pAd->MgmtRing.TxDmaIdx);
+		pAd->MgmtRing.TxSwFreeIdx = pAd->MgmtRing.TxDmaIdx;
+		pAd->MgmtRing.TxCpuIdx = pAd->MgmtRing.TxDmaIdx;
+		RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
+
+		NdisReleaseSpinLock(&pAd->MgmtRingLock);
+		pAd->RalinkCounters.MgmtRingFullCount = 0;
+		break;
+
+	case QID_RX:
+		/* We have to clean all descriptors in case some error happened with reset */
+		NdisAcquireSpinLock(&pAd->RxRingLock);
+
+		for (i = 0; i < RX_RING_SIZE; i++) {
+			pRxD = (struct rt_rxd *) pAd->RxRing.Cell[i].AllocVa;
+			pRxD->DDONE = 0;
+		}
+
+		RTMP_IO_READ32(pAd, RX_DRX_IDX, &pAd->RxRing.RxDmaIdx);
+		pAd->RxRing.RxSwReadIdx = pAd->RxRing.RxDmaIdx;
+		pAd->RxRing.RxCpuIdx =
+		    ((pAd->RxRing.RxDmaIdx ==
+		      0) ? (RX_RING_SIZE - 1) : (pAd->RxRing.RxDmaIdx - 1));
+		RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
+
+		NdisReleaseSpinLock(&pAd->RxRingLock);
+		break;
+
+	default:
+		break;
+	}
+}
+
+void RTMPFreeTxRxRingMemory(struct rt_rtmp_adapter *pAd)
+{
+	int index, num, j;
+	struct rt_rtmp_tx_ring *pTxRing;
+	struct rt_txd * pTxD;
+	void *pPacket;
+	unsigned int IrqFlags;
+
+	/*struct os_cookie *pObj =(struct os_cookie *)pAd->OS_Cookie; */
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPFreeTxRxRingMemory\n"));
+
+	/* Free TxSwQueue Packet */
+	for (index = 0; index < NUM_OF_TX_RING; index++) {
+		struct rt_queue_entry *pEntry;
+		void *pPacket;
+		struct rt_queue_header *pQueue;
+
+		RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+		pQueue = &pAd->TxSwQueue[index];
+		while (pQueue->Head) {
+			pEntry = RemoveHeadQueue(pQueue);
+			pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
+			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+		}
+		RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+	}
+
+	/* Free Tx Ring Packet */
+	for (index = 0; index < NUM_OF_TX_RING; index++) {
+		pTxRing = &pAd->TxRing[index];
+
+		for (j = 0; j < TX_RING_SIZE; j++) {
+			pTxD = (struct rt_txd *) (pTxRing->Cell[j].AllocVa);
+			pPacket = pTxRing->Cell[j].pNdisPacket;
+
+			if (pPacket) {
+				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0,
+						 pTxD->SDLen0,
+						 PCI_DMA_TODEVICE);
+				RELEASE_NDIS_PACKET(pAd, pPacket,
+						    NDIS_STATUS_SUCCESS);
+			}
+			/*Always assign pNdisPacket as NULL after clear */
+			pTxRing->Cell[j].pNdisPacket = NULL;
+
+			pPacket = pTxRing->Cell[j].pNextNdisPacket;
+
+			if (pPacket) {
+				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1,
+						 pTxD->SDLen1,
+						 PCI_DMA_TODEVICE);
+				RELEASE_NDIS_PACKET(pAd, pPacket,
+						    NDIS_STATUS_SUCCESS);
+			}
+			/*Always assign pNextNdisPacket as NULL after clear */
+			pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket =
+			    NULL;
+
+		}
+	}
+
+	for (index = RX_RING_SIZE - 1; index >= 0; index--) {
+		if ((pAd->RxRing.Cell[index].DmaBuf.AllocVa)
+		    && (pAd->RxRing.Cell[index].pNdisPacket)) {
+			PCI_UNMAP_SINGLE(pAd,
+					 pAd->RxRing.Cell[index].DmaBuf.AllocPa,
+					 pAd->RxRing.Cell[index].DmaBuf.
+					 AllocSize, PCI_DMA_FROMDEVICE);
+			RELEASE_NDIS_PACKET(pAd,
+					    pAd->RxRing.Cell[index].pNdisPacket,
+					    NDIS_STATUS_SUCCESS);
+		}
+	}
+	NdisZeroMemory(pAd->RxRing.Cell, RX_RING_SIZE * sizeof(struct rt_rtmp_dmacb));
+
+	if (pAd->RxDescRing.AllocVa) {
+		RTMP_FreeDescMemory(pAd, pAd->RxDescRing.AllocSize,
+				    pAd->RxDescRing.AllocVa,
+				    pAd->RxDescRing.AllocPa);
+	}
+	NdisZeroMemory(&pAd->RxDescRing, sizeof(struct rt_rtmp_dmabuf));
+
+	if (pAd->MgmtDescRing.AllocVa) {
+		RTMP_FreeDescMemory(pAd, pAd->MgmtDescRing.AllocSize,
+				    pAd->MgmtDescRing.AllocVa,
+				    pAd->MgmtDescRing.AllocPa);
+	}
+	NdisZeroMemory(&pAd->MgmtDescRing, sizeof(struct rt_rtmp_dmabuf));
+
+	for (num = 0; num < NUM_OF_TX_RING; num++) {
+		if (pAd->TxBufSpace[num].AllocVa) {
+			RTMP_FreeFirstTxBuffer(pAd,
+					       pAd->TxBufSpace[num].AllocSize,
+					       FALSE,
+					       pAd->TxBufSpace[num].AllocVa,
+					       pAd->TxBufSpace[num].AllocPa);
+		}
+		NdisZeroMemory(&pAd->TxBufSpace[num], sizeof(struct rt_rtmp_dmabuf));
+
+		if (pAd->TxDescRing[num].AllocVa) {
+			RTMP_FreeDescMemory(pAd, pAd->TxDescRing[num].AllocSize,
+					    pAd->TxDescRing[num].AllocVa,
+					    pAd->TxDescRing[num].AllocPa);
+		}
+		NdisZeroMemory(&pAd->TxDescRing[num], sizeof(struct rt_rtmp_dmabuf));
+	}
+
+	if (pAd->FragFrame.pFragPacket)
+		RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket,
+				    NDIS_STATUS_SUCCESS);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<-- RTMPFreeTxRxRingMemory\n"));
+}
+
+/***************************************************************************
+  *
+  *	register related procedures.
+  *
+  **************************************************************************/
+/*
+========================================================================
+Routine Description:
+    Disable DMA.
+
+Arguments:
+	*pAd				the raxx interface data pointer
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+void RT28XXDMADisable(struct rt_rtmp_adapter *pAd)
+{
+	WPDMA_GLO_CFG_STRUC GloCfg;
+
+	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
+	GloCfg.word &= 0xff0;
+	GloCfg.field.EnTXWriteBackDDONE = 1;
+	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
+}
+
+/*
+========================================================================
+Routine Description:
+    Enable DMA.
+
+Arguments:
+	*pAd				the raxx interface data pointer
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+void RT28XXDMAEnable(struct rt_rtmp_adapter *pAd)
+{
+	WPDMA_GLO_CFG_STRUC GloCfg;
+	int i = 0;
+
+	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
+	do {
+		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
+		if ((GloCfg.field.TxDMABusy == 0)
+		    && (GloCfg.field.RxDMABusy == 0))
+			break;
+
+		DBGPRINT(RT_DEBUG_TRACE, ("==>  DMABusy\n"));
+		RTMPusecDelay(1000);
+		i++;
+	} while (i < 200);
+
+	RTMPusecDelay(50);
+
+	GloCfg.field.EnTXWriteBackDDONE = 1;
+	GloCfg.field.WPDMABurstSIZE = 2;
+	GloCfg.field.EnableRxDMA = 1;
+	GloCfg.field.EnableTxDMA = 1;
+
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
+	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
+
+}
+
+BOOLEAN AsicCheckCommanOk(struct rt_rtmp_adapter *pAd, u8 Command)
+{
+	u32 CmdStatus = 0, CID = 0, i;
+	u32 ThisCIDMask = 0;
+
+	i = 0;
+	do {
+		RTMP_IO_READ32(pAd, H2M_MAILBOX_CID, &CID);
+		/* Find where the command is. Because this is randomly specified by firmware. */
+		if ((CID & CID0MASK) == Command) {
+			ThisCIDMask = CID0MASK;
+			break;
+		} else if ((((CID & CID1MASK) >> 8) & 0xff) == Command) {
+			ThisCIDMask = CID1MASK;
+			break;
+		} else if ((((CID & CID2MASK) >> 16) & 0xff) == Command) {
+			ThisCIDMask = CID2MASK;
+			break;
+		} else if ((((CID & CID3MASK) >> 24) & 0xff) == Command) {
+			ThisCIDMask = CID3MASK;
+			break;
+		}
+
+		RTMPusecDelay(100);
+		i++;
+	} while (i < 200);
+
+	/* Get CommandStatus Value */
+	RTMP_IO_READ32(pAd, H2M_MAILBOX_STATUS, &CmdStatus);
+
+	/* This command's status is at the same position as command. So AND command position's bitmask to read status. */
+	if (i < 200) {
+		/* If Status is 1, the comamnd is success. */
+		if (((CmdStatus & ThisCIDMask) == 0x1)
+		    || ((CmdStatus & ThisCIDMask) == 0x100)
+		    || ((CmdStatus & ThisCIDMask) == 0x10000)
+		    || ((CmdStatus & ThisCIDMask) == 0x1000000)) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("--> AsicCheckCommanOk CID = 0x%x, CmdStatus= 0x%x \n",
+				  CID, CmdStatus));
+			RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
+			RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
+			return TRUE;
+		}
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("--> AsicCheckCommanFail1 CID = 0x%x, CmdStatus= 0x%x \n",
+			  CID, CmdStatus));
+	} else {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("--> AsicCheckCommanFail2 Timeout Command = %d, CmdStatus= 0x%x \n",
+			  Command, CmdStatus));
+	}
+	/* Clear Command and Status. */
+	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
+	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
+
+	return FALSE;
+}
+
+/*
+========================================================================
+Routine Description:
+    Write Beacon buffer to Asic.
+
+Arguments:
+	*pAd				the raxx interface data pointer
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+void RT28xx_UpdateBeaconToAsic(struct rt_rtmp_adapter *pAd,
+			       int apidx,
+			       unsigned long FrameLen, unsigned long UpdatePos)
+{
+	unsigned long CapInfoPos = 0;
+	u8 *ptr, *ptr_update, *ptr_capinfo;
+	u32 i;
+	BOOLEAN bBcnReq = FALSE;
+	u8 bcn_idx = 0;
+
+	{
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("%s() : No valid Interface be found.\n", __func__));
+		return;
+	}
+
+	/*if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) */
+	/*      || ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) */
+	/*              || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP)) */
+	/*      ) */
+	if (bBcnReq == FALSE) {
+		/* when the ra interface is down, do not send its beacon frame */
+		/* clear all zero */
+		for (i = 0; i < TXWI_SIZE; i += 4)
+			RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i,
+					0x00);
+	} else {
+		ptr = (u8 *)& pAd->BeaconTxWI;
+		for (i = 0; i < TXWI_SIZE; i += 4)	/* 16-byte TXWI field */
+		{
+			u32 longptr =
+			    *ptr + (*(ptr + 1) << 8) + (*(ptr + 2) << 16) +
+			    (*(ptr + 3) << 24);
+			RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i,
+					longptr);
+			ptr += 4;
+		}
+
+		/* Update CapabilityInfo in Beacon */
+		for (i = CapInfoPos; i < (CapInfoPos + 2); i++) {
+			RTMP_IO_WRITE8(pAd,
+				       pAd->BeaconOffset[bcn_idx] + TXWI_SIZE +
+				       i, *ptr_capinfo);
+			ptr_capinfo++;
+		}
+
+		if (FrameLen > UpdatePos) {
+			for (i = UpdatePos; i < (FrameLen); i++) {
+				RTMP_IO_WRITE8(pAd,
+					       pAd->BeaconOffset[bcn_idx] +
+					       TXWI_SIZE + i, *ptr_update);
+				ptr_update++;
+			}
+		}
+
+	}
+
+}
+
+void RT28xxPciStaAsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx)
+{
+	AUTO_WAKEUP_STRUC AutoWakeupCfg;
+
+	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+		return;
+
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW)) {
+		DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n"));
+		return;
+	}
+
+	OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
+
+	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
+
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
+	    && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) {
+		/* Support PCIe Advance Power Save */
+		if (bFromTx == TRUE && (pAd->Mlme.bPsPollTimerRunning == TRUE)) {
+			pAd->Mlme.bPsPollTimerRunning = FALSE;
+			RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
+			RTMPusecDelay(3000);
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("=======AsicForceWakeup===bFromTx\n"));
+		}
+
+		AutoWakeupCfg.word = 0;
+		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+
+		if (RT28xxPciAsicRadioOn(pAd, DOT11POWERSAVE)) {
+#ifdef PCIE_PS_SUPPORT
+			/* add by johnli, RF power sequence setup, load RF normal operation-mode setup */
+			if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
+			    && IS_VERSION_AFTER_F(pAd)) {
+				struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
+
+				if (pChipOps->AsicReverseRfFromSleepMode)
+					pChipOps->
+					    AsicReverseRfFromSleepMode(pAd);
+			} else
+#endif /* PCIE_PS_SUPPORT // */
+			{
+				/* end johnli */
+				/* In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. */
+				if (INFRA_ON(pAd)
+				    && (pAd->CommonCfg.CentralChannel !=
+					pAd->CommonCfg.Channel)
+				    && (pAd->MlmeAux.HtCapability.HtCapInfo.
+					ChannelWidth == BW_40)) {
+					/* Must using 40MHz. */
+					AsicSwitchChannel(pAd,
+							  pAd->CommonCfg.
+							  CentralChannel,
+							  FALSE);
+					AsicLockChannel(pAd,
+							pAd->CommonCfg.
+							CentralChannel);
+				} else {
+					/* Must using 20MHz. */
+					AsicSwitchChannel(pAd,
+							  pAd->CommonCfg.
+							  Channel, FALSE);
+					AsicLockChannel(pAd,
+							pAd->CommonCfg.Channel);
+				}
+			}
+		}
+#ifdef PCIE_PS_SUPPORT
+		/* 3090 MCU Wakeup command needs more time to be stable. */
+		/* Before stable, don't issue other MCU command to prevent from firmware error. */
+		if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
+		     && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
+		    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
+		    && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("<==RT28xxPciStaAsicForceWakeup::Release the MCU Lock(3090)\n"));
+			RTMP_SEM_LOCK(&pAd->McuCmdLock);
+			pAd->brt30xxBanMcuCmd = FALSE;
+			RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
+		}
+#endif /* PCIE_PS_SUPPORT // */
+	} else {
+		/* PCI, 2860-PCIe */
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("<==RT28xxPciStaAsicForceWakeup::Original PCI Power Saving\n"));
+		AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
+		AutoWakeupCfg.word = 0;
+		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+	}
+
+	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
+	DBGPRINT(RT_DEBUG_TRACE, ("<=======RT28xxPciStaAsicForceWakeup\n"));
+}
+
+void RT28xxPciStaAsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd,
+					 u16 TbttNumToNextWakeUp)
+{
+	BOOLEAN brc;
+
+	if (pAd->StaCfg.bRadio == FALSE) {
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+		return;
+	}
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
+	    && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) {
+		unsigned long Now = 0;
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW)) {
+			DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n"));
+			OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+			return;
+		}
+
+		NdisGetSystemUpTime(&Now);
+		/* If last send NULL fram time is too close to this receiving beacon (within 8ms), don't go to sleep for this DTM. */
+		/* Because Some AP can't queuing outgoing frames immediately. */
+		if (((pAd->Mlme.LastSendNULLpsmTime + 8) >= Now)
+		    && (pAd->Mlme.LastSendNULLpsmTime <= Now)) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("Now = %lu, LastSendNULLpsmTime=%lu :  RxCountSinceLastNULL = %lu. \n",
+				  Now, pAd->Mlme.LastSendNULLpsmTime,
+				  pAd->RalinkCounters.RxCountSinceLastNULL));
+			return;
+		} else if ((pAd->RalinkCounters.RxCountSinceLastNULL > 0)
+			   &&
+			   ((pAd->Mlme.LastSendNULLpsmTime +
+			     pAd->CommonCfg.BeaconPeriod) >= Now)) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("Now = %lu, LastSendNULLpsmTime=%lu: RxCountSinceLastNULL = %lu > 0 \n",
+				  Now, pAd->Mlme.LastSendNULLpsmTime,
+				  pAd->RalinkCounters.RxCountSinceLastNULL));
+			return;
+		}
+
+		brc =
+		    RT28xxPciAsicRadioOff(pAd, DOT11POWERSAVE,
+					  TbttNumToNextWakeUp);
+		if (brc == TRUE)
+			OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
+	} else {
+		AUTO_WAKEUP_STRUC AutoWakeupCfg;
+		/* we have decided to SLEEP, so at least do it for a BEACON period. */
+		if (TbttNumToNextWakeUp == 0)
+			TbttNumToNextWakeUp = 1;
+
+		/*RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt); */
+
+		AutoWakeupCfg.word = 0;
+		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+		AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
+		AutoWakeupCfg.field.EnableAutoWakeup = 1;
+		AutoWakeupCfg.field.AutoLeadTime = 5;
+		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+		AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x00);	/* send POWER-SAVE command to MCU. Timeout 40us. */
+		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("<-- %s, TbttNumToNextWakeUp=%d \n", __func__,
+			  TbttNumToNextWakeUp));
+	}
+
+}
+
+void PsPollWakeExec(void *SystemSpecific1,
+		    void *FunctionContext,
+		    void *SystemSpecific2, void *SystemSpecific3)
+{
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
+	unsigned long flags;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("-->PsPollWakeExec \n"));
+	RTMP_INT_LOCK(&pAd->irq_lock, flags);
+	if (pAd->Mlme.bPsPollTimerRunning) {
+		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
+	}
+	pAd->Mlme.bPsPollTimerRunning = FALSE;
+	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+#ifdef PCIE_PS_SUPPORT
+	/* For rt30xx power solution 3, Use software timer to wake up in psm. So call */
+	/* AsicForceWakeup here instead of handling twakeup interrupt. */
+	if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
+	     && IS_VERSION_AFTER_F(pAd))
+	    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
+	    && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("<--PsPollWakeExec::3090 calls AsicForceWakeup(pAd, DOT11POWERSAVE) in advance \n"));
+		AsicForceWakeup(pAd, DOT11POWERSAVE);
+	}
+#endif /* PCIE_PS_SUPPORT // */
+}
+
+void RadioOnExec(void *SystemSpecific1,
+		 void *FunctionContext,
+		 void *SystemSpecific2, void *SystemSpecific3)
+{
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
+	struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
+	WPDMA_GLO_CFG_STRUC DmaCfg;
+	BOOLEAN Cancelled;
+
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("-->RadioOnExec() return on fOP_STATUS_DOZE == TRUE; \n"));
+/*KH Debug: Add the compile flag "RT2860 and condition */
+#ifdef RTMP_PCI_SUPPORT
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
+		    && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
+			RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
+#endif /* RTMP_PCI_SUPPORT // */
+		return;
+	}
+
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("-->RadioOnExec() return on SCAN_IN_PROGRESS; \n"));
+#ifdef RTMP_PCI_SUPPORT
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
+		    && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
+			RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
+#endif /* RTMP_PCI_SUPPORT // */
+		return;
+	}
+/*KH Debug: need to check. I add the compile flag "CONFIG_STA_SUPPORT" to enclose the following codes. */
+#ifdef RTMP_PCI_SUPPORT
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
+	    && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) {
+		pAd->Mlme.bPsPollTimerRunning = FALSE;
+		RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
+	}
+#endif /* RTMP_PCI_SUPPORT // */
+	if (pAd->StaCfg.bRadio == TRUE) {
+		pAd->bPCIclkOff = FALSE;
+		RTMPRingCleanUp(pAd, QID_AC_BK);
+		RTMPRingCleanUp(pAd, QID_AC_BE);
+		RTMPRingCleanUp(pAd, QID_AC_VI);
+		RTMPRingCleanUp(pAd, QID_AC_VO);
+		RTMPRingCleanUp(pAd, QID_MGMT);
+		RTMPRingCleanUp(pAd, QID_RX);
+
+		/* 2. Send wake up command. */
+		AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02);
+		/* 2-1. wait command ok. */
+		AsicCheckCommanOk(pAd, PowerWakeCID);
+
+		/* When PCI clock is off, don't want to service interrupt. So when back to clock on, enable interrupt. */
+		/*RTMP_IO_WRITE32(pAd, INT_MASK_CSR, (DELAYINTMASK|RxINT)); */
+		RTMP_ASIC_INTERRUPT_ENABLE(pAd);
+
+		/* 3. Enable Tx DMA. */
+		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
+		DmaCfg.field.EnableTxDMA = 1;
+		RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
+
+		/* In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. */
+		if (INFRA_ON(pAd)
+		    && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
+		    && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth ==
+			BW_40)) {
+			/* Must using 40MHz. */
+			AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel,
+					  FALSE);
+			AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+		} else {
+			/* Must using 20MHz. */
+			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+		}
+
+/*KH Debug:The following codes should be enclosed by RT3090 compile flag */
+		if (pChipOps->AsicReverseRfFromSleepMode)
+			pChipOps->AsicReverseRfFromSleepMode(pAd);
+
+#ifdef PCIE_PS_SUPPORT
+/* 3090 MCU Wakeup command needs more time to be stable. */
+/* Before stable, don't issue other MCU command to prevent from firmware error. */
+		if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
+		    && IS_VERSION_AFTER_F(pAd)
+		    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
+		    && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
+			RTMP_SEM_LOCK(&pAd->McuCmdLock);
+			pAd->brt30xxBanMcuCmd = FALSE;
+			RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
+		}
+#endif /* PCIE_PS_SUPPORT // */
+
+		/* Clear Radio off flag */
+		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
+		/* Set LED */
+		RTMPSetLED(pAd, LED_RADIO_ON);
+
+		if (pAd->StaCfg.Psm == PWR_ACTIVE) {
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3,
+						     pAd->StaCfg.BBPR3);
+		}
+	} else {
+		RT28xxPciAsicRadioOff(pAd, GUIRADIO_OFF, 0);
+	}
+}
+
+/*
+	==========================================================================
+	Description:
+		This routine sends command to firmware and turn our chip to wake up mode from power save mode.
+		Both RadioOn and .11 power save function needs to call this routine.
+	Input:
+		Level = GUIRADIO_OFF : call this function is from Radio Off to Radio On.  Need to restore PCI host value.
+		Level = other value : normal wake up function.
+
+	==========================================================================
+ */
+BOOLEAN RT28xxPciAsicRadioOn(struct rt_rtmp_adapter *pAd, u8 Level)
+{
+	/*WPDMA_GLO_CFG_STRUC       DmaCfg; */
+	BOOLEAN Cancelled;
+	/*u32                        MACValue; */
+
+	if (pAd->OpMode == OPMODE_AP && Level == DOT11POWERSAVE)
+		return FALSE;
+
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
+		if (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) {
+			pAd->Mlme.bPsPollTimerRunning = FALSE;
+			RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
+		}
+		if ((pAd->StaCfg.PSControl.field.EnableNewPS == TRUE &&
+		     (Level == GUIRADIO_OFF || Level == GUI_IDLE_POWER_SAVE)) ||
+		    RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND)) {
+			/* Some chips don't need to delay 6ms, so copy RTMPPCIePowerLinkCtrlRestore */
+			/* return condition here. */
+			/*
+			   if (((pAd->MACVersion&0xffff0000) != 0x28600000)
+			   && ((pAd->DeviceID == NIC2860_PCIe_DEVICE_ID)
+			   ||(pAd->DeviceID == NIC2790_PCIe_DEVICE_ID)))
+			 */
+			{
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("RT28xxPciAsicRadioOn ()\n"));
+				/* 1. Set PCI Link Control in Configuration Space. */
+				RTMPPCIeLinkCtrlValueRestore(pAd,
+							     RESTORE_WAKEUP);
+				RTMPusecDelay(6000);
+			}
+		}
+	}
+#ifdef PCIE_PS_SUPPORT
+	if (!
+	    (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
+	      && IS_VERSION_AFTER_F(pAd)
+	      && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
+	      && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))))
+#endif /* PCIE_PS_SUPPORT // */
+	{
+		pAd->bPCIclkOff = FALSE;
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("PSM :309xbPCIclkOff == %d\n", pAd->bPCIclkOff));
+	}
+	/* 2. Send wake up command. */
+	AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02);
+	pAd->bPCIclkOff = FALSE;
+	/* 2-1. wait command ok. */
+	AsicCheckCommanOk(pAd, PowerWakeCID);
+	RTMP_ASIC_INTERRUPT_ENABLE(pAd);
+
+	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
+	if (Level == GUI_IDLE_POWER_SAVE) {
+#ifdef  PCIE_PS_SUPPORT
+
+		/* add by johnli, RF power sequence setup, load RF normal operation-mode setup */
+		if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) {
+			struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
+
+			if (pChipOps->AsicReverseRfFromSleepMode)
+				pChipOps->AsicReverseRfFromSleepMode(pAd);
+			/* 3090 MCU Wakeup command needs more time to be stable. */
+			/* Before stable, don't issue other MCU command to prevent from firmware error. */
+			if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
+			    && IS_VERSION_AFTER_F(pAd)
+			    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode ==
+				3)
+			    && (pAd->StaCfg.PSControl.field.EnableNewPS ==
+				TRUE)) {
+				RTMP_SEM_LOCK(&pAd->McuCmdLock);
+				pAd->brt30xxBanMcuCmd = FALSE;
+				RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
+			}
+		} else
+			/* end johnli */
+#endif /* PCIE_PS_SUPPORT // */
+		{
+			/* In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. */
+			{
+				if (INFRA_ON(pAd)
+				    && (pAd->CommonCfg.CentralChannel !=
+					pAd->CommonCfg.Channel)
+				    && (pAd->MlmeAux.HtCapability.HtCapInfo.
+					ChannelWidth == BW_40)) {
+					/* Must using 40MHz. */
+					AsicSwitchChannel(pAd,
+							  pAd->CommonCfg.
+							  CentralChannel,
+							  FALSE);
+					AsicLockChannel(pAd,
+							pAd->CommonCfg.
+							CentralChannel);
+				} else {
+					/* Must using 20MHz. */
+					AsicSwitchChannel(pAd,
+							  pAd->CommonCfg.
+							  Channel, FALSE);
+					AsicLockChannel(pAd,
+							pAd->CommonCfg.Channel);
+				}
+			}
+
+		}
+	}
+	return TRUE;
+
+}
+
+/*
+	==========================================================================
+	Description:
+		This routine sends command to firmware and turn our chip to power save mode.
+		Both RadioOff and .11 power save function needs to call this routine.
+	Input:
+		Level = GUIRADIO_OFF  : GUI Radio Off mode
+		Level = DOT11POWERSAVE  : 802.11 power save mode
+		Level = RTMP_HALT  : When Disable device.
+
+	==========================================================================
+ */
+BOOLEAN RT28xxPciAsicRadioOff(struct rt_rtmp_adapter *pAd,
+			      u8 Level, u16 TbttNumToNextWakeUp)
+{
+	WPDMA_GLO_CFG_STRUC DmaCfg;
+	u8 i, tempBBP_R3 = 0;
+	BOOLEAN brc = FALSE, Cancelled;
+	u32 TbTTTime = 0;
+	u32 PsPollTime = 0 /*, MACValue */ ;
+	unsigned long BeaconPeriodTime;
+	u32 RxDmaIdx, RxCpuIdx;
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("AsicRadioOff ===> Lv= %d, TxCpuIdx = %d, TxDmaIdx = %d. RxCpuIdx = %d, RxDmaIdx = %d.\n",
+		  Level, pAd->TxRing[0].TxCpuIdx, pAd->TxRing[0].TxDmaIdx,
+		  pAd->RxRing.RxCpuIdx, pAd->RxRing.RxDmaIdx));
+
+	if (pAd->OpMode == OPMODE_AP && Level == DOT11POWERSAVE)
+		return FALSE;
+
+	/* Check Rx DMA busy status, if more than half is occupied, give up this radio off. */
+	RTMP_IO_READ32(pAd, RX_DRX_IDX, &RxDmaIdx);
+	RTMP_IO_READ32(pAd, RX_CRX_IDX, &RxCpuIdx);
+	if ((RxDmaIdx > RxCpuIdx) && ((RxDmaIdx - RxCpuIdx) > RX_RING_SIZE / 3)) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("AsicRadioOff ===> return1. RxDmaIdx = %d ,  RxCpuIdx = %d. \n",
+			  RxDmaIdx, RxCpuIdx));
+		return FALSE;
+	} else if ((RxCpuIdx >= RxDmaIdx)
+		   && ((RxCpuIdx - RxDmaIdx) < RX_RING_SIZE / 3)) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("AsicRadioOff ===> return2.  RxCpuIdx = %d. RxDmaIdx = %d ,  \n",
+			  RxCpuIdx, RxDmaIdx));
+		return FALSE;
+	}
+	/* Once go into this function, disable tx because don't want too many packets in queue to prevent HW stops. */
+	/*pAd->bPCIclkOffDisableTx = TRUE; */
+	RTMP_SET_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
+	    && pAd->OpMode == OPMODE_STA
+	    && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) {
+		RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
+		RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
+
+		if (Level == DOT11POWERSAVE) {
+			RTMP_IO_READ32(pAd, TBTT_TIMER, &TbTTTime);
+			TbTTTime &= 0x1ffff;
+			/* 00. check if need to do sleep in this DTIM period.   If next beacon will arrive within 30ms , ...doesn't necessarily sleep. */
+			/* TbTTTime uint = 64us, LEAD_TIME unit = 1024us, PsPollTime unit = 1ms */
+			if (((64 * TbTTTime) < ((LEAD_TIME * 1024) + 40000))
+			    && (TbttNumToNextWakeUp == 0)) {
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("TbTTTime = 0x%x , give up this sleep. \n",
+					  TbTTTime));
+				OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+				/*pAd->bPCIclkOffDisableTx = FALSE; */
+				RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
+				return FALSE;
+			} else {
+				PsPollTime =
+				    (64 * TbTTTime - LEAD_TIME * 1024) / 1000;
+#ifdef PCIE_PS_SUPPORT
+				if ((IS_RT3090(pAd) || IS_RT3572(pAd)
+				     || IS_RT3390(pAd))
+				    && IS_VERSION_AFTER_F(pAd)
+				    && (pAd->StaCfg.PSControl.field.
+					rt30xxPowerMode == 3)
+				    && (pAd->StaCfg.PSControl.field.
+					EnableNewPS == TRUE)) {
+					PsPollTime -= 5;
+				} else
+#endif /* PCIE_PS_SUPPORT // */
+					PsPollTime -= 3;
+
+				BeaconPeriodTime =
+				    pAd->CommonCfg.BeaconPeriod * 102 / 100;
+				if (TbttNumToNextWakeUp > 0)
+					PsPollTime +=
+					    ((TbttNumToNextWakeUp -
+					      1) * BeaconPeriodTime);
+
+				pAd->Mlme.bPsPollTimerRunning = TRUE;
+				RTMPSetTimer(&pAd->Mlme.PsPollTimer,
+					     PsPollTime);
+			}
+		}
+	} else {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("RT28xxPciAsicRadioOff::Level!=DOT11POWERSAVE \n"));
+	}
+
+	pAd->bPCIclkOffDisableTx = FALSE;
+
+	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
+
+	/* Set to 1R. */
+	if (pAd->Antenna.field.RxPath > 1 && pAd->OpMode == OPMODE_STA) {
+		tempBBP_R3 = (pAd->StaCfg.BBPR3 & 0xE7);
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, tempBBP_R3);
+	}
+	/* In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. */
+	if ((INFRA_ON(pAd) || pAd->OpMode == OPMODE_AP)
+	    && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
+	    && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) {
+		/* Must using 40MHz. */
+		AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
+	} else {
+		/* Must using 20MHz. */
+		AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
+	}
+
+	if (Level != RTMP_HALT) {
+		/* Change Interrupt bitmask. */
+		/* When PCI clock is off, don't want to service interrupt. */
+		RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt);
+	} else {
+		RTMP_ASIC_INTERRUPT_DISABLE(pAd);
+	}
+
+	RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
+	/*  2. Send Sleep command */
+	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
+	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
+	/* send POWER-SAVE command to MCU. high-byte = 1 save power as much as possible. high byte = 0 save less power */
+	AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x1);
+	/*  2-1. Wait command success */
+	/* Status = 1 : success, Status = 2, already sleep, Status = 3, Maybe MAC is busy so can't finish this task. */
+	brc = AsicCheckCommanOk(pAd, PowerSafeCID);
+
+	/*  3. After 0x30 command is ok, send radio off command. lowbyte = 0 for power safe. */
+	/* If 0x30 command is not ok this time, we can ignore 0x35 command. It will make sure not cause firmware'r problem. */
+	if ((Level == DOT11POWERSAVE) && (brc == TRUE)) {
+		AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 0, 0x00);	/* lowbyte = 0 means to do power safe, NOT turn off radio. */
+		/*  3-1. Wait command success */
+		AsicCheckCommanOk(pAd, PowerRadioOffCID);
+	} else if (brc == TRUE) {
+		AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 1, 0x00);	/* lowbyte = 0 means to do power safe, NOT turn off radio. */
+		/*  3-1. Wait command success */
+		AsicCheckCommanOk(pAd, PowerRadioOffCID);
+	}
+	/* 1. Wait DMA not busy */
+	i = 0;
+	do {
+		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
+		if ((DmaCfg.field.RxDMABusy == 0)
+		    && (DmaCfg.field.TxDMABusy == 0))
+			break;
+		RTMPusecDelay(20);
+		i++;
+	} while (i < 50);
+
+	/*
+	   if (i >= 50)
+	   {
+	   pAd->CheckDmaBusyCount++;
+	   DBGPRINT(RT_DEBUG_TRACE, ("DMA Rx keeps busy.  return on AsicRadioOff () CheckDmaBusyCount = %d \n", pAd->CheckDmaBusyCount));
+	   }
+	   else
+	   {
+	   pAd->CheckDmaBusyCount = 0;
+	   }
+	 */
+/*KH Debug:My original codes have the follwoing codes, but currecnt codes do not have it. */
+/* Disable for stability. If PCIE Link Control is modified for advance power save, re-covery this code segment. */
+	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x1280);
+/*OPSTATUS_SET_FLAG(pAd, fOP_STATUS_CLKSELECT_40MHZ); */
+
+#ifdef PCIE_PS_SUPPORT
+	if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
+	    && IS_VERSION_AFTER_F(pAd)
+	    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
+	    && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("RT28xxPciAsicRadioOff::3090 return to skip the following TbttNumToNextWakeUp setting for 279x\n"));
+		pAd->bPCIclkOff = TRUE;
+		RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
+		/* For this case, doesn't need to below actions, so return here. */
+		return brc;
+	}
+#endif /* PCIE_PS_SUPPORT // */
+
+	if (Level == DOT11POWERSAVE) {
+		AUTO_WAKEUP_STRUC AutoWakeupCfg;
+		/*RTMPSetTimer(&pAd->Mlme.PsPollTimer, 90); */
+
+		/* we have decided to SLEEP, so at least do it for a BEACON period. */
+		if (TbttNumToNextWakeUp == 0)
+			TbttNumToNextWakeUp = 1;
+
+		AutoWakeupCfg.word = 0;
+		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+
+		/* 1. Set auto wake up timer. */
+		AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
+		AutoWakeupCfg.field.EnableAutoWakeup = 1;
+		AutoWakeupCfg.field.AutoLeadTime = LEAD_TIME;
+		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+	}
+	/*  4-1. If it's to disable our device. Need to restore PCI Configuration Space to its original value. */
+	if (Level == RTMP_HALT && pAd->OpMode == OPMODE_STA) {
+		if ((brc == TRUE) && (i < 50))
+			RTMPPCIeLinkCtrlSetting(pAd, 1);
+	}
+	/*  4. Set PCI configuration Space Link Comtrol fields.  Only Radio Off needs to call this function */
+	else if (pAd->OpMode == OPMODE_STA) {
+		if ((brc == TRUE) && (i < 50))
+			RTMPPCIeLinkCtrlSetting(pAd, 3);
+	}
+	/*pAd->bPCIclkOffDisableTx = FALSE; */
+	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
+	return TRUE;
+}
+
+void RT28xxPciMlmeRadioOn(struct rt_rtmp_adapter *pAd)
+{
+	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+		return;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("%s===>\n", __func__));
+
+	if ((pAd->OpMode == OPMODE_AP) || ((pAd->OpMode == OPMODE_STA)
+					   &&
+					   (!OPSTATUS_TEST_FLAG
+					    (pAd, fOP_STATUS_PCIE_DEVICE)
+					    || pAd->StaCfg.PSControl.field.
+					    EnableNewPS == FALSE))) {
+		RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
+		/*NICResetFromError(pAd); */
+
+		RTMPRingCleanUp(pAd, QID_AC_BK);
+		RTMPRingCleanUp(pAd, QID_AC_BE);
+		RTMPRingCleanUp(pAd, QID_AC_VI);
+		RTMPRingCleanUp(pAd, QID_AC_VO);
+		RTMPRingCleanUp(pAd, QID_MGMT);
+		RTMPRingCleanUp(pAd, QID_RX);
+
+		/* Enable Tx/Rx */
+		RTMPEnableRxTx(pAd);
+
+		/* Clear Radio off flag */
+		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
+		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
+
+		/* Set LED */
+		RTMPSetLED(pAd, LED_RADIO_ON);
+	}
+
+	if ((pAd->OpMode == OPMODE_STA) &&
+	    (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
+	    && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
+		BOOLEAN Cancelled;
+
+		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
+
+		pAd->Mlme.bPsPollTimerRunning = FALSE;
+		RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
+		RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
+		RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 40);
+	}
+}
+
+void RT28xxPciMlmeRadioOFF(struct rt_rtmp_adapter *pAd)
+{
+	BOOLEAN brc = TRUE;
+
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+		return;
+
+	/* Link down first if any association exists */
+	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
+		if (INFRA_ON(pAd) || ADHOC_ON(pAd)) {
+			struct rt_mlme_disassoc_req DisReq;
+			struct rt_mlme_queue_elem *pMsgElem =
+			    (struct rt_mlme_queue_elem *)kmalloc(sizeof(struct rt_mlme_queue_elem),
+							MEM_ALLOC_FLAG);
+
+			if (pMsgElem) {
+				COPY_MAC_ADDR(&DisReq.Addr,
+					      pAd->CommonCfg.Bssid);
+				DisReq.Reason = REASON_DISASSOC_STA_LEAVING;
+
+				pMsgElem->Machine = ASSOC_STATE_MACHINE;
+				pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
+				pMsgElem->MsgLen =
+				    sizeof(struct rt_mlme_disassoc_req);
+				NdisMoveMemory(pMsgElem->Msg, &DisReq,
+					       sizeof
+					       (struct rt_mlme_disassoc_req));
+
+				MlmeDisassocReqAction(pAd, pMsgElem);
+				kfree(pMsgElem);
+
+				RTMPusecDelay(1000);
+			}
+		}
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("%s===>\n", __func__));
+
+	/* Set Radio off flag */
+	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
+	{
+		BOOLEAN Cancelled;
+		if (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) {
+			if (RTMP_TEST_FLAG
+			    (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) {
+				RTMPCancelTimer(&pAd->MlmeAux.ScanTimer,
+						&Cancelled);
+				RTMP_CLEAR_FLAG(pAd,
+						fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+			}
+			/* If during power safe mode. */
+			if (pAd->StaCfg.bRadio == TRUE) {
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("-->MlmeRadioOff() return on bRadio == TRUE; \n"));
+				return;
+			}
+			/* Always radio on since the NIC needs to set the MCU command (LED_RADIO_OFF). */
+			if (IDLE_ON(pAd) &&
+			    (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
+			{
+				RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
+			}
+			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
+				BOOLEAN Cancelled;
+				pAd->Mlme.bPsPollTimerRunning = FALSE;
+				RTMPCancelTimer(&pAd->Mlme.PsPollTimer,
+						&Cancelled);
+				RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer,
+						&Cancelled);
+			}
+		}
+		/* Link down first if any association exists */
+		if (INFRA_ON(pAd) || ADHOC_ON(pAd))
+			LinkDown(pAd, FALSE);
+		RTMPusecDelay(10000);
+		/*========================================== */
+		/* Clean up old bss table */
+		BssTableInit(&pAd->ScanTab);
+
+		/*
+		   if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
+		   {
+		   RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
+		   return;
+		   }
+		 */
+	}
+
+	/* Set LED.Move to here for fixing LED bug. This flag must be called after LinkDown */
+	RTMPSetLED(pAd, LED_RADIO_OFF);
+
+/*KH Debug:All PCIe devices need to use timer to execute radio off function, or the PCIe&&EnableNewPS needs. */
+/*KH Ans:It is right, because only when the PCIe and EnableNewPs is true, we need to delay the RadioOffTimer */
+/*to avoid the deadlock with PCIe Power saving function. */
+	if (pAd->OpMode == OPMODE_STA &&
+	    OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE) &&
+	    pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) {
+		RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
+	} else {
+		brc = RT28xxPciAsicRadioOff(pAd, GUIRADIO_OFF, 0);
+
+		if (brc == FALSE) {
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("%s call RT28xxPciAsicRadioOff fail!\n",
+				  __func__));
+		}
+	}
+/*
+*/
+}
+
+#endif /* RTMP_MAC_PCI // */
diff --git a/drivers/staging/rt2860/common/cmm_mac_usb.c b/drivers/staging/rt2860/common/cmm_mac_usb.c
new file mode 100644
index 0000000..9dd6959
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_mac_usb.c
@@ -0,0 +1,1165 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+*/
+
+#ifdef RTMP_MAC_USB
+
+#include	"../rt_config.h"
+
+/*
+========================================================================
+Routine Description:
+    Initialize receive data structures.
+
+Arguments:
+    pAd					Pointer to our adapter
+
+Return Value:
+	NDIS_STATUS_SUCCESS
+	NDIS_STATUS_RESOURCES
+
+Note:
+	Initialize all receive releated private buffer, include those define
+	in struct rt_rtmp_adapter structure and all private data structures. The mahor
+	work is to allocate buffer for each packet and chain buffer to
+	NDIS packet descriptor.
+========================================================================
+*/
+int NICInitRecv(struct rt_rtmp_adapter *pAd)
+{
+	u8 i;
+	int Status = NDIS_STATUS_SUCCESS;
+	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n"));
+	pObj = pObj;
+
+	/*InterlockedExchange(&pAd->PendingRx, 0); */
+	pAd->PendingRx = 0;
+	pAd->NextRxBulkInReadIndex = 0;	/* Next Rx Read index */
+	pAd->NextRxBulkInIndex = 0;	/*RX_RING_SIZE -1; // Rx Bulk pointer */
+	pAd->NextRxBulkInPosition = 0;
+
+	for (i = 0; i < (RX_RING_SIZE); i++) {
+		struct rt_rx_context *pRxContext = &(pAd->RxContext[i]);
+
+		/*Allocate URB */
+		pRxContext->pUrb = RTUSB_ALLOC_URB(0);
+		if (pRxContext->pUrb == NULL) {
+			Status = NDIS_STATUS_RESOURCES;
+			goto out1;
+		}
+		/* Allocate transfer buffer */
+		pRxContext->TransferBuffer =
+		    RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE,
+					   &pRxContext->data_dma);
+		if (pRxContext->TransferBuffer == NULL) {
+			Status = NDIS_STATUS_RESOURCES;
+			goto out1;
+		}
+
+		NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
+
+		pRxContext->pAd = pAd;
+		pRxContext->pIrp = NULL;
+		pRxContext->InUse = FALSE;
+		pRxContext->IRPPending = FALSE;
+		pRxContext->Readable = FALSE;
+		/*pRxContext->ReorderInUse = FALSE; */
+		pRxContext->bRxHandling = FALSE;
+		pRxContext->BulkInOffset = 0;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv(Status=%d)\n", Status));
+	return Status;
+
+out1:
+	for (i = 0; i < (RX_RING_SIZE); i++) {
+		struct rt_rx_context *pRxContext = &(pAd->RxContext[i]);
+
+		if (NULL != pRxContext->TransferBuffer) {
+			RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE,
+					      pRxContext->TransferBuffer,
+					      pRxContext->data_dma);
+			pRxContext->TransferBuffer = NULL;
+		}
+
+		if (NULL != pRxContext->pUrb) {
+			RTUSB_UNLINK_URB(pRxContext->pUrb);
+			RTUSB_FREE_URB(pRxContext->pUrb);
+			pRxContext->pUrb = NULL;
+		}
+	}
+
+	return Status;
+}
+
+/*
+========================================================================
+Routine Description:
+    Initialize transmit data structures.
+
+Arguments:
+    pAd					Pointer to our adapter
+
+Return Value:
+	NDIS_STATUS_SUCCESS
+	NDIS_STATUS_RESOURCES
+
+Note:
+========================================================================
+*/
+int NICInitTransmit(struct rt_rtmp_adapter *pAd)
+{
+#define LM_USB_ALLOC(pObj, Context, TB_Type, BufferSize, Status, msg1, err1, msg2, err2)	\
+	Context->pUrb = RTUSB_ALLOC_URB(0);		\
+	if (Context->pUrb == NULL) {			\
+		DBGPRINT(RT_DEBUG_ERROR, msg1);		\
+		Status = NDIS_STATUS_RESOURCES;		\
+		goto err1; }						\
+											\
+	Context->TransferBuffer =				\
+		(TB_Type)RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, BufferSize, &Context->data_dma);	\
+	if (Context->TransferBuffer == NULL) {	\
+		DBGPRINT(RT_DEBUG_ERROR, msg2);		\
+		Status = NDIS_STATUS_RESOURCES;		\
+		goto err2; }
+
+#define LM_URB_FREE(pObj, Context, BufferSize)				\
+	if (NULL != Context->pUrb) {							\
+		RTUSB_UNLINK_URB(Context->pUrb);					\
+		RTUSB_FREE_URB(Context->pUrb);						\
+		Context->pUrb = NULL; }								\
+	if (NULL != Context->TransferBuffer) {				\
+		RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize,	\
+								Context->TransferBuffer,	\
+								Context->data_dma);			\
+		Context->TransferBuffer = NULL; }
+
+	u8 i, acidx;
+	int Status = NDIS_STATUS_SUCCESS;
+	struct rt_tx_context *pNullContext = &(pAd->NullContext);
+	struct rt_tx_context *pPsPollContext = &(pAd->PsPollContext);
+	struct rt_tx_context *pRTSContext = &(pAd->RTSContext);
+	struct rt_tx_context *pMLMEContext = NULL;
+/*      struct rt_ht_tx_context *pHTTXContext = NULL; */
+	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
+	void *RingBaseVa;
+/*      struct rt_rtmp_tx_ring *pTxRing; */
+	struct rt_rtmp_mgmt_ring *pMgmtRing;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n"));
+	pObj = pObj;
+
+	/* Init 4 set of Tx parameters */
+	for (acidx = 0; acidx < NUM_OF_TX_RING; acidx++) {
+		/* Initialize all Transmit releated queues */
+		InitializeQueueHeader(&pAd->TxSwQueue[acidx]);
+
+		/* Next Local tx ring pointer waiting for buck out */
+		pAd->NextBulkOutIndex[acidx] = acidx;
+		pAd->BulkOutPending[acidx] = FALSE;	/* Buck Out control flag */
+		/*pAd->DataBulkDoneIdx[acidx] = 0; */
+	}
+
+	/*pAd->NextMLMEIndex    = 0; */
+	/*pAd->PushMgmtIndex    = 0; */
+	/*pAd->PopMgmtIndex     = 0; */
+	/*InterlockedExchange(&pAd->MgmtQueueSize, 0); */
+	/*InterlockedExchange(&pAd->TxCount, 0); */
+
+	/*pAd->PrioRingFirstIndex       = 0; */
+	/*pAd->PrioRingTxCnt            = 0; */
+
+	do {
+		/* */
+		/* TX_RING_SIZE, 4 ACs */
+		/* */
+		for (acidx = 0; acidx < 4; acidx++) {
+			struct rt_ht_tx_context *pHTTXContext = &(pAd->TxContext[acidx]);
+
+			NdisZeroMemory(pHTTXContext, sizeof(struct rt_ht_tx_context));
+			/*Allocate URB */
+			LM_USB_ALLOC(pObj, pHTTXContext, struct rt_httx_buffer *,
+				     sizeof(struct rt_httx_buffer), Status,
+				     ("<-- ERROR in Alloc TX TxContext[%d] urb!\n",
+				      acidx), done,
+				     ("<-- ERROR in Alloc TX TxContext[%d] struct rt_httx_buffer!\n",
+				      acidx), out1);
+
+			NdisZeroMemory(pHTTXContext->TransferBuffer->
+				       Aggregation, 4);
+			pHTTXContext->pAd = pAd;
+			pHTTXContext->pIrp = NULL;
+			pHTTXContext->IRPPending = FALSE;
+			pHTTXContext->NextBulkOutPosition = 0;
+			pHTTXContext->ENextBulkOutPosition = 0;
+			pHTTXContext->CurWritePosition = 0;
+			pHTTXContext->CurWriteRealPos = 0;
+			pHTTXContext->BulkOutSize = 0;
+			pHTTXContext->BulkOutPipeId = acidx;
+			pHTTXContext->bRingEmpty = TRUE;
+			pHTTXContext->bCopySavePad = FALSE;
+			pAd->BulkOutPending[acidx] = FALSE;
+		}
+
+		/* */
+		/* MGMT_RING_SIZE */
+		/* */
+
+		/* Allocate MGMT ring descriptor's memory */
+		pAd->MgmtDescRing.AllocSize =
+		    MGMT_RING_SIZE * sizeof(struct rt_tx_context);
+		os_alloc_mem(pAd, (u8 **) (&pAd->MgmtDescRing.AllocVa),
+			     pAd->MgmtDescRing.AllocSize);
+		if (pAd->MgmtDescRing.AllocVa == NULL) {
+			DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n"));
+			Status = NDIS_STATUS_RESOURCES;
+			goto out1;
+		}
+		NdisZeroMemory(pAd->MgmtDescRing.AllocVa,
+			       pAd->MgmtDescRing.AllocSize);
+		RingBaseVa = pAd->MgmtDescRing.AllocVa;
+
+		/* Initialize MGMT Ring and associated buffer memory */
+		pMgmtRing = &pAd->MgmtRing;
+		for (i = 0; i < MGMT_RING_SIZE; i++) {
+			/* link the pre-allocated Mgmt buffer to MgmtRing.Cell */
+			pMgmtRing->Cell[i].AllocSize = sizeof(struct rt_tx_context);
+			pMgmtRing->Cell[i].AllocVa = RingBaseVa;
+			pMgmtRing->Cell[i].pNdisPacket = NULL;
+			pMgmtRing->Cell[i].pNextNdisPacket = NULL;
+
+			/*Allocate URB for MLMEContext */
+			pMLMEContext =
+			    (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa;
+			pMLMEContext->pUrb = RTUSB_ALLOC_URB(0);
+			if (pMLMEContext->pUrb == NULL) {
+				DBGPRINT(RT_DEBUG_ERROR,
+					 ("<-- ERROR in Alloc TX MLMEContext[%d] urb!\n",
+					  i));
+				Status = NDIS_STATUS_RESOURCES;
+				goto out2;
+			}
+			pMLMEContext->pAd = pAd;
+			pMLMEContext->pIrp = NULL;
+			pMLMEContext->TransferBuffer = NULL;
+			pMLMEContext->InUse = FALSE;
+			pMLMEContext->IRPPending = FALSE;
+			pMLMEContext->bWaitingBulkOut = FALSE;
+			pMLMEContext->BulkOutSize = 0;
+			pMLMEContext->SelfIdx = i;
+
+			/* Offset to next ring descriptor address */
+			RingBaseVa = (u8 *)RingBaseVa + sizeof(struct rt_tx_context);
+		}
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("MGMT Ring: total %d entry allocated\n", i));
+
+		/*pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1); */
+		pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE;
+		pAd->MgmtRing.TxCpuIdx = 0;
+		pAd->MgmtRing.TxDmaIdx = 0;
+
+		/* */
+		/* BEACON_RING_SIZE */
+		/* */
+		for (i = 0; i < BEACON_RING_SIZE; i++)	/* 2 */
+		{
+			struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]);
+
+			NdisZeroMemory(pBeaconContext, sizeof(struct rt_tx_context));
+
+			/*Allocate URB */
+			LM_USB_ALLOC(pObj, pBeaconContext, struct rt_tx_buffer *,
+				     sizeof(struct rt_tx_buffer), Status,
+				     ("<-- ERROR in Alloc TX BeaconContext[%d] urb!\n",
+				      i), out2,
+				     ("<-- ERROR in Alloc TX BeaconContext[%d] struct rt_tx_buffer!\n",
+				      i), out3);
+
+			pBeaconContext->pAd = pAd;
+			pBeaconContext->pIrp = NULL;
+			pBeaconContext->InUse = FALSE;
+			pBeaconContext->IRPPending = FALSE;
+		}
+
+		/* */
+		/* NullContext */
+		/* */
+		NdisZeroMemory(pNullContext, sizeof(struct rt_tx_context));
+
+		/*Allocate URB */
+		LM_USB_ALLOC(pObj, pNullContext, struct rt_tx_buffer *, sizeof(struct rt_tx_buffer),
+			     Status,
+			     ("<-- ERROR in Alloc TX NullContext urb!\n"),
+			     out3,
+			     ("<-- ERROR in Alloc TX NullContext struct rt_tx_buffer!\n"),
+			     out4);
+
+		pNullContext->pAd = pAd;
+		pNullContext->pIrp = NULL;
+		pNullContext->InUse = FALSE;
+		pNullContext->IRPPending = FALSE;
+
+		/* */
+		/* RTSContext */
+		/* */
+		NdisZeroMemory(pRTSContext, sizeof(struct rt_tx_context));
+
+		/*Allocate URB */
+		LM_USB_ALLOC(pObj, pRTSContext, struct rt_tx_buffer *, sizeof(struct rt_tx_buffer),
+			     Status,
+			     ("<-- ERROR in Alloc TX RTSContext urb!\n"),
+			     out4,
+			     ("<-- ERROR in Alloc TX RTSContext struct rt_tx_buffer!\n"),
+			     out5);
+
+		pRTSContext->pAd = pAd;
+		pRTSContext->pIrp = NULL;
+		pRTSContext->InUse = FALSE;
+		pRTSContext->IRPPending = FALSE;
+
+		/* */
+		/* PsPollContext */
+		/* */
+		/*NdisZeroMemory(pPsPollContext, sizeof(struct rt_tx_context)); */
+		/*Allocate URB */
+		LM_USB_ALLOC(pObj, pPsPollContext, struct rt_tx_buffer *,
+			     sizeof(struct rt_tx_buffer), Status,
+			     ("<-- ERROR in Alloc TX PsPollContext urb!\n"),
+			     out5,
+			     ("<-- ERROR in Alloc TX PsPollContext struct rt_tx_buffer!\n"),
+			     out6);
+
+		pPsPollContext->pAd = pAd;
+		pPsPollContext->pIrp = NULL;
+		pPsPollContext->InUse = FALSE;
+		pPsPollContext->IRPPending = FALSE;
+		pPsPollContext->bAggregatible = FALSE;
+		pPsPollContext->LastOne = TRUE;
+
+	} while (FALSE);
+
+done:
+	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit(Status=%d)\n", Status));
+
+	return Status;
+
+	/* --------------------------- ERROR HANDLE --------------------------- */
+out6:
+	LM_URB_FREE(pObj, pPsPollContext, sizeof(struct rt_tx_buffer));
+
+out5:
+	LM_URB_FREE(pObj, pRTSContext, sizeof(struct rt_tx_buffer));
+
+out4:
+	LM_URB_FREE(pObj, pNullContext, sizeof(struct rt_tx_buffer));
+
+out3:
+	for (i = 0; i < BEACON_RING_SIZE; i++) {
+		struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]);
+		if (pBeaconContext)
+			LM_URB_FREE(pObj, pBeaconContext, sizeof(struct rt_tx_buffer));
+	}
+
+out2:
+	if (pAd->MgmtDescRing.AllocVa) {
+		pMgmtRing = &pAd->MgmtRing;
+		for (i = 0; i < MGMT_RING_SIZE; i++) {
+			pMLMEContext =
+			    (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa;
+			if (pMLMEContext)
+				LM_URB_FREE(pObj, pMLMEContext,
+					    sizeof(struct rt_tx_buffer));
+		}
+		os_free_mem(pAd, pAd->MgmtDescRing.AllocVa);
+		pAd->MgmtDescRing.AllocVa = NULL;
+	}
+
+out1:
+	for (acidx = 0; acidx < 4; acidx++) {
+		struct rt_ht_tx_context *pTxContext = &(pAd->TxContext[acidx]);
+		if (pTxContext)
+			LM_URB_FREE(pObj, pTxContext, sizeof(struct rt_httx_buffer));
+	}
+
+	/* Here we didn't have any pre-allocated memory need to free. */
+
+	return Status;
+}
+
+/*
+========================================================================
+Routine Description:
+    Allocate DMA memory blocks for send, receive.
+
+Arguments:
+    pAd					Pointer to our adapter
+
+Return Value:
+	NDIS_STATUS_SUCCESS
+	NDIS_STATUS_FAILURE
+	NDIS_STATUS_RESOURCES
+
+Note:
+========================================================================
+*/
+int RTMPAllocTxRxRingMemory(struct rt_rtmp_adapter *pAd)
+{
+/*      struct rt_counter_802_11  pCounter = &pAd->WlanCounters; */
+	int Status;
+	int num;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
+
+	do {
+		/* Init the struct rt_cmdq and CmdQLock */
+		NdisAllocateSpinLock(&pAd->CmdQLock);
+		NdisAcquireSpinLock(&pAd->CmdQLock);
+		RTUSBInitializeCmdQ(&pAd->CmdQ);
+		NdisReleaseSpinLock(&pAd->CmdQLock);
+
+		NdisAllocateSpinLock(&pAd->MLMEBulkOutLock);
+		/*NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock); */
+		NdisAllocateSpinLock(&pAd->BulkOutLock[0]);
+		NdisAllocateSpinLock(&pAd->BulkOutLock[1]);
+		NdisAllocateSpinLock(&pAd->BulkOutLock[2]);
+		NdisAllocateSpinLock(&pAd->BulkOutLock[3]);
+		NdisAllocateSpinLock(&pAd->BulkOutLock[4]);
+		NdisAllocateSpinLock(&pAd->BulkOutLock[5]);
+		NdisAllocateSpinLock(&pAd->BulkInLock);
+
+		for (num = 0; num < NUM_OF_TX_RING; num++) {
+			NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]);
+		}
+
+/*              NdisAllocateSpinLock(&pAd->MemLock);    // Not used in RT28XX */
+
+/*              NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit() */
+/*              NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit() */
+
+/*              for(num=0; num<MAX_LEN_OF_BA_REC_TABLE; num++) */
+/*              { */
+/*                      NdisAllocateSpinLock(&pAd->BATable.BARecEntry[num].RxReRingLock); */
+/*              } */
+
+		/* */
+		/* Init Mac Table */
+		/* */
+/*              MacTableInitialize(pAd); */
+
+		/* */
+		/* Init send data structures and related parameters */
+		/* */
+		Status = NICInitTransmit(pAd);
+		if (Status != NDIS_STATUS_SUCCESS)
+			break;
+
+		/* */
+		/* Init receive data structures and related parameters */
+		/* */
+		Status = NICInitRecv(pAd);
+		if (Status != NDIS_STATUS_SUCCESS)
+			break;
+
+		pAd->PendingIoCount = 1;
+
+	} while (FALSE);
+
+	NdisZeroMemory(&pAd->FragFrame, sizeof(struct rt_fragment_frame));
+	pAd->FragFrame.pFragPacket =
+	    RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
+
+	if (pAd->FragFrame.pFragPacket == NULL) {
+		Status = NDIS_STATUS_RESOURCES;
+	}
+
+	DBGPRINT_S(Status,
+		   ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
+	return Status;
+}
+
+/*
+========================================================================
+Routine Description:
+	Calls USB_InterfaceStop and frees memory allocated for the URBs
+    calls NdisMDeregisterDevice and frees the memory
+    allocated in VNetInitialize for the Adapter Object
+
+Arguments:
+	*pAd				the raxx interface data pointer
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+void RTMPFreeTxRxRingMemory(struct rt_rtmp_adapter *pAd)
+{
+#define LM_URB_FREE(pObj, Context, BufferSize)				\
+	if (NULL != Context->pUrb) {							\
+		RTUSB_UNLINK_URB(Context->pUrb);					\
+		RTUSB_FREE_URB(Context->pUrb);						\
+		Context->pUrb = NULL; }								\
+	if (NULL != Context->TransferBuffer) {					\
+		RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize,	\
+								Context->TransferBuffer,	\
+								Context->data_dma);			\
+		Context->TransferBuffer = NULL; }
+
+	u32 i, acidx;
+	struct rt_tx_context *pNullContext = &pAd->NullContext;
+	struct rt_tx_context *pPsPollContext = &pAd->PsPollContext;
+	struct rt_tx_context *pRTSContext = &pAd->RTSContext;
+/*      struct rt_ht_tx_context *pHTTXContext; */
+	/*PRTMP_REORDERBUF      pReorderBuf; */
+	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
+/*      struct rt_rtmp_tx_ring *pTxRing; */
+
+	DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n"));
+	pObj = pObj;
+
+	/* Free all resources for the RECEIVE buffer queue. */
+	for (i = 0; i < (RX_RING_SIZE); i++) {
+		struct rt_rx_context *pRxContext = &(pAd->RxContext[i]);
+		if (pRxContext)
+			LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE);
+	}
+
+	/* Free PsPoll frame resource */
+	LM_URB_FREE(pObj, pPsPollContext, sizeof(struct rt_tx_buffer));
+
+	/* Free NULL frame resource */
+	LM_URB_FREE(pObj, pNullContext, sizeof(struct rt_tx_buffer));
+
+	/* Free RTS frame resource */
+	LM_URB_FREE(pObj, pRTSContext, sizeof(struct rt_tx_buffer));
+
+	/* Free beacon frame resource */
+	for (i = 0; i < BEACON_RING_SIZE; i++) {
+		struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]);
+		if (pBeaconContext)
+			LM_URB_FREE(pObj, pBeaconContext, sizeof(struct rt_tx_buffer));
+	}
+
+	/* Free mgmt frame resource */
+	for (i = 0; i < MGMT_RING_SIZE; i++) {
+		struct rt_tx_context *pMLMEContext =
+		    (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa;
+		/*LM_URB_FREE(pObj, pMLMEContext, sizeof(struct rt_tx_buffer)); */
+		if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket) {
+			RTMPFreeNdisPacket(pAd,
+					   pAd->MgmtRing.Cell[i].pNdisPacket);
+			pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
+			pMLMEContext->TransferBuffer = NULL;
+		}
+
+		if (pMLMEContext) {
+			if (NULL != pMLMEContext->pUrb) {
+				RTUSB_UNLINK_URB(pMLMEContext->pUrb);
+				RTUSB_FREE_URB(pMLMEContext->pUrb);
+				pMLMEContext->pUrb = NULL;
+			}
+		}
+	}
+	if (pAd->MgmtDescRing.AllocVa)
+		os_free_mem(pAd, pAd->MgmtDescRing.AllocVa);
+
+	/* Free Tx frame resource */
+	for (acidx = 0; acidx < 4; acidx++) {
+		struct rt_ht_tx_context *pHTTXContext = &(pAd->TxContext[acidx]);
+		if (pHTTXContext)
+			LM_URB_FREE(pObj, pHTTXContext, sizeof(struct rt_httx_buffer));
+	}
+
+	if (pAd->FragFrame.pFragPacket)
+		RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket,
+				    NDIS_STATUS_SUCCESS);
+
+	for (i = 0; i < 6; i++) {
+		NdisFreeSpinLock(&pAd->BulkOutLock[i]);
+	}
+
+	NdisFreeSpinLock(&pAd->BulkInLock);
+	NdisFreeSpinLock(&pAd->MLMEBulkOutLock);
+
+	NdisFreeSpinLock(&pAd->CmdQLock);
+	/* Clear all pending bulk-out request flags. */
+	RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff);
+
+/*      NdisFreeSpinLock(&pAd->MacTabLock); */
+
+/*      for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++) */
+/*      { */
+/*              NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock); */
+/*      } */
+
+	DBGPRINT(RT_DEBUG_ERROR, ("<--- RTMPFreeTxRxRingMemory\n"));
+}
+
+/*
+========================================================================
+Routine Description:
+    Write WLAN MAC address to USB 2870.
+
+Arguments:
+    pAd					Pointer to our adapter
+
+Return Value:
+	NDIS_STATUS_SUCCESS
+
+Note:
+========================================================================
+*/
+int RTUSBWriteHWMACAddress(struct rt_rtmp_adapter *pAd)
+{
+	MAC_DW0_STRUC StaMacReg0;
+	MAC_DW1_STRUC StaMacReg1;
+	int Status = NDIS_STATUS_SUCCESS;
+	LARGE_INTEGER NOW;
+
+	/* initialize the random number generator */
+	RTMP_GetCurrentSystemTime(&NOW);
+
+	if (pAd->bLocalAdminMAC != TRUE) {
+		pAd->CurrentAddress[0] = pAd->PermanentAddress[0];
+		pAd->CurrentAddress[1] = pAd->PermanentAddress[1];
+		pAd->CurrentAddress[2] = pAd->PermanentAddress[2];
+		pAd->CurrentAddress[3] = pAd->PermanentAddress[3];
+		pAd->CurrentAddress[4] = pAd->PermanentAddress[4];
+		pAd->CurrentAddress[5] = pAd->PermanentAddress[5];
+	}
+	/* Write New MAC address to MAC_CSR2 & MAC_CSR3 & let ASIC know our new MAC */
+	StaMacReg0.field.Byte0 = pAd->CurrentAddress[0];
+	StaMacReg0.field.Byte1 = pAd->CurrentAddress[1];
+	StaMacReg0.field.Byte2 = pAd->CurrentAddress[2];
+	StaMacReg0.field.Byte3 = pAd->CurrentAddress[3];
+	StaMacReg1.field.Byte4 = pAd->CurrentAddress[4];
+	StaMacReg1.field.Byte5 = pAd->CurrentAddress[5];
+	StaMacReg1.field.U2MeMask = 0xff;
+	DBGPRINT_RAW(RT_DEBUG_TRACE,
+		     ("Local MAC = %02x:%02x:%02x:%02x:%02x:%02x\n",
+		      pAd->CurrentAddress[0], pAd->CurrentAddress[1],
+		      pAd->CurrentAddress[2], pAd->CurrentAddress[3],
+		      pAd->CurrentAddress[4], pAd->CurrentAddress[5]));
+
+	RTUSBWriteMACRegister(pAd, MAC_ADDR_DW0, StaMacReg0.word);
+	RTUSBWriteMACRegister(pAd, MAC_ADDR_DW1, StaMacReg1.word);
+	return Status;
+}
+
+/*
+========================================================================
+Routine Description:
+    Disable DMA.
+
+Arguments:
+	*pAd				the raxx interface data pointer
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+void RT28XXDMADisable(struct rt_rtmp_adapter *pAd)
+{
+	/* no use */
+}
+
+/*
+========================================================================
+Routine Description:
+    Enable DMA.
+
+Arguments:
+	*pAd				the raxx interface data pointer
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+void RT28XXDMAEnable(struct rt_rtmp_adapter *pAd)
+{
+	WPDMA_GLO_CFG_STRUC GloCfg;
+	USB_DMA_CFG_STRUC UsbCfg;
+	int i = 0;
+
+	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
+	do {
+		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
+		if ((GloCfg.field.TxDMABusy == 0)
+		    && (GloCfg.field.RxDMABusy == 0))
+			break;
+
+		DBGPRINT(RT_DEBUG_TRACE, ("==>  DMABusy\n"));
+		RTMPusecDelay(1000);
+		i++;
+	} while (i < 200);
+
+	RTMPusecDelay(50);
+	GloCfg.field.EnTXWriteBackDDONE = 1;
+	GloCfg.field.EnableRxDMA = 1;
+	GloCfg.field.EnableTxDMA = 1;
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
+	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
+
+	UsbCfg.word = 0;
+	UsbCfg.field.phyclear = 0;
+	/* usb version is 1.1,do not use bulk in aggregation */
+	if (pAd->BulkInMaxPacketSize == 512)
+		UsbCfg.field.RxBulkAggEn = 1;
+	/* for last packet, PBF might use more than limited, so minus 2 to prevent from error */
+	UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE / 1024) - 3;
+	UsbCfg.field.RxBulkAggTOut = 0x80;	/* 2006-10-18 */
+	UsbCfg.field.RxBulkEn = 1;
+	UsbCfg.field.TxBulkEn = 1;
+
+	RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word);
+
+}
+
+/********************************************************************
+  *
+  *	2870 Beacon Update Related functions.
+  *
+  ********************************************************************/
+
+/*
+========================================================================
+Routine Description:
+    Write Beacon buffer to Asic.
+
+Arguments:
+	*pAd				the raxx interface data pointer
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+void RT28xx_UpdateBeaconToAsic(struct rt_rtmp_adapter *pAd,
+			       int apidx,
+			       unsigned long FrameLen, unsigned long UpdatePos)
+{
+	u8 *pBeaconFrame = NULL;
+	u8 *ptr;
+	u32 i, padding;
+	struct rt_beacon_sync *pBeaconSync = pAd->CommonCfg.pBeaconSync;
+	u32 longValue;
+/*      u16                  shortValue; */
+	BOOLEAN bBcnReq = FALSE;
+	u8 bcn_idx = 0;
+
+	if (pBeaconFrame == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR, ("pBeaconFrame is NULL!\n"));
+		return;
+	}
+
+	if (pBeaconSync == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR, ("pBeaconSync is NULL!\n"));
+		return;
+	}
+	/*if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) || */
+	/*      ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP)) */
+	/*      ) */
+	if (bBcnReq == FALSE) {
+		/* when the ra interface is down, do not send its beacon frame */
+		/* clear all zero */
+		for (i = 0; i < TXWI_SIZE; i += 4) {
+			RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i,
+					0x00);
+		}
+		pBeaconSync->BeaconBitMap &=
+		    (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
+		NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE);
+	} else {
+		ptr = (u8 *)& pAd->BeaconTxWI;
+		if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE) {	/* If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames. */
+			pBeaconSync->BeaconBitMap &=
+			    (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
+			NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx],
+				       &pAd->BeaconTxWI, TXWI_SIZE);
+		}
+
+		if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) !=
+		    (1 << bcn_idx)) {
+			for (i = 0; i < TXWI_SIZE; i += 4)	/* 16-byte TXWI field */
+			{
+				longValue =
+				    *ptr + (*(ptr + 1) << 8) +
+				    (*(ptr + 2) << 16) + (*(ptr + 3) << 24);
+				RTMP_IO_WRITE32(pAd,
+						pAd->BeaconOffset[bcn_idx] + i,
+						longValue);
+				ptr += 4;
+			}
+		}
+
+		ptr = pBeaconSync->BeaconBuf[bcn_idx];
+		padding = (FrameLen & 0x01);
+		NdisZeroMemory((u8 *)(pBeaconFrame + FrameLen), padding);
+		FrameLen += padding;
+		for (i = 0; i < FrameLen /*HW_BEACON_OFFSET */ ; i += 2) {
+			if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE) {
+				NdisMoveMemory(ptr, pBeaconFrame, 2);
+				/*shortValue = *ptr + (*(ptr+1)<<8); */
+				/*RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue); */
+				RTUSBMultiWrite(pAd,
+						pAd->BeaconOffset[bcn_idx] +
+						TXWI_SIZE + i, ptr, 2);
+			}
+			ptr += 2;
+			pBeaconFrame += 2;
+		}
+
+		pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
+
+		/* For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame. */
+	}
+
+}
+
+void RTUSBBssBeaconStop(struct rt_rtmp_adapter *pAd)
+{
+	struct rt_beacon_sync *pBeaconSync;
+	int i, offset;
+	BOOLEAN Cancelled = TRUE;
+
+	pBeaconSync = pAd->CommonCfg.pBeaconSync;
+	if (pBeaconSync && pBeaconSync->EnableBeacon) {
+		int NumOfBcn;
+
+		{
+			NumOfBcn = MAX_MESH_NUM;
+		}
+
+		RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
+
+		for (i = 0; i < NumOfBcn; i++) {
+			NdisZeroMemory(pBeaconSync->BeaconBuf[i],
+				       HW_BEACON_OFFSET);
+			NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
+
+			for (offset = 0; offset < HW_BEACON_OFFSET; offset += 4)
+				RTMP_IO_WRITE32(pAd,
+						pAd->BeaconOffset[i] + offset,
+						0x00);
+
+			pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
+			pBeaconSync->TimIELocationInBeacon[i] = 0;
+		}
+		pBeaconSync->BeaconBitMap = 0;
+		pBeaconSync->DtimBitOn = 0;
+	}
+}
+
+void RTUSBBssBeaconStart(struct rt_rtmp_adapter *pAd)
+{
+	int apidx;
+	struct rt_beacon_sync *pBeaconSync;
+/*      LARGE_INTEGER   tsfTime, deltaTime; */
+
+	pBeaconSync = pAd->CommonCfg.pBeaconSync;
+	if (pBeaconSync && pBeaconSync->EnableBeacon) {
+		int NumOfBcn;
+
+		{
+			NumOfBcn = MAX_MESH_NUM;
+		}
+
+		for (apidx = 0; apidx < NumOfBcn; apidx++) {
+			u8 CapabilityInfoLocationInBeacon = 0;
+			u8 TimIELocationInBeacon = 0;
+
+			NdisZeroMemory(pBeaconSync->BeaconBuf[apidx],
+				       HW_BEACON_OFFSET);
+			pBeaconSync->CapabilityInfoLocationInBeacon[apidx] =
+			    CapabilityInfoLocationInBeacon;
+			pBeaconSync->TimIELocationInBeacon[apidx] =
+			    TimIELocationInBeacon;
+			NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx],
+				       TXWI_SIZE);
+		}
+		pBeaconSync->BeaconBitMap = 0;
+		pBeaconSync->DtimBitOn = 0;
+		pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE;
+
+		pAd->CommonCfg.BeaconAdjust = 0;
+		pAd->CommonCfg.BeaconFactor =
+		    0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10);
+		pAd->CommonCfg.BeaconRemain =
+		    (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1;
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("RTUSBBssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n",
+			  pAd->CommonCfg.BeaconFactor,
+			  pAd->CommonCfg.BeaconRemain));
+		RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer,
+			     10 /*pAd->CommonCfg.BeaconPeriod */ );
+
+	}
+}
+
+void RTUSBBssBeaconInit(struct rt_rtmp_adapter *pAd)
+{
+	struct rt_beacon_sync *pBeaconSync;
+	int i;
+
+	os_alloc_mem(pAd, (u8 **) (&pAd->CommonCfg.pBeaconSync),
+		     sizeof(struct rt_beacon_sync));
+	/*NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(struct rt_beacon_sync), MEM_ALLOC_FLAG); */
+	if (pAd->CommonCfg.pBeaconSync) {
+		pBeaconSync = pAd->CommonCfg.pBeaconSync;
+		NdisZeroMemory(pBeaconSync, sizeof(struct rt_beacon_sync));
+		for (i = 0; i < HW_BEACON_MAX_COUNT; i++) {
+			NdisZeroMemory(pBeaconSync->BeaconBuf[i],
+				       HW_BEACON_OFFSET);
+			pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
+			pBeaconSync->TimIELocationInBeacon[i] = 0;
+			NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
+		}
+		pBeaconSync->BeaconBitMap = 0;
+
+		/*RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE); */
+		pBeaconSync->EnableBeacon = TRUE;
+	}
+}
+
+void RTUSBBssBeaconExit(struct rt_rtmp_adapter *pAd)
+{
+	struct rt_beacon_sync *pBeaconSync;
+	BOOLEAN Cancelled = TRUE;
+	int i;
+
+	if (pAd->CommonCfg.pBeaconSync) {
+		pBeaconSync = pAd->CommonCfg.pBeaconSync;
+		pBeaconSync->EnableBeacon = FALSE;
+		RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
+		pBeaconSync->BeaconBitMap = 0;
+
+		for (i = 0; i < HW_BEACON_MAX_COUNT; i++) {
+			NdisZeroMemory(pBeaconSync->BeaconBuf[i],
+				       HW_BEACON_OFFSET);
+			pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
+			pBeaconSync->TimIELocationInBeacon[i] = 0;
+			NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
+		}
+
+		os_free_mem(pAd, pAd->CommonCfg.pBeaconSync);
+		pAd->CommonCfg.pBeaconSync = NULL;
+	}
+}
+
+/*
+    ========================================================================
+    Routine Description:
+        For device work as AP mode but didn't have TBTT interrupt event, we need a mechanism
+        to update the beacon context in each Beacon interval. Here we use a periodical timer
+        to simulate the TBTT interrupt to handle the beacon context update.
+
+    Arguments:
+        SystemSpecific1         - Not used.
+        FunctionContext         - Pointer to our Adapter context.
+        SystemSpecific2         - Not used.
+        SystemSpecific3         - Not used.
+
+    Return Value:
+        None
+
+    ========================================================================
+*/
+void BeaconUpdateExec(void *SystemSpecific1,
+		      void *FunctionContext,
+		      void *SystemSpecific2, void *SystemSpecific3)
+{
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
+	LARGE_INTEGER tsfTime_a;	/*, tsfTime_b, deltaTime_exp, deltaTime_ab; */
+	u32 delta, delta2MS, period2US, remain, remain_low, remain_high;
+/*      BOOLEAN                 positive; */
+
+	if (pAd->CommonCfg.IsUpdateBeacon == TRUE) {
+		ReSyncBeaconTime(pAd);
+
+	}
+
+	RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart);
+	RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart);
+
+	/*positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp); */
+	period2US = (pAd->CommonCfg.BeaconPeriod << 10);
+	remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart;
+	remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10);
+	remain =
+	    (remain_high + remain_low) % (pAd->CommonCfg.BeaconPeriod << 10);
+	delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain;
+
+	delta2MS = (delta >> 10);
+	if (delta2MS > 150) {
+		pAd->CommonCfg.BeaconUpdateTimer.TimerValue = 100;
+		pAd->CommonCfg.IsUpdateBeacon = FALSE;
+	} else {
+		pAd->CommonCfg.BeaconUpdateTimer.TimerValue = delta2MS + 10;
+		pAd->CommonCfg.IsUpdateBeacon = TRUE;
+	}
+
+}
+
+/********************************************************************
+  *
+  *	2870 Radio on/off Related functions.
+  *
+  ********************************************************************/
+void RT28xxUsbMlmeRadioOn(struct rt_rtmp_adapter *pAd)
+{
+	struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("RT28xxUsbMlmeRadioOn()\n"));
+
+	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+		return;
+
+	{
+		AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
+		RTMPusecDelay(10000);
+	}
+	/*NICResetFromError(pAd); */
+
+	/* Enable Tx/Rx */
+	RTMPEnableRxTx(pAd);
+
+	if (pChipOps->AsicReverseRfFromSleepMode)
+		pChipOps->AsicReverseRfFromSleepMode(pAd);
+
+	/* Clear Radio off flag */
+	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
+	RTUSBBulkReceive(pAd);
+
+	/* Set LED */
+	RTMPSetLED(pAd, LED_RADIO_ON);
+}
+
+void RT28xxUsbMlmeRadioOFF(struct rt_rtmp_adapter *pAd)
+{
+	WPDMA_GLO_CFG_STRUC GloCfg;
+	u32 Value, i;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("RT28xxUsbMlmeRadioOFF()\n"));
+
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+		return;
+
+	/* Clear PMKID cache. */
+	pAd->StaCfg.SavedPMKNum = 0;
+	RTMPZeroMemory(pAd->StaCfg.SavedPMK, (PMKID_NO * sizeof(struct rt_bssid_info)));
+
+	/* Link down first if any association exists */
+	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
+		if (INFRA_ON(pAd) || ADHOC_ON(pAd)) {
+			struct rt_mlme_disassoc_req DisReq;
+			struct rt_mlme_queue_elem *pMsgElem =
+			    (struct rt_mlme_queue_elem *)kmalloc(sizeof(struct rt_mlme_queue_elem),
+							MEM_ALLOC_FLAG);
+
+			if (pMsgElem) {
+				COPY_MAC_ADDR(&DisReq.Addr,
+					      pAd->CommonCfg.Bssid);
+				DisReq.Reason = REASON_DISASSOC_STA_LEAVING;
+
+				pMsgElem->Machine = ASSOC_STATE_MACHINE;
+				pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
+				pMsgElem->MsgLen =
+				    sizeof(struct rt_mlme_disassoc_req);
+				NdisMoveMemory(pMsgElem->Msg, &DisReq,
+					       sizeof
+					       (struct rt_mlme_disassoc_req));
+
+				MlmeDisassocReqAction(pAd, pMsgElem);
+				kfree(pMsgElem);
+
+				RTMPusecDelay(1000);
+			}
+		}
+	}
+	/* Set Radio off flag */
+	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
+	{
+		/* Link down first if any association exists */
+		if (INFRA_ON(pAd) || ADHOC_ON(pAd))
+			LinkDown(pAd, FALSE);
+		RTMPusecDelay(10000);
+
+		/*========================================== */
+		/* Clean up old bss table */
+		BssTableInit(&pAd->ScanTab);
+	}
+
+	/* Set LED */
+	RTMPSetLED(pAd, LED_RADIO_OFF);
+
+	if (pAd->CommonCfg.BBPCurrentBW == BW_40) {
+		/* Must using 40MHz. */
+		AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
+	} else {
+		/* Must using 20MHz. */
+		AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
+	}
+
+	/* Disable Tx/Rx DMA */
+	RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word);	/* disable DMA */
+	GloCfg.field.EnableTxDMA = 0;
+	GloCfg.field.EnableRxDMA = 0;
+	RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word);	/* abort all TX rings */
+
+	/* Waiting for DMA idle */
+	i = 0;
+	do {
+		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
+		if ((GloCfg.field.TxDMABusy == 0)
+		    && (GloCfg.field.RxDMABusy == 0))
+			break;
+
+		RTMPusecDelay(1000);
+	} while (i++ < 100);
+
+	/* Disable MAC Tx/Rx */
+	RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+	Value &= (0xfffffff3);
+	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+	{
+		AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
+	}
+}
+
+#endif /* RTMP_MAC_USB // */
diff --git a/drivers/staging/rt2860/common/cmm_sanity.c b/drivers/staging/rt2860/common/cmm_sanity.c
index 85855f7f..6b003c9 100644
--- a/drivers/staging/rt2860/common/cmm_sanity.c
+++ b/drivers/staging/rt2860/common/cmm_sanity.c
@@ -36,17 +36,16 @@
 */
 #include "../rt_config.h"
 
+extern u8 CISCO_OUI[];
 
-extern UCHAR	CISCO_OUI[];
-
-extern UCHAR	WPA_OUI[];
-extern UCHAR	RSN_OUI[];
-extern UCHAR	WME_INFO_ELEM[];
-extern UCHAR	WME_PARM_ELEM[];
-extern UCHAR	Ccx2QosInfo[];
-extern UCHAR	RALINK_OUI[];
-extern UCHAR	BROADCOM_OUI[];
-extern UCHAR    WPS_OUI[];
+extern u8 WPA_OUI[];
+extern u8 RSN_OUI[];
+extern u8 WME_INFO_ELEM[];
+extern u8 WME_PARM_ELEM[];
+extern u8 Ccx2QosInfo[];
+extern u8 RALINK_OUI[];
+extern u8 BROADCOM_OUI[];
+extern u8 WPS_OUI[];
 
 /*
     ==========================================================================
@@ -59,173 +58,172 @@
 
     ==========================================================================
  */
-BOOLEAN MlmeAddBAReqSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pAddr2)
+BOOLEAN MlmeAddBAReqSanity(struct rt_rtmp_adapter *pAd,
+			   void * Msg, unsigned long MsgLen, u8 *pAddr2)
 {
-    PMLME_ADDBA_REQ_STRUCT   pInfo;
+	struct rt_mlme_addba_req *pInfo;
 
-    pInfo = (MLME_ADDBA_REQ_STRUCT *)Msg;
+	pInfo = (struct rt_mlme_addba_req *)Msg;
 
-    if ((MsgLen != sizeof(MLME_ADDBA_REQ_STRUCT)))
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - message lenght not correct.\n"));
-        return FALSE;
-    }
-
-    if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE))
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - The peer Mac is not associated yet.\n"));
-        return FALSE;
-    }
-
-    if ((pInfo->pAddr[0]&0x01) == 0x01)
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - broadcast address not support BA\n"));
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-BOOLEAN MlmeDelBAReqSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen)
-{
-	MLME_DELBA_REQ_STRUCT *pInfo;
-	pInfo = (MLME_DELBA_REQ_STRUCT *)Msg;
-
-    if ((MsgLen != sizeof(MLME_DELBA_REQ_STRUCT)))
-    {
-        DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - message lenght not correct.\n"));
-        return FALSE;
-    }
-
-    if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE))
-    {
-        DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer Mac is not associated yet.\n"));
-        return FALSE;
-    }
-
-    if ((pInfo->TID & 0xf0))
-    {
-        DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer TID is incorrect.\n"));
-        return FALSE;
-    }
-
-	if (NdisEqualMemory(pAd->MacTab.Content[pInfo->Wcid].Addr, pInfo->Addr, MAC_ADDR_LEN) == 0)
-    {
-        DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - the peer addr dosen't exist.\n"));
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-BOOLEAN PeerAddBAReqActionSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *pMsg,
-    IN ULONG MsgLen,
-	OUT PUCHAR pAddr2)
-{
-	PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
-	PFRAME_ADDBA_REQ pAddFrame;
-	pAddFrame = (PFRAME_ADDBA_REQ)(pMsg);
-	if (MsgLen < (sizeof(FRAME_ADDBA_REQ)))
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request frame length size = %ld incorrect\n", MsgLen));
+	if ((MsgLen != sizeof(struct rt_mlme_addba_req))) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("MlmeAddBAReqSanity fail - message lenght not correct.\n"));
 		return FALSE;
 	}
-	// we support immediate BA.
-	*(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm));
+
+	if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE)) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("MlmeAddBAReqSanity fail - The peer Mac is not associated yet.\n"));
+		return FALSE;
+	}
+
+	if ((pInfo->pAddr[0] & 0x01) == 0x01) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("MlmeAddBAReqSanity fail - broadcast address not support BA\n"));
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        MLME message sanity check
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+BOOLEAN MlmeDelBAReqSanity(struct rt_rtmp_adapter *pAd, void * Msg, unsigned long MsgLen)
+{
+	struct rt_mlme_delba_req *pInfo;
+	pInfo = (struct rt_mlme_delba_req *)Msg;
+
+	if ((MsgLen != sizeof(struct rt_mlme_delba_req))) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("MlmeDelBAReqSanity fail - message lenght not correct.\n"));
+		return FALSE;
+	}
+
+	if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE)) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("MlmeDelBAReqSanity fail - The peer Mac is not associated yet.\n"));
+		return FALSE;
+	}
+
+	if ((pInfo->TID & 0xf0)) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("MlmeDelBAReqSanity fail - The peer TID is incorrect.\n"));
+		return FALSE;
+	}
+
+	if (NdisEqualMemory
+	    (pAd->MacTab.Content[pInfo->Wcid].Addr, pInfo->Addr,
+	     MAC_ADDR_LEN) == 0) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("MlmeDelBAReqSanity fail - the peer addr dosen't exist.\n"));
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+BOOLEAN PeerAddBAReqActionSanity(struct rt_rtmp_adapter *pAd,
+				 void * pMsg,
+				 unsigned long MsgLen, u8 *pAddr2)
+{
+	struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) pMsg;
+	struct rt_frame_addba_req * pAddFrame;
+	pAddFrame = (struct rt_frame_addba_req *) (pMsg);
+	if (MsgLen < (sizeof(struct rt_frame_addba_req))) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("PeerAddBAReqActionSanity: ADDBA Request frame length size = %ld incorrect\n",
+			  MsgLen));
+		return FALSE;
+	}
+	/* we support immediate BA. */
+	*(u16 *) (&pAddFrame->BaParm) =
+	    cpu2le16(*(u16 *) (&pAddFrame->BaParm));
 	pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue);
 	pAddFrame->BaStartSeq.word = cpu2le16(pAddFrame->BaStartSeq.word);
 
-	if (pAddFrame->BaParm.BAPolicy != IMMED_BA)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request Ba Policy[%d] not support\n", pAddFrame->BaParm.BAPolicy));
-		DBGPRINT(RT_DEBUG_ERROR,("ADDBA Request. tid=%x, Bufsize=%x, AMSDUSupported=%x \n", pAddFrame->BaParm.TID, pAddFrame->BaParm.BufSize, pAddFrame->BaParm.AMSDUSupported));
+	if (pAddFrame->BaParm.BAPolicy != IMMED_BA) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("PeerAddBAReqActionSanity: ADDBA Request Ba Policy[%d] not support\n",
+			  pAddFrame->BaParm.BAPolicy));
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("ADDBA Request. tid=%x, Bufsize=%x, AMSDUSupported=%x \n",
+			  pAddFrame->BaParm.TID, pAddFrame->BaParm.BufSize,
+			  pAddFrame->BaParm.AMSDUSupported));
 		return FALSE;
 	}
-
-	// we support immediate BA.
-	if (pAddFrame->BaParm.TID &0xfff0)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request incorrect TID = %d\n", pAddFrame->BaParm.TID));
+	/* we support immediate BA. */
+	if (pAddFrame->BaParm.TID & 0xfff0) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("PeerAddBAReqActionSanity: ADDBA Request incorrect TID = %d\n",
+			  pAddFrame->BaParm.TID));
 		return FALSE;
 	}
 	COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
 	return TRUE;
 }
 
-BOOLEAN PeerAddBARspActionSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *pMsg,
-    IN ULONG MsgLen)
+BOOLEAN PeerAddBARspActionSanity(struct rt_rtmp_adapter *pAd,
+				 void * pMsg, unsigned long MsgLen)
 {
-	PFRAME_ADDBA_RSP pAddFrame;
+	struct rt_frame_addba_rsp * pAddFrame;
 
-	pAddFrame = (PFRAME_ADDBA_RSP)(pMsg);
-	if (MsgLen < (sizeof(FRAME_ADDBA_RSP)))
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("PeerAddBARspActionSanity: ADDBA Response frame length size = %ld incorrect\n", MsgLen));
+	pAddFrame = (struct rt_frame_addba_rsp *) (pMsg);
+	if (MsgLen < (sizeof(struct rt_frame_addba_rsp))) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("PeerAddBARspActionSanity: ADDBA Response frame length size = %ld incorrect\n",
+			  MsgLen));
 		return FALSE;
 	}
-	// we support immediate BA.
-	*(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm));
+	/* we support immediate BA. */
+	*(u16 *) (&pAddFrame->BaParm) =
+	    cpu2le16(*(u16 *) (&pAddFrame->BaParm));
 	pAddFrame->StatusCode = cpu2le16(pAddFrame->StatusCode);
 	pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue);
 
-	if (pAddFrame->BaParm.BAPolicy != IMMED_BA)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Response Ba Policy[%d] not support\n", pAddFrame->BaParm.BAPolicy));
+	if (pAddFrame->BaParm.BAPolicy != IMMED_BA) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("PeerAddBAReqActionSanity: ADDBA Response Ba Policy[%d] not support\n",
+			  pAddFrame->BaParm.BAPolicy));
 		return FALSE;
 	}
-
-	// we support immediate BA.
-	if (pAddFrame->BaParm.TID &0xfff0)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("PeerAddBARspActionSanity: ADDBA Response incorrect TID = %d\n", pAddFrame->BaParm.TID));
+	/* we support immediate BA. */
+	if (pAddFrame->BaParm.TID & 0xfff0) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("PeerAddBARspActionSanity: ADDBA Response incorrect TID = %d\n",
+			  pAddFrame->BaParm.TID));
 		return FALSE;
 	}
 	return TRUE;
 
 }
 
-BOOLEAN PeerDelBAActionSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN UCHAR Wcid,
-    IN VOID *pMsg,
-    IN ULONG MsgLen )
+BOOLEAN PeerDelBAActionSanity(struct rt_rtmp_adapter *pAd,
+			      u8 Wcid, void * pMsg, unsigned long MsgLen)
 {
-	//PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
-	PFRAME_DELBA_REQ  pDelFrame;
-	if (MsgLen != (sizeof(FRAME_DELBA_REQ)))
+	/*struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *)pMsg; */
+	struct rt_frame_delba_req * pDelFrame;
+	if (MsgLen != (sizeof(struct rt_frame_delba_req)))
 		return FALSE;
 
 	if (Wcid >= MAX_LEN_OF_MAC_TABLE)
 		return FALSE;
 
-	pDelFrame = (PFRAME_DELBA_REQ)(pMsg);
+	pDelFrame = (struct rt_frame_delba_req *) (pMsg);
 
-	*(USHORT *)(&pDelFrame->DelbaParm) = cpu2le16(*(USHORT *)(&pDelFrame->DelbaParm));
+	*(u16 *) (&pDelFrame->DelbaParm) =
+	    cpu2le16(*(u16 *) (&pDelFrame->DelbaParm));
 	pDelFrame->ReasonCode = cpu2le16(pDelFrame->ReasonCode);
 
-	if (pDelFrame->DelbaParm.TID &0xfff0)
+	if (pDelFrame->DelbaParm.TID & 0xfff0)
 		return FALSE;
 
 	return TRUE;
@@ -242,472 +240,469 @@
 
     ==========================================================================
  */
-BOOLEAN PeerBeaconAndProbeRspSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    IN UCHAR  MsgChannel,
-    OUT PUCHAR pAddr2,
-    OUT PUCHAR pBssid,
-    OUT CHAR Ssid[],
-    OUT UCHAR *pSsidLen,
-    OUT UCHAR *pBssType,
-    OUT USHORT *pBeaconPeriod,
-    OUT UCHAR *pChannel,
-    OUT UCHAR *pNewChannel,
-    OUT LARGE_INTEGER *pTimestamp,
-    OUT CF_PARM *pCfParm,
-    OUT USHORT *pAtimWin,
-    OUT USHORT *pCapabilityInfo,
-    OUT UCHAR *pErp,
-    OUT UCHAR *pDtimCount,
-    OUT UCHAR *pDtimPeriod,
-    OUT UCHAR *pBcastFlag,
-    OUT UCHAR *pMessageToMe,
-    OUT UCHAR SupRate[],
-    OUT UCHAR *pSupRateLen,
-    OUT UCHAR ExtRate[],
-    OUT UCHAR *pExtRateLen,
-    OUT	UCHAR *pCkipFlag,
-    OUT	UCHAR *pAironetCellPowerLimit,
-    OUT PEDCA_PARM       pEdcaParm,
-    OUT PQBSS_LOAD_PARM  pQbssLoad,
-    OUT PQOS_CAPABILITY_PARM pQosCapability,
-    OUT ULONG *pRalinkIe,
-    OUT UCHAR		 *pHtCapabilityLen,
-    OUT UCHAR		 *pPreNHtCapabilityLen,
-    OUT HT_CAPABILITY_IE *pHtCapability,
-	OUT UCHAR		 *AddHtInfoLen,
-	OUT ADD_HT_INFO_IE *AddHtInfo,
-	OUT UCHAR *NewExtChannelOffset,		// Ht extension channel offset(above or below)
-    OUT USHORT *LengthVIE,
-    OUT	PNDIS_802_11_VARIABLE_IEs pVIE)
+BOOLEAN PeerBeaconAndProbeRspSanity(struct rt_rtmp_adapter *pAd, void * Msg, unsigned long MsgLen, u8 MsgChannel, u8 *pAddr2, u8 *pBssid, char Ssid[], u8 * pSsidLen, u8 * pBssType, u16 * pBeaconPeriod, u8 * pChannel, u8 * pNewChannel, OUT LARGE_INTEGER * pTimestamp, struct rt_cf_parm * pCfParm, u16 * pAtimWin, u16 * pCapabilityInfo, u8 * pErp, u8 * pDtimCount, u8 * pDtimPeriod, u8 * pBcastFlag, u8 * pMessageToMe, u8 SupRate[], u8 * pSupRateLen, u8 ExtRate[], u8 * pExtRateLen, u8 * pCkipFlag, u8 * pAironetCellPowerLimit, struct rt_edca_parm *pEdcaParm, struct rt_qbss_load_parm *pQbssLoad, struct rt_qos_capability_parm *pQosCapability, unsigned long * pRalinkIe, u8 * pHtCapabilityLen, u8 * pPreNHtCapabilityLen, struct rt_ht_capability_ie * pHtCapability, u8 * AddHtInfoLen, struct rt_add_ht_info_ie * AddHtInfo, u8 * NewExtChannelOffset,	/* Ht extension channel offset(above or below) */
+				    u16 * LengthVIE,
+				    struct rt_ndis_802_11_variable_ies *pVIE)
 {
-    CHAR				*Ptr;
-	CHAR 				TimLen;
-    PFRAME_802_11		pFrame;
-    PEID_STRUCT         pEid;
-    UCHAR				SubType;
-    UCHAR				Sanity;
-    //UCHAR				ECWMin, ECWMax;
-    //MAC_CSR9_STRUC		Csr9;
-    ULONG				Length = 0;
+	u8 *Ptr;
+	u8 TimLen;
+	struct rt_frame_802_11 * pFrame;
+	struct rt_eid * pEid;
+	u8 SubType;
+	u8 Sanity;
+	/*u8                             ECWMin, ECWMax; */
+	/*MAC_CSR9_STRUC            Csr9; */
+	unsigned long Length = 0;
 
-	// For some 11a AP which didn't have DS_IE, we use two conditions to decide the channel
-	//	1. If the AP is 11n enabled, then check the control channel.
-	//	2. If the AP didn't have any info about channel, use the channel we received this frame as the channel. (May inaccuracy!!)
-	UCHAR			CtrlChannel = 0;
+	/* For some 11a AP which didn't have DS_IE, we use two conditions to decide the channel */
+	/*      1. If the AP is 11n enabled, then check the control channel. */
+	/*      2. If the AP didn't have any info about channel, use the channel we received this frame as the channel. (May inaccuracy!) */
+	u8 CtrlChannel = 0;
 
-    // Add for 3 necessary EID field check
-    Sanity = 0;
+	/* Add for 3 necessary EID field check */
+	Sanity = 0;
 
-    *pAtimWin = 0;
-    *pErp = 0;
-    *pDtimCount = 0;
-    *pDtimPeriod = 0;
-    *pBcastFlag = 0;
-    *pMessageToMe = 0;
-    *pExtRateLen = 0;
-    *pCkipFlag = 0;			        // Default of CkipFlag is 0
-    *pAironetCellPowerLimit = 0xFF;  // Default of AironetCellPowerLimit is 0xFF
-    *LengthVIE = 0;					// Set the length of VIE to init value 0
-    *pHtCapabilityLen = 0;					// Set the length of VIE to init value 0
+	*pAtimWin = 0;
+	*pErp = 0;
+	*pDtimCount = 0;
+	*pDtimPeriod = 0;
+	*pBcastFlag = 0;
+	*pMessageToMe = 0;
+	*pExtRateLen = 0;
+	*pCkipFlag = 0;		/* Default of CkipFlag is 0 */
+	*pAironetCellPowerLimit = 0xFF;	/* Default of AironetCellPowerLimit is 0xFF */
+	*LengthVIE = 0;		/* Set the length of VIE to init value 0 */
+	*pHtCapabilityLen = 0;	/* Set the length of VIE to init value 0 */
 	if (pAd->OpMode == OPMODE_STA)
-		*pPreNHtCapabilityLen = 0;					// Set the length of VIE to init value 0
-    *AddHtInfoLen = 0;					// Set the length of VIE to init value 0
-    *pRalinkIe = 0;
-    *pNewChannel = 0;
-    *NewExtChannelOffset = 0xff;	//Default 0xff means no such IE
-    pCfParm->bValid = FALSE;        // default: no IE_CF found
-    pQbssLoad->bValid = FALSE;      // default: no IE_QBSS_LOAD found
-    pEdcaParm->bValid = FALSE;      // default: no IE_EDCA_PARAMETER found
-    pQosCapability->bValid = FALSE; // default: no IE_QOS_CAPABILITY found
+		*pPreNHtCapabilityLen = 0;	/* Set the length of VIE to init value 0 */
+	*AddHtInfoLen = 0;	/* Set the length of VIE to init value 0 */
+	*pRalinkIe = 0;
+	*pNewChannel = 0;
+	*NewExtChannelOffset = 0xff;	/*Default 0xff means no such IE */
+	pCfParm->bValid = FALSE;	/* default: no IE_CF found */
+	pQbssLoad->bValid = FALSE;	/* default: no IE_QBSS_LOAD found */
+	pEdcaParm->bValid = FALSE;	/* default: no IE_EDCA_PARAMETER found */
+	pQosCapability->bValid = FALSE;	/* default: no IE_QOS_CAPABILITY found */
 
-    pFrame = (PFRAME_802_11)Msg;
+	pFrame = (struct rt_frame_802_11 *) Msg;
 
-    // get subtype from header
-    SubType = (UCHAR)pFrame->Hdr.FC.SubType;
+	/* get subtype from header */
+	SubType = (u8)pFrame->Hdr.FC.SubType;
 
-    // get Addr2 and BSSID from header
-    COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
-    COPY_MAC_ADDR(pBssid, pFrame->Hdr.Addr3);
+	/* get Addr2 and BSSID from header */
+	COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+	COPY_MAC_ADDR(pBssid, pFrame->Hdr.Addr3);
 
-    Ptr = pFrame->Octet;
-    Length += LENGTH_802_11;
+	Ptr = pFrame->Octet;
+	Length += LENGTH_802_11;
 
-    // get timestamp from payload and advance the pointer
-    NdisMoveMemory(pTimestamp, Ptr, TIMESTAMP_LEN);
+	/* get timestamp from payload and advance the pointer */
+	NdisMoveMemory(pTimestamp, Ptr, TIMESTAMP_LEN);
 
 	pTimestamp->u.LowPart = cpu2le32(pTimestamp->u.LowPart);
 	pTimestamp->u.HighPart = cpu2le32(pTimestamp->u.HighPart);
 
-    Ptr += TIMESTAMP_LEN;
-    Length += TIMESTAMP_LEN;
+	Ptr += TIMESTAMP_LEN;
+	Length += TIMESTAMP_LEN;
 
-    // get beacon interval from payload and advance the pointer
-    NdisMoveMemory(pBeaconPeriod, Ptr, 2);
-    Ptr += 2;
-    Length += 2;
+	/* get beacon interval from payload and advance the pointer */
+	NdisMoveMemory(pBeaconPeriod, Ptr, 2);
+	Ptr += 2;
+	Length += 2;
 
-    // get capability info from payload and advance the pointer
-    NdisMoveMemory(pCapabilityInfo, Ptr, 2);
-    Ptr += 2;
-    Length += 2;
+	/* get capability info from payload and advance the pointer */
+	NdisMoveMemory(pCapabilityInfo, Ptr, 2);
+	Ptr += 2;
+	Length += 2;
 
-    if (CAP_IS_ESS_ON(*pCapabilityInfo))
-        *pBssType = BSS_INFRA;
-    else
-        *pBssType = BSS_ADHOC;
+	if (CAP_IS_ESS_ON(*pCapabilityInfo))
+		*pBssType = BSS_INFRA;
+	else
+		*pBssType = BSS_ADHOC;
 
-    pEid = (PEID_STRUCT) Ptr;
+	pEid = (struct rt_eid *) Ptr;
 
-    // get variable fields from payload and advance the pointer
-    while ((Length + 2 + pEid->Len) <= MsgLen)
-    {
-        //
-        // Secure copy VIE to VarIE[MAX_VIE_LEN] didn't overflow.
-        //
-        if ((*LengthVIE + pEid->Len + 2) >= MAX_VIE_LEN)
-        {
-            DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - Variable IEs out of resource [len(=%d) > MAX_VIE_LEN(=%d)]\n",
-                    (*LengthVIE + pEid->Len + 2), MAX_VIE_LEN));
-            break;
-        }
+	/* get variable fields from payload and advance the pointer */
+	while ((Length + 2 + pEid->Len) <= MsgLen) {
+		/* */
+		/* Secure copy VIE to VarIE[MAX_VIE_LEN] didn't overflow. */
+		/* */
+		if ((*LengthVIE + pEid->Len + 2) >= MAX_VIE_LEN) {
+			DBGPRINT(RT_DEBUG_WARN,
+				 ("PeerBeaconAndProbeRspSanity - Variable IEs out of resource [len(=%d) > MAX_VIE_LEN(=%d)]\n",
+				  (*LengthVIE + pEid->Len + 2), MAX_VIE_LEN));
+			break;
+		}
 
-        switch(pEid->Eid)
-        {
-            case IE_SSID:
-                // Already has one SSID EID in this beacon, ignore the second one
-                if (Sanity & 0x1)
-                    break;
-                if(pEid->Len <= MAX_LEN_OF_SSID)
-                {
-                    NdisMoveMemory(Ssid, pEid->Octet, pEid->Len);
-                    *pSsidLen = pEid->Len;
-                    Sanity |= 0x1;
-                }
-                else
-                {
-                    DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",pEid->Len));
-                    return FALSE;
-                }
-                break;
+		switch (pEid->Eid) {
+		case IE_SSID:
+			/* Already has one SSID EID in this beacon, ignore the second one */
+			if (Sanity & 0x1)
+				break;
+			if (pEid->Len <= MAX_LEN_OF_SSID) {
+				NdisMoveMemory(Ssid, pEid->Octet, pEid->Len);
+				*pSsidLen = pEid->Len;
+				Sanity |= 0x1;
+			} else {
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",
+					  pEid->Len));
+				return FALSE;
+			}
+			break;
 
-            case IE_SUPP_RATES:
-                if(pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
-                {
-                    Sanity |= 0x2;
-                    NdisMoveMemory(SupRate, pEid->Octet, pEid->Len);
-                    *pSupRateLen = pEid->Len;
+		case IE_SUPP_RATES:
+			if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) {
+				Sanity |= 0x2;
+				NdisMoveMemory(SupRate, pEid->Octet, pEid->Len);
+				*pSupRateLen = pEid->Len;
 
-                    // TODO: 2004-09-14 not a good design here, cause it exclude extra rates
-                    // from ScanTab. We should report as is. And filter out unsupported
-                    // rates in MlmeAux.
-                    // Check against the supported rates
-                    // RTMPCheckRates(pAd, SupRate, pSupRateLen);
-                }
-                else
-                {
-                    DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SUPP_RATES (len=%d)\n",pEid->Len));
-                    return FALSE;
-                }
-                break;
+				/* TODO: 2004-09-14 not a good design here, cause it exclude extra rates */
+				/* from ScanTab. We should report as is. And filter out unsupported */
+				/* rates in MlmeAux. */
+				/* Check against the supported rates */
+				/* RTMPCheckRates(pAd, SupRate, pSupRateLen); */
+			} else {
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("PeerBeaconAndProbeRspSanity - wrong IE_SUPP_RATES (len=%d)\n",
+					  pEid->Len));
+				return FALSE;
+			}
+			break;
 
-            case IE_HT_CAP:
-			if (pEid->Len >= SIZE_HT_CAP_IE)  //Note: allow extension.!!
+		case IE_HT_CAP:
+			if (pEid->Len >= SIZE_HT_CAP_IE)	/*Note: allow extension! */
 			{
-				NdisMoveMemory(pHtCapability, pEid->Octet, sizeof(HT_CAPABILITY_IE));
-				*pHtCapabilityLen = SIZE_HT_CAP_IE;	// Nnow we only support 26 bytes.
+				NdisMoveMemory(pHtCapability, pEid->Octet,
+					       sizeof(struct rt_ht_capability_ie));
+				*pHtCapabilityLen = SIZE_HT_CAP_IE;	/* Nnow we only support 26 bytes. */
 
-				*(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
-				*(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
+				*(u16 *) (&pHtCapability->HtCapInfo) =
+				    cpu2le16(*(u16 *)
+					     (&pHtCapability->HtCapInfo));
+				*(u16 *) (&pHtCapability->ExtHtCapInfo) =
+				    cpu2le16(*(u16 *)
+					     (&pHtCapability->ExtHtCapInfo));
 
 				{
-					*pPreNHtCapabilityLen = 0;	// Nnow we only support 26 bytes.
+					*pPreNHtCapabilityLen = 0;	/* Nnow we only support 26 bytes. */
 
-					Ptr = (PUCHAR) pVIE;
-					NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
+					Ptr = (u8 *)pVIE;
+					NdisMoveMemory(Ptr + *LengthVIE,
+						       &pEid->Eid,
+						       pEid->Len + 2);
 					*LengthVIE += (pEid->Len + 2);
 				}
-			}
-			else
-			{
-				DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_HT_CAP. pEid->Len = %d\n", pEid->Len));
+			} else {
+				DBGPRINT(RT_DEBUG_WARN,
+					 ("PeerBeaconAndProbeRspSanity - wrong IE_HT_CAP. pEid->Len = %d\n",
+					  pEid->Len));
 			}
 
-		break;
-            case IE_ADD_HT:
-			if (pEid->Len >= sizeof(ADD_HT_INFO_IE))
-			{
-				// This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only
-				// copy first sizeof(ADD_HT_INFO_IE)
-				NdisMoveMemory(AddHtInfo, pEid->Octet, sizeof(ADD_HT_INFO_IE));
+			break;
+		case IE_ADD_HT:
+			if (pEid->Len >= sizeof(struct rt_add_ht_info_ie)) {
+				/* This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only */
+				/* copy first sizeof(struct rt_add_ht_info_ie) */
+				NdisMoveMemory(AddHtInfo, pEid->Octet,
+					       sizeof(struct rt_add_ht_info_ie));
 				*AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
 
 				CtrlChannel = AddHtInfo->ControlChan;
 
-				*(USHORT *)(&AddHtInfo->AddHtInfo2) = cpu2le16(*(USHORT *)(&AddHtInfo->AddHtInfo2));
-				*(USHORT *)(&AddHtInfo->AddHtInfo3) = cpu2le16(*(USHORT *)(&AddHtInfo->AddHtInfo3));
+				*(u16 *) (&AddHtInfo->AddHtInfo2) =
+				    cpu2le16(*(u16 *)
+					     (&AddHtInfo->AddHtInfo2));
+				*(u16 *) (&AddHtInfo->AddHtInfo3) =
+				    cpu2le16(*(u16 *)
+					     (&AddHtInfo->AddHtInfo3));
 
 				{
-			                Ptr = (PUCHAR) pVIE;
-			                NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
-			                *LengthVIE += (pEid->Len + 2);
+					Ptr = (u8 *)pVIE;
+					NdisMoveMemory(Ptr + *LengthVIE,
+						       &pEid->Eid,
+						       pEid->Len + 2);
+					*LengthVIE += (pEid->Len + 2);
 				}
-			}
-			else
-			{
-				DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_ADD_HT. \n"));
+			} else {
+				DBGPRINT(RT_DEBUG_WARN,
+					 ("PeerBeaconAndProbeRspSanity - wrong IE_ADD_HT. \n"));
 			}
 
-		break;
-            case IE_SECONDARY_CH_OFFSET:
-			if (pEid->Len == 1)
-			{
+			break;
+		case IE_SECONDARY_CH_OFFSET:
+			if (pEid->Len == 1) {
 				*NewExtChannelOffset = pEid->Octet[0];
-			}
-			else
-			{
-				DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
+			} else {
+				DBGPRINT(RT_DEBUG_WARN,
+					 ("PeerBeaconAndProbeRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
 			}
 
-		break;
-            case IE_FH_PARM:
-                DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity(IE_FH_PARM) \n"));
-                break;
+			break;
+		case IE_FH_PARM:
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("PeerBeaconAndProbeRspSanity(IE_FH_PARM) \n"));
+			break;
 
-            case IE_DS_PARM:
-                if(pEid->Len == 1)
-                {
-                    *pChannel = *pEid->Octet;
+		case IE_DS_PARM:
+			if (pEid->Len == 1) {
+				*pChannel = *pEid->Octet;
 
-					{
-						if (ChannelSanity(pAd, *pChannel) == 0)
-						{
+				{
+					if (ChannelSanity(pAd, *pChannel) == 0) {
 
-							return FALSE;
-						}
+						return FALSE;
 					}
+				}
 
-                    Sanity |= 0x4;
-                }
-                else
-                {
-                    DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_DS_PARM (len=%d)\n",pEid->Len));
-                    return FALSE;
-                }
-                break;
+				Sanity |= 0x4;
+			} else {
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("PeerBeaconAndProbeRspSanity - wrong IE_DS_PARM (len=%d)\n",
+					  pEid->Len));
+				return FALSE;
+			}
+			break;
 
-            case IE_CF_PARM:
-                if(pEid->Len == 6)
-                {
-                    pCfParm->bValid = TRUE;
-                    pCfParm->CfpCount = pEid->Octet[0];
-                    pCfParm->CfpPeriod = pEid->Octet[1];
-                    pCfParm->CfpMaxDuration = pEid->Octet[2] + 256 * pEid->Octet[3];
-                    pCfParm->CfpDurRemaining = pEid->Octet[4] + 256 * pEid->Octet[5];
-                }
-                else
-                {
-                    DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_CF_PARM\n"));
-                    return FALSE;
-                }
-                break;
+		case IE_CF_PARM:
+			if (pEid->Len == 6) {
+				pCfParm->bValid = TRUE;
+				pCfParm->CfpCount = pEid->Octet[0];
+				pCfParm->CfpPeriod = pEid->Octet[1];
+				pCfParm->CfpMaxDuration =
+				    pEid->Octet[2] + 256 * pEid->Octet[3];
+				pCfParm->CfpDurRemaining =
+				    pEid->Octet[4] + 256 * pEid->Octet[5];
+			} else {
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("PeerBeaconAndProbeRspSanity - wrong IE_CF_PARM\n"));
+				return FALSE;
+			}
+			break;
 
-            case IE_IBSS_PARM:
-                if(pEid->Len == 2)
-                {
-                    NdisMoveMemory(pAtimWin, pEid->Octet, pEid->Len);
-                }
-                else
-                {
-                    DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_IBSS_PARM\n"));
-                    return FALSE;
-                }
-                break;
+		case IE_IBSS_PARM:
+			if (pEid->Len == 2) {
+				NdisMoveMemory(pAtimWin, pEid->Octet,
+					       pEid->Len);
+			} else {
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("PeerBeaconAndProbeRspSanity - wrong IE_IBSS_PARM\n"));
+				return FALSE;
+			}
+			break;
 
-            case IE_TIM:
-                if(INFRA_ON(pAd) && SubType == SUBTYPE_BEACON)
-                {
-                    GetTimBit((PUCHAR)pEid, pAd->StaActive.Aid, &TimLen, pBcastFlag, pDtimCount, pDtimPeriod, pMessageToMe);
-                }
-                break;
+		case IE_TIM:
+			if (INFRA_ON(pAd) && SubType == SUBTYPE_BEACON) {
+				GetTimBit((char *)pEid, pAd->StaActive.Aid,
+					  &TimLen, pBcastFlag, pDtimCount,
+					  pDtimPeriod, pMessageToMe);
+			}
+			break;
+		case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
+			if (pEid->Len == 3) {
+				*pNewChannel = pEid->Octet[1];	/*extract new channel number */
+			}
+			break;
 
-            case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
-                if(pEid->Len == 3)
-                {
-                	*pNewChannel = pEid->Octet[1];	//extract new channel number
-                }
-                break;
+			/* New for WPA */
+			/* CCX v2 has the same IE, we need to parse that too */
+			/* Wifi WMM use the same IE vale, need to parse that too */
+			/* case IE_WPA: */
+		case IE_VENDOR_SPECIFIC:
+			/* Check Broadcom/Atheros 802.11n OUI version, for HT Capability IE. */
+			/* This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan. */
+			/*if (NdisEqualMemory(pEid->Octet, BROADCOM_OUI, 3) && (pEid->Len >= 4))
+			   {
+			   if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 30))
+			   {
+			   {
+			   NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(struct rt_ht_capability_ie));
+			   *pHtCapabilityLen = SIZE_HT_CAP_IE;  // Nnow we only support 26 bytes.
+			   }
+			   }
+			   if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 26))
+			   {
+			   {
+			   NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(struct rt_add_ht_info_ie));
+			   *AddHtInfoLen = SIZE_ADD_HT_INFO_IE; // Nnow we only support 26 bytes.
+			   }
+			   }
+			   }
+			 */
+			/* Check the OUI version, filter out non-standard usage */
+			if (NdisEqualMemory(pEid->Octet, RALINK_OUI, 3)
+			    && (pEid->Len == 7)) {
+				/**pRalinkIe = pEid->Octet[3]; */
+				if (pEid->Octet[3] != 0)
+					*pRalinkIe = pEid->Octet[3];
+				else
+					*pRalinkIe = 0xf0000000;	/* Set to non-zero value (can't set bit0-2) to represent this is Ralink Chip. So at linkup, we will set ralinkchip flag. */
+			}
+			/* This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan. */
 
-            // New for WPA
-            // CCX v2 has the same IE, we need to parse that too
-            // Wifi WMM use the same IE vale, need to parse that too
-            // case IE_WPA:
-            case IE_VENDOR_SPECIFIC:
-                // Check the OUI version, filter out non-standard usage
-                if (NdisEqualMemory(pEid->Octet, RALINK_OUI, 3) && (pEid->Len == 7))
-                {
-                    //*pRalinkIe = pEid->Octet[3];
-                    if (pEid->Octet[3] != 0)
-        				*pRalinkIe = pEid->Octet[3];
-        			else
-        				*pRalinkIe = 0xf0000000; // Set to non-zero value (can't set bit0-2) to represent this is Ralink Chip. So at linkup, we will set ralinkchip flag.
-                }
-		// This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan.
+			/* Other vendors had production before IE_HT_CAP value is assigned. To backward support those old-firmware AP, */
+			/* Check broadcom-defiend pre-802.11nD1.0 OUI for HT related IE, including HT Capatilities IE and HT Information IE */
+			else if ((*pHtCapabilityLen == 0)
+				 && NdisEqualMemory(pEid->Octet, PRE_N_HT_OUI,
+						    3) && (pEid->Len >= 4)
+				 && (pAd->OpMode == OPMODE_STA)) {
+				if ((pEid->Octet[3] == OUI_PREN_HT_CAP)
+				    && (pEid->Len >= 30)
+				    && (*pHtCapabilityLen == 0)) {
+					NdisMoveMemory(pHtCapability,
+						       &pEid->Octet[4],
+						       sizeof
+						       (struct rt_ht_capability_ie));
+					*pPreNHtCapabilityLen = SIZE_HT_CAP_IE;
+				}
 
-                // Other vendors had production before IE_HT_CAP value is assigned. To backward support those old-firmware AP,
-                // Check broadcom-defiend pre-802.11nD1.0 OUI for HT related IE, including HT Capatilities IE and HT Information IE
-                else if ((*pHtCapabilityLen == 0) && NdisEqualMemory(pEid->Octet, PRE_N_HT_OUI, 3) && (pEid->Len >= 4) && (pAd->OpMode == OPMODE_STA))
-                {
-                    if ((pEid->Octet[3] == OUI_PREN_HT_CAP) && (pEid->Len >= 30) && (*pHtCapabilityLen == 0))
-                    {
-                        NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(HT_CAPABILITY_IE));
-                        *pPreNHtCapabilityLen = SIZE_HT_CAP_IE;
-                    }
+				if ((pEid->Octet[3] == OUI_PREN_ADD_HT)
+				    && (pEid->Len >= 26)) {
+					NdisMoveMemory(AddHtInfo,
+						       &pEid->Octet[4],
+						       sizeof(struct rt_add_ht_info_ie));
+					*AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
+				}
+			} else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)) {
+				/* Copy to pVIE which will report to microsoft bssid list. */
+				Ptr = (u8 *)pVIE;
+				NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid,
+					       pEid->Len + 2);
+				*LengthVIE += (pEid->Len + 2);
+			} else
+			    if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6)
+				&& (pEid->Len == 24)) {
+				u8 *ptr;
+				int i;
 
-                    if ((pEid->Octet[3] == OUI_PREN_ADD_HT) && (pEid->Len >= 26))
-                    {
-                        NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(ADD_HT_INFO_IE));
-                        *AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
-                    }
-                }
-                else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
-                {
-                    // Copy to pVIE which will report to microsoft bssid list.
-                    Ptr = (PUCHAR) pVIE;
-                    NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
-                    *LengthVIE += (pEid->Len + 2);
-                }
-                else if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) && (pEid->Len == 24))
-                {
-                    PUCHAR ptr;
-                    int i;
+				/* parsing EDCA parameters */
+				pEdcaParm->bValid = TRUE;
+				pEdcaParm->bQAck = FALSE;	/* pEid->Octet[0] & 0x10; */
+				pEdcaParm->bQueueRequest = FALSE;	/* pEid->Octet[0] & 0x20; */
+				pEdcaParm->bTxopRequest = FALSE;	/* pEid->Octet[0] & 0x40; */
+				pEdcaParm->EdcaUpdateCount =
+				    pEid->Octet[6] & 0x0f;
+				pEdcaParm->bAPSDCapable =
+				    (pEid->Octet[6] & 0x80) ? 1 : 0;
+				ptr = &pEid->Octet[8];
+				for (i = 0; i < 4; i++) {
+					u8 aci = (*ptr & 0x60) >> 5;	/* b5~6 is AC INDEX */
+					pEdcaParm->bACM[aci] = (((*ptr) & 0x10) == 0x10);	/* b5 is ACM */
+					pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f;	/* b0~3 is AIFSN */
+					pEdcaParm->Cwmin[aci] = *(ptr + 1) & 0x0f;	/* b0~4 is Cwmin */
+					pEdcaParm->Cwmax[aci] = *(ptr + 1) >> 4;	/* b5~8 is Cwmax */
+					pEdcaParm->Txop[aci] = *(ptr + 2) + 256 * (*(ptr + 3));	/* in unit of 32-us */
+					ptr += 4;	/* point to next AC */
+				}
+			} else
+			    if (NdisEqualMemory(pEid->Octet, WME_INFO_ELEM, 6)
+				&& (pEid->Len == 7)) {
+				/* parsing EDCA parameters */
+				pEdcaParm->bValid = TRUE;
+				pEdcaParm->bQAck = FALSE;	/* pEid->Octet[0] & 0x10; */
+				pEdcaParm->bQueueRequest = FALSE;	/* pEid->Octet[0] & 0x20; */
+				pEdcaParm->bTxopRequest = FALSE;	/* pEid->Octet[0] & 0x40; */
+				pEdcaParm->EdcaUpdateCount =
+				    pEid->Octet[6] & 0x0f;
+				pEdcaParm->bAPSDCapable =
+				    (pEid->Octet[6] & 0x80) ? 1 : 0;
 
-                    // parsing EDCA parameters
-                    pEdcaParm->bValid          = TRUE;
-                    pEdcaParm->bQAck           = FALSE; // pEid->Octet[0] & 0x10;
-                    pEdcaParm->bQueueRequest   = FALSE; // pEid->Octet[0] & 0x20;
-                    pEdcaParm->bTxopRequest    = FALSE; // pEid->Octet[0] & 0x40;
-                    pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
-                    pEdcaParm->bAPSDCapable    = (pEid->Octet[6] & 0x80) ? 1 : 0;
-                    ptr = &pEid->Octet[8];
-                    for (i=0; i<4; i++)
-                    {
-                        UCHAR aci = (*ptr & 0x60) >> 5; // b5~6 is AC INDEX
-                        pEdcaParm->bACM[aci]  = (((*ptr) & 0x10) == 0x10);   // b5 is ACM
-                        pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f;               // b0~3 is AIFSN
-                        pEdcaParm->Cwmin[aci] = *(ptr+1) & 0x0f;             // b0~4 is Cwmin
-                        pEdcaParm->Cwmax[aci] = *(ptr+1) >> 4;               // b5~8 is Cwmax
-                        pEdcaParm->Txop[aci]  = *(ptr+2) + 256 * (*(ptr+3)); // in unit of 32-us
-                        ptr += 4; // point to next AC
-                    }
-                }
-                else if (NdisEqualMemory(pEid->Octet, WME_INFO_ELEM, 6) && (pEid->Len == 7))
-                {
-                    // parsing EDCA parameters
-                    pEdcaParm->bValid          = TRUE;
-                    pEdcaParm->bQAck           = FALSE; // pEid->Octet[0] & 0x10;
-                    pEdcaParm->bQueueRequest   = FALSE; // pEid->Octet[0] & 0x20;
-                    pEdcaParm->bTxopRequest    = FALSE; // pEid->Octet[0] & 0x40;
-                    pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
-                    pEdcaParm->bAPSDCapable    = (pEid->Octet[6] & 0x80) ? 1 : 0;
+				/* use default EDCA parameter */
+				pEdcaParm->bACM[QID_AC_BE] = 0;
+				pEdcaParm->Aifsn[QID_AC_BE] = 3;
+				pEdcaParm->Cwmin[QID_AC_BE] = CW_MIN_IN_BITS;
+				pEdcaParm->Cwmax[QID_AC_BE] = CW_MAX_IN_BITS;
+				pEdcaParm->Txop[QID_AC_BE] = 0;
 
-                    // use default EDCA parameter
-                    pEdcaParm->bACM[QID_AC_BE]  = 0;
-                    pEdcaParm->Aifsn[QID_AC_BE] = 3;
-                    pEdcaParm->Cwmin[QID_AC_BE] = CW_MIN_IN_BITS;
-                    pEdcaParm->Cwmax[QID_AC_BE] = CW_MAX_IN_BITS;
-                    pEdcaParm->Txop[QID_AC_BE]  = 0;
+				pEdcaParm->bACM[QID_AC_BK] = 0;
+				pEdcaParm->Aifsn[QID_AC_BK] = 7;
+				pEdcaParm->Cwmin[QID_AC_BK] = CW_MIN_IN_BITS;
+				pEdcaParm->Cwmax[QID_AC_BK] = CW_MAX_IN_BITS;
+				pEdcaParm->Txop[QID_AC_BK] = 0;
 
-                    pEdcaParm->bACM[QID_AC_BK]  = 0;
-                    pEdcaParm->Aifsn[QID_AC_BK] = 7;
-                    pEdcaParm->Cwmin[QID_AC_BK] = CW_MIN_IN_BITS;
-                    pEdcaParm->Cwmax[QID_AC_BK] = CW_MAX_IN_BITS;
-                    pEdcaParm->Txop[QID_AC_BK]  = 0;
+				pEdcaParm->bACM[QID_AC_VI] = 0;
+				pEdcaParm->Aifsn[QID_AC_VI] = 2;
+				pEdcaParm->Cwmin[QID_AC_VI] =
+				    CW_MIN_IN_BITS - 1;
+				pEdcaParm->Cwmax[QID_AC_VI] = CW_MAX_IN_BITS;
+				pEdcaParm->Txop[QID_AC_VI] = 96;	/* AC_VI: 96*32us ~= 3ms */
 
-                    pEdcaParm->bACM[QID_AC_VI]  = 0;
-                    pEdcaParm->Aifsn[QID_AC_VI] = 2;
-                    pEdcaParm->Cwmin[QID_AC_VI] = CW_MIN_IN_BITS-1;
-                    pEdcaParm->Cwmax[QID_AC_VI] = CW_MAX_IN_BITS;
-                    pEdcaParm->Txop[QID_AC_VI]  = 96;   // AC_VI: 96*32us ~= 3ms
+				pEdcaParm->bACM[QID_AC_VO] = 0;
+				pEdcaParm->Aifsn[QID_AC_VO] = 2;
+				pEdcaParm->Cwmin[QID_AC_VO] =
+				    CW_MIN_IN_BITS - 2;
+				pEdcaParm->Cwmax[QID_AC_VO] =
+				    CW_MAX_IN_BITS - 1;
+				pEdcaParm->Txop[QID_AC_VO] = 48;	/* AC_VO: 48*32us ~= 1.5ms */
+			}
 
-                    pEdcaParm->bACM[QID_AC_VO]  = 0;
-                    pEdcaParm->Aifsn[QID_AC_VO] = 2;
-                    pEdcaParm->Cwmin[QID_AC_VO] = CW_MIN_IN_BITS-2;
-                    pEdcaParm->Cwmax[QID_AC_VO] = CW_MAX_IN_BITS-1;
-                    pEdcaParm->Txop[QID_AC_VO]  = 48;   // AC_VO: 48*32us ~= 1.5ms
-                }
-                break;
+			break;
 
-            case IE_EXT_SUPP_RATES:
-                if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
-                {
-                    NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
-                    *pExtRateLen = pEid->Len;
+		case IE_EXT_SUPP_RATES:
+			if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) {
+				NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
+				*pExtRateLen = pEid->Len;
 
-                    // TODO: 2004-09-14 not a good design here, cause it exclude extra rates
-                    // from ScanTab. We should report as is. And filter out unsupported
-                    // rates in MlmeAux.
-                    // Check against the supported rates
-                    // RTMPCheckRates(pAd, ExtRate, pExtRateLen);
-                }
-                break;
+				/* TODO: 2004-09-14 not a good design here, cause it exclude extra rates */
+				/* from ScanTab. We should report as is. And filter out unsupported */
+				/* rates in MlmeAux. */
+				/* Check against the supported rates */
+				/* RTMPCheckRates(pAd, ExtRate, pExtRateLen); */
+			}
+			break;
 
-            case IE_ERP:
-                if (pEid->Len == 1)
-                {
-                    *pErp = (UCHAR)pEid->Octet[0];
-                }
-                break;
+		case IE_ERP:
+			if (pEid->Len == 1) {
+				*pErp = (u8)pEid->Octet[0];
+			}
+			break;
 
-            case IE_AIRONET_CKIP:
-                // 0. Check Aironet IE length, it must be larger or equal to 28
-                // Cisco AP350 used length as 28
-                // Cisco AP12XX used length as 30
-                if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2))
-                    break;
+		case IE_AIRONET_CKIP:
+			/* 0. Check Aironet IE length, it must be larger or equal to 28 */
+			/* Cisco AP350 used length as 28 */
+			/* Cisco AP12XX used length as 30 */
+			if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2))
+				break;
 
-                // 1. Copy CKIP flag byte to buffer for process
-                *pCkipFlag = *(pEid->Octet + 8);
-                break;
+			/* 1. Copy CKIP flag byte to buffer for process */
+			*pCkipFlag = *(pEid->Octet + 8);
+			break;
 
-            case IE_AP_TX_POWER:
-                // AP Control of Client Transmit Power
-                //0. Check Aironet IE length, it must be 6
-                if (pEid->Len != 0x06)
-                    break;
+		case IE_AP_TX_POWER:
+			/* AP Control of Client Transmit Power */
+			/*0. Check Aironet IE length, it must be 6 */
+			if (pEid->Len != 0x06)
+				break;
 
-                // Get cell power limit in dBm
-                if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1)
-                    *pAironetCellPowerLimit = *(pEid->Octet + 4);
-                break;
+			/* Get cell power limit in dBm */
+			if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1)
+				*pAironetCellPowerLimit = *(pEid->Octet + 4);
+			break;
 
-            // WPA2 & 802.11i RSN
-            case IE_RSN:
-                // There is no OUI for version anymore, check the group cipher OUI before copying
-                if (RTMPEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
-                {
-                    // Copy to pVIE which will report to microsoft bssid list.
-                    Ptr = (PUCHAR) pVIE;
-                    NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
-                    *LengthVIE += (pEid->Len + 2);
-                }
-                break;
+			/* WPA2 & 802.11i RSN */
+		case IE_RSN:
+			/* There is no OUI for version anymore, check the group cipher OUI before copying */
+			if (RTMPEqualMemory(pEid->Octet + 2, RSN_OUI, 3)) {
+				/* Copy to pVIE which will report to microsoft bssid list. */
+				Ptr = (u8 *)pVIE;
+				NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid,
+					       pEid->Len + 2);
+				*LengthVIE += (pEid->Len + 2);
+			}
+			break;
 
-            default:
-                break;
-        }
+		default:
+			break;
+		}
 
-        Length = Length + 2 + pEid->Len;  // Eid[1] + Len[1]+ content[Len]
-        pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
-    }
+		Length = Length + 2 + pEid->Len;	/* Eid[1] + Len[1]+ content[Len] */
+		pEid = (struct rt_eid *) ((u8 *) pEid + 2 + pEid->Len);
+	}
 
-    // For some 11a AP. it did not have the channel EID, patch here
+	/* For some 11a AP. it did not have the channel EID, patch here */
 	{
-		UCHAR LatchRfChannel = MsgChannel;
-		if ((pAd->LatchRfRegs.Channel > 14) && ((Sanity & 0x4) == 0))
-		{
+		u8 LatchRfChannel = MsgChannel;
+		if ((pAd->LatchRfRegs.Channel > 14) && ((Sanity & 0x4) == 0)) {
 			if (CtrlChannel != 0)
 				*pChannel = CtrlChannel;
 			else
@@ -716,13 +711,12 @@
 		}
 	}
 
-	if (Sanity != 0x7)
-	{
-		DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", Sanity));
+	if (Sanity != 0x7) {
+		DBGPRINT(RT_DEBUG_LOUD,
+			 ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n",
+			  Sanity));
 		return FALSE;
-	}
-	else
-	{
+	} else {
 		return TRUE;
 	}
 
@@ -736,51 +730,42 @@
         TRUE if all parameters are OK, FALSE otherwise
     ==========================================================================
  */
-BOOLEAN MlmeScanReqSanity(
-	IN PRTMP_ADAPTER pAd,
-	IN VOID *Msg,
-	IN ULONG MsgLen,
-	OUT UCHAR *pBssType,
-	OUT CHAR Ssid[],
-	OUT UCHAR *pSsidLen,
-	OUT UCHAR *pScanType)
+BOOLEAN MlmeScanReqSanity(struct rt_rtmp_adapter *pAd,
+			  void * Msg,
+			  unsigned long MsgLen,
+			  u8 * pBssType,
+			  char Ssid[],
+			  u8 * pSsidLen, u8 * pScanType)
 {
-	MLME_SCAN_REQ_STRUCT *Info;
+	struct rt_mlme_scan_req *Info;
 
-	Info = (MLME_SCAN_REQ_STRUCT *)(Msg);
+	Info = (struct rt_mlme_scan_req *)(Msg);
 	*pBssType = Info->BssType;
 	*pSsidLen = Info->SsidLen;
 	NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen);
 	*pScanType = Info->ScanType;
 
-	if ((*pBssType == BSS_INFRA || *pBssType == BSS_ADHOC || *pBssType == BSS_ANY)
-		&& (*pScanType == SCAN_ACTIVE || *pScanType == SCAN_PASSIVE
-		|| *pScanType == SCAN_CISCO_PASSIVE || *pScanType == SCAN_CISCO_ACTIVE
-		|| *pScanType == SCAN_CISCO_CHANNEL_LOAD || *pScanType == SCAN_CISCO_NOISE
-		))
-	{
+	if ((*pBssType == BSS_INFRA || *pBssType == BSS_ADHOC
+	     || *pBssType == BSS_ANY)
+	    && (*pScanType == SCAN_ACTIVE || *pScanType == SCAN_PASSIVE)) {
 		return TRUE;
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqSanity fail - wrong BssType or ScanType\n"));
+	} else {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("MlmeScanReqSanity fail - wrong BssType or ScanType\n"));
 		return FALSE;
 	}
 }
 
-// IRQL = DISPATCH_LEVEL
-UCHAR ChannelSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN UCHAR channel)
+/* IRQL = DISPATCH_LEVEL */
+u8 ChannelSanity(struct rt_rtmp_adapter *pAd, u8 channel)
 {
-    int i;
+	int i;
 
-    for (i = 0; i < pAd->ChannelListNum; i ++)
-    {
-        if (channel == pAd->ChannelList[i].Channel)
-            return 1;
-    }
-    return 0;
+	for (i = 0; i < pAd->ChannelListNum; i++) {
+		if (channel == pAd->ChannelList[i].Channel)
+			return 1;
+	}
+	return 0;
 }
 
 /*
@@ -794,19 +779,17 @@
 
     ==========================================================================
  */
-BOOLEAN PeerDeauthSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pAddr2,
-    OUT USHORT *pReason)
+BOOLEAN PeerDeauthSanity(struct rt_rtmp_adapter *pAd,
+			 void * Msg,
+			 unsigned long MsgLen,
+			 u8 *pAddr2, u16 * pReason)
 {
-    PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
+	struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg;
 
-    COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
-    NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
+	COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+	NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
 
-    return TRUE;
+	return TRUE;
 }
 
 /*
@@ -820,58 +803,46 @@
 
     ==========================================================================
  */
-BOOLEAN PeerAuthSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pAddr,
-    OUT USHORT *pAlg,
-    OUT USHORT *pSeq,
-    OUT USHORT *pStatus,
-    CHAR *pChlgText)
+BOOLEAN PeerAuthSanity(struct rt_rtmp_adapter *pAd,
+		       void * Msg,
+		       unsigned long MsgLen,
+		       u8 *pAddr,
+		       u16 * pAlg,
+		       u16 * pSeq,
+		       u16 * pStatus, char * pChlgText)
 {
-    PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
+	struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg;
 
-    COPY_MAC_ADDR(pAddr,   pFrame->Hdr.Addr2);
-    NdisMoveMemory(pAlg,    &pFrame->Octet[0], 2);
-    NdisMoveMemory(pSeq,    &pFrame->Octet[2], 2);
-    NdisMoveMemory(pStatus, &pFrame->Octet[4], 2);
+	COPY_MAC_ADDR(pAddr, pFrame->Hdr.Addr2);
+	NdisMoveMemory(pAlg, &pFrame->Octet[0], 2);
+	NdisMoveMemory(pSeq, &pFrame->Octet[2], 2);
+	NdisMoveMemory(pStatus, &pFrame->Octet[4], 2);
 
-    if ((*pAlg == Ndis802_11AuthModeOpen)
-      )
-    {
-        if (*pSeq == 1 || *pSeq == 2)
-        {
-            return TRUE;
-        }
-        else
-        {
-            DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n"));
-            return FALSE;
-        }
-    }
-    else if (*pAlg == Ndis802_11AuthModeShared)
-    {
-        if (*pSeq == 1 || *pSeq == 4)
-        {
-            return TRUE;
-        }
-        else if (*pSeq == 2 || *pSeq == 3)
-        {
-            NdisMoveMemory(pChlgText, &pFrame->Octet[8], CIPHER_TEXT_LEN);
-            return TRUE;
-        }
-        else
-        {
-            DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n"));
-            return FALSE;
-        }
-    }
-    else
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong algorithm\n"));
-        return FALSE;
-    }
+	if (*pAlg == AUTH_MODE_OPEN) {
+		if (*pSeq == 1 || *pSeq == 2) {
+			return TRUE;
+		} else {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("PeerAuthSanity fail - wrong Seg#\n"));
+			return FALSE;
+		}
+	} else if (*pAlg == AUTH_MODE_KEY) {
+		if (*pSeq == 1 || *pSeq == 4) {
+			return TRUE;
+		} else if (*pSeq == 2 || *pSeq == 3) {
+			NdisMoveMemory(pChlgText, &pFrame->Octet[8],
+				       CIPHER_TEXT_LEN);
+			return TRUE;
+		} else {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("PeerAuthSanity fail - wrong Seg#\n"));
+			return FALSE;
+		}
+	} else {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("PeerAuthSanity fail - wrong algorithm\n"));
+		return FALSE;
+	}
 }
 
 /*
@@ -882,32 +853,27 @@
         TRUE if all parameters are OK, FALSE otherwise
     ==========================================================================
  */
-BOOLEAN MlmeAuthReqSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pAddr,
-    OUT ULONG *pTimeout,
-    OUT USHORT *pAlg)
+BOOLEAN MlmeAuthReqSanity(struct rt_rtmp_adapter *pAd,
+			  void * Msg,
+			  unsigned long MsgLen,
+			  u8 *pAddr,
+			  unsigned long * pTimeout, u16 * pAlg)
 {
-    MLME_AUTH_REQ_STRUCT *pInfo;
+	struct rt_mlme_auth_req *pInfo;
 
-    pInfo  = (MLME_AUTH_REQ_STRUCT *)Msg;
-    COPY_MAC_ADDR(pAddr, pInfo->Addr);
-    *pTimeout = pInfo->Timeout;
-    *pAlg = pInfo->Alg;
+	pInfo = (struct rt_mlme_auth_req *)Msg;
+	COPY_MAC_ADDR(pAddr, pInfo->Addr);
+	*pTimeout = pInfo->Timeout;
+	*pAlg = pInfo->Alg;
 
-    if (((*pAlg == Ndis802_11AuthModeShared) ||(*pAlg == Ndis802_11AuthModeOpen)
-     	) &&
-        ((*pAddr & 0x01) == 0))
-    {
-        return TRUE;
-    }
-    else
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("MlmeAuthReqSanity fail - wrong algorithm\n"));
-        return FALSE;
-    }
+	if (((*pAlg == AUTH_MODE_KEY) || (*pAlg == AUTH_MODE_OPEN)
+	    ) && ((*pAddr & 0x01) == 0)) {
+		return TRUE;
+	} else {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("MlmeAuthReqSanity fail - wrong algorithm\n"));
+		return FALSE;
+	}
 }
 
 /*
@@ -921,24 +887,22 @@
 
     ==========================================================================
  */
-BOOLEAN MlmeAssocReqSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pApAddr,
-    OUT USHORT *pCapabilityInfo,
-    OUT ULONG *pTimeout,
-    OUT USHORT *pListenIntv)
+BOOLEAN MlmeAssocReqSanity(struct rt_rtmp_adapter *pAd,
+			   void * Msg,
+			   unsigned long MsgLen,
+			   u8 *pApAddr,
+			   u16 * pCapabilityInfo,
+			   unsigned long * pTimeout, u16 * pListenIntv)
 {
-    MLME_ASSOC_REQ_STRUCT *pInfo;
+	struct rt_mlme_assoc_req *pInfo;
 
-    pInfo = (MLME_ASSOC_REQ_STRUCT *)Msg;
-    *pTimeout = pInfo->Timeout;                             // timeout
-    COPY_MAC_ADDR(pApAddr, pInfo->Addr);                   // AP address
-    *pCapabilityInfo = pInfo->CapabilityInfo;               // capability info
-    *pListenIntv = pInfo->ListenIntv;
+	pInfo = (struct rt_mlme_assoc_req *)Msg;
+	*pTimeout = pInfo->Timeout;	/* timeout */
+	COPY_MAC_ADDR(pApAddr, pInfo->Addr);	/* AP address */
+	*pCapabilityInfo = pInfo->CapabilityInfo;	/* capability info */
+	*pListenIntv = pInfo->ListenIntv;
 
-    return TRUE;
+	return TRUE;
 }
 
 /*
@@ -952,19 +916,17 @@
 
     ==========================================================================
  */
-BOOLEAN PeerDisassocSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pAddr2,
-    OUT USHORT *pReason)
+BOOLEAN PeerDisassocSanity(struct rt_rtmp_adapter *pAd,
+			   void * Msg,
+			   unsigned long MsgLen,
+			   u8 *pAddr2, u16 * pReason)
 {
-    PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
+	struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg;
 
-    COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
-    NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
+	COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+	NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
 
-    return TRUE;
+	return TRUE;
 }
 
 /*
@@ -984,71 +946,260 @@
 
 	========================================================================
 */
-NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(
-    IN PBSS_ENTRY pBss)
+NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(struct rt_bss_entry *pBss)
 {
-	NDIS_802_11_NETWORK_TYPE	NetWorkType;
-	UCHAR						rate, i;
+	NDIS_802_11_NETWORK_TYPE NetWorkType;
+	u8 rate, i;
 
 	NetWorkType = Ndis802_11DS;
 
-	if (pBss->Channel <= 14)
-	{
-		//
-		// First check support Rate.
-		//
-		for (i = 0; i < pBss->SupRateLen; i++)
-		{
-			rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit
-			if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22))
-			{
+	if (pBss->Channel <= 14) {
+		/* */
+		/* First check support Rate. */
+		/* */
+		for (i = 0; i < pBss->SupRateLen; i++) {
+			rate = pBss->SupRate[i] & 0x7f;	/* Mask out basic rate set bit */
+			if ((rate == 2) || (rate == 4) || (rate == 11)
+			    || (rate == 22)) {
 				continue;
-			}
-			else
-			{
-				//
-				// Otherwise (even rate > 108) means Ndis802_11OFDM24
-				//
+			} else {
+				/* */
+				/* Otherwise (even rate > 108) means Ndis802_11OFDM24 */
+				/* */
 				NetWorkType = Ndis802_11OFDM24;
 				break;
 			}
 		}
 
-		//
-		// Second check Extend Rate.
-		//
-		if (NetWorkType != Ndis802_11OFDM24)
-		{
-			for (i = 0; i < pBss->ExtRateLen; i++)
-			{
-				rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit
-				if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22))
-				{
+		/* */
+		/* Second check Extend Rate. */
+		/* */
+		if (NetWorkType != Ndis802_11OFDM24) {
+			for (i = 0; i < pBss->ExtRateLen; i++) {
+				rate = pBss->SupRate[i] & 0x7f;	/* Mask out basic rate set bit */
+				if ((rate == 2) || (rate == 4) || (rate == 11)
+				    || (rate == 22)) {
 					continue;
-				}
-				else
-				{
-					//
-					// Otherwise (even rate > 108) means Ndis802_11OFDM24
-					//
+				} else {
+					/* */
+					/* Otherwise (even rate > 108) means Ndis802_11OFDM24 */
+					/* */
 					NetWorkType = Ndis802_11OFDM24;
 					break;
 				}
 			}
 		}
-	}
-	else
-	{
+	} else {
 		NetWorkType = Ndis802_11OFDM5;
 	}
 
-    if (pBss->HtCapabilityLen != 0)
-    {
-        if (NetWorkType == Ndis802_11OFDM5)
-            NetWorkType = Ndis802_11OFDM5_N;
-        else
-            NetWorkType = Ndis802_11OFDM24_N;
-    }
+	if (pBss->HtCapabilityLen != 0) {
+		if (NetWorkType == Ndis802_11OFDM5)
+			NetWorkType = Ndis802_11OFDM5_N;
+		else
+			NetWorkType = Ndis802_11OFDM24_N;
+	}
 
 	return NetWorkType;
 }
+
+/*
+    ==========================================================================
+    Description:
+        Check the validity of the received EAPoL frame
+    Return:
+        TRUE if all parameters are OK,
+        FALSE otherwise
+    ==========================================================================
+ */
+BOOLEAN PeerWpaMessageSanity(struct rt_rtmp_adapter *pAd,
+			     struct rt_eapol_packet * pMsg,
+			     unsigned long MsgLen,
+			     u8 MsgType, struct rt_mac_table_entry *pEntry)
+{
+	u8 mic[LEN_KEY_DESC_MIC], digest[80], KEYDATA[MAX_LEN_OF_RSNIE];
+	BOOLEAN bReplayDiff = FALSE;
+	BOOLEAN bWPA2 = FALSE;
+	struct rt_key_info EapolKeyInfo;
+	u8 GroupKeyIndex = 0;
+
+	NdisZeroMemory(mic, sizeof(mic));
+	NdisZeroMemory(digest, sizeof(digest));
+	NdisZeroMemory(KEYDATA, sizeof(KEYDATA));
+	NdisZeroMemory((u8 *)& EapolKeyInfo, sizeof(EapolKeyInfo));
+
+	NdisMoveMemory((u8 *)& EapolKeyInfo,
+		       (u8 *)& pMsg->KeyDesc.KeyInfo, sizeof(struct rt_key_info));
+
+	*((u16 *) & EapolKeyInfo) = cpu2le16(*((u16 *) & EapolKeyInfo));
+
+	/* Choose WPA2 or not */
+	if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2)
+	    || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
+		bWPA2 = TRUE;
+
+	/* 0. Check MsgType */
+	if ((MsgType > EAPOL_GROUP_MSG_2) || (MsgType < EAPOL_PAIR_MSG_1)) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("The message type is invalid(%d)! \n", MsgType));
+		return FALSE;
+	}
+	/* 1. Replay counter check */
+	if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1)	/* For supplicant */
+	{
+		/* First validate replay counter, only accept message with larger replay counter. */
+		/* Let equal pass, some AP start with all zero replay counter */
+		u8 ZeroReplay[LEN_KEY_DESC_REPLAY];
+
+		NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
+		if ((RTMPCompareMemory
+		     (pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter,
+		      LEN_KEY_DESC_REPLAY) != 1)
+		    &&
+		    (RTMPCompareMemory
+		     (pMsg->KeyDesc.ReplayCounter, ZeroReplay,
+		      LEN_KEY_DESC_REPLAY) != 0)) {
+			bReplayDiff = TRUE;
+		}
+	} else if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2)	/* For authenticator */
+	{
+		/* check Replay Counter coresponds to MSG from authenticator, otherwise discard */
+		if (!NdisEqualMemory
+		    (pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter,
+		     LEN_KEY_DESC_REPLAY)) {
+			bReplayDiff = TRUE;
+		}
+	}
+	/* Replay Counter different condition */
+	if (bReplayDiff) {
+		/* send wireless event - for replay counter different */
+		if (pAd->CommonCfg.bWirelessEvent)
+			RTMPSendWirelessEvent(pAd,
+					      IW_REPLAY_COUNTER_DIFF_EVENT_FLAG,
+					      pEntry->Addr, pEntry->apidx, 0);
+
+		if (MsgType < EAPOL_GROUP_MSG_1) {
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("Replay Counter Different in pairwise msg %d of 4-way handshake!\n",
+				  MsgType));
+		} else {
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("Replay Counter Different in group msg %d of 2-way handshake!\n",
+				  (MsgType - EAPOL_PAIR_MSG_4)));
+		}
+
+		hex_dump("Receive replay counter ", pMsg->KeyDesc.ReplayCounter,
+			 LEN_KEY_DESC_REPLAY);
+		hex_dump("Current replay counter ", pEntry->R_Counter,
+			 LEN_KEY_DESC_REPLAY);
+		return FALSE;
+	}
+	/* 2. Verify MIC except Pairwise Msg1 */
+	if (MsgType != EAPOL_PAIR_MSG_1) {
+		u8 rcvd_mic[LEN_KEY_DESC_MIC];
+
+		/* Record the received MIC for check later */
+		NdisMoveMemory(rcvd_mic, pMsg->KeyDesc.KeyMic,
+			       LEN_KEY_DESC_MIC);
+		NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+
+		if (EapolKeyInfo.KeyDescVer == DESC_TYPE_TKIP)	/* TKIP */
+		{
+			HMAC_MD5(pEntry->PTK, LEN_EAP_MICK, (u8 *)pMsg,
+				 MsgLen, mic, MD5_DIGEST_SIZE);
+		} else if (EapolKeyInfo.KeyDescVer == DESC_TYPE_AES)	/* AES */
+		{
+			HMAC_SHA1(pEntry->PTK, LEN_EAP_MICK, (u8 *)pMsg,
+				  MsgLen, digest, SHA1_DIGEST_SIZE);
+			NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
+		}
+
+		if (!NdisEqualMemory(rcvd_mic, mic, LEN_KEY_DESC_MIC)) {
+			/* send wireless event - for MIC different */
+			if (pAd->CommonCfg.bWirelessEvent)
+				RTMPSendWirelessEvent(pAd,
+						      IW_MIC_DIFF_EVENT_FLAG,
+						      pEntry->Addr,
+						      pEntry->apidx, 0);
+
+			if (MsgType < EAPOL_GROUP_MSG_1) {
+				DBGPRINT(RT_DEBUG_ERROR,
+					 ("MIC Different in pairwise msg %d of 4-way handshake!\n",
+					  MsgType));
+			} else {
+				DBGPRINT(RT_DEBUG_ERROR,
+					 ("MIC Different in group msg %d of 2-way handshake!\n",
+					  (MsgType - EAPOL_PAIR_MSG_4)));
+			}
+
+			hex_dump("Received MIC", rcvd_mic, LEN_KEY_DESC_MIC);
+			hex_dump("Desired  MIC", mic, LEN_KEY_DESC_MIC);
+
+			return FALSE;
+		}
+	}
+	/* 1. Decrypt the Key Data field if GTK is included. */
+	/* 2. Extract the context of the Key Data field if it exist. */
+	/* The field in pairwise_msg_2_WPA1(WPA2) & pairwise_msg_3_WPA1 is clear. */
+	/* The field in group_msg_1_WPA1(WPA2) & pairwise_msg_3_WPA2 is encrypted. */
+	if (CONV_ARRARY_TO_u16(pMsg->KeyDesc.KeyDataLen) > 0) {
+		/* Decrypt this field */
+		if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2)
+		    || (MsgType == EAPOL_GROUP_MSG_1)) {
+			if ((EapolKeyInfo.KeyDescVer == DESC_TYPE_AES)) {
+				/* AES */
+				AES_GTK_KEY_UNWRAP(&pEntry->PTK[16], KEYDATA,
+						   CONV_ARRARY_TO_u16(pMsg->
+									 KeyDesc.
+									 KeyDataLen),
+						   pMsg->KeyDesc.KeyData);
+			} else {
+				int i;
+				u8 Key[32];
+				/* Decrypt TKIP GTK */
+				/* Construct 32 bytes RC4 Key */
+				NdisMoveMemory(Key, pMsg->KeyDesc.KeyIv, 16);
+				NdisMoveMemory(&Key[16], &pEntry->PTK[16], 16);
+				ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key,
+					     32);
+				/*discard first 256 bytes */
+				for (i = 0; i < 256; i++)
+					ARCFOUR_BYTE(&pAd->PrivateInfo.
+						     WEPCONTEXT);
+				/* Decrypt GTK. Becareful, there is no ICV to check the result is correct or not */
+				ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT,
+						KEYDATA, pMsg->KeyDesc.KeyData,
+						CONV_ARRARY_TO_u16(pMsg->
+								      KeyDesc.
+								      KeyDataLen));
+			}
+
+			if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))
+				GroupKeyIndex = EapolKeyInfo.KeyIndex;
+
+		} else if ((MsgType == EAPOL_PAIR_MSG_2)
+			   || (MsgType == EAPOL_PAIR_MSG_3 && !bWPA2)) {
+			NdisMoveMemory(KEYDATA, pMsg->KeyDesc.KeyData,
+				       CONV_ARRARY_TO_u16(pMsg->KeyDesc.
+							     KeyDataLen));
+		} else {
+
+			return TRUE;
+		}
+
+		/* Parse Key Data field to */
+		/* 1. verify RSN IE for pairwise_msg_2_WPA1(WPA2) ,pairwise_msg_3_WPA1(WPA2) */
+		/* 2. verify KDE format for pairwise_msg_3_WPA2, group_msg_1_WPA2 */
+		/* 3. update shared key for pairwise_msg_3_WPA2, group_msg_1_WPA1(WPA2) */
+		if (!RTMPParseEapolKeyData(pAd, KEYDATA,
+					   CONV_ARRARY_TO_u16(pMsg->KeyDesc.
+								 KeyDataLen),
+					   GroupKeyIndex, MsgType, bWPA2,
+					   pEntry)) {
+			return FALSE;
+		}
+	}
+
+	return TRUE;
+
+}
diff --git a/drivers/staging/rt2860/common/cmm_sync.c b/drivers/staging/rt2860/common/cmm_sync.c
index a6e1b6d..f84194d 100644
--- a/drivers/staging/rt2860/common/cmm_sync.c
+++ b/drivers/staging/rt2860/common/cmm_sync.c
@@ -25,7 +25,7 @@
  *************************************************************************
 
 	Module Name:
-	sync.c
+	cmm_sync.c
 
 	Abstract:
 
@@ -36,42 +36,62 @@
 */
 #include "../rt_config.h"
 
-// 2.4 Ghz channel plan index in the TxPower arrays.
-#define	BG_BAND_REGION_0_START	0			// 1,2,3,4,5,6,7,8,9,10,11
+/* 2.4 Ghz channel plan index in the TxPower arrays. */
+#define	BG_BAND_REGION_0_START	0	/* 1,2,3,4,5,6,7,8,9,10,11 */
 #define	BG_BAND_REGION_0_SIZE	11
-#define	BG_BAND_REGION_1_START	0			// 1,2,3,4,5,6,7,8,9,10,11,12,13
+#define	BG_BAND_REGION_1_START	0	/* 1,2,3,4,5,6,7,8,9,10,11,12,13 */
 #define	BG_BAND_REGION_1_SIZE	13
-#define	BG_BAND_REGION_2_START	9			// 10,11
+#define	BG_BAND_REGION_2_START	9	/* 10,11 */
 #define	BG_BAND_REGION_2_SIZE	2
-#define	BG_BAND_REGION_3_START	9			// 10,11,12,13
+#define	BG_BAND_REGION_3_START	9	/* 10,11,12,13 */
 #define	BG_BAND_REGION_3_SIZE	4
-#define	BG_BAND_REGION_4_START	13			// 14
+#define	BG_BAND_REGION_4_START	13	/* 14 */
 #define	BG_BAND_REGION_4_SIZE	1
-#define	BG_BAND_REGION_5_START	0			// 1,2,3,4,5,6,7,8,9,10,11,12,13,14
+#define	BG_BAND_REGION_5_START	0	/* 1,2,3,4,5,6,7,8,9,10,11,12,13,14 */
 #define	BG_BAND_REGION_5_SIZE	14
-#define	BG_BAND_REGION_6_START	2			// 3,4,5,6,7,8,9
+#define	BG_BAND_REGION_6_START	2	/* 3,4,5,6,7,8,9 */
 #define	BG_BAND_REGION_6_SIZE	7
-#define	BG_BAND_REGION_7_START	4			// 5,6,7,8,9,10,11,12,13
+#define	BG_BAND_REGION_7_START	4	/* 5,6,7,8,9,10,11,12,13 */
 #define	BG_BAND_REGION_7_SIZE	9
-#define	BG_BAND_REGION_31_START	0			// 1,2,3,4,5,6,7,8,9,10,11,12,13,14
+#define	BG_BAND_REGION_31_START	0	/* 1,2,3,4,5,6,7,8,9,10,11,12,13,14 */
 #define	BG_BAND_REGION_31_SIZE	14
 
-// 5 Ghz channel plan index in the TxPower arrays.
-UCHAR A_BAND_REGION_0_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165};
-UCHAR A_BAND_REGION_1_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
-UCHAR A_BAND_REGION_2_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64};
-UCHAR A_BAND_REGION_3_CHANNEL_LIST[]={52, 56, 60, 64, 149, 153, 157, 161};
-UCHAR A_BAND_REGION_4_CHANNEL_LIST[]={149, 153, 157, 161, 165};
-UCHAR A_BAND_REGION_5_CHANNEL_LIST[]={149, 153, 157, 161};
-UCHAR A_BAND_REGION_6_CHANNEL_LIST[]={36, 40, 44, 48};
-UCHAR A_BAND_REGION_7_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165};
-UCHAR A_BAND_REGION_8_CHANNEL_LIST[]={52, 56, 60, 64};
-UCHAR A_BAND_REGION_9_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165};
-UCHAR A_BAND_REGION_10_CHANNEL_LIST[]={36, 40, 44, 48, 149, 153, 157, 161, 165};
-UCHAR A_BAND_REGION_11_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161};
+/* 5 Ghz channel plan index in the TxPower arrays. */
+u8 A_BAND_REGION_0_CHANNEL_LIST[] =
+    { 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165 };
+u8 A_BAND_REGION_1_CHANNEL_LIST[] =
+    { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128,
+132, 136, 140 };
+u8 A_BAND_REGION_2_CHANNEL_LIST[] = { 36, 40, 44, 48, 52, 56, 60, 64 };
+u8 A_BAND_REGION_3_CHANNEL_LIST[] = { 52, 56, 60, 64, 149, 153, 157, 161 };
+u8 A_BAND_REGION_4_CHANNEL_LIST[] = { 149, 153, 157, 161, 165 };
+u8 A_BAND_REGION_5_CHANNEL_LIST[] = { 149, 153, 157, 161 };
+u8 A_BAND_REGION_6_CHANNEL_LIST[] = { 36, 40, 44, 48 };
+u8 A_BAND_REGION_7_CHANNEL_LIST[] =
+    { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128,
+132, 136, 140, 149, 153, 157, 161, 165, 169, 173 };
+u8 A_BAND_REGION_8_CHANNEL_LIST[] = { 52, 56, 60, 64 };
+u8 A_BAND_REGION_9_CHANNEL_LIST[] =
+    { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140,
+149, 153, 157, 161, 165 };
+u8 A_BAND_REGION_10_CHANNEL_LIST[] =
+    { 36, 40, 44, 48, 149, 153, 157, 161, 165 };
+u8 A_BAND_REGION_11_CHANNEL_LIST[] =
+    { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153,
+157, 161 };
+u8 A_BAND_REGION_12_CHANNEL_LIST[] =
+    { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128,
+132, 136, 140 };
+u8 A_BAND_REGION_13_CHANNEL_LIST[] =
+    { 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140,
+149, 153, 157, 161 };
+u8 A_BAND_REGION_14_CHANNEL_LIST[] =
+    { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149,
+153, 157, 161, 165 };
+u8 A_BAND_REGION_15_CHANNEL_LIST[] = { 149, 153, 157, 161, 165, 169, 173 };
 
-//BaSizeArray follows the 802.11n definition as MaxRxFactor.  2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8.
-UCHAR BaSizeArray[4] = {8,16,32,64};
+/*BaSizeArray follows the 802.11n definition as MaxRxFactor.  2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8. */
+u8 BaSizeArray[4] = { 8, 16, 32, 64 };
 
 /*
 	==========================================================================
@@ -85,155 +105,243 @@
 
 	==========================================================================
  */
-VOID BuildChannelList(
-	IN PRTMP_ADAPTER pAd)
+void BuildChannelList(struct rt_rtmp_adapter *pAd)
 {
-	UCHAR i, j, index=0, num=0;
-	PUCHAR	pChannelList = NULL;
+	u8 i, j, index = 0, num = 0;
+	u8 *pChannelList = NULL;
 
-	NdisZeroMemory(pAd->ChannelList, MAX_NUM_OF_CHANNELS * sizeof(CHANNEL_TX_POWER));
+	NdisZeroMemory(pAd->ChannelList,
+		       MAX_NUM_OF_CHANNELS * sizeof(struct rt_channel_tx_power));
 
-	// if not 11a-only mode, channel list starts from 2.4Ghz band
+	/* if not 11a-only mode, channel list starts from 2.4Ghz band */
 	if ((pAd->CommonCfg.PhyMode != PHY_11A)
-		&& (pAd->CommonCfg.PhyMode != PHY_11AN_MIXED) && (pAd->CommonCfg.PhyMode != PHY_11N_5G)
-	)
-	{
-		switch (pAd->CommonCfg.CountryRegion  & 0x7f)
-		{
-			case REGION_0_BG_BAND:	// 1 -11
-				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_0_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_0_SIZE);
-				index += BG_BAND_REGION_0_SIZE;
-				break;
-			case REGION_1_BG_BAND:	// 1 - 13
-				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_1_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_1_SIZE);
-				index += BG_BAND_REGION_1_SIZE;
-				break;
-			case REGION_2_BG_BAND:	// 10 - 11
-				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_2_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_2_SIZE);
-				index += BG_BAND_REGION_2_SIZE;
-				break;
-			case REGION_3_BG_BAND:	// 10 - 13
-				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_3_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_3_SIZE);
-				index += BG_BAND_REGION_3_SIZE;
-				break;
-			case REGION_4_BG_BAND:	// 14
-				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_4_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_4_SIZE);
-				index += BG_BAND_REGION_4_SIZE;
-				break;
-			case REGION_5_BG_BAND:	// 1 - 14
-				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_5_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_5_SIZE);
-				index += BG_BAND_REGION_5_SIZE;
-				break;
-			case REGION_6_BG_BAND:	// 3 - 9
-				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_6_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_6_SIZE);
-				index += BG_BAND_REGION_6_SIZE;
-				break;
-			case REGION_7_BG_BAND:  // 5 - 13
-				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_7_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_7_SIZE);
-				index += BG_BAND_REGION_7_SIZE;
-				break;
-			case REGION_31_BG_BAND:	// 1 - 14
-				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_31_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_31_SIZE);
-				index += BG_BAND_REGION_31_SIZE;
-				break;
-			default:            // Error. should never happen
-				break;
+	    && (pAd->CommonCfg.PhyMode != PHY_11AN_MIXED)
+	    && (pAd->CommonCfg.PhyMode != PHY_11N_5G)
+	    ) {
+		switch (pAd->CommonCfg.CountryRegion & 0x7f) {
+		case REGION_0_BG_BAND:	/* 1 -11 */
+			NdisMoveMemory(&pAd->ChannelList[index],
+				       &pAd->TxPower[BG_BAND_REGION_0_START],
+				       sizeof(struct rt_channel_tx_power) *
+				       BG_BAND_REGION_0_SIZE);
+			index += BG_BAND_REGION_0_SIZE;
+			break;
+		case REGION_1_BG_BAND:	/* 1 - 13 */
+			NdisMoveMemory(&pAd->ChannelList[index],
+				       &pAd->TxPower[BG_BAND_REGION_1_START],
+				       sizeof(struct rt_channel_tx_power) *
+				       BG_BAND_REGION_1_SIZE);
+			index += BG_BAND_REGION_1_SIZE;
+			break;
+		case REGION_2_BG_BAND:	/* 10 - 11 */
+			NdisMoveMemory(&pAd->ChannelList[index],
+				       &pAd->TxPower[BG_BAND_REGION_2_START],
+				       sizeof(struct rt_channel_tx_power) *
+				       BG_BAND_REGION_2_SIZE);
+			index += BG_BAND_REGION_2_SIZE;
+			break;
+		case REGION_3_BG_BAND:	/* 10 - 13 */
+			NdisMoveMemory(&pAd->ChannelList[index],
+				       &pAd->TxPower[BG_BAND_REGION_3_START],
+				       sizeof(struct rt_channel_tx_power) *
+				       BG_BAND_REGION_3_SIZE);
+			index += BG_BAND_REGION_3_SIZE;
+			break;
+		case REGION_4_BG_BAND:	/* 14 */
+			NdisMoveMemory(&pAd->ChannelList[index],
+				       &pAd->TxPower[BG_BAND_REGION_4_START],
+				       sizeof(struct rt_channel_tx_power) *
+				       BG_BAND_REGION_4_SIZE);
+			index += BG_BAND_REGION_4_SIZE;
+			break;
+		case REGION_5_BG_BAND:	/* 1 - 14 */
+			NdisMoveMemory(&pAd->ChannelList[index],
+				       &pAd->TxPower[BG_BAND_REGION_5_START],
+				       sizeof(struct rt_channel_tx_power) *
+				       BG_BAND_REGION_5_SIZE);
+			index += BG_BAND_REGION_5_SIZE;
+			break;
+		case REGION_6_BG_BAND:	/* 3 - 9 */
+			NdisMoveMemory(&pAd->ChannelList[index],
+				       &pAd->TxPower[BG_BAND_REGION_6_START],
+				       sizeof(struct rt_channel_tx_power) *
+				       BG_BAND_REGION_6_SIZE);
+			index += BG_BAND_REGION_6_SIZE;
+			break;
+		case REGION_7_BG_BAND:	/* 5 - 13 */
+			NdisMoveMemory(&pAd->ChannelList[index],
+				       &pAd->TxPower[BG_BAND_REGION_7_START],
+				       sizeof(struct rt_channel_tx_power) *
+				       BG_BAND_REGION_7_SIZE);
+			index += BG_BAND_REGION_7_SIZE;
+			break;
+		case REGION_31_BG_BAND:	/* 1 - 14 */
+			NdisMoveMemory(&pAd->ChannelList[index],
+				       &pAd->TxPower[BG_BAND_REGION_31_START],
+				       sizeof(struct rt_channel_tx_power) *
+				       BG_BAND_REGION_31_SIZE);
+			index += BG_BAND_REGION_31_SIZE;
+			break;
+		default:	/* Error. should never happen */
+			break;
 		}
-		for (i=0; i<index; i++)
+		for (i = 0; i < index; i++)
 			pAd->ChannelList[i].MaxTxPwr = 20;
 	}
 
-	if ((pAd->CommonCfg.PhyMode == PHY_11A) || (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
-		|| (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED)
-		|| (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)
-	)
-	{
-		switch (pAd->CommonCfg.CountryRegionForABand & 0x7f)
-		{
-			case REGION_0_A_BAND:
-				num = sizeof(A_BAND_REGION_0_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_0_CHANNEL_LIST;
-				break;
-			case REGION_1_A_BAND:
-				num = sizeof(A_BAND_REGION_1_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_1_CHANNEL_LIST;
-				break;
-			case REGION_2_A_BAND:
-				num = sizeof(A_BAND_REGION_2_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_2_CHANNEL_LIST;
-				break;
-			case REGION_3_A_BAND:
-				num = sizeof(A_BAND_REGION_3_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_3_CHANNEL_LIST;
-				break;
-			case REGION_4_A_BAND:
-				num = sizeof(A_BAND_REGION_4_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_4_CHANNEL_LIST;
-				break;
-			case REGION_5_A_BAND:
-				num = sizeof(A_BAND_REGION_5_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_5_CHANNEL_LIST;
-				break;
-			case REGION_6_A_BAND:
-				num = sizeof(A_BAND_REGION_6_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_6_CHANNEL_LIST;
-				break;
-			case REGION_7_A_BAND:
-				num = sizeof(A_BAND_REGION_7_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_7_CHANNEL_LIST;
-				break;
-			case REGION_8_A_BAND:
-				num = sizeof(A_BAND_REGION_8_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_8_CHANNEL_LIST;
-				break;
-			case REGION_9_A_BAND:
-				num = sizeof(A_BAND_REGION_9_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_9_CHANNEL_LIST;
-				break;
+	if ((pAd->CommonCfg.PhyMode == PHY_11A)
+	    || (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
+	    || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED)
+	    || (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED)
+	    || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)
+	    || (pAd->CommonCfg.PhyMode == PHY_11N_5G)
+	    ) {
+		switch (pAd->CommonCfg.CountryRegionForABand & 0x7f) {
+		case REGION_0_A_BAND:
+			num =
+			    sizeof(A_BAND_REGION_0_CHANNEL_LIST) /
+			    sizeof(u8);
+			pChannelList = A_BAND_REGION_0_CHANNEL_LIST;
+			break;
+		case REGION_1_A_BAND:
+			num =
+			    sizeof(A_BAND_REGION_1_CHANNEL_LIST) /
+			    sizeof(u8);
+			pChannelList = A_BAND_REGION_1_CHANNEL_LIST;
+			break;
+		case REGION_2_A_BAND:
+			num =
+			    sizeof(A_BAND_REGION_2_CHANNEL_LIST) /
+			    sizeof(u8);
+			pChannelList = A_BAND_REGION_2_CHANNEL_LIST;
+			break;
+		case REGION_3_A_BAND:
+			num =
+			    sizeof(A_BAND_REGION_3_CHANNEL_LIST) /
+			    sizeof(u8);
+			pChannelList = A_BAND_REGION_3_CHANNEL_LIST;
+			break;
+		case REGION_4_A_BAND:
+			num =
+			    sizeof(A_BAND_REGION_4_CHANNEL_LIST) /
+			    sizeof(u8);
+			pChannelList = A_BAND_REGION_4_CHANNEL_LIST;
+			break;
+		case REGION_5_A_BAND:
+			num =
+			    sizeof(A_BAND_REGION_5_CHANNEL_LIST) /
+			    sizeof(u8);
+			pChannelList = A_BAND_REGION_5_CHANNEL_LIST;
+			break;
+		case REGION_6_A_BAND:
+			num =
+			    sizeof(A_BAND_REGION_6_CHANNEL_LIST) /
+			    sizeof(u8);
+			pChannelList = A_BAND_REGION_6_CHANNEL_LIST;
+			break;
+		case REGION_7_A_BAND:
+			num =
+			    sizeof(A_BAND_REGION_7_CHANNEL_LIST) /
+			    sizeof(u8);
+			pChannelList = A_BAND_REGION_7_CHANNEL_LIST;
+			break;
+		case REGION_8_A_BAND:
+			num =
+			    sizeof(A_BAND_REGION_8_CHANNEL_LIST) /
+			    sizeof(u8);
+			pChannelList = A_BAND_REGION_8_CHANNEL_LIST;
+			break;
+		case REGION_9_A_BAND:
+			num =
+			    sizeof(A_BAND_REGION_9_CHANNEL_LIST) /
+			    sizeof(u8);
+			pChannelList = A_BAND_REGION_9_CHANNEL_LIST;
+			break;
 
-			case REGION_10_A_BAND:
-				num = sizeof(A_BAND_REGION_10_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_10_CHANNEL_LIST;
-				break;
+		case REGION_10_A_BAND:
+			num =
+			    sizeof(A_BAND_REGION_10_CHANNEL_LIST) /
+			    sizeof(u8);
+			pChannelList = A_BAND_REGION_10_CHANNEL_LIST;
+			break;
 
-			case REGION_11_A_BAND:
-				num = sizeof(A_BAND_REGION_11_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_11_CHANNEL_LIST;
-				break;
-
-			default:            // Error. should never happen
-				DBGPRINT(RT_DEBUG_WARN,("countryregion=%d not support", pAd->CommonCfg.CountryRegionForABand));
-				break;
+		case REGION_11_A_BAND:
+			num =
+			    sizeof(A_BAND_REGION_11_CHANNEL_LIST) /
+			    sizeof(u8);
+			pChannelList = A_BAND_REGION_11_CHANNEL_LIST;
+			break;
+		case REGION_12_A_BAND:
+			num =
+			    sizeof(A_BAND_REGION_12_CHANNEL_LIST) /
+			    sizeof(u8);
+			pChannelList = A_BAND_REGION_12_CHANNEL_LIST;
+			break;
+		case REGION_13_A_BAND:
+			num =
+			    sizeof(A_BAND_REGION_13_CHANNEL_LIST) /
+			    sizeof(u8);
+			pChannelList = A_BAND_REGION_13_CHANNEL_LIST;
+			break;
+		case REGION_14_A_BAND:
+			num =
+			    sizeof(A_BAND_REGION_14_CHANNEL_LIST) /
+			    sizeof(u8);
+			pChannelList = A_BAND_REGION_14_CHANNEL_LIST;
+			break;
+		case REGION_15_A_BAND:
+			num =
+			    sizeof(A_BAND_REGION_15_CHANNEL_LIST) /
+			    sizeof(u8);
+			pChannelList = A_BAND_REGION_15_CHANNEL_LIST;
+			break;
+		default:	/* Error. should never happen */
+			DBGPRINT(RT_DEBUG_WARN,
+				 ("countryregion=%d not support",
+				  pAd->CommonCfg.CountryRegionForABand));
+			break;
 		}
 
-		if (num != 0)
-		{
-			UCHAR RadarCh[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
-			for (i=0; i<num; i++)
-			{
-				for (j=0; j<MAX_NUM_OF_CHANNELS; j++)
-				{
-					if (pChannelList[i] == pAd->TxPower[j].Channel)
-						NdisMoveMemory(&pAd->ChannelList[index+i], &pAd->TxPower[j], sizeof(CHANNEL_TX_POWER));
-					}
-				for (j=0; j<15; j++)
-				{
-					if (pChannelList[i] == RadarCh[j])
-						pAd->ChannelList[index+i].DfsReq = TRUE;
+		if (num != 0) {
+			u8 RadarCh[15] =
+			    { 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124,
+		    128, 132, 136, 140 };
+			for (i = 0; i < num; i++) {
+				for (j = 0; j < MAX_NUM_OF_CHANNELS; j++) {
+					if (pChannelList[i] ==
+					    pAd->TxPower[j].Channel)
+						NdisMoveMemory(&pAd->
+							       ChannelList[index
+									   + i],
+							       &pAd->TxPower[j],
+							       sizeof
+							       (struct rt_channel_tx_power));
 				}
-				pAd->ChannelList[index+i].MaxTxPwr = 20;
+				for (j = 0; j < 15; j++) {
+					if (pChannelList[i] == RadarCh[j])
+						pAd->ChannelList[index +
+								 i].DfsReq =
+						    TRUE;
+				}
+				pAd->ChannelList[index + i].MaxTxPwr = 20;
 			}
 			index += num;
 		}
 	}
 
 	pAd->ChannelListNum = index;
-	DBGPRINT(RT_DEBUG_TRACE,("country code=%d/%d, RFIC=%d, PHY mode=%d, support %d channels\n",
-		pAd->CommonCfg.CountryRegion, pAd->CommonCfg.CountryRegionForABand, pAd->RfIcType, pAd->CommonCfg.PhyMode, pAd->ChannelListNum));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("country code=%d/%d, RFIC=%d, PHY mode=%d, support %d channels\n",
+		  pAd->CommonCfg.CountryRegion,
+		  pAd->CommonCfg.CountryRegionForABand, pAd->RfIcType,
+		  pAd->CommonCfg.PhyMode, pAd->ChannelListNum));
 #ifdef DBG
-	for (i=0;i<pAd->ChannelListNum;i++)
-	{
-		DBGPRINT_RAW(RT_DEBUG_TRACE,("BuildChannel # %d :: Pwr0 = %d, Pwr1 =%d, \n ", pAd->ChannelList[i].Channel, pAd->ChannelList[i].Power, pAd->ChannelList[i].Power2));
+	for (i = 0; i < pAd->ChannelListNum; i++) {
+		DBGPRINT_RAW(RT_DEBUG_TRACE,
+			     ("BuildChannel # %d :: Pwr0 = %d, Pwr1 =%d, \n ",
+			      pAd->ChannelList[i].Channel,
+			      pAd->ChannelList[i].Power,
+			      pAd->ChannelList[i].Power2));
 	}
 #endif
 }
@@ -251,8 +359,7 @@
 
 	==========================================================================
  */
-UCHAR FirstChannel(
-	IN PRTMP_ADAPTER pAd)
+u8 FirstChannel(struct rt_rtmp_adapter *pAd)
 {
 	return pAd->ChannelList[0].Channel;
 }
@@ -268,19 +375,16 @@
 		return 0 if no more next channel
 	==========================================================================
  */
-UCHAR NextChannel(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR channel)
+u8 NextChannel(struct rt_rtmp_adapter *pAd, u8 channel)
 {
 	int i;
-	UCHAR next_channel = 0;
+	u8 next_channel = 0;
 
 	for (i = 0; i < (pAd->ChannelListNum - 1); i++)
-		if (channel == pAd->ChannelList[i].Channel)
-		{
-			next_channel = pAd->ChannelList[i+1].Channel;
+		if (channel == pAd->ChannelList[i].Channel) {
+			next_channel = pAd->ChannelList[i + 1].Channel;
 			break;
-	}
+		}
 	return next_channel;
 }
 
@@ -304,16 +408,15 @@
 		the minimum value or next lower value.
 	==========================================================================
  */
-VOID ChangeToCellPowerLimit(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR         AironetCellPowerLimit)
+void ChangeToCellPowerLimit(struct rt_rtmp_adapter *pAd,
+			    u8 AironetCellPowerLimit)
 {
-	//valud 0xFF means that hasn't found power limit information
-	//from the AP's Beacon/Probe response.
+	/*valud 0xFF means that hasn't found power limit information */
+	/*from the AP's Beacon/Probe response. */
 	if (AironetCellPowerLimit == 0xFF)
 		return;
 
-	if (AironetCellPowerLimit < 6) //Used Lowest Power Percentage.
+	if (AironetCellPowerLimit < 6)	/*Used Lowest Power Percentage. */
 		pAd->CommonCfg.TxPowerPercentage = 6;
 	else if (AironetCellPowerLimit < 9)
 		pAd->CommonCfg.TxPowerPercentage = 10;
@@ -324,45 +427,40 @@
 	else if (AironetCellPowerLimit < 15)
 		pAd->CommonCfg.TxPowerPercentage = 75;
 	else
-		pAd->CommonCfg.TxPowerPercentage = 100; //else used maximum
+		pAd->CommonCfg.TxPowerPercentage = 100;	/*else used maximum */
 
 	if (pAd->CommonCfg.TxPowerPercentage > pAd->CommonCfg.TxPowerDefault)
-		pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
+		pAd->CommonCfg.TxPowerPercentage =
+		    pAd->CommonCfg.TxPowerDefault;
 
 }
 
-CHAR	ConvertToRssi(
-	IN PRTMP_ADAPTER pAd,
-	IN	CHAR			Rssi,
-	IN  UCHAR   RssiNumber)
+char ConvertToRssi(struct rt_rtmp_adapter *pAd, char Rssi, u8 RssiNumber)
 {
-	UCHAR	RssiOffset, LNAGain;
+	u8 RssiOffset, LNAGain;
 
-	// Rssi equals to zero should be an invalid value
+	/* Rssi equals to zero should be an invalid value */
 	if (Rssi == 0)
 		return -99;
 
 	LNAGain = GET_LNA_GAIN(pAd);
-    if (pAd->LatchRfRegs.Channel > 14)
-    {
-        if (RssiNumber == 0)
+	if (pAd->LatchRfRegs.Channel > 14) {
+		if (RssiNumber == 0)
 			RssiOffset = pAd->ARssiOffset0;
 		else if (RssiNumber == 1)
 			RssiOffset = pAd->ARssiOffset1;
 		else
 			RssiOffset = pAd->ARssiOffset2;
-    }
-    else
-    {
-        if (RssiNumber == 0)
+	} else {
+		if (RssiNumber == 0)
 			RssiOffset = pAd->BGRssiOffset0;
 		else if (RssiNumber == 1)
 			RssiOffset = pAd->BGRssiOffset1;
 		else
 			RssiOffset = pAd->BGRssiOffset2;
-    }
+	}
 
-    return (-12 - RssiOffset - LNAGain - Rssi);
+	return (-12 - RssiOffset - LNAGain - Rssi);
 }
 
 /*
@@ -371,63 +469,75 @@
 		Scan next channel
 	==========================================================================
  */
-VOID ScanNextChannel(
-	IN PRTMP_ADAPTER pAd)
+void ScanNextChannel(struct rt_rtmp_adapter *pAd)
 {
-	HEADER_802_11   Hdr80211;
-	PUCHAR          pOutBuffer = NULL;
-	NDIS_STATUS     NStatus;
-	ULONG           FrameLen = 0;
-	UCHAR           SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0;
-	USHORT          Status;
-	PHEADER_802_11  pHdr80211;
-	UINT			ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;
+	struct rt_header_802_11 Hdr80211;
+	u8 *pOutBuffer = NULL;
+	int NStatus;
+	unsigned long FrameLen = 0;
+	u8 SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0;
+	u16 Status;
+	struct rt_header_802_11 * pHdr80211;
+	u32 ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;
 
-	if (MONITOR_ON(pAd))
-		return;
-
-	if (pAd->MlmeAux.Channel == 0)
 	{
+		if (MONITOR_ON(pAd))
+			return;
+	}
+
+	if (pAd->MlmeAux.Channel == 0) {
 		if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
-			&& (INFRA_ON(pAd)
-				|| (pAd->OpMode == OPMODE_AP))
-			)
-		{
-			AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+		    && (INFRA_ON(pAd)
+			|| (pAd->OpMode == OPMODE_AP))
+		    ) {
+			AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel,
+					  FALSE);
 			AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
 			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
 			BBPValue &= (~0x18);
 			BBPValue |= 0x10;
 			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-			DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
-		}
-		else
-		{
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",
+				  pAd->CommonCfg.CentralChannel,
+				  pAd->ScanTab.BssNr));
+		} else {
 			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
 			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-			DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("SYNC - End of SCAN, restore to channel %d, Total BSS[%02d]\n",
+				  pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
 		}
 
 		{
-			//
-			// To prevent data lost.
-			// Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
-			// Now, we need to send an NULL data with turned PSM bit off to AP, when scan progress done
-			//
-			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)))
-			{
-				NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);
-				if (NStatus	== NDIS_STATUS_SUCCESS)
-				{
-					pHdr80211 = (PHEADER_802_11) pOutBuffer;
-					MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
+			/* */
+			/* To prevent data lost. */
+			/* Send an NULL data with turned PSM bit on to current associated AP before SCAN progress. */
+			/* Now, we need to send an NULL data with turned PSM bit off to AP, when scan progress done */
+			/* */
+			if (OPSTATUS_TEST_FLAG
+			    (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
+			    && (INFRA_ON(pAd))) {
+				NStatus =
+				    MlmeAllocateMemory(pAd,
+						       (void *)& pOutBuffer);
+				if (NStatus == NDIS_STATUS_SUCCESS) {
+					pHdr80211 = (struct rt_header_802_11 *) pOutBuffer;
+					MgtMacHeaderInit(pAd, pHdr80211,
+							 SUBTYPE_NULL_FUNC, 1,
+							 pAd->CommonCfg.Bssid,
+							 pAd->CommonCfg.Bssid);
 					pHdr80211->Duration = 0;
 					pHdr80211->FC.Type = BTYPE_DATA;
-					pHdr80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
+					pHdr80211->FC.PwrMgmt =
+					    (pAd->StaCfg.Psm == PWR_SAVE);
 
-					// Send using priority queue
-					MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
-					DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame\n"));
+					/* Send using priority queue */
+					MiniportMMRequest(pAd, 0, pOutBuffer,
+							  sizeof
+							  (struct rt_header_802_11));
+					DBGPRINT(RT_DEBUG_TRACE,
+						 ("MlmeScanReqAction -- Send PSM Data frame\n"));
 					MlmeFreeMemory(pAd, pOutBuffer);
 					RTMPusecDelay(5000);
 				}
@@ -435,155 +545,148 @@
 
 			pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
 			Status = MLME_SUCCESS;
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
+			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF,
+				    2, &Status);
 		}
 
 		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
 	}
-#ifdef RT2870
-	else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->OpMode == OPMODE_STA))
-	{
+#ifdef RTMP_MAC_USB
+	else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)
+		 && (pAd->OpMode == OPMODE_STA)) {
 		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
 		MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE);
 	}
-#endif // RT2870 //
-	else
-	{
+#endif /* RTMP_MAC_USB // */
+	else {
 		{
-		// BBP and RF are not accessible in PS mode, we has to wake them up first
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-#ifdef RT2860
-				AsicForceWakeup(pAd, FROM_TX);
-#endif
-#ifdef RT2870
-			AsicForceWakeup(pAd, TRUE);
-#endif
-			// leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON
+			/* BBP and RF are not accessible in PS mode, we has to wake them up first */
+			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+				AsicForceWakeup(pAd, TRUE);
+
+			/* leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON */
 			if (pAd->StaCfg.Psm == PWR_SAVE)
-				MlmeSetPsmBit(pAd, PWR_ACTIVE);
+				RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
 		}
 
 		AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE);
 		AsicLockChannel(pAd, pAd->MlmeAux.Channel);
 
 		{
-			if (pAd->MlmeAux.Channel > 14)
-			{
-				if ((pAd->CommonCfg.bIEEE80211H == 1) && RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
-				{
+			if (pAd->MlmeAux.Channel > 14) {
+				if ((pAd->CommonCfg.bIEEE80211H == 1)
+				    && RadarChannelCheck(pAd,
+							 pAd->MlmeAux.
+							 Channel)) {
 					ScanType = SCAN_PASSIVE;
 					ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
 				}
 			}
 		}
 
-		//Global country domain(ch1-11:active scan, ch12-14 passive scan)
-		if ((pAd->MlmeAux.Channel <= 14) && (pAd->MlmeAux.Channel >= 12) && ((pAd->CommonCfg.CountryRegion & 0x7f) == REGION_31_BG_BAND))
-		{
+		/*Global country domain(ch1-11:active scan, ch12-14 passive scan) */
+		if ((pAd->MlmeAux.Channel <= 14) && (pAd->MlmeAux.Channel >= 12)
+		    && ((pAd->CommonCfg.CountryRegion & 0x7f) ==
+			REGION_31_BG_BAND)) {
 			ScanType = SCAN_PASSIVE;
 		}
-
-		// We need to shorten active scan time in order for WZC connect issue
-		// Chnage the channel scan time for CISCO stuff based on its IAPP announcement
+		/* We need to shorten active scan time in order for WZC connect issue */
+		/* Chnage the channel scan time for CISCO stuff based on its IAPP announcement */
 		if (ScanType == FAST_SCAN_ACTIVE)
-			RTMPSetTimer(&pAd->MlmeAux.ScanTimer, FAST_ACTIVE_SCAN_TIME);
-		else if (((ScanType == SCAN_CISCO_ACTIVE) ||
-				(ScanType == SCAN_CISCO_PASSIVE) ||
-				(ScanType == SCAN_CISCO_CHANNEL_LOAD) ||
-				(ScanType == SCAN_CISCO_NOISE)) && (pAd->OpMode == OPMODE_STA))
-		{
-			if (pAd->StaCfg.CCXScanTime < 25)
-				RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime * 2);
-			else
-				RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime);
-		}
-		else // must be SCAN_PASSIVE or SCAN_ACTIVE
+			RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
+				     FAST_ACTIVE_SCAN_TIME);
+		else		/* must be SCAN_PASSIVE or SCAN_ACTIVE */
 		{
 			if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
-				|| (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)
-			)
-			{
+			    || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED)
+			    || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)
+			    ) {
 				if (pAd->MlmeAux.Channel > 14)
-					RTMPSetTimer(&pAd->MlmeAux.ScanTimer, ScanTimeIn5gChannel);
+					RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
+						     ScanTimeIn5gChannel);
 				else
-				RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MIN_CHANNEL_TIME);
-			}
-			else
-				RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MAX_CHANNEL_TIME);
+					RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
+						     MIN_CHANNEL_TIME);
+			} else
+				RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
+					     MAX_CHANNEL_TIME);
 		}
 
-		if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE) ||
-			(ScanType == SCAN_CISCO_ACTIVE))
-		{
-			NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-			if (NStatus != NDIS_STATUS_SUCCESS)
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("SYNC - ScanNextChannel() allocate memory fail\n"));
+		if ((ScanType == SCAN_ACTIVE)
+		    || (ScanType == FAST_SCAN_ACTIVE)
+		    ) {
+			NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
+			if (NStatus != NDIS_STATUS_SUCCESS) {
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("SYNC - ScanNextChannel() allocate memory fail\n"));
 
 				{
-					pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+					pAd->Mlme.SyncMachine.CurrState =
+					    SYNC_IDLE;
 					Status = MLME_FAIL_NO_RESOURCE;
-					MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
+					MlmeEnqueue(pAd,
+						    MLME_CNTL_STATE_MACHINE,
+						    MT2_SCAN_CONF, 2, &Status);
 				}
 
 				return;
 			}
-
-			// There is no need to send broadcast probe request if active scan is in effect.
-			if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE)
-				)
+			/* There is no need to send broadcast probe request if active scan is in effect. */
+			if ((ScanType == SCAN_ACTIVE)
+			    || (ScanType == FAST_SCAN_ACTIVE)
+			    )
 				SsidLen = pAd->MlmeAux.SsidLen;
 			else
 				SsidLen = 0;
 
-			MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
-			MakeOutgoingFrame(pOutBuffer,               &FrameLen,
-							  sizeof(HEADER_802_11),    &Hdr80211,
-							  1,                        &SsidIe,
-							  1,                        &SsidLen,
-							  SsidLen,			        pAd->MlmeAux.Ssid,
-							  1,                        &SupRateIe,
-							  1,                        &pAd->CommonCfg.SupRateLen,
-							  pAd->CommonCfg.SupRateLen,  pAd->CommonCfg.SupRate,
-							  END_OF_ARGS);
+			MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0,
+					 BROADCAST_ADDR, BROADCAST_ADDR);
+			MakeOutgoingFrame(pOutBuffer, &FrameLen,
+					  sizeof(struct rt_header_802_11), &Hdr80211, 1,
+					  &SsidIe, 1, &SsidLen, SsidLen,
+					  pAd->MlmeAux.Ssid, 1, &SupRateIe, 1,
+					  &pAd->CommonCfg.SupRateLen,
+					  pAd->CommonCfg.SupRateLen,
+					  pAd->CommonCfg.SupRate, END_OF_ARGS);
 
-			if (pAd->CommonCfg.ExtRateLen)
-			{
-				ULONG Tmp;
-				MakeOutgoingFrame(pOutBuffer + FrameLen,            &Tmp,
-								  1,                                &ExtRateIe,
-								  1,                                &pAd->CommonCfg.ExtRateLen,
-								  pAd->CommonCfg.ExtRateLen,          pAd->CommonCfg.ExtRate,
-								  END_OF_ARGS);
+			if (pAd->CommonCfg.ExtRateLen) {
+				unsigned long Tmp;
+				MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
+						  1, &ExtRateIe,
+						  1, &pAd->CommonCfg.ExtRateLen,
+						  pAd->CommonCfg.ExtRateLen,
+						  pAd->CommonCfg.ExtRate,
+						  END_OF_ARGS);
 				FrameLen += Tmp;
 			}
 
-			if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
-			{
-				ULONG	Tmp;
-				UCHAR	HtLen;
-				UCHAR	BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
+			if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) {
+				unsigned long Tmp;
+				u8 HtLen;
+				u8 BROADCOM[4] = { 0x0, 0x90, 0x4c, 0x33 };
 
-				if (pAd->bBroadComHT == TRUE)
-				{
-					HtLen = pAd->MlmeAux.HtCapabilityLen + 4;
+				if (pAd->bBroadComHT == TRUE) {
+					HtLen =
+					    pAd->MlmeAux.HtCapabilityLen + 4;
 
-					MakeOutgoingFrame(pOutBuffer + FrameLen,          &Tmp,
-									1,                                &WpaIe,
-									1,                                &HtLen,
-									4,                                &BROADCOM[0],
-									pAd->MlmeAux.HtCapabilityLen,     &pAd->MlmeAux.HtCapability,
-									END_OF_ARGS);
-				}
-				else
-				{
+					MakeOutgoingFrame(pOutBuffer + FrameLen,
+							  &Tmp, 1, &WpaIe, 1,
+							  &HtLen, 4,
+							  &BROADCOM[0],
+							  pAd->MlmeAux.
+							  HtCapabilityLen,
+							  &pAd->MlmeAux.
+							  HtCapability,
+							  END_OF_ARGS);
+				} else {
 					HtLen = pAd->MlmeAux.HtCapabilityLen;
 
-					MakeOutgoingFrame(pOutBuffer + FrameLen,          &Tmp,
-									1,                                &HtCapIe,
-									1,                                &HtLen,
-									HtLen,                            &pAd->CommonCfg.HtCapability,
-									END_OF_ARGS);
+					MakeOutgoingFrame(pOutBuffer + FrameLen,
+							  &Tmp, 1, &HtCapIe, 1,
+							  &HtLen, HtLen,
+							  &pAd->CommonCfg.
+							  HtCapability,
+							  END_OF_ARGS);
 				}
 				FrameLen += Tmp;
 			}
@@ -591,22 +694,18 @@
 			MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
 			MlmeFreeMemory(pAd, pOutBuffer);
 		}
-
-		// For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse
+		/* For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse */
 
 		pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN;
 	}
 }
 
-VOID MgtProbReqMacHeaderInit(
-	IN	PRTMP_ADAPTER	pAd,
-	IN OUT PHEADER_802_11 pHdr80211,
-	IN UCHAR SubType,
-	IN UCHAR ToDs,
-	IN PUCHAR pDA,
-	IN PUCHAR pBssid)
+void MgtProbReqMacHeaderInit(struct rt_rtmp_adapter *pAd,
+			     struct rt_header_802_11 * pHdr80211,
+			     u8 SubType,
+			     u8 ToDs, u8 *pDA, u8 *pBssid)
 {
-	NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
+	NdisZeroMemory(pHdr80211, sizeof(struct rt_header_802_11));
 
 	pHdr80211->FC.Type = BTYPE_MGMT;
 	pHdr80211->FC.SubType = SubType;
@@ -617,5 +716,3 @@
 	COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
 	COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
 }
-
-
diff --git a/drivers/staging/rt2860/common/cmm_tkip.c b/drivers/staging/rt2860/common/cmm_tkip.c
new file mode 100644
index 0000000..4881ef9
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_tkip.c
@@ -0,0 +1,833 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	cmm_tkip.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	Paul Wu		02-25-02		Initial
+*/
+
+#include	"../rt_config.h"
+
+/* Rotation functions on 32 bit values */
+#define ROL32( A, n ) \
+	( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) )
+#define ROR32( A, n ) ROL32( (A), 32-(n) )
+
+u32 Tkip_Sbox_Lower[256] = {
+	0xA5, 0x84, 0x99, 0x8D, 0x0D, 0xBD, 0xB1, 0x54,
+	0x50, 0x03, 0xA9, 0x7D, 0x19, 0x62, 0xE6, 0x9A,
+	0x45, 0x9D, 0x40, 0x87, 0x15, 0xEB, 0xC9, 0x0B,
+	0xEC, 0x67, 0xFD, 0xEA, 0xBF, 0xF7, 0x96, 0x5B,
+	0xC2, 0x1C, 0xAE, 0x6A, 0x5A, 0x41, 0x02, 0x4F,
+	0x5C, 0xF4, 0x34, 0x08, 0x93, 0x73, 0x53, 0x3F,
+	0x0C, 0x52, 0x65, 0x5E, 0x28, 0xA1, 0x0F, 0xB5,
+	0x09, 0x36, 0x9B, 0x3D, 0x26, 0x69, 0xCD, 0x9F,
+	0x1B, 0x9E, 0x74, 0x2E, 0x2D, 0xB2, 0xEE, 0xFB,
+	0xF6, 0x4D, 0x61, 0xCE, 0x7B, 0x3E, 0x71, 0x97,
+	0xF5, 0x68, 0x00, 0x2C, 0x60, 0x1F, 0xC8, 0xED,
+	0xBE, 0x46, 0xD9, 0x4B, 0xDE, 0xD4, 0xE8, 0x4A,
+	0x6B, 0x2A, 0xE5, 0x16, 0xC5, 0xD7, 0x55, 0x94,
+	0xCF, 0x10, 0x06, 0x81, 0xF0, 0x44, 0xBA, 0xE3,
+	0xF3, 0xFE, 0xC0, 0x8A, 0xAD, 0xBC, 0x48, 0x04,
+	0xDF, 0xC1, 0x75, 0x63, 0x30, 0x1A, 0x0E, 0x6D,
+	0x4C, 0x14, 0x35, 0x2F, 0xE1, 0xA2, 0xCC, 0x39,
+	0x57, 0xF2, 0x82, 0x47, 0xAC, 0xE7, 0x2B, 0x95,
+	0xA0, 0x98, 0xD1, 0x7F, 0x66, 0x7E, 0xAB, 0x83,
+	0xCA, 0x29, 0xD3, 0x3C, 0x79, 0xE2, 0x1D, 0x76,
+	0x3B, 0x56, 0x4E, 0x1E, 0xDB, 0x0A, 0x6C, 0xE4,
+	0x5D, 0x6E, 0xEF, 0xA6, 0xA8, 0xA4, 0x37, 0x8B,
+	0x32, 0x43, 0x59, 0xB7, 0x8C, 0x64, 0xD2, 0xE0,
+	0xB4, 0xFA, 0x07, 0x25, 0xAF, 0x8E, 0xE9, 0x18,
+	0xD5, 0x88, 0x6F, 0x72, 0x24, 0xF1, 0xC7, 0x51,
+	0x23, 0x7C, 0x9C, 0x21, 0xDD, 0xDC, 0x86, 0x85,
+	0x90, 0x42, 0xC4, 0xAA, 0xD8, 0x05, 0x01, 0x12,
+	0xA3, 0x5F, 0xF9, 0xD0, 0x91, 0x58, 0x27, 0xB9,
+	0x38, 0x13, 0xB3, 0x33, 0xBB, 0x70, 0x89, 0xA7,
+	0xB6, 0x22, 0x92, 0x20, 0x49, 0xFF, 0x78, 0x7A,
+	0x8F, 0xF8, 0x80, 0x17, 0xDA, 0x31, 0xC6, 0xB8,
+	0xC3, 0xB0, 0x77, 0x11, 0xCB, 0xFC, 0xD6, 0x3A
+};
+
+u32 Tkip_Sbox_Upper[256] = {
+	0xC6, 0xF8, 0xEE, 0xF6, 0xFF, 0xD6, 0xDE, 0x91,
+	0x60, 0x02, 0xCE, 0x56, 0xE7, 0xB5, 0x4D, 0xEC,
+	0x8F, 0x1F, 0x89, 0xFA, 0xEF, 0xB2, 0x8E, 0xFB,
+	0x41, 0xB3, 0x5F, 0x45, 0x23, 0x53, 0xE4, 0x9B,
+	0x75, 0xE1, 0x3D, 0x4C, 0x6C, 0x7E, 0xF5, 0x83,
+	0x68, 0x51, 0xD1, 0xF9, 0xE2, 0xAB, 0x62, 0x2A,
+	0x08, 0x95, 0x46, 0x9D, 0x30, 0x37, 0x0A, 0x2F,
+	0x0E, 0x24, 0x1B, 0xDF, 0xCD, 0x4E, 0x7F, 0xEA,
+	0x12, 0x1D, 0x58, 0x34, 0x36, 0xDC, 0xB4, 0x5B,
+	0xA4, 0x76, 0xB7, 0x7D, 0x52, 0xDD, 0x5E, 0x13,
+	0xA6, 0xB9, 0x00, 0xC1, 0x40, 0xE3, 0x79, 0xB6,
+	0xD4, 0x8D, 0x67, 0x72, 0x94, 0x98, 0xB0, 0x85,
+	0xBB, 0xC5, 0x4F, 0xED, 0x86, 0x9A, 0x66, 0x11,
+	0x8A, 0xE9, 0x04, 0xFE, 0xA0, 0x78, 0x25, 0x4B,
+	0xA2, 0x5D, 0x80, 0x05, 0x3F, 0x21, 0x70, 0xF1,
+	0x63, 0x77, 0xAF, 0x42, 0x20, 0xE5, 0xFD, 0xBF,
+	0x81, 0x18, 0x26, 0xC3, 0xBE, 0x35, 0x88, 0x2E,
+	0x93, 0x55, 0xFC, 0x7A, 0xC8, 0xBA, 0x32, 0xE6,
+	0xC0, 0x19, 0x9E, 0xA3, 0x44, 0x54, 0x3B, 0x0B,
+	0x8C, 0xC7, 0x6B, 0x28, 0xA7, 0xBC, 0x16, 0xAD,
+	0xDB, 0x64, 0x74, 0x14, 0x92, 0x0C, 0x48, 0xB8,
+	0x9F, 0xBD, 0x43, 0xC4, 0x39, 0x31, 0xD3, 0xF2,
+	0xD5, 0x8B, 0x6E, 0xDA, 0x01, 0xB1, 0x9C, 0x49,
+	0xD8, 0xAC, 0xF3, 0xCF, 0xCA, 0xF4, 0x47, 0x10,
+	0x6F, 0xF0, 0x4A, 0x5C, 0x38, 0x57, 0x73, 0x97,
+	0xCB, 0xA1, 0xE8, 0x3E, 0x96, 0x61, 0x0D, 0x0F,
+	0xE0, 0x7C, 0x71, 0xCC, 0x90, 0x06, 0xF7, 0x1C,
+	0xC2, 0x6A, 0xAE, 0x69, 0x17, 0x99, 0x3A, 0x27,
+	0xD9, 0xEB, 0x2B, 0x22, 0xD2, 0xA9, 0x07, 0x33,
+	0x2D, 0x3C, 0x15, 0xC9, 0x87, 0xAA, 0x50, 0xA5,
+	0x03, 0x59, 0x09, 0x1A, 0x65, 0xD7, 0x84, 0xD0,
+	0x82, 0x29, 0x5A, 0x1E, 0x7B, 0xA8, 0x6D, 0x2C
+};
+
+/* */
+/* Expanded IV for TKIP function. */
+/* */
+struct PACKED rt_tkip_iv {
+	union PACKED {
+		struct PACKED {
+			u8 rc0;
+			u8 rc1;
+			u8 rc2;
+
+			union PACKED {
+				struct PACKED {
+					u8 Rsvd:5;
+					u8 ExtIV:1;
+					u8 KeyID:2;
+				} field;
+				u8 Byte;
+			} CONTROL;
+		} field;
+
+		unsigned long word;
+	} IV16;
+
+	unsigned long IV32;
+};
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Convert from u8[] to unsigned long in a portable way
+
+	Arguments:
+      pMICKey		pointer to MIC Key
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+unsigned long RTMPTkipGetUInt32(u8 *pMICKey)
+{
+	unsigned long res = 0;
+	int i;
+
+	for (i = 0; i < 4; i++) {
+		res |= (*pMICKey++) << (8 * i);
+	}
+
+	return res;
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Convert from unsigned long to u8[] in a portable way
+
+	Arguments:
+      pDst			pointer to destination for convert unsigned long to u8[]
+      val			the value for convert
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+void RTMPTkipPutUInt32(IN u8 *pDst, unsigned long val)
+{
+	int i;
+
+	for (i = 0; i < 4; i++) {
+		*pDst++ = (u8)(val & 0xff);
+		val >>= 8;
+	}
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Set the MIC Key.
+
+	Arguments:
+      pAd		Pointer to our adapter
+      pMICKey		pointer to MIC Key
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+void RTMPTkipSetMICKey(struct rt_tkip_key_info *pTkip, u8 *pMICKey)
+{
+	/* Set the key */
+	pTkip->K0 = RTMPTkipGetUInt32(pMICKey);
+	pTkip->K1 = RTMPTkipGetUInt32(pMICKey + 4);
+	/* and reset the message */
+	pTkip->L = pTkip->K0;
+	pTkip->R = pTkip->K1;
+	pTkip->nBytesInM = 0;
+	pTkip->M = 0;
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Calculate the MIC Value.
+
+	Arguments:
+      pAd		Pointer to our adapter
+      uChar			Append this uChar
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+void RTMPTkipAppendByte(struct rt_tkip_key_info *pTkip, u8 uChar)
+{
+	/* Append the byte to our word-sized buffer */
+	pTkip->M |= (uChar << (8 * pTkip->nBytesInM));
+	pTkip->nBytesInM++;
+	/* Process the word if it is full. */
+	if (pTkip->nBytesInM >= 4) {
+		pTkip->L ^= pTkip->M;
+		pTkip->R ^= ROL32(pTkip->L, 17);
+		pTkip->L += pTkip->R;
+		pTkip->R ^=
+		    ((pTkip->L & 0xff00ff00) >> 8) | ((pTkip->
+						       L & 0x00ff00ff) << 8);
+		pTkip->L += pTkip->R;
+		pTkip->R ^= ROL32(pTkip->L, 3);
+		pTkip->L += pTkip->R;
+		pTkip->R ^= ROR32(pTkip->L, 2);
+		pTkip->L += pTkip->R;
+		/* Clear the buffer */
+		pTkip->M = 0;
+		pTkip->nBytesInM = 0;
+	}
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Calculate the MIC Value.
+
+	Arguments:
+      pAd		Pointer to our adapter
+      pSrc			Pointer to source data for Calculate MIC Value
+      Len			Indicate the length of the source data
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+void RTMPTkipAppend(struct rt_tkip_key_info *pTkip, u8 *pSrc, u32 nBytes)
+{
+	/* This is simple */
+	while (nBytes > 0) {
+		RTMPTkipAppendByte(pTkip, *pSrc++);
+		nBytes--;
+	}
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Get the MIC Value.
+
+	Arguments:
+      pAd		Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+		the MIC Value is store in pAd->PrivateInfo.MIC
+	========================================================================
+*/
+void RTMPTkipGetMIC(struct rt_tkip_key_info *pTkip)
+{
+	/* Append the minimum padding */
+	RTMPTkipAppendByte(pTkip, 0x5a);
+	RTMPTkipAppendByte(pTkip, 0);
+	RTMPTkipAppendByte(pTkip, 0);
+	RTMPTkipAppendByte(pTkip, 0);
+	RTMPTkipAppendByte(pTkip, 0);
+	/* and then zeroes until the length is a multiple of 4 */
+	while (pTkip->nBytesInM != 0) {
+		RTMPTkipAppendByte(pTkip, 0);
+	}
+	/* The appendByte function has already computed the result. */
+	RTMPTkipPutUInt32(pTkip->MIC, pTkip->L);
+	RTMPTkipPutUInt32(pTkip->MIC + 4, pTkip->R);
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Init Tkip function.
+
+	Arguments:
+      pAd		Pointer to our adapter
+		pTKey       Pointer to the Temporal Key (TK), TK shall be 128bits.
+		KeyId		TK Key ID
+		pTA			Pointer to transmitter address
+		pMICKey		pointer to MIC Key
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+void RTMPInitTkipEngine(struct rt_rtmp_adapter *pAd,
+			u8 *pKey,
+			u8 KeyId,
+			u8 *pTA,
+			u8 *pMICKey,
+			u8 *pTSC, unsigned long *pIV16, unsigned long *pIV32)
+{
+	struct rt_tkip_iv tkipIv;
+
+	/* Prepare 8 bytes TKIP encapsulation for MPDU */
+	NdisZeroMemory(&tkipIv, sizeof(struct rt_tkip_iv));
+	tkipIv.IV16.field.rc0 = *(pTSC + 1);
+	tkipIv.IV16.field.rc1 = (tkipIv.IV16.field.rc0 | 0x20) & 0x7f;
+	tkipIv.IV16.field.rc2 = *pTSC;
+	tkipIv.IV16.field.CONTROL.field.ExtIV = 1;	/* 0: non-extended IV, 1: an extended IV */
+	tkipIv.IV16.field.CONTROL.field.KeyID = KeyId;
+/*      tkipIv.IV32 = *(unsigned long *)(pTSC + 2); */
+	NdisMoveMemory(&tkipIv.IV32, (pTSC + 2), 4);	/* Copy IV */
+
+	*pIV16 = tkipIv.IV16.word;
+	*pIV32 = tkipIv.IV32;
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Init MIC Value calculation function which include set MIC key &
+		calculate first 16 bytes (DA + SA + priority +  0)
+
+	Arguments:
+      pAd		Pointer to our adapter
+		pTKey       Pointer to the Temporal Key (TK), TK shall be 128bits.
+		pDA			Pointer to DA address
+		pSA			Pointer to SA address
+		pMICKey		pointer to MIC Key
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+void RTMPInitMICEngine(struct rt_rtmp_adapter *pAd,
+		       u8 *pKey,
+		       u8 *pDA,
+		       u8 *pSA, u8 UserPriority, u8 *pMICKey)
+{
+	unsigned long Priority = UserPriority;
+
+	/* Init MIC value calculation */
+	RTMPTkipSetMICKey(&pAd->PrivateInfo.Tx, pMICKey);
+	/* DA */
+	RTMPTkipAppend(&pAd->PrivateInfo.Tx, pDA, MAC_ADDR_LEN);
+	/* SA */
+	RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSA, MAC_ADDR_LEN);
+	/* Priority + 3 bytes of 0 */
+	RTMPTkipAppend(&pAd->PrivateInfo.Tx, (u8 *)& Priority, 4);
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Compare MIC value of received MSDU
+
+	Arguments:
+		pAd	Pointer to our adapter
+		pSrc        Pointer to the received Plain text data
+		pDA			Pointer to DA address
+		pSA			Pointer to SA address
+		pMICKey		pointer to MIC Key
+		Len         the length of the received plain text data exclude MIC value
+
+	Return Value:
+		TRUE        MIC value matched
+		FALSE       MIC value mismatched
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+BOOLEAN RTMPTkipCompareMICValue(struct rt_rtmp_adapter *pAd,
+				u8 *pSrc,
+				u8 *pDA,
+				u8 *pSA,
+				u8 *pMICKey,
+				u8 UserPriority, u32 Len)
+{
+	u8 OldMic[8];
+	unsigned long Priority = UserPriority;
+
+	/* Init MIC value calculation */
+	RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
+	/* DA */
+	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
+	/* SA */
+	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
+	/* Priority + 3 bytes of 0 */
+	RTMPTkipAppend(&pAd->PrivateInfo.Rx, (u8 *)& Priority, 4);
+
+	/* Calculate MIC value from plain text data */
+	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
+
+	/* Get MIC valude from received frame */
+	NdisMoveMemory(OldMic, pSrc + Len, 8);
+
+	/* Get MIC value from decrypted plain data */
+	RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
+
+	/* Move MIC value from MSDU, this steps should move to data path. */
+	/* Since the MIC value might cross MPDUs. */
+	if (!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8)) {
+		DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValue(): TKIP MIC Error !\n"));	/*MIC error. */
+
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Copy frame from waiting queue into relative ring buffer and set
+	appropriate ASIC register to kick hardware transmit function
+
+	Arguments:
+		pAd		Pointer	to our adapter
+		void *	Pointer to Ndis Packet for MIC calculation
+		pEncap			Pointer to LLC encap data
+		LenEncap		Total encap length, might be 0 which indicates no encap
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+void RTMPCalculateMICValue(struct rt_rtmp_adapter *pAd,
+			   void *pPacket,
+			   u8 *pEncap,
+			   struct rt_cipher_key *pKey, u8 apidx)
+{
+	struct rt_packet_info PacketInfo;
+	u8 *pSrcBufVA;
+	u32 SrcBufLen;
+	u8 *pSrc;
+	u8 UserPriority;
+	u8 vlan_offset = 0;
+
+	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
+
+	UserPriority = RTMP_GET_PACKET_UP(pPacket);
+	pSrc = pSrcBufVA;
+
+	/* determine if this is a vlan packet */
+	if (((*(pSrc + 12) << 8) + *(pSrc + 13)) == 0x8100)
+		vlan_offset = 4;
+
+	{
+		RTMPInitMICEngine(pAd,
+				  pKey->Key,
+				  pSrc, pSrc + 6, UserPriority, pKey->TxMic);
+	}
+
+	if (pEncap != NULL) {
+		/* LLC encapsulation */
+		RTMPTkipAppend(&pAd->PrivateInfo.Tx, pEncap, 6);
+		/* Protocol Type */
+		RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc + 12 + vlan_offset,
+			       2);
+	}
+	SrcBufLen -= (14 + vlan_offset);
+	pSrc += (14 + vlan_offset);
+	do {
+		if (SrcBufLen > 0) {
+			RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc, SrcBufLen);
+		}
+
+		break;		/* No need handle next packet */
+
+	} while (TRUE);		/* End of copying payload */
+
+	/* Compute the final MIC Value */
+	RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
+}
+
+/************************************************************/
+/* tkip_sbox()																*/
+/* Returns a 16 bit value from a 64K entry table. The Table */
+/* is synthesized from two 256 entry byte wide tables.		*/
+/************************************************************/
+
+u32 tkip_sbox(u32 index)
+{
+	u32 index_low;
+	u32 index_high;
+	u32 left, right;
+
+	index_low = (index % 256);
+	index_high = ((index >> 8) % 256);
+
+	left = Tkip_Sbox_Lower[index_low] + (Tkip_Sbox_Upper[index_low] * 256);
+	right =
+	    Tkip_Sbox_Upper[index_high] + (Tkip_Sbox_Lower[index_high] * 256);
+
+	return (left ^ right);
+}
+
+u32 rotr1(u32 a)
+{
+	unsigned int b;
+
+	if ((a & 0x01) == 0x01) {
+		b = (a >> 1) | 0x8000;
+	} else {
+		b = (a >> 1) & 0x7fff;
+	}
+	b = b % 65536;
+	return b;
+}
+
+void RTMPTkipMixKey(u8 * key, u8 * ta, unsigned long pnl,	/* Least significant 16 bits of PN */
+		    unsigned long pnh,	/* Most significant 32 bits of PN */
+		    u8 * rc4key, u32 * p1k)
+{
+
+	u32 tsc0;
+	u32 tsc1;
+	u32 tsc2;
+
+	u32 ppk0;
+	u32 ppk1;
+	u32 ppk2;
+	u32 ppk3;
+	u32 ppk4;
+	u32 ppk5;
+
+	int i;
+	int j;
+
+	tsc0 = (unsigned int)((pnh >> 16) % 65536);	/* msb */
+	tsc1 = (unsigned int)(pnh % 65536);
+	tsc2 = (unsigned int)(pnl % 65536);	/* lsb */
+
+	/* Phase 1, step 1 */
+	p1k[0] = tsc1;
+	p1k[1] = tsc0;
+	p1k[2] = (u32)(ta[0] + (ta[1] * 256));
+	p1k[3] = (u32)(ta[2] + (ta[3] * 256));
+	p1k[4] = (u32)(ta[4] + (ta[5] * 256));
+
+	/* Phase 1, step 2 */
+	for (i = 0; i < 8; i++) {
+		j = 2 * (i & 1);
+		p1k[0] =
+		    (p1k[0] +
+		     tkip_sbox((p1k[4] ^ ((256 * key[1 + j]) + key[j])) %
+			       65536)) % 65536;
+		p1k[1] =
+		    (p1k[1] +
+		     tkip_sbox((p1k[0] ^ ((256 * key[5 + j]) + key[4 + j])) %
+			       65536)) % 65536;
+		p1k[2] =
+		    (p1k[2] +
+		     tkip_sbox((p1k[1] ^ ((256 * key[9 + j]) + key[8 + j])) %
+			       65536)) % 65536;
+		p1k[3] =
+		    (p1k[3] +
+		     tkip_sbox((p1k[2] ^ ((256 * key[13 + j]) + key[12 + j])) %
+			       65536)) % 65536;
+		p1k[4] =
+		    (p1k[4] +
+		     tkip_sbox((p1k[3] ^ (((256 * key[1 + j]) + key[j]))) %
+			       65536)) % 65536;
+		p1k[4] = (p1k[4] + i) % 65536;
+	}
+
+	/* Phase 2, Step 1 */
+	ppk0 = p1k[0];
+	ppk1 = p1k[1];
+	ppk2 = p1k[2];
+	ppk3 = p1k[3];
+	ppk4 = p1k[4];
+	ppk5 = (p1k[4] + tsc2) % 65536;
+
+	/* Phase2, Step 2 */
+	ppk0 = ppk0 + tkip_sbox((ppk5 ^ ((256 * key[1]) + key[0])) % 65536);
+	ppk1 = ppk1 + tkip_sbox((ppk0 ^ ((256 * key[3]) + key[2])) % 65536);
+	ppk2 = ppk2 + tkip_sbox((ppk1 ^ ((256 * key[5]) + key[4])) % 65536);
+	ppk3 = ppk3 + tkip_sbox((ppk2 ^ ((256 * key[7]) + key[6])) % 65536);
+	ppk4 = ppk4 + tkip_sbox((ppk3 ^ ((256 * key[9]) + key[8])) % 65536);
+	ppk5 = ppk5 + tkip_sbox((ppk4 ^ ((256 * key[11]) + key[10])) % 65536);
+
+	ppk0 = ppk0 + rotr1(ppk5 ^ ((256 * key[13]) + key[12]));
+	ppk1 = ppk1 + rotr1(ppk0 ^ ((256 * key[15]) + key[14]));
+	ppk2 = ppk2 + rotr1(ppk1);
+	ppk3 = ppk3 + rotr1(ppk2);
+	ppk4 = ppk4 + rotr1(ppk3);
+	ppk5 = ppk5 + rotr1(ppk4);
+
+	/* Phase 2, Step 3 */
+	/* Phase 2, Step 3 */
+
+	tsc0 = (unsigned int)((pnh >> 16) % 65536);	/* msb */
+	tsc1 = (unsigned int)(pnh % 65536);
+	tsc2 = (unsigned int)(pnl % 65536);	/* lsb */
+
+	rc4key[0] = (tsc2 >> 8) % 256;
+	rc4key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f;
+	rc4key[2] = tsc2 % 256;
+	rc4key[3] = ((ppk5 ^ ((256 * key[1]) + key[0])) >> 1) % 256;
+
+	rc4key[4] = ppk0 % 256;
+	rc4key[5] = (ppk0 >> 8) % 256;
+
+	rc4key[6] = ppk1 % 256;
+	rc4key[7] = (ppk1 >> 8) % 256;
+
+	rc4key[8] = ppk2 % 256;
+	rc4key[9] = (ppk2 >> 8) % 256;
+
+	rc4key[10] = ppk3 % 256;
+	rc4key[11] = (ppk3 >> 8) % 256;
+
+	rc4key[12] = ppk4 % 256;
+	rc4key[13] = (ppk4 >> 8) % 256;
+
+	rc4key[14] = ppk5 % 256;
+	rc4key[15] = (ppk5 >> 8) % 256;
+}
+
+/* */
+/* TRUE: Success! */
+/* FALSE: Decrypt Error! */
+/* */
+BOOLEAN RTMPSoftDecryptTKIP(struct rt_rtmp_adapter *pAd,
+			    u8 *pData,
+			    unsigned long DataByteCnt,
+			    u8 UserPriority, struct rt_cipher_key *pWpaKey)
+{
+	u8 KeyID;
+	u32 HeaderLen;
+	u8 fc0;
+	u8 fc1;
+	u16 fc;
+	u32 frame_type;
+	u32 frame_subtype;
+	u32 from_ds;
+	u32 to_ds;
+	int a4_exists;
+	int qc_exists;
+	u16 duration;
+	u16 seq_control;
+	u16 qos_control;
+	u8 TA[MAC_ADDR_LEN];
+	u8 DA[MAC_ADDR_LEN];
+	u8 SA[MAC_ADDR_LEN];
+	u8 RC4Key[16];
+	u32 p1k[5];		/*for mix_key; */
+	unsigned long pnl;		/* Least significant 16 bits of PN */
+	unsigned long pnh;		/* Most significant 32 bits of PN */
+	u32 num_blocks;
+	u32 payload_remainder;
+	struct rt_arcfourcontext ArcFourContext;
+	u32 crc32 = 0;
+	u32 trailfcs = 0;
+	u8 MIC[8];
+	u8 TrailMIC[8];
+
+	fc0 = *pData;
+	fc1 = *(pData + 1);
+
+	fc = *((u16 *)pData);
+
+	frame_type = ((fc0 >> 2) & 0x03);
+	frame_subtype = ((fc0 >> 4) & 0x0f);
+
+	from_ds = (fc1 & 0x2) >> 1;
+	to_ds = (fc1 & 0x1);
+
+	a4_exists = (from_ds & to_ds);
+	qc_exists = ((frame_subtype == 0x08) ||	/* Assumed QoS subtypes */
+		     (frame_subtype == 0x09) ||	/* Likely to change.    */
+		     (frame_subtype == 0x0a) || (frame_subtype == 0x0b)
+	    );
+
+	HeaderLen = 24;
+	if (a4_exists)
+		HeaderLen += 6;
+
+	KeyID = *((u8 *)(pData + HeaderLen + 3));
+	KeyID = KeyID >> 6;
+
+	if (pWpaKey[KeyID].KeyLen == 0) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("RTMPSoftDecryptTKIP failed!(KeyID[%d] Length can not be 0)\n",
+			  KeyID));
+		return FALSE;
+	}
+
+	duration = *((u16 *)(pData + 2));
+
+	seq_control = *((u16 *)(pData + 22));
+
+	if (qc_exists) {
+		if (a4_exists) {
+			qos_control = *((u16 *)(pData + 30));
+		} else {
+			qos_control = *((u16 *)(pData + 24));
+		}
+	}
+
+	if (to_ds == 0 && from_ds == 1) {
+		NdisMoveMemory(DA, pData + 4, MAC_ADDR_LEN);
+		NdisMoveMemory(SA, pData + 16, MAC_ADDR_LEN);
+		NdisMoveMemory(TA, pData + 10, MAC_ADDR_LEN);	/*BSSID */
+	} else if (to_ds == 0 && from_ds == 0) {
+		NdisMoveMemory(TA, pData + 10, MAC_ADDR_LEN);
+		NdisMoveMemory(DA, pData + 4, MAC_ADDR_LEN);
+		NdisMoveMemory(SA, pData + 10, MAC_ADDR_LEN);
+	} else if (to_ds == 1 && from_ds == 0) {
+		NdisMoveMemory(SA, pData + 10, MAC_ADDR_LEN);
+		NdisMoveMemory(TA, pData + 10, MAC_ADDR_LEN);
+		NdisMoveMemory(DA, pData + 16, MAC_ADDR_LEN);
+	} else if (to_ds == 1 && from_ds == 1) {
+		NdisMoveMemory(TA, pData + 10, MAC_ADDR_LEN);
+		NdisMoveMemory(DA, pData + 16, MAC_ADDR_LEN);
+		NdisMoveMemory(SA, pData + 22, MAC_ADDR_LEN);
+	}
+
+	num_blocks = (DataByteCnt - 16) / 16;
+	payload_remainder = (DataByteCnt - 16) % 16;
+
+	pnl = (*(pData + HeaderLen)) * 256 + *(pData + HeaderLen + 2);
+	pnh = *((unsigned long *)(pData + HeaderLen + 4));
+	pnh = cpu2le32(pnh);
+	RTMPTkipMixKey(pWpaKey[KeyID].Key, TA, pnl, pnh, RC4Key, p1k);
+
+	ARCFOUR_INIT(&ArcFourContext, RC4Key, 16);
+
+	ARCFOUR_DECRYPT(&ArcFourContext, pData + HeaderLen,
+			pData + HeaderLen + 8, DataByteCnt - HeaderLen - 8);
+	NdisMoveMemory(&trailfcs, pData + DataByteCnt - 8 - 4, 4);
+	crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 4);	/*Skip IV+EIV 8 bytes & Skip last 4 bytes(FCS). */
+	crc32 ^= 0xffffffff;	/* complement */
+
+	if (crc32 != cpu2le32(trailfcs)) {
+		DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP, WEP Data ICV Error !\n"));	/*ICV error. */
+
+		return (FALSE);
+	}
+
+	NdisMoveMemory(TrailMIC, pData + DataByteCnt - 8 - 8 - 4, 8);
+	RTMPInitMICEngine(pAd, pWpaKey[KeyID].Key, DA, SA, UserPriority,
+			  pWpaKey[KeyID].RxMic);
+	RTMPTkipAppend(&pAd->PrivateInfo.Tx, pData + HeaderLen,
+		       DataByteCnt - HeaderLen - 8 - 12);
+	RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
+	NdisMoveMemory(MIC, pAd->PrivateInfo.Tx.MIC, 8);
+
+	if (!NdisEqualMemory(MIC, TrailMIC, 8)) {
+		DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptTKIP, WEP Data MIC Error !\n"));	/*MIC error. */
+		/*RTMPReportMicError(pAd, &pWpaKey[KeyID]);     // marked by AlbertY @ 20060630 */
+		return (FALSE);
+	}
+	/*DBGPRINT(RT_DEBUG_TRACE, "RTMPSoftDecryptTKIP Decript done!\n"); */
+	return TRUE;
+}
diff --git a/drivers/staging/rt2860/common/cmm_wep.c b/drivers/staging/rt2860/common/cmm_wep.c
new file mode 100644
index 0000000..76f880c
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_wep.c
@@ -0,0 +1,473 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rtmp_wep.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	Paul Wu		10-28-02		Initial
+*/
+
+#include	"../rt_config.h"
+
+u32 FCSTAB_32[256] = {
+	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+	0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+	0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+	0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+	0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+	0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+	0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+	0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+	0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+	0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+	0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+	0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+	0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+	0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+	0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+	0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+	0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+	0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+	0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+	0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+	0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+	0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+	0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+	0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+	0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+	0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+	0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+	0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+	0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+	0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+	0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+	0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+	0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+	0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+	0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+	0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+	0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+	0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+	0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+	0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+	0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+	0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+	0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+/*
+u8   WEPKEY[] = {
+		//IV
+		0x00, 0x11, 0x22,
+		//WEP KEY
+		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
+	};
+ */
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Init WEP function.
+
+	Arguments:
+      pAd		Pointer to our adapter
+		pKey        Pointer to the WEP KEY
+		KeyId		   WEP Key ID
+		KeyLen      the length of WEP KEY
+		pDest       Pointer to the destination which Encryption data will store in.
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+void RTMPInitWepEngine(struct rt_rtmp_adapter *pAd,
+		       u8 *pKey,
+		       u8 KeyId, u8 KeyLen, IN u8 *pDest)
+{
+	u32 i;
+	u8 WEPKEY[] = {
+		/*IV */
+		0x00, 0x11, 0x22,
+		/*WEP KEY */
+		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
+		    0xAA, 0xBB, 0xCC
+	};
+
+	pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32;	/*Init crc32. */
+
+	{
+		NdisMoveMemory(WEPKEY + 3, pKey, KeyLen);
+
+		for (i = 0; i < 3; i++)
+			WEPKEY[i] = RandomByte(pAd);	/*Call mlme RandomByte() function. */
+		ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, KeyLen + 3);	/*INIT SBOX, KEYLEN+3(IV) */
+
+		NdisMoveMemory(pDest, WEPKEY, 3);	/*Append Init Vector */
+	}
+	*(pDest + 3) = (KeyId << 6);	/*Append KEYID */
+
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Encrypt transimitted data
+
+	Arguments:
+      pAd		Pointer to our adapter
+      pSrc        Pointer to the transimitted source data that will be encrypt
+      pDest       Pointer to the destination where entryption data will be store in.
+      Len			Indicate the length of the source data
+
+	Return Value:
+      None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+void RTMPEncryptData(struct rt_rtmp_adapter *pAd,
+		     u8 *pSrc, u8 *pDest, u32 Len)
+{
+	pAd->PrivateInfo.FCSCRC32 =
+	    RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, pSrc, Len);
+	ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, pSrc, Len);
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Decrypt received WEP data
+
+	Arguments:
+		pAdapter		Pointer to our adapter
+		pSrc        Pointer to the received data
+		Len         the length of the received data
+
+	Return Value:
+		TRUE        Decrypt WEP data success
+		FALSE       Decrypt WEP data failed
+
+	Note:
+
+	========================================================================
+*/
+BOOLEAN RTMPSoftDecryptWEP(struct rt_rtmp_adapter *pAd,
+			   u8 *pData,
+			   unsigned long DataByteCnt, struct rt_cipher_key *pGroupKey)
+{
+	u32 trailfcs;
+	u32 crc32;
+	u8 KeyIdx;
+	u8 WEPKEY[] = {
+		/*IV */
+		0x00, 0x11, 0x22,
+		/*WEP KEY */
+		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
+		    0xAA, 0xBB, 0xCC
+	};
+	u8 *pPayload = (u8 *) pData + LENGTH_802_11;
+	unsigned long payload_len = DataByteCnt - LENGTH_802_11;
+
+	NdisMoveMemory(WEPKEY, pPayload, 3);	/*Get WEP IV */
+
+	KeyIdx = (*(pPayload + 3) & 0xc0) >> 6;
+	if (pGroupKey[KeyIdx].KeyLen == 0)
+		return (FALSE);
+
+	NdisMoveMemory(WEPKEY + 3, pGroupKey[KeyIdx].Key,
+		       pGroupKey[KeyIdx].KeyLen);
+	ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY,
+		     pGroupKey[KeyIdx].KeyLen + 3);
+	ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, pPayload, pPayload + 4,
+			payload_len - 4);
+	NdisMoveMemory(&trailfcs, pPayload + payload_len - 8, 4);
+	crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pPayload, payload_len - 8);	/*Skip last 4 bytes(FCS). */
+	crc32 ^= 0xffffffff;	/* complement */
+
+	if (crc32 != cpu2le32(trailfcs)) {
+		DBGPRINT(RT_DEBUG_TRACE, ("WEP Data CRC Error!\n"));	/*CRC error. */
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		The Stream Cipher Encryption Algorithm "struct rt_arcfour" initialize
+
+	Arguments:
+	   Ctx         Pointer to struct rt_arcfour CONTEXT (SBOX)
+		pKey        Pointer to the WEP KEY
+		KeyLen      Indicate the length fo the WEP KEY
+
+	Return Value:
+	   None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+void ARCFOUR_INIT(struct rt_arcfourcontext *Ctx, u8 *pKey, u32 KeyLen)
+{
+	u8 t, u;
+	u32 keyindex;
+	u32 stateindex;
+	u8 *state;
+	u32 counter;
+
+	state = Ctx->STATE;
+	Ctx->X = 0;
+	Ctx->Y = 0;
+	for (counter = 0; counter < 256; counter++)
+		state[counter] = (u8)counter;
+	keyindex = 0;
+	stateindex = 0;
+	for (counter = 0; counter < 256; counter++) {
+		t = state[counter];
+		stateindex = (stateindex + pKey[keyindex] + t) & 0xff;
+		u = state[stateindex];
+		state[stateindex] = t;
+		state[counter] = u;
+		if (++keyindex >= KeyLen)
+			keyindex = 0;
+	}
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Get bytes from struct rt_arcfour CONTEXT (S-BOX)
+
+	Arguments:
+	   Ctx         Pointer to struct rt_arcfour CONTEXT (SBOX)
+
+	Return Value:
+	   u8  - the value of the struct rt_arcfour CONTEXT (S-BOX)
+
+	Note:
+
+	========================================================================
+*/
+u8 ARCFOUR_BYTE(struct rt_arcfourcontext *Ctx)
+{
+	u32 x;
+	u32 y;
+	u8 sx, sy;
+	u8 *state;
+
+	state = Ctx->STATE;
+	x = (Ctx->X + 1) & 0xff;
+	sx = state[x];
+	y = (sx + Ctx->Y) & 0xff;
+	sy = state[y];
+	Ctx->X = x;
+	Ctx->Y = y;
+	state[y] = sx;
+	state[x] = sy;
+
+	return (state[(sx + sy) & 0xff]);
+
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		The Stream Cipher Decryption Algorithm
+
+	Arguments:
+		Ctx         Pointer to struct rt_arcfour CONTEXT (SBOX)
+		pDest			Pointer to the Destination
+		pSrc        Pointer to the Source data
+		Len         Indicate the length of the Source data
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+void ARCFOUR_DECRYPT(struct rt_arcfourcontext *Ctx,
+		     u8 *pDest, u8 *pSrc, u32 Len)
+{
+	u32 i;
+
+	for (i = 0; i < Len; i++)
+		pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		The Stream Cipher Encryption Algorithm
+
+	Arguments:
+		Ctx         Pointer to struct rt_arcfour CONTEXT (SBOX)
+		pDest			Pointer to the Destination
+		pSrc        Pointer to the Source data
+		Len         Indicate the length of the Source dta
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+void ARCFOUR_ENCRYPT(struct rt_arcfourcontext *Ctx,
+		     u8 *pDest, u8 *pSrc, u32 Len)
+{
+	u32 i;
+
+	for (i = 0; i < Len; i++)
+		pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		The Stream Cipher Encryption Algorithm which conform to the special requirement to encrypt  GTK.
+
+	Arguments:
+		Ctx         Pointer to struct rt_arcfour CONTEXT (SBOX)
+		pDest			Pointer to the Destination
+		pSrc        Pointer to the Source data
+		Len         Indicate the length of the Source dta
+
+	========================================================================
+*/
+
+void WPAARCFOUR_ENCRYPT(struct rt_arcfourcontext *Ctx,
+			u8 *pDest, u8 *pSrc, u32 Len)
+{
+	u32 i;
+	/*discard first 256 bytes */
+	for (i = 0; i < 256; i++)
+		ARCFOUR_BYTE(Ctx);
+
+	for (i = 0; i < Len; i++)
+		pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Calculate a new FCS given the current FCS and the new data.
+
+	Arguments:
+		Fcs	      the original FCS value
+		Cp          pointer to the data which will be calculate the FCS
+		Len         the length of the data
+
+	Return Value:
+		u32 - FCS 32 bits
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+u32 RTMP_CALC_FCS32(u32 Fcs, u8 *Cp, int Len)
+{
+	while (Len--)
+		Fcs = (((Fcs) >> 8) ^ FCSTAB_32[((Fcs) ^ (*Cp++)) & 0xff]);
+
+	return (Fcs);
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Get last FCS and encrypt it to the destination
+
+	Arguments:
+		pDest			Pointer to the Destination
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+void RTMPSetICV(struct rt_rtmp_adapter *pAd, u8 *pDest)
+{
+	pAd->PrivateInfo.FCSCRC32 ^= 0xffffffff;	/* complement */
+	pAd->PrivateInfo.FCSCRC32 = cpu2le32(pAd->PrivateInfo.FCSCRC32);
+
+	ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest,
+			(u8 *)& pAd->PrivateInfo.FCSCRC32, 4);
+}
diff --git a/drivers/staging/rt2860/common/cmm_wpa.c b/drivers/staging/rt2860/common/cmm_wpa.c
index 2de29fd..94e119f 100644
--- a/drivers/staging/rt2860/common/cmm_wpa.c
+++ b/drivers/staging/rt2860/common/cmm_wpa.c
@@ -36,25 +36,1219 @@
 	Paul Lin	03-11-28		Modify for supplicant
 */
 #include "../rt_config.h"
-// WPA OUI
-UCHAR		OUI_WPA_NONE_AKM[4]		= {0x00, 0x50, 0xF2, 0x00};
-UCHAR       OUI_WPA_VERSION[4]      = {0x00, 0x50, 0xF2, 0x01};
-UCHAR       OUI_WPA_WEP40[4]      = {0x00, 0x50, 0xF2, 0x01};
-UCHAR       OUI_WPA_TKIP[4]     = {0x00, 0x50, 0xF2, 0x02};
-UCHAR       OUI_WPA_CCMP[4]     = {0x00, 0x50, 0xF2, 0x04};
-UCHAR       OUI_WPA_WEP104[4]      = {0x00, 0x50, 0xF2, 0x05};
-UCHAR       OUI_WPA_8021X_AKM[4]	= {0x00, 0x50, 0xF2, 0x01};
-UCHAR       OUI_WPA_PSK_AKM[4]      = {0x00, 0x50, 0xF2, 0x02};
-// WPA2 OUI
-UCHAR       OUI_WPA2_WEP40[4]   = {0x00, 0x0F, 0xAC, 0x01};
-UCHAR       OUI_WPA2_TKIP[4]        = {0x00, 0x0F, 0xAC, 0x02};
-UCHAR       OUI_WPA2_CCMP[4]        = {0x00, 0x0F, 0xAC, 0x04};
-UCHAR       OUI_WPA2_8021X_AKM[4]   = {0x00, 0x0F, 0xAC, 0x01};
-UCHAR       OUI_WPA2_PSK_AKM[4]   	= {0x00, 0x0F, 0xAC, 0x02};
-UCHAR       OUI_WPA2_WEP104[4]   = {0x00, 0x0F, 0xAC, 0x05};
-// MSA OUI
-UCHAR   	OUI_MSA_8021X_AKM[4]    = {0x00, 0x0F, 0xAC, 0x05};		// Not yet final - IEEE 802.11s-D1.06
-UCHAR   	OUI_MSA_PSK_AKM[4]   	= {0x00, 0x0F, 0xAC, 0x06};		// Not yet final - IEEE 802.11s-D1.06
+/* WPA OUI */
+u8 OUI_WPA_NONE_AKM[4] = { 0x00, 0x50, 0xF2, 0x00 };
+u8 OUI_WPA_VERSION[4] = { 0x00, 0x50, 0xF2, 0x01 };
+u8 OUI_WPA_WEP40[4] = { 0x00, 0x50, 0xF2, 0x01 };
+u8 OUI_WPA_TKIP[4] = { 0x00, 0x50, 0xF2, 0x02 };
+u8 OUI_WPA_CCMP[4] = { 0x00, 0x50, 0xF2, 0x04 };
+u8 OUI_WPA_WEP104[4] = { 0x00, 0x50, 0xF2, 0x05 };
+u8 OUI_WPA_8021X_AKM[4] = { 0x00, 0x50, 0xF2, 0x01 };
+u8 OUI_WPA_PSK_AKM[4] = { 0x00, 0x50, 0xF2, 0x02 };
+
+/* WPA2 OUI */
+u8 OUI_WPA2_WEP40[4] = { 0x00, 0x0F, 0xAC, 0x01 };
+u8 OUI_WPA2_TKIP[4] = { 0x00, 0x0F, 0xAC, 0x02 };
+u8 OUI_WPA2_CCMP[4] = { 0x00, 0x0F, 0xAC, 0x04 };
+u8 OUI_WPA2_8021X_AKM[4] = { 0x00, 0x0F, 0xAC, 0x01 };
+u8 OUI_WPA2_PSK_AKM[4] = { 0x00, 0x0F, 0xAC, 0x02 };
+u8 OUI_WPA2_WEP104[4] = { 0x00, 0x0F, 0xAC, 0x05 };
+
+static void ConstructEapolKeyData(struct rt_mac_table_entry *pEntry,
+				  u8 GroupKeyWepStatus,
+				  u8 keyDescVer,
+				  u8 MsgType,
+				  u8 DefaultKeyIdx,
+				  u8 * GTK,
+				  u8 * RSNIE,
+				  u8 RSNIE_LEN, struct rt_eapol_packet * pMsg);
+
+static void CalculateMIC(u8 KeyDescVer,
+			 u8 * PTK, struct rt_eapol_packet * pMsg);
+
+static void WpaEAPPacketAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
+
+static void WpaEAPOLASFAlertAction(struct rt_rtmp_adapter *pAd,
+				   struct rt_mlme_queue_elem *Elem);
+
+static void WpaEAPOLLogoffAction(struct rt_rtmp_adapter *pAd,
+				 struct rt_mlme_queue_elem *Elem);
+
+static void WpaEAPOLStartAction(struct rt_rtmp_adapter *pAd,
+				struct rt_mlme_queue_elem *Elem);
+
+static void WpaEAPOLKeyAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
+
+/*
+    ==========================================================================
+    Description:
+        association state machine init, including state transition and timer init
+    Parameters:
+        S - pointer to the association state machine
+    ==========================================================================
+ */
+void WpaStateMachineInit(struct rt_rtmp_adapter *pAd,
+			 struct rt_state_machine *S, OUT STATE_MACHINE_FUNC Trans[])
+{
+	StateMachineInit(S, (STATE_MACHINE_FUNC *) Trans, MAX_WPA_PTK_STATE,
+			 MAX_WPA_MSG, (STATE_MACHINE_FUNC) Drop, WPA_PTK,
+			 WPA_MACHINE_BASE);
+
+	StateMachineSetAction(S, WPA_PTK, MT2_EAPPacket,
+			      (STATE_MACHINE_FUNC) WpaEAPPacketAction);
+	StateMachineSetAction(S, WPA_PTK, MT2_EAPOLStart,
+			      (STATE_MACHINE_FUNC) WpaEAPOLStartAction);
+	StateMachineSetAction(S, WPA_PTK, MT2_EAPOLLogoff,
+			      (STATE_MACHINE_FUNC) WpaEAPOLLogoffAction);
+	StateMachineSetAction(S, WPA_PTK, MT2_EAPOLKey,
+			      (STATE_MACHINE_FUNC) WpaEAPOLKeyAction);
+	StateMachineSetAction(S, WPA_PTK, MT2_EAPOLASFAlert,
+			      (STATE_MACHINE_FUNC) WpaEAPOLASFAlertAction);
+}
+
+/*
+    ==========================================================================
+    Description:
+        this is state machine function.
+        When receiving EAP packets which is  for 802.1x authentication use.
+        Not use in PSK case
+    Return:
+    ==========================================================================
+*/
+void WpaEAPPacketAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
+{
+}
+
+void WpaEAPOLASFAlertAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
+{
+}
+
+void WpaEAPOLLogoffAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
+{
+}
+
+/*
+    ==========================================================================
+    Description:
+       Start 4-way HS when rcv EAPOL_START which may create by our driver in assoc.c
+    Return:
+    ==========================================================================
+*/
+void WpaEAPOLStartAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
+{
+	struct rt_mac_table_entry *pEntry;
+	struct rt_header_802_11 * pHeader;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLStartAction ===> \n"));
+
+	pHeader = (struct rt_header_802_11 *) Elem->Msg;
+
+	/*For normaol PSK, we enqueue an EAPOL-Start command to trigger the process. */
+	if (Elem->MsgLen == 6)
+		pEntry = MacTableLookup(pAd, Elem->Msg);
+	else {
+		pEntry = MacTableLookup(pAd, pHeader->Addr2);
+	}
+
+	if (pEntry) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 (" PortSecured(%d), WpaState(%d), AuthMode(%d), PMKID_CacheIdx(%d) \n",
+			  pEntry->PortSecured, pEntry->WpaState,
+			  pEntry->AuthMode, pEntry->PMKID_CacheIdx));
+
+		if ((pEntry->PortSecured == WPA_802_1X_PORT_NOT_SECURED)
+		    && (pEntry->WpaState < AS_PTKSTART)
+		    && ((pEntry->AuthMode == Ndis802_11AuthModeWPAPSK)
+			|| (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)
+			|| ((pEntry->AuthMode == Ndis802_11AuthModeWPA2)
+			    && (pEntry->PMKID_CacheIdx != ENTRY_NOT_FOUND)))) {
+			pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+			pEntry->WpaState = AS_INITPSK;
+			pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+			NdisZeroMemory(pEntry->R_Counter,
+				       sizeof(pEntry->R_Counter));
+			pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
+
+			WPAStart4WayHS(pAd, pEntry, PEER_MSG1_RETRY_EXEC_INTV);
+		}
+	}
+}
+
+/*
+    ==========================================================================
+    Description:
+        This is state machine function.
+        When receiving EAPOL packets which is  for 802.1x key management.
+        Use both in WPA, and WPAPSK case.
+        In this function, further dispatch to different functions according to the received packet.  3 categories are :
+          1.  normal 4-way pairwisekey and 2-way groupkey handshake
+          2.  MIC error (Countermeasures attack)  report packet from STA.
+          3.  Request for pairwise/group key update from STA
+    Return:
+    ==========================================================================
+*/
+void WpaEAPOLKeyAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
+{
+	struct rt_mac_table_entry *pEntry;
+	struct rt_header_802_11 * pHeader;
+	struct rt_eapol_packet * pEapol_packet;
+	struct rt_key_info peerKeyInfo;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLKeyAction ===>\n"));
+
+	pHeader = (struct rt_header_802_11 *) Elem->Msg;
+	pEapol_packet =
+	    (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+
+	NdisZeroMemory((u8 *)& peerKeyInfo, sizeof(peerKeyInfo));
+	NdisMoveMemory((u8 *)& peerKeyInfo,
+		       (u8 *)& pEapol_packet->KeyDesc.KeyInfo,
+		       sizeof(struct rt_key_info));
+
+	hex_dump("Received Eapol frame", (unsigned char *)pEapol_packet,
+		 (Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H));
+
+	*((u16 *) & peerKeyInfo) = cpu2le16(*((u16 *) & peerKeyInfo));
+
+	do {
+		pEntry = MacTableLookup(pAd, pHeader->Addr2);
+
+		if (!pEntry
+		    || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
+			break;
+
+		if (pEntry->AuthMode < Ndis802_11AuthModeWPA)
+			break;
+
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Receive EAPoL-Key frame from STA %02X-%02X-%02X-%02X-%02X-%02X\n",
+			  PRINT_MAC(pEntry->Addr)));
+
+		if (((pEapol_packet->ProVer != EAPOL_VER)
+		     && (pEapol_packet->ProVer != EAPOL_VER2))
+		    || ((pEapol_packet->KeyDesc.Type != WPA1_KEY_DESC)
+			&& (pEapol_packet->KeyDesc.Type != WPA2_KEY_DESC))) {
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("Key descripter does not match with WPA rule\n"));
+			break;
+		}
+		/* The value 1 shall be used for all EAPOL-Key frames to and from a STA when */
+		/* neither the group nor pairwise ciphers are CCMP for Key Descriptor 1. */
+		if ((pEntry->WepStatus == Ndis802_11Encryption2Enabled)
+		    && (peerKeyInfo.KeyDescVer != DESC_TYPE_TKIP)) {
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("Key descripter version not match(TKIP) \n"));
+			break;
+		}
+		/* The value 2 shall be used for all EAPOL-Key frames to and from a STA when */
+		/* either the pairwise or the group cipher is AES-CCMP for Key Descriptor 2. */
+		else if ((pEntry->WepStatus == Ndis802_11Encryption3Enabled)
+			 && (peerKeyInfo.KeyDescVer != DESC_TYPE_AES)) {
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("Key descripter version not match(AES) \n"));
+			break;
+		}
+		/* Check if this STA is in class 3 state and the WPA state is started */
+		if ((pEntry->Sst == SST_ASSOC)
+		    && (pEntry->WpaState >= AS_INITPSK)) {
+			/* Check the Key Ack (bit 7) of the Key Information to determine the Authenticator */
+			/* or not. */
+			/* An EAPOL-Key frame that is sent by the Supplicant in response to an EAPOL- */
+			/* Key frame from the Authenticator must not have the Ack bit set. */
+			if (peerKeyInfo.KeyAck == 1) {
+				/* The frame is snet by Authenticator. */
+				/* So the Supplicant side shall handle this. */
+
+				if ((peerKeyInfo.Secure == 0)
+				    && (peerKeyInfo.Request == 0)
+				    && (peerKeyInfo.Error == 0)
+				    && (peerKeyInfo.KeyType == PAIRWISEKEY)) {
+					/* Process 1. the message 1 of 4-way HS in WPA or WPA2 */
+					/*                        EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1) */
+					/*                 2. the message 3 of 4-way HS in WPA */
+					/*                        EAPOL-Key(0,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3) */
+					if (peerKeyInfo.KeyMic == 0)
+						PeerPairMsg1Action(pAd, pEntry,
+								   Elem);
+					else
+						PeerPairMsg3Action(pAd, pEntry,
+								   Elem);
+				} else if ((peerKeyInfo.Secure == 1)
+					   && (peerKeyInfo.KeyMic == 1)
+					   && (peerKeyInfo.Request == 0)
+					   && (peerKeyInfo.Error == 0)) {
+					/* Process 1. the message 3 of 4-way HS in WPA2 */
+					/*                        EAPOL-Key(1,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3) */
+					/*                 2. the message 1 of group KS in WPA or WPA2 */
+					/*                        EAPOL-Key(1,1,1,0,G,0,Key RSC,0, MIC,GTK[N]) */
+					if (peerKeyInfo.KeyType == PAIRWISEKEY)
+						PeerPairMsg3Action(pAd, pEntry,
+								   Elem);
+					else
+						PeerGroupMsg1Action(pAd, pEntry,
+								    Elem);
+				}
+			} else {
+				/* The frame is snet by Supplicant. */
+				/* So the Authenticator side shall handle this. */
+				if ((peerKeyInfo.Request == 0) &&
+				    (peerKeyInfo.Error == 0) &&
+				    (peerKeyInfo.KeyMic == 1)) {
+					if (peerKeyInfo.Secure == 0
+					    && peerKeyInfo.KeyType ==
+					    PAIRWISEKEY) {
+						/* EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,Data) */
+						/* Process 1. message 2 of 4-way HS in WPA or WPA2 */
+						/*                 2. message 4 of 4-way HS in WPA */
+						if (CONV_ARRARY_TO_u16
+						    (pEapol_packet->KeyDesc.
+						     KeyDataLen) == 0) {
+							PeerPairMsg4Action(pAd,
+									   pEntry,
+									   Elem);
+						} else {
+							PeerPairMsg2Action(pAd,
+									   pEntry,
+									   Elem);
+						}
+					} else if (peerKeyInfo.Secure == 1
+						   && peerKeyInfo.KeyType ==
+						   PAIRWISEKEY) {
+						/* EAPOL-Key(1,1,0,0,P,0,0,0,MIC,0) */
+						/* Process message 4 of 4-way HS in WPA2 */
+						PeerPairMsg4Action(pAd, pEntry,
+								   Elem);
+					} else if (peerKeyInfo.Secure == 1
+						   && peerKeyInfo.KeyType ==
+						   GROUPKEY) {
+						/* EAPOL-Key(1,1,0,0,G,0,0,0,MIC,0) */
+						/* Process message 2 of Group key HS in WPA or WPA2 */
+						PeerGroupMsg2Action(pAd, pEntry,
+								    &Elem->
+								    Msg
+								    [LENGTH_802_11],
+								    (Elem->
+								     MsgLen -
+								     LENGTH_802_11));
+					}
+				}
+			}
+		}
+	} while (FALSE);
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Copy frame from waiting queue into relative ring buffer and set
+	appropriate ASIC register to kick hardware encryption before really
+	sent out to air.
+
+	Arguments:
+		pAd		Pointer	to our adapter
+		void *	Pointer to outgoing Ndis frame
+		NumberOfFrag	Number of fragment required
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+void RTMPToWirelessSta(struct rt_rtmp_adapter *pAd,
+		       struct rt_mac_table_entry *pEntry,
+		       u8 *pHeader802_3,
+		       u32 HdrLen,
+		       u8 *pData, u32 DataLen, IN BOOLEAN bClearFrame)
+{
+	void *pPacket;
+	int Status;
+
+	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
+		return;
+
+	do {
+		/* build a NDIS packet */
+		Status =
+		    RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen,
+					   pData, DataLen);
+		if (Status != NDIS_STATUS_SUCCESS)
+			break;
+
+		if (bClearFrame)
+			RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1);
+		else
+			RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0);
+		{
+			RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
+
+			RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket, MAIN_MBSSID);	/* set a default value */
+			if (pEntry->apidx != 0)
+				RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket,
+								  pEntry->
+								  apidx);
+
+			RTMP_SET_PACKET_WCID(pPacket, (u8)pEntry->Aid);
+			RTMP_SET_PACKET_MOREDATA(pPacket, FALSE);
+		}
+
+		{
+			/* send out the packet */
+			Status = STASendPacket(pAd, pPacket);
+			if (Status == NDIS_STATUS_SUCCESS) {
+				u8 Index;
+
+				/* Dequeue one frame from TxSwQueue0..3 queue and process it */
+				/* There are three place calling dequeue for TX ring. */
+				/* 1. Here, right after queueing the frame. */
+				/* 2. At the end of TxRingTxDone service routine. */
+				/* 3. Upon NDIS call RTMPSendPackets */
+				if ((!RTMP_TEST_FLAG
+				     (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+				    &&
+				    (!RTMP_TEST_FLAG
+				     (pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS))) {
+					for (Index = 0; Index < 5; Index++)
+						if (pAd->TxSwQueue[Index].
+						    Number > 0)
+							RTMPDeQueuePacket(pAd,
+									  FALSE,
+									  Index,
+									  MAX_TX_PROCESS);
+				}
+			}
+		}
+
+	} while (FALSE);
+}
+
+/*
+    ==========================================================================
+    Description:
+        This is a function to initilize 4-way handshake
+
+    Return:
+
+    ==========================================================================
+*/
+void WPAStart4WayHS(struct rt_rtmp_adapter *pAd,
+		    struct rt_mac_table_entry *pEntry, unsigned long TimeInterval)
+{
+	u8 Header802_3[14];
+	struct rt_eapol_packet EAPOLPKT;
+	u8 *pBssid = NULL;
+	u8 group_cipher = Ndis802_11WEPDisabled;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart4WayHS\n"));
+
+	if (RTMP_TEST_FLAG
+	    (pAd,
+	     fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS))
+	{
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("[ERROR]WPAStart4WayHS : The interface is closed...\n"));
+		return;
+	}
+
+	if (pBssid == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("[ERROR]WPAStart4WayHS : No corresponding Authenticator.\n"));
+		return;
+	}
+	/* Check the status */
+	if ((pEntry->WpaState > AS_PTKSTART) || (pEntry->WpaState < AS_INITPMK)) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("[ERROR]WPAStart4WayHS : Not expect calling\n"));
+		return;
+	}
+
+	/* Increment replay counter by 1 */
+	ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
+
+	/* Randomly generate ANonce */
+	GenRandom(pAd, (u8 *) pBssid, pEntry->ANonce);
+
+	/* Construct EAPoL message - Pairwise Msg 1 */
+	/* EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1) */
+	NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
+	ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_1, 0,	/* Default key index */
+			  pEntry->ANonce, NULL,	/* TxRSC */
+			  NULL,	/* GTK */
+			  NULL,	/* RSNIE */
+			  0,	/* RSNIE length */
+			  &EAPOLPKT);
+
+	/* Make outgoing frame */
+	MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
+	RTMPToWirelessSta(pAd, pEntry, Header802_3,
+			  LENGTH_802_3, (u8 *)& EAPOLPKT,
+			  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4,
+			  (pEntry->PortSecured ==
+			   WPA_802_1X_PORT_SECURED) ? FALSE : TRUE);
+
+	/* Trigger Retry Timer */
+	RTMPModTimer(&pEntry->RetryTimer, TimeInterval);
+
+	/* Update State */
+	pEntry->WpaState = AS_PTKSTART;
+
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("<=== WPAStart4WayHS: send Msg1 of 4-way \n"));
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Process Pairwise key Msg-1 of 4-way handshaking and send Msg-2
+
+	Arguments:
+		pAd			Pointer	to our adapter
+		Elem		Message body
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+void PeerPairMsg1Action(struct rt_rtmp_adapter *pAd,
+			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
+{
+	u8 PTK[80];
+	u8 Header802_3[14];
+	struct rt_eapol_packet * pMsg1;
+	u32 MsgLen;
+	struct rt_eapol_packet EAPOLPKT;
+	u8 *pCurrentAddr = NULL;
+	u8 *pmk_ptr = NULL;
+	u8 group_cipher = Ndis802_11WEPDisabled;
+	u8 *rsnie_ptr = NULL;
+	u8 rsnie_len = 0;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg1Action \n"));
+
+	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
+		return;
+
+	if (Elem->MsgLen <
+	    (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
+	     sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
+		return;
+
+	{
+		pCurrentAddr = pAd->CurrentAddress;
+		pmk_ptr = pAd->StaCfg.PMK;
+		group_cipher = pAd->StaCfg.GroupCipher;
+		rsnie_ptr = pAd->StaCfg.RSN_IE;
+		rsnie_len = pAd->StaCfg.RSNIE_Len;
+	}
+
+	/* Store the received frame */
+	pMsg1 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
+
+	/* Sanity Check peer Pairwise message 1 - Replay Counter */
+	if (PeerWpaMessageSanity(pAd, pMsg1, MsgLen, EAPOL_PAIR_MSG_1, pEntry)
+	    == FALSE)
+		return;
+
+	/* Store Replay counter, it will use to verify message 3 and construct message 2 */
+	NdisMoveMemory(pEntry->R_Counter, pMsg1->KeyDesc.ReplayCounter,
+		       LEN_KEY_DESC_REPLAY);
+
+	/* Store ANonce */
+	NdisMoveMemory(pEntry->ANonce, pMsg1->KeyDesc.KeyNonce,
+		       LEN_KEY_DESC_NONCE);
+
+	/* Generate random SNonce */
+	GenRandom(pAd, (u8 *) pCurrentAddr, pEntry->SNonce);
+
+	{
+		/* Calculate PTK(ANonce, SNonce) */
+		WpaDerivePTK(pAd,
+			     pmk_ptr,
+			     pEntry->ANonce,
+			     pEntry->Addr,
+			     pEntry->SNonce, pCurrentAddr, PTK, LEN_PTK);
+
+		/* Save key to PTK entry */
+		NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK);
+	}
+
+	/* Update WpaState */
+	pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
+
+	/* Construct EAPoL message - Pairwise Msg 2 */
+	/*  EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,DataKD_M2) */
+	NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
+	ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_2, 0,	/* DefaultKeyIdx */
+			  pEntry->SNonce, NULL,	/* TxRsc */
+			  NULL,	/* GTK */
+			  (u8 *) rsnie_ptr, rsnie_len, &EAPOLPKT);
+
+	/* Make outgoing frame */
+	MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
+
+	RTMPToWirelessSta(pAd, pEntry,
+			  Header802_3, sizeof(Header802_3), (u8 *)& EAPOLPKT,
+			  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, TRUE);
+
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("<=== PeerPairMsg1Action: send Msg2 of 4-way \n"));
+}
+
+/*
+    ==========================================================================
+    Description:
+        When receiving the second packet of 4-way pairwisekey handshake.
+    Return:
+    ==========================================================================
+*/
+void PeerPairMsg2Action(struct rt_rtmp_adapter *pAd,
+			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
+{
+	u8 PTK[80];
+	BOOLEAN Cancelled;
+	struct rt_header_802_11 * pHeader;
+	struct rt_eapol_packet EAPOLPKT;
+	struct rt_eapol_packet * pMsg2;
+	u32 MsgLen;
+	u8 Header802_3[LENGTH_802_3];
+	u8 TxTsc[6];
+	u8 *pBssid = NULL;
+	u8 *pmk_ptr = NULL;
+	u8 *gtk_ptr = NULL;
+	u8 default_key = 0;
+	u8 group_cipher = Ndis802_11WEPDisabled;
+	u8 *rsnie_ptr = NULL;
+	u8 rsnie_len = 0;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg2Action \n"));
+
+	if ((!pEntry) || (!pEntry->ValidAsCLI))
+		return;
+
+	if (Elem->MsgLen <
+	    (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
+	     sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
+		return;
+
+	/* check Entry in valid State */
+	if (pEntry->WpaState < AS_PTKSTART)
+		return;
+
+	/* pointer to 802.11 header */
+	pHeader = (struct rt_header_802_11 *) Elem->Msg;
+
+	/* skip 802.11_header(24-byte) and LLC_header(8) */
+	pMsg2 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
+
+	/* Store SNonce */
+	NdisMoveMemory(pEntry->SNonce, pMsg2->KeyDesc.KeyNonce,
+		       LEN_KEY_DESC_NONCE);
+
+	{
+		/* Derive PTK */
+		WpaDerivePTK(pAd, (u8 *) pmk_ptr, pEntry->ANonce,	/* ANONCE */
+			     (u8 *) pBssid, pEntry->SNonce,	/* SNONCE */
+			     pEntry->Addr, PTK, LEN_PTK);
+
+		NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK);
+	}
+
+	/* Sanity Check peer Pairwise message 2 - Replay Counter, MIC, RSNIE */
+	if (PeerWpaMessageSanity(pAd, pMsg2, MsgLen, EAPOL_PAIR_MSG_2, pEntry)
+	    == FALSE)
+		return;
+
+	do {
+		/* delete retry timer */
+		RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
+
+		/* Change state */
+		pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
+
+		/* Increment replay counter by 1 */
+		ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
+
+		/* Construct EAPoL message - Pairwise Msg 3 */
+		NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
+		ConstructEapolMsg(pEntry,
+				  group_cipher,
+				  EAPOL_PAIR_MSG_3,
+				  default_key,
+				  pEntry->ANonce,
+				  TxTsc,
+				  (u8 *) gtk_ptr,
+				  (u8 *) rsnie_ptr, rsnie_len, &EAPOLPKT);
+
+		/* Make outgoing frame */
+		MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
+		RTMPToWirelessSta(pAd, pEntry, Header802_3, LENGTH_802_3,
+				  (u8 *)& EAPOLPKT,
+				  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4,
+				  (pEntry->PortSecured ==
+				   WPA_802_1X_PORT_SECURED) ? FALSE : TRUE);
+
+		pEntry->ReTryCounter = PEER_MSG3_RETRY_TIMER_CTR;
+		RTMPSetTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV);
+
+		/* Update State */
+		pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
+	} while (FALSE);
+
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("<=== PeerPairMsg2Action: send Msg3 of 4-way \n"));
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Process Pairwise key Msg 3 of 4-way handshaking and send Msg 4
+
+	Arguments:
+		pAd	Pointer	to our adapter
+		Elem		Message body
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+void PeerPairMsg3Action(struct rt_rtmp_adapter *pAd,
+			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
+{
+	struct rt_header_802_11 * pHeader;
+	u8 Header802_3[14];
+	struct rt_eapol_packet EAPOLPKT;
+	struct rt_eapol_packet * pMsg3;
+	u32 MsgLen;
+	u8 *pCurrentAddr = NULL;
+	u8 group_cipher = Ndis802_11WEPDisabled;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg3Action \n"));
+
+	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
+		return;
+
+	if (Elem->MsgLen <
+	    (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
+	     sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
+		return;
+
+	{
+		pCurrentAddr = pAd->CurrentAddress;
+		group_cipher = pAd->StaCfg.GroupCipher;
+
+	}
+
+	/* Record 802.11 header & the received EAPOL packet Msg3 */
+	pHeader = (struct rt_header_802_11 *) Elem->Msg;
+	pMsg3 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
+
+	/* Sanity Check peer Pairwise message 3 - Replay Counter, MIC, RSNIE */
+	if (PeerWpaMessageSanity(pAd, pMsg3, MsgLen, EAPOL_PAIR_MSG_3, pEntry)
+	    == FALSE)
+		return;
+
+	/* Save Replay counter, it will use construct message 4 */
+	NdisMoveMemory(pEntry->R_Counter, pMsg3->KeyDesc.ReplayCounter,
+		       LEN_KEY_DESC_REPLAY);
+
+	/* Double check ANonce */
+	if (!NdisEqualMemory
+	    (pEntry->ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE)) {
+		return;
+	}
+	/* Construct EAPoL message - Pairwise Msg 4 */
+	NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
+	ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_4, 0,	/* group key index not used in message 4 */
+			  NULL,	/* Nonce not used in message 4 */
+			  NULL,	/* TxRSC not used in message 4 */
+			  NULL,	/* GTK not used in message 4 */
+			  NULL,	/* RSN IE not used in message 4 */
+			  0, &EAPOLPKT);
+
+	/* Update WpaState */
+	pEntry->WpaState = AS_PTKINITDONE;
+
+	/* Update pairwise key */
+	{
+		struct rt_cipher_key *pSharedKey;
+
+		pSharedKey = &pAd->SharedKey[BSS0][0];
+
+		NdisMoveMemory(pAd->StaCfg.PTK, pEntry->PTK, LEN_PTK);
+
+		/* Prepare pair-wise key information into shared key table */
+		NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key));
+		pSharedKey->KeyLen = LEN_TKIP_EK;
+		NdisMoveMemory(pSharedKey->Key, &pAd->StaCfg.PTK[32],
+			       LEN_TKIP_EK);
+		NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.PTK[48],
+			       LEN_TKIP_RXMICK);
+		NdisMoveMemory(pSharedKey->TxMic,
+			       &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK],
+			       LEN_TKIP_TXMICK);
+
+		/* Decide its ChiperAlg */
+		if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+			pSharedKey->CipherAlg = CIPHER_TKIP;
+		else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
+			pSharedKey->CipherAlg = CIPHER_AES;
+		else
+			pSharedKey->CipherAlg = CIPHER_NONE;
+
+		/* Update these related information to struct rt_mac_table_entry */
+		pEntry = &pAd->MacTab.Content[BSSID_WCID];
+		NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32],
+			       LEN_TKIP_EK);
+		NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48],
+			       LEN_TKIP_RXMICK);
+		NdisMoveMemory(pEntry->PairwiseKey.TxMic,
+			       &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK],
+			       LEN_TKIP_TXMICK);
+		pEntry->PairwiseKey.CipherAlg = pSharedKey->CipherAlg;
+
+		/* Update pairwise key information to ASIC Shared Key Table */
+		AsicAddSharedKeyEntry(pAd,
+				      BSS0,
+				      0,
+				      pSharedKey->CipherAlg,
+				      pSharedKey->Key,
+				      pSharedKey->TxMic, pSharedKey->RxMic);
+
+		/* Update ASIC WCID attribute table and IVEIV table */
+		RTMPAddWcidAttributeEntry(pAd,
+					  BSS0,
+					  0, pSharedKey->CipherAlg, pEntry);
+
+	}
+
+	/* open 802.1x port control and privacy filter */
+	if (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK ||
+	    pEntry->AuthMode == Ndis802_11AuthModeWPA2) {
+		pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+		pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+
+		STA_PORT_SECURED(pAd);
+		/* Indicate Connected for GUI */
+		pAd->IndicateMediaState = NdisMediaStateConnected;
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("PeerPairMsg3Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n",
+			  GetAuthMode(pEntry->AuthMode),
+			  GetEncryptType(pEntry->WepStatus),
+			  GetEncryptType(group_cipher)));
+	} else {
+	}
+
+	/* Init 802.3 header and send out */
+	MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
+	RTMPToWirelessSta(pAd, pEntry,
+			  Header802_3, sizeof(Header802_3),
+			  (u8 *)& EAPOLPKT,
+			  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, TRUE);
+
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("<=== PeerPairMsg3Action: send Msg4 of 4-way \n"));
+}
+
+/*
+    ==========================================================================
+    Description:
+        When receiving the last packet of 4-way pairwisekey handshake.
+        Initilize 2-way groupkey handshake following.
+    Return:
+    ==========================================================================
+*/
+void PeerPairMsg4Action(struct rt_rtmp_adapter *pAd,
+			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
+{
+	struct rt_eapol_packet * pMsg4;
+	struct rt_header_802_11 * pHeader;
+	u32 MsgLen;
+	BOOLEAN Cancelled;
+	u8 group_cipher = Ndis802_11WEPDisabled;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg4Action\n"));
+
+	do {
+		if ((!pEntry) || (!pEntry->ValidAsCLI))
+			break;
+
+		if (Elem->MsgLen <
+		    (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
+		     sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
+			break;
+
+		if (pEntry->WpaState < AS_PTKINIT_NEGOTIATING)
+			break;
+
+		/* pointer to 802.11 header */
+		pHeader = (struct rt_header_802_11 *) Elem->Msg;
+
+		/* skip 802.11_header(24-byte) and LLC_header(8) */
+		pMsg4 =
+		    (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+		MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
+
+		/* Sanity Check peer Pairwise message 4 - Replay Counter, MIC */
+		if (PeerWpaMessageSanity
+		    (pAd, pMsg4, MsgLen, EAPOL_PAIR_MSG_4, pEntry) == FALSE)
+			break;
+
+		/* 3. uses the MLME.SETKEYS.request to configure PTK into MAC */
+		NdisZeroMemory(&pEntry->PairwiseKey, sizeof(struct rt_cipher_key));
+
+		/* reset IVEIV in Asic */
+		AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, 1, 0);
+
+		pEntry->PairwiseKey.KeyLen = LEN_TKIP_EK;
+		NdisMoveMemory(pEntry->PairwiseKey.Key, &pEntry->PTK[32],
+			       LEN_TKIP_EK);
+		NdisMoveMemory(pEntry->PairwiseKey.RxMic,
+			       &pEntry->PTK[TKIP_AP_RXMICK_OFFSET],
+			       LEN_TKIP_RXMICK);
+		NdisMoveMemory(pEntry->PairwiseKey.TxMic,
+			       &pEntry->PTK[TKIP_AP_TXMICK_OFFSET],
+			       LEN_TKIP_TXMICK);
+
+		/* Set pairwise key to Asic */
+		{
+			pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
+			if (pEntry->WepStatus == Ndis802_11Encryption2Enabled)
+				pEntry->PairwiseKey.CipherAlg = CIPHER_TKIP;
+			else if (pEntry->WepStatus ==
+				 Ndis802_11Encryption3Enabled)
+				pEntry->PairwiseKey.CipherAlg = CIPHER_AES;
+
+			/* Add Pair-wise key to Asic */
+			AsicAddPairwiseKeyEntry(pAd,
+						pEntry->Addr,
+						(u8)pEntry->Aid,
+						&pEntry->PairwiseKey);
+
+			/* update WCID attribute table and IVEIV table for this entry */
+			RTMPAddWcidAttributeEntry(pAd,
+						  pEntry->apidx,
+						  0,
+						  pEntry->PairwiseKey.CipherAlg,
+						  pEntry);
+		}
+
+		/* 4. upgrade state */
+		pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+		pEntry->WpaState = AS_PTKINITDONE;
+		pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+
+		if (pEntry->AuthMode == Ndis802_11AuthModeWPA2 ||
+		    pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) {
+			pEntry->GTKState = REKEY_ESTABLISHED;
+			RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
+
+			/* send wireless event - for set key done WPA2 */
+			if (pAd->CommonCfg.bWirelessEvent)
+				RTMPSendWirelessEvent(pAd,
+						      IW_SET_KEY_DONE_WPA2_EVENT_FLAG,
+						      pEntry->Addr,
+						      pEntry->apidx, 0);
+
+			DBGPRINT(RT_DEBUG_OFF,
+				 ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
+				  pEntry->AuthMode,
+				  GetAuthMode(pEntry->AuthMode),
+				  pEntry->WepStatus,
+				  GetEncryptType(pEntry->WepStatus),
+				  group_cipher, GetEncryptType(group_cipher)));
+		} else {
+			/* 5. init Group 2-way handshake if necessary. */
+			WPAStart2WayGroupHS(pAd, pEntry);
+
+			pEntry->ReTryCounter = GROUP_MSG1_RETRY_TIMER_CTR;
+			RTMPModTimer(&pEntry->RetryTimer,
+				     PEER_MSG3_RETRY_EXEC_INTV);
+		}
+	} while (FALSE);
+
+}
+
+/*
+    ==========================================================================
+    Description:
+        This is a function to send the first packet of 2-way groupkey handshake
+    Return:
+
+    ==========================================================================
+*/
+void WPAStart2WayGroupHS(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry)
+{
+	u8 Header802_3[14];
+	u8 TxTsc[6];
+	struct rt_eapol_packet EAPOLPKT;
+	u8 group_cipher = Ndis802_11WEPDisabled;
+	u8 default_key = 0;
+	u8 *gnonce_ptr = NULL;
+	u8 *gtk_ptr = NULL;
+	u8 *pBssid = NULL;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart2WayGroupHS\n"));
+
+	if ((!pEntry) || (!pEntry->ValidAsCLI))
+		return;
+
+	do {
+		/* Increment replay counter by 1 */
+		ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
+
+		/* Construct EAPoL message - Group Msg 1 */
+		NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
+		ConstructEapolMsg(pEntry,
+				  group_cipher,
+				  EAPOL_GROUP_MSG_1,
+				  default_key,
+				  (u8 *) gnonce_ptr,
+				  TxTsc, (u8 *) gtk_ptr, NULL, 0, &EAPOLPKT);
+
+		/* Make outgoing frame */
+		MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
+		RTMPToWirelessSta(pAd, pEntry,
+				  Header802_3, LENGTH_802_3,
+				  (u8 *)& EAPOLPKT,
+				  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4,
+				  FALSE);
+
+	} while (FALSE);
+
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("<=== WPAStart2WayGroupHS : send out Group Message 1 \n"));
+
+	return;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Process Group key 2-way handshaking
+
+	Arguments:
+		pAd	Pointer	to our adapter
+		Elem		Message body
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+void PeerGroupMsg1Action(struct rt_rtmp_adapter *pAd,
+			 struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
+{
+	u8 Header802_3[14];
+	struct rt_eapol_packet EAPOLPKT;
+	struct rt_eapol_packet * pGroup;
+	u32 MsgLen;
+	BOOLEAN Cancelled;
+	u8 default_key = 0;
+	u8 group_cipher = Ndis802_11WEPDisabled;
+	u8 *pCurrentAddr = NULL;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg1Action \n"));
+
+	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
+		return;
+
+	{
+		pCurrentAddr = pAd->CurrentAddress;
+		group_cipher = pAd->StaCfg.GroupCipher;
+		default_key = pAd->StaCfg.DefaultKeyId;
+	}
+
+	/* Process Group Message 1 frame. skip 802.11 header(24) & LLC_SNAP header(8) */
+	pGroup = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
+
+	/* Sanity Check peer group message 1 - Replay Counter, MIC, RSNIE */
+	if (PeerWpaMessageSanity(pAd, pGroup, MsgLen, EAPOL_GROUP_MSG_1, pEntry)
+	    == FALSE)
+		return;
+
+	/* delete retry timer */
+	RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
+
+	/* Save Replay counter, it will use to construct message 2 */
+	NdisMoveMemory(pEntry->R_Counter, pGroup->KeyDesc.ReplayCounter,
+		       LEN_KEY_DESC_REPLAY);
+
+	/* Construct EAPoL message - Group Msg 2 */
+	NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
+	ConstructEapolMsg(pEntry, group_cipher, EAPOL_GROUP_MSG_2, default_key, NULL,	/* Nonce not used */
+			  NULL,	/* TxRSC not used */
+			  NULL,	/* GTK not used */
+			  NULL,	/* RSN IE not used */
+			  0, &EAPOLPKT);
+
+	/* open 802.1x port control and privacy filter */
+	pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+	pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+
+	STA_PORT_SECURED(pAd);
+	/* Indicate Connected for GUI */
+	pAd->IndicateMediaState = NdisMediaStateConnected;
+
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("PeerGroupMsg1Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n",
+		  GetAuthMode(pEntry->AuthMode),
+		  GetEncryptType(pEntry->WepStatus),
+		  GetEncryptType(group_cipher)));
+
+	/* init header and Fill Packet and send Msg 2 to authenticator */
+	MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
+	RTMPToWirelessSta(pAd, pEntry,
+			  Header802_3, sizeof(Header802_3),
+			  (u8 *)& EAPOLPKT,
+			  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, FALSE);
+
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("<=== PeerGroupMsg1Action: sned group message 2\n"));
+}
+
+/*
+    ==========================================================================
+    Description:
+        When receiving the last packet of 2-way groupkey handshake.
+    Return:
+    ==========================================================================
+*/
+void PeerGroupMsg2Action(struct rt_rtmp_adapter *pAd,
+			 struct rt_mac_table_entry *pEntry,
+			 void * Msg, u32 MsgLen)
+{
+	u32 Len;
+	u8 *pData;
+	BOOLEAN Cancelled;
+	struct rt_eapol_packet * pMsg2;
+	u8 group_cipher = Ndis802_11WEPDisabled;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg2Action \n"));
+
+	do {
+		if ((!pEntry) || (!pEntry->ValidAsCLI))
+			break;
+
+		if (MsgLen <
+		    (LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(struct rt_key_descripter) -
+		     MAX_LEN_OF_RSNIE - 2))
+			break;
+
+		if (pEntry->WpaState != AS_PTKINITDONE)
+			break;
+
+		pData = (u8 *)Msg;
+		pMsg2 = (struct rt_eapol_packet *) (pData + LENGTH_802_1_H);
+		Len = MsgLen - LENGTH_802_1_H;
+
+		/* Sanity Check peer group message 2 - Replay Counter, MIC */
+		if (PeerWpaMessageSanity
+		    (pAd, pMsg2, Len, EAPOL_GROUP_MSG_2, pEntry) == FALSE)
+			break;
+
+		/* 3.  upgrade state */
+
+		RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
+		pEntry->GTKState = REKEY_ESTABLISHED;
+
+		if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2)
+		    || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) {
+			/* send wireless event - for set key done WPA2 */
+			if (pAd->CommonCfg.bWirelessEvent)
+				RTMPSendWirelessEvent(pAd,
+						      IW_SET_KEY_DONE_WPA2_EVENT_FLAG,
+						      pEntry->Addr,
+						      pEntry->apidx, 0);
+
+			DBGPRINT(RT_DEBUG_OFF,
+				 ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
+				  pEntry->AuthMode,
+				  GetAuthMode(pEntry->AuthMode),
+				  pEntry->WepStatus,
+				  GetEncryptType(pEntry->WepStatus),
+				  group_cipher, GetEncryptType(group_cipher)));
+		} else {
+			/* send wireless event - for set key done WPA */
+			if (pAd->CommonCfg.bWirelessEvent)
+				RTMPSendWirelessEvent(pAd,
+						      IW_SET_KEY_DONE_WPA1_EVENT_FLAG,
+						      pEntry->Addr,
+						      pEntry->apidx, 0);
+
+			DBGPRINT(RT_DEBUG_OFF,
+				 ("AP SETKEYS DONE - WPA1, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
+				  pEntry->AuthMode,
+				  GetAuthMode(pEntry->AuthMode),
+				  pEntry->WepStatus,
+				  GetEncryptType(pEntry->WepStatus),
+				  group_cipher, GetEncryptType(group_cipher)));
+		}
+	} while (FALSE);
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Classify WPA EAP message type
+
+	Arguments:
+		EAPType		Value of EAP message type
+		MsgType		Internal Message definition for MLME state machine
+
+	Return Value:
+		TRUE		Found appropriate message type
+		FALSE		No appropriate message type
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+		All these constants are defined in wpa.h
+		For supplicant, there is only EAPOL Key message avaliable
+
+	========================================================================
+*/
+BOOLEAN WpaMsgTypeSubst(u8 EAPType, int * MsgType)
+{
+	switch (EAPType) {
+	case EAPPacket:
+		*MsgType = MT2_EAPPacket;
+		break;
+	case EAPOLStart:
+		*MsgType = MT2_EAPOLStart;
+		break;
+	case EAPOLLogoff:
+		*MsgType = MT2_EAPOLLogoff;
+		break;
+	case EAPOLKey:
+		*MsgType = MT2_EAPOLKey;
+		break;
+	case EAPOLASFAlert:
+		*MsgType = MT2_EAPOLASFAlert;
+		break;
+	default:
+		return FALSE;
+	}
+	return TRUE;
+}
 
 /*
 	========================================================================
@@ -67,72 +1261,118 @@
 		It is used to generate PTK, GTK or some specific random value.
 
 	Arguments:
-		UCHAR	*key,		-	the key material for HMAC_SHA1 use
-		INT		key_len		-	the length of key
-		UCHAR	*prefix		-	a prefix label
-		INT		prefix_len	-	the length of the label
-		UCHAR	*data		-	a specific data with variable length
-		INT		data_len	-	the length of a specific data
-		INT		len			-	the output lenght
+		u8	*key,		-	the key material for HMAC_SHA1 use
+		int		key_len		-	the length of key
+		u8	*prefix		-	a prefix label
+		int		prefix_len	-	the length of the label
+		u8	*data		-	a specific data with variable length
+		int		data_len	-	the length of a specific data
+		int		len			-	the output lenght
 
 	Return Value:
-		UCHAR	*output		-	the calculated result
+		u8	*output		-	the calculated result
 
 	Note:
 		802.11i-2004	Annex H.3
 
 	========================================================================
 */
-VOID	PRF(
-	IN	UCHAR	*key,
-	IN	INT		key_len,
-	IN	UCHAR	*prefix,
-	IN	INT		prefix_len,
-	IN	UCHAR	*data,
-	IN	INT		data_len,
-	OUT	UCHAR	*output,
-	IN	INT		len)
+void PRF(u8 * key,
+	 int key_len,
+	 u8 * prefix,
+	 int prefix_len,
+	 u8 * data, int data_len, u8 * output, int len)
 {
-	INT		i;
-    UCHAR   *input;
-	INT		currentindex = 0;
-	INT		total_len;
+	int i;
+	u8 *input;
+	int currentindex = 0;
+	int total_len;
 
-	// Allocate memory for input
-	os_alloc_mem(NULL, (PUCHAR *)&input, 1024);
+	/* Allocate memory for input */
+	os_alloc_mem(NULL, (u8 **) & input, 1024);
 
-    if (input == NULL)
-    {
-        DBGPRINT(RT_DEBUG_ERROR, ("!!!PRF: no memory!!!\n"));
-        return;
-    }
-
-	// Generate concatenation input
+	if (input == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR, ("PRF: no memory!\n"));
+		return;
+	}
+	/* Generate concatenation input */
 	NdisMoveMemory(input, prefix, prefix_len);
 
-	// Concatenate a single octet containing 0
-	input[prefix_len] =	0;
+	/* Concatenate a single octet containing 0 */
+	input[prefix_len] = 0;
 
-	// Concatenate specific data
+	/* Concatenate specific data */
 	NdisMoveMemory(&input[prefix_len + 1], data, data_len);
-	total_len =	prefix_len + 1 + data_len;
+	total_len = prefix_len + 1 + data_len;
 
-	// Concatenate a single octet containing 0
-	// This octet shall be update later
+	/* Concatenate a single octet containing 0 */
+	/* This octet shall be update later */
 	input[total_len] = 0;
 	total_len++;
 
-	// Iterate to calculate the result by hmac-sha-1
-	// Then concatenate to last result
-	for	(i = 0;	i <	(len + 19) / 20; i++)
-	{
-		HMAC_SHA1(input, total_len,	key, key_len, &output[currentindex]);
-		currentindex +=	20;
+	/* Iterate to calculate the result by hmac-sha-1 */
+	/* Then concatenate to last result */
+	for (i = 0; i < (len + 19) / 20; i++) {
+		HMAC_SHA1(key, key_len, input, total_len, &output[currentindex],
+			  SHA1_DIGEST_SIZE);
+		currentindex += 20;
 
-		// update the last octet
+		/* update the last octet */
 		input[total_len - 1]++;
 	}
-    os_free_mem(NULL, input);
+	os_free_mem(NULL, input);
+}
+
+/*
+* F(P, S, c, i) = U1 xor U2 xor ... Uc
+* U1 = PRF(P, S || Int(i))
+* U2 = PRF(P, U1)
+* Uc = PRF(P, Uc-1)
+*/
+
+static void F(char *password, unsigned char *ssid, int ssidlength,
+	      int iterations, int count, unsigned char *output)
+{
+	unsigned char digest[36], digest1[SHA1_DIGEST_SIZE];
+	int i, j;
+
+	/* U1 = PRF(P, S || int(i)) */
+	memcpy(digest, ssid, ssidlength);
+	digest[ssidlength] = (unsigned char)((count >> 24) & 0xff);
+	digest[ssidlength + 1] = (unsigned char)((count >> 16) & 0xff);
+	digest[ssidlength + 2] = (unsigned char)((count >> 8) & 0xff);
+	digest[ssidlength + 3] = (unsigned char)(count & 0xff);
+	HMAC_SHA1((unsigned char *)password, (int)strlen(password), digest, ssidlength + 4, digest1, SHA1_DIGEST_SIZE);	/* for WPA update */
+
+	/* output = U1 */
+	memcpy(output, digest1, SHA1_DIGEST_SIZE);
+
+	for (i = 1; i < iterations; i++) {
+		/* Un = PRF(P, Un-1) */
+		HMAC_SHA1((unsigned char *)password, (int)strlen(password), digest1, SHA1_DIGEST_SIZE, digest, SHA1_DIGEST_SIZE);	/* for WPA update */
+		memcpy(digest1, digest, SHA1_DIGEST_SIZE);
+
+		/* output = output xor Un */
+		for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
+			output[j] ^= digest[j];
+		}
+	}
+}
+
+/*
+* password - ascii string up to 63 characters in length
+* ssid - octet string up to 32 octets
+* ssidlength - length of ssid in octets
+* output must be 40 octets in length and outputs 256 bits of key
+*/
+int PasswordHash(char *password, u8 *ssid, int ssidlength, u8 *output)
+{
+	if ((strlen(password) > 63) || (ssidlength > 32))
+		return 0;
+
+	F(password, ssid, ssidlength, 4096, 1, output);
+	F(password, ssid, ssidlength, 4096, 2, &output[SHA1_DIGEST_SIZE]);
+	return 1;
 }
 
 /*
@@ -143,7 +1383,7 @@
 		It shall be called by 4-way handshake processing.
 
 	Arguments:
-		pAd 	-	pointer to our pAdapter context
+		pAd	-	pointer to our pAdapter context
 		PMK		-	pointer to PMK
 		ANonce	-	pointer to ANonce
 		AA		-	pointer to Authenticator Address
@@ -159,56 +1399,55 @@
 
 	========================================================================
 */
-VOID WpaCountPTK(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR	*PMK,
-	IN	UCHAR	*ANonce,
-	IN	UCHAR	*AA,
-	IN	UCHAR	*SNonce,
-	IN	UCHAR	*SA,
-	OUT	UCHAR	*output,
-	IN	UINT	len)
+void WpaDerivePTK(struct rt_rtmp_adapter *pAd,
+		  u8 * PMK,
+		  u8 * ANonce,
+		  u8 * AA,
+		  u8 * SNonce,
+		  u8 * SA, u8 * output, u32 len)
 {
-	UCHAR	concatenation[76];
-	UINT	CurrPos = 0;
-	UCHAR	temp[32];
-	UCHAR	Prefix[] = {'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ',
-						'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'};
+	u8 concatenation[76];
+	u32 CurrPos = 0;
+	u8 temp[32];
+	u8 Prefix[] =
+	    { 'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ',
+		'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'
+	};
 
-	// initiate the concatenation input
+	/* initiate the concatenation input */
 	NdisZeroMemory(temp, sizeof(temp));
 	NdisZeroMemory(concatenation, 76);
 
-	// Get smaller address
+	/* Get smaller address */
 	if (RTMPCompareMemory(SA, AA, 6) == 1)
 		NdisMoveMemory(concatenation, AA, 6);
 	else
 		NdisMoveMemory(concatenation, SA, 6);
 	CurrPos += 6;
 
-	// Get larger address
+	/* Get larger address */
 	if (RTMPCompareMemory(SA, AA, 6) == 1)
 		NdisMoveMemory(&concatenation[CurrPos], SA, 6);
 	else
 		NdisMoveMemory(&concatenation[CurrPos], AA, 6);
 
-	// store the larger mac address for backward compatible of
-	// ralink proprietary STA-key issue
+	/* store the larger mac address for backward compatible of */
+	/* ralink proprietary STA-key issue */
 	NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN);
 	CurrPos += 6;
 
-	// Get smaller Nonce
+	/* Get smaller Nonce */
 	if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
-		NdisMoveMemory(&concatenation[CurrPos], temp, 32);	// patch for ralink proprietary STA-key issue
+		NdisMoveMemory(&concatenation[CurrPos], temp, 32);	/* patch for ralink proprietary STA-key issue */
 	else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
 		NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
 	else
 		NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
 	CurrPos += 32;
 
-	// Get larger Nonce
+	/* Get larger Nonce */
 	if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
-		NdisMoveMemory(&concatenation[CurrPos], temp, 32);	// patch for ralink proprietary STA-key issue
+		NdisMoveMemory(&concatenation[CurrPos], temp, 32);	/* patch for ralink proprietary STA-key issue */
 	else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
 		NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
 	else
@@ -217,7 +1456,7 @@
 
 	hex_dump("concatenation=", concatenation, 76);
 
-	// Use PRF to generate PTK
+	/* Use PRF to generate PTK */
 	PRF(PMK, LEN_MASTER_KEY, Prefix, 22, concatenation, 76, output, len);
 
 }
@@ -239,46 +1478,43 @@
 
 	========================================================================
 */
-VOID	GenRandom(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			*macAddr,
-	OUT	UCHAR			*random)
+void GenRandom(struct rt_rtmp_adapter *pAd, u8 * macAddr, u8 * random)
 {
-	INT		i, curr;
-	UCHAR	local[80], KeyCounter[32];
-	UCHAR	result[80];
-	ULONG	CurrentTime;
-	UCHAR	prefix[] = {'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r'};
+	int i, curr;
+	u8 local[80], KeyCounter[32];
+	u8 result[80];
+	unsigned long CurrentTime;
+	u8 prefix[] =
+	    { 'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r' };
 
-	// Zero the related information
+	/* Zero the related information */
 	NdisZeroMemory(result, 80);
 	NdisZeroMemory(local, 80);
 	NdisZeroMemory(KeyCounter, 32);
 
-	for	(i = 0;	i <	32;	i++)
-	{
-		// copy the local MAC address
+	for (i = 0; i < 32; i++) {
+		/* copy the local MAC address */
 		COPY_MAC_ADDR(local, macAddr);
-		curr =	MAC_ADDR_LEN;
+		curr = MAC_ADDR_LEN;
 
-		// concatenate the current time
+		/* concatenate the current time */
 		NdisGetSystemUpTime(&CurrentTime);
-		NdisMoveMemory(&local[curr],  &CurrentTime,	sizeof(CurrentTime));
-		curr +=	sizeof(CurrentTime);
+		NdisMoveMemory(&local[curr], &CurrentTime, sizeof(CurrentTime));
+		curr += sizeof(CurrentTime);
 
-		// concatenate the last result
-		NdisMoveMemory(&local[curr],  result, 32);
-		curr +=	32;
+		/* concatenate the last result */
+		NdisMoveMemory(&local[curr], result, 32);
+		curr += 32;
 
-		// concatenate a variable
-		NdisMoveMemory(&local[curr],  &i,  2);
-		curr +=	2;
+		/* concatenate a variable */
+		NdisMoveMemory(&local[curr], &i, 2);
+		curr += 2;
 
-		// calculate the result
-		PRF(KeyCounter, 32, prefix,12, local, curr, result, 32);
+		/* calculate the result */
+		PRF(KeyCounter, 32, prefix, 12, local, curr, result, 32);
 	}
 
-	NdisMoveMemory(random, result,	32);
+	NdisMoveMemory(random, result, 32);
 }
 
 /*
@@ -290,8 +1526,8 @@
 
 	Arguments:
 		pAd			-	pointer to our pAdapter context
-    	ElementID	-	indicate the WPA1 or WPA2
-    	WepStatus	-	indicate the encryption type
+	ElementID	-	indicate the WPA1 or WPA2
+	WepStatus	-	indicate the encryption type
 		bMixCipher	-	a boolean to indicate the pairwise cipher and group
 						cipher are the same or not
 
@@ -301,170 +1537,169 @@
 
 	========================================================================
 */
-static VOID RTMPInsertRsnIeCipher(
-	IN  PRTMP_ADAPTER   pAd,
-	IN	UCHAR			ElementID,
-	IN	UINT			WepStatus,
-	IN	BOOLEAN			bMixCipher,
-	IN	UCHAR			FlexibleCipher,
-	OUT	PUCHAR			pRsnIe,
-	OUT	UCHAR			*rsn_len)
+static void RTMPMakeRsnIeCipher(struct rt_rtmp_adapter *pAd,
+				u8 ElementID,
+				u32 WepStatus,
+				IN BOOLEAN bMixCipher,
+				u8 FlexibleCipher,
+				u8 *pRsnIe, u8 * rsn_len)
 {
-	UCHAR	PairwiseCnt;
+	u8 PairwiseCnt;
 
 	*rsn_len = 0;
 
-	// decide WPA2 or WPA1
-	if (ElementID == Wpa2Ie)
-	{
-		RSNIE2	*pRsnie_cipher = (RSNIE2*)pRsnIe;
+	/* decide WPA2 or WPA1 */
+	if (ElementID == Wpa2Ie) {
+		struct rt_rsnie2 *pRsnie_cipher = (struct rt_rsnie2 *)pRsnIe;
 
-		// Assign the verson as 1
+		/* Assign the verson as 1 */
 		pRsnie_cipher->version = 1;
 
-        switch (WepStatus)
-        {
-        	// TKIP mode
-            case Ndis802_11Encryption2Enabled:
-                NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
-                pRsnie_cipher->ucount = 1;
-                NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4);
-                *rsn_len = sizeof(RSNIE2);
-                break;
+		switch (WepStatus) {
+			/* TKIP mode */
+		case Ndis802_11Encryption2Enabled:
+			NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
+			pRsnie_cipher->ucount = 1;
+			NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
+				       OUI_WPA2_TKIP, 4);
+			*rsn_len = sizeof(struct rt_rsnie2);
+			break;
 
-			// AES mode
-            case Ndis802_11Encryption3Enabled:
-				if (bMixCipher)
-					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
-				else
-					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_CCMP, 4);
-                pRsnie_cipher->ucount = 1;
-                NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4);
-                *rsn_len = sizeof(RSNIE2);
-                break;
+			/* AES mode */
+		case Ndis802_11Encryption3Enabled:
+			if (bMixCipher)
+				NdisMoveMemory(pRsnie_cipher->mcast,
+					       OUI_WPA2_TKIP, 4);
+			else
+				NdisMoveMemory(pRsnie_cipher->mcast,
+					       OUI_WPA2_CCMP, 4);
+			pRsnie_cipher->ucount = 1;
+			NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
+				       OUI_WPA2_CCMP, 4);
+			*rsn_len = sizeof(struct rt_rsnie2);
+			break;
 
-			// TKIP-AES mix mode
-            case Ndis802_11Encryption4Enabled:
-                NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
+			/* TKIP-AES mix mode */
+		case Ndis802_11Encryption4Enabled:
+			NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
 
-				PairwiseCnt = 1;
-				// Insert WPA2 TKIP as the first pairwise cipher
-				if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher))
-				{
-                	NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4);
-					// Insert WPA2 AES as the secondary pairwise cipher
-					if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher))
-					{
-                		NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA2_CCMP, 4);
-						PairwiseCnt = 2;
-					}
+			PairwiseCnt = 1;
+			/* Insert WPA2 TKIP as the first pairwise cipher */
+			if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher)) {
+				NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
+					       OUI_WPA2_TKIP, 4);
+				/* Insert WPA2 AES as the secondary pairwise cipher */
+				if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher)) {
+					NdisMoveMemory(pRsnie_cipher->ucast[0].
+						       oui + 4, OUI_WPA2_CCMP,
+						       4);
+					PairwiseCnt = 2;
 				}
-				else
-				{
-					// Insert WPA2 AES as the first pairwise cipher
-					NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4);
-				}
-
-                pRsnie_cipher->ucount = PairwiseCnt;
-                *rsn_len = sizeof(RSNIE2) + (4 * (PairwiseCnt - 1));
-                break;
-        }
-
-		if ((pAd->OpMode == OPMODE_STA) &&
-			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
-			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
-		{
-			UINT GroupCipher = pAd->StaCfg.GroupCipher;
-			switch(GroupCipher)
-			{
-				case Ndis802_11GroupWEP40Enabled:
-					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP40, 4);
-					break;
-				case Ndis802_11GroupWEP104Enabled:
-					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP104, 4);
-					break;
+			} else {
+				/* Insert WPA2 AES as the first pairwise cipher */
+				NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
+					       OUI_WPA2_CCMP, 4);
 			}
+
+			pRsnie_cipher->ucount = PairwiseCnt;
+			*rsn_len = sizeof(struct rt_rsnie2) + (4 * (PairwiseCnt - 1));
+			break;
 		}
 
-		// swap for big-endian platform
+		if ((pAd->OpMode == OPMODE_STA) &&
+		    (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
+		    (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) {
+			u32 GroupCipher = pAd->StaCfg.GroupCipher;
+			switch (GroupCipher) {
+			case Ndis802_11GroupWEP40Enabled:
+				NdisMoveMemory(pRsnie_cipher->mcast,
+					       OUI_WPA2_WEP40, 4);
+				break;
+			case Ndis802_11GroupWEP104Enabled:
+				NdisMoveMemory(pRsnie_cipher->mcast,
+					       OUI_WPA2_WEP104, 4);
+				break;
+			}
+		}
+		/* swap for big-endian platform */
 		pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
-	    pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
-	}
-	else
-	{
-		RSNIE	*pRsnie_cipher = (RSNIE*)pRsnIe;
+		pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
+	} else {
+		struct rt_rsnie *pRsnie_cipher = (struct rt_rsnie *)pRsnIe;
 
-		// Assign OUI and version
+		/* Assign OUI and version */
 		NdisMoveMemory(pRsnie_cipher->oui, OUI_WPA_VERSION, 4);
-        pRsnie_cipher->version = 1;
+		pRsnie_cipher->version = 1;
 
-		switch (WepStatus)
-		{
-			// TKIP mode
-            case Ndis802_11Encryption2Enabled:
-                NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
-                pRsnie_cipher->ucount = 1;
-                NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4);
-                *rsn_len = sizeof(RSNIE);
-                break;
+		switch (WepStatus) {
+			/* TKIP mode */
+		case Ndis802_11Encryption2Enabled:
+			NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
+			pRsnie_cipher->ucount = 1;
+			NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
+				       OUI_WPA_TKIP, 4);
+			*rsn_len = sizeof(struct rt_rsnie);
+			break;
 
-			// AES mode
-            case Ndis802_11Encryption3Enabled:
-				if (bMixCipher)
-					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
-				else
-					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_CCMP, 4);
-                pRsnie_cipher->ucount = 1;
-                NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4);
-                *rsn_len = sizeof(RSNIE);
-                break;
+			/* AES mode */
+		case Ndis802_11Encryption3Enabled:
+			if (bMixCipher)
+				NdisMoveMemory(pRsnie_cipher->mcast,
+					       OUI_WPA_TKIP, 4);
+			else
+				NdisMoveMemory(pRsnie_cipher->mcast,
+					       OUI_WPA_CCMP, 4);
+			pRsnie_cipher->ucount = 1;
+			NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
+				       OUI_WPA_CCMP, 4);
+			*rsn_len = sizeof(struct rt_rsnie);
+			break;
 
-			// TKIP-AES mix mode
-            case Ndis802_11Encryption4Enabled:
-                NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
+			/* TKIP-AES mix mode */
+		case Ndis802_11Encryption4Enabled:
+			NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
 
-				PairwiseCnt = 1;
-				// Insert WPA TKIP as the first pairwise cipher
-				if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher))
-				{
-                	NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4);
-					// Insert WPA AES as the secondary pairwise cipher
-					if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher))
-					{
-                		NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA_CCMP, 4);
-						PairwiseCnt = 2;
-					}
+			PairwiseCnt = 1;
+			/* Insert WPA TKIP as the first pairwise cipher */
+			if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher)) {
+				NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
+					       OUI_WPA_TKIP, 4);
+				/* Insert WPA AES as the secondary pairwise cipher */
+				if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher)) {
+					NdisMoveMemory(pRsnie_cipher->ucast[0].
+						       oui + 4, OUI_WPA_CCMP,
+						       4);
+					PairwiseCnt = 2;
 				}
-				else
-				{
-					// Insert WPA AES as the first pairwise cipher
-					NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4);
-				}
-
-                pRsnie_cipher->ucount = PairwiseCnt;
-                *rsn_len = sizeof(RSNIE) + (4 * (PairwiseCnt - 1));
-                break;
-        }
-
-		if ((pAd->OpMode == OPMODE_STA) &&
-			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
-			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
-		{
-			UINT GroupCipher = pAd->StaCfg.GroupCipher;
-			switch(GroupCipher)
-			{
-				case Ndis802_11GroupWEP40Enabled:
-					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP40, 4);
-					break;
-				case Ndis802_11GroupWEP104Enabled:
-					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP104, 4);
-					break;
+			} else {
+				/* Insert WPA AES as the first pairwise cipher */
+				NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
+					       OUI_WPA_CCMP, 4);
 			}
+
+			pRsnie_cipher->ucount = PairwiseCnt;
+			*rsn_len = sizeof(struct rt_rsnie) + (4 * (PairwiseCnt - 1));
+			break;
 		}
 
-		// swap for big-endian platform
+		if ((pAd->OpMode == OPMODE_STA) &&
+		    (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
+		    (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) {
+			u32 GroupCipher = pAd->StaCfg.GroupCipher;
+			switch (GroupCipher) {
+			case Ndis802_11GroupWEP40Enabled:
+				NdisMoveMemory(pRsnie_cipher->mcast,
+					       OUI_WPA_WEP40, 4);
+				break;
+			case Ndis802_11GroupWEP104Enabled:
+				NdisMoveMemory(pRsnie_cipher->mcast,
+					       OUI_WPA_WEP104, 4);
+				break;
+			}
+		}
+		/* swap for big-endian platform */
 		pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
-	    pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
+		pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
 	}
 }
 
@@ -477,8 +1712,8 @@
 
 	Arguments:
 		pAd			-	pointer to our pAdapter context
-    	ElementID	-	indicate the WPA1 or WPA2
-    	AuthMode	-	indicate the authentication mode
+	ElementID	-	indicate the WPA1 or WPA2
+	AuthMode	-	indicate the authentication mode
 		apidx		-	indicate the interface index
 
 	Return Value:
@@ -487,62 +1722,66 @@
 
 	========================================================================
 */
-static VOID RTMPInsertRsnIeAKM(
-	IN  PRTMP_ADAPTER   pAd,
-	IN	UCHAR			ElementID,
-	IN	UINT			AuthMode,
-	IN	UCHAR			apidx,
-	OUT	PUCHAR			pRsnIe,
-	OUT	UCHAR			*rsn_len)
+static void RTMPMakeRsnIeAKM(struct rt_rtmp_adapter *pAd,
+			     u8 ElementID,
+			     u32 AuthMode,
+			     u8 apidx,
+			     u8 *pRsnIe, u8 * rsn_len)
 {
-	RSNIE_AUTH		*pRsnie_auth;
+	struct rt_rsnie_auth *pRsnie_auth;
+	u8 AkmCnt = 1;	/* default as 1 */
 
-	pRsnie_auth = (RSNIE_AUTH*)(pRsnIe + (*rsn_len));
+	pRsnie_auth = (struct rt_rsnie_auth *) (pRsnIe + (*rsn_len));
 
-	// decide WPA2 or WPA1
-	if (ElementID == Wpa2Ie)
-	{
-		switch (AuthMode)
-        {
-            case Ndis802_11AuthModeWPA2:
-            case Ndis802_11AuthModeWPA1WPA2:
-                pRsnie_auth->acount = 1;
-                	NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_8021X_AKM, 4);
-                break;
+	/* decide WPA2 or WPA1 */
+	if (ElementID == Wpa2Ie) {
 
-            case Ndis802_11AuthModeWPA2PSK:
-            case Ndis802_11AuthModeWPA1PSKWPA2PSK:
-                pRsnie_auth->acount = 1;
-                	NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_PSK_AKM, 4);
-                break;
-        }
-	}
-	else
-	{
-		switch (AuthMode)
-        {
-            case Ndis802_11AuthModeWPA:
-            case Ndis802_11AuthModeWPA1WPA2:
-                pRsnie_auth->acount = 1;
-                NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_8021X_AKM, 4);
-                break;
+		switch (AuthMode) {
+		case Ndis802_11AuthModeWPA2:
+		case Ndis802_11AuthModeWPA1WPA2:
+			NdisMoveMemory(pRsnie_auth->auth[0].oui,
+				       OUI_WPA2_8021X_AKM, 4);
+			break;
 
-            case Ndis802_11AuthModeWPAPSK:
-            case Ndis802_11AuthModeWPA1PSKWPA2PSK:
-                pRsnie_auth->acount = 1;
-                NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_PSK_AKM, 4);
-                break;
+		case Ndis802_11AuthModeWPA2PSK:
+		case Ndis802_11AuthModeWPA1PSKWPA2PSK:
+			NdisMoveMemory(pRsnie_auth->auth[0].oui,
+				       OUI_WPA2_PSK_AKM, 4);
+			break;
+		default:
+			AkmCnt = 0;
+			break;
 
-			case Ndis802_11AuthModeWPANone:
-                pRsnie_auth->acount = 1;
-                NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_NONE_AKM, 4);
-                break;
-        }
+		}
+	} else {
+		switch (AuthMode) {
+		case Ndis802_11AuthModeWPA:
+		case Ndis802_11AuthModeWPA1WPA2:
+			NdisMoveMemory(pRsnie_auth->auth[0].oui,
+				       OUI_WPA_8021X_AKM, 4);
+			break;
+
+		case Ndis802_11AuthModeWPAPSK:
+		case Ndis802_11AuthModeWPA1PSKWPA2PSK:
+			NdisMoveMemory(pRsnie_auth->auth[0].oui,
+				       OUI_WPA_PSK_AKM, 4);
+			break;
+
+		case Ndis802_11AuthModeWPANone:
+			NdisMoveMemory(pRsnie_auth->auth[0].oui,
+				       OUI_WPA_NONE_AKM, 4);
+			break;
+		default:
+			AkmCnt = 0;
+			break;
+		}
 	}
 
+	pRsnie_auth->acount = AkmCnt;
 	pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount);
 
-	(*rsn_len) += sizeof(RSNIE_AUTH);	// update current RSNIE length
+	/* update current RSNIE length */
+	(*rsn_len) += (sizeof(struct rt_rsnie_auth) + (4 * (AkmCnt - 1)));
 
 }
 
@@ -555,7 +1794,7 @@
 
 	Arguments:
 		pAd			-	pointer to our pAdapter context
-    	ElementID	-	indicate the WPA1 or WPA2
+	ElementID	-	indicate the WPA1 or WPA2
 		apidx		-	indicate the interface index
 
 	Return Value:
@@ -564,29 +1803,25 @@
 
 	========================================================================
 */
-static VOID RTMPInsertRsnIeCap(
-	IN  PRTMP_ADAPTER   pAd,
-	IN	UCHAR			ElementID,
-	IN	UCHAR			apidx,
-	OUT	PUCHAR			pRsnIe,
-	OUT	UCHAR			*rsn_len)
+static void RTMPMakeRsnIeCap(struct rt_rtmp_adapter *pAd,
+			     u8 ElementID,
+			     u8 apidx,
+			     u8 *pRsnIe, u8 * rsn_len)
 {
-	RSN_CAPABILITIES    *pRSN_Cap;
+	RSN_CAPABILITIES *pRSN_Cap;
 
-	// it could be ignored in WPA1 mode
+	/* it could be ignored in WPA1 mode */
 	if (ElementID == WpaIe)
 		return;
 
-	pRSN_Cap = (RSN_CAPABILITIES*)(pRsnIe + (*rsn_len));
-
+	pRSN_Cap = (RSN_CAPABILITIES *) (pRsnIe + (*rsn_len));
 
 	pRSN_Cap->word = cpu2le16(pRSN_Cap->word);
 
-	(*rsn_len) += sizeof(RSN_CAPABILITIES);	// update current RSNIE length
+	(*rsn_len) += sizeof(RSN_CAPABILITIES);	/* update current RSNIE length */
 
 }
 
-
 /*
 	========================================================================
 
@@ -595,8 +1830,8 @@
 
 	Arguments:
 		pAd			-	pointer to our pAdapter context
-    	AuthMode	-	indicate the authentication mode
-    	WepStatus	-	indicate the encryption type
+	AuthMode	-	indicate the authentication mode
+	WepStatus	-	indicate the encryption type
 		apidx		-	indicate the interface index
 
 	Return Value:
@@ -605,48 +1840,43 @@
 
 	========================================================================
 */
-VOID RTMPMakeRSNIE(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  UINT            AuthMode,
-    IN  UINT            WepStatus,
-	IN	UCHAR			apidx)
+void RTMPMakeRSNIE(struct rt_rtmp_adapter *pAd,
+		   u32 AuthMode, u32 WepStatus, u8 apidx)
 {
-	PUCHAR		pRsnIe = NULL;			// primary RSNIE
-	UCHAR 		*rsnielen_cur_p = 0;	// the length of the primary RSNIE
-	UCHAR		*rsnielen_ex_cur_p = 0;	// the length of the secondary RSNIE
-	UCHAR		PrimaryRsnie;
-	BOOLEAN		bMixCipher = FALSE;	// indicate the pairwise and group cipher are different
-	UCHAR		p_offset;
-	WPA_MIX_PAIR_CIPHER		FlexibleCipher = WPA_TKIPAES_WPA2_TKIPAES;	// it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode
+	u8 *pRsnIe = NULL;	/* primary RSNIE */
+	u8 *rsnielen_cur_p = 0;	/* the length of the primary RSNIE */
+	u8 *rsnielen_ex_cur_p = 0;	/* the length of the secondary RSNIE */
+	u8 PrimaryRsnie;
+	BOOLEAN bMixCipher = FALSE;	/* indicate the pairwise and group cipher are different */
+	u8 p_offset;
+	WPA_MIX_PAIR_CIPHER FlexibleCipher = WPA_TKIPAES_WPA2_TKIPAES;	/* it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode */
 
 	rsnielen_cur_p = NULL;
 	rsnielen_ex_cur_p = NULL;
 
 	{
 		{
-			if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
-			{
+			if (pAd->StaCfg.WpaSupplicantUP !=
+			    WPA_SUPPLICANT_DISABLE) {
 				if (AuthMode < Ndis802_11AuthModeWPA)
 					return;
-			}
-			else
-			{
-				// Support WPAPSK or WPA2PSK in STA-Infra mode
-				// Support WPANone in STA-Adhoc mode
+			} else {
+				/* Support WPAPSK or WPA2PSK in STA-Infra mode */
+				/* Support WPANone in STA-Adhoc mode */
 				if ((AuthMode != Ndis802_11AuthModeWPAPSK) &&
-					(AuthMode != Ndis802_11AuthModeWPA2PSK) &&
-					(AuthMode != Ndis802_11AuthModeWPANone)
-					)
+				    (AuthMode != Ndis802_11AuthModeWPA2PSK) &&
+				    (AuthMode != Ndis802_11AuthModeWPANone)
+				    )
 					return;
 			}
 
-			DBGPRINT(RT_DEBUG_TRACE,("==> RTMPMakeRSNIE(STA)\n"));
+			DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPMakeRSNIE(STA)\n"));
 
-			// Zero RSNIE context
+			/* Zero RSNIE context */
 			pAd->StaCfg.RSNIE_Len = 0;
 			NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE);
 
-			// Pointer to RSNIE
+			/* Pointer to RSNIE */
 			rsnielen_cur_p = &pAd->StaCfg.RSNIE_Len;
 			pRsnIe = pAd->StaCfg.RSN_IE;
 
@@ -654,34 +1884,35 @@
 		}
 	}
 
-	// indicate primary RSNIE as WPA or WPA2
+	/* indicate primary RSNIE as WPA or WPA2 */
 	if ((AuthMode == Ndis802_11AuthModeWPA) ||
-		(AuthMode == Ndis802_11AuthModeWPAPSK) ||
-		(AuthMode == Ndis802_11AuthModeWPANone) ||
-		(AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
-		(AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
+	    (AuthMode == Ndis802_11AuthModeWPAPSK) ||
+	    (AuthMode == Ndis802_11AuthModeWPANone) ||
+	    (AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
+	    (AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
 		PrimaryRsnie = WpaIe;
 	else
 		PrimaryRsnie = Wpa2Ie;
 
 	{
-		// Build the primary RSNIE
-		// 1. insert cipher suite
-		RTMPInsertRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher, FlexibleCipher, pRsnIe, &p_offset);
+		/* Build the primary RSNIE */
+		/* 1. insert cipher suite */
+		RTMPMakeRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher,
+				    FlexibleCipher, pRsnIe, &p_offset);
 
-		// 2. insert AKM
-		RTMPInsertRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe, &p_offset);
+		/* 2. insert AKM */
+		RTMPMakeRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe,
+				 &p_offset);
 
-		// 3. insert capability
-		RTMPInsertRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset);
+		/* 3. insert capability */
+		RTMPMakeRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset);
 	}
 
-	// 4. update the RSNIE length
+	/* 4. update the RSNIE length */
 	*rsnielen_cur_p = p_offset;
 
 	hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p));
 
-
 }
 
 /*
@@ -693,144 +1924,1093 @@
 		pAd				-	pointer to our pAdapter context
 		pEntry			-	pointer to active entry
 		pData			-	the received frame
-		DataByteCount 	-	the received frame's length
+		DataByteCount	-	the received frame's length
 		FromWhichBSSID	-	indicate the interface index
 
     Return:
-         TRUE 			-	This frame is EAP frame
-         FALSE 			-	otherwise
+         TRUE			-	This frame is EAP frame
+         FALSE			-	otherwise
     ==========================================================================
 */
-BOOLEAN RTMPCheckWPAframe(
-    IN PRTMP_ADAPTER    pAd,
-    IN PMAC_TABLE_ENTRY	pEntry,
-    IN PUCHAR           pData,
-    IN ULONG            DataByteCount,
-	IN UCHAR			FromWhichBSSID)
+BOOLEAN RTMPCheckWPAframe(struct rt_rtmp_adapter *pAd,
+			  struct rt_mac_table_entry *pEntry,
+			  u8 *pData,
+			  unsigned long DataByteCount, u8 FromWhichBSSID)
 {
-	ULONG	Body_len;
+	unsigned long Body_len;
 	BOOLEAN Cancelled;
 
+	if (DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H))
+		return FALSE;
 
-    if(DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H))
-        return FALSE;
+	/* Skip LLC header */
+	if (NdisEqualMemory(SNAP_802_1H, pData, 6) ||
+	    /* Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL */
+	    NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6)) {
+		pData += 6;
+	}
+	/* Skip 2-bytes EAPoL type */
+	if (NdisEqualMemory(EAPOL, pData, 2)) {
+		pData += 2;
+	} else
+		return FALSE;
 
+	switch (*(pData + 1)) {
+	case EAPPacket:
+		Body_len = (*(pData + 2) << 8) | (*(pData + 3));
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n",
+			  Body_len));
+		break;
+	case EAPOLStart:
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Receive EAPOL-Start frame, TYPE = 1 \n"));
+		if (pEntry->EnqueueEapolStartTimerRunning !=
+		    EAPOL_START_DISABLE) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("Cancel the EnqueueEapolStartTimerRunning \n"));
+			RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer,
+					&Cancelled);
+			pEntry->EnqueueEapolStartTimerRunning =
+			    EAPOL_START_DISABLE;
+		}
+		break;
+	case EAPOLLogoff:
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Receive EAPOLLogoff frame, TYPE = 2 \n"));
+		break;
+	case EAPOLKey:
+		Body_len = (*(pData + 2) << 8) | (*(pData + 3));
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n",
+			  Body_len));
+		break;
+	case EAPOLASFAlert:
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Receive EAPOLASFAlert frame, TYPE = 4 \n"));
+		break;
+	default:
+		return FALSE;
 
-	// Skip LLC header
-    if (NdisEqualMemory(SNAP_802_1H, pData, 6) ||
-        // Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL
-        NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6))
-    {
-        pData += 6;
-    }
-	// Skip 2-bytes EAPoL type
-    if (NdisEqualMemory(EAPOL, pData, 2))
-    {
-        pData += 2;
-    }
-    else
-        return FALSE;
+	}
+	return TRUE;
+}
 
-    switch (*(pData+1))
-    {
-        case EAPPacket:
-			Body_len = (*(pData+2)<<8) | (*(pData+3));
-            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n", Body_len));
-            break;
-        case EAPOLStart:
-            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Start frame, TYPE = 1 \n"));
-			if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
-            {
-            	DBGPRINT(RT_DEBUG_TRACE, ("Cancel the EnqueueEapolStartTimerRunning \n"));
-                RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
-                pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
-            }
-            break;
-        case EAPOLLogoff:
-            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLLogoff frame, TYPE = 2 \n"));
-            break;
-        case EAPOLKey:
-			Body_len = (*(pData+2)<<8) | (*(pData+3));
-            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n", Body_len));
-            break;
-        case EAPOLASFAlert:
-            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLASFAlert frame, TYPE = 4 \n"));
-            break;
-        default:
-            return FALSE;
+/*
+    ==========================================================================
+    Description:
+		Report the EAP message type
 
-    }
-    return TRUE;
+	Arguments:
+		msg		-	EAPOL_PAIR_MSG_1
+					EAPOL_PAIR_MSG_2
+					EAPOL_PAIR_MSG_3
+					EAPOL_PAIR_MSG_4
+					EAPOL_GROUP_MSG_1
+					EAPOL_GROUP_MSG_2
+
+    Return:
+         message type string
+
+    ==========================================================================
+*/
+char *GetEapolMsgType(char msg)
+{
+	if (msg == EAPOL_PAIR_MSG_1)
+		return "Pairwise Message 1";
+	else if (msg == EAPOL_PAIR_MSG_2)
+		return "Pairwise Message 2";
+	else if (msg == EAPOL_PAIR_MSG_3)
+		return "Pairwise Message 3";
+	else if (msg == EAPOL_PAIR_MSG_4)
+		return "Pairwise Message 4";
+	else if (msg == EAPOL_GROUP_MSG_1)
+		return "Group Message 1";
+	else if (msg == EAPOL_GROUP_MSG_2)
+		return "Group Message 2";
+	else
+		return "Invalid Message";
 }
 
 /*
 	========================================================================
 
 	Routine Description:
-		Misc function to decrypt AES body
+    Check Sanity RSN IE of EAPoL message
+
+	Arguments:
+
+	Return Value:
+
+	========================================================================
+*/
+BOOLEAN RTMPCheckRSNIE(struct rt_rtmp_adapter *pAd,
+		       u8 *pData,
+		       u8 DataLen,
+		       struct rt_mac_table_entry *pEntry, u8 * Offset)
+{
+	u8 *pVIE;
+	u8 len;
+	struct rt_eid * pEid;
+	BOOLEAN result = FALSE;
+
+	pVIE = pData;
+	len = DataLen;
+	*Offset = 0;
+
+	while (len > sizeof(struct rt_rsnie2)) {
+		pEid = (struct rt_eid *) pVIE;
+		/* WPA RSN IE */
+		if ((pEid->Eid == IE_WPA)
+		    && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))) {
+			if ((pEntry->AuthMode == Ndis802_11AuthModeWPA
+			     || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK)
+			    &&
+			    (NdisEqualMemory
+			     (pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len))
+			    && (pEntry->RSNIE_Len == (pEid->Len + 2))) {
+				result = TRUE;
+			}
+
+			*Offset += (pEid->Len + 2);
+		}
+		/* WPA2 RSN IE */
+		else if ((pEid->Eid == IE_RSN)
+			 && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))) {
+			if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2
+			     || pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)
+			    && (pEid->Eid == pEntry->RSN_IE[0])
+			    && ((pEid->Len + 2) >= pEntry->RSNIE_Len)
+			    &&
+			    (NdisEqualMemory
+			     (pEid->Octet, &pEntry->RSN_IE[2],
+			      pEntry->RSNIE_Len - 2))) {
+
+				result = TRUE;
+			}
+
+			*Offset += (pEid->Len + 2);
+		} else {
+			break;
+		}
+
+		pVIE += (pEid->Len + 2);
+		len -= (pEid->Len + 2);
+	}
+
+	return result;
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+    Parse KEYDATA field.  KEYDATA[] May contain 2 RSN IE and optionally GTK.
+    GTK  is encaptulated in KDE format at  p.83 802.11i D10
 
 	Arguments:
 
 	Return Value:
 
 	Note:
-		This function references to	RFC	3394 for aes key unwrap algorithm.
+        802.11i D10
 
 	========================================================================
 */
-VOID	AES_GTK_KEY_UNWRAP(
-	IN	UCHAR	*key,
-	OUT	UCHAR	*plaintext,
-	IN	UCHAR    c_len,
-	IN	UCHAR	*ciphertext)
-
+BOOLEAN RTMPParseEapolKeyData(struct rt_rtmp_adapter *pAd,
+			      u8 *pKeyData,
+			      u8 KeyDataLen,
+			      u8 GroupKeyIndex,
+			      u8 MsgType,
+			      IN BOOLEAN bWPA2, struct rt_mac_table_entry *pEntry)
 {
-	UCHAR       A[8], BIN[16], BOUT[16];
-	UCHAR       xor;
-	INT         i, j;
-	aes_context aesctx;
-	UCHAR       *R;
-	INT         num_blocks = c_len/8;	// unit:64bits
+	struct rt_kde_encap * pKDE = NULL;
+	u8 *pMyKeyData = pKeyData;
+	u8 KeyDataLength = KeyDataLen;
+	u8 GTKLEN = 0;
+	u8 DefaultIdx = 0;
+	u8 skip_offset;
 
+	/* Verify The RSN IE contained in pairewise_msg_2 && pairewise_msg_3 and skip it */
+	if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_3) {
+		/* Check RSN IE whether it is WPA2/WPA2PSK */
+		if (!RTMPCheckRSNIE
+		    (pAd, pKeyData, KeyDataLen, pEntry, &skip_offset)) {
+			/* send wireless event - for RSN IE different */
+			if (pAd->CommonCfg.bWirelessEvent)
+				RTMPSendWirelessEvent(pAd,
+						      IW_RSNIE_DIFF_EVENT_FLAG,
+						      pEntry->Addr,
+						      pEntry->apidx, 0);
 
-	os_alloc_mem(NULL, (PUCHAR *)&R, 512);
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("RSN_IE Different in msg %d of 4-way handshake!\n",
+				  MsgType));
+			hex_dump("Receive RSN_IE ", pKeyData, KeyDataLen);
+			hex_dump("Desired RSN_IE ", pEntry->RSN_IE,
+				 pEntry->RSNIE_Len);
 
-	if (R == NULL)
-    {
-        DBGPRINT(RT_DEBUG_ERROR, ("!!!AES_GTK_KEY_UNWRAP: no memory!!!\n"));
-        return;
-    } /* End of if */
+			return FALSE;
+		} else {
+			if (bWPA2 && MsgType == EAPOL_PAIR_MSG_3) {
+				WpaShowAllsuite(pMyKeyData, skip_offset);
 
-	// Initialize
-	NdisMoveMemory(A, ciphertext, 8);
-	//Input plaintext
-	for(i = 0; i < (c_len-8); i++)
-	{
-		R[ i] = ciphertext[i + 8];
-	}
-
-	rtmp_aes_set_key(&aesctx, key, 128);
-
-	for(j = 5; j >= 0; j--)
-	{
-		for(i = (num_blocks-1); i > 0; i--)
-		{
-			xor = (num_blocks -1 )* j + i;
-			NdisMoveMemory(BIN, A, 8);
-			BIN[7] = A[7] ^ xor;
-			NdisMoveMemory(&BIN[8], &R[(i-1)*8], 8);
-			rtmp_aes_decrypt(&aesctx, BIN, BOUT);
-			NdisMoveMemory(A, &BOUT[0], 8);
-			NdisMoveMemory(&R[(i-1)*8], &BOUT[8], 8);
+				/* skip RSN IE */
+				pMyKeyData += skip_offset;
+				KeyDataLength -= skip_offset;
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("RTMPParseEapolKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n",
+					  skip_offset));
+			} else
+				return TRUE;
 		}
 	}
 
-	// OUTPUT
-	for(i = 0; i < c_len; i++)
-	{
-		plaintext[i] = R[i];
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n",
+		  KeyDataLength));
+	/*hex_dump("remain data", pMyKeyData, KeyDataLength); */
+
+	/* Parse EKD format in pairwise_msg_3_WPA2 && group_msg_1_WPA2 */
+	if (bWPA2
+	    && (MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1)) {
+		if (KeyDataLength >= 8)	/* KDE format exclude GTK length */
+		{
+			pKDE = (struct rt_kde_encap *) pMyKeyData;
+
+			DefaultIdx = pKDE->GTKEncap.Kid;
+
+			/* Sanity check - KED length */
+			if (KeyDataLength < (pKDE->Len + 2)) {
+				DBGPRINT(RT_DEBUG_ERROR,
+					 ("ERROR: The len from KDE is too short \n"));
+				return FALSE;
+			}
+			/* Get GTK length - refer to IEEE 802.11i-2004 p.82 */
+			GTKLEN = pKDE->Len - 6;
+			if (GTKLEN < LEN_AES_KEY) {
+				DBGPRINT(RT_DEBUG_ERROR,
+					 ("ERROR: GTK Key length is too short (%d) \n",
+					  GTKLEN));
+				return FALSE;
+			}
+
+		} else {
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("ERROR: KDE format length is too short \n"));
+			return FALSE;
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n",
+			  DefaultIdx, GTKLEN));
+		/* skip it */
+		pMyKeyData += 8;
+		KeyDataLength -= 8;
+
+	} else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1) {
+		DefaultIdx = GroupKeyIndex;
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("GTK DefaultKeyID=%d \n", DefaultIdx));
+	}
+	/* Sanity check - shared key index must be 1 ~ 3 */
+	if (DefaultIdx < 1 || DefaultIdx > 3) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("ERROR: GTK Key index(%d) is invalid in %s %s \n",
+			  DefaultIdx, ((bWPA2) ? "WPA2" : "WPA"),
+			  GetEapolMsgType(MsgType)));
+		return FALSE;
 	}
 
+	{
+		struct rt_cipher_key *pSharedKey;
 
-	os_free_mem(NULL, R);
+		/* set key material, TxMic and RxMic */
+		NdisMoveMemory(pAd->StaCfg.GTK, pMyKeyData, 32);
+		pAd->StaCfg.DefaultKeyId = DefaultIdx;
+
+		pSharedKey = &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId];
+
+		/* Prepare pair-wise key information into shared key table */
+		NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key));
+		pSharedKey->KeyLen = LEN_TKIP_EK;
+		NdisMoveMemory(pSharedKey->Key, pAd->StaCfg.GTK, LEN_TKIP_EK);
+		NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.GTK[16],
+			       LEN_TKIP_RXMICK);
+		NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.GTK[24],
+			       LEN_TKIP_TXMICK);
+
+		/* Update Shared Key CipherAlg */
+		pSharedKey->CipherAlg = CIPHER_NONE;
+		if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
+			pSharedKey->CipherAlg = CIPHER_TKIP;
+		else if (pAd->StaCfg.GroupCipher ==
+			 Ndis802_11Encryption3Enabled)
+			pSharedKey->CipherAlg = CIPHER_AES;
+		else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
+			pSharedKey->CipherAlg = CIPHER_WEP64;
+		else if (pAd->StaCfg.GroupCipher ==
+			 Ndis802_11GroupWEP104Enabled)
+			pSharedKey->CipherAlg = CIPHER_WEP128;
+
+		/* Update group key information to ASIC Shared Key Table */
+		AsicAddSharedKeyEntry(pAd,
+				      BSS0,
+				      pAd->StaCfg.DefaultKeyId,
+				      pSharedKey->CipherAlg,
+				      pSharedKey->Key,
+				      pSharedKey->TxMic, pSharedKey->RxMic);
+
+		/* Update ASIC WCID attribute table and IVEIV table */
+		RTMPAddWcidAttributeEntry(pAd,
+					  BSS0,
+					  pAd->StaCfg.DefaultKeyId,
+					  pSharedKey->CipherAlg, NULL);
+	}
+
+	return TRUE;
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Construct EAPoL message for WPA handshaking
+		Its format is below,
+
+		+--------------------+
+		| Protocol Version	 |  1 octet
+		+--------------------+
+		| Protocol Type		 |	1 octet
+		+--------------------+
+		| Body Length		 |  2 octets
+		+--------------------+
+		| Descriptor Type	 |	1 octet
+		+--------------------+
+		| Key Information    |	2 octets
+		+--------------------+
+		| Key Length	     |  1 octet
+		+--------------------+
+		| Key Repaly Counter |	8 octets
+		+--------------------+
+		| Key Nonce		     |  32 octets
+		+--------------------+
+		| Key IV			 |  16 octets
+		+--------------------+
+		| Key RSC			 |  8 octets
+		+--------------------+
+		| Key ID or Reserved |	8 octets
+		+--------------------+
+		| Key MIC			 |	16 octets
+		+--------------------+
+		| Key Data Length	 |	2 octets
+		+--------------------+
+		| Key Data			 |	n octets
+		+--------------------+
+
+	Arguments:
+		pAd			Pointer	to our adapter
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+void ConstructEapolMsg(struct rt_mac_table_entry *pEntry,
+		       u8 GroupKeyWepStatus,
+		       u8 MsgType,
+		       u8 DefaultKeyIdx,
+		       u8 * KeyNonce,
+		       u8 * TxRSC,
+		       u8 * GTK,
+		       u8 * RSNIE,
+		       u8 RSNIE_Len, struct rt_eapol_packet * pMsg)
+{
+	BOOLEAN bWPA2 = FALSE;
+	u8 KeyDescVer;
+
+	/* Choose WPA2 or not */
+	if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
+	    (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
+		bWPA2 = TRUE;
+
+	/* Init Packet and Fill header */
+	pMsg->ProVer = EAPOL_VER;
+	pMsg->ProType = EAPOLKey;
+
+	/* Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field */
+	SET_u16_TO_ARRARY(pMsg->Body_Len, LEN_EAPOL_KEY_MSG);
+
+	/* Fill in EAPoL descriptor */
+	if (bWPA2)
+		pMsg->KeyDesc.Type = WPA2_KEY_DESC;
+	else
+		pMsg->KeyDesc.Type = WPA1_KEY_DESC;
+
+	/* Key Descriptor Version (bits 0-2) specifies the key descriptor version type */
+	{
+		/* Fill in Key information, refer to IEEE Std 802.11i-2004 page 78 */
+		/* When either the pairwise or the group cipher is AES, the DESC_TYPE_AES(2) shall be used. */
+		KeyDescVer =
+		    (((pEntry->WepStatus == Ndis802_11Encryption3Enabled)
+		      || (GroupKeyWepStatus ==
+			  Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES)
+		     : (DESC_TYPE_TKIP));
+	}
+
+	pMsg->KeyDesc.KeyInfo.KeyDescVer = KeyDescVer;
+
+	/* Specify Key Type as Group(0) or Pairwise(1) */
+	if (MsgType >= EAPOL_GROUP_MSG_1)
+		pMsg->KeyDesc.KeyInfo.KeyType = GROUPKEY;
+	else
+		pMsg->KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
+
+	/* Specify Key Index, only group_msg1_WPA1 */
+	if (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))
+		pMsg->KeyDesc.KeyInfo.KeyIndex = DefaultKeyIdx;
+
+	if (MsgType == EAPOL_PAIR_MSG_3)
+		pMsg->KeyDesc.KeyInfo.Install = 1;
+
+	if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3)
+	    || (MsgType == EAPOL_GROUP_MSG_1))
+		pMsg->KeyDesc.KeyInfo.KeyAck = 1;
+
+	if (MsgType != EAPOL_PAIR_MSG_1)
+		pMsg->KeyDesc.KeyInfo.KeyMic = 1;
+
+	if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) ||
+	    (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))) {
+		pMsg->KeyDesc.KeyInfo.Secure = 1;
+	}
+
+	if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) ||
+		      (MsgType == EAPOL_GROUP_MSG_1))) {
+		pMsg->KeyDesc.KeyInfo.EKD_DL = 1;
+	}
+	/* key Information element has done. */
+	*(u16 *) (&pMsg->KeyDesc.KeyInfo) =
+	    cpu2le16(*(u16 *) (&pMsg->KeyDesc.KeyInfo));
+
+	/* Fill in Key Length */
+	{
+		if (MsgType >= EAPOL_GROUP_MSG_1) {
+			/* the length of group key cipher */
+			pMsg->KeyDesc.KeyLength[1] =
+			    ((GroupKeyWepStatus ==
+			      Ndis802_11Encryption2Enabled) ? TKIP_GTK_LENGTH :
+			     LEN_AES_KEY);
+		} else {
+			/* the length of pairwise key cipher */
+			pMsg->KeyDesc.KeyLength[1] =
+			    ((pEntry->WepStatus ==
+			      Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY :
+			     LEN_AES_KEY);
+		}
+	}
+
+	/* Fill in replay counter */
+	NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter,
+		       LEN_KEY_DESC_REPLAY);
+
+	/* Fill Key Nonce field */
+	/* ANonce : pairwise_msg1 & pairwise_msg3 */
+	/* SNonce : pairwise_msg2 */
+	/* GNonce : group_msg1_wpa1 */
+	if ((MsgType <= EAPOL_PAIR_MSG_3)
+	    || ((!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))))
+		NdisMoveMemory(pMsg->KeyDesc.KeyNonce, KeyNonce,
+			       LEN_KEY_DESC_NONCE);
+
+	/* Fill key IV - WPA2 as 0, WPA1 as random */
+	if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1)) {
+		/* Suggest IV be random number plus some number, */
+		NdisMoveMemory(pMsg->KeyDesc.KeyIv, &KeyNonce[16],
+			       LEN_KEY_DESC_IV);
+		pMsg->KeyDesc.KeyIv[15] += 2;
+	}
+	/* Fill Key RSC field */
+	/* It contains the RSC for the GTK being installed. */
+	if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2)
+	    || (MsgType == EAPOL_GROUP_MSG_1)) {
+		NdisMoveMemory(pMsg->KeyDesc.KeyRsc, TxRSC, 6);
+	}
+	/* Clear Key MIC field for MIC calculation later */
+	NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+
+	ConstructEapolKeyData(pEntry,
+			      GroupKeyWepStatus,
+			      KeyDescVer,
+			      MsgType,
+			      DefaultKeyIdx, GTK, RSNIE, RSNIE_Len, pMsg);
+
+	/* Calculate MIC and fill in KeyMic Field except Pairwise Msg 1. */
+	if (MsgType != EAPOL_PAIR_MSG_1) {
+		CalculateMIC(KeyDescVer, pEntry->PTK, pMsg);
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("===> ConstructEapolMsg for %s %s\n",
+		  ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("	     Body length = %d \n",
+		  CONV_ARRARY_TO_u16(pMsg->Body_Len)));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("	     Key length  = %d \n",
+		  CONV_ARRARY_TO_u16(pMsg->KeyDesc.KeyLength)));
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Construct the Key Data field of EAPoL message
+
+	Arguments:
+		pAd			Pointer	to our adapter
+		Elem		Message body
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+void ConstructEapolKeyData(struct rt_mac_table_entry *pEntry,
+			   u8 GroupKeyWepStatus,
+			   u8 keyDescVer,
+			   u8 MsgType,
+			   u8 DefaultKeyIdx,
+			   u8 * GTK,
+			   u8 * RSNIE,
+			   u8 RSNIE_LEN, struct rt_eapol_packet * pMsg)
+{
+	u8 *mpool, *Key_Data, *Rc4GTK;
+	u8 ekey[(LEN_KEY_DESC_IV + LEN_EAP_EK)];
+	unsigned long data_offset;
+	BOOLEAN bWPA2Capable = FALSE;
+	struct rt_rtmp_adapter *pAd = pEntry->pAd;
+	BOOLEAN GTK_Included = FALSE;
+
+	/* Choose WPA2 or not */
+	if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
+	    (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
+		bWPA2Capable = TRUE;
+
+	if (MsgType == EAPOL_PAIR_MSG_1 ||
+	    MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2)
+		return;
+
+	/* allocate memory pool */
+	os_alloc_mem(NULL, (u8 **) & mpool, 1500);
+
+	if (mpool == NULL)
+		return;
+
+	/* Rc4GTK Len = 512 */
+	Rc4GTK = (u8 *) ROUND_UP(mpool, 4);
+	/* Key_Data Len = 512 */
+	Key_Data = (u8 *) ROUND_UP(Rc4GTK + 512, 4);
+
+	NdisZeroMemory(Key_Data, 512);
+	SET_u16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, 0);
+	data_offset = 0;
+
+	/* Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3 */
+	if (RSNIE_LEN
+	    && ((MsgType == EAPOL_PAIR_MSG_2)
+		|| (MsgType == EAPOL_PAIR_MSG_3))) {
+		u8 *pmkid_ptr = NULL;
+		u8 pmkid_len = 0;
+
+		RTMPInsertRSNIE(&Key_Data[data_offset],
+				&data_offset,
+				RSNIE, RSNIE_LEN, pmkid_ptr, pmkid_len);
+	}
+
+	/* Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2 */
+	if (bWPA2Capable
+	    && ((MsgType == EAPOL_PAIR_MSG_3)
+		|| (MsgType == EAPOL_GROUP_MSG_1))) {
+		/* Key Data Encapsulation (KDE) format - 802.11i-2004  Figure-43w and Table-20h */
+		Key_Data[data_offset + 0] = 0xDD;
+
+		if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) {
+			Key_Data[data_offset + 1] = 0x16;	/* 4+2+16(OUI+DataType+DataField) */
+		} else {
+			Key_Data[data_offset + 1] = 0x26;	/* 4+2+32(OUI+DataType+DataField) */
+		}
+
+		Key_Data[data_offset + 2] = 0x00;
+		Key_Data[data_offset + 3] = 0x0F;
+		Key_Data[data_offset + 4] = 0xAC;
+		Key_Data[data_offset + 5] = 0x01;
+
+		/* GTK KDE format - 802.11i-2004  Figure-43x */
+		Key_Data[data_offset + 6] = (DefaultKeyIdx & 0x03);
+		Key_Data[data_offset + 7] = 0x00;	/* Reserved Byte */
+
+		data_offset += 8;
+	}
+
+	/* Encapsulate GTK */
+	/* Only for pairwise_msg3_WPA2 and group_msg1 */
+	if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable)
+	    || (MsgType == EAPOL_GROUP_MSG_1)) {
+		/* Fill in GTK */
+		if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) {
+			NdisMoveMemory(&Key_Data[data_offset], GTK,
+				       LEN_AES_KEY);
+			data_offset += LEN_AES_KEY;
+		} else {
+			NdisMoveMemory(&Key_Data[data_offset], GTK,
+				       TKIP_GTK_LENGTH);
+			data_offset += TKIP_GTK_LENGTH;
+		}
+
+		GTK_Included = TRUE;
+	}
+
+	/* This whole key-data field shall be encrypted if a GTK is included. */
+	/* Encrypt the data material in key data field with KEK */
+	if (GTK_Included) {
+		/*hex_dump("GTK_Included", Key_Data, data_offset); */
+
+		if ((keyDescVer == DESC_TYPE_AES)) {
+			u8 remainder = 0;
+			u8 pad_len = 0;
+
+			/* Key Descriptor Version 2 or 3: AES key wrap, defined in IETF RFC 3394, */
+			/* shall be used to encrypt the Key Data field using the KEK field from */
+			/* the derived PTK. */
+
+			/* If the Key Data field uses the NIST AES key wrap, then the Key Data field */
+			/* shall be padded before encrypting if the key data length is less than 16 */
+			/* octets or if it is not a multiple of 8. The padding consists of appending */
+			/* a single octet 0xdd followed by zero or more 0x00 octets. */
+			if ((remainder = data_offset & 0x07) != 0) {
+				int i;
+
+				pad_len = (8 - remainder);
+				Key_Data[data_offset] = 0xDD;
+				for (i = 1; i < pad_len; i++)
+					Key_Data[data_offset + i] = 0;
+
+				data_offset += pad_len;
+			}
+
+			AES_GTK_KEY_WRAP(&pEntry->PTK[16], Key_Data,
+					 data_offset, Rc4GTK);
+			/* AES wrap function will grow 8 bytes in length */
+			data_offset += 8;
+		} else {
+			/*      Key Descriptor Version 1: ARC4 is used to encrypt the Key Data field
+			   using the KEK field from the derived PTK. */
+
+			/* PREPARE Encrypted  "Key DATA" field.  (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV) */
+			/* put TxTsc in Key RSC field */
+			pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32;	/*Init crc32. */
+
+			/* ekey is the contanetion of IV-field, and PTK[16]->PTK[31] */
+			NdisMoveMemory(ekey, pMsg->KeyDesc.KeyIv,
+				       LEN_KEY_DESC_IV);
+			NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &pEntry->PTK[16],
+				       LEN_EAP_EK);
+			ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, ekey, sizeof(ekey));	/*INIT SBOX, KEYLEN+3(IV) */
+			pAd->PrivateInfo.FCSCRC32 =
+			    RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, Key_Data,
+					    data_offset);
+			WPAARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, Rc4GTK,
+					   Key_Data, data_offset);
+		}
+
+		NdisMoveMemory(pMsg->KeyDesc.KeyData, Rc4GTK, data_offset);
+	} else {
+		NdisMoveMemory(pMsg->KeyDesc.KeyData, Key_Data, data_offset);
+	}
+
+	/* Update key data length field and total body length */
+	SET_u16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, data_offset);
+	INC_u16_TO_ARRARY(pMsg->Body_Len, data_offset);
+
+	os_free_mem(NULL, mpool);
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Calcaulate MIC. It is used during 4-ways handsharking.
+
+	Arguments:
+		pAd			-	pointer to our pAdapter context
+	PeerWepStatus	-	indicate the encryption type
+
+	Return Value:
+
+	Note:
+
+	========================================================================
+*/
+static void CalculateMIC(u8 KeyDescVer,
+			 u8 * PTK, struct rt_eapol_packet * pMsg)
+{
+	u8 *OutBuffer;
+	unsigned long FrameLen = 0;
+	u8 mic[LEN_KEY_DESC_MIC];
+	u8 digest[80];
+
+	/* allocate memory for MIC calculation */
+	os_alloc_mem(NULL, (u8 **) & OutBuffer, 512);
+
+	if (OutBuffer == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR, ("CalculateMIC: no memory!\n"));
+		return;
+	}
+	/* make a frame for calculating MIC. */
+	MakeOutgoingFrame(OutBuffer, &FrameLen,
+			  CONV_ARRARY_TO_u16(pMsg->Body_Len) + 4, pMsg,
+			  END_OF_ARGS);
+
+	NdisZeroMemory(mic, sizeof(mic));
+
+	/* Calculate MIC */
+	if (KeyDescVer == DESC_TYPE_AES) {
+		HMAC_SHA1(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, digest,
+			  SHA1_DIGEST_SIZE);
+		NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
+	} else {
+		HMAC_MD5(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, mic,
+			 MD5_DIGEST_SIZE);
+	}
+
+	/* store the calculated MIC */
+	NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC);
+
+	os_free_mem(NULL, OutBuffer);
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Some received frames can't decrypt by Asic, so decrypt them by software.
+
+	Arguments:
+		pAd			-	pointer to our pAdapter context
+	PeerWepStatus	-	indicate the encryption type
+
+	Return Value:
+		NDIS_STATUS_SUCCESS		-	decryption successful
+		NDIS_STATUS_FAILURE		-	decryption failure
+
+	========================================================================
+*/
+int RTMPSoftDecryptBroadCastData(struct rt_rtmp_adapter *pAd,
+					 struct rt_rx_blk *pRxBlk,
+					 IN NDIS_802_11_ENCRYPTION_STATUS
+					 GroupCipher, struct rt_cipher_key *pShard_key)
+{
+	struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
+
+	/* handle WEP decryption */
+	if (GroupCipher == Ndis802_11Encryption1Enabled) {
+		if (RTMPSoftDecryptWEP
+		    (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount,
+		     pShard_key)) {
+
+			/*Minus IV[4] & ICV[4] */
+			pRxWI->MPDUtotalByteCount -= 8;
+		} else {
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("ERROR : Software decrypt WEP data fails.\n"));
+			/* give up this frame */
+			return NDIS_STATUS_FAILURE;
+		}
+	}
+	/* handle TKIP decryption */
+	else if (GroupCipher == Ndis802_11Encryption2Enabled) {
+		if (RTMPSoftDecryptTKIP
+		    (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, 0,
+		     pShard_key)) {
+
+			/*Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV */
+			pRxWI->MPDUtotalByteCount -= 20;
+		} else {
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("ERROR : RTMPSoftDecryptTKIP Failed\n"));
+			/* give up this frame */
+			return NDIS_STATUS_FAILURE;
+		}
+	}
+	/* handle AES decryption */
+	else if (GroupCipher == Ndis802_11Encryption3Enabled) {
+		if (RTMPSoftDecryptAES
+		    (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount,
+		     pShard_key)) {
+
+			/*8 bytes MIC, 8 bytes IV/EIV (CCMP Header) */
+			pRxWI->MPDUtotalByteCount -= 16;
+		} else {
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("ERROR : RTMPSoftDecryptAES Failed\n"));
+			/* give up this frame */
+			return NDIS_STATUS_FAILURE;
+		}
+	} else {
+		/* give up this frame */
+		return NDIS_STATUS_FAILURE;
+	}
+
+	return NDIS_STATUS_SUCCESS;
+
+}
+
+u8 *GetSuiteFromRSNIE(u8 *rsnie,
+			 u32 rsnie_len, u8 type, u8 * count)
+{
+	struct rt_eid * pEid;
+	int len;
+	u8 *pBuf;
+	int offset = 0;
+	struct rt_rsnie_auth *pAkm;
+	u16 acount;
+	BOOLEAN isWPA2 = FALSE;
+
+	pEid = (struct rt_eid *) rsnie;
+	len = rsnie_len - 2;	/* exclude IE and length */
+	pBuf = (u8 *)& pEid->Octet[0];
+
+	/* set default value */
+	*count = 0;
+
+	/* Check length */
+	if ((len <= 0) || (pEid->Len != len)) {
+		DBGPRINT_ERR(("%s : The length is invalid\n", __func__));
+		return NULL;
+	}
+	/* Check WPA or WPA2 */
+	if (pEid->Eid == IE_WPA) {
+		struct rt_rsnie *pRsnie = (struct rt_rsnie *)pBuf;
+		u16 ucount;
+
+		if (len < sizeof(struct rt_rsnie)) {
+			DBGPRINT_ERR(("%s : The length is too short for WPA\n",
+				      __func__));
+			return NULL;
+		}
+		/* Get the count of pairwise cipher */
+		ucount = cpu2le16(pRsnie->ucount);
+		if (ucount > 2) {
+			DBGPRINT_ERR(("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount));
+			return NULL;
+		}
+		/* Get the group cipher */
+		if (type == GROUP_SUITE) {
+			*count = 1;
+			return pRsnie->mcast;
+		}
+		/* Get the pairwise cipher suite */
+		else if (type == PAIRWISE_SUITE) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("%s : The count of pairwise cipher is %d\n",
+				  __func__, ucount));
+			*count = ucount;
+			return pRsnie->ucast[0].oui;
+		}
+
+		offset = sizeof(struct rt_rsnie) + (4 * (ucount - 1));
+
+	} else if (pEid->Eid == IE_RSN) {
+		struct rt_rsnie2 *pRsnie = (struct rt_rsnie2 *)pBuf;
+		u16 ucount;
+
+		isWPA2 = TRUE;
+
+		if (len < sizeof(struct rt_rsnie2)) {
+			DBGPRINT_ERR(("%s : The length is too short for WPA2\n",
+				      __func__));
+			return NULL;
+		}
+		/* Get the count of pairwise cipher */
+		ucount = cpu2le16(pRsnie->ucount);
+		if (ucount > 2) {
+			DBGPRINT_ERR(("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount));
+			return NULL;
+		}
+		/* Get the group cipher */
+		if (type == GROUP_SUITE) {
+			*count = 1;
+			return pRsnie->mcast;
+		}
+		/* Get the pairwise cipher suite */
+		else if (type == PAIRWISE_SUITE) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("%s : The count of pairwise cipher is %d\n",
+				  __func__, ucount));
+			*count = ucount;
+			return pRsnie->ucast[0].oui;
+		}
+
+		offset = sizeof(struct rt_rsnie2) + (4 * (ucount - 1));
+
+	} else {
+		DBGPRINT_ERR(("%s : Unknown IE (%d)\n", __func__, pEid->Eid));
+		return NULL;
+	}
+
+	/* skip group cipher and pairwise cipher suite */
+	pBuf += offset;
+	len -= offset;
+
+	if (len < sizeof(struct rt_rsnie_auth)) {
+		DBGPRINT_ERR(("%s : The length of RSNIE is too short\n",
+			      __func__));
+		return NULL;
+	}
+	/* pointer to AKM count */
+	pAkm = (struct rt_rsnie_auth *)pBuf;
+
+	/* Get the count of pairwise cipher */
+	acount = cpu2le16(pAkm->acount);
+	if (acount > 2) {
+		DBGPRINT_ERR(("%s : The count(%d) of AKM is invlaid\n",
+			      __func__, acount));
+		return NULL;
+	}
+	/* Get the AKM suite */
+	if (type == AKM_SUITE) {
+		DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of AKM is %d\n",
+					  __func__, acount));
+		*count = acount;
+		return pAkm->auth[0].oui;
+	}
+	offset = sizeof(struct rt_rsnie_auth) + (4 * (acount - 1));
+
+	pBuf += offset;
+	len -= offset;
+
+	/* The remaining length must larger than (RSN-Capability(2) + PMKID-Count(2) + PMKID(16~)) */
+	if (len >= (sizeof(RSN_CAPABILITIES) + 2 + LEN_PMKID)) {
+		/* Skip RSN capability and PMKID-Count */
+		pBuf += (sizeof(RSN_CAPABILITIES) + 2);
+		len -= (sizeof(RSN_CAPABILITIES) + 2);
+
+		/* Get PMKID */
+		if (type == PMKID_LIST) {
+			*count = 1;
+			return pBuf;
+		}
+	} else {
+		DBGPRINT_ERR(("%s : it can't get any more information beyond AKM \n", __func__));
+		return NULL;
+	}
+
+	*count = 0;
+	/*DBGPRINT_ERR(("%s : The type(%d) doesn't support \n", __func__, type)); */
+	return NULL;
+
+}
+
+void WpaShowAllsuite(u8 *rsnie, u32 rsnie_len)
+{
+	u8 *pSuite = NULL;
+	u8 count;
+
+	hex_dump("RSNIE", rsnie, rsnie_len);
+
+	/* group cipher */
+	if ((pSuite =
+	     GetSuiteFromRSNIE(rsnie, rsnie_len, GROUP_SUITE,
+			       &count)) != NULL) {
+		hex_dump("group cipher", pSuite, 4 * count);
+	}
+	/* pairwise cipher */
+	if ((pSuite =
+	     GetSuiteFromRSNIE(rsnie, rsnie_len, PAIRWISE_SUITE,
+			       &count)) != NULL) {
+		hex_dump("pairwise cipher", pSuite, 4 * count);
+	}
+	/* AKM */
+	if ((pSuite =
+	     GetSuiteFromRSNIE(rsnie, rsnie_len, AKM_SUITE, &count)) != NULL) {
+		hex_dump("AKM suite", pSuite, 4 * count);
+	}
+	/* PMKID */
+	if ((pSuite =
+	     GetSuiteFromRSNIE(rsnie, rsnie_len, PMKID_LIST, &count)) != NULL) {
+		hex_dump("PMKID", pSuite, LEN_PMKID);
+	}
+
+}
+
+void RTMPInsertRSNIE(u8 *pFrameBuf,
+		     unsigned long *pFrameLen,
+		     u8 *rsnie_ptr,
+		     u8 rsnie_len,
+		     u8 *pmkid_ptr, u8 pmkid_len)
+{
+	u8 *pTmpBuf;
+	unsigned long TempLen = 0;
+	u8 extra_len = 0;
+	u16 pmk_count = 0;
+	u8 ie_num;
+	u8 total_len = 0;
+	u8 WPA2_OUI[3] = { 0x00, 0x0F, 0xAC };
+
+	pTmpBuf = pFrameBuf;
+
+	/* PMKID-List Must larger than 0 and the multiple of 16. */
+	if (pmkid_len > 0 && ((pmkid_len & 0x0f) == 0)) {
+		extra_len = sizeof(u16)+ pmkid_len;
+
+		pmk_count = (pmkid_len >> 4);
+		pmk_count = cpu2le16(pmk_count);
+	} else {
+		DBGPRINT(RT_DEBUG_WARN,
+			 ("%s : The length is PMKID-List is invalid (%d), so don't insert it.\n",
+			  __func__, pmkid_len));
+	}
+
+	if (rsnie_len != 0) {
+		ie_num = IE_WPA;
+		total_len = rsnie_len;
+
+		if (NdisEqualMemory(rsnie_ptr + 2, WPA2_OUI, sizeof(WPA2_OUI))) {
+			ie_num = IE_RSN;
+			total_len += extra_len;
+		}
+
+		/* construct RSNIE body */
+		MakeOutgoingFrame(pTmpBuf, &TempLen,
+				  1, &ie_num,
+				  1, &total_len,
+				  rsnie_len, rsnie_ptr, END_OF_ARGS);
+
+		pTmpBuf += TempLen;
+		*pFrameLen = *pFrameLen + TempLen;
+
+		if (ie_num == IE_RSN) {
+			/* Insert PMKID-List field */
+			if (extra_len > 0) {
+				MakeOutgoingFrame(pTmpBuf, &TempLen,
+						  2, &pmk_count,
+						  pmkid_len, pmkid_ptr,
+						  END_OF_ARGS);
+
+				pTmpBuf += TempLen;
+				*pFrameLen = *pFrameLen + TempLen;
+			}
+		}
+	}
+
+	return;
 }
diff --git a/drivers/staging/rt2860/common/crypt_hmac.c b/drivers/staging/rt2860/common/crypt_hmac.c
new file mode 100644
index 0000000..d7ab08e
--- /dev/null
+++ b/drivers/staging/rt2860/common/crypt_hmac.c
@@ -0,0 +1,187 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************/
+
+#include "../crypt_hmac.h"
+
+#ifdef HMAC_SHA1_SUPPORT
+/*
+========================================================================
+Routine Description:
+    HMAC using SHA1 hash function
+
+Arguments:
+    key             Secret key
+    key_len         The length of the key in bytes
+    message         Message context
+    message_len     The length of message in bytes
+    macLen          Request the length of message authentication code
+
+Return Value:
+    mac             Message authentication code
+
+Note:
+    None
+========================================================================
+*/
+void HMAC_SHA1(IN const u8 Key[],
+	       u32 KeyLen,
+	       IN const u8 Message[],
+	       u32 MessageLen, u8 MAC[], u32 MACLen)
+{
+	struct rt_sha1_ctx sha_ctx1;
+	struct rt_sha1_ctx sha_ctx2;
+	u8 K0[SHA1_BLOCK_SIZE];
+	u8 Digest[SHA1_DIGEST_SIZE];
+	u32 index;
+
+	NdisZeroMemory(&sha_ctx1, sizeof(struct rt_sha1_ctx));
+	NdisZeroMemory(&sha_ctx2, sizeof(struct rt_sha1_ctx));
+	/*
+	 * If the length of K = B(Block size): K0 = K.
+	 * If the length of K > B: hash K to obtain an L byte string,
+	 * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
+	 * If the length of K < B: append zeros to the end of K to create a B-byte string K0
+	 */
+	NdisZeroMemory(K0, SHA1_BLOCK_SIZE);
+	if (KeyLen <= SHA1_BLOCK_SIZE)
+		NdisMoveMemory(K0, Key, KeyLen);
+	else
+		RT_SHA1(Key, KeyLen, K0);
+	/* End of if */
+
+	/* Exclusive-Or K0 with ipad */
+	/* ipad: Inner pad; the byte x¡¦36¡¦ repeated B times. */
+	for (index = 0; index < SHA1_BLOCK_SIZE; index++)
+		K0[index] ^= 0x36;
+	/* End of for */
+
+	RT_SHA1_Init(&sha_ctx1);
+	/* H(K0^ipad) */
+	SHA1_Append(&sha_ctx1, K0, sizeof(K0));
+	/* H((K0^ipad)||text) */
+	SHA1_Append(&sha_ctx1, Message, MessageLen);
+	SHA1_End(&sha_ctx1, Digest);
+
+	/* Exclusive-Or K0 with opad and remove ipad */
+	/* opad: Outer pad; the byte x¡¦5c¡¦ repeated B times. */
+	for (index = 0; index < SHA1_BLOCK_SIZE; index++)
+		K0[index] ^= 0x36 ^ 0x5c;
+	/* End of for */
+
+	RT_SHA1_Init(&sha_ctx2);
+	/* H(K0^opad) */
+	SHA1_Append(&sha_ctx2, K0, sizeof(K0));
+	/* H( (K0^opad) || H((K0^ipad)||text) ) */
+	SHA1_Append(&sha_ctx2, Digest, SHA1_DIGEST_SIZE);
+	SHA1_End(&sha_ctx2, Digest);
+
+	if (MACLen > SHA1_DIGEST_SIZE)
+		NdisMoveMemory(MAC, Digest, SHA1_DIGEST_SIZE);
+	else
+		NdisMoveMemory(MAC, Digest, MACLen);
+}				/* End of HMAC_SHA1 */
+#endif /* HMAC_SHA1_SUPPORT */
+
+#ifdef HMAC_MD5_SUPPORT
+/*
+========================================================================
+Routine Description:
+    HMAC using MD5 hash function
+
+Arguments:
+    key             Secret key
+    key_len         The length of the key in bytes
+    message         Message context
+    message_len     The length of message in bytes
+    macLen          Request the length of message authentication code
+
+Return Value:
+    mac             Message authentication code
+
+Note:
+    None
+========================================================================
+*/
+void HMAC_MD5(IN const u8 Key[],
+	      u32 KeyLen,
+	      IN const u8 Message[],
+	      u32 MessageLen, u8 MAC[], u32 MACLen)
+{
+	struct rt_md5_ctx_struc md5_ctx1;
+	struct rt_md5_ctx_struc md5_ctx2;
+	u8 K0[MD5_BLOCK_SIZE];
+	u8 Digest[MD5_DIGEST_SIZE];
+	u32 index;
+
+	NdisZeroMemory(&md5_ctx1, sizeof(struct rt_md5_ctx_struc));
+	NdisZeroMemory(&md5_ctx2, sizeof(struct rt_md5_ctx_struc));
+	/*
+	 * If the length of K = B(Block size): K0 = K.
+	 * If the length of K > B: hash K to obtain an L byte string,
+	 * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
+	 * If the length of K < B: append zeros to the end of K to create a B-byte string K0
+	 */
+	NdisZeroMemory(K0, MD5_BLOCK_SIZE);
+	if (KeyLen <= MD5_BLOCK_SIZE) {
+		NdisMoveMemory(K0, Key, KeyLen);
+	} else {
+		RT_MD5(Key, KeyLen, K0);
+	}
+
+	/* Exclusive-Or K0 with ipad */
+	/* ipad: Inner pad; the byte x¡¦36¡¦ repeated B times. */
+	for (index = 0; index < MD5_BLOCK_SIZE; index++)
+		K0[index] ^= 0x36;
+	/* End of for */
+
+	MD5_Init(&md5_ctx1);
+	/* H(K0^ipad) */
+	MD5_Append(&md5_ctx1, K0, sizeof(K0));
+	/* H((K0^ipad)||text) */
+	MD5_Append(&md5_ctx1, Message, MessageLen);
+	MD5_End(&md5_ctx1, Digest);
+
+	/* Exclusive-Or K0 with opad and remove ipad */
+	/* opad: Outer pad; the byte x¡¦5c¡¦ repeated B times. */
+	for (index = 0; index < MD5_BLOCK_SIZE; index++)
+		K0[index] ^= 0x36 ^ 0x5c;
+	/* End of for */
+
+	MD5_Init(&md5_ctx2);
+	/* H(K0^opad) */
+	MD5_Append(&md5_ctx2, K0, sizeof(K0));
+	/* H( (K0^opad) || H((K0^ipad)||text) ) */
+	MD5_Append(&md5_ctx2, Digest, MD5_DIGEST_SIZE);
+	MD5_End(&md5_ctx2, Digest);
+
+	if (MACLen > MD5_DIGEST_SIZE)
+		NdisMoveMemory(MAC, Digest, MD5_DIGEST_SIZE);
+	else
+		NdisMoveMemory(MAC, Digest, MACLen);
+}				/* End of HMAC_SHA256 */
+#endif /* HMAC_MD5_SUPPORT */
+
+/* End of crypt_hmac.c */
diff --git a/drivers/staging/rt2860/common/crypt_md5.c b/drivers/staging/rt2860/common/crypt_md5.c
new file mode 100644
index 0000000..6deab65
--- /dev/null
+++ b/drivers/staging/rt2860/common/crypt_md5.c
@@ -0,0 +1,339 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************/
+
+#include "../crypt_md5.h"
+
+#ifdef MD5_SUPPORT
+/*
+ * F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+#define ROTL(x,n,w) ((x << n) | (x >> (w - n)))
+#define ROTL32(x,n) ROTL(x,n,32)	/* 32 bits word */
+
+#define ROUND1(a, b, c, d, x, s, ac) {          \
+    (a) += F((b),(c),(d)) + (x) + (u32)(ac); \
+    (a)  = ROTL32((a),(s));                     \
+    (a) += (b);                                 \
+}
+#define ROUND2(a, b, c, d, x, s, ac) {          \
+    (a) += G((b),(c),(d)) + (x) + (u32)(ac); \
+    (a)  = ROTL32((a),(s));                     \
+    (a) += (b);                                 \
+}
+#define ROUND3(a, b, c, d, x, s, ac) {          \
+    (a) += H((b),(c),(d)) + (x) + (u32)(ac); \
+    (a)  = ROTL32((a),(s));                     \
+    (a) += (b);                                 \
+}
+#define ROUND4(a, b, c, d, x, s, ac) {          \
+    (a) += I((b),(c),(d)) + (x) + (u32)(ac); \
+    (a)  = ROTL32((a),(s));                     \
+    (a) += (b);                                 \
+}
+static const u32 MD5_DefaultHashValue[4] = {
+	0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL
+};
+#endif /* MD5_SUPPORT */
+
+#ifdef MD5_SUPPORT
+/*
+========================================================================
+Routine Description:
+    Initial Md5_CTX_STRUC
+
+Arguments:
+    pMD5_CTX        Pointer to Md5_CTX_STRUC
+
+Return Value:
+    None
+
+Note:
+    None
+========================================================================
+*/
+void MD5_Init(struct rt_md5_ctx_struc *pMD5_CTX)
+{
+	NdisMoveMemory(pMD5_CTX->HashValue, MD5_DefaultHashValue,
+		       sizeof(MD5_DefaultHashValue));
+	NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE);
+	pMD5_CTX->BlockLen = 0;
+	pMD5_CTX->MessageLen = 0;
+}				/* End of MD5_Init */
+
+/*
+========================================================================
+Routine Description:
+    MD5 computation for one block (512 bits)
+
+Arguments:
+    pMD5_CTX        Pointer to Md5_CTX_STRUC
+
+Return Value:
+    None
+
+Note:
+    T[i] := floor(abs(sin(i + 1)) * (2 pow 32)), i is number of round
+========================================================================
+*/
+void MD5_Hash(struct rt_md5_ctx_struc *pMD5_CTX)
+{
+	u32 X_i;
+	u32 X[16];
+	u32 a, b, c, d;
+
+	/* Prepare the message schedule, {X_i} */
+	NdisMoveMemory(X, pMD5_CTX->Block, MD5_BLOCK_SIZE);
+	for (X_i = 0; X_i < 16; X_i++)
+		X[X_i] = cpu2le32(X[X_i]);	/* Endian Swap */
+	/* End of for */
+
+	/* MD5 hash computation */
+	/* Initialize the working variables */
+	a = pMD5_CTX->HashValue[0];
+	b = pMD5_CTX->HashValue[1];
+	c = pMD5_CTX->HashValue[2];
+	d = pMD5_CTX->HashValue[3];
+
+	/*
+	 *  Round 1
+	 *  Let [abcd k s i] denote the operation
+	 *  a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s)
+	 */
+	ROUND1(a, b, c, d, X[0], 7, 0xd76aa478);	/* 1 */
+	ROUND1(d, a, b, c, X[1], 12, 0xe8c7b756);	/* 2 */
+	ROUND1(c, d, a, b, X[2], 17, 0x242070db);	/* 3 */
+	ROUND1(b, c, d, a, X[3], 22, 0xc1bdceee);	/* 4 */
+	ROUND1(a, b, c, d, X[4], 7, 0xf57c0faf);	/* 5 */
+	ROUND1(d, a, b, c, X[5], 12, 0x4787c62a);	/* 6 */
+	ROUND1(c, d, a, b, X[6], 17, 0xa8304613);	/* 7 */
+	ROUND1(b, c, d, a, X[7], 22, 0xfd469501);	/* 8 */
+	ROUND1(a, b, c, d, X[8], 7, 0x698098d8);	/* 9 */
+	ROUND1(d, a, b, c, X[9], 12, 0x8b44f7af);	/* 10 */
+	ROUND1(c, d, a, b, X[10], 17, 0xffff5bb1);	/* 11 */
+	ROUND1(b, c, d, a, X[11], 22, 0x895cd7be);	/* 12 */
+	ROUND1(a, b, c, d, X[12], 7, 0x6b901122);	/* 13 */
+	ROUND1(d, a, b, c, X[13], 12, 0xfd987193);	/* 14 */
+	ROUND1(c, d, a, b, X[14], 17, 0xa679438e);	/* 15 */
+	ROUND1(b, c, d, a, X[15], 22, 0x49b40821);	/* 16 */
+
+	/*
+	 *  Round 2
+	 *  Let [abcd k s i] denote the operation
+	 *  a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s)
+	 */
+	ROUND2(a, b, c, d, X[1], 5, 0xf61e2562);	/* 17 */
+	ROUND2(d, a, b, c, X[6], 9, 0xc040b340);	/* 18 */
+	ROUND2(c, d, a, b, X[11], 14, 0x265e5a51);	/* 19 */
+	ROUND2(b, c, d, a, X[0], 20, 0xe9b6c7aa);	/* 20 */
+	ROUND2(a, b, c, d, X[5], 5, 0xd62f105d);	/* 21 */
+	ROUND2(d, a, b, c, X[10], 9, 0x2441453);	/* 22 */
+	ROUND2(c, d, a, b, X[15], 14, 0xd8a1e681);	/* 23 */
+	ROUND2(b, c, d, a, X[4], 20, 0xe7d3fbc8);	/* 24 */
+	ROUND2(a, b, c, d, X[9], 5, 0x21e1cde6);	/* 25 */
+	ROUND2(d, a, b, c, X[14], 9, 0xc33707d6);	/* 26 */
+	ROUND2(c, d, a, b, X[3], 14, 0xf4d50d87);	/* 27 */
+	ROUND2(b, c, d, a, X[8], 20, 0x455a14ed);	/* 28 */
+	ROUND2(a, b, c, d, X[13], 5, 0xa9e3e905);	/* 29 */
+	ROUND2(d, a, b, c, X[2], 9, 0xfcefa3f8);	/* 30 */
+	ROUND2(c, d, a, b, X[7], 14, 0x676f02d9);	/* 31 */
+	ROUND2(b, c, d, a, X[12], 20, 0x8d2a4c8a);	/* 32 */
+
+	/*
+	 *  Round 3
+	 *  Let [abcd k s t] denote the operation
+	 *  a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s)
+	 */
+	ROUND3(a, b, c, d, X[5], 4, 0xfffa3942);	/* 33 */
+	ROUND3(d, a, b, c, X[8], 11, 0x8771f681);	/* 34 */
+	ROUND3(c, d, a, b, X[11], 16, 0x6d9d6122);	/* 35 */
+	ROUND3(b, c, d, a, X[14], 23, 0xfde5380c);	/* 36 */
+	ROUND3(a, b, c, d, X[1], 4, 0xa4beea44);	/* 37 */
+	ROUND3(d, a, b, c, X[4], 11, 0x4bdecfa9);	/* 38 */
+	ROUND3(c, d, a, b, X[7], 16, 0xf6bb4b60);	/* 39 */
+	ROUND3(b, c, d, a, X[10], 23, 0xbebfbc70);	/* 40 */
+	ROUND3(a, b, c, d, X[13], 4, 0x289b7ec6);	/* 41 */
+	ROUND3(d, a, b, c, X[0], 11, 0xeaa127fa);	/* 42 */
+	ROUND3(c, d, a, b, X[3], 16, 0xd4ef3085);	/* 43 */
+	ROUND3(b, c, d, a, X[6], 23, 0x4881d05);	/* 44 */
+	ROUND3(a, b, c, d, X[9], 4, 0xd9d4d039);	/* 45 */
+	ROUND3(d, a, b, c, X[12], 11, 0xe6db99e5);	/* 46 */
+	ROUND3(c, d, a, b, X[15], 16, 0x1fa27cf8);	/* 47 */
+	ROUND3(b, c, d, a, X[2], 23, 0xc4ac5665);	/* 48 */
+
+	/*
+	 *  Round 4
+	 *  Let [abcd k s t] denote the operation
+	 *  a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s)
+	 */
+	ROUND4(a, b, c, d, X[0], 6, 0xf4292244);	/* 49 */
+	ROUND4(d, a, b, c, X[7], 10, 0x432aff97);	/* 50 */
+	ROUND4(c, d, a, b, X[14], 15, 0xab9423a7);	/* 51 */
+	ROUND4(b, c, d, a, X[5], 21, 0xfc93a039);	/* 52 */
+	ROUND4(a, b, c, d, X[12], 6, 0x655b59c3);	/* 53 */
+	ROUND4(d, a, b, c, X[3], 10, 0x8f0ccc92);	/* 54 */
+	ROUND4(c, d, a, b, X[10], 15, 0xffeff47d);	/* 55 */
+	ROUND4(b, c, d, a, X[1], 21, 0x85845dd1);	/* 56 */
+	ROUND4(a, b, c, d, X[8], 6, 0x6fa87e4f);	/* 57 */
+	ROUND4(d, a, b, c, X[15], 10, 0xfe2ce6e0);	/* 58 */
+	ROUND4(c, d, a, b, X[6], 15, 0xa3014314);	/* 59 */
+	ROUND4(b, c, d, a, X[13], 21, 0x4e0811a1);	/* 60 */
+	ROUND4(a, b, c, d, X[4], 6, 0xf7537e82);	/* 61 */
+	ROUND4(d, a, b, c, X[11], 10, 0xbd3af235);	/* 62 */
+	ROUND4(c, d, a, b, X[2], 15, 0x2ad7d2bb);	/* 63 */
+	ROUND4(b, c, d, a, X[9], 21, 0xeb86d391);	/* 64 */
+
+	/* Compute the i^th intermediate hash value H^(i) */
+	pMD5_CTX->HashValue[0] += a;
+	pMD5_CTX->HashValue[1] += b;
+	pMD5_CTX->HashValue[2] += c;
+	pMD5_CTX->HashValue[3] += d;
+
+	NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE);
+	pMD5_CTX->BlockLen = 0;
+}				/* End of MD5_Hash */
+
+/*
+========================================================================
+Routine Description:
+    The message is appended to block. If block size > 64 bytes, the MD5_Hash
+will be called.
+
+Arguments:
+    pMD5_CTX        Pointer to struct rt_md5_ctx_struc
+    message         Message context
+    messageLen      The length of message in bytes
+
+Return Value:
+    None
+
+Note:
+    None
+========================================================================
+*/
+void MD5_Append(struct rt_md5_ctx_struc *pMD5_CTX,
+		IN const u8 Message[], u32 MessageLen)
+{
+	u32 appendLen = 0;
+	u32 diffLen = 0;
+
+	while (appendLen != MessageLen) {
+		diffLen = MessageLen - appendLen;
+		if ((pMD5_CTX->BlockLen + diffLen) < MD5_BLOCK_SIZE) {
+			NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen,
+				       Message + appendLen, diffLen);
+			pMD5_CTX->BlockLen += diffLen;
+			appendLen += diffLen;
+		} else {
+			NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen,
+				       Message + appendLen,
+				       MD5_BLOCK_SIZE - pMD5_CTX->BlockLen);
+			appendLen += (MD5_BLOCK_SIZE - pMD5_CTX->BlockLen);
+			pMD5_CTX->BlockLen = MD5_BLOCK_SIZE;
+			MD5_Hash(pMD5_CTX);
+		}		/* End of if */
+	}			/* End of while */
+	pMD5_CTX->MessageLen += MessageLen;
+}				/* End of MD5_Append */
+
+/*
+========================================================================
+Routine Description:
+    1. Append bit 1 to end of the message
+    2. Append the length of message in rightmost 64 bits
+    3. Transform the Hash Value to digest message
+
+Arguments:
+    pMD5_CTX        Pointer to struct rt_md5_ctx_struc
+
+Return Value:
+    digestMessage   Digest message
+
+Note:
+    None
+========================================================================
+*/
+void MD5_End(struct rt_md5_ctx_struc *pMD5_CTX, u8 DigestMessage[])
+{
+	u32 index;
+	u64 message_length_bits;
+
+	/* append 1 bits to end of the message */
+	NdisFillMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen, 1, 0x80);
+
+	/* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
+	if (pMD5_CTX->BlockLen > 55)
+		MD5_Hash(pMD5_CTX);
+	/* End of if */
+
+	/* Append the length of message in rightmost 64 bits */
+	message_length_bits = pMD5_CTX->MessageLen * 8;
+	message_length_bits = cpu2le64(message_length_bits);
+	NdisMoveMemory(&pMD5_CTX->Block[56], &message_length_bits, 8);
+	MD5_Hash(pMD5_CTX);
+
+	/* Return message digest, transform the u32 hash value to bytes */
+	for (index = 0; index < 4; index++)
+		pMD5_CTX->HashValue[index] =
+		    cpu2le32(pMD5_CTX->HashValue[index]);
+	/* End of for */
+	NdisMoveMemory(DigestMessage, pMD5_CTX->HashValue, MD5_DIGEST_SIZE);
+}				/* End of MD5_End */
+
+/*
+========================================================================
+Routine Description:
+    MD5 algorithm
+
+Arguments:
+    message         Message context
+    messageLen      The length of message in bytes
+
+Return Value:
+    digestMessage   Digest message
+
+Note:
+    None
+========================================================================
+*/
+void RT_MD5(IN const u8 Message[],
+	    u32 MessageLen, u8 DigestMessage[])
+{
+	struct rt_md5_ctx_struc md5_ctx;
+
+	NdisZeroMemory(&md5_ctx, sizeof(struct rt_md5_ctx_struc));
+	MD5_Init(&md5_ctx);
+	MD5_Append(&md5_ctx, Message, MessageLen);
+	MD5_End(&md5_ctx, DigestMessage);
+}				/* End of RT_MD5 */
+
+#endif /* MD5_SUPPORT */
+
+/* End of crypt_md5.c */
diff --git a/drivers/staging/rt2860/common/crypt_sha2.c b/drivers/staging/rt2860/common/crypt_sha2.c
new file mode 100644
index 0000000..fa83fb2
--- /dev/null
+++ b/drivers/staging/rt2860/common/crypt_sha2.c
@@ -0,0 +1,269 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************/
+
+#include "../crypt_sha2.h"
+
+/* Basic operations */
+#define SHR(x,n) (x >> n)	/* SHR(x)^n, right shift n bits , x is w-bit word, 0 <= n <= w */
+#define ROTR(x,n,w) ((x >> n) | (x << (w - n)))	/* ROTR(x)^n, circular right shift n bits , x is w-bit word, 0 <= n <= w */
+#define ROTL(x,n,w) ((x << n) | (x >> (w - n)))	/* ROTL(x)^n, circular left shift n bits , x is w-bit word, 0 <= n <= w */
+#define ROTR32(x,n) ROTR(x,n,32)	/* 32 bits word */
+#define ROTL32(x,n) ROTL(x,n,32)	/* 32 bits word */
+
+/* Basic functions */
+#define Ch(x,y,z) ((x & y) ^ ((~x) & z))
+#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
+#define Parity(x,y,z) (x ^ y ^ z)
+
+#ifdef SHA1_SUPPORT
+/* SHA1 constants */
+#define SHA1_MASK 0x0000000f
+static const u32 SHA1_K[4] = {
+	0x5a827999UL, 0x6ed9eba1UL, 0x8f1bbcdcUL, 0xca62c1d6UL
+};
+
+static const u32 SHA1_DefaultHashValue[5] = {
+	0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL, 0xc3d2e1f0UL
+};
+
+/*
+========================================================================
+Routine Description:
+    Initial struct rt_sha1_ctx
+
+Arguments:
+    pSHA_CTX        Pointer to struct rt_sha1_ctx
+
+Return Value:
+    None
+
+Note:
+    None
+========================================================================
+*/
+void RT_SHA1_Init(struct rt_sha1_ctx *pSHA_CTX)
+{
+	NdisMoveMemory(pSHA_CTX->HashValue, SHA1_DefaultHashValue,
+		       sizeof(SHA1_DefaultHashValue));
+	NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE);
+	pSHA_CTX->MessageLen = 0;
+	pSHA_CTX->BlockLen = 0;
+}				/* End of RT_SHA1_Init */
+
+/*
+========================================================================
+Routine Description:
+    SHA1 computation for one block (512 bits)
+
+Arguments:
+    pSHA_CTX        Pointer to struct rt_sha1_ctx
+
+Return Value:
+    None
+
+Note:
+    None
+========================================================================
+*/
+void SHA1_Hash(struct rt_sha1_ctx *pSHA_CTX)
+{
+	u32 W_i, t, s;
+	u32 W[16];
+	u32 a, b, c, d, e, T, f_t = 0;
+
+	/* Prepare the message schedule, {W_i}, 0 < t < 15 */
+	NdisMoveMemory(W, pSHA_CTX->Block, SHA1_BLOCK_SIZE);
+	for (W_i = 0; W_i < 16; W_i++)
+		W[W_i] = cpu2be32(W[W_i]);	/* Endian Swap */
+	/* End of for */
+
+	/* SHA256 hash computation */
+	/* Initialize the working variables */
+	a = pSHA_CTX->HashValue[0];
+	b = pSHA_CTX->HashValue[1];
+	c = pSHA_CTX->HashValue[2];
+	d = pSHA_CTX->HashValue[3];
+	e = pSHA_CTX->HashValue[4];
+
+	/* 80 rounds */
+	for (t = 0; t < 80; t++) {
+		s = t & SHA1_MASK;
+		if (t > 15) {	/* Prepare the message schedule, {W_i}, 16 < t < 79 */
+			W[s] =
+			    (W[(s + 13) & SHA1_MASK]) ^ (W[(s + 8) & SHA1_MASK])
+			    ^ (W[(s + 2) & SHA1_MASK]) ^ W[s];
+			W[s] = ROTL32(W[s], 1);
+		}		/* End of if */
+		switch (t / 20) {
+		case 0:
+			f_t = Ch(b, c, d);
+			break;
+		case 1:
+			f_t = Parity(b, c, d);
+			break;
+		case 2:
+			f_t = Maj(b, c, d);
+			break;
+		case 3:
+			f_t = Parity(b, c, d);
+			break;
+		}		/* End of switch */
+		T = ROTL32(a, 5) + f_t + e + SHA1_K[t / 20] + W[s];
+		e = d;
+		d = c;
+		c = ROTL32(b, 30);
+		b = a;
+		a = T;
+	}			/* End of for */
+
+	/* Compute the i^th intermediate hash value H^(i) */
+	pSHA_CTX->HashValue[0] += a;
+	pSHA_CTX->HashValue[1] += b;
+	pSHA_CTX->HashValue[2] += c;
+	pSHA_CTX->HashValue[3] += d;
+	pSHA_CTX->HashValue[4] += e;
+
+	NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE);
+	pSHA_CTX->BlockLen = 0;
+}				/* End of SHA1_Hash */
+
+/*
+========================================================================
+Routine Description:
+    The message is appended to block. If block size > 64 bytes, the SHA1_Hash
+will be called.
+
+Arguments:
+    pSHA_CTX        Pointer to struct rt_sha1_ctx
+    message         Message context
+    messageLen      The length of message in bytes
+
+Return Value:
+    None
+
+Note:
+    None
+========================================================================
+*/
+void SHA1_Append(struct rt_sha1_ctx *pSHA_CTX,
+		 IN const u8 Message[], u32 MessageLen)
+{
+	u32 appendLen = 0;
+	u32 diffLen = 0;
+
+	while (appendLen != MessageLen) {
+		diffLen = MessageLen - appendLen;
+		if ((pSHA_CTX->BlockLen + diffLen) < SHA1_BLOCK_SIZE) {
+			NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
+				       Message + appendLen, diffLen);
+			pSHA_CTX->BlockLen += diffLen;
+			appendLen += diffLen;
+		} else {
+			NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
+				       Message + appendLen,
+				       SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen);
+			appendLen += (SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen);
+			pSHA_CTX->BlockLen = SHA1_BLOCK_SIZE;
+			SHA1_Hash(pSHA_CTX);
+		}		/* End of if */
+	}			/* End of while */
+	pSHA_CTX->MessageLen += MessageLen;
+}				/* End of SHA1_Append */
+
+/*
+========================================================================
+Routine Description:
+    1. Append bit 1 to end of the message
+    2. Append the length of message in rightmost 64 bits
+    3. Transform the Hash Value to digest message
+
+Arguments:
+    pSHA_CTX        Pointer to struct rt_sha1_ctx
+
+Return Value:
+    digestMessage   Digest message
+
+Note:
+    None
+========================================================================
+*/
+void SHA1_End(struct rt_sha1_ctx *pSHA_CTX, u8 DigestMessage[])
+{
+	u32 index;
+	u64 message_length_bits;
+
+	/* Append bit 1 to end of the message */
+	NdisFillMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, 1, 0x80);
+
+	/* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
+	if (pSHA_CTX->BlockLen > 55)
+		SHA1_Hash(pSHA_CTX);
+	/* End of if */
+
+	/* Append the length of message in rightmost 64 bits */
+	message_length_bits = pSHA_CTX->MessageLen * 8;
+	message_length_bits = cpu2be64(message_length_bits);
+	NdisMoveMemory(&pSHA_CTX->Block[56], &message_length_bits, 8);
+	SHA1_Hash(pSHA_CTX);
+
+	/* Return message digest, transform the u32 hash value to bytes */
+	for (index = 0; index < 5; index++)
+		pSHA_CTX->HashValue[index] =
+		    cpu2be32(pSHA_CTX->HashValue[index]);
+	/* End of for */
+	NdisMoveMemory(DigestMessage, pSHA_CTX->HashValue, SHA1_DIGEST_SIZE);
+}				/* End of SHA1_End */
+
+/*
+========================================================================
+Routine Description:
+    SHA1 algorithm
+
+Arguments:
+    message         Message context
+    messageLen      The length of message in bytes
+
+Return Value:
+    digestMessage   Digest message
+
+Note:
+    None
+========================================================================
+*/
+void RT_SHA1(IN const u8 Message[],
+	     u32 MessageLen, u8 DigestMessage[])
+{
+
+	struct rt_sha1_ctx sha_ctx;
+
+	NdisZeroMemory(&sha_ctx, sizeof(struct rt_sha1_ctx));
+	RT_SHA1_Init(&sha_ctx);
+	SHA1_Append(&sha_ctx, Message, MessageLen);
+	SHA1_End(&sha_ctx, DigestMessage);
+}				/* End of RT_SHA1 */
+#endif /* SHA1_SUPPORT */
+
+/* End of crypt_sha2.c */
diff --git a/drivers/staging/rt2860/common/dfs.c b/drivers/staging/rt2860/common/dfs.c
index 23330f2..71cbb26 100644
--- a/drivers/staging/rt2860/common/dfs.c
+++ b/drivers/staging/rt2860/common/dfs.c
@@ -33,164 +33,10 @@
     Revision History:
     Who       When            What
     --------  ----------      ----------------------------------------------
-    Fonchi    03-12-2007      created
 */
 
 #include "../rt_config.h"
 
-typedef struct _RADAR_DURATION_TABLE
-{
-	ULONG RDDurRegion;
-	ULONG RadarSignalDuration;
-	ULONG Tolerance;
-} RADAR_DURATION_TABLE, *PRADAR_DURATION_TABLE;
-
-
-static UCHAR RdIdleTimeTable[MAX_RD_REGION][4] =
-{
-	{9, 250, 250, 250},		// CE
-	{4, 250, 250, 250},		// FCC
-	{4, 250, 250, 250},		// JAP
-	{15, 250, 250, 250},	// JAP_W53
-	{4, 250, 250, 250}		// JAP_W56
-};
-
-/*
-	========================================================================
-
-	Routine Description:
-		Bbp Radar detection routine
-
-	Arguments:
-		pAd 	Pointer to our adapter
-
-	Return Value:
-
-	========================================================================
-*/
-VOID BbpRadarDetectionStart(
-	IN PRTMP_ADAPTER pAd)
-{
-	UINT8 RadarPeriod;
-
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 114, 0x02);
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 121, 0x20);
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 122, 0x00);
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 123, 0x08/*0x80*/);
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 124, 0x28);
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 125, 0xff);
-
-	RadarPeriod = ((UINT)RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + (UINT)pAd->CommonCfg.RadarDetect.DfsSessionTime) < 250 ?
-			(RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + pAd->CommonCfg.RadarDetect.DfsSessionTime) : 250;
-
-	RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
-	RTMP_IO_WRITE8(pAd, 0x7021, 0x40);
-
-	RadarDetectionStart(pAd, 0, RadarPeriod);
-	return;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Bbp Radar detection routine
-
-	Arguments:
-		pAd 	Pointer to our adapter
-
-	Return Value:
-
-	========================================================================
-*/
-VOID BbpRadarDetectionStop(
-	IN PRTMP_ADAPTER pAd)
-{
-	RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
-	RTMP_IO_WRITE8(pAd, 0x7021, 0x60);
-
-	RadarDetectionStop(pAd);
-	return;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Radar detection routine
-
-	Arguments:
-		pAd 	Pointer to our adapter
-
-	Return Value:
-
-	========================================================================
-*/
-VOID RadarDetectionStart(
-	IN PRTMP_ADAPTER pAd,
-	IN BOOLEAN CTSProtect,
-	IN UINT8 CTSPeriod)
-{
-	UINT8 DfsActiveTime = (pAd->CommonCfg.RadarDetect.DfsSessionTime & 0x1f);
-	UINT8 CtsProtect = (CTSProtect == 1) ? 0x02 : 0x01; // CTS protect.
-
-	if (CTSProtect != 0)
-	{
-		switch(pAd->CommonCfg.RadarDetect.RDDurRegion)
-		{
-		case FCC:
-		case JAP_W56:
-			CtsProtect = 0x03;
-			break;
-
-		case CE:
-		case JAP_W53:
-		default:
-			CtsProtect = 0x02;
-			break;
-		}
-	}
-	else
-		CtsProtect = 0x01;
-
-
-	// send start-RD with CTS protection command to MCU
-	// highbyte [7]		reserve
-	// highbyte [6:5]	0x: stop Carrier/Radar detection
-	// highbyte [10]:	Start Carrier/Radar detection without CTS protection, 11: Start Carrier/Radar detection with CTS protection
-	// highbyte [4:0]	Radar/carrier detection duration. In 1ms.
-
-	// lowbyte [7:0]	Radar/carrier detection period, in 1ms.
-	AsicSendCommandToMcu(pAd, 0x60, 0xff, CTSPeriod, DfsActiveTime | (CtsProtect << 5));
-	//AsicSendCommandToMcu(pAd, 0x63, 0xff, 10, 0);
-
-	return;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Radar detection routine
-
-	Arguments:
-		pAd 	Pointer to our adapter
-
-	Return Value:
-		TRUE	Found radar signal
-		FALSE	Not found radar signal
-
-	========================================================================
-*/
-VOID RadarDetectionStop(
-	IN PRTMP_ADAPTER	pAd)
-{
-	DBGPRINT(RT_DEBUG_TRACE,("RadarDetectionStop.\n"));
-	AsicSendCommandToMcu(pAd, 0x60, 0xff, 0x00, 0x00);	// send start-RD with CTS protection command to MCU
-
-	return;
-}
-
 /*
 	========================================================================
 
@@ -206,227 +52,17 @@
 
 	========================================================================
 */
-BOOLEAN RadarChannelCheck(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			Ch)
+BOOLEAN RadarChannelCheck(struct rt_rtmp_adapter *pAd, u8 Ch)
 {
-#if 1
-	INT		i;
+	int i;
 	BOOLEAN result = FALSE;
 
-	for (i=0; i<pAd->ChannelListNum; i++)
-	{
-		if (Ch == pAd->ChannelList[i].Channel)
-		{
+	for (i = 0; i < pAd->ChannelListNum; i++) {
+		if (Ch == pAd->ChannelList[i].Channel) {
 			result = pAd->ChannelList[i].DfsReq;
 			break;
 		}
 	}
 
 	return result;
-#else
-	INT		i;
-	UCHAR	Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
-
-	for (i=0; i<15; i++)
-	{
-		if (Ch == Channel[i])
-		{
-			break;
-		}
-	}
-
-	if (i != 15)
-		return TRUE;
-	else
-		return FALSE;
-#endif
 }
-
-ULONG JapRadarType(
-	IN PRTMP_ADAPTER pAd)
-{
-	ULONG		i;
-	const UCHAR	Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
-
-	if (pAd->CommonCfg.RadarDetect.RDDurRegion != JAP)
-	{
-		return pAd->CommonCfg.RadarDetect.RDDurRegion;
-	}
-
-	for (i=0; i<15; i++)
-	{
-		if (pAd->CommonCfg.Channel == Channel[i])
-		{
-			break;
-		}
-	}
-
-	if (i < 4)
-		return JAP_W53;
-	else if (i < 15)
-		return JAP_W56;
-	else
-		return JAP; // W52
-
-}
-
-ULONG RTMPBbpReadRadarDuration(
-	IN PRTMP_ADAPTER	pAd)
-{
-	UINT8 byteValue = 0;
-	ULONG result;
-
-	BBP_IO_READ8_BY_REG_ID(pAd, BBP_R115, &byteValue);
-
-	result = 0;
-	switch (byteValue)
-	{
-	case 1: // radar signal detected by pulse mode.
-	case 2: // radar signal detected by width mode.
-		result = RTMPReadRadarDuration(pAd);
-		break;
-
-	case 0: // No radar signal.
-	default:
-
-		result = 0;
-		break;
-	}
-
-	return result;
-}
-
-ULONG RTMPReadRadarDuration(
-	IN PRTMP_ADAPTER	pAd)
-{
-	ULONG result = 0;
-
-	return result;
-
-}
-
-VOID RTMPCleanRadarDuration(
-	IN PRTMP_ADAPTER	pAd)
-{
-	return;
-}
-
-/*
-    ========================================================================
-    Routine Description:
-        Radar wave detection. The API should be invoke each second.
-
-    Arguments:
-        pAd         - Adapter pointer
-
-    Return Value:
-        None
-
-    ========================================================================
-*/
-VOID ApRadarDetectPeriodic(
-	IN PRTMP_ADAPTER pAd)
-{
-	INT	i;
-
-	pAd->CommonCfg.RadarDetect.InServiceMonitorCount++;
-
-	for (i=0; i<pAd->ChannelListNum; i++)
-	{
-		if (pAd->ChannelList[i].RemainingTimeForUse > 0)
-		{
-			pAd->ChannelList[i].RemainingTimeForUse --;
-			if ((pAd->Mlme.PeriodicRound%5) == 0)
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("RadarDetectPeriodic - ch=%d, RemainingTimeForUse=%d\n", pAd->ChannelList[i].Channel, pAd->ChannelList[i].RemainingTimeForUse));
-			}
-		}
-	}
-
-	//radar detect
-	if ((pAd->CommonCfg.Channel > 14)
-		&& (pAd->CommonCfg.bIEEE80211H == 1)
-		&& RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
-	{
-		RadarDetectPeriodic(pAd);
-	}
-
-	return;
-}
-
-// Periodic Radar detection, switch channel will occur in RTMPHandleTBTTInterrupt()
-// Before switch channel, driver needs doing channel switch announcement.
-VOID RadarDetectPeriodic(
-	IN PRTMP_ADAPTER	pAd)
-{
-	// need to check channel availability, after switch channel
-	if (pAd->CommonCfg.RadarDetect.RDMode != RD_SILENCE_MODE)
-			return;
-
-	// channel availability check time is 60sec, use 65 for assurance
-	if (pAd->CommonCfg.RadarDetect.RDCount++ > pAd->CommonCfg.RadarDetect.ChMovingTime)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("Not found radar signal, start send beacon and radar detection in service monitor\n\n"));
-			BbpRadarDetectionStop(pAd);
-		AsicEnableBssSync(pAd);
-		pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
-
-
-		return;
-	}
-
-	return;
-}
-
-
-/*
-    ==========================================================================
-    Description:
-		change channel moving time for DFS testing.
-
-	Arguments:
-	    pAdapter                    Pointer to our adapter
-	    wrq                         Pointer to the ioctl argument
-
-    Return Value:
-        None
-
-    Note:
-        Usage:
-               1.) iwpriv ra0 set ChMovTime=[value]
-    ==========================================================================
-*/
-INT Set_ChMovingTime_Proc(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR arg)
-{
-	UINT8 Value;
-
-	Value = simple_strtol(arg, 0, 10);
-
-	pAd->CommonCfg.RadarDetect.ChMovingTime = Value;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __func__,
-		pAd->CommonCfg.RadarDetect.ChMovingTime));
-
-	return TRUE;
-}
-
-INT Set_LongPulseRadarTh_Proc(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR arg)
-{
-	UINT8 Value;
-
-	Value = simple_strtol(arg, 0, 10) > 10 ? 10 : simple_strtol(arg, 0, 10);
-
-	pAd->CommonCfg.RadarDetect.LongPulseRadarTh = Value;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __func__,
-		pAd->CommonCfg.RadarDetect.LongPulseRadarTh));
-
-	return TRUE;
-}
-
-
diff --git a/drivers/staging/rt2860/common/ee_efuse.c b/drivers/staging/rt2860/common/ee_efuse.c
new file mode 100644
index 0000000..03412f5
--- /dev/null
+++ b/drivers/staging/rt2860/common/ee_efuse.c
@@ -0,0 +1,344 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	ee_efuse.c
+
+	Abstract:
+	Miniport generic portion header file
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+#include	"../rt_config.h"
+
+#define EFUSE_USAGE_MAP_START	0x2d0
+#define EFUSE_USAGE_MAP_END		0x2fc
+#define EFUSE_USAGE_MAP_SIZE	45
+
+#define EFUSE_EEPROM_DEFULT_FILE	"RT30xxEEPROM.bin"
+#define MAX_EEPROM_BIN_FILE_SIZE	1024
+
+#define EFUSE_TAG				0x2fe
+
+typedef union _EFUSE_CTRL_STRUC {
+	struct {
+		u32 EFSROM_AOUT:6;
+		u32 EFSROM_MODE:2;
+		u32 EFSROM_LDO_OFF_TIME:6;
+		u32 EFSROM_LDO_ON_TIME:2;
+		u32 EFSROM_AIN:10;
+		u32 RESERVED:4;
+		u32 EFSROM_KICK:1;
+		u32 SEL_EFUSE:1;
+	} field;
+	u32 word;
+} EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC;
+
+/*
+========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+========================================================================
+*/
+u8 eFuseReadRegisters(struct rt_rtmp_adapter *pAd,
+			 u16 Offset, u16 Length, u16 * pData)
+{
+	EFUSE_CTRL_STRUC eFuseCtrlStruc;
+	int i;
+	u16 efuseDataOffset;
+	u32 data;
+
+	RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
+
+	/*Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment. */
+	/*Use the eeprom logical address and covert to address to block number */
+	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
+
+	/*Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 0. */
+	eFuseCtrlStruc.field.EFSROM_MODE = 0;
+
+	/*Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure. */
+	eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+	/*Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. */
+	i = 0;
+	while (i < 500) {
+		/*rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4); */
+		RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
+		if (eFuseCtrlStruc.field.EFSROM_KICK == 0) {
+			break;
+		}
+		RTMPusecDelay(2);
+		i++;
+	}
+
+	/*if EFSROM_AOUT is not found in physical address, write 0xffff */
+	if (eFuseCtrlStruc.field.EFSROM_AOUT == 0x3f) {
+		for (i = 0; i < Length / 2; i++)
+			*(pData + 2 * i) = 0xffff;
+	} else {
+		/*Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x590-0x59C) */
+		efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC);
+		/*data hold 4 bytes data. */
+		/*In RTMP_IO_READ32 will automatically execute 32-bytes swapping */
+		RTMP_IO_READ32(pAd, efuseDataOffset, &data);
+		/*Decide the upper 2 bytes or the bottom 2 bytes. */
+		/* Little-endian                S       |       S       Big-endian */
+		/* addr 3       2       1       0       |       0       1       2       3 */
+		/* Ori-V        D       C       B       A       |       A       B       C       D */
+		/*After swapping */
+		/*              D       C       B       A       |       D       C       B       A */
+		/*Return 2-bytes */
+		/*The return byte statrs from S. Therefore, the little-endian will return BA, the Big-endian will return DC. */
+		/*For returning the bottom 2 bytes, the Big-endian should shift right 2-bytes. */
+		data = data >> (8 * (Offset & 0x3));
+
+		NdisMoveMemory(pData, &data, Length);
+	}
+
+	return (u8)eFuseCtrlStruc.field.EFSROM_AOUT;
+
+}
+
+/*
+========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+========================================================================
+*/
+void eFusePhysicalReadRegisters(struct rt_rtmp_adapter *pAd,
+				u16 Offset,
+				u16 Length, u16 * pData)
+{
+	EFUSE_CTRL_STRUC eFuseCtrlStruc;
+	int i;
+	u16 efuseDataOffset;
+	u32 data;
+
+	RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
+
+	/*Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment. */
+	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
+
+	/*Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1. */
+	/*Read in physical view */
+	eFuseCtrlStruc.field.EFSROM_MODE = 1;
+
+	/*Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure. */
+	eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+	/*Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. */
+	i = 0;
+	while (i < 500) {
+		RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
+		if (eFuseCtrlStruc.field.EFSROM_KICK == 0)
+			break;
+		RTMPusecDelay(2);
+		i++;
+	}
+
+	/*Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590) */
+	/*Because the size of each EFUSE_DATA is 4 Bytes, the size of address of each is 2 bits. */
+	/*The previous 2 bits is the EFUSE_DATA number, the last 2 bits is used to decide which bytes */
+	/*Decide which EFUSE_DATA to read */
+	/*590:F E D C */
+	/*594:B A 9 8 */
+	/*598:7 6 5 4 */
+	/*59C:3 2 1 0 */
+	efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC);
+
+	RTMP_IO_READ32(pAd, efuseDataOffset, &data);
+
+	data = data >> (8 * (Offset & 0x3));
+
+	NdisMoveMemory(pData, &data, Length);
+
+}
+
+/*
+========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+========================================================================
+*/
+static void eFuseReadPhysical(struct rt_rtmp_adapter *pAd,
+			      u16 *lpInBuffer,
+			      unsigned long nInBufferSize,
+			      u16 *lpOutBuffer, unsigned long nOutBufferSize)
+{
+	u16 *pInBuf = (u16 *) lpInBuffer;
+	u16 *pOutBuf = (u16 *) lpOutBuffer;
+
+	u16 Offset = pInBuf[0];	/*addr */
+	u16 Length = pInBuf[1];	/*length */
+	int i;
+
+	for (i = 0; i < Length; i += 2) {
+		eFusePhysicalReadRegisters(pAd, Offset + i, 2, &pOutBuf[i / 2]);
+	}
+}
+
+/*
+========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+========================================================================
+*/
+int set_eFuseGetFreeBlockCount_Proc(struct rt_rtmp_adapter *pAd, char *arg)
+{
+	u16 i;
+	u16 LogicalAddress;
+	u16 efusefreenum = 0;
+	if (!pAd->bUseEfuse)
+		return FALSE;
+	for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i += 2) {
+		eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+		if ((LogicalAddress & 0xff) == 0) {
+			efusefreenum = (u8)(EFUSE_USAGE_MAP_END - i + 1);
+			break;
+		} else if (((LogicalAddress >> 8) & 0xff) == 0) {
+			efusefreenum = (u8)(EFUSE_USAGE_MAP_END - i);
+			break;
+		}
+
+		if (i == EFUSE_USAGE_MAP_END)
+			efusefreenum = 0;
+	}
+	printk("efuseFreeNumber is %d\n", efusefreenum);
+	return TRUE;
+}
+
+int set_eFusedump_Proc(struct rt_rtmp_adapter *pAd, char *arg)
+{
+	u16 InBuf[3];
+	int i = 0;
+	if (!pAd->bUseEfuse)
+		return FALSE;
+	for (i = 0; i < EFUSE_USAGE_MAP_END / 2; i++) {
+		InBuf[0] = 2 * i;
+		InBuf[1] = 2;
+		InBuf[2] = 0x0;
+
+		eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+		if (i % 4 == 0)
+			printk("\nBlock %x:", i / 8);
+		printk("%04x ", InBuf[2]);
+	}
+	return TRUE;
+}
+
+int rtmp_ee_efuse_read16(struct rt_rtmp_adapter *pAd,
+			 u16 Offset, u16 * pValue)
+{
+	eFuseReadRegisters(pAd, Offset, 2, pValue);
+	return (*pValue);
+}
+
+int RtmpEfuseSupportCheck(struct rt_rtmp_adapter *pAd)
+{
+	u16 value;
+
+	if (IS_RT30xx(pAd)) {
+		eFusePhysicalReadRegisters(pAd, EFUSE_TAG, 2, &value);
+		pAd->EFuseTag = (value & 0xff);
+	}
+	return 0;
+}
+
+void eFuseGetFreeBlockCount(struct rt_rtmp_adapter *pAd, u32 *EfuseFreeBlock)
+{
+	u16 i;
+	u16 LogicalAddress;
+	if (!pAd->bUseEfuse) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("eFuseGetFreeBlockCount Only supports efuse Mode\n"));
+		return;
+	}
+	for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i += 2) {
+		eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+		if ((LogicalAddress & 0xff) == 0) {
+			*EfuseFreeBlock = (u8)(EFUSE_USAGE_MAP_END - i + 1);
+			break;
+		} else if (((LogicalAddress >> 8) & 0xff) == 0) {
+			*EfuseFreeBlock = (u8)(EFUSE_USAGE_MAP_END - i);
+			break;
+		}
+
+		if (i == EFUSE_USAGE_MAP_END)
+			*EfuseFreeBlock = 0;
+	}
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("eFuseGetFreeBlockCount is 0x%x\n", *EfuseFreeBlock));
+}
+
+int eFuse_init(struct rt_rtmp_adapter *pAd)
+{
+	u32 EfuseFreeBlock = 0;
+	DBGPRINT(RT_DEBUG_ERROR,
+		 ("NVM is Efuse and its size =%x[%x-%x] \n",
+		  EFUSE_USAGE_MAP_SIZE, EFUSE_USAGE_MAP_START,
+		  EFUSE_USAGE_MAP_END));
+	eFuseGetFreeBlockCount(pAd, &EfuseFreeBlock);
+
+	return 0;
+}
diff --git a/drivers/staging/rt2860/common/ee_prom.c b/drivers/staging/rt2860/common/ee_prom.c
new file mode 100644
index 0000000..2083740
--- /dev/null
+++ b/drivers/staging/rt2860/common/ee_prom.c
@@ -0,0 +1,197 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	ee_prom.c
+
+	Abstract:
+	Miniport generic portion header file
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+#include	"../rt_config.h"
+
+/* IRQL = PASSIVE_LEVEL */
+static inline void RaiseClock(struct rt_rtmp_adapter *pAd, u32 * x)
+{
+	*x = *x | EESK;
+	RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
+	RTMPusecDelay(1);	/* Max frequency = 1MHz in Spec. definition */
+}
+
+/* IRQL = PASSIVE_LEVEL */
+static inline void LowerClock(struct rt_rtmp_adapter *pAd, u32 * x)
+{
+	*x = *x & ~EESK;
+	RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
+	RTMPusecDelay(1);
+}
+
+/* IRQL = PASSIVE_LEVEL */
+static inline u16 ShiftInBits(struct rt_rtmp_adapter *pAd)
+{
+	u32 x, i;
+	u16 data = 0;
+
+	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+
+	x &= ~(EEDO | EEDI);
+
+	for (i = 0; i < 16; i++) {
+		data = data << 1;
+		RaiseClock(pAd, &x);
+
+		RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+		LowerClock(pAd, &x);	/*prevent read failed */
+
+		x &= ~(EEDI);
+		if (x & EEDO)
+			data |= 1;
+	}
+
+	return data;
+}
+
+/* IRQL = PASSIVE_LEVEL */
+static inline void ShiftOutBits(struct rt_rtmp_adapter *pAd,
+				u16 data, u16 count)
+{
+	u32 x, mask;
+
+	mask = 0x01 << (count - 1);
+	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+
+	x &= ~(EEDO | EEDI);
+
+	do {
+		x &= ~EEDI;
+		if (data & mask)
+			x |= EEDI;
+
+		RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+		RaiseClock(pAd, &x);
+		LowerClock(pAd, &x);
+
+		mask = mask >> 1;
+	} while (mask);
+
+	x &= ~EEDI;
+	RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+}
+
+/* IRQL = PASSIVE_LEVEL */
+static inline void EEpromCleanup(struct rt_rtmp_adapter *pAd)
+{
+	u32 x;
+
+	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+
+	x &= ~(EECS | EEDI);
+	RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+	RaiseClock(pAd, &x);
+	LowerClock(pAd, &x);
+}
+
+static inline void EWEN(struct rt_rtmp_adapter *pAd)
+{
+	u32 x;
+
+	/* reset bits and set EECS */
+	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+	x &= ~(EEDI | EEDO | EESK);
+	x |= EECS;
+	RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+	/* kick a pulse */
+	RaiseClock(pAd, &x);
+	LowerClock(pAd, &x);
+
+	/* output the read_opcode and six pulse in that order */
+	ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5);
+	ShiftOutBits(pAd, 0, 6);
+
+	EEpromCleanup(pAd);
+}
+
+static inline void EWDS(struct rt_rtmp_adapter *pAd)
+{
+	u32 x;
+
+	/* reset bits and set EECS */
+	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+	x &= ~(EEDI | EEDO | EESK);
+	x |= EECS;
+	RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+	/* kick a pulse */
+	RaiseClock(pAd, &x);
+	LowerClock(pAd, &x);
+
+	/* output the read_opcode and six pulse in that order */
+	ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5);
+	ShiftOutBits(pAd, 0, 6);
+
+	EEpromCleanup(pAd);
+}
+
+/* IRQL = PASSIVE_LEVEL */
+int rtmp_ee_prom_read16(struct rt_rtmp_adapter *pAd,
+			u16 Offset, u16 * pValue)
+{
+	u32 x;
+	u16 data;
+
+	Offset /= 2;
+	/* reset bits and set EECS */
+	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+	x &= ~(EEDI | EEDO | EESK);
+	x |= EECS;
+	RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+	/* patch can not access e-Fuse issue */
+	if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) {
+		/* kick a pulse */
+		RaiseClock(pAd, &x);
+		LowerClock(pAd, &x);
+	}
+	/* output the read_opcode and register number in that order */
+	ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3);
+	ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
+
+	/* Now read the data (16 bits) in from the selected EEPROM word */
+	data = ShiftInBits(pAd);
+
+	EEpromCleanup(pAd);
+
+	*pValue = data;
+
+	return NDIS_STATUS_SUCCESS;
+}
diff --git a/drivers/staging/rt2860/common/eeprom.c b/drivers/staging/rt2860/common/eeprom.c
index ffcb4ce..9467007 100644
--- a/drivers/staging/rt2860/common/eeprom.c
+++ b/drivers/staging/rt2860/common/eeprom.c
@@ -36,1444 +36,56 @@
 */
 #include "../rt_config.h"
 
-// IRQL = PASSIVE_LEVEL
-VOID RaiseClock(
-    IN	PRTMP_ADAPTER	pAd,
-    IN  UINT32 *x)
+int RtmpChipOpsEepromHook(struct rt_rtmp_adapter *pAd, int infType)
 {
-    *x = *x | EESK;
-    RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
-    RTMPusecDelay(1);				// Max frequency = 1MHz in Spec. definition
-}
+	struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
+#ifdef RT30xx
+#ifdef RTMP_EFUSE_SUPPORT
+	u32 eFuseCtrl, MacCsr0;
+	int index;
 
-// IRQL = PASSIVE_LEVEL
-VOID LowerClock(
-    IN	PRTMP_ADAPTER	pAd,
-    IN  UINT32 *x)
-{
-    *x = *x & ~EESK;
-    RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
-    RTMPusecDelay(1);
-}
+	index = 0;
+	do {
+		RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
+		pAd->MACVersion = MacCsr0;
 
-// IRQL = PASSIVE_LEVEL
-USHORT ShiftInBits(
-    IN	PRTMP_ADAPTER	pAd)
-{
-    UINT32		x,i;
-	USHORT      data=0;
-
-    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-
-    x &= ~( EEDO | EEDI);
-
-    for(i=0; i<16; i++)
-    {
-        data = data << 1;
-        RaiseClock(pAd, &x);
-
-        RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-
-	LowerClock(pAd, &x); /* prevent read failed */
-
-        x &= ~(EEDI);
-        if(x & EEDO)
-            data |= 1;
-    }
-
-    return data;
-}
-
-// IRQL = PASSIVE_LEVEL
-VOID ShiftOutBits(
-    IN	PRTMP_ADAPTER	pAd,
-    IN  USHORT data,
-    IN  USHORT count)
-{
-    UINT32       x,mask;
-
-    mask = 0x01 << (count - 1);
-    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-
-    x &= ~(EEDO | EEDI);
-
-    do
-    {
-        x &= ~EEDI;
-        if(data & mask)		x |= EEDI;
-
-        RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-        RaiseClock(pAd, &x);
-        LowerClock(pAd, &x);
-
-        mask = mask >> 1;
-    } while(mask);
-
-    x &= ~EEDI;
-    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-}
-
-// IRQL = PASSIVE_LEVEL
-VOID EEpromCleanup(
-    IN	PRTMP_ADAPTER	pAd)
-{
-    UINT32 x;
-
-    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-
-    x &= ~(EECS | EEDI);
-    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-    RaiseClock(pAd, &x);
-    LowerClock(pAd, &x);
-}
-
-VOID EWEN(
-	IN	PRTMP_ADAPTER	pAd)
-{
-    UINT32	x;
-
-    // reset bits and set EECS
-    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-    x &= ~(EEDI | EEDO | EESK);
-    x |= EECS;
-    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-	// kick a pulse
-	RaiseClock(pAd, &x);
-	LowerClock(pAd, &x);
-
-    // output the read_opcode and six pulse in that order
-    ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5);
-    ShiftOutBits(pAd, 0, 6);
-
-    EEpromCleanup(pAd);
-}
-
-VOID EWDS(
-	IN	PRTMP_ADAPTER	pAd)
-{
-    UINT32	x;
-
-    // reset bits and set EECS
-    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-    x &= ~(EEDI | EEDO | EESK);
-    x |= EECS;
-    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-	// kick a pulse
-	RaiseClock(pAd, &x);
-	LowerClock(pAd, &x);
-
-    // output the read_opcode and six pulse in that order
-    ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5);
-    ShiftOutBits(pAd, 0, 6);
-
-    EEpromCleanup(pAd);
-}
-
-// IRQL = PASSIVE_LEVEL
-USHORT RTMP_EEPROM_READ16(
-    IN	PRTMP_ADAPTER	pAd,
-    IN  USHORT Offset)
-{
-    UINT32		x;
-    USHORT		data;
-
-#ifdef RT2870
-	if (pAd->NicConfig2.field.AntDiversity)
-    {
-    	pAd->EepromAccess = TRUE;
-    }
-#endif
-    Offset /= 2;
-    // reset bits and set EECS
-    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-    x &= ~(EEDI | EEDO | EESK);
-    x |= EECS;
-    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-	// patch can not access e-Fuse issue
-    if (!IS_RT3090(pAd))
-    {
-	// kick a pulse
-	RaiseClock(pAd, &x);
-	LowerClock(pAd, &x);
-    }
-
-    // output the read_opcode and register number in that order
-    ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3);
-    ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
-
-    // Now read the data (16 bits) in from the selected EEPROM word
-    data = ShiftInBits(pAd);
-
-    EEpromCleanup(pAd);
-
-#ifdef RT2870
-	// Antenna and EEPROM access are both using EESK pin,
-    // Therefor we should avoid accessing EESK at the same time
-    // Then restore antenna after EEPROM access
-	if ((pAd->NicConfig2.field.AntDiversity) || (pAd->RfIcType == RFIC_3020))
-    {
-	    pAd->EepromAccess = FALSE;
-	    AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
-    }
-#endif
-    return data;
-}	//ReadEEprom
-
-VOID RTMP_EEPROM_WRITE16(
-    IN	PRTMP_ADAPTER	pAd,
-    IN  USHORT Offset,
-    IN  USHORT Data)
-{
-    UINT32 x;
-
-#ifdef RT2870
-	if (pAd->NicConfig2.field.AntDiversity)
-    {
-    	pAd->EepromAccess = TRUE;
-    }
-#endif
-	Offset /= 2;
-
-	EWEN(pAd);
-
-    // reset bits and set EECS
-    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-    x &= ~(EEDI | EEDO | EESK);
-    x |= EECS;
-    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-	// patch can not access e-Fuse issue
-    if (!IS_RT3090(pAd))
-    {
-	// kick a pulse
-	RaiseClock(pAd, &x);
-	LowerClock(pAd, &x);
-    }
-
-    // output the read_opcode ,register number and data in that order
-    ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3);
-    ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
-	ShiftOutBits(pAd, Data, 16);		// 16-bit access
-
-    // read DO status
-    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-
-	EEpromCleanup(pAd);
-
-	RTMPusecDelay(10000);	//delay for twp(MAX)=10ms
-
-	EWDS(pAd);
-
-    EEpromCleanup(pAd);
-
-#ifdef RT2870
-	// Antenna and EEPROM access are both using EESK pin,
-    // Therefor we should avoid accessing EESK at the same time
-    // Then restore antenna after EEPROM access
-	if ((pAd->NicConfig2.field.AntDiversity) || (pAd->RfIcType == RFIC_3020))
-    {
-	    pAd->EepromAccess = FALSE;
-	    AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
-    }
-#endif
-}
-
-#ifdef RT2870
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-UCHAR eFuseReadRegisters(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	OUT	USHORT* pData)
-{
-	EFUSE_CTRL_STRUC		eFuseCtrlStruc;
-	int	i;
-	USHORT	efuseDataOffset;
-	UINT32	data;
-
-	RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
-
-	//Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
-	//Use the eeprom logical address and covert to address to block number
-	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
-
-	//Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 0.
-	eFuseCtrlStruc.field.EFSROM_MODE = 0;
-
-	//Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
-	eFuseCtrlStruc.field.EFSROM_KICK = 1;
-
-	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
-	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
-
-	//Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
-	i = 0;
-	while(i < 100)
-	{
-		//rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4);
-		RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
-		if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
-		{
-			break;
-		}
-		RTMPusecDelay(2);
-		i++;
-	}
-
-	//if EFSROM_AOUT is not found in physical address, write 0xffff
-	if (eFuseCtrlStruc.field.EFSROM_AOUT == 0x3f)
-	{
-		for(i=0; i<Length/2; i++)
-			*(pData+2*i) = 0xffff;
-	}
-	else
-	{
-		//Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x590-0x59C)
-		efuseDataOffset =  EFUSE_DATA3 - (Offset & 0xC)  ;
-		//data hold 4 bytes data.
-		//In RTMP_IO_READ32 will automatically execute 32-bytes swapping
-		RTMP_IO_READ32(pAd, efuseDataOffset, &data);
-		//Decide the upper 2 bytes or the bottom 2 bytes.
-		// Little-endian		S	|	S	Big-endian
-		// addr	3	2	1	0	|	0	1	2	3
-		// Ori-V	D	C	B	A	|	A	B	C	D
-		//After swapping
-		//		D	C	B	A	|	D	C	B	A
-		//Return 2-bytes
-		//The return byte statrs from S. Therefore, the little-endian will return BA, the Big-endian will return DC.
-		//For returning the bottom 2 bytes, the Big-endian should shift right 2-bytes.
-		data = data >> (8*(Offset & 0x3));
-
-		NdisMoveMemory(pData, &data, Length);
-	}
-
-	return (UCHAR) eFuseCtrlStruc.field.EFSROM_AOUT;
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-VOID eFusePhysicalReadRegisters(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	OUT	USHORT* pData)
-{
-	EFUSE_CTRL_STRUC		eFuseCtrlStruc;
-	int	i;
-	USHORT	efuseDataOffset;
-	UINT32	data;
-
-	RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
-
-	//Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
-	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
-
-	//Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
-	//Read in physical view
-	eFuseCtrlStruc.field.EFSROM_MODE = 1;
-
-	//Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
-	eFuseCtrlStruc.field.EFSROM_KICK = 1;
-
-	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
-	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
-
-	//Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
-	i = 0;
-	while(i < 100)
-	{
-		RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
-		if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
-			break;
-		RTMPusecDelay(2);
-		i++;
-	}
-
-	//Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
-	//Because the size of each EFUSE_DATA is 4 Bytes, the size of address of each is 2 bits.
-	//The previous 2 bits is the EFUSE_DATA number, the last 2 bits is used to decide which bytes
-	//Decide which EFUSE_DATA to read
-	//590:F E D C
-	//594:B A 9 8
-	//598:7 6 5 4
-	//59C:3 2 1 0
-	efuseDataOffset =  EFUSE_DATA3 - (Offset & 0xC)  ;
-
-	RTMP_IO_READ32(pAd, efuseDataOffset, &data);
-
-	data = data >> (8*(Offset & 0x3));
-
-	NdisMoveMemory(pData, &data, Length);
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-VOID eFuseReadPhysical(
-	IN	PRTMP_ADAPTER	pAd,
-  	IN	PUSHORT lpInBuffer,
-  	IN	ULONG nInBufferSize,
-  	OUT	PUSHORT lpOutBuffer,
-  	IN	ULONG nOutBufferSize
-)
-{
-	USHORT* pInBuf = (USHORT*)lpInBuffer;
-	USHORT* pOutBuf = (USHORT*)lpOutBuffer;
-
-	USHORT Offset = pInBuf[0];					//addr
-	USHORT Length = pInBuf[1];					//length
-	int 		i;
-
-	for(i=0; i<Length; i+=2)
-	{
-		eFusePhysicalReadRegisters(pAd,Offset+i, 2, &pOutBuf[i/2]);
-	}
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-NTSTATUS eFuseRead(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	OUT	PUCHAR			pData,
-	IN	USHORT			Length)
-{
-	USHORT* pOutBuf = (USHORT*)pData;
-	NTSTATUS	Status = STATUS_SUCCESS;
-	UCHAR	EFSROM_AOUT;
-	int	i;
-
-	for(i=0; i<Length; i+=2)
-	{
-		EFSROM_AOUT = eFuseReadRegisters(pAd, Offset+i, 2, &pOutBuf[i/2]);
-	}
-	return Status;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-VOID eFusePhysicalWriteRegisters(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	OUT	USHORT* pData)
-{
-	EFUSE_CTRL_STRUC		eFuseCtrlStruc;
-	int	i;
-	USHORT	efuseDataOffset;
-	UINT32	data, eFuseDataBuffer[4];
-
-	//Step0. Write 16-byte of data to EFUSE_DATA0-3 (0x590-0x59C), where EFUSE_DATA0 is the LSB DW, EFUSE_DATA3 is the MSB DW.
-
-	/////////////////////////////////////////////////////////////////
-	//read current values of 16-byte block
-	RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
-
-	//Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
-	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
-
-	//Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
-	eFuseCtrlStruc.field.EFSROM_MODE = 1;
-
-	//Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
-	eFuseCtrlStruc.field.EFSROM_KICK = 1;
-
-	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
-	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
-
-	//Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
-	i = 0;
-	while(i < 100)
-	{
-		RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
-
-		if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
-			break;
-		RTMPusecDelay(2);
-		i++;
-	}
-
-	//Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
-	efuseDataOffset =  EFUSE_DATA3;
-	for(i=0; i< 4; i++)
-	{
-		RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &eFuseDataBuffer[i]);
-		efuseDataOffset -=  4;
-	}
-
-	//Update the value, the offset is multiple of 2, length is 2
-	efuseDataOffset = (Offset & 0xc) >> 2;
-	data = pData[0] & 0xffff;
-	//The offset should be 0x***10 or 0x***00
-	if((Offset % 4) != 0)
-	{
-		eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff) | (data << 16);
-	}
-	else
-	{
-		eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff0000) | data;
-	}
-
-	efuseDataOffset =  EFUSE_DATA3;
-	for(i=0; i< 4; i++)
-	{
-		RTMP_IO_WRITE32(pAd, efuseDataOffset, eFuseDataBuffer[i]);
-		efuseDataOffset -= 4;
-	}
-	/////////////////////////////////////////////////////////////////
-
-	//Step1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
-	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
-
-	//Step2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
-	eFuseCtrlStruc.field.EFSROM_MODE = 3;
-
-	//Step3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
-	eFuseCtrlStruc.field.EFSROM_KICK = 1;
-
-	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
-	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
-
-	//Step4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It��s done.
-	i = 0;
-	while(i < 100)
-	{
-		RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
-
-		if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+		if ((pAd->MACVersion != 0x00)
+		    && (pAd->MACVersion != 0xFFFFFFFF))
 			break;
 
-		RTMPusecDelay(2);
-		i++;
+		RTMPusecDelay(10);
+	} while (index++ < 100);
+
+	pAd->bUseEfuse = FALSE;
+	RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrl);
+	pAd->bUseEfuse = ((eFuseCtrl & 0x80000000) == 0x80000000) ? 1 : 0;
+	if (pAd->bUseEfuse) {
+		pChipOps->eeinit = eFuse_init;
+		pChipOps->eeread = rtmp_ee_efuse_read16;
+		return 0;
+	} else
+		DBGPRINT(RT_DEBUG_TRACE, ("NVM is EEPROM\n"));
+#endif /* RTMP_EFUSE_SUPPORT // */
+#endif /* RT30xx // */
+
+	switch (infType) {
+#ifdef RTMP_PCI_SUPPORT
+	case RTMP_DEV_INF_PCI:
+		pChipOps->eeinit = NULL;
+		pChipOps->eeread = rtmp_ee_prom_read16;
+		break;
+#endif /* RTMP_PCI_SUPPORT // */
+#ifdef RTMP_USB_SUPPORT
+	case RTMP_DEV_INF_USB:
+		pChipOps->eeinit = NULL;
+		pChipOps->eeread = RTUSBReadEEPROM16;
+		break;
+#endif /* RTMP_USB_SUPPORT // */
+
+	default:
+		DBGPRINT(RT_DEBUG_ERROR, ("RtmpChipOpsEepromHook() failed!\n"));
+		break;
 	}
+
+	return 0;
 }
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-NTSTATUS eFuseWriteRegisters(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	IN	USHORT* pData)
-{
-	USHORT	i;
-	USHORT	eFuseData;
-	USHORT	LogicalAddress, BlkNum = 0xffff;
-	UCHAR	EFSROM_AOUT;
-
-	USHORT addr,tmpaddr, InBuf[3], tmpOffset;
-	USHORT buffer[8];
-	BOOLEAN		bWriteSuccess = TRUE;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters Offset=%x, pData=%x\n", Offset, *pData));
-
-	//Step 0. find the entry in the mapping table
-	//The address of EEPROM is 2-bytes alignment.
-	//The last bit is used for alignment, so it must be 0.
-	tmpOffset = Offset & 0xfffe;
-	EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
-
-	if( EFSROM_AOUT == 0x3f)
-	{	//find available logical address pointer
-		//the logical address does not exist, find an empty one
-		//from the first address of block 45=16*45=0x2d0 to the last address of block 47
-		//==>48*16-3(reserved)=2FC
-		for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
-		{
-			//Retrive the logical block nubmer form each logical address pointer
-			//It will access two logical address pointer each time.
-			eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
-			if( (LogicalAddress & 0xff) == 0)
-			{//Not used logical address pointer
-				BlkNum = i-EFUSE_USAGE_MAP_START;
-				break;
-			}
-			else if(( (LogicalAddress >> 8) & 0xff) == 0)
-			{//Not used logical address pointer
-				if (i != EFUSE_USAGE_MAP_END)
-				{
-					BlkNum = i-EFUSE_USAGE_MAP_START+1;
-				}
-				break;
-			}
-		}
-	}
-	else
-	{
-		BlkNum = EFSROM_AOUT;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
-
-	if(BlkNum == 0xffff)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
-		return FALSE;
-	}
-
-	//Step 1. Save data of this block	which is pointed by the avaible logical address pointer
-	// read and save the original block data
-	for(i =0; i<8; i++)
-	{
-		addr = BlkNum * 0x10 ;
-
-		InBuf[0] = addr+2*i;
-		InBuf[1] = 2;
-		InBuf[2] = 0x0;
-
-		eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
-
-		buffer[i] = InBuf[2];
-	}
-
-	//Step 2. Update the data in buffer, and write the data to Efuse
-	buffer[ (Offset >> 1) % 8] = pData[0];
-
-	do
-	{
-		//Step 3. Write the data to Efuse
-		if(!bWriteSuccess)
-		{
-			for(i =0; i<8; i++)
-			{
-				addr = BlkNum * 0x10 ;
-
-				InBuf[0] = addr+2*i;
-				InBuf[1] = 2;
-				InBuf[2] = buffer[i];
-
-				eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
-			}
-		}
-		else
-		{
-				addr = BlkNum * 0x10 ;
-
-				InBuf[0] = addr+(Offset % 16);
-				InBuf[1] = 2;
-				InBuf[2] = pData[0];
-
-				eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
-		}
-
-		//Step 4. Write mapping table
-		addr = EFUSE_USAGE_MAP_START+BlkNum;
-
-		tmpaddr = addr;
-
-		if(addr % 2 != 0)
-			addr = addr -1;
-		InBuf[0] = addr;
-		InBuf[1] = 2;
-
-		//convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
-		tmpOffset = Offset;
-		tmpOffset >>= 4;
-		tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^  (tmpOffset >> 2 & 0x01) ^  (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
-		tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
-
-		// write the logical address
-		if(tmpaddr%2 != 0)
-			InBuf[2] = tmpOffset<<8;
-		else
-			InBuf[2] = tmpOffset;
-
-		eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
-
-		//Step 5. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
-		bWriteSuccess = TRUE;
-		for(i =0; i<8; i++)
-		{
-			addr = BlkNum * 0x10 ;
-
-			InBuf[0] = addr+2*i;
-			InBuf[1] = 2;
-			InBuf[2] = 0x0;
-
-			eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
-
-			if(buffer[i] != InBuf[2])
-			{
-				bWriteSuccess = FALSE;
-				break;
-			}
-		}
-
-		//Step 6. invlidate mapping entry and find a free mapping entry if not succeed
-		if (!bWriteSuccess)
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess BlkNum = %d\n", BlkNum));
-
-			// the offset of current mapping entry
-			addr = EFUSE_USAGE_MAP_START+BlkNum;
-
-			//find a new mapping entry
-			BlkNum = 0xffff;
-			for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
-			{
-				eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
-				if( (LogicalAddress & 0xff) == 0)
-				{
-					BlkNum = i-EFUSE_USAGE_MAP_START;
-					break;
-				}
-				else if(( (LogicalAddress >> 8) & 0xff) == 0)
-				{
-					if (i != EFUSE_USAGE_MAP_END)
-					{
-						BlkNum = i+1-EFUSE_USAGE_MAP_START;
-					}
-					break;
-				}
-			}
-			DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess new BlkNum = %d\n", BlkNum));
-			if(BlkNum == 0xffff)
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
-				return FALSE;
-			}
-
-			//invalidate the original mapping entry if new entry is not found
-			tmpaddr = addr;
-
-			if(addr % 2 != 0)
-				addr = addr -1;
-			InBuf[0] = addr;
-			InBuf[1] = 2;
-
-			eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
-
-			// write the logical address
-			if(tmpaddr%2 != 0)
-			{
-				// Invalidate the high byte
-				for (i=8; i<15; i++)
-				{
-					if( ( (InBuf[2] >> i) & 0x01) == 0)
-					{
-						InBuf[2] |= (0x1 <<i);
-						break;
-					}
-				}
-			}
-			else
-			{
-				// invalidate the low byte
-				for (i=0; i<8; i++)
-				{
-					if( ( (InBuf[2] >> i) & 0x01) == 0)
-					{
-						InBuf[2] |= (0x1 <<i);
-						break;
-					}
-				}
-			}
-			eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
-		}
-	}
-	while(!bWriteSuccess);
-
-	return TRUE;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-VOID eFuseWritePhysical(
-	IN	PRTMP_ADAPTER	pAd,
-  	PUSHORT lpInBuffer,
-	ULONG nInBufferSize,
-  	PUCHAR lpOutBuffer,
-  	ULONG nOutBufferSize
-)
-{
-	USHORT* pInBuf = (USHORT*)lpInBuffer;
-	int 		i;
-	//USHORT* pOutBuf = (USHORT*)ioBuffer;
-
-	USHORT Offset = pInBuf[0];					//addr
-	USHORT Length = pInBuf[1];					//length
-	USHORT* pValueX = &pInBuf[2];				//value ...
-		// Little-endian		S	|	S	Big-endian
-		// addr	3	2	1	0	|	0	1	2	3
-		// Ori-V	D	C	B	A	|	A	B	C	D
-		//After swapping
-		//		D	C	B	A	|	D	C	B	A
-		//Both the little and big-endian use the same sequence to write  data.
-		//Therefore, we only need swap data when read the data.
-	for(i=0; i<Length; i+=2)
-	{
-		eFusePhysicalWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
-	}
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-NTSTATUS eFuseWrite(
-   	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	IN	PUCHAR			pData,
-	IN	USHORT			length)
-{
-	int i;
-
-	USHORT* pValueX = (PUSHORT) pData;				//value ...
-		//The input value=3070 will be stored as following
- 		// Little-endian		S	|	S	Big-endian
-		// addr			1	0	|	0	1
-		// Ori-V			30	70	|	30	70
-		//After swapping
-		//				30	70	|	70	30
-		//Casting
-		//				3070	|	7030 (x)
-		//The swapping should be removed for big-endian
-	for(i=0; i<length; i+=2)
-	{
-		eFuseWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
-	}
-
-	return TRUE;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-INT set_eFuseGetFreeBlockCount_Proc(
-   	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	USHORT i;
-	USHORT	LogicalAddress;
-	USHORT efusefreenum=0;
-	if(!pAd->bUseEfuse)
-		return FALSE;
-	for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i+=2)
-	{
-		eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
-		if( (LogicalAddress & 0xff) == 0)
-		{
-			efusefreenum= (UCHAR) (EFUSE_USAGE_MAP_END-i+1);
-			break;
-		}
-		else if(( (LogicalAddress >> 8) & 0xff) == 0)
-		{
-			efusefreenum = (UCHAR) (EFUSE_USAGE_MAP_END-i);
-			break;
-		}
-
-		if(i == EFUSE_USAGE_MAP_END)
-			efusefreenum = 0;
-	}
-	printk("efuseFreeNumber is %d\n",efusefreenum);
-	return TRUE;
-}
-INT set_eFusedump_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-USHORT InBuf[3];
-	INT i=0;
-	if(!pAd->bUseEfuse)
-		return FALSE;
-	for(i =0; i<EFUSE_USAGE_MAP_END/2; i++)
-	{
-		InBuf[0] = 2*i;
-		InBuf[1] = 2;
-		InBuf[2] = 0x0;
-
-		eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
-		if(i%4==0)
-		printk("\nBlock %x:",i/8);
-		printk("%04x ",InBuf[2]);
-	}
-	return TRUE;
-}
-INT	set_eFuseLoadFromBin_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	CHAR					*src;
-	struct file				*srcf;
-	INT 					retval;
-   	mm_segment_t			orgfs;
-	UCHAR					*buffer;
-	UCHAR					BinFileSize=0;
-	INT						i = 0,j=0,k=1;
-	USHORT					*PDATA;
-	USHORT					DATA;
-	BinFileSize=strlen("RT30xxEEPROM.bin");
-	src = kmalloc(128, MEM_ALLOC_FLAG);
-	NdisZeroMemory(src, 128);
-
- 	if(strlen(arg)>0)
-	{
-
-		NdisMoveMemory(src, arg, strlen(arg));
- 	}
-
-	else
-	{
-
-		NdisMoveMemory(src, "RT30xxEEPROM.bin", BinFileSize);
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src));
-	buffer = kmalloc(MAX_EEPROM_BIN_FILE_SIZE, MEM_ALLOC_FLAG);
-
-	if(buffer == NULL)
-	{
-		kfree(src);
-		 return FALSE;
-}
-	PDATA=kmalloc(sizeof(USHORT)*8,MEM_ALLOC_FLAG);
-
-	if(PDATA==NULL)
-	{
-		kfree(src);
-
-		kfree(buffer);
-		return FALSE;
-	}
-
-    	orgfs = get_fs();
-   	 set_fs(KERNEL_DS);
-
-	if (src && *src)
-	{
-		srcf = filp_open(src, O_RDONLY, 0);
-		if (IS_ERR(srcf))
-		{
-			DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
-			return FALSE;
-		}
-		else
-		{
-			// The object must have a read method
-			if (srcf->f_op && srcf->f_op->read)
-			{
-				memset(buffer, 0x00, MAX_EEPROM_BIN_FILE_SIZE);
-				while(srcf->f_op->read(srcf, &buffer[i], 1, &srcf->f_pos)==1)
-				{
-					DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[i]));
-					if((i+1)%8==0)
-						DBGPRINT(RT_DEBUG_TRACE, ("\n"));
-              			i++;
-						if(i>=MAX_EEPROM_BIN_FILE_SIZE)
-							{
-								DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld reading %s, The file is too large[1024]\n", -PTR_ERR(srcf),src));
-								kfree(PDATA);
-								kfree(buffer);
-								kfree(src);
-								return FALSE;
-							}
-			       }
-			}
-			else
-			{
-						DBGPRINT(RT_DEBUG_ERROR, ("--> Error!! System doest not support read function\n"));
-						kfree(PDATA);
-						kfree(buffer);
-						kfree(src);
-						return FALSE;
-			}
-      		}
-
-
-	}
-	else
-		{
-					DBGPRINT(RT_DEBUG_ERROR, ("--> Error src  or srcf is null\n"));
-					kfree(PDATA);
-					kfree(buffer);
-					return FALSE;
-
-		}
-
-
-	retval=filp_close(srcf,NULL);
-
-	if (retval)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
-	}
-	set_fs(orgfs);
-
-	for(j=0;j<i;j++)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[j]));
-		if((j+1)%2==0)
-			PDATA[j/2%8]=((buffer[j]<<8)&0xff00)|(buffer[j-1]&0xff);
-		if(j%16==0)
-		{
-			k=buffer[j];
-		}
-		else
-		{
-			k&=buffer[j];
-			if((j+1)%16==0)
-			{
-
-				DBGPRINT(RT_DEBUG_TRACE, (" result=%02X,blk=%02x\n",k,j/16));
-
-				if(k!=0xff)
-					eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
-				else
-					{
-						if(eFuseReadRegisters(pAd,j, 2,(PUSHORT)&DATA)!=0x3f)
-							eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
-					}
-				/*
-				for(l=0;l<8;l++)
-					printk("%04x ",PDATA[l]);
-				printk("\n");
-				*/
-				NdisZeroMemory(PDATA,16);
-
-
-			}
-		}
-
-
-	}
-
-
-	kfree(PDATA);
-	kfree(buffer);
-	kfree(src);
-	return TRUE;
-}
-NTSTATUS eFuseWriteRegistersFromBin(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	IN	USHORT* pData)
-{
-	USHORT	i;
-	USHORT	eFuseData;
-	USHORT	LogicalAddress, BlkNum = 0xffff;
-	UCHAR	EFSROM_AOUT,Loop=0;
-	EFUSE_CTRL_STRUC		eFuseCtrlStruc;
-	USHORT	efuseDataOffset;
-	UINT32	data,tempbuffer;
-	USHORT addr,tmpaddr, InBuf[3], tmpOffset;
-	UINT32 buffer[4];
-	BOOLEAN		bWriteSuccess = TRUE;
-	BOOLEAN		bNotWrite=TRUE;
-	BOOLEAN		bAllocateNewBlk=TRUE;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin Offset=%x, pData=%04x:%04x:%04x:%04x\n", Offset, *pData,*(pData+1),*(pData+2),*(pData+3)));
-
-	do
-	{
-	//Step 0. find the entry in the mapping table
-	//The address of EEPROM is 2-bytes alignment.
-	//The last bit is used for alignment, so it must be 0.
-	Loop++;
-	tmpOffset = Offset & 0xfffe;
-	EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
-
-	if( EFSROM_AOUT == 0x3f)
-	{	//find available logical address pointer
-		//the logical address does not exist, find an empty one
-		//from the first address of block 45=16*45=0x2d0 to the last address of block 47
-		//==>48*16-3(reserved)=2FC
-		bAllocateNewBlk=TRUE;
-		for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
-		{
-			//Retrive the logical block nubmer form each logical address pointer
-			//It will access two logical address pointer each time.
-			eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
-			if( (LogicalAddress & 0xff) == 0)
-			{//Not used logical address pointer
-				BlkNum = i-EFUSE_USAGE_MAP_START;
-				break;
-			}
-			else if(( (LogicalAddress >> 8) & 0xff) == 0)
-			{//Not used logical address pointer
-				if (i != EFUSE_USAGE_MAP_END)
-				{
-					BlkNum = i-EFUSE_USAGE_MAP_START+1;
-				}
-				break;
-			}
-		}
-	}
-	else
-	{
-		bAllocateNewBlk=FALSE;
-		BlkNum = EFSROM_AOUT;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
-
-	if(BlkNum == 0xffff)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
-		return FALSE;
-	}
-	//Step 1.1.0
-	//If the block is not existing in mapping table, create one
-	//and write down the 16-bytes data to the new block
-	if(bAllocateNewBlk)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk\n"));
-		efuseDataOffset =  EFUSE_DATA3;
-		for(i=0; i< 4; i++)
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk, Data%d=%04x%04x\n",3-i,pData[2*i+1],pData[2*i]));
-			tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
-
-
-			RTMP_IO_WRITE32(pAd, efuseDataOffset,tempbuffer);
-			efuseDataOffset -= 4;
-
-		}
-		/////////////////////////////////////////////////////////////////
-
-		//Step1.1.1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
-		eFuseCtrlStruc.field.EFSROM_AIN = BlkNum* 0x10 ;
-
-		//Step1.1.2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
-		eFuseCtrlStruc.field.EFSROM_MODE = 3;
-
-		//Step1.1.3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
-		eFuseCtrlStruc.field.EFSROM_KICK = 1;
-
-		NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
-
-		RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
-
-		//Step1.1.4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It��s done.
-		i = 0;
-		while(i < 100)
-		{
-			RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
-
-			if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
-				break;
-
-			RTMPusecDelay(2);
-			i++;
-		}
-
-	}
-	else
-	{	//Step1.2.
-		//If the same logical number is existing, check if the writting data and the data
-		//saving in this block are the same.
-		/////////////////////////////////////////////////////////////////
-		//read current values of 16-byte block
-		RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
-
-		//Step1.2.0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
-		eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
-
-		//Step1.2.1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
-		eFuseCtrlStruc.field.EFSROM_MODE = 0;
-
-		//Step1.2.2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
-		eFuseCtrlStruc.field.EFSROM_KICK = 1;
-
-		NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
-		RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
-
-		//Step1.2.3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
-		i = 0;
-		while(i < 100)
-		{
-			RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
-
-			if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
-				break;
-			RTMPusecDelay(2);
-			i++;
-		}
-
-		//Step1.2.4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
-		efuseDataOffset =  EFUSE_DATA3;
-		for(i=0; i< 4; i++)
-		{
-			RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &buffer[i]);
-			efuseDataOffset -=  4;
-		}
-		//Step1.2.5. Check if the data of efuse and the writing data are the same.
-		for(i =0; i<4; i++)
-		{
-			tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
-			DBGPRINT(RT_DEBUG_TRACE, ("buffer[%d]=%x,pData[%d]=%x,pData[%d]=%x,tempbuffer=%x\n",i,buffer[i],2*i,pData[2*i],2*i+1,pData[2*i+1],tempbuffer));
-
-			if(((buffer[i]&0xffff0000)==(pData[2*i+1]<<16))&&((buffer[i]&0xffff)==pData[2*i]))
-				bNotWrite&=TRUE;
-			else
-			{
-				bNotWrite&=FALSE;
-				break;
-			}
-		}
-		if(!bNotWrite)
-		{
-		printk("The data is not the same\n");
-
-			for(i =0; i<8; i++)
-			{
-				addr = BlkNum * 0x10 ;
-
-				InBuf[0] = addr+2*i;
-				InBuf[1] = 2;
-				InBuf[2] = pData[i];
-
-				eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
-			}
-
-		}
-		else
-			return TRUE;
-	     }
-
-
-
-		//Step 2. Write mapping table
-		addr = EFUSE_USAGE_MAP_START+BlkNum;
-
-		tmpaddr = addr;
-
-		if(addr % 2 != 0)
-			addr = addr -1;
-		InBuf[0] = addr;
-		InBuf[1] = 2;
-
-		//convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
-		tmpOffset = Offset;
-		tmpOffset >>= 4;
-		tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^  (tmpOffset >> 2 & 0x01) ^  (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
-		tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
-
-		// write the logical address
-		if(tmpaddr%2 != 0)
-			InBuf[2] = tmpOffset<<8;
-		else
-			InBuf[2] = tmpOffset;
-
-		eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
-
-		//Step 3. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
-		bWriteSuccess = TRUE;
-		for(i =0; i<8; i++)
-		{
-			addr = BlkNum * 0x10 ;
-
-			InBuf[0] = addr+2*i;
-			InBuf[1] = 2;
-			InBuf[2] = 0x0;
-
-			eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
-			DBGPRINT(RT_DEBUG_TRACE, ("addr=%x, buffer[i]=%x,InBuf[2]=%x\n",InBuf[0],pData[i],InBuf[2]));
-			if(pData[i] != InBuf[2])
-			{
-				bWriteSuccess = FALSE;
-				break;
-			}
-		}
-
-		//Step 4. invlidate mapping entry and find a free mapping entry if not succeed
-
-		if (!bWriteSuccess&&Loop<2)
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess BlkNum = %d\n", BlkNum));
-
-			// the offset of current mapping entry
-			addr = EFUSE_USAGE_MAP_START+BlkNum;
-
-			//find a new mapping entry
-			BlkNum = 0xffff;
-			for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
-			{
-				eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
-				if( (LogicalAddress & 0xff) == 0)
-				{
-					BlkNum = i-EFUSE_USAGE_MAP_START;
-					break;
-				}
-				else if(( (LogicalAddress >> 8) & 0xff) == 0)
-				{
-					if (i != EFUSE_USAGE_MAP_END)
-					{
-						BlkNum = i+1-EFUSE_USAGE_MAP_START;
-					}
-					break;
-				}
-			}
-			DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess new BlkNum = %d\n", BlkNum));
-			if(BlkNum == 0xffff)
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin: out of free E-fuse space!!!\n"));
-				return FALSE;
-			}
-
-			//invalidate the original mapping entry if new entry is not found
-			tmpaddr = addr;
-
-			if(addr % 2 != 0)
-				addr = addr -1;
-			InBuf[0] = addr;
-			InBuf[1] = 2;
-
-			eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
-
-			// write the logical address
-			if(tmpaddr%2 != 0)
-			{
-				// Invalidate the high byte
-				for (i=8; i<15; i++)
-				{
-					if( ( (InBuf[2] >> i) & 0x01) == 0)
-					{
-						InBuf[2] |= (0x1 <<i);
-						break;
-					}
-				}
-			}
-			else
-			{
-				// invalidate the low byte
-				for (i=0; i<8; i++)
-				{
-					if( ( (InBuf[2] >> i) & 0x01) == 0)
-					{
-						InBuf[2] |= (0x1 <<i);
-						break;
-					}
-				}
-			}
-			eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
-		}
-
-	}
-	while(!bWriteSuccess&&Loop<2);
-
-	return TRUE;
-}
-#endif
diff --git a/drivers/staging/rt2860/common/firmware.h b/drivers/staging/rt2860/common/firmware.h
index e72996f..2fecd32 100644
--- a/drivers/staging/rt2860/common/firmware.h
+++ b/drivers/staging/rt2860/common/firmware.h
@@ -43,7 +43,7 @@
 /* AUTO GEN PLEASE DO NOT MODIFY IT */
 
 
-UCHAR FirmwareImage [] = {
+u8 FirmwareImage_2860 [] = {
 0x02, 0x03, 0x5e, 0x02, 0x02, 0xb1, 0x22, 0x22, 0xff, 0xff, 0xff, 0x02, 0x01, 0x82, 0xff, 0xff,
 0xff, 0xff, 0xff, 0x02, 0x00, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x01, 0x33, 0xc0, 0xe0,
 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18, 0xc2, 0xaf, 0x30, 0x45, 0x03,
diff --git a/drivers/staging/rt2860/common/firmware_3070.h b/drivers/staging/rt2860/common/firmware_3070.h
new file mode 100644
index 0000000..b710d40
--- /dev/null
+++ b/drivers/staging/rt2860/common/firmware_3070.h
@@ -0,0 +1,517 @@
+/* AUTO GEN PLEASE DO NOT MODIFY IT */
+/* AUTO GEN PLEASE DO NOT MODIFY IT */
+
+
+u8 FirmwareImage_3070 [] = {
+0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x13, 0x1f, 0x02,
+0x13, 0x20, 0x02, 0x13, 0x3f, 0x02, 0x13, 0x44, 0x12, 0x13, 0x40, 0x22, 0x02, 0x17, 0xae, 0x02,
+0x18, 0xd2, 0x02, 0x14, 0x3d, 0x02, 0x13, 0x78, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x19,
+0x95, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40,
+0x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4,
+0x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4,
+0x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01,
+0x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xc8, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02,
+0x13, 0x1e, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0x9d, 0x10,
+0xd9, 0x31, 0x10, 0xbd, 0x36, 0x11, 0x02, 0x50, 0x11, 0x39, 0x51, 0x11, 0x42, 0x52, 0x11, 0x42,
+0x53, 0x11, 0x42, 0x54, 0x11, 0x83, 0x55, 0x11, 0xd2, 0x56, 0x12, 0x25, 0x70, 0x12, 0x50, 0x71,
+0x12, 0x7e, 0x72, 0x12, 0xd5, 0x73, 0x12, 0xf6, 0x80, 0x00, 0x00, 0x13, 0x1e, 0x90, 0x70, 0x11,
+0xe0, 0xf5, 0x3c, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe5, 0x56,
+0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d,
+0x02, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13,
+0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x85, 0x56, 0x41, 0xd2,
+0x02, 0x22, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff, 0xbf, 0x0a, 0x0d, 0x90, 0x70, 0x11, 0xe0,
+0xb4, 0x08, 0x06, 0x75, 0x4e, 0x01, 0x75, 0x4f, 0x84, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff,
+0xbf, 0x02, 0x12, 0x90, 0x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x04, 0xe0, 0xb4, 0x20, 0x06, 0x75,
+0x4e, 0x03, 0x75, 0x4f, 0x20, 0xe4, 0xf5, 0x27, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92,
+0x47, 0x22, 0x90, 0x04, 0x04, 0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0,
+0xff, 0x74, 0x47, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48,
+0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14,
+0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e,
+0x02, 0x13, 0x17, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x1d, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x17, 0xe5,
+0x47, 0x64, 0x09, 0x60, 0x11, 0xe5, 0x47, 0x64, 0x0a, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x0b, 0x60,
+0x05, 0xe5, 0x47, 0xb4, 0x0c, 0x08, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47,
+0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03, 0x03, 0xe4, 0xf5, 0x46, 0xe5, 0x47, 0xb4, 0x0a, 0x08,
+0xe5, 0x3a, 0xb4, 0x01, 0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0xd2,
+0x04, 0x22, 0x90, 0x70, 0x11, 0xe0, 0xf4, 0xff, 0x90, 0x70, 0x10, 0xe0, 0x5f, 0xff, 0x90, 0x70,
+0x11, 0xe0, 0x55, 0x27, 0x4f, 0x90, 0x70, 0x18, 0xf0, 0x90, 0x70, 0x11, 0xe0, 0x90, 0x70, 0x19,
+0xf0, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x30, 0x15, 0x03, 0xd2, 0x14, 0x22, 0x90, 0x70,
+0x18, 0xe0, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, 0x5e,
+0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x90,
+0x02, 0x28, 0xef, 0xf0, 0x22, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed,
+0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0,
+0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17,
+0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0,
+0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90,
+0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x90, 0x10,
+0x00, 0xe0, 0xf5, 0x57, 0x90, 0x10, 0x02, 0xe0, 0xf5, 0x58, 0xa3, 0xe0, 0xf5, 0x59, 0xe5, 0x58,
+0xb4, 0x70, 0x1e, 0xe5, 0x59, 0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd,
+0x90, 0x05, 0x05, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08,
+0xf0, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x3a, 0xff, 0x75, 0x3c, 0xff, 0xad, 0x57, 0xaf, 0x56,
+0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
+0xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf,
+0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
+0x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05,
+0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70,
+0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22,
+0xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2, 0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04,
+0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22,
+0xc2, 0x42, 0xd3, 0x22, 0x30, 0x14, 0x30, 0x90, 0x70, 0x19, 0xe0, 0x55, 0x27, 0xff, 0x90, 0x70,
+0x18, 0xe0, 0x4f, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef,
+0x5e, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff,
+0x90, 0x02, 0x28, 0xef, 0xf0, 0xc2, 0x14, 0x22, 0xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x0a,
+0x9d, 0x13, 0x9a, 0x00, 0x14, 0x28, 0x04, 0x14, 0x24, 0x08, 0x14, 0x04, 0x10, 0x13, 0xae, 0x20,
+0x13, 0xce, 0x60, 0x13, 0xdf, 0xa0, 0x00, 0x00, 0x14, 0x2a, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42,
+0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x14, 0x2a, 0x80, 0x1b, 0xe5, 0x48,
+0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54,
+0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x61, 0x53, 0x43, 0x0f, 0x80, 0x5c, 0x85, 0x49,
+0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4d, 0x80, 0x1b, 0xe5,
+0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4,
+0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x30, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10,
+0xf5, 0x43, 0x80, 0x26, 0xe5, 0x47, 0x64, 0x04, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43,
+0x5e, 0x04, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30,
+0xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4,
+0x54, 0xf0, 0xff, 0xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0xd2, 0x60, 0x22, 0xd2, 0x15, 0xe5,
+0x47, 0x24, 0xf5, 0x60, 0x0b, 0x24, 0xcb, 0x60, 0x07, 0x24, 0x40, 0x70, 0x06, 0xc2, 0x15, 0x22,
+0x12, 0x17, 0x79, 0x12, 0x14, 0x5f, 0xc2, 0x15, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2,
+0xaf, 0x90, 0x04, 0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45,
+0x4f, 0x24, 0xff, 0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74,
+0x1e, 0xf0, 0xe5, 0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5,
+0x5f, 0x20, 0xe5, 0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5,
+0x25, 0x70, 0x05, 0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f,
+0xe5, 0x5f, 0x30, 0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5,
+0x47, 0x64, 0x03, 0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25,
+0x70, 0x03, 0x30, 0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02,
+0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b,
+0xe5, 0x3a, 0x64, 0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0xe5,
+0x47, 0xb4, 0x0a, 0x13, 0xe5, 0x3a, 0xb4, 0x01, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x08, 0xe5,
+0x3a, 0x70, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2,
+0x68, 0x20, 0x6b, 0x07, 0xe5, 0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e,
+0x20, 0xe2, 0x02, 0xb2, 0x6c, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26, 0x30,
+0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80,
+0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e,
+0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x26,
+0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01,
+0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02,
+0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80,
+0x26, 0xe5, 0x47, 0x64, 0x0a, 0x70, 0x22, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x17,
+0xe5, 0x3a, 0xb4, 0x01, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x34, 0xe5, 0x46, 0x20, 0xe4, 0x03,
+0x30, 0xe5, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2,
+0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54,
+0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92,
+0x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3,
+0x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92, 0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13,
+0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2, 0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47,
+0x64, 0x06, 0x70, 0x39, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f,
+0x14, 0x60, 0x0c, 0x24, 0xfe, 0x60, 0x0c, 0x24, 0x03, 0x70, 0x13, 0xc2, 0x38, 0x80, 0x0f, 0xd2,
+0x38, 0x80, 0x0b, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x38, 0x30, 0x47,
+0x05, 0xaf, 0x27, 0x02, 0x17, 0x73, 0xe5, 0x27, 0xf4, 0xff, 0x02, 0x17, 0x73, 0xe5, 0x47, 0x64,
+0x07, 0x60, 0x0f, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02,
+0x16, 0xf2, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x22, 0x14, 0x60,
+0x25, 0x14, 0x60, 0x2d, 0x24, 0xfc, 0x60, 0x49, 0x24, 0xf9, 0x60, 0x14, 0x24, 0x0e, 0x70, 0x50,
+0xe5, 0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x24, 0xff, 0x80, 0x3a,
+0xd2, 0x39, 0xc2, 0x38, 0x80, 0x3e, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x1d, 0xc3, 0x80,
+0x1a, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f,
+0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x38, 0xc2, 0x39, 0x80,
+0x13, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0xc2, 0x38, 0x80, 0x04,
+0xc2, 0x38, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x02,
+0x17, 0x73, 0xe5, 0x47, 0x64, 0x0c, 0x60, 0x06, 0xe5, 0x47, 0x64, 0x0b, 0x70, 0x7a, 0x90, 0x02,
+0x29, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x20, 0x14, 0x60, 0x21, 0x14, 0x60, 0x2b,
+0x24, 0xfc, 0x60, 0x45, 0x24, 0xf9, 0x60, 0x12, 0x24, 0x0e, 0x70, 0x4a, 0xe5, 0x46, 0x13, 0x13,
+0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x80, 0x29, 0xd2, 0x39, 0x80, 0x3a, 0xe5, 0x46,
+0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0x80, 0x2d, 0xe5, 0x46, 0x30, 0xe2, 0x0d,
+0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f,
+0x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x39, 0x80, 0x0f, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80,
+0x01, 0xc3, 0x92, 0x39, 0x80, 0x02, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5,
+0x27, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0xe5, 0x47, 0xb4, 0x0b, 0x10, 0x90, 0x02,
+0x29, 0xe0, 0x54, 0xeb, 0xf0, 0xe5, 0x27, 0x54, 0xeb, 0x45, 0x45, 0xf5, 0x27, 0x22, 0xe4, 0x90,
+0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02,
+0x28, 0xef, 0xf0, 0x22, 0x8f, 0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5,
+0x62, 0xc2, 0xaf, 0xe5, 0x51, 0x14, 0x60, 0x48, 0x14, 0x60, 0x66, 0x24, 0x02, 0x60, 0x03, 0x02,
+0x18, 0xb6, 0xd2, 0x59, 0x75, 0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0,
+0x20, 0xe7, 0x23, 0x90, 0x04, 0x34, 0xe0, 0xb4, 0x02, 0x1c, 0xa3, 0xe0, 0xb4, 0x02, 0x17, 0xa3,
+0xe0, 0xb4, 0x02, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0,
+0x75, 0x51, 0x01, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x06, 0x75, 0x62, 0x03, 0x02, 0x18, 0xb6,
+0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x02, 0xa2,
+0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x03, 0x02, 0x18,
+0xb1, 0x90, 0x02, 0xa3, 0xe0, 0x30, 0xe6, 0x03, 0x02, 0x18, 0xad, 0x90, 0x04, 0x37, 0xe0, 0x64,
+0x22, 0x70, 0x7a, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96, 0xf0, 0x90, 0x12, 0x04,
+0x74, 0x0a, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x15, 0xe5, 0x59, 0xb4, 0x35, 0x10, 0xe4, 0x90, 0x05,
+0x00, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0x7f, 0x01, 0x12,
+0x0d, 0x2a, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xf0, 0xf0, 0xe5, 0x59,
+0xb4, 0x35, 0x14, 0xe5, 0x3c, 0xf4, 0x60, 0x06, 0xa3, 0xe0, 0x54, 0xf3, 0x80, 0x14, 0x90, 0x13,
+0x2a, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x14, 0xe5, 0x3c, 0xf4, 0x90, 0x13, 0x2a, 0x60, 0x08, 0xe0,
+0x54, 0xf2, 0x45, 0x3c, 0xf0, 0x80, 0x04, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54,
+0xfd, 0xf0, 0x75, 0x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70,
+0x05, 0x75, 0x62, 0x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2,
+0x59, 0xad, 0x62, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2,
+0xaf, 0x22, 0xc2, 0xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59,
+0xc2, 0x01, 0x7d, 0x02, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70,
+0x6d, 0x75, 0x52, 0x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13,
+0x28, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90,
+0x12, 0x04, 0x74, 0x03, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x16, 0xe5, 0x59, 0xb4, 0x35, 0x11, 0x90,
+0x05, 0x00, 0x74, 0xe2, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0,
+0x7f, 0x01, 0x12, 0x0d, 0x2a, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0,
+0x44, 0x0c, 0xf0, 0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x09, 0xc2, 0x02, 0x7d, 0x01, 0xaf,
+0x41, 0x12, 0x19, 0x61, 0x30, 0x03, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf,
+0x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5,
+0x83, 0xe0, 0xb4, 0xff, 0x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef,
+0xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe,
+0x04, 0xd5, 0x22, 0x22, 0x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70,
+0x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70,
+0x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0,
+0x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90,
+0x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70,
+0x24, 0xe0, 0x44, 0x01, 0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x7b, 0xc4,
+0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x13, 0x1f, 0x02,
+0x13, 0x20, 0x02, 0x13, 0x3f, 0x02, 0x13, 0x44, 0x12, 0x13, 0x40, 0x22, 0x02, 0x17, 0xae, 0x02,
+0x18, 0xd2, 0x02, 0x14, 0x3d, 0x02, 0x13, 0x78, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x19,
+0x95, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40,
+0x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4,
+0x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4,
+0x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01,
+0x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xdd, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02,
+0x13, 0x1e, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0xb6, 0x10,
+0xd9, 0x31, 0x10, 0xbd, 0x36, 0x11, 0x02, 0x50, 0x11, 0x39, 0x51, 0x11, 0x42, 0x52, 0x11, 0x42,
+0x53, 0x11, 0x42, 0x54, 0x11, 0x83, 0x55, 0x11, 0xd2, 0x56, 0x12, 0x25, 0x70, 0x12, 0x50, 0x71,
+0x12, 0x7e, 0x72, 0x12, 0xd5, 0x73, 0x12, 0xf6, 0x80, 0x00, 0x00, 0x13, 0x1e, 0x90, 0x70, 0x11,
+0xe0, 0xf5, 0x3c, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe5, 0x56,
+0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d,
+0x02, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13,
+0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x85, 0x56, 0x41, 0xd2,
+0x02, 0x22, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff, 0xbf, 0x0a, 0x0d, 0x90, 0x70, 0x11, 0xe0,
+0xb4, 0x08, 0x06, 0x75, 0x4e, 0x01, 0x75, 0x4f, 0x84, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff,
+0xbf, 0x02, 0x12, 0x90, 0x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x04, 0xe0, 0xb4, 0x20, 0x06, 0x75,
+0x4e, 0x03, 0x75, 0x4f, 0x20, 0xe4, 0xf5, 0x27, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92,
+0x47, 0x22, 0x90, 0x04, 0x04, 0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0,
+0xff, 0x74, 0x47, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48,
+0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14,
+0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e,
+0x02, 0x13, 0x17, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x1d, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x17, 0xe5,
+0x47, 0x64, 0x09, 0x60, 0x11, 0xe5, 0x47, 0x64, 0x0a, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x0b, 0x60,
+0x05, 0xe5, 0x47, 0xb4, 0x0c, 0x08, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47,
+0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03, 0x03, 0xe4, 0xf5, 0x46, 0xe5, 0x47, 0xb4, 0x0a, 0x08,
+0xe5, 0x3a, 0xb4, 0x01, 0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0xd2,
+0x04, 0x22, 0x90, 0x70, 0x11, 0xe0, 0xf4, 0xff, 0x90, 0x70, 0x10, 0xe0, 0x5f, 0xff, 0x90, 0x70,
+0x11, 0xe0, 0x55, 0x27, 0x4f, 0x90, 0x70, 0x18, 0xf0, 0x90, 0x70, 0x11, 0xe0, 0x90, 0x70, 0x19,
+0xf0, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x30, 0x15, 0x03, 0xd2, 0x14, 0x22, 0x90, 0x70,
+0x18, 0xe0, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, 0x5e,
+0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x90,
+0x02, 0x28, 0xef, 0xf0, 0x22, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed,
+0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0,
+0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17,
+0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0,
+0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90,
+0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x90, 0x10,
+0x00, 0xe0, 0xf5, 0x57, 0x90, 0x10, 0x02, 0xe0, 0xf5, 0x58, 0xa3, 0xe0, 0xf5, 0x59, 0xe5, 0x58,
+0xb4, 0x70, 0x1e, 0xe5, 0x59, 0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd,
+0x90, 0x05, 0x05, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08,
+0xf0, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x3a, 0xff, 0x75, 0x3c, 0xff, 0xad, 0x57, 0xaf, 0x56,
+0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
+0xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf,
+0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
+0x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05,
+0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70,
+0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22,
+0xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2, 0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04,
+0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22,
+0xc2, 0x42, 0xd3, 0x22, 0x30, 0x14, 0x30, 0x90, 0x70, 0x19, 0xe0, 0x55, 0x27, 0xff, 0x90, 0x70,
+0x18, 0xe0, 0x4f, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef,
+0x5e, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff,
+0x90, 0x02, 0x28, 0xef, 0xf0, 0xc2, 0x14, 0x22, 0xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x0a,
+0xb6, 0x13, 0x9a, 0x00, 0x14, 0x28, 0x04, 0x14, 0x24, 0x08, 0x14, 0x04, 0x10, 0x13, 0xae, 0x20,
+0x13, 0xce, 0x60, 0x13, 0xdf, 0xa0, 0x00, 0x00, 0x14, 0x2a, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42,
+0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x14, 0x2a, 0x80, 0x1b, 0xe5, 0x48,
+0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54,
+0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x61, 0x53, 0x43, 0x0f, 0x80, 0x5c, 0x85, 0x49,
+0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4d, 0x80, 0x1b, 0xe5,
+0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4,
+0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x30, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10,
+0xf5, 0x43, 0x80, 0x26, 0xe5, 0x47, 0x64, 0x04, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43,
+0x5e, 0x04, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30,
+0xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4,
+0x54, 0xf0, 0xff, 0xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0xd2, 0x60, 0x22, 0xd2, 0x15, 0xe5,
+0x47, 0x24, 0xf5, 0x60, 0x0b, 0x24, 0xcb, 0x60, 0x07, 0x24, 0x40, 0x70, 0x06, 0xc2, 0x15, 0x22,
+0x12, 0x17, 0x79, 0x12, 0x14, 0x5f, 0xc2, 0x15, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2,
+0xaf, 0x90, 0x04, 0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45,
+0x4f, 0x24, 0xff, 0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74,
+0x1e, 0xf0, 0xe5, 0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5,
+0x5f, 0x20, 0xe5, 0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5,
+0x25, 0x70, 0x05, 0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f,
+0xe5, 0x5f, 0x30, 0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5,
+0x47, 0x64, 0x03, 0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25,
+0x70, 0x03, 0x30, 0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02,
+0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b,
+0xe5, 0x3a, 0x64, 0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0xe5,
+0x47, 0xb4, 0x0a, 0x13, 0xe5, 0x3a, 0xb4, 0x01, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x08, 0xe5,
+0x3a, 0x70, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2,
+0x68, 0x20, 0x6b, 0x07, 0xe5, 0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e,
+0x20, 0xe2, 0x02, 0xb2, 0x6c, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26, 0x30,
+0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80,
+0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e,
+0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x26,
+0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01,
+0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02,
+0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80,
+0x26, 0xe5, 0x47, 0x64, 0x0a, 0x70, 0x22, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x17,
+0xe5, 0x3a, 0xb4, 0x01, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x34, 0xe5, 0x46, 0x20, 0xe4, 0x03,
+0x30, 0xe5, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2,
+0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54,
+0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92,
+0x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3,
+0x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92, 0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13,
+0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2, 0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47,
+0x64, 0x06, 0x70, 0x39, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f,
+0x14, 0x60, 0x0c, 0x24, 0xfe, 0x60, 0x0c, 0x24, 0x03, 0x70, 0x13, 0xc2, 0x38, 0x80, 0x0f, 0xd2,
+0x38, 0x80, 0x0b, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x38, 0x30, 0x47,
+0x05, 0xaf, 0x27, 0x02, 0x17, 0x73, 0xe5, 0x27, 0xf4, 0xff, 0x02, 0x17, 0x73, 0xe5, 0x47, 0x64,
+0x07, 0x60, 0x0f, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02,
+0x16, 0xf2, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x22, 0x14, 0x60,
+0x25, 0x14, 0x60, 0x2d, 0x24, 0xfc, 0x60, 0x49, 0x24, 0xf9, 0x60, 0x14, 0x24, 0x0e, 0x70, 0x50,
+0xe5, 0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x24, 0xff, 0x80, 0x3a,
+0xd2, 0x39, 0xc2, 0x38, 0x80, 0x3e, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x1d, 0xc3, 0x80,
+0x1a, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f,
+0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x38, 0xc2, 0x39, 0x80,
+0x13, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0xc2, 0x38, 0x80, 0x04,
+0xc2, 0x38, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x02,
+0x17, 0x73, 0xe5, 0x47, 0x64, 0x0c, 0x60, 0x06, 0xe5, 0x47, 0x64, 0x0b, 0x70, 0x7a, 0x90, 0x02,
+0x29, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x20, 0x14, 0x60, 0x21, 0x14, 0x60, 0x2b,
+0x24, 0xfc, 0x60, 0x45, 0x24, 0xf9, 0x60, 0x12, 0x24, 0x0e, 0x70, 0x4a, 0xe5, 0x46, 0x13, 0x13,
+0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x80, 0x29, 0xd2, 0x39, 0x80, 0x3a, 0xe5, 0x46,
+0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0x80, 0x2d, 0xe5, 0x46, 0x30, 0xe2, 0x0d,
+0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f,
+0x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x39, 0x80, 0x0f, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80,
+0x01, 0xc3, 0x92, 0x39, 0x80, 0x02, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5,
+0x27, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0xe5, 0x47, 0xb4, 0x0b, 0x10, 0x90, 0x02,
+0x29, 0xe0, 0x54, 0xeb, 0xf0, 0xe5, 0x27, 0x54, 0xeb, 0x45, 0x45, 0xf5, 0x27, 0x22, 0xe4, 0x90,
+0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02,
+0x28, 0xef, 0xf0, 0x22, 0x8f, 0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5,
+0x62, 0xc2, 0xaf, 0xe5, 0x51, 0x14, 0x60, 0x48, 0x14, 0x60, 0x66, 0x24, 0x02, 0x60, 0x03, 0x02,
+0x18, 0xb6, 0xd2, 0x59, 0x75, 0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0,
+0x20, 0xe7, 0x23, 0x90, 0x04, 0x34, 0xe0, 0xb4, 0x02, 0x1c, 0xa3, 0xe0, 0xb4, 0x02, 0x17, 0xa3,
+0xe0, 0xb4, 0x02, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0,
+0x75, 0x51, 0x01, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x06, 0x75, 0x62, 0x03, 0x02, 0x18, 0xb6,
+0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x02, 0xa2,
+0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x03, 0x02, 0x18,
+0xb1, 0x90, 0x02, 0xa3, 0xe0, 0x30, 0xe6, 0x03, 0x02, 0x18, 0xad, 0x90, 0x04, 0x37, 0xe0, 0x64,
+0x22, 0x70, 0x7a, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96, 0xf0, 0x90, 0x12, 0x04,
+0x74, 0x0a, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x15, 0xe5, 0x59, 0xb4, 0x35, 0x10, 0xe4, 0x90, 0x05,
+0x00, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0x7f, 0x01, 0x12,
+0x0d, 0x48, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xf0, 0xf0, 0xe5, 0x59,
+0xb4, 0x35, 0x14, 0xe5, 0x3c, 0xf4, 0x60, 0x06, 0xa3, 0xe0, 0x54, 0xf3, 0x80, 0x14, 0x90, 0x13,
+0x2a, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x14, 0xe5, 0x3c, 0xf4, 0x90, 0x13, 0x2a, 0x60, 0x08, 0xe0,
+0x54, 0xf2, 0x45, 0x3c, 0xf0, 0x80, 0x04, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54,
+0xfd, 0xf0, 0x75, 0x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70,
+0x05, 0x75, 0x62, 0x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2,
+0x59, 0xad, 0x62, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2,
+0xaf, 0x22, 0xc2, 0xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59,
+0xc2, 0x01, 0x7d, 0x02, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70,
+0x6d, 0x75, 0x52, 0x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13,
+0x28, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90,
+0x12, 0x04, 0x74, 0x03, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x16, 0xe5, 0x59, 0xb4, 0x35, 0x11, 0x90,
+0x05, 0x00, 0x74, 0xe2, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0,
+0x7f, 0x01, 0x12, 0x0d, 0x48, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0,
+0x44, 0x0c, 0xf0, 0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x09, 0xc2, 0x02, 0x7d, 0x01, 0xaf,
+0x41, 0x12, 0x19, 0x61, 0x30, 0x03, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf,
+0x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5,
+0x83, 0xe0, 0xb4, 0xff, 0x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef,
+0xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe,
+0x04, 0xd5, 0x22, 0x22, 0x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70,
+0x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70,
+0x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0,
+0x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90,
+0x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70,
+0x24, 0xe0, 0x44, 0x01, 0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x65, 0xd3, } ;
diff --git a/drivers/staging/rt2860/common/md5.c b/drivers/staging/rt2860/common/md5.c
deleted file mode 100644
index ad883ca..0000000
--- a/drivers/staging/rt2860/common/md5.c
+++ /dev/null
@@ -1,1415 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    md5.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Name		Date			Modification logs
-	jan			10-28-03		Initial
-	Rita    	11-23-04		Modify MD5 and SHA-1
-	Rita		10-14-05		Modify SHA-1 in big-endian platform
- */
-#include "../rt_config.h"
-
-/**
- * md5_mac:
- * @key: pointer to	the	key	used for MAC generation
- * @key_len: length	of the key in bytes
- * @data: pointer to the data area for which the MAC is	generated
- * @data_len: length of	the	data in	bytes
- * @mac: pointer to	the	buffer holding space for the MAC; the buffer should
- * have	space for 128-bit (16 bytes) MD5 hash value
- *
- * md5_mac() determines	the	message	authentication code	by using secure	hash
- * MD5(key | data |	key).
- */
-void md5_mac(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac)
-{
-	MD5_CTX	context;
-
-	MD5Init(&context);
-	MD5Update(&context,	key, key_len);
-	MD5Update(&context,	data, data_len);
-	MD5Update(&context,	key, key_len);
-	MD5Final(mac, &context);
-}
-
-/**
- * hmac_md5:
- * @key: pointer to	the	key	used for MAC generation
- * @key_len: length	of the key in bytes
- * @data: pointer to the data area for which the MAC is	generated
- * @data_len: length of	the	data in	bytes
- * @mac: pointer to	the	buffer holding space for the MAC; the buffer should
- * have	space for 128-bit (16 bytes) MD5 hash value
- *
- * hmac_md5() determines the message authentication	code using HMAC-MD5.
- * This	implementation is based	on the sample code presented in	RFC	2104.
- */
-void hmac_md5(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac)
-{
-	MD5_CTX	context;
-    u8 k_ipad[65]; /* inner padding - key XORd with ipad */
-    u8 k_opad[65]; /* outer padding - key XORd with opad */
-    u8 tk[16];
-	int	i;
-
-	//assert(key != NULL && data != NULL && mac != NULL);
-
-	/* if key is longer	than 64	bytes reset	it to key =	MD5(key) */
-	if (key_len	> 64) {
-		MD5_CTX	ttcontext;
-
-		MD5Init(&ttcontext);
-		MD5Update(&ttcontext, key, key_len);
-		MD5Final(tk, &ttcontext);
-		//key=(PUCHAR)ttcontext.buf;
-		key	= tk;
-		key_len	= 16;
-	}
-
-	/* the HMAC_MD5	transform looks	like:
-	 *
-	 * MD5(K XOR opad, MD5(K XOR ipad, text))
-	 *
-	 * where K is an n byte	key
-	 * ipad	is the byte	0x36 repeated 64 times
-	 * opad	is the byte	0x5c repeated 64 times
-	 * and text	is the data	being protected	*/
-
-	/* start out by	storing	key	in pads	*/
-	NdisZeroMemory(k_ipad, sizeof(k_ipad));
-	NdisZeroMemory(k_opad,	sizeof(k_opad));
-	//assert(key_len < sizeof(k_ipad));
-	NdisMoveMemory(k_ipad, key,	key_len);
-	NdisMoveMemory(k_opad, key,	key_len);
-
-	/* XOR key with	ipad and opad values */
-	for	(i = 0;	i <	64;	i++) {
-		k_ipad[i] ^= 0x36;
-		k_opad[i] ^= 0x5c;
-	}
-
-	/* perform inner MD5 */
-	MD5Init(&context);					 /*	init context for 1st pass */
-	MD5Update(&context,	k_ipad,	64);	 /*	start with inner pad */
-	MD5Update(&context,	data, data_len); /*	then text of datagram */
-	MD5Final(mac, &context);			 /*	finish up 1st pass */
-
-	/* perform outer MD5 */
-	MD5Init(&context);					 /*	init context for 2nd pass */
-	MD5Update(&context,	k_opad,	64);	 /*	start with outer pad */
-	MD5Update(&context,	mac, 16);		 /*	then results of	1st	hash */
-	MD5Final(mac, &context);			 /*	finish up 2nd pass */
-}
-
-#define byteReverse(buf, len)   /* Nothing */
-
-/* ==========================  MD5 implementation =========================== */
-// four base functions for MD5
-#define MD5_F1(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define MD5_F2(x, y, z) (((x) & (z)) | ((y) & (~z)))
-#define MD5_F3(x, y, z) ((x) ^ (y) ^ (z))
-#define MD5_F4(x, y, z) ((y) ^ ((x) | (~z)))
-#define CYCLIC_LEFT_SHIFT(w, s) (((w) << (s)) | ((w) >> (32-(s))))
-
-#define	MD5Step(f, w, x, y,	z, data, t, s)	\
-	( w	+= f(x,	y, z) +	data + t,  w = (CYCLIC_LEFT_SHIFT(w, s)) & 0xffffffff, w +=	x )
-
-
-/*
- *  Function Description:
- *      Initiate MD5 Context satisfied in RFC 1321
- *
- *  Arguments:
- *      pCtx        Pointer	to MD5 context
- *
- *  Return Value:
- *      None
- */
-VOID MD5Init(MD5_CTX *pCtx)
-{
-    pCtx->Buf[0]=0x67452301;
-    pCtx->Buf[1]=0xefcdab89;
-    pCtx->Buf[2]=0x98badcfe;
-    pCtx->Buf[3]=0x10325476;
-
-    pCtx->LenInBitCount[0]=0;
-    pCtx->LenInBitCount[1]=0;
-}
-
-
-/*
- *  Function Description:
- *      Update MD5 Context, allow of an arrary of octets as the next portion
- *      of the message
- *
- *  Arguments:
- *      pCtx		Pointer	to MD5 context
- * 	    pData       Pointer to input data
- *      LenInBytes  The length of input data (unit: byte)
- *
- *  Return Value:
- *      None
- *
- *  Note:
- *      Called after MD5Init or MD5Update(itself)
- */
-VOID MD5Update(MD5_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes)
-{
-
-    UINT32 TfTimes;
-    UINT32 temp;
-	unsigned int i;
-
-    temp = pCtx->LenInBitCount[0];
-
-    pCtx->LenInBitCount[0] = (UINT32) (pCtx->LenInBitCount[0] + (LenInBytes << 3));
-
-    if (pCtx->LenInBitCount[0] < temp)
-        pCtx->LenInBitCount[1]++;   //carry in
-
-    pCtx->LenInBitCount[1] += LenInBytes >> 29;
-
-    // mod 64 bytes
-    temp = (temp >> 3) & 0x3f;
-
-    // process lacks of 64-byte data
-    if (temp)
-    {
-        UCHAR *pAds = (UCHAR *) pCtx->Input + temp;
-
-        if ((temp+LenInBytes) < 64)
-        {
-            NdisMoveMemory(pAds, (UCHAR *)pData, LenInBytes);
-            return;
-        }
-
-        NdisMoveMemory(pAds, (UCHAR *)pData, 64-temp);
-        byteReverse(pCtx->Input, 16);
-        MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
-
-        pData += 64-temp;
-        LenInBytes -= 64-temp;
-    } // end of if (temp)
-
-
-    TfTimes = (LenInBytes >> 6);
-
-    for (i=TfTimes; i>0; i--)
-    {
-        NdisMoveMemory(pCtx->Input, (UCHAR *)pData, 64);
-        byteReverse(pCtx->Input, 16);
-        MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
-        pData += 64;
-        LenInBytes -= 64;
-    } // end of for
-
-    // buffering lacks of 64-byte data
-    if(LenInBytes)
-        NdisMoveMemory(pCtx->Input, (UCHAR *)pData, LenInBytes);
-
-}
-
-
-/*
- *  Function Description:
- *      Append padding bits and length of original message in the tail
- *      The message digest has to be completed in the end
- *
- *  Arguments:
- *      Digest		Output of Digest-Message for MD5
- *  	pCtx        Pointer	to MD5 context
- *
- *  Return Value:
- *      None
- *
- *  Note:
- *      Called after MD5Update
- */
-VOID MD5Final(UCHAR Digest[16], MD5_CTX *pCtx)
-{
-    UCHAR Remainder;
-    UCHAR PadLenInBytes;
-    UCHAR *pAppend=0;
-    unsigned int i;
-
-    Remainder = (UCHAR)((pCtx->LenInBitCount[0] >> 3) & 0x3f);
-
-    PadLenInBytes = (Remainder < 56) ? (56-Remainder) : (120-Remainder);
-
-    pAppend = (UCHAR *)pCtx->Input + Remainder;
-
-    // padding bits without crossing block(64-byte based) boundary
-    if (Remainder < 56)
-    {
-        *pAppend = 0x80;
-        PadLenInBytes --;
-
-        NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, PadLenInBytes);
-
-		// add data-length field, from low to high
-       	for (i=0; i<4; i++)
-        {
-        	pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[0] >> (i << 3)) & 0xff);
-        	pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[1] >> (i << 3)) & 0xff);
-      	}
-
-        byteReverse(pCtx->Input, 16);
-        MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
-    } // end of if
-
-    // padding bits with crossing block(64-byte based) boundary
-    else
-    {
-        // the first block ===
-        *pAppend = 0x80;
-        PadLenInBytes --;
-
-        NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, (64-Remainder-1));
-        PadLenInBytes -= (64 - Remainder - 1);
-
-        byteReverse(pCtx->Input, 16);
-        MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
-
-
-        // the second block ===
-        NdisZeroMemory((UCHAR *)pCtx->Input, PadLenInBytes);
-
-        // add data-length field
-        for (i=0; i<4; i++)
-        {
-        	pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[0] >> (i << 3)) & 0xff);
-        	pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[1] >> (i << 3)) & 0xff);
-      	}
-
-        byteReverse(pCtx->Input, 16);
-        MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
-    } // end of else
-
-
-    NdisMoveMemory((UCHAR *)Digest, (UINT32 *)pCtx->Buf, 16); // output
-    byteReverse((UCHAR *)Digest, 4);
-    NdisZeroMemory(pCtx, sizeof(pCtx)); // memory free
-}
-
-
-/*
- *  Function Description:
- *      The central algorithm of MD5, consists of four rounds and sixteen
- *  	steps per round
- *
- *  Arguments:
- *      Buf     Buffers of four states (output: 16 bytes)
- * 	    Mes     Input data (input: 64 bytes)
- *
- *  Return Value:
- *      None
- *
- *  Note:
- *      Called by MD5Update or MD5Final
- */
-VOID MD5Transform(UINT32 Buf[4], UINT32 Mes[16])
-{
-    UINT32 Reg[4], Temp;
-	unsigned int i;
-
-    static UCHAR LShiftVal[16] =
-    {
-        7, 12, 17, 22,
-		5, 9 , 14, 20,
-		4, 11, 16, 23,
- 		6, 10, 15, 21,
- 	};
-
-
-	// [equal to 4294967296*abs(sin(index))]
-    static UINT32 MD5Table[64] =
-	{
-		0xd76aa478,	0xe8c7b756,	0x242070db,	0xc1bdceee,
-		0xf57c0faf,	0x4787c62a,	0xa8304613, 0xfd469501,
-		0x698098d8,	0x8b44f7af,	0xffff5bb1,	0x895cd7be,
-    	0x6b901122,	0xfd987193,	0xa679438e,	0x49b40821,
-
-    	0xf61e2562,	0xc040b340,	0x265e5a51,	0xe9b6c7aa,
-    	0xd62f105d,	0x02441453,	0xd8a1e681,	0xe7d3fbc8,
-    	0x21e1cde6,	0xc33707d6,	0xf4d50d87,	0x455a14ed,
-    	0xa9e3e905,	0xfcefa3f8,	0x676f02d9,	0x8d2a4c8a,
-
-    	0xfffa3942,	0x8771f681,	0x6d9d6122,	0xfde5380c,
-    	0xa4beea44,	0x4bdecfa9,	0xf6bb4b60,	0xbebfbc70,
-    	0x289b7ec6,	0xeaa127fa,	0xd4ef3085,	0x04881d05,
-    	0xd9d4d039,	0xe6db99e5,	0x1fa27cf8,	0xc4ac5665,
-
-    	0xf4292244,	0x432aff97,	0xab9423a7,	0xfc93a039,
-   		0x655b59c3,	0x8f0ccc92,	0xffeff47d,	0x85845dd1,
-    	0x6fa87e4f,	0xfe2ce6e0,	0xa3014314,	0x4e0811a1,
-    	0xf7537e82,	0xbd3af235,	0x2ad7d2bb,	0xeb86d391
-	};
-
-
-    for (i=0; i<4; i++)
-        Reg[i]=Buf[i];
-
-
-    // 64 steps in MD5 algorithm
-    for (i=0; i<16; i++)
-    {
-        MD5Step(MD5_F1, Reg[0], Reg[1], Reg[2], Reg[3], Mes[i],
-                MD5Table[i], LShiftVal[i & 0x3]);
-
-        // one-word right shift
-        Temp   = Reg[3];
-        Reg[3] = Reg[2];
-        Reg[2] = Reg[1];
-        Reg[1] = Reg[0];
-        Reg[0] = Temp;
-    }
-    for (i=16; i<32; i++)
-    {
-        MD5Step(MD5_F2, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(5*(i & 0xf)+1) & 0xf],
-                MD5Table[i], LShiftVal[(0x1 << 2)+(i & 0x3)]);
-
-        // one-word right shift
-        Temp   = Reg[3];
-        Reg[3] = Reg[2];
-        Reg[2] = Reg[1];
-        Reg[1] = Reg[0];
-        Reg[0] = Temp;
-    }
-    for (i=32; i<48; i++)
-    {
-        MD5Step(MD5_F3, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(3*(i & 0xf)+5) & 0xf],
-                MD5Table[i], LShiftVal[(0x1 << 3)+(i & 0x3)]);
-
-        // one-word right shift
-        Temp   = Reg[3];
-        Reg[3] = Reg[2];
-        Reg[2] = Reg[1];
-        Reg[1] = Reg[0];
-        Reg[0] = Temp;
-    }
-    for (i=48; i<64; i++)
-    {
-        MD5Step(MD5_F4, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(7*(i & 0xf)) & 0xf],
-                MD5Table[i], LShiftVal[(0x3 << 2)+(i & 0x3)]);
-
-        // one-word right shift
-        Temp   = Reg[3];
-        Reg[3] = Reg[2];
-        Reg[2] = Reg[1];
-        Reg[1] = Reg[0];
-        Reg[0] = Temp;
-    }
-
-
-    // (temporary)output
-    for (i=0; i<4; i++)
-        Buf[i] += Reg[i];
-
-}
-
-
-
-/* =========================  SHA-1 implementation ========================== */
-// four base functions for SHA-1
-#define SHA1_F1(b, c, d)    (((b) & (c)) | ((~b) & (d)))
-#define SHA1_F2(b, c, d)    ((b) ^ (c) ^ (d))
-#define SHA1_F3(b, c, d)    (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
-
-
-#define SHA1Step(f, a, b, c, d, e, w, k)    \
-    ( e	+= ( f(b, c, d) + w + k + CYCLIC_LEFT_SHIFT(a, 5)) & 0xffffffff, \
-      b = CYCLIC_LEFT_SHIFT(b, 30) )
-
-//Initiate SHA-1 Context satisfied in RFC 3174
-VOID SHAInit(SHA_CTX *pCtx)
-{
-    pCtx->Buf[0]=0x67452301;
-    pCtx->Buf[1]=0xefcdab89;
-    pCtx->Buf[2]=0x98badcfe;
-    pCtx->Buf[3]=0x10325476;
-    pCtx->Buf[4]=0xc3d2e1f0;
-
-    pCtx->LenInBitCount[0]=0;
-    pCtx->LenInBitCount[1]=0;
-}
-
-/*
- *  Function Description:
- *      Update SHA-1 Context, allow of an arrary of octets as the next
- *      portion of the message
- *
- *  Arguments:
- *      pCtx		Pointer	to SHA-1 context
- * 	    pData       Pointer to input data
- *      LenInBytes  The length of input data (unit: byte)
- *
- *  Return Value:
- *      error       indicate more than pow(2,64) bits of data
- *
- *  Note:
- *      Called after SHAInit or SHAUpdate(itself)
- */
-UCHAR SHAUpdate(SHA_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes)
-{
-    UINT32 TfTimes;
-    UINT32 temp1,temp2;
-	unsigned int i;
-	UCHAR err=1;
-
-    temp1 = pCtx->LenInBitCount[0];
-    temp2 = pCtx->LenInBitCount[1];
-
-    pCtx->LenInBitCount[0] = (UINT32) (pCtx->LenInBitCount[0] + (LenInBytes << 3));
-    if (pCtx->LenInBitCount[0] < temp1)
-        pCtx->LenInBitCount[1]++;   //carry in
-
-
-    pCtx->LenInBitCount[1] = (UINT32) (pCtx->LenInBitCount[1] +(LenInBytes >> 29));
-    if (pCtx->LenInBitCount[1] < temp2)
-        return (err);   //check total length of original data
-
-
-    // mod 64 bytes
-    temp1 = (temp1 >> 3) & 0x3f;
-
-    // process lacks of 64-byte data
-    if (temp1)
-    {
-        UCHAR *pAds = (UCHAR *) pCtx->Input + temp1;
-
-        if ((temp1+LenInBytes) < 64)
-        {
-            NdisMoveMemory(pAds, (UCHAR *)pData, LenInBytes);
-            return (0);
-        }
-
-        NdisMoveMemory(pAds, (UCHAR *)pData, 64-temp1);
-        byteReverse((UCHAR *)pCtx->Input, 16);
-
-        NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
-        SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
-
-        pData += 64-temp1;
-        LenInBytes -= 64-temp1;
-    } // end of if (temp1)
-
-
-    TfTimes = (LenInBytes >> 6);
-
-    for (i=TfTimes; i>0; i--)
-    {
-        NdisMoveMemory(pCtx->Input, (UCHAR *)pData, 64);
-        byteReverse((UCHAR *)pCtx->Input, 16);
-
-        NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
-        SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
-        pData += 64;
-        LenInBytes -= 64;
-    } // end of for
-
-    // buffering lacks of 64-byte data
-    if(LenInBytes)
-        NdisMoveMemory(pCtx->Input, (UCHAR *)pData, LenInBytes);
-
-	return (0);
-
-}
-
-// Append padding bits and length of original message in the tail
-// The message digest has to be completed in the end
-VOID SHAFinal(SHA_CTX *pCtx, UCHAR Digest[20])
-{
-    UCHAR Remainder;
-    UCHAR PadLenInBytes;
-    UCHAR *pAppend=0;
-    unsigned int i;
-
-    Remainder = (UCHAR)((pCtx->LenInBitCount[0] >> 3) & 0x3f);
-
-    pAppend = (UCHAR *)pCtx->Input + Remainder;
-
-    PadLenInBytes = (Remainder < 56) ? (56-Remainder) : (120-Remainder);
-
-    // padding bits without crossing block(64-byte based) boundary
-    if (Remainder < 56)
-    {
-        *pAppend = 0x80;
-        PadLenInBytes --;
-
-        NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, PadLenInBytes);
-
-		// add data-length field, from high to low
-        for (i=0; i<4; i++)
-        {
-        	pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[1] >> ((3-i) << 3)) & 0xff);
-        	pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[0] >> ((3-i) << 3)) & 0xff);
-      	}
-
-        byteReverse((UCHAR *)pCtx->Input, 16);
-        NdisZeroMemory((UCHAR *)pCtx->Input + 64, 14);
-        SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
-    } // end of if
-
-    // padding bits with crossing block(64-byte based) boundary
-    else
-    {
-        // the first block ===
-        *pAppend = 0x80;
-        PadLenInBytes --;
-
-        NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, (64-Remainder-1));
-        PadLenInBytes -= (64 - Remainder - 1);
-
-        byteReverse((UCHAR *)pCtx->Input, 16);
-        NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
-        SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
-
-
-        // the second block ===
-        NdisZeroMemory((UCHAR *)pCtx->Input, PadLenInBytes);
-
-		// add data-length field
-		for (i=0; i<4; i++)
-        {
-        	pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[1] >> ((3-i) << 3)) & 0xff);
-        	pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[0] >> ((3-i) << 3)) & 0xff);
-      	}
-
-        byteReverse((UCHAR *)pCtx->Input, 16);
-        NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
-        SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
-    } // end of else
-
-
-    //Output, bytereverse
-    for (i=0; i<20; i++)
-    {
-        Digest [i] = (UCHAR)(pCtx->Buf[i>>2] >> 8*(3-(i & 0x3)));
-    }
-
-    NdisZeroMemory(pCtx, sizeof(pCtx)); // memory free
-}
-
-
-// The central algorithm of SHA-1, consists of four rounds and
-// twenty steps per round
-VOID SHATransform(UINT32 Buf[5], UINT32 Mes[20])
-{
-    UINT32 Reg[5],Temp;
-	unsigned int i;
-    UINT32 W[80];
-
-    static UINT32 SHA1Table[4] = { 0x5a827999, 0x6ed9eba1,
-                                  0x8f1bbcdc, 0xca62c1d6 };
-
-    Reg[0]=Buf[0];
-	Reg[1]=Buf[1];
-	Reg[2]=Buf[2];
-	Reg[3]=Buf[3];
-	Reg[4]=Buf[4];
-
-    //the first octet of a word is stored in the 0th element, bytereverse
-	for(i = 0; i < 16; i++)
-    {
-    	W[i]  = (Mes[i] >> 24) & 0xff;
-        W[i] |= (Mes[i] >> 8 ) & 0xff00;
-        W[i] |= (Mes[i] << 8 ) & 0xff0000;
-        W[i] |= (Mes[i] << 24) & 0xff000000;
-    }
-
-
-    for	(i = 0; i < 64; i++)
-	    W[16+i] = CYCLIC_LEFT_SHIFT(W[i] ^ W[2+i] ^ W[8+i] ^ W[13+i], 1);
-
-
-    // 80 steps in SHA-1 algorithm
-    for (i=0; i<80; i++)
-    {
-        if (i<20)
-            SHA1Step(SHA1_F1, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4],
-                     W[i], SHA1Table[0]);
-
-        else if (i>=20 && i<40)
-            SHA1Step(SHA1_F2, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4],
-                     W[i], SHA1Table[1]);
-
-		else if (i>=40 && i<60)
-            SHA1Step(SHA1_F3, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4],
-                      W[i], SHA1Table[2]);
-
-        else
-            SHA1Step(SHA1_F2, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4],
-                     W[i], SHA1Table[3]);
-
-
-       // one-word right shift
-		Temp   = Reg[4];
-        Reg[4] = Reg[3];
-        Reg[3] = Reg[2];
-        Reg[2] = Reg[1];
-        Reg[1] = Reg[0];
-        Reg[0] = Temp;
-
-    } // end of for-loop
-
-
-    // (temporary)output
-    for (i=0; i<5; i++)
-        Buf[i] += Reg[i];
-
-}
-
-
-/* =========================  AES En/Decryption ========================== */
-
-/* forward S-box */
-static uint32 FSb[256] =
-{
-	0x63, 0x7C,	0x77, 0x7B,	0xF2, 0x6B,	0x6F, 0xC5,
-	0x30, 0x01,	0x67, 0x2B,	0xFE, 0xD7,	0xAB, 0x76,
-	0xCA, 0x82,	0xC9, 0x7D,	0xFA, 0x59,	0x47, 0xF0,
-	0xAD, 0xD4,	0xA2, 0xAF,	0x9C, 0xA4,	0x72, 0xC0,
-	0xB7, 0xFD,	0x93, 0x26,	0x36, 0x3F,	0xF7, 0xCC,
-	0x34, 0xA5,	0xE5, 0xF1,	0x71, 0xD8,	0x31, 0x15,
-	0x04, 0xC7,	0x23, 0xC3,	0x18, 0x96,	0x05, 0x9A,
-	0x07, 0x12,	0x80, 0xE2,	0xEB, 0x27,	0xB2, 0x75,
-	0x09, 0x83,	0x2C, 0x1A,	0x1B, 0x6E,	0x5A, 0xA0,
-	0x52, 0x3B,	0xD6, 0xB3,	0x29, 0xE3,	0x2F, 0x84,
-	0x53, 0xD1,	0x00, 0xED,	0x20, 0xFC,	0xB1, 0x5B,
-	0x6A, 0xCB,	0xBE, 0x39,	0x4A, 0x4C,	0x58, 0xCF,
-	0xD0, 0xEF,	0xAA, 0xFB,	0x43, 0x4D,	0x33, 0x85,
-	0x45, 0xF9,	0x02, 0x7F,	0x50, 0x3C,	0x9F, 0xA8,
-	0x51, 0xA3,	0x40, 0x8F,	0x92, 0x9D,	0x38, 0xF5,
-	0xBC, 0xB6,	0xDA, 0x21,	0x10, 0xFF,	0xF3, 0xD2,
-	0xCD, 0x0C,	0x13, 0xEC,	0x5F, 0x97,	0x44, 0x17,
-	0xC4, 0xA7,	0x7E, 0x3D,	0x64, 0x5D,	0x19, 0x73,
-	0x60, 0x81,	0x4F, 0xDC,	0x22, 0x2A,	0x90, 0x88,
-	0x46, 0xEE,	0xB8, 0x14,	0xDE, 0x5E,	0x0B, 0xDB,
-	0xE0, 0x32,	0x3A, 0x0A,	0x49, 0x06,	0x24, 0x5C,
-	0xC2, 0xD3,	0xAC, 0x62,	0x91, 0x95,	0xE4, 0x79,
-	0xE7, 0xC8,	0x37, 0x6D,	0x8D, 0xD5,	0x4E, 0xA9,
-	0x6C, 0x56,	0xF4, 0xEA,	0x65, 0x7A,	0xAE, 0x08,
-	0xBA, 0x78,	0x25, 0x2E,	0x1C, 0xA6,	0xB4, 0xC6,
-	0xE8, 0xDD,	0x74, 0x1F,	0x4B, 0xBD,	0x8B, 0x8A,
-	0x70, 0x3E,	0xB5, 0x66,	0x48, 0x03,	0xF6, 0x0E,
-	0x61, 0x35,	0x57, 0xB9,	0x86, 0xC1,	0x1D, 0x9E,
-	0xE1, 0xF8,	0x98, 0x11,	0x69, 0xD9,	0x8E, 0x94,
-	0x9B, 0x1E,	0x87, 0xE9,	0xCE, 0x55,	0x28, 0xDF,
-	0x8C, 0xA1,	0x89, 0x0D,	0xBF, 0xE6,	0x42, 0x68,
-	0x41, 0x99,	0x2D, 0x0F,	0xB0, 0x54,	0xBB, 0x16
-};
-
-/* forward table */
-#define	FT \
-\
-	V(C6,63,63,A5),	V(F8,7C,7C,84),	V(EE,77,77,99),	V(F6,7B,7B,8D),	\
-	V(FF,F2,F2,0D),	V(D6,6B,6B,BD),	V(DE,6F,6F,B1),	V(91,C5,C5,54),	\
-	V(60,30,30,50),	V(02,01,01,03),	V(CE,67,67,A9),	V(56,2B,2B,7D),	\
-	V(E7,FE,FE,19),	V(B5,D7,D7,62),	V(4D,AB,AB,E6),	V(EC,76,76,9A),	\
-	V(8F,CA,CA,45),	V(1F,82,82,9D),	V(89,C9,C9,40),	V(FA,7D,7D,87),	\
-	V(EF,FA,FA,15),	V(B2,59,59,EB),	V(8E,47,47,C9),	V(FB,F0,F0,0B),	\
-	V(41,AD,AD,EC),	V(B3,D4,D4,67),	V(5F,A2,A2,FD),	V(45,AF,AF,EA),	\
-	V(23,9C,9C,BF),	V(53,A4,A4,F7),	V(E4,72,72,96),	V(9B,C0,C0,5B),	\
-	V(75,B7,B7,C2),	V(E1,FD,FD,1C),	V(3D,93,93,AE),	V(4C,26,26,6A),	\
-	V(6C,36,36,5A),	V(7E,3F,3F,41),	V(F5,F7,F7,02),	V(83,CC,CC,4F),	\
-	V(68,34,34,5C),	V(51,A5,A5,F4),	V(D1,E5,E5,34),	V(F9,F1,F1,08),	\
-	V(E2,71,71,93),	V(AB,D8,D8,73),	V(62,31,31,53),	V(2A,15,15,3F),	\
-	V(08,04,04,0C),	V(95,C7,C7,52),	V(46,23,23,65),	V(9D,C3,C3,5E),	\
-	V(30,18,18,28),	V(37,96,96,A1),	V(0A,05,05,0F),	V(2F,9A,9A,B5),	\
-	V(0E,07,07,09),	V(24,12,12,36),	V(1B,80,80,9B),	V(DF,E2,E2,3D),	\
-	V(CD,EB,EB,26),	V(4E,27,27,69),	V(7F,B2,B2,CD),	V(EA,75,75,9F),	\
-	V(12,09,09,1B),	V(1D,83,83,9E),	V(58,2C,2C,74),	V(34,1A,1A,2E),	\
-	V(36,1B,1B,2D),	V(DC,6E,6E,B2),	V(B4,5A,5A,EE),	V(5B,A0,A0,FB),	\
-	V(A4,52,52,F6),	V(76,3B,3B,4D),	V(B7,D6,D6,61),	V(7D,B3,B3,CE),	\
-	V(52,29,29,7B),	V(DD,E3,E3,3E),	V(5E,2F,2F,71),	V(13,84,84,97),	\
-	V(A6,53,53,F5),	V(B9,D1,D1,68),	V(00,00,00,00),	V(C1,ED,ED,2C),	\
-	V(40,20,20,60),	V(E3,FC,FC,1F),	V(79,B1,B1,C8),	V(B6,5B,5B,ED),	\
-	V(D4,6A,6A,BE),	V(8D,CB,CB,46),	V(67,BE,BE,D9),	V(72,39,39,4B),	\
-	V(94,4A,4A,DE),	V(98,4C,4C,D4),	V(B0,58,58,E8),	V(85,CF,CF,4A),	\
-	V(BB,D0,D0,6B),	V(C5,EF,EF,2A),	V(4F,AA,AA,E5),	V(ED,FB,FB,16),	\
-	V(86,43,43,C5),	V(9A,4D,4D,D7),	V(66,33,33,55),	V(11,85,85,94),	\
-	V(8A,45,45,CF),	V(E9,F9,F9,10),	V(04,02,02,06),	V(FE,7F,7F,81),	\
-	V(A0,50,50,F0),	V(78,3C,3C,44),	V(25,9F,9F,BA),	V(4B,A8,A8,E3),	\
-	V(A2,51,51,F3),	V(5D,A3,A3,FE),	V(80,40,40,C0),	V(05,8F,8F,8A),	\
-	V(3F,92,92,AD),	V(21,9D,9D,BC),	V(70,38,38,48),	V(F1,F5,F5,04),	\
-	V(63,BC,BC,DF),	V(77,B6,B6,C1),	V(AF,DA,DA,75),	V(42,21,21,63),	\
-	V(20,10,10,30),	V(E5,FF,FF,1A),	V(FD,F3,F3,0E),	V(BF,D2,D2,6D),	\
-	V(81,CD,CD,4C),	V(18,0C,0C,14),	V(26,13,13,35),	V(C3,EC,EC,2F),	\
-	V(BE,5F,5F,E1),	V(35,97,97,A2),	V(88,44,44,CC),	V(2E,17,17,39),	\
-	V(93,C4,C4,57),	V(55,A7,A7,F2),	V(FC,7E,7E,82),	V(7A,3D,3D,47),	\
-	V(C8,64,64,AC),	V(BA,5D,5D,E7),	V(32,19,19,2B),	V(E6,73,73,95),	\
-	V(C0,60,60,A0),	V(19,81,81,98),	V(9E,4F,4F,D1),	V(A3,DC,DC,7F),	\
-	V(44,22,22,66),	V(54,2A,2A,7E),	V(3B,90,90,AB),	V(0B,88,88,83),	\
-	V(8C,46,46,CA),	V(C7,EE,EE,29),	V(6B,B8,B8,D3),	V(28,14,14,3C),	\
-	V(A7,DE,DE,79),	V(BC,5E,5E,E2),	V(16,0B,0B,1D),	V(AD,DB,DB,76),	\
-	V(DB,E0,E0,3B),	V(64,32,32,56),	V(74,3A,3A,4E),	V(14,0A,0A,1E),	\
-	V(92,49,49,DB),	V(0C,06,06,0A),	V(48,24,24,6C),	V(B8,5C,5C,E4),	\
-	V(9F,C2,C2,5D),	V(BD,D3,D3,6E),	V(43,AC,AC,EF),	V(C4,62,62,A6),	\
-	V(39,91,91,A8),	V(31,95,95,A4),	V(D3,E4,E4,37),	V(F2,79,79,8B),	\
-	V(D5,E7,E7,32),	V(8B,C8,C8,43),	V(6E,37,37,59),	V(DA,6D,6D,B7),	\
-	V(01,8D,8D,8C),	V(B1,D5,D5,64),	V(9C,4E,4E,D2),	V(49,A9,A9,E0),	\
-	V(D8,6C,6C,B4),	V(AC,56,56,FA),	V(F3,F4,F4,07),	V(CF,EA,EA,25),	\
-	V(CA,65,65,AF),	V(F4,7A,7A,8E),	V(47,AE,AE,E9),	V(10,08,08,18),	\
-	V(6F,BA,BA,D5),	V(F0,78,78,88),	V(4A,25,25,6F),	V(5C,2E,2E,72),	\
-	V(38,1C,1C,24),	V(57,A6,A6,F1),	V(73,B4,B4,C7),	V(97,C6,C6,51),	\
-	V(CB,E8,E8,23),	V(A1,DD,DD,7C),	V(E8,74,74,9C),	V(3E,1F,1F,21),	\
-	V(96,4B,4B,DD),	V(61,BD,BD,DC),	V(0D,8B,8B,86),	V(0F,8A,8A,85),	\
-	V(E0,70,70,90),	V(7C,3E,3E,42),	V(71,B5,B5,C4),	V(CC,66,66,AA),	\
-	V(90,48,48,D8),	V(06,03,03,05),	V(F7,F6,F6,01),	V(1C,0E,0E,12),	\
-	V(C2,61,61,A3),	V(6A,35,35,5F),	V(AE,57,57,F9),	V(69,B9,B9,D0),	\
-	V(17,86,86,91),	V(99,C1,C1,58),	V(3A,1D,1D,27),	V(27,9E,9E,B9),	\
-	V(D9,E1,E1,38),	V(EB,F8,F8,13),	V(2B,98,98,B3),	V(22,11,11,33),	\
-	V(D2,69,69,BB),	V(A9,D9,D9,70),	V(07,8E,8E,89),	V(33,94,94,A7),	\
-	V(2D,9B,9B,B6),	V(3C,1E,1E,22),	V(15,87,87,92),	V(C9,E9,E9,20),	\
-	V(87,CE,CE,49),	V(AA,55,55,FF),	V(50,28,28,78),	V(A5,DF,DF,7A),	\
-	V(03,8C,8C,8F),	V(59,A1,A1,F8),	V(09,89,89,80),	V(1A,0D,0D,17),	\
-	V(65,BF,BF,DA),	V(D7,E6,E6,31),	V(84,42,42,C6),	V(D0,68,68,B8),	\
-	V(82,41,41,C3),	V(29,99,99,B0),	V(5A,2D,2D,77),	V(1E,0F,0F,11),	\
-	V(7B,B0,B0,CB),	V(A8,54,54,FC),	V(6D,BB,BB,D6),	V(2C,16,16,3A)
-
-#define	V(a,b,c,d) 0x##a##b##c##d
-static uint32 FT0[256] = { FT };
-#undef V
-
-#define	V(a,b,c,d) 0x##d##a##b##c
-static uint32 FT1[256] = { FT };
-#undef V
-
-#define	V(a,b,c,d) 0x##c##d##a##b
-static uint32 FT2[256] = { FT };
-#undef V
-
-#define	V(a,b,c,d) 0x##b##c##d##a
-static uint32 FT3[256] = { FT };
-#undef V
-
-#undef FT
-
-/* reverse S-box */
-
-static uint32 RSb[256] =
-{
-	0x52, 0x09,	0x6A, 0xD5,	0x30, 0x36,	0xA5, 0x38,
-	0xBF, 0x40,	0xA3, 0x9E,	0x81, 0xF3,	0xD7, 0xFB,
-	0x7C, 0xE3,	0x39, 0x82,	0x9B, 0x2F,	0xFF, 0x87,
-	0x34, 0x8E,	0x43, 0x44,	0xC4, 0xDE,	0xE9, 0xCB,
-	0x54, 0x7B,	0x94, 0x32,	0xA6, 0xC2,	0x23, 0x3D,
-	0xEE, 0x4C,	0x95, 0x0B,	0x42, 0xFA,	0xC3, 0x4E,
-	0x08, 0x2E,	0xA1, 0x66,	0x28, 0xD9,	0x24, 0xB2,
-	0x76, 0x5B,	0xA2, 0x49,	0x6D, 0x8B,	0xD1, 0x25,
-	0x72, 0xF8,	0xF6, 0x64,	0x86, 0x68,	0x98, 0x16,
-	0xD4, 0xA4,	0x5C, 0xCC,	0x5D, 0x65,	0xB6, 0x92,
-	0x6C, 0x70,	0x48, 0x50,	0xFD, 0xED,	0xB9, 0xDA,
-	0x5E, 0x15,	0x46, 0x57,	0xA7, 0x8D,	0x9D, 0x84,
-	0x90, 0xD8,	0xAB, 0x00,	0x8C, 0xBC,	0xD3, 0x0A,
-	0xF7, 0xE4,	0x58, 0x05,	0xB8, 0xB3,	0x45, 0x06,
-	0xD0, 0x2C,	0x1E, 0x8F,	0xCA, 0x3F,	0x0F, 0x02,
-	0xC1, 0xAF,	0xBD, 0x03,	0x01, 0x13,	0x8A, 0x6B,
-	0x3A, 0x91,	0x11, 0x41,	0x4F, 0x67,	0xDC, 0xEA,
-	0x97, 0xF2,	0xCF, 0xCE,	0xF0, 0xB4,	0xE6, 0x73,
-	0x96, 0xAC,	0x74, 0x22,	0xE7, 0xAD,	0x35, 0x85,
-	0xE2, 0xF9,	0x37, 0xE8,	0x1C, 0x75,	0xDF, 0x6E,
-	0x47, 0xF1,	0x1A, 0x71,	0x1D, 0x29,	0xC5, 0x89,
-	0x6F, 0xB7,	0x62, 0x0E,	0xAA, 0x18,	0xBE, 0x1B,
-	0xFC, 0x56,	0x3E, 0x4B,	0xC6, 0xD2,	0x79, 0x20,
-	0x9A, 0xDB,	0xC0, 0xFE,	0x78, 0xCD,	0x5A, 0xF4,
-	0x1F, 0xDD,	0xA8, 0x33,	0x88, 0x07,	0xC7, 0x31,
-	0xB1, 0x12,	0x10, 0x59,	0x27, 0x80,	0xEC, 0x5F,
-	0x60, 0x51,	0x7F, 0xA9,	0x19, 0xB5,	0x4A, 0x0D,
-	0x2D, 0xE5,	0x7A, 0x9F,	0x93, 0xC9,	0x9C, 0xEF,
-	0xA0, 0xE0,	0x3B, 0x4D,	0xAE, 0x2A,	0xF5, 0xB0,
-	0xC8, 0xEB,	0xBB, 0x3C,	0x83, 0x53,	0x99, 0x61,
-	0x17, 0x2B,	0x04, 0x7E,	0xBA, 0x77,	0xD6, 0x26,
-	0xE1, 0x69,	0x14, 0x63,	0x55, 0x21,	0x0C, 0x7D
-};
-
-/* reverse table */
-
-#define	RT \
-\
-	V(51,F4,A7,50),	V(7E,41,65,53),	V(1A,17,A4,C3),	V(3A,27,5E,96),	\
-	V(3B,AB,6B,CB),	V(1F,9D,45,F1),	V(AC,FA,58,AB),	V(4B,E3,03,93),	\
-	V(20,30,FA,55),	V(AD,76,6D,F6),	V(88,CC,76,91),	V(F5,02,4C,25),	\
-	V(4F,E5,D7,FC),	V(C5,2A,CB,D7),	V(26,35,44,80),	V(B5,62,A3,8F),	\
-	V(DE,B1,5A,49),	V(25,BA,1B,67),	V(45,EA,0E,98),	V(5D,FE,C0,E1),	\
-	V(C3,2F,75,02),	V(81,4C,F0,12),	V(8D,46,97,A3),	V(6B,D3,F9,C6),	\
-	V(03,8F,5F,E7),	V(15,92,9C,95),	V(BF,6D,7A,EB),	V(95,52,59,DA),	\
-	V(D4,BE,83,2D),	V(58,74,21,D3),	V(49,E0,69,29),	V(8E,C9,C8,44),	\
-	V(75,C2,89,6A),	V(F4,8E,79,78),	V(99,58,3E,6B),	V(27,B9,71,DD),	\
-	V(BE,E1,4F,B6),	V(F0,88,AD,17),	V(C9,20,AC,66),	V(7D,CE,3A,B4),	\
-	V(63,DF,4A,18),	V(E5,1A,31,82),	V(97,51,33,60),	V(62,53,7F,45),	\
-	V(B1,64,77,E0),	V(BB,6B,AE,84),	V(FE,81,A0,1C),	V(F9,08,2B,94),	\
-	V(70,48,68,58),	V(8F,45,FD,19),	V(94,DE,6C,87),	V(52,7B,F8,B7),	\
-	V(AB,73,D3,23),	V(72,4B,02,E2),	V(E3,1F,8F,57),	V(66,55,AB,2A),	\
-	V(B2,EB,28,07),	V(2F,B5,C2,03),	V(86,C5,7B,9A),	V(D3,37,08,A5),	\
-	V(30,28,87,F2),	V(23,BF,A5,B2),	V(02,03,6A,BA),	V(ED,16,82,5C),	\
-	V(8A,CF,1C,2B),	V(A7,79,B4,92),	V(F3,07,F2,F0),	V(4E,69,E2,A1),	\
-	V(65,DA,F4,CD),	V(06,05,BE,D5),	V(D1,34,62,1F),	V(C4,A6,FE,8A),	\
-	V(34,2E,53,9D),	V(A2,F3,55,A0),	V(05,8A,E1,32),	V(A4,F6,EB,75),	\
-	V(0B,83,EC,39),	V(40,60,EF,AA),	V(5E,71,9F,06),	V(BD,6E,10,51),	\
-	V(3E,21,8A,F9),	V(96,DD,06,3D),	V(DD,3E,05,AE),	V(4D,E6,BD,46),	\
-	V(91,54,8D,B5),	V(71,C4,5D,05),	V(04,06,D4,6F),	V(60,50,15,FF),	\
-	V(19,98,FB,24),	V(D6,BD,E9,97),	V(89,40,43,CC),	V(67,D9,9E,77),	\
-	V(B0,E8,42,BD),	V(07,89,8B,88),	V(E7,19,5B,38),	V(79,C8,EE,DB),	\
-	V(A1,7C,0A,47),	V(7C,42,0F,E9),	V(F8,84,1E,C9),	V(00,00,00,00),	\
-	V(09,80,86,83),	V(32,2B,ED,48),	V(1E,11,70,AC),	V(6C,5A,72,4E),	\
-	V(FD,0E,FF,FB),	V(0F,85,38,56),	V(3D,AE,D5,1E),	V(36,2D,39,27),	\
-	V(0A,0F,D9,64),	V(68,5C,A6,21),	V(9B,5B,54,D1),	V(24,36,2E,3A),	\
-	V(0C,0A,67,B1),	V(93,57,E7,0F),	V(B4,EE,96,D2),	V(1B,9B,91,9E),	\
-	V(80,C0,C5,4F),	V(61,DC,20,A2),	V(5A,77,4B,69),	V(1C,12,1A,16),	\
-	V(E2,93,BA,0A),	V(C0,A0,2A,E5),	V(3C,22,E0,43),	V(12,1B,17,1D),	\
-	V(0E,09,0D,0B),	V(F2,8B,C7,AD),	V(2D,B6,A8,B9),	V(14,1E,A9,C8),	\
-	V(57,F1,19,85),	V(AF,75,07,4C),	V(EE,99,DD,BB),	V(A3,7F,60,FD),	\
-	V(F7,01,26,9F),	V(5C,72,F5,BC),	V(44,66,3B,C5),	V(5B,FB,7E,34),	\
-	V(8B,43,29,76),	V(CB,23,C6,DC),	V(B6,ED,FC,68),	V(B8,E4,F1,63),	\
-	V(D7,31,DC,CA),	V(42,63,85,10),	V(13,97,22,40),	V(84,C6,11,20),	\
-	V(85,4A,24,7D),	V(D2,BB,3D,F8),	V(AE,F9,32,11),	V(C7,29,A1,6D),	\
-	V(1D,9E,2F,4B),	V(DC,B2,30,F3),	V(0D,86,52,EC),	V(77,C1,E3,D0),	\
-	V(2B,B3,16,6C),	V(A9,70,B9,99),	V(11,94,48,FA),	V(47,E9,64,22),	\
-	V(A8,FC,8C,C4),	V(A0,F0,3F,1A),	V(56,7D,2C,D8),	V(22,33,90,EF),	\
-	V(87,49,4E,C7),	V(D9,38,D1,C1),	V(8C,CA,A2,FE),	V(98,D4,0B,36),	\
-	V(A6,F5,81,CF),	V(A5,7A,DE,28),	V(DA,B7,8E,26),	V(3F,AD,BF,A4),	\
-	V(2C,3A,9D,E4),	V(50,78,92,0D),	V(6A,5F,CC,9B),	V(54,7E,46,62),	\
-	V(F6,8D,13,C2),	V(90,D8,B8,E8),	V(2E,39,F7,5E),	V(82,C3,AF,F5),	\
-	V(9F,5D,80,BE),	V(69,D0,93,7C),	V(6F,D5,2D,A9),	V(CF,25,12,B3),	\
-	V(C8,AC,99,3B),	V(10,18,7D,A7),	V(E8,9C,63,6E),	V(DB,3B,BB,7B),	\
-	V(CD,26,78,09),	V(6E,59,18,F4),	V(EC,9A,B7,01),	V(83,4F,9A,A8),	\
-	V(E6,95,6E,65),	V(AA,FF,E6,7E),	V(21,BC,CF,08),	V(EF,15,E8,E6),	\
-	V(BA,E7,9B,D9),	V(4A,6F,36,CE),	V(EA,9F,09,D4),	V(29,B0,7C,D6),	\
-	V(31,A4,B2,AF),	V(2A,3F,23,31),	V(C6,A5,94,30),	V(35,A2,66,C0),	\
-	V(74,4E,BC,37),	V(FC,82,CA,A6),	V(E0,90,D0,B0),	V(33,A7,D8,15),	\
-	V(F1,04,98,4A),	V(41,EC,DA,F7),	V(7F,CD,50,0E),	V(17,91,F6,2F),	\
-	V(76,4D,D6,8D),	V(43,EF,B0,4D),	V(CC,AA,4D,54),	V(E4,96,04,DF),	\
-	V(9E,D1,B5,E3),	V(4C,6A,88,1B),	V(C1,2C,1F,B8),	V(46,65,51,7F),	\
-	V(9D,5E,EA,04),	V(01,8C,35,5D),	V(FA,87,74,73),	V(FB,0B,41,2E),	\
-	V(B3,67,1D,5A),	V(92,DB,D2,52),	V(E9,10,56,33),	V(6D,D6,47,13),	\
-	V(9A,D7,61,8C),	V(37,A1,0C,7A),	V(59,F8,14,8E),	V(EB,13,3C,89),	\
-	V(CE,A9,27,EE),	V(B7,61,C9,35),	V(E1,1C,E5,ED),	V(7A,47,B1,3C),	\
-	V(9C,D2,DF,59),	V(55,F2,73,3F),	V(18,14,CE,79),	V(73,C7,37,BF),	\
-	V(53,F7,CD,EA),	V(5F,FD,AA,5B),	V(DF,3D,6F,14),	V(78,44,DB,86),	\
-	V(CA,AF,F3,81),	V(B9,68,C4,3E),	V(38,24,34,2C),	V(C2,A3,40,5F),	\
-	V(16,1D,C3,72),	V(BC,E2,25,0C),	V(28,3C,49,8B),	V(FF,0D,95,41),	\
-	V(39,A8,01,71),	V(08,0C,B3,DE),	V(D8,B4,E4,9C),	V(64,56,C1,90),	\
-	V(7B,CB,84,61),	V(D5,32,B6,70),	V(48,6C,5C,74),	V(D0,B8,57,42)
-
-#define	V(a,b,c,d) 0x##a##b##c##d
-static uint32 RT0[256] = { RT };
-#undef V
-
-#define	V(a,b,c,d) 0x##d##a##b##c
-static uint32 RT1[256] = { RT };
-#undef V
-
-#define	V(a,b,c,d) 0x##c##d##a##b
-static uint32 RT2[256] = { RT };
-#undef V
-
-#define	V(a,b,c,d) 0x##b##c##d##a
-static uint32 RT3[256] = { RT };
-#undef V
-
-#undef RT
-
-/* round constants */
-
-static uint32 RCON[10] =
-{
-	0x01000000,	0x02000000,	0x04000000,	0x08000000,
-	0x10000000,	0x20000000,	0x40000000,	0x80000000,
-	0x1B000000,	0x36000000
-};
-
-/* key schedule	tables */
-
-static int KT_init = 1;
-
-static uint32 KT0[256];
-static uint32 KT1[256];
-static uint32 KT2[256];
-static uint32 KT3[256];
-
-/* platform-independant	32-bit integer manipulation	macros */
-
-#define	GET_UINT32(n,b,i)						\
-{												\
-	(n)	= (	(uint32) (b)[(i)	] << 24	)		\
-		| (	(uint32) (b)[(i) + 1] << 16	)		\
-		| (	(uint32) (b)[(i) + 2] <<  8	)		\
-		| (	(uint32) (b)[(i) + 3]		);		\
-}
-
-#define	PUT_UINT32(n,b,i)						\
-{												\
-	(b)[(i)	   ] = (uint8) ( (n) >>	24 );		\
-	(b)[(i)	+ 1] = (uint8) ( (n) >>	16 );		\
-	(b)[(i)	+ 2] = (uint8) ( (n) >>	 8 );		\
-	(b)[(i)	+ 3] = (uint8) ( (n)	   );		\
-}
-
-/* AES key scheduling routine */
-
-int	rtmp_aes_set_key( aes_context *ctx, uint8 *key, int nbits )
-{
-	int	i;
-	uint32 *RK,	*SK;
-
-	switch(	nbits )
-	{
-		case 128: ctx->nr =	10;	break;
-		case 192: ctx->nr =	12;	break;
-		case 256: ctx->nr =	14;	break;
-		default	: return( 1	);
-	}
-
-	RK = ctx->erk;
-
-	for( i = 0;	i <	(nbits >> 5); i++ )
-	{
-		GET_UINT32(	RK[i], key,	i *	4 );
-	}
-
-	/* setup encryption	round keys */
-
-	switch(	nbits )
-	{
-	case 128:
-
-		for( i = 0;	i <	10;	i++, RK	+= 4 )
-		{
-			RK[4]  = RK[0] ^ RCON[i] ^
-						( FSb[ (uint8) ( RK[3] >> 16 ) ] <<	24 ) ^
-						( FSb[ (uint8) ( RK[3] >>  8 ) ] <<	16 ) ^
-						( FSb[ (uint8) ( RK[3]		 ) ] <<	 8 ) ^
-						( FSb[ (uint8) ( RK[3] >> 24 ) ]	   );
-
-			RK[5]  = RK[1] ^ RK[4];
-			RK[6]  = RK[2] ^ RK[5];
-			RK[7]  = RK[3] ^ RK[6];
-		}
-		break;
-
-	case 192:
-
-		for( i = 0;	i <	8; i++,	RK += 6	)
-		{
-			RK[6]  = RK[0] ^ RCON[i] ^
-						( FSb[ (uint8) ( RK[5] >> 16 ) ] <<	24 ) ^
-						( FSb[ (uint8) ( RK[5] >>  8 ) ] <<	16 ) ^
-						( FSb[ (uint8) ( RK[5]		 ) ] <<	 8 ) ^
-						( FSb[ (uint8) ( RK[5] >> 24 ) ]	   );
-
-			RK[7]  = RK[1] ^ RK[6];
-			RK[8]  = RK[2] ^ RK[7];
-			RK[9]  = RK[3] ^ RK[8];
-			RK[10] = RK[4] ^ RK[9];
-			RK[11] = RK[5] ^ RK[10];
-		}
-		break;
-
-	case 256:
-
-		for( i = 0;	i <	7; i++,	RK += 8	)
-		{
-			RK[8]  = RK[0] ^ RCON[i] ^
-						( FSb[ (uint8) ( RK[7] >> 16 ) ] <<	24 ) ^
-						( FSb[ (uint8) ( RK[7] >>  8 ) ] <<	16 ) ^
-						( FSb[ (uint8) ( RK[7]		 ) ] <<	 8 ) ^
-						( FSb[ (uint8) ( RK[7] >> 24 ) ]	   );
-
-			RK[9]  = RK[1] ^ RK[8];
-			RK[10] = RK[2] ^ RK[9];
-			RK[11] = RK[3] ^ RK[10];
-
-			RK[12] = RK[4] ^
-						( FSb[ (uint8) ( RK[11]	>> 24 )	] << 24	) ^
-						( FSb[ (uint8) ( RK[11]	>> 16 )	] << 16	) ^
-						( FSb[ (uint8) ( RK[11]	>>	8 )	] <<  8	) ^
-						( FSb[ (uint8) ( RK[11]		  )	]		);
-
-			RK[13] = RK[5] ^ RK[12];
-			RK[14] = RK[6] ^ RK[13];
-			RK[15] = RK[7] ^ RK[14];
-		}
-		break;
-	}
-
-	/* setup decryption	round keys */
-
-	if(	KT_init	)
-	{
-		for( i = 0;	i <	256; i++ )
-		{
-			KT0[i] = RT0[ FSb[i] ];
-			KT1[i] = RT1[ FSb[i] ];
-			KT2[i] = RT2[ FSb[i] ];
-			KT3[i] = RT3[ FSb[i] ];
-		}
-
-		KT_init	= 0;
-	}
-
-	SK = ctx->drk;
-
-	*SK++ =	*RK++;
-	*SK++ =	*RK++;
-	*SK++ =	*RK++;
-	*SK++ =	*RK++;
-
-	for( i = 1;	i <	ctx->nr; i++ )
-	{
-		RK -= 8;
-
-		*SK++ =	KT0[ (uint8) ( *RK >> 24 ) ] ^
-				KT1[ (uint8) ( *RK >> 16 ) ] ^
-				KT2[ (uint8) ( *RK >>  8 ) ] ^
-				KT3[ (uint8) ( *RK		 ) ]; RK++;
-
-		*SK++ =	KT0[ (uint8) ( *RK >> 24 ) ] ^
-				KT1[ (uint8) ( *RK >> 16 ) ] ^
-				KT2[ (uint8) ( *RK >>  8 ) ] ^
-				KT3[ (uint8) ( *RK		 ) ]; RK++;
-
-		*SK++ =	KT0[ (uint8) ( *RK >> 24 ) ] ^
-				KT1[ (uint8) ( *RK >> 16 ) ] ^
-				KT2[ (uint8) ( *RK >>  8 ) ] ^
-				KT3[ (uint8) ( *RK		 ) ]; RK++;
-
-		*SK++ =	KT0[ (uint8) ( *RK >> 24 ) ] ^
-				KT1[ (uint8) ( *RK >> 16 ) ] ^
-				KT2[ (uint8) ( *RK >>  8 ) ] ^
-				KT3[ (uint8) ( *RK		 ) ]; RK++;
-	}
-
-	RK -= 8;
-
-	*SK++ =	*RK++;
-	*SK++ =	*RK++;
-	*SK++ =	*RK++;
-	*SK++ =	*RK++;
-
-	return(	0 );
-}
-
-/* AES 128-bit block encryption	routine	*/
-
-void rtmp_aes_encrypt(aes_context *ctx, uint8 input[16],	uint8 output[16] )
-{
-	uint32 *RK,	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3;
-
-	RK = ctx->erk;
-	GET_UINT32(	X0,	input,	0 ); X0	^= RK[0];
-	GET_UINT32(	X1,	input,	4 ); X1	^= RK[1];
-	GET_UINT32(	X2,	input,	8 ); X2	^= RK[2];
-	GET_UINT32(	X3,	input, 12 ); X3	^= RK[3];
-
-#define	AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)		\
-{												\
-	RK += 4;									\
-												\
-	X0 = RK[0] ^ FT0[ (uint8) (	Y0 >> 24 ) ] ^	\
-				 FT1[ (uint8) (	Y1 >> 16 ) ] ^	\
-				 FT2[ (uint8) (	Y2 >>  8 ) ] ^	\
-				 FT3[ (uint8) (	Y3		 ) ];	\
-												\
-	X1 = RK[1] ^ FT0[ (uint8) (	Y1 >> 24 ) ] ^	\
-				 FT1[ (uint8) (	Y2 >> 16 ) ] ^	\
-				 FT2[ (uint8) (	Y3 >>  8 ) ] ^	\
-				 FT3[ (uint8) (	Y0		 ) ];	\
-												\
-	X2 = RK[2] ^ FT0[ (uint8) (	Y2 >> 24 ) ] ^	\
-				 FT1[ (uint8) (	Y3 >> 16 ) ] ^	\
-				 FT2[ (uint8) (	Y0 >>  8 ) ] ^	\
-				 FT3[ (uint8) (	Y1		 ) ];	\
-												\
-	X3 = RK[3] ^ FT0[ (uint8) (	Y3 >> 24 ) ] ^	\
-				 FT1[ (uint8) (	Y0 >> 16 ) ] ^	\
-				 FT2[ (uint8) (	Y1 >>  8 ) ] ^	\
-				 FT3[ (uint8) (	Y2		 ) ];	\
-}
-
-	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 1 */
-	AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 2 */
-	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 3 */
-	AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 4 */
-	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 5 */
-	AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 6 */
-	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 7 */
-	AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 8 */
-	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 9 */
-
-	if(	ctx->nr	> 10 )
-	{
-		AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );	/* round 10	*/
-		AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );	/* round 11	*/
-	}
-
-	if(	ctx->nr	> 12 )
-	{
-		AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );	/* round 12	*/
-		AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );	/* round 13	*/
-	}
-
-	/* last	round */
-
-	RK += 4;
-
-	X0 = RK[0] ^ ( FSb[	(uint8)	( Y0 >>	24 ) ] << 24 ) ^
-				 ( FSb[	(uint8)	( Y1 >>	16 ) ] << 16 ) ^
-				 ( FSb[	(uint8)	( Y2 >>	 8 ) ] <<  8 ) ^
-				 ( FSb[	(uint8)	( Y3	   ) ]		 );
-
-	X1 = RK[1] ^ ( FSb[	(uint8)	( Y1 >>	24 ) ] << 24 ) ^
-				 ( FSb[	(uint8)	( Y2 >>	16 ) ] << 16 ) ^
-				 ( FSb[	(uint8)	( Y3 >>	 8 ) ] <<  8 ) ^
-				 ( FSb[	(uint8)	( Y0	   ) ]		 );
-
-	X2 = RK[2] ^ ( FSb[	(uint8)	( Y2 >>	24 ) ] << 24 ) ^
-				 ( FSb[	(uint8)	( Y3 >>	16 ) ] << 16 ) ^
-				 ( FSb[	(uint8)	( Y0 >>	 8 ) ] <<  8 ) ^
-				 ( FSb[	(uint8)	( Y1	   ) ]		 );
-
-	X3 = RK[3] ^ ( FSb[	(uint8)	( Y3 >>	24 ) ] << 24 ) ^
-				 ( FSb[	(uint8)	( Y0 >>	16 ) ] << 16 ) ^
-				 ( FSb[	(uint8)	( Y1 >>	 8 ) ] <<  8 ) ^
-				 ( FSb[	(uint8)	( Y2	   ) ]		 );
-
-	PUT_UINT32(	X0,	output,	 0 );
-	PUT_UINT32(	X1,	output,	 4 );
-	PUT_UINT32(	X2,	output,	 8 );
-	PUT_UINT32(	X3,	output,	12 );
-}
-
-/* AES 128-bit block decryption	routine	*/
-
-void rtmp_aes_decrypt( aes_context *ctx,	uint8 input[16], uint8 output[16] )
-{
-	uint32 *RK,	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3;
-
-	RK = ctx->drk;
-
-	GET_UINT32(	X0,	input,	0 ); X0	^= RK[0];
-	GET_UINT32(	X1,	input,	4 ); X1	^= RK[1];
-	GET_UINT32(	X2,	input,	8 ); X2	^= RK[2];
-	GET_UINT32(	X3,	input, 12 ); X3	^= RK[3];
-
-#define	AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)		\
-{												\
-	RK += 4;									\
-												\
-	X0 = RK[0] ^ RT0[ (uint8) (	Y0 >> 24 ) ] ^	\
-				 RT1[ (uint8) (	Y3 >> 16 ) ] ^	\
-				 RT2[ (uint8) (	Y2 >>  8 ) ] ^	\
-				 RT3[ (uint8) (	Y1		 ) ];	\
-												\
-	X1 = RK[1] ^ RT0[ (uint8) (	Y1 >> 24 ) ] ^	\
-				 RT1[ (uint8) (	Y0 >> 16 ) ] ^	\
-				 RT2[ (uint8) (	Y3 >>  8 ) ] ^	\
-				 RT3[ (uint8) (	Y2		 ) ];	\
-												\
-	X2 = RK[2] ^ RT0[ (uint8) (	Y2 >> 24 ) ] ^	\
-				 RT1[ (uint8) (	Y1 >> 16 ) ] ^	\
-				 RT2[ (uint8) (	Y0 >>  8 ) ] ^	\
-				 RT3[ (uint8) (	Y3		 ) ];	\
-												\
-	X3 = RK[3] ^ RT0[ (uint8) (	Y3 >> 24 ) ] ^	\
-				 RT1[ (uint8) (	Y2 >> 16 ) ] ^	\
-				 RT2[ (uint8) (	Y1 >>  8 ) ] ^	\
-				 RT3[ (uint8) (	Y0		 ) ];	\
-}
-
-	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 1 */
-	AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 2 */
-	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 3 */
-	AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 4 */
-	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 5 */
-	AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 6 */
-	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 7 */
-	AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 8 */
-	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 9 */
-
-	if(	ctx->nr	> 10 )
-	{
-		AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );	/* round 10	*/
-		AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );	/* round 11	*/
-	}
-
-	if(	ctx->nr	> 12 )
-	{
-		AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );	/* round 12	*/
-		AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );	/* round 13	*/
-	}
-
-	/* last	round */
-
-	RK += 4;
-
-	X0 = RK[0] ^ ( RSb[	(uint8)	( Y0 >>	24 ) ] << 24 ) ^
-				 ( RSb[	(uint8)	( Y3 >>	16 ) ] << 16 ) ^
-				 ( RSb[	(uint8)	( Y2 >>	 8 ) ] <<  8 ) ^
-				 ( RSb[	(uint8)	( Y1	   ) ]		 );
-
-	X1 = RK[1] ^ ( RSb[	(uint8)	( Y1 >>	24 ) ] << 24 ) ^
-				 ( RSb[	(uint8)	( Y0 >>	16 ) ] << 16 ) ^
-				 ( RSb[	(uint8)	( Y3 >>	 8 ) ] <<  8 ) ^
-				 ( RSb[	(uint8)	( Y2	   ) ]		 );
-
-	X2 = RK[2] ^ ( RSb[	(uint8)	( Y2 >>	24 ) ] << 24 ) ^
-				 ( RSb[	(uint8)	( Y1 >>	16 ) ] << 16 ) ^
-				 ( RSb[	(uint8)	( Y0 >>	 8 ) ] <<  8 ) ^
-				 ( RSb[	(uint8)	( Y3	   ) ]		 );
-
-	X3 = RK[3] ^ ( RSb[	(uint8)	( Y3 >>	24 ) ] << 24 ) ^
-				 ( RSb[	(uint8)	( Y2 >>	16 ) ] << 16 ) ^
-				 ( RSb[	(uint8)	( Y1 >>	 8 ) ] <<  8 ) ^
-				 ( RSb[	(uint8)	( Y0	   ) ]		 );
-
-	PUT_UINT32(	X0,	output,	 0 );
-	PUT_UINT32(	X1,	output,	 4 );
-	PUT_UINT32(	X2,	output,	 8 );
-	PUT_UINT32(	X3,	output,	12 );
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		SHA1 function
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-VOID	HMAC_SHA1(
-	IN	UCHAR	*text,
-	IN	UINT	text_len,
-	IN	UCHAR	*key,
-	IN	UINT	key_len,
-	IN	UCHAR	*digest)
-{
-	SHA_CTX	context;
-	UCHAR	k_ipad[65]; /* inner padding - key XORd with ipad	*/
-	UCHAR	k_opad[65]; /* outer padding - key XORd with opad	*/
-	INT		i;
-
-	// if key is longer	than 64	bytes reset	it to key=SHA1(key)
-	if (key_len	> 64)
-	{
-		SHA_CTX		 tctx;
-		SHAInit(&tctx);
-		SHAUpdate(&tctx, key, key_len);
-		SHAFinal(&tctx,	key);
-		key_len	= 20;
-	}
-	NdisZeroMemory(k_ipad, sizeof(k_ipad));
-	NdisZeroMemory(k_opad, sizeof(k_opad));
-	NdisMoveMemory(k_ipad, key,	key_len);
-	NdisMoveMemory(k_opad, key,	key_len);
-
-	// XOR key with	ipad and opad values
-	for	(i = 0;	i <	64;	i++)
-	{
-		k_ipad[i] ^= 0x36;
-		k_opad[i] ^= 0x5c;
-	}
-
-	// perform inner SHA1
-	SHAInit(&context); 						/* init context for 1st pass */
-	SHAUpdate(&context,	k_ipad,	64);		/*	start with inner pad */
-	SHAUpdate(&context,	text, text_len);	/*	then text of datagram */
-	SHAFinal(&context, digest);				/* finish up 1st pass */
-
-	//perform outer	SHA1
-	SHAInit(&context);					/* init context for 2nd pass */
-	SHAUpdate(&context,	k_opad,	64);	/*	start with outer pad */
-	SHAUpdate(&context,	digest,	20);	/*	then results of	1st	hash */
-	SHAFinal(&context, digest);			/* finish up 2nd pass */
-
-}
-
-/*
-* F(P, S, c, i) = U1 xor U2 xor ... Uc
-* U1 = PRF(P, S || Int(i))
-* U2 = PRF(P, U1)
-* Uc = PRF(P, Uc-1)
-*/
-
-void F(char *password, unsigned char *ssid, int ssidlength, int iterations, int count, unsigned char *output)
-{
-    unsigned char digest[36], digest1[SHA_DIGEST_LEN];
-    int i, j;
-
-    /* U1 = PRF(P, S || int(i)) */
-    memcpy(digest, ssid, ssidlength);
-    digest[ssidlength] = (unsigned char)((count>>24) & 0xff);
-    digest[ssidlength+1] = (unsigned char)((count>>16) & 0xff);
-    digest[ssidlength+2] = (unsigned char)((count>>8) & 0xff);
-    digest[ssidlength+3] = (unsigned char)(count & 0xff);
-    HMAC_SHA1(digest, ssidlength+4, (unsigned char*) password, (int) strlen(password), digest1); // for WPA update
-
-    /* output = U1 */
-    memcpy(output, digest1, SHA_DIGEST_LEN);
-
-    for (i = 1; i < iterations; i++)
-    {
-        /* Un = PRF(P, Un-1) */
-        HMAC_SHA1(digest1, SHA_DIGEST_LEN, (unsigned char*) password, (int) strlen(password), digest); // for WPA update
-        memcpy(digest1, digest, SHA_DIGEST_LEN);
-
-        /* output = output xor Un */
-        for (j = 0; j < SHA_DIGEST_LEN; j++)
-        {
-            output[j] ^= digest[j];
-        }
-    }
-}
-/*
-* password - ascii string up to 63 characters in length
-* ssid - octet string up to 32 octets
-* ssidlength - length of ssid in octets
-* output must be 40 octets in length and outputs 256 bits of key
-*/
-int PasswordHash(char *password, unsigned char *ssid, int ssidlength, unsigned char *output)
-{
-    if ((strlen(password) > 63) || (ssidlength > 32))
-        return 0;
-
-    F(password, ssid, ssidlength, 4096, 1, output);
-    F(password, ssid, ssidlength, 4096, 2, &output[SHA_DIGEST_LEN]);
-    return 1;
-}
-
-
diff --git a/drivers/staging/rt2860/common/mlme.c b/drivers/staging/rt2860/common/mlme.c
index 61a2a4e..9fc34a8 100644
--- a/drivers/staging/rt2860/common/mlme.c
+++ b/drivers/staging/rt2860/common/mlme.c
@@ -39,413 +39,309 @@
 #include "../rt_config.h"
 #include <stdarg.h>
 
-UCHAR	CISCO_OUI[] = {0x00, 0x40, 0x96};
+u8 CISCO_OUI[] = { 0x00, 0x40, 0x96 };
 
-UCHAR	WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
-UCHAR	RSN_OUI[] = {0x00, 0x0f, 0xac};
-UCHAR   WME_INFO_ELEM[]  = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
-UCHAR   WME_PARM_ELEM[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
-UCHAR	Ccx2QosInfo[] = {0x00, 0x40, 0x96, 0x04};
-UCHAR   RALINK_OUI[]  = {0x00, 0x0c, 0x43};
-UCHAR   BROADCOM_OUI[]  = {0x00, 0x90, 0x4c};
-UCHAR   WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
-UCHAR	PRE_N_HT_OUI[]	= {0x00, 0x90, 0x4c};
+u8 WPA_OUI[] = { 0x00, 0x50, 0xf2, 0x01 };
+u8 RSN_OUI[] = { 0x00, 0x0f, 0xac };
+u8 WME_INFO_ELEM[] = { 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01 };
+u8 WME_PARM_ELEM[] = { 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01 };
+u8 Ccx2QosInfo[] = { 0x00, 0x40, 0x96, 0x04 };
+u8 RALINK_OUI[] = { 0x00, 0x0c, 0x43 };
+u8 BROADCOM_OUI[] = { 0x00, 0x90, 0x4c };
+u8 WPS_OUI[] = { 0x00, 0x50, 0xf2, 0x04 };
+u8 PRE_N_HT_OUI[] = { 0x00, 0x90, 0x4c };
 
-UCHAR RateSwitchTable[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x11, 0x00,  0,  0,  0,						// Initial used item after association
-    0x00, 0x00,  0, 40, 101,
-    0x01, 0x00,  1, 40, 50,
-    0x02, 0x00,  2, 35, 45,
-    0x03, 0x00,  3, 20, 45,
-    0x04, 0x21,  0, 30, 50,
-    0x05, 0x21,  1, 20, 50,
-    0x06, 0x21,  2, 20, 50,
-    0x07, 0x21,  3, 15, 50,
-    0x08, 0x21,  4, 15, 30,
-    0x09, 0x21,  5, 10, 25,
-    0x0a, 0x21,  6,  8, 25,
-    0x0b, 0x21,  7,  8, 25,
-    0x0c, 0x20, 12,  15, 30,
-    0x0d, 0x20, 13,  8, 20,
-    0x0e, 0x20, 14,  8, 20,
-    0x0f, 0x20, 15,  8, 25,
-    0x10, 0x22, 15,  8, 25,
-    0x11, 0x00,  0,  0,  0,
-    0x12, 0x00,  0,  0,  0,
-    0x13, 0x00,  0,  0,  0,
-    0x14, 0x00,  0,  0,  0,
-    0x15, 0x00,  0,  0,  0,
-    0x16, 0x00,  0,  0,  0,
-    0x17, 0x00,  0,  0,  0,
-    0x18, 0x00,  0,  0,  0,
-    0x19, 0x00,  0,  0,  0,
-    0x1a, 0x00,  0,  0,  0,
-    0x1b, 0x00,  0,  0,  0,
-    0x1c, 0x00,  0,  0,  0,
-    0x1d, 0x00,  0,  0,  0,
-    0x1e, 0x00,  0,  0,  0,
-    0x1f, 0x00,  0,  0,  0,
+u8 RateSwitchTable[] = {
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+	0x11, 0x00, 0, 0, 0,	/* Initial used item after association */
+	0x00, 0x00, 0, 40, 101,
+	0x01, 0x00, 1, 40, 50,
+	0x02, 0x00, 2, 35, 45,
+	0x03, 0x00, 3, 20, 45,
+	0x04, 0x21, 0, 30, 50,
+	0x05, 0x21, 1, 20, 50,
+	0x06, 0x21, 2, 20, 50,
+	0x07, 0x21, 3, 15, 50,
+	0x08, 0x21, 4, 15, 30,
+	0x09, 0x21, 5, 10, 25,
+	0x0a, 0x21, 6, 8, 25,
+	0x0b, 0x21, 7, 8, 25,
+	0x0c, 0x20, 12, 15, 30,
+	0x0d, 0x20, 13, 8, 20,
+	0x0e, 0x20, 14, 8, 20,
+	0x0f, 0x20, 15, 8, 25,
+	0x10, 0x22, 15, 8, 25,
+	0x11, 0x00, 0, 0, 0,
+	0x12, 0x00, 0, 0, 0,
+	0x13, 0x00, 0, 0, 0,
+	0x14, 0x00, 0, 0, 0,
+	0x15, 0x00, 0, 0, 0,
+	0x16, 0x00, 0, 0, 0,
+	0x17, 0x00, 0, 0, 0,
+	0x18, 0x00, 0, 0, 0,
+	0x19, 0x00, 0, 0, 0,
+	0x1a, 0x00, 0, 0, 0,
+	0x1b, 0x00, 0, 0, 0,
+	0x1c, 0x00, 0, 0, 0,
+	0x1d, 0x00, 0, 0, 0,
+	0x1e, 0x00, 0, 0, 0,
+	0x1f, 0x00, 0, 0, 0,
 };
 
-UCHAR RateSwitchTable11B[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x04, 0x03,  0,  0,  0,						// Initial used item after association
-    0x00, 0x00,  0, 40, 101,
-    0x01, 0x00,  1, 40, 50,
-    0x02, 0x00,  2, 35, 45,
-    0x03, 0x00,  3, 20, 45,
+u8 RateSwitchTable11B[] = {
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+	0x04, 0x03, 0, 0, 0,	/* Initial used item after association */
+	0x00, 0x00, 0, 40, 101,
+	0x01, 0x00, 1, 40, 50,
+	0x02, 0x00, 2, 35, 45,
+	0x03, 0x00, 3, 20, 45,
 };
 
-UCHAR RateSwitchTable11BG[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0a, 0x00,  0,  0,  0,						// Initial used item after association
-    0x00, 0x00,  0, 40, 101,
-    0x01, 0x00,  1, 40, 50,
-    0x02, 0x00,  2, 35, 45,
-    0x03, 0x00,  3, 20, 45,
-    0x04, 0x10,  2, 20, 35,
-    0x05, 0x10,  3, 16, 35,
-    0x06, 0x10,  4, 10, 25,
-    0x07, 0x10,  5, 16, 25,
-    0x08, 0x10,  6, 10, 25,
-    0x09, 0x10,  7, 10, 13,
+u8 RateSwitchTable11BG[] = {
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+	0x0a, 0x00, 0, 0, 0,	/* Initial used item after association */
+	0x00, 0x00, 0, 40, 101,
+	0x01, 0x00, 1, 40, 50,
+	0x02, 0x00, 2, 35, 45,
+	0x03, 0x00, 3, 20, 45,
+	0x04, 0x10, 2, 20, 35,
+	0x05, 0x10, 3, 16, 35,
+	0x06, 0x10, 4, 10, 25,
+	0x07, 0x10, 5, 16, 25,
+	0x08, 0x10, 6, 10, 25,
+	0x09, 0x10, 7, 10, 13,
 };
 
-UCHAR RateSwitchTable11G[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x08, 0x00,  0,  0,  0,						// Initial used item after association
-    0x00, 0x10,  0, 20, 101,
-    0x01, 0x10,  1, 20, 35,
-    0x02, 0x10,  2, 20, 35,
-    0x03, 0x10,  3, 16, 35,
-    0x04, 0x10,  4, 10, 25,
-    0x05, 0x10,  5, 16, 25,
-    0x06, 0x10,  6, 10, 25,
-    0x07, 0x10,  7, 10, 13,
+u8 RateSwitchTable11G[] = {
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+	0x08, 0x00, 0, 0, 0,	/* Initial used item after association */
+	0x00, 0x10, 0, 20, 101,
+	0x01, 0x10, 1, 20, 35,
+	0x02, 0x10, 2, 20, 35,
+	0x03, 0x10, 3, 16, 35,
+	0x04, 0x10, 4, 10, 25,
+	0x05, 0x10, 5, 16, 25,
+	0x06, 0x10, 6, 10, 25,
+	0x07, 0x10, 7, 10, 13,
 };
 
-UCHAR RateSwitchTable11N1S[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x09, 0x00,  0,  0,  0,						// Initial used item after association
-    0x00, 0x21,  0, 30, 101,
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 15, 50,
-    0x04, 0x21,  4, 15, 30,
-    0x05, 0x21,  5, 10, 25,
-    0x06, 0x21,  6,  8, 14,
-    0x07, 0x21,  7,  8, 14,
-    0x08, 0x23,  7,  8, 14,
+u8 RateSwitchTable11N1S[] = {
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+	0x0c, 0x0a, 0, 0, 0,	/* Initial used item after association */
+	0x00, 0x00, 0, 40, 101,
+	0x01, 0x00, 1, 40, 50,
+	0x02, 0x00, 2, 25, 45,
+	0x03, 0x21, 0, 20, 35,
+	0x04, 0x21, 1, 20, 35,
+	0x05, 0x21, 2, 20, 35,
+	0x06, 0x21, 3, 15, 35,
+	0x07, 0x21, 4, 15, 30,
+	0x08, 0x21, 5, 10, 25,
+	0x09, 0x21, 6, 8, 14,
+	0x0a, 0x21, 7, 8, 14,
+	0x0b, 0x23, 7, 8, 14,
 };
 
-UCHAR RateSwitchTable11N2S[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0a, 0x00,  0,  0,  0,      // Initial used item after association
-    0x00, 0x21,  0, 30, 101,
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 15, 50,
-    0x04, 0x21,  4, 15, 30,
-    0x05, 0x20, 12,  15, 30,
-    0x06, 0x20, 13,  8, 20,
-    0x07, 0x20, 14,  8, 20,
-    0x08, 0x20, 15,  8, 25,
-    0x09, 0x22, 15,  8, 25,
+u8 RateSwitchTable11N2S[] = {
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+	0x0e, 0x0c, 0, 0, 0,	/* Initial used item after association */
+	0x00, 0x00, 0, 40, 101,
+	0x01, 0x00, 1, 40, 50,
+	0x02, 0x00, 2, 25, 45,
+	0x03, 0x21, 0, 20, 35,
+	0x04, 0x21, 1, 20, 35,
+	0x05, 0x21, 2, 20, 35,
+	0x06, 0x21, 3, 15, 35,
+	0x07, 0x21, 4, 15, 30,
+	0x08, 0x20, 11, 15, 30,
+	0x09, 0x20, 12, 15, 30,
+	0x0a, 0x20, 13, 8, 20,
+	0x0b, 0x20, 14, 8, 20,
+	0x0c, 0x20, 15, 8, 25,
+	0x0d, 0x22, 15, 8, 15,
 };
 
-UCHAR RateSwitchTable11N3S[] = {
-// Item No.	Mode	Curr-MCS	TrainUp	TrainDown	// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0a, 0x00,  0,  0,  0,      // Initial used item after association
-    0x00, 0x21,  0, 30, 101,
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 15, 50,
-    0x04, 0x21,  4, 15, 30,
-    0x05, 0x20, 12,  15, 30,
-    0x06, 0x20, 13,  8, 20,
-    0x07, 0x20, 14,  8, 20,
-    0x08, 0x20, 15,  8, 25,
-    0x09, 0x22, 15,  8, 25,
+u8 RateSwitchTable11N3S[] = {
+/* Item No.     Mode    Curr-MCS        TrainUp TrainDown       // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+	0x0b, 0x00, 0, 0, 0,	/* 0x0a, 0x00,  0,  0,  0,      // Initial used item after association */
+	0x00, 0x21, 0, 30, 101,
+	0x01, 0x21, 1, 20, 50,
+	0x02, 0x21, 2, 20, 50,
+	0x03, 0x21, 3, 15, 50,
+	0x04, 0x21, 4, 15, 30,
+	0x05, 0x20, 11, 15, 30,	/* Required by System-Alan @ 20080812 */
+	0x06, 0x20, 12, 15, 30,	/* 0x05, 0x20, 12, 15, 30, */
+	0x07, 0x20, 13, 8, 20,	/* 0x06, 0x20, 13,  8, 20, */
+	0x08, 0x20, 14, 8, 20,	/* 0x07, 0x20, 14,  8, 20, */
+	0x09, 0x20, 15, 8, 25,	/* 0x08, 0x20, 15,  8, 25, */
+	0x0a, 0x22, 15, 8, 25,	/* 0x09, 0x22, 15,  8, 25, */
 };
 
-UCHAR RateSwitchTable11N2SForABand[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0b, 0x09,  0,  0,  0,						// Initial used item after association
-    0x00, 0x21,  0, 30, 101,
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 15, 50,
-    0x04, 0x21,  4, 15, 30,
-    0x05, 0x21,  5, 15, 30,
-    0x06, 0x20, 12,  15, 30,
-    0x07, 0x20, 13,  8, 20,
-    0x08, 0x20, 14,  8, 20,
-    0x09, 0x20, 15,  8, 25,
-    0x0a, 0x22, 15,  8, 25,
+u8 RateSwitchTable11N2SForABand[] = {
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+	0x0b, 0x09, 0, 0, 0,	/* Initial used item after association */
+	0x00, 0x21, 0, 30, 101,
+	0x01, 0x21, 1, 20, 50,
+	0x02, 0x21, 2, 20, 50,
+	0x03, 0x21, 3, 15, 50,
+	0x04, 0x21, 4, 15, 30,
+	0x05, 0x21, 5, 15, 30,
+	0x06, 0x20, 12, 15, 30,
+	0x07, 0x20, 13, 8, 20,
+	0x08, 0x20, 14, 8, 20,
+	0x09, 0x20, 15, 8, 25,
+	0x0a, 0x22, 15, 8, 25,
 };
 
-UCHAR RateSwitchTable11N3SForABand[] = { // 3*3
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0b, 0x09,  0,  0,  0,						// Initial used item after association
-    0x00, 0x21,  0, 30, 101,
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 15, 50,
-    0x04, 0x21,  4, 15, 30,
-    0x05, 0x21,  5, 15, 30,
-    0x06, 0x20, 12,  15, 30,
-    0x07, 0x20, 13,  8, 20,
-    0x08, 0x20, 14,  8, 20,
-    0x09, 0x20, 15,  8, 25,
-    0x0a, 0x22, 15,  8, 25,
+u8 RateSwitchTable11N3SForABand[] = {	/* 3*3 */
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+	0x0b, 0x09, 0, 0, 0,	/* Initial used item after association */
+	0x00, 0x21, 0, 30, 101,
+	0x01, 0x21, 1, 20, 50,
+	0x02, 0x21, 2, 20, 50,
+	0x03, 0x21, 3, 15, 50,
+	0x04, 0x21, 4, 15, 30,
+	0x05, 0x21, 5, 15, 30,
+	0x06, 0x20, 12, 15, 30,
+	0x07, 0x20, 13, 8, 20,
+	0x08, 0x20, 14, 8, 20,
+	0x09, 0x20, 15, 8, 25,
+	0x0a, 0x22, 15, 8, 25,
 };
 
-UCHAR RateSwitchTable11BGN1S[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0d, 0x00,  0,  0,  0,						// Initial used item after association
-    0x00, 0x00,  0, 40, 101,
-    0x01, 0x00,  1, 40, 50,
-    0x02, 0x00,  2, 35, 45,
-    0x03, 0x00,  3, 20, 45,
-    0x04, 0x21,  0, 30,101,	//50
-    0x05, 0x21,  1, 20, 50,
-    0x06, 0x21,  2, 20, 50,
-    0x07, 0x21,  3, 15, 50,
-    0x08, 0x21,  4, 15, 30,
-    0x09, 0x21,  5, 10, 25,
-    0x0a, 0x21,  6,  8, 14,
-    0x0b, 0x21,  7,  8, 14,
-	0x0c, 0x23,  7,  8, 14,
+u8 RateSwitchTable11BGN1S[] = {
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+	0x0c, 0x0a, 0, 0, 0,	/* Initial used item after association */
+	0x00, 0x00, 0, 40, 101,
+	0x01, 0x00, 1, 40, 50,
+	0x02, 0x00, 2, 25, 45,
+	0x03, 0x21, 0, 20, 35,
+	0x04, 0x21, 1, 20, 35,
+	0x05, 0x21, 2, 20, 35,
+	0x06, 0x21, 3, 15, 35,
+	0x07, 0x21, 4, 15, 30,
+	0x08, 0x21, 5, 10, 25,
+	0x09, 0x21, 6, 8, 14,
+	0x0a, 0x21, 7, 8, 14,
+	0x0b, 0x23, 7, 8, 14,
 };
 
-UCHAR RateSwitchTable11BGN2S[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0a, 0x00,  0,  0,  0,						// Initial used item after association
-    0x00, 0x21,  0, 30,101,	//50
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 15, 50,
-    0x04, 0x21,  4, 15, 30,
-    0x05, 0x20, 12, 15, 30,
-    0x06, 0x20, 13,  8, 20,
-    0x07, 0x20, 14,  8, 20,
-    0x08, 0x20, 15,  8, 25,
-    0x09, 0x22, 15,  8, 25,
+u8 RateSwitchTable11BGN2S[] = {
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+	0x0e, 0x0c, 0, 0, 0,	/* Initial used item after association */
+	0x00, 0x00, 0, 40, 101,
+	0x01, 0x00, 1, 40, 50,
+	0x02, 0x00, 2, 25, 45,
+	0x03, 0x21, 0, 20, 35,
+	0x04, 0x21, 1, 20, 35,
+	0x05, 0x21, 2, 20, 35,
+	0x06, 0x21, 3, 15, 35,
+	0x07, 0x21, 4, 15, 30,
+	0x08, 0x20, 11, 15, 30,
+	0x09, 0x20, 12, 15, 30,
+	0x0a, 0x20, 13, 8, 20,
+	0x0b, 0x20, 14, 8, 20,
+	0x0c, 0x20, 15, 8, 25,
+	0x0d, 0x22, 15, 8, 15,
 };
 
-UCHAR RateSwitchTable11BGN3S[] = { // 3*3
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0a, 0x00,  0,  0,  0,						// Initial used item after association
-    0x00, 0x21,  0, 30,101,	//50
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 20, 50,
-    0x04, 0x21,  4, 15, 50,
-    0x05, 0x20, 20, 15, 30,
-    0x06, 0x20, 21,  8, 20,
-    0x07, 0x20, 22,  8, 20,
-    0x08, 0x20, 23,  8, 25,
-    0x09, 0x22, 23,  8, 25,
+u8 RateSwitchTable11BGN3S[] = {	/* 3*3 */
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+	0x0a, 0x00, 0, 0, 0,	/* Initial used item after association */
+	0x00, 0x21, 0, 30, 101,	/*50 */
+	0x01, 0x21, 1, 20, 50,
+	0x02, 0x21, 2, 20, 50,
+	0x03, 0x21, 3, 20, 50,
+	0x04, 0x21, 4, 15, 50,
+	0x05, 0x20, 20, 15, 30,
+	0x06, 0x20, 21, 8, 20,
+	0x07, 0x20, 22, 8, 20,
+	0x08, 0x20, 23, 8, 25,
+	0x09, 0x22, 23, 8, 25,
 };
 
-UCHAR RateSwitchTable11BGN2SForABand[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0b, 0x09,  0,  0,  0,						// Initial used item after association
-    0x00, 0x21,  0, 30,101,	//50
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 15, 50,
-    0x04, 0x21,  4, 15, 30,
-    0x05, 0x21,  5, 15, 30,
-    0x06, 0x20, 12, 15, 30,
-    0x07, 0x20, 13,  8, 20,
-    0x08, 0x20, 14,  8, 20,
-    0x09, 0x20, 15,  8, 25,
-    0x0a, 0x22, 15,  8, 25,
+u8 RateSwitchTable11BGN2SForABand[] = {
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+	0x0b, 0x09, 0, 0, 0,	/* Initial used item after association */
+	0x00, 0x21, 0, 30, 101,	/*50 */
+	0x01, 0x21, 1, 20, 50,
+	0x02, 0x21, 2, 20, 50,
+	0x03, 0x21, 3, 15, 50,
+	0x04, 0x21, 4, 15, 30,
+	0x05, 0x21, 5, 15, 30,
+	0x06, 0x20, 12, 15, 30,
+	0x07, 0x20, 13, 8, 20,
+	0x08, 0x20, 14, 8, 20,
+	0x09, 0x20, 15, 8, 25,
+	0x0a, 0x22, 15, 8, 25,
 };
 
-UCHAR RateSwitchTable11BGN3SForABand[] = { // 3*3
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0c, 0x09,  0,  0,  0,						// Initial used item after association
-    0x00, 0x21,  0, 30,101,	//50
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 15, 50,
-    0x04, 0x21,  4, 15, 30,
-    0x05, 0x21,  5, 15, 30,
-    0x06, 0x21, 12, 15, 30,
-    0x07, 0x20, 20, 15, 30,
-    0x08, 0x20, 21,  8, 20,
-    0x09, 0x20, 22,  8, 20,
-    0x0a, 0x20, 23,  8, 25,
-    0x0b, 0x22, 23,  8, 25,
+u8 RateSwitchTable11BGN3SForABand[] = {	/* 3*3 */
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+	0x0c, 0x09, 0, 0, 0,	/* Initial used item after association */
+	0x00, 0x21, 0, 30, 101,	/*50 */
+	0x01, 0x21, 1, 20, 50,
+	0x02, 0x21, 2, 20, 50,
+	0x03, 0x21, 3, 15, 50,
+	0x04, 0x21, 4, 15, 30,
+	0x05, 0x21, 5, 15, 30,
+	0x06, 0x21, 12, 15, 30,
+	0x07, 0x20, 20, 15, 30,
+	0x08, 0x20, 21, 8, 20,
+	0x09, 0x20, 22, 8, 20,
+	0x0a, 0x20, 23, 8, 25,
+	0x0b, 0x22, 23, 8, 25,
 };
 
-PUCHAR ReasonString[] = {
-	/* 0  */	 "Reserved",
-	/* 1  */	 "Unspecified Reason",
-	/* 2  */	 "Previous Auth no longer valid",
-	/* 3  */	 "STA is leaving / has left",
-	/* 4  */	 "DIS-ASSOC due to inactivity",
-	/* 5  */	 "AP unable to hanle all associations",
-	/* 6  */	 "class 2 error",
-	/* 7  */	 "class 3 error",
-	/* 8  */	 "STA is leaving / has left",
-	/* 9  */	 "require auth before assoc/re-assoc",
-	/* 10 */	 "Reserved",
-	/* 11 */	 "Reserved",
-	/* 12 */	 "Reserved",
-	/* 13 */	 "invalid IE",
-	/* 14 */	 "MIC error",
-	/* 15 */	 "4-way handshake timeout",
-	/* 16 */	 "2-way (group key) handshake timeout",
-	/* 17 */	 "4-way handshake IE diff among AssosReq/Rsp/Beacon",
-	/* 18 */
+extern u8 OfdmRateToRxwiMCS[];
+/* since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate. */
+/* otherwise the WLAN peer may not be able to receive the ACK thus downgrade its data TX rate */
+unsigned long BasicRateMask[12] =
+    { 0xfffff001 /* 1-Mbps */ , 0xfffff003 /* 2 Mbps */ , 0xfffff007 /* 5.5 */ ,
+0xfffff00f /* 11 */ ,
+	0xfffff01f /* 6 */ , 0xfffff03f /* 9 */ , 0xfffff07f /* 12 */ ,
+	    0xfffff0ff /* 18 */ ,
+	0xfffff1ff /* 24 */ , 0xfffff3ff /* 36 */ , 0xfffff7ff /* 48 */ ,
+	    0xffffffff /* 54 */
 };
 
-extern UCHAR	 OfdmRateToRxwiMCS[];
-// since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate.
-// otherwise the WLAN peer may not be able to receive the ACK thus downgrade its data TX rate
-ULONG BasicRateMask[12]				= {0xfffff001 /* 1-Mbps */, 0xfffff003 /* 2 Mbps */, 0xfffff007 /* 5.5 */, 0xfffff00f /* 11 */,
-									  0xfffff01f /* 6 */	 , 0xfffff03f /* 9 */	  , 0xfffff07f /* 12 */ , 0xfffff0ff /* 18 */,
-									  0xfffff1ff /* 24 */	 , 0xfffff3ff /* 36 */	  , 0xfffff7ff /* 48 */ , 0xffffffff /* 54 */};
+u8 BROADCAST_ADDR[MAC_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+u8 ZERO_MAC_ADDR[MAC_ADDR_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 
-UCHAR MULTICAST_ADDR[MAC_ADDR_LEN] = {0x1,  0x00, 0x00, 0x00, 0x00, 0x00};
-UCHAR BROADCAST_ADDR[MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN]  = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+/* e.g. RssiSafeLevelForTxRate[RATE_36]" means if the current RSSI is greater than */
+/*              this value, then it's quaranteed capable of operating in 36 mbps TX rate in */
+/*              clean environment. */
+/*                                                                TxRate: 1   2   5.5   11       6        9    12       18       24   36   48   54       72  100 */
+char RssiSafeLevelForTxRate[] =
+    { -92, -91, -90, -87, -88, -86, -85, -83, -81, -78, -72, -71, -40, -40 };
 
-// e.g. RssiSafeLevelForTxRate[RATE_36]" means if the current RSSI is greater than
-//		this value, then it's quaranteed capable of operating in 36 mbps TX rate in
-//		clean environment.
-//								  TxRate: 1   2   5.5	11	 6	  9    12	18	 24   36   48	54	 72  100
-CHAR RssiSafeLevelForTxRate[] ={  -92, -91, -90, -87, -88, -86, -85, -83, -81, -78, -72, -71, -40, -40 };
+u8 RateIdToMbps[] = { 1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 72, 100 };
+u16 RateIdTo500Kbps[] =
+    { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 144, 200 };
 
-UCHAR  RateIdToMbps[]	 = { 1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 72, 100};
-USHORT RateIdTo500Kbps[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 144, 200};
+u8 SsidIe = IE_SSID;
+u8 SupRateIe = IE_SUPP_RATES;
+u8 ExtRateIe = IE_EXT_SUPP_RATES;
+u8 HtCapIe = IE_HT_CAP;
+u8 AddHtInfoIe = IE_ADD_HT;
+u8 NewExtChanIe = IE_SECONDARY_CH_OFFSET;
+u8 ErpIe = IE_ERP;
+u8 DsIe = IE_DS_PARM;
+u8 TimIe = IE_TIM;
+u8 WpaIe = IE_WPA;
+u8 Wpa2Ie = IE_WPA2;
+u8 IbssIe = IE_IBSS_PARM;
 
-UCHAR  SsidIe	 = IE_SSID;
-UCHAR  SupRateIe = IE_SUPP_RATES;
-UCHAR  ExtRateIe = IE_EXT_SUPP_RATES;
-UCHAR  HtCapIe = IE_HT_CAP;
-UCHAR  AddHtInfoIe = IE_ADD_HT;
-UCHAR  NewExtChanIe = IE_SECONDARY_CH_OFFSET;
-UCHAR  ErpIe	 = IE_ERP;
-UCHAR  DsIe 	 = IE_DS_PARM;
-UCHAR  TimIe	 = IE_TIM;
-UCHAR  WpaIe	 = IE_WPA;
-UCHAR  Wpa2Ie	 = IE_WPA2;
-UCHAR  IbssIe	 = IE_IBSS_PARM;
-UCHAR  Ccx2Ie	 = IE_CCX_V2;
+extern u8 WPA_OUI[];
 
-extern UCHAR	WPA_OUI[];
+u8 SES_OUI[] = { 0x00, 0x90, 0x4c };
 
-UCHAR	SES_OUI[] = {0x00, 0x90, 0x4c};
-
-UCHAR	ZeroSsid[32] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
-
-// Reset the RFIC setting to new series
-RTMP_RF_REGS RF2850RegTable[] = {
-//		ch	 R1 		 R2 		 R3(TX0~4=0) R4
-		{1,  0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b},
-		{2,  0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f},
-		{3,  0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b},
-		{4,  0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f},
-		{5,  0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b},
-		{6,  0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f},
-		{7,  0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b},
-		{8,  0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f},
-		{9,  0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b},
-		{10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f},
-		{11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b},
-		{12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f},
-		{13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b},
-		{14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193},
-
-		// 802.11 UNI / HyperLan 2
-		{36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3},
-		{38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193},
-		{40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183},
-		{44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3},
-		{46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b},
-		{48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b},
-		{52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193},
-		{54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3},
-		{56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b},
-		{60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183},
-		{62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193},
-		{64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}, // Plugfest#4, Day4, change RFR3 left4th 9->5.
-
-		// 802.11 HyperLan 2
-		{100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783},
-
-		// 2008.04.30 modified
-		// The system team has AN to improve the EVM value
-		// for channel 102 to 108 for the RT2850/RT2750 dual band solution.
-		{102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793},
-		{104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3},
-		{108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193},
-
-		{110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183},
-		{112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b},
-		{116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3},
-		{118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193},
-		{120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183},
-		{124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193},
-		{126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}, // 0x980ed1bb->0x980ed15b required by Rory 20070927
-		{128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3},
-		{132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b},
-		{134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193},
-		{136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b},
-		{140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183},
-
-		// 802.11 UNII
-		{149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7},
-		{151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187},
-		{153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f},
-		{157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f},
-		{159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7},
-		{161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187},
-		{165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197},
-
-		// Japan
-		{184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b},
-		{188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13},
-		{192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b},
-		{196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23},
-		{208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13},
-		{212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b},
-		{216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23},
-
-		// still lack of MMAC(Japan) ch 34,38,42,46
+u8 ZeroSsid[32] =
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	    0x00, 0x00, 0x00, 0x00
 };
-UCHAR	NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(RTMP_RF_REGS));
-
-FREQUENCY_ITEM FreqItems3020[] =
-{
-	/**************************************************/
-	// ISM : 2.4 to 2.483 GHz                         //
-	/**************************************************/
-	// 11g
-	/**************************************************/
-	//-CH---N-------R---K-----------
-	{1,    241,  2,  2},
-	{2,    241,	 2,  7},
-	{3,    242,	 2,  2},
-	{4,    242,	 2,  7},
-	{5,    243,	 2,  2},
-	{6,    243,	 2,  7},
-	{7,    244,	 2,  2},
-	{8,    244,	 2,  7},
-	{9,    245,	 2,  2},
-	{10,   245,	 2,  7},
-	{11,   246,	 2,  2},
-	{12,   246,	 2,  7},
-	{13,   247,	 2,  2},
-	{14,   248,	 2,  4},
-};
-UCHAR	NUM_OF_3020_CHNL=(sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM));
 
 /*
 	==========================================================================
@@ -460,17 +356,15 @@
 
 	==========================================================================
 */
-NDIS_STATUS MlmeInit(
-	IN PRTMP_ADAPTER pAd)
+int MlmeInit(struct rt_rtmp_adapter *pAd)
 {
-	NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+	int Status = NDIS_STATUS_SUCCESS;
 
 	DBGPRINT(RT_DEBUG_TRACE, ("--> MLME Initialize\n"));
 
-	do
-	{
+	do {
 		Status = MlmeQueueInit(&pAd->Mlme.Queue);
-		if(Status != NDIS_STATUS_SUCCESS)
+		if (Status != NDIS_STATUS_SUCCESS)
 			break;
 
 		pAd->Mlme.bRunning = FALSE;
@@ -479,40 +373,65 @@
 		{
 			BssTableInit(&pAd->ScanTab);
 
-			// init STA state machines
-			AssocStateMachineInit(pAd, &pAd->Mlme.AssocMachine, pAd->Mlme.AssocFunc);
-			AuthStateMachineInit(pAd, &pAd->Mlme.AuthMachine, pAd->Mlme.AuthFunc);
-			AuthRspStateMachineInit(pAd, &pAd->Mlme.AuthRspMachine, pAd->Mlme.AuthRspFunc);
-			SyncStateMachineInit(pAd, &pAd->Mlme.SyncMachine, pAd->Mlme.SyncFunc);
-			WpaPskStateMachineInit(pAd, &pAd->Mlme.WpaPskMachine, pAd->Mlme.WpaPskFunc);
-			AironetStateMachineInit(pAd, &pAd->Mlme.AironetMachine, pAd->Mlme.AironetFunc);
+			/* init STA state machines */
+			AssocStateMachineInit(pAd, &pAd->Mlme.AssocMachine,
+					      pAd->Mlme.AssocFunc);
+			AuthStateMachineInit(pAd, &pAd->Mlme.AuthMachine,
+					     pAd->Mlme.AuthFunc);
+			AuthRspStateMachineInit(pAd, &pAd->Mlme.AuthRspMachine,
+						pAd->Mlme.AuthRspFunc);
+			SyncStateMachineInit(pAd, &pAd->Mlme.SyncMachine,
+					     pAd->Mlme.SyncFunc);
 
-			// Since we are using switch/case to implement it, the init is different from the above
-			// state machine init
+			/* Since we are using switch/case to implement it, the init is different from the above */
+			/* state machine init */
 			MlmeCntlInit(pAd, &pAd->Mlme.CntlMachine, NULL);
 		}
 
-		ActionStateMachineInit(pAd, &pAd->Mlme.ActMachine, pAd->Mlme.ActFunc);
+		WpaStateMachineInit(pAd, &pAd->Mlme.WpaMachine,
+				    pAd->Mlme.WpaFunc);
 
-		// Init mlme periodic timer
-		RTMPInitTimer(pAd, &pAd->Mlme.PeriodicTimer, GET_TIMER_FUNCTION(MlmePeriodicExec), pAd, TRUE);
+		ActionStateMachineInit(pAd, &pAd->Mlme.ActMachine,
+				       pAd->Mlme.ActFunc);
 
-		// Set mlme periodic timer
+		/* Init mlme periodic timer */
+		RTMPInitTimer(pAd, &pAd->Mlme.PeriodicTimer,
+			      GET_TIMER_FUNCTION(MlmePeriodicExec), pAd, TRUE);
+
+		/* Set mlme periodic timer */
 		RTMPSetTimer(&pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
 
-		// software-based RX Antenna diversity
-		RTMPInitTimer(pAd, &pAd->Mlme.RxAntEvalTimer, GET_TIMER_FUNCTION(AsicRxAntEvalTimeout), pAd, FALSE);
+		/* software-based RX Antenna diversity */
+		RTMPInitTimer(pAd, &pAd->Mlme.RxAntEvalTimer,
+			      GET_TIMER_FUNCTION(AsicRxAntEvalTimeout), pAd,
+			      FALSE);
 
-#ifdef RT2860
 		{
-	        if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
-	        {
-	            // only PCIe cards need these two timers
-	    		RTMPInitTimer(pAd, &pAd->Mlme.PsPollTimer, GET_TIMER_FUNCTION(PsPollWakeExec), pAd, FALSE);
-	    		RTMPInitTimer(pAd, &pAd->Mlme.RadioOnOffTimer, GET_TIMER_FUNCTION(RadioOnExec), pAd, FALSE);
-	        }
+#ifdef RTMP_PCI_SUPPORT
+			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
+				/* only PCIe cards need these two timers */
+				RTMPInitTimer(pAd, &pAd->Mlme.PsPollTimer,
+					      GET_TIMER_FUNCTION
+					      (PsPollWakeExec), pAd, FALSE);
+				RTMPInitTimer(pAd, &pAd->Mlme.RadioOnOffTimer,
+					      GET_TIMER_FUNCTION(RadioOnExec),
+					      pAd, FALSE);
+			}
+#endif /* RTMP_PCI_SUPPORT // */
+
+			RTMPInitTimer(pAd, &pAd->Mlme.LinkDownTimer,
+				      GET_TIMER_FUNCTION(LinkDownExec), pAd,
+				      FALSE);
+
+#ifdef RTMP_MAC_USB
+			RTMPInitTimer(pAd, &pAd->Mlme.AutoWakeupTimer,
+				      GET_TIMER_FUNCTION
+				      (RtmpUsbStaAsicForceWakeupTimeout), pAd,
+				      FALSE);
+			pAd->Mlme.AutoWakeupTimerRunning = FALSE;
+#endif /* RTMP_MAC_USB // */
 		}
-#endif
+
 	} while (FALSE);
 
 	DBGPRINT(RT_DEBUG_TRACE, ("<-- MLME Initialize\n"));
@@ -534,93 +453,102 @@
 
 	==========================================================================
  */
-VOID MlmeHandler(
-	IN PRTMP_ADAPTER pAd)
+void MlmeHandler(struct rt_rtmp_adapter *pAd)
 {
-	MLME_QUEUE_ELEM 	   *Elem = NULL;
+	struct rt_mlme_queue_elem *Elem = NULL;
 
-	// Only accept MLME and Frame from peer side, no other (control/data) frame should
-	// get into this state machine
+	/* Only accept MLME and Frame from peer side, no other (control/data) frame should */
+	/* get into this state machine */
 
 	NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
-	if(pAd->Mlme.bRunning)
-	{
+	if (pAd->Mlme.bRunning) {
 		NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
 		return;
-	}
-	else
-	{
+	} else {
 		pAd->Mlme.bRunning = TRUE;
 	}
 	NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
 
-	while (!MlmeQueueEmpty(&pAd->Mlme.Queue))
-	{
+	while (!MlmeQueueEmpty(&pAd->Mlme.Queue)) {
 		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS) ||
-			RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
-			RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("Device Halted or Removed or MlmeRest, exit MlmeHandler! (queue num = %ld)\n", pAd->Mlme.Queue.Num));
+		    RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
+		    RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("Device Halted or Removed or MlmeRest, exit MlmeHandler! (queue num = %ld)\n",
+				  pAd->Mlme.Queue.Num));
 			break;
 		}
-
-		//From message type, determine which state machine I should drive
-		if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
-		{
-#ifdef RT2870
-			if (Elem->MsgType == MT2_RESET_CONF)
-			{
-				DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! reset MLME state machine !!!\n"));
+		/*From message type, determine which state machine I should drive */
+		if (MlmeDequeue(&pAd->Mlme.Queue, &Elem)) {
+#ifdef RTMP_MAC_USB
+			if (Elem->MsgType == MT2_RESET_CONF) {
+				DBGPRINT_RAW(RT_DEBUG_TRACE,
+					     ("reset MLME state machine!\n"));
 				MlmeRestartStateMachine(pAd);
 				Elem->Occupied = FALSE;
 				Elem->MsgLen = 0;
 				continue;
 			}
-#endif // RT2870 //
+#endif /* RTMP_MAC_USB // */
 
-			// if dequeue success
-			switch (Elem->Machine)
-			{
-				// STA state machines
-				case ASSOC_STATE_MACHINE:
-					StateMachinePerformAction(pAd, &pAd->Mlme.AssocMachine, Elem);
-					break;
-				case AUTH_STATE_MACHINE:
-					StateMachinePerformAction(pAd, &pAd->Mlme.AuthMachine, Elem);
-					break;
-				case AUTH_RSP_STATE_MACHINE:
-					StateMachinePerformAction(pAd, &pAd->Mlme.AuthRspMachine, Elem);
-					break;
-				case SYNC_STATE_MACHINE:
-					StateMachinePerformAction(pAd, &pAd->Mlme.SyncMachine, Elem);
-					break;
-				case MLME_CNTL_STATE_MACHINE:
-					MlmeCntlMachinePerformAction(pAd, &pAd->Mlme.CntlMachine, Elem);
-					break;
-				case WPA_PSK_STATE_MACHINE:
-					StateMachinePerformAction(pAd, &pAd->Mlme.WpaPskMachine, Elem);
-					break;
-				case AIRONET_STATE_MACHINE:
-					StateMachinePerformAction(pAd, &pAd->Mlme.AironetMachine, Elem);
-					break;
-				case ACTION_STATE_MACHINE:
-					StateMachinePerformAction(pAd, &pAd->Mlme.ActMachine, Elem);
-					break;
+			/* if dequeue success */
+			switch (Elem->Machine) {
+				/* STA state machines */
+			case ASSOC_STATE_MACHINE:
+				StateMachinePerformAction(pAd,
+							  &pAd->Mlme.
+							  AssocMachine, Elem);
+				break;
+			case AUTH_STATE_MACHINE:
+				StateMachinePerformAction(pAd,
+							  &pAd->Mlme.
+							  AuthMachine, Elem);
+				break;
+			case AUTH_RSP_STATE_MACHINE:
+				StateMachinePerformAction(pAd,
+							  &pAd->Mlme.
+							  AuthRspMachine, Elem);
+				break;
+			case SYNC_STATE_MACHINE:
+				StateMachinePerformAction(pAd,
+							  &pAd->Mlme.
+							  SyncMachine, Elem);
+				break;
+			case MLME_CNTL_STATE_MACHINE:
+				MlmeCntlMachinePerformAction(pAd,
+							     &pAd->Mlme.
+							     CntlMachine, Elem);
+				break;
+			case WPA_PSK_STATE_MACHINE:
+				StateMachinePerformAction(pAd,
+							  &pAd->Mlme.
+							  WpaPskMachine, Elem);
+				break;
 
+			case ACTION_STATE_MACHINE:
+				StateMachinePerformAction(pAd,
+							  &pAd->Mlme.ActMachine,
+							  Elem);
+				break;
 
+			case WPA_STATE_MACHINE:
+				StateMachinePerformAction(pAd,
+							  &pAd->Mlme.WpaMachine,
+							  Elem);
+				break;
 
+			default:
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("ERROR: Illegal machine %ld in MlmeHandler()\n",
+					  Elem->Machine));
+				break;
+			}	/* end of switch */
 
-				default:
-					DBGPRINT(RT_DEBUG_TRACE, ("ERROR: Illegal machine %ld in MlmeHandler()\n", Elem->Machine));
-					break;
-			} // end of switch
-
-			// free MLME element
+			/* free MLME element */
 			Elem->Occupied = FALSE;
 			Elem->MsgLen = 0;
 
-		}
-		else {
+		} else {
 			DBGPRINT_ERR(("MlmeHandler: MlmeQueue empty\n"));
 		}
 	}
@@ -643,73 +571,67 @@
 
 	==========================================================================
  */
-VOID MlmeHalt(
-	IN PRTMP_ADAPTER pAd)
+void MlmeHalt(struct rt_rtmp_adapter *pAd)
 {
-	BOOLEAN 	  Cancelled;
-#ifdef RT3070
-	UINT32		TxPinCfg = 0x00050F0F;
-#endif // RT3070 //
+	BOOLEAN Cancelled;
 
 	DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeHalt\n"));
 
-	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
-	{
-		// disable BEACON generation and other BEACON related hardware timers
+	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
+		/* disable BEACON generation and other BEACON related hardware timers */
 		AsicDisableSync(pAd);
 	}
 
 	{
-		// Cancel pending timers
-		RTMPCancelTimer(&pAd->MlmeAux.AssocTimer,		&Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer,		&Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer,	&Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.AuthTimer,		&Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer,		&Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.ScanTimer,		&Cancelled);
-#ifdef RT2860
-	    if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
-	    {
-	   	    RTMPCancelTimer(&pAd->Mlme.PsPollTimer,		&Cancelled);
-		    RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer,		&Cancelled);
+		/* Cancel pending timers */
+		RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
+
+#ifdef RTMP_MAC_PCI
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
+		    && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
+			RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
+			RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
 		}
-#endif
+#endif /* RTMP_MAC_PCI // */
+
+		RTMPCancelTimer(&pAd->Mlme.LinkDownTimer, &Cancelled);
+
+#ifdef RTMP_MAC_USB
+		RTMPCancelTimer(&pAd->Mlme.AutoWakeupTimer, &Cancelled);
+#endif /* RTMP_MAC_USB // */
 	}
 
-	RTMPCancelTimer(&pAd->Mlme.PeriodicTimer,		&Cancelled);
-	RTMPCancelTimer(&pAd->Mlme.RxAntEvalTimer,		&Cancelled);
+	RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
+	RTMPCancelTimer(&pAd->Mlme.RxAntEvalTimer, &Cancelled);
 
+	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
+		struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
 
-
-	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
-	{
-		// Set LED
+		/* Set LED */
 		RTMPSetLED(pAd, LED_HALT);
-        RTMPSetSignalLED(pAd, -100);	// Force signal strength Led to be turned off, firmware is not done it.
-#ifdef RT2870
-        {
-            LED_CFG_STRUC LedCfg;
-            RTMP_IO_READ32(pAd, LED_CFG, &LedCfg.word);
-            LedCfg.field.LedPolar = 0;
-            LedCfg.field.RLedMode = 0;
-            LedCfg.field.GLedMode = 0;
-            LedCfg.field.YLedMode = 0;
-            RTMP_IO_WRITE32(pAd, LED_CFG, LedCfg.word);
-        }
-#endif // RT2870 //
-#ifdef RT3070
-		//
-		// Turn off LNA_PE
-		//
-		if (IS_RT3070(pAd) || IS_RT3071(pAd))
+		RTMPSetSignalLED(pAd, -100);	/* Force signal strength Led to be turned off, firmware is not done it. */
+#ifdef RTMP_MAC_USB
 		{
-			TxPinCfg &= 0xFFFFF0F0;
-			RTUSBWriteMACRegister(pAd, TX_PIN_CFG, TxPinCfg);
+			LED_CFG_STRUC LedCfg;
+			RTMP_IO_READ32(pAd, LED_CFG, &LedCfg.word);
+			LedCfg.field.LedPolar = 0;
+			LedCfg.field.RLedMode = 0;
+			LedCfg.field.GLedMode = 0;
+			LedCfg.field.YLedMode = 0;
+			RTMP_IO_WRITE32(pAd, LED_CFG, LedCfg.word);
 		}
-#endif // RT3070 //
+#endif /* RTMP_MAC_USB // */
+
+		if (pChipOps->AsicHaltAction)
+			pChipOps->AsicHaltAction(pAd);
 	}
 
-	RTMPusecDelay(5000);    //  5 msec to gurantee Ant Diversity timer canceled
+	RTMPusecDelay(5000);	/*  5 msec to gurantee Ant Diversity timer canceled */
 
 	MlmeQueueDestroy(&pAd->Mlme.Queue);
 	NdisFreeSpinLock(&pAd->Mlme.TaskLock);
@@ -717,11 +639,11 @@
 	DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeHalt\n"));
 }
 
-VOID MlmeResetRalinkCounters(
-	IN  PRTMP_ADAPTER   pAd)
+void MlmeResetRalinkCounters(struct rt_rtmp_adapter *pAd)
 {
-	pAd->RalinkCounters.LastOneSecRxOkDataCnt = pAd->RalinkCounters.OneSecRxOkDataCnt;
-	// clear all OneSecxxx counters.
+	pAd->RalinkCounters.LastOneSecRxOkDataCnt =
+	    pAd->RalinkCounters.OneSecRxOkDataCnt;
+	/* clear all OneSecxxx counters. */
 	pAd->RalinkCounters.OneSecBeaconSentCnt = 0;
 	pAd->RalinkCounters.OneSecFalseCCACnt = 0;
 	pAd->RalinkCounters.OneSecRxFcsErrCnt = 0;
@@ -730,8 +652,10 @@
 	pAd->RalinkCounters.OneSecTxNoRetryOkCount = 0;
 	pAd->RalinkCounters.OneSecTxRetryOkCount = 0;
 	pAd->RalinkCounters.OneSecRxOkDataCnt = 0;
+	pAd->RalinkCounters.OneSecReceivedByteCount = 0;
+	pAd->RalinkCounters.OneSecTransmittedByteCount = 0;
 
-	// TODO: for debug only. to be removed
+	/* TODO: for debug only. to be removed */
 	pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] = 0;
 	pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BK] = 0;
 	pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VI] = 0;
@@ -748,9 +672,6 @@
 	return;
 }
 
-unsigned long rx_AMSDU;
-unsigned long rx_Total;
-
 /*
 	==========================================================================
 	Description:
@@ -767,229 +688,188 @@
 
 	==========================================================================
  */
-#define ADHOC_BEACON_LOST_TIME		(8*OS_HZ)  // 8 sec
-VOID MlmePeriodicExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3)
+#define ADHOC_BEACON_LOST_TIME		(8*OS_HZ)	/* 8 sec */
+void MlmePeriodicExec(void *SystemSpecific1,
+		      void *FunctionContext,
+		      void *SystemSpecific2, void *SystemSpecific3)
 {
-	ULONG			TxTotalCnt;
-	PRTMP_ADAPTER	pAd = (RTMP_ADAPTER *)FunctionContext;
+	unsigned long TxTotalCnt;
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
 
-#ifdef RT2860
-	//Baron 2008/07/10
-	//printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
-	//If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
-	//If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1.
-	if(pAd->StaCfg.WepStatus<2)
+#ifdef RTMP_MAC_PCI
 	{
-		pAd->StaCfg.WpaSupplicantUP = 0;
-	}
-	else
-	{
-		pAd->StaCfg.WpaSupplicantUP = 1;
-	}
+		/* If Hardware controlled Radio enabled, we have to check GPIO pin2 every 2 second. */
+		/* Move code to here, because following code will return when radio is off */
+		if ((pAd->Mlme.PeriodicRound % (MLME_TASK_EXEC_MULTIPLE * 2) ==
+		     0) && (pAd->StaCfg.bHardwareRadio == TRUE)
+		    && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+		    && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
+		    /*&&(pAd->bPCIclkOff == FALSE) */
+		    ) {
+			u32 data = 0;
 
-	{
-	    // If Hardware controlled Radio enabled, we have to check GPIO pin2 every 2 second.
-		// Move code to here, because following code will return when radio is off
-		if ((pAd->Mlme.PeriodicRound % (MLME_TASK_EXEC_MULTIPLE * 2) == 0) &&
-			(pAd->StaCfg.bHardwareRadio == TRUE) &&
-			(RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
-		{
-			UINT32				data = 0;
+			/* Read GPIO pin2 as Hardware controlled radio state */
+#ifndef RT3090
+			RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
+#endif /* RT3090 // */
+/*KH(PCIE PS):Added based on Jane<-- */
+#ifdef RT3090
+/* Read GPIO pin2 as Hardware controlled radio state */
+/* We need to Read GPIO if HW said so no mater what advance power saving */
+			if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd))
+			    &&
+			    (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
+			    && (pAd->StaCfg.PSControl.field.EnablePSinIdle ==
+				TRUE)) {
+				/* Want to make sure device goes to L0 state before reading register. */
+				RTMPPCIeLinkCtrlValueRestore(pAd, 0);
+				RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data);
+				RTMPPCIeLinkCtrlSetting(pAd, 3);
+			} else
+				RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data);
+#endif /* RT3090 // */
+/*KH(PCIE PS):Added based on Jane--> */
 
-			// Read GPIO pin2 as Hardware controlled radio state
-			RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data);
-			if (data & 0x04)
-			{
+			if (data & 0x04) {
 				pAd->StaCfg.bHwRadio = TRUE;
-			}
-			else
-			{
+			} else {
 				pAd->StaCfg.bHwRadio = FALSE;
 			}
-			if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
-			{
-				pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
-				if (pAd->StaCfg.bRadio == TRUE)
-				{
+			if (pAd->StaCfg.bRadio !=
+			    (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio)) {
+				pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio
+						      && pAd->StaCfg.bSwRadio);
+				if (pAd->StaCfg.bRadio == TRUE) {
 					MlmeRadioOn(pAd);
-					// Update extra information
+					/* Update extra information */
 					pAd->ExtraInfo = EXTRA_INFO_CLEAR;
-				}
-				else
-				{
+				} else {
 					MlmeRadioOff(pAd);
-					// Update extra information
+					/* Update extra information */
 					pAd->ExtraInfo = HW_RADIO_OFF;
 				}
 			}
 		}
 	}
-#endif /* RT2860 */
+#endif /* RTMP_MAC_PCI // */
 
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
+	/* Do nothing if the driver is starting halt state. */
+	/* This might happen when timer already been fired before cancel timer with mlmehalt */
 	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_HALT_IN_PROGRESS |
-								fRTMP_ADAPTER_RADIO_OFF |
-								fRTMP_ADAPTER_RADIO_MEASUREMENT |
-								fRTMP_ADAPTER_RESET_IN_PROGRESS))))
+				  fRTMP_ADAPTER_RADIO_OFF |
+				  fRTMP_ADAPTER_RADIO_MEASUREMENT |
+				  fRTMP_ADAPTER_RESET_IN_PROGRESS))))
 		return;
 
-#ifdef RT2860
-	{
-		if ((pAd->RalinkCounters.LastReceivedByteCount == pAd->RalinkCounters.ReceivedByteCount) && (pAd->StaCfg.bRadio == TRUE))
-		{
-			// If ReceiveByteCount doesn't change,  increase SameRxByteCount by 1.
-			pAd->SameRxByteCount++;
-		}
-		else
-			pAd->SameRxByteCount = 0;
-
-		// If after BBP, still not work...need to check to reset PBF&MAC.
-		if (pAd->SameRxByteCount == 702)
-		{
-			pAd->SameRxByteCount = 0;
-			AsicResetPBF(pAd);
-			AsicResetMAC(pAd);
-		}
-
-		// If SameRxByteCount keeps happens for 2 second in infra mode, or for 60 seconds in idle mode.
-		if (((INFRA_ON(pAd)) && (pAd->SameRxByteCount > 20)) || ((IDLE_ON(pAd)) && (pAd->SameRxByteCount > 600)))
-		{
-			if ((pAd->StaCfg.bRadio == TRUE) && (pAd->SameRxByteCount < 700))
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("--->  SameRxByteCount = %lu !!!!!!!!!!!!!!! \n", pAd->SameRxByteCount));
-				pAd->SameRxByteCount = 700;
-				AsicResetBBP(pAd);
-			}
-		}
-
-		// Update lastReceiveByteCount.
-		pAd->RalinkCounters.LastReceivedByteCount = pAd->RalinkCounters.ReceivedByteCount;
-
-		if ((pAd->CheckDmaBusyCount > 3) && (IDLE_ON(pAd)))
-		{
-			pAd->CheckDmaBusyCount = 0;
-			AsicResetFromDMABusy(pAd);
-		}
-	}
-#endif /* RT2860 */
-	RT28XX_MLME_PRE_SANITY_CHECK(pAd);
+	RTMP_MLME_PRE_SANITY_CHECK(pAd);
 
 	{
-		// Do nothing if monitor mode is on
+		/* Do nothing if monitor mode is on */
 		if (MONITOR_ON(pAd))
 			return;
 
-		if (pAd->Mlme.PeriodicRound & 0x1)
-		{
-			// This is the fix for wifi 11n extension channel overlapping test case.  for 2860D
+		if (pAd->Mlme.PeriodicRound & 0x1) {
+			/* This is the fix for wifi 11n extension channel overlapping test case.  for 2860D */
 			if (((pAd->MACVersion & 0xffff) == 0x0101) &&
-				(STA_TGN_WIFI_ON(pAd)) &&
-				(pAd->CommonCfg.IOTestParm.bToggle == FALSE))
-
-				{
-					RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x24Bf);
-					pAd->CommonCfg.IOTestParm.bToggle = TRUE;
-				}
-				else if ((STA_TGN_WIFI_ON(pAd)) &&
-						((pAd->MACVersion & 0xffff) == 0x0101))
-				{
-					RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x243f);
-					pAd->CommonCfg.IOTestParm.bToggle = FALSE;
-				}
+			    (STA_TGN_WIFI_ON(pAd)) &&
+			    (pAd->CommonCfg.IOTestParm.bToggle == FALSE))
+			{
+				RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x24Bf);
+				pAd->CommonCfg.IOTestParm.bToggle = TRUE;
+			} else if ((STA_TGN_WIFI_ON(pAd)) &&
+				   ((pAd->MACVersion & 0xffff) == 0x0101)) {
+				RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x243f);
+				pAd->CommonCfg.IOTestParm.bToggle = FALSE;
+			}
 		}
 	}
 
 	pAd->bUpdateBcnCntDone = FALSE;
 
-//	RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3);
-	pAd->Mlme.PeriodicRound ++;
+/*      RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3); */
+	pAd->Mlme.PeriodicRound++;
 
-#ifdef RT3070
-	// execute every 100ms, update the Tx FIFO Cnt for update Tx Rate.
+#ifdef RTMP_MAC_USB
+	/* execute every 100ms, update the Tx FIFO Cnt for update Tx Rate. */
 	NICUpdateFifoStaCounters(pAd);
-#endif // RT3070 //
-	// execute every 500ms
-	if ((pAd->Mlme.PeriodicRound % 5 == 0) && RTMPAutoRateSwitchCheck(pAd)/*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))*/)
+#endif /* RTMP_MAC_USB // */
+
+	/* execute every 500ms */
+	if ((pAd->Mlme.PeriodicRound % 5 == 0)
+	    && RTMPAutoRateSwitchCheck(pAd)
+	    /*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */ )
 	{
-		// perform dynamic tx rate switching based on past TX history
+		/* perform dynamic tx rate switching based on past TX history */
 		{
-			if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
-					)
-				&& (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)))
+			if ((OPSTATUS_TEST_FLAG
+			     (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
+			    )
+			    && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)))
 				MlmeDynamicTxRateSwitching(pAd);
 		}
 	}
+	/* Normal 1 second Mlme PeriodicExec. */
+	if (pAd->Mlme.PeriodicRound % MLME_TASK_EXEC_MULTIPLE == 0) {
+		pAd->Mlme.OneSecPeriodicRound++;
 
-	// Normal 1 second Mlme PeriodicExec.
-	if (pAd->Mlme.PeriodicRound %MLME_TASK_EXEC_MULTIPLE == 0)
-	{
-                pAd->Mlme.OneSecPeriodicRound ++;
+		/*ORIBATimerTimeout(pAd); */
 
-		if (rx_Total)
-		{
-
-			// reset counters
-			rx_AMSDU = 0;
-			rx_Total = 0;
-		}
-
-		// Media status changed, report to NDIS
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE))
-		{
+		/* Media status changed, report to NDIS */
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE)) {
 			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
-			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-			{
-				pAd->IndicateMediaState = NdisMediaStateConnected;
+			if (OPSTATUS_TEST_FLAG
+			    (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
+				pAd->IndicateMediaState =
+				    NdisMediaStateConnected;
 				RTMP_IndicateMediaState(pAd);
 
-			}
-			else
-			{
-				pAd->IndicateMediaState = NdisMediaStateDisconnected;
+			} else {
+				pAd->IndicateMediaState =
+				    NdisMediaStateDisconnected;
 				RTMP_IndicateMediaState(pAd);
 			}
 		}
 
 		NdisGetSystemUpTime(&pAd->Mlme.Now32);
 
-		// add the most up-to-date h/w raw counters into software variable, so that
-		// the dynamic tuning mechanism below are based on most up-to-date information
+		/* add the most up-to-date h/w raw counters into software variable, so that */
+		/* the dynamic tuning mechanism below are based on most up-to-date information */
 		NICUpdateRawCounters(pAd);
 
-#ifdef RT2870
-		RT2870_WatchDog(pAd);
-#endif // RT2870 //
+#ifdef RTMP_MAC_USB
+		RTUSBWatchDog(pAd);
+#endif /* RTMP_MAC_USB // */
 
-   		// Need statistics after read counter. So put after NICUpdateRawCounters
+		/* Need statistics after read counter. So put after NICUpdateRawCounters */
 		ORIBATimerTimeout(pAd);
 
-		// The time period for checking antenna is according to traffic
-		if (pAd->Mlme.bEnableAutoAntennaCheck)
-		{
-			TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
-							 pAd->RalinkCounters.OneSecTxRetryOkCount +
-							 pAd->RalinkCounters.OneSecTxFailCount;
+		/* if MGMT RING is full more than twice within 1 second, we consider there's */
+		/* a hardware problem stucking the TX path. In this case, try a hardware reset */
+		/* to recover the system */
+		/*      if (pAd->RalinkCounters.MgmtRingFullCount >= 2) */
+		/*              RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HARDWARE_ERROR); */
+		/*      else */
+		/*              pAd->RalinkCounters.MgmtRingFullCount = 0; */
 
-			// dynamic adjust antenna evaluation period according to the traffic
-			if (TxTotalCnt > 50)
-			{
-				if (pAd->Mlme.OneSecPeriodicRound % 10 == 0)
-				{
-					AsicEvaluateRxAnt(pAd);
-				}
-			}
-			else
-			{
-				if (pAd->Mlme.OneSecPeriodicRound % 3 == 0)
-				{
-					AsicEvaluateRxAnt(pAd);
+		/* The time period for checking antenna is according to traffic */
+		{
+			if (pAd->Mlme.bEnableAutoAntennaCheck) {
+				TxTotalCnt =
+				    pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+				    pAd->RalinkCounters.OneSecTxRetryOkCount +
+				    pAd->RalinkCounters.OneSecTxFailCount;
+
+				/* dynamic adjust antenna evaluation period according to the traffic */
+				if (TxTotalCnt > 50) {
+					if (pAd->Mlme.OneSecPeriodicRound %
+					    10 == 0) {
+						AsicEvaluateRxAnt(pAd);
+					}
+				} else {
+					if (pAd->Mlme.OneSecPeriodicRound % 3 ==
+					    0) {
+						AsicEvaluateRxAnt(pAd);
+					}
 				}
 			}
 		}
@@ -999,382 +879,40 @@
 		MlmeResetRalinkCounters(pAd);
 
 		{
-#ifdef RT2860
-			if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->bPCIclkOff == FALSE))
-#endif
+#ifdef RTMP_MAC_PCI
+			if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)
+			    && (pAd->bPCIclkOff == FALSE))
+#endif /* RTMP_MAC_PCI // */
 			{
-				// When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock
-				// and sending CTS-to-self over and over.
-				// Software Patch Solution:
-				// 1. Polling debug state register 0x10F4 every one second.
-				// 2. If in 0x10F4 the ((bit29==1) && (bit7==1)) OR ((bit29==1) && (bit5==1)), it means the deadlock has occurred.
-				// 3. If the deadlock occurred, reset MAC/BBP by setting 0x1004 to 0x0001 for a while then setting it back to 0x000C again.
+				/* When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock */
+				/* and sending CTS-to-self over and over. */
+				/* Software Patch Solution: */
+				/* 1. Polling debug state register 0x10F4 every one second. */
+				/* 2. If in 0x10F4 the ((bit29==1) && (bit7==1)) OR ((bit29==1) && (bit5==1)), it means the deadlock has occurred. */
+				/* 3. If the deadlock occurred, reset MAC/BBP by setting 0x1004 to 0x0001 for a while then setting it back to 0x000C again. */
 
-				UINT32	MacReg = 0;
+				u32 MacReg = 0;
 
 				RTMP_IO_READ32(pAd, 0x10F4, &MacReg);
-				if (((MacReg & 0x20000000) && (MacReg & 0x80)) || ((MacReg & 0x20000000) && (MacReg & 0x20)))
-				{
+				if (((MacReg & 0x20000000) && (MacReg & 0x80))
+				    || ((MacReg & 0x20000000)
+					&& (MacReg & 0x20))) {
 					RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
 					RTMPusecDelay(1);
 					RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xC);
 
-					DBGPRINT(RT_DEBUG_WARN,("Warning, MAC specific condition occurs \n"));
+					DBGPRINT(RT_DEBUG_WARN,
+						 ("Warning, MAC specific condition occurs \n"));
 				}
 			}
 		}
 
-		RT28XX_MLME_HANDLER(pAd);
+		RTMP_MLME_HANDLER(pAd);
 	}
 
 	pAd->bUpdateBcnCntDone = FALSE;
 }
 
-VOID STAMlmePeriodicExec(
-	PRTMP_ADAPTER pAd)
-{
-#ifdef RT2860
-	ULONG			    TxTotalCnt;
-#endif
-#ifdef RT2870
-	ULONG	TxTotalCnt;
-	int 	i;
-#endif
-
-    if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)
-    {
-    	// WPA MIC error should block association attempt for 60 seconds
-    	if (pAd->StaCfg.bBlockAssoc && (pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ) < pAd->Mlme.Now32))
-    		pAd->StaCfg.bBlockAssoc = FALSE;
-    }
-
-#ifdef RT2860
-	//Baron 2008/07/10
-	//printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
-	//If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
-	//If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1.
-	if(pAd->StaCfg.WepStatus<2)
-	{
-		pAd->StaCfg.WpaSupplicantUP = 0;
-	}
-	else
-	{
-		pAd->StaCfg.WpaSupplicantUP = 1;
-	}
-#endif
-
-    if ((pAd->PreMediaState != pAd->IndicateMediaState) && (pAd->CommonCfg.bWirelessEvent))
-	{
-		if (pAd->IndicateMediaState == NdisMediaStateConnected)
-		{
-			RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-		}
-		pAd->PreMediaState = pAd->IndicateMediaState;
-	}
-
-#ifdef RT2860
-	if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd)) &&
-        (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
-		(pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE) &&
-		(pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
-		(RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP)) &&
-		(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
-	{
-		RT28xxPciAsicRadioOff(pAd, GUI_IDLE_POWER_SAVE, 0);
-	}
-#endif
-
-
-
-   	AsicStaBbpTuning(pAd);
-
-	TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
-					 pAd->RalinkCounters.OneSecTxRetryOkCount +
-					 pAd->RalinkCounters.OneSecTxFailCount;
-
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-	{
-		// update channel quality for Roaming and UI LinkQuality display
-		MlmeCalculateChannelQuality(pAd, pAd->Mlme.Now32);
-	}
-
-	// must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if
-	// Radio is currently in noisy environment
-	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-		AsicAdjustTxPower(pAd);
-
-	if (INFRA_ON(pAd))
-	{
-		// Is PSM bit consistent with user power management policy?
-		// This is the only place that will set PSM bit ON.
-		if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-		MlmeCheckPsmChange(pAd, pAd->Mlme.Now32);
-
-		pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt;
-
-		if ((pAd->StaCfg.LastBeaconRxTime + 1*OS_HZ < pAd->Mlme.Now32) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
-			((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt < 600)))
-		{
-			RTMPSetAGCInitValue(pAd, BW_20);
-			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n", (0x2E + GET_LNA_GAIN(pAd))));
-		}
-
-        {
-    		if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)
-    		{
-    		    // When APSD is enabled, the period changes as 20 sec
-    			if ((pAd->Mlme.OneSecPeriodicRound % 20) == 8)
-    				RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
-    		}
-    		else
-    		{
-    		    // Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out)
-    			if ((pAd->Mlme.OneSecPeriodicRound % 10) == 8)
-                {
-                    if (pAd->CommonCfg.bWmmCapable)
-    					RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
-                    else
-						RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
-                }
-    		}
-        }
-
-		if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality))
-			{
-			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
-			pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE;
-			pAd->StaCfg.CCXAdjacentAPLinkDownTime = pAd->StaCfg.LastBeaconRxTime;
-
-			// Lost AP, send disconnect & link down event
-			LinkDown(pAd, FALSE);
-
-            {
-                union iwreq_data    wrqu;
-                memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
-                wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
-            }
-
-			MlmeAutoReconnectLastSSID(pAd);
-		}
-		else if (CQI_IS_BAD(pAd->Mlme.ChannelQuality))
-		{
-			pAd->RalinkCounters.BadCQIAutoRecoveryCount ++;
-			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Bad CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
-			MlmeAutoReconnectLastSSID(pAd);
-		}
-
-		// Add auto seamless roaming
-		if (pAd->StaCfg.bFastRoaming)
-		{
-			SHORT	dBmToRoam = (SHORT)pAd->StaCfg.dBmToRoam;
-
-			DBGPRINT(RT_DEBUG_TRACE, ("Rssi=%d, dBmToRoam=%d\n", RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2), (CHAR)dBmToRoam));
-
-			if (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) <= (CHAR)dBmToRoam)
-			{
-				MlmeCheckForFastRoaming(pAd, pAd->Mlme.Now32);
-			}
-		}
-	}
-	else if (ADHOC_ON(pAd))
-	{
-#ifdef RT2860
-		// 2003-04-17 john. this is a patch that driver forces a BEACON out if ASIC fails
-		// the "TX BEACON competition" for the entire past 1 sec.
-		// So that even when ASIC's BEACONgen engine been blocked
-		// by peer's BEACON due to slower system clock, this STA still can send out
-		// minimum BEACON to tell the peer I'm alive.
-		// drawback is that this BEACON won't be well aligned at TBTT boundary.
-		// EnqueueBeaconFrame(pAd);			  // software send BEACON
-
-		// if all 11b peers leave this BSS more than 5 seconds, update Tx rate,
-		// restore outgoing BEACON to support B/G-mixed mode
-		if ((pAd->CommonCfg.Channel <= 14)			   &&
-			(pAd->CommonCfg.MaxTxRate <= RATE_11)	   &&
-			(pAd->CommonCfg.MaxDesiredRate > RATE_11)  &&
-			((pAd->StaCfg.Last11bBeaconRxTime + 5*OS_HZ) < pAd->Mlme.Now32))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 11B peer left, update Tx rates\n"));
-			NdisMoveMemory(pAd->StaActive.SupRate, pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
-			pAd->StaActive.SupRateLen = pAd->CommonCfg.SupRateLen;
-			MlmeUpdateTxRates(pAd, FALSE, 0);
-			MakeIbssBeacon(pAd);		// re-build BEACON frame
-			AsicEnableIbssSync(pAd);	// copy to on-chip memory
-			pAd->StaCfg.AdhocBOnlyJoined = FALSE;
-		}
-
-		if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
-		{
-			if ((pAd->StaCfg.AdhocBGJoined) &&
-				((pAd->StaCfg.Last11gBeaconRxTime + 5 * OS_HZ) < pAd->Mlme.Now32))
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 11G peer left\n"));
-				pAd->StaCfg.AdhocBGJoined = FALSE;
-			}
-
-			if ((pAd->StaCfg.Adhoc20NJoined) &&
-				((pAd->StaCfg.Last20NBeaconRxTime + 5 * OS_HZ) < pAd->Mlme.Now32))
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 20MHz N peer left\n"));
-				pAd->StaCfg.Adhoc20NJoined = FALSE;
-			}
-		}
-#endif /* RT2860 */
-
-		//radar detect
-		if ((pAd->CommonCfg.Channel > 14)
-			&& (pAd->CommonCfg.bIEEE80211H == 1)
-			&& RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
-		{
-			RadarDetectPeriodic(pAd);
-		}
-
-		// If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState
-		// to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can
-		// join later.
-		if ((pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32) &&
-			OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-		{
-			MLME_START_REQ_STRUCT     StartReq;
-
-			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n"));
-			LinkDown(pAd, FALSE);
-
-			StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
-			MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
-		}
-
-#ifdef RT2870
-		for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
-		{
-			MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[i];
-
-			if (pEntry->ValidAsCLI == FALSE)
-				continue;
-
-			if (pEntry->LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32)
-				MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
-		}
-#endif
-	}
-	else // no INFRA nor ADHOC connection
-	{
-
-		if (pAd->StaCfg.bScanReqIsFromWebUI &&
-            ((pAd->StaCfg.LastScanTime + 30 * OS_HZ) > pAd->Mlme.Now32))
-			goto SKIP_AUTO_SCAN_CONN;
-        else
-            pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
-
-		if ((pAd->StaCfg.bAutoReconnect == TRUE)
-			&& RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)
-			&& (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
-		{
-			if ((pAd->ScanTab.BssNr==0) && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
-			{
-				MLME_SCAN_REQ_STRUCT	   ScanReq;
-
-				if ((pAd->StaCfg.LastScanTime + 10 * OS_HZ) < pAd->Mlme.Now32)
-				{
-					DBGPRINT(RT_DEBUG_TRACE, ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n", pAd->MlmeAux.AutoReconnectSsid));
-					ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen, BSS_ANY, SCAN_ACTIVE);
-					MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
-					pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
-					// Reset Missed scan number
-					pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
-				}
-				else if (pAd->StaCfg.BssType == BSS_ADHOC)	// Quit the forever scan when in a very clean room
-					MlmeAutoReconnectLastSSID(pAd);
-			}
-			else if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
-			{
-				if ((pAd->Mlme.OneSecPeriodicRound % 7) == 0)
-				{
-					MlmeAutoScan(pAd);
-					pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
-				}
-				else
-				{
-						MlmeAutoReconnectLastSSID(pAd);
-				}
-			}
-		}
-	}
-
-SKIP_AUTO_SCAN_CONN:
-
-    if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap !=0) && (pAd->MacTab.fAnyBASession == FALSE))
-	{
-		pAd->MacTab.fAnyBASession = TRUE;
-		AsicUpdateProtect(pAd, HT_FORCERTSCTS,  ALLN_SETPROTECT, FALSE, FALSE);
-	}
-	else if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap ==0) && (pAd->MacTab.fAnyBASession == TRUE))
-	{
-		pAd->MacTab.fAnyBASession = FALSE;
-		AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode,  ALLN_SETPROTECT, FALSE, FALSE);
-	}
-
-	return;
-}
-
-// Link down report
-VOID LinkDownExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3)
-{
-
-	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
-
-	pAd->IndicateMediaState = NdisMediaStateDisconnected;
-	RTMP_IndicateMediaState(pAd);
-    pAd->ExtraInfo = GENERAL_LINK_DOWN;
-}
-
-// IRQL = DISPATCH_LEVEL
-VOID MlmeAutoScan(
-	IN PRTMP_ADAPTER pAd)
-{
-	// check CntlMachine.CurrState to avoid collision with NDIS SetOID request
-	if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Driver auto scan\n"));
-		MlmeEnqueue(pAd,
-					MLME_CNTL_STATE_MACHINE,
-					OID_802_11_BSSID_LIST_SCAN,
-					0,
-					NULL);
-		RT28XX_MLME_HANDLER(pAd);
-	}
-}
-
-// IRQL = DISPATCH_LEVEL
-VOID MlmeAutoReconnectLastSSID(
-	IN PRTMP_ADAPTER pAd)
-{
-
-
-	// check CntlMachine.CurrState to avoid collision with NDIS SetOID request
-	if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
-		(MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
-	{
-		NDIS_802_11_SSID OidSsid;
-		OidSsid.SsidLength = pAd->MlmeAux.AutoReconnectSsidLen;
-		NdisMoveMemory(OidSsid.Ssid, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
-
-		DBGPRINT(RT_DEBUG_TRACE, ("Driver auto reconnect to last OID_802_11_SSID setting - %s, len - %d\n", pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen));
-		MlmeEnqueue(pAd,
-					MLME_CNTL_STATE_MACHINE,
-					OID_802_11_SSID,
-					sizeof(NDIS_802_11_SSID),
-					&OidSsid);
-		RT28XX_MLME_HANDLER(pAd);
-	}
-}
-
 /*
 	==========================================================================
 	Validate SSID for connection try and rescan purpose
@@ -1383,38 +921,31 @@
 	IRQL = DISPATCH_LEVEL
 	==========================================================================
  */
-BOOLEAN MlmeValidateSSID(
-	IN PUCHAR	pSsid,
-	IN UCHAR	SsidLen)
+BOOLEAN MlmeValidateSSID(u8 *pSsid, u8 SsidLen)
 {
-	int	index;
+	int index;
 
 	if (SsidLen > MAX_LEN_OF_SSID)
 		return (FALSE);
 
-	// Check each character value
-	for (index = 0; index < SsidLen; index++)
-	{
+	/* Check each character value */
+	for (index = 0; index < SsidLen; index++) {
 		if (pSsid[index] < 0x20)
 			return (FALSE);
 	}
 
-	// All checked
+	/* All checked */
 	return (TRUE);
 }
 
-VOID MlmeSelectTxRateTable(
-	IN PRTMP_ADAPTER		pAd,
-	IN PMAC_TABLE_ENTRY		pEntry,
-	IN PUCHAR				*ppTable,
-	IN PUCHAR				pTableSize,
-	IN PUCHAR				pInitTxRateIdx)
+void MlmeSelectTxRateTable(struct rt_rtmp_adapter *pAd,
+			   struct rt_mac_table_entry *pEntry,
+			   u8 ** ppTable,
+			   u8 *pTableSize, u8 *pInitTxRateIdx)
 {
-	do
-	{
-		// decide the rate table for tuning
-		if (pAd->CommonCfg.TxRateTableSize > 0)
-		{
+	do {
+		/* decide the rate table for tuning */
+		if (pAd->CommonCfg.TxRateTableSize > 0) {
 			*ppTable = RateSwitchTable;
 			*pTableSize = RateSwitchTable[0];
 			*pInitTxRateIdx = RateSwitchTable[1];
@@ -1422,84 +953,40 @@
 			break;
 		}
 
-		if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd))
-		{
-			if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
-#ifdef RT2860
-				!pAd->StaCfg.AdhocBOnlyJoined &&
-				!pAd->StaCfg.AdhocBGJoined &&
-				(pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
-				((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
-#endif
-#ifdef RT2870
-				(pEntry->HTCapability.MCSSet[0] == 0xff) &&
-				((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
-#endif
-			{// 11N 1S Adhoc
+		if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd)) {
+			if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1))) {	/* 11N 1S Adhoc */
 				*ppTable = RateSwitchTable11N1S;
 				*pTableSize = RateSwitchTable11N1S[0];
 				*pInitTxRateIdx = RateSwitchTable11N1S[1];
 
-			}
-			else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
-#ifdef RT2860
-					!pAd->StaCfg.AdhocBOnlyJoined &&
-					!pAd->StaCfg.AdhocBGJoined &&
-					(pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
-					(pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) &&
-#endif
-#ifdef RT2870
-					(pEntry->HTCapability.MCSSet[0] == 0xff) &&
-					(pEntry->HTCapability.MCSSet[1] == 0xff) &&
-#endif
-					(pAd->Antenna.field.TxPath == 2))
-			{// 11N 2S Adhoc
-				if (pAd->LatchRfRegs.Channel <= 14)
-				{
+			} else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2)) {	/* 11N 2S Adhoc */
+				if (pAd->LatchRfRegs.Channel <= 14) {
 					*ppTable = RateSwitchTable11N2S;
 					*pTableSize = RateSwitchTable11N2S[0];
-					*pInitTxRateIdx = RateSwitchTable11N2S[1];
-				}
-				else
-				{
+					*pInitTxRateIdx =
+					    RateSwitchTable11N2S[1];
+				} else {
 					*ppTable = RateSwitchTable11N2SForABand;
-					*pTableSize = RateSwitchTable11N2SForABand[0];
-					*pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
+					*pTableSize =
+					    RateSwitchTable11N2SForABand[0];
+					*pInitTxRateIdx =
+					    RateSwitchTable11N2SForABand[1];
 				}
 
-			}
-			else
-#ifdef RT2860
-				if (pAd->CommonCfg.PhyMode == PHY_11B)
-			{
+			} else if ((pEntry->RateLen == 4)
+				   && (pEntry->HTCapability.MCSSet[0] == 0)
+				   && (pEntry->HTCapability.MCSSet[1] == 0)
+			    ) {
 				*ppTable = RateSwitchTable11B;
 				*pTableSize = RateSwitchTable11B[0];
 				*pInitTxRateIdx = RateSwitchTable11B[1];
 
-			}
-	        else if((pAd->LatchRfRegs.Channel <= 14) && (pAd->StaCfg.AdhocBOnlyJoined == TRUE))
-#endif
-#ifdef RT2870
-				if ((pEntry->RateLen == 4)
-					&& (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
-					)
-#endif
-			{
-				// USe B Table when Only b-only Station in my IBSS .
-				*ppTable = RateSwitchTable11B;
-				*pTableSize = RateSwitchTable11B[0];
-				*pInitTxRateIdx = RateSwitchTable11B[1];
-
-			}
-			else if (pAd->LatchRfRegs.Channel <= 14)
-			{
+			} else if (pAd->LatchRfRegs.Channel <= 14) {
 				*ppTable = RateSwitchTable11BG;
 				*pTableSize = RateSwitchTable11BG[0];
 				*pInitTxRateIdx = RateSwitchTable11BG[1];
 
-			}
-			else
-			{
+			} else {
 				*ppTable = RateSwitchTable11G;
 				*pTableSize = RateSwitchTable11G[0];
 				*pInitTxRateIdx = RateSwitchTable11G[1];
@@ -1507,91 +994,82 @@
 			}
 			break;
 		}
-
-		if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
-			((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
-		{// 11BGN 1S AP
+		/*if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && */
+		/*      ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1))) */
+		if (((pEntry->RateLen == 12) || (pAd->OpMode == OPMODE_STA)) && (pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1))) {	/* 11BGN 1S AP */
 			*ppTable = RateSwitchTable11BGN1S;
 			*pTableSize = RateSwitchTable11BGN1S[0];
 			*pInitTxRateIdx = RateSwitchTable11BGN1S[1];
 
 			break;
 		}
-
-		if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
-			(pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
-		{// 11BGN 2S AP
-			if (pAd->LatchRfRegs.Channel <= 14)
-			{
+		/*else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && */
+		/*      (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2)) */
+		if (((pEntry->RateLen == 12) || (pAd->OpMode == OPMODE_STA)) && (pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2)) {	/* 11BGN 2S AP */
+			if (pAd->LatchRfRegs.Channel <= 14) {
 				*ppTable = RateSwitchTable11BGN2S;
 				*pTableSize = RateSwitchTable11BGN2S[0];
 				*pInitTxRateIdx = RateSwitchTable11BGN2S[1];
 
-			}
-			else
-			{
+			} else {
 				*ppTable = RateSwitchTable11BGN2SForABand;
 				*pTableSize = RateSwitchTable11BGN2SForABand[0];
-				*pInitTxRateIdx = RateSwitchTable11BGN2SForABand[1];
+				*pInitTxRateIdx =
+				    RateSwitchTable11BGN2SForABand[1];
 
 			}
 			break;
 		}
-
-		if ((pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
-		{// 11N 1S AP
+		/*else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1))) */
+		if ((pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1))) {	/* 11N 1S AP */
 			*ppTable = RateSwitchTable11N1S;
 			*pTableSize = RateSwitchTable11N1S[0];
 			*pInitTxRateIdx = RateSwitchTable11N1S[1];
 
 			break;
 		}
-
-		if ((pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
-		{// 11N 2S AP
-			if (pAd->LatchRfRegs.Channel <= 14)
-			{
-			*ppTable = RateSwitchTable11N2S;
-			*pTableSize = RateSwitchTable11N2S[0];
-			*pInitTxRateIdx = RateSwitchTable11N2S[1];
-            }
-			else
-			{
+		/*else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2)) */
+		if ((pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2)) {	/* 11N 2S AP */
+			if (pAd->LatchRfRegs.Channel <= 14) {
+				*ppTable = RateSwitchTable11N2S;
+				*pTableSize = RateSwitchTable11N2S[0];
+				*pInitTxRateIdx = RateSwitchTable11N2S[1];
+			} else {
 				*ppTable = RateSwitchTable11N2SForABand;
 				*pTableSize = RateSwitchTable11N2SForABand[0];
-				*pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
+				*pInitTxRateIdx =
+				    RateSwitchTable11N2SForABand[1];
 			}
 
 			break;
 		}
-
-		//else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
-		if (pEntry->RateLen == 4)
-		{// B only AP
+		/*else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) */
+		if ((pEntry->RateLen == 4 || pAd->CommonCfg.PhyMode == PHY_11B)
+		    /*Iverson mark for Adhoc b mode,sta will use rate 54  Mbps when connect with sta b/g/n mode */
+		    /* && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0) */
+		    ) {		/* B only AP */
 			*ppTable = RateSwitchTable11B;
 			*pTableSize = RateSwitchTable11B[0];
 			*pInitTxRateIdx = RateSwitchTable11B[1];
 
 			break;
 		}
-
-		//else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
+		/*else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) */
 		if ((pEntry->RateLen > 8)
-			&& (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
-			)
-		{// B/G  mixed AP
+		    && (pEntry->HTCapability.MCSSet[0] == 0)
+		    && (pEntry->HTCapability.MCSSet[1] == 0)
+		    ) {		/* B/G  mixed AP */
 			*ppTable = RateSwitchTable11BG;
 			*pTableSize = RateSwitchTable11BG[0];
 			*pInitTxRateIdx = RateSwitchTable11BG[1];
 
 			break;
 		}
-
-		//else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
+		/*else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) */
 		if ((pEntry->RateLen == 8)
-			&& (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
-			)
-		{// G only AP
+		    && (pEntry->HTCapability.MCSSet[0] == 0)
+		    && (pEntry->HTCapability.MCSSet[1] == 0)
+		    ) {		/* G only AP */
 			*ppTable = RateSwitchTable11G;
 			*pTableSize = RateSwitchTable11G[0];
 			*pInitTxRateIdx = RateSwitchTable11G[1];
@@ -1600,70 +1078,496 @@
 		}
 
 		{
-			//else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
-			if ((pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0))
-			{	// Legacy mode
-				if (pAd->CommonCfg.MaxTxRate <= RATE_11)
-				{
+			/*else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) */
+			if ((pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)) {	/* Legacy mode */
+				if (pAd->CommonCfg.MaxTxRate <= RATE_11) {
 					*ppTable = RateSwitchTable11B;
 					*pTableSize = RateSwitchTable11B[0];
 					*pInitTxRateIdx = RateSwitchTable11B[1];
-				}
-				else if ((pAd->CommonCfg.MaxTxRate > RATE_11) && (pAd->CommonCfg.MinTxRate > RATE_11))
-				{
+				} else if ((pAd->CommonCfg.MaxTxRate > RATE_11)
+					   && (pAd->CommonCfg.MinTxRate >
+					       RATE_11)) {
 					*ppTable = RateSwitchTable11G;
 					*pTableSize = RateSwitchTable11G[0];
 					*pInitTxRateIdx = RateSwitchTable11G[1];
 
-				}
-				else
-				{
+				} else {
 					*ppTable = RateSwitchTable11BG;
 					*pTableSize = RateSwitchTable11BG[0];
-					*pInitTxRateIdx = RateSwitchTable11BG[1];
+					*pInitTxRateIdx =
+					    RateSwitchTable11BG[1];
 				}
 				break;
 			}
-
-			if (pAd->LatchRfRegs.Channel <= 14)
-			{
-				if (pAd->CommonCfg.TxStream == 1)
-				{
+			if (pAd->LatchRfRegs.Channel <= 14) {
+				if (pAd->CommonCfg.TxStream == 1) {
 					*ppTable = RateSwitchTable11N1S;
 					*pTableSize = RateSwitchTable11N1S[0];
-					*pInitTxRateIdx = RateSwitchTable11N1S[1];
-					DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
-				}
-				else
-				{
+					*pInitTxRateIdx =
+					    RateSwitchTable11N1S[1];
+					DBGPRINT_RAW(RT_DEBUG_ERROR,
+						     ("DRS: unkown mode,default use 11N 1S AP \n"));
+				} else {
 					*ppTable = RateSwitchTable11N2S;
 					*pTableSize = RateSwitchTable11N2S[0];
-					*pInitTxRateIdx = RateSwitchTable11N2S[1];
-					DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
+					*pInitTxRateIdx =
+					    RateSwitchTable11N2S[1];
+					DBGPRINT_RAW(RT_DEBUG_ERROR,
+						     ("DRS: unkown mode,default use 11N 2S AP \n"));
 				}
-			}
-			else
-			{
-				if (pAd->CommonCfg.TxStream == 1)
-				{
+			} else {
+				if (pAd->CommonCfg.TxStream == 1) {
 					*ppTable = RateSwitchTable11N1S;
 					*pTableSize = RateSwitchTable11N1S[0];
-					*pInitTxRateIdx = RateSwitchTable11N1S[1];
-					DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
-				}
-				else
-				{
+					*pInitTxRateIdx =
+					    RateSwitchTable11N1S[1];
+					DBGPRINT_RAW(RT_DEBUG_ERROR,
+						     ("DRS: unkown mode,default use 11N 1S AP \n"));
+				} else {
 					*ppTable = RateSwitchTable11N2SForABand;
-					*pTableSize = RateSwitchTable11N2SForABand[0];
-					*pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
-					DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
+					*pTableSize =
+					    RateSwitchTable11N2SForABand[0];
+					*pInitTxRateIdx =
+					    RateSwitchTable11N2SForABand[1];
+					DBGPRINT_RAW(RT_DEBUG_ERROR,
+						     ("DRS: unkown mode,default use 11N 2S AP \n"));
 				}
 			}
-
-			DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n",
-				pAd->StaActive.SupRateLen, pAd->StaActive.ExtRateLen, pAd->StaActive.SupportedPhyInfo.MCSSet[0], pAd->StaActive.SupportedPhyInfo.MCSSet[1]));
+			DBGPRINT_RAW(RT_DEBUG_ERROR,
+				     ("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n",
+				      pAd->StaActive.SupRateLen,
+				      pAd->StaActive.ExtRateLen,
+				      pAd->StaActive.SupportedPhyInfo.MCSSet[0],
+				      pAd->StaActive.SupportedPhyInfo.
+				      MCSSet[1]));
 		}
-	} while(FALSE);
+	} while (FALSE);
+}
+
+void STAMlmePeriodicExec(struct rt_rtmp_adapter *pAd)
+{
+	unsigned long TxTotalCnt;
+	int i;
+
+	/*
+	   We return here in ATE mode, because the statistics
+	   that ATE need are not collected via this routine.
+	 */
+#if defined(RT305x)||defined(RT3070)
+	/* request by Gary, if Rssi0 > -42, BBP 82 need to be changed from 0x62 to 0x42, , bbp 67 need to be changed from 0x20 to 0x18 */
+	if (!pAd->CommonCfg.HighPowerPatchDisabled) {
+#ifdef RT3070
+		if ((IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201)))
+#endif /* RT3070 // */
+		{
+			if ((pAd->StaCfg.RssiSample.AvgRssi0 != 0)
+			    && (pAd->StaCfg.RssiSample.AvgRssi0 >
+				(pAd->BbpRssiToDbmDelta - 35))) {
+				RT30xxWriteRFRegister(pAd, RF_R27, 0x20);
+			} else {
+				RT30xxWriteRFRegister(pAd, RF_R27, 0x23);
+			}
+		}
+	}
+#endif
+#ifdef PCIE_PS_SUPPORT
+/* don't perform idle-power-save mechanism within 3 min after driver initialization. */
+/* This can make rebooter test more robust */
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
+		if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd))
+		    && (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE)
+		    && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
+		    && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) {
+			if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) {
+				if (pAd->StaCfg.PSControl.field.EnableNewPS ==
+				    TRUE) {
+					DBGPRINT(RT_DEBUG_TRACE,
+						 ("%s\n", __func__));
+					RT28xxPciAsicRadioOff(pAd,
+							      GUI_IDLE_POWER_SAVE,
+							      0);
+				} else {
+					AsicSendCommandToMcu(pAd, 0x30,
+							     PowerSafeCID, 0xff,
+							     0x2);
+					/* Wait command success */
+					AsicCheckCommanOk(pAd, PowerSafeCID);
+					RTMP_SET_FLAG(pAd,
+						      fRTMP_ADAPTER_IDLE_RADIO_OFF);
+					DBGPRINT(RT_DEBUG_TRACE,
+						 ("PSM - rt30xx Issue Sleep command)\n"));
+				}
+			} else if (pAd->Mlme.OneSecPeriodicRound > 180) {
+				if (pAd->StaCfg.PSControl.field.EnableNewPS ==
+				    TRUE) {
+					DBGPRINT(RT_DEBUG_TRACE,
+						 ("%s\n", __func__));
+					RT28xxPciAsicRadioOff(pAd,
+							      GUI_IDLE_POWER_SAVE,
+							      0);
+				} else {
+					AsicSendCommandToMcu(pAd, 0x30,
+							     PowerSafeCID, 0xff,
+							     0x02);
+					/* Wait command success */
+					AsicCheckCommanOk(pAd, PowerSafeCID);
+					RTMP_SET_FLAG(pAd,
+						      fRTMP_ADAPTER_IDLE_RADIO_OFF);
+					DBGPRINT(RT_DEBUG_TRACE,
+						 ("PSM -  rt28xx Issue Sleep command)\n"));
+				}
+			}
+		} else {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("STAMlmePeriodicExec MMCHK - CommonCfg.Ssid[%d]=%c%c%c%c... MlmeAux.Ssid[%d]=%c%c%c%c...\n",
+				  pAd->CommonCfg.SsidLen,
+				  pAd->CommonCfg.Ssid[0],
+				  pAd->CommonCfg.Ssid[1],
+				  pAd->CommonCfg.Ssid[2],
+				  pAd->CommonCfg.Ssid[3], pAd->MlmeAux.SsidLen,
+				  pAd->MlmeAux.Ssid[0], pAd->MlmeAux.Ssid[1],
+				  pAd->MlmeAux.Ssid[2], pAd->MlmeAux.Ssid[3]));
+		}
+	}
+#endif /* PCIE_PS_SUPPORT // */
+
+	if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE) {
+		/* WPA MIC error should block association attempt for 60 seconds */
+		if (pAd->StaCfg.bBlockAssoc &&
+		    RTMP_TIME_AFTER(pAd->Mlme.Now32,
+				    pAd->StaCfg.LastMicErrorTime +
+				    (60 * OS_HZ)))
+			pAd->StaCfg.bBlockAssoc = FALSE;
+	}
+
+	if ((pAd->PreMediaState != pAd->IndicateMediaState)
+	    && (pAd->CommonCfg.bWirelessEvent)) {
+		if (pAd->IndicateMediaState == NdisMediaStateConnected) {
+			RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG,
+					      pAd->MacTab.Content[BSSID_WCID].
+					      Addr, BSS0, 0);
+		}
+		pAd->PreMediaState = pAd->IndicateMediaState;
+	}
+
+	if (pAd->CommonCfg.PSPXlink && ADHOC_ON(pAd)) {
+	} else {
+		AsicStaBbpTuning(pAd);
+	}
+
+	TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+	    pAd->RalinkCounters.OneSecTxRetryOkCount +
+	    pAd->RalinkCounters.OneSecTxFailCount;
+
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
+		/* update channel quality for Roaming and UI LinkQuality display */
+		MlmeCalculateChannelQuality(pAd, NULL, pAd->Mlme.Now32);
+	}
+	/* must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if */
+	/* Radio is currently in noisy environment */
+	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+		AsicAdjustTxPower(pAd);
+
+	if (INFRA_ON(pAd)) {
+
+		/* Is PSM bit consistent with user power management policy? */
+		/* This is the only place that will set PSM bit ON. */
+		if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+			MlmeCheckPsmChange(pAd, pAd->Mlme.Now32);
+
+		pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt;
+
+		if ((RTMP_TIME_AFTER
+		     (pAd->Mlme.Now32,
+		      pAd->StaCfg.LastBeaconRxTime + (1 * OS_HZ)))
+		    &&
+		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+		    &&
+		    (((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt) <
+		      600))) {
+			RTMPSetAGCInitValue(pAd, BW_20);
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n",
+				  (0x2E + GET_LNA_GAIN(pAd))));
+		}
+		/*if ((pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) && */
+		/*    (pAd->RalinkCounters.OneSecTxRetryOkCount == 0)) */
+		{
+			if (pAd->CommonCfg.bAPSDCapable
+			    && pAd->CommonCfg.APEdcaParm.bAPSDCapable) {
+				/* When APSD is enabled, the period changes as 20 sec */
+				if ((pAd->Mlme.OneSecPeriodicRound % 20) == 8)
+					RTMPSendNullFrame(pAd,
+							  pAd->CommonCfg.TxRate,
+							  TRUE);
+			} else {
+				/* Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out) */
+				if ((pAd->Mlme.OneSecPeriodicRound % 10) == 8) {
+					if (pAd->CommonCfg.bWmmCapable)
+						RTMPSendNullFrame(pAd,
+								  pAd->
+								  CommonCfg.
+								  TxRate, TRUE);
+					else
+						RTMPSendNullFrame(pAd,
+								  pAd->
+								  CommonCfg.
+								  TxRate,
+								  FALSE);
+				}
+			}
+		}
+
+		if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality)) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n",
+				  pAd->RalinkCounters.BadCQIAutoRecoveryCount));
+
+			/* Lost AP, send disconnect & link down event */
+			LinkDown(pAd, FALSE);
+
+			RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL,
+						0);
+
+			/* RTMPPatchMacBbpBug(pAd); */
+			MlmeAutoReconnectLastSSID(pAd);
+		} else if (CQI_IS_BAD(pAd->Mlme.ChannelQuality)) {
+			pAd->RalinkCounters.BadCQIAutoRecoveryCount++;
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("MMCHK - Bad CQI. Auto Recovery attempt #%ld\n",
+				  pAd->RalinkCounters.BadCQIAutoRecoveryCount));
+			MlmeAutoReconnectLastSSID(pAd);
+		}
+
+		if (pAd->StaCfg.bAutoRoaming) {
+			BOOLEAN rv = FALSE;
+			char dBmToRoam = pAd->StaCfg.dBmToRoam;
+			char MaxRssi = RTMPMaxRssi(pAd,
+						   pAd->StaCfg.RssiSample.
+						   LastRssi0,
+						   pAd->StaCfg.RssiSample.
+						   LastRssi1,
+						   pAd->StaCfg.RssiSample.
+						   LastRssi2);
+
+			/* Scanning, ignore Roaming */
+			if (!RTMP_TEST_FLAG
+			    (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)
+			    && (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE)
+			    && (MaxRssi <= dBmToRoam)) {
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("Rssi=%d, dBmToRoam=%d\n", MaxRssi,
+					  (char)dBmToRoam));
+
+				/* Add auto seamless roaming */
+				if (rv == FALSE)
+					rv = MlmeCheckForFastRoaming(pAd);
+
+				if (rv == FALSE) {
+					if ((pAd->StaCfg.LastScanTime +
+					     10 * OS_HZ) < pAd->Mlme.Now32) {
+						DBGPRINT(RT_DEBUG_TRACE,
+							 ("MMCHK - Roaming, No eligable entry, try new scan!\n"));
+						pAd->StaCfg.ScanCnt = 2;
+						pAd->StaCfg.LastScanTime =
+						    pAd->Mlme.Now32;
+						MlmeAutoScan(pAd);
+					}
+				}
+			}
+		}
+	} else if (ADHOC_ON(pAd)) {
+		/* If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState */
+		/* to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can */
+		/* join later. */
+		if (RTMP_TIME_AFTER
+		    (pAd->Mlme.Now32,
+		     pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME)
+		    && OPSTATUS_TEST_FLAG(pAd,
+					  fOP_STATUS_MEDIA_STATE_CONNECTED)) {
+			struct rt_mlme_start_req StartReq;
+
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n"));
+			LinkDown(pAd, FALSE);
+
+			StartParmFill(pAd, &StartReq,
+				      (char *) pAd->MlmeAux.Ssid,
+				      pAd->MlmeAux.SsidLen);
+			MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ,
+				    sizeof(struct rt_mlme_start_req), &StartReq);
+			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
+		}
+
+		for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) {
+			struct rt_mac_table_entry *pEntry = &pAd->MacTab.Content[i];
+
+			if (pEntry->ValidAsCLI == FALSE)
+				continue;
+
+			if (RTMP_TIME_AFTER
+			    (pAd->Mlme.Now32,
+			     pEntry->LastBeaconRxTime + ADHOC_BEACON_LOST_TIME))
+				MacTableDeleteEntry(pAd, pEntry->Aid,
+						    pEntry->Addr);
+		}
+	} else			/* no INFRA nor ADHOC connection */
+	{
+
+		if (pAd->StaCfg.bScanReqIsFromWebUI &&
+		    RTMP_TIME_BEFORE(pAd->Mlme.Now32,
+				     pAd->StaCfg.LastScanTime + (30 * OS_HZ)))
+			goto SKIP_AUTO_SCAN_CONN;
+		else
+			pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
+
+		if ((pAd->StaCfg.bAutoReconnect == TRUE)
+		    && RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)
+		    &&
+		    (MlmeValidateSSID
+		     (pAd->MlmeAux.AutoReconnectSsid,
+		      pAd->MlmeAux.AutoReconnectSsidLen) == TRUE)) {
+			if ((pAd->ScanTab.BssNr == 0)
+			    && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)) {
+				struct rt_mlme_scan_req ScanReq;
+
+				if (RTMP_TIME_AFTER
+				    (pAd->Mlme.Now32,
+				     pAd->StaCfg.LastScanTime + (10 * OS_HZ))) {
+					DBGPRINT(RT_DEBUG_TRACE,
+						 ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n",
+						  pAd->MlmeAux.
+						  AutoReconnectSsid));
+					ScanParmFill(pAd, &ScanReq,
+						     (char *)pAd->MlmeAux.
+						     AutoReconnectSsid,
+						     pAd->MlmeAux.
+						     AutoReconnectSsidLen,
+						     BSS_ANY, SCAN_ACTIVE);
+					MlmeEnqueue(pAd, SYNC_STATE_MACHINE,
+						    MT2_MLME_SCAN_REQ,
+						    sizeof
+						    (struct rt_mlme_scan_req),
+						    &ScanReq);
+					pAd->Mlme.CntlMachine.CurrState =
+					    CNTL_WAIT_OID_LIST_SCAN;
+					/* Reset Missed scan number */
+					pAd->StaCfg.LastScanTime =
+					    pAd->Mlme.Now32;
+				} else if (pAd->StaCfg.BssType == BSS_ADHOC)	/* Quit the forever scan when in a very clean room */
+					MlmeAutoReconnectLastSSID(pAd);
+			} else if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) {
+				if ((pAd->Mlme.OneSecPeriodicRound % 7) == 0) {
+					MlmeAutoScan(pAd);
+					pAd->StaCfg.LastScanTime =
+					    pAd->Mlme.Now32;
+				} else {
+					MlmeAutoReconnectLastSSID(pAd);
+				}
+			}
+		}
+	}
+
+SKIP_AUTO_SCAN_CONN:
+
+	if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap != 0)
+	    && (pAd->MacTab.fAnyBASession == FALSE)) {
+		pAd->MacTab.fAnyBASession = TRUE;
+		AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, FALSE,
+				  FALSE);
+	} else if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap == 0)
+		   && (pAd->MacTab.fAnyBASession == TRUE)) {
+		pAd->MacTab.fAnyBASession = FALSE;
+		AsicUpdateProtect(pAd,
+				  pAd->MlmeAux.AddHtInfo.AddHtInfo2.
+				  OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
+	}
+
+	return;
+}
+
+/* Link down report */
+void LinkDownExec(void *SystemSpecific1,
+		  void *FunctionContext,
+		  void *SystemSpecific2, void *SystemSpecific3)
+{
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
+
+	if (pAd != NULL) {
+		struct rt_mlme_disassoc_req DisassocReq;
+
+		if ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) &&
+		    (INFRA_ON(pAd))) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("LinkDownExec(): disassociate with current AP...\n"));
+			DisassocParmFill(pAd, &DisassocReq,
+					 pAd->CommonCfg.Bssid,
+					 REASON_DISASSOC_STA_LEAVING);
+			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
+				    MT2_MLME_DISASSOC_REQ,
+				    sizeof(struct rt_mlme_disassoc_req),
+				    &DisassocReq);
+			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
+
+			pAd->IndicateMediaState = NdisMediaStateDisconnected;
+			RTMP_IndicateMediaState(pAd);
+			pAd->ExtraInfo = GENERAL_LINK_DOWN;
+		}
+	}
+}
+
+/* IRQL = DISPATCH_LEVEL */
+void MlmeAutoScan(struct rt_rtmp_adapter *pAd)
+{
+	/* check CntlMachine.CurrState to avoid collision with NDIS SetOID request */
+	if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) {
+		DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Driver auto scan\n"));
+		MlmeEnqueue(pAd,
+			    MLME_CNTL_STATE_MACHINE,
+			    OID_802_11_BSSID_LIST_SCAN,
+			    pAd->MlmeAux.AutoReconnectSsidLen,
+			    pAd->MlmeAux.AutoReconnectSsid);
+		RTMP_MLME_HANDLER(pAd);
+	}
+}
+
+/* IRQL = DISPATCH_LEVEL */
+void MlmeAutoReconnectLastSSID(struct rt_rtmp_adapter *pAd)
+{
+	if (pAd->StaCfg.bAutoConnectByBssid) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Driver auto reconnect to last OID_802_11_BSSID setting - %02X:%02X:%02X:%02X:%02X:%02X\n",
+			  pAd->MlmeAux.Bssid[0], pAd->MlmeAux.Bssid[1],
+			  pAd->MlmeAux.Bssid[2], pAd->MlmeAux.Bssid[3],
+			  pAd->MlmeAux.Bssid[4], pAd->MlmeAux.Bssid[5]));
+
+		pAd->MlmeAux.Channel = pAd->CommonCfg.Channel;
+		MlmeEnqueue(pAd,
+			    MLME_CNTL_STATE_MACHINE,
+			    OID_802_11_BSSID, MAC_ADDR_LEN, pAd->MlmeAux.Bssid);
+
+		pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+
+		RTMP_MLME_HANDLER(pAd);
+	}
+	/* check CntlMachine.CurrState to avoid collision with NDIS SetOID request */
+	else if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
+		 (MlmeValidateSSID
+		  (pAd->MlmeAux.AutoReconnectSsid,
+		   pAd->MlmeAux.AutoReconnectSsidLen) == TRUE)) {
+		struct rt_ndis_802_11_ssid OidSsid;
+		OidSsid.SsidLength = pAd->MlmeAux.AutoReconnectSsidLen;
+		NdisMoveMemory(OidSsid.Ssid, pAd->MlmeAux.AutoReconnectSsid,
+			       pAd->MlmeAux.AutoReconnectSsidLen);
+
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Driver auto reconnect to last OID_802_11_SSID setting - %s, len - %d\n",
+			  pAd->MlmeAux.AutoReconnectSsid,
+			  pAd->MlmeAux.AutoReconnectSsidLen));
+		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, OID_802_11_SSID,
+			    sizeof(struct rt_ndis_802_11_ssid), &OidSsid);
+		RTMP_MLME_HANDLER(pAd);
+	}
 }
 
 /*
@@ -1678,47 +1582,50 @@
 	Output:
 	==========================================================================
  */
-VOID MlmeCheckForRoaming(
-	IN PRTMP_ADAPTER pAd,
-	IN ULONG	Now32)
+void MlmeCheckForRoaming(struct rt_rtmp_adapter *pAd, unsigned long Now32)
 {
-	USHORT	   i;
-	BSS_TABLE  *pRoamTab = &pAd->MlmeAux.RoamTab;
-	BSS_ENTRY  *pBss;
+	u16 i;
+	struct rt_bss_table *pRoamTab = &pAd->MlmeAux.RoamTab;
+	struct rt_bss_entry *pBss;
 
 	DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForRoaming\n"));
-	// put all roaming candidates into RoamTab, and sort in RSSI order
+	/* put all roaming candidates into RoamTab, and sort in RSSI order */
 	BssTableInit(pRoamTab);
-	for (i = 0; i < pAd->ScanTab.BssNr; i++)
-	{
+	for (i = 0; i < pAd->ScanTab.BssNr; i++) {
 		pBss = &pAd->ScanTab.BssEntry[i];
 
-		if ((pBss->LastBeaconRxTime + BEACON_LOST_TIME) < Now32)
-			continue;	 // AP disappear
+		if ((pBss->LastBeaconRxTime + pAd->StaCfg.BeaconLostTime) <
+		    Now32)
+			continue;	/* AP disappear */
 		if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING)
-			continue;	 // RSSI too weak. forget it.
+			continue;	/* RSSI too weak. forget it. */
 		if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
-			continue;	 // skip current AP
-		if (pBss->Rssi < (pAd->StaCfg.RssiSample.LastRssi0 + RSSI_DELTA))
-			continue;	 // only AP with stronger RSSI is eligible for roaming
+			continue;	/* skip current AP */
+		if (pBss->Rssi <
+		    (pAd->StaCfg.RssiSample.LastRssi0 + RSSI_DELTA))
+			continue;	/* only AP with stronger RSSI is eligible for roaming */
 
-		// AP passing all above rules is put into roaming candidate table
-		NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
+		/* AP passing all above rules is put into roaming candidate table */
+		NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss,
+			       sizeof(struct rt_bss_entry));
 		pRoamTab->BssNr += 1;
 	}
 
-	if (pRoamTab->BssNr > 0)
-	{
-		// check CntlMachine.CurrState to avoid collision with NDIS SetOID request
-		if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
-		{
-			pAd->RalinkCounters.PoorCQIRoamingCount ++;
-			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
-			RT28XX_MLME_HANDLER(pAd);
+	if (pRoamTab->BssNr > 0) {
+		/* check CntlMachine.CurrState to avoid collision with NDIS SetOID request */
+		if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) {
+			pAd->RalinkCounters.PoorCQIRoamingCount++;
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("MMCHK - Roaming attempt #%ld\n",
+				  pAd->RalinkCounters.PoorCQIRoamingCount));
+			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE,
+				    MT2_MLME_ROAMING_REQ, 0, NULL);
+			RTMP_MLME_HANDLER(pAd);
 		}
 	}
-	DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForRoaming(# of candidate= %d)\n",pRoamTab->BssNr));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("<== MlmeCheckForRoaming(# of candidate= %d)\n",
+		  pRoamTab->BssNr));
 }
 
 /*
@@ -1733,159 +1640,74 @@
 	Output:
 	==========================================================================
  */
-VOID MlmeCheckForFastRoaming(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	ULONG			Now)
+BOOLEAN MlmeCheckForFastRoaming(struct rt_rtmp_adapter *pAd)
 {
-	USHORT		i;
-	BSS_TABLE	*pRoamTab = &pAd->MlmeAux.RoamTab;
-	BSS_ENTRY	*pBss;
+	u16 i;
+	struct rt_bss_table *pRoamTab = &pAd->MlmeAux.RoamTab;
+	struct rt_bss_entry *pBss;
 
 	DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForFastRoaming\n"));
-	// put all roaming candidates into RoamTab, and sort in RSSI order
+	/* put all roaming candidates into RoamTab, and sort in RSSI order */
 	BssTableInit(pRoamTab);
-	for (i = 0; i < pAd->ScanTab.BssNr; i++)
-	{
+	for (i = 0; i < pAd->ScanTab.BssNr; i++) {
 		pBss = &pAd->ScanTab.BssEntry[i];
 
-        if ((pBss->Rssi <= -50) && (pBss->Channel == pAd->CommonCfg.Channel))
-			continue;	 // RSSI too weak. forget it.
+		if ((pBss->Rssi <= -50)
+		    && (pBss->Channel == pAd->CommonCfg.Channel))
+			continue;	/* RSSI too weak. forget it. */
 		if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
-			continue;	 // skip current AP
-		if (!SSID_EQUAL(pBss->Ssid, pBss->SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
-			continue;	 // skip different SSID
-        if (pBss->Rssi < (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) + RSSI_DELTA))
-			continue;	 // skip AP without better RSSI
+			continue;	/* skip current AP */
+		if (!SSID_EQUAL
+		    (pBss->Ssid, pBss->SsidLen, pAd->CommonCfg.Ssid,
+		     pAd->CommonCfg.SsidLen))
+			continue;	/* skip different SSID */
+		if (pBss->Rssi <
+		    (RTMPMaxRssi
+		     (pAd, pAd->StaCfg.RssiSample.LastRssi0,
+		      pAd->StaCfg.RssiSample.LastRssi1,
+		      pAd->StaCfg.RssiSample.LastRssi2) + RSSI_DELTA))
+			continue;	/* skip AP without better RSSI */
 
-        DBGPRINT(RT_DEBUG_TRACE, ("LastRssi0 = %d, pBss->Rssi = %d\n", RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2), pBss->Rssi));
-		// AP passing all above rules is put into roaming candidate table
-		NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("LastRssi0 = %d, pBss->Rssi = %d\n",
+			  RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0,
+				      pAd->StaCfg.RssiSample.LastRssi1,
+				      pAd->StaCfg.RssiSample.LastRssi2),
+			  pBss->Rssi));
+		/* AP passing all above rules is put into roaming candidate table */
+		NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss,
+			       sizeof(struct rt_bss_entry));
 		pRoamTab->BssNr += 1;
 	}
 
-	if (pRoamTab->BssNr > 0)
-	{
-		// check CntlMachine.CurrState to avoid collision with NDIS SetOID request
-		if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
-		{
-			pAd->RalinkCounters.PoorCQIRoamingCount ++;
-			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
-			RT28XX_MLME_HANDLER(pAd);
-		}
-	}
-	// Maybe site survey required
-	else
-	{
-		if ((pAd->StaCfg.LastScanTime + 10 * 1000) < Now)
-		{
-			// check CntlMachine.CurrState to avoid collision with NDIS SetOID request
-			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming, No eligable entry, try new scan!\n"));
-			pAd->StaCfg.ScanCnt = 2;
-			pAd->StaCfg.LastScanTime = Now;
-			MlmeAutoScan(pAd);
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr));
+	if (pRoamTab->BssNr > 0) {
+		/* check CntlMachine.CurrState to avoid collision with NDIS SetOID request */
+		if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) {
+			pAd->RalinkCounters.PoorCQIRoamingCount++;
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("MMCHK - Roaming attempt #%ld\n",
+				  pAd->RalinkCounters.PoorCQIRoamingCount));
+			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE,
+				    MT2_MLME_ROAMING_REQ, 0, NULL);
+			RTMP_MLME_HANDLER(pAd);
+			return TRUE;
 		}
 	}
 
-    DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr));
+	return FALSE;
 }
 
-/*
-	==========================================================================
-	Description:
-		This routine calculates TxPER, RxPER of the past N-sec period. And
-		according to the calculation result, ChannelQuality is calculated here
-		to decide if current AP is still doing the job.
-
-		If ChannelQuality is not good, a ROAMing attempt may be tried later.
-	Output:
-		StaCfg.ChannelQuality - 0..100
-
-	IRQL = DISPATCH_LEVEL
-
-	NOTE: This routine decide channle quality based on RX CRC error ratio.
-		Caller should make sure a function call to NICUpdateRawCounters(pAd)
-		is performed right before this routine, so that this routine can decide
-		channel quality based on the most up-to-date information
-	==========================================================================
- */
-VOID MlmeCalculateChannelQuality(
-	IN PRTMP_ADAPTER pAd,
-	IN ULONG Now32)
+void MlmeSetTxRate(struct rt_rtmp_adapter *pAd,
+		   struct rt_mac_table_entry *pEntry, struct rt_rtmp_tx_rate_switch * pTxRate)
 {
-	ULONG TxOkCnt, TxCnt, TxPER, TxPRR;
-	ULONG RxCnt, RxPER;
-	UCHAR NorRssi;
-	CHAR  MaxRssi;
-	ULONG BeaconLostTime = BEACON_LOST_TIME;
-
-	MaxRssi = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2);
-
-	//
-	// calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics
-	//
-	TxOkCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + pAd->RalinkCounters.OneSecTxRetryOkCount;
-	TxCnt = TxOkCnt + pAd->RalinkCounters.OneSecTxFailCount;
-	if (TxCnt < 5)
-	{
-		TxPER = 0;
-		TxPRR = 0;
-	}
-	else
-	{
-		TxPER = (pAd->RalinkCounters.OneSecTxFailCount * 100) / TxCnt;
-		TxPRR = ((TxCnt - pAd->RalinkCounters.OneSecTxNoRetryOkCount) * 100) / TxCnt;
-	}
-
-	//
-	// calculate RX PER - don't take RxPER into consideration if too few sample
-	//
-	RxCnt = pAd->RalinkCounters.OneSecRxOkCnt + pAd->RalinkCounters.OneSecRxFcsErrCnt;
-	if (RxCnt < 5)
-		RxPER = 0;
-	else
-		RxPER = (pAd->RalinkCounters.OneSecRxFcsErrCnt * 100) / RxCnt;
-
-	//
-	// decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER
-	//
-	if (INFRA_ON(pAd) &&
-		(pAd->RalinkCounters.OneSecTxNoRetryOkCount < 2) && // no heavy traffic
-		(pAd->StaCfg.LastBeaconRxTime + BeaconLostTime < Now32))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", BeaconLostTime, TxOkCnt));
-		pAd->Mlme.ChannelQuality = 0;
-	}
-	else
-	{
-		// Normalize Rssi
-		if (MaxRssi > -40)
-			NorRssi = 100;
-		else if (MaxRssi < -90)
-			NorRssi = 0;
-		else
-			NorRssi = (MaxRssi + 90) * 2;
-
-		// ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER	 (RSSI 0..100), (TxPER 100..0), (RxPER 100..0)
-		pAd->Mlme.ChannelQuality = (RSSI_WEIGHTING * NorRssi +
-								   TX_WEIGHTING * (100 - TxPRR) +
-								   RX_WEIGHTING* (100 - RxPER)) / 100;
-		if (pAd->Mlme.ChannelQuality >= 100)
-			pAd->Mlme.ChannelQuality = 100;
-	}
-
-}
-
-VOID MlmeSetTxRate(
-	IN PRTMP_ADAPTER		pAd,
-	IN PMAC_TABLE_ENTRY		pEntry,
-	IN PRTMP_TX_RATE_SWITCH	pTxRate)
-{
-	UCHAR	MaxMode = MODE_OFDM;
+	u8 MaxMode = MODE_OFDM;
 
 	MaxMode = MODE_HTGREENFIELD;
 
-	if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC) && (pAd->Antenna.field.TxPath == 2))
+	if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC)
+	    && (pAd->Antenna.field.TxPath == 2))
 		pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE;
 	else
 		pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
@@ -1896,87 +1718,109 @@
 	if (pAd->StaCfg.HTPhyMode.field.MCS > 7)
 		pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
 
-   	if (ADHOC_ON(pAd))
-	{
-		// If peer adhoc is b-only mode, we can't send 11g rate.
+	if (ADHOC_ON(pAd)) {
+		/* If peer adhoc is b-only mode, we can't send 11g rate. */
 		pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
-		pEntry->HTPhyMode.field.STBC	= STBC_NONE;
+		pEntry->HTPhyMode.field.STBC = STBC_NONE;
 
-		//
-		// For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary
-		//
-		pEntry->HTPhyMode.field.MODE	= pTxRate->Mode;
-		pEntry->HTPhyMode.field.ShortGI	= pAd->StaCfg.HTPhyMode.field.ShortGI;
-		pEntry->HTPhyMode.field.MCS		= pAd->StaCfg.HTPhyMode.field.MCS;
+		/* */
+		/* For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary */
+		/* */
+		pEntry->HTPhyMode.field.MODE = pTxRate->Mode;
+		pEntry->HTPhyMode.field.ShortGI =
+		    pAd->StaCfg.HTPhyMode.field.ShortGI;
+		pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
 
-		// Patch speed error in status page
+		/* Patch speed error in status page */
 		pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE;
-	}
-	else
-	{
+	} else {
 		if (pTxRate->Mode <= MaxMode)
 			pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode;
 
-		if (pTxRate->ShortGI && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI))
+		if (pTxRate->ShortGI
+		    && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI))
 			pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400;
 		else
 			pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
 
-		// Reexam each bandwidth's SGI support.
-		if (pAd->StaCfg.HTPhyMode.field.ShortGI == GI_400)
-		{
-			if ((pEntry->HTPhyMode.field.BW == BW_20) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE)))
+		/* Reexam each bandwidth's SGI support. */
+		if (pAd->StaCfg.HTPhyMode.field.ShortGI == GI_400) {
+			if ((pEntry->HTPhyMode.field.BW == BW_20)
+			    &&
+			    (!CLIENT_STATUS_TEST_FLAG
+			     (pEntry, fCLIENT_STATUS_SGI20_CAPABLE)))
 				pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
-			if ((pEntry->HTPhyMode.field.BW == BW_40) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE)))
+			if ((pEntry->HTPhyMode.field.BW == BW_40)
+			    &&
+			    (!CLIENT_STATUS_TEST_FLAG
+			     (pEntry, fCLIENT_STATUS_SGI40_CAPABLE)))
 				pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
 		}
+		/* Turn RTS/CTS rate to 6Mbps. */
+		if ((pEntry->HTPhyMode.field.MCS == 0)
+		    && (pAd->StaCfg.HTPhyMode.field.MCS != 0)) {
+			pEntry->HTPhyMode.field.MCS =
+			    pAd->StaCfg.HTPhyMode.field.MCS;
+			if (pAd->MacTab.fAnyBASession) {
+				AsicUpdateProtect(pAd, HT_FORCERTSCTS,
+						  ALLN_SETPROTECT, TRUE,
+						  (BOOLEAN) pAd->MlmeAux.
+						  AddHtInfo.AddHtInfo2.
+						  NonGfPresent);
+			} else {
+				AsicUpdateProtect(pAd,
+						  pAd->MlmeAux.AddHtInfo.
+						  AddHtInfo2.OperaionMode,
+						  ALLN_SETPROTECT, TRUE,
+						  (BOOLEAN) pAd->MlmeAux.
+						  AddHtInfo.AddHtInfo2.
+						  NonGfPresent);
+			}
+		} else if ((pEntry->HTPhyMode.field.MCS == 8)
+			   && (pAd->StaCfg.HTPhyMode.field.MCS != 8)) {
+			pEntry->HTPhyMode.field.MCS =
+			    pAd->StaCfg.HTPhyMode.field.MCS;
+			if (pAd->MacTab.fAnyBASession) {
+				AsicUpdateProtect(pAd, HT_FORCERTSCTS,
+						  ALLN_SETPROTECT, TRUE,
+						  (BOOLEAN) pAd->MlmeAux.
+						  AddHtInfo.AddHtInfo2.
+						  NonGfPresent);
+			} else {
+				AsicUpdateProtect(pAd,
+						  pAd->MlmeAux.AddHtInfo.
+						  AddHtInfo2.OperaionMode,
+						  ALLN_SETPROTECT, TRUE,
+						  (BOOLEAN) pAd->MlmeAux.
+						  AddHtInfo.AddHtInfo2.
+						  NonGfPresent);
+			}
+		} else if ((pEntry->HTPhyMode.field.MCS != 0)
+			   && (pAd->StaCfg.HTPhyMode.field.MCS == 0)) {
+			AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT,
+					  TRUE,
+					  (BOOLEAN) pAd->MlmeAux.AddHtInfo.
+					  AddHtInfo2.NonGfPresent);
 
-		// Turn RTS/CTS rate to 6Mbps.
-		if ((pEntry->HTPhyMode.field.MCS == 0) && (pAd->StaCfg.HTPhyMode.field.MCS != 0))
-		{
-			pEntry->HTPhyMode.field.MCS		= pAd->StaCfg.HTPhyMode.field.MCS;
-			if (pAd->MacTab.fAnyBASession)
-			{
-				AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
-			}
-			else
-			{
-				AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
-			}
-		}
-		else if ((pEntry->HTPhyMode.field.MCS == 8) && (pAd->StaCfg.HTPhyMode.field.MCS != 8))
-		{
-			pEntry->HTPhyMode.field.MCS		= pAd->StaCfg.HTPhyMode.field.MCS;
-			if (pAd->MacTab.fAnyBASession)
-			{
-				AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
-			}
-			else
-			{
-				AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
-			}
-		}
-		else if ((pEntry->HTPhyMode.field.MCS != 0) && (pAd->StaCfg.HTPhyMode.field.MCS == 0))
-		{
-			AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
-
-		}
-		else if ((pEntry->HTPhyMode.field.MCS != 8) && (pAd->StaCfg.HTPhyMode.field.MCS == 8))
-		{
-			AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+		} else if ((pEntry->HTPhyMode.field.MCS != 8)
+			   && (pAd->StaCfg.HTPhyMode.field.MCS == 8)) {
+			AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT,
+					  TRUE,
+					  (BOOLEAN) pAd->MlmeAux.AddHtInfo.
+					  AddHtInfo2.NonGfPresent);
 		}
 
-		pEntry->HTPhyMode.field.STBC	= pAd->StaCfg.HTPhyMode.field.STBC;
-		pEntry->HTPhyMode.field.ShortGI	= pAd->StaCfg.HTPhyMode.field.ShortGI;
-		pEntry->HTPhyMode.field.MCS		= pAd->StaCfg.HTPhyMode.field.MCS;
-		pEntry->HTPhyMode.field.MODE	= pAd->StaCfg.HTPhyMode.field.MODE;
-
-		if ((pAd->StaCfg.MaxHTPhyMode.field.MODE == MODE_HTGREENFIELD) &&
-		    pAd->WIFItestbed.bGreenField)
-		    pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD;
+		pEntry->HTPhyMode.field.STBC = pAd->StaCfg.HTPhyMode.field.STBC;
+		pEntry->HTPhyMode.field.ShortGI =
+		    pAd->StaCfg.HTPhyMode.field.ShortGI;
+		pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+		pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
+		if ((pAd->StaCfg.MaxHTPhyMode.field.MODE == MODE_HTGREENFIELD)
+		    && pAd->WIFItestbed.bGreenField)
+			pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD;
 	}
 
-	pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
+	pAd->LastTxRate = (u16)(pEntry->HTPhyMode.word);
 }
 
 /*
@@ -1996,47 +1840,39 @@
 		call this routine every second
 	==========================================================================
  */
-VOID MlmeDynamicTxRateSwitching(
-	IN PRTMP_ADAPTER pAd)
+void MlmeDynamicTxRateSwitching(struct rt_rtmp_adapter *pAd)
 {
-	UCHAR					UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx;
-	ULONG					i, AccuTxTotalCnt = 0, TxTotalCnt;
-	ULONG					TxErrorRatio = 0;
-	BOOLEAN					bTxRateChanged, bUpgradeQuality = FALSE;
-	PRTMP_TX_RATE_SWITCH	pCurrTxRate, pNextTxRate = NULL;
-	PUCHAR					pTable;
-	UCHAR					TableSize = 0;
-	UCHAR					InitTxRateIdx = 0, TrainUp, TrainDown;
-	CHAR					Rssi, RssiOffset = 0;
-	TX_STA_CNT1_STRUC		StaTx1;
-	TX_STA_CNT0_STRUC		TxStaCnt0;
-	ULONG					TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
-	MAC_TABLE_ENTRY			*pEntry;
+	u8 UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx;
+	unsigned long i, AccuTxTotalCnt = 0, TxTotalCnt;
+	unsigned long TxErrorRatio = 0;
+	BOOLEAN bTxRateChanged = FALSE, bUpgradeQuality = FALSE;
+	struct rt_rtmp_tx_rate_switch *pCurrTxRate, *pNextTxRate = NULL;
+	u8 *pTable;
+	u8 TableSize = 0;
+	u8 InitTxRateIdx = 0, TrainUp, TrainDown;
+	char Rssi, RssiOffset = 0;
+	TX_STA_CNT1_STRUC StaTx1;
+	TX_STA_CNT0_STRUC TxStaCnt0;
+	unsigned long TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
+	struct rt_mac_table_entry *pEntry;
+	struct rt_rssi_sample *pRssi = &pAd->StaCfg.RssiSample;
 
-	//
-	// walk through MAC table, see if need to change AP's TX rate toward each entry
-	//
-   	for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
-	{
+	/* */
+	/* walk through MAC table, see if need to change AP's TX rate toward each entry */
+	/* */
+	for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) {
 		pEntry = &pAd->MacTab.Content[i];
 
-		// check if this entry need to switch rate automatically
+		/* check if this entry need to switch rate automatically */
 		if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
 			continue;
 
-		if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls))
-		{
-#ifdef RT2860
-			Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.RssiSample.AvgRssi0, (CHAR)pAd->StaCfg.RssiSample.AvgRssi1, (CHAR)pAd->StaCfg.RssiSample.AvgRssi2);
-#endif
-#ifdef RT2870
+		if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls)) {
 			Rssi = RTMPMaxRssi(pAd,
-							   pAd->StaCfg.RssiSample.AvgRssi0,
-							   pAd->StaCfg.RssiSample.AvgRssi1,
-							   pAd->StaCfg.RssiSample.AvgRssi2);
-#endif
+					   pRssi->AvgRssi0,
+					   pRssi->AvgRssi1, pRssi->AvgRssi2);
 
-			// Update statistic counter
+			/* Update statistic counter */
 			RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
 			RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
 			pAd->bUpdateBcnCntDone = TRUE;
@@ -2045,291 +1881,293 @@
 			TxFailCount = TxStaCnt0.field.TxFailCount;
 			TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
 
-			pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
-			pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
-			pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
-			pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
-			pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
-			pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
+			pAd->RalinkCounters.OneSecTxRetryOkCount +=
+			    StaTx1.field.TxRetransmit;
+			pAd->RalinkCounters.OneSecTxNoRetryOkCount +=
+			    StaTx1.field.TxSuccess;
+			pAd->RalinkCounters.OneSecTxFailCount +=
+			    TxStaCnt0.field.TxFailCount;
+			pAd->WlanCounters.TransmittedFragmentCount.u.LowPart +=
+			    StaTx1.field.TxSuccess;
+			pAd->WlanCounters.RetryCount.u.LowPart +=
+			    StaTx1.field.TxRetransmit;
+			pAd->WlanCounters.FailedCount.u.LowPart +=
+			    TxStaCnt0.field.TxFailCount;
 
-			// if no traffic in the past 1-sec period, don't change TX rate,
-			// but clear all bad history. because the bad history may affect the next
-			// Chariot throughput test
-			AccuTxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
-						 pAd->RalinkCounters.OneSecTxRetryOkCount +
-						 pAd->RalinkCounters.OneSecTxFailCount;
+			/* if no traffic in the past 1-sec period, don't change TX rate, */
+			/* but clear all bad history. because the bad history may affect the next */
+			/* Chariot throughput test */
+			AccuTxTotalCnt =
+			    pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+			    pAd->RalinkCounters.OneSecTxRetryOkCount +
+			    pAd->RalinkCounters.OneSecTxFailCount;
 
 			if (TxTotalCnt)
-				TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
-		}
-		else
-		{
-#ifdef RT2860
-			Rssi = RTMPMaxRssi(pAd, (CHAR)pEntry->RssiSample.AvgRssi0, (CHAR)pEntry->RssiSample.AvgRssi1, (CHAR)pEntry->RssiSample.AvgRssi2);
-#endif
-#ifdef RT2870
+				TxErrorRatio =
+				    ((TxRetransmit +
+				      TxFailCount) * 100) / TxTotalCnt;
+		} else {
 			if (INFRA_ON(pAd) && (i == 1))
 				Rssi = RTMPMaxRssi(pAd,
-								   pAd->StaCfg.RssiSample.AvgRssi0,
-								   pAd->StaCfg.RssiSample.AvgRssi1,
-								   pAd->StaCfg.RssiSample.AvgRssi2);
+						   pRssi->AvgRssi0,
+						   pRssi->AvgRssi1,
+						   pRssi->AvgRssi2);
 			else
 				Rssi = RTMPMaxRssi(pAd,
-								   pEntry->RssiSample.AvgRssi0,
-								   pEntry->RssiSample.AvgRssi1,
-								   pEntry->RssiSample.AvgRssi2);
-#endif
+						   pEntry->RssiSample.AvgRssi0,
+						   pEntry->RssiSample.AvgRssi1,
+						   pEntry->RssiSample.AvgRssi2);
 
 			TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
-				 pEntry->OneSecTxRetryOkCount +
-				 pEntry->OneSecTxFailCount;
+			    pEntry->OneSecTxRetryOkCount +
+			    pEntry->OneSecTxFailCount;
 
 			if (TxTotalCnt)
-				TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
+				TxErrorRatio =
+				    ((pEntry->OneSecTxRetryOkCount +
+				      pEntry->OneSecTxFailCount) * 100) /
+				    TxTotalCnt;
+		}
+
+		if (TxTotalCnt) {
+			/*
+			   Three AdHoc connections can not work normally if one AdHoc connection is disappeared from a heavy traffic environment generated by ping tool
+			   We force to set LongRtyLimit and ShortRtyLimit to 0 to stop retransmitting packet, after a while, resoring original settings
+			 */
+			if (TxErrorRatio == 100) {
+				TX_RTY_CFG_STRUC TxRtyCfg, TxRtyCfgtmp;
+				unsigned long Index;
+				unsigned long MACValue;
+
+				RTMP_IO_READ32(pAd, TX_RTY_CFG, &TxRtyCfg.word);
+				TxRtyCfgtmp.word = TxRtyCfg.word;
+				TxRtyCfg.field.LongRtyLimit = 0x0;
+				TxRtyCfg.field.ShortRtyLimit = 0x0;
+				RTMP_IO_WRITE32(pAd, TX_RTY_CFG, TxRtyCfg.word);
+
+				RTMPusecDelay(1);
+
+				Index = 0;
+				MACValue = 0;
+				do {
+					RTMP_IO_READ32(pAd, TXRXQ_PCNT,
+						       &MACValue);
+					if ((MACValue & 0xffffff) == 0)
+						break;
+					Index++;
+					RTMPusecDelay(1000);
+				} while ((Index < 330)
+					 &&
+					 (!RTMP_TEST_FLAG
+					  (pAd,
+					   fRTMP_ADAPTER_HALT_IN_PROGRESS)));
+
+				RTMP_IO_READ32(pAd, TX_RTY_CFG, &TxRtyCfg.word);
+				TxRtyCfg.field.LongRtyLimit =
+				    TxRtyCfgtmp.field.LongRtyLimit;
+				TxRtyCfg.field.ShortRtyLimit =
+				    TxRtyCfgtmp.field.ShortRtyLimit;
+				RTMP_IO_WRITE32(pAd, TX_RTY_CFG, TxRtyCfg.word);
+			}
 		}
 
 		CurrRateIdx = pEntry->CurrTxRateIndex;
 
-		MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
+		MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize,
+				      &InitTxRateIdx);
 
-		if (CurrRateIdx >= TableSize)
-		{
+		if (CurrRateIdx >= TableSize) {
 			CurrRateIdx = TableSize - 1;
 		}
-
-		// When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex.
-		// So need to sync here.
-		pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
+		/* When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex. */
+		/* So need to sync here. */
+		pCurrTxRate =
+		    (struct rt_rtmp_tx_rate_switch *) & pTable[(CurrRateIdx + 1) * 5];
 		if ((pEntry->HTPhyMode.field.MCS != pCurrTxRate->CurrMCS)
-			//&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
-			)
-		{
+		    /*&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE) */
+		    ) {
 
-			// Need to sync Real Tx rate and our record.
-			// Then return for next DRS.
-			pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(InitTxRateIdx+1)*5];
+			/* Need to sync Real Tx rate and our record. */
+			/* Then return for next DRS. */
+			pCurrTxRate =
+			    (struct rt_rtmp_tx_rate_switch *) & pTable[(InitTxRateIdx + 1)
+							    * 5];
 			pEntry->CurrTxRateIndex = InitTxRateIdx;
 			MlmeSetTxRate(pAd, pEntry, pCurrTxRate);
 
-			// reset all OneSecTx counters
+			/* reset all OneSecTx counters */
 			RESET_ONE_SEC_TX_CNT(pEntry);
 			continue;
 		}
-
-		// decide the next upgrade rate and downgrade rate, if any
-		if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
-		{
+		/* decide the next upgrade rate and downgrade rate, if any */
+		if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1))) {
 			UpRateIdx = CurrRateIdx + 1;
-			DownRateIdx = CurrRateIdx -1;
-		}
-		else if (CurrRateIdx == 0)
-		{
+			DownRateIdx = CurrRateIdx - 1;
+		} else if (CurrRateIdx == 0) {
 			UpRateIdx = CurrRateIdx + 1;
 			DownRateIdx = CurrRateIdx;
-		}
-		else if (CurrRateIdx == (TableSize - 1))
-		{
+		} else if (CurrRateIdx == (TableSize - 1)) {
 			UpRateIdx = CurrRateIdx;
 			DownRateIdx = CurrRateIdx - 1;
 		}
 
-		pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
+		pCurrTxRate =
+		    (struct rt_rtmp_tx_rate_switch *) & pTable[(CurrRateIdx + 1) * 5];
 
-		if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
-		{
-			TrainUp		= (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
-			TrainDown	= (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
-		}
-		else
-		{
-			TrainUp		= pCurrTxRate->TrainUp;
-			TrainDown	= pCurrTxRate->TrainDown;
+		if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX)) {
+			TrainUp =
+			    (pCurrTxRate->TrainUp +
+			     (pCurrTxRate->TrainUp >> 1));
+			TrainDown =
+			    (pCurrTxRate->TrainDown +
+			     (pCurrTxRate->TrainDown >> 1));
+		} else {
+			TrainUp = pCurrTxRate->TrainUp;
+			TrainDown = pCurrTxRate->TrainDown;
 		}
 
-		//pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction;
+		/*pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction; */
 
-		//
-		// Keep the last time TxRateChangeAction status.
-		//
-		pEntry->LastTimeTxRateChangeAction = pEntry->LastSecTxRateChangeAction;
+		/* */
+		/* Keep the last time TxRateChangeAction status. */
+		/* */
+		pEntry->LastTimeTxRateChangeAction =
+		    pEntry->LastSecTxRateChangeAction;
 
+		/* */
+		/* CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI */
+		/*         (criteria copied from RT2500 for Netopia case) */
+		/* */
+		if (TxTotalCnt <= 15) {
+			char idx = 0;
+			u8 TxRateIdx;
+			u8 MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 =
+			    0, MCS5 = 0, MCS6 = 0, MCS7 = 0;
+			u8 MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
+			u8 MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0;	/* 3*3 */
 
+			/* check the existence and index of each needed MCS */
+			while (idx < pTable[0]) {
+				pCurrTxRate =
+				    (struct rt_rtmp_tx_rate_switch *) & pTable[(idx + 1) *
+								    5];
 
-		//
-		// CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
-		//         (criteria copied from RT2500 for Netopia case)
-		//
-		if (TxTotalCnt <= 15)
-		{
-			CHAR	idx = 0;
-			UCHAR	TxRateIdx;
-			//UCHAR	MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS7 = 0, MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
-			UCHAR	MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0,  MCS5 =0, MCS6 = 0, MCS7 = 0;
-	        UCHAR	MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
-			UCHAR	MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0; // 3*3
-
-			// check the existence and index of each needed MCS
-			while (idx < pTable[0])
-			{
-				pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(idx+1)*5];
-
-				if (pCurrTxRate->CurrMCS == MCS_0)
-				{
+				if (pCurrTxRate->CurrMCS == MCS_0) {
 					MCS0 = idx;
-				}
-				else if (pCurrTxRate->CurrMCS == MCS_1)
-				{
+				} else if (pCurrTxRate->CurrMCS == MCS_1) {
 					MCS1 = idx;
-				}
-				else if (pCurrTxRate->CurrMCS == MCS_2)
-				{
+				} else if (pCurrTxRate->CurrMCS == MCS_2) {
 					MCS2 = idx;
-				}
-				else if (pCurrTxRate->CurrMCS == MCS_3)
-				{
+				} else if (pCurrTxRate->CurrMCS == MCS_3) {
 					MCS3 = idx;
-				}
-				else if (pCurrTxRate->CurrMCS == MCS_4)
-				{
+				} else if (pCurrTxRate->CurrMCS == MCS_4) {
 					MCS4 = idx;
+				} else if (pCurrTxRate->CurrMCS == MCS_5) {
+					MCS5 = idx;
+				} else if (pCurrTxRate->CurrMCS == MCS_6) {
+					MCS6 = idx;
 				}
-	            else if (pCurrTxRate->CurrMCS == MCS_5)
-	            {
-	                MCS5 = idx;
-	            }
-	            else if (pCurrTxRate->CurrMCS == MCS_6)
-	            {
-	                MCS6 = idx;
-	            }
-				//else if (pCurrTxRate->CurrMCS == MCS_7)
-				else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800))	// prevent the highest MCS using short GI when 1T and low throughput
+				/*else if (pCurrTxRate->CurrMCS == MCS_7) */
+				else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800))	/* prevent the highest MCS using short GI when 1T and low throughput */
 				{
 					MCS7 = idx;
-				}
-				else if (pCurrTxRate->CurrMCS == MCS_12)
-				{
+				} else if (pCurrTxRate->CurrMCS == MCS_12) {
 					MCS12 = idx;
-				}
-				else if (pCurrTxRate->CurrMCS == MCS_13)
-				{
+				} else if (pCurrTxRate->CurrMCS == MCS_13) {
 					MCS13 = idx;
-				}
-				else if (pCurrTxRate->CurrMCS == MCS_14)
-				{
+				} else if (pCurrTxRate->CurrMCS == MCS_14) {
 					MCS14 = idx;
 				}
-				else if ((pCurrTxRate->CurrMCS == MCS_15) && (pCurrTxRate->ShortGI == GI_800))	//we hope to use ShortGI as initial rate, however Atheros's chip has bugs when short GI
+				else if ((pCurrTxRate->CurrMCS == MCS_15) && (pCurrTxRate->ShortGI == GI_800))	/*we hope to use ShortGI as initial rate, however Atheros's chip has bugs when short GI */
 				{
 					MCS15 = idx;
-				}
-				else if (pCurrTxRate->CurrMCS == MCS_20) // 3*3
+				} else if (pCurrTxRate->CurrMCS == MCS_20)	/* 3*3 */
 				{
 					MCS20 = idx;
-				}
-				else if (pCurrTxRate->CurrMCS == MCS_21)
-				{
+				} else if (pCurrTxRate->CurrMCS == MCS_21) {
 					MCS21 = idx;
-				}
-				else if (pCurrTxRate->CurrMCS == MCS_22)
-				{
+				} else if (pCurrTxRate->CurrMCS == MCS_22) {
 					MCS22 = idx;
-				}
-				else if (pCurrTxRate->CurrMCS == MCS_23)
-				{
+				} else if (pCurrTxRate->CurrMCS == MCS_23) {
 					MCS23 = idx;
 				}
-				idx ++;
+				idx++;
 			}
 
-			if (pAd->LatchRfRegs.Channel <= 14)
-			{
-				if (pAd->NicConfig2.field.ExternalLNAForG)
-				{
+			if (pAd->LatchRfRegs.Channel <= 14) {
+				if (pAd->NicConfig2.field.ExternalLNAForG) {
 					RssiOffset = 2;
-				}
-				else
-				{
+				} else {
 					RssiOffset = 5;
 				}
-			}
-			else
-			{
-				if (pAd->NicConfig2.field.ExternalLNAForA)
-				{
+			} else {
+				if (pAd->NicConfig2.field.ExternalLNAForA) {
 					RssiOffset = 5;
-				}
-				else
-				{
+				} else {
 					RssiOffset = 8;
 				}
 			}
 
-			/*if (MCS15)*/
-			if ((pTable == RateSwitchTable11BGN3S) ||
-				(pTable == RateSwitchTable11N3S) ||
-				(pTable == RateSwitchTable))
-			{// N mode with 3 stream // 3*3
+			/*if (MCS15) */
+			if ((pTable == RateSwitchTable11BGN3S) || (pTable == RateSwitchTable11N3S) || (pTable == RateSwitchTable)) {	/* N mode with 3 stream // 3*3 */
 				if (MCS23 && (Rssi >= -70))
-					TxRateIdx = MCS15;
+					TxRateIdx = MCS23;
 				else if (MCS22 && (Rssi >= -72))
-					TxRateIdx = MCS14;
-        	    else if (MCS21 && (Rssi >= -76))
-					TxRateIdx = MCS13;
+					TxRateIdx = MCS22;
+				else if (MCS21 && (Rssi >= -76))
+					TxRateIdx = MCS21;
 				else if (MCS20 && (Rssi >= -78))
-					TxRateIdx = MCS12;
-			else if (MCS4 && (Rssi >= -82))
-				TxRateIdx = MCS4;
-			else if (MCS3 && (Rssi >= -84))
-				TxRateIdx = MCS3;
-			else if (MCS2 && (Rssi >= -86))
-				TxRateIdx = MCS2;
-			else if (MCS1 && (Rssi >= -88))
-				TxRateIdx = MCS1;
-			else
-				TxRateIdx = MCS0;
-		}
-		else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand)) // 3*3
-			{// N mode with 2 stream
-				if (MCS15 && (Rssi >= (-70+RssiOffset)))
+					TxRateIdx = MCS20;
+				else if (MCS4 && (Rssi >= -82))
+					TxRateIdx = MCS4;
+				else if (MCS3 && (Rssi >= -84))
+					TxRateIdx = MCS3;
+				else if (MCS2 && (Rssi >= -86))
+					TxRateIdx = MCS2;
+				else if (MCS1 && (Rssi >= -88))
+					TxRateIdx = MCS1;
+				else
+					TxRateIdx = MCS0;
+			}
+/*              else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand) || (pTable == RateSwitchTable)) */
+			else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) || (pTable == RateSwitchTable11N2S) || (pTable == RateSwitchTable11N2SForABand))	/* 3*3 */
+			{	/* N mode with 2 stream */
+				if (MCS15 && (Rssi >= (-70 + RssiOffset)))
 					TxRateIdx = MCS15;
-				else if (MCS14 && (Rssi >= (-72+RssiOffset)))
+				else if (MCS14 && (Rssi >= (-72 + RssiOffset)))
 					TxRateIdx = MCS14;
-				else if (MCS13 && (Rssi >= (-76+RssiOffset)))
+				else if (MCS13 && (Rssi >= (-76 + RssiOffset)))
 					TxRateIdx = MCS13;
-				else if (MCS12 && (Rssi >= (-78+RssiOffset)))
+				else if (MCS12 && (Rssi >= (-78 + RssiOffset)))
 					TxRateIdx = MCS12;
-				else if (MCS4 && (Rssi >= (-82+RssiOffset)))
+				else if (MCS4 && (Rssi >= (-82 + RssiOffset)))
 					TxRateIdx = MCS4;
-				else if (MCS3 && (Rssi >= (-84+RssiOffset)))
+				else if (MCS3 && (Rssi >= (-84 + RssiOffset)))
 					TxRateIdx = MCS3;
-				else if (MCS2 && (Rssi >= (-86+RssiOffset)))
+				else if (MCS2 && (Rssi >= (-86 + RssiOffset)))
 					TxRateIdx = MCS2;
-				else if (MCS1 && (Rssi >= (-88+RssiOffset)))
+				else if (MCS1 && (Rssi >= (-88 + RssiOffset)))
 					TxRateIdx = MCS1;
 				else
 					TxRateIdx = MCS0;
-			}
-			else if ((pTable == RateSwitchTable11BGN1S) || (pTable == RateSwitchTable11N1S))
-			{// N mode with 1 stream
-				if (MCS7 && (Rssi > (-72+RssiOffset)))
+			} else if ((pTable == RateSwitchTable11BGN1S) || (pTable == RateSwitchTable11N1S)) {	/* N mode with 1 stream */
+				if (MCS7 && (Rssi > (-72 + RssiOffset)))
 					TxRateIdx = MCS7;
-				else if (MCS6 && (Rssi > (-74+RssiOffset)))
+				else if (MCS6 && (Rssi > (-74 + RssiOffset)))
 					TxRateIdx = MCS6;
-				else if (MCS5 && (Rssi > (-77+RssiOffset)))
+				else if (MCS5 && (Rssi > (-77 + RssiOffset)))
 					TxRateIdx = MCS5;
-				else if (MCS4 && (Rssi > (-79+RssiOffset)))
+				else if (MCS4 && (Rssi > (-79 + RssiOffset)))
 					TxRateIdx = MCS4;
-				else if (MCS3 && (Rssi > (-81+RssiOffset)))
+				else if (MCS3 && (Rssi > (-81 + RssiOffset)))
 					TxRateIdx = MCS3;
-				else if (MCS2 && (Rssi > (-83+RssiOffset)))
+				else if (MCS2 && (Rssi > (-83 + RssiOffset)))
 					TxRateIdx = MCS2;
-				else if (MCS1 && (Rssi > (-86+RssiOffset)))
+				else if (MCS1 && (Rssi > (-86 + RssiOffset)))
 					TxRateIdx = MCS1;
 				else
 					TxRateIdx = MCS0;
-			}
-			else
-			{// Legacy mode
+			} else {	/* Legacy mode */
 				if (MCS7 && (Rssi > -70))
 					TxRateIdx = MCS7;
 				else if (MCS6 && (Rssi > -74))
@@ -2338,7 +2176,7 @@
 					TxRateIdx = MCS5;
 				else if (MCS4 && (Rssi > -82))
 					TxRateIdx = MCS4;
-				else if (MCS4 == 0)	// for B-only mode
+				else if (MCS4 == 0)	/* for B-only mode */
 					TxRateIdx = MCS3;
 				else if (MCS3 && (Rssi > -85))
 					TxRateIdx = MCS3;
@@ -2350,129 +2188,158 @@
 					TxRateIdx = MCS0;
 			}
 
+			/*              if (TxRateIdx != pAd->CommonCfg.TxRateIndex) */
 			{
 				pEntry->CurrTxRateIndex = TxRateIdx;
-				pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
+				pNextTxRate =
+				    (struct rt_rtmp_tx_rate_switch *) &
+				    pTable[(pEntry->CurrTxRateIndex + 1) * 5];
 				MlmeSetTxRate(pAd, pEntry, pNextTxRate);
 			}
 
-			NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
-			NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
+			NdisZeroMemory(pEntry->TxQuality,
+				       sizeof(u16)*
+				       MAX_STEP_OF_TX_RATE_SWITCH);
+			NdisZeroMemory(pEntry->PER,
+				       sizeof(u8)*
+				       MAX_STEP_OF_TX_RATE_SWITCH);
 			pEntry->fLastSecAccordingRSSI = TRUE;
-			// reset all OneSecTx counters
+			/* reset all OneSecTx counters */
 			RESET_ONE_SEC_TX_CNT(pEntry);
 
 			continue;
 		}
 
-		if (pEntry->fLastSecAccordingRSSI == TRUE)
-		{
+		if (pEntry->fLastSecAccordingRSSI == TRUE) {
 			pEntry->fLastSecAccordingRSSI = FALSE;
 			pEntry->LastSecTxRateChangeAction = 0;
-			// reset all OneSecTx counters
+			/* reset all OneSecTx counters */
 			RESET_ONE_SEC_TX_CNT(pEntry);
 
 			continue;
 		}
 
-		do
-		{
-			BOOLEAN	bTrainUpDown = FALSE;
+		do {
+			BOOLEAN bTrainUpDown = FALSE;
 
-			pEntry->CurrTxRateStableTime ++;
+			pEntry->CurrTxRateStableTime++;
 
-			// downgrade TX quality if PER >= Rate-Down threshold
-			if (TxErrorRatio >= TrainDown)
-			{
+			/* downgrade TX quality if PER >= Rate-Down threshold */
+			if (TxErrorRatio >= TrainDown) {
 				bTrainUpDown = TRUE;
-				pEntry->TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
+				pEntry->TxQuality[CurrRateIdx] =
+				    DRS_TX_QUALITY_WORST_BOUND;
 			}
-			// upgrade TX quality if PER <= Rate-Up threshold
-			else if (TxErrorRatio <= TrainUp)
-			{
+			/* upgrade TX quality if PER <= Rate-Up threshold */
+			else if (TxErrorRatio <= TrainUp) {
 				bTrainUpDown = TRUE;
 				bUpgradeQuality = TRUE;
 				if (pEntry->TxQuality[CurrRateIdx])
-					pEntry->TxQuality[CurrRateIdx] --;  // quality very good in CurrRate
+					pEntry->TxQuality[CurrRateIdx]--;	/* quality very good in CurrRate */
 
 				if (pEntry->TxRateUpPenalty)
-					pEntry->TxRateUpPenalty --;
+					pEntry->TxRateUpPenalty--;
 				else if (pEntry->TxQuality[UpRateIdx])
-					pEntry->TxQuality[UpRateIdx] --;    // may improve next UP rate's quality
+					pEntry->TxQuality[UpRateIdx]--;	/* may improve next UP rate's quality */
 			}
 
-			pEntry->PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
+			pEntry->PER[CurrRateIdx] = (u8)TxErrorRatio;
 
-			if (bTrainUpDown)
-			{
-				// perform DRS - consider TxRate Down first, then rate up.
-				if ((CurrRateIdx != DownRateIdx) && (pEntry->TxQuality[CurrRateIdx] >= DRS_TX_QUALITY_WORST_BOUND))
-				{
+			if (bTrainUpDown) {
+				/* perform DRS - consider TxRate Down first, then rate up. */
+				if ((CurrRateIdx != DownRateIdx)
+				    && (pEntry->TxQuality[CurrRateIdx] >=
+					DRS_TX_QUALITY_WORST_BOUND)) {
 					pEntry->CurrTxRateIndex = DownRateIdx;
-				}
-				else if ((CurrRateIdx != UpRateIdx) && (pEntry->TxQuality[UpRateIdx] <= 0))
-				{
+				} else if ((CurrRateIdx != UpRateIdx)
+					   && (pEntry->TxQuality[UpRateIdx] <=
+					       0)) {
 					pEntry->CurrTxRateIndex = UpRateIdx;
 				}
 			}
 		} while (FALSE);
 
-		// if rate-up happen, clear all bad history of all TX rates
-		if (pEntry->CurrTxRateIndex > CurrRateIdx)
-		{
+		/* if rate-up happen, clear all bad history of all TX rates */
+		if (pEntry->CurrTxRateIndex > CurrRateIdx) {
 			pEntry->CurrTxRateStableTime = 0;
 			pEntry->TxRateUpPenalty = 0;
-			pEntry->LastSecTxRateChangeAction = 1; // rate UP
-			NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
-			NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
+			pEntry->LastSecTxRateChangeAction = 1;	/* rate UP */
+			NdisZeroMemory(pEntry->TxQuality,
+				       sizeof(u16)*
+				       MAX_STEP_OF_TX_RATE_SWITCH);
+			NdisZeroMemory(pEntry->PER,
+				       sizeof(u8)*
+				       MAX_STEP_OF_TX_RATE_SWITCH);
 
-			//
-			// For TxRate fast train up
-			//
-			if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
-			{
-				RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
+			/* */
+			/* For TxRate fast train up */
+			/* */
+			if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning) {
+				RTMPSetTimer(&pAd->StaCfg.
+					     StaQuickResponeForRateUpTimer,
+					     100);
 
-				pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
+				pAd->StaCfg.
+				    StaQuickResponeForRateUpTimerRunning = TRUE;
 			}
 			bTxRateChanged = TRUE;
 		}
-		// if rate-down happen, only clear DownRate's bad history
-		else if (pEntry->CurrTxRateIndex < CurrRateIdx)
-		{
+		/* if rate-down happen, only clear DownRate's bad history */
+		else if (pEntry->CurrTxRateIndex < CurrRateIdx) {
 			pEntry->CurrTxRateStableTime = 0;
-			pEntry->TxRateUpPenalty = 0;           // no penalty
-			pEntry->LastSecTxRateChangeAction = 2; // rate DOWN
+			pEntry->TxRateUpPenalty = 0;	/* no penalty */
+			pEntry->LastSecTxRateChangeAction = 2;	/* rate DOWN */
 			pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0;
 			pEntry->PER[pEntry->CurrTxRateIndex] = 0;
 
-			//
-			// For TxRate fast train down
-			//
-			if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
-			{
-				RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
+			/* */
+			/* For TxRate fast train down */
+			/* */
+			if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning) {
+				RTMPSetTimer(&pAd->StaCfg.
+					     StaQuickResponeForRateUpTimer,
+					     100);
 
-				pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
+				pAd->StaCfg.
+				    StaQuickResponeForRateUpTimerRunning = TRUE;
 			}
 			bTxRateChanged = TRUE;
-		}
-		else
-		{
-			pEntry->LastSecTxRateChangeAction = 0; // rate no change
+		} else {
+			pEntry->LastSecTxRateChangeAction = 0;	/* rate no change */
 			bTxRateChanged = FALSE;
 		}
 
 		pEntry->LastTxOkCount = TxSuccess;
-
-		// reset all OneSecTx counters
-		RESET_ONE_SEC_TX_CNT(pEntry);
-
-		pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
-		if (bTxRateChanged && pNextTxRate)
 		{
+			u8 tmpTxRate;
+
+			/* to fix tcp ack issue */
+			if (!bTxRateChanged
+			    && (pAd->RalinkCounters.OneSecReceivedByteCount >
+				(pAd->RalinkCounters.
+				 OneSecTransmittedByteCount * 5))) {
+				tmpTxRate = DownRateIdx;
+				DBGPRINT_RAW(RT_DEBUG_TRACE,
+					     ("DRS: Rx(%d) is 5 times larger than Tx(%d), use low rate (curr=%d, tmp=%d)\n",
+					      pAd->RalinkCounters.
+					      OneSecReceivedByteCount,
+					      pAd->RalinkCounters.
+					      OneSecTransmittedByteCount,
+					      pEntry->CurrTxRateIndex,
+					      tmpTxRate));
+			} else {
+				tmpTxRate = pEntry->CurrTxRateIndex;
+			}
+
+			pNextTxRate =
+			    (struct rt_rtmp_tx_rate_switch *) & pTable[(tmpTxRate + 1) *
+							    5];
+		}
+		if (bTxRateChanged && pNextTxRate) {
 			MlmeSetTxRate(pAd, pEntry, pNextTxRate);
 		}
+		/* reset all OneSecTx counters */
+		RESET_ONE_SEC_TX_CNT(pEntry);
 	}
 }
 
@@ -2492,103 +2359,84 @@
 
 	========================================================================
 */
-VOID StaQuickResponeForRateUpExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3)
+void StaQuickResponeForRateUpExec(void *SystemSpecific1,
+				  void *FunctionContext,
+				  void *SystemSpecific2,
+				  void *SystemSpecific3)
 {
-	PRTMP_ADAPTER			pAd = (PRTMP_ADAPTER)FunctionContext;
-	UCHAR					UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0;
-	ULONG					TxTotalCnt;
-	ULONG					TxErrorRatio = 0;
-#ifdef RT2860
-	BOOLEAN					bTxRateChanged = TRUE; //, bUpgradeQuality = FALSE;
-#endif
-#ifdef RT2870
-	BOOLEAN					bTxRateChanged; //, bUpgradeQuality = FALSE;
-#endif
-	PRTMP_TX_RATE_SWITCH	pCurrTxRate, pNextTxRate = NULL;
-	PUCHAR					pTable;
-	UCHAR					TableSize = 0;
-	UCHAR					InitTxRateIdx = 0, TrainUp, TrainDown;
-	TX_STA_CNT1_STRUC		StaTx1;
-	TX_STA_CNT0_STRUC		TxStaCnt0;
-	CHAR					Rssi, ratio;
-	ULONG					TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
-	MAC_TABLE_ENTRY			*pEntry;
-	ULONG					i;
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
+	u8 UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0;
+	unsigned long TxTotalCnt;
+	unsigned long TxErrorRatio = 0;
+	BOOLEAN bTxRateChanged;	/*, bUpgradeQuality = FALSE; */
+	struct rt_rtmp_tx_rate_switch *pCurrTxRate, *pNextTxRate = NULL;
+	u8 *pTable;
+	u8 TableSize = 0;
+	u8 InitTxRateIdx = 0, TrainUp, TrainDown;
+	TX_STA_CNT1_STRUC StaTx1;
+	TX_STA_CNT0_STRUC TxStaCnt0;
+	char Rssi, ratio;
+	unsigned long TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
+	struct rt_mac_table_entry *pEntry;
+	unsigned long i;
 
 	pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
 
-    //
-    // walk through MAC table, see if need to change AP's TX rate toward each entry
-    //
-	for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
-	{
+	/* */
+	/* walk through MAC table, see if need to change AP's TX rate toward each entry */
+	/* */
+	for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) {
 		pEntry = &pAd->MacTab.Content[i];
 
-		// check if this entry need to switch rate automatically
+		/* check if this entry need to switch rate automatically */
 		if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
 			continue;
 
-#ifdef RT2860
-		//Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.AvgRssi0, (CHAR)pAd->StaCfg.AvgRssi1, (CHAR)pAd->StaCfg.AvgRssi2);
-	    if (pAd->Antenna.field.TxPath > 1)
-			Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
-		else
-			Rssi = pAd->StaCfg.RssiSample.AvgRssi0;
-#endif
-#ifdef RT2870
 		if (INFRA_ON(pAd) && (i == 1))
 			Rssi = RTMPMaxRssi(pAd,
-							   pAd->StaCfg.RssiSample.AvgRssi0,
-							   pAd->StaCfg.RssiSample.AvgRssi1,
-							   pAd->StaCfg.RssiSample.AvgRssi2);
+					   pAd->StaCfg.RssiSample.AvgRssi0,
+					   pAd->StaCfg.RssiSample.AvgRssi1,
+					   pAd->StaCfg.RssiSample.AvgRssi2);
 		else
 			Rssi = RTMPMaxRssi(pAd,
-							   pEntry->RssiSample.AvgRssi0,
-							   pEntry->RssiSample.AvgRssi1,
-							   pEntry->RssiSample.AvgRssi2);
-#endif
+					   pEntry->RssiSample.AvgRssi0,
+					   pEntry->RssiSample.AvgRssi1,
+					   pEntry->RssiSample.AvgRssi2);
 
 		CurrRateIdx = pAd->CommonCfg.TxRateIndex;
 
-			MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
+		MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize,
+				      &InitTxRateIdx);
 
-		// decide the next upgrade rate and downgrade rate, if any
-		if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
-		{
+		/* decide the next upgrade rate and downgrade rate, if any */
+		if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1))) {
 			UpRateIdx = CurrRateIdx + 1;
-			DownRateIdx = CurrRateIdx -1;
-		}
-		else if (CurrRateIdx == 0)
-		{
+			DownRateIdx = CurrRateIdx - 1;
+		} else if (CurrRateIdx == 0) {
 			UpRateIdx = CurrRateIdx + 1;
 			DownRateIdx = CurrRateIdx;
-		}
-		else if (CurrRateIdx == (TableSize - 1))
-		{
+		} else if (CurrRateIdx == (TableSize - 1)) {
 			UpRateIdx = CurrRateIdx;
 			DownRateIdx = CurrRateIdx - 1;
 		}
 
-		pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
+		pCurrTxRate =
+		    (struct rt_rtmp_tx_rate_switch *) & pTable[(CurrRateIdx + 1) * 5];
 
-		if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
-		{
-			TrainUp		= (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
-			TrainDown	= (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
-		}
-		else
-		{
-			TrainUp		= pCurrTxRate->TrainUp;
-			TrainDown	= pCurrTxRate->TrainDown;
+		if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX)) {
+			TrainUp =
+			    (pCurrTxRate->TrainUp +
+			     (pCurrTxRate->TrainUp >> 1));
+			TrainDown =
+			    (pCurrTxRate->TrainDown +
+			     (pCurrTxRate->TrainDown >> 1));
+		} else {
+			TrainUp = pCurrTxRate->TrainUp;
+			TrainDown = pCurrTxRate->TrainDown;
 		}
 
-		if (pAd->MacTab.Size == 1)
-		{
-			// Update statistic counter
+		if (pAd->MacTab.Size == 1) {
+			/* Update statistic counter */
 			RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
 			RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
 
@@ -2597,123 +2445,138 @@
 			TxFailCount = TxStaCnt0.field.TxFailCount;
 			TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
 
-			pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
-			pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
-			pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
-			pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
-			pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
-			pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
+			pAd->RalinkCounters.OneSecTxRetryOkCount +=
+			    StaTx1.field.TxRetransmit;
+			pAd->RalinkCounters.OneSecTxNoRetryOkCount +=
+			    StaTx1.field.TxSuccess;
+			pAd->RalinkCounters.OneSecTxFailCount +=
+			    TxStaCnt0.field.TxFailCount;
+			pAd->WlanCounters.TransmittedFragmentCount.u.LowPart +=
+			    StaTx1.field.TxSuccess;
+			pAd->WlanCounters.RetryCount.u.LowPart +=
+			    StaTx1.field.TxRetransmit;
+			pAd->WlanCounters.FailedCount.u.LowPart +=
+			    TxStaCnt0.field.TxFailCount;
 
 			if (TxTotalCnt)
-				TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
-		}
-		else
-		{
+				TxErrorRatio =
+				    ((TxRetransmit +
+				      TxFailCount) * 100) / TxTotalCnt;
+		} else {
 			TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
-				 pEntry->OneSecTxRetryOkCount +
-				 pEntry->OneSecTxFailCount;
+			    pEntry->OneSecTxRetryOkCount +
+			    pEntry->OneSecTxFailCount;
 
 			if (TxTotalCnt)
-				TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
+				TxErrorRatio =
+				    ((pEntry->OneSecTxRetryOkCount +
+				      pEntry->OneSecTxFailCount) * 100) /
+				    TxTotalCnt;
 		}
 
+		/* */
+		/* CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI */
+		/*         (criteria copied from RT2500 for Netopia case) */
+		/* */
+		if (TxTotalCnt <= 12) {
+			NdisZeroMemory(pAd->DrsCounters.TxQuality,
+				       sizeof(u16)*
+				       MAX_STEP_OF_TX_RATE_SWITCH);
+			NdisZeroMemory(pAd->DrsCounters.PER,
+				       sizeof(u8)*
+				       MAX_STEP_OF_TX_RATE_SWITCH);
 
-		//
-		// CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
-		//         (criteria copied from RT2500 for Netopia case)
-		//
-		if (TxTotalCnt <= 12)
-		{
-			NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
-			NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
-
-			if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
-			{
+			if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1)
+			    && (CurrRateIdx != DownRateIdx)) {
 				pAd->CommonCfg.TxRateIndex = DownRateIdx;
-				pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
-			}
-			else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
-			{
+				pAd->DrsCounters.TxQuality[CurrRateIdx] =
+				    DRS_TX_QUALITY_WORST_BOUND;
+			} else
+			    if ((pAd->DrsCounters.LastSecTxRateChangeAction ==
+				 2) && (CurrRateIdx != UpRateIdx)) {
 				pAd->CommonCfg.TxRateIndex = UpRateIdx;
 			}
 
-			DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: TxTotalCnt <= 15, train back to original rate \n"));
+			DBGPRINT_RAW(RT_DEBUG_TRACE,
+				     ("QuickDRS: TxTotalCnt <= 15, train back to original rate \n"));
 			return;
 		}
 
-		do
-		{
-			ULONG OneSecTxNoRetryOKRationCount;
+		do {
+			unsigned long OneSecTxNoRetryOKRationCount;
 
 			if (pAd->DrsCounters.LastTimeTxRateChangeAction == 0)
 				ratio = 5;
 			else
 				ratio = 4;
 
-			// downgrade TX quality if PER >= Rate-Down threshold
-			if (TxErrorRatio >= TrainDown)
-			{
-				pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
+			/* downgrade TX quality if PER >= Rate-Down threshold */
+			if (TxErrorRatio >= TrainDown) {
+				pAd->DrsCounters.TxQuality[CurrRateIdx] =
+				    DRS_TX_QUALITY_WORST_BOUND;
 			}
 
-			pAd->DrsCounters.PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
+			pAd->DrsCounters.PER[CurrRateIdx] =
+			    (u8)TxErrorRatio;
 
 			OneSecTxNoRetryOKRationCount = (TxSuccess * ratio);
 
-			// perform DRS - consider TxRate Down first, then rate up.
-			if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
-			{
-				if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
-				{
-					pAd->CommonCfg.TxRateIndex = DownRateIdx;
-					pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
+			/* perform DRS - consider TxRate Down first, then rate up. */
+			if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1)
+			    && (CurrRateIdx != DownRateIdx)) {
+				if ((pAd->DrsCounters.LastTxOkCount + 2) >=
+				    OneSecTxNoRetryOKRationCount) {
+					pAd->CommonCfg.TxRateIndex =
+					    DownRateIdx;
+					pAd->DrsCounters.
+					    TxQuality[CurrRateIdx] =
+					    DRS_TX_QUALITY_WORST_BOUND;
 
 				}
 
-			}
-			else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
-			{
-				if ((TxErrorRatio >= 50) || (TxErrorRatio >= TrainDown))
-				{
+			} else
+			    if ((pAd->DrsCounters.LastSecTxRateChangeAction ==
+				 2) && (CurrRateIdx != UpRateIdx)) {
+				if ((TxErrorRatio >= 50)
+				    || (TxErrorRatio >= TrainDown)) {
 
-				}
-				else if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
-				{
+				} else if ((pAd->DrsCounters.LastTxOkCount + 2)
+					   >= OneSecTxNoRetryOKRationCount) {
 					pAd->CommonCfg.TxRateIndex = UpRateIdx;
 				}
 			}
-		}while (FALSE);
+		} while (FALSE);
 
-		// if rate-up happen, clear all bad history of all TX rates
-		if (pAd->CommonCfg.TxRateIndex > CurrRateIdx)
-		{
+		/* if rate-up happen, clear all bad history of all TX rates */
+		if (pAd->CommonCfg.TxRateIndex > CurrRateIdx) {
 			pAd->DrsCounters.TxRateUpPenalty = 0;
-			NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
-			NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
-#ifdef RT2870
+			NdisZeroMemory(pAd->DrsCounters.TxQuality,
+				       sizeof(u16)*
+				       MAX_STEP_OF_TX_RATE_SWITCH);
+			NdisZeroMemory(pAd->DrsCounters.PER,
+				       sizeof(u8)*
+				       MAX_STEP_OF_TX_RATE_SWITCH);
 			bTxRateChanged = TRUE;
-#endif
 		}
-		// if rate-down happen, only clear DownRate's bad history
-		else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx)
-		{
-			DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: --TX rate from %d to %d \n", CurrRateIdx, pAd->CommonCfg.TxRateIndex));
+		/* if rate-down happen, only clear DownRate's bad history */
+		else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx) {
+			DBGPRINT_RAW(RT_DEBUG_TRACE,
+				     ("QuickDRS: --TX rate from %d to %d \n",
+				      CurrRateIdx, pAd->CommonCfg.TxRateIndex));
 
-			pAd->DrsCounters.TxRateUpPenalty = 0;           // no penalty
-			pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] = 0;
+			pAd->DrsCounters.TxRateUpPenalty = 0;	/* no penalty */
+			pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] =
+			    0;
 			pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0;
-#ifdef RT2870
 			bTxRateChanged = TRUE;
-#endif
-		}
-		else
-		{
+		} else {
 			bTxRateChanged = FALSE;
 		}
 
-		pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pAd->CommonCfg.TxRateIndex+1)*5];
-		if (bTxRateChanged && pNextTxRate)
-		{
+		pNextTxRate =
+		    (struct rt_rtmp_tx_rate_switch *) &
+		    pTable[(pAd->CommonCfg.TxRateIndex + 1) * 5];
+		if (bTxRateChanged && pNextTxRate) {
 			MlmeSetTxRate(pAd, pEntry, pNextTxRate);
 		}
 	}
@@ -2738,98 +2601,176 @@
 
 	==========================================================================
  */
-VOID MlmeCheckPsmChange(
-	IN PRTMP_ADAPTER pAd,
-	IN ULONG	Now32)
+void MlmeCheckPsmChange(struct rt_rtmp_adapter *pAd, unsigned long Now32)
 {
-	ULONG	PowerMode;
+	unsigned long PowerMode;
 
-	// condition -
-	// 1. Psm maybe ON only happen in INFRASTRUCTURE mode
-	// 2. user wants either MAX_PSP or FAST_PSP
-	// 3. but current psm is not in PWR_SAVE
-	// 4. CNTL state machine is not doing SCANning
-	// 5. no TX SUCCESS event for the past 1-sec period
-#ifdef NDIS51_MINIPORT
-	if (pAd->StaCfg.WindowsPowerProfile == NdisPowerProfileBattery)
-		PowerMode = pAd->StaCfg.WindowsBatteryPowerMode;
-	else
-#endif
-		PowerMode = pAd->StaCfg.WindowsPowerMode;
+	/* condition - */
+	/* 1. Psm maybe ON only happen in INFRASTRUCTURE mode */
+	/* 2. user wants either MAX_PSP or FAST_PSP */
+	/* 3. but current psm is not in PWR_SAVE */
+	/* 4. CNTL state machine is not doing SCANning */
+	/* 5. no TX SUCCESS event for the past 1-sec period */
+	PowerMode = pAd->StaCfg.WindowsPowerMode;
 
 	if (INFRA_ON(pAd) &&
-		(PowerMode != Ndis802_11PowerModeCAM) &&
-		(pAd->StaCfg.Psm == PWR_ACTIVE) &&
-#ifdef RT2860
-		RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP))
-#else
-		(pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
-#endif
-	{
-		// add by johnli, use Rx OK data count per second to calculate throughput
-		// If Ttraffic is too high ( > 400 Rx per second), don't go to sleep mode. If tx rate is low, use low criteria
-		// Mode=CCK/MCS=3 => 11 Mbps, Mode=OFDM/MCS=3 => 18 Mbps
-		if (((pAd->StaCfg.HTPhyMode.field.MCS <= 3) &&
-				(pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)100)) ||
-			((pAd->StaCfg.HTPhyMode.field.MCS > 3) &&
-			(pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)400)))
-		{
-				// Get this time
-			NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
-			pAd->RalinkCounters.RxCountSinceLastNULL = 0;
-			MlmeSetPsmBit(pAd, PWR_SAVE);
-			if (!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
-			{
-				RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
-			}
-			else
-			{
-				RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
-			}
+	    (PowerMode != Ndis802_11PowerModeCAM) &&
+	    (pAd->StaCfg.Psm == PWR_ACTIVE) &&
+/*              (! RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) */
+	    (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
+	    RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP)
+	    /*&&
+	       (pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
+	       (pAd->RalinkCounters.OneSecTxRetryOkCount == 0) */
+	    ) {
+		NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
+		pAd->RalinkCounters.RxCountSinceLastNULL = 0;
+		RTMP_SET_PSM_BIT(pAd, PWR_SAVE);
+		if (!
+		    (pAd->CommonCfg.bAPSDCapable
+		     && pAd->CommonCfg.APEdcaParm.bAPSDCapable)) {
+			RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
+		} else {
+			RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
 		}
 	}
 }
 
-// IRQL = PASSIVE_LEVEL
-// IRQL = DISPATCH_LEVEL
-VOID MlmeSetPsmBit(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT psm)
+/* IRQL = PASSIVE_LEVEL */
+/* IRQL = DISPATCH_LEVEL */
+void MlmeSetPsmBit(struct rt_rtmp_adapter *pAd, u16 psm)
 {
 	AUTO_RSP_CFG_STRUC csr4;
 
 	pAd->StaCfg.Psm = psm;
 	RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
-	csr4.field.AckCtsPsmBit = (psm == PWR_SAVE)? 1:0;
+	csr4.field.AckCtsPsmBit = (psm == PWR_SAVE) ? 1 : 0;
 	RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
 
 	DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetPsmBit = %d\n", psm));
 }
 
-// IRQL = DISPATCH_LEVEL
-VOID MlmeSetTxPreamble(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT TxPreamble)
+/*
+	==========================================================================
+	Description:
+		This routine calculates TxPER, RxPER of the past N-sec period. And
+		according to the calculation result, ChannelQuality is calculated here
+		to decide if current AP is still doing the job.
+
+		If ChannelQuality is not good, a ROAMing attempt may be tried later.
+	Output:
+		StaCfg.ChannelQuality - 0..100
+
+	IRQL = DISPATCH_LEVEL
+
+	NOTE: This routine decide channle quality based on RX CRC error ratio.
+		Caller should make sure a function call to NICUpdateRawCounters(pAd)
+		is performed right before this routine, so that this routine can decide
+		channel quality based on the most up-to-date information
+	==========================================================================
+ */
+void MlmeCalculateChannelQuality(struct rt_rtmp_adapter *pAd,
+				 struct rt_mac_table_entry *pMacEntry, unsigned long Now32)
+{
+	unsigned long TxOkCnt, TxCnt, TxPER, TxPRR;
+	unsigned long RxCnt, RxPER;
+	u8 NorRssi;
+	char MaxRssi;
+	struct rt_rssi_sample *pRssiSample = NULL;
+	u32 OneSecTxNoRetryOkCount = 0;
+	u32 OneSecTxRetryOkCount = 0;
+	u32 OneSecTxFailCount = 0;
+	u32 OneSecRxOkCnt = 0;
+	u32 OneSecRxFcsErrCnt = 0;
+	unsigned long ChannelQuality = 0;	/* 0..100, Channel Quality Indication for Roaming */
+	unsigned long BeaconLostTime = pAd->StaCfg.BeaconLostTime;
+
+	if (pAd->OpMode == OPMODE_STA) {
+		pRssiSample = &pAd->StaCfg.RssiSample;
+		OneSecTxNoRetryOkCount =
+		    pAd->RalinkCounters.OneSecTxNoRetryOkCount;
+		OneSecTxRetryOkCount = pAd->RalinkCounters.OneSecTxRetryOkCount;
+		OneSecTxFailCount = pAd->RalinkCounters.OneSecTxFailCount;
+		OneSecRxOkCnt = pAd->RalinkCounters.OneSecRxOkCnt;
+		OneSecRxFcsErrCnt = pAd->RalinkCounters.OneSecRxFcsErrCnt;
+	}
+
+	MaxRssi = RTMPMaxRssi(pAd, pRssiSample->LastRssi0,
+			      pRssiSample->LastRssi1, pRssiSample->LastRssi2);
+
+	/* */
+	/* calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics */
+	/* */
+	TxOkCnt = OneSecTxNoRetryOkCount + OneSecTxRetryOkCount;
+	TxCnt = TxOkCnt + OneSecTxFailCount;
+	if (TxCnt < 5) {
+		TxPER = 0;
+		TxPRR = 0;
+	} else {
+		TxPER = (OneSecTxFailCount * 100) / TxCnt;
+		TxPRR = ((TxCnt - OneSecTxNoRetryOkCount) * 100) / TxCnt;
+	}
+
+	/* */
+	/* calculate RX PER - don't take RxPER into consideration if too few sample */
+	/* */
+	RxCnt = OneSecRxOkCnt + OneSecRxFcsErrCnt;
+	if (RxCnt < 5)
+		RxPER = 0;
+	else
+		RxPER = (OneSecRxFcsErrCnt * 100) / RxCnt;
+
+	/* */
+	/* decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER */
+	/* */
+	if ((pAd->OpMode == OPMODE_STA) && INFRA_ON(pAd) && (OneSecTxNoRetryOkCount < 2) &&	/* no heavy traffic */
+	    ((pAd->StaCfg.LastBeaconRxTime + BeaconLostTime) < Now32)) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n",
+			  BeaconLostTime, TxOkCnt));
+		ChannelQuality = 0;
+	} else {
+		/* Normalize Rssi */
+		if (MaxRssi > -40)
+			NorRssi = 100;
+		else if (MaxRssi < -90)
+			NorRssi = 0;
+		else
+			NorRssi = (MaxRssi + 90) * 2;
+
+		/* ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER        (RSSI 0..100), (TxPER 100..0), (RxPER 100..0) */
+		ChannelQuality = (RSSI_WEIGHTING * NorRssi +
+				  TX_WEIGHTING * (100 - TxPRR) +
+				  RX_WEIGHTING * (100 - RxPER)) / 100;
+	}
+
+	if (pAd->OpMode == OPMODE_STA)
+		pAd->Mlme.ChannelQuality =
+		    (ChannelQuality > 100) ? 100 : ChannelQuality;
+
+}
+
+/* IRQL = DISPATCH_LEVEL */
+void MlmeSetTxPreamble(struct rt_rtmp_adapter *pAd, u16 TxPreamble)
 {
 	AUTO_RSP_CFG_STRUC csr4;
 
-	//
-	// Always use Long preamble before verifiation short preamble functionality works well.
-	// Todo: remove the following line if short preamble functionality works
-	//
-	//TxPreamble = Rt802_11PreambleLong;
+	/* */
+	/* Always use Long preamble before verifiation short preamble functionality works well. */
+	/* Todo: remove the following line if short preamble functionality works */
+	/* */
+	/*TxPreamble = Rt802_11PreambleLong; */
 
 	RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
-	if (TxPreamble == Rt802_11PreambleLong)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= LONG PREAMBLE)\n"));
+	if (TxPreamble == Rt802_11PreambleLong) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("MlmeSetTxPreamble (= long PREAMBLE)\n"));
 		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
 		csr4.field.AutoResponderPreamble = 0;
-	}
-	else
-	{
-		// NOTE: 1Mbps should always use long preamble
-		DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= SHORT PREAMBLE)\n"));
+	} else {
+		/* NOTE: 1Mbps should always use long preamble */
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("MlmeSetTxPreamble (= short PREAMBLE)\n"));
 		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
 		csr4.field.AutoResponderPreamble = 1;
 	}
@@ -2844,117 +2785,140 @@
     ==========================================================================
  */
 
-VOID UpdateBasicRateBitmap(
-    IN  PRTMP_ADAPTER   pAdapter)
+void UpdateBasicRateBitmap(struct rt_rtmp_adapter *pAdapter)
 {
-    INT  i, j;
-                  /* 1  2  5.5, 11,  6,  9, 12, 18, 24, 36, 48,  54 */
-    UCHAR rate[] = { 2, 4,  11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
-    UCHAR *sup_p = pAdapter->CommonCfg.SupRate;
-    UCHAR *ext_p = pAdapter->CommonCfg.ExtRate;
-    ULONG bitmap = pAdapter->CommonCfg.BasicRateBitmap;
+	int i, j;
+	/* 1  2  5.5, 11,  6,  9, 12, 18, 24, 36, 48,  54 */
+	u8 rate[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
+	u8 *sup_p = pAdapter->CommonCfg.SupRate;
+	u8 *ext_p = pAdapter->CommonCfg.ExtRate;
+	unsigned long bitmap = pAdapter->CommonCfg.BasicRateBitmap;
 
-
-    /* if A mode, always use fix BasicRateBitMap */
-    //if (pAdapter->CommonCfg.Channel == PHY_11A)
+	/* if A mode, always use fix BasicRateBitMap */
+	/*if (pAdapter->CommonCfg.Channel == PHY_11A) */
 	if (pAdapter->CommonCfg.Channel > 14)
-        pAdapter->CommonCfg.BasicRateBitmap = 0x150; /* 6, 12, 24M */
-    /* End of if */
+		pAdapter->CommonCfg.BasicRateBitmap = 0x150;	/* 6, 12, 24M */
+	/* End of if */
 
-    if (pAdapter->CommonCfg.BasicRateBitmap > 4095)
-    {
-        /* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */
-        return;
-    } /* End of if */
+	if (pAdapter->CommonCfg.BasicRateBitmap > 4095) {
+		/* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */
+		return;
+	}
+	/* End of if */
+	for (i = 0; i < MAX_LEN_OF_SUPPORTED_RATES; i++) {
+		sup_p[i] &= 0x7f;
+		ext_p[i] &= 0x7f;
+	}			/* End of for */
 
-    for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
-    {
-        sup_p[i] &= 0x7f;
-        ext_p[i] &= 0x7f;
-    } /* End of for */
+	for (i = 0; i < MAX_LEN_OF_SUPPORTED_RATES; i++) {
+		if (bitmap & (1 << i)) {
+			for (j = 0; j < MAX_LEN_OF_SUPPORTED_RATES; j++) {
+				if (sup_p[j] == rate[i])
+					sup_p[j] |= 0x80;
+				/* End of if */
+			}	/* End of for */
 
-    for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
-    {
-        if (bitmap & (1 << i))
-        {
-            for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
-            {
-                if (sup_p[j] == rate[i])
-                    sup_p[j] |= 0x80;
-                /* End of if */
-            } /* End of for */
+			for (j = 0; j < MAX_LEN_OF_SUPPORTED_RATES; j++) {
+				if (ext_p[j] == rate[i])
+					ext_p[j] |= 0x80;
+				/* End of if */
+			}	/* End of for */
+		}		/* End of if */
+	}			/* End of for */
+}				/* End of UpdateBasicRateBitmap */
 
-            for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
-            {
-                if (ext_p[j] == rate[i])
-                    ext_p[j] |= 0x80;
-                /* End of if */
-            } /* End of for */
-        } /* End of if */
-    } /* End of for */
-} /* End of UpdateBasicRateBitmap */
-
-// IRQL = PASSIVE_LEVEL
-// IRQL = DISPATCH_LEVEL
-// bLinkUp is to identify the inital link speed.
-// TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps.
-VOID MlmeUpdateTxRates(
-	IN PRTMP_ADAPTER 		pAd,
-	IN 	BOOLEAN		 		bLinkUp,
-	IN	UCHAR				apidx)
+/* IRQL = PASSIVE_LEVEL */
+/* IRQL = DISPATCH_LEVEL */
+/* bLinkUp is to identify the inital link speed. */
+/* TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps. */
+void MlmeUpdateTxRates(struct rt_rtmp_adapter *pAd, IN BOOLEAN bLinkUp, u8 apidx)
 {
 	int i, num;
-	UCHAR Rate = RATE_6, MaxDesire = RATE_1, MaxSupport = RATE_1;
-	UCHAR MinSupport = RATE_54;
-	ULONG BasicRateBitmap = 0;
-	UCHAR CurrBasicRate = RATE_1;
-	UCHAR *pSupRate, SupRateLen, *pExtRate, ExtRateLen;
-	PHTTRANSMIT_SETTING		pHtPhy = NULL;
-	PHTTRANSMIT_SETTING		pMaxHtPhy = NULL;
-	PHTTRANSMIT_SETTING		pMinHtPhy = NULL;
-	BOOLEAN 				*auto_rate_cur_p;
-	UCHAR					HtMcs = MCS_AUTO;
+	u8 Rate = RATE_6, MaxDesire = RATE_1, MaxSupport = RATE_1;
+	u8 MinSupport = RATE_54;
+	unsigned long BasicRateBitmap = 0;
+	u8 CurrBasicRate = RATE_1;
+	u8 *pSupRate, SupRateLen, *pExtRate, ExtRateLen;
+	PHTTRANSMIT_SETTING pHtPhy = NULL;
+	PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
+	PHTTRANSMIT_SETTING pMinHtPhy = NULL;
+	BOOLEAN *auto_rate_cur_p;
+	u8 HtMcs = MCS_AUTO;
 
-	// find max desired rate
+	/* find max desired rate */
 	UpdateBasicRateBitmap(pAd);
 
 	num = 0;
 	auto_rate_cur_p = NULL;
-	for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
-	{
-		switch (pAd->CommonCfg.DesireRate[i] & 0x7f)
-		{
-			case 2:  Rate = RATE_1;   num++;   break;
-			case 4:  Rate = RATE_2;   num++;   break;
-			case 11: Rate = RATE_5_5; num++;   break;
-			case 22: Rate = RATE_11;  num++;   break;
-			case 12: Rate = RATE_6;   num++;   break;
-			case 18: Rate = RATE_9;   num++;   break;
-			case 24: Rate = RATE_12;  num++;   break;
-			case 36: Rate = RATE_18;  num++;   break;
-			case 48: Rate = RATE_24;  num++;   break;
-			case 72: Rate = RATE_36;  num++;   break;
-			case 96: Rate = RATE_48;  num++;   break;
-			case 108: Rate = RATE_54; num++;   break;
-			//default: Rate = RATE_1;   break;
+	for (i = 0; i < MAX_LEN_OF_SUPPORTED_RATES; i++) {
+		switch (pAd->CommonCfg.DesireRate[i] & 0x7f) {
+		case 2:
+			Rate = RATE_1;
+			num++;
+			break;
+		case 4:
+			Rate = RATE_2;
+			num++;
+			break;
+		case 11:
+			Rate = RATE_5_5;
+			num++;
+			break;
+		case 22:
+			Rate = RATE_11;
+			num++;
+			break;
+		case 12:
+			Rate = RATE_6;
+			num++;
+			break;
+		case 18:
+			Rate = RATE_9;
+			num++;
+			break;
+		case 24:
+			Rate = RATE_12;
+			num++;
+			break;
+		case 36:
+			Rate = RATE_18;
+			num++;
+			break;
+		case 48:
+			Rate = RATE_24;
+			num++;
+			break;
+		case 72:
+			Rate = RATE_36;
+			num++;
+			break;
+		case 96:
+			Rate = RATE_48;
+			num++;
+			break;
+		case 108:
+			Rate = RATE_54;
+			num++;
+			break;
+			/*default: Rate = RATE_1;   break; */
 		}
-		if (MaxDesire < Rate)  MaxDesire = Rate;
+		if (MaxDesire < Rate)
+			MaxDesire = Rate;
 	}
 
-//===========================================================================
-//===========================================================================
+/*=========================================================================== */
+/*=========================================================================== */
 	{
-		pHtPhy 		= &pAd->StaCfg.HTPhyMode;
-		pMaxHtPhy	= &pAd->StaCfg.MaxHTPhyMode;
-		pMinHtPhy	= &pAd->StaCfg.MinHTPhyMode;
+		pHtPhy = &pAd->StaCfg.HTPhyMode;
+		pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
+		pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
 
 		auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
-		HtMcs 		= pAd->StaCfg.DesiredTransmitSetting.field.MCS;
+		HtMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
 
 		if ((pAd->StaCfg.BssType == BSS_ADHOC) &&
-			(pAd->CommonCfg.PhyMode == PHY_11B) &&
-			(MaxDesire > RATE_11))
-		{
+		    (pAd->CommonCfg.PhyMode == PHY_11B) &&
+		    (MaxDesire > RATE_11)) {
 			MaxDesire = RATE_11;
 		}
 	}
@@ -2964,111 +2928,211 @@
 	pMaxHtPhy->word = 0;
 	pHtPhy->word = 0;
 
-	// Auto rate switching is enabled only if more than one DESIRED RATES are
-	// specified; otherwise disabled
-	if (num <= 1)
-	{
+	/* Auto rate switching is enabled only if more than one DESIRED RATES are */
+	/* specified; otherwise disabled */
+	if (num <= 1) {
+		/*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */
+		/*pAd->CommonCfg.bAutoTxRateSwitch      = FALSE; */
 		*auto_rate_cur_p = FALSE;
-	}
-	else
-	{
+	} else {
+		/*OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */
+		/*pAd->CommonCfg.bAutoTxRateSwitch      = TRUE; */
 		*auto_rate_cur_p = TRUE;
 	}
 
-#if 1
-	if (HtMcs != MCS_AUTO)
-	{
+	if (HtMcs != MCS_AUTO) {
+		/*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */
+		/*pAd->CommonCfg.bAutoTxRateSwitch      = FALSE; */
 		*auto_rate_cur_p = FALSE;
-	}
-	else
-	{
+	} else {
+		/*OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */
+		/*pAd->CommonCfg.bAutoTxRateSwitch      = TRUE; */
 		*auto_rate_cur_p = TRUE;
 	}
-#endif
 
-	if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
-	{
+	if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) {
 		pSupRate = &pAd->StaActive.SupRate[0];
 		pExtRate = &pAd->StaActive.ExtRate[0];
 		SupRateLen = pAd->StaActive.SupRateLen;
 		ExtRateLen = pAd->StaActive.ExtRateLen;
-	}
-	else
-	{
+	} else {
 		pSupRate = &pAd->CommonCfg.SupRate[0];
 		pExtRate = &pAd->CommonCfg.ExtRate[0];
 		SupRateLen = pAd->CommonCfg.SupRateLen;
 		ExtRateLen = pAd->CommonCfg.ExtRateLen;
 	}
 
-	// find max supported rate
-	for (i=0; i<SupRateLen; i++)
-	{
-		switch (pSupRate[i] & 0x7f)
-		{
-			case 2:   Rate = RATE_1;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0001;	 break;
-			case 4:   Rate = RATE_2;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0002;	 break;
-			case 11:  Rate = RATE_5_5;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0004;	 break;
-			case 22:  Rate = RATE_11;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0008;	 break;
-			case 12:  Rate = RATE_6;	/*if (pSupRate[i] & 0x80)*/  BasicRateBitmap |= 0x0010;  break;
-			case 18:  Rate = RATE_9;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0020;	 break;
-			case 24:  Rate = RATE_12;	/*if (pSupRate[i] & 0x80)*/  BasicRateBitmap |= 0x0040;  break;
-			case 36:  Rate = RATE_18;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0080;	 break;
-			case 48:  Rate = RATE_24;	/*if (pSupRate[i] & 0x80)*/  BasicRateBitmap |= 0x0100;  break;
-			case 72:  Rate = RATE_36;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0200;	 break;
-			case 96:  Rate = RATE_48;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0400;	 break;
-			case 108: Rate = RATE_54;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0800;	 break;
-			default:  Rate = RATE_1;	break;
+	/* find max supported rate */
+	for (i = 0; i < SupRateLen; i++) {
+		switch (pSupRate[i] & 0x7f) {
+		case 2:
+			Rate = RATE_1;
+			if (pSupRate[i] & 0x80)
+				BasicRateBitmap |= 0x0001;
+			break;
+		case 4:
+			Rate = RATE_2;
+			if (pSupRate[i] & 0x80)
+				BasicRateBitmap |= 0x0002;
+			break;
+		case 11:
+			Rate = RATE_5_5;
+			if (pSupRate[i] & 0x80)
+				BasicRateBitmap |= 0x0004;
+			break;
+		case 22:
+			Rate = RATE_11;
+			if (pSupRate[i] & 0x80)
+				BasicRateBitmap |= 0x0008;
+			break;
+		case 12:
+			Rate = RATE_6;	/*if (pSupRate[i] & 0x80) */
+			BasicRateBitmap |= 0x0010;
+			break;
+		case 18:
+			Rate = RATE_9;
+			if (pSupRate[i] & 0x80)
+				BasicRateBitmap |= 0x0020;
+			break;
+		case 24:
+			Rate = RATE_12;	/*if (pSupRate[i] & 0x80) */
+			BasicRateBitmap |= 0x0040;
+			break;
+		case 36:
+			Rate = RATE_18;
+			if (pSupRate[i] & 0x80)
+				BasicRateBitmap |= 0x0080;
+			break;
+		case 48:
+			Rate = RATE_24;	/*if (pSupRate[i] & 0x80) */
+			BasicRateBitmap |= 0x0100;
+			break;
+		case 72:
+			Rate = RATE_36;
+			if (pSupRate[i] & 0x80)
+				BasicRateBitmap |= 0x0200;
+			break;
+		case 96:
+			Rate = RATE_48;
+			if (pSupRate[i] & 0x80)
+				BasicRateBitmap |= 0x0400;
+			break;
+		case 108:
+			Rate = RATE_54;
+			if (pSupRate[i] & 0x80)
+				BasicRateBitmap |= 0x0800;
+			break;
+		default:
+			Rate = RATE_1;
+			break;
 		}
-		if (MaxSupport < Rate)	MaxSupport = Rate;
+		if (MaxSupport < Rate)
+			MaxSupport = Rate;
 
-		if (MinSupport > Rate) MinSupport = Rate;
+		if (MinSupport > Rate)
+			MinSupport = Rate;
 	}
 
-	for (i=0; i<ExtRateLen; i++)
-	{
-		switch (pExtRate[i] & 0x7f)
-		{
-			case 2:   Rate = RATE_1;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0001;	 break;
-			case 4:   Rate = RATE_2;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0002;	 break;
-			case 11:  Rate = RATE_5_5;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0004;	 break;
-			case 22:  Rate = RATE_11;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0008;	 break;
-			case 12:  Rate = RATE_6;	/*if (pExtRate[i] & 0x80)*/  BasicRateBitmap |= 0x0010;  break;
-			case 18:  Rate = RATE_9;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0020;	 break;
-			case 24:  Rate = RATE_12;	/*if (pExtRate[i] & 0x80)*/  BasicRateBitmap |= 0x0040;  break;
-			case 36:  Rate = RATE_18;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0080;	 break;
-			case 48:  Rate = RATE_24;	/*if (pExtRate[i] & 0x80)*/  BasicRateBitmap |= 0x0100;  break;
-			case 72:  Rate = RATE_36;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0200;	 break;
-			case 96:  Rate = RATE_48;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0400;	 break;
-			case 108: Rate = RATE_54;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0800;	 break;
-			default:  Rate = RATE_1;	break;
+	for (i = 0; i < ExtRateLen; i++) {
+		switch (pExtRate[i] & 0x7f) {
+		case 2:
+			Rate = RATE_1;
+			if (pExtRate[i] & 0x80)
+				BasicRateBitmap |= 0x0001;
+			break;
+		case 4:
+			Rate = RATE_2;
+			if (pExtRate[i] & 0x80)
+				BasicRateBitmap |= 0x0002;
+			break;
+		case 11:
+			Rate = RATE_5_5;
+			if (pExtRate[i] & 0x80)
+				BasicRateBitmap |= 0x0004;
+			break;
+		case 22:
+			Rate = RATE_11;
+			if (pExtRate[i] & 0x80)
+				BasicRateBitmap |= 0x0008;
+			break;
+		case 12:
+			Rate = RATE_6;	/*if (pExtRate[i] & 0x80) */
+			BasicRateBitmap |= 0x0010;
+			break;
+		case 18:
+			Rate = RATE_9;
+			if (pExtRate[i] & 0x80)
+				BasicRateBitmap |= 0x0020;
+			break;
+		case 24:
+			Rate = RATE_12;	/*if (pExtRate[i] & 0x80) */
+			BasicRateBitmap |= 0x0040;
+			break;
+		case 36:
+			Rate = RATE_18;
+			if (pExtRate[i] & 0x80)
+				BasicRateBitmap |= 0x0080;
+			break;
+		case 48:
+			Rate = RATE_24;	/*if (pExtRate[i] & 0x80) */
+			BasicRateBitmap |= 0x0100;
+			break;
+		case 72:
+			Rate = RATE_36;
+			if (pExtRate[i] & 0x80)
+				BasicRateBitmap |= 0x0200;
+			break;
+		case 96:
+			Rate = RATE_48;
+			if (pExtRate[i] & 0x80)
+				BasicRateBitmap |= 0x0400;
+			break;
+		case 108:
+			Rate = RATE_54;
+			if (pExtRate[i] & 0x80)
+				BasicRateBitmap |= 0x0800;
+			break;
+		default:
+			Rate = RATE_1;
+			break;
 		}
-		if (MaxSupport < Rate)	MaxSupport = Rate;
+		if (MaxSupport < Rate)
+			MaxSupport = Rate;
 
-		if (MinSupport > Rate) MinSupport = Rate;
+		if (MinSupport > Rate)
+			MinSupport = Rate;
 	}
 
 	RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap);
 
-	// calculate the exptected ACK rate for each TX rate. This info is used to caculate
-	// the DURATION field of outgoing uniicast DATA/MGMT frame
-	for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
-	{
+	/* bug fix */
+	/* pAd->CommonCfg.BasicRateBitmap = BasicRateBitmap; */
+
+	/* calculate the exptected ACK rate for each TX rate. This info is used to caculate */
+	/* the DURATION field of outgoing uniicast DATA/MGMT frame */
+	for (i = 0; i < MAX_LEN_OF_SUPPORTED_RATES; i++) {
 		if (BasicRateBitmap & (0x01 << i))
-			CurrBasicRate = (UCHAR)i;
+			CurrBasicRate = (u8)i;
 		pAd->CommonCfg.ExpectedACKRate[i] = CurrBasicRate;
 	}
 
-	DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n", RateIdToMbps[MaxSupport], RateIdToMbps[MaxDesire]));
-	// max tx rate = min {max desire rate, max supported rate}
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n",
+		  RateIdToMbps[MaxSupport], RateIdToMbps[MaxDesire]));
+	/* max tx rate = min {max desire rate, max supported rate} */
 	if (MaxSupport < MaxDesire)
 		pAd->CommonCfg.MaxTxRate = MaxSupport;
 	else
 		pAd->CommonCfg.MaxTxRate = MaxDesire;
 
 	pAd->CommonCfg.MinTxRate = MinSupport;
-	if (*auto_rate_cur_p)
-	{
+	/* 2003-07-31 john - 2500 doesn't have good sensitivity at high OFDM rates. to increase the success */
+	/* ratio of initial DHCP packet exchange, TX rate starts from a lower rate depending */
+	/* on average RSSI */
+	/*       1. RSSI >= -70db, start at 54 Mbps (short distance) */
+	/*       2. -70 > RSSI >= -75, start at 24 Mbps (mid distance) */
+	/*       3. -75 > RSSI, start at 11 Mbps (long distance) */
+	if (*auto_rate_cur_p) {
 		short dbm = 0;
 
 		dbm = pAd->StaCfg.RssiSample.AvgRssi0 - pAd->BbpRssiToDbmDelta;
@@ -3083,113 +3147,137 @@
 		else if (dbm < -70)
 			pAd->CommonCfg.TxRate = RATE_24;
 
-		// should never exceed MaxTxRate (consider 11B-only mode)
+		/* should never exceed MaxTxRate (consider 11B-only mode) */
 		if (pAd->CommonCfg.TxRate > pAd->CommonCfg.MaxTxRate)
 			pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
 
 		pAd->CommonCfg.TxRateIndex = 0;
-	}
-	else
-	{
+	} else {
 		pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
-		pHtPhy->field.MCS	= (pAd->CommonCfg.MaxTxRate > 3) ? (pAd->CommonCfg.MaxTxRate - 4) : pAd->CommonCfg.MaxTxRate;
-		pHtPhy->field.MODE	= (pAd->CommonCfg.MaxTxRate > 3) ? MODE_OFDM : MODE_CCK;
+		pHtPhy->field.MCS =
+		    (pAd->CommonCfg.MaxTxRate >
+		     3) ? (pAd->CommonCfg.MaxTxRate -
+			   4) : pAd->CommonCfg.MaxTxRate;
+		pHtPhy->field.MODE =
+		    (pAd->CommonCfg.MaxTxRate > 3) ? MODE_OFDM : MODE_CCK;
 
-		pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC	= pHtPhy->field.STBC;
-		pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI	= pHtPhy->field.ShortGI;
-		pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS		= pHtPhy->field.MCS;
-		pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE	= pHtPhy->field.MODE;
+		pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC =
+		    pHtPhy->field.STBC;
+		pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI =
+		    pHtPhy->field.ShortGI;
+		pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS =
+		    pHtPhy->field.MCS;
+		pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE =
+		    pHtPhy->field.MODE;
 	}
 
-	if (pAd->CommonCfg.TxRate <= RATE_11)
-	{
+	if (pAd->CommonCfg.TxRate <= RATE_11) {
 		pMaxHtPhy->field.MODE = MODE_CCK;
 		pMaxHtPhy->field.MCS = pAd->CommonCfg.TxRate;
 		pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;
-	}
-	else
-	{
+	} else {
 		pMaxHtPhy->field.MODE = MODE_OFDM;
 		pMaxHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.TxRate];
-		if (pAd->CommonCfg.MinTxRate >= RATE_6 && (pAd->CommonCfg.MinTxRate <= RATE_54))
-			{pMinHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MinTxRate];}
-		else
-			{pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;}
+		if (pAd->CommonCfg.MinTxRate >= RATE_6
+		    && (pAd->CommonCfg.MinTxRate <= RATE_54)) {
+			pMinHtPhy->field.MCS =
+			    OfdmRateToRxwiMCS[pAd->CommonCfg.MinTxRate];
+		} else {
+			pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;
+		}
 	}
 
 	pHtPhy->word = (pMaxHtPhy->word);
-	if (bLinkUp && (pAd->OpMode == OPMODE_STA))
-	{
-			pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word = pHtPhy->word;
-			pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word = pMaxHtPhy->word;
-			pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word = pMinHtPhy->word;
-	}
-	else
-	{
-		switch (pAd->CommonCfg.PhyMode)
-		{
-			case PHY_11BG_MIXED:
-			case PHY_11B:
-			case PHY_11BGN_MIXED:
+	if (bLinkUp && (pAd->OpMode == OPMODE_STA)) {
+		pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word = pHtPhy->word;
+		pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word =
+		    pMaxHtPhy->word;
+		pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word =
+		    pMinHtPhy->word;
+	} else {
+		switch (pAd->CommonCfg.PhyMode) {
+		case PHY_11BG_MIXED:
+		case PHY_11B:
+		case PHY_11BGN_MIXED:
+			pAd->CommonCfg.MlmeRate = RATE_1;
+			pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
+			pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
+
+/*#ifdef        WIFI_TEST */
+			pAd->CommonCfg.RtsRate = RATE_11;
+/*#else */
+/*                              pAd->CommonCfg.RtsRate = RATE_1; */
+/*#endif */
+			break;
+		case PHY_11G:
+		case PHY_11A:
+		case PHY_11AGN_MIXED:
+		case PHY_11GN_MIXED:
+		case PHY_11N_2_4G:
+		case PHY_11AN_MIXED:
+		case PHY_11N_5G:
+			pAd->CommonCfg.MlmeRate = RATE_6;
+			pAd->CommonCfg.RtsRate = RATE_6;
+			pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+			pAd->CommonCfg.MlmeTransmit.field.MCS =
+			    OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+			break;
+		case PHY_11ABG_MIXED:
+		case PHY_11ABGN_MIXED:
+			if (pAd->CommonCfg.Channel <= 14) {
 				pAd->CommonCfg.MlmeRate = RATE_1;
-				pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
+				pAd->CommonCfg.RtsRate = RATE_1;
+				pAd->CommonCfg.MlmeTransmit.field.MODE =
+				    MODE_CCK;
 				pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
-				pAd->CommonCfg.RtsRate = RATE_11;
-				break;
-			case PHY_11G:
-			case PHY_11A:
-			case PHY_11AGN_MIXED:
-			case PHY_11GN_MIXED:
-			case PHY_11N_2_4G:
-			case PHY_11AN_MIXED:
-			case PHY_11N_5G:
+			} else {
 				pAd->CommonCfg.MlmeRate = RATE_6;
 				pAd->CommonCfg.RtsRate = RATE_6;
-				pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
-				pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-				break;
-			case PHY_11ABG_MIXED:
-			case PHY_11ABGN_MIXED:
-				if (pAd->CommonCfg.Channel <= 14)
-				{
-					pAd->CommonCfg.MlmeRate = RATE_1;
-					pAd->CommonCfg.RtsRate = RATE_1;
-					pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
-					pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
-				}
-				else
-				{
-					pAd->CommonCfg.MlmeRate = RATE_6;
-					pAd->CommonCfg.RtsRate = RATE_6;
-					pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
-					pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-				}
-				break;
-			default: // error
-				pAd->CommonCfg.MlmeRate = RATE_6;
-                        	pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
-				pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-				pAd->CommonCfg.RtsRate = RATE_1;
-				break;
+				pAd->CommonCfg.MlmeTransmit.field.MODE =
+				    MODE_OFDM;
+				pAd->CommonCfg.MlmeTransmit.field.MCS =
+				    OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+			}
+			break;
+		default:	/* error */
+			pAd->CommonCfg.MlmeRate = RATE_6;
+			pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+			pAd->CommonCfg.MlmeTransmit.field.MCS =
+			    OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+			pAd->CommonCfg.RtsRate = RATE_1;
+			break;
 		}
-		//
-		// Keep Basic Mlme Rate.
-		//
-		pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word = pAd->CommonCfg.MlmeTransmit.word;
+		/* */
+		/* Keep Basic Mlme Rate. */
+		/* */
+		pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word =
+		    pAd->CommonCfg.MlmeTransmit.word;
 		if (pAd->CommonCfg.MlmeTransmit.field.MODE == MODE_OFDM)
-			pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[RATE_24];
+			pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS =
+			    OfdmRateToRxwiMCS[RATE_24];
 		else
-			pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = RATE_1;
+			pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS =
+			    RATE_1;
 		pAd->CommonCfg.BasicMlmeRate = pAd->CommonCfg.MlmeRate;
 	}
 
-	DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n",
-			 RateIdToMbps[MaxDesire], RateIdToMbps[MaxSupport], RateIdToMbps[pAd->CommonCfg.MaxTxRate], RateIdToMbps[pAd->CommonCfg.MinTxRate],
-			 /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)*/*auto_rate_cur_p));
-	DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n",
-			 RateIdToMbps[pAd->CommonCfg.TxRate], RateIdToMbps[pAd->CommonCfg.RtsRate], BasicRateBitmap));
-	DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n",
-			 pAd->CommonCfg.MlmeTransmit.word, pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word ,pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word ,pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word ));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n",
+		  RateIdToMbps[MaxDesire], RateIdToMbps[MaxSupport],
+		  RateIdToMbps[pAd->CommonCfg.MaxTxRate],
+		  RateIdToMbps[pAd->CommonCfg.MinTxRate],
+		  /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) */
+		  *auto_rate_cur_p));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n",
+		  RateIdToMbps[pAd->CommonCfg.TxRate],
+		  RateIdToMbps[pAd->CommonCfg.RtsRate], BasicRateBitmap));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n",
+		  pAd->CommonCfg.MlmeTransmit.word,
+		  pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word,
+		  pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word,
+		  pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word));
 }
 
 /*
@@ -3198,168 +3286,196 @@
 		This function update HT Rate setting.
 		Input Wcid value is valid for 2 case :
 		1. it's used for Station in infra mode that copy AP rate to Mactable.
-		2. OR Station 	in adhoc mode to copy peer's HT rate to Mactable.
+		2. OR Station	in adhoc mode to copy peer's HT rate to Mactable.
 
-	IRQL = DISPATCH_LEVEL
+ IRQL = DISPATCH_LEVEL
 
 	==========================================================================
  */
-VOID MlmeUpdateHtTxRates(
-	IN PRTMP_ADAPTER 		pAd,
-	IN	UCHAR				apidx)
+void MlmeUpdateHtTxRates(struct rt_rtmp_adapter *pAd, u8 apidx)
 {
-	UCHAR	StbcMcs; //j, StbcMcs, bitmask;
-	CHAR 	i; // 3*3
-	RT_HT_CAPABILITY 	*pRtHtCap = NULL;
-	RT_HT_PHY_INFO		*pActiveHtPhy = NULL;
-	ULONG		BasicMCS;
-	UCHAR j, bitmask;
-	PRT_HT_PHY_INFO			pDesireHtPhy = NULL;
-	PHTTRANSMIT_SETTING		pHtPhy = NULL;
-	PHTTRANSMIT_SETTING		pMaxHtPhy = NULL;
-	PHTTRANSMIT_SETTING		pMinHtPhy = NULL;
-	BOOLEAN 				*auto_rate_cur_p;
+	u8 StbcMcs;		/*j, StbcMcs, bitmask; */
+	char i;			/* 3*3 */
+	struct rt_ht_capability *pRtHtCap = NULL;
+	struct rt_ht_phy_info *pActiveHtPhy = NULL;
+	unsigned long BasicMCS;
+	u8 j, bitmask;
+	struct rt_ht_phy_info *pDesireHtPhy = NULL;
+	PHTTRANSMIT_SETTING pHtPhy = NULL;
+	PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
+	PHTTRANSMIT_SETTING pMinHtPhy = NULL;
+	BOOLEAN *auto_rate_cur_p;
 
-	DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates===> \n"));
+	DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateHtTxRates===> \n"));
 
 	auto_rate_cur_p = NULL;
 
 	{
-		pDesireHtPhy	= &pAd->StaCfg.DesiredHtPhyInfo;
-		pActiveHtPhy	= &pAd->StaCfg.DesiredHtPhyInfo;
-		pHtPhy 		= &pAd->StaCfg.HTPhyMode;
-		pMaxHtPhy	= &pAd->StaCfg.MaxHTPhyMode;
-		pMinHtPhy	= &pAd->StaCfg.MinHTPhyMode;
+		pDesireHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
+		pActiveHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
+		pHtPhy = &pAd->StaCfg.HTPhyMode;
+		pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
+		pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
 
 		auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
 	}
 
-	if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
-	{
+	if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) {
 		if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
 			return;
 
 		pRtHtCap = &pAd->StaActive.SupportedHtPhy;
 		pActiveHtPhy = &pAd->StaActive.SupportedPhyInfo;
-		StbcMcs = (UCHAR)pAd->MlmeAux.AddHtInfo.AddHtInfo3.StbcMcs;
-		BasicMCS =pAd->MlmeAux.AddHtInfo.MCSSet[0]+(pAd->MlmeAux.AddHtInfo.MCSSet[1]<<8)+(StbcMcs<<16);
-		if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
+		StbcMcs = (u8)pAd->MlmeAux.AddHtInfo.AddHtInfo3.StbcMcs;
+		BasicMCS =
+		    pAd->MlmeAux.AddHtInfo.MCSSet[0] +
+		    (pAd->MlmeAux.AddHtInfo.MCSSet[1] << 8) + (StbcMcs << 16);
+		if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC)
+		    && (pAd->Antenna.field.TxPath == 2))
 			pMaxHtPhy->field.STBC = STBC_USE;
 		else
 			pMaxHtPhy->field.STBC = STBC_NONE;
-	}
-	else
-	{
+	} else {
 		if (pDesireHtPhy->bHtEnable == FALSE)
 			return;
 
 		pRtHtCap = &pAd->CommonCfg.DesiredHtPhy;
-		StbcMcs = (UCHAR)pAd->CommonCfg.AddHTInfo.AddHtInfo3.StbcMcs;
-		BasicMCS = pAd->CommonCfg.AddHTInfo.MCSSet[0]+(pAd->CommonCfg.AddHTInfo.MCSSet[1]<<8)+(StbcMcs<<16);
-		if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
+		StbcMcs = (u8)pAd->CommonCfg.AddHTInfo.AddHtInfo3.StbcMcs;
+		BasicMCS =
+		    pAd->CommonCfg.AddHTInfo.MCSSet[0] +
+		    (pAd->CommonCfg.AddHTInfo.MCSSet[1] << 8) + (StbcMcs << 16);
+		if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC)
+		    && (pAd->Antenna.field.TxPath == 2))
 			pMaxHtPhy->field.STBC = STBC_USE;
 		else
 			pMaxHtPhy->field.STBC = STBC_NONE;
 	}
 
-	// Decide MAX ht rate.
+	/* Decide MAX ht rate. */
 	if ((pRtHtCap->GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
 		pMaxHtPhy->field.MODE = MODE_HTGREENFIELD;
 	else
 		pMaxHtPhy->field.MODE = MODE_HTMIX;
 
-    if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth) && (pRtHtCap->ChannelWidth))
+	if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth)
+	    && (pRtHtCap->ChannelWidth))
 		pMaxHtPhy->field.BW = BW_40;
 	else
 		pMaxHtPhy->field.BW = BW_20;
 
-    if (pMaxHtPhy->field.BW == BW_20)
-		pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 & pRtHtCap->ShortGIfor20);
+	if (pMaxHtPhy->field.BW == BW_20)
+		pMaxHtPhy->field.ShortGI =
+		    (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 & pRtHtCap->
+		     ShortGIfor20);
 	else
-		pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 & pRtHtCap->ShortGIfor40);
+		pMaxHtPhy->field.ShortGI =
+		    (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 & pRtHtCap->
+		     ShortGIfor40);
 
-	for (i=23; i>=0; i--) // 3*3
+	if (pDesireHtPhy->MCSSet[4] != 0) {
+		pMaxHtPhy->field.MCS = 32;
+	}
+
+	for (i = 23; i >= 0; i--)	/* 3*3 */
 	{
-		j = i/8;
-		bitmask = (1<<(i-(j*8)));
+		j = i / 8;
+		bitmask = (1 << (i - (j * 8)));
 
-		if ((pActiveHtPhy->MCSSet[j] & bitmask) && (pDesireHtPhy->MCSSet[j] & bitmask))
-		{
+		if ((pActiveHtPhy->MCSSet[j] & bitmask)
+		    && (pDesireHtPhy->MCSSet[j] & bitmask)) {
 			pMaxHtPhy->field.MCS = i;
 			break;
 		}
 
-		if (i==0)
+		if (i == 0)
 			break;
 	}
 
-	// Copy MIN ht rate.  rt2860???
+	/* Copy MIN ht rate.  rt2860??? */
 	pMinHtPhy->field.BW = BW_20;
 	pMinHtPhy->field.MCS = 0;
 	pMinHtPhy->field.STBC = 0;
 	pMinHtPhy->field.ShortGI = 0;
-	//If STA assigns fixed rate. update to fixed here.
-	if ( (pAd->OpMode == OPMODE_STA) && (pDesireHtPhy->MCSSet[0] != 0xff))
-	{
-		if (pDesireHtPhy->MCSSet[4] != 0)
-		{
+	/*If STA assigns fixed rate. update to fixed here. */
+	if ((pAd->OpMode == OPMODE_STA) && (pDesireHtPhy->MCSSet[0] != 0xff)) {
+		if (pDesireHtPhy->MCSSet[4] != 0) {
 			pMaxHtPhy->field.MCS = 32;
 			pMinHtPhy->field.MCS = 32;
-			DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",pMinHtPhy->field.MCS));
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",
+				  pMinHtPhy->field.MCS));
 		}
 
-		for (i=23; (CHAR)i >= 0; i--) // 3*3
+		for (i = 23; (char)i >= 0; i--)	/* 3*3 */
 		{
-			j = i/8;
-			bitmask = (1<<(i-(j*8)));
-			if ( (pDesireHtPhy->MCSSet[j] & bitmask) && (pActiveHtPhy->MCSSet[j] & bitmask))
-			{
+			j = i / 8;
+			bitmask = (1 << (i - (j * 8)));
+			if ((pDesireHtPhy->MCSSet[j] & bitmask)
+			    && (pActiveHtPhy->MCSSet[j] & bitmask)) {
 				pMaxHtPhy->field.MCS = i;
 				pMinHtPhy->field.MCS = i;
 				break;
 			}
-			if (i==0)
+			if (i == 0)
 				break;
 		}
 	}
 
-	// Decide ht rate
+	/* Decide ht rate */
 	pHtPhy->field.STBC = pMaxHtPhy->field.STBC;
 	pHtPhy->field.BW = pMaxHtPhy->field.BW;
 	pHtPhy->field.MODE = pMaxHtPhy->field.MODE;
 	pHtPhy->field.MCS = pMaxHtPhy->field.MCS;
 	pHtPhy->field.ShortGI = pMaxHtPhy->field.ShortGI;
 
-	// use default now. rt2860
+	/* use default now. rt2860 */
 	if (pDesireHtPhy->MCSSet[0] != 0xff)
 		*auto_rate_cur_p = FALSE;
 	else
 		*auto_rate_cur_p = TRUE;
 
-	DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateHtTxRates<---.AMsduSize = %d  \n", pAd->CommonCfg.DesiredHtPhy.AmsduSize ));
-	DBGPRINT(RT_DEBUG_TRACE,("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d,  \n", pActiveHtPhy->MCSSet[0],pHtPhy->field.MCS,
-		pHtPhy->field.BW, pHtPhy->field.ShortGI, pHtPhy->field.MODE));
-	DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== \n"));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 (" MlmeUpdateHtTxRates<---.AMsduSize = %d  \n",
+		  pAd->CommonCfg.DesiredHtPhy.AmsduSize));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d,  \n",
+		  pActiveHtPhy->MCSSet[0], pHtPhy->field.MCS, pHtPhy->field.BW,
+		  pHtPhy->field.ShortGI, pHtPhy->field.MODE));
+	DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateHtTxRates<=== \n"));
 }
 
-// IRQL = DISPATCH_LEVEL
-VOID MlmeRadioOff(
-	IN PRTMP_ADAPTER pAd)
+void BATableInit(struct rt_rtmp_adapter *pAd, struct rt_ba_table *Tab)
 {
-	RT28XX_MLME_RADIO_OFF(pAd);
+	int i;
+
+	Tab->numAsOriginator = 0;
+	Tab->numAsRecipient = 0;
+	Tab->numDoneOriginator = 0;
+	NdisAllocateSpinLock(&pAd->BATabLock);
+	for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++) {
+		Tab->BARecEntry[i].REC_BA_Status = Recipient_NONE;
+		NdisAllocateSpinLock(&(Tab->BARecEntry[i].RxReRingLock));
+	}
+	for (i = 0; i < MAX_LEN_OF_BA_ORI_TABLE; i++) {
+		Tab->BAOriEntry[i].ORI_BA_Status = Originator_NONE;
+	}
 }
 
-// IRQL = DISPATCH_LEVEL
-VOID MlmeRadioOn(
-	IN PRTMP_ADAPTER pAd)
+/* IRQL = DISPATCH_LEVEL */
+void MlmeRadioOff(struct rt_rtmp_adapter *pAd)
 {
-	RT28XX_MLME_RADIO_ON(pAd);
+	RTMP_MLME_RADIO_OFF(pAd);
 }
 
-// ===========================================================================================
-// bss_table.c
-// ===========================================================================================
+/* IRQL = DISPATCH_LEVEL */
+void MlmeRadioOn(struct rt_rtmp_adapter *pAd)
+{
+	RTMP_MLME_RADIO_ON(pAd);
+}
 
+/* =========================================================================================== */
+/* bss_table.c */
+/* =========================================================================================== */
 
 /*! \brief initialize BSS table
  *	\param p_tab pointer to the table
@@ -3371,37 +3487,15 @@
  IRQL = DISPATCH_LEVEL
 
  */
-VOID BssTableInit(
-	IN BSS_TABLE *Tab)
+void BssTableInit(struct rt_bss_table *Tab)
 {
 	int i;
 
 	Tab->BssNr = 0;
-    Tab->BssOverlapNr = 0;
-	for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++)
-	{
-		NdisZeroMemory(&Tab->BssEntry[i], sizeof(BSS_ENTRY));
-		Tab->BssEntry[i].Rssi = -127;	// initial the rssi as a minimum value
-	}
-}
-
-VOID BATableInit(
-	IN PRTMP_ADAPTER pAd,
-    IN BA_TABLE *Tab)
-{
-	int i;
-
-	Tab->numAsOriginator = 0;
-	Tab->numAsRecipient = 0;
-	NdisAllocateSpinLock(&pAd->BATabLock);
-	for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
-	{
-		Tab->BARecEntry[i].REC_BA_Status = Recipient_NONE;
-		NdisAllocateSpinLock(&(Tab->BARecEntry[i].RxReRingLock));
-	}
-	for (i = 0; i < MAX_LEN_OF_BA_ORI_TABLE; i++)
-	{
-		Tab->BAOriEntry[i].ORI_BA_Status = Originator_NONE;
+	Tab->BssOverlapNr = 0;
+	for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++) {
+		NdisZeroMemory(&Tab->BssEntry[i], sizeof(struct rt_bss_entry));
+		Tab->BssEntry[i].Rssi = -127;	/* initial the rssi as a minimum value */
 	}
 }
 
@@ -3416,97 +3510,102 @@
  IRQL = DISPATCH_LEVEL
 
  */
-ULONG BssTableSearch(
-	IN BSS_TABLE *Tab,
-	IN PUCHAR	 pBssid,
-	IN UCHAR	 Channel)
+unsigned long BssTableSearch(struct rt_bss_table *Tab, u8 *pBssid, u8 Channel)
 {
-	UCHAR i;
+	u8 i;
 
-	for (i = 0; i < Tab->BssNr; i++)
-	{
-		//
-		// Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
-		// We should distinguish this case.
-		//
+	for (i = 0; i < Tab->BssNr; i++) {
+		/* */
+		/* Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G. */
+		/* We should distinguish this case. */
+		/* */
 		if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
-			 ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
-			MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid))
-		{
+		     ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
+		    MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid)) {
 			return i;
 		}
 	}
-	return (ULONG)BSS_NOT_FOUND;
+	return (unsigned long)BSS_NOT_FOUND;
 }
 
-ULONG BssSsidTableSearch(
-	IN BSS_TABLE *Tab,
-	IN PUCHAR	 pBssid,
-	IN PUCHAR	 pSsid,
-	IN UCHAR	 SsidLen,
-	IN UCHAR	 Channel)
+unsigned long BssSsidTableSearch(struct rt_bss_table *Tab,
+			 u8 *pBssid,
+			 u8 *pSsid, u8 SsidLen, u8 Channel)
 {
-	UCHAR i;
+	u8 i;
 
-	for (i = 0; i < Tab->BssNr; i++)
-	{
-		//
-		// Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
-		// We should distinguish this case.
-		//
+	for (i = 0; i < Tab->BssNr; i++) {
+		/* */
+		/* Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G. */
+		/* We should distinguish this case. */
+		/* */
 		if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
-			 ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
-			MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid) &&
-			SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen))
-		{
+		     ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
+		    MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid) &&
+		    SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid,
+			       Tab->BssEntry[i].SsidLen)) {
 			return i;
 		}
 	}
-	return (ULONG)BSS_NOT_FOUND;
+	return (unsigned long)BSS_NOT_FOUND;
 }
 
-ULONG BssTableSearchWithSSID(
-	IN BSS_TABLE *Tab,
-	IN PUCHAR	 Bssid,
-	IN PUCHAR	 pSsid,
-	IN UCHAR	 SsidLen,
-	IN UCHAR	 Channel)
+unsigned long BssTableSearchWithSSID(struct rt_bss_table *Tab,
+			     u8 *Bssid,
+			     u8 *pSsid,
+			     u8 SsidLen, u8 Channel)
 {
-	UCHAR i;
+	u8 i;
 
-	for (i = 0; i < Tab->BssNr; i++)
-	{
+	for (i = 0; i < Tab->BssNr; i++) {
 		if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
-			((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
-			MAC_ADDR_EQUAL(&(Tab->BssEntry[i].Bssid), Bssid) &&
-			(SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen) ||
-			(NdisEqualMemory(pSsid, ZeroSsid, SsidLen)) ||
-			(NdisEqualMemory(Tab->BssEntry[i].Ssid, ZeroSsid, Tab->BssEntry[i].SsidLen))))
-		{
+		     ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
+		    MAC_ADDR_EQUAL(&(Tab->BssEntry[i].Bssid), Bssid) &&
+		    (SSID_EQUAL
+		     (pSsid, SsidLen, Tab->BssEntry[i].Ssid,
+		      Tab->BssEntry[i].SsidLen)
+		     || (NdisEqualMemory(pSsid, ZeroSsid, SsidLen))
+		     ||
+		     (NdisEqualMemory
+		      (Tab->BssEntry[i].Ssid, ZeroSsid,
+		       Tab->BssEntry[i].SsidLen)))) {
 			return i;
 		}
 	}
-	return (ULONG)BSS_NOT_FOUND;
+	return (unsigned long)BSS_NOT_FOUND;
 }
 
-// IRQL = DISPATCH_LEVEL
-VOID BssTableDeleteEntry(
-	IN OUT	BSS_TABLE *Tab,
-	IN		PUCHAR	  pBssid,
-	IN		UCHAR	  Channel)
+unsigned long BssSsidTableSearchBySSID(struct rt_bss_table *Tab,
+			       u8 *pSsid, u8 SsidLen)
 {
-	UCHAR i, j;
+	u8 i;
 
-	for (i = 0; i < Tab->BssNr; i++)
-	{
+	for (i = 0; i < Tab->BssNr; i++) {
+		if (SSID_EQUAL
+		    (pSsid, SsidLen, Tab->BssEntry[i].Ssid,
+		     Tab->BssEntry[i].SsidLen)) {
+			return i;
+		}
+	}
+	return (unsigned long)BSS_NOT_FOUND;
+}
+
+/* IRQL = DISPATCH_LEVEL */
+void BssTableDeleteEntry(struct rt_bss_table *Tab,
+			 u8 *pBssid, u8 Channel)
+{
+	u8 i, j;
+
+	for (i = 0; i < Tab->BssNr; i++) {
 		if ((Tab->BssEntry[i].Channel == Channel) &&
-			(MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid)))
-		{
-			for (j = i; j < Tab->BssNr - 1; j++)
-			{
-				NdisMoveMemory(&(Tab->BssEntry[j]), &(Tab->BssEntry[j + 1]), sizeof(BSS_ENTRY));
+		    (MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid))) {
+			for (j = i; j < Tab->BssNr - 1; j++) {
+				NdisMoveMemory(&(Tab->BssEntry[j]),
+					       &(Tab->BssEntry[j + 1]),
+					       sizeof(struct rt_bss_entry));
 			}
-			NdisZeroMemory(&(Tab->BssEntry[Tab->BssNr - 1]), sizeof(BSS_ENTRY));
+			NdisZeroMemory(&(Tab->BssEntry[Tab->BssNr - 1]),
+				       sizeof(struct rt_bss_entry));
 			Tab->BssNr -= 1;
 			return;
 		}
@@ -3522,25 +3621,24 @@
 	// IRQL = DISPATCH_LEVEL
 	========================================================================
 */
-VOID BATableDeleteORIEntry(
-	IN OUT	PRTMP_ADAPTER pAd,
-	IN		BA_ORI_ENTRY	*pBAORIEntry)
+void BATableDeleteORIEntry(struct rt_rtmp_adapter *pAd,
+			   struct rt_ba_ori_entry *pBAORIEntry)
 {
 
-	if (pBAORIEntry->ORI_BA_Status != Originator_NONE)
-	{
+	if (pBAORIEntry->ORI_BA_Status != Originator_NONE) {
 		NdisAcquireSpinLock(&pAd->BATabLock);
-		if (pBAORIEntry->ORI_BA_Status == Originator_Done)
-		{
+		if (pBAORIEntry->ORI_BA_Status == Originator_Done) {
 			pAd->BATable.numAsOriginator -= 1;
-			DBGPRINT(RT_DEBUG_TRACE, ("BATableDeleteORIEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
-			// Erase Bitmap flag.
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("BATableDeleteORIEntry numAsOriginator= %ld\n",
+				  pAd->BATable.numAsRecipient));
+			/* Erase Bitmap flag. */
 		}
-		pAd->MacTab.Content[pBAORIEntry->Wcid].TXBAbitmap &= (~(1<<(pBAORIEntry->TID) ));	// If STA mode,  erase flag here
-		pAd->MacTab.Content[pBAORIEntry->Wcid].BAOriWcidArray[pBAORIEntry->TID] = 0;	// If STA mode,  erase flag here
+		pAd->MacTab.Content[pBAORIEntry->Wcid].TXBAbitmap &= (~(1 << (pBAORIEntry->TID)));	/* If STA mode,  erase flag here */
+		pAd->MacTab.Content[pBAORIEntry->Wcid].BAOriWcidArray[pBAORIEntry->TID] = 0;	/* If STA mode,  erase flag here */
 		pBAORIEntry->ORI_BA_Status = Originator_NONE;
 		pBAORIEntry->Token = 1;
-		// Not clear Sequence here.
+		/* Not clear Sequence here. */
 		NdisReleaseSpinLock(&pAd->BATabLock);
 	}
 }
@@ -3554,190 +3652,164 @@
  IRQL = DISPATCH_LEVEL
 
  */
-VOID BssEntrySet(
-	IN PRTMP_ADAPTER	pAd,
-	OUT BSS_ENTRY *pBss,
-	IN PUCHAR pBssid,
-	IN CHAR Ssid[],
-	IN UCHAR SsidLen,
-	IN UCHAR BssType,
-	IN USHORT BeaconPeriod,
-	IN PCF_PARM pCfParm,
-	IN USHORT AtimWin,
-	IN USHORT CapabilityInfo,
-	IN UCHAR SupRate[],
-	IN UCHAR SupRateLen,
-	IN UCHAR ExtRate[],
-	IN UCHAR ExtRateLen,
-	IN HT_CAPABILITY_IE *pHtCapability,
-	IN ADD_HT_INFO_IE *pAddHtInfo,	// AP might use this additional ht info IE
-	IN UCHAR			HtCapabilityLen,
-	IN UCHAR			AddHtInfoLen,
-	IN UCHAR			NewExtChanOffset,
-	IN UCHAR Channel,
-	IN CHAR Rssi,
-	IN LARGE_INTEGER TimeStamp,
-	IN UCHAR CkipFlag,
-	IN PEDCA_PARM pEdcaParm,
-	IN PQOS_CAPABILITY_PARM pQosCapability,
-	IN PQBSS_LOAD_PARM pQbssLoad,
-	IN USHORT LengthVIE,
-	IN PNDIS_802_11_VARIABLE_IEs pVIE)
+void BssEntrySet(struct rt_rtmp_adapter *pAd, struct rt_bss_entry *pBss, u8 *pBssid, char Ssid[], u8 SsidLen, u8 BssType, u16 BeaconPeriod, struct rt_cf_parm * pCfParm, u16 AtimWin, u16 CapabilityInfo, u8 SupRate[], u8 SupRateLen, u8 ExtRate[], u8 ExtRateLen, struct rt_ht_capability_ie * pHtCapability, struct rt_add_ht_info_ie * pAddHtInfo,	/* AP might use this additional ht info IE */
+		 u8 HtCapabilityLen,
+		 u8 AddHtInfoLen,
+		 u8 NewExtChanOffset,
+		 u8 Channel,
+		 char Rssi,
+		 IN LARGE_INTEGER TimeStamp,
+		 u8 CkipFlag,
+		 struct rt_edca_parm *pEdcaParm,
+		 struct rt_qos_capability_parm *pQosCapability,
+		 struct rt_qbss_load_parm *pQbssLoad,
+		 u16 LengthVIE, struct rt_ndis_802_11_variable_ies *pVIE)
 {
 	COPY_MAC_ADDR(pBss->Bssid, pBssid);
-	// Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID
+	/* Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID */
 	pBss->Hidden = 1;
-	if (SsidLen > 0)
-	{
-		// For hidden SSID AP, it might send beacon with SSID len equal to 0
-		// Or send beacon /probe response with SSID len matching real SSID length,
-		// but SSID is all zero. such as "00-00-00-00" with length 4.
-		// We have to prevent this case overwrite correct table
-		if (NdisEqualMemory(Ssid, ZeroSsid, SsidLen) == 0)
-		{
-		    NdisZeroMemory(pBss->Ssid, MAX_LEN_OF_SSID);
+	if (SsidLen > 0) {
+		/* For hidden SSID AP, it might send beacon with SSID len equal to 0 */
+		/* Or send beacon /probe response with SSID len matching real SSID length, */
+		/* but SSID is all zero. such as "00-00-00-00" with length 4. */
+		/* We have to prevent this case overwrite correct table */
+		if (NdisEqualMemory(Ssid, ZeroSsid, SsidLen) == 0) {
+			NdisZeroMemory(pBss->Ssid, MAX_LEN_OF_SSID);
 			NdisMoveMemory(pBss->Ssid, Ssid, SsidLen);
 			pBss->SsidLen = SsidLen;
 			pBss->Hidden = 0;
 		}
-	}
-	else
+	} else
 		pBss->SsidLen = 0;
 	pBss->BssType = BssType;
 	pBss->BeaconPeriod = BeaconPeriod;
-	if (BssType == BSS_INFRA)
-	{
-		if (pCfParm->bValid)
-		{
+	if (BssType == BSS_INFRA) {
+		if (pCfParm->bValid) {
 			pBss->CfpCount = pCfParm->CfpCount;
 			pBss->CfpPeriod = pCfParm->CfpPeriod;
 			pBss->CfpMaxDuration = pCfParm->CfpMaxDuration;
 			pBss->CfpDurRemaining = pCfParm->CfpDurRemaining;
 		}
-	}
-	else
-	{
+	} else {
 		pBss->AtimWin = AtimWin;
 	}
 
 	pBss->CapabilityInfo = CapabilityInfo;
-	// The privacy bit indicate security is ON, it maight be WEP, TKIP or AES
-	// Combine with AuthMode, they will decide the connection methods.
+	/* The privacy bit indicate security is ON, it maight be WEP, TKIP or AES */
+	/* Combine with AuthMode, they will decide the connection methods. */
 	pBss->Privacy = CAP_IS_PRIVACY_ON(pBss->CapabilityInfo);
 	ASSERT(SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
 	if (SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES)
 		NdisMoveMemory(pBss->SupRate, SupRate, SupRateLen);
 	else
-		NdisMoveMemory(pBss->SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES);
+		NdisMoveMemory(pBss->SupRate, SupRate,
+			       MAX_LEN_OF_SUPPORTED_RATES);
 	pBss->SupRateLen = SupRateLen;
 	ASSERT(ExtRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
 	NdisMoveMemory(pBss->ExtRate, ExtRate, ExtRateLen);
-	NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
-	NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
 	pBss->NewExtChanOffset = NewExtChanOffset;
 	pBss->ExtRateLen = ExtRateLen;
 	pBss->Channel = Channel;
 	pBss->CentralChannel = Channel;
 	pBss->Rssi = Rssi;
-	// Update CkipFlag. if not exists, the value is 0x0
+	/* Update CkipFlag. if not exists, the value is 0x0 */
 	pBss->CkipFlag = CkipFlag;
 
-	// New for microsoft Fixed IEs
+	/* New for microsoft Fixed IEs */
 	NdisMoveMemory(pBss->FixIEs.Timestamp, &TimeStamp, 8);
 	pBss->FixIEs.BeaconInterval = BeaconPeriod;
 	pBss->FixIEs.Capabilities = CapabilityInfo;
 
-	// New for microsoft Variable IEs
-	if (LengthVIE != 0)
-	{
+	/* New for microsoft Variable IEs */
+	if (LengthVIE != 0) {
 		pBss->VarIELen = LengthVIE;
 		NdisMoveMemory(pBss->VarIEs, pVIE, pBss->VarIELen);
-	}
-	else
-	{
+	} else {
 		pBss->VarIELen = 0;
 	}
 
 	pBss->AddHtInfoLen = 0;
 	pBss->HtCapabilityLen = 0;
-
-	if (HtCapabilityLen> 0)
-	{
+	if (HtCapabilityLen > 0) {
 		pBss->HtCapabilityLen = HtCapabilityLen;
-		NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
-		if (AddHtInfoLen > 0)
-		{
+		NdisMoveMemory(&pBss->HtCapability, pHtCapability,
+			       HtCapabilityLen);
+		if (AddHtInfoLen > 0) {
 			pBss->AddHtInfoLen = AddHtInfoLen;
-			NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
+			NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo,
+				       AddHtInfoLen);
 
-	 			if ((pAddHtInfo->ControlChan > 2)&& (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
-	 			{
-	 				pBss->CentralChannel = pAddHtInfo->ControlChan - 2;
-	 			}
-	 			else if ((pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
-				{
-		 				pBss->CentralChannel = pAddHtInfo->ControlChan + 2;
-				}
+			if ((pAddHtInfo->ControlChan > 2)
+			    && (pAddHtInfo->AddHtInfo.ExtChanOffset ==
+				EXTCHA_BELOW)
+			    && (pHtCapability->HtCapInfo.ChannelWidth ==
+				BW_40)) {
+				pBss->CentralChannel =
+				    pAddHtInfo->ControlChan - 2;
+			} else
+			    if ((pAddHtInfo->AddHtInfo.ExtChanOffset ==
+				 EXTCHA_ABOVE)
+				&& (pHtCapability->HtCapInfo.ChannelWidth ==
+				    BW_40)) {
+				pBss->CentralChannel =
+				    pAddHtInfo->ControlChan + 2;
+			}
 		}
 	}
 
 	BssCipherParse(pBss);
 
-	// new for QOS
+	/* new for QOS */
 	if (pEdcaParm)
-		NdisMoveMemory(&pBss->EdcaParm, pEdcaParm, sizeof(EDCA_PARM));
+		NdisMoveMemory(&pBss->EdcaParm, pEdcaParm, sizeof(struct rt_edca_parm));
 	else
 		pBss->EdcaParm.bValid = FALSE;
 	if (pQosCapability)
-		NdisMoveMemory(&pBss->QosCapability, pQosCapability, sizeof(QOS_CAPABILITY_PARM));
+		NdisMoveMemory(&pBss->QosCapability, pQosCapability,
+			       sizeof(struct rt_qos_capability_parm));
 	else
 		pBss->QosCapability.bValid = FALSE;
 	if (pQbssLoad)
-		NdisMoveMemory(&pBss->QbssLoad, pQbssLoad, sizeof(QBSS_LOAD_PARM));
+		NdisMoveMemory(&pBss->QbssLoad, pQbssLoad,
+			       sizeof(struct rt_qbss_load_parm));
 	else
 		pBss->QbssLoad.bValid = FALSE;
 
 	{
-		PEID_STRUCT     pEid;
-		USHORT          Length = 0;
-
+		struct rt_eid * pEid;
+		u16 Length = 0;
 
 		NdisZeroMemory(&pBss->WpaIE.IE[0], MAX_CUSTOM_LEN);
 		NdisZeroMemory(&pBss->RsnIE.IE[0], MAX_CUSTOM_LEN);
-
-		pEid = (PEID_STRUCT) pVIE;
-
-		while ((Length + 2 + (USHORT)pEid->Len) <= LengthVIE)
-		{
-			switch(pEid->Eid)
-			{
-				case IE_WPA:
-					if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
-					{
-						if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
-						{
-							pBss->WpaIE.IELen = 0;
-							break;
-						}
-						pBss->WpaIE.IELen = pEid->Len + 2;
-						NdisMoveMemory(pBss->WpaIE.IE, pEid, pBss->WpaIE.IELen);
+		pEid = (struct rt_eid *) pVIE;
+		while ((Length + 2 + (u16)pEid->Len) <= LengthVIE) {
+			switch (pEid->Eid) {
+			case IE_WPA:
+				if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)) {
+					if ((pEid->Len + 2) > MAX_CUSTOM_LEN) {
+						pBss->WpaIE.IELen = 0;
+						break;
 					}
-					break;
-                case IE_RSN:
-                    if (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
-					{
-						if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
-						{
-							pBss->RsnIE.IELen = 0;
-							break;
-						}
-						pBss->RsnIE.IELen = pEid->Len + 2;
-						NdisMoveMemory(pBss->RsnIE.IE, pEid, pBss->RsnIE.IELen);
-			}
+					pBss->WpaIE.IELen = pEid->Len + 2;
+					NdisMoveMemory(pBss->WpaIE.IE, pEid,
+						       pBss->WpaIE.IELen);
+				}
 				break;
-            }
-			Length = Length + 2 + (USHORT)pEid->Len;  // Eid[1] + Len[1]+ content[Len]
-			pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
+			case IE_RSN:
+				if (NdisEqualMemory
+				    (pEid->Octet + 2, RSN_OUI, 3)) {
+					if ((pEid->Len + 2) > MAX_CUSTOM_LEN) {
+						pBss->RsnIE.IELen = 0;
+						break;
+					}
+					pBss->RsnIE.IELen = pEid->Len + 2;
+					NdisMoveMemory(pBss->RsnIE.IE, pEid,
+						       pBss->RsnIE.IELen);
+				}
+				break;
+			}
+			Length = Length + 2 + (u16)pEid->Len;	/* Eid[1] + Len[1]+ content[Len] */
+			pEid = (struct rt_eid *) ((u8 *) pEid + 2 + pEid->Len);
 		}
 	}
 }
@@ -3765,301 +3837,337 @@
  IRQL = DISPATCH_LEVEL
 
  */
-ULONG BssTableSetEntry(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT BSS_TABLE *Tab,
-	IN PUCHAR pBssid,
-	IN CHAR Ssid[],
-	IN UCHAR SsidLen,
-	IN UCHAR BssType,
-	IN USHORT BeaconPeriod,
-	IN CF_PARM *CfParm,
-	IN USHORT AtimWin,
-	IN USHORT CapabilityInfo,
-	IN UCHAR SupRate[],
-	IN UCHAR SupRateLen,
-	IN UCHAR ExtRate[],
-	IN UCHAR ExtRateLen,
-	IN HT_CAPABILITY_IE *pHtCapability,
-	IN ADD_HT_INFO_IE *pAddHtInfo,	// AP might use this additional ht info IE
-	IN UCHAR			HtCapabilityLen,
-	IN UCHAR			AddHtInfoLen,
-	IN UCHAR			NewExtChanOffset,
-	IN UCHAR ChannelNo,
-	IN CHAR Rssi,
-	IN LARGE_INTEGER TimeStamp,
-	IN UCHAR CkipFlag,
-	IN PEDCA_PARM pEdcaParm,
-	IN PQOS_CAPABILITY_PARM pQosCapability,
-	IN PQBSS_LOAD_PARM pQbssLoad,
-	IN USHORT LengthVIE,
-	IN PNDIS_802_11_VARIABLE_IEs pVIE)
+unsigned long BssTableSetEntry(struct rt_rtmp_adapter *pAd, struct rt_bss_table *Tab, u8 *pBssid, char Ssid[], u8 SsidLen, u8 BssType, u16 BeaconPeriod, struct rt_cf_parm * CfParm, u16 AtimWin, u16 CapabilityInfo, u8 SupRate[], u8 SupRateLen, u8 ExtRate[], u8 ExtRateLen, struct rt_ht_capability_ie * pHtCapability, struct rt_add_ht_info_ie * pAddHtInfo,	/* AP might use this additional ht info IE */
+		       u8 HtCapabilityLen,
+		       u8 AddHtInfoLen,
+		       u8 NewExtChanOffset,
+		       u8 ChannelNo,
+		       char Rssi,
+		       IN LARGE_INTEGER TimeStamp,
+		       u8 CkipFlag,
+		       struct rt_edca_parm *pEdcaParm,
+		       struct rt_qos_capability_parm *pQosCapability,
+		       struct rt_qbss_load_parm *pQbssLoad,
+		       u16 LengthVIE, struct rt_ndis_802_11_variable_ies *pVIE)
 {
-	ULONG	Idx;
+	unsigned long Idx;
 
-	Idx = BssTableSearchWithSSID(Tab, pBssid,  Ssid, SsidLen, ChannelNo);
-	if (Idx == BSS_NOT_FOUND)
-	{
-		if (Tab->BssNr >= MAX_LEN_OF_BSS_TABLE)
-	    {
-			//
-			// It may happen when BSS Table was full.
-			// The desired AP will not be added into BSS Table
-			// In this case, if we found the desired AP then overwrite BSS Table.
-			//
-			if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-			{
-				if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, pBssid) ||
-					SSID_EQUAL(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Ssid, SsidLen))
-				{
+	Idx =
+	    BssTableSearchWithSSID(Tab, pBssid, (u8 *) Ssid, SsidLen,
+				   ChannelNo);
+	if (Idx == BSS_NOT_FOUND) {
+		if (Tab->BssNr >= MAX_LEN_OF_BSS_TABLE) {
+			/* */
+			/* It may happen when BSS Table was full. */
+			/* The desired AP will not be added into BSS Table */
+			/* In this case, if we found the desired AP then overwrite BSS Table. */
+			/* */
+			if (!OPSTATUS_TEST_FLAG
+			    (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
+				if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, pBssid)
+				    || SSID_EQUAL(pAd->MlmeAux.Ssid,
+						  pAd->MlmeAux.SsidLen, Ssid,
+						  SsidLen)) {
 					Idx = Tab->BssOverlapNr;
-					BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
-						CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
-						NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
-                    Tab->BssOverlapNr = (Tab->BssOverlapNr++) % MAX_LEN_OF_BSS_TABLE;
+					BssEntrySet(pAd, &Tab->BssEntry[Idx],
+						    pBssid, Ssid, SsidLen,
+						    BssType, BeaconPeriod,
+						    CfParm, AtimWin,
+						    CapabilityInfo, SupRate,
+						    SupRateLen, ExtRate,
+						    ExtRateLen, pHtCapability,
+						    pAddHtInfo, HtCapabilityLen,
+						    AddHtInfoLen,
+						    NewExtChanOffset, ChannelNo,
+						    Rssi, TimeStamp, CkipFlag,
+						    pEdcaParm, pQosCapability,
+						    pQbssLoad, LengthVIE, pVIE);
+					Tab->BssOverlapNr =
+					    (Tab->BssOverlapNr++) %
+					    MAX_LEN_OF_BSS_TABLE;
 				}
 				return Idx;
-			}
-			else
-			{
-			return BSS_NOT_FOUND;
+			} else {
+				return BSS_NOT_FOUND;
 			}
 		}
 		Idx = Tab->BssNr;
-		BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
-					CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
-					NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
+		BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen,
+			    BssType, BeaconPeriod, CfParm, AtimWin,
+			    CapabilityInfo, SupRate, SupRateLen, ExtRate,
+			    ExtRateLen, pHtCapability, pAddHtInfo,
+			    HtCapabilityLen, AddHtInfoLen, NewExtChanOffset,
+			    ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm,
+			    pQosCapability, pQbssLoad, LengthVIE, pVIE);
 		Tab->BssNr++;
-	}
-	else
-	{
+	} else {
 		/* avoid  Hidden SSID form beacon to overwirite correct SSID from probe response */
-		if ((SSID_EQUAL(Ssid, SsidLen, Tab->BssEntry[Idx].Ssid, Tab->BssEntry[Idx].SsidLen)) ||
-			(NdisEqualMemory(Tab->BssEntry[Idx].Ssid, ZeroSsid, Tab->BssEntry[Idx].SsidLen)))
-		{
-		BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod,CfParm, AtimWin,
-					CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
-					NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
+		if ((SSID_EQUAL
+		     (Ssid, SsidLen, Tab->BssEntry[Idx].Ssid,
+		      Tab->BssEntry[Idx].SsidLen))
+		    ||
+		    (NdisEqualMemory
+		     (Tab->BssEntry[Idx].Ssid, ZeroSsid,
+		      Tab->BssEntry[Idx].SsidLen))) {
+			BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid,
+				    SsidLen, BssType, BeaconPeriod, CfParm,
+				    AtimWin, CapabilityInfo, SupRate,
+				    SupRateLen, ExtRate, ExtRateLen,
+				    pHtCapability, pAddHtInfo, HtCapabilityLen,
+				    AddHtInfoLen, NewExtChanOffset, ChannelNo,
+				    Rssi, TimeStamp, CkipFlag, pEdcaParm,
+				    pQosCapability, pQbssLoad, LengthVIE, pVIE);
 		}
 	}
 
 	return Idx;
 }
 
-// IRQL = DISPATCH_LEVEL
-VOID BssTableSsidSort(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT BSS_TABLE *OutTab,
-	IN	CHAR Ssid[],
-	IN	UCHAR SsidLen)
+/* IRQL = DISPATCH_LEVEL */
+void BssTableSsidSort(struct rt_rtmp_adapter *pAd,
+		      struct rt_bss_table *OutTab, char Ssid[], u8 SsidLen)
 {
-	INT i;
+	int i;
 	BssTableInit(OutTab);
 
-	for (i = 0; i < pAd->ScanTab.BssNr; i++)
-	{
-		BSS_ENTRY *pInBss = &pAd->ScanTab.BssEntry[i];
-		BOOLEAN	bIsHiddenApIncluded = FALSE;
+	for (i = 0; i < pAd->ScanTab.BssNr; i++) {
+		struct rt_bss_entry *pInBss = &pAd->ScanTab.BssEntry[i];
+		BOOLEAN bIsHiddenApIncluded = FALSE;
 
 		if (((pAd->CommonCfg.bIEEE80211H == 1) &&
-            (pAd->MlmeAux.Channel > 14) &&
-             RadarChannelCheck(pAd, pInBss->Channel))
-            )
-		{
+		     (pAd->MlmeAux.Channel > 14) &&
+		     RadarChannelCheck(pAd, pInBss->Channel))
+		    ) {
 			if (pInBss->Hidden)
 				bIsHiddenApIncluded = TRUE;
 		}
 
 		if ((pInBss->BssType == pAd->StaCfg.BssType) &&
-			(SSID_EQUAL(Ssid, SsidLen, pInBss->Ssid, pInBss->SsidLen) || bIsHiddenApIncluded))
-		{
-			BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
+		    (SSID_EQUAL(Ssid, SsidLen, pInBss->Ssid, pInBss->SsidLen)
+		     || bIsHiddenApIncluded)) {
+			struct rt_bss_entry *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
 
-			// 2.4G/5G N only mode
+			/* 2.4G/5G N only mode */
 			if ((pInBss->HtCapabilityLen == 0) &&
-				((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
-			{
-				DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
+			    ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G)
+			     || (pAd->CommonCfg.PhyMode == PHY_11N_5G))) {
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
 				continue;
 			}
-
-			// New for WPA2
-			// Check the Authmode first
-			if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-			{
-				// Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
-				if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
-					// None matched
+			/* New for WPA2 */
+			/* Check the Authmode first */
+			if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) {
+				/* Check AuthMode and AuthModeAux for matching, in case AP support dual-mode */
+				if ((pAd->StaCfg.AuthMode != pInBss->AuthMode)
+				    && (pAd->StaCfg.AuthMode !=
+					pInBss->AuthModeAux))
+					/* None matched */
 					continue;
 
-				// Check cipher suite, AP must have more secured cipher than station setting
-				if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
-				{
-					// If it's not mixed mode, we should only let BSS pass with the same encryption
+				/* Check cipher suite, AP must have more secured cipher than station setting */
+				if ((pAd->StaCfg.AuthMode ==
+				     Ndis802_11AuthModeWPA)
+				    || (pAd->StaCfg.AuthMode ==
+					Ndis802_11AuthModeWPAPSK)) {
+					/* If it's not mixed mode, we should only let BSS pass with the same encryption */
 					if (pInBss->WPA.bMixMode == FALSE)
-						if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
+						if (pAd->StaCfg.WepStatus !=
+						    pInBss->WPA.GroupCipher)
 							continue;
 
-					// check group cipher
-					if (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP40Enabled &&
-					    pInBss->WPA.GroupCipher != Ndis802_11GroupWEP104Enabled &&
-					    pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
+					/* check group cipher */
+					if ((pAd->StaCfg.WepStatus <
+					     pInBss->WPA.GroupCipher)
+					    && (pInBss->WPA.GroupCipher !=
+						Ndis802_11GroupWEP40Enabled)
+					    && (pInBss->WPA.GroupCipher !=
+						Ndis802_11GroupWEP104Enabled))
 						continue;
 
-					// check pairwise cipher, skip if none matched
-					// If profile set to AES, let it pass without question.
-					// If profile set to TKIP, we must find one mateched
-					if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
-						(pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
-						(pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
+					/* check pairwise cipher, skip if none matched */
+					/* If profile set to AES, let it pass without question. */
+					/* If profile set to TKIP, we must find one mateched */
+					if ((pAd->StaCfg.WepStatus ==
+					     Ndis802_11Encryption2Enabled)
+					    && (pAd->StaCfg.WepStatus !=
+						pInBss->WPA.PairCipher)
+					    && (pAd->StaCfg.WepStatus !=
+						pInBss->WPA.PairCipherAux))
 						continue;
-				}
-				else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
-				{
-					// If it's not mixed mode, we should only let BSS pass with the same encryption
+				} else
+				    if ((pAd->StaCfg.AuthMode ==
+					 Ndis802_11AuthModeWPA2)
+					|| (pAd->StaCfg.AuthMode ==
+					    Ndis802_11AuthModeWPA2PSK)) {
+					/* If it's not mixed mode, we should only let BSS pass with the same encryption */
 					if (pInBss->WPA2.bMixMode == FALSE)
-						if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
+						if (pAd->StaCfg.WepStatus !=
+						    pInBss->WPA2.GroupCipher)
 							continue;
 
-					// check group cipher
-					if (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP40Enabled &&
-					    pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP104Enabled &&
-					    pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
+					/* check group cipher */
+					if ((pAd->StaCfg.WepStatus <
+					     pInBss->WPA.GroupCipher)
+					    && (pInBss->WPA2.GroupCipher !=
+						Ndis802_11GroupWEP40Enabled)
+					    && (pInBss->WPA2.GroupCipher !=
+						Ndis802_11GroupWEP104Enabled))
 						continue;
 
-					// check pairwise cipher, skip if none matched
-					// If profile set to AES, let it pass without question.
-					// If profile set to TKIP, we must find one mateched
-					if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
-						(pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
-						(pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
+					/* check pairwise cipher, skip if none matched */
+					/* If profile set to AES, let it pass without question. */
+					/* If profile set to TKIP, we must find one mateched */
+					if ((pAd->StaCfg.WepStatus ==
+					     Ndis802_11Encryption2Enabled)
+					    && (pAd->StaCfg.WepStatus !=
+						pInBss->WPA2.PairCipher)
+					    && (pAd->StaCfg.WepStatus !=
+						pInBss->WPA2.PairCipherAux))
 						continue;
 				}
 			}
-			// Bss Type matched, SSID matched.
-			// We will check wepstatus for qualification Bss
-			else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
-			{
-				DBGPRINT(RT_DEBUG_TRACE,("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n", pAd->StaCfg.WepStatus, pInBss->WepStatus));
-				//
-				// For the SESv2 case, we will not qualify WepStatus.
-				//
+			/* Bss Type matched, SSID matched. */
+			/* We will check wepstatus for qualification Bss */
+			else if (pAd->StaCfg.WepStatus != pInBss->WepStatus) {
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n",
+					  pAd->StaCfg.WepStatus,
+					  pInBss->WepStatus));
+				/* */
+				/* For the SESv2 case, we will not qualify WepStatus. */
+				/* */
 				if (!pInBss->bSES)
 					continue;
 			}
-
-			// Since the AP is using hidden SSID, and we are trying to connect to ANY
-			// It definitely will fail. So, skip it.
-			// CCX also require not even try to connect it!!
+			/* Since the AP is using hidden SSID, and we are trying to connect to ANY */
+			/* It definitely will fail. So, skip it. */
+			/* CCX also require not even try to connect it! */
 			if (SsidLen == 0)
 				continue;
 
-			// If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
-			// If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
+			/* If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region */
+			/* If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead, */
 			if ((pInBss->CentralChannel != pInBss->Channel) &&
-				(pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
-			{
-				if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
-				{
-					pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
+			    (pAd->CommonCfg.RegTransmitSetting.field.BW ==
+			     BW_40)) {
+				if (RTMPCheckChannel
+				    (pAd, pInBss->CentralChannel,
+				     pInBss->Channel) == FALSE) {
+					pAd->CommonCfg.RegTransmitSetting.field.
+					    BW = BW_20;
 					SetCommonHT(pAd);
-					pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
-				}
-				else
-				{
-					if (pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BAND_WIDTH_20)
-					{
+					pAd->CommonCfg.RegTransmitSetting.field.
+					    BW = BW_40;
+				} else {
+					if (pAd->CommonCfg.DesiredHtPhy.
+					    ChannelWidth == BAND_WIDTH_20) {
 						SetCommonHT(pAd);
 					}
 				}
 			}
-
-			// copy matching BSS from InTab to OutTab
-			NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
+			/* copy matching BSS from InTab to OutTab */
+			NdisMoveMemory(pOutBss, pInBss, sizeof(struct rt_bss_entry));
 
 			OutTab->BssNr++;
-		}
-		else if ((pInBss->BssType == pAd->StaCfg.BssType) && (SsidLen == 0))
-		{
-			BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
+		} else if ((pInBss->BssType == pAd->StaCfg.BssType)
+			   && (SsidLen == 0)) {
+			struct rt_bss_entry *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
 
-			// 2.4G/5G N only mode
+			/* 2.4G/5G N only mode */
 			if ((pInBss->HtCapabilityLen == 0) &&
-				((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
-			{
-				DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
+			    ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G)
+			     || (pAd->CommonCfg.PhyMode == PHY_11N_5G))) {
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
 				continue;
 			}
-
-			// New for WPA2
-			// Check the Authmode first
-			if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-			{
-				// Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
-				if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
-					// None matched
+			/* New for WPA2 */
+			/* Check the Authmode first */
+			if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) {
+				/* Check AuthMode and AuthModeAux for matching, in case AP support dual-mode */
+				if ((pAd->StaCfg.AuthMode != pInBss->AuthMode)
+				    && (pAd->StaCfg.AuthMode !=
+					pInBss->AuthModeAux))
+					/* None matched */
 					continue;
 
-				// Check cipher suite, AP must have more secured cipher than station setting
-				if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
-				{
-					// If it's not mixed mode, we should only let BSS pass with the same encryption
+				/* Check cipher suite, AP must have more secured cipher than station setting */
+				if ((pAd->StaCfg.AuthMode ==
+				     Ndis802_11AuthModeWPA)
+				    || (pAd->StaCfg.AuthMode ==
+					Ndis802_11AuthModeWPAPSK)) {
+					/* If it's not mixed mode, we should only let BSS pass with the same encryption */
 					if (pInBss->WPA.bMixMode == FALSE)
-						if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
+						if (pAd->StaCfg.WepStatus !=
+						    pInBss->WPA.GroupCipher)
 							continue;
 
-					// check group cipher
-					if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
+					/* check group cipher */
+					if (pAd->StaCfg.WepStatus <
+					    pInBss->WPA.GroupCipher)
 						continue;
 
-					// check pairwise cipher, skip if none matched
-					// If profile set to AES, let it pass without question.
-					// If profile set to TKIP, we must find one mateched
-					if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
-						(pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
-						(pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
+					/* check pairwise cipher, skip if none matched */
+					/* If profile set to AES, let it pass without question. */
+					/* If profile set to TKIP, we must find one mateched */
+					if ((pAd->StaCfg.WepStatus ==
+					     Ndis802_11Encryption2Enabled)
+					    && (pAd->StaCfg.WepStatus !=
+						pInBss->WPA.PairCipher)
+					    && (pAd->StaCfg.WepStatus !=
+						pInBss->WPA.PairCipherAux))
 						continue;
-				}
-				else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
-				{
-					// If it's not mixed mode, we should only let BSS pass with the same encryption
+				} else
+				    if ((pAd->StaCfg.AuthMode ==
+					 Ndis802_11AuthModeWPA2)
+					|| (pAd->StaCfg.AuthMode ==
+					    Ndis802_11AuthModeWPA2PSK)) {
+					/* If it's not mixed mode, we should only let BSS pass with the same encryption */
 					if (pInBss->WPA2.bMixMode == FALSE)
-						if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
+						if (pAd->StaCfg.WepStatus !=
+						    pInBss->WPA2.GroupCipher)
 							continue;
 
-					// check group cipher
-					if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
+					/* check group cipher */
+					if (pAd->StaCfg.WepStatus <
+					    pInBss->WPA2.GroupCipher)
 						continue;
 
-					// check pairwise cipher, skip if none matched
-					// If profile set to AES, let it pass without question.
-					// If profile set to TKIP, we must find one mateched
-					if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
-						(pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
-						(pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
+					/* check pairwise cipher, skip if none matched */
+					/* If profile set to AES, let it pass without question. */
+					/* If profile set to TKIP, we must find one mateched */
+					if ((pAd->StaCfg.WepStatus ==
+					     Ndis802_11Encryption2Enabled)
+					    && (pAd->StaCfg.WepStatus !=
+						pInBss->WPA2.PairCipher)
+					    && (pAd->StaCfg.WepStatus !=
+						pInBss->WPA2.PairCipherAux))
 						continue;
 				}
 			}
-			// Bss Type matched, SSID matched.
-			// We will check wepstatus for qualification Bss
+			/* Bss Type matched, SSID matched. */
+			/* We will check wepstatus for qualification Bss */
 			else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
-					continue;
+				continue;
 
-			// If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
-			// If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
+			/* If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region */
+			/* If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead, */
 			if ((pInBss->CentralChannel != pInBss->Channel) &&
-				(pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
-			{
-				if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
-				{
-					pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
+			    (pAd->CommonCfg.RegTransmitSetting.field.BW ==
+			     BW_40)) {
+				if (RTMPCheckChannel
+				    (pAd, pInBss->CentralChannel,
+				     pInBss->Channel) == FALSE) {
+					pAd->CommonCfg.RegTransmitSetting.field.
+					    BW = BW_20;
 					SetCommonHT(pAd);
-					pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
+					pAd->CommonCfg.RegTransmitSetting.field.
+					    BW = BW_40;
 				}
 			}
-
-			// copy matching BSS from InTab to OutTab
-			NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
+			/* copy matching BSS from InTab to OutTab */
+			NdisMoveMemory(pOutBss, pInBss, sizeof(struct rt_bss_entry));
 
 			OutTab->BssNr++;
 		}
@@ -4071,378 +4179,366 @@
 	BssTableSortByRssi(OutTab);
 }
 
-
-// IRQL = DISPATCH_LEVEL
-VOID BssTableSortByRssi(
-	IN OUT BSS_TABLE *OutTab)
+/* IRQL = DISPATCH_LEVEL */
+void BssTableSortByRssi(struct rt_bss_table *OutTab)
 {
-	INT 	  i, j;
-	BSS_ENTRY TmpBss;
+	int i, j;
+	struct rt_bss_entry TmpBss;
 
-	for (i = 0; i < OutTab->BssNr - 1; i++)
-	{
-		for (j = i+1; j < OutTab->BssNr; j++)
-		{
-			if (OutTab->BssEntry[j].Rssi > OutTab->BssEntry[i].Rssi)
-			{
-				NdisMoveMemory(&TmpBss, &OutTab->BssEntry[j], sizeof(BSS_ENTRY));
-				NdisMoveMemory(&OutTab->BssEntry[j], &OutTab->BssEntry[i], sizeof(BSS_ENTRY));
-				NdisMoveMemory(&OutTab->BssEntry[i], &TmpBss, sizeof(BSS_ENTRY));
+	for (i = 0; i < OutTab->BssNr - 1; i++) {
+		for (j = i + 1; j < OutTab->BssNr; j++) {
+			if (OutTab->BssEntry[j].Rssi > OutTab->BssEntry[i].Rssi) {
+				NdisMoveMemory(&TmpBss, &OutTab->BssEntry[j],
+					       sizeof(struct rt_bss_entry));
+				NdisMoveMemory(&OutTab->BssEntry[j],
+					       &OutTab->BssEntry[i],
+					       sizeof(struct rt_bss_entry));
+				NdisMoveMemory(&OutTab->BssEntry[i], &TmpBss,
+					       sizeof(struct rt_bss_entry));
 			}
 		}
 	}
 }
 
-VOID BssCipherParse(
-	IN OUT	PBSS_ENTRY	pBss)
+void BssCipherParse(struct rt_bss_entry *pBss)
 {
-	PEID_STRUCT 		 pEid;
-	PUCHAR				pTmp;
-	PRSN_IE_HEADER_STRUCT			pRsnHeader;
-	PCIPHER_SUITE_STRUCT			pCipher;
-	PAKM_SUITE_STRUCT				pAKM;
-	USHORT							Count;
-	INT								Length;
-	NDIS_802_11_ENCRYPTION_STATUS	TmpCipher;
+	struct rt_eid * pEid;
+	u8 *pTmp;
+	struct rt_rsn_ie_header * pRsnHeader;
+	struct rt_cipher_suite_struct * pCipher;
+	struct rt_akm_suite * pAKM;
+	u16 Count;
+	int Length;
+	NDIS_802_11_ENCRYPTION_STATUS TmpCipher;
 
-	//
-	// WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame.
-	//
-	if (pBss->Privacy)
-	{
-		pBss->WepStatus 	= Ndis802_11WEPEnabled;
+	/* */
+	/* WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame. */
+	/* */
+	if (pBss->Privacy) {
+		pBss->WepStatus = Ndis802_11WEPEnabled;
+	} else {
+		pBss->WepStatus = Ndis802_11WEPDisabled;
 	}
-	else
-	{
-		pBss->WepStatus 	= Ndis802_11WEPDisabled;
-	}
-	// Set default to disable & open authentication before parsing variable IE
-	pBss->AuthMode		= Ndis802_11AuthModeOpen;
-	pBss->AuthModeAux	= Ndis802_11AuthModeOpen;
+	/* Set default to disable & open authentication before parsing variable IE */
+	pBss->AuthMode = Ndis802_11AuthModeOpen;
+	pBss->AuthModeAux = Ndis802_11AuthModeOpen;
 
-	// Init WPA setting
-	pBss->WPA.PairCipher	= Ndis802_11WEPDisabled;
+	/* Init WPA setting */
+	pBss->WPA.PairCipher = Ndis802_11WEPDisabled;
 	pBss->WPA.PairCipherAux = Ndis802_11WEPDisabled;
-	pBss->WPA.GroupCipher	= Ndis802_11WEPDisabled;
+	pBss->WPA.GroupCipher = Ndis802_11WEPDisabled;
 	pBss->WPA.RsnCapability = 0;
-	pBss->WPA.bMixMode		= FALSE;
+	pBss->WPA.bMixMode = FALSE;
 
-	// Init WPA2 setting
-	pBss->WPA2.PairCipher	 = Ndis802_11WEPDisabled;
+	/* Init WPA2 setting */
+	pBss->WPA2.PairCipher = Ndis802_11WEPDisabled;
 	pBss->WPA2.PairCipherAux = Ndis802_11WEPDisabled;
-	pBss->WPA2.GroupCipher	 = Ndis802_11WEPDisabled;
+	pBss->WPA2.GroupCipher = Ndis802_11WEPDisabled;
 	pBss->WPA2.RsnCapability = 0;
-	pBss->WPA2.bMixMode 	 = FALSE;
+	pBss->WPA2.bMixMode = FALSE;
 
+	Length = (int)pBss->VarIELen;
 
-	Length = (INT) pBss->VarIELen;
-
-	while (Length > 0)
-	{
-		// Parse cipher suite base on WPA1 & WPA2, they should be parsed differently
-		pTmp = ((PUCHAR) pBss->VarIEs) + pBss->VarIELen - Length;
-		pEid = (PEID_STRUCT) pTmp;
-		switch (pEid->Eid)
-		{
-			case IE_WPA:
-				//Parse Cisco IE_WPA (LEAP, CCKM, etc.)
-				if ( NdisEqualMemory((pTmp+8), CISCO_OUI, 3))
-				{
-					pTmp   += 11;
-					switch (*pTmp)
-					{
-						case 1:
-						case 5:	// Although WEP is not allowed in WPA related auth mode, we parse it anyway
-							pBss->WepStatus = Ndis802_11Encryption1Enabled;
-							pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
-							pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
-							break;
-						case 2:
-							pBss->WepStatus = Ndis802_11Encryption2Enabled;
-							pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
-							pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
-							break;
-						case 4:
-							pBss->WepStatus = Ndis802_11Encryption3Enabled;
-							pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
-							pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
-							break;
-						default:
-							break;
-					}
-
-					// if Cisco IE_WPA, break
-					break;
-				}
-				else if (NdisEqualMemory(pEid->Octet, SES_OUI, 3) && (pEid->Len == 7))
-				{
-					pBss->bSES = TRUE;
-					break;
-				}
-				else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) != 1)
-				{
-					// if unsupported vendor specific IE
-					break;
-				}
-				// Skip OUI, version, and multicast suite
-				// This part should be improved in the future when AP supported multiple cipher suite.
-				// For now, it's OK since almost all APs have fixed cipher suite supported.
-				// pTmp = (PUCHAR) pEid->Octet;
-				pTmp   += 11;
-
-				// Cipher Suite Selectors from Spec P802.11i/D3.2 P26.
-				//	Value	   Meaning
-				//	0			None
-				//	1			WEP-40
-				//	2			Tkip
-				//	3			WRAP
-				//	4			AES
-				//	5			WEP-104
-				// Parse group cipher
-				switch (*pTmp)
-				{
-					case 1:
-						pBss->WPA.GroupCipher = Ndis802_11GroupWEP40Enabled;
-						break;
-					case 5:
-						pBss->WPA.GroupCipher = Ndis802_11GroupWEP104Enabled;
-						break;
-					case 2:
-						pBss->WPA.GroupCipher = Ndis802_11Encryption2Enabled;
-						break;
-					case 4:
-						pBss->WPA.GroupCipher = Ndis802_11Encryption3Enabled;
-						break;
-					default:
-						break;
-				}
-				// number of unicast suite
-				pTmp   += 1;
-
-				// skip all unicast cipher suites
-				//Count = *(PUSHORT) pTmp;
-				Count = (pTmp[1]<<8) + pTmp[0];
-				pTmp   += sizeof(USHORT);
-
-				// Parsing all unicast cipher suite
-				while (Count > 0)
-				{
-					// Skip OUI
-					pTmp += 3;
-					TmpCipher = Ndis802_11WEPDisabled;
-					switch (*pTmp)
-					{
-						case 1:
-						case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
-							TmpCipher = Ndis802_11Encryption1Enabled;
-							break;
-						case 2:
-							TmpCipher = Ndis802_11Encryption2Enabled;
-							break;
-						case 4:
-							TmpCipher = Ndis802_11Encryption3Enabled;
-							break;
-						default:
-							break;
-					}
-					if (TmpCipher > pBss->WPA.PairCipher)
-					{
-						// Move the lower cipher suite to PairCipherAux
-						pBss->WPA.PairCipherAux = pBss->WPA.PairCipher;
-						pBss->WPA.PairCipher	= TmpCipher;
-					}
-					else
-					{
-						pBss->WPA.PairCipherAux = TmpCipher;
-					}
-					pTmp++;
-					Count--;
-				}
-
-				// 4. get AKM suite counts
-				//Count	= *(PUSHORT) pTmp;
-				Count = (pTmp[1]<<8) + pTmp[0];
-				pTmp   += sizeof(USHORT);
-				pTmp   += 3;
-
-				switch (*pTmp)
-				{
-					case 1:
-						// Set AP support WPA mode
-						if (pBss->AuthMode == Ndis802_11AuthModeOpen)
-							pBss->AuthMode = Ndis802_11AuthModeWPA;
-						else
-							pBss->AuthModeAux = Ndis802_11AuthModeWPA;
-						break;
-					case 2:
-						// Set AP support WPA mode
-						if (pBss->AuthMode == Ndis802_11AuthModeOpen)
-							pBss->AuthMode = Ndis802_11AuthModeWPAPSK;
-						else
-							pBss->AuthModeAux = Ndis802_11AuthModeWPAPSK;
-						break;
-					default:
-						break;
-				}
-				pTmp   += 1;
-
-				// Fixed for WPA-None
-				if (pBss->BssType == BSS_ADHOC)
-				{
-					pBss->AuthMode	  = Ndis802_11AuthModeWPANone;
-					pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
-					pBss->WepStatus   = pBss->WPA.GroupCipher;
-					if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
-						pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
-				}
-				else
-					pBss->WepStatus   = pBss->WPA.PairCipher;
-
-				// Check the Pair & Group, if different, turn on mixed mode flag
-				if (pBss->WPA.GroupCipher != pBss->WPA.PairCipher)
-					pBss->WPA.bMixMode = TRUE;
-
+	while (Length > 0) {
+		/* Parse cipher suite base on WPA1 & WPA2, they should be parsed differently */
+		pTmp = ((u8 *)pBss->VarIEs) + pBss->VarIELen - Length;
+		pEid = (struct rt_eid *) pTmp;
+		switch (pEid->Eid) {
+		case IE_WPA:
+			if (NdisEqualMemory(pEid->Octet, SES_OUI, 3)
+			    && (pEid->Len == 7)) {
+				pBss->bSES = TRUE;
 				break;
+			} else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) !=
+				   1) {
+				/* if unsupported vendor specific IE */
+				break;
+			}
+			/* Skip OUI, version, and multicast suite */
+			/* This part should be improved in the future when AP supported multiple cipher suite. */
+			/* For now, it's OK since almost all APs have fixed cipher suite supported. */
+			/* pTmp = (u8 *)pEid->Octet; */
+			pTmp += 11;
 
-			case IE_RSN:
-				pRsnHeader = (PRSN_IE_HEADER_STRUCT) pTmp;
-
-				// 0. Version must be 1
-				if (le2cpu16(pRsnHeader->Version) != 1)
-					break;
-				pTmp   += sizeof(RSN_IE_HEADER_STRUCT);
-
-				// 1. Check group cipher
-				pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
-				if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
-					break;
-
-				// Parse group cipher
-				switch (pCipher->Type)
-				{
-					case 1:
-						pBss->WPA2.GroupCipher = Ndis802_11GroupWEP40Enabled;
-						break;
-					case 5:
-						pBss->WPA2.GroupCipher = Ndis802_11GroupWEP104Enabled;
-						break;
-					case 2:
-						pBss->WPA2.GroupCipher = Ndis802_11Encryption2Enabled;
-						break;
-					case 4:
-						pBss->WPA2.GroupCipher = Ndis802_11Encryption3Enabled;
-						break;
-					default:
-						break;
-				}
-				// set to correct offset for next parsing
-				pTmp   += sizeof(CIPHER_SUITE_STRUCT);
-
-				// 2. Get pairwise cipher counts
-				//Count = *(PUSHORT) pTmp;
-				Count = (pTmp[1]<<8) + pTmp[0];
-				pTmp   += sizeof(USHORT);
-
-				// 3. Get pairwise cipher
-				// Parsing all unicast cipher suite
-				while (Count > 0)
-				{
-					// Skip OUI
-					pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
-					TmpCipher = Ndis802_11WEPDisabled;
-					switch (pCipher->Type)
-					{
-						case 1:
-						case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
-							TmpCipher = Ndis802_11Encryption1Enabled;
-							break;
-						case 2:
-							TmpCipher = Ndis802_11Encryption2Enabled;
-							break;
-						case 4:
-							TmpCipher = Ndis802_11Encryption3Enabled;
-							break;
-						default:
-							break;
-					}
-					if (TmpCipher > pBss->WPA2.PairCipher)
-					{
-						// Move the lower cipher suite to PairCipherAux
-						pBss->WPA2.PairCipherAux = pBss->WPA2.PairCipher;
-						pBss->WPA2.PairCipher	 = TmpCipher;
-					}
-					else
-					{
-						pBss->WPA2.PairCipherAux = TmpCipher;
-					}
-					pTmp += sizeof(CIPHER_SUITE_STRUCT);
-					Count--;
-				}
-
-				// 4. get AKM suite counts
-				//Count	= *(PUSHORT) pTmp;
-				Count = (pTmp[1]<<8) + pTmp[0];
-				pTmp   += sizeof(USHORT);
-
-				// 5. Get AKM ciphers
-				pAKM = (PAKM_SUITE_STRUCT) pTmp;
-				if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
-					break;
-
-				switch (pAKM->Type)
-				{
-					case 1:
-						// Set AP support WPA mode
-						if (pBss->AuthMode == Ndis802_11AuthModeOpen)
-							pBss->AuthMode = Ndis802_11AuthModeWPA2;
-						else
-							pBss->AuthModeAux = Ndis802_11AuthModeWPA2;
-						break;
-					case 2:
-						// Set AP support WPA mode
-						if (pBss->AuthMode == Ndis802_11AuthModeOpen)
-							pBss->AuthMode = Ndis802_11AuthModeWPA2PSK;
-						else
-							pBss->AuthModeAux = Ndis802_11AuthModeWPA2PSK;
-						break;
-					default:
-						break;
-				}
-				pTmp   += (Count * sizeof(AKM_SUITE_STRUCT));
-
-				// Fixed for WPA-None
-				if (pBss->BssType == BSS_ADHOC)
-				{
-					pBss->AuthMode = Ndis802_11AuthModeWPANone;
-					pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
-					pBss->WPA.PairCipherAux = pBss->WPA2.PairCipherAux;
-					pBss->WPA.GroupCipher	= pBss->WPA2.GroupCipher;
-					pBss->WepStatus 		= pBss->WPA.GroupCipher;
-					if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
-						pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
-				}
-				pBss->WepStatus   = pBss->WPA2.PairCipher;
-
-				// 6. Get RSN capability
-				//pBss->WPA2.RsnCapability = *(PUSHORT) pTmp;
-				pBss->WPA2.RsnCapability = (pTmp[1]<<8) + pTmp[0];
-				pTmp += sizeof(USHORT);
-
-				// Check the Pair & Group, if different, turn on mixed mode flag
-				if (pBss->WPA2.GroupCipher != pBss->WPA2.PairCipher)
-					pBss->WPA2.bMixMode = TRUE;
-
+			/* Cipher Suite Selectors from Spec P802.11i/D3.2 P26. */
+			/*      Value      Meaning */
+			/*      0                       None */
+			/*      1                       WEP-40 */
+			/*      2                       Tkip */
+			/*      3                       WRAP */
+			/*      4                       AES */
+			/*      5                       WEP-104 */
+			/* Parse group cipher */
+			switch (*pTmp) {
+			case 1:
+				pBss->WPA.GroupCipher =
+				    Ndis802_11GroupWEP40Enabled;
+				break;
+			case 5:
+				pBss->WPA.GroupCipher =
+				    Ndis802_11GroupWEP104Enabled;
+				break;
+			case 2:
+				pBss->WPA.GroupCipher =
+				    Ndis802_11Encryption2Enabled;
+				break;
+			case 4:
+				pBss->WPA.GroupCipher =
+				    Ndis802_11Encryption3Enabled;
 				break;
 			default:
 				break;
+			}
+			/* number of unicast suite */
+			pTmp += 1;
+
+			/* skip all unicast cipher suites */
+			/*Count = *(u16 *)pTmp; */
+			Count = (pTmp[1] << 8) + pTmp[0];
+			pTmp += sizeof(u16);
+
+			/* Parsing all unicast cipher suite */
+			while (Count > 0) {
+				/* Skip OUI */
+				pTmp += 3;
+				TmpCipher = Ndis802_11WEPDisabled;
+				switch (*pTmp) {
+				case 1:
+				case 5:	/* Although WEP is not allowed in WPA related auth mode, we parse it anyway */
+					TmpCipher =
+					    Ndis802_11Encryption1Enabled;
+					break;
+				case 2:
+					TmpCipher =
+					    Ndis802_11Encryption2Enabled;
+					break;
+				case 4:
+					TmpCipher =
+					    Ndis802_11Encryption3Enabled;
+					break;
+				default:
+					break;
+				}
+				if (TmpCipher > pBss->WPA.PairCipher) {
+					/* Move the lower cipher suite to PairCipherAux */
+					pBss->WPA.PairCipherAux =
+					    pBss->WPA.PairCipher;
+					pBss->WPA.PairCipher = TmpCipher;
+				} else {
+					pBss->WPA.PairCipherAux = TmpCipher;
+				}
+				pTmp++;
+				Count--;
+			}
+
+			/* 4. get AKM suite counts */
+			/*Count = *(u16 *)pTmp; */
+			Count = (pTmp[1] << 8) + pTmp[0];
+			pTmp += sizeof(u16);
+			pTmp += 3;
+
+			switch (*pTmp) {
+			case 1:
+				/* Set AP support WPA-enterprise mode */
+				if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+					pBss->AuthMode = Ndis802_11AuthModeWPA;
+				else
+					pBss->AuthModeAux =
+					    Ndis802_11AuthModeWPA;
+				break;
+			case 2:
+				/* Set AP support WPA-PSK mode */
+				if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+					pBss->AuthMode =
+					    Ndis802_11AuthModeWPAPSK;
+				else
+					pBss->AuthModeAux =
+					    Ndis802_11AuthModeWPAPSK;
+				break;
+			default:
+				break;
+			}
+			pTmp += 1;
+
+			/* Fixed for WPA-None */
+			if (pBss->BssType == BSS_ADHOC) {
+				pBss->AuthMode = Ndis802_11AuthModeWPANone;
+				pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
+				pBss->WepStatus = pBss->WPA.GroupCipher;
+				/* Patched bugs for old driver */
+				if (pBss->WPA.PairCipherAux ==
+				    Ndis802_11WEPDisabled)
+					pBss->WPA.PairCipherAux =
+					    pBss->WPA.GroupCipher;
+			} else
+				pBss->WepStatus = pBss->WPA.PairCipher;
+
+			/* Check the Pair & Group, if different, turn on mixed mode flag */
+			if (pBss->WPA.GroupCipher != pBss->WPA.PairCipher)
+				pBss->WPA.bMixMode = TRUE;
+
+			break;
+
+		case IE_RSN:
+			pRsnHeader = (struct rt_rsn_ie_header *) pTmp;
+
+			/* 0. Version must be 1 */
+			if (le2cpu16(pRsnHeader->Version) != 1)
+				break;
+			pTmp += sizeof(struct rt_rsn_ie_header);
+
+			/* 1. Check group cipher */
+			pCipher = (struct rt_cipher_suite_struct *) pTmp;
+			if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
+				break;
+
+			/* Parse group cipher */
+			switch (pCipher->Type) {
+			case 1:
+				pBss->WPA2.GroupCipher =
+				    Ndis802_11GroupWEP40Enabled;
+				break;
+			case 5:
+				pBss->WPA2.GroupCipher =
+				    Ndis802_11GroupWEP104Enabled;
+				break;
+			case 2:
+				pBss->WPA2.GroupCipher =
+				    Ndis802_11Encryption2Enabled;
+				break;
+			case 4:
+				pBss->WPA2.GroupCipher =
+				    Ndis802_11Encryption3Enabled;
+				break;
+			default:
+				break;
+			}
+			/* set to correct offset for next parsing */
+			pTmp += sizeof(struct rt_cipher_suite_struct);
+
+			/* 2. Get pairwise cipher counts */
+			/*Count = *(u16 *)pTmp; */
+			Count = (pTmp[1] << 8) + pTmp[0];
+			pTmp += sizeof(u16);
+
+			/* 3. Get pairwise cipher */
+			/* Parsing all unicast cipher suite */
+			while (Count > 0) {
+				/* Skip OUI */
+				pCipher = (struct rt_cipher_suite_struct *) pTmp;
+				TmpCipher = Ndis802_11WEPDisabled;
+				switch (pCipher->Type) {
+				case 1:
+				case 5:	/* Although WEP is not allowed in WPA related auth mode, we parse it anyway */
+					TmpCipher =
+					    Ndis802_11Encryption1Enabled;
+					break;
+				case 2:
+					TmpCipher =
+					    Ndis802_11Encryption2Enabled;
+					break;
+				case 4:
+					TmpCipher =
+					    Ndis802_11Encryption3Enabled;
+					break;
+				default:
+					break;
+				}
+				if (TmpCipher > pBss->WPA2.PairCipher) {
+					/* Move the lower cipher suite to PairCipherAux */
+					pBss->WPA2.PairCipherAux =
+					    pBss->WPA2.PairCipher;
+					pBss->WPA2.PairCipher = TmpCipher;
+				} else {
+					pBss->WPA2.PairCipherAux = TmpCipher;
+				}
+				pTmp += sizeof(struct rt_cipher_suite_struct);
+				Count--;
+			}
+
+			/* 4. get AKM suite counts */
+			/*Count = *(u16 *)pTmp; */
+			Count = (pTmp[1] << 8) + pTmp[0];
+			pTmp += sizeof(u16);
+
+			/* 5. Get AKM ciphers */
+			/* Parsing all AKM ciphers */
+			while (Count > 0) {
+				pAKM = (struct rt_akm_suite *) pTmp;
+				if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
+					break;
+
+				switch (pAKM->Type) {
+				case 1:
+					/* Set AP support WPA-enterprise mode */
+					if (pBss->AuthMode ==
+					    Ndis802_11AuthModeOpen)
+						pBss->AuthMode =
+						    Ndis802_11AuthModeWPA2;
+					else
+						pBss->AuthModeAux =
+						    Ndis802_11AuthModeWPA2;
+					break;
+				case 2:
+					/* Set AP support WPA-PSK mode */
+					if (pBss->AuthMode ==
+					    Ndis802_11AuthModeOpen)
+						pBss->AuthMode =
+						    Ndis802_11AuthModeWPA2PSK;
+					else
+						pBss->AuthModeAux =
+						    Ndis802_11AuthModeWPA2PSK;
+					break;
+				default:
+					if (pBss->AuthMode ==
+					    Ndis802_11AuthModeOpen)
+						pBss->AuthMode =
+						    Ndis802_11AuthModeMax;
+					else
+						pBss->AuthModeAux =
+						    Ndis802_11AuthModeMax;
+					break;
+				}
+				pTmp += (Count * sizeof(struct rt_akm_suite));
+				Count--;
+			}
+
+			/* Fixed for WPA-None */
+			if (pBss->BssType == BSS_ADHOC) {
+				pBss->AuthMode = Ndis802_11AuthModeWPANone;
+				pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
+				pBss->WPA.PairCipherAux =
+				    pBss->WPA2.PairCipherAux;
+				pBss->WPA.GroupCipher = pBss->WPA2.GroupCipher;
+				pBss->WepStatus = pBss->WPA.GroupCipher;
+				/* Patched bugs for old driver */
+				if (pBss->WPA.PairCipherAux ==
+				    Ndis802_11WEPDisabled)
+					pBss->WPA.PairCipherAux =
+					    pBss->WPA.GroupCipher;
+			}
+			pBss->WepStatus = pBss->WPA2.PairCipher;
+
+			/* 6. Get RSN capability */
+			/*pBss->WPA2.RsnCapability = *(u16 *)pTmp; */
+			pBss->WPA2.RsnCapability = (pTmp[1] << 8) + pTmp[0];
+			pTmp += sizeof(u16);
+
+			/* Check the Pair & Group, if different, turn on mixed mode flag */
+			if (pBss->WPA2.GroupCipher != pBss->WPA2.PairCipher)
+				pBss->WPA2.bMixMode = TRUE;
+
+			break;
+		default:
+			break;
 		}
 		Length -= (pEid->Len + 2);
 	}
 }
 
-// ===========================================================================================
-// mac_table.c
-// ===========================================================================================
+/* =========================================================================================== */
+/* mac_table.c */
+/* =========================================================================================== */
 
 /*! \brief generates a random mac address value for IBSS BSSID
  *	\param Addr the bssid location
@@ -4450,18 +4546,15 @@
  *	\pre
  *	\post
  */
-VOID MacAddrRandomBssid(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pAddr)
+void MacAddrRandomBssid(struct rt_rtmp_adapter *pAd, u8 *pAddr)
 {
-	INT i;
+	int i;
 
-	for (i = 0; i < MAC_ADDR_LEN; i++)
-	{
+	for (i = 0; i < MAC_ADDR_LEN; i++) {
 		pAddr[i] = RandomByte(pAd);
 	}
 
-	pAddr[0] = (pAddr[0] & 0xfe) | 0x02;  // the first 2 bits must be 01xxxxxxxx
+	pAddr[0] = (pAddr[0] & 0xfe) | 0x02;	/* the first 2 bits must be 01xxxxxxxx */
 }
 
 /*! \brief init the management mac frame header
@@ -4475,33 +4568,30 @@
  *	\post
  *	\note this function initializes the following field
 
- IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
 
  */
-VOID MgtMacHeaderInit(
-	IN	PRTMP_ADAPTER	pAd,
-	IN OUT PHEADER_802_11 pHdr80211,
-	IN UCHAR SubType,
-	IN UCHAR ToDs,
-	IN PUCHAR pDA,
-	IN PUCHAR pBssid)
+void MgtMacHeaderInit(struct rt_rtmp_adapter *pAd,
+		      struct rt_header_802_11 * pHdr80211,
+		      u8 SubType,
+		      u8 ToDs, u8 *pDA, u8 *pBssid)
 {
-	NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
+	NdisZeroMemory(pHdr80211, sizeof(struct rt_header_802_11));
 
 	pHdr80211->FC.Type = BTYPE_MGMT;
 	pHdr80211->FC.SubType = SubType;
+/*      if (SubType == SUBTYPE_ACK)     // sample, no use, it will conflict with ACTION frame sub type */
+/*              pHdr80211->FC.Type = BTYPE_CNTL; */
 	pHdr80211->FC.ToDs = ToDs;
 	COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
-
 	COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
-
 	COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
 }
 
-// ===========================================================================================
-// mem_mgmt.c
-// ===========================================================================================
+/* =========================================================================================== */
+/* mem_mgmt.c */
+/* =========================================================================================== */
 
 /*!***************************************************************************
  * This routine build an outgoing frame, and fill all information specified
@@ -4510,49 +4600,45 @@
  * input params:
  *		Buffer - pointer to a pre-allocated memory segment
  *		args - a list of <int arg_size, arg> pairs.
- *		NOTE NOTE NOTE!!!! the last argument must be NULL, otherwise this
- *						   function will FAIL!!!
+ *		NOTE NOTE NOTE! the last argument must be NULL, otherwise this
+ *						   function will FAIL!
  * return:
  *		Size of the buffer
  * usage:
  *		MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS);
 
  IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
+	IRQL = DISPATCH_LEVEL
 
  ****************************************************************************/
-ULONG MakeOutgoingFrame(
-	OUT CHAR *Buffer,
-	OUT ULONG *FrameLen, ...)
+unsigned long MakeOutgoingFrame(u8 * Buffer, unsigned long * FrameLen, ...)
 {
-	CHAR   *p;
-	int 	leng;
-	ULONG	TotLeng;
+	u8 *p;
+	int leng;
+	unsigned long TotLeng;
 	va_list Args;
 
-	// calculates the total length
+	/* calculates the total length */
 	TotLeng = 0;
 	va_start(Args, FrameLen);
-	do
-	{
+	do {
 		leng = va_arg(Args, int);
-		if (leng == END_OF_ARGS)
-		{
+		if (leng == END_OF_ARGS) {
 			break;
 		}
-		p = va_arg(Args, PVOID);
+		p = va_arg(Args, void *);
 		NdisMoveMemory(&Buffer[TotLeng], p, leng);
 		TotLeng = TotLeng + leng;
-	} while(TRUE);
+	} while (TRUE);
 
-	va_end(Args); /* clean up */
+	va_end(Args);		/* clean up */
 	*FrameLen = TotLeng;
 	return TotLeng;
 }
 
-// ===========================================================================================
-// mlme_queue.c
-// ===========================================================================================
+/* =========================================================================================== */
+/* mlme_queue.c */
+/* =========================================================================================== */
 
 /*! \brief	Initialize The MLME Queue, used by MLME Functions
  *	\param	*Queue	   The MLME Queue
@@ -4564,19 +4650,17 @@
  IRQL = PASSIVE_LEVEL
 
  */
-NDIS_STATUS MlmeQueueInit(
-	IN MLME_QUEUE *Queue)
+int MlmeQueueInit(struct rt_mlme_queue *Queue)
 {
-	INT i;
+	int i;
 
 	NdisAllocateSpinLock(&Queue->Lock);
 
-	Queue->Num	= 0;
+	Queue->Num = 0;
 	Queue->Head = 0;
 	Queue->Tail = 0;
 
-	for (i = 0; i < MAX_LEN_OF_MLME_QUEUE; i++)
-	{
+	for (i = 0; i < MAX_LEN_OF_MLME_QUEUE; i++) {
 		Queue->Entry[i].Occupied = FALSE;
 		Queue->Entry[i].MsgLen = 0;
 		NdisZeroMemory(Queue->Entry[i].Msg, MGMT_DMA_BUFFER_SIZE);
@@ -4596,34 +4680,31 @@
  *	\post
  *	\note	 The message has to be initialized
 
- IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
 
  */
-BOOLEAN MlmeEnqueue(
-	IN	PRTMP_ADAPTER	pAd,
-	IN ULONG Machine,
-	IN ULONG MsgType,
-	IN ULONG MsgLen,
-	IN VOID *Msg)
+BOOLEAN MlmeEnqueue(struct rt_rtmp_adapter *pAd,
+		    unsigned long Machine,
+		    unsigned long MsgType, unsigned long MsgLen, void * Msg)
 {
-	INT Tail;
-	MLME_QUEUE	*Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
+	int Tail;
+	struct rt_mlme_queue *Queue = (struct rt_mlme_queue *)& pAd->Mlme.Queue;
 
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+	/* Do nothing if the driver is starting halt state. */
+	/* This might happen when timer already been fired before cancel timer with mlmehalt */
+	if (RTMP_TEST_FLAG
+	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
 		return FALSE;
 
-	// First check the size, it MUST not exceed the mlme queue size
-	if (MsgLen > MGMT_DMA_BUFFER_SIZE)
-	{
-		DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n", MsgLen));
+	/* First check the size, it MUST not exceed the mlme queue size */
+	if (MsgLen > MGMT_DMA_BUFFER_SIZE) {
+		DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n",
+			      MsgLen));
 		return FALSE;
 	}
 
-	if (MlmeQueueFull(Queue))
-	{
+	if (MlmeQueueFull(Queue)) {
 		return FALSE;
 	}
 
@@ -4631,8 +4712,7 @@
 	Tail = Queue->Tail;
 	Queue->Tail++;
 	Queue->Num++;
-	if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
-	{
+	if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE) {
 		Queue->Tail = 0;
 	}
 
@@ -4640,10 +4720,9 @@
 	Queue->Entry[Tail].Occupied = TRUE;
 	Queue->Entry[Tail].Machine = Machine;
 	Queue->Entry[Tail].MsgType = MsgType;
-	Queue->Entry[Tail].MsgLen  = MsgLen;
+	Queue->Entry[Tail].MsgLen = MsgLen;
 
-	if (Msg != NULL)
-	{
+	if (Msg != NULL) {
 		NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
 	}
 
@@ -4656,7 +4735,7 @@
  *	\param	 TimeStampHigh	 The upper 32 bit of timestamp
  *	\param	 TimeStampLow	 The lower 32 bit of timestamp
  *	\param	 Rssi			 The receiving RSSI strength
- *	\param	 MsgLen 		 The length of the message
+ *	\param	 MsgLen			 The length of the message
  *	\param	*Msg			 The message pointer
  *	\return  TRUE if everything ok, FALSE otherwise (like Queue Full)
  *	\pre
@@ -4665,87 +4744,78 @@
  IRQL = DISPATCH_LEVEL
 
  */
-BOOLEAN MlmeEnqueueForRecv(
-	IN	PRTMP_ADAPTER	pAd,
-	IN ULONG Wcid,
-	IN ULONG TimeStampHigh,
-	IN ULONG TimeStampLow,
-	IN UCHAR Rssi0,
-	IN UCHAR Rssi1,
-	IN UCHAR Rssi2,
-	IN ULONG MsgLen,
-	IN VOID *Msg,
-	IN UCHAR Signal)
+BOOLEAN MlmeEnqueueForRecv(struct rt_rtmp_adapter *pAd,
+			   unsigned long Wcid,
+			   unsigned long TimeStampHigh,
+			   unsigned long TimeStampLow,
+			   u8 Rssi0,
+			   u8 Rssi1,
+			   u8 Rssi2,
+			   unsigned long MsgLen, void * Msg, u8 Signal)
 {
-	INT 		 Tail, Machine;
-	PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
-	INT		 MsgType;
-	MLME_QUEUE	*Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
+	int Tail, Machine;
+	struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg;
+	int MsgType;
+	struct rt_mlme_queue *Queue = (struct rt_mlme_queue *)& pAd->Mlme.Queue;
 
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-	{
+	/* Do nothing if the driver is starting halt state. */
+	/* This might happen when timer already been fired before cancel timer with mlmehalt */
+	if (RTMP_TEST_FLAG
+	    (pAd,
+	     fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) {
 		DBGPRINT_ERR(("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n"));
 		return FALSE;
 	}
-
-	// First check the size, it MUST not exceed the mlme queue size
-	if (MsgLen > MGMT_DMA_BUFFER_SIZE)
-	{
+	/* First check the size, it MUST not exceed the mlme queue size */
+	if (MsgLen > MGMT_DMA_BUFFER_SIZE) {
 		DBGPRINT_ERR(("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
 		return FALSE;
 	}
 
-	if (MlmeQueueFull(Queue))
-	{
+	if (MlmeQueueFull(Queue)) {
 		return FALSE;
 	}
 
 	{
-		if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType))
-		{
-			DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n",pFrame->Hdr.FC.SubType));
+		if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType)) {
+			DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n", pFrame->Hdr.FC.SubType));
 			return FALSE;
 		}
 	}
 
-	// OK, we got all the informations, it is time to put things into queue
+	/* OK, we got all the informations, it is time to put things into queue */
 	NdisAcquireSpinLock(&(Queue->Lock));
 	Tail = Queue->Tail;
 	Queue->Tail++;
 	Queue->Num++;
-	if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
-	{
+	if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE) {
 		Queue->Tail = 0;
 	}
 	Queue->Entry[Tail].Occupied = TRUE;
 	Queue->Entry[Tail].Machine = Machine;
 	Queue->Entry[Tail].MsgType = MsgType;
-	Queue->Entry[Tail].MsgLen  = MsgLen;
+	Queue->Entry[Tail].MsgLen = MsgLen;
 	Queue->Entry[Tail].TimeStamp.u.LowPart = TimeStampLow;
 	Queue->Entry[Tail].TimeStamp.u.HighPart = TimeStampHigh;
 	Queue->Entry[Tail].Rssi0 = Rssi0;
 	Queue->Entry[Tail].Rssi1 = Rssi1;
 	Queue->Entry[Tail].Rssi2 = Rssi2;
 	Queue->Entry[Tail].Signal = Signal;
-	Queue->Entry[Tail].Wcid = (UCHAR)Wcid;
+	Queue->Entry[Tail].Wcid = (u8)Wcid;
 
 	Queue->Entry[Tail].Channel = pAd->LatchRfRegs.Channel;
 
-	if (Msg != NULL)
-	{
+	if (Msg != NULL) {
 		NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
 	}
 
 	NdisReleaseSpinLock(&(Queue->Lock));
 
-	RT28XX_MLME_HANDLER(pAd);
+	RTMP_MLME_HANDLER(pAd);
 
 	return TRUE;
 }
 
-
 /*! \brief	 Dequeue a message from the MLME Queue
  *	\param	*Queue	  The MLME Queue
  *	\param	*Elem	  The message dequeued from MLME Queue
@@ -4756,97 +4826,88 @@
  IRQL = DISPATCH_LEVEL
 
  */
-BOOLEAN MlmeDequeue(
-	IN MLME_QUEUE *Queue,
-	OUT MLME_QUEUE_ELEM **Elem)
+BOOLEAN MlmeDequeue(struct rt_mlme_queue *Queue, struct rt_mlme_queue_elem ** Elem)
 {
 	NdisAcquireSpinLock(&(Queue->Lock));
 	*Elem = &(Queue->Entry[Queue->Head]);
 	Queue->Num--;
 	Queue->Head++;
-	if (Queue->Head == MAX_LEN_OF_MLME_QUEUE)
-	{
+	if (Queue->Head == MAX_LEN_OF_MLME_QUEUE) {
 		Queue->Head = 0;
 	}
 	NdisReleaseSpinLock(&(Queue->Lock));
 	return TRUE;
 }
 
-// IRQL = DISPATCH_LEVEL
-VOID	MlmeRestartStateMachine(
-	IN	PRTMP_ADAPTER	pAd)
+/* IRQL = DISPATCH_LEVEL */
+void MlmeRestartStateMachine(struct rt_rtmp_adapter *pAd)
 {
-#ifdef RT2860
-	MLME_QUEUE_ELEM		*Elem = NULL;
-#endif
-	BOOLEAN				Cancelled;
+#ifdef RTMP_MAC_PCI
+	struct rt_mlme_queue_elem *Elem = NULL;
+#endif /* RTMP_MAC_PCI // */
+	BOOLEAN Cancelled;
 
 	DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n"));
 
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
 	NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
-	if(pAd->Mlme.bRunning)
-	{
+	if (pAd->Mlme.bRunning) {
 		NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
 		return;
-	}
-	else
-	{
+	} else {
 		pAd->Mlme.bRunning = TRUE;
 	}
 	NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
 
-	// Remove all Mlme queues elements
-	while (!MlmeQueueEmpty(&pAd->Mlme.Queue))
-	{
-		//From message type, determine which state machine I should drive
-		if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
-		{
-			// free MLME element
+	/* Remove all Mlme queues elements */
+	while (!MlmeQueueEmpty(&pAd->Mlme.Queue)) {
+		/*From message type, determine which state machine I should drive */
+		if (MlmeDequeue(&pAd->Mlme.Queue, &Elem)) {
+			/* free MLME element */
 			Elem->Occupied = FALSE;
 			Elem->MsgLen = 0;
 
-		}
-		else {
+		} else {
 			DBGPRINT_ERR(("MlmeRestartStateMachine: MlmeQueue empty\n"));
 		}
 	}
-#endif /* RT2860 */
+#endif /* RTMP_MAC_PCI // */
 
 	{
-		// Cancel all timer events
-		// Be careful to cancel new added timer
-		RTMPCancelTimer(&pAd->MlmeAux.AssocTimer,	  &Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer,   &Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer,  &Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.AuthTimer,	   &Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer,	   &Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.ScanTimer,	   &Cancelled);
+		/* Cancel all timer events */
+		/* Be careful to cancel new added timer */
+		RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
+
 	}
 
-	// Change back to original channel in case of doing scan
+	/* Change back to original channel in case of doing scan */
 	AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
 	AsicLockChannel(pAd, pAd->CommonCfg.Channel);
 
-	// Resume MSDU which is turned off durning scan
+	/* Resume MSDU which is turned off durning scan */
 	RTMPResumeMsduTransmission(pAd);
 
 	{
-		// Set all state machines back IDLE
-		pAd->Mlme.CntlMachine.CurrState    = CNTL_IDLE;
-		pAd->Mlme.AssocMachine.CurrState   = ASSOC_IDLE;
-		pAd->Mlme.AuthMachine.CurrState    = AUTH_REQ_IDLE;
+		/* Set all state machines back IDLE */
+		pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+		pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
 		pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE;
-		pAd->Mlme.SyncMachine.CurrState    = SYNC_IDLE;
-		pAd->Mlme.ActMachine.CurrState    = ACT_IDLE;
+		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+		pAd->Mlme.ActMachine.CurrState = ACT_IDLE;
 	}
 
-#ifdef RT2860
-	// Remove running state
+#ifdef RTMP_MAC_PCI
+	/* Remove running state */
 	NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
 	pAd->Mlme.bRunning = FALSE;
 	NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
-#endif
+#endif /* RTMP_MAC_PCI // */
 }
 
 /*! \brief	test if the MLME Queue is empty
@@ -4858,8 +4919,7 @@
  IRQL = DISPATCH_LEVEL
 
  */
-BOOLEAN MlmeQueueEmpty(
-	IN MLME_QUEUE *Queue)
+BOOLEAN MlmeQueueEmpty(struct rt_mlme_queue *Queue)
 {
 	BOOLEAN Ans;
 
@@ -4871,7 +4931,7 @@
 }
 
 /*! \brief	 test if the MLME Queue is full
- *	\param	 *Queue 	 The MLME Queue
+ *	\param	 *Queue		 The MLME Queue
  *	\return  TRUE if the Queue is empty, FALSE otherwise
  *	\pre
  *	\post
@@ -4880,13 +4940,13 @@
  IRQL = DISPATCH_LEVEL
 
  */
-BOOLEAN MlmeQueueFull(
-	IN MLME_QUEUE *Queue)
+BOOLEAN MlmeQueueFull(struct rt_mlme_queue *Queue)
 {
 	BOOLEAN Ans;
 
 	NdisAcquireSpinLock(&(Queue->Lock));
-	Ans = (Queue->Num == MAX_LEN_OF_MLME_QUEUE || Queue->Entry[Queue->Tail].Occupied);
+	Ans = (Queue->Num == MAX_LEN_OF_MLME_QUEUE
+	       || Queue->Entry[Queue->Tail].Occupied);
 	NdisReleaseSpinLock(&(Queue->Lock));
 
 	return Ans;
@@ -4902,11 +4962,10 @@
  IRQL = PASSIVE_LEVEL
 
  */
-VOID MlmeQueueDestroy(
-	IN MLME_QUEUE *pQueue)
+void MlmeQueueDestroy(struct rt_mlme_queue *pQueue)
 {
 	NdisAcquireSpinLock(&(pQueue->Lock));
-	pQueue->Num  = 0;
+	pQueue->Num = 0;
 	pQueue->Head = 0;
 	pQueue->Tail = 0;
 	NdisReleaseSpinLock(&(pQueue->Lock));
@@ -4924,126 +4983,112 @@
  IRQL = DISPATCH_LEVEL
 
  */
-BOOLEAN MsgTypeSubst(
-	IN PRTMP_ADAPTER  pAd,
-	IN PFRAME_802_11 pFrame,
-	OUT INT *Machine,
-	OUT INT *MsgType)
+BOOLEAN MsgTypeSubst(struct rt_rtmp_adapter *pAd,
+		     struct rt_frame_802_11 * pFrame,
+		     int * Machine, int * MsgType)
 {
-	USHORT	Seq;
-	UCHAR	EAPType;
-	PUCHAR	pData;
+	u16 Seq, Alg;
+	u8 EAPType;
+	u8 *pData;
 
-	// Pointer to start of data frames including SNAP header
-	pData = (PUCHAR) pFrame + LENGTH_802_11;
+	/* Pointer to start of data frames including SNAP header */
+	pData = (u8 *)pFrame + LENGTH_802_11;
 
-	// The only data type will pass to this function is EAPOL frame
-	if (pFrame->Hdr.FC.Type == BTYPE_DATA)
-	{
-		if (NdisEqualMemory(SNAP_AIRONET, pData, LENGTH_802_1_H))
+	/* The only data type will pass to this function is EAPOL frame */
+	if (pFrame->Hdr.FC.Type == BTYPE_DATA) {
 		{
-			// Cisco Aironet SNAP header
-			*Machine = AIRONET_STATE_MACHINE;
-			*MsgType = MT2_AIRONET_MSG;
-			return (TRUE);
-		}
-		{
-			*Machine = WPA_PSK_STATE_MACHINE;
-			EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
-			return(WpaMsgTypeSubst(EAPType, MsgType));
+			*Machine = WPA_STATE_MACHINE;
+			EAPType =
+			    *((u8 *) pFrame + LENGTH_802_11 +
+			      LENGTH_802_1_H + 1);
+			return (WpaMsgTypeSubst(EAPType, (int *) MsgType));
 		}
 	}
 
-	switch (pFrame->Hdr.FC.SubType)
-	{
-		case SUBTYPE_ASSOC_REQ:
-			*Machine = ASSOC_STATE_MACHINE;
-			*MsgType = MT2_PEER_ASSOC_REQ;
-			break;
-		case SUBTYPE_ASSOC_RSP:
-			*Machine = ASSOC_STATE_MACHINE;
-			*MsgType = MT2_PEER_ASSOC_RSP;
-			break;
-		case SUBTYPE_REASSOC_REQ:
-			*Machine = ASSOC_STATE_MACHINE;
-			*MsgType = MT2_PEER_REASSOC_REQ;
-			break;
-		case SUBTYPE_REASSOC_RSP:
-			*Machine = ASSOC_STATE_MACHINE;
-			*MsgType = MT2_PEER_REASSOC_RSP;
-			break;
-		case SUBTYPE_PROBE_REQ:
-			*Machine = SYNC_STATE_MACHINE;
-			*MsgType = MT2_PEER_PROBE_REQ;
-			break;
-		case SUBTYPE_PROBE_RSP:
-			*Machine = SYNC_STATE_MACHINE;
-			*MsgType = MT2_PEER_PROBE_RSP;
-			break;
-		case SUBTYPE_BEACON:
-			*Machine = SYNC_STATE_MACHINE;
-			*MsgType = MT2_PEER_BEACON;
-			break;
-		case SUBTYPE_ATIM:
-			*Machine = SYNC_STATE_MACHINE;
-			*MsgType = MT2_PEER_ATIM;
-			break;
-		case SUBTYPE_DISASSOC:
-			*Machine = ASSOC_STATE_MACHINE;
-			*MsgType = MT2_PEER_DISASSOC_REQ;
-			break;
-		case SUBTYPE_AUTH:
-			// get the sequence number from payload 24 Mac Header + 2 bytes algorithm
-			NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(USHORT));
-			if (Seq == 1 || Seq == 3)
-			{
-				*Machine = AUTH_RSP_STATE_MACHINE;
-				*MsgType = MT2_PEER_AUTH_ODD;
-			}
-			else if (Seq == 2 || Seq == 4)
-			{
+	switch (pFrame->Hdr.FC.SubType) {
+	case SUBTYPE_ASSOC_REQ:
+		*Machine = ASSOC_STATE_MACHINE;
+		*MsgType = MT2_PEER_ASSOC_REQ;
+		break;
+	case SUBTYPE_ASSOC_RSP:
+		*Machine = ASSOC_STATE_MACHINE;
+		*MsgType = MT2_PEER_ASSOC_RSP;
+		break;
+	case SUBTYPE_REASSOC_REQ:
+		*Machine = ASSOC_STATE_MACHINE;
+		*MsgType = MT2_PEER_REASSOC_REQ;
+		break;
+	case SUBTYPE_REASSOC_RSP:
+		*Machine = ASSOC_STATE_MACHINE;
+		*MsgType = MT2_PEER_REASSOC_RSP;
+		break;
+	case SUBTYPE_PROBE_REQ:
+		*Machine = SYNC_STATE_MACHINE;
+		*MsgType = MT2_PEER_PROBE_REQ;
+		break;
+	case SUBTYPE_PROBE_RSP:
+		*Machine = SYNC_STATE_MACHINE;
+		*MsgType = MT2_PEER_PROBE_RSP;
+		break;
+	case SUBTYPE_BEACON:
+		*Machine = SYNC_STATE_MACHINE;
+		*MsgType = MT2_PEER_BEACON;
+		break;
+	case SUBTYPE_ATIM:
+		*Machine = SYNC_STATE_MACHINE;
+		*MsgType = MT2_PEER_ATIM;
+		break;
+	case SUBTYPE_DISASSOC:
+		*Machine = ASSOC_STATE_MACHINE;
+		*MsgType = MT2_PEER_DISASSOC_REQ;
+		break;
+	case SUBTYPE_AUTH:
+		/* get the sequence number from payload 24 Mac Header + 2 bytes algorithm */
+		NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(u16));
+		NdisMoveMemory(&Alg, &pFrame->Octet[0], sizeof(u16));
+		if (Seq == 1 || Seq == 3) {
+			*Machine = AUTH_RSP_STATE_MACHINE;
+			*MsgType = MT2_PEER_AUTH_ODD;
+		} else if (Seq == 2 || Seq == 4) {
+			if (Alg == AUTH_MODE_OPEN || Alg == AUTH_MODE_KEY) {
 				*Machine = AUTH_STATE_MACHINE;
 				*MsgType = MT2_PEER_AUTH_EVEN;
 			}
-			else
-			{
-				return FALSE;
-			}
-			break;
-		case SUBTYPE_DEAUTH:
-			*Machine = AUTH_RSP_STATE_MACHINE;
-			*MsgType = MT2_PEER_DEAUTH;
-			break;
-		case SUBTYPE_ACTION:
-			*Machine = ACTION_STATE_MACHINE;
-			//  Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support
-			if ((pFrame->Octet[0]&0x7F) > MAX_PEER_CATE_MSG)
-			{
-				*MsgType = MT2_ACT_INVALID;
-			}
-			else
-			{
-				*MsgType = (pFrame->Octet[0]&0x7F);
-			}
-			break;
-		default:
+		} else {
 			return FALSE;
-			break;
+		}
+		break;
+	case SUBTYPE_DEAUTH:
+		*Machine = AUTH_RSP_STATE_MACHINE;
+		*MsgType = MT2_PEER_DEAUTH;
+		break;
+	case SUBTYPE_ACTION:
+		*Machine = ACTION_STATE_MACHINE;
+		/*  Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support */
+		if ((pFrame->Octet[0] & 0x7F) > MAX_PEER_CATE_MSG) {
+			*MsgType = MT2_ACT_INVALID;
+		} else {
+			*MsgType = (pFrame->Octet[0] & 0x7F);
+		}
+		break;
+	default:
+		return FALSE;
+		break;
 	}
 
 	return TRUE;
 }
 
-// ===========================================================================================
-// state_machine.c
-// ===========================================================================================
+/* =========================================================================================== */
+/* state_machine.c */
+/* =========================================================================================== */
 
 /*! \brief Initialize the state machine.
  *	\param *S			pointer to the state machine
  *	\param	Trans		State machine transition function
  *	\param	StNr		number of states
  *	\param	MsgNr		number of messages
- *	\param	DefFunc 	default function, when there is invalid state/message combination
+ *	\param	DefFunc		default function, when there is invalid state/message combination
  *	\param	InitState	initial state of the state machine
  *	\param	Base		StateMachine base, internal use only
  *	\pre p_sm should be a legal pointer
@@ -5052,34 +5097,30 @@
  IRQL = PASSIVE_LEVEL
 
  */
-VOID StateMachineInit(
-	IN STATE_MACHINE *S,
-	IN STATE_MACHINE_FUNC Trans[],
-	IN ULONG StNr,
-	IN ULONG MsgNr,
-	IN STATE_MACHINE_FUNC DefFunc,
-	IN ULONG InitState,
-	IN ULONG Base)
+void StateMachineInit(struct rt_state_machine *S,
+		      IN STATE_MACHINE_FUNC Trans[],
+		      unsigned long StNr,
+		      unsigned long MsgNr,
+		      IN STATE_MACHINE_FUNC DefFunc,
+		      unsigned long InitState, unsigned long Base)
 {
-	ULONG i, j;
+	unsigned long i, j;
 
-	// set number of states and messages
+	/* set number of states and messages */
 	S->NrState = StNr;
-	S->NrMsg   = MsgNr;
-	S->Base    = Base;
+	S->NrMsg = MsgNr;
+	S->Base = Base;
 
-	S->TransFunc  = Trans;
+	S->TransFunc = Trans;
 
-	// init all state transition to default function
-	for (i = 0; i < StNr; i++)
-	{
-		for (j = 0; j < MsgNr; j++)
-		{
+	/* init all state transition to default function */
+	for (i = 0; i < StNr; i++) {
+		for (j = 0; j < MsgNr; j++) {
 			S->TransFunc[i * MsgNr + j] = DefFunc;
 		}
 	}
 
-	// set the starting state
+	/* set the starting state */
 	S->CurrState = InitState;
 }
 
@@ -5094,38 +5135,34 @@
  IRQL = PASSIVE_LEVEL
 
  */
-VOID StateMachineSetAction(
-	IN STATE_MACHINE *S,
-	IN ULONG St,
-	IN ULONG Msg,
-	IN STATE_MACHINE_FUNC Func)
+void StateMachineSetAction(struct rt_state_machine *S,
+			   unsigned long St,
+			   unsigned long Msg, IN STATE_MACHINE_FUNC Func)
 {
-	ULONG MsgIdx;
+	unsigned long MsgIdx;
 
 	MsgIdx = Msg - S->Base;
 
-	if (St < S->NrState && MsgIdx < S->NrMsg)
-	{
-		// boundary checking before setting the action
+	if (St < S->NrState && MsgIdx < S->NrMsg) {
+		/* boundary checking before setting the action */
 		S->TransFunc[St * S->NrMsg + MsgIdx] = Func;
 	}
 }
 
 /*! \brief	 This function does the state transition
  *	\param	 *Adapter the NIC adapter pointer
- *	\param	 *S 	  the state machine
+ *	\param	 *S	  the state machine
  *	\param	 *Elem	  the message to be executed
  *	\return   None
 
  IRQL = DISPATCH_LEVEL
 
  */
-VOID StateMachinePerformAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN STATE_MACHINE *S,
-	IN MLME_QUEUE_ELEM *Elem)
+void StateMachinePerformAction(struct rt_rtmp_adapter *pAd,
+			       struct rt_state_machine *S, struct rt_mlme_queue_elem *Elem)
 {
-	(*(S->TransFunc[S->CurrState * S->NrMsg + Elem->MsgType - S->Base]))(pAd, Elem);
+	(*(S->TransFunc[S->CurrState * S->NrMsg + Elem->MsgType - S->Base]))
+	    (pAd, Elem);
 }
 
 /*
@@ -5136,15 +5173,13 @@
 		StateMachinePerformAction()
 	==========================================================================
  */
-VOID Drop(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void Drop(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
 }
 
-// ===========================================================================================
-// lfsr.c
-// ===========================================================================================
+/* =========================================================================================== */
+/* lfsr.c */
+/* =========================================================================================== */
 
 /*
 	==========================================================================
@@ -5154,9 +5189,7 @@
 
 	==========================================================================
  */
-VOID LfsrInit(
-	IN PRTMP_ADAPTER pAd,
-	IN ULONG Seed)
+void LfsrInit(struct rt_rtmp_adapter *pAd, unsigned long Seed)
 {
 	if (Seed == 0)
 		pAd->Mlme.ShiftReg = 1;
@@ -5169,26 +5202,23 @@
 	Description:
 	==========================================================================
  */
-UCHAR RandomByte(
-	IN PRTMP_ADAPTER pAd)
+u8 RandomByte(struct rt_rtmp_adapter *pAd)
 {
-	ULONG i;
-	UCHAR R, Result;
+	unsigned long i;
+	u8 R, Result;
 
 	R = 0;
 
 	if (pAd->Mlme.ShiftReg == 0)
-	NdisGetSystemUpTime((ULONG *)&pAd->Mlme.ShiftReg);
+		NdisGetSystemUpTime((unsigned long *) & pAd->Mlme.ShiftReg);
 
-	for (i = 0; i < 8; i++)
-	{
-		if (pAd->Mlme.ShiftReg & 0x00000001)
-		{
-			pAd->Mlme.ShiftReg = ((pAd->Mlme.ShiftReg ^ LFSR_MASK) >> 1) | 0x80000000;
+	for (i = 0; i < 8; i++) {
+		if (pAd->Mlme.ShiftReg & 0x00000001) {
+			pAd->Mlme.ShiftReg =
+			    ((pAd->Mlme.
+			      ShiftReg ^ LFSR_MASK) >> 1) | 0x80000000;
 			Result = 1;
-		}
-		else
-		{
+		} else {
 			pAd->Mlme.ShiftReg = pAd->Mlme.ShiftReg >> 1;
 			Result = 0;
 		}
@@ -5198,2454 +5228,6 @@
 	return R;
 }
 
-VOID AsicUpdateAutoFallBackTable(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pRateTable)
-{
-	UCHAR					i;
-	HT_FBK_CFG0_STRUC		HtCfg0;
-	HT_FBK_CFG1_STRUC		HtCfg1;
-	LG_FBK_CFG0_STRUC		LgCfg0;
-	LG_FBK_CFG1_STRUC		LgCfg1;
-	PRTMP_TX_RATE_SWITCH	pCurrTxRate, pNextTxRate;
-
-	// set to initial value
-	HtCfg0.word = 0x65432100;
-	HtCfg1.word = 0xedcba988;
-	LgCfg0.word = 0xedcba988;
-	LgCfg1.word = 0x00002100;
-
-	pNextTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1;
-	for (i = 1; i < *((PUCHAR) pRateTable); i++)
-	{
-		pCurrTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1+i;
-		switch (pCurrTxRate->Mode)
-		{
-			case 0:		//CCK
-				break;
-			case 1:		//OFDM
-				{
-					switch(pCurrTxRate->CurrMCS)
-					{
-						case 0:
-							LgCfg0.field.OFDMMCS0FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
-							break;
-						case 1:
-							LgCfg0.field.OFDMMCS1FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
-							break;
-						case 2:
-							LgCfg0.field.OFDMMCS2FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
-							break;
-						case 3:
-							LgCfg0.field.OFDMMCS3FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
-							break;
-						case 4:
-							LgCfg0.field.OFDMMCS4FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
-							break;
-						case 5:
-							LgCfg0.field.OFDMMCS5FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
-							break;
-						case 6:
-							LgCfg0.field.OFDMMCS6FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
-							break;
-						case 7:
-							LgCfg0.field.OFDMMCS7FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
-							break;
-					}
-				}
-				break;
-			case 2:		//HT-MIX
-			case 3:		//HT-GF
-				{
-					if ((pNextTxRate->Mode >= MODE_HTMIX) && (pCurrTxRate->CurrMCS != pNextTxRate->CurrMCS))
-					{
-						switch(pCurrTxRate->CurrMCS)
-						{
-							case 0:
-								HtCfg0.field.HTMCS0FBK = pNextTxRate->CurrMCS;
-								break;
-							case 1:
-								HtCfg0.field.HTMCS1FBK = pNextTxRate->CurrMCS;
-								break;
-							case 2:
-								HtCfg0.field.HTMCS2FBK = pNextTxRate->CurrMCS;
-								break;
-							case 3:
-								HtCfg0.field.HTMCS3FBK = pNextTxRate->CurrMCS;
-								break;
-							case 4:
-								HtCfg0.field.HTMCS4FBK = pNextTxRate->CurrMCS;
-								break;
-							case 5:
-								HtCfg0.field.HTMCS5FBK = pNextTxRate->CurrMCS;
-								break;
-							case 6:
-								HtCfg0.field.HTMCS6FBK = pNextTxRate->CurrMCS;
-								break;
-							case 7:
-								HtCfg0.field.HTMCS7FBK = pNextTxRate->CurrMCS;
-								break;
-							case 8:
-								HtCfg1.field.HTMCS8FBK = pNextTxRate->CurrMCS;
-								break;
-							case 9:
-								HtCfg1.field.HTMCS9FBK = pNextTxRate->CurrMCS;
-								break;
-							case 10:
-								HtCfg1.field.HTMCS10FBK = pNextTxRate->CurrMCS;
-								break;
-							case 11:
-								HtCfg1.field.HTMCS11FBK = pNextTxRate->CurrMCS;
-								break;
-							case 12:
-								HtCfg1.field.HTMCS12FBK = pNextTxRate->CurrMCS;
-								break;
-							case 13:
-								HtCfg1.field.HTMCS13FBK = pNextTxRate->CurrMCS;
-								break;
-							case 14:
-								HtCfg1.field.HTMCS14FBK = pNextTxRate->CurrMCS;
-								break;
-							case 15:
-								HtCfg1.field.HTMCS15FBK = pNextTxRate->CurrMCS;
-								break;
-							default:
-								DBGPRINT(RT_DEBUG_ERROR, ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n", pCurrTxRate->CurrMCS));
-						}
-					}
-				}
-				break;
-		}
-
-		pNextTxRate = pCurrTxRate;
-	}
-
-	RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word);
-	RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word);
-	RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word);
-	RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word);
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Set MAC register value according operation mode.
-		OperationMode AND bNonGFExist are for MM and GF Proteciton.
-		If MM or GF mask is not set, those passing argument doesn't not take effect.
-
-		Operation mode meaning:
-		= 0 : Pure HT, no preotection.
-		= 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
-		= 0x10: No Transmission in 40M is protected.
-		= 0x11: Transmission in both 40M and 20M shall be protected
-		if (bNonGFExist)
-			we should choose not to use GF. But still set correct ASIC registers.
-	========================================================================
-*/
-VOID 	AsicUpdateProtect(
-	IN		PRTMP_ADAPTER	pAd,
-	IN 		USHORT			OperationMode,
-	IN 		UCHAR			SetMask,
-	IN		BOOLEAN			bDisableBGProtect,
-	IN		BOOLEAN			bNonGFExist)
-{
-	PROT_CFG_STRUC	ProtCfg, ProtCfg4;
-	UINT32 Protect[6];
-	USHORT			offset;
-	UCHAR			i;
-	UINT32 MacReg = 0;
-
-	if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8))
-	{
-		return;
-	}
-
-	if (pAd->BATable.numAsOriginator)
-	{
-		//
-		// enable the RTS/CTS to avoid channel collision
-		//
-		SetMask = ALLN_SETPROTECT;
-		OperationMode = 8;
-	}
-
-	// Config ASIC RTS threshold register
-	RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
-	MacReg &= 0xFF0000FF;
-
-	// If the user want disable RtsThreshold and enable Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
-        if ((
-			(pAd->CommonCfg.BACapability.field.AmsduEnable) ||
-			(pAd->CommonCfg.bAggregationCapable == TRUE))
-            && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD)
-        {
-			MacReg |= (0x1000 << 8);
-        }
-        else
-        {
-			MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
-        }
-
-	RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
-
-	// Initial common protection settings
-	RTMPZeroMemory(Protect, sizeof(Protect));
-	ProtCfg4.word = 0;
-	ProtCfg.word = 0;
-	ProtCfg.field.TxopAllowGF40 = 1;
-	ProtCfg.field.TxopAllowGF20 = 1;
-	ProtCfg.field.TxopAllowMM40 = 1;
-	ProtCfg.field.TxopAllowMM20 = 1;
-	ProtCfg.field.TxopAllowOfdm = 1;
-	ProtCfg.field.TxopAllowCck = 1;
-	ProtCfg.field.RTSThEn = 1;
-	ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
-
-	// update PHY mode and rate
-	if (pAd->CommonCfg.Channel > 14)
-		ProtCfg.field.ProtectRate = 0x4000;
-	ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate;
-
-	// Handle legacy(B/G) protection
-	if (bDisableBGProtect)
-	{
-		//ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
-		ProtCfg.field.ProtectCtrl = 0;
-		Protect[0] = ProtCfg.word;
-		Protect[1] = ProtCfg.word;
-	}
-	else
-	{
-		//ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
-		ProtCfg.field.ProtectCtrl = 0;			// CCK do not need to be protected
-		Protect[0] = ProtCfg.word;
-		ProtCfg.field.ProtectCtrl = ASIC_CTS;	// OFDM needs using CCK to protect
-		Protect[1] = ProtCfg.word;
-	}
-
-	// Decide HT frame protection.
-	if ((SetMask & ALLN_SETPROTECT) != 0)
-	{
-		switch(OperationMode)
-		{
-			case 0x0:
-				// NO PROTECT
-				// 1.All STAs in the BSS are 20/40 MHz HT
-				// 2. in ai 20/40MHz BSS
-				// 3. all STAs are 20MHz in a 20MHz BSS
-				// Pure HT. no protection.
-
-				// MM20_PROT_CFG
-				//	Reserved (31:27)
-				// 	PROT_TXOP(25:20) -- 010111
-				//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
-				//  PROT_CTRL(17:16) -- 00 (None)
-				// 	PROT_RATE(15:0)  -- 0x4004 (OFDM 24M)
-				Protect[2] = 0x01744004;
-
-				// MM40_PROT_CFG
-				//	Reserved (31:27)
-				// 	PROT_TXOP(25:20) -- 111111
-				//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
-				//  PROT_CTRL(17:16) -- 00 (None)
-				// 	PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M)
-				Protect[3] = 0x03f44084;
-
-				// CF20_PROT_CFG
-				//	Reserved (31:27)
-				// 	PROT_TXOP(25:20) -- 010111
-				//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
-				//  PROT_CTRL(17:16) -- 00 (None)
-				// 	PROT_RATE(15:0)  -- 0x4004 (OFDM 24M)
-				Protect[4] = 0x01744004;
-
-				// CF40_PROT_CFG
-				//	Reserved (31:27)
-				// 	PROT_TXOP(25:20) -- 111111
-				//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
-				//  PROT_CTRL(17:16) -- 00 (None)
-				// 	PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M)
-				Protect[5] = 0x03f44084;
-
-				if (bNonGFExist)
-				{
-					// PROT_NAV(19:18)  -- 01 (Short NAV protectiion)
-					// PROT_CTRL(17:16) -- 01 (RTS/CTS)
-					Protect[4] = 0x01754004;
-					Protect[5] = 0x03f54084;
-				}
-				pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
-				break;
-
- 			case 1:
-				// This is "HT non-member protection mode."
-				// If there may be non-HT STAs my BSS
-				ProtCfg.word = 0x01744004;	// PROT_CTRL(17:16) : 0 (None)
-				ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
-				if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
-				{
-					ProtCfg.word = 0x01740003;	//ERP use Protection bit is set, use protection rate at Clause 18..
-					ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083;
-				}
-				//Assign Protection method for 20&40 MHz packets
-				ProtCfg.field.ProtectCtrl = ASIC_RTS;
-				ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
-				ProtCfg4.field.ProtectCtrl = ASIC_RTS;
-				ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
-				Protect[2] = ProtCfg.word;
-				Protect[3] = ProtCfg4.word;
-				Protect[4] = ProtCfg.word;
-				Protect[5] = ProtCfg4.word;
-				pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
-				break;
-
-			case 2:
-				// If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets
-				ProtCfg.word = 0x01744004;  // PROT_CTRL(17:16) : 0 (None)
-				ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
-
-				//Assign Protection method for 40MHz packets
-				ProtCfg4.field.ProtectCtrl = ASIC_RTS;
-				ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
-				Protect[2] = ProtCfg.word;
-				Protect[3] = ProtCfg4.word;
-				if (bNonGFExist)
-				{
-					ProtCfg.field.ProtectCtrl = ASIC_RTS;
-					ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
-				}
-				Protect[4] = ProtCfg.word;
-				Protect[5] = ProtCfg4.word;
-
-				pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
-				break;
-
-			case 3:
-				// HT mixed mode.	 PROTECT ALL!
-				// Assign Rate
-				ProtCfg.word = 0x01744004;	//duplicaet legacy 24M. BW set 1.
-				ProtCfg4.word = 0x03f44084;
-				// both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the
-				if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
-				{
-					ProtCfg.word = 0x01740003;	//ERP use Protection bit is set, use protection rate at Clause 18..
-					ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083
-				}
-				//Assign Protection method for 20&40 MHz packets
-				ProtCfg.field.ProtectCtrl = ASIC_RTS;
-				ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
-				ProtCfg4.field.ProtectCtrl = ASIC_RTS;
-				ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
-				Protect[2] = ProtCfg.word;
-				Protect[3] = ProtCfg4.word;
-				Protect[4] = ProtCfg.word;
-				Protect[5] = ProtCfg4.word;
-				pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
-				break;
-
-			case 8:
-				// Special on for Atheros problem n chip.
-				Protect[2] = 0x01754004;
-				Protect[3] = 0x03f54084;
-				Protect[4] = 0x01754004;
-				Protect[5] = 0x03f54084;
-				pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
-				break;
-		}
-	}
-
-	offset = CCK_PROT_CFG;
-	for (i = 0;i < 6;i++)
-	{
-		if ((SetMask & (1<< i)))
-		{
-			RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
-		}
-	}
-}
-
-#ifdef RT2870
-/*
-	==========================================================================
-	Description:
-
-	Load RF normal operation-mode setup
-
-	==========================================================================
- */
-VOID RT30xxLoadRFNormalModeSetup(
-	IN PRTMP_ADAPTER 	pAd)
-{
-	UCHAR RFValue;
-
-	// RX0_PD & TX0_PD, RF R1 register Bit 2 & Bit 3 to 0 and RF_BLOCK_en,RX1_PD & TX1_PD, Bit0, Bit 4 & Bit5 to 1
-	RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
-	RFValue = (RFValue & (~0x0C)) | 0x31;
-	RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
-
-	// TX_LO2_en, RF R15 register Bit 3 to 0
-	RT30xxReadRFRegister(pAd, RF_R15, &RFValue);
-	RFValue &= (~0x08);
-	RT30xxWriteRFRegister(pAd, RF_R15, RFValue);
-
-	// TX_LO1_en, RF R17 register Bit 3 to 0
-	RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
-	RFValue &= (~0x08);
-	// to fix rx long range issue
-	if (((pAd->MACVersion & 0xffff) >= 0x0211) && (pAd->NicConfig2.field.ExternalLNAForG == 0))
-	{
-		RFValue |= 0x20;
-	}
-	RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
-
-	// RX_LO1_en, RF R20 register Bit 3 to 0
-	RT30xxReadRFRegister(pAd, RF_R20, &RFValue);
-	RFValue &= (~0x08);
-	RT30xxWriteRFRegister(pAd, RF_R20, RFValue);
-
-	// RX_LO2_en, RF R21 register Bit 3 to 0
-	RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
-	RFValue &= (~0x08);
-	RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
-
-	// LDORF_VC, RF R27 register Bit 2 to 0
-	RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
-	if ((pAd->MACVersion & 0xffff) < 0x0211)
-		RFValue = (RFValue & (~0x77)) | 0x3;
-	else
-		RFValue = (RFValue & (~0x77));
-	RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
-	/* end johnli */
-}
-
-/*
-	==========================================================================
-	Description:
-
-	Load RF sleep-mode setup
-
-	==========================================================================
- */
-VOID RT30xxLoadRFSleepModeSetup(
-	IN PRTMP_ADAPTER 	pAd)
-{
-	UCHAR RFValue;
-	UINT32 MACValue;
-
-	// RF_BLOCK_en. RF R1 register Bit 0 to 0
-	RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
-	RFValue &= (~0x01);
-	RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
-
-	// VCO_IC, RF R7 register Bit 4 & Bit 5 to 0
-	RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
-	RFValue &= (~0x30);
-	RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
-
-	// Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 0
-	RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
-	RFValue &= (~0x0E);
-	RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
-
-	// RX_CTB_en, RF R21 register Bit 7 to 0
-	RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
-	RFValue &= (~0x80);
-	RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
-
-	// LDORF_VC, RF R27 register Bit 0, Bit 1 & Bit 2 to 1
-	RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
-	RFValue |= 0x77;
-	RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
-
-	RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
-	MACValue |= 0x1D000000;
-	RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
-}
-
-/*
-	==========================================================================
-	Description:
-
-	Reverse RF sleep-mode setup
-
-	==========================================================================
- */
-VOID RT30xxReverseRFSleepModeSetup(
-	IN PRTMP_ADAPTER 	pAd)
-{
-	UCHAR RFValue;
-	UINT32 MACValue;
-
-	// RF_BLOCK_en, RF R1 register Bit 0 to 1
-	RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
-	RFValue |= 0x01;
-	RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
-
-	// VCO_IC, RF R7 register Bit 4 & Bit 5 to 1
-	RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
-	RFValue |= 0x30;
-	RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
-
-	// Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1
-	RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
-	RFValue |= 0x0E;
-	RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
-
-	// RX_CTB_en, RF R21 register Bit 7 to 1
-	RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
-	RFValue |= 0x80;
-	RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
-
-	// LDORF_VC, RF R27 register Bit 2 to 0
-	RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
-	if ((pAd->MACVersion & 0xffff) < 0x0211)
-		RFValue = (RFValue & (~0x77)) | 0x3;
-	else
-		RFValue = (RFValue & (~0x77));
-	RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
-
-	// RT3071 version E has fixed this issue
-	if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
-	{
-		// patch tx EVM issue temporarily
-		RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
-		MACValue = ((MACValue & 0xE0FFFFFF) | 0x0D000000);
-		RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
-	}
-	else
-	{
-		RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
-		MACValue = ((MACValue & 0xE0FFFFFF) | 0x01000000);
-		RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
-	}
-}
-#endif
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AsicSwitchChannel(
-					  IN PRTMP_ADAPTER pAd,
-	IN	UCHAR			Channel,
-	IN	BOOLEAN			bScan)
-{
-	ULONG			R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0;
-	CHAR    TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; //Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER;
-	UCHAR	index;
-	UINT32 	Value = 0; //BbpReg, Value;
-	RTMP_RF_REGS *RFRegTable;
-
-	// Search Tx power value
-	// We can't use ChannelList to search channel, since some central channl's txpowr doesn't list
-	// in ChannelList, so use TxPower array instead.
-	//
-	for (index = 0; index < MAX_NUM_OF_CHANNELS; index++)
-	{
-		if (Channel == pAd->TxPower[index].Channel)
-	{
-			TxPwer = pAd->TxPower[index].Power;
-			TxPwer2 = pAd->TxPower[index].Power2;
-			break;
-		}
-	}
-
-	if (index == MAX_NUM_OF_CHANNELS)
-		DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel));
-
-#ifdef RT2870
-	// The RF programming sequence is difference between 3xxx and 2xxx
-	if ((IS_RT3070(pAd) || IS_RT3090(pAd)) && (
-	     (pAd->RfIcType == RFIC_3022) || (pAd->RfIcType == RFIC_3021) ||
-	     (pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020)))
-	{
-		/* modify by WY for Read RF Reg. error */
-		UCHAR RFValue;
-
-		for (index = 0; index < NUM_OF_3020_CHNL; index++)
-		{
-			if (Channel == FreqItems3020[index].Channel)
-			{
-				// Programming channel parameters
-				RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N);
-				RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3020[index].K);
-
-				RT30xxReadRFRegister(pAd, RF_R06, &RFValue);
-				RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
-				RT30xxWriteRFRegister(pAd, RF_R06, RFValue);
-
-				// Set Tx0 Power
-				RT30xxReadRFRegister(pAd, RF_R12, &RFValue);
-				RFValue = (RFValue & 0xE0) | TxPwer;
-				RT30xxWriteRFRegister(pAd, RF_R12, RFValue);
-
-				// Set Tx1 Power
-				RT30xxReadRFRegister(pAd, RF_R13, &RFValue);
-				RFValue = (RFValue & 0xE0) | TxPwer2;
-				RT30xxWriteRFRegister(pAd, RF_R13, RFValue);
-
-				// Tx/Rx Stream setting
-				RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
-				//if (IS_RT3090(pAd))
-				//	RFValue |= 0x01; // Enable RF block.
-				RFValue &= 0x03;	//clear bit[7~2]
-				if (pAd->Antenna.field.TxPath == 1)
-					RFValue |= 0xA0;
-				else if (pAd->Antenna.field.TxPath == 2)
-					RFValue |= 0x80;
-				if (pAd->Antenna.field.RxPath == 1)
-					RFValue |= 0x50;
-				else if (pAd->Antenna.field.RxPath == 2)
-					RFValue |= 0x40;
-				RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
-
-				// Set RF offset
-				RT30xxReadRFRegister(pAd, RF_R23, &RFValue);
-				RFValue = (RFValue & 0x80) | pAd->RfFreqOffset;
-				RT30xxWriteRFRegister(pAd, RF_R23, RFValue);
-
-				// Set BW
-				if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
-				{
-					RFValue = pAd->Mlme.CaliBW40RfR24;
-					//DISABLE_11N_CHECK(pAd);
-				}
-				else
-				{
-					RFValue = pAd->Mlme.CaliBW20RfR24;
-				}
-				RT30xxWriteRFRegister(pAd, RF_R24, RFValue);
-				RT30xxWriteRFRegister(pAd, RF_R31, RFValue);
-
-				// Enable RF tuning
-				RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
-				RFValue = RFValue | 0x1;
-				RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
-
-				// latch channel for future usage.
-				pAd->LatchRfRegs.Channel = Channel;
-
-				DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
-					Channel,
-					pAd->RfIcType,
-					TxPwer,
-					TxPwer2,
-					pAd->Antenna.field.TxPath,
-					FreqItems3020[index].N,
-					FreqItems3020[index].K,
-					FreqItems3020[index].R));
-				break;
-			}
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
-			Channel,
-			pAd->RfIcType,
-			TxPwer,
-			TxPwer2,
-			pAd->Antenna.field.TxPath,
-			FreqItems3020[index].N,
-			FreqItems3020[index].K,
-			FreqItems3020[index].R));
-	}
-	else
-#endif // RT2870 //
-	{
-		RFRegTable = RF2850RegTable;
-
-		switch (pAd->RfIcType)
-		{
-			case RFIC_2820:
-			case RFIC_2850:
-			case RFIC_2720:
-			case RFIC_2750:
-
-			for (index = 0; index < NUM_OF_2850_CHNL; index++)
-			{
-				if (Channel == RFRegTable[index].Channel)
-				{
-					R2 = RFRegTable[index].R2;
-					if (pAd->Antenna.field.TxPath == 1)
-					{
-						R2 |= 0x4000;	// If TXpath is 1, bit 14 = 1;
-					}
-
-					if (pAd->Antenna.field.RxPath == 2)
-					{
-						R2 |= 0x40;	// write 1 to off Rxpath.
-					}
-					else if (pAd->Antenna.field.RxPath == 1)
-					{
-						R2 |= 0x20040;	// write 1 to off RxPath
-					}
-
-					if (Channel > 14)
-					{
-						// initialize R3, R4
-						R3 = (RFRegTable[index].R3 & 0xffffc1ff);
-						R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15);
-
-						// 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
-						// R3
-						if ((TxPwer >= -7) && (TxPwer < 0))
-						{
-							TxPwer = (7+TxPwer);
-							TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
-							R3 |= (TxPwer << 10);
-							DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer=%d \n", TxPwer));
-						}
-						else
-						{
-							TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
-							R3 |= (TxPwer << 10) | (1 << 9);
-						}
-
-						// R4
-						if ((TxPwer2 >= -7) && (TxPwer2 < 0))
-						{
-							TxPwer2 = (7+TxPwer2);
-							TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
-							R4 |= (TxPwer2 << 7);
-							DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer2=%d \n", TxPwer2));
-						}
-						else
-						{
-							TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
-							R4 |= (TxPwer2 << 7) | (1 << 6);
-						}
-					}
-					else
-					{
-						R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0
-					R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 <<6);// Set freq Offset & TxPwr1
-					}
-
-					// Based on BBP current mode before changing RF channel.
-					if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
-					{
-						R4 |=0x200000;
-					}
-
-					// Update variables
-					pAd->LatchRfRegs.Channel = Channel;
-					pAd->LatchRfRegs.R1 = RFRegTable[index].R1;
-					pAd->LatchRfRegs.R2 = R2;
-					pAd->LatchRfRegs.R3 = R3;
-					pAd->LatchRfRegs.R4 = R4;
-
-					// Set RF value 1's set R3[bit2] = [0]
-					RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
-					RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
-					RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
-					RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
-
-					RTMPusecDelay(200);
-
-					// Set RF value 2's set R3[bit2] = [1]
-					RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
-					RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
-					RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04));
-					RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
-
-					RTMPusecDelay(200);
-
-					// Set RF value 3's set R3[bit2] = [0]
-					RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
-					RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
-					RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
-					RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
-
-					break;
-				}
-			}
-			break;
-
-			default:
-			break;
-		}
-	}
-
-	// Change BBP setting during siwtch from a->g, g->a
-	if (Channel <= 14)
-	{
-	    ULONG	TxPinCfg = 0x00050F0A;//Gary 2007/08/09 0x050A0A
-
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);//(0x44 - GET_LNA_GAIN(pAd)));	// According the Rory's suggestion to solve the middle range issue.
-		//RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
-
-		// Rx High power VGA offset for LNA select
-	    if (pAd->NicConfig2.field.ExternalLNAForG)
-	    {
-	        RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
-	    }
-	    else
-	    {
-	        RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
-	    }
-
-		// 5G band selection PIN, bit1 and bit2 are complement
-		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
-		Value &= (~0x6);
-		Value |= (0x04);
-		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
-
-        // Turn off unused PA or LNA when only 1T or 1R
-		if (pAd->Antenna.field.TxPath == 1)
-		{
-			TxPinCfg &= 0xFFFFFFF3;
-		}
-		if (pAd->Antenna.field.RxPath == 1)
-		{
-			TxPinCfg &= 0xFFFFF3FF;
-		}
-
-		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
-	}
-	else
-	{
-	    ULONG	TxPinCfg = 0x00050F05;//Gary 2007/8/9 0x050505
-
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);//(0x44 - GET_LNA_GAIN(pAd)));   // According the Rory's suggestion to solve the middle range issue.
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
-
-		// Rx High power VGA offset for LNA select
-		if (pAd->NicConfig2.field.ExternalLNAForA)
-		{
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
-		}
-		else
-		{
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
-		}
-
-		// 5G band selection PIN, bit1 and bit2 are complement
-		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
-		Value &= (~0x6);
-		Value |= (0x02);
-		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
-
-        // Turn off unused PA or LNA when only 1T or 1R
-		if (pAd->Antenna.field.TxPath == 1)
-		{
-			TxPinCfg &= 0xFFFFFFF3;
-	}
-		if (pAd->Antenna.field.RxPath == 1)
-		{
-			TxPinCfg &= 0xFFFFF3FF;
-	}
-
-		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
-	}
-
-    // R66 should be set according to Channel and use 20MHz when scanning
-	//RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd)));
-	if (bScan)
-		RTMPSetAGCInitValue(pAd, BW_20);
-	else
-		RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
-
-	//
-	// On 11A, We should delay and wait RF/BBP to be stable
-	// and the appropriate time should be 1000 micro seconds
-	// 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
-	//
-	RTMPusecDelay(1000);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%lu, Pwr1=%lu, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
-							  Channel,
-							  pAd->RfIcType,
-							  (R3 & 0x00003e00) >> 9,
-							  (R4 & 0x000007c0) >> 6,
-							  pAd->Antenna.field.TxPath,
-							  pAd->LatchRfRegs.R1,
-							  pAd->LatchRfRegs.R2,
-							  pAd->LatchRfRegs.R3,
-							  pAd->LatchRfRegs.R4));
-}
-
-/*
-	==========================================================================
-	Description:
-		This function is required for 2421 only, and should not be used during
-		site survey. It's only required after NIC decided to stay at a channel
-		for a longer period.
-		When this function is called, it's always after AsicSwitchChannel().
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AsicLockChannel(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR Channel)
-{
-}
-
-VOID AsicRfTuningExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3)
-{
-}
-
-/*
-	==========================================================================
-	Description:
-		Gives CCK TX rate 2 more dB TX power.
-		This routine works only in LINK UP in INFRASTRUCTURE mode.
-
-		calculate desired Tx power in RF R3.Tx0~5,	should consider -
-		0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
-		1. TxPowerPercentage
-		2. auto calibration based on TSSI feedback
-		3. extra 2 db for CCK
-		4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
-
-	NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
-		it should be called AFTER MlmeDynamicTxRatSwitching()
-	==========================================================================
- */
-VOID AsicAdjustTxPower(
-	IN PRTMP_ADAPTER pAd)
-{
-	INT			i, j;
-	CHAR		DeltaPwr = 0;
-	BOOLEAN		bAutoTxAgc = FALSE;
-	UCHAR		TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
-	UCHAR		BbpR1 = 0, BbpR49 = 0, idx;
-	PCHAR		pTxAgcCompensate;
-	ULONG		TxPwr[5];
-	CHAR		Value;
-
-#ifdef RT2860
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
-		|| (pAd->bPCIclkOff == TRUE)
-		|| RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)
-		|| RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-		return;
-#endif
-
-	if (pAd->CommonCfg.BBPCurrentBW == BW_40)
-	{
-		if (pAd->CommonCfg.CentralChannel > 14)
-		{
-			TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
-			TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
-			TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
-			TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
-			TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
-		}
-		else
-		{
-			TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
-			TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
-			TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
-			TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
-			TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
-		}
-	}
-	else
-	{
-		if (pAd->CommonCfg.Channel > 14)
-		{
-			TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
-			TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
-			TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
-			TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
-			TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
-		}
-		else
-		{
-			TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
-			TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
-			TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
-			TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
-			TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
-		}
-	}
-
-	// TX power compensation for temperature variation based on TSSI. try every 4 second
-	if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
-	{
-		if (pAd->CommonCfg.Channel <= 14)
-		{
-			/* bg channel */
-			bAutoTxAgc         = pAd->bAutoTxAgcG;
-			TssiRef            = pAd->TssiRefG;
-			pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
-			pTssiPlusBoundary  = &pAd->TssiPlusBoundaryG[0];
-			TxAgcStep          = pAd->TxAgcStepG;
-			pTxAgcCompensate   = &pAd->TxAgcCompensateG;
-		}
-		else
-		{
-			/* a channel */
-			bAutoTxAgc         = pAd->bAutoTxAgcA;
-			TssiRef            = pAd->TssiRefA;
-			pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
-			pTssiPlusBoundary  = &pAd->TssiPlusBoundaryA[0];
-			TxAgcStep          = pAd->TxAgcStepA;
-			pTxAgcCompensate   = &pAd->TxAgcCompensateA;
-		}
-
-		if (bAutoTxAgc)
-		{
-			/* BbpR1 is unsigned char */
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
-
-			/* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
-			/* compensate: +4     +3   +2   +1    0   -1   -2   -3   -4 * steps */
-			/* step value is defined in pAd->TxAgcStepG for tx power value */
-
-			/* [4]+1+[4]   p4     p3   p2   p1   o1   m1   m2   m3   m4 */
-			/* ex:         0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
-			   above value are examined in mass factory production */
-			/*             [4]    [3]  [2]  [1]  [0]  [1]  [2]  [3]  [4] */
-
-			/* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
-			/* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
-			/* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
-
-			if (BbpR49 > pTssiMinusBoundary[1])
-			{
-				// Reading is larger than the reference value
-				// check for how large we need to decrease the Tx power
-				for (idx = 1; idx < 5; idx++)
-				{
-					if (BbpR49 <= pTssiMinusBoundary[idx])  // Found the range
-						break;
-				}
-				// The index is the step we should decrease, idx = 0 means there is nothing to compensate
-				*pTxAgcCompensate = -(TxAgcStep * (idx-1));
-
-				DeltaPwr += (*pTxAgcCompensate);
-				DBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
-					BbpR49, TssiRef, TxAgcStep, idx-1));
-			}
-			else if (BbpR49 < pTssiPlusBoundary[1])
-			{
-				// Reading is smaller than the reference value
-				// check for how large we need to increase the Tx power
-				for (idx = 1; idx < 5; idx++)
-				{
-					if (BbpR49 >= pTssiPlusBoundary[idx])   // Found the range
-						break;
-				}
-				// The index is the step we should increase, idx = 0 means there is nothing to compensate
-				*pTxAgcCompensate = TxAgcStep * (idx-1);
-				DeltaPwr += (*pTxAgcCompensate);
-				DBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
-					BbpR49, TssiRef, TxAgcStep, idx-1));
-			}
-			else
-			{
-				*pTxAgcCompensate = 0;
-				DBGPRINT(RT_DEBUG_TRACE, ("   Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
-					BbpR49, TssiRef, TxAgcStep, 0));
-			}
-		}
-	}
-	else
-	{
-		if (pAd->CommonCfg.Channel <= 14)
-		{
-			bAutoTxAgc         = pAd->bAutoTxAgcG;
-			pTxAgcCompensate   = &pAd->TxAgcCompensateG;
-		}
-		else
-		{
-			bAutoTxAgc         = pAd->bAutoTxAgcA;
-			pTxAgcCompensate   = &pAd->TxAgcCompensateA;
-		}
-
-		if (bAutoTxAgc)
-			DeltaPwr += (*pTxAgcCompensate);
-	}
-
-	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1);
-	BbpR1 &= 0xFC;
-
-	/* calculate delta power based on the percentage specified from UI */
-	// E2PROM setting is calibrated for maximum TX power (i.e. 100%)
-	// We lower TX power here according to the percentage specified from UI
-	if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff)       // AUTO TX POWER control
-		;
-	else if (pAd->CommonCfg.TxPowerPercentage > 90)  // 91 ~ 100% & AUTO, treat as 100% in terms of mW
-		;
-	else if (pAd->CommonCfg.TxPowerPercentage > 60)  // 61 ~ 90%, treat as 75% in terms of mW		// DeltaPwr -= 1;
-	{
-		DeltaPwr -= 1;
-	}
-	else if (pAd->CommonCfg.TxPowerPercentage > 30)  // 31 ~ 60%, treat as 50% in terms of mW		// DeltaPwr -= 3;
-	{
-		DeltaPwr -= 3;
-	}
-	else if (pAd->CommonCfg.TxPowerPercentage > 15)  // 16 ~ 30%, treat as 25% in terms of mW		// DeltaPwr -= 6;
-	{
-		BbpR1 |= 0x01;
-	}
-	else if (pAd->CommonCfg.TxPowerPercentage > 9)   // 10 ~ 15%, treat as 12.5% in terms of mW		// DeltaPwr -= 9;
-	{
-		BbpR1 |= 0x01;
-		DeltaPwr -= 3;
-	}
-	else                                           // 0 ~ 9 %, treat as MIN(~3%) in terms of mW		// DeltaPwr -= 12;
-	{
-		BbpR1 |= 0x02;
-	}
-
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
-
-	/* reset different new tx power for different TX rate */
-	for(i=0; i<5; i++)
-	{
-		if (TxPwr[i] != 0xffffffff)
-		{
-			for (j=0; j<8; j++)
-			{
-				Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */
-
-				if ((Value + DeltaPwr) < 0)
-				{
-					Value = 0; /* min */
-				}
-				else if ((Value + DeltaPwr) > 0xF)
-				{
-					Value = 0xF; /* max */
-				}
-				else
-				{
-					Value += DeltaPwr; /* temperature compensation */
-				}
-
-				/* fill new value to CSR offset */
-				TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
-			}
-
-			/* write tx power value to CSR */
-			/* TX_PWR_CFG_0 (8 tx rate) for	TX power for OFDM 12M/18M
-											TX power for OFDM 6M/9M
-											TX power for CCK5.5M/11M
-											TX power for CCK1M/2M */
-			/* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
-			RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);
-		}
-	}
-
-}
-
-/*
-	==========================================================================
-	Description:
-		put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup
-		automatically. Instead, MCU will issue a TwakeUpInterrupt to host after
-		the wakeup timer timeout. Driver has to issue a separate command to wake
-		PHY up.
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AsicSleepThenAutoWakeup(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT TbttNumToNextWakeUp)
-{
-    RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp);
-}
-
-/*
-	==========================================================================
-	Description:
-		AsicForceWakeup() is used whenever manual wakeup is required
-		AsicForceSleep() should only be used when not in INFRA BSS. When
-		in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead.
-	==========================================================================
- */
-VOID AsicForceSleep(
-	IN PRTMP_ADAPTER pAd)
-{
-
-}
-
-/*
-	==========================================================================
-	Description:
-		AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
-		expired.
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-	==========================================================================
- */
-VOID AsicForceWakeup(
-	IN PRTMP_ADAPTER pAd,
-#ifdef RT2860
-	IN UCHAR    	 Level)
-#endif
-#ifdef RT2870
-	IN BOOLEAN    bFromTx)
-#endif
-{
-    DBGPRINT(RT_DEBUG_TRACE, ("--> AsicForceWakeup \n"));
-#ifdef RT2860
-    RT28XX_STA_FORCE_WAKEUP(pAd, Level);
-#endif
-#ifdef RT2870
-    RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx);
-#endif
-}
-
-/*
-	==========================================================================
-	Description:
-		Set My BSSID
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AsicSetBssid(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pBssid)
-{
-	ULONG		  Addr4;
-	DBGPRINT(RT_DEBUG_TRACE, ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n",
-		pBssid[0],pBssid[1],pBssid[2],pBssid[3], pBssid[4],pBssid[5]));
-
-	Addr4 = (ULONG)(pBssid[0])		 |
-			(ULONG)(pBssid[1] << 8)  |
-			(ULONG)(pBssid[2] << 16) |
-			(ULONG)(pBssid[3] << 24);
-	RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
-
-	Addr4 = 0;
-	// always one BSSID in STA mode
-	Addr4 = (ULONG)(pBssid[4]) | (ULONG)(pBssid[5] << 8);
-
-	RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
-}
-
-VOID AsicSetMcastWC(
-	IN PRTMP_ADAPTER pAd)
-{
-	MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[MCAST_WCID];
-	USHORT		offset;
-
-	pEntry->Sst        = SST_ASSOC;
-	pEntry->Aid        = MCAST_WCID;	// Softap supports 1 BSSID and use WCID=0 as multicast Wcid index
-	pEntry->PsMode     = PWR_ACTIVE;
-	pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate;
-	offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE;
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AsicDelWcidTab(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR	Wcid)
-{
-	ULONG		  Addr0 = 0x0, Addr1 = 0x0;
-	ULONG 		offset;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n",Wcid));
-	offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE;
-	RTMP_IO_WRITE32(pAd, offset, Addr0);
-	offset += 4;
-	RTMP_IO_WRITE32(pAd, offset, Addr1);
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AsicEnableRDG(
-	IN PRTMP_ADAPTER pAd)
-{
-	TX_LINK_CFG_STRUC	TxLinkCfg;
-	UINT32				Data = 0;
-
-	RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
-	TxLinkCfg.field.TxRDGEn = 1;
-	RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
-
-	RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
-	Data  &= 0xFFFFFF00;
-	Data  |= 0x80;
-	RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
-
-	//OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AsicDisableRDG(
-	IN PRTMP_ADAPTER pAd)
-{
-	TX_LINK_CFG_STRUC	TxLinkCfg;
-	UINT32				Data = 0;
-
-
-	RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
-	TxLinkCfg.field.TxRDGEn = 0;
-	RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
-
-	RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
-
-	Data  &= 0xFFFFFF00;
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)
-		&& (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE)
-	)
-	{
-		// For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
-		if (pAd->CommonCfg.bEnableTxBurst)
-			Data |= 0x20;
-	}
-	RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AsicDisableSync(
-	IN PRTMP_ADAPTER pAd)
-{
-	BCN_TIME_CFG_STRUC csr;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n"));
-
-	// 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect
-	//			  that NIC will never wakes up because TSF stops and no more
-	//			  TBTT interrupts
-	pAd->TbttTickCount = 0;
-	RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
-	csr.field.bBeaconGen = 0;
-	csr.field.bTBTTEnable = 0;
-	csr.field.TsfSyncMode = 0;
-	csr.field.bTsfTicking = 0;
-	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
-
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AsicEnableBssSync(
-	IN PRTMP_ADAPTER pAd)
-{
-	BCN_TIME_CFG_STRUC csr;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n"));
-
-	RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
-
-	{
-		csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
-		csr.field.bTsfTicking = 1;
-		csr.field.TsfSyncMode = 1; // sync TSF in INFRASTRUCTURE mode
-		csr.field.bBeaconGen  = 0; // do NOT generate BEACON
-		csr.field.bTBTTEnable = 1;
-	}
-
-	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
-}
-
-/*
-	==========================================================================
-	Description:
-	Note:
-		BEACON frame in shared memory should be built ok before this routine
-		can be called. Otherwise, a garbage frame maybe transmitted out every
-		Beacon period.
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AsicEnableIbssSync(
-	IN PRTMP_ADAPTER pAd)
-{
-	BCN_TIME_CFG_STRUC csr9;
-	PUCHAR			ptr;
-	UINT i;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", pAd->BeaconTxWI.MPDUtotalByteCount));
-
-	RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
-	csr9.field.bBeaconGen = 0;
-	csr9.field.bTBTTEnable = 0;
-	csr9.field.bTsfTicking = 0;
-	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
-
-#ifdef RT2860
-	// move BEACON TXD and frame content to on-chip memory
-	ptr = (PUCHAR)&pAd->BeaconTxWI;
-	for (i=0; i<TXWI_SIZE; i+=4)  // 16-byte TXWI field
-	{
-		UINT32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
-		RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
-		ptr += 4;
-	}
-
-	// start right after the 16-byte TXWI field
-	ptr = pAd->BeaconBuf;
-	for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=4)
-	{
-		UINT32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
-		RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
-		ptr +=4;
-	}
-#endif
-#ifdef RT2870
-	// move BEACON TXD and frame content to on-chip memory
-	ptr = (PUCHAR)&pAd->BeaconTxWI;
-	for (i=0; i<TXWI_SIZE; i+=2)  // 16-byte TXWI field
-	{
-		RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + i, ptr, 2);
-		ptr += 2;
-	}
-
-	// start right after the 16-byte TXWI field
-	ptr = pAd->BeaconBuf;
-	for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=2)
-	{
-		RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, ptr, 2);
-		ptr +=2;
-	}
-#endif // RT2870 //
-
-	// start sending BEACON
-	csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
-	csr9.field.bTsfTicking = 1;
-	csr9.field.TsfSyncMode = 2; // sync TSF in IBSS mode
-	csr9.field.bTBTTEnable = 1;
-	csr9.field.bBeaconGen = 1;
-	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AsicSetEdcaParm(
-	IN PRTMP_ADAPTER pAd,
-	IN PEDCA_PARM	 pEdcaParm)
-{
-	EDCA_AC_CFG_STRUC   Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg;
-	AC_TXOP_CSR0_STRUC csr0;
-	AC_TXOP_CSR1_STRUC csr1;
-	AIFSN_CSR_STRUC    AifsnCsr;
-	CWMIN_CSR_STRUC    CwminCsr;
-	CWMAX_CSR_STRUC    CwmaxCsr;
-	int i;
-
-	Ac0Cfg.word = 0;
-	Ac1Cfg.word = 0;
-	Ac2Cfg.word = 0;
-	Ac3Cfg.word = 0;
-	if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE))
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("AsicSetEdcaParm\n"));
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED);
-		for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
-		{
-			if (pAd->MacTab.Content[i].ValidAsCLI || pAd->MacTab.Content[i].ValidAsApCli)
-				CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[i], fCLIENT_STATUS_WMM_CAPABLE);
-		}
-
-		//========================================================
-		//      MAC Register has a copy .
-		//========================================================
-		if( pAd->CommonCfg.bEnableTxBurst )
-		{
-			// For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
-			Ac0Cfg.field.AcTxop = 0x20; // Suggest by John for TxBurst in HT Mode
-		}
-		else
-			Ac0Cfg.field.AcTxop = 0;	// QID_AC_BE
-		Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS;
-		Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS;
-		Ac0Cfg.field.Aifsn = 2;
-		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
-
-		Ac1Cfg.field.AcTxop = 0;	// QID_AC_BK
-		Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS;
-		Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS;
-		Ac1Cfg.field.Aifsn = 2;
-		RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
-
-		if (pAd->CommonCfg.PhyMode == PHY_11B)
-		{
-			Ac2Cfg.field.AcTxop = 192;	// AC_VI: 192*32us ~= 6ms
-			Ac3Cfg.field.AcTxop = 96;	// AC_VO: 96*32us  ~= 3ms
-		}
-		else
-		{
-			Ac2Cfg.field.AcTxop = 96;	// AC_VI: 96*32us ~= 3ms
-			Ac3Cfg.field.AcTxop = 48;	// AC_VO: 48*32us ~= 1.5ms
-		}
-		Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS;
-		Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS;
-		Ac2Cfg.field.Aifsn = 2;
-		RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
-		Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS;
-		Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS;
-		Ac3Cfg.field.Aifsn = 2;
-		RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
-
-		//========================================================
-		//      DMA Register has a copy too.
-		//========================================================
-		csr0.field.Ac0Txop = 0;		// QID_AC_BE
-		csr0.field.Ac1Txop = 0;		// QID_AC_BK
-		RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
-		if (pAd->CommonCfg.PhyMode == PHY_11B)
-		{
-			csr1.field.Ac2Txop = 192;		// AC_VI: 192*32us ~= 6ms
-			csr1.field.Ac3Txop = 96;		// AC_VO: 96*32us  ~= 3ms
-		}
-		else
-		{
-			csr1.field.Ac2Txop = 96;		// AC_VI: 96*32us ~= 3ms
-			csr1.field.Ac3Txop = 48;		// AC_VO: 48*32us ~= 1.5ms
-		}
-		RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
-
-		CwminCsr.word = 0;
-		CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS;
-		CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS;
-		CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS;
-		CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS;
-		RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
-
-		CwmaxCsr.word = 0;
-		CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS;
-		CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS;
-		CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS;
-		CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS;
-		RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
-
-		RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222);
-
-		NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(EDCA_PARM));
-	}
-	else
-	{
-		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED);
-		//========================================================
-		//      MAC Register has a copy.
-		//========================================================
-		//
-		// Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27
-		// To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue.
-		//
-		//pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this
-
-		Ac0Cfg.field.AcTxop =  pEdcaParm->Txop[QID_AC_BE];
-		Ac0Cfg.field.Cwmin= pEdcaParm->Cwmin[QID_AC_BE];
-		Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE];
-		Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]; //+1;
-
-		Ac1Cfg.field.AcTxop =  pEdcaParm->Txop[QID_AC_BK];
-		Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK]; //+2;
-		Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK];
-		Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; //+1;
-
-		Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10;
-		Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI];
-		Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI];
-		Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI];
-
-		{
-			// Tuning for Wi-Fi WMM S06
-			if (pAd->CommonCfg.bWiFiTest &&
-				pEdcaParm->Aifsn[QID_AC_VI] == 10)
-				Ac2Cfg.field.Aifsn -= 1;
-
-			// Tuning for TGn Wi-Fi 5.2.32
-			// STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta
-			if (STA_TGN_WIFI_ON(pAd) &&
-				pEdcaParm->Aifsn[QID_AC_VI] == 10)
-			{
-				Ac0Cfg.field.Aifsn = 3;
-				Ac2Cfg.field.AcTxop = 5;
-			}
-
-#ifdef RT2870
-			if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
-			{
-				// Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta.
-				Ac2Cfg.field.Aifsn = 5;
-			}
-#endif
-		}
-
-		Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO];
-		Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO];
-		Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO];
-		Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO];
-
-//#ifdef WIFI_TEST
-		if (pAd->CommonCfg.bWiFiTest)
-		{
-			if (Ac3Cfg.field.AcTxop == 102)
-			{
-			Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->Txop[QID_AC_BE] : 10;
-				Ac0Cfg.field.Aifsn  = pEdcaParm->Aifsn[QID_AC_BE]-1; /* AIFSN must >= 1 */
-			Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
-				Ac1Cfg.field.Aifsn  = pEdcaParm->Aifsn[QID_AC_BK];
-			Ac2Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VI];
-			} /* End of if */
-		}
-//#endif // WIFI_TEST //
-
-		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
-		RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
-		RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
-		RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
-
-
-		//========================================================
-		//      DMA Register has a copy too.
-		//========================================================
-		csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop;
-		csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop;
-		RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
-
-		csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop;
-		csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop;
-		RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
-
-		CwminCsr.word = 0;
-		CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE];
-		CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK];
-		CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI];
-
-		CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1; //for TGn wifi test
-
-		RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
-
-		CwmaxCsr.word = 0;
-		CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE];
-		CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK];
-		CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI];
-		CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO];
-		RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
-
-		AifsnCsr.word = 0;
-		AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BE];
-		AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BK];
-		AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_VI];
-
-		{
-			// Tuning for Wi-Fi WMM S06
-			if (pAd->CommonCfg.bWiFiTest &&
-				pEdcaParm->Aifsn[QID_AC_VI] == 10)
-				AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4;
-
-			// Tuning for TGn Wi-Fi 5.2.32
-			// STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta
-			if (STA_TGN_WIFI_ON(pAd) &&
-				pEdcaParm->Aifsn[QID_AC_VI] == 10)
-			{
-				AifsnCsr.field.Aifsn0 = 3;
-				AifsnCsr.field.Aifsn2 = 7;
-			}
-#ifdef RT2870
-			if (INFRA_ON(pAd))
-				CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_WMM_CAPABLE);
-#endif
-		}
-
-		AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test
-#ifdef RT2870
-		if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
-			AifsnCsr.field.Aifsn2 = 0x2; //pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04.
-#endif
-		RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
-
-		NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
-		if (!ADHOC_ON(pAd))
-		{
-			DBGPRINT(RT_DEBUG_TRACE,("EDCA [#%d]: AIFSN CWmin CWmax  TXOP(us)  ACM\n", pEdcaParm->EdcaUpdateCount));
-			DBGPRINT(RT_DEBUG_TRACE,("     AC_BE      %2d     %2d     %2d      %4d     %d\n",
-									 pEdcaParm->Aifsn[0],
-									 pEdcaParm->Cwmin[0],
-									 pEdcaParm->Cwmax[0],
-									 pEdcaParm->Txop[0]<<5,
-									 pEdcaParm->bACM[0]));
-			DBGPRINT(RT_DEBUG_TRACE,("     AC_BK      %2d     %2d     %2d      %4d     %d\n",
-									 pEdcaParm->Aifsn[1],
-									 pEdcaParm->Cwmin[1],
-									 pEdcaParm->Cwmax[1],
-									 pEdcaParm->Txop[1]<<5,
-									 pEdcaParm->bACM[1]));
-			DBGPRINT(RT_DEBUG_TRACE,("     AC_VI      %2d     %2d     %2d      %4d     %d\n",
-									 pEdcaParm->Aifsn[2],
-									 pEdcaParm->Cwmin[2],
-									 pEdcaParm->Cwmax[2],
-									 pEdcaParm->Txop[2]<<5,
-									 pEdcaParm->bACM[2]));
-			DBGPRINT(RT_DEBUG_TRACE,("     AC_VO      %2d     %2d     %2d      %4d     %d\n",
-									 pEdcaParm->Aifsn[3],
-									 pEdcaParm->Cwmin[3],
-									 pEdcaParm->Cwmax[3],
-									 pEdcaParm->Txop[3]<<5,
-									 pEdcaParm->bACM[3]));
-		}
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID 	AsicSetSlotTime(
-	IN PRTMP_ADAPTER pAd,
-	IN BOOLEAN bUseShortSlotTime)
-{
-	ULONG	SlotTime;
-	UINT32	RegValue = 0;
-
-	if (pAd->CommonCfg.Channel > 14)
-		bUseShortSlotTime = TRUE;
-
-	if (bUseShortSlotTime)
-		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
-	else
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
-
-	SlotTime = (bUseShortSlotTime)? 9 : 20;
-
-	{
-		// force using short SLOT time for FAE to demo performance when TxBurst is ON
-		if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
-			|| ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))
-			)
-		{
-			// In this case, we will think it is doing Wi-Fi test
-			// And we will not set to short slot when bEnableTxBurst is TRUE.
-		}
-		else if (pAd->CommonCfg.bEnableTxBurst)
-			SlotTime = 9;
-	}
-
-	//
-	// For some reasons, always set it to short slot time.
-	//
-	// ToDo: Should consider capability with 11B
-	//
-	if (pAd->StaCfg.BssType == BSS_ADHOC)
-		SlotTime = 20;
-
-	RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
-	RegValue = RegValue & 0xFFFFFF00;
-
-	RegValue |= SlotTime;
-
-	RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue);
-}
-
-/*
-	========================================================================
-	Description:
-		Add Shared key information into ASIC.
-		Update shared key, TxMic and RxMic to Asic Shared key table
-		Update its cipherAlg to Asic Shared key Mode.
-
-    Return:
-	========================================================================
-*/
-VOID AsicAddSharedKeyEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR		 BssIndex,
-	IN UCHAR		 KeyIdx,
-	IN UCHAR		 CipherAlg,
-	IN PUCHAR		 pKey,
-	IN PUCHAR		 pTxMic,
-	IN PUCHAR		 pRxMic)
-{
-	ULONG offset; //, csr0;
-	SHAREDKEY_MODE_STRUC csr1;
-#ifdef RT2860
-	INT   i;
-#endif
-
-	DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx));
-//============================================================================================
-
-	DBGPRINT(RT_DEBUG_TRACE,("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg], BssIndex*4 + KeyIdx));
-	DBGPRINT_RAW(RT_DEBUG_TRACE, (" 	Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-		pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15]));
-	if (pRxMic)
-	{
-		DBGPRINT_RAW(RT_DEBUG_TRACE, (" 	Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-			pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
-	}
-	if (pTxMic)
-	{
-		DBGPRINT_RAW(RT_DEBUG_TRACE, (" 	Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-			pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
-	}
-//============================================================================================
-	//
-	// fill key material - key + TX MIC + RX MIC
-	//
-
-	offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
-#ifdef RT2860
-	for (i=0; i<MAX_LEN_OF_SHARE_KEY; i++)
-	{
-		RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
-	}
-#endif
-#ifdef RT2870
-	RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_SHARE_KEY);
-#endif
-	offset += MAX_LEN_OF_SHARE_KEY;
-	if (pTxMic)
-	{
-#ifdef RT2860
-		for (i=0; i<8; i++)
-		{
-			RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
-		}
-#endif
-#ifdef RT2870
-		RTUSBMultiWrite(pAd, offset, pTxMic, 8);
-#endif
-	}
-
-	offset += 8;
-	if (pRxMic)
-	{
-#ifdef RT2860
-		for (i=0; i<8; i++)
-		{
-			RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
-		}
-#endif
-#ifdef RT2870
-		RTUSBMultiWrite(pAd, offset, pRxMic, 8);
-#endif
-	}
-
-
-	//
-	// Update cipher algorithm. WSTA always use BSS0
-	//
-	RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
-	DBGPRINT(RT_DEBUG_TRACE,("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n", BssIndex,KeyIdx, csr1.word));
-	if ((BssIndex%2) == 0)
-	{
-		if (KeyIdx == 0)
-			csr1.field.Bss0Key0CipherAlg = CipherAlg;
-		else if (KeyIdx == 1)
-			csr1.field.Bss0Key1CipherAlg = CipherAlg;
-		else if (KeyIdx == 2)
-			csr1.field.Bss0Key2CipherAlg = CipherAlg;
-		else
-			csr1.field.Bss0Key3CipherAlg = CipherAlg;
-	}
-	else
-	{
-		if (KeyIdx == 0)
-			csr1.field.Bss1Key0CipherAlg = CipherAlg;
-		else if (KeyIdx == 1)
-			csr1.field.Bss1Key1CipherAlg = CipherAlg;
-		else if (KeyIdx == 2)
-			csr1.field.Bss1Key2CipherAlg = CipherAlg;
-		else
-			csr1.field.Bss1Key3CipherAlg = CipherAlg;
-	}
-	DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
-	RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
-
-}
-
-//	IRQL = DISPATCH_LEVEL
-VOID AsicRemoveSharedKeyEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR		 BssIndex,
-	IN UCHAR		 KeyIdx)
-{
-	//ULONG SecCsr0;
-	SHAREDKEY_MODE_STRUC csr1;
-
-	DBGPRINT(RT_DEBUG_TRACE,("AsicRemoveSharedKeyEntry: #%d \n", BssIndex*4 + KeyIdx));
-
-	RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
-	if ((BssIndex%2) == 0)
-	{
-		if (KeyIdx == 0)
-			csr1.field.Bss0Key0CipherAlg = 0;
-		else if (KeyIdx == 1)
-			csr1.field.Bss0Key1CipherAlg = 0;
-		else if (KeyIdx == 2)
-			csr1.field.Bss0Key2CipherAlg = 0;
-		else
-			csr1.field.Bss0Key3CipherAlg = 0;
-	}
-	else
-	{
-		if (KeyIdx == 0)
-			csr1.field.Bss1Key0CipherAlg = 0;
-		else if (KeyIdx == 1)
-			csr1.field.Bss1Key1CipherAlg = 0;
-		else if (KeyIdx == 2)
-			csr1.field.Bss1Key2CipherAlg = 0;
-		else
-			csr1.field.Bss1Key3CipherAlg = 0;
-	}
-	DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
-	RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
-	ASSERT(BssIndex < 4);
-	ASSERT(KeyIdx < 4);
-
-}
-
-
-VOID AsicUpdateWCIDAttribute(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT		WCID,
-	IN UCHAR		BssIndex,
-	IN UCHAR        CipherAlg,
-	IN BOOLEAN		bUsePairewiseKeyTable)
-{
-	ULONG   WCIDAttri = 0, offset;
-
-	//
-	// Update WCID attribute.
-	// Only TxKey could update WCID attribute.
-	//
-	offset = MAC_WCID_ATTRIBUTE_BASE + (WCID * HW_WCID_ATTRI_SIZE);
-	WCIDAttri = (BssIndex << 4) | (CipherAlg << 1) | (bUsePairewiseKeyTable);
-	RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
-}
-
-VOID AsicUpdateWCIDIVEIV(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT		WCID,
-	IN ULONG        uIV,
-	IN ULONG        uEIV)
-{
-	ULONG	offset;
-
-	offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
-
-	RTMP_IO_WRITE32(pAd, offset, uIV);
-	RTMP_IO_WRITE32(pAd, offset + 4, uEIV);
-}
-
-VOID AsicUpdateRxWCIDTable(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT		WCID,
-	IN PUCHAR        pAddr)
-{
-	ULONG offset;
-	ULONG Addr;
-
-	offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE);
-	Addr = pAddr[0] + (pAddr[1] << 8) +(pAddr[2] << 16) +(pAddr[3] << 24);
-	RTMP_IO_WRITE32(pAd, offset, Addr);
-	Addr = pAddr[4] + (pAddr[5] << 8);
-	RTMP_IO_WRITE32(pAd, offset + 4, Addr);
-}
-
-
-/*
-    ========================================================================
-
-    Routine Description:
-        Set Cipher Key, Cipher algorithm, IV/EIV to Asic
-
-    Arguments:
-        pAd                     Pointer to our adapter
-        WCID                    WCID Entry number.
-        BssIndex                BSSID index, station or none multiple BSSID support
-                                this value should be 0.
-        KeyIdx                  This KeyIdx will set to IV's KeyID if bTxKey enabled
-        pCipherKey              Pointer to Cipher Key.
-        bUsePairewiseKeyTable   TRUE means saved the key in SharedKey table,
-                                otherwise PairewiseKey table
-        bTxKey                  This is the transmit key if enabled.
-
-    Return Value:
-        None
-
-    Note:
-        This routine will set the relative key stuff to Asic including WCID attribute,
-        Cipher Key, Cipher algorithm and IV/EIV.
-
-        IV/EIV will be update if this CipherKey is the transmission key because
-        ASIC will base on IV's KeyID value to select Cipher Key.
-
-        If bTxKey sets to FALSE, this is not the TX key, but it could be
-        RX key
-
-    	For AP mode bTxKey must be always set to TRUE.
-    ========================================================================
-*/
-VOID AsicAddKeyEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT		WCID,
-	IN UCHAR		BssIndex,
-	IN UCHAR		KeyIdx,
-	IN PCIPHER_KEY	pCipherKey,
-	IN BOOLEAN		bUsePairewiseKeyTable,
-	IN BOOLEAN		bTxKey)
-{
-	ULONG	offset;
-	UCHAR	IV4 = 0;
-	PUCHAR		pKey = pCipherKey->Key;
-	PUCHAR		pTxMic = pCipherKey->TxMic;
-	PUCHAR		pRxMic = pCipherKey->RxMic;
-	PUCHAR		pTxtsc = pCipherKey->TxTsc;
-	UCHAR		CipherAlg = pCipherKey->CipherAlg;
-	SHAREDKEY_MODE_STRUC csr1;
-#ifdef RT2860
-	UCHAR		i;
-#endif
-
-	DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
-	//
-	// 1.) decide key table offset
-	//
-	if (bUsePairewiseKeyTable)
-		offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
-	else
-		offset = SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE;
-
-	//
-	// 2.) Set Key to Asic
-	//
-	//for (i = 0; i < KeyLen; i++)
-#ifdef RT2860
-	for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++)
-	{
-		RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
-	}
-#endif
-#ifdef RT2870
-	RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_PEER_KEY);
-#endif
-	offset += MAX_LEN_OF_PEER_KEY;
-
-	//
-	// 3.) Set MIC key if available
-	//
-	if (pTxMic)
-	{
-#ifdef RT2860
-		for (i = 0; i < 8; i++)
-		{
-			RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
-		}
-#endif
-#ifdef RT2870
-		RTUSBMultiWrite(pAd, offset, pTxMic, 8);
-#endif
-	}
-	offset += LEN_TKIP_TXMICK;
-
-	if (pRxMic)
-	{
-#ifdef RT2860
-		for (i = 0; i < 8; i++)
-		{
-			RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
-		}
-#endif
-#ifdef RT2870
-		RTUSBMultiWrite(pAd, offset, pRxMic, 8);
-#endif
-	}
-
-
-	//
-	// 4.) Modify IV/EIV if needs
-	//     This will force Asic to use this key ID by setting IV.
-	//
-	if (bTxKey)
-	{
-#ifdef RT2860
-		offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
-		//
-		// Write IV
-		//
-		RTMP_IO_WRITE8(pAd, offset, pTxtsc[1]);
-		RTMP_IO_WRITE8(pAd, offset + 1, ((pTxtsc[1] | 0x20) & 0x7f));
-		RTMP_IO_WRITE8(pAd, offset + 2, pTxtsc[0]);
-
-		IV4 = (KeyIdx << 6);
-		if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
-			IV4 |= 0x20;  // turn on extension bit means EIV existence
-
-		RTMP_IO_WRITE8(pAd, offset + 3, IV4);
-
-		//
-		// Write EIV
-		//
-		offset += 4;
-		for (i = 0; i < 4; i++)
-		{
-			RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]);
-		}
-
-#endif
-#ifdef RT2870
-		UINT32 tmpVal;
-
-		//
-		// Write IV
-		//
-		IV4 = (KeyIdx << 6);
-		if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
-			IV4 |= 0x20;  // turn on extension bit means EIV existence
-
-		tmpVal = pTxtsc[1] + (((pTxtsc[1] | 0x20) & 0x7f) << 8) + (pTxtsc[0] << 16) + (IV4 << 24);
-		RTMP_IO_WRITE32(pAd, offset, tmpVal);
-
-		//
-		// Write EIV
-		//
-		offset += 4;
-		RTMP_IO_WRITE32(pAd, offset, *(PUINT32)&pCipherKey->TxTsc[2]);
-#endif // RT2870 //
-		AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, bUsePairewiseKeyTable);
-	}
-
-	if (!bUsePairewiseKeyTable)
-	{
-		//
-		// Only update the shared key security mode
-		//
-		RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), &csr1.word);
-		if ((BssIndex % 2) == 0)
-		{
-			if (KeyIdx == 0)
-				csr1.field.Bss0Key0CipherAlg = CipherAlg;
-			else if (KeyIdx == 1)
-				csr1.field.Bss0Key1CipherAlg = CipherAlg;
-			else if (KeyIdx == 2)
-				csr1.field.Bss0Key2CipherAlg = CipherAlg;
-			else
-				csr1.field.Bss0Key3CipherAlg = CipherAlg;
-		}
-		else
-		{
-			if (KeyIdx == 0)
-				csr1.field.Bss1Key0CipherAlg = CipherAlg;
-			else if (KeyIdx == 1)
-				csr1.field.Bss1Key1CipherAlg = CipherAlg;
-			else if (KeyIdx == 2)
-				csr1.field.Bss1Key2CipherAlg = CipherAlg;
-			else
-				csr1.field.Bss1Key3CipherAlg = CipherAlg;
-		}
-		RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), csr1.word);
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n"));
-}
-
-
-/*
-	========================================================================
-	Description:
-		Add Pair-wise key material into ASIC.
-		Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
-
-    Return:
-	========================================================================
-*/
-VOID AsicAddPairwiseKeyEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR        pAddr,
-	IN UCHAR		WCID,
-	IN CIPHER_KEY		 *pCipherKey)
-{
-	INT i;
-	ULONG 		offset;
-	PUCHAR		 pKey = pCipherKey->Key;
-	PUCHAR		 pTxMic = pCipherKey->TxMic;
-	PUCHAR		 pRxMic = pCipherKey->RxMic;
-#ifdef DBG
-	UCHAR		CipherAlg = pCipherKey->CipherAlg;
-#endif // DBG //
-
-	// EKEY
-	offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
-#ifdef RT2860
-	for (i=0; i<MAX_LEN_OF_PEER_KEY; i++)
-	{
-		RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
-	}
-#endif
-#ifdef RT2870
-	RTUSBMultiWrite(pAd, offset, &pCipherKey->Key[0], MAX_LEN_OF_PEER_KEY);
-#endif // RT2870 //
-	for (i=0; i<MAX_LEN_OF_PEER_KEY; i+=4)
-	{
-		UINT32 Value;
-		RTMP_IO_READ32(pAd, offset + i, &Value);
-	}
-
-	offset += MAX_LEN_OF_PEER_KEY;
-
-	//  MIC KEY
-	if (pTxMic)
-	{
-#ifdef RT2860
-		for (i=0; i<8; i++)
-		{
-			RTMP_IO_WRITE8(pAd, offset+i, pTxMic[i]);
-		}
-#endif
-#ifdef RT2870
-		RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8);
-#endif // RT2870 //
-	}
-	offset += 8;
-	if (pRxMic)
-	{
-#ifdef RT2860
-		for (i=0; i<8; i++)
-		{
-			RTMP_IO_WRITE8(pAd, offset+i, pRxMic[i]);
-		}
-#endif
-#ifdef RT2870
-		RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8);
-#endif // RT2870 //
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID, CipherName[CipherAlg]));
-	DBGPRINT(RT_DEBUG_TRACE,("	Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-		pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15]));
-	if (pRxMic)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("	Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-			pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
-	}
-	if (pTxMic)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("	Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-			pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
-	}
-}
-/*
-	========================================================================
-	Description:
-		Remove Pair-wise key material from ASIC.
-
-    Return:
-	========================================================================
-*/
-VOID AsicRemovePairwiseKeyEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR		 BssIdx,
-	IN UCHAR		 Wcid)
-{
-	ULONG		WCIDAttri;
-	USHORT		offset;
-
-	// re-set the entry's WCID attribute as OPEN-NONE.
-	offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
-	WCIDAttri = (BssIdx<<4) | PAIRWISEKEYTABLE;
-	RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
-}
-
-BOOLEAN AsicSendCommandToMcu(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR		 Command,
-	IN UCHAR		 Token,
-	IN UCHAR		 Arg0,
-	IN UCHAR		 Arg1)
-{
-	HOST_CMD_CSR_STRUC	H2MCmd;
-	H2M_MAILBOX_STRUC	H2MMailbox;
-	ULONG				i = 0;
-
-	do
-	{
-		RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
-		if (H2MMailbox.field.Owner == 0)
-			break;
-
-		RTMPusecDelay(2);
-	} while(i++ < 100);
-
-	if (i > 100)
-	{
-		{
-#ifdef RT2860
-			UINT32 Data;
-
-			// Reset DMA
-			RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
-			Data |= 0x2;
-			RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
-
-			// After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too.
-			// Reset DMA/CPU ring index
-			RTMPRingCleanUp(pAd, QID_AC_BK);
-			RTMPRingCleanUp(pAd, QID_AC_BE);
-			RTMPRingCleanUp(pAd, QID_AC_VI);
-			RTMPRingCleanUp(pAd, QID_AC_VO);
-			RTMPRingCleanUp(pAd, QID_HCCA);
-			RTMPRingCleanUp(pAd, QID_MGMT);
-			RTMPRingCleanUp(pAd, QID_RX);
-
-			// Clear Reset
-			RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
-			Data &= 0xfffffffd;
-			RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
-#endif /* RT2860 */
-		DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
-		}
-		//return FALSE;
-#ifdef RT2870
-		return FALSE;
-#endif
-	}
-
-	H2MMailbox.field.Owner	  = 1;	   // pass ownership to MCU
-	H2MMailbox.field.CmdToken = Token;
-	H2MMailbox.field.HighByte = Arg1;
-	H2MMailbox.field.LowByte  = Arg0;
-	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
-
-	H2MCmd.word 			  = 0;
-	H2MCmd.field.HostCommand  = Command;
-	RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
-
-	if (Command != 0x80)
-	{
-	}
-
-	return TRUE;
-}
-
-#ifdef RT2860
-BOOLEAN AsicCheckCommanOk(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR		 Command)
-{
-	UINT32	CmdStatus = 0, CID = 0, i;
-	UINT32	ThisCIDMask = 0;
-
-	i = 0;
-	do
-	{
-		RTMP_IO_READ32(pAd, H2M_MAILBOX_CID, &CID);
-		// Find where the command is. Because this is randomly specified by firmware.
-		if ((CID & CID0MASK) == Command)
-		{
-			ThisCIDMask = CID0MASK;
-			break;
-		}
-		else if ((((CID & CID1MASK)>>8) & 0xff) == Command)
-		{
-			ThisCIDMask = CID1MASK;
-			break;
-		}
-		else if ((((CID & CID2MASK)>>16) & 0xff) == Command)
-		{
-			ThisCIDMask = CID2MASK;
-			break;
-		}
-		else if ((((CID & CID3MASK)>>24) & 0xff) == Command)
-		{
-			ThisCIDMask = CID3MASK;
-			break;
-		}
-
-		RTMPusecDelay(100);
-		i++;
-	}while (i < 200);
-
-	// Get CommandStatus Value
-	RTMP_IO_READ32(pAd, H2M_MAILBOX_STATUS, &CmdStatus);
-
-	// This command's status is at the same position as command. So AND command position's bitmask to read status.
-	if (i < 200)
-	{
-		// If Status is 1, the comamnd is success.
-		if (((CmdStatus & ThisCIDMask) == 0x1) || ((CmdStatus & ThisCIDMask) == 0x100)
-			|| ((CmdStatus & ThisCIDMask) == 0x10000) || ((CmdStatus & ThisCIDMask) == 0x1000000))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanOk CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus));
-			RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
-			RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
-			return TRUE;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail1 CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus));
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail2 Timeout Command = %d, CmdStatus= 0x%x \n", Command, CmdStatus));
-	}
-	// Clear Command and Status.
-	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
-	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
-
-	return FALSE;
-}
-#endif /* RT8260 */
-
 /*
 	========================================================================
 
@@ -7662,13 +5244,11 @@
 
 	========================================================================
 */
-VOID	RTMPCheckRates(
-	IN		PRTMP_ADAPTER	pAd,
-	IN OUT	UCHAR			SupRate[],
-	IN OUT	UCHAR			*SupRateLen)
+void RTMPCheckRates(struct rt_rtmp_adapter *pAd,
+		    IN u8 SupRate[], IN u8 * SupRateLen)
 {
-	UCHAR	RateIdx, i, j;
-	UCHAR	NewRate[12], NewRateLen;
+	u8 RateIdx, i, j;
+	u8 NewRate[12], NewRateLen;
 
 	NewRateLen = 0;
 
@@ -7677,7 +5257,7 @@
 	else
 		RateIdx = 12;
 
-	// Check for support rates exclude basic rate bit
+	/* Check for support rates exclude basic rate bit */
 	for (i = 0; i < *SupRateLen; i++)
 		for (j = 0; j < RateIdx; j++)
 			if ((SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
@@ -7687,43 +5267,37 @@
 	NdisMoveMemory(SupRate, NewRate, NewRateLen);
 }
 
-BOOLEAN RTMPCheckChannel(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR		CentralChannel,
-	IN UCHAR		Channel)
+BOOLEAN RTMPCheckChannel(struct rt_rtmp_adapter *pAd,
+			 u8 CentralChannel, u8 Channel)
 {
-	UCHAR		k;
-	UCHAR		UpperChannel = 0, LowerChannel = 0;
-	UCHAR		NoEffectChannelinList = 0;
+	u8 k;
+	u8 UpperChannel = 0, LowerChannel = 0;
+	u8 NoEffectChannelinList = 0;
 
-	// Find upper and lower channel according to 40MHz current operation.
-	if (CentralChannel < Channel)
-	{
+	/* Find upper and lower channel according to 40MHz current operation. */
+	if (CentralChannel < Channel) {
 		UpperChannel = Channel;
 		if (CentralChannel > 2)
 			LowerChannel = CentralChannel - 2;
 		else
 			return FALSE;
-	}
-	else if (CentralChannel > Channel)
-	{
+	} else if (CentralChannel > Channel) {
 		UpperChannel = CentralChannel + 2;
 		LowerChannel = Channel;
 	}
 
-	for (k = 0;k < pAd->ChannelListNum;k++)
-	{
-		if (pAd->ChannelList[k].Channel == UpperChannel)
-		{
-			NoEffectChannelinList ++;
+	for (k = 0; k < pAd->ChannelListNum; k++) {
+		if (pAd->ChannelList[k].Channel == UpperChannel) {
+			NoEffectChannelinList++;
 		}
-		if (pAd->ChannelList[k].Channel == LowerChannel)
-		{
-			NoEffectChannelinList ++;
+		if (pAd->ChannelList[k].Channel == LowerChannel) {
+			NoEffectChannelinList++;
 		}
 	}
 
-	DBGPRINT(RT_DEBUG_TRACE,("Total Channel in Channel List = [%d]\n", NoEffectChannelinList));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("Total Channel in Channel List = [%d]\n",
+		  NoEffectChannelinList));
 	if (NoEffectChannelinList == 2)
 		return TRUE;
 	else
@@ -7746,88 +5320,114 @@
 
 	========================================================================
 */
-BOOLEAN 	RTMPCheckHt(
-	IN	PRTMP_ADAPTER			pAd,
-	IN	UCHAR					Wcid,
-	IN 	HT_CAPABILITY_IE		*pHtCapability,
-	IN 	ADD_HT_INFO_IE			*pAddHtInfo)
+BOOLEAN RTMPCheckHt(struct rt_rtmp_adapter *pAd,
+		    u8 Wcid,
+		    struct rt_ht_capability_ie * pHtCapability,
+		    struct rt_add_ht_info_ie * pAddHtInfo)
 {
 	if (Wcid >= MAX_LEN_OF_MAC_TABLE)
 		return FALSE;
 
-	// If use AMSDU, set flag.
+	/* If use AMSDU, set flag. */
 	if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable)
-		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_AMSDU_INUSED);
-	// Save Peer Capability
+		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
+				       fCLIENT_STATUS_AMSDU_INUSED);
+	/* Save Peer Capability */
 	if (pHtCapability->HtCapInfo.ShortGIfor20)
-		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI20_CAPABLE);
+		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
+				       fCLIENT_STATUS_SGI20_CAPABLE);
 	if (pHtCapability->HtCapInfo.ShortGIfor40)
-		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI40_CAPABLE);
+		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
+				       fCLIENT_STATUS_SGI40_CAPABLE);
 	if (pHtCapability->HtCapInfo.TxSTBC)
-		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_TxSTBC_CAPABLE);
+		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
+				       fCLIENT_STATUS_TxSTBC_CAPABLE);
 	if (pHtCapability->HtCapInfo.RxSTBC)
-		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RxSTBC_CAPABLE);
-	if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport)
-	{
-		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RDG_CAPABLE);
+		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
+				       fCLIENT_STATUS_RxSTBC_CAPABLE);
+	if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport) {
+		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
+				       fCLIENT_STATUS_RDG_CAPABLE);
 	}
 
-	if (Wcid < MAX_LEN_OF_MAC_TABLE)
-	{
-		pAd->MacTab.Content[Wcid].MpduDensity = pHtCapability->HtCapParm.MpduDensity;
+	if (Wcid < MAX_LEN_OF_MAC_TABLE) {
+		pAd->MacTab.Content[Wcid].MpduDensity =
+		    pHtCapability->HtCapParm.MpduDensity;
 	}
-
-	// Will check ChannelWidth for MCSSet[4] below
+	/* Will check ChannelWidth for MCSSet[4] below */
 	pAd->MlmeAux.HtCapability.MCSSet[4] = 0x1;
-    switch (pAd->CommonCfg.RxStream)
-	{
-		case 1:
-			pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
-			pAd->MlmeAux.HtCapability.MCSSet[1] = 0x00;
-            pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
-            pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
-			break;
-		case 2:
-			pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
-			pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
-            pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
-            pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
-			break;
-		case 3:
-			pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
-			pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
-            pAd->MlmeAux.HtCapability.MCSSet[2] = 0xff;
-            pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
-			break;
+	switch (pAd->CommonCfg.RxStream) {
+	case 1:
+		pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
+		pAd->MlmeAux.HtCapability.MCSSet[1] = 0x00;
+		pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
+		pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
+		break;
+	case 2:
+		pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
+		pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
+		pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
+		pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
+		break;
+	case 3:
+		pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
+		pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
+		pAd->MlmeAux.HtCapability.MCSSet[2] = 0xff;
+		pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
+		break;
 	}
 
-	pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth = pAddHtInfo->AddHtInfo.RecomWidth & pAd->CommonCfg.DesiredHtPhy.ChannelWidth;
+	pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth =
+	    pAddHtInfo->AddHtInfo.RecomWidth & pAd->CommonCfg.DesiredHtPhy.
+	    ChannelWidth;
 
-    DBGPRINT(RT_DEBUG_TRACE, ("RTMPCheckHt:: HtCapInfo.ChannelWidth=%d, RecomWidth=%d, DesiredHtPhy.ChannelWidth=%d, BW40MAvailForA/G=%d/%d, PhyMode=%d \n",
-		pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth, pAddHtInfo->AddHtInfo.RecomWidth, pAd->CommonCfg.DesiredHtPhy.ChannelWidth,
-		pAd->NicConfig2.field.BW40MAvailForA, pAd->NicConfig2.field.BW40MAvailForG, pAd->CommonCfg.PhyMode));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("RTMPCheckHt:: HtCapInfo.ChannelWidth=%d, RecomWidth=%d, DesiredHtPhy.ChannelWidth=%d, BW40MAvailForA/G=%d/%d, PhyMode=%d \n",
+		  pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth,
+		  pAddHtInfo->AddHtInfo.RecomWidth,
+		  pAd->CommonCfg.DesiredHtPhy.ChannelWidth,
+		  pAd->NicConfig2.field.BW40MAvailForA,
+		  pAd->NicConfig2.field.BW40MAvailForG,
+		  pAd->CommonCfg.PhyMode));
 
-	pAd->MlmeAux.HtCapability.HtCapInfo.GF =  pHtCapability->HtCapInfo.GF &pAd->CommonCfg.DesiredHtPhy.GF;
+	pAd->MlmeAux.HtCapability.HtCapInfo.GF =
+	    pHtCapability->HtCapInfo.GF & pAd->CommonCfg.DesiredHtPhy.GF;
 
-	// Send Assoc Req with my HT capability.
-	pAd->MlmeAux.HtCapability.HtCapInfo.AMsduSize =  pAd->CommonCfg.DesiredHtPhy.AmsduSize;
-	pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs =  pAd->CommonCfg.DesiredHtPhy.MimoPs;
-	pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20 =  (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20) & (pHtCapability->HtCapInfo.ShortGIfor20);
-	pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40 =  (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40) & (pHtCapability->HtCapInfo.ShortGIfor40);
-	pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC =  (pAd->CommonCfg.DesiredHtPhy.TxSTBC)&(pHtCapability->HtCapInfo.RxSTBC);
-	pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC =  (pAd->CommonCfg.DesiredHtPhy.RxSTBC)&(pHtCapability->HtCapInfo.TxSTBC);
-	pAd->MlmeAux.HtCapability.HtCapParm.MaxRAmpduFactor = pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor;
-    pAd->MlmeAux.HtCapability.HtCapParm.MpduDensity = pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity;
-	pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC;
-	pAd->MacTab.Content[Wcid].HTCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC;
-	if (pAd->CommonCfg.bRdg)
-	{
-		pAd->MlmeAux.HtCapability.ExtHtCapInfo.RDGSupport = pHtCapability->ExtHtCapInfo.RDGSupport;
-        pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = 1;
+	/* Send Assoc Req with my HT capability. */
+	pAd->MlmeAux.HtCapability.HtCapInfo.AMsduSize =
+	    pAd->CommonCfg.DesiredHtPhy.AmsduSize;
+	pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs =
+	    pAd->CommonCfg.DesiredHtPhy.MimoPs;
+	pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20 =
+	    (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20) & (pHtCapability->
+							  HtCapInfo.
+							  ShortGIfor20);
+	pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40 =
+	    (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40) & (pHtCapability->
+							  HtCapInfo.
+							  ShortGIfor40);
+	pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC =
+	    (pAd->CommonCfg.DesiredHtPhy.TxSTBC) & (pHtCapability->HtCapInfo.
+						    RxSTBC);
+	pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC =
+	    (pAd->CommonCfg.DesiredHtPhy.RxSTBC) & (pHtCapability->HtCapInfo.
+						    TxSTBC);
+	pAd->MlmeAux.HtCapability.HtCapParm.MaxRAmpduFactor =
+	    pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor;
+	pAd->MlmeAux.HtCapability.HtCapParm.MpduDensity =
+	    pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity;
+	pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC =
+	    pHtCapability->ExtHtCapInfo.PlusHTC;
+	pAd->MacTab.Content[Wcid].HTCapability.ExtHtCapInfo.PlusHTC =
+	    pHtCapability->ExtHtCapInfo.PlusHTC;
+	if (pAd->CommonCfg.bRdg) {
+		pAd->MlmeAux.HtCapability.ExtHtCapInfo.RDGSupport =
+		    pHtCapability->ExtHtCapInfo.RDGSupport;
+		pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = 1;
 	}
 
-    if (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_20)
-        pAd->MlmeAux.HtCapability.MCSSet[4] = 0x0;  // BW20 can't transmit MCS32
+	if (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_20)
+		pAd->MlmeAux.HtCapability.MCSSet[4] = 0x0;	/* BW20 can't transmit MCS32 */
 
 	COPY_AP_HTSETTINGS_FROM_BEACON(pAd, pHtCapability);
 	return TRUE;
@@ -7849,65 +5449,60 @@
 
 	========================================================================
 */
-VOID RTMPUpdateMlmeRate(
-	IN PRTMP_ADAPTER	pAd)
+void RTMPUpdateMlmeRate(struct rt_rtmp_adapter *pAd)
 {
-	UCHAR	MinimumRate;
-	UCHAR	ProperMlmeRate; //= RATE_54;
-	UCHAR	i, j, RateIdx = 12; //1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
-	BOOLEAN	bMatch = FALSE;
+	u8 MinimumRate;
+	u8 ProperMlmeRate;	/*= RATE_54; */
+	u8 i, j, RateIdx = 12;	/*1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */
+	BOOLEAN bMatch = FALSE;
 
-	switch (pAd->CommonCfg.PhyMode)
-	{
-		case PHY_11B:
+	switch (pAd->CommonCfg.PhyMode) {
+	case PHY_11B:
+		ProperMlmeRate = RATE_11;
+		MinimumRate = RATE_1;
+		break;
+	case PHY_11BG_MIXED:
+	case PHY_11ABGN_MIXED:
+	case PHY_11BGN_MIXED:
+		if ((pAd->MlmeAux.SupRateLen == 4) &&
+		    (pAd->MlmeAux.ExtRateLen == 0))
+			/* B only AP */
 			ProperMlmeRate = RATE_11;
-			MinimumRate = RATE_1;
-			break;
-		case PHY_11BG_MIXED:
-		case PHY_11ABGN_MIXED:
-		case PHY_11BGN_MIXED:
-			if ((pAd->MlmeAux.SupRateLen == 4) &&
-				(pAd->MlmeAux.ExtRateLen == 0))
-				// B only AP
-				ProperMlmeRate = RATE_11;
-			else
-				ProperMlmeRate = RATE_24;
+		else
+			ProperMlmeRate = RATE_24;
 
-			if (pAd->MlmeAux.Channel <= 14)
-				MinimumRate = RATE_1;
-			else
-				MinimumRate = RATE_6;
-			break;
-		case PHY_11A:
-		case PHY_11N_2_4G:	// rt2860 need to check mlmerate for 802.11n
-		case PHY_11GN_MIXED:
-		case PHY_11AGN_MIXED:
-		case PHY_11AN_MIXED:
-		case PHY_11N_5G:
-			ProperMlmeRate = RATE_24;
-			MinimumRate = RATE_6;
-			break;
-		case PHY_11ABG_MIXED:
-			ProperMlmeRate = RATE_24;
-			if (pAd->MlmeAux.Channel <= 14)
-			   MinimumRate = RATE_1;
-			else
-				MinimumRate = RATE_6;
-			break;
-		default: // error
-			ProperMlmeRate = RATE_1;
+		if (pAd->MlmeAux.Channel <= 14)
 			MinimumRate = RATE_1;
-			break;
+		else
+			MinimumRate = RATE_6;
+		break;
+	case PHY_11A:
+	case PHY_11N_2_4G:	/* rt2860 need to check mlmerate for 802.11n */
+	case PHY_11GN_MIXED:
+	case PHY_11AGN_MIXED:
+	case PHY_11AN_MIXED:
+	case PHY_11N_5G:
+		ProperMlmeRate = RATE_24;
+		MinimumRate = RATE_6;
+		break;
+	case PHY_11ABG_MIXED:
+		ProperMlmeRate = RATE_24;
+		if (pAd->MlmeAux.Channel <= 14)
+			MinimumRate = RATE_1;
+		else
+			MinimumRate = RATE_6;
+		break;
+	default:		/* error */
+		ProperMlmeRate = RATE_1;
+		MinimumRate = RATE_1;
+		break;
 	}
 
-	for (i = 0; i < pAd->MlmeAux.SupRateLen; i++)
-	{
-		for (j = 0; j < RateIdx; j++)
-		{
-			if ((pAd->MlmeAux.SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
-			{
-				if (j == ProperMlmeRate)
-				{
+	for (i = 0; i < pAd->MlmeAux.SupRateLen; i++) {
+		for (j = 0; j < RateIdx; j++) {
+			if ((pAd->MlmeAux.SupRate[i] & 0x7f) ==
+			    RateIdTo500Kbps[j]) {
+				if (j == ProperMlmeRate) {
 					bMatch = TRUE;
 					break;
 				}
@@ -7918,16 +5513,12 @@
 			break;
 	}
 
-	if (bMatch == FALSE)
-	{
-		for (i = 0; i < pAd->MlmeAux.ExtRateLen; i++)
-		{
-			for (j = 0; j < RateIdx; j++)
-			{
-				if ((pAd->MlmeAux.ExtRate[i] & 0x7f) == RateIdTo500Kbps[j])
-				{
-					if (j == ProperMlmeRate)
-					{
+	if (bMatch == FALSE) {
+		for (i = 0; i < pAd->MlmeAux.ExtRateLen; i++) {
+			for (j = 0; j < RateIdx; j++) {
+				if ((pAd->MlmeAux.ExtRate[i] & 0x7f) ==
+				    RateIdTo500Kbps[j]) {
+					if (j == ProperMlmeRate) {
 						bMatch = TRUE;
 						break;
 					}
@@ -7939,51 +5530,48 @@
 		}
 	}
 
-	if (bMatch == FALSE)
-	{
+	if (bMatch == FALSE) {
 		ProperMlmeRate = MinimumRate;
 	}
 
 	pAd->CommonCfg.MlmeRate = MinimumRate;
 	pAd->CommonCfg.RtsRate = ProperMlmeRate;
-	if (pAd->CommonCfg.MlmeRate >= RATE_6)
-	{
+	if (pAd->CommonCfg.MlmeRate >= RATE_6) {
 		pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
-		pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
-		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-	}
-	else
-	{
+		pAd->CommonCfg.MlmeTransmit.field.MCS =
+		    OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE =
+		    MODE_OFDM;
+		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS =
+		    OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+	} else {
 		pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
 		pAd->CommonCfg.MlmeTransmit.field.MCS = pAd->CommonCfg.MlmeRate;
-		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_CCK;
-		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = pAd->CommonCfg.MlmeRate;
+		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE =
+		    MODE_CCK;
+		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS =
+		    pAd->CommonCfg.MlmeRate;
 	}
 
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateMlmeRate ==>   MlmeTransmit = 0x%x  \n" , pAd->CommonCfg.MlmeTransmit.word));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("RTMPUpdateMlmeRate ==>   MlmeTransmit = 0x%x  \n",
+		  pAd->CommonCfg.MlmeTransmit.word));
 }
 
-CHAR RTMPMaxRssi(
-	IN PRTMP_ADAPTER	pAd,
-	IN CHAR				Rssi0,
-	IN CHAR				Rssi1,
-	IN CHAR				Rssi2)
+char RTMPMaxRssi(struct rt_rtmp_adapter *pAd,
+		 char Rssi0, char Rssi1, char Rssi2)
 {
-	CHAR	larger = -127;
+	char larger = -127;
 
-	if ((pAd->Antenna.field.RxPath == 1) && (Rssi0 != 0))
-	{
+	if ((pAd->Antenna.field.RxPath == 1) && (Rssi0 != 0)) {
 		larger = Rssi0;
 	}
 
-	if ((pAd->Antenna.field.RxPath >= 2) && (Rssi1 != 0))
-	{
+	if ((pAd->Antenna.field.RxPath >= 2) && (Rssi1 != 0)) {
 		larger = max(Rssi0, Rssi1);
 	}
 
-	if ((pAd->Antenna.field.RxPath == 3) && (Rssi2 != 0))
-	{
+	if ((pAd->Antenna.field.RxPath == 3) && (Rssi2 != 0)) {
 		larger = max(larger, Rssi2);
 	}
 
@@ -7993,56 +5581,6 @@
 	return larger;
 }
 
-#ifdef RT2870
-// Antenna divesity use GPIO3 and EESK pin for control
-// Antenna and EEPROM access are both using EESK pin,
-// Therefor we should avoid accessing EESK at the same time
-// Then restore antenna after EEPROM access
-VOID AsicSetRxAnt(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			Ant)
-{
-	UINT32	Value;
-	UINT32	x;
-
-	if ((pAd->EepromAccess)										||
-		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS))	||
-		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))	||
-		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))			||
-		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
-	{
-		return;
-	}
-
-	// the antenna selection is through firmware and MAC register(GPIO3)
-	if (Ant == 0)
-	{
-		// Main antenna
-		RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-		x |= (EESK);
-		RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-		RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
-		Value &= ~(0x0808);
-		RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
-		DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to main antenna\n"));
-	}
-	else
-	{
-		// Aux antenna
-		RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-		x &= ~(EESK);
-		RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-		RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
-		Value &= ~(0x0808);
-		Value |= 0x08;
-		RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
-		DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to aux antenna\n"));
-	}
-}
-#endif
-
 /*
     ========================================================================
     Routine Description:
@@ -8056,91 +5594,70 @@
 
     ========================================================================
 */
-VOID AsicEvaluateRxAnt(
-	IN PRTMP_ADAPTER	pAd)
+void AsicEvaluateRxAnt(struct rt_rtmp_adapter *pAd)
 {
-	UCHAR	BBPR3 = 0;
+	u8 BBPR3 = 0;
 
 	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
-				fRTMP_ADAPTER_HALT_IN_PROGRESS |
-				fRTMP_ADAPTER_RADIO_OFF |
-				fRTMP_ADAPTER_NIC_NOT_EXIST |
-				fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)
-				|| OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
-#ifdef RT2870
-				|| (pAd->EepromAccess)
-#endif
-				)
-			return;
-
+			   fRTMP_ADAPTER_HALT_IN_PROGRESS |
+			   fRTMP_ADAPTER_RADIO_OFF |
+			   fRTMP_ADAPTER_NIC_NOT_EXIST |
+			   fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) ||
+	    OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
 #ifdef RT30xx
-	// two antenna selection mechanism- one is antenna diversity, the other is failed antenna remove
-	// one is antenna diversity:there is only one antenna can rx and tx
-	// the other is failed antenna remove:two physical antenna can rx and tx
-	if (pAd->NicConfig2.field.AntDiversity)
+	    || (pAd->EepromAccess)
+#endif /* RT30xx // */
+#ifdef RT3090
+	    || (pAd->bPCIclkOff == TRUE)
+#endif /* RT3090 // */
+	    )
+		return;
+
 	{
-		DBGPRINT(RT_DEBUG_TRACE,("AntDiv - before evaluate Pair1-Ant (%d,%d)\n",
-			pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt));
+		/*if (pAd->StaCfg.Psm == PWR_SAVE) */
+		/*      return; */
 
-		AsicSetRxAnt(pAd, pAd->RxAnt.Pair1SecondaryRxAnt);
-
-		pAd->RxAnt.EvaluatePeriod = 1; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt
-		pAd->RxAnt.FirstPktArrivedWhenEvaluate = FALSE;
-		pAd->RxAnt.RcvPktNumWhenEvaluate = 0;
-
-		// a one-shot timer to end the evalution
-		// dynamic adjust antenna evaluation period according to the traffic
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-			RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 100);
-		else
-			RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
-	}
-	else
-#endif
-	{
-		if (pAd->StaCfg.Psm == PWR_SAVE)
-			return;
-
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
-		BBPR3 &= (~0x18);
-		if(pAd->Antenna.field.RxPath == 3)
 		{
-			BBPR3 |= (0x10);
-		}
-		else if(pAd->Antenna.field.RxPath == 2)
-		{
-			BBPR3 |= (0x8);
-		}
-		else if(pAd->Antenna.field.RxPath == 1)
-		{
-			BBPR3 |= (0x0);
-		}
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
 
-#ifdef RT2860
-		pAd->StaCfg.BBPR3 = BBPR3;
-#endif
+			if (pAd->StaCfg.Psm == PWR_SAVE)
+				return;
+
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
+			BBPR3 &= (~0x18);
+			if (pAd->Antenna.field.RxPath == 3) {
+				BBPR3 |= (0x10);
+			} else if (pAd->Antenna.field.RxPath == 2) {
+				BBPR3 |= (0x8);
+			} else if (pAd->Antenna.field.RxPath == 1) {
+				BBPR3 |= (0x0);
+			}
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
+#ifdef RTMP_MAC_PCI
+			pAd->StaCfg.BBPR3 = BBPR3;
+#endif /* RTMP_MAC_PCI // */
+			if (OPSTATUS_TEST_FLAG
+			    (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
+			    ) {
+				unsigned long TxTotalCnt =
+				    pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+				    pAd->RalinkCounters.OneSecTxRetryOkCount +
+				    pAd->RalinkCounters.OneSecTxFailCount;
+
+				/* dynamic adjust antenna evaluation period according to the traffic */
+				if (TxTotalCnt > 50) {
+					RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer,
+						     20);
+					pAd->Mlme.bLowThroughput = FALSE;
+				} else {
+					RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer,
+						     300);
+					pAd->Mlme.bLowThroughput = TRUE;
+				}
+			}
+		}
+
 	}
 
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
-		)
-	{
-		ULONG	TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
-								pAd->RalinkCounters.OneSecTxRetryOkCount +
-								pAd->RalinkCounters.OneSecTxFailCount;
-
-			// dynamic adjust antenna evaluation period according to the traffic
-		if (TxTotalCnt > 50)
-		{
-			RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 20);
-			pAd->Mlme.bLowThroughput = FALSE;
-		}
-		else
-		{
-			RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
-			pAd->Mlme.bLowThroughput = TRUE;
-		}
-	}
 }
 
 /*
@@ -8156,90 +5673,54 @@
 
     ========================================================================
 */
-VOID AsicRxAntEvalTimeout(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3)
+void AsicRxAntEvalTimeout(void *SystemSpecific1,
+			  void *FunctionContext,
+			  void *SystemSpecific2, void *SystemSpecific3)
 {
-	RTMP_ADAPTER	*pAd = (RTMP_ADAPTER *)FunctionContext;
-	UCHAR			BBPR3 = 0;
-	CHAR			larger = -127, rssi0, rssi1, rssi2;
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
+	u8 BBPR3 = 0;
+	char larger = -127, rssi0, rssi1, rssi2;
 
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS	|
-							fRTMP_ADAPTER_HALT_IN_PROGRESS	|
-							fRTMP_ADAPTER_RADIO_OFF			|
-							fRTMP_ADAPTER_NIC_NOT_EXIST)
-							|| OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
-#ifdef RT2870
-							|| (pAd->EepromAccess)
-#endif
-							)
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
+			   fRTMP_ADAPTER_HALT_IN_PROGRESS |
+			   fRTMP_ADAPTER_RADIO_OFF |
+			   fRTMP_ADAPTER_NIC_NOT_EXIST) ||
+	    OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
+#ifdef RT30xx
+	    || (pAd->EepromAccess)
+#endif /* RT30xx // */
+#ifdef RT3090
+	    || (pAd->bPCIclkOff == TRUE)
+#endif /* RT3090 // */
+	    )
 		return;
 
 	{
-#ifdef RT30xx
-		if (pAd->NicConfig2.field.AntDiversity)
-		{
-			if ((pAd->RxAnt.RcvPktNumWhenEvaluate != 0) && (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >= pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt]))
-			{
-				UCHAR			temp;
-
-				//
-				// select PrimaryRxAntPair
-				//    Role change, Used Pair1SecondaryRxAnt as PrimaryRxAntPair.
-				//    Since Pair1SecondaryRxAnt Quality good than Pair1PrimaryRxAnt
-				//
-				temp = pAd->RxAnt.Pair1PrimaryRxAnt;
-				pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt;
-				pAd->RxAnt.Pair1SecondaryRxAnt = temp;
-
-				pAd->RxAnt.Pair1LastAvgRssi = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >> 3);
-				pAd->RxAnt.EvaluateStableCnt = 0;
-			}
-			else
-			{
-				// if the evaluated antenna is not better than original, switch back to original antenna
-				AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
-				pAd->RxAnt.EvaluateStableCnt ++;
-			}
-
-			pAd->RxAnt.EvaluatePeriod = 0; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt
-
-			DBGPRINT(RT_DEBUG_TRACE,("AsicRxAntEvalAction::After Eval(fix in #%d), <%d, %d>, RcvPktNumWhenEvaluate=%ld\n",
-					pAd->RxAnt.Pair1PrimaryRxAnt, (pAd->RxAnt.Pair1AvgRssi[0] >> 3), (pAd->RxAnt.Pair1AvgRssi[1] >> 3), pAd->RxAnt.RcvPktNumWhenEvaluate));
-		}
-		else
-#endif
+		/*if (pAd->StaCfg.Psm == PWR_SAVE) */
+		/*      return; */
 		{
 			if (pAd->StaCfg.Psm == PWR_SAVE)
 				return;
 
-			// if the traffic is low, use average rssi as the criteria
-			if (pAd->Mlme.bLowThroughput == TRUE)
-			{
+			/* if the traffic is low, use average rssi as the criteria */
+			if (pAd->Mlme.bLowThroughput == TRUE) {
 				rssi0 = pAd->StaCfg.RssiSample.LastRssi0;
 				rssi1 = pAd->StaCfg.RssiSample.LastRssi1;
 				rssi2 = pAd->StaCfg.RssiSample.LastRssi2;
-			}
-			else
-			{
+			} else {
 				rssi0 = pAd->StaCfg.RssiSample.AvgRssi0;
 				rssi1 = pAd->StaCfg.RssiSample.AvgRssi1;
 				rssi2 = pAd->StaCfg.RssiSample.AvgRssi2;
 			}
 
-			if(pAd->Antenna.field.RxPath == 3)
-			{
+			if (pAd->Antenna.field.RxPath == 3) {
 				larger = max(rssi0, rssi1);
 
 				if (larger > (rssi2 + 20))
 					pAd->Mlme.RealRxPath = 2;
 				else
 					pAd->Mlme.RealRxPath = 3;
-			}
-			else if(pAd->Antenna.field.RxPath == 2)
-			{
+			} else if (pAd->Antenna.field.RxPath == 2) {
 				if (rssi0 > (rssi1 + 20))
 					pAd->Mlme.RealRxPath = 1;
 				else
@@ -8248,39 +5729,45 @@
 
 			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
 			BBPR3 &= (~0x18);
-			if(pAd->Mlme.RealRxPath == 3)
-			{
+			if (pAd->Mlme.RealRxPath == 3) {
 				BBPR3 |= (0x10);
-			}
-			else if(pAd->Mlme.RealRxPath == 2)
-			{
+			} else if (pAd->Mlme.RealRxPath == 2) {
 				BBPR3 |= (0x8);
-			}
-			else if(pAd->Mlme.RealRxPath == 1)
-			{
+			} else if (pAd->Mlme.RealRxPath == 1) {
 				BBPR3 |= (0x0);
 			}
 			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
 			pAd->StaCfg.BBPR3 = BBPR3;
-#endif
+#endif /* RTMP_MAC_PCI // */
 		}
 	}
+
 }
 
-VOID APSDPeriodicExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3)
+void APSDPeriodicExec(void *SystemSpecific1,
+		      void *FunctionContext,
+		      void *SystemSpecific2, void *SystemSpecific3)
 {
-	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
 
 	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
 		return;
 
 	pAd->CommonCfg.TriggerTimerCount++;
 
+/* Driver should not send trigger frame, it should be send by application layer */
+/*
+	if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable
+		&& (pAd->CommonCfg.bNeedSendTriggerFrame ||
+		(((pAd->CommonCfg.TriggerTimerCount%20) == 19) && (!pAd->CommonCfg.bAPSDAC_BE || !pAd->CommonCfg.bAPSDAC_BK || !pAd->CommonCfg.bAPSDAC_VI || !pAd->CommonCfg.bAPSDAC_VO))))
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("Sending trigger frame and enter service period when support APSD\n"));
+		RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
+		pAd->CommonCfg.bNeedSendTriggerFrame = FALSE;
+		pAd->CommonCfg.TriggerTimerCount = 0;
+		pAd->CommonCfg.bInServicePeriod = TRUE;
+	}*/
 }
 
 /*
@@ -8297,11 +5784,9 @@
 
     ========================================================================
 */
-VOID RTMPSetPiggyBack(
-    IN PRTMP_ADAPTER    pAd,
-    IN BOOLEAN          bPiggyBack)
+void RTMPSetPiggyBack(struct rt_rtmp_adapter *pAd, IN BOOLEAN bPiggyBack)
 {
-	TX_LINK_CFG_STRUC  TxLinkCfg;
+	TX_LINK_CFG_STRUC TxLinkCfg;
 
 	RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
 
@@ -8324,36 +5809,32 @@
 
     ========================================================================
 */
-BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(
-	IN PRTMP_ADAPTER    pAd,
-	IN PMAC_TABLE_ENTRY	pEntry)
+BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(struct rt_rtmp_adapter *pAd,
+					   struct rt_mac_table_entry *pEntry)
 {
-	BOOLEAN		result = TRUE;
+	BOOLEAN result = TRUE;
 
 	{
-		// only associated STA counts
-		if (pEntry && (pEntry->ValidAsCLI) && (pEntry->Sst == SST_ASSOC))
-		{
+		/* only associated STA counts */
+		if (pEntry && (pEntry->ValidAsCLI)
+		    && (pEntry->Sst == SST_ASSOC)) {
 			result = pAd->StaCfg.bAutoTxRateSwitch;
-		}
-		else
+		} else
 			result = FALSE;
 	}
 
 	return result;
 }
 
-
-BOOLEAN RTMPAutoRateSwitchCheck(
-	IN PRTMP_ADAPTER    pAd)
+BOOLEAN RTMPAutoRateSwitchCheck(struct rt_rtmp_adapter *pAd)
 {
-	if (pAd->StaCfg.bAutoTxRateSwitch)
-		return TRUE;
-
+	{
+		if (pAd->StaCfg.bAutoTxRateSwitch)
+			return TRUE;
+	}
 	return FALSE;
 }
 
-
 /*
     ========================================================================
     Routine Description:
@@ -8369,13 +5850,15 @@
 
     ========================================================================
 */
-UCHAR RTMPStaFixedTxMode(
-	IN PRTMP_ADAPTER    pAd,
-	IN PMAC_TABLE_ENTRY	pEntry)
+u8 RTMPStaFixedTxMode(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry)
 {
-	UCHAR	tx_mode = FIXED_TXMODE_HT;
+	u8 tx_mode = FIXED_TXMODE_HT;
 
-	tx_mode = (UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode;
+	{
+		tx_mode =
+		    (u8)pAd->StaCfg.DesiredTransmitSetting.field.
+		    FixedTxMode;
+	}
 
 	return tx_mode;
 }
@@ -8395,9 +5878,7 @@
 
     ========================================================================
 */
-VOID RTMPUpdateLegacyTxSetting(
-		UCHAR				fixed_tx_mode,
-		PMAC_TABLE_ENTRY	pEntry)
+void RTMPUpdateLegacyTxSetting(u8 fixed_tx_mode, struct rt_mac_table_entry *pEntry)
 {
 	HTTRANSMIT_SETTING TransmitSetting;
 
@@ -8409,26 +5890,24 @@
 	TransmitSetting.field.MODE = pEntry->HTPhyMode.field.MODE;
 	TransmitSetting.field.MCS = pEntry->HTPhyMode.field.MCS;
 
-	if (fixed_tx_mode == FIXED_TXMODE_CCK)
-	{
+	if (fixed_tx_mode == FIXED_TXMODE_CCK) {
 		TransmitSetting.field.MODE = MODE_CCK;
-		// CCK mode allow MCS 0~3
+		/* CCK mode allow MCS 0~3 */
 		if (TransmitSetting.field.MCS > MCS_3)
 			TransmitSetting.field.MCS = MCS_3;
-	}
-	else
-	{
+	} else {
 		TransmitSetting.field.MODE = MODE_OFDM;
-		// OFDM mode allow MCS 0~7
+		/* OFDM mode allow MCS 0~7 */
 		if (TransmitSetting.field.MCS > MCS_7)
 			TransmitSetting.field.MCS = MCS_7;
 	}
 
-	if (pEntry->HTPhyMode.field.MODE >= TransmitSetting.field.MODE)
-	{
+	if (pEntry->HTPhyMode.field.MODE >= TransmitSetting.field.MODE) {
 		pEntry->HTPhyMode.word = TransmitSetting.word;
-		DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateLegacyTxSetting : wcid-%d, MODE=%s, MCS=%d \n",
-				pEntry->Aid, GetPhyMode(pEntry->HTPhyMode.field.MODE), pEntry->HTPhyMode.field.MCS));
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("RTMPUpdateLegacyTxSetting : wcid-%d, MODE=%s, MCS=%d \n",
+			  pEntry->Aid, GetPhyMode(pEntry->HTPhyMode.field.MODE),
+			  pEntry->HTPhyMode.field.MCS));
 	}
 }
 
@@ -8442,381 +5921,150 @@
 
 	==========================================================================
  */
-VOID AsicStaBbpTuning(
-	IN PRTMP_ADAPTER pAd)
+void AsicStaBbpTuning(struct rt_rtmp_adapter *pAd)
 {
-	UCHAR	OrigR66Value = 0, R66;//, R66UpperBound = 0x30, R66LowerBound = 0x30;
-	CHAR	Rssi;
+	u8 OrigR66Value = 0, R66;	/*, R66UpperBound = 0x30, R66LowerBound = 0x30; */
+	char Rssi;
 
-	// 2860C did not support Fase CCA, therefore can't tune
+	/* 2860C did not support Fase CCA, therefore can't tune */
 	if (pAd->MACVersion == 0x28600100)
 		return;
 
-	//
-	// work as a STA
-	//
-	if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)  // no R66 tuning when SCANNING
+	/* */
+	/* work as a STA */
+	/* */
+	if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)	/* no R66 tuning when SCANNING */
 		return;
 
 	if ((pAd->OpMode == OPMODE_STA)
-		&& (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
-			)
-		&& !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-#ifdef RT2860
-		&& (pAd->bPCIclkOff == FALSE))
-#endif
-#ifdef RT2870
-		)
-#endif
-	{
+	    && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
+	    )
+	    && !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+#ifdef RTMP_MAC_PCI
+	    && (pAd->bPCIclkOff == FALSE)
+#endif /* RTMP_MAC_PCI // */
+	    ) {
 		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &OrigR66Value);
 		R66 = OrigR66Value;
 
 		if (pAd->Antenna.field.RxPath > 1)
-			Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
+			Rssi =
+			    (pAd->StaCfg.RssiSample.AvgRssi0 +
+			     pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
 		else
 			Rssi = pAd->StaCfg.RssiSample.AvgRssi0;
 
-		if (pAd->LatchRfRegs.Channel <= 14)
-		{	//BG band
-#ifdef RT2870
-			// RT3070 is a no LNA solution, it should have different control regarding to AGC gain control
-			// Otherwise, it will have some throughput side effect when low RSSI
-			if (IS_RT30xx(pAd))
-			{
-				if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
-				{
-					R66 = 0x1C + 2*GET_LNA_GAIN(pAd) + 0x20;
-					if (OrigR66Value != R66)
-						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+		if (pAd->LatchRfRegs.Channel <= 14) {	/*BG band */
+#ifdef RT30xx
+			/* RT3070 is a no LNA solution, it should have different control regarding to AGC gain control */
+			/* Otherwise, it will have some throughput side effect when low RSSI */
+
+			if (IS_RT3070(pAd) || IS_RT3090(pAd) || IS_RT3572(pAd)
+			    || IS_RT3390(pAd)) {
+				if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) {
+					R66 =
+					    0x1C + 2 * GET_LNA_GAIN(pAd) + 0x20;
+					if (OrigR66Value != R66) {
+						RTMP_BBP_IO_WRITE8_BY_REG_ID
+						    (pAd, BBP_R66, R66);
+					}
+				} else {
+					R66 = 0x1C + 2 * GET_LNA_GAIN(pAd);
+					if (OrigR66Value != R66) {
+						RTMP_BBP_IO_WRITE8_BY_REG_ID
+						    (pAd, BBP_R66, R66);
+					}
 				}
-				else
-				{
-					R66 = 0x1C + 2*GET_LNA_GAIN(pAd);
-					if (OrigR66Value != R66)
-						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-				}
-			}
-			else
-#endif // RT2870 //
+			} else
+#endif /* RT30xx // */
 			{
-				if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
-				{
+				if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) {
 					R66 = (0x2E + GET_LNA_GAIN(pAd)) + 0x10;
-					if (OrigR66Value != R66)
-					{
-						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+					if (OrigR66Value != R66) {
+						RTMP_BBP_IO_WRITE8_BY_REG_ID
+						    (pAd, BBP_R66, R66);
 					}
-				}
-				else
-				{
+				} else {
 					R66 = 0x2E + GET_LNA_GAIN(pAd);
-					if (OrigR66Value != R66)
-					{
-						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+					if (OrigR66Value != R66) {
+						RTMP_BBP_IO_WRITE8_BY_REG_ID
+						    (pAd, BBP_R66, R66);
 					}
 				}
 			}
-		}
-		else
-		{	//A band
-			if (pAd->CommonCfg.BBPCurrentBW == BW_20)
-			{
-				if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
-				{
-					R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3 + 0x10;
-					if (OrigR66Value != R66)
-					{
-						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+		} else {	/*A band */
+			if (pAd->CommonCfg.BBPCurrentBW == BW_20) {
+				if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) {
+					R66 =
+					    0x32 + (GET_LNA_GAIN(pAd) * 5) / 3 +
+					    0x10;
+					if (OrigR66Value != R66) {
+						RTMP_BBP_IO_WRITE8_BY_REG_ID
+						    (pAd, BBP_R66, R66);
+					}
+				} else {
+					R66 =
+					    0x32 + (GET_LNA_GAIN(pAd) * 5) / 3;
+					if (OrigR66Value != R66) {
+						RTMP_BBP_IO_WRITE8_BY_REG_ID
+						    (pAd, BBP_R66, R66);
 					}
 				}
-				else
-				{
-					R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3;
-					if (OrigR66Value != R66)
-					{
-						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+			} else {
+				if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) {
+					R66 =
+					    0x3A + (GET_LNA_GAIN(pAd) * 5) / 3 +
+					    0x10;
+					if (OrigR66Value != R66) {
+						RTMP_BBP_IO_WRITE8_BY_REG_ID
+						    (pAd, BBP_R66, R66);
 					}
-				}
-			}
-			else
-			{
-				if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
-				{
-					R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3 + 0x10;
-					if (OrigR66Value != R66)
-					{
-						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-					}
-				}
-				else
-				{
-					R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3;
-					if (OrigR66Value != R66)
-					{
-						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+				} else {
+					R66 =
+					    0x3A + (GET_LNA_GAIN(pAd) * 5) / 3;
+					if (OrigR66Value != R66) {
+						RTMP_BBP_IO_WRITE8_BY_REG_ID
+						    (pAd, BBP_R66, R66);
 					}
 				}
 			}
 		}
 
-
 	}
 }
 
-#ifdef RT2860
-VOID AsicResetFromDMABusy(
-	IN PRTMP_ADAPTER pAd)
+void RTMPSetAGCInitValue(struct rt_rtmp_adapter *pAd, u8 BandWidth)
 {
-	UINT32		Data;
-	BOOLEAN		bCtrl = FALSE;
+	u8 R66 = 0x30;
 
-	DBGPRINT(RT_DEBUG_TRACE, ("--->  AsicResetFromDMABusy  !!!!!!!!!!!!!!!!!!!!!!! \n"));
+	if (pAd->LatchRfRegs.Channel <= 14) {	/* BG band */
+#ifdef RT30xx
+		/* Gary was verified Amazon AP and find that RT307x has BBP_R66 invalid default value */
 
-	// Be sure restore link control value so we can write register.
-	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-	if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("AsicResetFromDMABusy==>\n"));
-		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
-		RTMPusecDelay(6000);
-		pAd->bPCIclkOff = FALSE;
-		bCtrl = TRUE;
-	}
-	// Reset DMA
-	RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
-	Data |= 0x2;
-	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
-
-	// After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too.
-	// Reset DMA/CPU ring index
-	RTMPRingCleanUp(pAd, QID_AC_BK);
-	RTMPRingCleanUp(pAd, QID_AC_BE);
-	RTMPRingCleanUp(pAd, QID_AC_VI);
-	RTMPRingCleanUp(pAd, QID_AC_VO);
-	RTMPRingCleanUp(pAd, QID_HCCA);
-	RTMPRingCleanUp(pAd, QID_MGMT);
-	RTMPRingCleanUp(pAd, QID_RX);
-
-	// Clear Reset
-	RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
-	Data &= 0xfffffffd;
-	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
-
-	// If in Radio off, should call RTMPPCIePowerLinkCtrl again.
-	if ((bCtrl == TRUE) && (pAd->StaCfg.bRadio == FALSE))
-		RTMPPCIeLinkCtrlSetting(pAd, 3);
-
-	RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS);
-	DBGPRINT(RT_DEBUG_TRACE, ("<---  AsicResetFromDMABusy !!!!!!!!!!!!!!!!!!!!!!!  \n"));
-}
-
-VOID AsicResetBBP(
-	IN PRTMP_ADAPTER pAd)
-{
-	DBGPRINT(RT_DEBUG_TRACE, ("--->  Asic HardReset BBP  !!!!!!!!!!!!!!!!!!!!!!! \n"));
-
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x2);
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc);
-
-	// After hard-reset BBP, initialize all BBP values.
-	NICRestoreBBPValue(pAd);
-	DBGPRINT(RT_DEBUG_TRACE, ("<---  Asic HardReset BBP !!!!!!!!!!!!!!!!!!!!!!!  \n"));
-}
-
-VOID AsicResetMAC(
-	IN PRTMP_ADAPTER pAd)
-{
-	ULONG		Data;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--->  AsicResetMAC   !!!! \n"));
-	RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
-	Data |= 0x4;
-	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
-	Data &= 0xfffffffb;
-	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<---  AsicResetMAC   !!!! \n"));
-}
-
-VOID AsicResetPBF(
-	IN PRTMP_ADAPTER pAd)
-{
-	ULONG		Value1, Value2;
-	ULONG		Data;
-
-	RTMP_IO_READ32(pAd, TXRXQ_PCNT, &Value1);
-	RTMP_IO_READ32(pAd, PBF_DBG, &Value2);
-
-	Value2 &= 0xff;
-	// sum should be equals to 0xff, which is the total buffer size.
-	if ((Value1 + Value2) < 0xff)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("--->  Asic HardReset PBF !!!! \n"));
-		RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
-		Data |= 0x8;
-		RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
-		Data &= 0xfffffff7;
-		RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
-
-		DBGPRINT(RT_DEBUG_TRACE, ("<---  Asic HardReset PBF !!!! \n"));
-	}
-}
-#endif /* RT2860 */
-
-VOID RTMPSetAGCInitValue(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			BandWidth)
-{
-	UCHAR	R66 = 0x30;
-
-	if (pAd->LatchRfRegs.Channel <= 14)
-	{	// BG band
-		R66 = 0x2E + GET_LNA_GAIN(pAd);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-	}
-	else
-	{	//A band
-		if (BandWidth == BW_20)
+		if (IS_RT3070(pAd) || IS_RT3090(pAd) || IS_RT3572(pAd)
+		    || IS_RT3390(pAd)) {
+			R66 = 0x1C + 2 * GET_LNA_GAIN(pAd);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+		} else
+#endif /* RT30xx // */
 		{
-			R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3);
+			R66 = 0x2E + GET_LNA_GAIN(pAd);
 			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
 		}
-		else
+	} else {		/*A band */
 		{
-			R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+			if (BandWidth == BW_20) {
+				R66 =
+				    (u8)(0x32 +
+					     (GET_LNA_GAIN(pAd) * 5) / 3);
+				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+			} else {
+				R66 =
+				    (u8)(0x3A +
+					     (GET_LNA_GAIN(pAd) * 5) / 3);
+				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+			}
 		}
 	}
 
 }
-
-VOID AsicTurnOffRFClk(
-	IN PRTMP_ADAPTER pAd,
-	IN	UCHAR		Channel)
-{
-
-	// RF R2 bit 18 = 0
-	UINT32			R1 = 0, R2 = 0, R3 = 0;
-	UCHAR			index;
-	RTMP_RF_REGS	*RFRegTable;
-
-	// The RF programming sequence is difference between 3xxx and 2xxx
-	if (IS_RT3090(pAd))
-	{
-		RT30xxLoadRFSleepModeSetup(pAd);  // add by johnli,  RF power sequence setup, load RF sleep-mode setup
-		return;
-	}
-
-	RFRegTable = RF2850RegTable;
-
-	switch (pAd->RfIcType)
-	{
-		case RFIC_2820:
-		case RFIC_2850:
-		case RFIC_2720:
-		case RFIC_2750:
-
-			for (index = 0; index < NUM_OF_2850_CHNL; index++)
-			{
-				if (Channel == RFRegTable[index].Channel)
-				{
-					R1 = RFRegTable[index].R1 & 0xffffdfff;
-					R2 = RFRegTable[index].R2 & 0xfffbffff;
-					R3 = RFRegTable[index].R3 & 0xfff3ffff;
-
-					RTMP_RF_IO_WRITE32(pAd, R1);
-					RTMP_RF_IO_WRITE32(pAd, R2);
-
-					// Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0.
-					// Set RF R2 bit18=0, R3 bit[18:19]=0
-					//if (pAd->StaCfg.bRadio == FALSE)
-					if (1)
-					{
-						RTMP_RF_IO_WRITE32(pAd, R3);
-
-						DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x,  R3 = 0x%08x \n",
-							Channel, pAd->RfIcType, R2, R3));
-					}
-					else
-						DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
-							Channel, pAd->RfIcType, R2));
-					break;
-				}
-			}
-			break;
-
-		default:
-			break;
-	}
-}
-
-
-VOID AsicTurnOnRFClk(
-	IN PRTMP_ADAPTER pAd,
-	IN	UCHAR			Channel)
-{
-
-	// RF R2 bit 18 = 0
-	UINT32			R1 = 0, R2 = 0, R3 = 0;
-	UCHAR			index;
-	RTMP_RF_REGS	*RFRegTable;
-
-	// The RF programming sequence is difference between 3xxx and 2xxx
-	if (IS_RT3090(pAd))
-		return;
-
-	RFRegTable = RF2850RegTable;
-
-	switch (pAd->RfIcType)
-	{
-		case RFIC_2820:
-		case RFIC_2850:
-		case RFIC_2720:
-		case RFIC_2750:
-
-			for (index = 0; index < NUM_OF_2850_CHNL; index++)
-			{
-				if (Channel == RFRegTable[index].Channel)
-				{
-					R3 = pAd->LatchRfRegs.R3;
-					R3 &= 0xfff3ffff;
-					R3 |= 0x00080000;
-					RTMP_RF_IO_WRITE32(pAd, R3);
-
-					R1 = RFRegTable[index].R1;
-					RTMP_RF_IO_WRITE32(pAd, R1);
-
-					R2 = RFRegTable[index].R2;
-					if (pAd->Antenna.field.TxPath == 1)
-					{
-						R2 |= 0x4000;	// If TXpath is 1, bit 14 = 1;
-					}
-
-					if (pAd->Antenna.field.RxPath == 2)
-					{
-						R2 |= 0x40;	// write 1 to off Rxpath.
-					}
-					else if (pAd->Antenna.field.RxPath == 1)
-					{
-						R2 |= 0x20040;	// write 1 to off RxPath
-					}
-					RTMP_RF_IO_WRITE32(pAd, R2);
-
-					break;
-				}
-			}
-			break;
-
-		default:
-			break;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n",
-		Channel,
-		pAd->RfIcType,
-		R2));
-}
-
diff --git a/drivers/staging/rt2860/common/rt_channel.c b/drivers/staging/rt2860/common/rt_channel.c
new file mode 100644
index 0000000..5387989
--- /dev/null
+++ b/drivers/staging/rt2860/common/rt_channel.c
@@ -0,0 +1,1705 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+*/
+#include "../rt_config.h"
+
+struct rt_ch_freq_map CH_HZ_ID_MAP[] = {
+	{1, 2412}
+	,
+	{2, 2417}
+	,
+	{3, 2422}
+	,
+	{4, 2427}
+	,
+	{5, 2432}
+	,
+	{6, 2437}
+	,
+	{7, 2442}
+	,
+	{8, 2447}
+	,
+	{9, 2452}
+	,
+	{10, 2457}
+	,
+	{11, 2462}
+	,
+	{12, 2467}
+	,
+	{13, 2472}
+	,
+	{14, 2484}
+	,
+
+	/*  UNII */
+	{36, 5180}
+	,
+	{40, 5200}
+	,
+	{44, 5220}
+	,
+	{48, 5240}
+	,
+	{52, 5260}
+	,
+	{56, 5280}
+	,
+	{60, 5300}
+	,
+	{64, 5320}
+	,
+	{149, 5745}
+	,
+	{153, 5765}
+	,
+	{157, 5785}
+	,
+	{161, 5805}
+	,
+	{165, 5825}
+	,
+	{167, 5835}
+	,
+	{169, 5845}
+	,
+	{171, 5855}
+	,
+	{173, 5865}
+	,
+
+	/* HiperLAN2 */
+	{100, 5500}
+	,
+	{104, 5520}
+	,
+	{108, 5540}
+	,
+	{112, 5560}
+	,
+	{116, 5580}
+	,
+	{120, 5600}
+	,
+	{124, 5620}
+	,
+	{128, 5640}
+	,
+	{132, 5660}
+	,
+	{136, 5680}
+	,
+	{140, 5700}
+	,
+
+	/* Japan MMAC */
+	{34, 5170}
+	,
+	{38, 5190}
+	,
+	{42, 5210}
+	,
+	{46, 5230}
+	,
+
+	/*  Japan */
+	{184, 4920}
+	,
+	{188, 4940}
+	,
+	{192, 4960}
+	,
+	{196, 4980}
+	,
+
+	{208, 5040}
+	,			/* Japan, means J08 */
+	{212, 5060}
+	,			/* Japan, means J12 */
+	{216, 5080}
+	,			/* Japan, means J16 */
+};
+
+int CH_HZ_ID_MAP_NUM = (sizeof(CH_HZ_ID_MAP) / sizeof(struct rt_ch_freq_map));
+
+struct rt_ch_region ChRegion[] = {
+	{			/* Antigua and Berbuda */
+	 "AG",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, BOTH, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, FALSE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Argentina */
+	 "AR",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {52, 4, 24, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {149, 4, 30, BOTH, FALSE}
+	  ,			/* 5G, ch 149~161 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Aruba */
+	 "AW",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, BOTH, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, FALSE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Australia */
+	 "AU",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, BOTH, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 24, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {149, 5, 30, BOTH, FALSE}
+	  ,			/* 5G, ch 149~165 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Austria */
+	 "AT",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Bahamas */
+	 "BS",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, BOTH, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 24, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {149, 5, 30, BOTH, FALSE}
+	  ,			/* 5G, ch 149~165 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Barbados */
+	 "BB",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, BOTH, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 24, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, FALSE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Bermuda */
+	 "BM",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, BOTH, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 24, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, FALSE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Brazil */
+	 "BR",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, BOTH, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 24, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 24, BOTH, FALSE}
+	  ,			/* 5G, ch 100~140 */
+	  {149, 5, 30, BOTH, FALSE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Belgium */
+	 "BE",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 18, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 18, IDOR, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Bulgaria */
+	 "BG",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, ODOR, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Canada */
+	 "CA",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, BOTH, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {149, 5, 30, BOTH, FALSE}
+	  ,			/* 5G, ch 149~165 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Cayman IsLands */
+	 "KY",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, BOTH, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 24, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, FALSE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Chile */
+	 "CL",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 20, BOTH, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 20, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {149, 5, 20, BOTH, FALSE}
+	  ,			/* 5G, ch 149~165 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* China */
+	 "CN",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {149, 4, 27, BOTH, FALSE}
+	  ,			/* 5G, ch 149~161 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Colombia */
+	 "CO",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 17, BOTH, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 24, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, FALSE}
+	  ,			/* 5G, ch 100~140 */
+	  {149, 5, 30, BOTH, FALSE}
+	  ,			/* 5G, ch 149~165 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Costa Rica */
+	 "CR",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 17, BOTH, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 24, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {149, 4, 30, BOTH, FALSE}
+	  ,			/* 5G, ch 149~161 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Cyprus */
+	 "CY",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 24, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Czech_Republic */
+	 "CZ",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Denmark */
+	 "DK",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Dominican Republic */
+	 "DO",
+	 CE,
+	 {
+	  {1, 0, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 0 */
+	  {149, 4, 20, BOTH, FALSE}
+	  ,			/* 5G, ch 149~161 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Equador */
+	 "EC",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {100, 11, 27, BOTH, FALSE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* El Salvador */
+	 "SV",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 30, BOTH, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {149, 4, 36, BOTH, TRUE}
+	  ,			/* 5G, ch 149~165 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Finland */
+	 "FI",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* France */
+	 "FR",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Germany */
+	 "DE",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Greece */
+	 "GR",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, ODOR, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Guam */
+	 "GU",
+	 CE,
+	 {
+	  {1, 11, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~11 */
+	  {36, 4, 17, BOTH, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 24, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, FALSE}
+	  ,			/* 5G, ch 100~140 */
+	  {149, 5, 30, BOTH, FALSE}
+	  ,			/* 5G, ch 149~165 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Guatemala */
+	 "GT",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 17, BOTH, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 24, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {149, 4, 30, BOTH, FALSE}
+	  ,			/* 5G, ch 149~161 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Haiti */
+	 "HT",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 17, BOTH, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 24, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {149, 4, 30, BOTH, FALSE}
+	  ,			/* 5G, ch 149~161 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Honduras */
+	 "HN",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {149, 4, 27, BOTH, FALSE}
+	  ,			/* 5G, ch 149~161 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Hong Kong */
+	 "HK",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {149, 4, 30, BOTH, FALSE}
+	  ,			/* 5G, ch 149~161 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Hungary */
+	 "HU",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Iceland */
+	 "IS",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* India */
+	 "IN",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {149, 4, 24, IDOR, FALSE}
+	  ,			/* 5G, ch 149~161 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Indonesia */
+	 "ID",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {149, 4, 27, BOTH, FALSE}
+	  ,			/* 5G, ch 149~161 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Ireland */
+	 "IE",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, ODOR, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Israel */
+	 "IL",
+	 CE,
+	 {
+	  {1, 3, 20, IDOR, FALSE}
+	  ,			/* 2.4 G, ch 1~3 */
+	  {4, 6, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 4~9 */
+	  {10, 4, 20, IDOR, FALSE}
+	  ,			/* 2.4 G, ch 10~13 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Italy */
+	 "IT",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, ODOR, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Japan */
+	 "JP",
+	 JAP,
+	 {
+	  {1, 14, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~14 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Jordan */
+	 "JO",
+	 CE,
+	 {
+	  {1, 13, 20, IDOR, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {149, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 149~161 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Latvia */
+	 "LV",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Liechtenstein */
+	 "LI",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Lithuania */
+	 "LT",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Luxemburg */
+	 "LU",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Malaysia */
+	 "MY",
+	 CE,
+	 {
+	  {36, 4, 23, BOTH, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {149, 5, 20, BOTH, FALSE}
+	  ,			/* 5G, ch 149~165 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Malta */
+	 "MT",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Marocco */
+	 "MA",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 24, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Mexico */
+	 "MX",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, BOTH, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 24, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {149, 5, 30, IDOR, FALSE}
+	  ,			/* 5G, ch 149~165 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Netherlands */
+	 "NL",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 24, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* New Zealand */
+	 "NZ",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 24, BOTH, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 24, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {149, 4, 30, BOTH, FALSE}
+	  ,			/* 5G, ch 149~161 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Norway */
+	 "NO",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 24, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 24, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, TRUE}
+	  ,			/* 5G, ch 149~161 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Peru */
+	 "PE",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {149, 4, 27, BOTH, FALSE}
+	  ,			/* 5G, ch 149~161 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Portugal */
+	 "PT",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Poland */
+	 "PL",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Romania */
+	 "RO",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Russia */
+	 "RU",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {149, 4, 20, IDOR, FALSE}
+	  ,			/* 5G, ch 149~161 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Saudi Arabia */
+	 "SA",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, BOTH, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {149, 4, 23, BOTH, FALSE}
+	  ,			/* 5G, ch 149~161 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Serbia_and_Montenegro */
+	 "CS",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Singapore */
+	 "SG",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, BOTH, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {149, 4, 20, BOTH, FALSE}
+	  ,			/* 5G, ch 149~161 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Slovakia */
+	 "SK",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Slovenia */
+	 "SI",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* South Africa */
+	 "ZA",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, BOTH, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {149, 4, 30, BOTH, FALSE}
+	  ,			/* 5G, ch 149~161 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* South Korea */
+	 "KR",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 20, BOTH, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 20, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 8, 20, BOTH, FALSE}
+	  ,			/* 5G, ch 100~128 */
+	  {149, 4, 20, BOTH, FALSE}
+	  ,			/* 5G, ch 149~161 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Spain */
+	 "ES",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 17, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Sweden */
+	 "SE",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Switzerland */
+	 "CH",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~13 */
+	  {36, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Taiwan */
+	 "TW",
+	 CE,
+	 {
+	  {1, 11, 30, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~11 */
+	  {52, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Turkey */
+	 "TR",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~11 */
+	  {36, 4, 23, BOTH, FALSE}
+	  ,			/* 5G, ch 36~48 */
+	  {52, 4, 23, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* UK */
+	 "GB",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~11 */
+	  {36, 4, 23, IDOR, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {52, 4, 23, IDOR, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Ukraine */
+	 "UA",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~11 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* United_Arab_Emirates */
+	 "AE",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~11 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* United_States */
+	 "US",
+	 CE,
+	 {
+	  {1, 11, 30, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~11 */
+	  {36, 4, 17, IDOR, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {52, 4, 24, BOTH, TRUE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 30, BOTH, TRUE}
+	  ,			/* 5G, ch 100~140 */
+	  {149, 5, 30, BOTH, FALSE}
+	  ,			/* 5G, ch 149~165 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Venezuela */
+	 "VE",
+	 CE,
+	 {
+	  {1, 13, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~11 */
+	  {149, 4, 27, BOTH, FALSE}
+	  ,			/* 5G, ch 149~161 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+
+	{			/* Default */
+	 "",
+	 CE,
+	 {
+	  {1, 11, 20, BOTH, FALSE}
+	  ,			/* 2.4 G, ch 1~11 */
+	  {36, 4, 20, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {52, 4, 20, BOTH, FALSE}
+	  ,			/* 5G, ch 52~64 */
+	  {100, 11, 20, BOTH, FALSE}
+	  ,			/* 5G, ch 100~140 */
+	  {149, 5, 20, BOTH, FALSE}
+	  ,			/* 5G, ch 149~165 */
+	  {0}
+	  ,			/* end */
+	  }
+	 }
+	,
+};
+
+static struct rt_ch_region *GetChRegion(u8 *CntryCode)
+{
+	int loop = 0;
+	struct rt_ch_region *pChRegion = NULL;
+
+	while (strcmp((char *)ChRegion[loop].CountReg, "") != 0) {
+		if (strncmp
+		    ((char *)ChRegion[loop].CountReg, (char *)CntryCode,
+		     2) == 0) {
+			pChRegion = &ChRegion[loop];
+			break;
+		}
+		loop++;
+	}
+
+	if (pChRegion == NULL)
+		pChRegion = &ChRegion[loop];
+	return pChRegion;
+}
+
+static void ChBandCheck(u8 PhyMode, u8 *pChType)
+{
+	switch (PhyMode) {
+	case PHY_11A:
+	case PHY_11AN_MIXED:
+		*pChType = BAND_5G;
+		break;
+	case PHY_11ABG_MIXED:
+	case PHY_11AGN_MIXED:
+	case PHY_11ABGN_MIXED:
+		*pChType = BAND_BOTH;
+		break;
+
+	default:
+		*pChType = BAND_24G;
+		break;
+	}
+}
+
+static u8 FillChList(struct rt_rtmp_adapter *pAd,
+			struct rt_ch_desp *pChDesp,
+			u8 Offset, u8 increment)
+{
+	int i, j, l;
+	u8 channel;
+
+	j = Offset;
+	for (i = 0; i < pChDesp->NumOfCh; i++) {
+		channel = pChDesp->FirstChannel + i * increment;
+		for (l = 0; l < MAX_NUM_OF_CHANNELS; l++) {
+			if (channel == pAd->TxPower[l].Channel) {
+				pAd->ChannelList[j].Power =
+				    pAd->TxPower[l].Power;
+				pAd->ChannelList[j].Power2 =
+				    pAd->TxPower[l].Power2;
+				break;
+			}
+		}
+		if (l == MAX_NUM_OF_CHANNELS)
+			continue;
+
+		pAd->ChannelList[j].Channel =
+		    pChDesp->FirstChannel + i * increment;
+		pAd->ChannelList[j].MaxTxPwr = pChDesp->MaxTxPwr;
+		pAd->ChannelList[j].DfsReq = pChDesp->DfsReq;
+		j++;
+	}
+	pAd->ChannelListNum = j;
+
+	return j;
+}
+
+static inline void CreateChList(struct rt_rtmp_adapter *pAd,
+				struct rt_ch_region *pChRegion, u8 Geography)
+{
+	int i;
+	u8 offset = 0;
+	struct rt_ch_desp *pChDesp;
+	u8 ChType;
+	u8 increment;
+
+	if (pChRegion == NULL)
+		return;
+
+	ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
+
+	for (i = 0; i < 10; i++) {
+		pChDesp = &pChRegion->ChDesp[i];
+		if (pChDesp->FirstChannel == 0)
+			break;
+
+		if (ChType == BAND_5G) {
+			if (pChDesp->FirstChannel <= 14)
+				continue;
+		} else if (ChType == BAND_24G) {
+			if (pChDesp->FirstChannel > 14)
+				continue;
+		}
+
+		if ((pChDesp->Geography == BOTH)
+		    || (pChDesp->Geography == Geography)) {
+			if (pChDesp->FirstChannel > 14)
+				increment = 4;
+			else
+				increment = 1;
+			offset = FillChList(pAd, pChDesp, offset, increment);
+		}
+	}
+}
+
+void BuildChannelListEx(struct rt_rtmp_adapter *pAd)
+{
+	struct rt_ch_region *pChReg;
+
+	pChReg = GetChRegion(pAd->CommonCfg.CountryCode);
+	CreateChList(pAd, pChReg, pAd->CommonCfg.Geography);
+}
+
+void BuildBeaconChList(struct rt_rtmp_adapter *pAd,
+		       u8 *pBuf, unsigned long *pBufLen)
+{
+	int i;
+	unsigned long TmpLen;
+	struct rt_ch_region *pChRegion;
+	struct rt_ch_desp *pChDesp;
+	u8 ChType;
+
+	pChRegion = GetChRegion(pAd->CommonCfg.CountryCode);
+
+	if (pChRegion == NULL)
+		return;
+
+	ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
+	*pBufLen = 0;
+
+	for (i = 0; i < 10; i++) {
+		pChDesp = &pChRegion->ChDesp[i];
+		if (pChDesp->FirstChannel == 0)
+			break;
+
+		if (ChType == BAND_5G) {
+			if (pChDesp->FirstChannel <= 14)
+				continue;
+		} else if (ChType == BAND_24G) {
+			if (pChDesp->FirstChannel > 14)
+				continue;
+		}
+
+		if ((pChDesp->Geography == BOTH)
+		    || (pChDesp->Geography == pAd->CommonCfg.Geography)) {
+			MakeOutgoingFrame(pBuf + *pBufLen, &TmpLen,
+					  1, &pChDesp->FirstChannel,
+					  1, &pChDesp->NumOfCh,
+					  1, &pChDesp->MaxTxPwr, END_OF_ARGS);
+			*pBufLen += TmpLen;
+		}
+	}
+}
+
+static BOOLEAN IsValidChannel(struct rt_rtmp_adapter *pAd, u8 channel)
+{
+	int i;
+
+	for (i = 0; i < pAd->ChannelListNum; i++) {
+		if (pAd->ChannelList[i].Channel == channel)
+			break;
+	}
+
+	if (i == pAd->ChannelListNum)
+		return FALSE;
+	else
+		return TRUE;
+}
+
+static u8 GetExtCh(u8 Channel, u8 Direction)
+{
+	char ExtCh;
+
+	if (Direction == EXTCHA_ABOVE)
+		ExtCh = Channel + 4;
+	else
+		ExtCh = (Channel - 4) > 0 ? (Channel - 4) : 0;
+
+	return ExtCh;
+}
+
+void N_ChannelCheck(struct rt_rtmp_adapter *pAd)
+{
+	/*u8 ChannelNum = pAd->ChannelListNum; */
+	u8 Channel = pAd->CommonCfg.Channel;
+
+	if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+	    && (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)) {
+		if (Channel > 14) {
+			if ((Channel == 36) || (Channel == 44)
+			    || (Channel == 52) || (Channel == 60)
+			    || (Channel == 100) || (Channel == 108)
+			    || (Channel == 116) || (Channel == 124)
+			    || (Channel == 132) || (Channel == 149)
+			    || (Channel == 157)) {
+				pAd->CommonCfg.RegTransmitSetting.field.EXTCHA =
+				    EXTCHA_ABOVE;
+			} else if ((Channel == 40) || (Channel == 48)
+				   || (Channel == 56) || (Channel == 64)
+				   || (Channel == 104) || (Channel == 112)
+				   || (Channel == 120) || (Channel == 128)
+				   || (Channel == 136) || (Channel == 153)
+				   || (Channel == 161)) {
+				pAd->CommonCfg.RegTransmitSetting.field.EXTCHA =
+				    EXTCHA_BELOW;
+			} else {
+				pAd->CommonCfg.RegTransmitSetting.field.BW =
+				    BW_20;
+			}
+		} else {
+			do {
+				u8 ExtCh;
+				u8 Dir =
+				    pAd->CommonCfg.RegTransmitSetting.field.
+				    EXTCHA;
+				ExtCh = GetExtCh(Channel, Dir);
+				if (IsValidChannel(pAd, ExtCh))
+					break;
+
+				Dir =
+				    (Dir ==
+				     EXTCHA_ABOVE) ? EXTCHA_BELOW :
+				    EXTCHA_ABOVE;
+				ExtCh = GetExtCh(Channel, Dir);
+				if (IsValidChannel(pAd, ExtCh)) {
+					pAd->CommonCfg.RegTransmitSetting.field.
+					    EXTCHA = Dir;
+					break;
+				}
+				pAd->CommonCfg.RegTransmitSetting.field.BW =
+				    BW_20;
+			} while (FALSE);
+
+			if (Channel == 14) {
+				pAd->CommonCfg.RegTransmitSetting.field.BW =
+				    BW_20;
+				/*pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_NONE; // We didn't set the ExtCh as NONE due to it'll set in RTMPSetHT() */
+			}
+		}
+	}
+
+}
+
+void N_SetCenCh(struct rt_rtmp_adapter *pAd)
+{
+	if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40) {
+		if (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA ==
+		    EXTCHA_ABOVE) {
+			pAd->CommonCfg.CentralChannel =
+			    pAd->CommonCfg.Channel + 2;
+		} else {
+			if (pAd->CommonCfg.Channel == 14)
+				pAd->CommonCfg.CentralChannel =
+				    pAd->CommonCfg.Channel - 1;
+			else
+				pAd->CommonCfg.CentralChannel =
+				    pAd->CommonCfg.Channel - 2;
+		}
+	} else {
+		pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
+	}
+}
+
+u8 GetCuntryMaxTxPwr(struct rt_rtmp_adapter *pAd, u8 channel)
+{
+	int i;
+	for (i = 0; i < pAd->ChannelListNum; i++) {
+		if (pAd->ChannelList[i].Channel == channel)
+			break;
+	}
+
+	if (i == pAd->ChannelListNum)
+		return 0xff;
+	else
+		return pAd->ChannelList[i].MaxTxPwr;
+}
diff --git a/drivers/staging/rt2860/common/rt_rf.c b/drivers/staging/rt2860/common/rt_rf.c
new file mode 100644
index 0000000..519121d
--- /dev/null
+++ b/drivers/staging/rt2860/common/rt_rf.c
@@ -0,0 +1,188 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rt_rf.c
+
+	Abstract:
+	Ralink Wireless driver RF related functions
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+#include "../rt_config.h"
+
+#ifdef RTMP_RF_RW_SUPPORT
+/*
+	========================================================================
+
+	Routine Description: Write RT30xx RF register through MAC
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+int RT30xxWriteRFRegister(struct rt_rtmp_adapter *pAd,
+				  u8 regID, u8 value)
+{
+	RF_CSR_CFG_STRUC rfcsr;
+	u32 i = 0;
+
+	do {
+		RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
+
+		if (!rfcsr.field.RF_CSR_KICK)
+			break;
+		i++;
+	}
+	while ((i < RETRY_LIMIT)
+	       && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
+
+	if ((i == RETRY_LIMIT)
+	    || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) {
+		DBGPRINT_RAW(RT_DEBUG_ERROR,
+			     ("Retry count exhausted or device removed!\n"));
+		return STATUS_UNSUCCESSFUL;
+	}
+
+	rfcsr.field.RF_CSR_WR = 1;
+	rfcsr.field.RF_CSR_KICK = 1;
+	rfcsr.field.TESTCSR_RFACC_REGNUM = regID;
+	rfcsr.field.RF_CSR_DATA = value;
+
+	RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+/*
+	========================================================================
+
+	Routine Description: Read RT30xx RF register through MAC
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+int RT30xxReadRFRegister(struct rt_rtmp_adapter *pAd,
+				 u8 regID, u8 *pValue)
+{
+	RF_CSR_CFG_STRUC rfcsr;
+	u32 i = 0, k = 0;
+
+	for (i = 0; i < MAX_BUSY_COUNT; i++) {
+		RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
+
+		if (rfcsr.field.RF_CSR_KICK == BUSY) {
+			continue;
+		}
+		rfcsr.word = 0;
+		rfcsr.field.RF_CSR_WR = 0;
+		rfcsr.field.RF_CSR_KICK = 1;
+		rfcsr.field.TESTCSR_RFACC_REGNUM = regID;
+		RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
+		for (k = 0; k < MAX_BUSY_COUNT; k++) {
+			RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
+
+			if (rfcsr.field.RF_CSR_KICK == IDLE)
+				break;
+		}
+		if ((rfcsr.field.RF_CSR_KICK == IDLE) &&
+		    (rfcsr.field.TESTCSR_RFACC_REGNUM == regID)) {
+			*pValue = (u8)rfcsr.field.RF_CSR_DATA;
+			break;
+		}
+	}
+	if (rfcsr.field.RF_CSR_KICK == BUSY) {
+		DBGPRINT_ERR(("RF read R%d=0x%x fail, i[%d], k[%d]\n", regID,
+			      rfcsr.word, i, k));
+		return STATUS_UNSUCCESSFUL;
+	}
+
+	return STATUS_SUCCESS;
+}
+
+void NICInitRFRegisters(struct rt_rtmp_adapter *pAd)
+{
+	if (pAd->chipOps.AsicRfInit)
+		pAd->chipOps.AsicRfInit(pAd);
+}
+
+void RtmpChipOpsRFHook(struct rt_rtmp_adapter *pAd)
+{
+	struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
+
+	pChipOps->pRFRegTable = NULL;
+	pChipOps->AsicRfInit = NULL;
+	pChipOps->AsicRfTurnOn = NULL;
+	pChipOps->AsicRfTurnOff = NULL;
+	pChipOps->AsicReverseRfFromSleepMode = NULL;
+	pChipOps->AsicHaltAction = NULL;
+	/* We depends on RfICType and MACVersion to assign the corresponding operation callbacks. */
+
+#ifdef RT30xx
+	if (IS_RT30xx(pAd)) {
+		pChipOps->pRFRegTable = RT30xx_RFRegTable;
+		pChipOps->AsicHaltAction = RT30xxHaltAction;
+#ifdef RT3070
+		if ((IS_RT3070(pAd) || IS_RT3071(pAd))
+		    && (pAd->infType == RTMP_DEV_INF_USB)) {
+			pChipOps->AsicRfInit = NICInitRT3070RFRegisters;
+			if (IS_RT3071(pAd)) {
+				pChipOps->AsicRfTurnOff =
+				    RT30xxLoadRFSleepModeSetup;
+				pChipOps->AsicReverseRfFromSleepMode =
+				    RT30xxReverseRFSleepModeSetup;
+			}
+		}
+#endif /* RT3070 // */
+#ifdef RT3090
+		if (IS_RT3090(pAd) && (pAd->infType == RTMP_DEV_INF_PCI)) {
+			pChipOps->AsicRfTurnOff = RT30xxLoadRFSleepModeSetup;
+			pChipOps->AsicRfInit = NICInitRT3090RFRegisters;
+			pChipOps->AsicReverseRfFromSleepMode =
+			    RT30xxReverseRFSleepModeSetup;
+		}
+#endif /* RT3090 // */
+	}
+#endif /* RT30xx // */
+}
+
+#endif /* RTMP_RF_RW_SUPPORT // */
diff --git a/drivers/staging/rt2860/common/rtmp_init.c b/drivers/staging/rt2860/common/rtmp_init.c
index 20c2ce2..21a95ff 100644
--- a/drivers/staging/rt2860/common/rtmp_init.c
+++ b/drivers/staging/rt2860/common/rtmp_init.c
@@ -33,172 +33,111 @@
 	Revision History:
 	Who         When          What
 	--------    ----------    ----------------------------------------------
-	Paul Lin    2002-08-01    created
-    John Chang  2004-08-20    RT2561/2661 use scatter-gather scheme
-    Jan Lee  2006-09-15    RT2860. Change for 802.11n , EEPROM, Led, BA, HT.
 */
 #include "../rt_config.h"
-#ifdef RT2860
-#include "firmware.h"
-#include <linux/bitrev.h>
-#endif
-#ifdef RT2870
-/* New firmware handles both RT2870 and RT3070. */
-#include "../../rt3070/firmware.h"
-#endif
 
-UCHAR    BIT8[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
-ULONG    BIT32[] = {0x00000001, 0x00000002, 0x00000004, 0x00000008,
-					0x00000010, 0x00000020, 0x00000040, 0x00000080,
-					0x00000100, 0x00000200, 0x00000400, 0x00000800,
-					0x00001000, 0x00002000, 0x00004000, 0x00008000,
-					0x00010000, 0x00020000, 0x00040000, 0x00080000,
-					0x00100000, 0x00200000, 0x00400000, 0x00800000,
-					0x01000000, 0x02000000, 0x04000000, 0x08000000,
-					0x10000000, 0x20000000, 0x40000000, 0x80000000};
+u8 BIT8[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
+char *CipherName[] =
+    { "none", "wep64", "wep128", "TKIP", "AES", "CKIP64", "CKIP128" };
 
-char*   CipherName[] = {"none","wep64","wep128","TKIP","AES","CKIP64","CKIP128"};
-
-//
-// BBP register initialization set
-//
-REG_PAIR   BBPRegTable[] = {
-	{BBP_R65,		0x2C},		// fix rssi issue
-	{BBP_R66,		0x38},	// Also set this default value to pAd->BbpTuning.R66CurrentValue at initial
-	{BBP_R69,		0x12},
-	{BBP_R70,		0xa},	// BBP_R70 will change to 0x8 in ApStartUp and LinkUp for rt2860C, otherwise value is 0xa
-	{BBP_R73,		0x10},
-	{BBP_R81,		0x37},
-	{BBP_R82,		0x62},
-	{BBP_R83,		0x6A},
-	{BBP_R84,		0x99},	// 0x19 is for rt2860E and after. This is for extension channel overlapping IOT. 0x99 is for rt2860D and before
-	{BBP_R86,		0x00},	// middle range issue, Rory @2008-01-28
-	{BBP_R91,		0x04},	// middle range issue, Rory @2008-01-28
-	{BBP_R92,		0x00},	// middle range issue, Rory @2008-01-28
-	{BBP_R103,  	0x00}, 	// near range high-power issue, requested from Gary @2008-0528
-	{BBP_R105,		0x05},	// 0x05 is for rt2860E to turn on FEQ control. It is safe for rt2860D and before, because Bit 7:2 are reserved in rt2860D and before.
+/* */
+/* BBP register initialization set */
+/* */
+struct rt_reg_pair BBPRegTable[] = {
+	{BBP_R65, 0x2C},	/* fix rssi issue */
+	{BBP_R66, 0x38},	/* Also set this default value to pAd->BbpTuning.R66CurrentValue at initial */
+	{BBP_R69, 0x12},
+	{BBP_R70, 0xa},		/* BBP_R70 will change to 0x8 in ApStartUp and LinkUp for rt2860C, otherwise value is 0xa */
+	{BBP_R73, 0x10},
+	{BBP_R81, 0x37},
+	{BBP_R82, 0x62},
+	{BBP_R83, 0x6A},
+	{BBP_R84, 0x99},	/* 0x19 is for rt2860E and after. This is for extension channel overlapping IOT. 0x99 is for rt2860D and before */
+	{BBP_R86, 0x00},	/* middle range issue, Rory @2008-01-28 */
+	{BBP_R91, 0x04},	/* middle range issue, Rory @2008-01-28 */
+	{BBP_R92, 0x00},	/* middle range issue, Rory @2008-01-28 */
+	{BBP_R103, 0x00},	/* near range high-power issue, requested from Gary @2008-0528 */
+	{BBP_R105, 0x05},	/* 0x05 is for rt2860E to turn on FEQ control. It is safe for rt2860D and before, because Bit 7:2 are reserved in rt2860D and before. */
+	{BBP_R106, 0x35},	/* for ShortGI throughput */
 };
-#define	NUM_BBP_REG_PARMS	(sizeof(BBPRegTable) / sizeof(REG_PAIR))
 
-//
-// RF register initialization set
-//
-#ifdef RT2870
-REG_PAIR   RT30xx_RFRegTable[] = {
-        {RF_R04,          0x40},
-        {RF_R05,          0x03},
-        {RF_R06,          0x02},
-        {RF_R07,          0x70},
-        {RF_R09,          0x0F},
-        {RF_R10,          0x41},
-        {RF_R11,          0x21},
-        {RF_R12,          0x7B},
-        {RF_R14,          0x90},
-        {RF_R15,          0x58},
-        {RF_R16,          0xB3},
-        {RF_R17,          0x92},
-        {RF_R18,          0x2C},
-        {RF_R19,          0x02},
-        {RF_R20,          0xBA},
-        {RF_R21,          0xDB},
-        {RF_R24,          0x16},
-        {RF_R25,          0x01},
-        {RF_R29,          0x1F},
-};
-#define	NUM_RF_REG_PARMS	(sizeof(RT30xx_RFRegTable) / sizeof(REG_PAIR))
-#endif // RT2870 //
+#define	NUM_BBP_REG_PARMS	(sizeof(BBPRegTable) / sizeof(struct rt_reg_pair))
 
-//
-// ASIC register initialization sets
-//
+/* */
+/* ASIC register initialization sets */
+/* */
 
-RTMP_REG_PAIR	MACRegTable[] =	{
+struct rt_rtmp_reg_pair MACRegTable[] = {
 #if defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x200)
-	{BCN_OFFSET0,			0xf8f0e8e0}, /* 0x3800(e0), 0x3A00(e8), 0x3C00(f0), 0x3E00(f8), 512B for each beacon */
-	{BCN_OFFSET1,			0x6f77d0c8}, /* 0x3200(c8), 0x3400(d0), 0x1DC0(77), 0x1BC0(6f), 512B for each beacon */
+	{BCN_OFFSET0, 0xf8f0e8e0},	/* 0x3800(e0), 0x3A00(e8), 0x3C00(f0), 0x3E00(f8), 512B for each beacon */
+	{BCN_OFFSET1, 0x6f77d0c8},	/* 0x3200(c8), 0x3400(d0), 0x1DC0(77), 0x1BC0(6f), 512B for each beacon */
 #elif defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x100)
-	{BCN_OFFSET0,			0xece8e4e0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
-	{BCN_OFFSET1,			0xfcf8f4f0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
+	{BCN_OFFSET0, 0xece8e4e0},	/* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
+	{BCN_OFFSET1, 0xfcf8f4f0},	/* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
 #else
-    #error You must re-calculate new value for BCN_OFFSET0 & BCN_OFFSET1 in MACRegTable[]!!!
-#endif // HW_BEACON_OFFSET //
+#error You must re-calculate new value for BCN_OFFSET0 & BCN_OFFSET1 in MACRegTable[]!
+#endif /* HW_BEACON_OFFSET // */
 
-	{LEGACY_BASIC_RATE,		0x0000013f}, //  Basic rate set bitmap
-	{HT_BASIC_RATE,		0x00008003}, // Basic HT rate set , 20M, MCS=3, MM. Format is the same as in TXWI.
-	{MAC_SYS_CTRL,		0x00}, // 0x1004, , default Disable RX
-	{RX_FILTR_CFG,		0x17f97}, //0x1400  , RX filter control,
-	{BKOFF_SLOT_CFG,	0x209}, // default set short slot time, CC_DELAY_TIME should be 2
-	{TX_SW_CFG0,		0x0}, 		// Gary,2008-05-21 for CWC test
-	{TX_SW_CFG1,		0x80606}, // Gary,2006-08-23
-	{TX_LINK_CFG,		0x1020},		// Gary,2006-08-23
-	{TX_TIMEOUT_CFG,	0x000a2090},	// CCK has some problem. So increase timieout value. 2006-10-09// MArvek RT , Modify for 2860E ,2007-08-01
-	{MAX_LEN_CFG,		MAX_AGGREGATION_SIZE | 0x00001000},	// 0x3018, MAX frame length. Max PSDU = 16kbytes.
-	{LED_CFG,		0x7f031e46}, // Gary, 2006-08-23
-	{PBF_MAX_PCNT,			0x1F3FBF9F}, 	//0x1F3f7f9f},		//Jan, 2006/04/20
-	{TX_RTY_CFG,			0x47d01f0f},	// Jan, 2006/11/16, Set TxWI->ACK =0 in Probe Rsp Modify for 2860E ,2007-08-03
-	{AUTO_RSP_CFG,			0x00000013},	// Initial Auto_Responder, because QA will turn off Auto-Responder
-	{CCK_PROT_CFG,			0x05740003 /*0x01740003*/},	// Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled.
-	{OFDM_PROT_CFG,			0x05740003 /*0x01740003*/},	// Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled.
-//PS packets use Tx1Q (for HCCA) when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
-#ifdef RT2870
-	{PBF_CFG, 				0xf40006}, 		// Only enable Queue 2
-	{MM40_PROT_CFG,			0x3F44084},		// Initial Auto_Responder, because QA will turn off Auto-Responder
-	{WPDMA_GLO_CFG,			0x00000030},
-#endif // RT2870 //
-	{GF20_PROT_CFG,			0x01744004},    // set 19:18 --> Short NAV for MIMO PS
-	{GF40_PROT_CFG,			0x03F44084},
-	{MM20_PROT_CFG,			0x01744004},
-#ifdef RT2860
-	{MM40_PROT_CFG,			0x03F54084},
-#endif
-	{TXOP_CTRL_CFG,			0x0000583f, /*0x0000243f*/ /*0x000024bf*/},	//Extension channel backoff.
-	{TX_RTS_CFG,			0x00092b20},
-	{EXP_ACK_TIME,			0x002400ca},	// default value
-	{TXOP_HLDR_ET, 			0x00000002},
+	{LEGACY_BASIC_RATE, 0x0000013f},	/*  Basic rate set bitmap */
+	{HT_BASIC_RATE, 0x00008003},	/* Basic HT rate set , 20M, MCS=3, MM. Format is the same as in TXWI. */
+	{MAC_SYS_CTRL, 0x00},	/* 0x1004, , default Disable RX */
+	{RX_FILTR_CFG, 0x17f97},	/*0x1400  , RX filter control, */
+	{BKOFF_SLOT_CFG, 0x209},	/* default set short slot time, CC_DELAY_TIME should be 2 */
+	/*{TX_SW_CFG0,          0x40a06}, // Gary,2006-08-23 */
+	{TX_SW_CFG0, 0x0},	/* Gary,2008-05-21 for CWC test */
+	{TX_SW_CFG1, 0x80606},	/* Gary,2006-08-23 */
+	{TX_LINK_CFG, 0x1020},	/* Gary,2006-08-23 */
+	/*{TX_TIMEOUT_CFG,      0x00182090},    // CCK has some problem. So increase timieout value. 2006-10-09// MArvek RT */
+	{TX_TIMEOUT_CFG, 0x000a2090},	/* CCK has some problem. So increase timieout value. 2006-10-09// MArvek RT , Modify for 2860E ,2007-08-01 */
+	{MAX_LEN_CFG, MAX_AGGREGATION_SIZE | 0x00001000},	/* 0x3018, MAX frame length. Max PSDU = 16kbytes. */
+	{LED_CFG, 0x7f031e46},	/* Gary, 2006-08-23 */
+
+	{PBF_MAX_PCNT, 0x1F3FBF9F},	/*0x1F3f7f9f},          //Jan, 2006/04/20 */
+
+	{TX_RTY_CFG, 0x47d01f0f},	/* Jan, 2006/11/16, Set TxWI->ACK =0 in Probe Rsp Modify for 2860E ,2007-08-03 */
+
+	{AUTO_RSP_CFG, 0x00000013},	/* Initial Auto_Responder, because QA will turn off Auto-Responder */
+	{CCK_PROT_CFG, 0x05740003 /*0x01740003 */ },	/* Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled. */
+	{OFDM_PROT_CFG, 0x05740003 /*0x01740003 */ },	/* Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled. */
+#ifdef RTMP_MAC_USB
+	{PBF_CFG, 0xf40006},	/* Only enable Queue 2 */
+	{MM40_PROT_CFG, 0x3F44084},	/* Initial Auto_Responder, because QA will turn off Auto-Responder */
+	{WPDMA_GLO_CFG, 0x00000030},
+#endif /* RTMP_MAC_USB // */
+	{GF20_PROT_CFG, 0x01744004},	/* set 19:18 --> Short NAV for MIMO PS */
+	{GF40_PROT_CFG, 0x03F44084},
+	{MM20_PROT_CFG, 0x01744004},
+#ifdef RTMP_MAC_PCI
+	{MM40_PROT_CFG, 0x03F54084},
+#endif /* RTMP_MAC_PCI // */
+	{TXOP_CTRL_CFG, 0x0000583f, /*0x0000243f *//*0x000024bf */ },	/*Extension channel backoff. */
+	{TX_RTS_CFG, 0x00092b20},
+	{EXP_ACK_TIME, 0x002400ca},	/* default value */
+
+	{TXOP_HLDR_ET, 0x00000002},
 
 	/* Jerry comments 2008/01/16: we use SIFS = 10us in CCK defaultly, but it seems that 10us
-		is too small for INTEL 2200bg card, so in MBSS mode, the delta time between beacon0
-		and beacon1 is SIFS (10us), so if INTEL 2200bg card connects to BSS0, the ping
-		will always lost. So we change the SIFS of CCK from 10us to 16us. */
-	{XIFS_TIME_CFG,			0x33a41010},
-	{PWR_PIN_CFG,			0x00000003},	// patch for 2880-E
+	   is too small for INTEL 2200bg card, so in MBSS mode, the delta time between beacon0
+	   and beacon1 is SIFS (10us), so if INTEL 2200bg card connects to BSS0, the ping
+	   will always lost. So we change the SIFS of CCK from 10us to 16us. */
+	{XIFS_TIME_CFG, 0x33a41010},
+	{PWR_PIN_CFG, 0x00000003},	/* patch for 2880-E */
 };
 
-RTMP_REG_PAIR	STAMACRegTable[] =	{
-	{WMM_AIFSN_CFG,		0x00002273},
-	{WMM_CWMIN_CFG,	0x00002344},
-	{WMM_CWMAX_CFG,	0x000034aa},
+struct rt_rtmp_reg_pair STAMACRegTable[] = {
+	{WMM_AIFSN_CFG, 0x00002273},
+	{WMM_CWMIN_CFG, 0x00002344},
+	{WMM_CWMAX_CFG, 0x000034aa},
 };
 
-#define	NUM_MAC_REG_PARMS		(sizeof(MACRegTable) / sizeof(RTMP_REG_PAIR))
-#define	NUM_STA_MAC_REG_PARMS	(sizeof(STAMACRegTable) / sizeof(RTMP_REG_PAIR))
-
-#ifdef RT2870
-//
-// RT2870 Firmware Spec only used 1 oct for version expression
-//
-#define FIRMWARE_MINOR_VERSION	7
-
-#endif // RT2870 //
-
-// New 8k byte firmware size for RT3071/RT3072
-#define FIRMWAREIMAGE_MAX_LENGTH	0x2000
-#define FIRMWAREIMAGE_LENGTH		(sizeof (FirmwareImage) / sizeof(UCHAR))
-#define FIRMWARE_MAJOR_VERSION	0
-
-#define FIRMWAREIMAGEV1_LENGTH	0x1000
-#define FIRMWAREIMAGEV2_LENGTH	0x1000
-
-#ifdef RT2860
-#define FIRMWARE_MINOR_VERSION	2
-#endif
-
+#define	NUM_MAC_REG_PARMS		(sizeof(MACRegTable) / sizeof(struct rt_rtmp_reg_pair))
+#define	NUM_STA_MAC_REG_PARMS	(sizeof(STAMACRegTable) / sizeof(struct rt_rtmp_reg_pair))
 
 /*
 	========================================================================
 
 	Routine Description:
-		Allocate RTMP_ADAPTER data block and do some initialization
+		Allocate struct rt_rtmp_adapter data block and do some initialization
 
 	Arguments:
 		Adapter		Pointer to our adapter
@@ -213,48 +152,48 @@
 
 	========================================================================
 */
-NDIS_STATUS	RTMPAllocAdapterBlock(
-	IN  PVOID	handle,
-	OUT	PRTMP_ADAPTER	*ppAdapter)
+int RTMPAllocAdapterBlock(void *handle,
+				  struct rt_rtmp_adapter * * ppAdapter)
 {
-	PRTMP_ADAPTER	pAd;
-	NDIS_STATUS		Status;
-	INT 			index;
-	UCHAR			*pBeaconBuf = NULL;
+	struct rt_rtmp_adapter *pAd;
+	int Status;
+	int index;
+	u8 *pBeaconBuf = NULL;
 
 	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocAdapterBlock\n"));
 
 	*ppAdapter = NULL;
 
-	do
-	{
-		// Allocate RTMP_ADAPTER memory block
+	do {
+		/* Allocate struct rt_rtmp_adapter memory block */
 		pBeaconBuf = kmalloc(MAX_BEACON_SIZE, MEM_ALLOC_FLAG);
-		if (pBeaconBuf == NULL)
-		{
+		if (pBeaconBuf == NULL) {
 			Status = NDIS_STATUS_FAILURE;
 			DBGPRINT_ERR(("Failed to allocate memory - BeaconBuf!\n"));
 			break;
 		}
+		NdisZeroMemory(pBeaconBuf, MAX_BEACON_SIZE);
 
-		Status = AdapterBlockAllocateMemory(handle, (PVOID *)&pAd);
-		if (Status != NDIS_STATUS_SUCCESS)
-		{
+		Status = AdapterBlockAllocateMemory(handle, (void **) & pAd);
+		if (Status != NDIS_STATUS_SUCCESS) {
 			DBGPRINT_ERR(("Failed to allocate memory - ADAPTER\n"));
 			break;
 		}
 		pAd->BeaconBuf = pBeaconBuf;
-		printk("\n\n=== pAd = %p, size = %d ===\n\n", pAd, (UINT32)sizeof(RTMP_ADAPTER));
+		DBGPRINT(RT_DEBUG_OFF,
+			 ("=== pAd = %p, size = %d ===\n", pAd,
+			  (u32)sizeof(struct rt_rtmp_adapter)));
 
-
-		// Init spin locks
+		/* Init spin locks */
 		NdisAllocateSpinLock(&pAd->MgmtRingLock);
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
 		NdisAllocateSpinLock(&pAd->RxRingLock);
-#endif
+#ifdef RT3090
+		NdisAllocateSpinLock(&pAd->McuCmdLock);
+#endif /* RT3090 // */
+#endif /* RTMP_MAC_PCI // */
 
-		for (index =0 ; index < NUM_OF_TX_RING; index++)
-		{
+		for (index = 0; index < NUM_OF_TX_RING; index++) {
 			NdisAllocateSpinLock(&pAd->TxSwQueueLock[index]);
 			NdisAllocateSpinLock(&pAd->DeQueueLock[index]);
 			pAd->DeQueueRunning[index] = FALSE;
@@ -291,518 +230,199 @@
 
 	========================================================================
 */
-VOID	RTMPReadTxPwrPerRate(
-	IN	PRTMP_ADAPTER	pAd)
+void RTMPReadTxPwrPerRate(struct rt_rtmp_adapter *pAd)
 {
-	ULONG		data, Adata, Gdata;
-	USHORT		i, value, value2;
-	INT			Apwrdelta, Gpwrdelta;
-	UCHAR		t1,t2,t3,t4;
-	BOOLEAN		bValid, bApwrdeltaMinus = TRUE, bGpwrdeltaMinus = TRUE;
+	unsigned long data, Adata, Gdata;
+	u16 i, value, value2;
+	int Apwrdelta, Gpwrdelta;
+	u8 t1, t2, t3, t4;
+	BOOLEAN bApwrdeltaMinus = TRUE, bGpwrdeltaMinus = TRUE;
 
-	//
-	// Get power delta for 20MHz and 40MHz.
-	//
+	/* */
+	/* Get power delta for 20MHz and 40MHz. */
+	/* */
 	DBGPRINT(RT_DEBUG_TRACE, ("Txpower per Rate\n"));
 	RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_DELTA, value2);
 	Apwrdelta = 0;
 	Gpwrdelta = 0;
 
-	if ((value2 & 0xff) != 0xff)
-	{
+	if ((value2 & 0xff) != 0xff) {
 		if ((value2 & 0x80))
-			Gpwrdelta = (value2&0xf);
+			Gpwrdelta = (value2 & 0xf);
 
 		if ((value2 & 0x40))
 			bGpwrdeltaMinus = FALSE;
 		else
 			bGpwrdeltaMinus = TRUE;
 	}
-	if ((value2 & 0xff00) != 0xff00)
-	{
+	if ((value2 & 0xff00) != 0xff00) {
 		if ((value2 & 0x8000))
-			Apwrdelta = ((value2&0xf00)>>8);
+			Apwrdelta = ((value2 & 0xf00) >> 8);
 
 		if ((value2 & 0x4000))
 			bApwrdeltaMinus = FALSE;
 		else
 			bApwrdeltaMinus = TRUE;
 	}
-	DBGPRINT(RT_DEBUG_TRACE, ("Gpwrdelta = %x, Apwrdelta = %x .\n", Gpwrdelta, Apwrdelta));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("Gpwrdelta = %x, Apwrdelta = %x .\n", Gpwrdelta, Apwrdelta));
 
-	//
-	// Get Txpower per MCS for 20MHz in 2.4G.
-	//
-	for (i=0; i<5; i++)
-	{
-		RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i*4, value);
+	/* */
+	/* Get Txpower per MCS for 20MHz in 2.4G. */
+	/* */
+	for (i = 0; i < 5; i++) {
+		RT28xx_EEPROM_READ16(pAd,
+				     EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i * 4,
+				     value);
 		data = value;
-		if (bApwrdeltaMinus == FALSE)
-		{
-			t1 = (value&0xf)+(Apwrdelta);
+		if (bApwrdeltaMinus == FALSE) {
+			t1 = (value & 0xf) + (Apwrdelta);
 			if (t1 > 0xf)
 				t1 = 0xf;
-			t2 = ((value&0xf0)>>4)+(Apwrdelta);
+			t2 = ((value & 0xf0) >> 4) + (Apwrdelta);
 			if (t2 > 0xf)
 				t2 = 0xf;
-			t3 = ((value&0xf00)>>8)+(Apwrdelta);
+			t3 = ((value & 0xf00) >> 8) + (Apwrdelta);
 			if (t3 > 0xf)
 				t3 = 0xf;
-			t4 = ((value&0xf000)>>12)+(Apwrdelta);
+			t4 = ((value & 0xf000) >> 12) + (Apwrdelta);
 			if (t4 > 0xf)
 				t4 = 0xf;
-		}
-		else
-		{
-			if ((value&0xf) > Apwrdelta)
-				t1 = (value&0xf)-(Apwrdelta);
+		} else {
+			if ((value & 0xf) > Apwrdelta)
+				t1 = (value & 0xf) - (Apwrdelta);
 			else
 				t1 = 0;
-			if (((value&0xf0)>>4) > Apwrdelta)
-				t2 = ((value&0xf0)>>4)-(Apwrdelta);
+			if (((value & 0xf0) >> 4) > Apwrdelta)
+				t2 = ((value & 0xf0) >> 4) - (Apwrdelta);
 			else
 				t2 = 0;
-			if (((value&0xf00)>>8) > Apwrdelta)
-				t3 = ((value&0xf00)>>8)-(Apwrdelta);
+			if (((value & 0xf00) >> 8) > Apwrdelta)
+				t3 = ((value & 0xf00) >> 8) - (Apwrdelta);
 			else
 				t3 = 0;
-			if (((value&0xf000)>>12) > Apwrdelta)
-				t4 = ((value&0xf000)>>12)-(Apwrdelta);
+			if (((value & 0xf000) >> 12) > Apwrdelta)
+				t4 = ((value & 0xf000) >> 12) - (Apwrdelta);
 			else
 				t4 = 0;
 		}
-		Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
-		if (bGpwrdeltaMinus == FALSE)
-		{
-			t1 = (value&0xf)+(Gpwrdelta);
+		Adata = t1 + (t2 << 4) + (t3 << 8) + (t4 << 12);
+		if (bGpwrdeltaMinus == FALSE) {
+			t1 = (value & 0xf) + (Gpwrdelta);
 			if (t1 > 0xf)
 				t1 = 0xf;
-			t2 = ((value&0xf0)>>4)+(Gpwrdelta);
+			t2 = ((value & 0xf0) >> 4) + (Gpwrdelta);
 			if (t2 > 0xf)
 				t2 = 0xf;
-			t3 = ((value&0xf00)>>8)+(Gpwrdelta);
+			t3 = ((value & 0xf00) >> 8) + (Gpwrdelta);
 			if (t3 > 0xf)
 				t3 = 0xf;
-			t4 = ((value&0xf000)>>12)+(Gpwrdelta);
+			t4 = ((value & 0xf000) >> 12) + (Gpwrdelta);
 			if (t4 > 0xf)
 				t4 = 0xf;
-		}
-		else
-		{
-			if ((value&0xf) > Gpwrdelta)
-				t1 = (value&0xf)-(Gpwrdelta);
+		} else {
+			if ((value & 0xf) > Gpwrdelta)
+				t1 = (value & 0xf) - (Gpwrdelta);
 			else
 				t1 = 0;
-			if (((value&0xf0)>>4) > Gpwrdelta)
-				t2 = ((value&0xf0)>>4)-(Gpwrdelta);
+			if (((value & 0xf0) >> 4) > Gpwrdelta)
+				t2 = ((value & 0xf0) >> 4) - (Gpwrdelta);
 			else
 				t2 = 0;
-			if (((value&0xf00)>>8) > Gpwrdelta)
-				t3 = ((value&0xf00)>>8)-(Gpwrdelta);
+			if (((value & 0xf00) >> 8) > Gpwrdelta)
+				t3 = ((value & 0xf00) >> 8) - (Gpwrdelta);
 			else
 				t3 = 0;
-			if (((value&0xf000)>>12) > Gpwrdelta)
-				t4 = ((value&0xf000)>>12)-(Gpwrdelta);
+			if (((value & 0xf000) >> 12) > Gpwrdelta)
+				t4 = ((value & 0xf000) >> 12) - (Gpwrdelta);
 			else
 				t4 = 0;
 		}
-		Gdata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
+		Gdata = t1 + (t2 << 4) + (t3 << 8) + (t4 << 12);
 
-		RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i*4 + 2, value);
-		if (bApwrdeltaMinus == FALSE)
-		{
-			t1 = (value&0xf)+(Apwrdelta);
+		RT28xx_EEPROM_READ16(pAd,
+				     EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i * 4 +
+				     2, value);
+		if (bApwrdeltaMinus == FALSE) {
+			t1 = (value & 0xf) + (Apwrdelta);
 			if (t1 > 0xf)
 				t1 = 0xf;
-			t2 = ((value&0xf0)>>4)+(Apwrdelta);
+			t2 = ((value & 0xf0) >> 4) + (Apwrdelta);
 			if (t2 > 0xf)
 				t2 = 0xf;
-			t3 = ((value&0xf00)>>8)+(Apwrdelta);
+			t3 = ((value & 0xf00) >> 8) + (Apwrdelta);
 			if (t3 > 0xf)
 				t3 = 0xf;
-			t4 = ((value&0xf000)>>12)+(Apwrdelta);
+			t4 = ((value & 0xf000) >> 12) + (Apwrdelta);
 			if (t4 > 0xf)
 				t4 = 0xf;
-		}
-		else
-		{
-			if ((value&0xf) > Apwrdelta)
-				t1 = (value&0xf)-(Apwrdelta);
+		} else {
+			if ((value & 0xf) > Apwrdelta)
+				t1 = (value & 0xf) - (Apwrdelta);
 			else
 				t1 = 0;
-			if (((value&0xf0)>>4) > Apwrdelta)
-				t2 = ((value&0xf0)>>4)-(Apwrdelta);
+			if (((value & 0xf0) >> 4) > Apwrdelta)
+				t2 = ((value & 0xf0) >> 4) - (Apwrdelta);
 			else
 				t2 = 0;
-			if (((value&0xf00)>>8) > Apwrdelta)
-				t3 = ((value&0xf00)>>8)-(Apwrdelta);
+			if (((value & 0xf00) >> 8) > Apwrdelta)
+				t3 = ((value & 0xf00) >> 8) - (Apwrdelta);
 			else
 				t3 = 0;
-			if (((value&0xf000)>>12) > Apwrdelta)
-				t4 = ((value&0xf000)>>12)-(Apwrdelta);
+			if (((value & 0xf000) >> 12) > Apwrdelta)
+				t4 = ((value & 0xf000) >> 12) - (Apwrdelta);
 			else
 				t4 = 0;
 		}
-		Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
-		if (bGpwrdeltaMinus == FALSE)
-		{
-			t1 = (value&0xf)+(Gpwrdelta);
+		Adata |= ((t1 << 16) + (t2 << 20) + (t3 << 24) + (t4 << 28));
+		if (bGpwrdeltaMinus == FALSE) {
+			t1 = (value & 0xf) + (Gpwrdelta);
 			if (t1 > 0xf)
 				t1 = 0xf;
-			t2 = ((value&0xf0)>>4)+(Gpwrdelta);
+			t2 = ((value & 0xf0) >> 4) + (Gpwrdelta);
 			if (t2 > 0xf)
 				t2 = 0xf;
-			t3 = ((value&0xf00)>>8)+(Gpwrdelta);
+			t3 = ((value & 0xf00) >> 8) + (Gpwrdelta);
 			if (t3 > 0xf)
 				t3 = 0xf;
-			t4 = ((value&0xf000)>>12)+(Gpwrdelta);
+			t4 = ((value & 0xf000) >> 12) + (Gpwrdelta);
 			if (t4 > 0xf)
 				t4 = 0xf;
-		}
-		else
-		{
-			if ((value&0xf) > Gpwrdelta)
-				t1 = (value&0xf)-(Gpwrdelta);
+		} else {
+			if ((value & 0xf) > Gpwrdelta)
+				t1 = (value & 0xf) - (Gpwrdelta);
 			else
 				t1 = 0;
-			if (((value&0xf0)>>4) > Gpwrdelta)
-				t2 = ((value&0xf0)>>4)-(Gpwrdelta);
+			if (((value & 0xf0) >> 4) > Gpwrdelta)
+				t2 = ((value & 0xf0) >> 4) - (Gpwrdelta);
 			else
 				t2 = 0;
-			if (((value&0xf00)>>8) > Gpwrdelta)
-				t3 = ((value&0xf00)>>8)-(Gpwrdelta);
+			if (((value & 0xf00) >> 8) > Gpwrdelta)
+				t3 = ((value & 0xf00) >> 8) - (Gpwrdelta);
 			else
 				t3 = 0;
-			if (((value&0xf000)>>12) > Gpwrdelta)
-				t4 = ((value&0xf000)>>12)-(Gpwrdelta);
+			if (((value & 0xf000) >> 12) > Gpwrdelta)
+				t4 = ((value & 0xf000) >> 12) - (Gpwrdelta);
 			else
 				t4 = 0;
 		}
-		Gdata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
-		data |= (value<<16);
+		Gdata |= ((t1 << 16) + (t2 << 20) + (t3 << 24) + (t4 << 28));
+		data |= (value << 16);
 
-		pAd->Tx20MPwrCfgABand[i] = pAd->Tx40MPwrCfgABand[i] = Adata;
-		pAd->Tx20MPwrCfgGBand[i] = pAd->Tx40MPwrCfgGBand[i] = Gdata;
+		/* For 20M/40M Power Delta issue */
+		pAd->Tx20MPwrCfgABand[i] = data;
+		pAd->Tx20MPwrCfgGBand[i] = data;
+		pAd->Tx40MPwrCfgABand[i] = Adata;
+		pAd->Tx40MPwrCfgGBand[i] = Gdata;
 
 		if (data != 0xffffffff)
-			RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, data);
-		DBGPRINT_RAW(RT_DEBUG_TRACE, ("20MHz BW, 2.4G band-%lx,  Adata = %lx,  Gdata = %lx \n", data, Adata, Gdata));
-	}
-
-	//
-	// Check this block is valid for 40MHz in 2.4G. If invalid, use parameter for 20MHz in 2.4G
-	//
-	bValid = TRUE;
-	for (i=0; i<6; i++)
-	{
-		RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + 2 + i*2, value);
-		if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
-		{
-			bValid = FALSE;
-			break;
-		}
-	}
-
-	//
-	// Get Txpower per MCS for 40MHz in 2.4G.
-	//
-	if (bValid)
-	{
-		for (i=0; i<4; i++)
-		{
-			RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + i*4, value);
-			if (bGpwrdeltaMinus == FALSE)
-			{
-				t1 = (value&0xf)+(Gpwrdelta);
-				if (t1 > 0xf)
-					t1 = 0xf;
-				t2 = ((value&0xf0)>>4)+(Gpwrdelta);
-				if (t2 > 0xf)
-					t2 = 0xf;
-				t3 = ((value&0xf00)>>8)+(Gpwrdelta);
-				if (t3 > 0xf)
-					t3 = 0xf;
-				t4 = ((value&0xf000)>>12)+(Gpwrdelta);
-				if (t4 > 0xf)
-					t4 = 0xf;
-			}
-			else
-			{
-				if ((value&0xf) > Gpwrdelta)
-					t1 = (value&0xf)-(Gpwrdelta);
-				else
-					t1 = 0;
-				if (((value&0xf0)>>4) > Gpwrdelta)
-					t2 = ((value&0xf0)>>4)-(Gpwrdelta);
-				else
-					t2 = 0;
-				if (((value&0xf00)>>8) > Gpwrdelta)
-					t3 = ((value&0xf00)>>8)-(Gpwrdelta);
-				else
-					t3 = 0;
-				if (((value&0xf000)>>12) > Gpwrdelta)
-					t4 = ((value&0xf000)>>12)-(Gpwrdelta);
-				else
-					t4 = 0;
-			}
-			Gdata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
-
-			RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + i*4 + 2, value);
-			if (bGpwrdeltaMinus == FALSE)
-			{
-				t1 = (value&0xf)+(Gpwrdelta);
-				if (t1 > 0xf)
-					t1 = 0xf;
-				t2 = ((value&0xf0)>>4)+(Gpwrdelta);
-				if (t2 > 0xf)
-					t2 = 0xf;
-				t3 = ((value&0xf00)>>8)+(Gpwrdelta);
-				if (t3 > 0xf)
-					t3 = 0xf;
-				t4 = ((value&0xf000)>>12)+(Gpwrdelta);
-				if (t4 > 0xf)
-					t4 = 0xf;
-			}
-			else
-			{
-				if ((value&0xf) > Gpwrdelta)
-					t1 = (value&0xf)-(Gpwrdelta);
-				else
-					t1 = 0;
-				if (((value&0xf0)>>4) > Gpwrdelta)
-					t2 = ((value&0xf0)>>4)-(Gpwrdelta);
-				else
-					t2 = 0;
-				if (((value&0xf00)>>8) > Gpwrdelta)
-					t3 = ((value&0xf00)>>8)-(Gpwrdelta);
-				else
-					t3 = 0;
-				if (((value&0xf000)>>12) > Gpwrdelta)
-					t4 = ((value&0xf000)>>12)-(Gpwrdelta);
-				else
-					t4 = 0;
-			}
-			Gdata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
-
-			if (i == 0)
-				pAd->Tx40MPwrCfgGBand[i+1] = (pAd->Tx40MPwrCfgGBand[i+1] & 0x0000FFFF) | (Gdata & 0xFFFF0000);
-			else
-				pAd->Tx40MPwrCfgGBand[i+1] = Gdata;
-
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("40MHz BW, 2.4G band, Gdata = %lx \n", Gdata));
-		}
-	}
-
-	//
-	// Check this block is valid for 20MHz in 5G. If invalid, use parameter for 20MHz in 2.4G
-	//
-	bValid = TRUE;
-	for (i=0; i<8; i++)
-	{
-		RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + 2 + i*2, value);
-		if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
-		{
-			bValid = FALSE;
-			break;
-		}
-	}
-
-	//
-	// Get Txpower per MCS for 20MHz in 5G.
-	//
-	if (bValid)
-	{
-		for (i=0; i<5; i++)
-		{
-			RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + i*4, value);
-			if (bApwrdeltaMinus == FALSE)
-			{
-				t1 = (value&0xf)+(Apwrdelta);
-				if (t1 > 0xf)
-					t1 = 0xf;
-				t2 = ((value&0xf0)>>4)+(Apwrdelta);
-				if (t2 > 0xf)
-					t2 = 0xf;
-				t3 = ((value&0xf00)>>8)+(Apwrdelta);
-				if (t3 > 0xf)
-					t3 = 0xf;
-				t4 = ((value&0xf000)>>12)+(Apwrdelta);
-				if (t4 > 0xf)
-					t4 = 0xf;
-			}
-			else
-			{
-				if ((value&0xf) > Apwrdelta)
-					t1 = (value&0xf)-(Apwrdelta);
-				else
-					t1 = 0;
-				if (((value&0xf0)>>4) > Apwrdelta)
-					t2 = ((value&0xf0)>>4)-(Apwrdelta);
-				else
-					t2 = 0;
-				if (((value&0xf00)>>8) > Apwrdelta)
-					t3 = ((value&0xf00)>>8)-(Apwrdelta);
-				else
-					t3 = 0;
-				if (((value&0xf000)>>12) > Apwrdelta)
-					t4 = ((value&0xf000)>>12)-(Apwrdelta);
-				else
-					t4 = 0;
-			}
-			Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
-
-			RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + i*4 + 2, value);
-			if (bApwrdeltaMinus == FALSE)
-			{
-				t1 = (value&0xf)+(Apwrdelta);
-				if (t1 > 0xf)
-					t1 = 0xf;
-				t2 = ((value&0xf0)>>4)+(Apwrdelta);
-				if (t2 > 0xf)
-					t2 = 0xf;
-				t3 = ((value&0xf00)>>8)+(Apwrdelta);
-				if (t3 > 0xf)
-					t3 = 0xf;
-				t4 = ((value&0xf000)>>12)+(Apwrdelta);
-				if (t4 > 0xf)
-					t4 = 0xf;
-			}
-			else
-			{
-				if ((value&0xf) > Apwrdelta)
-					t1 = (value&0xf)-(Apwrdelta);
-				else
-					t1 = 0;
-				if (((value&0xf0)>>4) > Apwrdelta)
-					t2 = ((value&0xf0)>>4)-(Apwrdelta);
-				else
-					t2 = 0;
-				if (((value&0xf00)>>8) > Apwrdelta)
-					t3 = ((value&0xf00)>>8)-(Apwrdelta);
-				else
-					t3 = 0;
-				if (((value&0xf000)>>12) > Apwrdelta)
-					t4 = ((value&0xf000)>>12)-(Apwrdelta);
-				else
-					t4 = 0;
-			}
-			Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
-
-			if (i == 0)
-				pAd->Tx20MPwrCfgABand[i] = (pAd->Tx20MPwrCfgABand[i] & 0x0000FFFF) | (Adata & 0xFFFF0000);
-			else
-				pAd->Tx20MPwrCfgABand[i] = Adata;
-
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("20MHz BW, 5GHz band, Adata = %lx \n", Adata));
-		}
-	}
-
-	//
-	// Check this block is valid for 40MHz in 5G. If invalid, use parameter for 20MHz in 2.4G
-	//
-	bValid = TRUE;
-	for (i=0; i<6; i++)
-	{
-		RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + 2 + i*2, value);
-		if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
-		{
-			bValid = FALSE;
-			break;
-		}
-	}
-
-	//
-	// Get Txpower per MCS for 40MHz in 5G.
-	//
-	if (bValid)
-	{
-		for (i=0; i<4; i++)
-		{
-			RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + i*4, value);
-			if (bApwrdeltaMinus == FALSE)
-			{
-				t1 = (value&0xf)+(Apwrdelta);
-				if (t1 > 0xf)
-					t1 = 0xf;
-				t2 = ((value&0xf0)>>4)+(Apwrdelta);
-				if (t2 > 0xf)
-					t2 = 0xf;
-				t3 = ((value&0xf00)>>8)+(Apwrdelta);
-				if (t3 > 0xf)
-					t3 = 0xf;
-				t4 = ((value&0xf000)>>12)+(Apwrdelta);
-				if (t4 > 0xf)
-					t4 = 0xf;
-			}
-			else
-			{
-				if ((value&0xf) > Apwrdelta)
-					t1 = (value&0xf)-(Apwrdelta);
-				else
-					t1 = 0;
-				if (((value&0xf0)>>4) > Apwrdelta)
-					t2 = ((value&0xf0)>>4)-(Apwrdelta);
-				else
-					t2 = 0;
-				if (((value&0xf00)>>8) > Apwrdelta)
-					t3 = ((value&0xf00)>>8)-(Apwrdelta);
-				else
-					t3 = 0;
-				if (((value&0xf000)>>12) > Apwrdelta)
-					t4 = ((value&0xf000)>>12)-(Apwrdelta);
-				else
-					t4 = 0;
-			}
-			Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
-
-			RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + i*4 + 2, value);
-			if (bApwrdeltaMinus == FALSE)
-			{
-				t1 = (value&0xf)+(Apwrdelta);
-				if (t1 > 0xf)
-					t1 = 0xf;
-				t2 = ((value&0xf0)>>4)+(Apwrdelta);
-				if (t2 > 0xf)
-					t2 = 0xf;
-				t3 = ((value&0xf00)>>8)+(Apwrdelta);
-				if (t3 > 0xf)
-					t3 = 0xf;
-				t4 = ((value&0xf000)>>12)+(Apwrdelta);
-				if (t4 > 0xf)
-					t4 = 0xf;
-			}
-			else
-			{
-				if ((value&0xf) > Apwrdelta)
-					t1 = (value&0xf)-(Apwrdelta);
-				else
-					t1 = 0;
-				if (((value&0xf0)>>4) > Apwrdelta)
-					t2 = ((value&0xf0)>>4)-(Apwrdelta);
-				else
-					t2 = 0;
-				if (((value&0xf00)>>8) > Apwrdelta)
-					t3 = ((value&0xf00)>>8)-(Apwrdelta);
-				else
-					t3 = 0;
-				if (((value&0xf000)>>12) > Apwrdelta)
-					t4 = ((value&0xf000)>>12)-(Apwrdelta);
-				else
-					t4 = 0;
-			}
-			Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
-
-			if (i == 0)
-				pAd->Tx40MPwrCfgABand[i+1] = (pAd->Tx40MPwrCfgABand[i+1] & 0x0000FFFF) | (Adata & 0xFFFF0000);
-			else
-				pAd->Tx40MPwrCfgABand[i+1] = Adata;
-
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("40MHz BW, 5GHz band, Adata = %lx \n", Adata));
-		}
+			RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i * 4, data);
+		DBGPRINT_RAW(RT_DEBUG_TRACE,
+			     ("20MHz BW, 2.4G band-%lx,  Adata = %lx,  Gdata = %lx \n",
+			      data, Adata, Gdata));
 	}
 }
 
-
 /*
 	========================================================================
 
@@ -821,23 +441,23 @@
 
 	========================================================================
 */
-VOID	RTMPReadChannelPwr(
-	IN	PRTMP_ADAPTER	pAd)
+void RTMPReadChannelPwr(struct rt_rtmp_adapter *pAd)
 {
-	UCHAR				i, choffset;
-	EEPROM_TX_PWR_STRUC	    Power;
-	EEPROM_TX_PWR_STRUC	    Power2;
+	u8 i, choffset;
+	EEPROM_TX_PWR_STRUC Power;
+	EEPROM_TX_PWR_STRUC Power2;
 
-	// Read Tx power value for all channels
-	// Value from 1 - 0x7f. Default value is 24.
-	// Power value : 2.4G 0x00 (0) ~ 0x1F (31)
-	//             : 5.5G 0xF9 (-7) ~ 0x0F (15)
+	/* Read Tx power value for all channels */
+	/* Value from 1 - 0x7f. Default value is 24. */
+	/* Power value : 2.4G 0x00 (0) ~ 0x1F (31) */
+	/*             : 5.5G 0xF9 (-7) ~ 0x0F (15) */
 
-	// 0. 11b/g, ch1 - ch 14
-	for (i = 0; i < 7; i++)
-	{
-		RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX_PWR_OFFSET + i * 2, Power.word);
-		RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX2_PWR_OFFSET + i * 2, Power2.word);
+	/* 0. 11b/g, ch1 - ch 14 */
+	for (i = 0; i < 7; i++) {
+		RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX_PWR_OFFSET + i * 2,
+				     Power.word);
+		RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX2_PWR_OFFSET + i * 2,
+				     Power2.word);
 		pAd->TxPower[i * 2].Channel = i * 2 + 1;
 		pAd->TxPower[i * 2 + 1].Channel = i * 2 + 2;
 
@@ -862,125 +482,149 @@
 			pAd->TxPower[i * 2 + 1].Power2 = Power2.field.Byte1;
 	}
 
-	// 1. U-NII lower/middle band: 36, 38, 40; 44, 46, 48; 52, 54, 56; 60, 62, 64 (including central frequency in BW 40MHz)
-	// 1.1 Fill up channel
+	/* 1. U-NII lower/middle band: 36, 38, 40; 44, 46, 48; 52, 54, 56; 60, 62, 64 (including central frequency in BW 40MHz) */
+	/* 1.1 Fill up channel */
 	choffset = 14;
-	for (i = 0; i < 4; i++)
-	{
-		pAd->TxPower[3 * i + choffset + 0].Channel	= 36 + i * 8 + 0;
-		pAd->TxPower[3 * i + choffset + 0].Power	= DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 0].Power2	= DEFAULT_RF_TX_POWER;
+	for (i = 0; i < 4; i++) {
+		pAd->TxPower[3 * i + choffset + 0].Channel = 36 + i * 8 + 0;
+		pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
 
-		pAd->TxPower[3 * i + choffset + 1].Channel	= 36 + i * 8 + 2;
-		pAd->TxPower[3 * i + choffset + 1].Power	= DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 1].Power2	= DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 1].Channel = 36 + i * 8 + 2;
+		pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
 
-		pAd->TxPower[3 * i + choffset + 2].Channel	= 36 + i * 8 + 4;
-		pAd->TxPower[3 * i + choffset + 2].Power	= DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 2].Power2	= DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 2].Channel = 36 + i * 8 + 4;
+		pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
 	}
 
-	// 1.2 Fill up power
-	for (i = 0; i < 6; i++)
-	{
-		RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + i * 2, Power.word);
-		RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + i * 2, Power2.word);
+	/* 1.2 Fill up power */
+	for (i = 0; i < 6; i++) {
+		RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + i * 2,
+				     Power.word);
+		RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + i * 2,
+				     Power2.word);
 
 		if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
-			pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0;
+			pAd->TxPower[i * 2 + choffset + 0].Power =
+			    Power.field.Byte0;
 
 		if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
-			pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1;
+			pAd->TxPower[i * 2 + choffset + 1].Power =
+			    Power.field.Byte1;
 
 		if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
-			pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0;
+			pAd->TxPower[i * 2 + choffset + 0].Power2 =
+			    Power2.field.Byte0;
 
 		if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
-			pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
+			pAd->TxPower[i * 2 + choffset + 1].Power2 =
+			    Power2.field.Byte1;
 	}
 
-	// 2. HipperLAN 2 100, 102 ,104; 108, 110, 112; 116, 118, 120; 124, 126, 128; 132, 134, 136; 140 (including central frequency in BW 40MHz)
-	// 2.1 Fill up channel
+	/* 2. HipperLAN 2 100, 102 ,104; 108, 110, 112; 116, 118, 120; 124, 126, 128; 132, 134, 136; 140 (including central frequency in BW 40MHz) */
+	/* 2.1 Fill up channel */
 	choffset = 14 + 12;
-	for (i = 0; i < 5; i++)
-	{
-		pAd->TxPower[3 * i + choffset + 0].Channel	= 100 + i * 8 + 0;
-		pAd->TxPower[3 * i + choffset + 0].Power	= DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 0].Power2	= DEFAULT_RF_TX_POWER;
+	for (i = 0; i < 5; i++) {
+		pAd->TxPower[3 * i + choffset + 0].Channel = 100 + i * 8 + 0;
+		pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
 
-		pAd->TxPower[3 * i + choffset + 1].Channel	= 100 + i * 8 + 2;
-		pAd->TxPower[3 * i + choffset + 1].Power	= DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 1].Power2	= DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 1].Channel = 100 + i * 8 + 2;
+		pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
 
-		pAd->TxPower[3 * i + choffset + 2].Channel	= 100 + i * 8 + 4;
-		pAd->TxPower[3 * i + choffset + 2].Power	= DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 2].Power2	= DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 2].Channel = 100 + i * 8 + 4;
+		pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
 	}
-	pAd->TxPower[3 * 5 + choffset + 0].Channel		= 140;
-	pAd->TxPower[3 * 5 + choffset + 0].Power		= DEFAULT_RF_TX_POWER;
-	pAd->TxPower[3 * 5 + choffset + 0].Power2		= DEFAULT_RF_TX_POWER;
+	pAd->TxPower[3 * 5 + choffset + 0].Channel = 140;
+	pAd->TxPower[3 * 5 + choffset + 0].Power = DEFAULT_RF_TX_POWER;
+	pAd->TxPower[3 * 5 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
 
-	// 2.2 Fill up power
-	for (i = 0; i < 8; i++)
-	{
-		RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2, Power.word);
-		RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2, Power2.word);
+	/* 2.2 Fill up power */
+	for (i = 0; i < 8; i++) {
+		RT28xx_EEPROM_READ16(pAd,
+				     EEPROM_A_TX_PWR_OFFSET + (choffset - 14) +
+				     i * 2, Power.word);
+		RT28xx_EEPROM_READ16(pAd,
+				     EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) +
+				     i * 2, Power2.word);
 
 		if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
-			pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0;
+			pAd->TxPower[i * 2 + choffset + 0].Power =
+			    Power.field.Byte0;
 
 		if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
-			pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1;
+			pAd->TxPower[i * 2 + choffset + 1].Power =
+			    Power.field.Byte1;
 
 		if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
-			pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0;
+			pAd->TxPower[i * 2 + choffset + 0].Power2 =
+			    Power2.field.Byte0;
 
 		if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
-			pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
+			pAd->TxPower[i * 2 + choffset + 1].Power2 =
+			    Power2.field.Byte1;
 	}
 
-	// 3. U-NII upper band: 149, 151, 153; 157, 159, 161; 165 (including central frequency in BW 40MHz)
-	// 3.1 Fill up channel
+	/* 3. U-NII upper band: 149, 151, 153; 157, 159, 161; 165, 167, 169; 171, 173 (including central frequency in BW 40MHz) */
+	/* 3.1 Fill up channel */
 	choffset = 14 + 12 + 16;
-	for (i = 0; i < 2; i++)
-	{
-		pAd->TxPower[3 * i + choffset + 0].Channel	= 149 + i * 8 + 0;
-		pAd->TxPower[3 * i + choffset + 0].Power	= DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 0].Power2	= DEFAULT_RF_TX_POWER;
+	/*for (i = 0; i < 2; i++) */
+	for (i = 0; i < 3; i++) {
+		pAd->TxPower[3 * i + choffset + 0].Channel = 149 + i * 8 + 0;
+		pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
 
-		pAd->TxPower[3 * i + choffset + 1].Channel	= 149 + i * 8 + 2;
-		pAd->TxPower[3 * i + choffset + 1].Power	= DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 1].Power2	= DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 1].Channel = 149 + i * 8 + 2;
+		pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
 
-		pAd->TxPower[3 * i + choffset + 2].Channel	= 149 + i * 8 + 4;
-		pAd->TxPower[3 * i + choffset + 2].Power	= DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 2].Power2	= DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 2].Channel = 149 + i * 8 + 4;
+		pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
 	}
-	pAd->TxPower[3 * 2 + choffset + 0].Channel		= 165;
-	pAd->TxPower[3 * 2 + choffset + 0].Power		= DEFAULT_RF_TX_POWER;
-	pAd->TxPower[3 * 2 + choffset + 0].Power2		= DEFAULT_RF_TX_POWER;
+	pAd->TxPower[3 * 3 + choffset + 0].Channel = 171;
+	pAd->TxPower[3 * 3 + choffset + 0].Power = DEFAULT_RF_TX_POWER;
+	pAd->TxPower[3 * 3 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
 
-	// 3.2 Fill up power
-	for (i = 0; i < 4; i++)
-	{
-		RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2, Power.word);
-		RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2, Power2.word);
+	pAd->TxPower[3 * 3 + choffset + 1].Channel = 173;
+	pAd->TxPower[3 * 3 + choffset + 1].Power = DEFAULT_RF_TX_POWER;
+	pAd->TxPower[3 * 3 + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
+
+	/* 3.2 Fill up power */
+	/*for (i = 0; i < 4; i++) */
+	for (i = 0; i < 6; i++) {
+		RT28xx_EEPROM_READ16(pAd,
+				     EEPROM_A_TX_PWR_OFFSET + (choffset - 14) +
+				     i * 2, Power.word);
+		RT28xx_EEPROM_READ16(pAd,
+				     EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) +
+				     i * 2, Power2.word);
 
 		if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
-			pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0;
+			pAd->TxPower[i * 2 + choffset + 0].Power =
+			    Power.field.Byte0;
 
 		if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
-			pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1;
+			pAd->TxPower[i * 2 + choffset + 1].Power =
+			    Power.field.Byte1;
 
 		if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
-			pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0;
+			pAd->TxPower[i * 2 + choffset + 0].Power2 =
+			    Power2.field.Byte0;
 
 		if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
-			pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
+			pAd->TxPower[i * 2 + choffset + 1].Power2 =
+			    Power2.field.Byte1;
 	}
 
-	// 4. Print and Debug
-	choffset = 14 + 12 + 16 + 7;
+	/* 4. Print and Debug */
+	/*choffset = 14 + 12 + 16 + 7; */
+	choffset = 14 + 12 + 16 + 11;
+
 }
 
 /*
@@ -1006,278 +650,14 @@
 
 	========================================================================
 */
-NDIS_STATUS	NICReadRegParameters(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	NDIS_HANDLE			WrapperConfigurationContext
-	)
+int NICReadRegParameters(struct rt_rtmp_adapter *pAd,
+				 void *WrapperConfigurationContext)
 {
-	NDIS_STATUS						Status = NDIS_STATUS_SUCCESS;
+	int Status = NDIS_STATUS_SUCCESS;
 	DBGPRINT_S(Status, ("<-- NICReadRegParameters, Status=%x\n", Status));
 	return Status;
 }
 
-
-#ifdef RT2870
-/*
-	========================================================================
-
-	Routine Description:
-		For RF filter calibration purpose
-
-	Arguments:
-		pAd                          Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	========================================================================
-*/
-VOID RTMPFilterCalibration(
-	IN PRTMP_ADAPTER pAd)
-{
-	UCHAR	R55x = 0, value, FilterTarget = 0x1E, BBPValue=0;
-	UINT	loop = 0, count = 0, loopcnt = 0, ReTry = 0;
-	UCHAR	RF_R24_Value = 0;
-
-	// Give bbp filter initial value
-#ifndef RT2870
-	pAd->Mlme.CaliBW20RfR24 = 0x16;
-	pAd->Mlme.CaliBW40RfR24 = 0x36;  //Bit[5] must be 1 for BW 40
-#else
-	pAd->Mlme.CaliBW20RfR24 = 0x1F;
-	pAd->Mlme.CaliBW40RfR24 = 0x2F; //Bit[5] must be 1 for BW 40
-#endif
-	do
-	{
-		if (loop == 1)	//BandWidth = 40 MHz
-		{
-			// Write 0x27 to RF_R24 to program filter
-			RF_R24_Value = 0x27;
-			RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
-			if (IS_RT3090(pAd))
-				FilterTarget = 0x15;
-			else
-				FilterTarget = 0x19;
-
-			// when calibrate BW40, BBP mask must set to BW40.
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-			BBPValue&= (~0x18);
-			BBPValue|= (0x10);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-#ifdef RT2870
-			// set to BW40
-			RT30xxReadRFRegister(pAd, RF_R31, &value);
-			value |= 0x20;
-			RT30xxWriteRFRegister(pAd, RF_R31, value);
-#endif
-		}
-		else			//BandWidth = 20 MHz
-		{
-			// Write 0x07 to RF_R24 to program filter
-			RF_R24_Value = 0x07;
-			RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
-			if (IS_RT3090(pAd))
-				FilterTarget = 0x13;
-			else
-				FilterTarget = 0x16;
-#ifdef RT2870
-			// set to BW20
-			RT30xxReadRFRegister(pAd, RF_R31, &value);
-			value &= (~0x20);
-			RT30xxWriteRFRegister(pAd, RF_R31, value);
-#endif
-		}
-
-		// Write 0x01 to RF_R22 to enable baseband loopback mode
-		RT30xxReadRFRegister(pAd, RF_R22, &value);
-		value |= 0x01;
-		RT30xxWriteRFRegister(pAd, RF_R22, value);
-
-		// Write 0x00 to BBP_R24 to set power & frequency of passband test tone
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
-
-		do
-		{
-			// Write 0x90 to BBP_R25 to transmit test tone
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
-
-			RTMPusecDelay(1000);
-			// Read BBP_R55[6:0] for received power, set R55x = BBP_R55[6:0]
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
-			R55x = value & 0xFF;
-
-		} while ((ReTry++ < 100) && (R55x == 0));
-
-		// Write 0x06 to BBP_R24 to set power & frequency of stopband test tone
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0x06);
-
-		while(TRUE)
-		{
-			// Write 0x90 to BBP_R25 to transmit test tone
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
-
-			//We need to wait for calibration
-			RTMPusecDelay(1000);
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
-			value &= 0xFF;
-			if ((R55x - value) < FilterTarget)
-			{
-				RF_R24_Value ++;
-			}
-			else if ((R55x - value) == FilterTarget)
-			{
-				RF_R24_Value ++;
-				count ++;
-			}
-			else
-			{
-				break;
-			}
-
-			// prevent infinite loop cause driver hang.
-			if (loopcnt++ > 100)
-			{
-				DBGPRINT(RT_DEBUG_ERROR, ("RTMPFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating", loopcnt));
-				break;
-			}
-
-			// Write RF_R24 to program filter
-			RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
-		}
-
-		if (count > 0)
-		{
-			RF_R24_Value = RF_R24_Value - ((count) ? (1) : (0));
-		}
-
-		// Store for future usage
-		if (loopcnt < 100)
-		{
-			if (loop++ == 0)
-			{
-				//BandWidth = 20 MHz
-				pAd->Mlme.CaliBW20RfR24 = (UCHAR)RF_R24_Value;
-			}
-			else
-			{
-				//BandWidth = 40 MHz
-				pAd->Mlme.CaliBW40RfR24 = (UCHAR)RF_R24_Value;
-				break;
-			}
-		}
-		else
-			break;
-
-		RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
-
-		// reset count
-		count = 0;
-	} while(TRUE);
-
-	//
-	// Set back to initial state
-	//
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
-
-	RT30xxReadRFRegister(pAd, RF_R22, &value);
-	value &= ~(0x01);
-	RT30xxWriteRFRegister(pAd, RF_R22, value);
-
-	// set BBP back to BW20
-	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-	BBPValue&= (~0x18);
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n", pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24));
-}
-
-VOID NICInitRT30xxRFRegisters(IN PRTMP_ADAPTER pAd)
-{
-	INT i;
-	// Driver must read EEPROM to get RfIcType before initial RF registers
-	// Initialize RF register to default value
-	if (IS_RT3070(pAd) || IS_RT3071(pAd))
-	{
-		// Init RF calibration
-		// Driver should toggle RF R30 bit7 before init RF registers
-		UINT32 RfReg = 0;
-		UINT32 data;
-
-		RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RfReg);
-		RfReg |= 0x80;
-		RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
-		RTMPusecDelay(1000);
-		RfReg &= 0x7F;
-		RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
-
-		// Initialize RF register to default value
-		for (i = 0; i < NUM_RF_REG_PARMS; i++)
-		{
-			RT30xxWriteRFRegister(pAd, RT30xx_RFRegTable[i].Register, RT30xx_RFRegTable[i].Value);
-		}
-
-		if (IS_RT3070(pAd))
-		{
-			//  Update MAC 0x05D4 from 01xxxxxx to 0Dxxxxxx (voltage 1.2V to 1.35V) for RT3070 to improve yield rate
-			RTUSBReadMACRegister(pAd, LDO_CFG0, &data);
-			data = ((data & 0xF0FFFFFF) | 0x0D000000);
-			RTUSBWriteMACRegister(pAd, LDO_CFG0, data);
-		}
-		else if (IS_RT3071(pAd))
-		{
-			// Driver should set RF R6 bit6 on before init RF registers
-			RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RfReg);
-			RfReg |= 0x40;
-			RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RfReg);
-
-			// init R31
-			RT30xxWriteRFRegister(pAd, RF_R31, 0x14);
-
-			// RT3071 version E has fixed this issue
-			if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
-			{
-				// patch tx EVM issue temporarily
-				RTUSBReadMACRegister(pAd, LDO_CFG0, &data);
-				data = ((data & 0xE0FFFFFF) | 0x0D000000);
-				RTUSBWriteMACRegister(pAd, LDO_CFG0, data);
-			}
-			else
-			{
-				RTMP_IO_READ32(pAd, LDO_CFG0, &data);
-				data = ((data & 0xE0FFFFFF) | 0x01000000);
-				RTMP_IO_WRITE32(pAd, LDO_CFG0, data);
-			}
-
-			// patch LNA_PE_G1 failed issue
-			RTUSBReadMACRegister(pAd, GPIO_SWITCH, &data);
-			data &= ~(0x20);
-			RTUSBWriteMACRegister(pAd, GPIO_SWITCH, data);
-		}
-
-		//For RF filter Calibration
-		RTMPFilterCalibration(pAd);
-
-		// Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration()
-		if ((pAd->MACVersion & 0xffff) < 0x0211)
-			RT30xxWriteRFRegister(pAd, RF_R27, 0x3);
-
-		// set led open drain enable
-		RTUSBReadMACRegister(pAd, OPT_14, &data);
-		data |= 0x01;
-		RTUSBWriteMACRegister(pAd, OPT_14, data);
-
-		if (IS_RT3071(pAd))
-		{
-			// add by johnli, RF power sequence setup, load RF normal operation-mode setup
-			RT30xxLoadRFNormalModeSetup(pAd);
-		}
-	}
-}
-#endif // RT2870 //
-
-
 /*
 	========================================================================
 
@@ -1296,88 +676,91 @@
 
 	========================================================================
 */
-VOID	NICReadEEPROMParameters(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			mac_addr)
+void NICReadEEPROMParameters(struct rt_rtmp_adapter *pAd, u8 *mac_addr)
 {
-	UINT32			data = 0;
-	USHORT			i, value, value2;
-	UCHAR			TmpPhy;
-	EEPROM_TX_PWR_STRUC	    Power;
-	EEPROM_VERSION_STRUC    Version;
-	EEPROM_ANTENNA_STRUC	Antenna;
-	EEPROM_NIC_CONFIG2_STRUC    NicConfig2;
+	u32 data = 0;
+	u16 i, value, value2;
+	u8 TmpPhy;
+	EEPROM_TX_PWR_STRUC Power;
+	EEPROM_VERSION_STRUC Version;
+	EEPROM_ANTENNA_STRUC Antenna;
+	EEPROM_NIC_CONFIG2_STRUC NicConfig2;
 
 	DBGPRINT(RT_DEBUG_TRACE, ("--> NICReadEEPROMParameters\n"));
 
-	// Init EEPROM Address Number, before access EEPROM; if 93c46, EEPROMAddressNum=6, else if 93c66, EEPROMAddressNum=8
+	if (pAd->chipOps.eeinit)
+		pAd->chipOps.eeinit(pAd);
+
+	/* Init EEPROM Address Number, before access EEPROM; if 93c46, EEPROMAddressNum=6, else if 93c66, EEPROMAddressNum=8 */
 	RTMP_IO_READ32(pAd, E2PROM_CSR, &data);
 	DBGPRINT(RT_DEBUG_TRACE, ("--> E2PROM_CSR = 0x%x\n", data));
 
-	if((data & 0x30) == 0)
-		pAd->EEPROMAddressNum = 6;		// 93C46
-	else if((data & 0x30) == 0x10)
-		pAd->EEPROMAddressNum = 8;     // 93C66
+	if ((data & 0x30) == 0)
+		pAd->EEPROMAddressNum = 6;	/* 93C46 */
+	else if ((data & 0x30) == 0x10)
+		pAd->EEPROMAddressNum = 8;	/* 93C66 */
 	else
-		pAd->EEPROMAddressNum = 8;     // 93C86
-	DBGPRINT(RT_DEBUG_TRACE, ("--> EEPROMAddressNum = %d\n", pAd->EEPROMAddressNum ));
+		pAd->EEPROMAddressNum = 8;	/* 93C86 */
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("--> EEPROMAddressNum = %d\n", pAd->EEPROMAddressNum));
 
-	// RT2860 MAC no longer auto load MAC address from E2PROM. Driver has to intialize
-	// MAC address registers according to E2PROM setting
+	/* RT2860 MAC no longer auto load MAC address from E2PROM. Driver has to intialize */
+	/* MAC address registers according to E2PROM setting */
 	if (mac_addr == NULL ||
-		strlen(mac_addr) != 17 ||
-		mac_addr[2] != ':'  || mac_addr[5] != ':'  || mac_addr[8] != ':' ||
-		mac_addr[11] != ':' || mac_addr[14] != ':')
-	{
-		USHORT  Addr01,Addr23,Addr45 ;
+	    strlen((char *)mac_addr) != 17 ||
+	    mac_addr[2] != ':' || mac_addr[5] != ':' || mac_addr[8] != ':' ||
+	    mac_addr[11] != ':' || mac_addr[14] != ':') {
+		u16 Addr01, Addr23, Addr45;
 
 		RT28xx_EEPROM_READ16(pAd, 0x04, Addr01);
 		RT28xx_EEPROM_READ16(pAd, 0x06, Addr23);
 		RT28xx_EEPROM_READ16(pAd, 0x08, Addr45);
 
-		pAd->PermanentAddress[0] = (UCHAR)(Addr01 & 0xff);
-		pAd->PermanentAddress[1] = (UCHAR)(Addr01 >> 8);
-		pAd->PermanentAddress[2] = (UCHAR)(Addr23 & 0xff);
-		pAd->PermanentAddress[3] = (UCHAR)(Addr23 >> 8);
-		pAd->PermanentAddress[4] = (UCHAR)(Addr45 & 0xff);
-		pAd->PermanentAddress[5] = (UCHAR)(Addr45 >> 8);
+		pAd->PermanentAddress[0] = (u8)(Addr01 & 0xff);
+		pAd->PermanentAddress[1] = (u8)(Addr01 >> 8);
+		pAd->PermanentAddress[2] = (u8)(Addr23 & 0xff);
+		pAd->PermanentAddress[3] = (u8)(Addr23 >> 8);
+		pAd->PermanentAddress[4] = (u8)(Addr45 & 0xff);
+		pAd->PermanentAddress[5] = (u8)(Addr45 >> 8);
 
-		DBGPRINT(RT_DEBUG_TRACE, ("Initialize MAC Address from E2PROM \n"));
-	}
-	else
-	{
-		INT		j;
-		PUCHAR	macptr;
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Initialize MAC Address from E2PROM \n"));
+	} else {
+		int j;
+		char *macptr;
 
-		macptr = mac_addr;
+		macptr = (char *)mac_addr;
 
-		for (j=0; j<MAC_ADDR_LEN; j++)
-		{
+		for (j = 0; j < MAC_ADDR_LEN; j++) {
 			AtoH(macptr, &pAd->PermanentAddress[j], 1);
-			macptr=macptr+3;
+			macptr = macptr + 3;
 		}
 
-		DBGPRINT(RT_DEBUG_TRACE, ("Initialize MAC Address from module parameter \n"));
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Initialize MAC Address from module parameter \n"));
 	}
 
-
 	{
-		//more conveninet to test mbssid, so ap's bssid &0xf1
+		/*more conveninet to test mbssid, so ap's bssid &0xf1 */
 		if (pAd->PermanentAddress[0] == 0xff)
-			pAd->PermanentAddress[0] = RandomByte(pAd)&0xf8;
+			pAd->PermanentAddress[0] = RandomByte(pAd) & 0xf8;
 
-		//if (pAd->PermanentAddress[5] == 0xff)
-		//	pAd->PermanentAddress[5] = RandomByte(pAd)&0xf8;
+		/*if (pAd->PermanentAddress[5] == 0xff) */
+		/*      pAd->PermanentAddress[5] = RandomByte(pAd)&0xf8; */
 
-		DBGPRINT_RAW(RT_DEBUG_TRACE,("E2PROM MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n",
-			pAd->PermanentAddress[0], pAd->PermanentAddress[1],
-			pAd->PermanentAddress[2], pAd->PermanentAddress[3],
-			pAd->PermanentAddress[4], pAd->PermanentAddress[5]));
-		if (pAd->bLocalAdminMAC == FALSE)
-		{
+		DBGPRINT_RAW(RT_DEBUG_TRACE,
+			     ("E2PROM MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n",
+			      pAd->PermanentAddress[0],
+			      pAd->PermanentAddress[1],
+			      pAd->PermanentAddress[2],
+			      pAd->PermanentAddress[3],
+			      pAd->PermanentAddress[4],
+			      pAd->PermanentAddress[5]));
+		if (pAd->bLocalAdminMAC == FALSE) {
 			MAC_DW0_STRUC csr2;
 			MAC_DW1_STRUC csr3;
-			COPY_MAC_ADDR(pAd->CurrentAddress, pAd->PermanentAddress);
+			COPY_MAC_ADDR(pAd->CurrentAddress,
+				      pAd->PermanentAddress);
 			csr2.field.Byte0 = pAd->CurrentAddress[0];
 			csr2.field.Byte1 = pAd->CurrentAddress[1];
 			csr2.field.Byte2 = pAd->CurrentAddress[2];
@@ -1388,118 +771,116 @@
 			csr3.field.Byte5 = pAd->CurrentAddress[5];
 			csr3.field.U2MeMask = 0xff;
 			RTMP_IO_WRITE32(pAd, MAC_ADDR_DW1, csr3.word);
-			DBGPRINT_RAW(RT_DEBUG_TRACE,("E2PROM MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n",
-				pAd->PermanentAddress[0], pAd->PermanentAddress[1],
-				pAd->PermanentAddress[2], pAd->PermanentAddress[3],
-				pAd->PermanentAddress[4], pAd->PermanentAddress[5]));
+			DBGPRINT_RAW(RT_DEBUG_TRACE,
+				     ("E2PROM MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n",
+				      PRINT_MAC(pAd->PermanentAddress)));
 		}
 	}
 
-	// if not return early. cause fail at emulation.
-	// Init the channel number for TX channel power
+	/* if not return early. cause fail at emulation. */
+	/* Init the channel number for TX channel power */
 	RTMPReadChannelPwr(pAd);
 
-	// if E2PROM version mismatch with driver's expectation, then skip
-	// all subsequent E2RPOM retieval and set a system error bit to notify GUI
+	/* if E2PROM version mismatch with driver's expectation, then skip */
+	/* all subsequent E2RPOM retieval and set a system error bit to notify GUI */
 	RT28xx_EEPROM_READ16(pAd, EEPROM_VERSION_OFFSET, Version.word);
-	pAd->EepromVersion = Version.field.Version + Version.field.FaeReleaseNumber * 256;
-	DBGPRINT(RT_DEBUG_TRACE, ("E2PROM: Version = %d, FAE release #%d\n", Version.field.Version, Version.field.FaeReleaseNumber));
+	pAd->EepromVersion =
+	    Version.field.Version + Version.field.FaeReleaseNumber * 256;
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("E2PROM: Version = %d, FAE release #%d\n",
+		  Version.field.Version, Version.field.FaeReleaseNumber));
 
-	if (Version.field.Version > VALID_EEPROM_VERSION)
-	{
-		DBGPRINT_ERR(("E2PROM: WRONG VERSION 0x%x, should be %d\n",Version.field.Version, VALID_EEPROM_VERSION));
+	if (Version.field.Version > VALID_EEPROM_VERSION) {
+		DBGPRINT_ERR(("E2PROM: WRONG VERSION 0x%x, should be %d\n",
+			      Version.field.Version, VALID_EEPROM_VERSION));
 		/*pAd->SystemErrorBitmap |= 0x00000001;
 
-		// hard-code default value when no proper E2PROM installed
-		pAd->bAutoTxAgcA = FALSE;
-		pAd->bAutoTxAgcG = FALSE;
+		   // hard-code default value when no proper E2PROM installed
+		   pAd->bAutoTxAgcA = FALSE;
+		   pAd->bAutoTxAgcG = FALSE;
 
-		// Default the channel power
-		for (i = 0; i < MAX_NUM_OF_CHANNELS; i++)
-			pAd->TxPower[i].Power = DEFAULT_RF_TX_POWER;
+		   // Default the channel power
+		   for (i = 0; i < MAX_NUM_OF_CHANNELS; i++)
+		   pAd->TxPower[i].Power = DEFAULT_RF_TX_POWER;
 
-		// Default the channel power
-		for (i = 0; i < MAX_NUM_OF_11JCHANNELS; i++)
-			pAd->TxPower11J[i].Power = DEFAULT_RF_TX_POWER;
+		   // Default the channel power
+		   for (i = 0; i < MAX_NUM_OF_11JCHANNELS; i++)
+		   pAd->TxPower11J[i].Power = DEFAULT_RF_TX_POWER;
 
-		for(i = 0; i < NUM_EEPROM_BBP_PARMS; i++)
-			pAd->EEPROMDefaultValue[i] = 0xffff;
-		return;  */
+		   for(i = 0; i < NUM_EEPROM_BBP_PARMS; i++)
+		   pAd->EEPROMDefaultValue[i] = 0xffff;
+		   return;  */
 	}
-
-	// Read BBP default value from EEPROM and store to array(EEPROMDefaultValue) in pAd
+	/* Read BBP default value from EEPROM and store to array(EEPROMDefaultValue) in pAd */
 	RT28xx_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET, value);
 	pAd->EEPROMDefaultValue[0] = value;
 
 	RT28xx_EEPROM_READ16(pAd, EEPROM_NIC2_OFFSET, value);
 	pAd->EEPROMDefaultValue[1] = value;
 
-	RT28xx_EEPROM_READ16(pAd, 0x38, value);	// Country Region
+	RT28xx_EEPROM_READ16(pAd, 0x38, value);	/* Country Region */
 	pAd->EEPROMDefaultValue[2] = value;
 
-	for(i = 0; i < 8; i++)
-	{
-		RT28xx_EEPROM_READ16(pAd, EEPROM_BBP_BASE_OFFSET + i*2, value);
-		pAd->EEPROMDefaultValue[i+3] = value;
+	for (i = 0; i < 8; i++) {
+		RT28xx_EEPROM_READ16(pAd, EEPROM_BBP_BASE_OFFSET + i * 2,
+				     value);
+		pAd->EEPROMDefaultValue[i + 3] = value;
 	}
 
-	// We have to parse NIC configuration 0 at here.
-	// If TSSI did not have preloaded value, it should reset the TxAutoAgc to false
-	// Therefore, we have to read TxAutoAgc control beforehand.
-	// Read Tx AGC control bit
+	/* We have to parse NIC configuration 0 at here. */
+	/* If TSSI did not have preloaded value, it should reset the TxAutoAgc to false */
+	/* Therefore, we have to read TxAutoAgc control beforehand. */
+	/* Read Tx AGC control bit */
 	Antenna.word = pAd->EEPROMDefaultValue[0];
-	if (Antenna.word == 0xFFFF)
-	{
-		if(IS_RT3090(pAd))
-		{
+	if (Antenna.word == 0xFFFF) {
+#ifdef RT30xx
+		if (IS_RT3090(pAd) || IS_RT3390(pAd)) {
 			Antenna.word = 0;
 			Antenna.field.RfIcType = RFIC_3020;
 			Antenna.field.TxPath = 1;
 			Antenna.field.RxPath = 1;
-		}
-		else
+		} else
+#endif /* RT30xx // */
 		{
-		Antenna.word = 0;
-		Antenna.field.RfIcType = RFIC_2820;
-		Antenna.field.TxPath = 1;
-		Antenna.field.RxPath = 2;
-		DBGPRINT(RT_DEBUG_WARN, ("E2PROM error, hard code as 0x%04x\n", Antenna.word));
+
+			Antenna.word = 0;
+			Antenna.field.RfIcType = RFIC_2820;
+			Antenna.field.TxPath = 1;
+			Antenna.field.RxPath = 2;
+			DBGPRINT(RT_DEBUG_WARN,
+				 ("E2PROM error, hard code as 0x%04x\n",
+				  Antenna.word));
 		}
 	}
-
-	// Choose the desired Tx&Rx stream.
-	if ((pAd->CommonCfg.TxStream == 0) || (pAd->CommonCfg.TxStream > Antenna.field.TxPath))
+	/* Choose the desired Tx&Rx stream. */
+	if ((pAd->CommonCfg.TxStream == 0)
+	    || (pAd->CommonCfg.TxStream > Antenna.field.TxPath))
 		pAd->CommonCfg.TxStream = Antenna.field.TxPath;
 
-	if ((pAd->CommonCfg.RxStream == 0) || (pAd->CommonCfg.RxStream > Antenna.field.RxPath))
-	{
+	if ((pAd->CommonCfg.RxStream == 0)
+	    || (pAd->CommonCfg.RxStream > Antenna.field.RxPath)) {
 		pAd->CommonCfg.RxStream = Antenna.field.RxPath;
 
 		if ((pAd->MACVersion < RALINK_2883_VERSION) &&
-			(pAd->CommonCfg.RxStream > 2))
-		{
-			// only 2 Rx streams for RT2860 series
+		    (pAd->CommonCfg.RxStream > 2)) {
+			/* only 2 Rx streams for RT2860 series */
 			pAd->CommonCfg.RxStream = 2;
 		}
 	}
-
-	// 3*3
-	// read value from EEPROM and set them to CSR174 ~ 177 in chain0 ~ chain2
-	// yet implement
-	for(i=0; i<3; i++)
-	{
+	/* 3*3 */
+	/* read value from EEPROM and set them to CSR174 ~ 177 in chain0 ~ chain2 */
+	/* yet implement */
+	for (i = 0; i < 3; i++) {
 	}
 
 	NicConfig2.word = pAd->EEPROMDefaultValue[1];
 
 	{
-		if ((NicConfig2.word & 0x00ff) == 0xff)
-		{
+		if ((NicConfig2.word & 0x00ff) == 0xff) {
 			NicConfig2.word &= 0xff00;
 		}
 
-		if ((NicConfig2.word >> 8) == 0xff)
-		{
+		if ((NicConfig2.word >> 8) == 0xff) {
 			NicConfig2.word &= 0x00ff;
 		}
 	}
@@ -1509,29 +890,43 @@
 	else
 		pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
 
-	DBGPRINT_RAW(RT_DEBUG_TRACE, ("NICReadEEPROMParameters: RxPath = %d, TxPath = %d\n", Antenna.field.RxPath, Antenna.field.TxPath));
+	DBGPRINT_RAW(RT_DEBUG_TRACE,
+		     ("NICReadEEPROMParameters: RxPath = %d, TxPath = %d\n",
+		      Antenna.field.RxPath, Antenna.field.TxPath));
 
-	// Save the antenna for future use
+	/* Save the antenna for future use */
 	pAd->Antenna.word = Antenna.word;
 
-	//
-	// Reset PhyMode if we don't support 802.11a
-	// Only RFIC_2850 & RFIC_2750 support 802.11a
-	//
-	if ((Antenna.field.RfIcType != RFIC_2850) && (Antenna.field.RfIcType != RFIC_2750))
-	{
+	/* Set the RfICType here, then we can initialize RFIC related operation callbacks */
+	pAd->Mlme.RealRxPath = (u8)Antenna.field.RxPath;
+	pAd->RfIcType = (u8)Antenna.field.RfIcType;
+
+#ifdef RTMP_RF_RW_SUPPORT
+	RtmpChipOpsRFHook(pAd);
+#endif /* RTMP_RF_RW_SUPPORT // */
+
+#ifdef RTMP_MAC_PCI
+	sprintf((char *)pAd->nickname, "RT2860STA");
+#endif /* RTMP_MAC_PCI // */
+
+	/* */
+	/* Reset PhyMode if we don't support 802.11a */
+	/* Only RFIC_2850 & RFIC_2750 support 802.11a */
+	/* */
+	if ((Antenna.field.RfIcType != RFIC_2850)
+	    && (Antenna.field.RfIcType != RFIC_2750)
+	    && (Antenna.field.RfIcType != RFIC_3052)) {
 		if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED) ||
-			(pAd->CommonCfg.PhyMode == PHY_11A))
+		    (pAd->CommonCfg.PhyMode == PHY_11A))
 			pAd->CommonCfg.PhyMode = PHY_11BG_MIXED;
-		else if ((pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED)	||
-				 (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED) 	||
-				 (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) 	||
-				 (pAd->CommonCfg.PhyMode == PHY_11N_5G))
+		else if ((pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) ||
+			 (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED) ||
+			 (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) ||
+			 (pAd->CommonCfg.PhyMode == PHY_11N_5G))
 			pAd->CommonCfg.PhyMode = PHY_11BGN_MIXED;
 	}
-
-	// Read TSSI reference and TSSI boundary for temperature compensation. This is ugly
-	// 0. 11b/g
+	/* Read TSSI reference and TSSI boundary for temperature compensation. This is ugly */
+	/* 0. 11b/g */
 	{
 		/* these are tempature reference value (0x00 ~ 0xFE)
 		   ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
@@ -1544,7 +939,7 @@
 		pAd->TssiMinusBoundaryG[2] = Power.field.Byte0;
 		pAd->TssiMinusBoundaryG[1] = Power.field.Byte1;
 		RT28xx_EEPROM_READ16(pAd, 0x72, Power.word);
-		pAd->TssiRefG   = Power.field.Byte0; /* reference value [0] */
+		pAd->TssiRefG = Power.field.Byte0;	/* reference value [0] */
 		pAd->TssiPlusBoundaryG[1] = Power.field.Byte1;
 		RT28xx_EEPROM_READ16(pAd, 0x74, Power.word);
 		pAd->TssiPlusBoundaryG[2] = Power.field.Byte0;
@@ -1554,19 +949,23 @@
 		pAd->TxAgcStepG = Power.field.Byte1;
 		pAd->TxAgcCompensateG = 0;
 		pAd->TssiMinusBoundaryG[0] = pAd->TssiRefG;
-		pAd->TssiPlusBoundaryG[0]  = pAd->TssiRefG;
+		pAd->TssiPlusBoundaryG[0] = pAd->TssiRefG;
 
-		// Disable TxAgc if the based value is not right
+		/* Disable TxAgc if the based value is not right */
 		if (pAd->TssiRefG == 0xff)
 			pAd->bAutoTxAgcG = FALSE;
 
-		DBGPRINT(RT_DEBUG_TRACE,("E2PROM: G Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
-			pAd->TssiMinusBoundaryG[4], pAd->TssiMinusBoundaryG[3], pAd->TssiMinusBoundaryG[2], pAd->TssiMinusBoundaryG[1],
-			pAd->TssiRefG,
-			pAd->TssiPlusBoundaryG[1], pAd->TssiPlusBoundaryG[2], pAd->TssiPlusBoundaryG[3], pAd->TssiPlusBoundaryG[4],
-			pAd->TxAgcStepG, pAd->bAutoTxAgcG));
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("E2PROM: G Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
+			  pAd->TssiMinusBoundaryG[4],
+			  pAd->TssiMinusBoundaryG[3],
+			  pAd->TssiMinusBoundaryG[2],
+			  pAd->TssiMinusBoundaryG[1], pAd->TssiRefG,
+			  pAd->TssiPlusBoundaryG[1], pAd->TssiPlusBoundaryG[2],
+			  pAd->TssiPlusBoundaryG[3], pAd->TssiPlusBoundaryG[4],
+			  pAd->TxAgcStepG, pAd->bAutoTxAgcG));
 	}
-	// 1. 11a
+	/* 1. 11a */
 	{
 		RT28xx_EEPROM_READ16(pAd, 0xD4, Power.word);
 		pAd->TssiMinusBoundaryA[4] = Power.field.Byte0;
@@ -1575,7 +974,7 @@
 		pAd->TssiMinusBoundaryA[2] = Power.field.Byte0;
 		pAd->TssiMinusBoundaryA[1] = Power.field.Byte1;
 		RT28xx_EEPROM_READ16(pAd, 0xD8, Power.word);
-		pAd->TssiRefA   = Power.field.Byte0;
+		pAd->TssiRefA = Power.field.Byte0;
 		pAd->TssiPlusBoundaryA[1] = Power.field.Byte1;
 		RT28xx_EEPROM_READ16(pAd, 0xDA, Power.word);
 		pAd->TssiPlusBoundaryA[2] = Power.field.Byte0;
@@ -1585,97 +984,119 @@
 		pAd->TxAgcStepA = Power.field.Byte1;
 		pAd->TxAgcCompensateA = 0;
 		pAd->TssiMinusBoundaryA[0] = pAd->TssiRefA;
-		pAd->TssiPlusBoundaryA[0]  = pAd->TssiRefA;
+		pAd->TssiPlusBoundaryA[0] = pAd->TssiRefA;
 
-		// Disable TxAgc if the based value is not right
+		/* Disable TxAgc if the based value is not right */
 		if (pAd->TssiRefA == 0xff)
 			pAd->bAutoTxAgcA = FALSE;
 
-		DBGPRINT(RT_DEBUG_TRACE,("E2PROM: A Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
-			pAd->TssiMinusBoundaryA[4], pAd->TssiMinusBoundaryA[3], pAd->TssiMinusBoundaryA[2], pAd->TssiMinusBoundaryA[1],
-			pAd->TssiRefA,
-			pAd->TssiPlusBoundaryA[1], pAd->TssiPlusBoundaryA[2], pAd->TssiPlusBoundaryA[3], pAd->TssiPlusBoundaryA[4],
-			pAd->TxAgcStepA, pAd->bAutoTxAgcA));
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("E2PROM: A Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
+			  pAd->TssiMinusBoundaryA[4],
+			  pAd->TssiMinusBoundaryA[3],
+			  pAd->TssiMinusBoundaryA[2],
+			  pAd->TssiMinusBoundaryA[1], pAd->TssiRefA,
+			  pAd->TssiPlusBoundaryA[1], pAd->TssiPlusBoundaryA[2],
+			  pAd->TssiPlusBoundaryA[3], pAd->TssiPlusBoundaryA[4],
+			  pAd->TxAgcStepA, pAd->bAutoTxAgcA));
 	}
 	pAd->BbpRssiToDbmDelta = 0x0;
 
-	// Read frequency offset setting for RF
+	/* Read frequency offset setting for RF */
 	RT28xx_EEPROM_READ16(pAd, EEPROM_FREQ_OFFSET, value);
 	if ((value & 0x00FF) != 0x00FF)
-		pAd->RfFreqOffset = (ULONG) (value & 0x00FF);
+		pAd->RfFreqOffset = (unsigned long)(value & 0x00FF);
 	else
 		pAd->RfFreqOffset = 0;
-	DBGPRINT(RT_DEBUG_TRACE, ("E2PROM: RF FreqOffset=0x%lx \n", pAd->RfFreqOffset));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("E2PROM: RF FreqOffset=0x%lx \n", pAd->RfFreqOffset));
 
-	//CountryRegion byte offset (38h)
-	value = pAd->EEPROMDefaultValue[2] >> 8;		// 2.4G band
-	value2 = pAd->EEPROMDefaultValue[2] & 0x00FF;	// 5G band
+	/*CountryRegion byte offset (38h) */
+	value = pAd->EEPROMDefaultValue[2] >> 8;	/* 2.4G band */
+	value2 = pAd->EEPROMDefaultValue[2] & 0x00FF;	/* 5G band */
 
-	if ((value <= REGION_MAXIMUM_BG_BAND) && (value2 <= REGION_MAXIMUM_A_BAND))
-	{
-		pAd->CommonCfg.CountryRegion = ((UCHAR) value) | 0x80;
-		pAd->CommonCfg.CountryRegionForABand = ((UCHAR) value2) | 0x80;
+	if ((value <= REGION_MAXIMUM_BG_BAND)
+	    && (value2 <= REGION_MAXIMUM_A_BAND)) {
+		pAd->CommonCfg.CountryRegion = ((u8)value) | 0x80;
+		pAd->CommonCfg.CountryRegionForABand = ((u8)value2) | 0x80;
 		TmpPhy = pAd->CommonCfg.PhyMode;
 		pAd->CommonCfg.PhyMode = 0xff;
 		RTMPSetPhyMode(pAd, TmpPhy);
 		SetCommonHT(pAd);
 	}
-
-	//
-	// Get RSSI Offset on EEPROM 0x9Ah & 0x9Ch.
-	// The valid value are (-10 ~ 10)
-	//
+	/* */
+	/* Get RSSI Offset on EEPROM 0x9Ah & 0x9Ch. */
+	/* The valid value are (-10 ~ 10) */
+	/* */
 	RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET, value);
 	pAd->BGRssiOffset0 = value & 0x00ff;
 	pAd->BGRssiOffset1 = (value >> 8);
-	RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET+2, value);
+	RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET + 2, value);
 	pAd->BGRssiOffset2 = value & 0x00ff;
 	pAd->ALNAGain1 = (value >> 8);
 	RT28xx_EEPROM_READ16(pAd, EEPROM_LNA_OFFSET, value);
 	pAd->BLNAGain = value & 0x00ff;
 	pAd->ALNAGain0 = (value >> 8);
 
-	// Validate 11b/g RSSI_0 offset.
+	/* Validate 11b/g RSSI_0 offset. */
 	if ((pAd->BGRssiOffset0 < -10) || (pAd->BGRssiOffset0 > 10))
 		pAd->BGRssiOffset0 = 0;
 
-	// Validate 11b/g RSSI_1 offset.
+	/* Validate 11b/g RSSI_1 offset. */
 	if ((pAd->BGRssiOffset1 < -10) || (pAd->BGRssiOffset1 > 10))
 		pAd->BGRssiOffset1 = 0;
 
-	// Validate 11b/g RSSI_2 offset.
+	/* Validate 11b/g RSSI_2 offset. */
 	if ((pAd->BGRssiOffset2 < -10) || (pAd->BGRssiOffset2 > 10))
 		pAd->BGRssiOffset2 = 0;
 
 	RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_A_OFFSET, value);
 	pAd->ARssiOffset0 = value & 0x00ff;
 	pAd->ARssiOffset1 = (value >> 8);
-	RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET+2), value);
+	RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET + 2), value);
 	pAd->ARssiOffset2 = value & 0x00ff;
 	pAd->ALNAGain2 = (value >> 8);
 
-	if (((UCHAR)pAd->ALNAGain1 == 0xFF) || (pAd->ALNAGain1 == 0x00))
+	if (((u8)pAd->ALNAGain1 == 0xFF) || (pAd->ALNAGain1 == 0x00))
 		pAd->ALNAGain1 = pAd->ALNAGain0;
-	if (((UCHAR)pAd->ALNAGain2 == 0xFF) || (pAd->ALNAGain2 == 0x00))
+	if (((u8)pAd->ALNAGain2 == 0xFF) || (pAd->ALNAGain2 == 0x00))
 		pAd->ALNAGain2 = pAd->ALNAGain0;
 
-	// Validate 11a RSSI_0 offset.
+	/* Validate 11a RSSI_0 offset. */
 	if ((pAd->ARssiOffset0 < -10) || (pAd->ARssiOffset0 > 10))
 		pAd->ARssiOffset0 = 0;
 
-	// Validate 11a RSSI_1 offset.
+	/* Validate 11a RSSI_1 offset. */
 	if ((pAd->ARssiOffset1 < -10) || (pAd->ARssiOffset1 > 10))
 		pAd->ARssiOffset1 = 0;
 
-	//Validate 11a RSSI_2 offset.
+	/*Validate 11a RSSI_2 offset. */
 	if ((pAd->ARssiOffset2 < -10) || (pAd->ARssiOffset2 > 10))
 		pAd->ARssiOffset2 = 0;
 
-	//
-	// Get LED Setting.
-	//
+#ifdef RT30xx
+	/* */
+	/* Get TX mixer gain setting */
+	/* 0xff are invalid value */
+	/* Note: RT30xX default value is 0x00 and will program to RF_R17 only when this value is not zero. */
+	/*       RT359X default value is 0x02 */
+	/* */
+	if (IS_RT30xx(pAd) || IS_RT3572(pAd)) {
+		RT28xx_EEPROM_READ16(pAd, EEPROM_TXMIXER_GAIN_2_4G, value);
+		pAd->TxMixerGain24G = 0;
+		value &= 0x00ff;
+		if (value != 0xff) {
+			value &= 0x07;
+			pAd->TxMixerGain24G = (u8)value;
+		}
+	}
+#endif /* RT30xx // */
+
+	/* */
+	/* Get LED Setting. */
+	/* */
 	RT28xx_EEPROM_READ16(pAd, 0x3a, value);
-	pAd->LedCntl.word = (value&0xff00) >> 8;
+	pAd->LedCntl.word = (value >> 8);
 	RT28xx_EEPROM_READ16(pAd, EEPROM_LED1_OFFSET, value);
 	pAd->Led1 = value;
 	RT28xx_EEPROM_READ16(pAd, EEPROM_LED2_OFFSET, value);
@@ -1685,6 +1106,12 @@
 
 	RTMPReadTxPwrPerRate(pAd);
 
+#ifdef RT30xx
+#ifdef RTMP_EFUSE_SUPPORT
+	RtmpEfuseSupportCheck(pAd);
+#endif /* RTMP_EFUSE_SUPPORT // */
+#endif /* RT30xx // */
+
 	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICReadEEPROMParameters\n"));
 }
 
@@ -1706,170 +1133,218 @@
 
 	========================================================================
 */
-VOID	NICInitAsicFromEEPROM(
-	IN	PRTMP_ADAPTER	pAd)
+void NICInitAsicFromEEPROM(struct rt_rtmp_adapter *pAd)
 {
-	UINT32					data = 0;
-	UCHAR	BBPR1 = 0;
-	USHORT					i;
-	EEPROM_ANTENNA_STRUC	Antenna;
-	EEPROM_NIC_CONFIG2_STRUC    NicConfig2;
-	UCHAR	BBPR3 = 0;
+	u32 data = 0;
+	u8 BBPR1 = 0;
+	u16 i;
+/*      EEPROM_ANTENNA_STRUC    Antenna; */
+	EEPROM_NIC_CONFIG2_STRUC NicConfig2;
+	u8 BBPR3 = 0;
 
 	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitAsicFromEEPROM\n"));
-	for(i = 3; i < NUM_EEPROM_BBP_PARMS; i++)
-	{
-		UCHAR BbpRegIdx, BbpValue;
+	for (i = 3; i < NUM_EEPROM_BBP_PARMS; i++) {
+		u8 BbpRegIdx, BbpValue;
 
-		if ((pAd->EEPROMDefaultValue[i] != 0xFFFF) && (pAd->EEPROMDefaultValue[i] != 0))
-		{
-			BbpRegIdx = (UCHAR)(pAd->EEPROMDefaultValue[i] >> 8);
-			BbpValue  = (UCHAR)(pAd->EEPROMDefaultValue[i] & 0xff);
+		if ((pAd->EEPROMDefaultValue[i] != 0xFFFF)
+		    && (pAd->EEPROMDefaultValue[i] != 0)) {
+			BbpRegIdx = (u8)(pAd->EEPROMDefaultValue[i] >> 8);
+			BbpValue = (u8)(pAd->EEPROMDefaultValue[i] & 0xff);
 			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BbpRegIdx, BbpValue);
 		}
 	}
 
-#ifndef RT2870
-	Antenna.word = pAd->Antenna.word;
-#else
-	Antenna.word = pAd->EEPROMDefaultValue[0];
-	if (Antenna.word == 0xFFFF)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("E2PROM error, hard code as 0x%04x\n", Antenna.word));
-		BUG_ON(Antenna.word == 0xFFFF);
-	}
-#endif
-	pAd->Mlme.RealRxPath = (UCHAR) Antenna.field.RxPath;
-	pAd->RfIcType = (UCHAR) Antenna.field.RfIcType;
-
-#ifdef RT2870
-	DBGPRINT(RT_DEBUG_WARN, ("pAd->RfIcType = %d, RealRxPath=%d, TxPath = %d\n", pAd->RfIcType, pAd->Mlme.RealRxPath,Antenna.field.TxPath));
-
-	// Save the antenna for future use
-	pAd->Antenna.word = Antenna.word;
-#endif
 	NicConfig2.word = pAd->EEPROMDefaultValue[1];
 
-#ifdef RT2870
 	{
-		if ((NicConfig2.word & 0x00ff) == 0xff)
-		{
+		if ((NicConfig2.word & 0x00ff) == 0xff) {
 			NicConfig2.word &= 0xff00;
 		}
 
-		if ((NicConfig2.word >> 8) == 0xff)
-		{
+		if ((NicConfig2.word >> 8) == 0xff) {
 			NicConfig2.word &= 0x00ff;
 		}
 	}
-#endif
-	// Save the antenna for future use
+
+	/* Save the antenna for future use */
 	pAd->NicConfig2.word = NicConfig2.word;
 
-#ifdef RT2870
-	// set default antenna as main
+#ifdef RT30xx
+	/* set default antenna as main */
 	if (pAd->RfIcType == RFIC_3020)
 		AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
-#endif
-	//
-	// Send LED Setting to MCU.
-	//
-	if (pAd->LedCntl.word == 0xFF)
-	{
+#endif /* RT30xx // */
+
+	/* */
+	/* Send LED Setting to MCU. */
+	/* */
+	if (pAd->LedCntl.word == 0xFF) {
 		pAd->LedCntl.word = 0x01;
 		pAd->Led1 = 0x5555;
 		pAd->Led2 = 0x2221;
-#ifdef RT2860
-		pAd->Led3 = 0xA9F8;
-#endif
 
-#ifdef RT2870
+#ifdef RTMP_MAC_PCI
+		pAd->Led3 = 0xA9F8;
+#endif /* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
 		pAd->Led3 = 0x5627;
-#endif // RT2870 //
+#endif /* RTMP_MAC_USB // */
 	}
 
-	AsicSendCommandToMcu(pAd, 0x52, 0xff, (UCHAR)pAd->Led1, (UCHAR)(pAd->Led1 >> 8));
-	AsicSendCommandToMcu(pAd, 0x53, 0xff, (UCHAR)pAd->Led2, (UCHAR)(pAd->Led2 >> 8));
-	AsicSendCommandToMcu(pAd, 0x54, 0xff, (UCHAR)pAd->Led3, (UCHAR)(pAd->Led3 >> 8));
-    pAd->LedIndicatorStregth = 0xFF;
-    RTMPSetSignalLED(pAd, -100);	// Force signal strength Led to be turned off, before link up
+	AsicSendCommandToMcu(pAd, 0x52, 0xff, (u8)pAd->Led1,
+			     (u8)(pAd->Led1 >> 8));
+	AsicSendCommandToMcu(pAd, 0x53, 0xff, (u8)pAd->Led2,
+			     (u8)(pAd->Led2 >> 8));
+	AsicSendCommandToMcu(pAd, 0x54, 0xff, (u8)pAd->Led3,
+			     (u8)(pAd->Led3 >> 8));
+	AsicSendCommandToMcu(pAd, 0x51, 0xff, 0, pAd->LedCntl.field.Polarity);
+
+	pAd->LedIndicatorStrength = 0xFF;
+	RTMPSetSignalLED(pAd, -100);	/* Force signal strength Led to be turned off, before link up */
 
 	{
-		// Read Hardware controlled Radio state enable bit
-		if (NicConfig2.field.HardwareRadioControl == 1)
-		{
+		/* Read Hardware controlled Radio state enable bit */
+		if (NicConfig2.field.HardwareRadioControl == 1) {
 			pAd->StaCfg.bHardwareRadio = TRUE;
 
-			// Read GPIO pin2 as Hardware controlled radio state
+			/* Read GPIO pin2 as Hardware controlled radio state */
 			RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
-			if ((data & 0x04) == 0)
-			{
+			if ((data & 0x04) == 0) {
 				pAd->StaCfg.bHwRadio = FALSE;
 				pAd->StaCfg.bRadio = FALSE;
+/*                              RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818); */
 				RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
 			}
-		}
-		else
+		} else
 			pAd->StaCfg.bHardwareRadio = FALSE;
 
-		if (pAd->StaCfg.bRadio == FALSE)
-		{
+		if (pAd->StaCfg.bRadio == FALSE) {
 			RTMPSetLED(pAd, LED_RADIO_OFF);
-		}
-		else
-		{
+		} else {
 			RTMPSetLED(pAd, LED_RADIO_ON);
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
+#ifdef RT3090
+			AsicSendCommandToMcu(pAd, 0x30, PowerRadioOffCID, 0xff,
+					     0x02);
+			AsicCheckCommanOk(pAd, PowerRadioOffCID);
+#endif /* RT3090 // */
+#ifndef RT3090
 			AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
-			AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x00);
-			// 2-1. wait command ok.
+#endif /* RT3090 // */
+			AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00,
+					     0x00);
+			/* 2-1. wait command ok. */
 			AsicCheckCommanOk(pAd, PowerWakeCID);
-#endif
+#endif /* RTMP_MAC_PCI // */
 		}
 	}
 
-	// Turn off patching for cardbus controller
-	if (NicConfig2.field.CardbusAcceleration == 1)
-	{
+#ifdef RTMP_MAC_PCI
+#ifdef RT30xx
+	if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) {
+		struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
+		if (pChipOps->AsicReverseRfFromSleepMode)
+			pChipOps->AsicReverseRfFromSleepMode(pAd);
+	}
+	/* 3090 MCU Wakeup command needs more time to be stable. */
+	/* Before stable, don't issue other MCU command to prevent from firmware error. */
+
+	if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
+	    && IS_VERSION_AFTER_F(pAd)
+	    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
+	    && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
+		DBGPRINT(RT_DEBUG_TRACE, ("%s, release Mcu Lock\n", __func__));
+		RTMP_SEM_LOCK(&pAd->McuCmdLock);
+		pAd->brt30xxBanMcuCmd = FALSE;
+		RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
+	}
+#endif /* RT30xx // */
+#endif /* RTMP_MAC_PCI // */
+
+	/* Turn off patching for cardbus controller */
+	if (NicConfig2.field.CardbusAcceleration == 1) {
+/*              pAd->bTest1 = TRUE; */
 	}
 
 	if (NicConfig2.field.DynamicTxAgcControl == 1)
 		pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
 	else
 		pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
-
-	/* BBP has been programmed so reset to UNKNOWN_BAND */
+	/* */
+	/* Since BBP has been progamed, to make sure BBP setting will be */
+	/* upate inside of AsicAntennaSelect, so reset to UNKNOWN_BAND! */
+	/* */
 	pAd->CommonCfg.BandState = UNKNOWN_BAND;
 
 	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
 	BBPR3 &= (~0x18);
-	if(pAd->Antenna.field.RxPath == 3)
-	{
+	if (pAd->Antenna.field.RxPath == 3) {
 		BBPR3 |= (0x10);
-	}
-	else if(pAd->Antenna.field.RxPath == 2)
-	{
+	} else if (pAd->Antenna.field.RxPath == 2) {
 		BBPR3 |= (0x8);
-	}
-	else if(pAd->Antenna.field.RxPath == 1)
-	{
+	} else if (pAd->Antenna.field.RxPath == 1) {
 		BBPR3 |= (0x0);
 	}
 	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
 
 	{
-		// Handle the difference when 1T
+		/* Handle the difference when 1T */
 		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BBPR1);
-		if(pAd->Antenna.field.TxPath == 1)
-		{
-		BBPR1 &= (~0x18);
+		if (pAd->Antenna.field.TxPath == 1) {
+			BBPR1 &= (~0x18);
 		}
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BBPR1);
 
-		DBGPRINT(RT_DEBUG_TRACE, ("Use Hw Radio Control Pin=%d; if used Pin=%d;\n", pAd->CommonCfg.bHardwareRadio, pAd->CommonCfg.bHardwareRadio));
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Use Hw Radio Control Pin=%d; if used Pin=%d;\n",
+			  pAd->CommonCfg.bHardwareRadio,
+			  pAd->CommonCfg.bHardwareRadio));
 	}
 
-	DBGPRINT(RT_DEBUG_TRACE, ("TxPath = %d, RxPath = %d, RFIC=%d, Polar+LED mode=%x\n", pAd->Antenna.field.TxPath, pAd->Antenna.field.RxPath, pAd->RfIcType, pAd->LedCntl.word));
+#ifdef RTMP_MAC_USB
+#ifdef RT30xx
+	/* update registers from EEPROM for RT3071 or later(3572/3592). */
+
+	if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) {
+		u8 RegIdx, RegValue;
+		u16 value;
+
+		/* after RT3071, write BBP from EEPROM 0xF0 to 0x102 */
+		for (i = 0xF0; i <= 0x102; i = i + 2) {
+			value = 0xFFFF;
+			RT28xx_EEPROM_READ16(pAd, i, value);
+			if ((value != 0xFFFF) && (value != 0)) {
+				RegIdx = (u8)(value >> 8);
+				RegValue = (u8)(value & 0xff);
+				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, RegIdx,
+							     RegValue);
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("Update BBP Registers from EEPROM(0x%0x), BBP(0x%x) = 0x%x\n",
+					  i, RegIdx, RegValue));
+			}
+		}
+
+		/* after RT3071, write RF from EEPROM 0x104 to 0x116 */
+		for (i = 0x104; i <= 0x116; i = i + 2) {
+			value = 0xFFFF;
+			RT28xx_EEPROM_READ16(pAd, i, value);
+			if ((value != 0xFFFF) && (value != 0)) {
+				RegIdx = (u8)(value >> 8);
+				RegValue = (u8)(value & 0xff);
+				RT30xxWriteRFRegister(pAd, RegIdx, RegValue);
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("Update RF Registers from EEPROM0x%x), BBP(0x%x) = 0x%x\n",
+					  i, RegIdx, RegValue));
+			}
+		}
+	}
+#endif /* RT30xx // */
+#endif /* RTMP_MAC_USB // */
+
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("TxPath = %d, RxPath = %d, RFIC=%d, Polar+LED mode=%x\n",
+		  pAd->Antenna.field.TxPath, pAd->Antenna.field.RxPath,
+		  pAd->RfIcType, pAd->LedCntl.word));
 	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitAsicFromEEPROM\n"));
 }
 
@@ -1891,39 +1366,39 @@
 
 	========================================================================
 */
-NDIS_STATUS	NICInitializeAdapter(
-	IN	PRTMP_ADAPTER	pAd,
-	IN   BOOLEAN    bHardReset)
+int NICInitializeAdapter(struct rt_rtmp_adapter *pAd, IN BOOLEAN bHardReset)
 {
-	NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;
-	WPDMA_GLO_CFG_STRUC	GloCfg;
-#ifdef RT2860
-	UINT32			Value;
-	DELAY_INT_CFG_STRUC	IntCfg;
-#endif
-	ULONG	i =0, j=0;
-	AC_TXOP_CSR0_STRUC	csr0;
+	int Status = NDIS_STATUS_SUCCESS;
+	WPDMA_GLO_CFG_STRUC GloCfg;
+#ifdef RTMP_MAC_PCI
+	u32 Value;
+	DELAY_INT_CFG_STRUC IntCfg;
+#endif /* RTMP_MAC_PCI // */
+/*      INT_MASK_CSR_STRUC              IntMask; */
+	unsigned long i = 0, j = 0;
+	AC_TXOP_CSR0_STRUC csr0;
 
 	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAdapter\n"));
 
-	// 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits:
+	/* 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits: */
 retry:
 	i = 0;
-	do
-	{
+	do {
 		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-		if ((GloCfg.field.TxDMABusy == 0)  && (GloCfg.field.RxDMABusy == 0))
+		if ((GloCfg.field.TxDMABusy == 0)
+		    && (GloCfg.field.RxDMABusy == 0))
 			break;
 
 		RTMPusecDelay(1000);
 		i++;
-	}while ( i<100);
-	DBGPRINT(RT_DEBUG_TRACE, ("<== DMA offset 0x208 = 0x%x\n", GloCfg.word));
+	} while (i < 100);
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("<== DMA offset 0x208 = 0x%x\n", GloCfg.word));
 	GloCfg.word &= 0xff0;
-	GloCfg.field.EnTXWriteBackDDONE =1;
+	GloCfg.field.EnTXWriteBackDDONE = 1;
 	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
 
-	// Record HW Beacon offset
+	/* Record HW Beacon offset */
 	pAd->BeaconOffset[0] = HW_BEACON_BASE0;
 	pAd->BeaconOffset[1] = HW_BEACON_BASE1;
 	pAd->BeaconOffset[2] = HW_BEACON_BASE2;
@@ -1933,91 +1408,87 @@
 	pAd->BeaconOffset[6] = HW_BEACON_BASE6;
 	pAd->BeaconOffset[7] = HW_BEACON_BASE7;
 
-	//
-	// write all shared Ring's base address into ASIC
-	//
+	/* */
+	/* write all shared Ring's base address into ASIC */
+	/* */
 
-	// asic simulation sequence put this ahead before loading firmware.
-	// pbf hardware reset
-#ifdef RT2860
-	RTMP_IO_WRITE32(pAd, WPDMA_RST_IDX, 0x1003f);	// 0x10000 for reset rx, 0x3f resets all 6 tx rings.
+	/* asic simulation sequence put this ahead before loading firmware. */
+	/* pbf hardware reset */
+#ifdef RTMP_MAC_PCI
+	RTMP_IO_WRITE32(pAd, WPDMA_RST_IDX, 0x1003f);	/* 0x10000 for reset rx, 0x3f resets all 6 tx rings. */
 	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe1f);
 	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe00);
-#endif
+#endif /* RTMP_MAC_PCI // */
 
-	// Initialze ASIC for TX & Rx operation
-	if (NICInitializeAsic(pAd , bHardReset) != NDIS_STATUS_SUCCESS)
-	{
-		if (j++ == 0)
-		{
+	/* Initialze ASIC for TX & Rx operation */
+	if (NICInitializeAsic(pAd, bHardReset) != NDIS_STATUS_SUCCESS) {
+		if (j++ == 0) {
 			NICLoadFirmware(pAd);
 			goto retry;
 		}
 		return NDIS_STATUS_FAILURE;
 	}
 
-
-#ifdef RT2860
-	// Write AC_BK base address register
-	Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BK].Cell[0].AllocPa);
+#ifdef RTMP_MAC_PCI
+	/* Write AC_BK base address register */
+	Value =
+	    RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BK].Cell[0].AllocPa);
 	RTMP_IO_WRITE32(pAd, TX_BASE_PTR1, Value);
 	DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR1 : 0x%x\n", Value));
 
-	// Write AC_BE base address register
-	Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BE].Cell[0].AllocPa);
+	/* Write AC_BE base address register */
+	Value =
+	    RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BE].Cell[0].AllocPa);
 	RTMP_IO_WRITE32(pAd, TX_BASE_PTR0, Value);
 	DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR0 : 0x%x\n", Value));
 
-	// Write AC_VI base address register
-	Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_VI].Cell[0].AllocPa);
+	/* Write AC_VI base address register */
+	Value =
+	    RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_VI].Cell[0].AllocPa);
 	RTMP_IO_WRITE32(pAd, TX_BASE_PTR2, Value);
 	DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR2 : 0x%x\n", Value));
 
-	// Write AC_VO base address register
-	Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_VO].Cell[0].AllocPa);
+	/* Write AC_VO base address register */
+	Value =
+	    RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_VO].Cell[0].AllocPa);
 	RTMP_IO_WRITE32(pAd, TX_BASE_PTR3, Value);
 	DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR3 : 0x%x\n", Value));
 
-	// Write HCCA base address register
-	  Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_HCCA].Cell[0].AllocPa);
-	  RTMP_IO_WRITE32(pAd, TX_BASE_PTR4, Value);
-	DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR4 : 0x%x\n", Value));
-
-	// Write MGMT_BASE_CSR register
+	/* Write MGMT_BASE_CSR register */
 	Value = RTMP_GetPhysicalAddressLow(pAd->MgmtRing.Cell[0].AllocPa);
 	RTMP_IO_WRITE32(pAd, TX_BASE_PTR5, Value);
 	DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR5 : 0x%x\n", Value));
 
-	// Write RX_BASE_CSR register
+	/* Write RX_BASE_CSR register */
 	Value = RTMP_GetPhysicalAddressLow(pAd->RxRing.Cell[0].AllocPa);
 	RTMP_IO_WRITE32(pAd, RX_BASE_PTR, Value);
 	DBGPRINT(RT_DEBUG_TRACE, ("--> RX_BASE_PTR : 0x%x\n", Value));
 
-	// Init RX Ring index pointer
+	/* Init RX Ring index pointer */
 	pAd->RxRing.RxSwReadIdx = 0;
-	pAd->RxRing.RxCpuIdx = RX_RING_SIZE-1;
+	pAd->RxRing.RxCpuIdx = RX_RING_SIZE - 1;
 	RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
 
-	// Init TX rings index pointer
+	/* Init TX rings index pointer */
 	{
-		for (i=0; i<NUM_OF_TX_RING; i++)
-		{
+		for (i = 0; i < NUM_OF_TX_RING; i++) {
 			pAd->TxRing[i].TxSwFreeIdx = 0;
 			pAd->TxRing[i].TxCpuIdx = 0;
-			RTMP_IO_WRITE32(pAd, (TX_CTX_IDX0 + i * 0x10) ,  pAd->TxRing[i].TxCpuIdx);
+			RTMP_IO_WRITE32(pAd, (TX_CTX_IDX0 + i * 0x10),
+					pAd->TxRing[i].TxCpuIdx);
 		}
 	}
 
-	// init MGMT ring index pointer
+	/* init MGMT ring index pointer */
 	pAd->MgmtRing.TxSwFreeIdx = 0;
 	pAd->MgmtRing.TxCpuIdx = 0;
-	RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX,  pAd->MgmtRing.TxCpuIdx);
+	RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
 
-	//
-	// set each Ring's SIZE  into ASIC. Descriptor Size is fixed by design.
-	//
+	/* */
+	/* set each Ring's SIZE  into ASIC. Descriptor Size is fixed by design. */
+	/* */
 
-	// Write TX_RING_CSR0 register
+	/* Write TX_RING_CSR0 register */
 	Value = TX_RING_SIZE;
 	RTMP_IO_WRITE32(pAd, TX_MAX_CNT0, Value);
 	RTMP_IO_WRITE32(pAd, TX_MAX_CNT1, Value);
@@ -2027,53 +1498,47 @@
 	Value = MGMT_RING_SIZE;
 	RTMP_IO_WRITE32(pAd, TX_MGMTMAX_CNT, Value);
 
-	// Write RX_RING_CSR register
+	/* Write RX_RING_CSR register */
 	Value = RX_RING_SIZE;
 	RTMP_IO_WRITE32(pAd, RX_MAX_CNT, Value);
-#endif /* RT2860 */
+#endif /* RTMP_MAC_PCI // */
 
-
-	// WMM parameter
+	/* WMM parameter */
 	csr0.word = 0;
 	RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
-	if (pAd->CommonCfg.PhyMode == PHY_11B)
-	{
-		csr0.field.Ac0Txop = 192;	// AC_VI: 192*32us ~= 6ms
-		csr0.field.Ac1Txop = 96;	// AC_VO: 96*32us  ~= 3ms
-	}
-	else
-	{
-		csr0.field.Ac0Txop = 96;	// AC_VI: 96*32us ~= 3ms
-		csr0.field.Ac1Txop = 48;	// AC_VO: 48*32us ~= 1.5ms
+	if (pAd->CommonCfg.PhyMode == PHY_11B) {
+		csr0.field.Ac0Txop = 192;	/* AC_VI: 192*32us ~= 6ms */
+		csr0.field.Ac1Txop = 96;	/* AC_VO: 96*32us  ~= 3ms */
+	} else {
+		csr0.field.Ac0Txop = 96;	/* AC_VI: 96*32us ~= 3ms */
+		csr0.field.Ac1Txop = 48;	/* AC_VO: 48*32us ~= 1.5ms */
 	}
 	RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr0.word);
 
-
-#ifdef RT2860
-	// 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits:
+#ifdef RTMP_MAC_PCI
+	/* 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits: */
 	i = 0;
-	do
-	{
+	do {
 		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-		if ((GloCfg.field.TxDMABusy == 0)  && (GloCfg.field.RxDMABusy == 0))
+		if ((GloCfg.field.TxDMABusy == 0)
+		    && (GloCfg.field.RxDMABusy == 0))
 			break;
 
 		RTMPusecDelay(1000);
 		i++;
-	}while ( i < 100);
+	} while (i < 100);
 
 	GloCfg.word &= 0xff0;
-	GloCfg.field.EnTXWriteBackDDONE =1;
+	GloCfg.field.EnTXWriteBackDDONE = 1;
 	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
 
 	IntCfg.word = 0;
 	RTMP_IO_WRITE32(pAd, DELAY_INT_CFG, IntCfg.word);
-#endif
+#endif /* RTMP_MAC_PCI // */
 
-
-	// reset action
-	// Load firmware
-	//  Status = NICLoadFirmware(pAd);
+	/* reset action */
+	/* Load firmware */
+	/*  Status = NICLoadFirmware(pAd); */
 
 	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAdapter\n"));
 	return Status;
@@ -2097,42 +1562,55 @@
 
 	========================================================================
 */
-NDIS_STATUS	NICInitializeAsic(
-	IN	PRTMP_ADAPTER	pAd,
-	IN  BOOLEAN		bHardReset)
+int NICInitializeAsic(struct rt_rtmp_adapter *pAd, IN BOOLEAN bHardReset)
 {
-	ULONG			Index = 0;
-	UCHAR			R0 = 0xff;
-	UINT32			MacCsr12 = 0, Counter = 0;
-#ifdef RT2870
-	UINT32			MacCsr0 = 0;
-	NTSTATUS		Status;
-	UCHAR			Value = 0xff;
-	UINT32			eFuseCtrl;
-#endif
-	USHORT			KeyIdx;
-	INT				i,apidx;
+	unsigned long Index = 0;
+	u8 R0 = 0xff;
+	u32 MacCsr12 = 0, Counter = 0;
+#ifdef RTMP_MAC_USB
+	u32 MacCsr0 = 0;
+	int Status;
+	u8 Value = 0xff;
+#endif /* RTMP_MAC_USB // */
+#ifdef RT30xx
+	u8 bbpreg = 0;
+	u8 RFValue = 0;
+#endif /* RT30xx // */
+	u16 KeyIdx;
+	int i, apidx;
 
 	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAsic\n"));
 
-#ifdef RT2860
-	if (bHardReset == TRUE)
-	{
+#ifdef RTMP_MAC_PCI
+	RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x3);	/* To fix driver disable/enable hang issue when radio off */
+	if (bHardReset == TRUE) {
 		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
-	}
-	else
+	} else
 		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
-#endif
-#ifdef RT2870
-	//
-	// Make sure MAC gets ready after NICLoadFirmware().
-	//
+
+	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
+	/* Initialize MAC register to default value */
+	for (Index = 0; Index < NUM_MAC_REG_PARMS; Index++) {
+		RTMP_IO_WRITE32(pAd, MACRegTable[Index].Register,
+				MACRegTable[Index].Value);
+	}
+
+	{
+		for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++) {
+			RTMP_IO_WRITE32(pAd, STAMACRegTable[Index].Register,
+					STAMACRegTable[Index].Value);
+		}
+	}
+#endif /* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
+	/* */
+	/* Make sure MAC gets ready after NICLoadFirmware(). */
+	/* */
 	Index = 0;
 
-	//To avoid hang-on issue when interface up in kernel 2.4,
-	//we use a local variable "MacCsr0" instead of using "pAd->MACVersion" directly.
-	do
-	{
+	/*To avoid hang-on issue when interface up in kernel 2.4, */
+	/*we use a local variable "MacCsr0" instead of using "pAd->MACVersion" directly. */
+	do {
 		RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
 
 		if ((MacCsr0 != 0x00) && (MacCsr0 != 0xFFFFFFFF))
@@ -2142,8 +1620,9 @@
 	} while (Index++ < 100);
 
 	pAd->MACVersion = MacCsr0;
-	DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0  [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
-	// turn on bit13 (set to zero) after rt2860D. This is to solve high-current issue.
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("MAC_CSR0  [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
+	/* turn on bit13 (set to zero) after rt2860D. This is to solve high-current issue. */
 	RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacCsr12);
 	MacCsr12 &= (~0x2000);
 	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, MacCsr12);
@@ -2151,203 +1630,223 @@
 	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
 	RTMP_IO_WRITE32(pAd, USB_DMA_CFG, 0x0);
 	Status = RTUSBVenderReset(pAd);
-#endif
 
 	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
 
-	// Initialize MAC register to default value
-#ifdef RT2860
-	for (Index = 0; Index < NUM_MAC_REG_PARMS; Index++)
-	{
-		RTMP_IO_WRITE32(pAd, MACRegTable[Index].Register, MACRegTable[Index].Value);
-	}
-#endif
-#ifdef RT2870
-	for(Index=0; Index<NUM_MAC_REG_PARMS; Index++)
-	{
-#ifdef RT3070
-		if ((MACRegTable[Index].Register == TX_SW_CFG0) && (IS_RT3070(pAd) || IS_RT3071(pAd)))
-		{
+	/* Initialize MAC register to default value */
+	for (Index = 0; Index < NUM_MAC_REG_PARMS; Index++) {
+#ifdef RT30xx
+		if ((MACRegTable[Index].Register == TX_SW_CFG0)
+		    && (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3572(pAd)
+			|| IS_RT3090(pAd) || IS_RT3390(pAd))) {
 			MACRegTable[Index].Value = 0x00000400;
 		}
-#endif // RT3070 //
-		RTMP_IO_WRITE32(pAd, (USHORT)MACRegTable[Index].Register, MACRegTable[Index].Value);
+#endif /* RT30xx // */
+		RTMP_IO_WRITE32(pAd, (u16)MACRegTable[Index].Register,
+				MACRegTable[Index].Value);
 	}
-#endif // RT2870 //
 
 	{
-		for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++)
-		{
-#ifdef RT2860
-			RTMP_IO_WRITE32(pAd, STAMACRegTable[Index].Register, STAMACRegTable[Index].Value);
-#endif
-#ifdef RT2870
-			RTMP_IO_WRITE32(pAd, (USHORT)STAMACRegTable[Index].Register, STAMACRegTable[Index].Value);
-#endif
+		for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++) {
+			RTMP_IO_WRITE32(pAd,
+					(u16)STAMACRegTable[Index].Register,
+					STAMACRegTable[Index].Value);
 		}
 	}
+#endif /* RTMP_MAC_USB // */
 
-	// Initialize RT3070 serial MAc registers which is different from RT2870 serial
-	if (IS_RT3090(pAd))
-	{
+#ifdef RT30xx
+	/* Initialize RT3070 serial MAC registers which is different from RT2870 serial */
+	if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) {
 		RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
 
-		// RT3071 version E has fixed this issue
-		if ((pAd->MACVersion & 0xffff) < 0x0211)
-		{
-			if (pAd->NicConfig2.field.DACTestBit == 1)
-			{
-				RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x1F);	// To fix throughput drop drastically
+		/* RT3071 version E has fixed this issue */
+		if ((pAd->MACVersion & 0xffff) < 0x0211) {
+			if (pAd->NicConfig2.field.DACTestBit == 1) {
+				RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x2C);	/* To fix throughput drop drastically */
+			} else {
+				RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0F);	/* To fix throughput drop drastically */
 			}
-			else
-			{
-				RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0F);	// To fix throughput drop drastically
-			}
-		}
-		else
-		{
+		} else {
 			RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0);
 		}
+	} else if (IS_RT3070(pAd)) {
+		if (((pAd->MACVersion & 0xffff) < 0x0201)) {
+			RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
+			RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x2C);	/* To fix throughput drop drastically */
+		} else {
+			RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0);
+		}
 	}
-#ifdef RT2870
-	else if (IS_RT3070(pAd))
-	{
-		RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
-		RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x1F);	// To fix throughput drop drastically
-	}
-#endif // RT30xx //
+#endif /* RT30xx // */
 
-	//
-	// Before program BBP, we need to wait BBP/RF get wake up.
-	//
+	/* */
+	/* Before program BBP, we need to wait BBP/RF get wake up. */
+	/* */
 	Index = 0;
-	do
-	{
+	do {
 		RTMP_IO_READ32(pAd, MAC_STATUS_CFG, &MacCsr12);
 
-		if ((MacCsr12 & 0x03) == 0)	// if BB.RF is stable
+		if ((MacCsr12 & 0x03) == 0)	/* if BB.RF is stable */
 			break;
 
-		DBGPRINT(RT_DEBUG_TRACE, ("Check MAC_STATUS_CFG  = Busy = %x\n", MacCsr12));
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Check MAC_STATUS_CFG  = Busy = %x\n", MacCsr12));
 		RTMPusecDelay(1000);
 	} while (Index++ < 100);
 
-    // The commands to firmware should be after these commands, these commands will init firmware
-	// PCI and USB are not the same because PCI driver needs to wait for PCI bus ready
-	RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, 0);	// initialize BBP R/W access agent
+	/* The commands to firmware should be after these commands, these commands will init firmware */
+	/* PCI and USB are not the same because PCI driver needs to wait for PCI bus ready */
+	RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, 0);	/* initialize BBP R/W access agent */
 	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, 0);
+#ifdef RT3090
+	/*2008/11/28:KH add to fix the dead rf frequency offset bug<-- */
+	AsicSendCommandToMcu(pAd, 0x72, 0, 0, 0);
+	/*2008/11/28:KH add to fix the dead rf frequency offset bug--> */
+#endif /* RT3090 // */
 	RTMPusecDelay(1000);
 
-	// Read BBP register, make sure BBP is up and running before write new data
+	/* Read BBP register, make sure BBP is up and running before write new data */
 	Index = 0;
-	do
-	{
+	do {
 		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R0, &R0);
 		DBGPRINT(RT_DEBUG_TRACE, ("BBP version = %x\n", R0));
 	} while ((++Index < 20) && ((R0 == 0xff) || (R0 == 0x00)));
-	//ASSERT(Index < 20); //this will cause BSOD on Check-build driver
+	/*ASSERT(Index < 20); //this will cause BSOD on Check-build driver */
 
 	if ((R0 == 0xff) || (R0 == 0x00))
 		return NDIS_STATUS_FAILURE;
 
-	// Initialize BBP register to default value
-	for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++)
-	{
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, BBPRegTable[Index].Value);
+	/* Initialize BBP register to default value */
+	for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++) {
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register,
+					     BBPRegTable[Index].Value);
 	}
 
-#ifndef RT2870
-	// for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT.
-	if ((pAd->MACVersion&0xffff) != 0x0101)
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19);
-#else
-	// for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT.
-	// RT3090 should not program BBP R84 to 0x19, otherwise TX will block.
-	if (((pAd->MACVersion&0xffff) != 0x0101) && (!IS_RT30xx(pAd)))
+#ifdef RTMP_MAC_PCI
+	/* TODO: shiang, check MACVersion, currently, rbus-based chip use this. */
+	if (pAd->MACVersion == 0x28720200) {
+		/*u8 value; */
+		unsigned long value2;
+
+		/*disable MLD by Bruce 20080704 */
+		/*BBP_IO_READ8_BY_REG_ID(pAd, BBP_R105, &value); */
+		/*BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R105, value | 4); */
+
+		/*Maximum PSDU length from 16K to 32K bytes */
+		RTMP_IO_READ32(pAd, MAX_LEN_CFG, &value2);
+		value2 &= ~(0x3 << 12);
+		value2 |= (0x2 << 12);
+		RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, value2);
+	}
+#endif /* RTMP_MAC_PCI // */
+
+	/* for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT. */
+	/* RT3090 should not program BBP R84 to 0x19, otherwise TX will block. */
+	/*3070/71/72,3090,3090A( are included in RT30xx),3572,3390 */
+	if (((pAd->MACVersion & 0xffff) != 0x0101)
+	    && !(IS_RT30xx(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)))
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19);
 
-// add by johnli, RF power sequence setup
-	if (IS_RT30xx(pAd))
-	{	//update for RT3070/71/72/90/91/92.
+#ifdef RT30xx
+/* add by johnli, RF power sequence setup */
+	if (IS_RT30xx(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) {	/*update for RT3070/71/72/90/91/92,3572,3390. */
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R79, 0x13);
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R80, 0x05);
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R81, 0x33);
 	}
 
-	if (IS_RT3090(pAd))
+	if (IS_RT3090(pAd) || IS_RT3390(pAd))	/* RT309x, RT3071/72 */
 	{
-		UCHAR		bbpreg=0;
-
-		// enable DC filter
-		if ((pAd->MACVersion & 0xffff) >= 0x0211)
-		{
+		/* enable DC filter */
+		if ((pAd->MACVersion & 0xffff) >= 0x0211) {
 			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0);
 		}
-
-		// improve power consumption
+		/* improve power consumption */
 		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R138, &bbpreg);
-		if (pAd->Antenna.field.TxPath == 1)
-		{
-			// turn off tx DAC_1
+		if (pAd->Antenna.field.TxPath == 1) {
+			/* turn off tx DAC_1 */
 			bbpreg = (bbpreg | 0x20);
 		}
 
-		if (pAd->Antenna.field.RxPath == 1)
-		{
-			// turn off tx ADC_1
+		if (pAd->Antenna.field.RxPath == 1) {
+			/* turn off tx ADC_1 */
 			bbpreg &= (~0x2);
 		}
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R138, bbpreg);
 
-		// improve power consumption in RT3071 Ver.E
-		if ((pAd->MACVersion & 0xffff) >= 0x0211)
-		{
+		/* improve power consumption in RT3071 Ver.E */
+		if ((pAd->MACVersion & 0xffff) >= 0x0211) {
 			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg);
 			bbpreg &= (~0x3);
 			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg);
 		}
+	} else if (IS_RT3070(pAd)) {
+		if ((pAd->MACVersion & 0xffff) >= 0x0201) {
+			/* enable DC filter */
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0);
+
+			/* improve power consumption in RT3070 Ver.F */
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg);
+			bbpreg &= (~0x3);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg);
+		}
+		/* TX_LO1_en, RF R17 register Bit 3 to 0 */
+		RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
+		RFValue &= (~0x08);
+		/* to fix rx long range issue */
+		if (pAd->NicConfig2.field.ExternalLNAForG == 0) {
+			RFValue |= 0x20;
+		}
+		/* set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h */
+		if (pAd->TxMixerGain24G >= 1) {
+			RFValue &= (~0x7);	/* clean bit [2:0] */
+			RFValue |= pAd->TxMixerGain24G;
+		}
+		RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
 	}
-#endif
-	if (pAd->MACVersion == 0x28600100)
-	{
+/* end johnli */
+#endif /* RT30xx // */
+
+	if (pAd->MACVersion == 0x28600100) {
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x12);
-    }
+	}
 
-	if (pAd->MACVersion >= RALINK_2880E_VERSION && pAd->MACVersion < RALINK_3070_VERSION) // 3*3
+	if (pAd->MACVersion >= RALINK_2880E_VERSION && pAd->MACVersion < RALINK_3070_VERSION)	/* 3*3 */
 	{
-		// enlarge MAX_LEN_CFG
-		UINT32 csr;
+		/* enlarge MAX_LEN_CFG */
+		u32 csr;
 		RTMP_IO_READ32(pAd, MAX_LEN_CFG, &csr);
 		csr &= 0xFFF;
 		csr |= 0x2000;
 		RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, csr);
 	}
-
-#ifdef RT2870
-{
-	UCHAR	MAC_Value[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0,0};
-
-	//Initialize WCID table
-	Value = 0xff;
-	for(Index =0 ;Index < 254;Index++)
+#ifdef RTMP_MAC_USB
 	{
-		RTUSBMultiWrite(pAd, (USHORT)(MAC_WCID_BASE + Index * 8), MAC_Value, 8);
+		u8 MAC_Value[] =
+		    { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0 };
+
+		/*Initialize WCID table */
+		Value = 0xff;
+		for (Index = 0; Index < 254; Index++) {
+			RTUSBMultiWrite(pAd,
+					(u16)(MAC_WCID_BASE + Index * 8),
+					MAC_Value, 8);
+		}
 	}
-}
-#endif // RT2870 //
+#endif /* RTMP_MAC_USB // */
 
-	// Add radio off control
+	/* Add radio off control */
 	{
-		if (pAd->StaCfg.bRadio == FALSE)
-		{
-//			RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818);
+		if (pAd->StaCfg.bRadio == FALSE) {
+/*                      RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818); */
 			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
 			DBGPRINT(RT_DEBUG_TRACE, ("Set Radio Off\n"));
 		}
 	}
 
-	// Clear raw counters
+	/* Clear raw counters */
 	RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter);
 	RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter);
 	RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter);
@@ -2355,65 +1854,55 @@
 	RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter);
 	RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter);
 
-	// ASIC will keep garbage value after boot
-	// Clear all seared key table when initial
-	// This routine can be ignored in radio-ON/OFF operation.
-	if (bHardReset)
-	{
-		for (KeyIdx = 0; KeyIdx < 4; KeyIdx++)
-		{
-			RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4*KeyIdx, 0);
+	/* ASIC will keep garbage value after boot */
+	/* Clear all shared key table when initial */
+	/* This routine can be ignored in radio-ON/OFF operation. */
+	if (bHardReset) {
+		for (KeyIdx = 0; KeyIdx < 4; KeyIdx++) {
+			RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * KeyIdx,
+					0);
 		}
 
-		// Clear all pairwise key table when initial
-		for (KeyIdx = 0; KeyIdx < 256; KeyIdx++)
-		{
-			RTMP_IO_WRITE32(pAd, MAC_WCID_ATTRIBUTE_BASE + (KeyIdx * HW_WCID_ATTRI_SIZE), 1);
+		/* Clear all pairwise key table when initial */
+		for (KeyIdx = 0; KeyIdx < 256; KeyIdx++) {
+			RTMP_IO_WRITE32(pAd,
+					MAC_WCID_ATTRIBUTE_BASE +
+					(KeyIdx * HW_WCID_ATTRI_SIZE), 1);
 		}
 	}
+	/* assert HOST ready bit */
+/*  RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x0); // 2004-09-14 asked by Mark */
+/*  RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x4); */
 
-
-	// It isn't necessary to clear this space when not hard reset.
-	if (bHardReset == TRUE)
-	{
-		// clear all on-chip BEACON frame space
-		for (apidx = 0; apidx < HW_BEACON_MAX_COUNT; apidx++)
-		{
-			for (i = 0; i < HW_BEACON_OFFSET>>2; i+=4)
-				RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[apidx] + i, 0x00);
+	/* It isn't necessary to clear this space when not hard reset. */
+	if (bHardReset == TRUE) {
+		/* clear all on-chip BEACON frame space */
+		for (apidx = 0; apidx < HW_BEACON_MAX_COUNT; apidx++) {
+			for (i = 0; i < HW_BEACON_OFFSET >> 2; i += 4)
+				RTMP_IO_WRITE32(pAd,
+						pAd->BeaconOffset[apidx] + i,
+						0x00);
 		}
 	}
-#ifdef RT2870
+#ifdef RTMP_MAC_USB
 	AsicDisableSync(pAd);
-	// Clear raw counters
+	/* Clear raw counters */
 	RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter);
 	RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter);
 	RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter);
 	RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter);
 	RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter);
 	RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter);
-	// Default PCI clock cycle per ms is different as default setting, which is based on PCI.
+	/* Default PCI clock cycle per ms is different as default setting, which is based on PCI. */
 	RTMP_IO_READ32(pAd, USB_CYC_CFG, &Counter);
-	Counter&=0xffffff00;
-	Counter|=0x000001e;
+	Counter &= 0xffffff00;
+	Counter |= 0x000001e;
 	RTMP_IO_WRITE32(pAd, USB_CYC_CFG, Counter);
-
-	pAd->bUseEfuse=FALSE;
-	RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrl);
-	pAd->bUseEfuse = ( (eFuseCtrl & 0x80000000) == 0x80000000) ? 1 : 0;
-	if(pAd->bUseEfuse)
-	{
-			DBGPRINT(RT_DEBUG_TRACE, ("NVM is Efuse\n"));
-	}
-	else
-	{
-			DBGPRINT(RT_DEBUG_TRACE, ("NVM is EEPROM\n"));
-	}
-#endif
+#endif /* RTMP_MAC_USB // */
 
 	{
-		// for rt2860E and after, init TXOP_CTRL_CFG with 0x583f. This is for extension channel overlapping IOT.
-		if ((pAd->MACVersion&0xffff) != 0x0101)
+		/* for rt2860E and after, init TXOP_CTRL_CFG with 0x583f. This is for extension channel overlapping IOT. */
+		if ((pAd->MACVersion & 0xffff) != 0x0101)
 			RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x583f);
 	}
 
@@ -2421,133 +1910,6 @@
 	return NDIS_STATUS_SUCCESS;
 }
 
-
-#ifdef RT2860
-VOID NICRestoreBBPValue(
-	IN PRTMP_ADAPTER pAd)
-{
-	UCHAR		index;
-	UCHAR		Value = 0;
-	ULONG		Data;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--->  NICRestoreBBPValue !!!!!!!!!!!!!!!!!!!!!!!  \n"));
-	// Initialize BBP register to default value (rtmp_init.c)
-	for (index = 0; index < NUM_BBP_REG_PARMS; index++)
-	{
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[index].Register, BBPRegTable[index].Value);
-	}
-	// copy from (rtmp_init.c)
-	if (pAd->MACVersion == 0x28600100)
-	{
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x12);
-	}
-
-	// copy from (connect.c LinkUp function)
-	if (INFRA_ON(pAd))
-	{
-		// Change to AP channel
-		if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
-		{
-			// Must using 40MHz.
-			pAd->CommonCfg.BBPCurrentBW = BW_40;
-			AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
-			AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
-
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
-			Value &= (~0x18);
-			Value |= 0x10;
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
-
-			//  RX : control channel at lower
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
-			Value &= (~0x20);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
-			// Record BBPR3 setting, But don't keep R Antenna # information.
-			pAd->StaCfg.BBPR3 = Value;
-
-			RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
-			Data &= 0xfffffffe;
-			RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
-
-			if (pAd->MACVersion == 0x28600100)
-			{
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
-				DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
-			}
-
-			DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
-		}
-		else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
-		{
-			// Must using 40MHz.
-			pAd->CommonCfg.BBPCurrentBW = BW_40;
-			AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
-			AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
-
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
-			Value &= (~0x18);
-			Value |= 0x10;
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
-
-			RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
-			Data |= 0x1;
-			RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
-
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
-			Value |= (0x20);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
-			// Record BBPR3 setting, But don't keep R Antenna # information.
-			pAd->StaCfg.BBPR3 = Value;
-
-			if (pAd->MACVersion == 0x28600100)
-			{
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
-				DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
-			}
-
-			DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
-		}
-		else
-		{
-			pAd->CommonCfg.BBPCurrentBW = BW_20;
-			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
-			Value &= (~0x18);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
-
-			RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
-			Data &= 0xfffffffe;
-			RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
-
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
-			Value &= (~0x20);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
-			// Record BBPR3 setting, But don't keep R Antenna # information.
-			pAd->StaCfg.BBPR3 = Value;
-
-			if (pAd->MACVersion == 0x28600100)
-			{
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
-				DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
-			}
-
-			DBGPRINT(RT_DEBUG_TRACE, ("!!!20MHz LINK UP !!! \n" ));
-		}
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<---  NICRestoreBBPValue !!!!!!!!!!!!!!!!!!!!!!!  \n"));
-}
-#endif /* RT2860 */
-
 /*
 	========================================================================
 
@@ -2567,19 +1929,21 @@
 
 	========================================================================
 */
-VOID	NICIssueReset(
-	IN	PRTMP_ADAPTER	pAd)
+void NICIssueReset(struct rt_rtmp_adapter *pAd)
 {
-	UINT32	Value = 0;
+	u32 Value = 0;
 	DBGPRINT(RT_DEBUG_TRACE, ("--> NICIssueReset\n"));
 
-	// Disable Rx, register value supposed will remain after reset
+	/* Abort Tx, prevent ASIC from writing to Host memory */
+	/*RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x001f0000); */
+
+	/* Disable Rx, register value supposed will remain after reset */
 	RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
 	Value &= (0xfffffff3);
 	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
 
-	// Issue reset and clear from reset state
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x03); // 2004-09-17 change from 0x01
+	/* Issue reset and clear from reset state */
+	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x03);	/* 2004-09-17 change from 0x01 */
 	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x00);
 
 	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICIssueReset\n"));
@@ -2601,134 +1965,115 @@
 
 	========================================================================
 */
-BOOLEAN	NICCheckForHang(
-	IN	PRTMP_ADAPTER	pAd)
+BOOLEAN NICCheckForHang(struct rt_rtmp_adapter *pAd)
 {
 	return (FALSE);
 }
 
-VOID NICUpdateFifoStaCounters(
-	IN PRTMP_ADAPTER pAd)
+void NICUpdateFifoStaCounters(struct rt_rtmp_adapter *pAd)
 {
-	TX_STA_FIFO_STRUC	StaFifo;
-	MAC_TABLE_ENTRY		*pEntry;
-	UCHAR				i = 0;
-	UCHAR			pid = 0, wcid = 0;
-	CHAR				reTry;
-	UCHAR				succMCS;
+	TX_STA_FIFO_STRUC StaFifo;
+	struct rt_mac_table_entry *pEntry;
+	u8 i = 0;
+	u8 pid = 0, wcid = 0;
+	char reTry;
+	u8 succMCS;
 
-		do
-		{
-			RTMP_IO_READ32(pAd, TX_STA_FIFO, &StaFifo.word);
+	do {
+		RTMP_IO_READ32(pAd, TX_STA_FIFO, &StaFifo.word);
 
-			if (StaFifo.field.bValid == 0)
-				break;
+		if (StaFifo.field.bValid == 0)
+			break;
 
-			wcid = (UCHAR)StaFifo.field.wcid;
-
+		wcid = (u8)StaFifo.field.wcid;
 
 		/* ignore NoACK and MGMT frame use 0xFF as WCID */
-			if ((StaFifo.field.TxAckRequired == 0) || (wcid >= MAX_LEN_OF_MAC_TABLE))
-			{
-				i++;
-				continue;
-			}
-
-			/* PID store Tx MCS Rate */
-			pid = (UCHAR)StaFifo.field.PidType;
-
-			pEntry = &pAd->MacTab.Content[wcid];
-
-			pEntry->DebugFIFOCount++;
-
-			if (StaFifo.field.TxBF) // 3*3
-				pEntry->TxBFCount++;
-
-#ifdef UAPSD_AP_SUPPORT
-			UAPSD_SP_AUE_Handle(pAd, pEntry, StaFifo.field.TxSuccess);
-#endif // UAPSD_AP_SUPPORT //
-
-			if (!StaFifo.field.TxSuccess)
-			{
-				pEntry->FIFOCount++;
-				pEntry->OneSecTxFailCount++;
-
-				if (pEntry->FIFOCount >= 1)
-				{
-					DBGPRINT(RT_DEBUG_TRACE, ("#"));
-					pEntry->NoBADataCountDown = 64;
-
-					if(pEntry->PsMode == PWR_ACTIVE)
-					{
-						int tid;
-						for (tid=0; tid<NUM_OF_TID; tid++)
-						{
-							BAOriSessionTearDown(pAd, pEntry->Aid,  tid, FALSE, FALSE);
-						}
-
-						// Update the continuous transmission counter except PS mode
-						pEntry->ContinueTxFailCnt++;
-					}
-					else
-					{
-						// Clear the FIFOCount when sta in Power Save mode. Basically we assume
-						//     this tx error happened due to sta just go to sleep.
-						pEntry->FIFOCount = 0;
-						pEntry->ContinueTxFailCnt = 0;
-					}
-				}
-			}
-			else
-			{
-				if ((pEntry->PsMode != PWR_SAVE) && (pEntry->NoBADataCountDown > 0))
-				{
-					pEntry->NoBADataCountDown--;
-					if (pEntry->NoBADataCountDown==0)
-					{
-						DBGPRINT(RT_DEBUG_TRACE, ("@\n"));
-					}
-				}
-
-				pEntry->FIFOCount = 0;
-				pEntry->OneSecTxNoRetryOkCount++;
-				// update NoDataIdleCount when sucessful send packet to STA.
-				pEntry->NoDataIdleCount = 0;
-				pEntry->ContinueTxFailCnt = 0;
-			}
-
-			succMCS = StaFifo.field.SuccessRate & 0x7F;
-
-			reTry = pid - succMCS;
-
-			if (StaFifo.field.TxSuccess)
-			{
-				pEntry->TXMCSExpected[pid]++;
-				if (pid == succMCS)
-				{
-					pEntry->TXMCSSuccessful[pid]++;
-				}
-				else
-				{
-					pEntry->TXMCSAutoFallBack[pid][succMCS]++;
-				}
-			}
-			else
-			{
-				pEntry->TXMCSFailed[pid]++;
-			}
-
-			if (reTry > 0)
-			{
-				if ((pid >= 12) && succMCS <=7)
-				{
-					reTry -= 4;
-				}
-				pEntry->OneSecTxRetryOkCount += reTry;
-			}
-
+		if ((StaFifo.field.TxAckRequired == 0)
+		    || (wcid >= MAX_LEN_OF_MAC_TABLE)) {
 			i++;
-			// ASIC store 16 stack
-		} while ( i < (2*TX_RING_SIZE) );
+			continue;
+		}
+
+		/* PID store Tx MCS Rate */
+		pid = (u8)StaFifo.field.PidType;
+
+		pEntry = &pAd->MacTab.Content[wcid];
+
+		pEntry->DebugFIFOCount++;
+
+		if (StaFifo.field.TxBF)	/* 3*3 */
+			pEntry->TxBFCount++;
+
+		if (!StaFifo.field.TxSuccess) {
+			pEntry->FIFOCount++;
+			pEntry->OneSecTxFailCount++;
+
+			if (pEntry->FIFOCount >= 1) {
+				DBGPRINT(RT_DEBUG_TRACE, ("#"));
+				pEntry->NoBADataCountDown = 64;
+
+				if (pEntry->PsMode == PWR_ACTIVE) {
+					int tid;
+					for (tid = 0; tid < NUM_OF_TID; tid++) {
+						BAOriSessionTearDown(pAd,
+								     pEntry->
+								     Aid, tid,
+								     FALSE,
+								     FALSE);
+					}
+
+					/* Update the continuous transmission counter except PS mode */
+					pEntry->ContinueTxFailCnt++;
+				} else {
+					/* Clear the FIFOCount when sta in Power Save mode. Basically we assume */
+					/*     this tx error happened due to sta just go to sleep. */
+					pEntry->FIFOCount = 0;
+					pEntry->ContinueTxFailCnt = 0;
+				}
+				/*pEntry->FIFOCount = 0; */
+			}
+			/*pEntry->bSendBAR = TRUE; */
+		} else {
+			if ((pEntry->PsMode != PWR_SAVE)
+			    && (pEntry->NoBADataCountDown > 0)) {
+				pEntry->NoBADataCountDown--;
+				if (pEntry->NoBADataCountDown == 0) {
+					DBGPRINT(RT_DEBUG_TRACE, ("@\n"));
+				}
+			}
+
+			pEntry->FIFOCount = 0;
+			pEntry->OneSecTxNoRetryOkCount++;
+			/* update NoDataIdleCount when sucessful send packet to STA. */
+			pEntry->NoDataIdleCount = 0;
+			pEntry->ContinueTxFailCnt = 0;
+		}
+
+		succMCS = StaFifo.field.SuccessRate & 0x7F;
+
+		reTry = pid - succMCS;
+
+		if (StaFifo.field.TxSuccess) {
+			pEntry->TXMCSExpected[pid]++;
+			if (pid == succMCS) {
+				pEntry->TXMCSSuccessful[pid]++;
+			} else {
+				pEntry->TXMCSAutoFallBack[pid][succMCS]++;
+			}
+		} else {
+			pEntry->TXMCSFailed[pid]++;
+		}
+
+		if (reTry > 0) {
+			if ((pid >= 12) && succMCS <= 7) {
+				reTry -= 4;
+			}
+			pEntry->OneSecTxRetryOkCount += reTry;
+		}
+
+		i++;
+		/* ASIC store 16 stack */
+	} while (i < (2 * TX_RING_SIZE));
 
 }
 
@@ -2749,87 +2094,99 @@
 
 	========================================================================
 */
-VOID NICUpdateRawCounters(
-	IN PRTMP_ADAPTER pAd)
+void NICUpdateRawCounters(struct rt_rtmp_adapter *pAd)
 {
-	UINT32	OldValue;
-	RX_STA_CNT0_STRUC	 RxStaCnt0;
-	RX_STA_CNT1_STRUC   RxStaCnt1;
-	RX_STA_CNT2_STRUC   RxStaCnt2;
-	TX_STA_CNT0_STRUC 	 TxStaCnt0;
-	TX_STA_CNT1_STRUC	 StaTx1;
-	TX_STA_CNT2_STRUC	 StaTx2;
-	TX_AGG_CNT_STRUC	TxAggCnt;
-	TX_AGG_CNT0_STRUC	TxAggCnt0;
-	TX_AGG_CNT1_STRUC	TxAggCnt1;
-	TX_AGG_CNT2_STRUC	TxAggCnt2;
-	TX_AGG_CNT3_STRUC	TxAggCnt3;
-	TX_AGG_CNT4_STRUC	TxAggCnt4;
-	TX_AGG_CNT5_STRUC	TxAggCnt5;
-	TX_AGG_CNT6_STRUC	TxAggCnt6;
-	TX_AGG_CNT7_STRUC	TxAggCnt7;
+	u32 OldValue;	/*, Value2; */
+	/*unsigned long PageSum, OneSecTransmitCount; */
+	/*unsigned long TxErrorRatio, Retry, Fail; */
+	RX_STA_CNT0_STRUC RxStaCnt0;
+	RX_STA_CNT1_STRUC RxStaCnt1;
+	RX_STA_CNT2_STRUC RxStaCnt2;
+	TX_STA_CNT0_STRUC TxStaCnt0;
+	TX_STA_CNT1_STRUC StaTx1;
+	TX_STA_CNT2_STRUC StaTx2;
+	TX_AGG_CNT_STRUC TxAggCnt;
+	TX_AGG_CNT0_STRUC TxAggCnt0;
+	TX_AGG_CNT1_STRUC TxAggCnt1;
+	TX_AGG_CNT2_STRUC TxAggCnt2;
+	TX_AGG_CNT3_STRUC TxAggCnt3;
+	TX_AGG_CNT4_STRUC TxAggCnt4;
+	TX_AGG_CNT5_STRUC TxAggCnt5;
+	TX_AGG_CNT6_STRUC TxAggCnt6;
+	TX_AGG_CNT7_STRUC TxAggCnt7;
+	struct rt_counter_ralink *pRalinkCounters;
+
+	pRalinkCounters = &pAd->RalinkCounters;
 
 	RTMP_IO_READ32(pAd, RX_STA_CNT0, &RxStaCnt0.word);
 	RTMP_IO_READ32(pAd, RX_STA_CNT2, &RxStaCnt2.word);
 
 	{
 		RTMP_IO_READ32(pAd, RX_STA_CNT1, &RxStaCnt1.word);
-	    // Update RX PLCP error counter
-	    pAd->PrivateInfo.PhyRxErrCnt += RxStaCnt1.field.PlcpErr;
-		// Update False CCA counter
-		pAd->RalinkCounters.OneSecFalseCCACnt += RxStaCnt1.field.FalseCca;
+		/* Update RX PLCP error counter */
+		pAd->PrivateInfo.PhyRxErrCnt += RxStaCnt1.field.PlcpErr;
+		/* Update False CCA counter */
+		pAd->RalinkCounters.OneSecFalseCCACnt +=
+		    RxStaCnt1.field.FalseCca;
 	}
 
-	// Update FCS counters
-	OldValue= pAd->WlanCounters.FCSErrorCount.u.LowPart;
-	pAd->WlanCounters.FCSErrorCount.u.LowPart += (RxStaCnt0.field.CrcErr); // >> 7);
+	/* Update FCS counters */
+	OldValue = pAd->WlanCounters.FCSErrorCount.u.LowPart;
+	pAd->WlanCounters.FCSErrorCount.u.LowPart += (RxStaCnt0.field.CrcErr);	/* >> 7); */
 	if (pAd->WlanCounters.FCSErrorCount.u.LowPart < OldValue)
 		pAd->WlanCounters.FCSErrorCount.u.HighPart++;
 
-	// Add FCS error count to private counters
-	pAd->RalinkCounters.OneSecRxFcsErrCnt += RxStaCnt0.field.CrcErr;
-	OldValue = pAd->RalinkCounters.RealFcsErrCount.u.LowPart;
-	pAd->RalinkCounters.RealFcsErrCount.u.LowPart += RxStaCnt0.field.CrcErr;
-	if (pAd->RalinkCounters.RealFcsErrCount.u.LowPart < OldValue)
-		pAd->RalinkCounters.RealFcsErrCount.u.HighPart++;
+	/* Add FCS error count to private counters */
+	pRalinkCounters->OneSecRxFcsErrCnt += RxStaCnt0.field.CrcErr;
+	OldValue = pRalinkCounters->RealFcsErrCount.u.LowPart;
+	pRalinkCounters->RealFcsErrCount.u.LowPart += RxStaCnt0.field.CrcErr;
+	if (pRalinkCounters->RealFcsErrCount.u.LowPart < OldValue)
+		pRalinkCounters->RealFcsErrCount.u.HighPart++;
 
-	// Update Duplicate Rcv check
-	pAd->RalinkCounters.DuplicateRcv += RxStaCnt2.field.RxDupliCount;
-	pAd->WlanCounters.FrameDuplicateCount.u.LowPart += RxStaCnt2.field.RxDupliCount;
-	// Update RX Overflow counter
+	/* Update Duplicate Rcv check */
+	pRalinkCounters->DuplicateRcv += RxStaCnt2.field.RxDupliCount;
+	pAd->WlanCounters.FrameDuplicateCount.u.LowPart +=
+	    RxStaCnt2.field.RxDupliCount;
+	/* Update RX Overflow counter */
 	pAd->Counters8023.RxNoBuffer += (RxStaCnt2.field.RxFifoOverflowCount);
 
-#ifdef RT2870
-	if (pAd->RalinkCounters.RxCount != pAd->watchDogRxCnt)
-	{
-		pAd->watchDogRxCnt = pAd->RalinkCounters.RxCount;
+	/*pAd->RalinkCounters.RxCount = 0; */
+#ifdef RTMP_MAC_USB
+	if (pRalinkCounters->RxCount != pAd->watchDogRxCnt) {
+		pAd->watchDogRxCnt = pRalinkCounters->RxCount;
 		pAd->watchDogRxOverFlowCnt = 0;
-	}
-	else
-	{
+	} else {
 		if (RxStaCnt2.field.RxFifoOverflowCount)
 			pAd->watchDogRxOverFlowCnt++;
 		else
 			pAd->watchDogRxOverFlowCnt = 0;
 	}
-#endif // RT2870 //
+#endif /* RTMP_MAC_USB // */
 
-
-	if (!pAd->bUpdateBcnCntDone)
-	{
-	// Update BEACON sent count
-	RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
-	RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
-	RTMP_IO_READ32(pAd, TX_STA_CNT2, &StaTx2.word);
-	pAd->RalinkCounters.OneSecBeaconSentCnt += TxStaCnt0.field.TxBeaconCount;
-	pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
-	pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
-	pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
-	pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
-	pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
-	pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
+	/*if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) || */
+	/*      (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) && (pAd->MacTab.Size != 1))) */
+	if (!pAd->bUpdateBcnCntDone) {
+		/* Update BEACON sent count */
+		RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
+		RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
+		RTMP_IO_READ32(pAd, TX_STA_CNT2, &StaTx2.word);
+		pRalinkCounters->OneSecBeaconSentCnt +=
+		    TxStaCnt0.field.TxBeaconCount;
+		pRalinkCounters->OneSecTxRetryOkCount +=
+		    StaTx1.field.TxRetransmit;
+		pRalinkCounters->OneSecTxNoRetryOkCount +=
+		    StaTx1.field.TxSuccess;
+		pRalinkCounters->OneSecTxFailCount +=
+		    TxStaCnt0.field.TxFailCount;
+		pAd->WlanCounters.TransmittedFragmentCount.u.LowPart +=
+		    StaTx1.field.TxSuccess;
+		pAd->WlanCounters.RetryCount.u.LowPart +=
+		    StaTx1.field.TxRetransmit;
+		pAd->WlanCounters.FailedCount.u.LowPart +=
+		    TxStaCnt0.field.TxFailCount;
 	}
 
+	/*if (pAd->bStaFifoTest == TRUE) */
 	{
 		RTMP_IO_READ32(pAd, TX_AGG_CNT, &TxAggCnt.word);
 		RTMP_IO_READ32(pAd, TX_AGG_CNT0, &TxAggCnt0.word);
@@ -2840,60 +2197,89 @@
 		RTMP_IO_READ32(pAd, TX_AGG_CNT5, &TxAggCnt5.word);
 		RTMP_IO_READ32(pAd, TX_AGG_CNT6, &TxAggCnt6.word);
 		RTMP_IO_READ32(pAd, TX_AGG_CNT7, &TxAggCnt7.word);
-		pAd->RalinkCounters.TxAggCount += TxAggCnt.field.AggTxCount;
-		pAd->RalinkCounters.TxNonAggCount += TxAggCnt.field.NonAggTxCount;
-		pAd->RalinkCounters.TxAgg1MPDUCount += TxAggCnt0.field.AggSize1Count;
-		pAd->RalinkCounters.TxAgg2MPDUCount += TxAggCnt0.field.AggSize2Count;
+		pRalinkCounters->TxAggCount += TxAggCnt.field.AggTxCount;
+		pRalinkCounters->TxNonAggCount += TxAggCnt.field.NonAggTxCount;
+		pRalinkCounters->TxAgg1MPDUCount +=
+		    TxAggCnt0.field.AggSize1Count;
+		pRalinkCounters->TxAgg2MPDUCount +=
+		    TxAggCnt0.field.AggSize2Count;
 
-		pAd->RalinkCounters.TxAgg3MPDUCount += TxAggCnt1.field.AggSize3Count;
-		pAd->RalinkCounters.TxAgg4MPDUCount += TxAggCnt1.field.AggSize4Count;
-		pAd->RalinkCounters.TxAgg5MPDUCount += TxAggCnt2.field.AggSize5Count;
-		pAd->RalinkCounters.TxAgg6MPDUCount += TxAggCnt2.field.AggSize6Count;
+		pRalinkCounters->TxAgg3MPDUCount +=
+		    TxAggCnt1.field.AggSize3Count;
+		pRalinkCounters->TxAgg4MPDUCount +=
+		    TxAggCnt1.field.AggSize4Count;
+		pRalinkCounters->TxAgg5MPDUCount +=
+		    TxAggCnt2.field.AggSize5Count;
+		pRalinkCounters->TxAgg6MPDUCount +=
+		    TxAggCnt2.field.AggSize6Count;
 
-		pAd->RalinkCounters.TxAgg7MPDUCount += TxAggCnt3.field.AggSize7Count;
-		pAd->RalinkCounters.TxAgg8MPDUCount += TxAggCnt3.field.AggSize8Count;
-		pAd->RalinkCounters.TxAgg9MPDUCount += TxAggCnt4.field.AggSize9Count;
-		pAd->RalinkCounters.TxAgg10MPDUCount += TxAggCnt4.field.AggSize10Count;
+		pRalinkCounters->TxAgg7MPDUCount +=
+		    TxAggCnt3.field.AggSize7Count;
+		pRalinkCounters->TxAgg8MPDUCount +=
+		    TxAggCnt3.field.AggSize8Count;
+		pRalinkCounters->TxAgg9MPDUCount +=
+		    TxAggCnt4.field.AggSize9Count;
+		pRalinkCounters->TxAgg10MPDUCount +=
+		    TxAggCnt4.field.AggSize10Count;
 
-		pAd->RalinkCounters.TxAgg11MPDUCount += TxAggCnt5.field.AggSize11Count;
-		pAd->RalinkCounters.TxAgg12MPDUCount += TxAggCnt5.field.AggSize12Count;
-		pAd->RalinkCounters.TxAgg13MPDUCount += TxAggCnt6.field.AggSize13Count;
-		pAd->RalinkCounters.TxAgg14MPDUCount += TxAggCnt6.field.AggSize14Count;
+		pRalinkCounters->TxAgg11MPDUCount +=
+		    TxAggCnt5.field.AggSize11Count;
+		pRalinkCounters->TxAgg12MPDUCount +=
+		    TxAggCnt5.field.AggSize12Count;
+		pRalinkCounters->TxAgg13MPDUCount +=
+		    TxAggCnt6.field.AggSize13Count;
+		pRalinkCounters->TxAgg14MPDUCount +=
+		    TxAggCnt6.field.AggSize14Count;
 
-		pAd->RalinkCounters.TxAgg15MPDUCount += TxAggCnt7.field.AggSize15Count;
-		pAd->RalinkCounters.TxAgg16MPDUCount += TxAggCnt7.field.AggSize16Count;
+		pRalinkCounters->TxAgg15MPDUCount +=
+		    TxAggCnt7.field.AggSize15Count;
+		pRalinkCounters->TxAgg16MPDUCount +=
+		    TxAggCnt7.field.AggSize16Count;
 
-		// Calculate the transmitted A-MPDU count
-		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += TxAggCnt0.field.AggSize1Count;
-		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt0.field.AggSize2Count / 2);
+		/* Calculate the transmitted A-MPDU count */
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
+		    TxAggCnt0.field.AggSize1Count;
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
+		    (TxAggCnt0.field.AggSize2Count / 2);
 
-		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize3Count / 3);
-		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize4Count / 4);
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
+		    (TxAggCnt1.field.AggSize3Count / 3);
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
+		    (TxAggCnt1.field.AggSize4Count / 4);
 
-		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize5Count / 5);
-		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize6Count / 6);
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
+		    (TxAggCnt2.field.AggSize5Count / 5);
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
+		    (TxAggCnt2.field.AggSize6Count / 6);
 
-		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize7Count / 7);
-		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize8Count / 8);
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
+		    (TxAggCnt3.field.AggSize7Count / 7);
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
+		    (TxAggCnt3.field.AggSize8Count / 8);
 
-		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize9Count / 9);
-		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize10Count / 10);
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
+		    (TxAggCnt4.field.AggSize9Count / 9);
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
+		    (TxAggCnt4.field.AggSize10Count / 10);
 
-		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize11Count / 11);
-		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize12Count / 12);
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
+		    (TxAggCnt5.field.AggSize11Count / 11);
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
+		    (TxAggCnt5.field.AggSize12Count / 12);
 
-		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize13Count / 13);
-		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize14Count / 14);
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
+		    (TxAggCnt6.field.AggSize13Count / 13);
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
+		    (TxAggCnt6.field.AggSize14Count / 14);
 
-		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize15Count / 15);
-		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize16Count / 16);
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
+		    (TxAggCnt7.field.AggSize15Count / 15);
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
+		    (TxAggCnt7.field.AggSize16Count / 16);
 	}
 
-
-
 }
 
-
 /*
 	========================================================================
 
@@ -2913,25 +2299,33 @@
 
 	========================================================================
 */
-VOID	NICResetFromError(
-	IN	PRTMP_ADAPTER	pAd)
+void NICResetFromError(struct rt_rtmp_adapter *pAd)
 {
-	// Reset BBP (according to alex, reset ASIC will force reset BBP
-	// Therefore, skip the reset BBP
-	// RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x2);
+	/* Reset BBP (according to alex, reset ASIC will force reset BBP */
+	/* Therefore, skip the reset BBP */
+	/* RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x2); */
 
 	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
-	// Remove ASIC from reset state
+	/* Remove ASIC from reset state */
 	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
 
 	NICInitializeAdapter(pAd, FALSE);
 	NICInitAsicFromEEPROM(pAd);
 
-	// Switch to current channel, since during reset process, the connection should remains on.
+	/* Switch to current channel, since during reset process, the connection should remains on. */
 	AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
 	AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
 }
 
+int NICLoadFirmware(struct rt_rtmp_adapter *pAd)
+{
+	int status = NDIS_STATUS_SUCCESS;
+	if (pAd->chipOps.loadFirmware)
+		status = pAd->chipOps.loadFirmware(pAd);
+
+	return status;
+}
+
 /*
 	========================================================================
 
@@ -2945,100 +2339,12 @@
 
 	========================================================================
 */
-VOID NICEraseFirmware(
-	IN PRTMP_ADAPTER pAd)
+void NICEraseFirmware(struct rt_rtmp_adapter *pAd)
 {
-	ULONG i;
+	if (pAd->chipOps.eraseFirmware)
+		pAd->chipOps.eraseFirmware(pAd);
 
-	for(i=0; i<MAX_FIRMWARE_IMAGE_SIZE; i+=4)
-		RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, 0);
-
-}/* End of NICEraseFirmware */
-
-/*
-	========================================================================
-
-	Routine Description:
-		Load 8051 firmware RT2561.BIN file into MAC ASIC
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		NDIS_STATUS_SUCCESS         firmware image load ok
-		NDIS_STATUS_FAILURE         image not found
-
-	IRQL = PASSIVE_LEVEL
-
-	========================================================================
-*/
-NDIS_STATUS NICLoadFirmware(
-	IN PRTMP_ADAPTER pAd)
-{
-	NDIS_STATUS		Status = NDIS_STATUS_SUCCESS;
-	PUCHAR			pFirmwareImage;
-	ULONG			FileLength, Index;
-	//ULONG			firm;
-	UINT32			MacReg = 0;
-#ifdef RT2870
-	UINT32			Version = (pAd->MACVersion >> 16);
-#endif // RT2870 //
-
-	pFirmwareImage = FirmwareImage;
-	FileLength = sizeof(FirmwareImage);
-#ifdef RT2870
-	// New 8k byte firmware size for RT3071/RT3072
-	//printk("Usb Chip\n");
-	if (FIRMWAREIMAGE_LENGTH == FIRMWAREIMAGE_MAX_LENGTH)
-	//The firmware image consists of two parts. One is the origianl and the other is the new.
-	//Use Second Part
-	{
-		if ((Version != 0x2860) && (Version != 0x2872) && (Version != 0x3070))
-		{	// Use Firmware V2.
-			//printk("KH:Use New Version,part2\n");
-			pFirmwareImage = (PUCHAR)&FirmwareImage[FIRMWAREIMAGEV1_LENGTH];
-			FileLength = FIRMWAREIMAGEV2_LENGTH;
-		}
-		else
-		{
-			//printk("KH:Use New Version,part1\n");
-			pFirmwareImage = FirmwareImage;
-			FileLength = FIRMWAREIMAGEV1_LENGTH;
-		}
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("KH: bin file should be 8KB.\n"));
-		Status = NDIS_STATUS_FAILURE;
-	}
-
-#endif // RT2870 //
-
-	RT28XX_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength);
-
-	/* check if MCU is ready */
-	Index = 0;
-	do
-	{
-		RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacReg);
-
-		if (MacReg & 0x80)
-			break;
-
-		RTMPusecDelay(1000);
-	} while (Index++ < 1000);
-
-    if (Index > 1000)
-	{
-		Status = NDIS_STATUS_FAILURE;
-		DBGPRINT(RT_DEBUG_ERROR, ("NICLoadFirmware: MCU is not ready\n\n\n"));
-	} /* End of if */
-
-    DBGPRINT(RT_DEBUG_TRACE,
-			 ("<=== %s (status=%d)\n", __func__, Status));
-    return Status;
-} /* End of NICLoadFirmware */
-
+}				/* End of NICEraseFirmware */
 
 /*
 	========================================================================
@@ -3061,8 +2367,7 @@
 
 	========================================================================
 */
-NDIS_STATUS NICLoadRateSwitchingParams(
-	IN PRTMP_ADAPTER pAd)
+int NICLoadRateSwitchingParams(struct rt_rtmp_adapter *pAd)
 {
 	return NDIS_STATUS_SUCCESS;
 }
@@ -3071,53 +2376,6 @@
 	========================================================================
 
 	Routine Description:
-		if  pSrc1 all zero with length Length, return 0.
-		If not all zero, return 1
-
-	Arguments:
-		pSrc1
-
-	Return Value:
-		1:			not all zero
-		0:			all zero
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-ULONG	RTMPNotAllZero(
-	IN	PVOID	pSrc1,
-	IN	ULONG	Length)
-{
-	PUCHAR	pMem1;
-	ULONG	Index = 0;
-
-	pMem1 = (PUCHAR) pSrc1;
-
-	for (Index = 0; Index < Length; Index++)
-	{
-		if (pMem1[Index] != 0x0)
-		{
-			break;
-		}
-	}
-
-	if (Index == Length)
-	{
-		return (0);
-	}
-	else
-	{
-		return (1);
-	}
-}
-
-/*
-	========================================================================
-
-	Routine Description:
 		Compare two memory block
 
 	Arguments:
@@ -3135,27 +2393,23 @@
 
 	========================================================================
 */
-ULONG	RTMPCompareMemory(
-	IN	PVOID	pSrc1,
-	IN	PVOID	pSrc2,
-	IN	ULONG	Length)
+unsigned long RTMPCompareMemory(void *pSrc1, void *pSrc2, unsigned long Length)
 {
-	PUCHAR	pMem1;
-	PUCHAR	pMem2;
-	ULONG	Index = 0;
+	u8 *pMem1;
+	u8 *pMem2;
+	unsigned long Index = 0;
 
-	pMem1 = (PUCHAR) pSrc1;
-	pMem2 = (PUCHAR) pSrc2;
+	pMem1 = (u8 *)pSrc1;
+	pMem2 = (u8 *)pSrc2;
 
-	for (Index = 0; Index < Length; Index++)
-	{
+	for (Index = 0; Index < Length; Index++) {
 		if (pMem1[Index] > pMem2[Index])
 			return (1);
 		else if (pMem1[Index] < pMem2[Index])
 			return (2);
 	}
 
-	// Equal
+	/* Equal */
 	return (0);
 }
 
@@ -3179,37 +2433,18 @@
 
 	========================================================================
 */
-VOID	RTMPZeroMemory(
-	IN	PVOID	pSrc,
-	IN	ULONG	Length)
+void RTMPZeroMemory(void *pSrc, unsigned long Length)
 {
-	PUCHAR	pMem;
-	ULONG	Index = 0;
+	u8 *pMem;
+	unsigned long Index = 0;
 
-	pMem = (PUCHAR) pSrc;
+	pMem = (u8 *)pSrc;
 
-	for (Index = 0; Index < Length; Index++)
-	{
+	for (Index = 0; Index < Length; Index++) {
 		pMem[Index] = 0x00;
 	}
 }
 
-VOID	RTMPFillMemory(
-	IN	PVOID	pSrc,
-	IN	ULONG	Length,
-	IN	UCHAR	Fill)
-{
-	PUCHAR	pMem;
-	ULONG	Index = 0;
-
-	pMem = (PUCHAR) pSrc;
-
-	for (Index = 0; Index < Length; Index++)
-	{
-		pMem[Index] = Fill;
-	}
-}
-
 /*
 	========================================================================
 
@@ -3231,22 +2466,18 @@
 
 	========================================================================
 */
-VOID	RTMPMoveMemory(
-	OUT	PVOID	pDest,
-	IN	PVOID	pSrc,
-	IN	ULONG	Length)
+void RTMPMoveMemory(void *pDest, void *pSrc, unsigned long Length)
 {
-	PUCHAR	pMem1;
-	PUCHAR	pMem2;
-	UINT	Index;
+	u8 *pMem1;
+	u8 *pMem2;
+	u32 Index;
 
-	ASSERT((Length==0) || (pDest && pSrc));
+	ASSERT((Length == 0) || (pDest && pSrc));
 
-	pMem1 = (PUCHAR) pDest;
-	pMem2 = (PUCHAR) pSrc;
+	pMem1 = (u8 *)pDest;
+	pMem2 = (u8 *)pSrc;
 
-	for (Index = 0; Index < Length; Index++)
-	{
+	for (Index = 0; Index < Length; Index++) {
 		pMem1[Index] = pMem2[Index];
 	}
 }
@@ -3269,17 +2500,16 @@
 
 	========================================================================
 */
-VOID	UserCfgInit(
-	IN	PRTMP_ADAPTER pAd)
+void UserCfgInit(struct rt_rtmp_adapter *pAd)
 {
-    UINT key_index, bss_index;
+	u32 key_index, bss_index;
 
 	DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit\n"));
 
-	//
-	//  part I. intialize common configuration
-	//
-#ifdef RT2870
+	/* */
+	/*  part I. intialize common configuration */
+	/* */
+#ifdef RTMP_MAC_USB
 	pAd->BulkOutReq = 0;
 
 	pAd->BulkOutComplete = 0;
@@ -3289,72 +2519,71 @@
 	pAd->BulkInComplete = 0;
 	pAd->BulkInCompleteFail = 0;
 
-	//pAd->QuickTimerP = 100;
-	//pAd->TurnAggrBulkInCount = 0;
+	/*pAd->QuickTimerP = 100; */
+	/*pAd->TurnAggrBulkInCount = 0; */
 	pAd->bUsbTxBulkAggre = 0;
 
-	// init as unsed value to ensure driver will set to MCU once.
-	pAd->LedIndicatorStregth = 0xFF;
+	/* init as unsed value to ensure driver will set to MCU once. */
+	pAd->LedIndicatorStrength = 0xFF;
 
 	pAd->CommonCfg.MaxPktOneTxBulk = 2;
 	pAd->CommonCfg.TxBulkFactor = 1;
-	pAd->CommonCfg.RxBulkFactor =1;
+	pAd->CommonCfg.RxBulkFactor = 1;
 
-	pAd->CommonCfg.TxPower = 100; //mW
+	pAd->CommonCfg.TxPower = 100;	/*mW */
 
-	NdisZeroMemory(&pAd->CommonCfg.IOTestParm, sizeof(pAd->CommonCfg.IOTestParm));
-#endif // RT2870 //
+	NdisZeroMemory(&pAd->CommonCfg.IOTestParm,
+		       sizeof(pAd->CommonCfg.IOTestParm));
+#endif /* RTMP_MAC_USB // */
 
-	for(key_index=0; key_index<SHARE_KEY_NUM; key_index++)
-	{
-		for(bss_index = 0; bss_index < MAX_MBSSID_NUM; bss_index++)
-		{
+	for (key_index = 0; key_index < SHARE_KEY_NUM; key_index++) {
+		for (bss_index = 0; bss_index < MAX_MBSSID_NUM; bss_index++) {
 			pAd->SharedKey[bss_index][key_index].KeyLen = 0;
-			pAd->SharedKey[bss_index][key_index].CipherAlg = CIPHER_NONE;
+			pAd->SharedKey[bss_index][key_index].CipherAlg =
+			    CIPHER_NONE;
 		}
 	}
 
-#ifdef RT2870
 	pAd->EepromAccess = FALSE;
-#endif
+
 	pAd->Antenna.word = 0;
 	pAd->CommonCfg.BBPCurrentBW = BW_20;
 
 	pAd->LedCntl.word = 0;
-#ifdef RT2860
-	pAd->LedIndicatorStregth = 0;
+#ifdef RTMP_MAC_PCI
+	pAd->LedIndicatorStrength = 0;
 	pAd->RLnkCtrlOffset = 0;
 	pAd->HostLnkCtrlOffset = 0;
+	pAd->StaCfg.PSControl.field.EnableNewPS = TRUE;
 	pAd->CheckDmaBusyCount = 0;
-#endif
+#endif /* RTMP_MAC_PCI // */
 
-	pAd->bAutoTxAgcA = FALSE;			// Default is OFF
-	pAd->bAutoTxAgcG = FALSE;			// Default is OFF
+	pAd->bAutoTxAgcA = FALSE;	/* Default is OFF */
+	pAd->bAutoTxAgcG = FALSE;	/* Default is OFF */
 	pAd->RfIcType = RFIC_2820;
 
-	// Init timer for reset complete event
+	/* Init timer for reset complete event */
 	pAd->CommonCfg.CentralChannel = 1;
 	pAd->bForcePrintTX = FALSE;
 	pAd->bForcePrintRX = FALSE;
 	pAd->bStaFifoTest = FALSE;
 	pAd->bProtectionTest = FALSE;
-	pAd->bHCCATest = FALSE;
-	pAd->bGenOneHCCA = FALSE;
-	pAd->CommonCfg.Dsifs = 10;      // in units of usec
-	pAd->CommonCfg.TxPower = 100; //mW
-	pAd->CommonCfg.TxPowerPercentage = 0xffffffff; // AUTO
-	pAd->CommonCfg.TxPowerDefault = 0xffffffff; // AUTO
-	pAd->CommonCfg.TxPreamble = Rt802_11PreambleAuto; // use Long preamble on TX by defaut
+	pAd->CommonCfg.Dsifs = 10;	/* in units of usec */
+	pAd->CommonCfg.TxPower = 100;	/*mW */
+	pAd->CommonCfg.TxPowerPercentage = 0xffffffff;	/* AUTO */
+	pAd->CommonCfg.TxPowerDefault = 0xffffffff;	/* AUTO */
+	pAd->CommonCfg.TxPreamble = Rt802_11PreambleAuto;	/* use Long preamble on TX by defaut */
 	pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
 	pAd->CommonCfg.RtsThreshold = 2347;
 	pAd->CommonCfg.FragmentThreshold = 2346;
-	pAd->CommonCfg.UseBGProtection = 0;    // 0: AUTO
-	pAd->CommonCfg.bEnableTxBurst = TRUE; //0;
-	pAd->CommonCfg.PhyMode = 0xff;     // unknown
+	pAd->CommonCfg.UseBGProtection = 0;	/* 0: AUTO */
+	pAd->CommonCfg.bEnableTxBurst = TRUE;	/*0; */
+	pAd->CommonCfg.PhyMode = 0xff;	/* unknown */
 	pAd->CommonCfg.BandState = UNKNOWN_BAND;
 	pAd->CommonCfg.RadarDetect.CSPeriod = 10;
 	pAd->CommonCfg.RadarDetect.CSCount = 0;
 	pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
+
 	pAd->CommonCfg.RadarDetect.ChMovingTime = 65;
 	pAd->CommonCfg.RadarDetect.LongPulseRadarTh = 3;
 	pAd->CommonCfg.bAPSDCapable = FALSE;
@@ -3367,18 +2596,22 @@
 
 	NdisZeroMemory(&pAd->BeaconTxWI, sizeof(pAd->BeaconTxWI));
 
-	NdisZeroMemory(&pAd->CommonCfg.HtCapability, sizeof(pAd->CommonCfg.HtCapability));
+	NdisZeroMemory(&pAd->CommonCfg.HtCapability,
+		       sizeof(pAd->CommonCfg.HtCapability));
 	pAd->HTCEnable = FALSE;
 	pAd->bBroadComHT = FALSE;
 	pAd->CommonCfg.bRdg = FALSE;
 
-	NdisZeroMemory(&pAd->CommonCfg.AddHTInfo, sizeof(pAd->CommonCfg.AddHTInfo));
+	NdisZeroMemory(&pAd->CommonCfg.AddHTInfo,
+		       sizeof(pAd->CommonCfg.AddHTInfo));
 	pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
 	pAd->CommonCfg.BACapability.field.MpduDensity = 0;
 	pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
-	pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64; //32;
-	pAd->CommonCfg.BACapability.field.TxBAWinLimit = 64; //32;
-	DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit. BACapability = 0x%x\n", pAd->CommonCfg.BACapability.word));
+	pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;	/*32; */
+	pAd->CommonCfg.BACapability.field.TxBAWinLimit = 64;	/*32; */
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("--> UserCfgInit. BACapability = 0x%x\n",
+		  pAd->CommonCfg.BACapability.word));
 
 	pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
 	BATableInit(pAd, &pAd->BATable);
@@ -3386,28 +2619,35 @@
 	pAd->CommonCfg.bExtChannelSwitchAnnouncement = 1;
 	pAd->CommonCfg.bHTProtect = 1;
 	pAd->CommonCfg.bMIMOPSEnable = TRUE;
+	/*2008/11/05:KH add to support Antenna power-saving of AP<-- */
+	pAd->CommonCfg.bGreenAPEnable = FALSE;
+	/*2008/11/05:KH add to support Antenna power-saving of AP--> */
 	pAd->CommonCfg.bBADecline = FALSE;
 	pAd->CommonCfg.bDisableReordering = FALSE;
 
-	pAd->CommonCfg.TxBASize = 7;
+	if (pAd->MACVersion == 0x28720200) {
+		pAd->CommonCfg.TxBASize = 13;	/*by Jerry recommend */
+	} else {
+		pAd->CommonCfg.TxBASize = 7;
+	}
 
 	pAd->CommonCfg.REGBACapability.word = pAd->CommonCfg.BACapability.word;
 
-	//pAd->CommonCfg.HTPhyMode.field.BW = BW_20;
-	//pAd->CommonCfg.HTPhyMode.field.MCS = MCS_AUTO;
-	//pAd->CommonCfg.HTPhyMode.field.ShortGI = GI_800;
-	//pAd->CommonCfg.HTPhyMode.field.STBC = STBC_NONE;
+	/*pAd->CommonCfg.HTPhyMode.field.BW = BW_20; */
+	/*pAd->CommonCfg.HTPhyMode.field.MCS = MCS_AUTO; */
+	/*pAd->CommonCfg.HTPhyMode.field.ShortGI = GI_800; */
+	/*pAd->CommonCfg.HTPhyMode.field.STBC = STBC_NONE; */
 	pAd->CommonCfg.TxRate = RATE_6;
 
 	pAd->CommonCfg.MlmeTransmit.field.MCS = MCS_RATE_6;
 	pAd->CommonCfg.MlmeTransmit.field.BW = BW_20;
 	pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
 
-	pAd->CommonCfg.BeaconPeriod = 100;     // in mSec
+	pAd->CommonCfg.BeaconPeriod = 100;	/* in mSec */
 
-	//
-	// part II. intialize STA specific configuration
-	//
+	/* */
+	/* part II. intialize STA specific configuration */
+	/* */
 	{
 		RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_DIRECT);
 		RX_FILTER_CLEAR_FLAG(pAd, fRX_FILTER_ACCEPT_MULTICAST);
@@ -3422,22 +2662,23 @@
 		pAd->StaCfg.bMixCipher = FALSE;
 		pAd->StaCfg.DefaultKeyId = 0;
 
-		// 802.1x port control
+		/* 802.1x port control */
 		pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
 		pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
 		pAd->StaCfg.LastMicErrorTime = 0;
-		pAd->StaCfg.MicErrCnt        = 0;
-		pAd->StaCfg.bBlockAssoc      = FALSE;
-		pAd->StaCfg.WpaState         = SS_NOTUSE;
+		pAd->StaCfg.MicErrCnt = 0;
+		pAd->StaCfg.bBlockAssoc = FALSE;
+		pAd->StaCfg.WpaState = SS_NOTUSE;
 
-		pAd->CommonCfg.NdisRadioStateOff = FALSE;		// New to support microsoft disable radio with OID command
+		pAd->CommonCfg.NdisRadioStateOff = FALSE;	/* New to support microsoft disable radio with OID command */
 
 		pAd->StaCfg.RssiTrigger = 0;
-		NdisZeroMemory(&pAd->StaCfg.RssiSample, sizeof(RSSI_SAMPLE));
-		pAd->StaCfg.RssiTriggerMode = RSSI_TRIGGERED_UPON_BELOW_THRESHOLD;
+		NdisZeroMemory(&pAd->StaCfg.RssiSample, sizeof(struct rt_rssi_sample));
+		pAd->StaCfg.RssiTriggerMode =
+		    RSSI_TRIGGERED_UPON_BELOW_THRESHOLD;
 		pAd->StaCfg.AtimWin = 0;
-		pAd->StaCfg.DefaultListenCount = 3;//default listen count;
-		pAd->StaCfg.BssType = BSS_INFRA;  // BSS_INFRA or BSS_ADHOC or BSS_MONITOR
+		pAd->StaCfg.DefaultListenCount = 3;	/*default listen count; */
+		pAd->StaCfg.BssType = BSS_INFRA;	/* BSS_INFRA or BSS_ADHOC or BSS_MONITOR */
 		pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
 		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
 		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
@@ -3446,158 +2687,174 @@
 		pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
 	}
 
-	// global variables mXXXX used in MAC protocol state machines
+#ifdef PCIE_PS_SUPPORT
+	pAd->brt30xxBanMcuCmd = FALSE;
+	pAd->b3090ESpecialChip = FALSE;
+/*KH Debug:the following must be removed */
+	pAd->StaCfg.PSControl.field.rt30xxPowerMode = 3;
+	pAd->StaCfg.PSControl.field.rt30xxForceASPMTest = 0;
+	pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM = 1;
+#endif /* PCIE_PS_SUPPORT // */
+
+	/* global variables mXXXX used in MAC protocol state machines */
 	OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
 	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
 	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
 
-	// PHY specification
-	pAd->CommonCfg.PhyMode = PHY_11BG_MIXED;		// default PHY mode
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);  // CCK use LONG preamble
+	/* PHY specification */
+	pAd->CommonCfg.PhyMode = PHY_11BG_MIXED;	/* default PHY mode */
+	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);	/* CCK use long preamble */
 
 	{
-		// user desired power mode
+		/* user desired power mode */
 		pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
 		pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
 		pAd->StaCfg.bWindowsACCAMEnable = FALSE;
 
-		RTMPInitTimer(pAd, &pAd->StaCfg.StaQuickResponeForRateUpTimer, GET_TIMER_FUNCTION(StaQuickResponeForRateUpExec), pAd, FALSE);
+		RTMPInitTimer(pAd, &pAd->StaCfg.StaQuickResponeForRateUpTimer,
+			      GET_TIMER_FUNCTION(StaQuickResponeForRateUpExec),
+			      pAd, FALSE);
 		pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
 
-		// Patch for Ndtest
+		/* Patch for Ndtest */
 		pAd->StaCfg.ScanCnt = 0;
 
-		// CCX 2.0 control flag init
-		pAd->StaCfg.CCXEnable = FALSE;
-		pAd->StaCfg.CCXReqType = MSRN_TYPE_UNUSED;
-		pAd->StaCfg.CCXQosECWMin	= 4;
-		pAd->StaCfg.CCXQosECWMax	= 10;
+		pAd->StaCfg.bHwRadio = TRUE;	/* Default Hardware Radio status is On */
+		pAd->StaCfg.bSwRadio = TRUE;	/* Default Software Radio status is On */
+		pAd->StaCfg.bRadio = TRUE;	/* bHwRadio && bSwRadio */
+		pAd->StaCfg.bHardwareRadio = FALSE;	/* Default is OFF */
+		pAd->StaCfg.bShowHiddenSSID = FALSE;	/* Default no show */
 
-		pAd->StaCfg.bHwRadio  = TRUE; // Default Hardware Radio status is On
-		pAd->StaCfg.bSwRadio  = TRUE; // Default Software Radio status is On
-		pAd->StaCfg.bRadio    = TRUE; // bHwRadio && bSwRadio
-		pAd->StaCfg.bHardwareRadio = FALSE;		// Default is OFF
-		pAd->StaCfg.bShowHiddenSSID = FALSE;		// Default no show
-
-		// Nitro mode control
+		/* Nitro mode control */
 		pAd->StaCfg.bAutoReconnect = TRUE;
 
-		// Save the init time as last scan time, the system should do scan after 2 seconds.
-		// This patch is for driver wake up from standby mode, system will do scan right away.
-		pAd->StaCfg.LastScanTime = 0;
-		NdisZeroMemory(pAd->nickname, IW_ESSID_MAX_SIZE+1);
-		sprintf(pAd->nickname, "%s", STA_NIC_DEVICE_NAME);
-		RTMPInitTimer(pAd, &pAd->StaCfg.WpaDisassocAndBlockAssocTimer, GET_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc), pAd, FALSE);
+		/* Save the init time as last scan time, the system should do scan after 2 seconds. */
+		/* This patch is for driver wake up from standby mode, system will do scan right away. */
+		NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime);
+		if (pAd->StaCfg.LastScanTime > 10 * OS_HZ)
+			pAd->StaCfg.LastScanTime -= (10 * OS_HZ);
+
+		NdisZeroMemory(pAd->nickname, IW_ESSID_MAX_SIZE + 1);
+#ifdef RTMP_MAC_PCI
+		sprintf((char *)pAd->nickname, "RT2860STA");
+#endif /* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
+		sprintf((char *)pAd->nickname, "RT2870STA");
+#endif /* RTMP_MAC_USB // */
+		RTMPInitTimer(pAd, &pAd->StaCfg.WpaDisassocAndBlockAssocTimer,
+			      GET_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc),
+			      pAd, FALSE);
 		pAd->StaCfg.IEEE8021X = FALSE;
 		pAd->StaCfg.IEEE8021x_required_keys = FALSE;
 		pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
+		pAd->StaCfg.bRSN_IE_FromWpaSupplicant = FALSE;
 		pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
+
+		NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
+
+		pAd->StaCfg.bAutoConnectByBssid = FALSE;
+		pAd->StaCfg.BeaconLostTime = BEACON_LOST_TIME;
+		NdisZeroMemory(pAd->StaCfg.WpaPassPhrase, 64);
+		pAd->StaCfg.WpaPassPhraseLen = 0;
+		pAd->StaCfg.bAutoRoaming = FALSE;
+		pAd->StaCfg.bForceTxBurst = FALSE;
 	}
 
-	// Default for extra information is not valid
+	/* Default for extra information is not valid */
 	pAd->ExtraInfo = EXTRA_INFO_CLEAR;
 
-	// Default Config change flag
+	/* Default Config change flag */
 	pAd->bConfigChanged = FALSE;
 
-	//
-	// part III. AP configurations
-	//
+	/* */
+	/* part III. AP configurations */
+	/* */
 
-
-	//
-	// part IV. others
-	//
-	// dynamic BBP R66:sensibity tuning to overcome background noise
-	pAd->BbpTuning.bEnable                = TRUE;
+	/* */
+	/* part IV. others */
+	/* */
+	/* dynamic BBP R66:sensibity tuning to overcome background noise */
+	pAd->BbpTuning.bEnable = TRUE;
 	pAd->BbpTuning.FalseCcaLowerThreshold = 100;
 	pAd->BbpTuning.FalseCcaUpperThreshold = 512;
-	pAd->BbpTuning.R66Delta               = 4;
+	pAd->BbpTuning.R66Delta = 4;
 	pAd->Mlme.bEnableAutoAntennaCheck = TRUE;
 
-	//
-	// Also initial R66CurrentValue, RTUSBResumeMsduTransmission might use this value.
-	// if not initial this value, the default value will be 0.
-	//
+	/* */
+	/* Also initial R66CurrentValue, RTUSBResumeMsduTransmission might use this value. */
+	/* if not initial this value, the default value will be 0. */
+	/* */
 	pAd->BbpTuning.R66CurrentValue = 0x38;
 
 	pAd->Bbp94 = BBPR94_DEFAULT;
 	pAd->BbpForCCK = FALSE;
 
-	// initialize MAC table and allocate spin lock
-	NdisZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE));
+	/* Default is FALSE for test bit 1 */
+	/*pAd->bTest1 = FALSE; */
+
+	/* initialize MAC table and allocate spin lock */
+	NdisZeroMemory(&pAd->MacTab, sizeof(struct rt_mac_table));
 	InitializeQueueHeader(&pAd->MacTab.McastPsQueue);
 	NdisAllocateSpinLock(&pAd->MacTabLock);
 
+	/*RTMPInitTimer(pAd, &pAd->RECBATimer, RECBATimerTimeout, pAd, TRUE); */
+	/*RTMPSetTimer(&pAd->RECBATimer, REORDER_EXEC_INTV); */
+
 	pAd->CommonCfg.bWiFiTest = FALSE;
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
 	pAd->bPCIclkOff = FALSE;
+#endif /* RTMP_MAC_PCI // */
 
 	RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-#endif
 	DBGPRINT(RT_DEBUG_TRACE, ("<-- UserCfgInit\n"));
 }
 
-// IRQL = PASSIVE_LEVEL
-UCHAR BtoH(char ch)
+/* IRQL = PASSIVE_LEVEL */
+u8 BtoH(char ch)
 {
-	if (ch >= '0' && ch <= '9') return (ch - '0');        // Handle numerals
-	if (ch >= 'A' && ch <= 'F') return (ch - 'A' + 0xA);  // Handle capitol hex digits
-	if (ch >= 'a' && ch <= 'f') return (ch - 'a' + 0xA);  // Handle small hex digits
-	return(255);
+	if (ch >= '0' && ch <= '9')
+		return (ch - '0');	/* Handle numerals */
+	if (ch >= 'A' && ch <= 'F')
+		return (ch - 'A' + 0xA);	/* Handle capitol hex digits */
+	if (ch >= 'a' && ch <= 'f')
+		return (ch - 'a' + 0xA);	/* Handle small hex digits */
+	return (255);
 }
 
-//
-//  FUNCTION: AtoH(char *, UCHAR *, int)
-//
-//  PURPOSE:  Converts ascii string to network order hex
-//
-//  PARAMETERS:
-//    src    - pointer to input ascii string
-//    dest   - pointer to output hex
-//    destlen - size of dest
-//
-//  COMMENTS:
-//
-//    2 ascii bytes make a hex byte so must put 1st ascii byte of pair
-//    into upper nibble and 2nd ascii byte of pair into lower nibble.
-//
-// IRQL = PASSIVE_LEVEL
+/* */
+/*  FUNCTION: AtoH(char *, u8 *, int) */
+/* */
+/*  PURPOSE:  Converts ascii string to network order hex */
+/* */
+/*  PARAMETERS: */
+/*    src    - pointer to input ascii string */
+/*    dest   - pointer to output hex */
+/*    destlen - size of dest */
+/* */
+/*  COMMENTS: */
+/* */
+/*    2 ascii bytes make a hex byte so must put 1st ascii byte of pair */
+/*    into upper nibble and 2nd ascii byte of pair into lower nibble. */
+/* */
+/* IRQL = PASSIVE_LEVEL */
 
-void AtoH(char * src, UCHAR * dest, int destlen)
+void AtoH(char *src, u8 *dest, int destlen)
 {
-	char * srcptr;
-	PUCHAR destTemp;
+	char *srcptr;
+	u8 *destTemp;
 
 	srcptr = src;
-	destTemp = (PUCHAR) dest;
+	destTemp = (u8 *)dest;
 
-	while(destlen--)
-	{
-		*destTemp = BtoH(*srcptr++) << 4;    // Put 1st ascii byte in upper nibble.
-		*destTemp += BtoH(*srcptr++);      // Add 2nd ascii byte to above.
+	while (destlen--) {
+		*destTemp = BtoH(*srcptr++) << 4;	/* Put 1st ascii byte in upper nibble. */
+		*destTemp += BtoH(*srcptr++);	/* Add 2nd ascii byte to above. */
 		destTemp++;
 	}
 }
 
-VOID	RTMPPatchMacBbpBug(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	ULONG	Index;
-
-	// Initialize BBP register to default value
-	for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++)
-	{
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, (UCHAR)BBPRegTable[Index].Value);
-	}
-
-	// Initialize RF register to default value
-	AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-	AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-
-	// Re-init BBP register from EEPROM value
-	NICInitAsicFromEEPROM(pAd);
-}
+/*+++Mark by shiang, not use now, need to remove after confirm */
+/*---Mark by shiang, not use now, need to remove after confirm */
 
 /*
 	========================================================================
@@ -3618,29 +2875,26 @@
 
 	========================================================================
 */
-VOID	RTMPInitTimer(
-	IN	PRTMP_ADAPTER			pAd,
-	IN	PRALINK_TIMER_STRUCT	pTimer,
-	IN	PVOID					pTimerFunc,
-	IN	PVOID					pData,
-	IN	BOOLEAN					Repeat)
+void RTMPInitTimer(struct rt_rtmp_adapter *pAd,
+		   struct rt_ralink_timer *pTimer,
+		   void *pTimerFunc, void *pData, IN BOOLEAN Repeat)
 {
-	//
-	// Set Valid to TRUE for later used.
-	// It will crash if we cancel a timer or set a timer
-	// that we haven't initialize before.
-	//
-	pTimer->Valid      = TRUE;
+	/* */
+	/* Set Valid to TRUE for later used. */
+	/* It will crash if we cancel a timer or set a timer */
+	/* that we haven't initialize before. */
+	/* */
+	pTimer->Valid = TRUE;
 
 	pTimer->PeriodicType = Repeat;
-	pTimer->State      = FALSE;
-	pTimer->cookie = (ULONG) pData;
+	pTimer->State = FALSE;
+	pTimer->cookie = (unsigned long)pData;
 
-#ifdef RT2870
+#ifdef RTMP_TIMER_TASK_SUPPORT
 	pTimer->pAd = pAd;
-#endif // RT2870 //
+#endif /* RTMP_TIMER_TASK_SUPPORT // */
 
-	RTMP_OS_Init_Timer(pAd,	&pTimer->TimerObj,	pTimerFunc, (PVOID) pTimer);
+	RTMP_OS_Init_Timer(pAd, &pTimer->TimerObj, pTimerFunc, (void *)pTimer);
 }
 
 /*
@@ -3661,32 +2915,23 @@
 
 	========================================================================
 */
-VOID	RTMPSetTimer(
-	IN	PRALINK_TIMER_STRUCT	pTimer,
-	IN	ULONG					Value)
+void RTMPSetTimer(struct rt_ralink_timer *pTimer, unsigned long Value)
 {
-	if (pTimer->Valid)
-	{
+	if (pTimer->Valid) {
 		pTimer->TimerValue = Value;
-		pTimer->State      = FALSE;
-		if (pTimer->PeriodicType == TRUE)
-		{
+		pTimer->State = FALSE;
+		if (pTimer->PeriodicType == TRUE) {
 			pTimer->Repeat = TRUE;
 			RTMP_SetPeriodicTimer(&pTimer->TimerObj, Value);
-		}
-		else
-		{
+		} else {
 			pTimer->Repeat = FALSE;
 			RTMP_OS_Add_Timer(&pTimer->TimerObj, Value);
 		}
-	}
-	else
-	{
+	} else {
 		DBGPRINT_ERR(("RTMPSetTimer failed, Timer hasn't been initialize!\n"));
 	}
 }
 
-
 /*
 	========================================================================
 
@@ -3705,28 +2950,20 @@
 
 	========================================================================
 */
-VOID	RTMPModTimer(
-	IN	PRALINK_TIMER_STRUCT	pTimer,
-	IN	ULONG					Value)
+void RTMPModTimer(struct rt_ralink_timer *pTimer, unsigned long Value)
 {
-	BOOLEAN	Cancel;
+	BOOLEAN Cancel;
 
-	if (pTimer->Valid)
-	{
+	if (pTimer->Valid) {
 		pTimer->TimerValue = Value;
-		pTimer->State      = FALSE;
-		if (pTimer->PeriodicType == TRUE)
-		{
+		pTimer->State = FALSE;
+		if (pTimer->PeriodicType == TRUE) {
 			RTMPCancelTimer(pTimer, &Cancel);
 			RTMPSetTimer(pTimer, Value);
-		}
-		else
-		{
+		} else {
 			RTMP_OS_Mod_Timer(&pTimer->TimerObj, Value);
 		}
-	}
-	else
-	{
+	} else {
 		DBGPRINT_ERR(("RTMPModTimer failed, Timer hasn't been initialize!\n"));
 	}
 }
@@ -3752,32 +2989,23 @@
 
 	========================================================================
 */
-VOID	RTMPCancelTimer(
-	IN	PRALINK_TIMER_STRUCT	pTimer,
-	OUT	BOOLEAN					*pCancelled)
+void RTMPCancelTimer(struct rt_ralink_timer *pTimer, OUT BOOLEAN * pCancelled)
 {
-	if (pTimer->Valid)
-	{
+	if (pTimer->Valid) {
 		if (pTimer->State == FALSE)
 			pTimer->Repeat = FALSE;
-			RTMP_OS_Del_Timer(&pTimer->TimerObj, pCancelled);
+
+		RTMP_OS_Del_Timer(&pTimer->TimerObj, pCancelled);
 
 		if (*pCancelled == TRUE)
 			pTimer->State = TRUE;
 
-#ifdef RT2870
-		// We need to go-through the TimerQ to findout this timer handler and remove it if
-		//		it's still waiting for execution.
-
-		RT2870_TimerQ_Remove(pTimer->pAd, pTimer);
-#endif // RT2870 //
-	}
-	else
-	{
-		//
-		// NdisMCancelTimer just canced the timer and not mean release the timer.
-		// And don't set the "Valid" to False. So that we can use this timer again.
-		//
+#ifdef RTMP_TIMER_TASK_SUPPORT
+		/* We need to go-through the TimerQ to findout this timer handler and remove it if */
+		/*              it's still waiting for execution. */
+		RtmpTimerQRemove(pTimer->pAd, pTimer);
+#endif /* RTMP_TIMER_TASK_SUPPORT // */
+	} else {
 		DBGPRINT_ERR(("RTMPCancelTimer failed, Timer hasn't been initialize!\n"));
 	}
 }
@@ -3802,64 +3030,64 @@
 
 	========================================================================
 */
-VOID RTMPSetLED(
-	IN PRTMP_ADAPTER 	pAd,
-	IN UCHAR			Status)
+void RTMPSetLED(struct rt_rtmp_adapter *pAd, u8 Status)
 {
-	//ULONG			data;
-	UCHAR			HighByte = 0;
-	UCHAR			LowByte;
+	/*unsigned long                 data; */
+	u8 HighByte = 0;
+	u8 LowByte;
 
-	LowByte = pAd->LedCntl.field.LedMode&0x7f;
-	switch (Status)
-	{
-		case LED_LINK_DOWN:
-			HighByte = 0x20;
-			AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
-			pAd->LedIndicatorStregth = 0;
-			break;
-		case LED_LINK_UP:
-			if (pAd->CommonCfg.Channel > 14)
-				HighByte = 0xa0;
-			else
-				HighByte = 0x60;
-			AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
-			break;
-		case LED_RADIO_ON:
-			HighByte = 0x20;
-			AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
-			break;
-		case LED_HALT:
-			LowByte = 0; // Driver sets MAC register and MAC controls LED
-		case LED_RADIO_OFF:
-			HighByte = 0;
-			AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
-			break;
-        case LED_WPS:
-			HighByte = 0x10;
-			AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
-			break;
-		case LED_ON_SITE_SURVEY:
-			HighByte = 0x08;
-			AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
-			break;
-		case LED_POWER_UP:
-			HighByte = 0x04;
-			AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
-			break;
-		default:
-			DBGPRINT(RT_DEBUG_WARN, ("RTMPSetLED::Unknown Status %d\n", Status));
-			break;
+	LowByte = pAd->LedCntl.field.LedMode & 0x7f;
+	switch (Status) {
+	case LED_LINK_DOWN:
+		HighByte = 0x20;
+		AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+		pAd->LedIndicatorStrength = 0;
+		break;
+	case LED_LINK_UP:
+		if (pAd->CommonCfg.Channel > 14)
+			HighByte = 0xa0;
+		else
+			HighByte = 0x60;
+		AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+		break;
+	case LED_RADIO_ON:
+		HighByte = 0x20;
+		AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+		break;
+	case LED_HALT:
+		LowByte = 0;	/* Driver sets MAC register and MAC controls LED */
+	case LED_RADIO_OFF:
+		HighByte = 0;
+		AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+		break;
+	case LED_WPS:
+		HighByte = 0x10;
+		AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+		break;
+	case LED_ON_SITE_SURVEY:
+		HighByte = 0x08;
+		AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+		break;
+	case LED_POWER_UP:
+		HighByte = 0x04;
+		AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+		break;
+	default:
+		DBGPRINT(RT_DEBUG_WARN,
+			 ("RTMPSetLED::Unknown Status %d\n", Status));
+		break;
 	}
 
-    //
-	// Keep LED status for LED SiteSurvey mode.
-	// After SiteSurvey, we will set the LED mode to previous status.
-	//
+	/* */
+	/* Keep LED status for LED SiteSurvey mode. */
+	/* After SiteSurvey, we will set the LED mode to previous status. */
+	/* */
 	if ((Status != LED_ON_SITE_SURVEY) && (Status != LED_POWER_UP))
 		pAd->LedStatus = Status;
 
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetLED::Mode=%d,HighByte=0x%02x,LowByte=0x%02x\n", pAd->LedCntl.field.LedMode, HighByte, LowByte));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("RTMPSetLED::Mode=%d,HighByte=0x%02x,LowByte=0x%02x\n",
+		  pAd->LedCntl.field.LedMode, HighByte, LowByte));
 }
 
 /*
@@ -3889,40 +3117,32 @@
 		 > -57  Excellent
 	========================================================================
 */
-VOID RTMPSetSignalLED(
-	IN PRTMP_ADAPTER 	pAd,
-	IN NDIS_802_11_RSSI Dbm)
+void RTMPSetSignalLED(struct rt_rtmp_adapter *pAd, IN NDIS_802_11_RSSI Dbm)
 {
-	UCHAR		nLed = 0;
+	u8 nLed = 0;
 
-	//
-	// if not Signal Stregth, then do nothing.
-	//
-	if (pAd->LedCntl.field.LedMode != LED_MODE_SIGNAL_STREGTH)
-	{
-		return;
-	}
+	if (pAd->LedCntl.field.LedMode == LED_MODE_SIGNAL_STREGTH) {
+		if (Dbm <= -90)
+			nLed = 0;
+		else if (Dbm <= -81)
+			nLed = 1;
+		else if (Dbm <= -71)
+			nLed = 3;
+		else if (Dbm <= -67)
+			nLed = 7;
+		else if (Dbm <= -57)
+			nLed = 15;
+		else
+			nLed = 31;
 
-	if (Dbm <= -90)
-		nLed = 0;
-	else if (Dbm <= -81)
-		nLed = 1;
-	else if (Dbm <= -71)
-		nLed = 3;
-	else if (Dbm <= -67)
-		nLed = 7;
-	else if (Dbm <= -57)
-		nLed = 15;
-	else
-		nLed = 31;
-
-	//
-	// Update Signal Stregth to firmware if changed.
-	//
-	if (pAd->LedIndicatorStregth != nLed)
-	{
-		AsicSendCommandToMcu(pAd, 0x51, 0xff, nLed, pAd->LedCntl.field.Polarity);
-		pAd->LedIndicatorStregth = nLed;
+		/* */
+		/* Update Signal Stregth to firmware if changed. */
+		/* */
+		if (pAd->LedIndicatorStrength != nLed) {
+			AsicSendCommandToMcu(pAd, 0x51, 0xff, nLed,
+					     pAd->LedCntl.field.Polarity);
+			pAd->LedIndicatorStrength = nLed;
+		}
 	}
 }
 
@@ -3944,29 +3164,394 @@
 		Before Enable RX, make sure you have enabled Interrupt.
 	========================================================================
 */
-VOID RTMPEnableRxTx(
-	IN PRTMP_ADAPTER	pAd)
+void RTMPEnableRxTx(struct rt_rtmp_adapter *pAd)
 {
+/*      WPDMA_GLO_CFG_STRUC     GloCfg; */
+/*      unsigned long   i = 0; */
+	u32 rx_filter_flag;
+
 	DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPEnableRxTx\n"));
 
-	// Enable Rx DMA.
+	/* Enable Rx DMA. */
 	RT28XXDMAEnable(pAd);
 
-	// enable RX of MAC block
-	if (pAd->OpMode == OPMODE_AP)
-	{
-		UINT32 rx_filter_flag = APNORMAL;
+	/* enable RX of MAC block */
+	if (pAd->OpMode == OPMODE_AP) {
+		rx_filter_flag = APNORMAL;
 
-
-		RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag);     // enable RX of DMA block
-	}
-	else
-	{
-		RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL);     // Staion not drop control frame will fail WiFi Certification.
+		RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag);	/* enable RX of DMA block */
+	} else {
+		if (pAd->CommonCfg.PSPXlink)
+			rx_filter_flag = PSPXLINK;
+		else
+			rx_filter_flag = STANORMAL;	/* Staion not drop control frame will fail WiFi Certification. */
+		RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag);
 	}
 
 	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc);
 	DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPEnableRxTx\n"));
 }
 
+/*+++Add by shiang, move from os/linux/rt_main_dev.c */
+void CfgInitHook(struct rt_rtmp_adapter *pAd)
+{
+	pAd->bBroadComHT = TRUE;
+}
 
+int rt28xx_init(struct rt_rtmp_adapter *pAd,
+		char *pDefaultMac, char *pHostName)
+{
+	u32 index;
+	u8 TmpPhy;
+	int Status;
+	u32 MacCsr0 = 0;
+
+#ifdef RTMP_MAC_PCI
+	{
+		/* If dirver doesn't wake up firmware here, */
+		/* NICLoadFirmware will hang forever when interface is up again. */
+		/* RT2860 PCI */
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) &&
+		    OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
+			AUTO_WAKEUP_STRUC AutoWakeupCfg;
+			AsicForceWakeup(pAd, TRUE);
+			AutoWakeupCfg.word = 0;
+			RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG,
+					AutoWakeupCfg.word);
+			OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+		}
+	}
+#endif /* RTMP_MAC_PCI // */
+
+	/* reset Adapter flags */
+	RTMP_CLEAR_FLAGS(pAd);
+
+	/* Init BssTab & ChannelInfo tabbles for auto channel select. */
+
+	/* Allocate BA Reordering memory */
+	ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM);
+
+	/* Make sure MAC gets ready. */
+	index = 0;
+	do {
+		RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
+		pAd->MACVersion = MacCsr0;
+
+		if ((pAd->MACVersion != 0x00)
+		    && (pAd->MACVersion != 0xFFFFFFFF))
+			break;
+
+		RTMPusecDelay(10);
+	} while (index++ < 100);
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("MAC_CSR0  [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
+
+#ifdef RTMP_MAC_PCI
+#ifdef PCIE_PS_SUPPORT
+	/*Iverson patch PCIE L1 issue to make sure that driver can be read,write ,BBP and RF register  at pcie L.1 level */
+	if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
+	    && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
+		RTMP_IO_READ32(pAd, AUX_CTRL, &MacCsr0);
+		MacCsr0 |= 0x402;
+		RTMP_IO_WRITE32(pAd, AUX_CTRL, MacCsr0);
+		DBGPRINT(RT_DEBUG_TRACE, ("AUX_CTRL = 0x%x\n", MacCsr0));
+	}
+#endif /* PCIE_PS_SUPPORT // */
+
+	/* To fix driver disable/enable hang issue when radio off */
+	RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x2);
+#endif /* RTMP_MAC_PCI // */
+
+	/* Disable DMA */
+	RT28XXDMADisable(pAd);
+
+	/* Load 8051 firmware */
+	Status = NICLoadFirmware(pAd);
+	if (Status != NDIS_STATUS_SUCCESS) {
+		DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n",
+			      Status));
+		goto err1;
+	}
+
+	NICLoadRateSwitchingParams(pAd);
+
+	/* Disable interrupts here which is as soon as possible */
+	/* This statement should never be true. We might consider to remove it later */
+#ifdef RTMP_MAC_PCI
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) {
+		RTMP_ASIC_INTERRUPT_DISABLE(pAd);
+	}
+#endif /* RTMP_MAC_PCI // */
+
+	Status = RTMPAllocTxRxRingMemory(pAd);
+	if (Status != NDIS_STATUS_SUCCESS) {
+		DBGPRINT_ERR(("RTMPAllocDMAMemory failed, Status[=0x%08x]\n",
+			      Status));
+		goto err1;
+	}
+
+	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
+
+	/* initialize MLME */
+	/* */
+
+	Status = RtmpMgmtTaskInit(pAd);
+	if (Status != NDIS_STATUS_SUCCESS)
+		goto err2;
+
+	Status = MlmeInit(pAd);
+	if (Status != NDIS_STATUS_SUCCESS) {
+		DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status));
+		goto err2;
+	}
+	/* Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default */
+	/* */
+	UserCfgInit(pAd);
+	Status = RtmpNetTaskInit(pAd);
+	if (Status != NDIS_STATUS_SUCCESS)
+		goto err3;
+
+/*      COPY_MAC_ADDR(pAd->ApCfg.MBSSID[apidx].Bssid, netif->hwaddr); */
+/*      pAd->bForcePrintTX = TRUE; */
+
+	CfgInitHook(pAd);
+
+	NdisAllocateSpinLock(&pAd->MacTabLock);
+
+	MeasureReqTabInit(pAd);
+	TpcReqTabInit(pAd);
+
+	/* */
+	/* Init the hardware, we need to init asic before read registry, otherwise mac register will be reset */
+	/* */
+	Status = NICInitializeAdapter(pAd, TRUE);
+	if (Status != NDIS_STATUS_SUCCESS) {
+		DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n",
+			      Status));
+		if (Status != NDIS_STATUS_SUCCESS)
+			goto err3;
+	}
+
+	DBGPRINT(RT_DEBUG_OFF, ("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode));
+
+#ifdef RTMP_MAC_USB
+	pAd->CommonCfg.bMultipleIRP = FALSE;
+
+	if (pAd->CommonCfg.bMultipleIRP)
+		pAd->CommonCfg.NumOfBulkInIRP = RX_RING_SIZE;
+	else
+		pAd->CommonCfg.NumOfBulkInIRP = 1;
+#endif /* RTMP_MAC_USB // */
+
+	/*Init Ba Capability parameters. */
+/*      RT28XX_BA_INIT(pAd); */
+	pAd->CommonCfg.DesiredHtPhy.MpduDensity =
+	    (u8)pAd->CommonCfg.BACapability.field.MpduDensity;
+	pAd->CommonCfg.DesiredHtPhy.AmsduEnable =
+	    (u16)pAd->CommonCfg.BACapability.field.AmsduEnable;
+	pAd->CommonCfg.DesiredHtPhy.AmsduSize =
+	    (u16)pAd->CommonCfg.BACapability.field.AmsduSize;
+	pAd->CommonCfg.DesiredHtPhy.MimoPs =
+	    (u16)pAd->CommonCfg.BACapability.field.MMPSmode;
+	/* UPdata to HT IE */
+	pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs =
+	    (u16)pAd->CommonCfg.BACapability.field.MMPSmode;
+	pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize =
+	    (u16)pAd->CommonCfg.BACapability.field.AmsduSize;
+	pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity =
+	    (u8)pAd->CommonCfg.BACapability.field.MpduDensity;
+
+	/* after reading Registry, we now know if in AP mode or STA mode */
+
+	/* Load 8051 firmware; crash when FW image not existent */
+	/* Status = NICLoadFirmware(pAd); */
+	/* if (Status != NDIS_STATUS_SUCCESS) */
+	/*    break; */
+
+	DBGPRINT(RT_DEBUG_OFF, ("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode));
+
+	/* We should read EEPROM for all cases.  rt2860b */
+	NICReadEEPROMParameters(pAd, (u8 *)pDefaultMac);
+
+	DBGPRINT(RT_DEBUG_OFF, ("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode));
+
+	NICInitAsicFromEEPROM(pAd);	/*rt2860b */
+
+	/* Set PHY to appropriate mode */
+	TmpPhy = pAd->CommonCfg.PhyMode;
+	pAd->CommonCfg.PhyMode = 0xff;
+	RTMPSetPhyMode(pAd, TmpPhy);
+	SetCommonHT(pAd);
+
+	/* No valid channels. */
+	if (pAd->ChannelListNum == 0) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n"));
+		goto err4;
+	}
+
+	DBGPRINT(RT_DEBUG_OFF,
+		 ("MCS Set = %02x %02x %02x %02x %02x\n",
+		  pAd->CommonCfg.HtCapability.MCSSet[0],
+		  pAd->CommonCfg.HtCapability.MCSSet[1],
+		  pAd->CommonCfg.HtCapability.MCSSet[2],
+		  pAd->CommonCfg.HtCapability.MCSSet[3],
+		  pAd->CommonCfg.HtCapability.MCSSet[4]));
+
+#ifdef RTMP_RF_RW_SUPPORT
+	/*Init RT30xx RFRegisters after read RFIC type from EEPROM */
+	NICInitRFRegisters(pAd);
+#endif /* RTMP_RF_RW_SUPPORT // */
+
+/*              APInitialize(pAd); */
+
+	/* */
+	/* Initialize RF register to default value */
+	/* */
+	AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+	AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+	/* 8051 firmware require the signal during booting time. */
+	/*2008/11/28:KH marked the following codes to patch Frequency offset bug */
+	/*AsicSendCommandToMcu(pAd, 0x72, 0xFF, 0x00, 0x00); */
+
+	if (pAd && (Status != NDIS_STATUS_SUCCESS)) {
+		/* */
+		/* Undo everything if it failed */
+		/* */
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
+/*                      NdisMDeregisterInterrupt(&pAd->Interrupt); */
+			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
+		}
+/*              RTMPFreeAdapter(pAd); // we will free it in disconnect() */
+	} else if (pAd) {
+		/* Microsoft HCT require driver send a disconnect event after driver initialization. */
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+/*              pAd->IndicateMediaState = NdisMediaStateDisconnected; */
+		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
+
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n"));
+
+#ifdef RTMP_MAC_USB
+		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
+		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
+
+		/* */
+		/* Support multiple BulkIn IRP, */
+		/* the value on pAd->CommonCfg.NumOfBulkInIRP may be large than 1. */
+		/* */
+		for (index = 0; index < pAd->CommonCfg.NumOfBulkInIRP; index++) {
+			RTUSBBulkReceive(pAd);
+			DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n"));
+		}
+#endif /* RTMP_MAC_USB // */
+	}			/* end of else */
+
+	/* Set up the Mac address */
+	RtmpOSNetDevAddrSet(pAd->net_dev, &pAd->CurrentAddress[0]);
+
+	DBGPRINT_S(Status, ("<==== rt28xx_init, Status=%x\n", Status));
+
+	return TRUE;
+
+err4:
+err3:
+	MlmeHalt(pAd);
+err2:
+	RTMPFreeTxRxRingMemory(pAd);
+err1:
+
+	os_free_mem(pAd, pAd->mpdu_blk_pool.mem);	/* free BA pool */
+
+	/* shall not set priv to NULL here because the priv didn't been free yet. */
+	/*net_dev->ml_priv = 0; */
+#ifdef ST
+err0:
+#endif /* ST // */
+
+	DBGPRINT(RT_DEBUG_ERROR, ("rt28xx Initialized fail!\n"));
+	return FALSE;
+}
+
+/*---Add by shiang, move from os/linux/rt_main_dev.c */
+
+static int RtmpChipOpsRegister(struct rt_rtmp_adapter *pAd, int infType)
+{
+	struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
+	int status;
+
+	memset(pChipOps, 0, sizeof(struct rt_rtmp_chip_op));
+
+	/* set eeprom related hook functions */
+	status = RtmpChipOpsEepromHook(pAd, infType);
+
+	/* set mcu related hook functions */
+	switch (infType) {
+#ifdef RTMP_PCI_SUPPORT
+	case RTMP_DEV_INF_PCI:
+		pChipOps->loadFirmware = RtmpAsicLoadFirmware;
+		pChipOps->eraseFirmware = RtmpAsicEraseFirmware;
+		pChipOps->sendCommandToMcu = RtmpAsicSendCommandToMcu;
+		break;
+#endif /* RTMP_PCI_SUPPORT // */
+#ifdef RTMP_USB_SUPPORT
+	case RTMP_DEV_INF_USB:
+		pChipOps->loadFirmware = RtmpAsicLoadFirmware;
+		pChipOps->sendCommandToMcu = RtmpAsicSendCommandToMcu;
+		break;
+#endif /* RTMP_USB_SUPPORT // */
+	default:
+		break;
+	}
+
+	return status;
+}
+
+int RtmpRaDevCtrlInit(struct rt_rtmp_adapter *pAd, IN RTMP_INF_TYPE infType)
+{
+	/*void  *handle; */
+
+	/* Assign the interface type. We need use it when do register/EEPROM access. */
+	pAd->infType = infType;
+
+	pAd->OpMode = OPMODE_STA;
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("STA Driver version-%s\n", STA_DRIVER_VERSION));
+
+#ifdef RTMP_MAC_USB
+	init_MUTEX(&(pAd->UsbVendorReq_semaphore));
+	os_alloc_mem(pAd, (u8 **) & pAd->UsbVendorReqBuf,
+		     MAX_PARAM_BUFFER_SIZE - 1);
+	if (pAd->UsbVendorReqBuf == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("Allocate vendor request temp buffer failed!\n"));
+		return FALSE;
+	}
+#endif /* RTMP_MAC_USB // */
+
+	RtmpChipOpsRegister(pAd, infType);
+
+	return 0;
+}
+
+BOOLEAN RtmpRaDevCtrlExit(struct rt_rtmp_adapter *pAd)
+{
+
+	RTMPFreeAdapter(pAd);
+
+	return TRUE;
+}
+
+/* not yet support MBSS */
+struct net_device *get_netdev_from_bssid(struct rt_rtmp_adapter *pAd, u8 FromWhichBSSID)
+{
+	struct net_device *dev_p = NULL;
+
+	{
+		dev_p = pAd->net_dev;
+	}
+
+	ASSERT(dev_p);
+	return dev_p;		/* return one of MBSS */
+}
diff --git a/drivers/staging/rt2860/common/rtmp_mcu.c b/drivers/staging/rt2860/common/rtmp_mcu.c
new file mode 100644
index 0000000..9f03901
--- /dev/null
+++ b/drivers/staging/rt2860/common/rtmp_mcu.c
@@ -0,0 +1,291 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rtmp_mcu.c
+
+	Abstract:
+	Miniport generic portion header file
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+#include	"../rt_config.h"
+
+#if defined(RT2860) || defined(RT3090)
+#include "firmware.h"
+#include "../../rt3090/firmware.h"
+#endif
+#ifdef RT2870
+#include "../../rt3070/firmware.h"
+#include "firmware_3070.h"
+#endif
+
+#include <linux/bitrev.h>
+
+#ifdef RTMP_MAC_USB
+/* */
+/* RT2870 Firmware Spec only used 1 oct for version expression */
+/* */
+#define FIRMWARE_MINOR_VERSION	7
+#endif /* RTMP_MAC_USB // */
+
+/* New 8k byte firmware size for RT3071/RT3072 */
+#define FIRMWAREIMAGE_MAX_LENGTH	0x2000
+#define FIRMWAREIMAGE_LENGTH			(sizeof (FirmwareImage) / sizeof(u8))
+#define FIRMWARE_MAJOR_VERSION		0
+
+#define FIRMWAREIMAGEV1_LENGTH		0x1000
+#define FIRMWAREIMAGEV2_LENGTH		0x1000
+
+#ifdef RTMP_MAC_PCI
+#define FIRMWARE_MINOR_VERSION		2
+#endif /* RTMP_MAC_PCI // */
+
+/*
+	========================================================================
+
+	Routine Description:
+		erase 8051 firmware image in MAC ASIC
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	IRQL = PASSIVE_LEVEL
+
+	========================================================================
+*/
+int RtmpAsicEraseFirmware(struct rt_rtmp_adapter *pAd)
+{
+	unsigned long i;
+
+	for (i = 0; i < MAX_FIRMWARE_IMAGE_SIZE; i += 4)
+		RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, 0);
+
+	return 0;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Load 8051 firmware file into MAC ASIC
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	Return Value:
+		NDIS_STATUS_SUCCESS         firmware image load ok
+		NDIS_STATUS_FAILURE         image not found
+
+	IRQL = PASSIVE_LEVEL
+
+	========================================================================
+*/
+int RtmpAsicLoadFirmware(struct rt_rtmp_adapter *pAd)
+{
+
+	int Status = NDIS_STATUS_SUCCESS;
+	u8 *pFirmwareImage = NULL;
+	unsigned long FileLength, Index;
+	u32 MacReg = 0;
+#ifdef RTMP_MAC_USB
+	u32 Version = (pAd->MACVersion >> 16);
+#endif
+
+	/* New 8k byte firmware size for RT3071/RT3072 */
+	{
+#ifdef RTMP_MAC_PCI
+		if (IS_RT3090(pAd) || IS_RT3390(pAd)) {
+			pFirmwareImage = FirmwareImage_3090;
+			FileLength = FIRMWAREIMAGE_MAX_LENGTH;
+		} else {
+			pFirmwareImage = FirmwareImage_2860;
+			FileLength = FIRMWAREIMAGE_MAX_LENGTH;
+		}
+#endif /* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
+		/* the firmware image consists of two parts */
+		if ((Version != 0x2860) && (Version != 0x2872) && (Version != 0x3070)) {	/* use the second part */
+			/*printk("KH:Use New Version,part2\n"); */
+			pFirmwareImage =
+			    (u8 *)&
+			    FirmwareImage_3070[FIRMWAREIMAGEV1_LENGTH];
+			FileLength = FIRMWAREIMAGEV2_LENGTH;
+		} else {
+			/*printk("KH:Use New Version,part1\n"); */
+			if (Version == 0x3070)
+				pFirmwareImage = FirmwareImage_3070;
+			else
+				pFirmwareImage = FirmwareImage_2870;
+			FileLength = FIRMWAREIMAGEV1_LENGTH;
+		}
+#endif /* RTMP_MAC_USB // */
+	}
+
+	RTMP_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength);
+
+	/* check if MCU is ready */
+	Index = 0;
+	do {
+		RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacReg);
+
+		if (MacReg & 0x80)
+			break;
+
+		RTMPusecDelay(1000);
+	} while (Index++ < 1000);
+
+	if (Index > 1000) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("NICLoadFirmware: MCU is not ready\n"));
+		Status = NDIS_STATUS_FAILURE;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<=== %s (status=%d)\n", __func__, Status));
+
+	return Status;
+}
+
+int RtmpAsicSendCommandToMcu(struct rt_rtmp_adapter *pAd,
+			     u8 Command,
+			     u8 Token, u8 Arg0, u8 Arg1)
+{
+	HOST_CMD_CSR_STRUC H2MCmd;
+	H2M_MAILBOX_STRUC H2MMailbox;
+	unsigned long i = 0;
+
+#ifdef PCIE_PS_SUPPORT
+	/* 3090F power solution 3 has hw limitation that needs to ban all mcu command */
+	/* when firmware is in radio state.  For other chip doesn't have this limitation. */
+	if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
+	     && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
+	    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
+	    && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
+		RTMP_SEM_LOCK(&pAd->McuCmdLock);
+		if ((pAd->brt30xxBanMcuCmd == TRUE)
+		    && (Command != WAKE_MCU_CMD) && (Command != RFOFF_MCU_CMD)) {
+			RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
+			DBGPRINT(RT_DEBUG_TRACE,
+				 (" Ban Mcu Cmd %x in sleep mode\n", Command));
+			return FALSE;
+		} else if ((Command == SLEEP_MCU_CMD)
+			   || (Command == RFOFF_MCU_CMD)) {
+			pAd->brt30xxBanMcuCmd = TRUE;
+		} else if (Command != WAKE_MCU_CMD) {
+			pAd->brt30xxBanMcuCmd = FALSE;
+		}
+
+		RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
+
+	}
+	if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
+	     && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
+	    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
+	    && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
+	    && (Command == WAKE_MCU_CMD)) {
+
+		do {
+			RTMP_IO_FORCE_READ32(pAd, H2M_MAILBOX_CSR,
+					     &H2MMailbox.word);
+			if (H2MMailbox.field.Owner == 0)
+				break;
+
+			RTMPusecDelay(2);
+			DBGPRINT(RT_DEBUG_INFO,
+				 ("AsicSendCommanToMcu::Mail box is busy\n"));
+		} while (i++ < 100);
+
+		if (i >= 100) {
+			DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
+			return FALSE;
+		}
+
+		H2MMailbox.field.Owner = 1;	/* pass ownership to MCU */
+		H2MMailbox.field.CmdToken = Token;
+		H2MMailbox.field.HighByte = Arg1;
+		H2MMailbox.field.LowByte = Arg0;
+		RTMP_IO_FORCE_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
+
+		H2MCmd.word = 0;
+		H2MCmd.field.HostCommand = Command;
+		RTMP_IO_FORCE_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
+
+	} else
+#endif /* PCIE_PS_SUPPORT // */
+	{
+		do {
+			RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
+			if (H2MMailbox.field.Owner == 0)
+				break;
+
+			RTMPusecDelay(2);
+		} while (i++ < 100);
+
+		if (i > 100) {
+#ifdef RTMP_MAC_PCI
+#endif /* RTMP_MAC_PCI // */
+			{
+				DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
+			}
+			return FALSE;
+		}
+#ifdef RTMP_MAC_PCI
+#endif /* RTMP_MAC_PCI // */
+
+		H2MMailbox.field.Owner = 1;	/* pass ownership to MCU */
+		H2MMailbox.field.CmdToken = Token;
+		H2MMailbox.field.HighByte = Arg1;
+		H2MMailbox.field.LowByte = Arg0;
+		RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
+
+		H2MCmd.word = 0;
+		H2MCmd.field.HostCommand = Command;
+		RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
+
+		if (Command != 0x80) {
+		}
+	}
+#ifdef PCIE_PS_SUPPORT
+	/* 3090 MCU Wakeup command needs more time to be stable. */
+	/* Before stable, don't issue other MCU command to prevent from firmware error. */
+	if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
+	     && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
+	    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
+	    && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
+	    && (Command == WAKE_MCU_CMD)) {
+		RTMPusecDelay(2000);
+		/*Put this is after RF programming. */
+		/*NdisAcquireSpinLock(&pAd->McuCmdLock); */
+		/*pAd->brt30xxBanMcuCmd = FALSE; */
+		/*NdisReleaseSpinLock(&pAd->McuCmdLock); */
+	}
+#endif /* PCIE_PS_SUPPORT // */
+
+	return TRUE;
+}
diff --git a/drivers/staging/rt2860/common/rtmp_timer.c b/drivers/staging/rt2860/common/rtmp_timer.c
new file mode 100644
index 0000000..42e47d9
--- /dev/null
+++ b/drivers/staging/rt2860/common/rtmp_timer.c
@@ -0,0 +1,302 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+    rtmp_timer.c
+
+    Abstract:
+    task for timer handling
+
+    Revision History:
+    Who         When            What
+    --------    ----------      ----------------------------------------------
+    Name          Date            Modification logs
+    Shiang Tu	08-28-2008   init version
+
+*/
+
+#include "../rt_config.h"
+
+BUILD_TIMER_FUNCTION(MlmePeriodicExec);
+/*BUILD_TIMER_FUNCTION(MlmeRssiReportExec); */
+BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
+BUILD_TIMER_FUNCTION(APSDPeriodicExec);
+BUILD_TIMER_FUNCTION(AsicRfTuningExec);
+#ifdef RTMP_MAC_USB
+BUILD_TIMER_FUNCTION(BeaconUpdateExec);
+#endif /* RTMP_MAC_USB // */
+
+BUILD_TIMER_FUNCTION(BeaconTimeout);
+BUILD_TIMER_FUNCTION(ScanTimeout);
+BUILD_TIMER_FUNCTION(AuthTimeout);
+BUILD_TIMER_FUNCTION(AssocTimeout);
+BUILD_TIMER_FUNCTION(ReassocTimeout);
+BUILD_TIMER_FUNCTION(DisassocTimeout);
+BUILD_TIMER_FUNCTION(LinkDownExec);
+BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
+BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
+#ifdef RTMP_MAC_PCI
+BUILD_TIMER_FUNCTION(PsPollWakeExec);
+BUILD_TIMER_FUNCTION(RadioOnExec);
+#endif /* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
+BUILD_TIMER_FUNCTION(RtmpUsbStaAsicForceWakeupTimeout);
+#endif /* RTMP_MAC_USB // */
+
+#if defined(AP_LED) || defined(STA_LED)
+extern void LedCtrlMain(void *SystemSpecific1,
+			void *FunctionContext,
+			void *SystemSpecific2, void *SystemSpecific3);
+BUILD_TIMER_FUNCTION(LedCtrlMain);
+#endif
+
+#ifdef RTMP_TIMER_TASK_SUPPORT
+static void RtmpTimerQHandle(struct rt_rtmp_adapter *pAd)
+{
+#ifndef KTHREAD_SUPPORT
+	int status;
+#endif
+	struct rt_ralink_timer *pTimer;
+	struct rt_rtmp_timer_task_entry *pEntry;
+	unsigned long irqFlag;
+	struct rt_rtmp_os_task *pTask;
+
+	pTask = &pAd->timerTask;
+	while (!pTask->task_killed) {
+		pTimer = NULL;
+
+#ifdef KTHREAD_SUPPORT
+		RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
+#else
+		RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
+#endif
+
+		if (pAd->TimerQ.status == RTMP_TASK_STAT_STOPED)
+			break;
+
+		/* event happened. */
+		while (pAd->TimerQ.pQHead) {
+			RTMP_INT_LOCK(&pAd->TimerQLock, irqFlag);
+			pEntry = pAd->TimerQ.pQHead;
+			if (pEntry) {
+				pTimer = pEntry->pRaTimer;
+
+				/* update pQHead */
+				pAd->TimerQ.pQHead = pEntry->pNext;
+				if (pEntry == pAd->TimerQ.pQTail)
+					pAd->TimerQ.pQTail = NULL;
+
+				/* return this queue entry to timerQFreeList. */
+				pEntry->pNext = pAd->TimerQ.pQPollFreeList;
+				pAd->TimerQ.pQPollFreeList = pEntry;
+			}
+			RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlag);
+
+			if (pTimer) {
+				if ((pTimer->handle != NULL)
+				    && (!pAd->PM_FlgSuspend))
+					pTimer->handle(NULL,
+						       (void *)pTimer->cookie,
+						       NULL, pTimer);
+				if ((pTimer->Repeat)
+				    && (pTimer->State == FALSE))
+					RTMP_OS_Add_Timer(&pTimer->TimerObj,
+							  pTimer->TimerValue);
+			}
+		}
+
+#ifndef KTHREAD_SUPPORT
+		if (status != 0) {
+			pAd->TimerQ.status = RTMP_TASK_STAT_STOPED;
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+			break;
+		}
+#endif
+	}
+}
+
+int RtmpTimerQThread(IN void *Context)
+{
+	struct rt_rtmp_os_task *pTask;
+	struct rt_rtmp_adapter *pAd;
+
+	pTask = (struct rt_rtmp_os_task *)Context;
+	pAd = (struct rt_rtmp_adapter *)pTask->priv;
+
+	RtmpOSTaskCustomize(pTask);
+
+	RtmpTimerQHandle(pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<---%s\n", __func__));
+#ifndef KTHREAD_SUPPORT
+	pTask->taskPID = THREAD_PID_INIT_VALUE;
+#endif
+	/* notify the exit routine that we're actually exiting now
+	 *
+	 * complete()/wait_for_completion() is similar to up()/down(),
+	 * except that complete() is safe in the case where the structure
+	 * is getting deleted in a parallel mode of execution (i.e. just
+	 * after the down() -- that's necessary for the thread-shutdown
+	 * case.
+	 *
+	 * complete_and_exit() goes even further than this -- it is safe in
+	 * the case that the thread of the caller is going away (not just
+	 * the structure) -- this is necessary for the module-remove case.
+	 * This is important in preemption kernels, which transfer the flow
+	 * of execution immediately upon a complete().
+	 */
+	RtmpOSTaskNotifyToExit(pTask);
+
+	return 0;
+
+}
+
+struct rt_rtmp_timer_task_entry *RtmpTimerQInsert(struct rt_rtmp_adapter *pAd,
+					struct rt_ralink_timer *pTimer)
+{
+	struct rt_rtmp_timer_task_entry *pQNode = NULL, *pQTail;
+	unsigned long irqFlags;
+	struct rt_rtmp_os_task *pTask = &pAd->timerTask;
+
+	RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
+	if (pAd->TimerQ.status & RTMP_TASK_CAN_DO_INSERT) {
+		if (pAd->TimerQ.pQPollFreeList) {
+			pQNode = pAd->TimerQ.pQPollFreeList;
+			pAd->TimerQ.pQPollFreeList = pQNode->pNext;
+
+			pQNode->pRaTimer = pTimer;
+			pQNode->pNext = NULL;
+
+			pQTail = pAd->TimerQ.pQTail;
+			if (pAd->TimerQ.pQTail != NULL)
+				pQTail->pNext = pQNode;
+			pAd->TimerQ.pQTail = pQNode;
+			if (pAd->TimerQ.pQHead == NULL)
+				pAd->TimerQ.pQHead = pQNode;
+		}
+	}
+	RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
+
+	if (pQNode) {
+#ifdef KTHREAD_SUPPORT
+		WAKE_UP(pTask);
+#else
+		RTMP_SEM_EVENT_UP(&pTask->taskSema);
+#endif
+	}
+
+	return pQNode;
+}
+
+BOOLEAN RtmpTimerQRemove(struct rt_rtmp_adapter *pAd, struct rt_ralink_timer *pTimer)
+{
+	struct rt_rtmp_timer_task_entry *pNode, *pPrev = NULL;
+	unsigned long irqFlags;
+
+	RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
+	if (pAd->TimerQ.status >= RTMP_TASK_STAT_INITED) {
+		pNode = pAd->TimerQ.pQHead;
+		while (pNode) {
+			if (pNode->pRaTimer == pTimer)
+				break;
+			pPrev = pNode;
+			pNode = pNode->pNext;
+		}
+
+		/* Now move it to freeList queue. */
+		if (pNode) {
+			if (pNode == pAd->TimerQ.pQHead)
+				pAd->TimerQ.pQHead = pNode->pNext;
+			if (pNode == pAd->TimerQ.pQTail)
+				pAd->TimerQ.pQTail = pPrev;
+			if (pPrev != NULL)
+				pPrev->pNext = pNode->pNext;
+
+			/* return this queue entry to timerQFreeList. */
+			pNode->pNext = pAd->TimerQ.pQPollFreeList;
+			pAd->TimerQ.pQPollFreeList = pNode;
+		}
+	}
+	RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
+
+	return TRUE;
+}
+
+void RtmpTimerQExit(struct rt_rtmp_adapter *pAd)
+{
+	struct rt_rtmp_timer_task_entry *pTimerQ;
+	unsigned long irqFlags;
+
+	RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
+	while (pAd->TimerQ.pQHead) {
+		pTimerQ = pAd->TimerQ.pQHead;
+		pAd->TimerQ.pQHead = pTimerQ->pNext;
+		/* remove the timeQ */
+	}
+	pAd->TimerQ.pQPollFreeList = NULL;
+	os_free_mem(pAd, pAd->TimerQ.pTimerQPoll);
+	pAd->TimerQ.pQTail = NULL;
+	pAd->TimerQ.pQHead = NULL;
+#ifndef KTHREAD_SUPPORT
+	pAd->TimerQ.status = RTMP_TASK_STAT_STOPED;
+#endif
+	RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
+
+}
+
+void RtmpTimerQInit(struct rt_rtmp_adapter *pAd)
+{
+	int i;
+	struct rt_rtmp_timer_task_entry *pQNode, *pEntry;
+	unsigned long irqFlags;
+
+	NdisAllocateSpinLock(&pAd->TimerQLock);
+
+	NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ));
+
+	os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll,
+		     sizeof(struct rt_rtmp_timer_task_entry) * TIMER_QUEUE_SIZE_MAX);
+	if (pAd->TimerQ.pTimerQPoll) {
+		pEntry = NULL;
+		pQNode = (struct rt_rtmp_timer_task_entry *)pAd->TimerQ.pTimerQPoll;
+		NdisZeroMemory(pAd->TimerQ.pTimerQPoll,
+			       sizeof(struct rt_rtmp_timer_task_entry) *
+			       TIMER_QUEUE_SIZE_MAX);
+
+		RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
+		for (i = 0; i < TIMER_QUEUE_SIZE_MAX; i++) {
+			pQNode->pNext = pEntry;
+			pEntry = pQNode;
+			pQNode++;
+		}
+		pAd->TimerQ.pQPollFreeList = pEntry;
+		pAd->TimerQ.pQHead = NULL;
+		pAd->TimerQ.pQTail = NULL;
+		pAd->TimerQ.status = RTMP_TASK_STAT_INITED;
+		RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
+	}
+}
+#endif /* RTMP_TIMER_TASK_SUPPORT // */
diff --git a/drivers/staging/rt2860/common/rtmp_tkip.c b/drivers/staging/rt2860/common/rtmp_tkip.c
deleted file mode 100644
index 4a7fda6..0000000
--- a/drivers/staging/rt2860/common/rtmp_tkip.c
+++ /dev/null
@@ -1,1586 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtmp_tkip.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Paul Wu		02-25-02		Initial
-*/
-
-#include "../rt_config.h"
-
-// Rotation functions on 32 bit values
-#define ROL32( A, n ) \
-	( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) )
-#define ROR32( A, n ) ROL32( (A), 32-(n) )
-
-UINT Tkip_Sbox_Lower[256] =
-{
-	0xA5,0x84,0x99,0x8D,0x0D,0xBD,0xB1,0x54,
-	0x50,0x03,0xA9,0x7D,0x19,0x62,0xE6,0x9A,
-	0x45,0x9D,0x40,0x87,0x15,0xEB,0xC9,0x0B,
-	0xEC,0x67,0xFD,0xEA,0xBF,0xF7,0x96,0x5B,
-	0xC2,0x1C,0xAE,0x6A,0x5A,0x41,0x02,0x4F,
-	0x5C,0xF4,0x34,0x08,0x93,0x73,0x53,0x3F,
-	0x0C,0x52,0x65,0x5E,0x28,0xA1,0x0F,0xB5,
-	0x09,0x36,0x9B,0x3D,0x26,0x69,0xCD,0x9F,
-	0x1B,0x9E,0x74,0x2E,0x2D,0xB2,0xEE,0xFB,
-	0xF6,0x4D,0x61,0xCE,0x7B,0x3E,0x71,0x97,
-	0xF5,0x68,0x00,0x2C,0x60,0x1F,0xC8,0xED,
-	0xBE,0x46,0xD9,0x4B,0xDE,0xD4,0xE8,0x4A,
-	0x6B,0x2A,0xE5,0x16,0xC5,0xD7,0x55,0x94,
-	0xCF,0x10,0x06,0x81,0xF0,0x44,0xBA,0xE3,
-	0xF3,0xFE,0xC0,0x8A,0xAD,0xBC,0x48,0x04,
-	0xDF,0xC1,0x75,0x63,0x30,0x1A,0x0E,0x6D,
-	0x4C,0x14,0x35,0x2F,0xE1,0xA2,0xCC,0x39,
-	0x57,0xF2,0x82,0x47,0xAC,0xE7,0x2B,0x95,
-	0xA0,0x98,0xD1,0x7F,0x66,0x7E,0xAB,0x83,
-	0xCA,0x29,0xD3,0x3C,0x79,0xE2,0x1D,0x76,
-	0x3B,0x56,0x4E,0x1E,0xDB,0x0A,0x6C,0xE4,
-	0x5D,0x6E,0xEF,0xA6,0xA8,0xA4,0x37,0x8B,
-	0x32,0x43,0x59,0xB7,0x8C,0x64,0xD2,0xE0,
-	0xB4,0xFA,0x07,0x25,0xAF,0x8E,0xE9,0x18,
-	0xD5,0x88,0x6F,0x72,0x24,0xF1,0xC7,0x51,
-	0x23,0x7C,0x9C,0x21,0xDD,0xDC,0x86,0x85,
-	0x90,0x42,0xC4,0xAA,0xD8,0x05,0x01,0x12,
-	0xA3,0x5F,0xF9,0xD0,0x91,0x58,0x27,0xB9,
-	0x38,0x13,0xB3,0x33,0xBB,0x70,0x89,0xA7,
-	0xB6,0x22,0x92,0x20,0x49,0xFF,0x78,0x7A,
-	0x8F,0xF8,0x80,0x17,0xDA,0x31,0xC6,0xB8,
-	0xC3,0xB0,0x77,0x11,0xCB,0xFC,0xD6,0x3A
-};
-
-UINT Tkip_Sbox_Upper[256] =
-{
-	0xC6,0xF8,0xEE,0xF6,0xFF,0xD6,0xDE,0x91,
-	0x60,0x02,0xCE,0x56,0xE7,0xB5,0x4D,0xEC,
-	0x8F,0x1F,0x89,0xFA,0xEF,0xB2,0x8E,0xFB,
-	0x41,0xB3,0x5F,0x45,0x23,0x53,0xE4,0x9B,
-	0x75,0xE1,0x3D,0x4C,0x6C,0x7E,0xF5,0x83,
-	0x68,0x51,0xD1,0xF9,0xE2,0xAB,0x62,0x2A,
-	0x08,0x95,0x46,0x9D,0x30,0x37,0x0A,0x2F,
-	0x0E,0x24,0x1B,0xDF,0xCD,0x4E,0x7F,0xEA,
-	0x12,0x1D,0x58,0x34,0x36,0xDC,0xB4,0x5B,
-	0xA4,0x76,0xB7,0x7D,0x52,0xDD,0x5E,0x13,
-	0xA6,0xB9,0x00,0xC1,0x40,0xE3,0x79,0xB6,
-	0xD4,0x8D,0x67,0x72,0x94,0x98,0xB0,0x85,
-	0xBB,0xC5,0x4F,0xED,0x86,0x9A,0x66,0x11,
-	0x8A,0xE9,0x04,0xFE,0xA0,0x78,0x25,0x4B,
-	0xA2,0x5D,0x80,0x05,0x3F,0x21,0x70,0xF1,
-	0x63,0x77,0xAF,0x42,0x20,0xE5,0xFD,0xBF,
-	0x81,0x18,0x26,0xC3,0xBE,0x35,0x88,0x2E,
-	0x93,0x55,0xFC,0x7A,0xC8,0xBA,0x32,0xE6,
-	0xC0,0x19,0x9E,0xA3,0x44,0x54,0x3B,0x0B,
-	0x8C,0xC7,0x6B,0x28,0xA7,0xBC,0x16,0xAD,
-	0xDB,0x64,0x74,0x14,0x92,0x0C,0x48,0xB8,
-	0x9F,0xBD,0x43,0xC4,0x39,0x31,0xD3,0xF2,
-	0xD5,0x8B,0x6E,0xDA,0x01,0xB1,0x9C,0x49,
-	0xD8,0xAC,0xF3,0xCF,0xCA,0xF4,0x47,0x10,
-	0x6F,0xF0,0x4A,0x5C,0x38,0x57,0x73,0x97,
-	0xCB,0xA1,0xE8,0x3E,0x96,0x61,0x0D,0x0F,
-	0xE0,0x7C,0x71,0xCC,0x90,0x06,0xF7,0x1C,
-	0xC2,0x6A,0xAE,0x69,0x17,0x99,0x3A,0x27,
-	0xD9,0xEB,0x2B,0x22,0xD2,0xA9,0x07,0x33,
-	0x2D,0x3C,0x15,0xC9,0x87,0xAA,0x50,0xA5,
-	0x03,0x59,0x09,0x1A,0x65,0xD7,0x84,0xD0,
-	0x82,0x29,0x5A,0x1E,0x7B,0xA8,0x6D,0x2C
-};
-
-/*****************************/
-/******** SBOX Table *********/
-/*****************************/
-
-UCHAR SboxTable[256] =
-{
-	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
-	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
-	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
-	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
-	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
-	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
-	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
-	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
-	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
-	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
-	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
-	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
-	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
-	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
-	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
-	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
-	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
-	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
-	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
-	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
-	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
-	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
-	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
-	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
-	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
-	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
-	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
-	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
-	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
-	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
-	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
-	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-};
-
-VOID xor_32(
-	IN  PUCHAR              a,
-	IN  PUCHAR              b,
-	OUT PUCHAR              out);
-
-VOID xor_128(
-	IN  PUCHAR              a,
-	IN  PUCHAR              b,
-	OUT PUCHAR              out);
-
-VOID next_key(
-	IN  PUCHAR              key,
-	IN  INT                 round);
-
-VOID byte_sub(
-	IN  PUCHAR              in,
-	OUT PUCHAR              out);
-
-VOID shift_row(
-	IN  PUCHAR              in,
-	OUT PUCHAR              out);
-
-VOID mix_column(
-	IN  PUCHAR              in,
-	OUT PUCHAR              out);
-
-UCHAR RTMPCkipSbox(
-	IN  UCHAR               a);
-//
-// Expanded IV for TKIP function.
-//
-typedef	struct	PACKED _IV_CONTROL_
-{
-	union PACKED
-	{
-		struct PACKED
-		{
-			UCHAR		rc0;
-			UCHAR		rc1;
-			UCHAR		rc2;
-
-			union PACKED
-			{
-				struct PACKED
-				{
-					UCHAR	Rsvd:5;
-					UCHAR	ExtIV:1;
-					UCHAR	KeyID:2;
-				}	field;
-				UCHAR		Byte;
-			}	CONTROL;
-		}	field;
-
-		ULONG	word;
-	}	IV16;
-
-	ULONG	IV32;
-}	TKIP_IV, *PTKIP_IV;
-
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Convert from UCHAR[] to ULONG in a portable way
-
-	Arguments:
-      pMICKey		pointer to MIC Key
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-ULONG	RTMPTkipGetUInt32(
-	IN	PUCHAR	pMICKey)
-{
-	ULONG	res = 0;
-	INT		i;
-
-	for (i = 0; i < 4; i++)
-	{
-		res |= (*pMICKey++) << (8 * i);
-	}
-
-	return res;
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Convert from ULONG to UCHAR[] in a portable way
-
-	Arguments:
-      pDst			pointer to destination for convert ULONG to UCHAR[]
-      val			the value for convert
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPTkipPutUInt32(
-	IN OUT	PUCHAR		pDst,
-	IN		ULONG		val)
-{
-	INT i;
-
-	for(i = 0; i < 4; i++)
-	{
-		*pDst++ = (UCHAR) (val & 0xff);
-		val >>= 8;
-	}
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Set the MIC Key.
-
-	Arguments:
-      pAd		Pointer to our adapter
-      pMICKey		pointer to MIC Key
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID RTMPTkipSetMICKey(
-	IN	PTKIP_KEY_INFO	pTkip,
-	IN	PUCHAR			pMICKey)
-{
-	// Set the key
-	pTkip->K0 = RTMPTkipGetUInt32(pMICKey);
-	pTkip->K1 = RTMPTkipGetUInt32(pMICKey + 4);
-	// and reset the message
-	pTkip->L = pTkip->K0;
-	pTkip->R = pTkip->K1;
-	pTkip->nBytesInM = 0;
-	pTkip->M = 0;
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Calculate the MIC Value.
-
-	Arguments:
-      pAd		Pointer to our adapter
-      uChar			Append this uChar
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPTkipAppendByte(
-	IN	PTKIP_KEY_INFO	pTkip,
-	IN	UCHAR 			uChar)
-{
-	// Append the byte to our word-sized buffer
-	pTkip->M |= (uChar << (8* pTkip->nBytesInM));
-	pTkip->nBytesInM++;
-	// Process the word if it is full.
-	if( pTkip->nBytesInM >= 4 )
-	{
-		pTkip->L ^= pTkip->M;
-		pTkip->R ^= ROL32( pTkip->L, 17 );
-		pTkip->L += pTkip->R;
-		pTkip->R ^= ((pTkip->L & 0xff00ff00) >> 8) | ((pTkip->L & 0x00ff00ff) << 8);
-		pTkip->L += pTkip->R;
-		pTkip->R ^= ROL32( pTkip->L, 3 );
-		pTkip->L += pTkip->R;
-		pTkip->R ^= ROR32( pTkip->L, 2 );
-		pTkip->L += pTkip->R;
-		// Clear the buffer
-		pTkip->M = 0;
-		pTkip->nBytesInM = 0;
-	}
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Calculate the MIC Value.
-
-	Arguments:
-      pAd		Pointer to our adapter
-      pSrc			Pointer to source data for Calculate MIC Value
-      Len			Indicate the length of the source data
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPTkipAppend(
-	IN	PTKIP_KEY_INFO	pTkip,
-	IN	PUCHAR			pSrc,
-	IN	UINT			nBytes)
-{
-	// This is simple
-	while(nBytes > 0)
-	{
-		RTMPTkipAppendByte(pTkip, *pSrc++);
-		nBytes--;
-	}
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Get the MIC Value.
-
-	Arguments:
-      pAd		Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-		the MIC Value is store in pAd->PrivateInfo.MIC
-	========================================================================
-*/
-VOID	RTMPTkipGetMIC(
-	IN	PTKIP_KEY_INFO	pTkip)
-{
-	// Append the minimum padding
-	RTMPTkipAppendByte(pTkip, 0x5a );
-	RTMPTkipAppendByte(pTkip, 0 );
-	RTMPTkipAppendByte(pTkip, 0 );
-	RTMPTkipAppendByte(pTkip, 0 );
-	RTMPTkipAppendByte(pTkip, 0 );
-	// and then zeroes until the length is a multiple of 4
-	while( pTkip->nBytesInM != 0 )
-	{
-		RTMPTkipAppendByte(pTkip, 0 );
-	}
-	// The appendByte function has already computed the result.
-	RTMPTkipPutUInt32(pTkip->MIC, pTkip->L);
-	RTMPTkipPutUInt32(pTkip->MIC + 4, pTkip->R);
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Init Tkip function.
-
-	Arguments:
-      pAd		Pointer to our adapter
-		pTKey       Pointer to the Temporal Key (TK), TK shall be 128bits.
-		KeyId		TK Key ID
-		pTA			Pointer to transmitter address
-		pMICKey		pointer to MIC Key
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPInitTkipEngine(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pKey,
-	IN	UCHAR			KeyId,
-	IN	PUCHAR			pTA,
-	IN	PUCHAR			pMICKey,
-	IN	PUCHAR			pTSC,
-	OUT	PULONG			pIV16,
-	OUT	PULONG			pIV32)
-{
-	TKIP_IV	tkipIv;
-
-	// Prepare 8 bytes TKIP encapsulation for MPDU
-	NdisZeroMemory(&tkipIv, sizeof(TKIP_IV));
-	tkipIv.IV16.field.rc0 = *(pTSC + 1);
-	tkipIv.IV16.field.rc1 = (tkipIv.IV16.field.rc0 | 0x20) & 0x7f;
-	tkipIv.IV16.field.rc2 = *pTSC;
-	tkipIv.IV16.field.CONTROL.field.ExtIV = 1;  // 0: non-extended IV, 1: an extended IV
-	tkipIv.IV16.field.CONTROL.field.KeyID = KeyId;
-	NdisMoveMemory(&tkipIv.IV32, (pTSC + 2), 4);   // Copy IV
-
-	*pIV16 = tkipIv.IV16.word;
-	*pIV32 = tkipIv.IV32;
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Init MIC Value calculation function which include set MIC key &
-		calculate first 16 bytes (DA + SA + priority +  0)
-
-	Arguments:
-      pAd		Pointer to our adapter
-		pTKey       Pointer to the Temporal Key (TK), TK shall be 128bits.
-		pDA			Pointer to DA address
-		pSA			Pointer to SA address
-		pMICKey		pointer to MIC Key
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPInitMICEngine(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pKey,
-	IN	PUCHAR			pDA,
-	IN	PUCHAR			pSA,
-	IN  UCHAR           UserPriority,
-	IN	PUCHAR			pMICKey)
-{
-	ULONG Priority = UserPriority;
-
-	// Init MIC value calculation
-	RTMPTkipSetMICKey(&pAd->PrivateInfo.Tx, pMICKey);
-	// DA
-	RTMPTkipAppend(&pAd->PrivateInfo.Tx, pDA, MAC_ADDR_LEN);
-	// SA
-	RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSA, MAC_ADDR_LEN);
-	// Priority + 3 bytes of 0
-	RTMPTkipAppend(&pAd->PrivateInfo.Tx, (PUCHAR)&Priority, 4);
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Compare MIC value of received MSDU
-
-	Arguments:
-		pAd	Pointer to our adapter
-		pSrc        Pointer to the received Plain text data
-		pDA			Pointer to DA address
-		pSA			Pointer to SA address
-		pMICKey		pointer to MIC Key
-		Len         the length of the received plain text data exclude MIC value
-
-	Return Value:
-		TRUE        MIC value matched
-		FALSE       MIC value mismatched
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-BOOLEAN	RTMPTkipCompareMICValue(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pSrc,
-	IN	PUCHAR			pDA,
-	IN	PUCHAR			pSA,
-	IN	PUCHAR			pMICKey,
-	IN	UCHAR			UserPriority,
-	IN	UINT			Len)
-{
-	UCHAR	OldMic[8];
-	ULONG	Priority = UserPriority;
-
-	// Init MIC value calculation
-	RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
-	// DA
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
-	// SA
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
-	// Priority + 3 bytes of 0
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
-
-	// Calculate MIC value from plain text data
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
-
-	// Get MIC valude from received frame
-	NdisMoveMemory(OldMic, pSrc + Len, 8);
-
-	// Get MIC value from decrypted plain data
-	RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
-
-	// Move MIC value from MSDU, this steps should move to data path.
-	// Since the MIC value might cross MPDUs.
-	if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8))
-	{
-		DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValue(): TKIP MIC Error !\n"));  //MIC error.
-
-
-		return (FALSE);
-	}
-	return (TRUE);
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Compare MIC value of received MSDU
-
-	Arguments:
-		pAd	Pointer to our adapter
-		pLLC		LLC header
-		pSrc        Pointer to the received Plain text data
-		pDA			Pointer to DA address
-		pSA			Pointer to SA address
-		pMICKey		pointer to MIC Key
-		Len         the length of the received plain text data exclude MIC value
-
-	Return Value:
-		TRUE        MIC value matched
-		FALSE       MIC value mismatched
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-BOOLEAN	RTMPTkipCompareMICValueWithLLC(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pLLC,
-	IN	PUCHAR			pSrc,
-	IN	PUCHAR			pDA,
-	IN	PUCHAR			pSA,
-	IN	PUCHAR			pMICKey,
-	IN	UINT			Len)
-{
-	UCHAR	OldMic[8];
-	ULONG	Priority = 0;
-
-	// Init MIC value calculation
-	RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
-	// DA
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
-	// SA
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
-	// Priority + 3 bytes of 0
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
-
-	// Start with LLC header
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pLLC, 8);
-
-	// Calculate MIC value from plain text data
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
-
-	// Get MIC valude from received frame
-	NdisMoveMemory(OldMic, pSrc + Len, 8);
-
-	// Get MIC value from decrypted plain data
-	RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
-
-	// Move MIC value from MSDU, this steps should move to data path.
-	// Since the MIC value might cross MPDUs.
-	if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8))
-	{
-		DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValueWithLLC(): TKIP MIC Error !\n"));  //MIC error.
-
-
-		return (FALSE);
-	}
-	return (TRUE);
-}
-/*
-	========================================================================
-
-	Routine	Description:
-		Copy frame from waiting queue into relative ring buffer and set
-	appropriate ASIC register to kick hardware transmit function
-
-	Arguments:
-		pAd		Pointer	to our adapter
-		PNDIS_PACKET	Pointer to Ndis Packet for MIC calculation
-		pEncap			Pointer to LLC encap data
-		LenEncap		Total encap length, might be 0 which indicates no encap
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPCalculateMICValue(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket,
-	IN	PUCHAR			pEncap,
-	IN	PCIPHER_KEY		pKey,
-	IN	UCHAR			apidx)
-{
-	PACKET_INFO		PacketInfo;
-	PUCHAR			pSrcBufVA;
-	UINT			SrcBufLen;
-	PUCHAR			pSrc;
-    UCHAR           UserPriority;
-	UCHAR			vlan_offset = 0;
-
-	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
-
-	UserPriority = RTMP_GET_PACKET_UP(pPacket);
-	pSrc = pSrcBufVA;
-
-	// determine if this is a vlan packet
-	if (((*(pSrc + 12) << 8) + *(pSrc + 13)) == 0x8100)
-		vlan_offset = 4;
-
-	{
-		RTMPInitMICEngine(
-			pAd,
-			pKey->Key,
-			pSrc,
-			pSrc + 6,
-			UserPriority,
-			pKey->TxMic);
-	}
-
-
-	if (pEncap != NULL)
-	{
-		// LLC encapsulation
-		RTMPTkipAppend(&pAd->PrivateInfo.Tx, pEncap, 6);
-		// Protocol Type
-		RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc + 12 + vlan_offset, 2);
-	}
-	SrcBufLen -= (14 + vlan_offset);
-	pSrc += (14 + vlan_offset);
-	do
-	{
-		if (SrcBufLen > 0)
-		{
-			RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc, SrcBufLen);
-		}
-
-		break;	// No need handle next packet
-
-	}	while (TRUE);		// End of copying payload
-
-	// Compute the final MIC Value
-	RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
-}
-
-
-/************************************************************/
-/* tkip_sbox()																*/
-/* Returns a 16 bit value from a 64K entry table. The Table */
-/* is synthesized from two 256 entry byte wide tables.		*/
-/************************************************************/
-
-UINT tkip_sbox(UINT index)
-{
-	UINT index_low;
-	UINT index_high;
-	UINT left, right;
-
-	index_low = (index % 256);
-	index_high = ((index >> 8) % 256);
-
-	left = Tkip_Sbox_Lower[index_low] + (Tkip_Sbox_Upper[index_low] * 256);
-	right = Tkip_Sbox_Upper[index_high] + (Tkip_Sbox_Lower[index_high] * 256);
-
-	return (left ^ right);
-}
-
-UINT rotr1(UINT a)
-{
-	unsigned int b;
-
-	if ((a & 0x01) == 0x01)
-	{
-		b = (a >> 1) | 0x8000;
-	}
-	else
-	{
-		b = (a >> 1) & 0x7fff;
-	}
-	b = b % 65536;
-	return b;
-}
-
-VOID RTMPTkipMixKey(
-	UCHAR *key,
-	UCHAR *ta,
-	ULONG pnl, /* Least significant 16 bits of PN */
-	ULONG pnh, /* Most significant 32 bits of PN */
-	UCHAR *rc4key,
-	UINT *p1k)
-{
-
-	UINT tsc0;
-	UINT tsc1;
-	UINT tsc2;
-
-	UINT ppk0;
-	UINT ppk1;
-	UINT ppk2;
-	UINT ppk3;
-	UINT ppk4;
-	UINT ppk5;
-
-	INT i;
-	INT j;
-
-	tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
-	tsc1 = (unsigned int)(pnh % 65536);
-	tsc2 = (unsigned int)(pnl % 65536); /* lsb */
-
-	/* Phase 1, step 1 */
-	p1k[0] = tsc1;
-	p1k[1] = tsc0;
-	p1k[2] = (UINT)(ta[0] + (ta[1]*256));
-	p1k[3] = (UINT)(ta[2] + (ta[3]*256));
-	p1k[4] = (UINT)(ta[4] + (ta[5]*256));
-
-	/* Phase 1, step 2 */
-	for (i=0; i<8; i++)
-	{
-		j = 2*(i & 1);
-		p1k[0] = (p1k[0] + tkip_sbox( (p1k[4] ^ ((256*key[1+j]) + key[j])) % 65536 )) % 65536;
-		p1k[1] = (p1k[1] + tkip_sbox( (p1k[0] ^ ((256*key[5+j]) + key[4+j])) % 65536 )) % 65536;
-		p1k[2] = (p1k[2] + tkip_sbox( (p1k[1] ^ ((256*key[9+j]) + key[8+j])) % 65536 )) % 65536;
-		p1k[3] = (p1k[3] + tkip_sbox( (p1k[2] ^ ((256*key[13+j]) + key[12+j])) % 65536 )) % 65536;
-		p1k[4] = (p1k[4] + tkip_sbox( (p1k[3] ^ (((256*key[1+j]) + key[j]))) % 65536 )) % 65536;
-		p1k[4] = (p1k[4] + i) % 65536;
-	}
-
-	/* Phase 2, Step 1 */
-	ppk0 = p1k[0];
-	ppk1 = p1k[1];
-	ppk2 = p1k[2];
-	ppk3 = p1k[3];
-	ppk4 = p1k[4];
-	ppk5 = (p1k[4] + tsc2) % 65536;
-
-	/* Phase2, Step 2 */
-	ppk0 = ppk0 + tkip_sbox( (ppk5 ^ ((256*key[1]) + key[0])) % 65536);
-	ppk1 = ppk1 + tkip_sbox( (ppk0 ^ ((256*key[3]) + key[2])) % 65536);
-	ppk2 = ppk2 + tkip_sbox( (ppk1 ^ ((256*key[5]) + key[4])) % 65536);
-	ppk3 = ppk3 + tkip_sbox( (ppk2 ^ ((256*key[7]) + key[6])) % 65536);
-	ppk4 = ppk4 + tkip_sbox( (ppk3 ^ ((256*key[9]) + key[8])) % 65536);
-	ppk5 = ppk5 + tkip_sbox( (ppk4 ^ ((256*key[11]) + key[10])) % 65536);
-
-	ppk0 = ppk0 + rotr1(ppk5 ^ ((256*key[13]) + key[12]));
-	ppk1 = ppk1 + rotr1(ppk0 ^ ((256*key[15]) + key[14]));
-	ppk2 = ppk2 + rotr1(ppk1);
-	ppk3 = ppk3 + rotr1(ppk2);
-	ppk4 = ppk4 + rotr1(ppk3);
-	ppk5 = ppk5 + rotr1(ppk4);
-
-	/* Phase 2, Step 3 */
-    /* Phase 2, Step 3 */
-
-	tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
-	tsc1 = (unsigned int)(pnh % 65536);
-	tsc2 = (unsigned int)(pnl % 65536); /* lsb */
-
-	rc4key[0] = (tsc2 >> 8) % 256;
-	rc4key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f;
-	rc4key[2] = tsc2 % 256;
-	rc4key[3] = ((ppk5 ^ ((256*key[1]) + key[0])) >> 1) % 256;
-
-	rc4key[4] = ppk0 % 256;
-	rc4key[5] = (ppk0 >> 8) % 256;
-
-	rc4key[6] = ppk1 % 256;
-	rc4key[7] = (ppk1 >> 8) % 256;
-
-	rc4key[8] = ppk2 % 256;
-	rc4key[9] = (ppk2 >> 8) % 256;
-
-	rc4key[10] = ppk3 % 256;
-	rc4key[11] = (ppk3 >> 8) % 256;
-
-	rc4key[12] = ppk4 % 256;
-	rc4key[13] = (ppk4 >> 8) % 256;
-
-	rc4key[14] = ppk5 % 256;
-	rc4key[15] = (ppk5 >> 8) % 256;
-}
-
-
-/************************************************/
-/* construct_mic_header1()                      */
-/* Builds the first MIC header block from       */
-/* header fields.                               */
-/************************************************/
-
-void construct_mic_header1(
-	unsigned char *mic_header1,
-	int header_length,
-	unsigned char *mpdu)
-{
-	mic_header1[0] = (unsigned char)((header_length - 2) / 256);
-	mic_header1[1] = (unsigned char)((header_length - 2) % 256);
-	mic_header1[2] = mpdu[0] & 0xcf;    /* Mute CF poll & CF ack bits */
-	mic_header1[3] = mpdu[1] & 0xc7;    /* Mute retry, more data and pwr mgt bits */
-	mic_header1[4] = mpdu[4];       /* A1 */
-	mic_header1[5] = mpdu[5];
-	mic_header1[6] = mpdu[6];
-	mic_header1[7] = mpdu[7];
-	mic_header1[8] = mpdu[8];
-	mic_header1[9] = mpdu[9];
-	mic_header1[10] = mpdu[10];     /* A2 */
-	mic_header1[11] = mpdu[11];
-	mic_header1[12] = mpdu[12];
-	mic_header1[13] = mpdu[13];
-	mic_header1[14] = mpdu[14];
-	mic_header1[15] = mpdu[15];
-}
-
-/************************************************/
-/* construct_mic_header2()                      */
-/* Builds the last MIC header block from        */
-/* header fields.                               */
-/************************************************/
-
-void construct_mic_header2(
-	unsigned char *mic_header2,
-	unsigned char *mpdu,
-	int a4_exists,
-	int qc_exists)
-{
-	int i;
-
-	for (i = 0; i<16; i++) mic_header2[i]=0x00;
-
-	mic_header2[0] = mpdu[16];    /* A3 */
-	mic_header2[1] = mpdu[17];
-	mic_header2[2] = mpdu[18];
-	mic_header2[3] = mpdu[19];
-	mic_header2[4] = mpdu[20];
-	mic_header2[5] = mpdu[21];
-
-	// In Sequence Control field, mute sequence numer bits (12-bit)
-	mic_header2[6] = mpdu[22] & 0x0f;   /* SC */
-	mic_header2[7] = 0x00; /* mpdu[23]; */
-
-	if ((!qc_exists) & a4_exists)
-	{
-		for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i];   /* A4 */
-
-	}
-
-	if (qc_exists && (!a4_exists))
-	{
-		mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
-		mic_header2[9] = mpdu[25] & 0x00;
-	}
-
-	if (qc_exists && a4_exists)
-	{
-		for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i];   /* A4 */
-
-		mic_header2[14] = mpdu[30] & 0x0f;
-		mic_header2[15] = mpdu[31] & 0x00;
-	}
-}
-
-
-/************************************************/
-/* construct_mic_iv()                           */
-/* Builds the MIC IV from header fields and PN  */
-/************************************************/
-
-void construct_mic_iv(
-	unsigned char *mic_iv,
-	int qc_exists,
-	int a4_exists,
-	unsigned char *mpdu,
-	unsigned int payload_length,
-	unsigned char *pn_vector)
-{
-	int i;
-
-	mic_iv[0] = 0x59;
-	if (qc_exists && a4_exists)
-		mic_iv[1] = mpdu[30] & 0x0f;    /* QoS_TC           */
-	if (qc_exists && !a4_exists)
-		mic_iv[1] = mpdu[24] & 0x0f;   /* mute bits 7-4    */
-	if (!qc_exists)
-		mic_iv[1] = 0x00;
-	for (i = 2; i < 8; i++)
-		mic_iv[i] = mpdu[i + 8];                    /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
-#ifdef CONSISTENT_PN_ORDER
-		for (i = 8; i < 14; i++)
-			mic_iv[i] = pn_vector[i - 8];           /* mic_iv[8:13] = PN[0:5] */
-#else
-		for (i = 8; i < 14; i++)
-			mic_iv[i] = pn_vector[13 - i];          /* mic_iv[8:13] = PN[5:0] */
-#endif
-	i = (payload_length / 256);
-	i = (payload_length % 256);
-	mic_iv[14] = (unsigned char) (payload_length / 256);
-	mic_iv[15] = (unsigned char) (payload_length % 256);
-
-}
-
-
-
-/************************************/
-/* bitwise_xor()                    */
-/* A 128 bit, bitwise exclusive or  */
-/************************************/
-
-void bitwise_xor(unsigned char *ina, unsigned char *inb, unsigned char *out)
-{
-	int i;
-	for (i=0; i<16; i++)
-	{
-		out[i] = ina[i] ^ inb[i];
-	}
-}
-
-
-void aes128k128d(unsigned char *key, unsigned char *data, unsigned char *ciphertext)
-{
-	int round;
-	int i;
-	unsigned char intermediatea[16];
-	unsigned char intermediateb[16];
-	unsigned char round_key[16];
-
-	for(i=0; i<16; i++) round_key[i] = key[i];
-
-	for (round = 0; round < 11; round++)
-	{
-		if (round == 0)
-		{
-			xor_128(round_key, data, ciphertext);
-			next_key(round_key, round);
-		}
-		else if (round == 10)
-		{
-			byte_sub(ciphertext, intermediatea);
-			shift_row(intermediatea, intermediateb);
-			xor_128(intermediateb, round_key, ciphertext);
-		}
-		else    /* 1 - 9 */
-		{
-			byte_sub(ciphertext, intermediatea);
-			shift_row(intermediatea, intermediateb);
-			mix_column(&intermediateb[0], &intermediatea[0]);
-			mix_column(&intermediateb[4], &intermediatea[4]);
-			mix_column(&intermediateb[8], &intermediatea[8]);
-			mix_column(&intermediateb[12], &intermediatea[12]);
-			xor_128(intermediatea, round_key, ciphertext);
-			next_key(round_key, round);
-		}
-	}
-
-}
-
-void construct_ctr_preload(
-	unsigned char *ctr_preload,
-	int a4_exists,
-	int qc_exists,
-	unsigned char *mpdu,
-	unsigned char *pn_vector,
-	int c)
-{
-
-	int i = 0;
-	for (i=0; i<16; i++) ctr_preload[i] = 0x00;
-	i = 0;
-
-	ctr_preload[0] = 0x01;                                  /* flag */
-	if (qc_exists && a4_exists) ctr_preload[1] = mpdu[30] & 0x0f;   /* QoC_Control  */
-	if (qc_exists && !a4_exists) ctr_preload[1] = mpdu[24] & 0x0f;
-
-	for (i = 2; i < 8; i++)
-		ctr_preload[i] = mpdu[i + 8];                       /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
-#ifdef CONSISTENT_PN_ORDER
-	  for (i = 8; i < 14; i++)
-			ctr_preload[i] =    pn_vector[i - 8];           /* ctr_preload[8:13] = PN[0:5] */
-#else
-	  for (i = 8; i < 14; i++)
-			ctr_preload[i] =    pn_vector[13 - i];          /* ctr_preload[8:13] = PN[5:0] */
-#endif
-	ctr_preload[14] =  (unsigned char) (c / 256); // Ctr
-	ctr_preload[15] =  (unsigned char) (c % 256);
-
-}
-
-
-//
-// TRUE: Success!
-// FALSE: Decrypt Error!
-//
-BOOLEAN RTMPSoftDecryptTKIP(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR	pData,
-	IN ULONG	DataByteCnt,
-	IN UCHAR    UserPriority,
-	IN PCIPHER_KEY	pWpaKey)
-{
-	UCHAR			KeyID;
-	UINT			HeaderLen;
-    UCHAR			fc0;
-	UCHAR			fc1;
-	USHORT			fc;
-	UINT			frame_type;
-	UINT			frame_subtype;
-    UINT			from_ds;
-    UINT			to_ds;
-	INT				a4_exists;
-	INT				qc_exists;
-	USHORT			duration;
-	USHORT			seq_control;
-	USHORT			qos_control;
-	UCHAR			TA[MAC_ADDR_LEN];
-	UCHAR			DA[MAC_ADDR_LEN];
-	UCHAR			SA[MAC_ADDR_LEN];
-	UCHAR			RC4Key[16];
-	UINT			p1k[5]; //for mix_key;
-	ULONG			pnl;/* Least significant 16 bits of PN */
-	ULONG			pnh;/* Most significant 32 bits of PN */
-	UINT			num_blocks;
-	UINT			payload_remainder;
-	ARCFOURCONTEXT 	ArcFourContext;
-	UINT			crc32 = 0;
-	UINT			trailfcs = 0;
-	UCHAR			MIC[8];
-	UCHAR			TrailMIC[8];
-
-	fc0 = *pData;
-	fc1 = *(pData + 1);
-
-	fc = *((PUSHORT)pData);
-
-	frame_type = ((fc0 >> 2) & 0x03);
-	frame_subtype = ((fc0 >> 4) & 0x0f);
-
-    from_ds = (fc1 & 0x2) >> 1;
-    to_ds = (fc1 & 0x1);
-
-    a4_exists = (from_ds & to_ds);
-    qc_exists = ((frame_subtype == 0x08) ||    /* Assumed QoS subtypes */
-                  (frame_subtype == 0x09) ||   /* Likely to change.    */
-                  (frame_subtype == 0x0a) ||
-                  (frame_subtype == 0x0b)
-                 );
-
-	HeaderLen = 24;
-	if (a4_exists)
-		HeaderLen += 6;
-
-	KeyID = *((PUCHAR)(pData+ HeaderLen + 3));
-	KeyID = KeyID >> 6;
-
-	if (pWpaKey[KeyID].KeyLen == 0)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP failed!(KeyID[%d] Length can not be 0)\n", KeyID));
-		return FALSE;
-	}
-
-	duration = *((PUSHORT)(pData+2));
-
-	seq_control = *((PUSHORT)(pData+22));
-
-	if (qc_exists)
-	{
-		if (a4_exists)
-		{
-			qos_control = *((PUSHORT)(pData+30));
-		}
-		else
-		{
-			qos_control = *((PUSHORT)(pData+24));
-		}
-	}
-
-	if (to_ds == 0 && from_ds == 1)
-	{
-		NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN);
-		NdisMoveMemory(SA, pData+16, MAC_ADDR_LEN);
-		NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);  //BSSID
-	}
-	else if (to_ds == 0 && from_ds == 0 )
-	{
-		NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
-		NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN);
-		NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN);
-	}
-	else if (to_ds == 1 && from_ds == 0)
-	{
-		NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN);
-		NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
-		NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN);
-	}
-	else if (to_ds == 1 && from_ds == 1)
-	{
-		NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
-		NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN);
-		NdisMoveMemory(SA, pData+22, MAC_ADDR_LEN);
-	}
-
-	num_blocks = (DataByteCnt - 16) / 16;
-	payload_remainder = (DataByteCnt - 16) % 16;
-
-	pnl = (*(pData + HeaderLen)) * 256 + *(pData + HeaderLen + 2);
-	pnh = *((PULONG)(pData + HeaderLen + 4));
-	pnh = cpu2le32(pnh);
-	RTMPTkipMixKey(pWpaKey[KeyID].Key, TA, pnl, pnh, RC4Key, p1k);
-
-	ARCFOUR_INIT(&ArcFourContext, RC4Key, 16);
-
-	ARCFOUR_DECRYPT(&ArcFourContext, pData + HeaderLen, pData + HeaderLen + 8, DataByteCnt - HeaderLen - 8);
-	NdisMoveMemory(&trailfcs, pData + DataByteCnt - 8 - 4, 4);
-	crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 4);  //Skip IV+EIV 8 bytes & Skip last 4 bytes(FCS).
-	crc32 ^= 0xffffffff;             /* complement */
-
-    if(crc32 != cpu2le32(trailfcs))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP, WEP Data ICV Error !\n"));	 //ICV error.
-
-		return (FALSE);
-	}
-
-	NdisMoveMemory(TrailMIC, pData + DataByteCnt - 8 - 8 - 4, 8);
-	RTMPInitMICEngine(pAd, pWpaKey[KeyID].Key, DA, SA, UserPriority, pWpaKey[KeyID].RxMic);
-	RTMPTkipAppend(&pAd->PrivateInfo.Tx, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 12);
-	RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
-	NdisMoveMemory(MIC, pAd->PrivateInfo.Tx.MIC, 8);
-
-	if (!NdisEqualMemory(MIC, TrailMIC, 8))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptTKIP, WEP Data MIC Error !\n"));	 //MIC error.
-		return (FALSE);
-	}
-
-	return TRUE;
-}
-
-
-
-
-BOOLEAN RTMPSoftDecryptAES(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR	pData,
-	IN ULONG	DataByteCnt,
-	IN PCIPHER_KEY	pWpaKey)
-{
-	UCHAR			KeyID;
-	UINT			HeaderLen;
-	UCHAR			PN[6];
-	UINT			payload_len;
-	UINT			num_blocks;
-	UINT			payload_remainder;
-	USHORT			fc;
-	UCHAR			fc0;
-	UCHAR			fc1;
-	UINT			frame_type;
-	UINT			frame_subtype;
-	UINT			from_ds;
-	UINT			to_ds;
-	INT				a4_exists;
-	INT				qc_exists;
-	UCHAR			aes_out[16];
-	int 			payload_index;
-	UINT 			i;
-	UCHAR 			ctr_preload[16];
-	UCHAR 			chain_buffer[16];
-	UCHAR 			padded_buffer[16];
-	UCHAR 			mic_iv[16];
-	UCHAR 			mic_header1[16];
-	UCHAR 			mic_header2[16];
-	UCHAR			MIC[8];
-	UCHAR			TrailMIC[8];
-
-	fc0 = *pData;
-	fc1 = *(pData + 1);
-
-	fc = *((PUSHORT)pData);
-
-	frame_type = ((fc0 >> 2) & 0x03);
-	frame_subtype = ((fc0 >> 4) & 0x0f);
-
-	from_ds = (fc1 & 0x2) >> 1;
-	to_ds = (fc1 & 0x1);
-
-	a4_exists = (from_ds & to_ds);
-	qc_exists = ((frame_subtype == 0x08) ||    /* Assumed QoS subtypes */
-				  (frame_subtype == 0x09) ||   /* Likely to change.    */
-				  (frame_subtype == 0x0a) ||
-				  (frame_subtype == 0x0b)
-				 );
-
-	HeaderLen = 24;
-	if (a4_exists)
-		HeaderLen += 6;
-
-	KeyID = *((PUCHAR)(pData+ HeaderLen + 3));
-	KeyID = KeyID >> 6;
-
-	if (pWpaKey[KeyID].KeyLen == 0)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptAES failed!(KeyID[%d] Length can not be 0)\n", KeyID));
-		return FALSE;
-	}
-
-	PN[0] = *(pData+ HeaderLen);
-	PN[1] = *(pData+ HeaderLen + 1);
-	PN[2] = *(pData+ HeaderLen + 4);
-	PN[3] = *(pData+ HeaderLen + 5);
-	PN[4] = *(pData+ HeaderLen + 6);
-	PN[5] = *(pData+ HeaderLen + 7);
-
-	payload_len = DataByteCnt - HeaderLen - 8 - 8;	// 8 bytes for CCMP header , 8 bytes for MIC
-	payload_remainder = (payload_len) % 16;
-	num_blocks = (payload_len) / 16;
-
-
-
-	// Find start of payload
-	payload_index = HeaderLen + 8; //IV+EIV
-
-	for (i=0; i< num_blocks; i++)
-	{
-		construct_ctr_preload(ctr_preload,
-								a4_exists,
-								qc_exists,
-								pData,
-								PN,
-								i+1 );
-
-		aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
-
-		bitwise_xor(aes_out, pData + payload_index, chain_buffer);
-		NdisMoveMemory(pData + payload_index - 8, chain_buffer, 16);
-		payload_index += 16;
-	}
-
-	//
-	// If there is a short final block, then pad it
-	// encrypt it and copy the unpadded part back
-	//
-	if (payload_remainder > 0)
-	{
-		construct_ctr_preload(ctr_preload,
-								a4_exists,
-								qc_exists,
-								pData,
-								PN,
-								num_blocks + 1);
-
-		NdisZeroMemory(padded_buffer, 16);
-		NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
-
-		aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
-
-		bitwise_xor(aes_out, padded_buffer, chain_buffer);
-		NdisMoveMemory(pData + payload_index - 8, chain_buffer, payload_remainder);
-		payload_index += payload_remainder;
-	}
-
-	//
-	// Descrypt the MIC
-	//
-	construct_ctr_preload(ctr_preload,
-							a4_exists,
-							qc_exists,
-							pData,
-							PN,
-							0);
-	NdisZeroMemory(padded_buffer, 16);
-	NdisMoveMemory(padded_buffer, pData + payload_index, 8);
-
-	aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
-
-	bitwise_xor(aes_out, padded_buffer, chain_buffer);
-
-	NdisMoveMemory(TrailMIC, chain_buffer, 8);
-
-	//
-	// Calculate MIC
-	//
-
-	//Force the protected frame bit on
-	*(pData + 1) = *(pData + 1) | 0x40;
-
-	// Find start of payload
-	// Because the CCMP header has been removed
-	payload_index = HeaderLen;
-
-	construct_mic_iv(
-					mic_iv,
-					qc_exists,
-					a4_exists,
-					pData,
-					payload_len,
-					PN);
-
-	construct_mic_header1(
-						mic_header1,
-						HeaderLen,
-						pData);
-
-	construct_mic_header2(
-						mic_header2,
-						pData,
-						a4_exists,
-						qc_exists);
-
-	aes128k128d(pWpaKey[KeyID].Key, mic_iv, aes_out);
-	bitwise_xor(aes_out, mic_header1, chain_buffer);
-	aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
-	bitwise_xor(aes_out, mic_header2, chain_buffer);
-	aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
-
-	// iterate through each 16 byte payload block
-	for (i = 0; i < num_blocks; i++)
-	{
-		bitwise_xor(aes_out, pData + payload_index, chain_buffer);
-		payload_index += 16;
-		aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
-	}
-
-	// Add on the final payload block if it needs padding
-	if (payload_remainder > 0)
-	{
-		NdisZeroMemory(padded_buffer, 16);
-		NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
-
-		bitwise_xor(aes_out, padded_buffer, chain_buffer);
-		aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
-	}
-	// aes_out contains padded mic, discard most significant
-	// 8 bytes to generate 64 bit MIC
-	for (i = 0 ; i < 8; i++) MIC[i] = aes_out[i];
-
-	if (!NdisEqualMemory(MIC, TrailMIC, 8))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptAES, MIC Error !\n"));	 //MIC error.
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-/****************************************/
-/* aes128k128d()                        */
-/* Performs a 128 bit AES encrypt with  */
-/* 128 bit data.                        */
-/****************************************/
-VOID xor_128(
-	IN  PUCHAR  a,
-	IN  PUCHAR  b,
-	OUT PUCHAR  out)
-{
-	INT i;
-
-	for (i=0;i<16; i++)
-	{
-		out[i] = a[i] ^ b[i];
-	}
-}
-
-VOID next_key(
-	IN  PUCHAR  key,
-	IN  INT     round)
-{
-	UCHAR       rcon;
-	UCHAR       sbox_key[4];
-	UCHAR       rcon_table[12] =
-	{
-		0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
-		0x1b, 0x36, 0x36, 0x36
-	};
-
-	sbox_key[0] = RTMPCkipSbox(key[13]);
-	sbox_key[1] = RTMPCkipSbox(key[14]);
-	sbox_key[2] = RTMPCkipSbox(key[15]);
-	sbox_key[3] = RTMPCkipSbox(key[12]);
-
-	rcon = rcon_table[round];
-
-	xor_32(&key[0], sbox_key, &key[0]);
-	key[0] = key[0] ^ rcon;
-
-	xor_32(&key[4], &key[0], &key[4]);
-	xor_32(&key[8], &key[4], &key[8]);
-	xor_32(&key[12], &key[8], &key[12]);
-}
-
-VOID xor_32(
-	IN  PUCHAR  a,
-	IN  PUCHAR  b,
-	OUT PUCHAR  out)
-{
-	INT i;
-
-	for (i=0;i<4; i++)
-	{
-		out[i] = a[i] ^ b[i];
-	}
-}
-
-VOID byte_sub(
-	IN  PUCHAR  in,
-	OUT PUCHAR  out)
-{
-	INT i;
-
-	for (i=0; i< 16; i++)
-	{
-		out[i] = RTMPCkipSbox(in[i]);
-	}
-}
-
-UCHAR RTMPCkipSbox(
-	IN  UCHAR   a)
-{
-	return SboxTable[(int)a];
-}
-
-VOID shift_row(
-	IN  PUCHAR  in,
-	OUT PUCHAR  out)
-{
-	out[0] =  in[0];
-	out[1] =  in[5];
-	out[2] =  in[10];
-	out[3] =  in[15];
-	out[4] =  in[4];
-	out[5] =  in[9];
-	out[6] =  in[14];
-	out[7] =  in[3];
-	out[8] =  in[8];
-	out[9] =  in[13];
-	out[10] = in[2];
-	out[11] = in[7];
-	out[12] = in[12];
-	out[13] = in[1];
-	out[14] = in[6];
-	out[15] = in[11];
-}
-
-VOID mix_column(
-	IN  PUCHAR  in,
-	OUT PUCHAR  out)
-{
-	INT         i;
-	UCHAR       add1b[4];
-	UCHAR       add1bf7[4];
-	UCHAR       rotl[4];
-	UCHAR       swap_halfs[4];
-	UCHAR       andf7[4];
-	UCHAR       rotr[4];
-	UCHAR       temp[4];
-	UCHAR       tempb[4];
-
-	for (i=0 ; i<4; i++)
-	{
-		if ((in[i] & 0x80)== 0x80)
-			add1b[i] = 0x1b;
-		else
-			add1b[i] = 0x00;
-	}
-
-	swap_halfs[0] = in[2];    /* Swap halfs */
-	swap_halfs[1] = in[3];
-	swap_halfs[2] = in[0];
-	swap_halfs[3] = in[1];
-
-	rotl[0] = in[3];        /* Rotate left 8 bits */
-	rotl[1] = in[0];
-	rotl[2] = in[1];
-	rotl[3] = in[2];
-
-	andf7[0] = in[0] & 0x7f;
-	andf7[1] = in[1] & 0x7f;
-	andf7[2] = in[2] & 0x7f;
-	andf7[3] = in[3] & 0x7f;
-
-	for (i = 3; i>0; i--)    /* logical shift left 1 bit */
-	{
-		andf7[i] = andf7[i] << 1;
-		if ((andf7[i-1] & 0x80) == 0x80)
-		{
-			andf7[i] = (andf7[i] | 0x01);
-		}
-	}
-	andf7[0] = andf7[0] << 1;
-	andf7[0] = andf7[0] & 0xfe;
-
-	xor_32(add1b, andf7, add1bf7);
-
-	xor_32(in, add1bf7, rotr);
-
-	temp[0] = rotr[0];         /* Rotate right 8 bits */
-	rotr[0] = rotr[1];
-	rotr[1] = rotr[2];
-	rotr[2] = rotr[3];
-	rotr[3] = temp[0];
-
-	xor_32(add1bf7, rotr, temp);
-	xor_32(swap_halfs, rotl,tempb);
-	xor_32(temp, tempb, out);
-}
-
diff --git a/drivers/staging/rt2860/common/rtmp_wep.c b/drivers/staging/rt2860/common/rtmp_wep.c
deleted file mode 100644
index 8e833e7..0000000
--- a/drivers/staging/rt2860/common/rtmp_wep.c
+++ /dev/null
@@ -1,497 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtmp_wep.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Paul Wu		10-28-02		Initial
-*/
-
-#include "../rt_config.h"
-
-UINT FCSTAB_32[256] =
-{
-	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
-	0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
-	0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
-	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
-	0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
-	0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
-	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
-	0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
-	0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
-	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
-	0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
-	0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
-	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
-	0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
-	0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
-	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
-	0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
-	0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
-	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
-	0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
-	0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
-	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
-	0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
-	0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
-	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
-	0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
-	0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
-	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
-	0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
-	0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
-	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
-	0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
-	0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
-	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
-	0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
-	0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
-	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
-	0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
-	0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
-	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
-	0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
-	0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
-	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
-	0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
-	0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
-	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
-	0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
-	0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
-	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
-	0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
-	0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
-	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
-	0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
-	0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
-	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
-	0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
-	0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
-	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
-	0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
-	0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
-	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
-	0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
-	0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
-	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
-};
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Init WEP function.
-
-	Arguments:
-      pAd		Pointer to our adapter
-		pKey        Pointer to the WEP KEY
-		KeyId		   WEP Key ID
-		KeyLen      the length of WEP KEY
-		pDest       Pointer to the destination which Encryption data will store in.
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPInitWepEngine(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pKey,
-	IN	UCHAR			KeyId,
-	IN	UCHAR			KeyLen,
-	IN OUT	PUCHAR		pDest)
-{
-	UINT i;
-	UCHAR   WEPKEY[] = {
-		//IV
-		0x00, 0x11, 0x22,
-		//WEP KEY
-		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
-	};
-
-	pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32;   //Init crc32.
-
-    if (pAd->StaCfg.bCkipOn && (pAd->StaCfg.CkipFlag & 0x10) && (pAd->OpMode == OPMODE_STA))
-    {
-        ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, pKey, KeyLen);  //INIT SBOX, KEYLEN+3(IV)
-        NdisMoveMemory(pDest, pKey, 3);  //Append Init Vector
-    }
-    else
-    {
-		NdisMoveMemory(WEPKEY + 3, pKey, KeyLen);
-
-        for(i = 0; i < 3; i++)
-			WEPKEY[i] = RandomByte(pAd);   //Call mlme RandomByte() function.
-		ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, KeyLen + 3);  //INIT SBOX, KEYLEN+3(IV)
-
-		NdisMoveMemory(pDest, WEPKEY, 3);  //Append Init Vector
-    }
-	*(pDest+3) = (KeyId << 6);       //Append KEYID
-
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Encrypt transimitted data
-
-	Arguments:
-      pAd		Pointer to our adapter
-      pSrc        Pointer to the transimitted source data that will be encrypt
-      pDest       Pointer to the destination where entryption data will be store in.
-      Len			Indicate the length of the source data
-
-	Return Value:
-      None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPEncryptData(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pSrc,
-	IN	PUCHAR			pDest,
-	IN	UINT			Len)
-{
-	pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, pSrc, Len);
-	ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, pSrc, Len);
-}
-
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Decrypt received WEP data
-
-	Arguments:
-		pAdapter		Pointer to our adapter
-		pSrc        Pointer to the received data
-		Len         the length of the received data
-
-	Return Value:
-		TRUE        Decrypt WEP data success
-		FALSE       Decrypt WEP data failed
-
-	Note:
-
-	========================================================================
-*/
-BOOLEAN	RTMPSoftDecryptWEP(
-	IN PRTMP_ADAPTER 	pAd,
-	IN PUCHAR			pData,
-	IN ULONG			DataByteCnt,
-	IN PCIPHER_KEY		pGroupKey)
-{
-	UINT	trailfcs;
-	UINT    crc32;
-	UCHAR	KeyIdx;
-	UCHAR   WEPKEY[] = {
-		//IV
-		0x00, 0x11, 0x22,
-		//WEP KEY
-		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
-	};
-	UCHAR 	*pPayload = (UCHAR *)pData + LENGTH_802_11;
-	ULONG	payload_len = DataByteCnt - LENGTH_802_11;
-
-	NdisMoveMemory(WEPKEY, pPayload, 3);    //Get WEP IV
-
-	KeyIdx = (*(pPayload + 3) & 0xc0) >> 6;
-	if (pGroupKey[KeyIdx].KeyLen == 0)
-		return (FALSE);
-
-	NdisMoveMemory(WEPKEY + 3, pGroupKey[KeyIdx].Key, pGroupKey[KeyIdx].KeyLen);
-	ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, pGroupKey[KeyIdx].KeyLen + 3);
-	ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, pPayload, pPayload + 4, payload_len - 4);
-	NdisMoveMemory(&trailfcs, pPayload + payload_len - 8, 4);
-	crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pPayload, payload_len - 8);  //Skip last 4 bytes(FCS).
-	crc32 ^= 0xffffffff;             /* complement */
-
-    if(crc32 != cpu2le32(trailfcs))
-    {
-		DBGPRINT(RT_DEBUG_TRACE, ("! WEP Data CRC Error !\n"));	 //CRC error.
-		return (FALSE);
-	}
-	return (TRUE);
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		The Stream Cipher Encryption Algorithm "ARCFOUR" initialize
-
-	Arguments:
-	   Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
-		pKey        Pointer to the WEP KEY
-		KeyLen      Indicate the length fo the WEP KEY
-
-	Return Value:
-	   None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	ARCFOUR_INIT(
-	IN	PARCFOURCONTEXT	Ctx,
-	IN	PUCHAR			pKey,
-	IN	UINT			KeyLen)
-{
-	UCHAR	t, u;
-	UINT	keyindex;
-	UINT	stateindex;
-	PUCHAR	state;
-	UINT	counter;
-
-	state = Ctx->STATE;
-	Ctx->X = 0;
-	Ctx->Y = 0;
-	for (counter = 0; counter < 256; counter++)
-		state[counter] = (UCHAR)counter;
-	keyindex = 0;
-	stateindex = 0;
-	for (counter = 0; counter < 256; counter++)
-	{
-		t = state[counter];
-		stateindex = (stateindex + pKey[keyindex] + t) & 0xff;
-		u = state[stateindex];
-		state[stateindex] = t;
-		state[counter] = u;
-		if (++keyindex >= KeyLen)
-			keyindex = 0;
-	}
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Get bytes from ARCFOUR CONTEXT (S-BOX)
-
-	Arguments:
-	   Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
-
-	Return Value:
-	   UCHAR  - the value of the ARCFOUR CONTEXT (S-BOX)
-
-	Note:
-
-	========================================================================
-*/
-UCHAR	ARCFOUR_BYTE(
-	IN	PARCFOURCONTEXT		Ctx)
-{
-  UINT x;
-  UINT y;
-  UCHAR sx, sy;
-  PUCHAR state;
-
-  state = Ctx->STATE;
-  x = (Ctx->X + 1) & 0xff;
-  sx = state[x];
-  y = (sx + Ctx->Y) & 0xff;
-  sy = state[y];
-  Ctx->X = x;
-  Ctx->Y = y;
-  state[y] = sx;
-  state[x] = sy;
-
-  return(state[(sx + sy) & 0xff]);
-
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		The Stream Cipher Decryption Algorithm
-
-	Arguments:
-		Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
-		pDest			Pointer to the Destination
-		pSrc        Pointer to the Source data
-		Len         Indicate the length of the Source data
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	ARCFOUR_DECRYPT(
-	IN	PARCFOURCONTEXT	Ctx,
-	IN	PUCHAR			pDest,
-	IN	PUCHAR			pSrc,
-	IN	UINT			Len)
-{
-	UINT i;
-
-	for (i = 0; i < Len; i++)
-		pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		The Stream Cipher Encryption Algorithm
-
-	Arguments:
-		Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
-		pDest			Pointer to the Destination
-		pSrc        Pointer to the Source data
-		Len         Indicate the length of the Source dta
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	ARCFOUR_ENCRYPT(
-	IN	PARCFOURCONTEXT	Ctx,
-	IN	PUCHAR			pDest,
-	IN	PUCHAR			pSrc,
-	IN	UINT			Len)
-{
-	UINT i;
-
-	for (i = 0; i < Len; i++)
-		pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		The Stream Cipher Encryption Algorithm which conform to the special requirement to encrypt  GTK.
-
-	Arguments:
-		Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
-		pDest			Pointer to the Destination
-		pSrc        Pointer to the Source data
-		Len         Indicate the length of the Source dta
-
-
-	========================================================================
-*/
-
-VOID	WPAARCFOUR_ENCRYPT(
-	IN	PARCFOURCONTEXT	Ctx,
-	IN	PUCHAR			pDest,
-	IN	PUCHAR			pSrc,
-	IN	UINT			Len)
-{
-	UINT i;
-        //discard first 256 bytes
-	for (i = 0; i < 256; i++)
-            ARCFOUR_BYTE(Ctx);
-
-	for (i = 0; i < Len; i++)
-		pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
-}
-
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Calculate a new FCS given the current FCS and the new data.
-
-	Arguments:
-		Fcs	      the original FCS value
-		Cp          pointer to the data which will be calculate the FCS
-		Len         the length of the data
-
-	Return Value:
-		UINT - FCS 32 bits
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-UINT	RTMP_CALC_FCS32(
-	IN	UINT	Fcs,
-	IN	PUCHAR	Cp,
-	IN	INT		Len)
-{
-	while (Len--)
-	   Fcs = (((Fcs) >> 8) ^ FCSTAB_32[((Fcs) ^ (*Cp++)) & 0xff]);
-
-	return (Fcs);
-}
-
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Get last FCS and encrypt it to the destination
-
-	Arguments:
-		pDest			Pointer to the Destination
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPSetICV(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR	pDest)
-{
-	pAd->PrivateInfo.FCSCRC32 ^= 0xffffffff;             /* complement */
-	pAd->PrivateInfo.FCSCRC32 = cpu2le32(pAd->PrivateInfo.FCSCRC32);
-
-	ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, (PUCHAR) &pAd->PrivateInfo.FCSCRC32, 4);
-}
-
diff --git a/drivers/staging/rt2860/common/spectrum.c b/drivers/staging/rt2860/common/spectrum.c
index c658bf3..51e38d8 100644
--- a/drivers/staging/rt2860/common/spectrum.c
+++ b/drivers/staging/rt2860/common/spectrum.c
@@ -24,7 +24,6 @@
  *                                                                       *
  *************************************************************************
 
-
     Module Name:
 	action.c
 
@@ -40,24 +39,382 @@
 #include "../rt_config.h"
 #include "action.h"
 
-VOID MeasureReqTabInit(
-	IN PRTMP_ADAPTER pAd)
+/* The regulatory information in the USA (US) */
+struct rt_dot11_regulatory_information USARegulatoryInfo[] = {
+/*  "regulatory class"  "number of channels"  "Max Tx Pwr"  "channel list" */
+	{0, {0, 0, {0}
+	     }
+	 }
+	,			/* Invlid entry */
+	{1, {4, 16, {36, 40, 44, 48}
+	     }
+	 }
+	,
+	{2, {4, 23, {52, 56, 60, 64}
+	     }
+	 }
+	,
+	{3, {4, 29, {149, 153, 157, 161}
+	     }
+	 }
+	,
+	{4, {11, 23, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}
+	     }
+	 }
+	,
+	{5, {5, 30, {149, 153, 157, 161, 165}
+	     }
+	 }
+	,
+	{6, {10, 14, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
+	     }
+	 }
+	,
+	{7, {10, 27, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
+	     }
+	 }
+	,
+	{8, {5, 17, {11, 13, 15, 17, 19}
+	     }
+	 }
+	,
+	{9, {5, 30, {11, 13, 15, 17, 19}
+	     }
+	 }
+	,
+	{10, {2, 20, {21, 25}
+	      }
+	 }
+	,
+	{11, {2, 33, {21, 25}
+	      }
+	 }
+	,
+	{12, {11, 30, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
+	      }
+	 }
+};
+
+#define USA_REGULATORY_INFO_SIZE (sizeof(USARegulatoryInfo) / sizeof(struct rt_dot11_regulatory_information))
+
+/* The regulatory information in Europe */
+struct rt_dot11_regulatory_information EuropeRegulatoryInfo[] = {
+/*  "regulatory class"  "number of channels"  "Max Tx Pwr"  "channel list" */
+	{0, {0, 0, {0}
+	     }
+	 }
+	,			/* Invalid entry */
+	{1, {4, 20, {36, 40, 44, 48}
+	     }
+	 }
+	,
+	{2, {4, 20, {52, 56, 60, 64}
+	     }
+	 }
+	,
+	{3, {11, 30, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}
+	     }
+	 }
+	,
+	{4, {13, 20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}
+	     }
+	 }
+};
+
+#define EU_REGULATORY_INFO_SIZE (sizeof(EuropeRegulatoryInfo) / sizeof(struct rt_dot11_regulatory_information))
+
+/* The regulatory information in Japan */
+struct rt_dot11_regulatory_information JapanRegulatoryInfo[] = {
+/*  "regulatory class"  "number of channels"  "Max Tx Pwr"  "channel list" */
+	{0, {0, 0, {0}
+	     }
+	 }
+	,			/* Invalid entry */
+	{1, {4, 22, {34, 38, 42, 46}
+	     }
+	 }
+	,
+	{2, {3, 24, {8, 12, 16}
+	     }
+	 }
+	,
+	{3, {3, 24, {8, 12, 16}
+	     }
+	 }
+	,
+	{4, {3, 24, {8, 12, 16}
+	     }
+	 }
+	,
+	{5, {3, 24, {8, 12, 16}
+	     }
+	 }
+	,
+	{6, {3, 22, {8, 12, 16}
+	     }
+	 }
+	,
+	{7, {4, 24, {184, 188, 192, 196}
+	     }
+	 }
+	,
+	{8, {4, 24, {184, 188, 192, 196}
+	     }
+	 }
+	,
+	{9, {4, 24, {184, 188, 192, 196}
+	     }
+	 }
+	,
+	{10, {4, 24, {184, 188, 192, 196}
+	      }
+	 }
+	,
+	{11, {4, 22, {184, 188, 192, 196}
+	      }
+	 }
+	,
+	{12, {4, 24, {7, 8, 9, 11}
+	      }
+	 }
+	,
+	{13, {4, 24, {7, 8, 9, 11}
+	      }
+	 }
+	,
+	{14, {4, 24, {7, 8, 9, 11}
+	      }
+	 }
+	,
+	{15, {4, 24, {7, 8, 9, 11}
+	      }
+	 }
+	,
+	{16, {6, 24, {183, 184, 185, 187, 188, 189}
+	      }
+	 }
+	,
+	{17, {6, 24, {183, 184, 185, 187, 188, 189}
+	      }
+	 }
+	,
+	{18, {6, 24, {183, 184, 185, 187, 188, 189}
+	      }
+	 }
+	,
+	{19, {6, 24, {183, 184, 185, 187, 188, 189}
+	      }
+	 }
+	,
+	{20, {6, 17, {183, 184, 185, 187, 188, 189}
+	      }
+	 }
+	,
+	{21, {6, 24, {6, 7, 8, 9, 10, 11}
+	      }
+	 }
+	,
+	{22, {6, 24, {6, 7, 8, 9, 10, 11}
+	      }
+	 }
+	,
+	{23, {6, 24, {6, 7, 8, 9, 10, 11}
+	      }
+	 }
+	,
+	{24, {6, 24, {6, 7, 8, 9, 10, 11}
+	      }
+	 }
+	,
+	{25, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}
+	      }
+	 }
+	,
+	{26, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}
+	      }
+	 }
+	,
+	{27, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}
+	      }
+	 }
+	,
+	{28, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}
+	      }
+	 }
+	,
+	{29, {8, 17, {182, 183, 184, 185, 186, 187, 188, 189}
+	      }
+	 }
+	,
+	{30, {13, 23, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}
+	      }
+	 }
+	,
+	{31, {1, 23, {14}
+	      }
+	 }
+	,
+	{32, {4, 22, {52, 56, 60, 64}
+	      }
+	 }
+};
+
+#define JP_REGULATORY_INFO_SIZE (sizeof(JapanRegulatoryInfo) / sizeof(struct rt_dot11_regulatory_information))
+
+char RTMP_GetTxPwr(struct rt_rtmp_adapter *pAd, IN HTTRANSMIT_SETTING HTTxMode)
+{
+	struct tx_pwr_cfg {
+		u8 Mode;
+		u8 MCS;
+		u16 req;
+		u8 shift;
+		u32 BitMask;
+	};
+
+	u32 Value;
+	int Idx;
+	u8 PhyMode;
+	char CurTxPwr;
+	u8 TxPwrRef = 0;
+	char DaltaPwr;
+	unsigned long TxPwr[5];
+
+	struct tx_pwr_cfg TxPwrCfg[] = {
+		{MODE_CCK, 0, 0, 4, 0x000000f0},
+		{MODE_CCK, 1, 0, 0, 0x0000000f},
+		{MODE_CCK, 2, 0, 12, 0x0000f000},
+		{MODE_CCK, 3, 0, 8, 0x00000f00},
+
+		{MODE_OFDM, 0, 0, 20, 0x00f00000},
+		{MODE_OFDM, 1, 0, 16, 0x000f0000},
+		{MODE_OFDM, 2, 0, 28, 0xf0000000},
+		{MODE_OFDM, 3, 0, 24, 0x0f000000},
+		{MODE_OFDM, 4, 1, 4, 0x000000f0},
+		{MODE_OFDM, 5, 1, 0, 0x0000000f},
+		{MODE_OFDM, 6, 1, 12, 0x0000f000},
+		{MODE_OFDM, 7, 1, 8, 0x00000f00}
+		, {MODE_HTMIX, 0, 1, 20, 0x00f00000},
+		{MODE_HTMIX, 1, 1, 16, 0x000f0000},
+		{MODE_HTMIX, 2, 1, 28, 0xf0000000},
+		{MODE_HTMIX, 3, 1, 24, 0x0f000000},
+		{MODE_HTMIX, 4, 2, 4, 0x000000f0},
+		{MODE_HTMIX, 5, 2, 0, 0x0000000f},
+		{MODE_HTMIX, 6, 2, 12, 0x0000f000},
+		{MODE_HTMIX, 7, 2, 8, 0x00000f00},
+		{MODE_HTMIX, 8, 2, 20, 0x00f00000},
+		{MODE_HTMIX, 9, 2, 16, 0x000f0000},
+		{MODE_HTMIX, 10, 2, 28, 0xf0000000},
+		{MODE_HTMIX, 11, 2, 24, 0x0f000000},
+		{MODE_HTMIX, 12, 3, 4, 0x000000f0},
+		{MODE_HTMIX, 13, 3, 0, 0x0000000f},
+		{MODE_HTMIX, 14, 3, 12, 0x0000f000},
+		{MODE_HTMIX, 15, 3, 8, 0x00000f00}
+	};
+#define MAX_TXPWR_TAB_SIZE (sizeof(TxPwrCfg) / sizeof(struct tx_pwr_cfg))
+
+	CurTxPwr = 19;
+
+	/* check Tx Power setting from UI. */
+	if (pAd->CommonCfg.TxPowerPercentage > 90) ;
+	else if (pAd->CommonCfg.TxPowerPercentage > 60)	/* reduce Pwr for 1 dB. */
+		CurTxPwr -= 1;
+	else if (pAd->CommonCfg.TxPowerPercentage > 30)	/* reduce Pwr for 3 dB. */
+		CurTxPwr -= 3;
+	else if (pAd->CommonCfg.TxPowerPercentage > 15)	/* reduce Pwr for 6 dB. */
+		CurTxPwr -= 6;
+	else if (pAd->CommonCfg.TxPowerPercentage > 9)	/* reduce Pwr for 9 dB. */
+		CurTxPwr -= 9;
+	else			/* reduce Pwr for 12 dB. */
+		CurTxPwr -= 12;
+
+	if (pAd->CommonCfg.BBPCurrentBW == BW_40) {
+		if (pAd->CommonCfg.CentralChannel > 14) {
+			TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
+			TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
+			TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
+			TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
+			TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
+		} else {
+			TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
+			TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
+			TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
+			TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
+			TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
+		}
+	} else {
+		if (pAd->CommonCfg.Channel > 14) {
+			TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
+			TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
+			TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
+			TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
+			TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
+		} else {
+			TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
+			TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
+			TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
+			TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
+			TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
+		}
+	}
+
+	switch (HTTxMode.field.MODE) {
+	case MODE_CCK:
+	case MODE_OFDM:
+		Value = TxPwr[1];
+		TxPwrRef = (Value & 0x00000f00) >> 8;
+
+		break;
+
+	case MODE_HTMIX:
+	case MODE_HTGREENFIELD:
+		if (pAd->CommonCfg.TxStream == 1) {
+			Value = TxPwr[2];
+			TxPwrRef = (Value & 0x00000f00) >> 8;
+		} else if (pAd->CommonCfg.TxStream == 2) {
+			Value = TxPwr[3];
+			TxPwrRef = (Value & 0x00000f00) >> 8;
+		}
+		break;
+	}
+
+	PhyMode = (HTTxMode.field.MODE == MODE_HTGREENFIELD)
+	    ? MODE_HTMIX : HTTxMode.field.MODE;
+
+	for (Idx = 0; Idx < MAX_TXPWR_TAB_SIZE; Idx++) {
+		if ((TxPwrCfg[Idx].Mode == PhyMode)
+		    && (TxPwrCfg[Idx].MCS == HTTxMode.field.MCS)) {
+			Value = TxPwr[TxPwrCfg[Idx].req];
+			DaltaPwr =
+			    TxPwrRef - (char)((Value & TxPwrCfg[Idx].BitMask)
+					       >> TxPwrCfg[Idx].shift);
+			CurTxPwr -= DaltaPwr;
+			break;
+		}
+	}
+
+	return CurTxPwr;
+}
+
+void MeasureReqTabInit(struct rt_rtmp_adapter *pAd)
 {
 	NdisAllocateSpinLock(&pAd->CommonCfg.MeasureReqTabLock);
 
-	pAd->CommonCfg.pMeasureReqTab = kmalloc(sizeof(MEASURE_REQ_TAB), GFP_ATOMIC);
+	pAd->CommonCfg.pMeasureReqTab =
+	    kmalloc(sizeof(struct rt_measure_req_tab), GFP_ATOMIC);
 	if (pAd->CommonCfg.pMeasureReqTab)
-		NdisZeroMemory(pAd->CommonCfg.pMeasureReqTab, sizeof(MEASURE_REQ_TAB));
+		NdisZeroMemory(pAd->CommonCfg.pMeasureReqTab,
+			       sizeof(struct rt_measure_req_tab));
 	else
-		DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pMeasureReqTab.\n", __func__));
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("%s Fail to alloc memory for pAd->CommonCfg.pMeasureReqTab.\n",
+			  __func__));
 
 	return;
 }
 
-VOID MeasureReqTabExit(
-	IN PRTMP_ADAPTER pAd)
+void MeasureReqTabExit(struct rt_rtmp_adapter *pAd)
 {
-	NdisFreeSpinLock(pAd->CommonCfg.MeasureReqTabLock);
+	NdisFreeSpinLock(&pAd->CommonCfg.MeasureReqTabLock);
 
 	if (pAd->CommonCfg.pMeasureReqTab)
 		kfree(pAd->CommonCfg.pMeasureReqTab);
@@ -66,18 +423,16 @@
 	return;
 }
 
-static PMEASURE_REQ_ENTRY MeasureReqLookUp(
-	IN PRTMP_ADAPTER	pAd,
-	IN UINT8			DialogToken)
+struct rt_measure_req_entry *MeasureReqLookUp(struct rt_rtmp_adapter *pAd, u8 DialogToken)
 {
-	UINT HashIdx;
-	PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
-	PMEASURE_REQ_ENTRY pEntry = NULL;
-	PMEASURE_REQ_ENTRY pPrevEntry = NULL;
+	u32 HashIdx;
+	struct rt_measure_req_tab *pTab = pAd->CommonCfg.pMeasureReqTab;
+	struct rt_measure_req_entry *pEntry = NULL;
+	struct rt_measure_req_entry *pPrevEntry = NULL;
 
-	if (pTab == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __func__));
+	if (pTab == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("%s: pMeasureReqTab doesn't exist.\n", __func__));
 		return NULL;
 	}
 
@@ -86,12 +441,10 @@
 	HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
 	pEntry = pTab->Hash[HashIdx];
 
-	while (pEntry)
-	{
+	while (pEntry) {
 		if (pEntry->DialogToken == DialogToken)
 			break;
-		else
-		{
+		else {
 			pPrevEntry = pEntry;
 			pEntry = pEntry->pNext;
 		}
@@ -102,50 +455,49 @@
 	return pEntry;
 }
 
-static PMEASURE_REQ_ENTRY MeasureReqInsert(
-	IN PRTMP_ADAPTER	pAd,
-	IN UINT8			DialogToken)
+struct rt_measure_req_entry *MeasureReqInsert(struct rt_rtmp_adapter *pAd, u8 DialogToken)
 {
-	INT i;
-	ULONG HashIdx;
-	PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
-	PMEASURE_REQ_ENTRY pEntry = NULL, pCurrEntry;
-	ULONG Now;
+	int i;
+	unsigned long HashIdx;
+	struct rt_measure_req_tab *pTab = pAd->CommonCfg.pMeasureReqTab;
+	struct rt_measure_req_entry *pEntry = NULL, *pCurrEntry;
+	unsigned long Now;
 
-	if(pTab == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __func__));
+	if (pTab == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("%s: pMeasureReqTab doesn't exist.\n", __func__));
 		return NULL;
 	}
 
 	pEntry = MeasureReqLookUp(pAd, DialogToken);
-	if (pEntry == NULL)
-	{
+	if (pEntry == NULL) {
 		RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
-		for (i = 0; i < MAX_MEASURE_REQ_TAB_SIZE; i++)
-		{
+		for (i = 0; i < MAX_MEASURE_REQ_TAB_SIZE; i++) {
 			NdisGetSystemUpTime(&Now);
 			pEntry = &pTab->Content[i];
 
 			if ((pEntry->Valid == TRUE)
-				&& RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + MQ_REQ_AGE_OUT)))
+			    && RTMP_TIME_AFTER((unsigned long)Now,
+					       (unsigned long)(pEntry->
+							       lastTime +
+							       MQ_REQ_AGE_OUT)))
 			{
-				PMEASURE_REQ_ENTRY pPrevEntry = NULL;
-				ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
-				PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
+				struct rt_measure_req_entry *pPrevEntry = NULL;
+				unsigned long HashIdx =
+				    MQ_DIALOGTOKEN_HASH_INDEX(pEntry->
+							      DialogToken);
+				struct rt_measure_req_entry *pProbeEntry =
+				    pTab->Hash[HashIdx];
 
-				// update Hash list
-				do
-				{
-					if (pProbeEntry == pEntry)
-					{
-						if (pPrevEntry == NULL)
-						{
-							pTab->Hash[HashIdx] = pEntry->pNext;
-						}
-						else
-						{
-							pPrevEntry->pNext = pEntry->pNext;
+				/* update Hash list */
+				do {
+					if (pProbeEntry == pEntry) {
+						if (pPrevEntry == NULL) {
+							pTab->Hash[HashIdx] =
+							    pEntry->pNext;
+						} else {
+							pPrevEntry->pNext =
+							    pEntry->pNext;
 						}
 						break;
 					}
@@ -154,7 +506,8 @@
 					pProbeEntry = pProbeEntry->pNext;
 				} while (pProbeEntry);
 
-				NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY));
+				NdisZeroMemory(pEntry,
+					       sizeof(struct rt_measure_req_entry));
 				pTab->Size--;
 
 				break;
@@ -164,30 +517,24 @@
 				break;
 		}
 
-		if (i < MAX_MEASURE_REQ_TAB_SIZE)
-		{
+		if (i < MAX_MEASURE_REQ_TAB_SIZE) {
 			NdisGetSystemUpTime(&Now);
 			pEntry->lastTime = Now;
 			pEntry->Valid = TRUE;
 			pEntry->DialogToken = DialogToken;
 			pTab->Size++;
-		}
-		else
-		{
+		} else {
 			pEntry = NULL;
-			DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab tab full.\n", __func__));
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("%s: pMeasureReqTab tab full.\n", __func__));
 		}
 
-		// add this Neighbor entry into HASH table
-		if (pEntry)
-		{
+		/* add this Neighbor entry into HASH table */
+		if (pEntry) {
 			HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
-			if (pTab->Hash[HashIdx] == NULL)
-			{
+			if (pTab->Hash[HashIdx] == NULL) {
 				pTab->Hash[HashIdx] = pEntry;
-			}
-			else
-			{
+			} else {
 				pCurrEntry = pTab->Hash[HashIdx];
 				while (pCurrEntry->pNext != NULL)
 					pCurrEntry = pCurrEntry->pNext;
@@ -201,45 +548,35 @@
 	return pEntry;
 }
 
-static VOID MeasureReqDelete(
-	IN PRTMP_ADAPTER	pAd,
-	IN UINT8			DialogToken)
+void MeasureReqDelete(struct rt_rtmp_adapter *pAd, u8 DialogToken)
 {
-	PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
-	PMEASURE_REQ_ENTRY pEntry = NULL;
+	struct rt_measure_req_tab *pTab = pAd->CommonCfg.pMeasureReqTab;
+	struct rt_measure_req_entry *pEntry = NULL;
 
-	if(pTab == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __func__));
+	if (pTab == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("%s: pMeasureReqTab doesn't exist.\n", __func__));
 		return;
 	}
-
-	// if empty, return
-	if (pTab->Size == 0)
-	{
+	/* if empty, return */
+	if (pTab->Size == 0) {
 		DBGPRINT(RT_DEBUG_ERROR, ("pMeasureReqTab empty.\n"));
 		return;
 	}
 
 	pEntry = MeasureReqLookUp(pAd, DialogToken);
-	if (pEntry != NULL)
-	{
-		PMEASURE_REQ_ENTRY pPrevEntry = NULL;
-		ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
-		PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
+	if (pEntry != NULL) {
+		struct rt_measure_req_entry *pPrevEntry = NULL;
+		unsigned long HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
+		struct rt_measure_req_entry *pProbeEntry = pTab->Hash[HashIdx];
 
 		RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
-		// update Hash list
-		do
-		{
-			if (pProbeEntry == pEntry)
-			{
-				if (pPrevEntry == NULL)
-				{
+		/* update Hash list */
+		do {
+			if (pProbeEntry == pEntry) {
+				if (pPrevEntry == NULL) {
 					pTab->Hash[HashIdx] = pEntry->pNext;
-				}
-				else
-				{
+				} else {
 					pPrevEntry->pNext = pEntry->pNext;
 				}
 				break;
@@ -249,7 +586,7 @@
 			pProbeEntry = pProbeEntry->pNext;
 		} while (pProbeEntry);
 
-		NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY));
+		NdisZeroMemory(pEntry, sizeof(struct rt_measure_req_entry));
 		pTab->Size--;
 
 		RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
@@ -258,24 +595,24 @@
 	return;
 }
 
-VOID TpcReqTabInit(
-	IN PRTMP_ADAPTER pAd)
+void TpcReqTabInit(struct rt_rtmp_adapter *pAd)
 {
 	NdisAllocateSpinLock(&pAd->CommonCfg.TpcReqTabLock);
 
-	pAd->CommonCfg.pTpcReqTab = kmalloc(sizeof(TPC_REQ_TAB), GFP_ATOMIC);
+	pAd->CommonCfg.pTpcReqTab = kmalloc(sizeof(struct rt_tpc_req_tab), GFP_ATOMIC);
 	if (pAd->CommonCfg.pTpcReqTab)
-		NdisZeroMemory(pAd->CommonCfg.pTpcReqTab, sizeof(TPC_REQ_TAB));
+		NdisZeroMemory(pAd->CommonCfg.pTpcReqTab, sizeof(struct rt_tpc_req_tab));
 	else
-		DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pTpcReqTab.\n", __func__));
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("%s Fail to alloc memory for pAd->CommonCfg.pTpcReqTab.\n",
+			  __func__));
 
 	return;
 }
 
-VOID TpcReqTabExit(
-	IN PRTMP_ADAPTER pAd)
+void TpcReqTabExit(struct rt_rtmp_adapter *pAd)
 {
-	NdisFreeSpinLock(pAd->CommonCfg.TpcReqTabLock);
+	NdisFreeSpinLock(&pAd->CommonCfg.TpcReqTabLock);
 
 	if (pAd->CommonCfg.pTpcReqTab)
 		kfree(pAd->CommonCfg.pTpcReqTab);
@@ -284,18 +621,16 @@
 	return;
 }
 
-static PTPC_REQ_ENTRY TpcReqLookUp(
-	IN PRTMP_ADAPTER	pAd,
-	IN UINT8			DialogToken)
+static struct rt_tpc_req_entry *TpcReqLookUp(struct rt_rtmp_adapter *pAd, u8 DialogToken)
 {
-	UINT HashIdx;
-	PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
-	PTPC_REQ_ENTRY pEntry = NULL;
-	PTPC_REQ_ENTRY pPrevEntry = NULL;
+	u32 HashIdx;
+	struct rt_tpc_req_tab *pTab = pAd->CommonCfg.pTpcReqTab;
+	struct rt_tpc_req_entry *pEntry = NULL;
+	struct rt_tpc_req_entry *pPrevEntry = NULL;
 
-	if (pTab == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __func__));
+	if (pTab == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("%s: pTpcReqTab doesn't exist.\n", __func__));
 		return NULL;
 	}
 
@@ -304,12 +639,10 @@
 	HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
 	pEntry = pTab->Hash[HashIdx];
 
-	while (pEntry)
-	{
+	while (pEntry) {
 		if (pEntry->DialogToken == DialogToken)
 			break;
-		else
-		{
+		else {
 			pPrevEntry = pEntry;
 			pEntry = pEntry->pNext;
 		}
@@ -320,51 +653,49 @@
 	return pEntry;
 }
 
-
-static PTPC_REQ_ENTRY TpcReqInsert(
-	IN PRTMP_ADAPTER	pAd,
-	IN UINT8			DialogToken)
+static struct rt_tpc_req_entry *TpcReqInsert(struct rt_rtmp_adapter *pAd, u8 DialogToken)
 {
-	INT i;
-	ULONG HashIdx;
-	PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
-	PTPC_REQ_ENTRY pEntry = NULL, pCurrEntry;
-	ULONG Now;
+	int i;
+	unsigned long HashIdx;
+	struct rt_tpc_req_tab *pTab = pAd->CommonCfg.pTpcReqTab;
+	struct rt_tpc_req_entry *pEntry = NULL, *pCurrEntry;
+	unsigned long Now;
 
-	if(pTab == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __func__));
+	if (pTab == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("%s: pTpcReqTab doesn't exist.\n", __func__));
 		return NULL;
 	}
 
 	pEntry = TpcReqLookUp(pAd, DialogToken);
-	if (pEntry == NULL)
-	{
+	if (pEntry == NULL) {
 		RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
-		for (i = 0; i < MAX_TPC_REQ_TAB_SIZE; i++)
-		{
+		for (i = 0; i < MAX_TPC_REQ_TAB_SIZE; i++) {
 			NdisGetSystemUpTime(&Now);
 			pEntry = &pTab->Content[i];
 
 			if ((pEntry->Valid == TRUE)
-				&& RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + TPC_REQ_AGE_OUT)))
+			    && RTMP_TIME_AFTER((unsigned long)Now,
+					       (unsigned long)(pEntry->
+							       lastTime +
+							       TPC_REQ_AGE_OUT)))
 			{
-				PTPC_REQ_ENTRY pPrevEntry = NULL;
-				ULONG HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
-				PTPC_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
+				struct rt_tpc_req_entry *pPrevEntry = NULL;
+				unsigned long HashIdx =
+				    TPC_DIALOGTOKEN_HASH_INDEX(pEntry->
+							       DialogToken);
+				struct rt_tpc_req_entry *pProbeEntry =
+				    pTab->Hash[HashIdx];
 
-				// update Hash list
-				do
-				{
-					if (pProbeEntry == pEntry)
-					{
-						if (pPrevEntry == NULL)
-						{
-							pTab->Hash[HashIdx] = pEntry->pNext;
-						}
-						else
-						{
-							pPrevEntry->pNext = pEntry->pNext;
+				/* update Hash list */
+				do {
+					if (pProbeEntry == pEntry) {
+						if (pPrevEntry == NULL) {
+							pTab->Hash[HashIdx] =
+							    pEntry->pNext;
+						} else {
+							pPrevEntry->pNext =
+							    pEntry->pNext;
 						}
 						break;
 					}
@@ -373,7 +704,7 @@
 					pProbeEntry = pProbeEntry->pNext;
 				} while (pProbeEntry);
 
-				NdisZeroMemory(pEntry, sizeof(TPC_REQ_ENTRY));
+				NdisZeroMemory(pEntry, sizeof(struct rt_tpc_req_entry));
 				pTab->Size--;
 
 				break;
@@ -383,30 +714,24 @@
 				break;
 		}
 
-		if (i < MAX_TPC_REQ_TAB_SIZE)
-		{
+		if (i < MAX_TPC_REQ_TAB_SIZE) {
 			NdisGetSystemUpTime(&Now);
 			pEntry->lastTime = Now;
 			pEntry->Valid = TRUE;
 			pEntry->DialogToken = DialogToken;
 			pTab->Size++;
-		}
-		else
-		{
+		} else {
 			pEntry = NULL;
-			DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab tab full.\n", __func__));
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("%s: pTpcReqTab tab full.\n", __func__));
 		}
 
-		// add this Neighbor entry into HASH table
-		if (pEntry)
-		{
+		/* add this Neighbor entry into HASH table */
+		if (pEntry) {
 			HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
-			if (pTab->Hash[HashIdx] == NULL)
-			{
+			if (pTab->Hash[HashIdx] == NULL) {
 				pTab->Hash[HashIdx] = pEntry;
-			}
-			else
-			{
+			} else {
 				pCurrEntry = pTab->Hash[HashIdx];
 				while (pCurrEntry->pNext != NULL)
 					pCurrEntry = pCurrEntry->pNext;
@@ -420,45 +745,35 @@
 	return pEntry;
 }
 
-static VOID TpcReqDelete(
-	IN PRTMP_ADAPTER	pAd,
-	IN UINT8			DialogToken)
+static void TpcReqDelete(struct rt_rtmp_adapter *pAd, u8 DialogToken)
 {
-	PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
-	PTPC_REQ_ENTRY pEntry = NULL;
+	struct rt_tpc_req_tab *pTab = pAd->CommonCfg.pTpcReqTab;
+	struct rt_tpc_req_entry *pEntry = NULL;
 
-	if(pTab == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __func__));
+	if (pTab == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("%s: pTpcReqTab doesn't exist.\n", __func__));
 		return;
 	}
-
-	// if empty, return
-	if (pTab->Size == 0)
-	{
+	/* if empty, return */
+	if (pTab->Size == 0) {
 		DBGPRINT(RT_DEBUG_ERROR, ("pTpcReqTab empty.\n"));
 		return;
 	}
 
 	pEntry = TpcReqLookUp(pAd, DialogToken);
-	if (pEntry != NULL)
-	{
-		PTPC_REQ_ENTRY pPrevEntry = NULL;
-		ULONG HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
-		PTPC_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
+	if (pEntry != NULL) {
+		struct rt_tpc_req_entry *pPrevEntry = NULL;
+		unsigned long HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
+		struct rt_tpc_req_entry *pProbeEntry = pTab->Hash[HashIdx];
 
 		RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
-		// update Hash list
-		do
-		{
-			if (pProbeEntry == pEntry)
-			{
-				if (pPrevEntry == NULL)
-				{
+		/* update Hash list */
+		do {
+			if (pProbeEntry == pEntry) {
+				if (pPrevEntry == NULL) {
 					pTab->Hash[HashIdx] = pEntry->pNext;
-				}
-				else
-				{
+				} else {
 					pPrevEntry->pNext = pEntry->pNext;
 				}
 				break;
@@ -468,7 +783,7 @@
 			pProbeEntry = pProbeEntry->pNext;
 		} while (pProbeEntry);
 
-		NdisZeroMemory(pEntry, sizeof(TPC_REQ_ENTRY));
+		NdisZeroMemory(pEntry, sizeof(struct rt_tpc_req_entry));
 		pTab->Size--;
 
 		RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
@@ -487,10 +802,9 @@
 	Return	: Current Time Stamp.
 	==========================================================================
  */
-static UINT64 GetCurrentTimeStamp(
-	IN PRTMP_ADAPTER pAd)
+static u64 GetCurrentTimeStamp(struct rt_rtmp_adapter *pAd)
 {
-	// get current time stamp.
+	/* get current time stamp. */
 	return 0;
 }
 
@@ -504,11 +818,73 @@
 	Return	: Current Time Stamp.
 	==========================================================================
  */
-static UINT8 GetCurTxPwr(
-	IN PRTMP_ADAPTER pAd,
-	IN UINT8 Wcid)
+static u8 GetCurTxPwr(struct rt_rtmp_adapter *pAd, u8 Wcid)
 {
-	return 16; /* 16 dBm */
+	return 16;		/* 16 dBm */
+}
+
+/*
+	==========================================================================
+	Description:
+		Get Current Transmit Power.
+
+	Parametrs:
+
+	Return	: Current Time Stamp.
+	==========================================================================
+ */
+void InsertChannelRepIE(struct rt_rtmp_adapter *pAd,
+			u8 *pFrameBuf,
+			unsigned long *pFrameLen,
+			char *pCountry, u8 RegulatoryClass)
+{
+	unsigned long TempLen;
+	u8 Len;
+	u8 IEId = IE_AP_CHANNEL_REPORT;
+	u8 *pChListPtr = NULL;
+
+	Len = 1;
+	if (strncmp(pCountry, "US", 2) == 0) {
+		if (RegulatoryClass >= USA_REGULATORY_INFO_SIZE) {
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("%s: USA Unknow Requlatory class (%d)\n",
+				  __func__, RegulatoryClass));
+			return;
+		}
+
+		Len +=
+		    USARegulatoryInfo[RegulatoryClass].ChannelSet.
+		    NumberOfChannels;
+		pChListPtr =
+		    USARegulatoryInfo[RegulatoryClass].ChannelSet.ChannelList;
+	} else if (strncmp(pCountry, "JP", 2) == 0) {
+		if (RegulatoryClass >= JP_REGULATORY_INFO_SIZE) {
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("%s: JP Unknow Requlatory class (%d)\n",
+				  __func__, RegulatoryClass));
+			return;
+		}
+
+		Len +=
+		    JapanRegulatoryInfo[RegulatoryClass].ChannelSet.
+		    NumberOfChannels;
+		pChListPtr =
+		    JapanRegulatoryInfo[RegulatoryClass].ChannelSet.ChannelList;
+	} else {
+		DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknow Country (%s)\n",
+					  __func__, pCountry));
+		return;
+	}
+
+	MakeOutgoingFrame(pFrameBuf, &TempLen,
+			  1, &IEId,
+			  1, &Len,
+			  1, &RegulatoryClass,
+			  Len - 1, pChListPtr, END_OF_ARGS);
+
+	*pFrameLen = *pFrameLen + TempLen;
+
+	return;
 }
 
 /*
@@ -524,16 +900,12 @@
 	Return	: None.
 	==========================================================================
  */
-static VOID InsertDialogToken(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pFrameBuf,
-	OUT PULONG pFrameLen,
-	IN UINT8 DialogToken)
+void InsertDialogToken(struct rt_rtmp_adapter *pAd,
+		       u8 *pFrameBuf,
+		       unsigned long *pFrameLen, u8 DialogToken)
 {
-	ULONG TempLen;
-	MakeOutgoingFrame(pFrameBuf,	&TempLen,
-					1,				&DialogToken,
-					END_OF_ARGS);
+	unsigned long TempLen;
+	MakeOutgoingFrame(pFrameBuf, &TempLen, 1, &DialogToken, END_OF_ARGS);
 
 	*pFrameLen = *pFrameLen + TempLen;
 
@@ -552,19 +924,15 @@
 	Return	: None.
 	==========================================================================
  */
- static VOID InsertTpcReqIE(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pFrameBuf,
-	OUT PULONG pFrameLen)
+static void InsertTpcReqIE(struct rt_rtmp_adapter *pAd,
+			   u8 *pFrameBuf, unsigned long *pFrameLen)
 {
-	ULONG TempLen;
-	ULONG Len = 0;
-	UINT8 ElementID = IE_TPC_REQUEST;
+	unsigned long TempLen;
+	unsigned long Len = 0;
+	u8 ElementID = IE_TPC_REQUEST;
 
-	MakeOutgoingFrame(pFrameBuf,					&TempLen,
-						1,							&ElementID,
-						1,							&Len,
-						END_OF_ARGS);
+	MakeOutgoingFrame(pFrameBuf, &TempLen,
+			  1, &ElementID, 1, &Len, END_OF_ARGS);
 
 	*pFrameLen = *pFrameLen + TempLen;
 
@@ -585,30 +953,25 @@
 	Return	: None.
 	==========================================================================
  */
- static VOID InsertTpcReportIE(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pFrameBuf,
-	OUT PULONG pFrameLen,
-	IN UINT8 TxPwr,
-	IN UINT8 LinkMargin)
+void InsertTpcReportIE(struct rt_rtmp_adapter *pAd,
+		       u8 *pFrameBuf,
+		       unsigned long *pFrameLen,
+		       u8 TxPwr, u8 LinkMargin)
 {
-	ULONG TempLen;
-	ULONG Len = sizeof(TPC_REPORT_INFO);
-	UINT8 ElementID = IE_TPC_REPORT;
-	TPC_REPORT_INFO TpcReportIE;
+	unsigned long TempLen;
+	unsigned long Len = sizeof(struct rt_tpc_report_info);
+	u8 ElementID = IE_TPC_REPORT;
+	struct rt_tpc_report_info TpcReportIE;
 
 	TpcReportIE.TxPwr = TxPwr;
 	TpcReportIE.LinkMargin = LinkMargin;
 
-	MakeOutgoingFrame(pFrameBuf,					&TempLen,
-						1,							&ElementID,
-						1,							&Len,
-						Len,						&TpcReportIE,
-						END_OF_ARGS);
+	MakeOutgoingFrame(pFrameBuf, &TempLen,
+			  1, &ElementID,
+			  1, &Len, Len, &TpcReportIE, END_OF_ARGS);
 
 	*pFrameLen = *pFrameLen + TempLen;
 
-
 	return;
 }
 
@@ -627,32 +990,26 @@
 	Return	: None.
 	==========================================================================
  */
-static VOID InsertChSwAnnIE(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pFrameBuf,
-	OUT PULONG pFrameLen,
-	IN UINT8 ChSwMode,
-	IN UINT8 NewChannel,
-	IN UINT8 ChSwCnt)
+static void InsertChSwAnnIE(struct rt_rtmp_adapter *pAd,
+			    u8 *pFrameBuf,
+			    unsigned long *pFrameLen,
+			    u8 ChSwMode,
+			    u8 NewChannel, u8 ChSwCnt)
 {
-	ULONG TempLen;
-	ULONG Len = sizeof(CH_SW_ANN_INFO);
-	UINT8 ElementID = IE_CHANNEL_SWITCH_ANNOUNCEMENT;
-	CH_SW_ANN_INFO ChSwAnnIE;
+	unsigned long TempLen;
+	unsigned long Len = sizeof(struct rt_ch_sw_ann_info);
+	u8 ElementID = IE_CHANNEL_SWITCH_ANNOUNCEMENT;
+	struct rt_ch_sw_ann_info ChSwAnnIE;
 
 	ChSwAnnIE.ChSwMode = ChSwMode;
 	ChSwAnnIE.Channel = NewChannel;
 	ChSwAnnIE.ChSwCnt = ChSwCnt;
 
-	MakeOutgoingFrame(pFrameBuf,				&TempLen,
-						1,						&ElementID,
-						1,						&Len,
-						Len,					&ChSwAnnIE,
-						END_OF_ARGS);
+	MakeOutgoingFrame(pFrameBuf, &TempLen,
+			  1, &ElementID, 1, &Len, Len, &ChSwAnnIE, END_OF_ARGS);
 
 	*pFrameLen = *pFrameLen + TempLen;
 
-
 	return;
 }
 
@@ -671,25 +1028,21 @@
 		7. Measure Start time.
 		8. Measure Duration.
 
-
 	Return	: None.
 	==========================================================================
  */
-static VOID InsertMeasureReqIE(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pFrameBuf,
-	OUT PULONG pFrameLen,
-	IN PMEASURE_REQ_INFO pMeasureReqIE)
+static void InsertMeasureReqIE(struct rt_rtmp_adapter *pAd,
+			       u8 *pFrameBuf,
+			       unsigned long *pFrameLen,
+			       u8 Len, struct rt_measure_req_info * pMeasureReqIE)
 {
-	ULONG TempLen;
-	UINT8 Len = sizeof(MEASURE_REQ_INFO);
-	UINT8 ElementID = IE_MEASUREMENT_REQUEST;
+	unsigned long TempLen;
+	u8 ElementID = IE_MEASUREMENT_REQUEST;
 
-	MakeOutgoingFrame(pFrameBuf,					&TempLen,
-						1,							&ElementID,
-						1,							&Len,
-						Len,						pMeasureReqIE,
-						END_OF_ARGS);
+	MakeOutgoingFrame(pFrameBuf, &TempLen,
+			  1, &ElementID,
+			  1, &Len,
+			  sizeof(struct rt_measure_req_info), pMeasureReqIE, END_OF_ARGS);
 
 	*pFrameLen = *pFrameLen + TempLen;
 
@@ -713,33 +1066,27 @@
 	Return	: None.
 	==========================================================================
  */
-static VOID InsertMeasureReportIE(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pFrameBuf,
-	OUT PULONG pFrameLen,
-	IN PMEASURE_REPORT_INFO pMeasureReportIE,
-	IN UINT8 ReportLnfoLen,
-	IN PUINT8 pReportInfo)
+static void InsertMeasureReportIE(struct rt_rtmp_adapter *pAd,
+				  u8 *pFrameBuf,
+				  unsigned long *pFrameLen,
+				  struct rt_measure_report_info * pMeasureReportIE,
+				  u8 ReportLnfoLen, u8 *pReportInfo)
 {
-	ULONG TempLen;
-	ULONG Len;
-	UINT8 ElementID = IE_MEASUREMENT_REPORT;
+	unsigned long TempLen;
+	unsigned long Len;
+	u8 ElementID = IE_MEASUREMENT_REPORT;
 
-	Len = sizeof(MEASURE_REPORT_INFO) + ReportLnfoLen;
+	Len = sizeof(struct rt_measure_report_info) + ReportLnfoLen;
 
-	MakeOutgoingFrame(pFrameBuf,					&TempLen,
-						1,							&ElementID,
-						1,							&Len,
-						Len,						pMeasureReportIE,
-						END_OF_ARGS);
+	MakeOutgoingFrame(pFrameBuf, &TempLen,
+			  1, &ElementID,
+			  1, &Len, Len, pMeasureReportIE, END_OF_ARGS);
 
 	*pFrameLen = *pFrameLen + TempLen;
 
-	if ((ReportLnfoLen > 0) && (pReportInfo != NULL))
-	{
-		MakeOutgoingFrame(pFrameBuf + *pFrameLen,		&TempLen,
-							ReportLnfoLen,				pReportInfo,
-							END_OF_ARGS);
+	if ((ReportLnfoLen > 0) && (pReportInfo != NULL)) {
+		MakeOutgoingFrame(pFrameBuf + *pFrameLen, &TempLen,
+				  ReportLnfoLen, pReportInfo, END_OF_ARGS);
 
 		*pFrameLen = *pFrameLen + TempLen;
 	}
@@ -758,53 +1105,40 @@
 	Return	: None.
 	==========================================================================
  */
-VOID EnqueueMeasurementReq(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDA,
-	IN UINT8 MeasureToken,
-	IN UINT8 MeasureReqMode,
-	IN UINT8 MeasureReqType,
-	IN UINT8 MeasureCh,
-	IN UINT16 MeasureDuration)
+void MakeMeasurementReqFrame(struct rt_rtmp_adapter *pAd,
+			     u8 *pOutBuffer,
+			     unsigned long *pFrameLen,
+			     u8 TotalLen,
+			     u8 Category,
+			     u8 Action,
+			     u8 MeasureToken,
+			     u8 MeasureReqMode,
+			     u8 MeasureReqType, u8 NumOfRepetitions)
 {
-	PUCHAR pOutBuffer = NULL;
-	NDIS_STATUS NStatus;
-	ULONG FrameLen;
-	HEADER_802_11 ActHdr;
-	MEASURE_REQ_INFO MeasureReqIE;
-	UINT8 RmReqDailogToken = RandomByte(pAd);
-	UINT64 MeasureStartTime = GetCurrentTimeStamp(pAd);
+	unsigned long TempLen;
+	struct rt_measure_req_info MeasureReqIE;
 
-	// build action frame header.
-	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
-						pAd->CurrentAddress);
+	InsertActField(pAd, (pOutBuffer + *pFrameLen), pFrameLen, Category,
+		       Action);
 
-	NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
-	if(NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__));
-		return;
+	/* fill Dialog Token */
+	InsertDialogToken(pAd, (pOutBuffer + *pFrameLen), pFrameLen,
+			  MeasureToken);
+
+	/* fill Number of repetitions. */
+	if (Category == CATEGORY_RM) {
+		MakeOutgoingFrame((pOutBuffer + *pFrameLen), &TempLen,
+				  2, &NumOfRepetitions, END_OF_ARGS);
+
+		*pFrameLen += TempLen;
 	}
-	NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
-	FrameLen = sizeof(HEADER_802_11);
-
-	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_MRQ);
-
-	// fill Dialog Token
-	InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, MeasureToken);
-
-	// prepare Measurement IE.
-	NdisZeroMemory(&MeasureReqIE, sizeof(MEASURE_REQ_INFO));
-	MeasureReqIE.Token = RmReqDailogToken;
+	/* prepare Measurement IE. */
+	NdisZeroMemory(&MeasureReqIE, sizeof(struct rt_measure_req_info));
+	MeasureReqIE.Token = MeasureToken;
 	MeasureReqIE.ReqMode.word = MeasureReqMode;
 	MeasureReqIE.ReqType = MeasureReqType;
-	MeasureReqIE.MeasureReq.ChNum = MeasureCh;
-	MeasureReqIE.MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime);
-	MeasureReqIE.MeasureReq.MeasureDuration = cpu2le16(MeasureDuration);
-	InsertMeasureReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureReqIE);
-
-	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
+	InsertMeasureReqIE(pAd, (pOutBuffer + *pFrameLen), pFrameLen,
+			   TotalLen, &MeasureReqIE);
 
 	return;
 }
@@ -821,46 +1155,46 @@
 	Return	: None.
 	==========================================================================
  */
-VOID EnqueueMeasurementRep(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDA,
-	IN UINT8 DialogToken,
-	IN UINT8 MeasureToken,
-	IN UINT8 MeasureReqMode,
-	IN UINT8 MeasureReqType,
-	IN UINT8 ReportInfoLen,
-	IN PUINT8 pReportInfo)
+void EnqueueMeasurementRep(struct rt_rtmp_adapter *pAd,
+			   u8 *pDA,
+			   u8 DialogToken,
+			   u8 MeasureToken,
+			   u8 MeasureReqMode,
+			   u8 MeasureReqType,
+			   u8 ReportInfoLen, u8 *pReportInfo)
 {
-	PUCHAR pOutBuffer = NULL;
-	NDIS_STATUS NStatus;
-	ULONG FrameLen;
-	HEADER_802_11 ActHdr;
-	MEASURE_REPORT_INFO MeasureRepIE;
+	u8 *pOutBuffer = NULL;
+	int NStatus;
+	unsigned long FrameLen;
+	struct rt_header_802_11 ActHdr;
+	struct rt_measure_report_info MeasureRepIE;
 
-	// build action frame header.
+	/* build action frame header. */
 	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
-						pAd->CurrentAddress);
+			 pAd->CurrentAddress);
 
-	NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
-	if(NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__));
+	NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer);	/*Get an unused nonpaged memory */
+	if (NStatus != NDIS_STATUS_SUCCESS) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("%s() allocate memory failed \n", __func__));
 		return;
 	}
-	NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
-	FrameLen = sizeof(HEADER_802_11);
+	NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
+	FrameLen = sizeof(struct rt_header_802_11);
 
-	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_MRP);
+	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen,
+		       CATEGORY_SPECTRUM, SPEC_MRP);
 
-	// fill Dialog Token
+	/* fill Dialog Token */
 	InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
 
-	// prepare Measurement IE.
-	NdisZeroMemory(&MeasureRepIE, sizeof(MEASURE_REPORT_INFO));
+	/* prepare Measurement IE. */
+	NdisZeroMemory(&MeasureRepIE, sizeof(struct rt_measure_report_info));
 	MeasureRepIE.Token = MeasureToken;
-	MeasureRepIE.ReportMode.word = MeasureReqMode;
+	MeasureRepIE.ReportMode = MeasureReqMode;
 	MeasureRepIE.ReportType = MeasureReqType;
-	InsertMeasureReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureRepIE, ReportInfoLen, pReportInfo);
+	InsertMeasureReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen,
+			      &MeasureRepIE, ReportInfoLen, pReportInfo);
 
 	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
 	MlmeFreeMemory(pAd, pOutBuffer);
@@ -880,36 +1214,34 @@
 	Return	: None.
 	==========================================================================
  */
-VOID EnqueueTPCReq(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDA,
-	IN UCHAR DialogToken)
+void EnqueueTPCReq(struct rt_rtmp_adapter *pAd, u8 *pDA, u8 DialogToken)
 {
-	PUCHAR pOutBuffer = NULL;
-	NDIS_STATUS NStatus;
-	ULONG FrameLen;
+	u8 *pOutBuffer = NULL;
+	int NStatus;
+	unsigned long FrameLen;
 
-	HEADER_802_11 ActHdr;
+	struct rt_header_802_11 ActHdr;
 
-	// build action frame header.
+	/* build action frame header. */
 	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
-						pAd->CurrentAddress);
+			 pAd->CurrentAddress);
 
-	NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
-	if(NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__));
+	NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer);	/*Get an unused nonpaged memory */
+	if (NStatus != NDIS_STATUS_SUCCESS) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("%s() allocate memory failed \n", __func__));
 		return;
 	}
-	NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
-	FrameLen = sizeof(HEADER_802_11);
+	NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
+	FrameLen = sizeof(struct rt_header_802_11);
 
-	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_TPCRQ);
+	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen,
+		       CATEGORY_SPECTRUM, SPEC_TPCRQ);
 
-	// fill Dialog Token
+	/* fill Dialog Token */
 	InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
 
-	// Insert TPC Request IE.
+	/* Insert TPC Request IE. */
 	InsertTpcReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen);
 
 	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
@@ -930,39 +1262,38 @@
 	Return	: None.
 	==========================================================================
  */
-VOID EnqueueTPCRep(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDA,
-	IN UINT8 DialogToken,
-	IN UINT8 TxPwr,
-	IN UINT8 LinkMargin)
+void EnqueueTPCRep(struct rt_rtmp_adapter *pAd,
+		   u8 *pDA,
+		   u8 DialogToken, u8 TxPwr, u8 LinkMargin)
 {
-	PUCHAR pOutBuffer = NULL;
-	NDIS_STATUS NStatus;
-	ULONG FrameLen;
+	u8 *pOutBuffer = NULL;
+	int NStatus;
+	unsigned long FrameLen;
 
-	HEADER_802_11 ActHdr;
+	struct rt_header_802_11 ActHdr;
 
-	// build action frame header.
+	/* build action frame header. */
 	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
-						pAd->CurrentAddress);
+			 pAd->CurrentAddress);
 
-	NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
-	if(NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__));
+	NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer);	/*Get an unused nonpaged memory */
+	if (NStatus != NDIS_STATUS_SUCCESS) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("%s() allocate memory failed \n", __func__));
 		return;
 	}
-	NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
-	FrameLen = sizeof(HEADER_802_11);
+	NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
+	FrameLen = sizeof(struct rt_header_802_11);
 
-	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_TPCRP);
+	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen,
+		       CATEGORY_SPECTRUM, SPEC_TPCRP);
 
-	// fill Dialog Token
+	/* fill Dialog Token */
 	InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
 
-	// Insert TPC Request IE.
-	InsertTpcReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, TxPwr, LinkMargin);
+	/* Insert TPC Request IE. */
+	InsertTpcReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, TxPwr,
+			  LinkMargin);
 
 	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
 	MlmeFreeMemory(pAd, pOutBuffer);
@@ -984,34 +1315,33 @@
 	Return	: None.
 	==========================================================================
  */
-VOID EnqueueChSwAnn(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDA,
-	IN UINT8 ChSwMode,
-	IN UINT8 NewCh)
+void EnqueueChSwAnn(struct rt_rtmp_adapter *pAd,
+		    u8 *pDA, u8 ChSwMode, u8 NewCh)
 {
-	PUCHAR pOutBuffer = NULL;
-	NDIS_STATUS NStatus;
-	ULONG FrameLen;
+	u8 *pOutBuffer = NULL;
+	int NStatus;
+	unsigned long FrameLen;
 
-	HEADER_802_11 ActHdr;
+	struct rt_header_802_11 ActHdr;
 
-	// build action frame header.
+	/* build action frame header. */
 	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
-						pAd->CurrentAddress);
+			 pAd->CurrentAddress);
 
-	NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
-	if(NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__));
+	NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer);	/*Get an unused nonpaged memory */
+	if (NStatus != NDIS_STATUS_SUCCESS) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("%s() allocate memory failed \n", __func__));
 		return;
 	}
-	NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
-	FrameLen = sizeof(HEADER_802_11);
+	NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
+	FrameLen = sizeof(struct rt_header_802_11);
 
-	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_CHANNEL_SWITCH);
+	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen,
+		       CATEGORY_SPECTRUM, SPEC_CHANNEL_SWITCH);
 
-	InsertChSwAnnIE(pAd, (pOutBuffer + FrameLen), &FrameLen, ChSwMode, NewCh, 0);
+	InsertChSwAnnIE(pAd, (pOutBuffer + FrameLen), &FrameLen, ChSwMode,
+			NewCh, 0);
 
 	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
 	MlmeFreeMemory(pAd, pOutBuffer);
@@ -1019,55 +1349,43 @@
 	return;
 }
 
-static BOOLEAN DfsRequirementCheck(
-	IN PRTMP_ADAPTER pAd,
-	IN UINT8 Channel)
+static BOOLEAN DfsRequirementCheck(struct rt_rtmp_adapter *pAd, u8 Channel)
 {
 	BOOLEAN Result = FALSE;
-	INT i;
+	int i;
 
-	do
-	{
-		// check DFS procedure is running.
-		// make sure DFS procedure won't start twice.
-		if (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
-		{
+	do {
+		/* check DFS procedure is running. */
+		/* make sure DFS procedure won't start twice. */
+		if (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE) {
 			Result = FALSE;
 			break;
 		}
-
-		// check the new channel carried from Channel Switch Announcemnet is valid.
-		for (i=0; i<pAd->ChannelListNum; i++)
-		{
+		/* check the new channel carried from Channel Switch Announcemnet is valid. */
+		for (i = 0; i < pAd->ChannelListNum; i++) {
 			if ((Channel == pAd->ChannelList[i].Channel)
-				&&(pAd->ChannelList[i].RemainingTimeForUse == 0))
-			{
-				// found radar signal in the channel. the channel can't use at least for 30 minutes.
-				pAd->ChannelList[i].RemainingTimeForUse = 1800;//30 min = 1800 sec
+			    && (pAd->ChannelList[i].RemainingTimeForUse == 0)) {
+				/* found radar signal in the channel. the channel can't use at least for 30 minutes. */
+				pAd->ChannelList[i].RemainingTimeForUse = 1800;	/*30 min = 1800 sec */
 				Result = TRUE;
 				break;
 			}
 		}
-	} while(FALSE);
+	} while (FALSE);
 
 	return Result;
 }
 
-VOID NotifyChSwAnnToPeerAPs(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pRA,
-	IN PUCHAR pTA,
-	IN UINT8 ChSwMode,
-	IN UINT8 Channel)
+void NotifyChSwAnnToPeerAPs(struct rt_rtmp_adapter *pAd,
+			    u8 *pRA,
+			    u8 *pTA, u8 ChSwMode, u8 Channel)
 {
 }
 
-static VOID StartDFSProcedure(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR Channel,
-	IN UINT8 ChSwMode)
+static void StartDFSProcedure(struct rt_rtmp_adapter *pAd,
+			      u8 Channel, u8 ChSwMode)
 {
-	// start DFS procedure
+	/* start DFS procedure */
 	pAd->CommonCfg.Channel = Channel;
 
 	N_ChannelCheck(pAd);
@@ -1086,7 +1404,6 @@
 		2. message length.
 		3. Channel switch announcement infomation buffer.
 
-
 	Return	: None.
 	==========================================================================
  */
@@ -1098,44 +1415,45 @@
   +----+-----+-----------+------------+-----------+
     1    1        1           1            1
 */
-static BOOLEAN PeerChSwAnnSanity(
-	IN PRTMP_ADAPTER pAd,
-	IN VOID *pMsg,
-	IN ULONG MsgLen,
-	OUT PCH_SW_ANN_INFO pChSwAnnInfo)
+static BOOLEAN PeerChSwAnnSanity(struct rt_rtmp_adapter *pAd,
+				 void * pMsg,
+				 unsigned long MsgLen,
+				 struct rt_ch_sw_ann_info * pChSwAnnInfo)
 {
-	PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
-	PUCHAR pFramePtr = Fr->Octet;
+	struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
+	u8 *pFramePtr = Fr->Octet;
 	BOOLEAN result = FALSE;
-	PEID_STRUCT eid_ptr;
+	struct rt_eid * eid_ptr;
 
-	// skip 802.11 header.
-	MsgLen -= sizeof(HEADER_802_11);
+	/* skip 802.11 header. */
+	MsgLen -= sizeof(struct rt_header_802_11);
 
-	// skip category and action code.
+	/* skip category and action code. */
 	pFramePtr += 2;
 	MsgLen -= 2;
 
 	if (pChSwAnnInfo == NULL)
 		return result;
 
-	eid_ptr = (PEID_STRUCT)pFramePtr;
-	while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
-	{
-		switch(eid_ptr->Eid)
-		{
-			case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
-				NdisMoveMemory(&pChSwAnnInfo->ChSwMode, eid_ptr->Octet, 1);
-				NdisMoveMemory(&pChSwAnnInfo->Channel, eid_ptr->Octet + 1, 1);
-				NdisMoveMemory(&pChSwAnnInfo->ChSwCnt, eid_ptr->Octet + 2, 1);
+	eid_ptr = (struct rt_eid *) pFramePtr;
+	while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
+	       ((u8 *)pFramePtr + MsgLen)) {
+		switch (eid_ptr->Eid) {
+		case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
+			NdisMoveMemory(&pChSwAnnInfo->ChSwMode, eid_ptr->Octet,
+				       1);
+			NdisMoveMemory(&pChSwAnnInfo->Channel,
+				       eid_ptr->Octet + 1, 1);
+			NdisMoveMemory(&pChSwAnnInfo->ChSwCnt,
+				       eid_ptr->Octet + 2, 1);
 
-				result = TRUE;
-                break;
+			result = TRUE;
+			break;
 
-			default:
-				break;
+		default:
+			break;
 		}
-		eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+		eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
 	}
 
 	return result;
@@ -1154,25 +1472,25 @@
 	Return	: None.
 	==========================================================================
  */
-static BOOLEAN PeerMeasureReqSanity(
-	IN PRTMP_ADAPTER pAd,
-	IN VOID *pMsg,
-	IN ULONG MsgLen,
-	OUT PUINT8 pDialogToken,
-	OUT PMEASURE_REQ_INFO pMeasureReqInfo)
+static BOOLEAN PeerMeasureReqSanity(struct rt_rtmp_adapter *pAd,
+				    void * pMsg,
+				    unsigned long MsgLen,
+				    u8 *pDialogToken,
+				    struct rt_measure_req_info * pMeasureReqInfo,
+				    struct rt_measure_req * pMeasureReq)
 {
-	PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
-	PUCHAR pFramePtr = Fr->Octet;
+	struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
+	u8 *pFramePtr = Fr->Octet;
 	BOOLEAN result = FALSE;
-	PEID_STRUCT eid_ptr;
-	PUCHAR ptr;
-	UINT64 MeasureStartTime;
-	UINT16 MeasureDuration;
+	struct rt_eid * eid_ptr;
+	u8 *ptr;
+	u64 MeasureStartTime;
+	u16 MeasureDuration;
 
-	// skip 802.11 header.
-	MsgLen -= sizeof(HEADER_802_11);
+	/* skip 802.11 header. */
+	MsgLen -= sizeof(struct rt_header_802_11);
 
-	// skip category and action code.
+	/* skip category and action code. */
 	pFramePtr += 2;
 	MsgLen -= 2;
 
@@ -1183,29 +1501,32 @@
 	pFramePtr += 1;
 	MsgLen -= 1;
 
-	eid_ptr = (PEID_STRUCT)pFramePtr;
-	while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
-	{
-		switch(eid_ptr->Eid)
-		{
-			case IE_MEASUREMENT_REQUEST:
-				NdisMoveMemory(&pMeasureReqInfo->Token, eid_ptr->Octet, 1);
-				NdisMoveMemory(&pMeasureReqInfo->ReqMode.word, eid_ptr->Octet + 1, 1);
-				NdisMoveMemory(&pMeasureReqInfo->ReqType, eid_ptr->Octet + 2, 1);
-				ptr = eid_ptr->Octet + 3;
-				NdisMoveMemory(&pMeasureReqInfo->MeasureReq.ChNum, ptr, 1);
-				NdisMoveMemory(&MeasureStartTime, ptr + 1, 8);
-				pMeasureReqInfo->MeasureReq.MeasureStartTime = SWAP64(MeasureStartTime);
-				NdisMoveMemory(&MeasureDuration, ptr + 9, 2);
-				pMeasureReqInfo->MeasureReq.MeasureDuration = SWAP16(MeasureDuration);
+	eid_ptr = (struct rt_eid *) pFramePtr;
+	while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
+	       ((u8 *)pFramePtr + MsgLen)) {
+		switch (eid_ptr->Eid) {
+		case IE_MEASUREMENT_REQUEST:
+			NdisMoveMemory(&pMeasureReqInfo->Token, eid_ptr->Octet,
+				       1);
+			NdisMoveMemory(&pMeasureReqInfo->ReqMode.word,
+				       eid_ptr->Octet + 1, 1);
+			NdisMoveMemory(&pMeasureReqInfo->ReqType,
+				       eid_ptr->Octet + 2, 1);
+			ptr = (u8 *)(eid_ptr->Octet + 3);
+			NdisMoveMemory(&pMeasureReq->ChNum, ptr, 1);
+			NdisMoveMemory(&MeasureStartTime, ptr + 1, 8);
+			pMeasureReq->MeasureStartTime =
+			    SWAP64(MeasureStartTime);
+			NdisMoveMemory(&MeasureDuration, ptr + 9, 2);
+			pMeasureReq->MeasureDuration = SWAP16(MeasureDuration);
 
-				result = TRUE;
-				break;
+			result = TRUE;
+			break;
 
-			default:
-				break;
+		default:
+			break;
 		}
-		eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+		eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
 	}
 
 	return result;
@@ -1245,24 +1566,24 @@
   +-----+---------------+---------------------+-------+------------+----------+
      0          1                  2              3         4          5-7
 */
-static BOOLEAN PeerMeasureReportSanity(
-	IN PRTMP_ADAPTER pAd,
-	IN VOID *pMsg,
-	IN ULONG MsgLen,
-	OUT PUINT8 pDialogToken,
-	OUT PMEASURE_REPORT_INFO pMeasureReportInfo,
-	OUT PUINT8 pReportBuf)
+static BOOLEAN PeerMeasureReportSanity(struct rt_rtmp_adapter *pAd,
+				       void * pMsg,
+				       unsigned long MsgLen,
+				       u8 *pDialogToken,
+				       struct rt_measure_report_info *
+				       pMeasureReportInfo,
+				       u8 *pReportBuf)
 {
-	PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
-	PUCHAR pFramePtr = Fr->Octet;
+	struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
+	u8 *pFramePtr = Fr->Octet;
 	BOOLEAN result = FALSE;
-	PEID_STRUCT eid_ptr;
-	PUCHAR ptr;
+	struct rt_eid * eid_ptr;
+	u8 *ptr;
 
-	// skip 802.11 header.
-	MsgLen -= sizeof(HEADER_802_11);
+	/* skip 802.11 header. */
+	MsgLen -= sizeof(struct rt_header_802_11);
 
-	// skip category and action code.
+	/* skip category and action code. */
 	pFramePtr += 2;
 	MsgLen -= 2;
 
@@ -1273,51 +1594,60 @@
 	pFramePtr += 1;
 	MsgLen -= 1;
 
-	eid_ptr = (PEID_STRUCT)pFramePtr;
-	while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
-	{
-		switch(eid_ptr->Eid)
-		{
-			case IE_MEASUREMENT_REPORT:
-				NdisMoveMemory(&pMeasureReportInfo->Token, eid_ptr->Octet, 1);
-				NdisMoveMemory(&pMeasureReportInfo->ReportMode, eid_ptr->Octet + 1, 1);
-				NdisMoveMemory(&pMeasureReportInfo->ReportType, eid_ptr->Octet + 2, 1);
-				if (pMeasureReportInfo->ReportType == RM_BASIC)
-				{
-					PMEASURE_BASIC_REPORT pReport = (PMEASURE_BASIC_REPORT)pReportBuf;
-					ptr = eid_ptr->Octet + 3;
-					NdisMoveMemory(&pReport->ChNum, ptr, 1);
-					NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
-					NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
-					NdisMoveMemory(&pReport->Map, ptr + 11, 1);
+	eid_ptr = (struct rt_eid *) pFramePtr;
+	while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
+	       ((u8 *)pFramePtr + MsgLen)) {
+		switch (eid_ptr->Eid) {
+		case IE_MEASUREMENT_REPORT:
+			NdisMoveMemory(&pMeasureReportInfo->Token,
+				       eid_ptr->Octet, 1);
+			NdisMoveMemory(&pMeasureReportInfo->ReportMode,
+				       eid_ptr->Octet + 1, 1);
+			NdisMoveMemory(&pMeasureReportInfo->ReportType,
+				       eid_ptr->Octet + 2, 1);
+			if (pMeasureReportInfo->ReportType == RM_BASIC) {
+				struct rt_measure_basic_report * pReport =
+				    (struct rt_measure_basic_report *) pReportBuf;
+				ptr = (u8 *)(eid_ptr->Octet + 3);
+				NdisMoveMemory(&pReport->ChNum, ptr, 1);
+				NdisMoveMemory(&pReport->MeasureStartTime,
+					       ptr + 1, 8);
+				NdisMoveMemory(&pReport->MeasureDuration,
+					       ptr + 9, 2);
+				NdisMoveMemory(&pReport->Map, ptr + 11, 1);
 
-				}
-				else if (pMeasureReportInfo->ReportType == RM_CCA)
-				{
-					PMEASURE_CCA_REPORT pReport = (PMEASURE_CCA_REPORT)pReportBuf;
-					ptr = eid_ptr->Octet + 3;
-					NdisMoveMemory(&pReport->ChNum, ptr, 1);
-					NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
-					NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
-					NdisMoveMemory(&pReport->CCA_Busy_Fraction, ptr + 11, 1);
+			} else if (pMeasureReportInfo->ReportType == RM_CCA) {
+				struct rt_measure_cca_report * pReport =
+				    (struct rt_measure_cca_report *) pReportBuf;
+				ptr = (u8 *)(eid_ptr->Octet + 3);
+				NdisMoveMemory(&pReport->ChNum, ptr, 1);
+				NdisMoveMemory(&pReport->MeasureStartTime,
+					       ptr + 1, 8);
+				NdisMoveMemory(&pReport->MeasureDuration,
+					       ptr + 9, 2);
+				NdisMoveMemory(&pReport->CCA_Busy_Fraction,
+					       ptr + 11, 1);
 
-				}
-				else if (pMeasureReportInfo->ReportType == RM_RPI_HISTOGRAM)
-				{
-					PMEASURE_RPI_REPORT pReport = (PMEASURE_RPI_REPORT)pReportBuf;
-					ptr = eid_ptr->Octet + 3;
-					NdisMoveMemory(&pReport->ChNum, ptr, 1);
-					NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
-					NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
-					NdisMoveMemory(&pReport->RPI_Density, ptr + 11, 8);
-				}
-				result = TRUE;
-                break;
+			} else if (pMeasureReportInfo->ReportType ==
+				   RM_RPI_HISTOGRAM) {
+				struct rt_measure_rpi_report * pReport =
+				    (struct rt_measure_rpi_report *) pReportBuf;
+				ptr = (u8 *)(eid_ptr->Octet + 3);
+				NdisMoveMemory(&pReport->ChNum, ptr, 1);
+				NdisMoveMemory(&pReport->MeasureStartTime,
+					       ptr + 1, 8);
+				NdisMoveMemory(&pReport->MeasureDuration,
+					       ptr + 9, 2);
+				NdisMoveMemory(&pReport->RPI_Density, ptr + 11,
+					       8);
+			}
+			result = TRUE;
+			break;
 
-			default:
-				break;
+		default:
+			break;
 		}
-		eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+		eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
 	}
 
 	return result;
@@ -1336,20 +1666,18 @@
 	Return	: None.
 	==========================================================================
  */
-static BOOLEAN PeerTpcReqSanity(
-	IN PRTMP_ADAPTER pAd,
-	IN VOID *pMsg,
-	IN ULONG MsgLen,
-	OUT PUINT8 pDialogToken)
+static BOOLEAN PeerTpcReqSanity(struct rt_rtmp_adapter *pAd,
+				void * pMsg,
+				unsigned long MsgLen, u8 *pDialogToken)
 {
-	PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
-	PUCHAR pFramePtr = Fr->Octet;
+	struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
+	u8 *pFramePtr = Fr->Octet;
 	BOOLEAN result = FALSE;
-	PEID_STRUCT eid_ptr;
+	struct rt_eid * eid_ptr;
 
-	MsgLen -= sizeof(HEADER_802_11);
+	MsgLen -= sizeof(struct rt_header_802_11);
 
-	// skip category and action code.
+	/* skip category and action code. */
 	pFramePtr += 2;
 	MsgLen -= 2;
 
@@ -1360,19 +1688,18 @@
 	pFramePtr += 1;
 	MsgLen -= 1;
 
-	eid_ptr = (PEID_STRUCT)pFramePtr;
-	while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
-	{
-		switch(eid_ptr->Eid)
-		{
-			case IE_TPC_REQUEST:
-				result = TRUE;
-                break;
+	eid_ptr = (struct rt_eid *) pFramePtr;
+	while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
+	       ((u8 *)pFramePtr + MsgLen)) {
+		switch (eid_ptr->Eid) {
+		case IE_TPC_REQUEST:
+			result = TRUE;
+			break;
 
-			default:
-				break;
+		default:
+			break;
 		}
-		eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+		eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
 	}
 
 	return result;
@@ -1392,21 +1719,20 @@
 	Return	: None.
 	==========================================================================
  */
-static BOOLEAN PeerTpcRepSanity(
-	IN PRTMP_ADAPTER pAd,
-	IN VOID *pMsg,
-	IN ULONG MsgLen,
-	OUT PUINT8 pDialogToken,
-	OUT PTPC_REPORT_INFO pTpcRepInfo)
+static BOOLEAN PeerTpcRepSanity(struct rt_rtmp_adapter *pAd,
+				void * pMsg,
+				unsigned long MsgLen,
+				u8 *pDialogToken,
+				struct rt_tpc_report_info * pTpcRepInfo)
 {
-	PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
-	PUCHAR pFramePtr = Fr->Octet;
+	struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
+	u8 *pFramePtr = Fr->Octet;
 	BOOLEAN result = FALSE;
-	PEID_STRUCT eid_ptr;
+	struct rt_eid * eid_ptr;
 
-	MsgLen -= sizeof(HEADER_802_11);
+	MsgLen -= sizeof(struct rt_header_802_11);
 
-	// skip category and action code.
+	/* skip category and action code. */
 	pFramePtr += 2;
 	MsgLen -= 2;
 
@@ -1417,21 +1743,21 @@
 	pFramePtr += 1;
 	MsgLen -= 1;
 
-	eid_ptr = (PEID_STRUCT)pFramePtr;
-	while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
-	{
-		switch(eid_ptr->Eid)
-		{
-			case IE_TPC_REPORT:
-				NdisMoveMemory(&pTpcRepInfo->TxPwr, eid_ptr->Octet, 1);
-				NdisMoveMemory(&pTpcRepInfo->LinkMargin, eid_ptr->Octet + 1, 1);
-				result = TRUE;
-                break;
+	eid_ptr = (struct rt_eid *) pFramePtr;
+	while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
+	       ((u8 *)pFramePtr + MsgLen)) {
+		switch (eid_ptr->Eid) {
+		case IE_TPC_REPORT:
+			NdisMoveMemory(&pTpcRepInfo->TxPwr, eid_ptr->Octet, 1);
+			NdisMoveMemory(&pTpcRepInfo->LinkMargin,
+				       eid_ptr->Octet + 1, 1);
+			result = TRUE;
+			break;
 
-			default:
-				break;
+		default:
+			break;
 		}
-		eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+		eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
 	}
 
 	return result;
@@ -1448,64 +1774,69 @@
 	Return	: None.
 	==========================================================================
  */
-static VOID PeerChSwAnnAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+static void PeerChSwAnnAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	CH_SW_ANN_INFO ChSwAnnInfo;
-	PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
-	UCHAR index = 0, Channel = 0, NewChannel = 0;
-	ULONG Bssidx = 0;
+	struct rt_ch_sw_ann_info ChSwAnnInfo;
+	struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg;
+	u8 index = 0, Channel = 0, NewChannel = 0;
+	unsigned long Bssidx = 0;
 
-	NdisZeroMemory(&ChSwAnnInfo, sizeof(CH_SW_ANN_INFO));
-	if (! PeerChSwAnnSanity(pAd, Elem->Msg, Elem->MsgLen, &ChSwAnnInfo))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("Invalid Channel Switch Action Frame.\n"));
+	NdisZeroMemory(&ChSwAnnInfo, sizeof(struct rt_ch_sw_ann_info));
+	if (!PeerChSwAnnSanity(pAd, Elem->Msg, Elem->MsgLen, &ChSwAnnInfo)) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Invalid Channel Switch Action Frame.\n"));
 		return;
 	}
 
-	if (pAd->OpMode == OPMODE_STA)
-	{
-		Bssidx = BssTableSearch(&pAd->ScanTab, pFr->Hdr.Addr3, pAd->CommonCfg.Channel);
-		if (Bssidx == BSS_NOT_FOUND)
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("PeerChSwAnnAction - Bssidx is not found\n"));
+	if (pAd->OpMode == OPMODE_STA) {
+		Bssidx =
+		    BssTableSearch(&pAd->ScanTab, pFr->Hdr.Addr3,
+				   pAd->CommonCfg.Channel);
+		if (Bssidx == BSS_NOT_FOUND) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("PeerChSwAnnAction - Bssidx is not found\n"));
 			return;
 		}
 
-		DBGPRINT(RT_DEBUG_TRACE, ("\n****Bssidx is %d, Channel = %d\n", index, pAd->ScanTab.BssEntry[Bssidx].Channel));
-		hex_dump("SSID",pAd->ScanTab.BssEntry[Bssidx].Bssid ,6);
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("\n****Bssidx is %d, Channel = %d\n", index,
+			  pAd->ScanTab.BssEntry[Bssidx].Channel));
+		hex_dump("SSID", pAd->ScanTab.BssEntry[Bssidx].Bssid, 6);
 
 		Channel = pAd->CommonCfg.Channel;
 		NewChannel = ChSwAnnInfo.Channel;
 
-		if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel))
-		{
-			// Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
-			// In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
+		if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0)
+		    && (Channel != NewChannel)) {
+			/* Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection). */
+			/* In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results. */
 			AsicSwitchChannel(pAd, 1, FALSE);
 			AsicLockChannel(pAd, 1);
-		    LinkDown(pAd, FALSE);
+			LinkDown(pAd, FALSE);
 			MlmeQueueInit(&pAd->Mlme.Queue);
 			BssTableInit(&pAd->ScanTab);
-		    RTMPusecDelay(1000000);		// use delay to prevent STA do reassoc
+			RTMPusecDelay(1000000);	/* use delay to prevent STA do reassoc */
 
-			// channel sanity check
-			for (index = 0 ; index < pAd->ChannelListNum; index++)
-			{
-				if (pAd->ChannelList[index].Channel == NewChannel)
-				{
-					pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel;
+			/* channel sanity check */
+			for (index = 0; index < pAd->ChannelListNum; index++) {
+				if (pAd->ChannelList[index].Channel ==
+				    NewChannel) {
+					pAd->ScanTab.BssEntry[Bssidx].Channel =
+					    NewChannel;
 					pAd->CommonCfg.Channel = NewChannel;
-					AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-					AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-					DBGPRINT(RT_DEBUG_TRACE, ("&&&&&&&&&&&&&&&&PeerChSwAnnAction - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel));
+					AsicSwitchChannel(pAd,
+							  pAd->CommonCfg.
+							  Channel, FALSE);
+					AsicLockChannel(pAd,
+							pAd->CommonCfg.Channel);
+					DBGPRINT(RT_DEBUG_TRACE,
+						 ("&&&&&&&&&&&&&&&&PeerChSwAnnAction - STA receive channel switch announcement IE (New Channel =%d)\n",
+						  NewChannel));
 					break;
 				}
 			}
 
-			if (index >= pAd->ChannelListNum)
-			{
+			if (index >= pAd->ChannelListNum) {
 				DBGPRINT_ERR(("&&&&&&&&&&&&&&&&&&&&&&&&&&PeerChSwAnnAction(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum));
 			}
 		}
@@ -1514,7 +1845,6 @@
 	return;
 }
 
-
 /*
 	==========================================================================
 	Description:
@@ -1526,20 +1856,23 @@
 	Return	: None.
 	==========================================================================
  */
-static VOID PeerMeasureReqAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+static void PeerMeasureReqAction(struct rt_rtmp_adapter *pAd,
+				 struct rt_mlme_queue_elem *Elem)
 {
-	PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
-	UINT8 DialogToken;
-	MEASURE_REQ_INFO MeasureReqInfo;
+	struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg;
+	u8 DialogToken;
+	struct rt_measure_req_info MeasureReqInfo;
+	struct rt_measure_req MeasureReq;
 	MEASURE_REPORT_MODE ReportMode;
 
-	if(PeerMeasureReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReqInfo))
-	{
+	if (PeerMeasureReqSanity
+	    (pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReqInfo,
+	     &MeasureReq)) {
 		ReportMode.word = 0;
 		ReportMode.field.Incapable = 1;
-		EnqueueMeasurementRep(pAd, pFr->Hdr.Addr2, DialogToken, MeasureReqInfo.Token, ReportMode.word, MeasureReqInfo.ReqType, 0, NULL);
+		EnqueueMeasurementRep(pAd, pFr->Hdr.Addr2, DialogToken,
+				      MeasureReqInfo.Token, ReportMode.word,
+				      MeasureReqInfo.ReqType, 0, NULL);
 	}
 
 	return;
@@ -1556,54 +1889,65 @@
 	Return	: None.
 	==========================================================================
  */
-static VOID PeerMeasureReportAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+static void PeerMeasureReportAction(struct rt_rtmp_adapter *pAd,
+				    struct rt_mlme_queue_elem *Elem)
 {
-	MEASURE_REPORT_INFO MeasureReportInfo;
-	PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
-	UINT8 DialogToken;
-	PUINT8 pMeasureReportInfo;
+	struct rt_measure_report_info MeasureReportInfo;
+	struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg;
+	u8 DialogToken;
+	u8 *pMeasureReportInfo;
 
-//	if (pAd->CommonCfg.bIEEE80211H != TRUE)
-//		return;
+/*      if (pAd->CommonCfg.bIEEE80211H != TRUE) */
+/*              return; */
 
-	if ((pMeasureReportInfo = kmalloc(sizeof(MEASURE_RPI_REPORT), GFP_ATOMIC)) == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%zu).\n", __func__, sizeof(MEASURE_RPI_REPORT)));
+	if ((pMeasureReportInfo =
+	     kmalloc(sizeof(struct rt_measure_rpi_report), GFP_ATOMIC)) == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("%s unable to alloc memory for measure report buffer (size=%zu).\n",
+			  __func__, sizeof(struct rt_measure_rpi_report)));
 		return;
 	}
 
-	NdisZeroMemory(&MeasureReportInfo, sizeof(MEASURE_REPORT_INFO));
-	NdisZeroMemory(pMeasureReportInfo, sizeof(MEASURE_RPI_REPORT));
-	if (PeerMeasureReportSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReportInfo, pMeasureReportInfo))
-	{
+	NdisZeroMemory(&MeasureReportInfo, sizeof(struct rt_measure_report_info));
+	NdisZeroMemory(pMeasureReportInfo, sizeof(struct rt_measure_rpi_report));
+	if (PeerMeasureReportSanity
+	    (pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReportInfo,
+	     pMeasureReportInfo)) {
 		do {
-			PMEASURE_REQ_ENTRY pEntry = NULL;
+			struct rt_measure_req_entry *pEntry = NULL;
 
-			// Not a autonomous measure report.
-			// check the dialog token field. drop it if the dialog token doesn't match.
+			/* Not a autonomous measure report. */
+			/* check the dialog token field. drop it if the dialog token doesn't match. */
 			if ((DialogToken != 0)
-				&& ((pEntry = MeasureReqLookUp(pAd, DialogToken)) == NULL))
+			    && ((pEntry = MeasureReqLookUp(pAd, DialogToken)) ==
+				NULL))
 				break;
 
 			if (pEntry != NULL)
 				MeasureReqDelete(pAd, pEntry->DialogToken);
 
-			if (MeasureReportInfo.ReportType == RM_BASIC)
-			{
-				PMEASURE_BASIC_REPORT pBasicReport = (PMEASURE_BASIC_REPORT)pMeasureReportInfo;
+			if (MeasureReportInfo.ReportType == RM_BASIC) {
+				struct rt_measure_basic_report * pBasicReport =
+				    (struct rt_measure_basic_report *) pMeasureReportInfo;
 				if ((pBasicReport->Map.field.Radar)
-					&& (DfsRequirementCheck(pAd, pBasicReport->ChNum) == TRUE))
-				{
-					NotifyChSwAnnToPeerAPs(pAd, pFr->Hdr.Addr1, pFr->Hdr.Addr2, 1, pBasicReport->ChNum);
-					StartDFSProcedure(pAd, pBasicReport->ChNum, 1);
+				    &&
+				    (DfsRequirementCheck
+				     (pAd, pBasicReport->ChNum) == TRUE)) {
+					NotifyChSwAnnToPeerAPs(pAd,
+							       pFr->Hdr.Addr1,
+							       pFr->Hdr.Addr2,
+							       1,
+							       pBasicReport->
+							       ChNum);
+					StartDFSProcedure(pAd,
+							  pBasicReport->ChNum,
+							  1);
 				}
 			}
 		} while (FALSE);
-	}
-	else
-		DBGPRINT(RT_DEBUG_TRACE, ("Invalid Measurement Report Frame.\n"));
+	} else
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Invalid Measurement Report Frame.\n"));
 
 	kfree(pMeasureReportInfo);
 
@@ -1621,34 +1965,33 @@
 	Return	: None.
 	==========================================================================
  */
-static VOID PeerTpcReqAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+static void PeerTpcReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
-	PUCHAR pFramePtr = pFr->Octet;
-	UINT8 DialogToken;
-	UINT8 TxPwr = GetCurTxPwr(pAd, Elem->Wcid);
-	UINT8 LinkMargin = 0;
-	CHAR RealRssi;
+	struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg;
+	u8 *pFramePtr = pFr->Octet;
+	u8 DialogToken;
+	u8 TxPwr = GetCurTxPwr(pAd, Elem->Wcid);
+	u8 LinkMargin = 0;
+	char RealRssi;
 
-	// link margin: Ratio of the received signal power to the minimum desired by the station (STA). The
-	//				STA may incorporate rate information and channel conditions, including interference, into its computation
-	//				of link margin.
+	/* link margin: Ratio of the received signal power to the minimum desired by the station (STA). The */
+	/*                              STA may incorporate rate information and channel conditions, including interference, into its computation */
+	/*                              of link margin. */
 
 	RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
-								ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
-								ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
+			       ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
+			       ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
 
-	// skip Category and action code.
+	/* skip Category and action code. */
 	pFramePtr += 2;
 
-	// Dialog token.
+	/* Dialog token. */
 	NdisMoveMemory(&DialogToken, pFramePtr, 1);
 
 	LinkMargin = (RealRssi / MIN_RCV_PWR);
 	if (PeerTpcReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken))
-		EnqueueTPCRep(pAd, pFr->Hdr.Addr2, DialogToken, TxPwr, LinkMargin);
+		EnqueueTPCRep(pAd, pFr->Hdr.Addr2, DialogToken, TxPwr,
+			      LinkMargin);
 
 	return;
 }
@@ -1664,22 +2007,21 @@
 	Return	: None.
 	==========================================================================
  */
-static VOID PeerTpcRepAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+static void PeerTpcRepAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	UINT8 DialogToken;
-	TPC_REPORT_INFO TpcRepInfo;
-	PTPC_REQ_ENTRY pEntry = NULL;
+	u8 DialogToken;
+	struct rt_tpc_report_info TpcRepInfo;
+	struct rt_tpc_req_entry *pEntry = NULL;
 
-	NdisZeroMemory(&TpcRepInfo, sizeof(TPC_REPORT_INFO));
-	if (PeerTpcRepSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &TpcRepInfo))
-	{
-		if ((pEntry = TpcReqLookUp(pAd, DialogToken)) != NULL)
-		{
+	NdisZeroMemory(&TpcRepInfo, sizeof(struct rt_tpc_report_info));
+	if (PeerTpcRepSanity
+	    (pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &TpcRepInfo)) {
+		if ((pEntry = TpcReqLookUp(pAd, DialogToken)) != NULL) {
 			TpcReqDelete(pAd, pEntry->DialogToken);
-			DBGPRINT(RT_DEBUG_TRACE, ("%s: DialogToken=%x, TxPwr=%d, LinkMargin=%d\n",
-				__func__, DialogToken, TpcRepInfo.TxPwr, TpcRepInfo.LinkMargin));
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("%s: DialogToken=%x, TxPwr=%d, LinkMargin=%d\n",
+				  __func__, DialogToken, TpcRepInfo.TxPwr,
+				  TpcRepInfo.LinkMargin));
 		}
 	}
 
@@ -1698,41 +2040,37 @@
 	Return	: None.
 	==========================================================================
  */
-VOID PeerSpectrumAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void PeerSpectrumAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
 
-	UCHAR	Action = Elem->Msg[LENGTH_802_11+1];
+	u8 Action = Elem->Msg[LENGTH_802_11 + 1];
 
 	if (pAd->CommonCfg.bIEEE80211H != TRUE)
 		return;
 
-	switch(Action)
-	{
-		case SPEC_MRQ:
-			// current rt2860 unable do such measure specified in Measurement Request.
-			// reject all measurement request.
-			PeerMeasureReqAction(pAd, Elem);
-			break;
+	switch (Action) {
+	case SPEC_MRQ:
+		/* current rt2860 unable do such measure specified in Measurement Request. */
+		/* reject all measurement request. */
+		PeerMeasureReqAction(pAd, Elem);
+		break;
 
-		case SPEC_MRP:
-			PeerMeasureReportAction(pAd, Elem);
-			break;
+	case SPEC_MRP:
+		PeerMeasureReportAction(pAd, Elem);
+		break;
 
-		case SPEC_TPCRQ:
-			PeerTpcReqAction(pAd, Elem);
-			break;
+	case SPEC_TPCRQ:
+		PeerTpcReqAction(pAd, Elem);
+		break;
 
-		case SPEC_TPCRP:
-			PeerTpcRepAction(pAd, Elem);
-			break;
+	case SPEC_TPCRP:
+		PeerTpcRepAction(pAd, Elem);
+		break;
 
-		case SPEC_CHANNEL_SWITCH:
-{
-}
-			PeerChSwAnnAction(pAd, Elem);
-			break;
+	case SPEC_CHANNEL_SWITCH:
+
+		PeerChSwAnnAction(pAd, Elem);
+		break;
 	}
 
 	return;
@@ -1747,49 +2085,63 @@
 	Return	: None.
 	==========================================================================
  */
-INT Set_MeasureReq_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+int Set_MeasureReq_Proc(struct rt_rtmp_adapter *pAd, char *arg)
 {
-	UINT Aid = 1;
-	UINT ArgIdx;
-	PUCHAR thisChar;
+	u32 Aid = 1;
+	u32 ArgIdx;
+	char *thisChar;
 
 	MEASURE_REQ_MODE MeasureReqMode;
-	UINT8 MeasureReqToken = RandomByte(pAd);
-	UINT8 MeasureReqType = RM_BASIC;
-	UINT8 MeasureCh = 1;
+	u8 MeasureReqToken = RandomByte(pAd);
+	u8 MeasureReqType = RM_BASIC;
+	u8 MeasureCh = 1;
+	u64 MeasureStartTime = GetCurrentTimeStamp(pAd);
+	struct rt_measure_req MeasureReq;
+	u8 TotalLen;
+
+	struct rt_header_802_11 ActHdr;
+	u8 *pOutBuffer = NULL;
+	int NStatus;
+	unsigned long FrameLen;
+
+	NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer);	/*Get an unused nonpaged memory */
+	if (NStatus != NDIS_STATUS_SUCCESS) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("%s() allocate memory failed \n", __func__));
+		goto END_OF_MEASURE_REQ;
+	}
 
 	ArgIdx = 1;
-	while ((thisChar = strsep((char **)&arg, "-")) != NULL)
-	{
-		switch(ArgIdx)
-		{
-			case 1:	// Aid.
-				Aid = simple_strtol(thisChar, 0, 16);
-				break;
+	while ((thisChar = strsep((char **)&arg, "-")) != NULL) {
+		switch (ArgIdx) {
+		case 1:	/* Aid. */
+			Aid = (u8)simple_strtol(thisChar, 0, 16);
+			break;
 
-			case 2: // Measurement Request Type.
-				MeasureReqType = simple_strtol(thisChar, 0, 16);
-				if (MeasureReqType > 3)
-				{
-					DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow MeasureReqType(%d)\n", __func__, MeasureReqType));
-					return TRUE;
-				}
-				break;
+		case 2:	/* Measurement Request Type. */
+			MeasureReqType = simple_strtol(thisChar, 0, 16);
+			if (MeasureReqType > 3) {
+				DBGPRINT(RT_DEBUG_ERROR,
+					 ("%s: unknow MeasureReqType(%d)\n",
+					  __func__, MeasureReqType));
+				goto END_OF_MEASURE_REQ;
+			}
+			break;
 
-			case 3: // Measurement channel.
-				MeasureCh = simple_strtol(thisChar, 0, 16);
-				break;
+		case 3:	/* Measurement channel. */
+			MeasureCh = (u8)simple_strtol(thisChar, 0, 16);
+			break;
 		}
 		ArgIdx++;
 	}
 
-	DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d, MeasureReqType=%d MeasureCh=%d\n", __func__, Aid, MeasureReqType, MeasureCh));
-	if (!VALID_WCID(Aid))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __func__, Aid));
-		return TRUE;
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("%s::Aid = %d, MeasureReqType=%d MeasureCh=%d\n", __func__,
+		  Aid, MeasureReqType, MeasureCh));
+	if (!VALID_WCID(Aid)) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("%s: unknow sta of Aid(%d)\n", __func__, Aid));
+		goto END_OF_MEASURE_REQ;
 	}
 
 	MeasureReqMode.word = 0;
@@ -1797,26 +2149,52 @@
 
 	MeasureReqInsert(pAd, MeasureReqToken);
 
-	EnqueueMeasurementReq(pAd, pAd->MacTab.Content[Aid].Addr,
-		MeasureReqToken, MeasureReqMode.word, MeasureReqType, MeasureCh, 2000);
+	/* build action frame header. */
+	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0,
+			 pAd->MacTab.Content[Aid].Addr, pAd->CurrentAddress);
+
+	NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
+	FrameLen = sizeof(struct rt_header_802_11);
+
+	TotalLen = sizeof(struct rt_measure_req_info) + sizeof(struct rt_measure_req);
+
+	MakeMeasurementReqFrame(pAd, pOutBuffer, &FrameLen,
+				sizeof(struct rt_measure_req_info), CATEGORY_RM, RM_BASIC,
+				MeasureReqToken, MeasureReqMode.word,
+				MeasureReqType, 0);
+
+	MeasureReq.ChNum = MeasureCh;
+	MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime);
+	MeasureReq.MeasureDuration = cpu2le16(2000);
+
+	{
+		unsigned long TempLen;
+		MakeOutgoingFrame(pOutBuffer + FrameLen, &TempLen,
+				  sizeof(struct rt_measure_req), &MeasureReq,
+				  END_OF_ARGS);
+		FrameLen += TempLen;
+	}
+
+	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, (u32)FrameLen);
+
+END_OF_MEASURE_REQ:
+	MlmeFreeMemory(pAd, pOutBuffer);
 
 	return TRUE;
 }
 
-INT Set_TpcReq_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+int Set_TpcReq_Proc(struct rt_rtmp_adapter *pAd, char *arg)
 {
-	UINT Aid;
+	u32 Aid;
 
-	UINT8 TpcReqToken = RandomByte(pAd);
+	u8 TpcReqToken = RandomByte(pAd);
 
-	Aid = simple_strtol(arg, 0, 16);
+	Aid = (u32)simple_strtol(arg, 0, 16);
 
 	DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d\n", __func__, Aid));
-	if (!VALID_WCID(Aid))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __func__, Aid));
+	if (!VALID_WCID(Aid)) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("%s: unknow sta of Aid(%d)\n", __func__, Aid));
 		return TRUE;
 	}
 
@@ -1826,4 +2204,3 @@
 
 	return TRUE;
 }
-
diff --git a/drivers/staging/rt2860/config.mk b/drivers/staging/rt2860/config.mk
deleted file mode 100644
index 25bd55a..0000000
--- a/drivers/staging/rt2860/config.mk
+++ /dev/null
@@ -1,241 +0,0 @@
-# Support ATE function
-HAS_ATE=n
-
-# Support 28xx QA ATE function
-HAS_28xx_QA=n
-
-# Support Wpa_Supplicant
-HAS_WPA_SUPPLICANT=n
-
-# Support Native WpaSupplicant for Network Maganger
-HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=n
-
-#Support Net interface block while Tx-Sw queue full
-HAS_BLOCK_NET_IF=n
-
-#Support DFS function
-HAS_DFS_SUPPORT=n
-
-#Support Carrier-Sense function
-HAS_CS_SUPPORT=n
-
-#ifdef MULTI_CARD
-# Support for Multiple Cards
-HAS_MC_SUPPORT=n
-#endif // MULTI_CARD //
-
-#Support for IEEE802.11e DLS
-HAS_QOS_DLS_SUPPORT=n
-
-#Support for EXT_CHANNEL
-HAS_EXT_BUILD_CHANNEL_LIST=n
-
-#Support for Net-SNMP
-HAS_SNMP_SUPPORT=n
-
-#Support features of Single SKU.
-HAS_SINGLE_SKU_SUPPORT=n
-
-#Support features of 802.11n
-HAS_DOT11_N_SUPPORT=y
-
-
-#################################################
-
-CC := $(CROSS_COMPILE)gcc
-LD := $(CROSS_COMPILE)ld
-
-WFLAGS := -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT  -DLINUX -Wall -Wstrict-prototypes -Wno-trigraphs
-
-
-#################################################
-
-#ifdef CONFIG_STA_SUPPORT
-# config for STA mode
-
-ifeq ($(RT28xx_MODE),STA)
-WFLAGS += -DCONFIG_STA_SUPPORT -DDBG
-
-ifeq ($(HAS_WPA_SUPPLICANT),y)
-WFLAGS += -DWPA_SUPPLICANT_SUPPORT
-endif
-
-ifeq ($(HAS_NATIVE_WPA_SUPPLICANT_SUPPORT),y)
-WFLAGS += -DNATIVE_WPA_SUPPLICANT_SUPPORT
-endif
-
-ifeq ($(HAS_ATE),y)
-WFLAGS += -DRALINK_ATE
-ifeq ($(HAS_28xx_QA),y)
-WFLAGS += -DRALINK_28xx_QA
-endif
-endif
-
-ifeq ($(HAS_SNMP_SUPPORT),y)
-WFLAGS += -DSNMP_SUPPORT
-endif
-
-ifeq ($(HAS_QOS_DLS_SUPPORT),y)
-WFLAGS += -DQOS_DLS_SUPPORT
-endif
-
-ifeq ($(HAS_DOT11_N_SUPPORT),y)
-WFLAGS += -DDOT11_N_SUPPORT
-endif
-
-ifeq ($(HAS_CS_SUPPORT),y)
-WFLAGS += -DCARRIER_DETECTION_SUPPORT
-endif
-
-ifeq ($(HAS_SINGLE_SKU_SUPPORT),y)
-WFLAGS += -DSINGLE_SKU
-endif
-
-endif
-# endif of ifeq ($(RT28xx_MODE),STA)
-#endif // CONFIG_STA_SUPPORT //
-
-#################################################
-
-#################################################
-
-#
-# Common compiler flag
-#
-
-
-ifeq ($(HAS_EXT_BUILD_CHANNEL_LIST),y)
-WFLAGS += -DEXT_BUILD_CHANNEL_LIST
-endif
-
-ifeq ($(CHIPSET),2870)
-WFLAGS +=-DRT2870
-endif
-
-ifeq ($(PLATFORM),5VT)
-#WFLAGS += -DCONFIG_5VT_ENHANCE
-endif
-
-ifeq ($(HAS_BLOCK_NET_IF),y)
-WFLAGS += -DBLOCK_NET_IF
-endif
-
-ifeq ($(HAS_DFS_SUPPORT),y)
-WFLAGS += -DDFS_SUPPORT
-endif
-
-#ifdef MULTI_CARD
-ifeq ($(HAS_MC_SUPPORT),y)
-WFLAGS += -DMULTIPLE_CARD_SUPPORT
-endif
-#endif // MULTI_CARD //
-
-ifeq ($(HAS_LLTD),y)
-WFLAGS += -DLLTD_SUPPORT
-endif
-
-ifeq ($(PLATFORM),IXP)
-WFLAGS += -DRT_BIG_ENDIAN
-endif
-
-ifeq ($(PLATFORM),IKANOS_V160)
-WFLAGS += -DRT_BIG_ENDIAN -DIKANOS_VX_1X0
-endif
-
-ifeq ($(PLATFORM),IKANOS_V180)
-WFLAGS += -DRT_BIG_ENDIAN -DIKANOS_VX_1X0
-endif
-
-ifeq ($(PLATFORM),INF_TWINPASS)
-WFLAGS += -DRT_BIG_ENDIAN -DINF_TWINPASS
-endif
-
-ifeq ($(PLATFORM),INF_DANUBE)
-WFLAGS += -DINF_DANUBE -DRT_BIG_ENDIAN
-endif
-
-ifeq ($(PLATFORM),CAVM_OCTEON)
-WFLAGS += -DRT_BIG_ENDIAN
-endif
-
-ifeq ($(PLATFORM),BRCM_6358)
-WFLAGS += -DRT_BIG_ENDIAN
-endif
-
-ifeq ($(PLATFORM),INF_AMAZON_SE)
-#WFLAGS += -DRT_BIG_ENDIAN -DINF_AMAZON_SE -DBG_FT_SUPPORT
-WFLAGS += -DRT_BIG_ENDIAN -DINF_AMAZON_SE
-endif
-
-#kernel build options for 2.4
-# move to Makefile outside LINUX_SRC := /opt/star/kernel/linux-2.4.27-star
-
-ifeq ($(PLATFORM),STAR)
-CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -Uarm -fno-common -pipe -mapcs-32 -D__LINUX_ARM_ARCH__=4 -march=armv4  -mshort-load-bytes -msoft-float -Uarm -DMODULE -DMODVERSIONS -include $(LINUX_SRC)/include/linux/modversions.h $(WFLAGS)
-
-export CFLAGS
-endif
-
-ifeq ($(PLATFORM),SIGMA)
-CFLAGS := -D__KERNEL__ -I$(RT28xx_DIR)/include -I$(LINUX_SRC)/include -I$(LINUX_SRC)/include/asm/gcc -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -DEM86XX_CHIP=EM86XX_CHIPID_TANGO2 -DEM86XX_REVISION=6 -I$(LINUX_SRC)/include/asm-mips/mach-generic -I$(RT2860_DIR)/include -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -O2     -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe  -mabi=32 -march=mips32r2 -Wa,-32 -Wa,-march=mips32r2 -Wa,-mips32r2 -Wa,--trap -DMODULE $(WFLAGS)
-
-export CFLAGS
-endif
-
-ifeq ($(PLATFORM),SIGMA_8622)
-CFLAGS := -D__KERNEL__ -I$(CROSS_COMPILE_INCLUDE)/include -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -fno-common -pipe -fno-builtin -D__linux__ -DNO_MM -mapcs-32 -march=armv4 -mtune=arm7tdmi -msoft-float -DMODULE -mshort-load-bytes -nostdinc -iwithprefix -DMODULE $(WFLAGS)
-export CFLAGS
-endif
-
-ifeq ($(PLATFORM),5VT)
-CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -mlittle-endian -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O3 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-omit-frame-pointer -mapcs -mno-sched-prolog -mabi=apcs-gnu -mno-thumb-interwork -D__LINUX_ARM_ARCH__=5 -march=armv5te -mtune=arm926ej-s --param max-inline-insns-single=40000  -Uarm -Wdeclaration-after-statement -Wno-pointer-sign -DMODULE $(WFLAGS)
-
-export CFLAGS
-endif
-
-ifeq ($(PLATFORM),IKANOS_V160)
-CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(LINUX_SRC)/include/asm/gcc -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -I$(LINUX_SRC)/include/asm-mips/mach-generic -I$(RT28xx_DIR)/include -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -O2 -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe -march=lx4189 -Wa, -DMODULE $(WFLAGS)
-export CFLAGS
-endif
-
-ifeq ($(PLATFORM),IKANOS_V180)
-CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(LINUX_SRC)/include/asm/gcc -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -I$(LINUX_SRC)/include/asm-mips/mach-generic -I$(RT28xx_DIR)/include -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -O2 -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe -mips32r2 -Wa, -DMODULE $(WFLAGS)
-export CFLAGS
-endif
-
-ifeq ($(PLATFORM),INF_TWINPASS)
-CFLAGS := -D__KERNEL__ -DMODULE -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -G 0 -mno-abicalls -fno-pic -march=4kc -mips32 -Wa,--trap -pipe -mlong-calls $(WFLAGS)
-export CFLAGS
-endif
-
-ifeq ($(PLATFORM),INF_DANUBE)
-CFLAGS := -I$(RT28xx_DIR)/include $(WFLAGS) -Wundef -fno-strict-aliasing -fno-common -ffreestanding -Os -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe -msoft-float  -mabi=32 -march=mips32 -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap -I$(LINUX_SRC)/include/asm-mips/mach-generic
-export CFLAGS
-endif
-
-ifeq ($(PLATFORM),BRCM_6358)
-CFLAGS := $(WFLAGS) -I$(RT28xx_DIR)/include -nostdinc -iwithprefix include -D__KERNEL__ -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -I $(LINUX_SRC)/include/asm/gcc -G 0 -mno-abicalls -fno-pic -pipe  -finline-limit=100000 -mabi=32 -march=mips32 -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap -I$(LINUX_SRC)/include/asm-mips/mach-bcm963xx -I$(LINUX_SRC)/include/asm-mips/mach-generic  -Os -fomit-frame-pointer -Wdeclaration-after-statement  -DMODULE -mlong-calls
-export CFLAGS
-endif
-
-ifeq ($(PLATFORM),PC)
-    ifneq (,$(findstring 2.4,$(LINUX_SRC)))
-	# Linux 2.4
-	CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -DMODULE -DMODVERSIONS -include $(LINUX_SRC)/include/linux/modversions.h $(WFLAGS)
-	export CFLAGS
-    else
-	# Linux 2.6
-	EXTRA_CFLAGS := $(WFLAGS) -I$(RT28xx_DIR)/include
-    endif
-endif
-
-ifeq ($(PLATFORM),IXP)
-        EXTRA_CFLAGS := -v $(WFLAGS) -I$(RT28xx_DIR)/include -mbig-endian
-endif
-
-ifeq ($(PLATFORM),CAVM_OCTEON)
-	EXTRA_CFLAGS := $(WFLAGS) -I$(RT28xx_DIR)/include \
-				    -mabi=64 $(WFLAGS)
-export CFLAGS
-endif
-
diff --git a/drivers/staging/rt2860/crypt_hmac.h b/drivers/staging/rt2860/crypt_hmac.h
new file mode 100644
index 0000000..7a56515
--- /dev/null
+++ b/drivers/staging/rt2860/crypt_hmac.h
@@ -0,0 +1,65 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+ */
+
+/****************************************************************************
+    Module Name:
+    HMAC
+
+    Abstract:
+    FIPS 198: The Keyed-Hash Message Authentication Code (HMAC)
+
+    Revision History:
+    Who         When            What
+    --------    ----------      ------------------------------------------
+    Eddy        2008/11/24      Create HMAC-SHA1, HMAC-SHA256
+***************************************************************************/
+#ifndef __CRYPT_HMAC_H__
+#define __CRYPT_HMAC_H__
+
+#ifdef CRYPT_TESTPLAN
+#include "crypt_testplan.h"
+#else
+#include "rt_config.h"
+#endif /* CRYPT_TESTPLAN */
+
+#ifdef SHA1_SUPPORT
+#define HMAC_SHA1_SUPPORT
+void HMAC_SHA1(IN const u8 Key[],
+	       u32 KeyLen,
+	       IN const u8 Message[],
+	       u32 MessageLen, u8 MAC[], u32 MACLen);
+#endif /* SHA1_SUPPORT */
+
+#ifdef MD5_SUPPORT
+#define HMAC_MD5_SUPPORT
+void HMAC_MD5(IN const u8 Key[],
+	      u32 KeyLen,
+	      IN const u8 Message[],
+	      u32 MessageLen, u8 MAC[], u32 MACLen);
+#endif /* MD5_SUPPORT */
+
+#endif /* __CRYPT_HMAC_H__ */
diff --git a/drivers/staging/rt2860/crypt_md5.h b/drivers/staging/rt2860/crypt_md5.h
new file mode 100644
index 0000000..26f9745
--- /dev/null
+++ b/drivers/staging/rt2860/crypt_md5.h
@@ -0,0 +1,73 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+ */
+
+/****************************************************************************
+    Module Name:
+    MD5
+
+    Abstract:
+    RFC1321: The MD5 Message-Digest Algorithm
+
+    Revision History:
+    Who         When            What
+    --------    ----------      ------------------------------------------
+    Eddy        2008/11/24      Create md5
+***************************************************************************/
+
+#ifndef __CRYPT_MD5_H__
+#define __CRYPT_MD5_H__
+
+#ifdef CRYPT_TESTPLAN
+#include "crypt_testplan.h"
+#else
+#include "rt_config.h"
+#endif /* CRYPT_TESTPLAN */
+
+/* Algorithm options */
+#define MD5_SUPPORT
+
+#ifdef MD5_SUPPORT
+#define MD5_BLOCK_SIZE    64	/* 512 bits = 64 bytes */
+#define MD5_DIGEST_SIZE   16	/* 128 bits = 16 bytes */
+
+struct rt_md5_ctx_struc {
+	u32 HashValue[4];
+	u64 MessageLen;
+	u8 Block[MD5_BLOCK_SIZE];
+	u32 BlockLen;
+};
+
+void MD5_Init(struct rt_md5_ctx_struc *pMD5_CTX);
+void MD5_Hash(struct rt_md5_ctx_struc *pMD5_CTX);
+void MD5_Append(struct rt_md5_ctx_struc *pMD5_CTX,
+		IN const u8 Message[], u32 MessageLen);
+void MD5_End(struct rt_md5_ctx_struc *pMD5_CTX, u8 DigestMessage[]);
+void RT_MD5(IN const u8 Message[],
+	    u32 MessageLen, u8 DigestMessage[]);
+#endif /* MD5_SUPPORT */
+
+#endif /* __CRYPT_MD5_H__ */
diff --git a/drivers/staging/rt2860/crypt_sha2.h b/drivers/staging/rt2860/crypt_sha2.h
new file mode 100644
index 0000000..20d11ab
--- /dev/null
+++ b/drivers/staging/rt2860/crypt_sha2.h
@@ -0,0 +1,73 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+ */
+
+/****************************************************************************
+    Module Name:
+    SHA2
+
+    Abstract:
+    FIPS 180-2: Secure Hash Standard (SHS)
+
+    Revision History:
+    Who         When            What
+    --------    ----------      ------------------------------------------
+    Eddy        2008/11/24      Create SHA1
+    Eddy        2008/07/23      Create SHA256
+***************************************************************************/
+
+#ifndef __CRYPT_SHA2_H__
+#define __CRYPT_SHA2_H__
+
+#ifdef CRYPT_TESTPLAN
+#include "crypt_testplan.h"
+#else
+#include "rt_config.h"
+#endif /* CRYPT_TESTPLAN */
+
+/* Algorithm options */
+#define SHA1_SUPPORT
+
+#ifdef SHA1_SUPPORT
+#define SHA1_BLOCK_SIZE    64	/* 512 bits = 64 bytes */
+#define SHA1_DIGEST_SIZE   20	/* 160 bits = 20 bytes */
+struct rt_sha1_ctx {
+	u32 HashValue[5];	/* 5 = (SHA1_DIGEST_SIZE / 32) */
+	u64 MessageLen;	/* total size */
+	u8 Block[SHA1_BLOCK_SIZE];
+	u32 BlockLen;
+};
+
+void RT_SHA1_Init(struct rt_sha1_ctx *pSHA_CTX);
+void SHA1_Hash(struct rt_sha1_ctx *pSHA_CTX);
+void SHA1_Append(struct rt_sha1_ctx *pSHA_CTX,
+		 IN const u8 Message[], u32 MessageLen);
+void SHA1_End(struct rt_sha1_ctx *pSHA_CTX, u8 DigestMessage[]);
+void RT_SHA1(IN const u8 Message[],
+	     u32 MessageLen, u8 DigestMessage[]);
+#endif /* SHA1_SUPPORT */
+
+#endif /* __CRYPT_SHA2_H__ */
diff --git a/drivers/staging/rt2860/dfs.h b/drivers/staging/rt2860/dfs.h
index f34f618..5fbab25 100644
--- a/drivers/staging/rt2860/dfs.h
+++ b/drivers/staging/rt2860/dfs.h
@@ -36,53 +36,4 @@
     Fonchi    03-12-2007      created
 */
 
-#define RADAR_PULSE 1
-#define RADAR_WIDTH 2
-
-#define WIDTH_RD_IDLE 0
-#define WIDTH_RD_CHECK 1
-
-
-VOID BbpRadarDetectionStart(
-	IN PRTMP_ADAPTER pAd);
-
-VOID BbpRadarDetectionStop(
-	IN PRTMP_ADAPTER pAd);
-
-VOID RadarDetectionStart(
-	IN PRTMP_ADAPTER pAd,
-	IN BOOLEAN CTS_Protect,
-	IN UINT8 CTSPeriod);
-
-VOID RadarDetectionStop(
-	IN PRTMP_ADAPTER	pAd);
-
-VOID RadarDetectPeriodic(
-	IN PRTMP_ADAPTER	pAd);
-
-
-BOOLEAN RadarChannelCheck(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			Ch);
-
-ULONG JapRadarType(
-	IN PRTMP_ADAPTER pAd);
-
-ULONG RTMPBbpReadRadarDuration(
-	IN PRTMP_ADAPTER	pAd);
-
-ULONG RTMPReadRadarDuration(
-	IN PRTMP_ADAPTER	pAd);
-
-VOID RTMPCleanRadarDuration(
-	IN PRTMP_ADAPTER	pAd);
-
-INT Set_ChMovingTime_Proc(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR arg);
-
-INT Set_LongPulseRadarTh_Proc(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR arg);
-
-
+BOOLEAN RadarChannelCheck(struct rt_rtmp_adapter *pAd, u8 Ch);
diff --git a/drivers/staging/rt2860/eeprom.h b/drivers/staging/rt2860/eeprom.h
new file mode 100644
index 0000000..039801a
--- /dev/null
+++ b/drivers/staging/rt2860/eeprom.h
@@ -0,0 +1,67 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	eeprom.h
+
+	Abstract:
+	Miniport header file for eeprom related information
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+#ifndef __EEPROM_H__
+#define __EEPROM_H__
+
+#ifdef RTMP_PCI_SUPPORT
+/*************************************************************************
+  *	Public function declarations for prom-based chipset
+  ************************************************************************/
+int rtmp_ee_prom_read16(struct rt_rtmp_adapter *pAd,
+			u16 Offset, u16 * pValue);
+#endif /* RTMP_PCI_SUPPORT // */
+#ifdef RTMP_USB_SUPPORT
+/*************************************************************************
+  *	Public function declarations for usb-based prom chipset
+  ************************************************************************/
+int RTUSBReadEEPROM16(struct rt_rtmp_adapter *pAd,
+			   u16 offset, u16 *pData);
+#endif /* RTMP_USB_SUPPORT // */
+
+#ifdef RT30xx
+#ifdef RTMP_EFUSE_SUPPORT
+int rtmp_ee_efuse_read16(struct rt_rtmp_adapter *pAd,
+			 u16 Offset, u16 * pValue);
+#endif /* RTMP_EFUSE_SUPPORT // */
+#endif /* RT30xx // */
+
+/*************************************************************************
+  *	Public function declarations for prom operation callback functions setting
+  ************************************************************************/
+int RtmpChipOpsEepromHook(struct rt_rtmp_adapter *pAd, int infType);
+
+#endif /* __EEPROM_H__ // */
diff --git a/drivers/staging/rt2860/iface/rtmp_pci.h b/drivers/staging/rt2860/iface/rtmp_pci.h
new file mode 100644
index 0000000..7759d56
--- /dev/null
+++ b/drivers/staging/rt2860/iface/rtmp_pci.h
@@ -0,0 +1,78 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+*/
+
+#ifndef __RTMP_PCI_H__
+#define __RTMP_PCI_H__
+
+#define RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p)				\
+	((struct os_cookie *)handle)->pci_dev = dev_p;
+
+#ifdef LINUX
+// set driver data
+#define RT28XX_DRVDATA_SET(_a)			pci_set_drvdata(_a, net_dev);
+
+#define RT28XX_PUT_DEVICE(dev_p)
+
+#define SA_SHIRQ IRQF_SHARED
+
+#ifdef PCI_MSI_SUPPORT
+#define RTMP_MSI_ENABLE(_pAd) \
+	{     struct os_cookie *_pObj = (struct os_cookie *)(_pAd->OS_Cookie); \
+		(_pAd)->HaveMsi = pci_enable_msi(_pObj->pci_dev) == 0 ? TRUE : FALSE; \
+	}
+
+#define RTMP_MSI_DISABLE(_pAd) \
+	{     struct os_cookie *_pObj = (struct os_cookie *)(_pAd->OS_Cookie); \
+		if (_pAd->HaveMsi == TRUE) \
+			pci_disable_msi(_pObj->pci_dev); \
+		_pAd->HaveMsi = FALSE;  \
+	}
+#else
+#define RTMP_MSI_ENABLE(_pAd)		do{}while(0)
+#define RTMP_MSI_DISABLE(_pAd)		do{}while(0)
+#endif // PCI_MSI_SUPPORT //
+
+#define RTMP_PCI_DEV_UNMAP()										\
+{	if (net_dev->base_addr)	{								\
+		iounmap((void *)(net_dev->base_addr));				\
+		release_mem_region(pci_resource_start(dev_p, 0),	\
+							pci_resource_len(dev_p, 0)); }	\
+	if (net_dev->irq) pci_release_regions(dev_p); }
+
+#define PCI_REG_READ_WORD(pci_dev, offset, Configuration)   \
+    if (pci_read_config_word(pci_dev, offset, &reg16) == 0)     \
+        Configuration = le2cpu16(reg16);                        \
+    else                                                        \
+        Configuration = 0;
+
+#define PCI_REG_WIRTE_WORD(pci_dev, offset, Configuration)  \
+    reg16 = cpu2le16(Configuration);                        \
+    pci_write_config_word(pci_dev, offset, reg16);
+
+#endif // LINUX //
+
+#endif // __RTMP_PCI_H__ //
diff --git a/drivers/staging/rt2860/iface/rtmp_usb.h b/drivers/staging/rt2860/iface/rtmp_usb.h
new file mode 100644
index 0000000..6bb384a
--- /dev/null
+++ b/drivers/staging/rt2860/iface/rtmp_usb.h
@@ -0,0 +1,182 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+*/
+
+#ifndef __RTMP_USB_H__
+#define __RTMP_USB_H__
+
+#include "../rtusb_io.h"
+
+#ifdef LINUX
+#include <linux/usb.h>
+#endif // LINUX //
+
+extern u8 EpToQueue[6];
+
+#define RXBULKAGGRE_ZISE			12
+#define MAX_TXBULK_LIMIT			(LOCAL_TXBUF_SIZE*(BULKAGGRE_ZISE-1))
+#define MAX_TXBULK_SIZE			(LOCAL_TXBUF_SIZE*BULKAGGRE_ZISE)
+#define MAX_RXBULK_SIZE			(LOCAL_TXBUF_SIZE*RXBULKAGGRE_ZISE)
+#define MAX_MLME_HANDLER_MEMORY 20
+
+// Flags for Bulkflags control for bulk out data
+//
+#define	fRTUSB_BULK_OUT_DATA_NULL				0x00000001
+#define	fRTUSB_BULK_OUT_RTS						0x00000002
+#define	fRTUSB_BULK_OUT_MLME						0x00000004
+
+#define	fRTUSB_BULK_OUT_PSPOLL					0x00000010
+#define	fRTUSB_BULK_OUT_DATA_FRAG				0x00000020
+#define	fRTUSB_BULK_OUT_DATA_FRAG_2				0x00000040
+#define	fRTUSB_BULK_OUT_DATA_FRAG_3				0x00000080
+#define	fRTUSB_BULK_OUT_DATA_FRAG_4				0x00000100
+
+#define	fRTUSB_BULK_OUT_DATA_NORMAL				0x00010000
+#define	fRTUSB_BULK_OUT_DATA_NORMAL_2			0x00020000
+#define	fRTUSB_BULK_OUT_DATA_NORMAL_3			0x00040000
+#define	fRTUSB_BULK_OUT_DATA_NORMAL_4			0x00080000
+
+// TODO:move to ./ate/include/iface/ate_usb.h
+
+#define FREE_HTTX_RING(_pCookie, _pipeId, _txContext)			\
+{										\
+	if ((_txContext)->ENextBulkOutPosition == (_txContext)->CurWritePosition)	\
+	{																	\
+		(_txContext)->bRingEmpty = TRUE;			\
+	}																	\
+	/*NdisInterlockedDecrement(&(_p)->TxCount); */\
+}
+
+/******************************************************************************
+
+	USB Bulk operation related definitions
+
+******************************************************************************/
+
+#ifdef LINUX
+#define BULKAGGRE_ZISE          100
+#define RT28XX_PUT_DEVICE							usb_put_dev
+#define RTUSB_ALLOC_URB(iso)							usb_alloc_urb(iso, GFP_ATOMIC)
+#define RTUSB_SUBMIT_URB(pUrb)							usb_submit_urb(pUrb, GFP_ATOMIC)
+#define RTUSB_URB_ALLOC_BUFFER(pUsb_Dev, BufSize, pDma_addr)			usb_buffer_alloc(pUsb_Dev, BufSize, GFP_ATOMIC, pDma_addr)
+#define RTUSB_URB_FREE_BUFFER(pUsb_Dev, BufSize, pTransferBuf, Dma_addr)	usb_buffer_free(pUsb_Dev, BufSize, pTransferBuf, Dma_addr)
+
+#define RTUSB_FREE_URB(pUrb)	usb_free_urb(pUrb)
+
+// unlink urb
+#define RTUSB_UNLINK_URB(pUrb)		usb_kill_urb(pUrb)
+
+extern void dump_urb(struct urb *purb);
+
+#define InterlockedIncrement		atomic_inc
+#define NdisInterlockedIncrement	atomic_inc
+#define InterlockedDecrement		atomic_dec
+#define NdisInterlockedDecrement	atomic_dec
+#define InterlockedExchange		atomic_set
+
+#endif // LINUX //
+
+#define NT_SUCCESS(status)			(((status) >=0) ? (TRUE):(FALSE))
+
+#define USBD_TRANSFER_DIRECTION_OUT		0
+#define USBD_TRANSFER_DIRECTION_IN		0
+#define USBD_SHORT_TRANSFER_OK			0
+#define PURB			struct urb *
+
+#define PIRP		void *
+#define NDIS_OID	u32
+#ifndef USB_ST_NOERROR
+#define USB_ST_NOERROR     0
+#endif
+
+// vendor-specific control operations
+#define CONTROL_TIMEOUT_JIFFIES ( (100 * OS_HZ) / 1000)
+#define UNLINK_TIMEOUT_MS		3
+
+void RTUSBBulkOutDataPacketComplete(struct urb *purb, struct pt_regs *pt_regs);
+void RTUSBBulkOutMLMEPacketComplete(struct urb *pUrb, struct pt_regs *pt_regs);
+void RTUSBBulkOutNullFrameComplete(struct urb *pUrb, struct pt_regs *pt_regs);
+void RTUSBBulkOutRTSFrameComplete(struct urb *pUrb, struct pt_regs *pt_regs);
+void RTUSBBulkOutPsPollComplete(struct urb *pUrb, struct pt_regs *pt_regs);
+void RTUSBBulkRxComplete(struct urb *pUrb, struct pt_regs *pt_regs);
+
+#ifdef KTHREAD_SUPPORT
+#define RTUSBMlmeUp(pAd) \
+	do{								    \
+		struct rt_rtmp_os_task *_pTask = &((pAd)->mlmeTask);\
+		if (_pTask->kthread_task) \
+        { \
+			_pTask->kthread_running = TRUE; \
+	        wake_up(&_pTask->kthread_q); \
+		} \
+	}while(0)
+#else
+#define RTUSBMlmeUp(pAd)	        \
+	do{								    \
+		struct rt_rtmp_os_task *_pTask = &((pAd)->mlmeTask);\
+		CHECK_PID_LEGALITY(_pTask->taskPID)		    \
+		{ \
+			RTMP_SEM_EVENT_UP(&(_pTask->taskSema)); \
+		}\
+	}while(0)
+#endif
+
+#ifdef KTHREAD_SUPPORT
+#define RTUSBCMDUp(pAd) \
+	do{	\
+		struct rt_rtmp_os_task *_pTask = &((pAd)->cmdQTask);	\
+		{ \
+			_pTask->kthread_running = TRUE; \
+	        wake_up(&_pTask->kthread_q); \
+		} \
+	}while(0)
+
+#else
+#define RTUSBCMDUp(pAd)	                \
+	do{									    \
+		struct rt_rtmp_os_task *_pTask = &((pAd)->cmdQTask);	\
+		CHECK_PID_LEGALITY(_pTask->taskPID)	    \
+		{\
+			RTMP_SEM_EVENT_UP(&(_pTask->taskSema)); \
+		}\
+	}while(0)
+#endif
+
+#define DEVICE_VENDOR_REQUEST_OUT       0x40
+#define DEVICE_VENDOR_REQUEST_IN        0xc0
+//#define INTERFACE_VENDOR_REQUEST_OUT    0x41
+//#define INTERFACE_VENDOR_REQUEST_IN     0xc1
+
+#define BULKOUT_MGMT_RESET_FLAG		0x80
+
+#define RTUSB_SET_BULK_FLAG(_M, _F)	((_M)->BulkFlags |= (_F))
+#define RTUSB_CLEAR_BULK_FLAG(_M, _F)	((_M)->BulkFlags &= ~(_F))
+#define RTUSB_TEST_BULK_FLAG(_M, _F)	(((_M)->BulkFlags & (_F)) != 0)
+
+#define RTMP_IRQ_REQUEST(net_dev)		do{}while(0)
+#define RTMP_IRQ_RELEASE(net_dev)		do{}while(0)
+
+#endif // __RTMP_USB_H__ //
diff --git a/drivers/staging/rt2860/md5.h b/drivers/staging/rt2860/md5.h
deleted file mode 100644
index d85db12..0000000
--- a/drivers/staging/rt2860/md5.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	md5.h
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Name		Date			Modification logs
-	jan			10-28-03		Initial
-	Rita    	11-23-04		Modify MD5 and SHA-1
-*/
-
-#ifndef	uint8
-#define	uint8  unsigned	char
-#endif
-
-#ifndef	uint32
-#define	uint32 unsigned	long int
-#endif
-
-
-#ifndef	__MD5_H__
-#define	__MD5_H__
-
-#define MD5_MAC_LEN 16
-
-typedef struct _MD5_CTX {
-    UINT32   Buf[4];             // buffers of four states
-	UCHAR   Input[64];          // input message
-	UINT32   LenInBitCount[2];   // length counter for input message, 0 up to 64 bits
-}   MD5_CTX;
-
-VOID MD5Init(MD5_CTX *pCtx);
-VOID MD5Update(MD5_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes);
-VOID MD5Final(UCHAR Digest[16], MD5_CTX *pCtx);
-VOID MD5Transform(UINT32 Buf[4], UINT32 Mes[16]);
-
-void md5_mac(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac);
-void hmac_md5(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac);
-
-//
-// SHA context
-//
-typedef	struct _SHA_CTX
-{
-	UINT32   Buf[5];             // buffers of five states
-	UCHAR   Input[80];          // input message
-	UINT32   LenInBitCount[2];   // length counter for input message, 0 up to 64 bits
-
-}	SHA_CTX;
-
-VOID SHAInit(SHA_CTX *pCtx);
-UCHAR SHAUpdate(SHA_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes);
-VOID SHAFinal(SHA_CTX *pCtx, UCHAR Digest[20]);
-VOID SHATransform(UINT32 Buf[5], UINT32 Mes[20]);
-
-#define SHA_DIGEST_LEN 20
-#endif // __MD5_H__
-
-/******************************************************************************/
-#ifndef	_AES_H
-#define	_AES_H
-
-typedef	struct
-{
-	uint32 erk[64];		/* encryption round	keys */
-	uint32 drk[64];		/* decryption round	keys */
-	int	nr;				/* number of rounds	*/
-}
-aes_context;
-
-int	 rtmp_aes_set_key( aes_context *ctx,	uint8 *key,	int	nbits );
-void rtmp_aes_encrypt( aes_context *ctx,	uint8 input[16], uint8 output[16] );
-void rtmp_aes_decrypt( aes_context *ctx,	uint8 input[16], uint8 output[16] );
-
-void F(char *password, unsigned char *ssid, int ssidlength, int iterations, int count, unsigned char *output);
-int PasswordHash(char *password, unsigned char *ssid, int ssidlength, unsigned char *output);
-
-#endif /* aes.h	*/
-
diff --git a/drivers/staging/rt2860/mlme.h b/drivers/staging/rt2860/mlme.h
index 3d1a828..1143413 100644
--- a/drivers/staging/rt2860/mlme.h
+++ b/drivers/staging/rt2860/mlme.h
@@ -39,18 +39,20 @@
 #ifndef __MLME_H__
 #define __MLME_H__
 
-// maximum supported capability information -
-// ESS, IBSS, Privacy, Short Preamble, Spectrum mgmt, Short Slot
+#include "rtmp_dot11.h"
+
+/* maximum supported capability information - */
+/* ESS, IBSS, Privacy, Short Preamble, Spectrum mgmt, Short Slot */
 #define SUPPORTED_CAPABILITY_INFO   0x0533
 
 #define END_OF_ARGS                 -1
 #define LFSR_MASK                   0x80000057
-#define MLME_TASK_EXEC_INTV         100/*200*/       //
+#define MLME_TASK_EXEC_INTV         100/*200*/	/* */
 #define LEAD_TIME                   5
-#define MLME_TASK_EXEC_MULTIPLE       10  /*5*/       // MLME_TASK_EXEC_MULTIPLE * MLME_TASK_EXEC_INTV = 1 sec
-#define REORDER_EXEC_INTV         	100       // 0.1 sec
+#define MLME_TASK_EXEC_MULTIPLE       10  /*5*/	/* MLME_TASK_EXEC_MULTIPLE * MLME_TASK_EXEC_INTV = 1 sec */
+#define REORDER_EXEC_INTV         	100	/* 0.1 sec */
 
-// The definition of Radar detection duration region
+/* The definition of Radar detection duration region */
 #define CE		0
 #define FCC		1
 #define JAP		2
@@ -58,62 +60,61 @@
 #define JAP_W56	4
 #define MAX_RD_REGION 5
 
-#ifdef	NDIS51_MINIPORT
-#define BEACON_LOST_TIME            4000       // 2048 msec = 2 sec
-#else
-#define BEACON_LOST_TIME            4 * OS_HZ    // 2048 msec = 2 sec
-#endif
+#define BEACON_LOST_TIME            4 * OS_HZ	/* 2048 msec = 2 sec */
 
-#define DLS_TIMEOUT                 1200      // unit: msec
-#define AUTH_TIMEOUT                300       // unit: msec
-#define ASSOC_TIMEOUT               300       // unit: msec
-#define JOIN_TIMEOUT                2 * OS_HZ      // unit: msec
-#define SHORT_CHANNEL_TIME          90        // unit: msec
-#define MIN_CHANNEL_TIME            110        // unit: msec, for dual band scan
-#define MAX_CHANNEL_TIME            140       // unit: msec, for single band scan
-#define	FAST_ACTIVE_SCAN_TIME	    30 		  // Active scan waiting for probe response time
-#define CW_MIN_IN_BITS              4         // actual CwMin = 2^CW_MIN_IN_BITS - 1
-#define CW_MAX_IN_BITS              10        // actual CwMax = 2^CW_MAX_IN_BITS - 1
+#define DLS_TIMEOUT                 1200	/* unit: msec */
+#define AUTH_TIMEOUT                300	/* unit: msec */
+#define ASSOC_TIMEOUT               300	/* unit: msec */
+#define JOIN_TIMEOUT                2000	/* unit: msec */
+#define SHORT_CHANNEL_TIME          90	/* unit: msec */
+#define MIN_CHANNEL_TIME            110	/* unit: msec, for dual band scan */
+#define MAX_CHANNEL_TIME            140	/* unit: msec, for single band scan */
+#define	FAST_ACTIVE_SCAN_TIME	    30	/* Active scan waiting for probe response time */
+#define CW_MIN_IN_BITS              4	/* actual CwMin = 2^CW_MIN_IN_BITS - 1 */
+#define LINK_DOWN_TIMEOUT           20000	/* unit: msec */
+#define AUTO_WAKEUP_TIMEOUT			70	/*unit: msec */
 
-// Note: RSSI_TO_DBM_OFFSET has been changed to variable for new RF (2004-0720).
-// SHould not refer to this constant anymore
-//#define RSSI_TO_DBM_OFFSET          120 // for RT2530 RSSI-115 = dBm
-#define RSSI_FOR_MID_TX_POWER       -55  // -55 db is considered mid-distance
-#define RSSI_FOR_LOW_TX_POWER       -45  // -45 db is considered very short distance and
-                                        // eligible to use a lower TX power
+#define CW_MAX_IN_BITS              10	/* actual CwMax = 2^CW_MAX_IN_BITS - 1 */
+
+/* Note: RSSI_TO_DBM_OFFSET has been changed to variable for new RF (2004-0720). */
+/* SHould not refer to this constant anymore */
+/*#define RSSI_TO_DBM_OFFSET          120 // for RT2530 RSSI-115 = dBm */
+#define RSSI_FOR_MID_TX_POWER       -55	/* -55 db is considered mid-distance */
+#define RSSI_FOR_LOW_TX_POWER       -45	/* -45 db is considered very short distance and */
+					/* eligible to use a lower TX power */
 #define RSSI_FOR_LOWEST_TX_POWER    -30
-//#define MID_TX_POWER_DELTA          0   // 0 db from full TX power upon mid-distance to AP
-#define LOW_TX_POWER_DELTA          6    // -3 db from full TX power upon very short distance. 1 grade is 0.5 db
-#define LOWEST_TX_POWER_DELTA       16   // -8 db from full TX power upon shortest distance. 1 grade is 0.5 db
+/*#define MID_TX_POWER_DELTA          0   // 0 db from full TX power upon mid-distance to AP */
+#define LOW_TX_POWER_DELTA          6	/* -3 db from full TX power upon very short distance. 1 grade is 0.5 db */
+#define LOWEST_TX_POWER_DELTA       16	/* -8 db from full TX power upon shortest distance. 1 grade is 0.5 db */
 
 #define RSSI_TRIGGERED_UPON_BELOW_THRESHOLD     0
 #define RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD   1
 #define RSSI_THRESHOLD_FOR_ROAMING              25
 #define RSSI_DELTA                              5
 
-// Channel Quality Indication
+/* Channel Quality Indication */
 #define CQI_IS_GOOD(cqi)            ((cqi) >= 50)
-//#define CQI_IS_FAIR(cqi)          (((cqi) >= 20) && ((cqi) < 50))
-#define CQI_IS_POOR(cqi)            (cqi < 50)  //(((cqi) >= 5) && ((cqi) < 20))
+/*#define CQI_IS_FAIR(cqi)          (((cqi) >= 20) && ((cqi) < 50)) */
+#define CQI_IS_POOR(cqi)            (cqi < 50)	/*(((cqi) >= 5) && ((cqi) < 20)) */
 #define CQI_IS_BAD(cqi)             (cqi < 5)
 #define CQI_IS_DEAD(cqi)            (cqi == 0)
 
-// weighting factor to calculate Channel quality, total should be 100%
+/* weighting factor to calculate Channel quality, total should be 100% */
 #define RSSI_WEIGHTING                   50
 #define TX_WEIGHTING                     30
 #define RX_WEIGHTING                     20
 
 #define BSS_NOT_FOUND                    0xFFFFFFFF
 
-#define MAX_LEN_OF_MLME_QUEUE            40 //10
+#define MAX_LEN_OF_MLME_QUEUE            40	/*10 */
 
-#define SCAN_PASSIVE                     18		// scan with no probe request, only wait beacon and probe response
-#define SCAN_ACTIVE                      19		// scan with probe request, and wait beacon and probe response
-#define	SCAN_CISCO_PASSIVE				 20		// Single channel passive scan
-#define	SCAN_CISCO_ACTIVE				 21		// Single channel active scan
-#define	SCAN_CISCO_NOISE				 22		// Single channel passive scan for noise histogram collection
-#define	SCAN_CISCO_CHANNEL_LOAD			 23		// Single channel passive scan for channel load collection
-#define FAST_SCAN_ACTIVE                 24		// scan with probe request, and wait beacon and probe response
+#define SCAN_PASSIVE                     18	/* scan with no probe request, only wait beacon and probe response */
+#define SCAN_ACTIVE                      19	/* scan with probe request, and wait beacon and probe response */
+#define	SCAN_CISCO_PASSIVE				 20	/* Single channel passive scan */
+#define	SCAN_CISCO_ACTIVE				 21	/* Single channel active scan */
+#define	SCAN_CISCO_NOISE				 22	/* Single channel passive scan for noise histogram collection */
+#define	SCAN_CISCO_CHANNEL_LOAD			 23	/* Single channel passive scan for channel load collection */
+#define FAST_SCAN_ACTIVE                 24	/* scan with probe request, and wait beacon and probe response */
 
 #define MAC_ADDR_IS_GROUP(Addr)       (((Addr[0]) & 0x01))
 #define MAC_ADDR_HASH(Addr)            (Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5])
@@ -121,13 +122,13 @@
 #define TID_MAC_HASH(Addr,TID)            (TID^Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5])
 #define TID_MAC_HASH_INDEX(Addr,TID)      (TID_MAC_HASH(Addr,TID) % HASH_TABLE_SIZE)
 
-// LED Control
-// assoiation ON. one LED ON. another blinking when TX, OFF when idle
-// no association, both LED off
+/* LED Control */
+/* assoiation ON. one LED ON. another blinking when TX, OFF when idle */
+/* no association, both LED off */
 #define ASIC_LED_ACT_ON(pAd)        RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00031e46)
 #define ASIC_LED_ACT_OFF(pAd)       RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00001e46)
 
-// bit definition of the 2-byte pBEACON->Capability field
+/* bit definition of the 2-byte pBEACON->Capability field */
 #define CAP_IS_ESS_ON(x)                 (((x) & 0x0001) != 0)
 #define CAP_IS_IBSS_ON(x)                (((x) & 0x0002) != 0)
 #define CAP_IS_CF_POLLABLE_ON(x)         (((x) & 0x0004) != 0)
@@ -136,44 +137,44 @@
 #define CAP_IS_SHORT_PREAMBLE_ON(x)      (((x) & 0x0020) != 0)
 #define CAP_IS_PBCC_ON(x)                (((x) & 0x0040) != 0)
 #define CAP_IS_AGILITY_ON(x)             (((x) & 0x0080) != 0)
-#define CAP_IS_SPECTRUM_MGMT(x)          (((x) & 0x0100) != 0)  // 802.11e d9
-#define CAP_IS_QOS(x)                    (((x) & 0x0200) != 0)  // 802.11e d9
+#define CAP_IS_SPECTRUM_MGMT(x)          (((x) & 0x0100) != 0)	/* 802.11e d9 */
+#define CAP_IS_QOS(x)                    (((x) & 0x0200) != 0)	/* 802.11e d9 */
 #define CAP_IS_SHORT_SLOT(x)             (((x) & 0x0400) != 0)
-#define CAP_IS_APSD(x)                   (((x) & 0x0800) != 0)  // 802.11e d9
-#define CAP_IS_IMMED_BA(x)               (((x) & 0x1000) != 0)  // 802.11e d9
+#define CAP_IS_APSD(x)                   (((x) & 0x0800) != 0)	/* 802.11e d9 */
+#define CAP_IS_IMMED_BA(x)               (((x) & 0x1000) != 0)	/* 802.11e d9 */
 #define CAP_IS_DSSS_OFDM(x)              (((x) & 0x2000) != 0)
-#define CAP_IS_DELAY_BA(x)               (((x) & 0x4000) != 0)  // 802.11e d9
+#define CAP_IS_DELAY_BA(x)               (((x) & 0x4000) != 0)	/* 802.11e d9 */
 
 #define CAP_GENERATE(ess,ibss,priv,s_pre,s_slot,spectrum)  (((ess) ? 0x0001 : 0x0000) | ((ibss) ? 0x0002 : 0x0000) | ((priv) ? 0x0010 : 0x0000) | ((s_pre) ? 0x0020 : 0x0000) | ((s_slot) ? 0x0400 : 0x0000) | ((spectrum) ? 0x0100 : 0x0000))
 
-#define ERP_IS_NON_ERP_PRESENT(x)        (((x) & 0x01) != 0)    // 802.11g
-#define ERP_IS_USE_PROTECTION(x)         (((x) & 0x02) != 0)    // 802.11g
-#define ERP_IS_USE_BARKER_PREAMBLE(x)    (((x) & 0x04) != 0)    // 802.11g
+#define ERP_IS_NON_ERP_PRESENT(x)        (((x) & 0x01) != 0)	/* 802.11g */
+#define ERP_IS_USE_PROTECTION(x)         (((x) & 0x02) != 0)	/* 802.11g */
+#define ERP_IS_USE_BARKER_PREAMBLE(x)    (((x) & 0x04) != 0)	/* 802.11g */
 
-#define DRS_TX_QUALITY_WORST_BOUND       8// 3  // just test by gary
+#define DRS_TX_QUALITY_WORST_BOUND       8	/* 3  // just test by gary */
 #define DRS_PENALTY                      8
 
 #define BA_NOTUSE 	2
-//BA Policy subfiled value in ADDBA frame
+/*BA Policy subfiled value in ADDBA frame */
 #define IMMED_BA 	1
 #define DELAY_BA	0
 
-// BA Initiator subfield in DELBA frame
+/* BA Initiator subfield in DELBA frame */
 #define ORIGINATOR	1
 #define RECIPIENT	0
 
-// ADDBA Status Code
+/* ADDBA Status Code */
 #define ADDBA_RESULTCODE_SUCCESS					0
 #define ADDBA_RESULTCODE_REFUSED					37
 #define ADDBA_RESULTCODE_INVALID_PARAMETERS			38
 
-// DELBA Reason Code
+/* DELBA Reason Code */
 #define DELBA_REASONCODE_QSTA_LEAVING				36
 #define DELBA_REASONCODE_END_BA						37
 #define DELBA_REASONCODE_UNKNOWN_BA					38
 #define DELBA_REASONCODE_TIMEOUT					39
 
-// reset all OneSecTx counters
+/* reset all OneSecTx counters */
 #define RESET_ONE_SEC_TX_CNT(__pEntry) \
 if (((__pEntry)) != NULL) \
 { \
@@ -182,957 +183,868 @@
 	(__pEntry)->OneSecTxNoRetryOkCount = 0; \
 }
 
-//
-// 802.11 frame formats
-//
-//  HT Capability INFO field in HT Cap IE .
-typedef struct PACKED {
-	USHORT	AdvCoding:1;
-	USHORT	ChannelWidth:1;
-	USHORT	MimoPs:2;//momi power safe
-	USHORT	GF:1;	//green field
-	USHORT	ShortGIfor20:1;
-	USHORT	ShortGIfor40:1;	//for40MHz
-	USHORT	TxSTBC:1;
-	USHORT	RxSTBC:2;
-	USHORT	DelayedBA:1;	//rt2860c not support
-	USHORT	AMsduSize:1;	// only support as zero
-	USHORT	CCKmodein40:1;
-	USHORT	PSMP:1;
-	USHORT	Forty_Mhz_Intolerant:1;
-	USHORT	LSIGTxopProSup:1;
-} HT_CAP_INFO, *PHT_CAP_INFO;
+/* */
+/* 802.11 frame formats */
+/* */
+/*  HT Capability INFO field in HT Cap IE . */
+struct PACKED rt_ht_cap_info {
+	u16 AdvCoding:1;
+	u16 ChannelWidth:1;
+	u16 MimoPs:2;	/*momi power safe */
+	u16 GF:1;		/*green field */
+	u16 ShortGIfor20:1;
+	u16 ShortGIfor40:1;	/*for40MHz */
+	u16 TxSTBC:1;
+	u16 RxSTBC:2;
+	u16 DelayedBA:1;	/*rt2860c not support */
+	u16 AMsduSize:1;	/* only support as zero */
+	u16 CCKmodein40:1;
+	u16 PSMP:1;
+	u16 Forty_Mhz_Intolerant:1;
+	u16 LSIGTxopProSup:1;
+};
 
-//  HT Capability INFO field in HT Cap IE .
-typedef struct PACKED {
-	UCHAR	MaxRAmpduFactor:2;
-	UCHAR	MpduDensity:3;
-	UCHAR	rsv:3;//momi power safe
-} HT_CAP_PARM, *PHT_CAP_PARM;
+/*  HT Capability INFO field in HT Cap IE . */
+struct PACKED rt_ht_cap_parm {
+	u8 MaxRAmpduFactor:2;
+	u8 MpduDensity:3;
+	u8 rsv:3;		/*momi power safe */
+};
 
-//  HT Capability INFO field in HT Cap IE .
-typedef struct PACKED {
-	UCHAR	MCSSet[10];
-	UCHAR	SupRate[2];  // unit : 1Mbps
-	UCHAR	TxMCSSetDefined:1;
-	UCHAR	TxRxNotEqual:1;
-	UCHAR	TxStream:2;
-	UCHAR	MpduDensity:1;
-	UCHAR	rsv:3;
-	UCHAR	rsv3[3];
-} HT_MCS_SET, *PHT_MCS_SET;
+/*  HT Capability INFO field in HT Cap IE . */
+struct PACKED rt_ht_mcs_set {
+	u8 MCSSet[10];
+	u8 SupRate[2];	/* unit : 1Mbps */
+	u8 TxMCSSetDefined:1;
+	u8 TxRxNotEqual:1;
+	u8 TxStream:2;
+	u8 MpduDensity:1;
+	u8 rsv:3;
+	u8 rsv3[3];
+};
 
-//  HT Capability INFO field in HT Cap IE .
-typedef struct PACKED {
-	USHORT	Pco:1;
-	USHORT	TranTime:2;
-	USHORT	rsv:5;//momi power safe
-	USHORT	MCSFeedback:2;	//0:no MCS feedback, 2:unsolicited MCS feedback, 3:Full MCS feedback,  1:rsv.
-	USHORT	PlusHTC:1;	//+HTC control field support
-	USHORT	RDGSupport:1;	//reverse Direction Grant  support
-	USHORT	rsv2:4;
-} EXT_HT_CAP_INFO, *PEXT_HT_CAP_INFO;
+/*  HT Capability INFO field in HT Cap IE . */
+struct PACKED rt_ext_ht_cap_info {
+	u16 Pco:1;
+	u16 TranTime:2;
+	u16 rsv:5;		/*momi power safe */
+	u16 MCSFeedback:2;	/*0:no MCS feedback, 2:unsolicited MCS feedback, 3:Full MCS feedback,  1:rsv. */
+	u16 PlusHTC:1;	/*+HTC control field support */
+	u16 RDGSupport:1;	/*reverse Direction Grant  support */
+	u16 rsv2:4;
+};
 
-//  HT Beamforming field in HT Cap IE .
-typedef struct PACKED _HT_BF_CAP{
-	ULONG	TxBFRecCapable:1;
-	ULONG	RxSoundCapable:1;
-	ULONG	TxSoundCapable:1;
-	ULONG	RxNDPCapable:1;
-	ULONG	TxNDPCapable:1;
-	ULONG	ImpTxBFCapable:1;
-	ULONG	Calibration:2;
-	ULONG	ExpCSICapable:1;
-	ULONG	ExpNoComSteerCapable:1;
-	ULONG	ExpComSteerCapable:1;
-	ULONG	ExpCSIFbk:2;
-	ULONG	ExpNoComBF:2;
-	ULONG	ExpComBF:2;
-	ULONG	MinGrouping:2;
-	ULONG	CSIBFAntSup:2;
-	ULONG	NoComSteerBFAntSup:2;
-	ULONG	ComSteerBFAntSup:2;
-	ULONG	CSIRowBFSup:2;
-	ULONG	ChanEstimation:2;
-	ULONG	rsv:3;
-} HT_BF_CAP, *PHT_BF_CAP;
+/*  HT Beamforming field in HT Cap IE . */
+struct PACKED rt_ht_bf_cap {
+	unsigned long TxBFRecCapable:1;
+	unsigned long RxSoundCapable:1;
+	unsigned long TxSoundCapable:1;
+	unsigned long RxNDPCapable:1;
+	unsigned long TxNDPCapable:1;
+	unsigned long ImpTxBFCapable:1;
+	unsigned long Calibration:2;
+	unsigned long ExpCSICapable:1;
+	unsigned long ExpNoComSteerCapable:1;
+	unsigned long ExpComSteerCapable:1;
+	unsigned long ExpCSIFbk:2;
+	unsigned long ExpNoComBF:2;
+	unsigned long ExpComBF:2;
+	unsigned long MinGrouping:2;
+	unsigned long CSIBFAntSup:2;
+	unsigned long NoComSteerBFAntSup:2;
+	unsigned long ComSteerBFAntSup:2;
+	unsigned long CSIRowBFSup:2;
+	unsigned long ChanEstimation:2;
+	unsigned long rsv:3;
+};
 
-//  HT antenna selection field in HT Cap IE .
-typedef struct PACKED _HT_AS_CAP{
-	UCHAR	AntSelect:1;
-	UCHAR	ExpCSIFbkTxASEL:1;
-	UCHAR	AntIndFbkTxASEL:1;
-	UCHAR	ExpCSIFbk:1;
-	UCHAR	AntIndFbk:1;
-	UCHAR	RxASel:1;
-	UCHAR	TxSoundPPDU:1;
-	UCHAR	rsv:1;
-} HT_AS_CAP, *PHT_AS_CAP;
+/*  HT antenna selection field in HT Cap IE . */
+struct PACKED rt_ht_as_cap {
+	u8 AntSelect:1;
+	u8 ExpCSIFbkTxASEL:1;
+	u8 AntIndFbkTxASEL:1;
+	u8 ExpCSIFbk:1;
+	u8 AntIndFbk:1;
+	u8 RxASel:1;
+	u8 TxSoundPPDU:1;
+	u8 rsv:1;
+};
 
-// Draft 1.0 set IE length 26, but is extensible..
+/* Draft 1.0 set IE length 26, but is extensible.. */
 #define SIZE_HT_CAP_IE		26
-// The structure for HT Capability IE.
-typedef struct PACKED _HT_CAPABILITY_IE{
-	HT_CAP_INFO		HtCapInfo;
-	HT_CAP_PARM		HtCapParm;
-//	HT_MCS_SET		HtMCSSet;
-	UCHAR			MCSSet[16];
-	EXT_HT_CAP_INFO	ExtHtCapInfo;
-	HT_BF_CAP		TxBFCap;	// beamforming cap. rt2860c not support beamforming.
-	HT_AS_CAP		ASCap;	//antenna selection.
-} HT_CAPABILITY_IE, *PHT_CAPABILITY_IE;
+/* The structure for HT Capability IE. */
+struct PACKED rt_ht_capability_ie {
+	struct rt_ht_cap_info HtCapInfo;
+	struct rt_ht_cap_parm HtCapParm;
+/*      struct rt_ht_mcs_set              HtMCSSet; */
+	u8 MCSSet[16];
+	struct rt_ext_ht_cap_info ExtHtCapInfo;
+	struct rt_ht_bf_cap TxBFCap;	/* beamforming cap. rt2860c not support beamforming. */
+	struct rt_ht_as_cap ASCap;	/*antenna selection. */
+};
 
+/* 802.11n draft3 related structure definitions. */
+/* 7.3.2.60 */
+#define dot11OBSSScanPassiveDwell							20	/* in TU. min amount of time that the STA continously scans each channel when performing an active OBSS scan. */
+#define dot11OBSSScanActiveDwell							10	/* in TU.min amount of time that the STA continously scans each channel when performing an passive OBSS scan. */
+#define dot11BSSWidthTriggerScanInterval					300	/* in sec. max interval between scan operations to be performed to detect BSS channel width trigger events. */
+#define dot11OBSSScanPassiveTotalPerChannel					200	/* in TU. min total amount of time that the STA scans each channel when performing a passive OBSS scan. */
+#define dot11OBSSScanActiveTotalPerChannel					20	/*in TU. min total amount of time that the STA scans each channel when performing a active OBSS scan */
+#define dot11BSSWidthChannelTransactionDelayFactor			5	/* min ratio between the delay time in performing a switch from 20MHz BSS to 20/40 BSS operation and the maximum */
+																/*      interval between overlapping BSS scan operations. */
+#define dot11BSSScanActivityThreshold						25	/* in %%, max total time that a STA may be active on the medium during a period of */
+																/*      (dot11BSSWidthChannelTransactionDelayFactor * dot11BSSWidthTriggerScanInterval) seconds without */
+																/*      being obligated to perform OBSS Scan operations. default is 25(== 0.25%) */
 
-// 802.11n draft3 related structure definitions.
-// 7.3.2.60
-#define dot11OBSSScanPassiveDwell							20	// in TU. min amount of time that the STA continously scans each channel when performing an active OBSS scan.
-#define dot11OBSSScanActiveDwell							10	// in TU.min amount of time that the STA continously scans each channel when performing an passive OBSS scan.
-#define dot11BSSWidthTriggerScanInterval					300  // in sec. max interval between scan operations to be performed to detect BSS channel width trigger events.
-#define dot11OBSSScanPassiveTotalPerChannel					200	// in TU. min total amount of time that the STA scans each channel when performing a passive OBSS scan.
-#define dot11OBSSScanActiveTotalPerChannel					20	//in TU. min total amount of time that the STA scans each channel when performing a active OBSS scan
-#define dot11BSSWidthChannelTransactionDelayFactor			5	// min ratio between the delay time in performing a switch from 20MHz BSS to 20/40 BSS operation and the maxima
-																//	interval between overlapping BSS scan operations.
-#define dot11BSSScanActivityThreshold						25	// in %%, max total time that a STA may be active on the medium during a period of
-																//	(dot11BSSWidthChannelTransactionDelayFactor * dot11BSSWidthTriggerScanInterval) seconds without
-																//	being obligated to perform OBSS Scan operations. default is 25(== 0.25%)
+struct PACKED rt_overlap_bss_scan_ie {
+	u16 ScanPassiveDwell;
+	u16 ScanActiveDwell;
+	u16 TriggerScanInt;	/* Trigger scan interval */
+	u16 PassiveTalPerChannel;	/* passive total per channel */
+	u16 ActiveTalPerChannel;	/* active total per channel */
+	u16 DelayFactor;	/* BSS width channel transition delay factor */
+	u16 ScanActThre;	/* Scan Activity threshold */
+};
 
-typedef struct PACKED _OVERLAP_BSS_SCAN_IE{
-	USHORT		ScanPassiveDwell;
-	USHORT		ScanActiveDwell;
-	USHORT		TriggerScanInt;				// Trigger scan interval
-	USHORT		PassiveTalPerChannel;		// passive total per channel
-	USHORT		ActiveTalPerChannel;		// active total per channel
-	USHORT		DelayFactor;				// BSS width channel transition delay factor
-	USHORT		ScanActThre;				// Scan Activity threshold
-}OVERLAP_BSS_SCAN_IE, *POVERLAP_BSS_SCAN_IE;
-
-
-//  7.3.2.56. 20/40 Coexistence element used in  Element ID = 72 = IE_2040_BSS_COEXIST
-typedef union PACKED _BSS_2040_COEXIST_IE{
- struct PACKED {
-	UCHAR	InfoReq:1;
-	UCHAR	Intolerant40:1;			// Inter-BSS. set 1 when prohibits a receiving BSS from operating as a 20/40 Mhz BSS.
-	UCHAR	BSS20WidthReq:1;		// Intra-BSS set 1 when prohibits a receiving AP from operating its BSS as a 20/40MHz BSS.
-	UCHAR	rsv:5;
-    } field;
- UCHAR   word;
+/*  7.3.2.56. 20/40 Coexistence element used in  Element ID = 72 = IE_2040_BSS_COEXIST */
+typedef union PACKED _BSS_2040_COEXIST_IE {
+	struct PACKED {
+		u8 InfoReq:1;
+		u8 Intolerant40:1;	/* Inter-BSS. set 1 when prohibits a receiving BSS from operating as a 20/40 Mhz BSS. */
+		u8 BSS20WidthReq:1;	/* Intra-BSS set 1 when prohibits a receiving AP from operating its BSS as a 20/40MHz BSS. */
+		u8 rsv:5;
+	} field;
+	u8 word;
 } BSS_2040_COEXIST_IE, *PBSS_2040_COEXIST_IE;
 
+struct rt_trigger_eventa {
+	BOOLEAN bValid;
+	u8 BSSID[6];
+	u8 RegClass;		/* Regulatory Class */
+	u16 Channel;
+	unsigned long CDCounter;	/* Maintain a seperate count down counter for each Event A. */
+};
 
-typedef struct  _TRIGGER_EVENTA{
-	BOOLEAN			bValid;
-	UCHAR	BSSID[6];
-	UCHAR	RegClass;	// Regulatory Class
-	USHORT	Channel;
-	ULONG	CDCounter;   // Maintain a seperate count down counter for each Event A.
-} TRIGGER_EVENTA, *PTRIGGER_EVENTA;
-
-// 20/40 trigger event table
-// If one Event A delete or created, or if Event B is detected or not detected, STA should send 2040BSSCoexistence to AP.
+/* 20/40 trigger event table */
+/* If one Event A delete or created, or if Event B is detected or not detected, STA should send 2040BSSCoexistence to AP. */
 #define MAX_TRIGGER_EVENT		64
-typedef struct  _TRIGGER_EVENT_TAB{
-	UCHAR	EventANo;
-	TRIGGER_EVENTA	EventA[MAX_TRIGGER_EVENT];
-	ULONG			EventBCountDown;	// Count down counter for Event B.
-} TRIGGER_EVENT_TAB, *PTRIGGER_EVENT_TAB;
+struct rt_trigger_event_tab {
+	u8 EventANo;
+	struct rt_trigger_eventa EventA[MAX_TRIGGER_EVENT];
+	unsigned long EventBCountDown;	/* Count down counter for Event B. */
+};
 
-// 7.3.27 20/40 Bss Coexistence Mgmt capability used in extended capabilities information IE( ID = 127 = IE_EXT_CAPABILITY).
-//	This is the first octet and was defined in 802.11n D3.03 and 802.11yD9.0
-typedef struct PACKED _EXT_CAP_INFO_ELEMENT{
-	UCHAR	BssCoexistMgmtSupport:1;
-	UCHAR	rsv:1;
-	UCHAR	ExtendChannelSwitch:1;
-	UCHAR	rsv2:5;
-}EXT_CAP_INFO_ELEMENT, *PEXT_CAP_INFO_ELEMENT;
+/* 7.3.27 20/40 Bss Coexistence Mgmt capability used in extended capabilities information IE( ID = 127 = IE_EXT_CAPABILITY). */
+/*      This is the first octet and was defined in 802.11n D3.03 and 802.11yD9.0 */
+struct PACKED rt_ext_cap_info_element {
+	u8 BssCoexistMgmtSupport:1;
+	u8 rsv:1;
+	u8 ExtendChannelSwitch:1;
+	u8 rsv2:5;
+};
 
+/* 802.11n 7.3.2.61 */
+struct PACKED rt_bss_2040_coexist_element {
+	u8 ElementID;	/* ID = IE_2040_BSS_COEXIST = 72 */
+	u8 Len;
+	BSS_2040_COEXIST_IE BssCoexistIe;
+};
 
-// 802.11n 7.3.2.61
-typedef struct PACKED _BSS_2040_COEXIST_ELEMENT{
-	UCHAR					ElementID;		// ID = IE_2040_BSS_COEXIST = 72
-	UCHAR					Len;
-	BSS_2040_COEXIST_IE		BssCoexistIe;
-}BSS_2040_COEXIST_ELEMENT, *PBSS_2040_COEXIST_ELEMENT;
+/*802.11n 7.3.2.59 */
+struct PACKED rt_bss_2040_intolerant_ch_report {
+	u8 ElementID;	/* ID = IE_2040_BSS_INTOLERANT_REPORT = 73 */
+	u8 Len;
+	u8 RegulatoryClass;
+	u8 ChList[0];
+};
 
+/* The structure for channel switch annoucement IE. This is in 802.11n D3.03 */
+struct PACKED rt_cha_switch_announce_ie {
+	u8 SwitchMode;	/*channel switch mode */
+	u8 NewChannel;	/* */
+	u8 SwitchCount;	/* */
+};
 
-//802.11n 7.3.2.59
-typedef struct PACKED _BSS_2040_INTOLERANT_CH_REPORT{
-	UCHAR				ElementID;		// ID = IE_2040_BSS_INTOLERANT_REPORT = 73
-	UCHAR				Len;
-	UCHAR				RegulatoryClass;
-	UCHAR				ChList[0];
-}BSS_2040_INTOLERANT_CH_REPORT, *PBSS_2040_INTOLERANT_CH_REPORT;
+/* The structure for channel switch annoucement IE. This is in 802.11n D3.03 */
+struct PACKED rt_sec_cha_offset_ie {
+	u8 SecondaryChannelOffset;	/* 1: Secondary above, 3: Secondary below, 0: no Secondary */
+};
 
+/* This structure is extracted from struct struct rt_ht_capability */
+struct rt_ht_phy_info {
+	BOOLEAN bHtEnable;	/* If we should use ht rate. */
+	BOOLEAN bPreNHt;	/* If we should use ht rate. */
+	/*Substract from HT Capability IE */
+	u8 MCSSet[16];
+};
 
-// The structure for channel switch annoucement IE. This is in 802.11n D3.03
-typedef struct PACKED _CHA_SWITCH_ANNOUNCE_IE{
-	UCHAR			SwitchMode;	//channel switch mode
-	UCHAR			NewChannel;	//
-	UCHAR			SwitchCount;	//
-} CHA_SWITCH_ANNOUNCE_IE, *PCHA_SWITCH_ANNOUNCE_IE;
+/*This structure substracts ralink supports from all 802.11n-related features. */
+/*Features not listed here but contained in 802.11n spec are not supported in rt2860. */
+struct rt_ht_capability {
+	u16 ChannelWidth:1;
+	u16 MimoPs:2;	/*mimo power safe MMPS_ */
+	u16 GF:1;		/*green field */
+	u16 ShortGIfor20:1;
+	u16 ShortGIfor40:1;	/*for40MHz */
+	u16 TxSTBC:1;
+	u16 RxSTBC:2;	/* 2 bits */
+	u16 AmsduEnable:1;	/* Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benifit of 802.11n */
+	u16 AmsduSize:1;	/* Max receiving A-MSDU size */
+	u16 rsv:5;
 
+	/*Substract from Addiont HT INFO IE */
+	u8 MaxRAmpduFactor:2;
+	u8 MpduDensity:3;
+	u8 ExtChanOffset:2;	/* Please not the difference with following     u8   NewExtChannelOffset; from 802.11n */
+	u8 RecomWidth:1;
 
-// The structure for channel switch annoucement IE. This is in 802.11n D3.03
-typedef struct PACKED _SEC_CHA_OFFSET_IE{
-	UCHAR			SecondaryChannelOffset;	 // 1: Secondary above, 3: Secondary below, 0: no Secondary
-} SEC_CHA_OFFSET_IE, *PSEC_CHA_OFFSET_IE;
+	u16 OperaionMode:2;
+	u16 NonGfPresent:1;
+	u16 rsv3:1;
+	u16 OBSS_NonHTExist:1;
+	u16 rsv2:11;
 
+	/* New Extension Channel Offset IE */
+	u8 NewExtChannelOffset;
+	/* Extension Capability IE = 127 */
+	u8 BSSCoexist2040;
+};
 
-// This structure is extracted from struct RT_HT_CAPABILITY
-typedef struct {
-	BOOLEAN			bHtEnable;	 // If we should use ht rate.
-	BOOLEAN			bPreNHt;	 // If we should use ht rate.
-	//Substract from HT Capability IE
-	UCHAR			MCSSet[16];	//only supoort MCS=0-15,32 ,
-} RT_HT_PHY_INFO, *PRT_HT_PHY_INFO;
+/*   field in Addtional HT Information IE . */
+struct PACKED rt_add_htinfo {
+	u8 ExtChanOffset:2;
+	u8 RecomWidth:1;
+	u8 RifsMode:1;
+	u8 S_PSMPSup:1;	/*Indicate support for scheduled PSMP */
+	u8 SerInterGranu:3;	/*service interval granularity */
+};
 
-//This structure substracts ralink supports from all 802.11n-related features.
-//Features not listed here but contained in 802.11n spec are not supported in rt2860.
-typedef struct {
-	USHORT	ChannelWidth:1;
-	USHORT	MimoPs:2;//mimo power safe MMPS_
-	USHORT	GF:1;	//green field
-	USHORT	ShortGIfor20:1;
-	USHORT	ShortGIfor40:1;	//for40MHz
-	USHORT	TxSTBC:1;
-	USHORT	RxSTBC:2;	// 2 bits
-	USHORT	AmsduEnable:1;	// Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benifit of 802.11n
-	USHORT	AmsduSize:1;	// Max receiving A-MSDU size
-	USHORT	rsv:5;
+struct PACKED rt_add_htinfo2 {
+	u16 OperaionMode:2;
+	u16 NonGfPresent:1;
+	u16 rsv:1;
+	u16 OBSS_NonHTExist:1;
+	u16 rsv2:11;
+};
 
-	//Substract from Addiont HT INFO IE
-	UCHAR	MaxRAmpduFactor:2;
-	UCHAR	MpduDensity:3;
-	UCHAR	ExtChanOffset:2;	// Please not the difference with following 	UCHAR	NewExtChannelOffset; from 802.11n
-	UCHAR	RecomWidth:1;
-
-	USHORT	OperaionMode:2;
-	USHORT	NonGfPresent:1;
-	USHORT	rsv3:1;
-	USHORT	OBSS_NonHTExist:1;
-	USHORT	rsv2:11;
-
-	// New Extension Channel Offset IE
-	UCHAR	NewExtChannelOffset;
-	// Extension Capability IE = 127
-	UCHAR	BSSCoexist2040;
-} RT_HT_CAPABILITY, *PRT_HT_CAPABILITY;
-
-//   field in Addtional HT Information IE .
-typedef struct PACKED {
-	UCHAR	ExtChanOffset:2;
-	UCHAR	RecomWidth:1;
-	UCHAR	RifsMode:1;
-	UCHAR	S_PSMPSup:1;	 //Indicate support for scheduled PSMP
-	UCHAR	SerInterGranu:3;	 //service interval granularity
-} ADD_HTINFO, *PADD_HTINFO;
-
-typedef struct PACKED{
-	USHORT	OperaionMode:2;
-	USHORT	NonGfPresent:1;
-	USHORT	rsv:1;
-	USHORT	OBSS_NonHTExist:1;
-	USHORT	rsv2:11;
-} ADD_HTINFO2, *PADD_HTINFO2;
-
-
-// TODO: Need sync with spec about the definition of StbcMcs. In Draft 3.03, it's reserved.
-typedef struct PACKED{
-	USHORT	StbcMcs:6;
-	USHORT	DualBeacon:1;
-	USHORT	DualCTSProtect:1;
-	USHORT	STBCBeacon:1;
-	USHORT	LsigTxopProt:1;	// L-SIG TXOP protection full support
-	USHORT	PcoActive:1;
-	USHORT	PcoPhase:1;
-	USHORT	rsv:4;
-} ADD_HTINFO3, *PADD_HTINFO3;
+/* TODO: Need sync with spec about the definition of StbcMcs. In Draft 3.03, it's reserved. */
+struct PACKED rt_add_htinfo3 {
+	u16 StbcMcs:6;
+	u16 DualBeacon:1;
+	u16 DualCTSProtect:1;
+	u16 STBCBeacon:1;
+	u16 LsigTxopProt:1;	/* L-SIG TXOP protection full support */
+	u16 PcoActive:1;
+	u16 PcoPhase:1;
+	u16 rsv:4;
+};
 
 #define SIZE_ADD_HT_INFO_IE		22
-typedef struct  PACKED{
-	UCHAR				ControlChan;
-	ADD_HTINFO			AddHtInfo;
-	ADD_HTINFO2			AddHtInfo2;
-	ADD_HTINFO3			AddHtInfo3;
-	UCHAR				MCSSet[16];		// Basic MCS set
-} ADD_HT_INFO_IE, *PADD_HT_INFO_IE;
+struct PACKED rt_add_ht_info_ie {
+	u8 ControlChan;
+	struct rt_add_htinfo AddHtInfo;
+	struct rt_add_htinfo2 AddHtInfo2;
+	struct rt_add_htinfo3 AddHtInfo3;
+	u8 MCSSet[16];	/* Basic MCS set */
+};
 
-typedef struct  PACKED{
-	UCHAR				NewExtChanOffset;
-} NEW_EXT_CHAN_IE, *PNEW_EXT_CHAN_IE;
+struct PACKED rt_new_ext_chan_ie {
+	u8 NewExtChanOffset;
+};
 
+struct PACKED rt_frame_802_11 {
+	struct rt_header_802_11 Hdr;
+	u8 Octet[1];
+};
 
-// 4-byte HTC field.  maybe included in any frame except non-QOS data frame.  The Order bit must set 1.
-typedef struct PACKED {
-    UINT32		MA:1;	//management action payload exist in (QoS Null+HTC)
-    UINT32		TRQ:1;	//sounding request
-    UINT32		MRQ:1;	//MCS feedback. Request for a MCS feedback
-    UINT32		MRSorASI:3;	// MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110.
-    UINT32		MFS:3;	//SET to the received value of MRS. 0x111 for unsolicited MFB.
-    UINT32		MFBorASC:7;	//Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available
-    UINT32		CalPos:2;	// calibration position
-    UINT32		CalSeq:2;  //calibration sequence
-    UINT32		FBKReq:2;	//feedback request
-    UINT32		CSISTEERING:2;	//CSI/ STEERING
-    UINT32		ZLFAnnouce:1;	// ZLF announcement
-    UINT32		rsv:5;  //calibration sequence
-    UINT32		ACConstraint:1;	//feedback request
-    UINT32		RDG:1;	//RDG / More PPDU
-} HT_CONTROL, *PHT_CONTROL;
+/* QoSNull embedding of management action. When HT Control MA field set to 1. */
+struct PACKED rt_ma_body {
+	u8 Category;
+	u8 Action;
+	u8 Octet[1];
+};
 
-// 2-byte QOS CONTROL field
-typedef struct PACKED {
-    USHORT      TID:4;
-    USHORT      EOSP:1;
-    USHORT      AckPolicy:2;  //0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP  3: BA
-    USHORT      AMsduPresent:1;
-    USHORT      Txop_QueueSize:8;
-} QOS_CONTROL, *PQOS_CONTROL;
+struct PACKED rt_header_802_3 {
+	u8 DAAddr1[MAC_ADDR_LEN];
+	u8 SAAddr2[MAC_ADDR_LEN];
+	u8 Octet[2];
+};
+/*//Block ACK related format */
+/* 2-byte BA Parameter  field  in       DELBA frames to terminate an already set up bA */
+struct PACKED rt_delba_parm {
+	u16 Rsv:11;		/* always set to 0 */
+	u16 Initiator:1;	/* 1: originator    0:recipient */
+	u16 TID:4;		/* value of TC os TS */
+};
 
-// 2-byte Frame control field
-typedef	struct	PACKED {
-	USHORT		Ver:2;				// Protocol version
-	USHORT		Type:2;				// MSDU type
-	USHORT		SubType:4;			// MSDU subtype
-	USHORT		ToDs:1;				// To DS indication
-	USHORT		FrDs:1;				// From DS indication
-	USHORT		MoreFrag:1;			// More fragment bit
-	USHORT		Retry:1;			// Retry status bit
-	USHORT		PwrMgmt:1;			// Power management bit
-	USHORT		MoreData:1;			// More data bit
-	USHORT		Wep:1;				// Wep data
-	USHORT		Order:1;			// Strict order expected
-} FRAME_CONTROL, *PFRAME_CONTROL;
+/* 2-byte BA Parameter Set field  in ADDBA frames to signal parm for setting up a BA */
+struct PACKED rt_ba_parm {
+	u16 AMSDUSupported:1;	/* 0: not permitted             1: permitted */
+	u16 BAPolicy:1;	/* 1: immediately BA    0:delayed BA */
+	u16 TID:4;		/* value of TC os TS */
+	u16 BufSize:10;	/* number of buffe of size 2304 octetsr */
+};
 
-typedef	struct	PACKED _HEADER_802_11	{
-    FRAME_CONTROL   FC;
-    USHORT          Duration;
-    UCHAR           Addr1[MAC_ADDR_LEN];
-    UCHAR           Addr2[MAC_ADDR_LEN];
-	UCHAR			Addr3[MAC_ADDR_LEN];
-	USHORT			Frag:4;
-	USHORT			Sequence:12;
-	UCHAR			Octet[0];
-}	HEADER_802_11, *PHEADER_802_11;
-
-typedef struct PACKED _FRAME_802_11 {
-    HEADER_802_11   Hdr;
-    UCHAR            Octet[1];
-}   FRAME_802_11, *PFRAME_802_11;
-
-// QoSNull embedding of management action. When HT Control MA field set to 1.
-typedef struct PACKED _MA_BODY {
-    UCHAR            Category;
-    UCHAR            Action;
-    UCHAR            Octet[1];
-}   MA_BODY, *PMA_BODY;
-
-typedef	struct	PACKED _HEADER_802_3	{
-    UCHAR           DAAddr1[MAC_ADDR_LEN];
-    UCHAR           SAAddr2[MAC_ADDR_LEN];
-    UCHAR           Octet[2];
-}	HEADER_802_3, *PHEADER_802_3;
-////Block ACK related format
-// 2-byte BA Parameter  field  in 	DELBA frames to terminate an already set up bA
-typedef struct PACKED{
-    USHORT      Rsv:11;	// always set to 0
-    USHORT      Initiator:1;	// 1: originator    0:recipient
-    USHORT      TID:4;	// value of TC os TS
-} DELBA_PARM, *PDELBA_PARM;
-
-// 2-byte BA Parameter Set field  in ADDBA frames to signal parm for setting up a BA
-typedef struct PACKED {
-    USHORT      AMSDUSupported:1;	// 0: not permitted		1: permitted
-    USHORT      BAPolicy:1;	// 1: immediately BA    0:delayed BA
-    USHORT      TID:4;	// value of TC os TS
-    USHORT      BufSize:10;	// number of buffe of size 2304 octetsr
-} BA_PARM, *PBA_PARM;
-
-// 2-byte BA Starting Seq CONTROL field
-typedef union PACKED {
-    struct PACKED {
-    USHORT      FragNum:4;	// always set to 0
-	USHORT      StartSeq:12;   // sequence number of the 1st MSDU for which this BAR is sent
-    }   field;
-    USHORT           word;
+/* 2-byte BA Starting Seq CONTROL field */
+typedef union PACKED _BASEQ_CONTROL {
+	struct PACKED {
+		u16 FragNum:4;	/* always set to 0 */
+		u16 StartSeq:12;	/* sequence number of the 1st MSDU for which this BAR is sent */
+	} field;
+	u16 word;
 } BASEQ_CONTROL, *PBASEQ_CONTROL;
 
-//BAControl and BARControl are the same
-// 2-byte BA CONTROL field in BA frame
-typedef struct PACKED {
-    USHORT      ACKPolicy:1; // only related to N-Delayed BA. But not support in RT2860b. 0:NormalACK  1:No ACK
-    USHORT      MTID:1;		//EWC V1.24
-    USHORT      Compressed:1;
-    USHORT      Rsv:9;
-    USHORT      TID:4;
-} BA_CONTROL, *PBA_CONTROL;
+/*BAControl and BARControl are the same */
+/* 2-byte BA CONTROL field in BA frame */
+struct PACKED rt_ba_control {
+	u16 ACKPolicy:1;	/* only related to N-Delayed BA. But not support in RT2860b. 0:NormalACK  1:No ACK */
+	u16 MTID:1;		/*EWC V1.24 */
+	u16 Compressed:1;
+	u16 Rsv:9;
+	u16 TID:4;
+};
 
-// 2-byte BAR CONTROL field in BAR frame
-typedef struct PACKED {
-    USHORT      ACKPolicy:1; // 0:normal ack,  1:no ack.
-    USHORT      MTID:1;		//if this bit1, use  FRAME_MTBA_REQ,  if 0, use FRAME_BA_REQ
-    USHORT      Compressed:1;
-    USHORT      Rsv1:9;
-    USHORT      TID:4;
-} BAR_CONTROL, *PBAR_CONTROL;
+/* 2-byte BAR CONTROL field in BAR frame */
+struct PACKED rt_bar_control {
+	u16 ACKPolicy:1;	/* 0:normal ack,  1:no ack. */
+	u16 MTID:1;		/*if this bit1, use  struct rt_frame_mtba_req,  if 0, use struct rt_frame_ba_req */
+	u16 Compressed:1;
+	u16 Rsv1:9;
+	u16 TID:4;
+};
 
-// BARControl in MTBAR frame
-typedef struct PACKED {
-    USHORT      ACKPolicy:1;
-    USHORT      MTID:1;
-    USHORT      Compressed:1;
-    USHORT      Rsv1:9;
-    USHORT      NumTID:4;
-} MTBAR_CONTROL, *PMTBAR_CONTROL;
+/* BARControl in MTBAR frame */
+struct PACKED rt_mtbar_control {
+	u16 ACKPolicy:1;
+	u16 MTID:1;
+	u16 Compressed:1;
+	u16 Rsv1:9;
+	u16 NumTID:4;
+};
 
-typedef struct PACKED {
-    USHORT      Rsv1:12;
-    USHORT      TID:4;
-} PER_TID_INFO, *PPER_TID_INFO;
+struct PACKED rt_per_tid_info {
+	u16 Rsv1:12;
+	u16 TID:4;
+};
 
-typedef struct {
-	PER_TID_INFO      PerTID;
-	BASEQ_CONTROL 	 BAStartingSeq;
-} EACH_TID, *PEACH_TID;
+struct rt_each_tid {
+	struct rt_per_tid_info PerTID;
+	BASEQ_CONTROL BAStartingSeq;
+};
 
+/* BAREQ AND MTBAREQ have the same subtype BAR, 802.11n BAR use compressed bitmap. */
+struct PACKED rt_frame_ba_req {
+	struct rt_frame_control FC;
+	u16 Duration;
+	u8 Addr1[MAC_ADDR_LEN];
+	u8 Addr2[MAC_ADDR_LEN];
+	struct rt_bar_control BARControl;
+	BASEQ_CONTROL BAStartingSeq;
+};
 
-typedef struct PACKED _PSPOLL_FRAME {
-    FRAME_CONTROL   FC;
-    USHORT          Aid;
-    UCHAR           Bssid[MAC_ADDR_LEN];
-    UCHAR           Ta[MAC_ADDR_LEN];
-}   PSPOLL_FRAME, *PPSPOLL_FRAME;
+struct PACKED rt_frame_mtba_req {
+	struct rt_frame_control FC;
+	u16 Duration;
+	u8 Addr1[MAC_ADDR_LEN];
+	u8 Addr2[MAC_ADDR_LEN];
+	struct rt_mtbar_control MTBARControl;
+	struct rt_per_tid_info PerTIDInfo;
+	BASEQ_CONTROL BAStartingSeq;
+};
 
-typedef	struct	PACKED _RTS_FRAME	{
-    FRAME_CONTROL   FC;
-    USHORT          Duration;
-    UCHAR           Addr1[MAC_ADDR_LEN];
-    UCHAR           Addr2[MAC_ADDR_LEN];
-}RTS_FRAME, *PRTS_FRAME;
+/* Compressed format is mandantory in HT STA */
+struct PACKED rt_frame_mtba {
+	struct rt_frame_control FC;
+	u16 Duration;
+	u8 Addr1[MAC_ADDR_LEN];
+	u8 Addr2[MAC_ADDR_LEN];
+	struct rt_ba_control BAControl;
+	BASEQ_CONTROL BAStartingSeq;
+	u8 BitMap[8];
+};
 
-// BAREQ AND MTBAREQ have the same subtype BAR, 802.11n BAR use compressed bitmap.
-typedef struct PACKED _FRAME_BA_REQ {
-	FRAME_CONTROL   FC;
-	USHORT          Duration;
-	UCHAR           Addr1[MAC_ADDR_LEN];
-	UCHAR           Addr2[MAC_ADDR_LEN];
-	BAR_CONTROL  BARControl;
-	BASEQ_CONTROL 	 BAStartingSeq;
-}   FRAME_BA_REQ, *PFRAME_BA_REQ;
+struct PACKED rt_frame_psmp_action {
+	struct rt_header_802_11 Hdr;
+	u8 Category;
+	u8 Action;
+	u8 Psmp;		/* 7.3.1.25 */
+};
 
-typedef struct PACKED _FRAME_MTBA_REQ {
-	FRAME_CONTROL   FC;
-	USHORT          Duration;
-	UCHAR           Addr1[MAC_ADDR_LEN];
-	UCHAR           Addr2[MAC_ADDR_LEN];
-	MTBAR_CONTROL  MTBARControl;
-	PER_TID_INFO	PerTIDInfo;
-	BASEQ_CONTROL 	 BAStartingSeq;
-}   FRAME_MTBA_REQ, *PFRAME_MTBA_REQ;
+struct PACKED rt_frame_action_hdr {
+	struct rt_header_802_11 Hdr;
+	u8 Category;
+	u8 Action;
+};
 
-// Compressed format is mandantory in HT STA
-typedef struct PACKED _FRAME_MTBA {
-	FRAME_CONTROL   FC;
-	USHORT          Duration;
-	UCHAR           Addr1[MAC_ADDR_LEN];
-	UCHAR           Addr2[MAC_ADDR_LEN];
-	BA_CONTROL  BAControl;
-	BASEQ_CONTROL 	 BAStartingSeq;
-	UCHAR		BitMap[8];
-}   FRAME_MTBA, *PFRAME_MTBA;
+/*Action Frame */
+/*Action Frame  Category:Spectrum,  Action:Channel Switch. 7.3.2.20 */
+struct PACKED rt_chan_switch_announce {
+	u8 ElementID;	/* ID = IE_CHANNEL_SWITCH_ANNOUNCEMENT = 37 */
+	u8 Len;
+	struct rt_cha_switch_announce_ie CSAnnounceIe;
+};
 
-typedef struct PACKED _FRAME_PSMP_ACTION {
-	HEADER_802_11   Hdr;
-	UCHAR	Category;
-	UCHAR	Action;
-	UCHAR	Psmp;	// 7.3.1.25
-}   FRAME_PSMP_ACTION, *PFRAME_PSMP_ACTION;
+/*802.11n : 7.3.2.20a */
+struct PACKED rt_second_chan_offset {
+	u8 ElementID;	/* ID = IE_SECONDARY_CH_OFFSET = 62 */
+	u8 Len;
+	struct rt_sec_cha_offset_ie SecChOffsetIe;
+};
 
-typedef struct PACKED _FRAME_ACTION_HDR {
-	HEADER_802_11   Hdr;
-	UCHAR	Category;
-	UCHAR	Action;
-}   FRAME_ACTION_HDR, *PFRAME_ACTION_HDR;
+struct PACKED rt_frame_spetrum_cs {
+	struct rt_header_802_11 Hdr;
+	u8 Category;
+	u8 Action;
+	struct rt_chan_switch_announce CSAnnounce;
+	struct rt_second_chan_offset SecondChannel;
+};
 
-//Action Frame
-//Action Frame  Category:Spectrum,  Action:Channel Switch. 7.3.2.20
-typedef struct PACKED _CHAN_SWITCH_ANNOUNCE {
-	UCHAR					ElementID;	// ID = IE_CHANNEL_SWITCH_ANNOUNCEMENT = 37
-	UCHAR					Len;
-	CHA_SWITCH_ANNOUNCE_IE	CSAnnounceIe;
-}   CHAN_SWITCH_ANNOUNCE, *PCHAN_SWITCH_ANNOUNCE;
+struct PACKED rt_frame_addba_req {
+	struct rt_header_802_11 Hdr;
+	u8 Category;
+	u8 Action;
+	u8 Token;		/* 1 */
+	struct rt_ba_parm BaParm;		/*  2 - 10 */
+	u16 TimeOutValue;	/* 0 - 0 */
+	BASEQ_CONTROL BaStartSeq;	/* 0-0 */
+};
 
+struct PACKED rt_frame_addba_rsp {
+	struct rt_header_802_11 Hdr;
+	u8 Category;
+	u8 Action;
+	u8 Token;
+	u16 StatusCode;
+	struct rt_ba_parm BaParm;		/*0 - 2 */
+	u16 TimeOutValue;
+};
 
-//802.11n : 7.3.2.20a
-typedef struct PACKED _SECOND_CHAN_OFFSET {
-	UCHAR				ElementID;		// ID = IE_SECONDARY_CH_OFFSET = 62
-	UCHAR				Len;
-	SEC_CHA_OFFSET_IE	SecChOffsetIe;
-}   SECOND_CHAN_OFFSET, *PSECOND_CHAN_OFFSET;
+struct PACKED rt_frame_delba_req {
+	struct rt_header_802_11 Hdr;
+	u8 Category;
+	u8 Action;
+	struct rt_delba_parm DelbaParm;
+	u16 ReasonCode;
+};
 
+/*7.2.1.7 */
+struct PACKED rt_frame_bar {
+	struct rt_frame_control FC;
+	u16 Duration;
+	u8 Addr1[MAC_ADDR_LEN];
+	u8 Addr2[MAC_ADDR_LEN];
+	struct rt_bar_control BarControl;
+	BASEQ_CONTROL StartingSeq;
+};
 
-typedef struct PACKED _FRAME_SPETRUM_CS {
-	HEADER_802_11   Hdr;
-	UCHAR	Category;
-	UCHAR	Action;
-	CHAN_SWITCH_ANNOUNCE	CSAnnounce;
-	SECOND_CHAN_OFFSET		SecondChannel;
-}   FRAME_SPETRUM_CS, *PFRAME_SPETRUM_CS;
+/*7.2.1.7 */
+struct PACKED rt_frame_ba {
+	struct rt_frame_control FC;
+	u16 Duration;
+	u8 Addr1[MAC_ADDR_LEN];
+	u8 Addr2[MAC_ADDR_LEN];
+	struct rt_bar_control BarControl;
+	BASEQ_CONTROL StartingSeq;
+	u8 bitmask[8];
+};
 
+/* Radio Measuement Request Frame Format */
+struct PACKED rt_frame_rm_req_action {
+	struct rt_header_802_11 Hdr;
+	u8 Category;
+	u8 Action;
+	u8 Token;
+	u16 Repetition;
+	u8 data[0];
+};
 
-typedef struct PACKED _FRAME_ADDBA_REQ {
-	HEADER_802_11   Hdr;
-	UCHAR	Category;
-	UCHAR	Action;
-	UCHAR	Token;	// 1
-	BA_PARM		BaParm;	      //  2 - 10
-	USHORT		TimeOutValue;	// 0 - 0
-	BASEQ_CONTROL	BaStartSeq; // 0-0
-}   FRAME_ADDBA_REQ, *PFRAME_ADDBA_REQ;
+struct PACKED rt_ht_ext_channel_switch_announcement_ie {
+	u8 ID;
+	u8 Length;
+	u8 ChannelSwitchMode;
+	u8 NewRegClass;
+	u8 NewChannelNum;
+	u8 ChannelSwitchCount;
+};
 
-typedef struct PACKED _FRAME_ADDBA_RSP {
-	HEADER_802_11   Hdr;
-	UCHAR	Category;
-	UCHAR	Action;
-	UCHAR	Token;
-	USHORT	StatusCode;
-	BA_PARM		BaParm; //0 - 2
-	USHORT		TimeOutValue;
-}   FRAME_ADDBA_RSP, *PFRAME_ADDBA_RSP;
-
-typedef struct PACKED _FRAME_DELBA_REQ {
-	HEADER_802_11   Hdr;
-	UCHAR	Category;
-	UCHAR	Action;
-	DELBA_PARM		DelbaParm;
-	USHORT	ReasonCode;
-}   FRAME_DELBA_REQ, *PFRAME_DELBA_REQ;
-
-
-//7.2.1.7
-typedef struct PACKED _FRAME_BAR {
-	FRAME_CONTROL   FC;
-	USHORT          Duration;
-	UCHAR           Addr1[MAC_ADDR_LEN];
-	UCHAR           Addr2[MAC_ADDR_LEN];
-	BAR_CONTROL		BarControl;
-	BASEQ_CONTROL	StartingSeq;
-}   FRAME_BAR, *PFRAME_BAR;
-
-//7.2.1.7
-typedef struct PACKED _FRAME_BA {
-	FRAME_CONTROL   FC;
-	USHORT          Duration;
-	UCHAR           Addr1[MAC_ADDR_LEN];
-	UCHAR           Addr2[MAC_ADDR_LEN];
-	BAR_CONTROL		BarControl;
-	BASEQ_CONTROL	StartingSeq;
-	UCHAR		bitmask[8];
-}   FRAME_BA, *PFRAME_BA;
-
-
-// Radio Measuement Request Frame Format
-typedef struct PACKED _FRAME_RM_REQ_ACTION {
-	HEADER_802_11   Hdr;
-	UCHAR	Category;
-	UCHAR	Action;
-	UCHAR	Token;
-	USHORT	Repetition;
-	UCHAR   data[0];
-}   FRAME_RM_REQ_ACTION, *PFRAME_RM_REQ_ACTION;
-
-typedef struct PACKED {
-	UCHAR		ID;
-	UCHAR		Length;
-	UCHAR		ChannelSwitchMode;
-	UCHAR		NewRegClass;
-	UCHAR		NewChannelNum;
-	UCHAR		ChannelSwitchCount;
-} HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE, *PHT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE;
-
-
-//
-// _Limit must be the 2**n - 1
-// _SEQ1 , _SEQ2 must be within 0 ~ _Limit
-//
+/* */
+/* _Limit must be the 2**n - 1 */
+/* _SEQ1 , _SEQ2 must be within 0 ~ _Limit */
+/* */
 #define SEQ_STEPONE(_SEQ1, _SEQ2, _Limit)	((_SEQ1 == ((_SEQ2+1) & _Limit)))
 #define SEQ_SMALLER(_SEQ1, _SEQ2, _Limit)	(((_SEQ1-_SEQ2) & ((_Limit+1)>>1)))
 #define SEQ_LARGER(_SEQ1, _SEQ2, _Limit)	((_SEQ1 != _SEQ2) && !(((_SEQ1-_SEQ2) & ((_Limit+1)>>1))))
 #define SEQ_WITHIN_WIN(_SEQ1, _SEQ2, _WIN, _Limit) (SEQ_LARGER(_SEQ1, _SEQ2, _Limit) &&  \
 												SEQ_SMALLER(_SEQ1, ((_SEQ2+_WIN+1)&_Limit), _Limit))
 
-//
-// Contention-free parameter (without ID and Length)
-//
-typedef struct PACKED {
-    BOOLEAN     bValid;         // 1: variable contains valid value
-    UCHAR       CfpCount;
-    UCHAR       CfpPeriod;
-    USHORT      CfpMaxDuration;
-    USHORT      CfpDurRemaining;
-} CF_PARM, *PCF_PARM;
+/* */
+/* Contention-free parameter (without ID and Length) */
+/* */
+struct PACKED rt_cf_parm {
+	BOOLEAN bValid;		/* 1: variable contains valid value */
+	u8 CfpCount;
+	u8 CfpPeriod;
+	u16 CfpMaxDuration;
+	u16 CfpDurRemaining;
+};
 
-typedef	struct	_CIPHER_SUITE	{
-	NDIS_802_11_ENCRYPTION_STATUS	PairCipher;		// Unicast cipher 1, this one has more secured cipher suite
-	NDIS_802_11_ENCRYPTION_STATUS	PairCipherAux;	// Unicast cipher 2 if AP announce two unicast cipher suite
-	NDIS_802_11_ENCRYPTION_STATUS	GroupCipher;	// Group cipher
-	USHORT							RsnCapability;	// RSN capability from beacon
-	BOOLEAN							bMixMode;		// Indicate Pair & Group cipher might be different
-}	CIPHER_SUITE, *PCIPHER_SUITE;
+struct rt_cipher_suite {
+	NDIS_802_11_ENCRYPTION_STATUS PairCipher;	/* Unicast cipher 1, this one has more secured cipher suite */
+	NDIS_802_11_ENCRYPTION_STATUS PairCipherAux;	/* Unicast cipher 2 if AP announce two unicast cipher suite */
+	NDIS_802_11_ENCRYPTION_STATUS GroupCipher;	/* Group cipher */
+	u16 RsnCapability;	/* RSN capability from beacon */
+	BOOLEAN bMixMode;	/* Indicate Pair & Group cipher might be different */
+};
 
-// EDCA configuration from AP's BEACON/ProbeRsp
-typedef struct {
-    BOOLEAN     bValid;         // 1: variable contains valid value
-    BOOLEAN     bAdd;         // 1: variable contains valid value
-    BOOLEAN     bQAck;
-    BOOLEAN     bQueueRequest;
-    BOOLEAN     bTxopRequest;
-    BOOLEAN     bAPSDCapable;
-//  BOOLEAN     bMoreDataAck;
-    UCHAR       EdcaUpdateCount;
-    UCHAR       Aifsn[4];       // 0:AC_BK, 1:AC_BE, 2:AC_VI, 3:AC_VO
-    UCHAR       Cwmin[4];
-    UCHAR       Cwmax[4];
-    USHORT      Txop[4];      // in unit of 32-us
-    BOOLEAN     bACM[4];      // 1: Admission Control of AC_BK is mandattory
-} EDCA_PARM, *PEDCA_PARM;
+/* EDCA configuration from AP's BEACON/ProbeRsp */
+struct rt_edca_parm {
+	BOOLEAN bValid;		/* 1: variable contains valid value */
+	BOOLEAN bAdd;		/* 1: variable contains valid value */
+	BOOLEAN bQAck;
+	BOOLEAN bQueueRequest;
+	BOOLEAN bTxopRequest;
+	BOOLEAN bAPSDCapable;
+/*  BOOLEAN     bMoreDataAck; */
+	u8 EdcaUpdateCount;
+	u8 Aifsn[4];		/* 0:AC_BK, 1:AC_BE, 2:AC_VI, 3:AC_VO */
+	u8 Cwmin[4];
+	u8 Cwmax[4];
+	u16 Txop[4];		/* in unit of 32-us */
+	BOOLEAN bACM[4];	/* 1: Admission Control of AC_BK is mandattory */
+};
 
-// QBSS LOAD information from QAP's BEACON/ProbeRsp
-typedef struct {
-    BOOLEAN     bValid;                     // 1: variable contains valid value
-    USHORT      StaNum;
-    UCHAR       ChannelUtilization;
-    USHORT      RemainingAdmissionControl;  // in unit of 32-us
-} QBSS_LOAD_PARM, *PQBSS_LOAD_PARM;
+/* QBSS LOAD information from QAP's BEACON/ProbeRsp */
+struct rt_qbss_load_parm {
+	BOOLEAN bValid;		/* 1: variable contains valid value */
+	u16 StaNum;
+	u8 ChannelUtilization;
+	u16 RemainingAdmissionControl;	/* in unit of 32-us */
+};
 
-// QBSS Info field in QSTA's assoc req
-typedef struct PACKED {
-    UCHAR		UAPSD_AC_VO:1;
-	UCHAR		UAPSD_AC_VI:1;
-	UCHAR		UAPSD_AC_BK:1;
-	UCHAR		UAPSD_AC_BE:1;
-	UCHAR		Rsv1:1;
-	UCHAR		MaxSPLength:2;
-	UCHAR		Rsv2:1;
-} QBSS_STA_INFO_PARM, *PQBSS_STA_INFO_PARM;
+/* QBSS Info field in QSTA's assoc req */
+struct PACKED rt_qbss_sta_info_parm {
+	u8 UAPSD_AC_VO:1;
+	u8 UAPSD_AC_VI:1;
+	u8 UAPSD_AC_BK:1;
+	u8 UAPSD_AC_BE:1;
+	u8 Rsv1:1;
+	u8 MaxSPLength:2;
+	u8 Rsv2:1;
+};
 
-// QBSS Info field in QAP's Beacon/ProbeRsp
-typedef struct PACKED {
-    UCHAR		ParamSetCount:4;
-	UCHAR		Rsv:3;
-	UCHAR		UAPSD:1;
-} QBSS_AP_INFO_PARM, *PQBSS_AP_INFO_PARM;
+/* QBSS Info field in QAP's Beacon/ProbeRsp */
+struct PACKED rt_qbss_ap_info_parm {
+	u8 ParamSetCount:4;
+	u8 Rsv:3;
+	u8 UAPSD:1;
+};
 
-// QOS Capability reported in QAP's BEACON/ProbeRsp
-// QOS Capability sent out in QSTA's AssociateReq/ReAssociateReq
-typedef struct {
-    BOOLEAN     bValid;                     // 1: variable contains valid value
-    BOOLEAN     bQAck;
-    BOOLEAN     bQueueRequest;
-    BOOLEAN     bTxopRequest;
-//  BOOLEAN     bMoreDataAck;
-    UCHAR       EdcaUpdateCount;
-} QOS_CAPABILITY_PARM, *PQOS_CAPABILITY_PARM;
+/* QOS Capability reported in QAP's BEACON/ProbeRsp */
+/* QOS Capability sent out in QSTA's AssociateReq/ReAssociateReq */
+struct rt_qos_capability_parm {
+	BOOLEAN bValid;		/* 1: variable contains valid value */
+	BOOLEAN bQAck;
+	BOOLEAN bQueueRequest;
+	BOOLEAN bTxopRequest;
+/*  BOOLEAN     bMoreDataAck; */
+	u8 EdcaUpdateCount;
+};
 
-typedef struct {
-    UCHAR       IELen;
-    UCHAR       IE[MAX_CUSTOM_LEN];
-} WPA_IE_;
+struct rt_wpa_ie {
+	u8 IELen;
+	u8 IE[MAX_CUSTOM_LEN];
+};
 
-typedef struct {
-    UCHAR   Bssid[MAC_ADDR_LEN];
-    UCHAR   Channel;
-	UCHAR   CentralChannel;	//Store the wide-band central channel for 40MHz.  .used in 40MHz AP. Or this is the same as Channel.
-    UCHAR   BssType;
-    USHORT  AtimWin;
-    USHORT  BeaconPeriod;
+struct rt_bss_entry {
+	u8 Bssid[MAC_ADDR_LEN];
+	u8 Channel;
+	u8 CentralChannel;	/*Store the wide-band central channel for 40MHz.  .used in 40MHz AP. Or this is the same as Channel. */
+	u8 BssType;
+	u16 AtimWin;
+	u16 BeaconPeriod;
 
-    UCHAR   SupRate[MAX_LEN_OF_SUPPORTED_RATES];
-    UCHAR   SupRateLen;
-    UCHAR   ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-    UCHAR   ExtRateLen;
-	HT_CAPABILITY_IE HtCapability;
-	UCHAR			HtCapabilityLen;
-	ADD_HT_INFO_IE AddHtInfo;	// AP might use this additional ht info IE
-	UCHAR			AddHtInfoLen;
-	UCHAR			NewExtChanOffset;
-	CHAR    Rssi;
-    UCHAR   Privacy;			// Indicate security function ON/OFF. Don't mess up with auth mode.
-	UCHAR	Hidden;
+	u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES];
+	u8 SupRateLen;
+	u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+	u8 ExtRateLen;
+	struct rt_ht_capability_ie HtCapability;
+	u8 HtCapabilityLen;
+	struct rt_add_ht_info_ie AddHtInfo;	/* AP might use this additional ht info IE */
+	u8 AddHtInfoLen;
+	u8 NewExtChanOffset;
+	char Rssi;
+	u8 Privacy;		/* Indicate security function ON/OFF. Don't mess up with auth mode. */
+	u8 Hidden;
 
-    USHORT  DtimPeriod;
-    USHORT  CapabilityInfo;
+	u16 DtimPeriod;
+	u16 CapabilityInfo;
 
-    USHORT  CfpCount;
-    USHORT  CfpPeriod;
-    USHORT  CfpMaxDuration;
-    USHORT  CfpDurRemaining;
-    UCHAR   SsidLen;
-    CHAR    Ssid[MAX_LEN_OF_SSID];
+	u16 CfpCount;
+	u16 CfpPeriod;
+	u16 CfpMaxDuration;
+	u16 CfpDurRemaining;
+	u8 SsidLen;
+	char Ssid[MAX_LEN_OF_SSID];
 
-    ULONG   LastBeaconRxTime; // OS's timestamp
+	unsigned long LastBeaconRxTime;	/* OS's timestamp */
 
-	BOOLEAN	bSES;
+	BOOLEAN bSES;
 
-	// New for WPA2
-	CIPHER_SUITE					WPA;			// AP announced WPA cipher suite
-	CIPHER_SUITE					WPA2;			// AP announced WPA2 cipher suite
+	/* New for WPA2 */
+	struct rt_cipher_suite WPA;	/* AP announced WPA cipher suite */
+	struct rt_cipher_suite WPA2;	/* AP announced WPA2 cipher suite */
 
-	// New for microsoft WPA support
-	NDIS_802_11_FIXED_IEs	FixIEs;
-	NDIS_802_11_AUTHENTICATION_MODE	AuthModeAux;	// Addition mode for WPA2 / WPA capable AP
-	NDIS_802_11_AUTHENTICATION_MODE	AuthMode;
-	NDIS_802_11_WEP_STATUS	WepStatus;				// Unicast Encryption Algorithm extract from VAR_IE
-	USHORT					VarIELen;				// Length of next VIE include EID & Length
-	UCHAR					VarIEs[MAX_VIE_LEN];
+	/* New for microsoft WPA support */
+	struct rt_ndis_802_11_fixed_ies FixIEs;
+	NDIS_802_11_AUTHENTICATION_MODE AuthModeAux;	/* Addition mode for WPA2 / WPA capable AP */
+	NDIS_802_11_AUTHENTICATION_MODE AuthMode;
+	NDIS_802_11_WEP_STATUS WepStatus;	/* Unicast Encryption Algorithm extract from VAR_IE */
+	u16 VarIELen;	/* Length of next VIE include EID & Length */
+	u8 VarIEs[MAX_VIE_LEN];
 
-	// CCX Ckip information
-    UCHAR   CkipFlag;
+	/* CCX Ckip information */
+	u8 CkipFlag;
 
-	// CCX 2 TSF
-	UCHAR	PTSF[4];		// Parent TSF
-	UCHAR	TTSF[8];		// Target TSF
+	/* CCX 2 TSF */
+	u8 PTSF[4];		/* Parent TSF */
+	u8 TTSF[8];		/* Target TSF */
 
-    // 802.11e d9, and WMM
-	EDCA_PARM           EdcaParm;
-	QOS_CAPABILITY_PARM QosCapability;
-	QBSS_LOAD_PARM      QbssLoad;
-    WPA_IE_     WpaIE;
-    WPA_IE_     RsnIE;
-} BSS_ENTRY, *PBSS_ENTRY;
+	/* 802.11e d9, and WMM */
+	struct rt_edca_parm EdcaParm;
+	struct rt_qos_capability_parm QosCapability;
+	struct rt_qbss_load_parm QbssLoad;
+	struct rt_wpa_ie WpaIE;
+	struct rt_wpa_ie RsnIE;
+};
 
-typedef struct {
-    UCHAR           BssNr;
-    UCHAR           BssOverlapNr;
-    BSS_ENTRY       BssEntry[MAX_LEN_OF_BSS_TABLE];
-} BSS_TABLE, *PBSS_TABLE;
+struct rt_bss_table {
+	u8 BssNr;
+	u8 BssOverlapNr;
+	struct rt_bss_entry BssEntry[MAX_LEN_OF_BSS_TABLE];
+};
 
+struct rt_mlme_queue_elem {
+	unsigned long Machine;
+	unsigned long MsgType;
+	unsigned long MsgLen;
+	u8 Msg[MGMT_DMA_BUFFER_SIZE];
+	LARGE_INTEGER TimeStamp;
+	u8 Rssi0;
+	u8 Rssi1;
+	u8 Rssi2;
+	u8 Signal;
+	u8 Channel;
+	u8 Wcid;
+	BOOLEAN Occupied;
+};
 
-typedef struct _MLME_QUEUE_ELEM {
-    ULONG             Machine;
-    ULONG             MsgType;
-    ULONG             MsgLen;
-    UCHAR             Msg[MGMT_DMA_BUFFER_SIZE];
-    LARGE_INTEGER     TimeStamp;
-    UCHAR             Rssi0;
-    UCHAR             Rssi1;
-    UCHAR             Rssi2;
-    UCHAR             Signal;
-    UCHAR             Channel;
-    UCHAR             Wcid;
-    BOOLEAN           Occupied;
-} MLME_QUEUE_ELEM, *PMLME_QUEUE_ELEM;
+struct rt_mlme_queue {
+	unsigned long Num;
+	unsigned long Head;
+	unsigned long Tail;
+	spinlock_t Lock;
+	struct rt_mlme_queue_elem Entry[MAX_LEN_OF_MLME_QUEUE];
+};
 
-typedef struct _MLME_QUEUE {
-    ULONG             Num;
-    ULONG             Head;
-    ULONG             Tail;
-    NDIS_SPIN_LOCK   Lock;
-    MLME_QUEUE_ELEM  Entry[MAX_LEN_OF_MLME_QUEUE];
-} MLME_QUEUE, *PMLME_QUEUE;
+typedef void(*STATE_MACHINE_FUNC) (void * Adaptor, struct rt_mlme_queue_elem *Elem);
 
-typedef VOID (*STATE_MACHINE_FUNC)(VOID *Adaptor, MLME_QUEUE_ELEM *Elem);
+struct rt_state_machine {
+	unsigned long Base;
+	unsigned long NrState;
+	unsigned long NrMsg;
+	unsigned long CurrState;
+	STATE_MACHINE_FUNC *TransFunc;
+};
 
-typedef struct _STATE_MACHINE {
-    ULONG                           Base;
-    ULONG                           NrState;
-    ULONG                           NrMsg;
-    ULONG                           CurrState;
-    STATE_MACHINE_FUNC             *TransFunc;
-} STATE_MACHINE, *PSTATE_MACHINE;
+/* MLME AUX data structure that hold temporarliy settings during a connection attempt. */
+/* Once this attemp succeeds, all settings will be copy to pAd->StaActive. */
+/* A connection attempt (user set OID, roaming, CCX fast roaming,..) consists of */
+/* several steps (JOIN, AUTH, ASSOC or REASSOC) and may fail at any step. We purposely */
+/* separate this under-trial settings away from pAd->StaActive so that once */
+/* this new attempt failed, driver can auto-recover back to the active settings. */
+struct rt_mlme_aux {
+	u8 BssType;
+	u8 Ssid[MAX_LEN_OF_SSID];
+	u8 SsidLen;
+	u8 Bssid[MAC_ADDR_LEN];
+	u8 AutoReconnectSsid[MAX_LEN_OF_SSID];
+	u8 AutoReconnectSsidLen;
+	u16 Alg;
+	u8 ScanType;
+	u8 Channel;
+	u8 CentralChannel;
+	u16 Aid;
+	u16 CapabilityInfo;
+	u16 BeaconPeriod;
+	u16 CfpMaxDuration;
+	u16 CfpPeriod;
+	u16 AtimWin;
 
+	/* Copy supported rate from desired AP's beacon. We are trying to match */
+	/* AP's supported and extended rate settings. */
+	u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES];
+	u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+	u8 SupRateLen;
+	u8 ExtRateLen;
+	struct rt_ht_capability_ie HtCapability;
+	u8 HtCapabilityLen;
+	struct rt_add_ht_info_ie AddHtInfo;	/* AP might use this additional ht info IE */
+	u8 NewExtChannelOffset;
+	/*struct rt_ht_capability      SupportedHtPhy; */
 
-// MLME AUX data structure that hold temporarliy settings during a connection attempt.
-// Once this attemp succeeds, all settings will be copy to pAd->StaActive.
-// A connection attempt (user set OID, roaming, CCX fast roaming,..) consists of
-// several steps (JOIN, AUTH, ASSOC or REASSOC) and may fail at any step. We purposely
-// separate this under-trial settings away from pAd->StaActive so that once
-// this new attempt failed, driver can auto-recover back to the active settings.
-typedef struct _MLME_AUX {
-    UCHAR               BssType;
-    UCHAR               Ssid[MAX_LEN_OF_SSID];
-    UCHAR               SsidLen;
-    UCHAR               Bssid[MAC_ADDR_LEN];
-	UCHAR				AutoReconnectSsid[MAX_LEN_OF_SSID];
-	UCHAR				AutoReconnectSsidLen;
-    USHORT              Alg;
-    UCHAR               ScanType;
-    UCHAR               Channel;
-	UCHAR               CentralChannel;
-    USHORT              Aid;
-    USHORT              CapabilityInfo;
-    USHORT              BeaconPeriod;
-    USHORT              CfpMaxDuration;
-    USHORT              CfpPeriod;
-    USHORT              AtimWin;
+	/* new for QOS */
+	struct rt_qos_capability_parm APQosCapability;	/* QOS capability of the current associated AP */
+	struct rt_edca_parm APEdcaParm;	/* EDCA parameters of the current associated AP */
+	struct rt_qbss_load_parm APQbssLoad;	/* QBSS load of the current associated AP */
 
-	// Copy supported rate from desired AP's beacon. We are trying to match
-	// AP's supported and extended rate settings.
-	UCHAR		        SupRate[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR		        ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR		        SupRateLen;
-	UCHAR		        ExtRateLen;
-	HT_CAPABILITY_IE		HtCapability;
-	UCHAR		        	HtCapabilityLen;
-	ADD_HT_INFO_IE		AddHtInfo;	// AP might use this additional ht info IE
-	UCHAR			NewExtChannelOffset;
-	//RT_HT_CAPABILITY	SupportedHtPhy;
+	/* new to keep Ralink specific feature */
+	unsigned long APRalinkIe;
 
-    // new for QOS
-    QOS_CAPABILITY_PARM APQosCapability;    // QOS capability of the current associated AP
-    EDCA_PARM           APEdcaParm;         // EDCA parameters of the current associated AP
-    QBSS_LOAD_PARM      APQbssLoad;         // QBSS load of the current associated AP
+	struct rt_bss_table SsidBssTab;	/* AP list for the same SSID */
+	struct rt_bss_table RoamTab;	/* AP list eligible for roaming */
+	unsigned long BssIdx;
+	unsigned long RoamIdx;
 
-    // new to keep Ralink specific feature
-    ULONG               APRalinkIe;
+	BOOLEAN CurrReqIsFromNdis;
 
-    BSS_TABLE           SsidBssTab;     // AP list for the same SSID
-    BSS_TABLE           RoamTab;        // AP list eligible for roaming
-    ULONG               BssIdx;
-    ULONG               RoamIdx;
+	struct rt_ralink_timer BeaconTimer, ScanTimer;
+	struct rt_ralink_timer AuthTimer;
+	struct rt_ralink_timer AssocTimer, ReassocTimer, DisassocTimer;
+};
 
-	BOOLEAN				CurrReqIsFromNdis;
+struct rt_mlme_addba_req {
+	u8 Wcid;		/* */
+	u8 pAddr[MAC_ADDR_LEN];
+	u8 BaBufSize;
+	u16 TimeOutValue;
+	u8 TID;
+	u8 Token;
+	u16 BaStartSeq;
+};
 
-    RALINK_TIMER_STRUCT BeaconTimer, ScanTimer;
-    RALINK_TIMER_STRUCT AuthTimer;
-    RALINK_TIMER_STRUCT AssocTimer, ReassocTimer, DisassocTimer;
-} MLME_AUX, *PMLME_AUX;
+struct rt_mlme_delba_req {
+	u8 Wcid;		/* */
+	u8 Addr[MAC_ADDR_LEN];
+	u8 TID;
+	u8 Initiator;
+};
 
-typedef struct _MLME_ADDBA_REQ_STRUCT{
-	UCHAR   Wcid;	//
-	UCHAR   pAddr[MAC_ADDR_LEN];
-	UCHAR   BaBufSize;
-	USHORT	TimeOutValue;
-	UCHAR   TID;
-	UCHAR   Token;
-	USHORT	BaStartSeq;
-} MLME_ADDBA_REQ_STRUCT, *PMLME_ADDBA_REQ_STRUCT;
+/* assoc struct is equal to reassoc */
+struct rt_mlme_assoc_req {
+	u8 Addr[MAC_ADDR_LEN];
+	u16 CapabilityInfo;
+	u16 ListenIntv;
+	unsigned long Timeout;
+};
 
+struct rt_mlme_disassoc_req {
+	u8 Addr[MAC_ADDR_LEN];
+	u16 Reason;
+};
 
-typedef struct _MLME_DELBA_REQ_STRUCT{
-	UCHAR   Wcid;	//
-	UCHAR     Addr[MAC_ADDR_LEN];
-	UCHAR   TID;
-	UCHAR	Initiator;
-} MLME_DELBA_REQ_STRUCT, *PMLME_DELBA_REQ_STRUCT;
+struct rt_mlme_auth_req {
+	u8 Addr[MAC_ADDR_LEN];
+	u16 Alg;
+	unsigned long Timeout;
+};
 
-// assoc struct is equal to reassoc
-typedef struct _MLME_ASSOC_REQ_STRUCT{
-    UCHAR     Addr[MAC_ADDR_LEN];
-    USHORT    CapabilityInfo;
-    USHORT    ListenIntv;
-    ULONG     Timeout;
-} MLME_ASSOC_REQ_STRUCT, *PMLME_ASSOC_REQ_STRUCT, MLME_REASSOC_REQ_STRUCT, *PMLME_REASSOC_REQ_STRUCT;
+struct rt_mlme_deauth_req {
+	u8 Addr[MAC_ADDR_LEN];
+	u16 Reason;
+};
 
-typedef struct _MLME_DISASSOC_REQ_STRUCT{
-    UCHAR     Addr[MAC_ADDR_LEN];
-    USHORT    Reason;
-} MLME_DISASSOC_REQ_STRUCT, *PMLME_DISASSOC_REQ_STRUCT;
+struct rt_mlme_join_req {
+	unsigned long BssIdx;
+};
 
-typedef struct _MLME_AUTH_REQ_STRUCT {
-    UCHAR        Addr[MAC_ADDR_LEN];
-    USHORT       Alg;
-    ULONG        Timeout;
-} MLME_AUTH_REQ_STRUCT, *PMLME_AUTH_REQ_STRUCT;
+struct rt_mlme_scan_req {
+	u8 Bssid[MAC_ADDR_LEN];
+	u8 BssType;
+	u8 ScanType;
+	u8 SsidLen;
+	char Ssid[MAX_LEN_OF_SSID];
+};
 
-typedef struct _MLME_DEAUTH_REQ_STRUCT {
-    UCHAR        Addr[MAC_ADDR_LEN];
-    USHORT       Reason;
-} MLME_DEAUTH_REQ_STRUCT, *PMLME_DEAUTH_REQ_STRUCT;
+struct rt_mlme_start_req {
+	char Ssid[MAX_LEN_OF_SSID];
+	u8 SsidLen;
+};
 
-typedef struct {
-    ULONG      BssIdx;
-} MLME_JOIN_REQ_STRUCT;
+struct PACKED rt_eid {
+	u8 Eid;
+	u8 Len;
+	u8 Octet[1];
+};
 
-typedef struct _MLME_SCAN_REQ_STRUCT {
-    UCHAR      Bssid[MAC_ADDR_LEN];
-    UCHAR      BssType;
-    UCHAR      ScanType;
-    UCHAR      SsidLen;
-    CHAR       Ssid[MAX_LEN_OF_SSID];
-} MLME_SCAN_REQ_STRUCT, *PMLME_SCAN_REQ_STRUCT;
+struct PACKED rt_rtmp_tx_rate_switch {
+	u8 ItemNo;
+	u8 STBC:1;
+	u8 ShortGI:1;
+	u8 BW:1;
+	u8 Rsv1:1;
+	u8 Mode:2;
+	u8 Rsv2:2;
+	u8 CurrMCS;
+	u8 TrainUp;
+	u8 TrainDown;
+};
 
-typedef struct _MLME_START_REQ_STRUCT {
-    CHAR        Ssid[MAX_LEN_OF_SSID];
-    UCHAR       SsidLen;
-} MLME_START_REQ_STRUCT, *PMLME_START_REQ_STRUCT;
-
-typedef struct PACKED {
-    UCHAR   Eid;
-    UCHAR   Len;
-    CHAR   Octet[1];
-} EID_STRUCT,*PEID_STRUCT, BEACON_EID_STRUCT, *PBEACON_EID_STRUCT;
-
-typedef struct PACKED _RTMP_TX_RATE_SWITCH
-{
-	UCHAR   ItemNo;
-	UCHAR	STBC:1;
-	UCHAR	ShortGI:1;
-	UCHAR	BW:1;
-	UCHAR	Rsv1:1;
-	UCHAR	Mode:2;
-	UCHAR	Rsv2:2;
-	UCHAR   CurrMCS;
-	UCHAR   TrainUp;
-	UCHAR   TrainDown;
-} RRTMP_TX_RATE_SWITCH, *PRTMP_TX_RATE_SWITCH;
-
-// ========================== AP mlme.h ===============================
-#define TBTT_PRELOAD_TIME       384        // usec. LomgPreamble + 24-byte at 1Mbps
+/* ========================== AP mlme.h =============================== */
+#define TBTT_PRELOAD_TIME       384	/* usec. LomgPreamble + 24-byte at 1Mbps */
 #define DEFAULT_DTIM_PERIOD     1
 
-#define MAC_TABLE_AGEOUT_TIME			300			// unit: sec
-#define MAC_TABLE_ASSOC_TIMEOUT			5			// unit: sec
+#define MAC_TABLE_AGEOUT_TIME			300	/* unit: sec */
+#define MAC_TABLE_ASSOC_TIMEOUT			5	/* unit: sec */
 #define MAC_TABLE_FULL(Tab)				((Tab).size == MAX_LEN_OF_MAC_TABLE)
 
-// AP shall drop the sta if contine Tx fail count reach it.
-#define MAC_ENTRY_LIFE_CHECK_CNT		20			// packet cnt.
+/* AP shall drop the sta if contine Tx fail count reach it. */
+#define MAC_ENTRY_LIFE_CHECK_CNT		20	/* packet cnt. */
 
-// Value domain of pMacEntry->Sst
+/* Value domain of pMacEntry->Sst */
 typedef enum _Sst {
-    SST_NOT_AUTH,   // 0: equivalent to IEEE 802.11/1999 state 1
-    SST_AUTH,       // 1: equivalent to IEEE 802.11/1999 state 2
-    SST_ASSOC       // 2: equivalent to IEEE 802.11/1999 state 3
+	SST_NOT_AUTH,		/* 0: equivalent to IEEE 802.11/1999 state 1 */
+	SST_AUTH,		/* 1: equivalent to IEEE 802.11/1999 state 2 */
+	SST_ASSOC		/* 2: equivalent to IEEE 802.11/1999 state 3 */
 } SST;
 
-// value domain of pMacEntry->AuthState
+/* value domain of pMacEntry->AuthState */
 typedef enum _AuthState {
-    AS_NOT_AUTH,
-    AS_AUTH_OPEN,       // STA has been authenticated using OPEN SYSTEM
-    AS_AUTH_KEY,        // STA has been authenticated using SHARED KEY
-    AS_AUTHENTICATING   // STA is waiting for AUTH seq#3 using SHARED KEY
+	AS_NOT_AUTH,
+	AS_AUTH_OPEN,		/* STA has been authenticated using OPEN SYSTEM */
+	AS_AUTH_KEY,		/* STA has been authenticated using SHARED KEY */
+	AS_AUTHENTICATING	/* STA is waiting for AUTH seq#3 using SHARED KEY */
 } AUTH_STATE;
 
-//for-wpa value domain of pMacEntry->WpaState  802.1i D3   p.114
+/*for-wpa value domain of pMacEntry->WpaState  802.1i D3   p.114 */
 typedef enum _ApWpaState {
-    AS_NOTUSE,              // 0
-    AS_DISCONNECT,          // 1
-    AS_DISCONNECTED,        // 2
-    AS_INITIALIZE,          // 3
-    AS_AUTHENTICATION,      // 4
-    AS_AUTHENTICATION2,     // 5
-    AS_INITPMK,             // 6
-    AS_INITPSK,             // 7
-    AS_PTKSTART,            // 8
-    AS_PTKINIT_NEGOTIATING, // 9
-    AS_PTKINITDONE,         // 10
-    AS_UPDATEKEYS,          // 11
-    AS_INTEGRITY_FAILURE,   // 12
-    AS_KEYUPDATE,           // 13
+	AS_NOTUSE,		/* 0 */
+	AS_DISCONNECT,		/* 1 */
+	AS_DISCONNECTED,	/* 2 */
+	AS_INITIALIZE,		/* 3 */
+	AS_AUTHENTICATION,	/* 4 */
+	AS_AUTHENTICATION2,	/* 5 */
+	AS_INITPMK,		/* 6 */
+	AS_INITPSK,		/* 7 */
+	AS_PTKSTART,		/* 8 */
+	AS_PTKINIT_NEGOTIATING,	/* 9 */
+	AS_PTKINITDONE,		/* 10 */
+	AS_UPDATEKEYS,		/* 11 */
+	AS_INTEGRITY_FAILURE,	/* 12 */
+	AS_KEYUPDATE,		/* 13 */
 } AP_WPA_STATE;
 
-// for-wpa value domain of pMacEntry->WpaState  802.1i D3   p.114
+/* for-wpa value domain of pMacEntry->WpaState  802.1i D3   p.114 */
 typedef enum _GTKState {
-    REKEY_NEGOTIATING,
-    REKEY_ESTABLISHED,
-    KEYERROR,
+	REKEY_NEGOTIATING,
+	REKEY_ESTABLISHED,
+	KEYERROR,
 } GTK_STATE;
 
-//  for-wpa  value domain of pMacEntry->WpaState  802.1i D3   p.114
+/*  for-wpa  value domain of pMacEntry->WpaState  802.1i D3   p.114 */
 typedef enum _WpaGTKState {
-    SETKEYS,
-    SETKEYS_DONE,
+	SETKEYS,
+	SETKEYS_DONE,
 } WPA_GTK_STATE;
-// ====================== end of AP mlme.h ============================
+/* ====================== end of AP mlme.h ============================ */
 
-
-#endif	// MLME_H__
+#endif /* MLME_H__ */
diff --git a/drivers/staging/rt2860/oid.h b/drivers/staging/rt2860/oid.h
index 0227c4a..fd1c141 100644
--- a/drivers/staging/rt2860/oid.h
+++ b/drivers/staging/rt2860/oid.h
@@ -37,32 +37,37 @@
 #ifndef _OID_H_
 #define _OID_H_
 
+/*#include <linux/wireless.h> */
 
+#ifndef TRUE
 #define TRUE				1
+#endif
+#ifndef FALSE
 #define FALSE				0
-//
-// IEEE 802.11 Structures and definitions
-//
-#define MAX_TX_POWER_LEVEL              100   /* mW */
-#define MAX_RSSI_TRIGGER                -10    /* dBm */
-#define MIN_RSSI_TRIGGER                -200   /* dBm */
-#define MAX_FRAG_THRESHOLD              2346  /* byte count */
-#define MIN_FRAG_THRESHOLD              256   /* byte count */
-#define MAX_RTS_THRESHOLD               2347  /* byte count */
+#endif
+/* */
+/* IEEE 802.11 Structures and definitions */
+/* */
+#define MAX_TX_POWER_LEVEL              100	/* mW */
+#define MAX_RSSI_TRIGGER                -10	/* dBm */
+#define MIN_RSSI_TRIGGER                -200	/* dBm */
+#define MAX_FRAG_THRESHOLD              2346	/* byte count */
+#define MIN_FRAG_THRESHOLD              256	/* byte count */
+#define MAX_RTS_THRESHOLD               2347	/* byte count */
 
-// new types for Media Specific Indications
-// Extension channel offset
+/* new types for Media Specific Indications */
+/* Extension channel offset */
 #define EXTCHA_NONE			0
 #define EXTCHA_ABOVE		0x1
 #define EXTCHA_BELOW		0x3
 
-// BW
+/* BW */
 #define BAND_WIDTH_20		0
 #define BAND_WIDTH_40		1
 #define BAND_WIDTH_BOTH		2
-#define BAND_WIDTH_10		3	// 802.11j has 10MHz. This definition is for internal usage. doesn't fill in the IE or other field.
-// SHORTGI
-#define GAP_INTERVAL_400	1	// only support in HT mode
+#define BAND_WIDTH_10		3	/* 802.11j has 10MHz. This definition is for internal usage. doesn't fill in the IE or other field. */
+/* SHORTGI */
+#define GAP_INTERVAL_400	1	/* only support in HT mode */
 #define GAP_INTERVAL_800	0
 #define GAP_INTERVAL_BOTH	2
 
@@ -73,24 +78,24 @@
 #define NDIS_802_11_LENGTH_RATES        8
 #define NDIS_802_11_LENGTH_RATES_EX     16
 #define MAC_ADDR_LENGTH                 6
-#define MAX_NUM_OF_CHS					49 // 14 channels @2.4G +  12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL terminationc
-#define MAX_NUMBER_OF_EVENT				10  // entry # in EVENT table
-#define MAX_NUMBER_OF_MAC				32 // if MAX_MBSSID_NUM is 8, this value can't be larger than 211
+/*#define MAX_NUM_OF_CHS                                        49 // 14 channels @2.4G +  12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL terminationc */
+#define MAX_NUM_OF_CHS				54	/* 14 channels @2.4G +  12@UNII(lower/middle) + 16@HiperLAN2 + 11@UNII(upper) + 0 @Japan + 1 as NULL termination */
+#define MAX_NUMBER_OF_EVENT				10	/* entry # in EVENT table */
+#define MAX_NUMBER_OF_MAC				32	/* if MAX_MBSSID_NUM is 8, this value can't be larger than 211 */
 #define MAX_NUMBER_OF_ACL				64
-#define MAX_LENGTH_OF_SUPPORT_RATES		12    // 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
+#define MAX_LENGTH_OF_SUPPORT_RATES		12	/* 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */
 #define MAX_NUMBER_OF_DLS_ENTRY			4
 
-#define OID_GEN_MACHINE_NAME               0x0001021A
-
 #define RT_QUERY_SIGNAL_CONTEXT				0x0402
 #define RT_SET_IAPP_PID                 	0x0404
 #define RT_SET_APD_PID						0x0405
 #define RT_SET_DEL_MAC_ENTRY				0x0406
-
-//
-// IEEE 802.11 OIDs
-//
+#define RT_QUERY_EVENT_TABLE			0x0407
+/* */
+/* IEEE 802.11 OIDs */
+/* */
 #define	OID_GET_SET_TOGGLE			0x8000
+#define	OID_GET_SET_FROM_UI			0x4000
 
 #define OID_802_11_ADD_WEP			0x0112
 #define OID_802_11_DISASSOCIATE			0x0114
@@ -101,38 +106,42 @@
 
 #define	RT_OID_DEVICE_NAME							0x0607
 #define	RT_OID_VERSION_INFO							0x0608
+#define	OID_802_11_BSSID_LIST						0x0609
+#define	OID_802_3_CURRENT_ADDRESS					0x060A
 #define	OID_GEN_MEDIA_CONNECT_STATUS				0x060B
+#define	RT_OID_802_11_QUERY_LINK_STATUS				0x060C
+#define	OID_802_11_RSSI								0x060D
+#define	OID_802_11_STATISTICS						0x060E
 #define	OID_GEN_RCV_OK								0x060F
 #define	OID_GEN_RCV_NO_BUFFER						0x0610
-
+#define	RT_OID_802_11_QUERY_EEPROM_VERSION			0x0611
+#define	RT_OID_802_11_QUERY_FIRMWARE_VERSION		0x0612
+#define	RT_OID_802_11_QUERY_LAST_RX_RATE			0x0613
+#define	RT_OID_802_11_TX_POWER_LEVEL_1				0x0614
+#define	RT_OID_802_11_QUERY_PIDVID					0x0615
+/*for WPA_SUPPLICANT_SUPPORT */
 #define OID_SET_COUNTERMEASURES                     0x0616
 #define RT_OID_WPA_SUPPLICANT_SUPPORT               0x0621
 #define RT_OID_WE_VERSION_COMPILED                  0x0622
 #define RT_OID_NEW_DRIVER                           0x0623
 
-//rt2860 , kathy
 #define RT_OID_DRIVER_DEVICE_NAME                   0x0645
 #define RT_OID_QUERY_MULTIPLE_CARD_SUPPORT          0x0647
 
-// Ralink defined OIDs
-// Dennis Lee move to platform specific
-
-typedef enum _NDIS_802_11_STATUS_TYPE
-{
-    Ndis802_11StatusType_Authentication,
-    Ndis802_11StatusType_MediaStreamMode,
-    Ndis802_11StatusType_PMKID_CandidateList,
-    Ndis802_11StatusTypeMax    // not a real type, defined as an upper bound
+typedef enum _NDIS_802_11_STATUS_TYPE {
+	Ndis802_11StatusType_Authentication,
+	Ndis802_11StatusType_MediaStreamMode,
+	Ndis802_11StatusType_PMKID_CandidateList,
+	Ndis802_11StatusTypeMax	/* not a real type, defined as an upper bound */
 } NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE;
 
-typedef UCHAR   NDIS_802_11_MAC_ADDRESS[6];
+typedef u8 NDIS_802_11_MAC_ADDRESS[6];
 
-typedef struct _NDIS_802_11_STATUS_INDICATION
-{
-    NDIS_802_11_STATUS_TYPE StatusType;
-} NDIS_802_11_STATUS_INDICATION, *PNDIS_802_11_STATUS_INDICATION;
+struct rt_ndis_802_11_status_indication {
+	NDIS_802_11_STATUS_TYPE StatusType;
+};
 
-// mask for authentication/integrity fields
+/* mask for authentication/integrity fields */
 #define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS        0x0f
 
 #define NDIS_802_11_AUTH_REQUEST_REAUTH             0x01
@@ -140,304 +149,283 @@
 #define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR     0x06
 #define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR        0x0E
 
-typedef struct _NDIS_802_11_AUTHENTICATION_REQUEST
-{
-    ULONG Length;            // Length of structure
-    NDIS_802_11_MAC_ADDRESS Bssid;
-    ULONG Flags;
-} NDIS_802_11_AUTHENTICATION_REQUEST, *PNDIS_802_11_AUTHENTICATION_REQUEST;
+struct rt_ndis_802_11_authentication_request {
+	unsigned long Length;		/* Length of structure */
+	NDIS_802_11_MAC_ADDRESS Bssid;
+	unsigned long Flags;
+};
 
-//Added new types for PMKID Candidate lists.
-typedef struct _PMKID_CANDIDATE {
-    NDIS_802_11_MAC_ADDRESS BSSID;
-    ULONG Flags;
-} PMKID_CANDIDATE, *PPMKID_CANDIDATE;
+/*Added new types for PMKID Candidate lists. */
+struct rt_pmkid_candidate {
+	NDIS_802_11_MAC_ADDRESS BSSID;
+	unsigned long Flags;
+};
 
-typedef struct _NDIS_802_11_PMKID_CANDIDATE_LIST
-{
-    ULONG Version;       // Version of the structure
-    ULONG NumCandidates; // No. of pmkid candidates
-    PMKID_CANDIDATE CandidateList[1];
-} NDIS_802_11_PMKID_CANDIDATE_LIST, *PNDIS_802_11_PMKID_CANDIDATE_LIST;
+struct rt_ndis_802_11_pmkid_candidate_list {
+	unsigned long Version;		/* Version of the structure */
+	unsigned long NumCandidates;	/* No. of pmkid candidates */
+	struct rt_pmkid_candidate CandidateList[1];
+};
 
-//Flags for PMKID Candidate list structure
+/*Flags for PMKID Candidate list structure */
 #define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED	0x01
 
-// Added new types for OFDM 5G and 2.4G
-typedef enum _NDIS_802_11_NETWORK_TYPE
-{
-   Ndis802_11FH,
-   Ndis802_11DS,
-    Ndis802_11OFDM5,
-    Ndis802_11OFDM5_N,
-    Ndis802_11OFDM24,
-    Ndis802_11OFDM24_N,
-   Ndis802_11Automode,
-    Ndis802_11NetworkTypeMax    // not a real type, defined as an upper bound
+/* Added new types for OFDM 5G and 2.4G */
+typedef enum _NDIS_802_11_NETWORK_TYPE {
+	Ndis802_11FH,
+	Ndis802_11DS,
+	Ndis802_11OFDM5,
+	Ndis802_11OFDM24,
+	Ndis802_11Automode,
+	Ndis802_11OFDM5_N,
+	Ndis802_11OFDM24_N,
+	Ndis802_11NetworkTypeMax	/* not a real type, defined as an upper bound */
 } NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE;
 
-typedef struct _NDIS_802_11_NETWORK_TYPE_LIST
-{
-    UINT                       NumberOfItems;  // in list below, at least 1
-   NDIS_802_11_NETWORK_TYPE    NetworkType [1];
-} NDIS_802_11_NETWORK_TYPE_LIST, *PNDIS_802_11_NETWORK_TYPE_LIST;
+struct rt_ndis_802_11_network_type_list {
+	u32 NumberOfItems;	/* in list below, at least 1 */
+	NDIS_802_11_NETWORK_TYPE NetworkType[1];
+};
 
-typedef enum _NDIS_802_11_POWER_MODE
-{
-    Ndis802_11PowerModeCAM,
-    Ndis802_11PowerModeMAX_PSP,
-    Ndis802_11PowerModeFast_PSP,
-    Ndis802_11PowerModeLegacy_PSP,
-    Ndis802_11PowerModeMax      // not a real mode, defined as an upper bound
+typedef enum _NDIS_802_11_POWER_MODE {
+	Ndis802_11PowerModeCAM,
+	Ndis802_11PowerModeMAX_PSP,
+	Ndis802_11PowerModeFast_PSP,
+	Ndis802_11PowerModeLegacy_PSP,
+	Ndis802_11PowerModeMax	/* not a real mode, defined as an upper bound */
 } NDIS_802_11_POWER_MODE, *PNDIS_802_11_POWER_MODE;
 
-typedef ULONG   NDIS_802_11_TX_POWER_LEVEL; // in milliwatts
+typedef unsigned long NDIS_802_11_TX_POWER_LEVEL;	/* in milliwatts */
 
-//
-// Received Signal Strength Indication
-//
-typedef LONG    NDIS_802_11_RSSI;           // in dBm
+/* */
+/* Received Signal Strength Indication */
+/* */
+typedef long NDIS_802_11_RSSI;	/* in dBm */
 
-typedef struct _NDIS_802_11_CONFIGURATION_FH
-{
-   ULONG           Length;            // Length of structure
-   ULONG           HopPattern;        // As defined by 802.11, MSB set
-   ULONG           HopSet;            // to one if non-802.11
-   ULONG           DwellTime;         // units are Kusec
-} NDIS_802_11_CONFIGURATION_FH, *PNDIS_802_11_CONFIGURATION_FH;
+struct rt_ndis_802_11_configuration_fh {
+	unsigned long Length;		/* Length of structure */
+	unsigned long HopPattern;	/* As defined by 802.11, MSB set */
+	unsigned long HopSet;		/* to one if non-802.11 */
+	unsigned long DwellTime;	/* units are Kusec */
+};
 
-typedef struct _NDIS_802_11_CONFIGURATION
-{
-   ULONG                           Length;             // Length of structure
-   ULONG                           BeaconPeriod;       // units are Kusec
-   ULONG                           ATIMWindow;         // units are Kusec
-   ULONG                           DSConfig;           // Frequency, units are kHz
-   NDIS_802_11_CONFIGURATION_FH    FHConfig;
-} NDIS_802_11_CONFIGURATION, *PNDIS_802_11_CONFIGURATION;
+struct rt_ndis_802_11_configuration {
+	unsigned long Length;		/* Length of structure */
+	unsigned long BeaconPeriod;	/* units are Kusec */
+	unsigned long ATIMWindow;	/* units are Kusec */
+	unsigned long DSConfig;		/* Frequency, units are kHz */
+	struct rt_ndis_802_11_configuration_fh FHConfig;
+};
 
-typedef struct _NDIS_802_11_STATISTICS
-{
-   ULONG           Length;             // Length of structure
-   LARGE_INTEGER   TransmittedFragmentCount;
-   LARGE_INTEGER   MulticastTransmittedFrameCount;
-   LARGE_INTEGER   FailedCount;
-   LARGE_INTEGER   RetryCount;
-   LARGE_INTEGER   MultipleRetryCount;
-   LARGE_INTEGER   RTSSuccessCount;
-   LARGE_INTEGER   RTSFailureCount;
-   LARGE_INTEGER   ACKFailureCount;
-   LARGE_INTEGER   FrameDuplicateCount;
-   LARGE_INTEGER   ReceivedFragmentCount;
-   LARGE_INTEGER   MulticastReceivedFrameCount;
-   LARGE_INTEGER   FCSErrorCount;
-   LARGE_INTEGER   TKIPLocalMICFailures;
-   LARGE_INTEGER   TKIPRemoteMICErrors;
-   LARGE_INTEGER   TKIPICVErrors;
-   LARGE_INTEGER   TKIPCounterMeasuresInvoked;
-   LARGE_INTEGER   TKIPReplays;
-   LARGE_INTEGER   CCMPFormatErrors;
-   LARGE_INTEGER   CCMPReplays;
-   LARGE_INTEGER   CCMPDecryptErrors;
-   LARGE_INTEGER   FourWayHandshakeFailures;
-} NDIS_802_11_STATISTICS, *PNDIS_802_11_STATISTICS;
+struct rt_ndis_802_11_statistics {
+	unsigned long Length;		/* Length of structure */
+	LARGE_INTEGER TransmittedFragmentCount;
+	LARGE_INTEGER MulticastTransmittedFrameCount;
+	LARGE_INTEGER FailedCount;
+	LARGE_INTEGER RetryCount;
+	LARGE_INTEGER MultipleRetryCount;
+	LARGE_INTEGER RTSSuccessCount;
+	LARGE_INTEGER RTSFailureCount;
+	LARGE_INTEGER ACKFailureCount;
+	LARGE_INTEGER FrameDuplicateCount;
+	LARGE_INTEGER ReceivedFragmentCount;
+	LARGE_INTEGER MulticastReceivedFrameCount;
+	LARGE_INTEGER FCSErrorCount;
+	LARGE_INTEGER TKIPLocalMICFailures;
+	LARGE_INTEGER TKIPRemoteMICErrors;
+	LARGE_INTEGER TKIPICVErrors;
+	LARGE_INTEGER TKIPCounterMeasuresInvoked;
+	LARGE_INTEGER TKIPReplays;
+	LARGE_INTEGER CCMPFormatErrors;
+	LARGE_INTEGER CCMPReplays;
+	LARGE_INTEGER CCMPDecryptErrors;
+	LARGE_INTEGER FourWayHandshakeFailures;
+};
 
-typedef  ULONG  NDIS_802_11_KEY_INDEX;
-typedef ULONGLONG   NDIS_802_11_KEY_RSC;
+typedef unsigned long NDIS_802_11_KEY_INDEX;
+typedef unsigned long long NDIS_802_11_KEY_RSC;
 
-#define MAX_RADIUS_SRV_NUM			2	  // 802.1x failover number
+#define MAX_RADIUS_SRV_NUM			2	/* 802.1x failover number */
 
-typedef struct PACKED _RADIUS_SRV_INFO {
-	UINT32			radius_ip;
-	UINT32			radius_port;
-	UCHAR			radius_key[64];
-	UCHAR			radius_key_len;
-} RADIUS_SRV_INFO, *PRADIUS_SRV_INFO;
+struct PACKED rt_radius_srv_info {
+	u32 radius_ip;
+	u32 radius_port;
+	u8 radius_key[64];
+	u8 radius_key_len;
+};
 
-typedef struct PACKED _RADIUS_KEY_INFO
-{
-	UCHAR			radius_srv_num;
-	RADIUS_SRV_INFO	radius_srv_info[MAX_RADIUS_SRV_NUM];
-	UCHAR			ieee8021xWEP;		 // dynamic WEP
-    UCHAR           key_index;
-    UCHAR           key_length;          // length of key in bytes
-    UCHAR           key_material[13];
-} RADIUS_KEY_INFO, *PRADIUS_KEY_INFO;
+struct PACKED rt_radius_key_info {
+	u8 radius_srv_num;
+	struct rt_radius_srv_info radius_srv_info[MAX_RADIUS_SRV_NUM];
+	u8 ieee8021xWEP;	/* dynamic WEP */
+	u8 key_index;
+	u8 key_length;	/* length of key in bytes */
+	u8 key_material[13];
+};
 
-// It's used by 802.1x daemon to require relative configuration
-typedef struct PACKED _RADIUS_CONF
-{
-    UINT32          Length;             // Length of this structure
-    UCHAR			mbss_num;			// indicate multiple BSS number
-	UINT32			own_ip_addr;
-	UINT32			retry_interval;
-	UINT32			session_timeout_interval;
-	UCHAR			EAPifname[IFNAMSIZ];
-	UCHAR			EAPifname_len;
-	UCHAR 			PreAuthifname[IFNAMSIZ];
-	UCHAR			PreAuthifname_len;
-	RADIUS_KEY_INFO	RadiusInfo[8/*MAX_MBSSID_NUM*/];
-} RADIUS_CONF, *PRADIUS_CONF;
+/* It's used by 802.1x daemon to require relative configuration */
+struct PACKED rt_radius_conf {
+	u32 Length;		/* Length of this structure */
+	u8 mbss_num;		/* indicate multiple BSS number */
+	u32 own_ip_addr;
+	u32 retry_interval;
+	u32 session_timeout_interval;
+	u8 EAPifname[8][IFNAMSIZ];
+	u8 EAPifname_len[8];
+	u8 PreAuthifname[8][IFNAMSIZ];
+	u8 PreAuthifname_len[8];
+	struct rt_radius_key_info RadiusInfo[8];
+};
 
-// Key mapping keys require a BSSID
-typedef struct _NDIS_802_11_KEY
-{
-    UINT           Length;             // Length of this structure
-    UINT           KeyIndex;
-    UINT           KeyLength;          // length of key in bytes
-    NDIS_802_11_MAC_ADDRESS BSSID;
-    NDIS_802_11_KEY_RSC KeyRSC;
-    UCHAR           KeyMaterial[1];     // variable length depending on above field
-} NDIS_802_11_KEY, *PNDIS_802_11_KEY;
+/* Key mapping keys require a BSSID */
+struct rt_ndis_802_11_key {
+	u32 Length;		/* Length of this structure */
+	u32 KeyIndex;
+	u32 KeyLength;		/* length of key in bytes */
+	NDIS_802_11_MAC_ADDRESS BSSID;
+	NDIS_802_11_KEY_RSC KeyRSC;
+	u8 KeyMaterial[1];	/* variable length depending on above field */
+};
 
-typedef struct _NDIS_802_11_REMOVE_KEY
-{
-    UINT           Length;             // Length of this structure
-    UINT           KeyIndex;
-    NDIS_802_11_MAC_ADDRESS BSSID;
-} NDIS_802_11_REMOVE_KEY, *PNDIS_802_11_REMOVE_KEY;
+struct rt_ndis_802_11_passphrase {
+	u32 KeyLength;		/* length of key in bytes */
+	NDIS_802_11_MAC_ADDRESS BSSID;
+	u8 KeyMaterial[1];	/* variable length depending on above field */
+};
 
-typedef struct _NDIS_802_11_WEP
-{
-   UINT     Length;        // Length of this structure
-   UINT     KeyIndex;           // 0 is the per-client key, 1-N are the
-                                        // global keys
-   UINT     KeyLength;     // length of key in bytes
-   UCHAR     KeyMaterial[1];// variable length depending on above field
-} NDIS_802_11_WEP, *PNDIS_802_11_WEP;
+struct rt_ndis_802_11_remove_key {
+	u32 Length;		/* Length of this structure */
+	u32 KeyIndex;
+	NDIS_802_11_MAC_ADDRESS BSSID;
+};
 
+struct rt_ndis_802_11_wep {
+	u32 Length;		/* Length of this structure */
+	u32 KeyIndex;		/* 0 is the per-client key, 1-N are the */
+	/* global keys */
+	u32 KeyLength;		/* length of key in bytes */
+	u8 KeyMaterial[1];	/* variable length depending on above field */
+};
 
-typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE
-{
-   Ndis802_11IBSS,
-   Ndis802_11Infrastructure,
-   Ndis802_11AutoUnknown,
-   Ndis802_11Monitor,
-   Ndis802_11InfrastructureMax     // Not a real value, defined as upper bound
+typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE {
+	Ndis802_11IBSS,
+	Ndis802_11Infrastructure,
+	Ndis802_11AutoUnknown,
+	Ndis802_11Monitor,
+	Ndis802_11InfrastructureMax	/* Not a real value, defined as upper bound */
 } NDIS_802_11_NETWORK_INFRASTRUCTURE, *PNDIS_802_11_NETWORK_INFRASTRUCTURE;
 
-// Add new authentication modes
-typedef enum _NDIS_802_11_AUTHENTICATION_MODE
-{
-   Ndis802_11AuthModeOpen,
-   Ndis802_11AuthModeShared,
-   Ndis802_11AuthModeAutoSwitch,
-    Ndis802_11AuthModeWPA,
-    Ndis802_11AuthModeWPAPSK,
-    Ndis802_11AuthModeWPANone,
-   Ndis802_11AuthModeWPA2,
-   Ndis802_11AuthModeWPA2PSK,
-   	Ndis802_11AuthModeWPA1WPA2,
+/* Add new authentication modes */
+typedef enum _NDIS_802_11_AUTHENTICATION_MODE {
+	Ndis802_11AuthModeOpen,
+	Ndis802_11AuthModeShared,
+	Ndis802_11AuthModeAutoSwitch,
+	Ndis802_11AuthModeWPA,
+	Ndis802_11AuthModeWPAPSK,
+	Ndis802_11AuthModeWPANone,
+	Ndis802_11AuthModeWPA2,
+	Ndis802_11AuthModeWPA2PSK,
+	Ndis802_11AuthModeWPA1WPA2,
 	Ndis802_11AuthModeWPA1PSKWPA2PSK,
-   Ndis802_11AuthModeMax           // Not a real mode, defined as upper bound
+	Ndis802_11AuthModeMax	/* Not a real mode, defined as upper bound */
 } NDIS_802_11_AUTHENTICATION_MODE, *PNDIS_802_11_AUTHENTICATION_MODE;
 
-typedef UCHAR   NDIS_802_11_RATES[NDIS_802_11_LENGTH_RATES];        // Set of 8 data rates
-typedef UCHAR   NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX];  // Set of 16 data rates
+typedef u8 NDIS_802_11_RATES[NDIS_802_11_LENGTH_RATES];	/* Set of 8 data rates */
+typedef u8 NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX];	/* Set of 16 data rates */
 
-typedef struct PACKED _NDIS_802_11_SSID
-{
-    UINT   SsidLength;         // length of SSID field below, in bytes;
-                                // this can be zero.
-    UCHAR   Ssid[NDIS_802_11_LENGTH_SSID];           // SSID information field
-} NDIS_802_11_SSID, *PNDIS_802_11_SSID;
+struct PACKED rt_ndis_802_11_ssid {
+	u32 SsidLength;	/* length of SSID field below, in bytes; */
+	/* this can be zero. */
+	u8 Ssid[NDIS_802_11_LENGTH_SSID];	/* SSID information field */
+};
 
+struct PACKED rt_ndis_wlan_bssid {
+	unsigned long Length;		/* Length of this structure */
+	NDIS_802_11_MAC_ADDRESS MacAddress;	/* BSSID */
+	u8 Reserved[2];
+	struct rt_ndis_802_11_ssid Ssid;	/* SSID */
+	unsigned long Privacy;		/* WEP encryption requirement */
+	NDIS_802_11_RSSI Rssi;	/* receive signal strength in dBm */
+	NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
+	struct rt_ndis_802_11_configuration Configuration;
+	NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
+	NDIS_802_11_RATES SupportedRates;
+};
 
-typedef struct PACKED _NDIS_WLAN_BSSID
-{
-   ULONG                               Length;     // Length of this structure
-   NDIS_802_11_MAC_ADDRESS             MacAddress; // BSSID
-   UCHAR                               Reserved[2];
-   NDIS_802_11_SSID                    Ssid;       // SSID
-   ULONG                               Privacy;    // WEP encryption requirement
-   NDIS_802_11_RSSI                    Rssi;       // receive signal strength in dBm
-   NDIS_802_11_NETWORK_TYPE            NetworkTypeInUse;
-   NDIS_802_11_CONFIGURATION           Configuration;
-   NDIS_802_11_NETWORK_INFRASTRUCTURE  InfrastructureMode;
-   NDIS_802_11_RATES                   SupportedRates;
-} NDIS_WLAN_BSSID, *PNDIS_WLAN_BSSID;
+struct PACKED rt_ndis_802_11_bssid_list {
+	u32 NumberOfItems;	/* in list below, at least 1 */
+	struct rt_ndis_wlan_bssid Bssid[1];
+};
 
-typedef struct PACKED _NDIS_802_11_BSSID_LIST
-{
-   UINT           NumberOfItems;      // in list below, at least 1
-   NDIS_WLAN_BSSID Bssid[1];
-} NDIS_802_11_BSSID_LIST, *PNDIS_802_11_BSSID_LIST;
+/* Added Capabilities, IELength and IEs for each BSSID */
+struct PACKED rt_ndis_wlan_bssid_ex {
+	unsigned long Length;		/* Length of this structure */
+	NDIS_802_11_MAC_ADDRESS MacAddress;	/* BSSID */
+	u8 Reserved[2];
+	struct rt_ndis_802_11_ssid Ssid;	/* SSID */
+	u32 Privacy;		/* WEP encryption requirement */
+	NDIS_802_11_RSSI Rssi;	/* receive signal */
+	/* strength in dBm */
+	NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
+	struct rt_ndis_802_11_configuration Configuration;
+	NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
+	NDIS_802_11_RATES_EX SupportedRates;
+	unsigned long IELength;
+	u8 IEs[1];
+};
 
-// Added Capabilities, IELength and IEs for each BSSID
-typedef struct PACKED _NDIS_WLAN_BSSID_EX
-{
-    ULONG                               Length;             // Length of this structure
-    NDIS_802_11_MAC_ADDRESS             MacAddress;         // BSSID
-    UCHAR                               Reserved[2];
-    NDIS_802_11_SSID                    Ssid;               // SSID
-    UINT                                Privacy;            // WEP encryption requirement
-    NDIS_802_11_RSSI                    Rssi;               // receive signal
-                                                            // strength in dBm
-    NDIS_802_11_NETWORK_TYPE            NetworkTypeInUse;
-    NDIS_802_11_CONFIGURATION           Configuration;
-    NDIS_802_11_NETWORK_INFRASTRUCTURE  InfrastructureMode;
-    NDIS_802_11_RATES_EX                SupportedRates;
-    ULONG                               IELength;
-    UCHAR                               IEs[1];
-} NDIS_WLAN_BSSID_EX, *PNDIS_WLAN_BSSID_EX;
+struct PACKED rt_ndis_802_11_bssid_list_ex {
+	u32 NumberOfItems;	/* in list below, at least 1 */
+	struct rt_ndis_wlan_bssid_ex Bssid[1];
+};
 
-typedef struct PACKED _NDIS_802_11_BSSID_LIST_EX
-{
-    UINT                   NumberOfItems;      // in list below, at least 1
-    NDIS_WLAN_BSSID_EX      Bssid[1];
-} NDIS_802_11_BSSID_LIST_EX, *PNDIS_802_11_BSSID_LIST_EX;
+struct PACKED rt_ndis_802_11_fixed_ies {
+	u8 Timestamp[8];
+	u16 BeaconInterval;
+	u16 Capabilities;
+};
 
-typedef struct PACKED _NDIS_802_11_FIXED_IEs
-{
-    UCHAR Timestamp[8];
-    USHORT BeaconInterval;
-    USHORT Capabilities;
-} NDIS_802_11_FIXED_IEs, *PNDIS_802_11_FIXED_IEs;
+struct rt_ndis_802_11_variable_ies {
+	u8 ElementID;
+	u8 Length;		/* Number of bytes in data field */
+	u8 data[1];
+};
 
-typedef struct _NDIS_802_11_VARIABLE_IEs
-{
-    UCHAR ElementID;
-    UCHAR Length;    // Number of bytes in data field
-    UCHAR data[1];
-} NDIS_802_11_VARIABLE_IEs, *PNDIS_802_11_VARIABLE_IEs;
+typedef unsigned long NDIS_802_11_FRAGMENTATION_THRESHOLD;
 
-typedef  ULONG   NDIS_802_11_FRAGMENTATION_THRESHOLD;
+typedef unsigned long NDIS_802_11_RTS_THRESHOLD;
 
-typedef  ULONG   NDIS_802_11_RTS_THRESHOLD;
+typedef unsigned long NDIS_802_11_ANTENNA;
 
-typedef  ULONG   NDIS_802_11_ANTENNA;
-
-typedef enum _NDIS_802_11_PRIVACY_FILTER
-{
-   Ndis802_11PrivFilterAcceptAll,
-   Ndis802_11PrivFilter8021xWEP
+typedef enum _NDIS_802_11_PRIVACY_FILTER {
+	Ndis802_11PrivFilterAcceptAll,
+	Ndis802_11PrivFilter8021xWEP
 } NDIS_802_11_PRIVACY_FILTER, *PNDIS_802_11_PRIVACY_FILTER;
 
-// Added new encryption types
-// Also aliased typedef to new name
-typedef enum _NDIS_802_11_WEP_STATUS
-{
-   Ndis802_11WEPEnabled,
-    Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
-   Ndis802_11WEPDisabled,
-    Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
-   Ndis802_11WEPKeyAbsent,
-    Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
-   Ndis802_11WEPNotSupported,
-    Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
-    Ndis802_11Encryption2Enabled,
-    Ndis802_11Encryption2KeyAbsent,
-    Ndis802_11Encryption3Enabled,
-    Ndis802_11Encryption3KeyAbsent,
-    Ndis802_11Encryption4Enabled,	// TKIP or AES mix
-    Ndis802_11Encryption4KeyAbsent,
-    Ndis802_11GroupWEP40Enabled,
+/* Added new encryption types */
+/* Also aliased typedef to new name */
+typedef enum _NDIS_802_11_WEP_STATUS {
+	Ndis802_11WEPEnabled,
+	Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
+	Ndis802_11WEPDisabled,
+	Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
+	Ndis802_11WEPKeyAbsent,
+	Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
+	Ndis802_11WEPNotSupported,
+	Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
+	Ndis802_11Encryption2Enabled,
+	Ndis802_11Encryption2KeyAbsent,
+	Ndis802_11Encryption3Enabled,
+	Ndis802_11Encryption3KeyAbsent,
+	Ndis802_11Encryption4Enabled,	/* TKIP or AES mix */
+	Ndis802_11Encryption4KeyAbsent,
+	Ndis802_11GroupWEP40Enabled,
 	Ndis802_11GroupWEP104Enabled,
 } NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS,
-  NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS;
+    NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS;
 
-typedef enum _NDIS_802_11_RELOAD_DEFAULTS
-{
-   Ndis802_11ReloadWEPKeys
+typedef enum _NDIS_802_11_RELOAD_DEFAULTS {
+	Ndis802_11ReloadWEPKeys
 } NDIS_802_11_RELOAD_DEFAULTS, *PNDIS_802_11_RELOAD_DEFAULTS;
 
 #define NDIS_802_11_AI_REQFI_CAPABILITIES      1
@@ -448,351 +436,343 @@
 #define NDIS_802_11_AI_RESFI_STATUSCODE        2
 #define NDIS_802_11_AI_RESFI_ASSOCIATIONID     4
 
-typedef struct _NDIS_802_11_AI_REQFI
-{
-    USHORT Capabilities;
-    USHORT ListenInterval;
-    NDIS_802_11_MAC_ADDRESS  CurrentAPAddress;
-} NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI;
+struct rt_ndis_802_11_ai_reqfi {
+	u16 Capabilities;
+	u16 ListenInterval;
+	NDIS_802_11_MAC_ADDRESS CurrentAPAddress;
+};
 
-typedef struct _NDIS_802_11_AI_RESFI
-{
-    USHORT Capabilities;
-    USHORT StatusCode;
-    USHORT AssociationId;
-} NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI;
+struct rt_ndis_802_11_ai_resfi {
+	u16 Capabilities;
+	u16 StatusCode;
+	u16 AssociationId;
+};
 
-typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION
-{
-    ULONG                   Length;
-    USHORT                  AvailableRequestFixedIEs;
-    NDIS_802_11_AI_REQFI    RequestFixedIEs;
-    ULONG                   RequestIELength;
-    ULONG                   OffsetRequestIEs;
-    USHORT                  AvailableResponseFixedIEs;
-    NDIS_802_11_AI_RESFI    ResponseFixedIEs;
-    ULONG                   ResponseIELength;
-    ULONG                   OffsetResponseIEs;
-} NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION;
+struct rt_ndis_802_11_association_information {
+	unsigned long Length;
+	u16 AvailableRequestFixedIEs;
+	struct rt_ndis_802_11_ai_reqfi RequestFixedIEs;
+	unsigned long RequestIELength;
+	unsigned long OffsetRequestIEs;
+	u16 AvailableResponseFixedIEs;
+	struct rt_ndis_802_11_ai_resfi ResponseFixedIEs;
+	unsigned long ResponseIELength;
+	unsigned long OffsetResponseIEs;
+};
 
-typedef struct _NDIS_802_11_AUTHENTICATION_EVENT
-{
-    NDIS_802_11_STATUS_INDICATION       Status;
-    NDIS_802_11_AUTHENTICATION_REQUEST  Request[1];
-} NDIS_802_11_AUTHENTICATION_EVENT, *PNDIS_802_11_AUTHENTICATION_EVENT;
+struct rt_ndis_802_11_authentication_event {
+	struct rt_ndis_802_11_status_indication Status;
+	struct rt_ndis_802_11_authentication_request Request[1];
+};
 
-// 802.11 Media stream constraints, associated with OID_802_11_MEDIA_STREAM_MODE
-typedef enum _NDIS_802_11_MEDIA_STREAM_MODE
-{
-    Ndis802_11MediaStreamOff,
-    Ndis802_11MediaStreamOn,
+/* 802.11 Media stream constraints, associated with OID_802_11_MEDIA_STREAM_MODE */
+typedef enum _NDIS_802_11_MEDIA_STREAM_MODE {
+	Ndis802_11MediaStreamOff,
+	Ndis802_11MediaStreamOn,
 } NDIS_802_11_MEDIA_STREAM_MODE, *PNDIS_802_11_MEDIA_STREAM_MODE;
 
-// PMKID Structures
-typedef UCHAR   NDIS_802_11_PMKID_VALUE[16];
+/* PMKID Structures */
+typedef u8 NDIS_802_11_PMKID_VALUE[16];
 
-typedef struct _BSSID_INFO
-{
-    NDIS_802_11_MAC_ADDRESS BSSID;
-    NDIS_802_11_PMKID_VALUE PMKID;
-} BSSID_INFO, *PBSSID_INFO;
+struct rt_bssid_info {
+	NDIS_802_11_MAC_ADDRESS BSSID;
+	NDIS_802_11_PMKID_VALUE PMKID;
+};
 
-typedef struct _NDIS_802_11_PMKID
-{
-    UINT    Length;
-    UINT    BSSIDInfoCount;
-    BSSID_INFO BSSIDInfo[1];
-} NDIS_802_11_PMKID, *PNDIS_802_11_PMKID;
+struct rt_ndis_802_11_pmkid {
+	u32 Length;
+	u32 BSSIDInfoCount;
+	struct rt_bssid_info BSSIDInfo[1];
+};
 
-typedef struct _NDIS_802_11_AUTHENTICATION_ENCRYPTION
-{
-    NDIS_802_11_AUTHENTICATION_MODE AuthModeSupported;
-    NDIS_802_11_ENCRYPTION_STATUS EncryptStatusSupported;
-} NDIS_802_11_AUTHENTICATION_ENCRYPTION, *PNDIS_802_11_AUTHENTICATION_ENCRYPTION;
+struct rt_ndis_802_11_authentication_encryption {
+	NDIS_802_11_AUTHENTICATION_MODE AuthModeSupported;
+	NDIS_802_11_ENCRYPTION_STATUS EncryptStatusSupported;
+};
 
-typedef struct _NDIS_802_11_CAPABILITY
-{
-     ULONG Length;
-     ULONG Version;
-     ULONG NoOfPMKIDs;
-     ULONG NoOfAuthEncryptPairsSupported;
-     NDIS_802_11_AUTHENTICATION_ENCRYPTION AuthenticationEncryptionSupported[1];
-} NDIS_802_11_CAPABILITY, *PNDIS_802_11_CAPABILITY;
+struct rt_ndis_802_11_capability {
+	unsigned long Length;
+	unsigned long Version;
+	unsigned long NoOfPMKIDs;
+	unsigned long NoOfAuthEncryptPairsSupported;
+	struct rt_ndis_802_11_authentication_encryption
+	    AuthenticationEncryptionSupported[1];
+};
 
-#define RT_PRIV_IOCTL_EXT							(SIOCIWFIRSTPRIV + 0x01) // Sync. with AP for wsc upnp daemon
+#define RT_PRIV_IOCTL							(SIOCIWFIRSTPRIV + 0x01)	/* Sync. with AP for wsc upnp daemon */
 #define RTPRIV_IOCTL_SET							(SIOCIWFIRSTPRIV + 0x02)
 
 #define RTPRIV_IOCTL_STATISTICS                     (SIOCIWFIRSTPRIV + 0x09)
 #define RTPRIV_IOCTL_ADD_PMKID_CACHE                (SIOCIWFIRSTPRIV + 0x0A)
 #define RTPRIV_IOCTL_RADIUS_DATA                    (SIOCIWFIRSTPRIV + 0x0C)
 #define RTPRIV_IOCTL_GSITESURVEY					(SIOCIWFIRSTPRIV + 0x0D)
-#define RT_PRIV_IOCTL								(SIOCIWFIRSTPRIV + 0x0E) // Sync. with RT61 (for wpa_supplicant)
+#define RT_PRIV_IOCTL_EXT							(SIOCIWFIRSTPRIV + 0x0E)	/* Sync. with RT61 (for wpa_supplicant) */
 #define RTPRIV_IOCTL_GET_MAC_TABLE					(SIOCIWFIRSTPRIV + 0x0F)
 
 #define RTPRIV_IOCTL_SHOW							(SIOCIWFIRSTPRIV + 0x11)
 enum {
-    SHOW_CONN_STATUS = 4,
-    SHOW_DRVIER_VERION = 5,
-    SHOW_BA_INFO = 6,
+	SHOW_CONN_STATUS = 4,
+	SHOW_DRVIER_VERION = 5,
+	SHOW_BA_INFO = 6,
 	SHOW_DESC_INFO = 7,
-#ifdef RT2870
+#ifdef RTMP_MAC_USB
 	SHOW_RXBULK_INFO = 8,
 	SHOW_TXBULK_INFO = 9,
-#endif // RT2870 //
-    RAIO_OFF = 10,
-    RAIO_ON = 11,
+#endif /* RTMP_MAC_USB // */
+	RAIO_OFF = 10,
+	RAIO_ON = 11,
 	SHOW_CFG_VALUE = 20,
-#if !defined(RT2860)
 	SHOW_ADHOC_ENTRY_INFO = 21,
-#endif
 };
 
-#ifdef LLTD_SUPPORT
-// for consistency with RT61
-#define RT_OID_GET_PHY_MODE                         0x761
-#endif // LLTD_SUPPORT //
+#define OID_802_11_BUILD_CHANNEL_EX				0x0714
+#define OID_802_11_GET_CH_LIST					0x0715
+#define OID_802_11_GET_COUNTRY_CODE				0x0716
+#define OID_802_11_GET_CHANNEL_GEOGRAPHY		0x0717
 
-#if defined(RT2860) || defined(RT30xx)
-// New for MeetingHouse Api support
+#define RT_OID_WSC_SET_PASSPHRASE                   0x0740	/* passphrase for wpa(2)-psk */
+#define RT_OID_WSC_DRIVER_AUTO_CONNECT              0x0741
+#define RT_OID_WSC_QUERY_DEFAULT_PROFILE            0x0742
+#define RT_OID_WSC_SET_CONN_BY_PROFILE_INDEX        0x0743
+#define RT_OID_WSC_SET_ACTION                       0x0744
+#define RT_OID_WSC_SET_SSID                         0x0745
+#define RT_OID_WSC_SET_PIN_CODE                     0x0746
+#define RT_OID_WSC_SET_MODE                         0x0747	/* PIN or PBC */
+#define RT_OID_WSC_SET_CONF_MODE                    0x0748	/* Enrollee or Registrar */
+#define RT_OID_WSC_SET_PROFILE                      0x0749
+#define	RT_OID_WSC_CONFIG_STATUS					0x074F
+#define RT_OID_802_11_WSC_QUERY_PROFILE				0x0750
+/* for consistency with RT61 */
+#define RT_OID_WSC_QUERY_STATUS						0x0751
+#define RT_OID_WSC_PIN_CODE							0x0752
+#define RT_OID_WSC_UUID								0x0753
+#define RT_OID_WSC_SET_SELECTED_REGISTRAR			0x0754
+#define RT_OID_WSC_EAPMSG							0x0755
+#define RT_OID_WSC_MANUFACTURER						0x0756
+#define RT_OID_WSC_MODEL_NAME						0x0757
+#define RT_OID_WSC_MODEL_NO							0x0758
+#define RT_OID_WSC_SERIAL_NO						0x0759
+#define RT_OID_WSC_MAC_ADDRESS						0x0760
+
+/* New for MeetingHouse Api support */
 #define OID_MH_802_1X_SUPPORTED               0xFFEDC100
-#endif
 
-// MIMO Tx parameter, ShortGI, MCS, STBC, etc.  these are fields in TXWI. Don't change this definition!!!
-typedef union  _HTTRANSMIT_SETTING {
-	struct	{
-	USHORT   	MCS:7;                 // MCS
-	USHORT		BW:1;	//channel bandwidth 20MHz or 40 MHz
-	USHORT		ShortGI:1;
-	USHORT		STBC:2;	//SPACE
-	USHORT		rsv:2;
-	USHORT		TxBF:1;
-	USHORT		MODE:2;	// Use definition MODE_xxx.
-	}	field;
-	USHORT		word;
- } HTTRANSMIT_SETTING, *PHTTRANSMIT_SETTING;
+/* MIMO Tx parameter, ShortGI, MCS, STBC, etc.  these are fields in TXWI. Don't change this definition! */
+typedef union _HTTRANSMIT_SETTING {
+	struct {
+		u16 MCS:7;	/* MCS */
+		u16 BW:1;	/*channel bandwidth 20MHz or 40 MHz */
+		u16 ShortGI:1;
+		u16 STBC:2;	/*SPACE */
+/*      u16          rsv:3; */
+		u16 rsv:2;
+		u16 TxBF:1;
+		u16 MODE:2;	/* Use definition MODE_xxx. */
+	} field;
+	u16 word;
+} HTTRANSMIT_SETTING, *PHTTRANSMIT_SETTING;
 
 typedef enum _RT_802_11_PREAMBLE {
-    Rt802_11PreambleLong,
-    Rt802_11PreambleShort,
-    Rt802_11PreambleAuto
+	Rt802_11PreambleLong,
+	Rt802_11PreambleShort,
+	Rt802_11PreambleAuto
 } RT_802_11_PREAMBLE, *PRT_802_11_PREAMBLE;
 
-// Only for STA, need to sync with AP
 typedef enum _RT_802_11_PHY_MODE {
 	PHY_11BG_MIXED = 0,
 	PHY_11B,
 	PHY_11A,
 	PHY_11ABG_MIXED,
 	PHY_11G,
-	PHY_11ABGN_MIXED,	// both band   5
-	PHY_11N_2_4G,		// 11n-only with 2.4G band   	6
-	PHY_11GN_MIXED,	// 2.4G band      7
-	PHY_11AN_MIXED,	// 5G  band       8
-	PHY_11BGN_MIXED,	// if check 802.11b.      9
-	PHY_11AGN_MIXED,	// if check 802.11b.      10
-	PHY_11N_5G,			// 11n-only with 5G band		11
+	PHY_11ABGN_MIXED,	/* both band   5 */
+	PHY_11N_2_4G,		/* 11n-only with 2.4G band      6 */
+	PHY_11GN_MIXED,		/* 2.4G band      7 */
+	PHY_11AN_MIXED,		/* 5G  band       8 */
+	PHY_11BGN_MIXED,	/* if check 802.11b.      9 */
+	PHY_11AGN_MIXED,	/* if check 802.11b.      10 */
+	PHY_11N_5G,		/* 11n-only with 5G band                11 */
 } RT_802_11_PHY_MODE;
 
-// put all proprietery for-query objects here to reduce # of Query_OID
-typedef struct _RT_802_11_LINK_STATUS {
-    ULONG   CurrTxRate;         // in units of 0.5Mbps
-    ULONG   ChannelQuality;     // 0..100 %
-    ULONG   TxByteCount;        // both ok and fail
-    ULONG   RxByteCount;        // both ok and fail
-    ULONG	CentralChannel;		// 40MHz central channel number
-} RT_802_11_LINK_STATUS, *PRT_802_11_LINK_STATUS;
+/* put all proprietery for-query objects here to reduce # of Query_OID */
+struct rt_802_11_link_status {
+	unsigned long CurrTxRate;	/* in units of 0.5Mbps */
+	unsigned long ChannelQuality;	/* 0..100 % */
+	unsigned long TxByteCount;	/* both ok and fail */
+	unsigned long RxByteCount;	/* both ok and fail */
+	unsigned long CentralChannel;	/* 40MHz central channel number */
+};
 
-typedef struct _RT_802_11_EVENT_LOG {
-    LARGE_INTEGER   SystemTime;  // timestammp via NdisGetCurrentSystemTime()
-    UCHAR           Addr[MAC_ADDR_LENGTH];
-    USHORT          Event;       // EVENT_xxx
-} RT_802_11_EVENT_LOG, *PRT_802_11_EVENT_LOG;
+struct rt_802_11_event_log {
+	LARGE_INTEGER SystemTime;	/* timestammp via NdisGetCurrentSystemTime() */
+	u8 Addr[MAC_ADDR_LENGTH];
+	u16 Event;		/* EVENT_xxx */
+};
 
-typedef struct _RT_802_11_EVENT_TABLE {
-    ULONG       Num;
-    ULONG       Rsv;     // to align Log[] at LARGE_INEGER boundary
-    RT_802_11_EVENT_LOG   Log[MAX_NUMBER_OF_EVENT];
-} RT_802_11_EVENT_TABLE, PRT_802_11_EVENT_TABLE;
+struct rt_802_11_event_table {
+	unsigned long Num;
+	unsigned long Rsv;		/* to align Log[] at LARGE_INEGER boundary */
+	struct rt_802_11_event_log Log[MAX_NUMBER_OF_EVENT];
+};
 
-// MIMO Tx parameter, ShortGI, MCS, STBC, etc.  these are fields in TXWI. Don't change this definition!!!
-typedef union  _MACHTTRANSMIT_SETTING {
-	struct	{
-	USHORT   	MCS:7;                 // MCS
-	USHORT		BW:1;	//channel bandwidth 20MHz or 40 MHz
-	USHORT		ShortGI:1;
-	USHORT		STBC:2;	//SPACE
-	USHORT		rsv:3;
-	USHORT		MODE:2;	// Use definition MODE_xxx.
-	}	field;
-	USHORT		word;
- } MACHTTRANSMIT_SETTING, *PMACHTTRANSMIT_SETTING;
+/* MIMO Tx parameter, ShortGI, MCS, STBC, etc.  these are fields in TXWI. Don't change this definition! */
+typedef union _MACHTTRANSMIT_SETTING {
+	struct {
+		u16 MCS:7;	/* MCS */
+		u16 BW:1;	/*channel bandwidth 20MHz or 40 MHz */
+		u16 ShortGI:1;
+		u16 STBC:2;	/*SPACE */
+		u16 rsv:3;
+		u16 MODE:2;	/* Use definition MODE_xxx. */
+	} field;
+	u16 word;
+} MACHTTRANSMIT_SETTING, *PMACHTTRANSMIT_SETTING;
 
-typedef struct _RT_802_11_MAC_ENTRY {
-    UCHAR       Addr[MAC_ADDR_LENGTH];
-    UCHAR       Aid;
-    UCHAR       Psm;     // 0:PWR_ACTIVE, 1:PWR_SAVE
-    UCHAR		MimoPs;  // 0:MMPS_STATIC, 1:MMPS_DYNAMIC, 3:MMPS_Enabled
-    CHAR		AvgRssi0;
-	CHAR		AvgRssi1;
-	CHAR		AvgRssi2;
-	UINT32		ConnectedTime;
-    MACHTTRANSMIT_SETTING	TxRate;
-} RT_802_11_MAC_ENTRY, *PRT_802_11_MAC_ENTRY;
+struct rt_802_11_mac_entry {
+	u8 Addr[MAC_ADDR_LENGTH];
+	u8 Aid;
+	u8 Psm;		/* 0:PWR_ACTIVE, 1:PWR_SAVE */
+	u8 MimoPs;		/* 0:MMPS_STATIC, 1:MMPS_DYNAMIC, 3:MMPS_Enabled */
+	char AvgRssi0;
+	char AvgRssi1;
+	char AvgRssi2;
+	u32 ConnectedTime;
+	MACHTTRANSMIT_SETTING TxRate;
+};
 
-typedef struct _RT_802_11_MAC_TABLE {
-    ULONG       Num;
-    RT_802_11_MAC_ENTRY Entry[MAX_NUMBER_OF_MAC];
-} RT_802_11_MAC_TABLE, *PRT_802_11_MAC_TABLE;
+struct rt_802_11_mac_table {
+	unsigned long Num;
+	struct rt_802_11_mac_entry Entry[MAX_NUMBER_OF_MAC];
+};
 
-// structure for query/set hardware register - MAC, BBP, RF register
-typedef struct _RT_802_11_HARDWARE_REGISTER {
-    ULONG   HardwareType;       // 0:MAC, 1:BBP, 2:RF register, 3:EEPROM
-    ULONG   Offset;             // Q/S register offset addr
-    ULONG   Data;               // R/W data buffer
-} RT_802_11_HARDWARE_REGISTER, *PRT_802_11_HARDWARE_REGISTER;
+/* structure for query/set hardware register - MAC, BBP, RF register */
+struct rt_802_11_hardware_register {
+	unsigned long HardwareType;	/* 0:MAC, 1:BBP, 2:RF register, 3:EEPROM */
+	unsigned long Offset;		/* Q/S register offset addr */
+	unsigned long Data;		/* R/W data buffer */
+};
 
-typedef struct _RT_802_11_AP_CONFIG {
-    ULONG   EnableTxBurst;      // 0-disable, 1-enable
-    ULONG   EnableTurboRate;    // 0-disable, 1-enable 72/100mbps turbo rate
-    ULONG   IsolateInterStaTraffic;     // 0-disable, 1-enable isolation
-    ULONG   HideSsid;           // 0-disable, 1-enable hiding
-    ULONG   UseBGProtection;    // 0-AUTO, 1-always ON, 2-always OFF
-    ULONG   UseShortSlotTime;   // 0-no use, 1-use 9-us short slot time
-    ULONG   Rsv1;               // must be 0
-    ULONG   SystemErrorBitmap;  // ignore upon SET, return system error upon QUERY
-} RT_802_11_AP_CONFIG, *PRT_802_11_AP_CONFIG;
+struct rt_802_11_ap_config {
+	unsigned long EnableTxBurst;	/* 0-disable, 1-enable */
+	unsigned long EnableTurboRate;	/* 0-disable, 1-enable 72/100mbps turbo rate */
+	unsigned long IsolateInterStaTraffic;	/* 0-disable, 1-enable isolation */
+	unsigned long HideSsid;		/* 0-disable, 1-enable hiding */
+	unsigned long UseBGProtection;	/* 0-AUTO, 1-always ON, 2-always OFF */
+	unsigned long UseShortSlotTime;	/* 0-no use, 1-use 9-us short slot time */
+	unsigned long Rsv1;		/* must be 0 */
+	unsigned long SystemErrorBitmap;	/* ignore upon SET, return system error upon QUERY */
+};
 
-// structure to query/set STA_CONFIG
-typedef struct _RT_802_11_STA_CONFIG {
-    ULONG   EnableTxBurst;      // 0-disable, 1-enable
-    ULONG   EnableTurboRate;    // 0-disable, 1-enable 72/100mbps turbo rate
-    ULONG   UseBGProtection;    // 0-AUTO, 1-always ON, 2-always OFF
-    ULONG   UseShortSlotTime;   // 0-no use, 1-use 9-us short slot time when applicable
-    ULONG   AdhocMode; 			// 0-11b rates only (WIFI spec), 1 - b/g mixed, 2 - g only
-    ULONG   HwRadioStatus;      // 0-OFF, 1-ON, default is 1, Read-Only
-    ULONG   Rsv1;               // must be 0
-    ULONG   SystemErrorBitmap;  // ignore upon SET, return system error upon QUERY
-} RT_802_11_STA_CONFIG, *PRT_802_11_STA_CONFIG;
+/* structure to query/set STA_CONFIG */
+struct rt_802_11_sta_config {
+	unsigned long EnableTxBurst;	/* 0-disable, 1-enable */
+	unsigned long EnableTurboRate;	/* 0-disable, 1-enable 72/100mbps turbo rate */
+	unsigned long UseBGProtection;	/* 0-AUTO, 1-always ON, 2-always OFF */
+	unsigned long UseShortSlotTime;	/* 0-no use, 1-use 9-us short slot time when applicable */
+	unsigned long AdhocMode;	/* 0-11b rates only (WIFI spec), 1 - b/g mixed, 2 - g only */
+	unsigned long HwRadioStatus;	/* 0-OFF, 1-ON, default is 1, Read-Only */
+	unsigned long Rsv1;		/* must be 0 */
+	unsigned long SystemErrorBitmap;	/* ignore upon SET, return system error upon QUERY */
+};
 
-//
-//  For OID Query or Set about BA structure
-//
-typedef	struct	_OID_BACAP_STRUC	{
-		UCHAR		RxBAWinLimit;
-		UCHAR		TxBAWinLimit;
-		UCHAR		Policy;	// 0: DELAY_BA 1:IMMED_BA  (//BA Policy subfiled value in ADDBA frame)   2:BA-not use. other value invalid
-		UCHAR		MpduDensity;	// 0: DELAY_BA 1:IMMED_BA  (//BA Policy subfiled value in ADDBA frame)   2:BA-not use. other value invalid
-		UCHAR       	AmsduEnable;	//Enable AMSDU transmisstion
-		UCHAR       	AmsduSize;	// 0:3839, 1:7935 bytes. UINT  MSDUSizeToBytes[]	= { 3839, 7935};
-		UCHAR       	MMPSmode;	// MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable
-		BOOLEAN		AutoBA;	// Auto BA will automatically
-} OID_BACAP_STRUC, *POID_BACAP_STRUC;
+/* */
+/*  For OID Query or Set about BA structure */
+/* */
+struct rt_oid_bacap {
+	u8 RxBAWinLimit;
+	u8 TxBAWinLimit;
+	u8 Policy;		/* 0: DELAY_BA 1:IMMED_BA  (//BA Policy subfiled value in ADDBA frame)   2:BA-not use. other value invalid */
+	u8 MpduDensity;	/* 0: DELAY_BA 1:IMMED_BA  (//BA Policy subfiled value in ADDBA frame)   2:BA-not use. other value invalid */
+	u8 AmsduEnable;	/*Enable AMSDU transmisstion */
+	u8 AmsduSize;	/* 0:3839, 1:7935 bytes. u32  MSDUSizeToBytes[]        = { 3839, 7935}; */
+	u8 MMPSmode;		/* MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable */
+	BOOLEAN AutoBA;		/* Auto BA will automatically */
+};
 
-typedef struct _RT_802_11_ACL_ENTRY {
-    UCHAR   Addr[MAC_ADDR_LENGTH];
-    USHORT  Rsv;
-} RT_802_11_ACL_ENTRY, *PRT_802_11_ACL_ENTRY;
+struct rt_802_11_acl_entry {
+	u8 Addr[MAC_ADDR_LENGTH];
+	u16 Rsv;
+};
 
-typedef struct PACKED _RT_802_11_ACL {
-    ULONG   Policy;             // 0-disable, 1-positive list, 2-negative list
-    ULONG   Num;
-    RT_802_11_ACL_ENTRY Entry[MAX_NUMBER_OF_ACL];
-} RT_802_11_ACL, *PRT_802_11_ACL;
+struct PACKED rt_rt_802_11_acl {
+	unsigned long Policy;		/* 0-disable, 1-positive list, 2-negative list */
+	unsigned long Num;
+	struct rt_802_11_acl_entry Entry[MAX_NUMBER_OF_ACL];
+};
 
-typedef struct _RT_802_11_WDS {
-    ULONG						Num;
-    NDIS_802_11_MAC_ADDRESS		Entry[24/*MAX_NUM_OF_WDS_LINK*/];
-	ULONG						KeyLength;
-	UCHAR						KeyMaterial[32];
-} RT_802_11_WDS, *PRT_802_11_WDS;
+struct rt_802_11_wds {
+	unsigned long Num;
+	NDIS_802_11_MAC_ADDRESS Entry[24 /*MAX_NUM_OF_WDS_LINK */ ];
+	unsigned long KeyLength;
+	u8 KeyMaterial[32];
+};
 
-typedef struct _RT_802_11_TX_RATES_ {
-    UCHAR       SupRateLen;
-    UCHAR       SupRate[MAX_LENGTH_OF_SUPPORT_RATES];
-    UCHAR       ExtRateLen;
-    UCHAR       ExtRate[MAX_LENGTH_OF_SUPPORT_RATES];
-} RT_802_11_TX_RATES, *PRT_802_11_TX_RATES;
+struct rt_802_11_tx_rates {
+	u8 SupRateLen;
+	u8 SupRate[MAX_LENGTH_OF_SUPPORT_RATES];
+	u8 ExtRateLen;
+	u8 ExtRate[MAX_LENGTH_OF_SUPPORT_RATES];
+};
 
-
-// Definition of extra information code
-#define	GENERAL_LINK_UP			0x0			// Link is Up
-#define	GENERAL_LINK_DOWN		0x1			// Link is Down
-#define	HW_RADIO_OFF			0x2			// Hardware radio off
-#define	SW_RADIO_OFF			0x3			// Software radio off
-#define	AUTH_FAIL				0x4			// Open authentication fail
-#define	AUTH_FAIL_KEYS			0x5			// Shared authentication fail
-#define	ASSOC_FAIL				0x6			// Association failed
-#define	EAP_MIC_FAILURE			0x7			// Deauthencation because MIC failure
-#define	EAP_4WAY_TIMEOUT		0x8			// Deauthencation on 4-way handshake timeout
-#define	EAP_GROUP_KEY_TIMEOUT	0x9			// Deauthencation on group key handshake timeout
-#define	EAP_SUCCESS				0xa			// EAP succeed
-#define	DETECT_RADAR_SIGNAL		0xb         // Radar signal occur in current channel
-#define EXTRA_INFO_MAX			0xb			// Indicate Last OID
+/* Definition of extra information code */
+#define	GENERAL_LINK_UP			0x0	/* Link is Up */
+#define	GENERAL_LINK_DOWN		0x1	/* Link is Down */
+#define	HW_RADIO_OFF			0x2	/* Hardware radio off */
+#define	SW_RADIO_OFF			0x3	/* Software radio off */
+#define	AUTH_FAIL				0x4	/* Open authentication fail */
+#define	AUTH_FAIL_KEYS			0x5	/* Shared authentication fail */
+#define	ASSOC_FAIL				0x6	/* Association failed */
+#define	EAP_MIC_FAILURE			0x7	/* Deauthencation because MIC failure */
+#define	EAP_4WAY_TIMEOUT		0x8	/* Deauthencation on 4-way handshake timeout */
+#define	EAP_GROUP_KEY_TIMEOUT	0x9	/* Deauthencation on group key handshake timeout */
+#define	EAP_SUCCESS				0xa	/* EAP succeed */
+#define	DETECT_RADAR_SIGNAL		0xb	/* Radar signal occur in current channel */
+#define EXTRA_INFO_MAX			0xb	/* Indicate Last OID */
 
 #define EXTRA_INFO_CLEAR		0xffffffff
 
-// This is OID setting structure. So only GF or MM as Mode. This is valid when our wirelss mode has 802.11n in use.
-typedef struct {
-	RT_802_11_PHY_MODE		PhyMode; 	//
-	UCHAR		TransmitNo;
-	UCHAR		HtMode; 	//HTMODE_GF or HTMODE_MM
-	UCHAR		ExtOffset;	//extension channel above or below
-	UCHAR		MCS;
-	UCHAR   	BW;
-	UCHAR		STBC;
-	UCHAR		SHORTGI;
-	UCHAR		rsv;
-} OID_SET_HT_PHYMODE, *POID_SET_HT_PHYMODE;
-
-#ifdef LLTD_SUPPORT
-typedef struct _RT_LLTD_ASSOICATION_ENTRY {
-    UCHAR           Addr[ETH_LENGTH_OF_ADDRESS];
-    unsigned short  MOR;        // maximum operational rate
-    UCHAR           phyMode;
-} RT_LLTD_ASSOICATION_ENTRY, *PRT_LLTD_ASSOICATION_ENTRY;
-
-typedef struct _RT_LLTD_ASSOICATION_TABLE {
-    unsigned int                Num;
-    RT_LLTD_ASSOICATION_ENTRY   Entry[MAX_NUMBER_OF_MAC];
-} RT_LLTD_ASSOICATION_TABLE, *PRT_LLTD_ASSOICATION_TABLE;
-#endif // LLTD_SUPPORT //
+/* This is OID setting structure. So only GF or MM as Mode. This is valid when our wirelss mode has 802.11n in use. */
+struct rt_oid_set_ht_phymode {
+	RT_802_11_PHY_MODE PhyMode;	/* */
+	u8 TransmitNo;
+	u8 HtMode;		/*HTMODE_GF or HTMODE_MM */
+	u8 ExtOffset;	/*extension channel above or below */
+	u8 MCS;
+	u8 BW;
+	u8 STBC;
+	u8 SHORTGI;
+	u8 rsv;
+};
 
 #define MAX_CUSTOM_LEN 128
 
-typedef enum _RT_802_11_D_CLIENT_MODE
-{
-   Rt802_11_D_None,
-   Rt802_11_D_Flexible,
-   Rt802_11_D_Strict,
+typedef enum _RT_802_11_D_CLIENT_MODE {
+	Rt802_11_D_None,
+	Rt802_11_D_Flexible,
+	Rt802_11_D_Strict,
 } RT_802_11_D_CLIENT_MODE, *PRT_802_11_D_CLIENT_MODE;
 
-typedef struct _RT_CHANNEL_LIST_INFO
-{
-	UCHAR ChannelList[MAX_NUM_OF_CHS];   // list all supported channels for site survey
-	UCHAR ChannelListNum; // number of channel in ChannelList[]
-} RT_CHANNEL_LIST_INFO, *PRT_CHANNEL_LIST_INFO;
+struct rt_channel_list_info {
+	u8 ChannelList[MAX_NUM_OF_CHS];	/* list all supported channels for site survey */
+	u8 ChannelListNum;	/* number of channel in ChannelList[] */
+};
 
-#ifdef RT2870
-// WSC configured credential
-typedef	struct	_WSC_CREDENTIAL
-{
-	NDIS_802_11_SSID	SSID;				// mandatory
-	USHORT				AuthType;			// mandatory, 1: open, 2: wpa-psk, 4: shared, 8:wpa, 0x10: wpa2, 0x20: wpa2-psk
-	USHORT				EncrType;			// mandatory, 1: none, 2: wep, 4: tkip, 8: aes
-	UCHAR				Key[64];			// mandatory, Maximum 64 byte
-	USHORT				KeyLength;
-	UCHAR				MacAddr[6];			// mandatory, AP MAC address
-	UCHAR				KeyIndex;			// optional, default is 1
-	UCHAR				Rsvd[3];			// Make alignment
-}	WSC_CREDENTIAL, *PWSC_CREDENTIAL;
+/* WSC configured credential */
+struct rt_wsc_credential {
+	struct rt_ndis_802_11_ssid SSID;	/* mandatory */
+	u16 AuthType;	/* mandatory, 1: open, 2: wpa-psk, 4: shared, 8:wpa, 0x10: wpa2, 0x20: wpa2-psk */
+	u16 EncrType;	/* mandatory, 1: none, 2: wep, 4: tkip, 8: aes */
+	u8 Key[64];		/* mandatory, Maximum 64 byte */
+	u16 KeyLength;
+	u8 MacAddr[6];	/* mandatory, AP MAC address */
+	u8 KeyIndex;		/* optional, default is 1 */
+	u8 Rsvd[3];		/* Make alignment */
+};
 
-// WSC configured profiles
-typedef	struct	_WSC_PROFILE
-{
-	UINT			ProfileCnt;
-	WSC_CREDENTIAL	Profile[8];				// Support up to 8 profiles
-}	WSC_PROFILE, *PWSC_PROFILE;
-#endif
+/* WSC configured profiles */
+struct rt_wsc_profile {
+	u32 ProfileCnt;
+	u32 ApplyProfileIdx;	/* add by johnli, fix WPS test plan 5.1.1 */
+	struct rt_wsc_credential Profile[8];	/* Support up to 8 profiles */
+};
 
-#endif // _OID_H_
-
+#endif /* _OID_H_ */
diff --git a/drivers/staging/rt2860/pci_main_dev.c b/drivers/staging/rt2860/pci_main_dev.c
new file mode 100644
index 0000000..6af4304
--- /dev/null
+++ b/drivers/staging/rt2860/pci_main_dev.c
@@ -0,0 +1,1190 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+    pci_main_dev.c
+
+    Abstract:
+    Create and register network interface for PCI based chipsets in Linux platform.
+
+    Revision History:
+    Who         When            What
+    --------    ----------      ----------------------------------------------
+*/
+
+#include "rt_config.h"
+#include <linux/pci.h>
+
+/* Following information will be show when you run 'modinfo' */
+/* *** If you have a solution for the bug in current version of driver, please mail to me. */
+/* Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. *** */
+MODULE_AUTHOR("Jett Chen <jett_chen@ralinktech.com>");
+MODULE_DESCRIPTION("RT2860/RT3090 Wireless Lan Linux Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("rt3090sta");
+
+/* */
+/* Function declarations */
+/* */
+extern int rt28xx_close(IN struct net_device *net_dev);
+extern int rt28xx_open(struct net_device *net_dev);
+
+static void __devexit rt2860_remove_one(struct pci_dev *pci_dev);
+static int __devinit rt2860_probe(struct pci_dev *pci_dev,
+				  const struct pci_device_id *ent);
+static void __exit rt2860_cleanup_module(void);
+static int __init rt2860_init_module(void);
+
+static void RTMPInitPCIeDevice(IN struct pci_dev *pci_dev,
+			       struct rt_rtmp_adapter *pAd);
+
+#ifdef CONFIG_PM
+static int rt2860_suspend(struct pci_dev *pci_dev, pm_message_t state);
+static int rt2860_resume(struct pci_dev *pci_dev);
+#endif /* CONFIG_PM // */
+
+/* */
+/* Ralink PCI device table, include all supported chipsets */
+/* */
+static struct pci_device_id rt2860_pci_tbl[] __devinitdata = {
+#ifdef RT2860
+	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2860_PCI_DEVICE_ID)},	/*RT28602.4G */
+	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2860_PCIe_DEVICE_ID)},
+	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2760_PCI_DEVICE_ID)},
+	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2790_PCIe_DEVICE_ID)},
+	{PCI_DEVICE(VEN_AWT_PCI_VENDOR_ID, VEN_AWT_PCIe_DEVICE_ID)},
+	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7708)},
+	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7728)},
+	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7758)},
+	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7727)},
+	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7738)},
+	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7748)},
+	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7768)},
+#endif
+#ifdef RT3090
+	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3090_PCIe_DEVICE_ID)},
+	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3091_PCIe_DEVICE_ID)},
+	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3092_PCIe_DEVICE_ID)},
+#endif /* RT3090 // */
+#ifdef RT3390
+	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3390_PCIe_DEVICE_ID)},
+	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3391_PCIe_DEVICE_ID)},
+	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3392_PCIe_DEVICE_ID)},
+#endif /* RT3390 // */
+	{0,}			/* terminate list */
+};
+
+MODULE_DEVICE_TABLE(pci, rt2860_pci_tbl);
+#ifdef MODULE_VERSION
+MODULE_VERSION(STA_DRIVER_VERSION);
+#endif
+
+/* */
+/* Our PCI driver structure */
+/* */
+static struct pci_driver rt2860_driver = {
+name:	"rt2860",
+id_table:rt2860_pci_tbl,
+probe:	rt2860_probe,
+remove:__devexit_p(rt2860_remove_one),
+#ifdef CONFIG_PM
+suspend:rt2860_suspend,
+resume:rt2860_resume,
+#endif
+};
+
+/***************************************************************************
+ *
+ *	PCI device initialization related procedures.
+ *
+ ***************************************************************************/
+#ifdef CONFIG_PM
+
+void RT2860RejectPendingPackets(struct rt_rtmp_adapter *pAd)
+{
+	/* clear PS packets */
+	/* clear TxSw packets */
+}
+
+static int rt2860_suspend(struct pci_dev *pci_dev, pm_message_t state)
+{
+	struct net_device *net_dev = pci_get_drvdata(pci_dev);
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)NULL;
+	int retval = 0;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_suspend()\n"));
+
+	if (net_dev == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n"));
+	} else {
+		GET_PAD_FROM_NET_DEV(pAd, net_dev);
+
+		/* we can not use IFF_UP because ra0 down but ra1 up */
+		/* and 1 suspend/resume function for 1 module, not for each interface */
+		/* so Linux will call suspend/resume function once */
+		if (VIRTUAL_IF_NUM(pAd) > 0) {
+			/* avoid users do suspend after interface is down */
+
+			/* stop interface */
+			netif_carrier_off(net_dev);
+			netif_stop_queue(net_dev);
+
+			/* mark device as removed from system and therefore no longer available */
+			netif_device_detach(net_dev);
+
+			/* mark halt flag */
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
+			/* take down the device */
+			rt28xx_close((struct net_device *)net_dev);
+
+			RT_MOD_DEC_USE_COUNT();
+		}
+	}
+
+	/* reference to http://vovo2000.com/type-lab/linux/kernel-api/linux-kernel-api.html */
+	/* enable device to generate PME# when suspended */
+	/* pci_choose_state(): Choose the power state of a PCI device to be suspended */
+	retval = pci_enable_wake(pci_dev, pci_choose_state(pci_dev, state), 1);
+	/* save the PCI configuration space of a device before suspending */
+	pci_save_state(pci_dev);
+	/* disable PCI device after use */
+	pci_disable_device(pci_dev);
+
+	retval = pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_suspend()\n"));
+	return retval;
+}
+
+static int rt2860_resume(struct pci_dev *pci_dev)
+{
+	struct net_device *net_dev = pci_get_drvdata(pci_dev);
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)NULL;
+	int retval;
+
+	/* set the power state of a PCI device */
+	/* PCI has 4 power states, DO (normal) ~ D3(less power) */
+	/* in include/linux/pci.h, you can find that */
+	/* #define PCI_D0          ((pci_power_t __force) 0) */
+	/* #define PCI_D1          ((pci_power_t __force) 1) */
+	/* #define PCI_D2          ((pci_power_t __force) 2) */
+	/* #define PCI_D3hot       ((pci_power_t __force) 3) */
+	/* #define PCI_D3cold      ((pci_power_t __force) 4) */
+	/* #define PCI_UNKNOWN     ((pci_power_t __force) 5) */
+	/* #define PCI_POWER_ERROR ((pci_power_t __force) -1) */
+	retval = pci_set_power_state(pci_dev, PCI_D0);
+
+	/* restore the saved state of a PCI device */
+	pci_restore_state(pci_dev);
+
+	/* initialize device before it's used by a driver */
+	if (pci_enable_device(pci_dev)) {
+		printk("pci enable fail!\n");
+		return 0;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_resume()\n"));
+
+	if (net_dev == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n"));
+	} else
+		GET_PAD_FROM_NET_DEV(pAd, net_dev);
+
+	if (pAd != NULL) {
+		/* we can not use IFF_UP because ra0 down but ra1 up */
+		/* and 1 suspend/resume function for 1 module, not for each interface */
+		/* so Linux will call suspend/resume function once */
+		if (VIRTUAL_IF_NUM(pAd) > 0) {
+			/* mark device as attached from system and restart if needed */
+			netif_device_attach(net_dev);
+
+			if (rt28xx_open((struct net_device *)net_dev) != 0) {
+				/* open fail */
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("<=== rt2860_resume()\n"));
+				return 0;
+			}
+			/* increase MODULE use count */
+			RT_MOD_INC_USE_COUNT();
+
+			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
+			netif_start_queue(net_dev);
+			netif_carrier_on(net_dev);
+			netif_wake_queue(net_dev);
+		}
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_resume()\n"));
+	return 0;
+}
+#endif /* CONFIG_PM // */
+
+static int __init rt2860_init_module(void)
+{
+	return pci_register_driver(&rt2860_driver);
+}
+
+/* */
+/* Driver module unload function */
+/* */
+static void __exit rt2860_cleanup_module(void)
+{
+	pci_unregister_driver(&rt2860_driver);
+}
+
+module_init(rt2860_init_module);
+module_exit(rt2860_cleanup_module);
+
+/* */
+/* PCI device probe & initialization function */
+/* */
+static int __devinit rt2860_probe(IN struct pci_dev *pci_dev,
+				  IN const struct pci_device_id *pci_id)
+{
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)NULL;
+	struct net_device *net_dev;
+	void *handle;
+	char *print_name;
+	unsigned long csr_addr;
+	int rv = 0;
+	struct rt_rtmp_os_netdev_op_hook netDevHook;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_probe\n"));
+
+/*PCIDevInit============================================== */
+	/* wake up and enable device */
+	if ((rv = pci_enable_device(pci_dev)) != 0) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("Enable PCI device failed, errno=%d!\n", rv));
+		return rv;
+	}
+
+	print_name = (char *)pci_name(pci_dev);
+
+	if ((rv = pci_request_regions(pci_dev, print_name)) != 0) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("Request PCI resource failed, errno=%d!\n", rv));
+		goto err_out;
+	}
+	/* map physical address to virtual address for accessing register */
+	csr_addr =
+	    (unsigned long)ioremap(pci_resource_start(pci_dev, 0),
+				   pci_resource_len(pci_dev, 0));
+	if (!csr_addr) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("ioremap failed for device %s, region 0x%lX @ 0x%lX\n",
+			  print_name, (unsigned long)pci_resource_len(pci_dev, 0),
+			  (unsigned long)pci_resource_start(pci_dev, 0)));
+		goto err_out_free_res;
+	} else {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("%s: at 0x%lx, VA 0x%lx, IRQ %d. \n", print_name,
+			  (unsigned long)pci_resource_start(pci_dev, 0),
+			  (unsigned long)csr_addr, pci_dev->irq));
+	}
+
+	/* Set DMA master */
+	pci_set_master(pci_dev);
+
+/*RtmpDevInit============================================== */
+	/* Allocate struct rt_rtmp_adapter adapter structure */
+	handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL);
+	if (handle == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("%s(): Allocate memory for os handle failed!\n",
+			  __func__));
+		goto err_out_iounmap;
+	}
+
+	((struct os_cookie *)handle)->pci_dev = pci_dev;
+
+	rv = RTMPAllocAdapterBlock(handle, &pAd);	/*shiang: we may need the pci_dev for allocate structure of "struct rt_rtmp_adapter" */
+	if (rv != NDIS_STATUS_SUCCESS)
+		goto err_out_iounmap;
+	/* Here are the struct rt_rtmp_adapter structure with pci-bus specific parameters. */
+	pAd->CSRBaseAddress = (u8 *)csr_addr;
+	DBGPRINT(RT_DEBUG_ERROR,
+		 ("pAd->CSRBaseAddress =0x%lx, csr_addr=0x%lx!\n",
+		  (unsigned long)pAd->CSRBaseAddress, csr_addr));
+	RtmpRaDevCtrlInit(pAd, RTMP_DEV_INF_PCI);
+
+/*NetDevInit============================================== */
+	net_dev = RtmpPhyNetDevInit(pAd, &netDevHook);
+	if (net_dev == NULL)
+		goto err_out_free_radev;
+
+	/* Here are the net_device structure with pci-bus specific parameters. */
+	net_dev->irq = pci_dev->irq;	/* Interrupt IRQ number */
+	net_dev->base_addr = csr_addr;	/* Save CSR virtual address and irq to device structure */
+	pci_set_drvdata(pci_dev, net_dev);	/* Set driver data */
+
+/* for supporting Network Manager */
+	/* Set the sysfs physical device reference for the network logical device
+	 * if set prior to registration will cause a symlink during initialization.
+	 */
+	SET_NETDEV_DEV(net_dev, &(pci_dev->dev));
+
+/*All done, it's time to register the net device to linux kernel. */
+	/* Register this device */
+	rv = RtmpOSNetDevAttach(net_dev, &netDevHook);
+	if (rv)
+		goto err_out_free_netdev;
+
+	pAd->StaCfg.OriDevType = net_dev->type;
+	RTMPInitPCIeDevice(pci_dev, pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_probe\n"));
+
+	return 0;		/* probe ok */
+
+	/* --------------------------- ERROR HANDLE --------------------------- */
+err_out_free_netdev:
+	RtmpOSNetDevFree(net_dev);
+
+err_out_free_radev:
+	/* free struct rt_rtmp_adapter strcuture and os_cookie */
+	RTMPFreeAdapter(pAd);
+
+err_out_iounmap:
+	iounmap((void *)(csr_addr));
+	release_mem_region(pci_resource_start(pci_dev, 0),
+			   pci_resource_len(pci_dev, 0));
+
+err_out_free_res:
+	pci_release_regions(pci_dev);
+
+err_out:
+	pci_disable_device(pci_dev);
+
+	DBGPRINT(RT_DEBUG_ERROR,
+		 ("<=== rt2860_probe failed with rv = %d!\n", rv));
+
+	return -ENODEV;		/* probe fail */
+}
+
+static void __devexit rt2860_remove_one(IN struct pci_dev *pci_dev)
+{
+	struct net_device *net_dev = pci_get_drvdata(pci_dev);
+	struct rt_rtmp_adapter *pAd = NULL;
+	unsigned long csr_addr = net_dev->base_addr;	/* pAd->CSRBaseAddress; */
+
+	GET_PAD_FROM_NET_DEV(pAd, net_dev);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_remove_one\n"));
+
+	if (pAd != NULL) {
+		/* Unregister/Free all allocated net_device. */
+		RtmpPhyNetDevExit(pAd, net_dev);
+
+		/* Unmap CSR base address */
+		iounmap((char *)(csr_addr));
+
+		/* release memory region */
+		release_mem_region(pci_resource_start(pci_dev, 0),
+				   pci_resource_len(pci_dev, 0));
+
+		/* Free struct rt_rtmp_adapter related structures. */
+		RtmpRaDevCtrlExit(pAd);
+
+	} else {
+		/* Unregister network device */
+		RtmpOSNetDevDetach(net_dev);
+
+		/* Unmap CSR base address */
+		iounmap((char *)(net_dev->base_addr));
+
+		/* release memory region */
+		release_mem_region(pci_resource_start(pci_dev, 0),
+				   pci_resource_len(pci_dev, 0));
+	}
+
+	/* Free the root net_device */
+	RtmpOSNetDevFree(net_dev);
+
+}
+
+/*
+========================================================================
+Routine Description:
+    Check the chipset vendor/product ID.
+
+Arguments:
+    _dev_p				Point to the PCI or USB device
+
+Return Value:
+    TRUE				Check ok
+	FALSE				Check fail
+
+Note:
+========================================================================
+*/
+BOOLEAN RT28XXChipsetCheck(IN void *_dev_p)
+{
+	/* always TRUE */
+	return TRUE;
+}
+
+/***************************************************************************
+ *
+ *	PCIe device initialization related procedures.
+ *
+ ***************************************************************************/
+static void RTMPInitPCIeDevice(struct pci_dev *pci_dev, struct rt_rtmp_adapter *pAd)
+{
+	u16 device_id;
+	struct os_cookie *pObj;
+
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
+	pci_read_config_word(pci_dev, PCI_DEVICE_ID, &device_id);
+	device_id = le2cpu16(device_id);
+	pObj->DeviceID = device_id;
+	if (
+#ifdef RT2860
+		   (device_id == NIC2860_PCIe_DEVICE_ID) ||
+		   (device_id == NIC2790_PCIe_DEVICE_ID) ||
+		   (device_id == VEN_AWT_PCIe_DEVICE_ID) ||
+#endif
+#ifdef RT3090
+		   (device_id == NIC3090_PCIe_DEVICE_ID) ||
+		   (device_id == NIC3091_PCIe_DEVICE_ID) ||
+		   (device_id == NIC3092_PCIe_DEVICE_ID) ||
+#endif /* RT3090 // */
+		   0) {
+		u32 MacCsr0 = 0, Index = 0;
+		do {
+			RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
+
+			if ((MacCsr0 != 0x00) && (MacCsr0 != 0xFFFFFFFF))
+				break;
+
+			RTMPusecDelay(10);
+		} while (Index++ < 100);
+
+		/* Support advanced power save after 2892/2790. */
+		/* MAC version at offset 0x1000 is 0x2872XXXX/0x2870XXXX(PCIe, USB, SDIO). */
+		if ((MacCsr0 & 0xffff0000) != 0x28600000) {
+			OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PCIE_DEVICE);
+		}
+	}
+}
+
+void RTMPInitPCIeLinkCtrlValue(struct rt_rtmp_adapter *pAd)
+{
+	int pos;
+	u16 reg16, data2, PCIePowerSaveLevel, Configuration;
+	u32 MacValue;
+	BOOLEAN bFindIntel = FALSE;
+	struct os_cookie *pObj;
+
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
+		return;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __func__));
+	/* Init EEPROM, and save settings */
+	if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) {
+		RT28xx_EEPROM_READ16(pAd, 0x22, PCIePowerSaveLevel);
+		pAd->PCIePowerSaveLevel = PCIePowerSaveLevel & 0xff;
+
+		pAd->LnkCtrlBitMask = 0;
+		if ((PCIePowerSaveLevel & 0xff) == 0xff) {
+			OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PCIE_DEVICE);
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("====> PCIePowerSaveLevel = 0x%x.\n",
+				  PCIePowerSaveLevel));
+			return;
+		} else {
+			PCIePowerSaveLevel &= 0x3;
+			RT28xx_EEPROM_READ16(pAd, 0x24, data2);
+
+			if (!
+			    (((data2 & 0xff00) == 0x9200)
+			     && ((data2 & 0x80) != 0))) {
+				if (PCIePowerSaveLevel > 1)
+					PCIePowerSaveLevel = 1;
+			}
+
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("====> Write 0x83 = 0x%x.\n",
+				  PCIePowerSaveLevel));
+			AsicSendCommandToMcu(pAd, 0x83, 0xff,
+					     (u8)PCIePowerSaveLevel, 0x00);
+			RT28xx_EEPROM_READ16(pAd, 0x22, PCIePowerSaveLevel);
+			PCIePowerSaveLevel &= 0xff;
+			PCIePowerSaveLevel = PCIePowerSaveLevel >> 6;
+			switch (PCIePowerSaveLevel) {
+			case 0:	/* Only support L0 */
+				pAd->LnkCtrlBitMask = 0;
+				break;
+			case 1:	/* Only enable L0s */
+				pAd->LnkCtrlBitMask = 1;
+				break;
+			case 2:	/* enable L1, L0s */
+				pAd->LnkCtrlBitMask = 3;
+				break;
+			case 3:	/* sync with host clk and enable L1, L0s */
+				pAd->LnkCtrlBitMask = 0x103;
+				break;
+			}
+			RT28xx_EEPROM_READ16(pAd, 0x24, data2);
+			if ((PCIePowerSaveLevel & 0xff) != 0xff) {
+				PCIePowerSaveLevel &= 0x3;
+
+				if (!
+				    (((data2 & 0xff00) == 0x9200)
+				     && ((data2 & 0x80) != 0))) {
+					if (PCIePowerSaveLevel > 1)
+						PCIePowerSaveLevel = 1;
+				}
+
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("====> rt28xx Write 0x83 Command = 0x%x.\n",
+					  PCIePowerSaveLevel));
+
+				AsicSendCommandToMcu(pAd, 0x83, 0xff,
+						     (u8)PCIePowerSaveLevel,
+						     0x00);
+			}
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("====> LnkCtrlBitMask = 0x%x.\n",
+				  pAd->LnkCtrlBitMask));
+		}
+	} else if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) {
+		u8 LinkCtrlSetting = 0;
+
+		/* Check 3090E special setting chip. */
+		RT28xx_EEPROM_READ16(pAd, 0x24, data2);
+		if ((data2 == 0x9280) && ((pAd->MACVersion & 0xffff) == 0x0211)) {
+			pAd->b3090ESpecialChip = TRUE;
+			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Special 3090E chip \n"));
+		}
+
+		RTMP_IO_READ32(pAd, AUX_CTRL, &MacValue);
+		/*enable WAKE_PCIE function, which forces to enable PCIE clock when mpu interrupt asserting. */
+		/*Force PCIE 125MHz CLK to toggle */
+		MacValue |= 0x402;
+		RTMP_IO_WRITE32(pAd, AUX_CTRL, MacValue);
+		DBGPRINT_RAW(RT_DEBUG_ERROR,
+			     (" AUX_CTRL = 0x%32x\n", MacValue));
+
+		/* for RT30xx F and after, PCIe infterface, and for power solution 3 */
+		if ((IS_VERSION_AFTER_F(pAd))
+		    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode >= 2)
+		    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode <= 3)) {
+			RTMP_IO_READ32(pAd, AUX_CTRL, &MacValue);
+			DBGPRINT_RAW(RT_DEBUG_ERROR,
+				     (" Read AUX_CTRL = 0x%x\n", MacValue));
+			/* turn on bit 12. */
+			/*enable 32KHz clock mode for power saving */
+			MacValue |= 0x1000;
+			if (MacValue != 0xffffffff) {
+				RTMP_IO_WRITE32(pAd, AUX_CTRL, MacValue);
+				DBGPRINT_RAW(RT_DEBUG_ERROR,
+					     (" Write AUX_CTRL = 0x%x\n",
+					      MacValue));
+				/* 1. if use PCIePowerSetting is 2 or 3, need to program OSC_CTRL to 0x3ff11. */
+				MacValue = 0x3ff11;
+				RTMP_IO_WRITE32(pAd, OSC_CTRL, MacValue);
+				DBGPRINT_RAW(RT_DEBUG_ERROR,
+					     (" OSC_CTRL = 0x%x\n", MacValue));
+				/* 2. Write PCI register Clk ref bit */
+				RTMPrt3xSetPCIePowerLinkCtrl(pAd);
+			} else {
+				/* Error read Aux_Ctrl value.  Force to use solution 1 */
+				DBGPRINT(RT_DEBUG_ERROR,
+					 (" Error Value in AUX_CTRL = 0x%x\n",
+					  MacValue));
+				pAd->StaCfg.PSControl.field.rt30xxPowerMode = 1;
+				DBGPRINT(RT_DEBUG_ERROR,
+					 (" Force to use power solution1 \n"));
+			}
+		}
+		/* 1. read setting from inf file. */
+
+		PCIePowerSaveLevel =
+		    (u16)pAd->StaCfg.PSControl.field.rt30xxPowerMode;
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("====> rt30xx Read PowerLevelMode =  0x%x.\n",
+			  PCIePowerSaveLevel));
+		/* 2. Check EnableNewPS. */
+		if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE)
+			PCIePowerSaveLevel = 1;
+
+		if (IS_VERSION_BEFORE_F(pAd)
+		    && (pAd->b3090ESpecialChip == FALSE)) {
+			/* Chip Version E only allow 1, So force set 1. */
+			PCIePowerSaveLevel &= 0x1;
+			pAd->PCIePowerSaveLevel = (u16)PCIePowerSaveLevel;
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("====> rt30xx E Write 0x83 Command = 0x%x.\n",
+				  PCIePowerSaveLevel));
+
+			AsicSendCommandToMcu(pAd, 0x83, 0xff,
+					     (u8)PCIePowerSaveLevel, 0x00);
+		} else {
+			/* Chip Version F and after only allow 1 or 2 or 3. This might be modified after new chip version come out. */
+			if (!
+			    ((PCIePowerSaveLevel == 1)
+			     || (PCIePowerSaveLevel == 3)))
+				PCIePowerSaveLevel = 1;
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("====> rt30xx F Write 0x83 Command = 0x%x.\n",
+				  PCIePowerSaveLevel));
+			pAd->PCIePowerSaveLevel = (u16)PCIePowerSaveLevel;
+			/* for 3090F , we need to add high-byte arg for 0x83 command to indicate the link control setting in */
+			/* PCI Configuration Space. Because firmware can't read PCI Configuration Space */
+			if ((pAd->Rt3xxRalinkLinkCtrl & 0x2)
+			    && (pAd->Rt3xxHostLinkCtrl & 0x2)) {
+				LinkCtrlSetting = 1;
+			}
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("====> rt30xxF LinkCtrlSetting = 0x%x.\n",
+				  LinkCtrlSetting));
+			AsicSendCommandToMcu(pAd, 0x83, 0xff,
+					     (u8)PCIePowerSaveLevel,
+					     LinkCtrlSetting);
+		}
+	}
+	/* Find Ralink PCIe Device's Express Capability Offset */
+	pos = pci_find_capability(pObj->pci_dev, PCI_CAP_ID_EXP);
+
+	if (pos != 0) {
+		/* Ralink PCIe Device's Link Control Register Offset */
+		pAd->RLnkCtrlOffset = pos + PCI_EXP_LNKCTL;
+		pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset,
+				     &reg16);
+		Configuration = le2cpu16(reg16);
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Read (Ralink PCIe Link Control Register) offset 0x%x = 0x%x\n",
+			  pAd->RLnkCtrlOffset, Configuration));
+		pAd->RLnkCtrlConfiguration = (Configuration & 0x103);
+		Configuration &= 0xfefc;
+		Configuration |= (0x0);
+#ifdef RT2860
+		if ((pObj->DeviceID == NIC2860_PCIe_DEVICE_ID)
+		    || (pObj->DeviceID == NIC2790_PCIe_DEVICE_ID)) {
+			reg16 = cpu2le16(Configuration);
+			pci_write_config_word(pObj->pci_dev,
+					      pAd->RLnkCtrlOffset, reg16);
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("Write (Ralink PCIe Link Control Register)  offset 0x%x = 0x%x\n",
+				  pos + PCI_EXP_LNKCTL, Configuration));
+		}
+#endif /* RT2860 // */
+
+		RTMPFindHostPCIDev(pAd);
+		if (pObj->parent_pci_dev) {
+			u16 vendor_id;
+
+			pci_read_config_word(pObj->parent_pci_dev,
+					     PCI_VENDOR_ID, &vendor_id);
+			vendor_id = le2cpu16(vendor_id);
+			if (vendor_id == PCIBUS_INTEL_VENDOR) {
+				bFindIntel = TRUE;
+				RTMP_SET_PSFLAG(pAd, fRTMP_PS_TOGGLE_L1);
+			}
+			/* Find PCI-to-PCI Bridge Express Capability Offset */
+			pos =
+			    pci_find_capability(pObj->parent_pci_dev,
+						PCI_CAP_ID_EXP);
+
+			if (pos != 0) {
+				BOOLEAN bChange = FALSE;
+				/* PCI-to-PCI Bridge Link Control Register Offset */
+				pAd->HostLnkCtrlOffset = pos + PCI_EXP_LNKCTL;
+				pci_read_config_word(pObj->parent_pci_dev,
+						     pAd->HostLnkCtrlOffset,
+						     &reg16);
+				Configuration = le2cpu16(reg16);
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("Read (Host PCI-to-PCI Bridge Link Control Register) offset 0x%x = 0x%x\n",
+					  pAd->HostLnkCtrlOffset,
+					  Configuration));
+				pAd->HostLnkCtrlConfiguration =
+				    (Configuration & 0x103);
+				Configuration &= 0xfefc;
+				Configuration |= (0x0);
+
+				switch (pObj->DeviceID) {
+#ifdef RT2860
+				case NIC2860_PCIe_DEVICE_ID:
+				case NIC2790_PCIe_DEVICE_ID:
+					bChange = TRUE;
+					break;
+#endif /* RT2860 // */
+#ifdef RT3090
+				case NIC3090_PCIe_DEVICE_ID:
+				case NIC3091_PCIe_DEVICE_ID:
+				case NIC3092_PCIe_DEVICE_ID:
+					if (bFindIntel == FALSE)
+						bChange = TRUE;
+					break;
+#endif /* RT3090 // */
+				default:
+					break;
+				}
+
+				if (bChange) {
+					reg16 = cpu2le16(Configuration);
+					pci_write_config_word(pObj->
+							      parent_pci_dev,
+							      pAd->
+							      HostLnkCtrlOffset,
+							      reg16);
+					DBGPRINT(RT_DEBUG_TRACE,
+						 ("Write (Host PCI-to-PCI Bridge Link Control Register) offset 0x%x = 0x%x\n",
+						  pAd->HostLnkCtrlOffset,
+						  Configuration));
+				}
+			} else {
+				pAd->HostLnkCtrlOffset = 0;
+				DBGPRINT(RT_DEBUG_ERROR,
+					 ("%s: cannot find PCI-to-PCI Bridge PCI Express Capability!\n",
+					  __func__));
+			}
+		}
+	} else {
+		pAd->RLnkCtrlOffset = 0;
+		pAd->HostLnkCtrlOffset = 0;
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("%s: cannot find Ralink PCIe Device's PCI Express Capability!\n",
+			  __func__));
+	}
+
+	if (bFindIntel == FALSE) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Doesn't find Intel PCI host controller. \n"));
+		/* Doesn't switch L0, L1, So set PCIePowerSaveLevel to 0xff */
+		pAd->PCIePowerSaveLevel = 0xff;
+		if ((pAd->RLnkCtrlOffset != 0)
+#ifdef RT3090
+		    && ((pObj->DeviceID == NIC3090_PCIe_DEVICE_ID)
+			|| (pObj->DeviceID == NIC3091_PCIe_DEVICE_ID)
+			|| (pObj->DeviceID == NIC3092_PCIe_DEVICE_ID))
+#endif /* RT3090 // */
+		    ) {
+			pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset,
+					     &reg16);
+			Configuration = le2cpu16(reg16);
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("Read (Ralink 30xx PCIe Link Control Register) offset 0x%x = 0x%x\n",
+				  pAd->RLnkCtrlOffset, Configuration));
+			pAd->RLnkCtrlConfiguration = (Configuration & 0x103);
+			Configuration &= 0xfefc;
+			Configuration |= (0x0);
+			reg16 = cpu2le16(Configuration);
+			pci_write_config_word(pObj->pci_dev,
+					      pAd->RLnkCtrlOffset, reg16);
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("Write (Ralink PCIe Link Control Register)  offset 0x%x = 0x%x\n",
+				  pos + PCI_EXP_LNKCTL, Configuration));
+		}
+	}
+}
+
+void RTMPFindHostPCIDev(struct rt_rtmp_adapter *pAd)
+{
+	u16 reg16;
+	u8 reg8;
+	u32 DevFn;
+	struct pci_dev *pPci_dev;
+	struct os_cookie *pObj;
+
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
+		return;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __func__));
+
+	pObj->parent_pci_dev = NULL;
+	if (pObj->pci_dev->bus->parent) {
+		for (DevFn = 0; DevFn < 255; DevFn++) {
+			pPci_dev =
+			    pci_get_slot(pObj->pci_dev->bus->parent, DevFn);
+			if (pPci_dev) {
+				pci_read_config_word(pPci_dev, PCI_CLASS_DEVICE,
+						     &reg16);
+				reg16 = le2cpu16(reg16);
+				pci_read_config_byte(pPci_dev, PCI_CB_CARD_BUS,
+						     &reg8);
+				if ((reg16 == PCI_CLASS_BRIDGE_PCI)
+				    && (reg8 == pObj->pci_dev->bus->number)) {
+					pObj->parent_pci_dev = pPci_dev;
+				}
+			}
+		}
+	}
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+		Level = RESTORE_HALT : Restore PCI host and Ralink PCIe Link Control field to its default value.
+		Level = Other Value : Restore from dot11 power save or radio off status. And force PCI host Link Control fields to 0x1
+
+	========================================================================
+*/
+void RTMPPCIeLinkCtrlValueRestore(struct rt_rtmp_adapter *pAd, u8 Level)
+{
+	u16 PCIePowerSaveLevel, reg16;
+	u16 Configuration;
+	struct os_cookie *pObj;
+
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
+		return;
+
+#ifdef RT2860
+	if (!((pObj->DeviceID == NIC2860_PCIe_DEVICE_ID)
+	      || (pObj->DeviceID == NIC2790_PCIe_DEVICE_ID)))
+		return;
+#endif /* RT2860 // */
+	/* Check PSControl Configuration */
+	if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE)
+		return;
+
+	/*3090 will not execute the following codes. */
+	/* Check interface : If not PCIe interface, return. */
+
+#ifdef RT3090
+	if ((pObj->DeviceID == NIC3090_PCIe_DEVICE_ID)
+	    || (pObj->DeviceID == NIC3091_PCIe_DEVICE_ID)
+	    || (pObj->DeviceID == NIC3092_PCIe_DEVICE_ID))
+		return;
+#endif /* RT3090 // */
+
+	DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __func__));
+	PCIePowerSaveLevel = pAd->PCIePowerSaveLevel;
+	if ((PCIePowerSaveLevel & 0xff) == 0xff) {
+		DBGPRINT(RT_DEBUG_TRACE, ("return  \n"));
+		return;
+	}
+
+	if (pObj->parent_pci_dev && (pAd->HostLnkCtrlOffset != 0)) {
+		PCI_REG_READ_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset,
+				  Configuration);
+		if ((Configuration != 0) && (Configuration != 0xFFFF)) {
+			Configuration &= 0xfefc;
+			/* If call from interface down, restore to orginial setting. */
+			if (Level == RESTORE_CLOSE) {
+				Configuration |= pAd->HostLnkCtrlConfiguration;
+			} else
+				Configuration |= 0x0;
+			PCI_REG_WIRTE_WORD(pObj->parent_pci_dev,
+					   pAd->HostLnkCtrlOffset,
+					   Configuration);
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("Restore PCI host : offset 0x%x = 0x%x\n",
+				  pAd->HostLnkCtrlOffset, Configuration));
+		} else
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("Restore PCI host : PCI_REG_READ_WORD failed (Configuration = 0x%x)\n",
+				  Configuration));
+	}
+
+	if (pObj->pci_dev && (pAd->RLnkCtrlOffset != 0)) {
+		PCI_REG_READ_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset,
+				  Configuration);
+		if ((Configuration != 0) && (Configuration != 0xFFFF)) {
+			Configuration &= 0xfefc;
+			/* If call from interface down, restore to orginial setting. */
+			if (Level == RESTORE_CLOSE)
+				Configuration |= pAd->RLnkCtrlConfiguration;
+			else
+				Configuration |= 0x0;
+			PCI_REG_WIRTE_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset,
+					   Configuration);
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("Restore Ralink : offset 0x%x = 0x%x\n",
+				  pAd->RLnkCtrlOffset, Configuration));
+		} else
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("Restore Ralink : PCI_REG_READ_WORD failed (Configuration = 0x%x)\n",
+				  Configuration));
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("%s <===\n", __func__));
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+		Max : limit Host PCI and Ralink PCIe device's LINK CONTROL field's value.
+		Because now frequently set our device to mode 1 or mode 3 will cause problem.
+
+	========================================================================
+*/
+void RTMPPCIeLinkCtrlSetting(struct rt_rtmp_adapter *pAd, u16 Max)
+{
+	u16 PCIePowerSaveLevel, reg16;
+	u16 Configuration;
+	struct os_cookie *pObj;
+
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
+		return;
+
+#ifdef RT2860
+	if (!((pObj->DeviceID == NIC2860_PCIe_DEVICE_ID)
+	      || (pObj->DeviceID == NIC2790_PCIe_DEVICE_ID)))
+		return;
+#endif /* RT2860 // */
+	/* Check PSControl Configuration */
+	if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE)
+		return;
+
+	/* Check interface : If not PCIe interface, return. */
+	/*Block 3090 to enter the following function */
+
+#ifdef RT3090
+	if ((pObj->DeviceID == NIC3090_PCIe_DEVICE_ID)
+	    || (pObj->DeviceID == NIC3091_PCIe_DEVICE_ID)
+	    || (pObj->DeviceID == NIC3092_PCIe_DEVICE_ID))
+		return;
+#endif /* RT3090 // */
+	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP)) {
+		DBGPRINT(RT_DEBUG_INFO,
+			 ("RTMPPCIePowerLinkCtrl return on fRTMP_PS_CAN_GO_SLEEP flag\n"));
+		return;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("%s===>\n", __func__));
+	PCIePowerSaveLevel = pAd->PCIePowerSaveLevel;
+	if ((PCIePowerSaveLevel & 0xff) == 0xff) {
+		DBGPRINT(RT_DEBUG_TRACE, ("return  \n"));
+		return;
+	}
+	PCIePowerSaveLevel = PCIePowerSaveLevel >> 6;
+
+	/* Skip non-exist deice right away */
+	if (pObj->parent_pci_dev && (pAd->HostLnkCtrlOffset != 0)) {
+		PCI_REG_READ_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset,
+				  Configuration);
+		switch (PCIePowerSaveLevel) {
+		case 0:
+			/* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 00 */
+			Configuration &= 0xfefc;
+			break;
+		case 1:
+			/* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 01 */
+			Configuration &= 0xfefc;
+			Configuration |= 0x1;
+			break;
+		case 2:
+			/*  Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 */
+			Configuration &= 0xfefc;
+			Configuration |= 0x3;
+			break;
+		case 3:
+			/* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 and bit 8 of LinkControl of 2892 to 1 */
+			Configuration &= 0xfefc;
+			Configuration |= 0x103;
+			break;
+		}
+		PCI_REG_WIRTE_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset,
+				   Configuration);
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Write PCI host offset 0x%x = 0x%x\n",
+			  pAd->HostLnkCtrlOffset, Configuration));
+	}
+
+	if (pObj->pci_dev && (pAd->RLnkCtrlOffset != 0)) {
+		/* first 2892 chip not allow to frequently set mode 3. will cause hang problem. */
+		if (PCIePowerSaveLevel > Max)
+			PCIePowerSaveLevel = Max;
+
+		PCI_REG_READ_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset,
+				  Configuration);
+		switch (PCIePowerSaveLevel) {
+		case 0:
+			/* No PCI power safe */
+			/* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 00 . */
+			Configuration &= 0xfefc;
+			break;
+		case 1:
+			/*  L0 */
+			/* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 01 . */
+			Configuration &= 0xfefc;
+			Configuration |= 0x1;
+			break;
+		case 2:
+			/* L0 and L1 */
+			/*  Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 */
+			Configuration &= 0xfefc;
+			Configuration |= 0x3;
+			break;
+		case 3:
+			/* L0 , L1 and clock management. */
+			/* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 and bit 8 of LinkControl of 2892 to 1 */
+			Configuration &= 0xfefc;
+			Configuration |= 0x103;
+			pAd->bPCIclkOff = TRUE;
+			break;
+		}
+		PCI_REG_WIRTE_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset,
+				   Configuration);
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Write Ralink device : offset 0x%x = 0x%x\n",
+			  pAd->RLnkCtrlOffset, Configuration));
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("RTMPPCIePowerLinkCtrl <==============\n"));
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		1. Write a PCI register for rt30xx power solution 3
+
+	========================================================================
+*/
+void RTMPrt3xSetPCIePowerLinkCtrl(struct rt_rtmp_adapter *pAd)
+{
+
+	unsigned long HostConfiguration = 0;
+	unsigned long Configuration;
+	struct os_cookie *pObj;
+	int pos;
+	u16 reg16;
+
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	DBGPRINT(RT_DEBUG_INFO,
+		 ("RTMPrt3xSetPCIePowerLinkCtrl.===> %lx\n",
+		  pAd->StaCfg.PSControl.word));
+
+	/* Check PSControl Configuration */
+	if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE)
+		return;
+	RTMPFindHostPCIDev(pAd);
+	if (pObj->parent_pci_dev) {
+		/* Find PCI-to-PCI Bridge Express Capability Offset */
+		pos = pci_find_capability(pObj->parent_pci_dev, PCI_CAP_ID_EXP);
+
+		if (pos != 0) {
+			pAd->HostLnkCtrlOffset = pos + PCI_EXP_LNKCTL;
+		}
+		/* If configurared to turn on L1. */
+		HostConfiguration = 0;
+		if (pAd->StaCfg.PSControl.field.rt30xxForceASPMTest == 1) {
+			DBGPRINT(RT_DEBUG_TRACE, ("Enter,PSM : Force ASPM \n"));
+
+			/* Skip non-exist deice right away */
+			if ((pAd->HostLnkCtrlOffset != 0)) {
+				PCI_REG_READ_WORD(pObj->parent_pci_dev,
+						  pAd->HostLnkCtrlOffset,
+						  HostConfiguration);
+				/* Prepare Configuration to write to Host */
+				HostConfiguration |= 0x3;
+				PCI_REG_WIRTE_WORD(pObj->parent_pci_dev,
+						   pAd->HostLnkCtrlOffset,
+						   HostConfiguration);
+				pAd->Rt3xxHostLinkCtrl = HostConfiguration;
+				/* Because in rt30xxForceASPMTest Mode, Force turn on L0s, L1. */
+				/* Fix HostConfiguration bit0:1 = 0x3 for later use. */
+				HostConfiguration = 0x3;
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("PSM : Force ASPM : "
+					  "Host device L1/L0s Value =  0x%lx\n",
+					  HostConfiguration));
+			}
+		} else if (pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM ==
+			   1) {
+
+			/* Skip non-exist deice right away */
+			if ((pAd->HostLnkCtrlOffset != 0)) {
+				PCI_REG_READ_WORD(pObj->parent_pci_dev,
+						  pAd->HostLnkCtrlOffset,
+						  HostConfiguration);
+				pAd->Rt3xxHostLinkCtrl = HostConfiguration;
+				HostConfiguration &= 0x3;
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("PSM : Follow Host ASPM : "
+					  "Host device L1/L0s Value =  0x%lx\n",
+					  HostConfiguration));
+			}
+		}
+	}
+	/* Prepare to write Ralink setting. */
+	/* Find Ralink PCIe Device's Express Capability Offset */
+	pos = pci_find_capability(pObj->pci_dev, PCI_CAP_ID_EXP);
+
+	if (pos != 0) {
+		/* Ralink PCIe Device's Link Control Register Offset */
+		pAd->RLnkCtrlOffset = pos + PCI_EXP_LNKCTL;
+		pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset,
+				     &reg16);
+		Configuration = le2cpu16(reg16);
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Read (Ralink PCIe Link Control Register) "
+			  "offset 0x%x = 0x%lx\n",
+			  pAd->RLnkCtrlOffset, Configuration));
+		Configuration |= 0x100;
+		if ((pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM == 1)
+		    || (pAd->StaCfg.PSControl.field.rt30xxForceASPMTest == 1)) {
+			switch (HostConfiguration) {
+			case 0:
+				Configuration &= 0xffffffc;
+				break;
+			case 1:
+				Configuration &= 0xffffffc;
+				Configuration |= 0x1;
+				break;
+			case 2:
+				Configuration &= 0xffffffc;
+				Configuration |= 0x2;
+				break;
+			case 3:
+				Configuration |= 0x3;
+				break;
+			}
+		}
+		reg16 = cpu2le16(Configuration);
+		pci_write_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset,
+				      reg16);
+		pAd->Rt3xxRalinkLinkCtrl = Configuration;
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("PSM :Write Ralink device L1/L0s Value =  0x%lx\n",
+			  Configuration));
+	}
+	DBGPRINT(RT_DEBUG_INFO,
+		 ("PSM :RTMPrt3xSetPCIePowerLinkCtrl <==============\n"));
+}
diff --git a/drivers/staging/rt2860/rt2860.h b/drivers/staging/rt2860/rt2860.h
deleted file mode 100644
index ed28fe5..0000000
--- a/drivers/staging/rt2860/rt2860.h
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
- */
-
-#ifndef __RT2860_H__
-#define __RT2860_H__
-
-#define RT28xx_CHIP_NAME	"RT2860"
-
-#define TXINFO_SIZE               0
-#define TXPADDING_SIZE      	  0
-
-/* ----------------- EEPROM Related MACRO ----------------- */
-#define RT28xx_EEPROM_READ16(pAd, offset, var)		\
-	var = RTMP_EEPROM_READ16(pAd, offset)
-
-#define RT28xx_EEPROM_WRITE16(pAd, offset, var)		\
-	RTMP_EEPROM_WRITE16(pAd, offset, var)
-
-/* ----------------- TASK/THREAD Related MACRO ----------------- */
-#define RT28XX_TASK_THREAD_INIT(pAd, Status)		\
-	init_thread_task(pAd); NICInitTxRxRingAndBacklogQueue(pAd);	\
-	Status = NDIS_STATUS_SUCCESS;
-
-/* function declarations */
-#define IRQ_HANDLE_TYPE  irqreturn_t
-
-IRQ_HANDLE_TYPE
-rt2860_interrupt(int irq, void *dev_instance);
-
-/* ----------------- Frimware Related MACRO ----------------- */
-#define RT28XX_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen)				\
-	do{																\
-		ULONG	_i, _firm;											\
-		RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x10000);				\
-																	\
-		for(_i=0; _i<_FwLen; _i+=4)									\
-		{															\
-			_firm = _pFwImage[_i] +									\
-			   (_pFwImage[_i+3] << 24) +							\
-			   (_pFwImage[_i+2] << 16) +							\
-			   (_pFwImage[_i+1] << 8);								\
-			RTMP_IO_WRITE32(_pAd, FIRMWARE_IMAGE_BASE + _i, _firm);	\
-		}															\
-		RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x00000);				\
-		RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x00001);				\
-																	\
-		/* initialize BBP R/W access agent */						\
-		RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, 0);					\
-		RTMP_IO_WRITE32(_pAd, H2M_MAILBOX_CSR, 0);					\
-	}while(0)
-
-/* ----------------- TX Related MACRO ----------------- */
-#define RT28XX_START_DEQUEUE(pAd, QueIdx, irqFlags)		do{}while(0)
-#define RT28XX_STOP_DEQUEUE(pAd, QueIdx, irqFlags)		do{}while(0)
-
-
-#define RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \
-		((freeNum) >= (ULONG)(pTxBlk->TotalFragNum + RTMP_GET_PACKET_FRAGMENTS(pPacket) + 3)) /* rough estimate we will use 3 more descriptor. */
-#define RT28XX_RELEASE_DESC_RESOURCE(pAd, QueIdx)					\
-		do{}while(0)
-
-#define NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, freeNum, _TxFrameType) \
-		(((freeNum != (TX_RING_SIZE-1)) && (pAd->TxSwQueue[QueIdx].Number == 0)) || (freeNum<3))
-		//(((freeNum) != (TX_RING_SIZE-1)) && (pAd->TxSwQueue[QueIdx].Number == 1 /*0*/))
-
-
-#define HAL_KickOutMgmtTx(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen)	\
-			RtmpPCIMgmtKickOut(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen)
-
-#define RTMP_PKT_TAIL_PADDING 0
-
-#define fRTMP_ADAPTER_NEED_STOP_TX	0
-
-#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)	\
-		/* RtmpPCI_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)*/
-
-#define HAL_WriteTxResource(pAd, pTxBlk,bIsLast, pFreeNumber)	\
-			RtmpPCI_WriteSingleTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)
-
-#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \
-			RtmpPCI_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber)
-
-#define HAL_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber)	\
-			RtmpPCI_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber)
-
-#define HAL_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx)	\
-			RtmpPCI_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx)
-
-#define HAL_LastTxIdx(_pAd, _QueIdx,_LastTxIdx) \
-			/*RtmpPCIDataLastTxIdx(_pAd, _QueIdx,_LastTxIdx)*/
-
-#define HAL_KickOutTx(_pAd, _pTxBlk, _QueIdx)	\
-			RTMP_IO_WRITE32((_pAd), TX_CTX_IDX0+((_QueIdx)*0x10), (_pAd)->TxRing[(_QueIdx)].TxCpuIdx)
-/*			RtmpPCIDataKickOut(_pAd, _pTxBlk, _QueIdx)*/
-
-#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen)	\
-			MiniportMMRequest(_pAd, _QueIdx, _pNullFrame, _frameLen)
-
-#define GET_TXRING_FREENO(_pAd, _QueIdx) \
-	(_pAd->TxRing[_QueIdx].TxSwFreeIdx > _pAd->TxRing[_QueIdx].TxCpuIdx)	? \
-			(_pAd->TxRing[_QueIdx].TxSwFreeIdx - _pAd->TxRing[_QueIdx].TxCpuIdx - 1) \
-			 :	\
-			(_pAd->TxRing[_QueIdx].TxSwFreeIdx + TX_RING_SIZE - _pAd->TxRing[_QueIdx].TxCpuIdx - 1);
-
-
-#define GET_MGMTRING_FREENO(_pAd) \
-	(_pAd->MgmtRing.TxSwFreeIdx > _pAd->MgmtRing.TxCpuIdx)	? \
-			(_pAd->MgmtRing.TxSwFreeIdx - _pAd->MgmtRing.TxCpuIdx - 1) \
-			 :	\
-			(_pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE - _pAd->MgmtRing.TxCpuIdx - 1);
-
-
-/* ----------------- RX Related MACRO ----------------- */
-
-// no use
-#define RT28XX_RCV_PKT_GET_INIT(pAd)
-#define RT28XX_RV_A_BUF_END
-//#define RT28XX_RV_ALL_BUF_END
-
-
-/* ----------------- ASIC Related MACRO ----------------- */
-// no use
-#define RT28XX_DMA_POST_WRITE(pAd)
-
-// reset MAC of a station entry to 0x000000000000
-#define RT28XX_STA_ENTRY_MAC_RESET(pAd, Wcid)						\
-	AsicDelWcidTab(pAd, Wcid);
-
-// add this entry into ASIC RX WCID search table
-#define RT28XX_STA_ENTRY_ADD(pAd, pEntry)							\
-	AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr);
-
-// remove Pair-wise key material from ASIC
-#define RT28XX_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid)					\
-	AsicRemovePairwiseKeyEntry(pAd, BssIdx, (UCHAR)Wcid);
-
-// add Client security information into ASIC WCID table and IVEIV table
-#define RT28XX_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry)		\
-	RTMPAddWcidAttributeEntry(pAd, apidx, KeyID, 					\
-							pAd->SharedKey[apidx][KeyID].CipherAlg, pEntry);
-
-#define RT28XX_SECURITY_KEY_ADD(pAd, apidx, KeyID, pEntry)				\
-	{	/* update pairwise key information to ASIC Shared Key Table */	\
-		AsicAddSharedKeyEntry(pAd, apidx, KeyID,						\
-						  pAd->SharedKey[apidx][KeyID].CipherAlg,		\
-						  pAd->SharedKey[apidx][KeyID].Key,				\
-						  pAd->SharedKey[apidx][KeyID].TxMic,			\
-						  pAd->SharedKey[apidx][KeyID].RxMic);			\
-		/* update ASIC WCID attribute table and IVEIV table */			\
-		RTMPAddWcidAttributeEntry(pAd, apidx, KeyID,					\
-						  pAd->SharedKey[apidx][KeyID].CipherAlg,		\
-						  pEntry); }
-
-
-// Insert the BA bitmap to ASIC for the Wcid entry
-#define RT28XX_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID)					\
-		do{																\
-			UINT32	_Value = 0, _Offset;									\
-			_Offset = MAC_WCID_BASE + (_Aid) * HW_WCID_ENTRY_SIZE + 4;	\
-			RTMP_IO_READ32((_pAd), _Offset, &_Value);					\
-			_Value |= (0x10000<<(_TID));								\
-			RTMP_IO_WRITE32((_pAd), _Offset, _Value);					\
-		}while(0)
-
-
-// Remove the BA bitmap from ASIC for the Wcid entry
-//		bitmap field starts at 0x10000 in ASIC WCID table
-#define RT28XX_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID)				\
-		do{																\
-			UINT32	_Value = 0, _Offset;									\
-			_Offset = MAC_WCID_BASE + (_Wcid) * HW_WCID_ENTRY_SIZE + 4;	\
-			RTMP_IO_READ32((_pAd), _Offset, &_Value);					\
-			_Value &= (~(0x10000 << (_TID)));							\
-			RTMP_IO_WRITE32((_pAd), _Offset, _Value);			\
-		}while(0)
-
-
-/* ----------------- PCI/USB Related MACRO ----------------- */
-
-#define RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p)				\
-	((POS_COOKIE)handle)->pci_dev = dev_p;
-
-// set driver data
-#define RT28XX_DRVDATA_SET(_a)			pci_set_drvdata(_a, net_dev);
-
-#define RT28XX_UNMAP()										\
-{	if (net_dev->base_addr)	{								\
-		iounmap((void *)(net_dev->base_addr));				\
-		release_mem_region(pci_resource_start(dev_p, 0),	\
-							pci_resource_len(dev_p, 0)); }	\
-	if (net_dev->irq) pci_release_regions(dev_p); }
-
-#ifdef PCI_MSI_SUPPORT
-#define RTMP_MSI_ENABLE(_pAd) \
-{ 	POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
-	(_pAd)->HaveMsi =	pci_enable_msi(_pObj->pci_dev) == 0 ? TRUE : FALSE; }
-
-#define RTMP_MSI_DISABLE(_pAd) \
-{ 	POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
-	if (_pAd->HaveMsi == TRUE) \
-		pci_disable_msi(_pObj->pci_dev); \
-	_pAd->HaveMsi = FALSE;	}
-#else
-#define RTMP_MSI_ENABLE(_pAd)
-#define RTMP_MSI_DISABLE(_pAd)
-#endif // PCI_MSI_SUPPORT //
-
-#define SA_SHIRQ IRQF_SHARED
-
-#define RT28XX_IRQ_REQUEST(net_dev)							\
-{	PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)((net_dev)->ml_priv);	\
-	POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie);		\
-	RTMP_MSI_ENABLE(_pAd);									\
-	if ((retval = request_irq(_pObj->pci_dev->irq, 		\
-							rt2860_interrupt, SA_SHIRQ,		\
-							(net_dev)->name, (net_dev)))) {	\
-		printk("RT2860: request_irq  ERROR(%d)\n", retval);	\
-	return retval; } }
-
-#define RT28XX_IRQ_RELEASE(net_dev)								\
-{	PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)((net_dev)->ml_priv);		\
-	POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie);			\
-	synchronize_irq(_pObj->pci_dev->irq);						\
-	free_irq(_pObj->pci_dev->irq, (net_dev));					\
-	RTMP_MSI_DISABLE(_pAd); }
-
-#define RT28XX_IRQ_INIT(pAd)										\
-	{	pAd->int_enable_reg = ((DELAYINTMASK) |						\
-							(RxINT|TxDataInt|TxMgmtInt)) & ~(0x03);	\
-		pAd->int_disable_mask = 0;									\
-		pAd->int_pending = 0; }
-
-#define RT28XX_IRQ_ENABLE(pAd)									\
-	{	/* clear garbage ints */								\
-		RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, 0xffffffff);		\
-		NICEnableInterrupt(pAd); }
-
-#define RT28XX_PUT_DEVICE(dev_p)
-
-
-/* ----------------- MLME Related MACRO ----------------- */
-#define RT28XX_MLME_HANDLER(pAd)			MlmeHandler(pAd)
-
-#define RT28XX_MLME_PRE_SANITY_CHECK(pAd)
-
-#define RT28XX_MLME_STA_QUICK_RSP_WAKE_UP(pAd)	\
-	RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
-
-#define RT28XX_MLME_RESET_STATE_MACHINE(pAd)	\
-		MlmeRestartStateMachine(pAd)
-
-#define RT28XX_HANDLE_COUNTER_MEASURE(_pAd, _pEntry)		\
-		HandleCounterMeasure(_pAd, _pEntry)
-
-/* ----------------- Power Save Related MACRO ----------------- */
-#define RT28XX_PS_POLL_ENQUEUE(pAd)				EnqueuePsPoll(pAd)
-
-//
-// Device ID & Vendor ID, these values should match EEPROM value
-//
-#define NIC2860_PCI_DEVICE_ID   0x0601
-#define NIC2860_PCIe_DEVICE_ID  0x0681
-#define NIC2760_PCI_DEVICE_ID   0x0701		// 1T/2R Cardbus ???
-#define NIC2790_PCIe_DEVICE_ID  0x0781	    // 1T/2R miniCard
-
-#define NIC_PCI_VENDOR_ID       0x1814
-
-#define VEN_AWT_PCIe_DEVICE_ID	0x1059
-#define VEN_AWT_PCI_VENDOR_ID	0x1A3B
-
-#define EDIMAX_PCI_VENDOR_ID	0x1432
-
-// For RTMPPCIePowerLinkCtrlRestore () function
-#define RESTORE_HALT		    1
-#define RESTORE_WAKEUP		    2
-#define RESTORE_CLOSE           3
-
-#define PowerSafeCID		1
-#define PowerRadioOffCID		2
-#define PowerWakeCID		3
-#define CID0MASK		0x000000ff
-#define CID1MASK		0x0000ff00
-#define CID2MASK		0x00ff0000
-#define CID3MASK		0xff000000
-
-#define PCI_REG_READ_WORD(pci_dev, offset, Configuration)   \
-    if (pci_read_config_word(pci_dev, offset, &reg16) == 0)     \
-        Configuration = le2cpu16(reg16);                        \
-    else                                                        \
-        Configuration = 0;
-
-#define PCI_REG_WIRTE_WORD(pci_dev, offset, Configuration)  \
-    reg16 = cpu2le16(Configuration);                        \
-    pci_write_config_word(pci_dev, offset, reg16);          \
-
-#define RT28XX_STA_FORCE_WAKEUP(pAd, Level) \
-    RT28xxPciStaAsicForceWakeup(pAd, Level);
-
-#define RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \
-    RT28xxPciStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
-
-#define RT28XX_MLME_RADIO_ON(pAd) \
-    RT28xxPciMlmeRadioOn(pAd);
-
-#define RT28XX_MLME_RADIO_OFF(pAd) \
-    RT28xxPciMlmeRadioOFF(pAd);
-
-#endif //__RT2860_H__
-
diff --git a/drivers/staging/rt2860/rt28xx.h b/drivers/staging/rt2860/rt28xx.h
deleted file mode 100644
index c085250..0000000
--- a/drivers/staging/rt2860/rt28xx.h
+++ /dev/null
@@ -1,1688 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rt28xx.h
-
-	Abstract:
-	RT28xx ASIC related definition & structures
-
-	Revision History:
-	Who			When		  What
-	--------	----------	  ----------------------------------------------
-       Jan Lee           Jan-3-2006     created for RT2860c
-*/
-
-#ifndef	__RT28XX_H__
-#define	__RT28XX_H__
-
-
-//
-// PCI registers - base address 0x0000
-//
-#define PCI_CFG			0x0000
-#define PCI_EECTRL			0x0004
-#define PCI_MCUCTRL			0x0008
-
-typedef int NTSTATUS;
-
-#define	OPT_14			0x114
-
-//
-// SCH/DMA registers - base address 0x0200
-//
-// INT_SOURCE_CSR: Interrupt source register. Write one to clear corresponding bit
-//
-#define DMA_CSR0      0x200
-#define INT_SOURCE_CSR      0x200
-typedef	union	_INT_SOURCE_CSR_STRUC	{
-	struct	{
-		UINT32		RxDelayINT:1;
-		UINT32		TxDelayINT:1;
-		UINT32		RxDone:1;
-		UINT32		Ac0DmaDone:1;//4
-		UINT32       	Ac1DmaDone:1;
-		UINT32       	Ac2DmaDone:1;
-		UINT32       	Ac3DmaDone:1;
-		UINT32       	HccaDmaDone:1; // bit7
-		UINT32       	MgmtDmaDone:1;
-		UINT32       	MCUCommandINT:1;//bit 9
-		UINT32       	RxTxCoherent:1;
-		UINT32       	TBTTInt:1;
-		UINT32       	PreTBTT:1;
-		UINT32       	TXFifoStatusInt:1;//FIFO Statistics is full, sw should read 0x171c
-		UINT32       	AutoWakeup:1;//bit14
-		UINT32       	GPTimer:1;
-		UINT32       	RxCoherent:1;//bit16
-		UINT32       	TxCoherent:1;
-		UINT32       	:14;
-	}	field;
-	UINT32			word;
-} INT_SOURCE_CSR_STRUC, *PINT_SOURCE_CSR_STRUC;
-
-//
-// INT_MASK_CSR:   Interrupt MASK register.   1: the interrupt is mask OFF
-//
-#define INT_MASK_CSR        0x204
-typedef	union	_INT_MASK_CSR_STRUC	{
-	struct	{
-		UINT32		RXDelay_INT_MSK:1;
-		UINT32		TxDelay:1;
-		UINT32		RxDone:1;
-		UINT32		Ac0DmaDone:1;
-		UINT32       	Ac1DmaDone:1;
-		UINT32       	Ac2DmaDone:1;
-		UINT32       	Ac3DmaDone:1;
-		UINT32       	HccaDmaDone:1;
-		UINT32       	MgmtDmaDone:1;
-		UINT32       	MCUCommandINT:1;
-		UINT32       	:20;
-		UINT32       	RxCoherent:1;
-		UINT32       	TxCoherent:1;
-	}	field;
-	UINT32			word;
-} INT_MASK_CSR_STRUC, *PINT_MASK_CSR_STRUC;
-
-#define WPDMA_GLO_CFG 	0x208
-typedef	union	_WPDMA_GLO_CFG_STRUC	{
-	struct	{
-		UINT32		EnableTxDMA:1;
-		UINT32		TxDMABusy:1;
-		UINT32		EnableRxDMA:1;
-		UINT32		RxDMABusy:1;
-		UINT32       	WPDMABurstSIZE:2;
-		UINT32       	EnTXWriteBackDDONE:1;
-		UINT32       	BigEndian:1;
-		UINT32       	RXHdrScater:8;
-		UINT32       	HDR_SEG_LEN:16;
-	}	field;
-	UINT32			word;
-} WPDMA_GLO_CFG_STRUC, *PWPDMA_GLO_CFG_STRUC;
-
-#define WPDMA_RST_IDX 	0x20c
-typedef	union	_WPDMA_RST_IDX_STRUC	{
-	struct	{
-		UINT32		RST_DTX_IDX0:1;
-		UINT32		RST_DTX_IDX1:1;
-		UINT32		RST_DTX_IDX2:1;
-		UINT32		RST_DTX_IDX3:1;
-		UINT32       	RST_DTX_IDX4:1;
-		UINT32       	RST_DTX_IDX5:1;
-		UINT32       	rsv:10;
-		UINT32       	RST_DRX_IDX0:1;
-		UINT32       	:15;
-	}	field;
-	UINT32			word;
-} WPDMA_RST_IDX_STRUC, *PWPDMA_RST_IDX_STRUC;
-
-#define DELAY_INT_CFG  0x0210
-typedef	union	_DELAY_INT_CFG_STRUC	{
-	struct	{
-		UINT32		RXMAX_PTIME:8;
-		UINT32       	RXMAX_PINT:7;
-		UINT32       	RXDLY_INT_EN:1;
-		UINT32       	TXMAX_PTIME:8;
-		UINT32       	TXMAX_PINT:7;
-		UINT32       	TXDLY_INT_EN:1;
-	}	field;
-	UINT32			word;
-} DELAY_INT_CFG_STRUC, *PDELAY_INT_CFG_STRUC;
-
-#define WMM_AIFSN_CFG   0x0214
-typedef	union	_AIFSN_CSR_STRUC	{
-	struct	{
-	    UINT32   Aifsn0:4;       // for AC_BE
-	    UINT32   Aifsn1:4;       // for AC_BK
-	    UINT32   Aifsn2:4;       // for AC_VI
-	    UINT32   Aifsn3:4;       // for AC_VO
-	    UINT32   Rsv:16;
-	}	field;
-	UINT32			word;
-}	AIFSN_CSR_STRUC, *PAIFSN_CSR_STRUC;
-
-//
-// CWMIN_CSR: CWmin for each EDCA AC
-//
-#define WMM_CWMIN_CFG   0x0218
-typedef	union	_CWMIN_CSR_STRUC	{
-	struct	{
-	    UINT32   Cwmin0:4;       // for AC_BE
-	    UINT32   Cwmin1:4;       // for AC_BK
-	    UINT32   Cwmin2:4;       // for AC_VI
-	    UINT32   Cwmin3:4;       // for AC_VO
-	    UINT32   Rsv:16;
-	}	field;
-	UINT32			word;
-}	CWMIN_CSR_STRUC, *PCWMIN_CSR_STRUC;
-
-//
-// CWMAX_CSR: CWmin for each EDCA AC
-//
-#define WMM_CWMAX_CFG   0x021c
-typedef	union	_CWMAX_CSR_STRUC	{
-	struct	{
-	    UINT32   Cwmax0:4;       // for AC_BE
-	    UINT32   Cwmax1:4;       // for AC_BK
-	    UINT32   Cwmax2:4;       // for AC_VI
-	    UINT32   Cwmax3:4;       // for AC_VO
-	    UINT32   Rsv:16;
-	}	field;
-	UINT32			word;
-}	CWMAX_CSR_STRUC, *PCWMAX_CSR_STRUC;
-
-//
-// AC_TXOP_CSR0: AC_BK/AC_BE TXOP register
-//
-#define WMM_TXOP0_CFG    0x0220
-typedef	union	_AC_TXOP_CSR0_STRUC	{
-	struct	{
-	    USHORT  Ac0Txop;        // for AC_BK, in unit of 32us
-	    USHORT  Ac1Txop;        // for AC_BE, in unit of 32us
-	}	field;
-	UINT32			word;
-}	AC_TXOP_CSR0_STRUC, *PAC_TXOP_CSR0_STRUC;
-
-//
-// AC_TXOP_CSR1: AC_VO/AC_VI TXOP register
-//
-#define WMM_TXOP1_CFG    0x0224
-typedef	union	_AC_TXOP_CSR1_STRUC	{
-	struct	{
-	    USHORT  Ac2Txop;        // for AC_VI, in unit of 32us
-	    USHORT  Ac3Txop;        // for AC_VO, in unit of 32us
-	}	field;
-	UINT32			word;
-}	AC_TXOP_CSR1_STRUC, *PAC_TXOP_CSR1_STRUC;
-
-#define RINGREG_DIFF			0x10
-#define GPIO_CTRL_CFG    0x0228	//MAC_CSR13
-#define MCU_CMD_CFG    0x022c
-#define TX_BASE_PTR0     0x0230	//AC_BK base address
-#define TX_MAX_CNT0      0x0234
-#define TX_CTX_IDX0       0x0238
-#define TX_DTX_IDX0      0x023c
-#define TX_BASE_PTR1     0x0240 	//AC_BE base address
-#define TX_MAX_CNT1      0x0244
-#define TX_CTX_IDX1       0x0248
-#define TX_DTX_IDX1      0x024c
-#define TX_BASE_PTR2     0x0250 	//AC_VI base address
-#define TX_MAX_CNT2      0x0254
-#define TX_CTX_IDX2       0x0258
-#define TX_DTX_IDX2      0x025c
-#define TX_BASE_PTR3     0x0260 	//AC_VO base address
-#define TX_MAX_CNT3      0x0264
-#define TX_CTX_IDX3       0x0268
-#define TX_DTX_IDX3      0x026c
-#define TX_BASE_PTR4     0x0270 	//HCCA base address
-#define TX_MAX_CNT4      0x0274
-#define TX_CTX_IDX4       0x0278
-#define TX_DTX_IDX4      0x027c
-#define TX_BASE_PTR5     0x0280 	//MGMT base address
-#define  TX_MAX_CNT5     0x0284
-#define TX_CTX_IDX5       0x0288
-#define TX_DTX_IDX5      0x028c
-#define TX_MGMTMAX_CNT      TX_MAX_CNT5
-#define TX_MGMTCTX_IDX       TX_CTX_IDX5
-#define TX_MGMTDTX_IDX      TX_DTX_IDX5
-#define RX_BASE_PTR     0x0290 	//RX base address
-#define RX_MAX_CNT      0x0294
-#define RX_CRX_IDX       0x0298
-#define RX_DRX_IDX      0x029c
-#define USB_DMA_CFG      0x02a0
-
-typedef	union	_USB_DMA_CFG_STRUC	{
-	struct	{
-	    UINT32  RxBulkAggTOut:8;        //Rx Bulk Aggregation TimeOut  in unit of 33ns
-	    UINT32  RxBulkAggLmt:8;        //Rx Bulk Aggregation Limit  in unit of 256 bytes
-	    UINT32  phyclear:1;        		//phy watch dog enable. write 1
-	    UINT32  rsv:2;
-	    UINT32  TxClear:1;        //Clear USB DMA TX path
-	    UINT32  TxopHalt:1;        //Halt TXOP count down when TX buffer is full.
-	    UINT32  RxBulkAggEn:1;        //Enable Rx Bulk Aggregation
-	    UINT32  RxBulkEn:1;        //Enable USB DMA Rx
-	    UINT32  TxBulkEn:1;        //Enable USB DMA Tx
-	    UINT32  EpoutValid:6;        //OUT endpoint data valid
-	    UINT32  RxBusy:1;        //USB DMA RX FSM busy
-	    UINT32  TxBusy:1;   	//USB DMA TX FSM busy
-	}	field;
-	UINT32			word;
-}	USB_DMA_CFG_STRUC, *PUSB_DMA_CFG_STRUC;
-
-//
-//  3  PBF  registers
-//
-//
-// Most are for debug. Driver doesn't touch PBF register.
-#define 	PBF_SYS_CTRL 	 0x0400
-#define     PBF_CFG                 0x0408
-#define 	PBF_MAX_PCNT 	 0x040C
-#define 	PBF_CTRL	 	0x0410
-#define 	PBF_INT_STA	 0x0414
-#define 	PBF_INT_ENA	 0x0418
-#define 	TXRXQ_PCNT  	 0x0438
-#define 	PBF_DBG 	 	 0x043c
-#define     PBF_CAP_CTRL     0x0440
-
-// eFuse registers
-#define EFUSE_CTRL              0x0580
-#define EFUSE_DATA0             0x0590
-#define EFUSE_DATA1             0x0594
-#define EFUSE_DATA2             0x0598
-#define EFUSE_DATA3             0x059c
-#define EFUSE_USAGE_MAP_START   0x2d0
-#define EFUSE_USAGE_MAP_END     0x2fc
-#define EFUSE_TAG               0x2fe
-#define EFUSE_USAGE_MAP_SIZE    45
-
-typedef	union	_EFUSE_CTRL_STRUC {
-	struct	{
-		UINT32            EFSROM_AOUT:6;
-		UINT32            EFSROM_MODE:2;
-		UINT32            EFSROM_LDO_OFF_TIME:6;
-		UINT32            EFSROM_LDO_ON_TIME:2;
-		UINT32            EFSROM_AIN:10;
-		UINT32            RESERVED:4;
-		UINT32            EFSROM_KICK:1;
-		UINT32            SEL_EFUSE:1;
-	}	field;
-	UINT32			word;
-}	EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC;
-
-#define LDO_CFG0 				0x05d4
-#define GPIO_SWITCH				0x05dc
-
-//
-//  4  MAC  registers
-//
-//
-//  4.1 MAC SYSTEM  configuration registers (offset:0x1000)
-//
-#define MAC_CSR0            0x1000
-typedef	union	_ASIC_VER_ID_STRUC	{
-	struct	{
-	    USHORT  ASICRev;        // reversion  : 0
-	    USHORT  ASICVer;        // version : 2860
-	}	field;
-	UINT32			word;
-}	ASIC_VER_ID_STRUC, *PASIC_VER_ID_STRUC;
-
-#define MAC_SYS_CTRL            0x1004		//MAC_CSR1
-#define MAC_ADDR_DW0            		0x1008		// MAC ADDR DW0
-#define MAC_ADDR_DW1           		 0x100c		// MAC ADDR DW1
-//
-// MAC_CSR2: STA MAC register 0
-//
-typedef	union	_MAC_DW0_STRUC	{
-	struct	{
-		UCHAR		Byte0;		// MAC address byte 0
-		UCHAR		Byte1;		// MAC address byte 1
-		UCHAR		Byte2;		// MAC address byte 2
-		UCHAR		Byte3;		// MAC address byte 3
-	}	field;
-	UINT32			word;
-}	MAC_DW0_STRUC, *PMAC_DW0_STRUC;
-
-//
-// MAC_CSR3: STA MAC register 1
-//
-typedef	union	_MAC_DW1_STRUC	{
-	struct	{
-		UCHAR		Byte4;		// MAC address byte 4
-		UCHAR		Byte5;		// MAC address byte 5
-		UCHAR		U2MeMask;
-		UCHAR		Rsvd1;
-	}	field;
-	UINT32			word;
-}	MAC_DW1_STRUC, *PMAC_DW1_STRUC;
-
-#define MAC_BSSID_DW0            		0x1010		// MAC BSSID DW0
-#define MAC_BSSID_DW1            		0x1014		// MAC BSSID DW1
-
-//
-// MAC_CSR5: BSSID register 1
-//
-typedef	union	_MAC_CSR5_STRUC	{
-	struct	{
-		UCHAR		Byte4;		 // BSSID byte 4
-		UCHAR		Byte5;		 // BSSID byte 5
-		USHORT      	BssIdMask:2; // 0: one BSSID, 10: 4 BSSID,  01: 2 BSSID , 11: 8BSSID
-		USHORT		MBssBcnNum:3;
-		USHORT		Rsvd:11;
-	}	field;
-	UINT32			word;
-}	MAC_CSR5_STRUC, *PMAC_CSR5_STRUC;
-
-#define MAX_LEN_CFG              0x1018		// rt2860b max 16k bytes. bit12:13 Maximum PSDU length (power factor) 0:2^13, 1:2^14, 2:2^15, 3:2^16
-#define BBP_CSR_CFG            		0x101c		//
-//
-// BBP_CSR_CFG: BBP serial control register
-//
-typedef	union	_BBP_CSR_CFG_STRUC	{
-	struct	{
-		UINT32		Value:8;			// Register	value to program into BBP
-		UINT32		RegNum:8;			// Selected	BBP	register
-		UINT32		fRead:1;		    // 0: Write	BBP, 1:	Read BBP
-		UINT32		Busy:1;				// 1: ASIC is busy execute BBP programming.
-		UINT32		BBP_PAR_DUR:1;		     // 0: 4 MAC clock cycles  1: 8 MAC clock cycles
-		UINT32		BBP_RW_MODE:1;		// 0: use serial mode  1:parallel
-		UINT32		:12;
-	}	field;
-	UINT32			word;
-}	BBP_CSR_CFG_STRUC, *PBBP_CSR_CFG_STRUC;
-
-#define RF_CSR_CFG0            		0x1020
-//
-// RF_CSR_CFG: RF control register
-//
-typedef	union	_RF_CSR_CFG0_STRUC	{
-	struct	{
-		UINT32		RegIdAndContent:24;			// Register	value to program into BBP
-		UINT32		bitwidth:5;			// Selected	BBP	register
-		UINT32		StandbyMode:1;		    // 0: high when stand by 1:	low when standby
-		UINT32		Sel:1;				// 0:RF_LE0 activate  1:RF_LE1 activate
-		UINT32		Busy:1;		    // 0: idle 1: 8busy
-	}	field;
-	UINT32			word;
-}	RF_CSR_CFG0_STRUC, *PRF_CSR_CFG0_STRUC;
-
-#define RF_CSR_CFG1           		0x1024
-typedef	union	_RF_CSR_CFG1_STRUC	{
-	struct	{
-		UINT32		RegIdAndContent:24;			// Register	value to program into BBP
-		UINT32		RFGap:5;			// Gap between BB_CONTROL_RF and RF_LE. 0: 3 system clock cycle (37.5usec) 1: 5 system clock cycle (62.5usec)
-		UINT32		rsv:7;		    // 0: idle 1: 8busy
-	}	field;
-	UINT32			word;
-}	RF_CSR_CFG1_STRUC, *PRF_CSR_CFG1_STRUC;
-
-#define RF_CSR_CFG2           		0x1028		//
-typedef	union	_RF_CSR_CFG2_STRUC	{
-	struct	{
-		UINT32		RegIdAndContent:24;			// Register	value to program into BBP
-		UINT32		rsv:8;		    // 0: idle 1: 8busy
-	}	field;
-	UINT32			word;
-}	RF_CSR_CFG2_STRUC, *PRF_CSR_CFG2_STRUC;
-
-#define LED_CFG           		0x102c		//  MAC_CSR14
-typedef	union	_LED_CFG_STRUC	{
-	struct	{
-		UINT32		OnPeriod:8;			// blinking on period unit 1ms
-		UINT32		OffPeriod:8;			// blinking off period unit 1ms
-		UINT32		SlowBlinkPeriod:6;			// slow blinking period. unit:1ms
-		UINT32		rsv:2;
-		UINT32		RLedMode:2;			// red Led Mode    0: off1: blinking upon TX2: periodic slow blinking3: always on
-		UINT32		GLedMode:2;			// green Led Mode
-		UINT32		YLedMode:2;			// yellow Led Mode
-		UINT32		LedPolar:1;			// Led Polarity.  0: active low1: active high
-		UINT32		:1;
-	}	field;
-	UINT32			word;
-}	LED_CFG_STRUC, *PLED_CFG_STRUC;
-
-//
-//  4.2 MAC TIMING  configuration registers (offset:0x1100)
-//
-#define XIFS_TIME_CFG             0x1100		 // MAC_CSR8  MAC_CSR9
-typedef	union	_IFS_SLOT_CFG_STRUC	{
-	struct	{
-	    UINT32  CckmSifsTime:8;        //  unit 1us. Applied after CCK RX/TX
-	    UINT32  OfdmSifsTime:8;        //  unit 1us. Applied after OFDM RX/TX
-	    UINT32  OfdmXifsTime:4;        //OFDM SIFS. unit 1us. Applied after OFDM RX when MAC doesn't reference BBP signal BBRXEND
-	    UINT32  EIFS:9;        //  unit 1us
-	    UINT32  BBRxendEnable:1;        //  reference RXEND signal to begin XIFS defer
-	    UINT32  rsv:2;
-	}	field;
-	UINT32			word;
-}	IFS_SLOT_CFG_STRUC, *PIFS_SLOT_CFG_STRUC;
-
-#define BKOFF_SLOT_CFG             0x1104		 //  mac_csr9 last 8 bits
-#define NAV_TIME_CFG             0x1108		 // NAV  (MAC_CSR15)
-#define CH_TIME_CFG             0x110C		 	// Count as channel busy
-#define PBF_LIFE_TIMER             0x1110		 //TX/RX MPDU timestamp timer (free run)Unit: 1us
-#define BCN_TIME_CFG             0x1114		 // TXRX_CSR9
-
-#define BCN_OFFSET0				0x042C
-#define BCN_OFFSET1				0x0430
-
-//
-// BCN_TIME_CFG : Synchronization control register
-//
-typedef	union	_BCN_TIME_CFG_STRUC	{
-	struct	{
-		UINT32       BeaconInterval:16;  // in unit of 1/16 TU
-		UINT32		bTsfTicking:1;		// Enable TSF auto counting
-		UINT32		TsfSyncMode:2;		// Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode
-        UINT32       bTBTTEnable:1;
-		UINT32		bBeaconGen:1;		// Enable beacon generator
-        UINT32       :3;
-		UINT32		TxTimestampCompensate:8;
-	}	field;
-	UINT32			word;
-}	BCN_TIME_CFG_STRUC, *PBCN_TIME_CFG_STRUC;
-
-#define TBTT_SYNC_CFG            0x1118  		// txrx_csr10
-#define TSF_TIMER_DW0             0x111C  		// Local TSF timer lsb 32 bits. Read-only
-#define TSF_TIMER_DW1             0x1120  		// msb 32 bits. Read-only.
-#define TBTT_TIMER             	0x1124  		// TImer remains till next TBTT. Read-only.  TXRX_CSR14
-#define INT_TIMER_CFG              	0x1128  		//
-#define INT_TIMER_EN             	0x112c  		//  GP-timer and pre-tbtt Int enable
-#define CH_IDLE_STA              	0x1130  		//  channel idle time
-#define CH_BUSY_STA              	0x1134  		//  channle busy time
-//
-//  4.2 MAC POWER  configuration registers (offset:0x1200)
-//
-#define MAC_STATUS_CFG             0x1200		 // old MAC_CSR12
-#define PWR_PIN_CFG             0x1204		 // old MAC_CSR12
-#define AUTO_WAKEUP_CFG             0x1208		 // old MAC_CSR10
-//
-// AUTO_WAKEUP_CFG: Manual power control / status register
-//
-typedef	union	_AUTO_WAKEUP_STRUC	{
-	struct	{
-		UINT32       AutoLeadTime:8;
-		UINT32       NumofSleepingTbtt:7;          // ForceWake has high privilege than PutToSleep when both set
-		UINT32		EnableAutoWakeup:1;	// 0:sleep, 1:awake
-		UINT32		:16;
-	}	field;
-	UINT32			word;
-}	AUTO_WAKEUP_STRUC, *PAUTO_WAKEUP_STRUC;
-
-//
-//  4.3 MAC TX  configuration registers (offset:0x1300)
-//
-
-#define EDCA_AC0_CFG	0x1300		//AC_TXOP_CSR0 0x3474
-#define EDCA_AC1_CFG	0x1304
-#define EDCA_AC2_CFG	0x1308
-#define EDCA_AC3_CFG	0x130c
-typedef	union	_EDCA_AC_CFG_STRUC	{
-	struct	{
-	    UINT32  AcTxop:8;        //  in unit of 32us
-	    UINT32  Aifsn:4;        // # of slot time
-	    UINT32  Cwmin:4;        //
-	    UINT32  Cwmax:4;        //unit power of 2
-	    UINT32  :12;       //
-	}	field;
-	UINT32			word;
-}	EDCA_AC_CFG_STRUC, *PEDCA_AC_CFG_STRUC;
-
-#define EDCA_TID_AC_MAP	0x1310
-#define TX_PWR_CFG_0	0x1314
-#define TX_PWR_CFG_1	0x1318
-#define TX_PWR_CFG_2	0x131C
-#define TX_PWR_CFG_3	0x1320
-#define TX_PWR_CFG_4	0x1324
-#define TX_PIN_CFG		0x1328
-#define TX_BAND_CFG	0x132c		// 0x1 use upper 20MHz. 0 juse lower 20MHz
-#define TX_SW_CFG0		0x1330
-#define TX_SW_CFG1		0x1334
-#define TX_SW_CFG2		0x1338
-#define TXOP_THRES_CFG		0x133c
-#define TXOP_CTRL_CFG		0x1340
-#define TX_RTS_CFG		0x1344
-
-typedef	union	_TX_RTS_CFG_STRUC	{
-	struct	{
-	    UINT32       AutoRtsRetryLimit:8;
-	    UINT32       RtsThres:16;    // unit:byte
-	    UINT32       RtsFbkEn:1;    // enable rts rate fallback
-	    UINT32       rsv:7;     // 1: HT non-STBC control frame enable
-	}	field;
-	UINT32			word;
-}	TX_RTS_CFG_STRUC, *PTX_RTS_CFG_STRUC;
-
-#define TX_TIMEOUT_CFG	0x1348
-typedef	union	_TX_TIMEOUT_CFG_STRUC	{
-	struct	{
-	    UINT32       rsv:4;
-	    UINT32       MpduLifeTime:4;    //  expiration time = 2^(9+MPDU LIFE TIME)  us
-	    UINT32       RxAckTimeout:8;	// unit:slot. Used for TX precedure
-	    UINT32       TxopTimeout:8;	//TXOP timeout value for TXOP truncation.  It is recommended that (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT)
-	    UINT32       rsv2:8;     // 1: HT non-STBC control frame enable
-	}	field;
-	UINT32			word;
-}	TX_TIMEOUT_CFG_STRUC, *PTX_TIMEOUT_CFG_STRUC;
-
-#define TX_RTY_CFG	0x134c
-typedef	union PACKED _TX_RTY_CFG_STRUC	{
-	struct	{
-	    UINT32       ShortRtyLimit:8;	//  short retry limit
-	    UINT32       LongRtyLimit:8;	//long retry limit
-	    UINT32       LongRtyThre:12;	// Long retry threshoold
-	    UINT32       NonAggRtyMode:1;	// Non-Aggregate MPDU retry mode.  0:expired by retry limit, 1: expired by mpdu life timer
-	    UINT32       AggRtyMode:1;	// Aggregate MPDU retry mode.  0:expired by retry limit, 1: expired by mpdu life timer
-	    UINT32       TxautoFBEnable:1;    // Tx retry PHY rate auto fallback enable
-	    UINT32       rsv:1;     // 1: HT non-STBC control frame enable
-	}	field;
-	UINT32			word;
-}	TX_RTY_CFG_STRUC, *PTX_RTY_CFG_STRUC;
-
-#define TX_LINK_CFG	0x1350
-typedef	union	PACKED _TX_LINK_CFG_STRUC	{
-	struct PACKED {
-	    UINT32       RemoteMFBLifeTime:8;	//remote MFB life time. unit : 32us
-	    UINT32       MFBEnable:1;	//  TX apply remote MFB 1:enable
-	    UINT32       RemoteUMFSEnable:1;	//  remote unsolicit  MFB enable.  0: not apply remote remote unsolicit (MFS=7)
-	    UINT32       TxMRQEn:1;	//  MCS request TX enable
-	    UINT32       TxRDGEn:1;	// RDG TX enable
-	    UINT32       TxCFAckEn:1;	//   Piggyback CF-ACK enable
-	    UINT32       rsv:3;	//
-	    UINT32       RemotMFB:8;    //  remote MCS feedback
-	    UINT32       RemotMFS:8;	//remote MCS feedback sequence number
-	}	field;
-	UINT32			word;
-}	TX_LINK_CFG_STRUC, *PTX_LINK_CFG_STRUC;
-
-#define HT_FBK_CFG0	0x1354
-typedef	union PACKED _HT_FBK_CFG0_STRUC	{
-	struct	{
-	    UINT32       HTMCS0FBK:4;
-	    UINT32       HTMCS1FBK:4;
-	    UINT32       HTMCS2FBK:4;
-	    UINT32       HTMCS3FBK:4;
-	    UINT32       HTMCS4FBK:4;
-	    UINT32       HTMCS5FBK:4;
-	    UINT32       HTMCS6FBK:4;
-	    UINT32       HTMCS7FBK:4;
-	}	field;
-	UINT32			word;
-}	HT_FBK_CFG0_STRUC, *PHT_FBK_CFG0_STRUC;
-
-#define HT_FBK_CFG1	0x1358
-typedef	union	_HT_FBK_CFG1_STRUC	{
-	struct	{
-	    UINT32       HTMCS8FBK:4;
-	    UINT32       HTMCS9FBK:4;
-	    UINT32       HTMCS10FBK:4;
-	    UINT32       HTMCS11FBK:4;
-	    UINT32       HTMCS12FBK:4;
-	    UINT32       HTMCS13FBK:4;
-	    UINT32       HTMCS14FBK:4;
-	    UINT32       HTMCS15FBK:4;
-	}	field;
-	UINT32			word;
-}	HT_FBK_CFG1_STRUC, *PHT_FBK_CFG1_STRUC;
-
-#define LG_FBK_CFG0	0x135c
-typedef	union	_LG_FBK_CFG0_STRUC	{
-	struct	{
-	    UINT32       OFDMMCS0FBK:4;	//initial value is 0
-	    UINT32       OFDMMCS1FBK:4;	//initial value is 0
-	    UINT32       OFDMMCS2FBK:4;	//initial value is 1
-	    UINT32       OFDMMCS3FBK:4;	//initial value is 2
-	    UINT32       OFDMMCS4FBK:4;	//initial value is 3
-	    UINT32       OFDMMCS5FBK:4;	//initial value is 4
-	    UINT32       OFDMMCS6FBK:4;	//initial value is 5
-	    UINT32       OFDMMCS7FBK:4;	//initial value is 6
-	}	field;
-	UINT32			word;
-}	LG_FBK_CFG0_STRUC, *PLG_FBK_CFG0_STRUC;
-
-#define LG_FBK_CFG1		0x1360
-typedef	union	_LG_FBK_CFG1_STRUC	{
-	struct	{
-	    UINT32       CCKMCS0FBK:4;	//initial value is 0
-	    UINT32       CCKMCS1FBK:4;	//initial value is 0
-	    UINT32       CCKMCS2FBK:4;	//initial value is 1
-	    UINT32       CCKMCS3FBK:4;	//initial value is 2
-	    UINT32       rsv:16;
-	}	field;
-	UINT32			word;
-}	LG_FBK_CFG1_STRUC, *PLG_FBK_CFG1_STRUC;
-
-//=======================================================
-//================ Protection Paramater================================
-//=======================================================
-#define CCK_PROT_CFG	0x1364		//CCK Protection
-#define ASIC_SHORTNAV		1
-#define ASIC_LONGNAV		2
-#define ASIC_RTS		1
-#define ASIC_CTS		2
-typedef	union	_PROT_CFG_STRUC	{
-	struct	{
-	    UINT32       ProtectRate:16;	//Protection control frame rate for CCK TX(RTS/CTS/CFEnd).
-	    UINT32       ProtectCtrl:2;	//Protection control frame type for CCK TX. 1:RTS/CTS, 2:CTS-to-self, 0:None, 3:rsv
-	    UINT32       ProtectNav:2;	//TXOP protection type for CCK TX. 0:None, 1:ShortNAVprotect,  2:LongNAVProtect, 3:rsv
-	    UINT32       TxopAllowCck:1;	//CCK TXOP allowance.0:disallow.
-	    UINT32       TxopAllowOfdm:1;	//CCK TXOP allowance.0:disallow.
-	    UINT32       TxopAllowMM20:1;	//CCK TXOP allowance. 0:disallow.
-	    UINT32       TxopAllowMM40:1;	//CCK TXOP allowance.0:disallow.
-	    UINT32       TxopAllowGF20:1;	//CCK TXOP allowance.0:disallow.
-	    UINT32       TxopAllowGF40:1;	//CCK TXOP allowance.0:disallow.
-	    UINT32       RTSThEn:1;	//RTS threshold enable on CCK TX
-	    UINT32       rsv:5;
-	}	field;
-	UINT32			word;
-}	PROT_CFG_STRUC, *PPROT_CFG_STRUC;
-
-#define OFDM_PROT_CFG	0x1368		//OFDM Protection
-#define MM20_PROT_CFG	0x136C		//MM20 Protection
-#define MM40_PROT_CFG	0x1370		//MM40 Protection
-#define GF20_PROT_CFG	0x1374		//GF20 Protection
-#define GF40_PROT_CFG	0x1378		//GR40 Protection
-#define EXP_CTS_TIME	0x137C		//
-#define EXP_ACK_TIME	0x1380		//
-
-//
-//  4.4 MAC RX configuration registers (offset:0x1400)
-//
-#define RX_FILTR_CFG	0x1400			//TXRX_CSR0
-#define AUTO_RSP_CFG	0x1404			//TXRX_CSR4
-//
-// TXRX_CSR4: Auto-Responder/
-//
-typedef union _AUTO_RSP_CFG_STRUC {
- struct {
-     UINT32       AutoResponderEnable:1;
-     UINT32       BACAckPolicyEnable:1;    // 0:long, 1:short preamble
-     UINT32       CTS40MMode:1;  // Response CTS 40MHz duplicate mode
-     UINT32       CTS40MRef:1;  // Response CTS 40MHz duplicate mode
-     UINT32       AutoResponderPreamble:1;    // 0:long, 1:short preamble
-     UINT32       rsv:1;   // Power bit value in conrtrol frame
-     UINT32       DualCTSEn:1;   // Power bit value in conrtrol frame
-     UINT32       AckCtsPsmBit:1;   // Power bit value in conrtrol frame
-     UINT32        :24;
- } field;
- UINT32   word;
-} AUTO_RSP_CFG_STRUC, *PAUTO_RSP_CFG_STRUC;
-
-#define LEGACY_BASIC_RATE	0x1408	//  TXRX_CSR5           0x3054
-#define HT_BASIC_RATE		0x140c
-#define HT_CTRL_CFG		0x1410
-#define SIFS_COST_CFG		0x1414
-#define RX_PARSER_CFG		0x1418	//Set NAV for all received frames
-
-//
-//  4.5 MAC Security configuration (offset:0x1500)
-//
-#define TX_SEC_CNT0		0x1500		//
-#define RX_SEC_CNT0		0x1504		//
-#define CCMP_FC_MUTE		0x1508		//
-//
-//  4.6 HCCA/PSMP (offset:0x1600)
-//
-#define TXOP_HLDR_ADDR0		0x1600
-#define TXOP_HLDR_ADDR1		0x1604
-#define TXOP_HLDR_ET		0x1608
-#define QOS_CFPOLL_RA_DW0		0x160c
-#define QOS_CFPOLL_A1_DW1		0x1610
-#define QOS_CFPOLL_QC		0x1614
-//
-//  4.7 MAC Statistis registers (offset:0x1700)
-//
-#define RX_STA_CNT0		0x1700		//
-#define RX_STA_CNT1		0x1704		//
-#define RX_STA_CNT2		0x1708		//
-
-//
-// RX_STA_CNT0_STRUC: RX PLCP error count & RX CRC error count
-//
-typedef	union	_RX_STA_CNT0_STRUC	{
-	struct	{
-	    USHORT  CrcErr;
-	    USHORT  PhyErr;
-	}	field;
-	UINT32			word;
-}	RX_STA_CNT0_STRUC, *PRX_STA_CNT0_STRUC;
-
-//
-// RX_STA_CNT1_STRUC: RX False CCA count & RX LONG frame count
-//
-typedef	union	_RX_STA_CNT1_STRUC	{
-	struct	{
-	    USHORT  FalseCca;
-	    USHORT  PlcpErr;
-	}	field;
-	UINT32			word;
-}	RX_STA_CNT1_STRUC, *PRX_STA_CNT1_STRUC;
-
-//
-// RX_STA_CNT2_STRUC:
-//
-typedef	union	_RX_STA_CNT2_STRUC	{
-	struct	{
-	    USHORT  RxDupliCount;
-	    USHORT  RxFifoOverflowCount;
-	}	field;
-	UINT32			word;
-}	RX_STA_CNT2_STRUC, *PRX_STA_CNT2_STRUC;
-
-#define TX_STA_CNT0		0x170C		//
-//
-// STA_CSR3: TX Beacon count
-//
-typedef	union	_TX_STA_CNT0_STRUC	{
-	struct	{
-	    USHORT  TxFailCount;
-	    USHORT  TxBeaconCount;
-	}	field;
-	UINT32			word;
-}	TX_STA_CNT0_STRUC, *PTX_STA_CNT0_STRUC;
-
-#define TX_STA_CNT1		0x1710		//
-//
-// TX_STA_CNT1: TX tx count
-//
-typedef	union	_TX_STA_CNT1_STRUC	{
-	struct	{
-	    USHORT  TxSuccess;
-	    USHORT  TxRetransmit;
-	}	field;
-	UINT32			word;
-}	TX_STA_CNT1_STRUC, *PTX_STA_CNT1_STRUC;
-
-#define TX_STA_CNT2		0x1714		//
-//
-// TX_STA_CNT2: TX tx count
-//
-typedef	union	_TX_STA_CNT2_STRUC	{
-	struct	{
-	    USHORT  TxZeroLenCount;
-	    USHORT  TxUnderFlowCount;
-	}	field;
-	UINT32			word;
-}	TX_STA_CNT2_STRUC, *PTX_STA_CNT2_STRUC;
-
-#define TX_STA_FIFO		0x1718		//
-//
-// TX_STA_FIFO_STRUC: TX Result for specific PID status fifo register
-//
-typedef	union PACKED _TX_STA_FIFO_STRUC	{
-	struct	{
-		UINT32       	bValid:1;   // 1:This register contains a valid TX result
-		UINT32       	PidType:4;
-		UINT32       	TxSuccess:1;   // Tx No retry success
-		UINT32       	TxAggre:1;    // Tx Retry Success
-		UINT32       	TxAckRequired:1;    // Tx fail
-		UINT32		wcid:8;		//wireless client index
-//		UINT32		SuccessRate:16;	//include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
-		UINT32		SuccessRate:13;	//include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
-		UINT32		TxBF:1;
-		UINT32		Reserve:2;
-	}	field;
-	UINT32			word;
-}	TX_STA_FIFO_STRUC, *PTX_STA_FIFO_STRUC;
-
-// Debug counter
-#define TX_AGG_CNT	0x171c
-typedef	union	_TX_AGG_CNT_STRUC	{
-	struct	{
-	    USHORT  NonAggTxCount;
-	    USHORT  AggTxCount;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT_STRUC, *PTX_AGG_CNT_STRUC;
-
-// Debug counter
-#define TX_AGG_CNT0	0x1720
-typedef	union	_TX_AGG_CNT0_STRUC	{
-	struct	{
-	    USHORT  AggSize1Count;
-	    USHORT  AggSize2Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT0_STRUC, *PTX_AGG_CNT0_STRUC;
-
-// Debug counter
-#define TX_AGG_CNT1	0x1724
-typedef	union	_TX_AGG_CNT1_STRUC	{
-	struct	{
-	    USHORT  AggSize3Count;
-	    USHORT  AggSize4Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT1_STRUC, *PTX_AGG_CNT1_STRUC;
-
-#define TX_AGG_CNT2	0x1728
-typedef	union	_TX_AGG_CNT2_STRUC	{
-	struct	{
-	    USHORT  AggSize5Count;
-	    USHORT  AggSize6Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT2_STRUC, *PTX_AGG_CNT2_STRUC;
-
-// Debug counter
-#define TX_AGG_CNT3	0x172c
-typedef	union	_TX_AGG_CNT3_STRUC	{
-	struct	{
-	    USHORT  AggSize7Count;
-	    USHORT  AggSize8Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT3_STRUC, *PTX_AGG_CNT3_STRUC;
-
-// Debug counter
-#define TX_AGG_CNT4	0x1730
-typedef	union	_TX_AGG_CNT4_STRUC	{
-	struct	{
-	    USHORT  AggSize9Count;
-	    USHORT  AggSize10Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT4_STRUC, *PTX_AGG_CNT4_STRUC;
-
-#define TX_AGG_CNT5	0x1734
-typedef	union	_TX_AGG_CNT5_STRUC	{
-	struct	{
-	    USHORT  AggSize11Count;
-	    USHORT  AggSize12Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT5_STRUC, *PTX_AGG_CNT5_STRUC;
-
-#define TX_AGG_CNT6		0x1738
-typedef	union	_TX_AGG_CNT6_STRUC	{
-	struct	{
-	    USHORT  AggSize13Count;
-	    USHORT  AggSize14Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT6_STRUC, *PTX_AGG_CNT6_STRUC;
-
-#define TX_AGG_CNT7		0x173c
-typedef	union	_TX_AGG_CNT7_STRUC	{
-	struct	{
-	    USHORT  AggSize15Count;
-	    USHORT  AggSize16Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT7_STRUC, *PTX_AGG_CNT7_STRUC;
-
-#define MPDU_DENSITY_CNT		0x1740
-typedef	union	_MPDU_DEN_CNT_STRUC	{
-	struct	{
-	    USHORT  TXZeroDelCount;	//TX zero length delimiter count
-	    USHORT  RXZeroDelCount;	//RX zero length delimiter count
-	}	field;
-	UINT32			word;
-}	MPDU_DEN_CNT_STRUC, *PMPDU_DEN_CNT_STRUC;
-
-//
-// TXRX control registers - base address 0x3000
-//
-// rt2860b  UNKNOWN reg use R/O Reg Addr 0x77d0 first..
-#define TXRX_CSR1           0x77d0
-
-//
-// Security key table memory, base address = 0x1000
-//
-#define MAC_WCID_BASE		0x1800 //8-bytes(use only 6-bytes) * 256 entry =
-#define HW_WCID_ENTRY_SIZE   8
-#define PAIRWISE_KEY_TABLE_BASE     0x4000      // 32-byte * 256-entry =  -byte
-#define HW_KEY_ENTRY_SIZE           0x20
-#define PAIRWISE_IVEIV_TABLE_BASE     0x6000      // 8-byte * 256-entry =  -byte
-#define MAC_IVEIV_TABLE_BASE     0x6000      // 8-byte * 256-entry =  -byte
-#define HW_IVEIV_ENTRY_SIZE   8
-#define MAC_WCID_ATTRIBUTE_BASE     0x6800      // 4-byte * 256-entry =  -byte
-#define HW_WCID_ATTRI_SIZE   4
-#define WCID_RESERVED          		0x6bfc
-#define SHARED_KEY_TABLE_BASE       0x6c00      // 32-byte * 16-entry = 512-byte
-#define SHARED_KEY_MODE_BASE       0x7000      // 32-byte * 16-entry = 512-byte
-#define HW_SHARED_KEY_MODE_SIZE   4
-#define SHAREDKEYTABLE			0
-#define PAIRWISEKEYTABLE			1
-
-typedef	union	_SHAREDKEY_MODE_STRUC	{
-	struct	{
-		UINT32       Bss0Key0CipherAlg:3;
-		UINT32       :1;
-		UINT32       Bss0Key1CipherAlg:3;
-		UINT32       :1;
-		UINT32       Bss0Key2CipherAlg:3;
-		UINT32       :1;
-		UINT32       Bss0Key3CipherAlg:3;
-		UINT32       :1;
-		UINT32       Bss1Key0CipherAlg:3;
-		UINT32       :1;
-		UINT32       Bss1Key1CipherAlg:3;
-		UINT32       :1;
-		UINT32       Bss1Key2CipherAlg:3;
-		UINT32       :1;
-		UINT32       Bss1Key3CipherAlg:3;
-		UINT32       :1;
-	}	field;
-	UINT32			word;
-}	SHAREDKEY_MODE_STRUC, *PSHAREDKEY_MODE_STRUC;
-
-// 64-entry for pairwise key table
-typedef struct _HW_WCID_ENTRY {  // 8-byte per entry
-    UCHAR   Address[6];
-    UCHAR   Rsv[2];
-} HW_WCID_ENTRY, PHW_WCID_ENTRY;
-
-
-
-//
-// Other on-chip shared memory space, base = 0x2000
-//
-
-// CIS space - base address = 0x2000
-#define HW_CIS_BASE             0x2000
-
-// Carrier-sense CTS frame base address. It's where mac stores carrier-sense frame for carrier-sense function.
-#define HW_CS_CTS_BASE			0x7700
-// DFS CTS frame base address. It's where mac stores CTS frame for DFS.
-#define HW_DFS_CTS_BASE			0x7780
-#define HW_CTS_FRAME_SIZE		0x80
-
-// 2004-11-08 john - since NULL frame won't be that long (256 byte). We steal 16 tail bytes
-// to save debugging settings
-#define HW_DEBUG_SETTING_BASE   0x77f0  // 0x77f0~0x77ff total 16 bytes
-#define HW_DEBUG_SETTING_BASE2   0x7770  // 0x77f0~0x77ff total 16 bytes
-
-// In order to support maximum 8 MBSS and its maximum length is 512 for each beacon
-// Three section discontinue memory segments will be used.
-// 1. The original region for BCN 0~3
-// 2. Extract memory from FCE table for BCN 4~5
-// 3. Extract memory from Pair-wise key table for BCN 6~7
-//	  It occupied those memory of wcid 238~253 for BCN 6
-//						      and wcid 222~237 for BCN 7
-#define HW_BEACON_MAX_SIZE      0x1000 /* unit: byte */
-#define HW_BEACON_BASE0         0x7800
-#define HW_BEACON_BASE1         0x7A00
-#define HW_BEACON_BASE2         0x7C00
-#define HW_BEACON_BASE3         0x7E00
-#define HW_BEACON_BASE4         0x7200
-#define HW_BEACON_BASE5         0x7400
-#define HW_BEACON_BASE6         0x5DC0
-#define HW_BEACON_BASE7         0x5BC0
-
-#define HW_BEACON_MAX_COUNT     8
-#define HW_BEACON_OFFSET		0x0200
-#define HW_BEACON_CONTENT_LEN	(HW_BEACON_OFFSET - TXWI_SIZE)
-
-// HOST-MCU shared memory - base address = 0x2100
-#define HOST_CMD_CSR		0x404
-#define H2M_MAILBOX_CSR         0x7010
-#define H2M_MAILBOX_CID         0x7014
-#define H2M_MAILBOX_STATUS      0x701c
-#define H2M_INT_SRC             0x7024
-#define H2M_BBP_AGENT           0x7028
-#define M2H_CMD_DONE_CSR        0x000c
-#define MCU_TXOP_ARRAY_BASE     0x000c   // TODO: to be provided by Albert
-#define MCU_TXOP_ENTRY_SIZE     32       // TODO: to be provided by Albert
-#define MAX_NUM_OF_TXOP_ENTRY   16       // TODO: must be same with 8051 firmware
-#define MCU_MBOX_VERSION        0x01     // TODO: to be confirmed by Albert
-#define MCU_MBOX_VERSION_OFFSET 5        // TODO: to be provided by Albert
-
-//
-// Host DMA registers - base address 0x200 .  TX0-3=EDCAQid0-3, TX4=HCCA, TX5=MGMT,
-//
-//
-//  DMA RING DESCRIPTOR
-//
-#define E2PROM_CSR          0x0004
-#define IO_CNTL_CSR         0x77d0
-
-#ifdef RT2860
-// 8051 firmware image for RT2860 - base address = 0x4000
-#define FIRMWARE_IMAGE_BASE     0x2000
-#define MAX_FIRMWARE_IMAGE_SIZE 0x2000    // 8kbyte
-#endif
-#ifdef RT2870
-// 8051 firmware image for usb - use last-half base address = 0x3000
-#define FIRMWARE_IMAGE_BASE     0x3000
-#define MAX_FIRMWARE_IMAGE_SIZE 0x1000    // 4kbyte
-#endif // RT2870 //
-
-// ================================================================
-// Tx /	Rx / Mgmt ring descriptor definition
-// ================================================================
-
-// the following PID values are used to mark outgoing frame type in TXD->PID so that
-// proper TX statistics can be collected based on these categories
-// b3-2 of PID field -
-#define PID_MGMT			0x05
-#define PID_BEACON			0x0c
-#define PID_DATA_NORMALUCAST	 	0x02
-#define PID_DATA_AMPDU	 	0x04
-#define PID_DATA_NO_ACK    	0x08
-#define PID_DATA_NOT_NORM_ACK	 	0x03
-// value domain of pTxD->HostQId (4-bit: 0~15)
-#define QID_AC_BK               1   // meet ACI definition in 802.11e
-#define QID_AC_BE               0   // meet ACI definition in 802.11e
-#define QID_AC_VI               2
-#define QID_AC_VO               3
-#define QID_HCCA                4
-#define NUM_OF_TX_RING          5
-#define QID_MGMT                13
-#define QID_RX                  14
-#define QID_OTHER               15
-
-
-// ------------------------------------------------------
-// BBP & RF	definition
-// ------------------------------------------------------
-#define	BUSY		                1
-#define	IDLE		                0
-
-#define	RF_R00					    0
-#define	RF_R01					    1
-#define	RF_R02					    2
-#define	RF_R03					    3
-#define	RF_R04					    4
-#define	RF_R05					    5
-#define	RF_R06					    6
-#define	RF_R07					    7
-#define	RF_R08					    8
-#define	RF_R09					    9
-#define	RF_R10					    10
-#define	RF_R11					    11
-#define	RF_R12					    12
-#define	RF_R13					    13
-#define	RF_R14					    14
-#define	RF_R15					    15
-#define	RF_R16					    16
-#define	RF_R17					    17
-#define	RF_R18					    18
-#define	RF_R19					    19
-#define	RF_R20					    20
-#define	RF_R21					    21
-#define	RF_R22					    22
-#define	RF_R23					    23
-#define	RF_R24					    24
-#define	RF_R25					    25
-#define	RF_R26					    26
-#define	RF_R27					    27
-#define	RF_R28					    28
-#define	RF_R29					    29
-#define	RF_R30					    30
-#define	RF_R31					    31
-
-#define	BBP_R0					    0  // version
-#define	BBP_R1				        1  // TSSI
-#define	BBP_R2          			2  // TX configure
-#define BBP_R3                      3
-#define BBP_R4                      4
-#define BBP_R5                      5
-#define BBP_R6                      6
-#define	BBP_R14			            14 // RX configure
-#define BBP_R16                     16
-#define BBP_R17                     17 // RX sensibility
-#define BBP_R18                     18
-#define BBP_R21                     21
-#define BBP_R22                     22
-#define BBP_R24                     24
-#define BBP_R25                     25
-#define BBP_R31                     31
-#define BBP_R49                     49 //TSSI
-#define BBP_R50                     50
-#define BBP_R51                     51
-#define BBP_R52                     52
-#define BBP_R55                     55
-#define BBP_R62                     62 // Rx SQ0 Threshold HIGH
-#define BBP_R63                     63
-#define BBP_R64                     64
-#define BBP_R65                     65
-#define BBP_R66                     66
-#define BBP_R67                     67
-#define BBP_R68                     68
-#define BBP_R69                     69
-#define BBP_R70                     70 // Rx AGC SQ CCK Xcorr threshold
-#define BBP_R73                     73
-#define BBP_R75						75
-#define BBP_R77                     77
-#define BBP_R79                     79
-#define BBP_R80                     80
-#define BBP_R81                     81
-#define BBP_R82                     82
-#define BBP_R83                     83
-#define BBP_R84                     84
-#define BBP_R86						86
-#define BBP_R91						91
-#define BBP_R92						92
-#define BBP_R94                     94 // Tx Gain Control
-#define BBP_R103                    103
-#define BBP_R105                    105
-#define BBP_R113                    113
-#define BBP_R114                    114
-#define BBP_R115                    115
-#define BBP_R116                    116
-#define BBP_R117                    117
-#define BBP_R118                    118
-#define BBP_R119                    119
-#define BBP_R120                    120
-#define BBP_R121                    121
-#define BBP_R122                    122
-#define BBP_R123                    123
-#define BBP_R138                    138 // add by johnli, RF power sequence setup, ADC dynamic on/off control
-
-
-#define BBPR94_DEFAULT              0x06 // Add 1 value will gain 1db
-
-#define RSSI_FOR_VERY_LOW_SENSIBILITY -35
-#define RSSI_FOR_LOW_SENSIBILITY      -58
-#define RSSI_FOR_MID_LOW_SENSIBILITY  -80
-#define RSSI_FOR_MID_SENSIBILITY      -90
-
-//-------------------------------------------------------------------------
-// EEPROM definition
-//-------------------------------------------------------------------------
-#define EEDO                        0x08
-#define EEDI                        0x04
-#define EECS                        0x02
-#define EESK                        0x01
-#define EERL                        0x80
-
-#define EEPROM_WRITE_OPCODE         0x05
-#define EEPROM_READ_OPCODE          0x06
-#define EEPROM_EWDS_OPCODE          0x10
-#define EEPROM_EWEN_OPCODE          0x13
-
-#define	NUM_EEPROM_BBP_PARMS		19			// Include NIC Config 0, 1, CR, TX ALC step, BBPs
-#define	NUM_EEPROM_TX_G_PARMS		7
-#define	EEPROM_NIC1_OFFSET          0x34		// The address is from NIC config 0, not BBP register ID
-#define	EEPROM_NIC2_OFFSET          0x36		// The address is from NIC config 0, not BBP register ID
-#define	EEPROM_BBP_BASE_OFFSET		0xf0		// The address is from NIC config 0, not BBP register ID
-#define	EEPROM_G_TX_PWR_OFFSET		0x52
-#define	EEPROM_G_TX2_PWR_OFFSET		0x60
-#define EEPROM_LED1_OFFSET			0x3c
-#define EEPROM_LED2_OFFSET			0x3e
-#define EEPROM_LED3_OFFSET			0x40
-#define EEPROM_LNA_OFFSET			0x44
-#define EEPROM_RSSI_BG_OFFSET		0x46
-#define EEPROM_RSSI_A_OFFSET		0x4a
-#define EEPROM_DEFINE_MAX_TXPWR		0x4e
-#define EEPROM_TXPOWER_BYRATE_20MHZ_2_4G	0xde	// 20MHZ 2.4G tx power.
-#define EEPROM_TXPOWER_BYRATE_40MHZ_2_4G	0xee	// 40MHZ 2.4G tx power.
-#define EEPROM_TXPOWER_BYRATE_20MHZ_5G		0xfa	// 20MHZ 5G tx power.
-#define EEPROM_TXPOWER_BYRATE_40MHZ_5G		0x10a	// 40MHZ 5G tx power.
-#define EEPROM_A_TX_PWR_OFFSET      0x78
-#define EEPROM_A_TX2_PWR_OFFSET      0xa6
-#define EEPROM_VERSION_OFFSET       0x02
-#define	EEPROM_FREQ_OFFSET			0x3a
-#define EEPROM_TXPOWER_BYRATE 	0xde	// 20MHZ power.
-#define EEPROM_TXPOWER_DELTA		0x50	// 20MHZ AND 40 MHZ use different power. This is delta in 40MHZ.
-#define VALID_EEPROM_VERSION        1
-
-// PairKeyMode definition
-#define PKMODE_NONE                 0
-#define PKMODE_WEP64                1
-#define PKMODE_WEP128               2
-#define PKMODE_TKIP                 3
-#define PKMODE_AES                  4
-#define PKMODE_CKIP64               5
-#define PKMODE_CKIP128              6
-#define PKMODE_TKIP_NO_MIC          7       // MIC appended by driver: not a valid value in hardware key table
-
-// =================================================================================
-// WCID  format
-// =================================================================================
-//7.1	WCID  ENTRY  format  : 8bytes
-typedef	struct	_WCID_ENTRY_STRUC {
-	UCHAR		RXBABitmap7;    // bit0 for TID8, bit7 for TID 15
-	UCHAR		RXBABitmap0;    // bit0 for TID0, bit7 for TID 7
-	UCHAR		MAC[6];	// 0 for shared key table.  1 for pairwise key table
-}	WCID_ENTRY_STRUC, *PWCID_ENTRY_STRUC;
-
-//8.1.1	SECURITY  KEY  format  : 8DW
-// 32-byte per entry, total 16-entry for shared key table, 64-entry for pairwise key table
-typedef struct _HW_KEY_ENTRY {          // 32-byte per entry
-    UCHAR   Key[16];
-    UCHAR   TxMic[8];
-    UCHAR   RxMic[8];
-} HW_KEY_ENTRY, *PHW_KEY_ENTRY;
-
-//8.1.2	IV/EIV  format  : 2DW
-
-//8.1.3	RX attribute entry format  : 1DW
-typedef	struct	_MAC_ATTRIBUTE_STRUC {
-	UINT32		KeyTab:1;	// 0 for shared key table.  1 for pairwise key table
-	UINT32		PairKeyMode:3;
-	UINT32		BSSIDIdx:3; //multipleBSS index for the WCID
-	UINT32		RXWIUDF:3;
-	UINT32		rsv:22;
-}	MAC_ATTRIBUTE_STRUC, *PMAC_ATTRIBUTE_STRUC;
-
-// =================================================================================
-// TX / RX ring descriptor format
-// =================================================================================
-
-// the first 24-byte in TXD is called TXINFO and will be DMAed to MAC block through TXFIFO.
-// MAC block use this TXINFO to control the transmission behavior of this frame.
-#define FIFO_MGMT                 0
-#define FIFO_HCCA                 1
-#define FIFO_EDCA                 2
-
-//
-// TX descriptor format, Tx	ring, Mgmt Ring
-//
-typedef	struct	PACKED _TXD_STRUC {
-	// Word	0
-	UINT32		SDPtr0;
-	// Word	1
-	UINT32		SDLen1:14;
-	UINT32		LastSec1:1;
-	UINT32		Burst:1;
-	UINT32		SDLen0:14;
-	UINT32		LastSec0:1;
-	UINT32		DMADONE:1;
-	//Word2
-	UINT32		SDPtr1;
-	//Word3
-	UINT32		rsv2:24;
-	UINT32		WIV:1;	// Wireless Info Valid. 1 if Driver already fill WI,  o if DMA needs to copy WI to correctposition
-	UINT32		QSEL:2;	// select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
-	UINT32		rsv:2;
-	UINT32		TCO:1;	//
-	UINT32		UCO:1;	//
-	UINT32		ICO:1;	//
-}	TXD_STRUC, *PTXD_STRUC;
-
-//
-// TXD Wireless Information format for Tx ring and Mgmt Ring
-//
-//txop : for txop mode
-// 0:txop for the MPDU frame will be handles by ASIC by register
-// 1/2/3:the MPDU frame is send after PIFS/backoff/SIFS
-typedef	struct	PACKED _TXWI_STRUC {
-	// Word	0
-	UINT32		FRAG:1;		// 1 to inform TKIP engine this is a fragment.
-	UINT32		MIMOps:1;	// the remote peer is in dynamic MIMO-PS mode
-	UINT32		CFACK:1;
-	UINT32		TS:1;
-
-	UINT32		AMPDU:1;
-	UINT32		MpduDensity:3;
-	UINT32		txop:2;	//FOR "THIS" frame. 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs only when previous frame exchange is successful.
-	UINT32		rsv:6;
-
-	UINT32		MCS:7;
-	UINT32		BW:1;	//channel bandwidth 20MHz or 40 MHz
-	UINT32		ShortGI:1;
-	UINT32		STBC:2;	// 1: STBC support MCS =0-7,   2,3 : RESERVE
-	UINT32		Ifs:1;	//
-	UINT32		rsv2:1;
-	UINT32		TxBF:1;	// 3*3
-	UINT32		PHYMODE:2;
-	// Word	1
-	UINT32		ACK:1;
-	UINT32		NSEQ:1;
-	UINT32		BAWinSize:6;
-	UINT32		WirelessCliID:8;
-	UINT32		MPDUtotalByteCount:12;
-	UINT32		PacketId:4;
-	//Word2
-	UINT32		IV;
-	//Word3
-	UINT32		EIV;
-}	TXWI_STRUC, *PTXWI_STRUC;
-
-//
-// Rx descriptor format, Rx	Ring
-//
-#ifdef RT2860
-typedef	struct	PACKED _RXD_STRUC	{
-	// Word	0
-	UINT32		SDP0;
-	// Word	1
-	UINT32		SDL1:14;
-	UINT32		Rsv:2;
-	UINT32		SDL0:14;
-	UINT32		LS0:1;
-	UINT32		DDONE:1;
-	// Word	2
-	UINT32		SDP1;
-	// Word	3
-	UINT32		BA:1;
-	UINT32		DATA:1;
-	UINT32		NULLDATA:1;
-	UINT32		FRAG:1;
-	UINT32		U2M:1;              // 1: this RX frame is unicast to me
-	UINT32		Mcast:1;            // 1: this is a multicast frame
-	UINT32		Bcast:1;            // 1: this is a broadcast frame
-	UINT32		MyBss:1;  	// 1: this frame belongs to the same BSSID
-	UINT32		Crc:1;              // 1: CRC error
-	UINT32		CipherErr:2;        // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid
-	UINT32		AMSDU:1;		// rx with 802.3 header, not 802.11 header.
-	UINT32		HTC:1;
-	UINT32		RSSI:1;
-	UINT32		L2PAD:1;
-	UINT32		AMPDU:1;
-	UINT32		Decrypted:1;	// this frame is being decrypted.
-	UINT32		PlcpSignal:1;		// To be moved
-	UINT32		PlcpRssil:1;// To be moved
-	UINT32		Rsv1:13;
-}	RXD_STRUC, *PRXD_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
-#endif /* RT2860 */
-
-//
-// RXWI wireless information format, in PBF. invisible in driver.
-//
-typedef	struct	PACKED _RXWI_STRUC {
-	// Word	0
-	UINT32		WirelessCliID:8;
-	UINT32		KeyIndex:2;
-	UINT32		BSSID:3;
-	UINT32		UDF:3;
-	UINT32		MPDUtotalByteCount:12;
-	UINT32		TID:4;
-	// Word	1
-	UINT32		FRAG:4;
-	UINT32		SEQUENCE:12;
-	UINT32		MCS:7;
-	UINT32		BW:1;
-	UINT32		ShortGI:1;
-	UINT32		STBC:2;
-	UINT32		rsv:3;
-	UINT32		PHYMODE:2;              // 1: this RX frame is unicast to me
-	//Word2
-	UINT32		RSSI0:8;
-	UINT32		RSSI1:8;
-	UINT32		RSSI2:8;
-	UINT32		rsv1:8;
-	//Word3
-	UINT32		SNR0:8;
-	UINT32		SNR1:8;
-	UINT32		rsv2:16;
-}	RXWI_STRUC, *PRXWI_STRUC;
-
-// =================================================================================
-// HOST-MCU communication data structure
-// =================================================================================
-
-//
-// H2M_MAILBOX_CSR: Host-to-MCU Mailbox
-//
-typedef union  _H2M_MAILBOX_STRUC {
-    struct {
-        UINT32       LowByte:8;
-        UINT32       HighByte:8;
-        UINT32       CmdToken:8;
-        UINT32       Owner:8;
-    }   field;
-    UINT32           word;
-} H2M_MAILBOX_STRUC, *PH2M_MAILBOX_STRUC;
-
-//
-// M2H_CMD_DONE_CSR: MCU-to-Host command complete indication
-//
-typedef union _M2H_CMD_DONE_STRUC {
-    struct  {
-        UINT32       CmdToken0;
-        UINT32       CmdToken1;
-        UINT32       CmdToken2;
-        UINT32       CmdToken3;
-    } field;
-    UINT32           word;
-} M2H_CMD_DONE_STRUC, *PM2H_CMD_DONE_STRUC;
-
-//
-// MCU_LEDCS: MCU LED Control Setting.
-//
-typedef union  _MCU_LEDCS_STRUC {
-	struct	{
-		UCHAR		LedMode:7;
-		UCHAR		Polarity:1;
-	} field;
-	UCHAR			word;
-} MCU_LEDCS_STRUC, *PMCU_LEDCS_STRUC;
-
-// =================================================================================
-// Register format
-// =================================================================================
-
-
-
-//NAV_TIME_CFG :NAV
-typedef	union	_NAV_TIME_CFG_STRUC	{
-	struct	{
-		UCHAR		Sifs;               // in unit of 1-us
-		UCHAR       SlotTime;    // in unit of 1-us
-		USHORT		Eifs:9;               // in unit of 1-us
-		USHORT		ZeroSifs:1;               // Applied zero SIFS timer after OFDM RX 0: disable
-		USHORT		rsv:6;
-	}	field;
-	UINT32			word;
-}	NAV_TIME_CFG_STRUC, *PNAV_TIME_CFG_STRUC;
-
-//
-// RX_FILTR_CFG:  /RX configuration register
-//
-typedef	union	_RX_FILTR_CFG_STRUC	{
-	struct	{
-		UINT32		DropCRCErr:1;		// Drop CRC error
-		UINT32		DropPhyErr:1;		// Drop physical error
-		UINT32		DropNotToMe:1;		// Drop not to me unicast frame
-		UINT32		DropNotMyBSSID:1;			// Drop fram ToDs bit is true
-
-		UINT32		DropVerErr:1;	    // Drop version error frame
-		UINT32		DropMcast:1;		// Drop multicast frames
-		UINT32		DropBcast:1;		// Drop broadcast frames
-		UINT32		DropDuplicate:1;		// Drop duplicate frame
-
-		UINT32		DropCFEndAck:1;		// Drop Ps-Poll
-		UINT32		DropCFEnd:1;		// Drop Ps-Poll
-		UINT32		DropAck:1;		// Drop Ps-Poll
-		UINT32		DropCts:1;		// Drop Ps-Poll
-
-		UINT32		DropRts:1;		// Drop Ps-Poll
-		UINT32		DropPsPoll:1;		// Drop Ps-Poll
-		UINT32		DropBA:1;		//
-        	UINT32       	DropBAR:1;       //
-
-		UINT32       	DropRsvCntlType:1;
-		UINT32		:15;
-	}	field;
-	UINT32			word;
-}	RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC;
-
-//
-// PHY_CSR4: RF serial control register
-//
-typedef	union	_PHY_CSR4_STRUC	{
-	struct	{
-		UINT32		RFRegValue:24;		// Register	value (include register	id)	serial out to RF/IF	chip.
-		UINT32		NumberOfBits:5;		// Number of bits used in RFRegValue (I:20,	RFMD:22)
-		UINT32		IFSelect:1;			// 1: select IF	to program,	0: select RF to	program
-		UINT32		PLL_LD:1;			// RF PLL_LD status
-		UINT32		Busy:1;				// 1: ASIC is busy execute RF programming.
-	}	field;
-	UINT32			word;
-}	PHY_CSR4_STRUC, *PPHY_CSR4_STRUC;
-
-//
-// SEC_CSR5: shared key table security mode register
-//
-typedef	union	_SEC_CSR5_STRUC	{
-	struct	{
-        UINT32       Bss2Key0CipherAlg:3;
-        UINT32       :1;
-        UINT32       Bss2Key1CipherAlg:3;
-        UINT32       :1;
-        UINT32       Bss2Key2CipherAlg:3;
-        UINT32       :1;
-        UINT32       Bss2Key3CipherAlg:3;
-        UINT32       :1;
-        UINT32       Bss3Key0CipherAlg:3;
-        UINT32       :1;
-        UINT32       Bss3Key1CipherAlg:3;
-        UINT32       :1;
-        UINT32       Bss3Key2CipherAlg:3;
-        UINT32       :1;
-        UINT32       Bss3Key3CipherAlg:3;
-        UINT32       :1;
-	}	field;
-	UINT32			word;
-}	SEC_CSR5_STRUC, *PSEC_CSR5_STRUC;
-
-//
-// HOST_CMD_CSR: For HOST to interrupt embedded processor
-//
-typedef	union	_HOST_CMD_CSR_STRUC	{
-	struct	{
-	    UINT32   HostCommand:8;
-	    UINT32   Rsv:24;
-	}	field;
-	UINT32			word;
-}	HOST_CMD_CSR_STRUC, *PHOST_CMD_CSR_STRUC;
-
-//
-// AIFSN_CSR: AIFSN for each EDCA AC
-//
-
-
-
-//
-// E2PROM_CSR: EEPROM control register
-//
-typedef	union	_E2PROM_CSR_STRUC	{
-	struct	{
-		UINT32		Reload:1;		// Reload EEPROM content, write one to reload, self-cleared.
-		UINT32		EepromSK:1;
-		UINT32		EepromCS:1;
-		UINT32		EepromDI:1;
-		UINT32		EepromDO:1;
-		UINT32		Type:1;			// 1: 93C46, 0:93C66
-		UINT32       LoadStatus:1;   // 1:loading, 0:done
-		UINT32		Rsvd:25;
-	}	field;
-	UINT32			word;
-}	E2PROM_CSR_STRUC, *PE2PROM_CSR_STRUC;
-
-// -------------------------------------------------------------------
-//  E2PROM data layout
-// -------------------------------------------------------------------
-
-//
-// EEPROM antenna select format
-//
-typedef	union	_EEPROM_ANTENNA_STRUC	{
-	struct	{
-		USHORT		RxPath:4;	// 1: 1R, 2: 2R, 3: 3R
-		USHORT		TxPath:4;	// 1: 1T, 2: 2T
-		USHORT      RfIcType:4;             // see E2PROM document
-		USHORT      Rsv:4;
-	}	field;
-	USHORT			word;
-}	EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC;
-
-typedef	union _EEPROM_NIC_CINFIG2_STRUC	{
-	struct {
-		USHORT		HardwareRadioControl:1;	// 1:enable, 0:disable
-		USHORT		DynamicTxAgcControl:1;			//
-		USHORT		ExternalLNAForG:1;				//
-		USHORT		ExternalLNAForA:1;			// external LNA enable for 2.4G
-		USHORT		CardbusAcceleration:1;	// !!! NOTE: 0 - enable, 1 - disable
-		USHORT		BW40MSidebandForG:1;
-		USHORT		BW40MSidebandForA:1;
-		USHORT		EnableWPSPBC:1;                 // WPS PBC Control bit
-		USHORT		BW40MAvailForG:1;			// 0:enable, 1:disable
-		USHORT		BW40MAvailForA:1;			// 0:enable, 1:disable
-		USHORT		Rsv1:1;					// must be 0
-		USHORT		AntDiversity:1;			// Antenna diversity
-		USHORT		Rsv2:3;					// must be 0
-		USHORT		DACTestBit:1;			// control if driver should patch the DAC issue
-	}	field;
-	USHORT			word;
-}	EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC;
-
-//
-// TX_PWR Value valid range 0xFA(-6) ~ 0x24(36)
-//
-typedef	union	_EEPROM_TX_PWR_STRUC	{
-	struct	{
-		CHAR	Byte0;				// Low Byte
-		CHAR	Byte1;				// High Byte
-	}	field;
-	USHORT	word;
-}	EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC;
-
-typedef	union	_EEPROM_VERSION_STRUC	{
-	struct	{
-		UCHAR	FaeReleaseNumber;	// Low Byte
-		UCHAR	Version;			// High Byte
-	}	field;
-	USHORT	word;
-}	EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC;
-
-typedef	union	_EEPROM_LED_STRUC	{
-	struct	{
-		USHORT	PolarityRDY_G:1;		// Polarity RDY_G setting.
-		USHORT	PolarityRDY_A:1;		// Polarity RDY_A setting.
-		USHORT	PolarityACT:1;		// Polarity ACT setting.
-		USHORT	PolarityGPIO_0:1;	// Polarity GPIO#0 setting.
-		USHORT	PolarityGPIO_1:1;	// Polarity GPIO#1 setting.
-		USHORT	PolarityGPIO_2:1;	// Polarity GPIO#2 setting.
-		USHORT	PolarityGPIO_3:1;	// Polarity GPIO#3 setting.
-		USHORT	PolarityGPIO_4:1;	// Polarity GPIO#4 setting.
-		USHORT	LedMode:5;			// Led mode.
-		USHORT	Rsvd:3;				// Reserved
-	}	field;
-	USHORT	word;
-}	EEPROM_LED_STRUC, *PEEPROM_LED_STRUC;
-
-typedef	union	_EEPROM_TXPOWER_DELTA_STRUC	{
-	struct	{
-		UCHAR	DeltaValue:6;	// Tx Power dalta value (MAX=4)
-		UCHAR	Type:1;			// 1: plus the delta value, 0: minus the delta value
-		UCHAR	TxPowerEnable:1;// Enable
-	}	field;
-	UCHAR	value;
-}	EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC;
-
-//
-// QOS_CSR0: TXOP holder address0 register
-//
-typedef	union	_QOS_CSR0_STRUC	{
-	struct	{
-		UCHAR		Byte0;		// MAC address byte 0
-		UCHAR		Byte1;		// MAC address byte 1
-		UCHAR		Byte2;		// MAC address byte 2
-		UCHAR		Byte3;		// MAC address byte 3
-	}	field;
-	UINT32			word;
-}	QOS_CSR0_STRUC, *PQOS_CSR0_STRUC;
-
-//
-// QOS_CSR1: TXOP holder address1 register
-//
-typedef	union	_QOS_CSR1_STRUC	{
-	struct	{
-		UCHAR		Byte4;		// MAC address byte 4
-		UCHAR		Byte5;		// MAC address byte 5
-		UCHAR		Rsvd0;
-		UCHAR		Rsvd1;
-	}	field;
-	UINT32			word;
-}	QOS_CSR1_STRUC, *PQOS_CSR1_STRUC;
-
-#define	RF_CSR_CFG	0x500
-typedef	union	_RF_CSR_CFG_STRUC	{
-	struct	{
-		UINT	RF_CSR_DATA:8;			// DATA
-		UINT	TESTCSR_RFACC_REGNUM:5;	// RF register ID
-		UINT	Rsvd2:3;				// Reserved
-		UINT	RF_CSR_WR:1;			// 0: read  1: write
-		UINT	RF_CSR_KICK:1;			// kick RF register read/write
-		UINT	Rsvd1:14;				// Reserved
-	}	field;
-	UINT	word;
-}	RF_CSR_CFG_STRUC, *PRF_CSR_CFG_STRUC;
-
-#endif	// __RT28XX_H__
diff --git a/drivers/staging/rt2860/rt_config.h b/drivers/staging/rt2860/rt_config.h
index 2093a80..d1adef8 100644
--- a/drivers/staging/rt2860/rt_config.h
+++ b/drivers/staging/rt2860/rt_config.h
@@ -41,32 +41,31 @@
 #define	__RT_CONFIG_H__
 
 #include    "rtmp_type.h"
-#ifdef LINUX
-#include	"rt_linux.h"
-#endif
-#include    "rtmp_def.h"
-#include    "rt28xx.h"
+#include "rtmp_os.h"
 
-#ifdef RT2860
-#include	"rt2860.h"
-#endif
-#ifdef RT2870
-#include	"../rt2870/rt2870.h"
-#endif // RT2870 //
+#include "rtmp_def.h"
+#include "rtmp_chip.h"
+#include "rtmp_timer.h"
 
 #include    "oid.h"
 #include    "mlme.h"
 #include    "wpa.h"
-#include    "md5.h"
+#include "crypt_md5.h"
+#include "crypt_sha2.h"
+#include "crypt_hmac.h"
 #include    "rtmp.h"
 #include	"ap.h"
 #include	"dfs.h"
 #include	"chlist.h"
 #include	"spectrum.h"
 
+#include "eeprom.h"
+#if defined(RTMP_PCI_SUPPORT) || defined(RTMP_USB_SUPPORT)
+#include "rtmp_mcu.h"
+#endif
+
 #ifdef IGMP_SNOOP_SUPPORT
 #include "igmp_snoop.h"
-#endif // IGMP_SNOOP_SUPPORT //
+#endif /* IGMP_SNOOP_SUPPORT // */
 
-#endif	// __RT_CONFIG_H__
-
+#endif /* __RT_CONFIG_H__ */
diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c
index ed27b85..9357fb2 100644
--- a/drivers/staging/rt2860/rt_linux.c
+++ b/drivers/staging/rt2860/rt_linux.c
@@ -28,149 +28,114 @@
 #include <linux/sched.h>
 #include "rt_config.h"
 
-ULONG	RTDebugLevel = RT_DEBUG_ERROR;
+unsigned long RTDebugLevel = RT_DEBUG_ERROR;
 
-BUILD_TIMER_FUNCTION(MlmePeriodicExec);
-BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
-BUILD_TIMER_FUNCTION(APSDPeriodicExec);
-BUILD_TIMER_FUNCTION(AsicRfTuningExec);
-#ifdef RT2870
-BUILD_TIMER_FUNCTION(BeaconUpdateExec);
-#endif // RT2870 //
-
-BUILD_TIMER_FUNCTION(BeaconTimeout);
-BUILD_TIMER_FUNCTION(ScanTimeout);
-BUILD_TIMER_FUNCTION(AuthTimeout);
-BUILD_TIMER_FUNCTION(AssocTimeout);
-BUILD_TIMER_FUNCTION(ReassocTimeout);
-BUILD_TIMER_FUNCTION(DisassocTimeout);
-BUILD_TIMER_FUNCTION(LinkDownExec);
-BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
-BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
-#ifdef RT2860
-BUILD_TIMER_FUNCTION(PsPollWakeExec);
-BUILD_TIMER_FUNCTION(RadioOnExec);
-#endif
-
-// for wireless system event message
+/* for wireless system event message */
 char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
-	// system status event
-    "had associated successfully",							/* IW_ASSOC_EVENT_FLAG */
-    "had disassociated",									/* IW_DISASSOC_EVENT_FLAG */
-    "had deauthenticated",									/* IW_DEAUTH_EVENT_FLAG */
-    "had been aged-out and disassociated",					/* IW_AGEOUT_EVENT_FLAG */
-    "occurred CounterMeasures attack",						/* IW_COUNTER_MEASURES_EVENT_FLAG */
-    "occurred replay counter different in Key Handshaking",	/* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
-    "occurred RSNIE different in Key Handshaking",			/* IW_RSNIE_DIFF_EVENT_FLAG */
-    "occurred MIC different in Key Handshaking",			/* IW_MIC_DIFF_EVENT_FLAG */
-    "occurred ICV error in RX",								/* IW_ICV_ERROR_EVENT_FLAG */
-    "occurred MIC error in RX",								/* IW_MIC_ERROR_EVENT_FLAG */
-	"Group Key Handshaking timeout",						/* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
-	"Pairwise Key Handshaking timeout",						/* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
-	"RSN IE sanity check failure",							/* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
-	"set key done in WPA/WPAPSK",							/* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
-	"set key done in WPA2/WPA2PSK",                         /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
-	"connects with our wireless client",                    /* IW_STA_LINKUP_EVENT_FLAG */
-	"disconnects with our wireless client",                 /* IW_STA_LINKDOWN_EVENT_FLAG */
-	"scan completed"										/* IW_SCAN_COMPLETED_EVENT_FLAG */
-	"scan terminate!! Busy!! Enqueue fail!!"				/* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
-	};
+	/* system status event */
+	"had associated successfully",	/* IW_ASSOC_EVENT_FLAG */
+	"had disassociated",	/* IW_DISASSOC_EVENT_FLAG */
+	"had deauthenticated",	/* IW_DEAUTH_EVENT_FLAG */
+	"had been aged-out and disassociated",	/* IW_AGEOUT_EVENT_FLAG */
+	"occurred CounterMeasures attack",	/* IW_COUNTER_MEASURES_EVENT_FLAG */
+	"occurred replay counter different in Key Handshaking",	/* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
+	"occurred RSNIE different in Key Handshaking",	/* IW_RSNIE_DIFF_EVENT_FLAG */
+	"occurred MIC different in Key Handshaking",	/* IW_MIC_DIFF_EVENT_FLAG */
+	"occurred ICV error in RX",	/* IW_ICV_ERROR_EVENT_FLAG */
+	"occurred MIC error in RX",	/* IW_MIC_ERROR_EVENT_FLAG */
+	"Group Key Handshaking timeout",	/* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
+	"Pairwise Key Handshaking timeout",	/* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
+	"RSN IE sanity check failure",	/* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
+	"set key done in WPA/WPAPSK",	/* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
+	"set key done in WPA2/WPA2PSK",	/* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
+	"connects with our wireless client",	/* IW_STA_LINKUP_EVENT_FLAG */
+	"disconnects with our wireless client",	/* IW_STA_LINKDOWN_EVENT_FLAG */
+	"scan completed"	/* IW_SCAN_COMPLETED_EVENT_FLAG */
+	    "scan terminate! Busy! Enqueue fail!"	/* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
+};
 
-// for wireless IDS_spoof_attack event message
+/* for wireless IDS_spoof_attack event message */
 char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
-    "detected conflict SSID",								/* IW_CONFLICT_SSID_EVENT_FLAG */
-    "detected spoofed association response",				/* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
-    "detected spoofed reassociation responses",				/* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
-    "detected spoofed probe response",						/* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
-    "detected spoofed beacon",								/* IW_SPOOF_BEACON_EVENT_FLAG */
-    "detected spoofed disassociation",						/* IW_SPOOF_DISASSOC_EVENT_FLAG */
-    "detected spoofed authentication",						/* IW_SPOOF_AUTH_EVENT_FLAG */
-    "detected spoofed deauthentication",					/* IW_SPOOF_DEAUTH_EVENT_FLAG */
-    "detected spoofed unknown management frame",			/* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
-	"detected replay attack"								/* IW_REPLAY_ATTACK_EVENT_FLAG */
-	};
+	"detected conflict SSID",	/* IW_CONFLICT_SSID_EVENT_FLAG */
+	"detected spoofed association response",	/* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
+	"detected spoofed reassociation responses",	/* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
+	"detected spoofed probe response",	/* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
+	"detected spoofed beacon",	/* IW_SPOOF_BEACON_EVENT_FLAG */
+	"detected spoofed disassociation",	/* IW_SPOOF_DISASSOC_EVENT_FLAG */
+	"detected spoofed authentication",	/* IW_SPOOF_AUTH_EVENT_FLAG */
+	"detected spoofed deauthentication",	/* IW_SPOOF_DEAUTH_EVENT_FLAG */
+	"detected spoofed unknown management frame",	/* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
+	"detected replay attack"	/* IW_REPLAY_ATTACK_EVENT_FLAG */
+};
 
-// for wireless IDS_flooding_attack event message
+/* for wireless IDS_flooding_attack event message */
 char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
-	"detected authentication flooding",						/* IW_FLOOD_AUTH_EVENT_FLAG */
-    "detected association request flooding",				/* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
-    "detected reassociation request flooding",				/* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
-    "detected probe request flooding",						/* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
-    "detected disassociation flooding",						/* IW_FLOOD_DISASSOC_EVENT_FLAG */
-    "detected deauthentication flooding",					/* IW_FLOOD_DEAUTH_EVENT_FLAG */
-    "detected 802.1x eap-request flooding"					/* IW_FLOOD_EAP_REQ_EVENT_FLAG */
-	};
+	"detected authentication flooding",	/* IW_FLOOD_AUTH_EVENT_FLAG */
+	"detected association request flooding",	/* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
+	"detected reassociation request flooding",	/* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
+	"detected probe request flooding",	/* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
+	"detected disassociation flooding",	/* IW_FLOOD_DISASSOC_EVENT_FLAG */
+	"detected deauthentication flooding",	/* IW_FLOOD_DEAUTH_EVENT_FLAG */
+	"detected 802.1x eap-request flooding"	/* IW_FLOOD_EAP_REQ_EVENT_FLAG */
+};
 
 /* timeout -- ms */
-VOID RTMP_SetPeriodicTimer(
-	IN	NDIS_MINIPORT_TIMER *pTimer,
-	IN	unsigned long timeout)
+void RTMP_SetPeriodicTimer(struct timer_list * pTimer,
+			   IN unsigned long timeout)
 {
-	timeout = ((timeout*HZ) / 1000);
+	timeout = ((timeout * OS_HZ) / 1000);
 	pTimer->expires = jiffies + timeout;
 	add_timer(pTimer);
 }
 
 /* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
-VOID RTMP_OS_Init_Timer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	NDIS_MINIPORT_TIMER *pTimer,
-	IN	TIMER_FUNCTION function,
-	IN	PVOID data)
+void RTMP_OS_Init_Timer(struct rt_rtmp_adapter *pAd,
+			struct timer_list * pTimer,
+			IN TIMER_FUNCTION function, void *data)
 {
 	init_timer(pTimer);
-    pTimer->data = (unsigned long)data;
-    pTimer->function = function;
+	pTimer->data = (unsigned long)data;
+	pTimer->function = function;
 }
 
-
-VOID RTMP_OS_Add_Timer(
-	IN	NDIS_MINIPORT_TIMER		*pTimer,
-	IN	unsigned long timeout)
+void RTMP_OS_Add_Timer(struct timer_list * pTimer,
+		       IN unsigned long timeout)
 {
 	if (timer_pending(pTimer))
 		return;
 
-	timeout = ((timeout*HZ) / 1000);
+	timeout = ((timeout * OS_HZ) / 1000);
 	pTimer->expires = jiffies + timeout;
 	add_timer(pTimer);
 }
 
-VOID RTMP_OS_Mod_Timer(
-	IN	NDIS_MINIPORT_TIMER		*pTimer,
-	IN	unsigned long timeout)
+void RTMP_OS_Mod_Timer(struct timer_list * pTimer,
+		       IN unsigned long timeout)
 {
-	timeout = ((timeout*HZ) / 1000);
+	timeout = ((timeout * OS_HZ) / 1000);
 	mod_timer(pTimer, jiffies + timeout);
 }
 
-VOID RTMP_OS_Del_Timer(
-	IN	NDIS_MINIPORT_TIMER		*pTimer,
-	OUT	BOOLEAN					*pCancelled)
+void RTMP_OS_Del_Timer(struct timer_list * pTimer,
+		       OUT BOOLEAN * pCancelled)
 {
-	if (timer_pending(pTimer))
-	{
+	if (timer_pending(pTimer)) {
 		*pCancelled = del_timer_sync(pTimer);
-	}
-	else
-	{
+	} else {
 		*pCancelled = TRUE;
 	}
 
 }
 
-VOID RTMP_OS_Release_Packet(
-	IN	PRTMP_ADAPTER pAd,
-	IN	PQUEUE_ENTRY  pEntry)
+void RTMP_OS_Release_Packet(struct rt_rtmp_adapter *pAd, struct rt_queue_entry *pEntry)
 {
-	//RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry);
+	/*RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry); */
 }
 
-// Unify all delay routine by using udelay
-VOID RTMPusecDelay(
-	IN	ULONG	usec)
+/* Unify all delay routine by using udelay */
+void RTMPusecDelay(unsigned long usec)
 {
-	ULONG	i;
+	unsigned long i;
 
 	for (i = 0; i < (usec / 50); i++)
 		udelay(50);
@@ -179,28 +144,23 @@
 		udelay(usec % 50);
 }
 
-void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
+void RTMP_GetCurrentSystemTime(LARGE_INTEGER * time)
 {
 	time->u.LowPart = jiffies;
 }
 
-// pAd MUST allow to be NULL
-NDIS_STATUS os_alloc_mem(
-	IN	PRTMP_ADAPTER pAd,
-	OUT	PUCHAR *mem,
-	IN	ULONG  size)
+/* pAd MUST allow to be NULL */
+int os_alloc_mem(struct rt_rtmp_adapter *pAd, u8 ** mem, unsigned long size)
 {
-	*mem = (PUCHAR) kmalloc(size, GFP_ATOMIC);
+	*mem = (u8 *)kmalloc(size, GFP_ATOMIC);
 	if (*mem)
 		return (NDIS_STATUS_SUCCESS);
 	else
 		return (NDIS_STATUS_FAILURE);
 }
 
-// pAd MUST allow to be NULL
-NDIS_STATUS os_free_mem(
-	IN	PRTMP_ADAPTER pAd,
-	IN	PUCHAR mem)
+/* pAd MUST allow to be NULL */
+int os_free_mem(struct rt_rtmp_adapter *pAd, void *mem)
 {
 
 	ASSERT(mem);
@@ -208,66 +168,64 @@
 	return (NDIS_STATUS_SUCCESS);
 }
 
+void *RtmpOSNetPktAlloc(struct rt_rtmp_adapter *pAd, IN int size)
+{
+	struct sk_buff *skb;
+	/* Add 2 more bytes for ip header alignment */
+	skb = dev_alloc_skb(size + 2);
 
-PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length)
+	return ((void *)skb);
+}
+
+void *RTMP_AllocateFragPacketBuffer(struct rt_rtmp_adapter *pAd,
+					   unsigned long Length)
 {
 	struct sk_buff *pkt;
 
 	pkt = dev_alloc_skb(Length);
 
-	if (pkt == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("can't allocate frag rx %ld size packet\n",Length));
+	if (pkt == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("can't allocate frag rx %ld size packet\n", Length));
 	}
 
-	if (pkt)
-	{
+	if (pkt) {
 		RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
 	}
 
-	return (PNDIS_PACKET) pkt;
+	return (void *)pkt;
 }
 
-
-PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress)
+void *RTMP_AllocateTxPacketBuffer(struct rt_rtmp_adapter *pAd,
+					 unsigned long Length,
+					 IN BOOLEAN Cached,
+					 void ** VirtualAddress)
 {
 	struct sk_buff *pkt;
 
 	pkt = dev_alloc_skb(Length);
 
-	if (pkt == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("can't allocate tx %ld size packet\n",Length));
+	if (pkt == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("can't allocate tx %ld size packet\n", Length));
 	}
 
-	if (pkt)
-	{
+	if (pkt) {
 		RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
-		*VirtualAddress = (PVOID) pkt->data;
-	}
-	else
-	{
-		*VirtualAddress = (PVOID) NULL;
+		*VirtualAddress = (void *)pkt->data;
+	} else {
+		*VirtualAddress = (void *)NULL;
 	}
 
-	return (PNDIS_PACKET) pkt;
+	return (void *)pkt;
 }
 
-
-VOID build_tx_packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket,
-	IN	PUCHAR	pFrame,
-	IN	ULONG	FrameLen)
+void build_tx_packet(struct rt_rtmp_adapter *pAd,
+		     void *pPacket,
+		     u8 *pFrame, unsigned long FrameLen)
 {
 
-	struct sk_buff	*pTxPkt;
+	struct sk_buff *pTxPkt;
 
 	ASSERT(pPacket);
 	pTxPkt = RTPKT_TO_OSPKT(pPacket);
@@ -275,32 +233,36 @@
 	NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
 }
 
-VOID	RTMPFreeAdapter(
-	IN	PRTMP_ADAPTER	pAd)
+void RTMPFreeAdapter(struct rt_rtmp_adapter *pAd)
 {
-    POS_COOKIE os_cookie;
+	struct os_cookie *os_cookie;
 	int index;
 
-	os_cookie=(POS_COOKIE)pAd->OS_Cookie;
+	os_cookie = (struct os_cookie *)pAd->OS_Cookie;
 
-	kfree(pAd->BeaconBuf);
-
+	if (pAd->BeaconBuf)
+		kfree(pAd->BeaconBuf);
 
 	NdisFreeSpinLock(&pAd->MgmtRingLock);
-#ifdef RT2860
+
+#ifdef RTMP_MAC_PCI
 	NdisFreeSpinLock(&pAd->RxRingLock);
-#endif
-	for (index =0 ; index < NUM_OF_TX_RING; index++)
-	{
-    	NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
+#ifdef RT3090
+	NdisFreeSpinLock(&pAd->McuCmdLock);
+#endif /* RT3090 // */
+#endif /* RTMP_MAC_PCI // */
+
+	for (index = 0; index < NUM_OF_TX_RING; index++) {
+		NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
 		NdisFreeSpinLock(&pAd->DeQueueLock[index]);
 		pAd->DeQueueRunning[index] = FALSE;
 	}
 
 	NdisFreeSpinLock(&pAd->irq_lock);
 
-	vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
-	kfree(os_cookie);
+	vfree(pAd);		/* pci_free_consistent(os_cookie->pci_dev,sizeof(struct rt_rtmp_adapter),pAd,os_cookie->pAd_pa); */
+	if (os_cookie)
+		kfree(os_cookie);
 }
 
 BOOLEAN OS_Need_Clone_Packet(void)
@@ -308,8 +270,6 @@
 	return (FALSE);
 }
 
-
-
 /*
 	========================================================================
 
@@ -317,7 +277,7 @@
 		clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
 		must have only one NDIS BUFFER
 		return - byte copied. 0 means can't create NDIS PACKET
-		NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket
+		NOTE: internally created char should be destroyed by RTMPFreeNdisPacket
 
 	Arguments:
 		pAd 	Pointer to our adapter
@@ -332,11 +292,10 @@
 
 	========================================================================
 */
-NDIS_STATUS RTMPCloneNdisPacket(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	BOOLEAN			pInsAMSDUHdr,
-	IN	PNDIS_PACKET	pInPacket,
-	OUT PNDIS_PACKET   *ppOutPacket)
+int RTMPCloneNdisPacket(struct rt_rtmp_adapter *pAd,
+				IN BOOLEAN pInsAMSDUHdr,
+				void *pInPacket,
+				void ** ppOutPacket)
 {
 
 	struct sk_buff *pkt;
@@ -344,19 +303,18 @@
 	ASSERT(pInPacket);
 	ASSERT(ppOutPacket);
 
-	// 1. Allocate a packet
+	/* 1. Allocate a packet */
 	pkt = dev_alloc_skb(2048);
 
-	if (pkt == NULL)
-	{
+	if (pkt == NULL) {
 		return NDIS_STATUS_FAILURE;
 	}
 
- 	skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
-	NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket));
+	skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
+	NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket),
+		       GET_OS_PKT_LEN(pInPacket));
 	*ppOutPacket = OSPKT_TO_RTPKT(pkt);
 
-
 	RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
 
 	printk("###Clone###\n");
@@ -364,42 +322,40 @@
 	return NDIS_STATUS_SUCCESS;
 }
 
-
-// the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
-NDIS_STATUS RTMPAllocateNdisPacket(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT PNDIS_PACKET   *ppPacket,
-	IN	PUCHAR			pHeader,
-	IN	UINT			HeaderLen,
-	IN	PUCHAR			pData,
-	IN	UINT			DataLen)
+/* the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket() */
+int RTMPAllocateNdisPacket(struct rt_rtmp_adapter *pAd,
+				   void ** ppPacket,
+				   u8 *pHeader,
+				   u32 HeaderLen,
+				   u8 *pData, u32 DataLen)
 {
-	PNDIS_PACKET	pPacket;
+	void *pPacket;
 	ASSERT(pData);
 	ASSERT(DataLen);
 
-	// 1. Allocate a packet
-	pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE);
-	if (pPacket == NULL)
- 	{
+	/* 1. Allocate a packet */
+	pPacket =
+	    (void **) dev_alloc_skb(HeaderLen + DataLen +
+					   RTMP_PKT_TAIL_PADDING);
+	if (pPacket == NULL) {
 		*ppPacket = NULL;
 #ifdef DEBUG
-		printk("RTMPAllocateNdisPacket Fail\n\n");
+		printk("RTMPAllocateNdisPacket Fail\n");
 #endif
 		return NDIS_STATUS_FAILURE;
 	}
-
-	// 2. clone the frame content
+	/* 2. clone the frame content */
 	if (HeaderLen > 0)
 		NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
 	if (DataLen > 0)
-		NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen);
+		NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData,
+			       DataLen);
 
-	// 3. update length of packet
- 	skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen);
+	/* 3. update length of packet */
+	skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen + DataLen);
 
 	RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
-//	printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket));
+/*      printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket)); */
 	*ppPacket = pPacket;
 	return NDIS_STATUS_SUCCESS;
 }
@@ -407,42 +363,34 @@
 /*
   ========================================================================
   Description:
-	This routine frees a miniport internally allocated NDIS_PACKET and its
+	This routine frees a miniport internally allocated char and its
 	corresponding NDIS_BUFFER and allocated memory.
   ========================================================================
 */
-VOID RTMPFreeNdisPacket(
-	IN PRTMP_ADAPTER pAd,
-	IN PNDIS_PACKET  pPacket)
+void RTMPFreeNdisPacket(struct rt_rtmp_adapter *pAd, void *pPacket)
 {
 	dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
 }
 
-
-// IRQL = DISPATCH_LEVEL
-// NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same
-//			 scatter gather buffer
-NDIS_STATUS Sniff2BytesFromNdisBuffer(
-	IN	PNDIS_BUFFER	pFirstBuffer,
-	IN	UCHAR			DesiredOffset,
-	OUT PUCHAR			pByte0,
-	OUT PUCHAR			pByte1)
+/* IRQL = DISPATCH_LEVEL */
+/* NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same */
+/*                       scatter gather buffer */
+int Sniff2BytesFromNdisBuffer(char *pFirstBuffer,
+				      u8 DesiredOffset,
+				      u8 *pByte0, u8 *pByte1)
 {
-    *pByte0 = *(PUCHAR)(pFirstBuffer + DesiredOffset);
-    *pByte1 = *(PUCHAR)(pFirstBuffer + DesiredOffset + 1);
+	*pByte0 = *(u8 *)(pFirstBuffer + DesiredOffset);
+	*pByte1 = *(u8 *)(pFirstBuffer + DesiredOffset + 1);
 
 	return NDIS_STATUS_SUCCESS;
 }
 
-
-void RTMP_QueryPacketInfo(
-	IN  PNDIS_PACKET pPacket,
-	OUT PACKET_INFO  *pPacketInfo,
-	OUT PUCHAR		 *pSrcBufVA,
-	OUT	UINT		 *pSrcBufLen)
+void RTMP_QueryPacketInfo(void *pPacket,
+			  struct rt_packet_info *pPacketInfo,
+			  u8 ** pSrcBufVA, u32 * pSrcBufLen)
 {
 	pPacketInfo->BufferCount = 1;
-	pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
+	pPacketInfo->pFirstBuffer = (char *)GET_OS_PKT_DATAPTR(pPacket);
 	pPacketInfo->PhysicalBufferCount = 1;
 	pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
 
@@ -450,30 +398,26 @@
 	*pSrcBufLen = GET_OS_PKT_LEN(pPacket);
 }
 
-void RTMP_QueryNextPacketInfo(
-	IN  PNDIS_PACKET *ppPacket,
-	OUT PACKET_INFO  *pPacketInfo,
-	OUT PUCHAR		 *pSrcBufVA,
-	OUT	UINT		 *pSrcBufLen)
+void RTMP_QueryNextPacketInfo(void ** ppPacket,
+			      struct rt_packet_info *pPacketInfo,
+			      u8 ** pSrcBufVA, u32 * pSrcBufLen)
 {
-	PNDIS_PACKET pPacket = NULL;
+	void *pPacket = NULL;
 
 	if (*ppPacket)
 		pPacket = GET_OS_PKT_NEXT(*ppPacket);
 
-	if (pPacket)
-	{
+	if (pPacket) {
 		pPacketInfo->BufferCount = 1;
-		pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
+		pPacketInfo->pFirstBuffer =
+		    (char *)GET_OS_PKT_DATAPTR(pPacket);
 		pPacketInfo->PhysicalBufferCount = 1;
 		pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
 
 		*pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
 		*pSrcBufLen = GET_OS_PKT_LEN(pPacket);
 		*ppPacket = GET_OS_PKT_NEXT(pPacket);
-	}
-	else
-	{
+	} else {
 		pPacketInfo->BufferCount = 0;
 		pPacketInfo->pFirstBuffer = NULL;
 		pPacketInfo->PhysicalBufferCount = 0;
@@ -485,36 +429,19 @@
 	}
 }
 
-// not yet support MBSS
-PNET_DEV get_netdev_from_bssid(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			FromWhichBSSID)
+void *DuplicatePacket(struct rt_rtmp_adapter *pAd,
+			     void *pPacket, u8 FromWhichBSSID)
 {
-    PNET_DEV dev_p = NULL;
+	struct sk_buff *skb;
+	void *pRetPacket = NULL;
+	u16 DataSize;
+	u8 *pData;
 
-	dev_p = pAd->net_dev;
-
-	ASSERT(dev_p);
-	return dev_p; /* return one of MBSS */
-}
-
-PNDIS_PACKET DuplicatePacket(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket,
-	IN	UCHAR			FromWhichBSSID)
-{
-	struct sk_buff	*skb;
-	PNDIS_PACKET	pRetPacket = NULL;
-	USHORT			DataSize;
-	UCHAR			*pData;
-
-	DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
-	pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
-
+	DataSize = (u16)GET_OS_PKT_LEN(pPacket);
+	pData = (u8 *)GET_OS_PKT_DATAPTR(pPacket);
 
 	skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
-	if (skb)
-	{
+	if (skb) {
 		skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
 		pRetPacket = OSPKT_TO_RTPKT(skb);
 	}
@@ -523,24 +450,21 @@
 
 }
 
-PNDIS_PACKET duplicate_pkt(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pHeader802_3,
-    IN  UINT            HdrLen,
-	IN	PUCHAR			pData,
-	IN	ULONG			DataSize,
-	IN	UCHAR			FromWhichBSSID)
+void *duplicate_pkt(struct rt_rtmp_adapter *pAd,
+			   u8 *pHeader802_3,
+			   u32 HdrLen,
+			   u8 *pData,
+			   unsigned long DataSize, u8 FromWhichBSSID)
 {
-	struct sk_buff	*skb;
-	PNDIS_PACKET	pPacket = NULL;
+	struct sk_buff *skb;
+	void *pPacket = NULL;
 
-
-	if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
-	{
+	if ((skb =
+	     __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL) {
 		skb_reserve(skb, 2);
-		NdisMoveMemory(skb_tail_pointer(skb), pHeader802_3, HdrLen);
+		NdisMoveMemory(skb->tail, pHeader802_3, HdrLen);
 		skb_put(skb, HdrLen);
-		NdisMoveMemory(skb_tail_pointer(skb), pData, DataSize);
+		NdisMoveMemory(skb->tail, pData, DataSize);
 		skb_put(skb, DataSize);
 		skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
 		pPacket = OSPKT_TO_RTPKT(skb);
@@ -549,24 +473,22 @@
 	return pPacket;
 }
 
-
 #define TKIP_TX_MIC_SIZE		8
-PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket)
+void *duplicate_pkt_with_TKIP_MIC(struct rt_rtmp_adapter *pAd,
+					 void *pPacket)
 {
-	struct sk_buff	*skb, *newskb;
-
+	struct sk_buff *skb, *newskb;
 
 	skb = RTPKT_TO_OSPKT(pPacket);
-	if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
-	{
-		// alloc a new skb and copy the packet
-		newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
+	if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE) {
+		/* alloc a new skb and copy the packet */
+		newskb =
+		    skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE,
+				    GFP_ATOMIC);
 		dev_kfree_skb_any(skb);
-		if (newskb == NULL)
-		{
-			DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
+		if (newskb == NULL) {
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
 			return NULL;
 		}
 		skb = newskb;
@@ -575,45 +497,37 @@
 	return OSPKT_TO_RTPKT(skb);
 }
 
-
-
-
-PNDIS_PACKET ClonePacket(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket,
-	IN	PUCHAR			pData,
-	IN	ULONG			DataSize)
+void *ClonePacket(struct rt_rtmp_adapter *pAd,
+			 void *pPacket,
+			 u8 *pData, unsigned long DataSize)
 {
-	struct sk_buff	*pRxPkt;
-	struct sk_buff	*pClonedPkt;
+	struct sk_buff *pRxPkt;
+	struct sk_buff *pClonedPkt;
 
 	ASSERT(pPacket);
 	pRxPkt = RTPKT_TO_OSPKT(pPacket);
 
-	// clone the packet
+	/* clone the packet */
 	pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
 
-	if (pClonedPkt)
-	{
-    	// set the correct dataptr and data len
-    	pClonedPkt->dev = pRxPkt->dev;
-    	pClonedPkt->data = pData;
-    	pClonedPkt->len = DataSize;
-    	pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
+	if (pClonedPkt) {
+		/* set the correct dataptr and data len */
+		pClonedPkt->dev = pRxPkt->dev;
+		pClonedPkt->data = pData;
+		pClonedPkt->len = DataSize;
+		pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
 		ASSERT(DataSize < 1530);
 	}
 	return pClonedPkt;
 }
 
-//
-// change OS packet DataPtr and DataLen
-//
-void  update_os_packet_info(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN  UCHAR			FromWhichBSSID)
+/* */
+/* change OS packet DataPtr and DataLen */
+/* */
+void update_os_packet_info(struct rt_rtmp_adapter *pAd,
+			   struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
 {
-	struct sk_buff	*pOSPkt;
+	struct sk_buff *pOSPkt;
 
 	ASSERT(pRxBlk->pRxPacket);
 	pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
@@ -624,14 +538,12 @@
 	pOSPkt->tail = pOSPkt->data + pOSPkt->len;
 }
 
-
-void wlan_802_11_to_802_3_packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	PUCHAR			pHeader802_3,
-	IN  UCHAR			FromWhichBSSID)
+void wlan_802_11_to_802_3_packet(struct rt_rtmp_adapter *pAd,
+				 struct rt_rx_blk *pRxBlk,
+				 u8 *pHeader802_3,
+				 u8 FromWhichBSSID)
 {
-	struct sk_buff	*pOSPkt;
+	struct sk_buff *pOSPkt;
 
 	ASSERT(pRxBlk->pRxPacket);
 	ASSERT(pHeader802_3);
@@ -643,37 +555,35 @@
 	pOSPkt->len = pRxBlk->DataSize;
 	pOSPkt->tail = pOSPkt->data + pOSPkt->len;
 
-	//
-	// copy 802.3 header
-	//
-	//
+	/* */
+	/* copy 802.3 header */
+	/* */
+	/* */
 
-	NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
+	NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3,
+		       LENGTH_802_3);
 }
 
-void announce_802_3_packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket)
+void announce_802_3_packet(struct rt_rtmp_adapter *pAd, void *pPacket)
 {
 
-	struct sk_buff	*pRxPkt;
+	struct sk_buff *pRxPkt;
 
 	ASSERT(pPacket);
 
 	pRxPkt = RTPKT_TO_OSPKT(pPacket);
 
-    /* Push up the protocol stack */
+	/* Push up the protocol stack */
 	pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
 
 	netif_rx(pRxPkt);
 }
 
-
-PRTMP_SCATTER_GATHER_LIST
-rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
+struct rt_rtmp_sg_list *
+rt_get_sg_list_from_packet(void *pPacket, struct rt_rtmp_sg_list *sg)
 {
 	sg->NumberOfElements = 1;
-	sg->Elements[0].Address =  GET_OS_PKT_DATAPTR(pPacket);
+	sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
 	sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
 	return (sg);
 }
@@ -687,13 +597,13 @@
 		return;
 
 	pt = pSrcBufVA;
-	printk("%s: %p, len = %d\n",str,  pSrcBufVA, SrcBufLen);
-	for (x=0; x<SrcBufLen; x++)
-	{
+	printk("%s: %p, len = %d\n", str, pSrcBufVA, SrcBufLen);
+	for (x = 0; x < SrcBufLen; x++) {
 		if (x % 16 == 0)
 			printk("0x%04x : ", x);
 		printk("%02x ", ((unsigned char)pt[x]));
-		if (x%16 == 15) printk("\n");
+		if (x % 16 == 15)
+			printk("\n");
 	}
 	printk("\n");
 }
@@ -718,187 +628,197 @@
 
 	========================================================================
 */
-VOID RTMPSendWirelessEvent(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Event_flag,
-	IN	PUCHAR 			pAddr,
-	IN	UCHAR			BssIdx,
-	IN	CHAR			Rssi)
+void RTMPSendWirelessEvent(struct rt_rtmp_adapter *pAd,
+			   u16 Event_flag,
+			   u8 *pAddr, u8 BssIdx, char Rssi)
 {
 
-	union 	iwreq_data      wrqu;
-	PUCHAR 	pBuf = NULL, pBufPtr = NULL;
-	USHORT	event, type, BufLen;
-	UCHAR	event_table_len = 0;
+	/*union         iwreq_data      wrqu; */
+	char *pBuf = NULL, *pBufPtr = NULL;
+	u16 event, type, BufLen;
+	u8 event_table_len = 0;
 
 	type = Event_flag & 0xFF00;
 	event = Event_flag & 0x00FF;
 
-	switch (type)
-	{
-		case IW_SYS_EVENT_FLAG_START:
-			event_table_len = IW_SYS_EVENT_TYPE_NUM;
-			break;
+	switch (type) {
+	case IW_SYS_EVENT_FLAG_START:
+		event_table_len = IW_SYS_EVENT_TYPE_NUM;
+		break;
 
-		case IW_SPOOF_EVENT_FLAG_START:
-			event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
-			break;
+	case IW_SPOOF_EVENT_FLAG_START:
+		event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
+		break;
 
-		case IW_FLOOD_EVENT_FLAG_START:
-			event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
-			break;
+	case IW_FLOOD_EVENT_FLAG_START:
+		event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
+		break;
 	}
 
-	if (event_table_len == 0)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __func__, type));
+	if (event_table_len == 0) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("%s : The type(%0x02x) is not valid.\n", __func__,
+			  type));
 		return;
 	}
 
-	if (event >= event_table_len)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __func__, event));
+	if (event >= event_table_len) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("%s : The event(%0x02x) is not valid.\n", __func__,
+			  event));
 		return;
 	}
-
-	//Allocate memory and copy the msg.
-	if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
-	{
-		//Prepare the payload
+	/*Allocate memory and copy the msg. */
+	if ((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL) {
+		/*Prepare the payload */
 		memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
 
 		pBufPtr = pBuf;
 
 		if (pAddr)
-			pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
+			pBufPtr +=
+			    sprintf(pBufPtr,
+				    "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ",
+				    PRINT_MAC(pAddr));
 		else if (BssIdx < MAX_MBSSID_NUM)
-			pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(wlan%d) ", BssIdx);
+			pBufPtr +=
+			    sprintf(pBufPtr, "(RT2860) BSS(wlan%d) ", BssIdx);
 		else
 			pBufPtr += sprintf(pBufPtr, "(RT2860) ");
 
 		if (type == IW_SYS_EVENT_FLAG_START)
-			pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
+			pBufPtr +=
+			    sprintf(pBufPtr, "%s",
+				    pWirelessSysEventText[event]);
 		else if (type == IW_SPOOF_EVENT_FLAG_START)
-			pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
+			pBufPtr +=
+			    sprintf(pBufPtr, "%s (RSSI=%d)",
+				    pWirelessSpoofEventText[event], Rssi);
 		else if (type == IW_FLOOD_EVENT_FLAG_START)
-			pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
+			pBufPtr +=
+			    sprintf(pBufPtr, "%s",
+				    pWirelessFloodEventText[event]);
 		else
 			pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
 
 		pBufPtr[pBufPtr - pBuf] = '\0';
 		BufLen = pBufPtr - pBuf;
 
-		memset(&wrqu, 0, sizeof(wrqu));
-	    wrqu.data.flags = Event_flag;
-		wrqu.data.length = BufLen;
-
-		//send wireless event
-	    wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf);
-
-		//DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf));
+		RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, Event_flag, NULL,
+					(u8 *)pBuf, BufLen);
+		/*DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf)); */
 
 		kfree(pBuf);
-	}
-	else
-		DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __func__));
+	} else
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("%s : Can't allocate memory for wireless event.\n",
+			  __func__));
 }
 
-void send_monitor_packets(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk)
+void send_monitor_packets(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
 {
-    struct sk_buff	*pOSPkt;
-    wlan_ng_prism2_header *ph;
-    int rate_index = 0;
-    USHORT header_len = 0;
-    UCHAR temp_header[40] = {0};
+	struct sk_buff *pOSPkt;
+	struct rt_wlan_ng_prism2_header *ph;
+	int rate_index = 0;
+	u16 header_len = 0;
+	u8 temp_header[40] = { 0 };
 
-    u_int32_t ralinkrate[256] = {2,4,11,22, 12,18,24,36,48,72,96,  108,   109, 110, 111, 112, 13, 26, 39, 52,78,104, 117, 130, 26, 52, 78,104, 156, 208, 234, 260, 27, 54,81,108,162, 216, 243, 270, // Last 38
-	54, 108, 162, 216, 324, 432, 486, 540,  14, 29, 43, 57, 87, 115, 130, 144, 29, 59,87,115, 173, 230,260, 288, 30, 60,90,120,180,240,270,300,60,120,180,240,360,480,540,600, 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,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80};
+	u_int32_t ralinkrate[256] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 109, 110, 111, 112, 13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260, 27, 54, 81, 108, 162, 216, 243, 270,	/* Last 38 */
+		54, 108, 162, 216, 324, 432, 486, 540, 14, 29, 43, 57, 87, 115,
+		    130, 144, 29, 59, 87, 115, 173, 230, 260, 288, 30, 60, 90,
+		    120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540,
+		    600, 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, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+		    42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+		    57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
+		    72, 73, 74, 75, 76, 77, 78, 79, 80
+	};
 
-
-    ASSERT(pRxBlk->pRxPacket);
-    if (pRxBlk->DataSize < 10)
-    {
-        DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __func__, pRxBlk->DataSize));
+	ASSERT(pRxBlk->pRxPacket);
+	if (pRxBlk->DataSize < 10) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("%s : Size is too small! (%d)\n", __func__,
+			  pRxBlk->DataSize));
 		goto err_free_sk_buff;
-    }
+	}
 
-    if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
-    {
-        DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%zu)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
+	if (pRxBlk->DataSize + sizeof(struct rt_wlan_ng_prism2_header) >
+	    RX_BUFFER_AGGRESIZE) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("%s : Size is too large! (%zu)\n", __func__,
+			  pRxBlk->DataSize + sizeof(struct rt_wlan_ng_prism2_header)));
 		goto err_free_sk_buff;
-    }
+	}
 
-    pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
+	pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
 	pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
-    if (pRxBlk->pHeader->FC.Type == BTYPE_DATA)
-    {
-        pRxBlk->DataSize -= LENGTH_802_11;
-        if ((pRxBlk->pHeader->FC.ToDs == 1) &&
-            (pRxBlk->pHeader->FC.FrDs == 1))
-            header_len = LENGTH_802_11_WITH_ADDR4;
-        else
-            header_len = LENGTH_802_11;
+	if (pRxBlk->pHeader->FC.Type == BTYPE_DATA) {
+		pRxBlk->DataSize -= LENGTH_802_11;
+		if ((pRxBlk->pHeader->FC.ToDs == 1) &&
+		    (pRxBlk->pHeader->FC.FrDs == 1))
+			header_len = LENGTH_802_11_WITH_ADDR4;
+		else
+			header_len = LENGTH_802_11;
 
-        // QOS
-    	if (pRxBlk->pHeader->FC.SubType & 0x08)
-    	{
-    	    header_len += 2;
-    		// Data skip QOS contorl field
-    		pRxBlk->DataSize -=2;
-    	}
-
-    	// Order bit: A-Ralink or HTC+
-    	if (pRxBlk->pHeader->FC.Order)
-    	{
-    	    header_len += 4;
-			// Data skip HTC contorl field
+		/* QOS */
+		if (pRxBlk->pHeader->FC.SubType & 0x08) {
+			header_len += 2;
+			/* Data skip QOS contorl field */
+			pRxBlk->DataSize -= 2;
+		}
+		/* Order bit: A-Ralink or HTC+ */
+		if (pRxBlk->pHeader->FC.Order) {
+			header_len += 4;
+			/* Data skip HTC contorl field */
 			pRxBlk->DataSize -= 4;
-    	}
+		}
+		/* Copy Header */
+		if (header_len <= 40)
+			NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
 
-        // Copy Header
-        if (header_len <= 40)
-            NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
-
-        // skip HW padding
-    	if (pRxBlk->RxD.L2PAD)
-    	    pRxBlk->pData += (header_len + 2);
-        else
-            pRxBlk->pData += header_len;
-    } //end if
-
+		/* skip HW padding */
+		if (pRxBlk->RxD.L2PAD)
+			pRxBlk->pData += (header_len + 2);
+		else
+			pRxBlk->pData += header_len;
+	}			/*end if */
 
 	if (pRxBlk->DataSize < pOSPkt->len) {
-        skb_trim(pOSPkt,pRxBlk->DataSize);
-    } else {
-        skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len));
-    } //end if
+		skb_trim(pOSPkt, pRxBlk->DataSize);
+	} else {
+		skb_put(pOSPkt, (pRxBlk->DataSize - pOSPkt->len));
+	}			/*end if */
 
-    if ((pRxBlk->pData - pOSPkt->data) > 0) {
-	    skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data));
-	    skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data));
-    } //end if
+	if ((pRxBlk->pData - pOSPkt->data) > 0) {
+		skb_put(pOSPkt, (pRxBlk->pData - pOSPkt->data));
+		skb_pull(pOSPkt, (pRxBlk->pData - pOSPkt->data));
+	}			/*end if */
 
-    if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) {
-        if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) {
-	        DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __func__));
+	if (skb_headroom(pOSPkt) < (sizeof(struct rt_wlan_ng_prism2_header) + header_len)) {
+		if (pskb_expand_head
+		    (pOSPkt, (sizeof(struct rt_wlan_ng_prism2_header) + header_len), 0,
+		     GFP_ATOMIC)) {
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("%s : Reallocate header size of sk_buff fail!\n",
+				  __func__));
 			goto err_free_sk_buff;
-	    } //end if
-    } //end if
+		}		/*end if */
+	}			/*end if */
 
-    if (header_len > 0)
-        NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len);
+	if (header_len > 0)
+		NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header,
+			       header_len);
 
-    ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header));
-	NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header));
+	ph = (struct rt_wlan_ng_prism2_header *)skb_push(pOSPkt,
+						sizeof(struct rt_wlan_ng_prism2_header));
+	NdisZeroMemory(ph, sizeof(struct rt_wlan_ng_prism2_header));
 
-    ph->msgcode		    = DIDmsg_lnxind_wlansniffrm;
-	ph->msglen		    = sizeof(wlan_ng_prism2_header);
-	strcpy(ph->devname, pAd->net_dev->name);
+	ph->msgcode = DIDmsg_lnxind_wlansniffrm;
+	ph->msglen = sizeof(struct rt_wlan_ng_prism2_header);
+	strcpy((char *)ph->devname, (char *)pAd->net_dev->name);
 
-    ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
+	ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
 	ph->hosttime.status = 0;
 	ph->hosttime.len = 4;
 	ph->hosttime.data = jiffies;
@@ -908,63 +828,71 @@
 	ph->mactime.len = 0;
 	ph->mactime.data = 0;
 
-    ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
+	ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
 	ph->istx.status = 0;
 	ph->istx.len = 0;
 	ph->istx.data = 0;
 
-    ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
+	ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
 	ph->channel.status = 0;
 	ph->channel.len = 4;
 
-    ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel;
+	ph->channel.data = (u_int32_t) pAd->CommonCfg.Channel;
 
-    ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
+	ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
 	ph->rssi.status = 0;
 	ph->rssi.len = 4;
-    ph->rssi.data = (u_int32_t)RTMPMaxRssi(pAd, ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0, RSSI_0), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI1, RSSI_1), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2, RSSI_2));;
+	ph->rssi.data =
+	    (u_int32_t) RTMPMaxRssi(pAd,
+				    ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0,
+						  RSSI_0), ConvertToRssi(pAd,
+									 pRxBlk->
+									 pRxWI->
+									 RSSI1,
+									 RSSI_1),
+				    ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2,
+						  RSSI_2));;
 
 	ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
 	ph->signal.status = 0;
 	ph->signal.len = 4;
-	ph->signal.data = 0; //rssi + noise;
+	ph->signal.data = 0;	/*rssi + noise; */
 
 	ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
 	ph->noise.status = 0;
 	ph->noise.len = 4;
 	ph->noise.data = 0;
 
-    if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX)
-    {
-    	rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS);
-    }
-    else
-	if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
-    	rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4;
-    else
-    	rate_index = (UCHAR)(pRxBlk->pRxWI->MCS);
-    if (rate_index < 0)
-        rate_index = 0;
-    if (rate_index > 255)
-        rate_index = 255;
+	if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX) {
+		rate_index =
+		    16 + ((u8)pRxBlk->pRxWI->BW * 16) +
+		    ((u8)pRxBlk->pRxWI->ShortGI * 32) +
+		    ((u8)pRxBlk->pRxWI->MCS);
+	} else if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
+		rate_index = (u8)(pRxBlk->pRxWI->MCS) + 4;
+	else
+		rate_index = (u8)(pRxBlk->pRxWI->MCS);
+	if (rate_index < 0)
+		rate_index = 0;
+	if (rate_index > 255)
+		rate_index = 255;
 
 	ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
 	ph->rate.status = 0;
 	ph->rate.len = 4;
-    ph->rate.data = ralinkrate[rate_index];
+	ph->rate.data = ralinkrate[rate_index];
 
 	ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
-    ph->frmlen.status = 0;
+	ph->frmlen.status = 0;
 	ph->frmlen.len = 4;
-	ph->frmlen.data	= (u_int32_t)pRxBlk->DataSize;
+	ph->frmlen.data = (u_int32_t) pRxBlk->DataSize;
 
+	pOSPkt->pkt_type = PACKET_OTHERHOST;
+	pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
+	pOSPkt->ip_summed = CHECKSUM_NONE;
+	netif_rx(pOSPkt);
 
-    pOSPkt->pkt_type = PACKET_OTHERHOST;
-    pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
-    pOSPkt->ip_summed = CHECKSUM_NONE;
-    netif_rx(pOSPkt);
-
-    return;
+	return;
 
 err_free_sk_buff:
 	RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
@@ -972,31 +900,470 @@
 
 }
 
-void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
+/*******************************************************************************
+
+	Device IRQ related functions.
+
+ *******************************************************************************/
+int RtmpOSIRQRequest(struct net_device *pNetDev)
 {
-	daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
+#ifdef RTMP_PCI_SUPPORT
+	struct net_device *net_dev = pNetDev;
+	struct rt_rtmp_adapter *pAd = NULL;
+	int retval = 0;
+
+	GET_PAD_FROM_NET_DEV(pAd, pNetDev);
+
+	ASSERT(pAd);
+
+	if (pAd->infType == RTMP_DEV_INF_PCI) {
+		struct os_cookie *_pObj = (struct os_cookie *)(pAd->OS_Cookie);
+		RTMP_MSI_ENABLE(pAd);
+		retval =
+		    request_irq(_pObj->pci_dev->irq, rt2860_interrupt, SA_SHIRQ,
+				(net_dev)->name, (net_dev));
+		if (retval != 0)
+			printk("RT2860: request_irq  ERROR(%d)\n", retval);
+	}
+
+	return retval;
+#else
+	return 0;
+#endif
+}
+
+int RtmpOSIRQRelease(struct net_device *pNetDev)
+{
+	struct net_device *net_dev = pNetDev;
+	struct rt_rtmp_adapter *pAd = NULL;
+
+	GET_PAD_FROM_NET_DEV(pAd, net_dev);
+
+	ASSERT(pAd);
+
+#ifdef RTMP_PCI_SUPPORT
+	if (pAd->infType == RTMP_DEV_INF_PCI) {
+		struct os_cookie *pObj = (struct os_cookie *)(pAd->OS_Cookie);
+		synchronize_irq(pObj->pci_dev->irq);
+		free_irq(pObj->pci_dev->irq, (net_dev));
+		RTMP_MSI_DISABLE(pAd);
+	}
+#endif /* RTMP_PCI_SUPPORT // */
+
+	return 0;
+}
+
+/*******************************************************************************
+
+	File open/close related functions.
+
+ *******************************************************************************/
+struct file *RtmpOSFileOpen(char *pPath, int flag, int mode)
+{
+	struct file *filePtr;
+
+	filePtr = filp_open(pPath, flag, 0);
+	if (IS_ERR(filePtr)) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("%s(): Error %ld opening %s\n", __func__,
+			  -PTR_ERR(filePtr), pPath));
+	}
+
+	return (struct file *)filePtr;
+}
+
+int RtmpOSFileClose(struct file *osfd)
+{
+	filp_close(osfd, NULL);
+	return 0;
+}
+
+void RtmpOSFileSeek(struct file *osfd, int offset)
+{
+	osfd->f_pos = offset;
+}
+
+int RtmpOSFileRead(struct file *osfd, char *pDataPtr, int readLen)
+{
+	/* The object must have a read method */
+	if (osfd->f_op && osfd->f_op->read) {
+		return osfd->f_op->read(osfd, pDataPtr, readLen, &osfd->f_pos);
+	} else {
+		DBGPRINT(RT_DEBUG_ERROR, ("no file read method\n"));
+		return -1;
+	}
+}
+
+int RtmpOSFileWrite(struct file *osfd, char *pDataPtr, int writeLen)
+{
+	return osfd->f_op->write(osfd, pDataPtr, (size_t) writeLen,
+				 &osfd->f_pos);
+}
+
+/*******************************************************************************
+
+	Task create/management/kill related functions.
+
+ *******************************************************************************/
+int RtmpOSTaskKill(struct rt_rtmp_os_task *pTask)
+{
+	struct rt_rtmp_adapter *pAd;
+	int ret = NDIS_STATUS_FAILURE;
+
+	pAd = (struct rt_rtmp_adapter *)pTask->priv;
+
+#ifdef KTHREAD_SUPPORT
+	if (pTask->kthread_task) {
+		kthread_stop(pTask->kthread_task);
+		ret = NDIS_STATUS_SUCCESS;
+	}
+#else
+	CHECK_PID_LEGALITY(pTask->taskPID) {
+		printk("Terminate the task(%s) with pid(%d)!\n",
+		       pTask->taskName, GET_PID_NUMBER(pTask->taskPID));
+		mb();
+		pTask->task_killed = 1;
+		mb();
+		ret = KILL_THREAD_PID(pTask->taskPID, SIGTERM, 1);
+		if (ret) {
+			printk(KERN_WARNING
+			       "kill task(%s) with pid(%d) failed(retVal=%d)!\n",
+			       pTask->taskName, GET_PID_NUMBER(pTask->taskPID),
+			       ret);
+		} else {
+			wait_for_completion(&pTask->taskComplete);
+			pTask->taskPID = THREAD_PID_INIT_VALUE;
+			pTask->task_killed = 0;
+			ret = NDIS_STATUS_SUCCESS;
+		}
+	}
+#endif
+
+	return ret;
+
+}
+
+int RtmpOSTaskNotifyToExit(struct rt_rtmp_os_task *pTask)
+{
+
+#ifndef KTHREAD_SUPPORT
+	complete_and_exit(&pTask->taskComplete, 0);
+#endif
+
+	return 0;
+}
+
+void RtmpOSTaskCustomize(struct rt_rtmp_os_task *pTask)
+{
+
+#ifndef KTHREAD_SUPPORT
+
+	daemonize((char *)& pTask->taskName[0] /*"%s",pAd->net_dev->name */ );
 
 	allow_signal(SIGTERM);
 	allow_signal(SIGKILL);
 	current->flags |= PF_NOFREEZE;
 
 	/* signal that we've started the thread */
-	complete(pNotify);
+	complete(&pTask->taskComplete);
+
+#endif
 }
 
-void RTMP_IndicateMediaState(
-	IN	PRTMP_ADAPTER	pAd)
+int RtmpOSTaskAttach(struct rt_rtmp_os_task *pTask,
+			     IN int (*fn) (void *), IN void *arg)
 {
-	if (pAd->CommonCfg.bWirelessEvent)
-	{
-		if (pAd->IndicateMediaState == NdisMediaStateConnected)
-		{
-			RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-		}
-		else
-		{
-			RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+	int status = NDIS_STATUS_SUCCESS;
+
+#ifdef KTHREAD_SUPPORT
+	pTask->task_killed = 0;
+	pTask->kthread_task = NULL;
+	pTask->kthread_task = kthread_run(fn, arg, pTask->taskName);
+	if (IS_ERR(pTask->kthread_task))
+		status = NDIS_STATUS_FAILURE;
+#else
+	pid_number = kernel_thread(fn, arg, RTMP_OS_MGMT_TASK_FLAGS);
+	if (pid_number < 0) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("Attach task(%s) failed!\n", pTask->taskName));
+		status = NDIS_STATUS_FAILURE;
+	} else {
+		pTask->taskPID = GET_PID(pid_number);
+
+		/* Wait for the thread to start */
+		wait_for_completion(&pTask->taskComplete);
+		status = NDIS_STATUS_SUCCESS;
+	}
+#endif
+	return status;
+}
+
+int RtmpOSTaskInit(struct rt_rtmp_os_task *pTask,
+			   char *pTaskName, void * pPriv)
+{
+	int len;
+
+	ASSERT(pTask);
+
+#ifndef KTHREAD_SUPPORT
+	NdisZeroMemory((u8 *)(pTask), sizeof(struct rt_rtmp_os_task));
+#endif
+
+	len = strlen(pTaskName);
+	len =
+	    len >
+	    (RTMP_OS_TASK_NAME_LEN - 1) ? (RTMP_OS_TASK_NAME_LEN - 1) : len;
+	NdisMoveMemory(&pTask->taskName[0], pTaskName, len);
+	pTask->priv = pPriv;
+
+#ifndef KTHREAD_SUPPORT
+	RTMP_SEM_EVENT_INIT_LOCKED(&(pTask->taskSema));
+	pTask->taskPID = THREAD_PID_INIT_VALUE;
+
+	init_completion(&pTask->taskComplete);
+#endif
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+void RTMP_IndicateMediaState(struct rt_rtmp_adapter *pAd)
+{
+	if (pAd->CommonCfg.bWirelessEvent) {
+		if (pAd->IndicateMediaState == NdisMediaStateConnected) {
+			RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG,
+					      pAd->MacTab.Content[BSSID_WCID].
+					      Addr, BSS0, 0);
+		} else {
+			RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG,
+					      pAd->MacTab.Content[BSSID_WCID].
+					      Addr, BSS0, 0);
 		}
 	}
 }
 
+int RtmpOSWrielessEventSend(struct rt_rtmp_adapter *pAd,
+			    u32 eventType,
+			    int flags,
+			    u8 *pSrcMac,
+			    u8 *pData, u32 dataLen)
+{
+	union iwreq_data wrqu;
+
+	memset(&wrqu, 0, sizeof(wrqu));
+
+	if (flags > -1)
+		wrqu.data.flags = flags;
+
+	if (pSrcMac)
+		memcpy(wrqu.ap_addr.sa_data, pSrcMac, MAC_ADDR_LEN);
+
+	if ((pData != NULL) && (dataLen > 0))
+		wrqu.data.length = dataLen;
+
+	wireless_send_event(pAd->net_dev, eventType, &wrqu, (char *)pData);
+	return 0;
+}
+
+int RtmpOSNetDevAddrSet(struct net_device *pNetDev, u8 *pMacAddr)
+{
+	struct net_device *net_dev;
+	struct rt_rtmp_adapter *pAd;
+
+	net_dev = pNetDev;
+	GET_PAD_FROM_NET_DEV(pAd, net_dev);
+
+	/* work-around for the SuSE due to it has it's own interface name management system. */
+	{
+		NdisZeroMemory(pAd->StaCfg.dev_name, 16);
+		NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name,
+			       strlen(net_dev->name));
+	}
+
+	NdisMoveMemory(net_dev->dev_addr, pMacAddr, 6);
+
+	return 0;
+}
+
+/*
+  *	Assign the network dev name for created Ralink WiFi interface.
+  */
+static int RtmpOSNetDevRequestName(struct rt_rtmp_adapter *pAd,
+				   struct net_device *dev,
+				   char *pPrefixStr, int devIdx)
+{
+	struct net_device *existNetDev;
+	char suffixName[IFNAMSIZ];
+	char desiredName[IFNAMSIZ];
+	int ifNameIdx, prefixLen, slotNameLen;
+	int Status;
+
+	prefixLen = strlen(pPrefixStr);
+	ASSERT((prefixLen < IFNAMSIZ));
+
+	for (ifNameIdx = devIdx; ifNameIdx < 32; ifNameIdx++) {
+		memset(suffixName, 0, IFNAMSIZ);
+		memset(desiredName, 0, IFNAMSIZ);
+		strncpy(&desiredName[0], pPrefixStr, prefixLen);
+
+		sprintf(suffixName, "%d", ifNameIdx);
+
+		slotNameLen = strlen(suffixName);
+		ASSERT(((slotNameLen + prefixLen) < IFNAMSIZ));
+		strcat(desiredName, suffixName);
+
+		existNetDev = RtmpOSNetDevGetByName(dev, &desiredName[0]);
+		if (existNetDev == NULL)
+			break;
+		else
+			RtmpOSNetDeviceRefPut(existNetDev);
+	}
+
+	if (ifNameIdx < 32) {
+		strcpy(&dev->name[0], &desiredName[0]);
+		Status = NDIS_STATUS_SUCCESS;
+	} else {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("Cannot request DevName with preifx(%s) and in range(0~32) as suffix from OS!\n",
+			  pPrefixStr));
+		Status = NDIS_STATUS_FAILURE;
+	}
+
+	return Status;
+}
+
+void RtmpOSNetDevClose(struct net_device *pNetDev)
+{
+	dev_close(pNetDev);
+}
+
+void RtmpOSNetDevFree(struct net_device *pNetDev)
+{
+	ASSERT(pNetDev);
+
+	free_netdev(pNetDev);
+}
+
+int RtmpOSNetDevAlloc(struct net_device ** new_dev_p, u32 privDataSize)
+{
+	/* assign it as null first. */
+	*new_dev_p = NULL;
+
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("Allocate a net device with private data size=%d!\n",
+		  privDataSize));
+	*new_dev_p = alloc_etherdev(privDataSize);
+	if (*new_dev_p)
+		return NDIS_STATUS_SUCCESS;
+	else
+		return NDIS_STATUS_FAILURE;
+}
+
+struct net_device *RtmpOSNetDevGetByName(struct net_device *pNetDev, char *pDevName)
+{
+	struct net_device *pTargetNetDev = NULL;
+
+	pTargetNetDev = dev_get_by_name(dev_net(pNetDev), pDevName);
+
+	return pTargetNetDev;
+}
+
+void RtmpOSNetDeviceRefPut(struct net_device *pNetDev)
+{
+	/*
+	   every time dev_get_by_name is called, and it has returned a valid struct
+	   net_device*, dev_put should be called afterwards, because otherwise the
+	   machine hangs when the device is unregistered (since dev->refcnt > 1).
+	 */
+	if (pNetDev)
+		dev_put(pNetDev);
+}
+
+int RtmpOSNetDevDestory(struct rt_rtmp_adapter *pAd, struct net_device *pNetDev)
+{
+
+	/* TODO: Need to fix this */
+	printk("WARNING: This function(%s) not implement yet!\n", __func__);
+	return 0;
+}
+
+void RtmpOSNetDevDetach(struct net_device *pNetDev)
+{
+	unregister_netdev(pNetDev);
+}
+
+int RtmpOSNetDevAttach(struct net_device *pNetDev,
+		       struct rt_rtmp_os_netdev_op_hook *pDevOpHook)
+{
+	int ret, rtnl_locked = FALSE;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("RtmpOSNetDevAttach()--->\n"));
+	/* If we need hook some callback function to the net device structrue, now do it. */
+	if (pDevOpHook) {
+		struct rt_rtmp_adapter *pAd = NULL;
+
+		GET_PAD_FROM_NET_DEV(pAd, pNetDev);
+
+		pNetDev->netdev_ops = pDevOpHook->netdev_ops;
+
+		/* OS specific flags, here we used to indicate if we are virtual interface */
+		pNetDev->priv_flags = pDevOpHook->priv_flags;
+
+		if (pAd->OpMode == OPMODE_STA) {
+			pNetDev->wireless_handlers = &rt28xx_iw_handler_def;
+		}
+
+		/* copy the net device mac address to the net_device structure. */
+		NdisMoveMemory(pNetDev->dev_addr, &pDevOpHook->devAddr[0],
+			       MAC_ADDR_LEN);
+
+		rtnl_locked = pDevOpHook->needProtcted;
+	}
+
+	if (rtnl_locked)
+		ret = register_netdevice(pNetDev);
+	else
+		ret = register_netdev(pNetDev);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<---RtmpOSNetDevAttach(), ret=%d\n", ret));
+	if (ret == 0)
+		return NDIS_STATUS_SUCCESS;
+	else
+		return NDIS_STATUS_FAILURE;
+}
+
+struct net_device *RtmpOSNetDevCreate(struct rt_rtmp_adapter *pAd,
+			    int devType,
+			    int devNum,
+			    int privMemSize, char *pNamePrefix)
+{
+	struct net_device *pNetDev = NULL;
+	int status;
+
+	/* allocate a new network device */
+	status = RtmpOSNetDevAlloc(&pNetDev, 0 /*privMemSize */ );
+	if (status != NDIS_STATUS_SUCCESS) {
+		/* allocation fail, exit */
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("Allocate network device fail (%s)...\n",
+			  pNamePrefix));
+		return NULL;
+	}
+
+	/* find a available interface name, max 32 interfaces */
+	status = RtmpOSNetDevRequestName(pAd, pNetDev, pNamePrefix, devNum);
+	if (status != NDIS_STATUS_SUCCESS) {
+		/* error! no any available ra name can be used! */
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("Assign interface name (%s with suffix 0~32) failed...\n",
+			  pNamePrefix));
+		RtmpOSNetDevFree(pNetDev);
+
+		return NULL;
+	} else {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("The name of the new %s interface is %s...\n",
+			  pNamePrefix, pNetDev->name));
+	}
+
+	return pNetDev;
+}
diff --git a/drivers/staging/rt2860/rt_linux.h b/drivers/staging/rt2860/rt_linux.h
index e8d64c3..f85508d 100644
--- a/drivers/staging/rt2860/rt_linux.h
+++ b/drivers/staging/rt2860/rt_linux.h
@@ -23,27 +23,22 @@
  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  *                                                                       *
  *************************************************************************
- */
 
-/***********************************************************************/
-/*                                                                     */
-/*   Program:    rt_linux.c                                            */
-/*   Created:    4/21/2006 1:17:38 PM                                  */
-/*   Author:     Wu Xi-Kun                                             */
-/*   Comments:   `description`                                         */
-/*                                                                     */
-/*---------------------------------------------------------------------*/
-/*                                                                     */
-/* History:                                                            */
-/*    Revision 1.1 4/21/2006 1:17:38 PM  xsikun                        */
-/*    Initial revision                                                 */
-/*                                                                     */
-/***********************************************************************/
+    Module Name:
+	rt_linux.h
 
-#include "rtmp_type.h"
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+*/
+
+#ifndef __RT_LINUX_H__
+#define __RT_LINUX_H__
+
 #include <linux/module.h>
 #include <linux/kernel.h>
-
 #include <linux/spinlock.h>
 #include <linux/init.h>
 #include <linux/string.h>
@@ -65,64 +60,57 @@
 
 #include <net/iw_handler.h>
 
-// load firmware
+/* load firmware */
 #define __KERNEL_SYSCALLS__
 #include <linux/unistd.h>
 #include <asm/uaccess.h>
+#include <asm/types.h>
+#include <asm/unaligned.h>	/* for get_unaligned() */
 
+#define KTHREAD_SUPPORT 1
+/* RT2870 2.1.0.0 has it disabled */
 
-#define MEM_ALLOC_FLAG      (GFP_ATOMIC) //(GFP_DMA | GFP_ATOMIC)
+#ifdef KTHREAD_SUPPORT
+#include <linux/err.h>
+#include <linux/kthread.h>
+#endif /* KTHREAD_SUPPORT // */
 
-#ifndef IFNAMSIZ
-#define IFNAMSIZ 16
-#endif
+/***********************************************************************************
+ *	Profile related sections
+ ***********************************************************************************/
 
-//#define CONFIG_CKIP_SUPPORT
+#ifdef RTMP_MAC_PCI
+#define STA_DRIVER_VERSION			"2.1.0.0"
+#endif /* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
+#define STA_DRIVER_VERSION			"2.1.0.0"
+/* RT3070 version: 2.1.1.0 */
+#endif /* RTMP_MAC_USB // */
 
+extern const struct iw_handler_def rt28xx_iw_handler_def;
+
+/***********************************************************************************
+ *	Compiler related definitions
+ ***********************************************************************************/
 #undef __inline
 #define __inline	   static inline
+#define IN
+#define OUT
+#define INOUT
 
-typedef int (*HARD_START_XMIT_FUNC)(struct sk_buff *skb, struct net_device *net_dev);
+/***********************************************************************************
+ *	OS Specific definitions and data structures
+ ***********************************************************************************/
+typedef int (*HARD_START_XMIT_FUNC) (struct sk_buff * skb,
+				     struct net_device * net_dev);
 
-// add by kathy
-
-/* order of "if defined()" is important, because for 3070 driver
-   both RT2870 and RT3070 are defined */
-#if defined(RT2860)
- #define STA_PROFILE_PATH			"/etc/Wireless/RT2860STA/RT2860STA.dat"
- #define STA_RTMP_FIRMWARE_FILE_NAME "/etc/Wireless/RT2860STA/RT2860STA.bin"
- #define STA_NIC_DEVICE_NAME			"RT2860STA"
- #define STA_DRIVER_VERSION			"1.8.1.1"
-#elif defined(RT3070)
- #define STA_PROFILE_PATH			"/etc/Wireless/RT3070STA/RT3070STA.dat"
- #define STA_RT2870_IMAGE_FILE_NAME  "/etc/Wireless/RT3070STA/rt2870.bin"
- #define STA_NIC_DEVICE_NAME			"RT3070STA"
- #define STA_DRIVER_VERSION			"2.0.1.0"
-#elif defined(RT2870)
- #define STA_PROFILE_PATH			"/etc/Wireless/RT2870STA/RT2870STA.dat"
- #define STA_RT2870_IMAGE_FILE_NAME  "/etc/Wireless/RT2870STA/rt2870.bin"
- #define STA_NIC_DEVICE_NAME			"RT2870STA"
- #define STA_DRIVER_VERSION			"1.4.0.0"
-#endif
-
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
 #ifndef PCI_DEVICE
 #define PCI_DEVICE(vend,dev) \
 	.vendor = (vend), .device = (dev), \
 	.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
-#endif // PCI_DEVICE //
-#endif
-
-#define RTMP_TIME_AFTER(a,b)		\
-	(typecheck(unsigned long, (unsigned long)a) && \
-	 typecheck(unsigned long, (unsigned long)b) && \
-	 ((long)(b) - (long)(a) < 0))
-
-#define RTMP_TIME_AFTER_EQ(a,b)	\
-	(typecheck(unsigned long, (unsigned long)a) && \
-	 typecheck(unsigned long, (unsigned long)b) && \
-	 ((long)(a) - (long)(b) >= 0))
-#define RTMP_TIME_BEFORE(a,b)	RTMP_TIME_AFTER_EQ(b,a)
+#endif /* PCI_DEVICE // */
+#endif /* RTMP_MAC_PCI // */
 
 #define RT_MOD_INC_USE_COUNT() \
 	if (!try_module_get(THIS_MODULE)) \
@@ -133,268 +121,105 @@
 
 #define RT_MOD_DEC_USE_COUNT() module_put(THIS_MODULE);
 
-#define OS_HZ			HZ
+#define RTMP_INC_REF(_A)		0
+#define RTMP_DEC_REF(_A)		0
+#define RTMP_GET_REF(_A)		0
+
+/* This function will be called when query /proc */
+struct iw_statistics *rt28xx_get_wireless_stats(IN struct net_device *net_dev);
+
+/***********************************************************************************
+ *	Network related constant definitions
+ ***********************************************************************************/
+#ifndef IFNAMSIZ
+#define IFNAMSIZ 16
+#endif
 
 #define ETH_LENGTH_OF_ADDRESS	6
 
-#define IN
-#define OUT
-
-#define NDIS_STATUS                             INT
 #define NDIS_STATUS_SUCCESS                     0x00
 #define NDIS_STATUS_FAILURE                     0x01
 #define NDIS_STATUS_INVALID_DATA				0x02
 #define NDIS_STATUS_RESOURCES                   0x03
 
-#define MIN_NET_DEVICE_FOR_AID			0x00		//0x00~0x3f
-#define MIN_NET_DEVICE_FOR_MBSSID		0x00		//0x00,0x10,0x20,0x30
-#define MIN_NET_DEVICE_FOR_WDS			0x10		//0x40,0x50,0x60,0x70
+#define NDIS_SET_PACKET_STATUS(_p, _status)			do{} while(0)
+#define NdisWriteErrorLogEntry(_a, _b, _c, _d)		do{} while(0)
+
+/* statistics counter */
+#define STATS_INC_RX_PACKETS(_pAd, _dev)
+#define STATS_INC_TX_PACKETS(_pAd, _dev)
+
+#define STATS_INC_RX_BYTESS(_pAd, _dev, len)
+#define STATS_INC_TX_BYTESS(_pAd, _dev, len)
+
+#define STATS_INC_RX_ERRORS(_pAd, _dev)
+#define STATS_INC_TX_ERRORS(_pAd, _dev)
+
+#define STATS_INC_RX_DROPPED(_pAd, _dev)
+#define STATS_INC_TX_DROPPED(_pAd, _dev)
+
+/***********************************************************************************
+ *	Ralink Specific network related constant definitions
+ ***********************************************************************************/
+#define MIN_NET_DEVICE_FOR_AID			0x00	/*0x00~0x3f */
+#define MIN_NET_DEVICE_FOR_MBSSID		0x00	/*0x00,0x10,0x20,0x30 */
+#define MIN_NET_DEVICE_FOR_WDS			0x10	/*0x40,0x50,0x60,0x70 */
 #define MIN_NET_DEVICE_FOR_APCLI		0x20
 #define MIN_NET_DEVICE_FOR_MESH			0x30
 #define MIN_NET_DEVICE_FOR_DLS			0x40
+#define NET_DEVICE_REAL_IDX_MASK		0x0f	/* for each operation mode, we maximum support 15 entities. */
 
 #define NDIS_PACKET_TYPE_DIRECTED		0
 #define NDIS_PACKET_TYPE_MULTICAST		1
 #define NDIS_PACKET_TYPE_BROADCAST		2
 #define NDIS_PACKET_TYPE_ALL_MULTICAST	3
+#define NDIS_PACKET_TYPE_PROMISCUOUS	4
 
-struct os_lock  {
-	spinlock_t		lock;
-	unsigned long  	flags;
+/***********************************************************************************
+ *	OS signaling related constant definitions
+ ***********************************************************************************/
+
+/***********************************************************************************
+ *	OS file operation related data structure definitions
+ ***********************************************************************************/
+struct rt_rtmp_os_fs_info {
+	int fsuid;
+	int fsgid;
+	mm_segment_t fs;
 };
 
+#define IS_FILE_OPEN_ERR(_fd)	IS_ERR((_fd))
 
-struct os_cookie {
-#ifdef RT2860
-	struct pci_dev 			*pci_dev;
-	struct pci_dev 			*parent_pci_dev;
-	dma_addr_t		  		pAd_pa;
-#endif
-#ifdef RT2870
-	struct usb_device		*pUsb_Dev;
-
-	struct pid	*MLMEThr_pid;
-	struct pid	*RTUSBCmdThr_pid;
-	struct pid	*TimerQThr_pid;
-#endif // RT2870 //
-
-	struct tasklet_struct 	rx_done_task;
-	struct tasklet_struct 	mgmt_dma_done_task;
-	struct tasklet_struct 	ac0_dma_done_task;
-	struct tasklet_struct 	ac1_dma_done_task;
-	struct tasklet_struct 	ac2_dma_done_task;
-	struct tasklet_struct 	ac3_dma_done_task;
-	struct tasklet_struct 	hcca_dma_done_task;
-	struct tasklet_struct	tbtt_task;
-#ifdef RT2860
-	struct tasklet_struct	fifo_statistic_full_task;
-#endif
-#ifdef RT2870
-	struct tasklet_struct	null_frame_complete_task;
-	struct tasklet_struct	rts_frame_complete_task;
-	struct tasklet_struct	pspoll_frame_complete_task;
-#endif // RT2870 //
-
-	unsigned long			apd_pid; //802.1x daemon pid
-	INT						ioctl_if_type;
-	INT 					ioctl_if;
+/***********************************************************************************
+ *	OS semaphore related data structure and definitions
+ ***********************************************************************************/
+struct os_lock {
+	spinlock_t lock;
+	unsigned long flags;
 };
 
-#undef  ASSERT
-#define ASSERT(x)
-
-typedef struct os_cookie	* POS_COOKIE;
-typedef struct pci_dev 		* PPCI_DEV;
-typedef struct net_device	* PNET_DEV;
-typedef void				* PNDIS_PACKET;
-typedef char				NDIS_PACKET;
-typedef PNDIS_PACKET		* PPNDIS_PACKET;
-typedef	dma_addr_t			NDIS_PHYSICAL_ADDRESS;
-typedef	dma_addr_t			* PNDIS_PHYSICAL_ADDRESS;
-typedef spinlock_t			NDIS_SPIN_LOCK;
-typedef struct timer_list	NDIS_MINIPORT_TIMER;
-typedef void				* NDIS_HANDLE;
-typedef char 				* PNDIS_BUFFER;
-
-
-
-void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen);
-
-dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, int sd_idx, int direction);
-void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, int direction);
-
-
-////////////////////////////////////////
-// MOVE TO rtmp.h ?
-/////////////////////////////////////////
-#define PKTSRC_NDIS             0x7f
-#define PKTSRC_DRIVER           0x0f
-#define PRINT_MAC(addr)	\
-	addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
-
-
-#define RT2860_PCI_DEVICE_ID		0x0601
-
-#ifdef RT2860
-#define PCI_MAP_SINGLE(_handle, _ptr, _size, _sd_idx, _dir) \
-	linux_pci_map_single(_handle, _ptr, _size, _sd_idx, _dir)
-
-#define PCI_UNMAP_SINGLE(_handle, _ptr, _size, _dir) \
-	linux_pci_unmap_single(_handle, _ptr, _size, _dir)
-
-#define PCI_ALLOC_CONSISTENT(_pci_dev, _size, _ptr) \
-	pci_alloc_consistent(_pci_dev, _size, _ptr)
-
-#define PCI_FREE_CONSISTENT(_pci_dev, _size, _virtual_addr, _physical_addr) \
-	pci_free_consistent(_pci_dev, _size, _virtual_addr, _physical_addr)
-
-#define DEV_ALLOC_SKB(_length) \
-	dev_alloc_skb(_length)
-#endif
-#ifdef RT2870
-#define PCI_MAP_SINGLE(_handle, _ptr, _size, _dir) (ULONG)0
-
-#define PCI_UNMAP_SINGLE(_handle, _ptr, _size, _dir)
-#endif // RT2870 //
-
-
-#define BEACON_FRAME_DMA_CACHE_WBACK(_ptr, _size)	\
-	dma_cache_wback(_ptr, _size)
-
-
-//////////////////////////////////////////
-//
-//////////////////////////////////////////
-
-
-#define NdisMIndicateStatus(_w, _x, _y, _z)
-
-typedef struct timer_list	RTMP_OS_TIMER;
-
-#ifdef RT2870
-/* ----------------- Timer Related MARCO ---------------*/
-// In RT2870, we have a lot of timer functions and will read/write register, it's
-//	not allowed in Linux USB sub-system to do it ( because of sleep issue when submit
-//  to ctrl pipe). So we need a wrapper function to take care it.
-
-typedef VOID (*RT2870_TIMER_HANDLE)(
-	IN  PVOID   SystemSpecific1,
-	IN  PVOID   FunctionContext,
-	IN  PVOID   SystemSpecific2,
-	IN  PVOID   SystemSpecific3);
-#endif // RT2870 //
-
-
-typedef struct  _RALINK_TIMER_STRUCT    {
-    RTMP_OS_TIMER		TimerObj;       // Ndis Timer object
-	BOOLEAN				Valid;			// Set to True when call RTMPInitTimer
-    BOOLEAN             State;          // True if timer cancelled
-    BOOLEAN	      		PeriodicType;	// True if timer is periodic timer
-    BOOLEAN             Repeat;         // True if periodic timer
-    ULONG               TimerValue;     // Timer value in milliseconds
-	ULONG				cookie;			// os specific object
-#ifdef RT2870
-	RT2870_TIMER_HANDLE	handle;
-	void				*pAd;
-#endif // RT2870 //
-}   RALINK_TIMER_STRUCT, *PRALINK_TIMER_STRUCT;
-
-
-#ifdef RT2870
-
-typedef enum _RT2870_KERNEL_THREAD_STATUS_
-{
-	RT2870_THREAD_UNKNOWN = 0,
-	RT2870_THREAD_INITED = 1,
-	RT2870_THREAD_RUNNING = 2,
-	RT2870_THREAD_STOPED = 4,
-}RT2870_KERNEL_THREAD_STATUS;
-
-#define RT2870_THREAD_CAN_DO_INSERT		(RT2870_THREAD_INITED |RT2870_THREAD_RUNNING)
-
-typedef struct _RT2870_TIMER_ENTRY_
-{
-	RALINK_TIMER_STRUCT 			*pRaTimer;
-	struct _RT2870_TIMER_ENTRY_ 	*pNext;
-}RT2870_TIMER_ENTRY;
-
-
-#define TIMER_QUEUE_SIZE_MAX	128
-typedef struct _RT2870_TIMER_QUEUE_
-{
-	unsigned int		status;
-	UCHAR				*pTimerQPoll;
-	RT2870_TIMER_ENTRY	*pQPollFreeList;
-	RT2870_TIMER_ENTRY 	*pQHead;
-	RT2870_TIMER_ENTRY 	*pQTail;
-}RT2870_TIMER_QUEUE;
-#endif // RT2870 //
-
-
-//#define DBG	1
-
-//
-//  MACRO for debugging information
-//
-
-#ifdef DBG
-extern ULONG    RTDebugLevel;
-
-#define DBGPRINT_RAW(Level, Fmt)    \
-{                                   \
-    if (Level <= RTDebugLevel)      \
-    {                               \
-        printk Fmt;               \
-    }                               \
-}
-
-#define DBGPRINT(Level, Fmt)    DBGPRINT_RAW(Level, Fmt)
-
-
-#define DBGPRINT_ERR(Fmt)           \
-{                                   \
-    printk("ERROR!!! ");          \
-    printk Fmt;                  \
-}
-
-#define DBGPRINT_S(Status, Fmt)		\
-{									\
-	printk Fmt;					\
-}
-
-
-#else
-#define DBGPRINT(Level, Fmt)
-#define DBGPRINT_RAW(Level, Fmt)
-#define DBGPRINT_S(Status, Fmt)
-#define DBGPRINT_ERR(Fmt)
-#endif
-
-
-//
-//  spin_lock enhanced for Nested spin lock
-//
+/* */
+/*  spin_lock enhanced for Nested spin lock */
+/* */
 #define NdisAllocateSpinLock(__lock)      \
 {                                       \
     spin_lock_init((spinlock_t *)(__lock));               \
 }
 
 #define NdisFreeSpinLock(lock)          \
-{                                       \
-}
-
+	do{}while(0)
 
 #define RTMP_SEM_LOCK(__lock)					\
 {												\
-	spin_lock_bh((spinlock_t *)(__lock));				\
+	spin_lock_bh((spinlock_t *)(__lock));		\
 }
 
 #define RTMP_SEM_UNLOCK(__lock)					\
 {												\
-	spin_unlock_bh((spinlock_t *)(__lock));				\
+	spin_unlock_bh((spinlock_t *)(__lock));		\
 }
 
-// sample, use semaphore lock to replace IRQ lock, 2007/11/15
+/* sample, use semaphore lock to replace IRQ lock, 2007/11/15 */
 #define RTMP_IRQ_LOCK(__lock, __irqflags)			\
 {													\
 	__irqflags = 0;									\
@@ -404,7 +229,7 @@
 
 #define RTMP_IRQ_UNLOCK(__lock, __irqflag)			\
 {													\
-	pAd->irq_disabled &= 0; \
+	pAd->irq_disabled &= 0;							\
 	spin_unlock_bh((spinlock_t *)(__lock));			\
 }
 
@@ -418,75 +243,8 @@
 	spin_unlock_irqrestore((spinlock_t *)(__lock), ((unsigned long)__irqflag));	\
 }
 
-#ifdef RT2860
-//Patch for ASIC turst read/write bug, needs to remove after metel fix
-#define RTMP_IO_READ32(_A, _R, _pV)								\
-{																\
-    if ((_A)->bPCIclkOff == FALSE)                                  \
-    {                                                               \
-		(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)));		\
-		(*_pV = readl((void *)((_A)->CSRBaseAddress + (_R))));			\
-    }                                                               \
-    else															\
-		*_pV = 0;													\
-}
-#define RTMP_IO_FORCE_READ32(_A, _R, _pV)							\
-{																	\
-	(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)));		\
-	(*_pV = readl((void *)((_A)->CSRBaseAddress + (_R))));			\
-}
-#define RTMP_IO_READ8(_A, _R, _pV)								\
-{																\
-	(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)));			\
-	(*_pV = readb((void *)((_A)->CSRBaseAddress + (_R))));				\
-}
-#define RTMP_IO_WRITE32(_A, _R, _V)												\
-{																				\
-    if ((_A)->bPCIclkOff == FALSE)                                  \
-    {                                                               \
-	UINT	Val;																\
-	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));			\
-	writel(_V, (void *)((_A)->CSRBaseAddress + (_R)));								\
-    }                                                               \
-}
-#define RTMP_IO_WRITE8(_A, _R, _V)												\
-{																				\
-	UINT	Val;																\
-	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));			\
-	writeb((_V), (PUCHAR)((_A)->CSRBaseAddress + (_R)));		\
-}
-#define RTMP_IO_WRITE16(_A, _R, _V)												\
-{																				\
-	UINT	Val;																\
-	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));			\
-	writew((_V), (PUSHORT)((_A)->CSRBaseAddress + (_R)));	\
-}
-#endif /* RT2860 */
-#ifdef RT2870
-//Patch for ASIC turst read/write bug, needs to remove after metel fix
-#define RTMP_IO_READ32(_A, _R, _pV)								\
-	RTUSBReadMACRegister(_A, _R, _pV)
-
-#define RTMP_IO_READ8(_A, _R, _pV)								\
-{																\
-}
-
-#define RTMP_IO_WRITE32(_A, _R, _V)								\
-	RTUSBWriteMACRegister(_A, _R, _V)
-
-
-#define RTMP_IO_WRITE8(_A, _R, _V)								\
-{																\
-	USHORT	_Val = _V;											\
-	RTUSBSingleWrite(_A, _R, _Val);								\
-}
-
-
-#define RTMP_IO_WRITE16(_A, _R, _V)								\
-{																\
-	RTUSBSingleWrite(_A, _R, _V);								\
-}
-#endif // RT2870 //
+#define NdisAcquireSpinLock		RTMP_SEM_LOCK
+#define NdisReleaseSpinLock		RTMP_SEM_UNLOCK
 
 #ifndef wait_event_interruptible_timeout
 #define __wait_event_interruptible_timeout(wq, condition, ret) \
@@ -519,7 +277,73 @@
         __ret; \
 })
 #endif
-#define ONE_TICK 1
+
+#define RTMP_SEM_EVENT_INIT_LOCKED(_pSema)	sema_init((_pSema), 0)
+#define RTMP_SEM_EVENT_INIT(_pSema)			sema_init((_pSema), 1)
+#define RTMP_SEM_EVENT_WAIT(_pSema, _status)	((_status) = down_interruptible((_pSema)))
+#define RTMP_SEM_EVENT_UP(_pSema)			up(_pSema)
+
+#ifdef KTHREAD_SUPPORT
+#define RTMP_WAIT_EVENT_INTERRUPTIBLE(_pAd, _pTask) \
+{ \
+		wait_event_interruptible(_pTask->kthread_q, \
+								 _pTask->kthread_running || kthread_should_stop()); \
+		_pTask->kthread_running = FALSE; \
+		if (kthread_should_stop()) \
+		{ \
+			RTMP_SET_FLAG(_pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); \
+			break; \
+		} \
+}
+#endif
+
+#ifdef KTHREAD_SUPPORT
+#define WAKE_UP(_pTask) \
+	do{ \
+		if ((_pTask)->kthread_task) \
+        { \
+			(_pTask)->kthread_running = TRUE; \
+	        wake_up(&(_pTask)->kthread_q); \
+		} \
+	}while(0)
+#endif
+
+/***********************************************************************************
+ *	OS Memory Access related data structure and definitions
+ ***********************************************************************************/
+#define MEM_ALLOC_FLAG      (GFP_ATOMIC)	/*(GFP_DMA | GFP_ATOMIC) */
+
+#define NdisMoveMemory(Destination, Source, Length) memmove(Destination, Source, Length)
+#define NdisCopyMemory(Destination, Source, Length) memcpy(Destination, Source, Length)
+#define NdisZeroMemory(Destination, Length)         memset(Destination, 0, Length)
+#define NdisFillMemory(Destination, Length, Fill)   memset(Destination, Fill, Length)
+#define NdisCmpMemory(Destination, Source, Length)  memcmp(Destination, Source, Length)
+#define NdisEqualMemory(Source1, Source2, Length)   (!memcmp(Source1, Source2, Length))
+#define RTMPEqualMemory(Source1, Source2, Length)	(!memcmp(Source1, Source2, Length))
+
+#define MlmeAllocateMemory(_pAd, _ppVA)		os_alloc_mem(_pAd, _ppVA, MGMT_DMA_BUFFER_SIZE)
+#define MlmeFreeMemory(_pAd, _pVA)			os_free_mem(_pAd, _pVA)
+
+#define COPY_MAC_ADDR(Addr1, Addr2)             memcpy((Addr1), (Addr2), MAC_ADDR_LEN)
+
+/***********************************************************************************
+ *	OS task related data structure and definitions
+ ***********************************************************************************/
+#define RTMP_OS_MGMT_TASK_FLAGS	CLONE_VM
+
+#define	THREAD_PID_INIT_VALUE	NULL
+#define	GET_PID(_v)	find_get_pid((_v))
+#define	GET_PID_NUMBER(_v)	pid_nr((_v))
+#define CHECK_PID_LEGALITY(_pid)	if (pid_nr((_pid)) > 0)
+#define KILL_THREAD_PID(_A, _B, _C)	kill_pid((_A), (_B), (_C))
+
+/***********************************************************************************
+ * Timer related definitions and data structures.
+ **********************************************************************************/
+#define OS_HZ			HZ
+
+typedef void (*TIMER_FUNCTION) (unsigned long);
+
 #define OS_WAIT(_time) \
 {	int _i; \
 	long _loop = ((_time)/(1000/OS_HZ)) > 0 ? ((_time)/(1000/OS_HZ)) : 1;\
@@ -528,71 +352,292 @@
 	for (_i=0; _i<(_loop); _i++) \
 		wait_event_interruptible_timeout(_wait, 0, ONE_TICK); }
 
+#define RTMP_TIME_AFTER(a,b)		\
+	(typecheck(unsigned long, (unsigned long)a) && \
+	 typecheck(unsigned long, (unsigned long)b) && \
+	 ((long)(b) - (long)(a) < 0))
 
-typedef void (*TIMER_FUNCTION)(unsigned long);
+#define RTMP_TIME_AFTER_EQ(a,b)	\
+	(typecheck(unsigned long, (unsigned long)a) && \
+	 typecheck(unsigned long, (unsigned long)b) && \
+	 ((long)(a) - (long)(b) >= 0))
+#define RTMP_TIME_BEFORE(a,b)	RTMP_TIME_AFTER_EQ(b,a)
 
-#define COPY_MAC_ADDR(Addr1, Addr2)             memcpy((Addr1), (Addr2), MAC_ADDR_LEN)
+#define ONE_TICK 1
 
-#define MlmeAllocateMemory(_pAd, _ppVA) os_alloc_mem(_pAd, _ppVA, MGMT_DMA_BUFFER_SIZE)
-#define MlmeFreeMemory(_pAd, _pVA)     os_free_mem(_pAd, _pVA)
-
-#ifdef RT2860
-#define BUILD_TIMER_FUNCTION(_func)												\
-void linux_##_func(unsigned long data)											\
-{																				\
-	PRALINK_TIMER_STRUCT	pTimer = (PRALINK_TIMER_STRUCT) data;				\
-																				\
-	_func(NULL, (PVOID) pTimer->cookie, NULL, pTimer); 							\
-	if (pTimer->Repeat)															\
-		RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);				\
+static inline void NdisGetSystemUpTime(unsigned long * time)
+{
+	*time = jiffies;
 }
+
+/***********************************************************************************
+ *	OS specific cookie data structure binding to struct rt_rtmp_adapter
+ ***********************************************************************************/
+
+struct os_cookie {
+#ifdef RTMP_MAC_PCI
+	struct pci_dev *pci_dev;
+	struct pci_dev *parent_pci_dev;
+	u16 DeviceID;
+	dma_addr_t pAd_pa;
+#endif				/* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
+	struct usb_device *pUsb_Dev;
+#endif				/* RTMP_MAC_USB // */
+
+	struct tasklet_struct rx_done_task;
+	struct tasklet_struct mgmt_dma_done_task;
+	struct tasklet_struct ac0_dma_done_task;
+	struct tasklet_struct ac1_dma_done_task;
+	struct tasklet_struct ac2_dma_done_task;
+	struct tasklet_struct ac3_dma_done_task;
+	struct tasklet_struct tbtt_task;
+#ifdef RTMP_MAC_PCI
+	struct tasklet_struct fifo_statistic_full_task;
+#endif				/* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
+	struct tasklet_struct null_frame_complete_task;
+	struct tasklet_struct rts_frame_complete_task;
+	struct tasklet_struct pspoll_frame_complete_task;
+#endif				/* RTMP_MAC_USB // */
+
+	unsigned long apd_pid;	/*802.1x daemon pid */
+	int ioctl_if_type;
+	int ioctl_if;
+};
+
+/***********************************************************************************
+ *	OS debugging and printing related definitions and data structure
+ ***********************************************************************************/
+#define PRINT_MAC(addr)	\
+	addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
+
+#ifdef DBG
+extern unsigned long RTDebugLevel;
+
+#define DBGPRINT_RAW(Level, Fmt)    \
+do{                                   \
+    if (Level <= RTDebugLevel)      \
+    {                               \
+        printk Fmt;               \
+    }                               \
+}while(0)
+
+#define DBGPRINT(Level, Fmt)    DBGPRINT_RAW(Level, Fmt)
+
+#define DBGPRINT_ERR(Fmt)           \
+{                                   \
+    printk("ERROR! ");          \
+    printk Fmt;                  \
+}
+
+#define DBGPRINT_S(Status, Fmt)		\
+{									\
+	printk Fmt;					\
+}
+
+#else
+#define DBGPRINT(Level, Fmt)
+#define DBGPRINT_RAW(Level, Fmt)
+#define DBGPRINT_S(Status, Fmt)
+#define DBGPRINT_ERR(Fmt)
 #endif
-#ifdef RT2870
-#define BUILD_TIMER_FUNCTION(_func)													\
-void linux_##_func(unsigned long data)												\
-{																					\
-	PRALINK_TIMER_STRUCT	_pTimer = (PRALINK_TIMER_STRUCT)data;					\
-	RT2870_TIMER_ENTRY		*_pQNode;												\
-	RTMP_ADAPTER			*_pAd;													\
-																				\
-	_pTimer->handle = _func;															\
-	_pAd = (RTMP_ADAPTER *)_pTimer->pAd;												\
-	_pQNode = RT2870_TimerQ_Insert(_pAd, _pTimer); 									\
-	if ((_pQNode == NULL) && (_pAd->TimerQ.status & RT2870_THREAD_CAN_DO_INSERT))	\
-		RTMP_OS_Add_Timer(&_pTimer->TimerObj, HZ);               					\
+
+#define ASSERT(x)
+
+void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen);
+
+/*********************************************************************************************************
+	The following code are not revised, temporary put it here.
+  *********************************************************************************************************/
+
+/***********************************************************************************
+ * Device DMA Access related definitions and data structures.
+ **********************************************************************************/
+#ifdef RTMP_MAC_PCI
+dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size,
+				int sd_idx, int direction);
+void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size,
+			    int direction);
+
+#define PCI_MAP_SINGLE(_handle, _ptr, _size, _sd_idx, _dir) \
+	linux_pci_map_single(_handle, _ptr, _size, _sd_idx, _dir)
+
+#define PCI_UNMAP_SINGLE(_handle, _ptr, _size, _dir) \
+	linux_pci_unmap_single(_handle, _ptr, _size, _dir)
+
+#define PCI_ALLOC_CONSISTENT(_pci_dev, _size, _ptr) \
+	pci_alloc_consistent(_pci_dev, _size, _ptr)
+
+#define PCI_FREE_CONSISTENT(_pci_dev, _size, _virtual_addr, _physical_addr) \
+	pci_free_consistent(_pci_dev, _size, _virtual_addr, _physical_addr)
+
+#define DEV_ALLOC_SKB(_length) \
+	dev_alloc_skb(_length)
+#endif /* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
+#define PCI_MAP_SINGLE(_handle, _ptr, _size, _dir) (unsigned long)0
+
+#define PCI_UNMAP_SINGLE(_handle, _ptr, _size, _dir)
+#endif /* RTMP_MAC_USB // */
+
+/*
+ * unsigned long
+ * RTMP_GetPhysicalAddressLow(
+ *   dma_addr_t  PhysicalAddress);
+ */
+#define RTMP_GetPhysicalAddressLow(PhysicalAddress)		(PhysicalAddress)
+
+/*
+ * unsigned long
+ * RTMP_GetPhysicalAddressHigh(
+ *   dma_addr_t  PhysicalAddress);
+ */
+#define RTMP_GetPhysicalAddressHigh(PhysicalAddress)		(0)
+
+/*
+ * void
+ * RTMP_SetPhysicalAddressLow(
+ *   dma_addr_t  PhysicalAddress,
+ *   unsigned long  Value);
+ */
+#define RTMP_SetPhysicalAddressLow(PhysicalAddress, Value)	\
+			PhysicalAddress = Value;
+
+/*
+ * void
+ * RTMP_SetPhysicalAddressHigh(
+ *   dma_addr_t  PhysicalAddress,
+ *   unsigned long  Value);
+ */
+#define RTMP_SetPhysicalAddressHigh(PhysicalAddress, Value)
+
+#define NdisMIndicateStatus(_w, _x, _y, _z)
+
+/***********************************************************************************
+ * Device Register I/O Access related definitions and data structures.
+ **********************************************************************************/
+#ifdef RTMP_MAC_PCI
+/*Patch for ASIC turst read/write bug, needs to remove after metel fix */
+#define RTMP_IO_READ32(_A, _R, _pV)								\
+{																\
+    if ((_A)->bPCIclkOff == FALSE)                                  \
+    {                                                               \
+		(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)));		\
+		(*_pV = readl((void *)((_A)->CSRBaseAddress + (_R))));			\
+    }                                                               \
+    else															\
+		*_pV = 0;													\
 }
-#endif // RT2870 //
 
+#define RTMP_IO_FORCE_READ32(_A, _R, _pV)							\
+{																	\
+	(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)));		\
+	(*_pV = readl((void *)((_A)->CSRBaseAddress + (_R))));			\
+}
 
-#define DECLARE_TIMER_FUNCTION(_func)			\
-void linux_##_func(unsigned long data)
+#define RTMP_IO_READ8(_A, _R, _pV)								\
+{																\
+	(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)));			\
+	(*_pV = readb((void *)((_A)->CSRBaseAddress + (_R))));				\
+}
+#define RTMP_IO_WRITE32(_A, _R, _V)												\
+{																				\
+    if ((_A)->bPCIclkOff == FALSE)                                  \
+    {                                                               \
+	u32 Val;																\
+	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));			\
+	writel((_V), (void *)((_A)->CSRBaseAddress + (_R)));								\
+    }                                                               \
+}
 
-#define GET_TIMER_FUNCTION(_func)				\
-		linux_##_func
+#define RTMP_IO_FORCE_WRITE32(_A, _R, _V)												\
+{																				\
+	u32 Val;																\
+	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));			\
+	writel(_V, (void *)((_A)->CSRBaseAddress + (_R)));								\
+}
 
-DECLARE_TIMER_FUNCTION(MlmePeriodicExec);
-DECLARE_TIMER_FUNCTION(MlmeRssiReportExec);
-DECLARE_TIMER_FUNCTION(AsicRxAntEvalTimeout);
-DECLARE_TIMER_FUNCTION(APSDPeriodicExec);
-DECLARE_TIMER_FUNCTION(AsicRfTuningExec);
-#ifdef RT2870
-DECLARE_TIMER_FUNCTION(BeaconUpdateExec);
-#endif // RT2870 //
+#if defined(RALINK_2880) || defined(RALINK_3052)
+#define RTMP_IO_WRITE8(_A, _R, _V)            \
+{                    \
+	unsigned long Val;                \
+	u8 _i;                \
+	_i = ((_R) & 0x3);             \
+	Val = readl((void *)((_A)->CSRBaseAddress + ((_R) - _i)));   \
+	Val = Val & (~(0x000000ff << ((_i)*8)));         \
+	Val = Val | ((unsigned long)(_V) << ((_i)*8));         \
+	writel((Val), (void *)((_A)->CSRBaseAddress + ((_R) - _i)));    \
+}
+#else
+#define RTMP_IO_WRITE8(_A, _R, _V)												\
+{																				\
+	u32 Val;																\
+	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));			\
+	writeb((_V), (u8 *)((_A)->CSRBaseAddress + (_R)));		\
+}
+#endif /* #if defined(BRCM_6358) || defined(RALINK_2880) // */
 
-DECLARE_TIMER_FUNCTION(BeaconTimeout);
-DECLARE_TIMER_FUNCTION(ScanTimeout);
-DECLARE_TIMER_FUNCTION(AuthTimeout);
-DECLARE_TIMER_FUNCTION(AssocTimeout);
-DECLARE_TIMER_FUNCTION(ReassocTimeout);
-DECLARE_TIMER_FUNCTION(DisassocTimeout);
-DECLARE_TIMER_FUNCTION(LinkDownExec);
-DECLARE_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
-DECLARE_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
-DECLARE_TIMER_FUNCTION(PsPollWakeExec);
-DECLARE_TIMER_FUNCTION(RadioOnExec);
+#define RTMP_IO_WRITE16(_A, _R, _V)												\
+{																				\
+	u32 Val;																\
+	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));			\
+	writew((_V), (u16 *)((_A)->CSRBaseAddress + (_R)));	\
+}
+#endif /* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
+/*Patch for ASIC turst read/write bug, needs to remove after metel fix */
+#define RTMP_IO_READ32(_A, _R, _pV)								\
+	RTUSBReadMACRegister((_A), (_R), (u32 *)(_pV))
 
-void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time);
+#define RTMP_IO_READ8(_A, _R, _pV)								\
+{																\
+}
 
+#define RTMP_IO_WRITE32(_A, _R, _V)								\
+	RTUSBWriteMACRegister((_A), (_R), (u32)(_V))
+
+#define RTMP_IO_WRITE8(_A, _R, _V)								\
+{																\
+	u16	_Val = _V;											\
+	RTUSBSingleWrite((_A), (_R), (u16)(_Val));								\
+}
+
+#define RTMP_IO_WRITE16(_A, _R, _V)								\
+{																\
+	RTUSBSingleWrite((_A), (_R), (u16)(_V));								\
+}
+#endif /* RTMP_MAC_USB // */
+
+/***********************************************************************************
+ *	Network Related data structure and marco definitions
+ ***********************************************************************************/
+#define PKTSRC_NDIS             0x7f
+#define PKTSRC_DRIVER           0x0f
+
+#define RTMP_OS_NETDEV_SET_PRIV(_pNetDev, _pPriv)	((_pNetDev)->ml_priv = (_pPriv))
+#define RTMP_OS_NETDEV_GET_PRIV(_pNetDev)		((_pNetDev)->ml_priv)
+#define RTMP_OS_NETDEV_GET_DEVNAME(_pNetDev)	((_pNetDev)->name)
+#define RTMP_OS_NETDEV_GET_PHYADDR(_PNETDEV)	((_PNETDEV)->dev_addr)
+
+#define RTMP_OS_NETDEV_START_QUEUE(_pNetDev)	netif_start_queue((_pNetDev))
+#define RTMP_OS_NETDEV_STOP_QUEUE(_pNetDev)	netif_stop_queue((_pNetDev))
+#define RTMP_OS_NETDEV_WAKE_QUEUE(_pNetDev)	netif_wake_queue((_pNetDev))
+#define RTMP_OS_NETDEV_CARRIER_OFF(_pNetDev)	netif_carrier_off((_pNetDev))
+
+#define QUEUE_ENTRY_TO_PACKET(pEntry) \
+	(void *)(pEntry)
+
+#define PACKET_TO_QUEUE_ENTRY(pPacket) \
+	(struct rt_queue_entry *)(pPacket)
+
+#define GET_SG_LIST_FROM_PACKET(_p, _sc)	\
+    rt_get_sg_list_from_packet(_p, _sc)
+
+#define RELEASE_NDIS_PACKET(_pAd, _pPacket, _Status)                    \
+{                                                                       \
+        RTMPFreeNdisPacket(_pAd, _pPacket);                             \
+}
 
 /*
  * packet helper
@@ -600,16 +645,22 @@
  *             os packet to rt packet
  */
 #define RTPKT_TO_OSPKT(_p)		((struct sk_buff *)(_p))
-#define OSPKT_TO_RTPKT(_p)		((PNDIS_PACKET)(_p))
+#define OSPKT_TO_RTPKT(_p)		((void *)(_p))
 
 #define GET_OS_PKT_DATAPTR(_pkt) \
 		(RTPKT_TO_OSPKT(_pkt)->data)
+#define SET_OS_PKT_DATAPTR(_pkt, _dataPtr)	\
+		(RTPKT_TO_OSPKT(_pkt)->data) = (_dataPtr)
 
 #define GET_OS_PKT_LEN(_pkt) \
 		(RTPKT_TO_OSPKT(_pkt)->len)
+#define SET_OS_PKT_LEN(_pkt, _len)	\
+		(RTPKT_TO_OSPKT(_pkt)->len) = (_len)
 
 #define GET_OS_PKT_DATATAIL(_pkt) \
 		(RTPKT_TO_OSPKT(_pkt)->tail)
+#define SET_OS_PKT_DATATAIL(_pkt, _start, _len)	\
+		((RTPKT_TO_OSPKT(_pkt))->tail) = (u8 *)((_start) + (_len))
 
 #define GET_OS_PKT_HEAD(_pkt) \
 		(RTPKT_TO_OSPKT(_pkt)->head)
@@ -619,6 +670,8 @@
 
 #define GET_OS_PKT_NETDEV(_pkt) \
 		(RTPKT_TO_OSPKT(_pkt)->dev)
+#define SET_OS_PKT_NETDEV(_pkt, _pNetDev)	\
+		(RTPKT_TO_OSPKT(_pkt)->dev) = (_pNetDev)
 
 #define GET_OS_PKT_TYPE(_pkt) \
 		(RTPKT_TO_OSPKT(_pkt))
@@ -626,6 +679,7 @@
 #define GET_OS_PKT_NEXT(_pkt) \
 		(RTPKT_TO_OSPKT(_pkt)->next)
 
+#define OS_PKT_CLONED(_pkt)		skb_cloned(RTPKT_TO_OSPKT(_pkt))
 
 #define OS_NTOHS(_Val) \
 		(ntohs(_Val))
@@ -636,55 +690,36 @@
 #define OS_HTONL(_Val) \
 		(htonl(_Val))
 
-/* statistics counter */
-#define STATS_INC_RX_PACKETS(_pAd, _dev)
-#define STATS_INC_TX_PACKETS(_pAd, _dev)
-
-#define STATS_INC_RX_BYTESS(_pAd, _dev, len)
-#define STATS_INC_TX_BYTESS(_pAd, _dev, len)
-
-#define STATS_INC_RX_ERRORS(_pAd, _dev)
-#define STATS_INC_TX_ERRORS(_pAd, _dev)
-
-#define STATS_INC_RX_DROPPED(_pAd, _dev)
-#define STATS_INC_TX_DROPPED(_pAd, _dev)
-
-
 #define CB_OFF  10
 
-
-//   check DDK NDIS_PACKET data structure and find out only MiniportReservedEx[0..7] can be used by our driver without
-//   ambiguity. Fields after pPacket->MiniportReservedEx[8] may be used by other wrapper layer thus crashes the driver
-//
-
-// User Priority
+/* User Priority */
 #define RTMP_SET_PACKET_UP(_p, _prio)			(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0] = _prio)
 #define RTMP_GET_PACKET_UP(_p)					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0])
 
-// Fragment #
+/* Fragment # */
 #define RTMP_SET_PACKET_FRAGMENTS(_p, _num)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1] = _num)
 #define RTMP_GET_PACKET_FRAGMENTS(_p)			(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1])
 
-// 0x0 ~0x7f: TX to AP's own BSS which has the specified AID. if AID>127, set bit 7 in RTMP_SET_PACKET_EMACTAB too.
-//(this value also as MAC(on-chip WCID) table index)
-// 0x80~0xff: TX to a WDS link. b0~6: WDS index
+/* 0x0 ~0x7f: TX to AP's own BSS which has the specified AID. if AID>127, set bit 7 in RTMP_SET_PACKET_EMACTAB too. */
+/*(this value also as MAC(on-chip WCID) table index) */
+/* 0x80~0xff: TX to a WDS link. b0~6: WDS index */
 #define RTMP_SET_PACKET_WCID(_p, _wdsidx)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2] = _wdsidx)
-#define RTMP_GET_PACKET_WCID(_p)          		((UCHAR)(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2]))
+#define RTMP_GET_PACKET_WCID(_p)          		((u8)(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2]))
 
-// 0xff: PKTSRC_NDIS, others: local TX buffer index. This value affects how to a packet
+/* 0xff: PKTSRC_NDIS, others: local TX buffer index. This value affects how to a packet */
 #define RTMP_SET_PACKET_SOURCE(_p, _pktsrc)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3] = _pktsrc)
 #define RTMP_GET_PACKET_SOURCE(_p)       		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3])
 
-// RTS/CTS-to-self protection method
+/* RTS/CTS-to-self protection method */
 #define RTMP_SET_PACKET_RTS(_p, _num)      		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4] = _num)
 #define RTMP_GET_PACKET_RTS(_p)          		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4])
-// see RTMP_S(G)ET_PACKET_EMACTAB
+/* see RTMP_S(G)ET_PACKET_EMACTAB */
 
-// TX rate index
+/* TX rate index */
 #define RTMP_SET_PACKET_TXRATE(_p, _rate)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5] = _rate)
 #define RTMP_GET_PACKET_TXRATE(_p)		  		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5])
 
-// From which Interface
+/* From which Interface */
 #define RTMP_SET_PACKET_IF(_p, _ifdx)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6] = _ifdx)
 #define RTMP_GET_PACKET_IF(_p)		  		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6])
 #define RTMP_SET_PACKET_NET_DEVICE_MBSSID(_p, _bss)		RTMP_SET_PACKET_IF((_p), (_bss))
@@ -697,10 +732,9 @@
 #define RTMP_SET_PACKET_MOREDATA(_p, _morebit)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7] = _morebit)
 #define RTMP_GET_PACKET_MOREDATA(_p)				(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7])
 
-
-//
-//	Sepcific Pakcet Type definition
-//
+/* */
+/*      Sepcific Pakcet Type definition */
+/* */
 #define RTMP_PACKET_SPECIFIC_CB_OFFSET	11
 
 #define RTMP_PACKET_SPECIFIC_DHCP		0x01
@@ -710,10 +744,10 @@
 #define RTMP_PACKET_SPECIFIC_VLAN		0x10
 #define RTMP_PACKET_SPECIFIC_LLCSNAP	0x20
 
-//Specific
+/*Specific */
 #define RTMP_SET_PACKET_SPECIFIC(_p, _flg)	   	(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] = _flg)
 
-//DHCP
+/*DHCP */
 #define RTMP_SET_PACKET_DHCP(_p, _flg)   													\
 			do{																				\
 				if (_flg)																	\
@@ -723,7 +757,7 @@
 			}while(0)
 #define RTMP_GET_PACKET_DHCP(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_DHCP)
 
-//EAPOL
+/*EAPOL */
 #define RTMP_SET_PACKET_EAPOL(_p, _flg)   													\
 			do{																				\
 				if (_flg)																	\
@@ -733,7 +767,7 @@
 			}while(0)
 #define RTMP_GET_PACKET_EAPOL(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_EAPOL)
 
-//WAI
+/*WAI */
 #define RTMP_SET_PACKET_WAI(_p, _flg)   													\
 			do{																				\
 				if (_flg)																	\
@@ -745,7 +779,7 @@
 
 #define RTMP_GET_PACKET_LOWRATE(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & (RTMP_PACKET_SPECIFIC_EAPOL | RTMP_PACKET_SPECIFIC_DHCP | RTMP_PACKET_SPECIFIC_WAI))
 
-//VLAN
+/*VLAN */
 #define RTMP_SET_PACKET_VLAN(_p, _flg)   													\
 			do{																				\
 				if (_flg)																	\
@@ -755,7 +789,7 @@
 			}while(0)
 #define RTMP_GET_PACKET_VLAN(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_VLAN)
 
-//LLC/SNAP
+/*LLC/SNAP */
 #define RTMP_SET_PACKET_LLCSNAP(_p, _flg)   													\
 			do{																				\
 				if (_flg)																	\
@@ -766,7 +800,7 @@
 
 #define RTMP_GET_PACKET_LLCSNAP(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_LLCSNAP)
 
-// IP
+/* IP */
 #define RTMP_SET_PACKET_IPV4(_p, _flg)														\
 			do{																				\
 				if (_flg)																	\
@@ -777,142 +811,35 @@
 
 #define RTMP_GET_PACKET_IPV4(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_IPV4)
 
-
-// If this flag is set, it indicates that this EAPoL frame MUST be clear.
+/* If this flag is set, it indicates that this EAPoL frame MUST be clear. */
 #define RTMP_SET_PACKET_CLEAR_EAP_FRAME(_p, _flg)   (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12] = _flg)
 #define RTMP_GET_PACKET_CLEAR_EAP_FRAME(_p)         (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12])
 
+/* use bit3 of cb[CB_OFF+16] */
+
 #define RTMP_SET_PACKET_5VT(_p, _flg)   (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22] = _flg)
 #define RTMP_GET_PACKET_5VT(_p)         (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22])
 
-#ifdef CONFIG_5VT_ENHANCE
-#define BRIDGE_TAG 0x35564252    // depends on 5VT define in br_input.c
-#endif
+/* Max skb->cb = 48B = [CB_OFF+38] */
 
-
-#define NDIS_SET_PACKET_STATUS(_p, _status)
-
-
-#define GET_SG_LIST_FROM_PACKET(_p, _sc)	\
-    rt_get_sg_list_from_packet(_p, _sc)
-
-#define NdisMoveMemory(Destination, Source, Length) memmove(Destination, Source, Length)
-#define NdisZeroMemory(Destination, Length)         memset(Destination, 0, Length)
-#define NdisFillMemory(Destination, Length, Fill)   memset(Destination, Fill, Length)
-#define NdisEqualMemory(Source1, Source2, Length)   (!memcmp(Source1, Source2, Length))
-#define RTMPEqualMemory(Source1, Source2, Length)	(!memcmp(Source1, Source2, Length))
-
-
-#define RTMP_INC_REF(_A)		0
-#define RTMP_DEC_REF(_A)		0
-#define RTMP_GET_REF(_A)		0
-
-
-
-/*
- * ULONG
- * RTMP_GetPhysicalAddressLow(
- *   IN NDIS_PHYSICAL_ADDRESS  PhysicalAddress);
- */
-#define RTMP_GetPhysicalAddressLow(PhysicalAddress)		(PhysicalAddress)
-
-/*
- * ULONG
- * RTMP_GetPhysicalAddressHigh(
- *   IN NDIS_PHYSICAL_ADDRESS  PhysicalAddress);
- */
-#define RTMP_GetPhysicalAddressHigh(PhysicalAddress)		(0)
-
-/*
- * VOID
- * RTMP_SetPhysicalAddressLow(
- *   IN NDIS_PHYSICAL_ADDRESS  PhysicalAddress,
- *   IN ULONG  Value);
- */
-#define RTMP_SetPhysicalAddressLow(PhysicalAddress, Value)	\
-			PhysicalAddress = Value;
-
-/*
- * VOID
- * RTMP_SetPhysicalAddressHigh(
- *   IN NDIS_PHYSICAL_ADDRESS  PhysicalAddress,
- *   IN ULONG  Value);
- */
-#define RTMP_SetPhysicalAddressHigh(PhysicalAddress, Value)
-
-
-//CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReservedEx);
-#define QUEUE_ENTRY_TO_PACKET(pEntry) \
-	(PNDIS_PACKET)(pEntry)
-
-#define PACKET_TO_QUEUE_ENTRY(pPacket) \
-	(PQUEUE_ENTRY)(pPacket)
-
-
-#ifndef CONTAINING_RECORD
-#define CONTAINING_RECORD(address, type, field)			\
-((type *)((PCHAR)(address) - offsetof(type, field)))
-#endif
-
-
-#define RELEASE_NDIS_PACKET(_pAd, _pPacket, _Status)                    \
-{                                                                       \
-        RTMPFreeNdisPacket(_pAd, _pPacket);                             \
-}
-
-
-#define SWITCH_PhyAB(_pAA, _pBB)    \
-{                                                                           \
-    ULONG	AABasePaHigh;                           \
-    ULONG	AABasePaLow;                           \
-    ULONG	BBBasePaHigh;                           \
-    ULONG	BBBasePaLow;                           \
-    BBBasePaHigh = RTMP_GetPhysicalAddressHigh(_pBB);                                                 \
-    BBBasePaLow = RTMP_GetPhysicalAddressLow(_pBB);                                                 \
-    AABasePaHigh = RTMP_GetPhysicalAddressHigh(_pAA);                                                 \
-    AABasePaLow = RTMP_GetPhysicalAddressLow(_pAA);                                                 \
-    RTMP_SetPhysicalAddressHigh(_pAA, BBBasePaHigh);                                                 \
-    RTMP_SetPhysicalAddressLow(_pAA, BBBasePaLow);                                                 \
-    RTMP_SetPhysicalAddressHigh(_pBB, AABasePaHigh);                                                 \
-    RTMP_SetPhysicalAddressLow(_pBB, AABasePaLow);                                                 \
-}
-
-
-#define NdisWriteErrorLogEntry(_a, _b, _c, _d)
-#define NdisMAllocateMapRegisters(_a, _b, _c, _d, _e)		NDIS_STATUS_SUCCESS
-
-
-#define NdisAcquireSpinLock		RTMP_SEM_LOCK
-#define NdisReleaseSpinLock		RTMP_SEM_UNLOCK
-
-static inline void NdisGetSystemUpTime(ULONG *time)
-{
-	*time = jiffies;
-}
-
-//pPacket = CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReservedEx);
-#define QUEUE_ENTRY_TO_PKT(pEntry) \
-		((PNDIS_PACKET) (pEntry))
-
+/***********************************************************************************
+ *	Other function prototypes definitions
+ ***********************************************************************************/
+void RTMP_GetCurrentSystemTime(LARGE_INTEGER * time);
 int rt28xx_packet_xmit(struct sk_buff *skb);
 
+#ifdef RTMP_MAC_PCI
+/* function declarations */
+#define IRQ_HANDLE_TYPE  irqreturn_t
 
+IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance);
+#endif /* RTMP_MAC_PCI // */
 
-void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify);
+int rt28xx_sta_ioctl(struct net_device *net_dev, IN OUT struct ifreq *rq, int cmd);
 
-#ifdef RT2860
-#if !defined(PCI_CAP_ID_EXP)
-#define PCI_CAP_ID_EXP			    0x10
-#endif
+extern int ra_mtd_write(int num, loff_t to, size_t len, const u_char * buf);
+extern int ra_mtd_read(int num, loff_t from, size_t len, u_char * buf);
 
-#if !defined(PCI_EXP_LNKCTL)
-#define PCI_EXP_LNKCTL			    0x10
-#endif
+#define GET_PAD_FROM_NET_DEV(_pAd, _net_dev)	(_pAd) = (struct rt_rtmp_adapter *)(_net_dev)->ml_priv;
 
-#if !defined(PCI_CLASS_BRIDGE_PCI)
-#define PCI_CLASS_BRIDGE_PCI		0x0604
-#endif
-
-#define PCIBUS_INTEL_VENDOR         0x8086
-#endif
-
+#endif /* __RT_LINUX_H__ // */
diff --git a/drivers/staging/rt2860/rt_main_dev.c b/drivers/staging/rt2860/rt_main_dev.c
index 22f37cf..c3d92802 100644
--- a/drivers/staging/rt2860/rt_main_dev.c
+++ b/drivers/staging/rt2860/rt_main_dev.c
@@ -33,53 +33,33 @@
     Revision History:
     Who         When            What
     --------    ----------      ----------------------------------------------
-	Sample		Mar/21/07		Merge RT2870 and RT2860 drivers.
 */
 
 #include "rt_config.h"
 
-#define FORTY_MHZ_INTOLERANT_INTERVAL	(60*1000) // 1 min
-
 /*---------------------------------------------------------------------*/
 /* Private Variables Used                                              */
 /*---------------------------------------------------------------------*/
-//static RALINK_TIMER_STRUCT     PeriodicTimer;
 
-char *mac = "";		   // default 00:00:00:00:00:00
-char *hostname = "";		   // default CMPC
-module_param (mac, charp, 0);
-MODULE_PARM_DESC (mac, "rt28xx: wireless mac addr");
-
+char *mac = "";		/* default 00:00:00:00:00:00 */
+char *hostname = "";		/* default CMPC */
+module_param(mac, charp, 0);
+MODULE_PARM_DESC(mac, "rt28xx: wireless mac addr");
 
 /*---------------------------------------------------------------------*/
 /* Prototypes of Functions Used                                        */
 /*---------------------------------------------------------------------*/
-extern BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num);
-extern void ba_reordering_resource_release(PRTMP_ADAPTER pAd);
-extern NDIS_STATUS NICLoadRateSwitchingParams(IN PRTMP_ADAPTER pAd);
 
-#ifdef RT2860
-extern void init_thread_task(PRTMP_ADAPTER pAd);
-#endif
+/* public function prototype */
+int rt28xx_close(IN struct net_device *net_dev);
+int rt28xx_open(struct net_device *net_dev);
 
-// public function prototype
-INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
-							IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
+/* private function prototype */
+static int rt28xx_send_packets(IN struct sk_buff *skb_p,
+			       IN struct net_device *net_dev);
 
-// private function prototype
-static int rt28xx_init(IN struct net_device *net_dev);
-INT rt28xx_send_packets(IN struct sk_buff *skb_p, IN struct net_device *net_dev);
-
-static void CfgInitHook(PRTMP_ADAPTER pAd);
-
-extern	const struct iw_handler_def rt28xx_iw_handler_def;
-
-// This function will be called when query /proc
-struct iw_statistics *rt28xx_get_wireless_stats(
-    IN struct net_device *net_dev);
-
-struct net_device_stats *RT28xx_get_ether_stats(
-    IN  struct net_device *net_dev);
+static struct net_device_stats *RT28xx_get_ether_stats(IN struct net_device
+						       *net_dev);
 
 /*
 ========================================================================
@@ -103,21 +83,66 @@
 */
 int MainVirtualIF_close(IN struct net_device *net_dev)
 {
-    RTMP_ADAPTER *pAd = net_dev->ml_priv;
+	struct rt_rtmp_adapter *pAd = NULL;
 
-	// Sanity check for pAd
+	GET_PAD_FROM_NET_DEV(pAd, net_dev);
+
+	/* Sanity check for pAd */
 	if (pAd == NULL)
-		return 0; // close ok
+		return 0;	/* close ok */
 
 	netif_carrier_off(pAd->net_dev);
 	netif_stop_queue(pAd->net_dev);
 
+	{
+		BOOLEAN Cancelled;
+
+		if (INFRA_ON(pAd) &&
+		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) {
+			struct rt_mlme_disassoc_req DisReq;
+			struct rt_mlme_queue_elem *MsgElem =
+			    (struct rt_mlme_queue_elem *)kmalloc(sizeof(struct rt_mlme_queue_elem),
+							MEM_ALLOC_FLAG);
+
+			if (MsgElem) {
+				COPY_MAC_ADDR(DisReq.Addr,
+					      pAd->CommonCfg.Bssid);
+				DisReq.Reason = REASON_DEAUTH_STA_LEAVING;
+
+				MsgElem->Machine = ASSOC_STATE_MACHINE;
+				MsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
+				MsgElem->MsgLen =
+				    sizeof(struct rt_mlme_disassoc_req);
+				NdisMoveMemory(MsgElem->Msg, &DisReq,
+					       sizeof
+					       (struct rt_mlme_disassoc_req));
+
+				/* Prevent to connect AP again in STAMlmePeriodicExec */
+				pAd->MlmeAux.AutoReconnectSsidLen = 32;
+				NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid,
+					       pAd->MlmeAux.
+					       AutoReconnectSsidLen);
+
+				pAd->Mlme.CntlMachine.CurrState =
+				    CNTL_WAIT_OID_DISASSOC;
+				MlmeDisassocReqAction(pAd, MsgElem);
+				kfree(MsgElem);
+			}
+
+			RTMPusecDelay(1000);
+		}
+
+		RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer,
+				&Cancelled);
+		RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer,
+				&Cancelled);
+	}
 
 	VIRTUAL_IF_DOWN(pAd);
 
 	RT_MOD_DEC_USE_COUNT();
 
-	return 0; // close ok
+	return 0;		/* close ok */
 }
 
 /*
@@ -142,16 +167,18 @@
 */
 int MainVirtualIF_open(IN struct net_device *net_dev)
 {
-    RTMP_ADAPTER *pAd = net_dev->ml_priv;
+	struct rt_rtmp_adapter *pAd = NULL;
 
-	// Sanity check for pAd
+	GET_PAD_FROM_NET_DEV(pAd, net_dev);
+
+	/* Sanity check for pAd */
 	if (pAd == NULL)
-		return 0; // close ok
+		return 0;	/* close ok */
 
 	if (VIRTUAL_IF_UP(pAd) != 0)
 		return -1;
 
-	// increase MODULE use count
+	/* increase MODULE use count */
 	RT_MOD_INC_USE_COUNT();
 
 	netif_start_queue(net_dev);
@@ -181,409 +208,160 @@
 		(3) BA Reordering: 				ba_reordering_resource_release()
 ========================================================================
 */
-int rt28xx_close(IN PNET_DEV dev)
+int rt28xx_close(struct net_device *dev)
 {
-	struct net_device * net_dev = (struct net_device *)dev;
-    RTMP_ADAPTER	*pAd = net_dev->ml_priv;
-	BOOLEAN 		Cancelled = FALSE;
-	UINT32			i = 0;
-#ifdef RT2870
-	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup);
+	struct net_device *net_dev = (struct net_device *)dev;
+	struct rt_rtmp_adapter *pAd = NULL;
+	BOOLEAN Cancelled;
+	u32 i = 0;
+
+#ifdef RTMP_MAC_USB
+	DECLARE_WAIT_QUEUE_HEAD(unlink_wakeup);
 	DECLARE_WAITQUEUE(wait, current);
+#endif /* RTMP_MAC_USB // */
 
-	//RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
-#endif // RT2870 //
+	GET_PAD_FROM_NET_DEV(pAd, net_dev);
 
+	DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n"));
 
-    DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n"));
-
-	// Sanity check for pAd
+	Cancelled = FALSE;
+	/* Sanity check for pAd */
 	if (pAd == NULL)
-		return 0; // close ok
+		return 0;	/* close ok */
 
 	{
-		// If dirver doesn't wake up firmware here,
-		// NICLoadFirmware will hang forever when interface is up again.
-#ifdef RT2860
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
-			RTMP_SET_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) ||
-			RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
-#endif
-#ifdef RT2870
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-#endif
-        {
-#ifdef RT2860
-		    AsicForceWakeup(pAd, RTMP_HALT);
-#endif
-#ifdef RT2870
-		    AsicForceWakeup(pAd, TRUE);
-#endif
-        }
+#ifdef RTMP_MAC_PCI
+		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_CLOSE);
+#endif /* RTMP_MAC_PCI // */
 
-		if (INFRA_ON(pAd) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
-		{
-			MLME_DISASSOC_REQ_STRUCT	DisReq;
-			MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
-
-			COPY_MAC_ADDR(DisReq.Addr, pAd->CommonCfg.Bssid);
-			DisReq.Reason =  REASON_DEAUTH_STA_LEAVING;
-
-			MsgElem->Machine = ASSOC_STATE_MACHINE;
-			MsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
-			MsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
-			NdisMoveMemory(MsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
-
-			// Prevent to connect AP again in STAMlmePeriodicExec
-			pAd->MlmeAux.AutoReconnectSsidLen= 32;
-			NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
-
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
-			MlmeDisassocReqAction(pAd, MsgElem);
-			kfree(MsgElem);
-
-			RTMPusecDelay(1000);
+		/* If dirver doesn't wake up firmware here, */
+		/* NICLoadFirmware will hang forever when interface is up again. */
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
+			AsicForceWakeup(pAd, TRUE);
 		}
-
-#ifdef RT2870
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
-#endif // RT2870 //
-
-#ifdef CCX_SUPPORT
-		RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &Cancelled);
-#endif
-
-		RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, &Cancelled);
-		RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, &Cancelled);
+#ifdef RTMP_MAC_USB
+		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
+#endif /* RTMP_MAC_USB // */
 
 		MlmeRadioOff(pAd);
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
 		pAd->bPCIclkOff = FALSE;
-#endif
+#endif /* RTMP_MAC_PCI // */
 	}
 
 	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
 
-	for (i = 0 ; i < NUM_OF_TX_RING; i++)
-	{
-		while (pAd->DeQueueRunning[i] == TRUE)
-		{
-			printk("Waiting for TxQueue[%d] done..........\n", i);
+	for (i = 0; i < NUM_OF_TX_RING; i++) {
+		while (pAd->DeQueueRunning[i] == TRUE) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("Waiting for TxQueue[%d] done..........\n",
+				  i));
 			RTMPusecDelay(1000);
 		}
 	}
 
-#ifdef RT2870
-	// ensure there are no more active urbs.
-	add_wait_queue (&unlink_wakeup, &wait);
+#ifdef RTMP_MAC_USB
+	/* ensure there are no more active urbs. */
+	add_wait_queue(&unlink_wakeup, &wait);
 	pAd->wait = &unlink_wakeup;
 
-	// maybe wait for deletions to finish.
+	/* maybe wait for deletions to finish. */
 	i = 0;
-	//while((i < 25) && atomic_read(&pAd->PendingRx) > 0)
-	while(i < 25)
-	{
+	/*while((i < 25) && atomic_read(&pAd->PendingRx) > 0) */
+	while (i < 25) {
 		unsigned long IrqFlags;
 
 		RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
-		if (pAd->PendingRx == 0)
-		{
+		if (pAd->PendingRx == 0) {
 			RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
 			break;
 		}
 		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
 
-		msleep(UNLINK_TIMEOUT_MS);	//Time in millisecond
+		msleep(UNLINK_TIMEOUT_MS);	/*Time in millisecond */
 		i++;
 	}
 	pAd->wait = NULL;
-	remove_wait_queue (&unlink_wakeup, &wait);
-#endif // RT2870 //
+	remove_wait_queue(&unlink_wakeup, &wait);
+#endif /* RTMP_MAC_USB // */
 
-#ifdef RT2870
-	// We need clear timerQ related structure before exits of the timer thread.
-	RT2870_TimerQ_Exit(pAd);
-	// Close kernel threads or tasklets
-	RT28xxThreadTerminate(pAd);
-#endif // RT2870 //
-
-	// Stop Mlme state machine
+	/* Stop Mlme state machine */
 	MlmeHalt(pAd);
 
-	// Close kernel threads or tasklets
-	kill_thread_task(pAd);
+	/* Close net tasklets */
+	RtmpNetTaskExit(pAd);
 
-	MacTableReset(pAd);
+	{
+		MacTableReset(pAd);
+	}
 
 	MeasureReqTabExit(pAd);
 	TpcReqTabExit(pAd);
 
-#ifdef RT2860
+	/* Close kernel threads */
+	RtmpMgmtTaskExit(pAd);
+
+#ifdef RTMP_MAC_PCI
+	{
+		BOOLEAN brc;
+		/*      unsigned long                   Value; */
+
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) {
+			RTMP_ASIC_INTERRUPT_DISABLE(pAd);
+		}
+		/* Receive packets to clear DMA index after disable interrupt. */
+		/*RTMPHandleRxDoneInterrupt(pAd); */
+		/* put to radio off to save power when driver unload.  After radiooff, can't write /read register.  So need to finish all */
+		/* register access before Radio off. */
+
+		brc = RT28xxPciAsicRadioOff(pAd, RTMP_HALT, 0);
+
+/*In  solution 3 of 3090F, the bPCIclkOff will be set to TRUE after calling RT28xxPciAsicRadioOff */
+		pAd->bPCIclkOff = FALSE;
+
+		if (brc == FALSE) {
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("%s call RT28xxPciAsicRadioOff fail!\n",
+				  __func__));
+		}
+	}
+
+/*
 	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
 	{
-		NICDisableInterrupt(pAd);
+		RTMP_ASIC_INTERRUPT_DISABLE(pAd);
 	}
 
 	// Disable Rx, register value supposed will remain after reset
 	NICIssueReset(pAd);
+*/
+#endif /* RTMP_MAC_PCI // */
 
-	// Free IRQ
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
-		// Deregister interrupt function
-		RT28XX_IRQ_RELEASE(net_dev)
+	/* Free IRQ */
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
+#ifdef RTMP_MAC_PCI
+		/* Deregister interrupt function */
+		RtmpOSIRQRelease(net_dev);
+#endif /* RTMP_MAC_PCI // */
 		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
 	}
-#endif
-
-	// Free Ring or USB buffers
+	/* Free Ring or USB buffers */
 	RTMPFreeTxRxRingMemory(pAd);
 
 	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
 
-	// Free BA reorder resource
+	/* Free BA reorder resource */
 	ba_reordering_resource_release(pAd);
 
 	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP);
 
-	return 0; // close ok
-} /* End of rt28xx_close */
-
-static int rt28xx_init(IN struct net_device *net_dev)
-{
-#ifdef RT2860
-	PRTMP_ADAPTER 			pAd = (PRTMP_ADAPTER)net_dev->ml_priv;
-#endif
-#ifdef RT2870
-	PRTMP_ADAPTER 			pAd = net_dev->ml_priv;
-#endif
-	UINT					index;
-	UCHAR					TmpPhy;
-	NDIS_STATUS				Status;
-	UINT32 		MacCsr0 = 0;
-
-	// Allocate BA Reordering memory
-	ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM);
-
-	// Make sure MAC gets ready.
-	index = 0;
-	do
+/*+++Modify by woody to solve the bulk fail+++*/
 	{
-		RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
-		pAd->MACVersion = MacCsr0;
-
-		if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF))
-			break;
-
-		RTMPusecDelay(10);
-	} while (index++ < 100);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0  [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
-/*Iverson patch PCIE L1 issue */
-
-	// Disable DMA
-	RT28XXDMADisable(pAd);
-
-	// Load 8051 firmware
-	Status = NICLoadFirmware(pAd);
-	if (Status != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", Status));
-		goto err1;
 	}
 
-	NICLoadRateSwitchingParams(pAd);
-
-	// Disable interrupts here which is as soon as possible
-	// This statement should never be true. We might consider to remove it later
-#ifdef RT2860
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
-	{
-		NICDisableInterrupt(pAd);
-	}
-#endif
-
-	Status = RTMPAllocTxRxRingMemory(pAd);
-	if (Status != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT_ERR(("RTMPAllocDMAMemory failed, Status[=0x%08x]\n", Status));
-		goto err1;
-	}
-
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
-
-	// initialize MLME
-	//
-
-	Status = MlmeInit(pAd);
-	if (Status != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status));
-		goto err2;
-	}
-
-	// Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default
-	//
-	UserCfgInit(pAd);
-
-#ifdef RT2870
-	// We need init timerQ related structure before create the timer thread.
-	RT2870_TimerQ_Init(pAd);
-#endif // RT2870 //
-
-	RT28XX_TASK_THREAD_INIT(pAd, Status);
-	if (Status != NDIS_STATUS_SUCCESS)
-		goto err1;
-
-	CfgInitHook(pAd);
-
-	NdisAllocateSpinLock(&pAd->MacTabLock);
-
-	MeasureReqTabInit(pAd);
-	TpcReqTabInit(pAd);
-
-	//
-	// Init the hardware, we need to init asic before read registry, otherwise mac register will be reset
-	//
-	Status = NICInitializeAdapter(pAd, TRUE);
-	if (Status != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n", Status));
-		if (Status != NDIS_STATUS_SUCCESS)
-		goto err3;
-	}
-
-	// Read parameters from Config File
-	Status = RTMPReadParametersHook(pAd);
-
-	printk("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
-	if (Status != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT_ERR(("NICReadRegParameters failed, Status[=0x%08x]\n",Status));
-		goto err4;
-	}
-
-#ifdef RT2870
-	pAd->CommonCfg.bMultipleIRP = FALSE;
-
-	if (pAd->CommonCfg.bMultipleIRP)
-		pAd->CommonCfg.NumOfBulkInIRP = RX_RING_SIZE;
-	else
-		pAd->CommonCfg.NumOfBulkInIRP = 1;
-#endif // RT2870 //
-
-
-   	//Init Ba Capability parameters.
-	pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
-	pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable;
-	pAd->CommonCfg.DesiredHtPhy.AmsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
-	pAd->CommonCfg.DesiredHtPhy.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
-	// UPdata to HT IE
-	pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
-	pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
-	pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
-
-	printk("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
-
-	// We should read EEPROM for all cases.  rt2860b
-	NICReadEEPROMParameters(pAd, mac);
-
-	printk("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
-
-	NICInitAsicFromEEPROM(pAd); //rt2860b
-
-	// Set PHY to appropriate mode
-	TmpPhy = pAd->CommonCfg.PhyMode;
-	pAd->CommonCfg.PhyMode = 0xff;
-	RTMPSetPhyMode(pAd, TmpPhy);
-	SetCommonHT(pAd);
-
-	// No valid channels.
-	if (pAd->ChannelListNum == 0)
-	{
-		printk("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n");
-		goto err4;
-	}
-
-	printk("MCS Set = %02x %02x %02x %02x %02x\n", pAd->CommonCfg.HtCapability.MCSSet[0],
-           pAd->CommonCfg.HtCapability.MCSSet[1], pAd->CommonCfg.HtCapability.MCSSet[2],
-           pAd->CommonCfg.HtCapability.MCSSet[3], pAd->CommonCfg.HtCapability.MCSSet[4]);
-
-#ifdef RT2870
-    //Init RT30xx RFRegisters after read RFIC type from EEPROM
-	NICInitRT30xxRFRegisters(pAd);
-#endif // RT2870 //
-
-
-		//
-	// Initialize RF register to default value
-	//
-	AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-	AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-
-#ifndef RT2870
-	// 8051 firmware require the signal during booting time.
-	AsicSendCommandToMcu(pAd, 0x72, 0xFF, 0x00, 0x00);
-#endif
-
-	if (pAd && (Status != NDIS_STATUS_SUCCESS))
-	{
-		//
-		// Undo everything if it failed
-		//
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-		{
-			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
-		}
-	}
-	else if (pAd)
-	{
-		// Microsoft HCT require driver send a disconnect event after driver initialization.
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
-		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
-
-		DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n"));
-
-
-#ifdef RT2870
-		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
-		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
-
-		//
-		// Support multiple BulkIn IRP,
-		// the value on pAd->CommonCfg.NumOfBulkInIRP may be large than 1.
-		//
-		for(index=0; index<pAd->CommonCfg.NumOfBulkInIRP; index++)
-		{
-			RTUSBBulkReceive(pAd);
-			DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n" ));
-		}
-#endif // RT2870 //
-	}// end of else
-
-
-	DBGPRINT_S(Status, ("<==== RTMPInitialize, Status=%x\n", Status));
-
-	return TRUE;
-
-
-err4:
-err3:
-	MlmeHalt(pAd);
-err2:
-	RTMPFreeTxRxRingMemory(pAd);
-err1:
-	os_free_mem(pAd, pAd->mpdu_blk_pool.mem); // free BA pool
-	RT28XX_IRQ_RELEASE(net_dev);
-
-	// shall not set ml_priv to NULL here because the ml_priv didn't been free yet.
-	//net_dev->ml_priv = 0;
-
-	printk("!!! %s Initialized fail !!!\n", RT28xx_CHIP_NAME);
-	return FALSE;
-} /* End of rt28xx_init */
-
+	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt28xx_close\n"));
+	return 0;		/* close ok */
+}				/* End of rt28xx_close */
 
 /*
 ========================================================================
@@ -600,234 +378,116 @@
 Note:
 ========================================================================
 */
-int rt28xx_open(IN PNET_DEV dev)
+int rt28xx_open(struct net_device *dev)
 {
-	struct net_device * net_dev = (struct net_device *)dev;
-	PRTMP_ADAPTER pAd = net_dev->ml_priv;
+	struct net_device *net_dev = (struct net_device *)dev;
+	struct rt_rtmp_adapter *pAd = NULL;
 	int retval = 0;
- 	POS_COOKIE pObj;
+	/*struct os_cookie *pObj; */
 
+	GET_PAD_FROM_NET_DEV(pAd, net_dev);
 
-	// Sanity check for pAd
-	if (pAd == NULL)
-	{
+	/* Sanity check for pAd */
+	if (pAd == NULL) {
 		/* if 1st open fail, pAd will be free;
 		   So the net_dev->ml_priv will be NULL in 2rd open */
 		return -1;
 	}
 
-	// Init
- 	pObj = (POS_COOKIE)pAd->OS_Cookie;
+	if (net_dev->priv_flags == INT_MAIN) {
+		if (pAd->OpMode == OPMODE_STA)
+			net_dev->wireless_handlers =
+			    (struct iw_handler_def *)&rt28xx_iw_handler_def;
+	}
+	/* Request interrupt service routine for PCI device */
+	/* register the interrupt routine with the os */
+	RtmpOSIRQRequest(net_dev);
 
-	// reset Adapter flags
-	RTMP_CLEAR_FLAGS(pAd);
+	/* Init IRQ parameters stored in pAd */
+	RTMP_IRQ_INIT(pAd);
 
-	// Request interrupt service routine for PCI device
-	// register the interrupt routine with the os
-	RT28XX_IRQ_REQUEST(net_dev);
-
-
-	// Init BssTab & ChannelInfo tabbles for auto channel select.
-
-
-	// Chip & other init
-	if (rt28xx_init(net_dev) == FALSE)
+	/* Chip & other init */
+	if (rt28xx_init(pAd, mac, hostname) == FALSE)
 		goto err;
 
-	NdisZeroMemory(pAd->StaCfg.dev_name, 16);
-	NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name, strlen(net_dev->name));
+	/* Enable Interrupt */
+	RTMP_IRQ_ENABLE(pAd);
 
-	// Set up the Mac address
-	NdisMoveMemory(net_dev->dev_addr, (void *) pAd->CurrentAddress, 6);
-
-	// Init IRQ parameters
-	RT28XX_IRQ_INIT(pAd);
-
-	// Various AP function init
-
-	// Enable Interrupt
-	RT28XX_IRQ_ENABLE(pAd);
-
-	// Now Enable RxTx
+	/* Now Enable RxTx */
 	RTMPEnableRxTx(pAd);
 	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP);
 
 	{
-	UINT32 reg = 0;
-	RTMP_IO_READ32(pAd, 0x1300, &reg);  // clear garbage interrupts
-	printk("0x1300 = %08x\n", reg);
+		u32 reg = 0;
+		RTMP_IO_READ32(pAd, 0x1300, &reg);	/* clear garbage interrupts */
+		printk("0x1300 = %08x\n", reg);
 	}
 
-#ifdef RT2860
-        RTMPInitPCIeLinkCtrlValue(pAd);
-#endif
+	{
+/*      u32 reg; */
+/*      u8  byte; */
+/*      u16 tmp; */
+
+/*      RTMP_IO_READ32(pAd, XIFS_TIME_CFG, &reg); */
+
+/*      tmp = 0x0805; */
+/*      reg  = (reg & 0xffff0000) | tmp; */
+/*      RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg); */
+
+	}
+#ifdef RTMP_MAC_PCI
+	RTMPInitPCIeLinkCtrlValue(pAd);
+#endif /* RTMP_MAC_PCI // */
+
 	return (retval);
 
 err:
+/*+++Add by shiang, move from rt28xx_init() to here. */
+	RtmpOSIRQRelease(net_dev);
+/*---Add by shiang, move from rt28xx_init() to here. */
 	return (-1);
-} /* End of rt28xx_open */
+}				/* End of rt28xx_open */
 
 static const struct net_device_ops rt2860_netdev_ops = {
-	.ndo_open		= MainVirtualIF_open,
-	.ndo_stop		= MainVirtualIF_close,
-	.ndo_do_ioctl		= rt28xx_sta_ioctl,
-	.ndo_get_stats		= RT28xx_get_ether_stats,
-	.ndo_validate_addr	= NULL,
-	.ndo_set_mac_address	= eth_mac_addr,
-	.ndo_change_mtu		= eth_change_mtu,
-	.ndo_start_xmit		= rt28xx_send_packets,
+	.ndo_open = MainVirtualIF_open,
+	.ndo_stop = MainVirtualIF_close,
+	.ndo_do_ioctl = rt28xx_sta_ioctl,
+	.ndo_get_stats = RT28xx_get_ether_stats,
+	.ndo_validate_addr = NULL,
+	.ndo_set_mac_address = eth_mac_addr,
+	.ndo_change_mtu = eth_change_mtu,
+	.ndo_start_xmit = rt28xx_send_packets,
 };
 
-/* Must not be called for mdev and apdev */
-static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd)
+struct net_device *RtmpPhyNetDevInit(struct rt_rtmp_adapter *pAd,
+			   struct rt_rtmp_os_netdev_op_hook *pNetDevHook)
 {
-	NDIS_STATUS Status;
-	INT     i=0;
-	CHAR    slot_name[IFNAMSIZ];
-	struct net_device   *device;
+	struct net_device *net_dev = NULL;
+/*      int             Status; */
 
-	if (pAd->OpMode == OPMODE_STA)
-	{
-		dev->wireless_handlers = &rt28xx_iw_handler_def;
+	net_dev =
+	    RtmpOSNetDevCreate(pAd, INT_MAIN, 0, sizeof(struct rt_rtmp_adapter *),
+			       INF_MAIN_DEV_NAME);
+	if (net_dev == NULL) {
+		printk
+		    ("RtmpPhyNetDevInit(): creation failed for main physical net device!\n");
+		return NULL;
 	}
 
-	dev->priv_flags = INT_MAIN;
-	dev->netdev_ops = &rt2860_netdev_ops;
-	// find available device name
-	for (i = 0; i < 8; i++)
-	{
-		sprintf(slot_name, "wlan%d", i);
+	NdisZeroMemory((unsigned char *)pNetDevHook,
+		       sizeof(struct rt_rtmp_os_netdev_op_hook));
+	pNetDevHook->netdev_ops = &rt2860_netdev_ops;
+	pNetDevHook->priv_flags = INT_MAIN;
+	pNetDevHook->needProtcted = FALSE;
 
-		device = dev_get_by_name(dev_net(dev), slot_name);
-		if (device != NULL)
-			dev_put(device);
-
-		if (device == NULL)
-			break;
-	}
-
-	if(i == 8)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("No available slot name\n"));
-		Status = NDIS_STATUS_FAILURE;
-	}
-	else
-	{
-		sprintf(dev->name, "wlan%d", i);
-		Status = NDIS_STATUS_SUCCESS;
-	}
-
-	return Status;
-
-}
-
-/*
-========================================================================
-Routine Description:
-    Probe RT28XX chipset.
-
-Arguments:
-    _dev_p				Point to the PCI or USB device
-	_dev_id_p			Point to the PCI or USB device ID
-
-Return Value:
-    0					Probe OK
-	-ENODEV				Probe Fail
-
-Note:
-========================================================================
-*/
-INT __devinit   rt28xx_probe(
-    IN  void *_dev_p,
-    IN  void *_dev_id_p,
-	IN  UINT argc,
-	OUT PRTMP_ADAPTER *ppAd)
-{
-    struct  net_device	*net_dev;
-    PRTMP_ADAPTER       pAd = (PRTMP_ADAPTER) NULL;
-    INT                 status;
-	PVOID				handle;
-#ifdef RT2860
-	struct pci_dev *dev_p = (struct pci_dev *)_dev_p;
-#endif
-#ifdef RT2870
-	struct usb_interface *intf = (struct usb_interface *)_dev_p;
-	struct usb_device *dev_p = interface_to_usbdev(intf);
-
-	dev_p = usb_get_dev(dev_p);
-#endif // RT2870 //
-
-    DBGPRINT(RT_DEBUG_TRACE, ("STA Driver version-%s\n", STA_DRIVER_VERSION));
-
-    net_dev = alloc_etherdev(sizeof(PRTMP_ADAPTER));
-    if (net_dev == NULL)
-    {
-        printk("alloc_netdev failed\n");
-
-        goto err_out;
-    }
+	net_dev->ml_priv = (void *)pAd;
+	pAd->net_dev = net_dev;
 
 	netif_stop_queue(net_dev);
 
-/* for supporting Network Manager */
-/* Set the sysfs physical device reference for the network logical device
- * if set prior to registration will cause a symlink during initialization.
- */
-    SET_NETDEV_DEV(net_dev, &(dev_p->dev));
+	return net_dev;
 
-	// Allocate RTMP_ADAPTER miniport adapter structure
-	handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL);
-	if (handle == NULL)
-		goto err_out_free_netdev;;
-	RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p);
-
-	status = RTMPAllocAdapterBlock(handle, &pAd);
-	if (status != NDIS_STATUS_SUCCESS)
-		goto err_out_free_netdev;
-
-	net_dev->ml_priv = (PVOID)pAd;
-    pAd->net_dev = net_dev; // must be before RT28XXNetDevInit()
-
-	RT28XXNetDevInit(_dev_p, net_dev, pAd);
-
-    pAd->StaCfg.OriDevType = net_dev->type;
-
-	// Post config
-	if (RT28XXProbePostConfig(_dev_p, pAd, 0) == FALSE)
-		goto err_out_unmap;
-
-	pAd->OpMode = OPMODE_STA;
-
-	// sample move
-	if (rt_ieee80211_if_setup(net_dev, pAd) != NDIS_STATUS_SUCCESS)
-		goto err_out_unmap;
-
-    // Register this device
-    status = register_netdev(net_dev);
-    if (status)
-        goto err_out_unmap;
-
-    // Set driver data
-	RT28XX_DRVDATA_SET(_dev_p);
-
-	*ppAd = pAd;
-    return 0; // probe ok
-
-
-	/* --------------------------- ERROR HANDLE --------------------------- */
-err_out_unmap:
-	RTMPFreeAdapter(pAd);
-	RT28XX_UNMAP();
-
-err_out_free_netdev:
-	free_netdev(net_dev);
-
-err_out:
-	RT28XX_PUT_DEVICE(dev_p);
-
-	return -ENODEV; /* probe fail */
-} /* End of rt28xx_probe */
-
+}
 
 /*
 ========================================================================
@@ -849,36 +509,32 @@
 int rt28xx_packet_xmit(struct sk_buff *skb)
 {
 	struct net_device *net_dev = skb->dev;
-	PRTMP_ADAPTER pAd = net_dev->ml_priv;
+	struct rt_rtmp_adapter *pAd = NULL;
 	int status = NETDEV_TX_OK;
-	PNDIS_PACKET pPacket = (PNDIS_PACKET) skb;
+	void *pPacket = (void *)skb;
+
+	GET_PAD_FROM_NET_DEV(pAd, net_dev);
+
+	/* RT2870STA does this in RTMPSendPackets() */
 
 	{
-		// Drop send request since we are in monitor mode
-		if (MONITOR_ON(pAd))
-		{
+		/* Drop send request since we are in monitor mode */
+		if (MONITOR_ON(pAd)) {
 			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
 			goto done;
 		}
 	}
 
-        // EapolStart size is 18
-	if (skb->len < 14)
-	{
-		//printk("bad packet size: %d\n", pkt->len);
+	/* EapolStart size is 18 */
+	if (skb->len < 14) {
+		/*printk("bad packet size: %d\n", pkt->len); */
 		hex_dump("bad packet", skb->data, skb->len);
 		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
 		goto done;
 	}
 
 	RTMP_SET_PACKET_5VT(pPacket, 0);
-#ifdef CONFIG_5VT_ENHANCE
-    if (*(int*)(skb->cb) == BRIDGE_TAG) {
-		RTMP_SET_PACKET_5VT(pPacket, 1);
-    }
-#endif
-
-	STASendPackets((NDIS_HANDLE)pAd, (PPNDIS_PACKET) &pPacket, 1);
+	STASendPackets((void *)pAd, (void **)& pPacket, 1);
 
 	status = NETDEV_TX_OK;
 done:
@@ -886,7 +542,6 @@
 	return status;
 }
 
-
 /*
 ========================================================================
 Routine Description:
@@ -903,72 +558,69 @@
 Note:
 ========================================================================
 */
-INT rt28xx_send_packets(
-	IN struct sk_buff 		*skb_p,
-	IN struct net_device 	*net_dev)
+static int rt28xx_send_packets(IN struct sk_buff *skb_p,
+			       IN struct net_device *net_dev)
 {
-    RTMP_ADAPTER *pAd = net_dev->ml_priv;
-	if (!(net_dev->flags & IFF_UP))
-	{
-		RELEASE_NDIS_PACKET(pAd, (PNDIS_PACKET)skb_p, NDIS_STATUS_FAILURE);
+	struct rt_rtmp_adapter *pAd = NULL;
+
+	GET_PAD_FROM_NET_DEV(pAd, net_dev);
+
+	if (!(net_dev->flags & IFF_UP)) {
+		RELEASE_NDIS_PACKET(pAd, (void *)skb_p,
+				    NDIS_STATUS_FAILURE);
 		return NETDEV_TX_OK;
 	}
 
-	NdisZeroMemory((PUCHAR)&skb_p->cb[CB_OFF], 15);
+	NdisZeroMemory((u8 *)& skb_p->cb[CB_OFF], 15);
 	RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p, MAIN_MBSSID);
 
 	return rt28xx_packet_xmit(skb_p);
+}
 
-} /* End of MBSS_VirtualIF_PacketSend */
-
-
-
-
-void CfgInitHook(PRTMP_ADAPTER pAd)
+/* This function will be called when query /proc */
+struct iw_statistics *rt28xx_get_wireless_stats(IN struct net_device *net_dev)
 {
-	pAd->bBroadComHT = TRUE;
-} /* End of CfgInitHook */
+	struct rt_rtmp_adapter *pAd = NULL;
 
-
-// This function will be called when query /proc
-struct iw_statistics *rt28xx_get_wireless_stats(
-    IN struct net_device *net_dev)
-{
-	PRTMP_ADAPTER pAd = net_dev->ml_priv;
-
+	GET_PAD_FROM_NET_DEV(pAd, net_dev);
 
 	DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n"));
 
-	pAd->iw_stats.status = 0; // Status - device dependent for now
+	pAd->iw_stats.status = 0;	/* Status - device dependent for now */
 
-	// link quality
-	pAd->iw_stats.qual.qual = ((pAd->Mlme.ChannelQuality * 12)/10 + 10);
-	if(pAd->iw_stats.qual.qual > 100)
+	/* link quality */
+	if (pAd->OpMode == OPMODE_STA)
+		pAd->iw_stats.qual.qual =
+		    ((pAd->Mlme.ChannelQuality * 12) / 10 + 10);
+
+	if (pAd->iw_stats.qual.qual > 100)
 		pAd->iw_stats.qual.qual = 100;
 
-	if (pAd->OpMode == OPMODE_STA)
-		pAd->iw_stats.qual.level = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2);
+	if (pAd->OpMode == OPMODE_STA) {
+		pAd->iw_stats.qual.level =
+		    RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0,
+				pAd->StaCfg.RssiSample.LastRssi1,
+				pAd->StaCfg.RssiSample.LastRssi2);
+	}
 
-	pAd->iw_stats.qual.noise = pAd->BbpWriteLatch[66]; // noise level (dBm)
+	pAd->iw_stats.qual.noise = pAd->BbpWriteLatch[66];	/* noise level (dBm) */
 
 	pAd->iw_stats.qual.noise += 256 - 143;
-	pAd->iw_stats.qual.updated = 1;     // Flags to know if updated
+	pAd->iw_stats.qual.updated = 1;	/* Flags to know if updated */
 #ifdef IW_QUAL_DBM
-	pAd->iw_stats.qual.updated |= IW_QUAL_DBM;	// Level + Noise are dBm
-#endif // IW_QUAL_DBM //
+	pAd->iw_stats.qual.updated |= IW_QUAL_DBM;	/* Level + Noise are dBm */
+#endif /* IW_QUAL_DBM // */
 
-	pAd->iw_stats.discard.nwid = 0;     // Rx : Wrong nwid/essid
-	pAd->iw_stats.miss.beacon = 0;      // Missed beacons/superframe
+	pAd->iw_stats.discard.nwid = 0;	/* Rx : Wrong nwid/essid */
+	pAd->iw_stats.miss.beacon = 0;	/* Missed beacons/superframe */
 
 	DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n"));
 	return &pAd->iw_stats;
-} /* End of rt28xx_get_wireless_stats */
-
-
+}
 
 void tbtt_tasklet(unsigned long data)
 {
-#define MAX_TX_IN_TBTT		(16)
+/*#define MAX_TX_IN_TBTT                (16) */
 
 }
 
@@ -988,19 +640,20 @@
 
     ========================================================================
 */
-struct net_device_stats *RT28xx_get_ether_stats(
-    IN  struct net_device *net_dev)
+static struct net_device_stats *RT28xx_get_ether_stats(IN struct net_device
+						       *net_dev)
 {
-    RTMP_ADAPTER *pAd = NULL;
+	struct rt_rtmp_adapter *pAd = NULL;
 
 	if (net_dev)
-		pAd = net_dev->ml_priv;
+		GET_PAD_FROM_NET_DEV(pAd, net_dev);
 
-	if (pAd)
-	{
+	if (pAd) {
 
-		pAd->stats.rx_packets = pAd->WlanCounters.ReceivedFragmentCount.QuadPart;
-		pAd->stats.tx_packets = pAd->WlanCounters.TransmittedFragmentCount.QuadPart;
+		pAd->stats.rx_packets =
+		    pAd->WlanCounters.ReceivedFragmentCount.QuadPart;
+		pAd->stats.tx_packets =
+		    pAd->WlanCounters.TransmittedFragmentCount.QuadPart;
 
 		pAd->stats.rx_bytes = pAd->RalinkCounters.ReceivedByteCount;
 		pAd->stats.tx_bytes = pAd->RalinkCounters.TransmittedByteCount;
@@ -1011,30 +664,73 @@
 		pAd->stats.rx_dropped = 0;
 		pAd->stats.tx_dropped = 0;
 
-	    pAd->stats.multicast = pAd->WlanCounters.MulticastReceivedFrameCount.QuadPart;   // multicast packets received
-	    pAd->stats.collisions = pAd->Counters8023.OneCollision + pAd->Counters8023.MoreCollisions;  // Collision packets
+		pAd->stats.multicast = pAd->WlanCounters.MulticastReceivedFrameCount.QuadPart;	/* multicast packets received */
+		pAd->stats.collisions = pAd->Counters8023.OneCollision + pAd->Counters8023.MoreCollisions;	/* Collision packets */
 
-	    pAd->stats.rx_length_errors = 0;
-	    pAd->stats.rx_over_errors = pAd->Counters8023.RxNoBuffer;                   // receiver ring buff overflow
-	    pAd->stats.rx_crc_errors = 0;//pAd->WlanCounters.FCSErrorCount;     // recved pkt with crc error
-	    pAd->stats.rx_frame_errors = pAd->Counters8023.RcvAlignmentErrors;          // recv'd frame alignment error
-	    pAd->stats.rx_fifo_errors = pAd->Counters8023.RxNoBuffer;                   // recv'r fifo overrun
-	    pAd->stats.rx_missed_errors = 0;                                            // receiver missed packet
+		pAd->stats.rx_length_errors = 0;
+		pAd->stats.rx_over_errors = pAd->Counters8023.RxNoBuffer;	/* receiver ring buff overflow */
+		pAd->stats.rx_crc_errors = 0;	/*pAd->WlanCounters.FCSErrorCount;     // recved pkt with crc error */
+		pAd->stats.rx_frame_errors = pAd->Counters8023.RcvAlignmentErrors;	/* recv'd frame alignment error */
+		pAd->stats.rx_fifo_errors = pAd->Counters8023.RxNoBuffer;	/* recv'r fifo overrun */
+		pAd->stats.rx_missed_errors = 0;	/* receiver missed packet */
 
-	    // detailed tx_errors
-	    pAd->stats.tx_aborted_errors = 0;
-	    pAd->stats.tx_carrier_errors = 0;
-	    pAd->stats.tx_fifo_errors = 0;
-	    pAd->stats.tx_heartbeat_errors = 0;
-	    pAd->stats.tx_window_errors = 0;
+		/* detailed tx_errors */
+		pAd->stats.tx_aborted_errors = 0;
+		pAd->stats.tx_carrier_errors = 0;
+		pAd->stats.tx_fifo_errors = 0;
+		pAd->stats.tx_heartbeat_errors = 0;
+		pAd->stats.tx_window_errors = 0;
 
-	    // for cslip etc
-	    pAd->stats.rx_compressed = 0;
-	    pAd->stats.tx_compressed = 0;
+		/* for cslip etc */
+		pAd->stats.rx_compressed = 0;
+		pAd->stats.tx_compressed = 0;
 
 		return &pAd->stats;
-	}
-	else
-    	return NULL;
+	} else
+		return NULL;
 }
 
+BOOLEAN RtmpPhyNetDevExit(struct rt_rtmp_adapter *pAd, struct net_device *net_dev)
+{
+
+	/* Unregister network device */
+	if (net_dev != NULL) {
+		printk
+		    ("RtmpOSNetDevDetach(): RtmpOSNetDeviceDetach(), dev->name=%s!\n",
+		     net_dev->name);
+		RtmpOSNetDevDetach(net_dev);
+	}
+
+	return TRUE;
+
+}
+
+/*
+========================================================================
+Routine Description:
+    Allocate memory for adapter control block.
+
+Arguments:
+    pAd					Pointer to our adapter
+
+Return Value:
+	NDIS_STATUS_SUCCESS
+	NDIS_STATUS_FAILURE
+	NDIS_STATUS_RESOURCES
+
+Note:
+========================================================================
+*/
+int AdapterBlockAllocateMemory(void *handle, void ** ppAd)
+{
+
+	*ppAd = (void *)vmalloc(sizeof(struct rt_rtmp_adapter));	/*pci_alloc_consistent(pci_dev, sizeof(struct rt_rtmp_adapter), phy_addr); */
+
+	if (*ppAd) {
+		NdisZeroMemory(*ppAd, sizeof(struct rt_rtmp_adapter));
+		((struct rt_rtmp_adapter *)* ppAd)->OS_Cookie = handle;
+		return (NDIS_STATUS_SUCCESS);
+	} else {
+		return (NDIS_STATUS_FAILURE);
+	}
+}
diff --git a/drivers/staging/rt2860/rt_pci_rbus.c b/drivers/staging/rt2860/rt_pci_rbus.c
new file mode 100644
index 0000000..e0a0aee
--- /dev/null
+++ b/drivers/staging/rt2860/rt_pci_rbus.c
@@ -0,0 +1,840 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+    rt_pci_rbus.c
+
+    Abstract:
+    Create and register network interface.
+
+    Revision History:
+    Who         When            What
+    --------    ----------      ----------------------------------------------
+*/
+
+#include "rt_config.h"
+#include <linux/pci.h>
+
+IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance);
+
+static void rx_done_tasklet(unsigned long data);
+static void mgmt_dma_done_tasklet(unsigned long data);
+static void ac0_dma_done_tasklet(unsigned long data);
+static void ac1_dma_done_tasklet(unsigned long data);
+static void ac2_dma_done_tasklet(unsigned long data);
+static void ac3_dma_done_tasklet(unsigned long data);
+static void fifo_statistic_full_tasklet(unsigned long data);
+
+/*---------------------------------------------------------------------*/
+/* Symbol & Macro Definitions                                          */
+/*---------------------------------------------------------------------*/
+#define RT2860_INT_RX_DLY				(1<<0)	/* bit 0 */
+#define RT2860_INT_TX_DLY				(1<<1)	/* bit 1 */
+#define RT2860_INT_RX_DONE				(1<<2)	/* bit 2 */
+#define RT2860_INT_AC0_DMA_DONE			(1<<3)	/* bit 3 */
+#define RT2860_INT_AC1_DMA_DONE			(1<<4)	/* bit 4 */
+#define RT2860_INT_AC2_DMA_DONE			(1<<5)	/* bit 5 */
+#define RT2860_INT_AC3_DMA_DONE			(1<<6)	/* bit 6 */
+#define RT2860_INT_HCCA_DMA_DONE		(1<<7)	/* bit 7 */
+#define RT2860_INT_MGMT_DONE			(1<<8)	/* bit 8 */
+
+#define INT_RX			RT2860_INT_RX_DONE
+
+#define INT_AC0_DLY		(RT2860_INT_AC0_DMA_DONE)	/*| RT2860_INT_TX_DLY) */
+#define INT_AC1_DLY		(RT2860_INT_AC1_DMA_DONE)	/*| RT2860_INT_TX_DLY) */
+#define INT_AC2_DLY		(RT2860_INT_AC2_DMA_DONE)	/*| RT2860_INT_TX_DLY) */
+#define INT_AC3_DLY		(RT2860_INT_AC3_DMA_DONE)	/*| RT2860_INT_TX_DLY) */
+#define INT_HCCA_DLY	(RT2860_INT_HCCA_DMA_DONE)	/*| RT2860_INT_TX_DLY) */
+#define INT_MGMT_DLY	RT2860_INT_MGMT_DONE
+
+/***************************************************************************
+  *
+  *	Interface-depended memory allocation/Free related procedures.
+  *		Mainly for Hardware TxDesc/RxDesc/MgmtDesc, DMA Memory for TxData/RxData, etc.,
+  *
+  **************************************************************************/
+/* Function for TxDesc Memory allocation. */
+void RTMP_AllocateTxDescMemory(struct rt_rtmp_adapter *pAd,
+			       u32 Index,
+			       unsigned long Length,
+			       IN BOOLEAN Cached,
+			       void ** VirtualAddress,
+			       dma_addr_t *PhysicalAddress)
+{
+	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	*VirtualAddress =
+	    (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
+					 PhysicalAddress);
+
+}
+
+/* Function for MgmtDesc Memory allocation. */
+void RTMP_AllocateMgmtDescMemory(struct rt_rtmp_adapter *pAd,
+				 unsigned long Length,
+				 IN BOOLEAN Cached,
+				 void ** VirtualAddress,
+				 dma_addr_t *PhysicalAddress)
+{
+	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	*VirtualAddress =
+	    (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
+					 PhysicalAddress);
+
+}
+
+/* Function for RxDesc Memory allocation. */
+void RTMP_AllocateRxDescMemory(struct rt_rtmp_adapter *pAd,
+			       unsigned long Length,
+			       IN BOOLEAN Cached,
+			       void ** VirtualAddress,
+			       dma_addr_t *PhysicalAddress)
+{
+	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	*VirtualAddress =
+	    (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
+					 PhysicalAddress);
+
+}
+
+/* Function for free allocated Desc Memory. */
+void RTMP_FreeDescMemory(struct rt_rtmp_adapter *pAd,
+			 unsigned long Length,
+			 void *VirtualAddress,
+			 dma_addr_t PhysicalAddress)
+{
+	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	pci_free_consistent(pObj->pci_dev, Length, VirtualAddress,
+			    PhysicalAddress);
+}
+
+/* Function for TxData DMA Memory allocation. */
+void RTMP_AllocateFirstTxBuffer(struct rt_rtmp_adapter *pAd,
+				u32 Index,
+				unsigned long Length,
+				IN BOOLEAN Cached,
+				void ** VirtualAddress,
+				dma_addr_t *PhysicalAddress)
+{
+	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	*VirtualAddress =
+	    (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
+					 PhysicalAddress);
+}
+
+void RTMP_FreeFirstTxBuffer(struct rt_rtmp_adapter *pAd,
+			    unsigned long Length,
+			    IN BOOLEAN Cached,
+			    void *VirtualAddress,
+			    dma_addr_t PhysicalAddress)
+{
+	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	pci_free_consistent(pObj->pci_dev, Length, VirtualAddress,
+			    PhysicalAddress);
+}
+
+/*
+ * FUNCTION: Allocate a common buffer for DMA
+ * ARGUMENTS:
+ *     AdapterHandle:  AdapterHandle
+ *     Length:  Number of bytes to allocate
+ *     Cached:  Whether or not the memory can be cached
+ *     VirtualAddress:  Pointer to memory is returned here
+ *     PhysicalAddress:  Physical address corresponding to virtual address
+ */
+void RTMP_AllocateSharedMemory(struct rt_rtmp_adapter *pAd,
+			       unsigned long Length,
+			       IN BOOLEAN Cached,
+			       void ** VirtualAddress,
+			       dma_addr_t *PhysicalAddress)
+{
+	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	*VirtualAddress =
+	    (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
+					 PhysicalAddress);
+}
+
+/*
+ * FUNCTION: Allocate a packet buffer for DMA
+ * ARGUMENTS:
+ *     AdapterHandle:  AdapterHandle
+ *     Length:  Number of bytes to allocate
+ *     Cached:  Whether or not the memory can be cached
+ *     VirtualAddress:  Pointer to memory is returned here
+ *     PhysicalAddress:  Physical address corresponding to virtual address
+ * Notes:
+ *     Cached is ignored: always cached memory
+ */
+void *RTMP_AllocateRxPacketBuffer(struct rt_rtmp_adapter *pAd,
+					 unsigned long Length,
+					 IN BOOLEAN Cached,
+					 void ** VirtualAddress,
+					 OUT dma_addr_t *
+					 PhysicalAddress)
+{
+	struct sk_buff *pkt;
+
+	pkt = dev_alloc_skb(Length);
+
+	if (pkt == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("can't allocate rx %ld size packet\n", Length));
+	}
+
+	if (pkt) {
+		RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
+		*VirtualAddress = (void *)pkt->data;
+		*PhysicalAddress =
+		    PCI_MAP_SINGLE(pAd, *VirtualAddress, Length, -1,
+				   PCI_DMA_FROMDEVICE);
+	} else {
+		*VirtualAddress = (void *)NULL;
+		*PhysicalAddress = (dma_addr_t)NULL;
+	}
+
+	return (void *)pkt;
+}
+
+void Invalid_Remaining_Packet(struct rt_rtmp_adapter *pAd, unsigned long VirtualAddress)
+{
+	dma_addr_t PhysicalAddress;
+
+	PhysicalAddress =
+	    PCI_MAP_SINGLE(pAd, (void *)(VirtualAddress + 1600),
+			   RX_BUFFER_NORMSIZE - 1600, -1, PCI_DMA_FROMDEVICE);
+}
+
+int RtmpNetTaskInit(struct rt_rtmp_adapter *pAd)
+{
+	struct os_cookie *pObj;
+
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->mgmt_dma_done_task, mgmt_dma_done_tasklet,
+		     (unsigned long)pAd);
+	tasklet_init(&pObj->ac0_dma_done_task, ac0_dma_done_tasklet,
+		     (unsigned long)pAd);
+	tasklet_init(&pObj->ac1_dma_done_task, ac1_dma_done_tasklet,
+		     (unsigned long)pAd);
+	tasklet_init(&pObj->ac2_dma_done_task, ac2_dma_done_tasklet,
+		     (unsigned long)pAd);
+	tasklet_init(&pObj->ac3_dma_done_task, ac3_dma_done_tasklet,
+		     (unsigned long)pAd);
+	tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->fifo_statistic_full_task,
+		     fifo_statistic_full_tasklet, (unsigned long)pAd);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+void RtmpNetTaskExit(struct rt_rtmp_adapter *pAd)
+{
+	struct os_cookie *pObj;
+
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	tasklet_kill(&pObj->rx_done_task);
+	tasklet_kill(&pObj->mgmt_dma_done_task);
+	tasklet_kill(&pObj->ac0_dma_done_task);
+	tasklet_kill(&pObj->ac1_dma_done_task);
+	tasklet_kill(&pObj->ac2_dma_done_task);
+	tasklet_kill(&pObj->ac3_dma_done_task);
+	tasklet_kill(&pObj->tbtt_task);
+	tasklet_kill(&pObj->fifo_statistic_full_task);
+}
+
+int RtmpMgmtTaskInit(struct rt_rtmp_adapter *pAd)
+{
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+/*
+========================================================================
+Routine Description:
+    Close kernel threads.
+
+Arguments:
+	*pAd				the raxx interface data pointer
+
+Return Value:
+    NONE
+
+Note:
+========================================================================
+*/
+void RtmpMgmtTaskExit(struct rt_rtmp_adapter *pAd)
+{
+
+	return;
+}
+
+static inline void rt2860_int_enable(struct rt_rtmp_adapter *pAd, unsigned int mode)
+{
+	u32 regValue;
+
+	pAd->int_disable_mask &= ~(mode);
+	regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask);
+	/*if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) */
+	{
+		RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue);	/* 1:enable */
+	}
+	/*else */
+	/*      DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_DOZE !\n")); */
+
+	if (regValue != 0)
+		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
+}
+
+static inline void rt2860_int_disable(struct rt_rtmp_adapter *pAd, unsigned int mode)
+{
+	u32 regValue;
+
+	pAd->int_disable_mask |= mode;
+	regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask);
+	RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue);	/* 0: disable */
+
+	if (regValue == 0) {
+		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
+	}
+}
+
+/***************************************************************************
+  *
+  *	tasklet related procedures.
+  *
+  **************************************************************************/
+static void mgmt_dma_done_tasklet(unsigned long data)
+{
+	unsigned long flags;
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
+	INT_SOURCE_CSR_STRUC IntSource;
+	struct os_cookie *pObj;
+
+	/* Do nothing if the driver is starting halt state. */
+	/* This might happen when timer already been fired before cancel timer with mlmehalt */
+	if (RTMP_TEST_FLAG
+	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+		return;
+
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+/*      printk("mgmt_dma_done_process\n"); */
+	IntSource.word = 0;
+	IntSource.field.MgmtDmaDone = 1;
+	pAd->int_pending &= ~INT_MGMT_DLY;
+
+	RTMPHandleMgmtRingDmaDoneInterrupt(pAd);
+
+	/* if you use RTMP_SEM_LOCK, sometimes kernel will hang up, no any */
+	/* bug report output */
+	RTMP_INT_LOCK(&pAd->irq_lock, flags);
+	/*
+	 * double check to avoid lose of interrupts
+	 */
+	if (pAd->int_pending & INT_MGMT_DLY) {
+		tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
+		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+		return;
+	}
+
+	/* enable TxDataInt again */
+	rt2860_int_enable(pAd, INT_MGMT_DLY);
+	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+}
+
+static void rx_done_tasklet(unsigned long data)
+{
+	unsigned long flags;
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
+	BOOLEAN bReschedule = 0;
+	struct os_cookie *pObj;
+
+	/* Do nothing if the driver is starting halt state. */
+	/* This might happen when timer already been fired before cancel timer with mlmehalt */
+	if (RTMP_TEST_FLAG
+	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+		return;
+
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	pAd->int_pending &= ~(INT_RX);
+	bReschedule = STARxDoneInterruptHandle(pAd, 0);
+
+	RTMP_INT_LOCK(&pAd->irq_lock, flags);
+	/*
+	 * double check to avoid rotting packet
+	 */
+	if (pAd->int_pending & INT_RX || bReschedule) {
+		tasklet_hi_schedule(&pObj->rx_done_task);
+		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+		return;
+	}
+
+	/* enable Rxint again */
+	rt2860_int_enable(pAd, INT_RX);
+	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+
+}
+
+void fifo_statistic_full_tasklet(unsigned long data)
+{
+	unsigned long flags;
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
+	struct os_cookie *pObj;
+
+	/* Do nothing if the driver is starting halt state. */
+	/* This might happen when timer already been fired before cancel timer with mlmehalt */
+	if (RTMP_TEST_FLAG
+	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+		return;
+
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	pAd->int_pending &= ~(FifoStaFullInt);
+	NICUpdateFifoStaCounters(pAd);
+
+	RTMP_INT_LOCK(&pAd->irq_lock, flags);
+	/*
+	 * double check to avoid rotting packet
+	 */
+	if (pAd->int_pending & FifoStaFullInt) {
+		tasklet_hi_schedule(&pObj->fifo_statistic_full_task);
+		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+		return;
+	}
+
+	/* enable Rxint again */
+
+	rt2860_int_enable(pAd, FifoStaFullInt);
+	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+
+}
+
+static void ac3_dma_done_tasklet(unsigned long data)
+{
+	unsigned long flags;
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
+	INT_SOURCE_CSR_STRUC IntSource;
+	struct os_cookie *pObj;
+	BOOLEAN bReschedule = 0;
+
+	/* Do nothing if the driver is starting halt state. */
+	/* This might happen when timer already been fired before cancel timer with mlmehalt */
+	if (RTMP_TEST_FLAG
+	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+		return;
+
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+/*      printk("ac0_dma_done_process\n"); */
+	IntSource.word = 0;
+	IntSource.field.Ac3DmaDone = 1;
+	pAd->int_pending &= ~INT_AC3_DLY;
+
+	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
+
+	RTMP_INT_LOCK(&pAd->irq_lock, flags);
+	/*
+	 * double check to avoid lose of interrupts
+	 */
+	if ((pAd->int_pending & INT_AC3_DLY) || bReschedule) {
+		tasklet_hi_schedule(&pObj->ac3_dma_done_task);
+		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+		return;
+	}
+
+	/* enable TxDataInt again */
+	rt2860_int_enable(pAd, INT_AC3_DLY);
+	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+}
+
+static void ac2_dma_done_tasklet(unsigned long data)
+{
+	unsigned long flags;
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
+	INT_SOURCE_CSR_STRUC IntSource;
+	struct os_cookie *pObj;
+	BOOLEAN bReschedule = 0;
+
+	/* Do nothing if the driver is starting halt state. */
+	/* This might happen when timer already been fired before cancel timer with mlmehalt */
+	if (RTMP_TEST_FLAG
+	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+		return;
+
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	IntSource.word = 0;
+	IntSource.field.Ac2DmaDone = 1;
+	pAd->int_pending &= ~INT_AC2_DLY;
+
+	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
+
+	RTMP_INT_LOCK(&pAd->irq_lock, flags);
+
+	/*
+	 * double check to avoid lose of interrupts
+	 */
+	if ((pAd->int_pending & INT_AC2_DLY) || bReschedule) {
+		tasklet_hi_schedule(&pObj->ac2_dma_done_task);
+		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+		return;
+	}
+
+	/* enable TxDataInt again */
+	rt2860_int_enable(pAd, INT_AC2_DLY);
+	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+}
+
+static void ac1_dma_done_tasklet(unsigned long data)
+{
+	unsigned long flags;
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
+	INT_SOURCE_CSR_STRUC IntSource;
+	struct os_cookie *pObj;
+	BOOLEAN bReschedule = 0;
+
+	/* Do nothing if the driver is starting halt state. */
+	/* This might happen when timer already been fired before cancel timer with mlmehalt */
+	if (RTMP_TEST_FLAG
+	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+		return;
+
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+/*      printk("ac0_dma_done_process\n"); */
+	IntSource.word = 0;
+	IntSource.field.Ac1DmaDone = 1;
+	pAd->int_pending &= ~INT_AC1_DLY;
+
+	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
+
+	RTMP_INT_LOCK(&pAd->irq_lock, flags);
+	/*
+	 * double check to avoid lose of interrupts
+	 */
+	if ((pAd->int_pending & INT_AC1_DLY) || bReschedule) {
+		tasklet_hi_schedule(&pObj->ac1_dma_done_task);
+		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+		return;
+	}
+
+	/* enable TxDataInt again */
+	rt2860_int_enable(pAd, INT_AC1_DLY);
+	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+}
+
+static void ac0_dma_done_tasklet(unsigned long data)
+{
+	unsigned long flags;
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
+	INT_SOURCE_CSR_STRUC IntSource;
+	struct os_cookie *pObj;
+	BOOLEAN bReschedule = 0;
+
+	/* Do nothing if the driver is starting halt state. */
+	/* This might happen when timer already been fired before cancel timer with mlmehalt */
+	if (RTMP_TEST_FLAG
+	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+		return;
+
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+/*      printk("ac0_dma_done_process\n"); */
+	IntSource.word = 0;
+	IntSource.field.Ac0DmaDone = 1;
+	pAd->int_pending &= ~INT_AC0_DLY;
+
+/*      RTMPHandleMgmtRingDmaDoneInterrupt(pAd); */
+	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
+
+	RTMP_INT_LOCK(&pAd->irq_lock, flags);
+	/*
+	 * double check to avoid lose of interrupts
+	 */
+	if ((pAd->int_pending & INT_AC0_DLY) || bReschedule) {
+		tasklet_hi_schedule(&pObj->ac0_dma_done_task);
+		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+		return;
+	}
+
+	/* enable TxDataInt again */
+	rt2860_int_enable(pAd, INT_AC0_DLY);
+	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+}
+
+/***************************************************************************
+  *
+  *	interrupt handler related procedures.
+  *
+  **************************************************************************/
+int print_int_count;
+
+IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance)
+{
+	struct net_device *net_dev = (struct net_device *)dev_instance;
+	struct rt_rtmp_adapter *pAd = NULL;
+	INT_SOURCE_CSR_STRUC IntSource;
+	struct os_cookie *pObj;
+
+	GET_PAD_FROM_NET_DEV(pAd, net_dev);
+
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	/* Note 03312008: we can not return here before
+	   RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
+	   RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word);
+	   Or kernel will panic after ifconfig ra0 down sometimes */
+
+	/* */
+	/* Inital the Interrupt source. */
+	/* */
+	IntSource.word = 0x00000000L;
+/*      McuIntSource.word = 0x00000000L; */
+
+	/* */
+	/* Get the interrupt sources & saved to local variable */
+	/* */
+	/*RTMP_IO_READ32(pAd, where, &McuIntSource.word); */
+	/*RTMP_IO_WRITE32(pAd, , McuIntSource.word); */
+
+	/* */
+	/* Flag fOP_STATUS_DOZE On, means ASIC put to sleep, elase means ASICK WakeUp */
+	/* And at the same time, clock maybe turned off that say there is no DMA service. */
+	/* when ASIC get to sleep. */
+	/* To prevent system hang on power saving. */
+	/* We need to check it before handle the INT_SOURCE_CSR, ASIC must be wake up. */
+	/* */
+	/* RT2661 => when ASIC is sleeping, MAC register cannot be read and written. */
+	/* RT2860 => when ASIC is sleeping, MAC register can be read and written. */
+/*      if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) */
+	{
+		RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
+		RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word);	/* write 1 to clear */
+	}
+/*      else */
+/*              DBGPRINT(RT_DEBUG_TRACE, (">>>fOP_STATUS_DOZE<<<\n")); */
+
+/*      RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IsrAfterClear); */
+/*      RTMP_IO_READ32(pAd, MCU_INT_SOURCE_CSR, &McuIsrAfterClear); */
+/*      DBGPRINT(RT_DEBUG_INFO, ("====> RTMPHandleInterrupt(ISR=%08x,Mcu ISR=%08x, After clear ISR=%08x, MCU ISR=%08x)\n", */
+/*                      IntSource.word, McuIntSource.word, IsrAfterClear, McuIsrAfterClear)); */
+
+	/* Do nothing if Reset in progress */
+	if (RTMP_TEST_FLAG
+	    (pAd,
+	     (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+	      fRTMP_ADAPTER_HALT_IN_PROGRESS))) {
+		return IRQ_HANDLED;
+	}
+	/* */
+	/* Handle interrupt, walk through all bits */
+	/* Should start from highest priority interrupt */
+	/* The priority can be adjust by altering processing if statement */
+	/* */
+
+#ifdef DBG
+
+#endif
+
+	pAd->bPCIclkOff = FALSE;
+
+	/* If required spinlock, each interrupt service routine has to acquire */
+	/* and release itself. */
+	/* */
+
+	/* Do nothing if NIC doesn't exist */
+	if (IntSource.word == 0xffffffff) {
+		RTMP_SET_FLAG(pAd,
+			      (fRTMP_ADAPTER_NIC_NOT_EXIST |
+			       fRTMP_ADAPTER_HALT_IN_PROGRESS));
+		return IRQ_HANDLED;
+	}
+
+	if (IntSource.word & TxCoherent) {
+		DBGPRINT(RT_DEBUG_ERROR, (">>>TxCoherent<<<\n"));
+		RTMPHandleRxCoherentInterrupt(pAd);
+	}
+
+	if (IntSource.word & RxCoherent) {
+		DBGPRINT(RT_DEBUG_ERROR, (">>>RxCoherent<<<\n"));
+		RTMPHandleRxCoherentInterrupt(pAd);
+	}
+
+	if (IntSource.word & FifoStaFullInt) {
+		if ((pAd->int_disable_mask & FifoStaFullInt) == 0) {
+			/* mask FifoStaFullInt */
+			rt2860_int_disable(pAd, FifoStaFullInt);
+			tasklet_hi_schedule(&pObj->fifo_statistic_full_task);
+		}
+		pAd->int_pending |= FifoStaFullInt;
+	}
+
+	if (IntSource.word & INT_MGMT_DLY) {
+		if ((pAd->int_disable_mask & INT_MGMT_DLY) == 0) {
+			rt2860_int_disable(pAd, INT_MGMT_DLY);
+			tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
+		}
+		pAd->int_pending |= INT_MGMT_DLY;
+	}
+
+	if (IntSource.word & INT_RX) {
+		if ((pAd->int_disable_mask & INT_RX) == 0) {
+
+			/* mask Rxint */
+			rt2860_int_disable(pAd, INT_RX);
+			tasklet_hi_schedule(&pObj->rx_done_task);
+		}
+		pAd->int_pending |= INT_RX;
+	}
+
+	if (IntSource.word & INT_AC3_DLY) {
+
+		if ((pAd->int_disable_mask & INT_AC3_DLY) == 0) {
+			/* mask TxDataInt */
+			rt2860_int_disable(pAd, INT_AC3_DLY);
+			tasklet_hi_schedule(&pObj->ac3_dma_done_task);
+		}
+		pAd->int_pending |= INT_AC3_DLY;
+	}
+
+	if (IntSource.word & INT_AC2_DLY) {
+
+		if ((pAd->int_disable_mask & INT_AC2_DLY) == 0) {
+			/* mask TxDataInt */
+			rt2860_int_disable(pAd, INT_AC2_DLY);
+			tasklet_hi_schedule(&pObj->ac2_dma_done_task);
+		}
+		pAd->int_pending |= INT_AC2_DLY;
+	}
+
+	if (IntSource.word & INT_AC1_DLY) {
+
+		pAd->int_pending |= INT_AC1_DLY;
+
+		if ((pAd->int_disable_mask & INT_AC1_DLY) == 0) {
+			/* mask TxDataInt */
+			rt2860_int_disable(pAd, INT_AC1_DLY);
+			tasklet_hi_schedule(&pObj->ac1_dma_done_task);
+		}
+
+	}
+
+	if (IntSource.word & INT_AC0_DLY) {
+
+/*
+		if (IntSource.word & 0x2) {
+			u32 reg;
+			RTMP_IO_READ32(pAd, DELAY_INT_CFG, &reg);
+			printk("IntSource.word = %08x, DELAY_REG = %08x\n", IntSource.word, reg);
+		}
+*/
+		pAd->int_pending |= INT_AC0_DLY;
+
+		if ((pAd->int_disable_mask & INT_AC0_DLY) == 0) {
+			/* mask TxDataInt */
+			rt2860_int_disable(pAd, INT_AC0_DLY);
+			tasklet_hi_schedule(&pObj->ac0_dma_done_task);
+		}
+
+	}
+
+	if (IntSource.word & PreTBTTInt) {
+		RTMPHandlePreTBTTInterrupt(pAd);
+	}
+
+	if (IntSource.word & TBTTInt) {
+		RTMPHandleTBTTInterrupt(pAd);
+	}
+
+	{
+		if (IntSource.word & AutoWakeupInt)
+			RTMPHandleTwakeupInterrupt(pAd);
+	}
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * invaild or writeback cache
+ * and convert virtual address to physical address
+ */
+dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size,
+				int sd_idx, int direction)
+{
+	struct rt_rtmp_adapter *pAd;
+	struct os_cookie *pObj;
+
+	/*
+	   ------ Porting Information ------
+	   > For Tx Alloc:
+	   mgmt packets => sd_idx = 0
+	   SwIdx: pAd->MgmtRing.TxCpuIdx
+	   pTxD : pAd->MgmtRing.Cell[SwIdx].AllocVa;
+
+	   data packets => sd_idx = 1
+	   TxIdx : pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx
+	   QueIdx: pTxBlk->QueIdx
+	   pTxD  : pAd->TxRing[pTxBlk->QueIdx].Cell[TxIdx].AllocVa;
+
+	   > For Rx Alloc:
+	   sd_idx = -1
+	 */
+
+	pAd = (struct rt_rtmp_adapter *)handle;
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	if (sd_idx == 1) {
+		struct rt_tx_blk *pTxBlk;
+		pTxBlk = (struct rt_tx_blk *)ptr;
+		return pci_map_single(pObj->pci_dev, pTxBlk->pSrcBufData,
+				      pTxBlk->SrcBufLen, direction);
+	} else {
+		return pci_map_single(pObj->pci_dev, ptr, size, direction);
+	}
+
+}
+
+void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size,
+			    int direction)
+{
+	struct rt_rtmp_adapter *pAd;
+	struct os_cookie *pObj;
+
+	pAd = (struct rt_rtmp_adapter *)handle;
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	pci_unmap_single(pObj->pci_dev, dma_addr, size, direction);
+
+}
diff --git a/drivers/staging/rt2860/rt_profile.c b/drivers/staging/rt2860/rt_profile.c
deleted file mode 100644
index 3bc41f8..0000000
--- a/drivers/staging/rt2860/rt_profile.c
+++ /dev/null
@@ -1,1862 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
- */
-
-#include "rt_config.h"
-
-static void HTParametersHook(
-	IN	PRTMP_ADAPTER pAd,
-	IN	CHAR		  *pValueStr,
-	IN	CHAR		  *pInput);
-
-#define ETH_MAC_ADDR_STR_LEN 17  // in format of xx:xx:xx:xx:xx:xx
-
-// We assume the s1 is a sting, s2 is a memory space with 6 bytes. and content of s1 will be changed.
-BOOLEAN rtstrmactohex(char *s1, char *s2)
-{
-	int i = 0;
-	char *ptokS = s1, *ptokE = s1;
-
-	if (strlen(s1) != ETH_MAC_ADDR_STR_LEN)
-		return FALSE;
-
-	while((*ptokS) != '\0')
-	{
-		if((ptokE = strchr(ptokS, ':')) != NULL)
-			*ptokE++ = '\0';
-		if ((strlen(ptokS) != 2) || (!isxdigit(*ptokS)) || (!isxdigit(*(ptokS+1))))
-			break; // fail
-		AtoH(ptokS, &s2[i++], 1);
-		ptokS = ptokE;
-		if (i == 6)
-			break; // parsing finished
-	}
-
-	return ( i == 6 ? TRUE : FALSE);
-
-}
-
-
-// we assume the s1 and s2 both are strings.
-BOOLEAN rtstrcasecmp(char *s1, char *s2)
-{
-	char *p1 = s1, *p2 = s2;
-
-	if (strlen(s1) != strlen(s2))
-		return FALSE;
-
-	while(*p1 != '\0')
-	{
-		if((*p1 != *p2) && ((*p1 ^ *p2) != 0x20))
-			return FALSE;
-		p1++;
-		p2++;
-	}
-
-	return TRUE;
-}
-
-// we assume the s1 (buffer) and s2 (key) both are strings.
-char * rtstrstruncasecmp(char * s1, char * s2)
-{
-	INT l1, l2, i;
-	char temp1, temp2;
-
-	l2 = strlen(s2);
-	if (!l2)
-		return (char *) s1;
-
-	l1 = strlen(s1);
-
-	while (l1 >= l2)
-	{
-		l1--;
-
-		for(i=0; i<l2; i++)
-		{
-			temp1 = *(s1+i);
-			temp2 = *(s2+i);
-
-			if (('a' <= temp1) && (temp1 <= 'z'))
-				temp1 = 'A'+(temp1-'a');
-			if (('a' <= temp2) && (temp2 <= 'z'))
-				temp2 = 'A'+(temp2-'a');
-
-			if (temp1 != temp2)
-				break;
-		}
-
-		if (i == l2)
-			return (char *) s1;
-
-		s1++;
-	}
-
-	return NULL; // not found
-}
-
-//add by kathy
-
- /**
-  * strstr - Find the first substring in a %NUL terminated string
-  * @s1: The string to be searched
-  * @s2: The string to search for
-  */
-char * rtstrstr(const char * s1,const char * s2)
-{
-	INT l1, l2;
-
-	l2 = strlen(s2);
-	if (!l2)
-		return (char *) s1;
-
-	l1 = strlen(s1);
-
-	while (l1 >= l2)
-	{
-		l1--;
-		if (!memcmp(s1,s2,l2))
-			return (char *) s1;
-		s1++;
-	}
-
-	return NULL;
-}
-
-/**
- * rstrtok - Split a string into tokens
- * @s: The string to be searched
- * @ct: The characters to search for
- * * WARNING: strtok is deprecated, use strsep instead. However strsep is not compatible with old architecture.
- */
-char * __rstrtok;
-char * rstrtok(char * s,const char * ct)
-{
-	char *sbegin, *send;
-
-	sbegin  = s ? s : __rstrtok;
-	if (!sbegin)
-	{
-		return NULL;
-	}
-
-	sbegin += strspn(sbegin,ct);
-	if (*sbegin == '\0')
-	{
-		__rstrtok = NULL;
-		return( NULL );
-	}
-
-	send = strpbrk( sbegin, ct);
-	if (send && *send != '\0')
-		*send++ = '\0';
-
-	__rstrtok = send;
-
-	return (sbegin);
-}
-
-/**
- * delimitcnt - return the count of a given delimiter in a given string.
- * @s: The string to be searched.
- * @ct: The delimiter to search for.
- * Notice : We suppose the delimiter is a single-char string(for example : ";").
- */
-INT delimitcnt(char * s,const char * ct)
-{
-	INT count = 0;
-	/* point to the beginning of the line */
-	const char *token = s;
-
-	for ( ;; )
-	{
-		token = strpbrk(token, ct); /* search for delimiters */
-
-        if ( token == NULL )
-		{
-			/* advanced to the terminating null character */
-			break;
-		}
-		/* skip the delimiter */
-	    ++token;
-
-		/*
-		 * Print the found text: use len with %.*s to specify field width.
-		 */
-
-		/* accumulate delimiter count */
-	    ++count;
-	}
-    return count;
-}
-
-/*
-  * converts the Internet host address from the standard numbers-and-dots notation
-  * into binary data.
-  * returns nonzero if the address is valid, zero if not.
-  */
-int rtinet_aton(const char *cp, unsigned int *addr)
-{
-	unsigned int 	val;
-	int         	base, n;
-	char        	c;
-	unsigned int    parts[4];
-	unsigned int    *pp = parts;
-
-	for (;;)
-    {
-         /*
-          * Collect number up to ``.''.
-          * Values are specified as for C:
-          *	0x=hex, 0=octal, other=decimal.
-          */
-         val = 0;
-         base = 10;
-         if (*cp == '0')
-         {
-             if (*++cp == 'x' || *cp == 'X')
-                 base = 16, cp++;
-             else
-                 base = 8;
-         }
-         while ((c = *cp) != '\0')
-         {
-             if (isdigit((unsigned char) c))
-             {
-                 val = (val * base) + (c - '0');
-                 cp++;
-                 continue;
-             }
-             if (base == 16 && isxdigit((unsigned char) c))
-             {
-                 val = (val << 4) +
-                     (c + 10 - (islower((unsigned char) c) ? 'a' : 'A'));
-                 cp++;
-                 continue;
-             }
-             break;
-         }
-         if (*cp == '.')
-         {
-             /*
-              * Internet format: a.b.c.d a.b.c   (with c treated as 16-bits)
-              * a.b     (with b treated as 24 bits)
-              */
-             if (pp >= parts + 3 || val > 0xff)
-                 return 0;
-             *pp++ = val, cp++;
-         }
-         else
-             break;
-     }
-
-     /*
-      * Check for trailing junk.
-      */
-     while (*cp)
-         if (!isspace((unsigned char) *cp++))
-             return 0;
-
-     /*
-      * Concoct the address according to the number of parts specified.
-      */
-     n = pp - parts + 1;
-     switch (n)
-     {
-
-         case 1:         /* a -- 32 bits */
-             break;
-
-         case 2:         /* a.b -- 8.24 bits */
-             if (val > 0xffffff)
-                 return 0;
-             val |= parts[0] << 24;
-             break;
-
-         case 3:         /* a.b.c -- 8.8.16 bits */
-             if (val > 0xffff)
-                 return 0;
-             val |= (parts[0] << 24) | (parts[1] << 16);
-             break;
-
-         case 4:         /* a.b.c.d -- 8.8.8.8 bits */
-             if (val > 0xff)
-                 return 0;
-             val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
-             break;
-     }
-
-     *addr = htonl(val);
-     return 1;
-
-}
-
-/*
-    ========================================================================
-
-    Routine Description:
-        Find key section for Get key parameter.
-
-    Arguments:
-        buffer                      Pointer to the buffer to start find the key section
-        section                     the key of the secion to be find
-
-    Return Value:
-        NULL                        Fail
-        Others                      Success
-    ========================================================================
-*/
-PUCHAR  RTMPFindSection(
-    IN  PCHAR   buffer)
-{
-    CHAR temp_buf[32];
-    PUCHAR  ptr;
-
-    strcpy(temp_buf, "Default");
-
-    if((ptr = rtstrstr(buffer, temp_buf)) != NULL)
-            return (ptr+strlen("\n"));
-        else
-            return NULL;
-}
-
-/*
-    ========================================================================
-
-    Routine Description:
-        Get key parameter.
-
-    Arguments:
-        key                         Pointer to key string
-        dest                        Pointer to destination
-        destsize                    The datasize of the destination
-        buffer                      Pointer to the buffer to start find the key
-
-    Return Value:
-        TRUE                        Success
-        FALSE                       Fail
-
-    Note:
-        This routine get the value with the matched key (case case-sensitive)
-    ========================================================================
-*/
-INT RTMPGetKeyParameter(
-    IN  PCHAR   key,
-    OUT PCHAR   dest,
-    IN  INT     destsize,
-    IN  PCHAR   buffer)
-{
-    UCHAR *temp_buf1 = NULL;
-    UCHAR *temp_buf2 = NULL;
-    CHAR *start_ptr;
-    CHAR *end_ptr;
-    CHAR *ptr;
-    CHAR *offset = 0;
-    INT  len;
-
-	//temp_buf1 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
-	os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
-
-	if(temp_buf1 == NULL)
-        return (FALSE);
-
-	//temp_buf2 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
-	os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
-	if(temp_buf2 == NULL)
-	{
-		os_free_mem(NULL, temp_buf1);
-        return (FALSE);
-	}
-
-    //find section
-    if((offset = RTMPFindSection(buffer)) == NULL)
-    {
-    	os_free_mem(NULL, temp_buf1);
-    	os_free_mem(NULL, temp_buf2);
-        return (FALSE);
-    }
-
-    strcpy(temp_buf1, "\n");
-    strcat(temp_buf1, key);
-    strcat(temp_buf1, "=");
-
-    //search key
-    if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
-    {
-		os_free_mem(NULL, temp_buf1);
-    	os_free_mem(NULL, temp_buf2);
-        return (FALSE);
-    }
-
-    start_ptr+=strlen("\n");
-    if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
-       end_ptr=start_ptr+strlen(start_ptr);
-
-    if (end_ptr<start_ptr)
-    {
-		os_free_mem(NULL, temp_buf1);
-    	os_free_mem(NULL, temp_buf2);
-        return (FALSE);
-    }
-
-    NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
-    temp_buf2[end_ptr-start_ptr]='\0';
-    len = strlen(temp_buf2);
-    strcpy(temp_buf1, temp_buf2);
-    if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
-    {
-		os_free_mem(NULL, temp_buf1);
-    	os_free_mem(NULL, temp_buf2);
-        return (FALSE);
-    }
-
-    strcpy(temp_buf2, start_ptr+1);
-    ptr = temp_buf2;
-    //trim space or tab
-    while(*ptr != 0x00)
-    {
-        if( (*ptr == ' ') || (*ptr == '\t') )
-            ptr++;
-        else
-           break;
-    }
-
-    len = strlen(ptr);
-    memset(dest, 0x00, destsize);
-    strncpy(dest, ptr, len >= destsize ?  destsize: len);
-
-	os_free_mem(NULL, temp_buf1);
-    os_free_mem(NULL, temp_buf2);
-    return TRUE;
-}
-
-/*
-    ========================================================================
-
-    Routine Description:
-        Get key parameter.
-
-    Arguments:
-        key                         Pointer to key string
-        dest                        Pointer to destination
-        destsize                    The datasize of the destination
-        buffer                      Pointer to the buffer to start find the key
-
-    Return Value:
-        TRUE                        Success
-        FALSE                       Fail
-
-    Note:
-        This routine get the value with the matched key (case case-sensitive).
-        It is called for parsing SSID and any key string.
-    ========================================================================
-*/
-INT RTMPGetCriticalParameter(
-    IN  PCHAR   key,
-    OUT PCHAR   dest,
-    IN  INT     destsize,
-    IN  PCHAR   buffer)
-{
-    UCHAR *temp_buf1 = NULL;
-    UCHAR *temp_buf2 = NULL;
-    CHAR *start_ptr;
-    CHAR *end_ptr;
-    CHAR *ptr;
-    CHAR *offset = 0;
-    INT  len;
-
-	//temp_buf1 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
-	os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
-
-	if(temp_buf1 == NULL)
-        return (FALSE);
-
-	//temp_buf2 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
-	os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
-	if(temp_buf2 == NULL)
-	{
-		os_free_mem(NULL, temp_buf1);
-        return (FALSE);
-	}
-
-    //find section
-    if((offset = RTMPFindSection(buffer)) == NULL)
-    {
-    	os_free_mem(NULL, temp_buf1);
-    	os_free_mem(NULL, temp_buf2);
-        return (FALSE);
-    }
-
-    strcpy(temp_buf1, "\n");
-    strcat(temp_buf1, key);
-    strcat(temp_buf1, "=");
-
-    //search key
-    if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
-    {
-		os_free_mem(NULL, temp_buf1);
-    	os_free_mem(NULL, temp_buf2);
-        return (FALSE);
-    }
-
-    start_ptr+=strlen("\n");
-    if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
-       end_ptr=start_ptr+strlen(start_ptr);
-
-    if (end_ptr<start_ptr)
-    {
-		os_free_mem(NULL, temp_buf1);
-    	os_free_mem(NULL, temp_buf2);
-        return (FALSE);
-    }
-
-    NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
-    temp_buf2[end_ptr-start_ptr]='\0';
-    len = strlen(temp_buf2);
-    strcpy(temp_buf1, temp_buf2);
-    if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
-    {
-		os_free_mem(NULL, temp_buf1);
-    	os_free_mem(NULL, temp_buf2);
-        return (FALSE);
-    }
-
-    strcpy(temp_buf2, start_ptr+1);
-    ptr = temp_buf2;
-
-    //trim tab
-    /* We cannot trim space(' ') for SSID and key string. */
-    while(*ptr != 0x00)
-    {
-        //if( (*ptr == ' ') || (*ptr == '\t') )
-        if( (*ptr == '\t') )
-            ptr++;
-        else
-           break;
-    }
-
-    len = strlen(ptr);
-    memset(dest, 0x00, destsize);
-    strncpy(dest, ptr, len >= destsize ?  destsize: len);
-
-	os_free_mem(NULL, temp_buf1);
-    os_free_mem(NULL, temp_buf2);
-    return TRUE;
-}
-
-/*
-    ========================================================================
-
-    Routine Description:
-        Get multiple key parameter.
-
-    Arguments:
-        key                         Pointer to key string
-        dest                        Pointer to destination
-        destsize                    The datasize of the destination
-        buffer                      Pointer to the buffer to start find the key
-
-    Return Value:
-        TRUE                        Success
-        FALSE                       Fail
-
-    Note:
-        This routine get the value with the matched key (case case-sensitive)
-    ========================================================================
-*/
-INT RTMPGetKeyParameterWithOffset(
-    IN  PCHAR   key,
-    OUT PCHAR   dest,
-    OUT	USHORT	*end_offset,
-    IN  INT     destsize,
-    IN  PCHAR   buffer,
-    IN	BOOLEAN	bTrimSpace)
-{
-    UCHAR *temp_buf1 = NULL;
-    UCHAR *temp_buf2 = NULL;
-    CHAR *start_ptr;
-    CHAR *end_ptr;
-    CHAR *ptr;
-    CHAR *offset = 0;
-    INT  len;
-
-	if (*end_offset >= MAX_INI_BUFFER_SIZE)
-		return (FALSE);
-
-	os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
-
-	if(temp_buf1 == NULL)
-        return (FALSE);
-
-	os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
-	if(temp_buf2 == NULL)
-	{
-		os_free_mem(NULL, temp_buf1);
-        return (FALSE);
-	}
-
-    //find section
-	if(*end_offset == 0)
-    {
-		if ((offset = RTMPFindSection(buffer)) == NULL)
-		{
-			os_free_mem(NULL, temp_buf1);
-	    	os_free_mem(NULL, temp_buf2);
-    	    return (FALSE);
-		}
-    }
-	else
-		offset = buffer + (*end_offset);
-
-    strcpy(temp_buf1, "\n");
-    strcat(temp_buf1, key);
-    strcat(temp_buf1, "=");
-
-    //search key
-    if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
-    {
-		os_free_mem(NULL, temp_buf1);
-    	os_free_mem(NULL, temp_buf2);
-        return (FALSE);
-    }
-
-    start_ptr+=strlen("\n");
-    if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
-       end_ptr=start_ptr+strlen(start_ptr);
-
-    if (end_ptr<start_ptr)
-    {
-		os_free_mem(NULL, temp_buf1);
-    	os_free_mem(NULL, temp_buf2);
-        return (FALSE);
-    }
-
-	*end_offset = end_ptr - buffer;
-
-    NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
-    temp_buf2[end_ptr-start_ptr]='\0';
-    len = strlen(temp_buf2);
-    strcpy(temp_buf1, temp_buf2);
-    if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
-    {
-		os_free_mem(NULL, temp_buf1);
-    	os_free_mem(NULL, temp_buf2);
-        return (FALSE);
-    }
-
-    strcpy(temp_buf2, start_ptr+1);
-    ptr = temp_buf2;
-    //trim space or tab
-    while(*ptr != 0x00)
-    {
-        if((bTrimSpace && (*ptr == ' ')) || (*ptr == '\t') )
-            ptr++;
-        else
-           break;
-    }
-
-    len = strlen(ptr);
-    memset(dest, 0x00, destsize);
-    strncpy(dest, ptr, len >= destsize ?  destsize: len);
-
-	os_free_mem(NULL, temp_buf1);
-    os_free_mem(NULL, temp_buf2);
-    return TRUE;
-}
-
-
-static int rtmp_parse_key_buffer_from_file(IN  PRTMP_ADAPTER pAd,IN  char *buffer,IN  ULONG KeyType,IN  INT BSSIdx,IN  INT KeyIdx)
-{
-	PUCHAR		keybuff;
-	INT			i = BSSIdx, idx = KeyIdx;
-	ULONG		KeyLen;
-	UCHAR		CipherAlg = CIPHER_WEP64;
-
-	keybuff = buffer;
-	KeyLen = strlen(keybuff);
-
-	if (KeyType == 1)
-	{//Ascii
-		if( (KeyLen == 5) || (KeyLen == 13))
-		{
-			pAd->SharedKey[i][idx].KeyLen = KeyLen;
-			NdisMoveMemory(pAd->SharedKey[i][idx].Key, keybuff, KeyLen);
-			if (KeyLen == 5)
-				CipherAlg = CIPHER_WEP64;
-			else
-				CipherAlg = CIPHER_WEP128;
-			pAd->SharedKey[i][idx].CipherAlg = CipherAlg;
-
-			DBGPRINT(RT_DEBUG_TRACE, ("I/F(wlan%d) Key%dStr=%s and type=%s\n", i, idx+1, keybuff, (KeyType == 0) ? "Hex":"Ascii"));
-			return 1;
-		}
-		else
-		{//Invalid key length
-			DBGPRINT(RT_DEBUG_ERROR, ("Key%dStr is Invalid key length! KeyLen = %ld!\n", idx+1, KeyLen));
-			return 0;
-		}
-	}
-	else
-	{//Hex type
-		if( (KeyLen == 10) || (KeyLen == 26))
-		{
-			pAd->SharedKey[i][idx].KeyLen = KeyLen / 2;
-			AtoH(keybuff, pAd->SharedKey[i][idx].Key, KeyLen / 2);
-			if (KeyLen == 10)
-				CipherAlg = CIPHER_WEP64;
-			else
-				CipherAlg = CIPHER_WEP128;
-			pAd->SharedKey[i][idx].CipherAlg = CipherAlg;
-
-			DBGPRINT(RT_DEBUG_TRACE, ("I/F(wlan%d) Key%dStr=%s and type=%s\n", i, idx+1, keybuff, (KeyType == 0) ? "Hex":"Ascii"));
-			return 1;
-		}
-		else
-		{//Invalid key length
-			DBGPRINT(RT_DEBUG_ERROR, ("I/F(wlan%d) Key%dStr is Invalid key length! KeyLen = %ld!\n", i, idx+1, KeyLen));
-			return 0;
-		}
-	}
-}
-static void rtmp_read_key_parms_from_file(IN  PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer)
-{
-	char		tok_str[16];
-	PUCHAR		macptr;
-	INT			i = 0, idx;
-	ULONG		KeyType[MAX_MBSSID_NUM];
-	ULONG		KeyIdx;
-
-	NdisZeroMemory(KeyType, MAX_MBSSID_NUM);
-
-	//DefaultKeyID
-	if(RTMPGetKeyParameter("DefaultKeyID", tmpbuf, 25, buffer))
-	{
-		{
-			KeyIdx = simple_strtol(tmpbuf, 0, 10);
-			if((KeyIdx >= 1 ) && (KeyIdx <= 4))
-				pAd->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1);
-			else
-				pAd->StaCfg.DefaultKeyId = 0;
-
-			DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyID(0~3)=%d\n", pAd->StaCfg.DefaultKeyId));
-		}
-	}
-
-
-	for (idx = 0; idx < 4; idx++)
-	{
-		sprintf(tok_str, "Key%dType", idx + 1);
-		//Key1Type
-		if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer))
-		{
-		    for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
-		    {
-			    KeyType[i] = simple_strtol(macptr, 0, 10);
-		    }
-
-			{
-				sprintf(tok_str, "Key%dStr", idx + 1);
-				if (RTMPGetCriticalParameter(tok_str, tmpbuf, 128, buffer))
-				{
-					rtmp_parse_key_buffer_from_file(pAd, tmpbuf, KeyType[BSS0], BSS0, idx);
-				}
-			}
-		}
-	}
-}
-
-static void rtmp_read_sta_wmm_parms_from_file(IN  PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer)
-{
-	PUCHAR					macptr;
-	INT						i=0;
-	BOOLEAN					bWmmEnable = FALSE;
-
-	//WmmCapable
-	if(RTMPGetKeyParameter("WmmCapable", tmpbuf, 32, buffer))
-	{
-		if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
-		{
-			pAd->CommonCfg.bWmmCapable = TRUE;
-			bWmmEnable = TRUE;
-		}
-		else //Disable
-		{
-			pAd->CommonCfg.bWmmCapable = FALSE;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("WmmCapable=%d\n", pAd->CommonCfg.bWmmCapable));
-	}
-
-	//AckPolicy for AC_BK, AC_BE, AC_VI, AC_VO
-	if(RTMPGetKeyParameter("AckPolicy", tmpbuf, 32, buffer))
-	{
-		for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
-		{
-			pAd->CommonCfg.AckPolicy[i] = (UCHAR)simple_strtol(macptr, 0, 10);
-
-			DBGPRINT(RT_DEBUG_TRACE, ("AckPolicy[%d]=%d\n", i, pAd->CommonCfg.AckPolicy[i]));
-		}
-	}
-
-	if (bWmmEnable)
-	{
-		//APSDCapable
-		if(RTMPGetKeyParameter("APSDCapable", tmpbuf, 10, buffer))
-		{
-			if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
-				pAd->CommonCfg.bAPSDCapable = TRUE;
-			else
-				pAd->CommonCfg.bAPSDCapable = FALSE;
-
-			DBGPRINT(RT_DEBUG_TRACE, ("APSDCapable=%d\n", pAd->CommonCfg.bAPSDCapable));
-		}
-
-		//APSDAC for AC_BE, AC_BK, AC_VI, AC_VO
-		if(RTMPGetKeyParameter("APSDAC", tmpbuf, 32, buffer))
-		{
-			BOOLEAN apsd_ac[4];
-
-			for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
-			{
-				apsd_ac[i] = (BOOLEAN)simple_strtol(macptr, 0, 10);
-
-				DBGPRINT(RT_DEBUG_TRACE, ("APSDAC%d  %d\n", i,  apsd_ac[i]));
-			}
-
-			pAd->CommonCfg.bAPSDAC_BE = apsd_ac[0];
-			pAd->CommonCfg.bAPSDAC_BK = apsd_ac[1];
-			pAd->CommonCfg.bAPSDAC_VI = apsd_ac[2];
-			pAd->CommonCfg.bAPSDAC_VO = apsd_ac[3];
-		}
-	}
-
-}
-
-NDIS_STATUS	RTMPReadParametersHook(
-	IN	PRTMP_ADAPTER pAd)
-{
-	PUCHAR					src = NULL;
-	struct file				*srcf;
-	INT 					retval;
-   	mm_segment_t			orgfs;
-	CHAR					*buffer;
-	CHAR					*tmpbuf;
-	ULONG					RtsThresh;
-	ULONG					FragThresh;
-	UCHAR	                keyMaterial[40];
-
-	PUCHAR					macptr;
-	INT						i = 0;
-
-	buffer = kmalloc(MAX_INI_BUFFER_SIZE, MEM_ALLOC_FLAG);
-	if(buffer == NULL)
-        return NDIS_STATUS_FAILURE;
-
-	tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
-	if(tmpbuf == NULL)
-	{
-		kfree(buffer);
-        return NDIS_STATUS_FAILURE;
-	}
-
-	src = STA_PROFILE_PATH;
-
-    orgfs = get_fs();
-    set_fs(KERNEL_DS);
-
-	if (src && *src)
-	{
-		srcf = filp_open(src, O_RDONLY, 0);
-		if (IS_ERR(srcf))
-		{
-			DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
-		}
-		else
-		{
-			// The object must have a read method
-			if (srcf->f_op && srcf->f_op->read)
-			{
-				memset(buffer, 0x00, MAX_INI_BUFFER_SIZE);
-				retval=srcf->f_op->read(srcf, buffer, MAX_INI_BUFFER_SIZE, &srcf->f_pos);
-				if (retval < 0)
-				{
-					DBGPRINT(RT_DEBUG_TRACE, ("--> Read %s error %d\n", src, -retval));
-				}
-				else
-				{
-					// set file parameter to portcfg
-					//CountryRegion
-					if(RTMPGetKeyParameter("CountryRegion", tmpbuf, 25, buffer))
-					{
-						pAd->CommonCfg.CountryRegion = (UCHAR) simple_strtol(tmpbuf, 0, 10);
-						DBGPRINT(RT_DEBUG_TRACE, ("CountryRegion=%d\n", pAd->CommonCfg.CountryRegion));
-					}
-					//CountryRegionABand
-					if(RTMPGetKeyParameter("CountryRegionABand", tmpbuf, 25, buffer))
-					{
-						pAd->CommonCfg.CountryRegionForABand= (UCHAR) simple_strtol(tmpbuf, 0, 10);
-						DBGPRINT(RT_DEBUG_TRACE, ("CountryRegionABand=%d\n", pAd->CommonCfg.CountryRegionForABand));
-					}
-					//CountryCode
-					if(RTMPGetKeyParameter("CountryCode", tmpbuf, 25, buffer))
-					{
-						NdisMoveMemory(pAd->CommonCfg.CountryCode, tmpbuf , 2);
-
-						if (strlen(pAd->CommonCfg.CountryCode) != 0)
-						{
-							pAd->CommonCfg.bCountryFlag = TRUE;
-						}
-						DBGPRINT(RT_DEBUG_TRACE, ("CountryCode=%s\n", pAd->CommonCfg.CountryCode));
-					}
-					//ChannelGeography
-					if(RTMPGetKeyParameter("ChannelGeography", tmpbuf, 25, buffer))
-					{
-						UCHAR Geography = (UCHAR) simple_strtol(tmpbuf, 0, 10);
-						if (Geography <= BOTH)
-						{
-							pAd->CommonCfg.Geography = Geography;
-							pAd->CommonCfg.CountryCode[2] =
-								(pAd->CommonCfg.Geography == BOTH) ? ' ' : ((pAd->CommonCfg.Geography == IDOR) ? 'I' : 'O');
-							DBGPRINT(RT_DEBUG_TRACE, ("ChannelGeography=%d\n", pAd->CommonCfg.Geography));
-						}
-					}
-					else
-					{
-						pAd->CommonCfg.Geography = BOTH;
-						pAd->CommonCfg.CountryCode[2] = ' ';
-					}
-
-					{
-						//SSID
-						if (RTMPGetCriticalParameter("SSID", tmpbuf, 256, buffer))
-						{
-							if (strlen(tmpbuf) <= 32)
-							{
-			 					pAd->CommonCfg.SsidLen = (UCHAR) strlen(tmpbuf);
-								NdisZeroMemory(pAd->CommonCfg.Ssid, NDIS_802_11_LENGTH_SSID);
-								NdisMoveMemory(pAd->CommonCfg.Ssid, tmpbuf, pAd->CommonCfg.SsidLen);
-								pAd->MlmeAux.AutoReconnectSsidLen = pAd->CommonCfg.SsidLen;
-								NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, NDIS_802_11_LENGTH_SSID);
-								NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, tmpbuf, pAd->MlmeAux.AutoReconnectSsidLen);
-								pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen;
-								NdisZeroMemory(pAd->MlmeAux.Ssid, NDIS_802_11_LENGTH_SSID);
-								NdisMoveMemory(pAd->MlmeAux.Ssid, tmpbuf, pAd->MlmeAux.SsidLen);
-								DBGPRINT(RT_DEBUG_TRACE, ("%s::(SSID=%s)\n", __func__, tmpbuf));
-							}
-						}
-					}
-
-					{
-						//NetworkType
-						if (RTMPGetKeyParameter("NetworkType", tmpbuf, 25, buffer))
-						{
-							pAd->bConfigChanged = TRUE;
-							if (strcmp(tmpbuf, "Adhoc") == 0)
-								pAd->StaCfg.BssType = BSS_ADHOC;
-							else //Default Infrastructure mode
-								pAd->StaCfg.BssType = BSS_INFRA;
-							// Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
-							pAd->StaCfg.WpaState = SS_NOTUSE;
-							DBGPRINT(RT_DEBUG_TRACE, ("%s::(NetworkType=%d)\n", __func__, pAd->StaCfg.BssType));
-						}
-					}
-
-					//Channel
-					if(RTMPGetKeyParameter("Channel", tmpbuf, 10, buffer))
-					{
-						pAd->CommonCfg.Channel = (UCHAR) simple_strtol(tmpbuf, 0, 10);
-						DBGPRINT(RT_DEBUG_TRACE, ("Channel=%d\n", pAd->CommonCfg.Channel));
-					}
-					//WirelessMode
-					if(RTMPGetKeyParameter("WirelessMode", tmpbuf, 10, buffer))
-					{
-						int value  = 0, maxPhyMode = PHY_11G;
-
-						maxPhyMode = PHY_11N_5G;
-
-						value = simple_strtol(tmpbuf, 0, 10);
-
-						if (value <= maxPhyMode)
-						{
-							pAd->CommonCfg.PhyMode = value;
-						}
-						DBGPRINT(RT_DEBUG_TRACE, ("PhyMode=%d\n", pAd->CommonCfg.PhyMode));
-					}
-                    //BasicRate
-					if(RTMPGetKeyParameter("BasicRate", tmpbuf, 10, buffer))
-					{
-						pAd->CommonCfg.BasicRateBitmap = (ULONG) simple_strtol(tmpbuf, 0, 10);
-						DBGPRINT(RT_DEBUG_TRACE, ("BasicRate=%ld\n", pAd->CommonCfg.BasicRateBitmap));
-					}
-					//BeaconPeriod
-					if(RTMPGetKeyParameter("BeaconPeriod", tmpbuf, 10, buffer))
-					{
-						pAd->CommonCfg.BeaconPeriod = (USHORT) simple_strtol(tmpbuf, 0, 10);
-						DBGPRINT(RT_DEBUG_TRACE, ("BeaconPeriod=%d\n", pAd->CommonCfg.BeaconPeriod));
-					}
-                    //TxPower
-					if(RTMPGetKeyParameter("TxPower", tmpbuf, 10, buffer))
-					{
-						pAd->CommonCfg.TxPowerPercentage = (ULONG) simple_strtol(tmpbuf, 0, 10);
-
-						pAd->CommonCfg.TxPowerDefault = pAd->CommonCfg.TxPowerPercentage;
-
-						DBGPRINT(RT_DEBUG_TRACE, ("TxPower=%ld\n", pAd->CommonCfg.TxPowerPercentage));
-					}
-					//BGProtection
-					if(RTMPGetKeyParameter("BGProtection", tmpbuf, 10, buffer))
-					{
-						switch (simple_strtol(tmpbuf, 0, 10))
-						{
-							case 1: //Always On
-								pAd->CommonCfg.UseBGProtection = 1;
-								break;
-							case 2: //Always OFF
-								pAd->CommonCfg.UseBGProtection = 2;
-								break;
-							case 0: //AUTO
-							default:
-								pAd->CommonCfg.UseBGProtection = 0;
-								break;
-						}
-						DBGPRINT(RT_DEBUG_TRACE, ("BGProtection=%ld\n", pAd->CommonCfg.UseBGProtection));
-					}
-					//OLBCDetection
-					if(RTMPGetKeyParameter("DisableOLBC", tmpbuf, 10, buffer))
-					{
-						switch (simple_strtol(tmpbuf, 0, 10))
-						{
-							case 1: //disable OLBC Detection
-								pAd->CommonCfg.DisableOLBCDetect = 1;
-								break;
-							case 0: //enable OLBC Detection
-								pAd->CommonCfg.DisableOLBCDetect = 0;
-								break;
-							default:
-								pAd->CommonCfg.DisableOLBCDetect= 0;
-								break;
-						}
-						DBGPRINT(RT_DEBUG_TRACE, ("OLBCDetection=%ld\n", pAd->CommonCfg.DisableOLBCDetect));
-					}
-					//TxPreamble
-					if(RTMPGetKeyParameter("TxPreamble", tmpbuf, 10, buffer))
-					{
-						switch (simple_strtol(tmpbuf, 0, 10))
-						{
-							case Rt802_11PreambleShort:
-								pAd->CommonCfg.TxPreamble = Rt802_11PreambleShort;
-								break;
-							case Rt802_11PreambleLong:
-							default:
-								pAd->CommonCfg.TxPreamble = Rt802_11PreambleLong;
-								break;
-						}
-						DBGPRINT(RT_DEBUG_TRACE, ("TxPreamble=%ld\n", pAd->CommonCfg.TxPreamble));
-					}
-					//RTSThreshold
-					if(RTMPGetKeyParameter("RTSThreshold", tmpbuf, 10, buffer))
-					{
-						RtsThresh = simple_strtol(tmpbuf, 0, 10);
-						if( (RtsThresh >= 1) && (RtsThresh <= MAX_RTS_THRESHOLD) )
-							pAd->CommonCfg.RtsThreshold  = (USHORT)RtsThresh;
-						else
-							pAd->CommonCfg.RtsThreshold = MAX_RTS_THRESHOLD;
-
-						DBGPRINT(RT_DEBUG_TRACE, ("RTSThreshold=%d\n", pAd->CommonCfg.RtsThreshold));
-					}
-					//FragThreshold
-					if(RTMPGetKeyParameter("FragThreshold", tmpbuf, 10, buffer))
-					{
-						FragThresh = simple_strtol(tmpbuf, 0, 10);
-						pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
-
-						if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
-						{ //illegal FragThresh so we set it to default
-							pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
-							pAd->CommonCfg.bUseZeroToDisableFragment = TRUE;
-						}
-						else if (FragThresh % 2 == 1)
-						{
-							// The length of each fragment shall always be an even number of octets, except for the last fragment
-							// of an MSDU or MMPDU, which may be either an even or an odd number of octets.
-							pAd->CommonCfg.FragmentThreshold = (USHORT)(FragThresh - 1);
-						}
-						else
-						{
-							pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
-						}
-						//pAd->CommonCfg.AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
-						DBGPRINT(RT_DEBUG_TRACE, ("FragThreshold=%d\n", pAd->CommonCfg.FragmentThreshold));
-					}
-					//TxBurst
-					if(RTMPGetKeyParameter("TxBurst", tmpbuf, 10, buffer))
-					{
-						if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
-							pAd->CommonCfg.bEnableTxBurst = TRUE;
-						else //Disable
-							pAd->CommonCfg.bEnableTxBurst = FALSE;
-						DBGPRINT(RT_DEBUG_TRACE, ("TxBurst=%d\n", pAd->CommonCfg.bEnableTxBurst));
-					}
-
-#ifdef AGGREGATION_SUPPORT
-					//PktAggregate
-					if(RTMPGetKeyParameter("PktAggregate", tmpbuf, 10, buffer))
-					{
-						if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
-							pAd->CommonCfg.bAggregationCapable = TRUE;
-						else //Disable
-							pAd->CommonCfg.bAggregationCapable = FALSE;
-#ifdef PIGGYBACK_SUPPORT
-						pAd->CommonCfg.bPiggyBackCapable = pAd->CommonCfg.bAggregationCapable;
-#endif // PIGGYBACK_SUPPORT //
-						DBGPRINT(RT_DEBUG_TRACE, ("PktAggregate=%d\n", pAd->CommonCfg.bAggregationCapable));
-					}
-#else
-					pAd->CommonCfg.bAggregationCapable = FALSE;
-					pAd->CommonCfg.bPiggyBackCapable = FALSE;
-#endif // AGGREGATION_SUPPORT //
-
-					// WmmCapable
-					rtmp_read_sta_wmm_parms_from_file(pAd, tmpbuf, buffer);
-
-					//ShortSlot
-					if(RTMPGetKeyParameter("ShortSlot", tmpbuf, 10, buffer))
-					{
-						if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
-							pAd->CommonCfg.bUseShortSlotTime = TRUE;
-						else //Disable
-							pAd->CommonCfg.bUseShortSlotTime = FALSE;
-
-						DBGPRINT(RT_DEBUG_TRACE, ("ShortSlot=%d\n", pAd->CommonCfg.bUseShortSlotTime));
-					}
-					//IEEE80211H
-					if(RTMPGetKeyParameter("IEEE80211H", tmpbuf, 10, buffer))
-					{
-					    for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
-					    {
-    						if(simple_strtol(macptr, 0, 10) != 0)  //Enable
-    							pAd->CommonCfg.bIEEE80211H = TRUE;
-    						else //Disable
-    							pAd->CommonCfg.bIEEE80211H = FALSE;
-
-    						DBGPRINT(RT_DEBUG_TRACE, ("IEEE80211H=%d\n", pAd->CommonCfg.bIEEE80211H));
-					    }
-					}
-					//CSPeriod
-					if(RTMPGetKeyParameter("CSPeriod", tmpbuf, 10, buffer))
-					{
-					    if(simple_strtol(tmpbuf, 0, 10) != 0)
-							pAd->CommonCfg.RadarDetect.CSPeriod = simple_strtol(tmpbuf, 0, 10);
-						else
-							pAd->CommonCfg.RadarDetect.CSPeriod = 0;
-
-   						DBGPRINT(RT_DEBUG_TRACE, ("CSPeriod=%d\n", pAd->CommonCfg.RadarDetect.CSPeriod));
-					}
-
-					//RDRegion
-					if(RTMPGetKeyParameter("RDRegion", tmpbuf, 128, buffer))
-					{
-						if ((strncmp(tmpbuf, "JAP_W53", 7) == 0) || (strncmp(tmpbuf, "jap_w53", 7) == 0))
-						{
-							pAd->CommonCfg.RadarDetect.RDDurRegion = JAP_W53;
-							pAd->CommonCfg.RadarDetect.DfsSessionTime = 15;
-						}
-						else if ((strncmp(tmpbuf, "JAP_W56", 7) == 0) || (strncmp(tmpbuf, "jap_w56", 7) == 0))
-						{
-							pAd->CommonCfg.RadarDetect.RDDurRegion = JAP_W56;
-							pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
-						}
-						else if ((strncmp(tmpbuf, "JAP", 3) == 0) || (strncmp(tmpbuf, "jap", 3) == 0))
-						{
-							pAd->CommonCfg.RadarDetect.RDDurRegion = JAP;
-							pAd->CommonCfg.RadarDetect.DfsSessionTime = 5;
-						}
-						else  if ((strncmp(tmpbuf, "FCC", 3) == 0) || (strncmp(tmpbuf, "fcc", 3) == 0))
-						{
-							pAd->CommonCfg.RadarDetect.RDDurRegion = FCC;
-							pAd->CommonCfg.RadarDetect.DfsSessionTime = 5;
-						}
-						else if ((strncmp(tmpbuf, "CE", 2) == 0) || (strncmp(tmpbuf, "ce", 2) == 0))
-						{
-							pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
-							pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
-						}
-						else
-						{
-							pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
-							pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
-						}
-
-						DBGPRINT(RT_DEBUG_TRACE, ("RDRegion=%d\n", pAd->CommonCfg.RadarDetect.RDDurRegion));
-					}
-					else
-					{
-						pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
-						pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
-					}
-
-					//WirelessEvent
-					if(RTMPGetKeyParameter("WirelessEvent", tmpbuf, 10, buffer))
-					{
-					    if(simple_strtol(tmpbuf, 0, 10) != 0)
-							pAd->CommonCfg.bWirelessEvent = simple_strtol(tmpbuf, 0, 10);
-						else
-							pAd->CommonCfg.bWirelessEvent = 0;	// disable
-   						DBGPRINT(RT_DEBUG_TRACE, ("WirelessEvent=%d\n", pAd->CommonCfg.bWirelessEvent));
-					}
-					if(RTMPGetKeyParameter("WiFiTest", tmpbuf, 10, buffer))
-					{
-					    if(simple_strtol(tmpbuf, 0, 10) != 0)
-							pAd->CommonCfg.bWiFiTest= simple_strtol(tmpbuf, 0, 10);
-						else
-							pAd->CommonCfg.bWiFiTest = 0;	// disable
-
-   						DBGPRINT(RT_DEBUG_TRACE, ("WiFiTest=%d\n", pAd->CommonCfg.bWiFiTest));
-					}
-					//AuthMode
-					if(RTMPGetKeyParameter("AuthMode", tmpbuf, 128, buffer))
-					{
-						{
-							if ((strcmp(tmpbuf, "WEPAUTO") == 0) || (strcmp(tmpbuf, "wepauto") == 0))
-							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
-							else if ((strcmp(tmpbuf, "SHARED") == 0) || (strcmp(tmpbuf, "shared") == 0))
-							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeShared;
-							else if ((strcmp(tmpbuf, "WPAPSK") == 0) || (strcmp(tmpbuf, "wpapsk") == 0))
-							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
-							else if ((strcmp(tmpbuf, "WPANONE") == 0) || (strcmp(tmpbuf, "wpanone") == 0))
-							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
-							else if ((strcmp(tmpbuf, "WPA2PSK") == 0) || (strcmp(tmpbuf, "wpa2psk") == 0))
-							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
-							else if ((strcmp(tmpbuf, "WPA") == 0) || (strcmp(tmpbuf, "wpa") == 0))
-							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
-							else if ((strcmp(tmpbuf, "WPA2") == 0) || (strcmp(tmpbuf, "wpa2") == 0))
-							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
-				                        else
-				                            pAd->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
-
-				                        pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-
-							DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __func__, pAd->StaCfg.WepStatus));
-						}
-					}
-					//EncrypType
-					if(RTMPGetKeyParameter("EncrypType", tmpbuf, 128, buffer))
-					{
-						{
-							if ((strcmp(tmpbuf, "WEP") == 0) || (strcmp(tmpbuf, "wep") == 0))
-								pAd->StaCfg.WepStatus	= Ndis802_11WEPEnabled;
-							else if ((strcmp(tmpbuf, "TKIP") == 0) || (strcmp(tmpbuf, "tkip") == 0))
-								pAd->StaCfg.WepStatus	= Ndis802_11Encryption2Enabled;
-							else if ((strcmp(tmpbuf, "AES") == 0) || (strcmp(tmpbuf, "aes") == 0))
-								pAd->StaCfg.WepStatus	= Ndis802_11Encryption3Enabled;
-							else
-								pAd->StaCfg.WepStatus	= Ndis802_11WEPDisabled;
-
-							// Update all wepstatus related
-							pAd->StaCfg.PairCipher		= pAd->StaCfg.WepStatus;
-							pAd->StaCfg.GroupCipher 	= pAd->StaCfg.WepStatus;
-							pAd->StaCfg.OrigWepStatus 	= pAd->StaCfg.WepStatus;
-							pAd->StaCfg.bMixCipher 		= FALSE;
-
-							DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __func__, pAd->StaCfg.WepStatus));
-						}
-					}
-
-					{
-						if(RTMPGetCriticalParameter("WPAPSK", tmpbuf, 512, buffer))
-						{
-							int     err=0;
-
-							tmpbuf[strlen(tmpbuf)] = '\0'; // make STA can process .$^& for WPAPSK input
-
-							if ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
-								(pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
-								(pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
-								)
-							{
-								err = 1;
-							}
-							else if ((strlen(tmpbuf) >= 8) && (strlen(tmpbuf) < 64))
-							{
-								PasswordHash((char *)tmpbuf, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, keyMaterial);
-								NdisMoveMemory(pAd->StaCfg.PMK, keyMaterial, 32);
-
-							}
-							else if (strlen(tmpbuf) == 64)
-							{
-								AtoH(tmpbuf, keyMaterial, 32);
-								NdisMoveMemory(pAd->StaCfg.PMK, keyMaterial, 32);
-							}
-							else
-							{
-								err = 1;
-								DBGPRINT(RT_DEBUG_ERROR, ("%s::(WPAPSK key-string required 8 ~ 64 characters!)\n", __func__));
-							}
-
-							if (err == 0)
-	                        			{
-	                        				if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
-									(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
-								{
-									// Start STA supplicant state machine
-									pAd->StaCfg.WpaState = SS_START;
-								}
-								else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
-								{
-									pAd->StaCfg.WpaState = SS_NOTUSE;
-								}
-
-								DBGPRINT(RT_DEBUG_TRACE, ("%s::(WPAPSK=%s)\n", __func__, tmpbuf));
-							}
-						}
-					}
-
-					//DefaultKeyID, KeyType, KeyStr
-					rtmp_read_key_parms_from_file(pAd, tmpbuf, buffer);
-
-					HTParametersHook(pAd, tmpbuf, buffer);
-
-					{
-						//PSMode
-#ifdef RT2860
-						if (RTMPGetKeyParameter("PSMode", tmpbuf, 32, buffer))
-#endif
-#ifdef RT2870
-						if (RTMPGetKeyParameter("PSMode", tmpbuf, 10, buffer))
-#endif
-						{
-							if (pAd->StaCfg.BssType == BSS_INFRA)
-							{
-								if ((strcmp(tmpbuf, "MAX_PSP") == 0) || (strcmp(tmpbuf, "max_psp") == 0))
-								{
-									// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
-									// to exclude certain situations.
-									//	   MlmeSetPsm(pAd, PWR_SAVE);
-									OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
-									if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
-										pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
-									pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
-									pAd->StaCfg.DefaultListenCount = 5;
-								}
-								else if ((strcmp(tmpbuf, "Fast_PSP") == 0) || (strcmp(tmpbuf, "fast_psp") == 0)
-									|| (strcmp(tmpbuf, "FAST_PSP") == 0))
-								{
-									// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
-									// to exclude certain situations.
-									//	   MlmeSetPsmBit(pAd, PWR_SAVE);
-									OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
-									if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
-										pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
-									pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
-									pAd->StaCfg.DefaultListenCount = 3;
-								}
-								else if ((strcmp(tmpbuf, "Legacy_PSP") == 0) || (strcmp(tmpbuf, "legacy_psp") == 0)
-									|| (strcmp(tmpbuf, "LEGACY_PSP") == 0))
-								{
-									// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
-									// to exclude certain situations.
-									//	   MlmeSetPsmBit(pAd, PWR_SAVE);
-									OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
-									if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
-										pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
-									pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
-									pAd->StaCfg.DefaultListenCount = 3;
-								}
-								else
-								{ //Default Ndis802_11PowerModeCAM
-									// clear PSM bit immediately
-									MlmeSetPsmBit(pAd, PWR_ACTIVE);
-									OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
-									if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
-										pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
-									pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
-								}
-								DBGPRINT(RT_DEBUG_TRACE, ("PSMode=%ld\n", pAd->StaCfg.WindowsPowerMode));
-							}
-						}
-						// FastRoaming
-						if (RTMPGetKeyParameter("FastRoaming", tmpbuf, 32, buffer))
-						{
-							if (simple_strtol(tmpbuf, 0, 10) == 0)
-								pAd->StaCfg.bFastRoaming = FALSE;
-							else
-								pAd->StaCfg.bFastRoaming = TRUE;
-
-							DBGPRINT(RT_DEBUG_TRACE, ("FastRoaming=%d\n", pAd->StaCfg.bFastRoaming));
-						}
-						// RoamThreshold
-						if (RTMPGetKeyParameter("RoamThreshold", tmpbuf, 32, buffer))
-						{
-							long lInfo = simple_strtol(tmpbuf, 0, 10);
-
-							if (lInfo > 90 || lInfo < 60)
-								pAd->StaCfg.dBmToRoam = -70;
-							else
-								pAd->StaCfg.dBmToRoam = (CHAR)(-1)*lInfo;
-
-							DBGPRINT(RT_DEBUG_TRACE, ("RoamThreshold=%d  dBm\n", pAd->StaCfg.dBmToRoam));
-						}
-
-						if(RTMPGetKeyParameter("TGnWifiTest", tmpbuf, 10, buffer))
-						{
-							if(simple_strtol(tmpbuf, 0, 10) == 0)
-								pAd->StaCfg.bTGnWifiTest = FALSE;
-							else
-								pAd->StaCfg.bTGnWifiTest = TRUE;
-								DBGPRINT(RT_DEBUG_TRACE, ("TGnWifiTest=%d\n", pAd->StaCfg.bTGnWifiTest));
-						}
-					}
-				}
-			}
-			else
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("--> %s does not have a write method\n", src));
-			}
-
-			retval=filp_close(srcf,NULL);
-
-			if (retval)
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
-			}
-		}
-	}
-
-	set_fs(orgfs);
-
-	kfree(buffer);
-	kfree(tmpbuf);
-
-	return (NDIS_STATUS_SUCCESS);
-}
-
-static void	HTParametersHook(
-	IN	PRTMP_ADAPTER pAd,
-	IN	CHAR		  *pValueStr,
-	IN	CHAR		  *pInput)
-{
-
-	INT Value;
-
-    if (RTMPGetKeyParameter("HT_PROTECT", pValueStr, 25, pInput))
-    {
-        Value = simple_strtol(pValueStr, 0, 10);
-        if (Value == 0)
-        {
-            pAd->CommonCfg.bHTProtect = FALSE;
-        }
-        else
-        {
-            pAd->CommonCfg.bHTProtect = TRUE;
-        }
-        DBGPRINT(RT_DEBUG_TRACE, ("HT: Protection  = %s\n", (Value==0) ? "Disable" : "Enable"));
-    }
-
-    if (RTMPGetKeyParameter("HT_MIMOPSEnable", pValueStr, 25, pInput))
-    {
-        Value = simple_strtol(pValueStr, 0, 10);
-        if (Value == 0)
-        {
-            pAd->CommonCfg.bMIMOPSEnable = FALSE;
-        }
-        else
-        {
-            pAd->CommonCfg.bMIMOPSEnable = TRUE;
-        }
-        DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPSEnable  = %s\n", (Value==0) ? "Disable" : "Enable"));
-    }
-
-
-    if (RTMPGetKeyParameter("HT_MIMOPSMode", pValueStr, 25, pInput))
-    {
-        Value = simple_strtol(pValueStr, 0, 10);
-        if (Value > MMPS_ENABLE)
-        {
-			pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
-        }
-        else
-        {
-            //TODO: add mimo power saving mechanism
-            pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
-			//pAd->CommonCfg.BACapability.field.MMPSmode = Value;
-        }
-        DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPS Mode  = %d\n", Value));
-    }
-
-    if (RTMPGetKeyParameter("HT_BADecline", pValueStr, 25, pInput))
-    {
-        Value = simple_strtol(pValueStr, 0, 10);
-        if (Value == 0)
-        {
-            pAd->CommonCfg.bBADecline = FALSE;
-        }
-        else
-        {
-            pAd->CommonCfg.bBADecline = TRUE;
-        }
-        DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Decline  = %s\n", (Value==0) ? "Disable" : "Enable"));
-    }
-
-
-    if (RTMPGetKeyParameter("HT_DisableReordering", pValueStr, 25, pInput))
-    {
-        Value = simple_strtol(pValueStr, 0, 10);
-        if (Value == 0)
-        {
-            pAd->CommonCfg.bDisableReordering = FALSE;
-        }
-        else
-        {
-            pAd->CommonCfg.bDisableReordering = TRUE;
-        }
-        DBGPRINT(RT_DEBUG_TRACE, ("HT: DisableReordering  = %s\n", (Value==0) ? "Disable" : "Enable"));
-    }
-
-    if (RTMPGetKeyParameter("HT_AutoBA", pValueStr, 25, pInput))
-    {
-        Value = simple_strtol(pValueStr, 0, 10);
-        if (Value == 0)
-        {
-            pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
-	    pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
-        }
-        else
-        {
-            pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
-	    pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
-        }
-        pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
-	pAd->CommonCfg.REGBACapability.field.Policy = pAd->CommonCfg.BACapability.field.Policy;
-        DBGPRINT(RT_DEBUG_TRACE, ("HT: Auto BA  = %s\n", (Value==0) ? "Disable" : "Enable"));
-    }
-
-	// Tx_+HTC frame
-    if (RTMPGetKeyParameter("HT_HTC", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-		if (Value == 0)
-		{
-			pAd->HTCEnable = FALSE;
-		}
-		else
-		{
-            		pAd->HTCEnable = TRUE;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx +HTC frame = %s\n", (Value==0) ? "Disable" : "Enable"));
-	}
-
-	// Enable HT Link Adaptation Control
-	if (RTMPGetKeyParameter("HT_LinkAdapt", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-		if (Value == 0)
-		{
-			pAd->bLinkAdapt = FALSE;
-		}
-		else
-		{
-			pAd->HTCEnable = TRUE;
-			pAd->bLinkAdapt = TRUE;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Link Adaptation Control = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
-	}
-
-	// Reverse Direction Mechanism
-    if (RTMPGetKeyParameter("HT_RDG", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-		if (Value == 0)
-		{
-			pAd->CommonCfg.bRdg = FALSE;
-		}
-		else
-		{
-			pAd->HTCEnable = TRUE;
-            pAd->CommonCfg.bRdg = TRUE;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: RDG = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
-	}
-
-
-
-
-	// Tx A-MSUD ?
-    if (RTMPGetKeyParameter("HT_AMSDU", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-		if (Value == 0)
-		{
-			pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE;
-		}
-		else
-		{
-            pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx A-MSDU = %s\n", (Value==0) ? "Disable" : "Enable"));
-	}
-
-	// MPDU Density
-    if (RTMPGetKeyParameter("HT_MpduDensity", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-		if (Value <=7 && Value >= 0)
-		{
-			pAd->CommonCfg.BACapability.field.MpduDensity = Value;
-			DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d\n", Value));
-		}
-		else
-		{
-			pAd->CommonCfg.BACapability.field.MpduDensity = 4;
-			DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d (Default)\n", 4));
-		}
-	}
-
-	// Max Rx BA Window Size
-    if (RTMPGetKeyParameter("HT_BAWinSize", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-
-		if (Value >=1 && Value <= 64)
-		{
-			pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value;
-			pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value;
-			DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = %d\n", Value));
-		}
-		else
-		{
-            pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64;
-			pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;
-			DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = 64 (Defualt)\n"));
-		}
-
-	}
-
-	// Guard Interval
-	if (RTMPGetKeyParameter("HT_GI", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-
-		if (Value == GI_400)
-		{
-			pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400;
-		}
-		else
-		{
-			pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Guard Interval = %s\n", (Value==GI_400) ? "400" : "800" ));
-	}
-
-	// HT Operation Mode : Mixed Mode , Green Field
-	if (RTMPGetKeyParameter("HT_OpMode", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-
-		if (Value == HTMODE_GF)
-		{
-
-			pAd->CommonCfg.RegTransmitSetting.field.HTMODE  = HTMODE_GF;
-		}
-		else
-		{
-			pAd->CommonCfg.RegTransmitSetting.field.HTMODE  = HTMODE_MM;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Operate Mode = %s\n", (Value==HTMODE_GF) ? "Green Field" : "Mixed Mode" ));
-	}
-
-	// Fixed Tx mode : CCK, OFDM
-	if (RTMPGetKeyParameter("FixedTxMode", pValueStr, 25, pInput))
-	{
-		UCHAR	fix_tx_mode;
-
-		{
-			fix_tx_mode = FIXED_TXMODE_HT;
-
-			if (strcmp(pValueStr, "OFDM") == 0 || strcmp(pValueStr, "ofdm") == 0)
-			{
-				fix_tx_mode = FIXED_TXMODE_OFDM;
-			}
-			else if (strcmp(pValueStr, "CCK") == 0 || strcmp(pValueStr, "cck") == 0)
-			{
-		        fix_tx_mode = FIXED_TXMODE_CCK;
-			}
-			else if (strcmp(pValueStr, "HT") == 0 || strcmp(pValueStr, "ht") == 0)
-			{
-		        fix_tx_mode = FIXED_TXMODE_HT;
-		}
-		else
-		{
-				Value = simple_strtol(pValueStr, 0, 10);
-				// 1 : CCK
-				// 2 : OFDM
-				// otherwise : HT
-				if (Value == FIXED_TXMODE_CCK || Value == FIXED_TXMODE_OFDM)
-					fix_tx_mode = Value;
-				else
-					fix_tx_mode = FIXED_TXMODE_HT;
-		}
-
-			pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode;
-			DBGPRINT(RT_DEBUG_TRACE, ("Fixed Tx Mode = %d\n", fix_tx_mode));
-
-		}
-	}
-
-
-	// Channel Width
-	if (RTMPGetKeyParameter("HT_BW", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-
-		if (Value == BW_40)
-		{
-			pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_40;
-		}
-		else
-		{
-            pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_20;
-		}
-
-#ifdef MCAST_RATE_SPECIFIC
-		pAd->CommonCfg.MCastPhyMode.field.BW = pAd->CommonCfg.RegTransmitSetting.field.BW;
-#endif // MCAST_RATE_SPECIFIC //
-
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Channel Width = %s\n", (Value==BW_40) ? "40 MHz" : "20 MHz" ));
-	}
-
-	if (RTMPGetKeyParameter("HT_EXTCHA", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-
-		if (Value == 0)
-		{
-
-			pAd->CommonCfg.RegTransmitSetting.field.EXTCHA  = EXTCHA_BELOW;
-		}
-		else
-		{
-            pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Ext Channel = %s\n", (Value==0) ? "BELOW" : "ABOVE" ));
-	}
-
-	// MSC
-	if (RTMPGetKeyParameter("HT_MCS", pValueStr, 50, pInput))
-	{
-		{
-			Value = simple_strtol(pValueStr, 0, 10);
-
-			if ((Value >= 0 && Value <= 23) || (Value == 32)) // 3*3
-		{
-				pAd->StaCfg.DesiredTransmitSetting.field.MCS  = Value;
-				pAd->StaCfg.bAutoTxRateSwitch = FALSE;
-				DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = %d\n", pAd->StaCfg.DesiredTransmitSetting.field.MCS));
-		}
-		else
-		{
-				pAd->StaCfg.DesiredTransmitSetting.field.MCS  = MCS_AUTO;
-				pAd->StaCfg.bAutoTxRateSwitch = TRUE;
-				DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = AUTO\n"));
-		}
-	}
-	}
-
-	// STBC
-    if (RTMPGetKeyParameter("HT_STBC", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-		if (Value == STBC_USE)
-		{
-			pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE;
-		}
-		else
-		{
-			pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: STBC = %d\n", pAd->CommonCfg.RegTransmitSetting.field.STBC));
-	}
-
-	// 40_Mhz_Intolerant
-	if (RTMPGetKeyParameter("HT_40MHZ_INTOLERANT", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-		if (Value == 0)
-		{
-			pAd->CommonCfg.bForty_Mhz_Intolerant = FALSE;
-		}
-		else
-		{
-			pAd->CommonCfg.bForty_Mhz_Intolerant = TRUE;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: 40MHZ INTOLERANT = %d\n", pAd->CommonCfg.bForty_Mhz_Intolerant));
-	}
-	//HT_TxStream
-	if(RTMPGetKeyParameter("HT_TxStream", pValueStr, 10, pInput))
-	{
-		switch (simple_strtol(pValueStr, 0, 10))
-		{
-			case 1:
-				pAd->CommonCfg.TxStream = 1;
-				break;
-			case 2:
-				pAd->CommonCfg.TxStream = 2;
-				break;
-			case 3: // 3*3
-			default:
-				pAd->CommonCfg.TxStream = 3;
-
-				if (pAd->MACVersion < RALINK_2883_VERSION)
-					pAd->CommonCfg.TxStream = 2; // only 2 tx streams for RT2860 series
-				break;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx Stream = %d\n", pAd->CommonCfg.TxStream));
-	}
-	//HT_RxStream
-	if(RTMPGetKeyParameter("HT_RxStream", pValueStr, 10, pInput))
-	{
-		switch (simple_strtol(pValueStr, 0, 10))
-		{
-			case 1:
-				pAd->CommonCfg.RxStream = 1;
-				break;
-			case 2:
-				pAd->CommonCfg.RxStream = 2;
-				break;
-			case 3:
-			default:
-				pAd->CommonCfg.RxStream = 3;
-
-				if (pAd->MACVersion < RALINK_2883_VERSION)
-					pAd->CommonCfg.RxStream = 2; // only 2 rx streams for RT2860 series
-				break;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Rx Stream = %d\n", pAd->CommonCfg.RxStream));
-	}
-
-}
diff --git a/drivers/staging/rt2860/rt_usb.c b/drivers/staging/rt2860/rt_usb.c
new file mode 100644
index 0000000..01a7eb4
--- /dev/null
+++ b/drivers/staging/rt2860/rt_usb.c
@@ -0,0 +1,799 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rtusb_bulk.c
+
+	Abstract:
+
+	Revision History:
+	Who			When		What
+	--------	----------	----------------------------------------------
+	Name		Date		Modification logs
+
+*/
+
+#include "rt_config.h"
+
+void dump_urb(struct urb *purb)
+{
+	printk("urb                  :0x%08lx\n", (unsigned long)purb);
+	printk("\tdev                   :0x%08lx\n", (unsigned long)purb->dev);
+	printk("\t\tdev->state          :0x%d\n", purb->dev->state);
+	printk("\tpipe                  :0x%08x\n", purb->pipe);
+	printk("\tstatus                :%d\n", purb->status);
+	printk("\ttransfer_flags        :0x%08x\n", purb->transfer_flags);
+	printk("\ttransfer_buffer       :0x%08lx\n",
+	       (unsigned long)purb->transfer_buffer);
+	printk("\ttransfer_buffer_length:%d\n", purb->transfer_buffer_length);
+	printk("\tactual_length         :%d\n", purb->actual_length);
+	printk("\tsetup_packet          :0x%08lx\n",
+	       (unsigned long)purb->setup_packet);
+	printk("\tstart_frame           :%d\n", purb->start_frame);
+	printk("\tnumber_of_packets     :%d\n", purb->number_of_packets);
+	printk("\tinterval              :%d\n", purb->interval);
+	printk("\terror_count           :%d\n", purb->error_count);
+	printk("\tcontext               :0x%08lx\n",
+	       (unsigned long)purb->context);
+	printk("\tcomplete              :0x%08lx\n\n",
+	       (unsigned long)purb->complete);
+}
+
+/*
+========================================================================
+Routine Description:
+    Create kernel threads & tasklets.
+
+Arguments:
+    *net_dev			Pointer to wireless net device interface
+
+Return Value:
+	NDIS_STATUS_SUCCESS
+	NDIS_STATUS_FAILURE
+
+Note:
+========================================================================
+*/
+int RtmpMgmtTaskInit(struct rt_rtmp_adapter *pAd)
+{
+	struct rt_rtmp_os_task *pTask;
+	int status;
+
+	/*
+	   Creat TimerQ Thread, We need init timerQ related structure before create the timer thread.
+	 */
+	RtmpTimerQInit(pAd);
+
+	pTask = &pAd->timerTask;
+	RtmpOSTaskInit(pTask, "RtmpTimerTask", pAd);
+	status = RtmpOSTaskAttach(pTask, RtmpTimerQThread, pTask);
+	if (status == NDIS_STATUS_FAILURE) {
+		printk(KERN_WARNING "%s: unable to start RtmpTimerQThread\n",
+		       RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev));
+		return NDIS_STATUS_FAILURE;
+	}
+
+	/* Creat MLME Thread */
+	pTask = &pAd->mlmeTask;
+	RtmpOSTaskInit(pTask, "RtmpMlmeTask", pAd);
+	status = RtmpOSTaskAttach(pTask, MlmeThread, pTask);
+	if (status == NDIS_STATUS_FAILURE) {
+		printk(KERN_WARNING "%s: unable to start MlmeThread\n",
+		       RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev));
+		return NDIS_STATUS_FAILURE;
+	}
+
+	/* Creat Command Thread */
+	pTask = &pAd->cmdQTask;
+	RtmpOSTaskInit(pTask, "RtmpCmdQTask", pAd);
+	status = RtmpOSTaskAttach(pTask, RTUSBCmdThread, pTask);
+	if (status == NDIS_STATUS_FAILURE) {
+		printk(KERN_WARNING "%s: unable to start RTUSBCmdThread\n",
+		       RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev));
+		return NDIS_STATUS_FAILURE;
+	}
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+/*
+========================================================================
+Routine Description:
+    Close kernel threads.
+
+Arguments:
+	*pAd				the raxx interface data pointer
+
+Return Value:
+    NONE
+
+Note:
+========================================================================
+*/
+void RtmpMgmtTaskExit(struct rt_rtmp_adapter *pAd)
+{
+	int ret;
+	struct rt_rtmp_os_task *pTask;
+
+	/* Sleep 50 milliseconds so pending io might finish normally */
+	RTMPusecDelay(50000);
+
+	/* We want to wait until all pending receives and sends to the */
+	/* device object. We cancel any */
+	/* irps. Wait until sends and receives have stopped. */
+	RTUSBCancelPendingIRPs(pAd);
+
+	/* We need clear timerQ related structure before exits of the timer thread. */
+	RtmpTimerQExit(pAd);
+
+	/* Terminate Mlme Thread */
+	pTask = &pAd->mlmeTask;
+	ret = RtmpOSTaskKill(pTask);
+	if (ret == NDIS_STATUS_FAILURE) {
+		DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n",
+					  RTMP_OS_NETDEV_GET_DEVNAME(pAd->
+								     net_dev),
+					  pTask->taskName));
+	}
+
+	/* Terminate cmdQ thread */
+	pTask = &pAd->cmdQTask;
+#ifdef KTHREAD_SUPPORT
+	if (pTask->kthread_task)
+#else
+	CHECK_PID_LEGALITY(pTask->taskPID)
+#endif
+	{
+		mb();
+		NdisAcquireSpinLock(&pAd->CmdQLock);
+		pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED;
+		NdisReleaseSpinLock(&pAd->CmdQLock);
+		mb();
+		/*RTUSBCMDUp(pAd); */
+		ret = RtmpOSTaskKill(pTask);
+		if (ret == NDIS_STATUS_FAILURE) {
+			DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n",
+						  RTMP_OS_NETDEV_GET_DEVNAME
+						  (pAd->net_dev),
+						  pTask->taskName));
+		}
+		pAd->CmdQ.CmdQState = RTMP_TASK_STAT_UNKNOWN;
+	}
+
+	/* Terminate timer thread */
+	pTask = &pAd->timerTask;
+	ret = RtmpOSTaskKill(pTask);
+	if (ret == NDIS_STATUS_FAILURE) {
+		DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n",
+					  RTMP_OS_NETDEV_GET_DEVNAME(pAd->
+								     net_dev),
+					  pTask->taskName));
+	}
+
+}
+
+static void rtusb_dataout_complete(unsigned long data)
+{
+	struct rt_rtmp_adapter *pAd;
+	struct urb *pUrb;
+	struct os_cookie *pObj;
+	struct rt_ht_tx_context *pHTTXContext;
+	u8 BulkOutPipeId;
+	int Status;
+	unsigned long IrqFlags;
+
+	pUrb = (struct urb *)data;
+	pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
+	pAd = pHTTXContext->pAd;
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
+	Status = pUrb->status;
+
+	/* Store BulkOut PipeId */
+	BulkOutPipeId = pHTTXContext->BulkOutPipeId;
+	pAd->BulkOutDataOneSecCount++;
+
+	/*DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition, */
+	/*              pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); */
+
+	RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+	pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+	pHTTXContext->IRPPending = FALSE;
+	pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
+
+	if (Status == USB_ST_NOERROR) {
+		pAd->BulkOutComplete++;
+
+		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+		pAd->Counters8023.GoodTransmits++;
+		/*RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */
+		FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext);
+		/*RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */
+
+	} else			/* STATUS_OTHER */
+	{
+		u8 *pBuf;
+
+		pAd->BulkOutCompleteOther++;
+
+		pBuf =
+		    &pHTTXContext->TransferBuffer->field.
+		    WirelessPacket[pHTTXContext->NextBulkOutPosition];
+
+		if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+					  fRTMP_ADAPTER_HALT_IN_PROGRESS |
+					  fRTMP_ADAPTER_NIC_NOT_EXIST |
+					  fRTMP_ADAPTER_BULKOUT_RESET))) {
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+			pAd->bulkResetPipeid = BulkOutPipeId;
+			pAd->bulkResetReq[BulkOutPipeId] = pAd->BulkOutReq;
+		}
+		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+		DBGPRINT_RAW(RT_DEBUG_ERROR,
+			     ("BulkOutDataPacket failed: ReasonCode=%d!\n",
+			      Status));
+		DBGPRINT_RAW(RT_DEBUG_ERROR,
+			     ("\t>>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n",
+			      pAd->BulkOutReq, pAd->BulkOutComplete,
+			      pAd->BulkOutCompleteOther));
+		DBGPRINT_RAW(RT_DEBUG_ERROR,
+			     ("\t>>BulkOut Header:%x %x %x %x %x %x %x %x\n",
+			      pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4],
+			      pBuf[5], pBuf[6], pBuf[7]));
+		/*DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther)); */
+
+	}
+
+	/* */
+	/* bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut */
+	/* bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out. */
+	/* */
+	/*RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */
+	if ((pHTTXContext->ENextBulkOutPosition !=
+	     pHTTXContext->CurWritePosition)
+	    && (pHTTXContext->ENextBulkOutPosition !=
+		(pHTTXContext->CurWritePosition + 8))
+	    && !RTUSB_TEST_BULK_FLAG(pAd,
+				     (fRTUSB_BULK_OUT_DATA_FRAG <<
+				      BulkOutPipeId))) {
+		/* Indicate There is data avaliable */
+		RTUSB_SET_BULK_FLAG(pAd,
+				    (fRTUSB_BULK_OUT_DATA_NORMAL <<
+				     BulkOutPipeId));
+	}
+	/*RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */
+
+	/* Always call Bulk routine, even reset bulk. */
+	/* The protection of rest bulk should be in BulkOut routine */
+	RTUSBKickBulkOut(pAd);
+}
+
+static void rtusb_null_frame_done_tasklet(unsigned long data)
+{
+	struct rt_rtmp_adapter *pAd;
+	struct rt_tx_context *pNullContext;
+	struct urb *pUrb;
+	int Status;
+	unsigned long irqFlag;
+
+	pUrb = (struct urb *)data;
+	pNullContext = (struct rt_tx_context *)pUrb->context;
+	pAd = pNullContext->pAd;
+	Status = pUrb->status;
+
+	/* Reset Null frame context flags */
+	RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
+	pNullContext->IRPPending = FALSE;
+	pNullContext->InUse = FALSE;
+	pAd->BulkOutPending[0] = FALSE;
+	pAd->watchDogTxPendingCnt[0] = 0;
+
+	if (Status == USB_ST_NOERROR) {
+		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+
+		RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+	} else			/* STATUS_OTHER */
+	{
+		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) {
+			DBGPRINT_RAW(RT_DEBUG_ERROR,
+				     ("Bulk Out Null Frame Failed, ReasonCode=%d!\n",
+				      Status));
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+			pAd->bulkResetPipeid =
+			    (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
+			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
+						NULL, 0);
+		} else {
+			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+		}
+	}
+
+	/* Always call Bulk routine, even reset bulk. */
+	/* The protectioon of rest bulk should be in BulkOut routine */
+	RTUSBKickBulkOut(pAd);
+}
+
+static void rtusb_rts_frame_done_tasklet(unsigned long data)
+{
+	struct rt_rtmp_adapter *pAd;
+	struct rt_tx_context *pRTSContext;
+	struct urb *pUrb;
+	int Status;
+	unsigned long irqFlag;
+
+	pUrb = (struct urb *)data;
+	pRTSContext = (struct rt_tx_context *)pUrb->context;
+	pAd = pRTSContext->pAd;
+	Status = pUrb->status;
+
+	/* Reset RTS frame context flags */
+	RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
+	pRTSContext->IRPPending = FALSE;
+	pRTSContext->InUse = FALSE;
+
+	if (Status == USB_ST_NOERROR) {
+		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+		RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+	} else			/* STATUS_OTHER */
+	{
+		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) {
+			DBGPRINT_RAW(RT_DEBUG_ERROR,
+				     ("Bulk Out RTS Frame Failed\n"));
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+			pAd->bulkResetPipeid =
+			    (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
+			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
+						NULL, 0);
+		} else {
+			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+		}
+	}
+
+	RTMP_SEM_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
+	pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE;
+	RTMP_SEM_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
+
+	/* Always call Bulk routine, even reset bulk. */
+	/* The protectioon of rest bulk should be in BulkOut routine */
+	RTUSBKickBulkOut(pAd);
+
+}
+
+static void rtusb_pspoll_frame_done_tasklet(unsigned long data)
+{
+	struct rt_rtmp_adapter *pAd;
+	struct rt_tx_context *pPsPollContext;
+	struct urb *pUrb;
+	int Status;
+
+	pUrb = (struct urb *)data;
+	pPsPollContext = (struct rt_tx_context *)pUrb->context;
+	pAd = pPsPollContext->pAd;
+	Status = pUrb->status;
+
+	/* Reset PsPoll context flags */
+	pPsPollContext->IRPPending = FALSE;
+	pPsPollContext->InUse = FALSE;
+	pAd->watchDogTxPendingCnt[0] = 0;
+
+	if (Status == USB_ST_NOERROR) {
+		RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+	} else			/* STATUS_OTHER */
+	{
+		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) {
+			DBGPRINT_RAW(RT_DEBUG_ERROR,
+				     ("Bulk Out PSPoll Failed\n"));
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+			pAd->bulkResetPipeid =
+			    (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
+						NULL, 0);
+		}
+	}
+
+	RTMP_SEM_LOCK(&pAd->BulkOutLock[0]);
+	pAd->BulkOutPending[0] = FALSE;
+	RTMP_SEM_UNLOCK(&pAd->BulkOutLock[0]);
+
+	/* Always call Bulk routine, even reset bulk. */
+	/* The protectioon of rest bulk should be in BulkOut routine */
+	RTUSBKickBulkOut(pAd);
+
+}
+
+/*
+========================================================================
+Routine Description:
+    Handle received packets.
+
+Arguments:
+	data				- URB information pointer
+
+Return Value:
+    None
+
+Note:
+========================================================================
+*/
+static void rx_done_tasklet(unsigned long data)
+{
+	struct urb *pUrb;
+	struct rt_rx_context *pRxContext;
+	struct rt_rtmp_adapter *pAd;
+	int Status;
+	unsigned int IrqFlags;
+
+	pUrb = (struct urb *)data;
+	pRxContext = (struct rt_rx_context *)pUrb->context;
+	pAd = pRxContext->pAd;
+	Status = pUrb->status;
+
+	RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+	pRxContext->InUse = FALSE;
+	pRxContext->IRPPending = FALSE;
+	pRxContext->BulkInOffset += pUrb->actual_length;
+	/*NdisInterlockedDecrement(&pAd->PendingRx); */
+	pAd->PendingRx--;
+
+	if (Status == USB_ST_NOERROR) {
+		pAd->BulkInComplete++;
+		pAd->NextRxBulkInPosition = 0;
+		if (pRxContext->BulkInOffset)	/* As jan's comment, it may bulk-in success but size is zero. */
+		{
+			pRxContext->Readable = TRUE;
+			INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
+		}
+		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+	} else			/* STATUS_OTHER */
+	{
+		pAd->BulkInCompleteFail++;
+		/* Still read this packet although it may comtain wrong bytes. */
+		pRxContext->Readable = FALSE;
+		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+
+		/* Parsing all packets. because after reset, the index will reset to all zero. */
+		if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+					   fRTMP_ADAPTER_BULKIN_RESET |
+					   fRTMP_ADAPTER_HALT_IN_PROGRESS |
+					   fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
+
+			DBGPRINT_RAW(RT_DEBUG_ERROR,
+				     ("Bulk In Failed. Status=%d, BIIdx=0x%x, BIRIdx=0x%x, actual_length= 0x%x\n",
+				      Status, pAd->NextRxBulkInIndex,
+				      pAd->NextRxBulkInReadIndex,
+				      pRxContext->pUrb->actual_length));
+
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN,
+						NULL, 0);
+		}
+	}
+
+	ASSERT((pRxContext->InUse == pRxContext->IRPPending));
+
+	RTUSBBulkReceive(pAd);
+
+	return;
+
+}
+
+static void rtusb_mgmt_dma_done_tasklet(unsigned long data)
+{
+	struct rt_rtmp_adapter *pAd;
+	struct rt_tx_context *pMLMEContext;
+	int index;
+	void *pPacket;
+	struct urb *pUrb;
+	int Status;
+	unsigned long IrqFlags;
+
+	pUrb = (struct urb *)data;
+	pMLMEContext = (struct rt_tx_context *)pUrb->context;
+	pAd = pMLMEContext->pAd;
+	Status = pUrb->status;
+	index = pMLMEContext->SelfIdx;
+
+	ASSERT((pAd->MgmtRing.TxDmaIdx == index));
+
+	RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+
+	if (Status != USB_ST_NOERROR) {
+		/*Bulk-Out fail status handle */
+		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) {
+			DBGPRINT_RAW(RT_DEBUG_ERROR,
+				     ("Bulk Out MLME Failed, Status=%d!\n",
+				      Status));
+			/* TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt? */
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+			pAd->bulkResetPipeid =
+			    (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
+		}
+	}
+
+	pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
+	RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+
+	RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
+	/* Reset MLME context flags */
+	pMLMEContext->IRPPending = FALSE;
+	pMLMEContext->InUse = FALSE;
+	pMLMEContext->bWaitingBulkOut = FALSE;
+	pMLMEContext->BulkOutSize = 0;
+
+	pPacket = pAd->MgmtRing.Cell[index].pNdisPacket;
+	pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
+
+	/* Increase MgmtRing Index */
+	INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE);
+	pAd->MgmtRing.TxSwFreeIdx++;
+	RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
+
+	/* No-matter success or fail, we free the mgmt packet. */
+	if (pPacket)
+		RTMPFreeNdisPacket(pAd, pPacket);
+
+	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+				  fRTMP_ADAPTER_HALT_IN_PROGRESS |
+				  fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
+		/* do nothing and return directly. */
+	} else {
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET) && ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG)) {	/* For Mgmt Bulk-Out failed, ignore it now. */
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
+						NULL, 0);
+		} else {
+
+			/* Always call Bulk routine, even reset bulk. */
+			/* The protectioon of rest bulk should be in BulkOut routine */
+			if (pAd->MgmtRing.TxSwFreeIdx <
+			    MGMT_RING_SIZE
+			    /* pMLMEContext->bWaitingBulkOut == TRUE */ ) {
+				RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
+			}
+			RTUSBKickBulkOut(pAd);
+		}
+	}
+
+}
+
+static void rtusb_ac3_dma_done_tasklet(unsigned long data)
+{
+	struct rt_rtmp_adapter *pAd;
+	struct rt_ht_tx_context *pHTTXContext;
+	u8 BulkOutPipeId = 3;
+	struct urb *pUrb;
+
+	pUrb = (struct urb *)data;
+	pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
+	pAd = pHTTXContext->pAd;
+
+	rtusb_dataout_complete((unsigned long)pUrb);
+
+	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+				  fRTMP_ADAPTER_HALT_IN_PROGRESS |
+				  fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
+		/* do nothing and return directly. */
+	} else {
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) {
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
+						NULL, 0);
+		} else {
+			pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
+			    /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
+			    (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
+			    (pHTTXContext->bCurWriting == FALSE)) {
+				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId,
+						  MAX_TX_PROCESS);
+			}
+
+			RTUSB_SET_BULK_FLAG(pAd,
+					    fRTUSB_BULK_OUT_DATA_NORMAL << 3);
+			RTUSBKickBulkOut(pAd);
+		}
+	}
+
+	return;
+}
+
+static void rtusb_ac2_dma_done_tasklet(unsigned long data)
+{
+	struct rt_rtmp_adapter *pAd;
+	struct rt_ht_tx_context *pHTTXContext;
+	u8 BulkOutPipeId = 2;
+	struct urb *pUrb;
+
+	pUrb = (struct urb *)data;
+	pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
+	pAd = pHTTXContext->pAd;
+
+	rtusb_dataout_complete((unsigned long)pUrb);
+
+	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+				  fRTMP_ADAPTER_HALT_IN_PROGRESS |
+				  fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
+		/* do nothing and return directly. */
+	} else {
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) {
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
+						NULL, 0);
+		} else {
+			pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
+			    /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
+			    (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
+			    (pHTTXContext->bCurWriting == FALSE)) {
+				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId,
+						  MAX_TX_PROCESS);
+			}
+
+			RTUSB_SET_BULK_FLAG(pAd,
+					    fRTUSB_BULK_OUT_DATA_NORMAL << 2);
+			RTUSBKickBulkOut(pAd);
+		}
+	}
+
+	return;
+}
+
+static void rtusb_ac1_dma_done_tasklet(unsigned long data)
+{
+	struct rt_rtmp_adapter *pAd;
+	struct rt_ht_tx_context *pHTTXContext;
+	u8 BulkOutPipeId = 1;
+	struct urb *pUrb;
+
+	pUrb = (struct urb *)data;
+	pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
+	pAd = pHTTXContext->pAd;
+
+	rtusb_dataout_complete((unsigned long)pUrb);
+
+	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+				  fRTMP_ADAPTER_HALT_IN_PROGRESS |
+				  fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
+		/* do nothing and return directly. */
+	} else {
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) {
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
+						NULL, 0);
+		} else {
+			pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
+			    /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
+			    (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
+			    (pHTTXContext->bCurWriting == FALSE)) {
+				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId,
+						  MAX_TX_PROCESS);
+			}
+
+			RTUSB_SET_BULK_FLAG(pAd,
+					    fRTUSB_BULK_OUT_DATA_NORMAL << 1);
+			RTUSBKickBulkOut(pAd);
+		}
+	}
+	return;
+
+}
+
+static void rtusb_ac0_dma_done_tasklet(unsigned long data)
+{
+	struct rt_rtmp_adapter *pAd;
+	struct rt_ht_tx_context *pHTTXContext;
+	u8 BulkOutPipeId = 0;
+	struct urb *pUrb;
+
+	pUrb = (struct urb *)data;
+	pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
+	pAd = pHTTXContext->pAd;
+
+	rtusb_dataout_complete((unsigned long)pUrb);
+
+	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+				  fRTMP_ADAPTER_HALT_IN_PROGRESS |
+				  fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
+		/* do nothing and return directly. */
+	} else {
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) {
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
+						NULL, 0);
+		} else {
+			pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
+			    /*  ((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
+			    (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
+			    (pHTTXContext->bCurWriting == FALSE)) {
+				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId,
+						  MAX_TX_PROCESS);
+			}
+
+			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL);
+			RTUSBKickBulkOut(pAd);
+		}
+	}
+
+	return;
+
+}
+
+int RtmpNetTaskInit(struct rt_rtmp_adapter *pAd)
+{
+	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	/* Create receive tasklet */
+	tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->mgmt_dma_done_task, rtusb_mgmt_dma_done_tasklet,
+		     (unsigned long)pAd);
+	tasklet_init(&pObj->ac0_dma_done_task, rtusb_ac0_dma_done_tasklet,
+		     (unsigned long)pAd);
+	tasklet_init(&pObj->ac1_dma_done_task, rtusb_ac1_dma_done_tasklet,
+		     (unsigned long)pAd);
+	tasklet_init(&pObj->ac2_dma_done_task, rtusb_ac2_dma_done_tasklet,
+		     (unsigned long)pAd);
+	tasklet_init(&pObj->ac3_dma_done_task, rtusb_ac3_dma_done_tasklet,
+		     (unsigned long)pAd);
+	tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->null_frame_complete_task,
+		     rtusb_null_frame_done_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->rts_frame_complete_task,
+		     rtusb_rts_frame_done_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->pspoll_frame_complete_task,
+		     rtusb_pspoll_frame_done_tasklet, (unsigned long)pAd);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+void RtmpNetTaskExit(struct rt_rtmp_adapter *pAd)
+{
+	struct os_cookie *pObj;
+
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	tasklet_kill(&pObj->rx_done_task);
+	tasklet_kill(&pObj->mgmt_dma_done_task);
+	tasklet_kill(&pObj->ac0_dma_done_task);
+	tasklet_kill(&pObj->ac1_dma_done_task);
+	tasklet_kill(&pObj->ac2_dma_done_task);
+	tasklet_kill(&pObj->ac3_dma_done_task);
+	tasklet_kill(&pObj->tbtt_task);
+	tasklet_kill(&pObj->null_frame_complete_task);
+	tasklet_kill(&pObj->rts_frame_complete_task);
+	tasklet_kill(&pObj->pspoll_frame_complete_task);
+}
diff --git a/drivers/staging/rt2860/rtmp.h b/drivers/staging/rt2860/rtmp.h
index 90fd40f..c50abf4 100644
--- a/drivers/staging/rt2860/rtmp.h
+++ b/drivers/staging/rt2860/rtmp.h
@@ -41,270 +41,136 @@
 #define __RTMP_H__
 
 #include "spectrum_def.h"
+#include "rtmp_dot11.h"
+#include "rtmp_chip.h"
 
-#include "aironet.h"
+struct rt_rtmp_adapter;
 
-#define VIRTUAL_IF_INC(__pAd) ((__pAd)->VirtualIfCnt++)
-#define VIRTUAL_IF_DEC(__pAd) ((__pAd)->VirtualIfCnt--)
-#define VIRTUAL_IF_NUM(__pAd) ((__pAd)->VirtualIfCnt)
+/*#define DBG           1 */
 
-#ifdef RT2870
-////////////////////////////////////////////////////////////////////////////
-// The TX_BUFFER structure forms the transmitted USB packet to the device
-////////////////////////////////////////////////////////////////////////////
-typedef struct __TX_BUFFER{
-	union	{
-		UCHAR			WirelessPacket[TX_BUFFER_NORMSIZE];
-		HEADER_802_11	NullFrame;
-		PSPOLL_FRAME	PsPollPacket;
-		RTS_FRAME		RTSFrame;
-	}field;
-	UCHAR			Aggregation[4];  //Buffer for save Aggregation size.
-} TX_BUFFER, *PTX_BUFFER;
+/*#define DBG_DIAGNOSE          1 */
 
-typedef struct __HTTX_BUFFER{
-	union	{
-		UCHAR			WirelessPacket[MAX_TXBULK_SIZE];
-		HEADER_802_11	NullFrame;
-		PSPOLL_FRAME	PsPollPacket;
-		RTS_FRAME		RTSFrame;
-	}field;
-	UCHAR			Aggregation[4];  //Buffer for save Aggregation size.
-} HTTX_BUFFER, *PHTTX_BUFFER;
-
-
-// used to track driver-generated write irps
-typedef struct _TX_CONTEXT
-{
-	PVOID			pAd;		//Initialized in MiniportInitialize
-	PURB			pUrb;			//Initialized in MiniportInitialize
-	PIRP			pIrp;			//used to cancel pending bulk out.
-									//Initialized in MiniportInitialize
-	PTX_BUFFER		TransferBuffer;	//Initialized in MiniportInitialize
-	ULONG			BulkOutSize;
-	UCHAR			BulkOutPipeId;
-	UCHAR			SelfIdx;
-	BOOLEAN			InUse;
-	BOOLEAN			bWaitingBulkOut; // at least one packet is in this TxContext, ready for making IRP anytime.
-	BOOLEAN			bFullForBulkOut; // all tx buffer are full , so waiting for tx bulkout.
-	BOOLEAN			IRPPending;
-	BOOLEAN			LastOne;
-	BOOLEAN			bAggregatible;
-	UCHAR			Header_802_3[LENGTH_802_3];
-	UCHAR			Rsv[2];
-	ULONG			DataOffset;
-	UINT			TxRate;
-	dma_addr_t		data_dma;		// urb dma on linux
-
-}	TX_CONTEXT, *PTX_CONTEXT, **PPTX_CONTEXT;
-
-
-// used to track driver-generated write irps
-typedef struct _HT_TX_CONTEXT
-{
-	PVOID			pAd;		//Initialized in MiniportInitialize
-	PURB			pUrb;			//Initialized in MiniportInitialize
-	PIRP			pIrp;			//used to cancel pending bulk out.
-									//Initialized in MiniportInitialize
-	PHTTX_BUFFER	TransferBuffer;	//Initialized in MiniportInitialize
-	ULONG			BulkOutSize;	// Indicate the total bulk-out size in bytes in one bulk-transmission
-	UCHAR			BulkOutPipeId;
-	BOOLEAN			IRPPending;
-	BOOLEAN			LastOne;
-	BOOLEAN			bCurWriting;
-	BOOLEAN			bRingEmpty;
-	BOOLEAN			bCopySavePad;
-	UCHAR			SavedPad[8];
-	UCHAR			Header_802_3[LENGTH_802_3];
-	ULONG			CurWritePosition;		// Indicate the buffer offset which packet will be inserted start from.
-	ULONG			CurWriteRealPos;		// Indicate the buffer offset which packet now are writing to.
-	ULONG			NextBulkOutPosition;	// Indicate the buffer start offset of a bulk-transmission
-	ULONG			ENextBulkOutPosition;	// Indicate the buffer end offset of a bulk-transmission
-	UINT			TxRate;
-	dma_addr_t		data_dma;		// urb dma on linux
-}	HT_TX_CONTEXT, *PHT_TX_CONTEXT, **PPHT_TX_CONTEXT;
-
-
-//
-// Structure to keep track of receive packets and buffers to indicate
-// receive data to the protocol.
-//
-typedef struct _RX_CONTEXT
-{
-	PUCHAR				TransferBuffer;
-	PVOID				pAd;
-	PIRP				pIrp;//used to cancel pending bulk in.
-	PURB				pUrb;
-	//These 2 Boolean shouldn't both be 1 at the same time.
-	ULONG				BulkInOffset;	// number of packets waiting for reordering .
-	BOOLEAN				bRxHandling;	// Notify this packet is being process now.
-	BOOLEAN				InUse;			// USB Hardware Occupied. Wait for USB HW to put packet.
-	BOOLEAN				Readable;		// Receive Complete back. OK for driver to indicate receiving packet.
-	BOOLEAN				IRPPending;		// TODO: To be removed
-	atomic_t			IrpLock;
-	NDIS_SPIN_LOCK		RxContextLock;
-	dma_addr_t			data_dma;		// urb dma on linux
-}	RX_CONTEXT, *PRX_CONTEXT;
-#endif // RT2870 //
-
-
-//
-//  NDIS Version definitions
-//
-#ifdef  NDIS50_MINIPORT
-#define RTMP_NDIS_MAJOR_VERSION     5
-#define RTMP_NDIS_MINOR_VERSION     0
-#endif
-
-#ifdef  NDIS51_MINIPORT
-#define RTMP_NDIS_MAJOR_VERSION     5
-#define RTMP_NDIS_MINOR_VERSION     1
-#endif
-
-extern  char    NIC_VENDOR_DESC[];
-extern  int     NIC_VENDOR_DESC_LEN;
-
-extern  unsigned char   SNAP_AIRONET[];
-extern  unsigned char   CipherSuiteCiscoCCKM[];
-extern  unsigned char   CipherSuiteCiscoCCKMLen;
-extern	unsigned char	CipherSuiteCiscoCCKM24[];
-extern	unsigned char	CipherSuiteCiscoCCKM24Len;
-extern  unsigned char   CipherSuiteCCXTkip[];
-extern  unsigned char   CipherSuiteCCXTkipLen;
-extern  unsigned char   CISCO_OUI[];
-extern  UCHAR	BaSizeArray[4];
-
-extern UCHAR BROADCAST_ADDR[MAC_ADDR_LEN];
-extern UCHAR MULTICAST_ADDR[MAC_ADDR_LEN];
-extern UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN];
-extern ULONG BIT32[32];
-extern UCHAR BIT8[8];
-extern char* CipherName[];
-extern char* MCSToMbps[];
-extern UCHAR	 RxwiMCSToOfdmRate[12];
-extern UCHAR SNAP_802_1H[6];
-extern UCHAR SNAP_BRIDGE_TUNNEL[6];
-extern UCHAR SNAP_AIRONET[8];
-extern UCHAR CKIP_LLC_SNAP[8];
-extern UCHAR EAPOL_LLC_SNAP[8];
-extern UCHAR EAPOL[2];
-extern UCHAR IPX[2];
-extern UCHAR APPLE_TALK[2];
-extern UCHAR RateIdToPlcpSignal[12]; // see IEEE802.11a-1999 p.14
-extern UCHAR	 OfdmRateToRxwiMCS[];
-extern UCHAR OfdmSignalToRateId[16] ;
-extern UCHAR default_cwmin[4];
-extern UCHAR default_cwmax[4];
-extern UCHAR default_sta_aifsn[4];
-extern UCHAR MapUserPriorityToAccessCategory[8];
-
-extern USHORT RateUpPER[];
-extern USHORT RateDownPER[];
-extern UCHAR  Phy11BNextRateDownward[];
-extern UCHAR  Phy11BNextRateUpward[];
-extern UCHAR  Phy11BGNextRateDownward[];
-extern UCHAR  Phy11BGNextRateUpward[];
-extern UCHAR  Phy11ANextRateDownward[];
-extern UCHAR  Phy11ANextRateUpward[];
-extern CHAR   RssiSafeLevelForTxRate[];
-extern UCHAR  RateIdToMbps[];
-extern USHORT RateIdTo500Kbps[];
-
-extern UCHAR  CipherSuiteWpaNoneTkip[];
-extern UCHAR  CipherSuiteWpaNoneTkipLen;
-
-extern UCHAR  CipherSuiteWpaNoneAes[];
-extern UCHAR  CipherSuiteWpaNoneAesLen;
-
-extern UCHAR  SsidIe;
-extern UCHAR  SupRateIe;
-extern UCHAR  ExtRateIe;
-
-extern UCHAR  HtCapIe;
-extern UCHAR  AddHtInfoIe;
-extern UCHAR  NewExtChanIe;
-
-extern UCHAR  ErpIe;
-extern UCHAR  DsIe;
-extern UCHAR  TimIe;
-extern UCHAR  WpaIe;
-extern UCHAR  Wpa2Ie;
-extern UCHAR  IbssIe;
-extern UCHAR  Ccx2Ie;
-
-extern UCHAR  WPA_OUI[];
-extern UCHAR  RSN_OUI[];
-extern UCHAR  WME_INFO_ELEM[];
-extern UCHAR  WME_PARM_ELEM[];
-extern UCHAR  Ccx2QosInfo[];
-extern UCHAR  Ccx2IeInfo[];
-extern UCHAR  RALINK_OUI[];
-extern UCHAR  PowerConstraintIE[];
-
-
-extern UCHAR  RateSwitchTable[];
-extern UCHAR  RateSwitchTable11B[];
-extern UCHAR  RateSwitchTable11G[];
-extern UCHAR  RateSwitchTable11BG[];
-
-extern UCHAR  RateSwitchTable11BGN1S[];
-extern UCHAR  RateSwitchTable11BGN2S[];
-extern UCHAR  RateSwitchTable11BGN2SForABand[];
-extern UCHAR  RateSwitchTable11N1S[];
-extern UCHAR  RateSwitchTable11N2S[];
-extern UCHAR  RateSwitchTable11N2SForABand[];
-
-extern UCHAR  PRE_N_HT_OUI[];
+/*+++Add by shiang for merge MiniportMMRequest() and MiniportDataMMRequest() into one function */
+#define MAX_DATAMM_RETRY	3
+#define MGMT_USE_QUEUE_FLAG	0x80
+/*---Add by shiang for merge MiniportMMRequest() and MiniportDataMMRequest() into one function */
 
 #define	MAXSEQ		(0xFFF)
 
-struct reordering_mpdu
-{
-	struct reordering_mpdu	*next;
-	PNDIS_PACKET			pPacket;		/* coverted to 802.3 frame */
-	int						Sequence;		/* sequence number of MPDU */
-	BOOLEAN					bAMSDU;
+extern unsigned char SNAP_AIRONET[];
+extern unsigned char CISCO_OUI[];
+extern u8 BaSizeArray[4];
+
+extern u8 BROADCAST_ADDR[MAC_ADDR_LEN];
+extern u8 ZERO_MAC_ADDR[MAC_ADDR_LEN];
+extern unsigned long BIT32[32];
+extern u8 BIT8[8];
+extern char *CipherName[];
+extern char *MCSToMbps[];
+extern u8 RxwiMCSToOfdmRate[12];
+extern u8 SNAP_802_1H[6];
+extern u8 SNAP_BRIDGE_TUNNEL[6];
+extern u8 SNAP_AIRONET[8];
+extern u8 CKIP_LLC_SNAP[8];
+extern u8 EAPOL_LLC_SNAP[8];
+extern u8 EAPOL[2];
+extern u8 IPX[2];
+extern u8 APPLE_TALK[2];
+extern u8 RateIdToPlcpSignal[12];	/* see IEEE802.11a-1999 p.14 */
+extern u8 OfdmRateToRxwiMCS[];
+extern u8 OfdmSignalToRateId[16];
+extern u8 default_cwmin[4];
+extern u8 default_cwmax[4];
+extern u8 default_sta_aifsn[4];
+extern u8 MapUserPriorityToAccessCategory[8];
+
+extern u16 RateUpPER[];
+extern u16 RateDownPER[];
+extern u8 Phy11BNextRateDownward[];
+extern u8 Phy11BNextRateUpward[];
+extern u8 Phy11BGNextRateDownward[];
+extern u8 Phy11BGNextRateUpward[];
+extern u8 Phy11ANextRateDownward[];
+extern u8 Phy11ANextRateUpward[];
+extern char RssiSafeLevelForTxRate[];
+extern u8 RateIdToMbps[];
+extern u16 RateIdTo500Kbps[];
+
+extern u8 CipherSuiteWpaNoneTkip[];
+extern u8 CipherSuiteWpaNoneTkipLen;
+
+extern u8 CipherSuiteWpaNoneAes[];
+extern u8 CipherSuiteWpaNoneAesLen;
+
+extern u8 SsidIe;
+extern u8 SupRateIe;
+extern u8 ExtRateIe;
+
+extern u8 HtCapIe;
+extern u8 AddHtInfoIe;
+extern u8 NewExtChanIe;
+
+extern u8 ErpIe;
+extern u8 DsIe;
+extern u8 TimIe;
+extern u8 WpaIe;
+extern u8 Wpa2Ie;
+extern u8 IbssIe;
+extern u8 Ccx2Ie;
+extern u8 WapiIe;
+
+extern u8 WPA_OUI[];
+extern u8 RSN_OUI[];
+extern u8 WAPI_OUI[];
+extern u8 WME_INFO_ELEM[];
+extern u8 WME_PARM_ELEM[];
+extern u8 Ccx2QosInfo[];
+extern u8 Ccx2IeInfo[];
+extern u8 RALINK_OUI[];
+extern u8 PowerConstraintIE[];
+
+extern u8 RateSwitchTable[];
+extern u8 RateSwitchTable11B[];
+extern u8 RateSwitchTable11G[];
+extern u8 RateSwitchTable11BG[];
+
+extern u8 RateSwitchTable11BGN1S[];
+extern u8 RateSwitchTable11BGN2S[];
+extern u8 RateSwitchTable11BGN2SForABand[];
+extern u8 RateSwitchTable11N1S[];
+extern u8 RateSwitchTable11N2S[];
+extern u8 RateSwitchTable11N2SForABand[];
+
+extern u8 PRE_N_HT_OUI[];
+
+struct rt_rssi_sample {
+	char LastRssi0;		/* last received RSSI */
+	char LastRssi1;		/* last received RSSI */
+	char LastRssi2;		/* last received RSSI */
+	char AvgRssi0;
+	char AvgRssi1;
+	char AvgRssi2;
+	short AvgRssi0X8;
+	short AvgRssi1X8;
+	short AvgRssi2X8;
 };
 
-struct reordering_list
-{
-	struct reordering_mpdu *next;
-	int 	qlen;
+/* */
+/*  Queue structure and macros */
+/* */
+struct rt_queue_entry;
+
+struct rt_queue_entry {
+	struct rt_queue_entry *Next;
 };
 
-struct reordering_mpdu_pool
-{
-	PVOID					mem;
-	NDIS_SPIN_LOCK			lock;
-	struct reordering_list 	freelist;
+/* Queue structure */
+struct rt_queue_header {
+	struct rt_queue_entry *Head;
+	struct rt_queue_entry *Tail;
+	unsigned long Number;
 };
 
-typedef struct 	_RSSI_SAMPLE {
-	CHAR			LastRssi0;             // last received RSSI
-	CHAR			LastRssi1;             // last received RSSI
-	CHAR			LastRssi2;             // last received RSSI
-	CHAR			AvgRssi0;
-	CHAR			AvgRssi1;
-	CHAR			AvgRssi2;
-	SHORT			AvgRssi0X8;
-	SHORT			AvgRssi1X8;
-	SHORT			AvgRssi2X8;
-} RSSI_SAMPLE;
-
-//
-//  Queue structure and macros
-//
-typedef struct  _QUEUE_ENTRY    {
-	struct _QUEUE_ENTRY     *Next;
-}   QUEUE_ENTRY, *PQUEUE_ENTRY;
-
-// Queue structure
-typedef struct  _QUEUE_HEADER   {
-	PQUEUE_ENTRY    Head;
-	PQUEUE_ENTRY    Tail;
-	ULONG           Number;
-}   QUEUE_HEADER, *PQUEUE_HEADER;
-
 #define InitializeQueueHeader(QueueHeader)              \
 {                                                       \
 	(QueueHeader)->Head = (QueueHeader)->Tail = NULL;   \
@@ -314,10 +180,11 @@
 #define RemoveHeadQueue(QueueHeader)                \
 (QueueHeader)->Head;                                \
 {                                                   \
-	PQUEUE_ENTRY pNext;                             \
+	struct rt_queue_entry *pNext;                             \
 	if ((QueueHeader)->Head != NULL)				\
 	{												\
 		pNext = (QueueHeader)->Head->Next;          \
+		(QueueHeader)->Head->Next = NULL;		\
 		(QueueHeader)->Head = pNext;                \
 		if (pNext == NULL)                          \
 			(QueueHeader)->Tail = NULL;             \
@@ -327,41 +194,49 @@
 
 #define InsertHeadQueue(QueueHeader, QueueEntry)            \
 {                                                           \
-		((PQUEUE_ENTRY)QueueEntry)->Next = (QueueHeader)->Head; \
-		(QueueHeader)->Head = (PQUEUE_ENTRY)(QueueEntry);       \
+		((struct rt_queue_entry *)QueueEntry)->Next = (QueueHeader)->Head; \
+		(QueueHeader)->Head = (struct rt_queue_entry *)(QueueEntry);       \
 		if ((QueueHeader)->Tail == NULL)                        \
-			(QueueHeader)->Tail = (PQUEUE_ENTRY)(QueueEntry);   \
+			(QueueHeader)->Tail = (struct rt_queue_entry *)(QueueEntry);   \
 		(QueueHeader)->Number++;                                \
 }
 
 #define InsertTailQueue(QueueHeader, QueueEntry)                \
 {                                                               \
-	((PQUEUE_ENTRY)QueueEntry)->Next = NULL;                    \
+	((struct rt_queue_entry *)QueueEntry)->Next = NULL;                    \
 	if ((QueueHeader)->Tail)                                    \
-		(QueueHeader)->Tail->Next = (PQUEUE_ENTRY)(QueueEntry); \
+		(QueueHeader)->Tail->Next = (struct rt_queue_entry *)(QueueEntry); \
 	else                                                        \
-		(QueueHeader)->Head = (PQUEUE_ENTRY)(QueueEntry);       \
-	(QueueHeader)->Tail = (PQUEUE_ENTRY)(QueueEntry);           \
+		(QueueHeader)->Head = (struct rt_queue_entry *)(QueueEntry);       \
+	(QueueHeader)->Tail = (struct rt_queue_entry *)(QueueEntry);           \
 	(QueueHeader)->Number++;                                    \
 }
 
-//
-//  Macros for flag and ref count operations
-//
+#define InsertTailQueueAc(pAd, pEntry, QueueHeader, QueueEntry)			\
+{																		\
+	((struct rt_queue_entry *)QueueEntry)->Next = NULL;							\
+	if ((QueueHeader)->Tail)											\
+		(QueueHeader)->Tail->Next = (struct rt_queue_entry *)(QueueEntry);			\
+	else																\
+		(QueueHeader)->Head = (struct rt_queue_entry *)(QueueEntry);				\
+	(QueueHeader)->Tail = (struct rt_queue_entry *)(QueueEntry);					\
+	(QueueHeader)->Number++;											\
+}
+
+/* */
+/*  Macros for flag and ref count operations */
+/* */
 #define RTMP_SET_FLAG(_M, _F)       ((_M)->Flags |= (_F))
 #define RTMP_CLEAR_FLAG(_M, _F)     ((_M)->Flags &= ~(_F))
 #define RTMP_CLEAR_FLAGS(_M)        ((_M)->Flags = 0)
 #define RTMP_TEST_FLAG(_M, _F)      (((_M)->Flags & (_F)) != 0)
 #define RTMP_TEST_FLAGS(_M, _F)     (((_M)->Flags & (_F)) == (_F))
-
-#ifdef RT2860
-// Macro for power save flag.
+/* Macro for power save flag. */
 #define RTMP_SET_PSFLAG(_M, _F)       ((_M)->PSFlags |= (_F))
 #define RTMP_CLEAR_PSFLAG(_M, _F)     ((_M)->PSFlags &= ~(_F))
 #define RTMP_CLEAR_PSFLAGS(_M)        ((_M)->PSFlags = 0)
 #define RTMP_TEST_PSFLAG(_M, _F)      (((_M)->PSFlags & (_F)) != 0)
 #define RTMP_TEST_PSFLAGS(_M, _F)     (((_M)->PSFlags & (_F)) == (_F))
-#endif
 
 #define OPSTATUS_SET_FLAG(_pAd, _F)     ((_pAd)->CommonCfg.OpStatusFlags |= (_F))
 #define OPSTATUS_CLEAR_FLAG(_pAd, _F)   ((_pAd)->CommonCfg.OpStatusFlags &= ~(_F))
@@ -385,59 +260,12 @@
 #define CKIP_KP_ON(_p)				((((_p)->StaCfg.CkipFlag) & 0x10) && ((_p)->StaCfg.bCkipCmicOn == TRUE))
 #define CKIP_CMIC_ON(_p)			((((_p)->StaCfg.CkipFlag) & 0x08) && ((_p)->StaCfg.bCkipCmicOn == TRUE))
 
-
 #define INC_RING_INDEX(_idx, _RingSize)    \
 {                                          \
     (_idx) = (_idx+1) % (_RingSize);       \
 }
 
-#ifdef RT2870
-// We will have a cost down version which mac version is 0x3090xxxx
-#define IS_RT3090(_pAd)				((((_pAd)->MACVersion & 0xffff0000) == 0x30710000) || (((_pAd)->MACVersion & 0xffff0000) == 0x30900000))
-#else
-#define IS_RT3090(_pAd)				0
-#endif
-#define IS_RT3070(_pAd)				(((_pAd)->MACVersion & 0xffff0000) == 0x30700000)
-#ifdef RT2870
-#define IS_RT3071(_pAd)				(((_pAd)->MACVersion & 0xffff0000) == 0x30710000)
-#define IS_RT30xx(_pAd)				(((_pAd)->MACVersion & 0xfff00000) == 0x30700000)
-#endif
-
-#define RING_PACKET_INIT(_TxRing, _idx)    \
-{                                          \
-    _TxRing->Cell[_idx].pNdisPacket = NULL;                              \
-    _TxRing->Cell[_idx].pNextNdisPacket = NULL;                              \
-}
-
-#define TXDT_INIT(_TxD)    \
-{                                          \
-	NdisZeroMemory(_TxD, TXD_SIZE);	\
-	_TxD->DMADONE = 1;                              \
-}
-
-//Set last data segment
-#define RING_SET_LASTDS(_TxD, _IsSD0)    \
-{                                          \
-    if (_IsSD0) {_TxD->LastSec0 = 1;}     \
-    else {_TxD->LastSec1 = 1;}     \
-}
-
-// Increase TxTsc value for next transmission
-// TODO:
-// When i==6, means TSC has done one full cycle, do re-keying stuff follow specs
-// Should send a special event microsoft defined to request re-key
-#define INC_TX_TSC(_tsc)                                \
-{                                                       \
-    int i=0;                                            \
-    while (++_tsc[i] == 0x0)                            \
-    {                                                   \
-        i++;                                            \
-        if (i == 6)                                     \
-            break;                                      \
-    }                                                   \
-}
-
-// StaActive.SupportedHtPhy.MCSSet is copied from AP beacon.  Don't need to update here.
+/* StaActive.SupportedHtPhy.MCSSet is copied from AP beacon.  Don't need to update here. */
 #define COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd)                                 \
 {                                                                                       \
 	_pAd->StaActive.SupportedHtPhy.ChannelWidth = _pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth;      \
@@ -451,343 +279,52 @@
 	_pAd->StaActive.SupportedHtPhy.RecomWidth = _pAd->MlmeAux.AddHtInfo.AddHtInfo.RecomWidth;      \
 	_pAd->StaActive.SupportedHtPhy.OperaionMode = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode;      \
 	_pAd->StaActive.SupportedHtPhy.NonGfPresent = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent;      \
-	NdisMoveMemory((_pAd)->MacTab.Content[BSSID_WCID].HTCapability.MCSSet, (_pAd)->StaActive.SupportedPhyInfo.MCSSet, sizeof(UCHAR) * 16);\
+	NdisMoveMemory((_pAd)->MacTab.Content[BSSID_WCID].HTCapability.MCSSet, (_pAd)->StaActive.SupportedPhyInfo.MCSSet, sizeof(u8)* 16);\
 }
 
 #define COPY_AP_HTSETTINGS_FROM_BEACON(_pAd, _pHtCapability)                                 \
 {                                                                                       \
-	_pAd->MacTab.Content[BSSID_WCID].AMsduSize = (UCHAR)(_pHtCapability->HtCapInfo.AMsduSize);	\
-	_pAd->MacTab.Content[BSSID_WCID].MmpsMode= (UCHAR)(_pHtCapability->HtCapInfo.MimoPs);	\
-	_pAd->MacTab.Content[BSSID_WCID].MaxRAmpduFactor = (UCHAR)(_pHtCapability->HtCapParm.MaxRAmpduFactor);	\
+	_pAd->MacTab.Content[BSSID_WCID].AMsduSize = (u8)(_pHtCapability->HtCapInfo.AMsduSize);	\
+	_pAd->MacTab.Content[BSSID_WCID].MmpsMode= (u8)(_pHtCapability->HtCapInfo.MimoPs);	\
+	_pAd->MacTab.Content[BSSID_WCID].MaxRAmpduFactor = (u8)(_pHtCapability->HtCapParm.MaxRAmpduFactor);	\
 }
 
-//
-// MACRO for 32-bit PCI register read / write
-//
-// Usage : RTMP_IO_READ32(
-//              PRTMP_ADAPTER pAd,
-//              ULONG Register_Offset,
-//              PULONG  pValue)
-//
-//         RTMP_IO_WRITE32(
-//              PRTMP_ADAPTER pAd,
-//              ULONG Register_Offset,
-//              ULONG Value)
-//
+/* */
+/* MACRO for 32-bit PCI register read / write */
+/* */
+/* Usage : RTMP_IO_READ32( */
+/*              struct rt_rtmp_adapter *pAd, */
+/*              unsigned long Register_Offset, */
+/*              unsigned long * pValue) */
+/* */
+/*         RTMP_IO_WRITE32( */
+/*              struct rt_rtmp_adapter *pAd, */
+/*              unsigned long Register_Offset, */
+/*              unsigned long Value) */
+/* */
 
-//
-// BBP & RF are using indirect access. Before write any value into it.
-// We have to make sure there is no outstanding command pending via checking busy bit.
-//
-#define MAX_BUSY_COUNT  100         // Number of retry before failing access BBP & RF indirect register
-//
-#ifdef RT2860
-#define RTMP_RF_IO_WRITE32(_A, _V)                  \
-{                                                   \
-    PHY_CSR4_STRUC  Value;                          \
-    ULONG           BusyCnt = 0;                    \
-    if ((_A)->bPCIclkOff) 	                \
-    {												\
-        return;										\
-    }                                               \
-    do {                                            \
-        RTMP_IO_READ32(_A, RF_CSR_CFG0, &Value.word);  \
-        if (Value.field.Busy == IDLE)               \
-            break;                                  \
-        BusyCnt++;                                  \
-    }   while (BusyCnt < MAX_BUSY_COUNT);           \
-    if (BusyCnt < MAX_BUSY_COUNT)                   \
-    {                                               \
-        RTMP_IO_WRITE32(_A, RF_CSR_CFG0, _V);          \
-    }                                               \
-}
-
-#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)        \
-{                                                       \
-    BBP_CSR_CFG_STRUC  BbpCsr;                             \
-    int             i, k;                               \
-    for (i=0; i<MAX_BUSY_COUNT; i++)                    \
-    {                                                   \
-        RTMP_IO_READ32(_A, BBP_CSR_CFG, &BbpCsr.word);     \
-        if (BbpCsr.field.Busy == BUSY)                  \
-        {                                               \
-            continue;                                   \
-        }                                               \
-        BbpCsr.word = 0;                                \
-        BbpCsr.field.fRead = 1;                         \
-        BbpCsr.field.BBP_RW_MODE = 1;                         \
-        BbpCsr.field.Busy = 1;                          \
-        BbpCsr.field.RegNum = _I;                       \
-        RTMP_IO_WRITE32(_A, BBP_CSR_CFG, BbpCsr.word);     \
-        for (k=0; k<MAX_BUSY_COUNT; k++)                \
-        {                                               \
-            RTMP_IO_READ32(_A, BBP_CSR_CFG, &BbpCsr.word); \
-            if (BbpCsr.field.Busy == IDLE)              \
-                break;                                  \
-        }                                               \
-        if ((BbpCsr.field.Busy == IDLE) &&              \
-            (BbpCsr.field.RegNum == _I))                \
-        {                                               \
-            *(_pV) = (UCHAR)BbpCsr.field.Value;         \
-            break;                                      \
-        }                                               \
-    }                                                   \
-    if (BbpCsr.field.Busy == BUSY)                      \
-    {                                                   \
-        DBGPRINT_ERR(("DFS BBP read R%d fail\n", _I));      \
-        *(_pV) = (_A)->BbpWriteLatch[_I];               \
-    }                                                   \
-}
-
-//#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)    {}
-// Read BBP register by register's ID. Generate PER to test BA
-#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)        \
-{                                                       \
-    BBP_CSR_CFG_STRUC  BbpCsr;                             \
-    int             i, k;                               \
-    if ((_A)->bPCIclkOff == FALSE)                     \
-    {                                                   \
-    for (i=0; i<MAX_BUSY_COUNT; i++)                    \
-    {                                                   \
-		RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);				\
-        if (BbpCsr.field.Busy == BUSY)                  \
-        {                                               \
-            continue;                                   \
-        }                                               \
-        BbpCsr.word = 0;                                \
-        BbpCsr.field.fRead = 1;                         \
-        BbpCsr.field.BBP_RW_MODE = 1;                         \
-        BbpCsr.field.Busy = 1;                          \
-        BbpCsr.field.RegNum = _I;                       \
-		RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
-		AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0);					\
-		RTMPusecDelay(1000);							\
-        for (k=0; k<MAX_BUSY_COUNT; k++)                \
-        {                                               \
-			RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);			\
-            if (BbpCsr.field.Busy == IDLE)              \
-                break;                                  \
-        }                                               \
-        if ((BbpCsr.field.Busy == IDLE) &&              \
-            (BbpCsr.field.RegNum == _I))                \
-        {                                               \
-            *(_pV) = (UCHAR)BbpCsr.field.Value;         \
-            break;                                      \
-        }                                               \
-    }                                                   \
-    if (BbpCsr.field.Busy == BUSY)                      \
-    {                                                   \
-		DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", _I, BbpCsr.word));	\
-        *(_pV) = (_A)->BbpWriteLatch[_I];               \
-		RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);				\
-		BbpCsr.field.Busy = 0;                          \
-		RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
-    }                                                   \
-    }                   \
-}
-
-#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)        \
-{                                                       \
-    BBP_CSR_CFG_STRUC  BbpCsr;                             \
-    int             BusyCnt;                            \
-    for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++)  \
-    {                                                   \
-        RTMP_IO_READ32(_A, BBP_CSR_CFG, &BbpCsr.word);     \
-        if (BbpCsr.field.Busy == BUSY)                  \
-            continue;                                   \
-        BbpCsr.word = 0;                                \
-        BbpCsr.field.fRead = 0;                         \
-        BbpCsr.field.BBP_RW_MODE = 1;                         \
-        BbpCsr.field.Busy = 1;                          \
-        BbpCsr.field.Value = _V;                        \
-        BbpCsr.field.RegNum = _I;                       \
-        RTMP_IO_WRITE32(_A, BBP_CSR_CFG, BbpCsr.word);     \
-        (_A)->BbpWriteLatch[_I] = _V;                   \
-        break;                                          \
-    }                                                   \
-    if (BusyCnt == MAX_BUSY_COUNT)                      \
-    {                                                   \
-        DBGPRINT_ERR(("BBP write R%d fail\n", _I));     \
-    }                                                   \
-}
-
-// Write BBP register by register's ID & value
-#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)        \
-{                                                       \
-    BBP_CSR_CFG_STRUC  BbpCsr;                             \
-    int             BusyCnt;                            \
-    if ((_A)->bPCIclkOff == FALSE)                     \
-    {                                                   \
-    for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++)  \
-    {                                                   \
-		RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);				\
-        if (BbpCsr.field.Busy == BUSY)                  \
-            continue;                                   \
-        BbpCsr.word = 0;                                \
-        BbpCsr.field.fRead = 0;                         \
-        BbpCsr.field.BBP_RW_MODE = 1;                         \
-        BbpCsr.field.Busy = 1;                          \
-        BbpCsr.field.Value = _V;                        \
-        BbpCsr.field.RegNum = _I;                       \
-		RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
-		AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0);					\
-            if (_A->OpMode == OPMODE_AP)                    \
-		RTMPusecDelay(1000);							\
-        (_A)->BbpWriteLatch[_I] = _V;                   \
-        break;                                          \
-    }                                                   \
-    if (BusyCnt == MAX_BUSY_COUNT)                      \
-    {                                                   \
-		DBGPRINT_ERR(("BBP write R%d=0x%x fail\n", _I, BbpCsr.word));	\
-		RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);				\
-		BbpCsr.field.Busy = 0;                          \
-		RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
-    }                                                   \
-    }                                                   \
-}
-#endif /* RT2860 */
-#ifdef RT2870
-#define RTMP_RF_IO_WRITE32(_A, _V)                 RTUSBWriteRFRegister(_A, _V)
-#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)   RTUSBReadBBPRegister(_A, _I, _pV)
-#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)   RTUSBWriteBBPRegister(_A, _I, _V)
-
-#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)			RTUSBWriteBBPRegister(_A, _I, _V)
-#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)   		RTUSBReadBBPRegister(_A, _I, _pV)
-#endif // RT2870 //
-
-#define     MAP_CHANNEL_ID_TO_KHZ(ch, khz)  {               \
-                switch (ch)                                 \
-                {                                           \
-                    case 1:     khz = 2412000;   break;     \
-                    case 2:     khz = 2417000;   break;     \
-                    case 3:     khz = 2422000;   break;     \
-                    case 4:     khz = 2427000;   break;     \
-                    case 5:     khz = 2432000;   break;     \
-                    case 6:     khz = 2437000;   break;     \
-                    case 7:     khz = 2442000;   break;     \
-                    case 8:     khz = 2447000;   break;     \
-                    case 9:     khz = 2452000;   break;     \
-                    case 10:    khz = 2457000;   break;     \
-                    case 11:    khz = 2462000;   break;     \
-                    case 12:    khz = 2467000;   break;     \
-                    case 13:    khz = 2472000;   break;     \
-                    case 14:    khz = 2484000;   break;     \
-                    case 36:  /* UNII */  khz = 5180000;   break;     \
-                    case 40:  /* UNII */  khz = 5200000;   break;     \
-                    case 44:  /* UNII */  khz = 5220000;   break;     \
-                    case 48:  /* UNII */  khz = 5240000;   break;     \
-                    case 52:  /* UNII */  khz = 5260000;   break;     \
-                    case 56:  /* UNII */  khz = 5280000;   break;     \
-                    case 60:  /* UNII */  khz = 5300000;   break;     \
-                    case 64:  /* UNII */  khz = 5320000;   break;     \
-                    case 149: /* UNII */  khz = 5745000;   break;     \
-                    case 153: /* UNII */  khz = 5765000;   break;     \
-                    case 157: /* UNII */  khz = 5785000;   break;     \
-                    case 161: /* UNII */  khz = 5805000;   break;     \
-                    case 165: /* UNII */  khz = 5825000;   break;     \
-                    case 100: /* HiperLAN2 */  khz = 5500000;   break;     \
-                    case 104: /* HiperLAN2 */  khz = 5520000;   break;     \
-                    case 108: /* HiperLAN2 */  khz = 5540000;   break;     \
-                    case 112: /* HiperLAN2 */  khz = 5560000;   break;     \
-                    case 116: /* HiperLAN2 */  khz = 5580000;   break;     \
-                    case 120: /* HiperLAN2 */  khz = 5600000;   break;     \
-                    case 124: /* HiperLAN2 */  khz = 5620000;   break;     \
-                    case 128: /* HiperLAN2 */  khz = 5640000;   break;     \
-                    case 132: /* HiperLAN2 */  khz = 5660000;   break;     \
-                    case 136: /* HiperLAN2 */  khz = 5680000;   break;     \
-                    case 140: /* HiperLAN2 */  khz = 5700000;   break;     \
-                    case 34:  /* Japan MMAC */   khz = 5170000;   break;   \
-                    case 38:  /* Japan MMAC */   khz = 5190000;   break;   \
-                    case 42:  /* Japan MMAC */   khz = 5210000;   break;   \
-                    case 46:  /* Japan MMAC */   khz = 5230000;   break;   \
-                    case 184: /* Japan */   khz = 4920000;   break;   \
-                    case 188: /* Japan */   khz = 4940000;   break;   \
-                    case 192: /* Japan */   khz = 4960000;   break;   \
-                    case 196: /* Japan */   khz = 4980000;   break;   \
-                    case 208: /* Japan, means J08 */   khz = 5040000;   break;   \
-                    case 212: /* Japan, means J12 */   khz = 5060000;   break;   \
-                    case 216: /* Japan, means J16 */   khz = 5080000;   break;   \
-                    default:    khz = 2412000;   break;     \
-                }                                           \
-            }
-
-#define     MAP_KHZ_TO_CHANNEL_ID(khz, ch)  {               \
-                switch (khz)                                \
-                {                                           \
-                    case 2412000:    ch = 1;     break;     \
-                    case 2417000:    ch = 2;     break;     \
-                    case 2422000:    ch = 3;     break;     \
-                    case 2427000:    ch = 4;     break;     \
-                    case 2432000:    ch = 5;     break;     \
-                    case 2437000:    ch = 6;     break;     \
-                    case 2442000:    ch = 7;     break;     \
-                    case 2447000:    ch = 8;     break;     \
-                    case 2452000:    ch = 9;     break;     \
-                    case 2457000:    ch = 10;    break;     \
-                    case 2462000:    ch = 11;    break;     \
-                    case 2467000:    ch = 12;    break;     \
-                    case 2472000:    ch = 13;    break;     \
-                    case 2484000:    ch = 14;    break;     \
-                    case 5180000:    ch = 36;  /* UNII */  break;     \
-                    case 5200000:    ch = 40;  /* UNII */  break;     \
-                    case 5220000:    ch = 44;  /* UNII */  break;     \
-                    case 5240000:    ch = 48;  /* UNII */  break;     \
-                    case 5260000:    ch = 52;  /* UNII */  break;     \
-                    case 5280000:    ch = 56;  /* UNII */  break;     \
-                    case 5300000:    ch = 60;  /* UNII */  break;     \
-                    case 5320000:    ch = 64;  /* UNII */  break;     \
-                    case 5745000:    ch = 149; /* UNII */  break;     \
-                    case 5765000:    ch = 153; /* UNII */  break;     \
-                    case 5785000:    ch = 157; /* UNII */  break;     \
-                    case 5805000:    ch = 161; /* UNII */  break;     \
-                    case 5825000:    ch = 165; /* UNII */  break;     \
-                    case 5500000:    ch = 100; /* HiperLAN2 */  break;     \
-                    case 5520000:    ch = 104; /* HiperLAN2 */  break;     \
-                    case 5540000:    ch = 108; /* HiperLAN2 */  break;     \
-                    case 5560000:    ch = 112; /* HiperLAN2 */  break;     \
-                    case 5580000:    ch = 116; /* HiperLAN2 */  break;     \
-                    case 5600000:    ch = 120; /* HiperLAN2 */  break;     \
-                    case 5620000:    ch = 124; /* HiperLAN2 */  break;     \
-                    case 5640000:    ch = 128; /* HiperLAN2 */  break;     \
-                    case 5660000:    ch = 132; /* HiperLAN2 */  break;     \
-                    case 5680000:    ch = 136; /* HiperLAN2 */  break;     \
-                    case 5700000:    ch = 140; /* HiperLAN2 */  break;     \
-                    case 5170000:    ch = 34;  /* Japan MMAC */   break;   \
-                    case 5190000:    ch = 38;  /* Japan MMAC */   break;   \
-                    case 5210000:    ch = 42;  /* Japan MMAC */   break;   \
-                    case 5230000:    ch = 46;  /* Japan MMAC */   break;   \
-                    case 4920000:    ch = 184; /* Japan */  break;   \
-                    case 4940000:    ch = 188; /* Japan */  break;   \
-                    case 4960000:    ch = 192; /* Japan */  break;   \
-                    case 4980000:    ch = 196; /* Japan */  break;   \
-                    case 5040000:    ch = 208; /* Japan, means J08 */  break;   \
-                    case 5060000:    ch = 212; /* Japan, means J12 */  break;   \
-                    case 5080000:    ch = 216; /* Japan, means J16 */  break;   \
-                    default:         ch = 1;     break;     \
-                }                                           \
-            }
-
-//
-// Common fragment list structure -  Identical to the scatter gather frag list structure
-//
+/* */
+/* Common fragment list structure -  Identical to the scatter gather frag list structure */
+/* */
+/*#define struct rt_rtmp_sg_element         SCATTER_GATHER_ELEMENT */
+/*#define struct rt_rtmp_sg_element *PSCATTER_GATHER_ELEMENT */
 #define NIC_MAX_PHYS_BUF_COUNT              8
 
-typedef struct _RTMP_SCATTER_GATHER_ELEMENT {
-    PVOID		Address;
-    ULONG		Length;
-    PULONG		Reserved;
-} RTMP_SCATTER_GATHER_ELEMENT, *PRTMP_SCATTER_GATHER_ELEMENT;
+struct rt_rtmp_sg_element {
+	void *Address;
+	unsigned long Length;
+	unsigned long *Reserved;
+};
 
+struct rt_rtmp_sg_list {
+	unsigned long NumberOfElements;
+	unsigned long *Reserved;
+	struct rt_rtmp_sg_element Elements[NIC_MAX_PHYS_BUF_COUNT];
+};
 
-typedef struct _RTMP_SCATTER_GATHER_LIST {
-    ULONG  NumberOfElements;
-    PULONG Reserved;
-    RTMP_SCATTER_GATHER_ELEMENT Elements[NIC_MAX_PHYS_BUF_COUNT];
-} RTMP_SCATTER_GATHER_LIST, *PRTMP_SCATTER_GATHER_LIST;
-
-//
-//  Some utility macros
-//
+/* */
+/*  Some utility macros */
+/* */
 #ifndef min
 #define min(_a, _b)     (((_a) < (_b)) ? (_a) : (_b))
 #endif
@@ -805,11 +342,11 @@
 #define MONITOR_ON(_p)              (((_p)->StaCfg.BssType) == BSS_MONITOR)
 #define IDLE_ON(_p)                 (!INFRA_ON(_p) && !ADHOC_ON(_p))
 
-// Check LEAP & CCKM flags
+/* Check LEAP & CCKM flags */
 #define LEAP_ON(_p)                 (((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP)
 #define LEAP_CCKM_ON(_p)            ((((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP) && ((_p)->StaCfg.LeapAuthInfo.CCKM == TRUE))
 
-// if orginal Ethernet frame contains no LLC/SNAP, then an extra LLC/SNAP encap is required
+/* if orginal Ethernet frame contains no LLC/SNAP, then an extra LLC/SNAP encap is required */
 #define EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(_pBufVA, _pExtraLlcSnapEncap)		\
 {																\
 	if (((*(_pBufVA + 12) << 8) + *(_pBufVA + 13)) > 1500)		\
@@ -827,7 +364,7 @@
 	}															\
 }
 
-// New Define for new Tx Path.
+/* New Define for new Tx Path. */
 #define EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(_pBufVA, _pExtraLlcSnapEncap)	\
 {																\
 	if (((*(_pBufVA) << 8) + *(_pBufVA + 1)) > 1500)			\
@@ -845,7 +382,6 @@
 	}															\
 }
 
-
 #define MAKE_802_3_HEADER(_p, _pMac1, _pMac2, _pType)                   \
 {                                                                       \
     NdisMoveMemory(_p, _pMac1, MAC_ADDR_LEN);                           \
@@ -853,13 +389,13 @@
     NdisMoveMemory((_p + MAC_ADDR_LEN * 2), _pType, LENGTH_802_3_TYPE); \
 }
 
-// if pData has no LLC/SNAP (neither RFC1042 nor Bridge tunnel), keep it that way.
-// else if the received frame is LLC/SNAP-encaped IPX or APPLETALK, preserve the LLC/SNAP field
-// else remove the LLC/SNAP field from the result Ethernet frame
-// Patch for WHQL only, which did not turn on Netbios but use IPX within its payload
-// Note:
-//     _pData & _DataSize may be altered (remove 8-byte LLC/SNAP) by this MACRO
-//     _pRemovedLLCSNAP: pointer to removed LLC/SNAP; NULL is not removed
+/* if pData has no LLC/SNAP (neither RFC1042 nor Bridge tunnel), keep it that way. */
+/* else if the received frame is LLC/SNAP-encaped IPX or APPLETALK, preserve the LLC/SNAP field */
+/* else remove the LLC/SNAP field from the result Ethernet frame */
+/* Patch for WHQL only, which did not turn on Netbios but use IPX within its payload */
+/* Note: */
+/*     _pData & _DataSize may be altered (remove 8-byte LLC/SNAP) by this MACRO */
+/*     _pRemovedLLCSNAP: pointer to removed LLC/SNAP; NULL is not removed */
 #define CONVERT_TO_802_3(_p8023hdr, _pDA, _pSA, _pData, _DataSize, _pRemovedLLCSNAP)      \
 {                                                                       \
     char LLC_Len[2];                                                    \
@@ -868,13 +404,13 @@
     if (NdisEqualMemory(SNAP_802_1H, _pData, 6)  ||                     \
         NdisEqualMemory(SNAP_BRIDGE_TUNNEL, _pData, 6))                 \
     {                                                                   \
-        PUCHAR pProto = _pData + 6;                                     \
+        u8 *pProto = _pData + 6;                                     \
                                                                         \
         if ((NdisEqualMemory(IPX, pProto, 2) || NdisEqualMemory(APPLE_TALK, pProto, 2)) &&  \
             NdisEqualMemory(SNAP_802_1H, _pData, 6))                    \
         {                                                               \
-            LLC_Len[0] = (UCHAR)(_DataSize / 256);                      \
-            LLC_Len[1] = (UCHAR)(_DataSize % 256);                      \
+            LLC_Len[0] = (u8)(_DataSize / 256);                      \
+            LLC_Len[1] = (u8)(_DataSize % 256);                      \
             MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len);          \
         }                                                               \
         else                                                            \
@@ -887,551 +423,437 @@
     }                                                                   \
     else                                                                \
     {                                                                   \
-        LLC_Len[0] = (UCHAR)(_DataSize / 256);                          \
-        LLC_Len[1] = (UCHAR)(_DataSize % 256);                          \
+        LLC_Len[0] = (u8)(_DataSize / 256);                          \
+        LLC_Len[1] = (u8)(_DataSize % 256);                          \
         MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len);              \
     }                                                                   \
 }
 
-#define SWITCH_AB( _pAA, _pBB)    \
-{                                                                           \
-    PVOID pCC;                                                          \
-    pCC = _pBB;                                                 \
-    _pBB = _pAA;                                                 \
-    _pAA = pCC;                                                 \
-}
-
-// Enqueue this frame to MLME engine
-// We need to enqueue the whole frame because MLME need to pass data type
-// information from 802.11 header
-#ifdef RT2860
+/* Enqueue this frame to MLME engine */
+/* We need to enqueue the whole frame because MLME need to pass data type */
+/* information from 802.11 header */
+#ifdef RTMP_MAC_PCI
 #define REPORT_MGMT_FRAME_TO_MLME(_pAd, Wcid, _pFrame, _FrameSize, _Rssi0, _Rssi1, _Rssi2, _PlcpSignal)        \
 {                                                                                       \
-    UINT32 High32TSF, Low32TSF;                                                          \
+    u32 High32TSF, Low32TSF;                                                          \
     RTMP_IO_READ32(_pAd, TSF_TIMER_DW1, &High32TSF);                                       \
     RTMP_IO_READ32(_pAd, TSF_TIMER_DW0, &Low32TSF);                                        \
-    MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (UCHAR)_Rssi0, (UCHAR)_Rssi1,(UCHAR)_Rssi2,_FrameSize, _pFrame, (UCHAR)_PlcpSignal);   \
+    MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (u8)_Rssi0, (u8)_Rssi1,(u8)_Rssi2,_FrameSize, _pFrame, (u8)_PlcpSignal);   \
 }
-#endif
-#ifdef RT2870
+#endif /* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
 #define REPORT_MGMT_FRAME_TO_MLME(_pAd, Wcid, _pFrame, _FrameSize, _Rssi0, _Rssi1, _Rssi2, _PlcpSignal)        \
 {                                                                                       \
-    UINT32 High32TSF=0, Low32TSF=0;                                                          \
-    MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (UCHAR)_Rssi0, (UCHAR)_Rssi1,(UCHAR)_Rssi2,_FrameSize, _pFrame, (UCHAR)_PlcpSignal);   \
+    u32 High32TSF=0, Low32TSF=0;                                                          \
+    MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (u8)_Rssi0, (u8)_Rssi1,(u8)_Rssi2,_FrameSize, _pFrame, (u8)_PlcpSignal);   \
 }
-#endif // RT2870 //
+#endif /* RTMP_MAC_USB // */
 
-//Need to collect each ant's rssi concurrently
-//rssi1 is report to pair2 Ant and rss2 is reprot to pair1 Ant when 4 Ant
-#define COLLECT_RX_ANTENNA_AVERAGE_RSSI(_pAd, _rssi1, _rssi2)					\
-{																				\
-	SHORT	AvgRssi;															\
-	UCHAR	UsedAnt;															\
-	if (_pAd->RxAnt.EvaluatePeriod == 0)									\
-	{																		\
-		UsedAnt = _pAd->RxAnt.Pair1PrimaryRxAnt;							\
-		AvgRssi = _pAd->RxAnt.Pair1AvgRssi[UsedAnt];						\
-		if (AvgRssi < 0)													\
-			AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi1;					\
-		else																\
-			AvgRssi = _rssi1 << 3;											\
-		_pAd->RxAnt.Pair1AvgRssi[UsedAnt] = AvgRssi;						\
-	}																		\
-	else																	\
-	{																		\
-		UsedAnt = _pAd->RxAnt.Pair1SecondaryRxAnt;							\
-		AvgRssi = _pAd->RxAnt.Pair1AvgRssi[UsedAnt];						\
-		if ((AvgRssi < 0) && (_pAd->RxAnt.FirstPktArrivedWhenEvaluate))		\
-			AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi1;					\
-		else																\
-		{																	\
-			_pAd->RxAnt.FirstPktArrivedWhenEvaluate = TRUE;					\
-			AvgRssi = _rssi1 << 3;											\
-		}																	\
-		_pAd->RxAnt.Pair1AvgRssi[UsedAnt] = AvgRssi;						\
-		_pAd->RxAnt.RcvPktNumWhenEvaluate++;								\
-	}																		\
-}
-
-#define NDIS_QUERY_BUFFER(_NdisBuf, _ppVA, _pBufLen)                    \
-    NdisQueryBuffer(_NdisBuf, _ppVA, _pBufLen)
-
-#define MAC_ADDR_EQUAL(pAddr1,pAddr2)           RTMPEqualMemory((PVOID)(pAddr1), (PVOID)(pAddr2), MAC_ADDR_LEN)
+#define MAC_ADDR_EQUAL(pAddr1,pAddr2)           RTMPEqualMemory((void *)(pAddr1), (void *)(pAddr2), MAC_ADDR_LEN)
 #define SSID_EQUAL(ssid1, len1, ssid2, len2)    ((len1==len2) && (RTMPEqualMemory(ssid1, ssid2, len1)))
 
-//
-// Check if it is Japan W53(ch52,56,60,64) channel.
-//
+/* */
+/* Check if it is Japan W53(ch52,56,60,64) channel. */
+/* */
 #define JapanChannelCheck(channel)  ((channel == 52) || (channel == 56) || (channel == 60) || (channel == 64))
 
-#ifdef RT2860
+#define STA_EXTRA_SETTING(_pAd)
+
 #define STA_PORT_SECURED(_pAd) \
 { \
-	_pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; \
-	RTMP_SET_PSFLAG(_pAd, fRTMP_PS_CAN_GO_SLEEP); \
-	NdisAcquireSpinLock(&(_pAd)->MacTabLock); \
-	_pAd->MacTab.Content[BSSID_WCID].PortSecured = _pAd->StaCfg.PortSecured; \
+	BOOLEAN	Cancelled; \
+	(_pAd)->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; \
+	NdisAcquireSpinLock(&((_pAd)->MacTabLock)); \
+	(_pAd)->MacTab.Content[BSSID_WCID].PortSecured = (_pAd)->StaCfg.PortSecured; \
+	(_pAd)->MacTab.Content[BSSID_WCID].PrivacyFilter = Ndis802_11PrivFilterAcceptAll;\
 	NdisReleaseSpinLock(&(_pAd)->MacTabLock); \
+	RTMPCancelTimer(&((_pAd)->Mlme.LinkDownTimer), &Cancelled);\
+	STA_EXTRA_SETTING(_pAd); \
 }
-#endif
-#ifdef RT2870
-#define STA_PORT_SECURED(_pAd) \
-{ \
-	_pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; \
-	NdisAcquireSpinLock(&_pAd->MacTabLock); \
-	_pAd->MacTab.Content[BSSID_WCID].PortSecured = _pAd->StaCfg.PortSecured; \
-	NdisReleaseSpinLock(&_pAd->MacTabLock); \
-}
-#endif
 
-//
-// Register set pair for initialzation register set definition
-//
-typedef struct  _RTMP_REG_PAIR
-{
-	ULONG   Register;
-	ULONG   Value;
-} RTMP_REG_PAIR, *PRTMP_REG_PAIR;
+/* */
+/*  Data buffer for DMA operation, the buffer must be contiguous physical memory */
+/*  Both DMA to / from CPU use the same structure. */
+/* */
+struct rt_rtmp_dmabuf {
+	unsigned long AllocSize;
+	void *AllocVa;		/* TxBuf virtual address */
+	dma_addr_t AllocPa;	/* TxBuf physical address */
+};
 
-typedef struct  _REG_PAIR
-{
-	UCHAR   Register;
-	UCHAR   Value;
-} REG_PAIR, *PREG_PAIR;
+/* */
+/* Control block (Descriptor) for all ring descriptor DMA operation, buffer must be */
+/* contiguous physical memory. char stored the binding Rx packet descriptor */
+/* which won't be released, driver has to wait until upper layer return the packet */
+/* before giveing up this rx ring descriptor to ASIC. NDIS_BUFFER is assocaited pair */
+/* to describe the packet buffer. For Tx, char stored the tx packet descriptor */
+/* which driver should ACK upper layer when the tx is physically done or failed. */
+/* */
+struct rt_rtmp_dmacb {
+	unsigned long AllocSize;	/* Control block size */
+	void *AllocVa;		/* Control block virtual address */
+	dma_addr_t AllocPa;	/* Control block physical address */
+	void *pNdisPacket;
+	void *pNextNdisPacket;
 
-//
-// Register set pair for initialzation register set definition
-//
-typedef struct  _RTMP_RF_REGS
-{
-	UCHAR   Channel;
-	ULONG   R1;
-	ULONG   R2;
-	ULONG   R3;
-	ULONG   R4;
-} RTMP_RF_REGS, *PRTMP_RF_REGS;
+	struct rt_rtmp_dmabuf DmaBuf;	/* Associated DMA buffer structure */
+};
 
-typedef struct _FREQUENCY_ITEM {
-	UCHAR	Channel;
-	UCHAR	N;
-	UCHAR	R;
-	UCHAR	K;
-} FREQUENCY_ITEM, *PFREQUENCY_ITEM;
+struct rt_rtmp_tx_ring {
+	struct rt_rtmp_dmacb Cell[TX_RING_SIZE];
+	u32 TxCpuIdx;
+	u32 TxDmaIdx;
+	u32 TxSwFreeIdx;	/* software next free tx index */
+};
 
-//
-//  Data buffer for DMA operation, the buffer must be contiguous physical memory
-//  Both DMA to / from CPU use the same structure.
-//
-typedef struct  _RTMP_DMABUF
-{
-	ULONG                   AllocSize;
-	PVOID                   AllocVa;            // TxBuf virtual address
-	NDIS_PHYSICAL_ADDRESS   AllocPa;            // TxBuf physical address
-} RTMP_DMABUF, *PRTMP_DMABUF;
+struct rt_rtmp_rx_ring {
+	struct rt_rtmp_dmacb Cell[RX_RING_SIZE];
+	u32 RxCpuIdx;
+	u32 RxDmaIdx;
+	int RxSwReadIdx;	/* software next read index */
+};
 
+struct rt_rtmp_mgmt_ring {
+	struct rt_rtmp_dmacb Cell[MGMT_RING_SIZE];
+	u32 TxCpuIdx;
+	u32 TxDmaIdx;
+	u32 TxSwFreeIdx;	/* software next free tx index */
+};
 
-typedef	union	_HEADER_802_11_SEQ{
-    struct {
-	USHORT			Frag:4;
-	USHORT			Sequence:12;
-    }   field;
-    USHORT           value;
-}	HEADER_802_11_SEQ, *PHEADER_802_11_SEQ;
+/* */
+/*  Statistic counter structure */
+/* */
+struct rt_counter_802_3 {
+	/* General Stats */
+	unsigned long GoodTransmits;
+	unsigned long GoodReceives;
+	unsigned long TxErrors;
+	unsigned long RxErrors;
+	unsigned long RxNoBuffer;
 
-//
-//  Data buffer for DMA operation, the buffer must be contiguous physical memory
-//  Both DMA to / from CPU use the same structure.
-//
-typedef struct  _RTMP_REORDERBUF
-{
-	BOOLEAN			IsFull;
-	PVOID                   AllocVa;            // TxBuf virtual address
-	UCHAR			Header802_3[14];
-	HEADER_802_11_SEQ			Sequence;	//support compressed bitmap BA, so no consider fragment in BA
-	UCHAR 		DataOffset;
-	USHORT 		Datasize;
-	ULONG                   AllocSize;
-#ifdef RT2860
-	NDIS_PHYSICAL_ADDRESS   AllocPa;            // TxBuf physical address
-#endif
-#ifdef RT2870
-	PUCHAR					AllocPa;
-#endif // RT2870 //
-}   RTMP_REORDERBUF, *PRTMP_REORDERBUF;
+	/* Ethernet Stats */
+	unsigned long RcvAlignmentErrors;
+	unsigned long OneCollision;
+	unsigned long MoreCollisions;
 
-//
-// Control block (Descriptor) for all ring descriptor DMA operation, buffer must be
-// contiguous physical memory. NDIS_PACKET stored the binding Rx packet descriptor
-// which won't be released, driver has to wait until upper layer return the packet
-// before giveing up this rx ring descriptor to ASIC. NDIS_BUFFER is assocaited pair
-// to describe the packet buffer. For Tx, NDIS_PACKET stored the tx packet descriptor
-// which driver should ACK upper layer when the tx is physically done or failed.
-//
-typedef struct _RTMP_DMACB
-{
-	ULONG                   AllocSize;          // Control block size
-	PVOID                   AllocVa;            // Control block virtual address
-	NDIS_PHYSICAL_ADDRESS   AllocPa;            // Control block physical address
-	PNDIS_PACKET pNdisPacket;
-	PNDIS_PACKET pNextNdisPacket;
+};
 
-	RTMP_DMABUF             DmaBuf;             // Associated DMA buffer structure
-} RTMP_DMACB, *PRTMP_DMACB;
+struct rt_counter_802_11 {
+	unsigned long Length;
+	LARGE_INTEGER LastTransmittedFragmentCount;
+	LARGE_INTEGER TransmittedFragmentCount;
+	LARGE_INTEGER MulticastTransmittedFrameCount;
+	LARGE_INTEGER FailedCount;
+	LARGE_INTEGER RetryCount;
+	LARGE_INTEGER MultipleRetryCount;
+	LARGE_INTEGER RTSSuccessCount;
+	LARGE_INTEGER RTSFailureCount;
+	LARGE_INTEGER ACKFailureCount;
+	LARGE_INTEGER FrameDuplicateCount;
+	LARGE_INTEGER ReceivedFragmentCount;
+	LARGE_INTEGER MulticastReceivedFrameCount;
+	LARGE_INTEGER FCSErrorCount;
+};
 
-typedef struct _RTMP_TX_BUF
-{
-	PQUEUE_ENTRY    Next;
-	UCHAR           Index;
-	ULONG                   AllocSize;          // Control block size
-	PVOID                   AllocVa;            // Control block virtual address
-	NDIS_PHYSICAL_ADDRESS   AllocPa;            // Control block physical address
-} RTMP_TXBUF, *PRTMP_TXBUF;
+struct rt_counter_ralink {
+	unsigned long TransmittedByteCount;	/* both successful and failure, used to calculate TX throughput */
+	unsigned long ReceivedByteCount;	/* both CRC okay and CRC error, used to calculate RX throughput */
+	unsigned long BeenDisassociatedCount;
+	unsigned long BadCQIAutoRecoveryCount;
+	unsigned long PoorCQIRoamingCount;
+	unsigned long MgmtRingFullCount;
+	unsigned long RxCountSinceLastNULL;
+	unsigned long RxCount;
+	unsigned long RxRingErrCount;
+	unsigned long KickTxCount;
+	unsigned long TxRingErrCount;
+	LARGE_INTEGER RealFcsErrCount;
+	unsigned long PendingNdisPacketCount;
 
-typedef struct _RTMP_RX_BUF
-{
-	BOOLEAN           InUse;
-	ULONG           	ByBaRecIndex;
-	RTMP_REORDERBUF	MAP_RXBuf[MAX_RX_REORDERBUF];
-} RTMP_RXBUF, *PRTMP_RXBUF;
-typedef struct _RTMP_TX_RING
-{
-	RTMP_DMACB  Cell[TX_RING_SIZE];
-	UINT32		TxCpuIdx;
-	UINT32		TxDmaIdx;
-	UINT32		TxSwFreeIdx; 	// software next free tx index
-} RTMP_TX_RING, *PRTMP_TX_RING;
+	unsigned long OneSecOsTxCount[NUM_OF_TX_RING];
+	unsigned long OneSecDmaDoneCount[NUM_OF_TX_RING];
+	u32 OneSecTxDoneCount;
+	unsigned long OneSecRxCount;
+	u32 OneSecTxAggregationCount;
+	u32 OneSecRxAggregationCount;
+	u32 OneSecReceivedByteCount;
+	u32 OneSecFrameDuplicateCount;
 
-typedef struct _RTMP_RX_RING
-{
-	RTMP_DMACB  Cell[RX_RING_SIZE];
-	UINT32		RxCpuIdx;
-	UINT32		RxDmaIdx;
-	INT32		RxSwReadIdx; 	// software next read index
-} RTMP_RX_RING, *PRTMP_RX_RING;
+	u32 OneSecTransmittedByteCount;	/* both successful and failure, used to calculate TX throughput */
+	u32 OneSecTxNoRetryOkCount;
+	u32 OneSecTxRetryOkCount;
+	u32 OneSecTxFailCount;
+	u32 OneSecFalseCCACnt;	/* CCA error count, for debug purpose, might move to global counter */
+	u32 OneSecRxOkCnt;	/* RX without error */
+	u32 OneSecRxOkDataCnt;	/* unicast-to-me DATA frame count */
+	u32 OneSecRxFcsErrCnt;	/* CRC error */
+	u32 OneSecBeaconSentCnt;
+	u32 LastOneSecTotalTxCount;	/* OneSecTxNoRetryOkCount + OneSecTxRetryOkCount + OneSecTxFailCount */
+	u32 LastOneSecRxOkDataCnt;	/* OneSecRxOkDataCnt */
+	unsigned long DuplicateRcv;
+	unsigned long TxAggCount;
+	unsigned long TxNonAggCount;
+	unsigned long TxAgg1MPDUCount;
+	unsigned long TxAgg2MPDUCount;
+	unsigned long TxAgg3MPDUCount;
+	unsigned long TxAgg4MPDUCount;
+	unsigned long TxAgg5MPDUCount;
+	unsigned long TxAgg6MPDUCount;
+	unsigned long TxAgg7MPDUCount;
+	unsigned long TxAgg8MPDUCount;
+	unsigned long TxAgg9MPDUCount;
+	unsigned long TxAgg10MPDUCount;
+	unsigned long TxAgg11MPDUCount;
+	unsigned long TxAgg12MPDUCount;
+	unsigned long TxAgg13MPDUCount;
+	unsigned long TxAgg14MPDUCount;
+	unsigned long TxAgg15MPDUCount;
+	unsigned long TxAgg16MPDUCount;
 
-typedef struct _RTMP_MGMT_RING
-{
-	RTMP_DMACB  Cell[MGMT_RING_SIZE];
-	UINT32		TxCpuIdx;
-	UINT32		TxDmaIdx;
-	UINT32		TxSwFreeIdx; // software next free tx index
-} RTMP_MGMT_RING, *PRTMP_MGMT_RING;
+	LARGE_INTEGER TransmittedOctetsInAMSDU;
+	LARGE_INTEGER TransmittedAMSDUCount;
+	LARGE_INTEGER ReceivedOctesInAMSDUCount;
+	LARGE_INTEGER ReceivedAMSDUCount;
+	LARGE_INTEGER TransmittedAMPDUCount;
+	LARGE_INTEGER TransmittedMPDUsInAMPDUCount;
+	LARGE_INTEGER TransmittedOctetsInAMPDUCount;
+	LARGE_INTEGER MPDUInReceivedAMPDUCount;
+};
 
-//
-//  Statistic counter structure
-//
-typedef struct _COUNTER_802_3
-{
-	// General Stats
-	ULONG       GoodTransmits;
-	ULONG       GoodReceives;
-	ULONG       TxErrors;
-	ULONG       RxErrors;
-	ULONG       RxNoBuffer;
+struct rt_counter_drs {
+	/* to record the each TX rate's quality. 0 is best, the bigger the worse. */
+	u16 TxQuality[MAX_STEP_OF_TX_RATE_SWITCH];
+	u8 PER[MAX_STEP_OF_TX_RATE_SWITCH];
+	u8 TxRateUpPenalty;	/* extra # of second penalty due to last unstable condition */
+	unsigned long CurrTxRateStableTime;	/* # of second in current TX rate */
+	BOOLEAN fNoisyEnvironment;
+	BOOLEAN fLastSecAccordingRSSI;
+	u8 LastSecTxRateChangeAction;	/* 0: no change, 1:rate UP, 2:rate down */
+	u8 LastTimeTxRateChangeAction;	/*Keep last time value of LastSecTxRateChangeAction */
+	unsigned long LastTxOkCount;
+};
 
-	// Ethernet Stats
-	ULONG       RcvAlignmentErrors;
-	ULONG       OneCollision;
-	ULONG       MoreCollisions;
+/***************************************************************************
+  *	security key related data structure
+  **************************************************************************/
+struct rt_cipher_key {
+	u8 Key[16];		/* right now we implement 4 keys, 128 bits max */
+	u8 RxMic[8];		/* make alignment */
+	u8 TxMic[8];
+	u8 TxTsc[6];		/* 48bit TSC value */
+	u8 RxTsc[6];		/* 48bit TSC value */
+	u8 CipherAlg;	/* 0-none, 1:WEP64, 2:WEP128, 3:TKIP, 4:AES, 5:CKIP64, 6:CKIP128 */
+	u8 KeyLen;
+	u8 BssId[6];
+	/* Key length for each key, 0: entry is invalid */
+	u8 Type;		/* Indicate Pairwise/Group when reporting MIC error */
+};
 
-} COUNTER_802_3, *PCOUNTER_802_3;
+/* structure to define WPA Group Key Rekey Interval */
+struct PACKED rt_802_11_wpa_rekey {
+	unsigned long ReKeyMethod;	/* mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based */
+	unsigned long ReKeyInterval;	/* time-based: seconds, packet-based: kilo-packets */
+};
 
-typedef struct _COUNTER_802_11 {
-	ULONG           Length;
-	LARGE_INTEGER   LastTransmittedFragmentCount;
-	LARGE_INTEGER   TransmittedFragmentCount;
-	LARGE_INTEGER   MulticastTransmittedFrameCount;
-	LARGE_INTEGER   FailedCount;
-	LARGE_INTEGER   RetryCount;
-	LARGE_INTEGER   MultipleRetryCount;
-	LARGE_INTEGER   RTSSuccessCount;
-	LARGE_INTEGER   RTSFailureCount;
-	LARGE_INTEGER   ACKFailureCount;
-	LARGE_INTEGER   FrameDuplicateCount;
-	LARGE_INTEGER   ReceivedFragmentCount;
-	LARGE_INTEGER   MulticastReceivedFrameCount;
-	LARGE_INTEGER   FCSErrorCount;
-} COUNTER_802_11, *PCOUNTER_802_11;
+#ifdef RTMP_MAC_USB
+/***************************************************************************
+  *	RTUSB I/O related data structure
+  **************************************************************************/
+struct rt_set_asic_wcid {
+	unsigned long WCID;		/* mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based */
+	unsigned long SetTid;		/* time-based: seconds, packet-based: kilo-packets */
+	unsigned long DeleteTid;	/* time-based: seconds, packet-based: kilo-packets */
+	u8 Addr[MAC_ADDR_LEN];	/* avoid in interrupt when write key */
+};
 
-typedef struct _COUNTER_RALINK {
-	ULONG           TransmittedByteCount;   // both successful and failure, used to calculate TX throughput
-#ifdef RT2860
-	ULONG           LastReceivedByteCount;
-#endif
-	ULONG           ReceivedByteCount;      // both CRC okay and CRC error, used to calculate RX throughput
-	ULONG           BeenDisassociatedCount;
-	ULONG           BadCQIAutoRecoveryCount;
-	ULONG           PoorCQIRoamingCount;
-	ULONG           MgmtRingFullCount;
-	ULONG           RxCountSinceLastNULL;
-	ULONG           RxCount;
-	ULONG           RxRingErrCount;
-	ULONG           KickTxCount;
-	ULONG           TxRingErrCount;
-	LARGE_INTEGER   RealFcsErrCount;
-	ULONG           PendingNdisPacketCount;
+struct rt_set_asic_wcid_attri {
+	unsigned long WCID;		/* mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based */
+	unsigned long Cipher;		/* ASIC Cipher definition */
+	u8 Addr[ETH_LENGTH_OF_ADDRESS];
+};
 
-	ULONG           OneSecOsTxCount[NUM_OF_TX_RING];
-	ULONG           OneSecDmaDoneCount[NUM_OF_TX_RING];
-	UINT32          OneSecTxDoneCount;
-	ULONG           OneSecRxCount;
-	UINT32          OneSecTxAggregationCount;
-	UINT32          OneSecRxAggregationCount;
+/* for USB interface, avoid in interrupt when write key */
+struct rt_add_pairwise_key_entry {
+	u8 MacAddr[6];
+	u16 MacTabMatchWCID;	/* ASIC */
+	struct rt_cipher_key CipherKey;
+};
 
-	UINT32   		OneSecFrameDuplicateCount;
+/* Cipher suite type for mixed mode group cipher, P802.11i-2004 */
+typedef enum _RT_802_11_CIPHER_SUITE_TYPE {
+	Cipher_Type_NONE,
+	Cipher_Type_WEP40,
+	Cipher_Type_TKIP,
+	Cipher_Type_RSVD,
+	Cipher_Type_CCMP,
+	Cipher_Type_WEP104
+} RT_802_11_CIPHER_SUITE_TYPE, *PRT_802_11_CIPHER_SUITE_TYPE;
+#endif /* RTMP_MAC_USB // */
 
-#ifdef RT2870
-	ULONG           OneSecTransmittedByteCount;   // both successful and failure, used to calculate TX throughput
-#endif // RT2870 //
+struct rt_rogueap_entry {
+	u8 Addr[MAC_ADDR_LEN];
+	u8 ErrorCode[2];	/*00 01-Invalid authentication type */
+	/*00 02-Authentication timeout */
+	/*00 03-Challenge from AP failed */
+	/*00 04-Challenge to AP failed */
+	BOOLEAN Reported;
+};
 
-	UINT32          OneSecTxNoRetryOkCount;
-	UINT32          OneSecTxRetryOkCount;
-	UINT32          OneSecTxFailCount;
-	UINT32          OneSecFalseCCACnt;      // CCA error count, for debug purpose, might move to global counter
-	UINT32          OneSecRxOkCnt;          // RX without error
-	UINT32          OneSecRxOkDataCnt;      // unicast-to-me DATA frame count
-	UINT32          OneSecRxFcsErrCnt;      // CRC error
-	UINT32          OneSecBeaconSentCnt;
-	UINT32          LastOneSecTotalTxCount; // OneSecTxNoRetryOkCount + OneSecTxRetryOkCount + OneSecTxFailCount
-	UINT32          LastOneSecRxOkDataCnt;  // OneSecRxOkDataCnt
-	ULONG		DuplicateRcv;
-	ULONG		TxAggCount;
-	ULONG		TxNonAggCount;
-	ULONG		TxAgg1MPDUCount;
-	ULONG		TxAgg2MPDUCount;
-	ULONG		TxAgg3MPDUCount;
-	ULONG		TxAgg4MPDUCount;
-	ULONG		TxAgg5MPDUCount;
-	ULONG		TxAgg6MPDUCount;
-	ULONG		TxAgg7MPDUCount;
-	ULONG		TxAgg8MPDUCount;
-	ULONG		TxAgg9MPDUCount;
-	ULONG		TxAgg10MPDUCount;
-	ULONG		TxAgg11MPDUCount;
-	ULONG		TxAgg12MPDUCount;
-	ULONG		TxAgg13MPDUCount;
-	ULONG		TxAgg14MPDUCount;
-	ULONG		TxAgg15MPDUCount;
-	ULONG		TxAgg16MPDUCount;
+struct rt_rogueap_table {
+	u8 RogueApNr;
+	struct rt_rogueap_entry RogueApEntry[MAX_LEN_OF_BSS_TABLE];
+};
 
-	LARGE_INTEGER       TransmittedOctetsInAMSDU;
-	LARGE_INTEGER       TransmittedAMSDUCount;
-	LARGE_INTEGER       ReceivedOctesInAMSDUCount;
-	LARGE_INTEGER       ReceivedAMSDUCount;
-	LARGE_INTEGER       TransmittedAMPDUCount;
-	LARGE_INTEGER       TransmittedMPDUsInAMPDUCount;
-	LARGE_INTEGER       TransmittedOctetsInAMPDUCount;
-	LARGE_INTEGER       MPDUInReceivedAMPDUCount;
-} COUNTER_RALINK, *PCOUNTER_RALINK;
+/* */
+/* Cisco IAPP format */
+/* */
+struct rt_cisco_iapp_content {
+	u16 Length;		/*IAPP Length */
+	u8 MessageType;	/*IAPP type */
+	u8 FunctionCode;	/*IAPP function type */
+	u8 DestinaionMAC[MAC_ADDR_LEN];
+	u8 SourceMAC[MAC_ADDR_LEN];
+	u16 Tag;		/*Tag(element IE) - Adjacent AP report */
+	u16 TagLength;	/*Length of element not including 4 byte header */
+	u8 OUI[4];		/*0x00, 0x40, 0x96, 0x00 */
+	u8 PreviousAP[MAC_ADDR_LEN];	/*MAC Address of access point */
+	u16 Channel;
+	u16 SsidLen;
+	u8 Ssid[MAX_LEN_OF_SSID];
+	u16 Seconds;		/*Seconds that the client has been disassociated. */
+};
 
-typedef struct _PID_COUNTER {
-	ULONG           TxAckRequiredCount;      // CRC error
-	ULONG           TxAggreCount;
-	ULONG           TxSuccessCount; // OneSecTxNoRetryOkCount + OneSecTxRetryOkCount + OneSecTxFailCount
-	ULONG		LastSuccessRate;
-} PID_COUNTER, *PPID_COUNTER;
+/*
+  *	Fragment Frame structure
+  */
+struct rt_fragment_frame {
+	void *pFragPacket;
+	unsigned long RxSize;
+	u16 Sequence;
+	u16 LastFrag;
+	unsigned long Flags;		/* Some extra frame information. bit 0: LLC presented */
+};
 
-typedef struct _COUNTER_DRS {
-	// to record the each TX rate's quality. 0 is best, the bigger the worse.
-	USHORT          TxQuality[MAX_STEP_OF_TX_RATE_SWITCH];
-	UCHAR           PER[MAX_STEP_OF_TX_RATE_SWITCH];
-	UCHAR           TxRateUpPenalty;      // extra # of second penalty due to last unstable condition
-	ULONG           CurrTxRateStableTime; // # of second in current TX rate
-	BOOLEAN         fNoisyEnvironment;
-	BOOLEAN         fLastSecAccordingRSSI;
-	UCHAR           LastSecTxRateChangeAction; // 0: no change, 1:rate UP, 2:rate down
-	UCHAR			LastTimeTxRateChangeAction; //Keep last time value of LastSecTxRateChangeAction
-	ULONG			LastTxOkCount;
-} COUNTER_DRS, *PCOUNTER_DRS;
+/* */
+/* Packet information for NdisQueryPacket */
+/* */
+struct rt_packet_info {
+	u32 PhysicalBufferCount;	/* Physical breaks of buffer descripor chained */
+	u32 BufferCount;	/* Number of Buffer descriptor chained */
+	u32 TotalPacketLength;	/* Self explained */
+	char *pFirstBuffer;	/* Pointer to first buffer descriptor */
+};
 
-//
-//  Arcfour Structure Added by PaulWu
-//
-typedef struct  _ARCFOUR
-{
-	UINT            X;
-	UINT            Y;
-	UCHAR           STATE[256];
-} ARCFOURCONTEXT, *PARCFOURCONTEXT;
+/* */
+/*  Arcfour Structure Added by PaulWu */
+/* */
+struct rt_arcfourcontext {
+	u32 X;
+	u32 Y;
+	u8 STATE[256];
+};
 
-// MIMO Tx parameter, ShortGI, MCS, STBC, etc.  these are fields in TXWI too. just copy to TXWI.
-typedef struct  _RECEIVE_SETTING {
-	USHORT   	NumOfRX:2;                 // MIMO. WE HAVE 3R
-	USHORT		Mode:2;	//channel bandwidth 20MHz or 40 MHz
-	USHORT		ShortGI:1;
-	USHORT		STBC:2;	//SPACE
-	USHORT		rsv:3;
-	USHORT		OFDM:1;
-	USHORT		MIMO:1;
- } RECEIVE_SETTING, *PRECEIVE_SETTING;
+/* */
+/* Tkip Key structure which RC4 key & MIC calculation */
+/* */
+struct rt_tkip_key_info {
+	u32 nBytesInM;		/* # bytes in M for MICKEY */
+	unsigned long IV16;
+	unsigned long IV32;
+	unsigned long K0;		/* for MICKEY Low */
+	unsigned long K1;		/* for MICKEY Hig */
+	unsigned long L;		/* Current state for MICKEY */
+	unsigned long R;		/* Current state for MICKEY */
+	unsigned long M;		/* Message accumulator for MICKEY */
+	u8 RC4KEY[16];
+	u8 MIC[8];
+};
 
-// Shared key data structure
-typedef struct  _WEP_KEY {
-	UCHAR   KeyLen;                     // Key length for each key, 0: entry is invalid
-	UCHAR   Key[MAX_LEN_OF_KEY];        // right now we implement 4 keys, 128 bits max
-} WEP_KEY, *PWEP_KEY;
+/* */
+/* Private / Misc data, counters for driver internal use */
+/* */
+struct rt_private {
+	u32 SystemResetCnt;	/* System reset counter */
+	u32 TxRingFullCnt;	/* Tx ring full occurrance number */
+	u32 PhyRxErrCnt;	/* PHY Rx error count, for debug purpose, might move to global counter */
+	/* Variables for WEP encryption / decryption in rtmp_wep.c */
+	u32 FCSCRC32;
+	struct rt_arcfourcontext WEPCONTEXT;
+	/* Tkip stuff */
+	struct rt_tkip_key_info Tx;
+	struct rt_tkip_key_info Rx;
+};
 
-typedef struct _CIPHER_KEY {
-	UCHAR   Key[16];            // right now we implement 4 keys, 128 bits max
-	UCHAR   RxMic[8];			// make alignment
-	UCHAR   TxMic[8];
-	UCHAR   TxTsc[6];           // 48bit TSC value
-	UCHAR   RxTsc[6];           // 48bit TSC value
-	UCHAR   CipherAlg;          // 0-none, 1:WEP64, 2:WEP128, 3:TKIP, 4:AES, 5:CKIP64, 6:CKIP128
-	UCHAR   KeyLen;
-	UCHAR   BssId[6];
-            // Key length for each key, 0: entry is invalid
-	UCHAR   Type;               // Indicate Pairwise/Group when reporting MIC error
-} CIPHER_KEY, *PCIPHER_KEY;
+/***************************************************************************
+  *	Channel and BBP related data structures
+  **************************************************************************/
+/* structure to tune BBP R66 (BBP TUNING) */
+struct rt_bbp_r66_tuning {
+	BOOLEAN bEnable;
+	u16 FalseCcaLowerThreshold;	/* default 100 */
+	u16 FalseCcaUpperThreshold;	/* default 512 */
+	u8 R66Delta;
+	u8 R66CurrentValue;
+	BOOLEAN R66LowerUpperSelect;	/*Before LinkUp, Used LowerBound or UpperBound as R66 value. */
+};
 
-typedef struct _BBP_TUNING_STRUCT {
-	BOOLEAN     Enable;
-	UCHAR       FalseCcaCountUpperBound;  // 100 per sec
-	UCHAR       FalseCcaCountLowerBound;  // 10 per sec
-	UCHAR       R17LowerBound;            // specified in E2PROM
-	UCHAR       R17UpperBound;            // 0x68 according to David Tung
-	UCHAR       CurrentR17Value;
-} BBP_TUNING, *PBBP_TUNING;
+/* structure to store channel TX power */
+struct rt_channel_tx_power {
+	u16 RemainingTimeForUse;	/*unit: sec */
+	u8 Channel;
+	char Power;
+	char Power2;
+	u8 MaxTxPwr;
+	u8 DfsReq;
+};
 
-typedef struct _SOFT_RX_ANT_DIVERSITY_STRUCT {
-	UCHAR     EvaluatePeriod;		 // 0:not evalute status, 1: evaluate status, 2: switching status
-#ifdef RT2870
-	UCHAR     EvaluateStableCnt;
-#endif
-	UCHAR     Pair1PrimaryRxAnt;     // 0:Ant-E1, 1:Ant-E2
-	UCHAR     Pair1SecondaryRxAnt;   // 0:Ant-E1, 1:Ant-E2
-	UCHAR     Pair2PrimaryRxAnt;     // 0:Ant-E3, 1:Ant-E4
-	UCHAR     Pair2SecondaryRxAnt;   // 0:Ant-E3, 1:Ant-E4
-	SHORT     Pair1AvgRssi[2];       // AvgRssi[0]:E1, AvgRssi[1]:E2
-	SHORT     Pair2AvgRssi[2];       // AvgRssi[0]:E3, AvgRssi[1]:E4
-	SHORT     Pair1LastAvgRssi;      //
-	SHORT     Pair2LastAvgRssi;      //
-	ULONG     RcvPktNumWhenEvaluate;
-	BOOLEAN   FirstPktArrivedWhenEvaluate;
-	RALINK_TIMER_STRUCT    RxAntDiversityTimer;
-} SOFT_RX_ANT_DIVERSITY, *PSOFT_RX_ANT_DIVERSITY;
+/* structure to store 802.11j channel TX power */
+struct rt_channel_11j_tx_power {
+	u8 Channel;
+	u8 BW;		/* BW_10 or BW_20 */
+	char Power;
+	char Power2;
+	u16 RemainingTimeForUse;	/*unit: sec */
+};
 
-typedef struct _LEAP_AUTH_INFO {
-	BOOLEAN         Enabled;        //Ture: Enable LEAP Authentication
-	BOOLEAN         CCKM;           //Ture: Use Fast Reauthentication with CCKM
-	UCHAR           Reserve[2];
-	UCHAR           UserName[256];  //LEAP, User name
-	ULONG           UserNameLen;
-	UCHAR           Password[256];  //LEAP, User Password
-	ULONG           PasswordLen;
-} LEAP_AUTH_INFO, *PLEAP_AUTH_INFO;
+struct rt_soft_rx_ant_diversity {
+	u8 EvaluatePeriod;	/* 0:not evalute status, 1: evaluate status, 2: switching status */
+	u8 EvaluateStableCnt;
+	u8 Pair1PrimaryRxAnt;	/* 0:Ant-E1, 1:Ant-E2 */
+	u8 Pair1SecondaryRxAnt;	/* 0:Ant-E1, 1:Ant-E2 */
+	u8 Pair2PrimaryRxAnt;	/* 0:Ant-E3, 1:Ant-E4 */
+	u8 Pair2SecondaryRxAnt;	/* 0:Ant-E3, 1:Ant-E4 */
+	short Pair1AvgRssi[2];	/* AvgRssi[0]:E1, AvgRssi[1]:E2 */
+	short Pair2AvgRssi[2];	/* AvgRssi[0]:E3, AvgRssi[1]:E4 */
+	short Pair1LastAvgRssi;	/* */
+	short Pair2LastAvgRssi;	/* */
+	unsigned long RcvPktNumWhenEvaluate;
+	BOOLEAN FirstPktArrivedWhenEvaluate;
+	struct rt_ralink_timer RxAntDiversityTimer;
+};
 
-typedef struct {
-	UCHAR        Addr[MAC_ADDR_LEN];
-	UCHAR        ErrorCode[2];  //00 01-Invalid authentication type
-								//00 02-Authentication timeout
-								//00 03-Challenge from AP failed
-								//00 04-Challenge to AP failed
-	BOOLEAN      Reported;
-} ROGUEAP_ENTRY, *PROGUEAP_ENTRY;
-
-typedef struct {
-	UCHAR               RogueApNr;
-	ROGUEAP_ENTRY       RogueApEntry[MAX_LEN_OF_BSS_TABLE];
-} ROGUEAP_TABLE, *PROGUEAP_TABLE;
-
-typedef struct {
-	BOOLEAN     Enable;
-	UCHAR       Delta;
-	BOOLEAN     PlusSign;
-} CCK_TX_POWER_CALIBRATE, *PCCK_TX_POWER_CALIBRATE;
-
-//
-// Receive Tuple Cache Format
-//
-typedef struct  _TUPLE_CACHE    {
-	BOOLEAN         Valid;
-	UCHAR           MacAddress[MAC_ADDR_LEN];
-	USHORT          Sequence;
-	USHORT          Frag;
-} TUPLE_CACHE, *PTUPLE_CACHE;
-
-//
-// Fragment Frame structure
-//
-typedef struct  _FRAGMENT_FRAME {
-	PNDIS_PACKET    pFragPacket;
-	ULONG       RxSize;
-	USHORT      Sequence;
-	USHORT      LastFrag;
-	ULONG       Flags;          // Some extra frame information. bit 0: LLC presented
-} FRAGMENT_FRAME, *PFRAGMENT_FRAME;
-
-
-//
-// Packet information for NdisQueryPacket
-//
-typedef struct  _PACKET_INFO    {
-	UINT            PhysicalBufferCount;    // Physical breaks of buffer descripor chained
-	UINT            BufferCount ;           // Number of Buffer descriptor chained
-	UINT            TotalPacketLength ;     // Self explained
-	PNDIS_BUFFER    pFirstBuffer;           // Pointer to first buffer descriptor
-} PACKET_INFO, *PPACKET_INFO;
-
-//
-// Tkip Key structure which RC4 key & MIC calculation
-//
-typedef struct  _TKIP_KEY_INFO  {
-	UINT        nBytesInM;  // # bytes in M for MICKEY
-	ULONG       IV16;
-	ULONG       IV32;
-	ULONG       K0;         // for MICKEY Low
-	ULONG       K1;         // for MICKEY Hig
-	ULONG       L;          // Current state for MICKEY
-	ULONG       R;          // Current state for MICKEY
-	ULONG       M;          // Message accumulator for MICKEY
-	UCHAR       RC4KEY[16];
-	UCHAR       MIC[8];
-} TKIP_KEY_INFO, *PTKIP_KEY_INFO;
-
-//
-// Private / Misc data, counters for driver internal use
-//
-typedef struct  __PRIVATE_STRUC {
-	UINT       SystemResetCnt;         // System reset counter
-	UINT       TxRingFullCnt;          // Tx ring full occurrance number
-	UINT       PhyRxErrCnt;            // PHY Rx error count, for debug purpose, might move to global counter
-	// Variables for WEP encryption / decryption in rtmp_wep.c
-	UINT       FCSCRC32;
-	ARCFOURCONTEXT  WEPCONTEXT;
-	// Tkip stuff
-	TKIP_KEY_INFO   Tx;
-	TKIP_KEY_INFO   Rx;
-} PRIVATE_STRUC, *PPRIVATE_STRUC;
-
-// structure to tune BBP R66 (BBP TUNING)
-typedef struct _BBP_R66_TUNING {
-	BOOLEAN     bEnable;
-	USHORT      FalseCcaLowerThreshold;  // default 100
-	USHORT      FalseCcaUpperThreshold;  // default 512
-	UCHAR       R66Delta;
-	UCHAR       R66CurrentValue;
-	BOOLEAN		R66LowerUpperSelect; //Before LinkUp, Used LowerBound or UpperBound as R66 value.
-} BBP_R66_TUNING, *PBBP_R66_TUNING;
-
-// structure to store channel TX power
-typedef struct _CHANNEL_TX_POWER {
-	USHORT     RemainingTimeForUse;		//unit: sec
-	UCHAR      Channel;
-	CHAR       Power;
-	CHAR       Power2;
-	UCHAR      MaxTxPwr;
-	UCHAR      DfsReq;
-} CHANNEL_TX_POWER, *PCHANNEL_TX_POWER;
-
-// structure to store 802.11j channel TX power
-typedef struct _CHANNEL_11J_TX_POWER {
-	UCHAR      Channel;
-	UCHAR      BW;	// BW_10 or BW_20
-	CHAR       Power;
-	CHAR       Power2;
-	USHORT     RemainingTimeForUse;		//unit: sec
-} CHANNEL_11J_TX_POWER, *PCHANNEL_11J_TX_POWER;
+/***************************************************************************
+  *	structure for radar detection and channel switch
+  **************************************************************************/
+struct rt_radar_detect {
+	/*BOOLEAN           IEEE80211H;                     // 0: disable, 1: enable IEEE802.11h */
+	u8 CSCount;		/*Channel switch counter */
+	u8 CSPeriod;		/*Channel switch period (beacon count) */
+	u8 RDCount;		/*Radar detection counter */
+	u8 RDMode;		/*Radar Detection mode */
+	u8 RDDurRegion;	/*Radar detection duration region */
+	u8 BBPR16;
+	u8 BBPR17;
+	u8 BBPR18;
+	u8 BBPR21;
+	u8 BBPR22;
+	u8 BBPR64;
+	unsigned long InServiceMonitorCount;	/* unit: sec */
+	u8 DfsSessionTime;
+	BOOLEAN bFastDfs;
+	u8 ChMovingTime;
+	u8 LongPulseRadarTh;
+};
 
 typedef enum _ABGBAND_STATE_ {
 	UNKNOWN_BAND,
@@ -1439,234 +861,291 @@
 	A_BAND,
 } ABGBAND_STATE;
 
-typedef struct _MLME_STRUCT {
-	// STA state machines
-	STATE_MACHINE           CntlMachine;
-	STATE_MACHINE           AssocMachine;
-	STATE_MACHINE           AuthMachine;
-	STATE_MACHINE           AuthRspMachine;
-	STATE_MACHINE           SyncMachine;
-	STATE_MACHINE           WpaPskMachine;
-	STATE_MACHINE           LeapMachine;
-	STATE_MACHINE           AironetMachine;
-	STATE_MACHINE_FUNC      AssocFunc[ASSOC_FUNC_SIZE];
-	STATE_MACHINE_FUNC      AuthFunc[AUTH_FUNC_SIZE];
-	STATE_MACHINE_FUNC      AuthRspFunc[AUTH_RSP_FUNC_SIZE];
-	STATE_MACHINE_FUNC      SyncFunc[SYNC_FUNC_SIZE];
-	STATE_MACHINE_FUNC      WpaPskFunc[WPA_PSK_FUNC_SIZE];
-	STATE_MACHINE_FUNC      AironetFunc[AIRONET_FUNC_SIZE];
-	STATE_MACHINE_FUNC      ActFunc[ACT_FUNC_SIZE];
-	// Action
-	STATE_MACHINE           ActMachine;
+#ifdef RTMP_MAC_PCI
+/* Power save method control */
+typedef union _PS_CONTROL {
+	struct {
+		unsigned long EnablePSinIdle:1;	/* Enable radio off when not connect to AP. radio on only when sitesurvey, */
+		unsigned long EnableNewPS:1;	/* Enable new  Chip power save fucntion . New method can only be applied in chip version after 2872. and PCIe. */
+		unsigned long rt30xxPowerMode:2;	/* Power Level Mode for rt30xx chip */
+		unsigned long rt30xxFollowHostASPM:1;	/* Card Follows Host's setting for rt30xx chip. */
+		unsigned long rt30xxForceASPMTest:1;	/* Force enable L1 for rt30xx chip. This has higher priority than rt30xxFollowHostASPM Mode. */
+		unsigned long rsv:26;	/* Radio Measurement Enable */
+	} field;
+	unsigned long word;
+} PS_CONTROL, *PPS_CONTROL;
+#endif /* RTMP_MAC_PCI // */
 
-	ULONG                   ChannelQuality;  // 0..100, Channel Quality Indication for Roaming
-	ULONG                   Now32;           // latch the value of NdisGetSystemUpTime()
-	ULONG                   LastSendNULLpsmTime;
+/***************************************************************************
+  *	structure for MLME state machine
+  **************************************************************************/
+struct rt_mlme {
+	/* STA state machines */
+	struct rt_state_machine CntlMachine;
+	struct rt_state_machine AssocMachine;
+	struct rt_state_machine AuthMachine;
+	struct rt_state_machine AuthRspMachine;
+	struct rt_state_machine SyncMachine;
+	struct rt_state_machine WpaPskMachine;
+	struct rt_state_machine LeapMachine;
+	STATE_MACHINE_FUNC AssocFunc[ASSOC_FUNC_SIZE];
+	STATE_MACHINE_FUNC AuthFunc[AUTH_FUNC_SIZE];
+	STATE_MACHINE_FUNC AuthRspFunc[AUTH_RSP_FUNC_SIZE];
+	STATE_MACHINE_FUNC SyncFunc[SYNC_FUNC_SIZE];
+	STATE_MACHINE_FUNC ActFunc[ACT_FUNC_SIZE];
+	/* Action */
+	struct rt_state_machine ActMachine;
 
-	BOOLEAN                 bRunning;
-	NDIS_SPIN_LOCK          TaskLock;
-	MLME_QUEUE              Queue;
+	/* common WPA state machine */
+	struct rt_state_machine WpaMachine;
+	STATE_MACHINE_FUNC WpaFunc[WPA_FUNC_SIZE];
 
-	UINT                    ShiftReg;
+	unsigned long ChannelQuality;	/* 0..100, Channel Quality Indication for Roaming */
+	unsigned long Now32;		/* latch the value of NdisGetSystemUpTime() */
+	unsigned long LastSendNULLpsmTime;
 
-	RALINK_TIMER_STRUCT     PeriodicTimer;
-	RALINK_TIMER_STRUCT     APSDPeriodicTimer;
-	RALINK_TIMER_STRUCT     LinkDownTimer;
-	RALINK_TIMER_STRUCT     LinkUpTimer;
-#ifdef RT2860
-    UCHAR                   bPsPollTimerRunning;
-    RALINK_TIMER_STRUCT     PsPollTimer;
-	RALINK_TIMER_STRUCT     RadioOnOffTimer;
-#endif
-	ULONG                   PeriodicRound;
-	ULONG                   OneSecPeriodicRound;
+	BOOLEAN bRunning;
+	spinlock_t TaskLock;
+	struct rt_mlme_queue Queue;
 
-	UCHAR					RealRxPath;
-	BOOLEAN					bLowThroughput;
-	BOOLEAN					bEnableAutoAntennaCheck;
-	RALINK_TIMER_STRUCT		RxAntEvalTimer;
+	u32 ShiftReg;
 
-#ifdef RT2870
-	UCHAR CaliBW40RfR24;
-	UCHAR CaliBW20RfR24;
-#endif // RT2870 //
-} MLME_STRUCT, *PMLME_STRUCT;
+	struct rt_ralink_timer PeriodicTimer;
+	struct rt_ralink_timer APSDPeriodicTimer;
+	struct rt_ralink_timer LinkDownTimer;
+	struct rt_ralink_timer LinkUpTimer;
+#ifdef RTMP_MAC_PCI
+	u8 bPsPollTimerRunning;
+	struct rt_ralink_timer PsPollTimer;
+	struct rt_ralink_timer RadioOnOffTimer;
+#endif				/* RTMP_MAC_PCI // */
+	unsigned long PeriodicRound;
+	unsigned long OneSecPeriodicRound;
 
-// structure for radar detection and channel switch
-typedef struct _RADAR_DETECT_STRUCT {
-	UCHAR		CSCount;			//Channel switch counter
-	UCHAR		CSPeriod;			//Channel switch period (beacon count)
-	UCHAR		RDCount;			//Radar detection counter
-	UCHAR		RDMode;				//Radar Detection mode
-	UCHAR		RDDurRegion;		//Radar detection duration region
-	UCHAR		BBPR16;
-	UCHAR		BBPR17;
-	UCHAR		BBPR18;
-	UCHAR		BBPR21;
-	UCHAR		BBPR22;
-	UCHAR		BBPR64;
-	ULONG		InServiceMonitorCount; // unit: sec
-	UINT8		DfsSessionTime;
-	BOOLEAN		bFastDfs;
-	UINT8		ChMovingTime;
-	UINT8		LongPulseRadarTh;
-} RADAR_DETECT_STRUCT, *PRADAR_DETECT_STRUCT;
+	u8 RealRxPath;
+	BOOLEAN bLowThroughput;
+	BOOLEAN bEnableAutoAntennaCheck;
+	struct rt_ralink_timer RxAntEvalTimer;
 
-typedef enum _REC_BLOCKACK_STATUS
-{
-    Recipient_NONE=0,
+#ifdef RT30xx
+	u8 CaliBW40RfR24;
+	u8 CaliBW20RfR24;
+#endif				/* RT30xx // */
+
+#ifdef RTMP_MAC_USB
+	struct rt_ralink_timer AutoWakeupTimer;
+	BOOLEAN AutoWakeupTimerRunning;
+#endif				/* RTMP_MAC_USB // */
+};
+
+/***************************************************************************
+  *	802.11 N related data structures
+  **************************************************************************/
+struct reordering_mpdu {
+	struct reordering_mpdu *next;
+	void *pPacket;	/* coverted to 802.3 frame */
+	int Sequence;		/* sequence number of MPDU */
+	BOOLEAN bAMSDU;
+};
+
+struct reordering_list {
+	struct reordering_mpdu *next;
+	int qlen;
+};
+
+struct reordering_mpdu_pool {
+	void *mem;
+	spinlock_t lock;
+	struct reordering_list freelist;
+};
+
+typedef enum _REC_BLOCKACK_STATUS {
+	Recipient_NONE = 0,
 	Recipient_USED,
 	Recipient_HandleRes,
-    Recipient_Accept
+	Recipient_Accept
 } REC_BLOCKACK_STATUS, *PREC_BLOCKACK_STATUS;
 
-typedef enum _ORI_BLOCKACK_STATUS
-{
-    Originator_NONE=0,
+typedef enum _ORI_BLOCKACK_STATUS {
+	Originator_NONE = 0,
 	Originator_USED,
-    Originator_WaitRes,
-    Originator_Done
+	Originator_WaitRes,
+	Originator_Done
 } ORI_BLOCKACK_STATUS, *PORI_BLOCKACK_STATUS;
 
-typedef struct _BA_ORI_ENTRY{
-	UCHAR   Wcid;
-	UCHAR   TID;
-	UCHAR   BAWinSize;
-	UCHAR   Token;
-// Sequence is to fill every outgoing QoS DATA frame's sequence field in 802.11 header.
-	USHORT	Sequence;
-	USHORT	TimeOutValue;
-	ORI_BLOCKACK_STATUS  ORI_BA_Status;
-	RALINK_TIMER_STRUCT ORIBATimer;
-	PVOID	pAdapter;
-} BA_ORI_ENTRY, *PBA_ORI_ENTRY;
+struct rt_ba_ori_entry {
+	u8 Wcid;
+	u8 TID;
+	u8 BAWinSize;
+	u8 Token;
+/* Sequence is to fill every outgoing QoS DATA frame's sequence field in 802.11 header. */
+	u16 Sequence;
+	u16 TimeOutValue;
+	ORI_BLOCKACK_STATUS ORI_BA_Status;
+	struct rt_ralink_timer ORIBATimer;
+	void *pAdapter;
+};
 
-typedef struct _BA_REC_ENTRY {
-	UCHAR   Wcid;
-	UCHAR   TID;
-	UCHAR   BAWinSize;	// 7.3.1.14. each buffer is capable of holding a max AMSDU or MSDU.
-	USHORT		LastIndSeq;
-	USHORT		TimeOutValue;
-	RALINK_TIMER_STRUCT RECBATimer;
-	ULONG		LastIndSeqAtTimer;
-	ULONG		nDropPacket;
-	ULONG		rcvSeq;
-	REC_BLOCKACK_STATUS  REC_BA_Status;
-	NDIS_SPIN_LOCK          RxReRingLock;                 // Rx Ring spinlock
-	PVOID	pAdapter;
-	struct reordering_list	list;
-} BA_REC_ENTRY, *PBA_REC_ENTRY;
+struct rt_ba_rec_entry {
+	u8 Wcid;
+	u8 TID;
+	u8 BAWinSize;	/* 7.3.1.14. each buffer is capable of holding a max AMSDU or MSDU. */
+	/*u8 NumOfRxPkt; */
+	/*u8    Curindidx; // the head in the RX reordering buffer */
+	u16 LastIndSeq;
+/*      u16          LastIndSeqAtTimer; */
+	u16 TimeOutValue;
+	struct rt_ralink_timer RECBATimer;
+	unsigned long LastIndSeqAtTimer;
+	unsigned long nDropPacket;
+	unsigned long rcvSeq;
+	REC_BLOCKACK_STATUS REC_BA_Status;
+/*      u8   RxBufIdxUsed; */
+	/* corresponding virtual address for RX reordering packet storage. */
+	/*RTMP_REORDERDMABUF MAP_RXBuf[MAX_RX_REORDERBUF]; */
+	spinlock_t RxReRingLock;	/* Rx Ring spinlock */
+/*      struct _BA_REC_ENTRY *pNext; */
+	void *pAdapter;
+	struct reordering_list list;
+};
 
+struct rt_ba_table {
+	unsigned long numAsRecipient;	/* I am recipient of numAsRecipient clients. These client are in the BARecEntry[] */
+	unsigned long numAsOriginator;	/* I am originator of   numAsOriginator clients. These clients are in the BAOriEntry[] */
+	unsigned long numDoneOriginator;	/* count Done Originator sessions */
+	struct rt_ba_ori_entry BAOriEntry[MAX_LEN_OF_BA_ORI_TABLE];
+	struct rt_ba_rec_entry BARecEntry[MAX_LEN_OF_BA_REC_TABLE];
+};
 
-typedef struct {
-	ULONG		numAsRecipient;		// I am recipient of numAsRecipient clients. These client are in the BARecEntry[]
-	ULONG		numAsOriginator;	// I am originator of 	numAsOriginator clients. These clients are in the BAOriEntry[]
-	BA_ORI_ENTRY       BAOriEntry[MAX_LEN_OF_BA_ORI_TABLE];
-	BA_REC_ENTRY       BARecEntry[MAX_LEN_OF_BA_REC_TABLE];
-} BA_TABLE, *PBA_TABLE;
+/*For QureyBATableOID use; */
+struct PACKED rt_oid_ba_rec_entry {
+	u8 MACAddr[MAC_ADDR_LEN];
+	u8 BaBitmap;		/* if (BaBitmap&(1<<TID)), this session with{MACAddr, TID}exists, so read BufSize[TID] for BufferSize */
+	u8 rsv;
+	u8 BufSize[8];
+	REC_BLOCKACK_STATUS REC_BA_Status[8];
+};
 
-//For QureyBATableOID use;
-typedef struct  PACKED _OID_BA_REC_ENTRY{
-	UCHAR   MACAddr[MAC_ADDR_LEN];
-	UCHAR   BaBitmap;   // if (BaBitmap&(1<<TID)), this session with{MACAddr, TID}exists, so read BufSize[TID] for BufferSize
-	UCHAR   rsv;
-	UCHAR   BufSize[8];
-	REC_BLOCKACK_STATUS	REC_BA_Status[8];
-} OID_BA_REC_ENTRY, *POID_BA_REC_ENTRY;
+/*For QureyBATableOID use; */
+struct PACKED rt_oid_ba_ori_entry {
+	u8 MACAddr[MAC_ADDR_LEN];
+	u8 BaBitmap;		/* if (BaBitmap&(1<<TID)), this session with{MACAddr, TID}exists, so read BufSize[TID] for BufferSize, read ORI_BA_Status[TID] for status */
+	u8 rsv;
+	u8 BufSize[8];
+	ORI_BLOCKACK_STATUS ORI_BA_Status[8];
+};
 
-//For QureyBATableOID use;
-typedef struct  PACKED _OID_BA_ORI_ENTRY{
-	UCHAR   MACAddr[MAC_ADDR_LEN];
-	UCHAR   BaBitmap;  // if (BaBitmap&(1<<TID)), this session with{MACAddr, TID}exists, so read BufSize[TID] for BufferSize, read ORI_BA_Status[TID] for status
-	UCHAR   rsv;
-	UCHAR   BufSize[8];
-	ORI_BLOCKACK_STATUS  ORI_BA_Status[8];
-} OID_BA_ORI_ENTRY, *POID_BA_ORI_ENTRY;
+struct rt_queryba_table {
+	struct rt_oid_ba_ori_entry BAOriEntry[32];
+	struct rt_oid_ba_rec_entry BARecEntry[32];
+	u8 OriNum;		/* Number of below BAOriEntry */
+	u8 RecNum;		/* Number of below BARecEntry */
+};
 
-typedef struct _QUERYBA_TABLE{
-	OID_BA_ORI_ENTRY       BAOriEntry[32];
-	OID_BA_REC_ENTRY       BARecEntry[32];
-	UCHAR   OriNum;// Number of below BAOriEntry
-	UCHAR   RecNum;// Number of below BARecEntry
-} QUERYBA_TABLE, *PQUERYBA_TABLE;
-
-typedef	union	_BACAP_STRUC	{
-	struct	{
-		UINT32		RxBAWinLimit:8;
-		UINT32		TxBAWinLimit:8;
-		UINT32		AutoBA:1;	// automatically BA
-		UINT32		Policy:2;	// 0: DELAY_BA 1:IMMED_BA  (//BA Policy subfiled value in ADDBA frame)   2:BA-not use
-		UINT32		MpduDensity:3;
-		UINT32       	AmsduEnable:1;	//Enable AMSDU transmisstion
-		UINT32       	AmsduSize:1;	// 0:3839, 1:7935 bytes. UINT  MSDUSizeToBytes[]	= { 3839, 7935};
-		UINT32       	MMPSmode:2;	// MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable
-		UINT32       	bHtAdhoc:1;			// adhoc can use ht rate.
-		UINT32       	b2040CoexistScanSup:1;		//As Sta, support do 2040 coexistence scan for AP. As Ap, support monitor trigger event to check if can use BW 40MHz.
-		UINT32       	:4;
-	}	field;
-	UINT32			word;
+typedef union _BACAP_STRUC {
+	struct {
+		u32 RxBAWinLimit:8;
+		u32 TxBAWinLimit:8;
+		u32 AutoBA:1;	/* automatically BA */
+		u32 Policy:2;	/* 0: DELAY_BA 1:IMMED_BA  (//BA Policy subfiled value in ADDBA frame)   2:BA-not use */
+		u32 MpduDensity:3;
+		u32 AmsduEnable:1;	/*Enable AMSDU transmisstion */
+		u32 AmsduSize:1;	/* 0:3839, 1:7935 bytes. u32  MSDUSizeToBytes[]        = { 3839, 7935}; */
+		u32 MMPSmode:2;	/* MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable */
+		u32 bHtAdhoc:1;	/* adhoc can use ht rate. */
+		u32 b2040CoexistScanSup:1;	/*As Sta, support do 2040 coexistence scan for AP. As Ap, support monitor trigger event to check if can use BW 40MHz. */
+		u32 : 4;
+	} field;
+	u32 word;
 } BACAP_STRUC, *PBACAP_STRUC;
 
-//This structure is for all 802.11n card InterOptibilityTest action. Reset all Num every n second.  (Details see MLMEPeriodic)
-typedef	struct	_IOT_STRUC	{
-	UCHAR			Threshold[2];
-	UCHAR			ReorderTimeOutNum[MAX_LEN_OF_BA_REC_TABLE];	// compare with threshold[0]
-	UCHAR			RefreshNum[MAX_LEN_OF_BA_REC_TABLE];	// compare with threshold[1]
-	ULONG			OneSecInWindowCount;
-	ULONG			OneSecFrameDuplicateCount;
-	ULONG			OneSecOutWindowCount;
-	UCHAR			DelOriAct;
-	UCHAR			DelRecAct;
-	UCHAR			RTSShortProt;
-	UCHAR			RTSLongProt;
-	BOOLEAN			bRTSLongProtOn;
-	BOOLEAN			bLastAtheros;
-    BOOLEAN			bCurrentAtheros;
-    BOOLEAN         bNowAtherosBurstOn;
-	BOOLEAN			bNextDisableRxBA;
-    BOOLEAN			bToggle;
-} IOT_STRUC, *PIOT_STRUC;
+struct rt_oid_add_ba_entry {
+	BOOLEAN IsRecipient;
+	u8 MACAddr[MAC_ADDR_LEN];
+	u8 TID;
+	u8 nMSDU;
+	u16 TimeOut;
+	BOOLEAN bAllTid;	/* If True, delete all TID for BA sessions with this MACaddr. */
+};
 
-// This is the registry setting for 802.11n transmit setting.  Used in advanced page.
+#define IS_HT_STA(_pMacEntry)	\
+	(_pMacEntry->MaxHTPhyMode.field.MODE >= MODE_HTMIX)
+
+#define IS_HT_RATE(_pMacEntry)	\
+	(_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
+
+#define PEER_IS_HT_RATE(_pMacEntry)	\
+	(_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
+
+/*This structure is for all 802.11n card InterOptibilityTest action. Reset all Num every n second.  (Details see MLMEPeriodic) */
+struct rt_iot {
+	u8 Threshold[2];
+	u8 ReorderTimeOutNum[MAX_LEN_OF_BA_REC_TABLE];	/* compare with threshold[0] */
+	u8 RefreshNum[MAX_LEN_OF_BA_REC_TABLE];	/* compare with threshold[1] */
+	unsigned long OneSecInWindowCount;
+	unsigned long OneSecFrameDuplicateCount;
+	unsigned long OneSecOutWindowCount;
+	u8 DelOriAct;
+	u8 DelRecAct;
+	u8 RTSShortProt;
+	u8 RTSLongProt;
+	BOOLEAN bRTSLongProtOn;
+	BOOLEAN bLastAtheros;
+	BOOLEAN bCurrentAtheros;
+	BOOLEAN bNowAtherosBurstOn;
+	BOOLEAN bNextDisableRxBA;
+	BOOLEAN bToggle;
+};
+
+/* This is the registry setting for 802.11n transmit setting.  Used in advanced page. */
 typedef union _REG_TRANSMIT_SETTING {
- struct {
-		 UINT32  rsv0:10;
-		 UINT32  TxBF:1;
-         UINT32  BW:1; //channel bandwidth 20MHz or 40 MHz
-         UINT32  ShortGI:1;
-         UINT32  STBC:1; //SPACE
-         UINT32  TRANSNO:2;
-         UINT32  HTMODE:1;
-         UINT32  EXTCHA:2;
-         UINT32  rsv:13;
-    } field;
- UINT32   word;
+	struct {
+		/*u32  PhyMode:4; */
+		/*u32  MCS:7;                 // MCS */
+		u32 rsv0:10;
+		u32 TxBF:1;
+		u32 BW:1;	/*channel bandwidth 20MHz or 40 MHz */
+		u32 ShortGI:1;
+		u32 STBC:1;	/*SPACE */
+		u32 TRANSNO:2;
+		u32 HTMODE:1;
+		u32 EXTCHA:2;
+		u32 rsv:13;
+	} field;
+	u32 word;
 } REG_TRANSMIT_SETTING, *PREG_TRANSMIT_SETTING;
 
-typedef union  _DESIRED_TRANSMIT_SETTING {
-	struct	{
-			USHORT   	MCS:7;                 	// MCS
-			USHORT		PhyMode:4;
-			USHORT	 	FixedTxMode:2;			// If MCS isn't AUTO, fix rate in CCK, OFDM or HT mode.
-			USHORT		rsv:3;
-	}	field;
-	USHORT		word;
- } DESIRED_TRANSMIT_SETTING, *PDESIRED_TRANSMIT_SETTING;
+typedef union _DESIRED_TRANSMIT_SETTING {
+	struct {
+		u16 MCS:7;	/* MCS */
+		u16 PhyMode:4;
+		u16 FixedTxMode:2;	/* If MCS isn't AUTO, fix rate in CCK, OFDM or HT mode. */
+		u16 rsv:3;
+	} field;
+	u16 word;
+} DESIRED_TRANSMIT_SETTING, *PDESIRED_TRANSMIT_SETTING;
 
-typedef struct {
-	BOOLEAN		IsRecipient;
-	UCHAR   MACAddr[MAC_ADDR_LEN];
-	UCHAR   TID;
-	UCHAR   nMSDU;
-	USHORT   TimeOut;
-	BOOLEAN bAllTid;  // If True, delete all TID for BA sessions with this MACaddr.
-} OID_ADD_BA_ENTRY, *POID_ADD_BA_ENTRY;
+#ifdef RTMP_MAC_USB
+/***************************************************************************
+  *	USB-based chip Beacon related data structures
+  **************************************************************************/
+#define BEACON_BITMAP_MASK		0xff
+struct rt_beacon_sync {
+	u8 BeaconBuf[HW_BEACON_MAX_COUNT][HW_BEACON_OFFSET];
+	u8 BeaconTxWI[HW_BEACON_MAX_COUNT][TXWI_SIZE];
+	unsigned long TimIELocationInBeacon[HW_BEACON_MAX_COUNT];
+	unsigned long CapabilityInfoLocationInBeacon[HW_BEACON_MAX_COUNT];
+	BOOLEAN EnableBeacon;	/* trigger to enable beacon transmission. */
+	u8 BeaconBitMap;	/* NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change. */
+	u8 DtimBitOn;	/* NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change. */
+};
+#endif /* RTMP_MAC_USB // */
 
-//
-// Multiple SSID structure
-//
-#define WLAN_MAX_NUM_OF_TIM			((MAX_LEN_OF_MAC_TABLE >> 3) + 1) /* /8 + 1 */
-#define WLAN_CT_TIM_BCMC_OFFSET		0 /* unit: 32B */
+/***************************************************************************
+  *	Multiple SSID related data structures
+  **************************************************************************/
+#define WLAN_MAX_NUM_OF_TIM			((MAX_LEN_OF_MAC_TABLE >> 3) + 1)	/* /8 + 1 */
+#define WLAN_CT_TIM_BCMC_OFFSET		0	/* unit: 32B */
 
 /* clear bcmc TIM bit */
 #define WLAN_MR_TIM_BCMC_CLEAR(apidx) \
@@ -1678,1322 +1157,1030 @@
 
 /* clear a station PS TIM bit */
 #define WLAN_MR_TIM_BIT_CLEAR(ad_p, apidx, wcid) \
-	{	UCHAR tim_offset = wcid >> 3; \
-		UCHAR bit_offset = wcid & 0x7; \
+	{	u8 tim_offset = wcid >> 3; \
+		u8 bit_offset = wcid & 0x7; \
 		ad_p->ApCfg.MBSSID[apidx].TimBitmaps[tim_offset] &= (~BIT8[bit_offset]); }
 
 /* set a station PS TIM bit */
 #define WLAN_MR_TIM_BIT_SET(ad_p, apidx, wcid) \
-	{	UCHAR tim_offset = wcid >> 3; \
-		UCHAR bit_offset = wcid & 0x7; \
+	{	u8 tim_offset = wcid >> 3; \
+		u8 bit_offset = wcid & 0x7; \
 		ad_p->ApCfg.MBSSID[apidx].TimBitmaps[tim_offset] |= BIT8[bit_offset]; }
 
-#ifdef RT2870
-#define BEACON_BITMAP_MASK		0xff
-typedef struct _BEACON_SYNC_STRUCT_
-{
-	UCHAR        			BeaconBuf[HW_BEACON_MAX_COUNT][HW_BEACON_OFFSET];
-	UCHAR					BeaconTxWI[HW_BEACON_MAX_COUNT][TXWI_SIZE];
-	ULONG 					TimIELocationInBeacon[HW_BEACON_MAX_COUNT];
-	ULONG					CapabilityInfoLocationInBeacon[HW_BEACON_MAX_COUNT];
-	BOOLEAN					EnableBeacon;		// trigger to enable beacon transmission.
-	UCHAR					BeaconBitMap;		// NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change.
-	UCHAR					DtimBitOn;			// NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change.
-}BEACON_SYNC_STRUCT;
-#endif // RT2870 //
+/* configuration common to OPMODE_AP as well as OPMODE_STA */
+struct rt_common_config {
 
-typedef struct _MULTISSID_STRUCT {
-	UCHAR								Bssid[MAC_ADDR_LEN];
-    UCHAR                               SsidLen;
-    CHAR                                Ssid[MAX_LEN_OF_SSID];
-    USHORT                              CapabilityInfo;
+	BOOLEAN bCountryFlag;
+	u8 CountryCode[3];
+	u8 Geography;
+	u8 CountryRegion;	/* Enum of country region, 0:FCC, 1:IC, 2:ETSI, 3:SPAIN, 4:France, 5:MKK, 6:MKK1, 7:Israel */
+	u8 CountryRegionForABand;	/* Enum of country region for A band */
+	u8 PhyMode;		/* PHY_11A, PHY_11B, PHY_11BG_MIXED, PHY_ABG_MIXED */
+	u16 Dsifs;		/* in units of usec */
+	unsigned long PacketFilter;	/* Packet filter for receiving */
+	u8 RegulatoryClass;
 
-    PNET_DEV                   			MSSIDDev;
+	char Ssid[MAX_LEN_OF_SSID];	/* NOT NULL-terminated */
+	u8 SsidLen;		/* the actual ssid length in used */
+	u8 LastSsidLen;	/* the actual ssid length in used */
+	char LastSsid[MAX_LEN_OF_SSID];	/* NOT NULL-terminated */
+	u8 LastBssid[MAC_ADDR_LEN];
 
-	NDIS_802_11_AUTHENTICATION_MODE     AuthMode;
-	NDIS_802_11_WEP_STATUS              WepStatus;
-	NDIS_802_11_WEP_STATUS				GroupKeyWepStatus;
-	WPA_MIX_PAIR_CIPHER					WpaMixPairCipher;
+	u8 Bssid[MAC_ADDR_LEN];
+	u16 BeaconPeriod;
+	u8 Channel;
+	u8 CentralChannel;	/* Central Channel when using 40MHz is indicating. not real channel. */
 
-	ULONG								TxCount;
-	ULONG								RxCount;
-	ULONG								ReceivedByteCount;
-	ULONG								TransmittedByteCount;
-	ULONG								RxErrorCount;
-	ULONG								RxDropCount;
+	u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES];
+	u8 SupRateLen;
+	u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+	u8 ExtRateLen;
+	u8 DesireRate[MAX_LEN_OF_SUPPORTED_RATES];	/* OID_802_11_DESIRED_RATES */
+	u8 MaxDesiredRate;
+	u8 ExpectedACKRate[MAX_LEN_OF_SUPPORTED_RATES];
 
-	HTTRANSMIT_SETTING					HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
-	RT_HT_PHY_INFO						DesiredHtPhyInfo;
-	DESIRED_TRANSMIT_SETTING        	DesiredTransmitSetting; // Desired transmit setting. this is for reading registry setting only. not useful.
-	BOOLEAN								bAutoTxRateSwitch;
+	unsigned long BasicRateBitmap;	/* backup basic ratebitmap */
 
-	UCHAR                               DefaultKeyId;
+	BOOLEAN bAPSDCapable;
+	BOOLEAN bInServicePeriod;
+	BOOLEAN bAPSDAC_BE;
+	BOOLEAN bAPSDAC_BK;
+	BOOLEAN bAPSDAC_VI;
+	BOOLEAN bAPSDAC_VO;
 
-	UCHAR								TxRate;       // RATE_1, RATE_2, RATE_5_5, RATE_11, ...
-	UCHAR     							DesiredRates[MAX_LEN_OF_SUPPORTED_RATES];// OID_802_11_DESIRED_RATES
-	UCHAR								DesiredRatesIndex;
-	UCHAR     							MaxTxRate;            // RATE_1, RATE_2, RATE_5_5, RATE_11
+	/* because TSPEC can modify the APSD flag, we need to keep the APSD flag
+	   requested in association stage from the station;
+	   we need to recover the APSD flag after the TSPEC is deleted. */
+	BOOLEAN bACMAPSDBackup[4];	/* for delivery-enabled & trigger-enabled both */
+	BOOLEAN bACMAPSDTr[4];	/* no use */
 
-	UCHAR								TimBitmaps[WLAN_MAX_NUM_OF_TIM];
+	BOOLEAN bNeedSendTriggerFrame;
+	BOOLEAN bAPSDForcePowerSave;	/* Force power save mode, should only use in APSD-STAUT */
+	unsigned long TriggerTimerCount;
+	u8 MaxSPLength;
+	u8 BBPCurrentBW;	/* BW_10,       BW_20, BW_40 */
+	/* move to MULTISSID_STRUCT for MBSS */
+	/*HTTRANSMIT_SETTING    HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI. */
+	REG_TRANSMIT_SETTING RegTransmitSetting;	/*registry transmit setting. this is for reading registry setting only. not useful. */
+	/*u8       FixedTxMode;              // Fixed Tx Mode (CCK, OFDM), for HT fixed tx mode (GF, MIX) , refer to RegTransmitSetting.field.HTMode */
+	u8 TxRate;		/* Same value to fill in TXD. TxRate is 6-bit */
+	u8 MaxTxRate;	/* RATE_1, RATE_2, RATE_5_5, RATE_11 */
+	u8 TxRateIndex;	/* Tx rate index in RateSwitchTable */
+	u8 TxRateTableSize;	/* Valid Tx rate table size in RateSwitchTable */
+	/*BOOLEAN               bAutoTxRateSwitch; */
+	u8 MinTxRate;	/* RATE_1, RATE_2, RATE_5_5, RATE_11 */
+	u8 RtsRate;		/* RATE_xxx */
+	HTTRANSMIT_SETTING MlmeTransmit;	/* MGMT frame PHY rate setting when operatin at Ht rate. */
+	u8 MlmeRate;		/* RATE_xxx, used to send MLME frames */
+	u8 BasicMlmeRate;	/* Default Rate for sending MLME frames */
 
-    // WPA
-    UCHAR                               GMK[32];
-    UCHAR                               PMK[32];
-	UCHAR								GTK[32];
-    BOOLEAN                             IEEE8021X;
-    BOOLEAN                             PreAuth;
-    UCHAR                               GNonce[32];
-    UCHAR                               PortSecured;
-    NDIS_802_11_PRIVACY_FILTER          PrivacyFilter;
-    UCHAR                               BANClass3Data;
-    ULONG                               IsolateInterStaTraffic;
+	u16 RtsThreshold;	/* in unit of BYTE */
+	u16 FragmentThreshold;	/* in unit of BYTE */
 
-    UCHAR                               RSNIE_Len[2];
-    UCHAR                               RSN_IE[2][MAX_LEN_OF_RSNIE];
+	u8 TxPower;		/* in unit of mW */
+	unsigned long TxPowerPercentage;	/* 0~100 % */
+	unsigned long TxPowerDefault;	/* keep for TxPowerPercentage */
+	u8 PwrConstraint;
 
+	BACAP_STRUC BACapability;	/*   NO USE = 0XFF  ;  IMMED_BA =1  ;  DELAY_BA=0 */
+	BACAP_STRUC REGBACapability;	/*   NO USE = 0XFF  ;  IMMED_BA =1  ;  DELAY_BA=0 */
 
-    UCHAR                   			TimIELocationInBeacon;
-    UCHAR                   			CapabilityInfoLocationInBeacon;
-    // outgoing BEACON frame buffer and corresponding TXWI
-	// PTXWI_STRUC                           BeaconTxWI; //
-    CHAR                                BeaconBuf[MAX_BEACON_SIZE]; // NOTE: BeaconBuf should be 4-byte aligned
+	struct rt_iot IOTestParm;	/* 802.11n InterOpbility Test Parameter; */
+	unsigned long TxPreamble;	/* Rt802_11PreambleLong, Rt802_11PreambleShort, Rt802_11PreambleAuto */
+	BOOLEAN bUseZeroToDisableFragment;	/* Microsoft use 0 as disable */
+	unsigned long UseBGProtection;	/* 0: auto, 1: always use, 2: always not use */
+	BOOLEAN bUseShortSlotTime;	/* 0: disable, 1 - use short slot (9us) */
+	BOOLEAN bEnableTxBurst;	/* 1: enble TX PACKET BURST (when BA is established or AP is not a legacy WMM AP), 0: disable TX PACKET BURST */
+	BOOLEAN bAggregationCapable;	/* 1: enable TX aggregation when the peer supports it */
+	BOOLEAN bPiggyBackCapable;	/* 1: enable TX piggy-back according MAC's version */
+	BOOLEAN bIEEE80211H;	/* 1: enable IEEE802.11h spec. */
+	unsigned long DisableOLBCDetect;	/* 0: enable OLBC detect; 1 disable OLBC detect */
 
-    BOOLEAN                             bHideSsid;
-	UINT16								StationKeepAliveTime; // unit: second
+	BOOLEAN bRdg;
 
-    USHORT                              VLAN_VID;
-    USHORT                              VLAN_Priority;
+	BOOLEAN bWmmCapable;	/* 0:disable WMM, 1:enable WMM */
+	struct rt_qos_capability_parm APQosCapability;	/* QOS capability of the current associated AP */
+	struct rt_edca_parm APEdcaParm;	/* EDCA parameters of the current associated AP */
+	struct rt_qbss_load_parm APQbssLoad;	/* QBSS load of the current associated AP */
+	u8 AckPolicy[4];	/* ACK policy of the specified AC. see ACK_xxx */
+	BOOLEAN bDLSCapable;	/* 0:disable DLS, 1:enable DLS */
+	/* a bitmap of BOOLEAN flags. each bit represent an operation status of a particular */
+	/* BOOLEAN control, either ON or OFF. These flags should always be accessed via */
+	/* OPSTATUS_TEST_FLAG(), OPSTATUS_SET_FLAG(), OP_STATUS_CLEAR_FLAG() macros. */
+	/* see fOP_STATUS_xxx in RTMP_DEF.C for detail bit definition */
+	unsigned long OpStatusFlags;
 
-    RT_802_11_ACL						AccessControlList;
+	BOOLEAN NdisRadioStateOff;	/*For HCT 12.0, set this flag to TRUE instead of called MlmeRadioOff. */
+	ABGBAND_STATE BandState;	/* For setting BBP used on B/G or A mode. */
 
-	// EDCA Qos
-    BOOLEAN								bWmmCapable;	// 0:disable WMM, 1:enable WMM
-    BOOLEAN								bDLSCapable;	// 0:disable DLS, 1:enable DLS
+	/* IEEE802.11H--DFS. */
+	struct rt_radar_detect RadarDetect;
 
-	UCHAR           					DlsPTK[64];		// Due to windows dirver count on meetinghouse to handle 4-way shake
+	/* HT */
+	u8 BASize;		/* USer desired BAWindowSize. Should not exceed our max capability */
+	/*struct rt_ht_capability      SupportedHtPhy; */
+	struct rt_ht_capability DesiredHtPhy;
+	struct rt_ht_capability_ie HtCapability;
+	struct rt_add_ht_info_ie AddHTInfo;	/* Useful as AP. */
+	/*This IE is used with channel switch announcement element when changing to a new 40MHz. */
+	/*This IE is included in channel switch ammouncement frames 7.4.1.5, beacons, probe Rsp. */
+	struct rt_new_ext_chan_ie NewExtChanOffset;	/*7.3.2.20A, 1 if extension channel is above the control channel, 3 if below, 0 if not present */
 
-	// For 802.1x daemon setting per BSS
-	UCHAR								radius_srv_num;
-	RADIUS_SRV_INFO						radius_srv_info[MAX_RADIUS_SRV_NUM];
+	BOOLEAN bHTProtect;
+	BOOLEAN bMIMOPSEnable;
+	BOOLEAN bBADecline;
+/*2008/11/05: KH add to support Antenna power-saving of AP<-- */
+	BOOLEAN bGreenAPEnable;
+/*2008/11/05: KH add to support Antenna power-saving of AP--> */
+	BOOLEAN bDisableReordering;
+	BOOLEAN bForty_Mhz_Intolerant;
+	BOOLEAN bExtChannelSwitchAnnouncement;
+	BOOLEAN bRcvBSSWidthTriggerEvents;
+	unsigned long LastRcvBSSWidthTriggerEventsTime;
 
-#ifdef RTL865X_SOC
-	unsigned int						mylinkid;
+	u8 TxBASize;
+
+	/* Enable wireless event */
+	BOOLEAN bWirelessEvent;
+	BOOLEAN bWiFiTest;	/* Enable this parameter for WiFi test */
+
+	/* Tx & Rx Stream number selection */
+	u8 TxStream;
+	u8 RxStream;
+
+	BOOLEAN bHardwareRadio;	/* Hardware controlled Radio enabled */
+
+#ifdef RTMP_MAC_USB
+	BOOLEAN bMultipleIRP;	/* Multiple Bulk IN flag */
+	u8 NumOfBulkInIRP;	/* if bMultipleIRP == TRUE, NumOfBulkInIRP will be 4 otherwise be 1 */
+	struct rt_ht_capability SupportedHtPhy;
+	unsigned long MaxPktOneTxBulk;
+	u8 TxBulkFactor;
+	u8 RxBulkFactor;
+
+	BOOLEAN IsUpdateBeacon;
+	struct rt_beacon_sync *pBeaconSync;
+	struct rt_ralink_timer BeaconUpdateTimer;
+	u32 BeaconAdjust;
+	u32 BeaconFactor;
+	u32 BeaconRemain;
+#endif				/* RTMP_MAC_USB // */
+
+	spinlock_t MeasureReqTabLock;
+	struct rt_measure_req_tab *pMeasureReqTab;
+
+	spinlock_t TpcReqTabLock;
+	struct rt_tpc_req_tab *pTpcReqTab;
+
+	BOOLEAN PSPXlink;	/* 0: Disable. 1: Enable */
+
+#if defined(RT305x)||defined(RT30xx)
+	/* request by Gary, for High Power issue */
+	u8 HighPowerPatchDisabled;
 #endif
 
-
-	UINT32					RcvdConflictSsidCount;
-	UINT32					RcvdSpoofedAssocRespCount;
-	UINT32					RcvdSpoofedReassocRespCount;
-	UINT32					RcvdSpoofedProbeRespCount;
-	UINT32					RcvdSpoofedBeaconCount;
-	UINT32					RcvdSpoofedDisassocCount;
-	UINT32					RcvdSpoofedAuthCount;
-	UINT32					RcvdSpoofedDeauthCount;
-	UINT32					RcvdSpoofedUnknownMgmtCount;
-	UINT32					RcvdReplayAttackCount;
-
-	CHAR					RssiOfRcvdConflictSsid;
-	CHAR					RssiOfRcvdSpoofedAssocResp;
-	CHAR					RssiOfRcvdSpoofedReassocResp;
-	CHAR					RssiOfRcvdSpoofedProbeResp;
-	CHAR					RssiOfRcvdSpoofedBeacon;
-	CHAR					RssiOfRcvdSpoofedDisassoc;
-	CHAR					RssiOfRcvdSpoofedAuth;
-	CHAR					RssiOfRcvdSpoofedDeauth;
-	CHAR					RssiOfRcvdSpoofedUnknownMgmt;
-	CHAR					RssiOfRcvdReplayAttack;
-
-	BOOLEAN					bBcnSntReq;
-	UCHAR					BcnBufIdx;
-} MULTISSID_STRUCT, *PMULTISSID_STRUCT;
-
-// configuration common to OPMODE_AP as well as OPMODE_STA
-typedef struct _COMMON_CONFIG {
-
-	BOOLEAN		bCountryFlag;
-	UCHAR		CountryCode[3];
-	UCHAR		Geography;
-	UCHAR       CountryRegion;      // Enum of country region, 0:FCC, 1:IC, 2:ETSI, 3:SPAIN, 4:France, 5:MKK, 6:MKK1, 7:Israel
-	UCHAR       CountryRegionForABand;	// Enum of country region for A band
-	UCHAR       PhyMode;            // PHY_11A, PHY_11B, PHY_11BG_MIXED, PHY_ABG_MIXED
-	USHORT      Dsifs;              // in units of usec
-	ULONG       PacketFilter;       // Packet filter for receiving
-
-	CHAR        Ssid[MAX_LEN_OF_SSID]; // NOT NULL-terminated
-	UCHAR       SsidLen;               // the actual ssid length in used
-	UCHAR       LastSsidLen;               // the actual ssid length in used
-	CHAR        LastSsid[MAX_LEN_OF_SSID]; // NOT NULL-terminated
-	UCHAR		LastBssid[MAC_ADDR_LEN];
-
-	UCHAR       Bssid[MAC_ADDR_LEN];
-	USHORT      BeaconPeriod;
-	UCHAR       Channel;
-	UCHAR       CentralChannel;    	// Central Channel when using 40MHz is indicating. not real channel.
-
-	UCHAR       SupRate[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR       SupRateLen;
-	UCHAR       ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR       ExtRateLen;
-	UCHAR       DesireRate[MAX_LEN_OF_SUPPORTED_RATES];      // OID_802_11_DESIRED_RATES
-	UCHAR       MaxDesiredRate;
-	UCHAR       ExpectedACKRate[MAX_LEN_OF_SUPPORTED_RATES];
-
-	ULONG       BasicRateBitmap;        // backup basic ratebitmap
-
-	BOOLEAN		bAPSDCapable;
-	BOOLEAN		bInServicePeriod;
-	BOOLEAN		bAPSDAC_BE;
-	BOOLEAN		bAPSDAC_BK;
-	BOOLEAN		bAPSDAC_VI;
-	BOOLEAN		bAPSDAC_VO;
-	BOOLEAN		bNeedSendTriggerFrame;
-	BOOLEAN		bAPSDForcePowerSave;	// Force power save mode, should only use in APSD-STAUT
-	ULONG		TriggerTimerCount;
-	UCHAR		MaxSPLength;
-	UCHAR		BBPCurrentBW;	// BW_10, 	BW_20, BW_40
-	REG_TRANSMIT_SETTING        RegTransmitSetting; //registry transmit setting. this is for reading registry setting only. not useful.
-	UCHAR       TxRate;                 // Same value to fill in TXD. TxRate is 6-bit
-	UCHAR       MaxTxRate;              // RATE_1, RATE_2, RATE_5_5, RATE_11
-	UCHAR       TxRateIndex;            // Tx rate index in RateSwitchTable
-	UCHAR       TxRateTableSize;        // Valid Tx rate table size in RateSwitchTable
-	UCHAR       MinTxRate;              // RATE_1, RATE_2, RATE_5_5, RATE_11
-	UCHAR       RtsRate;                // RATE_xxx
-	HTTRANSMIT_SETTING	MlmeTransmit;   // MGMT frame PHY rate setting when operatin at Ht rate.
-	UCHAR       MlmeRate;               // RATE_xxx, used to send MLME frames
-	UCHAR       BasicMlmeRate;          // Default Rate for sending MLME frames
-
-	USHORT      RtsThreshold;           // in unit of BYTE
-	USHORT      FragmentThreshold;      // in unit of BYTE
-
-	UCHAR       TxPower;                // in unit of mW
-	ULONG       TxPowerPercentage;      // 0~100 %
-	ULONG       TxPowerDefault;         // keep for TxPowerPercentage
-
-	BACAP_STRUC        BACapability; //   NO USE = 0XFF  ;  IMMED_BA =1  ;  DELAY_BA=0
-	BACAP_STRUC        REGBACapability; //   NO USE = 0XFF  ;  IMMED_BA =1  ;  DELAY_BA=0
-
-	IOT_STRUC		IOTestParm;	// 802.11n InterOpbility Test Parameter;
-	ULONG       TxPreamble;             // Rt802_11PreambleLong, Rt802_11PreambleShort, Rt802_11PreambleAuto
-	BOOLEAN     bUseZeroToDisableFragment;     // Microsoft use 0 as disable
-	ULONG       UseBGProtection;        // 0: auto, 1: always use, 2: always not use
-	BOOLEAN     bUseShortSlotTime;      // 0: disable, 1 - use short slot (9us)
-	BOOLEAN     bEnableTxBurst;         // 1: enble TX PACKET BURST, 0: disable TX PACKET BURST
-	BOOLEAN     bAggregationCapable;      // 1: enable TX aggregation when the peer supports it
-	BOOLEAN     bPiggyBackCapable;		// 1: enable TX piggy-back according MAC's version
-	BOOLEAN     bIEEE80211H;			// 1: enable IEEE802.11h spec.
-	ULONG		DisableOLBCDetect;		// 0: enable OLBC detect; 1 disable OLBC detect
-
-	BOOLEAN				bRdg;
-
-	BOOLEAN             bWmmCapable;        // 0:disable WMM, 1:enable WMM
-	QOS_CAPABILITY_PARM APQosCapability;    // QOS capability of the current associated AP
-	EDCA_PARM           APEdcaParm;         // EDCA parameters of the current associated AP
-	QBSS_LOAD_PARM      APQbssLoad;         // QBSS load of the current associated AP
-	UCHAR               AckPolicy[4];       // ACK policy of the specified AC. see ACK_xxx
-	BOOLEAN				bDLSCapable;		// 0:disable DLS, 1:enable DLS
-	// a bitmap of BOOLEAN flags. each bit represent an operation status of a particular
-	// BOOLEAN control, either ON or OFF. These flags should always be accessed via
-	// OPSTATUS_TEST_FLAG(), OPSTATUS_SET_FLAG(), OP_STATUS_CLEAR_FLAG() macros.
-	// see fOP_STATUS_xxx in RTMP_DEF.C for detail bit definition
-	ULONG               OpStatusFlags;
-
-	BOOLEAN				NdisRadioStateOff; //For HCT 12.0, set this flag to TRUE instead of called MlmeRadioOff.
-	ABGBAND_STATE		BandState;		// For setting BBP used on B/G or A mode.
-
-	// IEEE802.11H--DFS.
-	RADAR_DETECT_STRUCT	RadarDetect;
-
-	// HT
-	UCHAR			BASize;		// USer desired BAWindowSize. Should not exceed our max capability
-	//RT_HT_CAPABILITY	SupportedHtPhy;
-	RT_HT_CAPABILITY	DesiredHtPhy;
-	HT_CAPABILITY_IE		HtCapability;
-	ADD_HT_INFO_IE		AddHTInfo;	// Useful as AP.
-	//This IE is used with channel switch announcement element when changing to a new 40MHz.
-	//This IE is included in channel switch ammouncement frames 7.4.1.5, beacons, probe Rsp.
-	NEW_EXT_CHAN_IE	NewExtChanOffset;	//7.3.2.20A, 1 if extension channel is above the control channel, 3 if below, 0 if not present
-
-    BOOLEAN                 bHTProtect;
-    BOOLEAN                 bMIMOPSEnable;
-    BOOLEAN					bBADecline;
-	BOOLEAN					bDisableReordering;
-	BOOLEAN					bForty_Mhz_Intolerant;
-	BOOLEAN					bExtChannelSwitchAnnouncement;
-	BOOLEAN					bRcvBSSWidthTriggerEvents;
-	ULONG					LastRcvBSSWidthTriggerEventsTime;
-
-	UCHAR					TxBASize;
-
-	// Enable wireless event
-	BOOLEAN				bWirelessEvent;
-	BOOLEAN				bWiFiTest;				// Enable this parameter for WiFi test
-
-	// Tx & Rx Stream number selection
-	UCHAR				TxStream;
-	UCHAR				RxStream;
-
-	// transmit phy mode, trasmit rate for Multicast.
-#ifdef MCAST_RATE_SPECIFIC
-	UCHAR				McastTransmitMcs;
-	UCHAR				McastTransmitPhyMode;
-#endif // MCAST_RATE_SPECIFIC //
-
-	BOOLEAN     		bHardwareRadio;     // Hardware controlled Radio enabled
-
-#ifdef RT2870
-	BOOLEAN     		bMultipleIRP;       // Multiple Bulk IN flag
-	UCHAR       		NumOfBulkInIRP;     // if bMultipleIRP == TRUE, NumOfBulkInIRP will be 4 otherwise be 1
- 	RT_HT_CAPABILITY	SupportedHtPhy;
-	ULONG				MaxPktOneTxBulk;
-	UCHAR				TxBulkFactor;
-	UCHAR				RxBulkFactor;
-
-	BEACON_SYNC_STRUCT	*pBeaconSync;
-	RALINK_TIMER_STRUCT	BeaconUpdateTimer;
-	UINT32				BeaconAdjust;
-	UINT32				BeaconFactor;
-	UINT32				BeaconRemain;
-#endif // RT2870 //
-
-
- 	NDIS_SPIN_LOCK			MeasureReqTabLock;
-	PMEASURE_REQ_TAB		pMeasureReqTab;
-
-	NDIS_SPIN_LOCK			TpcReqTabLock;
-	PTPC_REQ_TAB			pTpcReqTab;
-
-	// transmit phy mode, trasmit rate for Multicast.
-#ifdef MCAST_RATE_SPECIFIC
-	HTTRANSMIT_SETTING		MCastPhyMode;
-#endif // MCAST_RATE_SPECIFIC //
-} COMMON_CONFIG, *PCOMMON_CONFIG;
+	BOOLEAN HT_DisallowTKIP;	/* Restrict the encryption type in 11n HT mode */
+};
 
 /* Modified by Wu Xi-Kun 4/21/2006 */
-// STA configuration and status
-typedef struct _STA_ADMIN_CONFIG {
-	// GROUP 1 -
-	//   User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe
-	//   the user intended configuration, but not necessary fully equal to the final
-	//   settings in ACTIVE BSS after negotiation/compromize with the BSS holder (either
-	//   AP or IBSS holder).
-	//   Once initialized, user configuration can only be changed via OID_xxx
-	UCHAR       BssType;              // BSS_INFRA or BSS_ADHOC
-	USHORT      AtimWin;          // used when starting a new IBSS
+/* STA configuration and status */
+struct rt_sta_admin_config {
+	/* GROUP 1 - */
+	/*   User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe */
+	/*   the user intended configuration, but not necessary fully equal to the final */
+	/*   settings in ACTIVE BSS after negotiation/compromize with the BSS holder (either */
+	/*   AP or IBSS holder). */
+	/*   Once initialized, user configuration can only be changed via OID_xxx */
+	u8 BssType;		/* BSS_INFRA or BSS_ADHOC */
+	u16 AtimWin;		/* used when starting a new IBSS */
 
-	// GROUP 2 -
-	//   User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe
-	//   the user intended configuration, and should be always applied to the final
-	//   settings in ACTIVE BSS without compromising with the BSS holder.
-	//   Once initialized, user configuration can only be changed via OID_xxx
-	UCHAR       RssiTrigger;
-	UCHAR       RssiTriggerMode;      // RSSI_TRIGGERED_UPON_BELOW_THRESHOLD or RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD
-	USHORT      DefaultListenCount;   // default listen count;
-	ULONG       WindowsPowerMode;           // Power mode for AC power
-	ULONG       WindowsBatteryPowerMode;    // Power mode for battery if exists
-	BOOLEAN     bWindowsACCAMEnable;        // Enable CAM power mode when AC on
-	BOOLEAN     bAutoReconnect;         // Set to TRUE when setting OID_802_11_SSID with no matching BSSID
-	ULONG       WindowsPowerProfile;    // Windows power profile, for NDIS5.1 PnP
+	/* GROUP 2 - */
+	/*   User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe */
+	/*   the user intended configuration, and should be always applied to the final */
+	/*   settings in ACTIVE BSS without compromising with the BSS holder. */
+	/*   Once initialized, user configuration can only be changed via OID_xxx */
+	u8 RssiTrigger;
+	u8 RssiTriggerMode;	/* RSSI_TRIGGERED_UPON_BELOW_THRESHOLD or RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD */
+	u16 DefaultListenCount;	/* default listen count; */
+	unsigned long WindowsPowerMode;	/* Power mode for AC power */
+	unsigned long WindowsBatteryPowerMode;	/* Power mode for battery if exists */
+	BOOLEAN bWindowsACCAMEnable;	/* Enable CAM power mode when AC on */
+	BOOLEAN bAutoReconnect;	/* Set to TRUE when setting OID_802_11_SSID with no matching BSSID */
+	unsigned long WindowsPowerProfile;	/* Windows power profile, for NDIS5.1 PnP */
 
-	// MIB:ieee802dot11.dot11smt(1).dot11StationConfigTable(1)
-	USHORT      Psm;                  // power management mode   (PWR_ACTIVE|PWR_SAVE)
-	USHORT      DisassocReason;
-	UCHAR       DisassocSta[MAC_ADDR_LEN];
-	USHORT      DeauthReason;
-	UCHAR       DeauthSta[MAC_ADDR_LEN];
-	USHORT      AuthFailReason;
-	UCHAR       AuthFailSta[MAC_ADDR_LEN];
+	/* MIB:ieee802dot11.dot11smt(1).dot11StationConfigTable(1) */
+	u16 Psm;		/* power management mode   (PWR_ACTIVE|PWR_SAVE) */
+	u16 DisassocReason;
+	u8 DisassocSta[MAC_ADDR_LEN];
+	u16 DeauthReason;
+	u8 DeauthSta[MAC_ADDR_LEN];
+	u16 AuthFailReason;
+	u8 AuthFailSta[MAC_ADDR_LEN];
 
-	NDIS_802_11_PRIVACY_FILTER          PrivacyFilter;  // PrivacyFilter enum for 802.1X
-	NDIS_802_11_AUTHENTICATION_MODE     AuthMode;       // This should match to whatever microsoft defined
-	NDIS_802_11_WEP_STATUS              WepStatus;
-	NDIS_802_11_WEP_STATUS				OrigWepStatus;	// Original wep status set from OID
+	NDIS_802_11_PRIVACY_FILTER PrivacyFilter;	/* PrivacyFilter enum for 802.1X */
+	NDIS_802_11_AUTHENTICATION_MODE AuthMode;	/* This should match to whatever microsoft defined */
+	NDIS_802_11_WEP_STATUS WepStatus;
+	NDIS_802_11_WEP_STATUS OrigWepStatus;	/* Original wep status set from OID */
 
-	// Add to support different cipher suite for WPA2/WPA mode
-	NDIS_802_11_ENCRYPTION_STATUS		GroupCipher;		// Multicast cipher suite
-	NDIS_802_11_ENCRYPTION_STATUS		PairCipher;			// Unicast cipher suite
-	BOOLEAN								bMixCipher;			// Indicate current Pair & Group use different cipher suites
-	USHORT								RsnCapability;
+	/* Add to support different cipher suite for WPA2/WPA mode */
+	NDIS_802_11_ENCRYPTION_STATUS GroupCipher;	/* Multicast cipher suite */
+	NDIS_802_11_ENCRYPTION_STATUS PairCipher;	/* Unicast cipher suite */
+	BOOLEAN bMixCipher;	/* Indicate current Pair & Group use different cipher suites */
+	u16 RsnCapability;
 
-	NDIS_802_11_WEP_STATUS              GroupKeyWepStatus;
+	NDIS_802_11_WEP_STATUS GroupKeyWepStatus;
 
-	UCHAR		PMK[32];                // WPA PSK mode PMK
-	UCHAR       PTK[64];                // WPA PSK mode PTK
-	UCHAR		GTK[32];				// GTK from authenticator
-	BSSID_INFO	SavedPMK[PMKID_NO];
-	UINT		SavedPMKNum;			// Saved PMKID number
+	u8 WpaPassPhrase[64];	/* WPA PSK pass phrase */
+	u32 WpaPassPhraseLen;	/* the length of WPA PSK pass phrase */
+	u8 PMK[32];		/* WPA PSK mode PMK */
+	u8 PTK[64];		/* WPA PSK mode PTK */
+	u8 GTK[32];		/* GTK from authenticator */
+	struct rt_bssid_info SavedPMK[PMKID_NO];
+	u32 SavedPMKNum;	/* Saved PMKID number */
 
-	UCHAR		DefaultKeyId;
+	u8 DefaultKeyId;
 
+	/* WPA 802.1x port control, WPA_802_1X_PORT_SECURED, WPA_802_1X_PORT_NOT_SECURED */
+	u8 PortSecured;
 
-	// WPA 802.1x port control, WPA_802_1X_PORT_SECURED, WPA_802_1X_PORT_NOT_SECURED
-	UCHAR       PortSecured;
+	/* For WPA countermeasures */
+	unsigned long LastMicErrorTime;	/* record last MIC error time */
+	unsigned long MicErrCnt;	/* Should be 0, 1, 2, then reset to zero (after disassoiciation). */
+	BOOLEAN bBlockAssoc;	/* Block associate attempt for 60 seconds after counter measure occurred. */
+	/* For WPA-PSK supplicant state */
+	WPA_STATE WpaState;	/* Default is SS_NOTUSE and handled by microsoft 802.1x */
+	u8 ReplayCounter[8];
+	u8 ANonce[32];	/* ANonce for WPA-PSK from aurhenticator */
+	u8 SNonce[32];	/* SNonce for WPA-PSK */
 
-	// For WPA countermeasures
-	ULONG       LastMicErrorTime;   // record last MIC error time
-	ULONG       MicErrCnt;          // Should be 0, 1, 2, then reset to zero (after disassoiciation).
-	BOOLEAN     bBlockAssoc;        // Block associate attempt for 60 seconds after counter measure occurred.
-	// For WPA-PSK supplicant state
-	WPA_STATE   WpaState;           // Default is SS_NOTUSE and handled by microsoft 802.1x
-	UCHAR       ReplayCounter[8];
-	UCHAR       ANonce[32];         // ANonce for WPA-PSK from aurhenticator
-	UCHAR       SNonce[32];         // SNonce for WPA-PSK
+	u8 LastSNR0;		/* last received BEACON's SNR */
+	u8 LastSNR1;		/* last received BEACON's SNR for 2nd  antenna */
+	struct rt_rssi_sample RssiSample;
+	unsigned long NumOfAvgRssiSample;
 
-	UCHAR       LastSNR0;             // last received BEACON's SNR
-	UCHAR       LastSNR1;            // last received BEACON's SNR for 2nd  antenna
-	RSSI_SAMPLE RssiSample;
-	ULONG       NumOfAvgRssiSample;
+	unsigned long LastBeaconRxTime;	/* OS's timestamp of the last BEACON RX time */
+	unsigned long Last11bBeaconRxTime;	/* OS's timestamp of the last 11B BEACON RX time */
+	unsigned long Last11gBeaconRxTime;	/* OS's timestamp of the last 11G BEACON RX time */
+	unsigned long Last20NBeaconRxTime;	/* OS's timestamp of the last 20MHz N BEACON RX time */
 
-	ULONG       LastBeaconRxTime;     // OS's timestamp of the last BEACON RX time
-	ULONG       Last11bBeaconRxTime;  // OS's timestamp of the last 11B BEACON RX time
-	ULONG		Last11gBeaconRxTime;	// OS's timestamp of the last 11G BEACON RX time
-	ULONG		Last20NBeaconRxTime;	// OS's timestamp of the last 20MHz N BEACON RX time
+	unsigned long LastScanTime;	/* Record last scan time for issue BSSID_SCAN_LIST */
+	unsigned long ScanCnt;		/* Scan counts since most recent SSID, BSSID, SCAN OID request */
+	BOOLEAN bSwRadio;	/* Software controlled Radio On/Off, TRUE: On */
+	BOOLEAN bHwRadio;	/* Hardware controlled Radio On/Off, TRUE: On */
+	BOOLEAN bRadio;		/* Radio state, And of Sw & Hw radio state */
+	BOOLEAN bHardwareRadio;	/* Hardware controlled Radio enabled */
+	BOOLEAN bShowHiddenSSID;	/* Show all known SSID in SSID list get operation */
 
-	ULONG       LastScanTime;       // Record last scan time for issue BSSID_SCAN_LIST
-	ULONG       ScanCnt;            // Scan counts since most recent SSID, BSSID, SCAN OID request
-	BOOLEAN     bSwRadio;           // Software controlled Radio On/Off, TRUE: On
-	BOOLEAN     bHwRadio;           // Hardware controlled Radio On/Off, TRUE: On
-	BOOLEAN     bRadio;             // Radio state, And of Sw & Hw radio state
-	BOOLEAN     bHardwareRadio;     // Hardware controlled Radio enabled
-	BOOLEAN     bShowHiddenSSID;    // Show all known SSID in SSID list get operation
-#ifdef RT2860
-    BOOLEAN		AdhocBOnlyJoined;	// Indicate Adhoc B Join.
-    BOOLEAN		AdhocBGJoined;		// Indicate Adhoc B/G Join.
-    BOOLEAN		Adhoc20NJoined;		// Indicate Adhoc 20MHz N Join.
-#endif
-	// New for WPA, windows want us to keep association information and
-	// Fixed IEs from last association response
-	NDIS_802_11_ASSOCIATION_INFORMATION     AssocInfo;
-	USHORT       ReqVarIELen;                // Length of next VIE include EID & Length
-	UCHAR       ReqVarIEs[MAX_VIE_LEN];		// The content saved here should be little-endian format.
-	USHORT       ResVarIELen;                // Length of next VIE include EID & Length
-	UCHAR       ResVarIEs[MAX_VIE_LEN];
+	/* New for WPA, windows want us to keep association information and */
+	/* Fixed IEs from last association response */
+	struct rt_ndis_802_11_association_information AssocInfo;
+	u16 ReqVarIELen;	/* Length of next VIE include EID & Length */
+	u8 ReqVarIEs[MAX_VIE_LEN];	/* The content saved here should be little-endian format. */
+	u16 ResVarIELen;	/* Length of next VIE include EID & Length */
+	u8 ResVarIEs[MAX_VIE_LEN];
 
-	UCHAR       RSNIE_Len;
-	UCHAR       RSN_IE[MAX_LEN_OF_RSNIE];	// The content saved here should be little-endian format.
+	u8 RSNIE_Len;
+	u8 RSN_IE[MAX_LEN_OF_RSNIE];	/* The content saved here should be little-endian format. */
 
-	// New variables used for CCX 1.0
-	BOOLEAN             bCkipOn;
-	BOOLEAN             bCkipCmicOn;
-	UCHAR               CkipFlag;
-	UCHAR               GIV[3];  //for CCX iv
-	UCHAR               RxSEQ[4];
-	UCHAR               TxSEQ[4];
-	UCHAR               CKIPMIC[4];
-	UCHAR               LeapAuthMode;
-	LEAP_AUTH_INFO      LeapAuthInfo;
-	UCHAR               HashPwd[16];
-	UCHAR               NetworkChallenge[8];
-	UCHAR               NetworkChallengeResponse[24];
-	UCHAR               PeerChallenge[8];
+	unsigned long CLBusyBytes;	/* Save the total bytes received durning channel load scan time */
+	u16 RPIDensity[8];	/* Array for RPI density collection */
 
-	UCHAR               PeerChallengeResponse[24];
-	UCHAR               SessionKey[16]; //Network session keys (NSK)
-	RALINK_TIMER_STRUCT LeapAuthTimer;
-	ROGUEAP_TABLE       RogueApTab;   //Cisco CCX1 Rogue AP Detection
+	u8 RMReqCnt;		/* Number of measurement request saved. */
+	u8 CurrentRMReqIdx;	/* Number of measurement request saved. */
+	BOOLEAN ParallelReq;	/* Parallel measurement, only one request performed, */
+	/* It must be the same channel with maximum duration */
+	u16 ParallelDuration;	/* Maximum duration for parallel measurement */
+	u8 ParallelChannel;	/* Only one channel with parallel measurement */
+	u16 IAPPToken;	/* IAPP dialog token */
+	/* Hack for channel load and noise histogram parameters */
+	u8 NHFactor;		/* Parameter for Noise histogram */
+	u8 CLFactor;		/* Parameter for channel load */
 
-	// New control flags for CCX
-	CCX_CONTROL         CCXControl;                 // Master administration state
-	BOOLEAN             CCXEnable;                  // Actual CCX state
-	UCHAR               CCXScanChannel;             // Selected channel for CCX beacon request
-	USHORT              CCXScanTime;                // Time out to wait for beacon and probe response
-	UCHAR               CCXReqType;                 // Current processing CCX request type
-	BSS_TABLE           CCXBssTab;                  // BSS Table
-	UCHAR               FrameReportBuf[2048];       // Buffer for creating frame report
-	USHORT              FrameReportLen;             // Current Frame report length
-	ULONG               CLBusyBytes;                // Save the total bytes received durning channel load scan time
-	USHORT              RPIDensity[8];              // Array for RPI density collection
-	// Start address of each BSS table within FrameReportBuf
-	// It's important to update the RxPower of the corresponding Bss
-	USHORT              BssReportOffset[MAX_LEN_OF_BSS_TABLE];
-	USHORT              BeaconToken;                // Token for beacon report
-	ULONG               LastBssIndex;               // Most current reported Bss index
-	RM_REQUEST_ACTION   MeasurementRequest[16];     // Saved measurement request
-	UCHAR               RMReqCnt;                   // Number of measurement request saved.
-	UCHAR               CurrentRMReqIdx;            // Number of measurement request saved.
-	BOOLEAN             ParallelReq;                // Parallel measurement, only one request performed,
-													// It must be the same channel with maximum duration
-	USHORT              ParallelDuration;           // Maximum duration for parallel measurement
-	UCHAR               ParallelChannel;            // Only one channel with parallel measurement
-	USHORT              IAPPToken;                  // IAPP dialog token
-	UCHAR               CCXQosECWMin;               // Cisco QOS ECWMin for AC 0
-	UCHAR               CCXQosECWMax;               // Cisco QOS ECWMax for AC 0
-	// Hack for channel load and noise histogram parameters
-	UCHAR               NHFactor;                   // Parameter for Noise histogram
-	UCHAR               CLFactor;                   // Parameter for channel load
+	struct rt_ralink_timer StaQuickResponeForRateUpTimer;
+	BOOLEAN StaQuickResponeForRateUpTimerRunning;
 
-	UCHAR               KRK[16];        //Key Refresh Key.
-	UCHAR               BTK[32];        //Base Transient Key
-	BOOLEAN             CCKMLinkUpFlag;
-	ULONG               CCKMRN;    //(Re)Association request number.
-	LARGE_INTEGER       CCKMBeaconAtJoinTimeStamp;  //TSF timer for Re-assocaite to the new AP
-	UCHAR               AironetCellPowerLimit;      //in dBm
-	UCHAR               AironetIPAddress[4];        //eg. 192.168.1.1
-	BOOLEAN             CCXAdjacentAPReportFlag;    //flag for determining report Assoc Lost time
-	CHAR                CCXAdjacentAPSsid[MAX_LEN_OF_SSID]; //Adjacent AP's SSID report
-	UCHAR               CCXAdjacentAPSsidLen;               // the actual ssid length in used
-	UCHAR               CCXAdjacentAPBssid[MAC_ADDR_LEN];         //Adjacent AP's BSSID report
-	USHORT              CCXAdjacentAPChannel;
-	ULONG               CCXAdjacentAPLinkDownTime;  //for Spec S32.
+	u8 DtimCount;	/* 0.. DtimPeriod-1 */
+	u8 DtimPeriod;	/* default = 3 */
 
-	RALINK_TIMER_STRUCT	StaQuickResponeForRateUpTimer;
-	BOOLEAN				StaQuickResponeForRateUpTimerRunning;
+	/*////////////////////////////////////////////////////////////////////////////////////// */
+	/* This is only for WHQL test. */
+	BOOLEAN WhqlTest;
+	/*////////////////////////////////////////////////////////////////////////////////////// */
 
-	UCHAR           	DtimCount;      // 0.. DtimPeriod-1
-	UCHAR           	DtimPeriod;     // default = 3
+	struct rt_ralink_timer WpaDisassocAndBlockAssocTimer;
+	/* Fast Roaming */
+	BOOLEAN bAutoRoaming;	/* 0:disable auto roaming by RSSI, 1:enable auto roaming by RSSI */
+	char dBmToRoam;		/* the condition to roam when receiving Rssi less than this value. It's negative value. */
 
-	////////////////////////////////////////////////////////////////////////////////////////
-	// This is only for WHQL test.
-	BOOLEAN				WhqlTest;
-	////////////////////////////////////////////////////////////////////////////////////////
+	BOOLEAN IEEE8021X;
+	BOOLEAN IEEE8021x_required_keys;
+	struct rt_cipher_key DesireSharedKey[4];	/* Record user desired WEP keys */
+	u8 DesireSharedKeyId;
 
-    RALINK_TIMER_STRUCT WpaDisassocAndBlockAssocTimer;
-    // Fast Roaming
-	BOOLEAN		        bFastRoaming;       // 0:disable fast roaming, 1:enable fast roaming
-	CHAR		        dBmToRoam;          // the condition to roam when receiving Rssi less than this value. It's negative value.
+	/* 0: driver ignores wpa_supplicant */
+	/* 1: wpa_supplicant initiates scanning and AP selection */
+	/* 2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters */
+	u8 WpaSupplicantUP;
+	u8 WpaSupplicantScanCount;
+	BOOLEAN bRSN_IE_FromWpaSupplicant;
 
-    BOOLEAN             IEEE8021X;
-    BOOLEAN             IEEE8021x_required_keys;
-    CIPHER_KEY	        DesireSharedKey[4];	// Record user desired WEP keys
-    UCHAR               DesireSharedKeyId;
+	char dev_name[16];
+	u16 OriDevType;
 
-    // 0: driver ignores wpa_supplicant
-    // 1: wpa_supplicant initiates scanning and AP selection
-    // 2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters
-    UCHAR               WpaSupplicantUP;
-	UCHAR				WpaSupplicantScanCount;
+	BOOLEAN bTGnWifiTest;
+	BOOLEAN bScanReqIsFromWebUI;
 
-    CHAR                dev_name[16];
-    USHORT              OriDevType;
+	HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;	/* For transmit phy setting in TXWI. */
+	DESIRED_TRANSMIT_SETTING DesiredTransmitSetting;
+	struct rt_ht_phy_info DesiredHtPhyInfo;
+	BOOLEAN bAutoTxRateSwitch;
 
-    BOOLEAN             bTGnWifiTest;
-	BOOLEAN			    bScanReqIsFromWebUI;
+#ifdef RTMP_MAC_PCI
+	u8 BBPR3;
+	/* PS Control has 2 meanings for advanced power save function. */
+	/* 1. EnablePSinIdle : When no connection, always radio off except need to do site survey. */
+	/* 2. EnableNewPS  : will save more current in sleep or radio off mode. */
+	PS_CONTROL PSControl;
+#endif				/* RTMP_MAC_PCI // */
 
-	HTTRANSMIT_SETTING				HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
-	DESIRED_TRANSMIT_SETTING       	DesiredTransmitSetting;
-	RT_HT_PHY_INFO					DesiredHtPhyInfo;
-	BOOLEAN							bAutoTxRateSwitch;
+	BOOLEAN bAutoConnectByBssid;
+	unsigned long BeaconLostTime;	/* seconds */
+	BOOLEAN bForceTxBurst;	/* 1: force enble TX PACKET BURST, 0: disable */
+};
 
-#ifdef RT2860
-    UCHAR       BBPR3;
-#endif
-} STA_ADMIN_CONFIG, *PSTA_ADMIN_CONFIG;
+/* This data structure keep the current active BSS/IBSS's configuration that this STA */
+/* had agreed upon joining the network. Which means these parameters are usually decided */
+/* by the BSS/IBSS creator instead of user configuration. Data in this data structurre */
+/* is valid only when either ADHOC_ON(pAd) or INFRA_ON(pAd) is TRUE. */
+/* Normally, after SCAN or failed roaming attempts, we need to recover back to */
+/* the current active settings. */
+struct rt_sta_active_config {
+	u16 Aid;
+	u16 AtimWin;		/* in kusec; IBSS parameter set element */
+	u16 CapabilityInfo;
+	u16 CfpMaxDuration;
+	u16 CfpPeriod;
 
-// This data structure keep the current active BSS/IBSS's configuration that this STA
-// had agreed upon joining the network. Which means these parameters are usually decided
-// by the BSS/IBSS creator instead of user configuration. Data in this data structurre
-// is valid only when either ADHOC_ON(pAd) or INFRA_ON(pAd) is TRUE.
-// Normally, after SCAN or failed roaming attempts, we need to recover back to
-// the current active settings.
-typedef struct _STA_ACTIVE_CONFIG {
-	USHORT      Aid;
-	USHORT      AtimWin;                // in kusec; IBSS parameter set element
-	USHORT      CapabilityInfo;
-	USHORT      CfpMaxDuration;
-	USHORT      CfpPeriod;
+	/* Copy supported rate from desired AP's beacon. We are trying to match */
+	/* AP's supported and extended rate settings. */
+	u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES];
+	u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+	u8 SupRateLen;
+	u8 ExtRateLen;
+	/* Copy supported ht from desired AP's beacon. We are trying to match */
+	struct rt_ht_phy_info SupportedPhyInfo;
+	struct rt_ht_capability SupportedHtPhy;
+};
 
-	// Copy supported rate from desired AP's beacon. We are trying to match
-	// AP's supported and extended rate settings.
-	UCHAR       SupRate[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR       ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR       SupRateLen;
-	UCHAR       ExtRateLen;
-	// Copy supported ht from desired AP's beacon. We are trying to match
-	RT_HT_PHY_INFO		SupportedPhyInfo;
-	RT_HT_CAPABILITY	SupportedHtPhy;
-} STA_ACTIVE_CONFIG, *PSTA_ACTIVE_CONFIG;
+struct rt_mac_table_entry;
 
-#ifdef RT2870
-// for USB interface, avoid in interrupt when write key
-typedef struct   RT_ADD_PAIRWISE_KEY_ENTRY {
-        NDIS_802_11_MAC_ADDRESS         MacAddr;
-        USHORT                          MacTabMatchWCID;        // ASIC
-        CIPHER_KEY                      CipherKey;
-} RT_ADD_PAIRWISE_KEY_ENTRY,*PRT_ADD_PAIRWISE_KEY_ENTRY;
-#endif // RT2870 //
+struct rt_mac_table_entry {
+	/*Choose 1 from ValidAsWDS and ValidAsCLI  to validize. */
+	BOOLEAN ValidAsCLI;	/* Sta mode, set this TRUE after Linkup,too. */
+	BOOLEAN ValidAsWDS;	/* This is WDS Entry. only for AP mode. */
+	BOOLEAN ValidAsApCli;	/*This is a AP-Client entry, only for AP mode which enable AP-Client functions. */
+	BOOLEAN ValidAsMesh;
+	BOOLEAN ValidAsDls;	/* This is DLS Entry. only for STA mode. */
+	BOOLEAN isCached;
+	BOOLEAN bIAmBadAtheros;	/* Flag if this is Atheros chip that has IOT problem.  We need to turn on RTS/CTS protection. */
 
-// ----------- start of AP --------------------------
-// AUTH-RSP State Machine Aux data structure
-typedef struct _AP_MLME_AUX {
-	UCHAR               Addr[MAC_ADDR_LEN];
-	USHORT              Alg;
-	CHAR                Challenge[CIPHER_TEXT_LEN];
-} AP_MLME_AUX, *PAP_MLME_AUX;
-
-// structure to define WPA Group Key Rekey Interval
-typedef struct PACKED _RT_802_11_WPA_REKEY {
-	ULONG ReKeyMethod;          // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based
-	ULONG ReKeyInterval;        // time-based: seconds, packet-based: kilo-packets
-} RT_WPA_REKEY,*PRT_WPA_REKEY, RT_802_11_WPA_REKEY, *PRT_802_11_WPA_REKEY;
-
-typedef struct _MAC_TABLE_ENTRY {
-	//Choose 1 from ValidAsWDS and ValidAsCLI  to validize.
-	BOOLEAN		ValidAsCLI;		// Sta mode, set this TRUE after Linkup,too.
-	BOOLEAN		ValidAsWDS;	// This is WDS Entry. only for AP mode.
-	BOOLEAN		ValidAsApCli;   //This is a AP-Client entry, only for AP mode which enable AP-Client functions.
-	BOOLEAN		ValidAsMesh;
-	BOOLEAN		ValidAsDls;	// This is DLS Entry. only for STA mode.
-	BOOLEAN		isCached;
-	BOOLEAN		bIAmBadAtheros;	// Flag if this is Atheros chip that has IOT problem.  We need to turn on RTS/CTS protection.
-
-	UCHAR         	EnqueueEapolStartTimerRunning;  // Enqueue EAPoL-Start for triggering EAP SM
-	//jan for wpa
-	// record which entry revoke MIC Failure , if it leaves the BSS itself, AP won't update aMICFailTime MIB
-	UCHAR           CMTimerRunning;
-	UCHAR           apidx;			// MBSS number
-	UCHAR           RSNIE_Len;
-	UCHAR           RSN_IE[MAX_LEN_OF_RSNIE];
-	UCHAR           ANonce[LEN_KEY_DESC_NONCE];
-	UCHAR           R_Counter[LEN_KEY_DESC_REPLAY];
-	UCHAR           PTK[64];
-	UCHAR           ReTryCounter;
-	RALINK_TIMER_STRUCT                 RetryTimer;
-	RALINK_TIMER_STRUCT					EnqueueStartForPSKTimer;	// A timer which enqueue EAPoL-Start for triggering PSK SM
-	NDIS_802_11_AUTHENTICATION_MODE     AuthMode;   // This should match to whatever microsoft defined
-	NDIS_802_11_WEP_STATUS              WepStatus;
-	AP_WPA_STATE    WpaState;
-	GTK_STATE       GTKState;
-	USHORT          PortSecured;
-	NDIS_802_11_PRIVACY_FILTER  PrivacyFilter;      // PrivacyFilter enum for 802.1X
-	CIPHER_KEY      PairwiseKey;
-	PVOID           pAd;
-    INT				PMKID_CacheIdx;
-    UCHAR			PMKID[LEN_PMKID];
-
-
-	UCHAR           Addr[MAC_ADDR_LEN];
-	UCHAR           PsMode;
-	SST             Sst;
-	AUTH_STATE      AuthState; // for SHARED KEY authentication state machine used only
-	BOOLEAN			IsReassocSta;	// Indicate whether this is a reassociation procedure
-	USHORT          Aid;
-	USHORT          CapabilityInfo;
-	UCHAR           LastRssi;
-	ULONG           NoDataIdleCount;
-	UINT16			StationKeepAliveCount; // unit: second
-	ULONG           PsQIdleCount;
-	QUEUE_HEADER    PsQueue;
-
-	UINT32			StaConnectTime;		// the live time of this station since associated with AP
-
-	BOOLEAN			bSendBAR;
-	USHORT			NoBADataCountDown;
-
-	UINT32   		CachedBuf[16];		// UINT (4 bytes) for alignment
-	UINT			TxBFCount; // 3*3
-	UINT			FIFOCount;
-	UINT			DebugFIFOCount;
-	UINT			DebugTxCount;
-    BOOLEAN			bDlsInit;
-
-
-//====================================================
-//WDS entry needs these
-// rt2860 add this. if ValidAsWDS==TRUE, MatchWDSTabIdx is the index in WdsTab.MacTab
-	UINT			MatchWDSTabIdx;
-	UCHAR           MaxSupportedRate;
-	UCHAR           CurrTxRate;
-	UCHAR           CurrTxRateIndex;
-	// to record the each TX rate's quality. 0 is best, the bigger the worse.
-	USHORT          TxQuality[MAX_STEP_OF_TX_RATE_SWITCH];
-	UINT32			OneSecTxNoRetryOkCount;
-	UINT32          OneSecTxRetryOkCount;
-	UINT32          OneSecTxFailCount;
-	UINT32			ContinueTxFailCnt;
-	UINT32          CurrTxRateStableTime; // # of second in current TX rate
-	UCHAR           TxRateUpPenalty;      // extra # of second penalty due to last unstable condition
-//====================================================
-
-	BOOLEAN         fNoisyEnvironment;
-	BOOLEAN			fLastSecAccordingRSSI;
-	UCHAR           LastSecTxRateChangeAction; // 0: no change, 1:rate UP, 2:rate down
-	CHAR			LastTimeTxRateChangeAction; //Keep last time value of LastSecTxRateChangeAction
-	ULONG			LastTxOkCount;
-	UCHAR           PER[MAX_STEP_OF_TX_RATE_SWITCH];
-
-	// a bitmap of BOOLEAN flags. each bit represent an operation status of a particular
-	// BOOLEAN control, either ON or OFF. These flags should always be accessed via
-	// CLIENT_STATUS_TEST_FLAG(), CLIENT_STATUS_SET_FLAG(), CLIENT_STATUS_CLEAR_FLAG() macros.
-	// see fOP_STATUS_xxx in RTMP_DEF.C for detail bit definition. fCLIENT_STATUS_AMSDU_INUSED
-	ULONG           ClientStatusFlags;
-
-	HTTRANSMIT_SETTING	HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
-
-	// HT EWC MIMO-N used parameters
-	USHORT		RXBAbitmap;	// fill to on-chip  RXWI_BA_BITMASK in 8.1.3RX attribute entry format
-	USHORT		TXBAbitmap;	// This bitmap as originator, only keep in software used to mark AMPDU bit in TXWI
-	USHORT		TXAutoBAbitmap;
-	USHORT		BADeclineBitmap;
-	USHORT		BARecWcidArray[NUM_OF_TID];	// The mapping wcid of recipient session. if RXBAbitmap bit is masked
-	USHORT		BAOriWcidArray[NUM_OF_TID]; // The mapping wcid of originator session. if TXBAbitmap bit is masked
-	USHORT		BAOriSequence[NUM_OF_TID]; // The mapping wcid of originator session. if TXBAbitmap bit is masked
-
-	// 802.11n features.
-	UCHAR		MpduDensity;
-	UCHAR		MaxRAmpduFactor;
-	UCHAR		AMsduSize;
-	UCHAR		MmpsMode;	// MIMO power save more.
-
-	HT_CAPABILITY_IE		HTCapability;
-
-	BOOLEAN		bAutoTxRateSwitch;
-
-	UCHAR       RateLen;
-	struct _MAC_TABLE_ENTRY *pNext;
-    USHORT      TxSeq[NUM_OF_TID];
-	USHORT		NonQosDataSeq;
-
-	RSSI_SAMPLE	RssiSample;
-
-	UINT32			TXMCSExpected[16];
-	UINT32			TXMCSSuccessful[16];
-	UINT32			TXMCSFailed[16];
-	UINT32			TXMCSAutoFallBack[16][16];
-#ifdef RT2870
-	ULONG   		LastBeaconRxTime;
-#endif
-} MAC_TABLE_ENTRY, *PMAC_TABLE_ENTRY;
-
-typedef struct _MAC_TABLE {
-	USHORT			Size;
-	MAC_TABLE_ENTRY *Hash[HASH_TABLE_SIZE];
-	MAC_TABLE_ENTRY Content[MAX_LEN_OF_MAC_TABLE];
-	QUEUE_HEADER    McastPsQueue;
-	ULONG           PsQIdleCount;
-	BOOLEAN         fAnyStationInPsm;
-	BOOLEAN         fAnyStationBadAtheros;	// Check if any Station is atheros 802.11n Chip.  We need to use RTS/CTS with Atheros 802,.11n chip.
-	BOOLEAN			fAnyTxOPForceDisable;	// Check if it is necessary to disable BE TxOP
-#ifdef RT2870
-	BOOLEAN			fAllStationAsRalink; 	// Check if all stations are ralink-chipset
-#endif
-	BOOLEAN         fAnyStationIsLegacy;	// Check if I use legacy rate to transmit to my BSS Station/
-	BOOLEAN         fAnyStationNonGF;		// Check if any Station can't support GF.
-	BOOLEAN         fAnyStation20Only;		// Check if any Station can't support GF.
-	BOOLEAN			fAnyStationMIMOPSDynamic; // Check if any Station is MIMO Dynamic
-	BOOLEAN         fAnyBASession;   // Check if there is BA session.  Force turn on RTS/CTS
-} MAC_TABLE, *PMAC_TABLE;
-
-#define IS_HT_STA(_pMacEntry)	\
-	(_pMacEntry->MaxHTPhyMode.field.MODE >= MODE_HTMIX)
-
-#define IS_HT_RATE(_pMacEntry)	\
-	(_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
-
-#define PEER_IS_HT_RATE(_pMacEntry)	\
-	(_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
-
-typedef struct _WDS_ENTRY {
-	BOOLEAN         Valid;
-	UCHAR           Addr[MAC_ADDR_LEN];
-	ULONG           NoDataIdleCount;
-	struct _WDS_ENTRY *pNext;
-} WDS_ENTRY, *PWDS_ENTRY;
+	u8 EnqueueEapolStartTimerRunning;	/* Enqueue EAPoL-Start for triggering EAP SM */
+	/*jan for wpa */
+	/* record which entry revoke MIC Failure , if it leaves the BSS itself, AP won't update aMICFailTime MIB */
+	u8 CMTimerRunning;
+	u8 apidx;		/* MBSS number */
+	u8 RSNIE_Len;
+	u8 RSN_IE[MAX_LEN_OF_RSNIE];
+	u8 ANonce[LEN_KEY_DESC_NONCE];
+	u8 SNonce[LEN_KEY_DESC_NONCE];
+	u8 R_Counter[LEN_KEY_DESC_REPLAY];
+	u8 PTK[64];
+	u8 ReTryCounter;
+	struct rt_ralink_timer RetryTimer;
+	struct rt_ralink_timer EnqueueStartForPSKTimer;	/* A timer which enqueue EAPoL-Start for triggering PSK SM */
+	NDIS_802_11_AUTHENTICATION_MODE AuthMode;	/* This should match to whatever microsoft defined */
+	NDIS_802_11_WEP_STATUS WepStatus;
+	NDIS_802_11_WEP_STATUS GroupKeyWepStatus;
+	AP_WPA_STATE WpaState;
+	GTK_STATE GTKState;
+	u16 PortSecured;
+	NDIS_802_11_PRIVACY_FILTER PrivacyFilter;	/* PrivacyFilter enum for 802.1X */
+	struct rt_cipher_key PairwiseKey;
+	void *pAd;
+	int PMKID_CacheIdx;
+	u8 PMKID[LEN_PMKID];
 
-typedef struct  _WDS_TABLE_ENTRY {
-	USHORT			Size;
-	UCHAR           WdsAddr[MAC_ADDR_LEN];
-	WDS_ENTRY       *Hash[HASH_TABLE_SIZE];
-	WDS_ENTRY       Content[MAX_LEN_OF_MAC_TABLE];
-	UCHAR           MaxSupportedRate;
-	UCHAR           CurrTxRate;
-	USHORT          TxQuality[MAX_LEN_OF_SUPPORTED_RATES];
-	USHORT          OneSecTxOkCount;
-	USHORT          OneSecTxRetryOkCount;
-	USHORT          OneSecTxFailCount;
-	ULONG           CurrTxRateStableTime; // # of second in current TX rate
-	UCHAR           TxRateUpPenalty;      // extra # of second penalty due to last unstable condition
-} WDS_TABLE_ENTRY, *PWDS_TABLE_ENTRY;
+	u8 Addr[MAC_ADDR_LEN];
+	u8 PsMode;
+	SST Sst;
+	AUTH_STATE AuthState;	/* for SHARED KEY authentication state machine used only */
+	BOOLEAN IsReassocSta;	/* Indicate whether this is a reassociation procedure */
+	u16 Aid;
+	u16 CapabilityInfo;
+	u8 LastRssi;
+	unsigned long NoDataIdleCount;
+	u16 StationKeepAliveCount;	/* unit: second */
+	unsigned long PsQIdleCount;
+	struct rt_queue_header PsQueue;
 
-typedef struct _RT_802_11_WDS_ENTRY {
-	PNET_DEV			dev;
-	UCHAR				Valid;
-	UCHAR				PhyMode;
-	UCHAR				PeerWdsAddr[MAC_ADDR_LEN];
-	UCHAR				MacTabMatchWCID;	// ASIC
-	NDIS_802_11_WEP_STATUS  WepStatus;
-	UCHAR					KeyIdx;
-	CIPHER_KEY          	WdsKey;
-	HTTRANSMIT_SETTING				HTPhyMode, MaxHTPhyMode, MinHTPhyMode;
-	RT_HT_PHY_INFO					DesiredHtPhyInfo;
-	BOOLEAN							bAutoTxRateSwitch;
-	DESIRED_TRANSMIT_SETTING       	DesiredTransmitSetting; // Desired transmit setting.
-} RT_802_11_WDS_ENTRY, *PRT_802_11_WDS_ENTRY;
+	u32 StaConnectTime;	/* the live time of this station since associated with AP */
 
-typedef struct _WDS_TABLE {
-	UCHAR               Mode;
-	ULONG               Size;
-	RT_802_11_WDS_ENTRY	WdsEntry[MAX_WDS_ENTRY];
-} WDS_TABLE, *PWDS_TABLE;
+	BOOLEAN bSendBAR;
+	u16 NoBADataCountDown;
 
-typedef struct _APCLI_STRUCT {
-	PNET_DEV				dev;
-#ifdef RTL865X_SOC
-	unsigned int            mylinkid;
-#endif
-	BOOLEAN                 Enable;	// Set it as 1 if the apcli interface was configured to "1"  or by iwpriv cmd "ApCliEnable"
-	BOOLEAN                 Valid;	// Set it as 1 if the apcli interface associated success to remote AP.
-	UCHAR					MacTabWCID;	//WCID value, which point to the entry of ASIC Mac table.
-	UCHAR                   SsidLen;
-	CHAR                    Ssid[MAX_LEN_OF_SSID];
+	u32 CachedBuf[16];	/* u32 (4 bytes) for alignment */
+	u32 TxBFCount;		/* 3*3 */
+	u32 FIFOCount;
+	u32 DebugFIFOCount;
+	u32 DebugTxCount;
+	BOOLEAN bDlsInit;
 
-	UCHAR                   CfgSsidLen;
-	CHAR                    CfgSsid[MAX_LEN_OF_SSID];
-	UCHAR                   CfgApCliBssid[ETH_LENGTH_OF_ADDRESS];
-	UCHAR                   CurrentAddress[ETH_LENGTH_OF_ADDRESS];
+/*==================================================== */
+/*WDS entry needs these */
+/* if ValidAsWDS==TRUE, MatchWDSTabIdx is the index in WdsTab.MacTab */
+	u32 MatchWDSTabIdx;
+	u8 MaxSupportedRate;
+	u8 CurrTxRate;
+	u8 CurrTxRateIndex;
+	/* to record the each TX rate's quality. 0 is best, the bigger the worse. */
+	u16 TxQuality[MAX_STEP_OF_TX_RATE_SWITCH];
+/*      u16          OneSecTxOkCount; */
+	u32 OneSecTxNoRetryOkCount;
+	u32 OneSecTxRetryOkCount;
+	u32 OneSecTxFailCount;
+	u32 ContinueTxFailCnt;
+	u32 CurrTxRateStableTime;	/* # of second in current TX rate */
+	u8 TxRateUpPenalty;	/* extra # of second penalty due to last unstable condition */
+/*==================================================== */
 
-	ULONG                   ApCliRcvBeaconTime;
+	BOOLEAN fNoisyEnvironment;
+	BOOLEAN fLastSecAccordingRSSI;
+	u8 LastSecTxRateChangeAction;	/* 0: no change, 1:rate UP, 2:rate down */
+	char LastTimeTxRateChangeAction;	/*Keep last time value of LastSecTxRateChangeAction */
+	unsigned long LastTxOkCount;
+	u8 PER[MAX_STEP_OF_TX_RATE_SWITCH];
 
-	ULONG                   CtrlCurrState;
-	ULONG                   SyncCurrState;
-	ULONG                   AuthCurrState;
-	ULONG                   AssocCurrState;
-	ULONG					WpaPskCurrState;
+	/* a bitmap of BOOLEAN flags. each bit represent an operation status of a particular */
+	/* BOOLEAN control, either ON or OFF. These flags should always be accessed via */
+	/* CLIENT_STATUS_TEST_FLAG(), CLIENT_STATUS_SET_FLAG(), CLIENT_STATUS_CLEAR_FLAG() macros. */
+	/* see fOP_STATUS_xxx in RTMP_DEF.C for detail bit definition. fCLIENT_STATUS_AMSDU_INUSED */
+	unsigned long ClientStatusFlags;
 
-	USHORT                  AuthReqCnt;
-	USHORT                  AssocReqCnt;
+	HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;	/* For transmit phy setting in TXWI. */
 
-	ULONG                   ClientStatusFlags;
-	UCHAR                   MpduDensity;
+	/* HT EWC MIMO-N used parameters */
+	u16 RXBAbitmap;	/* fill to on-chip  RXWI_BA_BITMASK in 8.1.3RX attribute entry format */
+	u16 TXBAbitmap;	/* This bitmap as originator, only keep in software used to mark AMPDU bit in TXWI */
+	u16 TXAutoBAbitmap;
+	u16 BADeclineBitmap;
+	u16 BARecWcidArray[NUM_OF_TID];	/* The mapping wcid of recipient session. if RXBAbitmap bit is masked */
+	u16 BAOriWcidArray[NUM_OF_TID];	/* The mapping wcid of originator session. if TXBAbitmap bit is masked */
+	u16 BAOriSequence[NUM_OF_TID];	/* The mapping wcid of originator session. if TXBAbitmap bit is masked */
 
-	NDIS_802_11_AUTHENTICATION_MODE     AuthMode;   // This should match to whatever microsoft defined
-	NDIS_802_11_WEP_STATUS              WepStatus;
+	/* 802.11n features. */
+	u8 MpduDensity;
+	u8 MaxRAmpduFactor;
+	u8 AMsduSize;
+	u8 MmpsMode;		/* MIMO power save more. */
 
-	// Add to support different cipher suite for WPA2/WPA mode
-	NDIS_802_11_ENCRYPTION_STATUS		GroupCipher;		// Multicast cipher suite
-	NDIS_802_11_ENCRYPTION_STATUS		PairCipher;			// Unicast cipher suite
-	BOOLEAN								bMixCipher;			// Indicate current Pair & Group use different cipher suites
-	USHORT								RsnCapability;
+	struct rt_ht_capability_ie HTCapability;
 
-	UCHAR		PSK[100];				// reserve PSK key material
-	UCHAR       PSKLen;
-	UCHAR       PMK[32];                // WPA PSK mode PMK
-	UCHAR		GTK[32];				// GTK from authenticator
+	BOOLEAN bAutoTxRateSwitch;
 
-	CIPHER_KEY      SharedKey[SHARE_KEY_NUM];
-	UCHAR           DefaultKeyId;
+	u8 RateLen;
+	struct rt_mac_table_entry *pNext;
+	u16 TxSeq[NUM_OF_TID];
+	u16 NonQosDataSeq;
 
-	// store RSN_IE built by driver
-	UCHAR		RSN_IE[MAX_LEN_OF_RSNIE];  // The content saved here should be convert to little-endian format.
-	UCHAR		RSNIE_Len;
+	struct rt_rssi_sample RssiSample;
 
-	// For WPA countermeasures
-	ULONG       LastMicErrorTime;   // record last MIC error time
-	BOOLEAN                 bBlockAssoc; // Block associate attempt for 60 seconds after counter measure occurred.
+	u32 TXMCSExpected[16];
+	u32 TXMCSSuccessful[16];
+	u32 TXMCSFailed[16];
+	u32 TXMCSAutoFallBack[16][16];
 
-	// For WPA-PSK supplicant state
-	UCHAR       	SNonce[32];         // SNonce for WPA-PSK
-	UCHAR			GNonce[32];			// GNonce for WPA-PSK from authenticator
+	unsigned long LastBeaconRxTime;
 
-	HTTRANSMIT_SETTING				HTPhyMode, MaxHTPhyMode, MinHTPhyMode;
-	RT_HT_PHY_INFO					DesiredHtPhyInfo;
-	BOOLEAN							bAutoTxRateSwitch;
-	DESIRED_TRANSMIT_SETTING       	DesiredTransmitSetting; // Desired transmit setting.
-} APCLI_STRUCT, *PAPCLI_STRUCT;
+	unsigned long AssocDeadLine;
+};
 
-// ----------- end of AP ----------------------------
+struct rt_mac_table {
+	u16 Size;
+	struct rt_mac_table_entry *Hash[HASH_TABLE_SIZE];
+	struct rt_mac_table_entry Content[MAX_LEN_OF_MAC_TABLE];
+	struct rt_queue_header McastPsQueue;
+	unsigned long PsQIdleCount;
+	BOOLEAN fAnyStationInPsm;
+	BOOLEAN fAnyStationBadAtheros;	/* Check if any Station is atheros 802.11n Chip.  We need to use RTS/CTS with Atheros 802,.11n chip. */
+	BOOLEAN fAnyTxOPForceDisable;	/* Check if it is necessary to disable BE TxOP */
+	BOOLEAN fAllStationAsRalink;	/* Check if all stations are ralink-chipset */
+	BOOLEAN fAnyStationIsLegacy;	/* Check if I use legacy rate to transmit to my BSS Station/ */
+	BOOLEAN fAnyStationNonGF;	/* Check if any Station can't support GF. */
+	BOOLEAN fAnyStation20Only;	/* Check if any Station can't support GF. */
+	BOOLEAN fAnyStationMIMOPSDynamic;	/* Check if any Station is MIMO Dynamic */
+	BOOLEAN fAnyBASession;	/* Check if there is BA session.  Force turn on RTS/CTS */
+/*2008/10/28: KH add to support Antenna power-saving of AP<-- */
+/*2008/10/28: KH add to support Antenna power-saving of AP--> */
+};
 
-struct wificonf
-{
-	BOOLEAN	bShortGI;
+struct wificonf {
+	BOOLEAN bShortGI;
 	BOOLEAN bGreenField;
 };
 
+struct rt_rtmp_dev_info {
+	u8 chipName[16];
+	RTMP_INF_TYPE infType;
+};
 
+struct rt_rtmp_chip_op {
+	/*  Calibration access related callback functions */
+	int (*eeinit) (struct rt_rtmp_adapter *pAd);	/* int (*eeinit)(struct rt_rtmp_adapter *pAd); */
+	int (*eeread) (struct rt_rtmp_adapter *pAd, u16 offset, u16 *pValue);	/* int (*eeread)(struct rt_rtmp_adapter *pAd, int offset, u16 *pValue); */
 
+	/* MCU related callback functions */
+	int (*loadFirmware) (struct rt_rtmp_adapter *pAd);	/* int (*loadFirmware)(struct rt_rtmp_adapter *pAd); */
+	int (*eraseFirmware) (struct rt_rtmp_adapter *pAd);	/* int (*eraseFirmware)(struct rt_rtmp_adapter *pAd); */
+	int (*sendCommandToMcu) (struct rt_rtmp_adapter *pAd, u8 cmd, u8 token, u8 arg0, u8 arg1);;	/* int (*sendCommandToMcu)(struct rt_rtmp_adapter *pAd, u8 cmd, u8 token, u8 arg0, u8 arg1); */
 
-typedef struct _INF_PCI_CONFIG
-{
-	PUCHAR                  CSRBaseAddress;     // PCI MMIO Base Address, all access will use
-}INF_PCI_CONFIG;
+	/* RF access related callback functions */
+	struct rt_reg_pair *pRFRegTable;
+	void (*AsicRfInit) (struct rt_rtmp_adapter *pAd);
+	void (*AsicRfTurnOn) (struct rt_rtmp_adapter *pAd);
+	void (*AsicRfTurnOff) (struct rt_rtmp_adapter *pAd);
+	void (*AsicReverseRfFromSleepMode) (struct rt_rtmp_adapter *pAd);
+	void (*AsicHaltAction) (struct rt_rtmp_adapter *pAd);
+};
 
-typedef struct _INF_USB_CONFIG
-{
-	UINT                BulkInEpAddr;		// bulk-in endpoint address
-	UINT                BulkOutEpAddr[6];	// bulk-out endpoint address
+/* */
+/*  The miniport adapter structure */
+/* */
+struct rt_rtmp_adapter {
+	void *OS_Cookie;	/* save specific structure relative to OS */
+	struct net_device *net_dev;
+	unsigned long VirtualIfCnt;
 
-}INF_USB_CONFIG;
+	struct rt_rtmp_chip_op chipOps;
+	u16 ThisTbttNumToNextWakeUp;
 
-
-
-//
-//  The miniport adapter structure
-//
-typedef struct _RTMP_ADAPTER
-{
-	PVOID					OS_Cookie;	// save specific structure relative to OS
-	PNET_DEV				net_dev;
-	ULONG					VirtualIfCnt;
-
-#ifdef RT2860
-    USHORT		            LnkCtrlBitMask;
-    USHORT		            RLnkCtrlConfiguration;
-    USHORT                  RLnkCtrlOffset;
-    USHORT		            HostLnkCtrlConfiguration;
-    USHORT                  HostLnkCtrlOffset;
-	USHORT		            PCIePowerSaveLevel;
-   	BOOLEAN					bPCIclkOff;						// flag that indicate if the PICE power status in Configuration SPace..
-   	ULONG					CheckDmaBusyCount;  // Check Interrupt Status Register Count.
-   	USHORT					ThisTbttNumToNextWakeUp;
-	ULONG					SameRxByteCount;
-
-
+#ifdef RTMP_MAC_PCI
 /*****************************************************************************************/
-/*      PCI related parameters                                                           */
+/*      PCI related parameters																  */
 /*****************************************************************************************/
-	PUCHAR                  CSRBaseAddress;     // PCI MMIO Base Address, all access will use
+	u8 *CSRBaseAddress;	/* PCI MMIO Base Address, all access will use */
+	unsigned int irq_num;
 
-	UINT					int_enable_reg;
-	UINT					int_disable_mask;
-	UINT					int_pending;
+	u16 LnkCtrlBitMask;
+	u16 RLnkCtrlConfiguration;
+	u16 RLnkCtrlOffset;
+	u16 HostLnkCtrlConfiguration;
+	u16 HostLnkCtrlOffset;
+	u16 PCIePowerSaveLevel;
+	unsigned long Rt3xxHostLinkCtrl;	/* USed for 3090F chip */
+	unsigned long Rt3xxRalinkLinkCtrl;	/* USed for 3090F chip */
+	u16 DeviceID;	/* Read from PCI config */
+	unsigned long AccessBBPFailCount;
+	BOOLEAN bPCIclkOff;	/* flag that indicate if the PICE power status in Configuration SPace.. */
+	BOOLEAN bPCIclkOffDisableTx;	/* */
 
+	BOOLEAN brt30xxBanMcuCmd;	/*when = 0xff means all commands are ok to set . */
+	BOOLEAN b3090ESpecialChip;	/*3090E special chip that write EEPROM 0x24=0x9280. */
+	unsigned long CheckDmaBusyCount;	/* Check Interrupt Status Register Count. */
 
-	RTMP_DMABUF             TxBufSpace[NUM_OF_TX_RING]; // Shared memory of all 1st pre-allocated TxBuf associated with each TXD
-	RTMP_DMABUF             RxDescRing;                 // Shared memory for RX descriptors
-	RTMP_DMABUF             TxDescRing[NUM_OF_TX_RING]; 	// Shared memory for Tx descriptors
-	RTMP_TX_RING            TxRing[NUM_OF_TX_RING];     	// AC0~4 + HCCA
-#endif
+	u32 int_enable_reg;
+	u32 int_disable_mask;
+	u32 int_pending;
 
-	NDIS_SPIN_LOCK          irq_lock;
-	UCHAR                   irq_disabled;
+	struct rt_rtmp_dmabuf TxBufSpace[NUM_OF_TX_RING];	/* Shared memory of all 1st pre-allocated TxBuf associated with each TXD */
+	struct rt_rtmp_dmabuf RxDescRing;	/* Shared memory for RX descriptors */
+	struct rt_rtmp_dmabuf TxDescRing[NUM_OF_TX_RING];	/* Shared memory for Tx descriptors */
+	struct rt_rtmp_tx_ring TxRing[NUM_OF_TX_RING];	/* AC0~4 + HCCA */
+#endif				/* RTMP_MAC_PCI // */
 
-#ifdef RT2870
+	spinlock_t irq_lock;
+	u8 irq_disabled;
+
+#ifdef RTMP_MAC_USB
 /*****************************************************************************************/
 /*      USB related parameters                                                           */
 /*****************************************************************************************/
-	struct usb_config_descriptor		*config;
-	UINT								BulkInEpAddr;		// bulk-in endpoint address
-	UINT								BulkOutEpAddr[6];	// bulk-out endpoint address
+	struct usb_config_descriptor *config;
+	u32 BulkInEpAddr;	/* bulk-in endpoint address */
+	u32 BulkOutEpAddr[6];	/* bulk-out endpoint address */
 
-	UINT								NumberOfPipes;
-	USHORT								BulkOutMaxPacketSize;
-	USHORT								BulkInMaxPacketSize;
+	u32 NumberOfPipes;
+	u16 BulkOutMaxPacketSize;
+	u16 BulkInMaxPacketSize;
 
-	//======Control Flags
-	LONG                    	PendingIoCount;
-	ULONG						BulkFlags;
-	BOOLEAN                     bUsbTxBulkAggre;	// Flags for bulk out data priority
+	/*======Control Flags */
+	long PendingIoCount;
+	unsigned long BulkFlags;
+	BOOLEAN bUsbTxBulkAggre;	/* Flags for bulk out data priority */
 
+	/*======Cmd Thread */
+	struct rt_cmdq CmdQ;
+	spinlock_t CmdQLock;	/* CmdQLock spinlock */
+	struct rt_rtmp_os_task cmdQTask;
 
-	//======Timer Thread
-	RT2870_TIMER_QUEUE		TimerQ;
-	NDIS_SPIN_LOCK			TimerQLock;
-
-
-	//======Cmd Thread
-	CmdQ					CmdQ;
-	NDIS_SPIN_LOCK			CmdQLock;				// CmdQLock spinlock
-
-	BOOLEAN					TimerFunc_kill;
-	BOOLEAN					mlme_kill;
-
-
-	//======Semaphores (event)
-	struct semaphore			mlme_semaphore;			/* to sleep thread on	*/
-	struct semaphore			RTUSBCmd_semaphore;		/* to sleep thread on	*/
-	struct semaphore			RTUSBTimer_semaphore;
-	struct completion			TimerQComplete;
-	struct completion			mlmeComplete;
-	struct completion			CmdQComplete;
-	wait_queue_head_t			*wait;
-#endif // RT2870 //
-
+	/*======Semaphores (event) */
+	struct semaphore UsbVendorReq_semaphore;
+	void *UsbVendorReqBuf;
+	wait_queue_head_t *wait;
+#endif				/* RTMP_MAC_USB // */
 
 /*****************************************************************************************/
-	/*      Both PCI/USB related parameters                                                  */
+/*      RBUS related parameters																  */
 /*****************************************************************************************/
 
+/*****************************************************************************************/
+/*      Both PCI/USB related parameters														  */
+/*****************************************************************************************/
+	/*struct rt_rtmp_dev_info                 chipInfo; */
+	RTMP_INF_TYPE infType;
+
+/*****************************************************************************************/
+/*      Driver Mgmt related parameters														  */
+/*****************************************************************************************/
+	struct rt_rtmp_os_task mlmeTask;
+#ifdef RTMP_TIMER_TASK_SUPPORT
+	/* If you want use timer task to handle the timer related jobs, enable this. */
+	struct rt_rtmp_timer_task_queue TimerQ;
+	spinlock_t TimerQLock;
+	struct rt_rtmp_os_task timerTask;
+#endif				/* RTMP_TIMER_TASK_SUPPORT // */
 
 /*****************************************************************************************/
 /*      Tx related parameters                                                           */
 /*****************************************************************************************/
-	BOOLEAN                 DeQueueRunning[NUM_OF_TX_RING];  // for ensuring RTUSBDeQueuePacket get call once
-	NDIS_SPIN_LOCK          DeQueueLock[NUM_OF_TX_RING];
+	BOOLEAN DeQueueRunning[NUM_OF_TX_RING];	/* for ensuring RTUSBDeQueuePacket get call once */
+	spinlock_t DeQueueLock[NUM_OF_TX_RING];
 
-#ifdef RT2870
-	// Data related context and AC specified, 4 AC supported
-	NDIS_SPIN_LOCK			BulkOutLock[6];			// BulkOut spinlock for 4 ACs
-	NDIS_SPIN_LOCK			MLMEBulkOutLock;	// MLME BulkOut lock
+#ifdef RTMP_MAC_USB
+	/* Data related context and AC specified, 4 AC supported */
+	spinlock_t BulkOutLock[6];	/* BulkOut spinlock for 4 ACs */
+	spinlock_t MLMEBulkOutLock;	/* MLME BulkOut lock */
 
-	HT_TX_CONTEXT			TxContext[NUM_OF_TX_RING];
-	NDIS_SPIN_LOCK			TxContextQueueLock[NUM_OF_TX_RING];		// TxContextQueue spinlock
+	struct rt_ht_tx_context TxContext[NUM_OF_TX_RING];
+	spinlock_t TxContextQueueLock[NUM_OF_TX_RING];	/* TxContextQueue spinlock */
 
-	// 4 sets of Bulk Out index and pending flag
-	UCHAR					NextBulkOutIndex[4];	// only used for 4 EDCA bulkout pipe
+	/* 4 sets of Bulk Out index and pending flag */
+	u8 NextBulkOutIndex[4];	/* only used for 4 EDCA bulkout pipe */
 
-	BOOLEAN					BulkOutPending[6];	// used for total 6 bulkout pipe
-	UCHAR					bulkResetPipeid;
-	BOOLEAN					MgmtBulkPending;
-	ULONG					bulkResetReq[6];
-#endif // RT2870 //
+	BOOLEAN BulkOutPending[6];	/* used for total 6 bulkout pipe */
+	u8 bulkResetPipeid;
+	BOOLEAN MgmtBulkPending;
+	unsigned long bulkResetReq[6];
+#endif				/* RTMP_MAC_USB // */
 
-	// resource for software backlog queues
-	QUEUE_HEADER            TxSwQueue[NUM_OF_TX_RING];  // 4 AC + 1 HCCA
-	NDIS_SPIN_LOCK          TxSwQueueLock[NUM_OF_TX_RING];	// TxSwQueue spinlock
+	/* resource for software backlog queues */
+	struct rt_queue_header TxSwQueue[NUM_OF_TX_RING];	/* 4 AC + 1 HCCA */
+	spinlock_t TxSwQueueLock[NUM_OF_TX_RING];	/* TxSwQueue spinlock */
 
-	RTMP_DMABUF             MgmtDescRing;               	// Shared memory for MGMT descriptors
-	RTMP_MGMT_RING          MgmtRing;
-	NDIS_SPIN_LOCK          MgmtRingLock;               	// Prio Ring spinlock
-
+	struct rt_rtmp_dmabuf MgmtDescRing;	/* Shared memory for MGMT descriptors */
+	struct rt_rtmp_mgmt_ring MgmtRing;
+	spinlock_t MgmtRingLock;	/* Prio Ring spinlock */
 
 /*****************************************************************************************/
 /*      Rx related parameters                                                           */
 /*****************************************************************************************/
-#ifdef RT2860
-	RTMP_RX_RING            RxRing;
-	NDIS_SPIN_LOCK          RxRingLock;                 // Rx Ring spinlock
-#endif
-#ifdef RT2870
-	RX_CONTEXT				RxContext[RX_RING_SIZE];  // 1 for redundant multiple IRP bulk in.
-	NDIS_SPIN_LOCK			BulkInLock;				// BulkIn spinlock for 4 ACs
-	UCHAR					PendingRx;				// The Maxima pending Rx value should be 	RX_RING_SIZE.
-	UCHAR					NextRxBulkInIndex;		// Indicate the current RxContext Index which hold by Host controller.
-	UCHAR					NextRxBulkInReadIndex;	// Indicate the current RxContext Index which driver can read & process it.
-	ULONG					NextRxBulkInPosition;   // Want to contatenate 2 URB buffer while 1st is bulkin failed URB. This Position is 1st URB TransferLength.
-	ULONG					TransferBufferLength;	// current length of the packet buffer
-	ULONG					ReadPosition;			// current read position in a packet buffer
-#endif // RT2870 //
 
+#ifdef RTMP_MAC_PCI
+	struct rt_rtmp_rx_ring RxRing;
+	spinlock_t RxRingLock;	/* Rx Ring spinlock */
+#ifdef RT3090
+	spinlock_t McuCmdLock;	/*MCU Command Queue spinlock */
+#endif				/* RT3090 // */
+#endif				/* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
+	struct rt_rx_context RxContext[RX_RING_SIZE];	/* 1 for redundant multiple IRP bulk in. */
+	spinlock_t BulkInLock;	/* BulkIn spinlock for 4 ACs */
+	u8 PendingRx;	/* The Maximum pending Rx value should be       RX_RING_SIZE. */
+	u8 NextRxBulkInIndex;	/* Indicate the current RxContext Index which hold by Host controller. */
+	u8 NextRxBulkInReadIndex;	/* Indicate the current RxContext Index which driver can read & process it. */
+	unsigned long NextRxBulkInPosition;	/* Want to contatenate 2 URB buffer while 1st is bulkin failed URB. This Position is 1st URB TransferLength. */
+	unsigned long TransferBufferLength;	/* current length of the packet buffer */
+	unsigned long ReadPosition;	/* current read position in a packet buffer */
+#endif				/* RTMP_MAC_USB // */
 
 /*****************************************************************************************/
 /*      ASIC related parameters                                                          */
 /*****************************************************************************************/
-	UINT32               	MACVersion;      	// MAC version. Record rt2860C(0x28600100) or rt2860D (0x28600101)..
+	u32 MACVersion;	/* MAC version. Record rt2860C(0x28600100) or rt2860D (0x28600101).. */
 
-	// ---------------------------
-	// E2PROM
-	// ---------------------------
-	ULONG                   EepromVersion;          // byte 0: version, byte 1: revision, byte 2~3: unused
-	UCHAR                   EEPROMAddressNum;       // 93c46=6  93c66=8
-	USHORT                  EEPROMDefaultValue[NUM_EEPROM_BBP_PARMS];
-#ifdef RT2870
-	BOOLEAN                 EepromAccess;
-#endif
-	ULONG                   FirmwareVersion;        // byte 0: Minor version, byte 1: Major version, otherwise unused.
+	/* --------------------------- */
+	/* E2PROM */
+	/* --------------------------- */
+	unsigned long EepromVersion;	/* byte 0: version, byte 1: revision, byte 2~3: unused */
+	unsigned long FirmwareVersion;	/* byte 0: Minor version, byte 1: Major version, otherwise unused. */
+	u16 EEPROMDefaultValue[NUM_EEPROM_BBP_PARMS];
+	u8 EEPROMAddressNum;	/* 93c46=6  93c66=8 */
+	BOOLEAN EepromAccess;
+	u8 EFuseTag;
 
-	// ---------------------------
-	// BBP Control
-	// ---------------------------
-	UCHAR                   BbpWriteLatch[140];     // record last BBP register value written via BBP_IO_WRITE/BBP_IO_WRITE_VY_REG_ID
-	UCHAR                   BbpRssiToDbmDelta;
-	BBP_R66_TUNING          BbpTuning;
+	/* --------------------------- */
+	/* BBP Control */
+	/* --------------------------- */
+	u8 BbpWriteLatch[140];	/* record last BBP register value written via BBP_IO_WRITE/BBP_IO_WRITE_VY_REG_ID */
+	char BbpRssiToDbmDelta;	/* change from u8 to char for high power */
+	struct rt_bbp_r66_tuning BbpTuning;
 
-	// ----------------------------
-	// RFIC control
-	// ----------------------------
-	UCHAR                   RfIcType;       // RFIC_xxx
-	ULONG                   RfFreqOffset;   // Frequency offset for channel switching
-	RTMP_RF_REGS            LatchRfRegs;    // latch th latest RF programming value since RF IC doesn't support READ
+	/* ---------------------------- */
+	/* RFIC control */
+	/* ---------------------------- */
+	u8 RfIcType;		/* RFIC_xxx */
+	unsigned long RfFreqOffset;	/* Frequency offset for channel switching */
+	struct rt_rtmp_rf_regs LatchRfRegs;	/* latch th latest RF programming value since RF IC doesn't support READ */
 
-	EEPROM_ANTENNA_STRUC    Antenna;                            // Since ANtenna definition is different for a & g. We need to save it for future reference.
-	EEPROM_NIC_CONFIG2_STRUC    NicConfig2;
+	EEPROM_ANTENNA_STRUC Antenna;	/* Since ANtenna definition is different for a & g. We need to save it for future reference. */
+	EEPROM_NIC_CONFIG2_STRUC NicConfig2;
 
-	// This soft Rx Antenna Diversity mechanism is used only when user set
-	// RX Antenna = DIVERSITY ON
-	SOFT_RX_ANT_DIVERSITY   RxAnt;
+	/* This soft Rx Antenna Diversity mechanism is used only when user set */
+	/* RX Antenna = DIVERSITY ON */
+	struct rt_soft_rx_ant_diversity RxAnt;
 
-	UCHAR                   RFProgSeq;
-	CHANNEL_TX_POWER        TxPower[MAX_NUM_OF_CHANNELS];       // Store Tx power value for all channels.
-	CHANNEL_TX_POWER        ChannelList[MAX_NUM_OF_CHANNELS];   // list all supported channels for site survey
-	CHANNEL_11J_TX_POWER    TxPower11J[MAX_NUM_OF_11JCHANNELS];       // 802.11j channel and bw
-	CHANNEL_11J_TX_POWER    ChannelList11J[MAX_NUM_OF_11JCHANNELS];   // list all supported channels for site survey
+	u8 RFProgSeq;
+	struct rt_channel_tx_power TxPower[MAX_NUM_OF_CHANNELS];	/* Store Tx power value for all channels. */
+	struct rt_channel_tx_power ChannelList[MAX_NUM_OF_CHANNELS];	/* list all supported channels for site survey */
+	struct rt_channel_11j_tx_power TxPower11J[MAX_NUM_OF_11JCHANNELS];	/* 802.11j channel and bw */
+	struct rt_channel_11j_tx_power ChannelList11J[MAX_NUM_OF_11JCHANNELS];	/* list all supported channels for site survey */
 
-	UCHAR                   ChannelListNum;                     // number of channel in ChannelList[]
-	UCHAR					Bbp94;
-	BOOLEAN					BbpForCCK;
-	ULONG		Tx20MPwrCfgABand[5];
-	ULONG		Tx20MPwrCfgGBand[5];
-	ULONG		Tx40MPwrCfgABand[5];
-	ULONG		Tx40MPwrCfgGBand[5];
+	u8 ChannelListNum;	/* number of channel in ChannelList[] */
+	u8 Bbp94;
+	BOOLEAN BbpForCCK;
+	unsigned long Tx20MPwrCfgABand[5];
+	unsigned long Tx20MPwrCfgGBand[5];
+	unsigned long Tx40MPwrCfgABand[5];
+	unsigned long Tx40MPwrCfgGBand[5];
 
-	BOOLEAN     bAutoTxAgcA;                // Enable driver auto Tx Agc control
-	UCHAR	    TssiRefA;					// Store Tssi reference value as 25 temperature.
-	UCHAR	    TssiPlusBoundaryA[5];		// Tssi boundary for increase Tx power to compensate.
-	UCHAR	    TssiMinusBoundaryA[5];		// Tssi boundary for decrease Tx power to compensate.
-	UCHAR	    TxAgcStepA;					// Store Tx TSSI delta increment / decrement value
-	CHAR		TxAgcCompensateA;			// Store the compensation (TxAgcStep * (idx-1))
+	BOOLEAN bAutoTxAgcA;	/* Enable driver auto Tx Agc control */
+	u8 TssiRefA;		/* Store Tssi reference value as 25 temperature. */
+	u8 TssiPlusBoundaryA[5];	/* Tssi boundary for increase Tx power to compensate. */
+	u8 TssiMinusBoundaryA[5];	/* Tssi boundary for decrease Tx power to compensate. */
+	u8 TxAgcStepA;	/* Store Tx TSSI delta increment / decrement value */
+	char TxAgcCompensateA;	/* Store the compensation (TxAgcStep * (idx-1)) */
 
-	BOOLEAN     bAutoTxAgcG;                // Enable driver auto Tx Agc control
-	UCHAR	    TssiRefG;					// Store Tssi reference value as 25 temperature.
-	UCHAR	    TssiPlusBoundaryG[5];		// Tssi boundary for increase Tx power to compensate.
-	UCHAR	    TssiMinusBoundaryG[5];		// Tssi boundary for decrease Tx power to compensate.
-	UCHAR	    TxAgcStepG;					// Store Tx TSSI delta increment / decrement value
-	CHAR		TxAgcCompensateG;			// Store the compensation (TxAgcStep * (idx-1))
+	BOOLEAN bAutoTxAgcG;	/* Enable driver auto Tx Agc control */
+	u8 TssiRefG;		/* Store Tssi reference value as 25 temperature. */
+	u8 TssiPlusBoundaryG[5];	/* Tssi boundary for increase Tx power to compensate. */
+	u8 TssiMinusBoundaryG[5];	/* Tssi boundary for decrease Tx power to compensate. */
+	u8 TxAgcStepG;	/* Store Tx TSSI delta increment / decrement value */
+	char TxAgcCompensateG;	/* Store the compensation (TxAgcStep * (idx-1)) */
 
-	//+++For RT2870, the parameteres is start from BGRssiOffset1 ~ BGRssiOffset3
-	CHAR		BGRssiOffset0;				// Store B/G RSSI#0 Offset value on EEPROM 0x46h
-	CHAR		BGRssiOffset1;				// Store B/G RSSI#1 Offset value
-	CHAR		BGRssiOffset2;				// Store B/G RSSI#2 Offset value
-	//---
+	char BGRssiOffset0;	/* Store B/G RSSI#0 Offset value on EEPROM 0x46h */
+	char BGRssiOffset1;	/* Store B/G RSSI#1 Offset value */
+	char BGRssiOffset2;	/* Store B/G RSSI#2 Offset value */
 
-	//+++For RT2870, the parameteres is start from ARssiOffset1 ~ ARssiOffset3
-	CHAR		ARssiOffset0;				// Store A RSSI#0 Offset value on EEPROM 0x4Ah
-	CHAR		ARssiOffset1;				// Store A RSSI#1 Offset value
-	CHAR		ARssiOffset2;				// Store A RSSI#2 Offset value
-	//---
+	char ARssiOffset0;	/* Store A RSSI#0 Offset value on EEPROM 0x4Ah */
+	char ARssiOffset1;	/* Store A RSSI#1 Offset value */
+	char ARssiOffset2;	/* Store A RSSI#2 Offset value */
 
-	CHAR		BLNAGain;					// Store B/G external LNA#0 value on EEPROM 0x44h
-	CHAR		ALNAGain0;					// Store A external LNA#0 value for ch36~64
-	CHAR		ALNAGain1;					// Store A external LNA#1 value for ch100~128
-	CHAR		ALNAGain2;					// Store A external LNA#2 value for ch132~165
+	char BLNAGain;		/* Store B/G external LNA#0 value on EEPROM 0x44h */
+	char ALNAGain0;		/* Store A external LNA#0 value for ch36~64 */
+	char ALNAGain1;		/* Store A external LNA#1 value for ch100~128 */
+	char ALNAGain2;		/* Store A external LNA#2 value for ch132~165 */
+#ifdef RT30xx
+	/* for 3572 */
+	u8 Bbp25;
+	u8 Bbp26;
 
-	// ----------------------------
-	// LED control
-	// ----------------------------
-	MCU_LEDCS_STRUC		LedCntl;
-	USHORT				Led1;	// read from EEPROM 0x3c
-	USHORT				Led2;	// EEPROM 0x3e
-	USHORT				Led3;	// EEPROM 0x40
-	UCHAR				LedIndicatorStregth;
-	UCHAR				RssiSingalstrengthOffet;
-    BOOLEAN				bLedOnScanning;
-	UCHAR				LedStatus;
+	u8 TxMixerGain24G;	/* Tx mixer gain value from EEPROM to improve Tx EVM / Tx DAC, 2.4G */
+	u8 TxMixerGain5G;
+#endif				/* RT30xx // */
+	/* ---------------------------- */
+	/* LED control */
+	/* ---------------------------- */
+	MCU_LEDCS_STRUC LedCntl;
+	u16 Led1;		/* read from EEPROM 0x3c */
+	u16 Led2;		/* EEPROM 0x3e */
+	u16 Led3;		/* EEPROM 0x40 */
+	u8 LedIndicatorStrength;
+	u8 RssiSingalstrengthOffet;
+	BOOLEAN bLedOnScanning;
+	u8 LedStatus;
 
 /*****************************************************************************************/
 /*      802.11 related parameters                                                        */
 /*****************************************************************************************/
-	// outgoing BEACON frame buffer and corresponding TXD
-	TXWI_STRUC              	BeaconTxWI;
-	PUCHAR						BeaconBuf;
-	USHORT						BeaconOffset[HW_BEACON_MAX_COUNT];
+	/* outgoing BEACON frame buffer and corresponding TXD */
+	struct rt_txwi BeaconTxWI;
+	u8 *BeaconBuf;
+	u16 BeaconOffset[HW_BEACON_MAX_COUNT];
 
-	// pre-build PS-POLL and NULL frame upon link up. for efficiency purpose.
-	PSPOLL_FRAME            	PsPollFrame;
-	HEADER_802_11           	NullFrame;
+	/* pre-build PS-POLL and NULL frame upon link up. for efficiency purpose. */
+	struct rt_pspoll_frame PsPollFrame;
+	struct rt_header_802_11 NullFrame;
 
-#ifdef RT2870
-	TX_CONTEXT				BeaconContext[BEACON_RING_SIZE];
-	TX_CONTEXT				NullContext;
-	TX_CONTEXT				PsPollContext;
-	TX_CONTEXT				RTSContext;
-#endif // RT2870 //
+#ifdef RTMP_MAC_USB
+	struct rt_tx_context BeaconContext[BEACON_RING_SIZE];
+	struct rt_tx_context NullContext;
+	struct rt_tx_context PsPollContext;
+	struct rt_tx_context RTSContext;
+#endif				/* RTMP_MAC_USB // */
 
+/*=========AP=========== */
 
+/*=======STA=========== */
+	/* ----------------------------------------------- */
+	/* STA specific configuration & operation status */
+	/* used only when pAd->OpMode == OPMODE_STA */
+	/* ----------------------------------------------- */
+	struct rt_sta_admin_config StaCfg;	/* user desired settings */
+	struct rt_sta_active_config StaActive;	/* valid only when ADHOC_ON(pAd) || INFRA_ON(pAd) */
+	char nickname[IW_ESSID_MAX_SIZE + 1];	/* nickname, only used in the iwconfig i/f */
+	int PreMediaState;
 
-//=========AP===========
+/*=======Common=========== */
+	/* OP mode: either AP or STA */
+	u8 OpMode;		/* OPMODE_STA, OPMODE_AP */
 
+	int IndicateMediaState;	/* Base on Indication state, default is NdisMediaStateDisConnected */
 
-//=======STA===========
-/* Modified by Wu Xi-Kun 4/21/2006 */
-	// -----------------------------------------------
-	// STA specific configuration & operation status
-	// used only when pAd->OpMode == OPMODE_STA
-	// -----------------------------------------------
-	STA_ADMIN_CONFIG        StaCfg;           // user desired settings
-	STA_ACTIVE_CONFIG       StaActive;         // valid only when ADHOC_ON(pAd) || INFRA_ON(pAd)
-	CHAR                    nickname[IW_ESSID_MAX_SIZE+1]; // nickname, only used in the iwconfig i/f
-	NDIS_MEDIA_STATE        PreMediaState;
+	/* MAT related parameters */
 
-//=======Common===========
-	// OP mode: either AP or STA
-	UCHAR                   OpMode;                     // OPMODE_STA, OPMODE_AP
+	/* configuration: read from Registry & E2PROM */
+	BOOLEAN bLocalAdminMAC;	/* Use user changed MAC */
+	u8 PermanentAddress[MAC_ADDR_LEN];	/* Factory default MAC address */
+	u8 CurrentAddress[MAC_ADDR_LEN];	/* User changed MAC address */
 
-	NDIS_MEDIA_STATE        IndicateMediaState;			// Base on Indication state, default is NdisMediaStateDisConnected
+	/* ------------------------------------------------------ */
+	/* common configuration to both OPMODE_STA and OPMODE_AP */
+	/* ------------------------------------------------------ */
+	struct rt_common_config CommonCfg;
+	struct rt_mlme Mlme;
 
+	/* AP needs those vaiables for site survey feature. */
+	struct rt_mlme_aux MlmeAux;	/* temporary settings used during MLME state machine */
+	struct rt_bss_table ScanTab;	/* store the latest SCAN result */
 
-	// configuration: read from Registry & E2PROM
-	BOOLEAN                 bLocalAdminMAC;             // Use user changed MAC
-	UCHAR                   PermanentAddress[MAC_ADDR_LEN];    // Factory default MAC address
-	UCHAR                   CurrentAddress[MAC_ADDR_LEN];      // User changed MAC address
+	/*About MacTab, the sta driver will use #0 and #1 for multicast and AP. */
+	struct rt_mac_table MacTab;	/* ASIC on-chip WCID entry table.  At TX, ASIC always use key according to this on-chip table. */
+	spinlock_t MacTabLock;
 
-	// ------------------------------------------------------
-	// common configuration to both OPMODE_STA and OPMODE_AP
-	// ------------------------------------------------------
-	COMMON_CONFIG           CommonCfg;
-	MLME_STRUCT             Mlme;
+	struct rt_ba_table BATable;
 
-	// AP needs those vaiables for site survey feature.
-	MLME_AUX                MlmeAux;           // temporary settings used during MLME state machine
-	BSS_TABLE               ScanTab;           // store the latest SCAN result
+	spinlock_t BATabLock;
+	struct rt_ralink_timer RECBATimer;
 
-	//About MacTab, the sta driver will use #0 and #1 for multicast and AP.
-	MAC_TABLE                 MacTab;     // ASIC on-chip WCID entry table.  At TX, ASIC always use key according to this on-chip table.
-	NDIS_SPIN_LOCK          MacTabLock;
+	/* encryption/decryption KEY tables */
+	struct rt_cipher_key SharedKey[MAX_MBSSID_NUM][4];	/* STA always use SharedKey[BSS0][0..3] */
 
-	BA_TABLE			BATable;
+	/* RX re-assembly buffer for fragmentation */
+	struct rt_fragment_frame FragFrame;	/* Frame storage for fragment frame */
 
-	NDIS_SPIN_LOCK          BATabLock;
-	RALINK_TIMER_STRUCT RECBATimer;
+	/* various Counters */
+	struct rt_counter_802_3 Counters8023;	/* 802.3 counters */
+	struct rt_counter_802_11 WlanCounters;	/* 802.11 MIB counters */
+	struct rt_counter_ralink RalinkCounters;	/* Ralink propriety counters */
+	struct rt_counter_drs DrsCounters;	/* counters for Dynamic TX Rate Switching */
+	struct rt_private PrivateInfo;	/* Private information & counters */
 
-	// encryption/decryption KEY tables
-	CIPHER_KEY              SharedKey[MAX_MBSSID_NUM][4]; // STA always use SharedKey[BSS0][0..3]
+	/* flags, see fRTMP_ADAPTER_xxx flags */
+	unsigned long Flags;		/* Represent current device status */
+	unsigned long PSFlags;		/* Power Save operation flag. */
 
-		// RX re-assembly buffer for fragmentation
-	FRAGMENT_FRAME          FragFrame;                  // Frame storage for fragment frame
+	/* current TX sequence # */
+	u16 Sequence;
 
-	// various Counters
-	COUNTER_802_3           Counters8023;               // 802.3 counters
-	COUNTER_802_11          WlanCounters;               // 802.11 MIB counters
-	COUNTER_RALINK          RalinkCounters;             // Ralink propriety counters
-	COUNTER_DRS             DrsCounters;                // counters for Dynamic TX Rate Switching
-	PRIVATE_STRUC           PrivateInfo;                // Private information & counters
+	/* Control disconnect / connect event generation */
+	/*+++Didn't used anymore */
+	unsigned long LinkDownTime;
+	/*--- */
+	unsigned long LastRxRate;
+	unsigned long LastTxRate;
+	/*+++Used only for Station */
+	BOOLEAN bConfigChanged;	/* Config Change flag for the same SSID setting */
+	/*--- */
 
-	// flags, see fRTMP_ADAPTER_xxx flags
-	ULONG                   Flags;                      // Represent current device status
-#ifdef RT2860
-	ULONG                   PSFlags;                    // Power Save operation flag.
-#endif
+	unsigned long ExtraInfo;	/* Extra information for displaying status */
+	unsigned long SystemErrorBitmap;	/* b0: E2PROM version error */
 
-	// current TX sequence #
-	USHORT                  Sequence;
+	/*+++Didn't used anymore */
+	unsigned long MacIcVersion;	/* MAC/BBP serial interface issue solved after ver.D */
+	/*--- */
 
-	// Control disconnect / connect event generation
-	//+++Didn't used anymore
-	ULONG                   LinkDownTime;
-	//---
-	ULONG                   LastRxRate;
-	ULONG                   LastTxRate;
-	//+++Used only for Station
-	BOOLEAN                 bConfigChanged;         // Config Change flag for the same SSID setting
-	//---
+	/* --------------------------- */
+	/* System event log */
+	/* --------------------------- */
+	struct rt_802_11_event_table EventTab;
 
-	ULONG                   ExtraInfo;              // Extra information for displaying status
-	ULONG                   SystemErrorBitmap;      // b0: E2PROM version error
-
-	//+++Didn't used anymore
-	ULONG                   MacIcVersion;           // MAC/BBP serial interface issue solved after ver.D
-	//---
-
-	// ---------------------------
-	// System event log
-	// ---------------------------
-	RT_802_11_EVENT_TABLE   EventTab;
-
-
-	BOOLEAN		HTCEnable;
+	BOOLEAN HTCEnable;
 
 	/*****************************************************************************************/
 	/*      Statistic related parameters                                                     */
 	/*****************************************************************************************/
-#ifdef RT2870
-	ULONG						BulkOutDataOneSecCount;
-	ULONG						BulkInDataOneSecCount;
-	ULONG						BulkLastOneSecCount; // BulkOutDataOneSecCount + BulkInDataOneSecCount
-	ULONG						watchDogRxCnt;
-	ULONG						watchDogRxOverFlowCnt;
-	ULONG						watchDogTxPendingCnt[NUM_OF_TX_RING];
-#endif // RT2870 //
+#ifdef RTMP_MAC_USB
+	unsigned long BulkOutDataOneSecCount;
+	unsigned long BulkInDataOneSecCount;
+	unsigned long BulkLastOneSecCount;	/* BulkOutDataOneSecCount + BulkInDataOneSecCount */
+	unsigned long watchDogRxCnt;
+	unsigned long watchDogRxOverFlowCnt;
+	unsigned long watchDogTxPendingCnt[NUM_OF_TX_RING];
+	int TransferedLength[NUM_OF_TX_RING];
+#endif				/* RTMP_MAC_USB // */
 
-	BOOLEAN						bUpdateBcnCntDone;
-	ULONG						watchDogMacDeadlock;	// prevent MAC/BBP into deadlock condition
-	// ----------------------------
-	// DEBUG paramerts
-	// ----------------------------
-	BOOLEAN		bBanAllBaSetup;
-	BOOLEAN		bPromiscuous;
+	BOOLEAN bUpdateBcnCntDone;
+	unsigned long watchDogMacDeadlock;	/* prevent MAC/BBP into deadlock condition */
+	/* ---------------------------- */
+	/* DEBUG paramerts */
+	/* ---------------------------- */
+	/*unsigned long         DebugSetting[4]; */
+	BOOLEAN bBanAllBaSetup;
+	BOOLEAN bPromiscuous;
 
-	// ----------------------------
-	// rt2860c emulation-use Parameters
-	// ----------------------------
-	ULONG		rtsaccu[30];
-	ULONG		ctsaccu[30];
-	ULONG		cfendaccu[30];
-	ULONG		bacontent[16];
-	ULONG		rxint[RX_RING_SIZE+1];
-	UCHAR		rcvba[60];
-	BOOLEAN		bLinkAdapt;
-	BOOLEAN		bForcePrintTX;
-	BOOLEAN		bForcePrintRX;
-	BOOLEAN		bDisablescanning;		//defined in RT2870 USB
-	BOOLEAN		bStaFifoTest;
-	BOOLEAN		bProtectionTest;
-	BOOLEAN		bHCCATest;
-	BOOLEAN		bGenOneHCCA;
-	BOOLEAN		bBroadComHT;
-	//+++Following add from RT2870 USB.
-	ULONG		BulkOutReq;
-	ULONG		BulkOutComplete;
-	ULONG		BulkOutCompleteOther;
-	ULONG		BulkOutCompleteCancel;	// seems not use now?
-	ULONG		BulkInReq;
-	ULONG		BulkInComplete;
-	ULONG		BulkInCompleteFail;
-	//---
+	/* ---------------------------- */
+	/* rt2860c emulation-use Parameters */
+	/* ---------------------------- */
+	/*unsigned long         rtsaccu[30]; */
+	/*unsigned long         ctsaccu[30]; */
+	/*unsigned long         cfendaccu[30]; */
+	/*unsigned long         bacontent[16]; */
+	/*unsigned long         rxint[RX_RING_SIZE+1]; */
+	/*u8         rcvba[60]; */
+	BOOLEAN bLinkAdapt;
+	BOOLEAN bForcePrintTX;
+	BOOLEAN bForcePrintRX;
+	/*BOOLEAN               bDisablescanning;               //defined in RT2870 USB */
+	BOOLEAN bStaFifoTest;
+	BOOLEAN bProtectionTest;
+	BOOLEAN bBroadComHT;
+	/*+++Following add from RT2870 USB. */
+	unsigned long BulkOutReq;
+	unsigned long BulkOutComplete;
+	unsigned long BulkOutCompleteOther;
+	unsigned long BulkOutCompleteCancel;	/* seems not use now? */
+	unsigned long BulkInReq;
+	unsigned long BulkInComplete;
+	unsigned long BulkInCompleteFail;
+	/*--- */
 
-    struct wificonf			WIFItestbed;
+	struct wificonf WIFItestbed;
 
 	struct reordering_mpdu_pool mpdu_blk_pool;
 
-	ULONG					OneSecondnonBEpackets;		// record non BE packets per second
+	unsigned long OneSecondnonBEpackets;	/* record non BE packets per second */
 
-    struct iw_statistics    iw_stats;
+#ifdef LINUX
+	struct iw_statistics iw_stats;
 
-	struct net_device_stats	stats;
+	struct net_device_stats stats;
+#endif				/* LINUX // */
 
-	ULONG					TbttTickCount;
+	unsigned long TbttTickCount;
 #ifdef PCI_MSI_SUPPORT
-	BOOLEAN					HaveMsi;
-#endif // PCI_MSI_SUPPORT //
+	BOOLEAN HaveMsi;
+#endif				/* PCI_MSI_SUPPORT // */
 
-
-	UCHAR					is_on;
+	u8 is_on;
 
 #define TIME_BASE			(1000000/OS_HZ)
 #define TIME_ONE_SECOND		(1000000/TIME_BASE)
-	UCHAR					flg_be_adjust;
-	ULONG					be_adjust_last_time;
+	u8 flg_be_adjust;
+	unsigned long be_adjust_last_time;
 
+	u8 FlgCtsEnabled;
+	u8 PM_FlgSuspend;
 
-
-	UINT8					PM_FlgSuspend;
-
-#ifdef RT2870
-	BOOLEAN		bUseEfuse;
-#endif
-} RTMP_ADAPTER, *PRTMP_ADAPTER;
-
-//
-// Cisco IAPP format
-//
-typedef struct  _CISCO_IAPP_CONTENT_
-{
-	USHORT     Length;        //IAPP Length
-	UCHAR      MessageType;      //IAPP type
-	UCHAR      FunctionCode;     //IAPP function type
-	UCHAR      DestinaionMAC[MAC_ADDR_LEN];
-	UCHAR      SourceMAC[MAC_ADDR_LEN];
-	USHORT     Tag;           //Tag(element IE) - Adjacent AP report
-	USHORT     TagLength;     //Length of element not including 4 byte header
-	UCHAR      OUI[4];           //0x00, 0x40, 0x96, 0x00
-	UCHAR      PreviousAP[MAC_ADDR_LEN];       //MAC Address of access point
-	USHORT     Channel;
-	USHORT     SsidLen;
-	UCHAR      Ssid[MAX_LEN_OF_SSID];
-	USHORT     Seconds;          //Seconds that the client has been disassociated.
-} CISCO_IAPP_CONTENT, *PCISCO_IAPP_CONTENT;
+#ifdef RT30xx
+#ifdef RTMP_EFUSE_SUPPORT
+	BOOLEAN bUseEfuse;
+	u8 EEPROMImage[1024];
+#endif				/* RTMP_EFUSE_SUPPORT // */
+#endif				/* RT30xx // */
+};
 
 #define DELAYINTMASK		0x0003fffb
 #define INTMASK				0x0003fffb
 #define IndMask				0x0003fffc
-#define RxINT				0x00000005	// Delayed Rx or indivi rx
-#define TxDataInt			0x000000fa	// Delayed Tx or indivi tx
-#define TxMgmtInt			0x00000102	// Delayed Tx or indivi tx
-#define TxCoherent			0x00020000	// tx coherent
-#define RxCoherent			0x00010000	// rx coherent
-#define McuCommand			0x00000200	// mcu
-#define PreTBTTInt			0x00001000	// Pre-TBTT interrupt
-#define TBTTInt				0x00000800		// TBTT interrupt
-#define GPTimeOutInt			0x00008000		// GPtimeout interrupt
-#define AutoWakeupInt		0x00004000		// AutoWakeupInt interrupt
-#define FifoStaFullInt			0x00002000	//  fifo statistics full interrupt
+#define RxINT				0x00000005	/* Delayed Rx or indivi rx */
+#define TxDataInt			0x000000fa	/* Delayed Tx or indivi tx */
+#define TxMgmtInt			0x00000102	/* Delayed Tx or indivi tx */
+#define TxCoherent			0x00020000	/* tx coherent */
+#define RxCoherent			0x00010000	/* rx coherent */
+#define McuCommand			0x00000200	/* mcu */
+#define PreTBTTInt			0x00001000	/* Pre-TBTT interrupt */
+#define TBTTInt				0x00000800	/* TBTT interrupt */
+#define GPTimeOutInt			0x00008000	/* GPtimeout interrupt */
+#define AutoWakeupInt		0x00004000	/* AutoWakeupInt interrupt */
+#define FifoStaFullInt			0x00002000	/*  fifo statistics full interrupt */
 
-
-typedef struct _RX_BLK_
-{
-	RT28XX_RXD_STRUC	RxD;
-	PRXWI_STRUC			pRxWI;
-	PHEADER_802_11		pHeader;
-	PNDIS_PACKET		pRxPacket;
-	UCHAR				*pData;
-	USHORT				DataSize;
-	USHORT				Flags;
-	UCHAR				UserPriority;	// for calculate TKIP MIC using
-} RX_BLK;
-
+/***************************************************************************
+  *	Rx Path software control block related data structures
+  **************************************************************************/
+struct rt_rx_blk {
+	RT28XX_RXD_STRUC RxD;
+	struct rt_rxwi * pRxWI;
+	struct rt_header_802_11 * pHeader;
+	void *pRxPacket;
+	u8 *pData;
+	u16 DataSize;
+	u16 Flags;
+	u8 UserPriority;	/* for calculate TKIP MIC using */
+};
 
 #define RX_BLK_SET_FLAG(_pRxBlk, _flag)		(_pRxBlk->Flags |= _flag)
 #define RX_BLK_TEST_FLAG(_pRxBlk, _flag)	(_pRxBlk->Flags & _flag)
 #define RX_BLK_CLEAR_FLAG(_pRxBlk, _flag)	(_pRxBlk->Flags &= ~(_flag))
 
-
 #define fRX_WDS			0x0001
 #define fRX_AMSDU       0x0002
 #define fRX_ARALINK     0x0004
@@ -3012,6 +2199,9 @@
 #define LENGTH_ARALINK_SUBFRAMEHEAD	14
 #define LENGTH_ARALINK_HEADER_FIELD	 2
 
+/***************************************************************************
+  *	Tx Path software control block related data structures
+  **************************************************************************/
 #define TX_UNKOWN_FRAME			0x00
 #define TX_MCAST_FRAME			0x01
 #define TX_LEGACY_FRAME			0x02
@@ -3020,114 +2210,65 @@
 #define TX_RALINK_FRAME			0x10
 #define TX_FRAG_FRAME			0x20
 
+/*      Currently the sizeof(struct rt_tx_blk) is 148 bytes. */
+struct rt_tx_blk {
+	u8 QueIdx;
+	u8 TxFrameType;	/* Indicate the Transmission type of the all frames in one batch */
+	u8 TotalFrameNum;	/* Total frame number want to send-out in one batch */
+	u16 TotalFragNum;	/* Total frame fragments required in one batch */
+	u16 TotalFrameLen;	/* Total length of all frames want to send-out in one batch */
 
-//	Currently the sizeof(TX_BLK) is 148 bytes.
-typedef struct _TX_BLK_
-{
-	UCHAR				QueIdx;
-	UCHAR				TxFrameType;				// Indicate the Transmission type of the all frames in one batch
-	UCHAR				TotalFrameNum;				// Total frame number want to send-out in one batch
-	USHORT				TotalFragNum;				// Total frame fragments required in one batch
-	USHORT				TotalFrameLen;				// Total length of all frames want to send-out in one batch
+	struct rt_queue_header TxPacketList;
+	struct rt_mac_table_entry *pMacEntry;	/* NULL: packet with 802.11 RA field is multicast/broadcast address */
+	HTTRANSMIT_SETTING *pTransmit;
 
-	QUEUE_HEADER		TxPacketList;
-	MAC_TABLE_ENTRY		*pMacEntry;					// NULL: packet with 802.11 RA field is multicast/broadcast address
-	HTTRANSMIT_SETTING	*pTransmit;
+	/* Following structure used for the characteristics of a specific packet. */
+	void *pPacket;
+	u8 *pSrcBufHeader;	/* Reference to the head of sk_buff->data */
+	u8 *pSrcBufData;	/* Reference to the sk_buff->data, will changed depends on hanlding progresss */
+	u32 SrcBufLen;		/* Length of packet payload which not including Layer 2 header */
+	u8 *pExtraLlcSnapEncap;	/* NULL means no extra LLC/SNAP is required */
+	u8 HeaderBuf[128];	/* TempBuffer for TX_INFO + TX_WI + 802.11 Header + padding + AMSDU SubHeader + LLC/SNAP */
+	/*RT2870 2.1.0.0 uses only 80 bytes */
+	/*RT3070 2.1.1.0 uses only 96 bytes */
+	/*RT3090 2.1.0.0 uses only 96 bytes */
+	u8 MpduHeaderLen;	/* 802.11 header length NOT including the padding */
+	u8 HdrPadLen;	/* recording Header Padding Length; */
+	u8 apidx;		/* The interface associated to this packet */
+	u8 Wcid;		/* The MAC entry associated to this packet */
+	u8 UserPriority;	/* priority class of packet */
+	u8 FrameGap;		/* what kind of IFS this packet use */
+	u8 MpduReqNum;	/* number of fragments of this frame */
+	u8 TxRate;		/* TODO: Obsoleted? Should change to MCS? */
+	u8 CipherAlg;	/* cipher alogrithm */
+	struct rt_cipher_key *pKey;
 
-	// Following structure used for the characteristics of a specific packet.
-	PNDIS_PACKET		pPacket;
-	PUCHAR				pSrcBufHeader;				// Reference to the head of sk_buff->data
-	PUCHAR				pSrcBufData;				// Reference to the sk_buff->data, will changed depends on hanlding progresss
-	UINT				SrcBufLen;					// Length of packet payload which not including Layer 2 header
-	PUCHAR				pExtraLlcSnapEncap;			// NULL means no extra LLC/SNAP is required
-	UCHAR				HeaderBuf[80];				// TempBuffer for TX_INFO + TX_WI + 802.11 Header + padding + AMSDU SubHeader + LLC/SNAP
-	UCHAR				MpduHeaderLen;				// 802.11 header length NOT including the padding
-	UCHAR				HdrPadLen;					// recording Header Padding Length;
-	UCHAR				apidx;						// The interface associated to this packet
-	UCHAR				Wcid;						// The MAC entry associated to this packet
-	UCHAR				UserPriority;				// priority class of packet
-	UCHAR				FrameGap;					// what kind of IFS this packet use
-	UCHAR				MpduReqNum;					// number of fragments of this frame
-	UCHAR				TxRate;						// TODO: Obsoleted? Should change to MCS?
-	UCHAR				CipherAlg;					// cipher alogrithm
-	PCIPHER_KEY			pKey;
+	u16 Flags;		/*See following definitions for detail. */
 
+	/*YOU SHOULD NOT TOUCH IT! Following parameters are used for hardware-depended layer. */
+	unsigned long Priv;		/* Hardware specific value saved in here. */
+};
 
-
-	USHORT				Flags;						//See following definitions for detail.
-
-	//YOU SHOULD NOT TOUCH IT! Following parameters are used for hardware-depended layer.
-	ULONG				Priv;						// Hardware specific value saved in here.
-} TX_BLK, *PTX_BLK;
-
-
-#define fTX_bRtsRequired		0x0001	// Indicate if need send RTS frame for protection. Not used in RT2860/RT2870.
-#define fTX_bAckRequired       	0x0002	// the packet need ack response
-#define fTX_bPiggyBack     		0x0004	// Legacy device use Piggback or not
-#define fTX_bHTRate         	0x0008	// allow to use HT rate
-#define fTX_bForceNonQoS       	0x0010	// force to transmit frame without WMM-QoS in HT mode
-#define fTX_bAllowFrag       	0x0020	// allow to fragment the packet, A-MPDU, A-MSDU, A-Ralink is not allowed to fragment
-#define fTX_bMoreData			0x0040	// there are more data packets in PowerSave Queue
-#define fTX_bWMM				0x0080	// QOS Data
-
+#define fTX_bRtsRequired		0x0001	/* Indicate if need send RTS frame for protection. Not used in RT2860/RT2870. */
+#define fTX_bAckRequired       	0x0002	/* the packet need ack response */
+#define fTX_bPiggyBack     		0x0004	/* Legacy device use Piggback or not */
+#define fTX_bHTRate         	0x0008	/* allow to use HT rate */
+#define fTX_bForceNonQoS       	0x0010	/* force to transmit frame without WMM-QoS in HT mode */
+#define fTX_bAllowFrag       	0x0020	/* allow to fragment the packet, A-MPDU, A-MSDU, A-Ralink is not allowed to fragment */
+#define fTX_bMoreData			0x0040	/* there are more data packets in PowerSave Queue */
+#define fTX_bWMM				0x0080	/* QOS Data */
 #define fTX_bClearEAPFrame		0x0100
 
-#define TX_BLK_ASSIGN_FLAG(_pTxBlk, _flag, value)	\
-		do {										\
-			if (value) 								\
-				(_pTxBlk->Flags |= _flag) 			\
-			else 									\
-				(_pTxBlk->Flags &= ~(_flag))		\
-		}while(0)
-
 #define TX_BLK_SET_FLAG(_pTxBlk, _flag)		(_pTxBlk->Flags |= _flag)
 #define TX_BLK_TEST_FLAG(_pTxBlk, _flag)	(((_pTxBlk->Flags & _flag) == _flag) ? 1 : 0)
 #define TX_BLK_CLEAR_FLAG(_pTxBlk, _flag)	(_pTxBlk->Flags &= ~(_flag))
 
-
-
-
-
-//------------------------------------------------------------------------------------------
-
-#ifdef RT2860
-//
-// Enable & Disable NIC interrupt via writing interrupt mask register
-// Since it use ADAPTER structure, it have to be put after structure definition.
-//
-__inline    VOID    NICDisableInterrupt(
-    IN  PRTMP_ADAPTER   pAd)
-{
-	RTMP_IO_WRITE32(pAd, INT_MASK_CSR, 0x0);     // 0: disable
-	//RTMP_IO_WRITE32(pAd, PBF_INT_ENA, 0x0);	 	// 0x418 is for firmware . SW doesn't handle here.
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
-}
-
-__inline    VOID    NICEnableInterrupt(
-    IN  PRTMP_ADAPTER   pAd)
-{
-	//
-	// Flag "fOP_STATUS_DOZE" On, means ASIC put to sleep, else means ASIC WakeUp
-	// To prevent System hang, we should enalbe the interrupt when
-	// ASIC is already Wake Up.
-	//
-    // RT2661 => when ASIC is sleeping, MAC register cannot be read and written.
-	// RT2860 => when ASIC is sleeping, MAC register can be read and written.
-	//if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-	{
-		RTMP_IO_WRITE32(pAd, INT_MASK_CSR, pAd->int_enable_reg /*DELAYINTMASK*/);     // 1:enable
-	}
-	//else
-	//	DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_DOZE !\n"));
-
-	//RTMP_IO_WRITE32(pAd, PBF_INT_ENA, 0x00000030); // 1 : enable
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
-}
-
-static inline VOID ConvertMulticastIP2MAC(
-	IN PUCHAR pIpAddr,
-	IN PUCHAR *ppMacAddr,
-	IN UINT16 ProtoType)
+/***************************************************************************
+  *	Other static inline function definitions
+  **************************************************************************/
+static inline void ConvertMulticastIP2MAC(u8 *pIpAddr,
+					  u8 ** ppMacAddr,
+					  u16 ProtoType)
 {
 	if (pIpAddr == NULL)
 		return;
@@ -3135,2414 +2276,1450 @@
 	if (ppMacAddr == NULL || *ppMacAddr == NULL)
 		return;
 
-	switch (ProtoType)
-	{
-		case ETH_P_IPV6:
-//			memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS);
-			*(*ppMacAddr) = 0x33;
-			*(*ppMacAddr + 1) = 0x33;
-			*(*ppMacAddr + 2) = pIpAddr[12];
-			*(*ppMacAddr + 3) = pIpAddr[13];
-			*(*ppMacAddr + 4) = pIpAddr[14];
-			*(*ppMacAddr + 5) = pIpAddr[15];
-			break;
+	switch (ProtoType) {
+	case ETH_P_IPV6:
+/*                      memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS); */
+		*(*ppMacAddr) = 0x33;
+		*(*ppMacAddr + 1) = 0x33;
+		*(*ppMacAddr + 2) = pIpAddr[12];
+		*(*ppMacAddr + 3) = pIpAddr[13];
+		*(*ppMacAddr + 4) = pIpAddr[14];
+		*(*ppMacAddr + 5) = pIpAddr[15];
+		break;
 
-		case ETH_P_IP:
-		default:
-//			memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS);
-			*(*ppMacAddr) = 0x01;
-			*(*ppMacAddr + 1) = 0x00;
-			*(*ppMacAddr + 2) = 0x5e;
-			*(*ppMacAddr + 3) = pIpAddr[1] & 0x7f;
-			*(*ppMacAddr + 4) = pIpAddr[2];
-			*(*ppMacAddr + 5) = pIpAddr[3];
-			break;
+	case ETH_P_IP:
+	default:
+/*                      memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS); */
+		*(*ppMacAddr) = 0x01;
+		*(*ppMacAddr + 1) = 0x00;
+		*(*ppMacAddr + 2) = 0x5e;
+		*(*ppMacAddr + 3) = pIpAddr[1] & 0x7f;
+		*(*ppMacAddr + 4) = pIpAddr[2];
+		*(*ppMacAddr + 5) = pIpAddr[3];
+		break;
 	}
 
 	return;
 }
-#endif /* RT2860 */
 
-//
-//  Private routines in rtmp_init.c
-//
-NDIS_STATUS RTMPAllocAdapterBlock(
-	IN PVOID			handle,
-	OUT PRTMP_ADAPTER   *ppAdapter
-	);
+char *GetPhyMode(int Mode);
+char *GetBW(int BW);
 
-NDIS_STATUS RTMPAllocTxRxRingMemory(
-	IN  PRTMP_ADAPTER   pAd
-	);
+/* */
+/*  Private routines in rtmp_init.c */
+/* */
+int RTMPAllocAdapterBlock(void *handle,
+				  struct rt_rtmp_adapter * * ppAdapter);
 
-NDIS_STATUS	RTMPReadParametersHook(
-	IN	PRTMP_ADAPTER pAd
-	);
+int RTMPAllocTxRxRingMemory(struct rt_rtmp_adapter *pAd);
 
-VOID RTMPFreeAdapter(
-	IN  PRTMP_ADAPTER   pAd
-	);
+void RTMPFreeAdapter(struct rt_rtmp_adapter *pAd);
 
-NDIS_STATUS NICReadRegParameters(
-	IN  PRTMP_ADAPTER       pAd,
-	IN  NDIS_HANDLE         WrapperConfigurationContext
-	);
+int NICReadRegParameters(struct rt_rtmp_adapter *pAd,
+				 void *WrapperConfigurationContext);
 
-#ifdef RT2870
-VOID NICInitRT30xxRFRegisters(
-	IN PRTMP_ADAPTER pAd);
-#endif // RT2870 //
+#ifdef RTMP_RF_RW_SUPPORT
+void NICInitRFRegisters(struct rt_rtmp_adapter *pAd);
 
-VOID NICReadEEPROMParameters(
-	IN  PRTMP_ADAPTER       pAd,
-	IN	PUCHAR				mac_addr);
+void RtmpChipOpsRFHook(struct rt_rtmp_adapter *pAd);
 
-VOID NICInitAsicFromEEPROM(
-	IN  PRTMP_ADAPTER       pAd);
+int RT30xxWriteRFRegister(struct rt_rtmp_adapter *pAd,
+				  u8 regID, u8 value);
 
-VOID NICInitTxRxRingAndBacklogQueue(
-	IN  PRTMP_ADAPTER   pAd);
+int RT30xxReadRFRegister(struct rt_rtmp_adapter *pAd,
+				 u8 regID, u8 *pValue);
+#endif /* RTMP_RF_RW_SUPPORT // */
 
-NDIS_STATUS NICInitializeAdapter(
-	IN  PRTMP_ADAPTER   pAd,
-	IN   BOOLEAN    bHardReset);
+void NICReadEEPROMParameters(struct rt_rtmp_adapter *pAd, u8 *mac_addr);
 
-NDIS_STATUS NICInitializeAsic(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  BOOLEAN		bHardReset);
-#ifdef RT2860
-VOID NICRestoreBBPValue(
-	IN PRTMP_ADAPTER pAd);
-#endif
-VOID NICIssueReset(
-	IN  PRTMP_ADAPTER   pAd);
+void NICInitAsicFromEEPROM(struct rt_rtmp_adapter *pAd);
 
-VOID RTMPRingCleanUp(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR           RingType);
+int NICInitializeAdapter(struct rt_rtmp_adapter *pAd, IN BOOLEAN bHardReset);
 
-VOID UserCfgInit(
-	IN  PRTMP_ADAPTER   pAd);
+int NICInitializeAsic(struct rt_rtmp_adapter *pAd, IN BOOLEAN bHardReset);
 
-VOID NICResetFromError(
-	IN  PRTMP_ADAPTER   pAd);
+void NICIssueReset(struct rt_rtmp_adapter *pAd);
 
-VOID NICEraseFirmware(
-	IN PRTMP_ADAPTER pAd);
+void RTMPRingCleanUp(struct rt_rtmp_adapter *pAd, u8 RingType);
 
-NDIS_STATUS NICLoadFirmware(
-	IN  PRTMP_ADAPTER   pAd);
+void UserCfgInit(struct rt_rtmp_adapter *pAd);
 
-NDIS_STATUS NICLoadRateSwitchingParams(
-	IN PRTMP_ADAPTER pAd);
+void NICResetFromError(struct rt_rtmp_adapter *pAd);
 
-BOOLEAN NICCheckForHang(
-	IN  PRTMP_ADAPTER   pAd);
+int NICLoadFirmware(struct rt_rtmp_adapter *pAd);
 
-VOID NICUpdateFifoStaCounters(
-	IN PRTMP_ADAPTER pAd);
+void NICEraseFirmware(struct rt_rtmp_adapter *pAd);
 
-VOID NICUpdateRawCounters(
-	IN  PRTMP_ADAPTER   pAd);
+int NICLoadRateSwitchingParams(struct rt_rtmp_adapter *pAd);
 
-ULONG	RTMPNotAllZero(
-	IN	PVOID	pSrc1,
-	IN	ULONG	Length);
+BOOLEAN NICCheckForHang(struct rt_rtmp_adapter *pAd);
 
-VOID RTMPZeroMemory(
-	IN  PVOID   pSrc,
-	IN  ULONG   Length);
+void NICUpdateFifoStaCounters(struct rt_rtmp_adapter *pAd);
 
-ULONG RTMPCompareMemory(
-	IN  PVOID   pSrc1,
-	IN  PVOID   pSrc2,
-	IN  ULONG   Length);
+void NICUpdateRawCounters(struct rt_rtmp_adapter *pAd);
 
-VOID RTMPMoveMemory(
-	OUT PVOID   pDest,
-	IN  PVOID   pSrc,
-	IN  ULONG   Length);
+void RTMPZeroMemory(void *pSrc, unsigned long Length);
 
-VOID AtoH(
-	char	*src,
-	UCHAR	*dest,
-	int		destlen);
+unsigned long RTMPCompareMemory(void *pSrc1, void *pSrc2, unsigned long Length);
 
-UCHAR BtoH(
-	char ch);
+void RTMPMoveMemory(void *pDest, void *pSrc, unsigned long Length);
 
-VOID RTMPPatchMacBbpBug(
-	IN  PRTMP_ADAPTER   pAd);
+void AtoH(char *src, u8 *dest, int destlen);
 
-VOID RTMPInitTimer(
-	IN  PRTMP_ADAPTER           pAd,
-	IN  PRALINK_TIMER_STRUCT    pTimer,
-	IN  PVOID                   pTimerFunc,
-	IN	PVOID					pData,
-	IN  BOOLEAN                 Repeat);
+u8 BtoH(char ch);
 
-VOID RTMPSetTimer(
-	IN  PRALINK_TIMER_STRUCT    pTimer,
-	IN  ULONG                   Value);
+void RTMPPatchMacBbpBug(struct rt_rtmp_adapter *pAd);
 
+void RTMPInitTimer(struct rt_rtmp_adapter *pAd,
+		   struct rt_ralink_timer *pTimer,
+		   void *pTimerFunc, void *pData, IN BOOLEAN Repeat);
 
-VOID RTMPModTimer(
-	IN	PRALINK_TIMER_STRUCT	pTimer,
-	IN	ULONG					Value);
+void RTMPSetTimer(struct rt_ralink_timer *pTimer, unsigned long Value);
 
-VOID RTMPCancelTimer(
-	IN  PRALINK_TIMER_STRUCT    pTimer,
-	OUT BOOLEAN                 *pCancelled);
+void RTMPModTimer(struct rt_ralink_timer *pTimer, unsigned long Value);
 
-VOID RTMPSetLED(
-	IN PRTMP_ADAPTER 	pAd,
-	IN UCHAR			Status);
+void RTMPCancelTimer(struct rt_ralink_timer *pTimer, OUT BOOLEAN * pCancelled);
 
-VOID RTMPSetSignalLED(
-	IN PRTMP_ADAPTER 	pAd,
-	IN NDIS_802_11_RSSI Dbm);
+void RTMPSetLED(struct rt_rtmp_adapter *pAd, u8 Status);
 
-VOID RTMPEnableRxTx(
-	IN PRTMP_ADAPTER	pAd);
+void RTMPSetSignalLED(struct rt_rtmp_adapter *pAd, IN NDIS_802_11_RSSI Dbm);
 
-//
-// prototype in action.c
-//
-VOID ActionStateMachineInit(
-    IN	PRTMP_ADAPTER	pAd,
-    IN  STATE_MACHINE *S,
-    OUT STATE_MACHINE_FUNC Trans[]);
+void RTMPEnableRxTx(struct rt_rtmp_adapter *pAd);
 
-VOID MlmeADDBAAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
+/* */
+/* prototype in action.c */
+/* */
+void ActionStateMachineInit(struct rt_rtmp_adapter *pAd,
+			    struct rt_state_machine *S,
+			    OUT STATE_MACHINE_FUNC Trans[]);
 
-VOID MlmeDELBAAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
+void MlmeADDBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID MlmeDLSAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
+void MlmeDELBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID MlmeInvalidAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
+void MlmeDLSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID MlmeQOSAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
+void MlmeInvalidAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID PeerAddBAReqAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
+void MlmeQOSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID PeerAddBARspAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
+void PeerAddBAReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID PeerDelBAAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
+void PeerAddBARspAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID PeerBAAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
+void PeerDelBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID SendPSMPAction(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			Wcid,
-	IN UCHAR			Psmp);
+void PeerBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID PeerRMAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
+void SendPSMPAction(struct rt_rtmp_adapter *pAd, u8 Wcid, u8 Psmp);
 
-VOID PeerPublicAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
+void PeerRMAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID PeerHTAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
+void PeerPublicAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID PeerQOSAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
+void PeerHTAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID RECBATimerTimeout(
-    IN PVOID SystemSpecific1,
-    IN PVOID FunctionContext,
-    IN PVOID SystemSpecific2,
-    IN PVOID SystemSpecific3);
+void PeerQOSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID ORIBATimerTimeout(
-	IN	PRTMP_ADAPTER	pAd);
+void RECBATimerTimeout(void *SystemSpecific1,
+		       void *FunctionContext,
+		       void *SystemSpecific2, void *SystemSpecific3);
 
-VOID SendRefreshBAR(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MAC_TABLE_ENTRY	*pEntry);
+void ORIBATimerTimeout(struct rt_rtmp_adapter *pAd);
 
-VOID ActHeaderInit(
-    IN	PRTMP_ADAPTER	pAd,
-    IN OUT PHEADER_802_11 pHdr80211,
-    IN PUCHAR Addr1,
-    IN PUCHAR Addr2,
-    IN PUCHAR Addr3);
+void SendRefreshBAR(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry);
 
-VOID BarHeaderInit(
-	IN	PRTMP_ADAPTER	pAd,
-	IN OUT PFRAME_BAR pCntlBar,
-	IN PUCHAR pDA,
-	IN PUCHAR pSA);
+void ActHeaderInit(struct rt_rtmp_adapter *pAd,
+		   struct rt_header_802_11 * pHdr80211,
+		   u8 *Addr1, u8 *Addr2, u8 *Addr3);
 
-VOID InsertActField(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pFrameBuf,
-	OUT PULONG pFrameLen,
-	IN UINT8 Category,
-	IN UINT8 ActCode);
+void BarHeaderInit(struct rt_rtmp_adapter *pAd,
+		   struct rt_frame_bar * pCntlBar, u8 *pDA, u8 *pSA);
 
-BOOLEAN CntlEnqueueForRecv(
-    IN	PRTMP_ADAPTER	pAd,
-	IN ULONG Wcid,
-    IN ULONG MsgLen,
-	IN PFRAME_BA_REQ pMsg);
+void InsertActField(struct rt_rtmp_adapter *pAd,
+		    u8 *pFrameBuf,
+		    unsigned long *pFrameLen, u8 Category, u8 ActCode);
 
-//
-// Private routines in rtmp_data.c
-//
-BOOLEAN RTMPHandleRxDoneInterrupt(
-	IN  PRTMP_ADAPTER   pAd);
+BOOLEAN CntlEnqueueForRecv(struct rt_rtmp_adapter *pAd,
+			   unsigned long Wcid,
+			   unsigned long MsgLen, struct rt_frame_ba_req * pMsg);
 
-BOOLEAN RTMPHandleTxRingDmaDoneInterrupt(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  INT_SOURCE_CSR_STRUC TxRingBitmap);
+/* */
+/* Private routines in rtmp_data.c */
+/* */
+BOOLEAN RTMPHandleRxDoneInterrupt(struct rt_rtmp_adapter *pAd);
 
-VOID RTMPHandleMgmtRingDmaDoneInterrupt(
-	IN  PRTMP_ADAPTER   pAd);
+BOOLEAN RTMPHandleTxRingDmaDoneInterrupt(struct rt_rtmp_adapter *pAd,
+					 INT_SOURCE_CSR_STRUC TxRingBitmap);
 
-VOID RTMPHandleTBTTInterrupt(
-	IN  PRTMP_ADAPTER   pAd);
+void RTMPHandleMgmtRingDmaDoneInterrupt(struct rt_rtmp_adapter *pAd);
 
-VOID RTMPHandlePreTBTTInterrupt(
-	IN  PRTMP_ADAPTER   pAd);
+void RTMPHandleTBTTInterrupt(struct rt_rtmp_adapter *pAd);
 
-void RTMPHandleTwakeupInterrupt(
-	IN PRTMP_ADAPTER pAd);
+void RTMPHandlePreTBTTInterrupt(struct rt_rtmp_adapter *pAd);
 
-VOID	RTMPHandleRxCoherentInterrupt(
-	IN	PRTMP_ADAPTER	pAd);
+void RTMPHandleTwakeupInterrupt(struct rt_rtmp_adapter *pAd);
 
-BOOLEAN TxFrameIsAggregatible(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pPrevAddr1,
-	IN  PUCHAR          p8023hdr);
+void RTMPHandleRxCoherentInterrupt(struct rt_rtmp_adapter *pAd);
 
-BOOLEAN PeerIsAggreOn(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  ULONG          TxRate,
-    IN  PMAC_TABLE_ENTRY pMacEntry);
+BOOLEAN TxFrameIsAggregatible(struct rt_rtmp_adapter *pAd,
+			      u8 *pPrevAddr1, u8 *p8023hdr);
 
-NDIS_STATUS Sniff2BytesFromNdisBuffer(
-	IN  PNDIS_BUFFER    pFirstBuffer,
-	IN  UCHAR           DesiredOffset,
-	OUT PUCHAR          pByte0,
-	OUT PUCHAR          pByte1);
+BOOLEAN PeerIsAggreOn(struct rt_rtmp_adapter *pAd,
+		      unsigned long TxRate, struct rt_mac_table_entry *pMacEntry);
 
-NDIS_STATUS STASendPacket(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PNDIS_PACKET    pPacket);
+int Sniff2BytesFromNdisBuffer(char *pFirstBuffer,
+				      u8 DesiredOffset,
+				      u8 *pByte0, u8 *pByte1);
 
-VOID STASendPackets(
-	IN  NDIS_HANDLE     MiniportAdapterContext,
-	IN  PPNDIS_PACKET   ppPacketArray,
-	IN  UINT            NumberOfPackets);
+int STASendPacket(struct rt_rtmp_adapter *pAd, void *pPacket);
 
-VOID RTMPDeQueuePacket(
-	IN  PRTMP_ADAPTER   pAd,
-   	IN	BOOLEAN			bIntContext,
-	IN  UCHAR			QueIdx,
-	IN	UCHAR			Max_Tx_Packets);
+void STASendPackets(void *MiniportAdapterContext,
+		    void **ppPacketArray, u32 NumberOfPackets);
 
-NDIS_STATUS	RTMPHardTransmit(
-	IN PRTMP_ADAPTER	pAd,
-	IN PNDIS_PACKET		pPacket,
-	IN  UCHAR			QueIdx,
-	OUT	PULONG			pFreeTXDLeft);
+void RTMPDeQueuePacket(struct rt_rtmp_adapter *pAd,
+		       IN BOOLEAN bIntContext,
+		       u8 QueIdx, u8 Max_Tx_Packets);
 
-NDIS_STATUS	STAHardTransmit(
-	IN PRTMP_ADAPTER	pAd,
-	IN TX_BLK			*pTxBlk,
-	IN  UCHAR			QueIdx);
+int RTMPHardTransmit(struct rt_rtmp_adapter *pAd,
+			     void *pPacket,
+			     u8 QueIdx, unsigned long *pFreeTXDLeft);
 
-VOID STARxEAPOLFrameIndicate(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MAC_TABLE_ENTRY	*pEntry,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID);
+int STAHardTransmit(struct rt_rtmp_adapter *pAd,
+			    struct rt_tx_blk *pTxBlk, u8 QueIdx);
 
-NDIS_STATUS RTMPFreeTXDRequest(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR           RingType,
-	IN  UCHAR           NumberRequired,
-	IN 	PUCHAR          FreeNumberIs);
+void STARxEAPOLFrameIndicate(struct rt_rtmp_adapter *pAd,
+			     struct rt_mac_table_entry *pEntry,
+			     struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID);
 
-NDIS_STATUS MlmeHardTransmit(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR	QueIdx,
-	IN  PNDIS_PACKET    pPacket);
+int RTMPFreeTXDRequest(struct rt_rtmp_adapter *pAd,
+			       u8 RingType,
+			       u8 NumberRequired, u8 *FreeNumberIs);
 
-NDIS_STATUS MlmeHardTransmitMgmtRing(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR	QueIdx,
-	IN  PNDIS_PACKET    pPacket);
+int MlmeHardTransmit(struct rt_rtmp_adapter *pAd,
+			     u8 QueIdx, void *pPacket);
 
-NDIS_STATUS MlmeHardTransmitTxRing(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR	QueIdx,
-	IN  PNDIS_PACKET    pPacket);
+int MlmeHardTransmitMgmtRing(struct rt_rtmp_adapter *pAd,
+				     u8 QueIdx, void *pPacket);
 
-USHORT  RTMPCalcDuration(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR           Rate,
-	IN  ULONG           Size);
+#ifdef RTMP_MAC_PCI
+int MlmeHardTransmitTxRing(struct rt_rtmp_adapter *pAd,
+				   u8 QueIdx, void *pPacket);
 
-VOID RTMPWriteTxWI(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PTXWI_STRUC		pTxWI,
-	IN  BOOLEAN    		FRAG,
-	IN  BOOLEAN    		CFACK,
-	IN  BOOLEAN    		InsTimestamp,
-	IN	BOOLEAN			AMPDU,
-	IN	BOOLEAN			Ack,
-	IN	BOOLEAN			NSeq,		// HW new a sequence.
-	IN	UCHAR			BASize,
-	IN	UCHAR			WCID,
-	IN	ULONG			Length,
-	IN  UCHAR      		PID,
-	IN	UCHAR			TID,
-	IN	UCHAR			TxRate,
-	IN	UCHAR			Txopmode,
-	IN	BOOLEAN			CfAck,
-	IN	HTTRANSMIT_SETTING	*pTransmit);
+int MlmeDataHardTransmit(struct rt_rtmp_adapter *pAd,
+				 u8 QueIdx, void *pPacket);
 
+void RTMPWriteTxDescriptor(struct rt_rtmp_adapter *pAd,
+			   struct rt_txd * pTxD, IN BOOLEAN bWIV, u8 QSEL);
+#endif /* RTMP_MAC_PCI // */
 
-VOID RTMPWriteTxWI_Data(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	OUT PTXWI_STRUC		pTxWI,
-	IN	TX_BLK				*pTxBlk);
+u16 RTMPCalcDuration(struct rt_rtmp_adapter *pAd, u8 Rate, unsigned long Size);
 
+void RTMPWriteTxWI(struct rt_rtmp_adapter *pAd, struct rt_txwi * pTxWI, IN BOOLEAN FRAG, IN BOOLEAN CFACK, IN BOOLEAN InsTimestamp, IN BOOLEAN AMPDU, IN BOOLEAN Ack, IN BOOLEAN NSeq,	/* HW new a sequence. */
+		   u8 BASize,
+		   u8 WCID,
+		   unsigned long Length,
+		   u8 PID,
+		   u8 TID,
+		   u8 TxRate,
+		   u8 Txopmode,
+		   IN BOOLEAN CfAck, IN HTTRANSMIT_SETTING * pTransmit);
 
-VOID RTMPWriteTxWI_Cache(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	OUT PTXWI_STRUC		pTxWI,
-	IN	TX_BLK				*pTxBlk);
+void RTMPWriteTxWI_Data(struct rt_rtmp_adapter *pAd,
+			struct rt_txwi * pTxWI, struct rt_tx_blk *pTxBlk);
 
-VOID RTMPWriteTxDescriptor(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PTXD_STRUC		pTxD,
-	IN	BOOLEAN			bWIV,
-	IN	UCHAR			QSEL);
+void RTMPWriteTxWI_Cache(struct rt_rtmp_adapter *pAd,
+			 struct rt_txwi * pTxWI, struct rt_tx_blk *pTxBlk);
 
-VOID RTMPSuspendMsduTransmission(
-	IN  PRTMP_ADAPTER   pAd);
+void RTMPSuspendMsduTransmission(struct rt_rtmp_adapter *pAd);
 
-VOID RTMPResumeMsduTransmission(
-	IN  PRTMP_ADAPTER   pAd);
+void RTMPResumeMsduTransmission(struct rt_rtmp_adapter *pAd);
 
-NDIS_STATUS MiniportMMRequest(
-	IN  PRTMP_ADAPTER   pAd,
-	IN	UCHAR			QueIdx,
-	IN	PUCHAR			pData,
-	IN  UINT            Length);
+int MiniportMMRequest(struct rt_rtmp_adapter *pAd,
+			      u8 QueIdx, u8 *pData, u32 Length);
 
-VOID RTMPSendNullFrame(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR           TxRate,
-	IN	BOOLEAN			bQosNull);
+/*+++mark by shiang, now this function merge to MiniportMMRequest() */
+/*---mark by shiang, now this function merge to MiniportMMRequest() */
 
-VOID RTMPSendDisassociationFrame(
-	IN	PRTMP_ADAPTER	pAd);
+void RTMPSendNullFrame(struct rt_rtmp_adapter *pAd,
+		       u8 TxRate, IN BOOLEAN bQosNull);
 
-VOID RTMPSendRTSFrame(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pDA,
-	IN	unsigned int	NextMpduSize,
-	IN  UCHAR           TxRate,
-	IN  UCHAR           RTSRate,
-	IN  USHORT          AckDuration,
-	IN  UCHAR           QueIdx,
-	IN  UCHAR			FrameGap);
+void RTMPSendDisassociationFrame(struct rt_rtmp_adapter *pAd);
 
-PQUEUE_HEADER   RTMPCheckTxSwQueue(
-	IN  PRTMP_ADAPTER   pAd,
-	OUT UCHAR           *QueIdx);
+void RTMPSendRTSFrame(struct rt_rtmp_adapter *pAd,
+		      u8 *pDA,
+		      IN unsigned int NextMpduSize,
+		      u8 TxRate,
+		      u8 RTSRate,
+		      u16 AckDuration,
+		      u8 QueIdx, u8 FrameGap);
 
-VOID RTMPReportMicError(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PCIPHER_KEY     pWpaKey);
+struct rt_queue_header *RTMPCheckTxSwQueue(struct rt_rtmp_adapter *pAd, u8 * QueIdx);
 
-VOID	WpaMicFailureReportFrame(
-	IN  PRTMP_ADAPTER    pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void RTMPReportMicError(struct rt_rtmp_adapter *pAd, struct rt_cipher_key *pWpaKey);
 
-VOID    WpaDisassocApAndBlockAssoc(
-    IN  PVOID SystemSpecific1,
-    IN  PVOID FunctionContext,
-    IN  PVOID SystemSpecific2,
-    IN  PVOID SystemSpecific3);
+void WpaMicFailureReportFrame(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-NDIS_STATUS RTMPCloneNdisPacket(
-	IN  PRTMP_ADAPTER   pAd,
-	IN	BOOLEAN    pInsAMSDUHdr,
-	IN  PNDIS_PACKET    pInPacket,
-	OUT PNDIS_PACKET   *ppOutPacket);
+void WpaDisassocApAndBlockAssoc(void *SystemSpecific1,
+				void *FunctionContext,
+				void *SystemSpecific2,
+				void *SystemSpecific3);
 
-NDIS_STATUS RTMPAllocateNdisPacket(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PNDIS_PACKET    *pPacket,
-	IN  PUCHAR          pHeader,
-	IN  UINT            HeaderLen,
-	IN  PUCHAR          pData,
-	IN  UINT            DataLen);
+void WpaStaPairwiseKeySetting(struct rt_rtmp_adapter *pAd);
 
-VOID RTMPFreeNdisPacket(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PNDIS_PACKET    pPacket);
+void WpaStaGroupKeySetting(struct rt_rtmp_adapter *pAd);
 
-BOOLEAN RTMPFreeTXDUponTxDmaDone(
-	IN PRTMP_ADAPTER    pAd,
-	IN UCHAR            QueIdx);
+int RTMPCloneNdisPacket(struct rt_rtmp_adapter *pAd,
+				IN BOOLEAN pInsAMSDUHdr,
+				void *pInPacket,
+				void ** ppOutPacket);
 
-BOOLEAN RTMPCheckDHCPFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket);
+int RTMPAllocateNdisPacket(struct rt_rtmp_adapter *pAd,
+				   void ** pPacket,
+				   u8 *pHeader,
+				   u32 HeaderLen,
+				   u8 *pData, u32 DataLen);
 
+void RTMPFreeNdisPacket(struct rt_rtmp_adapter *pAd, void *pPacket);
 
-BOOLEAN RTMPCheckEtherType(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket);
+BOOLEAN RTMPFreeTXDUponTxDmaDone(struct rt_rtmp_adapter *pAd, u8 QueIdx);
 
+BOOLEAN RTMPCheckDHCPFrame(struct rt_rtmp_adapter *pAd, void *pPacket);
 
-//
-// Private routines in rtmp_wep.c
-//
-VOID RTMPInitWepEngine(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pKey,
-	IN  UCHAR           KeyId,
-	IN  UCHAR           KeyLen,
-	IN  PUCHAR          pDest);
+BOOLEAN RTMPCheckEtherType(struct rt_rtmp_adapter *pAd, void *pPacket);
 
-VOID RTMPEncryptData(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pSrc,
-	IN  PUCHAR          pDest,
-	IN  UINT            Len);
+/* */
+/* Private routines in rtmp_wep.c */
+/* */
+void RTMPInitWepEngine(struct rt_rtmp_adapter *pAd,
+		       u8 *pKey,
+		       u8 KeyId, u8 KeyLen, u8 *pDest);
 
-BOOLEAN	RTMPSoftDecryptWEP(
-	IN PRTMP_ADAPTER 	pAd,
-	IN PUCHAR			pData,
-	IN ULONG			DataByteCnt,
-	IN PCIPHER_KEY		pGroupKey);
+void RTMPEncryptData(struct rt_rtmp_adapter *pAd,
+		     u8 *pSrc, u8 *pDest, u32 Len);
 
-VOID RTMPSetICV(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pDest);
+BOOLEAN RTMPSoftDecryptWEP(struct rt_rtmp_adapter *pAd,
+			   u8 *pData,
+			   unsigned long DataByteCnt, struct rt_cipher_key *pGroupKey);
 
-VOID ARCFOUR_INIT(
-	IN  PARCFOURCONTEXT Ctx,
-	IN  PUCHAR          pKey,
-	IN  UINT            KeyLen);
+void RTMPSetICV(struct rt_rtmp_adapter *pAd, u8 *pDest);
 
-UCHAR   ARCFOUR_BYTE(
-	IN  PARCFOURCONTEXT     Ctx);
+void ARCFOUR_INIT(struct rt_arcfourcontext *Ctx, u8 *pKey, u32 KeyLen);
 
-VOID ARCFOUR_DECRYPT(
-	IN  PARCFOURCONTEXT Ctx,
-	IN  PUCHAR          pDest,
-	IN  PUCHAR          pSrc,
-	IN  UINT            Len);
+u8 ARCFOUR_BYTE(struct rt_arcfourcontext *Ctx);
 
-VOID ARCFOUR_ENCRYPT(
-	IN  PARCFOURCONTEXT Ctx,
-	IN  PUCHAR          pDest,
-	IN  PUCHAR          pSrc,
-	IN  UINT            Len);
+void ARCFOUR_DECRYPT(struct rt_arcfourcontext *Ctx,
+		     u8 *pDest, u8 *pSrc, u32 Len);
 
-VOID WPAARCFOUR_ENCRYPT(
-	IN  PARCFOURCONTEXT Ctx,
-	IN  PUCHAR          pDest,
-	IN  PUCHAR          pSrc,
-	IN  UINT            Len);
+void ARCFOUR_ENCRYPT(struct rt_arcfourcontext *Ctx,
+		     u8 *pDest, u8 *pSrc, u32 Len);
 
-UINT RTMP_CALC_FCS32(
-	IN  UINT   Fcs,
-	IN  PUCHAR  Cp,
-	IN  INT     Len);
+void WPAARCFOUR_ENCRYPT(struct rt_arcfourcontext *Ctx,
+			u8 *pDest, u8 *pSrc, u32 Len);
 
-//
-// MLME routines
-//
+u32 RTMP_CALC_FCS32(u32 Fcs, u8 *Cp, int Len);
 
-// Asic/RF/BBP related functions
+/* */
+/* MLME routines */
+/* */
 
-VOID AsicAdjustTxPower(
-	IN PRTMP_ADAPTER pAd);
+/* Asic/RF/BBP related functions */
 
-VOID 	AsicUpdateProtect(
-	IN		PRTMP_ADAPTER	pAd,
-	IN 		USHORT			OperaionMode,
-	IN 		UCHAR			SetMask,
-	IN		BOOLEAN			bDisableBGProtect,
-	IN		BOOLEAN			bNonGFExist);
+void AsicAdjustTxPower(struct rt_rtmp_adapter *pAd);
 
-VOID AsicSwitchChannel(
-	IN  PRTMP_ADAPTER   pAd,
-	IN	UCHAR			Channel,
-	IN	BOOLEAN			bScan);
+void AsicUpdateProtect(struct rt_rtmp_adapter *pAd,
+		       u16 OperaionMode,
+		       u8 SetMask,
+		       IN BOOLEAN bDisableBGProtect, IN BOOLEAN bNonGFExist);
 
-VOID AsicLockChannel(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR Channel) ;
+void AsicSwitchChannel(struct rt_rtmp_adapter *pAd,
+		       u8 Channel, IN BOOLEAN bScan);
 
-VOID AsicRfTuningExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
+void AsicLockChannel(struct rt_rtmp_adapter *pAd, u8 Channel);
 
-VOID AsicSleepThenAutoWakeup(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  USHORT TbttNumToNextWakeUp);
+void AsicRfTuningExec(void *SystemSpecific1,
+		      void *FunctionContext,
+		      void *SystemSpecific2, void *SystemSpecific3);
 
-VOID AsicForceSleep(
-	IN PRTMP_ADAPTER pAd);
+void AsicResetBBPAgent(struct rt_rtmp_adapter *pAd);
 
-VOID AsicForceWakeup(
-	IN PRTMP_ADAPTER pAd,
-#ifdef RT2860
-	IN UCHAR    	 Level);
-#endif
-#ifdef RT2870
-	IN BOOLEAN    bFromTx);
-#endif
+void AsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd,
+			     u16 TbttNumToNextWakeUp);
 
-VOID AsicSetBssid(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR pBssid);
+void AsicForceSleep(struct rt_rtmp_adapter *pAd);
 
-VOID AsicSetMcastWC(
-	IN PRTMP_ADAPTER pAd);
+void AsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx);
 
-VOID AsicDelWcidTab(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR	Wcid);
+void AsicSetBssid(struct rt_rtmp_adapter *pAd, u8 *pBssid);
 
-VOID AsicEnableRDG(
-	IN PRTMP_ADAPTER pAd);
+void AsicSetMcastWC(struct rt_rtmp_adapter *pAd);
 
-VOID AsicDisableRDG(
-	IN PRTMP_ADAPTER pAd);
+void AsicDelWcidTab(struct rt_rtmp_adapter *pAd, u8 Wcid);
 
-VOID AsicDisableSync(
-	IN  PRTMP_ADAPTER   pAd);
+void AsicEnableRDG(struct rt_rtmp_adapter *pAd);
 
-VOID AsicEnableBssSync(
-	IN  PRTMP_ADAPTER   pAd);
+void AsicDisableRDG(struct rt_rtmp_adapter *pAd);
 
-VOID AsicEnableIbssSync(
-	IN  PRTMP_ADAPTER   pAd);
+void AsicDisableSync(struct rt_rtmp_adapter *pAd);
 
-VOID AsicSetEdcaParm(
-	IN PRTMP_ADAPTER pAd,
-	IN PEDCA_PARM    pEdcaParm);
+void AsicEnableBssSync(struct rt_rtmp_adapter *pAd);
 
-VOID AsicSetSlotTime(
-	IN PRTMP_ADAPTER pAd,
-	IN BOOLEAN bUseShortSlotTime);
+void AsicEnableIbssSync(struct rt_rtmp_adapter *pAd);
 
-VOID AsicAddSharedKeyEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR         BssIndex,
-	IN UCHAR         KeyIdx,
-	IN UCHAR         CipherAlg,
-	IN PUCHAR        pKey,
-	IN PUCHAR        pTxMic,
-	IN PUCHAR        pRxMic);
+void AsicSetEdcaParm(struct rt_rtmp_adapter *pAd, struct rt_edca_parm *pEdcaParm);
 
-VOID AsicRemoveSharedKeyEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR         BssIndex,
-	IN UCHAR         KeyIdx);
+void AsicSetSlotTime(struct rt_rtmp_adapter *pAd, IN BOOLEAN bUseShortSlotTime);
 
-VOID AsicUpdateWCIDAttribute(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT		WCID,
-	IN UCHAR		BssIndex,
-	IN UCHAR        CipherAlg,
-	IN BOOLEAN		bUsePairewiseKeyTable);
+void AsicAddSharedKeyEntry(struct rt_rtmp_adapter *pAd,
+			   u8 BssIndex,
+			   u8 KeyIdx,
+			   u8 CipherAlg,
+			   u8 *pKey, u8 *pTxMic, u8 *pRxMic);
 
-VOID AsicUpdateWCIDIVEIV(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT		WCID,
-	IN ULONG        uIV,
-	IN ULONG        uEIV);
+void AsicRemoveSharedKeyEntry(struct rt_rtmp_adapter *pAd,
+			      u8 BssIndex, u8 KeyIdx);
 
-VOID AsicUpdateRxWCIDTable(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT		WCID,
-	IN PUCHAR        pAddr);
+void AsicUpdateWCIDAttribute(struct rt_rtmp_adapter *pAd,
+			     u16 WCID,
+			     u8 BssIndex,
+			     u8 CipherAlg,
+			     IN BOOLEAN bUsePairewiseKeyTable);
 
-VOID AsicAddKeyEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT		WCID,
-	IN UCHAR		BssIndex,
-	IN UCHAR		KeyIdx,
-	IN PCIPHER_KEY	pCipherKey,
-	IN BOOLEAN		bUsePairewiseKeyTable,
-	IN BOOLEAN		bTxKey);
+void AsicUpdateWCIDIVEIV(struct rt_rtmp_adapter *pAd,
+			 u16 WCID, unsigned long uIV, unsigned long uEIV);
 
-VOID AsicAddPairwiseKeyEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR        pAddr,
-	IN UCHAR		WCID,
-	IN CIPHER_KEY		 *pCipherKey);
+void AsicUpdateRxWCIDTable(struct rt_rtmp_adapter *pAd,
+			   u16 WCID, u8 *pAddr);
 
-VOID AsicRemovePairwiseKeyEntry(
-	IN PRTMP_ADAPTER  pAd,
-	IN UCHAR		 BssIdx,
-	IN UCHAR		 Wcid);
+void AsicAddKeyEntry(struct rt_rtmp_adapter *pAd,
+		     u16 WCID,
+		     u8 BssIndex,
+		     u8 KeyIdx,
+		     struct rt_cipher_key *pCipherKey,
+		     IN BOOLEAN bUsePairewiseKeyTable, IN BOOLEAN bTxKey);
 
-BOOLEAN AsicSendCommandToMcu(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR         Command,
-	IN UCHAR         Token,
-	IN UCHAR         Arg0,
-	IN UCHAR         Arg1);
-#ifdef RT2860
-BOOLEAN AsicCheckCommanOk(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR		 Command);
-#endif
-VOID MacAddrRandomBssid(
-	IN  PRTMP_ADAPTER   pAd,
-	OUT PUCHAR pAddr);
+void AsicAddPairwiseKeyEntry(struct rt_rtmp_adapter *pAd,
+			     u8 *pAddr,
+			     u8 WCID, struct rt_cipher_key *pCipherKey);
 
-VOID MgtMacHeaderInit(
-	IN  PRTMP_ADAPTER     pAd,
-	IN OUT PHEADER_802_11 pHdr80211,
-	IN UCHAR SubType,
-	IN UCHAR ToDs,
-	IN PUCHAR pDA,
-	IN PUCHAR pBssid);
+void AsicRemovePairwiseKeyEntry(struct rt_rtmp_adapter *pAd,
+				u8 BssIdx, u8 Wcid);
 
-VOID MlmeRadioOff(
-	IN PRTMP_ADAPTER pAd);
+BOOLEAN AsicSendCommandToMcu(struct rt_rtmp_adapter *pAd,
+			     u8 Command,
+			     u8 Token, u8 Arg0, u8 Arg1);
 
-VOID MlmeRadioOn(
-	IN PRTMP_ADAPTER pAd);
+#ifdef RTMP_MAC_PCI
+BOOLEAN AsicCheckCommanOk(struct rt_rtmp_adapter *pAd, u8 Command);
+#endif /* RTMP_MAC_PCI // */
 
+void MacAddrRandomBssid(struct rt_rtmp_adapter *pAd, u8 *pAddr);
 
-VOID BssTableInit(
-	IN BSS_TABLE *Tab);
+void MgtMacHeaderInit(struct rt_rtmp_adapter *pAd,
+		      struct rt_header_802_11 * pHdr80211,
+		      u8 SubType,
+		      u8 ToDs, u8 *pDA, u8 *pBssid);
 
-VOID BATableInit(
-	IN PRTMP_ADAPTER pAd,
-    IN BA_TABLE *Tab);
+void MlmeRadioOff(struct rt_rtmp_adapter *pAd);
 
-ULONG BssTableSearch(
-	IN BSS_TABLE *Tab,
-	IN PUCHAR pBssid,
-	IN UCHAR Channel);
+void MlmeRadioOn(struct rt_rtmp_adapter *pAd);
 
-ULONG BssSsidTableSearch(
-	IN BSS_TABLE *Tab,
-	IN PUCHAR    pBssid,
-	IN PUCHAR    pSsid,
-	IN UCHAR     SsidLen,
-	IN UCHAR     Channel);
+void BssTableInit(struct rt_bss_table *Tab);
 
-ULONG BssTableSearchWithSSID(
-	IN BSS_TABLE *Tab,
-	IN PUCHAR    Bssid,
-	IN PUCHAR    pSsid,
-	IN UCHAR     SsidLen,
-	IN UCHAR     Channel);
+void BATableInit(struct rt_rtmp_adapter *pAd, struct rt_ba_table *Tab);
 
-VOID BssTableDeleteEntry(
-	IN OUT  PBSS_TABLE pTab,
-	IN      PUCHAR pBssid,
-	IN      UCHAR Channel);
+unsigned long BssTableSearch(struct rt_bss_table *Tab, u8 *pBssid, u8 Channel);
 
-VOID BATableDeleteORIEntry(
-	IN OUT	PRTMP_ADAPTER pAd,
-	IN		BA_ORI_ENTRY	*pBAORIEntry);
+unsigned long BssSsidTableSearch(struct rt_bss_table *Tab,
+			 u8 *pBssid,
+			 u8 *pSsid, u8 SsidLen, u8 Channel);
 
-VOID  BssEntrySet(
-	IN  PRTMP_ADAPTER   pAd,
-	OUT PBSS_ENTRY pBss,
-	IN PUCHAR pBssid,
-	IN CHAR Ssid[],
-	IN UCHAR SsidLen,
-	IN UCHAR BssType,
-	IN USHORT BeaconPeriod,
-	IN PCF_PARM CfParm,
-	IN USHORT AtimWin,
-	IN USHORT CapabilityInfo,
-	IN UCHAR SupRate[],
-	IN UCHAR SupRateLen,
-	IN UCHAR ExtRate[],
-	IN UCHAR ExtRateLen,
-	IN HT_CAPABILITY_IE *pHtCapability,
-	IN ADD_HT_INFO_IE *pAddHtInfo,	// AP might use this additional ht info IE
-	IN UCHAR			HtCapabilityLen,
-	IN UCHAR			AddHtInfoLen,
-	IN UCHAR			NewExtChanOffset,
-	IN UCHAR Channel,
-	IN CHAR Rssi,
-	IN LARGE_INTEGER TimeStamp,
-	IN UCHAR CkipFlag,
-	IN PEDCA_PARM pEdcaParm,
-	IN PQOS_CAPABILITY_PARM pQosCapability,
-	IN PQBSS_LOAD_PARM pQbssLoad,
-	IN USHORT LengthVIE,
-	IN PNDIS_802_11_VARIABLE_IEs pVIE);
+unsigned long BssTableSearchWithSSID(struct rt_bss_table *Tab,
+			     u8 *Bssid,
+			     u8 *pSsid,
+			     u8 SsidLen, u8 Channel);
 
-ULONG  BssTableSetEntry(
-	IN  PRTMP_ADAPTER   pAd,
-	OUT PBSS_TABLE pTab,
-	IN PUCHAR pBssid,
-	IN CHAR Ssid[],
-	IN UCHAR SsidLen,
-	IN UCHAR BssType,
-	IN USHORT BeaconPeriod,
-	IN CF_PARM *CfParm,
-	IN USHORT AtimWin,
-	IN USHORT CapabilityInfo,
-	IN UCHAR SupRate[],
-	IN UCHAR SupRateLen,
-	IN UCHAR ExtRate[],
-	IN UCHAR ExtRateLen,
-	IN HT_CAPABILITY_IE *pHtCapability,
-	IN ADD_HT_INFO_IE *pAddHtInfo,	// AP might use this additional ht info IE
-	IN UCHAR			HtCapabilityLen,
-	IN UCHAR			AddHtInfoLen,
-	IN UCHAR			NewExtChanOffset,
-	IN UCHAR Channel,
-	IN CHAR Rssi,
-	IN LARGE_INTEGER TimeStamp,
-	IN UCHAR CkipFlag,
-	IN PEDCA_PARM pEdcaParm,
-	IN PQOS_CAPABILITY_PARM pQosCapability,
-	IN PQBSS_LOAD_PARM pQbssLoad,
-	IN USHORT LengthVIE,
-	IN PNDIS_802_11_VARIABLE_IEs pVIE);
+unsigned long BssSsidTableSearchBySSID(struct rt_bss_table *Tab,
+			       u8 *pSsid, u8 SsidLen);
 
-VOID BATableInsertEntry(
-    IN	PRTMP_ADAPTER	pAd,
-	IN USHORT Aid,
-    IN USHORT		TimeOutValue,
-	IN USHORT		StartingSeq,
-    IN UCHAR TID,
-	IN UCHAR BAWinSize,
-	IN UCHAR OriginatorStatus,
-    IN BOOLEAN IsRecipient);
+void BssTableDeleteEntry(struct rt_bss_table *pTab,
+			 u8 *pBssid, u8 Channel);
 
-VOID BssTableSsidSort(
-	IN  PRTMP_ADAPTER   pAd,
-	OUT BSS_TABLE *OutTab,
-	IN  CHAR Ssid[],
-	IN  UCHAR SsidLen);
+void BATableDeleteORIEntry(struct rt_rtmp_adapter *pAd,
+			   struct rt_ba_ori_entry *pBAORIEntry);
 
-VOID  BssTableSortByRssi(
-	IN OUT BSS_TABLE *OutTab);
+void BssEntrySet(struct rt_rtmp_adapter *pAd, struct rt_bss_entry *pBss, u8 *pBssid, char Ssid[], u8 SsidLen, u8 BssType, u16 BeaconPeriod, struct rt_cf_parm * CfParm, u16 AtimWin, u16 CapabilityInfo, u8 SupRate[], u8 SupRateLen, u8 ExtRate[], u8 ExtRateLen, struct rt_ht_capability_ie * pHtCapability, struct rt_add_ht_info_ie * pAddHtInfo,	/* AP might use this additional ht info IE */
+		 u8 HtCapabilityLen,
+		 u8 AddHtInfoLen,
+		 u8 NewExtChanOffset,
+		 u8 Channel,
+		 char Rssi,
+		 IN LARGE_INTEGER TimeStamp,
+		 u8 CkipFlag,
+		 struct rt_edca_parm *pEdcaParm,
+		 struct rt_qos_capability_parm *pQosCapability,
+		 struct rt_qbss_load_parm *pQbssLoad,
+		 u16 LengthVIE, struct rt_ndis_802_11_variable_ies *pVIE);
 
-VOID BssCipherParse(
-	IN OUT  PBSS_ENTRY  pBss);
+unsigned long BssTableSetEntry(struct rt_rtmp_adapter *pAd, struct rt_bss_table *pTab, u8 *pBssid, char Ssid[], u8 SsidLen, u8 BssType, u16 BeaconPeriod, struct rt_cf_parm * CfParm, u16 AtimWin, u16 CapabilityInfo, u8 SupRate[], u8 SupRateLen, u8 ExtRate[], u8 ExtRateLen, struct rt_ht_capability_ie * pHtCapability, struct rt_add_ht_info_ie * pAddHtInfo,	/* AP might use this additional ht info IE */
+		       u8 HtCapabilityLen,
+		       u8 AddHtInfoLen,
+		       u8 NewExtChanOffset,
+		       u8 Channel,
+		       char Rssi,
+		       IN LARGE_INTEGER TimeStamp,
+		       u8 CkipFlag,
+		       struct rt_edca_parm *pEdcaParm,
+		       struct rt_qos_capability_parm *pQosCapability,
+		       struct rt_qbss_load_parm *pQbssLoad,
+		       u16 LengthVIE, struct rt_ndis_802_11_variable_ies *pVIE);
 
-NDIS_STATUS  MlmeQueueInit(
-	IN MLME_QUEUE *Queue);
+void BATableInsertEntry(struct rt_rtmp_adapter *pAd,
+			u16 Aid,
+			u16 TimeOutValue,
+			u16 StartingSeq,
+			u8 TID,
+			u8 BAWinSize,
+			u8 OriginatorStatus, IN BOOLEAN IsRecipient);
 
-VOID  MlmeQueueDestroy(
-	IN MLME_QUEUE *Queue);
+void BssTableSsidSort(struct rt_rtmp_adapter *pAd,
+		      struct rt_bss_table *OutTab, char Ssid[], u8 SsidLen);
 
-BOOLEAN MlmeEnqueue(
-	IN PRTMP_ADAPTER pAd,
-	IN ULONG Machine,
-	IN ULONG MsgType,
-	IN ULONG MsgLen,
-	IN VOID *Msg);
+void BssTableSortByRssi(struct rt_bss_table *OutTab);
 
-BOOLEAN MlmeEnqueueForRecv(
-	IN  PRTMP_ADAPTER   pAd,
-	IN ULONG Wcid,
-	IN ULONG TimeStampHigh,
-	IN ULONG TimeStampLow,
-	IN UCHAR Rssi0,
-	IN UCHAR Rssi1,
-	IN UCHAR Rssi2,
-	IN ULONG MsgLen,
-	IN PVOID Msg,
-	IN UCHAR Signal);
+void BssCipherParse(struct rt_bss_entry *pBss);
 
+int MlmeQueueInit(struct rt_mlme_queue *Queue);
 
-BOOLEAN MlmeDequeue(
-	IN MLME_QUEUE *Queue,
-	OUT MLME_QUEUE_ELEM **Elem);
+void MlmeQueueDestroy(struct rt_mlme_queue *Queue);
 
-VOID    MlmeRestartStateMachine(
-	IN  PRTMP_ADAPTER   pAd);
+BOOLEAN MlmeEnqueue(struct rt_rtmp_adapter *pAd,
+		    unsigned long Machine,
+		    unsigned long MsgType, unsigned long MsgLen, void * Msg);
 
-BOOLEAN  MlmeQueueEmpty(
-	IN MLME_QUEUE *Queue);
+BOOLEAN MlmeEnqueueForRecv(struct rt_rtmp_adapter *pAd,
+			   unsigned long Wcid,
+			   unsigned long TimeStampHigh,
+			   unsigned long TimeStampLow,
+			   u8 Rssi0,
+			   u8 Rssi1,
+			   u8 Rssi2,
+			   unsigned long MsgLen, void *Msg, u8 Signal);
 
-BOOLEAN  MlmeQueueFull(
-	IN MLME_QUEUE *Queue);
+BOOLEAN MlmeDequeue(struct rt_mlme_queue *Queue, struct rt_mlme_queue_elem ** Elem);
 
-BOOLEAN  MsgTypeSubst(
-	IN PRTMP_ADAPTER pAd,
-	IN PFRAME_802_11 pFrame,
-	OUT INT *Machine,
-	OUT INT *MsgType);
+void MlmeRestartStateMachine(struct rt_rtmp_adapter *pAd);
 
-VOID StateMachineInit(
-	IN STATE_MACHINE *Sm,
-	IN STATE_MACHINE_FUNC Trans[],
-	IN ULONG StNr,
-	IN ULONG MsgNr,
-	IN STATE_MACHINE_FUNC DefFunc,
-	IN ULONG InitState,
-	IN ULONG Base);
+BOOLEAN MlmeQueueEmpty(struct rt_mlme_queue *Queue);
 
-VOID StateMachineSetAction(
-	IN STATE_MACHINE *S,
-	IN ULONG St,
-	ULONG Msg,
-	IN STATE_MACHINE_FUNC F);
+BOOLEAN MlmeQueueFull(struct rt_mlme_queue *Queue);
 
-VOID StateMachinePerformAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN STATE_MACHINE *S,
-	IN MLME_QUEUE_ELEM *Elem);
+BOOLEAN MsgTypeSubst(struct rt_rtmp_adapter *pAd,
+		     struct rt_frame_802_11 * pFrame,
+		     int * Machine, int * MsgType);
 
-VOID Drop(
-	IN  PRTMP_ADAPTER   pAd,
-	IN MLME_QUEUE_ELEM *Elem);
+void StateMachineInit(struct rt_state_machine *Sm,
+		      IN STATE_MACHINE_FUNC Trans[],
+		      unsigned long StNr,
+		      unsigned long MsgNr,
+		      IN STATE_MACHINE_FUNC DefFunc,
+		      unsigned long InitState, unsigned long Base);
 
-VOID AssocStateMachineInit(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  STATE_MACHINE *Sm,
-	OUT STATE_MACHINE_FUNC Trans[]);
+void StateMachineSetAction(struct rt_state_machine *S,
+			   unsigned long St, unsigned long Msg, IN STATE_MACHINE_FUNC F);
 
-VOID ReassocTimeout(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
+void StateMachinePerformAction(struct rt_rtmp_adapter *pAd,
+			       struct rt_state_machine *S, struct rt_mlme_queue_elem *Elem);
 
-VOID AssocTimeout(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
+void Drop(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID DisassocTimeout(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
+void AssocStateMachineInit(struct rt_rtmp_adapter *pAd,
+			   struct rt_state_machine *Sm,
+			   OUT STATE_MACHINE_FUNC Trans[]);
 
-//----------------------------------------------
-VOID MlmeAssocReqAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void ReassocTimeout(void *SystemSpecific1,
+		    void *FunctionContext,
+		    void *SystemSpecific2, void *SystemSpecific3);
 
-VOID MlmeReassocReqAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void AssocTimeout(void *SystemSpecific1,
+		  void *FunctionContext,
+		  void *SystemSpecific2, void *SystemSpecific3);
 
-VOID MlmeDisassocReqAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void DisassocTimeout(void *SystemSpecific1,
+		     void *FunctionContext,
+		     void *SystemSpecific2, void *SystemSpecific3);
 
-VOID PeerAssocRspAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+/*---------------------------------------------- */
+void MlmeAssocReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID PeerReassocRspAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void MlmeReassocReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID PeerDisassocAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void MlmeDisassocReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID DisassocTimeoutAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void PeerAssocRspAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID AssocTimeoutAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void PeerReassocRspAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID  ReassocTimeoutAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void PeerDisassocAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID  Cls3errAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR pAddr);
+void DisassocTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID SwitchBetweenWepAndCkip(
-	IN PRTMP_ADAPTER pAd);
+void AssocTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID  InvalidStateWhenAssoc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void ReassocTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID  InvalidStateWhenReassoc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void Cls3errAction(struct rt_rtmp_adapter *pAd, u8 *pAddr);
 
-VOID InvalidStateWhenDisassociate(
-	IN  PRTMP_ADAPTER pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void InvalidStateWhenAssoc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-#ifdef RT2870
-VOID MlmeCntlConfirm(
-	IN PRTMP_ADAPTER pAd,
-	IN ULONG MsgType,
-	IN USHORT Msg);
-#endif // RT2870 //
+void InvalidStateWhenReassoc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID  ComposePsPoll(
-	IN  PRTMP_ADAPTER   pAd);
+void InvalidStateWhenDisassociate(struct rt_rtmp_adapter *pAd,
+				  struct rt_mlme_queue_elem *Elem);
 
-VOID  ComposeNullFrame(
-	IN  PRTMP_ADAPTER pAd);
+#ifdef RTMP_MAC_USB
+void MlmeCntlConfirm(struct rt_rtmp_adapter *pAd, unsigned long MsgType, u16 Msg);
+#endif /* RTMP_MAC_USB // */
 
-VOID  AssocPostProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR pAddr2,
-	IN  USHORT CapabilityInfo,
-	IN  USHORT Aid,
-	IN  UCHAR SupRate[],
-	IN  UCHAR SupRateLen,
-	IN  UCHAR ExtRate[],
-	IN  UCHAR ExtRateLen,
-	IN PEDCA_PARM pEdcaParm,
-	IN HT_CAPABILITY_IE		*pHtCapability,
-	IN  UCHAR HtCapabilityLen,
-	IN ADD_HT_INFO_IE		*pAddHtInfo);
+void ComposePsPoll(struct rt_rtmp_adapter *pAd);
 
-VOID AuthStateMachineInit(
-	IN  PRTMP_ADAPTER   pAd,
-	IN PSTATE_MACHINE sm,
-	OUT STATE_MACHINE_FUNC Trans[]);
+void ComposeNullFrame(struct rt_rtmp_adapter *pAd);
 
-VOID AuthTimeout(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
+void AssocPostProc(struct rt_rtmp_adapter *pAd,
+		   u8 *pAddr2,
+		   u16 CapabilityInfo,
+		   u16 Aid,
+		   u8 SupRate[],
+		   u8 SupRateLen,
+		   u8 ExtRate[],
+		   u8 ExtRateLen,
+		   struct rt_edca_parm *pEdcaParm,
+		   struct rt_ht_capability_ie * pHtCapability,
+		   u8 HtCapabilityLen, struct rt_add_ht_info_ie * pAddHtInfo);
+
+void AuthStateMachineInit(struct rt_rtmp_adapter *pAd,
+			  struct rt_state_machine *sm, OUT STATE_MACHINE_FUNC Trans[]);
+
+void AuthTimeout(void *SystemSpecific1,
+		 void *FunctionContext,
+		 void *SystemSpecific2, void *SystemSpecific3);
 
-VOID MlmeAuthReqAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void MlmeAuthReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID PeerAuthRspAtSeq2Action(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void PeerAuthRspAtSeq2Action(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID PeerAuthRspAtSeq4Action(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void PeerAuthRspAtSeq4Action(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID AuthTimeoutAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void AuthTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID Cls2errAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR pAddr);
+void Cls2errAction(struct rt_rtmp_adapter *pAd, u8 *pAddr);
 
-VOID MlmeDeauthReqAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void MlmeDeauthReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID InvalidStateWhenAuth(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void InvalidStateWhenAuth(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-//=============================================
+/*============================================= */
 
-VOID AuthRspStateMachineInit(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PSTATE_MACHINE Sm,
-	IN  STATE_MACHINE_FUNC Trans[]);
+void AuthRspStateMachineInit(struct rt_rtmp_adapter *pAd,
+			     struct rt_state_machine *Sm,
+			     IN STATE_MACHINE_FUNC Trans[]);
 
-VOID PeerDeauthAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
+void PeerDeauthAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID PeerAuthSimpleRspGenAndSend(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PHEADER_802_11  pHdr80211,
-	IN  USHORT Alg,
-	IN  USHORT Seq,
-	IN  USHORT Reason,
-	IN  USHORT Status);
+void PeerAuthSimpleRspGenAndSend(struct rt_rtmp_adapter *pAd,
+				 struct rt_header_802_11 * pHdr80211,
+				 u16 Alg,
+				 u16 Seq,
+				 u16 Reason, u16 Status);
 
-//
-// Private routines in dls.c
-//
+/* */
+/* Private routines in dls.c */
+/* */
 
-//========================================
+/*======================================== */
 
-VOID SyncStateMachineInit(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  STATE_MACHINE *Sm,
-	OUT STATE_MACHINE_FUNC Trans[]);
+void SyncStateMachineInit(struct rt_rtmp_adapter *pAd,
+			  struct rt_state_machine *Sm,
+			  OUT STATE_MACHINE_FUNC Trans[]);
 
-VOID BeaconTimeout(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
+void BeaconTimeout(void *SystemSpecific1,
+		   void *FunctionContext,
+		   void *SystemSpecific2, void *SystemSpecific3);
 
-VOID ScanTimeout(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
+void ScanTimeout(void *SystemSpecific1,
+		 void *FunctionContext,
+		 void *SystemSpecific2, void *SystemSpecific3);
 
-VOID InvalidStateWhenScan(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void InvalidStateWhenScan(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID InvalidStateWhenJoin(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void InvalidStateWhenJoin(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID InvalidStateWhenStart(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void InvalidStateWhenStart(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID EnqueueProbeRequest(
-	IN PRTMP_ADAPTER pAd);
+void EnqueueProbeRequest(struct rt_rtmp_adapter *pAd);
 
-BOOLEAN ScanRunning(
-		IN PRTMP_ADAPTER pAd);
-//=========================================
+BOOLEAN ScanRunning(struct rt_rtmp_adapter *pAd);
+/*========================================= */
 
-VOID MlmeCntlInit(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  STATE_MACHINE *S,
-	OUT STATE_MACHINE_FUNC Trans[]);
+void MlmeCntlInit(struct rt_rtmp_adapter *pAd,
+		  struct rt_state_machine *S, OUT STATE_MACHINE_FUNC Trans[]);
 
-VOID MlmeCntlMachinePerformAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  STATE_MACHINE *S,
-	IN  MLME_QUEUE_ELEM *Elem);
+void MlmeCntlMachinePerformAction(struct rt_rtmp_adapter *pAd,
+				  struct rt_state_machine *S,
+				  struct rt_mlme_queue_elem *Elem);
 
-VOID CntlIdleProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void CntlIdleProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID CntlOidScanProc(
-	IN  PRTMP_ADAPTER pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void CntlOidScanProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID CntlOidSsidProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM * Elem);
+void CntlOidSsidProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID CntlOidRTBssidProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM * Elem);
+void CntlOidRTBssidProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID CntlMlmeRoamingProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM * Elem);
+void CntlMlmeRoamingProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID CntlWaitDisassocProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void CntlWaitDisassocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID CntlWaitJoinProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void CntlWaitJoinProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID CntlWaitReassocProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void CntlWaitReassocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID CntlWaitStartProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void CntlWaitStartProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID CntlWaitAuthProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void CntlWaitAuthProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID CntlWaitAuthProc2(
-	IN  PRTMP_ADAPTER pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void CntlWaitAuthProc2(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID CntlWaitAssocProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void CntlWaitAssocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID LinkUp(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR BssType);
+void LinkUp(struct rt_rtmp_adapter *pAd, u8 BssType);
 
-VOID LinkDown(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  BOOLEAN         IsReqFromAP);
+void LinkDown(struct rt_rtmp_adapter *pAd, IN BOOLEAN IsReqFromAP);
 
-VOID IterateOnBssTab(
-	IN  PRTMP_ADAPTER   pAd);
+void IterateOnBssTab(struct rt_rtmp_adapter *pAd);
 
-VOID IterateOnBssTab2(
-	IN  PRTMP_ADAPTER   pAd);;
+void IterateOnBssTab2(struct rt_rtmp_adapter *pAd);;
 
-VOID JoinParmFill(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  OUT MLME_JOIN_REQ_STRUCT *JoinReq,
-	IN  ULONG BssIdx);
+void JoinParmFill(struct rt_rtmp_adapter *pAd,
+		  struct rt_mlme_join_req *JoinReq, unsigned long BssIdx);
 
-VOID AssocParmFill(
-	IN  PRTMP_ADAPTER   pAd,
-	IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
-	IN  PUCHAR pAddr,
-	IN  USHORT CapabilityInfo,
-	IN  ULONG Timeout,
-	IN  USHORT ListenIntv);
+void AssocParmFill(struct rt_rtmp_adapter *pAd,
+		   struct rt_mlme_assoc_req *AssocReq,
+		   u8 *pAddr,
+		   u16 CapabilityInfo,
+		   unsigned long Timeout, u16 ListenIntv);
 
-VOID ScanParmFill(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  OUT MLME_SCAN_REQ_STRUCT *ScanReq,
-	IN  CHAR Ssid[],
-	IN  UCHAR SsidLen,
-	IN  UCHAR BssType,
-	IN  UCHAR ScanType);
+void ScanParmFill(struct rt_rtmp_adapter *pAd,
+		  struct rt_mlme_scan_req *ScanReq,
+		  char Ssid[],
+		  u8 SsidLen, u8 BssType, u8 ScanType);
 
-VOID DisassocParmFill(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
-	IN  PUCHAR pAddr,
-	IN  USHORT Reason);
+void DisassocParmFill(struct rt_rtmp_adapter *pAd,
+		      struct rt_mlme_disassoc_req *DisassocReq,
+		      u8 *pAddr, u16 Reason);
 
-VOID StartParmFill(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  OUT MLME_START_REQ_STRUCT *StartReq,
-	IN  CHAR Ssid[],
-	IN  UCHAR SsidLen);
+void StartParmFill(struct rt_rtmp_adapter *pAd,
+		   struct rt_mlme_start_req *StartReq,
+		   char Ssid[], u8 SsidLen);
 
-VOID AuthParmFill(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  OUT MLME_AUTH_REQ_STRUCT *AuthReq,
-	IN  PUCHAR pAddr,
-	IN  USHORT Alg);
+void AuthParmFill(struct rt_rtmp_adapter *pAd,
+		  struct rt_mlme_auth_req *AuthReq,
+		  u8 *pAddr, u16 Alg);
 
-VOID EnqueuePsPoll(
-	IN  PRTMP_ADAPTER   pAd);
+void EnqueuePsPoll(struct rt_rtmp_adapter *pAd);
 
-VOID EnqueueBeaconFrame(
-	IN  PRTMP_ADAPTER   pAd);
+void EnqueueBeaconFrame(struct rt_rtmp_adapter *pAd);
 
-VOID MlmeJoinReqAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void MlmeJoinReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID MlmeScanReqAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void MlmeScanReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID MlmeStartReqAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void MlmeStartReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID ScanTimeoutAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void ScanTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID BeaconTimeoutAtJoinAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void BeaconTimeoutAtJoinAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID PeerBeaconAtScanAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void PeerBeaconAtScanAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID PeerBeaconAtJoinAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void PeerBeaconAtJoinAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID PeerBeacon(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void PeerBeacon(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID PeerProbeReqAction(
-	IN  PRTMP_ADAPTER pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void PeerProbeReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
-VOID ScanNextChannel(
-	IN  PRTMP_ADAPTER   pAd);
+void ScanNextChannel(struct rt_rtmp_adapter *pAd);
 
-ULONG MakeIbssBeacon(
-	IN  PRTMP_ADAPTER   pAd);
+unsigned long MakeIbssBeacon(struct rt_rtmp_adapter *pAd);
 
-VOID CCXAdjacentAPReport(
-	IN  PRTMP_ADAPTER   pAd);
+BOOLEAN MlmeScanReqSanity(struct rt_rtmp_adapter *pAd,
+			  void * Msg,
+			  unsigned long MsgLen,
+			  u8 * BssType,
+			  char ssid[],
+			  u8 * SsidLen, u8 * ScanType);
 
-BOOLEAN MlmeScanReqSanity(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  VOID *Msg,
-	IN  ULONG MsgLen,
-	OUT UCHAR *BssType,
-	OUT CHAR ssid[],
-	OUT UCHAR *SsidLen,
-	OUT UCHAR *ScanType);
+BOOLEAN PeerBeaconAndProbeRspSanity(struct rt_rtmp_adapter *pAd,
+				    void * Msg,
+				    unsigned long MsgLen,
+				    u8 MsgChannel,
+				    u8 *pAddr2,
+				    u8 *pBssid,
+				    char Ssid[],
+				    u8 * pSsidLen,
+				    u8 * pBssType,
+				    u16 * pBeaconPeriod,
+				    u8 * pChannel,
+				    u8 * pNewChannel,
+				    OUT LARGE_INTEGER * pTimestamp,
+				    struct rt_cf_parm * pCfParm,
+				    u16 * pAtimWin,
+				    u16 * pCapabilityInfo,
+				    u8 * pErp,
+				    u8 * pDtimCount,
+				    u8 * pDtimPeriod,
+				    u8 * pBcastFlag,
+				    u8 * pMessageToMe,
+				    u8 SupRate[],
+				    u8 * pSupRateLen,
+				    u8 ExtRate[],
+				    u8 * pExtRateLen,
+				    u8 * pCkipFlag,
+				    u8 * pAironetCellPowerLimit,
+				    struct rt_edca_parm *pEdcaParm,
+				    struct rt_qbss_load_parm *pQbssLoad,
+				    struct rt_qos_capability_parm *pQosCapability,
+				    unsigned long * pRalinkIe,
+				    u8 * pHtCapabilityLen,
+				    u8 * pPreNHtCapabilityLen,
+				    struct rt_ht_capability_ie * pHtCapability,
+				    u8 * AddHtInfoLen,
+				    struct rt_add_ht_info_ie * AddHtInfo,
+				    u8 * NewExtChannel,
+				    u16 * LengthVIE,
+				    struct rt_ndis_802_11_variable_ies *pVIE);
 
-BOOLEAN PeerBeaconAndProbeRspSanity(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  VOID *Msg,
-	IN  ULONG MsgLen,
-	IN  UCHAR MsgChannel,
-	OUT PUCHAR pAddr2,
-	OUT PUCHAR pBssid,
-	OUT CHAR Ssid[],
-	OUT UCHAR *pSsidLen,
-	OUT UCHAR *pBssType,
-	OUT USHORT *pBeaconPeriod,
-	OUT UCHAR *pChannel,
-	OUT UCHAR *pNewChannel,
-	OUT LARGE_INTEGER *pTimestamp,
-	OUT CF_PARM *pCfParm,
-	OUT USHORT *pAtimWin,
-	OUT USHORT *pCapabilityInfo,
-	OUT UCHAR *pErp,
-	OUT UCHAR *pDtimCount,
-	OUT UCHAR *pDtimPeriod,
-	OUT UCHAR *pBcastFlag,
-	OUT UCHAR *pMessageToMe,
-	OUT UCHAR SupRate[],
-	OUT UCHAR *pSupRateLen,
-	OUT UCHAR ExtRate[],
-	OUT UCHAR *pExtRateLen,
-	OUT	UCHAR *pCkipFlag,
-	OUT	UCHAR *pAironetCellPowerLimit,
-	OUT PEDCA_PARM       pEdcaParm,
-	OUT PQBSS_LOAD_PARM  pQbssLoad,
-	OUT PQOS_CAPABILITY_PARM pQosCapability,
-	OUT ULONG *pRalinkIe,
-	OUT UCHAR		 *pHtCapabilityLen,
-	OUT UCHAR		 *pPreNHtCapabilityLen,
-	OUT HT_CAPABILITY_IE *pHtCapability,
-	OUT UCHAR		 *AddHtInfoLen,
-	OUT ADD_HT_INFO_IE *AddHtInfo,
-	OUT UCHAR *NewExtChannel,
-	OUT USHORT *LengthVIE,
-	OUT PNDIS_802_11_VARIABLE_IEs pVIE);
+BOOLEAN PeerAddBAReqActionSanity(struct rt_rtmp_adapter *pAd,
+				 void * pMsg,
+				 unsigned long MsgLen, u8 *pAddr2);
 
-BOOLEAN PeerAddBAReqActionSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *pMsg,
-    IN ULONG MsgLen,
-	OUT PUCHAR pAddr2);
+BOOLEAN PeerAddBARspActionSanity(struct rt_rtmp_adapter *pAd,
+				 void * pMsg, unsigned long MsgLen);
 
-BOOLEAN PeerAddBARspActionSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *pMsg,
-    IN ULONG MsgLen);
+BOOLEAN PeerDelBAActionSanity(struct rt_rtmp_adapter *pAd,
+			      u8 Wcid, void * pMsg, unsigned long MsgLen);
 
-BOOLEAN PeerDelBAActionSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN UCHAR Wcid,
-    IN VOID *pMsg,
-    IN ULONG MsgLen);
+BOOLEAN MlmeAssocReqSanity(struct rt_rtmp_adapter *pAd,
+			   void * Msg,
+			   unsigned long MsgLen,
+			   u8 *pApAddr,
+			   u16 * CapabilityInfo,
+			   unsigned long * Timeout, u16 * ListenIntv);
 
-BOOLEAN MlmeAssocReqSanity(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  VOID *Msg,
-	IN  ULONG MsgLen,
-	OUT PUCHAR pApAddr,
-	OUT USHORT *CapabilityInfo,
-	OUT ULONG *Timeout,
-	OUT USHORT *ListenIntv);
+BOOLEAN MlmeAuthReqSanity(struct rt_rtmp_adapter *pAd,
+			  void * Msg,
+			  unsigned long MsgLen,
+			  u8 *pAddr,
+			  unsigned long * Timeout, u16 * Alg);
 
-BOOLEAN MlmeAuthReqSanity(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  VOID *Msg,
-	IN  ULONG MsgLen,
-	OUT PUCHAR pAddr,
-	OUT ULONG *Timeout,
-	OUT USHORT *Alg);
+BOOLEAN MlmeStartReqSanity(struct rt_rtmp_adapter *pAd,
+			   void * Msg,
+			   unsigned long MsgLen,
+			   char Ssid[], u8 * Ssidlen);
 
-BOOLEAN MlmeStartReqSanity(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  VOID *Msg,
-	IN  ULONG MsgLen,
-	OUT CHAR Ssid[],
-	OUT UCHAR *Ssidlen);
+BOOLEAN PeerAuthSanity(struct rt_rtmp_adapter *pAd,
+		       void * Msg,
+		       unsigned long MsgLen,
+		       u8 *pAddr,
+		       u16 * Alg,
+		       u16 * Seq,
+		       u16 * Status, char ChlgText[]);
 
-BOOLEAN PeerAuthSanity(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  VOID *Msg,
-	IN  ULONG MsgLen,
-	OUT PUCHAR pAddr,
-	OUT USHORT *Alg,
-	OUT USHORT *Seq,
-	OUT USHORT *Status,
-	OUT CHAR ChlgText[]);
+BOOLEAN PeerAssocRspSanity(struct rt_rtmp_adapter *pAd, void * pMsg, unsigned long MsgLen, u8 *pAddr2, u16 * pCapabilityInfo, u16 * pStatus, u16 * pAid, u8 SupRate[], u8 * pSupRateLen, u8 ExtRate[], u8 * pExtRateLen, struct rt_ht_capability_ie * pHtCapability, struct rt_add_ht_info_ie * pAddHtInfo,	/* AP might use this additional ht info IE */
+			   u8 * pHtCapabilityLen,
+			   u8 * pAddHtInfoLen,
+			   u8 * pNewExtChannelOffset,
+			   struct rt_edca_parm *pEdcaParm, u8 * pCkipFlag);
 
-BOOLEAN PeerAssocRspSanity(
-	IN  PRTMP_ADAPTER   pAd,
-    IN VOID *pMsg,
-	IN  ULONG MsgLen,
-	OUT PUCHAR pAddr2,
-	OUT USHORT *pCapabilityInfo,
-	OUT USHORT *pStatus,
-	OUT USHORT *pAid,
-	OUT UCHAR SupRate[],
-	OUT UCHAR *pSupRateLen,
-	OUT UCHAR ExtRate[],
-	OUT UCHAR *pExtRateLen,
-    OUT HT_CAPABILITY_IE		*pHtCapability,
-    OUT ADD_HT_INFO_IE		*pAddHtInfo,	// AP might use this additional ht info IE
-    OUT UCHAR			*pHtCapabilityLen,
-    OUT UCHAR			*pAddHtInfoLen,
-    OUT UCHAR			*pNewExtChannelOffset,
-	OUT PEDCA_PARM pEdcaParm,
-	OUT UCHAR *pCkipFlag);
+BOOLEAN PeerDisassocSanity(struct rt_rtmp_adapter *pAd,
+			   void * Msg,
+			   unsigned long MsgLen,
+			   u8 *pAddr2, u16 * Reason);
 
-BOOLEAN PeerDisassocSanity(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  VOID *Msg,
-	IN  ULONG MsgLen,
-	OUT PUCHAR pAddr2,
-	OUT USHORT *Reason);
+BOOLEAN PeerWpaMessageSanity(struct rt_rtmp_adapter *pAd,
+			     struct rt_eapol_packet * pMsg,
+			     unsigned long MsgLen,
+			     u8 MsgType, struct rt_mac_table_entry *pEntry);
 
-BOOLEAN PeerDeauthSanity(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  VOID *Msg,
-	IN  ULONG MsgLen,
-	OUT PUCHAR pAddr2,
-	OUT USHORT *Reason);
+BOOLEAN PeerDeauthSanity(struct rt_rtmp_adapter *pAd,
+			 void * Msg,
+			 unsigned long MsgLen,
+			 u8 *pAddr2, u16 * Reason);
 
-BOOLEAN PeerProbeReqSanity(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  VOID *Msg,
-	IN  ULONG MsgLen,
-	OUT PUCHAR pAddr2,
-	OUT CHAR Ssid[],
-	OUT UCHAR *pSsidLen);
+BOOLEAN PeerProbeReqSanity(struct rt_rtmp_adapter *pAd,
+			   void * Msg,
+			   unsigned long MsgLen,
+			   u8 *pAddr2,
+			   char Ssid[], u8 * pSsidLen);
 
-BOOLEAN GetTimBit(
-	IN  CHAR *Ptr,
-	IN  USHORT Aid,
-	OUT UCHAR *TimLen,
-	OUT UCHAR *BcastFlag,
-	OUT UCHAR *DtimCount,
-	OUT UCHAR *DtimPeriod,
-	OUT UCHAR *MessageToMe);
+BOOLEAN GetTimBit(char * Ptr,
+		  u16 Aid,
+		  u8 * TimLen,
+		  u8 * BcastFlag,
+		  u8 * DtimCount,
+		  u8 * DtimPeriod, u8 * MessageToMe);
 
-UCHAR ChannelSanity(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR channel);
+u8 ChannelSanity(struct rt_rtmp_adapter *pAd, u8 channel);
 
-NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(
-	IN PBSS_ENTRY pBss);
+NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(struct rt_bss_entry *pBss);
 
-BOOLEAN MlmeDelBAReqSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen);
+BOOLEAN MlmeDelBAReqSanity(struct rt_rtmp_adapter *pAd,
+			   void * Msg, unsigned long MsgLen);
 
-BOOLEAN MlmeAddBAReqSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pAddr2);
+BOOLEAN MlmeAddBAReqSanity(struct rt_rtmp_adapter *pAd,
+			   void * Msg, unsigned long MsgLen, u8 *pAddr2);
 
-ULONG MakeOutgoingFrame(
-	OUT CHAR *Buffer,
-	OUT ULONG *Length, ...);
+unsigned long MakeOutgoingFrame(u8 * Buffer, unsigned long * Length, ...);
 
-VOID  LfsrInit(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  ULONG Seed);
+void LfsrInit(struct rt_rtmp_adapter *pAd, unsigned long Seed);
 
-UCHAR RandomByte(
-	IN  PRTMP_ADAPTER   pAd);
+u8 RandomByte(struct rt_rtmp_adapter *pAd);
 
-VOID AsicUpdateAutoFallBackTable(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pTxRate);
+void AsicUpdateAutoFallBackTable(struct rt_rtmp_adapter *pAd, u8 *pTxRate);
 
-VOID  MlmePeriodicExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
+void MlmePeriodicExec(void *SystemSpecific1,
+		      void *FunctionContext,
+		      void *SystemSpecific2, void *SystemSpecific3);
 
-VOID LinkDownExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
+void LinkDownExec(void *SystemSpecific1,
+		  void *FunctionContext,
+		  void *SystemSpecific2, void *SystemSpecific3);
 
-VOID STAMlmePeriodicExec(
-	PRTMP_ADAPTER pAd);
+void STAMlmePeriodicExec(struct rt_rtmp_adapter *pAd);
 
-VOID MlmeAutoScan(
-	IN PRTMP_ADAPTER pAd);
+void MlmeAutoScan(struct rt_rtmp_adapter *pAd);
 
-VOID MlmeAutoReconnectLastSSID(
-	IN PRTMP_ADAPTER pAd);
+void MlmeAutoReconnectLastSSID(struct rt_rtmp_adapter *pAd);
 
-BOOLEAN MlmeValidateSSID(
-	IN PUCHAR pSsid,
-	IN UCHAR  SsidLen);
+BOOLEAN MlmeValidateSSID(u8 *pSsid, u8 SsidLen);
 
-VOID MlmeCheckForRoaming(
-	IN PRTMP_ADAPTER pAd,
-	IN ULONG    Now32);
+void MlmeCheckForRoaming(struct rt_rtmp_adapter *pAd, unsigned long Now32);
 
-VOID MlmeCheckForFastRoaming(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  ULONG           Now);
+BOOLEAN MlmeCheckForFastRoaming(struct rt_rtmp_adapter *pAd);
 
-VOID MlmeDynamicTxRateSwitching(
-	IN PRTMP_ADAPTER pAd);
+void MlmeDynamicTxRateSwitching(struct rt_rtmp_adapter *pAd);
 
-VOID MlmeSetTxRate(
-	IN PRTMP_ADAPTER		pAd,
-	IN PMAC_TABLE_ENTRY		pEntry,
-	IN PRTMP_TX_RATE_SWITCH	pTxRate);
+void MlmeSetTxRate(struct rt_rtmp_adapter *pAd,
+		   struct rt_mac_table_entry *pEntry, struct rt_rtmp_tx_rate_switch * pTxRate);
 
-VOID MlmeSelectTxRateTable(
-	IN PRTMP_ADAPTER		pAd,
-	IN PMAC_TABLE_ENTRY		pEntry,
-	IN PUCHAR				*ppTable,
-	IN PUCHAR				pTableSize,
-	IN PUCHAR				pInitTxRateIdx);
+void MlmeSelectTxRateTable(struct rt_rtmp_adapter *pAd,
+			   struct rt_mac_table_entry *pEntry,
+			   u8 ** ppTable,
+			   u8 *pTableSize, u8 *pInitTxRateIdx);
 
-VOID MlmeCalculateChannelQuality(
-	IN PRTMP_ADAPTER pAd,
-	IN ULONG Now);
+void MlmeCalculateChannelQuality(struct rt_rtmp_adapter *pAd,
+				 struct rt_mac_table_entry *pMacEntry, unsigned long Now);
 
-VOID MlmeCheckPsmChange(
-	IN PRTMP_ADAPTER pAd,
-	IN ULONG    Now32);
+void MlmeCheckPsmChange(struct rt_rtmp_adapter *pAd, unsigned long Now32);
 
-VOID MlmeSetPsmBit(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT psm);
+void MlmeSetPsmBit(struct rt_rtmp_adapter *pAd, u16 psm);
 
-VOID MlmeSetTxPreamble(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT TxPreamble);
+void MlmeSetTxPreamble(struct rt_rtmp_adapter *pAd, u16 TxPreamble);
 
-VOID UpdateBasicRateBitmap(
-	IN	PRTMP_ADAPTER	pAd);
+void UpdateBasicRateBitmap(struct rt_rtmp_adapter *pAd);
 
-VOID MlmeUpdateTxRates(
-	IN PRTMP_ADAPTER 	pAd,
-	IN 	BOOLEAN		 	bLinkUp,
-	IN	UCHAR			apidx);
+void MlmeUpdateTxRates(struct rt_rtmp_adapter *pAd,
+		       IN BOOLEAN bLinkUp, u8 apidx);
 
-VOID MlmeUpdateHtTxRates(
-	IN PRTMP_ADAPTER 		pAd,
-	IN	UCHAR				apidx);
+void MlmeUpdateHtTxRates(struct rt_rtmp_adapter *pAd, u8 apidx);
 
-VOID    RTMPCheckRates(
-	IN      PRTMP_ADAPTER   pAd,
-	IN OUT  UCHAR           SupRate[],
-	IN OUT  UCHAR           *SupRateLen);
+void RTMPCheckRates(struct rt_rtmp_adapter *pAd,
+		    IN u8 SupRate[], IN u8 * SupRateLen);
 
-BOOLEAN RTMPCheckChannel(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR		CentralChannel,
-	IN UCHAR		Channel);
+BOOLEAN RTMPCheckChannel(struct rt_rtmp_adapter *pAd,
+			 u8 CentralChannel, u8 Channel);
 
-BOOLEAN 	RTMPCheckHt(
-	IN		PRTMP_ADAPTER	pAd,
-	IN		UCHAR	Wcid,
-	IN OUT	HT_CAPABILITY_IE			*pHtCapability,
-	IN OUT	ADD_HT_INFO_IE			*pAddHtInfo);
+BOOLEAN RTMPCheckHt(struct rt_rtmp_adapter *pAd,
+		    u8 Wcid,
+		    struct rt_ht_capability_ie * pHtCapability,
+		    struct rt_add_ht_info_ie * pAddHtInfo);
 
-VOID StaQuickResponeForRateUpExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
+void StaQuickResponeForRateUpExec(void *SystemSpecific1,
+				  void *FunctionContext,
+				  void *SystemSpecific2,
+				  void *SystemSpecific3);
 
-VOID RTMPUpdateMlmeRate(
-	IN PRTMP_ADAPTER	pAd);
+void RTMPUpdateMlmeRate(struct rt_rtmp_adapter *pAd);
 
-CHAR RTMPMaxRssi(
-	IN PRTMP_ADAPTER	pAd,
-	IN CHAR				Rssi0,
-	IN CHAR				Rssi1,
-	IN CHAR				Rssi2);
+char RTMPMaxRssi(struct rt_rtmp_adapter *pAd,
+		 char Rssi0, char Rssi1, char Rssi2);
 
-VOID AsicSetRxAnt(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			Ant);
+#ifdef RT30xx
+void AsicSetRxAnt(struct rt_rtmp_adapter *pAd, u8 Ant);
 
-VOID AsicEvaluateRxAnt(
-	IN PRTMP_ADAPTER	pAd);
+void RTMPFilterCalibration(struct rt_rtmp_adapter *pAd);
 
-VOID AsicRxAntEvalTimeout(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
+#ifdef RTMP_EFUSE_SUPPORT
+/*2008/09/11:KH add to support efuse<-- */
+int set_eFuseGetFreeBlockCount_Proc(struct rt_rtmp_adapter *pAd, char *arg);
 
-VOID APSDPeriodicExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
+int set_eFusedump_Proc(struct rt_rtmp_adapter *pAd, char *arg);
 
-BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(
-	IN PRTMP_ADAPTER    pAd,
-	IN PMAC_TABLE_ENTRY	pEntry);
+void eFusePhysicalReadRegisters(struct rt_rtmp_adapter *pAd,
+				u16 Offset,
+				u16 Length, u16 * pData);
 
-UCHAR RTMPStaFixedTxMode(
-	IN PRTMP_ADAPTER    pAd,
-	IN PMAC_TABLE_ENTRY	pEntry);
+int RtmpEfuseSupportCheck(struct rt_rtmp_adapter *pAd);
 
-VOID RTMPUpdateLegacyTxSetting(
-		UCHAR				fixed_tx_mode,
-		PMAC_TABLE_ENTRY	pEntry);
+void eFuseGetFreeBlockCount(struct rt_rtmp_adapter *pAd, u32 *EfuseFreeBlock);
 
-BOOLEAN RTMPAutoRateSwitchCheck(
-	IN PRTMP_ADAPTER    pAd);
+int eFuse_init(struct rt_rtmp_adapter *pAd);
+/*2008/09/11:KH add to support efuse--> */
+#endif /* RTMP_EFUSE_SUPPORT // */
 
-NDIS_STATUS MlmeInit(
-	IN  PRTMP_ADAPTER   pAd);
+/* add by johnli, RF power sequence setup */
+void RT30xxLoadRFNormalModeSetup(struct rt_rtmp_adapter *pAd);
 
-VOID MlmeHandler(
-	IN  PRTMP_ADAPTER   pAd);
+void RT30xxLoadRFSleepModeSetup(struct rt_rtmp_adapter *pAd);
 
-VOID MlmeHalt(
-	IN  PRTMP_ADAPTER   pAd);
+void RT30xxReverseRFSleepModeSetup(struct rt_rtmp_adapter *pAd);
+/* end johnli */
 
-VOID MlmeResetRalinkCounters(
-	IN  PRTMP_ADAPTER   pAd);
+#ifdef RT3070
+void NICInitRT3070RFRegisters(struct rt_rtmp_adapter *pAd);
+#endif /* RT3070 // */
+#ifdef RT3090
+void NICInitRT3090RFRegisters(struct rt_rtmp_adapter *pAd);
+#endif /* RT3090 // */
 
-VOID BuildChannelList(
-	IN PRTMP_ADAPTER pAd);
+void RT30xxHaltAction(struct rt_rtmp_adapter *pAd);
 
-UCHAR FirstChannel(
-	IN  PRTMP_ADAPTER   pAd);
+void RT30xxSetRxAnt(struct rt_rtmp_adapter *pAd, u8 Ant);
+#endif /* RT30xx // */
 
-UCHAR NextChannel(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR channel);
+void AsicEvaluateRxAnt(struct rt_rtmp_adapter *pAd);
 
-VOID ChangeToCellPowerLimit(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR         AironetCellPowerLimit);
+void AsicRxAntEvalTimeout(void *SystemSpecific1,
+			  void *FunctionContext,
+			  void *SystemSpecific2, void *SystemSpecific3);
 
-USHORT RTMP_EEPROM_READ16(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  USHORT Offset);
+void APSDPeriodicExec(void *SystemSpecific1,
+		      void *FunctionContext,
+		      void *SystemSpecific2, void *SystemSpecific3);
 
-VOID RTMP_EEPROM_WRITE16(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  USHORT Offset,
-	IN  USHORT Data);
+BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(struct rt_rtmp_adapter *pAd,
+					   struct rt_mac_table_entry *pEntry);
 
-//
-// Prototypes of function definition in rtmp_tkip.c
-//
-VOID    RTMPInitTkipEngine(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pTKey,
-	IN  UCHAR           KeyId,
-	IN  PUCHAR          pTA,
-	IN  PUCHAR          pMICKey,
-	IN  PUCHAR          pTSC,
-	OUT PULONG          pIV16,
-	OUT PULONG          pIV32);
+u8 RTMPStaFixedTxMode(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry);
 
-VOID    RTMPInitMICEngine(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pKey,
-	IN  PUCHAR          pDA,
-	IN  PUCHAR          pSA,
-	IN  UCHAR           UserPriority,
-	IN  PUCHAR          pMICKey);
+void RTMPUpdateLegacyTxSetting(u8 fixed_tx_mode, struct rt_mac_table_entry *pEntry);
 
-BOOLEAN RTMPTkipCompareMICValue(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pSrc,
-	IN  PUCHAR          pDA,
-	IN  PUCHAR          pSA,
-	IN  PUCHAR          pMICKey,
-	IN	UCHAR			UserPriority,
-	IN  UINT            Len);
+BOOLEAN RTMPAutoRateSwitchCheck(struct rt_rtmp_adapter *pAd);
 
-VOID    RTMPCalculateMICValue(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PNDIS_PACKET    pPacket,
-	IN  PUCHAR          pEncap,
-	IN  PCIPHER_KEY     pKey,
-	IN	UCHAR			apidx);
+int MlmeInit(struct rt_rtmp_adapter *pAd);
 
-BOOLEAN RTMPTkipCompareMICValueWithLLC(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pLLC,
-	IN  PUCHAR          pSrc,
-	IN  PUCHAR          pDA,
-	IN  PUCHAR          pSA,
-	IN  PUCHAR          pMICKey,
-	IN  UINT            Len);
+void MlmeHandler(struct rt_rtmp_adapter *pAd);
 
-VOID    RTMPTkipAppendByte(
-	IN  PTKIP_KEY_INFO  pTkip,
-	IN  UCHAR           uChar);
+void MlmeHalt(struct rt_rtmp_adapter *pAd);
 
-VOID    RTMPTkipAppend(
-	IN  PTKIP_KEY_INFO  pTkip,
-	IN  PUCHAR          pSrc,
-	IN  UINT            nBytes);
+void MlmeResetRalinkCounters(struct rt_rtmp_adapter *pAd);
 
-VOID    RTMPTkipGetMIC(
-	IN  PTKIP_KEY_INFO  pTkip);
+void BuildChannelList(struct rt_rtmp_adapter *pAd);
 
-BOOLEAN RTMPSoftDecryptTKIP(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR	pData,
-	IN ULONG	DataByteCnt,
-	IN UCHAR    UserPriority,
-	IN PCIPHER_KEY	pWpaKey);
+u8 FirstChannel(struct rt_rtmp_adapter *pAd);
 
-BOOLEAN RTMPSoftDecryptAES(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR	pData,
-	IN ULONG	DataByteCnt,
-	IN PCIPHER_KEY	pWpaKey);
+u8 NextChannel(struct rt_rtmp_adapter *pAd, u8 channel);
 
-//
-// Prototypes of function definition in cmm_info.c
-//
-NDIS_STATUS RTMPWPARemoveKeyProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PVOID           pBuf);
+void ChangeToCellPowerLimit(struct rt_rtmp_adapter *pAd,
+			    u8 AironetCellPowerLimit);
 
-VOID    RTMPWPARemoveAllKeys(
-	IN  PRTMP_ADAPTER   pAd);
+/* */
+/* Prototypes of function definition in rtmp_tkip.c */
+/* */
+void RTMPInitTkipEngine(struct rt_rtmp_adapter *pAd,
+			u8 *pTKey,
+			u8 KeyId,
+			u8 *pTA,
+			u8 *pMICKey,
+			u8 *pTSC, unsigned long *pIV16, unsigned long *pIV32);
 
-BOOLEAN RTMPCheckStrPrintAble(
-    IN  CHAR *pInPutStr,
-    IN  UCHAR strLen);
+void RTMPInitMICEngine(struct rt_rtmp_adapter *pAd,
+		       u8 *pKey,
+		       u8 *pDA,
+		       u8 *pSA, u8 UserPriority, u8 *pMICKey);
 
-VOID    RTMPSetPhyMode(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  ULONG phymode);
+BOOLEAN RTMPTkipCompareMICValue(struct rt_rtmp_adapter *pAd,
+				u8 *pSrc,
+				u8 *pDA,
+				u8 *pSA,
+				u8 *pMICKey,
+				u8 UserPriority, u32 Len);
 
-VOID	RTMPUpdateHTIE(
-	IN	RT_HT_CAPABILITY	*pRtHt,
-	IN		UCHAR				*pMcsSet,
-	OUT		HT_CAPABILITY_IE *pHtCapability,
-	OUT		ADD_HT_INFO_IE		*pAddHtInfo);
+void RTMPCalculateMICValue(struct rt_rtmp_adapter *pAd,
+			   void *pPacket,
+			   u8 *pEncap,
+			   struct rt_cipher_key *pKey, u8 apidx);
 
-VOID	RTMPAddWcidAttributeEntry(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			BssIdx,
-	IN 	UCHAR		 	KeyIdx,
-	IN 	UCHAR		 	CipherAlg,
-	IN 	MAC_TABLE_ENTRY *pEntry);
+void RTMPTkipAppendByte(struct rt_tkip_key_info *pTkip, u8 uChar);
 
-CHAR *GetEncryptType(
-	CHAR enc);
+void RTMPTkipAppend(struct rt_tkip_key_info *pTkip, u8 *pSrc, u32 nBytes);
 
-CHAR *GetAuthMode(
-	CHAR auth);
+void RTMPTkipGetMIC(struct rt_tkip_key_info *pTkip);
 
-VOID RTMPIoctlGetSiteSurvey(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq);
+BOOLEAN RTMPSoftDecryptTKIP(struct rt_rtmp_adapter *pAd,
+			    u8 *pData,
+			    unsigned long DataByteCnt,
+			    u8 UserPriority, struct rt_cipher_key *pWpaKey);
 
-VOID RTMPIoctlGetMacTable(
-	IN PRTMP_ADAPTER pAd,
-	IN struct iwreq *wrq);
+BOOLEAN RTMPSoftDecryptAES(struct rt_rtmp_adapter *pAd,
+			   u8 *pData,
+			   unsigned long DataByteCnt, struct rt_cipher_key *pWpaKey);
 
-VOID    RTMPAddBSSIDCipher(
-    IN  PRTMP_ADAPTER   pAd,
-	IN	UCHAR	Aid,
-    IN  PNDIS_802_11_KEY    pKey,
-    IN  UCHAR   CipherAlg);
+/* */
+/* Prototypes of function definition in cmm_info.c */
+/* */
+int RT_CfgSetCountryRegion(struct rt_rtmp_adapter *pAd, char *arg, int band);
 
-VOID	RTMPSetHT(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	OID_SET_HT_PHYMODE *pHTPhyMode);
+int RT_CfgSetWirelessMode(struct rt_rtmp_adapter *pAd, char *arg);
 
-VOID	RTMPSetIndividualHT(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	UCHAR				apidx);
+int RT_CfgSetShortSlot(struct rt_rtmp_adapter *pAd, char *arg);
 
-VOID RTMPSendWirelessEvent(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Event_flag,
-	IN	PUCHAR 			pAddr,
-	IN  UCHAR			BssIdx,
-	IN	CHAR			Rssi);
+int RT_CfgSetWepKey(struct rt_rtmp_adapter *pAd,
+		    char *keyString,
+		    struct rt_cipher_key *pSharedKey, int keyIdx);
 
-//
-// prototype in wpa.c
-//
-BOOLEAN WpaMsgTypeSubst(
-	IN  UCHAR   EAPType,
-	OUT INT		*MsgType);
+int RT_CfgSetWPAPSKKey(struct rt_rtmp_adapter *pAd,
+		       char *keyString,
+		       u8 * pHashStr,
+		       int hashStrLen, u8 *pPMKBuf);
 
-VOID WpaPskStateMachineInit(
-	IN  PRTMP_ADAPTER       pAd,
-	IN  STATE_MACHINE       *S,
-	OUT STATE_MACHINE_FUNC Trans[]);
+/* */
+/* Prototypes of function definition in cmm_info.c */
+/* */
+void RTMPWPARemoveAllKeys(struct rt_rtmp_adapter *pAd);
 
-VOID WpaEAPOLKeyAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void RTMPSetPhyMode(struct rt_rtmp_adapter *pAd, unsigned long phymode);
 
-VOID    WpaPairMsg1Action(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void RTMPUpdateHTIE(struct rt_ht_capability *pRtHt,
+		    u8 * pMcsSet,
+		    struct rt_ht_capability_ie * pHtCapability,
+		    struct rt_add_ht_info_ie * pAddHtInfo);
 
-VOID    WpaPairMsg3Action(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void RTMPAddWcidAttributeEntry(struct rt_rtmp_adapter *pAd,
+			       u8 BssIdx,
+			       u8 KeyIdx,
+			       u8 CipherAlg, struct rt_mac_table_entry *pEntry);
 
-VOID    WpaGroupMsg1Action(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+char *GetEncryptType(char enc);
 
-VOID    WpaMacHeaderInit(
-	IN      PRTMP_ADAPTER   pAd,
-	IN OUT  PHEADER_802_11  pHdr80211,
-	IN      UCHAR           wep,
-	IN      PUCHAR          pAddr1);
+char *GetAuthMode(char auth);
 
-VOID    Wpa2PairMsg1Action(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  MLME_QUEUE_ELEM *Elem);
+void RTMPSetHT(struct rt_rtmp_adapter *pAd, struct rt_oid_set_ht_phymode *pHTPhyMode);
 
-VOID    Wpa2PairMsg3Action(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  MLME_QUEUE_ELEM *Elem);
+void RTMPSetIndividualHT(struct rt_rtmp_adapter *pAd, u8 apidx);
 
-BOOLEAN ParseKeyData(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PUCHAR          pKeyData,
-    IN  UCHAR           KeyDataLen,
-	IN	UCHAR			bPairewise);
+void RTMPSendWirelessEvent(struct rt_rtmp_adapter *pAd,
+			   u16 Event_flag,
+			   u8 *pAddr, u8 BssIdx, char Rssi);
 
-VOID    RTMPToWirelessSta(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pHeader802_3,
-    IN  UINT            HdrLen,
-	IN  PUCHAR          pData,
-    IN  UINT            DataLen,
-    IN	BOOLEAN			is4wayFrame);
+char ConvertToRssi(struct rt_rtmp_adapter *pAd, char Rssi, u8 RssiNumber);
 
-VOID    HMAC_SHA1(
-	IN  UCHAR   *text,
-	IN  UINT    text_len,
-	IN  UCHAR   *key,
-	IN  UINT    key_len,
-	IN  UCHAR   *digest);
+/*===================================
+	Function prototype in cmm_wpa.c
+  =================================== */
+void RTMPToWirelessSta(struct rt_rtmp_adapter *pAd,
+		       struct rt_mac_table_entry *pEntry,
+		       u8 *pHeader802_3,
+		       u32 HdrLen,
+		       u8 *pData,
+		       u32 DataLen, IN BOOLEAN bClearFrame);
 
-VOID    PRF(
-	IN  UCHAR   *key,
-	IN  INT     key_len,
-	IN  UCHAR   *prefix,
-	IN  INT     prefix_len,
-	IN  UCHAR   *data,
-	IN  INT     data_len,
-	OUT UCHAR   *output,
-	IN  INT     len);
+void WpaDerivePTK(struct rt_rtmp_adapter *pAd,
+		  u8 * PMK,
+		  u8 * ANonce,
+		  u8 * AA,
+		  u8 * SNonce,
+		  u8 * SA, u8 * output, u32 len);
 
-VOID    CCKMPRF(
-	IN  UCHAR   *key,
-	IN  INT     key_len,
-	IN  UCHAR   *data,
-	IN  INT     data_len,
-	OUT UCHAR   *output,
-	IN  INT     len);
+void GenRandom(struct rt_rtmp_adapter *pAd, u8 * macAddr, u8 * random);
 
-VOID WpaCountPTK(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR   *PMK,
-	IN  UCHAR   *ANonce,
-	IN  UCHAR   *AA,
-	IN  UCHAR   *SNonce,
-	IN  UCHAR   *SA,
-	OUT UCHAR   *output,
-	IN  UINT    len);
+BOOLEAN RTMPCheckWPAframe(struct rt_rtmp_adapter *pAd,
+			  struct rt_mac_table_entry *pEntry,
+			  u8 *pData,
+			  unsigned long DataByteCount, u8 FromWhichBSSID);
 
-VOID    GenRandom(
-	IN  PRTMP_ADAPTER   pAd,
-	IN	UCHAR			*macAddr,
-	OUT	UCHAR			*random);
+void AES_GTK_KEY_UNWRAP(u8 * key,
+			u8 * plaintext,
+			u32 c_len, u8 * ciphertext);
 
-//
-// prototype in aironet.c
-//
-VOID    AironetStateMachineInit(
-	IN  PRTMP_ADAPTER       pAd,
-	IN  STATE_MACHINE       *S,
-	OUT STATE_MACHINE_FUNC  Trans[]);
+BOOLEAN RTMPParseEapolKeyData(struct rt_rtmp_adapter *pAd,
+			      u8 *pKeyData,
+			      u8 KeyDataLen,
+			      u8 GroupKeyIndex,
+			      u8 MsgType,
+			      IN BOOLEAN bWPA2, struct rt_mac_table_entry *pEntry);
 
-VOID    AironetMsgAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+void ConstructEapolMsg(struct rt_mac_table_entry *pEntry,
+		       u8 GroupKeyWepStatus,
+		       u8 MsgType,
+		       u8 DefaultKeyIdx,
+		       u8 * KeyNonce,
+		       u8 * TxRSC,
+		       u8 * GTK,
+		       u8 * RSNIE,
+		       u8 RSNIE_Len, struct rt_eapol_packet * pMsg);
 
-VOID    AironetRequestAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+int RTMPSoftDecryptBroadCastData(struct rt_rtmp_adapter *pAd,
+					 struct rt_rx_blk *pRxBlk,
+					 IN NDIS_802_11_ENCRYPTION_STATUS
+					 GroupCipher,
+					 struct rt_cipher_key *pShard_key);
 
-VOID    ChannelLoadRequestAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR           Index);
+void RTMPMakeRSNIE(struct rt_rtmp_adapter *pAd,
+		   u32 AuthMode, u32 WepStatus, u8 apidx);
 
-VOID    NoiseHistRequestAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR           Index);
+/* */
+/* function prototype in ap_wpa.c */
+/* */
+void RTMPGetTxTscFromAsic(struct rt_rtmp_adapter *pAd,
+			  u8 apidx, u8 *pTxTsc);
 
-VOID    BeaconRequestAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR           Index);
+void APInstallPairwiseKey(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry);
 
-VOID    AironetReportAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
+u32 APValidateRSNIE(struct rt_rtmp_adapter *pAd,
+		     struct rt_mac_table_entry *pEntry,
+		     u8 *pRsnIe, u8 rsnie_len);
 
-VOID    ChannelLoadReportAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR           Index);
+void HandleCounterMeasure(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry);
 
-VOID    NoiseHistReportAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR           Index);
+void WPAStart4WayHS(struct rt_rtmp_adapter *pAd,
+		    struct rt_mac_table_entry *pEntry, unsigned long TimeInterval);
 
-VOID    AironetFinalReportAction(
-	IN  PRTMP_ADAPTER   pAd);
+void WPAStart2WayGroupHS(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry);
 
-VOID    BeaconReportAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR           Index);
+void PeerPairMsg1Action(struct rt_rtmp_adapter *pAd,
+			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem);
 
-VOID    AironetAddBeaconReport(
-	IN  PRTMP_ADAPTER       pAd,
-	IN  ULONG               Index,
-	IN  PMLME_QUEUE_ELEM    pElem);
+void PeerPairMsg2Action(struct rt_rtmp_adapter *pAd,
+			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem);
 
-VOID    AironetCreateBeaconReportFromBssTable(
-	IN  PRTMP_ADAPTER       pAd);
+void PeerPairMsg3Action(struct rt_rtmp_adapter *pAd,
+			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem);
 
-CHAR    ConvertToRssi(
-	IN PRTMP_ADAPTER  pAd,
-	IN CHAR				Rssi,
-	IN UCHAR    RssiNumber);
+void PeerPairMsg4Action(struct rt_rtmp_adapter *pAd,
+			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem);
 
-//
-// function prototype in cmm_wpa.c
-//
-BOOLEAN RTMPCheckWPAframe(
-	IN PRTMP_ADAPTER pAd,
-	IN PMAC_TABLE_ENTRY	pEntry,
-	IN PUCHAR 			pData,
-	IN ULONG 			DataByteCount,
-	IN UCHAR			FromWhichBSSID);
+void PeerGroupMsg1Action(struct rt_rtmp_adapter *pAd,
+			 struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem);
 
-VOID AES_GTK_KEY_UNWRAP(
-	IN  UCHAR   *key,
-	OUT UCHAR   *plaintext,
-	IN	UCHAR	c_len,
-	IN  UCHAR   *ciphertext);
+void PeerGroupMsg2Action(struct rt_rtmp_adapter *pAd,
+			 struct rt_mac_table_entry *pEntry,
+			 void * Msg, u32 MsgLen);
 
-VOID RTMPMakeRSNIE(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UINT            AuthMode,
-	IN  UINT            WepStatus,
-	IN	UCHAR			apidx);
+void WpaDeriveGTK(u8 * PMK,
+		  u8 * GNonce,
+		  u8 * AA, u8 * output, u32 len);
 
-//
-// function prototype in ap_wpa.c
-//
+void AES_GTK_KEY_WRAP(u8 * key,
+		      u8 * plaintext,
+		      u32 p_len, u8 * ciphertext);
 
-VOID HandleCounterMeasure(
-	IN PRTMP_ADAPTER pAd,
-	IN MAC_TABLE_ENTRY  *pEntry);
+/*typedef void (*TIMER_FUNCTION)(unsigned long); */
 
 /* timeout -- ms */
-VOID RTMP_SetPeriodicTimer(
-	IN	NDIS_MINIPORT_TIMER *pTimer,
-	IN	unsigned long timeout);
+void RTMP_SetPeriodicTimer(struct timer_list * pTimer,
+			   IN unsigned long timeout);
 
-VOID RTMP_OS_Init_Timer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	NDIS_MINIPORT_TIMER *pTimer,
-	IN	TIMER_FUNCTION function,
-	IN	PVOID data);
+void RTMP_OS_Init_Timer(struct rt_rtmp_adapter *pAd,
+			struct timer_list * pTimer,
+			IN TIMER_FUNCTION function, void *data);
 
-VOID RTMP_OS_Add_Timer(
-	IN	NDIS_MINIPORT_TIMER	*pTimer,
-	IN	unsigned long timeout);
+void RTMP_OS_Add_Timer(struct timer_list * pTimer,
+		       IN unsigned long timeout);
 
-VOID RTMP_OS_Mod_Timer(
-	IN	NDIS_MINIPORT_TIMER	*pTimer,
-	IN	unsigned long timeout);
+void RTMP_OS_Mod_Timer(struct timer_list * pTimer,
+		       IN unsigned long timeout);
 
+void RTMP_OS_Del_Timer(struct timer_list * pTimer,
+		       OUT BOOLEAN * pCancelled);
 
-VOID RTMP_OS_Del_Timer(
-	IN	NDIS_MINIPORT_TIMER	*pTimer,
-	OUT	BOOLEAN				 *pCancelled);
+void RTMP_OS_Release_Packet(struct rt_rtmp_adapter *pAd, struct rt_queue_entry *pEntry);
 
+void RTMPusecDelay(unsigned long usec);
 
-VOID RTMP_OS_Release_Packet(
-	IN	PRTMP_ADAPTER pAd,
-	IN	PQUEUE_ENTRY  pEntry);
+int os_alloc_mem(struct rt_rtmp_adapter *pAd,
+			 u8 ** mem, unsigned long size);
 
-VOID RTMPusecDelay(
-	IN	ULONG	usec);
+int os_free_mem(struct rt_rtmp_adapter *pAd, void *mem);
 
-NDIS_STATUS os_alloc_mem(
-	IN	PRTMP_ADAPTER pAd,
-	OUT	PUCHAR *mem,
-	IN	ULONG  size);
+void RTMP_AllocateSharedMemory(struct rt_rtmp_adapter *pAd,
+			       unsigned long Length,
+			       IN BOOLEAN Cached,
+			       void ** VirtualAddress,
+			       dma_addr_t *PhysicalAddress);
 
-NDIS_STATUS os_free_mem(
-	IN	PRTMP_ADAPTER pAd,
-	IN	PUCHAR mem);
+void RTMPFreeTxRxRingMemory(struct rt_rtmp_adapter *pAd);
 
+int AdapterBlockAllocateMemory(void *handle, void ** ppAd);
 
-void RTMP_AllocateSharedMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+void RTMP_AllocateTxDescMemory(struct rt_rtmp_adapter *pAd,
+			       u32 Index,
+			       unsigned long Length,
+			       IN BOOLEAN Cached,
+			       void ** VirtualAddress,
+			       dma_addr_t *PhysicalAddress);
 
-VOID RTMPFreeTxRxRingMemory(
-    IN  PRTMP_ADAPTER   pAd);
+void RTMP_AllocateFirstTxBuffer(struct rt_rtmp_adapter *pAd,
+				u32 Index,
+				unsigned long Length,
+				IN BOOLEAN Cached,
+				void ** VirtualAddress,
+				dma_addr_t *PhysicalAddress);
 
-NDIS_STATUS AdapterBlockAllocateMemory(
-	IN PVOID	handle,
-	OUT	PVOID	*ppAd);
+void RTMP_FreeFirstTxBuffer(struct rt_rtmp_adapter *pAd,
+			    unsigned long Length,
+			    IN BOOLEAN Cached,
+			    void *VirtualAddress,
+			    dma_addr_t PhysicalAddress);
 
-void RTMP_AllocateTxDescMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	UINT	Index,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+void RTMP_AllocateMgmtDescMemory(struct rt_rtmp_adapter *pAd,
+				 unsigned long Length,
+				 IN BOOLEAN Cached,
+				 void ** VirtualAddress,
+				 dma_addr_t *PhysicalAddress);
 
-void RTMP_AllocateFirstTxBuffer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	UINT	Index,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+void RTMP_AllocateRxDescMemory(struct rt_rtmp_adapter *pAd,
+			       unsigned long Length,
+			       IN BOOLEAN Cached,
+			       void ** VirtualAddress,
+			       dma_addr_t *PhysicalAddress);
 
-void RTMP_AllocateMgmtDescMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+void RTMP_FreeDescMemory(struct rt_rtmp_adapter *pAd,
+			 unsigned long Length,
+			 void *VirtualAddress,
+			 dma_addr_t PhysicalAddress);
 
-void RTMP_AllocateRxDescMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+void *RtmpOSNetPktAlloc(struct rt_rtmp_adapter *pAd, IN int size);
 
-PNDIS_PACKET RTMP_AllocateRxPacketBuffer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+void *RTMP_AllocateRxPacketBuffer(struct rt_rtmp_adapter *pAd,
+					 unsigned long Length,
+					 IN BOOLEAN Cached,
+					 void ** VirtualAddress,
+					 OUT dma_addr_t *
+					 PhysicalAddress);
 
-PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress);
+void *RTMP_AllocateTxPacketBuffer(struct rt_rtmp_adapter *pAd,
+					 unsigned long Length,
+					 IN BOOLEAN Cached,
+					 void ** VirtualAddress);
 
-PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length);
+void *RTMP_AllocateFragPacketBuffer(struct rt_rtmp_adapter *pAd,
+					   unsigned long Length);
 
-void RTMP_QueryPacketInfo(
-	IN  PNDIS_PACKET pPacket,
-	OUT PACKET_INFO  *pPacketInfo,
-	OUT PUCHAR		 *pSrcBufVA,
-	OUT	UINT		 *pSrcBufLen);
+void RTMP_QueryPacketInfo(void *pPacket,
+			  struct rt_packet_info *pPacketInfo,
+			  u8 ** pSrcBufVA, u32 * pSrcBufLen);
 
-void RTMP_QueryNextPacketInfo(
-	IN  PNDIS_PACKET *ppPacket,
-	OUT PACKET_INFO  *pPacketInfo,
-	OUT PUCHAR		 *pSrcBufVA,
-	OUT	UINT		 *pSrcBufLen);
+void RTMP_QueryNextPacketInfo(void ** ppPacket,
+			      struct rt_packet_info *pPacketInfo,
+			      u8 ** pSrcBufVA, u32 * pSrcBufLen);
 
+BOOLEAN RTMP_FillTxBlkInfo(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk);
 
-BOOLEAN RTMP_FillTxBlkInfo(
-	IN RTMP_ADAPTER *pAd,
-	IN TX_BLK *pTxBlk);
+struct rt_rtmp_sg_list *
+rt_get_sg_list_from_packet(void *pPacket, struct rt_rtmp_sg_list *sg);
 
+void announce_802_3_packet(struct rt_rtmp_adapter *pAd, void *pPacket);
 
-PRTMP_SCATTER_GATHER_LIST
-rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg);
+u32 BA_Reorder_AMSDU_Annnounce(struct rt_rtmp_adapter *pAd, void *pPacket);
 
+struct net_device *get_netdev_from_bssid(struct rt_rtmp_adapter *pAd, u8 FromWhichBSSID);
 
- void announce_802_3_packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket);
+void *duplicate_pkt(struct rt_rtmp_adapter *pAd,
+			   u8 *pHeader802_3,
+			   u32 HdrLen,
+			   u8 *pData,
+			   unsigned long DataSize, u8 FromWhichBSSID);
 
+void *duplicate_pkt_with_TKIP_MIC(struct rt_rtmp_adapter *pAd,
+					 void *pOldPkt);
 
-UINT BA_Reorder_AMSDU_Annnounce(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket);
+void ba_flush_reordering_timeout_mpdus(struct rt_rtmp_adapter *pAd,
+				       struct rt_ba_rec_entry *pBAEntry,
+				       unsigned long Now32);
 
-PNET_DEV get_netdev_from_bssid(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			FromWhichBSSID);
+void BAOriSessionSetUp(struct rt_rtmp_adapter *pAd,
+		       struct rt_mac_table_entry *pEntry,
+		       u8 TID,
+		       u16 TimeOut,
+		       unsigned long DelayTime, IN BOOLEAN isForced);
 
-
-PNDIS_PACKET duplicate_pkt(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pHeader802_3,
-    IN  UINT            HdrLen,
-	IN	PUCHAR			pData,
-	IN	ULONG			DataSize,
-	IN	UCHAR			FromWhichBSSID);
-
-
-PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pOldPkt);
-
-void ba_flush_reordering_timeout_mpdus(
-	IN PRTMP_ADAPTER	pAd,
-	IN PBA_REC_ENTRY	pBAEntry,
-	IN ULONG			Now32);
-
-
-VOID BAOriSessionSetUp(
-			IN PRTMP_ADAPTER    pAd,
-			IN MAC_TABLE_ENTRY	*pEntry,
-			IN UCHAR			TID,
-			IN USHORT			TimeOut,
-			IN ULONG			DelayTime,
-			IN BOOLEAN		isForced);
-
-VOID BASessionTearDownALL(
-	IN OUT	PRTMP_ADAPTER pAd,
-	IN		UCHAR Wcid);
+void BASessionTearDownALL(struct rt_rtmp_adapter *pAd, u8 Wcid);
 
 BOOLEAN OS_Need_Clone_Packet(void);
 
+void build_tx_packet(struct rt_rtmp_adapter *pAd,
+		     void *pPacket,
+		     u8 *pFrame, unsigned long FrameLen);
 
-VOID build_tx_packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket,
-	IN	PUCHAR	pFrame,
-	IN	ULONG	FrameLen);
+void BAOriSessionTearDown(struct rt_rtmp_adapter *pAd,
+			  u8 Wcid,
+			  u8 TID,
+			  IN BOOLEAN bPassive, IN BOOLEAN bForceSend);
 
+void BARecSessionTearDown(struct rt_rtmp_adapter *pAd,
+			  u8 Wcid, u8 TID, IN BOOLEAN bPassive);
 
-VOID BAOriSessionTearDown(
-	IN OUT	PRTMP_ADAPTER	pAd,
-	IN		UCHAR			Wcid,
-	IN		UCHAR			TID,
-	IN		BOOLEAN			bPassive,
-	IN		BOOLEAN			bForceSend);
+BOOLEAN ba_reordering_resource_init(struct rt_rtmp_adapter *pAd, int num);
+void ba_reordering_resource_release(struct rt_rtmp_adapter *pAd);
 
-VOID BARecSessionTearDown(
-	IN OUT	PRTMP_ADAPTER	pAd,
-	IN		UCHAR			Wcid,
-	IN		UCHAR			TID,
-	IN		BOOLEAN			bPassive);
+char *rstrtok(char *s, IN const char *ct);
 
-BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num);
-void ba_reordering_resource_release(PRTMP_ADAPTER pAd);
+/*//////// common ioctl functions ////////// */
+int SetCommonHT(struct rt_rtmp_adapter *pAd);
 
-BOOLEAN rtstrmactohex(
-	IN char *s1,
-	IN char *s2);
+int WpaCheckEapCode(struct rt_rtmp_adapter *pAd,
+		    u8 *pFrame, u16 FrameLen, u16 OffSet);
 
-BOOLEAN rtstrcasecmp(
-	IN char *s1,
-	IN char *s2);
+void WpaSendMicFailureToWpaSupplicant(struct rt_rtmp_adapter *pAd,
+				      IN BOOLEAN bUnicast);
 
-char *rtstrstruncasecmp(
-	IN char *s1,
-	IN char *s2);
+int wext_notify_event_assoc(struct rt_rtmp_adapter *pAd);
 
-char    *rtstrstr(
-	IN	const char * s1,
-	IN	const char * s2);
+BOOLEAN STARxDoneInterruptHandle(struct rt_rtmp_adapter *pAd, IN BOOLEAN argc);
 
-char *rstrtok(
-	IN char * s,
-	IN const char * ct);
+/* AMPDU packet indication */
+void Indicate_AMPDU_Packet(struct rt_rtmp_adapter *pAd,
+			   struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID);
 
-int rtinet_aton(
-	const char *cp,
-	unsigned int *addr);
+/* AMSDU packet indication */
+void Indicate_AMSDU_Packet(struct rt_rtmp_adapter *pAd,
+			   struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID);
 
-////////// common ioctl functions //////////
-INT Set_DriverVersion_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
+/* Normal legacy Rx packet indication */
+void Indicate_Legacy_Packet(struct rt_rtmp_adapter *pAd,
+			    struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID);
 
-INT Set_CountryRegion_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
+void Indicate_EAPOL_Packet(struct rt_rtmp_adapter *pAd,
+			   struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID);
 
-INT Set_CountryRegionABand_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
+void update_os_packet_info(struct rt_rtmp_adapter *pAd,
+			   struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID);
 
-INT Set_WirelessMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
+void wlan_802_11_to_802_3_packet(struct rt_rtmp_adapter *pAd,
+				 struct rt_rx_blk *pRxBlk,
+				 u8 *pHeader802_3,
+				 u8 FromWhichBSSID);
 
-INT Set_Channel_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_ShortSlot_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_TxPower_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT Set_BGProtection_Proc(
-	IN  PRTMP_ADAPTER		pAd,
-	IN  PUCHAR			arg);
-
-INT Set_TxPreamble_Proc(
-	IN  PRTMP_ADAPTER		pAd,
-	IN  PUCHAR			arg);
-
-INT Set_RTSThreshold_Proc(
-	IN  PRTMP_ADAPTER		pAd,
-	IN  PUCHAR			arg);
-
-INT Set_FragThreshold_Proc(
-	IN  PRTMP_ADAPTER		pAd,
-	IN  PUCHAR			arg);
-
-INT Set_TxBurst_Proc(
-	IN  PRTMP_ADAPTER		pAd,
-	IN  PUCHAR			arg);
-
-#ifdef AGGREGATION_SUPPORT
-INT	Set_PktAggregate_Proc(
-	IN  PRTMP_ADAPTER		pAd,
-	IN  PUCHAR			arg);
-#endif
-
-INT	Set_IEEE80211H_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-#ifdef DBG
-INT	Set_Debug_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-#endif
-
-INT	Show_DescInfo_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_ResetStatCounter_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_BASetup_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_BADecline_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_BAOriTearDown_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_BARecTearDown_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_HtBw_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_HtMcs_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_HtGi_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_HtOpMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_HtStbc_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_HtHtc_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_HtExtcha_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_HtMpduDensity_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_HtBaWinSize_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_HtRdg_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_HtLinkAdapt_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_HtAmsdu_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_HtAutoBa_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_HtProtect_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_HtMimoPs_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-
-INT	Set_ForceShortGI_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_ForceGF_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	SetCommonHT(
-	IN	PRTMP_ADAPTER	pAd);
-
-INT	Set_SendPSMPAction_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	Set_HtMIMOPSmode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-
-INT	Set_HtTxBASize_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-INT	    WpaCheckEapCode(
-	IN  PRTMP_ADAPTER   	pAd,
-	IN  PUCHAR				pFrame,
-	IN  USHORT				FrameLen,
-	IN  USHORT				OffSet);
-
-VOID    WpaSendMicFailureToWpaSupplicant(
-    IN  PRTMP_ADAPTER       pAd,
-    IN  BOOLEAN             bUnicast);
-
-int wext_notify_event_assoc(
-	IN  RTMP_ADAPTER *pAd);
-
-BOOLEAN STARxDoneInterruptHandle(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	BOOLEAN			argc);
-
-// AMPDU packet indication
-VOID Indicate_AMPDU_Packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID);
-
-// AMSDU packet indication
-VOID Indicate_AMSDU_Packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID);
-
-// Normal legacy Rx packet indication
-VOID Indicate_Legacy_Packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID);
-
-VOID Indicate_EAPOL_Packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID);
-
-void  update_os_packet_info(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID);
-
-void wlan_802_11_to_802_3_packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	PUCHAR			pHeader802_3,
-	IN  UCHAR			FromWhichBSSID);
-
-UINT deaggregate_AMSDU_announce(
-	IN	PRTMP_ADAPTER	pAd,
-	PNDIS_PACKET		pPacket,
-	IN	PUCHAR			pData,
-	IN	ULONG			DataSize);
-
-// remove LLC and get 802_3 Header
+/* remove LLC and get 802_3 Header */
 #define  RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(_pRxBlk, _pHeader802_3)	\
 {																				\
-	PUCHAR _pRemovedLLCSNAP = NULL, _pDA, _pSA;                                 \
+	u8 *_pRemovedLLCSNAP = NULL, *_pDA, *_pSA;                                 \
 																				\
 	if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_MESH))                                    \
 	{                                                                           \
 		_pDA = _pRxBlk->pHeader->Addr3;                                         \
-		_pSA = (PUCHAR)_pRxBlk->pHeader + sizeof(HEADER_802_11);                \
+		_pSA = (u8 *)_pRxBlk->pHeader + sizeof(struct rt_header_802_11);                \
 	}                                                                           \
 	else                                                                        \
 	{                                                                           \
@@ -5565,133 +3742,122 @@
 		_pRxBlk->DataSize, _pRemovedLLCSNAP);                                   \
 }
 
-VOID Sta_Announce_or_Forward_802_3_Packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket,
-	IN	UCHAR			FromWhichBSSID);
+void Sta_Announce_or_Forward_802_3_Packet(struct rt_rtmp_adapter *pAd,
+					  void *pPacket,
+					  u8 FromWhichBSSID);
 
 #define ANNOUNCE_OR_FORWARD_802_3_PACKET(_pAd, _pPacket, _FromWhichBSS)\
 			Sta_Announce_or_Forward_802_3_Packet(_pAd, _pPacket, _FromWhichBSS);
-			//announce_802_3_packet(_pAd, _pPacket);
+			/*announce_802_3_packet(_pAd, _pPacket); */
 
-PNDIS_PACKET DuplicatePacket(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket,
-	IN	UCHAR			FromWhichBSSID);
+void *DuplicatePacket(struct rt_rtmp_adapter *pAd,
+			     void *pPacket, u8 FromWhichBSSID);
 
+void *ClonePacket(struct rt_rtmp_adapter *pAd,
+			 void *pPacket,
+			 u8 *pData, unsigned long DataSize);
 
-PNDIS_PACKET ClonePacket(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket,
-	IN	PUCHAR			pData,
-	IN	ULONG			DataSize);
+/* Normal, AMPDU or AMSDU */
+void CmmRxnonRalinkFrameIndicate(struct rt_rtmp_adapter *pAd,
+				 struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID);
 
+void CmmRxRalinkFrameIndicate(struct rt_rtmp_adapter *pAd,
+			      struct rt_mac_table_entry *pEntry,
+			      struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID);
 
-// Normal, AMPDU or AMSDU
-VOID CmmRxnonRalinkFrameIndicate(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID);
+void Update_Rssi_Sample(struct rt_rtmp_adapter *pAd,
+			struct rt_rssi_sample *pRssi, struct rt_rxwi * pRxWI);
 
-VOID CmmRxRalinkFrameIndicate(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MAC_TABLE_ENTRY	*pEntry,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID);
+void *GetPacketFromRxRing(struct rt_rtmp_adapter *pAd,
+				 OUT PRT28XX_RXD_STRUC pSaveRxD,
+				 OUT BOOLEAN * pbReschedule,
+				 IN u32 * pRxPending);
 
-VOID Update_Rssi_Sample(
-	IN PRTMP_ADAPTER	pAd,
-	IN RSSI_SAMPLE		*pRssi,
-	IN PRXWI_STRUC		pRxWI);
+void *RTMPDeFragmentDataFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk);
 
-PNDIS_PACKET RTMPDeFragmentDataFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk);
-
-////////////////////////////////////////
 enum {
-	DIDmsg_lnxind_wlansniffrm		= 0x00000044,
-	DIDmsg_lnxind_wlansniffrm_hosttime	= 0x00010044,
-	DIDmsg_lnxind_wlansniffrm_mactime	= 0x00020044,
-	DIDmsg_lnxind_wlansniffrm_channel	= 0x00030044,
-	DIDmsg_lnxind_wlansniffrm_rssi		= 0x00040044,
-	DIDmsg_lnxind_wlansniffrm_sq		= 0x00050044,
-	DIDmsg_lnxind_wlansniffrm_signal	= 0x00060044,
-	DIDmsg_lnxind_wlansniffrm_noise		= 0x00070044,
-	DIDmsg_lnxind_wlansniffrm_rate		= 0x00080044,
-	DIDmsg_lnxind_wlansniffrm_istx		= 0x00090044,
-	DIDmsg_lnxind_wlansniffrm_frmlen	= 0x000A0044
+	DIDmsg_lnxind_wlansniffrm = 0x00000044,
+	DIDmsg_lnxind_wlansniffrm_hosttime = 0x00010044,
+	DIDmsg_lnxind_wlansniffrm_mactime = 0x00020044,
+	DIDmsg_lnxind_wlansniffrm_channel = 0x00030044,
+	DIDmsg_lnxind_wlansniffrm_rssi = 0x00040044,
+	DIDmsg_lnxind_wlansniffrm_sq = 0x00050044,
+	DIDmsg_lnxind_wlansniffrm_signal = 0x00060044,
+	DIDmsg_lnxind_wlansniffrm_noise = 0x00070044,
+	DIDmsg_lnxind_wlansniffrm_rate = 0x00080044,
+	DIDmsg_lnxind_wlansniffrm_istx = 0x00090044,
+	DIDmsg_lnxind_wlansniffrm_frmlen = 0x000A0044
 };
 enum {
-	P80211ENUM_msgitem_status_no_value	= 0x00
+	P80211ENUM_msgitem_status_no_value = 0x00
 };
 enum {
-	P80211ENUM_truth_false			= 0x00,
-	P80211ENUM_truth_true			= 0x01
+	P80211ENUM_truth_false = 0x00,
+	P80211ENUM_truth_true = 0x01
 };
 
 /* Definition from madwifi */
-typedef struct {
-        UINT32 did;
-        UINT16 status;
-        UINT16 len;
-        UINT32 data;
-} p80211item_uint32_t;
+struct rt_p80211item_uint32 {
+	u32 did;
+	u16 status;
+	u16 len;
+	u32 data;
+};
 
-typedef struct {
-        UINT32 msgcode;
-        UINT32 msglen;
+struct rt_wlan_ng_prism2_header {
+	u32 msgcode;
+	u32 msglen;
 #define WLAN_DEVNAMELEN_MAX 16
-        UINT8 devname[WLAN_DEVNAMELEN_MAX];
-        p80211item_uint32_t hosttime;
-        p80211item_uint32_t mactime;
-        p80211item_uint32_t channel;
-        p80211item_uint32_t rssi;
-        p80211item_uint32_t sq;
-        p80211item_uint32_t signal;
-        p80211item_uint32_t noise;
-        p80211item_uint32_t rate;
-        p80211item_uint32_t istx;
-        p80211item_uint32_t frmlen;
-} wlan_ng_prism2_header;
+	u8 devname[WLAN_DEVNAMELEN_MAX];
+	struct rt_p80211item_uint32 hosttime;
+	struct rt_p80211item_uint32 mactime;
+	struct rt_p80211item_uint32 channel;
+	struct rt_p80211item_uint32 rssi;
+	struct rt_p80211item_uint32 sq;
+	struct rt_p80211item_uint32 signal;
+	struct rt_p80211item_uint32 noise;
+	struct rt_p80211item_uint32 rate;
+	struct rt_p80211item_uint32 istx;
+	struct rt_p80211item_uint32 frmlen;
+};
 
 /* The radio capture header precedes the 802.11 header. */
-typedef struct PACKED _ieee80211_radiotap_header {
-    UINT8	it_version;	/* Version 0. Only increases
+struct PACKED rt_ieee80211_radiotap_header {
+	u8 it_version;	/* Version 0. Only increases
 				 * for drastic changes,
 				 * introduction of compatible
 				 * new fields does not count.
 				 */
-    UINT8	it_pad;
-    UINT16     it_len;         /* length of the whole
+	u8 it_pad;
+	u16 it_len;		/* length of the whole
 				 * header in bytes, including
 				 * it_version, it_pad,
 				 * it_len, and data fields.
 				 */
-    UINT32   it_present;	/* A bitmap telling which
-					 * fields are present. Set bit 31
-					 * (0x80000000) to extend the
-					 * bitmap by another 32 bits.
-					 * Additional extensions are made
-					 * by setting bit 31.
-					 */
-}ieee80211_radiotap_header ;
+	u32 it_present;	/* A bitmap telling which
+				 * fields are present. Set bit 31
+				 * (0x80000000) to extend the
+				 * bitmap by another 32 bits.
+				 * Additional extensions are made
+				 * by setting bit 31.
+				 */
+};
 
 enum ieee80211_radiotap_type {
-    IEEE80211_RADIOTAP_TSFT = 0,
-    IEEE80211_RADIOTAP_FLAGS = 1,
-    IEEE80211_RADIOTAP_RATE = 2,
-    IEEE80211_RADIOTAP_CHANNEL = 3,
-    IEEE80211_RADIOTAP_FHSS = 4,
-    IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
-    IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
-    IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
-    IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
-    IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
-    IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
-    IEEE80211_RADIOTAP_ANTENNA = 11,
-    IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
-    IEEE80211_RADIOTAP_DB_ANTNOISE = 13
+	IEEE80211_RADIOTAP_TSFT = 0,
+	IEEE80211_RADIOTAP_FLAGS = 1,
+	IEEE80211_RADIOTAP_RATE = 2,
+	IEEE80211_RADIOTAP_CHANNEL = 3,
+	IEEE80211_RADIOTAP_FHSS = 4,
+	IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
+	IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
+	IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
+	IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
+	IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
+	IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
+	IEEE80211_RADIOTAP_ANTENNA = 11,
+	IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
+	IEEE80211_RADIOTAP_DB_ANTNOISE = 13
 };
 
 #define WLAN_RADIOTAP_PRESENT (			\
@@ -5700,737 +3866,491 @@
 	(1 << IEEE80211_RADIOTAP_RATE)  | 	\
 	 0)
 
-typedef struct _wlan_radiotap_header {
-	ieee80211_radiotap_header wt_ihdr;
-	INT64 wt_tsft;
-	UINT8 wt_flags;
-	UINT8 wt_rate;
-} wlan_radiotap_header;
+struct rt_wlan_radiotap_header {
+	struct rt_ieee80211_radiotap_header wt_ihdr;
+	long long wt_tsft;
+	u8 wt_flags;
+	u8 wt_rate;
+};
 /* Definition from madwifi */
 
-void send_monitor_packets(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk);
+void send_monitor_packets(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk);
 
-// This function will be called when query /proc
-struct iw_statistics *rt28xx_get_wireless_stats(
-    IN struct net_device *net_dev);
+void RTMPSetDesiredRates(struct rt_rtmp_adapter *pAdapter, long Rates);
 
-VOID    RTMPSetDesiredRates(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  LONG            Rates);
+int Set_FixedTxMode_Proc(struct rt_rtmp_adapter *pAd, char *arg);
 
-INT	Set_FixedTxMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
+BOOLEAN RT28XXChipsetCheck(IN void *_dev_p);
 
-static inline char* GetPhyMode(
-	int Mode)
-{
-	switch(Mode)
-	{
-		case MODE_CCK:
-			return "CCK";
+void RT28XXDMADisable(struct rt_rtmp_adapter *pAd);
 
-		case MODE_OFDM:
-			return "OFDM";
-		case MODE_HTMIX:
-			return "HTMIX";
+void RT28XXDMAEnable(struct rt_rtmp_adapter *pAd);
 
-		case MODE_HTGREENFIELD:
-			return "GREEN";
-		default:
-			return "N/A";
-	}
-}
+void RT28xx_UpdateBeaconToAsic(struct rt_rtmp_adapter *pAd,
+			       int apidx,
+			       unsigned long BeaconLen, unsigned long UpdatePos);
 
+int rt28xx_init(struct rt_rtmp_adapter *pAd,
+		char *pDefaultMac, char *pHostName);
 
-static inline char* GetBW(
-	int BW)
-{
-	switch(BW)
-	{
-		case BW_10:
-			return "10M";
+int RtmpNetTaskInit(struct rt_rtmp_adapter *pAd);
 
-		case BW_20:
-			return "20M";
-		case BW_40:
-			return "40M";
-		default:
-			return "N/A";
-	}
-}
+void RtmpNetTaskExit(struct rt_rtmp_adapter *pAd);
 
+int RtmpMgmtTaskInit(struct rt_rtmp_adapter *pAd);
 
-VOID RT28xxThreadTerminate(
-	IN RTMP_ADAPTER *pAd);
-
-BOOLEAN RT28XXChipsetCheck(
-	IN void *_dev_p);
-
-BOOLEAN RT28XXNetDevInit(
-	IN void 				*_dev_p,
-	IN struct  net_device	*net_dev,
-	IN RTMP_ADAPTER 		*pAd);
-
-BOOLEAN RT28XXProbePostConfig(
-	IN void 				*_dev_p,
-	IN RTMP_ADAPTER 		*pAd,
-	IN INT32				argc);
-
-VOID RT28XXDMADisable(
-	IN RTMP_ADAPTER 		*pAd);
-
-VOID RT28XXDMAEnable(
-	IN RTMP_ADAPTER 		*pAd);
-
-VOID RT28xx_UpdateBeaconToAsic(
-	IN RTMP_ADAPTER * pAd,
-	IN INT apidx,
-	IN ULONG BeaconLen,
-	IN ULONG UpdatePos);
-
-INT rt28xx_sta_ioctl(
-	IN	struct net_device	*net_dev,
-	IN	OUT	struct ifreq	*rq,
-	IN	INT			cmd);
-
-////////////////////////////////////////
-PNDIS_PACKET GetPacketFromRxRing(
-	IN		PRTMP_ADAPTER	pAd,
-	OUT		PRT28XX_RXD_STRUC	pSaveRxD,
-	OUT		BOOLEAN			*pbReschedule,
-	IN OUT	UINT32			*pRxPending);
-
-
-void kill_thread_task(PRTMP_ADAPTER pAd);
+void RtmpMgmtTaskExit(struct rt_rtmp_adapter *pAd);
 
 void tbtt_tasklet(unsigned long data);
 
-#ifdef RT2860
-//
-// Function Prototype in cmm_data_2860.c
-//
-USHORT RtmpPCI_WriteTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	BOOLEAN			bIsLast,
-	OUT	USHORT			*FreeNumber);
+struct net_device *RtmpPhyNetDevInit(struct rt_rtmp_adapter *pAd,
+			   struct rt_rtmp_os_netdev_op_hook *pNetHook);
 
-USHORT RtmpPCI_WriteSingleTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	BOOLEAN			bIsLast,
-	OUT	USHORT			*FreeNumber);
+BOOLEAN RtmpPhyNetDevExit(struct rt_rtmp_adapter *pAd, struct net_device *net_dev);
 
-USHORT RtmpPCI_WriteMultiTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	UCHAR			frameNum,
-	OUT	USHORT			*FreeNumber);
+int RtmpRaDevCtrlInit(struct rt_rtmp_adapter *pAd, IN RTMP_INF_TYPE infType);
 
-USHORT	RtmpPCI_WriteFragTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	UCHAR			fragNum,
-	OUT	USHORT			*FreeNumber);
+BOOLEAN RtmpRaDevCtrlExit(struct rt_rtmp_adapter *pAd);
 
-USHORT RtmpPCI_WriteSubTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	BOOLEAN			bIsLast,
-	OUT	USHORT			*FreeNumber);
+#ifdef RTMP_MAC_PCI
+/* */
+/* Function Prototype in cmm_data_pci.c */
+/* */
+u16 RtmpPCI_WriteTxResource(struct rt_rtmp_adapter *pAd,
+			       struct rt_tx_blk *pTxBlk,
+			       IN BOOLEAN bIsLast, u16 * FreeNumber);
 
-VOID RtmpPCI_FinalWriteTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	USHORT			totalMPDUSize,
-	IN	USHORT			FirstTxIdx);
+u16 RtmpPCI_WriteSingleTxResource(struct rt_rtmp_adapter *pAd,
+				     struct rt_tx_blk *pTxBlk,
+				     IN BOOLEAN bIsLast,
+				     u16 * FreeNumber);
 
-VOID RtmpPCIDataLastTxIdx(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			QueIdx,
-	IN	USHORT			LastTxIdx);
+u16 RtmpPCI_WriteMultiTxResource(struct rt_rtmp_adapter *pAd,
+				    struct rt_tx_blk *pTxBlk,
+				    u8 frameNum, u16 * FreeNumber);
 
-VOID RtmpPCIDataKickOut(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	UCHAR			QueIdx);
+u16 RtmpPCI_WriteFragTxResource(struct rt_rtmp_adapter *pAd,
+				   struct rt_tx_blk *pTxBlk,
+				   u8 fragNum, u16 * FreeNumber);
 
+u16 RtmpPCI_WriteSubTxResource(struct rt_rtmp_adapter *pAd,
+				  struct rt_tx_blk *pTxBlk,
+				  IN BOOLEAN bIsLast, u16 * FreeNumber);
 
-int RtmpPCIMgmtKickOut(
-	IN RTMP_ADAPTER 	*pAd,
-	IN UCHAR 			QueIdx,
-	IN PNDIS_PACKET		pPacket,
-	IN PUCHAR			pSrcBufVA,
-	IN UINT 			SrcBufLen);
+void RtmpPCI_FinalWriteTxResource(struct rt_rtmp_adapter *pAd,
+				  struct rt_tx_blk *pTxBlk,
+				  u16 totalMPDUSize,
+				  u16 FirstTxIdx);
 
+void RtmpPCIDataLastTxIdx(struct rt_rtmp_adapter *pAd,
+			  u8 QueIdx, u16 LastTxIdx);
 
-NDIS_STATUS RTMPCheckRxError(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PHEADER_802_11  pHeader,
-	IN	PRXWI_STRUC	pRxWI,
-	IN  PRT28XX_RXD_STRUC      pRxD);
+void RtmpPCIDataKickOut(struct rt_rtmp_adapter *pAd,
+			struct rt_tx_blk *pTxBlk, u8 QueIdx);
 
-VOID RTMPInitPCIeLinkCtrlValue(
-	IN	PRTMP_ADAPTER	pAd);
+int RtmpPCIMgmtKickOut(struct rt_rtmp_adapter *pAd,
+		       u8 QueIdx,
+		       void *pPacket,
+		       u8 *pSrcBufVA, u32 SrcBufLen);
 
-VOID RTMPFindHostPCIDev(
-    IN	PRTMP_ADAPTER	pAd);
+int RTMPCheckRxError(struct rt_rtmp_adapter *pAd,
+			     struct rt_header_802_11 * pHeader,
+			     struct rt_rxwi * pRxWI, IN PRT28XX_RXD_STRUC pRxD);
 
-VOID RTMPPCIeLinkCtrlValueRestore(
-	IN	PRTMP_ADAPTER	pAd,
-	IN   UCHAR		Level);
+BOOLEAN RT28xxPciAsicRadioOff(struct rt_rtmp_adapter *pAd,
+			      u8 Level, u16 TbttNumToNextWakeUp);
 
-VOID RTMPPCIeLinkCtrlSetting(
-	IN	PRTMP_ADAPTER	pAd,
-	IN 	USHORT		Max);
+BOOLEAN RT28xxPciAsicRadioOn(struct rt_rtmp_adapter *pAd, u8 Level);
 
-VOID RT28xxPciAsicRadioOff(
-	IN PRTMP_ADAPTER    pAd,
-	IN UCHAR            Level,
-	IN USHORT           TbttNumToNextWakeUp);
+void RTMPInitPCIeLinkCtrlValue(struct rt_rtmp_adapter *pAd);
 
-BOOLEAN RT28xxPciAsicRadioOn(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR     Level);
+void RTMPFindHostPCIDev(struct rt_rtmp_adapter *pAd);
 
-VOID RT28xxPciStaAsicForceWakeup(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR    	 Level);
+void RTMPPCIeLinkCtrlValueRestore(struct rt_rtmp_adapter *pAd, u8 Level);
 
-VOID RT28xxPciStaAsicSleepThenAutoWakeup(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT TbttNumToNextWakeUp);
+void RTMPPCIeLinkCtrlSetting(struct rt_rtmp_adapter *pAd, u16 Max);
 
-VOID PsPollWakeExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
+void RTMPrt3xSetPCIePowerLinkCtrl(struct rt_rtmp_adapter *pAd);
 
-VOID  RadioOnExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
+void PsPollWakeExec(void *SystemSpecific1,
+		    void *FunctionContext,
+		    void *SystemSpecific2, void *SystemSpecific3);
 
-VOID RT28xxPciMlmeRadioOn(
-	IN PRTMP_ADAPTER pAd);
+void RadioOnExec(void *SystemSpecific1,
+		 void *FunctionContext,
+		 void *SystemSpecific2, void *SystemSpecific3);
 
-VOID RT28xxPciMlmeRadioOFF(
-	IN PRTMP_ADAPTER pAd);
-#endif /* RT2860 */
+void RT28xxPciStaAsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx);
 
-VOID AsicTurnOffRFClk(
-	IN PRTMP_ADAPTER    pAd,
-	IN	UCHAR           Channel);
+void RT28xxPciStaAsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd,
+					 u16 TbttNumToNextWakeUp);
 
-VOID AsicTurnOnRFClk(
-	IN PRTMP_ADAPTER 	pAd,
-	IN	UCHAR			Channel);
+void RT28xxPciMlmeRadioOn(struct rt_rtmp_adapter *pAd);
 
-NTSTATUS RT30xxWriteRFRegister(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			RegID,
-	IN	UCHAR			Value);
+void RT28xxPciMlmeRadioOFF(struct rt_rtmp_adapter *pAd);
+#endif /* RTMP_MAC_PCI // */
 
-NTSTATUS RT30xxReadRFRegister(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			RegID,
-	IN	PUCHAR			pValue);
+#ifdef RTMP_MAC_USB
+/* */
+/* Function Prototype in rtusb_bulk.c */
+/* */
+void RTUSBInitTxDesc(struct rt_rtmp_adapter *pAd,
+		     struct rt_tx_context *pTxContext,
+		     u8 BulkOutPipeId, IN usb_complete_t Func);
 
-UCHAR eFuseReadRegisters(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	OUT	USHORT* pData);
+void RTUSBInitHTTxDesc(struct rt_rtmp_adapter *pAd,
+		       struct rt_ht_tx_context *pTxContext,
+		       u8 BulkOutPipeId,
+		       unsigned long BulkOutSize, IN usb_complete_t Func);
 
-VOID eFuseReadPhysical(
-	IN	PRTMP_ADAPTER	pAd,
-  	IN	PUSHORT lpInBuffer,
-  	IN	ULONG nInBufferSize,
-  	OUT	PUSHORT lpOutBuffer,
-  	IN	ULONG nOutBufferSize
-);
+void RTUSBInitRxDesc(struct rt_rtmp_adapter *pAd, struct rt_rx_context *pRxContext);
 
-NTSTATUS eFuseRead(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	OUT	PUCHAR			pData,
-	IN	USHORT			Length);
+void RTUSBCleanUpDataBulkOutQueue(struct rt_rtmp_adapter *pAd);
 
-VOID eFusePhysicalWriteRegisters(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	OUT	USHORT* pData);
+void RTUSBCancelPendingBulkOutIRP(struct rt_rtmp_adapter *pAd);
 
-NTSTATUS eFuseWriteRegisters(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	IN	USHORT* pData);
+void RTUSBBulkOutDataPacket(struct rt_rtmp_adapter *pAd,
+			    u8 BulkOutPipeId, u8 Index);
 
-VOID eFuseWritePhysical(
-	IN	PRTMP_ADAPTER	pAd,
-  	PUSHORT lpInBuffer,
-	ULONG nInBufferSize,
-  	PUCHAR lpOutBuffer,
-  	ULONG nOutBufferSize
-);
+void RTUSBBulkOutNullFrame(struct rt_rtmp_adapter *pAd);
 
-NTSTATUS eFuseWrite(
-   	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	IN	PUCHAR			pData,
-	IN	USHORT			length);
+void RTUSBBulkOutRTSFrame(struct rt_rtmp_adapter *pAd);
 
-INT set_eFuseGetFreeBlockCount_Proc(
-   	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
+void RTUSBCancelPendingBulkInIRP(struct rt_rtmp_adapter *pAd);
 
-INT set_eFusedump_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
+void RTUSBCancelPendingIRPs(struct rt_rtmp_adapter *pAd);
 
-INT set_eFuseLoadFromBin_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
+void RTUSBBulkOutMLMEPacket(struct rt_rtmp_adapter *pAd, u8 Index);
 
-NTSTATUS eFuseWriteRegistersFromBin(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	IN	USHORT* pData);
+void RTUSBBulkOutPsPoll(struct rt_rtmp_adapter *pAd);
 
-VOID eFusePhysicalReadRegisters(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	OUT	USHORT* pData);
+void RTUSBCleanUpMLMEBulkOutQueue(struct rt_rtmp_adapter *pAd);
 
-VOID RT30xxLoadRFNormalModeSetup(
-	IN PRTMP_ADAPTER 	pAd);
+void RTUSBKickBulkOut(struct rt_rtmp_adapter *pAd);
 
-VOID RT30xxLoadRFSleepModeSetup(
-	IN PRTMP_ADAPTER 	pAd);
+void RTUSBBulkReceive(struct rt_rtmp_adapter *pAd);
 
-VOID RT30xxReverseRFSleepModeSetup(
-	IN PRTMP_ADAPTER 	pAd);
+void DoBulkIn(struct rt_rtmp_adapter *pAd);
 
-#ifdef RT2870
-//
-// Function Prototype in rtusb_bulk.c
-//
-VOID	RTUSBInitTxDesc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PTX_CONTEXT		pTxContext,
-	IN	UCHAR			BulkOutPipeId,
-	IN	usb_complete_t	Func);
+void RTUSBInitRxDesc(struct rt_rtmp_adapter *pAd, struct rt_rx_context *pRxContext);
 
-VOID	RTUSBInitHTTxDesc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PHT_TX_CONTEXT	pTxContext,
-	IN	UCHAR			BulkOutPipeId,
-	IN	ULONG			BulkOutSize,
-	IN	usb_complete_t	Func);
+void RTUSBBulkRxHandle(IN unsigned long data);
 
-VOID RTUSBCleanUpDataBulkOutQueue(
-	IN	PRTMP_ADAPTER	pAd);
+/* */
+/* Function Prototype in rtusb_io.c */
+/* */
+int RTUSBMultiRead(struct rt_rtmp_adapter *pAd,
+			u16 Offset, u8 *pData, u16 length);
 
-VOID RTUSBCancelPendingBulkOutIRP(
-	IN	PRTMP_ADAPTER	pAd);
+int RTUSBMultiWrite(struct rt_rtmp_adapter *pAd,
+			 u16 Offset, u8 *pData, u16 length);
 
-VOID RTUSBBulkOutDataPacket(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			BulkOutPipeId,
-	IN	UCHAR			Index);
+int RTUSBMultiWrite_OneByte(struct rt_rtmp_adapter *pAd,
+				 u16 Offset, u8 *pData);
 
-VOID RTUSBBulkOutNullFrame(
-	IN	PRTMP_ADAPTER	pAd);
+int RTUSBReadBBPRegister(struct rt_rtmp_adapter *pAd,
+			      u8 Id, u8 *pValue);
 
-VOID RTUSBBulkOutRTSFrame(
-	IN	PRTMP_ADAPTER	pAd);
+int RTUSBWriteBBPRegister(struct rt_rtmp_adapter *pAd,
+			       u8 Id, u8 Value);
 
-VOID RTUSBCancelPendingBulkInIRP(
-	IN	PRTMP_ADAPTER	pAd);
+int RTUSBWriteRFRegister(struct rt_rtmp_adapter *pAd, u32 Value);
 
-VOID RTUSBCancelPendingIRPs(
-	IN	PRTMP_ADAPTER	pAd);
+int RTUSB_VendorRequest(struct rt_rtmp_adapter *pAd,
+			     u32 TransferFlags,
+			     u8 ReservedBits,
+			     u8 Request,
+			     u16 Value,
+			     u16 Index,
+			     void *TransferBuffer,
+			     u32 TransferBufferLength);
 
-VOID RTUSBBulkOutMLMEPacket(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Index);
+int RTUSBReadEEPROM(struct rt_rtmp_adapter *pAd,
+			 u16 Offset, u8 *pData, u16 length);
 
-VOID RTUSBBulkOutPsPoll(
-	IN	PRTMP_ADAPTER	pAd);
+int RTUSBWriteEEPROM(struct rt_rtmp_adapter *pAd,
+			  u16 Offset, u8 *pData, u16 length);
 
-VOID RTUSBCleanUpMLMEBulkOutQueue(
-	IN	PRTMP_ADAPTER	pAd);
+void RTUSBPutToSleep(struct rt_rtmp_adapter *pAd);
 
-VOID RTUSBKickBulkOut(
-	IN	PRTMP_ADAPTER pAd);
+int RTUSBWakeUp(struct rt_rtmp_adapter *pAd);
 
-VOID	RTUSBBulkReceive(
-	IN	PRTMP_ADAPTER	pAd);
+void RTUSBInitializeCmdQ(struct rt_cmdq *cmdq);
 
-VOID DoBulkIn(
-	IN RTMP_ADAPTER *pAd);
+int RTUSBEnqueueCmdFromNdis(struct rt_rtmp_adapter *pAd,
+				    IN NDIS_OID Oid,
+				    IN BOOLEAN SetInformation,
+				    void *pInformationBuffer,
+				    u32 InformationBufferLength);
 
-VOID RTUSBInitRxDesc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN  PRX_CONTEXT		pRxContext);
+int RTUSBEnqueueInternalCmd(struct rt_rtmp_adapter *pAd,
+				    IN NDIS_OID Oid,
+				    void *pInformationBuffer,
+				    u32 InformationBufferLength);
 
-//
-// Function Prototype in rtusb_io.c
-//
-NTSTATUS RTUSBMultiRead(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	OUT	PUCHAR			pData,
-	IN	USHORT			length);
+void RTUSBDequeueCmd(struct rt_cmdq *cmdq, struct rt_cmdqelmt * * pcmdqelmt);
 
-NTSTATUS RTUSBMultiWrite(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	IN	PUCHAR			pData,
-	IN	USHORT			length);
+int RTUSBCmdThread(IN void *Context);
 
-NTSTATUS RTUSBMultiWrite_OneByte(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	IN	PUCHAR			pData);
+void RTUSBBssBeaconExit(struct rt_rtmp_adapter *pAd);
 
-NTSTATUS RTUSBReadBBPRegister(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Id,
-	IN	PUCHAR			pValue);
+void RTUSBBssBeaconStop(struct rt_rtmp_adapter *pAd);
 
-NTSTATUS RTUSBWriteBBPRegister(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Id,
-	IN	UCHAR			Value);
-
-NTSTATUS RTUSBWriteRFRegister(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UINT32			Value);
-
-NTSTATUS RTUSB_VendorRequest(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UINT32			TransferFlags,
-	IN	UCHAR			ReservedBits,
-	IN	UCHAR			Request,
-	IN	USHORT			Value,
-	IN	USHORT			Index,
-	IN	PVOID			TransferBuffer,
-	IN	UINT32			TransferBufferLength);
-
-NTSTATUS RTUSBReadEEPROM(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	OUT	PUCHAR			pData,
-	IN	USHORT			length);
-
-NTSTATUS RTUSBWriteEEPROM(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	IN	PUCHAR			pData,
-	IN	USHORT			length);
-
-VOID RTUSBPutToSleep(
-	IN	PRTMP_ADAPTER	pAd);
-
-NTSTATUS RTUSBWakeUp(
-	IN	PRTMP_ADAPTER	pAd);
-
-VOID RTUSBInitializeCmdQ(
-	IN	PCmdQ	cmdq);
-
-NDIS_STATUS	RTUSBEnqueueCmdFromNdis(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	NDIS_OID		Oid,
-	IN	BOOLEAN			SetInformation,
-	IN	PVOID			pInformationBuffer,
-	IN	UINT32			InformationBufferLength);
-
-NDIS_STATUS RTUSBEnqueueInternalCmd(
-	IN	PRTMP_ADAPTER	pAd,
-	IN NDIS_OID			Oid,
-	IN PVOID			pInformationBuffer,
-	IN UINT32			InformationBufferLength);
-
-VOID RTUSBDequeueCmd(
-	IN	PCmdQ		cmdq,
-	OUT	PCmdQElmt	*pcmdqelmt);
-
-INT RTUSBCmdThread(
-	IN OUT PVOID Context);
-
-INT TimerQThread(
-	IN OUT PVOID Context);
-
-RT2870_TIMER_ENTRY *RT2870_TimerQ_Insert(
-	IN RTMP_ADAPTER *pAd,
-	IN RALINK_TIMER_STRUCT *pTimer);
-
-BOOLEAN RT2870_TimerQ_Remove(
-	IN RTMP_ADAPTER *pAd,
-	IN RALINK_TIMER_STRUCT *pTimer);
-
-void RT2870_TimerQ_Exit(
-	IN RTMP_ADAPTER *pAd);
-
-void RT2870_TimerQ_Init(
-	IN RTMP_ADAPTER *pAd);
-
-VOID RT2870_BssBeaconExit(
-	IN RTMP_ADAPTER *pAd);
+void RTUSBBssBeaconStart(struct rt_rtmp_adapter *pAd);
 
-VOID RT2870_BssBeaconStop(
-	IN RTMP_ADAPTER *pAd);
+void RTUSBBssBeaconInit(struct rt_rtmp_adapter *pAd);
 
-VOID RT2870_BssBeaconStart(
-	IN RTMP_ADAPTER * pAd);
+void RTUSBWatchDog(struct rt_rtmp_adapter *pAd);
 
-VOID RT2870_BssBeaconInit(
-	IN RTMP_ADAPTER *pAd);
+int RTUSBWriteMACRegister(struct rt_rtmp_adapter *pAd,
+			       u16 Offset, u32 Value);
 
-VOID RT2870_WatchDog(
-	IN RTMP_ADAPTER *pAd);
+int RTUSBReadMACRegister(struct rt_rtmp_adapter *pAd,
+			      u16 Offset, u32 *pValue);
 
-NTSTATUS RTUSBWriteMACRegister(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	IN	UINT32			Value);
+int RTUSBSingleWrite(struct rt_rtmp_adapter *pAd,
+			  u16 Offset, u16 Value);
 
-NTSTATUS RTUSBReadMACRegister(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	OUT	PUINT32			pValue);
+int RTUSBFirmwareWrite(struct rt_rtmp_adapter *pAd,
+			    u8 *pFwImage, unsigned long FwLen);
 
-NTSTATUS RTUSBSingleWrite(
-	IN 	RTMP_ADAPTER 	*pAd,
-	IN	USHORT			Offset,
-	IN	USHORT			Value);
+int RTUSBVenderReset(struct rt_rtmp_adapter *pAd);
 
-NTSTATUS RTUSBFirmwareRun(
-	IN	PRTMP_ADAPTER	pAd);
+int RTUSBSetHardWareRegister(struct rt_rtmp_adapter *pAdapter, void *pBuf);
 
-NTSTATUS RTUSBFirmwareWrite(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR		pFwImage,
-	IN ULONG		FwLen);
+int RTUSBQueryHardWareRegister(struct rt_rtmp_adapter *pAdapter,
+				       void *pBuf);
 
-NTSTATUS	RTUSBFirmwareOpmode(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUINT32			pValue);
+void CMDHandler(struct rt_rtmp_adapter *pAd);
 
-NTSTATUS	RTUSBVenderReset(
-	IN	PRTMP_ADAPTER	pAd);
+int RTUSBWriteHWMACAddress(struct rt_rtmp_adapter *pAdapter);
 
-VOID CMDHandler(
-    IN PRTMP_ADAPTER pAd);
+void MacTableInitialize(struct rt_rtmp_adapter *pAd);
 
+void MlmeSetPsm(struct rt_rtmp_adapter *pAd, u16 psm);
 
-NDIS_STATUS	 CreateThreads(
-	IN	struct net_device *net_dev );
+int RTMPWPAAddKeyProc(struct rt_rtmp_adapter *pAd, void *pBuf);
 
+void AsicRxAntEvalAction(struct rt_rtmp_adapter *pAd);
 
-VOID MacTableInitialize(
-	IN  PRTMP_ADAPTER   pAd);
+void append_pkt(struct rt_rtmp_adapter *pAd,
+		u8 *pHeader802_3,
+		u32 HdrLen,
+		u8 *pData,
+		unsigned long DataSize, void ** ppPacket);
 
-VOID MlmeSetPsm(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT psm);
+u32 deaggregate_AMSDU_announce(struct rt_rtmp_adapter *pAd,
+				void *pPacket,
+				u8 *pData, unsigned long DataSize);
 
-NDIS_STATUS RTMPWPAAddKeyProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PVOID           pBuf);
+int RTMPCheckRxError(struct rt_rtmp_adapter *pAd,
+			     struct rt_header_802_11 * pHeader,
+			     struct rt_rxwi * pRxWI,
+			     IN PRT28XX_RXD_STRUC pRxINFO);
 
-VOID AsicRxAntEvalAction(
-	IN PRTMP_ADAPTER pAd);
+void RTUSBMlmeHardTransmit(struct rt_rtmp_adapter *pAd, struct rt_mgmt *pMgmt);
 
-NDIS_STATUS	RTMPCheckRxError(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PHEADER_802_11	pHeader,
-	IN	PRXWI_STRUC	pRxWI,
-	IN	PRT28XX_RXD_STRUC	pRxINFO);
+int MlmeThread(void *Context);
 
-INT MlmeThread(
-	IN PVOID Context);
+/* */
+/* Function Prototype in rtusb_data.c */
+/* */
+int RTUSBFreeDescriptorRequest(struct rt_rtmp_adapter *pAd,
+				       u8 BulkOutPipeId,
+				       u32 NumberRequired);
 
-//
-// Function Prototype in rtusb_data.c
-//
-NDIS_STATUS	RTUSBFreeDescriptorRequest(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			BulkOutPipeId,
-	IN	UINT32			NumberRequired);
+BOOLEAN RTUSBNeedQueueBackForAgg(struct rt_rtmp_adapter *pAd, u8 BulkOutPipeId);
 
+void RTMPWriteTxInfo(struct rt_rtmp_adapter *pAd,
+		     struct rt_txinfo *pTxInfo,
+		     u16 USBDMApktLen,
+		     IN BOOLEAN bWiv,
+		     u8 QueueSel, u8 NextValid, u8 TxBurst);
 
-BOOLEAN	RTUSBNeedQueueBackForAgg(
-	IN RTMP_ADAPTER *pAd,
-	IN UCHAR		BulkOutPipeId);
+/* */
+/* Function Prototype in cmm_data_usb.c */
+/* */
+u16 RtmpUSB_WriteSubTxResource(struct rt_rtmp_adapter *pAd,
+				  struct rt_tx_blk *pTxBlk,
+				  IN BOOLEAN bIsLast, u16 * FreeNumber);
 
+u16 RtmpUSB_WriteSingleTxResource(struct rt_rtmp_adapter *pAd,
+				     struct rt_tx_blk *pTxBlk,
+				     IN BOOLEAN bIsLast,
+				     u16 * FreeNumber);
 
-VOID RTMPWriteTxInfo(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PTXINFO_STRUC 	pTxInfo,
-	IN	  USHORT		USBDMApktLen,
-	IN	  BOOLEAN		bWiv,
-	IN	  UCHAR			QueueSel,
-	IN	  UCHAR			NextValid,
-	IN	  UCHAR			TxBurst);
+u16 RtmpUSB_WriteFragTxResource(struct rt_rtmp_adapter *pAd,
+				   struct rt_tx_blk *pTxBlk,
+				   u8 fragNum, u16 * FreeNumber);
 
-//
-// Function Prototype in cmm_data_2870.c
-//
-USHORT RtmpUSB_WriteSubTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	BOOLEAN			bIsLast,
-	OUT	USHORT			*FreeNumber);
+u16 RtmpUSB_WriteMultiTxResource(struct rt_rtmp_adapter *pAd,
+				    struct rt_tx_blk *pTxBlk,
+				    u8 frameNum, u16 * FreeNumber);
 
-USHORT RtmpUSB_WriteSingleTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	BOOLEAN			bIsLast,
-	OUT	USHORT			*FreeNumber);
+void RtmpUSB_FinalWriteTxResource(struct rt_rtmp_adapter *pAd,
+				  struct rt_tx_blk *pTxBlk,
+				  u16 totalMPDUSize, u16 TxIdx);
 
-USHORT	RtmpUSB_WriteFragTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	UCHAR			fragNum,
-	OUT	USHORT			*FreeNumber);
+void RtmpUSBDataLastTxIdx(struct rt_rtmp_adapter *pAd,
+			  u8 QueIdx, u16 TxIdx);
 
-USHORT RtmpUSB_WriteMultiTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	UCHAR			frameNum,
-	OUT	USHORT			*FreeNumber);
+void RtmpUSBDataKickOut(struct rt_rtmp_adapter *pAd,
+			struct rt_tx_blk *pTxBlk, u8 QueIdx);
 
-VOID RtmpUSB_FinalWriteTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	USHORT			totalMPDUSize,
-#ifdef RT2860
-	IN	USHORT			FirstTxIdx);
-#endif
-	IN	USHORT			TxIdx);
+int RtmpUSBMgmtKickOut(struct rt_rtmp_adapter *pAd,
+		       u8 QueIdx,
+		       void *pPacket,
+		       u8 *pSrcBufVA, u32 SrcBufLen);
 
-VOID RtmpUSBDataLastTxIdx(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			QueIdx,
-	IN	USHORT			TxIdx);
+void RtmpUSBNullFrameKickOut(struct rt_rtmp_adapter *pAd,
+			     u8 QueIdx,
+			     u8 * pNullFrame, u32 frameLen);
 
-VOID RtmpUSBDataKickOut(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	UCHAR			QueIdx);
+void RtmpUsbStaAsicForceWakeupTimeout(void *SystemSpecific1,
+				      void *FunctionContext,
+				      void *SystemSpecific2,
+				      void *SystemSpecific3);
 
+void RT28xxUsbStaAsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx);
 
-int RtmpUSBMgmtKickOut(
-	IN RTMP_ADAPTER 	*pAd,
-	IN UCHAR 			QueIdx,
-	IN PNDIS_PACKET		pPacket,
-	IN PUCHAR			pSrcBufVA,
-	IN UINT 			SrcBufLen);
+void RT28xxUsbStaAsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd,
+					 u16 TbttNumToNextWakeUp);
 
-VOID RtmpUSBNullFrameKickOut(
-	IN RTMP_ADAPTER *pAd,
-	IN UCHAR		QueIdx,
-	IN UCHAR		*pNullFrame,
-	IN UINT32		frameLen);
+void RT28xxUsbMlmeRadioOn(struct rt_rtmp_adapter *pAd);
 
-VOID RT28xxUsbStaAsicForceWakeup(
-	IN PRTMP_ADAPTER pAd,
-	IN BOOLEAN       bFromTx);
+void RT28xxUsbMlmeRadioOFF(struct rt_rtmp_adapter *pAd);
+#endif /* RTMP_MAC_USB // */
 
-VOID RT28xxUsbStaAsicSleepThenAutoWakeup(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT TbttNumToNextWakeUp);
+void AsicTurnOffRFClk(struct rt_rtmp_adapter *pAd, u8 Channel);
 
-VOID RT28xxUsbMlmeRadioOn(
-	IN PRTMP_ADAPTER pAd);
+void AsicTurnOnRFClk(struct rt_rtmp_adapter *pAd, u8 Channel);
 
-VOID RT28xxUsbMlmeRadioOFF(
-	IN PRTMP_ADAPTER pAd);
-#endif // RT2870 //
+#ifdef RTMP_TIMER_TASK_SUPPORT
+int RtmpTimerQThread(IN void *Context);
 
-INT RTMPShowCfgValue(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pName,
-	IN	PUCHAR			pBuf);
+struct rt_rtmp_timer_task_entry *RtmpTimerQInsert(struct rt_rtmp_adapter *pAd,
+					struct rt_ralink_timer *pTimer);
 
-PCHAR   RTMPGetRalinkAuthModeStr(
-    IN  NDIS_802_11_AUTHENTICATION_MODE authMode);
+BOOLEAN RtmpTimerQRemove(struct rt_rtmp_adapter *pAd,
+			 struct rt_ralink_timer *pTimer);
 
-PCHAR   RTMPGetRalinkEncryModeStr(
-    IN  USHORT encryMode);
+void RtmpTimerQExit(struct rt_rtmp_adapter *pAd);
 
-VOID AsicStaBbpTuning(
-	IN PRTMP_ADAPTER pAd);
+void RtmpTimerQInit(struct rt_rtmp_adapter *pAd);
+#endif /* RTMP_TIMER_TASK_SUPPORT // */
 
-#ifdef RT2860
-VOID AsicResetFromDMABusy(
-	IN PRTMP_ADAPTER pAd);
+void AsicStaBbpTuning(struct rt_rtmp_adapter *pAd);
 
-VOID AsicResetBBP(
-	IN PRTMP_ADAPTER pAd);
+BOOLEAN StaAddMacTableEntry(struct rt_rtmp_adapter *pAd,
+			    struct rt_mac_table_entry *pEntry,
+			    u8 MaxSupportedRateIn500Kbps,
+			    struct rt_ht_capability_ie * pHtCapability,
+			    u8 HtCapabilityLen,
+			    struct rt_add_ht_info_ie * pAddHtInfo,
+			    u8 AddHtInfoLen, u16 CapabilityInfo);
 
-VOID AsicResetMAC(
-	IN PRTMP_ADAPTER pAd);
+BOOLEAN AUTH_ReqSend(struct rt_rtmp_adapter *pAd,
+		     struct rt_mlme_queue_elem *pElem,
+		     struct rt_ralink_timer *pAuthTimer,
+		     char *pSMName,
+		     u16 SeqNo,
+		     u8 *pNewElement, unsigned long ElementLen);
 
-VOID AsicResetPBF(
-	IN PRTMP_ADAPTER pAd);
-#endif
-#ifdef RT2870
-BOOLEAN StaAddMacTableEntry(
-	IN  PRTMP_ADAPTER		pAd,
-	IN  PMAC_TABLE_ENTRY	pEntry,
-	IN  UCHAR				MaxSupportedRateIn500Kbps,
-	IN  HT_CAPABILITY_IE	*pHtCapability,
-	IN  UCHAR				HtCapabilityLen,
-	IN  USHORT        		CapabilityInfo);
-#endif
+void RTMP_IndicateMediaState(struct rt_rtmp_adapter *pAd);
 
-void RTMP_IndicateMediaState(
-	IN	PRTMP_ADAPTER	pAd);
+void ReSyncBeaconTime(struct rt_rtmp_adapter *pAd);
 
-VOID ReSyncBeaconTime(
-	IN  PRTMP_ADAPTER   pAd);
+void RTMPSetAGCInitValue(struct rt_rtmp_adapter *pAd, u8 BandWidth);
 
-VOID RTMPSetAGCInitValue(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			BandWidth);
+int rt28xx_close(struct net_device *dev);
+int rt28xx_open(struct net_device *dev);
 
-int rt28xx_close(IN PNET_DEV dev);
-int rt28xx_open(IN PNET_DEV dev);
+#define VIRTUAL_IF_INC(__pAd) ((__pAd)->VirtualIfCnt++)
+#define VIRTUAL_IF_DEC(__pAd) ((__pAd)->VirtualIfCnt--)
+#define VIRTUAL_IF_NUM(__pAd) ((__pAd)->VirtualIfCnt)
 
-__inline INT VIRTUAL_IF_UP(PRTMP_ADAPTER pAd)
+#ifdef LINUX
+__inline int VIRTUAL_IF_UP(struct rt_rtmp_adapter *pAd)
 {
-	if (VIRTUAL_IF_NUM(pAd) == 0)
-	{
-		if (rt28xx_open(pAd->net_dev) != 0)
+	if (VIRTUAL_IF_NUM(pAd) == 0) {
+		if (rt28xx_open(pAd->net_dev) != 0) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("rt28xx_open return fail!\n"));
 			return -1;
-	}
-	else
-	{
+		}
+	} else {
 	}
 	VIRTUAL_IF_INC(pAd);
 	return 0;
 }
 
-__inline VOID VIRTUAL_IF_DOWN(PRTMP_ADAPTER pAd)
+__inline void VIRTUAL_IF_DOWN(struct rt_rtmp_adapter *pAd)
 {
 	VIRTUAL_IF_DEC(pAd);
 	if (VIRTUAL_IF_NUM(pAd) == 0)
 		rt28xx_close(pAd->net_dev);
 	return;
 }
+#endif /* LINUX // */
 
+/*
+	OS Related funciton prototype definitions.
+	TODO: Maybe we need to move these function prototypes to other proper place.
+*/
+int RtmpOSWrielessEventSend(struct rt_rtmp_adapter *pAd,
+			    u32 eventType,
+			    int flags,
+			    u8 *pSrcMac,
+			    u8 *pData, u32 dataLen);
 
-#endif  // __RTMP_H__
+int RtmpOSNetDevAddrSet(struct net_device *pNetDev, u8 *pMacAddr);
 
+int RtmpOSNetDevAttach(struct net_device *pNetDev,
+		       struct rt_rtmp_os_netdev_op_hook *pDevOpHook);
+
+void RtmpOSNetDevClose(struct net_device *pNetDev);
+
+void RtmpOSNetDevDetach(struct net_device *pNetDev);
+
+int RtmpOSNetDevAlloc(struct net_device ** pNewNetDev, u32 privDataSize);
+
+void RtmpOSNetDevFree(struct net_device *pNetDev);
+
+struct net_device *RtmpOSNetDevGetByName(struct net_device *pNetDev, char *pDevName);
+
+void RtmpOSNetDeviceRefPut(struct net_device *pNetDev);
+
+struct net_device *RtmpOSNetDevCreate(struct rt_rtmp_adapter *pAd,
+			    int devType,
+			    int devNum,
+			    int privMemSize, char *pNamePrefix);
+
+/*
+	Task operation related function prototypes
+*/
+void RtmpOSTaskCustomize(struct rt_rtmp_os_task *pTask);
+
+int RtmpOSTaskNotifyToExit(struct rt_rtmp_os_task *pTask);
+
+int RtmpOSTaskKill(struct rt_rtmp_os_task *pTask);
+
+int RtmpOSTaskInit(struct rt_rtmp_os_task *pTask,
+			   char *pTaskName, void * pPriv);
+
+int RtmpOSTaskAttach(struct rt_rtmp_os_task *pTask,
+			     IN int (*fn) (void *), IN void *arg);
+
+/*
+	File operation related function prototypes
+*/
+struct file *RtmpOSFileOpen(IN char *pPath, IN int flag, IN int mode);
+
+int RtmpOSFileClose(struct file *osfd);
+
+void RtmpOSFileSeek(struct file *osfd, IN int offset);
+
+int RtmpOSFileRead(struct file *osfd, IN char *pDataPtr, IN int readLen);
+
+int RtmpOSFileWrite(struct file *osfd, IN char *pDataPtr, IN int writeLen);
+
+#endif /* __RTMP_H__ */
diff --git a/drivers/staging/rt2860/rtmp_chip.h b/drivers/staging/rt2860/rtmp_chip.h
new file mode 100644
index 0000000..0adf2cd
--- /dev/null
+++ b/drivers/staging/rt2860/rtmp_chip.h
@@ -0,0 +1,258 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rtmp_chip.h
+
+	Abstract:
+	Ralink Wireless Chip related definition & structures
+
+	Revision History:
+	Who			When		  What
+	--------	----------	  ----------------------------------------------
+*/
+
+#ifndef	__RTMP_CHIP_H__
+#define	__RTMP_CHIP_H__
+
+#include "rtmp_type.h"
+
+#ifdef RT2860
+#include "chip/rt2860.h"
+#endif /* RT2860 // */
+#ifdef RT2870
+#include "chip/rt2870.h"
+#endif /* RT2870 // */
+#ifdef RT3070
+#include "chip/rt3070.h"
+#endif /* RT3070 // */
+#ifdef RT3090
+#include "chip/rt3090.h"
+#endif /* RT3090 // */
+
+/* We will have a cost down version which mac version is 0x3090xxxx */
+/* */
+/* RT3090A facts */
+/* */
+/* a) 2.4 GHz */
+/* b) Replacement for RT3090 */
+/* c) Internal LNA */
+/* d) Interference over channel #14 */
+/* e) New BBP features (e.g., SIG re-modulation) */
+/* */
+#define IS_RT3090A(_pAd)				((((_pAd)->MACVersion & 0xffff0000) == 0x30900000))
+
+/* We will have a cost down version which mac version is 0x3090xxxx */
+#define IS_RT3090(_pAd)				((((_pAd)->MACVersion & 0xffff0000) == 0x30710000) || (IS_RT3090A(_pAd)))
+
+#define IS_RT3070(_pAd)		(((_pAd)->MACVersion & 0xffff0000) == 0x30700000)
+#define IS_RT3071(_pAd)		(((_pAd)->MACVersion & 0xffff0000) == 0x30710000)
+#define IS_RT2070(_pAd)		(((_pAd)->RfIcType == RFIC_2020) || ((_pAd)->EFuseTag == 0x27))
+
+#define IS_RT30xx(_pAd)		(((_pAd)->MACVersion & 0xfff00000) == 0x30700000||IS_RT3090A(_pAd))
+/*#define IS_RT305X(_pAd)               ((_pAd)->MACVersion == 0x28720200) */
+
+/* RT3572, 3592, 3562, 3062 share the same MAC version */
+#define IS_RT3572(_pAd)		(((_pAd)->MACVersion & 0xffff0000) == 0x35720000)
+#define IS_VERSION_BEFORE_F(_pAd)			(((_pAd)->MACVersion&0xffff) <= 0x0211)
+/* F version is 0x0212, E version is 0x0211. 309x can save more power after F version. */
+#define IS_VERSION_AFTER_F(_pAd)			((((_pAd)->MACVersion&0xffff) >= 0x0212) || (((_pAd)->b3090ESpecialChip == TRUE)))
+/* */
+/* RT3390 facts */
+/* */
+/* a) Base on RT3090 (RF IC: RT3020) */
+/* b) 2.4 GHz */
+/* c) 1x1 */
+/* d) Single chip */
+/* e) Internal components: PA and LNA */
+/* */
+/*RT3390,RT3370 */
+#define IS_RT3390(_pAd)				(((_pAd)->MACVersion & 0xFFFF0000) == 0x33900000)
+
+/* ------------------------------------------------------ */
+/* PCI registers - base address 0x0000 */
+/* ------------------------------------------------------ */
+#define CHIP_PCI_CFG		0x0000
+#define CHIP_PCI_EECTRL		0x0004
+#define CHIP_PCI_MCUCTRL	0x0008
+
+#define OPT_14			0x114
+
+#define RETRY_LIMIT		10
+
+/* ------------------------------------------------------ */
+/* BBP & RF     definition */
+/* ------------------------------------------------------ */
+#define	BUSY		                1
+#define	IDLE		                0
+
+/*------------------------------------------------------------------------- */
+/* EEPROM definition */
+/*------------------------------------------------------------------------- */
+#define EEDO                        0x08
+#define EEDI                        0x04
+#define EECS                        0x02
+#define EESK                        0x01
+#define EERL                        0x80
+
+#define EEPROM_WRITE_OPCODE         0x05
+#define EEPROM_READ_OPCODE          0x06
+#define EEPROM_EWDS_OPCODE          0x10
+#define EEPROM_EWEN_OPCODE          0x13
+
+#define NUM_EEPROM_BBP_PARMS		19	/* Include NIC Config 0, 1, CR, TX ALC step, BBPs */
+#define NUM_EEPROM_TX_G_PARMS		7
+#define EEPROM_NIC1_OFFSET          0x34	/* The address is from NIC config 0, not BBP register ID */
+#define EEPROM_NIC2_OFFSET          0x36	/* The address is from NIC config 0, not BBP register ID */
+#define EEPROM_BBP_BASE_OFFSET		0xf0	/* The address is from NIC config 0, not BBP register ID */
+#define EEPROM_G_TX_PWR_OFFSET		0x52
+#define EEPROM_G_TX2_PWR_OFFSET		0x60
+#define EEPROM_LED1_OFFSET			0x3c
+#define EEPROM_LED2_OFFSET			0x3e
+#define EEPROM_LED3_OFFSET			0x40
+#define EEPROM_LNA_OFFSET			0x44
+#define EEPROM_RSSI_BG_OFFSET		0x46
+#define EEPROM_TXMIXER_GAIN_2_4G	0x48
+#define EEPROM_RSSI_A_OFFSET		0x4a
+#define EEPROM_TXMIXER_GAIN_5G		0x4c
+#define EEPROM_DEFINE_MAX_TXPWR		0x4e
+#define EEPROM_TXPOWER_BYRATE_20MHZ_2_4G	0xde	/* 20MHZ 2.4G tx power. */
+#define EEPROM_TXPOWER_BYRATE_40MHZ_2_4G	0xee	/* 40MHZ 2.4G tx power. */
+#define EEPROM_TXPOWER_BYRATE_20MHZ_5G		0xfa	/* 20MHZ 5G tx power. */
+#define EEPROM_TXPOWER_BYRATE_40MHZ_5G		0x10a	/* 40MHZ 5G tx power. */
+#define EEPROM_A_TX_PWR_OFFSET      0x78
+#define EEPROM_A_TX2_PWR_OFFSET      0xa6
+/*#define EEPROM_Japan_TX_PWR_OFFSET      0x90 // 802.11j */
+/*#define EEPROM_Japan_TX2_PWR_OFFSET      0xbe */
+/*#define EEPROM_TSSI_REF_OFFSET        0x54 */
+/*#define EEPROM_TSSI_DELTA_OFFSET      0x24 */
+/*#define EEPROM_CCK_TX_PWR_OFFSET  0x62 */
+/*#define EEPROM_CALIBRATE_OFFSET       0x7c */
+#define EEPROM_VERSION_OFFSET       0x02
+#define EEPROM_FREQ_OFFSET			0x3a
+#define EEPROM_TXPOWER_BYRATE	0xde	/* 20MHZ power. */
+#define EEPROM_TXPOWER_DELTA		0x50	/* 20MHZ AND 40 MHZ use different power. This is delta in 40MHZ. */
+#define VALID_EEPROM_VERSION        1
+
+/*
+  *   EEPROM operation related marcos
+  */
+#define RT28xx_EEPROM_READ16(_pAd, _offset, _value)			\
+	(_pAd)->chipOps.eeread((struct rt_rtmp_adapter *)(_pAd), (u16)(_offset), (u16 *)&(_value))
+
+/* ------------------------------------------------------------------- */
+/*  E2PROM data layout */
+/* ------------------------------------------------------------------- */
+
+/* */
+/* MCU_LEDCS: MCU LED Control Setting. */
+/* */
+typedef union _MCU_LEDCS_STRUC {
+	struct {
+		u8 LedMode:7;
+		u8 Polarity:1;
+	} field;
+	u8 word;
+} MCU_LEDCS_STRUC, *PMCU_LEDCS_STRUC;
+
+/* */
+/* EEPROM antenna select format */
+/* */
+typedef union _EEPROM_ANTENNA_STRUC {
+	struct {
+		u16 RxPath:4;	/* 1: 1R, 2: 2R, 3: 3R */
+		u16 TxPath:4;	/* 1: 1T, 2: 2T */
+		u16 RfIcType:4;	/* see E2PROM document */
+		u16 Rsv:4;
+	} field;
+	u16 word;
+} EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC;
+
+typedef union _EEPROM_NIC_CINFIG2_STRUC {
+	struct {
+		u16 HardwareRadioControl:1;	/* 1:enable, 0:disable */
+		u16 DynamicTxAgcControl:1;	/* */
+		u16 ExternalLNAForG:1;	/* */
+		u16 ExternalLNAForA:1;	/* external LNA enable for 2.4G */
+		u16 CardbusAcceleration:1;	/* ! NOTE: 0 - enable, 1 - disable */
+		u16 BW40MSidebandForG:1;
+		u16 BW40MSidebandForA:1;
+		u16 EnableWPSPBC:1;	/* WPS PBC Control bit */
+		u16 BW40MAvailForG:1;	/* 0:enable, 1:disable */
+		u16 BW40MAvailForA:1;	/* 0:enable, 1:disable */
+		u16 Rsv1:1;	/* must be 0 */
+		u16 AntDiversity:1;	/* Antenna diversity */
+		u16 Rsv2:3;	/* must be 0 */
+		u16 DACTestBit:1;	/* control if driver should patch the DAC issue */
+	} field;
+	u16 word;
+} EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC;
+
+/* */
+/* TX_PWR Value valid range 0xFA(-6) ~ 0x24(36) */
+/* */
+typedef union _EEPROM_TX_PWR_STRUC {
+	struct {
+		char Byte0;	/* Low Byte */
+		char Byte1;	/* High Byte */
+	} field;
+	u16 word;
+} EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC;
+
+typedef union _EEPROM_VERSION_STRUC {
+	struct {
+		u8 FaeReleaseNumber;	/* Low Byte */
+		u8 Version;	/* High Byte */
+	} field;
+	u16 word;
+} EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC;
+
+typedef union _EEPROM_LED_STRUC {
+	struct {
+		u16 PolarityRDY_G:1;	/* Polarity RDY_G setting. */
+		u16 PolarityRDY_A:1;	/* Polarity RDY_A setting. */
+		u16 PolarityACT:1;	/* Polarity ACT setting. */
+		u16 PolarityGPIO_0:1;	/* Polarity GPIO#0 setting. */
+		u16 PolarityGPIO_1:1;	/* Polarity GPIO#1 setting. */
+		u16 PolarityGPIO_2:1;	/* Polarity GPIO#2 setting. */
+		u16 PolarityGPIO_3:1;	/* Polarity GPIO#3 setting. */
+		u16 PolarityGPIO_4:1;	/* Polarity GPIO#4 setting. */
+		u16 LedMode:5;	/* Led mode. */
+		u16 Rsvd:3;	/* Reserved */
+	} field;
+	u16 word;
+} EEPROM_LED_STRUC, *PEEPROM_LED_STRUC;
+
+typedef union _EEPROM_TXPOWER_DELTA_STRUC {
+	struct {
+		u8 DeltaValue:6;	/* Tx Power dalta value (MAX=4) */
+		u8 Type:1;	/* 1: plus the delta value, 0: minus the delta value */
+		u8 TxPowerEnable:1;	/* Enable */
+	} field;
+	u8 value;
+} EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC;
+
+#endif /* __RTMP_CHIP_H__ // */
diff --git a/drivers/staging/rt2860/rtmp_ckipmic.h b/drivers/staging/rt2860/rtmp_ckipmic.h
index 39955b9..6ff935d 100644
--- a/drivers/staging/rt2860/rtmp_ckipmic.h
+++ b/drivers/staging/rt2860/rtmp_ckipmic.h
@@ -37,42 +37,27 @@
 #ifndef	__RTMP_CKIPMIC_H__
 #define	__RTMP_CKIPMIC_H__
 
-typedef	struct	_MIC_CONTEXT	{
+struct rt_mic_context {
 	/* --- MMH context                            */
-	UCHAR		CK[16];				/* the key                                    */
-	UCHAR		coefficient[16];	/* current aes counter mode coefficients      */
-	ULONGLONG	accum;				/* accumulated mic, reduced to u32 in final() */
-	UINT		position;			/* current position (byte offset) in message  */
-	UCHAR		part[4];			/* for conversion of message to u32 for mmh   */
-}	MIC_CONTEXT, *PMIC_CONTEXT;
+	u8 CK[16];		/* the key                                    */
+	u8 coefficient[16];	/* current aes counter mode coefficients      */
+	unsigned long long accum;	/* accumulated mic, reduced to u32 in final() */
+	u32 position;		/* current position (byte offset) in message  */
+	u8 part[4];		/* for conversion of message to u32 for mmh   */
+};
 
-VOID xor_128(
-    IN  PUCHAR              a,
-    IN  PUCHAR              b,
-    OUT PUCHAR              out);
+void xor_128(u8 *a, u8 *b, u8 *out);
 
-UCHAR RTMPCkipSbox(
-    IN  UCHAR               a);
+u8 RTMPCkipSbox(u8 a);
 
-VOID xor_32(
-    IN  PUCHAR              a,
-    IN  PUCHAR              b,
-    OUT PUCHAR              out);
+void xor_32(u8 *a, u8 *b, u8 *out);
 
-VOID next_key(
-    IN  PUCHAR              key,
-    IN  INT                 round);
+void next_key(u8 *key, int round);
 
-VOID byte_sub(
-    IN  PUCHAR              in,
-    OUT PUCHAR              out);
+void byte_sub(u8 *in, u8 *out);
 
-VOID shift_row(
-    IN  PUCHAR              in,
-    OUT PUCHAR              out);
+void shift_row(u8 *in, u8 *out);
 
-VOID mix_column(
-    IN  PUCHAR              in,
-    OUT PUCHAR              out);
+void mix_column(u8 *in, u8 *out);
 
-#endif //__RTMP_CKIPMIC_H__
+#endif /*__RTMP_CKIPMIC_H__ */
diff --git a/drivers/staging/rt2860/rtmp_def.h b/drivers/staging/rt2860/rtmp_def.h
index f5fee57..9c54bac 100644
--- a/drivers/staging/rt2860/rtmp_def.h
+++ b/drivers/staging/rt2860/rtmp_def.h
@@ -41,9 +41,9 @@
 
 #include "oid.h"
 
-//
-//  Debug information verbosity: lower values indicate higher urgency
-//
+/* */
+/*  Debug information verbosity: lower values indicate higher urgency */
+/* */
 #define RT_DEBUG_OFF        0
 #define RT_DEBUG_ERROR      1
 #define RT_DEBUG_WARN       2
@@ -51,111 +51,101 @@
 #define RT_DEBUG_INFO       4
 #define RT_DEBUG_LOUD       5
 
-#define NIC_TAG             ((ULONG)'0682')
-#define NIC_DBG_STRING      ("**RT28xx**")
+#define NIC_TAG             ((unsigned long)'0682')
+#define NIC_DBG_char      ("**RT28xx**")
 
-#define RALINK_2883_VERSION		((UINT32)0x28830300)
-#define RALINK_2880E_VERSION	((UINT32)0x28720200)
-#define RALINK_3070_VERSION		((UINT32)0x30700200)
-
-//
-// NDIS version in use by the NIC driver.
-// The high byte is the major version. The low byte is the minor version.
-//
-#ifdef  NDIS51_MINIPORT
-#define NIC_DRIVER_VERSION      0x0501
-#else
-#define NIC_DRIVER_VERSION      0x0500
-#endif
-
-//
-// NDIS media type, current is ethernet, change if native wireless supported
-//
-#define NIC_MEDIA_TYPE          NdisMedium802_3
-#define NIC_PCI_HDR_LENGTH      0xe2
-#define NIC_MAX_PACKET_SIZE     2304
-#define NIC_HEADER_SIZE         14
-#define MAX_MAP_REGISTERS_NEEDED 32
-#define MIN_MAP_REGISTERS_NEEDED 2   //Todo: should consider fragment issue.
-
-//
-// interface type, we use PCI
-//
-#define NIC_INTERFACE_TYPE      NdisInterfacePci
-#define NIC_INTERRUPT_MODE      NdisInterruptLevelSensitive
-
-//
-// buffer size passed in NdisMQueryAdapterResources
-// We should only need three adapter resources (IO, interrupt and memory),
-// Some devices get extra resources, so have room for 10 resources
-//                    UF_SIZE   (sizeof(NDIS_RESOURCE_LIST) + (10*sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)))
-
-
-#define NIC_RESOURCE_B//
-// IO space length
-//
-#define NIC_MAP_IOSPACE_LENGTH  sizeof(CSR_STRUC)
-
-#define MAX_RX_PKT_LEN	1520
-
-//
-// Entry number for each DMA descriptor ring
-//
-
-#ifdef RT2860
-#define TX_RING_SIZE            64 //64
-#define MGMT_RING_SIZE          128
-#define RX_RING_SIZE            128 //64
-#define MAX_TX_PROCESS          TX_RING_SIZE //8
-#define MAX_DMA_DONE_PROCESS    TX_RING_SIZE
-#define MAX_TX_DONE_PROCESS     TX_RING_SIZE //8
-#define LOCAL_TXBUF_SIZE        2
-#endif
-#ifdef RT2870
-#define TX_RING_SIZE            8 // 1
+#ifdef RTMP_MAC_USB
+#define TX_RING_SIZE            8	/* 1 */
 #define PRIO_RING_SIZE          8
-#define MGMT_RING_SIZE       32 // PRIO_RING_SIZE
+#define MGMT_RING_SIZE		32	/* PRIO_RING_SIZE */
 #define RX_RING_SIZE            8
 #define MAX_TX_PROCESS          4
 #define LOCAL_TXBUF_SIZE        2048
-#endif // RT2870 //
+#endif /* RTMP_MAC_USB // */
 
-#define MAX_RX_PROCESS          128 //64 //32
+/*#define PACKED */
+
+#define RALINK_2883_VERSION		((u32)0x28830300)
+#define RALINK_2880E_VERSION	((u32)0x28720200)
+#define RALINK_3070_VERSION		((u32)0x30700200)
+
+#define MAX_RX_PKT_LEN	1520
+
+/* */
+/* Entry number for each DMA descriptor ring */
+/* */
+
+#ifdef RTMP_MAC_PCI
+#define TX_RING_SIZE            64	/*64 */
+#define MGMT_RING_SIZE          128
+#define RX_RING_SIZE            128	/*64 */
+#define MAX_TX_PROCESS          TX_RING_SIZE	/*8 */
+#define MAX_DMA_DONE_PROCESS    TX_RING_SIZE
+#define MAX_TX_DONE_PROCESS     TX_RING_SIZE	/*8 */
+#define LOCAL_TXBUF_SIZE        2
+#endif /* RTMP_MAC_PCI // */
+
+#define MAX_RX_PROCESS          128	/*64 //32 */
 #define NUM_OF_LOCAL_TXBUF      2
 #define TXD_SIZE                16
 #define TXWI_SIZE               16
 #define RXD_SIZE               	16
 #define RXWI_SIZE             	16
-// TXINFO_SIZE + TXWI_SIZE + 802.11 Header Size + AMSDU sub frame header
-#define TX_DMA_1ST_BUFFER_SIZE  96    // only the 1st physical buffer is pre-allocated
-#define MGMT_DMA_BUFFER_SIZE    1536 //2048
-#define RX_BUFFER_AGGRESIZE     3840 //3904 //3968 //4096 //2048 //4096
-#define RX_BUFFER_NORMSIZE      3840 //3904 //3968 //4096 //2048 //4096
+/* TXINFO_SIZE + TXWI_SIZE + 802.11 Header Size + AMSDU sub frame header */
+#define TX_DMA_1ST_BUFFER_SIZE  96	/* only the 1st physical buffer is pre-allocated */
+#define MGMT_DMA_BUFFER_SIZE    1536	/*2048 */
+#define RX_BUFFER_AGGRESIZE     3840	/*3904 //3968 //4096 //2048 //4096 */
+#define RX_BUFFER_NORMSIZE      3840	/*3904 //3968 //4096 //2048 //4096 */
 #define TX_BUFFER_NORMSIZE		RX_BUFFER_NORMSIZE
-#define MAX_FRAME_SIZE          2346                    // Maximum 802.11 frame size
-#define MAX_AGGREGATION_SIZE    3840 //3904 //3968 //4096
+#define MAX_FRAME_SIZE          2346	/* Maximum 802.11 frame size */
+#define MAX_AGGREGATION_SIZE    3840	/*3904 //3968 //4096 */
 #define MAX_NUM_OF_TUPLE_CACHE  2
 #define MAX_MCAST_LIST_SIZE     32
 #define MAX_LEN_OF_VENDOR_DESC  64
-//#define MAX_SIZE_OF_MCAST_PSQ   (NUM_OF_LOCAL_TXBUF >> 2) // AP won't spend more than 1/4 of total buffers on M/BCAST PSQ
+/*#define MAX_SIZE_OF_MCAST_PSQ   (NUM_OF_LOCAL_TXBUF >> 2) // AP won't spend more than 1/4 of total buffers on M/BCAST PSQ */
 #define MAX_SIZE_OF_MCAST_PSQ               32
 
 #define MAX_RX_PROCESS_CNT	(RX_RING_SIZE)
 
+/*
+	WMM Note: If memory of your system is not much, please reduce the definition;
+	or when you do WMM test, the queue for low priority AC will be full, i.e.
+	TX_RING_SIZE + MAX_PACKETS_IN_QUEUE packets for the AC will be buffered in
+	WLAN, maybe no any packet buffer can be got in Ethernet driver.
 
-#define MAX_PACKETS_IN_QUEUE				(512) //(512)    // to pass WMM A5-WPAPSK
+	Sometimes no packet buffer can be got in Ethernet driver, the system will
+	send flow control packet to the sender to slow down its sending rate.
+	So no WMM can be saw in the air.
+*/
+
+/*
+	Need to use 64 in vxworks for test case WMM A5-T07
+	Two dnlink (10Mbps) from a WMM station to a non-WMM station.
+	If use 256, queue is not enough.
+	And in rt_main_end.c, clConfig.clNum = RX_RING_SIZE * 3; is changed to
+	clConfig.clNum = RX_RING_SIZE * 4;
+*/
+/* TODO: For VxWorks the size is 256. Shall we cahnge the value as 256 for all OS????? */
+#define MAX_PACKETS_IN_QUEUE				(512)	/*(512)    // to pass WMM A5-WPAPSK */
+
 #define MAX_PACKETS_IN_MCAST_PS_QUEUE		32
-#define MAX_PACKETS_IN_PS_QUEUE				128	//32
-#define WMM_NUM_OF_AC                       4  /* AC0, AC1, AC2, and AC3 */
+#define MAX_PACKETS_IN_PS_QUEUE				128	/*32 */
+#define WMM_NUM_OF_AC                       4	/* AC0, AC1, AC2, and AC3 */
 
+#ifdef RTMP_EFUSE_SUPPORT
+/*2008/09/11:KH add to support efuse<-- */
 #define MAX_EEPROM_BIN_FILE_SIZE					1024
+#define EFUSE_BUFFER_PATH						"/tmp/RT30xxEEPROM.bin"
+/*2008/09/11:KH add to support efuse--> */
+#endif /* RTMP_EFUSE_SUPPORT // */
 
-// RxFilter
+/* RxFilter */
 #define STANORMAL	 0x17f97
 #define APNORMAL	 0x15f97
-//
-//  RTMP_ADAPTER flags
-//
+#define PSPXLINK	 0x17f93
+/* */
+/*  struct rt_rtmp_adapter flags */
+/* */
 #define fRTMP_ADAPTER_MAP_REGISTER          0x00000001
 #define fRTMP_ADAPTER_INTERRUPT_IN_USE      0x00000002
 #define fRTMP_ADAPTER_HARDWARE_ERROR        0x00000004
@@ -181,13 +171,13 @@
 #define fRTMP_ADAPTER_SCAN_2040 			0x04000000
 #define	fRTMP_ADAPTER_RADIO_MEASUREMENT		0x08000000
 
-#define fRTMP_ADAPTER_START_UP         		0x10000000	//Devive already initialized and enabled Tx/Rx.
+#define fRTMP_ADAPTER_START_UP         		0x10000000	/*Devive already initialized and enabled Tx/Rx. */
 #define fRTMP_ADAPTER_MEDIA_STATE_CHANGE    0x20000000
 #define fRTMP_ADAPTER_IDLE_RADIO_OFF        0x40000000
 
-//
-//  STA operation status flags
-//
+/* */
+/*  STA operation status flags */
+/* */
 #define fOP_STATUS_INFRA_ON                 0x00000001
 #define fOP_STATUS_ADHOC_ON                 0x00000002
 #define fOP_STATUS_BG_PROTECTION_INUSED     0x00000004
@@ -197,28 +187,34 @@
 #define fOP_STATUS_MEDIA_STATE_CONNECTED    0x00000080
 #define fOP_STATUS_WMM_INUSED               0x00000100
 #define fOP_STATUS_AGGREGATION_INUSED       0x00000200
-#define fOP_STATUS_DOZE                     0x00000400  // debug purpose
-#define fOP_STATUS_PIGGYBACK_INUSED         0x00000800  // piggy-back, and aggregation
+#define fOP_STATUS_DOZE                     0x00000400	/* debug purpose */
+#define fOP_STATUS_PIGGYBACK_INUSED         0x00000800	/* piggy-back, and aggregation */
 #define fOP_STATUS_APSD_INUSED				0x00001000
 #define fOP_STATUS_TX_AMSDU_INUSED			0x00002000
 #define fOP_STATUS_MAX_RETRY_ENABLED		0x00004000
 #define fOP_STATUS_WAKEUP_NOW               0x00008000
-#define fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE       0x00020000
+#define fOP_STATUS_PCIE_DEVICE       0x00020000
+#define fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE fOP_STATUS_PCIE_DEVICE
 
-#ifdef RT2860
-//
-//  RTMP_ADAPTER PSFlags : related to advanced power save.
-//
-// Indicate whether driver can go to sleep mode from now. This flag is useful AFTER link up
+/* */
+/*  struct rt_rtmp_adapter PSFlags : related to advanced power save. */
+/* */
+/* Indicate whether driver can go to sleep mode from now. This flag is useful AFTER link up */
 #define fRTMP_PS_CAN_GO_SLEEP          0x00000001
-// Indicate whether driver has issue a LinkControl command to PCIe L1
+/* Indicate whether driver has issue a LinkControl command to PCIe L1 */
 #define fRTMP_PS_SET_PCI_CLK_OFF_COMMAND          0x00000002
-// Indicate driver should disable kick off hardware to send packets from now.
+/* Indicate driver should disable kick off hardware to send packets from now. */
 #define fRTMP_PS_DISABLE_TX         0x00000004
-// Indicate driver should IMMEDIATELY fo to sleep after receiving AP's beacon in which  doesn't indicate unicate nor multicast packets for me
-//. This flag is used ONLY in RTMPHandleRxDoneInterrupt routine.
+/* Indicate driver should IMMEDIATELY fo to sleep after receiving AP's beacon in which  doesn't indicate unicate nor multicast packets for me */
+/*. This flag is used ONLY in RTMPHandleRxDoneInterrupt routine. */
 #define fRTMP_PS_GO_TO_SLEEP_NOW         0x00000008
-#endif
+#define fRTMP_PS_TOGGLE_L1		0x00000010	/* Use Toggle L1 mechanism for rt28xx PCIe */
+
+#ifdef RT3090
+#define WAKE_MCU_CMD				0x31
+#define SLEEP_MCU_CMD					0x30
+#define RFOFF_MCU_CMD				0x35
+#endif /* RT3090 // */
 
 #define CCKSETPROTECT		0x1
 #define OFDMSETPROTECT		0x2
@@ -228,12 +224,12 @@
 #define GR40SETPROTECT		0x20
 #define ALLN_SETPROTECT		(GR40SETPROTECT | GF20SETPROTECT | MM40SETPROTECT | MM20SETPROTECT)
 
-//
-//  AP's client table operation status flags
-//
-#define fCLIENT_STATUS_WMM_CAPABLE          0x00000001  // CLIENT can parse QOS DATA frame
-#define fCLIENT_STATUS_AGGREGATION_CAPABLE  0x00000002  // CLIENT can receive Ralink's proprietary TX aggregation frame
-#define fCLIENT_STATUS_PIGGYBACK_CAPABLE    0x00000004  // CLIENT support piggy-back
+/* */
+/*  AP's client table operation status flags */
+/* */
+#define fCLIENT_STATUS_WMM_CAPABLE          0x00000001	/* CLIENT can parse QOS DATA frame */
+#define fCLIENT_STATUS_AGGREGATION_CAPABLE  0x00000002	/* CLIENT can receive Ralink's proprietary TX aggregation frame */
+#define fCLIENT_STATUS_PIGGYBACK_CAPABLE    0x00000004	/* CLIENT support piggy-back */
 #define fCLIENT_STATUS_AMSDU_INUSED			0x00000008
 #define fCLIENT_STATUS_SGI20_CAPABLE		0x00000010
 #define fCLIENT_STATUS_SGI40_CAPABLE		0x00000020
@@ -242,47 +238,48 @@
 #define fCLIENT_STATUS_HTC_CAPABLE			0x00000100
 #define fCLIENT_STATUS_RDG_CAPABLE			0x00000200
 #define fCLIENT_STATUS_MCSFEEDBACK_CAPABLE  0x00000400
-#define fCLIENT_STATUS_APSD_CAPABLE         0x00000800  /* UAPSD STATION */
+#define fCLIENT_STATUS_APSD_CAPABLE         0x00000800	/* UAPSD STATION */
 
 #define fCLIENT_STATUS_RALINK_CHIPSET		0x00100000
-//
-//  STA configuration flags
-//
+/* */
+/*  STA configuration flags */
+/* */
 
-// 802.11n Operating Mode Definition. 0-3 also used in ASICUPdateProtect switch case
+/* 802.11n Operating Mode Definition. 0-3 also used in ASICUPdateProtect switch case */
 #define HT_NO_PROTECT	0
 #define HT_LEGACY_PROTECT	1
 #define HT_40_PROTECT	2
 #define HT_2040_PROTECT	3
 #define HT_RTSCTS_6M	7
-//following is our own definition in order to turn on our ASIC protection register in INFRASTRUCTURE.
-#define HT_ATHEROS	8	// rt2860c has problem with atheros chip. we need to turn on RTS/CTS .
-#define HT_FORCERTSCTS	9	// Force turn on RTS/CTS first. then go to evaluate if this force RTS is necessary.
+/*following is our own definition in order to turn on our ASIC protection register in INFRASTRUCTURE. */
+#define HT_ATHEROS	8	/* rt2860c has problem with atheros chip. we need to turn on RTS/CTS . */
+#define HT_FORCERTSCTS	9	/* Force turn on RTS/CTS first. then go to evaluate if this force RTS is necessary. */
 
-//
-// RX Packet Filter control flags. Apply on pAd->PacketFilter
-//
+/* */
+/* RX Packet Filter control flags. Apply on pAd->PacketFilter */
+/* */
 #define fRX_FILTER_ACCEPT_DIRECT            NDIS_PACKET_TYPE_DIRECTED
 #define fRX_FILTER_ACCEPT_MULTICAST         NDIS_PACKET_TYPE_MULTICAST
 #define fRX_FILTER_ACCEPT_BROADCAST         NDIS_PACKET_TYPE_BROADCAST
 #define fRX_FILTER_ACCEPT_ALL_MULTICAST     NDIS_PACKET_TYPE_ALL_MULTICAST
+#define fRX_FILTER_ACCEPT_PROMISCUOUS       NDIS_PACKET_TYPE_PROMISCUOUS
 
-//
-// Error code section
-//
-// NDIS_ERROR_CODE_ADAPTER_NOT_FOUND
+/* */
+/* Error code section */
+/* */
+/* NDIS_ERROR_CODE_ADAPTER_NOT_FOUND */
 #define ERRLOG_READ_PCI_SLOT_FAILED     0x00000101L
 #define ERRLOG_WRITE_PCI_SLOT_FAILED    0x00000102L
 #define ERRLOG_VENDOR_DEVICE_NOMATCH    0x00000103L
 
-// NDIS_ERROR_CODE_ADAPTER_DISABLED
+/* NDIS_ERROR_CODE_ADAPTER_DISABLED */
 #define ERRLOG_BUS_MASTER_DISABLED      0x00000201L
 
-// NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION
+/* NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION */
 #define ERRLOG_INVALID_SPEED_DUPLEX     0x00000301L
 #define ERRLOG_SET_SECONDARY_FAILED     0x00000302L
 
-// NDIS_ERROR_CODE_OUT_OF_RESOURCES
+/* NDIS_ERROR_CODE_OUT_OF_RESOURCES */
 #define ERRLOG_OUT_OF_MEMORY            0x00000401L
 #define ERRLOG_OUT_OF_SHARED_MEMORY     0x00000402L
 #define ERRLOG_OUT_OF_MAP_REGISTERS     0x00000403L
@@ -292,22 +289,21 @@
 #define ERRLOG_OUT_OF_NDIS_PACKET       0x00000407L
 #define ERRLOG_OUT_OF_LOOKASIDE_MEMORY  0x00000408L
 
-// NDIS_ERROR_CODE_HARDWARE_FAILURE
+/* NDIS_ERROR_CODE_HARDWARE_FAILURE */
 #define ERRLOG_SELFTEST_FAILED          0x00000501L
 #define ERRLOG_INITIALIZE_ADAPTER       0x00000502L
 #define ERRLOG_REMOVE_MINIPORT          0x00000503L
 
-// NDIS_ERROR_CODE_RESOURCE_CONFLICT
+/* NDIS_ERROR_CODE_RESOURCE_CONFLICT */
 #define ERRLOG_MAP_IO_SPACE             0x00000601L
 #define ERRLOG_QUERY_ADAPTER_RESOURCES  0x00000602L
 #define ERRLOG_NO_IO_RESOURCE           0x00000603L
 #define ERRLOG_NO_INTERRUPT_RESOURCE    0x00000604L
 #define ERRLOG_NO_MEMORY_RESOURCE       0x00000605L
 
-
-// WDS definition
+/* WDS definition */
 #define	MAX_WDS_ENTRY               4
-#define WDS_PAIRWISE_KEY_OFFSET     60    // WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table
+#define WDS_PAIRWISE_KEY_OFFSET     60	/* WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table */
 
 #define	WDS_DISABLE_MODE            0
 #define	WDS_RESTRICT_MODE           1
@@ -315,23 +311,20 @@
 #define	WDS_REPEATER_MODE           3
 #define	WDS_LAZY_MODE               4
 
-
 #define MAX_MESH_NUM				0
 
 #define MAX_APCLI_NUM				0
 
 #define MAX_MBSSID_NUM				1
-#if defined(RT2860) || defined(RT30xx)
 #ifdef MBSS_SUPPORT
 #undef	MAX_MBSSID_NUM
 #define MAX_MBSSID_NUM				(8 - MAX_MESH_NUM - MAX_APCLI_NUM)
-#endif // MBSS_SUPPORT //
-#endif
+#endif /* MBSS_SUPPORT // */
 
 /* sanity check for apidx */
 #define MBSS_MR_APIDX_SANITY_CHECK(apidx) \
     { if (apidx > MAX_MBSSID_NUM) { \
-          printk("%s> Error! apidx = %d > MAX_MBSSID_NUM!\n", __func__, apidx); \
+          DBGPRINT(RT_DEBUG_ERROR, ("%s> Error! apidx = %d > MAX_MBSSID_NUM!\n", __func__, apidx)); \
 	  apidx = MAIN_MBSSID; } }
 
 #define VALID_WCID(_wcid)	((_wcid) > 0 && (_wcid) < MAX_LEN_OF_MAC_TABLE )
@@ -339,12 +332,11 @@
 #define MAIN_MBSSID                 0
 #define FIRST_MBSSID                1
 
-
 #define MAX_BEACON_SIZE				512
-// If the MAX_MBSSID_NUM is larger than 6,
-// it shall reserve some WCID space(wcid 222~253) for beacon frames.
-// -	these wcid 238~253 are reserved for beacon#6(ra6).
-// -	these wcid 222~237 are reserved for beacon#7(ra7).
+/* If the MAX_MBSSID_NUM is larger than 6, */
+/* it shall reserve some WCID space(wcid 222~253) for beacon frames. */
+/* -    these wcid 238~253 are reserved for beacon#6(ra6). */
+/* -    these wcid 222~237 are reserved for beacon#7(ra7). */
 #if defined(MAX_MBSSID_NUM) && (MAX_MBSSID_NUM == 8)
 #define HW_RESERVED_WCID	222
 #elif defined(MAX_MBSSID_NUM) && (MAX_MBSSID_NUM == 7)
@@ -353,17 +345,17 @@
 #define HW_RESERVED_WCID	255
 #endif
 
-// Then dedicate wcid of DFS and Carrier-Sense.
+/* Then dedicate wcid of DFS and Carrier-Sense. */
 #define DFS_CTS_WCID 		(HW_RESERVED_WCID - 1)
 #define CS_CTS_WCID 		(HW_RESERVED_WCID - 2)
 #define LAST_SPECIFIC_WCID	(HW_RESERVED_WCID - 2)
 
-// If MAX_MBSSID_NUM is 8, the maximum available wcid for the associated STA is 211.
-// If MAX_MBSSID_NUM is 7, the maximum available wcid for the associated STA is 228.
+/* If MAX_MBSSID_NUM is 8, the maximum available wcid for the associated STA is 211. */
+/* If MAX_MBSSID_NUM is 7, the maximum available wcid for the associated STA is 228. */
 #define MAX_AVAILABLE_CLIENT_WCID	(LAST_SPECIFIC_WCID - MAX_MBSSID_NUM - 1)
 
-// TX need WCID to find Cipher Key
-// these wcid 212 ~ 219 are reserved for bc/mc packets if MAX_MBSSID_NUM is 8.
+/* TX need WCID to find Cipher Key */
+/* these wcid 212 ~ 219 are reserved for bc/mc packets if MAX_MBSSID_NUM is 8. */
 #define GET_GroupKey_WCID(__wcid, __bssidx) \
 	{										\
 		__wcid = LAST_SPECIFIC_WCID - (MAX_MBSSID_NUM) + __bssidx;	\
@@ -371,8 +363,7 @@
 
 #define IsGroupKeyWCID(__wcid) (((__wcid) < LAST_SPECIFIC_WCID) && ((__wcid) >= (LAST_SPECIFIC_WCID - (MAX_MBSSID_NUM))))
 
-
-// definition to support multiple BSSID
+/* definition to support multiple BSSID */
 #define BSS0                            0
 #define BSS1                            1
 #define BSS2                            2
@@ -382,26 +373,26 @@
 #define BSS6                            6
 #define BSS7                            7
 
-
-//============================================================
-// Length definitions
+/*============================================================ */
+/* Length definitions */
 #define PEER_KEY_NO                     2
 #define MAC_ADDR_LEN                    6
 #define TIMESTAMP_LEN                   8
-#define MAX_LEN_OF_SUPPORTED_RATES      MAX_LENGTH_OF_SUPPORT_RATES // 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
-#define MAX_LEN_OF_KEY                  32      // 32 octets == 256 bits, Redefine for WPA
-#define MAX_NUM_OF_CHANNELS             MAX_NUM_OF_CHS      // 14 channels @2.4G +  12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination
-#define MAX_NUM_OF_11JCHANNELS             20      // 14 channels @2.4G +  12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination
+#define MAX_LEN_OF_SUPPORTED_RATES      MAX_LENGTH_OF_SUPPORT_RATES	/* 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */
+#define MAX_LEN_OF_KEY                  32	/* 32 octets == 256 bits, Redefine for WPA */
+#define MAX_NUM_OF_CHANNELS             MAX_NUM_OF_CHS	/* 14 channels @2.4G +  12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination */
+#define MAX_NUM_OF_11JCHANNELS             20	/* 14 channels @2.4G +  12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination */
 #define MAX_LEN_OF_SSID                 32
 #define CIPHER_TEXT_LEN                 128
 #define HASH_TABLE_SIZE                 256
-#define MAX_VIE_LEN                     1024   // New for WPA cipher suite variable IE sizes.
+#define MAX_VIE_LEN                     1024	/* New for WPA cipher suite variable IE sizes. */
 #define MAX_SUPPORT_MCS             32
+#define MAX_NUM_OF_BBP_LATCH             140
 
-//============================================================
-// ASIC WCID Table definition.
-//============================================================
-#define BSSID_WCID		1	// in infra mode, always put bssid with this WCID
+/*============================================================ */
+/* ASIC WCID Table definition. */
+/*============================================================ */
+#define BSSID_WCID		1	/* in infra mode, always put bssid with this WCID */
 #define MCAST_WCID	0x0
 #define BSS0Mcast_WCID	0x0
 #define BSS1Mcast_WCID	0xf8
@@ -415,10 +406,10 @@
 
 #define MAX_NUM_OF_ACL_LIST				MAX_NUMBER_OF_ACL
 
-#define MAX_LEN_OF_MAC_TABLE            MAX_NUMBER_OF_MAC // if MAX_MBSSID_NUM is 8, this value can't be larger than 211
+#define MAX_LEN_OF_MAC_TABLE            MAX_NUMBER_OF_MAC	/* if MAX_MBSSID_NUM is 8, this value can't be larger than 211 */
 
 #if MAX_LEN_OF_MAC_TABLE>MAX_AVAILABLE_CLIENT_WCID
-#error MAX_LEN_OF_MAC_TABLE can not be larger than MAX_AVAILABLE_CLIENT_WCID!!!!
+#error MAX_LEN_OF_MAC_TABLE can not be larger than MAX_AVAILABLE_CLIENT_WCID!
 #endif
 
 #define MAX_NUM_OF_WDS_LINK_PERBSSID	            3
@@ -428,42 +419,41 @@
 
 #define NUM_OF_TID			8
 #define MAX_AID_BA                    4
-#define MAX_LEN_OF_BA_REC_TABLE          ((NUM_OF_TID * MAX_LEN_OF_MAC_TABLE)/2)//   (NUM_OF_TID*MAX_AID_BA + 32)	 //Block ACK recipient
-#define MAX_LEN_OF_BA_ORI_TABLE          ((NUM_OF_TID * MAX_LEN_OF_MAC_TABLE)/2)//   (NUM_OF_TID*MAX_AID_BA + 32)   // Block ACK originator
+#define MAX_LEN_OF_BA_REC_TABLE          ((NUM_OF_TID * MAX_LEN_OF_MAC_TABLE)/2)	/*   (NUM_OF_TID*MAX_AID_BA + 32)        //Block ACK recipient */
+#define MAX_LEN_OF_BA_ORI_TABLE          ((NUM_OF_TID * MAX_LEN_OF_MAC_TABLE)/2)	/*   (NUM_OF_TID*MAX_AID_BA + 32)   // Block ACK originator */
 #define MAX_LEN_OF_BSS_TABLE             64
 #define MAX_REORDERING_MPDU_NUM			 512
 
-// key related definitions
+/* key related definitions */
 #define SHARE_KEY_NUM                   4
-#define MAX_LEN_OF_SHARE_KEY            16    // byte count
-#define MAX_LEN_OF_PEER_KEY             16    // byte count
-#define PAIRWISE_KEY_NUM                64    // in MAC ASIC pairwise key table
+#define MAX_LEN_OF_SHARE_KEY            16	/* byte count */
+#define MAX_LEN_OF_PEER_KEY             16	/* byte count */
+#define PAIRWISE_KEY_NUM                64	/* in MAC ASIC pairwise key table */
 #define GROUP_KEY_NUM                   4
 #define PMK_LEN                         32
-#define WDS_PAIRWISE_KEY_OFFSET         60    // WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table
-#define	PMKID_NO                        4     // Number of PMKID saved supported
+#define WDS_PAIRWISE_KEY_OFFSET         60	/* WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table */
+#define	PMKID_NO                        4	/* Number of PMKID saved supported */
 #define MAX_LEN_OF_MLME_BUFFER          2048
 
-// power status related definitions
+/* power status related definitions */
 #define PWR_ACTIVE                      0
 #define PWR_SAVE                        1
-#define PWR_MMPS                        2			//MIMO power save
+#define PWR_MMPS                        2	/*MIMO power save */
 
-// Auth and Assoc mode related definitions
+/* Auth and Assoc mode related definitions */
 #define AUTH_MODE_OPEN                  0x00
 #define AUTH_MODE_KEY                   0x01
 
-// BSS Type definitions
-#define BSS_ADHOC                       0  // = Ndis802_11IBSS
-#define BSS_INFRA                       1  // = Ndis802_11Infrastructure
-#define BSS_ANY                         2  // = Ndis802_11AutoUnknown
-#define BSS_MONITOR			            3  // = Ndis802_11Monitor
+/* BSS Type definitions */
+#define BSS_ADHOC                       0	/* = Ndis802_11IBSS */
+#define BSS_INFRA                       1	/* = Ndis802_11Infrastructure */
+#define BSS_ANY                         2	/* = Ndis802_11AutoUnknown */
+#define BSS_MONITOR			            3	/* = Ndis802_11Monitor */
 
-
-// Reason code definitions
+/* Reason code definitions */
 #define REASON_RESERVED                 0
 #define REASON_UNSPECIFY                1
-#define REASON_NO_LONGER_VALID          2
+#define REASON_NO_longER_VALID          2
 #define REASON_DEAUTH_STA_LEAVING       3
 #define REASON_DISASSOC_INACTIVE        4
 #define REASON_DISASSPC_AP_UNABLE       5
@@ -495,7 +485,7 @@
 #define REASON_QOS_REQUEST_TIMEOUT        39
 #define REASON_QOS_CIPHER_NOT_SUPPORT     45
 
-// Status code definitions
+/* Status code definitions */
 #define MLME_SUCCESS                    0
 #define MLME_UNSPECIFY_FAIL             1
 #define MLME_CANNOT_SUPPORT_CAP         10
@@ -515,6 +505,9 @@
 #define MLME_QOS_UNSPECIFY                32
 #define MLME_REQUEST_DECLINED             37
 #define MLME_REQUEST_WITH_INVALID_PARAM   38
+#define MLME_INVALID_GROUP_CIPHER	  41
+#define MLME_INVALID_PAIRWISE_CIPHER	  42
+#define MLME_INVALID_AKMP			  43
 #define MLME_DLS_NOT_ALLOW_IN_QBSS        48
 #define MLME_DEST_STA_NOT_IN_QBSS         49
 #define MLME_DEST_STA_IS_NOT_A_QSTA       50
@@ -524,7 +517,7 @@
 #define MLME_STATE_MACHINE_REJECT       0x53
 #define MLME_MAC_TABLE_FAIL             0x54
 
-// IE code
+/* IE code */
 #define IE_SSID                         0
 #define IE_SUPP_RATES                   1
 #define IE_FH_PARM                      2
@@ -532,94 +525,95 @@
 #define IE_CF_PARM                      4
 #define IE_TIM                          5
 #define IE_IBSS_PARM                    6
-#define IE_COUNTRY                      7     // 802.11d
-#define IE_802_11D_REQUEST              10    // 802.11d
-#define IE_QBSS_LOAD                    11    // 802.11e d9
-#define IE_EDCA_PARAMETER               12    // 802.11e d9
-#define IE_TSPEC                        13    // 802.11e d9
-#define IE_TCLAS                        14    // 802.11e d9
-#define IE_SCHEDULE                     15    // 802.11e d9
+#define IE_COUNTRY                      7	/* 802.11d */
+#define IE_802_11D_REQUEST              10	/* 802.11d */
+#define IE_QBSS_LOAD                    11	/* 802.11e d9 */
+#define IE_EDCA_PARAMETER               12	/* 802.11e d9 */
+#define IE_TSPEC                        13	/* 802.11e d9 */
+#define IE_TCLAS                        14	/* 802.11e d9 */
+#define IE_SCHEDULE                     15	/* 802.11e d9 */
 #define IE_CHALLENGE_TEXT               16
-#define IE_POWER_CONSTRAINT             32    // 802.11h d3.3
-#define IE_POWER_CAPABILITY             33    // 802.11h d3.3
-#define IE_TPC_REQUEST                  34    // 802.11h d3.3
-#define IE_TPC_REPORT                   35    // 802.11h d3.3
-#define IE_SUPP_CHANNELS                36    // 802.11h d3.3
-#define IE_CHANNEL_SWITCH_ANNOUNCEMENT  37    // 802.11h d3.3
-#define IE_MEASUREMENT_REQUEST          38    // 802.11h d3.3
-#define IE_MEASUREMENT_REPORT           39    // 802.11h d3.3
-#define IE_QUIET                        40    // 802.11h d3.3
-#define IE_IBSS_DFS                     41    // 802.11h d3.3
-#define IE_ERP                          42    // 802.11g
-#define IE_TS_DELAY                     43    // 802.11e d9
-#define IE_TCLAS_PROCESSING             44    // 802.11e d9
-#define IE_QOS_CAPABILITY               46    // 802.11e d6
-#define IE_HT_CAP                       45    // 802.11n d1. HT CAPABILITY. ELEMENT ID TBD
-#define IE_AP_CHANNEL_REPORT			51    // 802.11k d6
-#define IE_HT_CAP2                         52    // 802.11n d1. HT CAPABILITY. ELEMENT ID TBD
-#define IE_RSN                          48    // 802.11i d3.0
-#define IE_WPA2                         48    // WPA2
-#define IE_EXT_SUPP_RATES               50    // 802.11g
-#define IE_SUPP_REG_CLASS               59    // 802.11y. Supported regulatory classes.
-#define IE_EXT_CHANNEL_SWITCH_ANNOUNCEMENT	60	// 802.11n
-#define IE_ADD_HT                         61    // 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD
-#define IE_ADD_HT2                        53    // 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD
+#define IE_POWER_CONSTRAint             32	/* 802.11h d3.3 */
+#define IE_POWER_CAPABILITY             33	/* 802.11h d3.3 */
+#define IE_TPC_REQUEST                  34	/* 802.11h d3.3 */
+#define IE_TPC_REPORT                   35	/* 802.11h d3.3 */
+#define IE_SUPP_CHANNELS                36	/* 802.11h d3.3 */
+#define IE_CHANNEL_SWITCH_ANNOUNCEMENT  37	/* 802.11h d3.3 */
+#define IE_MEASUREMENT_REQUEST          38	/* 802.11h d3.3 */
+#define IE_MEASUREMENT_REPORT           39	/* 802.11h d3.3 */
+#define IE_QUIET                        40	/* 802.11h d3.3 */
+#define IE_IBSS_DFS                     41	/* 802.11h d3.3 */
+#define IE_ERP                          42	/* 802.11g */
+#define IE_TS_DELAY                     43	/* 802.11e d9 */
+#define IE_TCLAS_PROCESSING             44	/* 802.11e d9 */
+#define IE_QOS_CAPABILITY               46	/* 802.11e d6 */
+#define IE_HT_CAP                       45	/* 802.11n d1. HT CAPABILITY. ELEMENT ID TBD */
+#define IE_AP_CHANNEL_REPORT			51	/* 802.11k d6 */
+#define IE_HT_CAP2                         52	/* 802.11n d1. HT CAPABILITY. ELEMENT ID TBD */
+#define IE_RSN                          48	/* 802.11i d3.0 */
+#define IE_WPA2                         48	/* WPA2 */
+#define IE_EXT_SUPP_RATES               50	/* 802.11g */
+#define IE_SUPP_REG_CLASS               59	/* 802.11y. Supported regulatory classes. */
+#define IE_EXT_CHANNEL_SWITCH_ANNOUNCEMENT	60	/* 802.11n */
+#define IE_ADD_HT                         61	/* 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD */
+#define IE_ADD_HT2                        53	/* 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD */
 
+/* For 802.11n D3.03 */
+/*#define IE_NEW_EXT_CHA_OFFSET             62    // 802.11n d1. New extension channel offset elemet */
+#define IE_SECONDARY_CH_OFFSET		62	/* 802.11n D3.03        Secondary Channel Offset element */
+#define IE_WAPI							68	/* WAPI information element */
+#define IE_2040_BSS_COEXIST               72	/* 802.11n D3.0.3 */
+#define IE_2040_BSS_INTOLERANT_REPORT     73	/* 802.11n D3.03 */
+#define IE_OVERLAPBSS_SCAN_PARM           74	/* 802.11n D3.03 */
+#define IE_EXT_CAPABILITY                127	/* 802.11n D3.03 */
 
-// For 802.11n D3.03
-//#define IE_NEW_EXT_CHA_OFFSET             62    // 802.11n d1. New extension channel offset elemet
-#define IE_SECONDARY_CH_OFFSET		62	// 802.11n D3.03	Secondary Channel Offset element
-#define IE_2040_BSS_COEXIST               72    // 802.11n D3.0.3
-#define IE_2040_BSS_INTOLERANT_REPORT     73    // 802.11n D3.03
-#define IE_OVERLAPBSS_SCAN_PARM           74    // 802.11n D3.03
-#define IE_EXT_CAPABILITY                127   // 802.11n D3.03
+#define IE_WPA                          221	/* WPA */
+#define IE_VENDOR_SPECIFIC              221	/* Wifi WMM (WME) */
 
+#define OUI_BROADCOM_HT              51	/* */
+#define OUI_BROADCOM_HTADD              52	/* */
+#define OUI_PREN_HT_CAP              51	/* */
+#define OUI_PREN_ADD_HT              52	/* */
 
-#define IE_WPA                          221   // WPA
-#define IE_VENDOR_SPECIFIC              221   // Wifi WMM (WME)
-
-#define OUI_BROADCOM_HT              51   //
-#define OUI_BROADCOM_HTADD              52   //
-#define OUI_PREN_HT_CAP              51   //
-#define OUI_PREN_ADD_HT              52   //
-
-// CCX information
-#define IE_AIRONET_CKIP                 133   // CCX1.0 ID 85H for CKIP
-#define IE_AP_TX_POWER                  150   // CCX 2.0 for AP transmit power
-#define IE_MEASUREMENT_CAPABILITY       221   // CCX 2.0
+/* CCX information */
+#define IE_AIRONET_CKIP                 133	/* CCX1.0 ID 85H for CKIP */
+#define IE_AP_TX_POWER                  150	/* CCX 2.0 for AP transmit power */
+#define IE_MEASUREMENT_CAPABILITY       221	/* CCX 2.0 */
 #define IE_CCX_V2                       221
-#define IE_AIRONET_IPADDRESS            149   // CCX ID 95H for IP Address
-#define IE_AIRONET_CCKMREASSOC          156   // CCX ID 9CH for CCKM Reassociation Request element
+#define IE_AIRONET_IPADDRESS            149	/* CCX ID 95H for IP Address */
+#define IE_AIRONET_CCKMREASSOC          156	/* CCX ID 9CH for CCKM Reassociation Request element */
 #define CKIP_NEGOTIATION_LENGTH         30
 #define AIRONET_IPADDRESS_LENGTH        10
 #define AIRONET_CCKMREASSOC_LENGTH      24
 
-// ========================================================
-// MLME state machine definition
-// ========================================================
+/* ======================================================== */
+/* MLME state machine definition */
+/* ======================================================== */
 
-// STA MLME state mahcines
+/* STA MLME state mahcines */
 #define ASSOC_STATE_MACHINE             1
 #define AUTH_STATE_MACHINE              2
 #define AUTH_RSP_STATE_MACHINE          3
 #define SYNC_STATE_MACHINE              4
 #define MLME_CNTL_STATE_MACHINE         5
 #define WPA_PSK_STATE_MACHINE           6
-#define LEAP_STATE_MACHINE              7
+/*#define LEAP_STATE_MACHINE              7 */
 #define AIRONET_STATE_MACHINE           8
 #define ACTION_STATE_MACHINE           9
 
-// AP MLME state machines
+/* AP MLME state machines */
 #define AP_ASSOC_STATE_MACHINE          11
 #define AP_AUTH_STATE_MACHINE           12
-#define AP_AUTH_RSP_STATE_MACHINE       13
 #define AP_SYNC_STATE_MACHINE           14
 #define AP_CNTL_STATE_MACHINE           15
-#define AP_WPA_STATE_MACHINE            16
+#define WSC_STATE_MACHINE            17
+#define WSC_UPNP_STATE_MACHINE		    18
 
-//
-// STA's CONTROL/CONNECT state machine: states, events, total function #
-//
+#define WPA_STATE_MACHINE			23
+
+/* */
+/* STA's CONTROL/CONNECT state machine: states, events, total function # */
+/* */
 #define CNTL_IDLE                       0
 #define CNTL_WAIT_DISASSOC              1
 #define CNTL_WAIT_JOIN                  2
@@ -630,9 +624,9 @@
 #define CNTL_WAIT_AUTH2                 7
 #define CNTL_WAIT_OID_LIST_SCAN         8
 #define CNTL_WAIT_OID_DISASSOC          9
-#ifdef RT2870
+#ifdef RTMP_MAC_USB
 #define CNTL_WAIT_SCAN_FOR_CONNECT      10
-#endif // RT2870 //
+#endif /* RTMP_MAC_USB // */
 
 #define MT2_ASSOC_CONF                  34
 #define MT2_AUTH_CONF                   35
@@ -646,13 +640,14 @@
 #define MT2_GET_CONF                    43
 #define MT2_SET_CONF                    44
 #define MT2_RESET_CONF                  45
+#define MT2_FT_OTD_CONF					46
 #define MT2_MLME_ROAMING_REQ            52
 
 #define CNTL_FUNC_SIZE                  1
 
-//
-// STA's ASSOC state machine: states, events, total function #
-//
+/* */
+/* STA's ASSOC state machine: states, events, total function # */
+/* */
 #define ASSOC_IDLE                      0
 #define ASSOC_WAIT_RSP                  1
 #define REASSOC_WAIT_RSP                2
@@ -675,24 +670,26 @@
 
 #define ASSOC_FUNC_SIZE                 (MAX_ASSOC_STATE * MAX_ASSOC_MSG)
 
-//
-// ACT state machine: states, events, total function #
-//
+/* */
+/* ACT state machine: states, events, total function # */
+/* */
 #define ACT_IDLE                      0
 #define MAX_ACT_STATE                 1
 
 #define ACT_MACHINE_BASE              0
 
-//Those PEER_xx_CATE number is based on real Categary value in IEEE spec. Please don'es modify it by your self.
-//Category
+/*Those PEER_xx_CATE number is based on real Categary value in IEEE spec. Please don'es modify it by your self. */
+/*Category */
 #define MT2_PEER_SPECTRUM_CATE              0
 #define MT2_PEER_QOS_CATE              1
 #define MT2_PEER_DLS_CATE             2
 #define MT2_PEER_BA_CATE             3
 #define MT2_PEER_PUBLIC_CATE             4
 #define MT2_PEER_RM_CATE             5
-#define MT2_PEER_HT_CATE             7	//	7.4.7
+/* "FT_CATEGORY_BSS_TRANSITION equal to 6" is defined file of "dot11r_ft.h" */
+#define MT2_PEER_HT_CATE             7	/*      7.4.7 */
 #define MAX_PEER_CATE_MSG                   7
+
 #define MT2_MLME_ADD_BA_CATE             8
 #define MT2_MLME_ORI_DELBA_CATE             9
 #define MT2_MLME_REC_DELBA_CATE             10
@@ -701,7 +698,7 @@
 #define MT2_ACT_INVALID             13
 #define MAX_ACT_MSG                   14
 
-//Category field
+/*Category field */
 #define CATEGORY_SPECTRUM		0
 #define CATEGORY_QOS			1
 #define CATEGORY_DLS			2
@@ -710,38 +707,35 @@
 #define CATEGORY_RM			5
 #define CATEGORY_HT			7
 
-
-// DLS Action frame definition
+/* DLS Action frame definition */
 #define ACTION_DLS_REQUEST			0
 #define ACTION_DLS_RESPONSE			1
 #define ACTION_DLS_TEARDOWN			2
 
-//Spectrum  Action field value 802.11h 7.4.1
-#define SPEC_MRQ	0	// Request
-#define SPEC_MRP	1	//Report
+/*Spectrum  Action field value 802.11h 7.4.1 */
+#define SPEC_MRQ	0	/* Request */
+#define SPEC_MRP	1	/*Report */
 #define SPEC_TPCRQ	2
 #define SPEC_TPCRP	3
 #define SPEC_CHANNEL_SWITCH	4
 
-
-//BA  Action field value
+/*BA  Action field value */
 #define ADDBA_REQ	0
 #define ADDBA_RESP	1
 #define DELBA   2
 
-//Public's  Action field value in Public Category.  Some in 802.11y and some in 11n
-#define ACTION_BSS_2040_COEXIST				0	// 11n
-#define ACTION_DSE_ENABLEMENT					1	// 11y D9.0
-#define ACTION_DSE_DEENABLEMENT				2	// 11y D9.0
-#define ACTION_DSE_REG_LOCATION_ANNOUNCE	3	// 11y D9.0
-#define ACTION_EXT_CH_SWITCH_ANNOUNCE		4	// 11y D9.0
-#define ACTION_DSE_MEASUREMENT_REQ			5	// 11y D9.0
-#define ACTION_DSE_MEASUREMENT_REPORT		6	// 11y D9.0
-#define ACTION_MEASUREMENT_PILOT_ACTION		7  	// 11y D9.0
-#define ACTION_DSE_POWER_CONSTRAINT			8	// 11y D9.0
+/*Public's  Action field value in Public Category.  Some in 802.11y and some in 11n */
+#define ACTION_BSS_2040_COEXIST				0	/* 11n */
+#define ACTION_DSE_ENABLEMENT					1	/* 11y D9.0 */
+#define ACTION_DSE_DEENABLEMENT				2	/* 11y D9.0 */
+#define ACTION_DSE_REG_LOCATION_ANNOUNCE	3	/* 11y D9.0 */
+#define ACTION_EXT_CH_SWITCH_ANNOUNCE		4	/* 11y D9.0 */
+#define ACTION_DSE_MEASUREMENT_REQ			5	/* 11y D9.0 */
+#define ACTION_DSE_MEASUREMENT_REPORT		6	/* 11y D9.0 */
+#define ACTION_MEASUREMENT_PILOT_ACTION		7	/* 11y D9.0 */
+#define ACTION_DSE_POWER_CONSTRAINT			8	/* 11y D9.0 */
 
-
-//HT  Action field value
+/*HT  Action field value */
 #define NOTIFY_BW_ACTION				0
 #define SMPS_ACTION						1
 #define PSMP_ACTION   					2
@@ -753,9 +747,9 @@
 #define HT_INFO_EXCHANGE				8
 
 #define ACT_FUNC_SIZE                 (MAX_ACT_STATE * MAX_ACT_MSG)
-//
-// STA's AUTHENTICATION state machine: states, evvents, total function #
-//
+/* */
+/* STA's AUTHENTICATION state machine: states, evvents, total function # */
+/* */
 #define AUTH_REQ_IDLE                   0
 #define AUTH_WAIT_SEQ2                  1
 #define AUTH_WAIT_SEQ4                  2
@@ -769,9 +763,9 @@
 
 #define AUTH_FUNC_SIZE                  (MAX_AUTH_STATE * MAX_AUTH_MSG)
 
-//
-// STA's AUTH_RSP state machine: states, events, total function #
-//
+/* */
+/* STA's AUTH_RSP state machine: states, events, total function # */
+/* */
 #define AUTH_RSP_IDLE                   0
 #define AUTH_RSP_WAIT_CHAL              1
 #define MAX_AUTH_RSP_STATE              2
@@ -784,10 +778,10 @@
 
 #define AUTH_RSP_FUNC_SIZE              (MAX_AUTH_RSP_STATE * MAX_AUTH_RSP_MSG)
 
-//
-// STA's SYNC state machine: states, events, total function #
-//
-#define SYNC_IDLE                       0  // merge NO_BSS,IBSS_IDLE,IBSS_ACTIVE and BSS in to 1 state
+/* */
+/* STA's SYNC state machine: states, events, total function # */
+/* */
+#define SYNC_IDLE                       0	/* merge NO_BSS,IBSS_IDLE,IBSS_ACTIVE and BSS in to 1 state */
 #define JOIN_WAIT_BEACON                1
 #define SCAN_LISTEN                     2
 #define MAX_SYNC_STATE                  3
@@ -807,7 +801,7 @@
 
 #define SYNC_FUNC_SIZE                  (MAX_SYNC_STATE * MAX_SYNC_MSG)
 
-//Messages for the DLS state machine
+/*Messages for the DLS state machine */
 #define DLS_IDLE						0
 #define MAX_DLS_STATE					1
 
@@ -821,45 +815,18 @@
 
 #define DLS_FUNC_SIZE					(MAX_DLS_STATE * MAX_DLS_MSG)
 
-//
-// STA's WPA-PSK State machine: states, events, total function #
-//
-#define WPA_PSK_IDLE					0
-#define MAX_WPA_PSK_STATE				1
+/* */
+/* WSC State machine: states, events, total function # */
+/* */
 
-#define WPA_MACHINE_BASE                0
-#define MT2_EAPPacket                   0
-#define MT2_EAPOLStart                  1
-#define MT2_EAPOLLogoff                 2
-#define MT2_EAPOLKey                    3
-#define MT2_EAPOLASFAlert               4
-#define MAX_WPA_PSK_MSG                 5
-
-#define	WPA_PSK_FUNC_SIZE				(MAX_WPA_PSK_STATE * MAX_WPA_PSK_MSG)
-
-//
-// STA's CISCO-AIRONET State machine: states, events, total function #
-//
-#define AIRONET_IDLE					0
-#define	AIRONET_SCANNING				1
-#define MAX_AIRONET_STATE				2
-
-#define AIRONET_MACHINE_BASE		    0
-#define MT2_AIRONET_MSG				    0
-#define MT2_AIRONET_SCAN_REQ		    1
-#define MT2_AIRONET_SCAN_DONE		    2
-#define MAX_AIRONET_MSG				    3
-
-#define	AIRONET_FUNC_SIZE				(MAX_AIRONET_STATE * MAX_AIRONET_MSG)
-
-//
-// AP's CONTROL/CONNECT state machine: states, events, total function #
-//
+/* */
+/* AP's CONTROL/CONNECT state machine: states, events, total function # */
+/* */
 #define AP_CNTL_FUNC_SIZE               1
 
-//
-// AP's ASSOC state machine: states, events, total function #
-//
+/* */
+/* AP's ASSOC state machine: states, events, total function # */
+/* */
 #define AP_ASSOC_IDLE                   0
 #define AP_MAX_ASSOC_STATE              1
 
@@ -873,36 +840,25 @@
 
 #define AP_ASSOC_FUNC_SIZE              (AP_MAX_ASSOC_STATE * AP_MAX_ASSOC_MSG)
 
-//
-// AP's AUTHENTICATION state machine: states, events, total function #
-//
+/* */
+/* AP's AUTHENTICATION state machine: states, events, total function # */
+/* */
 #define AP_AUTH_REQ_IDLE                0
 #define AP_MAX_AUTH_STATE               1
 
 #define AP_AUTH_MACHINE_BASE            0
 #define APMT2_MLME_DEAUTH_REQ           0
 #define APMT2_CLS2ERR                   1
-#define AP_MAX_AUTH_MSG                 2
+#define APMT2_PEER_DEAUTH               2
+#define APMT2_PEER_AUTH_REQ				3
+#define APMT2_PEER_AUTH_CONFIRM			4
+#define AP_MAX_AUTH_MSG                 5
 
 #define AP_AUTH_FUNC_SIZE               (AP_MAX_AUTH_STATE * AP_MAX_AUTH_MSG)
 
-//
-// AP's AUTH-RSP state machine: states, events, total function #
-//
-#define AP_AUTH_RSP_IDLE                0
-#define AP_MAX_AUTH_RSP_STATE           1
-
-#define AP_AUTH_RSP_MACHINE_BASE        0
-#define APMT2_AUTH_CHALLENGE_TIMEOUT    0
-#define APMT2_PEER_AUTH_ODD             1
-#define APMT2_PEER_DEAUTH               2
-#define AP_MAX_AUTH_RSP_MSG             3
-
-#define AP_AUTH_RSP_FUNC_SIZE           (AP_MAX_AUTH_RSP_STATE * AP_MAX_AUTH_RSP_MSG)
-
-//
-// AP's SYNC state machine: states, events, total function #
-//
+/* */
+/* AP's SYNC state machine: states, events, total function # */
+/* */
 #define AP_SYNC_IDLE                    0
 #define AP_SCAN_LISTEN					1
 #define AP_MAX_SYNC_STATE               2
@@ -918,30 +874,30 @@
 
 #define AP_SYNC_FUNC_SIZE               (AP_MAX_SYNC_STATE * AP_MAX_SYNC_MSG)
 
-//
-// AP's WPA state machine: states, events, total function #
-//
-#define AP_WPA_PTK                      0
-#define AP_MAX_WPA_PTK_STATE            1
+/* */
+/* Common WPA state machine: states, events, total function # */
+/* */
+#define WPA_PTK                      0
+#define MAX_WPA_PTK_STATE            1
 
-#define AP_WPA_MACHINE_BASE             0
-#define APMT2_EAPPacket                 0
-#define APMT2_EAPOLStart                1
-#define APMT2_EAPOLLogoff               2
-#define APMT2_EAPOLKey                  3
-#define APMT2_EAPOLASFAlert             4
-#define AP_MAX_WPA_MSG                  5
+#define WPA_MACHINE_BASE             0
+#define MT2_EAPPacket                0
+#define MT2_EAPOLStart               1
+#define MT2_EAPOLLogoff              2
+#define MT2_EAPOLKey                 3
+#define MT2_EAPOLASFAlert            4
+#define MAX_WPA_MSG                  5
 
-#define AP_WPA_FUNC_SIZE                (AP_MAX_WPA_PTK_STATE * AP_MAX_WPA_MSG)
+#define WPA_FUNC_SIZE                (MAX_WPA_PTK_STATE * MAX_WPA_MSG)
 
-// =============================================================================
+/* ============================================================================= */
 
-// value domain of 802.11 header FC.Tyte, which is b3..b2 of the 1st-byte of MAC header
+/* value domain of 802.11 header FC.Tyte, which is b3..b2 of the 1st-byte of MAC header */
 #define BTYPE_MGMT                  0
 #define BTYPE_CNTL                  1
 #define BTYPE_DATA                  2
 
-// value domain of 802.11 MGMT frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
+/* value domain of 802.11 MGMT frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header */
 #define SUBTYPE_ASSOC_REQ           0
 #define SUBTYPE_ASSOC_RSP           1
 #define SUBTYPE_REASSOC_REQ         2
@@ -956,7 +912,7 @@
 #define SUBTYPE_ACTION              13
 #define SUBTYPE_ACTION_NO_ACK              14
 
-// value domain of 802.11 CNTL frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
+/* value domain of 802.11 CNTL frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header */
 #define SUBTYPE_WRAPPER       	7
 #define SUBTYPE_BLOCK_ACK_REQ       8
 #define SUBTYPE_BLOCK_ACK           9
@@ -967,7 +923,7 @@
 #define SUBTYPE_CFEND               14
 #define SUBTYPE_CFEND_CFACK         15
 
-// value domain of 802.11 DATA frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
+/* value domain of 802.11 DATA frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header */
 #define SUBTYPE_DATA                0
 #define SUBTYPE_DATA_CFACK          1
 #define SUBTYPE_DATA_CFPOLL         2
@@ -985,15 +941,15 @@
 #define SUBTYPE_QOS_CFPOLL          14
 #define SUBTYPE_QOS_CFACK_CFPOLL    15
 
-// ACK policy of QOS Control field bit 6:5
-#define NORMAL_ACK                  0x00  // b6:5 = 00
-#define NO_ACK                      0x20  // b6:5 = 01
-#define NO_EXPLICIT_ACK             0x40  // b6:5 = 10
-#define BLOCK_ACK                   0x60  // b6:5 = 11
+/* ACK policy of QOS Control field bit 6:5 */
+#define NORMAL_ACK                  0x00	/* b6:5 = 00 */
+#define NO_ACK                      0x20	/* b6:5 = 01 */
+#define NO_EXPLICIT_ACK             0x40	/* b6:5 = 10 */
+#define BLOCK_ACK                   0x60	/* b6:5 = 11 */
 
-//
-// rtmp_data.c use these definition
-//
+/* */
+/* rtmp_data.c use these definition */
+/* */
 #define LENGTH_802_11               24
 #define LENGTH_802_11_AND_H         30
 #define LENGTH_802_11_CRC_H         34
@@ -1007,42 +963,42 @@
 #define LENGTH_CRC                  4
 #define MAX_SEQ_NUMBER              0x0fff
 #define LENGTH_802_3_NO_TYPE		12
-#define LENGTH_802_1Q				4 /* VLAN related */
+#define LENGTH_802_1Q				4	/* VLAN related */
 
-// STA_CSR4.field.TxResult
+/* STA_CSR4.field.TxResult */
 #define TX_RESULT_SUCCESS           0
 #define TX_RESULT_ZERO_LENGTH       1
 #define TX_RESULT_UNDER_RUN         2
 #define TX_RESULT_OHY_ERROR         4
 #define TX_RESULT_RETRY_FAIL        6
 
-// All PHY rate summary in TXD
-// Preamble MODE in TxD
+/* All PHY rate summary in TXD */
+/* Preamble MODE in TxD */
 #define MODE_CCK	0
 #define MODE_OFDM   1
 #define MODE_HTMIX	2
 #define MODE_HTGREENFIELD	3
 
-// MCS for CCK.  BW.SGI.STBC are reserved
-#define MCS_LONGP_RATE_1                      0	 // long preamble CCK 1Mbps
-#define MCS_LONGP_RATE_2                      1	// long preamble CCK 1Mbps
-#define MCS_LONGP_RATE_5_5                    2
-#define MCS_LONGP_RATE_11                     3
-#define MCS_SHORTP_RATE_1                      4	 // long preamble CCK 1Mbps. short is forbidden in 1Mbps
-#define MCS_SHORTP_RATE_2                      5	// short preamble CCK 2Mbps
+/* MCS for CCK.  BW.SGI.STBC are reserved */
+#define MCS_longP_RATE_1                      0	/* long preamble CCK 1Mbps */
+#define MCS_longP_RATE_2                      1	/* long preamble CCK 1Mbps */
+#define MCS_longP_RATE_5_5                    2
+#define MCS_longP_RATE_11                     3
+#define MCS_SHORTP_RATE_1                      4	/* long preamble CCK 1Mbps. short is forbidden in 1Mbps */
+#define MCS_SHORTP_RATE_2                      5	/* short preamble CCK 2Mbps */
 #define MCS_SHORTP_RATE_5_5                    6
 #define MCS_SHORTP_RATE_11                     7
-// To send duplicate legacy OFDM. set BW=BW_40.  SGI.STBC are reserved
-#define MCS_RATE_6                      0   // legacy OFDM
-#define MCS_RATE_9                      1   // OFDM
-#define MCS_RATE_12                     2   // OFDM
-#define MCS_RATE_18                     3   // OFDM
-#define MCS_RATE_24                     4  // OFDM
-#define MCS_RATE_36                     5   // OFDM
-#define MCS_RATE_48                     6  // OFDM
-#define MCS_RATE_54                     7 // OFDM
-// HT
-#define MCS_0		0	// 1S
+/* To send duplicate legacy OFDM. set BW=BW_40.  SGI.STBC are reserved */
+#define MCS_RATE_6                      0	/* legacy OFDM */
+#define MCS_RATE_9                      1	/* OFDM */
+#define MCS_RATE_12                     2	/* OFDM */
+#define MCS_RATE_18                     3	/* OFDM */
+#define MCS_RATE_24                     4	/* OFDM */
+#define MCS_RATE_36                     5	/* OFDM */
+#define MCS_RATE_48                     6	/* OFDM */
+#define MCS_RATE_54                     7	/* OFDM */
+/* HT */
+#define MCS_0		0	/* 1S */
 #define MCS_1		1
 #define MCS_2		2
 #define MCS_3		3
@@ -1050,7 +1006,7 @@
 #define MCS_5		5
 #define MCS_6		6
 #define MCS_7		7
-#define MCS_8		8	// 2S
+#define MCS_8		8	/* 2S */
 #define MCS_9		9
 #define MCS_10		10
 #define MCS_11		11
@@ -1058,7 +1014,7 @@
 #define MCS_13		13
 #define MCS_14		14
 #define MCS_15		15
-#define MCS_16		16	// 3*3
+#define MCS_16		16	/* 3*3 */
 #define MCS_17		17
 #define MCS_18		18
 #define MCS_19		19
@@ -1069,49 +1025,48 @@
 #define MCS_32		32
 #define MCS_AUTO		33
 
-// OID_HTPHYMODE
-// MODE
+/* OID_HTPHYMODE */
+/* MODE */
 #define HTMODE_MM	0
 #define HTMODE_GF	1
 
-// Fixed Tx MODE - HT, CCK or OFDM
+/* Fixed Tx MODE - HT, CCK or OFDM */
 #define FIXED_TXMODE_HT		0
 #define FIXED_TXMODE_CCK	1
 #define FIXED_TXMODE_OFDM 	2
-// BW
+/* BW */
 #define BW_20		BAND_WIDTH_20
 #define BW_40		BAND_WIDTH_40
 #define BW_BOTH		BAND_WIDTH_BOTH
-#define BW_10		BAND_WIDTH_10	// 802.11j has 10MHz. This definition is for internal usage. doesn't fill in the IE or other field.
+#define BW_10		BAND_WIDTH_10	/* 802.11j has 10MHz. This definition is for internal usage. doesn't fill in the IE or other field. */
 
-// SHORTGI
-#define GI_400		GAP_INTERVAL_400	// only support in HT mode
+/* SHORTGI */
+#define GI_400		GAP_INTERVAL_400	/* only support in HT mode */
 #define GI_BOTH		GAP_INTERVAL_BOTH
 #define GI_800		GAP_INTERVAL_800
-// STBC
+/* STBC */
 #define STBC_NONE	0
-#define STBC_USE	1	// limited use in rt2860b phy
-#define RXSTBC_ONE	1	// rx support of one spatial stream
-#define RXSTBC_TWO	2	// rx support of 1 and 2 spatial stream
-#define RXSTBC_THR	3	// rx support of 1~3 spatial stream
-// MCS FEEDBACK
-#define MCSFBK_NONE	0  // not support mcs feedback /
-#define MCSFBK_RSV	1	// reserved
-#define MCSFBK_UNSOLICIT	2	// only support unsolict mcs feedback
-#define MCSFBK_MRQ	3	// response to both MRQ and unsolict mcs feedback
+#define STBC_USE	1	/* limited use in rt2860b phy */
+#define RXSTBC_ONE	1	/* rx support of one spatial stream */
+#define RXSTBC_TWO	2	/* rx support of 1 and 2 spatial stream */
+#define RXSTBC_THR	3	/* rx support of 1~3 spatial stream */
+/* MCS FEEDBACK */
+#define MCSFBK_NONE	0	/* not support mcs feedback / */
+#define MCSFBK_RSV	1	/* reserved */
+#define MCSFBK_UNSOLICIT	2	/* only support unsolict mcs feedback */
+#define MCSFBK_MRQ	3	/* response to both MRQ and unsolict mcs feedback */
 
-// MIMO power safe
+/* MIMO power safe */
 #define	MMPS_STATIC	0
 #define	MMPS_DYNAMIC		1
 #define   MMPS_RSV		2
 #define MMPS_ENABLE		3
 
-
-// A-MSDU size
+/* A-MSDU size */
 #define	AMSDU_0	0
 #define	AMSDU_1		1
 
-// MCS use 7 bits
+/* MCS use 7 bits */
 #define TXRATEMIMO		0x80
 #define TXRATEMCS		0x7F
 #define TXRATEOFDM		0x7F
@@ -1119,73 +1074,77 @@
 #define RATE_2                      1
 #define RATE_5_5                    2
 #define RATE_11                     3
-#define RATE_6                      4   // OFDM
-#define RATE_9                      5   // OFDM
-#define RATE_12                     6   // OFDM
-#define RATE_18                     7   // OFDM
-#define RATE_24                     8   // OFDM
-#define RATE_36                     9   // OFDM
-#define RATE_48                     10  // OFDM
-#define RATE_54                     11  // OFDM
+#define RATE_6                      4	/* OFDM */
+#define RATE_9                      5	/* OFDM */
+#define RATE_12                     6	/* OFDM */
+#define RATE_18                     7	/* OFDM */
+#define RATE_24                     8	/* OFDM */
+#define RATE_36                     9	/* OFDM */
+#define RATE_48                     10	/* OFDM */
+#define RATE_54                     11	/* OFDM */
 #define RATE_FIRST_OFDM_RATE        RATE_6
 #define RATE_LAST_OFDM_RATE        	RATE_54
-#define RATE_6_5                    12  // HT mix
-#define RATE_13                     13  // HT mix
-#define RATE_19_5                   14  // HT mix
-#define RATE_26                     15  // HT mix
-#define RATE_39                     16  // HT mix
-#define RATE_52                     17  // HT mix
-#define RATE_58_5                   18  // HT mix
-#define RATE_65                     19  // HT mix
-#define RATE_78                     20  // HT mix
-#define RATE_104                    21  // HT mix
-#define RATE_117                    22  // HT mix
-#define RATE_130                    23  // HT mix
-//#define RATE_AUTO_SWITCH            255 // for StaCfg.FixedTxRate only
+#define RATE_6_5                    12	/* HT mix */
+#define RATE_13                     13	/* HT mix */
+#define RATE_19_5                   14	/* HT mix */
+#define RATE_26                     15	/* HT mix */
+#define RATE_39                     16	/* HT mix */
+#define RATE_52                     17	/* HT mix */
+#define RATE_58_5                   18	/* HT mix */
+#define RATE_65                     19	/* HT mix */
+#define RATE_78                     20	/* HT mix */
+#define RATE_104                    21	/* HT mix */
+#define RATE_117                    22	/* HT mix */
+#define RATE_130                    23	/* HT mix */
+/*#define RATE_AUTO_SWITCH            255 // for StaCfg.FixedTxRate only */
 #define HTRATE_0                      12
 #define RATE_FIRST_MM_RATE        HTRATE_0
 #define RATE_FIRST_HT_RATE        HTRATE_0
 #define RATE_LAST_HT_RATE        HTRATE_0
 
-// pTxWI->txop
-#define IFS_HTTXOP                 0	// The txop will be handles by ASIC.
+/* pTxWI->txop */
+#define IFS_HTTXOP                 0	/* The txop will be handles by ASIC. */
 #define IFS_PIFS                    1
 #define IFS_SIFS                    2
 #define IFS_BACKOFF                 3
 
-// pTxD->RetryMode
-#define LONG_RETRY                  1
+/* pTxD->RetryMode */
+#define long_RETRY                  1
 #define SHORT_RETRY                 0
 
-// Country Region definition
+/* Country Region definition */
 #define REGION_MINIMUM_BG_BAND            0
-#define REGION_0_BG_BAND                  0       // 1-11
-#define REGION_1_BG_BAND                  1       // 1-13
-#define REGION_2_BG_BAND                  2       // 10-11
-#define REGION_3_BG_BAND                  3       // 10-13
-#define REGION_4_BG_BAND                  4       // 14
-#define REGION_5_BG_BAND                  5       // 1-14
-#define REGION_6_BG_BAND                  6       // 3-9
-#define REGION_7_BG_BAND                  7       // 5-13
-#define REGION_31_BG_BAND                 31       // 5-13
+#define REGION_0_BG_BAND                  0	/* 1-11 */
+#define REGION_1_BG_BAND                  1	/* 1-13 */
+#define REGION_2_BG_BAND                  2	/* 10-11 */
+#define REGION_3_BG_BAND                  3	/* 10-13 */
+#define REGION_4_BG_BAND                  4	/* 14 */
+#define REGION_5_BG_BAND                  5	/* 1-14 */
+#define REGION_6_BG_BAND                  6	/* 3-9 */
+#define REGION_7_BG_BAND                  7	/* 5-13 */
+#define REGION_31_BG_BAND                 31	/* 5-13 */
 #define REGION_MAXIMUM_BG_BAND            7
 
 #define REGION_MINIMUM_A_BAND             0
-#define REGION_0_A_BAND                   0       // 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165
-#define REGION_1_A_BAND                   1       // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
-#define REGION_2_A_BAND                   2       // 36, 40, 44, 48, 52, 56, 60, 64
-#define REGION_3_A_BAND                   3       // 52, 56, 60, 64, 149, 153, 157, 161
-#define REGION_4_A_BAND                   4       // 149, 153, 157, 161, 165
-#define REGION_5_A_BAND                   5       // 149, 153, 157, 161
-#define REGION_6_A_BAND                   6       // 36, 40, 44, 48
-#define REGION_7_A_BAND                   7       // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165
-#define REGION_8_A_BAND                   8       // 52, 56, 60, 64
-#define REGION_9_A_BAND                   9       // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165
-#define REGION_10_A_BAND                  10	  // 36, 40, 44, 48, 149, 153, 157, 161, 165
-#define REGION_11_A_BAND                  11	  // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161
-#define REGION_MAXIMUM_A_BAND             11
+#define REGION_0_A_BAND                   0	/* 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165 */
+#define REGION_1_A_BAND                   1	/* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 */
+#define REGION_2_A_BAND                   2	/* 36, 40, 44, 48, 52, 56, 60, 64 */
+#define REGION_3_A_BAND                   3	/* 52, 56, 60, 64, 149, 153, 157, 161 */
+#define REGION_4_A_BAND                   4	/* 149, 153, 157, 161, 165 */
+#define REGION_5_A_BAND                   5	/* 149, 153, 157, 161 */
+#define REGION_6_A_BAND                   6	/* 36, 40, 44, 48 */
+#define REGION_7_A_BAND                   7	/* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, 169, 173 */
+#define REGION_8_A_BAND                   8	/* 52, 56, 60, 64 */
+#define REGION_9_A_BAND                   9	/* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165 */
+#define REGION_10_A_BAND                  10	/* 36, 40, 44, 48, 149, 153, 157, 161, 165 */
+#define REGION_11_A_BAND                  11	/* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161 */
+#define REGION_12_A_BAND                  12	/* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 */
+#define REGION_13_A_BAND                  13	/* 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161 */
+#define REGION_14_A_BAND                  14	/* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165 */
+#define REGION_15_A_BAND                  15	/* 149, 153, 157, 161, 165, 169, 173 */
+#define REGION_MAXIMUM_A_BAND             15
 
-// pTxD->CipherAlg
+/* pTxD->CipherAlg */
 #define CIPHER_NONE                 0
 #define CIPHER_WEP64                1
 #define CIPHER_WEP128               2
@@ -1193,20 +1152,10 @@
 #define CIPHER_AES                  4
 #define CIPHER_CKIP64               5
 #define CIPHER_CKIP128              6
-#define CIPHER_TKIP_NO_MIC          7       // MIC appended by driver: not a valid value in hardware key table
+#define CIPHER_TKIP_NO_MIC          7	/* MIC appended by driver: not a valid value in hardware key table */
 #define CIPHER_SMS4					8
 
-// value domain of pAd->RfIcType
-#define RFIC_2820                   1       // 2.4G 2T3R
-#define RFIC_2850                   2       // 2.4G/5G 2T3R
-#define RFIC_2720                   3       // 2.4G 1T2R
-#define RFIC_2750                   4       // 2.4G/5G 1T2R
-#define RFIC_3020                   5       // 2.4G 1T1R
-#define RFIC_2020                   6       // 2.4G B/G
-#define RFIC_3021                   7       // 2.4G 1T2R
-#define RFIC_3022                   8       // 2.4G 2T2R
-
-// LED Status.
+/* LED Status. */
 #define LED_LINK_DOWN               0
 #define LED_LINK_UP                 1
 #define LED_RADIO_OFF               2
@@ -1216,35 +1165,35 @@
 #define LED_ON_SITE_SURVEY          6
 #define LED_POWER_UP                7
 
-// value domain of pAd->LedCntl.LedMode and E2PROM
+/* value domain of pAd->LedCntl.LedMode and E2PROM */
 #define LED_MODE_DEFAULT            0
 #define LED_MODE_TWO_LED			1
-#define LED_MODE_SIGNAL_STREGTH		8  // EEPROM define =8
+/*#define LED_MODE_SIGNAL_STREGTH               8  // EEPROM define =8 */
+#define LED_MODE_SIGNAL_STREGTH		0x40	/* EEPROM define = 64 */
 
-// RC4 init value, used fro WEP & TKIP
-#define PPPINITFCS32                0xffffffff   /* Initial FCS value */
+/* RC4 init value, used fro WEP & TKIP */
+#define PPPINITFCS32                0xffffffff	/* Initial FCS value */
 
-// value domain of pAd->StaCfg.PortSecured. 802.1X controlled port definition
+/* value domain of pAd->StaCfg.PortSecured. 802.1X controlled port definition */
 #define WPA_802_1X_PORT_SECURED     1
 #define WPA_802_1X_PORT_NOT_SECURED 2
 
 #define PAIRWISE_KEY                1
 #define GROUP_KEY                   2
 
-//definition of DRS
+/*definition of DRS */
 #define MAX_STEP_OF_TX_RATE_SWITCH	32
 
-
-// pre-allocated free NDIS PACKET/BUFFER poll for internal usage
+/* pre-allocated free NDIS PACKET/BUFFER poll for internal usage */
 #define MAX_NUM_OF_FREE_NDIS_PACKET 128
 
-//Block ACK
+/*Block ACK */
 #define MAX_TX_REORDERBUF   64
 #define MAX_RX_REORDERBUF   64
 #define DEFAULT_TX_TIMEOUT   30
 #define DEFAULT_RX_TIMEOUT   30
 
-// definition of Recipient or Originator
+/* definition of Recipient or Originator */
 #define I_RECIPIENT                  TRUE
 #define I_ORIGINATOR                   FALSE
 
@@ -1252,46 +1201,45 @@
 #define DEFAULT_RF_TX_POWER         5
 
 #define MAX_INI_BUFFER_SIZE			4096
-#define MAX_PARAM_BUFFER_SIZE		(2048) // enough for ACL (18*64)
-											//18 : the length of Mac address acceptable format "01:02:03:04:05:06;")
-											//64 : MAX_NUM_OF_ACL_LIST
-// definition of pAd->OpMode
+#define MAX_PARAM_BUFFER_SIZE		(2048)	/* enough for ACL (18*64) */
+											/*18 : the length of Mac address acceptable format "01:02:03:04:05:06;") */
+											/*64 : MAX_NUM_OF_ACL_LIST */
+/* definition of pAd->OpMode */
 #define OPMODE_STA                  0
 #define OPMODE_AP                   1
-//#define OPMODE_L3_BRG               2       // as AP and STA at the same time
+/*#define OPMODE_L3_BRG               2       // as AP and STA at the same time */
 
-// ========================= AP rtmp_def.h ===========================
-// value domain for pAd->EventTab.Log[].Event
-#define EVENT_RESET_ACCESS_POINT    0 // Log = "hh:mm:ss   Restart Access Point"
-#define EVENT_ASSOCIATED            1 // Log = "hh:mm:ss   STA 00:01:02:03:04:05 associated"
-#define EVENT_DISASSOCIATED         2 // Log = "hh:mm:ss   STA 00:01:02:03:04:05 left this BSS"
-#define EVENT_AGED_OUT              3 // Log = "hh:mm:ss   STA 00:01:02:03:04:05 was aged-out and removed from this BSS"
+/* ========================= AP rtmp_def.h =========================== */
+/* value domain for pAd->EventTab.Log[].Event */
+#define EVENT_RESET_ACCESS_POint    0	/* Log = "hh:mm:ss   Restart Access Point" */
+#define EVENT_ASSOCIATED            1	/* Log = "hh:mm:ss   STA 00:01:02:03:04:05 associated" */
+#define EVENT_DISASSOCIATED         2	/* Log = "hh:mm:ss   STA 00:01:02:03:04:05 left this BSS" */
+#define EVENT_AGED_OUT              3	/* Log = "hh:mm:ss   STA 00:01:02:03:04:05 was aged-out and removed from this BSS" */
 #define EVENT_COUNTER_M             4
 #define EVENT_INVALID_PSK           5
 #define EVENT_MAX_EVENT_TYPE        6
-// ==== end of AP rtmp_def.h ============
+/* ==== end of AP rtmp_def.h ============ */
 
-// definition RSSI Number
+/* definition RSSI Number */
 #define RSSI_0					0
 #define RSSI_1					1
 #define RSSI_2					2
 
-// definition of radar detection
-#define RD_NORMAL_MODE				0	// Not found radar signal
-#define RD_SWITCHING_MODE			1	// Found radar signal, and doing channel switch
-#define RD_SILENCE_MODE				2	// After channel switch, need to be silence a while to ensure radar not found
+/* definition of radar detection */
+#define RD_NORMAL_MODE				0	/* Not found radar signal */
+#define RD_SWITCHING_MODE			1	/* Found radar signal, and doing channel switch */
+#define RD_SILENCE_MODE				2	/* After channel switch, need to be silence a while to ensure radar not found */
 
-//Driver defined cid for mapping status and command.
+/*Driver defined cid for mapping status and command. */
 #define  SLEEPCID	0x11
 #define  WAKECID	0x22
 #define  QUERYPOWERCID	0x33
 #define  OWNERMCU	0x1
 #define  OWNERCPU	0x0
 
-// MBSSID definition
+/* MBSSID definition */
 #define ENTRY_NOT_FOUND             0xFF
 
-
 /* After Linux 2.6.9,
  * VLAN module use Private (from user) interface flags (netdevice->priv_flags).
  * #define IFF_802_1Q_VLAN 0x1         --    802.1Q VLAN device.  in if.h
@@ -1305,19 +1253,21 @@
 #define INT_APCLI                   0x0400
 #define INT_MESH                   	0x0500
 
-// Use bitmap to allow coexist of ATE_TXFRAME and ATE_RXFRAME(i.e.,to support LoopBack mode)
+#define INF_MAIN_DEV_NAME		"wlan"
+#define INF_MBSSID_DEV_NAME		"ra"
+#define INF_WDS_DEV_NAME		"wds"
+#define INF_APCLI_DEV_NAME		"apcli"
+#define INF_MESH_DEV_NAME		"mesh"
 
-// WEP Key TYPE
+/* WEP Key TYPE */
 #define WEP_HEXADECIMAL_TYPE    0
 #define WEP_ASCII_TYPE          1
 
-
-
-// WIRELESS EVENTS definition
+/* WIRELESS EVENTS definition */
 /* Max number of char in custom event, refer to wireless_tools.28/wireless.20.h */
 #define IW_CUSTOM_MAX_LEN				  			255	/* In bytes */
 
-// For system event - start
+/* For system event - start */
 #define	IW_SYS_EVENT_FLAG_START                     0x0200
 #define	IW_ASSOC_EVENT_FLAG                         0x0200
 #define	IW_DISASSOC_EVENT_FLAG                      0x0201
@@ -1338,12 +1288,12 @@
 #define IW_STA_LINKDOWN_EVENT_FLAG					0x0210
 #define IW_SCAN_COMPLETED_EVENT_FLAG				0x0211
 #define IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG				0x0212
-// if add new system event flag, please upadte the IW_SYS_EVENT_FLAG_END
+/* if add new system event flag, please upadte the IW_SYS_EVENT_FLAG_END */
 #define	IW_SYS_EVENT_FLAG_END                       0x0212
 #define	IW_SYS_EVENT_TYPE_NUM						(IW_SYS_EVENT_FLAG_END - IW_SYS_EVENT_FLAG_START + 1)
-// For system event - end
+/* For system event - end */
 
-// For spoof attack event - start
+/* For spoof attack event - start */
 #define	IW_SPOOF_EVENT_FLAG_START                   0x0300
 #define IW_CONFLICT_SSID_EVENT_FLAG					0x0300
 #define IW_SPOOF_ASSOC_RESP_EVENT_FLAG				0x0301
@@ -1355,12 +1305,12 @@
 #define IW_SPOOF_DEAUTH_EVENT_FLAG					0x0307
 #define IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG			0x0308
 #define IW_REPLAY_ATTACK_EVENT_FLAG					0x0309
-// if add new spoof attack event flag, please upadte the IW_SPOOF_EVENT_FLAG_END
+/* if add new spoof attack event flag, please upadte the IW_SPOOF_EVENT_FLAG_END */
 #define	IW_SPOOF_EVENT_FLAG_END                     0x0309
 #define	IW_SPOOF_EVENT_TYPE_NUM						(IW_SPOOF_EVENT_FLAG_END - IW_SPOOF_EVENT_FLAG_START + 1)
-// For spoof attack event - end
+/* For spoof attack event - end */
 
-// For flooding attack event - start
+/* For flooding attack event - start */
 #define	IW_FLOOD_EVENT_FLAG_START                   0x0400
 #define IW_FLOOD_AUTH_EVENT_FLAG					0x0400
 #define IW_FLOOD_ASSOC_REQ_EVENT_FLAG				0x0401
@@ -1369,18 +1319,18 @@
 #define IW_FLOOD_DISASSOC_EVENT_FLAG				0x0404
 #define IW_FLOOD_DEAUTH_EVENT_FLAG					0x0405
 #define IW_FLOOD_EAP_REQ_EVENT_FLAG					0x0406
-// if add new flooding attack event flag, please upadte the IW_FLOOD_EVENT_FLAG_END
+/* if add new flooding attack event flag, please upadte the IW_FLOOD_EVENT_FLAG_END */
 #define	IW_FLOOD_EVENT_FLAG_END                   	0x0406
 #define	IW_FLOOD_EVENT_TYPE_NUM						(IW_FLOOD_EVENT_FLAG_END - IW_FLOOD_EVENT_FLAG_START + 1)
-// For flooding attack - end
+/* For flooding attack - end */
 
-// End - WIRELESS EVENTS definition
+/* End - WIRELESS EVENTS definition */
 
-// definition for DLS, kathy
+/* definition for DLS, kathy */
 #define	MAX_NUM_OF_INIT_DLS_ENTRY   1
 #define	MAX_NUM_OF_DLS_ENTRY        MAX_NUMBER_OF_DLS_ENTRY
 
-//Block ACK , rt2860, kathy
+/*Block ACK, kathy */
 #define MAX_TX_REORDERBUF		64
 #define MAX_RX_REORDERBUF		64
 #define DEFAULT_TX_TIMEOUT		30
@@ -1392,65 +1342,48 @@
 #define IW_ESSID_MAX_SIZE   		32
 #endif
 
-#ifdef MCAST_RATE_SPECIFIC
-#define MCAST_DISABLE	0
-#define MCAST_CCK		1
-#define MCAST_OFDM		2
-#define MCAST_HTMIX		3
-#endif // MCAST_RATE_SPECIFIC //
-
-#ifdef RT2860
-// For AsicRadioOff/AsicRadioOn/AsicForceWakeup function
-// This is to indicate from where to call this function.
-#define DOT11POWERSAVE		0	// TO do .11 power save sleep
-#define GUIRADIO_OFF		1	// To perform Radio OFf command from GUI
-#define RTMP_HALT			2	// Called from Halt handler.
-#define GUI_IDLE_POWER_SAVE	3	// Call to sleep before link up with AP
-#define FROM_TX				4	// Force wake up from Tx packet.
-#endif
-#ifdef RT2870
-// For AsicRadioOff/AsicRadioOn function
+/* For AsicRadioOff/AsicRadioOn function */
 #define DOT11POWERSAVE		0
 #define GUIRADIO_OFF		1
 #define RTMP_HALT		    2
 #define GUI_IDLE_POWER_SAVE		3
-#endif
+/* -- */
 
-// definition for WpaSupport flag
+/* definition for WpaSupport flag */
 #define WPA_SUPPLICANT_DISABLE				0
 #define WPA_SUPPLICANT_ENABLE				1
 #define	WPA_SUPPLICANT_ENABLE_WITH_WEB_UI	2
 
-// Endian byte swapping codes
+/* Endian byte swapping codes */
 #define SWAP16(x) \
-    ((UINT16)( \
-    (((UINT16)(x) & (UINT16) 0x00ffU) << 8) | \
-    (((UINT16)(x) & (UINT16) 0xff00U) >> 8) ))
+    ((u16)( \
+    (((u16)(x) & (u16)0x00ffU) << 8) | \
+    (((u16)(x) & (u16)0xff00U) >> 8) ))
 
 #define SWAP32(x) \
-    ((UINT32)( \
-    (((UINT32)(x) & (UINT32) 0x000000ffUL) << 24) | \
-    (((UINT32)(x) & (UINT32) 0x0000ff00UL) <<  8) | \
-    (((UINT32)(x) & (UINT32) 0x00ff0000UL) >>  8) | \
-    (((UINT32)(x) & (UINT32) 0xff000000UL) >> 24) ))
+    ((u32)( \
+    (((u32)(x) & (u32)0x000000ffUL) << 24) | \
+    (((u32)(x) & (u32)0x0000ff00UL) <<  8) | \
+    (((u32)(x) & (u32)0x00ff0000UL) >>  8) | \
+    (((u32)(x) & (u32)0xff000000UL) >> 24) ))
 
 #define SWAP64(x) \
-    ((UINT64)( \
-    (UINT64)(((UINT64)(x) & (UINT64) 0x00000000000000ffULL) << 56) | \
-    (UINT64)(((UINT64)(x) & (UINT64) 0x000000000000ff00ULL) << 40) | \
-    (UINT64)(((UINT64)(x) & (UINT64) 0x0000000000ff0000ULL) << 24) | \
-    (UINT64)(((UINT64)(x) & (UINT64) 0x00000000ff000000ULL) <<  8) | \
-    (UINT64)(((UINT64)(x) & (UINT64) 0x000000ff00000000ULL) >>  8) | \
-    (UINT64)(((UINT64)(x) & (UINT64) 0x0000ff0000000000ULL) >> 24) | \
-    (UINT64)(((UINT64)(x) & (UINT64) 0x00ff000000000000ULL) >> 40) | \
-    (UINT64)(((UINT64)(x) & (UINT64) 0xff00000000000000ULL) >> 56) ))
+    ((u64)( \
+    (u64)(((u64)(x) & (u64)0x00000000000000ffULL) << 56) | \
+    (u64)(((u64)(x) & (u64)0x000000000000ff00ULL) << 40) | \
+    (u64)(((u64)(x) & (u64)0x0000000000ff0000ULL) << 24) | \
+    (u64)(((u64)(x) & (u64)0x00000000ff000000ULL) <<  8) | \
+    (u64)(((u64)(x) & (u64)0x000000ff00000000ULL) >>  8) | \
+    (u64)(((u64)(x) & (u64)0x0000ff0000000000ULL) >> 24) | \
+    (u64)(((u64)(x) & (u64)0x00ff000000000000ULL) >> 40) | \
+    (u64)(((u64)(x) & (u64)0xff00000000000000ULL) >> 56) ))
 
-#define cpu2le64(x) ((UINT64)(x))
-#define le2cpu64(x) ((UINT64)(x))
-#define cpu2le32(x) ((UINT32)(x))
-#define le2cpu32(x) ((UINT32)(x))
-#define cpu2le16(x) ((UINT16)(x))
-#define le2cpu16(x) ((UINT16)(x))
+#define cpu2le64(x) ((u64)(x))
+#define le2cpu64(x) ((u64)(x))
+#define cpu2le32(x) ((u32)(x))
+#define le2cpu32(x) ((u32)(x))
+#define cpu2le16(x) ((u16)(x))
+#define le2cpu16(x) ((u16)(x))
 #define cpu2be64(x) SWAP64((x))
 #define be2cpu64(x) SWAP64((x))
 #define cpu2be32(x) SWAP32((x))
@@ -1458,6 +1391,36 @@
 #define cpu2be16(x) SWAP16((x))
 #define be2cpu16(x) SWAP16((x))
 
-#endif  // __RTMP_DEF_H__
+#define ABS(_x, _y) ((_x) > (_y)) ? ((_x) -(_y)) : ((_y) -(_x))
 
+#define A2Dec(_X, _p)				\
+{									\
+	u8 *p;						\
+	_X = 0;							\
+	p = _p;							\
+	while (((*p >= '0') && (*p <= '9')))		\
+	{												\
+		if ((*p >= '0') && (*p <= '9'))		\
+			_X = _X * 10 + *p - 48;					\
+		p++;										\
+	}												\
+}
 
+#define A2Hex(_X, _p)				\
+do{									\
+	char *__p;						\
+	(_X) = 0;							\
+	__p = (char *)(_p);							\
+	while (((*__p >= 'a') && (*__p <= 'f')) || ((*__p >= 'A') && (*__p <= 'F')) || ((*__p >= '0') && (*__p <= '9')))		\
+	{												\
+		if ((*__p >= 'a') && (*__p <= 'f'))				\
+			(_X) = (_X) * 16 + *__p - 87;					\
+		else if ((*__p >= 'A') && (*__p <= 'F'))		\
+			(_X) = (_X) * 16 + *__p - 55;					\
+		else if ((*__p >= '0') && (*__p <= '9'))		\
+			(_X) = (_X) * 16 + *__p - 48;					\
+		__p++;										\
+	}												\
+}while(0)
+
+#endif /* __RTMP_DEF_H__ */
diff --git a/drivers/staging/rt2860/rtmp_dot11.h b/drivers/staging/rt2860/rtmp_dot11.h
new file mode 100644
index 0000000..4f8abd7
--- /dev/null
+++ b/drivers/staging/rt2860/rtmp_dot11.h
@@ -0,0 +1,100 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+*/
+
+#ifndef __DOT11_BASE_H__
+#define __DOT11_BASE_H__
+
+#include "rtmp_type.h"
+
+/* 4-byte HTC field.  maybe included in any frame except non-QOS data frame.  The Order bit must set 1. */
+struct PACKED rt_ht_control {
+	u32 MA:1;		/*management action payload exist in (QoS Null+HTC) */
+	u32 TRQ:1;		/*sounding request */
+	u32 MRQ:1;		/*MCS feedback. Request for a MCS feedback */
+	u32 MRSorASI:3;	/* MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110. */
+	u32 MFS:3;		/*SET to the received value of MRS. 0x111 for unsolicited MFB. */
+	u32 MFBorASC:7;	/*Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available */
+	u32 CalPos:2;	/* calibration position */
+	u32 CalSeq:2;	/*calibration sequence */
+	u32 FBKReq:2;	/*feedback request */
+	u32 CSISTEERING:2;	/*CSI/ STEERING */
+	u32 ZLFAnnouce:1;	/* ZLF announcement */
+	u32 rsv:5;		/*calibration sequence */
+	u32 ACConstraint:1;	/*feedback request */
+	u32 RDG:1;		/*RDG / More PPDU */
+};
+
+/* 2-byte QOS CONTROL field */
+struct PACKED rt_qos_control {
+	u16 TID:4;
+	u16 EOSP:1;
+	u16 AckPolicy:2;	/*0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP  3: BA */
+	u16 AMsduPresent:1;
+	u16 Txop_QueueSize:8;
+};
+
+/* 2-byte Frame control field */
+struct PACKED rt_frame_control {
+	u16 Ver:2;		/* Protocol version */
+	u16 Type:2;		/* MSDU type */
+	u16 SubType:4;	/* MSDU subtype */
+	u16 ToDs:1;		/* To DS indication */
+	u16 FrDs:1;		/* From DS indication */
+	u16 MoreFrag:1;	/* More fragment bit */
+	u16 Retry:1;		/* Retry status bit */
+	u16 PwrMgmt:1;	/* Power management bit */
+	u16 MoreData:1;	/* More data bit */
+	u16 Wep:1;		/* Wep data */
+	u16 Order:1;		/* Strict order expected */
+};
+
+struct PACKED rt_header_802_11 {
+	struct rt_frame_control FC;
+	u16 Duration;
+	u8 Addr1[MAC_ADDR_LEN];
+	u8 Addr2[MAC_ADDR_LEN];
+	u8 Addr3[MAC_ADDR_LEN];
+	u16 Frag:4;
+	u16 Sequence:12;
+	u8 Octet[0];
+};
+
+struct PACKED rt_pspoll_frame {
+	struct rt_frame_control FC;
+	u16 Aid;
+	u8 Bssid[MAC_ADDR_LEN];
+	u8 Ta[MAC_ADDR_LEN];
+};
+
+struct PACKED rt_rts_frame {
+	struct rt_frame_control FC;
+	u16 Duration;
+	u8 Addr1[MAC_ADDR_LEN];
+	u8 Addr2[MAC_ADDR_LEN];
+};
+
+#endif /* __DOT11_BASE_H__ // */
diff --git a/drivers/staging/rt2860/rtmp_iface.h b/drivers/staging/rt2860/rtmp_iface.h
new file mode 100644
index 0000000..808c055
--- /dev/null
+++ b/drivers/staging/rt2860/rtmp_iface.h
@@ -0,0 +1,75 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+	rt_iface.h
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#ifndef __RTMP_IFACE_H__
+#define __RTMP_IFACE_H__
+
+#ifdef RTMP_PCI_SUPPORT
+#include "iface/rtmp_pci.h"
+#endif /* RTMP_PCI_SUPPORT // */
+#ifdef RTMP_USB_SUPPORT
+#include "iface/rtmp_usb.h"
+#endif /* RTMP_USB_SUPPORT // */
+
+struct rt_inf_pci_config {
+	unsigned long CSRBaseAddress;	/* PCI MMIO Base Address, all access will use */
+	unsigned int irq_num;
+};
+
+struct rt_inf_usb_config {
+	u8 BulkInEpAddr;	/* bulk-in endpoint address */
+	u8 BulkOutEpAddr[6];	/* bulk-out endpoint address */
+};
+
+struct rt_inf_rbus_config {
+	unsigned long csr_addr;
+	unsigned int irq;
+};
+
+typedef enum _RTMP_INF_TYPE_ {
+	RTMP_DEV_INF_UNKNOWN = 0,
+	RTMP_DEV_INF_PCI = 1,
+	RTMP_DEV_INF_USB = 2,
+	RTMP_DEV_INF_RBUS = 4,
+} RTMP_INF_TYPE;
+
+typedef union _RTMP_INF_CONFIG_ {
+	struct rt_inf_pci_config pciConfig;
+	struct rt_inf_usb_config usbConfig;
+	struct rt_inf_rbus_config rbusConfig;
+} RTMP_INF_CONFIG;
+
+#endif /* __RTMP_IFACE_H__ // */
diff --git a/drivers/staging/rt2860/rtmp_mcu.h b/drivers/staging/rt2860/rtmp_mcu.h
new file mode 100644
index 0000000..d0987e5
--- /dev/null
+++ b/drivers/staging/rt2860/rtmp_mcu.h
@@ -0,0 +1,49 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rtmp_mcu.h
+
+	Abstract:
+	Miniport header file for mcu related information
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+#ifndef __RTMP_MCU_H__
+#define __RTMP_MCU_H__
+
+int RtmpAsicEraseFirmware(struct rt_rtmp_adapter *pAd);
+
+int RtmpAsicLoadFirmware(struct rt_rtmp_adapter *pAd);
+
+int RtmpAsicSendCommandToMcu(struct rt_rtmp_adapter *pAd,
+			     u8 Command,
+			     u8 Token, u8 Arg0, u8 Arg1);
+
+#endif /* __RTMP_MCU_H__ // */
diff --git a/drivers/staging/rt2860/rtmp_os.h b/drivers/staging/rt2860/rtmp_os.h
new file mode 100644
index 0000000..94c30c8c
--- /dev/null
+++ b/drivers/staging/rt2860/rtmp_os.h
@@ -0,0 +1,90 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+	rtmp_os.h
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#ifndef __RTMP_OS_H__
+#define __RTMP_OS_H__
+
+#ifdef LINUX
+#include "rt_linux.h"
+#endif /* LINUX // */
+
+/*
+	This data structure mainly strip some callback function defined in
+	"struct net_device" in kernel source "include/linux/netdevice.h".
+
+	The definition of this data structure may various depends on different
+	OS. Use it carefully.
+*/
+struct rt_rtmp_os_netdev_op_hook {
+	const struct net_device_ops *netdev_ops;
+	void *priv;
+	int priv_flags;
+	unsigned char devAddr[6];
+	unsigned char devName[16];
+	unsigned char needProtcted;
+};
+
+typedef enum _RTMP_TASK_STATUS_ {
+	RTMP_TASK_STAT_UNKNOWN = 0,
+	RTMP_TASK_STAT_INITED = 1,
+	RTMP_TASK_STAT_RUNNING = 2,
+	RTMP_TASK_STAT_STOPED = 4,
+} RTMP_TASK_STATUS;
+#define RTMP_TASK_CAN_DO_INSERT		(RTMP_TASK_STAT_INITED |RTMP_TASK_STAT_RUNNING)
+
+#define RTMP_OS_TASK_NAME_LEN	16
+struct rt_rtmp_os_task {
+	char taskName[RTMP_OS_TASK_NAME_LEN];
+	void *priv;
+	/*unsigned long         taskFlags; */
+	RTMP_TASK_STATUS taskStatus;
+#ifndef KTHREAD_SUPPORT
+	struct semaphore taskSema;
+	struct pid *taskPID;
+	struct completion taskComplete;
+#endif
+	unsigned char task_killed;
+#ifdef KTHREAD_SUPPORT
+	struct task_struct *kthread_task;
+	wait_queue_head_t kthread_q;
+	BOOLEAN kthread_running;
+#endif
+};
+
+int RtmpOSIRQRequest(struct net_device *pNetDev);
+int RtmpOSIRQRelease(struct net_device *pNetDev);
+
+#endif /* __RMTP_OS_H__ // */
diff --git a/drivers/staging/rt2860/rtmp_timer.h b/drivers/staging/rt2860/rtmp_timer.h
new file mode 100644
index 0000000..28b8ac6
--- /dev/null
+++ b/drivers/staging/rt2860/rtmp_timer.h
@@ -0,0 +1,147 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+	rtmp_timer.h
+
+    Abstract:
+	Ralink Wireless Driver timer related data structures and delcarations
+
+    Revision History:
+	Who           When                What
+	--------    ----------      ----------------------------------------------
+	Name          Date                 Modification logs
+	Shiang Tu    Aug-28-2008	init version
+
+*/
+
+#ifndef __RTMP_TIMER_H__
+#define  __RTMP_TIMER_H__
+
+#include "rtmp_os.h"
+
+#define DECLARE_TIMER_FUNCTION(_func)			\
+	void rtmp_timer_##_func(unsigned long data)
+
+#define GET_TIMER_FUNCTION(_func)				\
+	rtmp_timer_##_func
+
+/* ----------------- Timer Related MARCO ---------------*/
+/* In some os or chipset, we have a lot of timer functions and will read/write register, */
+/*   it's not allowed in Linux USB sub-system to do it ( because of sleep issue when */
+/*  submit to ctrl pipe). So we need a wrapper function to take care it. */
+
+#ifdef RTMP_TIMER_TASK_SUPPORT
+typedef void(*RTMP_TIMER_TASK_HANDLE) (void *SystemSpecific1,
+				       void *FunctionContext,
+				       void *SystemSpecific2,
+				       void *SystemSpecific3);
+#endif /* RTMP_TIMER_TASK_SUPPORT // */
+
+struct rt_ralink_timer {
+	struct timer_list TimerObj;	/* Ndis Timer object */
+	BOOLEAN Valid;		/* Set to True when call RTMPInitTimer */
+	BOOLEAN State;		/* True if timer cancelled */
+	BOOLEAN PeriodicType;	/* True if timer is periodic timer */
+	BOOLEAN Repeat;		/* True if periodic timer */
+	unsigned long TimerValue;	/* Timer value in milliseconds */
+	unsigned long cookie;		/* os specific object */
+#ifdef RTMP_TIMER_TASK_SUPPORT
+	RTMP_TIMER_TASK_HANDLE handle;
+	void *pAd;
+#endif				/* RTMP_TIMER_TASK_SUPPORT // */
+};
+
+#ifdef RTMP_TIMER_TASK_SUPPORT
+struct rt_rtmp_timer_task_entry {
+	struct rt_ralink_timer *pRaTimer;
+	struct rt_rtmp_timer_task_entry *pNext;
+};
+
+#define TIMER_QUEUE_SIZE_MAX	128
+struct rt_rtmp_timer_task_queue {
+	unsigned int status;
+	unsigned char *pTimerQPoll;
+	struct rt_rtmp_timer_task_entry *pQPollFreeList;
+	struct rt_rtmp_timer_task_entry *pQHead;
+	struct rt_rtmp_timer_task_entry *pQTail;
+};
+
+#define BUILD_TIMER_FUNCTION(_func)										\
+void rtmp_timer_##_func(unsigned long data)										\
+{																			\
+	struct rt_ralink_timer *_pTimer = (struct rt_ralink_timer *)data;				\
+	struct rt_rtmp_timer_task_entry *_pQNode;										\
+	struct rt_rtmp_adapter *_pAd;											\
+																			\
+	_pTimer->handle = _func;													\
+	_pAd = (struct rt_rtmp_adapter *)_pTimer->pAd;										\
+	_pQNode = RtmpTimerQInsert(_pAd, _pTimer);								\
+	if ((_pQNode == NULL) && (_pAd->TimerQ.status & RTMP_TASK_CAN_DO_INSERT))	\
+		RTMP_OS_Add_Timer(&_pTimer->TimerObj, OS_HZ);							\
+}
+#else
+#define BUILD_TIMER_FUNCTION(_func)										\
+void rtmp_timer_##_func(unsigned long data)										\
+{																			\
+	struct rt_ralink_timer *pTimer = (struct rt_ralink_timer *)data;				\
+																			\
+	_func(NULL, (void *)pTimer->cookie, NULL, pTimer);							\
+	if (pTimer->Repeat)														\
+		RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);			\
+}
+#endif /* RTMP_TIMER_TASK_SUPPORT // */
+
+DECLARE_TIMER_FUNCTION(MlmePeriodicExec);
+DECLARE_TIMER_FUNCTION(MlmeRssiReportExec);
+DECLARE_TIMER_FUNCTION(AsicRxAntEvalTimeout);
+DECLARE_TIMER_FUNCTION(APSDPeriodicExec);
+DECLARE_TIMER_FUNCTION(AsicRfTuningExec);
+#ifdef RTMP_MAC_USB
+DECLARE_TIMER_FUNCTION(BeaconUpdateExec);
+#endif /* RTMP_MAC_USB // */
+
+DECLARE_TIMER_FUNCTION(BeaconTimeout);
+DECLARE_TIMER_FUNCTION(ScanTimeout);
+DECLARE_TIMER_FUNCTION(AuthTimeout);
+DECLARE_TIMER_FUNCTION(AssocTimeout);
+DECLARE_TIMER_FUNCTION(ReassocTimeout);
+DECLARE_TIMER_FUNCTION(DisassocTimeout);
+DECLARE_TIMER_FUNCTION(LinkDownExec);
+DECLARE_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
+DECLARE_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
+DECLARE_TIMER_FUNCTION(PsPollWakeExec);
+DECLARE_TIMER_FUNCTION(RadioOnExec);
+
+#ifdef RTMP_MAC_USB
+DECLARE_TIMER_FUNCTION(RtmpUsbStaAsicForceWakeupTimeout);
+#endif /* RTMP_MAC_USB // */
+
+#if defined(AP_LED) || defined(STA_LED)
+DECLARE_TIMER_FUNCTION(LedCtrlMain);
+#endif
+
+#endif /* __RTMP_TIMER_H__ // */
diff --git a/drivers/staging/rt2860/rtmp_type.h b/drivers/staging/rt2860/rtmp_type.h
index 1fd7df1..d9bb2d6 100644
--- a/drivers/staging/rt2860/rtmp_type.h
+++ b/drivers/staging/rt2860/rtmp_type.h
@@ -38,57 +38,52 @@
 #ifndef __RTMP_TYPE_H__
 #define __RTMP_TYPE_H__
 
+#include <linux/types.h>
+
 #define PACKED  __attribute__ ((packed))
 
-// Put platform dependent declaration here
-// For example, linux type definition
-typedef unsigned char		UINT8;
-typedef unsigned short		UINT16;
-typedef unsigned int		UINT32;
-typedef unsigned long long	UINT64;
-typedef int					INT32;
-typedef long long 			INT64;
-
-typedef unsigned char *			PUINT8;
-typedef unsigned short *		PUINT16;
-typedef unsigned int *			PUINT32;
-typedef unsigned long long *	PUINT64;
-typedef int	*					PINT32;
-typedef long long * 			PINT64;
-
-typedef signed char			CHAR;
-typedef signed short		SHORT;
-typedef signed int			INT;
-typedef signed long			LONG;
-typedef signed long long	LONGLONG;
-
-
-typedef unsigned char		UCHAR;
-typedef unsigned short		USHORT;
-typedef unsigned int		UINT;
-typedef unsigned long		ULONG;
-typedef unsigned long long	ULONGLONG;
-
-typedef unsigned char		BOOLEAN;
-typedef void				VOID;
-
-typedef VOID *				PVOID;
-typedef CHAR *				PCHAR;
-typedef UCHAR * 			PUCHAR;
-typedef USHORT *			PUSHORT;
-typedef LONG *				PLONG;
-typedef ULONG *				PULONG;
-typedef UINT *				PUINT;
-
-typedef unsigned int	NDIS_MEDIA_STATE;
+typedef unsigned char BOOLEAN;
 
 typedef union _LARGE_INTEGER {
-    struct {
-        UINT LowPart;
-        INT32 HighPart;
-    } u;
-    INT64 QuadPart;
+	struct {
+		u32 LowPart;
+		int HighPart;
+	} u;
+	long long QuadPart;
 } LARGE_INTEGER;
 
-#endif  // __RTMP_TYPE_H__
+/* */
+/* Register set pair for initialzation register set definition */
+/* */
+struct rt_rtmp_reg_pair {
+	unsigned long Register;
+	unsigned long Value;
+};
 
+struct rt_reg_pair {
+	u8 Register;
+	u8 Value;
+};
+
+/* */
+/* Register set pair for initialzation register set definition */
+/* */
+struct rt_rtmp_rf_regs {
+	u8 Channel;
+	unsigned long R1;
+	unsigned long R2;
+	unsigned long R3;
+	unsigned long R4;
+};
+
+struct rt_frequency_item {
+	u8 Channel;
+	u8 N;
+	u8 R;
+	u8 K;
+};
+
+#define STATUS_SUCCESS				0x00
+#define STATUS_UNSUCCESSFUL		0x01
+
+#endif /* __RTMP_TYPE_H__ // */
diff --git a/drivers/staging/rt2860/rtusb_io.h b/drivers/staging/rt2860/rtusb_io.h
new file mode 100644
index 0000000..64a2fe4
--- /dev/null
+++ b/drivers/staging/rt2860/rtusb_io.h
@@ -0,0 +1,185 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+*/
+
+#ifndef __RTUSB_IO_H__
+#define __RTUSB_IO_H__
+
+#include "rtmp_type.h"
+
+/* New for MeetingHouse Api support */
+#define CMDTHREAD_VENDOR_RESET                      0x0D730101	/* cmd */
+#define CMDTHREAD_VENDOR_UNPLUG                     0x0D730102	/* cmd */
+#define CMDTHREAD_VENDOR_SWITCH_FUNCTION            0x0D730103	/* cmd */
+#define CMDTHREAD_MULTI_WRITE_MAC                   0x0D730107	/* cmd */
+#define CMDTHREAD_MULTI_READ_MAC                    0x0D730108	/* cmd */
+#define CMDTHREAD_VENDOR_EEPROM_WRITE               0x0D73010A	/* cmd */
+#define CMDTHREAD_VENDOR_EEPROM_READ                0x0D73010B	/* cmd */
+#define CMDTHREAD_VENDOR_ENTER_TESTMODE             0x0D73010C	/* cmd */
+#define CMDTHREAD_VENDOR_EXIT_TESTMODE              0x0D73010D	/* cmd */
+#define CMDTHREAD_VENDOR_WRITE_BBP                  0x0D730119	/* cmd */
+#define CMDTHREAD_VENDOR_READ_BBP                   0x0D730118	/* cmd */
+#define CMDTHREAD_VENDOR_WRITE_RF                   0x0D73011A	/* cmd */
+#define CMDTHREAD_VENDOR_FLIP_IQ                    0x0D73011D	/* cmd */
+#define CMDTHREAD_RESET_BULK_OUT                    0x0D730210	/* cmd */
+#define CMDTHREAD_RESET_BULK_IN                     0x0D730211	/* cmd */
+#define CMDTHREAD_SET_PSM_BIT				0x0D730212	/* cmd */
+#define CMDTHREAD_SET_RADIO                         0x0D730214	/* cmd */
+#define CMDTHREAD_UPDATE_TX_RATE                    0x0D730216	/* cmd */
+#define CMDTHREAD_802_11_ADD_KEY_WEP                0x0D730218	/* cmd */
+#define CMDTHREAD_RESET_FROM_ERROR                  0x0D73021A	/* cmd */
+#define CMDTHREAD_LINK_DOWN                         0x0D73021B	/* cmd */
+#define CMDTHREAD_RESET_FROM_NDIS                   0x0D73021C	/* cmd */
+#define CMDTHREAD_CHECK_GPIO                        0x0D730215	/* cmd */
+#define CMDTHREAD_FORCE_WAKE_UP                     0x0D730222	/* cmd */
+#define CMDTHREAD_SET_BW                            0x0D730225	/* cmd */
+#define CMDTHREAD_SET_ASIC_WCID                     0x0D730226	/* cmd */
+#define CMDTHREAD_SET_ASIC_WCID_CIPHER              0x0D730227	/* cmd */
+#define CMDTHREAD_QKERIODIC_EXECUT                  0x0D73023D	/* cmd */
+#define RT_CMD_SET_KEY_TABLE                        0x0D730228	/* cmd */
+#define RT_CMD_SET_RX_WCID_TABLE                    0x0D730229	/* cmd */
+#define CMDTHREAD_SET_CLIENT_MAC_ENTRY              0x0D73023E	/* cmd */
+#define CMDTHREAD_SET_GROUP_KEY						0x0D73023F	/* cmd */
+#define CMDTHREAD_SET_PAIRWISE_KEY					0x0D730240	/* cmd */
+
+#define CMDTHREAD_802_11_QUERY_HARDWARE_REGISTER    0x0D710105	/* cmd */
+#define CMDTHREAD_802_11_SET_PHY_MODE               0x0D79010C	/* cmd */
+#define CMDTHREAD_802_11_SET_STA_CONFIG             0x0D790111	/* cmd */
+#define CMDTHREAD_802_11_SET_PREAMBLE               0x0D790101	/* cmd */
+#define CMDTHREAD_802_11_COUNTER_MEASURE			0x0D790102	/* cmd */
+/* add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet */
+#define CMDTHREAD_UPDATE_PROTECT					0x0D790103	/* cmd */
+/* end johnli */
+
+/*CMDTHREAD_MULTI_READ_MAC */
+/*CMDTHREAD_MULTI_WRITE_MAC */
+/*CMDTHREAD_VENDOR_EEPROM_READ */
+/*CMDTHREAD_VENDOR_EEPROM_WRITE */
+struct rt_cmdhandler_tlv {
+	u16 Offset;
+	u16 Length;
+	u8 DataFirst;
+};
+
+struct rt_cmdqelmt;
+
+struct rt_cmdqelmt {
+	u32 command;
+	void *buffer;
+	unsigned long bufferlength;
+	BOOLEAN CmdFromNdis;
+	BOOLEAN SetOperation;
+	struct rt_cmdqelmt *next;
+};
+
+struct rt_cmdq {
+	u32 size;
+	struct rt_cmdqelmt *head;
+	struct rt_cmdqelmt *tail;
+	u32 CmdQState;
+};
+
+#define EnqueueCmd(cmdq, cmdqelmt)		\
+{										\
+	if (cmdq->size == 0)				\
+		cmdq->head = cmdqelmt;			\
+	else								\
+		cmdq->tail->next = cmdqelmt;	\
+	cmdq->tail = cmdqelmt;				\
+	cmdqelmt->next = NULL;				\
+	cmdq->size++;						\
+}
+
+/******************************************************************************
+
+	USB Cmd to ASIC Related MACRO
+
+******************************************************************************/
+/* reset MAC of a station entry to 0xFFFFFFFFFFFF */
+#define RTMP_STA_ENTRY_MAC_RESET(pAd, Wcid)					\
+	{	struct rt_set_asic_wcid	SetAsicWcid;						\
+		SetAsicWcid.WCID = Wcid;								\
+		SetAsicWcid.SetTid = 0xffffffff;						\
+		SetAsicWcid.DeleteTid = 0xffffffff;						\
+		RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID,	\
+				&SetAsicWcid, sizeof(struct rt_set_asic_wcid));	}
+
+/* add this entry into ASIC RX WCID search table */
+#define RTMP_STA_ENTRY_ADD(pAd, pEntry)							\
+	RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_CLIENT_MAC_ENTRY,	\
+							pEntry, sizeof(struct rt_mac_table_entry));
+
+/* add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet */
+/* Set MAC register value according operation mode */
+#define RTMP_UPDATE_PROTECT(pAd)	\
+	RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_UPDATE_PROTECT, NULL, 0);
+/* end johnli */
+
+/* remove Pair-wise key material from ASIC */
+/* yet implement */
+#define RTMP_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid)
+
+/* add Client security information into ASIC WCID table and IVEIV table */
+#define RTMP_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry)						\
+	{	RTMP_STA_ENTRY_MAC_RESET(pAd, pEntry->Aid);								\
+		if (pEntry->Aid >= 1) {														\
+			struct rt_set_asic_wcid_attri	SetAsicWcidAttri;								\
+			SetAsicWcidAttri.WCID = pEntry->Aid;									\
+			if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) &&				\
+				(pEntry->WepStatus == Ndis802_11Encryption1Enabled))				\
+			{																		\
+				SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg;	\
+			}																		\
+			else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone)					\
+			{																		\
+				SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg;	\
+			}																		\
+			else SetAsicWcidAttri.Cipher = 0;										\
+            DBGPRINT(RT_DEBUG_TRACE, ("aid cipher = %ld\n",SetAsicWcidAttri.Cipher));       \
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID_CIPHER,			\
+							&SetAsicWcidAttri, sizeof(struct rt_set_asic_wcid_attri)); } }
+
+/* Insert the BA bitmap to ASIC for the Wcid entry */
+#define RTMP_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID)					\
+		do{																\
+			struct rt_set_asic_wcid	SetAsicWcid;							\
+			SetAsicWcid.WCID = (_Aid);									\
+			SetAsicWcid.SetTid = (0x10000<<(_TID));						\
+			SetAsicWcid.DeleteTid = 0xffffffff;							\
+			RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(struct rt_set_asic_wcid));	\
+		}while(0)
+
+/* Remove the BA bitmap from ASIC for the Wcid entry */
+#define RTMP_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID)				\
+		do{																\
+			struct rt_set_asic_wcid	SetAsicWcid;							\
+			SetAsicWcid.WCID = (_Wcid);									\
+			SetAsicWcid.SetTid = (0xffffffff);							\
+			SetAsicWcid.DeleteTid = (0x10000<<(_TID) );					\
+			RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(struct rt_set_asic_wcid));	\
+		}while(0)
+
+#endif /* __RTUSB_IO_H__ // */
diff --git a/drivers/staging/rt2860/spectrum.h b/drivers/staging/rt2860/spectrum.h
index 0a878ba..648fd63 100644
--- a/drivers/staging/rt2860/spectrum.h
+++ b/drivers/staging/rt2860/spectrum.h
@@ -23,7 +23,7 @@
  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  *                                                                       *
  *************************************************************************
-*/
+ */
 
 #ifndef __SPECTRUM_H__
 #define __SPECTRUM_H__
@@ -31,112 +31,7 @@
 #include "rtmp_type.h"
 #include "spectrum_def.h"
 
-typedef struct PACKED _TPC_REPORT_INFO
-{
-	UINT8 TxPwr;
-	UINT8 LinkMargin;
-} TPC_REPORT_INFO, *PTPC_REPORT_INFO;
-
-typedef struct PACKED _CH_SW_ANN_INFO
-{
-	UINT8 ChSwMode;
-	UINT8 Channel;
-	UINT8 ChSwCnt;
-} CH_SW_ANN_INFO, *PCH_SW_ANN_INFO;
-
-typedef union PACKED _MEASURE_REQ_MODE
-{
-	struct PACKED
-	{
-		UINT8 Rev0:1;
-		UINT8 Enable:1;
-		UINT8 Request:1;
-		UINT8 Report:1;
-		UINT8 Rev1:4;
-	} field;
-	UINT8 word;
-} MEASURE_REQ_MODE, *PMEASURE_REQ_MODE;
-
-typedef struct PACKED _MEASURE_REQ
-{
-	UINT8 ChNum;
-	UINT64 MeasureStartTime;
-	UINT16 MeasureDuration;
-} MEASURE_REQ, *PMEASURE_REQ;
-
-typedef struct PACKED _MEASURE_REQ_INFO
-{
-	UINT8 Token;
-	MEASURE_REQ_MODE ReqMode;
-	UINT8 ReqType;
-	MEASURE_REQ MeasureReq;
-} MEASURE_REQ_INFO, *PMEASURE_REQ_INFO;
-
-typedef union PACKED _MEASURE_BASIC_REPORT_MAP
-{
-	struct PACKED
-	{
-		UINT8 BSS:1;
-		UINT8 OfdmPreamble:1;
-		UINT8 UnidentifiedSignal:1;
-		UINT8 Radar:1;
-		UINT8 Unmeasure:1;
-		UINT8 Rev:3;
-	} field;
-	UINT8 word;
-} MEASURE_BASIC_REPORT_MAP, *PMEASURE_BASIC_REPORT_MAP;
-
-typedef struct PACKED _MEASURE_BASIC_REPORT
-{
-	UINT8 ChNum;
-	UINT64 MeasureStartTime;
-	UINT16 MeasureDuration;
-	MEASURE_BASIC_REPORT_MAP Map;
-} MEASURE_BASIC_REPORT, *PMEASURE_BASIC_REPORT;
-
-typedef struct PACKED _MEASURE_CCA_REPORT
-{
-	UINT8 ChNum;
-	UINT64 MeasureStartTime;
-	UINT16 MeasureDuration;
-	UINT8 CCA_Busy_Fraction;
-} MEASURE_CCA_REPORT, *PMEASURE_CCA_REPORT;
-
-typedef struct PACKED _MEASURE_RPI_REPORT
-{
-	UINT8 ChNum;
-	UINT64 MeasureStartTime;
-	UINT16 MeasureDuration;
-	UINT8 RPI_Density[8];
-} MEASURE_RPI_REPORT, *PMEASURE_RPI_REPORT;
-
-typedef union PACKED _MEASURE_REPORT_MODE
-{
-	struct PACKED
-	{
-		UINT8 Late:1;
-		UINT8 Incapable:1;
-		UINT8 Refused:1;
-		UINT8 Rev:5;
-	} field;
-	UINT8 word;
-} MEASURE_REPORT_MODE, *PMEASURE_REPORT_MODE;
-
-typedef struct PACKED _MEASURE_REPORT_INFO
-{
-	UINT8 Token;
-	MEASURE_REPORT_MODE ReportMode;
-	UINT8 ReportType;
-	UINT8 Octect[0];
-} MEASURE_REPORT_INFO, *PMEASURE_REPORT_INFO;
-
-typedef struct PACKED _QUIET_INFO
-{
-	UINT8 QuietCnt;
-	UINT8 QuietPeriod;
-	UINT8 QuietDuration;
-	UINT8 QuietOffset;
-} QUIET_INFO, *PQUIET_INFO;
+char RTMP_GetTxPwr(struct rt_rtmp_adapter *pAd, IN HTTRANSMIT_SETTING HTTxMode);
 
 /*
 	==========================================================================
@@ -150,14 +45,16 @@
 	Return	: None.
 	==========================================================================
  */
-VOID EnqueueMeasurementReq(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDA,
-	IN UINT8 MeasureToken,
-	IN UINT8 MeasureReqMode,
-	IN UINT8 MeasureReqType,
-	IN UINT8 MeasureCh,
-	IN UINT16 MeasureDuration);
+void MakeMeasurementReqFrame(struct rt_rtmp_adapter *pAd,
+			     u8 *pOutBuffer,
+			     unsigned long *pFrameLen,
+			     u8 TotalLen,
+			     u8 Category,
+			     u8 Action,
+			     u8 MeasureToken,
+			     u8 MeasureReqMode,
+			     u8 MeasureReqType,
+			     u8 NumOfRepetitions);
 
 /*
 	==========================================================================
@@ -171,15 +68,13 @@
 	Return	: None.
 	==========================================================================
  */
-VOID EnqueueMeasurementRep(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDA,
-	IN UINT8 DialogToken,
-	IN UINT8 MeasureToken,
-	IN UINT8 MeasureReqMode,
-	IN UINT8 MeasureReqType,
-	IN UINT8 ReportInfoLen,
-	IN PUINT8 pReportInfo);
+void EnqueueMeasurementRep(struct rt_rtmp_adapter *pAd,
+			   u8 *pDA,
+			   u8 DialogToken,
+			   u8 MeasureToken,
+			   u8 MeasureReqMode,
+			   u8 MeasureReqType,
+			   u8 ReportInfoLen, u8 *pReportInfo);
 
 /*
 	==========================================================================
@@ -193,10 +88,7 @@
 	Return	: None.
 	==========================================================================
  */
-VOID EnqueueTPCReq(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDA,
-	IN UCHAR DialogToken);
+void EnqueueTPCReq(struct rt_rtmp_adapter *pAd, u8 *pDA, u8 DialogToken);
 
 /*
 	==========================================================================
@@ -210,12 +102,9 @@
 	Return	: None.
 	==========================================================================
  */
-VOID EnqueueTPCRep(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDA,
-	IN UINT8 DialogToken,
-	IN UINT8 TxPwr,
-	IN UINT8 LinkMargin);
+void EnqueueTPCRep(struct rt_rtmp_adapter *pAd,
+		   u8 *pDA,
+		   u8 DialogToken, u8 TxPwr, u8 LinkMargin);
 
 /*
 	==========================================================================
@@ -231,11 +120,8 @@
 	Return	: None.
 	==========================================================================
  */
-VOID EnqueueChSwAnn(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDA,
-	IN UINT8 ChSwMode,
-	IN UINT8 NewCh);
+void EnqueueChSwAnn(struct rt_rtmp_adapter *pAd,
+		    u8 *pDA, u8 ChSwMode, u8 NewCh);
 
 /*
 	==========================================================================
@@ -249,9 +135,7 @@
 	Return	: None.
 	==========================================================================
  */
-VOID PeerSpectrumAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
+void PeerSpectrumAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
 
 /*
 	==========================================================================
@@ -262,31 +146,44 @@
 	Return	: None.
 	==========================================================================
  */
-INT Set_MeasureReq_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
+int Set_MeasureReq_Proc(struct rt_rtmp_adapter *pAd, char *arg);
 
-INT Set_TpcReq_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
+int Set_TpcReq_Proc(struct rt_rtmp_adapter *pAd, char *arg);
 
-VOID MeasureReqTabInit(
-	IN PRTMP_ADAPTER pAd);
+int Set_PwrConstraint(struct rt_rtmp_adapter *pAd, char *arg);
 
-VOID MeasureReqTabExit(
-	IN PRTMP_ADAPTER pAd);
+void MeasureReqTabInit(struct rt_rtmp_adapter *pAd);
 
-VOID TpcReqTabInit(
-	IN PRTMP_ADAPTER pAd);
+void MeasureReqTabExit(struct rt_rtmp_adapter *pAd);
 
-VOID TpcReqTabExit(
-	IN PRTMP_ADAPTER pAd);
+struct rt_measure_req_entry *MeasureReqLookUp(struct rt_rtmp_adapter *pAd, u8 DialogToken);
 
-VOID NotifyChSwAnnToPeerAPs(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pRA,
-	IN PUCHAR pTA,
-	IN UINT8 ChSwMode,
-	IN UINT8 Channel);
-#endif // __SPECTRUM_H__ //
+struct rt_measure_req_entry *MeasureReqInsert(struct rt_rtmp_adapter *pAd, u8 DialogToken);
 
+void MeasureReqDelete(struct rt_rtmp_adapter *pAd, u8 DialogToken);
+
+void InsertChannelRepIE(struct rt_rtmp_adapter *pAd,
+			u8 *pFrameBuf,
+			unsigned long *pFrameLen,
+			char *pCountry, u8 RegulatoryClass);
+
+void InsertTpcReportIE(struct rt_rtmp_adapter *pAd,
+		       u8 *pFrameBuf,
+		       unsigned long *pFrameLen,
+		       u8 TxPwr, u8 LinkMargin);
+
+void InsertDialogToken(struct rt_rtmp_adapter *pAd,
+		       u8 *pFrameBuf,
+		       unsigned long *pFrameLen, u8 DialogToken);
+
+void TpcReqTabInit(struct rt_rtmp_adapter *pAd);
+
+void TpcReqTabExit(struct rt_rtmp_adapter *pAd);
+
+void NotifyChSwAnnToPeerAPs(struct rt_rtmp_adapter *pAd,
+			    u8 *pRA,
+			    u8 *pTA, u8 ChSwMode, u8 Channel);
+
+void RguClass_BuildBcnChList(struct rt_rtmp_adapter *pAd,
+			     u8 *pBuf, unsigned long *pBufLen);
+#endif /* __SPECTRUM_H__ // */
diff --git a/drivers/staging/rt2860/spectrum_def.h b/drivers/staging/rt2860/spectrum_def.h
index 4ca4817..8ffcfb0d 100644
--- a/drivers/staging/rt2860/spectrum_def.h
+++ b/drivers/staging/rt2860/spectrum_def.h
@@ -39,13 +39,62 @@
 #ifndef __SPECTRUM_DEF_H__
 #define __SPECTRUM_DEF_H__
 
-#define MAX_MEASURE_REQ_TAB_SIZE		3
+#define MAX_MEASURE_REQ_TAB_SIZE		32
 #define MAX_HASH_MEASURE_REQ_TAB_SIZE	MAX_MEASURE_REQ_TAB_SIZE
 
-#define MAX_TPC_REQ_TAB_SIZE			3
+#define MAX_TPC_REQ_TAB_SIZE			32
 #define MAX_HASH_TPC_REQ_TAB_SIZE		MAX_TPC_REQ_TAB_SIZE
 
-#define MIN_RCV_PWR				100		/* Negative value ((dBm) */
+#define MIN_RCV_PWR				100	/* Negative value ((dBm) */
+
+#define TPC_REQ_AGE_OUT			500	/* ms */
+#define MQ_REQ_AGE_OUT			500	/* ms */
+
+#define TPC_DIALOGTOKEN_HASH_INDEX(_DialogToken)	((_DialogToken) % MAX_HASH_TPC_REQ_TAB_SIZE)
+#define MQ_DIALOGTOKEN_HASH_INDEX(_DialogToken)		((_DialogToken) % MAX_MEASURE_REQ_TAB_SIZE)
+
+struct rt_measure_req_entry;
+
+struct rt_measure_req_entry {
+	struct rt_measure_req_entry *pNext;
+	unsigned long lastTime;
+	BOOLEAN Valid;
+	u8 DialogToken;
+	u8 MeasureDialogToken[3];	/* 0:basic measure, 1: CCA measure, 2: RPI_Histogram measure. */
+};
+
+struct rt_measure_req_tab {
+	u8 Size;
+	struct rt_measure_req_entry *Hash[MAX_HASH_MEASURE_REQ_TAB_SIZE];
+	struct rt_measure_req_entry Content[MAX_MEASURE_REQ_TAB_SIZE];
+};
+
+struct rt_tpc_req_entry;
+
+struct rt_tpc_req_entry {
+	struct rt_tpc_req_entry *pNext;
+	unsigned long lastTime;
+	BOOLEAN Valid;
+	u8 DialogToken;
+};
+
+struct rt_tpc_req_tab {
+	u8 Size;
+	struct rt_tpc_req_entry *Hash[MAX_HASH_TPC_REQ_TAB_SIZE];
+	struct rt_tpc_req_entry Content[MAX_TPC_REQ_TAB_SIZE];
+};
+
+/* The regulatory information */
+struct rt_dot11_channel_set {
+	u8 NumberOfChannels;
+	u8 MaxTxPwr;
+	u8 ChannelList[16];
+};
+
+struct rt_dot11_regulatory_information {
+	u8 RegulatoryClass;
+	struct rt_dot11_channel_set ChannelSet;
+};
 
 #define RM_TPC_REQ				0
 #define RM_MEASURE_REQ			1
@@ -53,43 +102,101 @@
 #define RM_BASIC				0
 #define RM_CCA					1
 #define RM_RPI_HISTOGRAM		2
+#define RM_CH_LOAD				3
+#define RM_NOISE_HISTOGRAM		4
 
-#define TPC_REQ_AGE_OUT			500		/* ms */
-#define MQ_REQ_AGE_OUT			500		/* ms */
+struct PACKED rt_tpc_report_info {
+	u8 TxPwr;
+	u8 LinkMargin;
+};
 
-#define TPC_DIALOGTOKEN_HASH_INDEX(_DialogToken)	((_DialogToken) % MAX_HASH_TPC_REQ_TAB_SIZE)
-#define MQ_DIALOGTOKEN_HASH_INDEX(_DialogToken)		((_DialogToken) % MAX_MEASURE_REQ_TAB_SIZE)
+struct PACKED rt_ch_sw_ann_info {
+	u8 ChSwMode;
+	u8 Channel;
+	u8 ChSwCnt;
+};
 
-typedef struct _MEASURE_REQ_ENTRY
-{
-	struct _MEASURE_REQ_ENTRY *pNext;
-	ULONG lastTime;
-	BOOLEAN	Valid;
-	UINT8 DialogToken;
-	UINT8 MeasureDialogToken[3];	// 0:basic measure, 1: CCA measure, 2: RPI_Histogram measure.
-} MEASURE_REQ_ENTRY, *PMEASURE_REQ_ENTRY;
+typedef union PACKED _MEASURE_REQ_MODE {
+	struct PACKED {
+		u8 Parallel:1;
+		u8 Enable:1;
+		u8 Request:1;
+		u8 Report:1;
+		u8 DurationMandatory:1;
+		 u8:3;
+	} field;
+	u8 word;
+} MEASURE_REQ_MODE, *PMEASURE_REQ_MODE;
 
-typedef struct _MEASURE_REQ_TAB
-{
-	UCHAR Size;
-	PMEASURE_REQ_ENTRY Hash[MAX_HASH_MEASURE_REQ_TAB_SIZE];
-	MEASURE_REQ_ENTRY Content[MAX_MEASURE_REQ_TAB_SIZE];
-} MEASURE_REQ_TAB, *PMEASURE_REQ_TAB;
+struct PACKED rt_measure_req {
+	u8 ChNum;
+	u64 MeasureStartTime;
+	u16 MeasureDuration;
+};
 
-typedef struct _TPC_REQ_ENTRY
-{
-	struct _TPC_REQ_ENTRY *pNext;
-	ULONG lastTime;
-	BOOLEAN Valid;
-	UINT8 DialogToken;
-} TPC_REQ_ENTRY, *PTPC_REQ_ENTRY;
+struct PACKED rt_measure_req_info {
+	u8 Token;
+	MEASURE_REQ_MODE ReqMode;
+	u8 ReqType;
+	u8 Oct[0];
+};
 
-typedef struct _TPC_REQ_TAB
-{
-	UCHAR Size;
-	PTPC_REQ_ENTRY Hash[MAX_HASH_TPC_REQ_TAB_SIZE];
-	TPC_REQ_ENTRY Content[MAX_TPC_REQ_TAB_SIZE];
-} TPC_REQ_TAB, *PTPC_REQ_TAB;
+typedef union PACKED _MEASURE_BASIC_REPORT_MAP {
+	struct PACKED {
+		u8 BSS:1;
 
-#endif // __SPECTRUM_DEF_H__ //
+		u8 OfdmPreamble:1;
+		u8 UnidentifiedSignal:1;
+		u8 Radar:1;
+		u8 Unmeasure:1;
+		u8 Rev:3;
+	} field;
+	u8 word;
+} MEASURE_BASIC_REPORT_MAP, *PMEASURE_BASIC_REPORT_MAP;
 
+struct PACKED rt_measure_basic_report {
+	u8 ChNum;
+	u64 MeasureStartTime;
+	u16 MeasureDuration;
+	MEASURE_BASIC_REPORT_MAP Map;
+};
+
+struct PACKED rt_measure_cca_report {
+	u8 ChNum;
+	u64 MeasureStartTime;
+	u16 MeasureDuration;
+	u8 CCA_Busy_Fraction;
+};
+
+struct PACKED rt_measure_rpi_report {
+	u8 ChNum;
+	u64 MeasureStartTime;
+	u16 MeasureDuration;
+	u8 RPI_Density[8];
+};
+
+typedef union PACKED _MEASURE_REPORT_MODE {
+	struct PACKED {
+		u8 Late:1;
+		u8 Incapable:1;
+		u8 Refused:1;
+		u8 Rev:5;
+	} field;
+	u8 word;
+} MEASURE_REPORT_MODE, *PMEASURE_REPORT_MODE;
+
+struct PACKED rt_measure_report_info {
+	u8 Token;
+	u8 ReportMode;
+	u8 ReportType;
+	u8 Octect[0];
+};
+
+struct PACKED rt_quiet_info {
+	u8 QuietCnt;
+	u8 QuietPeriod;
+	u16 QuietDuration;
+	u16 QuietOffset;
+};
+
+#endif /* __SPECTRUM_DEF_H__ // */
diff --git a/drivers/staging/rt2860/sta/aironet.c b/drivers/staging/rt2860/sta/aironet.c
deleted file mode 100644
index 4af4a19..0000000
--- a/drivers/staging/rt2860/sta/aironet.c
+++ /dev/null
@@ -1,1312 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	aironet.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Paul Lin	04-06-15		Initial
-*/
-#include "../rt_config.h"
-
-/*
-	==========================================================================
-	Description:
-		association	state machine init,	including state	transition and timer init
-	Parameters:
-		S -	pointer	to the association state machine
-	==========================================================================
- */
-VOID	AironetStateMachineInit(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	STATE_MACHINE		*S,
-	OUT	STATE_MACHINE_FUNC	Trans[])
-{
-	StateMachineInit(S,	Trans, MAX_AIRONET_STATE, MAX_AIRONET_MSG, (STATE_MACHINE_FUNC)Drop, AIRONET_IDLE, AIRONET_MACHINE_BASE);
-	StateMachineSetAction(S, AIRONET_IDLE, MT2_AIRONET_MSG, (STATE_MACHINE_FUNC)AironetMsgAction);
-	StateMachineSetAction(S, AIRONET_IDLE, MT2_AIRONET_SCAN_REQ, (STATE_MACHINE_FUNC)AironetRequestAction);
-	StateMachineSetAction(S, AIRONET_SCANNING, MT2_AIRONET_SCAN_DONE, (STATE_MACHINE_FUNC)AironetReportAction);
-}
-
-/*
-	==========================================================================
-	Description:
-		This is	state machine function.
-		When receiving EAPOL packets which is  for 802.1x key management.
-		Use	both in	WPA, and WPAPSK	case.
-		In this	function, further dispatch to different	functions according	to the received	packet.	 3 categories are :
-		  1.  normal 4-way pairwisekey and 2-way groupkey handshake
-		  2.  MIC error	(Countermeasures attack)  report packet	from STA.
-		  3.  Request for pairwise/group key update	from STA
-	Return:
-	==========================================================================
-*/
-VOID	AironetMsgAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MLME_QUEUE_ELEM	*Elem)
-{
-	USHORT							Length;
-	UCHAR							Index, i;
-	PUCHAR							pData;
-	PAIRONET_RM_REQUEST_FRAME		pRMReq;
-	PRM_REQUEST_ACTION				pReqElem;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("-----> AironetMsgAction\n"));
-
-	// 0. Get Aironet IAPP header first
-	pRMReq = (PAIRONET_RM_REQUEST_FRAME) &Elem->Msg[LENGTH_802_11];
-	pData  = (PUCHAR) &Elem->Msg[LENGTH_802_11];
-
-	// 1. Change endian format form network to little endian
-	Length = be2cpu16(pRMReq->IAPP.Length);
-
-	// 2.0 Sanity check, this should only happen when CCX 2.0 support is enabled
-	if (pAd->StaCfg.CCXEnable != TRUE)
-		return;
-
-	// 2.1 Radio measurement must be on
-	if (pAd->StaCfg.CCXControl.field.RMEnable != 1)
-		return;
-
-	// 2.2. Debug print all bit information
-	DBGPRINT(RT_DEBUG_TRACE, ("IAPP ID & Length %d\n", Length));
-	DBGPRINT(RT_DEBUG_TRACE, ("IAPP Type %x\n", pRMReq->IAPP.Type));
-	DBGPRINT(RT_DEBUG_TRACE, ("IAPP SubType %x\n", pRMReq->IAPP.SubType));
-	DBGPRINT(RT_DEBUG_TRACE, ("IAPP Dialog Token %x\n", pRMReq->IAPP.Token));
-	DBGPRINT(RT_DEBUG_TRACE, ("IAPP Activation Delay %x\n", pRMReq->Delay));
-	DBGPRINT(RT_DEBUG_TRACE, ("IAPP Measurement Offset %x\n", pRMReq->Offset));
-
-	// 3. Check IAPP frame type, it must be 0x32 for Cisco Aironet extension
-	if (pRMReq->IAPP.Type != AIRONET_IAPP_TYPE)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP type for Cisco Aironet extension\n"));
-		return;
-	}
-
-	// 4. Check IAPP frame subtype, it must be 0x01 for Cisco Aironet extension request.
-	//    Since we are acting as client only, we will disregards reply subtype.
-	if (pRMReq->IAPP.SubType != AIRONET_IAPP_SUBTYPE_REQUEST)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP subtype for Cisco Aironet extension\n"));
-		return;
-	}
-
-	// 5. Verify Destination MAC and Source MAC, both should be all zeros.
-	if (! MAC_ADDR_EQUAL(pRMReq->IAPP.DA, ZERO_MAC_ADDR))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP DA for Cisco Aironet extension, it's not Zero\n"));
-		return;
-	}
-
-	if (! MAC_ADDR_EQUAL(pRMReq->IAPP.SA, ZERO_MAC_ADDR))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP SA for Cisco Aironet extension, it's not Zero\n"));
-		return;
-	}
-
-	// 6. Reinit all report related fields
-	NdisZeroMemory(pAd->StaCfg.FrameReportBuf, 2048);
-	NdisZeroMemory(pAd->StaCfg.BssReportOffset, sizeof(USHORT) * MAX_LEN_OF_BSS_TABLE);
-	NdisZeroMemory(pAd->StaCfg.MeasurementRequest, sizeof(RM_REQUEST_ACTION) * 4);
-
-	// 7. Point to the start of first element report element
-	pAd->StaCfg.FrameReportLen   = LENGTH_802_11 + sizeof(AIRONET_IAPP_HEADER);
-	DBGPRINT(RT_DEBUG_TRACE, ("FR len = %d\n", pAd->StaCfg.FrameReportLen));
-	pAd->StaCfg.LastBssIndex     = 0xff;
-	pAd->StaCfg.RMReqCnt         = 0;
-	pAd->StaCfg.ParallelReq      = FALSE;
-	pAd->StaCfg.ParallelDuration = 0;
-	pAd->StaCfg.ParallelChannel  = 0;
-	pAd->StaCfg.IAPPToken        = pRMReq->IAPP.Token;
-	pAd->StaCfg.CurrentRMReqIdx  = 0;
-	pAd->StaCfg.CLBusyBytes      = 0;
-	// Reset the statistics
-	for (i = 0; i < 8; i++)
-		pAd->StaCfg.RPIDensity[i] = 0;
-
-	Index = 0;
-
-	// 8. Save dialog token for report
-	pAd->StaCfg.IAPPToken = pRMReq->IAPP.Token;
-
-	// Save Activation delay & measurement offset, Not really needed
-
-	// 9. Point to the first request element
-	pData += sizeof(AIRONET_RM_REQUEST_FRAME);
-	//    Length should exclude the CISCO Aironet SNAP header
-	Length -= (sizeof(AIRONET_RM_REQUEST_FRAME) - LENGTH_802_1_H);
-
-	// 10. Start Parsing the Measurement elements.
-	//    Be careful about multiple MR elements within one frames.
-	while (Length > 0)
-	{
-		pReqElem = (PRM_REQUEST_ACTION) pData;
-		switch (pReqElem->ReqElem.Eid)
-		{
-			case IE_MEASUREMENT_REQUEST:
-				// From the example, it seems we only need to support one request in one frame
-				// There is no multiple request in one frame.
-				// Besides, looks like we need to take care the measurement request only.
-				// The measurement request is always 4 bytes.
-
-				// Start parsing this type of request.
-				// 0. Eid is IE_MEASUREMENT_REQUEST
-				// 1. Length didn't include Eid and Length field, it always be 8.
-				// 2. Measurement Token, we nned to save it for the corresponding report.
-				// 3. Measurement Mode, Although there are definitions, but we din't see value other than
-				//    0 from test specs examples.
-				// 4. Measurement Type, this is what we need to do.
-				switch (pReqElem->ReqElem.Type)
-				{
-					case MSRN_TYPE_CHANNEL_LOAD_REQ:
-					case MSRN_TYPE_NOISE_HIST_REQ:
-					case MSRN_TYPE_BEACON_REQ:
-						// Check the Enable non-serving channel measurement control
-						if (pAd->StaCfg.CCXControl.field.DCRMEnable == 0)
-						{
-							// Check channel before enqueue the action
-							if (pReqElem->Measurement.Channel != pAd->CommonCfg.Channel)
-								break;
-						}
-						else
-						{
-							// If off channel measurement, check the TU duration limit
-							if (pReqElem->Measurement.Channel != pAd->CommonCfg.Channel)
-								if (pReqElem->Measurement.Duration > pAd->StaCfg.CCXControl.field.TuLimit)
-									break;
-						}
-
-						// Save requests and execute actions later
-						NdisMoveMemory(&pAd->StaCfg.MeasurementRequest[Index], pReqElem, sizeof(RM_REQUEST_ACTION));
-						Index += 1;
-						break;
-
-					case MSRN_TYPE_FRAME_REQ:
-						// Since it's option, we will support later
-						// FrameRequestAction(pAd, pData);
-						break;
-
-					default:
-						break;
-				}
-
-				// Point to next Measurement request
-				pData  += sizeof(RM_REQUEST_ACTION);
-				Length -= sizeof(RM_REQUEST_ACTION);
-				break;
-
-			// We accept request only, all others are dropped
-			case IE_MEASUREMENT_REPORT:
-			case IE_AP_TX_POWER:
-			case IE_MEASUREMENT_CAPABILITY:
-			default:
-				return;
-		}
-	}
-
-	// 11. Update some flags and index
-	pAd->StaCfg.RMReqCnt = Index;
-
-	if (Index)
-	{
-		MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_REQ, 0, NULL);
-		RT28XX_MLME_HANDLER(pAd);
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<----- AironetMsgAction\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	AironetRequestAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MLME_QUEUE_ELEM	*Elem)
-{
-	PRM_REQUEST_ACTION	pReq;
-
-	// 1. Point to next request element
-	pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
-
-	// 2. Parse measurement type and call appropriate functions
-	if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ)
-		// Channel Load measurement request
-		ChannelLoadRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
-	else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ)
-		// Noise Histogram measurement request
-		NoiseHistRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
-	else if (pReq->ReqElem.Type == MSRN_TYPE_BEACON_REQ)
-		// Beacon measurement request
-		BeaconRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
-	else
-		// Unknown. Do nothing and return, this should never happen
-		return;
-
-	// 3. Peek into the next request, if it's parallel, we will update the scan time to the largest one
-	if ((pAd->StaCfg.CurrentRMReqIdx + 1) < pAd->StaCfg.RMReqCnt)
-	{
-		pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx + 1];
-		// Check for parallel bit
-		if ((pReq->ReqElem.Mode & 0x01) && (pReq->Measurement.Channel == pAd->StaCfg.CCXScanChannel))
-		{
-			// Update parallel mode request information
-			pAd->StaCfg.ParallelReq = TRUE;
-			pAd->StaCfg.CCXScanTime = ((pReq->Measurement.Duration > pAd->StaCfg.CCXScanTime) ?
-			(pReq->Measurement.Duration) : (pAd->StaCfg.CCXScanTime));
-		}
-	}
-
-	// 4. Call RT28XX_MLME_HANDLER to execute the request mlme commands, Scan request is the only one used
-	RT28XX_MLME_HANDLER(pAd);
-
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Prepare channel load report action, special scan operation added
-		to support
-
-	Arguments:
-		pAd	Pointer	to our adapter
-		pData		Start from element ID
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	ChannelLoadRequestAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Index)
-{
-	PRM_REQUEST_ACTION				pReq;
-	MLME_SCAN_REQ_STRUCT			ScanReq;
-	UCHAR							ZeroSsid[32];
-	NDIS_STATUS						NStatus;
-	PUCHAR							pOutBuffer = NULL;
-	PHEADER_802_11					pNullFrame;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadRequestAction ----->\n"));
-
-	pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index];
-	NdisZeroMemory(ZeroSsid, 32);
-
-	// Prepare for special scan request
-	// The scan definition is different with our Active, Passive scan definition.
-	// For CCX2, Active means send out probe request with broadcast BSSID.
-	// Passive means no probe request sent, only listen to the beacons.
-	// The channel scanned is fixed as specified, no need to scan all channels.
-	// The scan wait time is specified in the request too.
-	// Passive scan Mode
-
-	// Control state machine is not idle, reject the request
-	if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0))
-		return;
-
-	// Fill out stuff for scan request
-	ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_CHANNEL_LOAD);
-	MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
-	pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
-
-	// Reset some internal control flags to make sure this scan works.
-	BssTableInit(&pAd->StaCfg.CCXBssTab);
-	pAd->StaCfg.ScanCnt        = 0;
-	pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
-	pAd->StaCfg.CCXScanTime    = pReq->Measurement.Duration;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Duration %d, Channel %d!\n", pReq->Measurement.Duration, pReq->Measurement.Channel));
-
-	// If it's non serving channel scan, send out a null frame with PSM bit on.
-	if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
-	{
-		// Use MLME enqueue method
-		NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
-		if (NStatus	!= NDIS_STATUS_SUCCESS)
-			return;
-
-		pNullFrame = (PHEADER_802_11) pOutBuffer;;
-		// Make the power save Null frame with PSM bit on
-		MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
-		pNullFrame->Duration 	= 0;
-		pNullFrame->FC.Type 	= BTYPE_DATA;
-		pNullFrame->FC.PwrMgmt	= PWR_SAVE;
-
-		// Send using priority queue
-		MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
-		MlmeFreeMemory(pAd, pOutBuffer);
-		DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
-		RTMPusecDelay(5000);
-	}
-
-	pAd->StaCfg.CCXReqType     = MSRN_TYPE_CHANNEL_LOAD_REQ;
-	pAd->StaCfg.CLBusyBytes    = 0;
-	// Enable Rx with promiscuous reception
-	RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, 0x1010);
-
-	// Set channel load measurement flag
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
-
-	pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadRequestAction <-----\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Prepare noise histogram report action, special scan operation added
-		to support
-
-	Arguments:
-		pAd	Pointer	to our adapter
-		pData		Start from element ID
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	NoiseHistRequestAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Index)
-{
-	PRM_REQUEST_ACTION				pReq;
-	MLME_SCAN_REQ_STRUCT			ScanReq;
-	UCHAR							ZeroSsid[32], i;
-	NDIS_STATUS						NStatus;
-	PUCHAR							pOutBuffer = NULL;
-	PHEADER_802_11					pNullFrame;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistRequestAction ----->\n"));
-
-	pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index];
-	NdisZeroMemory(ZeroSsid, 32);
-
-	// Prepare for special scan request
-	// The scan definition is different with our Active, Passive scan definition.
-	// For CCX2, Active means send out probe request with broadcast BSSID.
-	// Passive means no probe request sent, only listen to the beacons.
-	// The channel scanned is fixed as specified, no need to scan all channels.
-	// The scan wait time is specified in the request too.
-	// Passive scan Mode
-
-	// Control state machine is not idle, reject the request
-	if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0))
-		return;
-
-	// Fill out stuff for scan request
-	ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_NOISE);
-	MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
-	pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
-
-	// Reset some internal control flags to make sure this scan works.
-	BssTableInit(&pAd->StaCfg.CCXBssTab);
-	pAd->StaCfg.ScanCnt        = 0;
-	pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
-	pAd->StaCfg.CCXScanTime    = pReq->Measurement.Duration;
-	pAd->StaCfg.CCXReqType     = MSRN_TYPE_NOISE_HIST_REQ;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Duration %d, Channel %d!\n", pReq->Measurement.Duration, pReq->Measurement.Channel));
-
-	// If it's non serving channel scan, send out a null frame with PSM bit on.
-	if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
-	{
-		// Use MLME enqueue method
-		NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
-		if (NStatus	!= NDIS_STATUS_SUCCESS)
-			return;
-
-		pNullFrame = (PHEADER_802_11) pOutBuffer;
-		// Make the power save Null frame with PSM bit on
-		MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
-		pNullFrame->Duration 	= 0;
-		pNullFrame->FC.Type  	= BTYPE_DATA;
-		pNullFrame->FC.PwrMgmt	= PWR_SAVE;
-
-		// Send using priority queue
-		MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
-		MlmeFreeMemory(pAd, pOutBuffer);
-		DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
-		RTMPusecDelay(5000);
-	}
-
-	// Reset the statistics
-	for (i = 0; i < 8; i++)
-		pAd->StaCfg.RPIDensity[i] = 0;
-
-	// Enable Rx with promiscuous reception
-	RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, 0x1010);
-
-	// Set channel load measurement flag
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
-
-	pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistRequestAction <-----\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Prepare Beacon report action, special scan operation added
-		to support
-
-	Arguments:
-		pAd	Pointer	to our adapter
-		pData		Start from element ID
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	BeaconRequestAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Index)
-{
-	PRM_REQUEST_ACTION				pReq;
-	NDIS_STATUS						NStatus;
-	PUCHAR							pOutBuffer = NULL;
-	PHEADER_802_11					pNullFrame;
-	MLME_SCAN_REQ_STRUCT			ScanReq;
-	UCHAR							ZeroSsid[32];
-
-	DBGPRINT(RT_DEBUG_TRACE, ("BeaconRequestAction ----->\n"));
-
-	pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index];
-	NdisZeroMemory(ZeroSsid, 32);
-
-	// Prepare for special scan request
-	// The scan definition is different with our Active, Passive scan definition.
-	// For CCX2, Active means send out probe request with broadcast BSSID.
-	// Passive means no probe request sent, only listen to the beacons.
-	// The channel scanned is fixed as specified, no need to scan all channels.
-	// The scan wait time is specified in the request too.
-	if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_PASSIVE)
-	{
-		// Passive scan Mode
-		DBGPRINT(RT_DEBUG_TRACE, ("Passive Scan Mode!\n"));
-
-		// Control state machine is not idle, reject the request
-		if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0))
-			return;
-
-		// Fill out stuff for scan request
-		ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_PASSIVE);
-		MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
-		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
-
-		// Reset some internal control flags to make sure this scan works.
-		BssTableInit(&pAd->StaCfg.CCXBssTab);
-		pAd->StaCfg.ScanCnt        = 0;
-		pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
-		pAd->StaCfg.CCXScanTime    = pReq->Measurement.Duration;
-		pAd->StaCfg.CCXReqType     = MSRN_TYPE_BEACON_REQ;
-		DBGPRINT(RT_DEBUG_TRACE, ("Duration %d!\n", pReq->Measurement.Duration));
-
-		// If it's non serving channel scan, send out a null frame with PSM bit on.
-		if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
-		{
-			// Use MLME enqueue method
-			NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
-			if (NStatus	!= NDIS_STATUS_SUCCESS)
-				return;
-
-			pNullFrame = (PHEADER_802_11) pOutBuffer;
-			// Make the power save Null frame with PSM bit on
-			MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
-			pNullFrame->Duration 	= 0;
-			pNullFrame->FC.Type     = BTYPE_DATA;
-			pNullFrame->FC.PwrMgmt  = PWR_SAVE;
-
-			// Send using priority queue
-			MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
-			MlmeFreeMemory(pAd, pOutBuffer);
-			DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
-			RTMPusecDelay(5000);
-		}
-
-		pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
-	}
-	else if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_ACTIVE)
-	{
-		// Active scan Mode
-		DBGPRINT(RT_DEBUG_TRACE, ("Active Scan Mode!\n"));
-
-		// Control state machine is not idle, reject the request
-		if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)
-			return;
-
-		// Fill out stuff for scan request
-		ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_ACTIVE);
-		MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
-		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
-
-		// Reset some internal control flags to make sure this scan works.
-		BssTableInit(&pAd->StaCfg.CCXBssTab);
-		pAd->StaCfg.ScanCnt        = 0;
-		pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
-		pAd->StaCfg.CCXScanTime    = pReq->Measurement.Duration;
-		pAd->StaCfg.CCXReqType     = MSRN_TYPE_BEACON_REQ;
-		DBGPRINT(RT_DEBUG_TRACE, ("Duration %d!\n", pReq->Measurement.Duration));
-
-		// If it's non serving channel scan, send out a null frame with PSM bit on.
-		if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
-		{
-			// Use MLME enqueue method
-			NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
-			if (NStatus	!= NDIS_STATUS_SUCCESS)
-				return;
-
-			pNullFrame = (PHEADER_802_11) pOutBuffer;
-			// Make the power save Null frame with PSM bit on
-			MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
-			pNullFrame->Duration 	= 0;
-			pNullFrame->FC.Type     = BTYPE_DATA;
-			pNullFrame->FC.PwrMgmt  = PWR_SAVE;
-
-			// Send using priority queue
-			MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
-			MlmeFreeMemory(pAd, pOutBuffer);
-			DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
-			RTMPusecDelay(5000);
-		}
-
-		pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
-	}
-	else if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_BEACON_TABLE)
-	{
-		// Beacon report Mode, report all the APS in current bss table
-		DBGPRINT(RT_DEBUG_TRACE, ("Beacon Report Mode!\n"));
-
-		// Copy current BSS table to CCX table, we can omit this step later on.
-		NdisMoveMemory(&pAd->StaCfg.CCXBssTab, &pAd->ScanTab, sizeof(BSS_TABLE));
-
-		// Create beacon report from Bss table
-		AironetCreateBeaconReportFromBssTable(pAd);
-
-		// Set state to scanning
-		pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
-
-		// Enqueue report request
-		// Cisco scan request is finished, prepare beacon report
-		MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
-	}
-	else
-	{
-		// Wrong scan Mode
-		DBGPRINT(RT_DEBUG_TRACE, ("Wrong Scan Mode!\n"));
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("BeaconRequestAction <-----\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	AironetReportAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MLME_QUEUE_ELEM	*Elem)
-{
-	PRM_REQUEST_ACTION	pReq;
-	ULONG				Now32;
-
-    NdisGetSystemUpTime(&Now32);
-	pAd->StaCfg.LastBeaconRxTime = Now32;
-
-	pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
-
-	DBGPRINT(RT_DEBUG_TRACE, ("AironetReportAction ----->\n"));
-
-	// 1. Parse measurement type and call appropriate functions
-	if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ)
-		// Channel Load measurement request
-		ChannelLoadReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
-	else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ)
-		// Noise Histogram measurement request
-		NoiseHistReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
-	else if (pReq->ReqElem.Type == MSRN_TYPE_BEACON_REQ)
-		// Beacon measurement request
-		BeaconReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
-	else
-		// Unknown. Do nothing and return
-		;
-
-	// 2. Point to the correct index of action element, start from 0
-	pAd->StaCfg.CurrentRMReqIdx++;
-
-	// 3. Check for parallel actions
-	if (pAd->StaCfg.ParallelReq == TRUE)
-	{
-		pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
-
-		// Process next action right away
-		if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ)
-			// Channel Load measurement request
-			ChannelLoadReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
-		else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ)
-			// Noise Histogram measurement request
-			NoiseHistReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
-
-		pAd->StaCfg.ParallelReq = FALSE;
-		pAd->StaCfg.CurrentRMReqIdx++;
-	}
-
-	if (pAd->StaCfg.CurrentRMReqIdx >= pAd->StaCfg.RMReqCnt)
-	{
-		// 4. There is no more unprocessed measurement request, go for transmit this report
-		AironetFinalReportAction(pAd);
-		pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
-	}
-	else
-	{
-		pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
-
-		if (pReq->Measurement.Channel != pAd->CommonCfg.Channel)
-		{
-			RTMPusecDelay(100000);
-		}
-
-		// 5. There are more requests to be measure
-		MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_REQ, 0, NULL);
-		RT28XX_MLME_HANDLER(pAd);
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("AironetReportAction <-----\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	AironetFinalReportAction(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	PUCHAR					pDest;
-	PAIRONET_IAPP_HEADER	pIAPP;
-	PHEADER_802_11			pHeader;
-	UCHAR					AckRate = RATE_2;
-	USHORT					AckDuration = 0;
-	NDIS_STATUS				NStatus;
-	PUCHAR					pOutBuffer = NULL;
-	ULONG					FrameLen = 0;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("AironetFinalReportAction ----->\n"));
-
-	// 0. Set up the frame pointer, Frame was inited at the end of message action
-	pDest = &pAd->StaCfg.FrameReportBuf[LENGTH_802_11];
-
-	// 1. Update report IAPP fields
-	pIAPP = (PAIRONET_IAPP_HEADER) pDest;
-
-	// 2. Copy Cisco SNAP header
-	NdisMoveMemory(pIAPP->CiscoSnapHeader, SNAP_AIRONET, LENGTH_802_1_H);
-
-	// 3. network order for this 16bit length
-	pIAPP->Length  = cpu2be16(pAd->StaCfg.FrameReportLen - LENGTH_802_11 - LENGTH_802_1_H);
-
-	// 3.1 sanity check the report length, ignore it if there is nothing to report
-	if (be2cpu16(pIAPP->Length) <= 18)
-		return;
-
-	// 4. Type must be 0x32
-	pIAPP->Type    = AIRONET_IAPP_TYPE;
-
-	// 5. SubType for report must be 0x81
-	pIAPP->SubType = AIRONET_IAPP_SUBTYPE_REPORT;
-
-	// 6. DA is not used and must be zero, although the whole frame was cleared at the start of function
-	//    We will do it again here. We can use BSSID instead
-	COPY_MAC_ADDR(pIAPP->DA, pAd->CommonCfg.Bssid);
-
-	// 7. SA is the client reporting which must be our MAC
-	COPY_MAC_ADDR(pIAPP->SA, pAd->CurrentAddress);
-
-	// 8. Copy the saved dialog token
-	pIAPP->Token = pAd->StaCfg.IAPPToken;
-
-	// 9. Make the Report frame 802.11 header
-	//    Reuse function in wpa.c
-	pHeader = (PHEADER_802_11) pAd->StaCfg.FrameReportBuf;
-	pAd->Sequence ++;
-	WpaMacHeaderInit(pAd, pHeader, 0, pAd->CommonCfg.Bssid);
-
-	// ACK size	is 14 include CRC, and its rate	is based on real time information
-	AckRate     = pAd->CommonCfg.ExpectedACKRate[pAd->CommonCfg.MlmeRate];
-	AckDuration = RTMPCalcDuration(pAd, AckRate, 14);
-	pHeader->Duration = pAd->CommonCfg.Dsifs + AckDuration;
-
-	// Use MLME enqueue method
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-	if (NStatus	!= NDIS_STATUS_SUCCESS)
-		return;
-
-	// 10. Prepare report frame with dynamic outbuffer. Just simply copy everything.
-	MakeOutgoingFrame(pOutBuffer,                       &FrameLen,
-	                  pAd->StaCfg.FrameReportLen, pAd->StaCfg.FrameReportBuf,
-		              END_OF_ARGS);
-
-	// 11. Send using priority queue
-	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-	pAd->StaCfg.CCXReqType = MSRN_TYPE_UNUSED;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("AironetFinalReportAction <-----\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	ChannelLoadReportAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Index)
-{
-	PMEASUREMENT_REPORT_ELEMENT	pReport;
-	PCHANNEL_LOAD_REPORT		pLoad;
-	PUCHAR						pDest;
-	UCHAR						CCABusyFraction;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadReportAction ----->\n"));
-
-	// Disable Rx with promiscuous reception, make it back to normal
-	RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification.
-
-	// 0. Setup pointer for processing beacon & probe response
-	pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
-	pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest;
-
-	// 1. Fill Measurement report element field.
-	pReport->Eid    = IE_MEASUREMENT_REPORT;
-	// Fixed Length at 9, not include Eid and length fields
-	pReport->Length = 9;
-	pReport->Token  = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Token;
-	pReport->Mode   = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Mode;
-	pReport->Type   = MSRN_TYPE_CHANNEL_LOAD_REQ;
-
-	// 2. Fill channel report measurement data
-	pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
-	pLoad  = (PCHANNEL_LOAD_REPORT) pDest;
-	pLoad->Channel  = pAd->StaCfg.MeasurementRequest[Index].Measurement.Channel;
-	pLoad->Spare    = 0;
-	pLoad->Duration = pAd->StaCfg.MeasurementRequest[Index].Measurement.Duration;
-
-	// 3. Calculate the CCA Busy Fraction
-	//    (Bytes + ACK size) * 8 / Tx speed * 255 / 1000 / measurement duration, use 24 us Tx speed
-	//     =  (Bytes + ACK) / 12 / duration
-	//     9 is the good value for pAd->StaCfg.CLFactor
-	// CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / 9 / pLoad->Duration);
-	CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / pAd->StaCfg.CLFactor / pLoad->Duration);
-	if (CCABusyFraction < 10)
-			CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / 3 / pLoad->Duration) + 1;
-
-	pLoad->CCABusy = CCABusyFraction;
-	DBGPRINT(RT_DEBUG_TRACE, ("CLBusyByte %ld, Duration %d, Result, %d\n", pAd->StaCfg.CLBusyBytes, pLoad->Duration, CCABusyFraction));
-
-	DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen %d\n", pAd->StaCfg.FrameReportLen));
-	pAd->StaCfg.FrameReportLen += (sizeof(MEASUREMENT_REPORT_ELEMENT) + sizeof(CHANNEL_LOAD_REPORT));
-	DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen %d\n", pAd->StaCfg.FrameReportLen));
-
-	// 4. Clear channel load measurement flag
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
-
-	// 5. reset to idle state
-	pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadReportAction <-----\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	NoiseHistReportAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Index)
-{
-	PMEASUREMENT_REPORT_ELEMENT	pReport;
-	PNOISE_HIST_REPORT			pNoise;
-	PUCHAR						pDest;
-	UCHAR						i,NoiseCnt;
-	USHORT						TotalRPICnt, TotalRPISum;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistReportAction ----->\n"));
-
-	// 0. Disable Rx with promiscuous reception, make it back to normal
-	RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification.
-	// 1. Setup pointer for processing beacon & probe response
-	pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
-	pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest;
-
-	// 2. Fill Measurement report element field.
-	pReport->Eid    = IE_MEASUREMENT_REPORT;
-	// Fixed Length at 16, not include Eid and length fields
-	pReport->Length = 16;
-	pReport->Token  = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Token;
-	pReport->Mode   = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Mode;
-	pReport->Type   = MSRN_TYPE_NOISE_HIST_REQ;
-
-	// 3. Fill noise histogram report measurement data
-	pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
-	pNoise  = (PNOISE_HIST_REPORT) pDest;
-	pNoise->Channel  = pAd->StaCfg.MeasurementRequest[Index].Measurement.Channel;
-	pNoise->Spare    = 0;
-	pNoise->Duration = pAd->StaCfg.MeasurementRequest[Index].Measurement.Duration;
-	// 4. Fill Noise histogram, the total RPI counts should be 0.4 * TU
-	//    We estimate 4000 normal packets received durning 10 seconds test.
-	//    Adjust it if required.
-	// 3 is a good value for pAd->StaCfg.NHFactor
-	// TotalRPICnt = pNoise->Duration * 3 / 10;
-	TotalRPICnt = pNoise->Duration * pAd->StaCfg.NHFactor / 10;
-	TotalRPISum = 0;
-
-	for (i = 0; i < 8; i++)
-	{
-		TotalRPISum += pAd->StaCfg.RPIDensity[i];
-		DBGPRINT(RT_DEBUG_TRACE, ("RPI %d Conuts %d\n", i, pAd->StaCfg.RPIDensity[i]));
-	}
-
-	// Double check if the counter is larger than our expectation.
-	// We will replace it with the total number plus a fraction.
-	if (TotalRPISum > TotalRPICnt)
-		TotalRPICnt = TotalRPISum + pNoise->Duration / 20;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Total RPI Conuts %d\n", TotalRPICnt));
-
-	// 5. Initialize noise count for the total summation of 0xff
-	NoiseCnt = 0;
-	for (i = 1; i < 8; i++)
-	{
-		pNoise->Density[i] = (UCHAR) (pAd->StaCfg.RPIDensity[i] * 255 / TotalRPICnt);
-		if ((pNoise->Density[i] == 0) && (pAd->StaCfg.RPIDensity[i] != 0))
-			pNoise->Density[i]++;
-		NoiseCnt += pNoise->Density[i];
-		DBGPRINT(RT_DEBUG_TRACE, ("Reported RPI[%d]  = 0x%02x\n", i, pNoise->Density[i]));
-	}
-
-	// 6. RPI[0] represents the rest of counts
-	pNoise->Density[0] = 0xff - NoiseCnt;
-	DBGPRINT(RT_DEBUG_TRACE, ("Reported RPI[0]  = 0x%02x\n", pNoise->Density[0]));
-
-	pAd->StaCfg.FrameReportLen += (sizeof(MEASUREMENT_REPORT_ELEMENT) + sizeof(NOISE_HIST_REPORT));
-
-	// 7. Clear channel load measurement flag
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
-
-	// 8. reset to idle state
-	pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistReportAction <-----\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Prepare Beacon report action,
-
-	Arguments:
-		pAd	Pointer	to our adapter
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	BeaconReportAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Index)
-{
-	DBGPRINT(RT_DEBUG_TRACE, ("BeaconReportAction ----->\n"));
-
-	// Looks like we don't have anything thing need to do here.
-	// All measurement report already finished in AddBeaconReport
-	// The length is in the FrameReportLen
-
-	// reset Beacon index for next beacon request
-	pAd->StaCfg.LastBssIndex = 0xff;
-
-	// reset to idle state
-	pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("BeaconReportAction <-----\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-		Index		Current BSSID in CCXBsstab entry index
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-VOID	AironetAddBeaconReport(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	ULONG				Index,
-	IN	PMLME_QUEUE_ELEM	pElem)
-{
-	PVOID						pMsg;
-	PUCHAR						pSrc, pDest;
-	UCHAR						ReqIdx;
-	ULONG						MsgLen;
-	USHORT						Length;
-	PFRAME_802_11				pFrame;
-	PMEASUREMENT_REPORT_ELEMENT	pReport;
-	PEID_STRUCT			        pEid;
-	PBEACON_REPORT				pBeaconReport;
-	PBSS_ENTRY					pBss;
-
-	// 0. Setup pointer for processing beacon & probe response
-	pMsg   = pElem->Msg;
-	MsgLen = pElem->MsgLen;
-	pFrame = (PFRAME_802_11) pMsg;
-	pSrc   = pFrame->Octet;				// Start from AP TSF
-	pBss   = (PBSS_ENTRY) &pAd->StaCfg.CCXBssTab.BssEntry[Index];
-	ReqIdx = pAd->StaCfg.CurrentRMReqIdx;
-
-	// 1 Check the Index, if we already create this entry, only update the average RSSI
-	if ((Index <= pAd->StaCfg.LastBssIndex) && (pAd->StaCfg.LastBssIndex != 0xff))
-	{
-		pDest  = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.BssReportOffset[Index]];
-		// Point to bss report information
-		pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
-		pBeaconReport = (PBEACON_REPORT) pDest;
-
-		// Update Rx power, in dBm
-		// Get the original RSSI readback from BBP
-		pBeaconReport->RxPower += pAd->BbpRssiToDbmDelta;
-		// Average the Rssi reading
-		pBeaconReport->RxPower  = (pBeaconReport->RxPower + pBss->Rssi) / 2;
-		// Get to dBm format
-		pBeaconReport->RxPower -= pAd->BbpRssiToDbmDelta;
-
-		DBGPRINT(RT_DEBUG_TRACE, ("Bssid %02x:%02x:%02x:%02x:%02x:%02x ",
-			pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2],
-			pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
-		DBGPRINT(RT_DEBUG_TRACE, ("RxPower[%ld] Rssi %d, Avg Rssi %d\n", Index, (pBss->Rssi - pAd->BbpRssiToDbmDelta), pBeaconReport->RxPower - 256));
-		DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen = %d\n", pAd->StaCfg.BssReportOffset[Index]));
-
-		// Update other information here
-
-		// Done
-		return;
-	}
-
-	// 2. Update reported Index
-	pAd->StaCfg.LastBssIndex = Index;
-
-	// 3. Setup the buffer address for copying this BSSID into reporting frame
-	//    The offset should start after 802.11 header and report frame header.
-	pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
-
-	// 4. Save the start offset of each Bss in report frame
-	pAd->StaCfg.BssReportOffset[Index] = pAd->StaCfg.FrameReportLen;
-
-	// 5. Fill Measurement report fields
-	pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest;
-	pReport->Eid = IE_MEASUREMENT_REPORT;
-	pReport->Length = 0;
-	pReport->Token  = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Token;
-	pReport->Mode   = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Mode;
-	pReport->Type   = MSRN_TYPE_BEACON_REQ;
-	Length          = sizeof(MEASUREMENT_REPORT_ELEMENT);
-	pDest          += sizeof(MEASUREMENT_REPORT_ELEMENT);
-
-	// 6. Start thebeacon report format
-	pBeaconReport = (PBEACON_REPORT) pDest;
-	pDest        += sizeof(BEACON_REPORT);
-	Length       += sizeof(BEACON_REPORT);
-
-	// 7. Copy Channel number
-	pBeaconReport->Channel        = pBss->Channel;
-	pBeaconReport->Spare          = 0;
-	pBeaconReport->Duration       = pAd->StaCfg.MeasurementRequest[ReqIdx].Measurement.Duration;
-	pBeaconReport->PhyType        = ((pBss->SupRateLen+pBss->ExtRateLen > 4) ? PHY_ERP : PHY_DSS);
-	// 8. Rx power, in dBm
-	pBeaconReport->RxPower        = pBss->Rssi - pAd->BbpRssiToDbmDelta;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Bssid %02x:%02x:%02x:%02x:%02x:%02x ",
-		pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2],
-		pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
-	DBGPRINT(RT_DEBUG_TRACE, ("RxPower[%ld], Rssi %d\n", Index, pBeaconReport->RxPower - 256));
-	DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen = %d\n", pAd->StaCfg.FrameReportLen));
-
-	pBeaconReport->BeaconInterval = pBss->BeaconPeriod;
-	COPY_MAC_ADDR(pBeaconReport->BSSID, pFrame->Hdr.Addr3);
-	NdisMoveMemory(pBeaconReport->ParentTSF, pSrc, 4);
-	NdisMoveMemory(pBeaconReport->TargetTSF, &pElem->TimeStamp.u.LowPart, 4);
-	NdisMoveMemory(&pBeaconReport->TargetTSF[4], &pElem->TimeStamp.u.HighPart, 4);
-
-	// 9. Skip the beacon frame and offset to start of capabilityinfo since we already processed capabilityinfo
-	pSrc += (TIMESTAMP_LEN + 2);
-	pBeaconReport->CapabilityInfo = *(USHORT *)pSrc;
-
-	// 10. Point to start of element ID
-	pSrc += 2;
-	pEid = (PEID_STRUCT) pSrc;
-
-	// 11. Start process all variable Eid oayload and add the appropriate to the frame report
-	while (((PUCHAR) pEid + pEid->Len + 1) < ((PUCHAR) pFrame + MsgLen))
-	{
-		// Only limited EID are required to report for CCX 2. It includes SSID, Supported rate,
-		// FH paramenter set, DS parameter set, CF parameter set, IBSS parameter set,
-		// TIM (report first 4 bytes only, radio measurement capability
-		switch (pEid->Eid)
-		{
-			case IE_SSID:
-			case IE_SUPP_RATES:
-			case IE_FH_PARM:
-			case IE_DS_PARM:
-			case IE_CF_PARM:
-			case IE_IBSS_PARM:
-				NdisMoveMemory(pDest, pEid, pEid->Len + 2);
-				pDest  += (pEid->Len + 2);
-				Length += (pEid->Len + 2);
-				break;
-
-			case IE_MEASUREMENT_CAPABILITY:
-				// Since this IE is duplicated with WPA security IE, we has to do sanity check before
-				// recognize it.
-				// 1. It also has fixed 6 bytes IE length.
-				if (pEid->Len != 6)
-					break;
-				// 2. Check the Cisco Aironet OUI
-				if (NdisEqualMemory(CISCO_OUI, (pSrc + 2), 3))
-				{
-					// Matched, this is what we want
-					NdisMoveMemory(pDest, pEid, pEid->Len + 2);
-					pDest  += (pEid->Len + 2);
-					Length += (pEid->Len + 2);
-				}
-				break;
-
-			case IE_TIM:
-				if (pEid->Len > 4)
-				{
-					// May truncate and report the first 4 bytes only, with the eid & len, total should be 6
-					NdisMoveMemory(pDest, pEid, 6);
-					pDest  += 6;
-					Length += 6;
-				}
-				else
-				{
-					NdisMoveMemory(pDest, pEid, pEid->Len + 2);
-					pDest  += (pEid->Len + 2);
-					Length += (pEid->Len + 2);
-				}
-				break;
-
-			default:
-				break;
-		}
-		// 12. Move to next element ID
-		pSrc += (2 + pEid->Len);
-		pEid = (PEID_STRUCT) pSrc;
-	}
-
-	// 13. Update the length in the header, not include EID and length
-	pReport->Length = Length - 4;
-
-	// 14. Update the frame report buffer data length
-	pAd->StaCfg.FrameReportLen += Length;
-	DBGPRINT(RT_DEBUG_TRACE, ("FR len = %d\n", pAd->StaCfg.FrameReportLen));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-		Index		Current BSSID in CCXBsstab entry index
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-VOID	AironetCreateBeaconReportFromBssTable(
-	IN	PRTMP_ADAPTER		pAd)
-{
-	PMEASUREMENT_REPORT_ELEMENT	pReport;
-	PBEACON_REPORT				pBeaconReport;
-	UCHAR						Index, ReqIdx;
-	USHORT						Length;
-	PUCHAR						pDest;
-	PBSS_ENTRY					pBss;
-
-	// 0. setup base pointer
-	ReqIdx = pAd->StaCfg.CurrentRMReqIdx;
-
-	for (Index = 0; Index < pAd->StaCfg.CCXBssTab.BssNr; Index++)
-	{
-		// 1. Setup the buffer address for copying this BSSID into reporting frame
-		//    The offset should start after 802.11 header and report frame header.
-		pDest  = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
-		pBss   = (PBSS_ENTRY) &pAd->StaCfg.CCXBssTab.BssEntry[Index];
-		Length = 0;
-
-		// 2. Fill Measurement report fields
-		pReport         = (PMEASUREMENT_REPORT_ELEMENT) pDest;
-		pReport->Eid    = IE_MEASUREMENT_REPORT;
-		pReport->Length = 0;
-		pReport->Token  = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Token;
-		pReport->Mode   = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Mode;
-		pReport->Type   = MSRN_TYPE_BEACON_REQ;
-		Length          = sizeof(MEASUREMENT_REPORT_ELEMENT);
-		pDest          += sizeof(MEASUREMENT_REPORT_ELEMENT);
-
-		// 3. Start the beacon report format
-		pBeaconReport = (PBEACON_REPORT) pDest;
-		pDest        += sizeof(BEACON_REPORT);
-		Length       += sizeof(BEACON_REPORT);
-
-		// 4. Copy Channel number
-		pBeaconReport->Channel        = pBss->Channel;
-		pBeaconReport->Spare          = 0;
-		pBeaconReport->Duration       = pAd->StaCfg.MeasurementRequest[ReqIdx].Measurement.Duration;
-		pBeaconReport->PhyType        = ((pBss->SupRateLen+pBss->ExtRateLen > 4) ? PHY_ERP : PHY_DSS);
-		pBeaconReport->RxPower        = pBss->Rssi - pAd->BbpRssiToDbmDelta;
-		pBeaconReport->BeaconInterval = pBss->BeaconPeriod;
-		pBeaconReport->CapabilityInfo = pBss->CapabilityInfo;
-		COPY_MAC_ADDR(pBeaconReport->BSSID, pBss->Bssid);
-		NdisMoveMemory(pBeaconReport->ParentTSF, pBss->PTSF, 4);
-		NdisMoveMemory(pBeaconReport->TargetTSF, pBss->TTSF, 8);
-
-		// 5. Create SSID
-		*pDest++ = 0x00;
-		*pDest++ = pBss->SsidLen;
-		NdisMoveMemory(pDest, pBss->Ssid, pBss->SsidLen);
-		pDest  += pBss->SsidLen;
-		Length += (2 + pBss->SsidLen);
-
-		// 6. Create SupportRates
-		*pDest++ = 0x01;
-		*pDest++ = pBss->SupRateLen;
-		NdisMoveMemory(pDest, pBss->SupRate, pBss->SupRateLen);
-		pDest  += pBss->SupRateLen;
-		Length += (2 + pBss->SupRateLen);
-
-		// 7. DS Parameter
-		*pDest++ = 0x03;
-		*pDest++ = 1;
-		*pDest++ = pBss->Channel;
-		Length  += 3;
-
-		// 8. IBSS parameter if presents
-		if (pBss->BssType == BSS_ADHOC)
-		{
-			*pDest++ = 0x06;
-			*pDest++ = 2;
-			*(PUSHORT) pDest = pBss->AtimWin;
-			pDest   += 2;
-			Length  += 4;
-		}
-
-		// 9. Update length field, not include EID and length
-		pReport->Length = Length - 4;
-
-		// 10. Update total frame size
-		pAd->StaCfg.FrameReportLen += Length;
-	}
-}
diff --git a/drivers/staging/rt2860/sta/assoc.c b/drivers/staging/rt2860/sta/assoc.c
index 1a58715..7055f22 100644
--- a/drivers/staging/rt2860/sta/assoc.c
+++ b/drivers/staging/rt2860/sta/assoc.c
@@ -36,31 +36,31 @@
 */
 #include "../rt_config.h"
 
-UCHAR	CipherWpaTemplate[] = {
-		0xdd, 					// WPA IE
-		0x16,					// Length
-		0x00, 0x50, 0xf2, 0x01,	// oui
-		0x01, 0x00,				// Version
-		0x00, 0x50, 0xf2, 0x02,	// Multicast
-		0x01, 0x00,				// Number of unicast
-		0x00, 0x50, 0xf2, 0x02,	// unicast
-		0x01, 0x00,				// number of authentication method
-		0x00, 0x50, 0xf2, 0x01	// authentication
-		};
+u8 CipherWpaTemplate[] = {
+	0xdd,			/* WPA IE */
+	0x16,			/* Length */
+	0x00, 0x50, 0xf2, 0x01,	/* oui */
+	0x01, 0x00,		/* Version */
+	0x00, 0x50, 0xf2, 0x02,	/* Multicast */
+	0x01, 0x00,		/* Number of unicast */
+	0x00, 0x50, 0xf2, 0x02,	/* unicast */
+	0x01, 0x00,		/* number of authentication method */
+	0x00, 0x50, 0xf2, 0x01	/* authentication */
+};
 
-UCHAR	CipherWpa2Template[] = {
-		0x30,					// RSN IE
-		0x14,					// Length
-		0x01, 0x00,				// Version
-		0x00, 0x0f, 0xac, 0x02,	// group cipher, TKIP
-		0x01, 0x00,				// number of pairwise
-		0x00, 0x0f, 0xac, 0x02,	// unicast
-		0x01, 0x00,				// number of authentication method
-		0x00, 0x0f, 0xac, 0x02,	// authentication
-		0x00, 0x00,				// RSN capability
-		};
+u8 CipherWpa2Template[] = {
+	0x30,			/* RSN IE */
+	0x14,			/* Length */
+	0x01, 0x00,		/* Version */
+	0x00, 0x0f, 0xac, 0x02,	/* group cipher, TKIP */
+	0x01, 0x00,		/* number of pairwise */
+	0x00, 0x0f, 0xac, 0x02,	/* unicast */
+	0x01, 0x00,		/* number of authentication method */
+	0x00, 0x0f, 0xac, 0x02,	/* authentication */
+	0x00, 0x00,		/* RSN capability */
+};
 
-UCHAR	Ccx2IeInfo[] = { 0x00, 0x40, 0x96, 0x03, 0x02};
+u8 Ccx2IeInfo[] = { 0x00, 0x40, 0x96, 0x03, 0x02 };
 
 /*
 	==========================================================================
@@ -73,55 +73,84 @@
 
 	==========================================================================
  */
-VOID AssocStateMachineInit(
-	IN	PRTMP_ADAPTER	pAd,
-	IN  STATE_MACHINE *S,
-	OUT STATE_MACHINE_FUNC Trans[])
+void AssocStateMachineInit(struct rt_rtmp_adapter *pAd,
+			   struct rt_state_machine *S, OUT STATE_MACHINE_FUNC Trans[])
 {
-	StateMachineInit(S, Trans, MAX_ASSOC_STATE, MAX_ASSOC_MSG, (STATE_MACHINE_FUNC)Drop, ASSOC_IDLE, ASSOC_MACHINE_BASE);
+	StateMachineInit(S, Trans, MAX_ASSOC_STATE, MAX_ASSOC_MSG,
+			 (STATE_MACHINE_FUNC) Drop, ASSOC_IDLE,
+			 ASSOC_MACHINE_BASE);
 
-	// first column
-	StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)MlmeAssocReqAction);
-	StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)MlmeReassocReqAction);
-	StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)MlmeDisassocReqAction);
-	StateMachineSetAction(S, ASSOC_IDLE, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
+	/* first column */
+	StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_ASSOC_REQ,
+			      (STATE_MACHINE_FUNC) MlmeAssocReqAction);
+	StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_REASSOC_REQ,
+			      (STATE_MACHINE_FUNC) MlmeReassocReqAction);
+	StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_DISASSOC_REQ,
+			      (STATE_MACHINE_FUNC) MlmeDisassocReqAction);
+	StateMachineSetAction(S, ASSOC_IDLE, MT2_PEER_DISASSOC_REQ,
+			      (STATE_MACHINE_FUNC) PeerDisassocAction);
 
-	// second column
-	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
-	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
-	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
-	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
-	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP, (STATE_MACHINE_FUNC)PeerAssocRspAction);
-	//
-	// Patch 3Com AP MOde:3CRWE454G72
-	// We send Assoc request frame to this AP, it always send Reassoc Rsp not Associate Rsp.
-	//
-	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP, (STATE_MACHINE_FUNC)PeerAssocRspAction);
-	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_ASSOC_TIMEOUT, (STATE_MACHINE_FUNC)AssocTimeoutAction);
+	/* second column */
+	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ,
+			      (STATE_MACHINE_FUNC) InvalidStateWhenAssoc);
+	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ,
+			      (STATE_MACHINE_FUNC) InvalidStateWhenReassoc);
+	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ,
+			      (STATE_MACHINE_FUNC)
+			      InvalidStateWhenDisassociate);
+	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ,
+			      (STATE_MACHINE_FUNC) PeerDisassocAction);
+	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP,
+			      (STATE_MACHINE_FUNC) PeerAssocRspAction);
+	/* */
+	/* Patch 3Com AP MOde:3CRWE454G72 */
+	/* We send Assoc request frame to this AP, it always send Reassoc Rsp not Associate Rsp. */
+	/* */
+	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP,
+			      (STATE_MACHINE_FUNC) PeerAssocRspAction);
+	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_ASSOC_TIMEOUT,
+			      (STATE_MACHINE_FUNC) AssocTimeoutAction);
 
-	// third column
-	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
-	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
-	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
-	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
-	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP, (STATE_MACHINE_FUNC)PeerReassocRspAction);
-	//
-	// Patch, AP doesn't send Reassociate Rsp frame to Station.
-	//
-	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP, (STATE_MACHINE_FUNC)PeerReassocRspAction);
-	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_REASSOC_TIMEOUT, (STATE_MACHINE_FUNC)ReassocTimeoutAction);
+	/* third column */
+	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ,
+			      (STATE_MACHINE_FUNC) InvalidStateWhenAssoc);
+	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ,
+			      (STATE_MACHINE_FUNC) InvalidStateWhenReassoc);
+	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ,
+			      (STATE_MACHINE_FUNC)
+			      InvalidStateWhenDisassociate);
+	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ,
+			      (STATE_MACHINE_FUNC) PeerDisassocAction);
+	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP,
+			      (STATE_MACHINE_FUNC) PeerReassocRspAction);
+	/* */
+	/* Patch, AP doesn't send Reassociate Rsp frame to Station. */
+	/* */
+	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP,
+			      (STATE_MACHINE_FUNC) PeerReassocRspAction);
+	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_REASSOC_TIMEOUT,
+			      (STATE_MACHINE_FUNC) ReassocTimeoutAction);
 
-	// fourth column
-	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
-	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
-	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
-	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
-	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_DISASSOC_TIMEOUT, (STATE_MACHINE_FUNC)DisassocTimeoutAction);
+	/* fourth column */
+	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ,
+			      (STATE_MACHINE_FUNC) InvalidStateWhenAssoc);
+	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ,
+			      (STATE_MACHINE_FUNC) InvalidStateWhenReassoc);
+	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ,
+			      (STATE_MACHINE_FUNC)
+			      InvalidStateWhenDisassociate);
+	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ,
+			      (STATE_MACHINE_FUNC) PeerDisassocAction);
+	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_DISASSOC_TIMEOUT,
+			      (STATE_MACHINE_FUNC) DisassocTimeoutAction);
 
-	// initialize the timer
-	RTMPInitTimer(pAd, &pAd->MlmeAux.AssocTimer, GET_TIMER_FUNCTION(AssocTimeout), pAd, FALSE);
-	RTMPInitTimer(pAd, &pAd->MlmeAux.ReassocTimer, GET_TIMER_FUNCTION(ReassocTimeout), pAd, FALSE);
-	RTMPInitTimer(pAd, &pAd->MlmeAux.DisassocTimer, GET_TIMER_FUNCTION(DisassocTimeout), pAd, FALSE);
+	/* initialize the timer */
+	RTMPInitTimer(pAd, &pAd->MlmeAux.AssocTimer,
+		      GET_TIMER_FUNCTION(AssocTimeout), pAd, FALSE);
+	RTMPInitTimer(pAd, &pAd->MlmeAux.ReassocTimer,
+		      GET_TIMER_FUNCTION(ReassocTimeout), pAd, FALSE);
+	RTMPInitTimer(pAd, &pAd->MlmeAux.DisassocTimer,
+		      GET_TIMER_FUNCTION(DisassocTimeout), pAd, FALSE);
 }
 
 /*
@@ -136,20 +165,20 @@
 
 	==========================================================================
  */
-VOID AssocTimeout(IN PVOID SystemSpecific1,
-				 IN PVOID FunctionContext,
-				 IN PVOID SystemSpecific2,
-				 IN PVOID SystemSpecific3)
+void AssocTimeout(void *SystemSpecific1,
+		  void *FunctionContext,
+		  void *SystemSpecific2, void *SystemSpecific3)
 {
-	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
 
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+	/* Do nothing if the driver is starting halt state. */
+	/* This might happen when timer already been fired before cancel timer with mlmehalt */
+	if (RTMP_TEST_FLAG
+	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
 		return;
 
 	MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_ASSOC_TIMEOUT, 0, NULL);
-	RT28XX_MLME_HANDLER(pAd);
+	RTMP_MLME_HANDLER(pAd);
 }
 
 /*
@@ -164,20 +193,20 @@
 
 	==========================================================================
  */
-VOID ReassocTimeout(IN PVOID SystemSpecific1,
-					IN PVOID FunctionContext,
-					IN PVOID SystemSpecific2,
-					IN PVOID SystemSpecific3)
+void ReassocTimeout(void *SystemSpecific1,
+		    void *FunctionContext,
+		    void *SystemSpecific2, void *SystemSpecific3)
 {
-	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
 
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+	/* Do nothing if the driver is starting halt state. */
+	/* This might happen when timer already been fired before cancel timer with mlmehalt */
+	if (RTMP_TEST_FLAG
+	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
 		return;
 
 	MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_REASSOC_TIMEOUT, 0, NULL);
-	RT28XX_MLME_HANDLER(pAd);
+	RTMP_MLME_HANDLER(pAd);
 }
 
 /*
@@ -192,20 +221,20 @@
 
 	==========================================================================
  */
-VOID DisassocTimeout(IN PVOID SystemSpecific1,
-					IN PVOID FunctionContext,
-					IN PVOID SystemSpecific2,
-					IN PVOID SystemSpecific3)
+void DisassocTimeout(void *SystemSpecific1,
+		     void *FunctionContext,
+		     void *SystemSpecific2, void *SystemSpecific3)
 {
-	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
 
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+	/* Do nothing if the driver is starting halt state. */
+	/* This might happen when timer already been fired before cancel timer with mlmehalt */
+	if (RTMP_TEST_FLAG
+	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
 		return;
 
 	MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_DISASSOC_TIMEOUT, 0, NULL);
-	RT28XX_MLME_HANDLER(pAd);
+	RTMP_MLME_HANDLER(pAd);
 }
 
 /*
@@ -230,349 +259,315 @@
 
 	==========================================================================
  */
-VOID MlmeAssocReqAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void MlmeAssocReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	UCHAR			ApAddr[6];
-	HEADER_802_11	AssocHdr;
-	UCHAR			Ccx2Len = 5;
-	UCHAR			WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
-	USHORT			ListenIntv;
-	ULONG			Timeout;
-	USHORT			CapabilityInfo;
-	BOOLEAN			TimerCancelled;
-	PUCHAR			pOutBuffer = NULL;
-	NDIS_STATUS		NStatus;
-	ULONG			FrameLen = 0;
-	ULONG			tmp;
-	USHORT			VarIesOffset;
-	UCHAR			CkipFlag;
-	UCHAR			CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH];
-	UCHAR			AironetCkipIe = IE_AIRONET_CKIP;
-	UCHAR			AironetCkipLen = CKIP_NEGOTIATION_LENGTH;
-	UCHAR			AironetIPAddressIE = IE_AIRONET_IPADDRESS;
-	UCHAR			AironetIPAddressLen = AIRONET_IPADDRESS_LENGTH;
-	UCHAR			AironetIPAddressBuffer[AIRONET_IPADDRESS_LENGTH] = {0x00, 0x40, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
-	USHORT			Status;
+	u8 ApAddr[6];
+	struct rt_header_802_11 AssocHdr;
+	u8 WmeIe[9] =
+	    { IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01,
+       0x00 };
+	u16 ListenIntv;
+	unsigned long Timeout;
+	u16 CapabilityInfo;
+	BOOLEAN TimerCancelled;
+	u8 *pOutBuffer = NULL;
+	int NStatus;
+	unsigned long FrameLen = 0;
+	unsigned long tmp;
+	u16 VarIesOffset;
+	u16 Status;
 
-	// Block all authentication request durning WPA block period
-	if (pAd->StaCfg.bBlockAssoc == TRUE)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Block Assoc request durning WPA block period!\n"));
+	/* Block all authentication request durning WPA block period */
+	if (pAd->StaCfg.bBlockAssoc == TRUE) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("ASSOC - Block Assoc request durning WPA block period!\n"));
 		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
 		Status = MLME_STATE_MACHINE_REJECT;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
+		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2,
+			    &Status);
 	}
-	// check sanity first
-	else if (MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, &Timeout, &ListenIntv))
-	{
+	/* check sanity first */
+	else if (MlmeAssocReqSanity
+		 (pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo,
+		  &Timeout, &ListenIntv)) {
 		RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &TimerCancelled);
 		COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr);
 
-		// Get an unused nonpaged memory
+		/* Get an unused nonpaged memory */
 		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
-		if (NStatus != NDIS_STATUS_SUCCESS)
-		{
-			DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeAssocReqAction() allocate memory failed \n"));
+		if (NStatus != NDIS_STATUS_SUCCESS) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("ASSOC - MlmeAssocReqAction() allocate memory failed \n"));
 			pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
 			Status = MLME_FAIL_NO_RESOURCE;
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
+			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE,
+				    MT2_ASSOC_CONF, 2, &Status);
 			return;
 		}
-
-		// Add by James 03/06/27
-		pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
-		// Association don't need to report MAC address
+		/* Add by James 03/06/27 */
+		pAd->StaCfg.AssocInfo.Length =
+		    sizeof(struct rt_ndis_802_11_association_information);
+		/* Association don't need to report MAC address */
 		pAd->StaCfg.AssocInfo.AvailableRequestFixedIEs =
-			NDIS_802_11_AI_REQFI_CAPABILITIES | NDIS_802_11_AI_REQFI_LISTENINTERVAL;
-		pAd->StaCfg.AssocInfo.RequestFixedIEs.Capabilities = CapabilityInfo;
-		pAd->StaCfg.AssocInfo.RequestFixedIEs.ListenInterval = ListenIntv;
-		// Only reassociate need this
-		//COPY_MAC_ADDR(pAd->StaCfg.AssocInfo.RequestFixedIEs.CurrentAPAddress, ApAddr);
-		pAd->StaCfg.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
+		    NDIS_802_11_AI_REQFI_CAPABILITIES |
+		    NDIS_802_11_AI_REQFI_LISTENINTERVAL;
+		pAd->StaCfg.AssocInfo.RequestFixedIEs.Capabilities =
+		    CapabilityInfo;
+		pAd->StaCfg.AssocInfo.RequestFixedIEs.ListenInterval =
+		    ListenIntv;
+		/* Only reassociate need this */
+		/*COPY_MAC_ADDR(pAd->StaCfg.AssocInfo.RequestFixedIEs.CurrentAPAddress, ApAddr); */
+		pAd->StaCfg.AssocInfo.OffsetRequestIEs =
+		    sizeof(struct rt_ndis_802_11_association_information);
 
-        NdisZeroMemory(pAd->StaCfg.ReqVarIEs, MAX_VIE_LEN);
-		// First add SSID
+		NdisZeroMemory(pAd->StaCfg.ReqVarIEs, MAX_VIE_LEN);
+		/* First add SSID */
 		VarIesOffset = 0;
-		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SsidIe, 1);
+		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SsidIe,
+			       1);
 		VarIesOffset += 1;
-		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->MlmeAux.SsidLen, 1);
+		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset,
+			       &pAd->MlmeAux.SsidLen, 1);
 		VarIesOffset += 1;
-		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset,
+			       pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
 		VarIesOffset += pAd->MlmeAux.SsidLen;
 
-		// Second add Supported rates
-		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SupRateIe, 1);
+		/* Second add Supported rates */
+		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SupRateIe,
+			       1);
 		VarIesOffset += 1;
-		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->MlmeAux.SupRateLen, 1);
+		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset,
+			       &pAd->MlmeAux.SupRateLen, 1);
 		VarIesOffset += 1;
-		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->MlmeAux.SupRate, pAd->MlmeAux.SupRateLen);
+		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset,
+			       pAd->MlmeAux.SupRate, pAd->MlmeAux.SupRateLen);
 		VarIesOffset += pAd->MlmeAux.SupRateLen;
-		// End Add by James
+		/* End Add by James */
 
-        if ((pAd->CommonCfg.Channel > 14) &&
-            (pAd->CommonCfg.bIEEE80211H == TRUE))
-            CapabilityInfo |= 0x0100;
+		if ((pAd->CommonCfg.Channel > 14) &&
+		    (pAd->CommonCfg.bIEEE80211H == TRUE))
+			CapabilityInfo |= 0x0100;
 
 		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send ASSOC request...\n"));
-		MgtMacHeaderInit(pAd, &AssocHdr, SUBTYPE_ASSOC_REQ, 0, ApAddr, ApAddr);
+		MgtMacHeaderInit(pAd, &AssocHdr, SUBTYPE_ASSOC_REQ, 0, ApAddr,
+				 ApAddr);
 
-		// Build basic frame first
-		MakeOutgoingFrame(pOutBuffer,				&FrameLen,
-						  sizeof(HEADER_802_11),	&AssocHdr,
-						  2,						&CapabilityInfo,
-						  2,						&ListenIntv,
-						  1,						&SsidIe,
-						  1,						&pAd->MlmeAux.SsidLen,
-						  pAd->MlmeAux.SsidLen, 	pAd->MlmeAux.Ssid,
-						  1,						&SupRateIe,
-						  1,						&pAd->MlmeAux.SupRateLen,
-						  pAd->MlmeAux.SupRateLen,  pAd->MlmeAux.SupRate,
-						  END_OF_ARGS);
+		/* Build basic frame first */
+		MakeOutgoingFrame(pOutBuffer, &FrameLen,
+				  sizeof(struct rt_header_802_11), &AssocHdr,
+				  2, &CapabilityInfo,
+				  2, &ListenIntv,
+				  1, &SsidIe,
+				  1, &pAd->MlmeAux.SsidLen,
+				  pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid,
+				  1, &SupRateIe,
+				  1, &pAd->MlmeAux.SupRateLen,
+				  pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
+				  END_OF_ARGS);
 
-		if (pAd->MlmeAux.ExtRateLen != 0)
-		{
-			MakeOutgoingFrame(pOutBuffer + FrameLen,    &tmp,
-							  1,                        &ExtRateIe,
-							  1,                        &pAd->MlmeAux.ExtRateLen,
-							  pAd->MlmeAux.ExtRateLen,  pAd->MlmeAux.ExtRate,
-							  END_OF_ARGS);
+		if (pAd->MlmeAux.ExtRateLen != 0) {
+			MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+					  1, &ExtRateIe,
+					  1, &pAd->MlmeAux.ExtRateLen,
+					  pAd->MlmeAux.ExtRateLen,
+					  pAd->MlmeAux.ExtRate, END_OF_ARGS);
 			FrameLen += tmp;
 		}
-
-		// HT
-		if ((pAd->MlmeAux.HtCapabilityLen > 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
-		{
-			ULONG TmpLen;
-			UCHAR HtLen;
-			UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
-			if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE)
-			{
+		/* HT */
+		if ((pAd->MlmeAux.HtCapabilityLen > 0)
+		    && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) {
+			unsigned long TmpLen;
+			u8 HtLen;
+			u8 BROADCOM[4] = { 0x0, 0x90, 0x4c, 0x33 };
+			if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE) {
 				HtLen = SIZE_HT_CAP_IE + 4;
-				MakeOutgoingFrame(pOutBuffer + FrameLen,            &TmpLen,
-							  1,                                &WpaIe,
-							  1,                                &HtLen,
-							  4,                                &BROADCOM[0],
-							 pAd->MlmeAux.HtCapabilityLen,          &pAd->MlmeAux.HtCapability,
-							  END_OF_ARGS);
-			}
-			else
-			{
-				MakeOutgoingFrame(pOutBuffer + FrameLen,            &TmpLen,
-							  1,                                &HtCapIe,
-							  1,                                &pAd->MlmeAux.HtCapabilityLen,
-							 pAd->MlmeAux.HtCapabilityLen,          &pAd->MlmeAux.HtCapability,
-							  END_OF_ARGS);
+				MakeOutgoingFrame(pOutBuffer + FrameLen,
+						  &TmpLen, 1, &WpaIe, 1, &HtLen,
+						  4, &BROADCOM[0],
+						  pAd->MlmeAux.HtCapabilityLen,
+						  &pAd->MlmeAux.HtCapability,
+						  END_OF_ARGS);
+			} else {
+				MakeOutgoingFrame(pOutBuffer + FrameLen,
+						  &TmpLen, 1, &HtCapIe, 1,
+						  &pAd->MlmeAux.HtCapabilityLen,
+						  pAd->MlmeAux.HtCapabilityLen,
+						  &pAd->MlmeAux.HtCapability,
+						  END_OF_ARGS);
 			}
 			FrameLen += TmpLen;
 		}
-
-		// add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION
-		// Case I: (Aggregation + Piggy-Back)
-		// 1. user enable aggregation, AND
-		// 2. Mac support piggy-back
-		// 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON
-		// Case II: (Aggregation)
-		// 1. user enable aggregation, AND
-		// 2. AP annouces it's AGGREGATION-capable in BEACON
-		if (pAd->CommonCfg.bAggregationCapable)
-		{
-			if ((pAd->CommonCfg.bPiggyBackCapable) && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3))
-			{
-				ULONG TmpLen;
-				UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x03, 0x00, 0x00, 0x00};
-				MakeOutgoingFrame(pOutBuffer+FrameLen,           &TmpLen,
-								  9,                             RalinkIe,
-								  END_OF_ARGS);
+		/* add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION */
+		/* Case I: (Aggregation + Piggy-Back) */
+		/* 1. user enable aggregation, AND */
+		/* 2. Mac support piggy-back */
+		/* 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON */
+		/* Case II: (Aggregation) */
+		/* 1. user enable aggregation, AND */
+		/* 2. AP annouces it's AGGREGATION-capable in BEACON */
+		if (pAd->CommonCfg.bAggregationCapable) {
+			if ((pAd->CommonCfg.bPiggyBackCapable)
+			    && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)) {
+				unsigned long TmpLen;
+				u8 RalinkIe[9] =
+				    { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43,
+			    0x03, 0x00, 0x00, 0x00 };
+				MakeOutgoingFrame(pOutBuffer + FrameLen,
+						  &TmpLen, 9, RalinkIe,
+						  END_OF_ARGS);
+				FrameLen += TmpLen;
+			} else if (pAd->MlmeAux.APRalinkIe & 0x00000001) {
+				unsigned long TmpLen;
+				u8 RalinkIe[9] =
+				    { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43,
+			    0x01, 0x00, 0x00, 0x00 };
+				MakeOutgoingFrame(pOutBuffer + FrameLen,
+						  &TmpLen, 9, RalinkIe,
+						  END_OF_ARGS);
 				FrameLen += TmpLen;
 			}
-			else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
-			{
-				ULONG TmpLen;
-				UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00};
-				MakeOutgoingFrame(pOutBuffer+FrameLen,           &TmpLen,
-								  9,                             RalinkIe,
-								  END_OF_ARGS);
-				FrameLen += TmpLen;
-			}
-		}
-		else
-		{
-			ULONG TmpLen;
-			UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x06, 0x00, 0x00, 0x00};
-			MakeOutgoingFrame(pOutBuffer+FrameLen,		 &TmpLen,
-							  9,						 RalinkIe,
-							  END_OF_ARGS);
+		} else {
+			unsigned long TmpLen;
+			u8 RalinkIe[9] =
+			    { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x06,
+		    0x00, 0x00, 0x00 };
+			MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 9,
+					  RalinkIe, END_OF_ARGS);
 			FrameLen += TmpLen;
 		}
 
-		if (pAd->MlmeAux.APEdcaParm.bValid)
-		{
-			if (pAd->CommonCfg.bAPSDCapable && pAd->MlmeAux.APEdcaParm.bAPSDCapable)
-			{
-				QBSS_STA_INFO_PARM QosInfo;
+		if (pAd->MlmeAux.APEdcaParm.bValid) {
+			if (pAd->CommonCfg.bAPSDCapable
+			    && pAd->MlmeAux.APEdcaParm.bAPSDCapable) {
+				struct rt_qbss_sta_info_parm QosInfo;
 
-				NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM));
+				NdisZeroMemory(&QosInfo,
+					       sizeof(struct rt_qbss_sta_info_parm));
 				QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE;
 				QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK;
 				QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI;
 				QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO;
-				QosInfo.MaxSPLength = pAd->CommonCfg.MaxSPLength;
-				WmeIe[8] |= *(PUCHAR)&QosInfo;
-			}
-			else
-			{
-                // The Parameter Set Count is set to ¡§0¡¨ in the association request frames
-                // WmeIe[8] |= (pAd->MlmeAux.APEdcaParm.EdcaUpdateCount & 0x0f);
+				QosInfo.MaxSPLength =
+				    pAd->CommonCfg.MaxSPLength;
+				WmeIe[8] |= *(u8 *)& QosInfo;
+			} else {
+				/* The Parameter Set Count is set to ¡§0¡¨ in the association request frames */
+				/* WmeIe[8] |= (pAd->MlmeAux.APEdcaParm.EdcaUpdateCount & 0x0f); */
 			}
 
-			MakeOutgoingFrame(pOutBuffer + FrameLen,    &tmp,
-							  9,                        &WmeIe[0],
-							  END_OF_ARGS);
+			MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+					  9, &WmeIe[0], END_OF_ARGS);
 			FrameLen += tmp;
 		}
-
-		//
-		// Let WPA(#221) Element ID on the end of this association frame.
-		// Otherwise some AP will fail on parsing Element ID and set status fail on Assoc Rsp.
-		// For example: Put Vendor Specific IE on the front of WPA IE.
-		// This happens on AP (Model No:Linksys WRK54G)
-		//
+		/* */
+		/* Let WPA(#221) Element ID on the end of this association frame. */
+		/* Otherwise some AP will fail on parsing Element ID and set status fail on Assoc Rsp. */
+		/* For example: Put Vendor Specific IE on the front of WPA IE. */
+		/* This happens on AP (Model No:Linksys WRK54G) */
+		/* */
 		if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
-            (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
-            (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
-            (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
-			)
-            )
-		{
-			UCHAR RSNIe = IE_WPA;
+		     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
+		     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
+		     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
+		    )
+		    ) {
+			u8 RSNIe = IE_WPA;
 
-			if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
-                (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
-			{
+			if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
+			    || (pAd->StaCfg.AuthMode ==
+				Ndis802_11AuthModeWPA2)) {
 				RSNIe = IE_WPA2;
 			}
 
-			if (pAd->StaCfg.WpaSupplicantUP != 1)
-            RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
+			if ((pAd->StaCfg.WpaSupplicantUP !=
+			     WPA_SUPPLICANT_ENABLE)
+			    && (pAd->StaCfg.bRSN_IE_FromWpaSupplicant == FALSE))
+				RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode,
+					      pAd->StaCfg.WepStatus, BSS0);
 
-            // Check for WPA PMK cache list
-			if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
-			{
-			    INT     idx;
-                BOOLEAN FoundPMK = FALSE;
-				// Search chched PMKID, append it if existed
-				for (idx = 0; idx < PMKID_NO; idx++)
-				{
-					if (NdisEqualMemory(ApAddr, &pAd->StaCfg.SavedPMK[idx].BSSID, 6))
-					{
+			/* Check for WPA PMK cache list */
+			if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) {
+				int idx;
+				BOOLEAN FoundPMK = FALSE;
+				/* Search chched PMKID, append it if existed */
+				for (idx = 0; idx < PMKID_NO; idx++) {
+					if (NdisEqualMemory
+					    (ApAddr,
+					     &pAd->StaCfg.SavedPMK[idx].BSSID,
+					     6)) {
 						FoundPMK = TRUE;
 						break;
 					}
 				}
-
-				if (FoundPMK)
-				{
-					// Set PMK number
-					*(PUSHORT) &pAd->StaCfg.RSN_IE[pAd->StaCfg.RSNIE_Len] = 1;
-					NdisMoveMemory(&pAd->StaCfg.RSN_IE[pAd->StaCfg.RSNIE_Len + 2], &pAd->StaCfg.SavedPMK[idx].PMKID, 16);
-                    pAd->StaCfg.RSNIE_Len += 18;
+				if (FoundPMK) {
+					/* Set PMK number */
+					*(u16 *)& pAd->StaCfg.RSN_IE[pAd->
+									StaCfg.
+									RSNIE_Len]
+					    = 1;
+					NdisMoveMemory(&pAd->StaCfg.
+						       RSN_IE[pAd->StaCfg.
+							      RSNIE_Len + 2],
+						       &pAd->StaCfg.
+						       SavedPMK[idx].PMKID, 16);
+					pAd->StaCfg.RSNIE_Len += 18;
 				}
 			}
 
-			if (pAd->StaCfg.WpaSupplicantUP == 1)
-			{
-				MakeOutgoingFrame(pOutBuffer + FrameLen,    		&tmp,
-		                        	pAd->StaCfg.RSNIE_Len,			pAd->StaCfg.RSN_IE,
-		                        	END_OF_ARGS);
-			}
-			else
-			{
-				MakeOutgoingFrame(pOutBuffer + FrameLen,    		&tmp,
-				              		1,                              &RSNIe,
-		                        	1,                              &pAd->StaCfg.RSNIE_Len,
-		                        	pAd->StaCfg.RSNIE_Len,			pAd->StaCfg.RSN_IE,
-		                        	END_OF_ARGS);
+			if ((pAd->StaCfg.WpaSupplicantUP ==
+			     WPA_SUPPLICANT_ENABLE)
+			    && (pAd->StaCfg.bRSN_IE_FromWpaSupplicant ==
+				TRUE)) {
+				MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+						  pAd->StaCfg.RSNIE_Len,
+						  pAd->StaCfg.RSN_IE,
+						  END_OF_ARGS);
+			} else {
+				MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+						  1, &RSNIe,
+						  1, &pAd->StaCfg.RSNIE_Len,
+						  pAd->StaCfg.RSNIE_Len,
+						  pAd->StaCfg.RSN_IE,
+						  END_OF_ARGS);
 			}
 
 			FrameLen += tmp;
 
-			if (pAd->StaCfg.WpaSupplicantUP != 1)
-			{
-	            // Append Variable IE
-	            NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &RSNIe, 1);
-	            VarIesOffset += 1;
-	            NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->StaCfg.RSNIE_Len, 1);
-	            VarIesOffset += 1;
+			if ((pAd->StaCfg.WpaSupplicantUP !=
+			     WPA_SUPPLICANT_ENABLE)
+			    || (pAd->StaCfg.bRSN_IE_FromWpaSupplicant ==
+				FALSE)) {
+				/* Append Variable IE */
+				NdisMoveMemory(pAd->StaCfg.ReqVarIEs +
+					       VarIesOffset, &RSNIe, 1);
+				VarIesOffset += 1;
+				NdisMoveMemory(pAd->StaCfg.ReqVarIEs +
+					       VarIesOffset,
+					       &pAd->StaCfg.RSNIE_Len, 1);
+				VarIesOffset += 1;
 			}
-			NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
+			NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset,
+				       pAd->StaCfg.RSN_IE,
+				       pAd->StaCfg.RSNIE_Len);
 			VarIesOffset += pAd->StaCfg.RSNIE_Len;
 
-			// Set Variable IEs Length
+			/* Set Variable IEs Length */
 			pAd->StaCfg.ReqVarIELen = VarIesOffset;
 		}
 
-		// We have update that at PeerBeaconAtJoinRequest()
-		CkipFlag = pAd->StaCfg.CkipFlag;
-		if (CkipFlag != 0)
-		{
-			NdisZeroMemory(CkipNegotiationBuffer, CKIP_NEGOTIATION_LENGTH);
-			CkipNegotiationBuffer[2] = 0x66;
-			// Make it try KP & MIC, since we have to follow the result from AssocRsp
-			CkipNegotiationBuffer[8] = 0x18;
-			CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH - 1] = 0x22;
-			CkipFlag = 0x18;
-
-			MakeOutgoingFrame(pOutBuffer + FrameLen, 	&tmp,
-						1,						  		&AironetCkipIe,
-						1,						  		&AironetCkipLen,
-						AironetCkipLen, 		  		CkipNegotiationBuffer,
-						END_OF_ARGS);
-			FrameLen += tmp;
-		}
-
-		// Add CCX v2 request if CCX2 admin state is on
-		if (pAd->StaCfg.CCXControl.field.Enable == 1)
-		{
-
-			//
-			// Add AironetIPAddressIE for Cisco CCX 2.X
-			// Add CCX Version
-			//
-			MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
-						1,							&AironetIPAddressIE,
-						1,							&AironetIPAddressLen,
-						AironetIPAddressLen,		AironetIPAddressBuffer,
-						1,							&Ccx2Ie,
-						1,							&Ccx2Len,
-						Ccx2Len,				    Ccx2IeInfo,
-						END_OF_ARGS);
-			FrameLen += tmp;
-
-			// Add by James 03/06/27
-			// Set Variable IEs Length
-			pAd->StaCfg.ReqVarIELen = VarIesOffset;
-			pAd->StaCfg.AssocInfo.RequestIELength = VarIesOffset;
-
-			// OffsetResponseIEs follow ReqVarIE
-			pAd->StaCfg.AssocInfo.OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAd->StaCfg.ReqVarIELen;
-			// End Add by James
-		}
-
-
 		MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
 		MlmeFreeMemory(pAd, pOutBuffer);
 
 		RTMPSetTimer(&pAd->MlmeAux.AssocTimer, Timeout);
 		pAd->Mlme.AssocMachine.CurrState = ASSOC_WAIT_RSP;
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeAssocReqAction() sanity check failed. BUG!!!!!! \n"));
+	} else {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("ASSOC - MlmeAssocReqAction() sanity check failed. BUG!\n"));
 		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
 		Status = MLME_INVALID_FORMAT;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
+		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2,
+			    &Status);
 	}
 
 }
@@ -594,187 +589,168 @@
 
 	==========================================================================
  */
-VOID MlmeReassocReqAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void MlmeReassocReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	UCHAR			ApAddr[6];
-	HEADER_802_11	ReassocHdr;
-	UCHAR			Ccx2Len = 5;
-	UCHAR			WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
-	USHORT			CapabilityInfo, ListenIntv;
-	ULONG			Timeout;
-	ULONG			FrameLen = 0;
-	BOOLEAN			TimerCancelled;
-	NDIS_STATUS		NStatus;
-	ULONG			tmp;
-	PUCHAR			pOutBuffer = NULL;
-	USHORT			Status;
+	u8 ApAddr[6];
+	struct rt_header_802_11 ReassocHdr;
+	u8 WmeIe[9] =
+	    { IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01,
+       0x00 };
+	u16 CapabilityInfo, ListenIntv;
+	unsigned long Timeout;
+	unsigned long FrameLen = 0;
+	BOOLEAN TimerCancelled;
+	int NStatus;
+	unsigned long tmp;
+	u8 *pOutBuffer = NULL;
+	u16 Status;
 
-	// Block all authentication request durning WPA block period
-	if (pAd->StaCfg.bBlockAssoc == TRUE)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Block ReAssoc request durning WPA block period!\n"));
+	/* Block all authentication request durning WPA block period */
+	if (pAd->StaCfg.bBlockAssoc == TRUE) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("ASSOC - Block ReAssoc request durning WPA block period!\n"));
 		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
 		Status = MLME_STATE_MACHINE_REJECT;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2,
+			    &Status);
 	}
-	// the parameters are the same as the association
-	else if(MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, &Timeout, &ListenIntv))
-	{
+	/* the parameters are the same as the association */
+	else if (MlmeAssocReqSanity
+		 (pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo,
+		  &Timeout, &ListenIntv)) {
 		RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &TimerCancelled);
 
-		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-		if(NStatus != NDIS_STATUS_SUCCESS)
-		{
-			DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeReassocReqAction() allocate memory failed \n"));
+		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
+		if (NStatus != NDIS_STATUS_SUCCESS) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("ASSOC - MlmeReassocReqAction() allocate memory failed \n"));
 			pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
 			Status = MLME_FAIL_NO_RESOURCE;
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE,
+				    MT2_REASSOC_CONF, 2, &Status);
 			return;
 		}
 
 		COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr);
 
-		// make frame, use bssid as the AP address??
-		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send RE-ASSOC request...\n"));
-		MgtMacHeaderInit(pAd, &ReassocHdr, SUBTYPE_REASSOC_REQ, 0, ApAddr, ApAddr);
-		MakeOutgoingFrame(pOutBuffer,               &FrameLen,
-						  sizeof(HEADER_802_11),    &ReassocHdr,
-						  2,                        &CapabilityInfo,
-						  2,                        &ListenIntv,
-						  MAC_ADDR_LEN,             ApAddr,
-						  1,                        &SsidIe,
-						  1,                        &pAd->MlmeAux.SsidLen,
-						  pAd->MlmeAux.SsidLen,     pAd->MlmeAux.Ssid,
-						  1,                        &SupRateIe,
-						  1,						&pAd->MlmeAux.SupRateLen,
-						  pAd->MlmeAux.SupRateLen,  pAd->MlmeAux.SupRate,
-						  END_OF_ARGS);
+		/* make frame, use bssid as the AP address?? */
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("ASSOC - Send RE-ASSOC request...\n"));
+		MgtMacHeaderInit(pAd, &ReassocHdr, SUBTYPE_REASSOC_REQ, 0,
+				 ApAddr, ApAddr);
+		MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(struct rt_header_802_11),
+				  &ReassocHdr, 2, &CapabilityInfo, 2,
+				  &ListenIntv, MAC_ADDR_LEN, ApAddr, 1, &SsidIe,
+				  1, &pAd->MlmeAux.SsidLen,
+				  pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid, 1,
+				  &SupRateIe, 1, &pAd->MlmeAux.SupRateLen,
+				  pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
+				  END_OF_ARGS);
 
-		if (pAd->MlmeAux.ExtRateLen != 0)
-		{
-			MakeOutgoingFrame(pOutBuffer + FrameLen,        &tmp,
-							  1,                            &ExtRateIe,
-							  1,                            &pAd->MlmeAux.ExtRateLen,
-							  pAd->MlmeAux.ExtRateLen,	    pAd->MlmeAux.ExtRate,
-							  END_OF_ARGS);
+		if (pAd->MlmeAux.ExtRateLen != 0) {
+			MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+					  1, &ExtRateIe,
+					  1, &pAd->MlmeAux.ExtRateLen,
+					  pAd->MlmeAux.ExtRateLen,
+					  pAd->MlmeAux.ExtRate, END_OF_ARGS);
 			FrameLen += tmp;
 		}
 
-		if (pAd->MlmeAux.APEdcaParm.bValid)
-		{
-			if (pAd->CommonCfg.bAPSDCapable && pAd->MlmeAux.APEdcaParm.bAPSDCapable)
-			{
-				QBSS_STA_INFO_PARM QosInfo;
+		if (pAd->MlmeAux.APEdcaParm.bValid) {
+			if (pAd->CommonCfg.bAPSDCapable
+			    && pAd->MlmeAux.APEdcaParm.bAPSDCapable) {
+				struct rt_qbss_sta_info_parm QosInfo;
 
-				NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM));
+				NdisZeroMemory(&QosInfo,
+					       sizeof(struct rt_qbss_sta_info_parm));
 				QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE;
 				QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK;
 				QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI;
 				QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO;
-				QosInfo.MaxSPLength = pAd->CommonCfg.MaxSPLength;
-				WmeIe[8] |= *(PUCHAR)&QosInfo;
+				QosInfo.MaxSPLength =
+				    pAd->CommonCfg.MaxSPLength;
+				WmeIe[8] |= *(u8 *)& QosInfo;
 			}
 
-			MakeOutgoingFrame(pOutBuffer + FrameLen,    &tmp,
-							  9,                        &WmeIe[0],
-							  END_OF_ARGS);
-			FrameLen += tmp;
-		}
-
-		// HT
-		if ((pAd->MlmeAux.HtCapabilityLen > 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
-		{
-			ULONG TmpLen;
-			UCHAR HtLen;
-			UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
-			if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE)
-			{
-				HtLen = SIZE_HT_CAP_IE + 4;
-				MakeOutgoingFrame(pOutBuffer + FrameLen,            &TmpLen,
-							  1,                                &WpaIe,
-							  1,                                &HtLen,
-							  4,                                &BROADCOM[0],
-							 pAd->MlmeAux.HtCapabilityLen,          &pAd->MlmeAux.HtCapability,
-							  END_OF_ARGS);
-			}
-			else
-			{
-				MakeOutgoingFrame(pOutBuffer + FrameLen,            &TmpLen,
-							  1,                                &HtCapIe,
-							  1,                                &pAd->MlmeAux.HtCapabilityLen,
-							 pAd->MlmeAux.HtCapabilityLen,          &pAd->MlmeAux.HtCapability,
-							  END_OF_ARGS);
-			}
-			FrameLen += TmpLen;
-		}
-
-		// add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION
-		// Case I: (Aggregation + Piggy-Back)
-		// 1. user enable aggregation, AND
-		// 2. Mac support piggy-back
-		// 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON
-		// Case II: (Aggregation)
-		// 1. user enable aggregation, AND
-		// 2. AP annouces it's AGGREGATION-capable in BEACON
-		if (pAd->CommonCfg.bAggregationCapable)
-		{
-			if ((pAd->CommonCfg.bPiggyBackCapable) && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3))
-			{
-				ULONG TmpLen;
-				UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x03, 0x00, 0x00, 0x00};
-				MakeOutgoingFrame(pOutBuffer+FrameLen,           &TmpLen,
-								  9,                             RalinkIe,
-								  END_OF_ARGS);
-				FrameLen += TmpLen;
-			}
-			else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
-			{
-				ULONG TmpLen;
-				UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00};
-				MakeOutgoingFrame(pOutBuffer+FrameLen,           &TmpLen,
-								  9,                             RalinkIe,
-								  END_OF_ARGS);
-				FrameLen += TmpLen;
-			}
-		}
-		else
-		{
-			ULONG TmpLen;
-			UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x04, 0x00, 0x00, 0x00};
-			MakeOutgoingFrame(pOutBuffer+FrameLen,		 &TmpLen,
-							  9,						 RalinkIe,
-							  END_OF_ARGS);
-			FrameLen += TmpLen;
-		}
-
-		// Add CCX v2 request if CCX2 admin state is on
-		if (pAd->StaCfg.CCXControl.field.Enable == 1)
-		{
-			//
-			// Add CCX Version
-			//
 			MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
-						1,							&Ccx2Ie,
-						1,							&Ccx2Len,
-						Ccx2Len,				    Ccx2IeInfo,
-						END_OF_ARGS);
+					  9, &WmeIe[0], END_OF_ARGS);
 			FrameLen += tmp;
 		}
+		/* HT */
+		if ((pAd->MlmeAux.HtCapabilityLen > 0)
+		    && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) {
+			unsigned long TmpLen;
+			u8 HtLen;
+			u8 BROADCOM[4] = { 0x0, 0x90, 0x4c, 0x33 };
+			if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE) {
+				HtLen = SIZE_HT_CAP_IE + 4;
+				MakeOutgoingFrame(pOutBuffer + FrameLen,
+						  &TmpLen, 1, &WpaIe, 1, &HtLen,
+						  4, &BROADCOM[0],
+						  pAd->MlmeAux.HtCapabilityLen,
+						  &pAd->MlmeAux.HtCapability,
+						  END_OF_ARGS);
+			} else {
+				MakeOutgoingFrame(pOutBuffer + FrameLen,
+						  &TmpLen, 1, &HtCapIe, 1,
+						  &pAd->MlmeAux.HtCapabilityLen,
+						  pAd->MlmeAux.HtCapabilityLen,
+						  &pAd->MlmeAux.HtCapability,
+						  END_OF_ARGS);
+			}
+			FrameLen += TmpLen;
+		}
+		/* add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION */
+		/* Case I: (Aggregation + Piggy-Back) */
+		/* 1. user enable aggregation, AND */
+		/* 2. Mac support piggy-back */
+		/* 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON */
+		/* Case II: (Aggregation) */
+		/* 1. user enable aggregation, AND */
+		/* 2. AP annouces it's AGGREGATION-capable in BEACON */
+		if (pAd->CommonCfg.bAggregationCapable) {
+			if ((pAd->CommonCfg.bPiggyBackCapable)
+			    && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)) {
+				unsigned long TmpLen;
+				u8 RalinkIe[9] =
+				    { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43,
+			    0x03, 0x00, 0x00, 0x00 };
+				MakeOutgoingFrame(pOutBuffer + FrameLen,
+						  &TmpLen, 9, RalinkIe,
+						  END_OF_ARGS);
+				FrameLen += TmpLen;
+			} else if (pAd->MlmeAux.APRalinkIe & 0x00000001) {
+				unsigned long TmpLen;
+				u8 RalinkIe[9] =
+				    { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43,
+			    0x01, 0x00, 0x00, 0x00 };
+				MakeOutgoingFrame(pOutBuffer + FrameLen,
+						  &TmpLen, 9, RalinkIe,
+						  END_OF_ARGS);
+				FrameLen += TmpLen;
+			}
+		} else {
+			unsigned long TmpLen;
+			u8 RalinkIe[9] =
+			    { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x04,
+		    0x00, 0x00, 0x00 };
+			MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 9,
+					  RalinkIe, END_OF_ARGS);
+			FrameLen += TmpLen;
+		}
 
 		MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
 		MlmeFreeMemory(pAd, pOutBuffer);
 
-		RTMPSetTimer(&pAd->MlmeAux.ReassocTimer, Timeout); /* in mSec */
+		RTMPSetTimer(&pAd->MlmeAux.ReassocTimer, Timeout);	/* in mSec */
 		pAd->Mlme.AssocMachine.CurrState = REASSOC_WAIT_RSP;
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeReassocReqAction() sanity check failed. BUG!!!! \n"));
+	} else {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("ASSOC - MlmeReassocReqAction() sanity check failed. BUG!\n"));
 		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
 		Status = MLME_INVALID_FORMAT;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2,
+			    &Status);
 	}
 }
 
@@ -789,51 +765,50 @@
 
 	==========================================================================
  */
-VOID MlmeDisassocReqAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void MlmeDisassocReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	PMLME_DISASSOC_REQ_STRUCT pDisassocReq;
-	HEADER_802_11         DisassocHdr;
-	PHEADER_802_11        pDisassocHdr;
-	PUCHAR                pOutBuffer = NULL;
-	ULONG                 FrameLen = 0;
-	NDIS_STATUS           NStatus;
-	BOOLEAN               TimerCancelled;
-	ULONG                 Timeout = 0;
-	USHORT                Status;
+	struct rt_mlme_disassoc_req *pDisassocReq;
+	struct rt_header_802_11 DisassocHdr;
+	struct rt_header_802_11 * pDisassocHdr;
+	u8 *pOutBuffer = NULL;
+	unsigned long FrameLen = 0;
+	int NStatus;
+	BOOLEAN TimerCancelled;
+	unsigned long Timeout = 500;
+	u16 Status;
 
-	// skip sanity check
-	pDisassocReq = (PMLME_DISASSOC_REQ_STRUCT)(Elem->Msg);
+	/* skip sanity check */
+	pDisassocReq = (struct rt_mlme_disassoc_req *)(Elem->Msg);
 
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-	if (NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - MlmeDisassocReqAction() allocate memory failed\n"));
+	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
+	if (NStatus != NDIS_STATUS_SUCCESS) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("ASSOC - MlmeDisassocReqAction() allocate memory failed\n"));
 		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
 		Status = MLME_FAIL_NO_RESOURCE;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
+		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2,
+			    &Status);
 		return;
 	}
 
-
-
 	RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &TimerCancelled);
 
-	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send DISASSOC request[BSSID::%02x:%02x:%02x:%02x:%02x:%02x (Reason=%d)\n",
-				pDisassocReq->Addr[0], pDisassocReq->Addr[1], pDisassocReq->Addr[2],
-				pDisassocReq->Addr[3], pDisassocReq->Addr[4], pDisassocReq->Addr[5], pDisassocReq->Reason));
-	MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pDisassocReq->Addr, pDisassocReq->Addr);	// patch peap ttls switching issue
-	MakeOutgoingFrame(pOutBuffer,           &FrameLen,
-					  sizeof(HEADER_802_11),&DisassocHdr,
-					  2,                    &pDisassocReq->Reason,
-					  END_OF_ARGS);
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("ASSOC - Send DISASSOC request[BSSID::%02x:%02x:%02x:%02x:%02x:%02x (Reason=%d)\n",
+		  pDisassocReq->Addr[0], pDisassocReq->Addr[1],
+		  pDisassocReq->Addr[2], pDisassocReq->Addr[3],
+		  pDisassocReq->Addr[4], pDisassocReq->Addr[5],
+		  pDisassocReq->Reason));
+	MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pDisassocReq->Addr, pDisassocReq->Addr);	/* patch peap ttls switching issue */
+	MakeOutgoingFrame(pOutBuffer, &FrameLen,
+			  sizeof(struct rt_header_802_11), &DisassocHdr,
+			  2, &pDisassocReq->Reason, END_OF_ARGS);
 	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
 
-	// To patch Instance and Buffalo(N) AP
-	// Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine
-	// Therefore, we send both of them.
-	pDisassocHdr = (PHEADER_802_11)pOutBuffer;
+	/* To patch Instance and Buffalo(N) AP */
+	/* Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine */
+	/* Therefore, we send both of them. */
+	pDisassocHdr = (struct rt_header_802_11 *) pOutBuffer;
 	pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH;
 	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
 
@@ -842,14 +817,11 @@
 	pAd->StaCfg.DisassocReason = REASON_DISASSOC_STA_LEAVING;
 	COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pDisassocReq->Addr);
 
-	RTMPSetTimer(&pAd->MlmeAux.DisassocTimer, Timeout); /* in mSec */
+	RTMPSetTimer(&pAd->MlmeAux.DisassocTimer, Timeout);	/* in mSec */
 	pAd->Mlme.AssocMachine.CurrState = DISASSOC_WAIT_RSP;
 
-    {
-        union iwreq_data    wrqu;
-        memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
-        wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
-    }
+	RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0);
+
 }
 
 /*
@@ -863,94 +835,81 @@
 
 	==========================================================================
  */
-VOID PeerAssocRspAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void PeerAssocRspAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	USHORT        CapabilityInfo, Status, Aid;
-	UCHAR         SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
-	UCHAR         ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
-	UCHAR         Addr2[MAC_ADDR_LEN];
-	BOOLEAN       TimerCancelled;
-	UCHAR         CkipFlag;
-	EDCA_PARM     EdcaParm;
-	HT_CAPABILITY_IE		HtCapability;
-	ADD_HT_INFO_IE		AddHtInfo;	// AP might use this additional ht info IE
-	UCHAR			HtCapabilityLen;
-	UCHAR			AddHtInfoLen;
-	UCHAR			NewExtChannelOffset = 0xff;
+	u16 CapabilityInfo, Status, Aid;
+	u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
+	u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
+	u8 Addr2[MAC_ADDR_LEN];
+	BOOLEAN TimerCancelled;
+	u8 CkipFlag;
+	struct rt_edca_parm EdcaParm;
+	struct rt_ht_capability_ie HtCapability;
+	struct rt_add_ht_info_ie AddHtInfo;	/* AP might use this additional ht info IE */
+	u8 HtCapabilityLen = 0;
+	u8 AddHtInfoLen;
+	u8 NewExtChannelOffset = 0xff;
 
-	if (PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen,
-		&HtCapability,&AddHtInfo, &HtCapabilityLen,&AddHtInfoLen,&NewExtChannelOffset, &EdcaParm, &CkipFlag))
-	{
-		// The frame is for me ?
-		if(MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspAction():ASSOC - receive ASSOC_RSP to me (status=%d)\n", Status));
-			DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspAction():MacTable [%d].AMsduSize = %d. ClientStatusFlags = 0x%lx \n",Elem->Wcid, pAd->MacTab.Content[BSSID_WCID].AMsduSize, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
-			RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &TimerCancelled);
-			if(Status == MLME_SUCCESS)
-			{
-#ifdef RT2860
-				// go to procedure listed on page 376
-				AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen,
-					&EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo);
+	if (PeerAssocRspSanity
+	    (pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status,
+	     &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen, &HtCapability,
+	     &AddHtInfo, &HtCapabilityLen, &AddHtInfoLen, &NewExtChannelOffset,
+	     &EdcaParm, &CkipFlag)) {
+		/* The frame is for me ? */
+		if (MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid)) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("PeerAssocRspAction():ASSOC - receive ASSOC_RSP to me (status=%d)\n",
+				  Status));
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("PeerAssocRspAction():MacTable [%d].AMsduSize = %d. ClientStatusFlags = 0x%lx \n",
+				  Elem->Wcid,
+				  pAd->MacTab.Content[BSSID_WCID].AMsduSize,
+				  pAd->MacTab.Content[BSSID_WCID].
+				  ClientStatusFlags));
+			RTMPCancelTimer(&pAd->MlmeAux.AssocTimer,
+					&TimerCancelled);
 
-                {
-                    union iwreq_data    wrqu;
-                    wext_notify_event_assoc(pAd);
+			if (Status == MLME_SUCCESS) {
+				u8 MaxSupportedRateIn500Kbps = 0;
+				u8 idx;
 
-                    memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
-                    memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
-                    wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
-
-                }
-#endif
-#ifdef RT2870
-				UCHAR			MaxSupportedRateIn500Kbps = 0;
-				UCHAR			idx;
-
-				// supported rates array may not be sorted. sort it and find the maximum rate
-			    for (idx=0; idx<SupRateLen; idx++)
-                {
-			        if (MaxSupportedRateIn500Kbps < (SupRate[idx] & 0x7f))
-			            MaxSupportedRateIn500Kbps = SupRate[idx] & 0x7f;
-			    }
-
-				for (idx=0; idx<ExtRateLen; idx++)
-			    {
-			        if (MaxSupportedRateIn500Kbps < (ExtRate[idx] & 0x7f))
-			            MaxSupportedRateIn500Kbps = ExtRate[idx] & 0x7f;
-                }
-				// go to procedure listed on page 376
-				AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen,
-					&EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo);
-
-				StaAddMacTableEntry(pAd, &pAd->MacTab.Content[BSSID_WCID], MaxSupportedRateIn500Kbps, &HtCapability, HtCapabilityLen, CapabilityInfo);
-#endif
-				pAd->StaCfg.CkipFlag = CkipFlag;
-				if (CkipFlag & 0x18)
-				{
-					NdisZeroMemory(pAd->StaCfg.TxSEQ, 4);
-					NdisZeroMemory(pAd->StaCfg.RxSEQ, 4);
-					NdisZeroMemory(pAd->StaCfg.CKIPMIC, 4);
-					pAd->StaCfg.GIV[0] = RandomByte(pAd);
-					pAd->StaCfg.GIV[1] = RandomByte(pAd);
-					pAd->StaCfg.GIV[2] = RandomByte(pAd);
-					pAd->StaCfg.bCkipOn = TRUE;
-					DBGPRINT(RT_DEBUG_TRACE, ("<CCX> pAd->StaCfg.CkipFlag = 0x%02x\n", pAd->StaCfg.CkipFlag));
+				/* supported rates array may not be sorted. sort it and find the maximum rate */
+				for (idx = 0; idx < SupRateLen; idx++) {
+					if (MaxSupportedRateIn500Kbps <
+					    (SupRate[idx] & 0x7f))
+						MaxSupportedRateIn500Kbps =
+						    SupRate[idx] & 0x7f;
 				}
-			}
-			else
-			{
+
+				for (idx = 0; idx < ExtRateLen; idx++) {
+					if (MaxSupportedRateIn500Kbps <
+					    (ExtRate[idx] & 0x7f))
+						MaxSupportedRateIn500Kbps =
+						    ExtRate[idx] & 0x7f;
+				}
+				/* go to procedure listed on page 376 */
+				AssocPostProc(pAd, Addr2, CapabilityInfo, Aid,
+					      SupRate, SupRateLen, ExtRate,
+					      ExtRateLen, &EdcaParm,
+					      &HtCapability, HtCapabilityLen,
+					      &AddHtInfo);
+
+				StaAddMacTableEntry(pAd,
+						    &pAd->MacTab.
+						    Content[BSSID_WCID],
+						    MaxSupportedRateIn500Kbps,
+						    &HtCapability,
+						    HtCapabilityLen, &AddHtInfo,
+						    AddHtInfoLen,
+						    CapabilityInfo);
 			}
 			pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
+			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE,
+				    MT2_ASSOC_CONF, 2, &Status);
 		}
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerAssocRspAction() sanity check fail\n"));
+	} else {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("ASSOC - PeerAssocRspAction() sanity check fail\n"));
 	}
 }
 
@@ -965,61 +924,62 @@
 
 	==========================================================================
  */
-VOID PeerReassocRspAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void PeerReassocRspAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	USHORT      CapabilityInfo;
-	USHORT      Status;
-	USHORT      Aid;
-	UCHAR       SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
-	UCHAR       ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
-	UCHAR       Addr2[MAC_ADDR_LEN];
-	UCHAR       CkipFlag;
-	BOOLEAN     TimerCancelled;
-	EDCA_PARM   EdcaParm;
-	HT_CAPABILITY_IE		HtCapability;
-	ADD_HT_INFO_IE		AddHtInfo;	// AP might use this additional ht info IE
-	UCHAR			HtCapabilityLen;
-	UCHAR			AddHtInfoLen;
-	UCHAR			NewExtChannelOffset = 0xff;
+	u16 CapabilityInfo;
+	u16 Status;
+	u16 Aid;
+	u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
+	u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
+	u8 Addr2[MAC_ADDR_LEN];
+	u8 CkipFlag;
+	BOOLEAN TimerCancelled;
+	struct rt_edca_parm EdcaParm;
+	struct rt_ht_capability_ie HtCapability;
+	struct rt_add_ht_info_ie AddHtInfo;	/* AP might use this additional ht info IE */
+	u8 HtCapabilityLen;
+	u8 AddHtInfoLen;
+	u8 NewExtChannelOffset = 0xff;
 
-	if(PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen,
-								&HtCapability,	&AddHtInfo, &HtCapabilityLen, &AddHtInfoLen,&NewExtChannelOffset, &EdcaParm, &CkipFlag))
-	{
-		if(MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid)) // The frame is for me ?
+	if (PeerAssocRspSanity
+	    (pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status,
+	     &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen, &HtCapability,
+	     &AddHtInfo, &HtCapabilityLen, &AddHtInfoLen, &NewExtChannelOffset,
+	     &EdcaParm, &CkipFlag)) {
+		if (MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid))	/* The frame is for me ? */
 		{
-			DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - receive REASSOC_RSP to me (status=%d)\n", Status));
-			RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &TimerCancelled);
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("ASSOC - receive REASSOC_RSP to me (status=%d)\n",
+				  Status));
+			RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer,
+					&TimerCancelled);
 
-			if(Status == MLME_SUCCESS)
-			{
-				// go to procedure listed on page 376
-				AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen,
-					 &EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo);
+			if (Status == MLME_SUCCESS) {
+				/* go to procedure listed on page 376 */
+				AssocPostProc(pAd, Addr2, CapabilityInfo, Aid,
+					      SupRate, SupRateLen, ExtRate,
+					      ExtRateLen, &EdcaParm,
+					      &HtCapability, HtCapabilityLen,
+					      &AddHtInfo);
 
-                {
-                    union iwreq_data    wrqu;
-                    wext_notify_event_assoc(pAd);
-
-                    memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
-                    memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
-                    wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
-
-                }
+				{
+					wext_notify_event_assoc(pAd);
+					RtmpOSWrielessEventSend(pAd, SIOCGIWAP,
+								-1,
+								&pAd->MlmeAux.
+								Bssid[0], NULL,
+								0);
+				}
 
 			}
-
-			{
-				// CkipFlag is no use for reassociate
-				pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-				MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
-			}
+			/* CkipFlag is no use for reassociate */
+			pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE,
+				    MT2_REASSOC_CONF, 2, &Status);
 		}
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerReassocRspAction() sanity check fail\n"));
+	} else {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("ASSOC - PeerReassocRspAction() sanity check fail\n"));
 	}
 
 }
@@ -1034,30 +994,18 @@
 
 	==========================================================================
  */
-VOID AssocPostProc(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pAddr2,
-	IN USHORT CapabilityInfo,
-	IN USHORT Aid,
-	IN UCHAR SupRate[],
-	IN UCHAR SupRateLen,
-	IN UCHAR ExtRate[],
-	IN UCHAR ExtRateLen,
-	IN PEDCA_PARM pEdcaParm,
-	IN HT_CAPABILITY_IE		*pHtCapability,
-	IN UCHAR HtCapabilityLen,
-	IN ADD_HT_INFO_IE		*pAddHtInfo)	// AP might use this additional ht info IE
+void AssocPostProc(struct rt_rtmp_adapter *pAd, u8 *pAddr2, u16 CapabilityInfo, u16 Aid, u8 SupRate[], u8 SupRateLen, u8 ExtRate[], u8 ExtRateLen, struct rt_edca_parm *pEdcaParm, struct rt_ht_capability_ie * pHtCapability, u8 HtCapabilityLen, struct rt_add_ht_info_ie * pAddHtInfo)	/* AP might use this additional ht info IE */
 {
-	ULONG Idx;
+	unsigned long Idx;
 
 	pAd->MlmeAux.BssType = BSS_INFRA;
 	COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pAddr2);
 	pAd->MlmeAux.Aid = Aid;
-	pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
+	pAd->MlmeAux.CapabilityInfo =
+	    CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
 
-	// Some HT AP might lost WMM IE. We add WMM ourselves. beacuase HT requires QoS on.
-	if ((HtCapabilityLen > 0) && (pEdcaParm->bValid == FALSE))
-	{
+	/* Some HT AP might lost WMM IE. We add WMM ourselves. beacuase HT requires QoS on. */
+	if ((HtCapabilityLen > 0) && (pEdcaParm->bValid == FALSE)) {
 		pEdcaParm->bValid = TRUE;
 		pEdcaParm->Aifsn[0] = 3;
 		pEdcaParm->Aifsn[1] = 7;
@@ -1074,88 +1022,113 @@
 		pEdcaParm->Cwmax[2] = 4;
 		pEdcaParm->Cwmax[3] = 3;
 
-		pEdcaParm->Txop[0]  = 0;
-		pEdcaParm->Txop[1]  = 0;
-		pEdcaParm->Txop[2]  = 96;
-		pEdcaParm->Txop[3]  = 48;
+		pEdcaParm->Txop[0] = 0;
+		pEdcaParm->Txop[1] = 0;
+		pEdcaParm->Txop[2] = 96;
+		pEdcaParm->Txop[3] = 48;
 
 	}
 
-	NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
+	NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, pEdcaParm, sizeof(struct rt_edca_parm));
 
-	// filter out un-supported rates
+	/* filter out un-supported rates */
 	pAd->MlmeAux.SupRateLen = SupRateLen;
 	NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen);
 	RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
 
-	// filter out un-supported rates
+	/* filter out un-supported rates */
 	pAd->MlmeAux.ExtRateLen = ExtRateLen;
 	NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen);
 	RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
 
-	if (HtCapabilityLen > 0)
-	{
+	if (HtCapabilityLen > 0) {
 		RTMPCheckHt(pAd, BSSID_WCID, pHtCapability, pAddHtInfo);
 	}
-	DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===>  AP.AMsduSize = %d. ClientStatusFlags = 0x%lx \n", pAd->MacTab.Content[BSSID_WCID].AMsduSize, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("AssocPostProc===>  AP.AMsduSize = %d. ClientStatusFlags = 0x%lx \n",
+		  pAd->MacTab.Content[BSSID_WCID].AMsduSize,
+		  pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
 
-	DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===>    (Mmps=%d, AmsduSize=%d, )\n",
-		pAd->MacTab.Content[BSSID_WCID].MmpsMode, pAd->MacTab.Content[BSSID_WCID].AMsduSize));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("AssocPostProc===>    (Mmps=%d, AmsduSize=%d, )\n",
+		  pAd->MacTab.Content[BSSID_WCID].MmpsMode,
+		  pAd->MacTab.Content[BSSID_WCID].AMsduSize));
 
-	// Set New WPA information
+	/* Set New WPA information */
 	Idx = BssTableSearch(&pAd->ScanTab, pAddr2, pAd->MlmeAux.Channel);
-	if (Idx == BSS_NOT_FOUND)
-	{
+	if (Idx == BSS_NOT_FOUND) {
 		DBGPRINT_ERR(("ASSOC - Can't find BSS after receiving Assoc response\n"));
-	}
-	else
-	{
-		// Init variable
+	} else {
+		/* Init variable */
 		pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = 0;
-		NdisZeroMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, MAX_LEN_OF_RSNIE);
+		NdisZeroMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE,
+			       MAX_LEN_OF_RSNIE);
 
-		// Store appropriate RSN_IE for WPA SM negotiation later
-		if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAd->ScanTab.BssEntry[Idx].VarIELen != 0))
-		{
-			PUCHAR              pVIE;
-			USHORT              len;
-			PEID_STRUCT         pEid;
+		/* Store appropriate RSN_IE for WPA SM negotiation later */
+		if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+		    && (pAd->ScanTab.BssEntry[Idx].VarIELen != 0)) {
+			u8 *pVIE;
+			u16 len;
+			struct rt_eid * pEid;
 
 			pVIE = pAd->ScanTab.BssEntry[Idx].VarIEs;
-			len	 = pAd->ScanTab.BssEntry[Idx].VarIELen;
+			len = pAd->ScanTab.BssEntry[Idx].VarIELen;
+			/*KH need to check again */
+			/* Don't allow to go to sleep mode if authmode is WPA-related. */
+			/*This can make Authentication process more smoothly. */
+			RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
 
-			while (len > 0)
-			{
-				pEid = (PEID_STRUCT) pVIE;
-				// For WPA/WPAPSK
-				if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
-					&& (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
-				{
-					NdisMoveMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, pVIE, (pEid->Len + 2));
-					pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = (pEid->Len + 2);
-					DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> Store RSN_IE for WPA SM negotiation \n"));
+			while (len > 0) {
+				pEid = (struct rt_eid *) pVIE;
+				/* For WPA/WPAPSK */
+				if ((pEid->Eid == IE_WPA)
+				    &&
+				    (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
+				    && (pAd->StaCfg.AuthMode ==
+					Ndis802_11AuthModeWPA
+					|| pAd->StaCfg.AuthMode ==
+					Ndis802_11AuthModeWPAPSK)) {
+					NdisMoveMemory(pAd->MacTab.
+						       Content[BSSID_WCID].
+						       RSN_IE, pVIE,
+						       (pEid->Len + 2));
+					pAd->MacTab.Content[BSSID_WCID].
+					    RSNIE_Len = (pEid->Len + 2);
+					DBGPRINT(RT_DEBUG_TRACE,
+						 ("AssocPostProc===> Store RSN_IE for WPA SM negotiation \n"));
 				}
-				// For WPA2/WPA2PSK
-				else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
-					&& (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2 || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
-				{
-					NdisMoveMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, pVIE, (pEid->Len + 2));
-					pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = (pEid->Len + 2);
-					DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> Store RSN_IE for WPA2 SM negotiation \n"));
+				/* For WPA2/WPA2PSK */
+				else if ((pEid->Eid == IE_RSN)
+					 &&
+					 (NdisEqualMemory
+					  (pEid->Octet + 2, RSN_OUI, 3))
+					 && (pAd->StaCfg.AuthMode ==
+					     Ndis802_11AuthModeWPA2
+					     || pAd->StaCfg.AuthMode ==
+					     Ndis802_11AuthModeWPA2PSK)) {
+					NdisMoveMemory(pAd->MacTab.
+						       Content[BSSID_WCID].
+						       RSN_IE, pVIE,
+						       (pEid->Len + 2));
+					pAd->MacTab.Content[BSSID_WCID].
+					    RSNIE_Len = (pEid->Len + 2);
+					DBGPRINT(RT_DEBUG_TRACE,
+						 ("AssocPostProc===> Store RSN_IE for WPA2 SM negotiation \n"));
 				}
 
 				pVIE += (pEid->Len + 2);
-				len  -= (pEid->Len + 2);
+				len -= (pEid->Len + 2);
 			}
+
 		}
 
-		if (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == 0)
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> no RSN_IE \n"));
-		}
-		else
-		{
-			hex_dump("RSN_IE", pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len);
+		if (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == 0) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("AssocPostProc===> no RSN_IE \n"));
+		} else {
+			hex_dump("RSN_IE",
+				 pAd->MacTab.Content[BSSID_WCID].RSN_IE,
+				 pAd->MacTab.Content[BSSID_WCID].RSNIE_Len);
 		}
 	}
 }
@@ -1171,43 +1144,36 @@
 
 	==========================================================================
  */
-VOID PeerDisassocAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void PeerDisassocAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	UCHAR         Addr2[MAC_ADDR_LEN];
-	USHORT        Reason;
+	u8 Addr2[MAC_ADDR_LEN];
+	u16 Reason;
 
 	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction()\n"));
-	if(PeerDisassocSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction() Reason = %d\n", Reason));
-		if (INFRA_ON(pAd) && MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, Addr2))
-		{
+	if (PeerDisassocSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason)) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("ASSOC - PeerDisassocAction() Reason = %d\n",
+			  Reason));
+		if (INFRA_ON(pAd)
+		    && MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, Addr2)) {
 
-			if (pAd->CommonCfg.bWirelessEvent)
-			{
-				RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+			if (pAd->CommonCfg.bWirelessEvent) {
+				RTMPSendWirelessEvent(pAd,
+						      IW_DISASSOC_EVENT_FLAG,
+						      pAd->MacTab.
+						      Content[BSSID_WCID].Addr,
+						      BSS0, 0);
 			}
 
-			//
-			// Get Current System time and Turn on AdjacentAPReport
-			//
-			NdisGetSystemUpTime(&pAd->StaCfg.CCXAdjacentAPLinkDownTime);
-			pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE;
 			LinkDown(pAd, TRUE);
 			pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
 
-            {
-                union iwreq_data    wrqu;
-                memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
-                wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
-            }
+			RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL,
+						0);
 		}
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction() sanity check fail\n"));
+	} else {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("ASSOC - PeerDisassocAction() sanity check fail\n"));
 	}
 
 }
@@ -1223,11 +1189,9 @@
 
 	==========================================================================
  */
-VOID AssocTimeoutAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void AssocTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	USHORT  Status;
+	u16 Status;
 	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - AssocTimeoutAction\n"));
 	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
 	Status = MLME_REJ_TIMEOUT;
@@ -1243,11 +1207,9 @@
 
 	==========================================================================
  */
-VOID ReassocTimeoutAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void ReassocTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	USHORT  Status;
+	u16 Status;
 	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - ReassocTimeoutAction\n"));
 	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
 	Status = MLME_REJ_TIMEOUT;
@@ -1263,51 +1225,49 @@
 
 	==========================================================================
  */
-VOID DisassocTimeoutAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void DisassocTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	USHORT  Status;
+	u16 Status;
 	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - DisassocTimeoutAction\n"));
 	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
 	Status = MLME_SUCCESS;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
+	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2,
+		    &Status);
 }
 
-VOID InvalidStateWhenAssoc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void InvalidStateWhenAssoc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	USHORT  Status;
-	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenAssoc(state=%ld), reset ASSOC state machine\n",
-		pAd->Mlme.AssocMachine.CurrState));
+	u16 Status;
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("ASSOC - InvalidStateWhenAssoc(state=%ld), reset ASSOC state machine\n",
+		  pAd->Mlme.AssocMachine.CurrState));
 	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
 	Status = MLME_STATE_MACHINE_REJECT;
 	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
 }
 
-VOID InvalidStateWhenReassoc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void InvalidStateWhenReassoc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	USHORT Status;
-	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenReassoc(state=%ld), reset ASSOC state machine\n",
-		pAd->Mlme.AssocMachine.CurrState));
+	u16 Status;
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("ASSOC - InvalidStateWhenReassoc(state=%ld), reset ASSOC state machine\n",
+		  pAd->Mlme.AssocMachine.CurrState));
 	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
 	Status = MLME_STATE_MACHINE_REJECT;
 	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
 }
 
-VOID InvalidStateWhenDisassociate(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void InvalidStateWhenDisassociate(struct rt_rtmp_adapter *pAd,
+				  struct rt_mlme_queue_elem *Elem)
 {
-	USHORT Status;
-	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenDisassoc(state=%ld), reset ASSOC state machine\n",
-		pAd->Mlme.AssocMachine.CurrState));
+	u16 Status;
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("ASSOC - InvalidStateWhenDisassoc(state=%ld), reset ASSOC state machine\n",
+		  pAd->Mlme.AssocMachine.CurrState));
 	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
 	Status = MLME_STATE_MACHINE_REJECT;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
+	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2,
+		    &Status);
 }
 
 /*
@@ -1323,33 +1283,31 @@
 
 	==========================================================================
  */
-VOID Cls3errAction(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR        pAddr)
+void Cls3errAction(struct rt_rtmp_adapter *pAd, u8 *pAddr)
 {
-	HEADER_802_11         DisassocHdr;
-	PHEADER_802_11        pDisassocHdr;
-	PUCHAR                pOutBuffer = NULL;
-	ULONG                 FrameLen = 0;
-	NDIS_STATUS           NStatus;
-	USHORT                Reason = REASON_CLS3ERR;
+	struct rt_header_802_11 DisassocHdr;
+	struct rt_header_802_11 * pDisassocHdr;
+	u8 *pOutBuffer = NULL;
+	unsigned long FrameLen = 0;
+	int NStatus;
+	u16 Reason = REASON_CLS3ERR;
 
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
+	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
 	if (NStatus != NDIS_STATUS_SUCCESS)
 		return;
 
-	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Class 3 Error, Send DISASSOC frame\n"));
-	MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pAddr, pAd->CommonCfg.Bssid);	// patch peap ttls switching issue
-	MakeOutgoingFrame(pOutBuffer,           &FrameLen,
-					  sizeof(HEADER_802_11),&DisassocHdr,
-					  2,                    &Reason,
-					  END_OF_ARGS);
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("ASSOC - Class 3 Error, Send DISASSOC frame\n"));
+	MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pAddr, pAd->CommonCfg.Bssid);	/* patch peap ttls switching issue */
+	MakeOutgoingFrame(pOutBuffer, &FrameLen,
+			  sizeof(struct rt_header_802_11), &DisassocHdr,
+			  2, &Reason, END_OF_ARGS);
 	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
 
-	// To patch Instance and Buffalo(N) AP
-	// Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine
-	// Therefore, we send both of them.
-	pDisassocHdr = (PHEADER_802_11)pOutBuffer;
+	/* To patch Instance and Buffalo(N) AP */
+	/* Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine */
+	/* Therefore, we send both of them. */
+	pDisassocHdr = (struct rt_header_802_11 *) pOutBuffer;
 	pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH;
 	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
 
@@ -1359,352 +1317,271 @@
 	COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pAddr);
 }
 
- /*
-	 ==========================================================================
-	 Description:
-		 Switch between WEP and CKIP upon new association up.
-	 Parameters:
-
-	 IRQL = DISPATCH_LEVEL
-
-	 ==========================================================================
-  */
-VOID SwitchBetweenWepAndCkip(
-	IN PRTMP_ADAPTER pAd)
+int wext_notify_event_assoc(struct rt_rtmp_adapter *pAd)
 {
-	int            i;
-	SHAREDKEY_MODE_STRUC  csr1;
+	char custom[IW_CUSTOM_MAX] = { 0 };
 
-	// if KP is required. change the CipherAlg in hardware shard key table from WEP
-	// to CKIP. else remain as WEP
-	if (pAd->StaCfg.bCkipOn && (pAd->StaCfg.CkipFlag & 0x10))
-	{
-		// modify hardware key table so that MAC use correct algorithm to decrypt RX
-		RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE, &csr1.word);
-		if (csr1.field.Bss0Key0CipherAlg == CIPHER_WEP64)
-			csr1.field.Bss0Key0CipherAlg = CIPHER_CKIP64;
-		else if (csr1.field.Bss0Key0CipherAlg == CIPHER_WEP128)
-			csr1.field.Bss0Key0CipherAlg = CIPHER_CKIP128;
-
-		if (csr1.field.Bss0Key1CipherAlg == CIPHER_WEP64)
-			csr1.field.Bss0Key1CipherAlg = CIPHER_CKIP64;
-		else if (csr1.field.Bss0Key1CipherAlg == CIPHER_WEP128)
-			csr1.field.Bss0Key1CipherAlg = CIPHER_CKIP128;
-
-		if (csr1.field.Bss0Key2CipherAlg == CIPHER_WEP64)
-			csr1.field.Bss0Key2CipherAlg = CIPHER_CKIP64;
-		else if (csr1.field.Bss0Key2CipherAlg == CIPHER_WEP128)
-			csr1.field.Bss0Key2CipherAlg = CIPHER_CKIP128;
-
-		if (csr1.field.Bss0Key3CipherAlg == CIPHER_WEP64)
-			csr1.field.Bss0Key3CipherAlg = CIPHER_CKIP64;
-		else if (csr1.field.Bss0Key3CipherAlg == CIPHER_WEP128)
-			csr1.field.Bss0Key3CipherAlg = CIPHER_CKIP128;
-		RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, csr1.word);
-		DBGPRINT(RT_DEBUG_TRACE, ("SwitchBetweenWepAndCkip: modify BSS0 cipher to %s\n", CipherName[csr1.field.Bss0Key0CipherAlg]));
-
-		// modify software key table so that driver can specify correct algorithm in TXD upon TX
-		for (i=0; i<SHARE_KEY_NUM; i++)
-		{
-			if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_WEP64)
-				pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_CKIP64;
-			else if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_WEP128)
-				pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_CKIP128;
-		}
-	}
-
-	// else if KP NOT inused. change the CipherAlg in hardware shard key table from CKIP
-	// to WEP.
-	else
-	{
-		// modify hardware key table so that MAC use correct algorithm to decrypt RX
-		RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE, &csr1.word);
-		if (csr1.field.Bss0Key0CipherAlg == CIPHER_CKIP64)
-			csr1.field.Bss0Key0CipherAlg = CIPHER_WEP64;
-		else if (csr1.field.Bss0Key0CipherAlg == CIPHER_CKIP128)
-			csr1.field.Bss0Key0CipherAlg = CIPHER_WEP128;
-
-		if (csr1.field.Bss0Key1CipherAlg == CIPHER_CKIP64)
-			csr1.field.Bss0Key1CipherAlg = CIPHER_WEP64;
-		else if (csr1.field.Bss0Key1CipherAlg == CIPHER_CKIP128)
-			csr1.field.Bss0Key1CipherAlg = CIPHER_WEP128;
-
-		if (csr1.field.Bss0Key2CipherAlg == CIPHER_CKIP64)
-			csr1.field.Bss0Key2CipherAlg = CIPHER_WEP64;
-		else if (csr1.field.Bss0Key2CipherAlg == CIPHER_CKIP128)
-			csr1.field.Bss0Key2CipherAlg = CIPHER_WEP128;
-
-		if (csr1.field.Bss0Key3CipherAlg == CIPHER_CKIP64)
-			csr1.field.Bss0Key3CipherAlg = CIPHER_WEP64;
-		else if (csr1.field.Bss0Key3CipherAlg == CIPHER_CKIP128)
-			csr1.field.Bss0Key3CipherAlg = CIPHER_WEP128;
-
-		// modify software key table so that driver can specify correct algorithm in TXD upon TX
-		for (i=0; i<SHARE_KEY_NUM; i++)
-		{
-			if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_CKIP64)
-				pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_WEP64;
-			else if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_CKIP128)
-				pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_WEP128;
-		}
-
-		//
-		// On WPA-NONE, must update CipherAlg.
-		// Because the OID_802_11_WEP_STATUS was been set after OID_802_11_ADD_KEY
-		// and CipherAlg will be CIPHER_NONE by Windows ZeroConfig.
-		// So we need to update CipherAlg after connect.
-		//
-		if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
-		{
-			for (i = 0; i < SHARE_KEY_NUM; i++)
-			{
-				if (pAd->SharedKey[BSS0][i].KeyLen != 0)
-				{
-					if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
-					{
-						pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_TKIP;
-					}
-					else if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
-					{
-						pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_AES;
-					}
-				}
-				else
-				{
-					pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_NONE;
-				}
-			}
-
-			csr1.field.Bss0Key0CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
-			csr1.field.Bss0Key1CipherAlg = pAd->SharedKey[BSS0][1].CipherAlg;
-			csr1.field.Bss0Key2CipherAlg = pAd->SharedKey[BSS0][2].CipherAlg;
-			csr1.field.Bss0Key3CipherAlg = pAd->SharedKey[BSS0][3].CipherAlg;
-		}
-		RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, csr1.word);
-		DBGPRINT(RT_DEBUG_TRACE, ("SwitchBetweenWepAndCkip: modify BSS0 cipher to %s\n", CipherName[csr1.field.Bss0Key0CipherAlg]));
-	}
-}
-
-int wext_notify_event_assoc(
-	IN  RTMP_ADAPTER *pAd)
-{
-    union iwreq_data    wrqu;
-    char custom[IW_CUSTOM_MAX] = {0};
-
-    if (pAd->StaCfg.ReqVarIELen <= IW_CUSTOM_MAX)
-    {
-        wrqu.data.length = pAd->StaCfg.ReqVarIELen;
-        memcpy(custom, pAd->StaCfg.ReqVarIEs, pAd->StaCfg.ReqVarIELen);
-        wireless_send_event(pAd->net_dev, IWEVASSOCREQIE, &wrqu, custom);
-    }
-    else
-        DBGPRINT(RT_DEBUG_TRACE, ("pAd->StaCfg.ReqVarIELen > MAX_CUSTOM_LEN\n"));
+	if (pAd->StaCfg.ReqVarIELen <= IW_CUSTOM_MAX) {
+		NdisMoveMemory(custom, pAd->StaCfg.ReqVarIEs,
+			       pAd->StaCfg.ReqVarIELen);
+		RtmpOSWrielessEventSend(pAd, IWEVASSOCREQIE, -1, NULL, custom,
+					pAd->StaCfg.ReqVarIELen);
+	} else
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("pAd->StaCfg.ReqVarIELen > MAX_CUSTOM_LEN\n"));
 
 	return 0;
 
 }
 
-#ifdef RT2870
-BOOLEAN StaAddMacTableEntry(
-	IN  PRTMP_ADAPTER		pAd,
-	IN  PMAC_TABLE_ENTRY	pEntry,
-	IN  UCHAR				MaxSupportedRateIn500Kbps,
-	IN  HT_CAPABILITY_IE	*pHtCapability,
-	IN  UCHAR				HtCapabilityLen,
-	IN  USHORT        		CapabilityInfo)
+BOOLEAN StaAddMacTableEntry(struct rt_rtmp_adapter *pAd,
+			    struct rt_mac_table_entry *pEntry,
+			    u8 MaxSupportedRateIn500Kbps,
+			    struct rt_ht_capability_ie * pHtCapability,
+			    u8 HtCapabilityLen,
+			    struct rt_add_ht_info_ie * pAddHtInfo,
+			    u8 AddHtInfoLen, u16 CapabilityInfo)
 {
-	UCHAR            MaxSupportedRate = RATE_11;
+	u8 MaxSupportedRate = RATE_11;
 
 	if (ADHOC_ON(pAd))
 		CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
 
-	switch (MaxSupportedRateIn500Kbps)
-    {
-        case 108: MaxSupportedRate = RATE_54;   break;
-        case 96:  MaxSupportedRate = RATE_48;   break;
-        case 72:  MaxSupportedRate = RATE_36;   break;
-        case 48:  MaxSupportedRate = RATE_24;   break;
-        case 36:  MaxSupportedRate = RATE_18;   break;
-        case 24:  MaxSupportedRate = RATE_12;   break;
-        case 18:  MaxSupportedRate = RATE_9;    break;
-        case 12:  MaxSupportedRate = RATE_6;    break;
-        case 22:  MaxSupportedRate = RATE_11;   break;
-        case 11:  MaxSupportedRate = RATE_5_5;  break;
-        case 4:   MaxSupportedRate = RATE_2;    break;
-        case 2:   MaxSupportedRate = RATE_1;    break;
-        default:  MaxSupportedRate = RATE_11;   break;
-    }
+	switch (MaxSupportedRateIn500Kbps) {
+	case 108:
+		MaxSupportedRate = RATE_54;
+		break;
+	case 96:
+		MaxSupportedRate = RATE_48;
+		break;
+	case 72:
+		MaxSupportedRate = RATE_36;
+		break;
+	case 48:
+		MaxSupportedRate = RATE_24;
+		break;
+	case 36:
+		MaxSupportedRate = RATE_18;
+		break;
+	case 24:
+		MaxSupportedRate = RATE_12;
+		break;
+	case 18:
+		MaxSupportedRate = RATE_9;
+		break;
+	case 12:
+		MaxSupportedRate = RATE_6;
+		break;
+	case 22:
+		MaxSupportedRate = RATE_11;
+		break;
+	case 11:
+		MaxSupportedRate = RATE_5_5;
+		break;
+	case 4:
+		MaxSupportedRate = RATE_2;
+		break;
+	case 2:
+		MaxSupportedRate = RATE_1;
+		break;
+	default:
+		MaxSupportedRate = RATE_11;
+		break;
+	}
 
-    if ((pAd->CommonCfg.PhyMode == PHY_11G) && (MaxSupportedRate < RATE_FIRST_OFDM_RATE))
-        return FALSE;
+	if ((pAd->CommonCfg.PhyMode == PHY_11G)
+	    && (MaxSupportedRate < RATE_FIRST_OFDM_RATE))
+		return FALSE;
 
-	// 11n only
-	if (((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G))&& (HtCapabilityLen == 0))
+	/* 11n only */
+	if (((pAd->CommonCfg.PhyMode == PHY_11N_2_4G)
+	     || (pAd->CommonCfg.PhyMode == PHY_11N_5G))
+	    && (HtCapabilityLen == 0))
 		return FALSE;
 
 	if (!pEntry)
-        return FALSE;
+		return FALSE;
 
 	NdisAcquireSpinLock(&pAd->MacTabLock);
-	if (pEntry)
-	{
+	if (pEntry) {
 		pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
 		if ((MaxSupportedRate < RATE_FIRST_OFDM_RATE) ||
-			(pAd->CommonCfg.PhyMode == PHY_11B))
-		{
+		    (pAd->CommonCfg.PhyMode == PHY_11B)) {
 			pEntry->RateLen = 4;
 			if (MaxSupportedRate >= RATE_FIRST_OFDM_RATE)
 				MaxSupportedRate = RATE_11;
-		}
-		else
+		} else
 			pEntry->RateLen = 12;
 
 		pEntry->MaxHTPhyMode.word = 0;
 		pEntry->MinHTPhyMode.word = 0;
 		pEntry->HTPhyMode.word = 0;
 		pEntry->MaxSupportedRate = MaxSupportedRate;
-		if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
-		{
+		if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE) {
 			pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
-			pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+			pEntry->MaxHTPhyMode.field.MCS =
+			    pEntry->MaxSupportedRate;
 			pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
-			pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+			pEntry->MinHTPhyMode.field.MCS =
+			    pEntry->MaxSupportedRate;
 			pEntry->HTPhyMode.field.MODE = MODE_CCK;
 			pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
-		}
-		else
-		{
+		} else {
 			pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
-			pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+			pEntry->MaxHTPhyMode.field.MCS =
+			    OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
 			pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
-			pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+			pEntry->MinHTPhyMode.field.MCS =
+			    OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
 			pEntry->HTPhyMode.field.MODE = MODE_OFDM;
-			pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+			pEntry->HTPhyMode.field.MCS =
+			    OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
 		}
 		pEntry->CapabilityInfo = CapabilityInfo;
-		CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE);
-		CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE);
+		CLIENT_STATUS_CLEAR_FLAG(pEntry,
+					 fCLIENT_STATUS_AGGREGATION_CAPABLE);
+		CLIENT_STATUS_CLEAR_FLAG(pEntry,
+					 fCLIENT_STATUS_PIGGYBACK_CAPABLE);
 	}
 
-	// If this Entry supports 802.11n, upgrade to HT rate.
-	if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
-	{
-		UCHAR	j, bitmask; //k,bitmask;
-		CHAR    i;
+	NdisZeroMemory(&pEntry->HTCapability, sizeof(pEntry->HTCapability));
+	/* If this Entry supports 802.11n, upgrade to HT rate. */
+	if ((HtCapabilityLen != 0)
+	    && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) {
+		u8 j, bitmask;	/*k,bitmask; */
+		char i;
 
 		if (ADHOC_ON(pAd))
-			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
-		if ((pHtCapability->HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
-		{
+			CLIENT_STATUS_SET_FLAG(pEntry,
+					       fCLIENT_STATUS_WMM_CAPABLE);
+		if ((pHtCapability->HtCapInfo.GF)
+		    && (pAd->CommonCfg.DesiredHtPhy.GF)) {
 			pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
-		}
-		else
-		{
+		} else {
 			pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
 			pAd->MacTab.fAnyStationNonGF = TRUE;
 			pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
 		}
 
-		if ((pHtCapability->HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
-		{
-			pEntry->MaxHTPhyMode.field.BW= BW_40;
-			pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(pHtCapability->HtCapInfo.ShortGIfor40));
-		}
-		else
-		{
+		if ((pHtCapability->HtCapInfo.ChannelWidth) &&
+		    (pAd->CommonCfg.DesiredHtPhy.ChannelWidth) &&
+		    ((pAd->StaCfg.BssType == BSS_INFRA)
+		     || ((pAd->StaCfg.BssType == BSS_ADHOC)
+			 && (pAddHtInfo->AddHtInfo.ExtChanOffset ==
+			     pAd->CommonCfg.AddHTInfo.AddHtInfo.
+			     ExtChanOffset)))) {
+			pEntry->MaxHTPhyMode.field.BW = BW_40;
+			pEntry->MaxHTPhyMode.field.ShortGI =
+			    ((pAd->CommonCfg.DesiredHtPhy.
+			      ShortGIfor40) & (pHtCapability->HtCapInfo.
+					       ShortGIfor40));
+		} else {
 			pEntry->MaxHTPhyMode.field.BW = BW_20;
-			pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(pHtCapability->HtCapInfo.ShortGIfor20));
+			pEntry->MaxHTPhyMode.field.ShortGI =
+			    ((pAd->CommonCfg.DesiredHtPhy.
+			      ShortGIfor20) & (pHtCapability->HtCapInfo.
+					       ShortGIfor20));
 			pAd->MacTab.fAnyStation20Only = TRUE;
 		}
 
-		// 3*3
-		if (pAd->MACVersion >= RALINK_2883_VERSION && pAd->MACVersion < RALINK_3070_VERSION)
-			pEntry->MaxHTPhyMode.field.TxBF = pAd->CommonCfg.RegTransmitSetting.field.TxBF;
+		/* 3*3 */
+		if (pAd->MACVersion >= RALINK_2883_VERSION
+		    && pAd->MACVersion < RALINK_3070_VERSION)
+			pEntry->MaxHTPhyMode.field.TxBF =
+			    pAd->CommonCfg.RegTransmitSetting.field.TxBF;
 
-		// find max fixed rate
-		for (i=23; i>=0; i--) // 3*3
+		/* find max fixed rate */
+		for (i = 23; i >= 0; i--)	/* 3*3 */
 		{
-			j = i/8;
-			bitmask = (1<<(i-(j*8)));
-			if ((pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j] & bitmask) && (pHtCapability->MCSSet[j] & bitmask))
-			{
+			j = i / 8;
+			bitmask = (1 << (i - (j * 8)));
+			if ((pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j] & bitmask)
+			    && (pHtCapability->MCSSet[j] & bitmask)) {
 				pEntry->MaxHTPhyMode.field.MCS = i;
 				break;
 			}
-			if (i==0)
+			if (i == 0)
 				break;
 		}
 
-
-		if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
-		{
-			if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
-			{
-				// Fix MCS as HT Duplicated Mode
+		if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) {
+			if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32) {
+				/* Fix MCS as HT Duplicated Mode */
 				pEntry->MaxHTPhyMode.field.BW = 1;
 				pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
 				pEntry->MaxHTPhyMode.field.STBC = 0;
 				pEntry->MaxHTPhyMode.field.ShortGI = 0;
 				pEntry->MaxHTPhyMode.field.MCS = 32;
-			}
-			else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
-			{
-				// STA supports fixed MCS
-				pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+			} else if (pEntry->MaxHTPhyMode.field.MCS >
+				   pAd->StaCfg.HTPhyMode.field.MCS) {
+				/* STA supports fixed MCS */
+				pEntry->MaxHTPhyMode.field.MCS =
+				    pAd->StaCfg.HTPhyMode.field.MCS;
 			}
 		}
 
-		pEntry->MaxHTPhyMode.field.STBC = (pHtCapability->HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
+		pEntry->MaxHTPhyMode.field.STBC =
+		    (pHtCapability->HtCapInfo.
+		     RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
 		pEntry->MpduDensity = pHtCapability->HtCapParm.MpduDensity;
-		pEntry->MaxRAmpduFactor = pHtCapability->HtCapParm.MaxRAmpduFactor;
-		pEntry->MmpsMode = (UCHAR)pHtCapability->HtCapInfo.MimoPs;
-		pEntry->AMsduSize = (UCHAR)pHtCapability->HtCapInfo.AMsduSize;
+		pEntry->MaxRAmpduFactor =
+		    pHtCapability->HtCapParm.MaxRAmpduFactor;
+		pEntry->MmpsMode = (u8)pHtCapability->HtCapInfo.MimoPs;
+		pEntry->AMsduSize = (u8)pHtCapability->HtCapInfo.AMsduSize;
 		pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
 
-		if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE))
-			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED);
+		if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable
+		    && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE))
+			CLIENT_STATUS_SET_FLAG(pEntry,
+					       fCLIENT_STATUS_AMSDU_INUSED);
 		if (pHtCapability->HtCapInfo.ShortGIfor20)
-			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
+			CLIENT_STATUS_SET_FLAG(pEntry,
+					       fCLIENT_STATUS_SGI20_CAPABLE);
 		if (pHtCapability->HtCapInfo.ShortGIfor40)
-			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
+			CLIENT_STATUS_SET_FLAG(pEntry,
+					       fCLIENT_STATUS_SGI40_CAPABLE);
 		if (pHtCapability->HtCapInfo.TxSTBC)
-			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
+			CLIENT_STATUS_SET_FLAG(pEntry,
+					       fCLIENT_STATUS_TxSTBC_CAPABLE);
 		if (pHtCapability->HtCapInfo.RxSTBC)
-			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
+			CLIENT_STATUS_SET_FLAG(pEntry,
+					       fCLIENT_STATUS_RxSTBC_CAPABLE);
 		if (pHtCapability->ExtHtCapInfo.PlusHTC)
-			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
-		if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport)
-			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
+			CLIENT_STATUS_SET_FLAG(pEntry,
+					       fCLIENT_STATUS_HTC_CAPABLE);
+		if (pAd->CommonCfg.bRdg
+		    && pHtCapability->ExtHtCapInfo.RDGSupport)
+			CLIENT_STATUS_SET_FLAG(pEntry,
+					       fCLIENT_STATUS_RDG_CAPABLE);
 		if (pHtCapability->ExtHtCapInfo.MCSFeedback == 0x03)
-			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
-	}
-	else
-	{
+			CLIENT_STATUS_SET_FLAG(pEntry,
+					       fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
+		NdisMoveMemory(&pEntry->HTCapability, pHtCapability,
+			       HtCapabilityLen);
+	} else {
 		pAd->MacTab.fAnyStationIsLegacy = TRUE;
 	}
 
-	NdisMoveMemory(&pEntry->HTCapability, pHtCapability, sizeof(HT_CAPABILITY_IE));
-
 	pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
 	pEntry->CurrTxRate = pEntry->MaxSupportedRate;
 
-	// Set asic auto fall back
-	if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
-	{
-		PUCHAR					pTable;
-		UCHAR					TableSize = 0;
+	/* Set asic auto fall back */
+	if (pAd->StaCfg.bAutoTxRateSwitch == TRUE) {
+		u8 *pTable;
+		u8 TableSize = 0;
 
-		MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
+		MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize,
+				      &pEntry->CurrTxRateIndex);
 		pEntry->bAutoTxRateSwitch = TRUE;
-	}
-	else
-	{
-		pEntry->HTPhyMode.field.MODE	= pAd->StaCfg.HTPhyMode.field.MODE;
-		pEntry->HTPhyMode.field.MCS	= pAd->StaCfg.HTPhyMode.field.MCS;
+	} else {
+		pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
+		pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
 		pEntry->bAutoTxRateSwitch = FALSE;
 
-		// If the legacy mode is set, overwrite the transmit setting of this entry.
-		RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
+		/* If the legacy mode is set, overwrite the transmit setting of this entry. */
+		RTMPUpdateLegacyTxSetting((u8)pAd->StaCfg.
+					  DesiredTransmitSetting.field.
+					  FixedTxMode, pEntry);
 	}
 
 	pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
@@ -1715,15 +1592,14 @@
 
 	NdisReleaseSpinLock(&pAd->MacTabLock);
 
-    {
-        union iwreq_data    wrqu;
-        wext_notify_event_assoc(pAd);
+	{
+		union iwreq_data wrqu;
+		wext_notify_event_assoc(pAd);
 
-        memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
-        memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
-        wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+		memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+		memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
+		wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
 
-    }
+	}
 	return TRUE;
 }
-#endif /* RT2870 */
diff --git a/drivers/staging/rt2860/sta/auth.c b/drivers/staging/rt2860/sta/auth.c
index d8414ea..404bd22 100644
--- a/drivers/staging/rt2860/sta/auth.c
+++ b/drivers/staging/rt2860/sta/auth.c
@@ -55,27 +55,35 @@
     ==========================================================================
  */
 
-void AuthStateMachineInit(
-    IN PRTMP_ADAPTER pAd,
-    IN STATE_MACHINE *Sm,
-    OUT STATE_MACHINE_FUNC Trans[])
+void AuthStateMachineInit(struct rt_rtmp_adapter *pAd,
+			  struct rt_state_machine *Sm, OUT STATE_MACHINE_FUNC Trans[])
 {
-    StateMachineInit(Sm, Trans, MAX_AUTH_STATE, MAX_AUTH_MSG, (STATE_MACHINE_FUNC)Drop, AUTH_REQ_IDLE, AUTH_MACHINE_BASE);
+	StateMachineInit(Sm, Trans, MAX_AUTH_STATE, MAX_AUTH_MSG,
+			 (STATE_MACHINE_FUNC) Drop, AUTH_REQ_IDLE,
+			 AUTH_MACHINE_BASE);
 
-    // the first column
-    StateMachineSetAction(Sm, AUTH_REQ_IDLE, MT2_MLME_AUTH_REQ, (STATE_MACHINE_FUNC)MlmeAuthReqAction);
+	/* the first column */
+	StateMachineSetAction(Sm, AUTH_REQ_IDLE, MT2_MLME_AUTH_REQ,
+			      (STATE_MACHINE_FUNC) MlmeAuthReqAction);
 
-    // the second column
-    StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_MLME_AUTH_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAuth);
-    StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_PEER_AUTH_EVEN, (STATE_MACHINE_FUNC)PeerAuthRspAtSeq2Action);
-    StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_AUTH_TIMEOUT, (STATE_MACHINE_FUNC)AuthTimeoutAction);
+	/* the second column */
+	StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_MLME_AUTH_REQ,
+			      (STATE_MACHINE_FUNC) InvalidStateWhenAuth);
+	StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_PEER_AUTH_EVEN,
+			      (STATE_MACHINE_FUNC) PeerAuthRspAtSeq2Action);
+	StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_AUTH_TIMEOUT,
+			      (STATE_MACHINE_FUNC) AuthTimeoutAction);
 
-    // the third column
-    StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_MLME_AUTH_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAuth);
-    StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_PEER_AUTH_EVEN, (STATE_MACHINE_FUNC)PeerAuthRspAtSeq4Action);
-    StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_AUTH_TIMEOUT, (STATE_MACHINE_FUNC)AuthTimeoutAction);
+	/* the third column */
+	StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_MLME_AUTH_REQ,
+			      (STATE_MACHINE_FUNC) InvalidStateWhenAuth);
+	StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_PEER_AUTH_EVEN,
+			      (STATE_MACHINE_FUNC) PeerAuthRspAtSeq4Action);
+	StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_AUTH_TIMEOUT,
+			      (STATE_MACHINE_FUNC) AuthTimeoutAction);
 
-	RTMPInitTimer(pAd, &pAd->MlmeAux.AuthTimer, GET_TIMER_FUNCTION(AuthTimeout), pAd, FALSE);
+	RTMPInitTimer(pAd, &pAd->MlmeAux.AuthTimer,
+		      GET_TIMER_FUNCTION(AuthTimeout), pAd, FALSE);
 }
 
 /*
@@ -87,31 +95,28 @@
 
     ==========================================================================
  */
-VOID AuthTimeout(
-    IN PVOID SystemSpecific1,
-    IN PVOID FunctionContext,
-    IN PVOID SystemSpecific2,
-    IN PVOID SystemSpecific3)
+void AuthTimeout(void *SystemSpecific1,
+		 void *FunctionContext,
+		 void *SystemSpecific2, void *SystemSpecific3)
 {
-    RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
 
-    DBGPRINT(RT_DEBUG_TRACE,("AUTH - AuthTimeout\n"));
+	DBGPRINT(RT_DEBUG_TRACE, ("AUTH - AuthTimeout\n"));
 
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+	/* Do nothing if the driver is starting halt state. */
+	/* This might happen when timer already been fired before cancel timer with mlmehalt */
+	if (RTMP_TEST_FLAG
+	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
 		return;
 
-	// send a de-auth to reset AP's state machine (Patch AP-Dir635)
+	/* send a de-auth to reset AP's state machine (Patch AP-Dir635) */
 	if (pAd->Mlme.AuthMachine.CurrState == AUTH_WAIT_SEQ2)
 		Cls2errAction(pAd, pAd->MlmeAux.Bssid);
 
-
-    MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_AUTH_TIMEOUT, 0, NULL);
-    RT28XX_MLME_HANDLER(pAd);
+	MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_AUTH_TIMEOUT, 0, NULL);
+	RTMP_MLME_HANDLER(pAd);
 }
 
-
 /*
     ==========================================================================
     Description:
@@ -120,67 +125,19 @@
 
     ==========================================================================
  */
-VOID MlmeAuthReqAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
+void MlmeAuthReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-    UCHAR              Addr[6];
-    USHORT             Alg, Seq, Status;
-    ULONG              Timeout;
-    HEADER_802_11      AuthHdr;
-    BOOLEAN            TimerCancelled;
-    NDIS_STATUS        NStatus;
-    PUCHAR             pOutBuffer = NULL;
-    ULONG              FrameLen = 0;
+	if (AUTH_ReqSend
+	    (pAd, Elem, &pAd->MlmeAux.AuthTimer, "AUTH", 1, NULL, 0))
+		pAd->Mlme.AuthMachine.CurrState = AUTH_WAIT_SEQ2;
+	else {
+		u16 Status;
 
-	// Block all authentication request durning WPA block period
-	if (pAd->StaCfg.bBlockAssoc == TRUE)
-	{
-        DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Block Auth request durning WPA block period!\n"));
-        pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-        Status = MLME_STATE_MACHINE_REJECT;
-        MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+		pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+		Status = MLME_INVALID_FORMAT;
+		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2,
+			    &Status);
 	}
-    else if(MlmeAuthReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr, &Timeout, &Alg))
-    {
-        // reset timer
-        RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &TimerCancelled);
-        COPY_MAC_ADDR(pAd->MlmeAux.Bssid, Addr);
-        pAd->MlmeAux.Alg  = Alg;
-        Seq = 1;
-        Status = MLME_SUCCESS;
-
-        NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-        if(NStatus != NDIS_STATUS_SUCCESS)
-        {
-            DBGPRINT(RT_DEBUG_TRACE, ("AUTH - MlmeAuthReqAction(Alg:%d) allocate memory failed\n", Alg));
-            pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-            Status = MLME_FAIL_NO_RESOURCE;
-            MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
-            return;
-        }
-
-        DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send AUTH request seq#1 (Alg=%d)...\n", Alg));
-        MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr, pAd->MlmeAux.Bssid);
-        MakeOutgoingFrame(pOutBuffer,           &FrameLen,
-                          sizeof(HEADER_802_11),&AuthHdr,
-                          2,                    &Alg,
-                          2,                    &Seq,
-                          2,                    &Status,
-                          END_OF_ARGS);
-        MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-    	MlmeFreeMemory(pAd, pOutBuffer);
-
-        RTMPSetTimer(&pAd->MlmeAux.AuthTimer, Timeout);
-        pAd->Mlme.AuthMachine.CurrState = AUTH_WAIT_SEQ2;
-    }
-    else
-    {
-        DBGPRINT_ERR(("AUTH - MlmeAuthReqAction() sanity check failed\n"));
-        pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-        Status = MLME_INVALID_FORMAT;
-        MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
-    }
 }
 
 /*
@@ -191,102 +148,130 @@
 
     ==========================================================================
  */
-VOID PeerAuthRspAtSeq2Action(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
+void PeerAuthRspAtSeq2Action(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-    UCHAR         Addr2[MAC_ADDR_LEN];
-    USHORT        Seq, Status, RemoteStatus, Alg;
-    UCHAR         ChlgText[CIPHER_TEXT_LEN];
-    UCHAR         CyperChlgText[CIPHER_TEXT_LEN + 8 + 8];
-    UCHAR         Element[2];
-    HEADER_802_11 AuthHdr;
-    BOOLEAN       TimerCancelled;
-    PUCHAR        pOutBuffer = NULL;
-    NDIS_STATUS   NStatus;
-    ULONG         FrameLen = 0;
-    USHORT        Status2;
+	u8 Addr2[MAC_ADDR_LEN];
+	u16 Seq, Status, RemoteStatus, Alg;
+	u8 ChlgText[CIPHER_TEXT_LEN];
+	u8 CyperChlgText[CIPHER_TEXT_LEN + 8 + 8];
+	u8 Element[2];
+	struct rt_header_802_11 AuthHdr;
+	BOOLEAN TimerCancelled;
+	u8 *pOutBuffer = NULL;
+	int NStatus;
+	unsigned long FrameLen = 0;
+	u16 Status2;
 
-    if (PeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, ChlgText))
-    {
-        if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 2)
-        {
-            DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Receive AUTH_RSP seq#2 to me (Alg=%d, Status=%d)\n", Alg, Status));
-            RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &TimerCancelled);
+	if (PeerAuthSanity
+	    (pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status,
+	     (char *)ChlgText)) {
+		if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 2) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("AUTH - Receive AUTH_RSP seq#2 to me (Alg=%d, Status=%d)\n",
+				  Alg, Status));
+			RTMPCancelTimer(&pAd->MlmeAux.AuthTimer,
+					&TimerCancelled);
 
-            if (Status == MLME_SUCCESS)
-            {
-                // Authentication Mode "LEAP" has allow for CCX 1.X
-                if ((pAd->MlmeAux.Alg == Ndis802_11AuthModeOpen)
-				)
-                {
-                    pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-                    MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
-                }
-                else
-                {
-                    // 2. shared key, need to be challenged
-                    Seq++;
-                    RemoteStatus = MLME_SUCCESS;
+			if (Status == MLME_SUCCESS) {
+				/* Authentication Mode "LEAP" has allow for CCX 1.X */
+				if (pAd->MlmeAux.Alg == Ndis802_11AuthModeOpen) {
+					pAd->Mlme.AuthMachine.CurrState =
+					    AUTH_REQ_IDLE;
+					MlmeEnqueue(pAd,
+						    MLME_CNTL_STATE_MACHINE,
+						    MT2_AUTH_CONF, 2, &Status);
+				} else {
+					/* 2. shared key, need to be challenged */
+					Seq++;
+					RemoteStatus = MLME_SUCCESS;
 
-					// Get an unused nonpaged memory
-                    NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
-                    if(NStatus != NDIS_STATUS_SUCCESS)
-                    {
-                        DBGPRINT(RT_DEBUG_TRACE, ("AUTH - PeerAuthRspAtSeq2Action() allocate memory fail\n"));
-                        pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-                        Status2 = MLME_FAIL_NO_RESOURCE;
-                        MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status2);
-                        return;
-                    }
+					/* Get an unused nonpaged memory */
+					NStatus =
+					    MlmeAllocateMemory(pAd,
+							       &pOutBuffer);
+					if (NStatus != NDIS_STATUS_SUCCESS) {
+						DBGPRINT(RT_DEBUG_TRACE,
+							 ("AUTH - PeerAuthRspAtSeq2Action() allocate memory fail\n"));
+						pAd->Mlme.AuthMachine.
+						    CurrState = AUTH_REQ_IDLE;
+						Status2 = MLME_FAIL_NO_RESOURCE;
+						MlmeEnqueue(pAd,
+							    MLME_CNTL_STATE_MACHINE,
+							    MT2_AUTH_CONF, 2,
+							    &Status2);
+						return;
+					}
 
-                    DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send AUTH request seq#3...\n"));
-                    MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr2, pAd->MlmeAux.Bssid);
-                    AuthHdr.FC.Wep = 1;
-                    // Encrypt challenge text & auth information
-                    RTMPInitWepEngine(
-                    	pAd,
-                    	pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
-                    	pAd->StaCfg.DefaultKeyId,
-                    	pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen,
-                    	CyperChlgText);
+					DBGPRINT(RT_DEBUG_TRACE,
+						 ("AUTH - Send AUTH request seq#3...\n"));
+					MgtMacHeaderInit(pAd, &AuthHdr,
+							 SUBTYPE_AUTH, 0, Addr2,
+							 pAd->MlmeAux.Bssid);
+					AuthHdr.FC.Wep = 1;
+					/* Encrypt challenge text & auth information */
+					RTMPInitWepEngine(pAd,
+							  pAd->
+							  SharedKey[BSS0][pAd->
+									  StaCfg.
+									  DefaultKeyId].
+							  Key,
+							  pAd->StaCfg.
+							  DefaultKeyId,
+							  pAd->
+							  SharedKey[BSS0][pAd->
+									  StaCfg.
+									  DefaultKeyId].
+							  KeyLen,
+							  CyperChlgText);
 
-					Alg = cpu2le16(*(USHORT *)&Alg);
-					Seq = cpu2le16(*(USHORT *)&Seq);
-					RemoteStatus= cpu2le16(*(USHORT *)&RemoteStatus);
+					Alg = cpu2le16(*(u16 *) & Alg);
+					Seq = cpu2le16(*(u16 *) & Seq);
+					RemoteStatus =
+					    cpu2le16(*(u16 *) &
+						     RemoteStatus);
 
-					RTMPEncryptData(pAd, (PUCHAR) &Alg, CyperChlgText + 4, 2);
-					RTMPEncryptData(pAd, (PUCHAR) &Seq, CyperChlgText + 6, 2);
-					RTMPEncryptData(pAd, (PUCHAR) &RemoteStatus, CyperChlgText + 8, 2);
+					RTMPEncryptData(pAd, (u8 *)& Alg,
+							CyperChlgText + 4, 2);
+					RTMPEncryptData(pAd, (u8 *)& Seq,
+							CyperChlgText + 6, 2);
+					RTMPEncryptData(pAd,
+							(u8 *)& RemoteStatus,
+							CyperChlgText + 8, 2);
 					Element[0] = 16;
 					Element[1] = 128;
-					RTMPEncryptData(pAd, Element, CyperChlgText + 10, 2);
-					RTMPEncryptData(pAd, ChlgText, CyperChlgText + 12, 128);
+					RTMPEncryptData(pAd, Element,
+							CyperChlgText + 10, 2);
+					RTMPEncryptData(pAd, ChlgText,
+							CyperChlgText + 12,
+							128);
 					RTMPSetICV(pAd, CyperChlgText + 140);
-                    MakeOutgoingFrame(pOutBuffer,               &FrameLen,
-                                      sizeof(HEADER_802_11),    &AuthHdr,
-                                      CIPHER_TEXT_LEN + 16,     CyperChlgText,
-                                      END_OF_ARGS);
-                    MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-                	MlmeFreeMemory(pAd, pOutBuffer);
+					MakeOutgoingFrame(pOutBuffer, &FrameLen,
+							  sizeof(struct rt_header_802_11),
+							  &AuthHdr,
+							  CIPHER_TEXT_LEN + 16,
+							  CyperChlgText,
+							  END_OF_ARGS);
+					MiniportMMRequest(pAd, 0, pOutBuffer,
+							  FrameLen);
+					MlmeFreeMemory(pAd, pOutBuffer);
 
-                    RTMPSetTimer(&pAd->MlmeAux.AuthTimer, AUTH_TIMEOUT);
-                    pAd->Mlme.AuthMachine.CurrState = AUTH_WAIT_SEQ4;
-                }
-            }
-            else
-            {
-                pAd->StaCfg.AuthFailReason = Status;
-                COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2);
-                pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-                MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
-            }
-        }
-    }
-    else
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("AUTH - PeerAuthSanity() sanity check fail\n"));
-    }
+					RTMPSetTimer(&pAd->MlmeAux.AuthTimer,
+						     AUTH_TIMEOUT);
+					pAd->Mlme.AuthMachine.CurrState =
+					    AUTH_WAIT_SEQ4;
+				}
+			} else {
+				pAd->StaCfg.AuthFailReason = Status;
+				COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2);
+				pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+				MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE,
+					    MT2_AUTH_CONF, 2, &Status);
+			}
+		}
+	} else {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("AUTH - PeerAuthSanity() sanity check fail\n"));
+	}
 }
 
 /*
@@ -297,36 +282,35 @@
 
     ==========================================================================
  */
-VOID PeerAuthRspAtSeq4Action(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
+void PeerAuthRspAtSeq4Action(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-    UCHAR         Addr2[MAC_ADDR_LEN];
-    USHORT        Alg, Seq, Status;
-    CHAR          ChlgText[CIPHER_TEXT_LEN];
-    BOOLEAN       TimerCancelled;
+	u8 Addr2[MAC_ADDR_LEN];
+	u16 Alg, Seq, Status;
+	char ChlgText[CIPHER_TEXT_LEN];
+	BOOLEAN TimerCancelled;
 
-    if(PeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, ChlgText))
-    {
-        if(MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 4)
-        {
-            DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Receive AUTH_RSP seq#4 to me\n"));
-            RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &TimerCancelled);
+	if (PeerAuthSanity
+	    (pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status,
+	     ChlgText)) {
+		if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 4) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("AUTH - Receive AUTH_RSP seq#4 to me\n"));
+			RTMPCancelTimer(&pAd->MlmeAux.AuthTimer,
+					&TimerCancelled);
 
-            if (Status != MLME_SUCCESS)
-            {
-                pAd->StaCfg.AuthFailReason = Status;
-                COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2);
-            }
+			if (Status != MLME_SUCCESS) {
+				pAd->StaCfg.AuthFailReason = Status;
+				COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2);
+			}
 
-            pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-            MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
-        }
-    }
-    else
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("AUTH - PeerAuthRspAtSeq4Action() sanity check fail\n"));
-    }
+			pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF,
+				    2, &Status);
+		}
+	} else {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("AUTH - PeerAuthRspAtSeq4Action() sanity check fail\n"));
+	}
 }
 
 /*
@@ -337,47 +321,49 @@
 
     ==========================================================================
  */
-VOID MlmeDeauthReqAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
+void MlmeDeauthReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-    MLME_DEAUTH_REQ_STRUCT *pInfo;
-    HEADER_802_11 DeauthHdr;
-    PUCHAR        pOutBuffer = NULL;
-    NDIS_STATUS   NStatus;
-    ULONG         FrameLen = 0;
-    USHORT        Status;
+	struct rt_mlme_deauth_req *pInfo;
+	struct rt_header_802_11 DeauthHdr;
+	u8 *pOutBuffer = NULL;
+	int NStatus;
+	unsigned long FrameLen = 0;
+	u16 Status;
 
-    pInfo = (MLME_DEAUTH_REQ_STRUCT *)Elem->Msg;
+	pInfo = (struct rt_mlme_deauth_req *)Elem->Msg;
 
-    NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-    if (NStatus != NDIS_STATUS_SUCCESS)
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("AUTH - MlmeDeauthReqAction() allocate memory fail\n"));
-        pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-        Status = MLME_FAIL_NO_RESOURCE;
-        MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, &Status);
-        return;
-    }
+	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
+	if (NStatus != NDIS_STATUS_SUCCESS) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("AUTH - MlmeDeauthReqAction() allocate memory fail\n"));
+		pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+		Status = MLME_FAIL_NO_RESOURCE;
+		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2,
+			    &Status);
+		return;
+	}
 
-    DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send DE-AUTH request (Reason=%d)...\n", pInfo->Reason));
-    MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pInfo->Addr, pAd->MlmeAux.Bssid);
-    MakeOutgoingFrame(pOutBuffer,           &FrameLen,
-                      sizeof(HEADER_802_11),&DeauthHdr,
-                      2,                    &pInfo->Reason,
-                      END_OF_ARGS);
-    MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("AUTH - Send DE-AUTH request (Reason=%d)...\n",
+		  pInfo->Reason));
+	MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pInfo->Addr,
+			 pAd->MlmeAux.Bssid);
+	MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(struct rt_header_802_11),
+			  &DeauthHdr, 2, &pInfo->Reason, END_OF_ARGS);
+	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
 	MlmeFreeMemory(pAd, pOutBuffer);
 
-    pAd->StaCfg.DeauthReason = pInfo->Reason;
-    COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pInfo->Addr);
-    pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-    Status = MLME_SUCCESS;
-    MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, &Status);
+	pAd->StaCfg.DeauthReason = pInfo->Reason;
+	COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pInfo->Addr);
+	pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+	Status = MLME_SUCCESS;
+	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, &Status);
 
-	// send wireless event - for deauthentication
+	/* send wireless event - for deauthentication */
 	if (pAd->CommonCfg.bWirelessEvent)
-		RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+		RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG,
+				      pAd->MacTab.Content[BSSID_WCID].Addr,
+				      BSS0, 0);
 }
 
 /*
@@ -388,15 +374,13 @@
 
     ==========================================================================
  */
-VOID AuthTimeoutAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
+void AuthTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-    USHORT Status;
-    DBGPRINT(RT_DEBUG_TRACE, ("AUTH - AuthTimeoutAction\n"));
-    pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-    Status = MLME_REJ_TIMEOUT;
-    MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+	u16 Status;
+	DBGPRINT(RT_DEBUG_TRACE, ("AUTH - AuthTimeoutAction\n"));
+	pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+	Status = MLME_REJ_TIMEOUT;
+	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
 }
 
 /*
@@ -407,15 +391,15 @@
 
     ==========================================================================
  */
-VOID InvalidStateWhenAuth(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
+void InvalidStateWhenAuth(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-    USHORT Status;
-    DBGPRINT(RT_DEBUG_TRACE, ("AUTH - InvalidStateWhenAuth (state=%ld), reset AUTH state machine\n", pAd->Mlme.AuthMachine.CurrState));
-    pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-    Status = MLME_STATE_MACHINE_REJECT;
-    MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+	u16 Status;
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("AUTH - InvalidStateWhenAuth (state=%ld), reset AUTH state machine\n",
+		  pAd->Mlme.AuthMachine.CurrState));
+	pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+	Status = MLME_STATE_MACHINE_REJECT;
+	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
 }
 
 /*
@@ -430,31 +414,104 @@
 
     ==========================================================================
  */
-VOID Cls2errAction(
-    IN PRTMP_ADAPTER pAd,
-    IN PUCHAR pAddr)
+void Cls2errAction(struct rt_rtmp_adapter *pAd, u8 *pAddr)
 {
-    HEADER_802_11 DeauthHdr;
-    PUCHAR        pOutBuffer = NULL;
-    NDIS_STATUS   NStatus;
-    ULONG         FrameLen = 0;
-    USHORT        Reason = REASON_CLS2ERR;
+	struct rt_header_802_11 DeauthHdr;
+	u8 *pOutBuffer = NULL;
+	int NStatus;
+	unsigned long FrameLen = 0;
+	u16 Reason = REASON_CLS2ERR;
 
-    NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-    if (NStatus != NDIS_STATUS_SUCCESS)
-        return;
+	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
+	if (NStatus != NDIS_STATUS_SUCCESS)
+		return;
 
-    DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Class 2 error, Send DEAUTH frame...\n"));
-    MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pAddr, pAd->MlmeAux.Bssid);
-    MakeOutgoingFrame(pOutBuffer,           &FrameLen,
-                      sizeof(HEADER_802_11),&DeauthHdr,
-                      2,                    &Reason,
-                      END_OF_ARGS);
-    MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("AUTH - Class 2 error, Send DEAUTH frame...\n"));
+	MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pAddr,
+			 pAd->MlmeAux.Bssid);
+	MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(struct rt_header_802_11),
+			  &DeauthHdr, 2, &Reason, END_OF_ARGS);
+	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
 	MlmeFreeMemory(pAd, pOutBuffer);
 
-    pAd->StaCfg.DeauthReason = Reason;
-    COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pAddr);
+	pAd->StaCfg.DeauthReason = Reason;
+	COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pAddr);
 }
 
+BOOLEAN AUTH_ReqSend(struct rt_rtmp_adapter *pAd,
+		     struct rt_mlme_queue_elem *pElem,
+		     struct rt_ralink_timer *pAuthTimer,
+		     char *pSMName,
+		     u16 SeqNo,
+		     u8 *pNewElement, unsigned long ElementLen)
+{
+	u16 Alg, Seq, Status;
+	u8 Addr[6];
+	unsigned long Timeout;
+	struct rt_header_802_11 AuthHdr;
+	BOOLEAN TimerCancelled;
+	int NStatus;
+	u8 *pOutBuffer = NULL;
+	unsigned long FrameLen = 0, tmp = 0;
 
+	/* Block all authentication request durning WPA block period */
+	if (pAd->StaCfg.bBlockAssoc == TRUE) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("%s - Block Auth request durning WPA block period!\n",
+			  pSMName));
+		pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+		Status = MLME_STATE_MACHINE_REJECT;
+		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2,
+			    &Status);
+	} else
+	    if (MlmeAuthReqSanity
+		(pAd, pElem->Msg, pElem->MsgLen, Addr, &Timeout, &Alg)) {
+		/* reset timer */
+		RTMPCancelTimer(pAuthTimer, &TimerCancelled);
+
+		COPY_MAC_ADDR(pAd->MlmeAux.Bssid, Addr);
+		pAd->MlmeAux.Alg = Alg;
+		Seq = SeqNo;
+		Status = MLME_SUCCESS;
+
+		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
+		if (NStatus != NDIS_STATUS_SUCCESS) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("%s - MlmeAuthReqAction(Alg:%d) allocate memory failed\n",
+				  pSMName, Alg));
+			pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+			Status = MLME_FAIL_NO_RESOURCE;
+			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF,
+				    2, &Status);
+			return FALSE;
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("%s - Send AUTH request seq#1 (Alg=%d)...\n", pSMName,
+			  Alg));
+		MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr,
+				 pAd->MlmeAux.Bssid);
+		MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(struct rt_header_802_11),
+				  &AuthHdr, 2, &Alg, 2, &Seq, 2, &Status,
+				  END_OF_ARGS);
+
+		if (pNewElement && ElementLen) {
+			MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+					  ElementLen, pNewElement, END_OF_ARGS);
+			FrameLen += tmp;
+		}
+
+		MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+		MlmeFreeMemory(pAd, pOutBuffer);
+
+		RTMPSetTimer(pAuthTimer, Timeout);
+		return TRUE;
+	} else {
+		DBGPRINT_ERR(("%s - MlmeAuthReqAction() sanity check failed\n",
+			      pSMName));
+		return FALSE;
+	}
+
+	return TRUE;
+}
diff --git a/drivers/staging/rt2860/sta/auth_rsp.c b/drivers/staging/rt2860/sta/auth_rsp.c
index cc639b1..5b018b7 100644
--- a/drivers/staging/rt2860/sta/auth_rsp.c
+++ b/drivers/staging/rt2860/sta/auth_rsp.c
@@ -47,18 +47,21 @@
 
     ==========================================================================
  */
-VOID AuthRspStateMachineInit(
-    IN PRTMP_ADAPTER pAd,
-    IN PSTATE_MACHINE Sm,
-    IN STATE_MACHINE_FUNC Trans[])
+void AuthRspStateMachineInit(struct rt_rtmp_adapter *pAd,
+			     struct rt_state_machine *Sm,
+			     IN STATE_MACHINE_FUNC Trans[])
 {
-    StateMachineInit(Sm, Trans, MAX_AUTH_RSP_STATE, MAX_AUTH_RSP_MSG, (STATE_MACHINE_FUNC)Drop, AUTH_RSP_IDLE, AUTH_RSP_MACHINE_BASE);
+	StateMachineInit(Sm, Trans, MAX_AUTH_RSP_STATE, MAX_AUTH_RSP_MSG,
+			 (STATE_MACHINE_FUNC) Drop, AUTH_RSP_IDLE,
+			 AUTH_RSP_MACHINE_BASE);
 
-    // column 1
-    StateMachineSetAction(Sm, AUTH_RSP_IDLE, MT2_PEER_DEAUTH, (STATE_MACHINE_FUNC)PeerDeauthAction);
+	/* column 1 */
+	StateMachineSetAction(Sm, AUTH_RSP_IDLE, MT2_PEER_DEAUTH,
+			      (STATE_MACHINE_FUNC) PeerDeauthAction);
 
-    // column 2
-    StateMachineSetAction(Sm, AUTH_RSP_WAIT_CHAL, MT2_PEER_DEAUTH, (STATE_MACHINE_FUNC)PeerDeauthAction);
+	/* column 2 */
+	StateMachineSetAction(Sm, AUTH_RSP_WAIT_CHAL, MT2_PEER_DEAUTH,
+			      (STATE_MACHINE_FUNC) PeerDeauthAction);
 
 }
 
@@ -70,39 +73,32 @@
 
     ==========================================================================
 */
-VOID PeerAuthSimpleRspGenAndSend(
-    IN PRTMP_ADAPTER pAd,
-    IN PHEADER_802_11 pHdr80211,
-    IN USHORT Alg,
-    IN USHORT Seq,
-    IN USHORT Reason,
-    IN USHORT Status)
+void PeerAuthSimpleRspGenAndSend(struct rt_rtmp_adapter *pAd,
+				 struct rt_header_802_11 * pHdr80211,
+				 u16 Alg,
+				 u16 Seq,
+				 u16 Reason, u16 Status)
 {
-    HEADER_802_11     AuthHdr;
-    ULONG             FrameLen = 0;
-    PUCHAR            pOutBuffer = NULL;
-    NDIS_STATUS       NStatus;
+	struct rt_header_802_11 AuthHdr;
+	unsigned long FrameLen = 0;
+	u8 *pOutBuffer = NULL;
+	int NStatus;
 
-    if (Reason != MLME_SUCCESS)
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("Peer AUTH fail...\n"));
-        return;
-    }
+	if (Reason != MLME_SUCCESS) {
+		DBGPRINT(RT_DEBUG_TRACE, ("Peer AUTH fail...\n"));
+		return;
+	}
+	/*Get an unused nonpaged memory */
+	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+	if (NStatus != NDIS_STATUS_SUCCESS)
+		return;
 
-	//Get an unused nonpaged memory
-    NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
-    if (NStatus != NDIS_STATUS_SUCCESS)
-        return;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("Send AUTH response (seq#2)...\n"));
-    MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, pHdr80211->Addr2, pAd->MlmeAux.Bssid);
-    MakeOutgoingFrame(pOutBuffer,               &FrameLen,
-                      sizeof(HEADER_802_11),    &AuthHdr,
-                      2,                        &Alg,
-                      2,                        &Seq,
-                      2,                        &Reason,
-                      END_OF_ARGS);
-    MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+	DBGPRINT(RT_DEBUG_TRACE, ("Send AUTH response (seq#2)...\n"));
+	MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, pHdr80211->Addr2,
+			 pAd->MlmeAux.Bssid);
+	MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(struct rt_header_802_11),
+			  &AuthHdr, 2, &Alg, 2, &Seq, 2, &Reason, END_OF_ARGS);
+	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
 	MlmeFreeMemory(pAd, pOutBuffer);
 }
 
@@ -114,35 +110,33 @@
 
     ==========================================================================
 */
-VOID PeerDeauthAction(
-    IN PRTMP_ADAPTER pAd,
-    IN PMLME_QUEUE_ELEM Elem)
+void PeerDeauthAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-    UCHAR       Addr2[MAC_ADDR_LEN];
-    USHORT      Reason;
+	u8 Addr2[MAC_ADDR_LEN];
+	u16 Reason;
 
-    if (PeerDeauthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason))
-    {
-        if (INFRA_ON(pAd) && MAC_ADDR_EQUAL(Addr2, pAd->CommonCfg.Bssid))
-        {
-            DBGPRINT(RT_DEBUG_TRACE,("AUTH_RSP - receive DE-AUTH from our AP (Reason=%d)\n", Reason));
+	if (PeerDeauthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason)) {
+		if (INFRA_ON(pAd)
+		    && MAC_ADDR_EQUAL(Addr2, pAd->CommonCfg.Bssid)
+		    ) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("AUTH_RSP - receive DE-AUTH from our AP (Reason=%d)\n",
+				  Reason));
 
-            {
-                union iwreq_data    wrqu;
-                memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
-                wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
-            }
+			RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL,
+						0);
 
-			// send wireless event - for deauthentication
+			/* send wireless event - for deauthentication */
 			if (pAd->CommonCfg.bWirelessEvent)
-				RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+				RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG,
+						      pAd->MacTab.
+						      Content[BSSID_WCID].Addr,
+						      BSS0, 0);
 
-            LinkDown(pAd, TRUE);
-        }
-    }
-    else
-    {
-        DBGPRINT(RT_DEBUG_TRACE,("AUTH_RSP - PeerDeauthAction() sanity check fail\n"));
-    }
+			LinkDown(pAd, TRUE);
+		}
+	} else {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("AUTH_RSP - PeerDeauthAction() sanity check fail\n"));
+	}
 }
-
diff --git a/drivers/staging/rt2860/sta/connect.c b/drivers/staging/rt2860/sta/connect.c
index 7bc75ab..17e59ba 100644
--- a/drivers/staging/rt2860/sta/connect.c
+++ b/drivers/staging/rt2860/sta/connect.c
@@ -36,34 +36,39 @@
 */
 #include "../rt_config.h"
 
-UCHAR	CipherSuiteWpaNoneTkip[] = {
-		0x00, 0x50, 0xf2, 0x01,	// oui
-		0x01, 0x00,				// Version
-		0x00, 0x50, 0xf2, 0x02,	// Multicast
-		0x01, 0x00,				// Number of unicast
-		0x00, 0x50, 0xf2, 0x02,	// unicast
-		0x01, 0x00,				// number of authentication method
-		0x00, 0x50, 0xf2, 0x00	// authentication
-		};
-UCHAR	CipherSuiteWpaNoneTkipLen = (sizeof(CipherSuiteWpaNoneTkip) / sizeof(UCHAR));
+u8 CipherSuiteWpaNoneTkip[] = {
+	0x00, 0x50, 0xf2, 0x01,	/* oui */
+	0x01, 0x00,		/* Version */
+	0x00, 0x50, 0xf2, 0x02,	/* Multicast */
+	0x01, 0x00,		/* Number of unicast */
+	0x00, 0x50, 0xf2, 0x02,	/* unicast */
+	0x01, 0x00,		/* number of authentication method */
+	0x00, 0x50, 0xf2, 0x00	/* authentication */
+};
 
-UCHAR	CipherSuiteWpaNoneAes[] = {
-		0x00, 0x50, 0xf2, 0x01,	// oui
-		0x01, 0x00,				// Version
-		0x00, 0x50, 0xf2, 0x04,	// Multicast
-		0x01, 0x00,				// Number of unicast
-		0x00, 0x50, 0xf2, 0x04,	// unicast
-		0x01, 0x00,				// number of authentication method
-		0x00, 0x50, 0xf2, 0x00	// authentication
-		};
-UCHAR	CipherSuiteWpaNoneAesLen = (sizeof(CipherSuiteWpaNoneAes) / sizeof(UCHAR));
+u8 CipherSuiteWpaNoneTkipLen =
+    (sizeof(CipherSuiteWpaNoneTkip) / sizeof(u8));
 
-// The following MACRO is called after 1. starting an new IBSS, 2. succesfully JOIN an IBSS,
-// or 3. succesfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS
-// All settings successfuly negotiated furing MLME state machines become final settings
-// and are copied to pAd->StaActive
+u8 CipherSuiteWpaNoneAes[] = {
+	0x00, 0x50, 0xf2, 0x01,	/* oui */
+	0x01, 0x00,		/* Version */
+	0x00, 0x50, 0xf2, 0x04,	/* Multicast */
+	0x01, 0x00,		/* Number of unicast */
+	0x00, 0x50, 0xf2, 0x04,	/* unicast */
+	0x01, 0x00,		/* number of authentication method */
+	0x00, 0x50, 0xf2, 0x00	/* authentication */
+};
+
+u8 CipherSuiteWpaNoneAesLen =
+    (sizeof(CipherSuiteWpaNoneAes) / sizeof(u8));
+
+/* The following MACRO is called after 1. starting an new IBSS, 2. succesfully JOIN an IBSS, */
+/* or 3. succesfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS */
+/* All settings successfuly negotiated furing MLME state machines become final settings */
+/* and are copied to pAd->StaActive */
 #define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd)                                 \
 {                                                                                       \
+	NdisZeroMemory((_pAd)->CommonCfg.Ssid, MAX_LEN_OF_SSID);							\
 	(_pAd)->CommonCfg.SsidLen = (_pAd)->MlmeAux.SsidLen;                                \
 	NdisMoveMemory((_pAd)->CommonCfg.Ssid, (_pAd)->MlmeAux.Ssid, (_pAd)->MlmeAux.SsidLen); \
 	COPY_MAC_ADDR((_pAd)->CommonCfg.Bssid, (_pAd)->MlmeAux.Bssid);                      \
@@ -79,9 +84,9 @@
 	NdisMoveMemory((_pAd)->StaActive.SupRate, (_pAd)->MlmeAux.SupRate, (_pAd)->MlmeAux.SupRateLen);\
 	(_pAd)->StaActive.ExtRateLen = (_pAd)->MlmeAux.ExtRateLen;                          \
 	NdisMoveMemory((_pAd)->StaActive.ExtRate, (_pAd)->MlmeAux.ExtRate, (_pAd)->MlmeAux.ExtRateLen);\
-	NdisMoveMemory(&(_pAd)->CommonCfg.APEdcaParm, &(_pAd)->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));\
-	NdisMoveMemory(&(_pAd)->CommonCfg.APQosCapability, &(_pAd)->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));\
-	NdisMoveMemory(&(_pAd)->CommonCfg.APQbssLoad, &(_pAd)->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));\
+	NdisMoveMemory(&(_pAd)->CommonCfg.APEdcaParm, &(_pAd)->MlmeAux.APEdcaParm, sizeof(struct rt_edca_parm));\
+	NdisMoveMemory(&(_pAd)->CommonCfg.APQosCapability, &(_pAd)->MlmeAux.APQosCapability, sizeof(struct rt_qos_capability_parm));\
+	NdisMoveMemory(&(_pAd)->CommonCfg.APQbssLoad, &(_pAd)->MlmeAux.APQbssLoad, sizeof(struct rt_qbss_load_parm));\
 	COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].Addr, (_pAd)->MlmeAux.Bssid);      \
 	(_pAd)->MacTab.Content[BSSID_WCID].Aid = (_pAd)->MlmeAux.Aid;                       \
 	(_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = (_pAd)->StaCfg.PairCipher;\
@@ -97,13 +102,11 @@
 
 	==========================================================================
 */
-VOID MlmeCntlInit(
-	IN PRTMP_ADAPTER pAd,
-	IN STATE_MACHINE *S,
-	OUT STATE_MACHINE_FUNC Trans[])
+void MlmeCntlInit(struct rt_rtmp_adapter *pAd,
+		  struct rt_state_machine *S, OUT STATE_MACHINE_FUNC Trans[])
 {
-	// Control state machine differs from other state machines, the interface
-	// follows the standard interface
+	/* Control state machine differs from other state machines, the interface */
+	/* follows the standard interface */
 	pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
 }
 
@@ -115,118 +118,108 @@
 
 	==========================================================================
 */
-VOID MlmeCntlMachinePerformAction(
-	IN PRTMP_ADAPTER pAd,
-	IN STATE_MACHINE *S,
-	IN MLME_QUEUE_ELEM *Elem)
+void MlmeCntlMachinePerformAction(struct rt_rtmp_adapter *pAd,
+				  struct rt_state_machine *S,
+				  struct rt_mlme_queue_elem *Elem)
 {
-	switch(pAd->Mlme.CntlMachine.CurrState)
-	{
-		case CNTL_IDLE:
-			{
-				CntlIdleProc(pAd, Elem);
+	switch (pAd->Mlme.CntlMachine.CurrState) {
+	case CNTL_IDLE:
+		CntlIdleProc(pAd, Elem);
+		break;
+	case CNTL_WAIT_DISASSOC:
+		CntlWaitDisassocProc(pAd, Elem);
+		break;
+	case CNTL_WAIT_JOIN:
+		CntlWaitJoinProc(pAd, Elem);
+		break;
+
+		/* CNTL_WAIT_REASSOC is the only state in CNTL machine that does */
+		/* not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)". */
+		/* Therefore not protected by NDIS's "only one outstanding OID request" */
+		/* rule. Which means NDIS may SET OID in the middle of ROAMing attempts. */
+		/* Current approach is to block new SET request at RTMPSetInformation() */
+		/* when CntlMachine.CurrState is not CNTL_IDLE */
+	case CNTL_WAIT_REASSOC:
+		CntlWaitReassocProc(pAd, Elem);
+		break;
+
+	case CNTL_WAIT_START:
+		CntlWaitStartProc(pAd, Elem);
+		break;
+	case CNTL_WAIT_AUTH:
+		CntlWaitAuthProc(pAd, Elem);
+		break;
+	case CNTL_WAIT_AUTH2:
+		CntlWaitAuthProc2(pAd, Elem);
+		break;
+	case CNTL_WAIT_ASSOC:
+		CntlWaitAssocProc(pAd, Elem);
+		break;
+
+	case CNTL_WAIT_OID_LIST_SCAN:
+		if (Elem->MsgType == MT2_SCAN_CONF) {
+			/* Resume TxRing after SCANING complete. We hope the out-of-service time */
+			/* won't be too long to let upper layer time-out the waiting frames */
+			RTMPResumeMsduTransmission(pAd);
+
+			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+
+			/* */
+			/* Set LED status to previous status. */
+			/* */
+			if (pAd->bLedOnScanning) {
+				pAd->bLedOnScanning = FALSE;
+				RTMPSetLED(pAd, pAd->LedStatus);
 			}
-			break;
-		case CNTL_WAIT_DISASSOC:
-			CntlWaitDisassocProc(pAd, Elem);
-			break;
-		case CNTL_WAIT_JOIN:
-			CntlWaitJoinProc(pAd, Elem);
-			break;
+		}
+		break;
 
-		// CNTL_WAIT_REASSOC is the only state in CNTL machine that does
-		// not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)".
-		// Therefore not protected by NDIS's "only one outstanding OID request"
-		// rule. Which means NDIS may SET OID in the middle of ROAMing attempts.
-		// Current approach is to block new SET request at RTMPSetInformation()
-		// when CntlMachine.CurrState is not CNTL_IDLE
-		case CNTL_WAIT_REASSOC:
-			CntlWaitReassocProc(pAd, Elem);
-			break;
-
-		case CNTL_WAIT_START:
-			CntlWaitStartProc(pAd, Elem);
-			break;
-		case CNTL_WAIT_AUTH:
-			CntlWaitAuthProc(pAd, Elem);
-			break;
-		case CNTL_WAIT_AUTH2:
-			CntlWaitAuthProc2(pAd, Elem);
-			break;
-		case CNTL_WAIT_ASSOC:
-			CntlWaitAssocProc(pAd, Elem);
-			break;
-
-		case CNTL_WAIT_OID_LIST_SCAN:
-			if(Elem->MsgType == MT2_SCAN_CONF)
-			{
-				// Resume TxRing after SCANING complete. We hope the out-of-service time
-				// won't be too long to let upper layer time-out the waiting frames
-				RTMPResumeMsduTransmission(pAd);
-				if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
-				{
-					// Cisco scan request is finished, prepare beacon report
-					MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
-				}
-				pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-
-                //
-				// Set LED status to previous status.
-				//
-				if (pAd->bLedOnScanning)
-				{
-					pAd->bLedOnScanning = FALSE;
-					RTMPSetLED(pAd, pAd->LedStatus);
-				}
-			}
-			break;
-
-		case CNTL_WAIT_OID_DISASSOC:
-			if (Elem->MsgType == MT2_DISASSOC_CONF)
-			{
-				LinkDown(pAd, FALSE);
-				pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-			}
-			break;
-#ifdef RT2870
-		//
-		// This state is for that we want to connect to an AP but
-		// it didn't find on BSS List table. So we need to scan the air first,
-		// after that we can try to connect to the desired AP if available.
-		//
-		case CNTL_WAIT_SCAN_FOR_CONNECT:
-			if(Elem->MsgType == MT2_SCAN_CONF)
-			{
-				// Resume TxRing after SCANING complete. We hope the out-of-service time
-				// won't be too long to let upper layer time-out the waiting frames
-				RTMPResumeMsduTransmission(pAd);
+	case CNTL_WAIT_OID_DISASSOC:
+		if (Elem->MsgType == MT2_DISASSOC_CONF) {
+			LinkDown(pAd, FALSE);
+			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+		}
+		break;
+#ifdef RTMP_MAC_USB
+		/* */
+		/* This state is for that we want to connect to an AP but */
+		/* it didn't find on BSS List table. So we need to scan the air first, */
+		/* after that we can try to connect to the desired AP if available. */
+		/* */
+	case CNTL_WAIT_SCAN_FOR_CONNECT:
+		if (Elem->MsgType == MT2_SCAN_CONF) {
+			/* Resume TxRing after SCANING complete. We hope the out-of-service time */
+			/* won't be too long to let upper layer time-out the waiting frames */
+			RTMPResumeMsduTransmission(pAd);
 #ifdef CCX_SUPPORT
-				if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
-				{
-					// Cisco scan request is finished, prepare beacon report
-					MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
-				}
-#endif // CCX_SUPPORT //
-				pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-
-				//
-				// Check if we can connect to.
-				//
-				BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
-				if (pAd->MlmeAux.SsidBssTab.BssNr > 0)
-				{
-					MlmeAutoReconnectLastSSID(pAd);
-				}
+			if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED) {
+				/* Cisco scan request is finished, prepare beacon report */
+				MlmeEnqueue(pAd, AIRONET_STATE_MACHINE,
+					    MT2_AIRONET_SCAN_DONE, 0, NULL);
 			}
-			break;
-#endif // RT2870 //
-		default:
-			DBGPRINT_ERR(("!ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType));
-			break;
+#endif /* CCX_SUPPORT // */
+			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+
+			/* */
+			/* Check if we can connect to. */
+			/* */
+			BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab,
+					 (char *) pAd->MlmeAux.
+					 AutoReconnectSsid,
+					 pAd->MlmeAux.AutoReconnectSsidLen);
+			if (pAd->MlmeAux.SsidBssTab.BssNr > 0) {
+				MlmeAutoReconnectLastSSID(pAd);
+			}
+		}
+		break;
+#endif /* RTMP_MAC_USB // */
+	default:
+		DBGPRINT_ERR(("ERROR! CNTL - Illegal message type(=%ld)",
+			      Elem->MsgType));
+		break;
 	}
 }
 
-
 /*
 	==========================================================================
 	Description:
@@ -235,92 +228,95 @@
 
 	==========================================================================
 */
-VOID CntlIdleProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void CntlIdleProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	MLME_DISASSOC_REQ_STRUCT   DisassocReq;
+	struct rt_mlme_disassoc_req DisassocReq;
 
 	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
 		return;
 
-	switch(Elem->MsgType)
-	{
-		case OID_802_11_SSID:
-			CntlOidSsidProc(pAd, Elem);
-			break;
+	switch (Elem->MsgType) {
+	case OID_802_11_SSID:
+		CntlOidSsidProc(pAd, Elem);
+		break;
 
-		case OID_802_11_BSSID:
-			CntlOidRTBssidProc(pAd,Elem);
-			break;
+	case OID_802_11_BSSID:
+		CntlOidRTBssidProc(pAd, Elem);
+		break;
 
-		case OID_802_11_BSSID_LIST_SCAN:
-			CntlOidScanProc(pAd,Elem);
-			break;
+	case OID_802_11_BSSID_LIST_SCAN:
+		CntlOidScanProc(pAd, Elem);
+		break;
 
-		case OID_802_11_DISASSOCIATE:
-			DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
-			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
+	case OID_802_11_DISASSOCIATE:
+		DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid,
+				 REASON_DISASSOC_STA_LEAVING);
+		MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
+			    sizeof(struct rt_mlme_disassoc_req), &DisassocReq);
+		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
 
-            if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI)
-            {
-    			// Set the AutoReconnectSsid to prevent it reconnect to old SSID
-    			// Since calling this indicate user don't want to connect to that SSID anymore.
-    			pAd->MlmeAux.AutoReconnectSsidLen= 32;
-    			NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
-            }
-			break;
+		if (pAd->StaCfg.WpaSupplicantUP !=
+		    WPA_SUPPLICANT_ENABLE_WITH_WEB_UI) {
+			/* Set the AutoReconnectSsid to prevent it reconnect to old SSID */
+			/* Since calling this indicate user don't want to connect to that SSID anymore. */
+			pAd->MlmeAux.AutoReconnectSsidLen = 32;
+			NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid,
+				       pAd->MlmeAux.AutoReconnectSsidLen);
+		}
+		break;
 
-		case MT2_MLME_ROAMING_REQ:
-			CntlMlmeRoamingProc(pAd, Elem);
-			break;
+	case MT2_MLME_ROAMING_REQ:
+		CntlMlmeRoamingProc(pAd, Elem);
+		break;
 
-        case OID_802_11_MIC_FAILURE_REPORT_FRAME:
-            WpaMicFailureReportFrame(pAd, Elem);
-            break;
+	case OID_802_11_MIC_FAILURE_REPORT_FRAME:
+		WpaMicFailureReportFrame(pAd, Elem);
+		break;
 
-		default:
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",Elem->MsgType));
-			break;
+	default:
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",
+			  Elem->MsgType));
+		break;
 	}
 }
 
-VOID CntlOidScanProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void CntlOidScanProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	MLME_SCAN_REQ_STRUCT       ScanReq;
-	ULONG                      BssIdx = BSS_NOT_FOUND;
-	BSS_ENTRY                  CurrBss;
+	struct rt_mlme_scan_req ScanReq;
+	unsigned long BssIdx = BSS_NOT_FOUND;
+	struct rt_bss_entry CurrBss;
 
-	// record current BSS if network is connected.
-	// 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-	{
-		BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel);
-		if (BssIdx != BSS_NOT_FOUND)
-		{
-			NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
+	/* record current BSS if network is connected. */
+	/* 2003-2-13 do not include current IBSS if this is the only STA in this IBSS. */
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
+		BssIdx =
+		    BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid,
+				       (u8 *)pAd->CommonCfg.Ssid,
+				       pAd->CommonCfg.SsidLen,
+				       pAd->CommonCfg.Channel);
+		if (BssIdx != BSS_NOT_FOUND) {
+			NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx],
+				       sizeof(struct rt_bss_entry));
 		}
 	}
-
-	// clean up previous SCAN result, add current BSS back to table if any
+	/* clean up previous SCAN result, add current BSS back to table if any */
 	BssTableInit(&pAd->ScanTab);
-	if (BssIdx != BSS_NOT_FOUND)
-	{
-		// DDK Note: If the NIC is associated with a particular BSSID and SSID
-		//    that are not contained in the list of BSSIDs generated by this scan, the
-		//    BSSID description of the currently associated BSSID and SSID should be
-		//    appended to the list of BSSIDs in the NIC's database.
-		// To ensure this, we append this BSS as the first entry in SCAN result
-		NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
+	if (BssIdx != BSS_NOT_FOUND) {
+		/* DDK Note: If the NIC is associated with a particular BSSID and SSID */
+		/*    that are not contained in the list of BSSIDs generated by this scan, the */
+		/*    BSSID description of the currently associated BSSID and SSID should be */
+		/*    appended to the list of BSSIDs in the NIC's database. */
+		/* To ensure this, we append this BSS as the first entry in SCAN result */
+		NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss,
+			       sizeof(struct rt_bss_entry));
 		pAd->ScanTab.BssNr = 1;
 	}
 
-	ScanParmFill(pAd, &ScanReq, "", 0, BSS_ANY, SCAN_ACTIVE);
+	ScanParmFill(pAd, &ScanReq, (char *)Elem->Msg, Elem->MsgLen, BSS_ANY,
+		     SCAN_ACTIVE);
 	MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
-		sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+		    sizeof(struct rt_mlme_scan_req), &ScanReq);
 	pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
 }
 
@@ -333,171 +329,174 @@
 
 	==========================================================================
 */
-VOID CntlOidSsidProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM * Elem)
+void CntlOidSsidProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	PNDIS_802_11_SSID          pOidSsid = (NDIS_802_11_SSID *)Elem->Msg;
-	MLME_DISASSOC_REQ_STRUCT   DisassocReq;
-	ULONG					   Now;
+	struct rt_ndis_802_11_ssid * pOidSsid = (struct rt_ndis_802_11_ssid *) Elem->Msg;
+	struct rt_mlme_disassoc_req DisassocReq;
+	unsigned long Now;
 
-#ifdef RT2860
-	// BBP and RF are not accessible in PS mode, we has to wake them up first
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-		AsicForceWakeup(pAd, RTMP_HALT);
-#endif
-
-	// Step 1. record the desired user settings to MlmeAux
+	/* Step 1. record the desired user settings to MlmeAux */
 	NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
 	NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
-	pAd->MlmeAux.SsidLen = (UCHAR)pOidSsid->SsidLength;
+	pAd->MlmeAux.SsidLen = (u8)pOidSsid->SsidLength;
 	NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
 	pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
 
+	pAd->StaCfg.bAutoConnectByBssid = FALSE;
 
-	//
-	// Update Reconnect Ssid, that user desired to connect.
-	//
+	/* */
+	/* Update Reconnect Ssid, that user desired to connect. */
+	/* */
 	NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
-	NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+	NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid,
+		       pAd->MlmeAux.SsidLen);
 	pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
 
-	// step 2. find all matching BSS in the lastest SCAN result (inBssTab)
-	//    & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order
-	BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+	/* step 2. find all matching BSS in the lastest SCAN result (inBssTab) */
+	/*    & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order */
+	BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab,
+			 (char *)pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
 
-	DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
-			pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
+		  pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr,
+		  pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
 	NdisGetSystemUpTime(&Now);
 
 	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
-		(pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) &&
-		NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) &&
-		MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid))
-	{
-		// Case 1. already connected with an AP who has the desired SSID
-		//         with highest RSSI
+	    (pAd->CommonCfg.SsidLen ==
+	     pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen)
+	    && NdisEqualMemory(pAd->CommonCfg.Ssid,
+			       pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid,
+			       pAd->CommonCfg.SsidLen)
+	    && MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid,
+			      pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid)) {
+		/* Case 1. already connected with an AP who has the desired SSID */
+		/*         with highest RSSI */
 
-		// Add checking Mode "LEAP" for CCX 1.0
+		/* Add checking Mode "LEAP" for CCX 1.0 */
 		if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
-			 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
-			 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
-			 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
-			 ) &&
-			(pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
-		{
-			// case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo
-			//          connection process
-			DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
-			DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
-			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
-						sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+		     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+		     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
+		     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
+		    ) &&
+		    (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)) {
+			/* case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo */
+			/*          connection process */
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
+			DisassocParmFill(pAd, &DisassocReq,
+					 pAd->CommonCfg.Bssid,
+					 REASON_DISASSOC_STA_LEAVING);
+			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
+				    MT2_MLME_DISASSOC_REQ,
+				    sizeof(struct rt_mlme_disassoc_req),
+				    &DisassocReq);
 			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
-		}
-		else if (pAd->bConfigChanged == TRUE)
-		{
-			// case 1.2 Important Config has changed, we have to reconnect to the same AP
-			DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
-			DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
-			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
-						sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+		} else if (pAd->bConfigChanged == TRUE) {
+			/* case 1.2 Important Config has changed, we have to reconnect to the same AP */
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
+			DisassocParmFill(pAd, &DisassocReq,
+					 pAd->CommonCfg.Bssid,
+					 REASON_DISASSOC_STA_LEAVING);
+			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
+				    MT2_MLME_DISASSOC_REQ,
+				    sizeof(struct rt_mlme_disassoc_req),
+				    &DisassocReq);
 			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
-		}
-		else
-		{
-			// case 1.3. already connected to the SSID with highest RSSI.
-			DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
-			//
-			// (HCT 12.1) 1c_wlan_mediaevents required
-			// media connect events are indicated when associating with the same AP
-			//
-			if (INFRA_ON(pAd))
-			{
-				//
-				// Since MediaState already is NdisMediaStateConnected
-				// We just indicate the connect event again to meet the WHQL required.
-				//
-				pAd->IndicateMediaState = NdisMediaStateConnected;
+		} else {
+			/* case 1.3. already connected to the SSID with highest RSSI. */
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
+			/* */
+			/* (HCT 12.1) 1c_wlan_mediaevents required */
+			/* media connect events are indicated when associating with the same AP */
+			/* */
+			if (INFRA_ON(pAd)) {
+				/* */
+				/* Since MediaState already is NdisMediaStateConnected */
+				/* We just indicate the connect event again to meet the WHQL required. */
+				/* */
+				pAd->IndicateMediaState =
+				    NdisMediaStateConnected;
 				RTMP_IndicateMediaState(pAd);
-                pAd->ExtraInfo = GENERAL_LINK_UP;   // Update extra information to link is up
+				pAd->ExtraInfo = GENERAL_LINK_UP;	/* Update extra information to link is up */
 			}
 
 			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-
-            {
-                union iwreq_data    wrqu;
-
-                memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
-                memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
-                wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
-
-            }
+			RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1,
+						&pAd->MlmeAux.Bssid[0], NULL,
+						0);
 		}
-	}
-	else if (INFRA_ON(pAd))
-	{
-		//
-		// For RT61
-		// [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
-		// RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect
-		// But media status is connected, so the SSID not report correctly.
-		//
-		if (!SSID_EQUAL(pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen))
-		{
-			//
-			// Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event.
-			//
+	} else if (INFRA_ON(pAd)) {
+		/* */
+		/* For RT61 */
+		/* [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: ) */
+		/* RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect */
+		/* But media status is connected, so the SSID not report correctly. */
+		/* */
+		if (!SSID_EQUAL
+		    (pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen,
+		     pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen)) {
+			/* */
+			/* Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event. */
+			/* */
 			pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
 		}
-		// case 2. active INFRA association existent
-		//    roaming is done within miniport driver, nothing to do with configuration
-		//    utility. so upon a new SET(OID_802_11_SSID) is received, we just
-		//    disassociate with the current associated AP,
-		//    then perform a new association with this new SSID, no matter the
-		//    new/old SSID are the same or not.
-		DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
-		DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
+		/* case 2. active INFRA association existent */
+		/*    roaming is done within miniport driver, nothing to do with configuration */
+		/*    utility. so upon a new SET(OID_802_11_SSID) is received, we just */
+		/*    disassociate with the current associated AP, */
+		/*    then perform a new association with this new SSID, no matter the */
+		/*    new/old SSID are the same or not. */
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
+		DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid,
+				 REASON_DISASSOC_STA_LEAVING);
 		MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
-					sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+			    sizeof(struct rt_mlme_disassoc_req), &DisassocReq);
 		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
-	}
-	else
-	{
-		if (ADHOC_ON(pAd))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
+	} else {
+		if (ADHOC_ON(pAd)) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
 			LinkDown(pAd, FALSE);
-			OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+			OPSTATUS_CLEAR_FLAG(pAd,
+					    fOP_STATUS_MEDIA_STATE_CONNECTED);
 			pAd->IndicateMediaState = NdisMediaStateDisconnected;
 			RTMP_IndicateMediaState(pAd);
-            pAd->ExtraInfo = GENERAL_LINK_DOWN;
-			DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
+			pAd->ExtraInfo = GENERAL_LINK_DOWN;
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
 		}
 
 		if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
-			(pAd->StaCfg.bAutoReconnect == TRUE) &&
-			(pAd->MlmeAux.BssType == BSS_INFRA) &&
-			(MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) == TRUE)
-			)
-		{
-			MLME_SCAN_REQ_STRUCT       ScanReq;
+		    (pAd->StaCfg.bAutoReconnect == TRUE) &&
+		    (pAd->MlmeAux.BssType == BSS_INFRA) &&
+		    (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen)
+		     == TRUE)
+		    ) {
+			struct rt_mlme_scan_req ScanReq;
 
-			DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
-			ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
-			MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
-			// Reset Missed scan number
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
+			ScanParmFill(pAd, &ScanReq, (char *)pAd->MlmeAux.Ssid,
+				     pAd->MlmeAux.SsidLen, BSS_ANY,
+				     SCAN_ACTIVE);
+			MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
+				    sizeof(struct rt_mlme_scan_req), &ScanReq);
+			pAd->Mlme.CntlMachine.CurrState =
+			    CNTL_WAIT_OID_LIST_SCAN;
+			/* Reset Missed scan number */
 			pAd->StaCfg.LastScanTime = Now;
-		}
-		else
-		{
+		} else {
 			pAd->MlmeAux.BssIdx = 0;
 			IterateOnBssTab(pAd);
 		}
 	}
 }
 
-
 /*
 	==========================================================================
 	Description:
@@ -506,165 +505,196 @@
 
 	==========================================================================
 */
-VOID CntlOidRTBssidProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM * Elem)
+void CntlOidRTBssidProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	ULONG       BssIdx;
-	PUCHAR      pOidBssid = (PUCHAR)Elem->Msg;
-	MLME_DISASSOC_REQ_STRUCT    DisassocReq;
-	MLME_JOIN_REQ_STRUCT        JoinReq;
+	unsigned long BssIdx;
+	u8 *pOidBssid = (u8 *)Elem->Msg;
+	struct rt_mlme_disassoc_req DisassocReq;
+	struct rt_mlme_join_req JoinReq;
 
-	// record user desired settings
+	/* record user desired settings */
 	COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
 	pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
 
-	//
-	// Update Reconnect Ssid, that user desired to connect.
-	//
-	NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
-	pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
-	NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
-
-	// find the desired BSS in the latest SCAN result table
+	/* find the desired BSS in the latest SCAN result table */
 	BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
-	if (BssIdx == BSS_NOT_FOUND)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
-		pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+	if (BssIdx == BSS_NOT_FOUND) {
+		struct rt_mlme_scan_req ScanReq;
+
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
+		/*pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; */
+
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("CNTL - BSSID not found. start a new scan\n"));
+		ScanParmFill(pAd, &ScanReq, (char *)pAd->MlmeAux.Ssid,
+			     pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
+		MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
+			    sizeof(struct rt_mlme_scan_req), &ScanReq);
+		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+		/* Reset Missed scan number */
+		NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime);
 		return;
 	}
+	/* */
+	/* Update Reconnect Ssid, that user desired to connect. */
+	/* */
+	NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
+	pAd->MlmeAux.AutoReconnectSsidLen =
+	    pAd->ScanTab.BssEntry[BssIdx].SsidLen;
+	NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid,
+		       pAd->ScanTab.BssEntry[BssIdx].Ssid,
+		       pAd->ScanTab.BssEntry[BssIdx].SsidLen);
 
-	// copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why?
-	// Because we need this entry to become the JOIN target in later on SYNC state machine
+	/* copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why? */
+	/* Because we need this entry to become the JOIN target in later on SYNC state machine */
 	pAd->MlmeAux.BssIdx = 0;
 	pAd->MlmeAux.SsidBssTab.BssNr = 1;
-	NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
+	NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0],
+		       &pAd->ScanTab.BssEntry[BssIdx], sizeof(struct rt_bss_entry));
 
-	// 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
-	//   we just follow normal procedure. The reason of user doing this may because he/she changed
-	//   AP to another channel, but we still received BEACON from it thus don't claim Link Down.
-	//   Since user knows he's changed AP channel, he'll re-connect again. By skipping the following
-	//   checking, we'll disassociate then re-do normal association with this AP at the new channel.
-	// 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
-	//   connection when setting the same BSSID.
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
-		MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid))
+	/* Add SSID into MlmeAux for site surey joining hidden SSID */
+	pAd->MlmeAux.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
+	NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid,
+		       pAd->MlmeAux.SsidLen);
+
 	{
-		// already connected to the same BSSID, go back to idle state directly
-		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n"));
-		pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-
-            {
-                union iwreq_data    wrqu;
-
-                memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
-                memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
-                wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
-
-            }
-	}
-	else
-	{
-		if (INFRA_ON(pAd))
-		{
-			// disassoc from current AP first
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
-			DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
-			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
-						sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+		if (INFRA_ON(pAd)) {
+			/* disassoc from current AP first */
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("CNTL - disassociate with current AP ...\n"));
+			DisassocParmFill(pAd, &DisassocReq,
+					 pAd->CommonCfg.Bssid,
+					 REASON_DISASSOC_STA_LEAVING);
+			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
+				    MT2_MLME_DISASSOC_REQ,
+				    sizeof(struct rt_mlme_disassoc_req),
+				    &DisassocReq);
 
 			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
-		}
-		else
-		{
-			if (ADHOC_ON(pAd))
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
+		} else {
+			if (ADHOC_ON(pAd)) {
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("CNTL - drop current ADHOC\n"));
 				LinkDown(pAd, FALSE);
-				OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
-				pAd->IndicateMediaState = NdisMediaStateDisconnected;
+				OPSTATUS_CLEAR_FLAG(pAd,
+						    fOP_STATUS_MEDIA_STATE_CONNECTED);
+				pAd->IndicateMediaState =
+				    NdisMediaStateDisconnected;
 				RTMP_IndicateMediaState(pAd);
-                pAd->ExtraInfo = GENERAL_LINK_DOWN;
-				DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
+				pAd->ExtraInfo = GENERAL_LINK_DOWN;
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
 			}
-
-			// Change the wepstatus to original wepstatus
-			pAd->StaCfg.WepStatus   = pAd->StaCfg.OrigWepStatus;
-			pAd->StaCfg.PairCipher  = pAd->StaCfg.OrigWepStatus;
+			/* Change the wepstatus to original wepstatus */
+			pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
+			pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
 			pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
 
-			// Check cipher suite, AP must have more secured cipher than station setting
-			// Set the Pairwise and Group cipher to match the intended AP setting
-			// We can only connect to AP with less secured cipher setting
-			if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
-			{
-				pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
+			/* Check cipher suite, AP must have more secured cipher than station setting */
+			/* Set the Pairwise and Group cipher to match the intended AP setting */
+			/* We can only connect to AP with less secured cipher setting */
+			if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA)
+			    || (pAd->StaCfg.AuthMode ==
+				Ndis802_11AuthModeWPAPSK)) {
+				pAd->StaCfg.GroupCipher =
+				    pAd->ScanTab.BssEntry[BssIdx].WPA.
+				    GroupCipher;
 
-				if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
-					pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
-				else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
-					pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
-				else	// There is no PairCipher Aux, downgrade our capability to TKIP
-					pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
+				if (pAd->StaCfg.WepStatus ==
+				    pAd->ScanTab.BssEntry[BssIdx].WPA.
+				    PairCipher)
+					pAd->StaCfg.PairCipher =
+					    pAd->ScanTab.BssEntry[BssIdx].WPA.
+					    PairCipher;
+				else if (pAd->ScanTab.BssEntry[BssIdx].WPA.
+					 PairCipherAux != Ndis802_11WEPDisabled)
+					pAd->StaCfg.PairCipher =
+					    pAd->ScanTab.BssEntry[BssIdx].WPA.
+					    PairCipherAux;
+				else	/* There is no PairCipher Aux, downgrade our capability to TKIP */
+					pAd->StaCfg.PairCipher =
+					    Ndis802_11Encryption2Enabled;
+			} else
+			    if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
+				|| (pAd->StaCfg.AuthMode ==
+				    Ndis802_11AuthModeWPA2PSK)) {
+				pAd->StaCfg.GroupCipher =
+				    pAd->ScanTab.BssEntry[BssIdx].WPA2.
+				    GroupCipher;
+
+				if (pAd->StaCfg.WepStatus ==
+				    pAd->ScanTab.BssEntry[BssIdx].WPA2.
+				    PairCipher)
+					pAd->StaCfg.PairCipher =
+					    pAd->ScanTab.BssEntry[BssIdx].WPA2.
+					    PairCipher;
+				else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.
+					 PairCipherAux != Ndis802_11WEPDisabled)
+					pAd->StaCfg.PairCipher =
+					    pAd->ScanTab.BssEntry[BssIdx].WPA2.
+					    PairCipherAux;
+				else	/* There is no PairCipher Aux, downgrade our capability to TKIP */
+					pAd->StaCfg.PairCipher =
+					    Ndis802_11Encryption2Enabled;
+
+				/* RSN capability */
+				pAd->StaCfg.RsnCapability =
+				    pAd->ScanTab.BssEntry[BssIdx].WPA2.
+				    RsnCapability;
 			}
-			else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
-			{
-				pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
-
-				if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
-					pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
-				else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
-					pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
-				else	// There is no PairCipher Aux, downgrade our capability to TKIP
-					pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
-
-				// RSN capability
-				pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
-			}
-
-			// Set Mix cipher flag
-			pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
-			if (pAd->StaCfg.bMixCipher == TRUE)
-			{
-				// If mix cipher, re-build RSNIE
-				RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
-			}
-			// No active association, join the BSS immediately
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
-				pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
+			/* Set Mix cipher flag */
+			pAd->StaCfg.bMixCipher =
+			    (pAd->StaCfg.PairCipher ==
+			     pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
+			/*if (pAd->StaCfg.bMixCipher == TRUE)
+			   {
+			   // If mix cipher, re-build RSNIE
+			   RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
+			   } */
+			/* No active association, join the BSS immediately */
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
+				  pOidBssid[0], pOidBssid[1], pOidBssid[2],
+				  pOidBssid[3], pOidBssid[4], pOidBssid[5]));
 
 			JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
-			MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
+			MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ,
+				    sizeof(struct rt_mlme_join_req), &JoinReq);
 
 			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
 		}
 	}
 }
 
-// Roaming is the only external request triggering CNTL state machine
-// despite of other "SET OID" operation. All "SET OID" related oerations
-// happen in sequence, because no other SET OID will be sent to this device
-// until the the previous SET operation is complete (successful o failed).
-// So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
-// or been corrupted by other "SET OID"?
-//
-// IRQL = DISPATCH_LEVEL
-VOID CntlMlmeRoamingProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+/* Roaming is the only external request triggering CNTL state machine */
+/* despite of other "SET OID" operation. All "SET OID" related oerations */
+/* happen in sequence, because no other SET OID will be sent to this device */
+/* until the the previous SET operation is complete (successful o failed). */
+/* So, how do we quarantee this ROAMING request won't corrupt other "SET OID"? */
+/* or been corrupted by other "SET OID"? */
+/* */
+/* IRQL = DISPATCH_LEVEL */
+void CntlMlmeRoamingProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	// TODO:
-	// AP in different channel may show lower RSSI than actual value??
-	// should we add a weighting factor to compensate it?
-	DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
+	u8 BBPValue = 0;
 
-	NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
-	pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
+	DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Roaming in MlmeAux.RoamTab...\n"));
 
-	BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
-	pAd->MlmeAux.BssIdx = 0;
-	IterateOnBssTab(pAd);
+	{
+		/*Let BBP register at 20MHz to do (fast) roaming. */
+		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+		BBPValue &= (~0x18);
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+
+		NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab,
+			       sizeof(pAd->MlmeAux.RoamTab));
+		pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
+
+		BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
+		pAd->MlmeAux.BssIdx = 0;
+		IterateOnBssTab(pAd);
+	}
 }
 
 /*
@@ -675,34 +705,35 @@
 
 	==========================================================================
 */
-VOID CntlWaitDisassocProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void CntlWaitDisassocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	MLME_START_REQ_STRUCT     StartReq;
+	struct rt_mlme_start_req StartReq;
 
-	if (Elem->MsgType == MT2_DISASSOC_CONF)
-	{
+	if (Elem->MsgType == MT2_DISASSOC_CONF) {
 		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
 
-	    if (pAd->CommonCfg.bWirelessEvent)
-		{
-			RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+		if (pAd->CommonCfg.bWirelessEvent) {
+			RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG,
+					      pAd->MacTab.Content[BSSID_WCID].
+					      Addr, BSS0, 0);
 		}
 
 		LinkDown(pAd, FALSE);
 
-		// case 1. no matching BSS, and user wants ADHOC, so we just start a new one
-		if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
-			StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
-			MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
+		/* case 1. no matching BSS, and user wants ADHOC, so we just start a new one */
+		if ((pAd->MlmeAux.SsidBssTab.BssNr == 0)
+		    && (pAd->StaCfg.BssType == BSS_ADHOC)) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",
+				  pAd->MlmeAux.Ssid));
+			StartParmFill(pAd, &StartReq, (char *)pAd->MlmeAux.Ssid,
+				      pAd->MlmeAux.SsidLen);
+			MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ,
+				    sizeof(struct rt_mlme_start_req), &StartReq);
 			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
 		}
-		// case 2. try each matched BSS
-		else
-		{
+		/* case 2. try each matched BSS */
+		else {
 			pAd->MlmeAux.BssIdx = 0;
 
 			IterateOnBssTab(pAd);
@@ -718,74 +749,81 @@
 
 	==========================================================================
 */
-VOID CntlWaitJoinProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void CntlWaitJoinProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	USHORT                      Reason;
-	MLME_AUTH_REQ_STRUCT        AuthReq;
+	u16 Reason;
+	struct rt_mlme_auth_req AuthReq;
 
-	if (Elem->MsgType == MT2_JOIN_CONF)
-	{
-		NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
-		if (Reason == MLME_SUCCESS)
-		{
-			// 1. joined an IBSS, we are pretty much done here
-			if (pAd->MlmeAux.BssType == BSS_ADHOC)
-			{
-			    //
-				// 5G bands rules of Japan:
-				// Ad hoc must be disabled in W53(ch52,56,60,64) channels.
-				//
-				if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
-                      RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
-				   )
-				{
-					pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-					DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
+	if (Elem->MsgType == MT2_JOIN_CONF) {
+		NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16));
+		if (Reason == MLME_SUCCESS) {
+			/* 1. joined an IBSS, we are pretty much done here */
+			if (pAd->MlmeAux.BssType == BSS_ADHOC) {
+				/* */
+				/* 5G bands rules of Japan: */
+				/* Ad hoc must be disabled in W53(ch52,56,60,64) channels. */
+				/* */
+				if ((pAd->CommonCfg.bIEEE80211H == 1) &&
+				    RadarChannelCheck(pAd,
+						      pAd->CommonCfg.Channel)
+				    ) {
+					pAd->Mlme.CntlMachine.CurrState =
+					    CNTL_IDLE;
+					DBGPRINT(RT_DEBUG_TRACE,
+						 ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n",
+						  pAd->CommonCfg.Channel));
 					return;
 				}
 
 				LinkUp(pAd, BSS_ADHOC);
 				pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-				DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
-				pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
-				pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
+					  pAd->CommonCfg.Bssid[0],
+					  pAd->CommonCfg.Bssid[1],
+					  pAd->CommonCfg.Bssid[2],
+					  pAd->CommonCfg.Bssid[3],
+					  pAd->CommonCfg.Bssid[4],
+					  pAd->CommonCfg.Bssid[5]));
 
-                pAd->IndicateMediaState = NdisMediaStateConnected;
-                pAd->ExtraInfo = GENERAL_LINK_UP;
+				pAd->IndicateMediaState =
+				    NdisMediaStateConnected;
+				pAd->ExtraInfo = GENERAL_LINK_UP;
 			}
-			// 2. joined a new INFRA network, start from authentication
-			else
-			{
+			/* 2. joined a new INFRA network, start from authentication */
+			else {
 				{
-					// either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
-					if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
-						(pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
-					{
-						AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
+					/* either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first */
+					if ((pAd->StaCfg.AuthMode ==
+					     Ndis802_11AuthModeShared)
+					    || (pAd->StaCfg.AuthMode ==
+						Ndis802_11AuthModeAutoSwitch)) {
+						AuthParmFill(pAd, &AuthReq,
+							     pAd->MlmeAux.Bssid,
+							     AUTH_MODE_KEY);
+					} else {
+						AuthParmFill(pAd, &AuthReq,
+							     pAd->MlmeAux.Bssid,
+							     AUTH_MODE_OPEN);
 					}
-					else
-					{
-						AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
-					}
+					MlmeEnqueue(pAd, AUTH_STATE_MACHINE,
+						    MT2_MLME_AUTH_REQ,
+						    sizeof
+						    (struct rt_mlme_auth_req),
+						    &AuthReq);
 				}
-				MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
-							sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
 
-				pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
+				pAd->Mlme.CntlMachine.CurrState =
+				    CNTL_WAIT_AUTH;
 			}
-		}
-		else
-		{
-			// 3. failed, try next BSS
+		} else {
+			/* 3. failed, try next BSS */
 			pAd->MlmeAux.BssIdx++;
 			IterateOnBssTab(pAd);
 		}
 	}
 }
 
-
 /*
 	==========================================================================
 	Description:
@@ -794,74 +832,86 @@
 
 	==========================================================================
 */
-VOID CntlWaitStartProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void CntlWaitStartProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	USHORT      Result;
+	u16 Result;
 
-	if (Elem->MsgType == MT2_START_CONF)
-	{
-		NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
-		if (Result == MLME_SUCCESS)
-		{
-		    //
-			// 5G bands rules of Japan:
-			// Ad hoc must be disabled in W53(ch52,56,60,64) channels.
-			//
-			if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
-                  RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
-			   )
-			{
+	if (Elem->MsgType == MT2_START_CONF) {
+		NdisMoveMemory(&Result, Elem->Msg, sizeof(u16));
+		if (Result == MLME_SUCCESS) {
+			/* */
+			/* 5G bands rules of Japan: */
+			/* Ad hoc must be disabled in W53(ch52,56,60,64) channels. */
+			/* */
+			if ((pAd->CommonCfg.bIEEE80211H == 1) &&
+			    RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
+			    ) {
 				pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-				DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n",
+					  pAd->CommonCfg.Channel));
 				return;
 			}
-
-			if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
-			{
+			NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.
+				       MCSSet[0], 16);
+			if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) {
 				N_ChannelCheck(pAd);
 				SetCommonHT(pAd);
-				NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
-				RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
-				pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
-				NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
-				NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
-				COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
+				NdisMoveMemory(&pAd->MlmeAux.AddHtInfo,
+					       &pAd->CommonCfg.AddHTInfo,
+					       sizeof(struct rt_add_ht_info_ie));
+				RTMPCheckHt(pAd, BSSID_WCID,
+					    &pAd->CommonCfg.HtCapability,
+					    &pAd->CommonCfg.AddHTInfo);
+				pAd->StaActive.SupportedPhyInfo.bHtEnable =
+				    TRUE;
+				NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.
+					       MCSSet[0],
+					       &pAd->CommonCfg.HtCapability.
+					       MCSSet[0], 16);
+				COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG
+				    (pAd);
 
-				if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth  == BW_40) &&
-					(pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
-				{
-					pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
+				if ((pAd->CommonCfg.HtCapability.HtCapInfo.
+				     ChannelWidth == BW_40)
+				    && (pAd->CommonCfg.AddHTInfo.AddHtInfo.
+					ExtChanOffset == EXTCHA_ABOVE)) {
+					pAd->MlmeAux.CentralChannel =
+					    pAd->CommonCfg.Channel + 2;
+				} else
+				    if ((pAd->CommonCfg.HtCapability.HtCapInfo.
+					 ChannelWidth == BW_40)
+					&& (pAd->CommonCfg.AddHTInfo.AddHtInfo.
+					    ExtChanOffset == EXTCHA_BELOW)) {
+					pAd->MlmeAux.CentralChannel =
+					    pAd->CommonCfg.Channel - 2;
 				}
-				else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth  == BW_40) &&
-						 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
-				{
-					pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
-				}
-			}
-			else
-			{
-				pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
+			} else {
+				pAd->StaActive.SupportedPhyInfo.bHtEnable =
+				    FALSE;
 			}
 			LinkUp(pAd, BSS_ADHOC);
 			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-			// Before send beacon, driver need do radar detection
-			if ((pAd->CommonCfg.Channel > 14 )
-				&& (pAd->CommonCfg.bIEEE80211H == 1)
-				&& RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
-			{
-				pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
+			/* Before send beacon, driver need do radar detection */
+			if ((pAd->CommonCfg.Channel > 14)
+			    && (pAd->CommonCfg.bIEEE80211H == 1)
+			    && RadarChannelCheck(pAd, pAd->CommonCfg.Channel)) {
+				pAd->CommonCfg.RadarDetect.RDMode =
+				    RD_SILENCE_MODE;
 				pAd->CommonCfg.RadarDetect.RDCount = 0;
 			}
 
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
-				pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
-				pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
-		}
-		else
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
+				  pAd->CommonCfg.Bssid[0],
+				  pAd->CommonCfg.Bssid[1],
+				  pAd->CommonCfg.Bssid[2],
+				  pAd->CommonCfg.Bssid[3],
+				  pAd->CommonCfg.Bssid[4],
+				  pAd->CommonCfg.Bssid[5]));
+		} else {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("CNTL - Start IBSS fail. BUG!\n"));
 			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
 		}
 	}
@@ -875,52 +925,57 @@
 
 	==========================================================================
 */
-VOID CntlWaitAuthProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void CntlWaitAuthProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	USHORT                       Reason;
-	MLME_ASSOC_REQ_STRUCT        AssocReq;
-	MLME_AUTH_REQ_STRUCT         AuthReq;
+	u16 Reason;
+	struct rt_mlme_assoc_req AssocReq;
+	struct rt_mlme_auth_req AuthReq;
 
-	if (Elem->MsgType == MT2_AUTH_CONF)
-	{
-		NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
-		if (Reason == MLME_SUCCESS)
-		{
+	if (Elem->MsgType == MT2_AUTH_CONF) {
+		NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16));
+		if (Reason == MLME_SUCCESS) {
 			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
-			AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
-						  ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
+			AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid,
+				      pAd->MlmeAux.CapabilityInfo,
+				      ASSOC_TIMEOUT,
+				      pAd->StaCfg.DefaultListenCount);
 
 			{
-				MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
-							sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
+				MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
+					    MT2_MLME_ASSOC_REQ,
+					    sizeof(struct rt_mlme_assoc_req),
+					    &AssocReq);
 
-				pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
+				pAd->Mlme.CntlMachine.CurrState =
+				    CNTL_WAIT_ASSOC;
 			}
-		}
-		else
-		{
-			// This fail may because of the AP already keep us in its MAC table without
-			// ageing-out. The previous authentication attempt must have let it remove us.
-			// so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
+		} else {
+			/* This fail may because of the AP already keep us in its MAC table without */
+			/* ageing-out. The previous authentication attempt must have let it remove us. */
+			/* so try Authentication again may help. For D-Link DWL-900AP+ compatibility. */
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("CNTL - AUTH FAIL, try again...\n"));
 
 			{
-				if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
-					(pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
-				{
-					// either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
-					AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
+				if ((pAd->StaCfg.AuthMode ==
+				     Ndis802_11AuthModeShared)
+				    || (pAd->StaCfg.AuthMode ==
+					Ndis802_11AuthModeAutoSwitch)) {
+					/* either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first */
+					AuthParmFill(pAd, &AuthReq,
+						     pAd->MlmeAux.Bssid,
+						     AUTH_MODE_KEY);
+				} else {
+					AuthParmFill(pAd, &AuthReq,
+						     pAd->MlmeAux.Bssid,
+						     AUTH_MODE_OPEN);
 				}
-				else
-				{
-					AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
-				}
-			}
-			MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
-						sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
+				MlmeEnqueue(pAd, AUTH_STATE_MACHINE,
+					    MT2_MLME_AUTH_REQ,
+					    sizeof(struct rt_mlme_auth_req),
+					    &AuthReq);
 
+			}
 			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
 		}
 	}
@@ -934,44 +989,49 @@
 
 	==========================================================================
 */
-VOID CntlWaitAuthProc2(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void CntlWaitAuthProc2(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	USHORT                       Reason;
-	MLME_ASSOC_REQ_STRUCT        AssocReq;
-	MLME_AUTH_REQ_STRUCT         AuthReq;
+	u16 Reason;
+	struct rt_mlme_assoc_req AssocReq;
+	struct rt_mlme_auth_req AuthReq;
 
-	if (Elem->MsgType == MT2_AUTH_CONF)
-	{
-		NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
-		if (Reason == MLME_SUCCESS)
-		{
+	if (Elem->MsgType == MT2_AUTH_CONF) {
+		NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16));
+		if (Reason == MLME_SUCCESS) {
 			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
-			AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
-						  ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
-			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
-						sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
-
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
-		}
-		else
-		{
-			if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
-				 (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
+			AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid,
+				      pAd->MlmeAux.CapabilityInfo,
+				      ASSOC_TIMEOUT,
+				      pAd->StaCfg.DefaultListenCount);
 			{
-				DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
-				AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
-				MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
-							sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
+				MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
+					    MT2_MLME_ASSOC_REQ,
+					    sizeof(struct rt_mlme_assoc_req),
+					    &AssocReq);
 
-				pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
+				pAd->Mlme.CntlMachine.CurrState =
+				    CNTL_WAIT_ASSOC;
 			}
-			else
-			{
-				// not success, try next BSS
-				DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
-				pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
+		} else {
+			if ((pAd->StaCfg.AuthMode ==
+			     Ndis802_11AuthModeAutoSwitch)
+			    && (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared)) {
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("CNTL - AUTH FAIL, try OPEN system...\n"));
+				AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid,
+					     Ndis802_11AuthModeOpen);
+				MlmeEnqueue(pAd, AUTH_STATE_MACHINE,
+					    MT2_MLME_AUTH_REQ,
+					    sizeof(struct rt_mlme_auth_req),
+					    &AuthReq);
+
+				pAd->Mlme.CntlMachine.CurrState =
+				    CNTL_WAIT_AUTH2;
+			} else {
+				/* not success, try next BSS */
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("CNTL - AUTH FAIL, give up; try next BSS\n"));
+				pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;	/*??????? */
 				pAd->MlmeAux.BssIdx++;
 				IterateOnBssTab(pAd);
 			}
@@ -987,30 +1047,30 @@
 
 	==========================================================================
 */
-VOID CntlWaitAssocProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void CntlWaitAssocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	USHORT      Reason;
+	u16 Reason;
 
-	if (Elem->MsgType == MT2_ASSOC_CONF)
-	{
-		NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
-		if (Reason == MLME_SUCCESS)
-		{
+	if (Elem->MsgType == MT2_ASSOC_CONF) {
+		NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16));
+		if (Reason == MLME_SUCCESS) {
+			if (pAd->CommonCfg.bWirelessEvent) {
+				RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG,
+						      pAd->MacTab.
+						      Content[BSSID_WCID].Addr,
+						      BSS0, 0);
+			}
+
 			LinkUp(pAd, BSS_INFRA);
 			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
-
-			if (pAd->CommonCfg.bWirelessEvent)
-			{
-				RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-			}
-		}
-		else
-		{
-			// not success, try next BSS
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("CNTL - Association successful on BSS #%ld\n",
+				  pAd->MlmeAux.BssIdx));
+		} else {
+			/* not success, try next BSS */
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("CNTL - Association fails on BSS #%ld\n",
+				  pAd->MlmeAux.BssIdx));
 			pAd->MlmeAux.BssIdx++;
 			IterateOnBssTab(pAd);
 		}
@@ -1025,52 +1085,51 @@
 
 	==========================================================================
 */
-VOID CntlWaitReassocProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void CntlWaitReassocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	USHORT      Result;
+	u16 Result;
 
-	if (Elem->MsgType == MT2_REASSOC_CONF)
-	{
-		NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
-		if (Result == MLME_SUCCESS)
-		{
-			//
-			// NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
-			//
+	if (Elem->MsgType == MT2_REASSOC_CONF) {
+		NdisMoveMemory(&Result, Elem->Msg, sizeof(u16));
+		if (Result == MLME_SUCCESS) {
+			/* send wireless event - for association */
+			if (pAd->CommonCfg.bWirelessEvent)
+				RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG,
+						      pAd->MacTab.
+						      Content[BSSID_WCID].Addr,
+						      BSS0, 0);
+
+			/* */
+			/* NDIS requires a new Link UP indication but no Link Down for RE-ASSOC */
+			/* */
 			LinkUp(pAd, BSS_INFRA);
 
-			// send wireless event - for association
-			if (pAd->CommonCfg.bWirelessEvent)
-				RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-
 			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
-		}
-		else
-		{
-			// reassoc failed, try to pick next BSS in the BSS Table
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
-			pAd->MlmeAux.RoamIdx++;
-			IterateOnBssTab2(pAd);
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("CNTL - Re-assocition successful on BSS #%ld\n",
+				  pAd->MlmeAux.RoamIdx));
+		} else {
+			/* reassoc failed, try to pick next BSS in the BSS Table */
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("CNTL - Re-assocition fails on BSS #%ld\n",
+				  pAd->MlmeAux.RoamIdx));
+			{
+				pAd->MlmeAux.RoamIdx++;
+				IterateOnBssTab2(pAd);
+			}
 		}
 	}
 }
 
-
-#ifdef RT2870
-VOID	AdhocTurnOnQos(
-	IN  PRTMP_ADAPTER pAd)
+void AdhocTurnOnQos(struct rt_rtmp_adapter *pAd)
 {
 #define AC0_DEF_TXOP		0
 #define AC1_DEF_TXOP		0
 #define AC2_DEF_TXOP		94
 #define AC3_DEF_TXOP		47
 
-	// Turn on QOs if use HT rate.
-	if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
-	{
+	/* Turn on QOs if use HT rate. */
+	if (pAd->CommonCfg.APEdcaParm.bValid == FALSE) {
 		pAd->CommonCfg.APEdcaParm.bValid = TRUE;
 		pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
 		pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
@@ -1087,14 +1146,13 @@
 		pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
 		pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
 
-		pAd->CommonCfg.APEdcaParm.Txop[0]  = 0;
-		pAd->CommonCfg.APEdcaParm.Txop[1]  = 0;
-		pAd->CommonCfg.APEdcaParm.Txop[2]  = AC2_DEF_TXOP;
-		pAd->CommonCfg.APEdcaParm.Txop[3]  = AC3_DEF_TXOP;
+		pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
+		pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
+		pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP;
+		pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP;
 	}
 	AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
 }
-#endif /* RT2870 */
 
 /*
 	==========================================================================
@@ -1104,110 +1162,81 @@
 
 	==========================================================================
 */
-VOID LinkUp(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR BssType)
+void LinkUp(struct rt_rtmp_adapter *pAd, u8 BssType)
 {
-	ULONG	Now;
-	UINT32	Data;
-	BOOLEAN	Cancelled;
-	UCHAR	Value = 0, idx;
-	MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
+	unsigned long Now;
+	u32 Data;
+	BOOLEAN Cancelled;
+	u8 Value = 0, idx = 0, HashIdx = 0;
+	struct rt_mac_table_entry *pEntry = NULL, *pCurrEntry = NULL;
 
-#ifdef RT2860
-	if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
-	{
-		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
-		RTMPusecDelay(6000);
-		pAd->bPCIclkOff = FALSE;
+	/* Init ChannelQuality to prevent DEAD_CQI at initial LinkUp */
+	pAd->Mlme.ChannelQuality = 50;
+
+	pEntry = MacTableLookup(pAd, pAd->CommonCfg.Bssid);
+	if (pEntry) {
+		MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
+		pEntry = NULL;
 	}
-#endif
 
 	pEntry = &pAd->MacTab.Content[BSSID_WCID];
 
-	//
-	// ASSOC - DisassocTimeoutAction
-	// CNTL - Dis-associate successful
-	// !!! LINK DOWN !!!
-	// [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
-	//
-	// To prevent DisassocTimeoutAction to call Link down after we link up,
-	// cancel the DisassocTimer no matter what it start or not.
-	//
-	RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer,  &Cancelled);
+	/* */
+	/* ASSOC - DisassocTimeoutAction */
+	/* CNTL - Dis-associate successful */
+	/* ! LINK DOWN ! */
+	/* [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: ) */
+	/* */
+	/* To prevent DisassocTimeoutAction to call Link down after we link up, */
+	/* cancel the DisassocTimer no matter what it start or not. */
+	/* */
+	RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
 
 	COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
 
 	COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
 
-	// It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS
-	// is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place
-	// to examine if cipher algorithm switching is required.
-	//rt2860b. Don't know why need this
-	SwitchBetweenWepAndCkip(pAd);
-
-#ifdef RT2860
-	// Before power save before link up function, We will force use 1R.
-	// So after link up, check Rx antenna # again.
+#ifdef RTMP_MAC_PCI
+	/* Before power save before link up function, We will force use 1R. */
+	/* So after link up, check Rx antenna # again. */
 	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
-	if(pAd->Antenna.field.RxPath == 3)
-	{
+	if (pAd->Antenna.field.RxPath == 3) {
 		Value |= (0x10);
-	}
-	else if(pAd->Antenna.field.RxPath == 2)
-	{
+	} else if (pAd->Antenna.field.RxPath == 2) {
 		Value |= (0x8);
-	}
-	else if(pAd->Antenna.field.RxPath == 1)
-	{
+	} else if (pAd->Antenna.field.RxPath == 1) {
 		Value |= (0x0);
 	}
 	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
 	pAd->StaCfg.BBPR3 = Value;
-#endif /* RT2860 */
+#endif /* RTMP_MAC_PCI // */
 
-	if (BssType == BSS_ADHOC)
-	{
+	if (BssType == BSS_ADHOC) {
 		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
 		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
 
-		if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth  == BW_40) &&
-			(pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
-		{
-			pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
-		}
-		else if ((pAd->CommonCfg.Channel > 2) &&
-				 (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth  == BW_40) &&
-				 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
-		{
-			pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
-		}
-#ifdef RT2870
 		if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
 			AdhocTurnOnQos(pAd);
-#endif
 
-		DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
-	}
-	else
-	{
+		DBGPRINT(RT_DEBUG_TRACE, ("Adhoc LINK UP!\n"));
+	} else {
 		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
 		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
 
-		DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
+		DBGPRINT(RT_DEBUG_TRACE, ("Infra LINK UP!\n"));
 	}
 
-	// 3*3
-	// reset Tx beamforming bit
+	/* 3*3 */
+	/* reset Tx beamforming bit */
 	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
 	Value &= (~0x01);
 	Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
 	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
 
-	// Change to AP channel
-    if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
-	{
-		// Must using 40MHz.
+	/* Change to AP channel */
+	if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
+	    && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) {
+		/* Must using 40MHz. */
 		pAd->CommonCfg.BBPCurrentBW = BW_40;
 		AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
 		AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
@@ -1217,34 +1246,35 @@
 		Value |= 0x10;
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
 
-		//  RX : control channel at lower
+		/*  RX : control channel at lower */
 		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
 		Value &= (~0x20);
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
-#ifdef RT2860
-        pAd->StaCfg.BBPR3 = Value;
-#endif
+#ifdef RTMP_MAC_PCI
+		pAd->StaCfg.BBPR3 = Value;
+#endif /* RTMP_MAC_PCI // */
 
 		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
 		Data &= 0xfffffffe;
 		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
 
-		if (pAd->MACVersion == 0x28600100)
-		{
+		if (pAd->MACVersion == 0x28600100) {
 			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
 			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
 			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
-            DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+			DBGPRINT(RT_DEBUG_TRACE, ("rt2860C !\n"));
 		}
 
-		DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
-	}
-	else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
-    {
-	    // Must using 40MHz.
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("40MHz Lower LINK UP! Control Channel at Below. Central = %d \n",
+			  pAd->CommonCfg.CentralChannel));
+	} else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
+		   && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth ==
+		       BW_40)) {
+		/* Must using 40MHz. */
 		pAd->CommonCfg.BBPCurrentBW = BW_40;
 		AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
-	    AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+		AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
 
 		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
 		Value &= (~0x18);
@@ -1256,25 +1286,24 @@
 		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
 
 		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
-	    Value |= (0x20);
+		Value |= (0x20);
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
-#ifdef RT2860
-        pAd->StaCfg.BBPR3 = Value;
-#endif
+#ifdef RTMP_MAC_PCI
+		pAd->StaCfg.BBPR3 = Value;
+#endif /* RTMP_MAC_PCI // */
 
-		if (pAd->MACVersion == 0x28600100)
-		{
+		if (pAd->MACVersion == 0x28600100) {
 			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
 			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
 			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
-			    DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+			DBGPRINT(RT_DEBUG_TRACE, ("rt2860C !\n"));
 		}
 
-	    DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
-    }
-    else
-    {
-	    pAd->CommonCfg.BBPCurrentBW = BW_20;
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("40MHz Upper LINK UP! Control Channel at UpperCentral = %d \n",
+			  pAd->CommonCfg.CentralChannel));
+	} else {
+		pAd->CommonCfg.BBPCurrentBW = BW_20;
 		pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
 		AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
 		AsicLockChannel(pAd, pAd->CommonCfg.Channel);
@@ -1290,511 +1319,533 @@
 		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
 		Value &= (~0x20);
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
-#ifdef RT2860
-        pAd->StaCfg.BBPR3 = Value;
-#endif
+#ifdef RTMP_MAC_PCI
+		pAd->StaCfg.BBPR3 = Value;
+#endif /* RTMP_MAC_PCI // */
 
-		if (pAd->MACVersion == 0x28600100)
-		{
+		if (pAd->MACVersion == 0x28600100) {
 			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
 			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
 			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
-            DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+			DBGPRINT(RT_DEBUG_TRACE, ("rt2860C !\n"));
 		}
 
-	    DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
-    }
+		DBGPRINT(RT_DEBUG_TRACE, ("20MHz LINK UP!\n"));
+	}
 
 	RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
-	//
-	// Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
-	//
-	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
 
-	DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
-		BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
+	/* */
+	/* Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission */
+	/* */
+	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66,
+				    &pAd->BbpTuning.R66CurrentValue);
 
-	DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("LINK UP! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
+		  BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid,
+		  pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
 
-		AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("LINK UP! (Density =%d, )\n",
+		  pAd->MacTab.Content[BSSID_WCID].MpduDensity));
+
+	AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
 
 	AsicSetSlotTime(pAd, TRUE);
 	AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
 
-	// Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
-	AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
+	/* Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit */
+	AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE,
+			  FALSE);
 
-	if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
-	{
-		// Update HT protectionfor based on AP's operating mode.
-    	if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
-    	{
-    		AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode,  ALLN_SETPROTECT, FALSE, TRUE);
-    	}
-    	else
-   			AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode,  ALLN_SETPROTECT, FALSE, FALSE);
+	if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE)) {
+		/* Update HT protectionfor based on AP's operating mode. */
+		if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1) {
+			AsicUpdateProtect(pAd,
+					  pAd->MlmeAux.AddHtInfo.AddHtInfo2.
+					  OperaionMode, ALLN_SETPROTECT, FALSE,
+					  TRUE);
+		} else
+			AsicUpdateProtect(pAd,
+					  pAd->MlmeAux.AddHtInfo.AddHtInfo2.
+					  OperaionMode, ALLN_SETPROTECT, FALSE,
+					  FALSE);
 	}
 
-	NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
+	NdisZeroMemory(&pAd->DrsCounters, sizeof(struct rt_counter_drs));
 
 	NdisGetSystemUpTime(&Now);
-	pAd->StaCfg.LastBeaconRxTime = Now;   // last RX timestamp
+	pAd->StaCfg.LastBeaconRxTime = Now;	/* last RX timestamp */
 
 	if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
-		CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
-	{
+	    CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo)) {
 		MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
 	}
 
 	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
 
-	if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
-	{
+	if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE) {
 	}
 	pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
 
-	if (BssType == BSS_ADHOC)
-	{
+	if (BssType == BSS_ADHOC) {
 		MakeIbssBeacon(pAd);
 		if ((pAd->CommonCfg.Channel > 14)
-			&& (pAd->CommonCfg.bIEEE80211H == 1)
-			&& RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
-		{
-			; //Do nothing
-		}
-		else
-		{
+		    && (pAd->CommonCfg.bIEEE80211H == 1)
+		    && RadarChannelCheck(pAd, pAd->CommonCfg.Channel)) {
+			;	/*Do nothing */
+		} else {
 			AsicEnableIbssSync(pAd);
 		}
 
-		// In ad hoc mode, use MAC table from index 1.
-		// p.s ASIC use all 0xff as termination of WCID table search.To prevent it's 0xff-ff-ff-ff-ff-ff, Write 0 here.
+		/* In ad hoc mode, use MAC table from index 1. */
+		/* p.s ASIC use all 0xff as termination of WCID table search.To prevent it's 0xff-ff-ff-ff-ff-ff, Write 0 here. */
 		RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
 		RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
 
-		// If WEP is enabled, add key material and cipherAlg into Asic
-		// Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
+		/* If WEP is enabled, add key material and cipherAlg into Asic */
+		/* Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000) */
 
-		if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
-		{
-			PUCHAR	Key;
-			UCHAR 	CipherAlg;
+		if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) {
+			u8 *Key;
+			u8 CipherAlg;
 
-			for (idx=0; idx < SHARE_KEY_NUM; idx++)
-        	{
+			for (idx = 0; idx < SHARE_KEY_NUM; idx++) {
 				CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
-    			Key = pAd->SharedKey[BSS0][idx].Key;
+				Key = pAd->SharedKey[BSS0][idx].Key;
 
-				if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
-				{
-					// Set key material and cipherAlg to Asic
-    				AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
+				if (pAd->SharedKey[BSS0][idx].KeyLen > 0) {
+					/* Set key material and cipherAlg to Asic */
+					AsicAddSharedKeyEntry(pAd, BSS0, idx,
+							      CipherAlg, Key,
+							      NULL, NULL);
 
-                    if (idx == pAd->StaCfg.DefaultKeyId)
-					{
-						// Update WCID attribute table and IVEIV table for this group key table
-						RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
+					if (idx == pAd->StaCfg.DefaultKeyId) {
+						/* Update WCID attribute table and IVEIV table for this group key table */
+						RTMPAddWcidAttributeEntry(pAd,
+									  BSS0,
+									  idx,
+									  CipherAlg,
+									  NULL);
 					}
 				}
 
-
 			}
 		}
-		// If WPANone is enabled, add key material and cipherAlg into Asic
-		// Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
-		else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
-		{
-			pAd->StaCfg.DefaultKeyId = 0;	// always be zero
+		/* If WPANone is enabled, add key material and cipherAlg into Asic */
+		/* Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000) */
+		else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) {
+			pAd->StaCfg.DefaultKeyId = 0;	/* always be zero */
 
-            NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
-							pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
-			NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
+			NdisZeroMemory(&pAd->SharedKey[BSS0][0],
+				       sizeof(struct rt_cipher_key));
+			pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
+			NdisMoveMemory(pAd->SharedKey[BSS0][0].Key,
+				       pAd->StaCfg.PMK, LEN_TKIP_EK);
 
-            if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
-            {
-    			NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
-    			NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
-            }
-
-			// Decide its ChiperAlg
-			if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+			if (pAd->StaCfg.PairCipher ==
+			    Ndis802_11Encryption2Enabled) {
+				NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic,
+					       &pAd->StaCfg.PMK[16],
+					       LEN_TKIP_RXMICK);
+				NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic,
+					       &pAd->StaCfg.PMK[16],
+					       LEN_TKIP_TXMICK);
+			}
+			/* Decide its ChiperAlg */
+			if (pAd->StaCfg.PairCipher ==
+			    Ndis802_11Encryption2Enabled)
 				pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
-			else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
+			else if (pAd->StaCfg.PairCipher ==
+				 Ndis802_11Encryption3Enabled)
 				pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
-			else
-            {
-                DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
+			else {
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("Unknow Cipher (=%d), set Cipher to AES\n",
+					  pAd->StaCfg.PairCipher));
 				pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
-            }
+			}
 
-			// Set key material and cipherAlg to Asic
+			/* Set key material and cipherAlg to Asic */
 			AsicAddSharedKeyEntry(pAd,
-								  BSS0,
-								  0,
-								  pAd->SharedKey[BSS0][0].CipherAlg,
-								  pAd->SharedKey[BSS0][0].Key,
-								  pAd->SharedKey[BSS0][0].TxMic,
-								  pAd->SharedKey[BSS0][0].RxMic);
+					      BSS0,
+					      0,
+					      pAd->SharedKey[BSS0][0].CipherAlg,
+					      pAd->SharedKey[BSS0][0].Key,
+					      pAd->SharedKey[BSS0][0].TxMic,
+					      pAd->SharedKey[BSS0][0].RxMic);
 
-            // Update WCID attribute table and IVEIV table for this group key table
-			RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
+			/* Update WCID attribute table and IVEIV table for this group key table */
+			RTMPAddWcidAttributeEntry(pAd, BSS0, 0,
+						  pAd->SharedKey[BSS0][0].
+						  CipherAlg, NULL);
 
 		}
 
-	}
-	else // BSS_INFRA
+	} else			/* BSS_INFRA */
 	{
-		// Check the new SSID with last SSID
-		while (Cancelled == TRUE)
-		{
-			if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
-			{
-				if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
-				{
-					// Link to the old one no linkdown is required.
+		/* Check the new SSID with last SSID */
+		while (Cancelled == TRUE) {
+			if (pAd->CommonCfg.LastSsidLen ==
+			    pAd->CommonCfg.SsidLen) {
+				if (RTMPCompareMemory
+				    (pAd->CommonCfg.LastSsid,
+				     pAd->CommonCfg.Ssid,
+				     pAd->CommonCfg.LastSsidLen) == 0) {
+					/* Link to the old one no linkdown is required. */
 					break;
 				}
 			}
-			// Send link down event before set to link up
+			/* Send link down event before set to link up */
 			pAd->IndicateMediaState = NdisMediaStateDisconnected;
 			RTMP_IndicateMediaState(pAd);
-            pAd->ExtraInfo = GENERAL_LINK_DOWN;
-			DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
+			pAd->ExtraInfo = GENERAL_LINK_DOWN;
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
 			break;
 		}
 
-		//
-		// On WPA mode, Remove All Keys if not connect to the last BSSID
-		// Key will be set after 4-way handshake.
-		//
-		if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
-		{
-			ULONG 		IV;
+		/* */
+		/* On WPA mode, Remove All Keys if not connect to the last BSSID */
+		/* Key will be set after 4-way handshake. */
+		/* */
+		if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) {
+			unsigned long IV;
 
-			// Remove all WPA keys
+			/* Remove all WPA keys */
+			RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
 			RTMPWPARemoveAllKeys(pAd);
 			pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-			pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+			pAd->StaCfg.PrivacyFilter =
+			    Ndis802_11PrivFilter8021xWEP;
 
-			// Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
-			// If IV related values are too large in GroupMsg2, AP would ignore this message.
-			IV = 0;
+			/* Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP */
+			/* If IV related values are too large in GroupMsg2, AP would ignore this message. */
+			IV = 1;
 			IV |= (pAd->StaCfg.DefaultKeyId << 30);
 			AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
-
-#ifdef RT2860
-			RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-#endif
 		}
-		// NOTE:
-		// the decision of using "short slot time" or not may change dynamically due to
-		// new STA association to the AP. so we have to decide that upon parsing BEACON, not here
+		/* NOTE: */
+		/* the decision of using "short slot time" or not may change dynamically due to */
+		/* new STA association to the AP. so we have to decide that upon parsing BEACON, not here */
 
-		// NOTE:
-		// the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
-		// due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
+		/* NOTE: */
+		/* the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically */
+		/* due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here */
 
 		ComposePsPoll(pAd);
 		ComposeNullFrame(pAd);
 
-			AsicEnableBssSync(pAd);
+		AsicEnableBssSync(pAd);
 
-		// Add BSSID to WCID search table
+		/* Add BSSID to WCID search table */
 		AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
 
-		NdisAcquireSpinLock(&pAd->MacTabLock);
-		// add this BSSID entry into HASH table
-		{
-			UCHAR HashIdx;
+		/* If WEP is enabled, add paiewise and shared key */
+		if (((pAd->StaCfg.WpaSupplicantUP) &&
+		     (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
+		     (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
+		    ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE) &&
+		     (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled))) {
+			u8 *Key;
+			u8 CipherAlg;
 
-			//pEntry = &pAd->MacTab.Content[BSSID_WCID];
-			HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
-			if (pAd->MacTab.Hash[HashIdx] == NULL)
-			{
-				pAd->MacTab.Hash[HashIdx] = pEntry;
-			}
-			else
-			{
-				pCurrEntry = pAd->MacTab.Hash[HashIdx];
-				while (pCurrEntry->pNext != NULL)
-					pCurrEntry = pCurrEntry->pNext;
-				pCurrEntry->pNext = pEntry;
-			}
-		}
-		NdisReleaseSpinLock(&pAd->MacTabLock);
-
-
-		// If WEP is enabled, add paiewise and shared key
-        if (((pAd->StaCfg.WpaSupplicantUP)&&
-             (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
-             (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
-            ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
-              (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
-		{
-			PUCHAR	Key;
-			UCHAR 	CipherAlg;
-
-			for (idx=0; idx < SHARE_KEY_NUM; idx++)
-        	{
+			for (idx = 0; idx < SHARE_KEY_NUM; idx++) {
 				CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
-    			Key = pAd->SharedKey[BSS0][idx].Key;
+				Key = pAd->SharedKey[BSS0][idx].Key;
 
-				if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
-				{
-					// Set key material and cipherAlg to Asic
-    				AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
+				if (pAd->SharedKey[BSS0][idx].KeyLen > 0) {
+					/* Set key material and cipherAlg to Asic */
+					AsicAddSharedKeyEntry(pAd, BSS0, idx,
+							      CipherAlg, Key,
+							      NULL, NULL);
 
-					if (idx == pAd->StaCfg.DefaultKeyId)
-					{
-						// Assign group key info
-						RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
+					if (idx == pAd->StaCfg.DefaultKeyId) {
+						/* Assign group key info */
+						RTMPAddWcidAttributeEntry(pAd,
+									  BSS0,
+									  idx,
+									  CipherAlg,
+									  NULL);
 
-						// Assign pairwise key info
-						RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
+						pEntry->Aid = BSSID_WCID;
+						/* Assign pairwise key info */
+						RTMPAddWcidAttributeEntry(pAd,
+									  BSS0,
+									  idx,
+									  CipherAlg,
+									  pEntry);
 					}
 				}
 			}
 		}
-
-		// only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
-		// should wait until at least 2 active nodes in this BSSID.
+		/* only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode */
+		/* should wait until at least 2 active nodes in this BSSID. */
 		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
 
-        // For GUI ++
-		if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
-		{
+		/* For GUI ++ */
+		if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA) {
 			pAd->IndicateMediaState = NdisMediaStateConnected;
 			pAd->ExtraInfo = GENERAL_LINK_UP;
-#ifdef RT2870
 			RTMP_IndicateMediaState(pAd);
-#endif
+		} else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+			   (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+		{
+			if (pAd->StaCfg.WpaSupplicantUP ==
+			    WPA_SUPPLICANT_DISABLE)
+				RTMPSetTimer(&pAd->Mlme.LinkDownTimer,
+					     LINK_DOWN_TIMEOUT);
 		}
-        // --
-#ifdef RT2860
-		RTMP_IndicateMediaState(pAd);
-#endif
+		/* -- */
 
-		// Add BSSID in my MAC Table.
-        NdisAcquireSpinLock(&pAd->MacTabLock);
-		RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
-		pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID;
-		pAd->MacTab.Content[BSSID_WCID].pAd = pAd;
-		pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE;	//Although this is bssid..still set ValidAsCl
-		pAd->MacTab.Size = 1;	// infra mode always set MACtab size =1.
-		pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC;
-		pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC;
-		pAd->MacTab.Content[BSSID_WCID].AuthMode = pAd->StaCfg.AuthMode;
-		pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
-        NdisReleaseSpinLock(&pAd->MacTabLock);
+		/* Add BSSID in my MAC Table. */
+		NdisAcquireSpinLock(&pAd->MacTabLock);
+		/* add this MAC entry into HASH table */
+		if (pEntry) {
+			HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
+			if (pAd->MacTab.Hash[HashIdx] == NULL) {
+				pAd->MacTab.Hash[HashIdx] = pEntry;
+			} else {
+				pCurrEntry = pAd->MacTab.Hash[HashIdx];
+				while (pCurrEntry->pNext != NULL) {
+					pCurrEntry = pCurrEntry->pNext;
+				}
+				pCurrEntry->pNext = pEntry;
+			}
+		}
+		RTMPMoveMemory(pEntry->Addr, pAd->CommonCfg.Bssid,
+			       MAC_ADDR_LEN);
+		pEntry->Aid = BSSID_WCID;
+		pEntry->pAd = pAd;
+		pEntry->ValidAsCLI = TRUE;	/*Although this is bssid..still set ValidAsCl */
+		pAd->MacTab.Size = 1;	/* infra mode always set MACtab size =1. */
+		pEntry->Sst = SST_ASSOC;
+		pEntry->AuthState = SST_ASSOC;
+		pEntry->AuthMode = pAd->StaCfg.AuthMode;
+		pEntry->WepStatus = pAd->StaCfg.WepStatus;
+		if (pEntry->AuthMode < Ndis802_11AuthModeWPA) {
+			pEntry->WpaState = AS_NOTUSE;
+			pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+		} else {
+			pEntry->WpaState = AS_PTKSTART;
+			pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+		}
+		NdisReleaseSpinLock(&pAd->MacTabLock);
 
-		DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!!  ClientStatusFlags=%lx)\n",
-			pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("LINK UP!  ClientStatusFlags=%lx)\n",
+			  pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
 
 		MlmeUpdateTxRates(pAd, TRUE, BSS0);
 		MlmeUpdateHtTxRates(pAd, BSS0);
-		DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("LINK UP! (StaActive.bHtEnable =%d, )\n",
+			  pAd->StaActive.SupportedPhyInfo.bHtEnable));
 
-		if (pAd->CommonCfg.bAggregationCapable)
-		{
-			if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
-			{
-
-				OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
-				OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
-                RTMPSetPiggyBack(pAd, TRUE);
-				DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
-			}
-			else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
-			{
-				OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
+		if (pAd->CommonCfg.bAggregationCapable) {
+			if ((pAd->CommonCfg.bPiggyBackCapable)
+			    && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3) {
+				OPSTATUS_SET_FLAG(pAd,
+						  fOP_STATUS_PIGGYBACK_INUSED);
+				OPSTATUS_SET_FLAG(pAd,
+						  fOP_STATUS_AGGREGATION_INUSED);
+				CLIENT_STATUS_SET_FLAG(pEntry,
+						       fCLIENT_STATUS_AGGREGATION_CAPABLE);
+				CLIENT_STATUS_SET_FLAG(pEntry,
+						       fCLIENT_STATUS_PIGGYBACK_CAPABLE);
+				RTMPSetPiggyBack(pAd, TRUE);
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("Turn on Piggy-Back\n"));
+			} else if (pAd->MlmeAux.APRalinkIe & 0x00000001) {
+				OPSTATUS_SET_FLAG(pAd,
+						  fOP_STATUS_AGGREGATION_INUSED);
+				CLIENT_STATUS_SET_FLAG(pEntry,
+						       fCLIENT_STATUS_AGGREGATION_CAPABLE);
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("Ralink Aggregation\n"));
 			}
 		}
 
-		if (pAd->MlmeAux.APRalinkIe != 0x0)
-		{
-			if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
-			{
+		if (pAd->MlmeAux.APRalinkIe != 0x0) {
+			if (CLIENT_STATUS_TEST_FLAG
+			    (pEntry, fCLIENT_STATUS_RDG_CAPABLE)) {
 				AsicEnableRDG(pAd);
 			}
-
 			OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
-			CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
-		}
-		else
-		{
+			CLIENT_STATUS_SET_FLAG(pEntry,
+					       fCLIENT_STATUS_RALINK_CHIPSET);
+		} else {
 			OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
-			CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
+			CLIENT_STATUS_CLEAR_FLAG(pEntry,
+						 fCLIENT_STATUS_RALINK_CHIPSET);
 		}
 	}
 
-	DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_CONNECT Event B!.BACapability = %x. ClientStatusFlags = %lx\n", pAd->CommonCfg.BACapability.word, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("NDIS_STATUS_MEDIA_CONNECT Event B!.BACapability = %x. ClientStatusFlags = %lx\n",
+		  pAd->CommonCfg.BACapability.word,
+		  pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
 
-	// Set LED
+	/* Set LED */
 	RTMPSetLED(pAd, LED_LINK_UP);
 
 	pAd->Mlme.PeriodicRound = 0;
 	pAd->Mlme.OneSecPeriodicRound = 0;
-	pAd->bConfigChanged = FALSE;        // Reset config flag
-	pAd->ExtraInfo = GENERAL_LINK_UP;   // Update extra information to link is up
+	pAd->bConfigChanged = FALSE;	/* Reset config flag */
+	pAd->ExtraInfo = GENERAL_LINK_UP;	/* Update extra information to link is up */
 
-	// Set asic auto fall back
+	/* Set asic auto fall back */
 	{
-		PUCHAR					pTable;
-		UCHAR					TableSize = 0;
+		u8 *pTable;
+		u8 TableSize = 0;
 
-		MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
+		MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID],
+				      &pTable, &TableSize,
+				      &pAd->CommonCfg.TxRateIndex);
 		AsicUpdateAutoFallBackTable(pAd, pTable);
 	}
 
 	NdisAcquireSpinLock(&pAd->MacTabLock);
-    pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
-    pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
-	if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
-	{
+	pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
+	pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
+	if (pAd->StaCfg.bAutoTxRateSwitch == FALSE) {
 		pEntry->bAutoTxRateSwitch = FALSE;
 
 		if (pEntry->HTPhyMode.field.MCS == 32)
 			pEntry->HTPhyMode.field.ShortGI = GI_800;
 
-		if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
+		if ((pEntry->HTPhyMode.field.MCS > MCS_7)
+		    || (pEntry->HTPhyMode.field.MCS == 32))
 			pEntry->HTPhyMode.field.STBC = STBC_NONE;
 
-		// If the legacy mode is set, overwrite the transmit setting of this entry.
+		/* If the legacy mode is set, overwrite the transmit setting of this entry. */
 		if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
-			RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
-	}
-	else
+			RTMPUpdateLegacyTxSetting((u8)pAd->StaCfg.
+						  DesiredTransmitSetting.field.
+						  FixedTxMode, pEntry);
+	} else
 		pEntry->bAutoTxRateSwitch = TRUE;
 	NdisReleaseSpinLock(&pAd->MacTabLock);
 
-	//  Let Link Status Page display first initial rate.
-	pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
-	// Select DAC according to HT or Legacy
-	if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
-	{
+	/*  Let Link Status Page display first initial rate. */
+	pAd->LastTxRate = (u16)(pEntry->HTPhyMode.word);
+	/* Select DAC according to HT or Legacy */
+	if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00) {
 		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
 		Value &= (~0x18);
-		if (pAd->Antenna.field.TxPath == 2)
-		{
-		    Value |= 0x10;
+		if (pAd->Antenna.field.TxPath == 2) {
+			Value |= 0x10;
 		}
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
-	}
-	else
-	{
+	} else {
 		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
 		Value &= (~0x18);
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
 	}
 
-	if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
-	{
-	}
-	else if (pEntry->MaxRAmpduFactor == 0)
-	{
-	    // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
-	    // Because our Init value is 1 at MACRegTable.
+	if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) {
+	} else if (pEntry->MaxRAmpduFactor == 0) {
+		/* If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0. */
+		/* Because our Init value is 1 at MACRegTable. */
 		RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
 	}
-
-	// Patch for Marvel AP to gain high throughput
-	// Need to set as following,
-	// 1. Set txop in register-EDCA_AC0_CFG as 0x60
-	// 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
-	// 3. PBF_MAX_PCNT as 0x1F3FBF9F
-	// 4. kick per two packets when dequeue
-	//
-	// Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
-	//
-	// if 1. Legacy AP WMM on,  or 2. 11n AP, AMPDU disable.  Force turn off burst no matter what bEnableTxBurst is.
-	if (
-		!(pAd->CommonCfg.RxStream == 1 && pAd->CommonCfg.TxStream == 1) &&
-		(((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
-		|| ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))))
-	{
+	/* Patch for Marvel AP to gain high throughput */
+	/* Need to set as following, */
+	/* 1. Set txop in register-EDCA_AC0_CFG as 0x60 */
+	/* 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero */
+	/* 3. PBF_MAX_PCNT as 0x1F3FBF9F */
+	/* 4. kick per two packets when dequeue */
+	/* */
+	/* Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable */
+	/* */
+	/* if 1. Legacy AP WMM on,  or 2. 11n AP, AMPDU disable.  Force turn off burst no matter what bEnableTxBurst is. */
+	if (!((pAd->CommonCfg.RxStream == 1) && (pAd->CommonCfg.TxStream == 1))
+	    && (pAd->StaCfg.bForceTxBurst == FALSE)
+	    &&
+	    (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
+	      && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
+	     || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE)
+		 && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))) {
 		RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
-		Data  &= 0xFFFFFF00;
+		Data &= 0xFFFFFF00;
 		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
 
 		RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
 		DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
-	}
-	else
-	if (pAd->CommonCfg.bEnableTxBurst)
-	{
+	} else if (pAd->CommonCfg.bEnableTxBurst) {
 		RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
-		Data  &= 0xFFFFFF00;
-		Data  |= 0x60;
+		Data &= 0xFFFFFF00;
+		Data |= 0x60;
 		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
 		pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
 
 		RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
 		DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
-	}
-	else
-	{
+	} else {
 		RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
-		Data  &= 0xFFFFFF00;
+		Data &= 0xFFFFFF00;
 		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
 
 		RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
 		DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
 	}
 
-	// Re-check to turn on TX burst or not.
-	if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
-	{
+	/* Re-check to turn on TX burst or not. */
+	if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE)
+	    && ((STA_WEP_ON(pAd)) || (STA_TKIP_ON(pAd)))) {
 		pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
-		if (pAd->CommonCfg.bEnableTxBurst)
-		{
-		    UINT32 MACValue = 0;
-			// Force disable  TXOP value in this case. The same action in MLMEUpdateProtect too.
-			// I didn't change PBF_MAX_PCNT setting.
+		if (pAd->CommonCfg.bEnableTxBurst) {
+			u32 MACValue = 0;
+			/* Force disable  TXOP value in this case. The same action in MLMEUpdateProtect too. */
+			/* I didn't change PBF_MAX_PCNT setting. */
 			RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
-			MACValue  &= 0xFFFFFF00;
+			MACValue &= 0xFFFFFF00;
 			RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
 			pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
 		}
-	}
-	else
-	{
+	} else {
 		pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
 	}
 
 	pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
 	COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
-	DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
-	// BSSID add in one MAC entry too.  Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
-	// Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
-	// Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("pAd->bNextDisableRxBA= %d \n",
+		  pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
+	/* BSSID add in one MAC entry too.  Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap */
+	/* Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver. */
+	/* Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same. */
 
-    if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
-    {
-        pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
-		pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+	if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled) {
+		if (pAd->StaCfg.WpaSupplicantUP &&
+		    (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
+		    (pAd->StaCfg.IEEE8021X == TRUE)) ;
+		else {
+			pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+			pAd->StaCfg.PrivacyFilter =
+			    Ndis802_11PrivFilterAcceptAll;
+		}
 	}
 
 	NdisAcquireSpinLock(&pAd->MacTabLock);
 	pEntry->PortSecured = pAd->StaCfg.PortSecured;
 	NdisReleaseSpinLock(&pAd->MacTabLock);
 
-    //
-	// Patch Atheros AP TX will breakdown issue.
-	// AP Model: DLink DWL-8200AP
-	//
-	if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
-	{
+	/* */
+	/* Patch Atheros AP TX will breakdown issue. */
+	/* AP Model: DLink DWL-8200AP */
+	/* */
+	if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)
+	    && STA_TKIP_ON(pAd)) {
 		RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
-	}
-	else
-	{
+	} else {
 		RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
 	}
 
 	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
-#ifdef RT2860
+
 	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
-#endif
 }
 
 /*
@@ -1822,220 +1873,190 @@
 
 	==========================================================================
 */
-VOID LinkDown(
-	IN PRTMP_ADAPTER pAd,
-	IN  BOOLEAN      IsReqFromAP)
+void LinkDown(struct rt_rtmp_adapter *pAd, IN BOOLEAN IsReqFromAP)
 {
-	UCHAR			    i, ByteValue = 0;
-#ifdef RT2860
-	BOOLEAN		Cancelled;
-#endif
+	u8 i, ByteValue = 0;
 
-	// Do nothing if monitor mode is on
+	/* Do nothing if monitor mode is on */
 	if (MONITOR_ON(pAd))
 		return;
 
-#ifdef RT2860
 	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
-	RTMPCancelTimer(&pAd->Mlme.PsPollTimer,		&Cancelled);
-
-	// Not allow go to sleep within linkdown function.
+	/*Comment the codes, beasue the line 2291 call the same function. */
+	/*RTMPCancelTimer(&pAd->Mlme.PsPollTimer,               &Cancelled); */
+	/* Not allow go to sleep within linkdown function. */
 	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-#endif
 
-    if (pAd->CommonCfg.bWirelessEvent)
-	{
-		RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+	if (pAd->CommonCfg.bWirelessEvent) {
+		RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG,
+				      pAd->MacTab.Content[BSSID_WCID].Addr,
+				      BSS0, 0);
 	}
 
-	DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
+	DBGPRINT(RT_DEBUG_TRACE, ("LINK DOWN!\n"));
 	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
 
-#ifdef RT2860
-    if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
-    {
-	    BOOLEAN Cancelled;
-        pAd->Mlme.bPsPollTimerRunning = FALSE;
-        RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
-    }
+#ifdef RTMP_MAC_PCI
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
+		BOOLEAN Cancelled;
+		pAd->Mlme.bPsPollTimerRunning = FALSE;
+		RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
+	}
 
-    if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
-		RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) ||
-		RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
-    {
-		AsicForceWakeup(pAd, RTMP_HALT);
-        OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-    }
+	pAd->bPCIclkOff = FALSE;
+#endif /* RTMP_MAC_PCI // */
 
-    pAd->bPCIclkOff = FALSE;
-#endif
-	if (ADHOC_ON(pAd))		// Adhoc mode link down
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
+	    || RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND)
+	    || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) {
+		AUTO_WAKEUP_STRUC AutoWakeupCfg;
+		AsicForceWakeup(pAd, TRUE);
+		AutoWakeupCfg.word = 0;
+		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+	}
+#ifdef RTMP_MAC_PCI
+	pAd->bPCIclkOff = FALSE;
+#endif /* RTMP_MAC_PCI // */
+
+	if (ADHOC_ON(pAd))	/* Adhoc mode link down */
 	{
-		DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
+		DBGPRINT(RT_DEBUG_TRACE, ("LINK DOWN 1!\n"));
 
 		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
 		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
 		pAd->IndicateMediaState = NdisMediaStateDisconnected;
 		RTMP_IndicateMediaState(pAd);
-        pAd->ExtraInfo = GENERAL_LINK_DOWN;
-		BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
-		DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
-	}
-	else					// Infra structure mode
+		pAd->ExtraInfo = GENERAL_LINK_DOWN;
+		BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid,
+				    pAd->CommonCfg.Channel);
+		DBGPRINT(RT_DEBUG_TRACE,
+			 (" MacTab.Size=%d !\n", pAd->MacTab.Size));
+	} else			/* Infra structure mode */
 	{
-		DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
+		DBGPRINT(RT_DEBUG_TRACE, ("LINK DOWN 2!\n"));
 
 		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
 		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
 
-		// Saved last SSID for linkup comparison
+		/* Saved last SSID for linkup comparison */
 		pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
-		NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
+		NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid,
+			       pAd->CommonCfg.LastSsidLen);
 		COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
-		if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
-		{
+		if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE) {
 			pAd->IndicateMediaState = NdisMediaStateDisconnected;
 			RTMP_IndicateMediaState(pAd);
-            pAd->ExtraInfo = GENERAL_LINK_DOWN;
-			DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
+			pAd->ExtraInfo = GENERAL_LINK_DOWN;
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
 			pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
-		}
-		else
-		{
-            //
-			// If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
-			// Otherwise lost beacon or receive De-Authentication from AP,
-			// then we should delete BSSID from BssTable.
-			// If we don't delete from entry, roaming will fail.
-			//
-			BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
+		} else {
+			/* */
+			/* If disassociation request is from NDIS, then we don't need to delete BSSID from entry. */
+			/* Otherwise lost beacon or receive De-Authentication from AP, */
+			/* then we should delete BSSID from BssTable. */
+			/* If we don't delete from entry, roaming will fail. */
+			/* */
+			BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid,
+					    pAd->CommonCfg.Channel);
 		}
 
-		// restore back to -
-		//      1. long slot (20 us) or short slot (9 us) time
-		//      2. turn on/off RTS/CTS and/or CTS-to-self protection
-		//      3. short preamble
+		/* restore back to - */
+		/*      1. long slot (20 us) or short slot (9 us) time */
+		/*      2. turn on/off RTS/CTS and/or CTS-to-self protection */
+		/*      3. short preamble */
 		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
 
-		if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
-		{
-			//
-			// Record current AP's information.
-			// for later used reporting Adjacent AP report.
-			//
-			pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
-			pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
-			NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
-			COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
-		}
 	}
 
-	for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
-	{
+	for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) {
 		if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
-			MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
+			MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid,
+					    pAd->MacTab.Content[i].Addr);
 	}
 
-	pAd->StaCfg.CCXQosECWMin	= 4;
-	pAd->StaCfg.CCXQosECWMax	= 10;
-
-	AsicSetSlotTime(pAd, TRUE); //FALSE);
+	AsicSetSlotTime(pAd, TRUE);	/*FALSE); */
 	AsicSetEdcaParm(pAd, NULL);
 
-	// Set LED
+	/* Set LED */
 	RTMPSetLED(pAd, LED_LINK_DOWN);
-    pAd->LedIndicatorStregth = 0xF0;
-    RTMPSetSignalLED(pAd, -100);	// Force signal strength Led to be turned off, firmware is not done it.
+	pAd->LedIndicatorStrength = 0xF0;
+	RTMPSetSignalLED(pAd, -100);	/* Force signal strength Led to be turned off, firmware is not done it. */
 
-		AsicDisableSync(pAd);
+	AsicDisableSync(pAd);
 
 	pAd->Mlme.PeriodicRound = 0;
 	pAd->Mlme.OneSecPeriodicRound = 0;
 
-	if (pAd->StaCfg.BssType == BSS_INFRA)
-	{
-		// Remove StaCfg Information after link down
+	if (pAd->StaCfg.BssType == BSS_INFRA) {
+		/* Remove StaCfg Information after link down */
 		NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
 		NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
 		pAd->CommonCfg.SsidLen = 0;
 	}
 
-	NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
-	NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
+	NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(struct rt_ht_capability_ie));
+	NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(struct rt_add_ht_info_ie));
 	pAd->MlmeAux.HtCapabilityLen = 0;
 	pAd->MlmeAux.NewExtChannelOffset = 0xff;
 
-	// Reset WPA-PSK state. Only reset when supplicant enabled
-	if (pAd->StaCfg.WpaState != SS_NOTUSE)
-	{
+	/* Reset WPA-PSK state. Only reset when supplicant enabled */
+	if (pAd->StaCfg.WpaState != SS_NOTUSE) {
 		pAd->StaCfg.WpaState = SS_START;
-		// Clear Replay counter
+		/* Clear Replay counter */
 		NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
+
 	}
-
-
-	//
-	// if link down come from AP, we need to remove all WPA keys on WPA mode.
-	// otherwise will cause 4-way handshaking failed, since the WPA key not empty.
-	//
-	if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
-	{
-		// Remove all WPA keys
+	/* */
+	/* if link down come from AP, we need to remove all WPA keys on WPA mode. */
+	/* otherwise will cause 4-way handshaking failed, since the WPA key not empty. */
+	/* */
+	if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)) {
+		/* Remove all WPA keys */
 		RTMPWPARemoveAllKeys(pAd);
 	}
+	/* 802.1x port control */
 
-	// 802.1x port control
-
-	// Prevent clear PortSecured here with static WEP
-	// NetworkManger set security policy first then set SSID to connect AP.
+	/* Prevent clear PortSecured here with static WEP */
+	/* NetworkManger set security policy first then set SSID to connect AP. */
 	if (pAd->StaCfg.WpaSupplicantUP &&
-		(pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
-		(pAd->StaCfg.IEEE8021X == FALSE))
-	{
+	    (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
+	    (pAd->StaCfg.IEEE8021X == FALSE)) {
 		pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
-	}
-	else
-	{
+	} else {
 		pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
 		pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
 	}
 
 	NdisAcquireSpinLock(&pAd->MacTabLock);
+	NdisZeroMemory(&pAd->MacTab, sizeof(struct rt_mac_table));
 	pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
 	NdisReleaseSpinLock(&pAd->MacTabLock);
 
 	pAd->StaCfg.MicErrCnt = 0;
 
-	// Turn off Ckip control flag
-	pAd->StaCfg.bCkipOn = FALSE;
-	pAd->StaCfg.CCXEnable = FALSE;
-
-    pAd->IndicateMediaState = NdisMediaStateDisconnected;
-	// Update extra information to link is up
+	pAd->IndicateMediaState = NdisMediaStateDisconnected;
+	/* Update extra information to link is up */
 	pAd->ExtraInfo = GENERAL_LINK_DOWN;
 
-#ifdef RT2860
-    pAd->StaCfg.AdhocBOnlyJoined = FALSE;
-	pAd->StaCfg.AdhocBGJoined = FALSE;
-	pAd->StaCfg.Adhoc20NJoined = FALSE;
-#endif
-    pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
+	pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
 
-	// Reset the Current AP's IP address
-	NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
-#ifdef RT2870
+#ifdef RTMP_MAC_USB
 	pAd->bUsbTxBulkAggre = FALSE;
-#endif // RT2870 //
+#endif /* RTMP_MAC_USB // */
 
-	// Clean association information
-	NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
-	pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
+	/* Clean association information */
+	NdisZeroMemory(&pAd->StaCfg.AssocInfo,
+		       sizeof(struct rt_ndis_802_11_association_information));
+	pAd->StaCfg.AssocInfo.Length =
+	    sizeof(struct rt_ndis_802_11_association_information);
 	pAd->StaCfg.ReqVarIELen = 0;
 	pAd->StaCfg.ResVarIELen = 0;
 
-	//
-	// Reset RSSI value after link down
-	//
+	/* */
+	/* Reset RSSI value after link down */
+	/* */
 	pAd->StaCfg.RssiSample.AvgRssi0 = 0;
 	pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
 	pAd->StaCfg.RssiSample.AvgRssi1 = 0;
@@ -2043,37 +2064,36 @@
 	pAd->StaCfg.RssiSample.AvgRssi2 = 0;
 	pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
 
-	// Restore MlmeRate
+	/* Restore MlmeRate */
 	pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
 	pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
 
-	//
-	// After Link down, reset piggy-back setting in ASIC. Disable RDG.
-	//
-	if (pAd->CommonCfg.BBPCurrentBW == BW_40)
-	{
+	/* */
+	/* After Link down, reset piggy-back setting in ASIC. Disable RDG. */
+	/* */
+	if (pAd->CommonCfg.BBPCurrentBW == BW_40) {
 		pAd->CommonCfg.BBPCurrentBW = BW_20;
 		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
 		ByteValue &= (~0x18);
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
 	}
-
-	// Reset DAC
+	/* Reset DAC */
 	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
 	ByteValue &= (~0x18);
-	if (pAd->Antenna.field.TxPath == 2)
-	{
+	if (pAd->Antenna.field.TxPath == 2) {
 		ByteValue |= 0x10;
 	}
 	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
 
-	RTMPSetPiggyBack(pAd,FALSE);
+	RTMPSetPiggyBack(pAd, FALSE);
 	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
 
 	pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
 
-	// Restore all settings in the following.
-	AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
+	/* Restore all settings in the following. */
+	AsicUpdateProtect(pAd, 0,
+			  (ALLN_SETPROTECT | CCKSETPROTECT | OFDMSETPROTECT),
+			  TRUE, FALSE);
 	AsicDisableRDG(pAd);
 	pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
 	pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
@@ -2081,30 +2101,17 @@
 	RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
 	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
 
-#ifdef RT2860
-	// Allow go to sleep after linkdown steps.
+/* Allow go to sleep after linkdown steps. */
 	RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-#endif
 
-	{
-		union iwreq_data    wrqu;
-		memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
-		wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+	RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0);
+
+#ifdef RT30xx
+	if ((IS_RT30xx(pAd) || IS_RT3090(pAd) || IS_RT3390(pAd))
+	    && (pAd->Antenna.field.RxPath > 1 || pAd->Antenna.field.TxPath > 1)) {
+		RTMP_ASIC_MMPS_DISABLE(pAd);
 	}
-
-	if (IS_RT3090(pAd))
-	{
-		UINT32				macdata;
-		// disable MMPS BBP control register
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &ByteValue);
-		ByteValue &= ~(0x04);	//bit 2
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, ByteValue);
-
-		// disable MMPS MAC control register
-		RTMP_IO_READ32(pAd, 0x1210, &macdata);
-		macdata &= ~(0x09);	//bit 0, 3
-		RTMP_IO_WRITE32(pAd, 0x1210, macdata);
-	}
+#endif /* RT30xx // */
 }
 
 /*
@@ -2115,112 +2122,148 @@
 
 	==========================================================================
 */
-VOID IterateOnBssTab(
-	IN PRTMP_ADAPTER pAd)
+void IterateOnBssTab(struct rt_rtmp_adapter *pAd)
 {
-	MLME_START_REQ_STRUCT   StartReq;
-	MLME_JOIN_REQ_STRUCT    JoinReq;
-	ULONG                   BssIdx;
+	struct rt_mlme_start_req StartReq;
+	struct rt_mlme_join_req JoinReq;
+	unsigned long BssIdx;
 
-	// Change the wepstatus to original wepstatus
-	pAd->StaCfg.WepStatus   = pAd->StaCfg.OrigWepStatus;
-	pAd->StaCfg.PairCipher  = pAd->StaCfg.OrigWepStatus;
+	/* Change the wepstatus to original wepstatus */
+	pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
+	pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
 	pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
 
 	BssIdx = pAd->MlmeAux.BssIdx;
-	if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
-	{
-		// Check cipher suite, AP must have more secured cipher than station setting
-		// Set the Pairwise and Group cipher to match the intended AP setting
-		// We can only connect to AP with less secured cipher setting
-		if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
-		{
-			pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
+	if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr) {
+		/* Check cipher suite, AP must have more secured cipher than station setting */
+		/* Set the Pairwise and Group cipher to match the intended AP setting */
+		/* We can only connect to AP with less secured cipher setting */
+		if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA)
+		    || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) {
+			pAd->StaCfg.GroupCipher =
+			    pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.
+			    GroupCipher;
 
-			if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
-				pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
-			else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
-				pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
-			else	// There is no PairCipher Aux, downgrade our capability to TKIP
-				pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
+			if (pAd->StaCfg.WepStatus ==
+			    pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.
+			    PairCipher)
+				pAd->StaCfg.PairCipher =
+				    pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].
+				    WPA.PairCipher;
+			else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.
+				 PairCipherAux != Ndis802_11WEPDisabled)
+				pAd->StaCfg.PairCipher =
+				    pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].
+				    WPA.PairCipherAux;
+			else	/* There is no PairCipher Aux, downgrade our capability to TKIP */
+				pAd->StaCfg.PairCipher =
+				    Ndis802_11Encryption2Enabled;
+		} else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
+			   || (pAd->StaCfg.AuthMode ==
+			       Ndis802_11AuthModeWPA2PSK)) {
+			pAd->StaCfg.GroupCipher =
+			    pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.
+			    GroupCipher;
+
+			if (pAd->StaCfg.WepStatus ==
+			    pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.
+			    PairCipher)
+				pAd->StaCfg.PairCipher =
+				    pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].
+				    WPA2.PairCipher;
+			else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.
+				 PairCipherAux != Ndis802_11WEPDisabled)
+				pAd->StaCfg.PairCipher =
+				    pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].
+				    WPA2.PairCipherAux;
+			else	/* There is no PairCipher Aux, downgrade our capability to TKIP */
+				pAd->StaCfg.PairCipher =
+				    Ndis802_11Encryption2Enabled;
+
+			/* RSN capability */
+			pAd->StaCfg.RsnCapability =
+			    pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.
+			    RsnCapability;
 		}
-		else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
-		{
-			pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
+		/* Set Mix cipher flag */
+		pAd->StaCfg.bMixCipher =
+		    (pAd->StaCfg.PairCipher ==
+		     pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
+		/*if (pAd->StaCfg.bMixCipher == TRUE)
+		   {
+		   // If mix cipher, re-build RSNIE
+		   RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
+		   } */
 
-			if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
-				pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
-			else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
-				pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
-			else	// There is no PairCipher Aux, downgrade our capability to TKIP
-				pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
-
-			// RSN capability
-			pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
-		}
-
-		// Set Mix cipher flag
-		pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
-		if (pAd->StaCfg.bMixCipher == TRUE)
-		{
-			// If mix cipher, re-build RSNIE
-			RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("CNTL - iterate BSS %ld of %d\n", BssIdx,
+			  pAd->MlmeAux.SsidBssTab.BssNr));
 		JoinParmFill(pAd, &JoinReq, BssIdx);
-		MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
-					&JoinReq);
+		MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ,
+			    sizeof(struct rt_mlme_join_req), &JoinReq);
 		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
-	}
-	else if (pAd->StaCfg.BssType == BSS_ADHOC)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
-		StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
-		MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
+	} else if (pAd->StaCfg.BssType == BSS_ADHOC) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",
+			  pAd->MlmeAux.Ssid));
+		StartParmFill(pAd, &StartReq, (char *)pAd->MlmeAux.Ssid,
+			      pAd->MlmeAux.SsidLen);
+		MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ,
+			    sizeof(struct rt_mlme_start_req), &StartReq);
 		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
-	}
-	else // no more BSS
+	} else			/* no more BSS */
 	{
-		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
-		AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-		AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+		{
+			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n",
+				  pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
+		}
+
 		pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
 	}
 }
 
-// for re-association only
-// IRQL = DISPATCH_LEVEL
-VOID IterateOnBssTab2(
-	IN PRTMP_ADAPTER pAd)
+/* for re-association only */
+/* IRQL = DISPATCH_LEVEL */
+void IterateOnBssTab2(struct rt_rtmp_adapter *pAd)
 {
-	MLME_REASSOC_REQ_STRUCT ReassocReq;
-	ULONG                   BssIdx;
-	BSS_ENTRY               *pBss;
+	struct rt_mlme_assoc_req ReassocReq;
+	unsigned long BssIdx;
+	struct rt_bss_entry *pBss;
 
 	BssIdx = pAd->MlmeAux.RoamIdx;
 	pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
 
-	if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
+	if (BssIdx < pAd->MlmeAux.RoamTab.BssNr) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("CNTL - iterate BSS %ld of %d\n", BssIdx,
+			  pAd->MlmeAux.RoamTab.BssNr));
 
 		AsicSwitchChannel(pAd, pBss->Channel, FALSE);
 		AsicLockChannel(pAd, pBss->Channel);
 
-		// reassociate message has the same structure as associate message
-		AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
-					  ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
+		/* reassociate message has the same structure as associate message */
+		AssocParmFill(pAd, &ReassocReq, pBss->Bssid,
+			      pBss->CapabilityInfo, ASSOC_TIMEOUT,
+			      pAd->StaCfg.DefaultListenCount);
 		MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
-					sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
+			    sizeof(struct rt_mlme_assoc_req), &ReassocReq);
 
 		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
-	}
-	else // no more BSS
+	} else			/* no more BSS */
 	{
-		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel));
-		AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-		AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+		{
+			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n",
+				  pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
+		}
+
 		pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
 	}
 }
@@ -2233,10 +2276,8 @@
 
 	==========================================================================
 */
-VOID JoinParmFill(
-	IN PRTMP_ADAPTER pAd,
-	IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
-	IN ULONG BssIdx)
+void JoinParmFill(struct rt_rtmp_adapter *pAd,
+		  struct rt_mlme_join_req *JoinReq, unsigned long BssIdx)
 {
 	JoinReq->BssIdx = BssIdx;
 }
@@ -2249,15 +2290,12 @@
 
 	==========================================================================
 */
-VOID ScanParmFill(
-	IN PRTMP_ADAPTER pAd,
-	IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
-	IN CHAR Ssid[],
-	IN UCHAR SsidLen,
-	IN UCHAR BssType,
-	IN UCHAR ScanType)
+void ScanParmFill(struct rt_rtmp_adapter *pAd,
+		  struct rt_mlme_scan_req *ScanReq,
+		  char Ssid[],
+		  u8 SsidLen, u8 BssType, u8 ScanType)
 {
-    NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
+	NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
 	ScanReq->SsidLen = SsidLen;
 	NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
 	ScanReq->BssType = BssType;
@@ -2272,11 +2310,9 @@
 
 	==========================================================================
 */
-VOID StartParmFill(
-	IN PRTMP_ADAPTER pAd,
-	IN OUT MLME_START_REQ_STRUCT *StartReq,
-	IN CHAR Ssid[],
-	IN UCHAR SsidLen)
+void StartParmFill(struct rt_rtmp_adapter *pAd,
+		   struct rt_mlme_start_req *StartReq,
+		   char Ssid[], u8 SsidLen)
 {
 	ASSERT(SsidLen <= MAX_LEN_OF_SSID);
 	NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
@@ -2291,11 +2327,9 @@
 
 	==========================================================================
 */
-VOID AuthParmFill(
-	IN PRTMP_ADAPTER pAd,
-	IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
-	IN PUCHAR pAddr,
-	IN USHORT Alg)
+void AuthParmFill(struct rt_rtmp_adapter *pAd,
+		  struct rt_mlme_auth_req *AuthReq,
+		  u8 *pAddr, u16 Alg)
 {
 	COPY_MAC_ADDR(AuthReq->Addr, pAddr);
 	AuthReq->Alg = Alg;
@@ -2310,82 +2344,109 @@
 
 	==========================================================================
  */
-
-
-#ifdef RT2870
-
-VOID MlmeCntlConfirm(
-	IN PRTMP_ADAPTER pAd,
-	IN ULONG MsgType,
-	IN USHORT Msg)
+#ifdef RTMP_MAC_PCI
+void ComposePsPoll(struct rt_rtmp_adapter *pAd)
 {
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(USHORT), &Msg);
-}
-#endif
-
-VOID ComposePsPoll(
-	IN PRTMP_ADAPTER pAd)
-{
-#ifdef RT2870
-	PTXINFO_STRUC		pTxInfo;
-	PTXWI_STRUC		pTxWI;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n"));
-#endif
-	NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
-
-#ifdef RT2870
-	pAd->PsPollFrame.FC.PwrMgmt = 0;
-#endif
+	NdisZeroMemory(&pAd->PsPollFrame, sizeof(struct rt_pspoll_frame));
 	pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
 	pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
 	pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
 	COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
 	COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
-
-#ifdef RT2870
-	RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0], 100);
-	pTxInfo = (PTXINFO_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0];
-	RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(PSPOLL_FRAME)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE,  FALSE);
-	pTxWI = (PTXWI_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
-	RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(PSPOLL_FRAME)),
-		0,  0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
-	RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
-	// Append 4 extra zero bytes.
-	pAd->PsPollContext.BulkOutSize =  TXINFO_SIZE + TXWI_SIZE + sizeof(PSPOLL_FRAME) + 4;
-#endif
 }
 
-// IRQL = DISPATCH_LEVEL
-VOID ComposeNullFrame(
-	IN PRTMP_ADAPTER pAd)
+/* IRQL = DISPATCH_LEVEL */
+void ComposeNullFrame(struct rt_rtmp_adapter *pAd)
 {
-#ifdef RT2870
-	PTXINFO_STRUC		pTxInfo;
-	PTXWI_STRUC		pTxWI;
-#endif
-
-	NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
+	NdisZeroMemory(&pAd->NullFrame, sizeof(struct rt_header_802_11));
 	pAd->NullFrame.FC.Type = BTYPE_DATA;
 	pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
 	pAd->NullFrame.FC.ToDs = 1;
 	COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
 	COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
 	COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
-#ifdef RT2870
-	RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], 100);
-	pTxInfo = (PTXINFO_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0];
-	RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE,  FALSE);
-	pTxWI = (PTXWI_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
-	RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
-		0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
-	RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
-	pAd->NullContext.BulkOutSize =  TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
-#endif
+}
+#endif /* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
+void MlmeCntlConfirm(struct rt_rtmp_adapter *pAd, unsigned long MsgType, u16 Msg)
+{
+	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(u16),
+		    &Msg);
 }
 
+void ComposePsPoll(struct rt_rtmp_adapter *pAd)
+{
+	struct rt_txinfo *pTxInfo;
+	struct rt_txwi * pTxWI;
 
+	DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n"));
+	NdisZeroMemory(&pAd->PsPollFrame, sizeof(struct rt_pspoll_frame));
 
+	pAd->PsPollFrame.FC.PwrMgmt = 0;
+	pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
+	pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
+	pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
+	COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
+	COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
+
+	RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field.
+		       WirelessPacket[0], 100);
+	pTxInfo =
+	    (struct rt_txinfo *)& pAd->PsPollContext.TransferBuffer->field.
+	    WirelessPacket[0];
+	RTMPWriteTxInfo(pAd, pTxInfo,
+			(u16)(sizeof(struct rt_pspoll_frame) + TXWI_SIZE), TRUE,
+			EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
+	pTxWI =
+	    (struct rt_txwi *) & pAd->PsPollContext.TransferBuffer->field.
+	    WirelessPacket[TXINFO_SIZE];
+	RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0,
+		      BSSID_WCID, (sizeof(struct rt_pspoll_frame)), 0, 0,
+		      (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
+		      IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
+	RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field.
+		       WirelessPacket[TXWI_SIZE + TXINFO_SIZE],
+		       &pAd->PsPollFrame, sizeof(struct rt_pspoll_frame));
+	/* Append 4 extra zero bytes. */
+	pAd->PsPollContext.BulkOutSize =
+	    TXINFO_SIZE + TXWI_SIZE + sizeof(struct rt_pspoll_frame) + 4;
+}
+
+/* IRQL = DISPATCH_LEVEL */
+void ComposeNullFrame(struct rt_rtmp_adapter *pAd)
+{
+	struct rt_txinfo *pTxInfo;
+	struct rt_txwi * pTxWI;
+
+	NdisZeroMemory(&pAd->NullFrame, sizeof(struct rt_header_802_11));
+	pAd->NullFrame.FC.Type = BTYPE_DATA;
+	pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
+	pAd->NullFrame.FC.ToDs = 1;
+	COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
+	COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
+	COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
+	RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.
+		       WirelessPacket[0], 100);
+	pTxInfo =
+	    (struct rt_txinfo *)& pAd->NullContext.TransferBuffer->field.
+	    WirelessPacket[0];
+	RTMPWriteTxInfo(pAd, pTxInfo,
+			(u16)(sizeof(struct rt_header_802_11) + TXWI_SIZE), TRUE,
+			EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
+	pTxWI =
+	    (struct rt_txwi *) & pAd->NullContext.TransferBuffer->field.
+	    WirelessPacket[TXINFO_SIZE];
+	RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0,
+		      BSSID_WCID, (sizeof(struct rt_header_802_11)), 0, 0,
+		      (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
+		      IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
+	RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.
+		       WirelessPacket[TXWI_SIZE + TXINFO_SIZE], &pAd->NullFrame,
+		       sizeof(struct rt_header_802_11));
+	pAd->NullContext.BulkOutSize =
+	    TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
+}
+#endif /* RTMP_MAC_USB // */
 
 /*
 	==========================================================================
@@ -2397,73 +2458,71 @@
 
 	==========================================================================
 */
-ULONG MakeIbssBeacon(
-	IN PRTMP_ADAPTER pAd)
+unsigned long MakeIbssBeacon(struct rt_rtmp_adapter *pAd)
 {
-	UCHAR         DsLen = 1, IbssLen = 2;
-	UCHAR         LocalErpIe[3] = {IE_ERP, 1, 0x04};
-	HEADER_802_11 BcnHdr;
-	USHORT        CapabilityInfo;
+	u8 DsLen = 1, IbssLen = 2;
+	u8 LocalErpIe[3] = { IE_ERP, 1, 0x04 };
+	struct rt_header_802_11 BcnHdr;
+	u16 CapabilityInfo;
 	LARGE_INTEGER FakeTimestamp;
-	ULONG         FrameLen = 0;
-	PTXWI_STRUC	  pTxWI = &pAd->BeaconTxWI;
-	CHAR         *pBeaconFrame = pAd->BeaconBuf;
-	BOOLEAN       Privacy;
-	UCHAR         SupRate[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR         SupRateLen = 0;
-	UCHAR         ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR         ExtRateLen = 0;
-	UCHAR         RSNIe = IE_WPA;
+	unsigned long FrameLen = 0;
+	struct rt_txwi * pTxWI = &pAd->BeaconTxWI;
+	u8 *pBeaconFrame = pAd->BeaconBuf;
+	BOOLEAN Privacy;
+	u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES];
+	u8 SupRateLen = 0;
+	u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+	u8 ExtRateLen = 0;
+	u8 RSNIe = IE_WPA;
 
-	if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
-	{
-		SupRate[0] = 0x82; // 1 mbps
-		SupRate[1] = 0x84; // 2 mbps
-		SupRate[2] = 0x8b; // 5.5 mbps
-		SupRate[3] = 0x96; // 11 mbps
+	if ((pAd->CommonCfg.PhyMode == PHY_11B)
+	    && (pAd->CommonCfg.Channel <= 14)) {
+		SupRate[0] = 0x82;	/* 1 mbps */
+		SupRate[1] = 0x84;	/* 2 mbps */
+		SupRate[2] = 0x8b;	/* 5.5 mbps */
+		SupRate[3] = 0x96;	/* 11 mbps */
 		SupRateLen = 4;
 		ExtRateLen = 0;
-	}
-	else if (pAd->CommonCfg.Channel > 14)
-	{
-		SupRate[0]  = 0x8C;    // 6 mbps, in units of 0.5 Mbps, basic rate
-		SupRate[1]  = 0x12;    // 9 mbps, in units of 0.5 Mbps
-		SupRate[2]  = 0x98;    // 12 mbps, in units of 0.5 Mbps, basic rate
-		SupRate[3]  = 0x24;    // 18 mbps, in units of 0.5 Mbps
-		SupRate[4]  = 0xb0;    // 24 mbps, in units of 0.5 Mbps, basic rate
-		SupRate[5]  = 0x48;    // 36 mbps, in units of 0.5 Mbps
-		SupRate[6]  = 0x60;    // 48 mbps, in units of 0.5 Mbps
-		SupRate[7]  = 0x6c;    // 54 mbps, in units of 0.5 Mbps
-		SupRateLen  = 8;
-		ExtRateLen  = 0;
+	} else if (pAd->CommonCfg.Channel > 14) {
+		SupRate[0] = 0x8C;	/* 6 mbps, in units of 0.5 Mbps, basic rate */
+		SupRate[1] = 0x12;	/* 9 mbps, in units of 0.5 Mbps */
+		SupRate[2] = 0x98;	/* 12 mbps, in units of 0.5 Mbps, basic rate */
+		SupRate[3] = 0x24;	/* 18 mbps, in units of 0.5 Mbps */
+		SupRate[4] = 0xb0;	/* 24 mbps, in units of 0.5 Mbps, basic rate */
+		SupRate[5] = 0x48;	/* 36 mbps, in units of 0.5 Mbps */
+		SupRate[6] = 0x60;	/* 48 mbps, in units of 0.5 Mbps */
+		SupRate[7] = 0x6c;	/* 54 mbps, in units of 0.5 Mbps */
+		SupRateLen = 8;
+		ExtRateLen = 0;
 
-		//
-		// Also Update MlmeRate & RtsRate for G only & A only
-		//
+		/* */
+		/* Also Update MlmeRate & RtsRate for G only & A only */
+		/* */
 		pAd->CommonCfg.MlmeRate = RATE_6;
 		pAd->CommonCfg.RtsRate = RATE_6;
 		pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
-		pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
-		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-	}
-	else
-	{
-		SupRate[0] = 0x82; // 1 mbps
-		SupRate[1] = 0x84; // 2 mbps
-		SupRate[2] = 0x8b; // 5.5 mbps
-		SupRate[3] = 0x96; // 11 mbps
+		pAd->CommonCfg.MlmeTransmit.field.MCS =
+		    OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE =
+		    MODE_OFDM;
+		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS =
+		    OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+	} else {
+		SupRate[0] = 0x82;	/* 1 mbps */
+		SupRate[1] = 0x84;	/* 2 mbps */
+		SupRate[2] = 0x8b;	/* 5.5 mbps */
+		SupRate[3] = 0x96;	/* 11 mbps */
 		SupRateLen = 4;
 
-		ExtRate[0]  = 0x0C;    // 6 mbps, in units of 0.5 Mbps,
-		ExtRate[1]  = 0x12;    // 9 mbps, in units of 0.5 Mbps
-		ExtRate[2]  = 0x18;    // 12 mbps, in units of 0.5 Mbps,
-		ExtRate[3]  = 0x24;    // 18 mbps, in units of 0.5 Mbps
-		ExtRate[4]  = 0x30;    // 24 mbps, in units of 0.5 Mbps,
-		ExtRate[5]  = 0x48;    // 36 mbps, in units of 0.5 Mbps
-		ExtRate[6]  = 0x60;    // 48 mbps, in units of 0.5 Mbps
-		ExtRate[7]  = 0x6c;    // 54 mbps, in units of 0.5 Mbps
-		ExtRateLen  = 8;
+		ExtRate[0] = 0x0C;	/* 6 mbps, in units of 0.5 Mbps, */
+		ExtRate[1] = 0x12;	/* 9 mbps, in units of 0.5 Mbps */
+		ExtRate[2] = 0x18;	/* 12 mbps, in units of 0.5 Mbps, */
+		ExtRate[3] = 0x24;	/* 18 mbps, in units of 0.5 Mbps */
+		ExtRate[4] = 0x30;	/* 24 mbps, in units of 0.5 Mbps, */
+		ExtRate[5] = 0x48;	/* 36 mbps, in units of 0.5 Mbps */
+		ExtRate[6] = 0x60;	/* 48 mbps, in units of 0.5 Mbps */
+		ExtRate[7] = 0x6c;	/* 54 mbps, in units of 0.5 Mbps */
+		ExtRateLen = 8;
 	}
 
 	pAd->StaActive.SupRateLen = SupRateLen;
@@ -2471,99 +2530,96 @@
 	pAd->StaActive.ExtRateLen = ExtRateLen;
 	NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
 
-	// compose IBSS beacon frame
-	MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
-	Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
-			  (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
-			  (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
-	CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
+	/* compose IBSS beacon frame */
+	MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR,
+			 pAd->CommonCfg.Bssid);
+	Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled)
+	    || (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
+	    || (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
+	CapabilityInfo =
+	    CAP_GENERATE(0, 1, Privacy,
+			 (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort),
+			 0, 0);
 
-	MakeOutgoingFrame(pBeaconFrame,                &FrameLen,
-					  sizeof(HEADER_802_11),           &BcnHdr,
-					  TIMESTAMP_LEN,                   &FakeTimestamp,
-					  2,                               &pAd->CommonCfg.BeaconPeriod,
-					  2,                               &CapabilityInfo,
-					  1,                               &SsidIe,
-					  1,                               &pAd->CommonCfg.SsidLen,
-					  pAd->CommonCfg.SsidLen,          pAd->CommonCfg.Ssid,
-					  1,                               &SupRateIe,
-					  1,                               &SupRateLen,
-					  SupRateLen,                      SupRate,
-					  1,                               &DsIe,
-					  1,                               &DsLen,
-					  1,                               &pAd->CommonCfg.Channel,
-					  1,                               &IbssIe,
-					  1,                               &IbssLen,
-					  2,                               &pAd->StaActive.AtimWin,
-					  END_OF_ARGS);
+	MakeOutgoingFrame(pBeaconFrame, &FrameLen,
+			  sizeof(struct rt_header_802_11), &BcnHdr,
+			  TIMESTAMP_LEN, &FakeTimestamp,
+			  2, &pAd->CommonCfg.BeaconPeriod,
+			  2, &CapabilityInfo,
+			  1, &SsidIe,
+			  1, &pAd->CommonCfg.SsidLen,
+			  pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
+			  1, &SupRateIe,
+			  1, &SupRateLen,
+			  SupRateLen, SupRate,
+			  1, &DsIe,
+			  1, &DsLen,
+			  1, &pAd->CommonCfg.Channel,
+			  1, &IbssIe,
+			  1, &IbssLen, 2, &pAd->StaActive.AtimWin, END_OF_ARGS);
 
-	// add ERP_IE and EXT_RAE IE of in 802.11g
-	if (ExtRateLen)
-	{
-		ULONG	tmp;
+	/* add ERP_IE and EXT_RAE IE of in 802.11g */
+	if (ExtRateLen) {
+		unsigned long tmp;
 
-		MakeOutgoingFrame(pBeaconFrame + FrameLen,         &tmp,
-						  3,                               LocalErpIe,
-						  1,                               &ExtRateIe,
-						  1,                               &ExtRateLen,
-						  ExtRateLen,                      ExtRate,
-						  END_OF_ARGS);
+		MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
+				  3, LocalErpIe,
+				  1, &ExtRateIe,
+				  1, &ExtRateLen,
+				  ExtRateLen, ExtRate, END_OF_ARGS);
+		FrameLen += tmp;
+	}
+	/* If adhoc secruity is set for WPA-None, append the cipher suite IE */
+	if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) {
+		unsigned long tmp;
+		RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus,
+			      BSS0);
+
+		MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
+				  1, &RSNIe,
+				  1, &pAd->StaCfg.RSNIE_Len,
+				  pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
+				  END_OF_ARGS);
 		FrameLen += tmp;
 	}
 
-	// If adhoc secruity is set for WPA-None, append the cipher suite IE
-	if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
-	{
-		ULONG tmp;
-        RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
+	if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) {
+		unsigned long TmpLen;
+		u8 HtLen, HtLen1;
 
-		MakeOutgoingFrame(pBeaconFrame + FrameLen,        	&tmp,
-						  1,                              	&RSNIe,
-						  1,                            	&pAd->StaCfg.RSNIE_Len,
-						  pAd->StaCfg.RSNIE_Len,      		pAd->StaCfg.RSN_IE,
-						  END_OF_ARGS);
-		FrameLen += tmp;
-	}
-
-	if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
-	{
-		ULONG TmpLen;
-		UCHAR HtLen, HtLen1;
-
-		// add HT Capability IE
+		/* add HT Capability IE */
 		HtLen = sizeof(pAd->CommonCfg.HtCapability);
 		HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
 
-		MakeOutgoingFrame(pBeaconFrame+FrameLen,	&TmpLen,
-						  1,						&HtCapIe,
-						  1,						&HtLen,
-						  HtLen,					&pAd->CommonCfg.HtCapability,
-						  1,						&AddHtInfoIe,
-						  1,						&HtLen1,
-						  HtLen1,					&pAd->CommonCfg.AddHTInfo,
-						  END_OF_ARGS);
+		MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen,
+				  1, &HtCapIe,
+				  1, &HtLen,
+				  HtLen, &pAd->CommonCfg.HtCapability,
+				  1, &AddHtInfoIe,
+				  1, &HtLen1,
+				  HtLen1, &pAd->CommonCfg.AddHTInfo,
+				  END_OF_ARGS);
 
 		FrameLen += TmpLen;
 	}
-
-	//beacon use reserved WCID 0xff
-    if (pAd->CommonCfg.Channel > 14)
-    {
-	RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE,  TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
-		PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
-    }
-    else
-    {
-        // Set to use 1Mbps for Adhoc beacon.
+	/*beacon use reserved WCID 0xff */
+	if (pAd->CommonCfg.Channel > 14) {
+		RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE,
+			      TRUE, 0, 0xff, FrameLen, PID_MGMT, PID_BEACON,
+			      RATE_1, IFS_HTTXOP, FALSE,
+			      &pAd->CommonCfg.MlmeTransmit);
+	} else {
+		/* Set to use 1Mbps for Adhoc beacon. */
 		HTTRANSMIT_SETTING Transmit;
-        Transmit.word = 0;
-        RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE,  TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
-    		PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
-    }
+		Transmit.word = 0;
+		RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE,
+			      TRUE, 0, 0xff, FrameLen, PID_MGMT, PID_BEACON,
+			      RATE_1, IFS_HTTXOP, FALSE, &Transmit);
+	}
 
-    DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
-					FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
+		  FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel,
+		  pAd->CommonCfg.PhyMode));
 	return FrameLen;
 }
-
-
diff --git a/drivers/staging/rt2860/sta/rtmp_data.c b/drivers/staging/rt2860/sta/rtmp_data.c
index f751ab6..5d348e9 100644
--- a/drivers/staging/rt2860/sta/rtmp_data.c
+++ b/drivers/staging/rt2860/sta/rtmp_data.c
@@ -33,111 +33,167 @@
 	Revision History:
 	Who 		When			What
 	--------	----------		----------------------------------------------
-	John		      Aug/17/04		major modification for RT2561/2661
-	Jan Lee	      Mar/17/06		major modification for RT2860 New Ring Design
 */
 #include "../rt_config.h"
 
-
-
-VOID STARxEAPOLFrameIndicate(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MAC_TABLE_ENTRY	*pEntry,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID)
+void STARxEAPOLFrameIndicate(struct rt_rtmp_adapter *pAd,
+			     struct rt_mac_table_entry *pEntry,
+			     struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
 {
-	PRT28XX_RXD_STRUC	pRxD = &(pRxBlk->RxD);
-	PRXWI_STRUC		pRxWI = pRxBlk->pRxWI;
-	UCHAR			*pTmpBuf;
+	PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
+	struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
+	u8 *pTmpBuf;
 
-	if (pAd->StaCfg.WpaSupplicantUP)
-	{
-		// All EAPoL frames have to pass to upper layer (ex. WPA_SUPPLICANT daemon)
-		// TBD : process fragmented EAPol frames
+	if (pAd->StaCfg.WpaSupplicantUP) {
+		/* All EAPoL frames have to pass to upper layer (ex. WPA_SUPPLICANT daemon) */
+		/* TBD : process fragmented EAPol frames */
 		{
-			// In 802.1x mode, if the received frame is EAP-SUCCESS packet, turn on the PortSecured variable
-			if ( pAd->StaCfg.IEEE8021X == TRUE &&
-				 (EAP_CODE_SUCCESS == WpaCheckEapCode(pAd, pRxBlk->pData, pRxBlk->DataSize, LENGTH_802_1_H)))
-			{
-				PUCHAR	Key;
-				UCHAR 	CipherAlg;
-				int     idx = 0;
+			/* In 802.1x mode, if the received frame is EAP-SUCCESS packet, turn on the PortSecured variable */
+			if (pAd->StaCfg.IEEE8021X == TRUE &&
+			    (EAP_CODE_SUCCESS ==
+			     WpaCheckEapCode(pAd, pRxBlk->pData,
+					     pRxBlk->DataSize,
+					     LENGTH_802_1_H))) {
+				u8 *Key;
+				u8 CipherAlg;
+				int idx = 0;
 
-				DBGPRINT_RAW(RT_DEBUG_TRACE, ("Receive EAP-SUCCESS Packet\n"));
+				DBGPRINT_RAW(RT_DEBUG_TRACE,
+					     ("Receive EAP-SUCCESS Packet\n"));
+				/*pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
 				STA_PORT_SECURED(pAd);
 
-                if (pAd->StaCfg.IEEE8021x_required_keys == FALSE)
-                {
-                    idx = pAd->StaCfg.DesireSharedKeyId;
-                    CipherAlg = pAd->StaCfg.DesireSharedKey[idx].CipherAlg;
-					Key = pAd->StaCfg.DesireSharedKey[idx].Key;
+				if (pAd->StaCfg.IEEE8021x_required_keys ==
+				    FALSE) {
+					idx = pAd->StaCfg.DesireSharedKeyId;
+					CipherAlg =
+					    pAd->StaCfg.DesireSharedKey[idx].
+					    CipherAlg;
+					Key =
+					    pAd->StaCfg.DesireSharedKey[idx].
+					    Key;
 
-                    if (pAd->StaCfg.DesireSharedKey[idx].KeyLen > 0)
-    				{
-#ifdef RT2860
-						MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[BSSID_WCID];
+					if (pAd->StaCfg.DesireSharedKey[idx].
+					    KeyLen > 0) {
+#ifdef RTMP_MAC_PCI
+						struct rt_mac_table_entry *pEntry =
+						    &pAd->MacTab.
+						    Content[BSSID_WCID];
 
-						// Set key material and cipherAlg to Asic
-						AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
+						/* Set key material and cipherAlg to Asic */
+						AsicAddSharedKeyEntry(pAd, BSS0,
+								      idx,
+								      CipherAlg,
+								      Key, NULL,
+								      NULL);
 
-						// Assign group key info
-						RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
+						/* Assign group key info */
+						RTMPAddWcidAttributeEntry(pAd,
+									  BSS0,
+									  idx,
+									  CipherAlg,
+									  NULL);
 
-						// Assign pairwise key info
-						RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
+						/* Assign pairwise key info */
+						RTMPAddWcidAttributeEntry(pAd,
+									  BSS0,
+									  idx,
+									  CipherAlg,
+									  pEntry);
 
-                        pAd->IndicateMediaState = NdisMediaStateConnected;
-                        pAd->ExtraInfo = GENERAL_LINK_UP;
-#endif
-#ifdef RT2870
-						union
-						{
-							char buf[sizeof(NDIS_802_11_WEP)+MAX_LEN_OF_KEY- 1];
-							NDIS_802_11_WEP keyinfo;
-						}  WepKey;
+						pAd->IndicateMediaState =
+						    NdisMediaStateConnected;
+						pAd->ExtraInfo =
+						    GENERAL_LINK_UP;
+#endif /* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
+						union {
+							char buf[sizeof
+								 (struct rt_ndis_802_11_wep)
+								 +
+								 MAX_LEN_OF_KEY
+								 - 1];
+							struct rt_ndis_802_11_wep keyinfo;
+						}
+						WepKey;
 						int len;
 
+						NdisZeroMemory(&WepKey,
+							       sizeof(WepKey));
+						len =
+						    pAd->StaCfg.
+						    DesireSharedKey[idx].KeyLen;
 
-						NdisZeroMemory(&WepKey, sizeof(WepKey));
-						len =pAd->StaCfg.DesireSharedKey[idx].KeyLen;
+						NdisMoveMemory(WepKey.keyinfo.
+							       KeyMaterial,
+							       pAd->StaCfg.
+							       DesireSharedKey
+							       [idx].Key,
+							       pAd->StaCfg.
+							       DesireSharedKey
+							       [idx].KeyLen);
 
-						NdisMoveMemory(WepKey.keyinfo.KeyMaterial,
-							pAd->StaCfg.DesireSharedKey[idx].Key,
-							pAd->StaCfg.DesireSharedKey[idx].KeyLen);
-
-						WepKey.keyinfo.KeyIndex = 0x80000000 + idx;
+						WepKey.keyinfo.KeyIndex =
+						    0x80000000 + idx;
 						WepKey.keyinfo.KeyLength = len;
-						pAd->SharedKey[BSS0][idx].KeyLen =(UCHAR) (len <= 5 ? 5 : 13);
+						pAd->SharedKey[BSS0][idx].
+						    KeyLen =
+						    (u8)(len <= 5 ? 5 : 13);
 
-						pAd->IndicateMediaState = NdisMediaStateConnected;
-						pAd->ExtraInfo = GENERAL_LINK_UP;
-						// need to enqueue cmd to thread
-						RTUSBEnqueueCmdFromNdis(pAd, OID_802_11_ADD_WEP, TRUE, &WepKey, sizeof(WepKey.keyinfo) + len - 1);
-#endif // RT2870 //
-						// For Preventing ShardKey Table is cleared by remove key procedure.
-    					pAd->SharedKey[BSS0][idx].CipherAlg = CipherAlg;
-						pAd->SharedKey[BSS0][idx].KeyLen = pAd->StaCfg.DesireSharedKey[idx].KeyLen;
-						NdisMoveMemory(pAd->SharedKey[BSS0][idx].Key,
-									   pAd->StaCfg.DesireSharedKey[idx].Key,
-									   pAd->StaCfg.DesireSharedKey[idx].KeyLen);
-    				}
+						pAd->IndicateMediaState =
+						    NdisMediaStateConnected;
+						pAd->ExtraInfo =
+						    GENERAL_LINK_UP;
+						/* need to enqueue cmd to thread */
+						RTUSBEnqueueCmdFromNdis(pAd,
+									OID_802_11_ADD_WEP,
+									TRUE,
+									&WepKey,
+									sizeof
+									(WepKey.
+									 keyinfo)
+									+ len -
+									1);
+#endif /* RTMP_MAC_USB // */
+						/* For Preventing ShardKey Table is cleared by remove key procedure. */
+						pAd->SharedKey[BSS0][idx].
+						    CipherAlg = CipherAlg;
+						pAd->SharedKey[BSS0][idx].
+						    KeyLen =
+						    pAd->StaCfg.
+						    DesireSharedKey[idx].KeyLen;
+						NdisMoveMemory(pAd->
+							       SharedKey[BSS0]
+							       [idx].Key,
+							       pAd->StaCfg.
+							       DesireSharedKey
+							       [idx].Key,
+							       pAd->StaCfg.
+							       DesireSharedKey
+							       [idx].KeyLen);
+					}
 				}
 			}
 
 			Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
 			return;
 		}
-	}
-	else
-	{
-		// Special DATA frame that has to pass to MLME
-		//	 1. Cisco Aironet frames for CCX2. We need pass it to MLME for special process
-		//	 2. EAPOL handshaking frames when driver supplicant enabled, pass to MLME for special process
+	} else {
+		/* Special DATA frame that has to pass to MLME */
+		/*       1. Cisco Aironet frames for CCX2. We need pass it to MLME for special process */
+		/*       2. EAPOL handshaking frames when driver supplicant enabled, pass to MLME for special process */
 		{
 			pTmpBuf = pRxBlk->pData - LENGTH_802_11;
 			NdisMoveMemory(pTmpBuf, pRxBlk->pHeader, LENGTH_802_11);
-			REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pTmpBuf, pRxBlk->DataSize + LENGTH_802_11, pRxWI->RSSI0, pRxWI->RSSI1, pRxWI->RSSI2, pRxD->PlcpSignal);
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! report EAPOL/AIRONET DATA to MLME (len=%d) !!!\n", pRxBlk->DataSize));
+			REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID,
+						  pTmpBuf,
+						  pRxBlk->DataSize +
+						  LENGTH_802_11, pRxWI->RSSI0,
+						  pRxWI->RSSI1, pRxWI->RSSI2,
+						  pRxD->PlcpSignal);
+			DBGPRINT_RAW(RT_DEBUG_TRACE,
+				     ("report EAPOL/AIRONET DATA to MLME (len=%d) !\n",
+				      pRxBlk->DataSize));
 		}
 	}
 
@@ -146,495 +202,483 @@
 
 }
 
-VOID STARxDataFrameAnnounce(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MAC_TABLE_ENTRY	*pEntry,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID)
+void STARxDataFrameAnnounce(struct rt_rtmp_adapter *pAd,
+			    struct rt_mac_table_entry *pEntry,
+			    struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
 {
 
-	// non-EAP frame
-	if (!RTMPCheckWPAframe(pAd, pEntry, pRxBlk->pData, pRxBlk->DataSize, FromWhichBSSID))
-	{
+	/* non-EAP frame */
+	if (!RTMPCheckWPAframe
+	    (pAd, pEntry, pRxBlk->pData, pRxBlk->DataSize, FromWhichBSSID)) {
+
 		{
-			// drop all non-EAP DATA frame before
-			// this client's Port-Access-Control is secured
-			if (pRxBlk->pHeader->FC.Wep)
-			{
-				// unsupported cipher suite
-				if (pAd->StaCfg.WepStatus == Ndis802_11EncryptionDisabled)
-				{
-					// release packet
-					RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+			/* drop all non-EAP DATA frame before */
+			/* this client's Port-Access-Control is secured */
+			if (pRxBlk->pHeader->FC.Wep) {
+				/* unsupported cipher suite */
+				if (pAd->StaCfg.WepStatus ==
+				    Ndis802_11EncryptionDisabled) {
+					/* release packet */
+					RELEASE_NDIS_PACKET(pAd,
+							    pRxBlk->pRxPacket,
+							    NDIS_STATUS_FAILURE);
 					return;
 				}
-			}
-			else
-			{
-				// encryption in-use but receive a non-EAPOL clear text frame, drop it
-				if ((pAd->StaCfg.WepStatus != Ndis802_11EncryptionDisabled) &&
-					(pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
-				{
-					// release packet
-					RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+			} else {
+				/* encryption in-use but receive a non-EAPOL clear text frame, drop it */
+				if ((pAd->StaCfg.WepStatus !=
+				     Ndis802_11EncryptionDisabled)
+				    && (pAd->StaCfg.PortSecured ==
+					WPA_802_1X_PORT_NOT_SECURED)) {
+					/* release packet */
+					RELEASE_NDIS_PACKET(pAd,
+							    pRxBlk->pRxPacket,
+							    NDIS_STATUS_FAILURE);
 					return;
 				}
 			}
 		}
 		RX_BLK_CLEAR_FLAG(pRxBlk, fRX_EAP);
-		if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_ARALINK))
-		{
-			// Normal legacy, AMPDU or AMSDU
-			CmmRxnonRalinkFrameIndicate(pAd, pRxBlk, FromWhichBSSID);
+		if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_ARALINK)) {
+			/* Normal legacy, AMPDU or AMSDU */
+			CmmRxnonRalinkFrameIndicate(pAd, pRxBlk,
+						    FromWhichBSSID);
 
+		} else {
+			/* ARALINK */
+			CmmRxRalinkFrameIndicate(pAd, pEntry, pRxBlk,
+						 FromWhichBSSID);
 		}
-		else
-		{
-			// ARALINK
-			CmmRxRalinkFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
-		}
-	}
-	else
-	{
+	} else {
 		RX_BLK_SET_FLAG(pRxBlk, fRX_EAP);
 
-		if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
-		{
+		if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU)
+		    && (pAd->CommonCfg.bDisableReordering == 0)) {
 			Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
-		}
-		else
-		{
-			// Determin the destination of the EAP frame
-			//  to WPA state machine or upper layer
-			STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
+		} else {
+			/* Determin the destination of the EAP frame */
+			/*  to WPA state machine or upper layer */
+			STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk,
+						FromWhichBSSID);
 		}
 	}
 }
 
-
-// For TKIP frame, calculate the MIC value
-BOOLEAN STACheckTkipMICValue(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MAC_TABLE_ENTRY	*pEntry,
-	IN	RX_BLK			*pRxBlk)
+/* For TKIP frame, calculate the MIC value */
+BOOLEAN STACheckTkipMICValue(struct rt_rtmp_adapter *pAd,
+			     struct rt_mac_table_entry *pEntry, struct rt_rx_blk *pRxBlk)
 {
-	PHEADER_802_11	pHeader = pRxBlk->pHeader;
-	UCHAR			*pData = pRxBlk->pData;
-	USHORT			DataSize = pRxBlk->DataSize;
-	UCHAR			UserPriority = pRxBlk->UserPriority;
-	PCIPHER_KEY		pWpaKey;
-	UCHAR			*pDA, *pSA;
+	struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
+	u8 *pData = pRxBlk->pData;
+	u16 DataSize = pRxBlk->DataSize;
+	u8 UserPriority = pRxBlk->UserPriority;
+	struct rt_cipher_key *pWpaKey;
+	u8 *pDA, *pSA;
 
 	pWpaKey = &pAd->SharedKey[BSS0][pRxBlk->pRxWI->KeyIndex];
 
 	pDA = pHeader->Addr1;
-	if (RX_BLK_TEST_FLAG(pRxBlk, fRX_INFRA))
-	{
+	if (RX_BLK_TEST_FLAG(pRxBlk, fRX_INFRA)) {
 		pSA = pHeader->Addr3;
-	}
-	else
-	{
+	} else {
 		pSA = pHeader->Addr2;
 	}
 
 	if (RTMPTkipCompareMICValue(pAd,
-								pData,
-								pDA,
-								pSA,
-								pWpaKey->RxMic,
-								UserPriority,
-								DataSize) == FALSE)
-	{
-		DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error 2\n"));
+				    pData,
+				    pDA,
+				    pSA,
+				    pWpaKey->RxMic,
+				    UserPriority, DataSize) == FALSE) {
+		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Rx MIC Value error 2\n"));
 
-		if (pAd->StaCfg.WpaSupplicantUP)
-		{
-			WpaSendMicFailureToWpaSupplicant(pAd, (pWpaKey->Type == PAIRWISEKEY) ? TRUE : FALSE);
-		}
-		else
-		{
+		if (pAd->StaCfg.WpaSupplicantUP) {
+			WpaSendMicFailureToWpaSupplicant(pAd,
+							 (pWpaKey->Type ==
+							  PAIRWISEKEY) ? TRUE :
+							 FALSE);
+		} else {
 			RTMPReportMicError(pAd, pWpaKey);
 		}
 
-		// release packet
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+		/* release packet */
+		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
+				    NDIS_STATUS_FAILURE);
 		return FALSE;
 	}
 
 	return TRUE;
 }
 
-
-//
-// All Rx routines use RX_BLK structure to hande rx events
-// It is very important to build pRxBlk attributes
-//  1. pHeader pointer to 802.11 Header
-//  2. pData pointer to payload including LLC (just skip Header)
-//  3. set payload size including LLC to DataSize
-//  4. set some flags with RX_BLK_SET_FLAG()
-//
-VOID STAHandleRxDataFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk)
+/* */
+/* All Rx routines use struct rt_rx_blk structure to hande rx events */
+/* It is very important to build pRxBlk attributes */
+/*  1. pHeader pointer to 802.11 Header */
+/*  2. pData pointer to payload including LLC (just skip Header) */
+/*  3. set payload size including LLC to DataSize */
+/*  4. set some flags with RX_BLK_SET_FLAG() */
+/* */
+void STAHandleRxDataFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
 {
-	PRT28XX_RXD_STRUC				pRxD = &(pRxBlk->RxD);
-	PRXWI_STRUC						pRxWI = pRxBlk->pRxWI;
-	PHEADER_802_11					pHeader = pRxBlk->pHeader;
-	PNDIS_PACKET					pRxPacket = pRxBlk->pRxPacket;
-	BOOLEAN 						bFragment = FALSE;
-	MAC_TABLE_ENTRY	    			*pEntry = NULL;
-	UCHAR							FromWhichBSSID = BSS0;
-	UCHAR                           UserPriority = 0;
+	PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
+	struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
+	struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
+	void *pRxPacket = pRxBlk->pRxPacket;
+	BOOLEAN bFragment = FALSE;
+	struct rt_mac_table_entry *pEntry = NULL;
+	u8 FromWhichBSSID = BSS0;
+	u8 UserPriority = 0;
 
 	{
-		// before LINK UP, all DATA frames are rejected
-		if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-		{
-			// release packet
-			RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+		/* before LINK UP, all DATA frames are rejected */
+		if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
+			/* release packet */
+			RELEASE_NDIS_PACKET(pAd, pRxPacket,
+					    NDIS_STATUS_FAILURE);
 			return;
 		}
-
-		// Drop not my BSS frames
-		if (pRxD->MyBss == 0)
-		{
+		/* Drop not my BSS frames */
+		if (pRxD->MyBss == 0) {
 			{
-				// release packet
-				RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+				/* release packet */
+				RELEASE_NDIS_PACKET(pAd, pRxPacket,
+						    NDIS_STATUS_FAILURE);
 				return;
 			}
 		}
 
 		pAd->RalinkCounters.RxCountSinceLastNULL++;
-		if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable && (pHeader->FC.SubType & 0x08))
-		{
-			UCHAR *pData;
-			DBGPRINT(RT_DEBUG_TRACE,("bAPSDCapable\n"));
+		if (pAd->CommonCfg.bAPSDCapable
+		    && pAd->CommonCfg.APEdcaParm.bAPSDCapable
+		    && (pHeader->FC.SubType & 0x08)) {
+			u8 *pData;
+			DBGPRINT(RT_DEBUG_INFO, ("bAPSDCapable\n"));
 
-			// Qos bit 4
-			pData = (PUCHAR)pHeader + LENGTH_802_11;
-			if ((*pData >> 4) & 0x01)
-			{
-				DBGPRINT(RT_DEBUG_TRACE,("RxDone- Rcv EOSP frame, driver may fall into sleep\n"));
+			/* Qos bit 4 */
+			pData = (u8 *)pHeader + LENGTH_802_11;
+			if ((*pData >> 4) & 0x01) {
+				DBGPRINT(RT_DEBUG_INFO,
+					 ("RxDone- Rcv EOSP frame, driver may fall into sleep\n"));
 				pAd->CommonCfg.bInServicePeriod = FALSE;
 
-				// Force driver to fall into sleep mode when rcv EOSP frame
-				if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-				{
-					USHORT  TbttNumToNextWakeUp;
-					USHORT  NextDtim = pAd->StaCfg.DtimPeriod;
-					ULONG   Now;
+				/* Force driver to fall into sleep mode when rcv EOSP frame */
+				if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
+					u16 TbttNumToNextWakeUp;
+					u16 NextDtim =
+					    pAd->StaCfg.DtimPeriod;
+					unsigned long Now;
 
 					NdisGetSystemUpTime(&Now);
-					NextDtim -= (USHORT)(Now - pAd->StaCfg.LastBeaconRxTime)/pAd->CommonCfg.BeaconPeriod;
+					NextDtim -=
+					    (u16)(Now -
+						      pAd->StaCfg.
+						      LastBeaconRxTime) /
+					    pAd->CommonCfg.BeaconPeriod;
 
-					TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
-					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
+					TbttNumToNextWakeUp =
+					    pAd->StaCfg.DefaultListenCount;
+					if (OPSTATUS_TEST_FLAG
+					    (pAd, fOP_STATUS_RECEIVE_DTIM)
+					    && (TbttNumToNextWakeUp > NextDtim))
 						TbttNumToNextWakeUp = NextDtim;
 
-					MlmeSetPsmBit(pAd, PWR_SAVE);
-					// if WMM-APSD is failed, try to disable following line
-					AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
+					RTMP_SET_PSM_BIT(pAd, PWR_SAVE);
+					/* if WMM-APSD is failed, try to disable following line */
+					AsicSleepThenAutoWakeup(pAd,
+								TbttNumToNextWakeUp);
 				}
 			}
 
-			if ((pHeader->FC.MoreData) && (pAd->CommonCfg.bInServicePeriod))
-			{
-				DBGPRINT(RT_DEBUG_TRACE,("Sending another trigger frame when More Data bit is set to 1\n"));
+			if ((pHeader->FC.MoreData)
+			    && (pAd->CommonCfg.bInServicePeriod)) {
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("Sending another trigger frame when More Data bit is set to 1\n"));
 			}
 		}
-
-		// Drop NULL, CF-ACK(no data), CF-POLL(no data), and CF-ACK+CF-POLL(no data) data frame
-		if ((pHeader->FC.SubType & 0x04)) // bit 2 : no DATA
+		/* Drop NULL, CF-ACK(no data), CF-POLL(no data), and CF-ACK+CF-POLL(no data) data frame */
+		if ((pHeader->FC.SubType & 0x04))	/* bit 2 : no DATA */
 		{
-			// release packet
-			RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+			/* release packet */
+			RELEASE_NDIS_PACKET(pAd, pRxPacket,
+					    NDIS_STATUS_FAILURE);
 			return;
 		}
+		/* Drop not my BSS frame (we can not only check the MyBss bit in RxD) */
 
-	    // Drop not my BSS frame (we can not only check the MyBss bit in RxD)
-
-		if (INFRA_ON(pAd))
-		{
-			// Infrastructure mode, check address 2 for BSSID
-			if (!RTMPEqualMemory(&pHeader->Addr2, &pAd->CommonCfg.Bssid, 6))
-			{
-				// Receive frame not my BSSID
-	            // release packet
-	            RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+		if (INFRA_ON(pAd)) {
+			/* Infrastructure mode, check address 2 for BSSID */
+			if (!RTMPEqualMemory
+			    (&pHeader->Addr2, &pAd->CommonCfg.Bssid, 6)) {
+				/* Receive frame not my BSSID */
+				/* release packet */
+				RELEASE_NDIS_PACKET(pAd, pRxPacket,
+						    NDIS_STATUS_FAILURE);
 				return;
 			}
-		}
-		else	// Ad-Hoc mode or Not associated
+		} else		/* Ad-Hoc mode or Not associated */
 		{
-			// Ad-Hoc mode, check address 3 for BSSID
-			if (!RTMPEqualMemory(&pHeader->Addr3, &pAd->CommonCfg.Bssid, 6))
-			{
-				// Receive frame not my BSSID
-	            // release packet
-	            RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+			/* Ad-Hoc mode, check address 3 for BSSID */
+			if (!RTMPEqualMemory
+			    (&pHeader->Addr3, &pAd->CommonCfg.Bssid, 6)) {
+				/* Receive frame not my BSSID */
+				/* release packet */
+				RELEASE_NDIS_PACKET(pAd, pRxPacket,
+						    NDIS_STATUS_FAILURE);
 				return;
 			}
 		}
 
-		//
-		// find pEntry
-		//
-		if (pRxWI->WirelessCliID < MAX_LEN_OF_MAC_TABLE)
-		{
+		/* */
+		/* find pEntry */
+		/* */
+		if (pRxWI->WirelessCliID < MAX_LEN_OF_MAC_TABLE) {
 			pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
-		}
-		else
-		{
-			// 1. release packet if infra mode
-			// 2. new a pEntry if ad-hoc mode
-			RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+		} else {
+			/* 1. release packet if infra mode */
+			/* 2. new a pEntry if ad-hoc mode */
+			RELEASE_NDIS_PACKET(pAd, pRxPacket,
+					    NDIS_STATUS_FAILURE);
 			return;
 		}
 
-		// infra or ad-hoc
-		if (INFRA_ON(pAd))
-		{
+		/* infra or ad-hoc */
+		if (INFRA_ON(pAd)) {
 			RX_BLK_SET_FLAG(pRxBlk, fRX_INFRA);
 			ASSERT(pRxWI->WirelessCliID == BSSID_WCID);
 		}
-
-		// check Atheros Client
-		if ((pEntry->bIAmBadAtheros == FALSE) &&  (pRxD->AMPDU == 1) && (pHeader->FC.Retry ))
-		{
+		/* check Atheros Client */
+		if ((pEntry->bIAmBadAtheros == FALSE) && (pRxD->AMPDU == 1)
+		    && (pHeader->FC.Retry)) {
 			pEntry->bIAmBadAtheros = TRUE;
 			pAd->CommonCfg.IOTestParm.bCurrentAtheros = TRUE;
 			pAd->CommonCfg.IOTestParm.bLastAtheros = TRUE;
-			if (!STA_AES_ON(pAd))
-			{
-				AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, TRUE, FALSE);
+			if (!STA_AES_ON(pAd)) {
+				AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, TRUE,
+						  FALSE);
 			}
 		}
 	}
 
-	pRxBlk->pData = (UCHAR *)pHeader;
+	pRxBlk->pData = (u8 *) pHeader;
 
-	//
-	// update RxBlk->pData, DataSize
-	// 802.11 Header, QOS, HTC, Hw Padding
-	//
+	/* */
+	/* update RxBlk->pData, DataSize */
+	/* 802.11 Header, QOS, HTC, Hw Padding */
+	/* */
 
-	// 1. skip 802.11 HEADER
+	/* 1. skip 802.11 HEADER */
 	{
 		pRxBlk->pData += LENGTH_802_11;
 		pRxBlk->DataSize -= LENGTH_802_11;
 	}
 
-	// 2. QOS
-	if (pHeader->FC.SubType & 0x08)
-	{
+	/* 2. QOS */
+	if (pHeader->FC.SubType & 0x08) {
 		RX_BLK_SET_FLAG(pRxBlk, fRX_QOS);
 		UserPriority = *(pRxBlk->pData) & 0x0f;
-		// bit 7 in QoS Control field signals the HT A-MSDU format
-		if ((*pRxBlk->pData) & 0x80)
-		{
+		/* bit 7 in QoS Control field signals the HT A-MSDU format */
+		if ((*pRxBlk->pData) & 0x80) {
 			RX_BLK_SET_FLAG(pRxBlk, fRX_AMSDU);
 		}
-
-		// skip QOS contorl field
+		/* skip QOS contorl field */
 		pRxBlk->pData += 2;
-		pRxBlk->DataSize -=2;
+		pRxBlk->DataSize -= 2;
 	}
 	pRxBlk->UserPriority = UserPriority;
 
-	// 3. Order bit: A-Ralink or HTC+
-	if (pHeader->FC.Order)
-	{
+	/* check if need to resend PS Poll when received packet with MoreData = 1 */
+	if ((pAd->StaCfg.Psm == PWR_SAVE) && (pHeader->FC.MoreData == 1)) {
+		if ((((UserPriority == 0) || (UserPriority == 3)) &&
+		     pAd->CommonCfg.bAPSDAC_BE == 0) ||
+		    (((UserPriority == 1) || (UserPriority == 2)) &&
+		     pAd->CommonCfg.bAPSDAC_BK == 0) ||
+		    (((UserPriority == 4) || (UserPriority == 5)) &&
+		     pAd->CommonCfg.bAPSDAC_VI == 0) ||
+		    (((UserPriority == 6) || (UserPriority == 7)) &&
+		     pAd->CommonCfg.bAPSDAC_VO == 0)) {
+			/* non-UAPSD delivery-enabled AC */
+			RTMP_PS_POLL_ENQUEUE(pAd);
+		}
+	}
+	/* 3. Order bit: A-Ralink or HTC+ */
+	if (pHeader->FC.Order) {
 #ifdef AGGREGATION_SUPPORT
-		if ((pRxWI->PHYMODE <= MODE_OFDM) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)))
+		if ((pRxWI->PHYMODE <= MODE_OFDM)
+		    && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)))
 		{
 			RX_BLK_SET_FLAG(pRxBlk, fRX_ARALINK);
-		}
-		else
-#endif
+		} else
+#endif /* AGGREGATION_SUPPORT // */
 		{
 			RX_BLK_SET_FLAG(pRxBlk, fRX_HTC);
-			// skip HTC contorl field
+			/* skip HTC contorl field */
 			pRxBlk->pData += 4;
 			pRxBlk->DataSize -= 4;
 		}
 	}
-
-	// 4. skip HW padding
-	if (pRxD->L2PAD)
-	{
-		// just move pData pointer
-		// because DataSize excluding HW padding
+	/* 4. skip HW padding */
+	if (pRxD->L2PAD) {
+		/* just move pData pointer */
+		/* because DataSize excluding HW padding */
 		RX_BLK_SET_FLAG(pRxBlk, fRX_PAD);
 		pRxBlk->pData += 2;
 	}
 
-	if (pRxD->BA)
-	{
+	if (pRxD->BA) {
 		RX_BLK_SET_FLAG(pRxBlk, fRX_AMPDU);
 	}
-
-	//
-	// Case I  Process Broadcast & Multicast data frame
-	//
-	if (pRxD->Bcast || pRxD->Mcast)
-	{
+	/* */
+	/* Case I  Process Broadcast & Multicast data frame */
+	/* */
+	if (pRxD->Bcast || pRxD->Mcast) {
 		INC_COUNTER64(pAd->WlanCounters.MulticastReceivedFrameCount);
 
-		// Drop Mcast/Bcast frame with fragment bit on
-		if (pHeader->FC.MoreFrag)
-		{
-			// release packet
-			RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+		/* Drop Mcast/Bcast frame with fragment bit on */
+		if (pHeader->FC.MoreFrag) {
+			/* release packet */
+			RELEASE_NDIS_PACKET(pAd, pRxPacket,
+					    NDIS_STATUS_FAILURE);
 			return;
 		}
-
-		// Filter out Bcast frame which AP relayed for us
-		if (pHeader->FC.FrDs && MAC_ADDR_EQUAL(pHeader->Addr3, pAd->CurrentAddress))
-		{
-			// release packet
-			RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+		/* Filter out Bcast frame which AP relayed for us */
+		if (pHeader->FC.FrDs
+		    && MAC_ADDR_EQUAL(pHeader->Addr3, pAd->CurrentAddress)) {
+			/* release packet */
+			RELEASE_NDIS_PACKET(pAd, pRxPacket,
+					    NDIS_STATUS_FAILURE);
 			return;
 		}
 
 		Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
 		return;
-	}
-	else if (pRxD->U2M)
-	{
-		pAd->LastRxRate = (USHORT)((pRxWI->MCS) + (pRxWI->BW <<7) + (pRxWI->ShortGI <<8)+ (pRxWI->PHYMODE <<14)) ;
+	} else if (pRxD->U2M) {
+		pAd->LastRxRate =
+		    (u16)((pRxWI->MCS) + (pRxWI->BW << 7) +
+			      (pRxWI->ShortGI << 8) + (pRxWI->PHYMODE << 14));
 
-		if (ADHOC_ON(pAd))
-		{
+		if (ADHOC_ON(pAd)) {
 			pEntry = MacTableLookup(pAd, pHeader->Addr2);
 			if (pEntry)
-				Update_Rssi_Sample(pAd, &pEntry->RssiSample, pRxWI);
+				Update_Rssi_Sample(pAd, &pEntry->RssiSample,
+						   pRxWI);
 		}
 
-
 		Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
 
-		pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0);
-		pAd->StaCfg.LastSNR1 = (UCHAR)(pRxWI->SNR1);
+		pAd->StaCfg.LastSNR0 = (u8)(pRxWI->SNR0);
+		pAd->StaCfg.LastSNR1 = (u8)(pRxWI->SNR1);
 
 		pAd->RalinkCounters.OneSecRxOkDataCnt++;
 
+		if (!((pHeader->Frag == 0) && (pHeader->FC.MoreFrag == 0))) {
+			/* re-assemble the fragmented packets */
+			/* return complete frame (pRxPacket) or NULL */
+			bFragment = TRUE;
+			pRxPacket = RTMPDeFragmentDataFrame(pAd, pRxBlk);
+		}
 
-    	if (!((pHeader->Frag == 0) && (pHeader->FC.MoreFrag == 0)))
-    	{
-    		// re-assemble the fragmented packets
-    		// return complete frame (pRxPacket) or NULL
-    		bFragment = TRUE;
-    		pRxPacket = RTMPDeFragmentDataFrame(pAd, pRxBlk);
-    	}
-
-    	if (pRxPacket)
-    	{
+		if (pRxPacket) {
 			pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
 
-    		// process complete frame
-    		if (bFragment && (pRxD->Decrypted) && (pEntry->WepStatus == Ndis802_11Encryption2Enabled))
-    		{
-				// Minus MIC length
+			/* process complete frame */
+			if (bFragment && (pRxD->Decrypted)
+			    && (pEntry->WepStatus ==
+				Ndis802_11Encryption2Enabled)) {
+				/* Minus MIC length */
 				pRxBlk->DataSize -= 8;
 
-    			// For TKIP frame, calculate the MIC value
-    			if (STACheckTkipMICValue(pAd, pEntry, pRxBlk) == FALSE)
-    			{
-    				return;
-    			}
-    		}
+				/* For TKIP frame, calculate the MIC value */
+				if (STACheckTkipMICValue(pAd, pEntry, pRxBlk) ==
+				    FALSE) {
+					return;
+				}
+			}
 
-    		STARxDataFrameAnnounce(pAd, pEntry, pRxBlk, FromWhichBSSID);
+			STARxDataFrameAnnounce(pAd, pEntry, pRxBlk,
+					       FromWhichBSSID);
 			return;
-    	}
-    	else
-    	{
-    		// just return
-    		// because RTMPDeFragmentDataFrame() will release rx packet,
-    		// if packet is fragmented
-    		return;
-    	}
+		} else {
+			/* just return */
+			/* because RTMPDeFragmentDataFrame() will release rx packet, */
+			/* if packet is fragmented */
+			return;
+		}
 	}
 
 	ASSERT(0);
-	// release packet
+	/* release packet */
 	RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
 }
 
-VOID STAHandleRxMgmtFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk)
+void STAHandleRxMgmtFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
 {
-	PRT28XX_RXD_STRUC	pRxD = &(pRxBlk->RxD);
-	PRXWI_STRUC		pRxWI = pRxBlk->pRxWI;
-	PHEADER_802_11	pHeader = pRxBlk->pHeader;
-	PNDIS_PACKET	pRxPacket = pRxBlk->pRxPacket;
+	PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
+	struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
+	struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
+	void *pRxPacket = pRxBlk->pRxPacket;
 
-	do
-	{
+	do {
 
-		// We should collect RSSI not only U2M data but also my beacon
-		if (pAd->RxAnt.EvaluatePeriod == 0 &&
-		    pHeader->FC.SubType == SUBTYPE_BEACON &&
-		    MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2)) {
-			Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
-
-			pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0);
-			pAd->StaCfg.LastSNR1 = (UCHAR)(pRxWI->SNR1);
-		}
-
-#ifdef RT2870
-		// collect rssi information for antenna diversity
-		if (pAd->NicConfig2.field.AntDiversity)
-		{
-			if ((pRxD->U2M) || ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2))))
-			{
-					COLLECT_RX_ANTENNA_AVERAGE_RSSI(pAd, ConvertToRssi(pAd, (UCHAR)pRxWI->RSSI0, RSSI_0), 0); //Note: RSSI2 not used on RT73
-					pAd->StaCfg.NumOfAvgRssiSample ++;
+		/* check if need to resend PS Poll when received packet with MoreData = 1 */
+		if ((pAd->StaCfg.Psm == PWR_SAVE)
+		    && (pHeader->FC.MoreData == 1)) {
+			/* for UAPSD, all management frames will be VO priority */
+			if (pAd->CommonCfg.bAPSDAC_VO == 0) {
+				/* non-UAPSD delivery-enabled AC */
+				RTMP_PS_POLL_ENQUEUE(pAd);
 			}
 		}
-#endif
 
-		// First check the size, it MUST not exceed the mlme queue size
-		if (pRxWI->MPDUtotalByteCount > MGMT_DMA_BUFFER_SIZE)
-		{
+		/* TODO: if MoreData == 0, station can go to sleep */
+
+		/* We should collect RSSI not only U2M data but also my beacon */
+		if ((pHeader->FC.SubType == SUBTYPE_BEACON)
+		    && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2))
+		    && (pAd->RxAnt.EvaluatePeriod == 0)) {
+			Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
+
+			pAd->StaCfg.LastSNR0 = (u8)(pRxWI->SNR0);
+			pAd->StaCfg.LastSNR1 = (u8)(pRxWI->SNR1);
+		}
+
+		/* First check the size, it MUST not exceed the mlme queue size */
+		if (pRxWI->MPDUtotalByteCount > MGMT_DMA_BUFFER_SIZE) {
 			DBGPRINT_ERR(("STAHandleRxMgmtFrame: frame too large, size = %d \n", pRxWI->MPDUtotalByteCount));
 			break;
 		}
 
-		REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pHeader, pRxWI->MPDUtotalByteCount,
-									pRxWI->RSSI0, pRxWI->RSSI1, pRxWI->RSSI2, pRxD->PlcpSignal);
+		REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pHeader,
+					  pRxWI->MPDUtotalByteCount,
+					  pRxWI->RSSI0, pRxWI->RSSI1,
+					  pRxWI->RSSI2, pRxD->PlcpSignal);
 	} while (FALSE);
 
 	RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
 }
 
-VOID STAHandleRxControlFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk)
+void STAHandleRxControlFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
 {
-	PRXWI_STRUC		pRxWI = pRxBlk->pRxWI;
-	PHEADER_802_11	pHeader = pRxBlk->pHeader;
-	PNDIS_PACKET	pRxPacket = pRxBlk->pRxPacket;
+	struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
+	struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
+	void *pRxPacket = pRxBlk->pRxPacket;
 
-	switch (pHeader->FC.SubType)
-	{
-		case SUBTYPE_BLOCK_ACK_REQ:
-			{
-				CntlEnqueueForRecv(pAd, pRxWI->WirelessCliID, (pRxWI->MPDUtotalByteCount), (PFRAME_BA_REQ)pHeader);
-			}
-			break;
-		case SUBTYPE_BLOCK_ACK:
-		case SUBTYPE_ACK:
-		default:
-			break;
+	switch (pHeader->FC.SubType) {
+	case SUBTYPE_BLOCK_ACK_REQ:
+		{
+			CntlEnqueueForRecv(pAd, pRxWI->WirelessCliID,
+					   (pRxWI->MPDUtotalByteCount),
+					   (struct rt_frame_ba_req *) pHeader);
+		}
+		break;
+	case SUBTYPE_BLOCK_ACK:
+	case SUBTYPE_ACK:
+	default:
+		break;
 	}
 
 	RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
 }
 
-
 /*
 	========================================================================
 
@@ -654,141 +698,127 @@
 		Need to consider QOS DATA format when converting to 802.3
 	========================================================================
 */
-BOOLEAN STARxDoneInterruptHandle(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	BOOLEAN			argc)
+BOOLEAN STARxDoneInterruptHandle(struct rt_rtmp_adapter *pAd, IN BOOLEAN argc)
 {
-	NDIS_STATUS			Status;
-	UINT32			RxProcessed, RxPending;
-	BOOLEAN			bReschedule = FALSE;
-	RT28XX_RXD_STRUC	*pRxD;
-	UCHAR			*pData;
-	PRXWI_STRUC		pRxWI;
-	PNDIS_PACKET	pRxPacket;
-	PHEADER_802_11	pHeader;
-	RX_BLK			RxCell;
+	int Status;
+	u32 RxProcessed, RxPending;
+	BOOLEAN bReschedule = FALSE;
+	PRT28XX_RXD_STRUC pRxD;
+	u8 *pData;
+	struct rt_rxwi * pRxWI;
+	void *pRxPacket;
+	struct rt_header_802_11 * pHeader;
+	struct rt_rx_blk RxCell;
 
 	RxProcessed = RxPending = 0;
 
-	// process whole rx ring
-	while (1)
-	{
+	/* process whole rx ring */
+	while (1) {
 
 		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF |
-								fRTMP_ADAPTER_RESET_IN_PROGRESS |
-								fRTMP_ADAPTER_HALT_IN_PROGRESS |
-								fRTMP_ADAPTER_NIC_NOT_EXIST) ||
-			!RTMP_TEST_FLAG(pAd,fRTMP_ADAPTER_START_UP))
-		{
+				   fRTMP_ADAPTER_RESET_IN_PROGRESS |
+				   fRTMP_ADAPTER_HALT_IN_PROGRESS |
+				   fRTMP_ADAPTER_NIC_NOT_EXIST) ||
+		    !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) {
 			break;
 		}
-
-#ifdef RT2860
-		if (RxProcessed++ > MAX_RX_PROCESS_CNT)
-		{
-			// need to reschedule rx handle
+#ifdef RTMP_MAC_PCI
+		if (RxProcessed++ > MAX_RX_PROCESS_CNT) {
+			/* need to reschedule rx handle */
 			bReschedule = TRUE;
 			break;
 		}
-#endif
+#endif /* RTMP_MAC_PCI // */
 
-		RxProcessed ++; // test
+		RxProcessed++;	/* test */
 
-		// 1. allocate a new data packet into rx ring to replace received packet
-		//    then processing the received packet
-		// 2. the callee must take charge of release of packet
-		// 3. As far as driver is concerned ,
-		//    the rx packet must
-		//      a. be indicated to upper layer or
-		//      b. be released if it is discarded
-		pRxPacket = GetPacketFromRxRing(pAd, &(RxCell.RxD), &bReschedule, &RxPending);
-		if (pRxPacket == NULL)
-		{
-			// no more packet to process
+		/* 1. allocate a new data packet into rx ring to replace received packet */
+		/*    then processing the received packet */
+		/* 2. the callee must take charge of release of packet */
+		/* 3. As far as driver is concerned , */
+		/*    the rx packet must */
+		/*      a. be indicated to upper layer or */
+		/*      b. be released if it is discarded */
+		pRxPacket =
+		    GetPacketFromRxRing(pAd, &(RxCell.RxD), &bReschedule,
+					&RxPending);
+		if (pRxPacket == NULL) {
+			/* no more packet to process */
 			break;
 		}
-
-		// get rx ring descriptor
+		/* get rx ring descriptor */
 		pRxD = &(RxCell.RxD);
-		// get rx data buffer
-		pData	= GET_OS_PKT_DATAPTR(pRxPacket);
-		pRxWI	= (PRXWI_STRUC) pData;
-		pHeader = (PHEADER_802_11) (pData+RXWI_SIZE) ;
+		/* get rx data buffer */
+		pData = GET_OS_PKT_DATAPTR(pRxPacket);
+		pRxWI = (struct rt_rxwi *) pData;
+		pHeader = (struct rt_header_802_11 *) (pData + RXWI_SIZE);
 
-		// build RxCell
+		/* build RxCell */
 		RxCell.pRxWI = pRxWI;
 		RxCell.pHeader = pHeader;
 		RxCell.pRxPacket = pRxPacket;
-		RxCell.pData = (UCHAR *) pHeader;
+		RxCell.pData = (u8 *) pHeader;
 		RxCell.DataSize = pRxWI->MPDUtotalByteCount;
 		RxCell.Flags = 0;
 
-		// Increase Total receive byte counter after real data received no mater any error or not
-		pAd->RalinkCounters.ReceivedByteCount +=  pRxWI->MPDUtotalByteCount;
-		pAd->RalinkCounters.RxCount ++;
+		/* Increase Total receive byte counter after real data received no mater any error or not */
+		pAd->RalinkCounters.ReceivedByteCount +=
+		    pRxWI->MPDUtotalByteCount;
+		pAd->RalinkCounters.OneSecReceivedByteCount +=
+		    pRxWI->MPDUtotalByteCount;
+		pAd->RalinkCounters.RxCount++;
 
 		INC_COUNTER64(pAd->WlanCounters.ReceivedFragmentCount);
 
 		if (pRxWI->MPDUtotalByteCount < 14)
 			Status = NDIS_STATUS_FAILURE;
 
-        if (MONITOR_ON(pAd))
-		{
-            send_monitor_packets(pAd, &RxCell);
+		if (MONITOR_ON(pAd)) {
+			send_monitor_packets(pAd, &RxCell);
 			break;
 		}
-		/* RT2870 invokes STARxDoneInterruptHandle() in rtusb_bulk.c */
 
-		// Check for all RxD errors
+		/* STARxDoneInterruptHandle() is called in rtusb_bulk.c */
+
+		/* Check for all RxD errors */
 		Status = RTMPCheckRxError(pAd, pHeader, pRxWI, pRxD);
 
-		// Handle the received frame
-		if (Status == NDIS_STATUS_SUCCESS)
-		{
-			switch (pHeader->FC.Type)
-			{
-				// CASE I, receive a DATA frame
-				case BTYPE_DATA:
+		/* Handle the received frame */
+		if (Status == NDIS_STATUS_SUCCESS) {
+			switch (pHeader->FC.Type) {
+				/* CASE I, receive a DATA frame */
+			case BTYPE_DATA:
 				{
-					// process DATA frame
+					/* process DATA frame */
 					STAHandleRxDataFrame(pAd, &RxCell);
 				}
 				break;
-				// CASE II, receive a MGMT frame
-				case BTYPE_MGMT:
+				/* CASE II, receive a MGMT frame */
+			case BTYPE_MGMT:
 				{
 					STAHandleRxMgmtFrame(pAd, &RxCell);
 				}
 				break;
-				// CASE III. receive a CNTL frame
-				case BTYPE_CNTL:
+				/* CASE III. receive a CNTL frame */
+			case BTYPE_CNTL:
 				{
 					STAHandleRxControlFrame(pAd, &RxCell);
 				}
 				break;
-				// discard other type
-				default:
-					RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
-					break;
+				/* discard other type */
+			default:
+				RELEASE_NDIS_PACKET(pAd, pRxPacket,
+						    NDIS_STATUS_FAILURE);
+				break;
 			}
-		}
-		else
-		{
+		} else {
 			pAd->Counters8023.RxErrors++;
-			// discard this frame
-			RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+			/* discard this frame */
+			RELEASE_NDIS_PACKET(pAd, pRxPacket,
+					    NDIS_STATUS_FAILURE);
 		}
 	}
 
-#ifdef RT2860
-	// fRTMP_PS_GO_TO_SLEEP_NOW is set if receiving beacon.
-	if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW) && (INFRA_ON(pAd)))
-	{
-		RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
-		AsicSleepThenAutoWakeup(pAd, pAd->ThisTbttNumToNextWakeUp);
-		bReschedule = FALSE;
-	}
-#endif
 	return bReschedule;
 }
 
@@ -803,15 +833,9 @@
 
 	========================================================================
 */
-VOID	RTMPHandleTwakeupInterrupt(
-	IN PRTMP_ADAPTER pAd)
+void RTMPHandleTwakeupInterrupt(struct rt_rtmp_adapter *pAd)
 {
-#ifdef RT2860
-	AsicForceWakeup(pAd, DOT11POWERSAVE);
-#endif
-#ifdef RT2870
 	AsicForceWakeup(pAd, FALSE);
-#endif
 }
 
 /*
@@ -820,9 +844,9 @@
     Early checking and OS-depened parsing for Tx packet send to our STA driver.
 
 Arguments:
-    NDIS_HANDLE 	MiniportAdapterContext	Pointer refer to the device handle, i.e., the pAd.
-	PPNDIS_PACKET	ppPacketArray			The packet array need to do transmission.
-	UINT			NumberOfPackets			Number of packet in packet array.
+    void *	MiniportAdapterContext	Pointer refer to the device handle, i.e., the pAd.
+	void **	ppPacketArray			The packet array need to do transmission.
+	u32			NumberOfPackets			Number of packet in packet array.
 
 Return Value:
 	NONE
@@ -832,47 +856,39 @@
 	You only can put OS-depened & STA related code in here.
 ========================================================================
 */
-VOID STASendPackets(
-	IN	NDIS_HANDLE		MiniportAdapterContext,
-	IN	PPNDIS_PACKET	ppPacketArray,
-	IN	UINT			NumberOfPackets)
+void STASendPackets(void *MiniportAdapterContext,
+		    void **ppPacketArray, u32 NumberOfPackets)
 {
-	UINT			Index;
-	PRTMP_ADAPTER	pAd = (PRTMP_ADAPTER) MiniportAdapterContext;
-	PNDIS_PACKET	pPacket;
-	BOOLEAN			allowToSend = FALSE;
+	u32 Index;
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)MiniportAdapterContext;
+	void *pPacket;
+	BOOLEAN allowToSend = FALSE;
 
-
-	for (Index = 0; Index < NumberOfPackets; Index++)
-	{
+	for (Index = 0; Index < NumberOfPackets; Index++) {
 		pPacket = ppPacketArray[Index];
 
-		do
-		{
-			if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
-				RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
-				RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
-			{
-				// Drop send request since hardware is in reset state
-					break;
-			}
-			else if (!INFRA_ON(pAd) && !ADHOC_ON(pAd))
-			{
-				// Drop send request since there are no physical connection yet
-					break;
-			}
-			else
-			{
-				// Record that orignal packet source is from NDIS layer,so that
-				// later on driver knows how to release this NDIS PACKET
-				RTMP_SET_PACKET_WCID(pPacket, 0); // this field is useless when in STA mode
+		do {
+			if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)
+			    || RTMP_TEST_FLAG(pAd,
+					      fRTMP_ADAPTER_HALT_IN_PROGRESS)
+			    || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) {
+				/* Drop send request since hardware is in reset state */
+				break;
+			} else if (!INFRA_ON(pAd) && !ADHOC_ON(pAd)) {
+				/* Drop send request since there are no physical connection yet */
+				break;
+			} else {
+				/* Record that orignal packet source is from NDIS layer,so that */
+				/* later on driver knows how to release this NDIS PACKET */
+				RTMP_SET_PACKET_WCID(pPacket, 0);	/* this field is useless when in STA mode */
 				RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
-				NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_PENDING);
+				NDIS_SET_PACKET_STATUS(pPacket,
+						       NDIS_STATUS_PENDING);
 				pAd->RalinkCounters.PendingNdisPacketCount++;
 
 				allowToSend = TRUE;
 			}
-		} while(FALSE);
+		} while (FALSE);
 
 		if (allowToSend == TRUE)
 			STASendPacket(pAd, pPacket);
@@ -880,12 +896,11 @@
 			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
 	}
 
-	// Dequeue outgoing frames from TxSwQueue[] and process it
+	/* Dequeue outgoing frames from TxSwQueue[] and process it */
 	RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
 
 }
 
-
 /*
 ========================================================================
 Routine Description:
@@ -898,201 +913,199 @@
 	pPacket 	Pointer to send packet
 
 Return Value:
-	NDIS_STATUS_SUCCESS			If succes to queue the packet into TxSwQueue.
+	NDIS_STATUS_SUCCESS			If success to queue the packet into TxSwQueue.
 	NDIS_STATUS_FAILURE			If failed to do en-queue.
 
 Note:
 	You only can put OS-indepened & STA related code in here.
 ========================================================================
 */
-NDIS_STATUS STASendPacket(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket)
+int STASendPacket(struct rt_rtmp_adapter *pAd, void *pPacket)
 {
-	PACKET_INFO 	PacketInfo;
-	PUCHAR			pSrcBufVA;
-	UINT			SrcBufLen;
-	UINT			AllowFragSize;
-	UCHAR			NumberOfFrag;
-	UCHAR			QueIdx, UserPriority;
-	MAC_TABLE_ENTRY *pEntry = NULL;
-	unsigned int 	IrqFlags;
-	UCHAR			FlgIsIP = 0;
-	UCHAR			Rate;
+	struct rt_packet_info PacketInfo;
+	u8 *pSrcBufVA;
+	u32 SrcBufLen;
+	u32 AllowFragSize;
+	u8 NumberOfFrag;
+	u8 RTSRequired;
+	u8 QueIdx, UserPriority;
+	struct rt_mac_table_entry *pEntry = NULL;
+	unsigned int IrqFlags;
+	u8 FlgIsIP = 0;
+	u8 Rate;
 
-	// Prepare packet information structure for buffer descriptor
-	// chained within a single NDIS packet.
+	/* Prepare packet information structure for buffer descriptor */
+	/* chained within a single NDIS packet. */
 	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
 
-	if (pSrcBufVA == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("STASendPacket --> pSrcBufVA == NULL !!!SrcBufLen=%x\n",SrcBufLen));
-		// Resourece is low, system did not allocate virtual address
-		// return NDIS_STATUS_FAILURE directly to upper layer
+	if (pSrcBufVA == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("STASendPacket --> pSrcBufVA == NULL !SrcBufLen=%x\n",
+			  SrcBufLen));
+		/* Resourece is low, system did not allocate virtual address */
+		/* return NDIS_STATUS_FAILURE directly to upper layer */
 		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
 		return NDIS_STATUS_FAILURE;
 	}
 
-
-	if (SrcBufLen < 14)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("STASendPacket --> Ndis Packet buffer error !!!\n"));
+	if (SrcBufLen < 14) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("STASendPacket --> Ndis Packet buffer error!\n"));
 		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
 		return (NDIS_STATUS_FAILURE);
 	}
-
-	// In HT rate adhoc mode, A-MPDU is often used. So need to lookup BA Table and MAC Entry.
-	// Note multicast packets in adhoc also use BSSID_WCID index.
+	/* In HT rate adhoc mode, A-MPDU is often used. So need to lookup BA Table and MAC Entry. */
+	/* Note multicast packets in adhoc also use BSSID_WCID index. */
 	{
-		if(INFRA_ON(pAd))
-		{
+		if (INFRA_ON(pAd)) {
 			{
-			pEntry = &pAd->MacTab.Content[BSSID_WCID];
-			RTMP_SET_PACKET_WCID(pPacket, BSSID_WCID);
-			Rate = pAd->CommonCfg.TxRate;
-		}
-		}
-		else if (ADHOC_ON(pAd))
-		{
-			if (*pSrcBufVA & 0x01)
-			{
+				pEntry = &pAd->MacTab.Content[BSSID_WCID];
+				RTMP_SET_PACKET_WCID(pPacket, BSSID_WCID);
+				Rate = pAd->CommonCfg.TxRate;
+			}
+		} else if (ADHOC_ON(pAd)) {
+			if (*pSrcBufVA & 0x01) {
 				RTMP_SET_PACKET_WCID(pPacket, MCAST_WCID);
 				pEntry = &pAd->MacTab.Content[MCAST_WCID];
-			}
-			else
-			{
+			} else {
 				pEntry = MacTableLookup(pAd, pSrcBufVA);
 			}
 			Rate = pAd->CommonCfg.TxRate;
 		}
 	}
 
-	if (!pEntry)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("STASendPacket->Cannot find pEntry(%2x:%2x:%2x:%2x:%2x:%2x) in MacTab!\n", PRINT_MAC(pSrcBufVA)));
-		// Resourece is low, system did not allocate virtual address
-		// return NDIS_STATUS_FAILURE directly to upper layer
+	if (!pEntry) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("STASendPacket->Cannot find pEntry(%2x:%2x:%2x:%2x:%2x:%2x) in MacTab!\n",
+			  PRINT_MAC(pSrcBufVA)));
+		/* Resourece is low, system did not allocate virtual address */
+		/* return NDIS_STATUS_FAILURE directly to upper layer */
 		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
 		return NDIS_STATUS_FAILURE;
 	}
 
 	if (ADHOC_ON(pAd)
-		)
-	{
-		RTMP_SET_PACKET_WCID(pPacket, (UCHAR)pEntry->Aid);
+	    ) {
+		RTMP_SET_PACKET_WCID(pPacket, (u8)pEntry->Aid);
 	}
-
-	//
-	// Check the Ethernet Frame type of this packet, and set the RTMP_SET_PACKET_SPECIFIC flags.
-	//		Here we set the PACKET_SPECIFIC flags(LLC, VLAN, DHCP/ARP, EAPOL).
+	/* */
+	/* Check the Ethernet Frame type of this packet, and set the RTMP_SET_PACKET_SPECIFIC flags. */
+	/*              Here we set the PACKET_SPECIFIC flags(LLC, VLAN, DHCP/ARP, EAPOL). */
 	RTMPCheckEtherType(pAd, pPacket);
 
-
-
-	//
-	// WPA 802.1x secured port control - drop all non-802.1x frame before port secured
-	//
+	/* */
+	/* WPA 802.1x secured port control - drop all non-802.1x frame before port secured */
+	/* */
 	if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
-		 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
-		 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
-		 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
-		  || (pAd->StaCfg.IEEE8021X == TRUE)
-		  )
-		  && ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) || (pAd->StaCfg.MicErrCnt >= 2))
-		  && (RTMP_GET_PACKET_EAPOL(pPacket)== FALSE)
-		  )
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("STASendPacket --> Drop packet before port secured !!!\n"));
+	     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+	     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
+	     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
+	     || (pAd->StaCfg.IEEE8021X == TRUE)
+	    )
+	    && ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)
+		|| (pAd->StaCfg.MicErrCnt >= 2))
+	    && (RTMP_GET_PACKET_EAPOL(pPacket) == FALSE)
+	    ) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("STASendPacket --> Drop packet before port secured!\n"));
 		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
 
 		return (NDIS_STATUS_FAILURE);
 	}
 
+	/* STEP 1. Decide number of fragments required to deliver this MSDU. */
+	/*         The estimation here is not very accurate because difficult to */
+	/*         take encryption overhead into consideration here. The result */
+	/*         "NumberOfFrag" is then just used to pre-check if enough free */
+	/*         TXD are available to hold this MSDU. */
 
-	// STEP 1. Decide number of fragments required to deliver this MSDU.
-	//	   The estimation here is not very accurate because difficult to
-	//	   take encryption overhead into consideration here. The result
-	//	   "NumberOfFrag" is then just used to pre-check if enough free
-	//	   TXD are available to hold this MSDU.
-
-
-	if (*pSrcBufVA & 0x01)	// fragmentation not allowed on multicast & broadcast
+	if (*pSrcBufVA & 0x01)	/* fragmentation not allowed on multicast & broadcast */
 		NumberOfFrag = 1;
 	else if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED))
-		NumberOfFrag = 1;	// Aggregation overwhelms fragmentation
+		NumberOfFrag = 1;	/* Aggregation overwhelms fragmentation */
 	else if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED))
-		NumberOfFrag = 1;	// Aggregation overwhelms fragmentation
-	else if ((pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTMIX) || (pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTGREENFIELD))
-		NumberOfFrag = 1;	// MIMO RATE overwhelms fragmentation
-	else
-	{
-		// The calculated "NumberOfFrag" is a rough estimation because of various
-		// encryption/encapsulation overhead not taken into consideration. This number is just
-		// used to make sure enough free TXD are available before fragmentation takes place.
-		// In case the actual required number of fragments of an NDIS packet
-		// excceeds "NumberOfFrag"caculated here and not enough free TXD available, the
-		// last fragment (i.e. last MPDU) will be dropped in RTMPHardTransmit() due to out of
-		// resource, and the NDIS packet will be indicated NDIS_STATUS_FAILURE. This should
-		// rarely happen and the penalty is just like a TX RETRY fail. Affordable.
+		NumberOfFrag = 1;	/* Aggregation overwhelms fragmentation */
+	else if ((pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTMIX)
+		 || (pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTGREENFIELD))
+		NumberOfFrag = 1;	/* MIMO RATE overwhelms fragmentation */
+	else {
+		/* The calculated "NumberOfFrag" is a rough estimation because of various */
+		/* encryption/encapsulation overhead not taken into consideration. This number is just */
+		/* used to make sure enough free TXD are available before fragmentation takes place. */
+		/* In case the actual required number of fragments of an NDIS packet */
+		/* excceeds "NumberOfFrag"caculated here and not enough free TXD available, the */
+		/* last fragment (i.e. last MPDU) will be dropped in RTMPHardTransmit() due to out of */
+		/* resource, and the NDIS packet will be indicated NDIS_STATUS_FAILURE. This should */
+		/* rarely happen and the penalty is just like a TX RETRY fail. Affordable. */
 
-		AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
-		NumberOfFrag = ((PacketInfo.TotalPacketLength - LENGTH_802_3 + LENGTH_802_1_H) / AllowFragSize) + 1;
-		// To get accurate number of fragmentation, Minus 1 if the size just match to allowable fragment size
-		if (((PacketInfo.TotalPacketLength - LENGTH_802_3 + LENGTH_802_1_H) % AllowFragSize) == 0)
-		{
+		AllowFragSize =
+		    (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 -
+		    LENGTH_CRC;
+		NumberOfFrag =
+		    ((PacketInfo.TotalPacketLength - LENGTH_802_3 +
+		      LENGTH_802_1_H) / AllowFragSize) + 1;
+		/* To get accurate number of fragmentation, Minus 1 if the size just match to allowable fragment size */
+		if (((PacketInfo.TotalPacketLength - LENGTH_802_3 +
+		      LENGTH_802_1_H) % AllowFragSize) == 0) {
 			NumberOfFrag--;
 		}
 	}
 
-	// Save fragment number to Ndis packet reserved field
+	/* Save fragment number to Ndis packet reserved field */
 	RTMP_SET_PACKET_FRAGMENTS(pPacket, NumberOfFrag);
 
+	/* STEP 2. Check the requirement of RTS: */
+	/*         If multiple fragment required, RTS is required only for the first fragment */
+	/*         if the fragment size large than RTS threshold */
+	/*     For RT28xx, Let ASIC send RTS/CTS */
+/*      RTMP_SET_PACKET_RTS(pPacket, 0); */
+	if (NumberOfFrag > 1)
+		RTSRequired =
+		    (pAd->CommonCfg.FragmentThreshold >
+		     pAd->CommonCfg.RtsThreshold) ? 1 : 0;
+	else
+		RTSRequired =
+		    (PacketInfo.TotalPacketLength >
+		     pAd->CommonCfg.RtsThreshold) ? 1 : 0;
 
-	// STEP 2. Check the requirement of RTS:
-	//	   If multiple fragment required, RTS is required only for the first fragment
-	//	   if the fragment size large than RTS threshold
-	//     For RT28xx, Let ASIC send RTS/CTS
-	RTMP_SET_PACKET_RTS(pPacket, 0);
+	/* Save RTS requirement to Ndis packet reserved field */
+	RTMP_SET_PACKET_RTS(pPacket, RTSRequired);
 	RTMP_SET_PACKET_TXRATE(pPacket, pAd->CommonCfg.TxRate);
 
-	//
-	// STEP 3. Traffic classification. outcome = <UserPriority, QueIdx>
-	//
+	/* */
+	/* STEP 3. Traffic classification. outcome = <UserPriority, QueIdx> */
+	/* */
 	UserPriority = 0;
-	QueIdx		 = QID_AC_BE;
-#ifdef RT2860
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
-#endif
-#ifdef RT2870
+	QueIdx = QID_AC_BE;
 	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
-		CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE))
-#endif
-	{
-		USHORT Protocol;
-		UCHAR  LlcSnapLen = 0, Byte0, Byte1;
-		do
-		{
-			// get Ethernet protocol field
-			Protocol = (USHORT)((pSrcBufVA[12] << 8) + pSrcBufVA[13]);
-			if (Protocol <= 1500)
-			{
-				// get Ethernet protocol field from LLC/SNAP
-				if (Sniff2BytesFromNdisBuffer(PacketInfo.pFirstBuffer, LENGTH_802_3 + 6, &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
+	    CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE)) {
+		u16 Protocol;
+		u8 LlcSnapLen = 0, Byte0, Byte1;
+		do {
+			/* get Ethernet protocol field */
+			Protocol =
+			    (u16)((pSrcBufVA[12] << 8) + pSrcBufVA[13]);
+			if (Protocol <= 1500) {
+				/* get Ethernet protocol field from LLC/SNAP */
+				if (Sniff2BytesFromNdisBuffer
+				    (PacketInfo.pFirstBuffer, LENGTH_802_3 + 6,
+				     &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
 					break;
 
-				Protocol = (USHORT)((Byte0 << 8) + Byte1);
+				Protocol = (u16)((Byte0 << 8) + Byte1);
 				LlcSnapLen = 8;
 			}
-
-			// always AC_BE for non-IP packet
+			/* always AC_BE for non-IP packet */
 			if (Protocol != 0x0800)
 				break;
 
-			// get IP header
-			if (Sniff2BytesFromNdisBuffer(PacketInfo.pFirstBuffer, LENGTH_802_3 + LlcSnapLen, &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
+			/* get IP header */
+			if (Sniff2BytesFromNdisBuffer
+			    (PacketInfo.pFirstBuffer, LENGTH_802_3 + LlcSnapLen,
+			     &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
 				break;
 
-			// return AC_BE if packet is not IPv4
+			/* return AC_BE if packet is not IPv4 */
 			if ((Byte0 & 0xf0) != 0x40)
 				break;
 
@@ -1100,63 +1113,59 @@
 			UserPriority = (Byte1 & 0xe0) >> 5;
 			QueIdx = MapUserPriorityToAccessCategory[UserPriority];
 
-			// TODO: have to check ACM bit. apply TSPEC if ACM is ON
-			// TODO: downgrade UP & QueIdx before passing ACM
-			if (pAd->CommonCfg.APEdcaParm.bACM[QueIdx])
-			{
+			/* TODO: have to check ACM bit. apply TSPEC if ACM is ON */
+			/* TODO: downgrade UP & QueIdx before passing ACM */
+			/*
+			   Under WMM ACM control, we dont need to check the bit;
+			   Or when a TSPEC is built for VO but we will change to issue
+			   BA session for BE here, so we will not use BA to send VO packets.
+			 */
+			if (pAd->CommonCfg.APEdcaParm.bACM[QueIdx]) {
 				UserPriority = 0;
-				QueIdx		 = QID_AC_BE;
+				QueIdx = QID_AC_BE;
 			}
 		} while (FALSE);
 	}
 
 	RTMP_SET_PACKET_UP(pPacket, UserPriority);
 
-
-
-	// Make sure SendTxWait queue resource won't be used by other threads
+	/* Make sure SendTxWait queue resource won't be used by other threads */
 	RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-	if (pAd->TxSwQueue[QueIdx].Number >= MAX_PACKETS_IN_QUEUE)
-	{
+	if (pAd->TxSwQueue[QueIdx].Number >= MAX_PACKETS_IN_QUEUE) {
 		RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
 		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
 
 		return NDIS_STATUS_FAILURE;
-	}
-	else
-	{
-		InsertTailQueue(&pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pPacket));
+	} else {
+		InsertTailQueueAc(pAd, pEntry, &pAd->TxSwQueue[QueIdx],
+				  PACKET_TO_QUEUE_ENTRY(pPacket));
 	}
 	RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
 
-    if ((pAd->CommonCfg.BACapability.field.AutoBA == TRUE)&&
-#ifdef RT2860
-        (pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
-#endif
-#ifdef RT2870
-        IS_HT_STA(pEntry))
-#endif
-	{
-		if (((pEntry->TXBAbitmap & (1<<UserPriority)) == 0) &&
-            ((pEntry->BADeclineBitmap & (1<<UserPriority)) == 0) &&
-            (pEntry->PortSecured == WPA_802_1X_PORT_SECURED)
-			 // For IOT compatibility, if
-			 // 1. It is Ralink chip or
-			 // 2. It is OPEN or AES mode,
-			 // then BA session can be bulit.
-			 && ((pEntry->ValidAsCLI && pAd->MlmeAux.APRalinkIe != 0x0) ||
-			 	 (pEntry->WepStatus == Ndis802_11WEPDisabled || pEntry->WepStatus == Ndis802_11Encryption3Enabled))
-			)
-		{
-			BAOriSessionSetUp(pAd, pEntry, 0, 0, 10, FALSE);
+	if ((pAd->CommonCfg.BACapability.field.AutoBA == TRUE) &&
+	    IS_HT_STA(pEntry)) {
+		/*struct rt_mac_table_entry *pMacEntry = &pAd->MacTab.Content[BSSID_WCID]; */
+		if (((pEntry->TXBAbitmap & (1 << UserPriority)) == 0) &&
+		    ((pEntry->BADeclineBitmap & (1 << UserPriority)) == 0) &&
+		    (pEntry->PortSecured == WPA_802_1X_PORT_SECURED)
+		    /* For IOT compatibility, if */
+		    /* 1. It is Ralink chip or */
+		    /* 2. It is OPEN or AES mode, */
+		    /* then BA session can be bulit. */
+		    && ((pEntry->ValidAsCLI && pAd->MlmeAux.APRalinkIe != 0x0)
+			|| (pEntry->WepStatus != Ndis802_11WEPEnabled
+			    && pEntry->WepStatus !=
+			    Ndis802_11Encryption2Enabled))
+		    ) {
+			BAOriSessionSetUp(pAd, pEntry, UserPriority, 0, 10,
+					  FALSE);
 		}
 	}
 
-	pAd->RalinkCounters.OneSecOsTxCount[QueIdx]++; // TODO: for debug only. to be removed
+	pAd->RalinkCounters.OneSecOsTxCount[QueIdx]++;	/* TODO: for debug only. to be removed */
 	return NDIS_STATUS_SUCCESS;
 }
 
-
 /*
 	========================================================================
 
@@ -1179,123 +1188,132 @@
 
 	========================================================================
 */
+#ifdef RTMP_MAC_PCI
+int RTMPFreeTXDRequest(struct rt_rtmp_adapter *pAd,
+			       u8 QueIdx,
+			       u8 NumberRequired, u8 *FreeNumberIs)
+{
+	unsigned long FreeNumber = 0;
+	int Status = NDIS_STATUS_FAILURE;
 
-#ifdef RT2870
+	switch (QueIdx) {
+	case QID_AC_BK:
+	case QID_AC_BE:
+	case QID_AC_VI:
+	case QID_AC_VO:
+		if (pAd->TxRing[QueIdx].TxSwFreeIdx >
+		    pAd->TxRing[QueIdx].TxCpuIdx)
+			FreeNumber =
+			    pAd->TxRing[QueIdx].TxSwFreeIdx -
+			    pAd->TxRing[QueIdx].TxCpuIdx - 1;
+		else
+			FreeNumber =
+			    pAd->TxRing[QueIdx].TxSwFreeIdx + TX_RING_SIZE -
+			    pAd->TxRing[QueIdx].TxCpuIdx - 1;
+
+		if (FreeNumber >= NumberRequired)
+			Status = NDIS_STATUS_SUCCESS;
+		break;
+
+	case QID_MGMT:
+		if (pAd->MgmtRing.TxSwFreeIdx > pAd->MgmtRing.TxCpuIdx)
+			FreeNumber =
+			    pAd->MgmtRing.TxSwFreeIdx - pAd->MgmtRing.TxCpuIdx -
+			    1;
+		else
+			FreeNumber =
+			    pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE -
+			    pAd->MgmtRing.TxCpuIdx - 1;
+
+		if (FreeNumber >= NumberRequired)
+			Status = NDIS_STATUS_SUCCESS;
+		break;
+
+	default:
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx));
+		break;
+	}
+	*FreeNumberIs = (u8)FreeNumber;
+
+	return (Status);
+}
+#endif /* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
 /*
 	Actually, this function used to check if the TxHardware Queue still has frame need to send.
 	If no frame need to send, go to sleep, else, still wake up.
 */
-#endif
-NDIS_STATUS RTMPFreeTXDRequest(
-	IN		PRTMP_ADAPTER	pAd,
-	IN		UCHAR			QueIdx,
-	IN		UCHAR			NumberRequired,
-	IN		PUCHAR			FreeNumberIs)
+int RTMPFreeTXDRequest(struct rt_rtmp_adapter *pAd,
+			       u8 QueIdx,
+			       u8 NumberRequired, u8 *FreeNumberIs)
 {
-#ifdef RT2860
-	ULONG		FreeNumber = 0;
-#endif
-	NDIS_STATUS 	Status = NDIS_STATUS_FAILURE;
-#ifdef RT2870
-	unsigned long   IrqFlags;
-	HT_TX_CONTEXT	*pHTTXContext;
-#endif
+	/*unsigned long         FreeNumber = 0; */
+	int Status = NDIS_STATUS_FAILURE;
+	unsigned long IrqFlags;
+	struct rt_ht_tx_context *pHTTXContext;
 
-	switch (QueIdx)
-	{
-		case QID_AC_BK:
-		case QID_AC_BE:
-		case QID_AC_VI:
-		case QID_AC_VO:
-		case QID_HCCA:
-#ifdef RT2860
-			if (pAd->TxRing[QueIdx].TxSwFreeIdx > pAd->TxRing[QueIdx].TxCpuIdx)
-				FreeNumber = pAd->TxRing[QueIdx].TxSwFreeIdx - pAd->TxRing[QueIdx].TxCpuIdx - 1;
-			else
-				FreeNumber = pAd->TxRing[QueIdx].TxSwFreeIdx + TX_RING_SIZE - pAd->TxRing[QueIdx].TxCpuIdx - 1;
-
-			if (FreeNumber >= NumberRequired)
-				Status = NDIS_STATUS_SUCCESS;
-#endif
-#ifdef RT2870
-			{
-				pHTTXContext = &pAd->TxContext[QueIdx];
-				RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-				if ((pHTTXContext->CurWritePosition != pHTTXContext->ENextBulkOutPosition) ||
-					(pHTTXContext->IRPPending == TRUE))
-				{
-					Status = NDIS_STATUS_FAILURE;
-				}
-				else
-				{
-					Status = NDIS_STATUS_SUCCESS;
-				}
-				RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-			}
-#endif
-			break;
-
-		case QID_MGMT:
-#ifdef RT2860
-			if (pAd->MgmtRing.TxSwFreeIdx > pAd->MgmtRing.TxCpuIdx)
-				FreeNumber = pAd->MgmtRing.TxSwFreeIdx - pAd->MgmtRing.TxCpuIdx - 1;
-			else
-				FreeNumber = pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE - pAd->MgmtRing.TxCpuIdx - 1;
-
-			if (FreeNumber >= NumberRequired)
-				Status = NDIS_STATUS_SUCCESS;
-#endif
-#ifdef RT2870
-			if (pAd->MgmtRing.TxSwFreeIdx != MGMT_RING_SIZE)
+	switch (QueIdx) {
+	case QID_AC_BK:
+	case QID_AC_BE:
+	case QID_AC_VI:
+	case QID_AC_VO:
+		{
+			pHTTXContext = &pAd->TxContext[QueIdx];
+			RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx],
+				      IrqFlags);
+			if ((pHTTXContext->CurWritePosition !=
+			     pHTTXContext->ENextBulkOutPosition)
+			    || (pHTTXContext->IRPPending == TRUE)) {
 				Status = NDIS_STATUS_FAILURE;
-			else
+			} else {
 				Status = NDIS_STATUS_SUCCESS;
-#endif
-			break;
-
-		default:
-			DBGPRINT(RT_DEBUG_ERROR,("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx));
-			break;
+			}
+			RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx],
+					IrqFlags);
+		}
+		break;
+	case QID_MGMT:
+		if (pAd->MgmtRing.TxSwFreeIdx != MGMT_RING_SIZE)
+			Status = NDIS_STATUS_FAILURE;
+		else
+			Status = NDIS_STATUS_SUCCESS;
+		break;
+	default:
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx));
+		break;
 	}
-#ifdef RT2860
-	*FreeNumberIs = (UCHAR)FreeNumber;
-#endif
 
 	return (Status);
 }
+#endif /* RTMP_MAC_USB // */
 
-
-
-VOID RTMPSendDisassociationFrame(
-	IN	PRTMP_ADAPTER	pAd)
+void RTMPSendDisassociationFrame(struct rt_rtmp_adapter *pAd)
 {
 }
 
-VOID	RTMPSendNullFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			TxRate,
-	IN	BOOLEAN 		bQosNull)
+void RTMPSendNullFrame(struct rt_rtmp_adapter *pAd,
+		       u8 TxRate, IN BOOLEAN bQosNull)
 {
-	UCHAR	NullFrame[48];
-	ULONG	Length;
-	PHEADER_802_11	pHeader_802_11;
+	u8 NullFrame[48];
+	unsigned long Length;
+	struct rt_header_802_11 * pHeader_802_11;
 
-    // WPA 802.1x secured port control
-    if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
-         (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
-         (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
-         (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
-			  || (pAd->StaCfg.IEEE8021X == TRUE)
-        ) &&
-       (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
-	{
+	/* WPA 802.1x secured port control */
+	if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
+	     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+	     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
+	     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
+	     || (pAd->StaCfg.IEEE8021X == TRUE)
+	    ) && (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)) {
 		return;
 	}
 
 	NdisZeroMemory(NullFrame, 48);
-	Length = sizeof(HEADER_802_11);
+	Length = sizeof(struct rt_header_802_11);
 
-	pHeader_802_11 = (PHEADER_802_11) NullFrame;
+	pHeader_802_11 = (struct rt_header_802_11 *) NullFrame;
 
 	pHeader_802_11->FC.Type = BTYPE_DATA;
 	pHeader_802_11->FC.SubType = SUBTYPE_NULL_FUNC;
@@ -1304,97 +1322,84 @@
 	COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
 	COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
 
-	if (pAd->CommonCfg.bAPSDForcePowerSave)
-	{
+	if (pAd->CommonCfg.bAPSDForcePowerSave) {
 		pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
+	} else {
+		pHeader_802_11->FC.PwrMgmt =
+		    (pAd->StaCfg.Psm == PWR_SAVE) ? 1 : 0;
 	}
-	else
-	{
-		pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE) ? 1: 0;
-	}
-	pHeader_802_11->Duration = pAd->CommonCfg.Dsifs + RTMPCalcDuration(pAd, TxRate, 14);
+	pHeader_802_11->Duration =
+	    pAd->CommonCfg.Dsifs + RTMPCalcDuration(pAd, TxRate, 14);
 
 	pAd->Sequence++;
 	pHeader_802_11->Sequence = pAd->Sequence;
 
-	// Prepare QosNull function frame
-	if (bQosNull)
-	{
+	/* Prepare QosNull function frame */
+	if (bQosNull) {
 		pHeader_802_11->FC.SubType = SUBTYPE_QOS_NULL;
 
-		// copy QOS control bytes
-		NullFrame[Length]	=  0;
-		NullFrame[Length+1] =  0;
-		Length += 2;// if pad with 2 bytes for alignment, APSD will fail
+		/* copy QOS control bytes */
+		NullFrame[Length] = 0;
+		NullFrame[Length + 1] = 0;
+		Length += 2;	/* if pad with 2 bytes for alignment, APSD will fail */
 	}
 
 	HAL_KickOutNullFrameTx(pAd, 0, NullFrame, Length);
 
 }
 
-// IRQL = DISPATCH_LEVEL
-VOID	RTMPSendRTSFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pDA,
-	IN	unsigned int	NextMpduSize,
-	IN	UCHAR			TxRate,
-	IN	UCHAR			RTSRate,
-	IN	USHORT			AckDuration,
-	IN	UCHAR			QueIdx,
-	IN	UCHAR			FrameGap)
+/* IRQL = DISPATCH_LEVEL */
+void RTMPSendRTSFrame(struct rt_rtmp_adapter *pAd,
+		      u8 *pDA,
+		      IN unsigned int NextMpduSize,
+		      u8 TxRate,
+		      u8 RTSRate,
+		      u16 AckDuration, u8 QueIdx, u8 FrameGap)
 {
 }
 
-
-
-// --------------------------------------------------------
-//  FIND ENCRYPT KEY AND DECIDE CIPHER ALGORITHM
-//		Find the WPA key, either Group or Pairwise Key
-//		LEAP + TKIP also use WPA key.
-// --------------------------------------------------------
-// Decide WEP bit and cipher suite to be used. Same cipher suite should be used for whole fragment burst
-// In Cisco CCX 2.0 Leap Authentication
-//		   WepStatus is Ndis802_11Encryption1Enabled but the key will use PairwiseKey
-//		   Instead of the SharedKey, SharedKey Length may be Zero.
-VOID STAFindCipherAlgorithm(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk)
+/* -------------------------------------------------------- */
+/*  FIND ENCRYPT KEY AND DECIDE CIPHER ALGORITHM */
+/*              Find the WPA key, either Group or Pairwise Key */
+/*              LEAP + TKIP also use WPA key. */
+/* -------------------------------------------------------- */
+/* Decide WEP bit and cipher suite to be used. Same cipher suite should be used for whole fragment burst */
+/* In Cisco CCX 2.0 Leap Authentication */
+/*                 WepStatus is Ndis802_11Encryption1Enabled but the key will use PairwiseKey */
+/*                 Instead of the SharedKey, SharedKey Length may be Zero. */
+void STAFindCipherAlgorithm(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
 {
-	NDIS_802_11_ENCRYPTION_STATUS	Cipher;				// To indicate cipher used for this packet
-	UCHAR							CipherAlg = CIPHER_NONE;		// cipher alogrithm
-	UCHAR							KeyIdx = 0xff;
-	PUCHAR							pSrcBufVA;
-	PCIPHER_KEY						pKey = NULL;
+	NDIS_802_11_ENCRYPTION_STATUS Cipher;	/* To indicate cipher used for this packet */
+	u8 CipherAlg = CIPHER_NONE;	/* cipher alogrithm */
+	u8 KeyIdx = 0xff;
+	u8 *pSrcBufVA;
+	struct rt_cipher_key *pKey = NULL;
 
 	pSrcBufVA = GET_OS_PKT_DATAPTR(pTxBlk->pPacket);
 
 	{
-	    // Select Cipher
-	    if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))
-	        Cipher = pAd->StaCfg.GroupCipher; // Cipher for Multicast or Broadcast
-	    else
-	        Cipher = pAd->StaCfg.PairCipher; // Cipher for Unicast
+		/* Select Cipher */
+		if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))
+			Cipher = pAd->StaCfg.GroupCipher;	/* Cipher for Multicast or Broadcast */
+		else
+			Cipher = pAd->StaCfg.PairCipher;	/* Cipher for Unicast */
 
-		if (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
-		{
-			ASSERT(pAd->SharedKey[BSS0][0].CipherAlg <= CIPHER_CKIP128);
+		if (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket)) {
+			ASSERT(pAd->SharedKey[BSS0][0].CipherAlg <=
+			       CIPHER_CKIP128);
 
-			// 4-way handshaking frame must be clear
-			if (!(TX_BLK_TEST_FLAG(pTxBlk, fTX_bClearEAPFrame)) && (pAd->SharedKey[BSS0][0].CipherAlg) &&
-				(pAd->SharedKey[BSS0][0].KeyLen))
-			{
+			/* 4-way handshaking frame must be clear */
+			if (!(TX_BLK_TEST_FLAG(pTxBlk, fTX_bClearEAPFrame))
+			    && (pAd->SharedKey[BSS0][0].CipherAlg)
+			    && (pAd->SharedKey[BSS0][0].KeyLen)) {
 				CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
 				KeyIdx = 0;
 			}
-		}
-		else if (Cipher == Ndis802_11Encryption1Enabled)
-		{
-				KeyIdx = pAd->StaCfg.DefaultKeyId;
-		}
-		else if ((Cipher == Ndis802_11Encryption2Enabled) ||
-				 (Cipher == Ndis802_11Encryption3Enabled))
-		{
-			if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))) // multicast
+		} else if (Cipher == Ndis802_11Encryption1Enabled) {
+			KeyIdx = pAd->StaCfg.DefaultKeyId;
+		} else if ((Cipher == Ndis802_11Encryption2Enabled) ||
+			   (Cipher == Ndis802_11Encryption3Enabled)) {
+			if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))	/* multicast */
 				KeyIdx = pAd->StaCfg.DefaultKeyId;
 			else if (pAd->SharedKey[BSS0][0].KeyLen)
 				KeyIdx = 0;
@@ -1404,16 +1409,17 @@
 
 		if (KeyIdx == 0xff)
 			CipherAlg = CIPHER_NONE;
-		else if ((Cipher == Ndis802_11EncryptionDisabled) || (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 0))
+		else if ((Cipher == Ndis802_11EncryptionDisabled)
+			 || (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 0))
 			CipherAlg = CIPHER_NONE;
-	    else if ( pAd->StaCfg.WpaSupplicantUP &&
-	             (Cipher == Ndis802_11Encryption1Enabled) &&
-	             (pAd->StaCfg.IEEE8021X == TRUE) &&
-	             (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
-	        CipherAlg = CIPHER_NONE;
-		else
-		{
-			//Header_802_11.FC.Wep = 1;
+		else if (pAd->StaCfg.WpaSupplicantUP &&
+			 (Cipher == Ndis802_11Encryption1Enabled) &&
+			 (pAd->StaCfg.IEEE8021X == TRUE) &&
+			 (pAd->StaCfg.PortSecured ==
+			  WPA_802_1X_PORT_NOT_SECURED))
+			CipherAlg = CIPHER_NONE;
+		else {
+			/*Header_802_11.FC.Wep = 1; */
 			CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
 			pKey = &pAd->SharedKey[BSS0][KeyIdx];
 		}
@@ -1423,47 +1429,47 @@
 	pTxBlk->pKey = pKey;
 }
 
-
-VOID STABuildCommon802_11Header(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  TX_BLK          *pTxBlk)
+void STABuildCommon802_11Header(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
 {
-	HEADER_802_11	*pHeader_802_11;
+	struct rt_header_802_11 *pHeader_802_11;
 
-	//
-	// MAKE A COMMON 802.11 HEADER
-	//
+	/* */
+	/* MAKE A COMMON 802.11 HEADER */
+	/* */
 
-	// normal wlan header size : 24 octets
-	pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11);
+	/* normal wlan header size : 24 octets */
+	pTxBlk->MpduHeaderLen = sizeof(struct rt_header_802_11);
 
-	pHeader_802_11 = (HEADER_802_11 *) &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
+	pHeader_802_11 =
+	    (struct rt_header_802_11 *) & pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
 
-	NdisZeroMemory(pHeader_802_11, sizeof(HEADER_802_11));
+	NdisZeroMemory(pHeader_802_11, sizeof(struct rt_header_802_11));
 
 	pHeader_802_11->FC.FrDs = 0;
 	pHeader_802_11->FC.Type = BTYPE_DATA;
-	pHeader_802_11->FC.SubType = ((TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) ? SUBTYPE_QDATA : SUBTYPE_DATA);
+	pHeader_802_11->FC.SubType =
+	    ((TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) ? SUBTYPE_QDATA :
+	     SUBTYPE_DATA);
 
-    if (pTxBlk->pMacEntry)
-	{
-		if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bForceNonQoS))
-		{
-			pHeader_802_11->Sequence = pTxBlk->pMacEntry->NonQosDataSeq;
-			pTxBlk->pMacEntry->NonQosDataSeq = (pTxBlk->pMacEntry->NonQosDataSeq+1) & MAXSEQ;
-		}
-		else
-		{
+	if (pTxBlk->pMacEntry) {
+		if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bForceNonQoS)) {
+			pHeader_802_11->Sequence =
+			    pTxBlk->pMacEntry->NonQosDataSeq;
+			pTxBlk->pMacEntry->NonQosDataSeq =
+			    (pTxBlk->pMacEntry->NonQosDataSeq + 1) & MAXSEQ;
+		} else {
 			{
-    	    pHeader_802_11->Sequence = pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority];
-    	    pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority] = (pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ;
-    	}
-	}
-	}
-	else
-	{
+				pHeader_802_11->Sequence =
+				    pTxBlk->pMacEntry->TxSeq[pTxBlk->
+							     UserPriority];
+				pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority] =
+				    (pTxBlk->pMacEntry->
+				     TxSeq[pTxBlk->UserPriority] + 1) & MAXSEQ;
+			}
+		}
+	} else {
 		pHeader_802_11->Sequence = pAd->Sequence;
-		pAd->Sequence = (pAd->Sequence+1) & MAXSEQ; // next sequence
+		pAd->Sequence = (pAd->Sequence + 1) & MAXSEQ;	/* next sequence */
 	}
 
 	pHeader_802_11->Frag = 0;
@@ -1471,20 +1477,23 @@
 	pHeader_802_11->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
 
 	{
-		if (INFRA_ON(pAd))
-		{
+		if (INFRA_ON(pAd)) {
 			{
-			COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid);
-			COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
-			COPY_MAC_ADDR(pHeader_802_11->Addr3, pTxBlk->pSrcBufHeader);
-			pHeader_802_11->FC.ToDs = 1;
-		}
-		}
-		else if (ADHOC_ON(pAd))
-		{
-			COPY_MAC_ADDR(pHeader_802_11->Addr1, pTxBlk->pSrcBufHeader);
-			COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
-			COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
+				COPY_MAC_ADDR(pHeader_802_11->Addr1,
+					      pAd->CommonCfg.Bssid);
+				COPY_MAC_ADDR(pHeader_802_11->Addr2,
+					      pAd->CurrentAddress);
+				COPY_MAC_ADDR(pHeader_802_11->Addr3,
+					      pTxBlk->pSrcBufHeader);
+				pHeader_802_11->FC.ToDs = 1;
+			}
+		} else if (ADHOC_ON(pAd)) {
+			COPY_MAC_ADDR(pHeader_802_11->Addr1,
+				      pTxBlk->pSrcBufHeader);
+			COPY_MAC_ADDR(pHeader_802_11->Addr2,
+				      pAd->CurrentAddress);
+			COPY_MAC_ADDR(pHeader_802_11->Addr3,
+				      pAd->CommonCfg.Bssid);
 			pHeader_802_11->FC.ToDs = 0;
 		}
 	}
@@ -1492,107 +1501,107 @@
 	if (pTxBlk->CipherAlg != CIPHER_NONE)
 		pHeader_802_11->FC.Wep = 1;
 
-	// -----------------------------------------------------------------
-	// STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later.
-	// -----------------------------------------------------------------
+	/* ----------------------------------------------------------------- */
+	/* STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later. */
+	/* ----------------------------------------------------------------- */
 	if (pAd->CommonCfg.bAPSDForcePowerSave)
-    	pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
+		pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
 	else
-    	pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
+		pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
 }
 
-VOID STABuildCache802_11Header(
-	IN RTMP_ADAPTER		*pAd,
-	IN TX_BLK			*pTxBlk,
-	IN UCHAR			*pHeader)
+void STABuildCache802_11Header(struct rt_rtmp_adapter *pAd,
+			       struct rt_tx_blk *pTxBlk, u8 * pHeader)
 {
-	MAC_TABLE_ENTRY	*pMacEntry;
-	PHEADER_802_11	pHeader80211;
+	struct rt_mac_table_entry *pMacEntry;
+	struct rt_header_802_11 * pHeader80211;
 
-	pHeader80211 = (PHEADER_802_11)pHeader;
+	pHeader80211 = (struct rt_header_802_11 *) pHeader;
 	pMacEntry = pTxBlk->pMacEntry;
 
-	//
-	// Update the cached 802.11 HEADER
-	//
+	/* */
+	/* Update the cached 802.11 HEADER */
+	/* */
 
-	// normal wlan header size : 24 octets
-	pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11);
+	/* normal wlan header size : 24 octets */
+	pTxBlk->MpduHeaderLen = sizeof(struct rt_header_802_11);
 
-	// More Bit
+	/* More Bit */
 	pHeader80211->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
 
-	// Sequence
+	/* Sequence */
 	pHeader80211->Sequence = pMacEntry->TxSeq[pTxBlk->UserPriority];
-    pMacEntry->TxSeq[pTxBlk->UserPriority] = (pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ;
+	pMacEntry->TxSeq[pTxBlk->UserPriority] =
+	    (pMacEntry->TxSeq[pTxBlk->UserPriority] + 1) & MAXSEQ;
 
 	{
-		// The addr3 of normal packet send from DS is Dest Mac address.
+		/* Check if the frame can be sent through DLS direct link interface */
+		/* If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability) */
+
+		/* The addr3 of normal packet send from DS is Dest Mac address. */
 		if (ADHOC_ON(pAd))
-			COPY_MAC_ADDR(pHeader80211->Addr3, pAd->CommonCfg.Bssid);
+			COPY_MAC_ADDR(pHeader80211->Addr3,
+				      pAd->CommonCfg.Bssid);
 		else
-			COPY_MAC_ADDR(pHeader80211->Addr3, pTxBlk->pSrcBufHeader);
+			COPY_MAC_ADDR(pHeader80211->Addr3,
+				      pTxBlk->pSrcBufHeader);
 	}
 
-	// -----------------------------------------------------------------
-	// STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later.
-	// -----------------------------------------------------------------
+	/* ----------------------------------------------------------------- */
+	/* STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later. */
+	/* ----------------------------------------------------------------- */
 	if (pAd->CommonCfg.bAPSDForcePowerSave)
-    	pHeader80211->FC.PwrMgmt = PWR_SAVE;
+		pHeader80211->FC.PwrMgmt = PWR_SAVE;
 	else
-    	pHeader80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
+		pHeader80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
 }
 
-static inline PUCHAR STA_Build_ARalink_Frame_Header(
-	IN RTMP_ADAPTER *pAd,
-	IN TX_BLK		*pTxBlk)
+static inline u8 *STA_Build_ARalink_Frame_Header(struct rt_rtmp_adapter *pAd,
+						    struct rt_tx_blk *pTxBlk)
 {
-	PUCHAR			pHeaderBufPtr;
-	HEADER_802_11	*pHeader_802_11;
-	PNDIS_PACKET	pNextPacket;
-	UINT32			nextBufLen;
-	PQUEUE_ENTRY	pQEntry;
+	u8 *pHeaderBufPtr;
+	struct rt_header_802_11 *pHeader_802_11;
+	void *pNextPacket;
+	u32 nextBufLen;
+	struct rt_queue_entry *pQEntry;
 
 	STAFindCipherAlgorithm(pAd, pTxBlk);
 	STABuildCommon802_11Header(pAd, pTxBlk);
 
-
 	pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
-	pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
+	pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;
 
-	// steal "order" bit to mark "aggregation"
+	/* steal "order" bit to mark "aggregation" */
 	pHeader_802_11->FC.Order = 1;
 
-	// skip common header
+	/* skip common header */
 	pHeaderBufPtr += pTxBlk->MpduHeaderLen;
 
-	if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
-	{
-		//
-		// build QOS Control bytes
-		//
+	if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) {
+		/* */
+		/* build QOS Control bytes */
+		/* */
 		*pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
 
-		*(pHeaderBufPtr+1) = 0;
-		pHeaderBufPtr +=2;
+		*(pHeaderBufPtr + 1) = 0;
+		pHeaderBufPtr += 2;
 		pTxBlk->MpduHeaderLen += 2;
 	}
+	/* padding at front of LLC header. LLC header should at 4-bytes aligment. */
+	pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
+	pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
+	pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);
 
-	// padding at front of LLC header. LLC header should at 4-bytes aligment.
-	pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
-	pHeaderBufPtr = (PCHAR)ROUND_UP(pHeaderBufPtr, 4);
-	pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
-
-	// For RA Aggregation,
-	// put the 2nd MSDU length(extra 2-byte field) after QOS_CONTROL in little endian format
+	/* For RA Aggregation, */
+	/* put the 2nd MSDU length(extra 2-byte field) after struct rt_qos_control in little endian format */
 	pQEntry = pTxBlk->TxPacketList.Head;
-	pNextPacket = QUEUE_ENTRY_TO_PKT(pQEntry);
+	pNextPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
 	nextBufLen = GET_OS_PKT_LEN(pNextPacket);
 	if (RTMP_GET_PACKET_VLAN(pNextPacket))
 		nextBufLen -= LENGTH_802_1Q;
 
-	*pHeaderBufPtr = (UCHAR)nextBufLen & 0xff;
-	*(pHeaderBufPtr+1) = (UCHAR)(nextBufLen >> 8);
+	*pHeaderBufPtr = (u8)nextBufLen & 0xff;
+	*(pHeaderBufPtr + 1) = (u8)(nextBufLen >> 8);
 
 	pHeaderBufPtr += 2;
 	pTxBlk->MpduHeaderLen += 2;
@@ -1601,198 +1610,207 @@
 
 }
 
-static inline PUCHAR STA_Build_AMSDU_Frame_Header(
-	IN RTMP_ADAPTER *pAd,
-	IN TX_BLK		*pTxBlk)
+static inline u8 *STA_Build_AMSDU_Frame_Header(struct rt_rtmp_adapter *pAd,
+						  struct rt_tx_blk *pTxBlk)
 {
-	PUCHAR			pHeaderBufPtr;//, pSaveBufPtr;
-	HEADER_802_11	*pHeader_802_11;
-
+	u8 *pHeaderBufPtr;	/*, pSaveBufPtr; */
+	struct rt_header_802_11 *pHeader_802_11;
 
 	STAFindCipherAlgorithm(pAd, pTxBlk);
 	STABuildCommon802_11Header(pAd, pTxBlk);
 
 	pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
-	pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
+	pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;
 
-	// skip common header
+	/* skip common header */
 	pHeaderBufPtr += pTxBlk->MpduHeaderLen;
 
-	//
-	// build QOS Control bytes
-	//
+	/* */
+	/* build QOS Control bytes */
+	/* */
 	*pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
 
-	//
-	// A-MSDU packet
-	//
+	/* */
+	/* A-MSDU packet */
+	/* */
 	*pHeaderBufPtr |= 0x80;
 
-	*(pHeaderBufPtr+1) = 0;
-	pHeaderBufPtr +=2;
+	*(pHeaderBufPtr + 1) = 0;
+	pHeaderBufPtr += 2;
 	pTxBlk->MpduHeaderLen += 2;
 
-	//pSaveBufPtr = pHeaderBufPtr;
+	/*pSaveBufPtr = pHeaderBufPtr; */
 
-	//
-	// padding at front of LLC header
-	// LLC header should locate at 4-octets aligment
-	//
-	// @@@ MpduHeaderLen excluding padding @@@
-	//
-	pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
-	pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
-	pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
+	/* */
+	/* padding at front of LLC header */
+	/* LLC header should locate at 4-octets aligment */
+	/* */
+	/* @@@ MpduHeaderLen excluding padding @@@ */
+	/* */
+	pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
+	pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
+	pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);
 
 	return pHeaderBufPtr;
 
 }
 
-
-VOID STA_AMPDU_Frame_Tx(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk)
+void STA_AMPDU_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
 {
-	HEADER_802_11	*pHeader_802_11;
-	PUCHAR			pHeaderBufPtr;
-	USHORT			FreeNumber;
-	MAC_TABLE_ENTRY	*pMacEntry;
-	BOOLEAN			bVLANPkt;
-	PQUEUE_ENTRY	pQEntry;
+	struct rt_header_802_11 *pHeader_802_11;
+	u8 *pHeaderBufPtr;
+	u16 FreeNumber;
+	struct rt_mac_table_entry *pMacEntry;
+	BOOLEAN bVLANPkt;
+	struct rt_queue_entry *pQEntry;
 
 	ASSERT(pTxBlk);
 
-	while(pTxBlk->TxPacketList.Head)
-	{
+	while (pTxBlk->TxPacketList.Head) {
 		pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
 		pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
-		if ( RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
-		{
-			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+		if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
+			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket,
+					    NDIS_STATUS_FAILURE);
 			continue;
 		}
 
-		bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
+		bVLANPkt =
+		    (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
 
 		pMacEntry = pTxBlk->pMacEntry;
-		if (pMacEntry->isCached)
-		{
-			// NOTE: Please make sure the size of pMacEntry->CachedBuf[] is smaller than pTxBlk->HeaderBuf[]!!!!
-			NdisMoveMemory((PUCHAR)&pTxBlk->HeaderBuf[TXINFO_SIZE], (PUCHAR)&pMacEntry->CachedBuf[0], TXWI_SIZE + sizeof(HEADER_802_11));
-			pHeaderBufPtr = (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]);
+		if (pMacEntry->isCached) {
+			/* NOTE: Please make sure the size of pMacEntry->CachedBuf[] is smaller than pTxBlk->HeaderBuf[]! */
+			NdisMoveMemory((u8 *)& pTxBlk->
+				       HeaderBuf[TXINFO_SIZE],
+				       (u8 *)& pMacEntry->CachedBuf[0],
+				       TXWI_SIZE + sizeof(struct rt_header_802_11));
+			pHeaderBufPtr =
+			    (u8 *)(&pTxBlk->
+				      HeaderBuf[TXINFO_SIZE + TXWI_SIZE]);
 			STABuildCache802_11Header(pAd, pTxBlk, pHeaderBufPtr);
-		}
-		else
-		{
+		} else {
 			STAFindCipherAlgorithm(pAd, pTxBlk);
 			STABuildCommon802_11Header(pAd, pTxBlk);
 
-			pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
+			pHeaderBufPtr =
+			    &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
 		}
 
+		pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;
 
-		pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
-
-		// skip common header
+		/* skip common header */
 		pHeaderBufPtr += pTxBlk->MpduHeaderLen;
 
-		//
-		// build QOS Control bytes
-		//
+		/* */
+		/* build QOS Control bytes */
+		/* */
 		*pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
-		*(pHeaderBufPtr+1) = 0;
-		pHeaderBufPtr +=2;
+		*(pHeaderBufPtr + 1) = 0;
+		pHeaderBufPtr += 2;
 		pTxBlk->MpduHeaderLen += 2;
 
-		//
-		// build HTC+
-		// HTC control filed following QoS field
-		//
-		if ((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry, fCLIENT_STATUS_RDG_CAPABLE))
-		{
-			if (pMacEntry->isCached == FALSE)
-			{
-				// mark HTC bit
+		/* */
+		/* build HTC+ */
+		/* HTC control filed following QoS field */
+		/* */
+		if ((pAd->CommonCfg.bRdg == TRUE)
+		    && CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry,
+					       fCLIENT_STATUS_RDG_CAPABLE)) {
+			if (pMacEntry->isCached == FALSE) {
+				/* mark HTC bit */
 				pHeader_802_11->FC.Order = 1;
 
 				NdisZeroMemory(pHeaderBufPtr, 4);
-				*(pHeaderBufPtr+3) |= 0x80;
+				*(pHeaderBufPtr + 3) |= 0x80;
 			}
 			pHeaderBufPtr += 4;
 			pTxBlk->MpduHeaderLen += 4;
 		}
-
-		//pTxBlk->MpduHeaderLen = pHeaderBufPtr - pTxBlk->HeaderBuf - TXWI_SIZE - TXINFO_SIZE;
+		/*pTxBlk->MpduHeaderLen = pHeaderBufPtr - pTxBlk->HeaderBuf - TXWI_SIZE - TXINFO_SIZE; */
 		ASSERT(pTxBlk->MpduHeaderLen >= 24);
 
-		// skip 802.3 header
+		/* skip 802.3 header */
 		pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
-		pTxBlk->SrcBufLen  -= LENGTH_802_3;
+		pTxBlk->SrcBufLen -= LENGTH_802_3;
 
-		// skip vlan tag
-		if (bVLANPkt)
-		{
-			pTxBlk->pSrcBufData	+= LENGTH_802_1Q;
-			pTxBlk->SrcBufLen	-= LENGTH_802_1Q;
+		/* skip vlan tag */
+		if (bVLANPkt) {
+			pTxBlk->pSrcBufData += LENGTH_802_1Q;
+			pTxBlk->SrcBufLen -= LENGTH_802_1Q;
 		}
-
-		//
-		// padding at front of LLC header
-		// LLC header should locate at 4-octets aligment
-		//
-		// @@@ MpduHeaderLen excluding padding @@@
-		//
-		pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
-		pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
-		pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
+		/* */
+		/* padding at front of LLC header */
+		/* LLC header should locate at 4-octets aligment */
+		/* */
+		/* @@@ MpduHeaderLen excluding padding @@@ */
+		/* */
+		pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
+		pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
+		pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);
 
 		{
 
-			//
-			// Insert LLC-SNAP encapsulation - 8 octets
-			//
-			EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
-			if (pTxBlk->pExtraLlcSnapEncap)
-			{
-				NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
+			/* */
+			/* Insert LLC-SNAP encapsulation - 8 octets */
+			/* */
+			EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->
+							    pSrcBufData - 2,
+							    pTxBlk->
+							    pExtraLlcSnapEncap);
+			if (pTxBlk->pExtraLlcSnapEncap) {
+				NdisMoveMemory(pHeaderBufPtr,
+					       pTxBlk->pExtraLlcSnapEncap, 6);
 				pHeaderBufPtr += 6;
-				// get 2 octets (TypeofLen)
-				NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
+				/* get 2 octets (TypeofLen) */
+				NdisMoveMemory(pHeaderBufPtr,
+					       pTxBlk->pSrcBufData - 2, 2);
 				pHeaderBufPtr += 2;
 				pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
 			}
 
 		}
 
-		if (pMacEntry->isCached)
-		{
-            RTMPWriteTxWI_Cache(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
-		}
-		else
-		{
-			RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+		if (pMacEntry->isCached) {
+			RTMPWriteTxWI_Cache(pAd,
+					    (struct rt_txwi *) (&pTxBlk->
+							   HeaderBuf
+							   [TXINFO_SIZE]),
+					    pTxBlk);
+		} else {
+			RTMPWriteTxWI_Data(pAd,
+					   (struct rt_txwi *) (&pTxBlk->
+							  HeaderBuf
+							  [TXINFO_SIZE]),
+					   pTxBlk);
 
-			NdisZeroMemory((PUCHAR)(&pMacEntry->CachedBuf[0]), sizeof(pMacEntry->CachedBuf));
-			NdisMoveMemory((PUCHAR)(&pMacEntry->CachedBuf[0]), (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), (pHeaderBufPtr - (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE])));
+			NdisZeroMemory((u8 *)(&pMacEntry->CachedBuf[0]),
+				       sizeof(pMacEntry->CachedBuf));
+			NdisMoveMemory((u8 *)(&pMacEntry->CachedBuf[0]),
+				       (u8 *)(&pTxBlk->
+						 HeaderBuf[TXINFO_SIZE]),
+				       (pHeaderBufPtr -
+					(u8 *)(&pTxBlk->
+						  HeaderBuf[TXINFO_SIZE])));
 			pMacEntry->isCached = TRUE;
 		}
 
-		// calculate Transmitted AMPDU count and ByteCount
+		/* calculate Transmitted AMPDU count and ByteCount */
 		{
-			pAd->RalinkCounters.TransmittedMPDUsInAMPDUCount.u.LowPart ++;
-			pAd->RalinkCounters.TransmittedOctetsInAMPDUCount.QuadPart += pTxBlk->SrcBufLen;
+			pAd->RalinkCounters.TransmittedMPDUsInAMPDUCount.u.
+			    LowPart++;
+			pAd->RalinkCounters.TransmittedOctetsInAMPDUCount.
+			    QuadPart += pTxBlk->SrcBufLen;
 		}
 
-		//FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
+		/*FreeNumber = GET_TXRING_FREENO(pAd, QueIdx); */
 
 		HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
 
-		//
-		// Kick out Tx
-		//
-#ifdef RT2860
+		/* */
+		/* Kick out Tx */
+		/* */
 		if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
-#endif
 			HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
 
 		pAd->RalinkCounters.KickTxCount++;
@@ -1801,118 +1819,124 @@
 
 }
 
-
-VOID STA_AMSDU_Frame_Tx(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk)
+void STA_AMSDU_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
 {
-	PUCHAR			pHeaderBufPtr;
-	USHORT			FreeNumber;
-	USHORT			subFramePayloadLen = 0;	// AMSDU Subframe length without AMSDU-Header / Padding.
-	USHORT			totalMPDUSize=0;
-	UCHAR			*subFrameHeader;
-	UCHAR			padding = 0;
-	USHORT			FirstTx = 0, LastTxIdx = 0;
-	BOOLEAN			bVLANPkt;
-	int 			frameNum = 0;
-	PQUEUE_ENTRY	pQEntry;
-
+	u8 *pHeaderBufPtr;
+	u16 FreeNumber;
+	u16 subFramePayloadLen = 0;	/* AMSDU Subframe length without AMSDU-Header / Padding. */
+	u16 totalMPDUSize = 0;
+	u8 *subFrameHeader;
+	u8 padding = 0;
+	u16 FirstTx = 0, LastTxIdx = 0;
+	BOOLEAN bVLANPkt;
+	int frameNum = 0;
+	struct rt_queue_entry *pQEntry;
 
 	ASSERT(pTxBlk);
 
 	ASSERT((pTxBlk->TxPacketList.Number > 1));
 
-	while(pTxBlk->TxPacketList.Head)
-	{
+	while (pTxBlk->TxPacketList.Head) {
 		pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
 		pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
-		if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
-		{
-			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+		if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
+			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket,
+					    NDIS_STATUS_FAILURE);
 			continue;
 		}
 
-		bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
+		bVLANPkt =
+		    (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
 
-		// skip 802.3 header
+		/* skip 802.3 header */
 		pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
-		pTxBlk->SrcBufLen  -= LENGTH_802_3;
+		pTxBlk->SrcBufLen -= LENGTH_802_3;
 
-		// skip vlan tag
-		if (bVLANPkt)
-		{
-			pTxBlk->pSrcBufData	+= LENGTH_802_1Q;
-			pTxBlk->SrcBufLen	-= LENGTH_802_1Q;
+		/* skip vlan tag */
+		if (bVLANPkt) {
+			pTxBlk->pSrcBufData += LENGTH_802_1Q;
+			pTxBlk->SrcBufLen -= LENGTH_802_1Q;
 		}
 
-		if (frameNum == 0)
-		{
-			pHeaderBufPtr = STA_Build_AMSDU_Frame_Header(pAd, pTxBlk);
+		if (frameNum == 0) {
+			pHeaderBufPtr =
+			    STA_Build_AMSDU_Frame_Header(pAd, pTxBlk);
 
-			// NOTE: TxWI->MPDUtotalByteCount will be updated after final frame was handled.
-			RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
-		}
-		else
-		{
+			/* NOTE: TxWI->MPDUtotalByteCount will be updated after final frame was handled. */
+			RTMPWriteTxWI_Data(pAd,
+					   (struct rt_txwi *) (&pTxBlk->
+							  HeaderBuf
+							  [TXINFO_SIZE]),
+					   pTxBlk);
+		} else {
 			pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
-			padding = ROUND_UP(LENGTH_AMSDU_SUBFRAMEHEAD + subFramePayloadLen, 4) - (LENGTH_AMSDU_SUBFRAMEHEAD + subFramePayloadLen);
-			NdisZeroMemory(pHeaderBufPtr, padding + LENGTH_AMSDU_SUBFRAMEHEAD);
+			padding =
+			    ROUND_UP(LENGTH_AMSDU_SUBFRAMEHEAD +
+				     subFramePayloadLen,
+				     4) - (LENGTH_AMSDU_SUBFRAMEHEAD +
+					   subFramePayloadLen);
+			NdisZeroMemory(pHeaderBufPtr,
+				       padding + LENGTH_AMSDU_SUBFRAMEHEAD);
 			pHeaderBufPtr += padding;
 			pTxBlk->MpduHeaderLen = padding;
 		}
 
-		//
-		// A-MSDU subframe
-		//   DA(6)+SA(6)+Length(2) + LLC/SNAP Encap
-		//
+		/* */
+		/* A-MSDU subframe */
+		/*   DA(6)+SA(6)+Length(2) + LLC/SNAP Encap */
+		/* */
 		subFrameHeader = pHeaderBufPtr;
 		subFramePayloadLen = pTxBlk->SrcBufLen;
 
 		NdisMoveMemory(subFrameHeader, pTxBlk->pSrcBufHeader, 12);
 
-
 		pHeaderBufPtr += LENGTH_AMSDU_SUBFRAMEHEAD;
 		pTxBlk->MpduHeaderLen += LENGTH_AMSDU_SUBFRAMEHEAD;
 
-
-		//
-		// Insert LLC-SNAP encapsulation - 8 octets
-		//
-		EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
+		/* */
+		/* Insert LLC-SNAP encapsulation - 8 octets */
+		/* */
+		EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData - 2,
+						    pTxBlk->pExtraLlcSnapEncap);
 
 		subFramePayloadLen = pTxBlk->SrcBufLen;
 
-		if (pTxBlk->pExtraLlcSnapEncap)
-		{
-			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
+		if (pTxBlk->pExtraLlcSnapEncap) {
+			NdisMoveMemory(pHeaderBufPtr,
+				       pTxBlk->pExtraLlcSnapEncap, 6);
 			pHeaderBufPtr += 6;
-			// get 2 octets (TypeofLen)
-			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
+			/* get 2 octets (TypeofLen) */
+			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData - 2,
+				       2);
 			pHeaderBufPtr += 2;
 			pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
 			subFramePayloadLen += LENGTH_802_1_H;
 		}
-
-		// update subFrame Length field
+		/* update subFrame Length field */
 		subFrameHeader[12] = (subFramePayloadLen & 0xFF00) >> 8;
 		subFrameHeader[13] = subFramePayloadLen & 0xFF;
 
 		totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
 
-		if (frameNum ==0)
-			FirstTx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
+		if (frameNum == 0)
+			FirstTx =
+			    HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum,
+						     &FreeNumber);
 		else
-			LastTxIdx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
+			LastTxIdx =
+			    HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum,
+						     &FreeNumber);
 
 		frameNum++;
 
 		pAd->RalinkCounters.KickTxCount++;
 		pAd->RalinkCounters.OneSecTxDoneCount++;
 
-		// calculate Transmitted AMSDU Count and ByteCount
+		/* calculate Transmitted AMSDU Count and ByteCount */
 		{
-			pAd->RalinkCounters.TransmittedAMSDUCount.u.LowPart ++;
-			pAd->RalinkCounters.TransmittedOctetsInAMSDU.QuadPart += totalMPDUSize;
+			pAd->RalinkCounters.TransmittedAMSDUCount.u.LowPart++;
+			pAd->RalinkCounters.TransmittedOctetsInAMSDU.QuadPart +=
+			    totalMPDUSize;
 		}
 
 	}
@@ -1920,38 +1944,31 @@
 	HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
 	HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
 
-	//
-	// Kick out Tx
-	//
-#ifdef RT2860
+	/* */
+	/* Kick out Tx */
+	/* */
 	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
-#endif
 		HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
 }
 
-VOID STA_Legacy_Frame_Tx(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk)
+void STA_Legacy_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
 {
-	HEADER_802_11	*pHeader_802_11;
-	PUCHAR			pHeaderBufPtr;
-	USHORT			FreeNumber;
-	BOOLEAN			bVLANPkt;
-	PQUEUE_ENTRY	pQEntry;
+	struct rt_header_802_11 *pHeader_802_11;
+	u8 *pHeaderBufPtr;
+	u16 FreeNumber;
+	BOOLEAN bVLANPkt;
+	struct rt_queue_entry *pQEntry;
 
 	ASSERT(pTxBlk);
 
-
 	pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
 	pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
-	if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
-	{
+	if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
 		RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
 		return;
 	}
 
-	if (pTxBlk->TxFrameType == TX_MCAST_FRAME)
-	{
+	if (pTxBlk->TxFrameType == TX_MCAST_FRAME) {
 		INC_COUNTER64(pAd->WlanCounters.MulticastTransmittedFrameCount);
 	}
 
@@ -1968,181 +1985,187 @@
 	STAFindCipherAlgorithm(pAd, pTxBlk);
 	STABuildCommon802_11Header(pAd, pTxBlk);
 
-
-	// skip 802.3 header
+	/* skip 802.3 header */
 	pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
-	pTxBlk->SrcBufLen  -= LENGTH_802_3;
+	pTxBlk->SrcBufLen -= LENGTH_802_3;
 
-	// skip vlan tag
-	if (bVLANPkt)
-	{
-		pTxBlk->pSrcBufData	+= LENGTH_802_1Q;
-		pTxBlk->SrcBufLen	-= LENGTH_802_1Q;
+	/* skip vlan tag */
+	if (bVLANPkt) {
+		pTxBlk->pSrcBufData += LENGTH_802_1Q;
+		pTxBlk->SrcBufLen -= LENGTH_802_1Q;
 	}
 
 	pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
-	pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
+	pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;
 
-	// skip common header
+	/* skip common header */
 	pHeaderBufPtr += pTxBlk->MpduHeaderLen;
 
-	if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
-	{
-		//
-		// build QOS Control bytes
-		//
-		*pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
-		*(pHeaderBufPtr+1) = 0;
-		pHeaderBufPtr +=2;
+	if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) {
+		/* */
+		/* build QOS Control bytes */
+		/* */
+		*(pHeaderBufPtr) =
+		    ((pTxBlk->UserPriority & 0x0F) | (pAd->CommonCfg.
+						      AckPolicy[pTxBlk->
+								QueIdx] << 5));
+		*(pHeaderBufPtr + 1) = 0;
+		pHeaderBufPtr += 2;
 		pTxBlk->MpduHeaderLen += 2;
 	}
-
-	// The remaining content of MPDU header should locate at 4-octets aligment
-	pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
-	pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
-	pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
+	/* The remaining content of MPDU header should locate at 4-octets aligment */
+	pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
+	pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
+	pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);
 
 	{
 
-		//
-		// Insert LLC-SNAP encapsulation - 8 octets
-		//
-		//
-   		// if original Ethernet frame contains no LLC/SNAP,
-		// then an extra LLC/SNAP encap is required
-		//
-		EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader, pTxBlk->pExtraLlcSnapEncap);
-		if (pTxBlk->pExtraLlcSnapEncap)
-		{
-			UCHAR vlan_size;
+		/* */
+		/* Insert LLC-SNAP encapsulation - 8 octets */
+		/* */
+		/* */
+		/* if original Ethernet frame contains no LLC/SNAP, */
+		/* then an extra LLC/SNAP encap is required */
+		/* */
+		EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader,
+						   pTxBlk->pExtraLlcSnapEncap);
+		if (pTxBlk->pExtraLlcSnapEncap) {
+			u8 vlan_size;
 
-			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
+			NdisMoveMemory(pHeaderBufPtr,
+				       pTxBlk->pExtraLlcSnapEncap, 6);
 			pHeaderBufPtr += 6;
-			// skip vlan tag
-			vlan_size =  (bVLANPkt) ? LENGTH_802_1Q : 0;
-			// get 2 octets (TypeofLen)
-			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader+12+vlan_size, 2);
+			/* skip vlan tag */
+			vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0;
+			/* get 2 octets (TypeofLen) */
+			NdisMoveMemory(pHeaderBufPtr,
+				       pTxBlk->pSrcBufHeader + 12 + vlan_size,
+				       2);
 			pHeaderBufPtr += 2;
 			pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
 		}
 
 	}
 
-	//
-	// prepare for TXWI
-	// use Wcid as Key Index
-	//
+	/* */
+	/* prepare for TXWI */
+	/* use Wcid as Key Index */
+	/* */
 
-	RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+	RTMPWriteTxWI_Data(pAd, (struct rt_txwi *) (&pTxBlk->HeaderBuf[TXINFO_SIZE]),
+			   pTxBlk);
 
-	//FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
+	/*FreeNumber = GET_TXRING_FREENO(pAd, QueIdx); */
 
 	HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
 
 	pAd->RalinkCounters.KickTxCount++;
 	pAd->RalinkCounters.OneSecTxDoneCount++;
 
-	//
-	// Kick out Tx
-	//
-#ifdef RT2860
+	/* */
+	/* Kick out Tx */
+	/* */
 	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
-#endif
 		HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
 }
 
-
-VOID STA_ARalink_Frame_Tx(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk)
+void STA_ARalink_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
 {
-	PUCHAR			pHeaderBufPtr;
-	USHORT			FreeNumber;
-	USHORT			totalMPDUSize=0;
-	USHORT			FirstTx, LastTxIdx;
-	int 			frameNum = 0;
-	BOOLEAN			bVLANPkt;
-	PQUEUE_ENTRY	pQEntry;
-
+	u8 *pHeaderBufPtr;
+	u16 FreeNumber;
+	u16 totalMPDUSize = 0;
+	u16 FirstTx, LastTxIdx;
+	int frameNum = 0;
+	BOOLEAN bVLANPkt;
+	struct rt_queue_entry *pQEntry;
 
 	ASSERT(pTxBlk);
 
-	ASSERT((pTxBlk->TxPacketList.Number== 2));
+	ASSERT((pTxBlk->TxPacketList.Number == 2));
 
-
-	FirstTx = LastTxIdx = 0;  // Is it ok init they as 0?
-	while(pTxBlk->TxPacketList.Head)
-	{
+	FirstTx = LastTxIdx = 0;	/* Is it ok init they as 0? */
+	while (pTxBlk->TxPacketList.Head) {
 		pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
 		pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
 
-		if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
-		{
-			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+		if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
+			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket,
+					    NDIS_STATUS_FAILURE);
 			continue;
 		}
 
-		bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
+		bVLANPkt =
+		    (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
 
-		// skip 802.3 header
+		/* skip 802.3 header */
 		pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
-		pTxBlk->SrcBufLen  -= LENGTH_802_3;
+		pTxBlk->SrcBufLen -= LENGTH_802_3;
 
-		// skip vlan tag
-		if (bVLANPkt)
-		{
-			pTxBlk->pSrcBufData	+= LENGTH_802_1Q;
-			pTxBlk->SrcBufLen	-= LENGTH_802_1Q;
+		/* skip vlan tag */
+		if (bVLANPkt) {
+			pTxBlk->pSrcBufData += LENGTH_802_1Q;
+			pTxBlk->SrcBufLen -= LENGTH_802_1Q;
 		}
 
-		if (frameNum == 0)
-		{	// For first frame, we need to create the 802.11 header + padding(optional) + RA-AGG-LEN + SNAP Header
+		if (frameNum == 0) {	/* For first frame, we need to create the 802.11 header + padding(optional) + RA-AGG-LEN + SNAP Header */
 
-			pHeaderBufPtr = STA_Build_ARalink_Frame_Header(pAd, pTxBlk);
+			pHeaderBufPtr =
+			    STA_Build_ARalink_Frame_Header(pAd, pTxBlk);
 
-			// It's ok write the TxWI here, because the TxWI->MPDUtotalByteCount
-			//	will be updated after final frame was handled.
-			RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+			/* It's ok write the TxWI here, because the TxWI->MPDUtotalByteCount */
+			/*      will be updated after final frame was handled. */
+			RTMPWriteTxWI_Data(pAd,
+					   (struct rt_txwi *) (&pTxBlk->
+							  HeaderBuf
+							  [TXINFO_SIZE]),
+					   pTxBlk);
 
+			/* */
+			/* Insert LLC-SNAP encapsulation - 8 octets */
+			/* */
+			EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->
+							    pSrcBufData - 2,
+							    pTxBlk->
+							    pExtraLlcSnapEncap);
 
-			//
-			// Insert LLC-SNAP encapsulation - 8 octets
-			//
-			EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
-
-			if (pTxBlk->pExtraLlcSnapEncap)
-			{
-				NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
+			if (pTxBlk->pExtraLlcSnapEncap) {
+				NdisMoveMemory(pHeaderBufPtr,
+					       pTxBlk->pExtraLlcSnapEncap, 6);
 				pHeaderBufPtr += 6;
-				// get 2 octets (TypeofLen)
-				NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
+				/* get 2 octets (TypeofLen) */
+				NdisMoveMemory(pHeaderBufPtr,
+					       pTxBlk->pSrcBufData - 2, 2);
 				pHeaderBufPtr += 2;
 				pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
 			}
-		}
-		else
-		{	// For second aggregated frame, we need create the 802.3 header to headerBuf, because PCI will copy it to SDPtr0.
+		} else {	/* For second aggregated frame, we need create the 802.3 header to headerBuf, because PCI will copy it to SDPtr0. */
 
 			pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
 			pTxBlk->MpduHeaderLen = 0;
 
-			// A-Ralink sub-sequent frame header is the same as 802.3 header.
-			//   DA(6)+SA(6)+FrameType(2)
-			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader, 12);
+			/* A-Ralink sub-sequent frame header is the same as 802.3 header. */
+			/*   DA(6)+SA(6)+FrameType(2) */
+			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader,
+				       12);
 			pHeaderBufPtr += 12;
-			// get 2 octets (TypeofLen)
-			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
+			/* get 2 octets (TypeofLen) */
+			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData - 2,
+				       2);
 			pHeaderBufPtr += 2;
 			pTxBlk->MpduHeaderLen = LENGTH_ARALINK_SUBFRAMEHEAD;
 		}
 
 		totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
 
-		//FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
-		if (frameNum ==0)
-			FirstTx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
+		/*FreeNumber = GET_TXRING_FREENO(pAd, QueIdx); */
+		if (frameNum == 0)
+			FirstTx =
+			    HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum,
+						     &FreeNumber);
 		else
-			LastTxIdx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
+			LastTxIdx =
+			    HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum,
+						     &FreeNumber);
 
 		frameNum++;
 
@@ -2155,40 +2178,34 @@
 	HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
 	HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
 
-	//
-	// Kick out Tx
-	//
-#ifdef RT2860
+	/* */
+	/* Kick out Tx */
+	/* */
 	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
-#endif
 		HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
 
 }
 
-
-VOID STA_Fragment_Frame_Tx(
-	IN RTMP_ADAPTER *pAd,
-	IN TX_BLK		*pTxBlk)
+void STA_Fragment_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
 {
-	HEADER_802_11	*pHeader_802_11;
-	PUCHAR			pHeaderBufPtr;
-	USHORT			FreeNumber;
-	UCHAR 			fragNum = 0;
-	PACKET_INFO		PacketInfo;
-	USHORT			EncryptionOverhead = 0;
-	UINT32			FreeMpduSize, SrcRemainingBytes;
-	USHORT			AckDuration;
-	UINT 			NextMpduSize;
-	BOOLEAN			bVLANPkt;
-	PQUEUE_ENTRY	pQEntry;
-
+	struct rt_header_802_11 *pHeader_802_11;
+	u8 *pHeaderBufPtr;
+	u16 FreeNumber;
+	u8 fragNum = 0;
+	struct rt_packet_info PacketInfo;
+	u16 EncryptionOverhead = 0;
+	u32 FreeMpduSize, SrcRemainingBytes;
+	u16 AckDuration;
+	u32 NextMpduSize;
+	BOOLEAN bVLANPkt;
+	struct rt_queue_entry *pQEntry;
+	HTTRANSMIT_SETTING *pTransmit;
 
 	ASSERT(pTxBlk);
 
 	pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
 	pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
-	if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
-	{
+	if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
 		RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
 		return;
 	}
@@ -2199,112 +2216,125 @@
 	STAFindCipherAlgorithm(pAd, pTxBlk);
 	STABuildCommon802_11Header(pAd, pTxBlk);
 
-	if (pTxBlk->CipherAlg == CIPHER_TKIP)
-	{
-		pTxBlk->pPacket = duplicate_pkt_with_TKIP_MIC(pAd, pTxBlk->pPacket);
+	if (pTxBlk->CipherAlg == CIPHER_TKIP) {
+		pTxBlk->pPacket =
+		    duplicate_pkt_with_TKIP_MIC(pAd, pTxBlk->pPacket);
 		if (pTxBlk->pPacket == NULL)
 			return;
-		RTMP_QueryPacketInfo(pTxBlk->pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
+		RTMP_QueryPacketInfo(pTxBlk->pPacket, &PacketInfo,
+				     &pTxBlk->pSrcBufHeader,
+				     &pTxBlk->SrcBufLen);
 	}
-
-	// skip 802.3 header
+	/* skip 802.3 header */
 	pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
-	pTxBlk->SrcBufLen  -= LENGTH_802_3;
+	pTxBlk->SrcBufLen -= LENGTH_802_3;
 
-
-	// skip vlan tag
-	if (bVLANPkt)
-	{
-		pTxBlk->pSrcBufData	+= LENGTH_802_1Q;
-		pTxBlk->SrcBufLen	-= LENGTH_802_1Q;
+	/* skip vlan tag */
+	if (bVLANPkt) {
+		pTxBlk->pSrcBufData += LENGTH_802_1Q;
+		pTxBlk->SrcBufLen -= LENGTH_802_1Q;
 	}
 
 	pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
-	pHeader_802_11 = (HEADER_802_11 *)pHeaderBufPtr;
+	pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;
 
-
-	// skip common header
+	/* skip common header */
 	pHeaderBufPtr += pTxBlk->MpduHeaderLen;
 
-	if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
-	{
-		//
-		// build QOS Control bytes
-		//
+	if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) {
+		/* */
+		/* build QOS Control bytes */
+		/* */
 		*pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
 
-		*(pHeaderBufPtr+1) = 0;
-		pHeaderBufPtr +=2;
+		*(pHeaderBufPtr + 1) = 0;
+		pHeaderBufPtr += 2;
 		pTxBlk->MpduHeaderLen += 2;
 	}
+	/* */
+	/* padding at front of LLC header */
+	/* LLC header should locate at 4-octets aligment */
+	/* */
+	pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
+	pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
+	pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);
 
-	//
-	// padding at front of LLC header
-	// LLC header should locate at 4-octets aligment
-	//
-	pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
-	pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
-	pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
-
-
-
-	//
-	// Insert LLC-SNAP encapsulation - 8 octets
-	//
-	//
-   	// if original Ethernet frame contains no LLC/SNAP,
-	// then an extra LLC/SNAP encap is required
-	//
-	EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader, pTxBlk->pExtraLlcSnapEncap);
-	if (pTxBlk->pExtraLlcSnapEncap)
-	{
-		UCHAR vlan_size;
+	/* */
+	/* Insert LLC-SNAP encapsulation - 8 octets */
+	/* */
+	/* */
+	/* if original Ethernet frame contains no LLC/SNAP, */
+	/* then an extra LLC/SNAP encap is required */
+	/* */
+	EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader,
+					   pTxBlk->pExtraLlcSnapEncap);
+	if (pTxBlk->pExtraLlcSnapEncap) {
+		u8 vlan_size;
 
 		NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
 		pHeaderBufPtr += 6;
-		// skip vlan tag
-		vlan_size =  (bVLANPkt) ? LENGTH_802_1Q : 0;
-		// get 2 octets (TypeofLen)
-		NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader+12+vlan_size, 2);
+		/* skip vlan tag */
+		vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0;
+		/* get 2 octets (TypeofLen) */
+		NdisMoveMemory(pHeaderBufPtr,
+			       pTxBlk->pSrcBufHeader + 12 + vlan_size, 2);
 		pHeaderBufPtr += 2;
 		pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
 	}
 
+	/* If TKIP is used and fragmentation is required. Driver has to */
+	/*      append TKIP MIC at tail of the scatter buffer */
+	/*      MAC ASIC will only perform IV/EIV/ICV insertion but no TKIP MIC */
+	if (pTxBlk->CipherAlg == CIPHER_TKIP) {
+		RTMPCalculateMICValue(pAd, pTxBlk->pPacket,
+				      pTxBlk->pExtraLlcSnapEncap, pTxBlk->pKey,
+				      0);
 
-	// If TKIP is used and fragmentation is required. Driver has to
-	//	append TKIP MIC at tail of the scatter buffer
-	//	MAC ASIC will only perform IV/EIV/ICV insertion but no TKIP MIC
-	if (pTxBlk->CipherAlg == CIPHER_TKIP)
-	{
-
-		// NOTE: DON'T refer the skb->len directly after following copy. Becasue the length is not adjust
-		//			to correct lenght, refer to pTxBlk->SrcBufLen for the packet length in following progress.
-		NdisMoveMemory(pTxBlk->pSrcBufData + pTxBlk->SrcBufLen, &pAd->PrivateInfo.Tx.MIC[0], 8);
-		//skb_put((RTPKT_TO_OSPKT(pTxBlk->pPacket))->tail, 8);
+		/* NOTE: DON'T refer the skb->len directly after following copy. Becasue the length is not adjust */
+		/*                      to correct lenght, refer to pTxBlk->SrcBufLen for the packet length in following progress. */
+		NdisMoveMemory(pTxBlk->pSrcBufData + pTxBlk->SrcBufLen,
+			       &pAd->PrivateInfo.Tx.MIC[0], 8);
+		/*skb_put((RTPKT_TO_OSPKT(pTxBlk->pPacket))->tail, 8); */
 		pTxBlk->SrcBufLen += 8;
 		pTxBlk->TotalFrameLen += 8;
 		pTxBlk->CipherAlg = CIPHER_TKIP_NO_MIC;
 	}
-
-	//
-	// calcuate the overhead bytes that encryption algorithm may add. This
-	// affects the calculate of "duration" field
-	//
-	if ((pTxBlk->CipherAlg == CIPHER_WEP64) || (pTxBlk->CipherAlg == CIPHER_WEP128))
-		EncryptionOverhead = 8; //WEP: IV[4] + ICV[4];
+	/* */
+	/* calcuate the overhead bytes that encryption algorithm may add. This */
+	/* affects the calculate of "duration" field */
+	/* */
+	if ((pTxBlk->CipherAlg == CIPHER_WEP64)
+	    || (pTxBlk->CipherAlg == CIPHER_WEP128))
+		EncryptionOverhead = 8;	/*WEP: IV[4] + ICV[4]; */
 	else if (pTxBlk->CipherAlg == CIPHER_TKIP_NO_MIC)
-		EncryptionOverhead = 12;//TKIP: IV[4] + EIV[4] + ICV[4], MIC will be added to TotalPacketLength
+		EncryptionOverhead = 12;	/*TKIP: IV[4] + EIV[4] + ICV[4], MIC will be added to TotalPacketLength */
 	else if (pTxBlk->CipherAlg == CIPHER_TKIP)
-		EncryptionOverhead = 20;//TKIP: IV[4] + EIV[4] + ICV[4] + MIC[8]
+		EncryptionOverhead = 20;	/*TKIP: IV[4] + EIV[4] + ICV[4] + MIC[8] */
 	else if (pTxBlk->CipherAlg == CIPHER_AES)
-		EncryptionOverhead = 16;	// AES: IV[4] + EIV[4] + MIC[8]
+		EncryptionOverhead = 16;	/* AES: IV[4] + EIV[4] + MIC[8] */
 	else
 		EncryptionOverhead = 0;
 
-	// decide how much time an ACK/CTS frame will consume in the air
-	AckDuration = RTMPCalcDuration(pAd, pAd->CommonCfg.ExpectedACKRate[pTxBlk->TxRate], 14);
+	pTransmit = pTxBlk->pTransmit;
+	/* Decide the TX rate */
+	if (pTransmit->field.MODE == MODE_CCK)
+		pTxBlk->TxRate = pTransmit->field.MCS;
+	else if (pTransmit->field.MODE == MODE_OFDM)
+		pTxBlk->TxRate = pTransmit->field.MCS + RATE_FIRST_OFDM_RATE;
+	else
+		pTxBlk->TxRate = RATE_6_5;
 
-	// Init the total payload length of this frame.
+	/* decide how much time an ACK/CTS frame will consume in the air */
+	if (pTxBlk->TxRate <= RATE_LAST_OFDM_RATE)
+		AckDuration =
+		    RTMPCalcDuration(pAd,
+				     pAd->CommonCfg.ExpectedACKRate[pTxBlk->
+								    TxRate],
+				     14);
+	else
+		AckDuration = RTMPCalcDuration(pAd, RATE_6_5, 14);
+
+	/* Init the total payload length of this frame. */
 	SrcRemainingBytes = pTxBlk->SrcBufLen;
 
 	pTxBlk->TotalFragNum = 0xff;
@@ -2315,25 +2345,28 @@
 
 		FreeMpduSize -= pTxBlk->MpduHeaderLen;
 
-		if (SrcRemainingBytes <= FreeMpduSize)
-		{	// this is the last or only fragment
+		if (SrcRemainingBytes <= FreeMpduSize) {	/* this is the last or only fragment */
 
 			pTxBlk->SrcBufLen = SrcRemainingBytes;
 
 			pHeader_802_11->FC.MoreFrag = 0;
-			pHeader_802_11->Duration = pAd->CommonCfg.Dsifs + AckDuration;
+			pHeader_802_11->Duration =
+			    pAd->CommonCfg.Dsifs + AckDuration;
 
-			// Indicate the lower layer that this's the last fragment.
+			/* Indicate the lower layer that this's the last fragment. */
 			pTxBlk->TotalFragNum = fragNum;
-		}
-		else
-		{	// more fragment is required
+		} else {	/* more fragment is required */
 
 			pTxBlk->SrcBufLen = FreeMpduSize;
 
-			NextMpduSize = min(((UINT)SrcRemainingBytes - pTxBlk->SrcBufLen), ((UINT)pAd->CommonCfg.FragmentThreshold));
+			NextMpduSize =
+			    min(((u32)SrcRemainingBytes - pTxBlk->SrcBufLen),
+				((u32)pAd->CommonCfg.FragmentThreshold));
 			pHeader_802_11->FC.MoreFrag = 1;
-			pHeader_802_11->Duration = (3 * pAd->CommonCfg.Dsifs) + (2 * AckDuration) + RTMPCalcDuration(pAd, pTxBlk->TxRate, NextMpduSize + EncryptionOverhead);
+			pHeader_802_11->Duration =
+			    (3 * pAd->CommonCfg.Dsifs) + (2 * AckDuration) +
+			    RTMPCalcDuration(pAd, pTxBlk->TxRate,
+					     NextMpduSize + EncryptionOverhead);
 		}
 
 		if (fragNum == 0)
@@ -2341,16 +2374,19 @@
 		else
 			pTxBlk->FrameGap = IFS_SIFS;
 
-		RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+		RTMPWriteTxWI_Data(pAd,
+				   (struct rt_txwi *) (&pTxBlk->
+						  HeaderBuf[TXINFO_SIZE]),
+				   pTxBlk);
 
 		HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, &FreeNumber);
 
 		pAd->RalinkCounters.KickTxCount++;
 		pAd->RalinkCounters.OneSecTxDoneCount++;
 
-		// Update the frame number, remaining size of the NDIS packet payload.
+		/* Update the frame number, remaining size of the NDIS packet payload. */
 
-		// space for 802.11 header.
+		/* space for 802.11 header. */
 		if (fragNum == 0 && pTxBlk->pExtraLlcSnapEncap)
 			pTxBlk->MpduHeaderLen -= LENGTH_802_1_H;
 
@@ -2358,17 +2394,17 @@
 		SrcRemainingBytes -= pTxBlk->SrcBufLen;
 		pTxBlk->pSrcBufData += pTxBlk->SrcBufLen;
 
-		pHeader_802_11->Frag++;	 // increase Frag #
+		pHeader_802_11->Frag++;	/* increase Frag # */
 
-	}while(SrcRemainingBytes > 0);
+	} while (SrcRemainingBytes > 0);
 
-	//
-	// Kick out Tx
-	//
-	HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+	/* */
+	/* Kick out Tx */
+	/* */
+	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
+		HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
 }
 
-
 #define RELEASE_FRAMES_OF_TXBLK(_pAd, _pTxBlk, _pQEntry, _Status) 										\
 		while(_pTxBlk->TxPacketList.Head)														\
 		{																						\
@@ -2376,7 +2412,6 @@
 			RELEASE_NDIS_PACKET(_pAd, QUEUE_ENTRY_TO_PACKET(_pQEntry), _Status);	\
 		}
 
-
 /*
 	========================================================================
 
@@ -2387,7 +2422,7 @@
 
 	Arguments:
 		pAd 	Pointer to our adapter
-		PNDIS_PACKET	Pointer to outgoing Ndis frame
+		void *	Pointer to outgoing Ndis frame
 		NumberOfFrag	Number of fragment required
 
 	Return Value:
@@ -2399,122 +2434,117 @@
 
 	========================================================================
 */
-NDIS_STATUS STAHardTransmit(
-	IN PRTMP_ADAPTER	pAd,
-	IN TX_BLK 			*pTxBlk,
-	IN	UCHAR			QueIdx)
+int STAHardTransmit(struct rt_rtmp_adapter *pAd,
+			    struct rt_tx_blk *pTxBlk, u8 QueIdx)
 {
-	NDIS_PACKET		*pPacket;
-	PQUEUE_ENTRY	pQEntry;
+	char *pPacket;
+	struct rt_queue_entry *pQEntry;
 
-	// ---------------------------------------------
-	// STEP 0. DO SANITY CHECK AND SOME EARLY PREPARATION.
-	// ---------------------------------------------
-	//
+	/* --------------------------------------------- */
+	/* STEP 0. DO SANITY CHECK AND SOME EARLY PREPARATION. */
+	/* --------------------------------------------- */
+	/* */
 	ASSERT(pTxBlk->TxPacketList.Number);
-	if (pTxBlk->TxPacketList.Head == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("pTxBlk->TotalFrameNum == %ld!\n", pTxBlk->TxPacketList.Number));
+	if (pTxBlk->TxPacketList.Head == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("pTxBlk->TotalFrameNum == %ld!\n",
+			  pTxBlk->TxPacketList.Number));
 		return NDIS_STATUS_FAILURE;
 	}
 
 	pPacket = QUEUE_ENTRY_TO_PACKET(pTxBlk->TxPacketList.Head);
 
-	// ------------------------------------------------------------------
-	// STEP 1. WAKE UP PHY
-	//		outgoing frame always wakeup PHY to prevent frame lost and
-	//		turn off PSM bit to improve performance
-	// ------------------------------------------------------------------
-	// not to change PSM bit, just send this frame out?
-	if ((pAd->StaCfg.Psm == PWR_SAVE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-	{
-	    DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicForceWakeup At HardTx\n"));
-#ifdef RT2860
-		AsicForceWakeup(pAd, FROM_TX);
-#endif
-#ifdef RT2870
+	/* ------------------------------------------------------------------ */
+	/* STEP 1. WAKE UP PHY */
+	/*              outgoing frame always wakeup PHY to prevent frame lost and */
+	/*              turn off PSM bit to improve performance */
+	/* ------------------------------------------------------------------ */
+	/* not to change PSM bit, just send this frame out? */
+	if ((pAd->StaCfg.Psm == PWR_SAVE)
+	    && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
+		DBGPRINT_RAW(RT_DEBUG_INFO, ("AsicForceWakeup At HardTx\n"));
+#ifdef RTMP_MAC_PCI
 		AsicForceWakeup(pAd, TRUE);
-#endif
+#endif /* RTMP_MAC_PCI // */
+#ifdef RTMP_MAC_USB
+		RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_FORCE_WAKE_UP, NULL, 0);
+#endif /* RTMP_MAC_USB // */
 	}
-
-	// It should not change PSM bit, when APSD turn on.
-	if ((!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable) && (pAd->CommonCfg.bAPSDForcePowerSave == FALSE))
-		|| (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
-		|| (RTMP_GET_PACKET_WAI(pTxBlk->pPacket)))
-	{
+	/* It should not change PSM bit, when APSD turn on. */
+	if ((!
+	     (pAd->CommonCfg.bAPSDCapable
+	      && pAd->CommonCfg.APEdcaParm.bAPSDCapable)
+	     && (pAd->CommonCfg.bAPSDForcePowerSave == FALSE))
+	    || (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
+	    || (RTMP_GET_PACKET_WAI(pTxBlk->pPacket))) {
 		if ((pAd->StaCfg.Psm == PWR_SAVE) &&
-            (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeFast_PSP))
-			MlmeSetPsmBit(pAd, PWR_ACTIVE);
+		    (pAd->StaCfg.WindowsPowerMode ==
+		     Ndis802_11PowerModeFast_PSP))
+			RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
 	}
 
-	switch (pTxBlk->TxFrameType)
-	{
-		case TX_AMPDU_FRAME:
-				STA_AMPDU_Frame_Tx(pAd, pTxBlk);
-			break;
-		case TX_AMSDU_FRAME:
-				STA_AMSDU_Frame_Tx(pAd, pTxBlk);
-			break;
-		case TX_LEGACY_FRAME:
-				STA_Legacy_Frame_Tx(pAd, pTxBlk);
-			break;
-		case TX_MCAST_FRAME:
-				STA_Legacy_Frame_Tx(pAd, pTxBlk);
-			break;
-		case TX_RALINK_FRAME:
-				STA_ARalink_Frame_Tx(pAd, pTxBlk);
-			break;
-		case TX_FRAG_FRAME:
-				STA_Fragment_Frame_Tx(pAd, pTxBlk);
-			break;
-		default:
-			{
-				// It should not happened!
-				DBGPRINT(RT_DEBUG_ERROR, ("Send a pacekt was not classified!! It should not happen!\n"));
-				while(pTxBlk->TxPacketList.Number)
-				{
-					pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
-					pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
-					if (pPacket)
-						RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-				}
+	switch (pTxBlk->TxFrameType) {
+	case TX_AMPDU_FRAME:
+		STA_AMPDU_Frame_Tx(pAd, pTxBlk);
+		break;
+	case TX_AMSDU_FRAME:
+		STA_AMSDU_Frame_Tx(pAd, pTxBlk);
+		break;
+	case TX_LEGACY_FRAME:
+		STA_Legacy_Frame_Tx(pAd, pTxBlk);
+		break;
+	case TX_MCAST_FRAME:
+		STA_Legacy_Frame_Tx(pAd, pTxBlk);
+		break;
+	case TX_RALINK_FRAME:
+		STA_ARalink_Frame_Tx(pAd, pTxBlk);
+		break;
+	case TX_FRAG_FRAME:
+		STA_Fragment_Frame_Tx(pAd, pTxBlk);
+		break;
+	default:
+		{
+			/* It should not happened! */
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("Send a packet was not classified! It should not happen!\n"));
+			while (pTxBlk->TxPacketList.Number) {
+				pQEntry =
+				    RemoveHeadQueue(&pTxBlk->TxPacketList);
+				pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+				if (pPacket)
+					RELEASE_NDIS_PACKET(pAd, pPacket,
+							    NDIS_STATUS_FAILURE);
 			}
-			break;
+		}
+		break;
 	}
 
 	return (NDIS_STATUS_SUCCESS);
 
 }
 
-ULONG  HashBytesPolynomial(UCHAR *value, unsigned int len)
+unsigned long HashBytesPolynomial(u8 * value, unsigned int len)
 {
-   unsigned char *word = value;
-   unsigned int ret = 0;
-   unsigned int i;
+	unsigned char *word = value;
+	unsigned int ret = 0;
+	unsigned int i;
 
-   for(i=0; i < len; i++)
-   {
-	  int mod = i % 32;
-	  ret ^=(unsigned int) (word[i]) << mod;
-	  ret ^=(unsigned int) (word[i]) >> (32 - mod);
-   }
-   return ret;
+	for (i = 0; i < len; i++) {
+		int mod = i % 32;
+		ret ^= (unsigned int)(word[i]) << mod;
+		ret ^= (unsigned int)(word[i]) >> (32 - mod);
+	}
+	return ret;
 }
 
-VOID Sta_Announce_or_Forward_802_3_Packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket,
-	IN	UCHAR			FromWhichBSSID)
+void Sta_Announce_or_Forward_802_3_Packet(struct rt_rtmp_adapter *pAd,
+					  void *pPacket,
+					  u8 FromWhichBSSID)
 {
-	if (TRUE
-		)
-	{
+	if (TRUE) {
 		announce_802_3_packet(pAd, pPacket);
-	}
-	else
-	{
-		// release packet
+	} else {
+		/* release packet */
 		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
 	}
 }
-
diff --git a/drivers/staging/rt2860/sta/sanity.c b/drivers/staging/rt2860/sta/sanity.c
index 7d530f6..8f9fd19 100644
--- a/drivers/staging/rt2860/sta/sanity.c
+++ b/drivers/staging/rt2860/sta/sanity.c
@@ -36,15 +36,15 @@
 */
 #include "../rt_config.h"
 
-extern UCHAR	CISCO_OUI[];
+extern u8 CISCO_OUI[];
 
-extern UCHAR	WPA_OUI[];
-extern UCHAR	RSN_OUI[];
-extern UCHAR	WME_INFO_ELEM[];
-extern UCHAR	WME_PARM_ELEM[];
-extern UCHAR	Ccx2QosInfo[];
-extern UCHAR	RALINK_OUI[];
-extern UCHAR	BROADCOM_OUI[];
+extern u8 WPA_OUI[];
+extern u8 RSN_OUI[];
+extern u8 WME_INFO_ELEM[];
+extern u8 WME_PARM_ELEM[];
+extern u8 Ccx2QosInfo[];
+extern u8 RALINK_OUI[];
+extern u8 BROADCOM_OUI[];
 
 /*
     ==========================================================================
@@ -54,27 +54,25 @@
         TRUE if all parameters are OK, FALSE otherwise
     ==========================================================================
  */
-BOOLEAN MlmeStartReqSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT CHAR Ssid[],
-    OUT UCHAR *pSsidLen)
+BOOLEAN MlmeStartReqSanity(struct rt_rtmp_adapter *pAd,
+			   void * Msg,
+			   unsigned long MsgLen,
+			   char Ssid[], u8 * pSsidLen)
 {
-    MLME_START_REQ_STRUCT *Info;
+	struct rt_mlme_start_req *Info;
 
-    Info = (MLME_START_REQ_STRUCT *)(Msg);
+	Info = (struct rt_mlme_start_req *)(Msg);
 
-    if (Info->SsidLen > MAX_LEN_OF_SSID)
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqSanity fail - wrong SSID length\n"));
-        return FALSE;
-    }
+	if (Info->SsidLen > MAX_LEN_OF_SSID) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("MlmeStartReqSanity fail - wrong SSID length\n"));
+		return FALSE;
+	}
 
-    *pSsidLen = Info->SsidLen;
-    NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen);
+	*pSsidLen = Info->SsidLen;
+	NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen);
 
-    return TRUE;
+	return TRUE;
 }
 
 /*
@@ -88,211 +86,161 @@
 
     ==========================================================================
  */
-BOOLEAN PeerAssocRspSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *pMsg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pAddr2,
-    OUT USHORT *pCapabilityInfo,
-    OUT USHORT *pStatus,
-    OUT USHORT *pAid,
-    OUT UCHAR SupRate[],
-    OUT UCHAR *pSupRateLen,
-    OUT UCHAR ExtRate[],
-    OUT UCHAR *pExtRateLen,
-    OUT HT_CAPABILITY_IE		*pHtCapability,
-    OUT ADD_HT_INFO_IE		*pAddHtInfo,	// AP might use this additional ht info IE
-    OUT UCHAR			*pHtCapabilityLen,
-    OUT UCHAR			*pAddHtInfoLen,
-    OUT UCHAR			*pNewExtChannelOffset,
-    OUT PEDCA_PARM pEdcaParm,
-    OUT UCHAR *pCkipFlag)
+BOOLEAN PeerAssocRspSanity(struct rt_rtmp_adapter *pAd, void * pMsg, unsigned long MsgLen, u8 *pAddr2, u16 * pCapabilityInfo, u16 * pStatus, u16 * pAid, u8 SupRate[], u8 * pSupRateLen, u8 ExtRate[], u8 * pExtRateLen, struct rt_ht_capability_ie * pHtCapability, struct rt_add_ht_info_ie * pAddHtInfo,	/* AP might use this additional ht info IE */
+			   u8 * pHtCapabilityLen,
+			   u8 * pAddHtInfoLen,
+			   u8 * pNewExtChannelOffset,
+			   struct rt_edca_parm *pEdcaParm, u8 * pCkipFlag)
 {
-    CHAR          IeType, *Ptr;
-    PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
-    PEID_STRUCT   pEid;
-    ULONG         Length = 0;
+	char IeType, *Ptr;
+	struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) pMsg;
+	struct rt_eid * pEid;
+	unsigned long Length = 0;
 
 	*pNewExtChannelOffset = 0xff;
 	*pHtCapabilityLen = 0;
 	*pAddHtInfoLen = 0;
-    COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
-    Ptr = pFrame->Octet;
-    Length += LENGTH_802_11;
+	COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+	Ptr = (char *)pFrame->Octet;
+	Length += LENGTH_802_11;
 
-    NdisMoveMemory(pCapabilityInfo, &pFrame->Octet[0], 2);
-    Length += 2;
-    NdisMoveMemory(pStatus,         &pFrame->Octet[2], 2);
-    Length += 2;
-    *pCkipFlag = 0;
-    *pExtRateLen = 0;
-    pEdcaParm->bValid = FALSE;
+	NdisMoveMemory(pCapabilityInfo, &pFrame->Octet[0], 2);
+	Length += 2;
+	NdisMoveMemory(pStatus, &pFrame->Octet[2], 2);
+	Length += 2;
+	*pCkipFlag = 0;
+	*pExtRateLen = 0;
+	pEdcaParm->bValid = FALSE;
 
-    if (*pStatus != MLME_SUCCESS)
-        return TRUE;
+	if (*pStatus != MLME_SUCCESS)
+		return TRUE;
 
-    NdisMoveMemory(pAid, &pFrame->Octet[4], 2);
-    Length += 2;
+	NdisMoveMemory(pAid, &pFrame->Octet[4], 2);
+	Length += 2;
 
-    // Aid already swaped byte order in RTMPFrameEndianChange() for big endian platform
-    *pAid = (*pAid) & 0x3fff; // AID is low 14-bit
+	/* Aid already swaped byte order in RTMPFrameEndianChange() for big endian platform */
+	*pAid = (*pAid) & 0x3fff;	/* AID is low 14-bit */
 
-    // -- get supported rates from payload and advance the pointer
-    IeType = pFrame->Octet[6];
-    *pSupRateLen = pFrame->Octet[7];
-    if ((IeType != IE_SUPP_RATES) || (*pSupRateLen > MAX_LEN_OF_SUPPORTED_RATES))
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspSanity fail - wrong SupportedRates IE\n"));
-        return FALSE;
-    }
-    else
-        NdisMoveMemory(SupRate, &pFrame->Octet[8], *pSupRateLen);
+	/* -- get supported rates from payload and advance the pointer */
+	IeType = pFrame->Octet[6];
+	*pSupRateLen = pFrame->Octet[7];
+	if ((IeType != IE_SUPP_RATES)
+	    || (*pSupRateLen > MAX_LEN_OF_SUPPORTED_RATES)) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("PeerAssocRspSanity fail - wrong SupportedRates IE\n"));
+		return FALSE;
+	} else
+		NdisMoveMemory(SupRate, &pFrame->Octet[8], *pSupRateLen);
 
-    Length = Length + 2 + *pSupRateLen;
+	Length = Length + 2 + *pSupRateLen;
 
-    // many AP implement proprietary IEs in non-standard order, we'd better
-    // tolerate mis-ordered IEs to get best compatibility
-    pEid = (PEID_STRUCT) &pFrame->Octet[8 + (*pSupRateLen)];
+	/* many AP implement proprietary IEs in non-standard order, we'd better */
+	/* tolerate mis-ordered IEs to get best compatibility */
+	pEid = (struct rt_eid *) & pFrame->Octet[8 + (*pSupRateLen)];
 
-    // get variable fields from payload and advance the pointer
-    while ((Length + 2 + pEid->Len) <= MsgLen)
-    {
-        switch (pEid->Eid)
-        {
-            case IE_EXT_SUPP_RATES:
-                if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
-                {
-                    NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
-                    *pExtRateLen = pEid->Len;
-                }
-                break;
+	/* get variable fields from payload and advance the pointer */
+	while ((Length + 2 + pEid->Len) <= MsgLen) {
+		switch (pEid->Eid) {
+		case IE_EXT_SUPP_RATES:
+			if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) {
+				NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
+				*pExtRateLen = pEid->Len;
+			}
+			break;
 
-             case IE_HT_CAP:
-            case IE_HT_CAP2:
-			if (pEid->Len >= SIZE_HT_CAP_IE)  //Note: allow extension.!!
+		case IE_HT_CAP:
+		case IE_HT_CAP2:
+			if (pEid->Len >= SIZE_HT_CAP_IE)	/*Note: allow extension! */
 			{
-				NdisMoveMemory(pHtCapability, pEid->Octet, SIZE_HT_CAP_IE);
+				NdisMoveMemory(pHtCapability, pEid->Octet,
+					       SIZE_HT_CAP_IE);
 
-				*(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
-				*(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
+				*(u16 *) (&pHtCapability->HtCapInfo) =
+				    cpu2le16(*(u16 *)
+					     (&pHtCapability->HtCapInfo));
+				*(u16 *) (&pHtCapability->ExtHtCapInfo) =
+				    cpu2le16(*(u16 *)
+					     (&pHtCapability->ExtHtCapInfo));
 
 				*pHtCapabilityLen = SIZE_HT_CAP_IE;
-			}
-			else
-			{
-				DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_HT_CAP. \n"));
+			} else {
+				DBGPRINT(RT_DEBUG_WARN,
+					 ("PeerAssocRspSanity - wrong IE_HT_CAP. \n"));
 			}
 
-		break;
-            case IE_ADD_HT:
-            case IE_ADD_HT2:
-			if (pEid->Len >= sizeof(ADD_HT_INFO_IE))
-			{
-				// This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only
-				// copy first sizeof(ADD_HT_INFO_IE)
-				NdisMoveMemory(pAddHtInfo, pEid->Octet, sizeof(ADD_HT_INFO_IE));
+			break;
+		case IE_ADD_HT:
+		case IE_ADD_HT2:
+			if (pEid->Len >= sizeof(struct rt_add_ht_info_ie)) {
+				/* This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only */
+				/* copy first sizeof(struct rt_add_ht_info_ie) */
+				NdisMoveMemory(pAddHtInfo, pEid->Octet,
+					       sizeof(struct rt_add_ht_info_ie));
 
-				*(USHORT *)(&pAddHtInfo->AddHtInfo2) = cpu2le16(*(USHORT *)(&pAddHtInfo->AddHtInfo2));
-				*(USHORT *)(&pAddHtInfo->AddHtInfo3) = cpu2le16(*(USHORT *)(&pAddHtInfo->AddHtInfo3));
+				*(u16 *) (&pAddHtInfo->AddHtInfo2) =
+				    cpu2le16(*(u16 *)
+					     (&pAddHtInfo->AddHtInfo2));
+				*(u16 *) (&pAddHtInfo->AddHtInfo3) =
+				    cpu2le16(*(u16 *)
+					     (&pAddHtInfo->AddHtInfo3));
 
 				*pAddHtInfoLen = SIZE_ADD_HT_INFO_IE;
-			}
-			else
-			{
-				DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_ADD_HT. \n"));
+			} else {
+				DBGPRINT(RT_DEBUG_WARN,
+					 ("PeerAssocRspSanity - wrong IE_ADD_HT. \n"));
 			}
 
-		break;
-            case IE_SECONDARY_CH_OFFSET:
-			if (pEid->Len == 1)
-			{
+			break;
+		case IE_SECONDARY_CH_OFFSET:
+			if (pEid->Len == 1) {
 				*pNewExtChannelOffset = pEid->Octet[0];
+			} else {
+				DBGPRINT(RT_DEBUG_WARN,
+					 ("PeerAssocRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
 			}
-			else
-			{
-				DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
+			break;
+
+		case IE_VENDOR_SPECIFIC:
+			/* handle WME PARAMTER ELEMENT */
+			if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6)
+			    && (pEid->Len == 24)) {
+				u8 *ptr;
+				int i;
+
+				/* parsing EDCA parameters */
+				pEdcaParm->bValid = TRUE;
+				pEdcaParm->bQAck = FALSE;	/* pEid->Octet[0] & 0x10; */
+				pEdcaParm->bQueueRequest = FALSE;	/* pEid->Octet[0] & 0x20; */
+				pEdcaParm->bTxopRequest = FALSE;	/* pEid->Octet[0] & 0x40; */
+				/*pEdcaParm->bMoreDataAck    = FALSE; // pEid->Octet[0] & 0x80; */
+				pEdcaParm->EdcaUpdateCount =
+				    pEid->Octet[6] & 0x0f;
+				pEdcaParm->bAPSDCapable =
+				    (pEid->Octet[6] & 0x80) ? 1 : 0;
+				ptr = (u8 *)& pEid->Octet[8];
+				for (i = 0; i < 4; i++) {
+					u8 aci = (*ptr & 0x60) >> 5;	/* b5~6 is AC INDEX */
+					pEdcaParm->bACM[aci] = (((*ptr) & 0x10) == 0x10);	/* b5 is ACM */
+					pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f;	/* b0~3 is AIFSN */
+					pEdcaParm->Cwmin[aci] = *(ptr + 1) & 0x0f;	/* b0~4 is Cwmin */
+					pEdcaParm->Cwmax[aci] = *(ptr + 1) >> 4;	/* b5~8 is Cwmax */
+					pEdcaParm->Txop[aci] = *(ptr + 2) + 256 * (*(ptr + 3));	/* in unit of 32-us */
+					ptr += 4;	/* point to next AC */
+				}
 			}
-		break;
-            case IE_AIRONET_CKIP:
-                // 0. Check Aironet IE length, it must be larger or equal to 28
-                //    Cisco's AP VxWork version(will not be supported) used this IE length as 28
-                //    Cisco's AP IOS version used this IE length as 30
-                if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2))
-                break;
+			break;
+		default:
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("PeerAssocRspSanity - ignore unrecognized EID = %d\n",
+				  pEid->Eid));
+			break;
+		}
 
-                // 1. Copy CKIP flag byte to buffer for process
-                *pCkipFlag = *(pEid->Octet + 8);
-                break;
+		Length = Length + 2 + pEid->Len;
+		pEid = (struct rt_eid *) ((u8 *) pEid + 2 + pEid->Len);
+	}
 
-            case IE_AIRONET_IPADDRESS:
-                if (pEid->Len != 0x0A)
-                break;
-
-                // Get Cisco Aironet IP information
-                if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1)
-                    NdisMoveMemory(pAd->StaCfg.AironetIPAddress, pEid->Octet + 4, 4);
-                break;
-
-            // CCX2, WMM use the same IE value
-            // case IE_CCX_V2:
-            case IE_VENDOR_SPECIFIC:
-                // handle WME PARAMTER ELEMENT
-                if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) && (pEid->Len == 24))
-                {
-                    PUCHAR ptr;
-                    int i;
-
-                    // parsing EDCA parameters
-                    pEdcaParm->bValid          = TRUE;
-                    pEdcaParm->bQAck           = FALSE; // pEid->Octet[0] & 0x10;
-                    pEdcaParm->bQueueRequest   = FALSE; // pEid->Octet[0] & 0x20;
-                    pEdcaParm->bTxopRequest    = FALSE; // pEid->Octet[0] & 0x40;
-                    //pEdcaParm->bMoreDataAck    = FALSE; // pEid->Octet[0] & 0x80;
-                    pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
-                    pEdcaParm->bAPSDCapable    = (pEid->Octet[6] & 0x80) ? 1 : 0;
-                    ptr = &pEid->Octet[8];
-                    for (i=0; i<4; i++)
-                    {
-                        UCHAR aci = (*ptr & 0x60) >> 5; // b5~6 is AC INDEX
-                        pEdcaParm->bACM[aci]  = (((*ptr) & 0x10) == 0x10);   // b5 is ACM
-                        pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f;               // b0~3 is AIFSN
-                        pEdcaParm->Cwmin[aci] = *(ptr+1) & 0x0f;             // b0~4 is Cwmin
-                        pEdcaParm->Cwmax[aci] = *(ptr+1) >> 4;               // b5~8 is Cwmax
-                        pEdcaParm->Txop[aci]  = *(ptr+2) + 256 * (*(ptr+3)); // in unit of 32-us
-                        ptr += 4; // point to next AC
-                    }
-                }
-
-                // handle CCX IE
-                else
-                {
-                    // 0. Check the size and CCX admin control
-                    if (pAd->StaCfg.CCXControl.field.Enable == 0)
-                        break;
-                    if (pEid->Len != 5)
-                        break;
-
-                    // Turn CCX2 if matched
-                    if (NdisEqualMemory(pEid->Octet, Ccx2IeInfo, 5) == 1)
-                        pAd->StaCfg.CCXEnable = TRUE;
-                    break;
-                }
-                break;
-
-            default:
-                DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspSanity - ignore unrecognized EID = %d\n", pEid->Eid));
-                break;
-        }
-
-        Length = Length + 2 + pEid->Len;
-        pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
-    }
-
-    // Force CCX2 enable to TRUE for those AP didn't replay CCX v2 IE, we still force it to be on
-    if (pAd->StaCfg.CCXControl.field.Enable == 1)
-        pAd->StaCfg.CCXEnable = TRUE;
-
-    return TRUE;
+	return TRUE;
 }
 
 /*
@@ -306,47 +254,46 @@
 
     ==========================================================================
  */
-BOOLEAN PeerProbeReqSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pAddr2,
-    OUT CHAR Ssid[],
-    OUT UCHAR *pSsidLen)
+BOOLEAN PeerProbeReqSanity(struct rt_rtmp_adapter *pAd,
+			   void * Msg,
+			   unsigned long MsgLen,
+			   u8 *pAddr2,
+			   char Ssid[], u8 * pSsidLen)
 {
-    UCHAR         Idx;
-    UCHAR	      RateLen;
-    CHAR          IeType;
-    PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
+	u8 Idx;
+	u8 RateLen;
+	char IeType;
+	struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg;
 
-    COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+	COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
 
-    if ((pFrame->Octet[0] != IE_SSID) || (pFrame->Octet[1] > MAX_LEN_OF_SSID))
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("PeerProbeReqSanity fail - wrong SSID IE(Type=%d,Len=%d)\n",pFrame->Octet[0],pFrame->Octet[1]));
-        return FALSE;
-    }
+	if ((pFrame->Octet[0] != IE_SSID)
+	    || (pFrame->Octet[1] > MAX_LEN_OF_SSID)) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("PeerProbeReqSanity fail - wrong SSID IE(Type=%d,Len=%d)\n",
+			  pFrame->Octet[0], pFrame->Octet[1]));
+		return FALSE;
+	}
 
-    *pSsidLen = pFrame->Octet[1];
-    NdisMoveMemory(Ssid, &pFrame->Octet[2], *pSsidLen);
+	*pSsidLen = pFrame->Octet[1];
+	NdisMoveMemory(Ssid, &pFrame->Octet[2], *pSsidLen);
 
-    Idx = *pSsidLen + 2;
+	Idx = *pSsidLen + 2;
 
-    // -- get supported rates from payload and advance the pointer
-    IeType = pFrame->Octet[Idx];
-    RateLen = pFrame->Octet[Idx + 1];
-    if (IeType != IE_SUPP_RATES)
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("PeerProbeReqSanity fail - wrong SupportRates IE(Type=%d,Len=%d)\n",pFrame->Octet[Idx],pFrame->Octet[Idx+1]));
-        return FALSE;
-    }
-    else
-    {
-        if ((pAd->CommonCfg.PhyMode == PHY_11G) && (RateLen < 8))
-            return (FALSE);
-    }
+	/* -- get supported rates from payload and advance the pointer */
+	IeType = pFrame->Octet[Idx];
+	RateLen = pFrame->Octet[Idx + 1];
+	if (IeType != IE_SUPP_RATES) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("PeerProbeReqSanity fail - wrong SupportRates IE(Type=%d,Len=%d)\n",
+			  pFrame->Octet[Idx], pFrame->Octet[Idx + 1]));
+		return FALSE;
+	} else {
+		if ((pAd->CommonCfg.PhyMode == PHY_11G) && (RateLen < 8))
+			return (FALSE);
+	}
 
-    return TRUE;
+	return TRUE;
 }
 
 /*
@@ -357,62 +304,58 @@
 
     ==========================================================================
  */
-BOOLEAN GetTimBit(
-    IN CHAR *Ptr,
-    IN USHORT Aid,
-    OUT UCHAR *TimLen,
-    OUT UCHAR *BcastFlag,
-    OUT UCHAR *DtimCount,
-    OUT UCHAR *DtimPeriod,
-    OUT UCHAR *MessageToMe)
+BOOLEAN GetTimBit(char * Ptr,
+		  u16 Aid,
+		  u8 * TimLen,
+		  u8 * BcastFlag,
+		  u8 * DtimCount,
+		  u8 * DtimPeriod, u8 * MessageToMe)
 {
-    UCHAR          BitCntl, N1, N2, MyByte, MyBit;
-    CHAR          *IdxPtr;
+	u8 BitCntl, N1, N2, MyByte, MyBit;
+	char *IdxPtr;
 
-    IdxPtr = Ptr;
+	IdxPtr = Ptr;
 
-    IdxPtr ++;
-    *TimLen = *IdxPtr;
+	IdxPtr++;
+	*TimLen = *IdxPtr;
 
-    // get DTIM Count from TIM element
-    IdxPtr ++;
-    *DtimCount = *IdxPtr;
+	/* get DTIM Count from TIM element */
+	IdxPtr++;
+	*DtimCount = *IdxPtr;
 
-    // get DTIM Period from TIM element
-    IdxPtr++;
-    *DtimPeriod = *IdxPtr;
+	/* get DTIM Period from TIM element */
+	IdxPtr++;
+	*DtimPeriod = *IdxPtr;
 
-    // get Bitmap Control from TIM element
-    IdxPtr++;
-    BitCntl = *IdxPtr;
+	/* get Bitmap Control from TIM element */
+	IdxPtr++;
+	BitCntl = *IdxPtr;
 
-    if ((*DtimCount == 0) && (BitCntl & 0x01))
-        *BcastFlag = TRUE;
-    else
-        *BcastFlag = FALSE;
+	if ((*DtimCount == 0) && (BitCntl & 0x01))
+		*BcastFlag = TRUE;
+	else
+		*BcastFlag = FALSE;
 
-    // Parse Partial Virtual Bitmap from TIM element
-    N1 = BitCntl & 0xfe;    // N1 is the first bitmap byte#
-    N2 = *TimLen - 4 + N1;  // N2 is the last bitmap byte#
+	/* Parse Partial Virtual Bitmap from TIM element */
+	N1 = BitCntl & 0xfe;	/* N1 is the first bitmap byte# */
+	N2 = *TimLen - 4 + N1;	/* N2 is the last bitmap byte# */
 
-    if ((Aid < (N1 << 3)) || (Aid >= ((N2 + 1) << 3)))
-        *MessageToMe = FALSE;
-    else
-    {
-        MyByte = (Aid >> 3) - N1;                       // my byte position in the bitmap byte-stream
-        MyBit = Aid % 16 - ((MyByte & 0x01)? 8:0);
+	if ((Aid < (N1 << 3)) || (Aid >= ((N2 + 1) << 3)))
+		*MessageToMe = FALSE;
+	else {
+		MyByte = (Aid >> 3) - N1;	/* my byte position in the bitmap byte-stream */
+		MyBit = Aid % 16 - ((MyByte & 0x01) ? 8 : 0);
 
-        IdxPtr += (MyByte + 1);
+		IdxPtr += (MyByte + 1);
 
-        //if (*IdxPtr)
-        //    DBGPRINT(RT_DEBUG_WARN, ("TIM bitmap = 0x%02x\n", *IdxPtr));
+		/*if (*IdxPtr) */
+		/*    DBGPRINT(RT_DEBUG_WARN, ("TIM bitmap = 0x%02x\n", *IdxPtr)); */
 
-        if (*IdxPtr & (0x01 << MyBit))
-            *MessageToMe = TRUE;
-        else
-            *MessageToMe = FALSE;
-    }
+		if (*IdxPtr & (0x01 << MyBit))
+			*MessageToMe = TRUE;
+		else
+			*MessageToMe = FALSE;
+	}
 
-    return TRUE;
+	return TRUE;
 }
-
diff --git a/drivers/staging/rt2860/sta/sync.c b/drivers/staging/rt2860/sta/sync.c
index a6e4362..cbe90a6 100644
--- a/drivers/staging/rt2860/sta/sync.c
+++ b/drivers/staging/rt2860/sta/sync.c
@@ -37,45 +37,7 @@
 */
 #include "../rt_config.h"
 
-#ifdef RT2860
-#define AC0_DEF_TXOP		0
-#define AC1_DEF_TXOP		0
-#define AC2_DEF_TXOP		94
-#define AC3_DEF_TXOP		47
-
-VOID	AdhocTurnOnQos(
-	IN  PRTMP_ADAPTER pAd)
-{
-	// Turn on QOs if use HT rate.
-	if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
-	{
-		pAd->CommonCfg.APEdcaParm.bValid = TRUE;
-		pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
-		pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
-		pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
-		pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
-
-		pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
-		pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
-		pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
-		pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
-
-		pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10;
-		pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6;
-		pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
-		pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
-
-		pAd->CommonCfg.APEdcaParm.Txop[0]  = 0;
-		pAd->CommonCfg.APEdcaParm.Txop[1]  = 0;
-		pAd->CommonCfg.APEdcaParm.Txop[2]  = AC2_DEF_TXOP;
-		pAd->CommonCfg.APEdcaParm.Txop[3]  = AC3_DEF_TXOP;
-	}
-	AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
-}
-#endif /* RT2860 */
-#ifdef RT2870
-#define ADHOC_ENTRY_BEACON_LOST_TIME	(2*OS_HZ)	// 2 sec
-#endif
+#define ADHOC_ENTRY_BEACON_LOST_TIME	(2*OS_HZ)	/* 2 sec */
 
 /*
 	==========================================================================
@@ -88,38 +50,56 @@
 
 	==========================================================================
  */
-VOID SyncStateMachineInit(
-	IN PRTMP_ADAPTER pAd,
-	IN STATE_MACHINE *Sm,
-	OUT STATE_MACHINE_FUNC Trans[])
+void SyncStateMachineInit(struct rt_rtmp_adapter *pAd,
+			  struct rt_state_machine *Sm, OUT STATE_MACHINE_FUNC Trans[])
 {
-	StateMachineInit(Sm, Trans, MAX_SYNC_STATE, MAX_SYNC_MSG, (STATE_MACHINE_FUNC)Drop, SYNC_IDLE, SYNC_MACHINE_BASE);
+	StateMachineInit(Sm, Trans, MAX_SYNC_STATE, MAX_SYNC_MSG,
+			 (STATE_MACHINE_FUNC) Drop, SYNC_IDLE,
+			 SYNC_MACHINE_BASE);
 
-	// column 1
-	StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)MlmeScanReqAction);
-	StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)MlmeJoinReqAction);
-	StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)MlmeStartReqAction);
-	StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeacon);
-	StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_PROBE_REQ, (STATE_MACHINE_FUNC)PeerProbeReqAction);
+	/* column 1 */
+	StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_SCAN_REQ,
+			      (STATE_MACHINE_FUNC) MlmeScanReqAction);
+	StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_JOIN_REQ,
+			      (STATE_MACHINE_FUNC) MlmeJoinReqAction);
+	StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_START_REQ,
+			      (STATE_MACHINE_FUNC) MlmeStartReqAction);
+	StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_BEACON,
+			      (STATE_MACHINE_FUNC) PeerBeacon);
+	StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_PROBE_REQ,
+			      (STATE_MACHINE_FUNC) PeerProbeReqAction);
 
-	//column 2
-	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan);
-	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin);
-	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart);
-	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtJoinAction);
-	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_BEACON_TIMEOUT, (STATE_MACHINE_FUNC)BeaconTimeoutAtJoinAction);
+	/*column 2 */
+	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_SCAN_REQ,
+			      (STATE_MACHINE_FUNC) InvalidStateWhenScan);
+	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_JOIN_REQ,
+			      (STATE_MACHINE_FUNC) InvalidStateWhenJoin);
+	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_START_REQ,
+			      (STATE_MACHINE_FUNC) InvalidStateWhenStart);
+	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_PEER_BEACON,
+			      (STATE_MACHINE_FUNC) PeerBeaconAtJoinAction);
+	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_BEACON_TIMEOUT,
+			      (STATE_MACHINE_FUNC) BeaconTimeoutAtJoinAction);
 
-	// column 3
-	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan);
-	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin);
-	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart);
-	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction);
-	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_PROBE_RSP, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction);
-	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_SCAN_TIMEOUT, (STATE_MACHINE_FUNC)ScanTimeoutAction);
+	/* column 3 */
+	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_SCAN_REQ,
+			      (STATE_MACHINE_FUNC) InvalidStateWhenScan);
+	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_JOIN_REQ,
+			      (STATE_MACHINE_FUNC) InvalidStateWhenJoin);
+	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_START_REQ,
+			      (STATE_MACHINE_FUNC) InvalidStateWhenStart);
+	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_BEACON,
+			      (STATE_MACHINE_FUNC) PeerBeaconAtScanAction);
+	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_PROBE_RSP,
+			      (STATE_MACHINE_FUNC) PeerBeaconAtScanAction);
+	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_SCAN_TIMEOUT,
+			      (STATE_MACHINE_FUNC) ScanTimeoutAction);
 
-	// timer init
-	RTMPInitTimer(pAd, &pAd->MlmeAux.BeaconTimer, GET_TIMER_FUNCTION(BeaconTimeout), pAd, FALSE);
-	RTMPInitTimer(pAd, &pAd->MlmeAux.ScanTimer, GET_TIMER_FUNCTION(ScanTimeout), pAd, FALSE);
+	/* timer init */
+	RTMPInitTimer(pAd, &pAd->MlmeAux.BeaconTimer,
+		      GET_TIMER_FUNCTION(BeaconTimeout), pAd, FALSE);
+	RTMPInitTimer(pAd, &pAd->MlmeAux.ScanTimer,
+		      GET_TIMER_FUNCTION(ScanTimeout), pAd, FALSE);
 }
 
 /*
@@ -131,36 +111,35 @@
 
 	==========================================================================
  */
-VOID BeaconTimeout(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3)
+void BeaconTimeout(void *SystemSpecific1,
+		   void *FunctionContext,
+		   void *SystemSpecific2, void *SystemSpecific3)
 {
-	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
 
-	DBGPRINT(RT_DEBUG_TRACE,("SYNC - BeaconTimeout\n"));
+	DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeout\n"));
 
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
+	/* Do nothing if the driver is starting halt state. */
+	/* This might happen when timer already been fired before cancel timer with mlmehalt */
 	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
 		return;
 
 	if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
-		)
-	{
-		UCHAR        BBPValue = 0;
+	    ) {
+		u8 BBPValue = 0;
 		AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
 		AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
 		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
 		BBPValue &= (~0x18);
 		BBPValue |= 0x10;
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-		DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",
+			  pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
 	}
 
 	MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_BEACON_TIMEOUT, 0, NULL);
-	RT28XX_MLME_HANDLER(pAd);
+	RTMP_MLME_HANDLER(pAd);
 }
 
 /*
@@ -172,32 +151,28 @@
 
 	==========================================================================
  */
-VOID ScanTimeout(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3)
+void ScanTimeout(void *SystemSpecific1,
+		 void *FunctionContext,
+		 void *SystemSpecific2, void *SystemSpecific3)
 {
-	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
 
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
+	/* Do nothing if the driver is starting halt state. */
+	/* This might happen when timer already been fired before cancel timer with mlmehalt */
 	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
 		return;
 
-	if (MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_SCAN_TIMEOUT, 0, NULL))
-	{
-		RT28XX_MLME_HANDLER(pAd);
-	}
-	else
-	{
-		// To prevent SyncMachine.CurrState is SCAN_LISTEN forever.
+	if (MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_SCAN_TIMEOUT, 0, NULL)) {
+		RTMP_MLME_HANDLER(pAd);
+	} else {
+		/* To prevent SyncMachine.CurrState is SCAN_LISTEN forever. */
 		pAd->MlmeAux.Channel = 0;
 		ScanNextChannel(pAd);
-		if (pAd->CommonCfg.bWirelessEvent)
-		{
-			RTMPSendWirelessEvent(pAd, IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+		if (pAd->CommonCfg.bWirelessEvent) {
+			RTMPSendWirelessEvent(pAd,
+					      IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG,
+					      pAd->MacTab.Content[BSSID_WCID].
+					      Addr, BSS0, 0);
 		}
 	}
 }
@@ -208,81 +183,78 @@
 		MLME SCAN req state machine procedure
 	==========================================================================
  */
-VOID MlmeScanReqAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void MlmeScanReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	UCHAR          Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType, BBPValue = 0;
-	BOOLEAN        TimerCancelled;
-	ULONG		   Now;
-	USHORT         Status;
-	PHEADER_802_11 pHdr80211;
-	PUCHAR         pOutBuffer = NULL;
-	NDIS_STATUS    NStatus;
+	u8 Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType, BBPValue = 0;
+	BOOLEAN TimerCancelled;
+	unsigned long Now;
+	u16 Status;
+	struct rt_header_802_11 * pHdr80211;
+	u8 *pOutBuffer = NULL;
+	int NStatus;
 
-	// Check the total scan tries for one single OID command
-	// If this is the CCX 2.0 Case, skip that!
-	if ( !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeScanReqAction before Startup\n"));
+	/* Check the total scan tries for one single OID command */
+	/* If this is the CCX 2.0 Case, skip that! */
+	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("SYNC - MlmeScanReqAction before Startup\n"));
 		return;
 	}
-
-	// Increase the scan retry counters.
+	/* Increase the scan retry counters. */
 	pAd->StaCfg.ScanCnt++;
 
-#ifdef RT2860
-    if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
-        (IDLE_ON(pAd)) &&
-		(pAd->StaCfg.bRadio == TRUE) &&
-		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
-	{
-		RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
+#ifdef RTMP_MAC_PCI
+	if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) &&
+	    (IDLE_ON(pAd)) &&
+	    (pAd->StaCfg.bRadio == TRUE) &&
+	    (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) {
+		if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE) {
+			AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00,
+					     0x02);
+			AsicCheckCommanOk(pAd, PowerWakeCID);
+			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("PSM - Issue Wake up command \n"));
+		} else {
+			RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
+		}
 	}
-#endif
+#endif /* RTMP_MAC_PCI // */
 
-	// first check the parameter sanity
+	/* first check the parameter sanity */
 	if (MlmeScanReqSanity(pAd,
-						  Elem->Msg,
-						  Elem->MsgLen,
-						  &BssType,
-						  Ssid,
-						  &SsidLen,
-						  &ScanType))
-	{
+			      Elem->Msg,
+			      Elem->MsgLen,
+			      &BssType, (char *)Ssid, &SsidLen, &ScanType)) {
 
-		// Check for channel load and noise hist request
-		// Suspend MSDU only at scan request, not the last two mentioned
-		if ((ScanType == SCAN_CISCO_NOISE) || (ScanType == SCAN_CISCO_CHANNEL_LOAD))
-		{
-			if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
-				RTMPSuspendMsduTransmission(pAd);			// Suspend MSDU transmission here
-		}
-		else
-		{
-			// Suspend MSDU transmission here
-			RTMPSuspendMsduTransmission(pAd);
-		}
+		/* Check for channel load and noise hist request */
+		/* Suspend MSDU only at scan request, not the last two mentioned */
+		/* Suspend MSDU transmission here */
+		RTMPSuspendMsduTransmission(pAd);
 
-		//
-		// To prevent data lost.
-		// Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
-		// And should send an NULL data with turned PSM bit off to AP, when scan progress done
-		//
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)))
-		{
-			NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);
-			if (NStatus	== NDIS_STATUS_SUCCESS)
-			{
-				pHdr80211 = (PHEADER_802_11) pOutBuffer;
-				MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
+		/* */
+		/* To prevent data lost. */
+		/* Send an NULL data with turned PSM bit on to current associated AP before SCAN progress. */
+		/* And should send an NULL data with turned PSM bit off to AP, when scan progress done */
+		/* */
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
+		    && (INFRA_ON(pAd))) {
+			NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer);
+			if (NStatus == NDIS_STATUS_SUCCESS) {
+				pHdr80211 = (struct rt_header_802_11 *) pOutBuffer;
+				MgtMacHeaderInit(pAd, pHdr80211,
+						 SUBTYPE_NULL_FUNC, 1,
+						 pAd->CommonCfg.Bssid,
+						 pAd->CommonCfg.Bssid);
 				pHdr80211->Duration = 0;
 				pHdr80211->FC.Type = BTYPE_DATA;
 				pHdr80211->FC.PwrMgmt = PWR_SAVE;
 
-				// Send using priority queue
-				MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
-				DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame for off channel RM\n"));
+				/* Send using priority queue */
+				MiniportMMRequest(pAd, 0, pOutBuffer,
+						  sizeof(struct rt_header_802_11));
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("MlmeScanReqAction -- Send PSM Data frame for off channel RM\n"));
 				MlmeFreeMemory(pAd, pOutBuffer);
 				RTMPusecDelay(5000);
 			}
@@ -290,38 +262,32 @@
 
 		NdisGetSystemUpTime(&Now);
 		pAd->StaCfg.LastScanTime = Now;
-		// reset all the timers
+		/* reset all the timers */
 		RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
 		RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
 
-		// record desired BSS parameters
+		/* record desired BSS parameters */
 		pAd->MlmeAux.BssType = BssType;
 		pAd->MlmeAux.ScanType = ScanType;
 		pAd->MlmeAux.SsidLen = SsidLen;
-        NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
+		NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
 		NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
 
-		// start from the first channel
+		/* start from the first channel */
 		pAd->MlmeAux.Channel = FirstChannel(pAd);
 
-		// Change the scan channel when dealing with CCX beacon report
-		if ((ScanType == SCAN_CISCO_PASSIVE) || (ScanType == SCAN_CISCO_ACTIVE) ||
-			(ScanType == SCAN_CISCO_CHANNEL_LOAD) || (ScanType == SCAN_CISCO_NOISE))
-			pAd->MlmeAux.Channel = pAd->StaCfg.CCXScanChannel;
-
-		// Let BBP register at 20MHz to do scan
+		/* Let BBP register at 20MHz to do scan */
 		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
 		BBPValue &= (~0x18);
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
 		DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
 		ScanNextChannel(pAd);
-	}
-	else
-	{
+	} else {
 		DBGPRINT_ERR(("SYNC - MlmeScanReqAction() sanity check fail\n"));
 		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
 		Status = MLME_INVALID_FORMAT;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
+		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2,
+			    &Status);
 	}
 }
 
@@ -331,49 +297,47 @@
 		MLME JOIN req state machine procedure
 	==========================================================================
  */
-VOID MlmeJoinReqAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void MlmeJoinReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	UCHAR        BBPValue = 0;
-	BSS_ENTRY    *pBss;
-	BOOLEAN       TimerCancelled;
-	HEADER_802_11 Hdr80211;
-	NDIS_STATUS   NStatus;
-	ULONG         FrameLen = 0;
-	PUCHAR        pOutBuffer = NULL;
-	PUCHAR        pSupRate = NULL;
-	UCHAR         SupRateLen;
-	PUCHAR        pExtRate = NULL;
-	UCHAR         ExtRateLen;
-	UCHAR         ASupRate[] = {0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C};
-	UCHAR         ASupRateLen = sizeof(ASupRate)/sizeof(UCHAR);
-	MLME_JOIN_REQ_STRUCT *pInfo = (MLME_JOIN_REQ_STRUCT *)(Elem->Msg);
+	u8 BBPValue = 0;
+	struct rt_bss_entry *pBss;
+	BOOLEAN TimerCancelled;
+	struct rt_header_802_11 Hdr80211;
+	int NStatus;
+	unsigned long FrameLen = 0;
+	u8 *pOutBuffer = NULL;
+	u8 *pSupRate = NULL;
+	u8 SupRateLen;
+	u8 *pExtRate = NULL;
+	u8 ExtRateLen;
+	u8 ASupRate[] = { 0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C };
+	u8 ASupRateLen = sizeof(ASupRate) / sizeof(u8);
+	struct rt_mlme_join_req *pInfo = (struct rt_mlme_join_req *)(Elem->Msg);
 
-	DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx));
 
-#ifdef RT2860
-    if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
-        (IDLE_ON(pAd)) &&
-		(pAd->StaCfg.bRadio == TRUE) &&
-		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
-	{
+#ifdef RTMP_MAC_PCI
+	if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) &&
+	    (IDLE_ON(pAd)) &&
+	    (pAd->StaCfg.bRadio == TRUE) &&
+	    (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) {
 		RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
 	}
-#endif
+#endif /* RTMP_MAC_PCI // */
 
-	// reset all the timers
+	/* reset all the timers */
 	RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
 	RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
 
 	pBss = &pAd->MlmeAux.SsidBssTab.BssEntry[pInfo->BssIdx];
 
-	// record the desired SSID & BSSID we're waiting for
+	/* record the desired SSID & BSSID we're waiting for */
 	COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pBss->Bssid);
 
-	// If AP's SSID is not hidden, it is OK for updating ssid to MlmeAux again.
-	if (pBss->Hidden == 0)
-	{
+	/* If AP's SSID is not hidden, it is OK for updating ssid to MlmeAux again. */
+	if (pBss->Hidden == 0) {
+		RTMPZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
 		NdisMoveMemory(pAd->MlmeAux.Ssid, pBss->Ssid, pBss->SsidLen);
 		pAd->MlmeAux.SsidLen = pBss->SsidLen;
 	}
@@ -382,88 +346,87 @@
 	pAd->MlmeAux.Channel = pBss->Channel;
 	pAd->MlmeAux.CentralChannel = pBss->CentralChannel;
 
-	// Let BBP register at 20MHz to do scan
+	/* Let BBP register at 20MHz to do scan */
 	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
 	BBPValue &= (~0x18);
 	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+
 	DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
 
-	// switch channel and waiting for beacon timer
+	/* switch channel and waiting for beacon timer */
 	AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
 	AsicLockChannel(pAd, pAd->MlmeAux.Channel);
 	RTMPSetTimer(&pAd->MlmeAux.BeaconTimer, JOIN_TIMEOUT);
 
-    do
-	{
+	do {
 		if (((pAd->CommonCfg.bIEEE80211H == 1) &&
-            (pAd->MlmeAux.Channel > 14) &&
-             RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
-            )
-		{
-			//
-			// We can't send any Probe request frame to meet 802.11h.
-			//
+		     (pAd->MlmeAux.Channel > 14) &&
+		     RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
+		    ) {
+			/* */
+			/* We can't send any Probe request frame to meet 802.11h. */
+			/* */
 			if (pBss->Hidden == 0)
 				break;
 		}
-
-		//
-		// send probe request
-		//
+		/* */
+		/* send probe request */
+		/* */
 		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
-		if (NStatus == NDIS_STATUS_SUCCESS)
-		{
-			if (pAd->MlmeAux.Channel <= 14)
-			{
+		if (NStatus == NDIS_STATUS_SUCCESS) {
+			if (pAd->MlmeAux.Channel <= 14) {
 				pSupRate = pAd->CommonCfg.SupRate;
 				SupRateLen = pAd->CommonCfg.SupRateLen;
 				pExtRate = pAd->CommonCfg.ExtRate;
 				ExtRateLen = pAd->CommonCfg.ExtRateLen;
-			}
-			else
-			{
-				//
-				// Overwrite Support Rate, CCK rate are not allowed
-				//
+			} else {
+				/* */
+				/* Overwrite Support Rate, CCK rate are not allowed */
+				/* */
 				pSupRate = ASupRate;
 				SupRateLen = ASupRateLen;
 				ExtRateLen = 0;
 			}
 
 			if (pAd->MlmeAux.BssType == BSS_INFRA)
-				MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, pAd->MlmeAux.Bssid, pAd->MlmeAux.Bssid);
+				MgtMacHeaderInit(pAd, &Hdr80211,
+						 SUBTYPE_PROBE_REQ, 0,
+						 pAd->MlmeAux.Bssid,
+						 pAd->MlmeAux.Bssid);
 			else
-				MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
+				MgtMacHeaderInit(pAd, &Hdr80211,
+						 SUBTYPE_PROBE_REQ, 0,
+						 BROADCAST_ADDR,
+						 BROADCAST_ADDR);
 
-			MakeOutgoingFrame(pOutBuffer,               &FrameLen,
-							  sizeof(HEADER_802_11),    &Hdr80211,
-							  1,                        &SsidIe,
-							  1,                        &pAd->MlmeAux.SsidLen,
-							  pAd->MlmeAux.SsidLen,	    pAd->MlmeAux.Ssid,
-							  1,                        &SupRateIe,
-							  1,                        &SupRateLen,
-							  SupRateLen,               pSupRate,
-							  END_OF_ARGS);
+			MakeOutgoingFrame(pOutBuffer, &FrameLen,
+					  sizeof(struct rt_header_802_11), &Hdr80211,
+					  1, &SsidIe,
+					  1, &pAd->MlmeAux.SsidLen,
+					  pAd->MlmeAux.SsidLen,
+					  pAd->MlmeAux.Ssid, 1, &SupRateIe, 1,
+					  &SupRateLen, SupRateLen, pSupRate,
+					  END_OF_ARGS);
 
-			if (ExtRateLen)
-			{
-				ULONG Tmp;
-				MakeOutgoingFrame(pOutBuffer + FrameLen,            &Tmp,
-								  1,                                &ExtRateIe,
-								  1,                                &ExtRateLen,
-								  ExtRateLen,                       pExtRate,
-								  END_OF_ARGS);
+			if (ExtRateLen) {
+				unsigned long Tmp;
+				MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
+						  1, &ExtRateIe,
+						  1, &ExtRateLen,
+						  ExtRateLen, pExtRate,
+						  END_OF_ARGS);
 				FrameLen += Tmp;
 			}
 
-
 			MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
 			MlmeFreeMemory(pAd, pOutBuffer);
 		}
-    } while (FALSE);
+	} while (FALSE);
 
-	DBGPRINT(RT_DEBUG_TRACE, ("SYNC - Switch to ch %d, Wait BEACON from %02x:%02x:%02x:%02x:%02x:%02x\n",
-		pBss->Channel, pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2], pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("SYNC - Switch to ch %d, Wait BEACON from %02x:%02x:%02x:%02x:%02x:%02x\n",
+		  pBss->Channel, pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2],
+		  pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
 
 	pAd->Mlme.SyncMachine.CurrState = JOIN_WAIT_BEACON;
 }
@@ -474,95 +437,110 @@
 		MLME START Request state machine procedure, starting an IBSS
 	==========================================================================
  */
-VOID MlmeStartReqAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void MlmeStartReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	UCHAR         Ssid[MAX_LEN_OF_SSID], SsidLen;
-	BOOLEAN       TimerCancelled;
+	u8 Ssid[MAX_LEN_OF_SSID], SsidLen;
+	BOOLEAN TimerCancelled;
 
-	// New for WPA security suites
-	UCHAR						VarIE[MAX_VIE_LEN]; 	// Total VIE length = MAX_VIE_LEN - -5
-	NDIS_802_11_VARIABLE_IEs	*pVIE = NULL;
-	LARGE_INTEGER				TimeStamp;
+	/* New for WPA security suites */
+	u8 VarIE[MAX_VIE_LEN];	/* Total VIE length = MAX_VIE_LEN - -5 */
+	struct rt_ndis_802_11_variable_ies *pVIE = NULL;
+	LARGE_INTEGER TimeStamp;
 	BOOLEAN Privacy;
-	USHORT Status;
+	u16 Status;
 
-	// Init Variable IE structure
-	pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
+	/* Init Variable IE structure */
+	pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE;
 	pVIE->Length = 0;
-	TimeStamp.u.LowPart  = 0;
+	TimeStamp.u.LowPart = 0;
 	TimeStamp.u.HighPart = 0;
 
-	if (MlmeStartReqSanity(pAd, Elem->Msg, Elem->MsgLen, Ssid, &SsidLen))
-	{
-		// reset all the timers
+	if (MlmeStartReqSanity
+	    (pAd, Elem->Msg, Elem->MsgLen, (char *)Ssid, &SsidLen)) {
+		/* reset all the timers */
 		RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
 		RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
 
-		//
-		// Start a new IBSS. All IBSS parameters are decided now....
-		//
-		DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqAction - Start a new IBSS. All IBSS parameters are decided now.... \n"));
-		pAd->MlmeAux.BssType           = BSS_ADHOC;
+		/* */
+		/* Start a new IBSS. All IBSS parameters are decided now.... */
+		/* */
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("MlmeStartReqAction - Start a new IBSS. All IBSS parameters are decided now.... \n"));
+		pAd->MlmeAux.BssType = BSS_ADHOC;
 		NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
-		pAd->MlmeAux.SsidLen           = SsidLen;
+		pAd->MlmeAux.SsidLen = SsidLen;
 
-		// generate a radom number as BSSID
+		/* generate a radom number as BSSID */
 		MacAddrRandomBssid(pAd, pAd->MlmeAux.Bssid);
-		DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqAction - generate a radom number as BSSID \n"));
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("MlmeStartReqAction - generate a radom number as BSSID \n"));
 
-		Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
-				  (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
-				  (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
-		pAd->MlmeAux.CapabilityInfo    = CAP_GENERATE(0,1,Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 1, 0);
-		pAd->MlmeAux.BeaconPeriod      = pAd->CommonCfg.BeaconPeriod;
-		pAd->MlmeAux.AtimWin           = pAd->StaCfg.AtimWin;
-		pAd->MlmeAux.Channel           = pAd->CommonCfg.Channel;
+		Privacy =
+		    (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled)
+		    || (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
+		    || (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
+		pAd->MlmeAux.CapabilityInfo =
+		    CAP_GENERATE(0, 1, Privacy,
+				 (pAd->CommonCfg.TxPreamble ==
+				  Rt802_11PreambleShort), 1, 0);
+		pAd->MlmeAux.BeaconPeriod = pAd->CommonCfg.BeaconPeriod;
+		pAd->MlmeAux.AtimWin = pAd->StaCfg.AtimWin;
+		pAd->MlmeAux.Channel = pAd->CommonCfg.Channel;
 
-		pAd->CommonCfg.CentralChannel  = pAd->CommonCfg.Channel;
-		pAd->MlmeAux.CentralChannel    = pAd->CommonCfg.CentralChannel;
+		pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
+		pAd->MlmeAux.CentralChannel = pAd->CommonCfg.CentralChannel;
 
-		pAd->MlmeAux.SupRateLen= pAd->CommonCfg.SupRateLen;
-		NdisMoveMemory(pAd->MlmeAux.SupRate, pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
-		RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
+		pAd->MlmeAux.SupRateLen = pAd->CommonCfg.SupRateLen;
+		NdisMoveMemory(pAd->MlmeAux.SupRate, pAd->CommonCfg.SupRate,
+			       MAX_LEN_OF_SUPPORTED_RATES);
+		RTMPCheckRates(pAd, pAd->MlmeAux.SupRate,
+			       &pAd->MlmeAux.SupRateLen);
 		pAd->MlmeAux.ExtRateLen = pAd->CommonCfg.ExtRateLen;
-		NdisMoveMemory(pAd->MlmeAux.ExtRate, pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
-		RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
+		NdisMoveMemory(pAd->MlmeAux.ExtRate, pAd->CommonCfg.ExtRate,
+			       MAX_LEN_OF_SUPPORTED_RATES);
+		RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate,
+			       &pAd->MlmeAux.ExtRateLen);
 
-		if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
-		{
-			RTMPUpdateHTIE(&pAd->CommonCfg.DesiredHtPhy, &pAd->StaCfg.DesiredHtPhyInfo.MCSSet[0], &pAd->MlmeAux.HtCapability, &pAd->MlmeAux.AddHtInfo);
-			pAd->MlmeAux.HtCapabilityLen = sizeof(HT_CAPABILITY_IE);
-			// Not turn pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE here.
-			DBGPRINT(RT_DEBUG_TRACE, ("SYNC -pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE\n"));
-		}
-		else
-		{
+		if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) {
+			RTMPUpdateHTIE(&pAd->CommonCfg.DesiredHtPhy,
+				       &pAd->StaCfg.DesiredHtPhyInfo.MCSSet[0],
+				       &pAd->MlmeAux.HtCapability,
+				       &pAd->MlmeAux.AddHtInfo);
+			pAd->MlmeAux.HtCapabilityLen = sizeof(struct rt_ht_capability_ie);
+			/* Not turn pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE here. */
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("SYNC -pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE\n"));
+		} else {
 			pAd->MlmeAux.HtCapabilityLen = 0;
 			pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
+			NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.
+				       MCSSet[0], 16);
 		}
-		// temporarily not support QOS in IBSS
-		NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));
-		NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));
-		NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));
+		/* temporarily not support QOS in IBSS */
+		NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(struct rt_edca_parm));
+		NdisZeroMemory(&pAd->MlmeAux.APQbssLoad,
+			       sizeof(struct rt_qbss_load_parm));
+		NdisZeroMemory(&pAd->MlmeAux.APQosCapability,
+			       sizeof(struct rt_qos_capability_parm));
 
 		AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
 		AsicLockChannel(pAd, pAd->MlmeAux.Channel);
 
-		DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeStartReqAction(ch= %d,sup rates= %d, ext rates=%d)\n",
-			pAd->MlmeAux.Channel, pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen));
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("SYNC - MlmeStartReqAction(ch= %d,sup rates= %d, ext rates=%d)\n",
+			  pAd->MlmeAux.Channel, pAd->MlmeAux.SupRateLen,
+			  pAd->MlmeAux.ExtRateLen));
 
 		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
 		Status = MLME_SUCCESS;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
-	}
-	else
-	{
+		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2,
+			    &Status);
+	} else {
 		DBGPRINT_ERR(("SYNC - MlmeStartReqAction() sanity check fail.\n"));
 		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
 		Status = MLME_INVALID_FORMAT;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
+		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2,
+			    &Status);
 	}
 }
 
@@ -572,126 +550,116 @@
 		peer sends beacon back when scanning
 	==========================================================================
  */
-VOID PeerBeaconAtScanAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void PeerBeaconAtScanAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	UCHAR           Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
-	UCHAR           Ssid[MAX_LEN_OF_SSID], BssType, Channel, NewChannel,
-					SsidLen, DtimCount, DtimPeriod, BcastFlag, MessageToMe;
-	CF_PARM         CfParm;
-	USHORT          BeaconPeriod, AtimWin, CapabilityInfo;
-	PFRAME_802_11   pFrame;
-	LARGE_INTEGER   TimeStamp;
-	UCHAR           Erp;
-	UCHAR         	SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR		  	SupRateLen, ExtRateLen;
-	USHORT 			LenVIE;
-	UCHAR			CkipFlag;
-	UCHAR			AironetCellPowerLimit;
-	EDCA_PARM       EdcaParm;
-	QBSS_LOAD_PARM  QbssLoad;
-	QOS_CAPABILITY_PARM QosCapability;
-	ULONG						RalinkIe;
-	UCHAR						VarIE[MAX_VIE_LEN];		// Total VIE length = MAX_VIE_LEN - -5
-	NDIS_802_11_VARIABLE_IEs	*pVIE = NULL;
-	HT_CAPABILITY_IE		HtCapability;
-	ADD_HT_INFO_IE		AddHtInfo;	// AP might use this additional ht info IE
-	UCHAR			HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
-	UCHAR			AddHtInfoLen;
-	UCHAR			NewExtChannelOffset = 0xff;
+	u8 Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
+	u8 Ssid[MAX_LEN_OF_SSID], BssType, Channel, NewChannel,
+	    SsidLen, DtimCount, DtimPeriod, BcastFlag, MessageToMe;
+	struct rt_cf_parm CfParm;
+	u16 BeaconPeriod, AtimWin, CapabilityInfo;
+	struct rt_frame_802_11 * pFrame;
+	LARGE_INTEGER TimeStamp;
+	u8 Erp;
+	u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES],
+	    ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+	u8 SupRateLen, ExtRateLen;
+	u16 LenVIE;
+	u8 CkipFlag;
+	u8 AironetCellPowerLimit;
+	struct rt_edca_parm EdcaParm;
+	struct rt_qbss_load_parm QbssLoad;
+	struct rt_qos_capability_parm QosCapability;
+	unsigned long RalinkIe;
+	u8 VarIE[MAX_VIE_LEN];	/* Total VIE length = MAX_VIE_LEN - -5 */
+	struct rt_ndis_802_11_variable_ies *pVIE = NULL;
+	struct rt_ht_capability_ie HtCapability;
+	struct rt_add_ht_info_ie AddHtInfo;	/* AP might use this additional ht info IE */
+	u8 HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
+	u8 AddHtInfoLen;
+	u8 NewExtChannelOffset = 0xff;
 
-	pFrame = (PFRAME_802_11) Elem->Msg;
-	// Init Variable IE structure
-	pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
+	/* NdisFillMemory(Ssid, MAX_LEN_OF_SSID, 0x00); */
+	pFrame = (struct rt_frame_802_11 *) Elem->Msg;
+	/* Init Variable IE structure */
+	pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE;
 	pVIE->Length = 0;
 
-    RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
-	RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
+	RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
+	RTMPZeroMemory(&AddHtInfo, sizeof(struct rt_add_ht_info_ie));
 
 	if (PeerBeaconAndProbeRspSanity(pAd,
-								Elem->Msg,
-								Elem->MsgLen,
-								Elem->Channel,
-								Addr2,
-								Bssid,
-								Ssid,
-								&SsidLen,
-								&BssType,
-								&BeaconPeriod,
-								&Channel,
-								&NewChannel,
-								&TimeStamp,
-								&CfParm,
-								&AtimWin,
-								&CapabilityInfo,
-								&Erp,
-								&DtimCount,
-								&DtimPeriod,
-								&BcastFlag,
-								&MessageToMe,
-								SupRate,
-								&SupRateLen,
-								ExtRate,
-								&ExtRateLen,
-								&CkipFlag,
-								&AironetCellPowerLimit,
-								&EdcaParm,
-								&QbssLoad,
-								&QosCapability,
-								&RalinkIe,
-								&HtCapabilityLen,
-								&PreNHtCapabilityLen,
-								&HtCapability,
-								&AddHtInfoLen,
-								&AddHtInfo,
-								&NewExtChannelOffset,
-								&LenVIE,
-								pVIE))
-	{
-		ULONG Idx;
-		CHAR Rssi = 0;
+					Elem->Msg,
+					Elem->MsgLen,
+					Elem->Channel,
+					Addr2,
+					Bssid,
+					(char *)Ssid,
+					&SsidLen,
+					&BssType,
+					&BeaconPeriod,
+					&Channel,
+					&NewChannel,
+					&TimeStamp,
+					&CfParm,
+					&AtimWin,
+					&CapabilityInfo,
+					&Erp,
+					&DtimCount,
+					&DtimPeriod,
+					&BcastFlag,
+					&MessageToMe,
+					SupRate,
+					&SupRateLen,
+					ExtRate,
+					&ExtRateLen,
+					&CkipFlag,
+					&AironetCellPowerLimit,
+					&EdcaParm,
+					&QbssLoad,
+					&QosCapability,
+					&RalinkIe,
+					&HtCapabilityLen,
+					&PreNHtCapabilityLen,
+					&HtCapability,
+					&AddHtInfoLen,
+					&AddHtInfo,
+					&NewExtChannelOffset, &LenVIE, pVIE)) {
+		unsigned long Idx;
+		char Rssi = 0;
 
 		Idx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
 		if (Idx != BSS_NOT_FOUND)
 			Rssi = pAd->ScanTab.BssEntry[Idx].Rssi;
 
-		Rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
+		Rssi =
+		    RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
+				ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
+				ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
 
 		if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
 			HtCapabilityLen = SIZE_HT_CAP_IE;
 
-		if ((pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED) && (Channel == pAd->StaCfg.CCXScanChannel))
-		{
-			Idx = BssTableSetEntry(pAd, &pAd->StaCfg.CCXBssTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
-						 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen,ExtRate, ExtRateLen, &HtCapability,
-						 &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag,
-						 &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
-			if (Idx != BSS_NOT_FOUND)
-			{
-				NdisMoveMemory(pAd->StaCfg.CCXBssTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4);
-				NdisMoveMemory(&pAd->StaCfg.CCXBssTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
-				NdisMoveMemory(&pAd->StaCfg.CCXBssTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
-				if (pAd->StaCfg.CCXReqType == MSRN_TYPE_BEACON_REQ)
-					AironetAddBeaconReport(pAd, Idx, Elem);
-			}
-		}
-		else
-		{
-			Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
-						  &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,  &HtCapability,
-						 &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag,
-						 &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
+		Idx =
+		    BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, (char *)Ssid,
+				     SsidLen, BssType, BeaconPeriod, &CfParm,
+				     AtimWin, CapabilityInfo, SupRate,
+				     SupRateLen, ExtRate, ExtRateLen,
+				     &HtCapability, &AddHtInfo, HtCapabilityLen,
+				     AddHtInfoLen, NewExtChannelOffset, Channel,
+				     Rssi, TimeStamp, CkipFlag, &EdcaParm,
+				     &QosCapability, &QbssLoad, LenVIE, pVIE);
 
-			if (Idx != BSS_NOT_FOUND)
-			{
-				NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4);
-				NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
-				NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
-			}
+		if (Idx != BSS_NOT_FOUND) {
+			NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF,
+				       &Elem->Msg[24], 4);
+			NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0],
+				       &Elem->TimeStamp.u.LowPart, 4);
+			NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4],
+				       &Elem->TimeStamp.u.LowPart, 4);
 		}
+
 	}
-	// sanity check fail, ignored
+	/* sanity check fail, ignored */
 }
 
 /*
@@ -700,134 +668,207 @@
 		When waiting joining the (I)BSS, beacon received from external
 	==========================================================================
  */
-VOID PeerBeaconAtJoinAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void PeerBeaconAtJoinAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	UCHAR         Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
-	UCHAR         Ssid[MAX_LEN_OF_SSID], SsidLen, BssType, Channel, MessageToMe,
-				  DtimCount, DtimPeriod, BcastFlag, NewChannel;
+	u8 Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
+	u8 Ssid[MAX_LEN_OF_SSID], SsidLen, BssType, Channel, MessageToMe,
+	    DtimCount, DtimPeriod, BcastFlag, NewChannel;
 	LARGE_INTEGER TimeStamp;
-	USHORT        BeaconPeriod, AtimWin, CapabilityInfo;
-	CF_PARM       Cf;
-	BOOLEAN       TimerCancelled;
-	UCHAR         Erp;
-	UCHAR         SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR		  SupRateLen, ExtRateLen;
-	UCHAR         CkipFlag;
-	USHORT 		  LenVIE;
-	UCHAR		  AironetCellPowerLimit;
-	EDCA_PARM       EdcaParm;
-	QBSS_LOAD_PARM  QbssLoad;
-	QOS_CAPABILITY_PARM QosCapability;
-	USHORT        Status;
-	UCHAR						VarIE[MAX_VIE_LEN];		// Total VIE length = MAX_VIE_LEN - -5
-	NDIS_802_11_VARIABLE_IEs	*pVIE = NULL;
-	ULONG           RalinkIe;
-	ULONG         Idx;
-	HT_CAPABILITY_IE		HtCapability;
-	ADD_HT_INFO_IE		AddHtInfo;	// AP might use this additional ht info IE
-	UCHAR				HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
-	UCHAR			AddHtInfoLen;
-	UCHAR			NewExtChannelOffset = 0xff;
-	UCHAR			CentralChannel;
+	u16 BeaconPeriod, AtimWin, CapabilityInfo;
+	struct rt_cf_parm Cf;
+	BOOLEAN TimerCancelled;
+	u8 Erp;
+	u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES],
+	    ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+	u8 SupRateLen, ExtRateLen;
+	u8 CkipFlag;
+	u16 LenVIE;
+	u8 AironetCellPowerLimit;
+	struct rt_edca_parm EdcaParm;
+	struct rt_qbss_load_parm QbssLoad;
+	struct rt_qos_capability_parm QosCapability;
+	u16 Status;
+	u8 VarIE[MAX_VIE_LEN];	/* Total VIE length = MAX_VIE_LEN - -5 */
+	struct rt_ndis_802_11_variable_ies *pVIE = NULL;
+	unsigned long RalinkIe;
+	unsigned long Idx;
+	struct rt_ht_capability_ie HtCapability;
+	struct rt_add_ht_info_ie AddHtInfo;	/* AP might use this additional ht info IE */
+	u8 HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
+	u8 AddHtInfoLen;
+	u8 NewExtChannelOffset = 0xff;
+	u8 CentralChannel;
+	BOOLEAN bAllowNrate = FALSE;
 
-	// Init Variable IE structure
-	pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
+	/* Init Variable IE structure */
+	pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE;
 	pVIE->Length = 0;
-    RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
-	RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
-
+	RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
+	RTMPZeroMemory(&AddHtInfo, sizeof(struct rt_add_ht_info_ie));
 
 	if (PeerBeaconAndProbeRspSanity(pAd,
-								Elem->Msg,
-								Elem->MsgLen,
-								Elem->Channel,
-								Addr2,
-								Bssid,
-								Ssid,
-								&SsidLen,
-								&BssType,
-								&BeaconPeriod,
-								&Channel,
-								&NewChannel,
-								&TimeStamp,
-								&Cf,
-								&AtimWin,
-								&CapabilityInfo,
-								&Erp,
-								&DtimCount,
-								&DtimPeriod,
-								&BcastFlag,
-								&MessageToMe,
-								SupRate,
-								&SupRateLen,
-								ExtRate,
-								&ExtRateLen,
-								&CkipFlag,
-								&AironetCellPowerLimit,
-								&EdcaParm,
-								&QbssLoad,
-								&QosCapability,
-								&RalinkIe,
-								&HtCapabilityLen,
-								&PreNHtCapabilityLen,
-								&HtCapability,
-								&AddHtInfoLen,
-								&AddHtInfo,
-								&NewExtChannelOffset,
-								&LenVIE,
-								pVIE))
-	{
-		// Disqualify 11b only adhoc when we are in 11g only adhoc mode
-		if ((BssType == BSS_ADHOC) && (pAd->CommonCfg.PhyMode == PHY_11G) && ((SupRateLen+ExtRateLen)< 12))
+					Elem->Msg,
+					Elem->MsgLen,
+					Elem->Channel,
+					Addr2,
+					Bssid,
+					(char *)Ssid,
+					&SsidLen,
+					&BssType,
+					&BeaconPeriod,
+					&Channel,
+					&NewChannel,
+					&TimeStamp,
+					&Cf,
+					&AtimWin,
+					&CapabilityInfo,
+					&Erp,
+					&DtimCount,
+					&DtimPeriod,
+					&BcastFlag,
+					&MessageToMe,
+					SupRate,
+					&SupRateLen,
+					ExtRate,
+					&ExtRateLen,
+					&CkipFlag,
+					&AironetCellPowerLimit,
+					&EdcaParm,
+					&QbssLoad,
+					&QosCapability,
+					&RalinkIe,
+					&HtCapabilityLen,
+					&PreNHtCapabilityLen,
+					&HtCapability,
+					&AddHtInfoLen,
+					&AddHtInfo,
+					&NewExtChannelOffset, &LenVIE, pVIE)) {
+		/* Disqualify 11b only adhoc when we are in 11g only adhoc mode */
+		if ((BssType == BSS_ADHOC)
+		    && (pAd->CommonCfg.PhyMode == PHY_11G)
+		    && ((SupRateLen + ExtRateLen) < 12))
 			return;
 
-		// BEACON from desired BSS/IBSS found. We should be able to decide most
-		// BSS parameters here.
-		// Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION?
-		//    Do we need to receover back all parameters belonging to previous BSS?
-		// A. Should be not. There's no back-door recover to previous AP. It still need
-		//    a new JOIN-AUTH-ASSOC sequence.
-		if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Bssid))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n", Channel));
-			RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
+		/* BEACON from desired BSS/IBSS found. We should be able to decide most */
+		/* BSS parameters here. */
+		/* Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION? */
+		/*    Do we need to receover back all parameters belonging to previous BSS? */
+		/* A. Should be not. There's no back-door recover to previous AP. It still need */
+		/*    a new JOIN-AUTH-ASSOC sequence. */
+		if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Bssid)) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n",
+				  Channel));
+			RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer,
+					&TimerCancelled);
 
-			// Update RSSI to prevent No signal display when cards first initialized
-			pAd->StaCfg.RssiSample.LastRssi0	= ConvertToRssi(pAd, Elem->Rssi0, RSSI_0);
-			pAd->StaCfg.RssiSample.LastRssi1	= ConvertToRssi(pAd, Elem->Rssi1, RSSI_1);
-			pAd->StaCfg.RssiSample.LastRssi2	= ConvertToRssi(pAd, Elem->Rssi2, RSSI_2);
-			pAd->StaCfg.RssiSample.AvgRssi0	= pAd->StaCfg.RssiSample.LastRssi0;
-			pAd->StaCfg.RssiSample.AvgRssi0X8	= pAd->StaCfg.RssiSample.AvgRssi0 << 3;
-			pAd->StaCfg.RssiSample.AvgRssi1	= pAd->StaCfg.RssiSample.LastRssi1;
-			pAd->StaCfg.RssiSample.AvgRssi1X8	= pAd->StaCfg.RssiSample.AvgRssi1 << 3;
-			pAd->StaCfg.RssiSample.AvgRssi2	= pAd->StaCfg.RssiSample.LastRssi2;
-			pAd->StaCfg.RssiSample.AvgRssi2X8	= pAd->StaCfg.RssiSample.AvgRssi2 << 3;
+			/* Update RSSI to prevent No signal display when cards first initialized */
+			pAd->StaCfg.RssiSample.LastRssi0 =
+			    ConvertToRssi(pAd, Elem->Rssi0, RSSI_0);
+			pAd->StaCfg.RssiSample.LastRssi1 =
+			    ConvertToRssi(pAd, Elem->Rssi1, RSSI_1);
+			pAd->StaCfg.RssiSample.LastRssi2 =
+			    ConvertToRssi(pAd, Elem->Rssi2, RSSI_2);
+			pAd->StaCfg.RssiSample.AvgRssi0 =
+			    pAd->StaCfg.RssiSample.LastRssi0;
+			pAd->StaCfg.RssiSample.AvgRssi0X8 =
+			    pAd->StaCfg.RssiSample.AvgRssi0 << 3;
+			pAd->StaCfg.RssiSample.AvgRssi1 =
+			    pAd->StaCfg.RssiSample.LastRssi1;
+			pAd->StaCfg.RssiSample.AvgRssi1X8 =
+			    pAd->StaCfg.RssiSample.AvgRssi1 << 3;
+			pAd->StaCfg.RssiSample.AvgRssi2 =
+			    pAd->StaCfg.RssiSample.LastRssi2;
+			pAd->StaCfg.RssiSample.AvgRssi2X8 =
+			    pAd->StaCfg.RssiSample.AvgRssi2 << 3;
 
-			//
-			// We need to check if SSID only set to any, then we can record the current SSID.
-			// Otherwise will cause hidden SSID association failed.
-			//
-			if (pAd->MlmeAux.SsidLen == 0)
-			{
-				NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
+			/* */
+			/* We need to check if SSID only set to any, then we can record the current SSID. */
+			/* Otherwise will cause hidden SSID association failed. */
+			/* */
+			if (pAd->MlmeAux.SsidLen == 0) {
+				NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid,
+					       SsidLen);
 				pAd->MlmeAux.SsidLen = SsidLen;
-			}
-			else
-			{
-				Idx = BssSsidTableSearch(&pAd->ScanTab, Bssid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Channel);
+			} else {
+				Idx =
+				    BssSsidTableSearch(&pAd->ScanTab, Bssid,
+						       pAd->MlmeAux.Ssid,
+						       pAd->MlmeAux.SsidLen,
+						       Channel);
 
-				if (Idx != BSS_NOT_FOUND)
-				{
-					//
-					// Multiple SSID case, used correct CapabilityInfo
-					//
-					CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo;
+				if (Idx == BSS_NOT_FOUND) {
+					char Rssi = 0;
+					Rssi =
+					    RTMPMaxRssi(pAd,
+							ConvertToRssi(pAd,
+								      Elem->
+								      Rssi0,
+								      RSSI_0),
+							ConvertToRssi(pAd,
+								      Elem->
+								      Rssi1,
+								      RSSI_1),
+							ConvertToRssi(pAd,
+								      Elem->
+								      Rssi2,
+								      RSSI_2));
+					Idx =
+					    BssTableSetEntry(pAd, &pAd->ScanTab,
+							     Bssid,
+							     (char *) Ssid,
+							     SsidLen, BssType,
+							     BeaconPeriod, &Cf,
+							     AtimWin,
+							     CapabilityInfo,
+							     SupRate,
+							     SupRateLen,
+							     ExtRate,
+							     ExtRateLen,
+							     &HtCapability,
+							     &AddHtInfo,
+							     HtCapabilityLen,
+							     AddHtInfoLen,
+							     NewExtChannelOffset,
+							     Channel, Rssi,
+							     TimeStamp,
+							     CkipFlag,
+							     &EdcaParm,
+							     &QosCapability,
+							     &QbssLoad, LenVIE,
+							     pVIE);
+					if (Idx != BSS_NOT_FOUND) {
+						NdisMoveMemory(pAd->ScanTab.
+							       BssEntry[Idx].
+							       PTSF,
+							       &Elem->Msg[24],
+							       4);
+						NdisMoveMemory(&pAd->ScanTab.
+							       BssEntry[Idx].
+							       TTSF[0],
+							       &Elem->TimeStamp.
+							       u.LowPart, 4);
+						NdisMoveMemory(&pAd->ScanTab.
+							       BssEntry[Idx].
+							       TTSF[4],
+							       &Elem->TimeStamp.
+							       u.LowPart, 4);
+						CapabilityInfo =
+						    pAd->ScanTab.BssEntry[Idx].
+						    CapabilityInfo;
+					}
+				} else {
+					/* */
+					/* Multiple SSID case, used correct CapabilityInfo */
+					/* */
+					CapabilityInfo =
+					    pAd->ScanTab.BssEntry[Idx].
+					    CapabilityInfo;
 				}
 			}
 			NdisMoveMemory(pAd->MlmeAux.Bssid, Bssid, MAC_ADDR_LEN);
-			pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
+			pAd->MlmeAux.CapabilityInfo =
+			    CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
 			pAd->MlmeAux.BssType = BssType;
 			pAd->MlmeAux.BeaconPeriod = BeaconPeriod;
 			pAd->MlmeAux.Channel = Channel;
@@ -836,107 +877,159 @@
 			pAd->MlmeAux.CfpMaxDuration = Cf.CfpMaxDuration;
 			pAd->MlmeAux.APRalinkIe = RalinkIe;
 
-			// Copy AP's supported rate to MlmeAux for creating assoication request
-			// Also filter out not supported rate
+			/* Copy AP's supported rate to MlmeAux for creating assoication request */
+			/* Also filter out not supported rate */
 			pAd->MlmeAux.SupRateLen = SupRateLen;
-			NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen);
-			RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
+			NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate,
+				       SupRateLen);
+			RTMPCheckRates(pAd, pAd->MlmeAux.SupRate,
+				       &pAd->MlmeAux.SupRateLen);
 			pAd->MlmeAux.ExtRateLen = ExtRateLen;
-			NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen);
-			RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
+			NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate,
+				       ExtRateLen);
+			RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate,
+				       &pAd->MlmeAux.ExtRateLen);
 
-            NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, 16);
+			NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet,
+				       16);
+
+			if (((pAd->StaCfg.WepStatus != Ndis802_11WEPEnabled)
+			     && (pAd->StaCfg.WepStatus !=
+				 Ndis802_11Encryption2Enabled))
+			    || (pAd->CommonCfg.HT_DisallowTKIP == FALSE)) {
+				bAllowNrate = TRUE;
+			}
 
 			pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
 			pAd->MlmeAux.HtCapabilityLen = HtCapabilityLen;
 
-			// filter out un-supported ht rates
-			if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
-			{
-				RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
-   				RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo, &AddHtInfo, SIZE_ADD_HT_INFO_IE);
+			RTMPZeroMemory(&pAd->MlmeAux.HtCapability,
+				       SIZE_HT_CAP_IE);
+			/* filter out un-supported ht rates */
+			if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
+			    && ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+				&& (bAllowNrate))) {
+				RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo,
+					       &AddHtInfo, SIZE_ADD_HT_INFO_IE);
 
-				// StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability
-				NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, HtCapability.MCSSet, 16);
-				pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
+				/* StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability */
+				NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.
+					       MCSSet, HtCapability.MCSSet, 16);
+				pAd->MlmeAux.NewExtChannelOffset =
+				    NewExtChannelOffset;
 				pAd->MlmeAux.HtCapabilityLen = SIZE_HT_CAP_IE;
-				pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
+				pAd->StaActive.SupportedPhyInfo.bHtEnable =
+				    TRUE;
 				if (PreNHtCapabilityLen > 0)
-					pAd->StaActive.SupportedPhyInfo.bPreNHt = TRUE;
-				RTMPCheckHt(pAd, BSSID_WCID, &HtCapability, &AddHtInfo);
-				// Copy AP Parameter to StaActive.  This is also in LinkUp.
-				DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n",
-					pAd->StaActive.SupportedHtPhy.MpduDensity, pAd->StaActive.SupportedHtPhy.MaxRAmpduFactor, HtCapability.HtCapInfo.ChannelWidth));
+					pAd->StaActive.SupportedPhyInfo.
+					    bPreNHt = TRUE;
+				RTMPCheckHt(pAd, BSSID_WCID, &HtCapability,
+					    &AddHtInfo);
+				/* Copy AP Parameter to StaActive.  This is also in LinkUp. */
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n",
+					  pAd->StaActive.SupportedHtPhy.
+					  MpduDensity,
+					  pAd->StaActive.SupportedHtPhy.
+					  MaxRAmpduFactor,
+					  HtCapability.HtCapInfo.ChannelWidth));
 
-				if (AddHtInfoLen > 0)
-				{
+				if (AddHtInfoLen > 0) {
 					CentralChannel = AddHtInfo.ControlChan;
-		 			// Check again the Bandwidth capability of this AP.
-		 			if ((AddHtInfo.ControlChan > 2)&& (AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (HtCapability.HtCapInfo.ChannelWidth == BW_40))
-		 			{
-		 				CentralChannel = AddHtInfo.ControlChan - 2;
-		 			}
-		 			else if ((AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (HtCapability.HtCapInfo.ChannelWidth == BW_40))
-		 			{
-		 				CentralChannel = AddHtInfo.ControlChan + 2;
-		 			}
+					/* Check again the Bandwidth capability of this AP. */
+					if ((AddHtInfo.ControlChan > 2)
+					    && (AddHtInfo.AddHtInfo.
+						ExtChanOffset == EXTCHA_BELOW)
+					    && (HtCapability.HtCapInfo.
+						ChannelWidth == BW_40)) {
+						CentralChannel =
+						    AddHtInfo.ControlChan - 2;
+					} else
+					    if ((AddHtInfo.AddHtInfo.
+						 ExtChanOffset == EXTCHA_ABOVE)
+						&& (HtCapability.HtCapInfo.
+						    ChannelWidth == BW_40)) {
+						CentralChannel =
+						    AddHtInfo.ControlChan + 2;
+					}
+					/* Check Error . */
+					if (pAd->MlmeAux.CentralChannel !=
+					    CentralChannel)
+						DBGPRINT(RT_DEBUG_ERROR,
+							 ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n",
+							  CentralChannel,
+							  AddHtInfo.ControlChan,
+							  pAd->MlmeAux.
+							  CentralChannel));
 
-					// Check Error .
-					if (pAd->MlmeAux.CentralChannel != CentralChannel)
-		 				DBGPRINT(RT_DEBUG_ERROR, ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n", CentralChannel, AddHtInfo.ControlChan, pAd->MlmeAux.CentralChannel));
-
-		 			DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d,  .\n", CentralChannel, AddHtInfo.ControlChan));
+					DBGPRINT(RT_DEBUG_TRACE,
+						 ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d,  .\n",
+						  CentralChannel,
+						  AddHtInfo.ControlChan));
 
 				}
 
-			}
-			else
-			{
-   				// To prevent error, let legacy AP must have same CentralChannel and Channel.
-				if ((HtCapabilityLen == 0) && (PreNHtCapabilityLen == 0))
-					pAd->MlmeAux.CentralChannel = pAd->MlmeAux.Channel;
+			} else {
+				/* To prevent error, let legacy AP must have same CentralChannel and Channel. */
+				if ((HtCapabilityLen == 0)
+				    && (PreNHtCapabilityLen == 0))
+					pAd->MlmeAux.CentralChannel =
+					    pAd->MlmeAux.Channel;
 
-				pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
-				RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
-				RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE);
+				pAd->StaActive.SupportedPhyInfo.bHtEnable =
+				    FALSE;
+				pAd->MlmeAux.NewExtChannelOffset = 0xff;
+				RTMPZeroMemory(&pAd->MlmeAux.HtCapability,
+					       SIZE_HT_CAP_IE);
+				pAd->MlmeAux.HtCapabilityLen = 0;
+				RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo,
+					       SIZE_ADD_HT_INFO_IE);
 			}
 
 			RTMPUpdateMlmeRate(pAd);
 
-			// copy QOS related information
+			/* copy QOS related information */
 			if ((pAd->CommonCfg.bWmmCapable)
-				 || (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
-				)
-			{
-				NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, &EdcaParm, sizeof(EDCA_PARM));
-				NdisMoveMemory(&pAd->MlmeAux.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM));
-				NdisMoveMemory(&pAd->MlmeAux.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM));
-			}
-			else
-			{
-				NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));
-				NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));
-				NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));
+			    || (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+			    ) {
+				NdisMoveMemory(&pAd->MlmeAux.APEdcaParm,
+					       &EdcaParm, sizeof(struct rt_edca_parm));
+				NdisMoveMemory(&pAd->MlmeAux.APQbssLoad,
+					       &QbssLoad,
+					       sizeof(struct rt_qbss_load_parm));
+				NdisMoveMemory(&pAd->MlmeAux.APQosCapability,
+					       &QosCapability,
+					       sizeof(struct rt_qos_capability_parm));
+			} else {
+				NdisZeroMemory(&pAd->MlmeAux.APEdcaParm,
+					       sizeof(struct rt_edca_parm));
+				NdisZeroMemory(&pAd->MlmeAux.APQbssLoad,
+					       sizeof(struct rt_qbss_load_parm));
+				NdisZeroMemory(&pAd->MlmeAux.APQosCapability,
+					       sizeof(struct rt_qos_capability_parm));
 			}
 
-			DBGPRINT(RT_DEBUG_TRACE, ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n",
-										pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen));
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n",
+				  pAd->MlmeAux.SupRateLen,
+				  pAd->MlmeAux.ExtRateLen));
 
-			if (AironetCellPowerLimit != 0xFF)
-			{
-				//We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power
-				ChangeToCellPowerLimit(pAd, AironetCellPowerLimit);
-			}
-			else  //Used the default TX Power Percentage.
-				pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
+			if (AironetCellPowerLimit != 0xFF) {
+				/*We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power */
+				ChangeToCellPowerLimit(pAd,
+						       AironetCellPowerLimit);
+			} else	/*Used the default TX Power Percentage. */
+				pAd->CommonCfg.TxPowerPercentage =
+				    pAd->CommonCfg.TxPowerDefault;
 
 			pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
 			Status = MLME_SUCCESS;
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
+			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF,
+				    2, &Status);
 		}
-		// not to me BEACON, ignored
+		/* not to me BEACON, ignored */
 	}
-	// sanity check fail, ignore this frame
+	/* sanity check fail, ignore this frame */
 }
 
 /*
@@ -948,662 +1041,660 @@
 
 	==========================================================================
  */
-VOID PeerBeacon(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void PeerBeacon(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	UCHAR         Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
-	CHAR          Ssid[MAX_LEN_OF_SSID];
-	CF_PARM       CfParm;
-	UCHAR         SsidLen, MessageToMe=0, BssType, Channel, NewChannel, index=0;
-	UCHAR         DtimCount=0, DtimPeriod=0, BcastFlag=0;
-	USHORT        CapabilityInfo, AtimWin, BeaconPeriod;
+	u8 Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
+	char Ssid[MAX_LEN_OF_SSID];
+	struct rt_cf_parm CfParm;
+	u8 SsidLen, MessageToMe = 0, BssType, Channel, NewChannel, index = 0;
+	u8 DtimCount = 0, DtimPeriod = 0, BcastFlag = 0;
+	u16 CapabilityInfo, AtimWin, BeaconPeriod;
 	LARGE_INTEGER TimeStamp;
-	USHORT        TbttNumToNextWakeUp;
-	UCHAR         Erp;
-	UCHAR         SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR		  SupRateLen, ExtRateLen;
-	UCHAR		  CkipFlag;
-	USHORT        LenVIE;
-	UCHAR		  AironetCellPowerLimit;
-	EDCA_PARM       EdcaParm;
-	QBSS_LOAD_PARM  QbssLoad;
-	QOS_CAPABILITY_PARM QosCapability;
-	ULONG           RalinkIe;
-	// New for WPA security suites
-	UCHAR						VarIE[MAX_VIE_LEN];		// Total VIE length = MAX_VIE_LEN - -5
-	NDIS_802_11_VARIABLE_IEs	*pVIE = NULL;
-	HT_CAPABILITY_IE		HtCapability;
-	ADD_HT_INFO_IE		AddHtInfo;	// AP might use this additional ht info IE
-	UCHAR			HtCapabilityLen, PreNHtCapabilityLen;
-	UCHAR			AddHtInfoLen;
-	UCHAR			NewExtChannelOffset = 0xff;
+	u16 TbttNumToNextWakeUp;
+	u8 Erp;
+	u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES],
+	    ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+	u8 SupRateLen, ExtRateLen;
+	u8 CkipFlag;
+	u16 LenVIE;
+	u8 AironetCellPowerLimit;
+	struct rt_edca_parm EdcaParm;
+	struct rt_qbss_load_parm QbssLoad;
+	struct rt_qos_capability_parm QosCapability;
+	unsigned long RalinkIe;
+	/* New for WPA security suites */
+	u8 VarIE[MAX_VIE_LEN];	/* Total VIE length = MAX_VIE_LEN - -5 */
+	struct rt_ndis_802_11_variable_ies *pVIE = NULL;
+	struct rt_ht_capability_ie HtCapability;
+	struct rt_add_ht_info_ie AddHtInfo;	/* AP might use this additional ht info IE */
+	u8 HtCapabilityLen, PreNHtCapabilityLen;
+	u8 AddHtInfoLen;
+	u8 NewExtChannelOffset = 0xff;
 
 	if (!(INFRA_ON(pAd) || ADHOC_ON(pAd)
-		))
+	    ))
 		return;
 
-	// Init Variable IE structure
-	pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
+	/* Init Variable IE structure */
+	pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE;
 	pVIE->Length = 0;
-    RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
-	RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
+	RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
+	RTMPZeroMemory(&AddHtInfo, sizeof(struct rt_add_ht_info_ie));
 
 	if (PeerBeaconAndProbeRspSanity(pAd,
-								Elem->Msg,
-								Elem->MsgLen,
-								Elem->Channel,
-								Addr2,
-								Bssid,
-								Ssid,
-								&SsidLen,
-								&BssType,
-								&BeaconPeriod,
-								&Channel,
-								&NewChannel,
-								&TimeStamp,
-								&CfParm,
-								&AtimWin,
-								&CapabilityInfo,
-								&Erp,
-								&DtimCount,
-								&DtimPeriod,
-								&BcastFlag,
-								&MessageToMe,
-								SupRate,
-								&SupRateLen,
-								ExtRate,
-								&ExtRateLen,
-								&CkipFlag,
-								&AironetCellPowerLimit,
-								&EdcaParm,
-								&QbssLoad,
-								&QosCapability,
-								&RalinkIe,
-								&HtCapabilityLen,
-								&PreNHtCapabilityLen,
-								&HtCapability,
-								&AddHtInfoLen,
-								&AddHtInfo,
-								&NewExtChannelOffset,
-								&LenVIE,
-								pVIE))
-	{
+					Elem->Msg,
+					Elem->MsgLen,
+					Elem->Channel,
+					Addr2,
+					Bssid,
+					Ssid,
+					&SsidLen,
+					&BssType,
+					&BeaconPeriod,
+					&Channel,
+					&NewChannel,
+					&TimeStamp,
+					&CfParm,
+					&AtimWin,
+					&CapabilityInfo,
+					&Erp,
+					&DtimCount,
+					&DtimPeriod,
+					&BcastFlag,
+					&MessageToMe,
+					SupRate,
+					&SupRateLen,
+					ExtRate,
+					&ExtRateLen,
+					&CkipFlag,
+					&AironetCellPowerLimit,
+					&EdcaParm,
+					&QbssLoad,
+					&QosCapability,
+					&RalinkIe,
+					&HtCapabilityLen,
+					&PreNHtCapabilityLen,
+					&HtCapability,
+					&AddHtInfoLen,
+					&AddHtInfo,
+					&NewExtChannelOffset, &LenVIE, pVIE)) {
 		BOOLEAN is_my_bssid, is_my_ssid;
-		ULONG   Bssidx, Now;
-		BSS_ENTRY *pBss;
-		CHAR		RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
+		unsigned long Bssidx, Now;
+		struct rt_bss_entry *pBss;
+		char RealRssi =
+		    RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
+				ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
+				ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
 
-		is_my_bssid = MAC_ADDR_EQUAL(Bssid, pAd->CommonCfg.Bssid)? TRUE : FALSE;
-		is_my_ssid = SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)? TRUE:FALSE;
+		is_my_bssid =
+		    MAC_ADDR_EQUAL(Bssid, pAd->CommonCfg.Bssid) ? TRUE : FALSE;
+		is_my_ssid =
+		    SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid,
+			       pAd->CommonCfg.SsidLen) ? TRUE : FALSE;
 
-
-		// ignore BEACON not for my SSID
-		if ((! is_my_ssid) && (! is_my_bssid))
+		/* ignore BEACON not for my SSID */
+		if ((!is_my_ssid) && (!is_my_bssid))
 			return;
 
-		// It means STA waits disassoc completely from this AP, ignores this beacon.
+		/* It means STA waits disassoc completely from this AP, ignores this beacon. */
 		if (pAd->Mlme.CntlMachine.CurrState == CNTL_WAIT_DISASSOC)
 			return;
 
-		// Copy Control channel for this BSSID.
+		/* Copy Control channel for this BSSID. */
 		if (AddHtInfoLen != 0)
 			Channel = AddHtInfo.ControlChan;
 
 		if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
 			HtCapabilityLen = SIZE_HT_CAP_IE;
 
-		//
-		// Housekeeping "SsidBssTab" table for later-on ROAMing usage.
-		//
+		/* */
+		/* Housekeeping "SsidBssTab" table for later-on ROAMing usage. */
+		/* */
 		Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
-		if (Bssidx == BSS_NOT_FOUND)
-		{
-			// discover new AP of this network, create BSS entry
-			Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
-						 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,
-						&HtCapability, &AddHtInfo,HtCapabilityLen,AddHtInfoLen,NewExtChannelOffset, Channel,
-						RealRssi, TimeStamp, CkipFlag, &EdcaParm, &QosCapability,
-						&QbssLoad, LenVIE, pVIE);
-			if (Bssidx == BSS_NOT_FOUND) // return if BSS table full
+		if (Bssidx == BSS_NOT_FOUND) {
+			/* discover new AP of this network, create BSS entry */
+			Bssidx =
+			    BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid,
+					     SsidLen, BssType, BeaconPeriod,
+					     &CfParm, AtimWin, CapabilityInfo,
+					     SupRate, SupRateLen, ExtRate,
+					     ExtRateLen, &HtCapability,
+					     &AddHtInfo, HtCapabilityLen,
+					     AddHtInfoLen, NewExtChannelOffset,
+					     Channel, RealRssi, TimeStamp,
+					     CkipFlag, &EdcaParm,
+					     &QosCapability, &QbssLoad, LenVIE,
+					     pVIE);
+			if (Bssidx == BSS_NOT_FOUND)	/* return if BSS table full */
 				return;
 
-			NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, &Elem->Msg[24], 4);
-			NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
-			NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
-
-
+			NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF,
+				       &Elem->Msg[24], 4);
+			NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0],
+				       &Elem->TimeStamp.u.LowPart, 4);
+			NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4],
+				       &Elem->TimeStamp.u.LowPart, 4);
 
 		}
 
-		if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel))
-		{
-			// Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
-			// In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
+		if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0)
+		    && (Channel != NewChannel)) {
+			/* Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection). */
+			/* In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results. */
 			AsicSwitchChannel(pAd, 1, FALSE);
 			AsicLockChannel(pAd, 1);
-		    LinkDown(pAd, FALSE);
+			LinkDown(pAd, FALSE);
 			MlmeQueueInit(&pAd->Mlme.Queue);
 			BssTableInit(&pAd->ScanTab);
-		    RTMPusecDelay(1000000);		// use delay to prevent STA do reassoc
+			RTMPusecDelay(1000000);	/* use delay to prevent STA do reassoc */
 
-			// channel sanity check
-			for (index = 0 ; index < pAd->ChannelListNum; index++)
-			{
-				if (pAd->ChannelList[index].Channel == NewChannel)
-				{
-					pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel;
+			/* channel sanity check */
+			for (index = 0; index < pAd->ChannelListNum; index++) {
+				if (pAd->ChannelList[index].Channel ==
+				    NewChannel) {
+					pAd->ScanTab.BssEntry[Bssidx].Channel =
+					    NewChannel;
 					pAd->CommonCfg.Channel = NewChannel;
-					AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-					AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-					DBGPRINT(RT_DEBUG_TRACE, ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel));
+					AsicSwitchChannel(pAd,
+							  pAd->CommonCfg.
+							  Channel, FALSE);
+					AsicLockChannel(pAd,
+							pAd->CommonCfg.Channel);
+					DBGPRINT(RT_DEBUG_TRACE,
+						 ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n",
+						  NewChannel));
 					break;
 				}
 			}
 
-			if (index >= pAd->ChannelListNum)
-			{
+			if (index >= pAd->ChannelListNum) {
 				DBGPRINT_ERR(("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum));
 			}
 		}
+		/* if the ssid matched & bssid unmatched, we should select the bssid with large value. */
+		/* This might happened when two STA start at the same time */
+		if ((!is_my_bssid) && ADHOC_ON(pAd)) {
+			int i;
 
-		// if the ssid matched & bssid unmatched, we should select the bssid with large value.
-		// This might happened when two STA start at the same time
-		if ((! is_my_bssid) && ADHOC_ON(pAd))
-		{
-			INT	i;
-
-			// Add the safeguard against the mismatch of adhoc wep status
-			if (pAd->StaCfg.WepStatus != pAd->ScanTab.BssEntry[Bssidx].WepStatus)
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("SYNC - Not matched wep status %d %d\n", pAd->StaCfg.WepStatus, pAd->ScanTab.BssEntry[Bssidx].WepStatus));
-				DBGPRINT(RT_DEBUG_TRACE, ("bssid=%s\n", pAd->ScanTab.BssEntry[Bssidx].Bssid));
+			/* Add the safeguard against the mismatch of adhoc wep status */
+			if (pAd->StaCfg.WepStatus !=
+			    pAd->ScanTab.BssEntry[Bssidx].WepStatus) {
 				return;
 			}
-
-			// collapse into the ADHOC network which has bigger BSSID value.
-			for (i = 0; i < 6; i++)
-			{
-				if (Bssid[i] > pAd->CommonCfg.Bssid[i])
-				{
-					DBGPRINT(RT_DEBUG_TRACE, ("SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n",
-						Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
+			/* collapse into the ADHOC network which has bigger BSSID value. */
+			for (i = 0; i < 6; i++) {
+				if (Bssid[i] > pAd->CommonCfg.Bssid[i]) {
+					DBGPRINT(RT_DEBUG_TRACE,
+						 ("SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n",
+						  Bssid[0], Bssid[1], Bssid[2],
+						  Bssid[3], Bssid[4],
+						  Bssid[5]));
 					AsicDisableSync(pAd);
-					COPY_MAC_ADDR(pAd->CommonCfg.Bssid, Bssid);
+					COPY_MAC_ADDR(pAd->CommonCfg.Bssid,
+						      Bssid);
 					AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
-					MakeIbssBeacon(pAd);        // re-build BEACON frame
-					AsicEnableIbssSync(pAd);    // copy BEACON frame to on-chip memory
+					MakeIbssBeacon(pAd);	/* re-build BEACON frame */
+					AsicEnableIbssSync(pAd);	/* copy BEACON frame to on-chip memory */
 					is_my_bssid = TRUE;
 					break;
-				}
-				else if (Bssid[i] < pAd->CommonCfg.Bssid[i])
+				} else if (Bssid[i] < pAd->CommonCfg.Bssid[i])
 					break;
 			}
 		}
 
-
 		NdisGetSystemUpTime(&Now);
 		pBss = &pAd->ScanTab.BssEntry[Bssidx];
-		pBss->Rssi = RealRssi;       // lastest RSSI
-		pBss->LastBeaconRxTime = Now;   // last RX timestamp
+		pBss->Rssi = RealRssi;	/* lastest RSSI */
+		pBss->LastBeaconRxTime = Now;	/* last RX timestamp */
 
-		//
-		// BEACON from my BSSID - either IBSS or INFRA network
-		//
-		if (is_my_bssid)
-		{
-			RXWI_STRUC	RxWI;
+		/* */
+		/* BEACON from my BSSID - either IBSS or INFRA network */
+		/* */
+		if (is_my_bssid) {
+			struct rt_rxwi RxWI;
 
 			pAd->StaCfg.DtimCount = DtimCount;
 			pAd->StaCfg.DtimPeriod = DtimPeriod;
 			pAd->StaCfg.LastBeaconRxTime = Now;
 
-
 			RxWI.RSSI0 = Elem->Rssi0;
 			RxWI.RSSI1 = Elem->Rssi1;
 			RxWI.RSSI2 = Elem->Rssi2;
 
 			Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, &RxWI);
-			if (AironetCellPowerLimit != 0xFF)
-			{
-				//
-				// We get the Cisco (ccx) "TxPower Limit" required
-				// Changed to appropriate TxPower Limit for Ciso Compatible Extensions
-				//
-				ChangeToCellPowerLimit(pAd, AironetCellPowerLimit);
-			}
-			else
-			{
-				//
-				// AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist.
-				// Used the default TX Power Percentage, that set from UI.
-				//
-				pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
+			if (AironetCellPowerLimit != 0xFF) {
+				/* */
+				/* We get the Cisco (ccx) "TxPower Limit" required */
+				/* Changed to appropriate TxPower Limit for Ciso Compatible Extensions */
+				/* */
+				ChangeToCellPowerLimit(pAd,
+						       AironetCellPowerLimit);
+			} else {
+				/* */
+				/* AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist. */
+				/* Used the default TX Power Percentage, that set from UI. */
+				/* */
+				pAd->CommonCfg.TxPowerPercentage =
+				    pAd->CommonCfg.TxPowerDefault;
 			}
 
-#ifdef RT2860
-			// at least one 11b peer joined. downgrade the MaxTxRate to 11Mbps
-			// after last 11b peer left for several seconds, we'll auto switch back to 11G rate
-			// in MlmePeriodicExec()
-#endif
-			if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo)))
-			{
-#ifdef RT2860
-				BOOLEAN	bRestart;
-                BOOLEAN	bnRestart;
+			if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo))) {
+				u8 MaxSupportedRateIn500Kbps = 0;
+				u8 idx;
+				struct rt_mac_table_entry *pEntry;
 
-				bRestart = FALSE;
-                bnRestart = FALSE;
-
-				do
-				{
-					if ((SupRateLen+ExtRateLen <= 4) && (pAd->CommonCfg.MaxTxRate > RATE_11))
-					{
-						if (pAd->StaCfg.AdhocBOnlyJoined == FALSE)
-						{
-							DBGPRINT(RT_DEBUG_TRACE, ("SYNC - 11b peer joined. down-grade to 11b TX rates \n"));
-							bRestart = TRUE;
-							NdisMoveMemory(pAd->StaActive.SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES);
-							pAd->StaActive.SupRateLen = SupRateLen;
-							NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
-							pAd->StaActive.ExtRateLen = ExtRateLen;
-							pAd->StaCfg.AdhocBOnlyJoined = TRUE;
-							pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
-							AsicSetEdcaParm(pAd, NULL);
-						}
-
-						// this timestamp is for MlmePeriodicExec() to check if all 11B peers have left
-						pAd->StaCfg.Last11bBeaconRxTime = Now;
-						break;
-					}
-
-					// Update Ht Phy.
-					if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
-					{
-						if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
-							!pAd->StaCfg.AdhocBGJoined &&
-							!pAd->StaCfg.AdhocBOnlyJoined)
-							AdhocTurnOnQos(pAd);
-
-						// Handle rate switch issue when Adhoc mode
-						if ((SupRateLen+ExtRateLen >= 8) && (HtCapability.MCSSet[0] == 0) && (HtCapability.MCSSet[1] == 0))
-						{
-							if (pAd->StaCfg.AdhocBGJoined == FALSE)
-							{
-								DBGPRINT(RT_DEBUG_TRACE, ("SYNC - 11g peer joined. down-grade to 11g TX rates \n"));
-								bRestart = TRUE;
-								NdisMoveMemory(pAd->StaActive.SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES);
-								pAd->StaActive.SupRateLen = SupRateLen;
-								NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
-								pAd->StaActive.ExtRateLen = ExtRateLen;
-								pAd->StaCfg.AdhocBGJoined = TRUE;
-								pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
-								AsicSetEdcaParm(pAd, NULL);
-							}
-
-							// this timestamp is for MlmePeriodicExec() to check if all 11g peers have left
-							pAd->StaCfg.Last11gBeaconRxTime = Now;
-							break;
-						}
-						else if (!pAd->StaCfg.AdhocBGJoined &&
-								 !pAd->StaCfg.AdhocBOnlyJoined &&
-								 (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40) &&
-								 (HtCapability.HtCapInfo.ChannelWidth == BW_20))
-						{
-							if (pAd->StaCfg.Adhoc20NJoined == FALSE)
-							{
-								pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
-
-								pAd->StaCfg.Adhoc20NJoined = TRUE;
-								NdisMoveMemory(&pAd->MlmeAux.HtCapability, &HtCapability, SIZE_HT_CAP_IE);
-								if (AddHtInfoLen != 0)
-									NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &AddHtInfo, AddHtInfoLen);
-								NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, HtCapability.MCSSet, 16);
-
-								RTMPCheckHt(pAd, Elem->Wcid, &pAd->MlmeAux.HtCapability, &pAd->MlmeAux.AddHtInfo);
-								COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
-								pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
-								bRestart = TRUE;
-								bnRestart = TRUE;
-							}
-							// this timestamp is for MlmePeriodicExec() to check if all 20MHz N peers have left
-							pAd->StaCfg.Last20NBeaconRxTime = Now;
-						}
-
-					}
-					else
-					{
-						RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
-						RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE);
-					}
-				}while (FALSE);
-
-				// If peer Adhoc is legacy mode, I don't need to call MlmeUpdateHtTxRates no matter I support HT or not
-				if ((bRestart == TRUE) && (bnRestart == FALSE))
-				{
-					MlmeUpdateTxRates(pAd, FALSE, 0);
-					MakeIbssBeacon(pAd);        // re-build BEACON frame
-					AsicEnableIbssSync(pAd);    // copy to on-chip memory
-				}
-				else if ((bRestart == TRUE) && (bnRestart == TRUE))
-				{
-					MlmeUpdateTxRates(pAd, FALSE, BSS0);
-					MlmeUpdateHtTxRates(pAd, BSS0);
-					MakeIbssBeacon(pAd);        // re-build BEACON frame
-					AsicEnableIbssSync(pAd);    // copy to on-chip memory
+				/* supported rates array may not be sorted. sort it and find the maximum rate */
+				for (idx = 0; idx < SupRateLen; idx++) {
+					if (MaxSupportedRateIn500Kbps <
+					    (SupRate[idx] & 0x7f))
+						MaxSupportedRateIn500Kbps =
+						    SupRate[idx] & 0x7f;
 				}
 
-				// At least another peer in this IBSS, declare MediaState as CONNECTED
-				if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-				{
-					OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
-
-					pAd->IndicateMediaState = NdisMediaStateConnected;
-					RTMP_IndicateMediaState(pAd);
-	                pAd->ExtraInfo = GENERAL_LINK_UP;
-					AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
-
-					// 2003/03/12 - john
-					// Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that
-					// "site survey" result should always include the current connected network.
-					//
-					Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
-					if (Bssidx == BSS_NOT_FOUND)
-					{
-						Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
-									&CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability,
-									&AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, RealRssi, TimeStamp, 0,
-									&EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
-					}
-					DBGPRINT(RT_DEBUG_TRACE, ("ADHOC  fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
+				for (idx = 0; idx < ExtRateLen; idx++) {
+					if (MaxSupportedRateIn500Kbps <
+					    (ExtRate[idx] & 0x7f))
+						MaxSupportedRateIn500Kbps =
+						    ExtRate[idx] & 0x7f;
 				}
 
-				// Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon.
-				// To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station.
-				if (ADHOC_ON(pAd) && (Elem->Wcid == RESERVED_WCID))
-				{
-					UCHAR	idx;
-					MAC_TABLE_ENTRY *pEntry;
-
-					// look up the existing table
-					pEntry = MacTableLookup(pAd, Addr2);
-					if (pEntry == NULL)
-					{
-						// Another adhoc joining, add to our MAC table.
-						pEntry = MacTableInsertEntry(pAd, Addr2, BSS0, FALSE);
-						if (pEntry)
-						{
-							pEntry->Sst = SST_ASSOC;
-							idx = pAd->StaCfg.DefaultKeyId;
-							// After InsertEntry, Write to ASIC on-chip table.
-							RT28XX_STA_SECURITY_INFO_ADD(pAd, BSS0, idx, pEntry);
-							DBGPRINT(RT_DEBUG_TRACE, ("ADHOC %x:%x:%x:%x:%x:%x  join in.Entry=%d\n", Addr2[0],Addr2[1],Addr2[2],Addr2[3],Addr2[4],Addr2[5], pEntry->Aid));
-
-							pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
-	                        if (HtCapabilityLen <= 0)
-	                        {
-	                            pEntry->HTPhyMode.field.STBC = 0;
-	                            pEntry->HTPhyMode.field.BW = 0;
-	                            pEntry->HTPhyMode.field.ShortGI = 0;
-	                            if ((SupRateLen+ExtRateLen <= 4) && (pAd->CommonCfg.Channel <= 14))
-	        					{
-	        						pEntry->HTPhyMode.field.MODE = MODE_CCK;
-	        					}
-	        					else
-	        					{
-	        						pEntry->HTPhyMode.field.MODE = MODE_OFDM;
-	        					}
-								MlmeUpdateTxRates(pAd, FALSE, 0);
-	                        }
-							else
-							{
-								MlmeUpdateTxRates(pAd, FALSE, 0);
-								MlmeUpdateHtTxRates(pAd, BSS0);
-							}
-
-	                        {
-	                            union iwreq_data    wrqu;
-	                            wext_notify_event_assoc(pAd);
-
-	                            memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
-	                            memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
-	                            wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
-
-	                        }
-						}
-					}
-				}
-#endif /* RT2860 */
-#ifdef RT2870
-				UCHAR			MaxSupportedRateIn500Kbps = 0;
-				UCHAR			idx;
-				MAC_TABLE_ENTRY *pEntry;
-
-				// supported rates array may not be sorted. sort it and find the maximum rate
-			    for (idx=0; idx<SupRateLen; idx++)
-			    {
-			        if (MaxSupportedRateIn500Kbps < (SupRate[idx] & 0x7f))
-			            MaxSupportedRateIn500Kbps = SupRate[idx] & 0x7f;
-			    }
-
-				for (idx=0; idx<ExtRateLen; idx++)
-			    {
-			        if (MaxSupportedRateIn500Kbps < (ExtRate[idx] & 0x7f))
-			            MaxSupportedRateIn500Kbps = ExtRate[idx] & 0x7f;
-			    }
-
-				// look up the existing table
+				/* look up the existing table */
 				pEntry = MacTableLookup(pAd, Addr2);
 
-				// Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon.
-				// To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station.
-				if ((ADHOC_ON(pAd) && (Elem->Wcid == RESERVED_WCID)) ||
-					(pEntry && ((pEntry->LastBeaconRxTime + ADHOC_ENTRY_BEACON_LOST_TIME) < Now)))
-				{
+				/* Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon. */
+				/* To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station. */
+				if ((ADHOC_ON(pAd)
+				     && (Elem->Wcid == RESERVED_WCID))
+				    || (pEntry
+					&&
+					((pEntry->LastBeaconRxTime +
+					  ADHOC_ENTRY_BEACON_LOST_TIME) <
+					 Now))) {
 					if (pEntry == NULL)
-						// Another adhoc joining, add to our MAC table.
-						pEntry = MacTableInsertEntry(pAd, Addr2, BSS0, FALSE);
+						/* Another adhoc joining, add to our MAC table. */
+						pEntry =
+						    MacTableInsertEntry(pAd,
+									Addr2,
+									BSS0,
+									FALSE);
 
-					if (StaAddMacTableEntry(pAd, pEntry, MaxSupportedRateIn500Kbps, &HtCapability, HtCapabilityLen, CapabilityInfo) == FALSE)
-					{
-						DBGPRINT(RT_DEBUG_TRACE, ("ADHOC - Add Entry failed.\n"));
+					if (StaAddMacTableEntry(pAd,
+								pEntry,
+								MaxSupportedRateIn500Kbps,
+								&HtCapability,
+								HtCapabilityLen,
+								&AddHtInfo,
+								AddHtInfoLen,
+								CapabilityInfo)
+					    == FALSE) {
+						DBGPRINT(RT_DEBUG_TRACE,
+							 ("ADHOC - Add Entry failed.\n"));
 						return;
 					}
 
 					if (pEntry &&
-						(Elem->Wcid == RESERVED_WCID))
-					{
+					    (Elem->Wcid == RESERVED_WCID)) {
 						idx = pAd->StaCfg.DefaultKeyId;
-						RT28XX_STA_SECURITY_INFO_ADD(pAd, BSS0, idx, pEntry);
+						RTMP_STA_SECURITY_INFO_ADD(pAd,
+									   BSS0,
+									   idx,
+									   pEntry);
 					}
 				}
 
 				if (pEntry && pEntry->ValidAsCLI)
 					pEntry->LastBeaconRxTime = Now;
 
-				// At least another peer in this IBSS, declare MediaState as CONNECTED
-				if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-				{
-					OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+				/* At least another peer in this IBSS, declare MediaState as CONNECTED */
+				if (!OPSTATUS_TEST_FLAG
+				    (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
+					OPSTATUS_SET_FLAG(pAd,
+							  fOP_STATUS_MEDIA_STATE_CONNECTED);
 
-					pAd->IndicateMediaState = NdisMediaStateConnected;
+					pAd->IndicateMediaState =
+					    NdisMediaStateConnected;
 					RTMP_IndicateMediaState(pAd);
-	                pAd->ExtraInfo = GENERAL_LINK_UP;
+					pAd->ExtraInfo = GENERAL_LINK_UP;
 					AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
 
-					// 2003/03/12 - john
-					// Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that
-					// "site survey" result should always include the current connected network.
-					//
-					Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
-					if (Bssidx == BSS_NOT_FOUND)
-					{
-						Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
-									&CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability,
-									&AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, RealRssi, TimeStamp, 0,
-									&EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
+					/* 2003/03/12 - john */
+					/* Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that */
+					/* "site survey" result should always include the current connected network. */
+					/* */
+					Bssidx =
+					    BssTableSearch(&pAd->ScanTab, Bssid,
+							   Channel);
+					if (Bssidx == BSS_NOT_FOUND) {
+						Bssidx =
+						    BssTableSetEntry(pAd,
+								     &pAd->
+								     ScanTab,
+								     Bssid,
+								     Ssid,
+								     SsidLen,
+								     BssType,
+								     BeaconPeriod,
+								     &CfParm,
+								     AtimWin,
+								     CapabilityInfo,
+								     SupRate,
+								     SupRateLen,
+								     ExtRate,
+								     ExtRateLen,
+								     &HtCapability,
+								     &AddHtInfo,
+								     HtCapabilityLen,
+								     AddHtInfoLen,
+								     NewExtChannelOffset,
+								     Channel,
+								     RealRssi,
+								     TimeStamp,
+								     0,
+								     &EdcaParm,
+								     &QosCapability,
+								     &QbssLoad,
+								     LenVIE,
+								     pVIE);
 					}
-					DBGPRINT(RT_DEBUG_TRACE, ("ADHOC  fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
+					DBGPRINT(RT_DEBUG_TRACE,
+						 ("ADHOC  fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
 				}
-#endif /* RT2870 */
 			}
 
-			if (INFRA_ON(pAd))
-			{
+			if (INFRA_ON(pAd)) {
 				BOOLEAN bUseShortSlot, bUseBGProtection;
 
-				// decide to use/change to -
-				//      1. long slot (20 us) or short slot (9 us) time
-				//      2. turn on/off RTS/CTS and/or CTS-to-self protection
-				//      3. short preamble
+				/* decide to use/change to - */
+				/*      1. long slot (20 us) or short slot (9 us) time */
+				/*      2. turn on/off RTS/CTS and/or CTS-to-self protection */
+				/*      3. short preamble */
 
-				//bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo);
-				bUseShortSlot = CAP_IS_SHORT_SLOT(CapabilityInfo);
-				if (bUseShortSlot != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))
+				/*bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo); */
+				bUseShortSlot =
+				    CAP_IS_SHORT_SLOT(CapabilityInfo);
+				if (bUseShortSlot !=
+				    OPSTATUS_TEST_FLAG(pAd,
+						       fOP_STATUS_SHORT_SLOT_INUSED))
 					AsicSetSlotTime(pAd, bUseShortSlot);
 
-				bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) ||    // always use
-								   ((pAd->CommonCfg.UseBGProtection == 0) && ERP_IS_USE_PROTECTION(Erp));
+				bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) ||	/* always use */
+				    ((pAd->CommonCfg.UseBGProtection == 0)
+				     && ERP_IS_USE_PROTECTION(Erp));
 
-				if (pAd->CommonCfg.Channel > 14) // always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP
+				if (pAd->CommonCfg.Channel > 14)	/* always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP */
 					bUseBGProtection = FALSE;
 
-				if (bUseBGProtection != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
+				if (bUseBGProtection !=
+				    OPSTATUS_TEST_FLAG(pAd,
+						       fOP_STATUS_BG_PROTECTION_INUSED))
 				{
-					if (bUseBGProtection)
-					{
-						OPSTATUS_SET_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
-						AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),FALSE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
-					}
-					else
-					{
-						OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
-						AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),TRUE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
+					if (bUseBGProtection) {
+						OPSTATUS_SET_FLAG(pAd,
+								  fOP_STATUS_BG_PROTECTION_INUSED);
+						AsicUpdateProtect(pAd,
+								  pAd->MlmeAux.
+								  AddHtInfo.
+								  AddHtInfo2.
+								  OperaionMode,
+								  (OFDMSETPROTECT
+								   |
+								   CCKSETPROTECT
+								   |
+								   ALLN_SETPROTECT),
+								  FALSE,
+								  (pAd->MlmeAux.
+								   AddHtInfo.
+								   AddHtInfo2.
+								   NonGfPresent
+								   == 1));
+					} else {
+						OPSTATUS_CLEAR_FLAG(pAd,
+								    fOP_STATUS_BG_PROTECTION_INUSED);
+						AsicUpdateProtect(pAd,
+								  pAd->MlmeAux.
+								  AddHtInfo.
+								  AddHtInfo2.
+								  OperaionMode,
+								  (OFDMSETPROTECT
+								   |
+								   CCKSETPROTECT
+								   |
+								   ALLN_SETPROTECT),
+								  TRUE,
+								  (pAd->MlmeAux.
+								   AddHtInfo.
+								   AddHtInfo2.
+								   NonGfPresent
+								   == 1));
 					}
 
-					DBGPRINT(RT_DEBUG_WARN, ("SYNC - AP changed B/G protection to %d\n", bUseBGProtection));
+					DBGPRINT(RT_DEBUG_WARN,
+						 ("SYNC - AP changed B/G protection to %d\n",
+						  bUseBGProtection));
 				}
-
-				// check Ht protection mode. and adhere to the Non-GF device indication by AP.
+				/* check Ht protection mode. and adhere to the Non-GF device indication by AP. */
 				if ((AddHtInfoLen != 0) &&
-					((AddHtInfo.AddHtInfo2.OperaionMode != pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode) ||
-					(AddHtInfo.AddHtInfo2.NonGfPresent != pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent)))
-				{
-					pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent = AddHtInfo.AddHtInfo2.NonGfPresent;
-					pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode = AddHtInfo.AddHtInfo2.OperaionMode;
-					if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
-				{
-						AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
-					}
-					else
-						AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
+				    ((AddHtInfo.AddHtInfo2.OperaionMode !=
+				      pAd->MlmeAux.AddHtInfo.AddHtInfo2.
+				      OperaionMode)
+				     || (AddHtInfo.AddHtInfo2.NonGfPresent !=
+					 pAd->MlmeAux.AddHtInfo.AddHtInfo2.
+					 NonGfPresent))) {
+					pAd->MlmeAux.AddHtInfo.AddHtInfo2.
+					    NonGfPresent =
+					    AddHtInfo.AddHtInfo2.NonGfPresent;
+					pAd->MlmeAux.AddHtInfo.AddHtInfo2.
+					    OperaionMode =
+					    AddHtInfo.AddHtInfo2.OperaionMode;
+					if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.
+					    NonGfPresent == 1) {
+						AsicUpdateProtect(pAd,
+								  pAd->MlmeAux.
+								  AddHtInfo.
+								  AddHtInfo2.
+								  OperaionMode,
+								  ALLN_SETPROTECT,
+								  FALSE, TRUE);
+					} else
+						AsicUpdateProtect(pAd,
+								  pAd->MlmeAux.
+								  AddHtInfo.
+								  AddHtInfo2.
+								  OperaionMode,
+								  ALLN_SETPROTECT,
+								  FALSE, FALSE);
 
-					DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP changed N OperaionMode to %d\n", pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode));
+					DBGPRINT(RT_DEBUG_TRACE,
+						 ("SYNC - AP changed N OperaionMode to %d\n",
+						  pAd->MlmeAux.AddHtInfo.
+						  AddHtInfo2.OperaionMode));
 				}
 
-				if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED) &&
-					ERP_IS_USE_BARKER_PREAMBLE(Erp))
-				{
-					MlmeSetTxPreamble(pAd, Rt802_11PreambleLong);
-					DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP forced to use LONG preamble\n"));
+				if (OPSTATUS_TEST_FLAG
+				    (pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED)
+				    && ERP_IS_USE_BARKER_PREAMBLE(Erp)) {
+					MlmeSetTxPreamble(pAd,
+							  Rt802_11PreambleLong);
+					DBGPRINT(RT_DEBUG_TRACE,
+						 ("SYNC - AP forced to use long preamble\n"));
 				}
 
-				if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)    &&
-					(EdcaParm.bValid == TRUE)                          &&
-					(EdcaParm.EdcaUpdateCount != pAd->CommonCfg.APEdcaParm.EdcaUpdateCount))
-				{
-					DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP change EDCA parameters(from %d to %d)\n",
-						pAd->CommonCfg.APEdcaParm.EdcaUpdateCount,
-						EdcaParm.EdcaUpdateCount));
+				if (OPSTATUS_TEST_FLAG
+				    (pAd, fOP_STATUS_WMM_INUSED)
+				    && (EdcaParm.bValid == TRUE)
+				    && (EdcaParm.EdcaUpdateCount !=
+					pAd->CommonCfg.APEdcaParm.
+					EdcaUpdateCount)) {
+					DBGPRINT(RT_DEBUG_TRACE,
+						 ("SYNC - AP change EDCA parameters(from %d to %d)\n",
+						  pAd->CommonCfg.APEdcaParm.
+						  EdcaUpdateCount,
+						  EdcaParm.EdcaUpdateCount));
 					AsicSetEdcaParm(pAd, &EdcaParm);
 				}
-
-				// copy QOS related information
-				NdisMoveMemory(&pAd->CommonCfg.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM));
-				NdisMoveMemory(&pAd->CommonCfg.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM));
+				/* copy QOS related information */
+				NdisMoveMemory(&pAd->CommonCfg.APQbssLoad,
+					       &QbssLoad,
+					       sizeof(struct rt_qbss_load_parm));
+				NdisMoveMemory(&pAd->CommonCfg.APQosCapability,
+					       &QosCapability,
+					       sizeof(struct rt_qos_capability_parm));
 			}
-
-			// only INFRASTRUCTURE mode support power-saving feature
-			if ((INFRA_ON(pAd) && (pAd->StaCfg.Psm == PWR_SAVE)) || (pAd->CommonCfg.bAPSDForcePowerSave))
-			{
-				UCHAR FreeNumber;
-				//  1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL
-				//  2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE
-				//  3. we have outgoing frames in TxRing or MgmtRing, better stay AWAKE
-				//  4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE
-				//  5. otherwise, put PHY back to sleep to save battery.
-				if (MessageToMe)
-				{
-#ifdef RT2860
-					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
-					{
-						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
+			/* only INFRASTRUCTURE mode support power-saving feature */
+			if ((INFRA_ON(pAd) && (pAd->StaCfg.Psm == PWR_SAVE))
+			    || (pAd->CommonCfg.bAPSDForcePowerSave)) {
+				u8 FreeNumber;
+				/*  1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL */
+				/*  2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE */
+				/*  3. we have outgoing frames in TxRing or MgmtRing, better stay AWAKE */
+				/*  4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE */
+				/*  5. otherwise, put PHY back to sleep to save battery. */
+				if (MessageToMe) {
+#ifdef RTMP_MAC_PCI
+					if (OPSTATUS_TEST_FLAG
+					    (pAd, fOP_STATUS_PCIE_DEVICE)) {
+						/* Restore to correct BBP R3 value */
+						if (pAd->Antenna.field.RxPath >
+						    1)
+							RTMP_BBP_IO_WRITE8_BY_REG_ID
+							    (pAd, BBP_R3,
+							     pAd->StaCfg.BBPR3);
+						/* Turn clk to 80Mhz. */
 					}
-#endif
-					if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable &&
-						pAd->CommonCfg.bAPSDAC_BE && pAd->CommonCfg.bAPSDAC_BK && pAd->CommonCfg.bAPSDAC_VI && pAd->CommonCfg.bAPSDAC_VO)
-					{
-						pAd->CommonCfg.bNeedSendTriggerFrame = TRUE;
-					}
-					else
-						RT28XX_PS_POLL_ENQUEUE(pAd);
-				}
-				else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM))
+#endif /* RTMP_MAC_PCI // */
+					if (pAd->CommonCfg.bAPSDCapable
+					    && pAd->CommonCfg.APEdcaParm.
+					    bAPSDCapable
+					    && pAd->CommonCfg.bAPSDAC_BE
+					    && pAd->CommonCfg.bAPSDAC_BK
+					    && pAd->CommonCfg.bAPSDAC_VI
+					    && pAd->CommonCfg.bAPSDAC_VO) {
+						pAd->CommonCfg.
+						    bNeedSendTriggerFrame =
+						    TRUE;
+					} else
+						RTMP_PS_POLL_ENQUEUE(pAd);
+				} else if (BcastFlag && (DtimCount == 0)
+					   && OPSTATUS_TEST_FLAG(pAd,
+								 fOP_STATUS_RECEIVE_DTIM))
 				{
-#ifdef RT2860
-					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
-					{
-						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
+#ifdef RTMP_MAC_PCI
+					if (OPSTATUS_TEST_FLAG
+					    (pAd, fOP_STATUS_PCIE_DEVICE)) {
+						if (pAd->Antenna.field.RxPath >
+						    1)
+							RTMP_BBP_IO_WRITE8_BY_REG_ID
+							    (pAd, BBP_R3,
+							     pAd->StaCfg.BBPR3);
 					}
-#endif
-				}
-				else if ((pAd->TxSwQueue[QID_AC_BK].Number != 0)													||
-						(pAd->TxSwQueue[QID_AC_BE].Number != 0)														||
-						(pAd->TxSwQueue[QID_AC_VI].Number != 0)														||
-						(pAd->TxSwQueue[QID_AC_VO].Number != 0)														||
-						(RTMPFreeTXDRequest(pAd, QID_AC_BK, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS)	||
-						(RTMPFreeTXDRequest(pAd, QID_AC_BE, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS)	||
-						(RTMPFreeTXDRequest(pAd, QID_AC_VI, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS)	||
-						(RTMPFreeTXDRequest(pAd, QID_AC_VO, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS)	||
-						(RTMPFreeTXDRequest(pAd, QID_MGMT, MGMT_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS))
-				{
-					// TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme
-					// can we cheat here (i.e. just check MGMT & AC_BE) for better performance?
-#ifdef RT2860
-					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
-					{
-						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
+#endif /* RTMP_MAC_PCI // */
+				} else
+				    if ((pAd->TxSwQueue[QID_AC_BK].Number != 0)
+					|| (pAd->TxSwQueue[QID_AC_BE].Number !=
+					    0)
+					|| (pAd->TxSwQueue[QID_AC_VI].Number !=
+					    0)
+					|| (pAd->TxSwQueue[QID_AC_VO].Number !=
+					    0)
+					||
+					(RTMPFreeTXDRequest
+					 (pAd, QID_AC_BK, TX_RING_SIZE - 1,
+					  &FreeNumber) != NDIS_STATUS_SUCCESS)
+					||
+					(RTMPFreeTXDRequest
+					 (pAd, QID_AC_BE, TX_RING_SIZE - 1,
+					  &FreeNumber) != NDIS_STATUS_SUCCESS)
+					||
+					(RTMPFreeTXDRequest
+					 (pAd, QID_AC_VI, TX_RING_SIZE - 1,
+					  &FreeNumber) != NDIS_STATUS_SUCCESS)
+					||
+					(RTMPFreeTXDRequest
+					 (pAd, QID_AC_VO, TX_RING_SIZE - 1,
+					  &FreeNumber) != NDIS_STATUS_SUCCESS)
+					||
+					(RTMPFreeTXDRequest
+					 (pAd, QID_MGMT, MGMT_RING_SIZE - 1,
+					  &FreeNumber) !=
+					 NDIS_STATUS_SUCCESS)) {
+					/* TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme */
+					/* can we cheat here (i.e. just check MGMT & AC_BE) for better performance? */
+#ifdef RTMP_MAC_PCI
+					if (OPSTATUS_TEST_FLAG
+					    (pAd, fOP_STATUS_PCIE_DEVICE)) {
+						if (pAd->Antenna.field.RxPath >
+						    1)
+							RTMP_BBP_IO_WRITE8_BY_REG_ID
+							    (pAd, BBP_R3,
+							     pAd->StaCfg.BBPR3);
 					}
-#endif
-				}
-				else
-				{
-					USHORT NextDtim = DtimCount;
+#endif /* RTMP_MAC_PCI // */
+				} else {
+					if ((pAd->CommonCfg.
+					     bACMAPSDTr[QID_AC_VO])
+					    || (pAd->CommonCfg.
+						bACMAPSDTr[QID_AC_VI])
+					    || (pAd->CommonCfg.
+						bACMAPSDTr[QID_AC_BK])
+					    || (pAd->CommonCfg.
+						bACMAPSDTr[QID_AC_BE])) {
+						/*
+						   WMM Spec v1.0 3.6.2.4,
+						   The WMM STA shall remain awake until it receives a
+						   QoS Data or Null frame addressed to it, with the
+						   EOSP subfield in QoS Control field set to 1.
 
-					if (NextDtim == 0)
-						NextDtim = DtimPeriod;
+						   So we can not sleep here or we will suffer a case:
 
-					TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
-					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
-						TbttNumToNextWakeUp = NextDtim;
+						   PS Management Frame -->
+						   Trigger frame -->
+						   Beacon (TIM=0) (Beacon is closer to Trig frame) -->
+						   Station goes to sleep -->
+						   AP delivery queued UAPSD packets -->
+						   Station can NOT receive the reply
 
-					if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-					{
-#ifdef RT2860
-						// Set a flag to go to sleep . Then after parse this RxDoneInterrupt, will go to sleep mode.
-						RTMP_SET_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
-						pAd->ThisTbttNumToNextWakeUp = TbttNumToNextWakeUp;
-#endif
-#ifdef RT2870
-						AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
-#endif
+						   Maybe we need a timeout timer to avoid that we do
+						   NOT receive the EOSP frame.
+
+						   We can not use More Data to check if SP is ended
+						   due to MaxSPLength.
+						 */
+					} else {
+						u16 NextDtim = DtimCount;
+
+						if (NextDtim == 0)
+							NextDtim = DtimPeriod;
+
+						TbttNumToNextWakeUp =
+						    pAd->StaCfg.
+						    DefaultListenCount;
+						if (OPSTATUS_TEST_FLAG
+						    (pAd,
+						     fOP_STATUS_RECEIVE_DTIM)
+						    && (TbttNumToNextWakeUp >
+							NextDtim))
+							TbttNumToNextWakeUp =
+							    NextDtim;
+
+						if (!OPSTATUS_TEST_FLAG
+						    (pAd, fOP_STATUS_DOZE)) {
+							/* Set a flag to go to sleep . Then after parse this RxDoneInterrupt, will go to sleep mode. */
+							pAd->
+							    ThisTbttNumToNextWakeUp
+							    =
+							    TbttNumToNextWakeUp;
+							AsicSleepThenAutoWakeup
+							    (pAd,
+							     pAd->
+							     ThisTbttNumToNextWakeUp);
+						}
 					}
 				}
 			}
 		}
-		// not my BSSID, ignore it
+		/* not my BSSID, ignore it */
 	}
-	// sanity check fail, ignore this frame
+	/* sanity check fail, ignore this frame */
 }
 
 /*
@@ -1612,116 +1703,126 @@
 		Receive PROBE REQ from remote peer when operating in IBSS mode
 	==========================================================================
  */
-VOID PeerProbeReqAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void PeerProbeReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	UCHAR         Addr2[MAC_ADDR_LEN];
-	CHAR          Ssid[MAX_LEN_OF_SSID];
-	UCHAR         SsidLen;
-	UCHAR		  HtLen, AddHtLen, NewExtLen;
-	HEADER_802_11 ProbeRspHdr;
-	NDIS_STATUS   NStatus;
-	PUCHAR        pOutBuffer = NULL;
-	ULONG         FrameLen = 0;
+	u8 Addr2[MAC_ADDR_LEN];
+	char Ssid[MAX_LEN_OF_SSID];
+	u8 SsidLen;
+	u8 HtLen, AddHtLen, NewExtLen;
+	struct rt_header_802_11 ProbeRspHdr;
+	int NStatus;
+	u8 *pOutBuffer = NULL;
+	unsigned long FrameLen = 0;
 	LARGE_INTEGER FakeTimestamp;
-	UCHAR         DsLen = 1, IbssLen = 2;
-	UCHAR         LocalErpIe[3] = {IE_ERP, 1, 0};
-	BOOLEAN       Privacy;
-	USHORT        CapabilityInfo;
-	UCHAR		  RSNIe = IE_WPA;
+	u8 DsLen = 1, IbssLen = 2;
+	u8 LocalErpIe[3] = { IE_ERP, 1, 0 };
+	BOOLEAN Privacy;
+	u16 CapabilityInfo;
+	u8 RSNIe = IE_WPA;
 
-	if (! ADHOC_ON(pAd))
+	if (!ADHOC_ON(pAd))
 		return;
 
-	if (PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen))
-	{
-		if ((SsidLen == 0) || SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
-		{
-			// allocate and send out ProbeRsp frame
-			NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
+	if (PeerProbeReqSanity
+	    (pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen)) {
+		if ((SsidLen == 0)
+		    || SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid,
+				  pAd->CommonCfg.SsidLen)) {
+			/* allocate and send out ProbeRsp frame */
+			NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
 			if (NStatus != NDIS_STATUS_SUCCESS)
 				return;
 
-			//pAd->StaCfg.AtimWin = 0;  // ??????
+			/*pAd->StaCfg.AtimWin = 0;  // ?????? */
 
-			Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
-					  (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
-					  (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
-			CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
+			Privacy =
+			    (pAd->StaCfg.WepStatus ==
+			     Ndis802_11Encryption1Enabled)
+			    || (pAd->StaCfg.WepStatus ==
+				Ndis802_11Encryption2Enabled)
+			    || (pAd->StaCfg.WepStatus ==
+				Ndis802_11Encryption3Enabled);
+			CapabilityInfo =
+			    CAP_GENERATE(0, 1, Privacy,
+					 (pAd->CommonCfg.TxPreamble ==
+					  Rt802_11PreambleShort), 0, 0);
 
-			MakeOutgoingFrame(pOutBuffer,                   &FrameLen,
-							  sizeof(HEADER_802_11),        &ProbeRspHdr,
-							  TIMESTAMP_LEN,                &FakeTimestamp,
-							  2,                            &pAd->CommonCfg.BeaconPeriod,
-							  2,                            &CapabilityInfo,
-							  1,                            &SsidIe,
-							  1,                            &pAd->CommonCfg.SsidLen,
-							  pAd->CommonCfg.SsidLen,       pAd->CommonCfg.Ssid,
-							  1,                            &SupRateIe,
-							  1,                            &pAd->StaActive.SupRateLen,
-							  pAd->StaActive.SupRateLen,    pAd->StaActive.SupRate,
-							  1,                            &DsIe,
-							  1,                            &DsLen,
-							  1,                            &pAd->CommonCfg.Channel,
-							  1,                            &IbssIe,
-							  1,                            &IbssLen,
-							  2,                            &pAd->StaActive.AtimWin,
-							  END_OF_ARGS);
+			MakeOutgoingFrame(pOutBuffer, &FrameLen,
+					  sizeof(struct rt_header_802_11), &ProbeRspHdr,
+					  TIMESTAMP_LEN, &FakeTimestamp,
+					  2, &pAd->CommonCfg.BeaconPeriod,
+					  2, &CapabilityInfo,
+					  1, &SsidIe,
+					  1, &pAd->CommonCfg.SsidLen,
+					  pAd->CommonCfg.SsidLen,
+					  pAd->CommonCfg.Ssid, 1, &SupRateIe, 1,
+					  &pAd->StaActive.SupRateLen,
+					  pAd->StaActive.SupRateLen,
+					  pAd->StaActive.SupRate, 1, &DsIe, 1,
+					  &DsLen, 1, &pAd->CommonCfg.Channel, 1,
+					  &IbssIe, 1, &IbssLen, 2,
+					  &pAd->StaActive.AtimWin, END_OF_ARGS);
 
-			if (pAd->StaActive.ExtRateLen)
-			{
-				ULONG tmp;
-				MakeOutgoingFrame(pOutBuffer + FrameLen,        &tmp,
-								  3,                            LocalErpIe,
-								  1,                            &ExtRateIe,
-								  1,                            &pAd->StaActive.ExtRateLen,
-								  pAd->StaActive.ExtRateLen,    &pAd->StaActive.ExtRate,
-								  END_OF_ARGS);
+			if (pAd->StaActive.ExtRateLen) {
+				unsigned long tmp;
+				MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+						  3, LocalErpIe,
+						  1, &ExtRateIe,
+						  1, &pAd->StaActive.ExtRateLen,
+						  pAd->StaActive.ExtRateLen,
+						  &pAd->StaActive.ExtRate,
+						  END_OF_ARGS);
+				FrameLen += tmp;
+			}
+			/* If adhoc secruity is set for WPA-None, append the cipher suite IE */
+			if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) {
+				unsigned long tmp;
+				MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+						  1, &RSNIe,
+						  1, &pAd->StaCfg.RSNIE_Len,
+						  pAd->StaCfg.RSNIE_Len,
+						  pAd->StaCfg.RSN_IE,
+						  END_OF_ARGS);
 				FrameLen += tmp;
 			}
 
-			// If adhoc secruity is set for WPA-None, append the cipher suite IE
-			if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
-			{
-				ULONG tmp;
-				MakeOutgoingFrame(pOutBuffer + FrameLen,        	&tmp,
-						  			1,                              &RSNIe,
-						  			1,                            	&pAd->StaCfg.RSNIE_Len,
-						  			pAd->StaCfg.RSNIE_Len,      	pAd->StaCfg.RSN_IE,
-						  			END_OF_ARGS);
-				FrameLen += tmp;
-			}
-
-			if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
-			{
-				ULONG TmpLen;
-				UCHAR	BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
+			if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) {
+				unsigned long TmpLen;
+				u8 BROADCOM[4] = { 0x0, 0x90, 0x4c, 0x33 };
 				HtLen = sizeof(pAd->CommonCfg.HtCapability);
 				AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo);
 				NewExtLen = 1;
-				//New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame
-				if (pAd->bBroadComHT == TRUE)
-				{
-					MakeOutgoingFrame(pOutBuffer + FrameLen,            &TmpLen,
-								  1,                                &WpaIe,
-								  4,                                &BROADCOM[0],
-								 pAd->MlmeAux.HtCapabilityLen,          &pAd->MlmeAux.HtCapability,
-								  END_OF_ARGS);
-				}
-				else
-				{
-				MakeOutgoingFrame(pOutBuffer + FrameLen,            &TmpLen,
-								  1,                                &HtCapIe,
-								  1,                                &HtLen,
-								 sizeof(HT_CAPABILITY_IE),          &pAd->CommonCfg.HtCapability,
-								  1,                                &AddHtInfoIe,
-								  1,                                &AddHtLen,
-								 sizeof(ADD_HT_INFO_IE),          &pAd->CommonCfg.AddHTInfo,
-								  1,                                &NewExtChanIe,
-								  1,                                &NewExtLen,
-								 sizeof(NEW_EXT_CHAN_IE),          &pAd->CommonCfg.NewExtChanOffset,
-								  END_OF_ARGS);
+				/*New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame */
+				if (pAd->bBroadComHT == TRUE) {
+					MakeOutgoingFrame(pOutBuffer + FrameLen,
+							  &TmpLen, 1, &WpaIe, 4,
+							  &BROADCOM[0],
+							  pAd->MlmeAux.
+							  HtCapabilityLen,
+							  &pAd->MlmeAux.
+							  HtCapability,
+							  END_OF_ARGS);
+				} else {
+					MakeOutgoingFrame(pOutBuffer + FrameLen,
+							  &TmpLen, 1, &HtCapIe,
+							  1, &HtLen,
+							  sizeof
+							  (struct rt_ht_capability_ie),
+							  &pAd->CommonCfg.
+							  HtCapability, 1,
+							  &AddHtInfoIe, 1,
+							  &AddHtLen,
+							  sizeof
+							  (struct rt_add_ht_info_ie),
+							  &pAd->CommonCfg.
+							  AddHTInfo, 1,
+							  &NewExtChanIe, 1,
+							  &NewExtLen,
+							  sizeof
+							  (struct rt_new_ext_chan_ie),
+							  &pAd->CommonCfg.
+							  NewExtChanOffset,
+							  END_OF_ARGS);
 				}
 				FrameLen += TmpLen;
 			}
@@ -1732,11 +1833,9 @@
 	}
 }
 
-VOID BeaconTimeoutAtJoinAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void BeaconTimeoutAtJoinAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	USHORT Status;
+	u16 Status;
 	DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeoutAtJoinAction\n"));
 	pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
 	Status = MLME_REJ_TIMEOUT;
@@ -1749,20 +1848,18 @@
 		Scan timeout procedure. basically add channel index by 1 and rescan
 	==========================================================================
  */
-VOID ScanTimeoutAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void ScanTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
 	pAd->MlmeAux.Channel = NextChannel(pAd, pAd->MlmeAux.Channel);
 
-	// Only one channel scanned for CISCO beacon request
+	/* Only one channel scanned for CISCO beacon request */
 	if ((pAd->MlmeAux.ScanType == SCAN_CISCO_ACTIVE) ||
-		(pAd->MlmeAux.ScanType == SCAN_CISCO_PASSIVE) ||
-		(pAd->MlmeAux.ScanType == SCAN_CISCO_NOISE) ||
-		(pAd->MlmeAux.ScanType == SCAN_CISCO_CHANNEL_LOAD))
+	    (pAd->MlmeAux.ScanType == SCAN_CISCO_PASSIVE) ||
+	    (pAd->MlmeAux.ScanType == SCAN_CISCO_NOISE) ||
+	    (pAd->MlmeAux.ScanType == SCAN_CISCO_CHANNEL_LOAD))
 		pAd->MlmeAux.Channel = 0;
 
-	// this routine will stop if pAd->MlmeAux.Channel == 0
+	/* this routine will stop if pAd->MlmeAux.Channel == 0 */
 	ScanNextChannel(pAd);
 }
 
@@ -1771,12 +1868,12 @@
 	Description:
 	==========================================================================
  */
-VOID InvalidStateWhenScan(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void InvalidStateWhenScan(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	USHORT Status;
-	DBGPRINT(RT_DEBUG_TRACE, ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
+	u16 Status;
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n",
+		  pAd->Mlme.SyncMachine.CurrState));
 	pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
 	Status = MLME_STATE_MACHINE_REJECT;
 	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
@@ -1787,12 +1884,12 @@
 	Description:
 	==========================================================================
  */
-VOID InvalidStateWhenJoin(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void InvalidStateWhenJoin(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	USHORT Status;
-	DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenJoin(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
+	u16 Status;
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("InvalidStateWhenJoin(state=%ld). Reset SYNC machine\n",
+		  pAd->Mlme.SyncMachine.CurrState));
 	pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
 	Status = MLME_STATE_MACHINE_REJECT;
 	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
@@ -1803,12 +1900,12 @@
 	Description:
 	==========================================================================
  */
-VOID InvalidStateWhenStart(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void InvalidStateWhenStart(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	USHORT Status;
-	DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenStart(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
+	u16 Status;
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("InvalidStateWhenStart(state=%ld). Reset SYNC machine\n",
+		  pAd->Mlme.SyncMachine.CurrState));
 	pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
 	Status = MLME_STATE_MACHINE_REJECT;
 	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
@@ -1822,54 +1919,51 @@
 
 	==========================================================================
  */
-VOID EnqueuePsPoll(
-	IN PRTMP_ADAPTER pAd)
+void EnqueuePsPoll(struct rt_rtmp_adapter *pAd)
 {
-	if (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeLegacy_PSP)
-    	pAd->PsPollFrame.FC.PwrMgmt = PWR_SAVE;
-	MiniportMMRequest(pAd, 0, (PUCHAR)&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
-}
 
+	if (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeLegacy_PSP)
+		pAd->PsPollFrame.FC.PwrMgmt = PWR_SAVE;
+	MiniportMMRequest(pAd, 0, (u8 *)& pAd->PsPollFrame,
+			  sizeof(struct rt_pspoll_frame));
+}
 
 /*
 	==========================================================================
 	Description:
 	==========================================================================
  */
-VOID EnqueueProbeRequest(
-	IN PRTMP_ADAPTER pAd)
+void EnqueueProbeRequest(struct rt_rtmp_adapter *pAd)
 {
-	NDIS_STATUS     NState;
-	PUCHAR          pOutBuffer;
-	ULONG           FrameLen = 0;
-	HEADER_802_11   Hdr80211;
+	int NState;
+	u8 *pOutBuffer;
+	unsigned long FrameLen = 0;
+	struct rt_header_802_11 Hdr80211;
 
 	DBGPRINT(RT_DEBUG_TRACE, ("force out a ProbeRequest ...\n"));
 
-	NState = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-	if (NState == NDIS_STATUS_SUCCESS)
-	{
-		MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
+	NState = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
+	if (NState == NDIS_STATUS_SUCCESS) {
+		MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0,
+				 BROADCAST_ADDR, BROADCAST_ADDR);
 
-		// this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse
-		MakeOutgoingFrame(pOutBuffer,                     &FrameLen,
-						  sizeof(HEADER_802_11),          &Hdr80211,
-						  1,                              &SsidIe,
-						  1,                              &pAd->CommonCfg.SsidLen,
-						  pAd->CommonCfg.SsidLen,		  pAd->CommonCfg.Ssid,
-						  1,                              &SupRateIe,
-						  1,                              &pAd->StaActive.SupRateLen,
-						  pAd->StaActive.SupRateLen,      pAd->StaActive.SupRate,
-						  END_OF_ARGS);
+		/* this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse */
+		MakeOutgoingFrame(pOutBuffer, &FrameLen,
+				  sizeof(struct rt_header_802_11), &Hdr80211,
+				  1, &SsidIe,
+				  1, &pAd->CommonCfg.SsidLen,
+				  pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
+				  1, &SupRateIe,
+				  1, &pAd->StaActive.SupRateLen,
+				  pAd->StaActive.SupRateLen,
+				  pAd->StaActive.SupRate, END_OF_ARGS);
 		MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
 		MlmeFreeMemory(pAd, pOutBuffer);
 	}
 
 }
 
-BOOLEAN ScanRunning(
-		IN PRTMP_ADAPTER pAd)
+BOOLEAN ScanRunning(struct rt_rtmp_adapter *pAd)
 {
 	return (pAd->Mlme.SyncMachine.CurrState == SCAN_LISTEN) ? TRUE : FALSE;
 }
-
diff --git a/drivers/staging/rt2860/sta/wpa.c b/drivers/staging/rt2860/sta/wpa.c
index 8c34e39..69b8a24 100644
--- a/drivers/staging/rt2860/sta/wpa.c
+++ b/drivers/staging/rt2860/sta/wpa.c
@@ -37,1813 +37,7 @@
 */
 #include "../rt_config.h"
 
-#define		WPARSNIE	0xdd
-#define		WPA2RSNIE	0x30
-
-//extern UCHAR BIT8[];
-UCHAR	CipherWpaPskTkip[] = {
-		0xDD, 0x16,				// RSN IE
-		0x00, 0x50, 0xf2, 0x01,	// oui
-		0x01, 0x00,				// Version
-		0x00, 0x50, 0xf2, 0x02,	// Multicast
-		0x01, 0x00,				// Number of unicast
-		0x00, 0x50, 0xf2, 0x02,	// unicast
-		0x01, 0x00,				// number of authentication method
-		0x00, 0x50, 0xf2, 0x02	// authentication
-		};
-UCHAR	CipherWpaPskTkipLen = (sizeof(CipherWpaPskTkip) / sizeof(UCHAR));
-
-UCHAR	CipherWpaPskAes[] = {
-		0xDD, 0x16, 			// RSN IE
-		0x00, 0x50, 0xf2, 0x01,	// oui
-		0x01, 0x00,				// Version
-		0x00, 0x50, 0xf2, 0x04,	// Multicast
-		0x01, 0x00,				// Number of unicast
-		0x00, 0x50, 0xf2, 0x04,	// unicast
-		0x01, 0x00,				// number of authentication method
-		0x00, 0x50, 0xf2, 0x02	// authentication
-		};
-UCHAR	CipherWpaPskAesLen = (sizeof(CipherWpaPskAes) / sizeof(UCHAR));
-
-UCHAR	CipherSuiteCiscoCCKM[] = {
-		0xDD, 0x16,				// RSN IE
-		0x00, 0x50, 0xf2, 0x01, // oui
-		0x01, 0x00,				// Version
-		0x00, 0x40, 0x96, 0x01, // Multicast
-		0x01, 0x00,				// Number of uicast
-		0x00, 0x40, 0x96, 0x01, // unicast
-		0x01, 0x00,				// number of authentication method
-		0x00, 0x40, 0x96, 0x00  // Authentication
-		};
-UCHAR	CipherSuiteCiscoCCKMLen = (sizeof(CipherSuiteCiscoCCKM) / sizeof(UCHAR));
-
-UCHAR	CipherSuiteCiscoCCKM24[] = {
-		0xDD, 0x18,				// RSN IE
-		0x00, 0x50, 0xf2, 0x01, // oui
-		0x01, 0x00,				// Version
-		0x00, 0x40, 0x96, 0x01, // Multicast
-		0x01, 0x00,				// Number of uicast
-		0x00, 0x40, 0x96, 0x01, // unicast
-		0x01, 0x00,				// number of authentication method
-		0x00, 0x40, 0x96, 0x00,
-		0x28, 0x00// Authentication
-		};
-
-UCHAR	CipherSuiteCiscoCCKM24Len = (sizeof(CipherSuiteCiscoCCKM24) / sizeof(UCHAR));
-
-UCHAR	CipherSuiteCCXTkip[] = {
-		0xDD, 0x16,				// RSN IE
-		0x00, 0x50, 0xf2, 0x01,	// oui
-		0x01, 0x00,				// Version
-		0x00, 0x50, 0xf2, 0x02,	// Multicast
-		0x01, 0x00,				// Number of unicast
-		0x00, 0x50, 0xf2, 0x02,	// unicast
-		0x01, 0x00,				// number of authentication method
-		0x00, 0x50, 0xf2, 0x01	// authentication
-		};
-UCHAR	CipherSuiteCCXTkipLen = (sizeof(CipherSuiteCCXTkip) / sizeof(UCHAR));
-
-UCHAR	CCX_LLC_HDR[] = {0xAA, 0xAA, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02};
-UCHAR	LLC_NORMAL[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
-
-UCHAR	EAPOL_FRAME[] = {0x88, 0x8E};
-
-BOOLEAN CheckRSNIE(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pData,
-	IN  UCHAR           DataLen,
-	OUT	UCHAR			*Offset);
-
-void inc_byte_array(UCHAR *counter, int len);
-
-/*
-	========================================================================
-
-	Routine Description:
-		Classify WPA EAP message type
-
-	Arguments:
-		EAPType		Value of EAP message type
-		MsgType		Internal Message definition for MLME state machine
-
-	Return Value:
-		TRUE		Found appropriate message type
-		FALSE		No appropriate message type
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-		All these constants are defined in wpa.h
-		For supplicant, there is only EAPOL Key message avaliable
-
-	========================================================================
-*/
-BOOLEAN	WpaMsgTypeSubst(
-	IN	UCHAR	EAPType,
-	OUT	INT		*MsgType)
-{
-	switch (EAPType)
-	{
-		case EAPPacket:
-			*MsgType = MT2_EAPPacket;
-			break;
-		case EAPOLStart:
-			*MsgType = MT2_EAPOLStart;
-			break;
-		case EAPOLLogoff:
-			*MsgType = MT2_EAPOLLogoff;
-			break;
-		case EAPOLKey:
-			*MsgType = MT2_EAPOLKey;
-			break;
-		case EAPOLASFAlert:
-			*MsgType = MT2_EAPOLASFAlert;
-			break;
-		default:
-			return FALSE;
-	}
-	return TRUE;
-}
-
-/*
-	==========================================================================
-	Description:
-		association	state machine init,	including state	transition and timer init
-	Parameters:
-		S -	pointer	to the association state machine
-	==========================================================================
- */
-VOID WpaPskStateMachineInit(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	STATE_MACHINE *S,
-	OUT	STATE_MACHINE_FUNC Trans[])
-{
-	StateMachineInit(S,	Trans, MAX_WPA_PSK_STATE, MAX_WPA_PSK_MSG, (STATE_MACHINE_FUNC)Drop, WPA_PSK_IDLE, WPA_MACHINE_BASE);
-	StateMachineSetAction(S, WPA_PSK_IDLE, MT2_EAPOLKey, (STATE_MACHINE_FUNC)WpaEAPOLKeyAction);
-}
-
-/*
-	==========================================================================
-	Description:
-		This is	state machine function.
-		When receiving EAPOL packets which is  for 802.1x key management.
-		Use	both in	WPA, and WPAPSK	case.
-		In this	function, further dispatch to different	functions according	to the received	packet.	 3 categories are :
-		  1.  normal 4-way pairwisekey and 2-way groupkey handshake
-		  2.  MIC error	(Countermeasures attack)  report packet	from STA.
-		  3.  Request for pairwise/group key update	from STA
-	Return:
-	==========================================================================
-*/
-VOID WpaEAPOLKeyAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MLME_QUEUE_ELEM	*Elem)
-
-{
-	INT             MsgType = EAPOL_MSG_INVALID;
-	PKEY_DESCRIPTER pKeyDesc;
-	PHEADER_802_11  pHeader; //red
-	UCHAR           ZeroReplay[LEN_KEY_DESC_REPLAY];
-	UCHAR EapolVr;
-	KEY_INFO		peerKeyInfo;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("-----> WpaEAPOLKeyAction\n"));
-
-	// Get 802.11 header first
-	pHeader = (PHEADER_802_11) Elem->Msg;
-
-	// Get EAPoL-Key Descriptor
-	pKeyDesc = (PKEY_DESCRIPTER) &Elem->Msg[(LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H)];
-
-	NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
-	NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pKeyDesc->KeyInfo, sizeof(KEY_INFO));
-
-	*((USHORT *)&peerKeyInfo) = cpu2le16(*((USHORT *)&peerKeyInfo));
-
-
-	// 1. Check EAPOL frame version and type
-	EapolVr	= (UCHAR) Elem->Msg[LENGTH_802_11+LENGTH_802_1_H];
-
-    if (((EapolVr != EAPOL_VER) && (EapolVr != EAPOL_VER2)) || ((pKeyDesc->Type != WPA1_KEY_DESC) && (pKeyDesc->Type != WPA2_KEY_DESC)))
-	{
-        DBGPRINT(RT_DEBUG_ERROR, ("Key descripter does not match with WPA rule\n"));
-			return;
-	}
-
-	// First validate replay counter, only accept message with larger replay counter
-	// Let equal pass, some AP start with all zero replay counter
-	NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
-
-	if((RTMPCompareMemory(pKeyDesc->ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1) &&
-		(RTMPCompareMemory(pKeyDesc->ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("   ReplayCounter not match   \n"));
-		return;
-	}
-
-	// Process WPA2PSK frame
-	if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
-	{
-		if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
-			(peerKeyInfo.EKD_DL == 0) &&
-			(peerKeyInfo.KeyAck == 1) &&
-			(peerKeyInfo.KeyMic == 0) &&
-			(peerKeyInfo.Secure == 0) &&
-			(peerKeyInfo.Error == 0) &&
-			(peerKeyInfo.Request == 0))
-		{
-			MsgType = EAPOL_PAIR_MSG_1;
-			DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 1\n"));
-		} else if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
-			(peerKeyInfo.EKD_DL  == 1) &&
-			(peerKeyInfo.KeyAck == 1) &&
-			(peerKeyInfo.KeyMic == 1) &&
-			(peerKeyInfo.Secure == 1) &&
-			(peerKeyInfo.Error == 0) &&
-			(peerKeyInfo.Request == 0))
-		{
-			MsgType = EAPOL_PAIR_MSG_3;
-			DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 3\n"));
-		} else if((peerKeyInfo.KeyType == GROUPKEY) &&
-			(peerKeyInfo.EKD_DL == 1) &&
-			(peerKeyInfo.KeyAck == 1) &&
-			(peerKeyInfo.KeyMic == 1) &&
-			(peerKeyInfo.Secure == 1) &&
-			(peerKeyInfo.Error == 0) &&
-			(peerKeyInfo.Request == 0))
-		{
-			MsgType = EAPOL_GROUP_MSG_1;
-			DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Group Message 1\n"));
-		}
-
-		// We will assume link is up (assoc suceess and port not secured).
-		// All state has to be able to process message from previous state
-		switch(pAd->StaCfg.WpaState)
-		{
-		case SS_START:
-			if(MsgType == EAPOL_PAIR_MSG_1)
-			{
-				Wpa2PairMsg1Action(pAd, Elem);
-				pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
-			}
-			break;
-
-		case SS_WAIT_MSG_3:
-			if(MsgType == EAPOL_PAIR_MSG_1)
-			{
-				Wpa2PairMsg1Action(pAd, Elem);
-				pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
-			}
-			else if(MsgType == EAPOL_PAIR_MSG_3)
-			{
-				Wpa2PairMsg3Action(pAd, Elem);
-				pAd->StaCfg.WpaState = SS_WAIT_GROUP;
-			}
-			break;
-
-		case SS_WAIT_GROUP:		// When doing group key exchange
-		case SS_FINISH:			// This happened when update group key
-			if(MsgType == EAPOL_PAIR_MSG_1)
-			{
-			    // Reset port secured variable
-				pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-				Wpa2PairMsg1Action(pAd, Elem);
-				pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
-			}
-			else if(MsgType == EAPOL_PAIR_MSG_3)
-			{
-			    // Reset port secured variable
-				pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-				Wpa2PairMsg3Action(pAd, Elem);
-				pAd->StaCfg.WpaState = SS_WAIT_GROUP;
-			}
-			else if(MsgType == EAPOL_GROUP_MSG_1)
-			{
-				WpaGroupMsg1Action(pAd, Elem);
-				pAd->StaCfg.WpaState = SS_FINISH;
-			}
-			break;
-
-		default:
-			break;
-		}
-	}
-	// Process WPAPSK Frame
-	// Classify message Type, either pairwise message 1, 3, or group message 1 for supplicant
-	else if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
-	{
-		if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
-			(peerKeyInfo.KeyIndex == 0) &&
-			(peerKeyInfo.KeyAck == 1) &&
-			(peerKeyInfo.KeyMic == 0) &&
-			(peerKeyInfo.Secure == 0) &&
-			(peerKeyInfo.Error == 0) &&
-			(peerKeyInfo.Request == 0))
-		{
-			MsgType = EAPOL_PAIR_MSG_1;
-			DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 1\n"));
-		}
-		else if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
-			(peerKeyInfo.KeyIndex == 0) &&
-			(peerKeyInfo.KeyAck == 1) &&
-			(peerKeyInfo.KeyMic == 1) &&
-			(peerKeyInfo.Secure == 0) &&
-			(peerKeyInfo.Error == 0) &&
-			(peerKeyInfo.Request == 0))
-		{
-			MsgType = EAPOL_PAIR_MSG_3;
-			DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 3\n"));
-		}
-		else if((peerKeyInfo.KeyType == GROUPKEY) &&
-			(peerKeyInfo.KeyIndex != 0) &&
-			(peerKeyInfo.KeyAck == 1) &&
-			(peerKeyInfo.KeyMic == 1) &&
-			(peerKeyInfo.Secure == 1) &&
-			(peerKeyInfo.Error == 0) &&
-			(peerKeyInfo.Request == 0))
-		{
-			MsgType = EAPOL_GROUP_MSG_1;
-			DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Group Message 1\n"));
-		}
-
-		// We will assume link is up (assoc suceess and port not secured).
-		// All state has to be able to process message from previous state
-		switch(pAd->StaCfg.WpaState)
-		{
-		case SS_START:
-			if(MsgType == EAPOL_PAIR_MSG_1)
-			{
-				WpaPairMsg1Action(pAd, Elem);
-				pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
-			}
-			break;
-
-		case SS_WAIT_MSG_3:
-			if(MsgType == EAPOL_PAIR_MSG_1)
-			{
-				WpaPairMsg1Action(pAd, Elem);
-				pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
-			}
-			else if(MsgType == EAPOL_PAIR_MSG_3)
-			{
-				WpaPairMsg3Action(pAd, Elem);
-				pAd->StaCfg.WpaState = SS_WAIT_GROUP;
-			}
-			break;
-
-		case SS_WAIT_GROUP:		// When doing group key exchange
-		case SS_FINISH:			// This happened when update group key
-			if(MsgType == EAPOL_PAIR_MSG_1)
-			{
-				WpaPairMsg1Action(pAd, Elem);
-				pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
-				// Reset port secured variable
-				pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-			}
-			else if(MsgType == EAPOL_PAIR_MSG_3)
-			{
-				WpaPairMsg3Action(pAd, Elem);
-				pAd->StaCfg.WpaState = SS_WAIT_GROUP;
-				// Reset port secured variable
-				pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-			}
-			else if(MsgType == EAPOL_GROUP_MSG_1)
-			{
-				WpaGroupMsg1Action(pAd, Elem);
-				pAd->StaCfg.WpaState = SS_FINISH;
-			}
-			break;
-
-		default:
-			break;
-		}
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<----- WpaEAPOLKeyAction\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Process Pairwise key 4-way handshaking
-
-	Arguments:
-		pAd	Pointer	to our adapter
-		Elem		Message body
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	WpaPairMsg1Action(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem)
-{
-	PHEADER_802_11      pHeader;
-	UCHAR				*mpool, *PTK, *digest;
-	PUCHAR              pOutBuffer = NULL;
-	UCHAR               Header802_3[14];
-	ULONG               FrameLen = 0;
-	PEAPOL_PACKET       pMsg1;
-	EAPOL_PACKET        Packet;
-	UCHAR               Mic[16];
-
-	DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg1Action ----->\n"));
-
-	// allocate memory pool
-	os_alloc_mem(pAd, (PUCHAR *)&mpool, 256);
-
-	if (mpool == NULL)
-		return;
-
-	// PTK Len = 80.
-	PTK = (UCHAR *) ROUND_UP(mpool, 4);
-	// digest Len = 80.
-	digest = (UCHAR *) ROUND_UP(PTK + 80, 4);
-
-	pHeader = (PHEADER_802_11) Elem->Msg;
-
-	// Process message 1 from authenticator
-	pMsg1 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
-
-	// 1. Save Replay counter, it will use to verify message 3 and construct message 2
-	NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
-
-	// 2. Save ANonce
-	NdisMoveMemory(pAd->StaCfg.ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE);
-
-	// Generate random SNonce
-	GenRandom(pAd, pAd->CurrentAddress, pAd->StaCfg.SNonce);
-
-	// Calc PTK(ANonce, SNonce)
-	WpaCountPTK(pAd,
-		pAd->StaCfg.PMK,
-		pAd->StaCfg.ANonce,
-		pAd->CommonCfg.Bssid,
-		pAd->StaCfg.SNonce,
-		pAd->CurrentAddress,
-		PTK,
-		LEN_PTK);
-
-	// Save key to PTK entry
-	NdisMoveMemory(pAd->StaCfg.PTK, PTK, LEN_PTK);
-
-	// init 802.3 header and Fill Packet
-	MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
-
-	// Zero Message 2 body
-	NdisZeroMemory(&Packet, sizeof(Packet));
-	Packet.ProVer	= EAPOL_VER;
-	Packet.ProType	= EAPOLKey;
-	//
-	// Message 2 as  EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
-	//
-	Packet.KeyDesc.Type = WPA1_KEY_DESC;
-	// 1. Key descriptor version and appropriate RSN IE
-	if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
-	{
-		Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
-	}
-	else	  // TKIP
-	{
-		Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
-	}
-
-	// fill in Data Material and its length
-	Packet.KeyDesc.KeyData[0] = IE_WPA;
-	Packet.KeyDesc.KeyData[1] = pAd->StaCfg.RSNIE_Len;
-	Packet.KeyDesc.KeyDataLen[1] = pAd->StaCfg.RSNIE_Len + 2;
-	NdisMoveMemory(&Packet.KeyDesc.KeyData[2], pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
-
-	// Update packet length after decide Key data payload
-	Packet.Body_Len[1]  = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + Packet.KeyDesc.KeyDataLen[1];
-
-	// Update Key length
-	Packet.KeyDesc.KeyLength[0] = pMsg1->KeyDesc.KeyLength[0];
-	Packet.KeyDesc.KeyLength[1] = pMsg1->KeyDesc.KeyLength[1];
-	// 2. Key Type PeerKey
-	Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
-
-	// 3. KeyMic field presented
-	Packet.KeyDesc.KeyInfo.KeyMic  = 1;
-
-	//Convert to little-endian format.
-	*((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
-
-
-	// 4. Fill SNonce
-	NdisMoveMemory(Packet.KeyDesc.KeyNonce, pAd->StaCfg.SNonce, LEN_KEY_DESC_NONCE);
-
-	// 5. Key Replay Count
-	NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
-
-	// Send EAPOL(0, 1, 0, 0, 0, P, 0, SNonce, MIC, RSN_IE)
-	// Out buffer for transmitting message 2
-	MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer);  // allocate memory
-	if(pOutBuffer == NULL)
-	{
-		os_free_mem(pAd, mpool);
-		return;
-	}
-	// Prepare EAPOL frame for MIC calculation
-	// Be careful, only EAPOL frame is counted for MIC calculation
-	MakeOutgoingFrame(pOutBuffer,           &FrameLen,
-		Packet.Body_Len[1] + 4,    &Packet,
-		END_OF_ARGS);
-
-	// 6. Prepare and Fill MIC value
-	NdisZeroMemory(Mic, sizeof(Mic));
-	if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
-	{	// AES
-
-		HMAC_SHA1(pOutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);
-		NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
-	}
-	else
-	{	// TKIP
-		hmac_md5(PTK,  LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
-	}
-	NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
-
-	//hex_dump("MIC", Mic, LEN_KEY_DESC_MIC);
-
-		MakeOutgoingFrame(pOutBuffer,           	&FrameLen,
-			  			LENGTH_802_3,     			&Header802_3,
-						Packet.Body_Len[1] + 4,    &Packet,
-						END_OF_ARGS);
-
-
-	// 5. Copy frame to Tx ring and send Msg 2 to authenticator
-	RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
-
-	MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
-	os_free_mem(pAd, (PUCHAR)mpool);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg1Action <-----\n"));
-}
-
-VOID Wpa2PairMsg1Action(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem)
-{
-	PHEADER_802_11      pHeader;
-	UCHAR				*mpool, *PTK, *digest;
-	PUCHAR              pOutBuffer = NULL;
-	UCHAR               Header802_3[14];
-	ULONG               FrameLen = 0;
-	PEAPOL_PACKET       pMsg1;
-	EAPOL_PACKET        Packet;
-	UCHAR               Mic[16];
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg1Action ----->\n"));
-
-	// allocate memory pool
-	os_alloc_mem(pAd, (PUCHAR *)&mpool, 256);
-
-	if (mpool == NULL)
-		return;
-
-	// PTK Len = 80.
-	PTK = (UCHAR *) ROUND_UP(mpool, 4);
-	// digest Len = 80.
-	digest = (UCHAR *) ROUND_UP(PTK + 80, 4);
-
-	pHeader = (PHEADER_802_11) Elem->Msg;
-
-	// Process message 1 from authenticator
-		pMsg1 = (PEAPOL_PACKET)	&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
-
-	// 1. Save Replay counter, it will use to verify message 3 and construct message 2
-	NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
-
-	// 2. Save ANonce
-	NdisMoveMemory(pAd->StaCfg.ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE);
-
-	// Generate random SNonce
-	GenRandom(pAd, pAd->CurrentAddress, pAd->StaCfg.SNonce);
-
-	if(pMsg1->KeyDesc.KeyDataLen[1] > 0 )
-	{
-		// cached PMKID
-	}
-
-	// Calc PTK(ANonce, SNonce)
-	WpaCountPTK(pAd,
-		pAd->StaCfg.PMK,
-		pAd->StaCfg.ANonce,
-		pAd->CommonCfg.Bssid,
-		pAd->StaCfg.SNonce,
-		pAd->CurrentAddress,
-		PTK,
-		LEN_PTK);
-
-	// Save key to PTK entry
-	NdisMoveMemory(pAd->StaCfg.PTK, PTK, LEN_PTK);
-
-	// init 802.3 header and Fill Packet
-	MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
-
-	// Zero message 2 body
-	NdisZeroMemory(&Packet, sizeof(Packet));
-	Packet.ProVer	= EAPOL_VER;
-	Packet.ProType	= EAPOLKey;
-	//
-	// Message 2 as  EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
-	//
-	Packet.KeyDesc.Type = WPA2_KEY_DESC;
-
-	// 1. Key descriptor version and appropriate RSN IE
-	if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
-	{
-		Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
-	}
-	else	  // TKIP
-	{
-		Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
-	}
-
-	// fill in Data Material and its length
-	Packet.KeyDesc.KeyData[0] = IE_WPA2;
-	Packet.KeyDesc.KeyData[1] = pAd->StaCfg.RSNIE_Len;
-	Packet.KeyDesc.KeyDataLen[1] = pAd->StaCfg.RSNIE_Len + 2;
-	NdisMoveMemory(&Packet.KeyDesc.KeyData[2], pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
-
-	// Update packet length after decide Key data payload
-	Packet.Body_Len[1]  = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + Packet.KeyDesc.KeyDataLen[1];
-
-	// 2. Key Type PeerKey
-	Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
-
-	// 3. KeyMic field presented
-	Packet.KeyDesc.KeyInfo.KeyMic  = 1;
-
-	// Update Key Length
-	Packet.KeyDesc.KeyLength[0] = 0;
-	Packet.KeyDesc.KeyLength[1] = pMsg1->KeyDesc.KeyLength[1];
-
-	// 4. Fill SNonce
-	NdisMoveMemory(Packet.KeyDesc.KeyNonce, pAd->StaCfg.SNonce, LEN_KEY_DESC_NONCE);
-
-	// 5. Key Replay Count
-	NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
-
-	// Convert to little-endian format.
-	*((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
-
-	// Send EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
-	// Out buffer for transmitting message 2
-	MlmeAllocateMemory(pAd,  (PUCHAR *)&pOutBuffer);  // allocate memory
-	if(pOutBuffer == NULL)
-	{
-		os_free_mem(pAd, mpool);
-		return;
-	}
-
-	// Prepare EAPOL frame for MIC calculation
-	// Be careful, only EAPOL frame is counted for MIC calculation
-	MakeOutgoingFrame(pOutBuffer,        &FrameLen,
-		Packet.Body_Len[1] + 4, &Packet,
-		END_OF_ARGS);
-
-	// 6. Prepare and Fill MIC value
-	NdisZeroMemory(Mic, sizeof(Mic));
-	if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
-	{
-		// AES
-		HMAC_SHA1(pOutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);
-		NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
-	}
-	else
-	{
-		hmac_md5(PTK,  LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
-	}
-	NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
-
-
-	// Make  Transmitting frame
-	MakeOutgoingFrame(pOutBuffer,           	&FrameLen,
-			  			LENGTH_802_3,     		&Header802_3,
-						Packet.Body_Len[1] + 4, &Packet,
-						END_OF_ARGS);
-
-
-	// 5. Copy frame to Tx ring
-	RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
-
-	MlmeFreeMemory(pAd, pOutBuffer);
-	os_free_mem(pAd, mpool);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg1Action <-----\n"));
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Process Pairwise key 4-way handshaking
-
-	Arguments:
-		pAd	Pointer	to our adapter
-		Elem		Message body
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	WpaPairMsg3Action(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MLME_QUEUE_ELEM	*Elem)
-
-{
-	PHEADER_802_11      pHeader;
-	PUCHAR          	pOutBuffer = NULL;
-	UCHAR               Header802_3[14];
-	ULONG           	FrameLen = 0;
-	EAPOL_PACKET        Packet;
-	PEAPOL_PACKET       pMsg3;
-	UCHAR           	Mic[16], OldMic[16];
-	MAC_TABLE_ENTRY 	*pEntry = NULL;
-	UCHAR				skip_offset;
-	KEY_INFO			peerKeyInfo;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg3Action ----->\n"));
-
-	// Record 802.11 header & the received EAPOL packet Msg3
-	pHeader = (PHEADER_802_11) Elem->Msg;
-	pMsg3 = (PEAPOL_PACKET)	&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
-
-	NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
-	NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pMsg3->KeyDesc.KeyInfo, sizeof(KEY_INFO));
-
-	*((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
-
-
-	// 1. Verify cipher type match
-	if (pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer != 2))
-	{
-		return;
-	}
-	else if(pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
-	{
-		return;
-	}
-
-	// Verify RSN IE
-	//if (!RTMPEqualMemory(pMsg3->KeyDesc.KeyData, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len))
-	if (!CheckRSNIE(pAd, pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1], &skip_offset))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("RSN_IE Different in Msg 3 of WPA1 4-way handshake!! \n"));
-		hex_dump("The original RSN_IE", pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len);
-		hex_dump("The received RSN_IE", pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1]);
-		return;
-	}
-	else
-		DBGPRINT(RT_DEBUG_TRACE, ("RSN_IE VALID in Msg 3 of WPA1 4-way handshake!! \n"));
-
-
-	// 2. Check MIC value
-	// Save the MIC and replace with zero
-	NdisMoveMemory(OldMic, pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
-	NdisZeroMemory(pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
-	if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
-	{
-		// AES
-		UCHAR digest[80];
-
-		HMAC_SHA1((PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
-		NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
-	}
-	else	// TKIP
-	{
-		hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, Mic);
-	}
-
-	if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in msg 3 of 4-way handshake!!!!!!!!!! \n"));
-		return;
-	}
-	else
-		DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in msg 3 of 4-way handshake!!!!!!!!!! \n"));
-
-	// 3. Check Replay Counter, it has to be larger than last one. No need to be exact one larger
-	if(RTMPCompareMemory(pMsg3->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
-		return;
-
-	// Update new replay counter
-	NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
-
-	// 4. Double check ANonce
-	if(!NdisEqualMemory(pAd->StaCfg.ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE))
-		return;
-
-	// init 802.3 header and Fill Packet
-	MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
-
-	// Zero Message 4 body
-	NdisZeroMemory(&Packet, sizeof(Packet));
-	Packet.ProVer	= EAPOL_VER;
-	Packet.ProType	= EAPOLKey;
-	Packet.Body_Len[1]  = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE;		// No data field
-
-	//
-	// Message 4 as  EAPOL-Key(0,1,0,0,0,P,0,0,MIC,0)
-	//
-	Packet.KeyDesc.Type = WPA1_KEY_DESC;
-
-	// Key descriptor version and appropriate RSN IE
-	Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
-
-	// Update Key Length
-	Packet.KeyDesc.KeyLength[0] = pMsg3->KeyDesc.KeyLength[0];
-	Packet.KeyDesc.KeyLength[1] = pMsg3->KeyDesc.KeyLength[1];
-
-	// Key Type PeerKey
-	Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
-
-	// KeyMic field presented
-	Packet.KeyDesc.KeyInfo.KeyMic  = 1;
-
-	// In Msg3,  KeyInfo.secure =0 if Group Key HS to come. 1 if no group key HS
-	// Station sends Msg4  KeyInfo.secure should be the same as that in Msg.3
-	Packet.KeyDesc.KeyInfo.Secure= peerKeyInfo.Secure;
-
-	// Convert to little-endian format.
-	*((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
-
-	// Key Replay count
-	NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
-
-	// Out buffer for transmitting message 4
-	MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer);  // allocate memory
-	if(pOutBuffer == NULL)
-		return;
-
-	// Prepare EAPOL frame for MIC calculation
-	// Be careful, only EAPOL frame is counted for MIC calculation
-	MakeOutgoingFrame(pOutBuffer,           &FrameLen,
-		Packet.Body_Len[1] + 4,    &Packet,
-		END_OF_ARGS);
-
-	// Prepare and Fill MIC value
-	NdisZeroMemory(Mic, sizeof(Mic));
-	if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
-	{
-		// AES
-		UCHAR digest[80];
-
-		HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
-		NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
-	}
-	else
-	{
-		hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
-	}
-	NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
-
-	// Update PTK
-	// Prepare pair-wise key information into shared key table
-	NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
-	pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
-    NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
-	NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
-	NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
-
-	// Decide its ChiperAlg
-	if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
-		pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
-	else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
-		pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
-	else
-		pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
-
-	// Update these related information to MAC_TABLE_ENTRY
-	pEntry = &pAd->MacTab.Content[BSSID_WCID];
-	NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
-	NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
-	NdisMoveMemory(pEntry->PairwiseKey.TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
-	pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
-
-	// Update pairwise key information to ASIC Shared Key Table
-	AsicAddSharedKeyEntry(pAd,
-						  BSS0,
-						  0,
-						  pAd->SharedKey[BSS0][0].CipherAlg,
-						  pAd->SharedKey[BSS0][0].Key,
-						  pAd->SharedKey[BSS0][0].TxMic,
-						  pAd->SharedKey[BSS0][0].RxMic);
-
-	// Update ASIC WCID attribute table and IVEIV table
-	RTMPAddWcidAttributeEntry(pAd,
-							  BSS0,
-							  0,
-							  pAd->SharedKey[BSS0][0].CipherAlg,
-							  pEntry);
-
-	// Make transmitting frame
-	MakeOutgoingFrame(pOutBuffer,           	&FrameLen,
-			  			LENGTH_802_3,     		&Header802_3,
-						Packet.Body_Len[1] + 4, &Packet,
-						END_OF_ARGS);
-
-
-	// Copy frame to Tx ring and Send Message 4 to authenticator
-	RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
-
-	MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg3Action <-----\n"));
-}
-
-VOID    Wpa2PairMsg3Action(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem)
-
-{
-	PHEADER_802_11      pHeader;
-	PUCHAR              pOutBuffer = NULL;
-	UCHAR               Header802_3[14];
-	ULONG               FrameLen = 0;
-	EAPOL_PACKET        Packet;
-	PEAPOL_PACKET       pMsg3;
-	UCHAR               Mic[16], OldMic[16];
-	UCHAR               *mpool, *KEYDATA, *digest;
-	UCHAR               Key[32];
-	MAC_TABLE_ENTRY 	*pEntry = NULL;
-	KEY_INFO			peerKeyInfo;
-
-	// allocate memory
-	os_alloc_mem(pAd, (PUCHAR *)&mpool, 1024);
-
-	if(mpool == NULL)
-		return;
-
-	// KEYDATA Len = 512.
-	KEYDATA = (UCHAR *) ROUND_UP(mpool, 4);
-	// digest Len = 80.
-	digest = (UCHAR *) ROUND_UP(KEYDATA + 512, 4);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg3Action ----->\n"));
-
-	pHeader = (PHEADER_802_11) Elem->Msg;
-
-	// Process message 3 frame.
-	pMsg3 = (PEAPOL_PACKET)	&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
-
-	NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
-	NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pMsg3->KeyDesc.KeyInfo, sizeof(KEY_INFO));
-
-	*((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
-
-	// 1. Verify cipher type match
-	if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer!= 2))
-	{
-		os_free_mem(pAd, (PUCHAR)mpool);
-		return;
-	}
-	else if(pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
-	{
-		os_free_mem(pAd, (PUCHAR)mpool);
-		return;
-	}
-
-	// 2. Check MIC value
-	// Save the MIC and replace with zero
-	NdisMoveMemory(OldMic, pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
-	NdisZeroMemory(pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
-	if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
-	{
-		// AES
-		HMAC_SHA1((PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
-		NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
-	}
-	else
-	{
-		hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, Mic);
-	}
-
-	if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in msg 3 of 4-way handshake!!!!!!!!!! \n"));
-		os_free_mem(pAd, (PUCHAR)mpool);
-		return;
-	}
-	else
-		DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in msg 3 of 4-way handshake!!!!!!!!!! \n"));
-
-	// 3. Check Replay Counter, it has to be larger than last one. No need to be exact one larger
-	if(RTMPCompareMemory(pMsg3->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
-	{
-		os_free_mem(pAd, (PUCHAR)mpool);
-		return;
-	}
-
-	// Update new replay counter
-	NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
-
-	// 4. Double check ANonce
-	if(!NdisEqualMemory(pAd->StaCfg.ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE))
-	{
-		os_free_mem(pAd, (PUCHAR)mpool);
-		return;
-	}
-
-	// Obtain GTK
-	// 5. Decrypt GTK from Key Data
-	DBGPRINT_RAW(RT_DEBUG_TRACE, ("EKD = %d\n", peerKeyInfo.EKD_DL));
-	if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
-	{
-		// Decrypt AES GTK
-		AES_GTK_KEY_UNWRAP(&pAd->StaCfg.PTK[16], KEYDATA, pMsg3->KeyDesc.KeyDataLen[1],pMsg3->KeyDesc.KeyData);
-	}
-	else	  // TKIP
-	{
-		INT i;
-		// Decrypt TKIP GTK
-		// Construct 32 bytes RC4 Key
-		NdisMoveMemory(Key, pMsg3->KeyDesc.KeyIv, 16);
-		NdisMoveMemory(&Key[16], &pAd->StaCfg.PTK[16], 16);
-		ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
-		//discard first 256 bytes
-		for(i = 0; i < 256; i++)
-			ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
-		// Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
-		ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1]);
-	}
-
-	if (!ParseKeyData(pAd, KEYDATA, pMsg3->KeyDesc.KeyDataLen[1], 1))
-	{
-		os_free_mem(pAd, (PUCHAR)mpool);
-		return;
-	}
-
-	// Update GTK to ASIC
-	// Update group key information to ASIC Shared Key Table
-	AsicAddSharedKeyEntry(pAd,
-						  BSS0,
-						  pAd->StaCfg.DefaultKeyId,
-						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
-						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
-						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
-						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
-
-	// Update ASIC WCID attribute table and IVEIV table
-	RTMPAddWcidAttributeEntry(pAd,
-							  BSS0,
-							  pAd->StaCfg.DefaultKeyId,
-							  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
-							  NULL);
-
-	// init 802.3 header and Fill Packet
-	MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
-
-	// Zero message 4 body
-	NdisZeroMemory(&Packet, sizeof(Packet));
-	Packet.ProVer	= EAPOL_VER;
-	Packet.ProType	= EAPOLKey;
-	Packet.Body_Len[1]  	= sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE;		// No data field
-
-	//
-	// Message 4 as  EAPOL-Key(0,1,0,0,0,P,0,0,MIC,0)
-	//
-	Packet.KeyDesc.Type = WPA2_KEY_DESC;
-
-	// Key descriptor version and appropriate RSN IE
-	Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
-
-	// Update Key Length
-	Packet.KeyDesc.KeyLength[0] = pMsg3->KeyDesc.KeyLength[0];
-	Packet.KeyDesc.KeyLength[1] = pMsg3->KeyDesc.KeyLength[1];
-
-	// Key Type PeerKey
-	Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
-
-	// KeyMic field presented
-	Packet.KeyDesc.KeyInfo.KeyMic  = 1;
-	Packet.KeyDesc.KeyInfo.Secure = 1;
-
-	// Convert to little-endian format.
-	*((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
-
-	// Key Replay count
-	NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
-
-	// Out buffer for transmitting message 4
-	MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer);  // allocate memory
-	if(pOutBuffer == NULL)
-	{
-		os_free_mem(pAd, (PUCHAR)mpool);
-		return;
-	}
-
-	// Prepare EAPOL frame for MIC calculation
-	// Be careful, only EAPOL frame is counted for MIC calculation
-	MakeOutgoingFrame(pOutBuffer,           &FrameLen,
-		Packet.Body_Len[1] + 4,    &Packet,
-		END_OF_ARGS);
-
-	// Prepare and Fill MIC value
-	NdisZeroMemory(Mic, sizeof(Mic));
-	if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
-	{
-		// AES
-		HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
-		NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
-	}
-	else
-	{
-		hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
-	}
-	NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
-
-	// Update PTK
-	// Prepare pair-wise key information into shared key table
-	NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
-	pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
-    NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
-	NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
-	NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
-
-	// Decide its ChiperAlg
-	if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
-		pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
-	else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
-		pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
-	else
-		pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
-
-	// Update these related information to MAC_TABLE_ENTRY
-	pEntry = &pAd->MacTab.Content[BSSID_WCID];
-	NdisMoveMemory(&pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
-	NdisMoveMemory(&pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
-	NdisMoveMemory(&pEntry->PairwiseKey.TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
-	pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
-
-	// Update pairwise key information to ASIC Shared Key Table
-	AsicAddSharedKeyEntry(pAd,
-						  BSS0,
-						  0,
-						  pAd->SharedKey[BSS0][0].CipherAlg,
-						  pAd->SharedKey[BSS0][0].Key,
-						  pAd->SharedKey[BSS0][0].TxMic,
-						  pAd->SharedKey[BSS0][0].RxMic);
-
-	// Update ASIC WCID attribute table and IVEIV table
-	RTMPAddWcidAttributeEntry(pAd,
-							  BSS0,
-							  0,
-							  pAd->SharedKey[BSS0][0].CipherAlg,
-							  pEntry);
-
-	// Make  Transmitting frame
-	MakeOutgoingFrame(pOutBuffer,           	&FrameLen,
-			  			LENGTH_802_3,     		&Header802_3,
-						Packet.Body_Len[1] + 4, &Packet,
-						END_OF_ARGS);
-
-
-	// Copy frame to Tx ring and Send Message 4 to authenticator
-	RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
-
-	// set 802.1x port control
-	STA_PORT_SECURED(pAd);
-
-    // Indicate Connected for GUI
-    pAd->IndicateMediaState = NdisMediaStateConnected;
-
-	MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
-	os_free_mem(pAd, (PUCHAR)mpool);
-
-
-	// send wireless event - for set key done WPA2
-	if (pAd->CommonCfg.bWirelessEvent)
-		RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pEntry->Addr, BSS0, 0);
-
-	DBGPRINT(RT_DEBUG_ERROR, ("Wpa2PairMsg3Action <-----\n"));
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Process Group key 2-way handshaking
-
-	Arguments:
-		pAd	Pointer	to our adapter
-		Elem		Message body
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	WpaGroupMsg1Action(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MLME_QUEUE_ELEM	*Elem)
-
-{
-	PUCHAR              pOutBuffer = NULL;
-	UCHAR               Header802_3[14];
-	ULONG               FrameLen = 0;
-	EAPOL_PACKET        Packet;
-	PEAPOL_PACKET       pGroup;
-	UCHAR               *mpool, *digest, *KEYDATA;
-	UCHAR               Mic[16], OldMic[16];
-	UCHAR               GTK[32], Key[32];
-	KEY_INFO			peerKeyInfo;
-
-	// allocate memory
-	os_alloc_mem(pAd, (PUCHAR *)&mpool, 1024);
-
-	if(mpool == NULL)
-		return;
-
-	// digest Len = 80.
-	digest = (UCHAR *) ROUND_UP(mpool, 4);
-	// KEYDATA Len = 512.
-	KEYDATA = (UCHAR *) ROUND_UP(digest + 80, 4);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("WpaGroupMsg1Action ----->\n"));
-
-	// Process Group Message 1 frame. skip 802.11 header(24) & LLC_SNAP header(8)
-	pGroup = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
-
-	NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
-	NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pGroup->KeyDesc.KeyInfo, sizeof(KEY_INFO));
-
-	*((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
-
-	// 0. Check cipher type match
-	if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer != 2))
-	{
-		os_free_mem(pAd, (PUCHAR)mpool);
-		return;
-	}
-	else if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
-	{
-		os_free_mem(pAd, (PUCHAR)mpool);
-		return;
-	}
-
-	// 1. Verify Replay counter
-	//    Check Replay Counter, it has to be larger than last one. No need to be exact one larger
-	if(RTMPCompareMemory(pGroup->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
-	{
-		os_free_mem(pAd, (PUCHAR)mpool);
-		return;
-	}
-
-	// Update new replay counter
-	NdisMoveMemory(pAd->StaCfg.ReplayCounter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
-
-	// 2. Verify MIC is valid
-	// Save the MIC and replace with zero
-	NdisMoveMemory(OldMic, pGroup->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
-	NdisZeroMemory(pGroup->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
-
-	if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
-	{	// AES
-		HMAC_SHA1((PUCHAR) pGroup, pGroup->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
-		NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
-	}
-	else
-	{	// TKIP
-		hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pGroup, pGroup->Body_Len[1] + 4, Mic);
-	}
-
-	if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in group msg 1 of 2-way handshake!!!!!!!!!! \n"));
-		MlmeFreeMemory(pAd, (PUCHAR)mpool);
-		return;
-	}
-	else
-		DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in group msg 1 of 2-way handshake!!!!!!!!!! \n"));
-
-
-	// 3. Decrypt GTK from Key Data
-	if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
-	{
-		// Decrypt AES GTK
-		AES_GTK_KEY_UNWRAP(&pAd->StaCfg.PTK[16], KEYDATA,  pGroup->KeyDesc.KeyDataLen[1], pGroup->KeyDesc.KeyData);
-	}
-	else	// TKIP
-	{
-		INT i;
-
-		// Decrypt TKIP GTK
-		// Construct 32 bytes RC4 Key
-		NdisMoveMemory(Key, pGroup->KeyDesc.KeyIv, 16);
-		NdisMoveMemory(&Key[16], &pAd->StaCfg.PTK[16], 16);
-		ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
-		//discard first 256 bytes
-		for(i = 0; i < 256; i++)
-			ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
-		// Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
-		ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pGroup->KeyDesc.KeyData, pGroup->KeyDesc.KeyDataLen[1]);
-	}
-
-	// Process decrypted key data material
-	// Parse keyData to handle KDE format for WPA2PSK
-	if (peerKeyInfo.EKD_DL)
-	{
-		if (!ParseKeyData(pAd, KEYDATA, pGroup->KeyDesc.KeyDataLen[1], 0))
-		{
-			os_free_mem(pAd, (PUCHAR)mpool);
-			return;
-		}
-	}
-	else	// WPAPSK
-	{
-		// set key material, TxMic and RxMic for WPAPSK
-		NdisMoveMemory(GTK, KEYDATA, 32);
-		NdisMoveMemory(pAd->StaCfg.GTK, GTK, 32);
-		pAd->StaCfg.DefaultKeyId = peerKeyInfo.KeyIndex;
-
-		// Prepare pair-wise key information into shared key table
-		NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
-		pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
-		NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, GTK, LEN_TKIP_EK);
-		NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, &GTK[16], LEN_TKIP_RXMICK);
-		NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, &GTK[24], LEN_TKIP_TXMICK);
-
-		// Update Shared Key CipherAlg
-		pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
-		if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
-			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
-		else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
-			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
-		else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
-			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP64;
-		else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
-			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP128;
-
-    	//hex_dump("Group Key :", pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, LEN_TKIP_EK);
-	}
-
-	// Update group key information to ASIC Shared Key Table
-	AsicAddSharedKeyEntry(pAd,
-						  BSS0,
-						  pAd->StaCfg.DefaultKeyId,
-						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
-						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
-						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
-						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
-
-	// Update ASIC WCID attribute table and IVEIV table
-	RTMPAddWcidAttributeEntry(pAd,
-							  BSS0,
-							  pAd->StaCfg.DefaultKeyId,
-							  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
-							  NULL);
-
-	// set 802.1x port control
-	STA_PORT_SECURED(pAd);
-
-    // Indicate Connected for GUI
-    pAd->IndicateMediaState = NdisMediaStateConnected;
-
-	// init header and Fill Packet
-	MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
-
-	// Zero Group message 1 body
-	NdisZeroMemory(&Packet, sizeof(Packet));
-	Packet.ProVer	= EAPOL_VER;
-	Packet.ProType	= EAPOLKey;
-	Packet.Body_Len[1]  = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE;		// No data field
-
-	//
-	// Group Message 2 as  EAPOL-Key(1,0,0,0,G,0,0,MIC,0)
-	//
-	if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
-	{
-		Packet.KeyDesc.Type = WPA2_KEY_DESC;
-	}
-	else
-	{
-		Packet.KeyDesc.Type = WPA1_KEY_DESC;
-	}
-
-	// Key descriptor version and appropriate RSN IE
-	Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
-
-	// Update Key Length
-	Packet.KeyDesc.KeyLength[0] = pGroup->KeyDesc.KeyLength[0];
-	Packet.KeyDesc.KeyLength[1] = pGroup->KeyDesc.KeyLength[1];
-
-	// Key Index as G-Msg 1
-	if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
-		Packet.KeyDesc.KeyInfo.KeyIndex = peerKeyInfo.KeyIndex;
-
-	// Key Type Group key
-	Packet.KeyDesc.KeyInfo.KeyType = GROUPKEY;
-
-	// KeyMic field presented
-	Packet.KeyDesc.KeyInfo.KeyMic  = 1;
-
-	// Secure bit
-	Packet.KeyDesc.KeyInfo.Secure  = 1;
-
-	// Convert to little-endian format.
-	*((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
-
-	// Key Replay count
-	NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
-
-	// Out buffer for transmitting group message 2
-	MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer);  // allocate memory
-	if(pOutBuffer == NULL)
-	{
-		MlmeFreeMemory(pAd, (PUCHAR)mpool);
-		return;
-	}
-
-	// Prepare EAPOL frame for MIC calculation
-	// Be careful, only EAPOL frame is counted for MIC calculation
-	MakeOutgoingFrame(pOutBuffer,           &FrameLen,
-		Packet.Body_Len[1] + 4,    &Packet,
-		END_OF_ARGS);
-
-	// Prepare and Fill MIC value
-	NdisZeroMemory(Mic, sizeof(Mic));
-	if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
-	{
-		// AES
-		HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
-		NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
-	}
-	else
-	{
-		hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
-	}
-	NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
-
-
-	MakeOutgoingFrame(pOutBuffer,       		&FrameLen,
-						LENGTH_802_3,     		&Header802_3,
-						Packet.Body_Len[1] + 4, &Packet,
-						END_OF_ARGS);
-
-
-	// 5. Copy frame to Tx ring and prepare for encryption
-	RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, FALSE);
-
-	// 6 Free allocated memory
-	MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
-	os_free_mem(pAd, (PUCHAR)mpool);
-
-	// send wireless event - for set key done WPA2
-	if (pAd->CommonCfg.bWirelessEvent)
-		RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("WpaGroupMsg1Action <-----\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Init WPA MAC header
-
-	Arguments:
-		pAd	Pointer	to our adapter
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	WpaMacHeaderInit(
-	IN		PRTMP_ADAPTER	pAd,
-	IN OUT	PHEADER_802_11	pHdr80211,
-	IN		UCHAR			wep,
-	IN		PUCHAR		    pAddr1)
-{
-	NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
-	pHdr80211->FC.Type	= BTYPE_DATA;
-	pHdr80211->FC.ToDs	= 1;
-	if (wep	== 1)
-		pHdr80211->FC.Wep = 1;
-
-	 //	Addr1: BSSID, Addr2: SA, Addr3:	DA
-	COPY_MAC_ADDR(pHdr80211->Addr1, pAddr1);
-	COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
-	COPY_MAC_ADDR(pHdr80211->Addr3, pAd->CommonCfg.Bssid);
-	pHdr80211->Sequence =	pAd->Sequence;
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Copy frame from waiting queue into relative ring buffer and set
-	appropriate ASIC register to kick hardware encryption before really
-	sent out to air.
-
-	Arguments:
-		pAd		Pointer	to our adapter
-		PNDIS_PACKET	Pointer to outgoing Ndis frame
-		NumberOfFrag	Number of fragment required
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID    RTMPToWirelessSta(
-	IN	PRTMP_ADAPTER	pAd,
-	IN  PUCHAR          pHeader802_3,
-    IN  UINT            HdrLen,
-	IN  PUCHAR          pData,
-    IN  UINT            DataLen,
-    IN	BOOLEAN			is4wayFrame)
-
-{
-	NDIS_STATUS     Status;
-	PNDIS_PACKET    pPacket;
-	UCHAR   Index;
-
-	do
-	{
-		// 1. build a NDIS packet and call RTMPSendPacket();
-		//    be careful about how/when to release this internal allocated NDIS PACKET buffer
-		Status = RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen, pData, DataLen);
-		if (Status != NDIS_STATUS_SUCCESS)
-			break;
-
-		if (is4wayFrame)
-			RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1);
-		else
-			RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0);
-
-		// 2. send out the packet
-		Status = STASendPacket(pAd, pPacket);
-		if(Status == NDIS_STATUS_SUCCESS)
-		{
-			// Dequeue one frame from TxSwQueue0..3 queue and process it
-			// There are three place calling dequeue for TX ring.
-			// 1. Here, right after queueing the frame.
-			// 2. At the end of TxRingTxDone service routine.
-			// 3. Upon NDIS call RTMPSendPackets
-			if((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
-				(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)))
-			{
-				for(Index = 0; Index < 5; Index ++)
-					if(pAd->TxSwQueue[Index].Number > 0)
-						RTMPDeQueuePacket(pAd, FALSE, Index, MAX_TX_PROCESS);
-			}
-		}
-	} while(FALSE);
-
-}
-
-/*
-    ========================================================================
-
-    Routine Description:
-    Check Sanity RSN IE form AP
-
-    Arguments:
-
-    Return Value:
-
-
-    ========================================================================
-*/
-BOOLEAN CheckRSNIE(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pData,
-	IN  UCHAR           DataLen,
-	OUT	UCHAR			*Offset)
-{
-	PUCHAR              pVIE;
-	UCHAR               len;
-	PEID_STRUCT         pEid;
-	BOOLEAN				result = FALSE;
-
-	pVIE = pData;
-	len	 = DataLen;
-	*Offset = 0;
-
-	while (len > sizeof(RSNIE2))
-	{
-		pEid = (PEID_STRUCT) pVIE;
-		// WPA RSN IE
-		if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)))
-		{
-			if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) &&
-				(NdisEqualMemory(pVIE, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len)) &&
-				(pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == (pEid->Len + 2)))
-			{
-					DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> WPA/WPAPSK RSN IE matched in Msg 3, Length(%d) \n", (pEid->Len + 2)));
-					result = TRUE;
-			}
-
-			*Offset += (pEid->Len + 2);
-		}
-		// WPA2 RSN IE
-		else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)))
-		{
-			if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2 || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) &&
-				(NdisEqualMemory(pVIE, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len)) &&
-				(pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == (pEid->Len + 2)))
-			{
-					DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", (pEid->Len + 2)));
-					result = TRUE;
-			}
-
-			*Offset += (pEid->Len + 2);
-		}
-		else
-		{
-			break;
-		}
-
-		pVIE += (pEid->Len + 2);
-		len  -= (pEid->Len + 2);
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> skip_offset(%d) \n", *Offset));
-
-	return result;
-
-}
-
-
-/*
-    ========================================================================
-
-    Routine Description:
-    Parse KEYDATA field.  KEYDATA[] May contain 2 RSN IE and optionally GTK.
-    GTK  is encaptulated in KDE format at  p.83 802.11i D10
-
-    Arguments:
-
-    Return Value:
-
-    Note:
-        802.11i D10
-
-    ========================================================================
-*/
-BOOLEAN ParseKeyData(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pKeyData,
-	IN  UCHAR           KeyDataLen,
-	IN	UCHAR			bPairewise)
-{
-    PKDE_ENCAP          pKDE = NULL;
-    PUCHAR              pMyKeyData = pKeyData;
-    UCHAR               KeyDataLength = KeyDataLen;
-    UCHAR               GTKLEN;
-	UCHAR				skip_offset;
-
-	// Verify The RSN IE contained in Pairewise-Msg 3 and skip it
-	if (bPairewise)
-    {
-		// Check RSN IE whether it is WPA2/WPA2PSK
-		if (!CheckRSNIE(pAd, pKeyData, KeyDataLen, &skip_offset))
-		{
-			DBGPRINT(RT_DEBUG_ERROR, ("ParseKeyData ==> WPA2/WPA2PSK RSN IE mismatched \n"));
-			hex_dump("Get KEYDATA :", pKeyData, KeyDataLen);
-			return FALSE;
-    	}
-    	else
-		{
-			// skip RSN IE
-			pMyKeyData += skip_offset;
-			KeyDataLength -= skip_offset;
-
-			//DBGPRINT(RT_DEBUG_TRACE, ("ParseKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset));
-		}
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,("ParseKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength));
-
-	// Parse EKD format
-	if (KeyDataLength >= 8)
-    {
-        pKDE = (PKDE_ENCAP) pMyKeyData;
-    }
-	else
-    {
-		DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KeyDataLength is too short \n"));
-        return FALSE;
-    }
-
-
-	// Sanity check - shared key index should not be 0
-	if (pKDE->GTKEncap.Kid == 0)
-    {
-        DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index zero \n"));
-        return FALSE;
-    }
-
-	// Sanity check - KED length
-	if (KeyDataLength < (pKDE->Len + 2))
-    {
-        DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The len from KDE is too short \n"));
-        return FALSE;
-    }
-
-	// Get GTK length - refer to IEEE 802.11i-2004 p.82
-	GTKLEN = pKDE->Len -6;
-
-	if (GTKLEN < LEN_AES_KEY)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));
-        return FALSE;
-	}
-	else
-		DBGPRINT(RT_DEBUG_TRACE, ("GTK Key with KDE formet got index=%d, len=%d \n", pKDE->GTKEncap.Kid, GTKLEN));
-
-	// Update GTK
-	// set key material, TxMic and RxMic for WPAPSK
-	NdisMoveMemory(pAd->StaCfg.GTK, pKDE->GTKEncap.GTK, 32);
-	pAd->StaCfg.DefaultKeyId = pKDE->GTKEncap.Kid;
-
-	// Update shared key table
-	NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
-	pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
-	NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKDE->GTKEncap.GTK, LEN_TKIP_EK);
-	NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, &pKDE->GTKEncap.GTK[16], LEN_TKIP_RXMICK);
-	NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, &pKDE->GTKEncap.GTK[24], LEN_TKIP_TXMICK);
-
-	// Update Shared Key CipherAlg
-	pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
-	if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
-		pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
-	else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
-		pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
-	else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
-		pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP64;
-	else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
-		pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP128;
-
-	return TRUE;
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Cisco CCKM PRF function
-
-	Arguments:
-		key				Cisco Base Transient Key (BTK)
-		key_len			The key length of the BTK
-		data			Ruquest Number(RN) + BSSID
-		data_len		The length of the data
-		output			Store for PTK(Pairwise transient keys)
-		len				The length of the output
-	Return Value:
-		None
-
-	Note:
-		802.1i	Annex F.9
-
-	========================================================================
-*/
-VOID CCKMPRF(
-	IN	UCHAR	*key,
-	IN	INT		key_len,
-	IN	UCHAR	*data,
-	IN	INT		data_len,
-	OUT	UCHAR	*output,
-	IN	INT		len)
-{
-	INT		i;
-	UCHAR	input[1024];
-	INT		currentindex = 0;
-	INT		total_len;
-
-	NdisMoveMemory(input, data, data_len);
-	total_len = data_len;
-	input[total_len] = 0;
-	total_len++;
-	for	(i = 0;	i <	(len + 19) / 20; i++)
-	{
-		HMAC_SHA1(input, total_len,	key, key_len, &output[currentindex]);
-		currentindex +=	20;
-		input[total_len - 1]++;
-	}
-}
+void inc_byte_array(u8 * counter, int len);
 
 /*
 	========================================================================
@@ -1864,189 +58,178 @@
 
 	========================================================================
 */
-VOID	RTMPReportMicError(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PCIPHER_KEY 	pWpaKey)
+void RTMPReportMicError(struct rt_rtmp_adapter *pAd, struct rt_cipher_key *pWpaKey)
 {
-	ULONG	Now;
-    UCHAR   unicastKey = (pWpaKey->Type == PAIRWISE_KEY ? 1:0);
+	unsigned long Now;
+	u8 unicastKey = (pWpaKey->Type == PAIRWISE_KEY ? 1 : 0);
 
-	// Record Last MIC error time and count
-	Now = jiffies;
-	if (pAd->StaCfg.MicErrCnt == 0)
-	{
+	/* Record Last MIC error time and count */
+	NdisGetSystemUpTime(&Now);
+	if (pAd->StaCfg.MicErrCnt == 0) {
 		pAd->StaCfg.MicErrCnt++;
 		pAd->StaCfg.LastMicErrorTime = Now;
-        NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
-	}
-	else if (pAd->StaCfg.MicErrCnt == 1)
-	{
-		if ((pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ)) < Now)
-		{
-			// Update Last MIC error time, this did not violate two MIC errors within 60 seconds
+		NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
+	} else if (pAd->StaCfg.MicErrCnt == 1) {
+		if ((pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ)) < Now) {
+			/* Update Last MIC error time, this did not violate two MIC errors within 60 seconds */
 			pAd->StaCfg.LastMicErrorTime = Now;
-		}
-		else
-		{
+		} else {
 
 			if (pAd->CommonCfg.bWirelessEvent)
-				RTMPSendWirelessEvent(pAd, IW_COUNTER_MEASURES_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+				RTMPSendWirelessEvent(pAd,
+						      IW_COUNTER_MEASURES_EVENT_FLAG,
+						      pAd->MacTab.
+						      Content[BSSID_WCID].Addr,
+						      BSS0, 0);
 
 			pAd->StaCfg.LastMicErrorTime = Now;
-			// Violate MIC error counts, MIC countermeasures kicks in
+			/* Violate MIC error counts, MIC countermeasures kicks in */
 			pAd->StaCfg.MicErrCnt++;
+			/* We shall block all reception */
+			/* We shall clean all Tx ring and disassoicate from AP after next EAPOL frame */
+			/* */
+			/* No necessary to clean all Tx ring, on RTMPHardTransmit will stop sending non-802.1X EAPOL packets */
+			/* if pAd->StaCfg.MicErrCnt greater than 2. */
+			/* */
+			/* RTMPRingCleanUp(pAd, QID_AC_BK); */
+			/* RTMPRingCleanUp(pAd, QID_AC_BE); */
+			/* RTMPRingCleanUp(pAd, QID_AC_VI); */
+			/* RTMPRingCleanUp(pAd, QID_AC_VO); */
+			/* RTMPRingCleanUp(pAd, QID_HCCA); */
 		}
-	}
-	else
-	{
-		// MIC error count >= 2
-		// This should not happen
+	} else {
+		/* MIC error count >= 2 */
+		/* This should not happen */
 		;
 	}
-    MlmeEnqueue(pAd,
-				MLME_CNTL_STATE_MACHINE,
-				OID_802_11_MIC_FAILURE_REPORT_FRAME,
-				1,
-				&unicastKey);
+	MlmeEnqueue(pAd,
+		    MLME_CNTL_STATE_MACHINE,
+		    OID_802_11_MIC_FAILURE_REPORT_FRAME, 1, &unicastKey);
 
-    if (pAd->StaCfg.MicErrCnt == 2)
-    {
-        RTMPSetTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, 100);
-    }
+	if (pAd->StaCfg.MicErrCnt == 2) {
+		RTMPSetTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, 100);
+	}
 }
 
 #define	LENGTH_EAP_H    4
-// If the received frame is EAP-Packet ,find out its EAP-Code (Request(0x01), Response(0x02), Success(0x03), Failure(0x04)).
-INT	    WpaCheckEapCode(
-	IN  PRTMP_ADAPTER   		pAd,
-	IN  PUCHAR				pFrame,
-	IN  USHORT				FrameLen,
-	IN  USHORT				OffSet)
+/* If the received frame is EAP-Packet ,find out its EAP-Code (Request(0x01), Response(0x02), Success(0x03), Failure(0x04)). */
+int WpaCheckEapCode(struct rt_rtmp_adapter *pAd,
+		    u8 *pFrame, u16 FrameLen, u16 OffSet)
 {
 
-	PUCHAR	pData;
-	INT	result = 0;
+	u8 *pData;
+	int result = 0;
 
-	if( FrameLen < OffSet + LENGTH_EAPOL_H + LENGTH_EAP_H )
+	if (FrameLen < OffSet + LENGTH_EAPOL_H + LENGTH_EAP_H)
 		return result;
 
-	pData = pFrame + OffSet; // skip offset bytes
+	pData = pFrame + OffSet;	/* skip offset bytes */
 
-	if(*(pData+1) == EAPPacket) 	// 802.1x header - Packet Type
+	if (*(pData + 1) == EAPPacket)	/* 802.1x header - Packet Type */
 	{
-		 result = *(pData+4);		// EAP header - Code
+		result = *(pData + 4);	/* EAP header - Code */
 	}
 
 	return result;
 }
 
-VOID    WpaSendMicFailureToWpaSupplicant(
-    IN  PRTMP_ADAPTER    pAd,
-    IN  BOOLEAN          bUnicast)
+void WpaSendMicFailureToWpaSupplicant(struct rt_rtmp_adapter *pAd, IN BOOLEAN bUnicast)
 {
-    union iwreq_data    wrqu;
-    char custom[IW_CUSTOM_MAX] = {0};
+	char custom[IW_CUSTOM_MAX] = { 0 };
 
-    sprintf(custom, "MLME-MICHAELMICFAILURE.indication");
-    if (bUnicast)
-        sprintf(custom, "%s unicast", custom);
-    wrqu.data.length = strlen(custom);
-    wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
+	sprintf(custom, "MLME-MICHAELMICFAILURE.indication");
+	if (bUnicast)
+		sprintf(custom, "%s unicast", custom);
 
-    return;
+	RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, -1, NULL, (u8 *)custom,
+				strlen(custom));
+
+	return;
 }
 
-VOID	WpaMicFailureReportFrame(
-	IN  PRTMP_ADAPTER   pAd,
-	IN MLME_QUEUE_ELEM *Elem)
+void WpaMicFailureReportFrame(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
 {
-	PUCHAR              pOutBuffer = NULL;
-	UCHAR               Header802_3[14];
-	ULONG               FrameLen = 0;
-	EAPOL_PACKET        Packet;
-	UCHAR               Mic[16];
-    BOOLEAN             bUnicast;
+	u8 *pOutBuffer = NULL;
+	u8 Header802_3[14];
+	unsigned long FrameLen = 0;
+	struct rt_eapol_packet Packet;
+	u8 Mic[16];
+	BOOLEAN bUnicast;
 
 	DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame ----->\n"));
 
-    bUnicast = (Elem->Msg[0] == 1 ? TRUE:FALSE);
+	bUnicast = (Elem->Msg[0] == 1 ? TRUE : FALSE);
 	pAd->Sequence = ((pAd->Sequence) + 1) & (MAX_SEQ_NUMBER);
 
-	// init 802.3 header and Fill Packet
-	MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+	/* init 802.3 header and Fill Packet */
+	MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid,
+			  pAd->CurrentAddress, EAPOL);
 
 	NdisZeroMemory(&Packet, sizeof(Packet));
-	Packet.ProVer	= EAPOL_VER;
-	Packet.ProType	= EAPOLKey;
+	Packet.ProVer = EAPOL_VER;
+	Packet.ProType = EAPOLKey;
 
 	Packet.KeyDesc.Type = WPA1_KEY_DESC;
 
-    // Request field presented
-    Packet.KeyDesc.KeyInfo.Request = 1;
+	/* Request field presented */
+	Packet.KeyDesc.KeyInfo.Request = 1;
 
-	if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
-	{
+	if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) {
 		Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
-	}
-	else	  // TKIP
+	} else			/* TKIP */
 	{
 		Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
 	}
 
-    Packet.KeyDesc.KeyInfo.KeyType = (bUnicast ? PAIRWISEKEY : GROUPKEY);
+	Packet.KeyDesc.KeyInfo.KeyType = (bUnicast ? PAIRWISEKEY : GROUPKEY);
 
-	// KeyMic field presented
-	Packet.KeyDesc.KeyInfo.KeyMic  = 1;
+	/* KeyMic field presented */
+	Packet.KeyDesc.KeyInfo.KeyMic = 1;
 
-    // Error field presented
-	Packet.KeyDesc.KeyInfo.Error  = 1;
+	/* Error field presented */
+	Packet.KeyDesc.KeyInfo.Error = 1;
 
-	// Update packet length after decide Key data payload
-	Packet.Body_Len[1]  = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE;
+	/* Update packet length after decide Key data payload */
+	SET_u16_TO_ARRARY(Packet.Body_Len, LEN_EAPOL_KEY_MSG)
+	    /* Key Replay Count */
+	    NdisMoveMemory(Packet.KeyDesc.ReplayCounter,
+			   pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
+	inc_byte_array(pAd->StaCfg.ReplayCounter, 8);
 
-	// Key Replay Count
-	NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
-    inc_byte_array(pAd->StaCfg.ReplayCounter, 8);
+	/* Convert to little-endian format. */
+	*((u16 *) & Packet.KeyDesc.KeyInfo) =
+	    cpu2le16(*((u16 *) & Packet.KeyDesc.KeyInfo));
 
-	// Convert to little-endian format.
-	*((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
-
-
-	MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer);  // allocate memory
-	if(pOutBuffer == NULL)
-	{
+	MlmeAllocateMemory(pAd, (u8 **) & pOutBuffer);	/* allocate memory */
+	if (pOutBuffer == NULL) {
 		return;
 	}
+	/* Prepare EAPOL frame for MIC calculation */
+	/* Be careful, only EAPOL frame is counted for MIC calculation */
+	MakeOutgoingFrame(pOutBuffer, &FrameLen,
+			  CONV_ARRARY_TO_u16(Packet.Body_Len) + 4, &Packet,
+			  END_OF_ARGS);
 
-	// Prepare EAPOL frame for MIC calculation
-	// Be careful, only EAPOL frame is counted for MIC calculation
-	MakeOutgoingFrame(pOutBuffer,               &FrameLen,
-		              Packet.Body_Len[1] + 4,   &Packet,
-		              END_OF_ARGS);
-
-	// Prepare and Fill MIC value
+	/* Prepare and Fill MIC value */
 	NdisZeroMemory(Mic, sizeof(Mic));
-	if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
-	{	// AES
-        UCHAR digest[20] = {0};
-		HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
+	if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) {	/* AES */
+		u8 digest[20] = { 0 };
+		HMAC_SHA1(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen,
+			  digest, SHA1_DIGEST_SIZE);
 		NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
-	}
-	else
-	{	// TKIP
-		hmac_md5(pAd->StaCfg.PTK,  LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+	} else {		/* TKIP */
+		HMAC_MD5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen,
+			 Mic, MD5_DIGEST_SIZE);
 	}
 	NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
 
-    MakeOutgoingFrame(pOutBuffer,           	&FrameLen,
-    	  			LENGTH_802_3,     			&Header802_3,
-    				Packet.Body_Len[1] + 4,     &Packet,
-    				END_OF_ARGS);
+	/* copy frame to Tx ring and send MIC failure report frame to authenticator */
+	RTMPToWirelessSta(pAd, &pAd->MacTab.Content[BSSID_WCID],
+			  Header802_3, LENGTH_802_3,
+			  (u8 *)& Packet,
+			  CONV_ARRARY_TO_u16(Packet.Body_Len) + 4, FALSE);
 
-	// opy frame to Tx ring and send MIC failure report frame to authenticator
-	RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, FALSE);
-
-	MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
+	MlmeFreeMemory(pAd, (u8 *)pOutBuffer);
 
 	DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame <-----\n"));
 }
@@ -2060,7 +243,7 @@
  * rolling over to more significant bytes if the byte was incremented from
  * 0xff to 0x00.
  */
-void inc_byte_array(UCHAR *counter, int len)
+void inc_byte_array(u8 * counter, int len)
 {
 	int pos = len - 1;
 	while (pos >= 0) {
@@ -2071,21 +254,120 @@
 	}
 }
 
-VOID WpaDisassocApAndBlockAssoc(
-    IN PVOID SystemSpecific1,
-    IN PVOID FunctionContext,
-    IN PVOID SystemSpecific2,
-    IN PVOID SystemSpecific3)
+void WpaDisassocApAndBlockAssoc(void *SystemSpecific1,
+				void *FunctionContext,
+				void *SystemSpecific2,
+				void *SystemSpecific3)
 {
-    RTMP_ADAPTER                *pAd = (PRTMP_ADAPTER)FunctionContext;
-    MLME_DISASSOC_REQ_STRUCT    DisassocReq;
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
+	struct rt_mlme_disassoc_req DisassocReq;
 
-	// disassoc from current AP first
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPReportMicError - disassociate with current AP after sending second continuous EAPOL frame\n"));
-	DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_MIC_FAILURE);
-	MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+	/* disassoc from current AP first */
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("RTMPReportMicError - disassociate with current AP after sending second continuous EAPOL frame\n"));
+	DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid,
+			 REASON_MIC_FAILURE);
+	MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
+		    sizeof(struct rt_mlme_disassoc_req), &DisassocReq);
 
 	pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
 	pAd->StaCfg.bBlockAssoc = TRUE;
 }
 
+void WpaStaPairwiseKeySetting(struct rt_rtmp_adapter *pAd)
+{
+	struct rt_cipher_key *pSharedKey;
+	struct rt_mac_table_entry *pEntry;
+
+	pEntry = &pAd->MacTab.Content[BSSID_WCID];
+
+	/* Pairwise key shall use key#0 */
+	pSharedKey = &pAd->SharedKey[BSS0][0];
+
+	NdisMoveMemory(pAd->StaCfg.PTK, pEntry->PTK, LEN_PTK);
+
+	/* Prepare pair-wise key information into shared key table */
+	NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key));
+	pSharedKey->KeyLen = LEN_TKIP_EK;
+	NdisMoveMemory(pSharedKey->Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
+	NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.PTK[48],
+		       LEN_TKIP_RXMICK);
+	NdisMoveMemory(pSharedKey->TxMic,
+		       &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
+
+	/* Decide its ChiperAlg */
+	if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+		pSharedKey->CipherAlg = CIPHER_TKIP;
+	else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
+		pSharedKey->CipherAlg = CIPHER_AES;
+	else
+		pSharedKey->CipherAlg = CIPHER_NONE;
+
+	/* Update these related information to struct rt_mac_table_entry */
+	NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32],
+		       LEN_TKIP_EK);
+	NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48],
+		       LEN_TKIP_RXMICK);
+	NdisMoveMemory(pEntry->PairwiseKey.TxMic,
+		       &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
+	pEntry->PairwiseKey.CipherAlg = pSharedKey->CipherAlg;
+
+	/* Update pairwise key information to ASIC Shared Key Table */
+	AsicAddSharedKeyEntry(pAd,
+			      BSS0,
+			      0,
+			      pSharedKey->CipherAlg,
+			      pSharedKey->Key,
+			      pSharedKey->TxMic, pSharedKey->RxMic);
+
+	/* Update ASIC WCID attribute table and IVEIV table */
+	RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pSharedKey->CipherAlg, pEntry);
+	STA_PORT_SECURED(pAd);
+	pAd->IndicateMediaState = NdisMediaStateConnected;
+
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("%s : AID(%d) port secured\n", __func__, pEntry->Aid));
+
+}
+
+void WpaStaGroupKeySetting(struct rt_rtmp_adapter *pAd)
+{
+	struct rt_cipher_key *pSharedKey;
+
+	pSharedKey = &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId];
+
+	/* Prepare pair-wise key information into shared key table */
+	NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key));
+	pSharedKey->KeyLen = LEN_TKIP_EK;
+	NdisMoveMemory(pSharedKey->Key, pAd->StaCfg.GTK, LEN_TKIP_EK);
+	NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.GTK[16],
+		       LEN_TKIP_RXMICK);
+	NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.GTK[24],
+		       LEN_TKIP_TXMICK);
+
+	/* Update Shared Key CipherAlg */
+	pSharedKey->CipherAlg = CIPHER_NONE;
+	if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
+		pSharedKey->CipherAlg = CIPHER_TKIP;
+	else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
+		pSharedKey->CipherAlg = CIPHER_AES;
+	else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
+		pSharedKey->CipherAlg = CIPHER_WEP64;
+	else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
+		pSharedKey->CipherAlg = CIPHER_WEP128;
+
+	/* Update group key information to ASIC Shared Key Table */
+	AsicAddSharedKeyEntry(pAd,
+			      BSS0,
+			      pAd->StaCfg.DefaultKeyId,
+			      pSharedKey->CipherAlg,
+			      pSharedKey->Key,
+			      pSharedKey->TxMic, pSharedKey->RxMic);
+
+	/* Update ASIC WCID attribute table and IVEIV table */
+	RTMPAddWcidAttributeEntry(pAd,
+				  BSS0,
+				  pAd->StaCfg.DefaultKeyId,
+				  pSharedKey->CipherAlg, NULL);
+
+}
diff --git a/drivers/staging/rt2860/sta_ioctl.c b/drivers/staging/rt2860/sta_ioctl.c
index c0e0425..d8fbe6c 100644
--- a/drivers/staging/rt2860/sta_ioctl.c
+++ b/drivers/staging/rt2860/sta_ioctl.c
@@ -40,7 +40,7 @@
 #include	"rt_config.h"
 
 #ifdef DBG
-extern ULONG    RTDebugLevel;
+extern unsigned long RTDebugLevel;
 #endif
 
 #define NR_WEP_KEYS 				4
@@ -49,424 +49,310 @@
 
 #define GROUP_KEY_NO                4
 
-extern UCHAR    CipherWpa2Template[];
-extern UCHAR    CipherWpaPskTkip[];
-extern UCHAR    CipherWpaPskTkipLen;
+extern u8 CipherWpa2Template[];
 
-typedef struct PACKED _RT_VERSION_INFO{
-    UCHAR       DriverVersionW;
-    UCHAR       DriverVersionX;
-    UCHAR       DriverVersionY;
-    UCHAR       DriverVersionZ;
-    UINT        DriverBuildYear;
-    UINT        DriverBuildMonth;
-    UINT        DriverBuildDay;
-} RT_VERSION_INFO, *PRT_VERSION_INFO;
-
-struct iw_priv_args privtab[] = {
-{ RTPRIV_IOCTL_SET,
-  IW_PRIV_TYPE_CHAR | 1024, 0,
-  "set"},
-
-{ RTPRIV_IOCTL_SHOW, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
-  ""},
-{ RTPRIV_IOCTL_SHOW, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
-  ""},
-/* --- sub-ioctls definitions --- */
-    { SHOW_CONN_STATUS,
-	  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "connStatus" },
-	{ SHOW_DRVIER_VERION,
-	  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "driverVer" },
-    { SHOW_BA_INFO,
-	  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "bainfo" },
-	{ SHOW_DESC_INFO,
-	  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "descinfo" },
-    { RAIO_OFF,
-	  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_off" },
-	{ RAIO_ON,
-	  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_on" },
-	{ SHOW_CFG_VALUE,
-	  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "show" },
-/* --- sub-ioctls relations --- */
-
-{ RTPRIV_IOCTL_STATISTICS,
-  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
-  "stat"},
-{ RTPRIV_IOCTL_GSITESURVEY,
-  0, IW_PRIV_TYPE_CHAR | 1024,
-  "get_site_survey"},
+struct PACKED rt_version_info {
+	u8 DriverVersionW;
+	u8 DriverVersionX;
+	u8 DriverVersionY;
+	u8 DriverVersionZ;
+	u32 DriverBuildYear;
+	u32 DriverBuildMonth;
+	u32 DriverBuildDay;
 };
 
-INT Set_SSID_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          arg);
-
-#ifdef WMM_SUPPORT
-INT	Set_WmmCapable_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-#endif
-
-INT Set_NetworkType_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          arg);
-
-INT Set_AuthMode_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          arg);
-
-INT Set_EncrypType_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          arg);
-
-INT Set_DefaultKeyID_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          arg);
-
-INT Set_Key1_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          arg);
-
-INT Set_Key2_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          arg);
-
-INT Set_Key3_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          arg);
-
-INT Set_Key4_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          arg);
-
-INT Set_WPAPSK_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          arg);
-
-
-INT Set_PSMode_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          arg);
-
-INT Set_Wpa_Support(
-    IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-NDIS_STATUS RTMPWPANoneAddKeyProc(
-    IN  PRTMP_ADAPTER   pAd,
-    IN	PVOID			pBuf);
-
-INT Set_FragTest_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          arg);
-
-INT Set_TGnWifiTest_Proc(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PUCHAR          arg);
-
-INT Set_LongRetryLimit_Proc(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	PUCHAR			arg);
-
-INT Set_ShortRetryLimit_Proc(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	PUCHAR			arg);
-
-static struct {
-	CHAR *name;
-	INT (*set_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg);
-} *PRTMP_PRIVATE_SET_PROC, RTMP_PRIVATE_SUPPORT_PROC[] = {
-	{"DriverVersion",				Set_DriverVersion_Proc},
-	{"CountryRegion",				Set_CountryRegion_Proc},
-	{"CountryRegionABand",			Set_CountryRegionABand_Proc},
-	{"SSID",						Set_SSID_Proc},
-	{"WirelessMode",				Set_WirelessMode_Proc},
-	{"TxBurst",					Set_TxBurst_Proc},
-	{"TxPreamble",				Set_TxPreamble_Proc},
-	{"TxPower",					Set_TxPower_Proc},
-	{"Channel",					Set_Channel_Proc},
-	{"BGProtection",				Set_BGProtection_Proc},
-	{"RTSThreshold",				Set_RTSThreshold_Proc},
-	{"FragThreshold",				Set_FragThreshold_Proc},
-	{"HtBw",		                Set_HtBw_Proc},
-	{"HtMcs",		                Set_HtMcs_Proc},
-	{"HtGi",		                Set_HtGi_Proc},
-	{"HtOpMode",		            Set_HtOpMode_Proc},
-	{"HtExtcha",		            Set_HtExtcha_Proc},
-	{"HtMpduDensity",		        Set_HtMpduDensity_Proc},
-	{"HtBaWinSize",		        	Set_HtBaWinSize_Proc},
-	{"HtRdg",		        		Set_HtRdg_Proc},
-	{"HtAmsdu",		        		Set_HtAmsdu_Proc},
-	{"HtAutoBa",		        	Set_HtAutoBa_Proc},
-	{"HtBaDecline",					Set_BADecline_Proc},
-	{"HtProtect",		        	Set_HtProtect_Proc},
-	{"HtMimoPs",		        	Set_HtMimoPs_Proc},
-#ifdef AGGREGATION_SUPPORT
-	{"PktAggregate",				Set_PktAggregate_Proc},
-#endif
-
-#ifdef WMM_SUPPORT
-	{"WmmCapable",					Set_WmmCapable_Proc},
-#endif
-	{"IEEE80211H",					Set_IEEE80211H_Proc},
-    {"NetworkType",                 Set_NetworkType_Proc},
-	{"AuthMode",					Set_AuthMode_Proc},
-	{"EncrypType",					Set_EncrypType_Proc},
-	{"DefaultKeyID",				Set_DefaultKeyID_Proc},
-	{"Key1",						Set_Key1_Proc},
-	{"Key2",						Set_Key2_Proc},
-	{"Key3",						Set_Key3_Proc},
-	{"Key4",						Set_Key4_Proc},
-	{"WPAPSK",						Set_WPAPSK_Proc},
-	{"ResetCounter",				Set_ResetStatCounter_Proc},
-	{"PSMode",                      Set_PSMode_Proc},
-#ifdef DBG
-	{"Debug",						Set_Debug_Proc},
-#endif
-    {"WpaSupport",                  Set_Wpa_Support},
-	{"FixedTxMode",                 Set_FixedTxMode_Proc},
-    {"TGnWifiTest",                 Set_TGnWifiTest_Proc},
-    {"ForceGF",		        		Set_ForceGF_Proc},
-	{"LongRetry",	        		Set_LongRetryLimit_Proc},
-	{"ShortRetry",	        		Set_ShortRetryLimit_Proc},
-#ifdef RT2870
-	{"efuseFreeNumber",				set_eFuseGetFreeBlockCount_Proc},
-	{"efuseDump",					set_eFusedump_Proc},
-	{"efuseLoadFromBin",				set_eFuseLoadFromBin_Proc},
-#endif
-	{NULL,}
+static __s32 ralinkrate[] = { 2, 4, 11, 22,	/* CCK */
+	12, 18, 24, 36, 48, 72, 96, 108,	/* OFDM */
+	13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260,	/* 20MHz, 800ns GI, MCS: 0 ~ 15 */
+	39, 78, 117, 156, 234, 312, 351, 390,	/* 20MHz, 800ns GI, MCS: 16 ~ 23 */
+	27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540,	/* 40MHz, 800ns GI, MCS: 0 ~ 15 */
+	81, 162, 243, 324, 486, 648, 729, 810,	/* 40MHz, 800ns GI, MCS: 16 ~ 23 */
+	14, 29, 43, 57, 87, 115, 130, 144, 29, 59, 87, 115, 173, 230, 260, 288,	/* 20MHz, 400ns GI, MCS: 0 ~ 15 */
+	43, 87, 130, 173, 260, 317, 390, 433,	/* 20MHz, 400ns GI, MCS: 16 ~ 23 */
+	30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600,	/* 40MHz, 400ns GI, MCS: 0 ~ 15 */
+	90, 180, 270, 360, 540, 720, 810, 900
 };
 
+int Set_SSID_Proc(struct rt_rtmp_adapter *pAdapter, char *arg);
 
-VOID RTMPAddKey(
-	IN	PRTMP_ADAPTER	    pAd,
-	IN	PNDIS_802_11_KEY    pKey)
+int Set_NetworkType_Proc(struct rt_rtmp_adapter *pAdapter, char *arg);
+
+void RTMPAddKey(struct rt_rtmp_adapter *pAd, struct rt_ndis_802_11_key *pKey)
 {
-	ULONG				KeyIdx;
-	MAC_TABLE_ENTRY  	*pEntry;
+	unsigned long KeyIdx;
+	struct rt_mac_table_entry *pEntry;
 
-    DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey ------>\n"));
+	DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey ------>\n"));
 
-#ifdef RT2860
-	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-	if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
-	{
-		if (pAd->StaCfg.bRadio == FALSE)
-		{
-			RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-			return;
-		}
-		DBGPRINT(RT_DEBUG_TRACE,("RTMPWPAAddKeyProc1==>\n"));
-		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
-		RTMPusecDelay(6000);
-		pAd->bPCIclkOff = FALSE;
-	}
-#endif
+	if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) {
+		if (pKey->KeyIndex & 0x80000000) {
+			if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) {
+				NdisZeroMemory(pAd->StaCfg.PMK, 32);
+				NdisMoveMemory(pAd->StaCfg.PMK,
+					       pKey->KeyMaterial,
+					       pKey->KeyLength);
+				goto end;
+			}
+			/* Update PTK */
+			NdisZeroMemory(&pAd->SharedKey[BSS0][0],
+				       sizeof(struct rt_cipher_key));
+			pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
+			NdisMoveMemory(pAd->SharedKey[BSS0][0].Key,
+				       pKey->KeyMaterial, LEN_TKIP_EK);
 
-	if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-	{
-		if (pKey->KeyIndex & 0x80000000)
-		{
-		    if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
-            {
-                NdisZeroMemory(pAd->StaCfg.PMK, 32);
-                NdisMoveMemory(pAd->StaCfg.PMK, pKey->KeyMaterial, pKey->KeyLength);
-                goto end;
-            }
-		    // Update PTK
-		    NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
-            pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
-            NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pKey->KeyMaterial, LEN_TKIP_EK);
+			if (pAd->StaCfg.PairCipher ==
+			    Ndis802_11Encryption2Enabled) {
+				NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic,
+					       pKey->KeyMaterial + LEN_TKIP_EK,
+					       LEN_TKIP_TXMICK);
+				NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic,
+					       pKey->KeyMaterial + LEN_TKIP_EK +
+					       LEN_TKIP_TXMICK,
+					       LEN_TKIP_RXMICK);
+			} else {
+				NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic,
+					       pKey->KeyMaterial + LEN_TKIP_EK,
+					       LEN_TKIP_TXMICK);
+				NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic,
+					       pKey->KeyMaterial + LEN_TKIP_EK +
+					       LEN_TKIP_TXMICK,
+					       LEN_TKIP_RXMICK);
+			}
 
-            if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
-            {
-                NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
-                NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
-            }
-            else
-            {
-            	NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
-                NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
-            }
+			/* Decide its ChiperAlg */
+			if (pAd->StaCfg.PairCipher ==
+			    Ndis802_11Encryption2Enabled)
+				pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
+			else if (pAd->StaCfg.PairCipher ==
+				 Ndis802_11Encryption3Enabled)
+				pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
+			else
+				pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
 
-            // Decide its ChiperAlg
-        	if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
-        		pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
-        	else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
-        		pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
-        	else
-        		pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
+			/* Update these related information to struct rt_mac_table_entry */
+			pEntry = &pAd->MacTab.Content[BSSID_WCID];
+			NdisMoveMemory(pEntry->PairwiseKey.Key,
+				       pAd->SharedKey[BSS0][0].Key,
+				       LEN_TKIP_EK);
+			NdisMoveMemory(pEntry->PairwiseKey.RxMic,
+				       pAd->SharedKey[BSS0][0].RxMic,
+				       LEN_TKIP_RXMICK);
+			NdisMoveMemory(pEntry->PairwiseKey.TxMic,
+				       pAd->SharedKey[BSS0][0].TxMic,
+				       LEN_TKIP_TXMICK);
+			pEntry->PairwiseKey.CipherAlg =
+			    pAd->SharedKey[BSS0][0].CipherAlg;
 
-            // Update these related information to MAC_TABLE_ENTRY
-        	pEntry = &pAd->MacTab.Content[BSSID_WCID];
-            NdisMoveMemory(pEntry->PairwiseKey.Key, pAd->SharedKey[BSS0][0].Key, LEN_TKIP_EK);
-        	NdisMoveMemory(pEntry->PairwiseKey.RxMic, pAd->SharedKey[BSS0][0].RxMic, LEN_TKIP_RXMICK);
-        	NdisMoveMemory(pEntry->PairwiseKey.TxMic, pAd->SharedKey[BSS0][0].TxMic, LEN_TKIP_TXMICK);
-        	pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
+			/* Update pairwise key information to ASIC Shared Key Table */
+			AsicAddSharedKeyEntry(pAd,
+					      BSS0,
+					      0,
+					      pAd->SharedKey[BSS0][0].CipherAlg,
+					      pAd->SharedKey[BSS0][0].Key,
+					      pAd->SharedKey[BSS0][0].TxMic,
+					      pAd->SharedKey[BSS0][0].RxMic);
 
-        	// Update pairwise key information to ASIC Shared Key Table
-        	AsicAddSharedKeyEntry(pAd,
-        						  BSS0,
-        						  0,
-        						  pAd->SharedKey[BSS0][0].CipherAlg,
-        						  pAd->SharedKey[BSS0][0].Key,
-        						  pAd->SharedKey[BSS0][0].TxMic,
-        						  pAd->SharedKey[BSS0][0].RxMic);
+			/* Update ASIC WCID attribute table and IVEIV table */
+			RTMPAddWcidAttributeEntry(pAd,
+						  BSS0,
+						  0,
+						  pAd->SharedKey[BSS0][0].
+						  CipherAlg, pEntry);
 
-        	// Update ASIC WCID attribute table and IVEIV table
-        	RTMPAddWcidAttributeEntry(pAd,
-        							  BSS0,
-        							  0,
-        							  pAd->SharedKey[BSS0][0].CipherAlg,
-        							  pEntry);
-
-            if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
-            {
-                // set 802.1x port control
+			if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2) {
+				/* set 802.1x port control */
+				/*pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
 				STA_PORT_SECURED(pAd);
 
-                // Indicate Connected for GUI
-                pAd->IndicateMediaState = NdisMediaStateConnected;
-            }
-		}
-        else
-        {
-            // Update GTK
-            pAd->StaCfg.DefaultKeyId = (pKey->KeyIndex & 0xFF);
-            NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
-            pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
-            NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKey->KeyMaterial, LEN_TKIP_EK);
+				/* Indicate Connected for GUI */
+				pAd->IndicateMediaState =
+				    NdisMediaStateConnected;
+			}
+		} else {
+			/* Update GTK */
+			pAd->StaCfg.DefaultKeyId = (pKey->KeyIndex & 0xFF);
+			NdisZeroMemory(&pAd->
+				       SharedKey[BSS0][pAd->StaCfg.
+						       DefaultKeyId],
+				       sizeof(struct rt_cipher_key));
+			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen =
+			    LEN_TKIP_EK;
+			NdisMoveMemory(pAd->
+				       SharedKey[BSS0][pAd->StaCfg.
+						       DefaultKeyId].Key,
+				       pKey->KeyMaterial, LEN_TKIP_EK);
 
-            if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
-            {
-                NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
-                NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
-            }
-            else
-            {
-            	NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
-                NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
-            }
+			if (pAd->StaCfg.GroupCipher ==
+			    Ndis802_11Encryption2Enabled) {
+				NdisMoveMemory(pAd->
+					       SharedKey[BSS0][pAd->StaCfg.
+							       DefaultKeyId].
+					       RxMic,
+					       pKey->KeyMaterial + LEN_TKIP_EK,
+					       LEN_TKIP_TXMICK);
+				NdisMoveMemory(pAd->
+					       SharedKey[BSS0][pAd->StaCfg.
+							       DefaultKeyId].
+					       TxMic,
+					       pKey->KeyMaterial + LEN_TKIP_EK +
+					       LEN_TKIP_TXMICK,
+					       LEN_TKIP_RXMICK);
+			} else {
+				NdisMoveMemory(pAd->
+					       SharedKey[BSS0][pAd->StaCfg.
+							       DefaultKeyId].
+					       TxMic,
+					       pKey->KeyMaterial + LEN_TKIP_EK,
+					       LEN_TKIP_TXMICK);
+				NdisMoveMemory(pAd->
+					       SharedKey[BSS0][pAd->StaCfg.
+							       DefaultKeyId].
+					       RxMic,
+					       pKey->KeyMaterial + LEN_TKIP_EK +
+					       LEN_TKIP_TXMICK,
+					       LEN_TKIP_RXMICK);
+			}
 
-            // Update Shared Key CipherAlg
-    		pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
-    		if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
-    			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
-    		else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
-    			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
+			/* Update Shared Key CipherAlg */
+			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].
+			    CipherAlg = CIPHER_NONE;
+			if (pAd->StaCfg.GroupCipher ==
+			    Ndis802_11Encryption2Enabled)
+				pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].
+				    CipherAlg = CIPHER_TKIP;
+			else if (pAd->StaCfg.GroupCipher ==
+				 Ndis802_11Encryption3Enabled)
+				pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].
+				    CipherAlg = CIPHER_AES;
 
-            // Update group key information to ASIC Shared Key Table
-        	AsicAddSharedKeyEntry(pAd,
-        						  BSS0,
-        						  pAd->StaCfg.DefaultKeyId,
-        						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
-        						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
-        						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
-        						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
+			/* Update group key information to ASIC Shared Key Table */
+			AsicAddSharedKeyEntry(pAd,
+					      BSS0,
+					      pAd->StaCfg.DefaultKeyId,
+					      pAd->SharedKey[BSS0][pAd->StaCfg.
+								   DefaultKeyId].
+					      CipherAlg,
+					      pAd->SharedKey[BSS0][pAd->StaCfg.
+								   DefaultKeyId].
+					      Key,
+					      pAd->SharedKey[BSS0][pAd->StaCfg.
+								   DefaultKeyId].
+					      TxMic,
+					      pAd->SharedKey[BSS0][pAd->StaCfg.
+								   DefaultKeyId].
+					      RxMic);
 
-        	// Update ASIC WCID attribute table and IVEIV table
-        	RTMPAddWcidAttributeEntry(pAd,
-        							  BSS0,
-        							  pAd->StaCfg.DefaultKeyId,
-        							  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
-        							  NULL);
+			/* Update ASIC WCID attribute table and IVEIV table */
+			RTMPAddWcidAttributeEntry(pAd,
+						  BSS0,
+						  pAd->StaCfg.DefaultKeyId,
+						  pAd->SharedKey[BSS0][pAd->
+								       StaCfg.
+								       DefaultKeyId].
+						  CipherAlg, NULL);
 
-            // set 802.1x port control
+			/* set 802.1x port control */
+			/*pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
 			STA_PORT_SECURED(pAd);
 
-            // Indicate Connected for GUI
-            pAd->IndicateMediaState = NdisMediaStateConnected;
-        }
-	}
-	else	// dynamic WEP from wpa_supplicant
+			/* Indicate Connected for GUI */
+			pAd->IndicateMediaState = NdisMediaStateConnected;
+		}
+	} else			/* dynamic WEP from wpa_supplicant */
 	{
-		UCHAR	CipherAlg;
-    	PUCHAR	Key;
+		u8 CipherAlg;
+		u8 *Key;
 
-		if(pKey->KeyLength == 32)
+		if (pKey->KeyLength == 32)
 			goto end;
 
 		KeyIdx = pKey->KeyIndex & 0x0fffffff;
 
-		if (KeyIdx < 4)
-		{
-			// it is a default shared key, for Pairwise key setting
-			if (pKey->KeyIndex & 0x80000000)
-			{
+		if (KeyIdx < 4) {
+			/* it is a default shared key, for Pairwise key setting */
+			if (pKey->KeyIndex & 0x80000000) {
 				pEntry = MacTableLookup(pAd, pKey->BSSID);
 
-				if (pEntry)
-				{
-					DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey: Set Pair-wise Key\n"));
+				if (pEntry) {
+					DBGPRINT(RT_DEBUG_TRACE,
+						 ("RTMPAddKey: Set Pair-wise Key\n"));
 
-					// set key material and key length
- 					pEntry->PairwiseKey.KeyLen = (UCHAR)pKey->KeyLength;
-					NdisMoveMemory(pEntry->PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
+					/* set key material and key length */
+					pEntry->PairwiseKey.KeyLen =
+					    (u8)pKey->KeyLength;
+					NdisMoveMemory(pEntry->PairwiseKey.Key,
+						       &pKey->KeyMaterial,
+						       pKey->KeyLength);
 
-					// set Cipher type
+					/* set Cipher type */
 					if (pKey->KeyLength == 5)
-						pEntry->PairwiseKey.CipherAlg = CIPHER_WEP64;
+						pEntry->PairwiseKey.CipherAlg =
+						    CIPHER_WEP64;
 					else
-						pEntry->PairwiseKey.CipherAlg = CIPHER_WEP128;
+						pEntry->PairwiseKey.CipherAlg =
+						    CIPHER_WEP128;
 
-					// Add Pair-wise key to Asic
-					AsicAddPairwiseKeyEntry(
-						pAd,
-						pEntry->Addr,
-						(UCHAR)pEntry->Aid,
-                		&pEntry->PairwiseKey);
+					/* Add Pair-wise key to Asic */
+					AsicAddPairwiseKeyEntry(pAd,
+								pEntry->Addr,
+								(u8)pEntry->
+								Aid,
+								&pEntry->
+								PairwiseKey);
 
-					// update WCID attribute table and IVEIV table for this entry
-					RTMPAddWcidAttributeEntry(
-						pAd,
-						BSS0,
-						KeyIdx, // The value may be not zero
-						pEntry->PairwiseKey.CipherAlg,
-						pEntry);
+					/* update WCID attribute table and IVEIV table for this entry */
+					RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx,	/* The value may be not zero */
+								  pEntry->
+								  PairwiseKey.
+								  CipherAlg,
+								  pEntry);
 
 				}
-			}
-			else
-            {
-				// Default key for tx (shared key)
-				pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
+			} else {
+				/* Default key for tx (shared key) */
+				pAd->StaCfg.DefaultKeyId = (u8)KeyIdx;
 
-				// set key material and key length
-				pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pKey->KeyLength;
-				NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pKey->KeyMaterial, pKey->KeyLength);
+				/* set key material and key length */
+				pAd->SharedKey[BSS0][KeyIdx].KeyLen =
+				    (u8)pKey->KeyLength;
+				NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key,
+					       &pKey->KeyMaterial,
+					       pKey->KeyLength);
 
-				// Set Ciper type
+				/* Set Ciper type */
 				if (pKey->KeyLength == 5)
-					pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP64;
+					pAd->SharedKey[BSS0][KeyIdx].CipherAlg =
+					    CIPHER_WEP64;
 				else
-					pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP128;
+					pAd->SharedKey[BSS0][KeyIdx].CipherAlg =
+					    CIPHER_WEP128;
 
-    			CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
-    			Key = pAd->SharedKey[BSS0][KeyIdx].Key;
+				CipherAlg =
+				    pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
+				Key = pAd->SharedKey[BSS0][KeyIdx].Key;
 
-				// Set Group key material to Asic
-    			AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
+				/* Set Group key material to Asic */
+				AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx,
+						      CipherAlg, Key, NULL,
+						      NULL);
 
-				// Update WCID attribute table and IVEIV table for this group key table
-				RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx, CipherAlg, NULL);
+				/* Update WCID attribute table and IVEIV table for this group key table */
+				RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx,
+							  CipherAlg, NULL);
 
 			}
 		}
 	}
 end:
-#ifdef RT2860
-	RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-    DBGPRINT(RT_DEBUG_INFO, ("<------ RTMPAddKey\n"));
-#endif
 	return;
 }
 
-char * rtstrchr(const char * s, int c)
+char *rtstrchr(const char *s, int c)
 {
-    for(; *s != (char) c; ++s)
-        if (*s == '\0')
-            return NULL;
-    return (char *) s;
+	for (; *s != (char)c; ++s)
+		if (*s == '\0')
+			return NULL;
+	return (char *)s;
 }
 
 /*
@@ -475,159 +361,164 @@
 
 int
 rt_ioctl_giwname(struct net_device *dev,
-		   struct iw_request_info *info,
-		   char *name, char *extra)
+		 struct iw_request_info *info, char *name, char *extra)
 {
-//	PRTMP_ADAPTER pAdapter = dev->ml_priv;
-	strncpy(name, RT28xx_CHIP_NAME " Wireless", IFNAMSIZ);
+	strncpy(name, "Ralink STA", IFNAMSIZ);
+	/* RT2870 2.1.0.0 uses "RT2870 Wireless" */
+	/* RT3090 2.1.0.0 uses "RT2860 Wireless" */
 	return 0;
 }
 
 int rt_ioctl_siwfreq(struct net_device *dev,
-			struct iw_request_info *info,
-			struct iw_freq *freq, char *extra)
+		     struct iw_request_info *info,
+		     struct iw_freq *freq, char *extra)
 {
-	PRTMP_ADAPTER pAdapter = dev->ml_priv;
-	int 	chan = -1;
+	struct rt_rtmp_adapter *pAdapter = NULL;
+	int chan = -1;
 
-    //check if the interface is down
-    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-        return -ENETDOWN;
-    }
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
 
+	/*check if the interface is down */
+	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
+		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+		return -ENETDOWN;
+	}
 
 	if (freq->e > 1)
 		return -EINVAL;
 
-	if((freq->e == 0) && (freq->m <= 1000))
-		chan = freq->m;	// Setting by channel number
+	if ((freq->e == 0) && (freq->m <= 1000))
+		chan = freq->m;	/* Setting by channel number */
 	else
-		MAP_KHZ_TO_CHANNEL_ID( (freq->m /100) , chan); // Setting by frequency - search the table , like 2.412G, 2.422G,
+		MAP_KHZ_TO_CHANNEL_ID((freq->m / 100), chan);	/* Setting by frequency - search the table , like 2.412G, 2.422G, */
 
-    if (ChannelSanity(pAdapter, chan) == TRUE)
-    {
-	pAdapter->CommonCfg.Channel = chan;
-	DBGPRINT(RT_DEBUG_ERROR, ("==>rt_ioctl_siwfreq::SIOCSIWFREQ[cmd=0x%x] (Channel=%d)\n", SIOCSIWFREQ, pAdapter->CommonCfg.Channel));
-    }
-    else
-        return -EINVAL;
+	if (ChannelSanity(pAdapter, chan) == TRUE) {
+		pAdapter->CommonCfg.Channel = chan;
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("==>rt_ioctl_siwfreq::SIOCSIWFREQ[cmd=0x%x] (Channel=%d)\n",
+			  SIOCSIWFREQ, pAdapter->CommonCfg.Channel));
+	} else
+		return -EINVAL;
 
 	return 0;
 }
+
 int rt_ioctl_giwfreq(struct net_device *dev,
-		   struct iw_request_info *info,
-		   struct iw_freq *freq, char *extra)
+		     struct iw_request_info *info,
+		     struct iw_freq *freq, char *extra)
 {
-	PRTMP_ADAPTER pAdapter = dev->ml_priv;
-	UCHAR ch = pAdapter->CommonCfg.Channel;
-	ULONG	m;
+	struct rt_rtmp_adapter *pAdapter = NULL;
+	u8 ch;
+	unsigned long m = 2412000;
 
-	DBGPRINT(RT_DEBUG_TRACE,("==>rt_ioctl_giwfreq  %d\n", ch));
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
 
-    MAP_CHANNEL_ID_TO_KHZ(ch, m);
+	ch = pAdapter->CommonCfg.Channel;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("==>rt_ioctl_giwfreq  %d\n", ch));
+
+	MAP_CHANNEL_ID_TO_KHZ(ch, m);
 	freq->m = m * 100;
 	freq->e = 1;
 	return 0;
 }
 
 int rt_ioctl_siwmode(struct net_device *dev,
-		   struct iw_request_info *info,
-		   __u32 *mode, char *extra)
+		     struct iw_request_info *info, __u32 * mode, char *extra)
 {
-	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+	struct rt_rtmp_adapter *pAdapter = NULL;
 
-	//check if the interface is down
-    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-    {
-    	DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-       	return -ENETDOWN;
-    }
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
 
-	switch (*mode)
-	{
-		case IW_MODE_ADHOC:
-			Set_NetworkType_Proc(pAdapter, "Adhoc");
-			break;
-		case IW_MODE_INFRA:
-			Set_NetworkType_Proc(pAdapter, "Infra");
-			break;
-        case IW_MODE_MONITOR:
-			Set_NetworkType_Proc(pAdapter, "Monitor");
-			break;
-		default:
-			DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_siwmode::SIOCSIWMODE (unknown %d)\n", *mode));
-			return -EINVAL;
+	/*check if the interface is down */
+	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
+		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+		return -ENETDOWN;
 	}
 
-	// Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
+	switch (*mode) {
+	case IW_MODE_ADHOC:
+		Set_NetworkType_Proc(pAdapter, "Adhoc");
+		break;
+	case IW_MODE_INFRA:
+		Set_NetworkType_Proc(pAdapter, "Infra");
+		break;
+	case IW_MODE_MONITOR:
+		Set_NetworkType_Proc(pAdapter, "Monitor");
+		break;
+	default:
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("===>rt_ioctl_siwmode::SIOCSIWMODE (unknown %d)\n",
+			  *mode));
+		return -EINVAL;
+	}
+
+	/* Reset Ralink supplicant to not use, it will be set to start when UI set PMK key */
 	pAdapter->StaCfg.WpaState = SS_NOTUSE;
 
 	return 0;
 }
 
 int rt_ioctl_giwmode(struct net_device *dev,
-		   struct iw_request_info *info,
-		   __u32 *mode, char *extra)
+		     struct iw_request_info *info, __u32 * mode, char *extra)
 {
-	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+	struct rt_rtmp_adapter *pAdapter = NULL;
+
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
 
 	if (ADHOC_ON(pAdapter))
 		*mode = IW_MODE_ADHOC;
-    else if (INFRA_ON(pAdapter))
+	else if (INFRA_ON(pAdapter))
 		*mode = IW_MODE_INFRA;
-    else if (MONITOR_ON(pAdapter))
-    {
-        *mode = IW_MODE_MONITOR;
-    }
-    else
-        *mode = IW_MODE_AUTO;
+	else if (MONITOR_ON(pAdapter)) {
+		*mode = IW_MODE_MONITOR;
+	} else
+		*mode = IW_MODE_AUTO;
 
 	DBGPRINT(RT_DEBUG_TRACE, ("==>rt_ioctl_giwmode(mode=%d)\n", *mode));
 	return 0;
 }
 
 int rt_ioctl_siwsens(struct net_device *dev,
-		   struct iw_request_info *info,
-		   char *name, char *extra)
+		     struct iw_request_info *info, char *name, char *extra)
 {
-	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+	struct rt_rtmp_adapter *pAdapter = NULL;
 
-	//check if the interface is down
-    	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-    	{
-        	DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-        	return -ENETDOWN;
-    	}
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
+
+	/*check if the interface is down */
+	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
+		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+		return -ENETDOWN;
+	}
 
 	return 0;
 }
 
 int rt_ioctl_giwsens(struct net_device *dev,
-		   struct iw_request_info *info,
-		   char *name, char *extra)
+		     struct iw_request_info *info, char *name, char *extra)
 {
 	return 0;
 }
 
 int rt_ioctl_giwrange(struct net_device *dev,
-		   struct iw_request_info *info,
-		   struct iw_point *data, char *extra)
+		      struct iw_request_info *info,
+		      struct iw_point *data, char *extra)
 {
-	PRTMP_ADAPTER pAdapter = dev->ml_priv;
-	struct iw_range *range = (struct iw_range *) extra;
+	struct rt_rtmp_adapter *pAdapter = NULL;
+	struct iw_range *range = (struct iw_range *)extra;
 	u16 val;
 	int i;
 
-	DBGPRINT(RT_DEBUG_TRACE ,("===>rt_ioctl_giwrange\n"));
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_giwrange\n"));
 	data->length = sizeof(struct iw_range);
 	memset(range, 0, sizeof(struct iw_range));
 
 	range->txpower_capa = IW_TXPOW_DBM;
 
-	if (INFRA_ON(pAdapter)||ADHOC_ON(pAdapter))
-	{
+	if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter)) {
 		range->min_pmp = 1 * 1024;
 		range->max_pmp = 65535 * 1024;
 		range->min_pmt = 1 * 1024;
@@ -635,7 +526,7 @@
 		range->pmp_flags = IW_POWER_PERIOD;
 		range->pmt_flags = IW_POWER_TIMEOUT;
 		range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT |
-			IW_POWER_UNICAST_R | IW_POWER_ALL_R;
+		    IW_POWER_UNICAST_R | IW_POWER_ALL_R;
 	}
 
 	range->we_version_compiled = WIRELESS_EXT;
@@ -646,15 +537,14 @@
 	range->min_retry = 0;
 	range->max_retry = 255;
 
-	range->num_channels =  pAdapter->ChannelListNum;
+	range->num_channels = pAdapter->ChannelListNum;
 
 	val = 0;
-	for (i = 1; i <= range->num_channels; i++)
-	{
-		u32 m;
-		range->freq[val].i = pAdapter->ChannelList[i-1].Channel;
-		MAP_CHANNEL_ID_TO_KHZ(pAdapter->ChannelList[i-1].Channel, m);
-		range->freq[val].m = m * 100; /* HZ */
+	for (i = 1; i <= range->num_channels; i++) {
+		u32 m = 2412000;
+		range->freq[val].i = pAdapter->ChannelList[i - 1].Channel;
+		MAP_CHANNEL_ID_TO_KHZ(pAdapter->ChannelList[i - 1].Channel, m);
+		range->freq[val].m = m * 100;	/* OS_HZ */
 
 		range->freq[val].e = 1;
 		val++;
@@ -663,11 +553,11 @@
 	}
 	range->num_frequency = val;
 
-	range->max_qual.qual = 100; /* what is correct max? This was not
-					* documented exactly. At least
-					* 69 has been observed. */
-	range->max_qual.level = 0; /* dB */
-	range->max_qual.noise = 0; /* dB */
+	range->max_qual.qual = 100;	/* what is correct max? This was not
+					 * documented exactly. At least
+					 * 69 has been observed. */
+	range->max_qual.level = 0;	/* dB */
+	range->max_qual.noise = 0;	/* dB */
 
 	/* What would be suitable values for "average/typical" qual? */
 	range->avg_qual.qual = 20;
@@ -687,70 +577,68 @@
 
 	/* IW_ENC_CAPA_* bit field */
 	range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
-					IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+	    IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
 
 	return 0;
 }
 
 int rt_ioctl_siwap(struct net_device *dev,
-		      struct iw_request_info *info,
-		      struct sockaddr *ap_addr, char *extra)
+		   struct iw_request_info *info,
+		   struct sockaddr *ap_addr, char *extra)
 {
-	PRTMP_ADAPTER pAdapter = dev->ml_priv;
-    NDIS_802_11_MAC_ADDRESS Bssid;
+	struct rt_rtmp_adapter *pAdapter = NULL;
+	NDIS_802_11_MAC_ADDRESS Bssid;
 
-	//check if the interface is down
-	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
-       	DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-       	return -ENETDOWN;
-    }
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
 
-	if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
-    {
-        RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
-        DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
-    }
+	/*check if the interface is down */
+	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
+		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+		return -ENETDOWN;
+	}
 
-    // tell CNTL state machine to call NdisMSetInformationComplete() after completing
-    // this request, because this request is initiated by NDIS.
-    pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
-	// Prevent to connect AP again in STAMlmePeriodicExec
-	pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
+	if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE) {
+		RTMP_MLME_RESET_STATE_MACHINE(pAdapter);
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("MLME busy, reset MLME state machine!\n"));
+	}
+	/* tell CNTL state machine to call NdisMSetInformationComplete() after completing */
+	/* this request, because this request is initiated by NDIS. */
+	pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
+	/* Prevent to connect AP again in STAMlmePeriodicExec */
+	pAdapter->MlmeAux.AutoReconnectSsidLen = 32;
 
-    memset(Bssid, 0, MAC_ADDR_LEN);
-    memcpy(Bssid, ap_addr->sa_data, MAC_ADDR_LEN);
-    MlmeEnqueue(pAdapter,
-                MLME_CNTL_STATE_MACHINE,
-                OID_802_11_BSSID,
-                sizeof(NDIS_802_11_MAC_ADDRESS),
-                (VOID *)&Bssid);
+	memset(Bssid, 0, MAC_ADDR_LEN);
+	memcpy(Bssid, ap_addr->sa_data, MAC_ADDR_LEN);
+	MlmeEnqueue(pAdapter,
+		    MLME_CNTL_STATE_MACHINE,
+		    OID_802_11_BSSID,
+		    sizeof(NDIS_802_11_MAC_ADDRESS), (void *) & Bssid);
 
-    DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCSIWAP %02x:%02x:%02x:%02x:%02x:%02x\n",
-        Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("IOCTL::SIOCSIWAP %02x:%02x:%02x:%02x:%02x:%02x\n", Bssid[0],
+		  Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
 
 	return 0;
 }
 
 int rt_ioctl_giwap(struct net_device *dev,
-		      struct iw_request_info *info,
-		      struct sockaddr *ap_addr, char *extra)
+		   struct iw_request_info *info,
+		   struct sockaddr *ap_addr, char *extra)
 {
-	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+	struct rt_rtmp_adapter *pAdapter = NULL;
 
-	if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
-	{
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
+
+	if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter)) {
 		ap_addr->sa_family = ARPHRD_ETHER;
 		memcpy(ap_addr->sa_data, &pAdapter->CommonCfg.Bssid, ETH_ALEN);
 	}
-    // Add for RT2870
-    else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
-    {
-        ap_addr->sa_family = ARPHRD_ETHER;
-        memcpy(ap_addr->sa_data, &pAdapter->MlmeAux.Bssid, ETH_ALEN);
-    }
-	else
-	{
+	/* Add for RT2870 */
+	else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) {
+		ap_addr->sa_family = ARPHRD_ETHER;
+		memcpy(ap_addr->sa_data, &pAdapter->MlmeAux.Bssid, ETH_ALEN);
+	} else {
 		DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIWAP(=EMPTY)\n"));
 		return -ENOTCONN;
 	}
@@ -774,316 +662,317 @@
  * NB: various calculations are based on the orinoco/wavelan
  *     drivers for compatibility
  */
-static void set_quality(PRTMP_ADAPTER pAdapter,
-                        struct iw_quality *iq,
-                        signed char rssi)
+static void set_quality(struct rt_rtmp_adapter *pAdapter,
+			struct iw_quality *iq, signed char rssi)
 {
 	__u8 ChannelQuality;
 
-	// Normalize Rssi
+	/* Normalize Rssi */
 	if (rssi >= -50)
 		ChannelQuality = 100;
-	else if (rssi >= -80) // between -50 ~ -80dbm
-		ChannelQuality = (__u8)(24 + ((rssi + 80) * 26)/10);
-	else if (rssi >= -90)   // between -80 ~ -90dbm
-        ChannelQuality = (__u8)((rssi + 90) * 26)/10;
+	else if (rssi >= -80)	/* between -50 ~ -80dbm */
+		ChannelQuality = (__u8) (24 + ((rssi + 80) * 26) / 10);
+	else if (rssi >= -90)	/* between -80 ~ -90dbm */
+		ChannelQuality = (__u8) ((rssi + 90) * 26) / 10;
 	else
 		ChannelQuality = 0;
 
-    iq->qual = (__u8)ChannelQuality;
+	iq->qual = (__u8) ChannelQuality;
 
-    iq->level = (__u8)(rssi);
-    iq->noise = (pAdapter->BbpWriteLatch[66] > pAdapter->BbpTuning.FalseCcaUpperThreshold) ? ((__u8)pAdapter->BbpTuning.FalseCcaUpperThreshold) : ((__u8) pAdapter->BbpWriteLatch[66]); 	// noise level (dBm)
-    iq->noise += 256 - 143;
-    iq->updated = pAdapter->iw_stats.qual.updated;
+	iq->level = (__u8) (rssi);
+	iq->noise = (pAdapter->BbpWriteLatch[66] > pAdapter->BbpTuning.FalseCcaUpperThreshold) ? ((__u8) pAdapter->BbpTuning.FalseCcaUpperThreshold) : ((__u8) pAdapter->BbpWriteLatch[66]);	/* noise level (dBm) */
+	iq->noise += 256 - 143;
+	iq->updated = pAdapter->iw_stats.qual.updated;
 }
 
 int rt_ioctl_iwaplist(struct net_device *dev,
-			struct iw_request_info *info,
-			struct iw_point *data, char *extra)
+		      struct iw_request_info *info,
+		      struct iw_point *data, char *extra)
 {
- 	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+	struct rt_rtmp_adapter *pAdapter = NULL;
 
 	struct sockaddr addr[IW_MAX_AP];
 	struct iw_quality qual[IW_MAX_AP];
 	int i;
 
-   	//check if the interface is down
-    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-    {
-       	DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
+
+	/*check if the interface is down */
+	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
+		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
 		data->length = 0;
 		return 0;
-        //return -ENETDOWN;
+		/*return -ENETDOWN; */
 	}
 
-	for (i = 0; i <IW_MAX_AP ; i++)
-	{
-		if (i >=  pAdapter->ScanTab.BssNr)
+	for (i = 0; i < IW_MAX_AP; i++) {
+		if (i >= pAdapter->ScanTab.BssNr)
 			break;
 		addr[i].sa_family = ARPHRD_ETHER;
-			memcpy(addr[i].sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
-		set_quality(pAdapter, &qual[i], pAdapter->ScanTab.BssEntry[i].Rssi);
+		memcpy(addr[i].sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid,
+		       MAC_ADDR_LEN);
+		set_quality(pAdapter, &qual[i],
+			    pAdapter->ScanTab.BssEntry[i].Rssi);
 	}
 	data->length = i;
-	memcpy(extra, &addr, i*sizeof(addr[0]));
-	data->flags = 1;		/* signal quality present (sort of) */
-	memcpy(extra + i*sizeof(addr[0]), &qual, i*sizeof(qual[i]));
+	memcpy(extra, &addr, i * sizeof(addr[0]));
+	data->flags = 1;	/* signal quality present (sort of) */
+	memcpy(extra + i * sizeof(addr[0]), &qual, i * sizeof(qual[i]));
 
 	return 0;
 }
 
 int rt_ioctl_siwscan(struct net_device *dev,
-			struct iw_request_info *info,
-			struct iw_point *data, char *extra)
+		     struct iw_request_info *info,
+		     struct iw_point *data, char *extra)
 {
-	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+	struct rt_rtmp_adapter *pAdapter = NULL;
 
-	ULONG								Now;
+	unsigned long Now;
 	int Status = NDIS_STATUS_SUCCESS;
 
-	//check if the interface is down
-	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
+
+	/*check if the interface is down */
+	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
 		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
 		return -ENETDOWN;
 	}
 
-	if (MONITOR_ON(pAdapter))
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
-        return -EINVAL;
-    }
-#ifdef RT2860
-	if ((pAdapter->OpMode == OPMODE_STA) && (IDLE_ON(pAdapter))
-		&& (pAdapter->StaCfg.bRadio == TRUE)
-		&& (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
-	{
-		RT28xxPciAsicRadioOn(pAdapter, GUI_IDLE_POWER_SAVE);
+	if (MONITOR_ON(pAdapter)) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Driver is in Monitor Mode now!\n"));
+		return -EINVAL;
 	}
-	// Check if still radio off.
-	else if (pAdapter->bPCIclkOff == TRUE)
-		return 0;
-#endif
-	if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
-	{
+
+	if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) {
 		pAdapter->StaCfg.WpaSupplicantScanCount++;
 	}
 
-    pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
+	pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
 	if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-		return 0;
-	do{
+		return NDIS_STATUS_SUCCESS;
+	do {
 		Now = jiffies;
 
-		if ((pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) &&
-			(pAdapter->StaCfg.WpaSupplicantScanCount > 3))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("!!! WpaSupplicantScanCount > 3\n"));
+		if ((pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
+		    && (pAdapter->StaCfg.WpaSupplicantScanCount > 3)) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("WpaSupplicantScanCount > 3\n"));
 			Status = NDIS_STATUS_SUCCESS;
 			break;
 		}
 
-		if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
-			((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
-			(pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) &&
-			(pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
+		if ((OPSTATUS_TEST_FLAG
+		     (pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED))
+		    && ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA)
+			|| (pAdapter->StaCfg.AuthMode ==
+			    Ndis802_11AuthModeWPAPSK))
+		    && (pAdapter->StaCfg.PortSecured ==
+			WPA_802_1X_PORT_NOT_SECURED)) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
 			Status = NDIS_STATUS_SUCCESS;
 			break;
 		}
 
-		if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
-		{
-			RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
-			DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
+		if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE) {
+			RTMP_MLME_RESET_STATE_MACHINE(pAdapter);
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("MLME busy, reset MLME state machine!\n"));
 		}
-
-		// tell CNTL state machine to call NdisMSetInformationComplete() after completing
-		// this request, because this request is initiated by NDIS.
+		/* tell CNTL state machine to call NdisMSetInformationComplete() after completing */
+		/* this request, because this request is initiated by NDIS. */
 		pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
-		// Reset allowed scan retries
+		/* Reset allowed scan retries */
 		pAdapter->StaCfg.ScanCnt = 0;
 		pAdapter->StaCfg.LastScanTime = Now;
 
 		MlmeEnqueue(pAdapter,
-			MLME_CNTL_STATE_MACHINE,
-			OID_802_11_BSSID_LIST_SCAN,
-			0,
-			NULL);
+			    MLME_CNTL_STATE_MACHINE,
+			    OID_802_11_BSSID_LIST_SCAN, 0, NULL);
 
 		Status = NDIS_STATUS_SUCCESS;
-		RT28XX_MLME_HANDLER(pAdapter);
-	}while(0);
-	return 0;
+		RTMP_MLME_HANDLER(pAdapter);
+	} while (0);
+	return NDIS_STATUS_SUCCESS;
 }
 
 int rt_ioctl_giwscan(struct net_device *dev,
-			struct iw_request_info *info,
-			struct iw_point *data, char *extra)
+		     struct iw_request_info *info,
+		     struct iw_point *data, char *extra)
 {
-
-	PRTMP_ADAPTER pAdapter = dev->ml_priv;
-	int i=0;
+	struct rt_rtmp_adapter *pAdapter = NULL;
+	int i = 0;
 	char *current_ev = extra, *previous_ev = extra;
 	char *end_buf;
-	char *current_val, custom[MAX_CUSTOM_LEN] = {0};
+	char *current_val;
+	char custom[MAX_CUSTOM_LEN] = { 0 };
 	struct iw_event iwe;
 
-	if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-    {
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
+
+	if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) {
 		/*
 		 * Still scanning, indicate the caller should try again.
 		 */
 		return -EAGAIN;
 	}
 
-	if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
-	{
+	if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) {
 		pAdapter->StaCfg.WpaSupplicantScanCount = 0;
 	}
 
-	if (pAdapter->ScanTab.BssNr == 0)
-	{
+	if (pAdapter->ScanTab.BssNr == 0) {
 		data->length = 0;
 		return 0;
 	}
 
-    if (data->length > 0)
-        end_buf = extra + data->length;
-    else
-        end_buf = extra + IW_SCAN_MAX_DATA;
+	if (data->length > 0)
+		end_buf = extra + data->length;
+	else
+		end_buf = extra + IW_SCAN_MAX_DATA;
 
-	for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
-	{
-		if (current_ev >= end_buf)
+	for (i = 0; i < pAdapter->ScanTab.BssNr; i++) {
+		if (current_ev >= end_buf) {
 			return -E2BIG;
-
-		//MAC address
-		//================================
+		}
+		/*MAC address */
+		/*================================ */
 		memset(&iwe, 0, sizeof(iwe));
 		iwe.cmd = SIOCGIWAP;
 		iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
-		memcpy(iwe.u.ap_addr.sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, ETH_ALEN);
+		memcpy(iwe.u.ap_addr.sa_data,
+		       &pAdapter->ScanTab.BssEntry[i].Bssid, ETH_ALEN);
 
-        previous_ev = current_ev;
-		current_ev = iwe_stream_add_event(info, current_ev,end_buf, &iwe, IW_EV_ADDR_LEN);
-        if (current_ev == previous_ev)
-		return -E2BIG;
+		previous_ev = current_ev;
+		current_ev =
+		    iwe_stream_add_event(info, current_ev, end_buf, &iwe,
+					 IW_EV_ADDR_LEN);
+		if (current_ev == previous_ev)
+			return -E2BIG;
 
 		/*
-		Protocol:
-			it will show scanned AP's WirelessMode .
-			it might be
-					802.11a
-					802.11a/n
-					802.11g/n
-					802.11b/g/n
-					802.11g
-					802.11b/g
-		*/
+		   Protocol:
+		   it will show scanned AP's WirelessMode .
+		   it might be
+		   802.11a
+		   802.11a/n
+		   802.11g/n
+		   802.11b/g/n
+		   802.11g
+		   802.11b/g
+		 */
 		memset(&iwe, 0, sizeof(iwe));
 		iwe.cmd = SIOCGIWNAME;
 
-
-	{
-		PBSS_ENTRY pBssEntry=&pAdapter->ScanTab.BssEntry[i];
-		BOOLEAN isGonly=FALSE;
-		int rateCnt=0;
-
-		if (pBssEntry->Channel>14)
 		{
-			if (pBssEntry->HtCapabilityLen!=0)
-				strcpy(iwe.u.name,"802.11a/n");
-			else
-				strcpy(iwe.u.name,"802.11a");
-		}
-		else
-		{
-			/*
-				if one of non B mode rate is set supported rate . it mean G only.
-			*/
-			for (rateCnt=0;rateCnt<pBssEntry->SupRateLen;rateCnt++)
-			{
+			struct rt_bss_entry *pBssEntry = &pAdapter->ScanTab.BssEntry[i];
+			BOOLEAN isGonly = FALSE;
+			int rateCnt = 0;
+
+			if (pBssEntry->Channel > 14) {
+				if (pBssEntry->HtCapabilityLen != 0)
+					strcpy(iwe.u.name, "802.11a/n");
+				else
+					strcpy(iwe.u.name, "802.11a");
+			} else {
 				/*
-					6Mbps(140) 9Mbps(146) and >=12Mbps(152) are supported rate , it mean G only.
-				*/
-				if (pBssEntry->SupRate[rateCnt]==140 || pBssEntry->SupRate[rateCnt]==146 || pBssEntry->SupRate[rateCnt]>=152)
-					isGonly=TRUE;
-			}
+				   if one of non B mode rate is set supported rate . it mean G only.
+				 */
+				for (rateCnt = 0;
+				     rateCnt < pBssEntry->SupRateLen;
+				     rateCnt++) {
+					/*
+					   6Mbps(140) 9Mbps(146) and >=12Mbps(152) are supported rate , it mean G only.
+					 */
+					if (pBssEntry->SupRate[rateCnt] == 140
+					    || pBssEntry->SupRate[rateCnt] ==
+					    146
+					    || pBssEntry->SupRate[rateCnt] >=
+					    152)
+						isGonly = TRUE;
+				}
 
-			for (rateCnt=0;rateCnt<pBssEntry->ExtRateLen;rateCnt++)
-			{
-				if (pBssEntry->ExtRate[rateCnt]==140 || pBssEntry->ExtRate[rateCnt]==146 || pBssEntry->ExtRate[rateCnt]>=152)
-					isGonly=TRUE;
-			}
+				for (rateCnt = 0;
+				     rateCnt < pBssEntry->ExtRateLen;
+				     rateCnt++) {
+					if (pBssEntry->ExtRate[rateCnt] == 140
+					    || pBssEntry->ExtRate[rateCnt] ==
+					    146
+					    || pBssEntry->ExtRate[rateCnt] >=
+					    152)
+						isGonly = TRUE;
+				}
 
-
-			if (pBssEntry->HtCapabilityLen!=0)
-			{
-				if (isGonly==TRUE)
-					strcpy(iwe.u.name,"802.11g/n");
-				else
-					strcpy(iwe.u.name,"802.11b/g/n");
-			}
-			else
-			{
-				if (isGonly==TRUE)
-					strcpy(iwe.u.name,"802.11g");
-				else
-				{
-					if (pBssEntry->SupRateLen==4 && pBssEntry->ExtRateLen==0)
-						strcpy(iwe.u.name,"802.11b");
+				if (pBssEntry->HtCapabilityLen != 0) {
+					if (isGonly == TRUE)
+						strcpy(iwe.u.name, "802.11g/n");
 					else
-						strcpy(iwe.u.name,"802.11b/g");
+						strcpy(iwe.u.name,
+						       "802.11b/g/n");
+				} else {
+					if (isGonly == TRUE)
+						strcpy(iwe.u.name, "802.11g");
+					else {
+						if (pBssEntry->SupRateLen == 4
+						    && pBssEntry->ExtRateLen ==
+						    0)
+							strcpy(iwe.u.name,
+							       "802.11b");
+						else
+							strcpy(iwe.u.name,
+							       "802.11b/g");
+					}
 				}
 			}
 		}
-	}
 
 		previous_ev = current_ev;
-		current_ev	 = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
-        if (current_ev == previous_ev)
-		return -E2BIG;
+		current_ev =
+		    iwe_stream_add_event(info, current_ev, end_buf, &iwe,
+					 IW_EV_ADDR_LEN);
+		if (current_ev == previous_ev)
+			return -E2BIG;
 
-		//ESSID
-		//================================
+		/*ESSID */
+		/*================================ */
 		memset(&iwe, 0, sizeof(iwe));
 		iwe.cmd = SIOCGIWESSID;
 		iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].SsidLen;
 		iwe.u.data.flags = 1;
 
-        previous_ev = current_ev;
-		current_ev = iwe_stream_add_point(info, current_ev,end_buf, &iwe, pAdapter->ScanTab.BssEntry[i].Ssid);
-        if (current_ev == previous_ev)
-		return -E2BIG;
+		previous_ev = current_ev;
+		current_ev =
+		    iwe_stream_add_point(info, current_ev, end_buf, &iwe,
+					 (char *)pAdapter->ScanTab.
+					 BssEntry[i].Ssid);
+		if (current_ev == previous_ev)
+			return -E2BIG;
 
-		//Network Type
-		//================================
+		/*Network Type */
+		/*================================ */
 		memset(&iwe, 0, sizeof(iwe));
 		iwe.cmd = SIOCGIWMODE;
-		if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11IBSS)
-		{
+		if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11IBSS) {
 			iwe.u.mode = IW_MODE_ADHOC;
-		}
-		else if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11Infrastructure)
-		{
+		} else if (pAdapter->ScanTab.BssEntry[i].BssType ==
+			   Ndis802_11Infrastructure) {
 			iwe.u.mode = IW_MODE_INFRA;
-		}
-		else
-		{
+		} else {
 			iwe.u.mode = IW_MODE_AUTO;
 		}
 		iwe.len = IW_EV_UINT_LEN;
 
-        previous_ev = current_ev;
-		current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,  IW_EV_UINT_LEN);
-        if (current_ev == previous_ev)
-		return -E2BIG;
+		previous_ev = current_ev;
+		current_ev =
+		    iwe_stream_add_event(info, current_ev, end_buf, &iwe,
+					 IW_EV_UINT_LEN);
+		if (current_ev == previous_ev)
+			return -E2BIG;
 
-		//Channel and Frequency
-		//================================
+		/*Channel and Frequency */
+		/*================================ */
 		memset(&iwe, 0, sizeof(iwe));
 		iwe.cmd = SIOCGIWFREQ;
 		if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
@@ -1094,172 +983,217 @@
 		iwe.u.freq.i = 0;
 
 		previous_ev = current_ev;
-		current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
-        if (current_ev == previous_ev)
-		return -E2BIG;
+		current_ev =
+		    iwe_stream_add_event(info, current_ev, end_buf, &iwe,
+					 IW_EV_FREQ_LEN);
+		if (current_ev == previous_ev)
+			return -E2BIG;
 
-        //Add quality statistics
-        //================================
-        memset(&iwe, 0, sizeof(iwe));
-    	iwe.cmd = IWEVQUAL;
-    	iwe.u.qual.level = 0;
-    	iwe.u.qual.noise = 0;
-        set_quality(pAdapter, &iwe.u.qual, pAdapter->ScanTab.BssEntry[i].Rssi);
-    	current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
-        if (current_ev == previous_ev)
-		return -E2BIG;
+		/*Add quality statistics */
+		/*================================ */
+		memset(&iwe, 0, sizeof(iwe));
+		iwe.cmd = IWEVQUAL;
+		iwe.u.qual.level = 0;
+		iwe.u.qual.noise = 0;
+		set_quality(pAdapter, &iwe.u.qual,
+			    pAdapter->ScanTab.BssEntry[i].Rssi);
+		current_ev =
+		    iwe_stream_add_event(info, current_ev, end_buf, &iwe,
+					 IW_EV_QUAL_LEN);
+		if (current_ev == previous_ev)
+			return -E2BIG;
 
-		//Encyption key
-		//================================
+		/*Encyption key */
+		/*================================ */
 		memset(&iwe, 0, sizeof(iwe));
 		iwe.cmd = SIOCGIWENCODE;
-		if (CAP_IS_PRIVACY_ON (pAdapter->ScanTab.BssEntry[i].CapabilityInfo ))
-			iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+		if (CAP_IS_PRIVACY_ON
+		    (pAdapter->ScanTab.BssEntry[i].CapabilityInfo))
+			iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
 		else
 			iwe.u.data.flags = IW_ENCODE_DISABLED;
 
-        previous_ev = current_ev;
-        current_ev = iwe_stream_add_point(info, current_ev, end_buf,&iwe, (char *)pAdapter->SharedKey[BSS0][(iwe.u.data.flags & IW_ENCODE_INDEX)-1].Key);
-        if (current_ev == previous_ev)
-		return -E2BIG;
+		previous_ev = current_ev;
+		current_ev =
+		    iwe_stream_add_point(info, current_ev, end_buf, &iwe,
+					 (char *)pAdapter->
+					 SharedKey[BSS0][(iwe.u.data.
+							  flags &
+							  IW_ENCODE_INDEX) -
+							 1].Key);
+		if (current_ev == previous_ev)
+			return -E2BIG;
 
-		//Bit Rate
-		//================================
-		if (pAdapter->ScanTab.BssEntry[i].SupRateLen)
-        {
-            UCHAR tmpRate = pAdapter->ScanTab.BssEntry[i].SupRate[pAdapter->ScanTab.BssEntry[i].SupRateLen-1];
+		/*Bit Rate */
+		/*================================ */
+		if (pAdapter->ScanTab.BssEntry[i].SupRateLen) {
+			u8 tmpRate =
+			    pAdapter->ScanTab.BssEntry[i].SupRate[pAdapter->
+								  ScanTab.
+								  BssEntry[i].
+								  SupRateLen -
+								  1];
 			memset(&iwe, 0, sizeof(iwe));
 			iwe.cmd = SIOCGIWRATE;
-    		current_val = current_ev + IW_EV_LCP_LEN;
-            if (tmpRate == 0x82)
-                iwe.u.bitrate.value =  1 * 1000000;
-            else if (tmpRate == 0x84)
-                iwe.u.bitrate.value =  2 * 1000000;
-            else if (tmpRate == 0x8B)
-                iwe.u.bitrate.value =  5.5 * 1000000;
-            else if (tmpRate == 0x96)
-                iwe.u.bitrate.value =  11 * 1000000;
-            else
-    		    iwe.u.bitrate.value =  (tmpRate/2) * 1000000;
+			current_val = current_ev + IW_EV_LCP_LEN;
+			if (tmpRate == 0x82)
+				iwe.u.bitrate.value = 1 * 1000000;
+			else if (tmpRate == 0x84)
+				iwe.u.bitrate.value = 2 * 1000000;
+			else if (tmpRate == 0x8B)
+				iwe.u.bitrate.value = 5.5 * 1000000;
+			else if (tmpRate == 0x96)
+				iwe.u.bitrate.value = 11 * 1000000;
+			else
+				iwe.u.bitrate.value = (tmpRate / 2) * 1000000;
+
+			if (tmpRate == 0x6c
+			    && pAdapter->ScanTab.BssEntry[i].HtCapabilityLen >
+			    0) {
+				int rate_count =
+				    sizeof(ralinkrate) / sizeof(__s32);
+				struct rt_ht_cap_info capInfo =
+				    pAdapter->ScanTab.BssEntry[i].HtCapability.
+				    HtCapInfo;
+				int shortGI =
+				    capInfo.ChannelWidth ? capInfo.
+				    ShortGIfor40 : capInfo.ShortGIfor20;
+				int maxMCS =
+				    pAdapter->ScanTab.BssEntry[i].HtCapability.
+				    MCSSet[1] ? 15 : 7;
+				int rate_index =
+				    12 + ((u8)capInfo.ChannelWidth * 24) +
+				    ((u8)shortGI * 48) + ((u8)maxMCS);
+				if (rate_index < 0)
+					rate_index = 0;
+				if (rate_index > rate_count)
+					rate_index = rate_count;
+				iwe.u.bitrate.value =
+				    ralinkrate[rate_index] * 500000;
+			}
 
 			iwe.u.bitrate.disabled = 0;
 			current_val = iwe_stream_add_value(info, current_ev,
-				current_val, end_buf, &iwe,
-    			IW_EV_PARAM_LEN);
+							   current_val, end_buf,
+							   &iwe,
+							   IW_EV_PARAM_LEN);
 
-        	if((current_val-current_ev)>IW_EV_LCP_LEN)
-            	current_ev = current_val;
-        	else
-			return -E2BIG;
-        }
-
-		//WPA IE
-		if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
-		{
+			if ((current_val - current_ev) > IW_EV_LCP_LEN)
+				current_ev = current_val;
+			else
+				return -E2BIG;
+		}
+		/*WPA IE */
+		if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0) {
 			memset(&iwe, 0, sizeof(iwe));
 			memset(&custom[0], 0, MAX_CUSTOM_LEN);
-			memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].WpaIE.IE[0]),
-						   pAdapter->ScanTab.BssEntry[i].WpaIE.IELen);
+			memcpy(custom,
+			       &(pAdapter->ScanTab.BssEntry[i].WpaIE.IE[0]),
+			       pAdapter->ScanTab.BssEntry[i].WpaIE.IELen);
 			iwe.cmd = IWEVGENIE;
-			iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].WpaIE.IELen;
-			current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, custom);
+			iwe.u.data.length =
+			    pAdapter->ScanTab.BssEntry[i].WpaIE.IELen;
+			current_ev =
+			    iwe_stream_add_point(info, current_ev, end_buf,
+						 &iwe, custom);
 			if (current_ev == previous_ev)
 				return -E2BIG;
 		}
-
-		//WPA2 IE
-        if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
-        {
-        	memset(&iwe, 0, sizeof(iwe));
+		/*WPA2 IE */
+		if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0) {
+			memset(&iwe, 0, sizeof(iwe));
 			memset(&custom[0], 0, MAX_CUSTOM_LEN);
-			memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].RsnIE.IE[0]),
-						   pAdapter->ScanTab.BssEntry[i].RsnIE.IELen);
+			memcpy(custom,
+			       &(pAdapter->ScanTab.BssEntry[i].RsnIE.IE[0]),
+			       pAdapter->ScanTab.BssEntry[i].RsnIE.IELen);
 			iwe.cmd = IWEVGENIE;
-			iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].RsnIE.IELen;
-			current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, custom);
+			iwe.u.data.length =
+			    pAdapter->ScanTab.BssEntry[i].RsnIE.IELen;
+			current_ev =
+			    iwe_stream_add_point(info, current_ev, end_buf,
+						 &iwe, custom);
 			if (current_ev == previous_ev)
 				return -E2BIG;
-        }
+		}
 	}
 
 	data->length = current_ev - extra;
-    pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
-	DBGPRINT(RT_DEBUG_ERROR ,("===>rt_ioctl_giwscan. %d(%d) BSS returned, data->length = %d\n",i , pAdapter->ScanTab.BssNr, data->length));
+	pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
+	DBGPRINT(RT_DEBUG_ERROR,
+		 ("===>rt_ioctl_giwscan. %d(%d) BSS returned, data->length = %d\n",
+		  i, pAdapter->ScanTab.BssNr, data->length));
 	return 0;
 }
 
 int rt_ioctl_siwessid(struct net_device *dev,
-			 struct iw_request_info *info,
-			 struct iw_point *data, char *essid)
+		      struct iw_request_info *info,
+		      struct iw_point *data, char *essid)
 {
-	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+	struct rt_rtmp_adapter *pAdapter = NULL;
 
-	//check if the interface is down
-    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-    {
-       	DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-       	return -ENETDOWN;
-    }
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
 
-	if (data->flags)
-	{
-		PCHAR	pSsidString = NULL;
+	/*check if the interface is down */
+	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
+		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+		return -ENETDOWN;
+	}
 
-		// Includes null character.
+	if (data->flags) {
+		char *pSsidString = NULL;
+
+		/* Includes null character. */
 		if (data->length > (IW_ESSID_MAX_SIZE + 1))
 			return -E2BIG;
 
-		pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
-		if (pSsidString)
-		{
-			NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
+		pSsidString = kmalloc(MAX_LEN_OF_SSID + 1, MEM_ALLOC_FLAG);
+		if (pSsidString) {
+			NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID + 1);
 			NdisMoveMemory(pSsidString, essid, data->length);
 			if (Set_SSID_Proc(pAdapter, pSsidString) == FALSE)
 				return -EINVAL;
-		}
-		else
+		} else
 			return -ENOMEM;
-	}
-	else
-	{
-		// ANY ssid
+	} else {
+		/* ANY ssid */
 		if (Set_SSID_Proc(pAdapter, "") == FALSE)
 			return -EINVAL;
-    }
+	}
 	return 0;
 }
 
 int rt_ioctl_giwessid(struct net_device *dev,
-			 struct iw_request_info *info,
-			 struct iw_point *data, char *essid)
+		      struct iw_request_info *info,
+		      struct iw_point *data, char *essid)
 {
-	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+	struct rt_rtmp_adapter *pAdapter = NULL;
+
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
 
 	data->flags = 1;
-    if (MONITOR_ON(pAdapter))
-    {
-        data->length  = 0;
-        return 0;
-    }
+	if (MONITOR_ON(pAdapter)) {
+		data->length = 0;
+		return 0;
+	}
 
-	if (OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED))
-	{
-		DBGPRINT(RT_DEBUG_TRACE ,("MediaState is connected\n"));
+	if (OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
+		DBGPRINT(RT_DEBUG_TRACE, ("MediaState is connected\n"));
 		data->length = pAdapter->CommonCfg.SsidLen;
-		memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
+		memcpy(essid, pAdapter->CommonCfg.Ssid,
+		       pAdapter->CommonCfg.SsidLen);
 	}
-#ifdef RT2870
-    // Add for RT2870
-    else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
-    {
-        data->length = pAdapter->CommonCfg.SsidLen;
-		memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
+#ifdef RTMP_MAC_USB
+	/* Add for RT2870 */
+	else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) {
+		data->length = pAdapter->CommonCfg.SsidLen;
+		memcpy(essid, pAdapter->CommonCfg.Ssid,
+		       pAdapter->CommonCfg.SsidLen);
 	}
-#endif // RT2870 //
-	else
-	{//the ANY ssid was specified
-		data->length  = 0;
-		DBGPRINT(RT_DEBUG_TRACE ,("MediaState is not connected, ess\n"));
+#endif /* RTMP_MAC_USB // */
+	else {			/*the ANY ssid was specified */
+		data->length = 0;
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("MediaState is not connected, ess\n"));
 	}
 
 	return 0;
@@ -1267,17 +1201,18 @@
 }
 
 int rt_ioctl_siwnickn(struct net_device *dev,
-			 struct iw_request_info *info,
-			 struct iw_point *data, char *nickname)
+		      struct iw_request_info *info,
+		      struct iw_point *data, char *nickname)
 {
-	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+	struct rt_rtmp_adapter *pAdapter = NULL;
 
-    //check if the interface is down
-    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-    {
-        DBGPRINT(RT_DEBUG_TRACE ,("INFO::Network is down!\n"));
-        return -ENETDOWN;
-    }
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
+
+	/*check if the interface is down */
+	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
+		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+		return -ENETDOWN;
+	}
 
 	if (data->length > IW_ESSID_MAX_SIZE)
 		return -EINVAL;
@@ -1285,45 +1220,47 @@
 	memset(pAdapter->nickname, 0, IW_ESSID_MAX_SIZE + 1);
 	memcpy(pAdapter->nickname, nickname, data->length);
 
-
 	return 0;
 }
 
 int rt_ioctl_giwnickn(struct net_device *dev,
-			 struct iw_request_info *info,
-			 struct iw_point *data, char *nickname)
+		      struct iw_request_info *info,
+		      struct iw_point *data, char *nickname)
 {
-	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+	struct rt_rtmp_adapter *pAdapter = NULL;
 
-	if (data->length > strlen(pAdapter->nickname) + 1)
-		data->length = strlen(pAdapter->nickname) + 1;
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
+
+	if (data->length > strlen((char *)pAdapter->nickname) + 1)
+		data->length = strlen((char *)pAdapter->nickname) + 1;
 	if (data->length > 0) {
-		memcpy(nickname, pAdapter->nickname, data->length-1);
-		nickname[data->length-1] = '\0';
+		memcpy(nickname, pAdapter->nickname, data->length - 1);
+		nickname[data->length - 1] = '\0';
 	}
 	return 0;
 }
 
 int rt_ioctl_siwrts(struct net_device *dev,
-		       struct iw_request_info *info,
-		       struct iw_param *rts, char *extra)
+		    struct iw_request_info *info,
+		    struct iw_param *rts, char *extra)
 {
-	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+	struct rt_rtmp_adapter *pAdapter = NULL;
 	u16 val;
 
-    //check if the interface is down
-    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-        return -ENETDOWN;
-    }
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
+
+	/*check if the interface is down */
+	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
+		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+		return -ENETDOWN;
+	}
 
 	if (rts->disabled)
 		val = MAX_RTS_THRESHOLD;
 	else if (rts->value < 0 || rts->value > MAX_RTS_THRESHOLD)
 		return -EINVAL;
 	else if (rts->value == 0)
-	    val = MAX_RTS_THRESHOLD;
+		val = MAX_RTS_THRESHOLD;
 	else
 		val = rts->value;
 
@@ -1334,17 +1271,18 @@
 }
 
 int rt_ioctl_giwrts(struct net_device *dev,
-		       struct iw_request_info *info,
-		       struct iw_param *rts, char *extra)
+		    struct iw_request_info *info,
+		    struct iw_param *rts, char *extra)
 {
-	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+	struct rt_rtmp_adapter *pAdapter = NULL;
 
-	//check if the interface is down
-    	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-    	{
-      		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-        	return -ENETDOWN;
-    	}
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
+
+	/*check if the interface is down */
+	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
+		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+		return -ENETDOWN;
+	}
 
 	rts->value = pAdapter->CommonCfg.RtsThreshold;
 	rts->disabled = (rts->value == MAX_RTS_THRESHOLD);
@@ -1354,25 +1292,27 @@
 }
 
 int rt_ioctl_siwfrag(struct net_device *dev,
-			struct iw_request_info *info,
-			struct iw_param *frag, char *extra)
+		     struct iw_request_info *info,
+		     struct iw_param *frag, char *extra)
 {
-	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+	struct rt_rtmp_adapter *pAdapter = NULL;
 	u16 val;
 
-	//check if the interface is down
-    	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-    	{
-      		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-        	return -ENETDOWN;
-    	}
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
+
+	/*check if the interface is down */
+	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
+		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+		return -ENETDOWN;
+	}
 
 	if (frag->disabled)
 		val = MAX_FRAG_THRESHOLD;
-	else if (frag->value >= MIN_FRAG_THRESHOLD && frag->value <= MAX_FRAG_THRESHOLD)
-		val = __cpu_to_le16(frag->value & ~0x1); /* even numbers only */
+	else if (frag->value >= MIN_FRAG_THRESHOLD
+		 && frag->value <= MAX_FRAG_THRESHOLD)
+		val = __cpu_to_le16(frag->value & ~0x1);	/* even numbers only */
 	else if (frag->value == 0)
-	    val = MAX_FRAG_THRESHOLD;
+		val = MAX_FRAG_THRESHOLD;
 	else
 		return -EINVAL;
 
@@ -1381,17 +1321,18 @@
 }
 
 int rt_ioctl_giwfrag(struct net_device *dev,
-			struct iw_request_info *info,
-			struct iw_param *frag, char *extra)
+		     struct iw_request_info *info,
+		     struct iw_param *frag, char *extra)
 {
-	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+	struct rt_rtmp_adapter *pAdapter = NULL;
 
-	//check if the interface is down
-    	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-    	{
-      		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-        	return -ENETDOWN;
-    	}
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
+
+	/*check if the interface is down */
+	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
+		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+		return -ENETDOWN;
+	}
 
 	frag->value = pAdapter->CommonCfg.FragmentThreshold;
 	frag->disabled = (frag->value == MAX_FRAG_THRESHOLD);
@@ -1403,156 +1344,161 @@
 #define MAX_WEP_KEY_SIZE 13
 #define MIN_WEP_KEY_SIZE 5
 int rt_ioctl_siwencode(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_point *erq, char *extra)
+		       struct iw_request_info *info,
+		       struct iw_point *erq, char *extra)
 {
-	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+	struct rt_rtmp_adapter *pAdapter = NULL;
 
-	//check if the interface is down
-    	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-    	{
-      		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-        	return -ENETDOWN;
-    	}
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
 
-	if ((erq->length == 0) &&
-        (erq->flags & IW_ENCODE_DISABLED))
-	{
+	/*check if the interface is down */
+	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
+		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+		return -ENETDOWN;
+	}
+
+	if ((erq->length == 0) && (erq->flags & IW_ENCODE_DISABLED)) {
 		pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
 		pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
 		pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
-        pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
-        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
-        goto done;
-	} else if (
-		 (erq->flags & IW_ENCODE_RESTRICTED || erq->flags & IW_ENCODE_OPEN)) {
+		pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+		pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+		goto done;
+	} else if (erq->flags & IW_ENCODE_RESTRICTED
+		   || erq->flags & IW_ENCODE_OPEN) {
+		/*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
 		STA_PORT_SECURED(pAdapter);
 		pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
 		pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
 		pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
-        pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+		pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
 		if (erq->flags & IW_ENCODE_RESTRICTED)
 			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
-    	else
+		else
 			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
 	}
 
-    if (erq->length > 0)
-	{
+	if (erq->length > 0) {
 		int keyIdx = (erq->flags & IW_ENCODE_INDEX) - 1;
 		/* Check the size of the key */
 		if (erq->length > MAX_WEP_KEY_SIZE) {
 			return -EINVAL;
 		}
 		/* Check key index */
-		if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
-        {
-            DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::Wrong keyIdx=%d! Using default key instead (%d)\n",
-                                        keyIdx, pAdapter->StaCfg.DefaultKeyId));
+		if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS)) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("==>rt_ioctl_siwencode::Wrong keyIdx=%d! Using default key instead (%d)\n",
+				  keyIdx, pAdapter->StaCfg.DefaultKeyId));
 
-            //Using default key
+			/*Using default key */
 			keyIdx = pAdapter->StaCfg.DefaultKeyId;
-        }
-		else
-			pAdapter->StaCfg.DefaultKeyId=keyIdx;
+		} else
+			pAdapter->StaCfg.DefaultKeyId = keyIdx;
 
-        NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,  16);
+		NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, 16);
 
-		if (erq->length == MAX_WEP_KEY_SIZE)
-        {
-			pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
-            pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
-		}
-		else if (erq->length == MIN_WEP_KEY_SIZE)
-        {
-            pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
-            pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
-		}
-		else
+		if (erq->length == MAX_WEP_KEY_SIZE) {
+			pAdapter->SharedKey[BSS0][keyIdx].KeyLen =
+			    MAX_WEP_KEY_SIZE;
+			pAdapter->SharedKey[BSS0][keyIdx].CipherAlg =
+			    CIPHER_WEP128;
+		} else if (erq->length == MIN_WEP_KEY_SIZE) {
+			pAdapter->SharedKey[BSS0][keyIdx].KeyLen =
+			    MIN_WEP_KEY_SIZE;
+			pAdapter->SharedKey[BSS0][keyIdx].CipherAlg =
+			    CIPHER_WEP64;
+		} else
 			/* Disable the key */
 			pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
 
 		/* Check if the key is not marked as invalid */
-		if(!(erq->flags & IW_ENCODE_NOKEY)) {
+		if (!(erq->flags & IW_ENCODE_NOKEY)) {
 			/* Copy the key in the driver */
-			NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, extra, erq->length);
-        }
-	}
-    else
-			{
+			NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,
+				       extra, erq->length);
+		}
+	} else {
 		/* Do we want to just set the transmit key index ? */
 		int index = (erq->flags & IW_ENCODE_INDEX) - 1;
-		if ((index >= 0) && (index < 4))
-        {
+		if ((index >= 0) && (index < 4)) {
 			pAdapter->StaCfg.DefaultKeyId = index;
-            }
-        else
+		} else
 			/* Don't complain if only change the mode */
-			if (!(erq->flags & IW_ENCODE_MODE)) {
-				return -EINVAL;
-		}
+		if (!(erq->flags & IW_ENCODE_MODE))
+			return -EINVAL;
 	}
 
 done:
-    DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::erq->flags=%x\n",erq->flags));
-	DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::AuthMode=%x\n",pAdapter->StaCfg.AuthMode));
-	DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::DefaultKeyId=%x, KeyLen = %d\n",pAdapter->StaCfg.DefaultKeyId , pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen));
-	DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::WepStatus=%x\n",pAdapter->StaCfg.WepStatus));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("==>rt_ioctl_siwencode::erq->flags=%x\n", erq->flags));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("==>rt_ioctl_siwencode::AuthMode=%x\n",
+		  pAdapter->StaCfg.AuthMode));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("==>rt_ioctl_siwencode::DefaultKeyId=%x, KeyLen = %d\n",
+		  pAdapter->StaCfg.DefaultKeyId,
+		  pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].
+		  KeyLen));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("==>rt_ioctl_siwencode::WepStatus=%x\n",
+		  pAdapter->StaCfg.WepStatus));
 	return 0;
 }
 
 int
 rt_ioctl_giwencode(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_point *erq, char *key)
+		   struct iw_request_info *info,
+		   struct iw_point *erq, char *key)
 {
-	PRTMP_ADAPTER pAdapter = dev->ml_priv;
 	int kid;
+	struct rt_rtmp_adapter *pAdapter = NULL;
 
-	//check if the interface is down
-	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
-  		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-    	return -ENETDOWN;
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
+
+	/*check if the interface is down */
+	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
+		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+		return -ENETDOWN;
 	}
 
 	kid = erq->flags & IW_ENCODE_INDEX;
-	DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_giwencode %d\n", erq->flags & IW_ENCODE_INDEX));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("===>rt_ioctl_giwencode %d\n", erq->flags & IW_ENCODE_INDEX));
 
-	if (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled)
-	{
+	if (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled) {
 		erq->length = 0;
 		erq->flags = IW_ENCODE_DISABLED;
-	}
-	else if ((kid > 0) && (kid <=4))
-	{
-		// copy wep key
-		erq->flags = kid ;			/* NB: base 1 */
-		if (erq->length > pAdapter->SharedKey[BSS0][kid-1].KeyLen)
-			erq->length = pAdapter->SharedKey[BSS0][kid-1].KeyLen;
-		memcpy(key, pAdapter->SharedKey[BSS0][kid-1].Key, erq->length);
-		//if ((kid == pAdapter->PortCfg.DefaultKeyId))
-		//erq->flags |= IW_ENCODE_ENABLED;	/* XXX */
+	} else if ((kid > 0) && (kid <= 4)) {
+		/* copy wep key */
+		erq->flags = kid;	/* NB: base 1 */
+		if (erq->length > pAdapter->SharedKey[BSS0][kid - 1].KeyLen)
+			erq->length = pAdapter->SharedKey[BSS0][kid - 1].KeyLen;
+		memcpy(key, pAdapter->SharedKey[BSS0][kid - 1].Key,
+		       erq->length);
+		/*if ((kid == pAdapter->PortCfg.DefaultKeyId)) */
+		/*erq->flags |= IW_ENCODE_ENABLED; */	/* XXX */
 		if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
-			erq->flags |= IW_ENCODE_RESTRICTED;		/* XXX */
+			erq->flags |= IW_ENCODE_RESTRICTED;	/* XXX */
 		else
-			erq->flags |= IW_ENCODE_OPEN;		/* XXX */
+			erq->flags |= IW_ENCODE_OPEN;	/* XXX */
 
-	}
-	else if (kid == 0)
-	{
+	} else if (kid == 0) {
 		if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
-			erq->flags |= IW_ENCODE_RESTRICTED;		/* XXX */
+			erq->flags |= IW_ENCODE_RESTRICTED;	/* XXX */
 		else
-			erq->flags |= IW_ENCODE_OPEN;		/* XXX */
-		erq->length = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
-		memcpy(key, pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, erq->length);
-		// copy default key ID
+			erq->flags |= IW_ENCODE_OPEN;	/* XXX */
+		erq->length =
+		    pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].
+		    KeyLen;
+		memcpy(key,
+		       pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].
+		       Key, erq->length);
+		/* copy default key ID */
 		if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
-			erq->flags |= IW_ENCODE_RESTRICTED;		/* XXX */
+			erq->flags |= IW_ENCODE_RESTRICTED;	/* XXX */
 		else
-			erq->flags |= IW_ENCODE_OPEN;		/* XXX */
-		erq->flags = pAdapter->StaCfg.DefaultKeyId + 1;			/* NB: base 1 */
+			erq->flags |= IW_ENCODE_OPEN;	/* XXX */
+		erq->flags = pAdapter->StaCfg.DefaultKeyId + 1;	/* NB: base 1 */
 		erq->flags |= IW_ENCODE_ENABLED;	/* XXX */
 	}
 
@@ -1560,770 +1506,585 @@
 
 }
 
-static int
-rt_ioctl_setparam(struct net_device *dev, struct iw_request_info *info,
-			 void *w, char *extra)
+void getBaInfo(struct rt_rtmp_adapter *pAd, char *pOutBuf)
 {
-	PRTMP_ADAPTER pAdapter = dev->ml_priv;
-	POS_COOKIE pObj = (POS_COOKIE)pAdapter->OS_Cookie;
-	char *this_char = extra;
-	char *value;
-	int  Status=0;
+	int i, j;
+	struct rt_ba_ori_entry *pOriBAEntry;
+	struct rt_ba_rec_entry *pRecBAEntry;
 
-	{
-		pObj->ioctl_if_type = INT_MAIN;
-        pObj->ioctl_if = MAIN_MBSSID;
-	}
-
-	//check if the interface is down
-    	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-    	{
-      		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-			return -ENETDOWN;
-    	}
-
-	if (!*this_char)
-		return -EINVAL;
-
-	if ((value = rtstrchr(this_char, '=')) != NULL)
-	    *value++ = 0;
-
-	if (!value)
-	    return -EINVAL;
-
-	// reject setting nothing besides ANY ssid(ssidLen=0)
-    if (!*value && (strcmp(this_char, "SSID") != 0))
-        return -EINVAL;
-
-	for (PRTMP_PRIVATE_SET_PROC = RTMP_PRIVATE_SUPPORT_PROC; PRTMP_PRIVATE_SET_PROC->name; PRTMP_PRIVATE_SET_PROC++)
-	{
-	    if (strcmp(this_char, PRTMP_PRIVATE_SET_PROC->name) == 0)
-	    {
-	        if(!PRTMP_PRIVATE_SET_PROC->set_proc(pAdapter, value))
-	        {	//FALSE:Set private failed then return Invalid argument
-			    Status = -EINVAL;
-	        }
-		    break;	//Exit for loop.
-	    }
-	}
-
-	if(PRTMP_PRIVATE_SET_PROC->name == NULL)
-	{  //Not found argument
-	    Status = -EINVAL;
-	    DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_setparam:: (iwpriv) Not Support Set Command [%s=%s]\n", this_char, value));
-	}
-
-    return Status;
-}
-
-
-static int
-rt_private_get_statistics(struct net_device *dev, struct iw_request_info *info,
-		struct iw_point *wrq, char *extra)
-{
-	INT				Status = 0;
-    PRTMP_ADAPTER   pAd = dev->ml_priv;
-
-    if (extra == NULL)
-    {
-        wrq->length = 0;
-        return -EIO;
-    }
-
-    memset(extra, 0x00, IW_PRIV_SIZE_MASK);
-    sprintf(extra, "\n\n");
-
-	{
-    sprintf(extra+strlen(extra), "Tx success                      = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart);
-    sprintf(extra+strlen(extra), "Tx success without retry        = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart - (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
-	}
-    sprintf(extra+strlen(extra), "Tx success after retry          = %ld\n", (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
-    sprintf(extra+strlen(extra), "Tx fail to Rcv ACK after retry  = %ld\n", (ULONG)pAd->WlanCounters.FailedCount.QuadPart);
-    sprintf(extra+strlen(extra), "RTS Success Rcv CTS             = %ld\n", (ULONG)pAd->WlanCounters.RTSSuccessCount.QuadPart);
-    sprintf(extra+strlen(extra), "RTS Fail Rcv CTS                = %ld\n", (ULONG)pAd->WlanCounters.RTSFailureCount.QuadPart);
-
-    sprintf(extra+strlen(extra), "Rx success                      = %ld\n", (ULONG)pAd->WlanCounters.ReceivedFragmentCount.QuadPart);
-    sprintf(extra+strlen(extra), "Rx with CRC                     = %ld\n", (ULONG)pAd->WlanCounters.FCSErrorCount.QuadPart);
-    sprintf(extra+strlen(extra), "Rx drop due to out of resource  = %ld\n", (ULONG)pAd->Counters8023.RxNoBuffer);
-    sprintf(extra+strlen(extra), "Rx duplicate frame              = %ld\n", (ULONG)pAd->WlanCounters.FrameDuplicateCount.QuadPart);
-
-    sprintf(extra+strlen(extra), "False CCA (one second)          = %ld\n", (ULONG)pAd->RalinkCounters.OneSecFalseCCACnt);
-	{
-    	sprintf(extra+strlen(extra), "RSSI-A                          = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi0 - pAd->BbpRssiToDbmDelta));
-        sprintf(extra+strlen(extra), "RSSI-B (if available)           = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi1 - pAd->BbpRssiToDbmDelta));
-        sprintf(extra+strlen(extra), "RSSI-C (if available)           = %ld\n\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi2 - pAd->BbpRssiToDbmDelta));
-	}
-    sprintf(extra+strlen(extra), "WpaSupplicantUP                 = %d\n\n", pAd->StaCfg.WpaSupplicantUP);
-
-    wrq->length = strlen(extra) + 1; // 1: size of '\0'
-    DBGPRINT(RT_DEBUG_TRACE, ("<== rt_private_get_statistics, wrq->length = %d\n", wrq->length));
-
-    return Status;
-}
-
-void	getBaInfo(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pOutBuf)
-{
-	INT i, j;
-	BA_ORI_ENTRY *pOriBAEntry;
-	BA_REC_ENTRY *pRecBAEntry;
-
-	for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
-	{
-		PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
-		if (((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
-			|| (pEntry->ValidAsWDS) || (pEntry->ValidAsMesh))
-		{
-			sprintf(pOutBuf + strlen(pOutBuf), "\n%02X:%02X:%02X:%02X:%02X:%02X (Aid = %d) (AP) -\n",
-				pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
-				pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5], pEntry->Aid);
+	for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++) {
+		struct rt_mac_table_entry *pEntry = &pAd->MacTab.Content[i];
+		if (((pEntry->ValidAsCLI || pEntry->ValidAsApCli)
+		     && (pEntry->Sst == SST_ASSOC))
+		    || (pEntry->ValidAsWDS) || (pEntry->ValidAsMesh)) {
+			sprintf(pOutBuf + strlen(pOutBuf),
+				"\n%02X:%02X:%02X:%02X:%02X:%02X (Aid = %d) (AP) -\n",
+				pEntry->Addr[0], pEntry->Addr[1],
+				pEntry->Addr[2], pEntry->Addr[3],
+				pEntry->Addr[4], pEntry->Addr[5], pEntry->Aid);
 
 			sprintf(pOutBuf, "%s[Recipient]\n", pOutBuf);
-			for (j=0; j < NUM_OF_TID; j++)
-			{
-				if (pEntry->BARecWcidArray[j] != 0)
-				{
-					pRecBAEntry =&pAd->BATable.BARecEntry[pEntry->BARecWcidArray[j]];
-					sprintf(pOutBuf + strlen(pOutBuf), "TID=%d, BAWinSize=%d, LastIndSeq=%d, ReorderingPkts=%d\n", j, pRecBAEntry->BAWinSize, pRecBAEntry->LastIndSeq, pRecBAEntry->list.qlen);
+			for (j = 0; j < NUM_OF_TID; j++) {
+				if (pEntry->BARecWcidArray[j] != 0) {
+					pRecBAEntry =
+					    &pAd->BATable.BARecEntry[pEntry->
+								     BARecWcidArray
+								     [j]];
+					sprintf(pOutBuf + strlen(pOutBuf),
+						"TID=%d, BAWinSize=%d, LastIndSeq=%d, ReorderingPkts=%d\n",
+						j, pRecBAEntry->BAWinSize,
+						pRecBAEntry->LastIndSeq,
+						pRecBAEntry->list.qlen);
 				}
 			}
 			sprintf(pOutBuf, "%s\n", pOutBuf);
 
 			sprintf(pOutBuf, "%s[Originator]\n", pOutBuf);
-			for (j=0; j < NUM_OF_TID; j++)
-			{
-				if (pEntry->BAOriWcidArray[j] != 0)
-				{
-					pOriBAEntry =&pAd->BATable.BAOriEntry[pEntry->BAOriWcidArray[j]];
-					sprintf(pOutBuf + strlen(pOutBuf), "TID=%d, BAWinSize=%d, StartSeq=%d, CurTxSeq=%d\n", j, pOriBAEntry->BAWinSize, pOriBAEntry->Sequence, pEntry->TxSeq[j]);
+			for (j = 0; j < NUM_OF_TID; j++) {
+				if (pEntry->BAOriWcidArray[j] != 0) {
+					pOriBAEntry =
+					    &pAd->BATable.BAOriEntry[pEntry->
+								     BAOriWcidArray
+								     [j]];
+					sprintf(pOutBuf + strlen(pOutBuf),
+						"TID=%d, BAWinSize=%d, StartSeq=%d, CurTxSeq=%d\n",
+						j, pOriBAEntry->BAWinSize,
+						pOriBAEntry->Sequence,
+						pEntry->TxSeq[j]);
 				}
 			}
 			sprintf(pOutBuf, "%s\n\n", pOutBuf);
 		}
-        if (strlen(pOutBuf) > (IW_PRIV_SIZE_MASK - 30))
-                break;
+		if (strlen(pOutBuf) > (IW_PRIV_SIZE_MASK - 30))
+			break;
 	}
 
 	return;
 }
 
-static int
-rt_private_show(struct net_device *dev, struct iw_request_info *info,
-		struct iw_point *wrq, char *extra)
-{
-    INT				Status = 0;
-    PRTMP_ADAPTER pAd = dev->ml_priv;
-    POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
-    u32             subcmd = wrq->flags;
-
-    if (extra == NULL)
-    {
-        wrq->length = 0;
-        return -EIO;
-    }
-    memset(extra, 0x00, IW_PRIV_SIZE_MASK);
-
-	{
-		pObj->ioctl_if_type = INT_MAIN;
-        pObj->ioctl_if = MAIN_MBSSID;
-	}
-
-    switch(subcmd)
-    {
-
-        case SHOW_CONN_STATUS:
-            if (MONITOR_ON(pAd))
-            {
-                if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
-                    pAd->CommonCfg.RegTransmitSetting.field.BW)
-                    sprintf(extra, "Monitor Mode(CentralChannel %d)\n", pAd->CommonCfg.CentralChannel);
-                else
-                    sprintf(extra, "Monitor Mode(Channel %d)\n", pAd->CommonCfg.Channel);
-            }
-            else
-            {
-                if (pAd->IndicateMediaState == NdisMediaStateConnected)
-            	{
-            	    if (INFRA_ON(pAd))
-                    {
-                    sprintf(extra, "Connected(AP: %s[%02X:%02X:%02X:%02X:%02X:%02X])\n",
-                                    pAd->CommonCfg.Ssid,
-                                    pAd->CommonCfg.Bssid[0],
-                                    pAd->CommonCfg.Bssid[1],
-                                    pAd->CommonCfg.Bssid[2],
-                                    pAd->CommonCfg.Bssid[3],
-                                    pAd->CommonCfg.Bssid[4],
-                                    pAd->CommonCfg.Bssid[5]);
-            		DBGPRINT(RT_DEBUG_TRACE ,("Ssid=%s ,Ssidlen = %d\n",pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen));
-            	}
-                    else if (ADHOC_ON(pAd))
-                        sprintf(extra, "Connected\n");
-            	}
-            	else
-            	{
-            	    sprintf(extra, "Disconnected\n");
-            		DBGPRINT(RT_DEBUG_TRACE ,("ConnStatus is not connected\n"));
-            	}
-            }
-            wrq->length = strlen(extra) + 1; // 1: size of '\0'
-            break;
-        case SHOW_DRVIER_VERION:
-            sprintf(extra, "Driver version-%s, %s %s\n", STA_DRIVER_VERSION, __DATE__, __TIME__ );
-            wrq->length = strlen(extra) + 1; // 1: size of '\0'
-            break;
-        case SHOW_BA_INFO:
-            getBaInfo(pAd, extra);
-            wrq->length = strlen(extra) + 1; // 1: size of '\0'
-            break;
-		case SHOW_DESC_INFO:
-			{
-				Show_DescInfo_Proc(pAd, NULL);
-				wrq->length = 0; // 1: size of '\0'
-			}
-			break;
-        case RAIO_OFF:
-            if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-            {
-                sprintf(extra, "Scanning\n");
-                wrq->length = strlen(extra) + 1; // 1: size of '\0'
-                break;
-            }
-            pAd->StaCfg.bSwRadio = FALSE;
-            if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
-            {
-                pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
-                if (pAd->StaCfg.bRadio == FALSE)
-                {
-                    MlmeRadioOff(pAd);
-                    // Update extra information
-					pAd->ExtraInfo = SW_RADIO_OFF;
-                }
-            }
-            sprintf(extra, "Radio Off\n");
-            wrq->length = strlen(extra) + 1; // 1: size of '\0'
-            break;
-        case RAIO_ON:
-#ifdef RT2870
-            if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-            {
-                sprintf(extra, "Scanning\n");
-                wrq->length = strlen(extra) + 1; // 1: size of '\0'
-                break;
-            }
-#endif
-            pAd->StaCfg.bSwRadio = TRUE;
-            //if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
-            {
-                pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
-                if (pAd->StaCfg.bRadio == TRUE)
-                {
-                    MlmeRadioOn(pAd);
-                    // Update extra information
-					pAd->ExtraInfo = EXTRA_INFO_CLEAR;
-                }
-            }
-            sprintf(extra, "Radio On\n");
-            wrq->length = strlen(extra) + 1; // 1: size of '\0'
-            break;
-
-		case SHOW_CFG_VALUE:
-			{
-				Status = RTMPShowCfgValue(pAd, wrq->pointer, extra);
-				if (Status == 0)
-					wrq->length = strlen(extra) + 1; // 1: size of '\0'
-			}
-			break;
-        default:
-            DBGPRINT(RT_DEBUG_TRACE, ("%s - unknow subcmd = %d\n", __func__, subcmd));
-            break;
-    }
-
-    return Status;
-}
-
 int rt_ioctl_siwmlme(struct net_device *dev,
-			   struct iw_request_info *info,
-			   union iwreq_data *wrqu,
-			   char *extra)
+		     struct iw_request_info *info,
+		     union iwreq_data *wrqu, char *extra)
 {
-	PRTMP_ADAPTER   pAd = dev->ml_priv;
+	struct rt_rtmp_adapter *pAd = NULL;
 	struct iw_mlme *pMlme = (struct iw_mlme *)wrqu->data.pointer;
-	MLME_QUEUE_ELEM				MsgElem;
-	MLME_DISASSOC_REQ_STRUCT	DisAssocReq;
-	MLME_DEAUTH_REQ_STRUCT      DeAuthReq;
+	struct rt_mlme_queue_elem MsgElem;
+	struct rt_mlme_disassoc_req DisAssocReq;
+	struct rt_mlme_deauth_req DeAuthReq;
+
+	GET_PAD_FROM_NET_DEV(pAd, dev);
 
 	DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __func__));
 
 	if (pMlme == NULL)
 		return -EINVAL;
 
-	switch(pMlme->cmd)
-	{
+	switch (pMlme->cmd) {
 #ifdef IW_MLME_DEAUTH
-		case IW_MLME_DEAUTH:
-			DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DEAUTH\n", __func__));
-			COPY_MAC_ADDR(DeAuthReq.Addr, pAd->CommonCfg.Bssid);
-			DeAuthReq.Reason = pMlme->reason_code;
-			MsgElem.MsgLen = sizeof(MLME_DEAUTH_REQ_STRUCT);
-			NdisMoveMemory(MsgElem.Msg, &DeAuthReq, sizeof(MLME_DEAUTH_REQ_STRUCT));
-			MlmeDeauthReqAction(pAd, &MsgElem);
-			if (INFRA_ON(pAd))
-			{
-			    LinkDown(pAd, FALSE);
-			    pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-			}
-			break;
-#endif // IW_MLME_DEAUTH //
+	case IW_MLME_DEAUTH:
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("====> %s - IW_MLME_DEAUTH\n", __func__));
+		COPY_MAC_ADDR(DeAuthReq.Addr, pAd->CommonCfg.Bssid);
+		DeAuthReq.Reason = pMlme->reason_code;
+		MsgElem.MsgLen = sizeof(struct rt_mlme_deauth_req);
+		NdisMoveMemory(MsgElem.Msg, &DeAuthReq,
+			       sizeof(struct rt_mlme_deauth_req));
+		MlmeDeauthReqAction(pAd, &MsgElem);
+		if (INFRA_ON(pAd)) {
+			LinkDown(pAd, FALSE);
+			pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+		}
+		break;
+#endif /* IW_MLME_DEAUTH // */
 #ifdef IW_MLME_DISASSOC
-		case IW_MLME_DISASSOC:
-			DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DISASSOC\n", __func__));
-			COPY_MAC_ADDR(DisAssocReq.Addr, pAd->CommonCfg.Bssid);
-			DisAssocReq.Reason =  pMlme->reason_code;
+	case IW_MLME_DISASSOC:
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("====> %s - IW_MLME_DISASSOC\n", __func__));
+		COPY_MAC_ADDR(DisAssocReq.Addr, pAd->CommonCfg.Bssid);
+		DisAssocReq.Reason = pMlme->reason_code;
 
-			MsgElem.Machine = ASSOC_STATE_MACHINE;
-			MsgElem.MsgType = MT2_MLME_DISASSOC_REQ;
-			MsgElem.MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
-			NdisMoveMemory(MsgElem.Msg, &DisAssocReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
+		MsgElem.Machine = ASSOC_STATE_MACHINE;
+		MsgElem.MsgType = MT2_MLME_DISASSOC_REQ;
+		MsgElem.MsgLen = sizeof(struct rt_mlme_disassoc_req);
+		NdisMoveMemory(MsgElem.Msg, &DisAssocReq,
+			       sizeof(struct rt_mlme_disassoc_req));
 
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
-			MlmeDisassocReqAction(pAd, &MsgElem);
-			break;
-#endif // IW_MLME_DISASSOC //
-		default:
-			DBGPRINT(RT_DEBUG_TRACE, ("====> %s - Unknow Command\n", __func__));
-			break;
+		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
+		MlmeDisassocReqAction(pAd, &MsgElem);
+		break;
+#endif /* IW_MLME_DISASSOC // */
+	default:
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("====> %s - Unknow Command\n", __func__));
+		break;
 	}
 
 	return 0;
 }
 
 int rt_ioctl_siwauth(struct net_device *dev,
-			  struct iw_request_info *info,
-			  union iwreq_data *wrqu, char *extra)
+		     struct iw_request_info *info,
+		     union iwreq_data *wrqu, char *extra)
 {
-	PRTMP_ADAPTER   pAdapter = dev->ml_priv;
+	struct rt_rtmp_adapter *pAdapter = NULL;
 	struct iw_param *param = &wrqu->param;
 
-    //check if the interface is down
-	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
-  		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-    	return -ENETDOWN;
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
+
+	/*check if the interface is down */
+	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
+		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+		return -ENETDOWN;
 	}
 	switch (param->flags & IW_AUTH_INDEX) {
-    	case IW_AUTH_WPA_VERSION:
-            if (param->value == IW_AUTH_WPA_VERSION_WPA)
-            {
-                pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
-				if (pAdapter->StaCfg.BssType == BSS_ADHOC)
-					pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
-            }
-            else if (param->value == IW_AUTH_WPA_VERSION_WPA2)
-                pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
+	case IW_AUTH_WPA_VERSION:
+		if (param->value == IW_AUTH_WPA_VERSION_WPA) {
+			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
+			if (pAdapter->StaCfg.BssType == BSS_ADHOC)
+				pAdapter->StaCfg.AuthMode =
+				    Ndis802_11AuthModeWPANone;
+		} else if (param->value == IW_AUTH_WPA_VERSION_WPA2)
+			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
 
-            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __func__, param->value));
-            break;
-    	case IW_AUTH_CIPHER_PAIRWISE:
-            if (param->value == IW_AUTH_CIPHER_NONE)
-            {
-                pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
-                pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
-                pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
-            }
-            else if (param->value == IW_AUTH_CIPHER_WEP40 ||
-                     param->value == IW_AUTH_CIPHER_WEP104)
-            {
-                pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
-                pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
-                pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
-                pAdapter->StaCfg.IEEE8021X = FALSE;
-            }
-            else if (param->value == IW_AUTH_CIPHER_TKIP)
-            {
-                pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
-                pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
-                pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
-            }
-            else if (param->value == IW_AUTH_CIPHER_CCMP)
-            {
-                pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
-                pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
-                pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
-            }
-            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_PAIRWISE - param->value = %d!\n", __func__, param->value));
-            break;
-    	case IW_AUTH_CIPHER_GROUP:
-            if (param->value == IW_AUTH_CIPHER_NONE)
-            {
-                pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
-            }
-            else if (param->value == IW_AUTH_CIPHER_WEP40 ||
-                     param->value == IW_AUTH_CIPHER_WEP104)
-            {
-                pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
-            }
-            else if (param->value == IW_AUTH_CIPHER_TKIP)
-            {
-                pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
-            }
-            else if (param->value == IW_AUTH_CIPHER_CCMP)
-            {
-                pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
-            }
-            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_GROUP - param->value = %d!\n", __func__, param->value));
-            break;
-    	case IW_AUTH_KEY_MGMT:
-            if (param->value == IW_AUTH_KEY_MGMT_802_1X)
-            {
-                if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
-                {
-                    pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
-                    pAdapter->StaCfg.IEEE8021X = FALSE;
-                }
-                else if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
-                {
-                    pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
-                    pAdapter->StaCfg.IEEE8021X = FALSE;
-                }
-                else
-                    // WEP 1x
-                    pAdapter->StaCfg.IEEE8021X = TRUE;
-            }
-            else if (param->value == 0)
-            {
-				STA_PORT_SECURED(pAdapter);
-            }
-            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_KEY_MGMT - param->value = %d!\n", __func__, param->value));
-            break;
-    	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
-            break;
-    	case IW_AUTH_PRIVACY_INVOKED:
-            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_PRIVACY_INVOKED - param->value = %d!\n", __func__, param->value));
-    		break;
-    	case IW_AUTH_DROP_UNENCRYPTED:
-            if (param->value != 0)
-                pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-			else
-			{
-				STA_PORT_SECURED(pAdapter);
-			}
-            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __func__, param->value));
-    		break;
-    	case IW_AUTH_80211_AUTH_ALG:
-			if (param->value & IW_AUTH_ALG_SHARED_KEY)
-            {
-				pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
-			}
-            else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
-            {
-				pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
-			}
-            else
-				return -EINVAL;
-            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_80211_AUTH_ALG - param->value = %d!\n", __func__, param->value));
-			break;
-    	case IW_AUTH_WPA_ENABLED:
-    		DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_ENABLED - Driver supports WPA!(param->value = %d)\n", __func__, param->value));
-    		break;
-    	default:
-    		return -EOPNOTSUPP;
-}
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n",
+			  __func__, param->value));
+		break;
+	case IW_AUTH_CIPHER_PAIRWISE:
+		if (param->value == IW_AUTH_CIPHER_NONE) {
+			pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
+			pAdapter->StaCfg.OrigWepStatus =
+			    pAdapter->StaCfg.WepStatus;
+			pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
+		} else if (param->value == IW_AUTH_CIPHER_WEP40 ||
+			   param->value == IW_AUTH_CIPHER_WEP104) {
+			pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
+			pAdapter->StaCfg.OrigWepStatus =
+			    pAdapter->StaCfg.WepStatus;
+			pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
+			pAdapter->StaCfg.IEEE8021X = FALSE;
+		} else if (param->value == IW_AUTH_CIPHER_TKIP) {
+			pAdapter->StaCfg.WepStatus =
+			    Ndis802_11Encryption2Enabled;
+			pAdapter->StaCfg.OrigWepStatus =
+			    pAdapter->StaCfg.WepStatus;
+			pAdapter->StaCfg.PairCipher =
+			    Ndis802_11Encryption2Enabled;
+		} else if (param->value == IW_AUTH_CIPHER_CCMP) {
+			pAdapter->StaCfg.WepStatus =
+			    Ndis802_11Encryption3Enabled;
+			pAdapter->StaCfg.OrigWepStatus =
+			    pAdapter->StaCfg.WepStatus;
+			pAdapter->StaCfg.PairCipher =
+			    Ndis802_11Encryption3Enabled;
+		}
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("%s::IW_AUTH_CIPHER_PAIRWISE - param->value = %d!\n",
+			  __func__, param->value));
+		break;
+	case IW_AUTH_CIPHER_GROUP:
+		if (param->value == IW_AUTH_CIPHER_NONE) {
+			pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
+		} else if (param->value == IW_AUTH_CIPHER_WEP40 ||
+			   param->value == IW_AUTH_CIPHER_WEP104) {
+			pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
+		} else if (param->value == IW_AUTH_CIPHER_TKIP) {
+			pAdapter->StaCfg.GroupCipher =
+			    Ndis802_11Encryption2Enabled;
+		} else if (param->value == IW_AUTH_CIPHER_CCMP) {
+			pAdapter->StaCfg.GroupCipher =
+			    Ndis802_11Encryption3Enabled;
+		}
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("%s::IW_AUTH_CIPHER_GROUP - param->value = %d!\n",
+			  __func__, param->value));
+		break;
+	case IW_AUTH_KEY_MGMT:
+		if (param->value == IW_AUTH_KEY_MGMT_802_1X) {
+			if (pAdapter->StaCfg.AuthMode ==
+			    Ndis802_11AuthModeWPAPSK) {
+				pAdapter->StaCfg.AuthMode =
+				    Ndis802_11AuthModeWPA;
+				pAdapter->StaCfg.IEEE8021X = FALSE;
+			} else if (pAdapter->StaCfg.AuthMode ==
+				   Ndis802_11AuthModeWPA2PSK) {
+				pAdapter->StaCfg.AuthMode =
+				    Ndis802_11AuthModeWPA2;
+				pAdapter->StaCfg.IEEE8021X = FALSE;
+			} else
+				/* WEP 1x */
+				pAdapter->StaCfg.IEEE8021X = TRUE;
+		} else if (param->value == 0) {
+			/*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
+			STA_PORT_SECURED(pAdapter);
+		}
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("%s::IW_AUTH_KEY_MGMT - param->value = %d!\n",
+			  __func__, param->value));
+		break;
+	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+		break;
+	case IW_AUTH_PRIVACY_INVOKED:
+		/*if (param->value == 0)
+		   {
+		   pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+		   pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
+		   pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+		   pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
+		   pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
+		   } */
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("%s::IW_AUTH_PRIVACY_INVOKED - param->value = %d!\n",
+			  __func__, param->value));
+		break;
+	case IW_AUTH_DROP_UNENCRYPTED:
+		if (param->value != 0)
+			pAdapter->StaCfg.PortSecured =
+			    WPA_802_1X_PORT_NOT_SECURED;
+		else {
+			/*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
+			STA_PORT_SECURED(pAdapter);
+		}
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n",
+			  __func__, param->value));
+		break;
+	case IW_AUTH_80211_AUTH_ALG:
+		if (param->value & IW_AUTH_ALG_SHARED_KEY) {
+			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
+		} else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
+			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+		} else
+			return -EINVAL;
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("%s::IW_AUTH_80211_AUTH_ALG - param->value = %d!\n",
+			  __func__, param->value));
+		break;
+	case IW_AUTH_WPA_ENABLED:
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("%s::IW_AUTH_WPA_ENABLED - Driver supports WPA!(param->value = %d)\n",
+			  __func__, param->value));
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
 
 	return 0;
 }
 
 int rt_ioctl_giwauth(struct net_device *dev,
-			       struct iw_request_info *info,
-			       union iwreq_data *wrqu, char *extra)
+		     struct iw_request_info *info,
+		     union iwreq_data *wrqu, char *extra)
 {
-	PRTMP_ADAPTER   pAdapter = dev->ml_priv;
+	struct rt_rtmp_adapter *pAdapter = NULL;
 	struct iw_param *param = &wrqu->param;
 
-    //check if the interface is down
-	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-    {
-  		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-    	return -ENETDOWN;
-    }
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
+
+	/*check if the interface is down */
+	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
+		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+		return -ENETDOWN;
+	}
 
 	switch (param->flags & IW_AUTH_INDEX) {
 	case IW_AUTH_DROP_UNENCRYPTED:
-        param->value = (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled) ? 0 : 1;
+		param->value =
+		    (pAdapter->StaCfg.WepStatus ==
+		     Ndis802_11WEPDisabled) ? 0 : 1;
 		break;
 
 	case IW_AUTH_80211_AUTH_ALG:
-        param->value = (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared) ? IW_AUTH_ALG_SHARED_KEY : IW_AUTH_ALG_OPEN_SYSTEM;
+		param->value =
+		    (pAdapter->StaCfg.AuthMode ==
+		     Ndis802_11AuthModeShared) ? IW_AUTH_ALG_SHARED_KEY :
+		    IW_AUTH_ALG_OPEN_SYSTEM;
 		break;
 
 	case IW_AUTH_WPA_ENABLED:
-		param->value = (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) ? 1 : 0;
+		param->value =
+		    (pAdapter->StaCfg.AuthMode >=
+		     Ndis802_11AuthModeWPA) ? 1 : 0;
 		break;
 
 	default:
 		return -EOPNOTSUPP;
 	}
-    DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_giwauth::param->value = %d!\n", param->value));
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("rt_ioctl_giwauth::param->value = %d!\n", param->value));
 	return 0;
 }
 
-void fnSetCipherKey(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  INT             keyIdx,
-    IN  UCHAR           CipherAlg,
-    IN  BOOLEAN         bGTK,
-    IN  struct iw_encode_ext *ext)
+void fnSetCipherKey(struct rt_rtmp_adapter *pAdapter,
+		    int keyIdx,
+		    u8 CipherAlg,
+		    IN BOOLEAN bGTK, IN struct iw_encode_ext *ext)
 {
-#ifdef RT2860
-	RTMP_CLEAR_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
-	if (RTMP_TEST_PSFLAG(pAdapter, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
-	{
-		if (pAdapter->StaCfg.bRadio == FALSE)
-		{
-			RTMP_SET_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
-			return;
-		}
-		DBGPRINT(RT_DEBUG_TRACE,("RTMPWPAAddKeyProc1==>\n"));
-		RTMPPCIeLinkCtrlValueRestore(pAdapter, RESTORE_HALT);
-		RTMPusecDelay(6000);
-		pAdapter->bPCIclkOff = FALSE;
-	}
-#endif
-    NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
-    pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK;
-    NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, LEN_TKIP_EK);
-    NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].TxMic, ext->key + LEN_TKIP_EK, LEN_TKIP_TXMICK);
-    NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].RxMic, ext->key + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
-    pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CipherAlg;
+	NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(struct rt_cipher_key));
+	pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK;
+	NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key,
+		       LEN_TKIP_EK);
+	NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].TxMic,
+		       ext->key + LEN_TKIP_EK, LEN_TKIP_TXMICK);
+	NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].RxMic,
+		       ext->key + LEN_TKIP_EK + LEN_TKIP_TXMICK,
+		       LEN_TKIP_RXMICK);
+	pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CipherAlg;
 
-    // Update group key information to ASIC Shared Key Table
+	/* Update group key information to ASIC Shared Key Table */
 	AsicAddSharedKeyEntry(pAdapter,
-						  BSS0,
-						  keyIdx,
-						  pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
-						  pAdapter->SharedKey[BSS0][keyIdx].Key,
-						  pAdapter->SharedKey[BSS0][keyIdx].TxMic,
-						  pAdapter->SharedKey[BSS0][keyIdx].RxMic);
+			      BSS0,
+			      keyIdx,
+			      pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
+			      pAdapter->SharedKey[BSS0][keyIdx].Key,
+			      pAdapter->SharedKey[BSS0][keyIdx].TxMic,
+			      pAdapter->SharedKey[BSS0][keyIdx].RxMic);
 
-    if (bGTK)
-        // Update ASIC WCID attribute table and IVEIV table
-    	RTMPAddWcidAttributeEntry(pAdapter,
-    							  BSS0,
-    							  keyIdx,
-    							  pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
-    							  NULL);
-    else
-        // Update ASIC WCID attribute table and IVEIV table
-    	RTMPAddWcidAttributeEntry(pAdapter,
-    							  BSS0,
-    							  keyIdx,
-    							  pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
-    							  &pAdapter->MacTab.Content[BSSID_WCID]);
-#ifdef RT2860
-	RTMP_SET_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
-#endif
+	if (bGTK)
+		/* Update ASIC WCID attribute table and IVEIV table */
+		RTMPAddWcidAttributeEntry(pAdapter,
+					  BSS0,
+					  keyIdx,
+					  pAdapter->SharedKey[BSS0][keyIdx].
+					  CipherAlg, NULL);
+	else
+		/* Update ASIC WCID attribute table and IVEIV table */
+		RTMPAddWcidAttributeEntry(pAdapter,
+					  BSS0,
+					  keyIdx,
+					  pAdapter->SharedKey[BSS0][keyIdx].
+					  CipherAlg,
+					  &pAdapter->MacTab.
+					  Content[BSSID_WCID]);
 }
 
 int rt_ioctl_siwencodeext(struct net_device *dev,
-			   struct iw_request_info *info,
-			   union iwreq_data *wrqu,
-			   char *extra)
-			{
-    PRTMP_ADAPTER   pAdapter = dev->ml_priv;
+			  struct iw_request_info *info,
+			  union iwreq_data *wrqu, char *extra)
+{
+	struct rt_rtmp_adapter *pAdapter = NULL;
 	struct iw_point *encoding = &wrqu->encoding;
 	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-    int keyIdx, alg = ext->alg;
+	int keyIdx, alg = ext->alg;
 
-    //check if the interface is down
-	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
-  		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-    	return -ENETDOWN;
+	GET_PAD_FROM_NET_DEV(pAdapter, dev);
+
+	/*check if the interface is down */
+	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
+		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+		return -ENETDOWN;
 	}
 
-    if (encoding->flags & IW_ENCODE_DISABLED)
-	{
-        keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
-        // set BSSID wcid entry of the Pair-wise Key table as no-security mode
-	    AsicRemovePairwiseKeyEntry(pAdapter, BSS0, BSSID_WCID);
-        pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
+	if (encoding->flags & IW_ENCODE_DISABLED) {
+		keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
+		/* set BSSID wcid entry of the Pair-wise Key table as no-security mode */
+		AsicRemovePairwiseKeyEntry(pAdapter, BSS0, BSSID_WCID);
+		pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
 		pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_NONE;
-		AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)keyIdx);
-        NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
-        DBGPRINT(RT_DEBUG_TRACE, ("%s::Remove all keys!(encoding->flags = %x)\n", __func__, encoding->flags));
-    }
-					else
-    {
-        // Get Key Index and convet to our own defined key index
-    	keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
-    	if((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
-    		return -EINVAL;
+		AsicRemoveSharedKeyEntry(pAdapter, 0, (u8)keyIdx);
+		NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx],
+			       sizeof(struct rt_cipher_key));
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("%s::Remove all keys!(encoding->flags = %x)\n",
+			  __func__, encoding->flags));
+	} else {
+		/* Get Key Index and convet to our own defined key index */
+		keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
+		if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
+			return -EINVAL;
 
-        if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
-        {
-            pAdapter->StaCfg.DefaultKeyId = keyIdx;
-            DBGPRINT(RT_DEBUG_TRACE, ("%s::DefaultKeyId = %d\n", __func__, pAdapter->StaCfg.DefaultKeyId));
-        }
+		if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+			pAdapter->StaCfg.DefaultKeyId = keyIdx;
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("%s::DefaultKeyId = %d\n", __func__,
+				  pAdapter->StaCfg.DefaultKeyId));
+		}
 
-        switch (alg) {
-    		case IW_ENCODE_ALG_NONE:
-                DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_NONE\n", __func__));
-    			break;
-    		case IW_ENCODE_ALG_WEP:
-                DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_WEP - ext->key_len = %d, keyIdx = %d\n", __func__, ext->key_len, keyIdx));
-    			if (ext->key_len == MAX_WEP_KEY_SIZE)
-                {
-        			pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
-                    pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
-				}
-        		else if (ext->key_len == MIN_WEP_KEY_SIZE)
-                {
-                    pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
-                    pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
+		switch (alg) {
+		case IW_ENCODE_ALG_NONE:
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("%s::IW_ENCODE_ALG_NONE\n", __func__));
+			break;
+		case IW_ENCODE_ALG_WEP:
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("%s::IW_ENCODE_ALG_WEP - ext->key_len = %d, keyIdx = %d\n",
+				  __func__, ext->key_len, keyIdx));
+			if (ext->key_len == MAX_WEP_KEY_SIZE) {
+				pAdapter->SharedKey[BSS0][keyIdx].KeyLen =
+				    MAX_WEP_KEY_SIZE;
+				pAdapter->SharedKey[BSS0][keyIdx].CipherAlg =
+				    CIPHER_WEP128;
+			} else if (ext->key_len == MIN_WEP_KEY_SIZE) {
+				pAdapter->SharedKey[BSS0][keyIdx].KeyLen =
+				    MIN_WEP_KEY_SIZE;
+				pAdapter->SharedKey[BSS0][keyIdx].CipherAlg =
+				    CIPHER_WEP64;
+			} else
+				return -EINVAL;
+
+			NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,
+				       16);
+			NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,
+				       ext->key, ext->key_len);
+			if (pAdapter->StaCfg.GroupCipher ==
+			    Ndis802_11GroupWEP40Enabled
+			    || pAdapter->StaCfg.GroupCipher ==
+			    Ndis802_11GroupWEP104Enabled) {
+				/* Set Group key material to Asic */
+				AsicAddSharedKeyEntry(pAdapter, BSS0, keyIdx,
+						      pAdapter->
+						      SharedKey[BSS0][keyIdx].
+						      CipherAlg,
+						      pAdapter->
+						      SharedKey[BSS0][keyIdx].
+						      Key, NULL, NULL);
+
+				/* Update WCID attribute table and IVEIV table for this group key table */
+				RTMPAddWcidAttributeEntry(pAdapter, BSS0,
+							  keyIdx,
+							  pAdapter->
+							  SharedKey[BSS0]
+							  [keyIdx].CipherAlg,
+							  NULL);
+
+				STA_PORT_SECURED(pAdapter);
+
+				/* Indicate Connected for GUI */
+				pAdapter->IndicateMediaState =
+				    NdisMediaStateConnected;
 			}
-        		else
-                    return -EINVAL;
-
-                NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,  16);
-			    NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, ext->key_len);
-				if (pAdapter->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled ||
-					pAdapter->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
+			break;
+		case IW_ENCODE_ALG_TKIP:
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n",
+				  __func__, keyIdx, ext->key_len));
+			if (ext->key_len == 32) {
+				if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+					fnSetCipherKey(pAdapter, keyIdx,
+						       CIPHER_TKIP, FALSE, ext);
+					if (pAdapter->StaCfg.AuthMode >=
+					    Ndis802_11AuthModeWPA2) {
+						/*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
+						STA_PORT_SECURED(pAdapter);
+						pAdapter->IndicateMediaState =
+						    NdisMediaStateConnected;
+					}
+				} else if (ext->
+					   ext_flags & IW_ENCODE_EXT_GROUP_KEY)
 				{
-					// Set Group key material to Asic
-					AsicAddSharedKeyEntry(pAdapter, BSS0, keyIdx, pAdapter->SharedKey[BSS0][keyIdx].CipherAlg, pAdapter->SharedKey[BSS0][keyIdx].Key, NULL, NULL);
+					fnSetCipherKey(pAdapter, keyIdx,
+						       CIPHER_TKIP, TRUE, ext);
 
-					// Update WCID attribute table and IVEIV table for this group key table
-					RTMPAddWcidAttributeEntry(pAdapter, BSS0, keyIdx, pAdapter->SharedKey[BSS0][keyIdx].CipherAlg, NULL);
-
+					/* set 802.1x port control */
+					/*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
 					STA_PORT_SECURED(pAdapter);
-
-    				// Indicate Connected for GUI
-    				pAdapter->IndicateMediaState = NdisMediaStateConnected;
+					pAdapter->IndicateMediaState =
+					    NdisMediaStateConnected;
 				}
-    			break;
-            case IW_ENCODE_ALG_TKIP:
-                DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n", __func__, keyIdx, ext->key_len));
-                if (ext->key_len == 32)
-                {
-                    if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
-                    {
-                        fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, FALSE, ext);
-                        if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
-                        {
-                            STA_PORT_SECURED(pAdapter);
-                        }
+			} else
+				return -EINVAL;
+			break;
+		case IW_ENCODE_ALG_CCMP:
+			if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+				fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES,
+					       FALSE, ext);
+				if (pAdapter->StaCfg.AuthMode >=
+				    Ndis802_11AuthModeWPA2)
+					/*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
+					STA_PORT_SECURED(pAdapter);
+				pAdapter->IndicateMediaState =
+				    NdisMediaStateConnected;
+			} else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
+				fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES,
+					       TRUE, ext);
+
+				/* set 802.1x port control */
+				/*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
+				STA_PORT_SECURED(pAdapter);
+				pAdapter->IndicateMediaState =
+				    NdisMediaStateConnected;
+			}
+			break;
+		default:
+			return -EINVAL;
 		}
-                    else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
-                    {
-                        fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, TRUE, ext);
+	}
 
-                        // set 802.1x port control
-            	        STA_PORT_SECURED(pAdapter);
-                    }
-                }
-                else
-                    return -EINVAL;
-                break;
-            case IW_ENCODE_ALG_CCMP:
-                if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
-		{
-                    fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, FALSE, ext);
-                    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
-                    	STA_PORT_SECURED(pAdapter);
-                }
-                else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
-                {
-                    fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, TRUE, ext);
-
-                    // set 802.1x port control
-        	        STA_PORT_SECURED(pAdapter);
-                }
-                break;
-    		default:
-    			return -EINVAL;
-		}
-    }
-
-    return 0;
+	return 0;
 }
 
 int
 rt_ioctl_giwencodeext(struct net_device *dev,
-			  struct iw_request_info *info,
-			  union iwreq_data *wrqu, char *extra)
+		      struct iw_request_info *info,
+		      union iwreq_data *wrqu, char *extra)
 {
-	PRTMP_ADAPTER pAd = dev->ml_priv;
-	PCHAR pKey = NULL;
+	struct rt_rtmp_adapter *pAd = NULL;
+	char *pKey = NULL;
 	struct iw_point *encoding = &wrqu->encoding;
 	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
 	int idx, max_key_len;
 
-	DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_giwencodeext\n"));
+	GET_PAD_FROM_NET_DEV(pAd, dev);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> rt_ioctl_giwencodeext\n"));
 
 	max_key_len = encoding->length - sizeof(*ext);
 	if (max_key_len < 0)
 		return -EINVAL;
 
 	idx = encoding->flags & IW_ENCODE_INDEX;
-	if (idx)
-	{
+	if (idx) {
 		if (idx < 1 || idx > 4)
 			return -EINVAL;
 		idx--;
 
 		if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
-			(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled))
-		{
-			if (idx != pAd->StaCfg.DefaultKeyId)
-			{
+		    (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)) {
+			if (idx != pAd->StaCfg.DefaultKeyId) {
 				ext->key_len = 0;
 				return 0;
 			}
 		}
-	}
-	else
+	} else
 		idx = pAd->StaCfg.DefaultKeyId;
 
 	encoding->flags = idx + 1;
 	memset(ext, 0, sizeof(*ext));
 
 	ext->key_len = 0;
-	switch(pAd->StaCfg.WepStatus) {
-		case Ndis802_11WEPDisabled:
-			ext->alg = IW_ENCODE_ALG_NONE;
-			encoding->flags |= IW_ENCODE_DISABLED;
-			break;
-		case Ndis802_11WEPEnabled:
-			ext->alg = IW_ENCODE_ALG_WEP;
-			if (pAd->SharedKey[BSS0][idx].KeyLen > max_key_len)
-				return -E2BIG;
-			else
-			{
-				ext->key_len = pAd->SharedKey[BSS0][idx].KeyLen;
-				pKey = &(pAd->SharedKey[BSS0][idx].Key[0]);
-			}
-			break;
-		case Ndis802_11Encryption2Enabled:
-		case Ndis802_11Encryption3Enabled:
-			if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
-				ext->alg = IW_ENCODE_ALG_TKIP;
-			else
-				ext->alg = IW_ENCODE_ALG_CCMP;
+	switch (pAd->StaCfg.WepStatus) {
+	case Ndis802_11WEPDisabled:
+		ext->alg = IW_ENCODE_ALG_NONE;
+		encoding->flags |= IW_ENCODE_DISABLED;
+		break;
+	case Ndis802_11WEPEnabled:
+		ext->alg = IW_ENCODE_ALG_WEP;
+		if (pAd->SharedKey[BSS0][idx].KeyLen > max_key_len)
+			return -E2BIG;
+		else {
+			ext->key_len = pAd->SharedKey[BSS0][idx].KeyLen;
+			pKey = (char *)& (pAd->SharedKey[BSS0][idx].Key[0]);
+		}
+		break;
+	case Ndis802_11Encryption2Enabled:
+	case Ndis802_11Encryption3Enabled:
+		if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
+			ext->alg = IW_ENCODE_ALG_TKIP;
+		else
+			ext->alg = IW_ENCODE_ALG_CCMP;
 
-			if (max_key_len < 32)
-				return -E2BIG;
-			else
-			{
-				ext->key_len = 32;
-				pKey = &pAd->StaCfg.PMK[0];
-			}
-			break;
-		default:
-			return -EINVAL;
+		if (max_key_len < 32)
+			return -E2BIG;
+		else {
+			ext->key_len = 32;
+			pKey = (char *)& pAd->StaCfg.PMK[0];
+		}
+		break;
+	default:
+		return -EINVAL;
 	}
 
-	if (ext->key_len && pKey)
-	{
+	if (ext->key_len && pKey) {
 		encoding->flags |= IW_ENCODE_ENABLED;
 		memcpy(ext->key, pKey, ext->key_len);
 	}
@@ -2332,22 +2093,25 @@
 }
 
 int rt_ioctl_siwgenie(struct net_device *dev,
-			  struct iw_request_info *info,
-			  union iwreq_data *wrqu, char *extra)
+		      struct iw_request_info *info,
+		      union iwreq_data *wrqu, char *extra)
 {
-	PRTMP_ADAPTER   pAd = dev->ml_priv;
+	struct rt_rtmp_adapter *pAd = NULL;
 
+	GET_PAD_FROM_NET_DEV(pAd, dev);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> rt_ioctl_siwgenie\n"));
+	pAd->StaCfg.bRSN_IE_FromWpaSupplicant = FALSE;
 	if (wrqu->data.length > MAX_LEN_OF_RSNIE ||
 	    (wrqu->data.length && extra == NULL))
 		return -EINVAL;
 
-	if (wrqu->data.length)
-	{
+	if (wrqu->data.length) {
 		pAd->StaCfg.RSNIE_Len = wrqu->data.length;
-		NdisMoveMemory(&pAd->StaCfg.RSN_IE[0], extra, pAd->StaCfg.RSNIE_Len);
-	}
-	else
-	{
+		NdisMoveMemory(&pAd->StaCfg.RSN_IE[0], extra,
+			       pAd->StaCfg.RSNIE_Len);
+		pAd->StaCfg.bRSN_IE_FromWpaSupplicant = TRUE;
+	} else {
 		pAd->StaCfg.RSNIE_Len = 0;
 		NdisZeroMemory(&pAd->StaCfg.RSN_IE[0], MAX_LEN_OF_RSNIE);
 	}
@@ -2356,182 +2120,213 @@
 }
 
 int rt_ioctl_giwgenie(struct net_device *dev,
-			       struct iw_request_info *info,
-			       union iwreq_data *wrqu, char *extra)
+		      struct iw_request_info *info,
+		      union iwreq_data *wrqu, char *extra)
 {
-	PRTMP_ADAPTER   pAd = dev->ml_priv;
+	struct rt_rtmp_adapter *pAd = NULL;
+
+	GET_PAD_FROM_NET_DEV(pAd, dev);
 
 	if ((pAd->StaCfg.RSNIE_Len == 0) ||
-		(pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA))
-	{
+	    (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)) {
 		wrqu->data.length = 0;
 		return 0;
 	}
 
-	if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
-	{
-	if (wrqu->data.length < pAd->StaCfg.RSNIE_Len)
-		return -E2BIG;
+	if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) {
+		if (wrqu->data.length < pAd->StaCfg.RSNIE_Len)
+			return -E2BIG;
 
-	wrqu->data.length = pAd->StaCfg.RSNIE_Len;
-	memcpy(extra, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
-	}
-	else
-	{
-		UCHAR RSNIe = IE_WPA;
+		wrqu->data.length = pAd->StaCfg.RSNIE_Len;
+		memcpy(extra, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
+	} else {
+		u8 RSNIe = IE_WPA;
 
-		if (wrqu->data.length < (pAd->StaCfg.RSNIE_Len + 2)) // ID, Len
+		if (wrqu->data.length < (pAd->StaCfg.RSNIE_Len + 2))	/* ID, Len */
 			return -E2BIG;
 		wrqu->data.length = pAd->StaCfg.RSNIE_Len + 2;
 
 		if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
-            (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
+		    (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
 			RSNIe = IE_RSN;
 
 		extra[0] = (char)RSNIe;
 		extra[1] = pAd->StaCfg.RSNIE_Len;
-		memcpy(extra+2, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
+		memcpy(extra + 2, &pAd->StaCfg.RSN_IE[0],
+		       pAd->StaCfg.RSNIE_Len);
 	}
 
 	return 0;
 }
 
 int rt_ioctl_siwpmksa(struct net_device *dev,
-			   struct iw_request_info *info,
-			   union iwreq_data *wrqu,
-			   char *extra)
+		      struct iw_request_info *info,
+		      union iwreq_data *wrqu, char *extra)
 {
-	PRTMP_ADAPTER   pAd = dev->ml_priv;
+	struct rt_rtmp_adapter *pAd = NULL;
 	struct iw_pmksa *pPmksa = (struct iw_pmksa *)wrqu->data.pointer;
-	INT	CachedIdx = 0, idx = 0;
+	int CachedIdx = 0, idx = 0;
+
+	GET_PAD_FROM_NET_DEV(pAd, dev);
 
 	if (pPmksa == NULL)
 		return -EINVAL;
 
-	DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_siwpmksa\n"));
-	switch(pPmksa->cmd)
-	{
-		case IW_PMKSA_FLUSH:
-			NdisZeroMemory(pAd->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
-			DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_FLUSH\n"));
-			break;
-		case IW_PMKSA_REMOVE:
-			for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
-			{
-		        // compare the BSSID
-		        if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
-		        {
-		        	NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN);
-					NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].PMKID, 16);
-					for (idx = CachedIdx; idx < (pAd->StaCfg.SavedPMKNum - 1); idx++)
-					{
-						NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].BSSID[0], &pAd->StaCfg.SavedPMK[idx+1].BSSID[0], MAC_ADDR_LEN);
-						NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].PMKID[0], &pAd->StaCfg.SavedPMK[idx+1].PMKID[0], 16);
-					}
-					pAd->StaCfg.SavedPMKNum--;
-			        break;
-		        }
-	        }
+	DBGPRINT(RT_DEBUG_TRACE, ("===> rt_ioctl_siwpmksa\n"));
+	switch (pPmksa->cmd) {
+	case IW_PMKSA_FLUSH:
+		NdisZeroMemory(pAd->StaCfg.SavedPMK,
+			       sizeof(struct rt_bssid_info) * PMKID_NO);
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("rt_ioctl_siwpmksa - IW_PMKSA_FLUSH\n"));
+		break;
+	case IW_PMKSA_REMOVE:
+		for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum;
+		     CachedIdx++) {
+			/* compare the BSSID */
+			if (NdisEqualMemory
+			    (pPmksa->bssid.sa_data,
+			     pAd->StaCfg.SavedPMK[CachedIdx].BSSID,
+			     MAC_ADDR_LEN)) {
+				NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].
+					       BSSID, MAC_ADDR_LEN);
+				NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].
+					       PMKID, 16);
+				for (idx = CachedIdx;
+				     idx < (pAd->StaCfg.SavedPMKNum - 1);
+				     idx++) {
+					NdisMoveMemory(&pAd->StaCfg.
+						       SavedPMK[idx].BSSID[0],
+						       &pAd->StaCfg.
+						       SavedPMK[idx +
+								1].BSSID[0],
+						       MAC_ADDR_LEN);
+					NdisMoveMemory(&pAd->StaCfg.
+						       SavedPMK[idx].PMKID[0],
+						       &pAd->StaCfg.
+						       SavedPMK[idx +
+								1].PMKID[0],
+						       16);
+				}
+				pAd->StaCfg.SavedPMKNum--;
+				break;
+			}
+		}
 
-			DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_REMOVE\n"));
-			break;
-		case IW_PMKSA_ADD:
-			for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
-			{
-		        // compare the BSSID
-		        if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
-			        break;
-	        }
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("rt_ioctl_siwpmksa - IW_PMKSA_REMOVE\n"));
+		break;
+	case IW_PMKSA_ADD:
+		for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum;
+		     CachedIdx++) {
+			/* compare the BSSID */
+			if (NdisEqualMemory
+			    (pPmksa->bssid.sa_data,
+			     pAd->StaCfg.SavedPMK[CachedIdx].BSSID,
+			     MAC_ADDR_LEN))
+				break;
+		}
 
-	        // Found, replace it
-	        if (CachedIdx < PMKID_NO)
-	        {
-		        DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
-		        NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
-				NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
-		        pAd->StaCfg.SavedPMKNum++;
-	        }
-	        // Not found, replace the last one
-	        else
-	        {
-		        // Randomly replace one
-		        CachedIdx = (pPmksa->bssid.sa_data[5] % PMKID_NO);
-		        DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
-		        NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
-				NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
-	        }
+		/* Found, replace it */
+		if (CachedIdx < PMKID_NO) {
+			DBGPRINT(RT_DEBUG_OFF,
+				 ("Update PMKID, idx = %d\n", CachedIdx));
+			NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].
+				       BSSID[0], pPmksa->bssid.sa_data,
+				       MAC_ADDR_LEN);
+			NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].
+				       PMKID[0], pPmksa->pmkid, 16);
+			pAd->StaCfg.SavedPMKNum++;
+		}
+		/* Not found, replace the last one */
+		else {
+			/* Randomly replace one */
+			CachedIdx = (pPmksa->bssid.sa_data[5] % PMKID_NO);
+			DBGPRINT(RT_DEBUG_OFF,
+				 ("Update PMKID, idx = %d\n", CachedIdx));
+			NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].
+				       BSSID[0], pPmksa->bssid.sa_data,
+				       MAC_ADDR_LEN);
+			NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].
+				       PMKID[0], pPmksa->pmkid, 16);
+		}
 
-			DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_ADD\n"));
-			break;
-		default:
-			DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - Unknow Command!!\n"));
-			break;
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("rt_ioctl_siwpmksa - IW_PMKSA_ADD\n"));
+		break;
+	default:
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("rt_ioctl_siwpmksa - Unknown Command!\n"));
+		break;
 	}
 
 	return 0;
 }
 
 int rt_ioctl_siwrate(struct net_device *dev,
-			struct iw_request_info *info,
-			union iwreq_data *wrqu, char *extra)
+		     struct iw_request_info *info,
+		     union iwreq_data *wrqu, char *extra)
 {
-    PRTMP_ADAPTER   pAd = dev->ml_priv;
-    UINT32          rate = wrqu->bitrate.value, fixed = wrqu->bitrate.fixed;
+	struct rt_rtmp_adapter *pAd = NULL;
+	u32 rate = wrqu->bitrate.value, fixed = wrqu->bitrate.fixed;
 
-    //check if the interface is down
-	if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
-  		DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::Network is down!\n"));
-    	return -ENETDOWN;
+	GET_PAD_FROM_NET_DEV(pAd, dev);
+
+	/*check if the interface is down */
+	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("rt_ioctl_siwrate::Network is down!\n"));
+		return -ENETDOWN;
 	}
 
-    DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(rate = %d, fixed = %d)\n", rate, fixed));
-    /* rate = -1 => auto rate
-       rate = X, fixed = 1 => (fixed rate X)
-    */
-    if (rate == -1)
-    {
-		//Auto Rate
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("rt_ioctl_siwrate::(rate = %d, fixed = %d)\n", rate, fixed));
+	/* rate = -1 => auto rate
+	   rate = X, fixed = 1 => (fixed rate X)
+	 */
+	if (rate == -1) {
+		/*Auto Rate */
 		pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
 		pAd->StaCfg.bAutoTxRateSwitch = TRUE;
 		if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
-		    (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
+		    (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <=
+		     MODE_OFDM))
 			RTMPSetDesiredRates(pAd, -1);
 
 		SetCommonHT(pAd);
-    }
-    else
-    {
-        if (fixed)
-        {
-        	pAd->StaCfg.bAutoTxRateSwitch = FALSE;
-            if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
-                (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
-                RTMPSetDesiredRates(pAd, rate);
-            else
-            {
-                pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
-                SetCommonHT(pAd);
-            }
-            DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(HtMcs=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.MCS));
-        }
-        else
-        {
-            // TODO: rate = X, fixed = 0 => (rates <= X)
-            return -EOPNOTSUPP;
-        }
-    }
+	} else {
+		if (fixed) {
+			pAd->StaCfg.bAutoTxRateSwitch = FALSE;
+			if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
+			    (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.
+			     MODE <= MODE_OFDM))
+				RTMPSetDesiredRates(pAd, rate);
+			else {
+				pAd->StaCfg.DesiredTransmitSetting.field.MCS =
+				    MCS_AUTO;
+				SetCommonHT(pAd);
+			}
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("rt_ioctl_siwrate::(HtMcs=%d)\n",
+				  pAd->StaCfg.DesiredTransmitSetting.field.
+				  MCS));
+		} else {
+			/* TODO: rate = X, fixed = 0 => (rates <= X) */
+			return -EOPNOTSUPP;
+		}
+	}
 
-    return 0;
+	return 0;
 }
 
 int rt_ioctl_giwrate(struct net_device *dev,
-			       struct iw_request_info *info,
-			       union iwreq_data *wrqu, char *extra)
+		     struct iw_request_info *info,
+		     union iwreq_data *wrqu, char *extra)
 {
-    PRTMP_ADAPTER   pAd = dev->ml_priv;
-    int rate_index = 0, rate_count = 0;
-    HTTRANSMIT_SETTING ht_setting;
+	struct rt_rtmp_adapter *pAd = NULL;
+	int rate_index = 0, rate_count = 0;
+	HTTRANSMIT_SETTING ht_setting;
+/* Remove to global variable
     __s32 ralinkrate[] =
 	{2,  4,   11,  22, // CCK
 	12, 18,   24,  36, 48, 72, 96, 108, // OFDM
@@ -2543,329 +2338,295 @@
 	43, 87,  130, 173, 260, 317, 390, 433,										  // 20MHz, 400ns GI, MCS: 16 ~ 23
 	30, 60,   90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, // 40MHz, 400ns GI, MCS: 0 ~ 15
 	90, 180, 270, 360, 540, 720, 810, 900};										  // 40MHz, 400ns GI, MCS: 16 ~ 23
+*/
+	GET_PAD_FROM_NET_DEV(pAd, dev);
 
-    rate_count = sizeof(ralinkrate)/sizeof(__s32);
-    //check if the interface is down
-	if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
-  		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-    	return -ENETDOWN;
+	rate_count = sizeof(ralinkrate) / sizeof(__s32);
+	/*check if the interface is down */
+	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
+		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+		return -ENETDOWN;
 	}
 
-    if ((pAd->StaCfg.bAutoTxRateSwitch == FALSE) &&
-        (INFRA_ON(pAd)) &&
-        ((pAd->CommonCfg.PhyMode <= PHY_11G) || (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM)))
-        ht_setting.word = pAd->StaCfg.HTPhyMode.word;
-    else
-        ht_setting.word = pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word;
+	if ((pAd->StaCfg.bAutoTxRateSwitch == FALSE) &&
+	    (INFRA_ON(pAd)) &&
+	    ((pAd->CommonCfg.PhyMode <= PHY_11G)
+	     || (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <=
+		 MODE_OFDM)))
+		ht_setting.word = pAd->StaCfg.HTPhyMode.word;
+	else
+		ht_setting.word =
+		    pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word;
 
-    if (ht_setting.field.MODE >= MODE_HTMIX)
-    {
-    	rate_index = 12 + ((UCHAR)ht_setting.field.BW *24) + ((UCHAR)ht_setting.field.ShortGI *48) + ((UCHAR)ht_setting.field.MCS);
-    }
-    else
-    if (ht_setting.field.MODE == MODE_OFDM)
-    	rate_index = (UCHAR)(ht_setting.field.MCS) + 4;
-    else if (ht_setting.field.MODE == MODE_CCK)
-    	rate_index = (UCHAR)(ht_setting.field.MCS);
+	if (ht_setting.field.MODE >= MODE_HTMIX) {
+/*      rate_index = 12 + ((u8)ht_setting.field.BW *16) + ((u8)ht_setting.field.ShortGI *32) + ((u8)ht_setting.field.MCS); */
+		rate_index =
+		    12 + ((u8)ht_setting.field.BW * 24) +
+		    ((u8)ht_setting.field.ShortGI * 48) +
+		    ((u8)ht_setting.field.MCS);
+	} else if (ht_setting.field.MODE == MODE_OFDM)
+		rate_index = (u8)(ht_setting.field.MCS) + 4;
+	else if (ht_setting.field.MODE == MODE_CCK)
+		rate_index = (u8)(ht_setting.field.MCS);
 
-    if (rate_index < 0)
-        rate_index = 0;
+	if (rate_index < 0)
+		rate_index = 0;
 
-    if (rate_index > rate_count)
-        rate_index = rate_count;
+	if (rate_index > rate_count)
+		rate_index = rate_count;
 
-    wrqu->bitrate.value = ralinkrate[rate_index] * 500000;
-    wrqu->bitrate.disabled = 0;
+	wrqu->bitrate.value = ralinkrate[rate_index] * 500000;
+	wrqu->bitrate.disabled = 0;
 
-    return 0;
+	return 0;
 }
 
-static const iw_handler rt_handler[] =
-{
-	(iw_handler) NULL,			            /* SIOCSIWCOMMIT */
-	(iw_handler) rt_ioctl_giwname,			/* SIOCGIWNAME   */
-	(iw_handler) NULL,			            /* SIOCSIWNWID   */
-	(iw_handler) NULL,			            /* SIOCGIWNWID   */
-	(iw_handler) rt_ioctl_siwfreq,		    /* SIOCSIWFREQ   */
-	(iw_handler) rt_ioctl_giwfreq,		    /* SIOCGIWFREQ   */
-	(iw_handler) rt_ioctl_siwmode,		    /* SIOCSIWMODE   */
-	(iw_handler) rt_ioctl_giwmode,		    /* SIOCGIWMODE   */
-	(iw_handler) NULL,		                /* SIOCSIWSENS   */
-	(iw_handler) NULL,		                /* SIOCGIWSENS   */
-	(iw_handler) NULL /* not used */,		/* SIOCSIWRANGE  */
-	(iw_handler) rt_ioctl_giwrange,		    /* SIOCGIWRANGE  */
-	(iw_handler) NULL /* not used */,		/* SIOCSIWPRIV   */
-	(iw_handler) NULL /* kernel code */,    /* SIOCGIWPRIV   */
-	(iw_handler) NULL /* not used */,		/* SIOCSIWSTATS  */
-	(iw_handler) rt28xx_get_wireless_stats /* kernel code */,    /* SIOCGIWSTATS  */
-	(iw_handler) NULL,		                /* SIOCSIWSPY    */
-	(iw_handler) NULL,		                /* SIOCGIWSPY    */
-	(iw_handler) NULL,				        /* SIOCSIWTHRSPY */
-	(iw_handler) NULL,				        /* SIOCGIWTHRSPY */
-	(iw_handler) rt_ioctl_siwap,            /* SIOCSIWAP     */
-	(iw_handler) rt_ioctl_giwap,		    /* SIOCGIWAP     */
-	(iw_handler) rt_ioctl_siwmlme,	        /* SIOCSIWMLME   */
-	(iw_handler) rt_ioctl_iwaplist,		    /* SIOCGIWAPLIST */
-	(iw_handler) rt_ioctl_siwscan,		    /* SIOCSIWSCAN   */
-	(iw_handler) rt_ioctl_giwscan,		    /* SIOCGIWSCAN   */
-	(iw_handler) rt_ioctl_siwessid,		    /* SIOCSIWESSID  */
-	(iw_handler) rt_ioctl_giwessid,		    /* SIOCGIWESSID  */
-	(iw_handler) rt_ioctl_siwnickn,		    /* SIOCSIWNICKN  */
-	(iw_handler) rt_ioctl_giwnickn,		    /* SIOCGIWNICKN  */
-	(iw_handler) NULL,				        /* -- hole --    */
-	(iw_handler) NULL,				        /* -- hole --    */
-	(iw_handler) rt_ioctl_siwrate,          /* SIOCSIWRATE   */
-	(iw_handler) rt_ioctl_giwrate,          /* SIOCGIWRATE   */
-	(iw_handler) rt_ioctl_siwrts,		    /* SIOCSIWRTS    */
-	(iw_handler) rt_ioctl_giwrts,		    /* SIOCGIWRTS    */
-	(iw_handler) rt_ioctl_siwfrag,		    /* SIOCSIWFRAG   */
-	(iw_handler) rt_ioctl_giwfrag,		    /* SIOCGIWFRAG   */
-	(iw_handler) NULL,		                /* SIOCSIWTXPOW  */
-	(iw_handler) NULL,		                /* SIOCGIWTXPOW  */
-	(iw_handler) NULL,		                /* SIOCSIWRETRY  */
-	(iw_handler) NULL,		                /* SIOCGIWRETRY  */
-	(iw_handler) rt_ioctl_siwencode,		/* SIOCSIWENCODE */
-	(iw_handler) rt_ioctl_giwencode,		/* SIOCGIWENCODE */
-	(iw_handler) NULL,		                /* SIOCSIWPOWER  */
-	(iw_handler) NULL,		                /* SIOCGIWPOWER  */
-	(iw_handler) NULL,						/* -- hole -- */
-	(iw_handler) NULL,						/* -- hole -- */
-    (iw_handler) rt_ioctl_siwgenie,         /* SIOCSIWGENIE  */
-	(iw_handler) rt_ioctl_giwgenie,         /* SIOCGIWGENIE  */
-	(iw_handler) rt_ioctl_siwauth,		    /* SIOCSIWAUTH   */
-	(iw_handler) rt_ioctl_giwauth,		    /* SIOCGIWAUTH   */
-	(iw_handler) rt_ioctl_siwencodeext,	    /* SIOCSIWENCODEEXT */
-	(iw_handler) rt_ioctl_giwencodeext,		/* SIOCGIWENCODEEXT */
-	(iw_handler) rt_ioctl_siwpmksa,         /* SIOCSIWPMKSA  */
+static const iw_handler rt_handler[] = {
+	(iw_handler) NULL,	/* SIOCSIWCOMMIT */
+	(iw_handler) rt_ioctl_giwname,	/* SIOCGIWNAME   */
+	(iw_handler) NULL,	/* SIOCSIWNWID   */
+	(iw_handler) NULL,	/* SIOCGIWNWID   */
+	(iw_handler) rt_ioctl_siwfreq,	/* SIOCSIWFREQ   */
+	(iw_handler) rt_ioctl_giwfreq,	/* SIOCGIWFREQ   */
+	(iw_handler) rt_ioctl_siwmode,	/* SIOCSIWMODE   */
+	(iw_handler) rt_ioctl_giwmode,	/* SIOCGIWMODE   */
+	(iw_handler) NULL,	/* SIOCSIWSENS   */
+	(iw_handler) NULL,	/* SIOCGIWSENS   */
+	(iw_handler) NULL /* not used */ ,	/* SIOCSIWRANGE  */
+	(iw_handler) rt_ioctl_giwrange,	/* SIOCGIWRANGE  */
+	(iw_handler) NULL /* not used */ ,	/* SIOCSIWPRIV   */
+	(iw_handler) NULL /* kernel code */ ,	/* SIOCGIWPRIV   */
+	(iw_handler) NULL /* not used */ ,	/* SIOCSIWSTATS  */
+	(iw_handler) rt28xx_get_wireless_stats /* kernel code */ ,	/* SIOCGIWSTATS  */
+	(iw_handler) NULL,	/* SIOCSIWSPY    */
+	(iw_handler) NULL,	/* SIOCGIWSPY    */
+	(iw_handler) NULL,	/* SIOCSIWTHRSPY */
+	(iw_handler) NULL,	/* SIOCGIWTHRSPY */
+	(iw_handler) rt_ioctl_siwap,	/* SIOCSIWAP     */
+	(iw_handler) rt_ioctl_giwap,	/* SIOCGIWAP     */
+	(iw_handler) rt_ioctl_siwmlme,	/* SIOCSIWMLME   */
+	(iw_handler) rt_ioctl_iwaplist,	/* SIOCGIWAPLIST */
+	(iw_handler) rt_ioctl_siwscan,	/* SIOCSIWSCAN   */
+	(iw_handler) rt_ioctl_giwscan,	/* SIOCGIWSCAN   */
+	(iw_handler) rt_ioctl_siwessid,	/* SIOCSIWESSID  */
+	(iw_handler) rt_ioctl_giwessid,	/* SIOCGIWESSID  */
+	(iw_handler) rt_ioctl_siwnickn,	/* SIOCSIWNICKN  */
+	(iw_handler) rt_ioctl_giwnickn,	/* SIOCGIWNICKN  */
+	(iw_handler) NULL,	/* -- hole --    */
+	(iw_handler) NULL,	/* -- hole --    */
+	(iw_handler) rt_ioctl_siwrate,	/* SIOCSIWRATE   */
+	(iw_handler) rt_ioctl_giwrate,	/* SIOCGIWRATE   */
+	(iw_handler) rt_ioctl_siwrts,	/* SIOCSIWRTS    */
+	(iw_handler) rt_ioctl_giwrts,	/* SIOCGIWRTS    */
+	(iw_handler) rt_ioctl_siwfrag,	/* SIOCSIWFRAG   */
+	(iw_handler) rt_ioctl_giwfrag,	/* SIOCGIWFRAG   */
+	(iw_handler) NULL,	/* SIOCSIWTXPOW  */
+	(iw_handler) NULL,	/* SIOCGIWTXPOW  */
+	(iw_handler) NULL,	/* SIOCSIWRETRY  */
+	(iw_handler) NULL,	/* SIOCGIWRETRY  */
+	(iw_handler) rt_ioctl_siwencode,	/* SIOCSIWENCODE */
+	(iw_handler) rt_ioctl_giwencode,	/* SIOCGIWENCODE */
+	(iw_handler) NULL,	/* SIOCSIWPOWER  */
+	(iw_handler) NULL,	/* SIOCGIWPOWER  */
+	(iw_handler) NULL,	/* -- hole -- */
+	(iw_handler) NULL,	/* -- hole -- */
+	(iw_handler) rt_ioctl_siwgenie,	/* SIOCSIWGENIE  */
+	(iw_handler) rt_ioctl_giwgenie,	/* SIOCGIWGENIE  */
+	(iw_handler) rt_ioctl_siwauth,	/* SIOCSIWAUTH   */
+	(iw_handler) rt_ioctl_giwauth,	/* SIOCGIWAUTH   */
+	(iw_handler) rt_ioctl_siwencodeext,	/* SIOCSIWENCODEEXT */
+	(iw_handler) rt_ioctl_giwencodeext,	/* SIOCGIWENCODEEXT */
+	(iw_handler) rt_ioctl_siwpmksa,	/* SIOCSIWPMKSA  */
 };
 
-static const iw_handler rt_priv_handlers[] = {
-	(iw_handler) NULL, /* + 0x00 */
-	(iw_handler) NULL, /* + 0x01 */
-	(iw_handler) rt_ioctl_setparam, /* + 0x02 */
-	(iw_handler) NULL, /* + 0x03 */
-	(iw_handler) NULL, /* + 0x04 */
-	(iw_handler) NULL, /* + 0x05 */
-	(iw_handler) NULL, /* + 0x06 */
-	(iw_handler) NULL, /* + 0x07 */
-	(iw_handler) NULL, /* + 0x08 */
-	(iw_handler) rt_private_get_statistics, /* + 0x09 */
-	(iw_handler) NULL, /* + 0x0A */
-	(iw_handler) NULL, /* + 0x0B */
-	(iw_handler) NULL, /* + 0x0C */
-	(iw_handler) NULL, /* + 0x0D */
-	(iw_handler) NULL, /* + 0x0E */
-	(iw_handler) NULL, /* + 0x0F */
-	(iw_handler) NULL, /* + 0x10 */
-	(iw_handler) rt_private_show, /* + 0x11 */
-    (iw_handler) NULL, /* + 0x12 */
-	(iw_handler) NULL, /* + 0x13 */
-	(iw_handler) NULL, /* + 0x15 */
-	(iw_handler) NULL, /* + 0x17 */
-	(iw_handler) NULL, /* + 0x18 */
-};
-
-const struct iw_handler_def rt28xx_iw_handler_def =
-{
-#define	N(a)	(sizeof (a) / sizeof (a[0]))
-	.standard	= (iw_handler *) rt_handler,
-	.num_standard	= sizeof(rt_handler) / sizeof(iw_handler),
-	.private	= (iw_handler *) rt_priv_handlers,
-	.num_private		= N(rt_priv_handlers),
-	.private_args	= (struct iw_priv_args *) privtab,
-	.num_private_args	= N(privtab),
+const struct iw_handler_def rt28xx_iw_handler_def = {
+	.standard = (iw_handler *) rt_handler,
+	.num_standard = sizeof(rt_handler) / sizeof(iw_handler),
 #if IW_HANDLER_VERSION >= 7
-    .get_wireless_stats = rt28xx_get_wireless_stats,
+	.get_wireless_stats = rt28xx_get_wireless_stats,
 #endif
 };
 
-INT rt28xx_sta_ioctl(
-	IN	struct net_device	*net_dev,
-	IN	OUT	struct ifreq	*rq,
-	IN	INT					cmd)
+int rt28xx_sta_ioctl(IN struct net_device *net_dev,
+		     IN OUT struct ifreq *rq, int cmd)
 {
-	RTMP_ADAPTER *pAd = net_dev->ml_priv;
-	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
-	struct iwreq        *wrq = (struct iwreq *) rq;
-	BOOLEAN				StateMachineTouched = FALSE;
-	INT					Status = NDIS_STATUS_SUCCESS;
+	struct os_cookie *pObj;
+	struct rt_rtmp_adapter *pAd = NULL;
+	struct iwreq *wrq = (struct iwreq *)rq;
+	BOOLEAN StateMachineTouched = FALSE;
+	int Status = NDIS_STATUS_SUCCESS;
 
-    //check if the interface is down
-    if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-    {
-        {
-            DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		    return -ENETDOWN;
-        }
-    }
+	GET_PAD_FROM_NET_DEV(pAd, net_dev);
 
-	{	// determine this ioctl command is comming from which interface.
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
+
+	/*check if the interface is down */
+	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+			return -ENETDOWN;
+		}
+	}
+
+	{			/* determine this ioctl command is comming from which interface. */
 		pObj->ioctl_if_type = INT_MAIN;
 		pObj->ioctl_if = MAIN_MBSSID;
 	}
 
-	switch(cmd)
-	{
-        case SIOCGIFHWADDR:
-			DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIFHWADDR\n"));
-			memcpy(wrq->u.name, pAd->CurrentAddress, ETH_ALEN);
-			break;
-		case SIOCGIWNAME:
-        {
-        	char *name=&wrq->u.name[0];
-        	rt_ioctl_giwname(net_dev, NULL, name, NULL);
+	switch (cmd) {
+	case SIOCGIFHWADDR:
+		DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIFHWADDR\n"));
+		memcpy(wrq->u.name, pAd->CurrentAddress, ETH_ALEN);
+		break;
+	case SIOCGIWNAME:
+		{
+			char *name = &wrq->u.name[0];
+			rt_ioctl_giwname(net_dev, NULL, name, NULL);
 			break;
 		}
-		case SIOCGIWESSID:  //Get ESSID
-        {
-        	struct iw_point *essid=&wrq->u.essid;
-        	rt_ioctl_giwessid(net_dev, NULL, essid, essid->pointer);
+	case SIOCGIWESSID:	/*Get ESSID */
+		{
+			struct iw_point *essid = &wrq->u.essid;
+			rt_ioctl_giwessid(net_dev, NULL, essid, essid->pointer);
 			break;
 		}
-		case SIOCSIWESSID:  //Set ESSID
-        {
-        	struct iw_point	*essid=&wrq->u.essid;
-        	rt_ioctl_siwessid(net_dev, NULL, essid, essid->pointer);
+	case SIOCSIWESSID:	/*Set ESSID */
+		{
+			struct iw_point *essid = &wrq->u.essid;
+			rt_ioctl_siwessid(net_dev, NULL, essid, essid->pointer);
 			break;
 		}
-		case SIOCSIWNWID:   // set network id (the cell)
-		case SIOCGIWNWID:   // get network id
-			Status = -EOPNOTSUPP;
-			break;
-		case SIOCSIWFREQ:   //set channel/frequency (Hz)
-        {
-        	struct iw_freq *freq=&wrq->u.freq;
-        	rt_ioctl_siwfreq(net_dev, NULL, freq, NULL);
+	case SIOCSIWNWID:	/* set network id (the cell) */
+	case SIOCGIWNWID:	/* get network id */
+		Status = -EOPNOTSUPP;
+		break;
+	case SIOCSIWFREQ:	/*set channel/frequency (Hz) */
+		{
+			struct iw_freq *freq = &wrq->u.freq;
+			rt_ioctl_siwfreq(net_dev, NULL, freq, NULL);
 			break;
 		}
-		case SIOCGIWFREQ:   // get channel/frequency (Hz)
-        {
-        	struct iw_freq *freq=&wrq->u.freq;
-        	rt_ioctl_giwfreq(net_dev, NULL, freq, NULL);
+	case SIOCGIWFREQ:	/* get channel/frequency (Hz) */
+		{
+			struct iw_freq *freq = &wrq->u.freq;
+			rt_ioctl_giwfreq(net_dev, NULL, freq, NULL);
 			break;
 		}
-		case SIOCSIWNICKN: //set node name/nickname
-        {
-        	struct iw_point *data=&wrq->u.data;
-        	rt_ioctl_siwnickn(net_dev, NULL, data, NULL);
+	case SIOCSIWNICKN:	/*set node name/nickname */
+		{
+			/*struct iw_point *data=&wrq->u.data; */
+			/*rt_ioctl_siwnickn(net_dev, NULL, data, NULL); */
 			break;
 		}
-		case SIOCGIWNICKN: //get node name/nickname
-        {
-        	struct iw_point *data=&wrq->u.data;
-        	rt_ioctl_giwnickn(net_dev, NULL, data, NULL);
+	case SIOCGIWNICKN:	/*get node name/nickname */
+		{
+			struct iw_point *erq = NULL;
+			erq = &wrq->u.data;
+			erq->length = strlen((char *)pAd->nickname);
+			Status =
+			    copy_to_user(erq->pointer, pAd->nickname,
+					 erq->length);
 			break;
 		}
-		case SIOCGIWRATE:   //get default bit rate (bps)
-		    rt_ioctl_giwrate(net_dev, NULL, &wrq->u, NULL);
-            break;
-	    case SIOCSIWRATE:  //set default bit rate (bps)
-	        rt_ioctl_siwrate(net_dev, NULL, &wrq->u, NULL);
-            break;
-        case SIOCGIWRTS:  // get RTS/CTS threshold (bytes)
-        {
-        	struct iw_param *rts=&wrq->u.rts;
-        	rt_ioctl_giwrts(net_dev, NULL, rts, NULL);
+	case SIOCGIWRATE:	/*get default bit rate (bps) */
+		rt_ioctl_giwrate(net_dev, NULL, &wrq->u, NULL);
+		break;
+	case SIOCSIWRATE:	/*set default bit rate (bps) */
+		rt_ioctl_siwrate(net_dev, NULL, &wrq->u, NULL);
+		break;
+	case SIOCGIWRTS:	/* get RTS/CTS threshold (bytes) */
+		{
+			struct iw_param *rts = &wrq->u.rts;
+			rt_ioctl_giwrts(net_dev, NULL, rts, NULL);
 			break;
 		}
-        case SIOCSIWRTS:  //set RTS/CTS threshold (bytes)
-        {
-        	struct iw_param *rts=&wrq->u.rts;
-        	rt_ioctl_siwrts(net_dev, NULL, rts, NULL);
+	case SIOCSIWRTS:	/*set RTS/CTS threshold (bytes) */
+		{
+			struct iw_param *rts = &wrq->u.rts;
+			rt_ioctl_siwrts(net_dev, NULL, rts, NULL);
 			break;
 		}
-        case SIOCGIWFRAG:  //get fragmentation thr (bytes)
-        {
-        	struct iw_param *frag=&wrq->u.frag;
-        	rt_ioctl_giwfrag(net_dev, NULL, frag, NULL);
+	case SIOCGIWFRAG:	/*get fragmentation thr (bytes) */
+		{
+			struct iw_param *frag = &wrq->u.frag;
+			rt_ioctl_giwfrag(net_dev, NULL, frag, NULL);
 			break;
 		}
-        case SIOCSIWFRAG:  //set fragmentation thr (bytes)
-        {
-        	struct iw_param *frag=&wrq->u.frag;
-        	rt_ioctl_siwfrag(net_dev, NULL, frag, NULL);
+	case SIOCSIWFRAG:	/*set fragmentation thr (bytes) */
+		{
+			struct iw_param *frag = &wrq->u.frag;
+			rt_ioctl_siwfrag(net_dev, NULL, frag, NULL);
 			break;
 		}
-        case SIOCGIWENCODE:  //get encoding token & mode
-        {
-        	struct iw_point *erq=&wrq->u.encoding;
-        	if(erq->pointer)
-        		rt_ioctl_giwencode(net_dev, NULL, erq, erq->pointer);
+	case SIOCGIWENCODE:	/*get encoding token & mode */
+		{
+			struct iw_point *erq = &wrq->u.encoding;
+			if (erq)
+				rt_ioctl_giwencode(net_dev, NULL, erq,
+						   erq->pointer);
 			break;
 		}
-        case SIOCSIWENCODE:  //set encoding token & mode
-        {
-        	struct iw_point *erq=&wrq->u.encoding;
-        	if(erq->pointer)
-        		rt_ioctl_siwencode(net_dev, NULL, erq, erq->pointer);
+	case SIOCSIWENCODE:	/*set encoding token & mode */
+		{
+			struct iw_point *erq = &wrq->u.encoding;
+			if (erq)
+				rt_ioctl_siwencode(net_dev, NULL, erq,
+						   erq->pointer);
 			break;
 		}
-		case SIOCGIWAP:     //get access point MAC addresses
-        {
-        	struct sockaddr *ap_addr=&wrq->u.ap_addr;
-        	rt_ioctl_giwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
+	case SIOCGIWAP:	/*get access point MAC addresses */
+		{
+			struct sockaddr *ap_addr = &wrq->u.ap_addr;
+			rt_ioctl_giwap(net_dev, NULL, ap_addr,
+				       ap_addr->sa_data);
 			break;
 		}
-	    case SIOCSIWAP:  //set access point MAC addresses
-        {
-        	struct sockaddr *ap_addr=&wrq->u.ap_addr;
-        	rt_ioctl_siwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
+	case SIOCSIWAP:	/*set access point MAC addresses */
+		{
+			struct sockaddr *ap_addr = &wrq->u.ap_addr;
+			rt_ioctl_siwap(net_dev, NULL, ap_addr,
+				       ap_addr->sa_data);
 			break;
 		}
-		case SIOCGIWMODE:   //get operation mode
-        {
-        	__u32 *mode=&wrq->u.mode;
-        	rt_ioctl_giwmode(net_dev, NULL, mode, NULL);
+	case SIOCGIWMODE:	/*get operation mode */
+		{
+			__u32 *mode = &wrq->u.mode;
+			rt_ioctl_giwmode(net_dev, NULL, mode, NULL);
 			break;
 		}
-		case SIOCSIWMODE:   //set operation mode
-        {
-        	__u32 *mode=&wrq->u.mode;
-        	rt_ioctl_siwmode(net_dev, NULL, mode, NULL);
+	case SIOCSIWMODE:	/*set operation mode */
+		{
+			__u32 *mode = &wrq->u.mode;
+			rt_ioctl_siwmode(net_dev, NULL, mode, NULL);
 			break;
 		}
-		case SIOCGIWSENS:   //get sensitivity (dBm)
-		case SIOCSIWSENS:	//set sensitivity (dBm)
-		case SIOCGIWPOWER:  //get Power Management settings
-		case SIOCSIWPOWER:  //set Power Management settings
-		case SIOCGIWTXPOW:  //get transmit power (dBm)
-		case SIOCSIWTXPOW:  //set transmit power (dBm)
-		case SIOCGIWRANGE:	//Get range of parameters
-		case SIOCGIWRETRY:	//get retry limits and lifetime
-		case SIOCSIWRETRY:	//set retry limits and lifetime
-		case RT_PRIV_IOCTL:
-		case RT_PRIV_IOCTL_EXT:
-			Status = -EOPNOTSUPP;
-			break;
-		case SIOCGIWPRIV:
-			if (wrq->u.data.pointer)
-			{
-				if ( access_ok(VERIFY_WRITE, wrq->u.data.pointer, sizeof(privtab)) != TRUE)
-					break;
-				wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
-				if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
-					Status = -EFAULT;
-			}
-			break;
-		case RTPRIV_IOCTL_SET:
-			if(access_ok(VERIFY_READ, wrq->u.data.pointer, wrq->u.data.length) != TRUE)
-				break;
-			rt_ioctl_setparam(net_dev, NULL, NULL, wrq->u.data.pointer);
-			break;
-		case RTPRIV_IOCTL_GSITESURVEY:
-			RTMPIoctlGetSiteSurvey(pAd, wrq);
-		    break;
-        case SIOCETHTOOL:
-                break;
-		default:
-			DBGPRINT(RT_DEBUG_ERROR, ("IOCTL::unknown IOCTL's cmd = 0x%08x\n", cmd));
-			Status = -EOPNOTSUPP;
-			break;
+	case SIOCGIWSENS:	/*get sensitivity (dBm) */
+	case SIOCSIWSENS:	/*set sensitivity (dBm) */
+	case SIOCGIWPOWER:	/*get Power Management settings */
+	case SIOCSIWPOWER:	/*set Power Management settings */
+	case SIOCGIWTXPOW:	/*get transmit power (dBm) */
+	case SIOCSIWTXPOW:	/*set transmit power (dBm) */
+	case SIOCGIWRANGE:	/*Get range of parameters */
+	case SIOCGIWRETRY:	/*get retry limits and lifetime */
+	case SIOCSIWRETRY:	/*set retry limits and lifetime */
+	case RT_PRIV_IOCTL:
+	case RT_PRIV_IOCTL_EXT:
+	case RTPRIV_IOCTL_SET:
+	case RTPRIV_IOCTL_GSITESURVEY:
+	case SIOCGIWPRIV:
+		Status = -EOPNOTSUPP;
+		break;
+	case SIOCETHTOOL:
+		break;
+	default:
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("IOCTL::unknown IOCTL's cmd = 0x%08x\n", cmd));
+		Status = -EOPNOTSUPP;
+		break;
 	}
 
-    if(StateMachineTouched) // Upper layer sent a MLME-related operations
-    	RT28XX_MLME_HANDLER(pAd);
+	if (StateMachineTouched)	/* Upper layer sent a MLME-related operations */
+		RTMP_MLME_HANDLER(pAd);
 
 	return Status;
 }
@@ -2878,95 +2639,77 @@
         TRUE if all parameters are OK, FALSE otherwise
     ==========================================================================
 */
-INT Set_SSID_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          arg)
+int Set_SSID_Proc(struct rt_rtmp_adapter *pAdapter, char *arg)
 {
-    NDIS_802_11_SSID                    Ssid, *pSsid=NULL;
-    BOOLEAN                             StateMachineTouched = FALSE;
-    int                                 success = TRUE;
+	struct rt_ndis_802_11_ssid Ssid, *pSsid = NULL;
+	BOOLEAN StateMachineTouched = FALSE;
+	int success = TRUE;
 
-    if( strlen(arg) <= MAX_LEN_OF_SSID)
-    {
-        NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
-        if (strlen(arg) != 0)
-        {
-            NdisMoveMemory(Ssid.Ssid, arg, strlen(arg));
-            Ssid.SsidLength = strlen(arg);
-        }
-        else   //ANY ssid
-        {
-            Ssid.SsidLength = 0;
-		    memcpy(Ssid.Ssid, "", 0);
+	if (strlen(arg) <= MAX_LEN_OF_SSID) {
+		NdisZeroMemory(&Ssid, sizeof(struct rt_ndis_802_11_ssid));
+		if (strlen(arg) != 0) {
+			NdisMoveMemory(Ssid.Ssid, arg, strlen(arg));
+			Ssid.SsidLength = strlen(arg);
+		} else		/*ANY ssid */
+		{
+			Ssid.SsidLength = 0;
+			memcpy(Ssid.Ssid, "", 0);
 			pAdapter->StaCfg.BssType = BSS_INFRA;
 			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
-	        pAdapter->StaCfg.WepStatus  = Ndis802_11EncryptionDisabled;
+			pAdapter->StaCfg.WepStatus =
+			    Ndis802_11EncryptionDisabled;
 		}
-        pSsid = &Ssid;
+		pSsid = &Ssid;
 
-        if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
-        {
-            RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
-            DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
-        }
+		if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE) {
+			RTMP_MLME_RESET_STATE_MACHINE(pAdapter);
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("MLME busy, reset MLME state machine!\n"));
+		}
 
-        pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
-        pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
+		if ((pAdapter->StaCfg.WpaPassPhraseLen >= 8) &&
+		    (pAdapter->StaCfg.WpaPassPhraseLen <= 64)) {
+			char passphrase_str[65] = { 0 };
+			u8 keyMaterial[40];
+
+			RTMPMoveMemory(passphrase_str,
+				       pAdapter->StaCfg.WpaPassPhrase,
+				       pAdapter->StaCfg.WpaPassPhraseLen);
+			RTMPZeroMemory(pAdapter->StaCfg.PMK, 32);
+			if (pAdapter->StaCfg.WpaPassPhraseLen == 64) {
+				AtoH((char *)pAdapter->StaCfg.WpaPassPhrase,
+				     pAdapter->StaCfg.PMK, 32);
+			} else {
+				PasswordHash((char *)pAdapter->StaCfg.
+					     WpaPassPhrase, Ssid.Ssid,
+					     Ssid.SsidLength, keyMaterial);
+				NdisMoveMemory(pAdapter->StaCfg.PMK,
+					       keyMaterial, 32);
+			}
+		}
+
+		pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
+		pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
 		pAdapter->bConfigChanged = TRUE;
 
-        MlmeEnqueue(pAdapter,
-                    MLME_CNTL_STATE_MACHINE,
-                    OID_802_11_SSID,
-                    sizeof(NDIS_802_11_SSID),
-                    (VOID *)pSsid);
+		MlmeEnqueue(pAdapter,
+			    MLME_CNTL_STATE_MACHINE,
+			    OID_802_11_SSID,
+			    sizeof(struct rt_ndis_802_11_ssid), (void *) pSsid);
 
-        StateMachineTouched = TRUE;
-        DBGPRINT(RT_DEBUG_TRACE, ("Set_SSID_Proc::(Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
-    }
-    else
-        success = FALSE;
+		StateMachineTouched = TRUE;
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Set_SSID_Proc::(Len=%d,Ssid=%s)\n", Ssid.SsidLength,
+			  Ssid.Ssid));
+	} else
+		success = FALSE;
 
-    if (StateMachineTouched) // Upper layer sent a MLME-related operations
-    	RT28XX_MLME_HANDLER(pAdapter);
+	if (StateMachineTouched)	/* Upper layer sent a MLME-related operations */
+		RTMP_MLME_HANDLER(pAdapter);
 
-    return success;
+	return success;
 }
 
-#ifdef WMM_SUPPORT
-/*
-    ==========================================================================
-    Description:
-        Set WmmCapable Enable or Disable
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_WmmCapable_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	BOOLEAN	bWmmCapable;
-
-	bWmmCapable = simple_strtol(arg, 0, 10);
-
-	if ((bWmmCapable == 1)
-#ifdef RT2870
-		&& (pAd->NumberOfPipes >= 5)
-#endif // RT2870 //
-		)
-		pAd->CommonCfg.bWmmCapable = TRUE;
-	else if (bWmmCapable == 0)
-		pAd->CommonCfg.bWmmCapable = FALSE;
-	else
-		return FALSE;  //Invalid argument
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_WmmCapable_Proc::(bWmmCapable=%d)\n",
-		pAd->CommonCfg.bWmmCapable));
-
-	return TRUE;
-}
-#endif // WMM_SUPPORT //
-
 /*
     ==========================================================================
     Description:
@@ -2975,166 +2718,184 @@
         TRUE if all parameters are OK, FALSE otherwise
     ==========================================================================
 */
-INT Set_NetworkType_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          arg)
+int Set_NetworkType_Proc(struct rt_rtmp_adapter *pAdapter, char *arg)
 {
-    UINT32	Value = 0;
+	u32 Value = 0;
 
-    if (strcmp(arg, "Adhoc") == 0)
-	{
-		if (pAdapter->StaCfg.BssType != BSS_ADHOC)
-		{
-			// Config has changed
+	if (strcmp(arg, "Adhoc") == 0) {
+		if (pAdapter->StaCfg.BssType != BSS_ADHOC) {
+			/* Config has changed */
 			pAdapter->bConfigChanged = TRUE;
-            if (MONITOR_ON(pAdapter))
-            {
-                RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
-                RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
+			if (MONITOR_ON(pAdapter)) {
+				RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG,
+						STANORMAL);
+				RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
 				Value &= (~0x80);
 				RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
-                OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
-                pAdapter->StaCfg.bAutoReconnect = TRUE;
-                LinkDown(pAdapter, FALSE);
-            }
-			if (INFRA_ON(pAdapter))
-			{
-				//BOOLEAN Cancelled;
-				// Set the AutoReconnectSsid to prevent it reconnect to old SSID
-				// Since calling this indicate user don't want to connect to that SSID anymore.
-				pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
-				NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
+				OPSTATUS_CLEAR_FLAG(pAdapter,
+						    fOP_STATUS_MEDIA_STATE_CONNECTED);
+				pAdapter->StaCfg.bAutoReconnect = TRUE;
+				LinkDown(pAdapter, FALSE);
+			}
+			if (INFRA_ON(pAdapter)) {
+				/*BOOLEAN Cancelled; */
+				/* Set the AutoReconnectSsid to prevent it reconnect to old SSID */
+				/* Since calling this indicate user don't want to connect to that SSID anymore. */
+				pAdapter->MlmeAux.AutoReconnectSsidLen = 32;
+				NdisZeroMemory(pAdapter->MlmeAux.
+					       AutoReconnectSsid,
+					       pAdapter->MlmeAux.
+					       AutoReconnectSsidLen);
 
 				LinkDown(pAdapter, FALSE);
 
-				DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event BB!\n"));
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("NDIS_STATUS_MEDIA_DISCONNECT Event BB!\n"));
 			}
 		}
 		pAdapter->StaCfg.BssType = BSS_ADHOC;
-        pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
-		DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(AD-HOC)\n"));
-	}
-    else if (strcmp(arg, "Infra") == 0)
-	{
-		if (pAdapter->StaCfg.BssType != BSS_INFRA)
-		{
-			// Config has changed
+		pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("===>Set_NetworkType_Proc::(AD-HOC)\n"));
+	} else if (strcmp(arg, "Infra") == 0) {
+		if (pAdapter->StaCfg.BssType != BSS_INFRA) {
+			/* Config has changed */
 			pAdapter->bConfigChanged = TRUE;
-            if (MONITOR_ON(pAdapter))
-            {
-                RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
-                RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
+			if (MONITOR_ON(pAdapter)) {
+				RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG,
+						STANORMAL);
+				RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
 				Value &= (~0x80);
 				RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
-                OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
-                pAdapter->StaCfg.bAutoReconnect = TRUE;
-                LinkDown(pAdapter, FALSE);
-            }
-			if (ADHOC_ON(pAdapter))
-			{
-				// Set the AutoReconnectSsid to prevent it reconnect to old SSID
-				// Since calling this indicate user don't want to connect to that SSID anymore.
-				pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
-				NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
+				OPSTATUS_CLEAR_FLAG(pAdapter,
+						    fOP_STATUS_MEDIA_STATE_CONNECTED);
+				pAdapter->StaCfg.bAutoReconnect = TRUE;
+				LinkDown(pAdapter, FALSE);
+			}
+			if (ADHOC_ON(pAdapter)) {
+				/* Set the AutoReconnectSsid to prevent it reconnect to old SSID */
+				/* Since calling this indicate user don't want to connect to that SSID anymore. */
+				pAdapter->MlmeAux.AutoReconnectSsidLen = 32;
+				NdisZeroMemory(pAdapter->MlmeAux.
+					       AutoReconnectSsid,
+					       pAdapter->MlmeAux.
+					       AutoReconnectSsidLen);
 
 				LinkDown(pAdapter, FALSE);
 			}
 		}
 		pAdapter->StaCfg.BssType = BSS_INFRA;
-        pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
-		DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(INFRA)\n"));
-
-        pAdapter->StaCfg.BssType = BSS_INFRA;
-	}
-    else if (strcmp(arg, "Monitor") == 0)
-    {
-		UCHAR	bbpValue = 0;
+		pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("===>Set_NetworkType_Proc::(INFRA)\n"));
+	} else if (strcmp(arg, "Monitor") == 0) {
+		u8 bbpValue = 0;
 		BCN_TIME_CFG_STRUC csr;
 		OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_INFRA_ON);
-        OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_ADHOC_ON);
+		OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_ADHOC_ON);
 		OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
-		// disable all periodic state machine
+		/* disable all periodic state machine */
 		pAdapter->StaCfg.bAutoReconnect = FALSE;
-		// reset all mlme state machine
-		RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
-		DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_MEDIA_STATE_CONNECTED \n"));
-        if (pAdapter->CommonCfg.CentralChannel == 0)
-        {
-            if (pAdapter->CommonCfg.PhyMode == PHY_11AN_MIXED)
-                pAdapter->CommonCfg.CentralChannel = 36;
-            else
-                pAdapter->CommonCfg.CentralChannel = 6;
-        }
-        else
-            N_ChannelCheck(pAdapter);
+		/* reset all mlme state machine */
+		RTMP_MLME_RESET_STATE_MACHINE(pAdapter);
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("fOP_STATUS_MEDIA_STATE_CONNECTED \n"));
+		if (pAdapter->CommonCfg.CentralChannel == 0) {
+			if (pAdapter->CommonCfg.PhyMode == PHY_11AN_MIXED)
+				pAdapter->CommonCfg.CentralChannel = 36;
+			else
+				pAdapter->CommonCfg.CentralChannel = 6;
+		} else
+			N_ChannelCheck(pAdapter);
 
-	if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
-            pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
-            pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
-		{
-			// 40MHz ,control channel at lower
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
+		if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
+		    pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
+		    pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA ==
+		    EXTCHA_ABOVE) {
+			/* 40MHz ,control channel at lower */
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4,
+						    &bbpValue);
 			bbpValue &= (~0x18);
 			bbpValue |= 0x10;
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4,
+						     bbpValue);
 			pAdapter->CommonCfg.BBPCurrentBW = BW_40;
-			//  RX : control channel at lower
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
+			/*  RX : control channel at lower */
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3,
+						    &bbpValue);
 			bbpValue &= (~0x20);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3,
+						     bbpValue);
 
 			RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
 			Value &= 0xfffffffe;
 			RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
-			pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel + 2;
-            AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
-		    AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
-            DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
-                                       pAdapter->CommonCfg.Channel,
-                                       pAdapter->CommonCfg.CentralChannel));
-		}
-		else if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
-                 pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
-                 pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW)
-		{
-			// 40MHz ,control channel at upper
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
+			pAdapter->CommonCfg.CentralChannel =
+			    pAdapter->CommonCfg.Channel + 2;
+			AsicSwitchChannel(pAdapter,
+					  pAdapter->CommonCfg.CentralChannel,
+					  FALSE);
+			AsicLockChannel(pAdapter,
+					pAdapter->CommonCfg.CentralChannel);
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
+				  pAdapter->CommonCfg.Channel,
+				  pAdapter->CommonCfg.CentralChannel));
+		} else if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED
+			   && pAdapter->CommonCfg.RegTransmitSetting.field.BW ==
+			   BW_40
+			   && pAdapter->CommonCfg.RegTransmitSetting.field.
+			   EXTCHA == EXTCHA_BELOW) {
+			/* 40MHz ,control channel at upper */
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4,
+						    &bbpValue);
 			bbpValue &= (~0x18);
 			bbpValue |= 0x10;
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4,
+						     bbpValue);
 			pAdapter->CommonCfg.BBPCurrentBW = BW_40;
 			RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
 			Value |= 0x1;
 			RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
 
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3,
+						    &bbpValue);
 			bbpValue |= (0x20);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
-			pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel - 2;
-            AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
-		    AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
-            DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
-                                       pAdapter->CommonCfg.Channel,
-                                       pAdapter->CommonCfg.CentralChannel));
-		}
-		else
-		{
-			// 20MHz
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3,
+						     bbpValue);
+			pAdapter->CommonCfg.CentralChannel =
+			    pAdapter->CommonCfg.Channel - 2;
+			AsicSwitchChannel(pAdapter,
+					  pAdapter->CommonCfg.CentralChannel,
+					  FALSE);
+			AsicLockChannel(pAdapter,
+					pAdapter->CommonCfg.CentralChannel);
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
+				  pAdapter->CommonCfg.Channel,
+				  pAdapter->CommonCfg.CentralChannel));
+		} else {
+			/* 20MHz */
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4,
+						    &bbpValue);
 			bbpValue &= (~0x18);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4,
+						     bbpValue);
 			pAdapter->CommonCfg.BBPCurrentBW = BW_20;
-			AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.Channel, FALSE);
+			AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.Channel,
+					  FALSE);
 			AsicLockChannel(pAdapter, pAdapter->CommonCfg.Channel);
-			DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAdapter->CommonCfg.Channel));
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("BW_20, Channel(%d)\n",
+				  pAdapter->CommonCfg.Channel));
 		}
-		// Enable Rx with promiscuous reception
+		/* Enable Rx with promiscuous reception */
 		RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, 0x3);
-		// ASIC supporsts sniffer function with replacing RSSI with timestamp.
-		//RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
-		//Value |= (0x80);
-		//RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
-		// disable sync
+		/* ASIC supporsts sniffer function with replacing RSSI with timestamp. */
+		/*RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value); */
+		/*Value |= (0x80); */
+		/*RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value); */
+		/* disable sync */
 		RTMP_IO_READ32(pAdapter, BCN_TIME_CFG, &csr.word);
 		csr.field.bBeaconGen = 0;
 		csr.field.bTBTTEnable = 0;
@@ -3142,655 +2903,16 @@
 		RTMP_IO_WRITE32(pAdapter, BCN_TIME_CFG, csr.word);
 
 		pAdapter->StaCfg.BssType = BSS_MONITOR;
-        pAdapter->net_dev->type = ARPHRD_IEEE80211_PRISM; //ARPHRD_IEEE80211; // IEEE80211
-		DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(MONITOR)\n"));
-    }
+		pAdapter->net_dev->type = ARPHRD_IEEE80211_PRISM;	/*ARPHRD_IEEE80211; // IEEE80211 */
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("===>Set_NetworkType_Proc::(MONITOR)\n"));
+	}
+	/* Reset Ralink supplicant to not use, it will be set to start when UI set PMK key */
+	pAdapter->StaCfg.WpaState = SS_NOTUSE;
 
-    // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
-    pAdapter->StaCfg.WpaState = SS_NOTUSE;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("Set_NetworkType_Proc::(NetworkType=%d)\n", pAdapter->StaCfg.BssType));
-
-    return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set Authentication mode
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_AuthMode_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          arg)
-{
-    if ((strcmp(arg, "WEPAUTO") == 0) || (strcmp(arg, "wepauto") == 0))
-        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
-    else if ((strcmp(arg, "OPEN") == 0) || (strcmp(arg, "open") == 0))
-        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
-    else if ((strcmp(arg, "SHARED") == 0) || (strcmp(arg, "shared") == 0))
-        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
-    else if ((strcmp(arg, "WPAPSK") == 0) || (strcmp(arg, "wpapsk") == 0))
-        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
-    else if ((strcmp(arg, "WPANONE") == 0) || (strcmp(arg, "wpanone") == 0))
-        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
-    else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "wpa2psk") == 0))
-        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
-    else if ((strcmp(arg, "WPA") == 0) || (strcmp(arg, "wpa") == 0))
-        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
-    else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "wpa2") == 0))
-        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
-    else
-        return FALSE;
-
-    pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("Set_AuthMode_Proc::(AuthMode=%d)\n", pAdapter->StaCfg.AuthMode));
-
-    return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set Encryption Type
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_EncrypType_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          arg)
-{
-    if ((strcmp(arg, "NONE") == 0) || (strcmp(arg, "none") == 0))
-    {
-        if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-            return TRUE;    // do nothing
-
-        pAdapter->StaCfg.WepStatus     = Ndis802_11WEPDisabled;
-        pAdapter->StaCfg.PairCipher    = Ndis802_11WEPDisabled;
-	    pAdapter->StaCfg.GroupCipher   = Ndis802_11WEPDisabled;
-    }
-    else if ((strcmp(arg, "WEP") == 0) || (strcmp(arg, "wep") == 0))
-    {
-        if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-            return TRUE;    // do nothing
-
-        pAdapter->StaCfg.WepStatus     = Ndis802_11WEPEnabled;
-        pAdapter->StaCfg.PairCipher    = Ndis802_11WEPEnabled;
-	    pAdapter->StaCfg.GroupCipher   = Ndis802_11WEPEnabled;
-    }
-    else if ((strcmp(arg, "TKIP") == 0) || (strcmp(arg, "tkip") == 0))
-    {
-        if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
-            return TRUE;    // do nothing
-
-        pAdapter->StaCfg.WepStatus     = Ndis802_11Encryption2Enabled;
-        pAdapter->StaCfg.PairCipher    = Ndis802_11Encryption2Enabled;
-	    pAdapter->StaCfg.GroupCipher   = Ndis802_11Encryption2Enabled;
-    }
-    else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "aes") == 0))
-    {
-        if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
-            return TRUE;    // do nothing
-
-        pAdapter->StaCfg.WepStatus     = Ndis802_11Encryption3Enabled;
-        pAdapter->StaCfg.PairCipher    = Ndis802_11Encryption3Enabled;
-	    pAdapter->StaCfg.GroupCipher   = Ndis802_11Encryption3Enabled;
-    }
-    else
-        return FALSE;
-
-    pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("Set_EncrypType_Proc::(EncrypType=%d)\n", pAdapter->StaCfg.WepStatus));
-
-    return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set Default Key ID
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_DefaultKeyID_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          arg)
-{
-    ULONG                               KeyIdx;
-
-    KeyIdx = simple_strtol(arg, 0, 10);
-    if((KeyIdx >= 1 ) && (KeyIdx <= 4))
-        pAdapter->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1 );
-    else
-        return FALSE;  //Invalid argument
-
-    DBGPRINT(RT_DEBUG_TRACE, ("Set_DefaultKeyID_Proc::(DefaultKeyID=%d)\n", pAdapter->StaCfg.DefaultKeyId));
-
-    return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set WEP KEY1
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_Key1_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          arg)
-{
-    int                                 KeyLen;
-    int                                 i;
-    UCHAR                               CipherAlg=CIPHER_WEP64;
-
-    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-        return TRUE;    // do nothing
-
-    KeyLen = strlen(arg);
-
-    switch (KeyLen)
-    {
-        case 5: //wep 40 Ascii type
-            pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
-            memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
-            CipherAlg = CIPHER_WEP64;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
-            break;
-        case 10: //wep 40 Hex type
-            for(i=0; i < KeyLen; i++)
-            {
-                if( !isxdigit(*(arg+i)) )
-                    return FALSE;  //Not Hex value;
-            }
-            pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
-            AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
-            CipherAlg = CIPHER_WEP64;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
-            break;
-        case 13: //wep 104 Ascii type
-            pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
-            memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
-            CipherAlg = CIPHER_WEP128;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
-            break;
-        case 26: //wep 104 Hex type
-            for(i=0; i < KeyLen; i++)
-            {
-                if( !isxdigit(*(arg+i)) )
-                    return FALSE;  //Not Hex value;
-            }
-            pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
-            AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
-            CipherAlg = CIPHER_WEP128;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
-            break;
-        default: //Invalid argument
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::Invalid argument (=%s)\n", arg));
-            return FALSE;
-    }
-
-    pAdapter->SharedKey[BSS0][0].CipherAlg = CipherAlg;
-
-    // Set keys (into ASIC)
-    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-        ;   // not support
-    else    // Old WEP stuff
-    {
-        AsicAddSharedKeyEntry(pAdapter,
-                              0,
-                              0,
-                              pAdapter->SharedKey[BSS0][0].CipherAlg,
-                              pAdapter->SharedKey[BSS0][0].Key,
-                              NULL,
-                              NULL);
-    }
-
-    return TRUE;
-}
-/*
-    ==========================================================================
-
-    Description:
-        Set WEP KEY2
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_Key2_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          arg)
-{
-    int                                 KeyLen;
-    int                                 i;
-    UCHAR                               CipherAlg=CIPHER_WEP64;
-
-    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-        return TRUE;    // do nothing
-
-    KeyLen = strlen(arg);
-
-    switch (KeyLen)
-    {
-        case 5: //wep 40 Ascii type
-            pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
-            memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
-            CipherAlg = CIPHER_WEP64;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
-            break;
-        case 10: //wep 40 Hex type
-            for(i=0; i < KeyLen; i++)
-            {
-                if( !isxdigit(*(arg+i)) )
-                    return FALSE;  //Not Hex value;
-            }
-            pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
-            AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
-            CipherAlg = CIPHER_WEP64;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
-            break;
-        case 13: //wep 104 Ascii type
-            pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
-            memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
-            CipherAlg = CIPHER_WEP128;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
-            break;
-        case 26: //wep 104 Hex type
-            for(i=0; i < KeyLen; i++)
-            {
-                if( !isxdigit(*(arg+i)) )
-                    return FALSE;  //Not Hex value;
-            }
-            pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
-            AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
-            CipherAlg = CIPHER_WEP128;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
-            break;
-        default: //Invalid argument
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::Invalid argument (=%s)\n", arg));
-            return FALSE;
-    }
-    pAdapter->SharedKey[BSS0][1].CipherAlg = CipherAlg;
-
-    // Set keys (into ASIC)
-    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-        ;   // not support
-    else    // Old WEP stuff
-    {
-        AsicAddSharedKeyEntry(pAdapter,
-                              0,
-                              1,
-                              pAdapter->SharedKey[BSS0][1].CipherAlg,
-                              pAdapter->SharedKey[BSS0][1].Key,
-                              NULL,
-                              NULL);
-    }
-
-    return TRUE;
-}
-/*
-    ==========================================================================
-    Description:
-        Set WEP KEY3
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_Key3_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          arg)
-{
-    int                                 KeyLen;
-    int                                 i;
-    UCHAR                               CipherAlg=CIPHER_WEP64;
-
-    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-        return TRUE;    // do nothing
-
-    KeyLen = strlen(arg);
-
-    switch (KeyLen)
-    {
-        case 5: //wep 40 Ascii type
-            pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
-            memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
-            CipherAlg = CIPHER_WEP64;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
-            break;
-        case 10: //wep 40 Hex type
-            for(i=0; i < KeyLen; i++)
-            {
-                if( !isxdigit(*(arg+i)) )
-                    return FALSE;  //Not Hex value;
-            }
-            pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
-            AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
-            CipherAlg = CIPHER_WEP64;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
-            break;
-        case 13: //wep 104 Ascii type
-            pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
-            memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
-            CipherAlg = CIPHER_WEP128;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
-            break;
-        case 26: //wep 104 Hex type
-            for(i=0; i < KeyLen; i++)
-            {
-                if( !isxdigit(*(arg+i)) )
-                    return FALSE;  //Not Hex value;
-            }
-            pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
-            AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
-            CipherAlg = CIPHER_WEP128;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
-            break;
-        default: //Invalid argument
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::Invalid argument (=%s)\n", arg));
-            return FALSE;
-    }
-    pAdapter->SharedKey[BSS0][2].CipherAlg = CipherAlg;
-
-    // Set keys (into ASIC)
-    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-        ;   // not support
-    else    // Old WEP stuff
-    {
-        AsicAddSharedKeyEntry(pAdapter,
-                              0,
-                              2,
-                              pAdapter->SharedKey[BSS0][2].CipherAlg,
-                              pAdapter->SharedKey[BSS0][2].Key,
-                              NULL,
-                              NULL);
-    }
-
-    return TRUE;
-}
-/*
-    ==========================================================================
-    Description:
-        Set WEP KEY4
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_Key4_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          arg)
-{
-    int                                 KeyLen;
-    int                                 i;
-    UCHAR                               CipherAlg=CIPHER_WEP64;
-
-    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-        return TRUE;    // do nothing
-
-    KeyLen = strlen(arg);
-
-    switch (KeyLen)
-    {
-        case 5: //wep 40 Ascii type
-            pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
-            memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
-            CipherAlg = CIPHER_WEP64;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
-            break;
-        case 10: //wep 40 Hex type
-            for(i=0; i < KeyLen; i++)
-            {
-                if( !isxdigit(*(arg+i)) )
-                    return FALSE;  //Not Hex value;
-            }
-            pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
-            AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
-            CipherAlg = CIPHER_WEP64;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
-            break;
-        case 13: //wep 104 Ascii type
-            pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
-            memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
-            CipherAlg = CIPHER_WEP128;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
-            break;
-        case 26: //wep 104 Hex type
-            for(i=0; i < KeyLen; i++)
-            {
-                if( !isxdigit(*(arg+i)) )
-                    return FALSE;  //Not Hex value;
-            }
-            pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
-            AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
-            CipherAlg = CIPHER_WEP128;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
-            break;
-        default: //Invalid argument
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::Invalid argument (=%s)\n", arg));
-            return FALSE;
-    }
-    pAdapter->SharedKey[BSS0][3].CipherAlg = CipherAlg;
-
-    // Set keys (into ASIC)
-    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-        ;   // not support
-    else    // Old WEP stuff
-    {
-        AsicAddSharedKeyEntry(pAdapter,
-                              0,
-                              3,
-                              pAdapter->SharedKey[BSS0][3].CipherAlg,
-                              pAdapter->SharedKey[BSS0][3].Key,
-                              NULL,
-                              NULL);
-    }
-
-    return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set WPA PSK key
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_WPAPSK_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          arg)
-{
-    UCHAR                   keyMaterial[40];
-
-    if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
-        (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
-	    (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
-		)
-        return TRUE;    // do nothing
-
-    DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc::(WPAPSK=%s)\n", arg));
-
-    NdisZeroMemory(keyMaterial, 40);
-
-    if ((strlen(arg) < 8) || (strlen(arg) > 64))
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("Set failed!!(WPAPSK=%s), WPAPSK key-string required 8 ~ 64 characters \n", arg));
-        return FALSE;
-    }
-
-    if (strlen(arg) == 64)
-    {
-        AtoH(arg, keyMaterial, 32);
-        NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
-
-    }
-    else
-    {
-        PasswordHash((char *)arg, pAdapter->MlmeAux.Ssid, pAdapter->MlmeAux.SsidLen, keyMaterial);
-        NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
-    }
-
-
-
-    if(pAdapter->StaCfg.BssType == BSS_ADHOC &&
-       pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
-    {
-         pAdapter->StaCfg.WpaState = SS_NOTUSE;
-    }
-    else
-    {
-        // Start STA supplicant state machine
-        pAdapter->StaCfg.WpaState = SS_START;
-    }
-
-    return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set Power Saving mode
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_PSMode_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          arg)
-{
-    if (pAdapter->StaCfg.BssType == BSS_INFRA)
-    {
-        if ((strcmp(arg, "Max_PSP") == 0) ||
-			(strcmp(arg, "max_psp") == 0) ||
-			(strcmp(arg, "MAX_PSP") == 0))
-        {
-            // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
-            // to exclude certain situations.
-            if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
-                pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
-            pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
-            OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
-            pAdapter->StaCfg.DefaultListenCount = 5;
-
-        }
-        else if ((strcmp(arg, "Fast_PSP") == 0) ||
-				 (strcmp(arg, "fast_psp") == 0) ||
-                 (strcmp(arg, "FAST_PSP") == 0))
-        {
-            // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
-            // to exclude certain situations.
-            OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
-            if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
-                pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
-            pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
-            pAdapter->StaCfg.DefaultListenCount = 3;
-        }
-        else if ((strcmp(arg, "Legacy_PSP") == 0) ||
-                 (strcmp(arg, "legacy_psp") == 0) ||
-                 (strcmp(arg, "LEGACY_PSP") == 0))
-        {
-            // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
-            // to exclude certain situations.
-            OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
-            if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
-                pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
-            pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
-            pAdapter->StaCfg.DefaultListenCount = 3;
-        }
-        else
-        {
-            //Default Ndis802_11PowerModeCAM
-            // clear PSM bit immediately
-            MlmeSetPsmBit(pAdapter, PWR_ACTIVE);
-            OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
-            if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
-                pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
-            pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
-        }
-
-        DBGPRINT(RT_DEBUG_TRACE, ("Set_PSMode_Proc::(PSMode=%ld)\n", pAdapter->StaCfg.WindowsPowerMode));
-    }
-    else
-        return FALSE;
-
-
-    return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set WpaSupport flag.
-    Value:
-        0: Driver ignore wpa_supplicant.
-        1: wpa_supplicant initiates scanning and AP selection.
-        2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters.
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_Wpa_Support(
-    IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-
-    if ( simple_strtol(arg, 0, 10) == 0)
-        pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
-    else if ( simple_strtol(arg, 0, 10) == 1)
-        pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
-    else if ( simple_strtol(arg, 0, 10) == 2)
-        pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE_WITH_WEB_UI;
-    else
-        pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("Set_Wpa_Support::(WpaSupplicantUP=%d)\n", pAd->StaCfg.WpaSupplicantUP));
-
-    return TRUE;
-}
-
-INT Set_TGnWifiTest_Proc(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PUCHAR          arg)
-{
-    if (simple_strtol(arg, 0, 10) == 0)
-        pAd->StaCfg.bTGnWifiTest = FALSE;
-    else
-        pAd->StaCfg.bTGnWifiTest = TRUE;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("IF Set_TGnWifiTest_Proc::(bTGnWifiTest=%d)\n", pAd->StaCfg.bTGnWifiTest));
-	return TRUE;
-}
-
-INT Set_LongRetryLimit_Proc(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	PUCHAR			arg)
-{
-	TX_RTY_CFG_STRUC	tx_rty_cfg;
-	UCHAR				LongRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
-
-	RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
-	tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
-	RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
-	DBGPRINT(RT_DEBUG_TRACE, ("IF Set_LongRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
-	return TRUE;
-}
-
-INT Set_ShortRetryLimit_Proc(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	PUCHAR			arg)
-{
-	TX_RTY_CFG_STRUC	tx_rty_cfg;
-	UCHAR				ShortRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("Set_NetworkType_Proc::(NetworkType=%d)\n",
+		  pAdapter->StaCfg.BssType));
 
-	RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
-	tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
-	RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
-	DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
 	return TRUE;
 }
diff --git a/drivers/staging/rt2860/usb_main_dev.c b/drivers/staging/rt2860/usb_main_dev.c
new file mode 100644
index 0000000..925a236
--- /dev/null
+++ b/drivers/staging/rt2860/usb_main_dev.c
@@ -0,0 +1,887 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************/
+
+#include "rt_config.h"
+
+/* Following information will be show when you run 'modinfo' */
+/* *** If you have a solution for the bug in current version of driver, please mail to me. */
+/* Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. *** */
+MODULE_AUTHOR("Paul Lin <paul_lin@ralinktech.com>");
+MODULE_DESCRIPTION("RT2870/RT3070 Wireless Lan Linux Driver");
+MODULE_LICENSE("GPL");
+#ifdef MODULE_VERSION
+MODULE_VERSION(STA_DRIVER_VERSION);
+#endif
+
+/* module table */
+struct usb_device_id rtusb_usb_id[] = {
+#ifdef RT2870
+	{USB_DEVICE(0x148F, 0x2770)},	/* Ralink */
+	{USB_DEVICE(0x148F, 0x2870)},	/* Ralink */
+	{USB_DEVICE(0x07B8, 0x2870)},	/* AboCom */
+	{USB_DEVICE(0x07B8, 0x2770)},	/* AboCom */
+	{USB_DEVICE(0x0DF6, 0x0039)},	/* Sitecom 2770 */
+	{USB_DEVICE(0x083A, 0x7512)},	/* Arcadyan 2770 */
+	{USB_DEVICE(0x0789, 0x0162)},	/* Logitec 2870 */
+	{USB_DEVICE(0x0789, 0x0163)},	/* Logitec 2870 */
+	{USB_DEVICE(0x0789, 0x0164)},	/* Logitec 2870 */
+	{USB_DEVICE(0x177f, 0x0302)},	/* lsusb */
+	{USB_DEVICE(0x0B05, 0x1731)},	/* Asus */
+	{USB_DEVICE(0x0B05, 0x1732)},	/* Asus */
+	{USB_DEVICE(0x0B05, 0x1742)},	/* Asus */
+	{USB_DEVICE(0x0DF6, 0x0017)},	/* Sitecom */
+	{USB_DEVICE(0x0DF6, 0x002B)},	/* Sitecom */
+	{USB_DEVICE(0x0DF6, 0x002C)},	/* Sitecom */
+	{USB_DEVICE(0x0DF6, 0x002D)},	/* Sitecom */
+	{USB_DEVICE(0x14B2, 0x3C06)},	/* Conceptronic */
+	{USB_DEVICE(0x14B2, 0x3C28)},	/* Conceptronic */
+	{USB_DEVICE(0x2019, 0xED06)},	/* Planex Communications, Inc. */
+	{USB_DEVICE(0x07D1, 0x3C09)},	/* D-Link */
+	{USB_DEVICE(0x07D1, 0x3C11)},	/* D-Link */
+	{USB_DEVICE(0x14B2, 0x3C07)},	/* AL */
+	{USB_DEVICE(0x050D, 0x8053)},	/* Belkin */
+	{USB_DEVICE(0x14B2, 0x3C23)},	/* Airlink */
+	{USB_DEVICE(0x14B2, 0x3C27)},	/* Airlink */
+	{USB_DEVICE(0x07AA, 0x002F)},	/* Corega */
+	{USB_DEVICE(0x07AA, 0x003C)},	/* Corega */
+	{USB_DEVICE(0x07AA, 0x003F)},	/* Corega */
+	{USB_DEVICE(0x1044, 0x800B)},	/* Gigabyte */
+	{USB_DEVICE(0x15A9, 0x0006)},	/* Sparklan */
+	{USB_DEVICE(0x083A, 0xB522)},	/* SMC */
+	{USB_DEVICE(0x083A, 0xA618)},	/* SMC */
+	{USB_DEVICE(0x083A, 0x8522)},	/* Arcadyan */
+	{USB_DEVICE(0x083A, 0x7522)},	/* Arcadyan */
+	{USB_DEVICE(0x0CDE, 0x0022)},	/* ZCOM */
+	{USB_DEVICE(0x0586, 0x3416)},	/* Zyxel */
+	{USB_DEVICE(0x0CDE, 0x0025)},	/* Zyxel */
+	{USB_DEVICE(0x1740, 0x9701)},	/* EnGenius */
+	{USB_DEVICE(0x1740, 0x9702)},	/* EnGenius */
+	{USB_DEVICE(0x0471, 0x200f)},	/* Philips */
+	{USB_DEVICE(0x14B2, 0x3C25)},	/* Draytek */
+	{USB_DEVICE(0x13D3, 0x3247)},	/* AzureWave */
+	{USB_DEVICE(0x083A, 0x6618)},	/* Accton */
+	{USB_DEVICE(0x15c5, 0x0008)},	/* Amit */
+	{USB_DEVICE(0x0E66, 0x0001)},	/* Hawking */
+	{USB_DEVICE(0x0E66, 0x0003)},	/* Hawking */
+	{USB_DEVICE(0x129B, 0x1828)},	/* Siemens */
+	{USB_DEVICE(0x157E, 0x300E)},	/* U-Media */
+	{USB_DEVICE(0x050d, 0x805c)},
+	{USB_DEVICE(0x050d, 0x815c)},
+	{USB_DEVICE(0x1482, 0x3C09)},	/* Abocom */
+	{USB_DEVICE(0x14B2, 0x3C09)},	/* Alpha */
+	{USB_DEVICE(0x04E8, 0x2018)},	/* samsung */
+	{USB_DEVICE(0x5A57, 0x0280)},	/* Zinwell */
+	{USB_DEVICE(0x5A57, 0x0282)},	/* Zinwell */
+	{USB_DEVICE(0x7392, 0x7718)},
+	{USB_DEVICE(0x7392, 0x7717)},
+	{USB_DEVICE(0x1737, 0x0070)},	/* Linksys WUSB100 */
+	{USB_DEVICE(0x1737, 0x0071)},	/* Linksys WUSB600N */
+	{USB_DEVICE(0x0411, 0x00e8)},	/* Buffalo WLI-UC-G300N */
+	{USB_DEVICE(0x050d, 0x815c)},	/* Belkin F5D8053 */
+#endif /* RT2870 // */
+#ifdef RT3070
+	{USB_DEVICE(0x148F, 0x3070)},	/* Ralink 3070 */
+	{USB_DEVICE(0x148F, 0x3071)},	/* Ralink 3071 */
+	{USB_DEVICE(0x148F, 0x3072)},	/* Ralink 3072 */
+	{USB_DEVICE(0x0DB0, 0x3820)},	/* Ralink 3070 */
+	{USB_DEVICE(0x0DF6, 0x003E)},	/* Sitecom 3070 */
+	{USB_DEVICE(0x0DF6, 0x0042)},	/* Sitecom 3072 */
+	{USB_DEVICE(0x14B2, 0x3C12)},	/* AL 3070 */
+	{USB_DEVICE(0x18C5, 0x0012)},	/* Corega 3070 */
+	{USB_DEVICE(0x083A, 0x7511)},	/* Arcadyan 3070 */
+	{USB_DEVICE(0x1740, 0x9703)},	/* EnGenius 3070 */
+	{USB_DEVICE(0x1740, 0x9705)},	/* EnGenius 3071 */
+	{USB_DEVICE(0x1740, 0x9706)},	/* EnGenius 3072 */
+	{USB_DEVICE(0x13D3, 0x3273)},	/* AzureWave 3070 */
+	{USB_DEVICE(0x1044, 0x800D)},	/* Gigabyte GN-WB32L 3070 */
+	{USB_DEVICE(0x2019, 0xAB25)},	/* Planex Communications, Inc. RT3070 */
+	{USB_DEVICE(0x07B8, 0x3070)},	/* AboCom 3070 */
+	{USB_DEVICE(0x07B8, 0x3071)},	/* AboCom 3071 */
+	{USB_DEVICE(0x07B8, 0x3072)},	/* Abocom 3072 */
+	{USB_DEVICE(0x7392, 0x7711)},	/* Edimax 3070 */
+	{USB_DEVICE(0x1A32, 0x0304)},	/* Quanta 3070 */
+	{USB_DEVICE(0x1EDA, 0x2310)},	/* AirTies 3070 */
+	{USB_DEVICE(0x07D1, 0x3C0A)},	/* D-Link 3072 */
+	{USB_DEVICE(0x07D1, 0x3C0D)},	/* D-Link 3070 */
+	{USB_DEVICE(0x07D1, 0x3C0E)},	/* D-Link 3070 */
+	{USB_DEVICE(0x07D1, 0x3C0F)},	/* D-Link 3070 */
+	{USB_DEVICE(0x1D4D, 0x000C)},	/* Pegatron Corporation 3070 */
+	{USB_DEVICE(0x1D4D, 0x000E)},	/* Pegatron Corporation 3070 */
+	{USB_DEVICE(0x5A57, 0x5257)},	/* Zinwell 3070 */
+	{USB_DEVICE(0x5A57, 0x0283)},	/* Zinwell 3072 */
+	{USB_DEVICE(0x04BB, 0x0945)},	/* I-O DATA 3072 */
+	{USB_DEVICE(0x203D, 0x1480)},	/* Encore 3070 */
+#endif /* RT3070 // */
+	{USB_DEVICE(0x0DF6, 0x003F)},	/* Sitecom WL-608 */
+	{USB_DEVICE(0x1737, 0x0077)},	/* Linksys WUSB54GC-EU v3 */
+	{USB_DEVICE(0x2001, 0x3C09)},	/* D-Link */
+	{USB_DEVICE(0x2001, 0x3C0A)},	/* D-Link 3072 */
+	{USB_DEVICE(0x2019, 0xED14)},	/* Planex Communications, Inc. */
+	{}			/* Terminating entry */
+};
+
+int const rtusb_usb_id_len =
+    sizeof(rtusb_usb_id) / sizeof(struct usb_device_id);
+
+MODULE_DEVICE_TABLE(usb, rtusb_usb_id);
+
+static void rt2870_disconnect(struct usb_device *dev, struct rt_rtmp_adapter *pAd);
+
+static int __devinit rt2870_probe(IN struct usb_interface *intf,
+				  IN struct usb_device *usb_dev,
+				  IN const struct usb_device_id *dev_id,
+				  struct rt_rtmp_adapter ** ppAd);
+
+#ifndef PF_NOFREEZE
+#define PF_NOFREEZE  0
+#endif
+
+extern int rt28xx_close(IN struct net_device *net_dev);
+extern int rt28xx_open(struct net_device *net_dev);
+
+static BOOLEAN USBDevConfigInit(IN struct usb_device *dev,
+				IN struct usb_interface *intf,
+				struct rt_rtmp_adapter *pAd);
+
+/*
+========================================================================
+Routine Description:
+    Check the chipset vendor/product ID.
+
+Arguments:
+    _dev_p				Point to the PCI or USB device
+
+Return Value:
+    TRUE				Check ok
+	FALSE				Check fail
+
+Note:
+========================================================================
+*/
+BOOLEAN RT28XXChipsetCheck(IN void *_dev_p)
+{
+	struct usb_interface *intf = (struct usb_interface *)_dev_p;
+	struct usb_device *dev_p = interface_to_usbdev(intf);
+	u32 i;
+
+	for (i = 0; i < rtusb_usb_id_len; i++) {
+		if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
+		    dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct) {
+			printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
+			       dev_p->descriptor.idVendor,
+			       dev_p->descriptor.idProduct);
+			break;
+		}
+	}
+
+	if (i == rtusb_usb_id_len) {
+		printk("rt2870: Error! Device Descriptor not matching!\n");
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+/**************************************************************************/
+/**************************************************************************/
+/*tested for kernel 2.6series */
+/**************************************************************************/
+/**************************************************************************/
+
+#ifdef CONFIG_PM
+static int rt2870_suspend(struct usb_interface *intf, pm_message_t state);
+static int rt2870_resume(struct usb_interface *intf);
+#endif /* CONFIG_PM // */
+
+static int rtusb_probe(struct usb_interface *intf,
+		       const struct usb_device_id *id);
+static void rtusb_disconnect(struct usb_interface *intf);
+
+static BOOLEAN USBDevConfigInit(IN struct usb_device *dev,
+				IN struct usb_interface *intf,
+				struct rt_rtmp_adapter *pAd)
+{
+	struct usb_host_interface *iface_desc;
+	unsigned long BulkOutIdx;
+	u32 i;
+
+	/* get the active interface descriptor */
+	iface_desc = intf->cur_altsetting;
+
+	/* get # of enpoints  */
+	pAd->NumberOfPipes = iface_desc->desc.bNumEndpoints;
+	DBGPRINT(RT_DEBUG_TRACE,
+		 ("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints));
+
+	/* Configure Pipes */
+	BulkOutIdx = 0;
+
+	for (i = 0; i < pAd->NumberOfPipes; i++) {
+		if ((iface_desc->endpoint[i].desc.bmAttributes ==
+		     USB_ENDPOINT_XFER_BULK) &&
+		    ((iface_desc->endpoint[i].desc.bEndpointAddress &
+		      USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)) {
+			pAd->BulkInEpAddr =
+			    iface_desc->endpoint[i].desc.bEndpointAddress;
+			pAd->BulkInMaxPacketSize =
+			    le2cpu16(iface_desc->endpoint[i].desc.
+				     wMaxPacketSize);
+
+			DBGPRINT_RAW(RT_DEBUG_TRACE,
+				     ("BULK IN MaxPacketSize = %d\n",
+				      pAd->BulkInMaxPacketSize));
+			DBGPRINT_RAW(RT_DEBUG_TRACE,
+				     ("EP address = 0x%2x\n",
+				      iface_desc->endpoint[i].desc.
+				      bEndpointAddress));
+		} else
+		    if ((iface_desc->endpoint[i].desc.bmAttributes ==
+			 USB_ENDPOINT_XFER_BULK)
+			&&
+			((iface_desc->endpoint[i].desc.
+			  bEndpointAddress & USB_ENDPOINT_DIR_MASK) ==
+			 USB_DIR_OUT)) {
+			/* there are 6 bulk out EP. EP6 highest priority. */
+			/* EP1-4 is EDCA.  EP5 is HCCA. */
+			pAd->BulkOutEpAddr[BulkOutIdx++] =
+			    iface_desc->endpoint[i].desc.bEndpointAddress;
+			pAd->BulkOutMaxPacketSize =
+			    le2cpu16(iface_desc->endpoint[i].desc.
+				     wMaxPacketSize);
+
+			DBGPRINT_RAW(RT_DEBUG_TRACE,
+				     ("BULK OUT MaxPacketSize = %d\n",
+				      pAd->BulkOutMaxPacketSize));
+			DBGPRINT_RAW(RT_DEBUG_TRACE,
+				     ("EP address = 0x%2x  \n",
+				      iface_desc->endpoint[i].desc.
+				      bEndpointAddress));
+		}
+	}
+
+	if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0])) {
+		printk
+		    ("%s: Could not find both bulk-in and bulk-out endpoints\n",
+		     __FUNCTION__);
+		return FALSE;
+	}
+
+	pAd->config = &dev->config->desc;
+	usb_set_intfdata(intf, pAd);
+
+	return TRUE;
+
+}
+
+static int rtusb_probe(struct usb_interface *intf,
+		       const struct usb_device_id *id)
+{
+	struct rt_rtmp_adapter *pAd;
+	struct usb_device *dev;
+	int rv;
+
+	dev = interface_to_usbdev(intf);
+	dev = usb_get_dev(dev);
+
+	rv = rt2870_probe(intf, dev, id, &pAd);
+	if (rv != 0)
+		usb_put_dev(dev);
+
+	return rv;
+}
+
+static void rtusb_disconnect(struct usb_interface *intf)
+{
+	struct usb_device *dev = interface_to_usbdev(intf);
+	struct rt_rtmp_adapter *pAd;
+
+	pAd = usb_get_intfdata(intf);
+	usb_set_intfdata(intf, NULL);
+
+	rt2870_disconnect(dev, pAd);
+}
+
+struct usb_driver rtusb_driver = {
+	.name = "rt2870",
+	.probe = rtusb_probe,
+	.disconnect = rtusb_disconnect,
+	.id_table = rtusb_usb_id,
+
+#ifdef CONFIG_PM
+suspend:rt2870_suspend,
+resume:rt2870_resume,
+#endif
+};
+
+#ifdef CONFIG_PM
+
+void RT2870RejectPendingPackets(struct rt_rtmp_adapter *pAd)
+{
+	/* clear PS packets */
+	/* clear TxSw packets */
+}
+
+static int rt2870_suspend(struct usb_interface *intf, pm_message_t state)
+{
+	struct net_device *net_dev;
+	struct rt_rtmp_adapter *pAd = usb_get_intfdata(intf);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n"));
+	net_dev = pAd->net_dev;
+	netif_device_detach(net_dev);
+
+	pAd->PM_FlgSuspend = 1;
+	if (netif_running(net_dev)) {
+		RTUSBCancelPendingBulkInIRP(pAd);
+		RTUSBCancelPendingBulkOutIRP(pAd);
+	}
+	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_suspend()\n"));
+	return 0;
+}
+
+static int rt2870_resume(struct usb_interface *intf)
+{
+	struct net_device *net_dev;
+	struct rt_rtmp_adapter *pAd = usb_get_intfdata(intf);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_resume()\n"));
+
+	pAd->PM_FlgSuspend = 0;
+	net_dev = pAd->net_dev;
+	netif_device_attach(net_dev);
+	netif_start_queue(net_dev);
+	netif_carrier_on(net_dev);
+	netif_wake_queue(net_dev);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n"));
+	return 0;
+}
+#endif /* CONFIG_PM // */
+
+/* Init driver module */
+int __init rtusb_init(void)
+{
+	printk("rtusb init --->\n");
+	return usb_register(&rtusb_driver);
+}
+
+/* Deinit driver module */
+void __exit rtusb_exit(void)
+{
+	usb_deregister(&rtusb_driver);
+	printk("<--- rtusb exit\n");
+}
+
+module_init(rtusb_init);
+module_exit(rtusb_exit);
+
+/*---------------------------------------------------------------------	*/
+/* function declarations												*/
+/*---------------------------------------------------------------------	*/
+
+/*
+========================================================================
+Routine Description:
+    MLME kernel thread.
+
+Arguments:
+	*Context			the pAd, driver control block pointer
+
+Return Value:
+    0					close the thread
+
+Note:
+========================================================================
+*/
+int MlmeThread(IN void *Context)
+{
+	struct rt_rtmp_adapter *pAd;
+	struct rt_rtmp_os_task *pTask;
+	int status;
+	status = 0;
+
+	pTask = (struct rt_rtmp_os_task *)Context;
+	pAd = (struct rt_rtmp_adapter *)pTask->priv;
+
+	RtmpOSTaskCustomize(pTask);
+
+	while (!pTask->task_killed) {
+#ifdef KTHREAD_SUPPORT
+		RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
+#else
+		RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
+
+		/* unlock the device pointers */
+		if (status != 0) {
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+			break;
+		}
+#endif
+
+		/* lock the device pointers , need to check if required */
+		/*down(&(pAd->usbdev_semaphore)); */
+
+		if (!pAd->PM_FlgSuspend)
+			MlmeHandler(pAd);
+	}
+
+	/* notify the exit routine that we're actually exiting now
+	 *
+	 * complete()/wait_for_completion() is similar to up()/down(),
+	 * except that complete() is safe in the case where the structure
+	 * is getting deleted in a parallel mode of execution (i.e. just
+	 * after the down() -- that's necessary for the thread-shutdown
+	 * case.
+	 *
+	 * complete_and_exit() goes even further than this -- it is safe in
+	 * the case that the thread of the caller is going away (not just
+	 * the structure) -- this is necessary for the module-remove case.
+	 * This is important in preemption kernels, which transfer the flow
+	 * of execution immediately upon a complete().
+	 */
+	DBGPRINT(RT_DEBUG_TRACE, ("<---%s\n", __FUNCTION__));
+#ifndef KTHREAD_SUPPORT
+	pTask->taskPID = THREAD_PID_INIT_VALUE;
+	complete_and_exit(&pTask->taskComplete, 0);
+#endif
+	return 0;
+
+}
+
+/*
+========================================================================
+Routine Description:
+    USB command kernel thread.
+
+Arguments:
+	*Context			the pAd, driver control block pointer
+
+Return Value:
+    0					close the thread
+
+Note:
+========================================================================
+*/
+int RTUSBCmdThread(IN void *Context)
+{
+	struct rt_rtmp_adapter *pAd;
+	struct rt_rtmp_os_task *pTask;
+	int status;
+	status = 0;
+
+	pTask = (struct rt_rtmp_os_task *)Context;
+	pAd = (struct rt_rtmp_adapter *)pTask->priv;
+
+	RtmpOSTaskCustomize(pTask);
+
+	NdisAcquireSpinLock(&pAd->CmdQLock);
+	pAd->CmdQ.CmdQState = RTMP_TASK_STAT_RUNNING;
+	NdisReleaseSpinLock(&pAd->CmdQLock);
+
+	while (pAd && pAd->CmdQ.CmdQState == RTMP_TASK_STAT_RUNNING) {
+#ifdef KTHREAD_SUPPORT
+		RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
+#else
+		/* lock the device pointers */
+		RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
+
+		if (status != 0) {
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+			break;
+		}
+#endif
+
+		if (pAd->CmdQ.CmdQState == RTMP_TASK_STAT_STOPED)
+			break;
+
+		if (!pAd->PM_FlgSuspend)
+			CMDHandler(pAd);
+	}
+
+	if (pAd && !pAd->PM_FlgSuspend) {	/* Clear the CmdQElements. */
+		struct rt_cmdqelmt *pCmdQElmt = NULL;
+
+		NdisAcquireSpinLock(&pAd->CmdQLock);
+		pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED;
+		while (pAd->CmdQ.size) {
+			RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt);
+			if (pCmdQElmt) {
+				if (pCmdQElmt->CmdFromNdis == TRUE) {
+					if (pCmdQElmt->buffer != NULL)
+						os_free_mem(pAd,
+							    pCmdQElmt->buffer);
+					os_free_mem(pAd, (u8 *)pCmdQElmt);
+				} else {
+					if ((pCmdQElmt->buffer != NULL)
+					    && (pCmdQElmt->bufferlength != 0))
+						os_free_mem(pAd,
+							    pCmdQElmt->buffer);
+					os_free_mem(pAd, (u8 *)pCmdQElmt);
+				}
+			}
+		}
+
+		NdisReleaseSpinLock(&pAd->CmdQLock);
+	}
+	/* notify the exit routine that we're actually exiting now
+	 *
+	 * complete()/wait_for_completion() is similar to up()/down(),
+	 * except that complete() is safe in the case where the structure
+	 * is getting deleted in a parallel mode of execution (i.e. just
+	 * after the down() -- that's necessary for the thread-shutdown
+	 * case.
+	 *
+	 * complete_and_exit() goes even further than this -- it is safe in
+	 * the case that the thread of the caller is going away (not just
+	 * the structure) -- this is necessary for the module-remove case.
+	 * This is important in preemption kernels, which transfer the flow
+	 * of execution immediately upon a complete().
+	 */
+	DBGPRINT(RT_DEBUG_TRACE, ("<---RTUSBCmdThread\n"));
+
+#ifndef KTHREAD_SUPPORT
+	pTask->taskPID = THREAD_PID_INIT_VALUE;
+	complete_and_exit(&pTask->taskComplete, 0);
+#endif
+	return 0;
+
+}
+
+void RTUSBWatchDog(struct rt_rtmp_adapter *pAd)
+{
+	struct rt_ht_tx_context *pHTTXContext;
+	int idx;
+	unsigned long irqFlags;
+	PURB pUrb;
+	BOOLEAN needDumpSeq = FALSE;
+	u32 MACValue;
+	u32 TxRxQ_Pcnt;
+
+	idx = 0;
+	RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
+	if ((MACValue & 0xff) != 0) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("TX QUEUE 0 Not EMPTY(Value=0x%0x)!\n",
+			  MACValue));
+		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012);
+		while ((MACValue & 0xff) != 0 && (idx++ < 10)) {
+			RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
+			RTMPusecDelay(1);
+		}
+		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
+	}
+
+	if (pAd->watchDogRxOverFlowCnt >= 2) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n"));
+		if ((!RTMP_TEST_FLAG
+		     (pAd,
+		      (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+		       fRTMP_ADAPTER_BULKIN_RESET |
+		       fRTMP_ADAPTER_HALT_IN_PROGRESS |
+		       fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n"));
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN,
+						NULL, 0);
+			needDumpSeq = TRUE;
+		}
+		pAd->watchDogRxOverFlowCnt = 0;
+	}
+
+	RTUSBReadMACRegister(pAd, 0x438, &TxRxQ_Pcnt);
+
+	for (idx = 0; idx < NUM_OF_TX_RING; idx++) {
+		pUrb = NULL;
+
+		RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags);
+		if ((pAd->BulkOutPending[idx] == TRUE)
+		    && pAd->watchDogTxPendingCnt) {
+			int actual_length = 0, transfer_buffer_length = 0;
+			BOOLEAN isDataPacket = FALSE;
+			pAd->watchDogTxPendingCnt[idx]++;
+
+			if ((pAd->watchDogTxPendingCnt[idx] > 2) &&
+			    (!RTMP_TEST_FLAG
+			     (pAd,
+			      (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+			       fRTMP_ADAPTER_HALT_IN_PROGRESS |
+			       fRTMP_ADAPTER_NIC_NOT_EXIST |
+			       fRTMP_ADAPTER_BULKOUT_RESET)))
+			    ) {
+				/* FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it! */
+				pHTTXContext =
+				    (struct rt_ht_tx_context *)(&pAd->TxContext[idx]);
+				if (pHTTXContext->IRPPending) {	/* Check TxContext. */
+					pUrb = pHTTXContext->pUrb;
+
+					actual_length = pUrb->actual_length;
+					transfer_buffer_length =
+					    pUrb->transfer_buffer_length;
+					isDataPacket = TRUE;
+				} else if (idx == MGMTPIPEIDX) {
+					struct rt_tx_context *pMLMEContext, *pNULLContext,
+					    *pPsPollContext;
+
+					/*Check MgmtContext. */
+					pMLMEContext =
+					    (struct rt_tx_context *)(pAd->MgmtRing.
+							   Cell[pAd->MgmtRing.
+								TxDmaIdx].
+							   AllocVa);
+					pPsPollContext =
+					    (struct rt_tx_context *)(&pAd->PsPollContext);
+					pNULLContext =
+					    (struct rt_tx_context *)(&pAd->NullContext);
+
+					if (pMLMEContext->IRPPending) {
+						ASSERT(pMLMEContext->
+						       IRPPending);
+						pUrb = pMLMEContext->pUrb;
+					} else if (pNULLContext->IRPPending) {
+						ASSERT(pNULLContext->
+						       IRPPending);
+						pUrb = pNULLContext->pUrb;
+					} else if (pPsPollContext->IRPPending) {
+						ASSERT(pPsPollContext->
+						       IRPPending);
+						pUrb = pPsPollContext->pUrb;
+					}
+				}
+
+				RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx],
+						irqFlags);
+
+				printk(KERN_INFO "%d:%lu LTL=%d , TL=%d L:%d\n",
+				       idx, pAd->watchDogTxPendingCnt[idx],
+				       pAd->TransferedLength[idx],
+				       actual_length, transfer_buffer_length);
+
+				if (pUrb) {
+					if ((isDataPacket
+					     && pAd->TransferedLength[idx] ==
+					     actual_length
+					     && pAd->TransferedLength[idx] <
+					     transfer_buffer_length
+					     && actual_length != 0
+/*                                      && TxRxQ_Pcnt==0 */
+					     && pAd->watchDogTxPendingCnt[idx] >
+					     3)
+					    || isDataPacket == FALSE
+					    || pAd->watchDogTxPendingCnt[idx] >
+					    6) {
+						DBGPRINT(RT_DEBUG_TRACE,
+							 ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n",
+							  idx));
+						DBGPRINT(RT_DEBUG_TRACE,
+							 ("Unlink the pending URB!\n"));
+						/* unlink it now */
+						RTUSB_UNLINK_URB(pUrb);
+						/* Sleep 200 microseconds to give cancellation time to work */
+						/*RTMPusecDelay(200); */
+						needDumpSeq = TRUE;
+					}
+				} else {
+					DBGPRINT(RT_DEBUG_ERROR,
+						 ("Unknown bulkOut URB maybe hanged!\n"));
+				}
+			} else {
+				RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx],
+						irqFlags);
+			}
+
+			if (isDataPacket == TRUE)
+				pAd->TransferedLength[idx] = actual_length;
+		} else {
+			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
+		}
+	}
+
+	/* For Sigma debug, dump the ba_reordering sequence. */
+	if ((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0)) {
+		u16 Idx;
+		struct rt_ba_rec_entry *pBAEntry = NULL;
+		u8 count = 0;
+		struct reordering_mpdu *mpdu_blk;
+
+		Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0];
+
+		pBAEntry = &pAd->BATable.BARecEntry[Idx];
+		if ((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL)) {
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n"));
+			NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
+			mpdu_blk = pBAEntry->list.next;
+			while (mpdu_blk) {
+				DBGPRINT(RT_DEBUG_TRACE,
+					 ("\t%d:Seq-%d, bAMSDU-%d!\n", count,
+					  mpdu_blk->Sequence,
+					  mpdu_blk->bAMSDU));
+				mpdu_blk = mpdu_blk->next;
+				count++;
+			}
+
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("\npBAEntry->LastIndSeq=%d!\n",
+				  pBAEntry->LastIndSeq));
+			NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
+		}
+	}
+}
+
+/*
+========================================================================
+Routine Description:
+    Release allocated resources.
+
+Arguments:
+    *dev				Point to the PCI or USB device
+	pAd					driver control block pointer
+
+Return Value:
+    None
+
+Note:
+========================================================================
+*/
+static void rt2870_disconnect(struct usb_device *dev, struct rt_rtmp_adapter *pAd)
+{
+	DBGPRINT(RT_DEBUG_ERROR,
+		 ("rtusb_disconnect: unregister usbnet usb-%s-%s\n",
+		  dev->bus->bus_name, dev->devpath));
+	if (!pAd) {
+		usb_put_dev(dev);
+		printk("rtusb_disconnect: pAd == NULL!\n");
+		return;
+	}
+	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
+
+	/* for debug, wait to show some messages to /proc system */
+	udelay(1);
+
+	RtmpPhyNetDevExit(pAd, pAd->net_dev);
+
+	/* FIXME: Shall we need following delay and flush the schedule?? */
+	udelay(1);
+	flush_scheduled_work();
+	udelay(1);
+
+	/* free the root net_device */
+	RtmpOSNetDevFree(pAd->net_dev);
+
+	RtmpRaDevCtrlExit(pAd);
+
+	/* release a use of the usb device structure */
+	usb_put_dev(dev);
+	udelay(1);
+
+	DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n"));
+}
+
+static int __devinit rt2870_probe(IN struct usb_interface *intf,
+				  IN struct usb_device *usb_dev,
+				  IN const struct usb_device_id *dev_id,
+				  struct rt_rtmp_adapter ** ppAd)
+{
+	struct net_device *net_dev = NULL;
+	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)NULL;
+	int status, rv;
+	void *handle;
+	struct rt_rtmp_os_netdev_op_hook netDevHook;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===>rt2870_probe()!\n"));
+
+	/* Check chipset vendor/product ID */
+	/*if (RT28XXChipsetCheck(_dev_p) == FALSE) */
+	/*      goto err_out; */
+
+/*RtmpDevInit============================================= */
+	/* Allocate struct rt_rtmp_adapter adapter structure */
+	handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL);
+	if (handle == NULL) {
+		printk
+		    ("rt2870_probe(): Allocate memory for os handle failed!\n");
+		return -ENOMEM;
+	}
+	((struct os_cookie *)handle)->pUsb_Dev = usb_dev;
+
+	rv = RTMPAllocAdapterBlock(handle, &pAd);
+	if (rv != NDIS_STATUS_SUCCESS) {
+		kfree(handle);
+		goto err_out;
+	}
+/*USBDevInit============================================== */
+	if (USBDevConfigInit(usb_dev, intf, pAd) == FALSE)
+		goto err_out_free_radev;
+
+	RtmpRaDevCtrlInit(pAd, RTMP_DEV_INF_USB);
+
+/*NetDevInit============================================== */
+	net_dev = RtmpPhyNetDevInit(pAd, &netDevHook);
+	if (net_dev == NULL)
+		goto err_out_free_radev;
+
+	/* Here are the net_device structure with usb specific parameters. */
+	/* for supporting Network Manager.
+	 * Set the sysfs physical device reference for the network logical device if set prior to registration will
+	 * cause a symlink during initialization.
+	 */
+	SET_NETDEV_DEV(net_dev, &(usb_dev->dev));
+
+	pAd->StaCfg.OriDevType = net_dev->type;
+
+/*All done, it's time to register the net device to linux kernel. */
+	/* Register this device */
+	status = RtmpOSNetDevAttach(net_dev, &netDevHook);
+	if (status != 0)
+		goto err_out_free_netdev;
+
+#ifdef KTHREAD_SUPPORT
+	init_waitqueue_head(&pAd->mlmeTask.kthread_q);
+	init_waitqueue_head(&pAd->timerTask.kthread_q);
+	init_waitqueue_head(&pAd->cmdQTask.kthread_q);
+#endif
+
+	*ppAd = pAd;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<===rt2870_probe()!\n"));
+
+	return 0;
+
+	/* --------------------------- ERROR HANDLE --------------------------- */
+err_out_free_netdev:
+	RtmpOSNetDevFree(net_dev);
+
+err_out_free_radev:
+	RTMPFreeAdapter(pAd);
+
+err_out:
+	*ppAd = NULL;
+
+	return -1;
+
+}
diff --git a/drivers/staging/rt2860/wpa.h b/drivers/staging/rt2860/wpa.h
index 7006e38..6199ae6 100644
--- a/drivers/staging/rt2860/wpa.h
+++ b/drivers/staging/rt2860/wpa.h
@@ -38,7 +38,7 @@
 #ifndef	__WPA_H__
 #define	__WPA_H__
 
-// EAPOL Key descripter frame format related length
+/* EAPOL Key descripter frame format related length */
 #define LEN_KEY_DESC_NONCE			32
 #define LEN_KEY_DESC_IV				16
 #define LEN_KEY_DESC_RSC			8
@@ -46,39 +46,38 @@
 #define LEN_KEY_DESC_REPLAY			8
 #define LEN_KEY_DESC_MIC			16
 
-// The length is the EAPoL-Key frame except key data field.
-// Please refer to 802.11i-2004 ,Figure 43u in p.78
-#define LEN_EAPOL_KEY_MSG			(sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE)
+/* The length is the EAPoL-Key frame except key data field. */
+/* Please refer to 802.11i-2004 ,Figure 43u in p.78 */
+#define LEN_EAPOL_KEY_MSG			(sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE)
 
-// EAP Code Type.
+/* EAP Code Type. */
 #define EAP_CODE_REQUEST	1
 #define EAP_CODE_RESPONSE	2
 #define EAP_CODE_SUCCESS    3
 #define EAP_CODE_FAILURE    4
 
-// EAPOL frame Protocol Version
+/* EAPOL frame Protocol Version */
 #define	EAPOL_VER					1
 #define	EAPOL_VER2					2
 
-// EAPOL-KEY Descriptor Type
+/* EAPOL-KEY Descriptor Type */
 #define	WPA1_KEY_DESC				0xfe
 #define WPA2_KEY_DESC               0x02
 
-// Key Descriptor Version of Key Information
+/* Key Descriptor Version of Key Information */
 #define	DESC_TYPE_TKIP				1
 #define	DESC_TYPE_AES				2
-#define DESC_TYPE_MESH				3
 
 #define LEN_MSG1_2WAY               0x7f
 #define MAX_LEN_OF_EAP_HS           256
 
 #define LEN_MASTER_KEY				32
 
-// EAPOL EK, MK
+/* EAPOL EK, MK */
 #define LEN_EAP_EK					16
 #define LEN_EAP_MICK				16
 #define LEN_EAP_KEY					((LEN_EAP_EK)+(LEN_EAP_MICK))
-// TKIP key related
+/* TKIP key related */
 #define LEN_PMKID					16
 #define LEN_TKIP_EK					16
 #define LEN_TKIP_RXMICK				8
@@ -90,12 +89,18 @@
 #define TKIP_AP_RXMICK_OFFSET		(TKIP_AP_TXMICK_OFFSET+LEN_TKIP_TXMICK)
 #define TKIP_GTK_LENGTH				((LEN_TKIP_EK)+(LEN_TKIP_RXMICK)+(LEN_TKIP_TXMICK))
 #define LEN_PTK						((LEN_EAP_KEY)+(LEN_TKIP_KEY))
+#define MIN_LEN_OF_GTK				5
+#define LEN_PMK						32
+#define LEN_PMK_NAME				16
+#define LEN_NONCE					32
 
-// RSN IE Length definition
-#define MAX_LEN_OF_RSNIE         	90
+/* RSN IE Length definition */
+#define MAX_LEN_OF_RSNIE		255
 #define MIN_LEN_OF_RSNIE         	8
 
-//EAP Packet Type
+#define KEY_LIFETIME				3600
+
+/*EAP Packet Type */
 #define	EAPPacket		0
 #define	EAPOLStart		1
 #define	EAPOLLogoff		2
@@ -114,11 +119,33 @@
 #define PAIRWISEKEY					1
 #define GROUPKEY					0
 
-// Retry timer counter initial value
+/* Retry timer counter initial value */
 #define PEER_MSG1_RETRY_TIMER_CTR           0
 #define PEER_MSG3_RETRY_TIMER_CTR           10
 #define GROUP_MSG1_RETRY_TIMER_CTR          20
 
+/*#ifdef CONFIG_AP_SUPPORT */
+/* WPA mechanism retry timer interval */
+#define PEER_MSG1_RETRY_EXEC_INTV           1000	/* 1 sec */
+#define PEER_MSG3_RETRY_EXEC_INTV           3000	/* 3 sec */
+#define GROUP_KEY_UPDATE_EXEC_INTV          1000	/* 1 sec */
+#define PEER_GROUP_KEY_UPDATE_INIV			2000	/* 2 sec */
+
+#define ENQUEUE_EAPOL_START_TIMER			200	/* 200 ms */
+
+/* group rekey interval */
+#define TIME_REKEY                          0
+#define PKT_REKEY                           1
+#define DISABLE_REKEY                       2
+#define MAX_REKEY                           2
+
+#define MAX_REKEY_INTER                     0x3ffffff
+/*#endif // CONFIG_AP_SUPPORT // */
+
+#define GROUP_SUITE					0
+#define PAIRWISE_SUITE				1
+#define AKM_SUITE					2
+#define PMKID_LIST					3
 
 #define EAPOL_START_DISABLE					0
 #define EAPOL_START_PSK						1
@@ -129,12 +156,33 @@
 #define MIX_CIPHER_WPA2_TKIP_ON(x)      (((x) & 0x02) != 0)
 #define MIX_CIPHER_WPA2_AES_ON(x)       (((x) & 0x01) != 0)
 
+#ifndef ROUND_UP
 #define ROUND_UP(__x, __y) \
-	(((ULONG)((__x)+((__y)-1))) & ((ULONG)~((__y)-1)))
+	(((unsigned long)((__x)+((__y)-1))) & ((unsigned long)~((__y)-1)))
+#endif
+
+#define	SET_u16_TO_ARRARY(_V, _LEN)		\
+{											\
+	_V[0] = (_LEN & 0xFF00) >> 8;			\
+	_V[1] = (_LEN & 0xFF);					\
+}
+
+#define	INC_u16_TO_ARRARY(_V, _LEN)			\
+{												\
+	u16	var_len;							\
+												\
+	var_len = (_V[0]<<8) | (_V[1]);				\
+	var_len += _LEN;							\
+												\
+	_V[0] = (var_len & 0xFF00) >> 8;			\
+	_V[1] = (var_len & 0xFF);					\
+}
+
+#define	CONV_ARRARY_TO_u16(_V)	((_V[0]<<8) | (_V[1]))
 
 #define	ADD_ONE_To_64BIT_VAR(_V)		\
 {										\
-	UCHAR	cnt = LEN_KEY_DESC_REPLAY;	\
+	u8	cnt = LEN_KEY_DESC_REPLAY;	\
 	do									\
 	{									\
 		cnt--;							\
@@ -146,182 +194,200 @@
 
 #define IS_WPA_CAPABILITY(a)       (((a) >= Ndis802_11AuthModeWPA) && ((a) <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
 
-// EAPOL Key Information definition within Key descriptor format
-typedef	struct PACKED _KEY_INFO
-{
-	UCHAR	KeyMic:1;
-	UCHAR	Secure:1;
-	UCHAR	Error:1;
-	UCHAR	Request:1;
-	UCHAR	EKD_DL:1;       // EKD for AP; DL for STA
-	UCHAR	Rsvd:3;
-	UCHAR	KeyDescVer:3;
-	UCHAR	KeyType:1;
-	UCHAR	KeyIndex:2;
-	UCHAR	Install:1;
-	UCHAR	KeyAck:1;
-}	KEY_INFO, *PKEY_INFO;
+/* EAPOL Key Information definition within Key descriptor format */
+struct PACKED rt_key_info {
+	u8 KeyMic:1;
+	u8 Secure:1;
+	u8 Error:1;
+	u8 Request:1;
+	u8 EKD_DL:1;		/* EKD for AP; DL for STA */
+	u8 Rsvd:3;
+	u8 KeyDescVer:3;
+	u8 KeyType:1;
+	u8 KeyIndex:2;
+	u8 Install:1;
+	u8 KeyAck:1;
+};
 
-// EAPOL Key descriptor format
-typedef	struct PACKED _KEY_DESCRIPTER
-{
-	UCHAR		Type;
-	KEY_INFO	KeyInfo;
-	UCHAR		KeyLength[2];
-	UCHAR		ReplayCounter[LEN_KEY_DESC_REPLAY];
-	UCHAR		KeyNonce[LEN_KEY_DESC_NONCE];
-	UCHAR		KeyIv[LEN_KEY_DESC_IV];
-	UCHAR		KeyRsc[LEN_KEY_DESC_RSC];
-	UCHAR		KeyId[LEN_KEY_DESC_ID];
-	UCHAR		KeyMic[LEN_KEY_DESC_MIC];
-	UCHAR		KeyDataLen[2];
-	UCHAR		KeyData[MAX_LEN_OF_RSNIE];
-}	KEY_DESCRIPTER, *PKEY_DESCRIPTER;
+/* EAPOL Key descriptor format */
+struct PACKED rt_key_descripter {
+	u8 Type;
+	struct rt_key_info KeyInfo;
+	u8 KeyLength[2];
+	u8 ReplayCounter[LEN_KEY_DESC_REPLAY];
+	u8 KeyNonce[LEN_KEY_DESC_NONCE];
+	u8 KeyIv[LEN_KEY_DESC_IV];
+	u8 KeyRsc[LEN_KEY_DESC_RSC];
+	u8 KeyId[LEN_KEY_DESC_ID];
+	u8 KeyMic[LEN_KEY_DESC_MIC];
+	u8 KeyDataLen[2];
+	u8 KeyData[MAX_LEN_OF_RSNIE];
+};
 
-typedef	struct PACKED _EAPOL_PACKET
-{
-	UCHAR	 			ProVer;
-	UCHAR	 			ProType;
-	UCHAR	 			Body_Len[2];
-	KEY_DESCRIPTER		KeyDesc;
-}	EAPOL_PACKET, *PEAPOL_PACKET;
+struct PACKED rt_eapol_packet {
+	u8 ProVer;
+	u8 ProType;
+	u8 Body_Len[2];
+	struct rt_key_descripter KeyDesc;
+};
 
-//802.11i D10 page 83
-typedef struct PACKED _GTK_ENCAP
-{
-    UCHAR               Kid:2;
-    UCHAR               tx:1;
-    UCHAR               rsv:5;
-    UCHAR               rsv1;
-    UCHAR               GTK[TKIP_GTK_LENGTH];
-}   GTK_ENCAP, *PGTK_ENCAP;
+/*802.11i D10 page 83 */
+struct PACKED rt_gtk_encap {
+	u8 Kid:2;
+	u8 tx:1;
+	u8 rsv:5;
+	u8 rsv1;
+	u8 GTK[TKIP_GTK_LENGTH];
+};
 
-typedef struct PACKED _KDE_ENCAP
-{
-    UCHAR               Type;
-    UCHAR               Len;
-    UCHAR               OUI[3];
-    UCHAR               DataType;
-    GTK_ENCAP      GTKEncap;
-}   KDE_ENCAP, *PKDE_ENCAP;
+struct PACKED rt_kde_encap {
+	u8 Type;
+	u8 Len;
+	u8 OUI[3];
+	u8 DataType;
+	struct rt_gtk_encap GTKEncap;
+};
 
-// For WPA1
-typedef struct PACKED _RSNIE {
-    UCHAR   oui[4];
-    USHORT  version;
-    UCHAR   mcast[4];
-    USHORT  ucount;
-    struct PACKED {
-        UCHAR oui[4];
-    }ucast[1];
-} RSNIE, *PRSNIE;
+/* For WPA1 */
+struct PACKED rt_rsnie {
+	u8 oui[4];
+	u16 version;
+	u8 mcast[4];
+	u16 ucount;
+	struct PACKED {
+		u8 oui[4];
+	} ucast[1];
+};
 
-// For WPA2
-typedef struct PACKED _RSNIE2 {
-    USHORT  version;
-    UCHAR   mcast[4];
-    USHORT  ucount;
-    struct PACKED {
-        UCHAR oui[4];
-    }ucast[1];
-} RSNIE2, *PRSNIE2;
+/* For WPA2 */
+struct PACKED rt_rsnie2 {
+	u16 version;
+	u8 mcast[4];
+	u16 ucount;
+	struct PACKED {
+		u8 oui[4];
+	} ucast[1];
+};
 
-// AKM Suite
-typedef struct PACKED _RSNIE_AUTH {
-    USHORT acount;
-    struct PACKED {
-        UCHAR oui[4];
-    }auth[1];
-} RSNIE_AUTH,*PRSNIE_AUTH;
+/* AKM Suite */
+struct PACKED rt_rsnie_auth {
+	u16 acount;
+	struct PACKED {
+		u8 oui[4];
+	} auth[1];
+};
 
-typedef	union PACKED _RSN_CAPABILITIES	{
-	struct	PACKED {
-        USHORT		PreAuth:1;
-		USHORT		No_Pairwise:1;
-		USHORT		PTKSA_R_Counter:2;
-		USHORT		GTKSA_R_Counter:2;
-		USHORT		Rsvd:10;
-	}	field;
-	USHORT			word;
-}	RSN_CAPABILITIES, *PRSN_CAPABILITIES;
+typedef union PACKED _RSN_CAPABILITIES {
+	struct PACKED {
+		u16 PreAuth:1;
+		u16 No_Pairwise:1;
+		u16 PTKSA_R_Counter:2;
+		u16 GTKSA_R_Counter:2;
+		u16 Rsvd:10;
+	} field;
+	u16 word;
+} RSN_CAPABILITIES, *PRSN_CAPABILITIES;
 
-typedef struct PACKED _EAP_HDR {
-    UCHAR   ProVer;
-    UCHAR   ProType;
-    UCHAR   Body_Len[2];
-    UCHAR   code;
-    UCHAR   identifier;
-    UCHAR   length[2]; // including code and identifier, followed by length-2 octets of data
-} EAP_HDR, *PEAP_HDR;
+struct PACKED rt_eap_hdr {
+	u8 ProVer;
+	u8 ProType;
+	u8 Body_Len[2];
+	u8 code;
+	u8 identifier;
+	u8 length[2];	/* including code and identifier, followed by length-2 octets of data */
+};
 
-// For supplicant state machine states. 802.11i Draft 4.1, p. 97
-// We simplified it
-typedef	enum	_WpaState
-{
-	SS_NOTUSE,				// 0
-	SS_START,				// 1
-	SS_WAIT_MSG_3,			// 2
-	SS_WAIT_GROUP,			// 3
-	SS_FINISH,  			// 4
-	SS_KEYUPDATE,			// 5
-}	WPA_STATE;
+/* For supplicant state machine states. 802.11i Draft 4.1, p. 97 */
+/* We simplified it */
+typedef enum _WpaState {
+	SS_NOTUSE,		/* 0 */
+	SS_START,		/* 1 */
+	SS_WAIT_MSG_3,		/* 2 */
+	SS_WAIT_GROUP,		/* 3 */
+	SS_FINISH,		/* 4 */
+	SS_KEYUPDATE,		/* 5 */
+} WPA_STATE;
 
-//
-//	The definition of the cipher combination
-//
-// 	 bit3	bit2  bit1   bit0
-//	+------------+------------+
-// 	|	  WPA	 |	   WPA2   |
-//	+------+-----+------+-----+
-//	| TKIP | AES | TKIP | AES |
-//	|	0  |  1  |   1  |  0  | -> 0x06
-//	|	0  |  1  |   1  |  1  | -> 0x07
-//	|	1  |  0  |   0  |  1  | -> 0x09
-//	|	1  |  0  |   1  |  1  | -> 0x0B
-//	|	1  |  1  |   0  |  1  | -> 0x0D
-//	|	1  |  1  |   1  |  0  | -> 0x0E
-//	|	1  |  1  |   1  |  1  |	-> 0x0F
-//	+------+-----+------+-----+
-//
-typedef	enum	_WpaMixPairCipher
-{
-	MIX_CIPHER_NOTUSE 			= 0x00,
-	WPA_NONE_WPA2_TKIPAES		= 0x03,		// WPA2-TKIPAES
-	WPA_AES_WPA2_TKIP 			= 0x06,
-	WPA_AES_WPA2_TKIPAES		= 0x07,
-	WPA_TKIP_WPA2_AES			= 0x09,
-	WPA_TKIP_WPA2_TKIPAES		= 0x0B,
-	WPA_TKIPAES_WPA2_NONE		= 0x0C,		// WPA-TKIPAES
-	WPA_TKIPAES_WPA2_AES		= 0x0D,
-	WPA_TKIPAES_WPA2_TKIP		= 0x0E,
-	WPA_TKIPAES_WPA2_TKIPAES	= 0x0F,
-}	WPA_MIX_PAIR_CIPHER;
+/* */
+/*      The definition of the cipher combination */
+/* */
+/*       bit3   bit2  bit1   bit0 */
+/*      +------------+------------+ */
+/*      |         WPA    |         WPA2   | */
+/*      +------+-----+------+-----+ */
+/*      | TKIP | AES | TKIP | AES | */
+/*      |       0  |  1  |   1  |  0  | -> 0x06 */
+/*      |       0  |  1  |   1  |  1  | -> 0x07 */
+/*      |       1  |  0  |   0  |  1  | -> 0x09 */
+/*      |       1  |  0  |   1  |  1  | -> 0x0B */
+/*      |       1  |  1  |   0  |  1  | -> 0x0D */
+/*      |       1  |  1  |   1  |  0  | -> 0x0E */
+/*      |       1  |  1  |   1  |  1  | -> 0x0F */
+/*      +------+-----+------+-----+ */
+/* */
+typedef enum _WpaMixPairCipher {
+	MIX_CIPHER_NOTUSE = 0x00,
+	WPA_NONE_WPA2_TKIPAES = 0x03,	/* WPA2-TKIPAES */
+	WPA_AES_WPA2_TKIP = 0x06,
+	WPA_AES_WPA2_TKIPAES = 0x07,
+	WPA_TKIP_WPA2_AES = 0x09,
+	WPA_TKIP_WPA2_TKIPAES = 0x0B,
+	WPA_TKIPAES_WPA2_NONE = 0x0C,	/* WPA-TKIPAES */
+	WPA_TKIPAES_WPA2_AES = 0x0D,
+	WPA_TKIPAES_WPA2_TKIP = 0x0E,
+	WPA_TKIPAES_WPA2_TKIPAES = 0x0F,
+} WPA_MIX_PAIR_CIPHER;
 
-typedef struct PACKED _RSN_IE_HEADER_STRUCT	{
-	UCHAR		Eid;
-	UCHAR		Length;
-	USHORT		Version;	// Little endian format
-}	RSN_IE_HEADER_STRUCT, *PRSN_IE_HEADER_STRUCT;
+struct PACKED rt_rsn_ie_header {
+	u8 Eid;
+	u8 Length;
+	u16 Version;		/* Little endian format */
+};
 
-// Cipher suite selector types
-typedef struct PACKED _CIPHER_SUITE_STRUCT	{
-	UCHAR		Oui[3];
-	UCHAR		Type;
-}	CIPHER_SUITE_STRUCT, *PCIPHER_SUITE_STRUCT;
+/* Cipher suite selector types */
+struct PACKED rt_cipher_suite_struct {
+	u8 Oui[3];
+	u8 Type;
+};
 
-// Authentication and Key Management suite selector
-typedef struct PACKED _AKM_SUITE_STRUCT	{
-	UCHAR		Oui[3];
-	UCHAR		Type;
-}	AKM_SUITE_STRUCT, *PAKM_SUITE_STRUCT;
+/* Authentication and Key Management suite selector */
+struct PACKED rt_akm_suite {
+	u8 Oui[3];
+	u8 Type;
+};
 
-// RSN capability
-typedef struct	PACKED _RSN_CAPABILITY	{
-	USHORT		Rsv:10;
-	USHORT		GTKSAReplayCnt:2;
-	USHORT		PTKSAReplayCnt:2;
-	USHORT		NoPairwise:1;
-	USHORT		PreAuth:1;
-}	RSN_CAPABILITY, *PRSN_CAPABILITY;
+/* RSN capability */
+struct PACKED rt_rsn_capability {
+	u16 Rsv:10;
+	u16 GTKSAReplayCnt:2;
+	u16 PTKSAReplayCnt:2;
+	u16 NoPairwise:1;
+	u16 PreAuth:1;
+};
+
+/*========================================
+	The prototype is defined in cmm_wpa.c
+  ========================================*/
+BOOLEAN WpaMsgTypeSubst(u8 EAPType, int * MsgType);
+
+void PRF(u8 * key,
+	 int key_len,
+	 u8 * prefix,
+	 int prefix_len,
+	 u8 * data, int data_len, u8 * output, int len);
+
+int PasswordHash(char *password,
+		 unsigned char *ssid, int ssidlength, unsigned char *output);
+
+u8 *GetSuiteFromRSNIE(u8 *rsnie,
+			 u32 rsnie_len, u8 type, u8 * count);
+
+void WpaShowAllsuite(u8 *rsnie, u32 rsnie_len);
+
+void RTMPInsertRSNIE(u8 *pFrameBuf,
+		     unsigned long *pFrameLen,
+		     u8 *rsnie_ptr,
+		     u8 rsnie_len,
+		     u8 *pmkid_ptr, u8 pmkid_len);
 
 #endif
diff --git a/drivers/staging/rt2870/2870_main_dev.c b/drivers/staging/rt2870/2870_main_dev.c
deleted file mode 100644
index d0ed48b..0000000
--- a/drivers/staging/rt2870/2870_main_dev.c
+++ /dev/null
@@ -1,1530 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    rtmp_main.c
-
-    Abstract:
-    main initialization routines
-
-    Revision History:
-    Who         When            What
-    --------    ----------      ----------------------------------------------
-    Name        Date            Modification logs
-    Jan Lee		01-10-2005	    modified
-	Sample		Jun/01/07		Merge RT2870 and RT2860 drivers.
-*/
-
-#include "rt_config.h"
-
-
-// Following information will be show when you run 'modinfo'
-// *** If you have a solution for the bug in current version of driver, please mail to me.
-// Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. ***
-MODULE_AUTHOR("Paul Lin <paul_lin@ralinktech.com>");
-MODULE_DESCRIPTION(RT28xx_CHIP_NAME " Wireless LAN Linux Driver");
-MODULE_LICENSE("GPL");
-#ifdef MODULE_VERSION
-MODULE_VERSION(STA_DRIVER_VERSION);
-#endif
-MODULE_ALIAS("rt3070sta");
-
-/* Kernel thread and vars, which handles packets that are completed. Only
- * packets that have a "complete" function are sent here. This way, the
- * completion is run out of kernel context, and doesn't block the rest of
- * the stack. */
-
-extern INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
-									IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
-
-struct usb_device_id rtusb_usb_id[] = {
-	{ USB_DEVICE(0x148F, 0x2770) }, /* Ralink */
-	{ USB_DEVICE(0x1737, 0x0071) }, /* Linksys WUSB600N */
-	{ USB_DEVICE(0x1737, 0x0070) }, /* Linksys */
-	{ USB_DEVICE(0x148F, 0x2870) }, /* Ralink */
-	{ USB_DEVICE(0x148F, 0x3070) }, /* Ralink 3070 */
-	{ USB_DEVICE(0x148F, 0x3071) }, /* Ralink 3071 */
-	{ USB_DEVICE(0x148F, 0x3072) }, /* Ralink 3072 */
-	{ USB_DEVICE(0x0B05, 0x1731) }, /* Asus */
-	{ USB_DEVICE(0x0B05, 0x1732) }, /* Asus */
-	{ USB_DEVICE(0x0B05, 0x1742) }, /* Asus */
-	{ USB_DEVICE(0x0DF6, 0x0017) }, /* Sitecom */
-	{ USB_DEVICE(0x0DF6, 0x002B) }, /* Sitecom */
-	{ USB_DEVICE(0x0DF6, 0x002C) }, /* Sitecom */
-	{ USB_DEVICE(0x0DF6, 0x003E) }, /* Sitecom 3070 */
-	{ USB_DEVICE(0x0DF6, 0x002D) }, /* Sitecom */
-	{ USB_DEVICE(0x0DF6, 0x0039) }, /* Sitecom 2770 */
-	{ USB_DEVICE(0x0DF6, 0x003F) }, /* Sitecom WL-608 */
-	{ USB_DEVICE(0x14B2, 0x3C06) }, /* Conceptronic */
-	{ USB_DEVICE(0x14B2, 0x3C28) }, /* Conceptronic */
-	{ USB_DEVICE(0x2019, 0xED06) }, /* Planex Communications, Inc. */
-	{ USB_DEVICE(0x2019, 0xED14) }, /* Planex Communications, Inc. */
-	{ USB_DEVICE(0x2019, 0xAB25) }, /* Planex Communications, Inc. RT3070 */
-	{ USB_DEVICE(0x07D1, 0x3C09) }, /* D-Link */
-	{ USB_DEVICE(0x07D1, 0x3C11) }, /* D-Link */
-	{ USB_DEVICE(0x2001, 0x3C09) }, /* D-Link */
-	{ USB_DEVICE(0x2001, 0x3C0A) }, /* D-Link 3072*/
-	{ USB_DEVICE(0x14B2, 0x3C07) }, /* AL */
-	{ USB_DEVICE(0x14B2, 0x3C12) }, /* AL 3070 */
-	{ USB_DEVICE(0x050D, 0x8053) }, /* Belkin */
-	{ USB_DEVICE(0x050D, 0x815C) }, /* Belkin */
-	{ USB_DEVICE(0x050D, 0x825a) }, /* Belkin */
-	{ USB_DEVICE(0x14B2, 0x3C23) }, /* Airlink */
-	{ USB_DEVICE(0x14B2, 0x3C27) }, /* Airlink */
-	{ USB_DEVICE(0x07AA, 0x002F) }, /* Corega */
-	{ USB_DEVICE(0x07AA, 0x003C) }, /* Corega */
-	{ USB_DEVICE(0x07AA, 0x003F) }, /* Corega */
-	{ USB_DEVICE(0x18C5, 0x0012) }, /* Corega 3070 */
-	{ USB_DEVICE(0x1044, 0x800B) }, /* Gigabyte */
-	{ USB_DEVICE(0x1044, 0x800D) }, /* Gigabyte GN-WB32L 3070 */
-	{ USB_DEVICE(0x15A9, 0x0006) }, /* Sparklan */
-	{ USB_DEVICE(0x083A, 0xB522) }, /* SMC */
-	{ USB_DEVICE(0x083A, 0xA618) }, /* SMC */
-	{ USB_DEVICE(0x083A, 0x8522) }, /* Arcadyan */
-	{ USB_DEVICE(0x083A, 0x7512) }, /* Arcadyan 2770 */
-	{ USB_DEVICE(0x083A, 0x7522) }, /* Arcadyan */
-	{ USB_DEVICE(0x083A, 0x7511) }, /* Arcadyan 3070 */
-	{ USB_DEVICE(0x0CDE, 0x0022) }, /* ZCOM */
-	{ USB_DEVICE(0x0586, 0x3416) }, /* Zyxel */
-	{ USB_DEVICE(0x0CDE, 0x0025) }, /* Zyxel */
-	{ USB_DEVICE(0x1740, 0x9701) }, /* EnGenius */
-	{ USB_DEVICE(0x1740, 0x9702) }, /* EnGenius */
-	{ USB_DEVICE(0x1740, 0x9703) }, /* EnGenius 3070 */
-	{ USB_DEVICE(0x0471, 0x200f) }, /* Philips */
-	{ USB_DEVICE(0x14B2, 0x3C25) }, /* Draytek */
-	{ USB_DEVICE(0x13D3, 0x3247) }, /* AzureWave */
-	{ USB_DEVICE(0x13D3, 0x3273) }, /* AzureWave 3070*/
-	{ USB_DEVICE(0x083A, 0x6618) }, /* Accton */
-	{ USB_DEVICE(0x15c5, 0x0008) }, /* Amit */
-	{ USB_DEVICE(0x0E66, 0x0001) }, /* Hawking */
-	{ USB_DEVICE(0x0E66, 0x0003) }, /* Hawking */
-	{ USB_DEVICE(0x129B, 0x1828) }, /* Siemens */
-	{ USB_DEVICE(0x157E, 0x300E) }, /* U-Media */
-	{ USB_DEVICE(0x050d, 0x805c) },
-	{ USB_DEVICE(0x1482, 0x3C09) }, /* Abocom*/
-	{ USB_DEVICE(0x14B2, 0x3C09) }, /* Alpha */
-	{ USB_DEVICE(0x04E8, 0x2018) }, /* samsung */
-	{ USB_DEVICE(0x07B8, 0x3070) }, /* AboCom 3070 */
-	{ USB_DEVICE(0x07B8, 0x3071) }, /* AboCom 3071 */
-	{ USB_DEVICE(0x07B8, 0x2870) }, /* AboCom */
-	{ USB_DEVICE(0x07B8, 0x2770) }, /* AboCom */
-	{ USB_DEVICE(0x07B8, 0x3072) }, /* Abocom 3072 */
-	{ USB_DEVICE(0x7392, 0x7711) }, /* Edimax 3070 */
-	{ USB_DEVICE(0x5A57, 0x0280) }, /* Zinwell */
-	{ USB_DEVICE(0x5A57, 0x0282) }, /* Zinwell */
-	{ USB_DEVICE(0x1A32, 0x0304) }, /* Quanta 3070 */
-	{ USB_DEVICE(0x0789, 0x0162) }, /* Logitec 2870 */
-	{ USB_DEVICE(0x0789, 0x0163) }, /* Logitec 2870 */
-	{ USB_DEVICE(0x0789, 0x0164) }, /* Logitec 2870 */
-	{ USB_DEVICE(0x7392, 0x7717) }, /* Edimax */
-	{ USB_DEVICE(0x1EDA, 0x2310) }, /* AirTies 3070 */
-	{ USB_DEVICE(0x1737, 0x0077) }, /* Linksys WUSB54GC-EU v3 */
-	{ } /* Terminating entry */
-};
-
-INT const               rtusb_usb_id_len = sizeof(rtusb_usb_id) / sizeof(struct usb_device_id);
-MODULE_DEVICE_TABLE(usb, rtusb_usb_id);
-
-#ifndef PF_NOFREEZE
-#define PF_NOFREEZE  0
-#endif
-
-
-#ifdef CONFIG_PM
-static int rt2870_suspend(struct usb_interface *intf, pm_message_t state);
-static int rt2870_resume(struct usb_interface *intf);
-#endif // CONFIG_PM //
-
-/**************************************************************************/
-/**************************************************************************/
-//tested for kernel 2.6series
-/**************************************************************************/
-/**************************************************************************/
-static int rtusb_probe (struct usb_interface *intf,
-						const struct usb_device_id *id);
-static void rtusb_disconnect(struct usb_interface *intf);
-
-struct usb_driver rtusb_driver = {
-	.name="rt2870",
-	.probe=rtusb_probe,
-	.disconnect=rtusb_disconnect,
-	.id_table=rtusb_usb_id,
-
-#ifdef CONFIG_PM
-	suspend:	rt2870_suspend,
-	resume:		rt2870_resume,
-#endif
-	};
-
-#ifdef CONFIG_PM
-
-VOID RT2860RejectPendingPackets(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	// clear PS packets
-	// clear TxSw packets
-}
-
-static int rt2870_suspend(
-	struct usb_interface *intf,
-	pm_message_t state)
-{
-	struct net_device *net_dev;
-	PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
-
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n"));
-	net_dev = pAd->net_dev;
-	netif_device_detach (net_dev);
-
-	pAd->PM_FlgSuspend = 1;
-	if (netif_running(net_dev)) {
-		RTUSBCancelPendingBulkInIRP(pAd);
-		RTUSBCancelPendingBulkOutIRP(pAd);
-	}
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_suspend()\n"));
-	return 0;
-}
-
-static int rt2870_resume(
-	struct usb_interface *intf)
-{
-	struct net_device *net_dev;
-	PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
-
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_resume()\n"));
-
-	pAd->PM_FlgSuspend = 0;
-	net_dev = pAd->net_dev;
-	netif_device_attach (net_dev);
-	netif_start_queue(net_dev);
-	netif_carrier_on(net_dev);
-	netif_wake_queue(net_dev);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n"));
-	return 0;
-}
-#endif // CONFIG_PM //
-
-
-// Init driver module
-INT __init rtusb_init(void)
-{
-	printk("rtusb init --->\n");
-	return usb_register(&rtusb_driver);
-}
-
-// Deinit driver module
-VOID __exit rtusb_exit(void)
-{
-	usb_deregister(&rtusb_driver);
-	printk("<--- rtusb exit\n");
-}
-
-module_init(rtusb_init);
-module_exit(rtusb_exit);
-
-
-
-
-/*---------------------------------------------------------------------	*/
-/* function declarations												*/
-/*---------------------------------------------------------------------	*/
-
-/*
-========================================================================
-Routine Description:
-    MLME kernel thread.
-
-Arguments:
-	*Context			the pAd, driver control block pointer
-
-Return Value:
-    0					close the thread
-
-Note:
-========================================================================
-*/
-INT MlmeThread(
-	IN void *Context)
-{
-	PRTMP_ADAPTER	pAd = (PRTMP_ADAPTER)Context;
-	POS_COOKIE	pObj;
-	int status;
-
-	pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	rtmp_os_thread_init("rt2870MlmeThread", (PVOID)&(pAd->mlmeComplete));
-
-	while (pAd->mlme_kill == 0)
-	{
-		/* lock the device pointers */
-		//down(&(pAd->mlme_semaphore));
-		status = down_interruptible(&(pAd->mlme_semaphore));
-
-		/* lock the device pointers , need to check if required*/
-		//down(&(pAd->usbdev_semaphore));
-
-		if (!pAd->PM_FlgSuspend)
-		MlmeHandler(pAd);
-
-		/* unlock the device pointers */
-		//up(&(pAd->usbdev_semaphore));
-		if (status != 0)
-		{
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-			break;
-		}
-	}
-
-	/* notify the exit routine that we're actually exiting now
-	 *
-	 * complete()/wait_for_completion() is similar to up()/down(),
-	 * except that complete() is safe in the case where the structure
-	 * is getting deleted in a parallel mode of execution (i.e. just
-	 * after the down() -- that's necessary for the thread-shutdown
-	 * case.
-	 *
-	 * complete_and_exit() goes even further than this -- it is safe in
-	 * the case that the thread of the caller is going away (not just
-	 * the structure) -- this is necessary for the module-remove case.
-	 * This is important in preemption kernels, which transfer the flow
-	 * of execution immediately upon a complete().
-	 */
-	DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
-
-	pObj->MLMEThr_pid = NULL;
-
-	complete_and_exit (&pAd->mlmeComplete, 0);
-	return 0;
-
-}
-
-
-/*
-========================================================================
-Routine Description:
-    USB command kernel thread.
-
-Arguments:
-	*Context			the pAd, driver control block pointer
-
-Return Value:
-    0					close the thread
-
-Note:
-========================================================================
-*/
-INT RTUSBCmdThread(
-	IN void * Context)
-{
-	PRTMP_ADAPTER	pAd = (PRTMP_ADAPTER)Context;
-	POS_COOKIE		pObj;
-	int status;
-
-	pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	rtmp_os_thread_init("rt2870CmdThread", (PVOID)&(pAd->CmdQComplete));
-
-	NdisAcquireSpinLock(&pAd->CmdQLock);
-	pAd->CmdQ.CmdQState = RT2870_THREAD_RUNNING;
-	NdisReleaseSpinLock(&pAd->CmdQLock);
-
-	while (pAd->CmdQ.CmdQState == RT2870_THREAD_RUNNING)
-	{
-		/* lock the device pointers */
-		//down(&(pAd->RTUSBCmd_semaphore));
-		status = down_interruptible(&(pAd->RTUSBCmd_semaphore));
-
-		if (pAd->CmdQ.CmdQState == RT2870_THREAD_STOPED)
-			break;
-
-		if (status != 0)
-		{
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-			break;
-		}
-		/* lock the device pointers , need to check if required*/
-		//down(&(pAd->usbdev_semaphore));
-
-		if (!pAd->PM_FlgSuspend)
-		CMDHandler(pAd);
-
-		/* unlock the device pointers */
-		//up(&(pAd->usbdev_semaphore));
-	}
-
-	if (!pAd->PM_FlgSuspend)
-	{	// Clear the CmdQElements.
-		CmdQElmt	*pCmdQElmt = NULL;
-
-		NdisAcquireSpinLock(&pAd->CmdQLock);
-		pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
-		while(pAd->CmdQ.size)
-		{
-			RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt);
-			if (pCmdQElmt)
-			{
-				if (pCmdQElmt->CmdFromNdis == TRUE)
-				{
-					if (pCmdQElmt->buffer != NULL)
-						NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
-
-					NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
-				}
-				else
-				{
-					if ((pCmdQElmt->buffer != NULL) && (pCmdQElmt->bufferlength != 0))
-						NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
-		            {
-						NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
-					}
-				}
-			}
-		}
-
-		NdisReleaseSpinLock(&pAd->CmdQLock);
-	}
-	/* notify the exit routine that we're actually exiting now
-	 *
-	 * complete()/wait_for_completion() is similar to up()/down(),
-	 * except that complete() is safe in the case where the structure
-	 * is getting deleted in a parallel mode of execution (i.e. just
-	 * after the down() -- that's necessary for the thread-shutdown
-	 * case.
-	 *
-	 * complete_and_exit() goes even further than this -- it is safe in
-	 * the case that the thread of the caller is going away (not just
-	 * the structure) -- this is necessary for the module-remove case.
-	 * This is important in preemption kernels, which transfer the flow
-	 * of execution immediately upon a complete().
-	 */
-	DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n"));
-
-	pObj->RTUSBCmdThr_pid = NULL;
-
-	complete_and_exit (&pAd->CmdQComplete, 0);
-	return 0;
-
-}
-
-
-static void RT2870_TimerQ_Handle(RTMP_ADAPTER *pAd)
-{
-	int status;
-	RALINK_TIMER_STRUCT	*pTimer;
-	RT2870_TIMER_ENTRY	*pEntry;
-	unsigned long	irqFlag;
-
-	while(!pAd->TimerFunc_kill)
-	{
-//		printk("waiting for event!\n");
-		pTimer = NULL;
-
-		status = down_interruptible(&(pAd->RTUSBTimer_semaphore));
-
-		if (pAd->TimerQ.status == RT2870_THREAD_STOPED)
-			break;
-
-		// event happened.
-		while(pAd->TimerQ.pQHead)
-		{
-			RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlag);
-			pEntry = pAd->TimerQ.pQHead;
-			if (pEntry)
-			{
-				pTimer = pEntry->pRaTimer;
-
-				// update pQHead
-				pAd->TimerQ.pQHead = pEntry->pNext;
-				if (pEntry == pAd->TimerQ.pQTail)
-					pAd->TimerQ.pQTail = NULL;
-
-				// return this queue entry to timerQFreeList.
-				pEntry->pNext = pAd->TimerQ.pQPollFreeList;
-				pAd->TimerQ.pQPollFreeList = pEntry;
-			}
-			RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlag);
-
-			if (pTimer)
-			{
-				if (pTimer->handle != NULL)
-				if (!pAd->PM_FlgSuspend)
-					pTimer->handle(NULL, (PVOID) pTimer->cookie, NULL, pTimer);
-				if ((pTimer->Repeat) && (pTimer->State == FALSE))
-					RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);
-			}
-		}
-
-		if (status != 0)
-		{
-			pAd->TimerQ.status = RT2870_THREAD_STOPED;
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-			break;
-		}
-	}
-}
-
-
-INT TimerQThread(
-	IN OUT PVOID Context)
-{
-	PRTMP_ADAPTER	pAd;
-	POS_COOKIE	pObj;
-
-	pAd = (PRTMP_ADAPTER)Context;
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	rtmp_os_thread_init("rt2870TimerQHandle", (PVOID)&(pAd->TimerQComplete));
-
-	RT2870_TimerQ_Handle(pAd);
-
-	/* notify the exit routine that we're actually exiting now
-	 *
-	 * complete()/wait_for_completion() is similar to up()/down(),
-	 * except that complete() is safe in the case where the structure
-	 * is getting deleted in a parallel mode of execution (i.e. just
-	 * after the down() -- that's necessary for the thread-shutdown
-	 * case.
-	 *
-	 * complete_and_exit() goes even further than this -- it is safe in
-	 * the case that the thread of the caller is going away (not just
-	 * the structure) -- this is necessary for the module-remove case.
-	 * This is important in preemption kernels, which transfer the flow
-	 * of execution immediately upon a complete().
-	 */
-	DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
-
-	pObj->TimerQThr_pid = NULL;
-
-	complete_and_exit(&pAd->TimerQComplete, 0);
-	return 0;
-
-}
-
-
-RT2870_TIMER_ENTRY *RT2870_TimerQ_Insert(
-	IN RTMP_ADAPTER *pAd,
-	IN RALINK_TIMER_STRUCT *pTimer)
-{
-	RT2870_TIMER_ENTRY *pQNode = NULL, *pQTail;
-	unsigned long irqFlags;
-
-
-	RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
-	if (pAd->TimerQ.status & RT2870_THREAD_CAN_DO_INSERT)
-	{
-		if(pAd->TimerQ.pQPollFreeList)
-		{
-			pQNode = pAd->TimerQ.pQPollFreeList;
-			pAd->TimerQ.pQPollFreeList = pQNode->pNext;
-
-			pQNode->pRaTimer = pTimer;
-			pQNode->pNext = NULL;
-
-			pQTail = pAd->TimerQ.pQTail;
-			if (pAd->TimerQ.pQTail != NULL)
-				pQTail->pNext = pQNode;
-			pAd->TimerQ.pQTail = pQNode;
-			if (pAd->TimerQ.pQHead == NULL)
-				pAd->TimerQ.pQHead = pQNode;
-		}
-		RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
-
-		if (pQNode)
-			up(&pAd->RTUSBTimer_semaphore);
-			//wake_up(&timerWaitQ);
-	}
-	else
-	{
-		RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
-	}
-	return pQNode;
-}
-
-
-BOOLEAN RT2870_TimerQ_Remove(
-	IN RTMP_ADAPTER *pAd,
-	IN RALINK_TIMER_STRUCT *pTimer)
-{
-	RT2870_TIMER_ENTRY *pNode, *pPrev = NULL;
-	unsigned long irqFlags;
-
-	RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
-	if (pAd->TimerQ.status >= RT2870_THREAD_INITED)
-	{
-		pNode = pAd->TimerQ.pQHead;
-		while (pNode)
-		{
-			if (pNode->pRaTimer == pTimer)
-				break;
-			pPrev = pNode;
-			pNode = pNode->pNext;
-		}
-
-		// Now move it to freeList queue.
-		if (pNode)
-		{
-			if (pNode == pAd->TimerQ.pQHead)
-				pAd->TimerQ.pQHead = pNode->pNext;
-			if (pNode == pAd->TimerQ.pQTail)
-				pAd->TimerQ.pQTail = pPrev;
-			if (pPrev != NULL)
-				pPrev->pNext = pNode->pNext;
-
-			// return this queue entry to timerQFreeList.
-			pNode->pNext = pAd->TimerQ.pQPollFreeList;
-			pAd->TimerQ.pQPollFreeList = pNode;
-		}
-	}
-	RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
-
-	return TRUE;
-}
-
-
-void RT2870_TimerQ_Exit(RTMP_ADAPTER *pAd)
-{
-	RT2870_TIMER_ENTRY *pTimerQ;
-	unsigned long irqFlags;
-
-	RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
-	while (pAd->TimerQ.pQHead)
-	{
-		pTimerQ = pAd->TimerQ.pQHead;
-		pAd->TimerQ.pQHead = pTimerQ->pNext;
-		// remove the timeQ
-	}
-	pAd->TimerQ.pQPollFreeList = NULL;
-	os_free_mem(pAd, pAd->TimerQ.pTimerQPoll);
-	pAd->TimerQ.pQTail = NULL;
-	pAd->TimerQ.pQHead = NULL;
-	pAd->TimerQ.status = RT2870_THREAD_STOPED;
-	RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
-
-}
-
-
-void RT2870_TimerQ_Init(RTMP_ADAPTER *pAd)
-{
-	int 	i;
-	RT2870_TIMER_ENTRY *pQNode, *pEntry;
-	unsigned long irqFlags;
-
-	NdisAllocateSpinLock(&pAd->TimerQLock);
-
-	RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
-	NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ));
-	//InterlockedExchange(&pAd->TimerQ.count, 0);
-
-	/* Initialise the wait q head */
-	//init_waitqueue_head(&timerWaitQ);
-
-	os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll, sizeof(RT2870_TIMER_ENTRY) * TIMER_QUEUE_SIZE_MAX);
-	if (pAd->TimerQ.pTimerQPoll)
-	{
-		pEntry = NULL;
-		pQNode = (RT2870_TIMER_ENTRY *)pAd->TimerQ.pTimerQPoll;
-		for (i = 0 ;i <TIMER_QUEUE_SIZE_MAX; i++)
-		{
-			pQNode->pNext = pEntry;
-			pEntry = pQNode;
-			pQNode++;
-		}
-		pAd->TimerQ.pQPollFreeList = pEntry;
-		pAd->TimerQ.pQHead = NULL;
-		pAd->TimerQ.pQTail = NULL;
-		pAd->TimerQ.status = RT2870_THREAD_INITED;
-	}
-	RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
-}
-
-
-VOID RT2870_WatchDog(IN RTMP_ADAPTER *pAd)
-{
-	PHT_TX_CONTEXT		pHTTXContext;
-	int 					idx;
-	ULONG				irqFlags;
-	PURB		   		pUrb;
-	BOOLEAN				needDumpSeq = FALSE;
-	UINT32          	MACValue;
-
-
-	idx = 0;
-	RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
-	if ((MACValue & 0xff) !=0 )
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 0 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
-		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012);
-		while((MACValue &0xff) != 0 && (idx++ < 10))
-		{
-		        RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
-		        NdisMSleep(1);
-		}
-		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
-	}
-
-//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
-	idx = 0;
-	if ((MACValue & 0xff00) !=0 )
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 1 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
-		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf4000a);
-		while((MACValue &0xff00) != 0 && (idx++ < 10))
-		{
-			RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
-			NdisMSleep(1);
-		}
-		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
-	}
-
-	if (pAd->watchDogRxOverFlowCnt >= 2)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n"));
-		if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-									fRTMP_ADAPTER_BULKIN_RESET |
-									fRTMP_ADAPTER_HALT_IN_PROGRESS |
-									fRTMP_ADAPTER_NIC_NOT_EXIST))))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n"));
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
-			needDumpSeq = TRUE;
-		}
-		pAd->watchDogRxOverFlowCnt = 0;
-	}
-
-
-	for (idx = 0; idx < NUM_OF_TX_RING; idx++)
-	{
-		pUrb = NULL;
-
-		RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags);
-		if ((pAd->BulkOutPending[idx] == TRUE) && pAd->watchDogTxPendingCnt)
-		{
-			pAd->watchDogTxPendingCnt[idx]++;
-
-			if ((pAd->watchDogTxPendingCnt[idx] > 2) &&
-				 (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_BULKOUT_RESET)))
-				)
-			{
-				// FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it!
-				pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[idx]);
-				if (pHTTXContext->IRPPending)
-				{	// Check TxContext.
-					pUrb = pHTTXContext->pUrb;
-				}
-				else if (idx == MGMTPIPEIDX)
-				{
-					PTX_CONTEXT pMLMEContext, pNULLContext, pPsPollContext;
-
-					//Check MgmtContext.
-					pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
-					pPsPollContext = (PTX_CONTEXT)(&pAd->PsPollContext);
-					pNULLContext = (PTX_CONTEXT)(&pAd->NullContext);
-
-					if (pMLMEContext->IRPPending)
-					{
-						ASSERT(pMLMEContext->IRPPending);
-						pUrb = pMLMEContext->pUrb;
-					}
-					else if (pNULLContext->IRPPending)
-					{
-						ASSERT(pNULLContext->IRPPending);
-						pUrb = pNULLContext->pUrb;
-					}
-					else if (pPsPollContext->IRPPending)
-					{
-						ASSERT(pPsPollContext->IRPPending);
-						pUrb = pPsPollContext->pUrb;
-					}
-				}
-
-				RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
-
-				DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", idx));
-				if (pUrb)
-				{
-					DBGPRINT(RT_DEBUG_TRACE, ("Unlink the pending URB!\n"));
-					// unlink it now
-					RTUSB_UNLINK_URB(pUrb);
-					// Sleep 200 microseconds to give cancellation time to work
-					RTMPusecDelay(200);
-					needDumpSeq = TRUE;
-				}
-				else
-				{
-					DBGPRINT(RT_DEBUG_ERROR, ("Unkonw bulkOut URB maybe hanged!!!!!!!!!!!!\n"));
-				}
-			}
-			else
-			{
-				RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
-			}
-		}
-		else
-		{
-			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
-		}
-	}
-
-	// For Sigma debug, dump the ba_reordering sequence.
-	if((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0))
-	{
-		USHORT				Idx;
-		PBA_REC_ENTRY		pBAEntry = NULL;
-		UCHAR				count = 0;
-		struct reordering_mpdu *mpdu_blk;
-
-		Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0];
-
-		pBAEntry = &pAd->BATable.BARecEntry[Idx];
-		if((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n"));
-			NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
-			mpdu_blk = pBAEntry->list.next;
-			while (mpdu_blk)
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("\t%d:Seq-%d, bAMSDU-%d!\n", count, mpdu_blk->Sequence, mpdu_blk->bAMSDU));
-				mpdu_blk = mpdu_blk->next;
-				count++;
-			}
-
-			DBGPRINT(RT_DEBUG_TRACE, ("\npBAEntry->LastIndSeq=%d!\n", pBAEntry->LastIndSeq));
-			NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
-		}
-	}
-}
-
-/*
-========================================================================
-Routine Description:
-    Release allocated resources.
-
-Arguments:
-    *dev				Point to the PCI or USB device
-	pAd					driver control block pointer
-
-Return Value:
-    None
-
-Note:
-========================================================================
-*/
-static void _rtusb_disconnect(struct usb_device *dev, PRTMP_ADAPTER pAd)
-{
-	struct net_device	*net_dev = NULL;
-
-
-	DBGPRINT(RT_DEBUG_ERROR, ("rtusb_disconnect: unregister usbnet usb-%s-%s\n",
-				dev->bus->bus_name, dev->devpath));
-	if (!pAd)
-	{
-		usb_put_dev(dev);
-
-		printk("rtusb_disconnect: pAd == NULL!\n");
-		return;
-	}
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
-
-
-
-	// for debug, wait to show some messages to /proc system
-	udelay(1);
-
-
-
-
-	net_dev = pAd->net_dev;
-	if (pAd->net_dev != NULL)
-	{
-		printk("rtusb_disconnect: unregister_netdev(), dev->name=%s!\n", net_dev->name);
-		unregister_netdev (pAd->net_dev);
-	}
-	udelay(1);
-	flush_scheduled_work();
-	udelay(1);
-
-	// free net_device memory
-	free_netdev(net_dev);
-
-	// free adapter memory
-	RTMPFreeAdapter(pAd);
-
-	// release a use of the usb device structure
-	usb_put_dev(dev);
-	udelay(1);
-
-	DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n"));
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Probe RT28XX chipset.
-
-Arguments:
-    *dev				Point to the PCI or USB device
-	interface
-	*id_table			Point to the PCI or USB device ID
-
-Return Value:
-    None
-
-Note:
-========================================================================
-*/
-static int rtusb_probe (struct usb_interface *intf,
-						const struct usb_device_id *id)
-{
-	PRTMP_ADAPTER pAd;
-	return (int)rt28xx_probe((void *)intf, (void *)id, 0, &pAd);
-}
-
-
-static void rtusb_disconnect(struct usb_interface *intf)
-{
-	struct usb_device   *dev = interface_to_usbdev(intf);
-	PRTMP_ADAPTER       pAd;
-
-
-	pAd = usb_get_intfdata(intf);
-	usb_set_intfdata(intf, NULL);
-
-	_rtusb_disconnect(dev, pAd);
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Close kernel threads.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-    NONE
-
-Note:
-========================================================================
-*/
-VOID RT28xxThreadTerminate(
-	IN RTMP_ADAPTER *pAd)
-{
-	POS_COOKIE	pObj = (POS_COOKIE) pAd->OS_Cookie;
-	INT			ret;
-
-
-	// Sleep 50 milliseconds so pending io might finish normally
-	RTMPusecDelay(50000);
-
-	// We want to wait until all pending receives and sends to the
-	// device object. We cancel any
-	// irps. Wait until sends and receives have stopped.
-	RTUSBCancelPendingIRPs(pAd);
-
-	// Terminate Threads
-
-	if (pid_nr(pObj->TimerQThr_pid) > 0)
-	{
-		POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-		printk("Terminate the TimerQThr_pid=%d!\n", pid_nr(pObj->TimerQThr_pid));
-		mb();
-		pAd->TimerFunc_kill = 1;
-		mb();
-		ret = kill_pid(pObj->TimerQThr_pid, SIGTERM, 1);
-		if (ret)
-		{
-			printk(KERN_WARNING "%s: unable to stop TimerQThread, pid=%d, ret=%d!\n",
-					pAd->net_dev->name, pid_nr(pObj->TimerQThr_pid), ret);
-		}
-		else
-		{
-			wait_for_completion(&pAd->TimerQComplete);
-			pObj->TimerQThr_pid = NULL;
-		}
-	}
-
-	if (pid_nr(pObj->MLMEThr_pid) > 0)
-	{
-		printk("Terminate the MLMEThr_pid=%d!\n", pid_nr(pObj->MLMEThr_pid));
-		mb();
-		pAd->mlme_kill = 1;
-		//RT28XX_MLME_HANDLER(pAd);
-		mb();
-		ret = kill_pid(pObj->MLMEThr_pid, SIGTERM, 1);
-		if (ret)
-		{
-			printk (KERN_WARNING "%s: unable to Mlme thread, pid=%d, ret=%d!\n",
-					pAd->net_dev->name, pid_nr(pObj->MLMEThr_pid), ret);
-		}
-		else
-		{
-			//wait_for_completion (&pAd->notify);
-			wait_for_completion (&pAd->mlmeComplete);
-			pObj->MLMEThr_pid = NULL;
-		}
-	}
-
-	if (pid_nr(pObj->RTUSBCmdThr_pid) > 0)
-	{
-		printk("Terminate the RTUSBCmdThr_pid=%d!\n", pid_nr(pObj->RTUSBCmdThr_pid));
-		mb();
-		NdisAcquireSpinLock(&pAd->CmdQLock);
-		pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
-		NdisReleaseSpinLock(&pAd->CmdQLock);
-		mb();
-		//RTUSBCMDUp(pAd);
-		ret = kill_pid(pObj->RTUSBCmdThr_pid, SIGTERM, 1);
-		if (ret)
-		{
-			printk(KERN_WARNING "%s: unable to RTUSBCmd thread, pid=%d, ret=%d!\n",
-					pAd->net_dev->name, pid_nr(pObj->RTUSBCmdThr_pid), ret);
-		}
-		else
-		{
-			//wait_for_completion (&pAd->notify);
-			wait_for_completion (&pAd->CmdQComplete);
-			pObj->RTUSBCmdThr_pid = NULL;
-		}
-	}
-
-	// Kill tasklets
-	pAd->mlme_kill = 0;
-	pAd->CmdQ.CmdQState = RT2870_THREAD_UNKNOWN;
-	pAd->TimerFunc_kill = 0;
-}
-
-
-void kill_thread_task(IN PRTMP_ADAPTER pAd)
-{
-	POS_COOKIE pObj;
-
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	tasklet_kill(&pObj->rx_done_task);
-	tasklet_kill(&pObj->mgmt_dma_done_task);
-	tasklet_kill(&pObj->ac0_dma_done_task);
-	tasklet_kill(&pObj->ac1_dma_done_task);
-	tasklet_kill(&pObj->ac2_dma_done_task);
-	tasklet_kill(&pObj->ac3_dma_done_task);
-	tasklet_kill(&pObj->hcca_dma_done_task);
-	tasklet_kill(&pObj->tbtt_task);
-
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Check the chipset vendor/product ID.
-
-Arguments:
-    _dev_p				Point to the PCI or USB device
-
-Return Value:
-    TRUE				Check ok
-	FALSE				Check fail
-
-Note:
-========================================================================
-*/
-BOOLEAN RT28XXChipsetCheck(
-	IN void *_dev_p)
-{
-	struct usb_interface *intf = (struct usb_interface *)_dev_p;
-	struct usb_device *dev_p = interface_to_usbdev(intf);
-	UINT32 i;
-
-
-	for(i=0; i<rtusb_usb_id_len; i++)
-	{
-		if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
-			dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct)
-		{
-			printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
-					dev_p->descriptor.idVendor, dev_p->descriptor.idProduct);
-			break;
-		}
-	}
-
-	if (i == rtusb_usb_id_len)
-	{
-		printk("rt2870: Error! Device Descriptor not matching!\n");
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Init net device structure.
-
-Arguments:
-    _dev_p				Point to the PCI or USB device
-    *net_dev			Point to the net device
-	*pAd				the raxx interface data pointer
-
-Return Value:
-    TRUE				Init ok
-	FALSE				Init fail
-
-Note:
-========================================================================
-*/
-BOOLEAN RT28XXNetDevInit(
-	IN void 				*_dev_p,
-	IN struct  net_device	*net_dev,
-	IN RTMP_ADAPTER 		*pAd)
-{
-	struct usb_interface *intf = (struct usb_interface *)_dev_p;
-	struct usb_device *dev_p = interface_to_usbdev(intf);
-
-
-	pAd->config = &dev_p->config->desc;
-	return TRUE;
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Init net device structure.
-
-Arguments:
-    _dev_p				Point to the PCI or USB device
-	*pAd				the raxx interface data pointer
-
-Return Value:
-    TRUE				Config ok
-	FALSE				Config fail
-
-Note:
-========================================================================
-*/
-BOOLEAN RT28XXProbePostConfig(
-	IN void 				*_dev_p,
-	IN RTMP_ADAPTER 		*pAd,
-	IN INT32				interface)
-{
-	struct usb_interface *intf = (struct usb_interface *)_dev_p;
-	struct usb_host_interface *iface_desc;
-	ULONG BulkOutIdx;
-	UINT32 i;
-
-
-	/* get the active interface descriptor */
-	iface_desc = intf->cur_altsetting;
-
-	/* get # of enpoints  */
-	pAd->NumberOfPipes = iface_desc->desc.bNumEndpoints;
-	DBGPRINT(RT_DEBUG_TRACE,
-			("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints));
-
-	/* Configure Pipes */
-	BulkOutIdx = 0;
-
-	for(i=0; i<pAd->NumberOfPipes; i++)
-	{
-		if ((iface_desc->endpoint[i].desc.bmAttributes ==
-				USB_ENDPOINT_XFER_BULK) &&
-			((iface_desc->endpoint[i].desc.bEndpointAddress &
-				USB_ENDPOINT_DIR_MASK) == USB_DIR_IN))
-		{
-			pAd->BulkInEpAddr = iface_desc->endpoint[i].desc.bEndpointAddress;
-			pAd->BulkInMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
-
-			DBGPRINT_RAW(RT_DEBUG_TRACE,
-				("BULK IN MaximumPacketSize = %d\n", pAd->BulkInMaxPacketSize));
-			DBGPRINT_RAW(RT_DEBUG_TRACE,
-				("EP address = 0x%2x\n", iface_desc->endpoint[i].desc.bEndpointAddress));
-		}
-		else if ((iface_desc->endpoint[i].desc.bmAttributes ==
-					USB_ENDPOINT_XFER_BULK) &&
-				((iface_desc->endpoint[i].desc.bEndpointAddress &
-					USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT))
-		{
-			// there are 6 bulk out EP. EP6 highest priority.
-			// EP1-4 is EDCA.  EP5 is HCCA.
-			pAd->BulkOutEpAddr[BulkOutIdx++] = iface_desc->endpoint[i].desc.bEndpointAddress;
-			pAd->BulkOutMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
-
-			DBGPRINT_RAW(RT_DEBUG_TRACE,
-				("BULK OUT MaximumPacketSize = %d\n", pAd->BulkOutMaxPacketSize));
-			DBGPRINT_RAW(RT_DEBUG_TRACE,
-				("EP address = 0x%2x  \n", iface_desc->endpoint[i].desc.bEndpointAddress));
-		}
-	}
-
-	if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0]))
-	{
-		printk("%s: Could not find both bulk-in and bulk-out endpoints\n", __func__);
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Disable DMA.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-VOID RT28XXDMADisable(
-	IN RTMP_ADAPTER 		*pAd)
-{
-	// no use
-}
-
-
-
-/*
-========================================================================
-Routine Description:
-    Enable DMA.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-VOID RT28XXDMAEnable(
-	IN RTMP_ADAPTER 		*pAd)
-{
-	WPDMA_GLO_CFG_STRUC	GloCfg;
-	USB_DMA_CFG_STRUC	UsbCfg;
-	int					i = 0;
-
-
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
-	do
-	{
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-		if ((GloCfg.field.TxDMABusy == 0)  && (GloCfg.field.RxDMABusy == 0))
-			break;
-
-		DBGPRINT(RT_DEBUG_TRACE, ("==>  DMABusy\n"));
-		RTMPusecDelay(1000);
-		i++;
-	}while ( i <200);
-
-
-	RTMPusecDelay(50);
-	GloCfg.field.EnTXWriteBackDDONE = 1;
-	GloCfg.field.EnableRxDMA = 1;
-	GloCfg.field.EnableTxDMA = 1;
-	DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
-	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
-
-	UsbCfg.word = 0;
-	UsbCfg.field.phyclear = 0;
-	/* usb version is 1.1,do not use bulk in aggregation */
-	if (pAd->BulkInMaxPacketSize == 512)
-			UsbCfg.field.RxBulkAggEn = 1;
-	/* for last packet, PBF might use more than limited, so minus 2 to prevent from error */
-	UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE /1024)-3;
-	UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */
-	UsbCfg.field.RxBulkEn = 1;
-	UsbCfg.field.TxBulkEn = 1;
-
-	RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word);
-
-}
-
-/*
-========================================================================
-Routine Description:
-    Write Beacon buffer to Asic.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-VOID RT28xx_UpdateBeaconToAsic(
-	IN RTMP_ADAPTER		*pAd,
-	IN INT				apidx,
-	IN ULONG			FrameLen,
-	IN ULONG			UpdatePos)
-{
-	PUCHAR        	pBeaconFrame = NULL;
-	UCHAR  			*ptr;
-	UINT  			i, padding;
-	BEACON_SYNC_STRUCT	*pBeaconSync = pAd->CommonCfg.pBeaconSync;
-	UINT32			longValue;
-	BOOLEAN			bBcnReq = FALSE;
-	UCHAR			bcn_idx = 0;
-
-
-	if (pBeaconFrame == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("pBeaconFrame is NULL!\n"));
-		return;
-	}
-
-	if (pBeaconSync == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("pBeaconSync is NULL!\n"));
-		return;
-	}
-
-	//if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) ||
-	//	((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP))
-	//	)
-	if (bBcnReq == FALSE)
-	{
-		/* when the ra interface is down, do not send its beacon frame */
-		/* clear all zero */
-		for(i=0; i<TXWI_SIZE; i+=4) {
-			RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, 0x00);
-		}
-		pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
-		NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE);
-	}
-	else
-	{
-		ptr = (PUCHAR)&pAd->BeaconTxWI;
-
-		if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE)
-		{	// If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames.
-			pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
-			NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE);
-		}
-
-		if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) != (1 << bcn_idx))
-		{
-			for (i=0; i<TXWI_SIZE; i+=4)  // 16-byte TXWI field
-			{
-				longValue =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
-				RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longValue);
-				ptr += 4;
-			}
-		}
-
-		ptr = pBeaconSync->BeaconBuf[bcn_idx];
-		padding = (FrameLen & 0x01);
-		NdisZeroMemory((PUCHAR)(pBeaconFrame + FrameLen), padding);
-		FrameLen += padding;
-		for (i = 0 ; i < FrameLen /*HW_BEACON_OFFSET*/; i += 2)
-		{
-			if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE)
-			{
-				NdisMoveMemory(ptr, pBeaconFrame, 2);
-				//shortValue = *ptr + (*(ptr+1)<<8);
-				//RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue);
-				RTUSBMultiWrite(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, ptr, 2);
-			}
-			ptr +=2;
-			pBeaconFrame += 2;
-		}
-
-		pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
-
-		// For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame.
-	}
-
-}
-
-
-VOID RT2870_BssBeaconStop(
-	IN RTMP_ADAPTER *pAd)
-{
-	BEACON_SYNC_STRUCT	*pBeaconSync;
-	int i, offset;
-	BOOLEAN	Cancelled = TRUE;
-
-	pBeaconSync = pAd->CommonCfg.pBeaconSync;
-	if (pBeaconSync && pBeaconSync->EnableBeacon)
-	{
-		INT NumOfBcn;
-
-		NumOfBcn = MAX_MESH_NUM;
-
-		RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
-
-		for(i=0; i<NumOfBcn; i++)
-		{
-			NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
-			NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
-
-			for (offset=0; offset<HW_BEACON_OFFSET; offset+=4)
-				RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[i] + offset, 0x00);
-
-			pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
-			pBeaconSync->TimIELocationInBeacon[i] = 0;
-		}
-		pBeaconSync->BeaconBitMap = 0;
-		pBeaconSync->DtimBitOn = 0;
-	}
-}
-
-
-VOID RT2870_BssBeaconStart(
-	IN RTMP_ADAPTER *pAd)
-{
-	int apidx;
-	BEACON_SYNC_STRUCT	*pBeaconSync;
-//	LARGE_INTEGER 	tsfTime, deltaTime;
-
-	pBeaconSync = pAd->CommonCfg.pBeaconSync;
-	if (pBeaconSync && pBeaconSync->EnableBeacon)
-	{
-		INT NumOfBcn;
-
-		NumOfBcn = MAX_MESH_NUM;
-
-		for(apidx=0; apidx<NumOfBcn; apidx++)
-		{
-			UCHAR CapabilityInfoLocationInBeacon = 0;
-			UCHAR TimIELocationInBeacon = 0;
-
-			NdisZeroMemory(pBeaconSync->BeaconBuf[apidx], HW_BEACON_OFFSET);
-			pBeaconSync->CapabilityInfoLocationInBeacon[apidx] = CapabilityInfoLocationInBeacon;
-			pBeaconSync->TimIELocationInBeacon[apidx] = TimIELocationInBeacon;
-			NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx], TXWI_SIZE);
-		}
-		pBeaconSync->BeaconBitMap = 0;
-		pBeaconSync->DtimBitOn = 0;
-		pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE;
-
-		pAd->CommonCfg.BeaconAdjust = 0;
-		pAd->CommonCfg.BeaconFactor = 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10);
-		pAd->CommonCfg.BeaconRemain = (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1;
-		printk(RT28xx_CHIP_NAME "_BssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n", pAd->CommonCfg.BeaconFactor, pAd->CommonCfg.BeaconRemain);
-		RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer, pAd->CommonCfg.BeaconPeriod);
-
-	}
-}
-
-
-VOID RT2870_BssBeaconInit(
-	IN RTMP_ADAPTER *pAd)
-{
-	BEACON_SYNC_STRUCT	*pBeaconSync;
-	int i;
-
-	NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(BEACON_SYNC_STRUCT), MEM_ALLOC_FLAG);
-	if (pAd->CommonCfg.pBeaconSync)
-	{
-		pBeaconSync = pAd->CommonCfg.pBeaconSync;
-		NdisZeroMemory(pBeaconSync, sizeof(BEACON_SYNC_STRUCT));
-		for(i=0; i < HW_BEACON_MAX_COUNT; i++)
-		{
-			NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
-			pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
-			pBeaconSync->TimIELocationInBeacon[i] = 0;
-			NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
-		}
-		pBeaconSync->BeaconBitMap = 0;
-
-		//RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE);
-		pBeaconSync->EnableBeacon = TRUE;
-	}
-}
-
-
-VOID RT2870_BssBeaconExit(
-	IN RTMP_ADAPTER *pAd)
-{
-	BEACON_SYNC_STRUCT	*pBeaconSync;
-	BOOLEAN	Cancelled = TRUE;
-	int i;
-
-	if (pAd->CommonCfg.pBeaconSync)
-	{
-		pBeaconSync = pAd->CommonCfg.pBeaconSync;
-		pBeaconSync->EnableBeacon = FALSE;
-		RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
-		pBeaconSync->BeaconBitMap = 0;
-
-		for(i=0; i<HW_BEACON_MAX_COUNT; i++)
-		{
-			NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
-			pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
-			pBeaconSync->TimIELocationInBeacon[i] = 0;
-			NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
-		}
-
-		NdisFreeMemory(pAd->CommonCfg.pBeaconSync, HW_BEACON_OFFSET * HW_BEACON_MAX_COUNT, 0);
-		pAd->CommonCfg.pBeaconSync = NULL;
-	}
-}
-
-VOID BeaconUpdateExec(
-    IN PVOID SystemSpecific1,
-    IN PVOID FunctionContext,
-    IN PVOID SystemSpecific2,
-    IN PVOID SystemSpecific3)
-{
-	PRTMP_ADAPTER	pAd = (PRTMP_ADAPTER)FunctionContext;
-	LARGE_INTEGER	tsfTime_a;//, tsfTime_b, deltaTime_exp, deltaTime_ab;
-	UINT32			delta, remain, remain_low, remain_high;
-//	BOOLEAN			positive;
-
-	ReSyncBeaconTime(pAd);
-
-
-
-	RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart);
-	RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart);
-
-
-	//positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp);
-	remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart;
-	remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10);
-	remain = (remain_high + remain_low)%(pAd->CommonCfg.BeaconPeriod << 10);
-	delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain;
-
-	pAd->CommonCfg.BeaconUpdateTimer.TimerValue = (delta >> 10) + 10;
-
-}
-
diff --git a/drivers/staging/rt2870/Kconfig b/drivers/staging/rt2870/Kconfig
index aea5c82..fd3ba3a 100644
--- a/drivers/staging/rt2870/Kconfig
+++ b/drivers/staging/rt2870/Kconfig
@@ -1,5 +1,7 @@
 config RT2870
 	tristate "Ralink 2870/3070 wireless support"
 	depends on USB && X86 && WLAN
+	select WIRELESS_EXT
+	select WEXT_PRIV
 	---help---
 	  This is an experimental driver for the Ralink xx70 wireless chips.
diff --git a/drivers/staging/rt2870/Makefile b/drivers/staging/rt2870/Makefile
index 306c331..523e7e7 100644
--- a/drivers/staging/rt2870/Makefile
+++ b/drivers/staging/rt2870/Makefile
@@ -1,27 +1,35 @@
+#
 obj-$(CONFIG_RT2870)	+= rt2870sta.o
 
 # TODO: all of these should be removed
 EXTRA_CFLAGS += -DLINUX -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT
-EXTRA_CFLAGS += -DRT2870 -DRT3070
+EXTRA_CFLAGS += -DRTMP_MAC_USB -DRTMP_USB_SUPPORT -DRT2870 -DRTMP_TIMER_TASK_SUPPORT
+EXTRA_CFLAGS += -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DRT30xx -DRT3070
 EXTRA_CFLAGS += -DDBG
 
 rt2870sta-objs :=		\
-	common/md5.o		\
+	common/crypt_md5.o	\
+	common/crypt_sha2.o	\
+	common/crypt_hmac.o	\
 	common/mlme.o		\
-	common/rtmp_wep.o	\
+	common/cmm_wep.o	\
 	common/action.o		\
 	common/cmm_data.o	\
 	common/rtmp_init.o	\
-	common/rtmp_tkip.o	\
+	common/cmm_tkip.o	\
+	common/cmm_aes.o	\
 	common/cmm_sync.o	\
 	common/eeprom.o		\
 	common/cmm_sanity.o	\
 	common/cmm_info.o	\
+	common/cmm_cfg.o	\
 	common/cmm_wpa.o	\
 	common/dfs.o		\
 	common/spectrum.o	\
+	common/rtmp_timer.o	\
+	common/rt_channel.o	\
+	common/cmm_asic.o	\
 	sta/assoc.o		\
-	sta/aironet.o		\
 	sta/auth.o		\
 	sta/auth_rsp.o		\
 	sta/sync.o		\
@@ -30,14 +38,18 @@
 	sta/connect.o		\
 	sta/wpa.o		\
 	rt_linux.o		\
-	rt_profile.o		\
 	rt_main_dev.o		\
 	sta_ioctl.o		\
 	common/ba_action.o	\
-	2870_main_dev.o		\
-	common/2870_rtmp_init.o	\
+	usb_main_dev.o		\
+	rt_usb.o		\
+	common/cmm_mac_usb.o	\
 	common/rtusb_io.o	\
 	common/rtusb_bulk.o	\
 	common/rtusb_data.o	\
-	common/cmm_data_2870.o
-
+	common/cmm_data_usb.o	\
+	common/rtmp_mcu.o	\
+	common/ee_efuse.o	\
+	chips/rt30xx.o		\
+	common/rt_rf.o		\
+	chips/rt3070.o
diff --git a/drivers/staging/rt2870/chips/rt3070.c b/drivers/staging/rt2870/chips/rt3070.c
new file mode 100644
index 0000000..3a6db5e
--- /dev/null
+++ b/drivers/staging/rt2870/chips/rt3070.c
@@ -0,0 +1 @@
+#include "../../rt2860/chips/rt3070.c"
diff --git a/drivers/staging/rt2870/chips/rt30xx.c b/drivers/staging/rt2870/chips/rt30xx.c
new file mode 100644
index 0000000..6c56b84
--- /dev/null
+++ b/drivers/staging/rt2870/chips/rt30xx.c
@@ -0,0 +1 @@
+#include "../../rt2860/chips/rt30xx.c"
diff --git a/drivers/staging/rt2870/common/2870_rtmp_init.c b/drivers/staging/rt2870/common/2870_rtmp_init.c
deleted file mode 100644
index f517d9e..0000000
--- a/drivers/staging/rt2870/common/2870_rtmp_init.c
+++ /dev/null
@@ -1,1730 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	2870_rtmp_init.c
-
-	Abstract:
-	Miniport generic portion header file
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-	Paul Lin    2002-08-01    created
-    John Chang  2004-08-20    RT2561/2661 use scatter-gather scheme
-    Jan Lee  	2006-09-15    RT2860. Change for 802.11n , EEPROM, Led, BA, HT.
-	Sample Lin	2007-05-31    Merge RT2860 and RT2870 drivers.
-*/
-
-#include "../rt_config.h"
-
-
-static void rx_done_tasklet(unsigned long data);
-static void rt2870_hcca_dma_done_tasklet(unsigned long data);
-static void rt2870_ac3_dma_done_tasklet(unsigned long data);
-static void rt2870_ac2_dma_done_tasklet(unsigned long data);
-static void rt2870_ac1_dma_done_tasklet(unsigned long data);
-static void rt2870_ac0_dma_done_tasklet(unsigned long data);
-static void rt2870_mgmt_dma_done_tasklet(unsigned long data);
-static void rt2870_null_frame_complete_tasklet(unsigned long data);
-static void rt2870_rts_frame_complete_tasklet(unsigned long data);
-static void rt2870_pspoll_frame_complete_tasklet(unsigned long data);
-static void rt2870_dataout_complete_tasklet(unsigned long data);
-
-
-/*
-========================================================================
-Routine Description:
-    Initialize receive data structures.
-
-Arguments:
-    pAd					Pointer to our adapter
-
-Return Value:
-	NDIS_STATUS_SUCCESS
-	NDIS_STATUS_RESOURCES
-
-Note:
-	Initialize all receive releated private buffer, include those define
-	in RTMP_ADAPTER structure and all private data structures. The mahor
-	work is to allocate buffer for each packet and chain buffer to
-	NDIS packet descriptor.
-========================================================================
-*/
-NDIS_STATUS	NICInitRecv(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	UCHAR				i;
-	NDIS_STATUS			Status = NDIS_STATUS_SUCCESS;
-	POS_COOKIE			pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n"));
-	pObj = pObj;
-
-	//InterlockedExchange(&pAd->PendingRx, 0);
-	pAd->PendingRx = 0;
-	pAd->NextRxBulkInReadIndex 	= 0;	// Next Rx Read index
-	pAd->NextRxBulkInIndex		= 0 ; //RX_RING_SIZE -1; // Rx Bulk pointer
-	pAd->NextRxBulkInPosition 	= 0;
-
-	for (i = 0; i < (RX_RING_SIZE); i++)
-	{
-		PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
-
-		//Allocate URB
-		pRxContext->pUrb = RTUSB_ALLOC_URB(0);
-		if (pRxContext->pUrb == NULL)
-		{
-			Status = NDIS_STATUS_RESOURCES;
-			goto out1;
-		}
-
-		// Allocate transfer buffer
-		pRxContext->TransferBuffer = RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, &pRxContext->data_dma);
-		if (pRxContext->TransferBuffer == NULL)
-		{
-			Status = NDIS_STATUS_RESOURCES;
-			goto out1;
-		}
-
-		NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
-
-		pRxContext->pAd	= pAd;
-		pRxContext->pIrp = NULL;
-		pRxContext->InUse		= FALSE;
-		pRxContext->IRPPending	= FALSE;
-		pRxContext->Readable	= FALSE;
-		//pRxContext->ReorderInUse = FALSE;
-		pRxContext->bRxHandling = FALSE;
-		pRxContext->BulkInOffset = 0;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv\n"));
-	return Status;
-
-out1:
-	for (i = 0; i < (RX_RING_SIZE); i++)
-	{
-		PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
-
-		if (NULL != pRxContext->TransferBuffer)
-		{
-			RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE,
-								pRxContext->TransferBuffer, pRxContext->data_dma);
-			pRxContext->TransferBuffer = NULL;
-		}
-
-		if (NULL != pRxContext->pUrb)
-		{
-			RTUSB_UNLINK_URB(pRxContext->pUrb);
-			RTUSB_FREE_URB(pRxContext->pUrb);
-			pRxContext->pUrb = NULL;
-		}
-	}
-
-	return Status;
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Initialize transmit data structures.
-
-Arguments:
-    pAd					Pointer to our adapter
-
-Return Value:
-	NDIS_STATUS_SUCCESS
-	NDIS_STATUS_RESOURCES
-
-Note:
-========================================================================
-*/
-NDIS_STATUS	NICInitTransmit(
-	IN	PRTMP_ADAPTER	pAd)
-{
-#define LM_USB_ALLOC(pObj, Context, TB_Type, BufferSize, Status, msg1, err1, msg2, err2)	\
-	Context->pUrb = RTUSB_ALLOC_URB(0);		\
-	if (Context->pUrb == NULL) {			\
-		DBGPRINT(RT_DEBUG_ERROR, msg1);		\
-		Status = NDIS_STATUS_RESOURCES;		\
-		goto err1; }						\
-											\
-	Context->TransferBuffer = 				\
-		(TB_Type)RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, BufferSize, &Context->data_dma);	\
-	if (Context->TransferBuffer == NULL) {	\
-		DBGPRINT(RT_DEBUG_ERROR, msg2);		\
-		Status = NDIS_STATUS_RESOURCES;		\
-		goto err2; }
-
-#define LM_URB_FREE(pObj, Context, BufferSize)				\
-	if (NULL != Context->pUrb) {							\
-		RTUSB_UNLINK_URB(Context->pUrb);					\
-		RTUSB_FREE_URB(Context->pUrb);						\
-		Context->pUrb = NULL; }								\
-	if (NULL != Context->TransferBuffer) {				\
-		RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize,	\
-								Context->TransferBuffer,	\
-								Context->data_dma);			\
-		Context->TransferBuffer = NULL; }
-
-	UCHAR			i, acidx;
-	NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;
-	PTX_CONTEXT		pNullContext   = &(pAd->NullContext);
-	PTX_CONTEXT		pPsPollContext = &(pAd->PsPollContext);
-	PTX_CONTEXT		pRTSContext    = &(pAd->RTSContext);
-	PTX_CONTEXT		pMLMEContext = NULL;
-//	PHT_TX_CONTEXT	pHTTXContext = NULL;
-	POS_COOKIE		pObj = (POS_COOKIE) pAd->OS_Cookie;
-	PVOID			RingBaseVa;
-//	RTMP_TX_RING	*pTxRing;
-	RTMP_MGMT_RING  *pMgmtRing;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n"));
-	pObj = pObj;
-
-	// Init 4 set of Tx parameters
-	for(acidx = 0; acidx < NUM_OF_TX_RING; acidx++)
-	{
-		// Initialize all Transmit releated queues
-		InitializeQueueHeader(&pAd->TxSwQueue[acidx]);
-
-		// Next Local tx ring pointer waiting for buck out
-		pAd->NextBulkOutIndex[acidx] = acidx;
-		pAd->BulkOutPending[acidx] = FALSE; // Buck Out control flag
-		//pAd->DataBulkDoneIdx[acidx] = 0;
-	}
-
-	//pAd->NextMLMEIndex	= 0;
-	//pAd->PushMgmtIndex	= 0;
-	//pAd->PopMgmtIndex	= 0;
-	//InterlockedExchange(&pAd->MgmtQueueSize, 0);
-	//InterlockedExchange(&pAd->TxCount, 0);
-
-	//pAd->PrioRingFirstIndex	= 0;
-	//pAd->PrioRingTxCnt		= 0;
-
-	do
-	{
-		//
-		// TX_RING_SIZE, 4 ACs
-		//
-		for(acidx=0; acidx<4; acidx++)
-		{
-			PHT_TX_CONTEXT	pHTTXContext = &(pAd->TxContext[acidx]);
-
-			NdisZeroMemory(pHTTXContext, sizeof(HT_TX_CONTEXT));
-			//Allocate URB
-			LM_USB_ALLOC(pObj, pHTTXContext, PHTTX_BUFFER, sizeof(HTTX_BUFFER), Status,
-							("<-- ERROR in Alloc TX TxContext[%d] urb!! \n", acidx),
-							done,
-							("<-- ERROR in Alloc TX TxContext[%d] HTTX_BUFFER !! \n", acidx),
-							out1);
-
-			NdisZeroMemory(pHTTXContext->TransferBuffer->Aggregation, 4);
-			pHTTXContext->pAd = pAd;
-			pHTTXContext->pIrp = NULL;
-			pHTTXContext->IRPPending = FALSE;
-			pHTTXContext->NextBulkOutPosition = 0;
-			pHTTXContext->ENextBulkOutPosition = 0;
-			pHTTXContext->CurWritePosition = 0;
-			pHTTXContext->CurWriteRealPos = 0;
-			pHTTXContext->BulkOutSize = 0;
-			pHTTXContext->BulkOutPipeId = acidx;
-			pHTTXContext->bRingEmpty = TRUE;
-			pHTTXContext->bCopySavePad = FALSE;
-
-			pAd->BulkOutPending[acidx] = FALSE;
-		}
-
-
-		//
-		// MGMT_RING_SIZE
-		//
-		// Allocate MGMT ring descriptor's memory
-		pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * sizeof(TX_CONTEXT);
-		RTMPAllocateMemory(&pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
-		if (pAd->MgmtDescRing.AllocVa == NULL)
-		{
-			DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n"));
-			Status = NDIS_STATUS_RESOURCES;
-			goto out1;
-		}
-		NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
-		RingBaseVa     = pAd->MgmtDescRing.AllocVa;
-
-		// Initialize MGMT Ring and associated buffer memory
-		pMgmtRing = &pAd->MgmtRing;
-		for (i = 0; i < MGMT_RING_SIZE; i++)
-		{
-			// link the pre-allocated Mgmt buffer to MgmtRing.Cell
-			pMgmtRing->Cell[i].AllocSize = sizeof(TX_CONTEXT);
-			pMgmtRing->Cell[i].AllocVa = RingBaseVa;
-			pMgmtRing->Cell[i].pNdisPacket = NULL;
-			pMgmtRing->Cell[i].pNextNdisPacket = NULL;
-
-			//Allocate URB for MLMEContext
-			pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
-			pMLMEContext->pUrb = RTUSB_ALLOC_URB(0);
-			if (pMLMEContext->pUrb == NULL)
-			{
-				DBGPRINT(RT_DEBUG_ERROR, ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i));
-				Status = NDIS_STATUS_RESOURCES;
-				goto out2;
-			}
-			pMLMEContext->pAd = pAd;
-			pMLMEContext->pIrp = NULL;
-			pMLMEContext->TransferBuffer = NULL;
-			pMLMEContext->InUse = FALSE;
-			pMLMEContext->IRPPending = FALSE;
-			pMLMEContext->bWaitingBulkOut = FALSE;
-			pMLMEContext->BulkOutSize = 0;
-			pMLMEContext->SelfIdx = i;
-
-			// Offset to next ring descriptor address
-			RingBaseVa = (PUCHAR) RingBaseVa + sizeof(TX_CONTEXT);
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", i));
-
-		//pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1);
-		pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE;
-		pAd->MgmtRing.TxCpuIdx = 0;
-		pAd->MgmtRing.TxDmaIdx = 0;
-
-		//
-		// BEACON_RING_SIZE
-		//
-		for(i=0; i<BEACON_RING_SIZE; i++) // 2
-		{
-			PTX_CONTEXT	pBeaconContext = &(pAd->BeaconContext[i]);
-
-
-			NdisZeroMemory(pBeaconContext, sizeof(TX_CONTEXT));
-
-			//Allocate URB
-			LM_USB_ALLOC(pObj, pBeaconContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
-							("<-- ERROR in Alloc TX BeaconContext[%d] urb!! \n", i),
-							out2,
-							("<-- ERROR in Alloc TX BeaconContext[%d] TX_BUFFER !! \n", i),
-							out3);
-
-			pBeaconContext->pAd = pAd;
-			pBeaconContext->pIrp = NULL;
-			pBeaconContext->InUse = FALSE;
-			pBeaconContext->IRPPending = FALSE;
-		}
-
-		//
-		// NullContext
-		//
-		NdisZeroMemory(pNullContext, sizeof(TX_CONTEXT));
-
-		//Allocate URB
-		LM_USB_ALLOC(pObj, pNullContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
-						("<-- ERROR in Alloc TX NullContext urb!! \n"),
-						out3,
-						("<-- ERROR in Alloc TX NullContext TX_BUFFER !! \n"),
-						out4);
-
-		pNullContext->pAd = pAd;
-		pNullContext->pIrp = NULL;
-		pNullContext->InUse = FALSE;
-		pNullContext->IRPPending = FALSE;
-
-		//
-		// RTSContext
-		//
-		NdisZeroMemory(pRTSContext, sizeof(TX_CONTEXT));
-
-		//Allocate URB
-		LM_USB_ALLOC(pObj, pRTSContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
-						("<-- ERROR in Alloc TX RTSContext urb!! \n"),
-						out4,
-						("<-- ERROR in Alloc TX RTSContext TX_BUFFER !! \n"),
-						out5);
-
-		pRTSContext->pAd = pAd;
-		pRTSContext->pIrp = NULL;
-		pRTSContext->InUse = FALSE;
-		pRTSContext->IRPPending = FALSE;
-
-		//
-		// PsPollContext
-		//
-		//NdisZeroMemory(pPsPollContext, sizeof(TX_CONTEXT));
-		//Allocate URB
-		LM_USB_ALLOC(pObj, pPsPollContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
-						("<-- ERROR in Alloc TX PsPollContext urb!! \n"),
-						out5,
-						("<-- ERROR in Alloc TX PsPollContext TX_BUFFER !! \n"),
-						out6);
-
-		pPsPollContext->pAd = pAd;
-		pPsPollContext->pIrp = NULL;
-		pPsPollContext->InUse = FALSE;
-		pPsPollContext->IRPPending = FALSE;
-		pPsPollContext->bAggregatible = FALSE;
-		pPsPollContext->LastOne = TRUE;
-
-	}   while (FALSE);
-
-
-done:
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit\n"));
-
-	return Status;
-
-	/* --------------------------- ERROR HANDLE --------------------------- */
-out6:
-	LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
-
-out5:
-	LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
-
-out4:
-	LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
-
-out3:
-	for(i=0; i<BEACON_RING_SIZE; i++)
-	{
-		PTX_CONTEXT	pBeaconContext = &(pAd->BeaconContext[i]);
-		if (pBeaconContext)
-			LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
-	}
-
-out2:
-	if (pAd->MgmtDescRing.AllocVa)
-	{
-		pMgmtRing = &pAd->MgmtRing;
-	for(i=0; i<MGMT_RING_SIZE; i++)
-	{
-		pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
-		if (pMLMEContext)
-			LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
-	}
-		NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0);
-		pAd->MgmtDescRing.AllocVa = NULL;
-	}
-
-out1:
-	for (acidx = 0; acidx < 4; acidx++)
-	{
-		PHT_TX_CONTEXT pTxContext = &(pAd->TxContext[acidx]);
-		if (pTxContext)
-			LM_URB_FREE(pObj, pTxContext, sizeof(HTTX_BUFFER));
-	}
-
-	// Here we didn't have any pre-allocated memory need to free.
-
-	return Status;
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Allocate DMA memory blocks for send, receive.
-
-Arguments:
-    pAd					Pointer to our adapter
-
-Return Value:
-	NDIS_STATUS_SUCCESS
-	NDIS_STATUS_FAILURE
-	NDIS_STATUS_RESOURCES
-
-Note:
-========================================================================
-*/
-NDIS_STATUS	RTMPAllocTxRxRingMemory(
-	IN	PRTMP_ADAPTER	pAd)
-{
-//	COUNTER_802_11	pCounter = &pAd->WlanCounters;
-	NDIS_STATUS		Status;
-	INT				num;
-
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
-
-
-	do
-	{
-		// Init the CmdQ and CmdQLock
-		NdisAllocateSpinLock(&pAd->CmdQLock);
-		NdisAcquireSpinLock(&pAd->CmdQLock);
-		RTUSBInitializeCmdQ(&pAd->CmdQ);
-		NdisReleaseSpinLock(&pAd->CmdQLock);
-
-
-		NdisAllocateSpinLock(&pAd->MLMEBulkOutLock);
-		//NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock);
-		NdisAllocateSpinLock(&pAd->BulkOutLock[0]);
-		NdisAllocateSpinLock(&pAd->BulkOutLock[1]);
-		NdisAllocateSpinLock(&pAd->BulkOutLock[2]);
-		NdisAllocateSpinLock(&pAd->BulkOutLock[3]);
-		NdisAllocateSpinLock(&pAd->BulkOutLock[4]);
-		NdisAllocateSpinLock(&pAd->BulkOutLock[5]);
-		NdisAllocateSpinLock(&pAd->BulkInLock);
-
-		for (num = 0; num < NUM_OF_TX_RING; num++)
-		{
-			NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]);
-		}
-
-//		NdisAllocateSpinLock(&pAd->MemLock);	// Not used in RT28XX
-
-//		NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit()
-//		NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit()
-
-//		for(num=0; num<MAX_LEN_OF_BA_REC_TABLE; num++)
-//		{
-//			NdisAllocateSpinLock(&pAd->BATable.BARecEntry[num].RxReRingLock);
-//		}
-
-		//
-		// Init Mac Table
-		//
-//		MacTableInitialize(pAd);
-
-		//
-		// Init send data structures and related parameters
-		//
-		Status = NICInitTransmit(pAd);
-		if (Status != NDIS_STATUS_SUCCESS)
-			break;
-
-		//
-		// Init receive data structures and related parameters
-		//
-		Status = NICInitRecv(pAd);
-		if (Status != NDIS_STATUS_SUCCESS)
-			break;
-
-		pAd->PendingIoCount = 1;
-
-	} while (FALSE);
-
-	NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));
-	pAd->FragFrame.pFragPacket =  RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
-
-	if (pAd->FragFrame.pFragPacket == NULL)
-	{
-		Status = NDIS_STATUS_RESOURCES;
-	}
-
-	DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
-	return Status;
-}
-
-
-/*
-========================================================================
-Routine Description:
-	Calls USB_InterfaceStop and frees memory allocated for the URBs
-    calls NdisMDeregisterDevice and frees the memory
-    allocated in VNetInitialize for the Adapter Object
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-VOID	RTMPFreeTxRxRingMemory(
-	IN	PRTMP_ADAPTER	pAd)
-{
-#define LM_URB_FREE(pObj, Context, BufferSize)				\
-	if (NULL != Context->pUrb) {							\
-		RTUSB_UNLINK_URB(Context->pUrb);					\
-		RTUSB_FREE_URB(Context->pUrb);						\
-		Context->pUrb = NULL; }								\
-	if (NULL != Context->TransferBuffer) {					\
-		RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize,	\
-								Context->TransferBuffer,	\
-								Context->data_dma);			\
-		Context->TransferBuffer = NULL; }
-
-
-	UINT                i, acidx;
-	PTX_CONTEXT			pNullContext   = &pAd->NullContext;
-	PTX_CONTEXT			pPsPollContext = &pAd->PsPollContext;
-	PTX_CONTEXT			pRTSContext    = &pAd->RTSContext;
-//	PHT_TX_CONTEXT 		pHTTXContext;
-	//PRTMP_REORDERBUF	pReorderBuf;
-	POS_COOKIE			pObj = (POS_COOKIE) pAd->OS_Cookie;
-//	RTMP_TX_RING		*pTxRing;
-
-	DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n"));
-	pObj = pObj;
-
-	// Free all resources for the RECEIVE buffer queue.
-	for(i=0; i<(RX_RING_SIZE); i++)
-	{
-		PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
-		if (pRxContext)
-			LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE);
-	}
-
-	// Free PsPoll frame resource
-	LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
-
-	// Free NULL frame resource
-	LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
-
-	// Free RTS frame resource
-	LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
-
-
-	// Free beacon frame resource
-	for(i=0; i<BEACON_RING_SIZE; i++)
-	{
-		PTX_CONTEXT	pBeaconContext = &(pAd->BeaconContext[i]);
-		if (pBeaconContext)
-			LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
-	}
-
-
-	// Free mgmt frame resource
-	for(i = 0; i < MGMT_RING_SIZE; i++)
-	{
-		PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
-		//LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
-		if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket)
-		{
-			RTMPFreeNdisPacket(pAd, pAd->MgmtRing.Cell[i].pNdisPacket);
-			pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
-			pMLMEContext->TransferBuffer = NULL;
-		}
-
-		if (pMLMEContext)
-		{
-			if (NULL != pMLMEContext->pUrb)
-			{
-				RTUSB_UNLINK_URB(pMLMEContext->pUrb);
-				RTUSB_FREE_URB(pMLMEContext->pUrb);
-				pMLMEContext->pUrb = NULL;
-			}
-		}
-	}
-	if (pAd->MgmtDescRing.AllocVa)
-		NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0);
-
-
-	// Free Tx frame resource
-		for(acidx=0; acidx<4; acidx++)
-		{
-		PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
-			if (pHTTXContext)
-				LM_URB_FREE(pObj, pHTTXContext, sizeof(HTTX_BUFFER));
-		}
-
-	if (pAd->FragFrame.pFragPacket)
-		RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS);
-
-	for(i=0; i<6; i++)
-	{
-		NdisFreeSpinLock(&pAd->BulkOutLock[i]);
-	}
-
-	NdisFreeSpinLock(&pAd->BulkInLock);
-	NdisFreeSpinLock(&pAd->MLMEBulkOutLock);
-
-	NdisFreeSpinLock(&pAd->CmdQLock);
-
-	// Clear all pending bulk-out request flags.
-	RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff);
-
-//	NdisFreeSpinLock(&pAd->MacTabLock);
-
-//	for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++)
-//	{
-//		NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock);
-//	}
-
-	DBGPRINT(RT_DEBUG_ERROR, ("<--- ReleaseAdapter\n"));
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Allocate memory for adapter control block.
-
-Arguments:
-    pAd					Pointer to our adapter
-
-Return Value:
-	NDIS_STATUS_SUCCESS
-	NDIS_STATUS_FAILURE
-	NDIS_STATUS_RESOURCES
-
-Note:
-========================================================================
-*/
-NDIS_STATUS AdapterBlockAllocateMemory(
-	IN PVOID	handle,
-	OUT	PVOID	*ppAd)
-{
-	PUSB_DEV	usb_dev;
-	POS_COOKIE	pObj = (POS_COOKIE) handle;
-
-
-	usb_dev = pObj->pUsb_Dev;
-
-	pObj->MLMEThr_pid	= NULL;
-	pObj->RTUSBCmdThr_pid	= NULL;
-
-	*ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER));
-
-	if (*ppAd)
-	{
-		NdisZeroMemory(*ppAd, sizeof(RTMP_ADAPTER));
-		((PRTMP_ADAPTER)*ppAd)->OS_Cookie = handle;
-		return (NDIS_STATUS_SUCCESS);
-	}
-	else
-	{
-		return (NDIS_STATUS_FAILURE);
-	}
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Create kernel threads & tasklets.
-
-Arguments:
-    *net_dev			Pointer to wireless net device interface
-
-Return Value:
-	NDIS_STATUS_SUCCESS
-	NDIS_STATUS_FAILURE
-
-Note:
-========================================================================
-*/
-NDIS_STATUS	 CreateThreads(
-	IN	struct net_device *net_dev)
-{
-	PRTMP_ADAPTER pAd = net_dev->ml_priv;
-	POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
-	pid_t pid_number;
-
-	//init_MUTEX(&(pAd->usbdev_semaphore));
-
-	init_MUTEX_LOCKED(&(pAd->mlme_semaphore));
-	init_completion (&pAd->mlmeComplete);
-
-	init_MUTEX_LOCKED(&(pAd->RTUSBCmd_semaphore));
-	init_completion (&pAd->CmdQComplete);
-
-	init_MUTEX_LOCKED(&(pAd->RTUSBTimer_semaphore));
-	init_completion (&pAd->TimerQComplete);
-
-	// Creat MLME Thread
-	pObj->MLMEThr_pid = NULL;
-	pid_number = kernel_thread(MlmeThread, pAd, CLONE_VM);
-	if (pid_number < 0)
-	{
-		printk (KERN_WARNING "%s: unable to start Mlme thread\n",pAd->net_dev->name);
-		return NDIS_STATUS_FAILURE;
-	}
-
-	pObj->MLMEThr_pid = find_get_pid(pid_number);
-
-	// Wait for the thread to start
-	wait_for_completion(&(pAd->mlmeComplete));
-
-	// Creat Command Thread
-	pObj->RTUSBCmdThr_pid = NULL;
-	pid_number = kernel_thread(RTUSBCmdThread, pAd, CLONE_VM);
-	if (pid_number < 0)
-	{
-		printk (KERN_WARNING "%s: unable to start RTUSBCmd thread\n",pAd->net_dev->name);
-		return NDIS_STATUS_FAILURE;
-	}
-
-	pObj->RTUSBCmdThr_pid = find_get_pid(pid_number);
-
-	wait_for_completion(&(pAd->CmdQComplete));
-
-	pObj->TimerQThr_pid = NULL;
-	pid_number = kernel_thread(TimerQThread, pAd, CLONE_VM);
-	if (pid_number < 0)
-	{
-		printk (KERN_WARNING "%s: unable to start TimerQThread\n",pAd->net_dev->name);
-		return NDIS_STATUS_FAILURE;
-	}
-
-	pObj->TimerQThr_pid = find_get_pid(pid_number);
-
-	// Wait for the thread to start
-	wait_for_completion(&(pAd->TimerQComplete));
-
-	// Create receive tasklet
-	tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (ULONG)pAd);
-	tasklet_init(&pObj->mgmt_dma_done_task, rt2870_mgmt_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->ac0_dma_done_task, rt2870_ac0_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->ac1_dma_done_task, rt2870_ac1_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->ac2_dma_done_task, rt2870_ac2_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->ac3_dma_done_task, rt2870_ac3_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->hcca_dma_done_task, rt2870_hcca_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->null_frame_complete_task, rt2870_null_frame_complete_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->rts_frame_complete_task, rt2870_rts_frame_complete_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->pspoll_frame_complete_task, rt2870_pspoll_frame_complete_tasklet, (unsigned long)pAd);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-/*
-========================================================================
-Routine Description:
- 	As STA's BSSID is a WC too, it uses shared key table.
- 	This function write correct unicast TX key to ASIC WCID.
- 	And we still make a copy in our MacTab.Content[BSSID_WCID].PairwiseKey.
-	Caller guarantee TKIP/AES always has keyidx = 0. (pairwise key)
-	Caller guarantee WEP calls this function when set Txkey,  default key index=0~3.
-
-Arguments:
-	pAd 					Pointer to our adapter
-	pKey					Pointer to the where the key stored
-
-Return Value:
-	NDIS_SUCCESS			Add key successfully
-
-Note:
-========================================================================
-*/
-VOID	RTMPAddBSSIDCipher(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	UCHAR				Aid,
-	IN	PNDIS_802_11_KEY	pKey,
-	IN  UCHAR   			CipherAlg)
-{
-	PUCHAR		pTxMic, pRxMic;
-	BOOLEAN 	bKeyRSC, bAuthenticator; // indicate the receive SC set by KeyRSC value
-//	UCHAR		CipherAlg;
-	UCHAR		i;
-	ULONG		WCIDAttri;
-	USHORT	 	offset;
-	UCHAR		KeyIdx, IVEIV[8];
-	UINT32		Value;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddBSSIDCipher==> Aid = %d\n",Aid));
-
-	// Bit 29 of Add-key KeyRSC
-	bKeyRSC 	   = (pKey->KeyIndex & 0x20000000) ? TRUE : FALSE;
-
-	// Bit 28 of Add-key Authenticator
-	bAuthenticator = (pKey->KeyIndex & 0x10000000) ? TRUE : FALSE;
-	KeyIdx = (UCHAR)pKey->KeyIndex&0xff;
-
-	if (KeyIdx > 4)
-		return;
-
-
-	if (pAd->MacTab.Content[Aid].PairwiseKey.CipherAlg == CIPHER_TKIP)
-	{	if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
-		{
-			// for WPA-None Tx, Rx MIC is the same
-			pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
-			pRxMic = pTxMic;
-		}
-		else if (bAuthenticator == TRUE)
-		{
-			pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
-			pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 24;
-		}
-		else
-		{
-			pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
-			pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 24;
-		}
-
-		offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE) + 0x10;
-		for (i=0; i<8; )
-		{
-			Value = *(pTxMic+i);
-			Value += (*(pTxMic+i+1)<<8);
-			Value += (*(pTxMic+i+2)<<16);
-			Value += (*(pTxMic+i+3)<<24);
-			RTUSBWriteMACRegister(pAd, offset+i, Value);
-			i+=4;
-		}
-
-		offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE) + 0x18;
-		for (i=0; i<8; )
-		{
-			Value = *(pRxMic+i);
-			Value += (*(pRxMic+i+1)<<8);
-			Value += (*(pRxMic+i+2)<<16);
-			Value += (*(pRxMic+i+3)<<24);
-			RTUSBWriteMACRegister(pAd, offset+i, Value);
-			i+=4;
-		}
-
-		// Only Key lenth equal to TKIP key have these
-		NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxMic, pRxMic, 8);
-		NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.TxMic, pTxMic, 8);
-
-		DBGPRINT(RT_DEBUG_TRACE,
-				("	TxMIC  = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n",
-				pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],
-				pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
-		DBGPRINT(RT_DEBUG_TRACE,
-				("	RxMIC  = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n",
-				pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],
-				pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
-	}
-
-	// 2. Record Security Key.
-	pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen= (UCHAR)pKey->KeyLength;
-	NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
-
-	// 3. Check RxTsc. And used to init to ASIC IV.
-	if (bKeyRSC == TRUE)
-		NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxTsc, &pKey->KeyRSC, 6);
-	else
-		NdisZeroMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxTsc, 6);
-
-	// 4. Init TxTsc to one based on WiFi WPA specs
-	pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[0] = 1;
-	pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[1] = 0;
-	pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[2] = 0;
-	pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[3] = 0;
-	pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[4] = 0;
-	pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[5] = 0;
-
-	CipherAlg = pAd->MacTab.Content[Aid].PairwiseKey.CipherAlg;
-
-	offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE);
-	RTUSBMultiWrite(pAd, (USHORT) offset, pKey->KeyMaterial,
-				((pKey->KeyLength == LEN_TKIP_KEY) ? 16 : (USHORT)pKey->KeyLength));
-
-	offset = SHARED_KEY_TABLE_BASE + (KeyIdx * HW_KEY_ENTRY_SIZE);
-	RTUSBMultiWrite(pAd, (USHORT) offset, pKey->KeyMaterial, (USHORT)pKey->KeyLength);
-
-	offset = PAIRWISE_IVEIV_TABLE_BASE + (Aid * HW_IVEIV_ENTRY_SIZE);
-	NdisZeroMemory(IVEIV, 8);
-
-	// IV/EIV
-	if ((CipherAlg == CIPHER_TKIP) ||
-		(CipherAlg == CIPHER_TKIP_NO_MIC) ||
-		(CipherAlg == CIPHER_AES))
-	{
-		IVEIV[3] = 0x20; // Eiv bit on. keyid always 0 for pairwise key
-	}
-	// default key idx needs to set.
-	// in TKIP/AES KeyIdx = 0 , WEP KeyIdx is default tx key.
-	else
-	{
-		IVEIV[3] |= (KeyIdx<< 6);
-	}
-	RTUSBMultiWrite(pAd, (USHORT) offset, IVEIV, 8);
-
-	// WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0
-	if ((CipherAlg == CIPHER_TKIP) ||
-		(CipherAlg == CIPHER_TKIP_NO_MIC) ||
-		(CipherAlg == CIPHER_AES))
-	{
-		WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
-	}
-	else
-		WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
-
-	offset = MAC_WCID_ATTRIBUTE_BASE + (Aid* HW_WCID_ATTRI_SIZE);
-	RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
-	RTUSBReadMACRegister(pAd, offset, &Value);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("BSSID_WCID : offset = %x, WCIDAttri = %lx\n",
-			offset, WCIDAttri));
-
-	// pAddr
-	// Add Bssid mac address at linkup. not here.  check!
-	/*offset = MAC_WCID_BASE + (BSSID_WCID * HW_WCID_ENTRY_SIZE);
-	*for (i=0; i<MAC_ADDR_LEN; i++)
-	{
-		RTMP_IO_WRITE8(pAd, offset+i, pKey->BSSID[i]);
-	}
-	*/
-
-	DBGPRINT(RT_DEBUG_ERROR, ("AddBSSIDasWCIDEntry: Alg=%s, KeyLength = %d\n",
-			CipherName[CipherAlg], pKey->KeyLength));
-	DBGPRINT(RT_DEBUG_TRACE, ("Key [idx=%x] [KeyLen = %d]\n",
-			pKey->KeyIndex, pKey->KeyLength));
-	for(i=0; i<pKey->KeyLength; i++)
-		DBGPRINT_RAW(RT_DEBUG_TRACE,(" %x:", pKey->KeyMaterial[i]));
-	DBGPRINT(RT_DEBUG_TRACE,("	 \n"));
-}
-
-/*
-========================================================================
-Routine Description:
-    Get a received packet.
-
-Arguments:
-	pAd					device control block
-	pSaveRxD			receive descriptor information
-	*pbReschedule		need reschedule flag
-	*pRxPending			pending received packet flag
-
-Return Value:
-    the recieved packet
-
-Note:
-========================================================================
-*/
-#define RT2870_RXDMALEN_FIELD_SIZE			4
-PNDIS_PACKET GetPacketFromRxRing(
-	IN		PRTMP_ADAPTER		pAd,
-	OUT		PRT28XX_RXD_STRUC	pSaveRxD,
-	OUT		BOOLEAN				*pbReschedule,
-	IN OUT	UINT32				*pRxPending)
-{
-	PRX_CONTEXT		pRxContext;
-	PNDIS_PACKET	pSkb;
-	PUCHAR			pData;
-	ULONG			ThisFrameLen;
-	ULONG			RxBufferLength;
-	PRXWI_STRUC		pRxWI;
-
-	pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex];
-	if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE))
-		return NULL;
-
-	RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition;
-	if (RxBufferLength < (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXWI_STRUC) + sizeof(RXINFO_STRUC)))
-	{
-		goto label_null;
-	}
-
-	pData = &pRxContext->TransferBuffer[pAd->ReadPosition]; /* 4KB */
-	// The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding)
-	ThisFrameLen = *pData + (*(pData+1)<<8);
-    if (ThisFrameLen == 0)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n",
-								pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));
-		goto label_null;
-	}
-	if ((ThisFrameLen&0x3) != 0)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n",
-								pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));
-		goto label_null;
-	}
-
-	if ((ThisFrameLen + 8)> RxBufferLength)	// 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n",
-						pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset, RxBufferLength, pAd->ReadPosition));
-
-		// error frame. finish this loop
-		goto label_null;
-	}
-
-	// skip USB frame length field
-	pData += RT2870_RXDMALEN_FIELD_SIZE;
-	pRxWI = (PRXWI_STRUC)pData;
-
-	if (pRxWI->MPDUtotalByteCount > ThisFrameLen)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n",
-									__func__, pRxWI->MPDUtotalByteCount, ThisFrameLen));
-		goto label_null;
-	}
-
-	// allocate a rx packet
-	pSkb = dev_alloc_skb(ThisFrameLen);
-	if (pSkb == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n", __func__));
-		goto label_null;
-	}
-
-	// copy the rx packet
-	memcpy(skb_put(pSkb, ThisFrameLen), pData, ThisFrameLen);
-	RTPKT_TO_OSPKT(pSkb)->dev = get_netdev_from_bssid(pAd, BSS0);
-	RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pSkb), PKTSRC_NDIS);
-
-	// copy RxD
-	*pSaveRxD = *(PRXINFO_STRUC)(pData + ThisFrameLen);
-
-	// update next packet read position.
-	pAd->ReadPosition += (ThisFrameLen + RT2870_RXDMALEN_FIELD_SIZE + RXINFO_SIZE);	// 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
-
-	return pSkb;
-
-label_null:
-
-	return NULL;
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Handle received packets.
-
-Arguments:
-	data				- URB information pointer
-
-Return Value:
-    None
-
-Note:
-========================================================================
-*/
-static void rx_done_tasklet(unsigned long data)
-{
-	purbb_t 			pUrb;
-	PRX_CONTEXT			pRxContext;
-	PRTMP_ADAPTER		pAd;
-	NTSTATUS			Status;
-	unsigned int		IrqFlags;
-
-	pUrb		= (purbb_t)data;
-	pRxContext	= (PRX_CONTEXT)pUrb->context;
-	pAd 		= pRxContext->pAd;
-	Status = pUrb->status;
-
-
-	RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
-	pRxContext->InUse = FALSE;
-	pRxContext->IRPPending = FALSE;
-	pRxContext->BulkInOffset += pUrb->actual_length;
-	//NdisInterlockedDecrement(&pAd->PendingRx);
-	pAd->PendingRx--;
-
-	if (Status == USB_ST_NOERROR)
-	{
-		pAd->BulkInComplete++;
-		pAd->NextRxBulkInPosition = 0;
-		if (pRxContext->BulkInOffset)	// As jan's comment, it may bulk-in success but size is zero.
-		{
-			pRxContext->Readable = TRUE;
-			INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
-		}
-		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
-	}
-	else	 // STATUS_OTHER
-	{
-		pAd->BulkInCompleteFail++;
-		// Still read this packet although it may comtain wrong bytes.
-		pRxContext->Readable = FALSE;
-		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
-
-		// Parsing all packets. because after reset, the index will reset to all zero.
-		if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-									fRTMP_ADAPTER_BULKIN_RESET |
-									fRTMP_ADAPTER_HALT_IN_PROGRESS |
-									fRTMP_ADAPTER_NIC_NOT_EXIST))))
-		{
-
-			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk In Failed. Status=%d, BIIdx=0x%x, BIRIdx=0x%x, actual_length= 0x%x\n",
-							Status, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pRxContext->pUrb->actual_length));
-
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
-		}
-	}
-
-	ASSERT((pRxContext->InUse == pRxContext->IRPPending));
-
-	RTUSBBulkReceive(pAd);
-
-	return;
-
-}
-
-
-static void rt2870_mgmt_dma_done_tasklet(unsigned long data)
-{
-	PRTMP_ADAPTER 	pAd;
-	PTX_CONTEXT		pMLMEContext;
-	int				index;
-	PNDIS_PACKET	pPacket;
-	purbb_t			pUrb;
-	NTSTATUS		Status;
-	unsigned long	IrqFlags;
-
-
-	pUrb			= (purbb_t)data;
-	pMLMEContext	= (PTX_CONTEXT)pUrb->context;
-	pAd 			= pMLMEContext->pAd;
-	Status			= pUrb->status;
-	index 			= pMLMEContext->SelfIdx;
-
-	ASSERT((pAd->MgmtRing.TxDmaIdx == index));
-
-	RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
-
-
-	if (Status != USB_ST_NOERROR)
-	{
-		//Bulk-Out fail status handle
-		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
-		{
-			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status));
-			// TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt?
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
-			pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
-		}
-	}
-
-	pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
-	RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
-
-	RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
-	// Reset MLME context flags
-	pMLMEContext->IRPPending = FALSE;
-	pMLMEContext->InUse = FALSE;
-	pMLMEContext->bWaitingBulkOut = FALSE;
-	pMLMEContext->BulkOutSize = 0;
-
-	pPacket = pAd->MgmtRing.Cell[index].pNdisPacket;
-	pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
-
-	// Increase MgmtRing Index
-	INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE);
-	pAd->MgmtRing.TxSwFreeIdx++;
-	RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
-
-	// No-matter success or fail, we free the mgmt packet.
-	if (pPacket)
-		RTMPFreeNdisPacket(pAd, pPacket);
-
-	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-								fRTMP_ADAPTER_HALT_IN_PROGRESS |
-								fRTMP_ADAPTER_NIC_NOT_EXIST))))
-	{
-		// do nothing and return directly.
-	}
-	else
-	{
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET) &&
-			((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG))
-		{	// For Mgmt Bulk-Out failed, ignore it now.
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
-		}
-		else
-		{
-
-			// Always call Bulk routine, even reset bulk.
-			// The protectioon of rest bulk should be in BulkOut routine
-			if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
-			{
-				RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
-			}
-				RTUSBKickBulkOut(pAd);
-			}
-		}
-
-}
-
-
-static void rt2870_hcca_dma_done_tasklet(unsigned long data)
-{
-	PRTMP_ADAPTER		pAd;
-	PHT_TX_CONTEXT		pHTTXContext;
-	UCHAR				BulkOutPipeId = 4;
-	purbb_t				pUrb;
-
-	DBGPRINT_RAW(RT_DEBUG_ERROR, ("--->hcca_dma_done_tasklet\n"));
-
-	pUrb			= (purbb_t)data;
-	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
-	pAd				= pHTTXContext->pAd;
-
-	rt2870_dataout_complete_tasklet((unsigned long)pUrb);
-
-	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-								fRTMP_ADAPTER_HALT_IN_PROGRESS |
-								fRTMP_ADAPTER_NIC_NOT_EXIST))))
-	{
-		// do nothing and return directly.
-	}
-	else
-	{
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
-		{
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
-		}
-		else
-		{	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
-			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
-				/*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
-				(pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
-				(pHTTXContext->bCurWriting == FALSE))
-			{
-				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
-			}
-
-			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<4);
-			RTUSBKickBulkOut(pAd);
-		}
-	}
-
-	DBGPRINT_RAW(RT_DEBUG_ERROR, ("<---hcca_dma_done_tasklet\n"));
-}
-
-
-static void rt2870_ac3_dma_done_tasklet(unsigned long data)
-{
-	PRTMP_ADAPTER		pAd;
-	PHT_TX_CONTEXT		pHTTXContext;
-	UCHAR				BulkOutPipeId = 3;
-	purbb_t				pUrb;
-
-
-	pUrb			= (purbb_t)data;
-	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
-	pAd				= pHTTXContext->pAd;
-
-	rt2870_dataout_complete_tasklet((unsigned long)pUrb);
-
-	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-								fRTMP_ADAPTER_HALT_IN_PROGRESS |
-								fRTMP_ADAPTER_NIC_NOT_EXIST))))
-	{
-		// do nothing and return directly.
-	}
-	else
-	{
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
-		{
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
-		}
-		else
-		{	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
-			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
-				/*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
-				(pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
-				(pHTTXContext->bCurWriting == FALSE))
-			{
-				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
-			}
-
-			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<3);
-			RTUSBKickBulkOut(pAd);
-		}
-	}
-
-
-		return;
-}
-
-
-static void rt2870_ac2_dma_done_tasklet(unsigned long data)
-{
-	PRTMP_ADAPTER		pAd;
-	PHT_TX_CONTEXT		pHTTXContext;
-	UCHAR				BulkOutPipeId = 2;
-	purbb_t				pUrb;
-
-
-	pUrb			= (purbb_t)data;
-	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
-	pAd				= pHTTXContext->pAd;
-
-	rt2870_dataout_complete_tasklet((unsigned long)pUrb);
-
-	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-								fRTMP_ADAPTER_HALT_IN_PROGRESS |
-								fRTMP_ADAPTER_NIC_NOT_EXIST))))
-	{
-		// do nothing and return directly.
-	}
-	else
-	{
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
-		{
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
-		}
-		else
-		{	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
-			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
-				/*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
-				(pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
-				(pHTTXContext->bCurWriting == FALSE))
-			{
-				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
-			}
-
-			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<2);
-			RTUSBKickBulkOut(pAd);
-		}
-	}
-
-		return;
-}
-
-
-static void rt2870_ac1_dma_done_tasklet(unsigned long data)
-{
-	PRTMP_ADAPTER		pAd;
-	PHT_TX_CONTEXT		pHTTXContext;
-	UCHAR				BulkOutPipeId = 1;
-	purbb_t				pUrb;
-
-
-	pUrb			= (purbb_t)data;
-	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
-	pAd				= pHTTXContext->pAd;
-
-	rt2870_dataout_complete_tasklet((unsigned long)pUrb);
-
-	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-								fRTMP_ADAPTER_HALT_IN_PROGRESS |
-								fRTMP_ADAPTER_NIC_NOT_EXIST))))
-	{
-		// do nothing and return directly.
-	}
-	else
-	{
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
-		{
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
-		}
-		else
-		{	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
-			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
-				/*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
-				(pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
-				(pHTTXContext->bCurWriting == FALSE))
-			{
-				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
-			}
-
-			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<1);
-			RTUSBKickBulkOut(pAd);
-		}
-	}
-
-
-	return;
-}
-
-
-static void rt2870_ac0_dma_done_tasklet(unsigned long data)
-{
-	PRTMP_ADAPTER		pAd;
-	PHT_TX_CONTEXT		pHTTXContext;
-	UCHAR				BulkOutPipeId = 0;
-	purbb_t				pUrb;
-
-
-	pUrb			= (purbb_t)data;
-	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
-	pAd				= pHTTXContext->pAd;
-
-	rt2870_dataout_complete_tasklet((unsigned long)pUrb);
-
-	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-								fRTMP_ADAPTER_HALT_IN_PROGRESS |
-								fRTMP_ADAPTER_NIC_NOT_EXIST))))
-	{
-		// do nothing and return directly.
-	}
-	else
-	{
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
-		{
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
-		}
-		else
-		{	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
-			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
-				/*  ((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
-				(pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
-				(pHTTXContext->bCurWriting == FALSE))
-			{
-				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
-			}
-
-			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL);
-			RTUSBKickBulkOut(pAd);
-		}
-	}
-
-
-	return;
-
-}
-
-
-static void rt2870_null_frame_complete_tasklet(unsigned long data)
-{
-	PRTMP_ADAPTER	pAd;
-	PTX_CONTEXT		pNullContext;
-	purbb_t			pUrb;
-	NTSTATUS		Status;
-	unsigned long	irqFlag;
-
-
-	pUrb			= (purbb_t)data;
-	pNullContext	= (PTX_CONTEXT)pUrb->context;
-	pAd 			= pNullContext->pAd;
-	Status 			= pUrb->status;
-
-	// Reset Null frame context flags
-	RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
-	pNullContext->IRPPending 	= FALSE;
-	pNullContext->InUse 		= FALSE;
-	pAd->BulkOutPending[0] = FALSE;
-	pAd->watchDogTxPendingCnt[0] = 0;
-
-	if (Status == USB_ST_NOERROR)
-	{
-		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
-
-		RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
-	}
-	else	// STATUS_OTHER
-	{
-		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
-		{
-			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out Null Frame Failed, ReasonCode=%d!\n", Status));
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
-			pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
-			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
-		}
-		else
-		{
-			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
-		}
-	}
-
-	// Always call Bulk routine, even reset bulk.
-	// The protectioon of rest bulk should be in BulkOut routine
-	RTUSBKickBulkOut(pAd);
-
-}
-
-
-static void rt2870_rts_frame_complete_tasklet(unsigned long data)
-{
-	PRTMP_ADAPTER	pAd;
-	PTX_CONTEXT		pRTSContext;
-	purbb_t			pUrb;
-	NTSTATUS		Status;
-	unsigned long	irqFlag;
-
-
-	pUrb		= (purbb_t)data;
-	pRTSContext	= (PTX_CONTEXT)pUrb->context;
-	pAd			= pRTSContext->pAd;
-	Status		= pUrb->status;
-
-	// Reset RTS frame context flags
-	RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
-	pRTSContext->IRPPending = FALSE;
-	pRTSContext->InUse		= FALSE;
-
-	if (Status == USB_ST_NOERROR)
-	{
-		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
-		RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
-	}
-	else	// STATUS_OTHER
-	{
-		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
-		{
-			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out RTS Frame Failed\n"));
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
-			pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
-			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
-		}
-		else
-		{
-			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
-		}
-	}
-
-	RTMP_SEM_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
-	pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE;
-	RTMP_SEM_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
-
-	// Always call Bulk routine, even reset bulk.
-	// The protectioon of rest bulk should be in BulkOut routine
-	RTUSBKickBulkOut(pAd);
-
-}
-
-
-static void rt2870_pspoll_frame_complete_tasklet(unsigned long data)
-{
-	PRTMP_ADAPTER	pAd;
-	PTX_CONTEXT		pPsPollContext;
-	purbb_t			pUrb;
-	NTSTATUS		Status;
-
-
-	pUrb			= (purbb_t)data;
-	pPsPollContext	= (PTX_CONTEXT)pUrb->context;
-	pAd				= pPsPollContext->pAd;
-	Status			= pUrb->status;
-
-	// Reset PsPoll context flags
-	pPsPollContext->IRPPending	= FALSE;
-	pPsPollContext->InUse		= FALSE;
-	pAd->watchDogTxPendingCnt[0] = 0;
-
-	if (Status == USB_ST_NOERROR)
-	{
-		RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
-	}
-	else // STATUS_OTHER
-	{
-		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
-		{
-			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out PSPoll Failed\n"));
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
-			pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
-		}
-	}
-
-	RTMP_SEM_LOCK(&pAd->BulkOutLock[0]);
-	pAd->BulkOutPending[0] = FALSE;
-	RTMP_SEM_UNLOCK(&pAd->BulkOutLock[0]);
-
-	// Always call Bulk routine, even reset bulk.
-	// The protectioon of rest bulk should be in BulkOut routine
-	RTUSBKickBulkOut(pAd);
-
-}
-
-
-static void rt2870_dataout_complete_tasklet(unsigned long data)
-{
-	PRTMP_ADAPTER		pAd;
-	purbb_t				pUrb;
-	POS_COOKIE			pObj;
-	PHT_TX_CONTEXT		pHTTXContext;
-	UCHAR				BulkOutPipeId;
-	NTSTATUS			Status;
-	unsigned long		IrqFlags;
-
-
-	pUrb			= (purbb_t)data;
-	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
-	pAd				= pHTTXContext->pAd;
-	pObj 			= (POS_COOKIE) pAd->OS_Cookie;
-	Status			= pUrb->status;
-
-	// Store BulkOut PipeId
-	BulkOutPipeId = pHTTXContext->BulkOutPipeId;
-	pAd->BulkOutDataOneSecCount++;
-
-	//DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition,
-	//		pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
-
-	RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
-	pAd->BulkOutPending[BulkOutPipeId] = FALSE;
-	pHTTXContext->IRPPending = FALSE;
-	pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
-
-	if (Status == USB_ST_NOERROR)
-	{
-		pAd->BulkOutComplete++;
-
-		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
-
-		pAd->Counters8023.GoodTransmits++;
-		//RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
-		FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext);
-		//RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
-
-
-	}
-	else	// STATUS_OTHER
-	{
-		PUCHAR	pBuf;
-
-		pAd->BulkOutCompleteOther++;
-
-		pBuf = &pHTTXContext->TransferBuffer->field.WirelessPacket[pHTTXContext->NextBulkOutPosition];
-
-		if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-									fRTMP_ADAPTER_HALT_IN_PROGRESS |
-									fRTMP_ADAPTER_NIC_NOT_EXIST |
-									fRTMP_ADAPTER_BULKOUT_RESET)))
-		{
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
-			pAd->bulkResetPipeid = BulkOutPipeId;
-			pAd->bulkResetReq[BulkOutPipeId] = pAd->BulkOutReq;
-		}
-		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
-
-		DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkOutDataPacket failed: ReasonCode=%d!\n", Status));
-		DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
-		DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Header:%x %x %x %x %x %x %x %x\n", pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6], pBuf[7]));
-		//DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther));
-
-	}
-
-	//
-	// bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut
-	// bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out.
-	//
-	//RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
-	if ((pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition) &&
-		(pHTTXContext->ENextBulkOutPosition != (pHTTXContext->CurWritePosition+8)) &&
-		!RTUSB_TEST_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)))
-	{
-		// Indicate There is data avaliable
-		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
-	}
-	//RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
-
-	// Always call Bulk routine, even reset bulk.
-	// The protection of rest bulk should be in BulkOut routine
-	RTUSBKickBulkOut(pAd);
-}
-
-/* End of 2870_rtmp_init.c */
diff --git a/drivers/staging/rt2870/common/acction.c b/drivers/staging/rt2870/common/acction.c
new file mode 100644
index 0000000..fd806c3
--- /dev/null
+++ b/drivers/staging/rt2870/common/acction.c
@@ -0,0 +1 @@
+#include "../../rt2860/common/action.c"
diff --git a/drivers/staging/rt2870/common/cmm_aes.c b/drivers/staging/rt2870/common/cmm_aes.c
new file mode 100644
index 0000000..15d6a14
--- /dev/null
+++ b/drivers/staging/rt2870/common/cmm_aes.c
@@ -0,0 +1 @@
+#include "../../rt2860/common/cmm_aes.c"
diff --git a/drivers/staging/rt2870/common/cmm_asic.c b/drivers/staging/rt2870/common/cmm_asic.c
new file mode 100644
index 0000000..38de817
--- /dev/null
+++ b/drivers/staging/rt2870/common/cmm_asic.c
@@ -0,0 +1 @@
+#include "../../rt2860/common/cmm_asic.c"
diff --git a/drivers/staging/rt2870/common/cmm_cfg.c b/drivers/staging/rt2870/common/cmm_cfg.c
new file mode 100644
index 0000000..6b2bdd7
--- /dev/null
+++ b/drivers/staging/rt2870/common/cmm_cfg.c
@@ -0,0 +1 @@
+#include "../../rt2860/common/cmm_cfg.c"
diff --git a/drivers/staging/rt2870/common/cmm_data_2870.c b/drivers/staging/rt2870/common/cmm_data_2870.c
deleted file mode 100644
index 3b63a48..0000000
--- a/drivers/staging/rt2870/common/cmm_data_2870.c
+++ /dev/null
@@ -1,936 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-*/
-/*
-   All functions in this file must be USB-depended, or you should out your function
-	in other files.
-
-*/
-#include "../rt_config.h"
-
-
-/*
-	We can do copy the frame into pTxContext when match following conditions.
-		=>
-		=>
-		=>
-*/
-static inline NDIS_STATUS RtmpUSBCanDoWrite(
-	IN RTMP_ADAPTER		*pAd,
-	IN UCHAR			QueIdx,
-	IN HT_TX_CONTEXT 	*pHTTXContext)
-{
-	NDIS_STATUS	canWrite = NDIS_STATUS_RESOURCES;
-
-	if (((pHTTXContext->CurWritePosition) < pHTTXContext->NextBulkOutPosition) && (pHTTXContext->CurWritePosition + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c1!\n"));
-		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
-	}
-	else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < LOCAL_TXBUF_SIZE))
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c2!\n"));
-		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
-	}
-	else if (pHTTXContext->bCurWriting == TRUE)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c3!\n"));
-	}
-	else
-	{
-		canWrite = NDIS_STATUS_SUCCESS;
-	}
-
-
-	return canWrite;
-}
-
-
-USHORT RtmpUSB_WriteSubTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	BOOLEAN			bIsLast,
-	OUT	USHORT			*FreeNumber)
-{
-
-	// Dummy function. Should be removed in the future.
-	return 0;
-
-}
-
-USHORT	RtmpUSB_WriteFragTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	UCHAR			fragNum,
-	OUT	USHORT			*FreeNumber)
-{
-	HT_TX_CONTEXT	*pHTTXContext;
-	USHORT			hwHdrLen;	// The hwHdrLen consist of 802.11 header length plus the header padding length.
-	UINT32			fillOffset;
-	TXINFO_STRUC	*pTxInfo;
-	TXWI_STRUC		*pTxWI;
-	PUCHAR			pWirelessPacket = NULL;
-	UCHAR			QueIdx;
-	NDIS_STATUS		Status;
-	unsigned long	IrqFlags;
-	UINT32			USBDMApktLen = 0, DMAHdrLen, padding;
-	BOOLEAN			TxQLastRound = FALSE;
-
-	//
-	// get Tx Ring Resource & Dma Buffer address
-	//
-	QueIdx = pTxBlk->QueIdx;
-	pHTTXContext  = &pAd->TxContext[QueIdx];
-
-	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-	pHTTXContext  = &pAd->TxContext[QueIdx];
-	fillOffset = pHTTXContext->CurWritePosition;
-
-	if(fragNum == 0)
-	{
-		// Check if we have enough space for this bulk-out batch.
-		Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
-		if (Status == NDIS_STATUS_SUCCESS)
-		{
-			pHTTXContext->bCurWriting = TRUE;
-
-			// Reserve space for 8 bytes padding.
-			if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
-			{
-				pHTTXContext->ENextBulkOutPosition += 8;
-				pHTTXContext->CurWritePosition += 8;
-				fillOffset += 8;
-			}
-			pTxBlk->Priv = 0;
-			pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
-		}
-		else
-		{
-			RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
-			return(Status);
-		}
-	}
-	else
-	{
-		// For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer.
-		Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
-		if (Status == NDIS_STATUS_SUCCESS)
-		{
-			fillOffset += pTxBlk->Priv;
-		}
-		else
-		{
-			RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
-			return(Status);
-		}
-	}
-
-	NdisZeroMemory((PUCHAR)(&pTxBlk->HeaderBuf[0]), TXINFO_SIZE);
-	pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
-	pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
-
-	pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
-
-	// copy TXWI + WLAN Header + LLC into DMA Header Buffer
-	//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
-	hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
-
-	// Build our URB for USBD
-	DMAHdrLen = TXWI_SIZE + hwHdrLen;
-	USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
-	padding = (4 - (USBDMApktLen % 4)) & 0x03;	// round up to 4 byte alignment
-	USBDMApktLen += padding;
-
-	pTxBlk->Priv += (TXINFO_SIZE + USBDMApktLen);
-
-	// For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload
-	RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/,  FALSE);
-
-	if (fragNum == pTxBlk->TotalFragNum)
-	{
-		pTxInfo->USBDMATxburst = 0;
-		if ((pHTTXContext->CurWritePosition + pTxBlk->Priv + 3906)> MAX_TXBULK_LIMIT)
-		{
-			pTxInfo->SwUseLastRound = 1;
-			TxQLastRound = TRUE;
-		}
-	}
-	else
-	{
-		pTxInfo->USBDMATxburst = 1;
-	}
-
-	NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
-	pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
-	pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
-
-	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-	NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
-
-	//	Zero the last padding.
-	pWirelessPacket += pTxBlk->SrcBufLen;
-	NdisZeroMemory(pWirelessPacket, padding + 8);
-
-	if (fragNum == pTxBlk->TotalFragNum)
-	{
-		RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-		// Update the pHTTXContext->CurWritePosition. 3906 used to prevent the NextBulkOut is a A-RALINK/A-MSDU Frame.
-		pHTTXContext->CurWritePosition += pTxBlk->Priv;
-		if (TxQLastRound == TRUE)
-			pHTTXContext->CurWritePosition = 8;
-		pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
-
-
-		// Finally, set bCurWriting as FALSE
-	pHTTXContext->bCurWriting = FALSE;
-
-		RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-		// succeed and release the skb buffer
-		RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
-	}
-
-
-	return(Status);
-
-}
-
-
-USHORT RtmpUSB_WriteSingleTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	BOOLEAN			bIsLast,
-	OUT	USHORT			*FreeNumber)
-{
-	HT_TX_CONTEXT	*pHTTXContext;
-	USHORT			hwHdrLen;
-	UINT32			fillOffset;
-	TXINFO_STRUC	*pTxInfo;
-	TXWI_STRUC		*pTxWI;
-	PUCHAR			pWirelessPacket;
-	UCHAR			QueIdx;
-	unsigned long	IrqFlags;
-	NDIS_STATUS		Status;
-	UINT32			USBDMApktLen = 0, DMAHdrLen, padding;
-	BOOLEAN			bTxQLastRound = FALSE;
-
-	// For USB, didn't need PCI_MAP_SINGLE()
-	//SrcBufPA = PCI_MAP_SINGLE(pAd, (char *) pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, PCI_DMA_TODEVICE);
-
-
-	//
-	// get Tx Ring Resource & Dma Buffer address
-	//
-	QueIdx = pTxBlk->QueIdx;
-
-	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-	pHTTXContext  = &pAd->TxContext[QueIdx];
-	fillOffset = pHTTXContext->CurWritePosition;
-
-
-
-	// Check ring full.
-	Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
-	if(Status == NDIS_STATUS_SUCCESS)
-	{
-		pHTTXContext->bCurWriting = TRUE;
-
-		pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
-		pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
-
-		// Reserve space for 8 bytes padding.
-		if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
-		{
-			pHTTXContext->ENextBulkOutPosition += 8;
-			pHTTXContext->CurWritePosition += 8;
-			fillOffset += 8;
-		}
-		pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
-
-		pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
-
-		// copy TXWI + WLAN Header + LLC into DMA Header Buffer
-		//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
-		hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
-
-		// Build our URB for USBD
-		DMAHdrLen = TXWI_SIZE + hwHdrLen;
-		USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
-		padding = (4 - (USBDMApktLen % 4)) & 0x03;	// round up to 4 byte alignment
-		USBDMApktLen += padding;
-
-		pTxBlk->Priv = (TXINFO_SIZE + USBDMApktLen);
-
-		// For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload
-		//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
-		RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/,  FALSE);
-
-		if ((pHTTXContext->CurWritePosition + 3906 + pTxBlk->Priv) > MAX_TXBULK_LIMIT)
-		{
-			pTxInfo->SwUseLastRound = 1;
-			bTxQLastRound = TRUE;
-		}
-		NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
-		pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
-
-		// We unlock it here to prevent the first 8 bytes maybe over-writed issue.
-		//	1. First we got CurWritePosition but the first 8 bytes still not write to the pTxcontext.
-		//	2. An interrupt break our routine and handle bulk-out complete.
-		//	3. In the bulk-out compllete, it need to do another bulk-out,
-		//			if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,
-		//			but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.
-		//	4. Interrupt complete.
-		//  5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.
-		//	6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.
-		//		and the packet will wrong.
-		pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
-		RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-		NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
-		pWirelessPacket += pTxBlk->SrcBufLen;
-		NdisZeroMemory(pWirelessPacket, padding + 8);
-
-		RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-		pHTTXContext->CurWritePosition += pTxBlk->Priv;
-		if (bTxQLastRound)
-			pHTTXContext->CurWritePosition = 8;
-		pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
-
-	pHTTXContext->bCurWriting = FALSE;
-	}
-
-
-	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-
-	// succeed and release the skb buffer
-	RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
-
-	return(Status);
-
-}
-
-
-USHORT RtmpUSB_WriteMultiTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	UCHAR			frameNum,
-	OUT	USHORT			*FreeNumber)
-{
-	HT_TX_CONTEXT	*pHTTXContext;
-	USHORT			hwHdrLen;	// The hwHdrLen consist of 802.11 header length plus the header padding length.
-	UINT32			fillOffset;
-	TXINFO_STRUC	*pTxInfo;
-	TXWI_STRUC		*pTxWI;
-	PUCHAR			pWirelessPacket = NULL;
-	UCHAR			QueIdx;
-	NDIS_STATUS		Status;
-	unsigned long	IrqFlags;
-	//UINT32			USBDMApktLen = 0, DMAHdrLen, padding;
-
-	//
-	// get Tx Ring Resource & Dma Buffer address
-	//
-	QueIdx = pTxBlk->QueIdx;
-	pHTTXContext  = &pAd->TxContext[QueIdx];
-
-	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-	if(frameNum == 0)
-	{
-		// Check if we have enough space for this bulk-out batch.
-		Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
-		if (Status == NDIS_STATUS_SUCCESS)
-		{
-			pHTTXContext->bCurWriting = TRUE;
-
-			pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
-			pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
-
-
-			// Reserve space for 8 bytes padding.
-			if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
-			{
-
-				pHTTXContext->CurWritePosition += 8;
-				pHTTXContext->ENextBulkOutPosition += 8;
-			}
-			fillOffset = pHTTXContext->CurWritePosition;
-			pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
-
-			pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
-
-			//
-			// Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
-			//
-			if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
-				//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD;
-				hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
-			else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
-				//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD;
-				hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + LENGTH_ARALINK_HEADER_FIELD;
-			else
-				//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
-				hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
-
-			// Update the pTxBlk->Priv.
-			pTxBlk->Priv = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
-
-			//	pTxInfo->USBDMApktLen now just a temp value and will to correct latter.
-			RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(pTxBlk->Priv), FALSE, FIFO_EDCA, FALSE /*NextValid*/,  FALSE);
-
-			// Copy it.
-			NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->Priv);
-			pHTTXContext->CurWriteRealPos += pTxBlk->Priv;
-			pWirelessPacket += pTxBlk->Priv;
-		}
-	}
-	else
-	{	// For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer.
-
-		Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
-		if (Status == NDIS_STATUS_SUCCESS)
-		{
-			fillOffset =  (pHTTXContext->CurWritePosition + pTxBlk->Priv);
-			pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
-
-			//hwHdrLen = pTxBlk->MpduHeaderLen;
-			NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->MpduHeaderLen);
-			pWirelessPacket += (pTxBlk->MpduHeaderLen);
-			pTxBlk->Priv += pTxBlk->MpduHeaderLen;
-		}
-		else
-		{	// It should not happened now unless we are going to shutdown.
-			DBGPRINT(RT_DEBUG_ERROR, ("WriteMultiTxResource():bCurWriting is FALSE when handle sub-sequent frames.\n"));
-			Status = NDIS_STATUS_FAILURE;
-		}
-	}
-
-
-	// We unlock it here to prevent the first 8 bytes maybe over-write issue.
-	//	1. First we got CurWritePosition but the first 8 bytes still not write to the pTxContext.
-	//	2. An interrupt break our routine and handle bulk-out complete.
-	//	3. In the bulk-out compllete, it need to do another bulk-out,
-	//			if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,
-	//			but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.
-	//	4. Interrupt complete.
-	//  5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.
-	//	6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.
-	//		and the packet will wrong.
-	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-	if (Status != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("WriteMultiTxResource: CWPos = %ld, NBOutPos = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition));
-		goto done;
-	}
-
-	// Copy the frame content into DMA buffer and update the pTxBlk->Priv
-	NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
-	pWirelessPacket += pTxBlk->SrcBufLen;
-	pTxBlk->Priv += pTxBlk->SrcBufLen;
-
-done:
-	// Release the skb buffer here
-	RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
-
-	return(Status);
-
-}
-
-
-VOID RtmpUSB_FinalWriteTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	USHORT			totalMPDUSize,
-	IN	USHORT			TxIdx)
-{
-	UCHAR			QueIdx;
-	HT_TX_CONTEXT	*pHTTXContext;
-	UINT32			fillOffset;
-	TXINFO_STRUC	*pTxInfo;
-	TXWI_STRUC		*pTxWI;
-	UINT32			USBDMApktLen, padding;
-	unsigned long	IrqFlags;
-	PUCHAR			pWirelessPacket;
-
-	QueIdx = pTxBlk->QueIdx;
-	pHTTXContext  = &pAd->TxContext[QueIdx];
-
-	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-	if (pHTTXContext->bCurWriting == TRUE)
-	{
-		fillOffset = pHTTXContext->CurWritePosition;
-		if (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
-			&& (pHTTXContext->bCopySavePad == TRUE))
-			pWirelessPacket = (PUCHAR)(&pHTTXContext->SavedPad[0]);
-		else
-			pWirelessPacket = (PUCHAR)(&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]);
-
-		//
-		// Update TxInfo->USBDMApktLen ,
-		//		the length = TXWI_SIZE + 802.11_hdr + 802.11_hdr_pad + payload_of_all_batch_frames + Bulk-Out-padding
-		//
-		pTxInfo = (PTXINFO_STRUC)(pWirelessPacket);
-
-		// Calculate the bulk-out padding
-		USBDMApktLen = pTxBlk->Priv - TXINFO_SIZE;
-		padding = (4 - (USBDMApktLen % 4)) & 0x03;	// round up to 4 byte alignment
-		USBDMApktLen += padding;
-
-		pTxInfo->USBDMATxPktLen = USBDMApktLen;
-
-		//
-		// Update TXWI->MPDUtotalByteCount ,
-		//		the length = 802.11 header + payload_of_all_batch_frames
-		pTxWI= (PTXWI_STRUC)(pWirelessPacket + TXINFO_SIZE);
-		pTxWI->MPDUtotalByteCount = totalMPDUSize;
-
-		//
-		// Update the pHTTXContext->CurWritePosition
-		//
-		pHTTXContext->CurWritePosition += (TXINFO_SIZE + USBDMApktLen);
-		if ((pHTTXContext->CurWritePosition + 3906)> MAX_TXBULK_LIMIT)
-		{	// Add 3906 for prevent the NextBulkOut packet size is a A-RALINK/A-MSDU Frame.
-			pHTTXContext->CurWritePosition = 8;
-			pTxInfo->SwUseLastRound = 1;
-		}
-		pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
-
-
-		//
-		//	Zero the last padding.
-		//
-		pWirelessPacket = (&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset + pTxBlk->Priv]);
-		NdisZeroMemory(pWirelessPacket, padding + 8);
-
-		// Finally, set bCurWriting as FALSE
-		pHTTXContext->bCurWriting = FALSE;
-
-	}
-	else
-	{	// It should not happened now unless we are going to shutdown.
-		DBGPRINT(RT_DEBUG_ERROR, ("FinalWriteTxResource():bCurWriting is FALSE when handle last frames.\n"));
-	}
-
-	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-}
-
-
-VOID RtmpUSBDataLastTxIdx(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			QueIdx,
-	IN	USHORT			TxIdx)
-{
-	// DO nothing for USB.
-}
-
-
-/*
-	When can do bulk-out:
-		1. TxSwFreeIdx < TX_RING_SIZE;
-			It means has at least one Ring entity is ready for bulk-out, kick it out.
-		2. If TxSwFreeIdx == TX_RING_SIZE
-			Check if the CurWriting flag is FALSE, if it's FALSE, we can do kick out.
-
-*/
-VOID RtmpUSBDataKickOut(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	UCHAR			QueIdx)
-{
-	RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
-	RTUSBKickBulkOut(pAd);
-
-}
-
-
-/*
-	Must be run in Interrupt context
-	This function handle RT2870 specific TxDesc and cpu index update and kick the packet out.
- */
-int RtmpUSBMgmtKickOut(
-	IN RTMP_ADAPTER 	*pAd,
-	IN UCHAR 			QueIdx,
-	IN PNDIS_PACKET		pPacket,
-	IN PUCHAR			pSrcBufVA,
-	IN UINT 			SrcBufLen)
-{
-	PTXINFO_STRUC	pTxInfo;
-	ULONG			BulkOutSize;
-	UCHAR			padLen;
-	PUCHAR			pDest;
-	ULONG			SwIdx = pAd->MgmtRing.TxCpuIdx;
-	PTX_CONTEXT		pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa;
-	unsigned long	IrqFlags;
-
-
-	pTxInfo = (PTXINFO_STRUC)(pSrcBufVA);
-
-	// Build our URB for USBD
-	BulkOutSize = SrcBufLen;
-	BulkOutSize = (BulkOutSize + 3) & (~3);
-	RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE,  FALSE);
-
-	BulkOutSize += 4; // Always add 4 extra bytes at every packet.
-
-	// If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again.
-	if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0)
-		BulkOutSize += 4;
-
-	padLen = BulkOutSize - SrcBufLen;
-	ASSERT((padLen <= RTMP_PKT_TAIL_PADDING));
-
-	// Now memzero all extra padding bytes.
-	pDest = (PUCHAR)(pSrcBufVA + SrcBufLen);
-	skb_put(GET_OS_PKT_TYPE(pPacket), padLen);
-	NdisZeroMemory(pDest, padLen);
-
-	RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
-
-	pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket;
-	pMLMEContext->TransferBuffer = (PTX_BUFFER)(GET_OS_PKT_DATAPTR(pPacket));
-
-	// Length in TxInfo should be 8 less than bulkout size.
-	pMLMEContext->BulkOutSize = BulkOutSize;
-	pMLMEContext->InUse = TRUE;
-	pMLMEContext->bWaitingBulkOut = TRUE;
-
-
-	//for debug
-	//hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize));
-
-	//pAd->RalinkCounters.KickTxCount++;
-	//pAd->RalinkCounters.OneSecTxDoneCount++;
-
-	//if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE)
-	//	needKickOut = TRUE;
-
-	// Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX
-	pAd->MgmtRing.TxSwFreeIdx--;
-	INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
-
-	RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
-
-	RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
-	//if (needKickOut)
-	RTUSBKickBulkOut(pAd);
-
-	return 0;
-}
-
-
-VOID RtmpUSBNullFrameKickOut(
-	IN RTMP_ADAPTER *pAd,
-	IN UCHAR		QueIdx,
-	IN UCHAR		*pNullFrame,
-	IN UINT32		frameLen)
-{
-	if (pAd->NullContext.InUse == FALSE)
-	{
-		PTX_CONTEXT		pNullContext;
-		PTXINFO_STRUC	pTxInfo;
-		PTXWI_STRUC		pTxWI;
-		PUCHAR			pWirelessPkt;
-
-		pNullContext = &(pAd->NullContext);
-
-		// Set the in use bit
-		pNullContext->InUse = TRUE;
-		pWirelessPkt = (PUCHAR)&pNullContext->TransferBuffer->field.WirelessPacket[0];
-
-		RTMPZeroMemory(&pWirelessPkt[0], 100);
-		pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[0];
-		RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE,  FALSE);
-		pTxInfo->QSEL = FIFO_EDCA;
-		pTxWI = (PTXWI_STRUC)&pWirelessPkt[TXINFO_SIZE];
-		RTMPWriteTxWI(pAd, pTxWI,  FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
-			0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
-		RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
-		pAd->NullContext.BulkOutSize =  TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
-
-		// Fill out frame length information for global Bulk out arbitor
-		//pNullContext->BulkOutSize = TransferBufferLength;
-		DBGPRINT(RT_DEBUG_TRACE, ("SYNC - send NULL Frame @%d Mbps...\n", RateIdToMbps[pAd->CommonCfg.TxRate]));
-		RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
-
-		// Kick bulk out
-		RTUSBKickBulkOut(pAd);
-	}
-
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
-
-	Arguments:
-		pRxD		Pointer	to the Rx descriptor
-
-	Return Value:
-		NDIS_STATUS_SUCCESS		No err
-		NDIS_STATUS_FAILURE		Error
-
-	Note:
-
-	========================================================================
-*/
-NDIS_STATUS	RTMPCheckRxError(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PHEADER_802_11	pHeader,
-	IN	PRXWI_STRUC	pRxWI,
-	IN	PRT28XX_RXD_STRUC	pRxINFO)
-{
-	PCIPHER_KEY pWpaKey;
-	INT	dBm;
-
-	if (pAd->bPromiscuous == TRUE)
-		return(NDIS_STATUS_SUCCESS);
-	if(pRxINFO == NULL)
-		return(NDIS_STATUS_FAILURE);
-
-	// Phy errors & CRC errors
-	if (pRxINFO->Crc)
-	{
-		// Check RSSI for Noise Hist statistic collection.
-		dBm = (INT) (pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
-		if (dBm <= -87)
-			pAd->StaCfg.RPIDensity[0] += 1;
-		else if (dBm <= -82)
-			pAd->StaCfg.RPIDensity[1] += 1;
-		else if (dBm <= -77)
-			pAd->StaCfg.RPIDensity[2] += 1;
-		else if (dBm <= -72)
-			pAd->StaCfg.RPIDensity[3] += 1;
-		else if (dBm <= -67)
-			pAd->StaCfg.RPIDensity[4] += 1;
-		else if (dBm <= -62)
-			pAd->StaCfg.RPIDensity[5] += 1;
-		else if (dBm <= -57)
-			pAd->StaCfg.RPIDensity[6] += 1;
-		else if (dBm > -57)
-			pAd->StaCfg.RPIDensity[7] += 1;
-
-		return(NDIS_STATUS_FAILURE);
-	}
-
-	// Add Rx size to channel load counter, we should ignore error counts
-	pAd->StaCfg.CLBusyBytes += (pRxWI->MPDUtotalByteCount+ 14);
-
-	// Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics
-	if (pHeader->FC.ToDs)
-	{
-		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Err;FC.ToDs\n"));
-		return NDIS_STATUS_FAILURE;
-	}
-
-	// Paul 04-03 for OFDM Rx length issue
-	if (pRxWI->MPDUtotalByteCount > MAX_AGGREGATION_SIZE)
-	{
-		DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n"));
-		return NDIS_STATUS_FAILURE;
-	}
-
-	// Drop not U2M frames, cant's drop here because we will drop beacon in this case
-	// I am kind of doubting the U2M bit operation
-	// if (pRxD->U2M == 0)
-	//	return(NDIS_STATUS_FAILURE);
-
-	// drop decyption fail frame
-	if (pRxINFO->Decrypted && pRxINFO->CipherErr)
-	{
-
-		//
-		// MIC Error
-		//
-		if ((pRxINFO->CipherErr == 2) && pRxINFO->MyBss)
-		{
-			pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
-			RTMPReportMicError(pAd, pWpaKey);
-			DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n"));
-		}
-
-		if (pRxINFO->Decrypted &&
-			(pAd->SharedKey[BSS0][pRxWI->KeyIndex].CipherAlg == CIPHER_AES) &&
-			(pHeader->Sequence == pAd->FragFrame.Sequence))
-		{
-			//
-			// Acceptable since the First FragFrame no CipherErr problem.
-			//
-			return(NDIS_STATUS_SUCCESS);
-		}
-
-		return(NDIS_STATUS_FAILURE);
-	}
-
-	return(NDIS_STATUS_SUCCESS);
-}
-
-VOID RT28xxUsbStaAsicForceWakeup(
-	IN PRTMP_ADAPTER pAd,
-	IN BOOLEAN       bFromTx)
-{
-    AUTO_WAKEUP_STRUC	AutoWakeupCfg;
-
-	AutoWakeupCfg.word = 0;
-	RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-
-	AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
-
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-}
-
-VOID RT28xxUsbStaAsicSleepThenAutoWakeup(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT TbttNumToNextWakeUp)
-{
-	AUTO_WAKEUP_STRUC	AutoWakeupCfg;
-
-	// we have decided to SLEEP, so at least do it for a BEACON period.
-	if (TbttNumToNextWakeUp == 0)
-		TbttNumToNextWakeUp = 1;
-
-	AutoWakeupCfg.word = 0;
-	RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-
-	AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
-	AutoWakeupCfg.field.EnableAutoWakeup = 1;
-	AutoWakeupCfg.field.AutoLeadTime = 5;
-	RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-
-	AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);   // send POWER-SAVE command to MCU. Timeout 40us.
-
-	OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
-
-}
-
-VOID RT28xxUsbMlmeRadioOn(
-	IN PRTMP_ADAPTER pAd)
-{
-    DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOn()\n"));
-
-	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
-		return;
-
-    	AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
-		RTMPusecDelay(10000);
-
-	NICResetFromError(pAd);
-
-	// Enable Tx/Rx
-	RTMPEnableRxTx(pAd);
-
-#ifdef RT3070
-	if (IS_RT3071(pAd))
-	{
-		RT30xxReverseRFSleepModeSetup(pAd);
-	}
-#endif // RT3070 //
-
-	// Clear Radio off flag
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-	RTUSBBulkReceive(pAd);
-
-	// Set LED
-	RTMPSetLED(pAd, LED_RADIO_ON);
-}
-
-VOID RT28xxUsbMlmeRadioOFF(
-	IN PRTMP_ADAPTER pAd)
-{
-	WPDMA_GLO_CFG_STRUC	GloCfg;
-	UINT32	Value, i;
-
-	DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOFF()\n"));
-
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
-		return;
-
-	// Set LED
-	RTMPSetLED(pAd, LED_RADIO_OFF);
-	// Set Radio off flag
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-	{
-		// Link down first if any association exists
-		if (INFRA_ON(pAd) || ADHOC_ON(pAd))
-			LinkDown(pAd, FALSE);
-		RTMPusecDelay(10000);
-
-		//==========================================
-		// Clean up old bss table
-		BssTableInit(&pAd->ScanTab);
-	}
-
-	if (pAd->CommonCfg.BBPCurrentBW == BW_40)
-	{
-		// Must using 40MHz.
-		AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
-	}
-	else
-	{
-		// Must using 20MHz.
-		AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
-	}
-
-	// Disable Tx/Rx DMA
-	RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word);	   // disable DMA
-	GloCfg.field.EnableTxDMA = 0;
-	GloCfg.field.EnableRxDMA = 0;
-	RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word);	   // abort all TX rings
-
-	// Waiting for DMA idle
-	i = 0;
-	do
-	{
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-		if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
-			break;
-
-		RTMPusecDelay(1000);
-	}while (i++ < 100);
-
-	// Disable MAC Tx/Rx
-	RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
-	Value &= (0xfffffff3);
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-
-	AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
-}
-
diff --git a/drivers/staging/rt2870/common/cmm_data_usb.c b/drivers/staging/rt2870/common/cmm_data_usb.c
new file mode 100644
index 0000000..704675f
--- /dev/null
+++ b/drivers/staging/rt2870/common/cmm_data_usb.c
@@ -0,0 +1 @@
+#include "../../rt2860/common/cmm_data_usb.c"
diff --git a/drivers/staging/rt2870/common/cmm_mac_usb.c b/drivers/staging/rt2870/common/cmm_mac_usb.c
new file mode 100644
index 0000000..b26af4a
--- /dev/null
+++ b/drivers/staging/rt2870/common/cmm_mac_usb.c
@@ -0,0 +1 @@
+#include "../../rt2860/common/cmm_mac_usb.c"
diff --git a/drivers/staging/rt2870/common/cmm_profile.c b/drivers/staging/rt2870/common/cmm_profile.c
new file mode 100644
index 0000000..9926e45
--- /dev/null
+++ b/drivers/staging/rt2870/common/cmm_profile.c
@@ -0,0 +1 @@
+#include "../../rt2860/common/cmm_profile.c"
diff --git a/drivers/staging/rt2870/common/cmm_tkip.c b/drivers/staging/rt2870/common/cmm_tkip.c
new file mode 100644
index 0000000..f73c71b
--- /dev/null
+++ b/drivers/staging/rt2870/common/cmm_tkip.c
@@ -0,0 +1 @@
+#include "../../rt2860/common/cmm_tkip.c"
diff --git a/drivers/staging/rt2870/common/cmm_wep.c b/drivers/staging/rt2870/common/cmm_wep.c
new file mode 100644
index 0000000..5f68107
--- /dev/null
+++ b/drivers/staging/rt2870/common/cmm_wep.c
@@ -0,0 +1 @@
+#include "../../rt2860/common/cmm_wep.c"
diff --git a/drivers/staging/rt2870/common/crypt_hmac.c b/drivers/staging/rt2870/common/crypt_hmac.c
new file mode 100644
index 0000000..24d84e7
--- /dev/null
+++ b/drivers/staging/rt2870/common/crypt_hmac.c
@@ -0,0 +1 @@
+#include "../../rt2860/common/crypt_hmac.c"
diff --git a/drivers/staging/rt2870/common/crypt_md5.c b/drivers/staging/rt2870/common/crypt_md5.c
new file mode 100644
index 0000000..457a2ca
--- /dev/null
+++ b/drivers/staging/rt2870/common/crypt_md5.c
@@ -0,0 +1 @@
+#include "../../rt2860/common/crypt_md5.c"
diff --git a/drivers/staging/rt2870/common/crypt_sha2.c b/drivers/staging/rt2870/common/crypt_sha2.c
new file mode 100644
index 0000000..07ffb30
--- /dev/null
+++ b/drivers/staging/rt2870/common/crypt_sha2.c
@@ -0,0 +1 @@
+#include "../../rt2860/common/crypt_sha2.c"
diff --git a/drivers/staging/rt2870/common/ee_efuse.c b/drivers/staging/rt2870/common/ee_efuse.c
new file mode 100644
index 0000000..0e34e65
--- /dev/null
+++ b/drivers/staging/rt2870/common/ee_efuse.c
@@ -0,0 +1 @@
+#include "../../rt2860/common/ee_efuse.c"
diff --git a/drivers/staging/rt2870/common/rt_channel.c b/drivers/staging/rt2870/common/rt_channel.c
new file mode 100644
index 0000000..c8ceb4c
--- /dev/null
+++ b/drivers/staging/rt2870/common/rt_channel.c
@@ -0,0 +1 @@
+#include "../../rt2860/common/rt_channel.c"
diff --git a/drivers/staging/rt2870/common/rt_rf.c b/drivers/staging/rt2870/common/rt_rf.c
new file mode 100644
index 0000000..b81cff3
--- /dev/null
+++ b/drivers/staging/rt2870/common/rt_rf.c
@@ -0,0 +1 @@
+#include "../../rt2860/common/rt_rf.c"
diff --git a/drivers/staging/rt2870/common/rtmp_mcu.c b/drivers/staging/rt2870/common/rtmp_mcu.c
new file mode 100644
index 0000000..20b7f13
--- /dev/null
+++ b/drivers/staging/rt2870/common/rtmp_mcu.c
@@ -0,0 +1 @@
+#include "../../rt2860/common/rtmp_mcu.c"
diff --git a/drivers/staging/rt2870/common/rtmp_timer.c b/drivers/staging/rt2870/common/rtmp_timer.c
new file mode 100644
index 0000000..fd4aedc
--- /dev/null
+++ b/drivers/staging/rt2870/common/rtmp_timer.c
@@ -0,0 +1 @@
+#include "../../rt2860/common/rtmp_timer.c"
diff --git a/drivers/staging/rt2870/common/rtusb_bulk.c b/drivers/staging/rt2870/common/rtusb_bulk.c
index a4244b5..379780c 100644
--- a/drivers/staging/rt2870/common/rtusb_bulk.c
+++ b/drivers/staging/rt2870/common/rtusb_bulk.c
@@ -1,4 +1,4 @@
- /*
+/*
  *************************************************************************
  * Ralink Tech Inc.
  * 5F., No.36, Taiyuan St., Jhubei City,
@@ -37,133 +37,124 @@
 
 */
 
+#ifdef RTMP_MAC_USB
+
 #include "../rt_config.h"
-// Match total 6 bulkout endpoint to corresponding queue.
-UCHAR	EpToQueue[6]={FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_MGMT};
+/* Match total 6 bulkout endpoint to corresponding queue. */
+u8 EpToQueue[6] =
+    { FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_MGMT };
 
-//static BOOLEAN SingleBulkOut = FALSE;
+/*static BOOLEAN SingleBulkOut = FALSE; */
 
-void RTUSB_FILL_BULK_URB (struct urb *pUrb,
-	struct usb_device *pUsb_Dev,
-	unsigned int bulkpipe,
-	void *pTransferBuf,
-	int BufSize,
-	usb_complete_t Complete,
-	void *pContext)
+void RTUSB_FILL_BULK_URB(struct urb *pUrb,
+			 struct usb_device *pUsb_Dev,
+			 unsigned int bulkpipe,
+			 void *pTransferBuf,
+			 int BufSize, usb_complete_t Complete, void *pContext)
 {
 
-	usb_fill_bulk_urb(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, (usb_complete_t)Complete, pContext);
+	usb_fill_bulk_urb(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize,
+			  (usb_complete_t) Complete, pContext);
 
 }
 
-VOID	RTUSBInitTxDesc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PTX_CONTEXT		pTxContext,
-	IN	UCHAR			BulkOutPipeId,
-	IN	usb_complete_t	Func)
+void RTUSBInitTxDesc(struct rt_rtmp_adapter *pAd,
+		     struct rt_tx_context *pTxContext,
+		     u8 BulkOutPipeId, IN usb_complete_t Func)
 {
-	PURB				pUrb;
-	PUCHAR				pSrc = NULL;
-	POS_COOKIE			pObj = (POS_COOKIE) pAd->OS_Cookie;
+	PURB pUrb;
+	u8 *pSrc = NULL;
+	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
 
 	pUrb = pTxContext->pUrb;
 	ASSERT(pUrb);
 
-	// Store BulkOut PipeId
+	/* Store BulkOut PipeId */
 	pTxContext->BulkOutPipeId = BulkOutPipeId;
 
-	if (pTxContext->bAggregatible)
-	{
+	if (pTxContext->bAggregatible) {
 		pSrc = &pTxContext->TransferBuffer->Aggregation[2];
-	}
-	else
-	{
-		pSrc = (PUCHAR) pTxContext->TransferBuffer->field.WirelessPacket;
+	} else {
+		pSrc =
+		    (u8 *)pTxContext->TransferBuffer->field.WirelessPacket;
 	}
 
-
-	//Initialize a tx bulk urb
+	/*Initialize a tx bulk urb */
 	RTUSB_FILL_BULK_URB(pUrb,
-						pObj->pUsb_Dev,
-						usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
-						pSrc,
-						pTxContext->BulkOutSize,
-						Func,
-						pTxContext);
+			    pObj->pUsb_Dev,
+			    usb_sndbulkpipe(pObj->pUsb_Dev,
+					    pAd->BulkOutEpAddr[BulkOutPipeId]),
+			    pSrc, pTxContext->BulkOutSize, Func, pTxContext);
 
 	if (pTxContext->bAggregatible)
-		pUrb->transfer_dma	= (pTxContext->data_dma + TX_BUFFER_NORMSIZE + 2);
+		pUrb->transfer_dma =
+		    (pTxContext->data_dma + TX_BUFFER_NORMSIZE + 2);
 	else
-		pUrb->transfer_dma	= pTxContext->data_dma;
+		pUrb->transfer_dma = pTxContext->data_dma;
 
 	pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
 }
 
-VOID	RTUSBInitHTTxDesc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PHT_TX_CONTEXT	pTxContext,
-	IN	UCHAR			BulkOutPipeId,
-	IN	ULONG			BulkOutSize,
-	IN	usb_complete_t	Func)
+void RTUSBInitHTTxDesc(struct rt_rtmp_adapter *pAd,
+		       struct rt_ht_tx_context *pTxContext,
+		       u8 BulkOutPipeId,
+		       unsigned long BulkOutSize, IN usb_complete_t Func)
 {
-	PURB				pUrb;
-	PUCHAR				pSrc = NULL;
-	POS_COOKIE			pObj = (POS_COOKIE) pAd->OS_Cookie;
+	PURB pUrb;
+	u8 *pSrc = NULL;
+	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
 
 	pUrb = pTxContext->pUrb;
 	ASSERT(pUrb);
 
-	// Store BulkOut PipeId
+	/* Store BulkOut PipeId */
 	pTxContext->BulkOutPipeId = BulkOutPipeId;
 
-	pSrc = &pTxContext->TransferBuffer->field.WirelessPacket[pTxContext->NextBulkOutPosition];
+	pSrc =
+	    &pTxContext->TransferBuffer->field.WirelessPacket[pTxContext->
+							      NextBulkOutPosition];
 
-
-	//Initialize a tx bulk urb
+	/*Initialize a tx bulk urb */
 	RTUSB_FILL_BULK_URB(pUrb,
-						pObj->pUsb_Dev,
-						usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
-						pSrc,
-						BulkOutSize,
-						Func,
-						pTxContext);
+			    pObj->pUsb_Dev,
+			    usb_sndbulkpipe(pObj->pUsb_Dev,
+					    pAd->BulkOutEpAddr[BulkOutPipeId]),
+			    pSrc, BulkOutSize, Func, pTxContext);
 
-	pUrb->transfer_dma	= (pTxContext->data_dma + pTxContext->NextBulkOutPosition);
+	pUrb->transfer_dma =
+	    (pTxContext->data_dma + pTxContext->NextBulkOutPosition);
 	pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
 }
 
-VOID	RTUSBInitRxDesc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PRX_CONTEXT		pRxContext)
+void RTUSBInitRxDesc(struct rt_rtmp_adapter *pAd, struct rt_rx_context *pRxContext)
 {
-	PURB				pUrb;
-	POS_COOKIE			pObj = (POS_COOKIE) pAd->OS_Cookie;
-	ULONG				RX_bulk_size;
-
+	PURB pUrb;
+	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
+	unsigned long RX_bulk_size;
 
 	pUrb = pRxContext->pUrb;
 	ASSERT(pUrb);
 
-	if ( pAd->BulkInMaxPacketSize == 64)
+	if (pAd->BulkInMaxPacketSize == 64)
 		RX_bulk_size = 4096;
 	else
 		RX_bulk_size = MAX_RXBULK_SIZE;
 
-	//Initialize a rx bulk urb
+	/*Initialize a rx bulk urb */
 	RTUSB_FILL_BULK_URB(pUrb,
-						pObj->pUsb_Dev,
-						usb_rcvbulkpipe(pObj->pUsb_Dev, pAd->BulkInEpAddr),
-						&(pRxContext->TransferBuffer[pAd->NextRxBulkInPosition]),
-						RX_bulk_size - (pAd->NextRxBulkInPosition),
-						(usb_complete_t)RTUSBBulkRxComplete,
-						(void *)pRxContext);
+			    pObj->pUsb_Dev,
+			    usb_rcvbulkpipe(pObj->pUsb_Dev, pAd->BulkInEpAddr),
+			    &(pRxContext->
+			      TransferBuffer[pAd->NextRxBulkInPosition]),
+			    RX_bulk_size - (pAd->NextRxBulkInPosition),
+			    (usb_complete_t) RTUSBBulkRxComplete,
+			    (void *)pRxContext);
 
-	pUrb->transfer_dma	= pRxContext->data_dma + pAd->NextRxBulkInPosition;
+	pUrb->transfer_dma = pRxContext->data_dma + pAd->NextRxBulkInPosition;
 	pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
-
 }
 
 /*
@@ -188,177 +179,215 @@
 		if(1 /*!(in_interrupt() & 0xffff0000)*/)	\
 			RTMP_IRQ_UNLOCK((pLock), IrqFlags);
 
-
-VOID	RTUSBBulkOutDataPacket(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			BulkOutPipeId,
-	IN	UCHAR			Index)
+void RTUSBBulkOutDataPacket(struct rt_rtmp_adapter *pAd,
+			    u8 BulkOutPipeId, u8 Index)
 {
 
-	PHT_TX_CONTEXT	pHTTXContext;
-	PURB			pUrb;
-	int				ret = 0;
-	PTXINFO_STRUC	pTxInfo, pLastTxInfo = NULL;
-	PTXWI_STRUC             pTxWI;
-	ULONG			TmpBulkEndPos, ThisBulkSize;
-	unsigned long	IrqFlags = 0, IrqFlags2 = 0;
-	PUCHAR			pWirelessPkt, pAppendant;
-	BOOLEAN			bTxQLastRound = FALSE;
-	UCHAR			allzero[4]= {0x0,0x0,0x0,0x0};
+	struct rt_ht_tx_context *pHTTXContext;
+	PURB pUrb;
+	int ret = 0;
+	struct rt_txinfo *pTxInfo, *pLastTxInfo = NULL;
+	struct rt_txwi * pTxWI;
+	unsigned long TmpBulkEndPos, ThisBulkSize;
+	unsigned long IrqFlags = 0, IrqFlags2 = 0;
+	u8 *pWirelessPkt, *pAppendant;
+	BOOLEAN bTxQLastRound = FALSE;
+	u8 allzero[4] = { 0x0, 0x0, 0x0, 0x0 };
 
 	BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
-	if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
-	{
+	if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE)
+	    || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) {
 		BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
 		return;
 	}
 	pAd->BulkOutPending[BulkOutPipeId] = TRUE;
 
 	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
-		)
-	{
+	    ) {
 		pAd->BulkOutPending[BulkOutPipeId] = FALSE;
 		BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
 		return;
 	}
 	BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
 
-
 	pHTTXContext = &(pAd->TxContext[BulkOutPipeId]);
 
 	BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
-	if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)
-		|| ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
-	{
-		BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
+	if ((pHTTXContext->ENextBulkOutPosition ==
+	     pHTTXContext->CurWritePosition)
+	    || ((pHTTXContext->ENextBulkOutPosition - 8) ==
+		pHTTXContext->CurWritePosition)) {
+		BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId],
+				IrqFlags2);
 
 		BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
 		pAd->BulkOutPending[BulkOutPipeId] = FALSE;
 
-		// Clear Data flag
-		RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
-		RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
+		/* Clear Data flag */
+		RTUSB_CLEAR_BULK_FLAG(pAd,
+				      (fRTUSB_BULK_OUT_DATA_FRAG <<
+				       BulkOutPipeId));
+		RTUSB_CLEAR_BULK_FLAG(pAd,
+				      (fRTUSB_BULK_OUT_DATA_NORMAL <<
+				       BulkOutPipeId));
 
 		BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
 		return;
 	}
+	/* Clear Data flag */
+	RTUSB_CLEAR_BULK_FLAG(pAd,
+			      (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
+	RTUSB_CLEAR_BULK_FLAG(pAd,
+			      (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
 
-	// Clear Data flag
-	RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
-	RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
-
-	//DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", in_interrupt(),
-	//							pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition,
-	//							pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
+	/*DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", in_interrupt(), */
+	/*                                                      pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, */
+	/*                                                      pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); */
 	pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition;
 	ThisBulkSize = 0;
 	TmpBulkEndPos = pHTTXContext->NextBulkOutPosition;
 	pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0];
 
-	if ((pHTTXContext->bCopySavePad == TRUE))
-	{
-		if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
-		{
-			DBGPRINT_RAW(RT_DEBUG_ERROR,("e1, allzero : %x  %x  %x  %x  %x  %x  %x  %x \n",
-				pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
-				,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
+	if ((pHTTXContext->bCopySavePad == TRUE)) {
+		if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero, 4)) {
+			DBGPRINT_RAW(RT_DEBUG_ERROR,
+				     ("e1, allzero : %x  %x  %x  %x  %x  %x  %x  %x \n",
+				      pHTTXContext->SavedPad[0],
+				      pHTTXContext->SavedPad[1],
+				      pHTTXContext->SavedPad[2],
+				      pHTTXContext->SavedPad[3]
+				      , pHTTXContext->SavedPad[4],
+				      pHTTXContext->SavedPad[5],
+				      pHTTXContext->SavedPad[6],
+				      pHTTXContext->SavedPad[7]));
 		}
-		NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos], pHTTXContext->SavedPad, 8);
+		NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos],
+			       pHTTXContext->SavedPad, 8);
 		pHTTXContext->bCopySavePad = FALSE;
 		if (pAd->bForcePrintTX == TRUE)
-			DBGPRINT(RT_DEBUG_TRACE,("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld.   ENextBulk = %ld.\n",   pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition));
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld.   ENextBulk = %ld.\n",
+				  pHTTXContext->CurWritePosition,
+				  pHTTXContext->NextBulkOutPosition,
+				  pHTTXContext->ENextBulkOutPosition));
 	}
 
-	do
-	{
-		pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[TmpBulkEndPos];
-		pTxWI = (PTXWI_STRUC)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE];
+	do {
+		pTxInfo = (struct rt_txinfo *)& pWirelessPkt[TmpBulkEndPos];
+		pTxWI =
+		    (struct rt_txwi *) & pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE];
 
 		if (pAd->bForcePrintTX == TRUE)
-			DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkOutDataPacket AMPDU = %d.\n",   pTxWI->AMPDU));
+			DBGPRINT(RT_DEBUG_TRACE,
+				 ("RTUSBBulkOutDataPacket AMPDU = %d.\n",
+				  pTxWI->AMPDU));
 
-		// add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items
-		//if ((ThisBulkSize != 0)  && (pTxWI->AMPDU == 0))
-		if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK))
-		{
-			if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000))
-			{
-				// Limit BulkOut size to about 4k bytes.
-				pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+		/* add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items */
+		/*if ((ThisBulkSize != 0)  && (pTxWI->AMPDU == 0)) */
+		if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK)) {
+			if (((ThisBulkSize & 0xffff8000) != 0)
+			    || ((ThisBulkSize & 0x1000) == 0x1000)) {
+				/* Limit BulkOut size to about 4k bytes. */
+				pHTTXContext->ENextBulkOutPosition =
+				    TmpBulkEndPos;
 				break;
-			}
-			else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0)  && (pTxWI->AMPDU == 0))*/)
-			{
-				// For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
-				// For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.
-				pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+			} else
+			    if (((pAd->BulkOutMaxPacketSize < 512)
+				 && ((ThisBulkSize & 0xfffff800) !=
+				     0))
+				/*|| ( (ThisBulkSize != 0)  && (pTxWI->AMPDU == 0)) */
+				) {
+				/* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */
+				/* For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04. */
+				pHTTXContext->ENextBulkOutPosition =
+				    TmpBulkEndPos;
 				break;
 			}
 		}
-		// end Iverson
-		else
-		{
-			if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000))
-			{	// Limit BulkOut size to about 24k bytes.
-				pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+		/* end Iverson */
+		else {
+			if (((ThisBulkSize & 0xffff8000) != 0) || ((ThisBulkSize & 0x6000) == 0x6000)) {	/* Limit BulkOut size to about 24k bytes. */
+				pHTTXContext->ENextBulkOutPosition =
+				    TmpBulkEndPos;
 				break;
-			}
-			else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0)  && (pTxWI->AMPDU == 0))*/)
-			{	// For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
-				// For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.
-				pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+			} else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize & 0xfffff800) != 0)) /*|| ( (ThisBulkSize != 0)  && (pTxWI->AMPDU == 0)) */ ) {	/* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */
+				/* For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04. */
+				pHTTXContext->ENextBulkOutPosition =
+				    TmpBulkEndPos;
 				break;
 			}
 		}
 
-		if (TmpBulkEndPos == pHTTXContext->CurWritePosition)
-		{
+		if (TmpBulkEndPos == pHTTXContext->CurWritePosition) {
 			pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
 			break;
 		}
 
-		//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
-		if (pTxInfo->QSEL != FIFO_EDCA)
-		{
-			printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __func__, pTxInfo->QSEL);
-			printk("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad);
-			hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition));
+		if (pTxInfo->QSEL != FIFO_EDCA) {
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n",
+				  __FUNCTION__, pTxInfo->QSEL));
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n",
+				  pHTTXContext->CurWritePosition,
+				  pHTTXContext->NextBulkOutPosition,
+				  pHTTXContext->ENextBulkOutPosition,
+				  pHTTXContext->bCopySavePad));
+			hex_dump("Wrong QSel Pkt:",
+				 (u8 *)& pWirelessPkt[TmpBulkEndPos],
+				 (pHTTXContext->CurWritePosition -
+				  pHTTXContext->NextBulkOutPosition));
 		}
 
-		if (pTxInfo->USBDMATxPktLen <= 8)
-		{
-			BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
-			DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n",
-					pHTTXContext->BulkOutSize, pHTTXContext->bCopySavePad, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->CurWriteRealPos));
+		if (pTxInfo->USBDMATxPktLen <= 8) {
+			BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId],
+					IrqFlags2);
+			DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE */ ,
+				 ("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n",
+				  pHTTXContext->BulkOutSize,
+				  pHTTXContext->bCopySavePad,
+				  pHTTXContext->CurWritePosition,
+				  pHTTXContext->NextBulkOutPosition,
+				  pHTTXContext->CurWriteRealPos));
 			{
-				DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("%x  %x  %x  %x  %x  %x  %x  %x \n",
-					pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
-					,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
+				DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE */
+					     ,
+					     ("%x  %x  %x  %x  %x  %x  %x  %x \n",
+					      pHTTXContext->SavedPad[0],
+					      pHTTXContext->SavedPad[1],
+					      pHTTXContext->SavedPad[2],
+					      pHTTXContext->SavedPad[3]
+					      , pHTTXContext->SavedPad[4],
+					      pHTTXContext->SavedPad[5],
+					      pHTTXContext->SavedPad[6],
+					      pHTTXContext->SavedPad[7]));
 			}
 			pAd->bForcePrintTX = TRUE;
-			BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+			BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId],
+				      IrqFlags);
 			pAd->BulkOutPending[BulkOutPipeId] = FALSE;
-			BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
-			//DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen));
+			BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId],
+					IrqFlags);
+			/*DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen)); */
 			return;
 		}
-
-			// Increase Total transmit byte counter
-		pAd->RalinkCounters.OneSecTransmittedByteCount +=  pTxWI->MPDUtotalByteCount;
-		pAd->RalinkCounters.TransmittedByteCount +=  pTxWI->MPDUtotalByteCount;
+		/* Increase Total transmit byte counter */
+		pAd->RalinkCounters.OneSecTransmittedByteCount +=
+		    pTxWI->MPDUtotalByteCount;
+		pAd->RalinkCounters.TransmittedByteCount +=
+		    pTxWI->MPDUtotalByteCount;
 
 		pLastTxInfo = pTxInfo;
 
-		// Make sure we use EDCA QUEUE.
-		pTxInfo->QSEL = FIFO_EDCA;  //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
-		ThisBulkSize += (pTxInfo->USBDMATxPktLen+4);
-		TmpBulkEndPos += (pTxInfo->USBDMATxPktLen+4);
+		/* Make sure we use EDCA QUEUE. */
+		pTxInfo->QSEL = FIFO_EDCA;
+		ThisBulkSize += (pTxInfo->USBDMATxPktLen + 4);
+		TmpBulkEndPos += (pTxInfo->USBDMATxPktLen + 4);
 
 		if (TmpBulkEndPos != pHTTXContext->CurWritePosition)
 			pTxInfo->USBDMANextVLD = 1;
 
-		if (pTxInfo->SwUseLastRound == 1)
-		{
+		if (pTxInfo->SwUseLastRound == 1) {
 			if (pHTTXContext->CurWritePosition == 8)
 				pTxInfo->USBDMANextVLD = 0;
 			pTxInfo->SwUseLastRound = 0;
@@ -368,68 +397,88 @@
 
 			break;
 		}
-	}while (TRUE);
 
-	// adjust the pTxInfo->USBDMANextVLD value of last pTxInfo.
-	if (pLastTxInfo)
-	{
+	} while (TRUE);
+
+	/* adjust the pTxInfo->USBDMANextVLD value of last pTxInfo. */
+	if (pLastTxInfo) {
 		pLastTxInfo->USBDMANextVLD = 0;
 	}
 
 	/*
-		We need to copy SavedPad when following condition matched!
-			1. Not the last round of the TxQueue and
-			2. any match of following cases:
-				(1). The End Position of this bulk out is reach to the Currenct Write position and
-						the TxInfo and related header already write to the CurWritePosition.
-			   		=>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition)
+	   We need to copy SavedPad when following condition matched!
+	   1. Not the last round of the TxQueue and
+	   2. any match of following cases:
+	   (1). The End Position of this bulk out is reach to the Currenct Write position and
+	   the TxInfo and related header already write to the CurWritePosition.
+	   =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition)
 
-				(2). The EndPosition of the bulk out is not reach to the Current Write Position.
-					=>(ENextBulkOutPosition != CurWritePosition)
-	*/
+	   (2). The EndPosition of the bulk out is not reach to the Current Write Position.
+	   =>(ENextBulkOutPosition != CurWritePosition)
+	 */
 	if ((bTxQLastRound == FALSE) &&
-		 (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) && (pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition)) ||
-		  (pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition))
-		)
-	{
-		NdisMoveMemory(pHTTXContext->SavedPad, &pWirelessPkt[pHTTXContext->ENextBulkOutPosition], 8);
+	    (((pHTTXContext->ENextBulkOutPosition ==
+	       pHTTXContext->CurWritePosition)
+	      && (pHTTXContext->CurWriteRealPos >
+		  pHTTXContext->CurWritePosition))
+	     || (pHTTXContext->ENextBulkOutPosition !=
+		 pHTTXContext->CurWritePosition))
+	    ) {
+		NdisMoveMemory(pHTTXContext->SavedPad,
+			       &pWirelessPkt[pHTTXContext->
+					     ENextBulkOutPosition], 8);
 		pHTTXContext->bCopySavePad = TRUE;
-		if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
-		{
-			PUCHAR	pBuf = &pHTTXContext->SavedPad[0];
-			DBGPRINT_RAW(RT_DEBUG_ERROR,("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n",
-				pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7], pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos,
-				pHTTXContext->bCurWriting, pHTTXContext->NextBulkOutPosition, TmpBulkEndPos, ThisBulkSize));
+		if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero, 4)) {
+			u8 *pBuf = &pHTTXContext->SavedPad[0];
+			DBGPRINT_RAW(RT_DEBUG_ERROR,
+				     ("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n",
+				      pBuf[0], pBuf[1], pBuf[2], pBuf[3],
+				      pBuf[4], pBuf[5], pBuf[6], pBuf[7],
+				      pHTTXContext->CurWritePosition,
+				      pHTTXContext->CurWriteRealPos,
+				      pHTTXContext->bCurWriting,
+				      pHTTXContext->NextBulkOutPosition,
+				      TmpBulkEndPos, ThisBulkSize));
 
 			pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition];
-			DBGPRINT_RAW(RT_DEBUG_ERROR,("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n", pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7]));
+			DBGPRINT_RAW(RT_DEBUG_ERROR,
+				     ("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n",
+				      pBuf[0], pBuf[1], pBuf[2], pBuf[3],
+				      pBuf[4], pBuf[5], pBuf[6], pBuf[7]));
 		}
-		//DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad));
+		/*DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad)); */
 	}
 
 	if (pAd->bForcePrintTX == TRUE)
-		DBGPRINT(RT_DEBUG_TRACE,("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
-	//DBGPRINT(RT_DEBUG_LOUD,("BulkOut-A:Size=%ld, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, bLRound=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, bTxQLastRound));
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n",
+			  ThisBulkSize, pHTTXContext->CurWritePosition,
+			  pHTTXContext->NextBulkOutPosition,
+			  pHTTXContext->ENextBulkOutPosition,
+			  pHTTXContext->bCopySavePad));
+	/*DBGPRINT(RT_DEBUG_LOUD,("BulkOut-A:Size=%ld, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, bLRound=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, bTxQLastRound)); */
 
-		// USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize.
+	/* USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize. */
 	pAppendant = &pWirelessPkt[TmpBulkEndPos];
 	NdisZeroMemory(pAppendant, 8);
+	ThisBulkSize += 4;
+	pHTTXContext->LastOne = TRUE;
+	if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0)
 		ThisBulkSize += 4;
-		pHTTXContext->LastOne = TRUE;
-		if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0)
-			ThisBulkSize += 4;
 	pHTTXContext->BulkOutSize = ThisBulkSize;
 
 	pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1;
 	BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
 
-	// Init Tx context descriptor
-	RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
+	/* Init Tx context descriptor */
+	RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize,
+			  (usb_complete_t) RTUSBBulkOutDataPacketComplete);
 
 	pUrb = pHTTXContext->pUrb;
-	if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
+	if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n",
+			  ret));
 
 		BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
 		pAd->BulkOutPending[BulkOutPipeId] = FALSE;
@@ -446,48 +495,41 @@
 
 }
 
-
-VOID RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
+void RTUSBBulkOutDataPacketComplete(struct urb *pUrb, struct pt_regs * pt_regs)
 {
-	PHT_TX_CONTEXT	pHTTXContext;
-	PRTMP_ADAPTER	pAd;
-	POS_COOKIE 		pObj;
-	UCHAR			BulkOutPipeId;
+	struct rt_ht_tx_context *pHTTXContext;
+	struct rt_rtmp_adapter *pAd;
+	struct os_cookie *pObj;
+	u8 BulkOutPipeId;
 
+	pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
+	pAd = pHTTXContext->pAd;
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
 
-	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
-	pAd 			= pHTTXContext->pAd;
-	pObj 			= (POS_COOKIE) pAd->OS_Cookie;
-
-	// Store BulkOut PipeId
-	BulkOutPipeId	= pHTTXContext->BulkOutPipeId;
+	/* Store BulkOut PipeId */
+	BulkOutPipeId = pHTTXContext->BulkOutPipeId;
 	pAd->BulkOutDataOneSecCount++;
 
-	switch (BulkOutPipeId)
-	{
-		case 0:
-				pObj->ac0_dma_done_task.data = (unsigned long)pUrb;
-				tasklet_hi_schedule(&pObj->ac0_dma_done_task);
-				break;
-		case 1:
-				pObj->ac1_dma_done_task.data = (unsigned long)pUrb;
-				tasklet_hi_schedule(&pObj->ac1_dma_done_task);
-				break;
-		case 2:
-				pObj->ac2_dma_done_task.data = (unsigned long)pUrb;
-				tasklet_hi_schedule(&pObj->ac2_dma_done_task);
-				break;
-		case 3:
-				pObj->ac3_dma_done_task.data = (unsigned long)pUrb;
-				tasklet_hi_schedule(&pObj->ac3_dma_done_task);
-				break;
-		case 4:
-				pObj->hcca_dma_done_task.data = (unsigned long)pUrb;
-				tasklet_hi_schedule(&pObj->hcca_dma_done_task);
-				break;
+	switch (BulkOutPipeId) {
+	case 0:
+		pObj->ac0_dma_done_task.data = (unsigned long)pUrb;
+		tasklet_hi_schedule(&pObj->ac0_dma_done_task);
+		break;
+	case 1:
+		pObj->ac1_dma_done_task.data = (unsigned long)pUrb;
+		tasklet_hi_schedule(&pObj->ac1_dma_done_task);
+		break;
+	case 2:
+		pObj->ac2_dma_done_task.data = (unsigned long)pUrb;
+		tasklet_hi_schedule(&pObj->ac2_dma_done_task);
+		break;
+	case 3:
+		pObj->ac3_dma_done_task.data = (unsigned long)pUrb;
+		tasklet_hi_schedule(&pObj->ac3_dma_done_task);
+		break;
 	}
-}
 
+}
 
 /*
 	========================================================================
@@ -502,17 +544,16 @@
 
 	========================================================================
 */
-VOID	RTUSBBulkOutNullFrame(
-	IN	PRTMP_ADAPTER	pAd)
+void RTUSBBulkOutNullFrame(struct rt_rtmp_adapter *pAd)
 {
-	PTX_CONTEXT		pNullContext = &(pAd->NullContext);
-	PURB			pUrb;
-	int				ret = 0;
-	unsigned long	IrqFlags;
+	struct rt_tx_context *pNullContext = &(pAd->NullContext);
+	PURB pUrb;
+	int ret = 0;
+	unsigned long IrqFlags;
 
 	RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
-	if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
-	{
+	if ((pAd->BulkOutPending[0] == TRUE)
+	    || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) {
 		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
 		return;
 	}
@@ -521,45 +562,45 @@
 	pNullContext->IRPPending = TRUE;
 	RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
 
-	// Increase Total transmit byte counter
-	pAd->RalinkCounters.TransmittedByteCount +=  pNullContext->BulkOutSize;
+	/* Increase Total transmit byte counter */
+	pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize;
 
-
-	// Clear Null frame bulk flag
+	/* Clear Null frame bulk flag */
 	RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
 
-	// Init Tx context descriptor
-	RTUSBInitTxDesc(pAd, pNullContext, 0, (usb_complete_t)RTUSBBulkOutNullFrameComplete);
+	/* Init Tx context descriptor */
+	RTUSBInitTxDesc(pAd, pNullContext, 0,
+			(usb_complete_t) RTUSBBulkOutNullFrameComplete);
 
 	pUrb = pNullContext->pUrb;
-	if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
-	{
+	if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) {
 		RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
 		pAd->BulkOutPending[0] = FALSE;
 		pAd->watchDogTxPendingCnt[0] = 0;
 		pNullContext->IRPPending = FALSE;
 		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
 
-		DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n", ret));
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n",
+			  ret));
 		return;
 	}
 
 }
 
-// NULL frame use BulkOutPipeId = 0
-VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs)
+/* NULL frame use BulkOutPipeId = 0 */
+void RTUSBBulkOutNullFrameComplete(struct urb *pUrb, struct pt_regs * pt_regs)
 {
-	PRTMP_ADAPTER		pAd;
-	PTX_CONTEXT			pNullContext;
-	NTSTATUS			Status;
-	POS_COOKIE			pObj;
+	struct rt_rtmp_adapter *pAd;
+	struct rt_tx_context *pNullContext;
+	int Status;
+	struct os_cookie *pObj;
 
+	pNullContext = (struct rt_tx_context *)pUrb->context;
+	pAd = pNullContext->pAd;
+	Status = pUrb->status;
 
-	pNullContext	= (PTX_CONTEXT)pUrb->context;
-	pAd 			= pNullContext->pAd;
-	Status 			= pUrb->status;
-
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
 	pObj->null_frame_complete_task.data = (unsigned long)pUrb;
 	tasklet_hi_schedule(&pObj->null_frame_complete_task);
 }
@@ -577,34 +618,30 @@
 
 	========================================================================
 */
-VOID	RTUSBBulkOutMLMEPacket(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Index)
+void RTUSBBulkOutMLMEPacket(struct rt_rtmp_adapter *pAd, u8 Index)
 {
-	PTX_CONTEXT		pMLMEContext;
-	PURB			pUrb;
-	int				ret = 0;
-	unsigned long	IrqFlags;
+	struct rt_tx_context *pMLMEContext;
+	PURB pUrb;
+	int ret = 0;
+	unsigned long IrqFlags;
 
-	pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa;
+	pMLMEContext =
+	    (struct rt_tx_context *)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa;
 	pUrb = pMLMEContext->pUrb;
 
 	if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) ||
-		(pMLMEContext->InUse == FALSE) ||
-		(pMLMEContext->bWaitingBulkOut == FALSE))
-	{
+	    (pMLMEContext->InUse == FALSE) ||
+	    (pMLMEContext->bWaitingBulkOut == FALSE)) {
 
-
-		// Clear MLME bulk flag
+		/* Clear MLME bulk flag */
 		RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
 
 		return;
 	}
 
-
 	RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
-	if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
-	{
+	if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE)
+	    || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) {
 		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
 		return;
 	}
@@ -615,23 +652,25 @@
 	pMLMEContext->bWaitingBulkOut = FALSE;
 	RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
 
-	// Increase Total transmit byte counter
-	pAd->RalinkCounters.TransmittedByteCount +=  pMLMEContext->BulkOutSize;
+	/* Increase Total transmit byte counter */
+	pAd->RalinkCounters.TransmittedByteCount += pMLMEContext->BulkOutSize;
 
-	// Clear MLME bulk flag
+	/* Clear MLME bulk flag */
 	RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
 
-	// Init Tx context descriptor
-	RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutMLMEPacketComplete);
+	/* Init Tx context descriptor */
+	RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX,
+			(usb_complete_t) RTUSBBulkOutMLMEPacketComplete);
 
-	//For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping.
-	pUrb->transfer_dma	= 0;
+	/*For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping. */
+	pUrb->transfer_dma = 0;
 	pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP);
 
 	pUrb = pMLMEContext->pUrb;
-	if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n", ret));
+	if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n",
+			  ret));
 		RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
 		pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
 		pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0;
@@ -641,32 +680,29 @@
 
 		return;
 	}
-
-	//DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n"));
-//	printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
+	/*DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n")); */
+/*      printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx); */
 }
 
-
-VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
+void RTUSBBulkOutMLMEPacketComplete(struct urb *pUrb, struct pt_regs * pt_regs)
 {
-	PTX_CONTEXT			pMLMEContext;
-	PRTMP_ADAPTER		pAd;
-	NTSTATUS			Status;
-	POS_COOKIE 			pObj;
-	int					index;
+	struct rt_tx_context *pMLMEContext;
+	struct rt_rtmp_adapter *pAd;
+	int Status;
+	struct os_cookie *pObj;
+	int index;
 
-	//DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n"));
-	pMLMEContext	= (PTX_CONTEXT)pUrb->context;
-	pAd 			= pMLMEContext->pAd;
-	pObj 			= (POS_COOKIE)pAd->OS_Cookie;
-	Status			= pUrb->status;
-	index 			= pMLMEContext->SelfIdx;
+	/*DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n")); */
+	pMLMEContext = (struct rt_tx_context *)pUrb->context;
+	pAd = pMLMEContext->pAd;
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
+	Status = pUrb->status;
+	index = pMLMEContext->SelfIdx;
 
 	pObj->mgmt_dma_done_task.data = (unsigned long)pUrb;
 	tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
 }
 
-
 /*
 	========================================================================
 
@@ -680,17 +716,16 @@
 
 	========================================================================
 */
-VOID	RTUSBBulkOutPsPoll(
-	IN	PRTMP_ADAPTER	pAd)
+void RTUSBBulkOutPsPoll(struct rt_rtmp_adapter *pAd)
 {
-	PTX_CONTEXT		pPsPollContext = &(pAd->PsPollContext);
-	PURB			pUrb;
-	int				ret = 0;
-	unsigned long	IrqFlags;
+	struct rt_tx_context *pPsPollContext = &(pAd->PsPollContext);
+	PURB pUrb;
+	int ret = 0;
+	unsigned long IrqFlags;
 
 	RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
-	if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
-	{
+	if ((pAd->BulkOutPending[0] == TRUE)
+	    || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) {
 		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
 		return;
 	}
@@ -699,57 +734,57 @@
 	pPsPollContext->IRPPending = TRUE;
 	RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
 
-
-	// Clear PS-Poll bulk flag
+	/* Clear PS-Poll bulk flag */
 	RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);
 
-	// Init Tx context descriptor
-	RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutPsPollComplete);
+	/* Init Tx context descriptor */
+	RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX,
+			(usb_complete_t) RTUSBBulkOutPsPollComplete);
 
 	pUrb = pPsPollContext->pUrb;
-	if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
-	{
+	if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) {
 		RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
 		pAd->BulkOutPending[0] = FALSE;
 		pAd->watchDogTxPendingCnt[0] = 0;
 		pPsPollContext->IRPPending = FALSE;
 		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
 
-		DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n", ret));
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n",
+			  ret));
 		return;
 	}
 
 }
 
-// PS-Poll frame use BulkOutPipeId = 0
-VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb,struct pt_regs *pt_regs)
+/* PS-Poll frame use BulkOutPipeId = 0 */
+void RTUSBBulkOutPsPollComplete(struct urb *pUrb, struct pt_regs * pt_regs)
 {
-	PRTMP_ADAPTER		pAd;
-	PTX_CONTEXT			pPsPollContext;
-	NTSTATUS			Status;
-	POS_COOKIE			pObj;
+	struct rt_rtmp_adapter *pAd;
+	struct rt_tx_context *pPsPollContext;
+	int Status;
+	struct os_cookie *pObj;
 
-
-	pPsPollContext= (PTX_CONTEXT)pUrb->context;
+	pPsPollContext = (struct rt_tx_context *)pUrb->context;
 	pAd = pPsPollContext->pAd;
 	Status = pUrb->status;
 
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
 	pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb;
 	tasklet_hi_schedule(&pObj->pspoll_frame_complete_task);
 }
 
-VOID DoBulkIn(IN RTMP_ADAPTER *pAd)
+void DoBulkIn(struct rt_rtmp_adapter *pAd)
 {
-	PRX_CONTEXT		pRxContext;
-	PURB			pUrb;
-	int				ret = 0;
-	unsigned long	IrqFlags;
+	struct rt_rx_context *pRxContext;
+	PURB pUrb;
+	int ret = 0;
+	unsigned long IrqFlags;
 
 	RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
 	pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
-	if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
-	{
+	if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE)
+	    || (pRxContext->InUse == TRUE)) {
 		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
 		return;
 	}
@@ -759,13 +794,12 @@
 	pAd->BulkInReq++;
 	RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
 
-	// Init Rx context descriptor
+	/* Init Rx context descriptor */
 	NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset);
 	RTUSBInitRxDesc(pAd, pRxContext);
 
 	pUrb = pRxContext->pUrb;
-	if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
-	{	// fail
+	if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) {	/* fail */
 
 		RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
 		pRxContext->InUse = FALSE;
@@ -773,16 +807,14 @@
 		pAd->PendingRx--;
 		pAd->BulkInReq--;
 		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
-		DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
-	}
-	else
-	{	// success
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
+	} else {		/* success */
 		ASSERT((pRxContext->InUse == pRxContext->IRPPending));
-		//printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex);
+		/*printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex); */
 	}
 }
 
-
 /*
 	========================================================================
 
@@ -813,44 +845,40 @@
 		 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
 		 fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
 
-VOID	RTUSBBulkReceive(
-	IN	PRTMP_ADAPTER	pAd)
+void RTUSBBulkReceive(struct rt_rtmp_adapter *pAd)
 {
-	PRX_CONTEXT		pRxContext;
-	unsigned long	IrqFlags;
-
+	struct rt_rx_context *pRxContext;
+	unsigned long IrqFlags;
 
 	/* sanity check */
 	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX))
 		return;
 
-	while(1)
-	{
+	while (1) {
 
 		RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
 		pRxContext = &(pAd->RxContext[pAd->NextRxBulkInReadIndex]);
-		if (((pRxContext->InUse == FALSE) && (pRxContext->Readable == TRUE)) &&
-			(pRxContext->bRxHandling == FALSE))
-		{
+		if (((pRxContext->InUse == FALSE)
+		     && (pRxContext->Readable == TRUE))
+		    && (pRxContext->bRxHandling == FALSE)) {
 			pRxContext->bRxHandling = TRUE;
 			RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
 
-			// read RxContext, Since not
+			/* read RxContext, Since not */
 			STARxDoneInterruptHandle(pAd, TRUE);
 
-			// Finish to handle this bulkIn buffer.
+			/* Finish to handle this bulkIn buffer. */
 			RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
 			pRxContext->BulkInOffset = 0;
 			pRxContext->Readable = FALSE;
 			pRxContext->bRxHandling = FALSE;
 			pAd->ReadPosition = 0;
 			pAd->TransferBufferLength = 0;
-			INC_RING_INDEX(pAd->NextRxBulkInReadIndex, RX_RING_SIZE);
+			INC_RING_INDEX(pAd->NextRxBulkInReadIndex,
+				       RX_RING_SIZE);
 			RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
 
-		}
-		else
-		{
+		} else {
 			RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
 			break;
 		}
@@ -861,7 +889,6 @@
 
 }
 
-
 /*
 	========================================================================
 
@@ -885,27 +912,24 @@
 		Always returns STATUS_MORE_PROCESSING_REQUIRED
 	========================================================================
 */
-VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs)
+void RTUSBBulkRxComplete(struct urb *pUrb, struct pt_regs *pt_regs)
 {
-	// use a receive tasklet to handle received packets;
-	// or sometimes hardware IRQ will be disabled here, so we can not
-	// use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :<
-	PRX_CONTEXT		pRxContext;
-	PRTMP_ADAPTER	pAd;
-	POS_COOKIE 		pObj;
+	/* use a receive tasklet to handle received packets; */
+	/* or sometimes hardware IRQ will be disabled here, so we can not */
+	/* use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :< */
+	struct rt_rx_context *pRxContext;
+	struct rt_rtmp_adapter *pAd;
+	struct os_cookie *pObj;
 
-
-	pRxContext	= (PRX_CONTEXT)pUrb->context;
-	pAd 		= pRxContext->pAd;
-	pObj 		= (POS_COOKIE) pAd->OS_Cookie;
+	pRxContext = (struct rt_rx_context *)pUrb->context;
+	pAd = pRxContext->pAd;
+	pObj = (struct os_cookie *)pAd->OS_Cookie;
 
 	pObj->rx_done_task.data = (unsigned long)pUrb;
 	tasklet_hi_schedule(&pObj->rx_done_task);
 
 }
 
-
-
 /*
 	========================================================================
 
@@ -919,86 +943,78 @@
 
 	========================================================================
 */
-VOID	RTUSBKickBulkOut(
-	IN	PRTMP_ADAPTER pAd)
+void RTUSBKickBulkOut(struct rt_rtmp_adapter *pAd)
 {
-	// BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged.
-	if (!RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX)
-		)
-	{
-		// 2. PS-Poll frame is next
-		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL))
-		{
+	/* BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged. */
+	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)
+	    ) {
+		/* 2. PS-Poll frame is next */
+		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL)) {
 			RTUSBBulkOutPsPoll(pAd);
 		}
-
-		// 5. Mlme frame is next
-		else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) &&
-				 (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE))
-		{
+		/* 5. Mlme frame is next */
+		else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) ||
+			 (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE)) {
 			RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx);
 		}
-
-		// 6. Data frame normal is next
-		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL))
-		{
-			if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
-				(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-				))
-			{
-				RTUSBBulkOutDataPacket(pAd, 0, pAd->NextBulkOutIndex[0]);
+		/* 6. Data frame normal is next */
+		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL)) {
+			if (((!RTMP_TEST_FLAG
+			      (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+			     ||
+			     (!OPSTATUS_TEST_FLAG
+			      (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+			    )) {
+				RTUSBBulkOutDataPacket(pAd, 0,
+						       pAd->
+						       NextBulkOutIndex[0]);
 			}
 		}
-		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2))
-		{
-			if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
-				(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-				))
-			{
-				RTUSBBulkOutDataPacket(pAd, 1, pAd->NextBulkOutIndex[1]);
+		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2)) {
+			if (((!RTMP_TEST_FLAG
+			      (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+			     ||
+			     (!OPSTATUS_TEST_FLAG
+			      (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+			    )) {
+				RTUSBBulkOutDataPacket(pAd, 1,
+						       pAd->
+						       NextBulkOutIndex[1]);
 			}
 		}
-		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3))
-		{
-			if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
-				(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-				))
-			{
-				RTUSBBulkOutDataPacket(pAd, 2, pAd->NextBulkOutIndex[2]);
+		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3)) {
+			if (((!RTMP_TEST_FLAG
+			      (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+			     ||
+			     (!OPSTATUS_TEST_FLAG
+			      (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+			    )) {
+				RTUSBBulkOutDataPacket(pAd, 2,
+						       pAd->
+						       NextBulkOutIndex[2]);
 			}
 		}
-		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4))
-		{
-			if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
-				(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-				))
-			{
-				RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]);
+		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4)) {
+			if (((!RTMP_TEST_FLAG
+			      (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+			     ||
+			     (!OPSTATUS_TEST_FLAG
+			      (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+			    )) {
+				RTUSBBulkOutDataPacket(pAd, 3,
+						       pAd->
+						       NextBulkOutIndex[3]);
 			}
 		}
-
-		//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
-		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_5))
-		{
-			if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
-				(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-				))
-			{
-			}
-		}
-
-		// 7. Null frame is the last
-		else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL))
-		{
-			if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-			{
+		/* 7. Null frame is the last */
+		else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL)) {
+			if (!RTMP_TEST_FLAG
+			    (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) {
 				RTUSBBulkOutNullFrame(pAd);
 			}
 		}
-
-		// 8. No data avaliable
-		else
-		{
+		/* 8. No data avaliable */
+		else {
 
 		}
 	}
@@ -1017,16 +1033,14 @@
 
 	========================================================================
 */
-VOID	RTUSBCleanUpDataBulkOutQueue(
-	IN	PRTMP_ADAPTER	pAd)
+void RTUSBCleanUpDataBulkOutQueue(struct rt_rtmp_adapter *pAd)
 {
-	UCHAR			Idx;
-	PHT_TX_CONTEXT	pTxContext;
+	u8 Idx;
+	struct rt_ht_tx_context *pTxContext;
 
 	DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpDataBulkOutQueue\n"));
 
-	for (Idx = 0; Idx < 4; Idx++)
-	{
+	for (Idx = 0; Idx < 4; Idx++) {
 		pTxContext = &pAd->TxContext[Idx];
 
 		pTxContext->CurWritePosition = pTxContext->NextBulkOutPosition;
@@ -1052,14 +1066,12 @@
 
 	========================================================================
 */
-VOID	RTUSBCleanUpMLMEBulkOutQueue(
-	IN	PRTMP_ADAPTER	pAd)
+void RTUSBCleanUpMLMEBulkOutQueue(struct rt_rtmp_adapter *pAd)
 {
 	DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpMLMEBulkOutQueue\n"));
 	DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpMLMEBulkOutQueue\n"));
 }
 
-
 /*
 	========================================================================
 
@@ -1069,13 +1081,11 @@
 
 	Return Value:
 
-
 	Note:
 
 	========================================================================
 */
-VOID	RTUSBCancelPendingIRPs(
-	IN	PRTMP_ADAPTER	pAd)
+void RTUSBCancelPendingIRPs(struct rt_rtmp_adapter *pAd)
 {
 	RTUSBCancelPendingBulkInIRP(pAd);
 	RTUSBCancelPendingBulkOutIRP(pAd);
@@ -1094,29 +1104,25 @@
 
 	========================================================================
 */
-VOID	RTUSBCancelPendingBulkInIRP(
-	IN	PRTMP_ADAPTER	pAd)
+void RTUSBCancelPendingBulkInIRP(struct rt_rtmp_adapter *pAd)
 {
-	PRX_CONTEXT		pRxContext;
-	UINT			i;
+	struct rt_rx_context *pRxContext;
+	u32 i;
 
 	DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n"));
-	for ( i = 0; i < (RX_RING_SIZE); i++)
-	{
+	for (i = 0; i < (RX_RING_SIZE); i++) {
 		pRxContext = &(pAd->RxContext[i]);
-		if(pRxContext->IRPPending == TRUE)
-		{
+		if (pRxContext->IRPPending == TRUE) {
 			RTUSB_UNLINK_URB(pRxContext->pUrb);
 			pRxContext->IRPPending = FALSE;
 			pRxContext->InUse = FALSE;
-			//NdisInterlockedDecrement(&pAd->PendingRx);
-			//pAd->PendingRx--;
+			/*NdisInterlockedDecrement(&pAd->PendingRx); */
+			/*pAd->PendingRx--; */
 		}
 	}
 	DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n"));
 }
 
-
 /*
 	========================================================================
 
@@ -1130,83 +1136,74 @@
 
 	========================================================================
 */
-VOID	RTUSBCancelPendingBulkOutIRP(
-	IN	PRTMP_ADAPTER	pAd)
+void RTUSBCancelPendingBulkOutIRP(struct rt_rtmp_adapter *pAd)
 {
-	PHT_TX_CONTEXT		pHTTXContext;
-	PTX_CONTEXT			pMLMEContext;
-	PTX_CONTEXT			pBeaconContext;
-	PTX_CONTEXT			pNullContext;
-	PTX_CONTEXT			pPsPollContext;
-	PTX_CONTEXT			pRTSContext;
-	UINT				i, Idx;
-//	unsigned int 		IrqFlags;
-//	NDIS_SPIN_LOCK		*pLock;
-//	BOOLEAN				*pPending;
+	struct rt_ht_tx_context *pHTTXContext;
+	struct rt_tx_context *pMLMEContext;
+	struct rt_tx_context *pBeaconContext;
+	struct rt_tx_context *pNullContext;
+	struct rt_tx_context *pPsPollContext;
+	struct rt_tx_context *pRTSContext;
+	u32 i, Idx;
+/*      unsigned int            IrqFlags; */
+/*      spinlock_t          *pLock; */
+/*      BOOLEAN                         *pPending; */
 
+/*      pLock = &pAd->BulkOutLock[MGMTPIPEIDX]; */
+/*      pPending = &pAd->BulkOutPending[MGMTPIPEIDX]; */
 
-//	pLock = &pAd->BulkOutLock[MGMTPIPEIDX];
-//	pPending = &pAd->BulkOutPending[MGMTPIPEIDX];
-
-	for (Idx = 0; Idx < 4; Idx++)
-	{
+	for (Idx = 0; Idx < 4; Idx++) {
 		pHTTXContext = &(pAd->TxContext[Idx]);
 
-		if (pHTTXContext->IRPPending == TRUE)
-		{
+		if (pHTTXContext->IRPPending == TRUE) {
 
-			// Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
-			// remove it from the HeadPendingSendList and NULL out HeadPendingSendList
-			//	when the last IRP on the list has been	cancelled; that's how we exit this loop
-			//
+			/* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */
+			/* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */
+			/*      when the last IRP on the list has been  cancelled; that's how we exit this loop */
+			/* */
 
 			RTUSB_UNLINK_URB(pHTTXContext->pUrb);
 
-			// Sleep 200 microseconds to give cancellation time to work
+			/* Sleep 200 microseconds to give cancellation time to work */
 			RTMPusecDelay(200);
 		}
 
 		pAd->BulkOutPending[Idx] = FALSE;
 	}
 
-	//RTMP_IRQ_LOCK(pLock, IrqFlags);
-	for (i = 0; i < MGMT_RING_SIZE; i++)
-	{
-		pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
-		if(pMLMEContext && (pMLMEContext->IRPPending == TRUE))
-		{
+	/*RTMP_IRQ_LOCK(pLock, IrqFlags); */
+	for (i = 0; i < MGMT_RING_SIZE; i++) {
+		pMLMEContext = (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa;
+		if (pMLMEContext && (pMLMEContext->IRPPending == TRUE)) {
 
-			// Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
-			// remove it from the HeadPendingSendList and NULL out HeadPendingSendList
-			//	when the last IRP on the list has been	cancelled; that's how we exit this loop
-			//
+			/* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */
+			/* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */
+			/*      when the last IRP on the list has been  cancelled; that's how we exit this loop */
+			/* */
 
 			RTUSB_UNLINK_URB(pMLMEContext->pUrb);
 			pMLMEContext->IRPPending = FALSE;
 
-			// Sleep 200 microsecs to give cancellation time to work
+			/* Sleep 200 microsecs to give cancellation time to work */
 			RTMPusecDelay(200);
 		}
 	}
 	pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
-	//RTMP_IRQ_UNLOCK(pLock, IrqFlags);
+	/*RTMP_IRQ_UNLOCK(pLock, IrqFlags); */
 
-
-	for (i = 0; i < BEACON_RING_SIZE; i++)
-	{
+	for (i = 0; i < BEACON_RING_SIZE; i++) {
 		pBeaconContext = &(pAd->BeaconContext[i]);
 
-		if(pBeaconContext->IRPPending == TRUE)
-		{
+		if (pBeaconContext->IRPPending == TRUE) {
 
-			// Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
-			// remove it from the HeadPendingSendList and NULL out HeadPendingSendList
-			//	when the last IRP on the list has been	cancelled; that's how we exit this loop
-			//
+			/* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */
+			/* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */
+			/*      when the last IRP on the list has been  cancelled; that's how we exit this loop */
+			/* */
 
 			RTUSB_UNLINK_URB(pBeaconContext->pUrb);
 
-			// Sleep 200 microsecs to give cancellation time to work
+			/* Sleep 200 microsecs to give cancellation time to work */
 			RTMPusecDelay(200);
 		}
 	}
@@ -1223,11 +1220,11 @@
 	if (pPsPollContext->IRPPending == TRUE)
 		RTUSB_UNLINK_URB(pPsPollContext->pUrb);
 
-	for (Idx = 0; Idx < 4; Idx++)
-	{
+	for (Idx = 0; Idx < 4; Idx++) {
 		NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
 		pAd->BulkOutPending[Idx] = FALSE;
 		NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
 	}
 }
 
+#endif /* RTMP_MAC_USB // */
diff --git a/drivers/staging/rt2870/common/rtusb_data.c b/drivers/staging/rt2870/common/rtusb_data.c
index 6b003f6..4583764 100644
--- a/drivers/staging/rt2870/common/rtusb_data.c
+++ b/drivers/staging/rt2870/common/rtusb_data.c
@@ -36,82 +36,102 @@
 	Jan            03-25-2006    created
 
 */
+
+#ifdef RTMP_MAC_USB
+
 #include "../rt_config.h"
 
-extern  UCHAR Phy11BGNextRateUpward[]; // defined in mlme.c
-extern UCHAR	EpToQueue[];
+extern u8 Phy11BGNextRateUpward[];	/* defined in mlme.c */
+extern u8 EpToQueue[];
 
-VOID REPORT_AMSDU_FRAMES_TO_LLC(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pData,
-	IN	ULONG			DataSize)
+void REPORT_AMSDU_FRAMES_TO_LLC(struct rt_rtmp_adapter *pAd,
+				u8 *pData, unsigned long DataSize)
 {
-	PNDIS_PACKET	pPacket;
-	UINT			nMSDU;
-	struct			sk_buff *pSkb;
+	void *pPacket;
+	u32 nMSDU;
+	struct sk_buff *pSkb;
 
 	nMSDU = 0;
 	/* allocate a rx packet */
 	pSkb = dev_alloc_skb(RX_BUFFER_AGGRESIZE);
-	pPacket = (PNDIS_PACKET)OSPKT_TO_RTPKT(pSkb);
-	if (pSkb)
-	{
+	pPacket = (void *)OSPKT_TO_RTPKT(pSkb);
+	if (pSkb) {
 
 		/* convert 802.11 to 802.3 packet */
 		pSkb->dev = get_netdev_from_bssid(pAd, BSS0);
 		RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
 		deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("Can't allocate skb\n"));
+	} else {
+		DBGPRINT(RT_DEBUG_ERROR, ("Can't allocate skb\n"));
 	}
 }
 
-NDIS_STATUS	RTUSBFreeDescriptorRequest(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			BulkOutPipeId,
-	IN	UINT32			NumberRequired)
-{
-//	UCHAR			FreeNumber = 0;
-//	UINT			Index;
-	NDIS_STATUS		Status = NDIS_STATUS_FAILURE;
-	unsigned long   IrqFlags;
-	HT_TX_CONTEXT	*pHTTXContext;
+/*
+	========================================================================
 
+	Routine	Description:
+		This subroutine will scan through releative ring descriptor to find
+		out avaliable free ring descriptor and compare with request size.
+
+	Arguments:
+		pAd	Pointer	to our adapter
+		RingType	Selected Ring
+
+	Return Value:
+		NDIS_STATUS_FAILURE		Not enough free descriptor
+		NDIS_STATUS_SUCCESS		Enough free descriptor
+
+	Note:
+
+	========================================================================
+*/
+int RTUSBFreeDescriptorRequest(struct rt_rtmp_adapter *pAd,
+				       u8 BulkOutPipeId,
+				       u32 NumberRequired)
+{
+/*      u8                   FreeNumber = 0; */
+/*      u32                    Index; */
+	int Status = NDIS_STATUS_FAILURE;
+	unsigned long IrqFlags;
+	struct rt_ht_tx_context *pHTTXContext;
 
 	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
 	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
-	if ((pHTTXContext->CurWritePosition < pHTTXContext->NextBulkOutPosition) && ((pHTTXContext->CurWritePosition + NumberRequired + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition))
-	{
+	if ((pHTTXContext->CurWritePosition < pHTTXContext->NextBulkOutPosition)
+	    &&
+	    ((pHTTXContext->CurWritePosition + NumberRequired +
+	      LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition)) {
 
-		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
-	}
-	else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < (NumberRequired + LOCAL_TXBUF_SIZE)))
-	{
-		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
-	}
-	else if (pHTTXContext->bCurWriting == TRUE)
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("RTUSBFreeD c3 --> QueIdx=%d, CWPos=%ld, NBOutPos=%ld!\n", BulkOutPipeId, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition));
-		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
-	}
-	else
-	{
+		RTUSB_SET_BULK_FLAG(pAd,
+				    (fRTUSB_BULK_OUT_DATA_NORMAL <<
+				     BulkOutPipeId));
+	} else if ((pHTTXContext->CurWritePosition == 8)
+		   && (pHTTXContext->NextBulkOutPosition <
+		       (NumberRequired + LOCAL_TXBUF_SIZE))) {
+		RTUSB_SET_BULK_FLAG(pAd,
+				    (fRTUSB_BULK_OUT_DATA_NORMAL <<
+				     BulkOutPipeId));
+	} else if (pHTTXContext->bCurWriting == TRUE) {
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("RTUSBFreeD c3 --> QueIdx=%d, CWPos=%ld, NBOutPos=%ld!\n",
+			  BulkOutPipeId, pHTTXContext->CurWritePosition,
+			  pHTTXContext->NextBulkOutPosition));
+		RTUSB_SET_BULK_FLAG(pAd,
+				    (fRTUSB_BULK_OUT_DATA_NORMAL <<
+				     BulkOutPipeId));
+	} else {
 		Status = NDIS_STATUS_SUCCESS;
 	}
 	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
 
-
 	return (Status);
 }
 
-NDIS_STATUS RTUSBFreeDescriptorRelease(
-	IN RTMP_ADAPTER *pAd,
-	IN UCHAR		BulkOutPipeId)
+int RTUSBFreeDescriptorRelease(struct rt_rtmp_adapter *pAd,
+				       u8 BulkOutPipeId)
 {
-	unsigned long   IrqFlags;
-	HT_TX_CONTEXT	*pHTTXContext;
+	unsigned long IrqFlags;
+	struct rt_ht_tx_context *pHTTXContext;
 
 	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
 	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
@@ -121,28 +141,32 @@
 	return (NDIS_STATUS_SUCCESS);
 }
 
-
-BOOLEAN	RTUSBNeedQueueBackForAgg(
-	IN RTMP_ADAPTER *pAd,
-	IN UCHAR		BulkOutPipeId)
+BOOLEAN RTUSBNeedQueueBackForAgg(struct rt_rtmp_adapter *pAd, u8 BulkOutPipeId)
 {
-	unsigned long   IrqFlags;
-	HT_TX_CONTEXT	*pHTTXContext;
-	BOOLEAN			needQueBack = FALSE;
+	unsigned long IrqFlags;
+	struct rt_ht_tx_context *pHTTXContext;
+	BOOLEAN needQueBack = FALSE;
 
 	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
 
 	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
-	if ((pHTTXContext->IRPPending == TRUE)  /*&& (pAd->TxSwQueue[BulkOutPipeId].Number == 0) */)
-	{
-		if ((pHTTXContext->CurWritePosition < pHTTXContext->ENextBulkOutPosition) &&
-			(((pHTTXContext->ENextBulkOutPosition+MAX_AGGREGATION_SIZE) < MAX_TXBULK_LIMIT) || (pHTTXContext->CurWritePosition > MAX_AGGREGATION_SIZE)))
-		{
+	if ((pHTTXContext->IRPPending ==
+	     TRUE) /*&& (pAd->TxSwQueue[BulkOutPipeId].Number == 0) */ ) {
+		if ((pHTTXContext->CurWritePosition <
+		     pHTTXContext->ENextBulkOutPosition)
+		    &&
+		    (((pHTTXContext->ENextBulkOutPosition +
+		       MAX_AGGREGATION_SIZE) < MAX_TXBULK_LIMIT)
+		     || (pHTTXContext->CurWritePosition >
+			 MAX_AGGREGATION_SIZE))) {
 			needQueBack = TRUE;
-		}
-		else if ((pHTTXContext->CurWritePosition > pHTTXContext->ENextBulkOutPosition) &&
-				 ((pHTTXContext->ENextBulkOutPosition + MAX_AGGREGATION_SIZE) < pHTTXContext->CurWritePosition))
-		{
+		} else
+		    if ((pHTTXContext->CurWritePosition >
+			 pHTTXContext->ENextBulkOutPosition)
+			&&
+			((pHTTXContext->ENextBulkOutPosition +
+			  MAX_AGGREGATION_SIZE) <
+			 pHTTXContext->CurWritePosition)) {
 			needQueBack = TRUE;
 		}
 	}
@@ -152,7 +176,6 @@
 
 }
 
-
 /*
 	========================================================================
 
@@ -168,21 +191,17 @@
 
 	========================================================================
 */
-VOID	RTUSBRejectPendingPackets(
-	IN	PRTMP_ADAPTER	pAd)
+void RTUSBRejectPendingPackets(struct rt_rtmp_adapter *pAd)
 {
-	UCHAR			Index;
-	PQUEUE_ENTRY	pEntry;
-	PNDIS_PACKET	pPacket;
-	PQUEUE_HEADER	pQueue;
+	u8 Index;
+	struct rt_queue_entry *pEntry;
+	void *pPacket;
+	struct rt_queue_header *pQueue;
 
-
-	for (Index = 0; Index < 4; Index++)
-	{
+	for (Index = 0; Index < 4; Index++) {
 		NdisAcquireSpinLock(&pAd->TxSwQueueLock[Index]);
-		while (pAd->TxSwQueue[Index].Head != NULL)
-		{
-			pQueue = (PQUEUE_HEADER) &(pAd->TxSwQueue[Index]);
+		while (pAd->TxSwQueue[Index].Head != NULL) {
+			pQueue = (struct rt_queue_header *)& (pAd->TxSwQueue[Index]);
 			pEntry = RemoveHeadQueue(pQueue);
 			pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
 			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
@@ -193,20 +212,46 @@
 
 }
 
-VOID RTMPWriteTxInfo(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PTXINFO_STRUC 	pTxInfo,
-	IN	  USHORT		USBDMApktLen,
-	IN	  BOOLEAN		bWiv,
-	IN	  UCHAR			QueueSel,
-	IN	  UCHAR			NextValid,
-	IN	  UCHAR			TxBurst)
+/*
+	========================================================================
+
+	Routine	Description:
+		Calculates the duration which is required to transmit out frames
+	with given size and specified rate.
+
+	Arguments:
+		pTxD		Pointer to transmit descriptor
+		Ack			Setting for Ack requirement bit
+		Fragment	Setting for Fragment bit
+		RetryMode	Setting for retry mode
+		Ifs			Setting for IFS gap
+		Rate		Setting for transmit rate
+		Service		Setting for service
+		Length		Frame length
+		TxPreamble  Short or Long preamble when using CCK rates
+		QueIdx - 0-3, according to 802.11e/d4.4 June/2003
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	========================================================================
+*/
+
+void RTMPWriteTxInfo(struct rt_rtmp_adapter *pAd,
+		     struct rt_txinfo *pTxInfo,
+		     u16 USBDMApktLen,
+		     IN BOOLEAN bWiv,
+		     u8 QueueSel, u8 NextValid, u8 TxBurst)
 {
 	pTxInfo->USBDMATxPktLen = USBDMApktLen;
 	pTxInfo->QSEL = QueueSel;
 	if (QueueSel != FIFO_EDCA)
-		DBGPRINT(RT_DEBUG_TRACE, ("====> QueueSel != FIFO_EDCA<============\n"));
-	pTxInfo->USBDMANextVLD = FALSE; //NextValid;  // Need to check with Jan about this.
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("====> QueueSel != FIFO_EDCA<============\n"));
+	pTxInfo->USBDMANextVLD = FALSE;	/*NextValid;  // Need to check with Jan about this. */
 	pTxInfo->USBDMATxburst = TxBurst;
 	pTxInfo->WIV = bWiv;
 	pTxInfo->SwUseLastRound = 0;
@@ -214,3 +259,4 @@
 	pTxInfo->rsv2 = 0;
 }
 
+#endif /* RTMP_MAC_USB // */
diff --git a/drivers/staging/rt2870/common/rtusb_io.c b/drivers/staging/rt2870/common/rtusb_io.c
index 1d69590..34443f2 100644
--- a/drivers/staging/rt2870/common/rtusb_io.c
+++ b/drivers/staging/rt2870/common/rtusb_io.c
@@ -36,8 +36,9 @@
 	Paul Lin    06-25-2004  created
 */
 
-#include "../rt_config.h"
+#ifdef RTMP_MAC_USB
 
+#include "../rt_config.h"
 
 /*
 	========================================================================
@@ -55,26 +56,18 @@
 	========================================================================
 */
 
-NTSTATUS	RTUSBFirmwareRun(
-	IN	PRTMP_ADAPTER	pAd)
+static int RTUSBFirmwareRun(struct rt_rtmp_adapter *pAd)
 {
-	NTSTATUS	Status;
+	int Status;
 
-	Status = RTUSB_VendorRequest(
-		pAd,
-		USBD_TRANSFER_DIRECTION_OUT,
-		DEVICE_VENDOR_REQUEST_OUT,
-		0x01,
-		0x8,
-		0,
-		NULL,
-		0);
+	Status = RTUSB_VendorRequest(pAd,
+				     USBD_TRANSFER_DIRECTION_OUT,
+				     DEVICE_VENDOR_REQUEST_OUT,
+				     0x01, 0x8, 0, NULL, 0);
 
 	return Status;
 }
 
-
-
 /*
 	========================================================================
 
@@ -90,19 +83,16 @@
 
 	========================================================================
 */
-NTSTATUS RTUSBFirmwareWrite(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR		pFwImage,
-	IN ULONG		FwLen)
+int RTUSBFirmwareWrite(struct rt_rtmp_adapter *pAd,
+			    u8 *pFwImage, unsigned long FwLen)
 {
-	UINT32		MacReg;
-	NTSTATUS 	Status;
-//	ULONG 		i;
-	USHORT		writeLen;
+	u32 MacReg;
+	int Status;
+/*      unsigned long           i; */
+	u16 writeLen;
 
 	Status = RTUSBReadMACRegister(pAd, MAC_CSR0, &MacReg);
 
-
 	writeLen = FwLen;
 	RTUSBMultiWrite(pAd, FIRMWARE_IMAGE_BASE, pFwImage, writeLen);
 
@@ -110,66 +100,28 @@
 	Status = RTUSBWriteMACRegister(pAd, 0x701c, 0xffffffff);
 	Status = RTUSBFirmwareRun(pAd);
 
+	/*2008/11/28:KH add to fix the dead rf frequency offset bug<-- */
 	RTMPusecDelay(10000);
-	RTUSBWriteMACRegister(pAd,H2M_MAILBOX_CSR,0);
-	AsicSendCommandToMcu(pAd, 0x72, 0x00, 0x00, 0x00);//reset rf by MCU supported by new firmware
+	RTUSBWriteMACRegister(pAd, H2M_MAILBOX_CSR, 0);
+	AsicSendCommandToMcu(pAd, 0x72, 0x00, 0x00, 0x00);	/*reset rf by MCU supported by new firmware */
+	/*2008/11/28:KH add to fix the dead rf frequency offset bug--> */
 
 	return Status;
 }
 
-
-/*
-	========================================================================
-
-	Routine Description: Get current firmware operation mode (Return Value)
-
-	Arguments:
-
-	Return Value:
-		0 or 1 = Downloaded by host driver
-		others = Driver doesn't download firmware
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-NTSTATUS	RTUSBFirmwareOpmode(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUINT32			pValue)
+int RTUSBVenderReset(struct rt_rtmp_adapter *pAd)
 {
-	NTSTATUS	Status;
-
-	Status = RTUSB_VendorRequest(
-		pAd,
-		(USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
-		DEVICE_VENDOR_REQUEST_IN,
-		0x1,
-		0x11,
-		0,
-		pValue,
-		4);
-	return Status;
-}
-NTSTATUS	RTUSBVenderReset(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	NTSTATUS	Status;
+	int Status;
 	DBGPRINT_RAW(RT_DEBUG_ERROR, ("-->RTUSBVenderReset\n"));
-	Status = RTUSB_VendorRequest(
-		pAd,
-		USBD_TRANSFER_DIRECTION_OUT,
-		DEVICE_VENDOR_REQUEST_OUT,
-		0x01,
-		0x1,
-		0,
-		NULL,
-		0);
+	Status = RTUSB_VendorRequest(pAd,
+				     USBD_TRANSFER_DIRECTION_OUT,
+				     DEVICE_VENDOR_REQUEST_OUT,
+				     0x01, 0x1, 0, NULL, 0);
 
 	DBGPRINT_RAW(RT_DEBUG_ERROR, ("<--RTUSBVenderReset\n"));
 	return Status;
 }
+
 /*
 	========================================================================
 
@@ -185,23 +137,16 @@
 
 	========================================================================
 */
-NTSTATUS	RTUSBMultiRead(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	OUT	PUCHAR			pData,
-	IN	USHORT			length)
+int RTUSBMultiRead(struct rt_rtmp_adapter *pAd,
+			u16 Offset, u8 *pData, u16 length)
 {
-	NTSTATUS	Status;
+	int Status;
 
-	Status = RTUSB_VendorRequest(
-		pAd,
-		(USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
-		DEVICE_VENDOR_REQUEST_IN,
-		0x7,
-		0,
-		Offset,
-		pData,
-		length);
+	Status = RTUSB_VendorRequest(pAd,
+				     (USBD_TRANSFER_DIRECTION_IN |
+				      USBD_SHORT_TRANSFER_OK),
+				     DEVICE_VENDOR_REQUEST_IN, 0x7, 0, Offset,
+				     pData, length);
 
 	return Status;
 }
@@ -221,77 +166,56 @@
 
 	========================================================================
 */
-NTSTATUS	RTUSBMultiWrite_OneByte(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	IN	PUCHAR			pData)
+int RTUSBMultiWrite_OneByte(struct rt_rtmp_adapter *pAd,
+				 u16 Offset, u8 *pData)
 {
-	NTSTATUS	Status;
+	int Status;
 
-	// TODO: In 2870, use this funciton carefully cause it's not stable.
-	Status = RTUSB_VendorRequest(
-		pAd,
-		USBD_TRANSFER_DIRECTION_OUT,
-		DEVICE_VENDOR_REQUEST_OUT,
-		0x6,
-		0,
-		Offset,
-		pData,
-		1);
+	/* TODO: In 2870, use this funciton carefully cause it's not stable. */
+	Status = RTUSB_VendorRequest(pAd,
+				     USBD_TRANSFER_DIRECTION_OUT,
+				     DEVICE_VENDOR_REQUEST_OUT,
+				     0x6, 0, Offset, pData, 1);
 
 	return Status;
 }
 
-NTSTATUS	RTUSBMultiWrite(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	IN	PUCHAR			pData,
-	IN	USHORT			length)
+int RTUSBMultiWrite(struct rt_rtmp_adapter *pAd,
+			 u16 Offset, u8 *pData, u16 length)
 {
-	NTSTATUS	Status;
+	int Status;
 
+	u16 index = 0, Value;
+	u8 *pSrc = pData;
+	u16 resude = 0;
 
-        USHORT          index = 0,Value;
-        PUCHAR          pSrc = pData;
-        USHORT          resude = 0;
-
-        resude = length % 2;
-		length  += resude;
-		do
-		{
-			Value =(USHORT)( *pSrc  | (*(pSrc + 1) << 8));
-		Status = RTUSBSingleWrite(pAd,Offset + index,Value);
-            index +=2;
-            length -= 2;
-            pSrc = pSrc + 2;
-        }while(length > 0);
+	resude = length % 2;
+	length += resude;
+	do {
+		Value = (u16)(*pSrc | (*(pSrc + 1) << 8));
+		Status = RTUSBSingleWrite(pAd, Offset + index, Value);
+		index += 2;
+		length -= 2;
+		pSrc = pSrc + 2;
+	} while (length > 0);
 
 	return Status;
 }
 
-
-NTSTATUS RTUSBSingleWrite(
-	IN 	RTMP_ADAPTER 	*pAd,
-	IN	USHORT			Offset,
-	IN	USHORT			Value)
+int RTUSBSingleWrite(struct rt_rtmp_adapter *pAd,
+			  u16 Offset, u16 Value)
 {
-	NTSTATUS	Status;
+	int Status;
 
-	Status = RTUSB_VendorRequest(
-		pAd,
-		USBD_TRANSFER_DIRECTION_OUT,
-		DEVICE_VENDOR_REQUEST_OUT,
-		0x2,
-		Value,
-		Offset,
-		NULL,
-		0);
+	Status = RTUSB_VendorRequest(pAd,
+				     USBD_TRANSFER_DIRECTION_OUT,
+				     DEVICE_VENDOR_REQUEST_OUT,
+				     0x2, Value, Offset, NULL, 0);
 
 	return Status;
 
 }
 
-
 /*
 	========================================================================
 
@@ -307,34 +231,26 @@
 
 	========================================================================
 */
-NTSTATUS	RTUSBReadMACRegister(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	OUT	PUINT32			pValue)
+int RTUSBReadMACRegister(struct rt_rtmp_adapter *pAd,
+			      u16 Offset, u32 *pValue)
 {
-	NTSTATUS	Status;
-	UINT32		localVal;
+	int Status = 0;
+	u32 localVal;
 
-	Status = RTUSB_VendorRequest(
-		pAd,
-		(USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
-		DEVICE_VENDOR_REQUEST_IN,
-		0x7,
-		0,
-		Offset,
-		&localVal,
-		4);
+	Status = RTUSB_VendorRequest(pAd,
+				     (USBD_TRANSFER_DIRECTION_IN |
+				      USBD_SHORT_TRANSFER_OK),
+				     DEVICE_VENDOR_REQUEST_IN, 0x7, 0, Offset,
+				     &localVal, 4);
 
 	*pValue = le2cpu32(localVal);
 
-
 	if (Status < 0)
 		*pValue = 0xffffffff;
 
 	return Status;
 }
 
-
 /*
 	========================================================================
 
@@ -350,25 +266,22 @@
 
 	========================================================================
 */
-NTSTATUS	RTUSBWriteMACRegister(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	IN	UINT32			Value)
+int RTUSBWriteMACRegister(struct rt_rtmp_adapter *pAd,
+			       u16 Offset, u32 Value)
 {
-	NTSTATUS	Status;
-	UINT32		localVal;
+	int Status;
+	u32 localVal;
 
 	localVal = Value;
 
-	Status = RTUSBSingleWrite(pAd, Offset, (USHORT)(localVal & 0xffff));
-	Status = RTUSBSingleWrite(pAd, Offset + 2, (USHORT)((localVal & 0xffff0000) >> 16));
+	Status = RTUSBSingleWrite(pAd, Offset, (u16)(localVal & 0xffff));
+	Status =
+	    RTUSBSingleWrite(pAd, Offset + 2,
+			     (u16)((localVal & 0xffff0000) >> 16));
 
 	return Status;
 }
 
-
-
-#if 1
 /*
 	========================================================================
 
@@ -384,139 +297,77 @@
 
 	========================================================================
 */
-NTSTATUS	RTUSBReadBBPRegister(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Id,
-	IN	PUCHAR			pValue)
+int RTUSBReadBBPRegister(struct rt_rtmp_adapter *pAd,
+			      u8 Id, u8 *pValue)
 {
-	BBP_CSR_CFG_STRUC	BbpCsr;
-	UINT			i = 0;
-	NTSTATUS		status;
+	BBP_CSR_CFG_STRUC BbpCsr;
+	u32 i = 0;
+	int status;
 
-	// Verify the busy condition
-	do
-	{
+	/* Verify the busy condition */
+	do {
 		status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
-		if(status >= 0)
-		{
-		if (!(BbpCsr.field.Busy == BUSY))
-			break;
+		if (status >= 0) {
+			if (!(BbpCsr.field.Busy == BUSY))
+				break;
 		}
-		printk("RTUSBReadBBPRegister(BBP_CSR_CFG_1):retry count=%d!\n", i);
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("RTUSBReadBBPRegister(BBP_CSR_CFG_1):retry count=%d!\n",
+			  i));
 		i++;
-	}
-	while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
+	} while ((i < RETRY_LIMIT)
+		 && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
 
-	if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
-	{
-		//
-		// Read failed then Return Default value.
-		//
+	if ((i == RETRY_LIMIT)
+	    || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) {
+		/* */
+		/* Read failed then Return Default value. */
+		/* */
 		*pValue = pAd->BbpWriteLatch[Id];
 
-		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
+		DBGPRINT_RAW(RT_DEBUG_ERROR,
+			     ("Retry count exhausted or device removed!!!\n"));
 		return STATUS_UNSUCCESSFUL;
 	}
-
-	// Prepare for write material
-	BbpCsr.word 				= 0;
-	BbpCsr.field.fRead			= 1;
-	BbpCsr.field.Busy			= 1;
-	BbpCsr.field.RegNum 		= Id;
+	/* Prepare for write material */
+	BbpCsr.word = 0;
+	BbpCsr.field.fRead = 1;
+	BbpCsr.field.Busy = 1;
+	BbpCsr.field.RegNum = Id;
 	RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word);
 
 	i = 0;
-	// Verify the busy condition
-	do
-	{
+	/* Verify the busy condition */
+	do {
 		status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
-		if (status >= 0)
-		{
-		if (!(BbpCsr.field.Busy == BUSY))
-		{
-			*pValue = (UCHAR)BbpCsr.field.Value;
-			break;
-		}
-		}
-		printk("RTUSBReadBBPRegister(BBP_CSR_CFG_2):retry count=%d!\n", i);
-		i++;
-	}
-	while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
-
-	if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
-	{
-		//
-		// Read failed then Return Default value.
-		//
-		*pValue = pAd->BbpWriteLatch[Id];
-
-		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
-		return STATUS_UNSUCCESSFUL;
-	}
-
-	return STATUS_SUCCESS;
-}
-#else
-/*
-	========================================================================
-
-	Routine Description: Read 8-bit BBP register via firmware
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-NTSTATUS	RTUSBReadBBPRegister(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Id,
-	IN	PUCHAR			pValue)
-{
-	BBP_CSR_CFG_STRUC	BbpCsr;
-	int					i, k;
-	for (i=0; i<MAX_BUSY_COUNT; i++)
-	{
-		RTUSBReadMACRegister(pAd, H2M_BBP_AGENT, &BbpCsr.word);
-		if (BbpCsr.field.Busy == BUSY)
-		{
-			continue;
-		}
-		BbpCsr.word = 0;
-		BbpCsr.field.fRead = 1;
-		BbpCsr.field.BBP_RW_MODE = 1;
-		BbpCsr.field.Busy = 1;
-		BbpCsr.field.RegNum = Id;
-		RTUSBWriteMACRegister(pAd, H2M_BBP_AGENT, BbpCsr.word);
-		AsicSendCommandToMcu(pAd, 0x80, 0xff, 0x0, 0x0);
-		for (k=0; k<MAX_BUSY_COUNT; k++)
-		{
-			RTUSBReadMACRegister(pAd, H2M_BBP_AGENT, &BbpCsr.word);
-			if (BbpCsr.field.Busy == IDLE)
+		if (status >= 0) {
+			if (!(BbpCsr.field.Busy == BUSY)) {
+				*pValue = (u8)BbpCsr.field.Value;
 				break;
+			}
 		}
-		if ((BbpCsr.field.Busy == IDLE) &&
-			(BbpCsr.field.RegNum == Id))
-		{
-			*pValue = (UCHAR)BbpCsr.field.Value;
-			break;
-		}
-	}
-	if (BbpCsr.field.Busy == BUSY)
-	{
-		DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", Id, BbpCsr.word));
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("RTUSBReadBBPRegister(BBP_CSR_CFG_2):retry count=%d!\n",
+			  i));
+		i++;
+	} while ((i < RETRY_LIMIT)
+		 && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
+
+	if ((i == RETRY_LIMIT)
+	    || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) {
+		/* */
+		/* Read failed then Return Default value. */
+		/* */
 		*pValue = pAd->BbpWriteLatch[Id];
+
+		DBGPRINT_RAW(RT_DEBUG_ERROR,
+			     ("Retry count exhausted or device removed!!!\n"));
 		return STATUS_UNSUCCESSFUL;
 	}
+
 	return STATUS_SUCCESS;
 }
-#endif
 
-#if 1
 /*
 	========================================================================
 
@@ -532,95 +383,46 @@
 
 	========================================================================
 */
-NTSTATUS	RTUSBWriteBBPRegister(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Id,
-	IN	UCHAR			Value)
+int RTUSBWriteBBPRegister(struct rt_rtmp_adapter *pAd,
+			       u8 Id, u8 Value)
 {
-	BBP_CSR_CFG_STRUC	BbpCsr;
-	UINT			i = 0;
-	NTSTATUS		status;
-	// Verify the busy condition
-	do
-	{
+	BBP_CSR_CFG_STRUC BbpCsr;
+	u32 i = 0;
+	int status;
+	/* Verify the busy condition */
+	do {
 		status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
-		if (status >= 0)
-		{
-		if (!(BbpCsr.field.Busy == BUSY))
-			break;
+		if (status >= 0) {
+			if (!(BbpCsr.field.Busy == BUSY))
+				break;
 		}
-		printk("RTUSBWriteBBPRegister(BBP_CSR_CFG):retry count=%d!\n", i);
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("RTUSBWriteBBPRegister(BBP_CSR_CFG):retry count=%d!\n",
+			  i));
 		i++;
 	}
-	while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
+	while ((i < RETRY_LIMIT)
+	       && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
 
-	if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
-	{
-		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
+	if ((i == RETRY_LIMIT)
+	    || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) {
+		DBGPRINT_RAW(RT_DEBUG_ERROR,
+			     ("Retry count exhausted or device removed!!!\n"));
 		return STATUS_UNSUCCESSFUL;
 	}
-
-	// Prepare for write material
-	BbpCsr.word 				= 0;
-	BbpCsr.field.fRead			= 0;
-	BbpCsr.field.Value			= Value;
-	BbpCsr.field.Busy			= 1;
-	BbpCsr.field.RegNum 		= Id;
+	/* Prepare for write material */
+	BbpCsr.word = 0;
+	BbpCsr.field.fRead = 0;
+	BbpCsr.field.Value = Value;
+	BbpCsr.field.Busy = 1;
+	BbpCsr.field.RegNum = Id;
 	RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word);
 
 	pAd->BbpWriteLatch[Id] = Value;
 
 	return STATUS_SUCCESS;
 }
-#else
-/*
-	========================================================================
 
-	Routine Description: Write 8-bit BBP register via firmware
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-
-NTSTATUS	RTUSBWriteBBPRegister(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Id,
-	IN	UCHAR			Value)
-
-{
-	BBP_CSR_CFG_STRUC	BbpCsr;
-	int					BusyCnt;
-	for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++)
-	{
-		RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word);
-		if (BbpCsr.field.Busy == BUSY)
-			continue;
-		BbpCsr.word = 0;
-		BbpCsr.field.fRead = 0;
-		BbpCsr.field.BBP_RW_MODE = 1;
-		BbpCsr.field.Busy = 1;
-		BbpCsr.field.Value = Value;
-		BbpCsr.field.RegNum = Id;
-		RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word);
-		AsicSendCommandToMcu(pAd, 0x80, 0xff, 0x0, 0x0);
-		pAd->BbpWriteLatch[Id] = Value;
-		break;
-	}
-	if (BusyCnt == MAX_BUSY_COUNT)
-	{
-		DBGPRINT_ERR(("BBP write R%d=0x%x fail\n", Id, BbpCsr.word));
-		return STATUS_UNSUCCESSFUL;
-	}
-	return STATUS_SUCCESS;
-}
-#endif
 /*
 	========================================================================
 
@@ -636,31 +438,31 @@
 
 	========================================================================
 */
-NTSTATUS	RTUSBWriteRFRegister(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UINT32			Value)
+int RTUSBWriteRFRegister(struct rt_rtmp_adapter *pAd, u32 Value)
 {
-	PHY_CSR4_STRUC	PhyCsr4;
-	UINT			i = 0;
-	NTSTATUS		status;
+	PHY_CSR4_STRUC PhyCsr4;
+	u32 i = 0;
+	int status;
 
 	NdisZeroMemory(&PhyCsr4, sizeof(PHY_CSR4_STRUC));
-	do
-	{
+	do {
 		status = RTUSBReadMACRegister(pAd, RF_CSR_CFG0, &PhyCsr4.word);
-		if (status >= 0)
-		{
-		if (!(PhyCsr4.field.Busy))
-			break;
+		if (status >= 0) {
+			if (!(PhyCsr4.field.Busy))
+				break;
 		}
-		printk("RTUSBWriteRFRegister(RF_CSR_CFG0):retry count=%d!\n", i);
+		DBGPRINT(RT_DEBUG_TRACE,
+			 ("RTUSBWriteRFRegister(RF_CSR_CFG0):retry count=%d!\n",
+			  i));
 		i++;
 	}
-	while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
+	while ((i < RETRY_LIMIT)
+	       && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
 
-	if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
-	{
-		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
+	if ((i == RETRY_LIMIT)
+	    || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) {
+		DBGPRINT_RAW(RT_DEBUG_ERROR,
+			     ("Retry count exhausted or device removed!!!\n"));
 		return STATUS_UNSUCCESSFUL;
 	}
 
@@ -672,115 +474,6 @@
 /*
 	========================================================================
 
-	Routine Description: Write RT30xx RF register through MAC
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-NTSTATUS RT30xxWriteRFRegister(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			RegID,
-	IN	UCHAR			Value)
-{
-	RF_CSR_CFG_STRUC	rfcsr;
-	UINT				i = 0;
-
-	do
-	{
-		RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
-
-		if (!rfcsr.field.RF_CSR_KICK)
-			break;
-		i++;
-	}
-	while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
-
-	if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
-	{
-		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
-		return STATUS_UNSUCCESSFUL;
-	}
-
-	rfcsr.field.RF_CSR_WR = 1;
-	rfcsr.field.RF_CSR_KICK = 1;
-	rfcsr.field.TESTCSR_RFACC_REGNUM = RegID;
-	rfcsr.field.RF_CSR_DATA = Value;
-
-	RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
-
-	return STATUS_SUCCESS;
-}
-
-
-/*
-	========================================================================
-
-	Routine Description: Read RT30xx RF register through MAC
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-NTSTATUS RT30xxReadRFRegister(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			RegID,
-	IN	PUCHAR			pValue)
-{
-	RF_CSR_CFG_STRUC	rfcsr;
-	UINT				i=0, k=0;
-
-	for (i=0; i<MAX_BUSY_COUNT; i++)
-	{
-		RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
-
-		if (rfcsr.field.RF_CSR_KICK == BUSY)
-		{
-			continue;
-		}
-		rfcsr.word = 0;
-		rfcsr.field.RF_CSR_WR = 0;
-		rfcsr.field.RF_CSR_KICK = 1;
-		rfcsr.field.TESTCSR_RFACC_REGNUM = RegID;
-		RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
-		for (k=0; k<MAX_BUSY_COUNT; k++)
-		{
-			RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
-
-			if (rfcsr.field.RF_CSR_KICK == IDLE)
-				break;
-		}
-		if ((rfcsr.field.RF_CSR_KICK == IDLE) &&
-			(rfcsr.field.TESTCSR_RFACC_REGNUM == RegID))
-		{
-			*pValue = (UCHAR)rfcsr.field.RF_CSR_DATA;
-			break;
-		}
-	}
-	if (rfcsr.field.RF_CSR_KICK == BUSY)
-	{
-		DBGPRINT_ERR(("RF read R%d=0x%x fail, i[%d], k[%d]\n", RegID, rfcsr.word,i,k));
-		return STATUS_UNSUCCESSFUL;
-	}
-
-	return STATUS_SUCCESS;
-}
-
-/*
-	========================================================================
-
 	Routine Description:
 
 	Arguments:
@@ -793,28 +486,16 @@
 
 	========================================================================
 */
-NTSTATUS	RTUSBReadEEPROM(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	OUT	PUCHAR			pData,
-	IN	USHORT			length)
+int RTUSBReadEEPROM(struct rt_rtmp_adapter *pAd,
+			 u16 Offset, u8 *pData, u16 length)
 {
-	NTSTATUS	Status = STATUS_SUCCESS;
+	int Status = STATUS_SUCCESS;
 
-	if(pAd->bUseEfuse)
-		Status =eFuseRead(pAd, Offset, pData, length);
-	else
-	{
-	Status = RTUSB_VendorRequest(
-		pAd,
-		(USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
-		DEVICE_VENDOR_REQUEST_IN,
-		0x9,
-		0,
-		Offset,
-		pData,
-		length);
-	}
+	Status = RTUSB_VendorRequest(pAd,
+				     (USBD_TRANSFER_DIRECTION_IN |
+				      USBD_SHORT_TRANSFER_OK),
+				     DEVICE_VENDOR_REQUEST_IN, 0x9, 0, Offset,
+				     pData, length);
 
 	return Status;
 }
@@ -834,32 +515,33 @@
 
 	========================================================================
 */
-NTSTATUS	RTUSBWriteEEPROM(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	IN	PUCHAR			pData,
-	IN	USHORT			length)
+int RTUSBWriteEEPROM(struct rt_rtmp_adapter *pAd,
+			  u16 Offset, u8 *pData, u16 length)
 {
-	NTSTATUS	Status = STATUS_SUCCESS;
+	int Status = STATUS_SUCCESS;
 
-	if(pAd->bUseEfuse)
-		Status = eFuseWrite(pAd, Offset, pData, length);
-	else
-	{
-	Status = RTUSB_VendorRequest(
-		pAd,
-		USBD_TRANSFER_DIRECTION_OUT,
-		DEVICE_VENDOR_REQUEST_OUT,
-		0x8,
-		0,
-		Offset,
-		pData,
-		length);
-	}
+	Status = RTUSB_VendorRequest(pAd,
+				     USBD_TRANSFER_DIRECTION_OUT,
+				     DEVICE_VENDOR_REQUEST_OUT,
+				     0x8, 0, Offset, pData, length);
 
 	return Status;
 }
 
+int RTUSBReadEEPROM16(struct rt_rtmp_adapter *pAd,
+			   u16 offset, u16 *pData)
+{
+	int status;
+	u16 localData;
+
+	status = RTUSBReadEEPROM(pAd, offset, (u8 *)(&localData), 2);
+	if (status == STATUS_SUCCESS)
+		*pData = le2cpu16(localData);
+
+	return status;
+
+}
+
 /*
 	========================================================================
 
@@ -875,16 +557,15 @@
 
 	========================================================================
 */
-VOID RTUSBPutToSleep(
-	IN	PRTMP_ADAPTER	pAd)
+void RTUSBPutToSleep(struct rt_rtmp_adapter *pAd)
 {
-	UINT32		value;
+	u32 value;
 
-	// Timeout 0x40 x 50us
-	value = (SLEEPCID<<16)+(OWNERMCU<<24)+ (0x40<<8)+1;
+	/* Timeout 0x40 x 50us */
+	value = (SLEEPCID << 16) + (OWNERMCU << 24) + (0x40 << 8) + 1;
 	RTUSBWriteMACRegister(pAd, 0x7010, value);
 	RTUSBWriteMACRegister(pAd, 0x404, 0x30);
-	//RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+	/*RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); */
 	DBGPRINT_RAW(RT_DEBUG_ERROR, ("Sleep Mailbox testvalue %x\n", value));
 
 }
@@ -904,20 +585,14 @@
 
 	========================================================================
 */
-NTSTATUS RTUSBWakeUp(
-	IN	PRTMP_ADAPTER	pAd)
+int RTUSBWakeUp(struct rt_rtmp_adapter *pAd)
 {
-	NTSTATUS	Status;
+	int Status;
 
-	Status = RTUSB_VendorRequest(
-		pAd,
-		USBD_TRANSFER_DIRECTION_OUT,
-		DEVICE_VENDOR_REQUEST_OUT,
-		0x01,
-		0x09,
-		0,
-		NULL,
-		0);
+	Status = RTUSB_VendorRequest(pAd,
+				     USBD_TRANSFER_DIRECTION_OUT,
+				     DEVICE_VENDOR_REQUEST_OUT,
+				     0x01, 0x09, 0, NULL, 0);
 
 	return Status;
 }
@@ -937,13 +612,12 @@
 
 	========================================================================
 */
-VOID	RTUSBInitializeCmdQ(
-	IN	PCmdQ	cmdq)
+void RTUSBInitializeCmdQ(struct rt_cmdq *cmdq)
 {
 	cmdq->head = NULL;
 	cmdq->tail = NULL;
 	cmdq->size = 0;
-	cmdq->CmdQState = RT2870_THREAD_INITED;
+	cmdq->CmdQState = RTMP_TASK_STAT_INITED;
 }
 
 /*
@@ -961,41 +635,45 @@
 
 	========================================================================
 */
-NDIS_STATUS	RTUSBEnqueueCmdFromNdis(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	NDIS_OID		Oid,
-	IN	BOOLEAN			SetInformation,
-	IN	PVOID			pInformationBuffer,
-	IN	UINT32			InformationBufferLength)
+int RTUSBEnqueueCmdFromNdis(struct rt_rtmp_adapter *pAd,
+				    IN NDIS_OID Oid,
+				    IN BOOLEAN SetInformation,
+				    void *pInformationBuffer,
+				    u32 InformationBufferLength)
 {
-	NDIS_STATUS	status;
-	PCmdQElmt	cmdqelmt = NULL;
-	POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+	int status;
+	struct rt_cmdqelmt *cmdqelmt = NULL;
+	struct rt_rtmp_os_task *pTask = &pAd->cmdQTask;
 
-	if (pid_nr(pObj->RTUSBCmdThr_pid) > 0)
-		return (NDIS_STATUS_RESOURCES);
+#ifdef KTHREAD_SUPPORT
+	if (pTask->kthread_task == NULL)
+#else
+	CHECK_PID_LEGALITY(pTask->taskPID) {
+	}
+	else
+#endif
+	return (NDIS_STATUS_RESOURCES);
 
-	status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt));
+	status = os_alloc_mem(pAd, (u8 **) (&cmdqelmt), sizeof(struct rt_cmdqelmt));
 	if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
 		return (NDIS_STATUS_RESOURCES);
 
-		cmdqelmt->buffer = NULL;
-		if (pInformationBuffer != NULL)
-		{
-			status = RTMPAllocateMemory((PVOID *)&cmdqelmt->buffer, InformationBufferLength);
-			if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL))
-			{
-				kfree(cmdqelmt);
-				return (NDIS_STATUS_RESOURCES);
-			}
-			else
-			{
-				NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength);
-				cmdqelmt->bufferlength = InformationBufferLength;
-			}
+	cmdqelmt->buffer = NULL;
+	if (pInformationBuffer != NULL) {
+		status =
+		    os_alloc_mem(pAd, (u8 **) & cmdqelmt->buffer,
+				 InformationBufferLength);
+		if ((status != NDIS_STATUS_SUCCESS)
+		    || (cmdqelmt->buffer == NULL)) {
+			kfree(cmdqelmt);
+			return (NDIS_STATUS_RESOURCES);
+		} else {
+			NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer,
+				       InformationBufferLength);
+			cmdqelmt->bufferlength = InformationBufferLength;
 		}
-		else
-			cmdqelmt->bufferlength = 0;
+	} else
+		cmdqelmt->bufferlength = 0;
 
 	cmdqelmt->command = Oid;
 	cmdqelmt->CmdFromNdis = TRUE;
@@ -1005,28 +683,22 @@
 		cmdqelmt->SetOperation = FALSE;
 
 	NdisAcquireSpinLock(&pAd->CmdQLock);
-	if (pAd->CmdQ.CmdQState & RT2870_THREAD_CAN_DO_INSERT)
-	{
+	if (pAd->CmdQ.CmdQState & RTMP_TASK_CAN_DO_INSERT) {
 		EnqueueCmd((&pAd->CmdQ), cmdqelmt);
 		status = NDIS_STATUS_SUCCESS;
-	}
-	else
-	{
+	} else {
 		status = NDIS_STATUS_FAILURE;
 	}
 	NdisReleaseSpinLock(&pAd->CmdQLock);
 
-	if (status == NDIS_STATUS_FAILURE)
-	{
+	if (status == NDIS_STATUS_FAILURE) {
 		if (cmdqelmt->buffer)
-			NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
-		NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
-	}
-	else
-	RTUSBCMDUp(pAd);
+			os_free_mem(pAd, cmdqelmt->buffer);
+		os_free_mem(pAd, cmdqelmt);
+	} else
+		RTUSBCMDUp(pAd);
 
-
-    return(NDIS_STATUS_SUCCESS);
+	return (NDIS_STATUS_SUCCESS);
 }
 
 /*
@@ -1044,37 +716,33 @@
 
 	========================================================================
 */
-NDIS_STATUS RTUSBEnqueueInternalCmd(
-	IN PRTMP_ADAPTER	pAd,
-	IN NDIS_OID			Oid,
-	IN PVOID			pInformationBuffer,
-	IN UINT32			InformationBufferLength)
+int RTUSBEnqueueInternalCmd(struct rt_rtmp_adapter *pAd,
+				    IN NDIS_OID Oid,
+				    void *pInformationBuffer,
+				    u32 InformationBufferLength)
 {
-	NDIS_STATUS	status;
-	PCmdQElmt	cmdqelmt = NULL;
+	int status;
+	struct rt_cmdqelmt *cmdqelmt = NULL;
 
-
-	status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt));
+	status = os_alloc_mem(pAd, (u8 **) & cmdqelmt, sizeof(struct rt_cmdqelmt));
 	if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
 		return (NDIS_STATUS_RESOURCES);
-	NdisZeroMemory(cmdqelmt, sizeof(CmdQElmt));
+	NdisZeroMemory(cmdqelmt, sizeof(struct rt_cmdqelmt));
 
-	if(InformationBufferLength > 0)
-	{
-		status = RTMPAllocateMemory((PVOID *)&cmdqelmt->buffer, InformationBufferLength);
-		if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL))
-		{
-			NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
+	if (InformationBufferLength > 0) {
+		status =
+		    os_alloc_mem(pAd, (u8 **) & cmdqelmt->buffer,
+				 InformationBufferLength);
+		if ((status != NDIS_STATUS_SUCCESS)
+		    || (cmdqelmt->buffer == NULL)) {
+			os_free_mem(pAd, cmdqelmt);
 			return (NDIS_STATUS_RESOURCES);
-		}
-		else
-		{
-			NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength);
+		} else {
+			NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer,
+				       InformationBufferLength);
 			cmdqelmt->bufferlength = InformationBufferLength;
 		}
-	}
-	else
-	{
+	} else {
 		cmdqelmt->buffer = NULL;
 		cmdqelmt->bufferlength = 0;
 	}
@@ -1082,30 +750,24 @@
 	cmdqelmt->command = Oid;
 	cmdqelmt->CmdFromNdis = FALSE;
 
-	if (cmdqelmt != NULL)
-	{
+	if (cmdqelmt != NULL) {
 		NdisAcquireSpinLock(&pAd->CmdQLock);
-		if (pAd->CmdQ.CmdQState & RT2870_THREAD_CAN_DO_INSERT)
-		{
+		if (pAd->CmdQ.CmdQState & RTMP_TASK_CAN_DO_INSERT) {
 			EnqueueCmd((&pAd->CmdQ), cmdqelmt);
 			status = NDIS_STATUS_SUCCESS;
-		}
-		else
-		{
+		} else {
 			status = NDIS_STATUS_FAILURE;
 		}
 		NdisReleaseSpinLock(&pAd->CmdQLock);
 
-		if (status == NDIS_STATUS_FAILURE)
-		{
+		if (status == NDIS_STATUS_FAILURE) {
 			if (cmdqelmt->buffer)
-				NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
-			NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
-		}
-		else
-		RTUSBCMDUp(pAd);
+				os_free_mem(pAd, cmdqelmt->buffer);
+			os_free_mem(pAd, cmdqelmt);
+		} else
+			RTUSBCMDUp(pAd);
 	}
-	return(NDIS_STATUS_SUCCESS);
+	return (NDIS_STATUS_SUCCESS);
 }
 
 /*
@@ -1123,14 +785,11 @@
 
 	========================================================================
 */
-VOID	RTUSBDequeueCmd(
-	IN	PCmdQ		cmdq,
-	OUT	PCmdQElmt	*pcmdqelmt)
+void RTUSBDequeueCmd(struct rt_cmdq *cmdq, struct rt_cmdqelmt * * pcmdqelmt)
 {
 	*pcmdqelmt = cmdq->head;
 
-	if (*pcmdqelmt != NULL)
-	{
+	if (*pcmdqelmt != NULL) {
 		cmdq->head = cmdq->head->next;
 		cmdq->size--;
 		if (cmdq->size == 0)
@@ -1164,7 +823,6 @@
 	  method can wait for it to complete.  Since you don't have a handle on
 	  the URB used, you can't cancel the request.
 
-
 	Routine Description:
 
 	Arguments:
@@ -1175,68 +833,109 @@
 
 	========================================================================
 */
-NTSTATUS    RTUSB_VendorRequest(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UINT32			TransferFlags,
-	IN	UCHAR			RequestType,
-	IN	UCHAR			Request,
-	IN	USHORT			Value,
-	IN	USHORT			Index,
-	IN	PVOID			TransferBuffer,
-	IN	UINT32			TransferBufferLength)
+int RTUSB_VendorRequest(struct rt_rtmp_adapter *pAd,
+			     u32 TransferFlags,
+			     u8 RequestType,
+			     u8 Request,
+			     u16 Value,
+			     u16 Index,
+			     void *TransferBuffer,
+			     u32 TransferBufferLength)
 {
-	int				ret;
-	POS_COOKIE		pObj = (POS_COOKIE) pAd->OS_Cookie;
+	int ret = 0;
+	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
 
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
-	{
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
 		DBGPRINT(RT_DEBUG_ERROR, ("device disconnected\n"));
 		return -1;
-	}
-	else if (in_interrupt())
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("in_interrupt, RTUSB_VendorRequest Request%02x Value%04x Offset%04x\n",Request,Value,Index));
+	} else if (in_interrupt()) {
+		DBGPRINT(RT_DEBUG_ERROR,
+			 ("in_interrupt, RTUSB_VendorRequest Request%02x Value%04x Offset%04x\n",
+			  Request, Value, Index));
 
 		return -1;
-	}
-	else
-	{
+	} else {
 #define MAX_RETRY_COUNT  10
 
 		int retryCount = 0;
-		void	*tmpBuf = TransferBuffer;
+		void *tmpBuf = TransferBuffer;
 
-		// Acquire Control token
-		do {
-		if( RequestType == DEVICE_VENDOR_REQUEST_OUT)
-			ret=usb_control_msg(pObj->pUsb_Dev, usb_sndctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
-		else if(RequestType == DEVICE_VENDOR_REQUEST_IN)
-			ret=usb_control_msg(pObj->pUsb_Dev, usb_rcvctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
-		else
-		{
-			DBGPRINT(RT_DEBUG_ERROR, ("vendor request direction is failed\n"));
-			ret = -1;
+		ret = down_interruptible(&(pAd->UsbVendorReq_semaphore));
+		if (pAd->UsbVendorReqBuf) {
+			ASSERT(TransferBufferLength < MAX_PARAM_BUFFER_SIZE);
+
+			tmpBuf = (void *)pAd->UsbVendorReqBuf;
+			NdisZeroMemory(pAd->UsbVendorReqBuf,
+				       TransferBufferLength);
+
+			if (RequestType == DEVICE_VENDOR_REQUEST_OUT)
+				NdisMoveMemory(tmpBuf, TransferBuffer,
+					       TransferBufferLength);
 		}
 
+		do {
+			if (RequestType == DEVICE_VENDOR_REQUEST_OUT)
+				ret =
+				    usb_control_msg(pObj->pUsb_Dev,
+						    usb_sndctrlpipe(pObj->
+								    pUsb_Dev,
+								    0), Request,
+						    RequestType, Value, Index,
+						    tmpBuf,
+						    TransferBufferLength,
+						    CONTROL_TIMEOUT_JIFFIES);
+			else if (RequestType == DEVICE_VENDOR_REQUEST_IN)
+				ret =
+				    usb_control_msg(pObj->pUsb_Dev,
+						    usb_rcvctrlpipe(pObj->
+								    pUsb_Dev,
+								    0), Request,
+						    RequestType, Value, Index,
+						    tmpBuf,
+						    TransferBufferLength,
+						    CONTROL_TIMEOUT_JIFFIES);
+			else {
+				DBGPRINT(RT_DEBUG_ERROR,
+					 ("vendor request direction is failed\n"));
+				ret = -1;
+			}
+
 			retryCount++;
 			if (ret < 0) {
-				printk("#\n");
+				DBGPRINT(RT_DEBUG_OFF, ("#\n"));
 				RTMPusecDelay(5000);
 			}
-		} while((ret < 0) && (retryCount < MAX_RETRY_COUNT));
+		} while ((ret < 0) && (retryCount < MAX_RETRY_COUNT));
 
-        if (ret < 0) {
-//			DBGPRINT(RT_DEBUG_ERROR, ("USBVendorRequest failed ret=%d \n",ret));
-			DBGPRINT(RT_DEBUG_ERROR, ("RTUSB_VendorRequest failed(%d),TxFlags=0x%x, ReqType=%s, Req=0x%x, Index=0x%x\n",
-						ret, TransferFlags, (RequestType == DEVICE_VENDOR_REQUEST_OUT ? "OUT" : "IN"), Request, Index));
+		if ((pAd->UsbVendorReqBuf)
+		    && (RequestType == DEVICE_VENDOR_REQUEST_IN))
+			NdisMoveMemory(TransferBuffer, tmpBuf,
+				       TransferBufferLength);
+		up(&(pAd->UsbVendorReq_semaphore));
+
+		if (ret < 0) {
+			DBGPRINT(RT_DEBUG_ERROR,
+				 ("RTUSB_VendorRequest failed(%d),TxFlags=0x%x, ReqType=%s, Req=0x%x, Index=0x%x\n",
+				  ret, TransferFlags,
+				  (RequestType ==
+				   DEVICE_VENDOR_REQUEST_OUT ? "OUT" : "IN"),
+				  Request, Index));
 			if (Request == 0x2)
-				DBGPRINT(RT_DEBUG_ERROR, ("\tRequest Value=0x%04x!\n", Value));
+				DBGPRINT(RT_DEBUG_ERROR,
+					 ("\tRequest Value=0x%04x!\n", Value));
 
-			if ((TransferBuffer!= NULL) && (TransferBufferLength > 0))
-				hex_dump("Failed TransferBuffer value", TransferBuffer, TransferBufferLength);
-        }
+			if ((TransferBuffer != NULL)
+			    && (TransferBufferLength > 0))
+				hex_dump("Failed TransferBuffer value",
+					 TransferBuffer, TransferBufferLength);
+		}
+
 	}
-	return ret;
+
+	if (ret != -1)
+		return STATUS_SUCCESS;
+	else
+		return STATUS_UNSUCCESSFUL;
 }
 
 /*
@@ -1255,28 +954,25 @@
 
 	========================================================================
 */
-NTSTATUS	RTUSB_ResetDevice(
-	IN	PRTMP_ADAPTER	pAd)
+int RTUSB_ResetDevice(struct rt_rtmp_adapter *pAd)
 {
-	NTSTATUS		Status = TRUE;
+	int Status = TRUE;
 
 	DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->USB_ResetDevice\n"));
-	//RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
+	/*RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS); */
 	return Status;
 }
 
-VOID CMDHandler(
-    IN PRTMP_ADAPTER pAd)
+void CMDHandler(struct rt_rtmp_adapter *pAd)
 {
-	PCmdQElmt		cmdqelmt;
-	PUCHAR			pData;
-	NDIS_STATUS		NdisStatus = NDIS_STATUS_SUCCESS;
-//	ULONG			Now = 0;
-	NTSTATUS		ntStatus;
-//	unsigned long	IrqFlags;
+	struct rt_cmdqelmt *cmdqelmt;
+	u8 *pData;
+	int NdisStatus = NDIS_STATUS_SUCCESS;
+/*      unsigned long                   Now = 0; */
+	int ntStatus;
+/*      unsigned long   IrqFlags; */
 
-	while (pAd->CmdQ.size > 0)
-	{
+	while (pAd && pAd->CmdQ.size > 0) {
 		NdisStatus = NDIS_STATUS_SUCCESS;
 
 		NdisAcquireSpinLock(&pAd->CmdQLock);
@@ -1288,591 +984,1129 @@
 
 		pData = cmdqelmt->buffer;
 
-		if(!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
-		{
-			switch (cmdqelmt->command)
-			{
-				case CMDTHREAD_CHECK_GPIO:
+		if (!
+		    (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)
+		     || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) {
+			switch (cmdqelmt->command) {
+			case CMDTHREAD_CHECK_GPIO:
+				{
+					u32 data;
+
 					{
-						UINT32 data;
+						/* Read GPIO pin2 as Hardware controlled radio state */
 
-						{
-							// Read GPIO pin2 as Hardware controlled radio state
+						RTUSBReadMACRegister(pAd,
+								     GPIO_CTRL_CFG,
+								     &data);
 
-							RTUSBReadMACRegister( pAd, GPIO_CTRL_CFG, &data);
+						if (data & 0x04) {
+							pAd->StaCfg.bHwRadio =
+							    TRUE;
+						} else {
+							pAd->StaCfg.bHwRadio =
+							    FALSE;
+						}
 
-							if (data & 0x04)
-							{
-								pAd->StaCfg.bHwRadio = TRUE;
+						if (pAd->StaCfg.bRadio !=
+						    (pAd->StaCfg.bHwRadio
+						     && pAd->StaCfg.bSwRadio)) {
+							pAd->StaCfg.bRadio =
+							    (pAd->StaCfg.
+							     bHwRadio
+							     && pAd->StaCfg.
+							     bSwRadio);
+							if (pAd->StaCfg.
+							    bRadio == TRUE) {
+								DBGPRINT_RAW
+								    (RT_DEBUG_ERROR,
+								     ("!!! Radio On !!!\n"));
+
+								MlmeRadioOn
+								    (pAd);
+								/* Update extra information */
+								pAd->ExtraInfo =
+								    EXTRA_INFO_CLEAR;
+							} else {
+								DBGPRINT_RAW
+								    (RT_DEBUG_ERROR,
+								     ("!!! Radio Off !!!\n"));
+
+								MlmeRadioOff
+								    (pAd);
+								/* Update extra information */
+								pAd->ExtraInfo =
+								    HW_RADIO_OFF;
 							}
-							else
-							{
-								pAd->StaCfg.bHwRadio = FALSE;
-							}
+						}
+					}
+				}
+				break;
 
-							if(pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
-							{
-								pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
-								if(pAd->StaCfg.bRadio == TRUE)
-								{
-									DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio On !!!\n"));
+			case CMDTHREAD_QKERIODIC_EXECUT:
+				{
+					StaQuickResponeForRateUpExec(NULL, pAd,
+								     NULL,
+								     NULL);
+				}
+				break;
 
-									MlmeRadioOn(pAd);
-									// Update extra information
-									pAd->ExtraInfo = EXTRA_INFO_CLEAR;
+			case CMDTHREAD_RESET_BULK_OUT:
+				{
+					u32 MACValue;
+					u8 Index;
+					int ret = 0;
+					struct rt_ht_tx_context *pHTTXContext;
+/*                                              struct rt_rtmp_tx_ring *pTxRing; */
+					unsigned long IrqFlags;
+
+					DBGPRINT_RAW(RT_DEBUG_TRACE,
+						     ("CmdThread : CMDTHREAD_RESET_BULK_OUT(ResetPipeid=0x%0x)===>\n",
+						      pAd->bulkResetPipeid));
+					/* All transfers must be aborted or cancelled before attempting to reset the pipe. */
+					/*RTUSBCancelPendingBulkOutIRP(pAd); */
+					/* Wait 10ms to let previous packet that are already in HW FIFO to clear. by MAXLEE 12-25-2007 */
+					Index = 0;
+					do {
+						RTUSBReadMACRegister(pAd,
+								     TXRXQ_PCNT,
+								     &MACValue);
+						if ((MACValue & 0xf00000
+						     /*0x800000 */ ) == 0)
+							break;
+						Index++;
+						RTMPusecDelay(10000);
+					} while (Index < 100);
+					MACValue = 0;
+					RTUSBReadMACRegister(pAd, USB_DMA_CFG,
+							     &MACValue);
+					/* To prevent Read Register error, we 2nd check the validity. */
+					if ((MACValue & 0xc00000) == 0)
+						RTUSBReadMACRegister(pAd,
+								     USB_DMA_CFG,
+								     &MACValue);
+					/* To prevent Read Register error, we 3rd check the validity. */
+					if ((MACValue & 0xc00000) == 0)
+						RTUSBReadMACRegister(pAd,
+								     USB_DMA_CFG,
+								     &MACValue);
+					MACValue |= 0x80000;
+					RTUSBWriteMACRegister(pAd, USB_DMA_CFG,
+							      MACValue);
+
+					/* Wait 1ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007 */
+					RTMPusecDelay(1000);
+
+					MACValue &= (~0x80000);
+					RTUSBWriteMACRegister(pAd, USB_DMA_CFG,
+							      MACValue);
+					DBGPRINT_RAW(RT_DEBUG_TRACE,
+						     ("\tSet 0x2a0 bit19. Clear USB DMA TX path\n"));
+
+					/* Wait 5ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007 */
+					/*RTMPusecDelay(5000); */
+
+					if ((pAd->
+					     bulkResetPipeid &
+					     BULKOUT_MGMT_RESET_FLAG) ==
+					    BULKOUT_MGMT_RESET_FLAG) {
+						RTMP_CLEAR_FLAG(pAd,
+								fRTMP_ADAPTER_BULKOUT_RESET);
+						if (pAd->MgmtRing.TxSwFreeIdx <
+						    MGMT_RING_SIZE
+						    /* pMLMEContext->bWaitingBulkOut == TRUE */
+						    ) {
+							RTUSB_SET_BULK_FLAG(pAd,
+									    fRTUSB_BULK_OUT_MLME);
+						}
+						RTUSBKickBulkOut(pAd);
+
+						DBGPRINT_RAW(RT_DEBUG_TRACE,
+							     ("\tTX MGMT RECOVER Done!\n"));
+					} else {
+						pHTTXContext =
+						    &(pAd->
+						      TxContext[pAd->
+								bulkResetPipeid]);
+						/*NdisAcquireSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]); */
+						RTMP_INT_LOCK(&pAd->
+							      BulkOutLock[pAd->
+									  bulkResetPipeid],
+							      IrqFlags);
+						if (pAd->
+						    BulkOutPending[pAd->
+								   bulkResetPipeid]
+						    == FALSE) {
+							pAd->
+							    BulkOutPending[pAd->
+									   bulkResetPipeid]
+							    = TRUE;
+							pHTTXContext->
+							    IRPPending = TRUE;
+							pAd->
+							    watchDogTxPendingCnt
+							    [pAd->
+							     bulkResetPipeid] =
+							    1;
+
+							/* no matter what, clean the flag */
+							RTMP_CLEAR_FLAG(pAd,
+									fRTMP_ADAPTER_BULKOUT_RESET);
+
+							/*NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]); */
+							RTMP_INT_UNLOCK(&pAd->
+									BulkOutLock
+									[pAd->
+									 bulkResetPipeid],
+									IrqFlags);
+							{
+								RTUSBInitHTTxDesc
+								    (pAd,
+								     pHTTXContext,
+								     pAd->
+								     bulkResetPipeid,
+								     pHTTXContext->
+								     BulkOutSize,
+								     (usb_complete_t)
+								     RTUSBBulkOutDataPacketComplete);
+
+								if ((ret =
+								     RTUSB_SUBMIT_URB
+								     (pHTTXContext->
+								      pUrb)) !=
+								    0) {
+									RTMP_INT_LOCK
+									    (&pAd->
+									     BulkOutLock
+									     [pAd->
+									      bulkResetPipeid],
+									     IrqFlags);
+									pAd->
+									    BulkOutPending
+									    [pAd->
+									     bulkResetPipeid]
+									    =
+									    FALSE;
+									pHTTXContext->
+									    IRPPending
+									    =
+									    FALSE;
+									pAd->
+									    watchDogTxPendingCnt
+									    [pAd->
+									     bulkResetPipeid]
+									    = 0;
+									RTMP_INT_UNLOCK
+									    (&pAd->
+									     BulkOutLock
+									     [pAd->
+									      bulkResetPipeid],
+									     IrqFlags);
+
+									DBGPRINT
+									    (RT_DEBUG_ERROR,
+									     ("CmdThread : CMDTHREAD_RESET_BULK_OUT: Submit Tx URB failed %d\n",
+									      ret));
+								} else {
+									RTMP_IRQ_LOCK
+									    (&pAd->
+									     BulkOutLock
+									     [pAd->
+									      bulkResetPipeid],
+									     IrqFlags);
+									DBGPRINT_RAW
+									    (RT_DEBUG_TRACE,
+									     ("\tCMDTHREAD_RESET_BULK_OUT: TxContext[%d]:CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, pending=%d!\n",
+									      pAd->
+									      bulkResetPipeid,
+									      pHTTXContext->
+									      CurWritePosition,
+									      pHTTXContext->
+									      NextBulkOutPosition,
+									      pHTTXContext->
+									      ENextBulkOutPosition,
+									      pHTTXContext->
+									      bCopySavePad,
+									      pAd->
+									      BulkOutPending
+									      [pAd->
+									       bulkResetPipeid]));
+									DBGPRINT_RAW
+									    (RT_DEBUG_TRACE,
+									     ("\t\tBulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n",
+									      pAd->
+									      BulkOutReq,
+									      pAd->
+									      BulkOutComplete,
+									      pAd->
+									      BulkOutCompleteOther));
+									RTMP_IRQ_UNLOCK
+									    (&pAd->
+									     BulkOutLock
+									     [pAd->
+									      bulkResetPipeid],
+									     IrqFlags);
+									DBGPRINT_RAW
+									    (RT_DEBUG_TRACE,
+									     ("\tCMDTHREAD_RESET_BULK_OUT: Submit Tx DATA URB for failed BulkReq(0x%lx) Done, status=%d!\n",
+									      pAd->
+									      bulkResetReq
+									      [pAd->
+									       bulkResetPipeid],
+									      pHTTXContext->
+									      pUrb->
+									      status));
+
 								}
+							}
+						} else {
+							/*NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]); */
+							/*RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); */
+
+							DBGPRINT_RAW
+							    (RT_DEBUG_ERROR,
+							     ("CmdThread : TX DATA RECOVER FAIL for BulkReq(0x%lx) because BulkOutPending[%d] is TRUE!\n",
+							      pAd->
+							      bulkResetReq[pAd->
+									   bulkResetPipeid],
+							      pAd->
+							      bulkResetPipeid));
+							if (pAd->
+							    bulkResetPipeid ==
+							    0) {
+								u8
+								    pendingContext
+								    = 0;
+								struct rt_ht_tx_context *
+								    pHTTXContext
+								    =
+								    (struct rt_ht_tx_context *)
+								    (&pAd->
+								     TxContext
+								     [pAd->
+								      bulkResetPipeid]);
+								struct rt_tx_context *
+								    pMLMEContext
+								    =
+								    (struct rt_tx_context *)
+								    (pAd->
+								     MgmtRing.
+								     Cell[pAd->
+									  MgmtRing.
+									  TxDmaIdx].
+								     AllocVa);
+								struct rt_tx_context *
+								    pNULLContext
+								    =
+								    (struct rt_tx_context *)
+								    (&pAd->
+								     PsPollContext);
+								struct rt_tx_context *
+								    pPsPollContext
+								    =
+								    (struct rt_tx_context *)
+								    (&pAd->
+								     NullContext);
+
+								if (pHTTXContext->IRPPending)
+									pendingContext
+									    |=
+									    1;
+								else if
+								    (pMLMEContext->
+								     IRPPending)
+									pendingContext
+									    |=
+									    2;
+								else if
+								    (pNULLContext->
+								     IRPPending)
+									pendingContext
+									    |=
+									    4;
+								else if
+								    (pPsPollContext->
+								     IRPPending)
+									pendingContext
+									    |=
+									    8;
 								else
-								{
-									DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio Off !!!\n"));
+									pendingContext
+									    = 0;
 
-									MlmeRadioOff(pAd);
-									// Update extra information
-									pAd->ExtraInfo = HW_RADIO_OFF;
-								}
+								DBGPRINT_RAW
+								    (RT_DEBUG_ERROR,
+								     ("\tTX Occupied by %d!\n",
+								      pendingContext));
 							}
+							/* no matter what, clean the flag */
+							RTMP_CLEAR_FLAG(pAd,
+									fRTMP_ADAPTER_BULKOUT_RESET);
+
+							RTMP_INT_UNLOCK(&pAd->
+									BulkOutLock
+									[pAd->
+									 bulkResetPipeid],
+									IrqFlags);
+
+							RTUSB_SET_BULK_FLAG(pAd,
+									    (fRTUSB_BULK_OUT_DATA_NORMAL
+									     <<
+									     pAd->
+									     bulkResetPipeid));
 						}
+
+						RTMPDeQueuePacket(pAd, FALSE,
+								  NUM_OF_TX_RING,
+								  MAX_TX_PROCESS);
+						/*RTUSBKickBulkOut(pAd); */
 					}
-					break;
 
-				case CMDTHREAD_QKERIODIC_EXECUT:
+				}
+				/*
+				   // Don't cancel BULKIN.
+				   while ((atomic_read(&pAd->PendingRx) > 0) &&
+				   (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+				   {
+				   if (atomic_read(&pAd->PendingRx) > 0)
+				   {
+				   DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!cancel it!\n"));
+				   RTUSBCancelPendingBulkInIRP(pAd);
+				   }
+				   RTMPusecDelay(100000);
+				   }
+
+				   if ((atomic_read(&pAd->PendingRx) == 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
+				   {
+				   u8        i;
+				   RTUSBRxPacket(pAd);
+				   pAd->NextRxBulkInReadIndex = 0;      // Next Rx Read index
+				   pAd->NextRxBulkInIndex               = 0;    // Rx Bulk pointer
+				   for (i = 0; i < (RX_RING_SIZE); i++)
+				   {
+				   struct rt_rx_context *pRxContext = &(pAd->RxContext[i]);
+
+				   pRxContext->pAd      = pAd;
+				   pRxContext->InUse            = FALSE;
+				   pRxContext->IRPPending       = FALSE;
+				   pRxContext->Readable = FALSE;
+				   pRxContext->ReorderInUse = FALSE;
+
+				   }
+				   RTUSBBulkReceive(pAd);
+				   DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTUSBBulkReceive\n"));
+				   } */
+				DBGPRINT_RAW(RT_DEBUG_TRACE,
+					     ("CmdThread : CMDTHREAD_RESET_BULK_OUT<===\n"));
+				break;
+
+			case CMDTHREAD_RESET_BULK_IN:
+				DBGPRINT_RAW(RT_DEBUG_TRACE,
+					     ("CmdThread : CMDTHREAD_RESET_BULK_IN === >\n"));
+
+				/* All transfers must be aborted or cancelled before attempting to reset the pipe. */
+				{
+					u32 MACValue;
+
 					{
-						StaQuickResponeForRateUpExec(NULL, pAd, NULL, NULL);
-					}
-					break;
-
-				case CMDTHREAD_RESET_BULK_OUT:
-					{
-						UINT32		MACValue;
-						UCHAR		Index;
-						int			ret=0;
-						PHT_TX_CONTEXT	pHTTXContext;
-//						RTMP_TX_RING *pTxRing;
-						unsigned long IrqFlags;
-
-						DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT(ResetPipeid=0x%0x)===>\n", pAd->bulkResetPipeid));
-						// All transfers must be aborted or cancelled before attempting to reset the pipe.
-						//RTUSBCancelPendingBulkOutIRP(pAd);
-						// Wait 10ms to let previous packet that are already in HW FIFO to clear. by MAXLEE 12-25-2007
-						Index = 0;
-						do
+						/*while ((atomic_read(&pAd->PendingRx) > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) */
+						if ((pAd->PendingRx > 0)
+						    &&
+						    (!RTMP_TEST_FLAG
+						     (pAd,
+						      fRTMP_ADAPTER_NIC_NOT_EXIST)))
 						{
-							RTUSBReadMACRegister(pAd, TXRXQ_PCNT, &MACValue);
-							if ((MACValue & 0xf00000/*0x800000*/) == 0)
-								break;
-							Index++;
-							RTMPusecDelay(10000);
-						}while(Index < 100);
-						MACValue = 0;
-						RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
-						// To prevent Read Register error, we 2nd check the validity.
-						if ((MACValue & 0xc00000) == 0)
-							RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
-						// To prevent Read Register error, we 3rd check the validity.
-						if ((MACValue & 0xc00000) == 0)
-							RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
-						MACValue |= 0x80000;
-						RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);
-
-						// Wait 1ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
-						RTMPusecDelay(1000);
-
-						MACValue &= (~0x80000);
-						RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);
-						DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tSet 0x2a0 bit19. Clear USB DMA TX path\n"));
-
-						// Wait 5ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
-						//RTMPusecDelay(5000);
-
-						if ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG)
-						{
-							RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
-							if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
-							{
-								RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
-							}
-							RTUSBKickBulkOut(pAd);
-
-							DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tTX MGMT RECOVER Done!\n"));
-						}
-						else
-						{
-							pHTTXContext = &(pAd->TxContext[pAd->bulkResetPipeid]);
-							//NdisAcquireSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
-							RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
-							if ( pAd->BulkOutPending[pAd->bulkResetPipeid] == FALSE)
-							{
-								pAd->BulkOutPending[pAd->bulkResetPipeid] = TRUE;
-								pHTTXContext->IRPPending = TRUE;
-								pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 1;
-
-								// no matter what, clean the flag
-								RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
-
-								//NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
-								RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
-/*-----------------------------------------------------------------------------------------------*/
-/*-----------------------------------------------------------------------------------------------*/
-								{
-								RTUSBInitHTTxDesc(pAd, pHTTXContext, pAd->bulkResetPipeid, pHTTXContext->BulkOutSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
-
-								if((ret = RTUSB_SUBMIT_URB(pHTTXContext->pUrb))!=0)
-								{
-										RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
-									pAd->BulkOutPending[pAd->bulkResetPipeid] = FALSE;
-									pHTTXContext->IRPPending = FALSE;
-										pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 0;
-										RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
-
-										DBGPRINT(RT_DEBUG_ERROR, ("CmdThread : CMDTHREAD_RESET_BULK_OUT: Submit Tx URB failed %d\n", ret));
-								}
-									else
-									{
-										RTMP_IRQ_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
-										DBGPRINT_RAW(RT_DEBUG_TRACE,("\tCMDTHREAD_RESET_BULK_OUT: TxContext[%d]:CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, pending=%d!\n",
-												pAd->bulkResetPipeid, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition,
-															pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, pAd->BulkOutPending[pAd->bulkResetPipeid]));
-										DBGPRINT_RAW(RT_DEBUG_TRACE,("\t\tBulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n",
-															pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
-										RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
-										DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tCMDTHREAD_RESET_BULK_OUT: Submit Tx DATA URB for failed BulkReq(0x%lx) Done, status=%d!\n", pAd->bulkResetReq[pAd->bulkResetPipeid], pHTTXContext->pUrb->status));
-
-									}
-								}
-							}
-							else
-							{
-								//NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
-								//RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
-
-								DBGPRINT_RAW(RT_DEBUG_ERROR, ("CmdThread : TX DATA RECOVER FAIL for BulkReq(0x%lx) because BulkOutPending[%d] is TRUE!\n", pAd->bulkResetReq[pAd->bulkResetPipeid], pAd->bulkResetPipeid));
-								if (pAd->bulkResetPipeid == 0)
-								{
-									UCHAR	pendingContext = 0;
-									PHT_TX_CONTEXT pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[pAd->bulkResetPipeid ]);
-									PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
-									PTX_CONTEXT pNULLContext = (PTX_CONTEXT)(&pAd->PsPollContext);
-									PTX_CONTEXT pPsPollContext = (PTX_CONTEXT)(&pAd->NullContext);
-
-									if (pHTTXContext->IRPPending)
-										pendingContext |= 1;
-									else if (pMLMEContext->IRPPending)
-										pendingContext |= 2;
-									else if (pNULLContext->IRPPending)
-										pendingContext |= 4;
-									else if (pPsPollContext->IRPPending)
-										pendingContext |= 8;
-									else
-										pendingContext = 0;
-
-									DBGPRINT_RAW(RT_DEBUG_ERROR, ("\tTX Occupied by %d!\n", pendingContext));
-								}
-
-							// no matter what, clean the flag
-							RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
-
-								RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
-
-								RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << pAd->bulkResetPipeid));
-							}
-
-							RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
-							//RTUSBKickBulkOut(pAd);
-						}
-
-					}
-					/*
-						// Don't cancel BULKIN.
-						while ((atomic_read(&pAd->PendingRx) > 0) &&
-								(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
-						{
-							if (atomic_read(&pAd->PendingRx) > 0)
-							{
-								DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!cancel it!\n"));
-								RTUSBCancelPendingBulkInIRP(pAd);
-							}
-							RTMPusecDelay(100000);
-						}
-
-						if ((atomic_read(&pAd->PendingRx) == 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
-						{
-							UCHAR	i;
-							RTUSBRxPacket(pAd);
-							pAd->NextRxBulkInReadIndex = 0;	// Next Rx Read index
-							pAd->NextRxBulkInIndex		= 0;	// Rx Bulk pointer
-							for (i = 0; i < (RX_RING_SIZE); i++)
-							{
-								PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
-
-								pRxContext->pAd	= pAd;
-								pRxContext->InUse		= FALSE;
-								pRxContext->IRPPending	= FALSE;
-								pRxContext->Readable	= FALSE;
-								pRxContext->ReorderInUse = FALSE;
-
-							}
-							RTUSBBulkReceive(pAd);
-							DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTUSBBulkReceive\n"));
-						}*/
-					DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT<===\n"));
-    	   			break;
-
-				case CMDTHREAD_RESET_BULK_IN:
-					DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN === >\n"));
-
-					// All transfers must be aborted or cancelled before attempting to reset the pipe.
-					{
-						UINT32		MACValue;
-/*-----------------------------------------------------------------------------------------------*/
-/*-----------------------------------------------------------------------------------------------*/
-						{
-						//while ((atomic_read(&pAd->PendingRx) > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
-						if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
-						{
-							DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!!\n"));
-							RTUSBCancelPendingBulkInIRP(pAd);
+							DBGPRINT_RAW
+							    (RT_DEBUG_ERROR,
+							     ("BulkIn IRP Pending!!!\n"));
+							RTUSBCancelPendingBulkInIRP
+							    (pAd);
 							RTMPusecDelay(100000);
 							pAd->PendingRx = 0;
 						}
+					}
+
+					/* Wait 10ms before reading register. */
+					RTMPusecDelay(10000);
+					ntStatus =
+					    RTUSBReadMACRegister(pAd, MAC_CSR0,
+								 &MACValue);
+
+					if ((NT_SUCCESS(ntStatus) == TRUE) &&
+					    (!(RTMP_TEST_FLAG
+					       (pAd,
+						(fRTMP_ADAPTER_RESET_IN_PROGRESS
+						 | fRTMP_ADAPTER_RADIO_OFF |
+						 fRTMP_ADAPTER_HALT_IN_PROGRESS
+						 |
+						 fRTMP_ADAPTER_NIC_NOT_EXIST)))))
+					{
+						u8 i;
+
+						if (RTMP_TEST_FLAG
+						    (pAd,
+						     (fRTMP_ADAPTER_RESET_IN_PROGRESS
+						      | fRTMP_ADAPTER_RADIO_OFF
+						      |
+						      fRTMP_ADAPTER_HALT_IN_PROGRESS
+						      |
+						      fRTMP_ADAPTER_NIC_NOT_EXIST)))
+							break;
+						pAd->NextRxBulkInPosition =
+						    pAd->RxContext[pAd->
+								   NextRxBulkInIndex].
+						    BulkInOffset;
+						DBGPRINT(RT_DEBUG_TRACE,
+							 ("BULK_IN_RESET: NBIIdx=0x%x,NBIRIdx=0x%x, BIRPos=0x%lx. BIReq=x%lx, BIComplete=0x%lx, BICFail0x%lx\n",
+							  pAd->
+							  NextRxBulkInIndex,
+							  pAd->
+							  NextRxBulkInReadIndex,
+							  pAd->
+							  NextRxBulkInPosition,
+							  pAd->BulkInReq,
+							  pAd->BulkInComplete,
+							  pAd->
+							  BulkInCompleteFail));
+						for (i = 0; i < RX_RING_SIZE;
+						     i++) {
+							DBGPRINT(RT_DEBUG_TRACE,
+								 ("\tRxContext[%d]: IRPPending=%d, InUse=%d, Readable=%d!\n",
+								  i,
+								  pAd->
+								  RxContext[i].
+								  IRPPending,
+								  pAd->
+								  RxContext[i].
+								  InUse,
+								  pAd->
+								  RxContext[i].
+								  Readable));
 						}
+						/*
 
-						// Wait 10ms before reading register.
-						RTMPusecDelay(10000);
-						ntStatus = RTUSBReadMACRegister(pAd, MAC_CSR0, &MACValue);
+						   DBGPRINT_RAW(RT_DEBUG_ERROR, ("==========================================\n"));
 
-						if ((NT_SUCCESS(ntStatus) == TRUE) &&
-							(!(RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF |
-													fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))))
-						{
-							UCHAR	i;
+						   pAd->NextRxBulkInReadIndex = 0;      // Next Rx Read index
+						   pAd->NextRxBulkInIndex               = 0;    // Rx Bulk pointer
+						   for (i = 0; i < (RX_RING_SIZE); i++)
+						   {
+						   struct rt_rx_context *pRxContext = &(pAd->RxContext[i]);
 
-							if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF |
-														fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))
+						   pRxContext->pAd      = pAd;
+						   pRxContext->InUse            = FALSE;
+						   pRxContext->IRPPending       = FALSE;
+						   pRxContext->Readable = FALSE;
+						   pRxContext->ReorderInUse = FALSE;
+
+						   } */
+						RTMP_CLEAR_FLAG(pAd,
+								fRTMP_ADAPTER_BULKIN_RESET);
+						for (i = 0;
+						     i <
+						     pAd->CommonCfg.
+						     NumOfBulkInIRP; i++) {
+							/*RTUSBBulkReceive(pAd); */
+							struct rt_rx_context *pRxContext;
+							PURB pUrb;
+							int ret = 0;
+							unsigned long IrqFlags;
+
+							RTMP_IRQ_LOCK(&pAd->
+								      BulkInLock,
+								      IrqFlags);
+							pRxContext =
+							    &(pAd->
+							      RxContext[pAd->
+									NextRxBulkInIndex]);
+							if ((pAd->PendingRx > 0)
+							    || (pRxContext->
+								Readable ==
+								TRUE)
+							    || (pRxContext->
+								InUse ==
+								TRUE)) {
+								RTMP_IRQ_UNLOCK
+								    (&pAd->
+								     BulkInLock,
+								     IrqFlags);
 								break;
-							pAd->NextRxBulkInPosition = pAd->RxContext[pAd->NextRxBulkInIndex].BulkInOffset;
-							DBGPRINT(RT_DEBUG_TRACE, ("BULK_IN_RESET: NBIIdx=0x%x,NBIRIdx=0x%x, BIRPos=0x%lx. BIReq=x%lx, BIComplete=0x%lx, BICFail0x%lx\n",
-									pAd->NextRxBulkInIndex,  pAd->NextRxBulkInReadIndex, pAd->NextRxBulkInPosition, pAd->BulkInReq, pAd->BulkInComplete, pAd->BulkInCompleteFail));
-							for (i = 0; i < RX_RING_SIZE; i++)
-							{
- 								DBGPRINT(RT_DEBUG_TRACE, ("\tRxContext[%d]: IRPPending=%d, InUse=%d, Readable=%d!\n"
-									, i, pAd->RxContext[i].IRPPending, pAd->RxContext[i].InUse, pAd->RxContext[i].Readable));
 							}
- 							/*
+							pRxContext->InUse =
+							    TRUE;
+							pRxContext->IRPPending =
+							    TRUE;
+							pAd->PendingRx++;
+							pAd->BulkInReq++;
+							RTMP_IRQ_UNLOCK(&pAd->
+									BulkInLock,
+									IrqFlags);
 
-							DBGPRINT_RAW(RT_DEBUG_ERROR, ("==========================================\n"));
+							/* Init Rx context descriptor */
+							RTUSBInitRxDesc(pAd,
+									pRxContext);
+							pUrb = pRxContext->pUrb;
+							if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) {	/* fail */
 
-							pAd->NextRxBulkInReadIndex = 0;	// Next Rx Read index
-							pAd->NextRxBulkInIndex		= 0;	// Rx Bulk pointer
-							for (i = 0; i < (RX_RING_SIZE); i++)
-							{
-								PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
-
-								pRxContext->pAd	= pAd;
-								pRxContext->InUse		= FALSE;
-								pRxContext->IRPPending	= FALSE;
-								pRxContext->Readable	= FALSE;
-								pRxContext->ReorderInUse = FALSE;
-
-							}*/
-							RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
-							for (i = 0; i < pAd->CommonCfg.NumOfBulkInIRP; i++)
-							{
-								//RTUSBBulkReceive(pAd);
-								PRX_CONTEXT		pRxContext;
-								PURB			pUrb;
-								int				ret = 0;
-								unsigned long	IrqFlags;
-
-
-								RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
-								pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
-								if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
-								{
-									RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
-									break;
-								}
-								pRxContext->InUse = TRUE;
-								pRxContext->IRPPending = TRUE;
-								pAd->PendingRx++;
-								pAd->BulkInReq++;
-								RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
-
-								// Init Rx context descriptor
-								RTUSBInitRxDesc(pAd, pRxContext);
-								pUrb = pRxContext->pUrb;
-								if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
-								{	// fail
-
-									RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
-									pRxContext->InUse = FALSE;
-									pRxContext->IRPPending = FALSE;
-									pAd->PendingRx--;
-									pAd->BulkInReq--;
-									RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
-									DBGPRINT(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB failed(%d), status=%d\n", ret, pUrb->status));
-								}
-								else
-								{	// success
-									DBGPRINT_RAW(RT_DEBUG_TRACE, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB Done, status=%d!\n", pUrb->status));
-									ASSERT((pRxContext->InUse == pRxContext->IRPPending));
-								}
+								RTMP_IRQ_LOCK
+								    (&pAd->
+								     BulkInLock,
+								     IrqFlags);
+								pRxContext->
+								    InUse =
+								    FALSE;
+								pRxContext->
+								    IRPPending =
+								    FALSE;
+								pAd->
+								    PendingRx--;
+								pAd->
+								    BulkInReq--;
+								RTMP_IRQ_UNLOCK
+								    (&pAd->
+								     BulkInLock,
+								     IrqFlags);
+								DBGPRINT
+								    (RT_DEBUG_ERROR,
+								     ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB failed(%d), status=%d\n",
+								      ret,
+								      pUrb->
+								      status));
+							} else {	/* success */
+								/*DBGPRINT(RT_DEBUG_TRACE, ("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", */
+								/*                                                      pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex)); */
+								DBGPRINT_RAW
+								    (RT_DEBUG_TRACE,
+								     ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB Done, status=%d!\n",
+								      pUrb->
+								      status));
+								ASSERT((pRxContext->InUse == pRxContext->IRPPending));
 							}
-
 						}
-						else
-						{
-							// Card must be removed
-							if (NT_SUCCESS(ntStatus) != TRUE)
-							{
-							RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
-								DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Read Register Failed!Card must be removed!!\n\n"));
-							}
-							else
-							{
-								DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Cannot do bulk in because flags(0x%lx) on !\n", pAd->Flags));
+
+					} else {
+						/* Card must be removed */
+						if (NT_SUCCESS(ntStatus) !=
+						    TRUE) {
+							RTMP_SET_FLAG(pAd,
+								      fRTMP_ADAPTER_NIC_NOT_EXIST);
+							DBGPRINT_RAW
+							    (RT_DEBUG_ERROR,
+							     ("CMDTHREAD_RESET_BULK_IN: Read Register Failed!Card must be removed!!\n\n"));
+						} else {
+							DBGPRINT_RAW
+							    (RT_DEBUG_ERROR,
+							     ("CMDTHREAD_RESET_BULK_IN: Cannot do bulk in because flags(0x%lx) on !\n",
+							      pAd->Flags));
 						}
 					}
-					}
-					DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN <===\n"));
-					break;
+				}
+				DBGPRINT_RAW(RT_DEBUG_TRACE,
+					     ("CmdThread : CMDTHREAD_RESET_BULK_IN <===\n"));
+				break;
 
-				case CMDTHREAD_SET_ASIC_WCID:
+			case CMDTHREAD_SET_ASIC_WCID:
+				{
+					struct rt_set_asic_wcid SetAsicWcid;
+					u16 offset;
+					u32 MACValue, MACRValue = 0;
+					SetAsicWcid =
+					    *((struct rt_set_asic_wcid *)(pData));
+
+					if (SetAsicWcid.WCID >=
+					    MAX_LEN_OF_MAC_TABLE)
+						return;
+
+					offset =
+					    MAC_WCID_BASE +
+					    ((u8)SetAsicWcid.WCID) *
+					    HW_WCID_ENTRY_SIZE;
+
+					DBGPRINT_RAW(RT_DEBUG_TRACE,
+						     ("CmdThread : CMDTHREAD_SET_ASIC_WCID : WCID = %ld, SetTid  = %lx, DeleteTid = %lx.\n",
+						      SetAsicWcid.WCID,
+						      SetAsicWcid.SetTid,
+						      SetAsicWcid.DeleteTid));
+					MACValue =
+					    (pAd->MacTab.
+					     Content[SetAsicWcid.WCID].
+					     Addr[3] << 24) +
+					    (pAd->MacTab.
+					     Content[SetAsicWcid.WCID].
+					     Addr[2] << 16) +
+					    (pAd->MacTab.
+					     Content[SetAsicWcid.WCID].
+					     Addr[1] << 8) +
+					    (pAd->MacTab.
+					     Content[SetAsicWcid.WCID].Addr[0]);
+					DBGPRINT_RAW(RT_DEBUG_TRACE,
+						     ("1-MACValue= %x,\n",
+						      MACValue));
+					RTUSBWriteMACRegister(pAd, offset,
+							      MACValue);
+					/* Read bitmask */
+					RTUSBReadMACRegister(pAd, offset + 4,
+							     &MACRValue);
+					if (SetAsicWcid.DeleteTid != 0xffffffff)
+						MACRValue &=
+						    (~SetAsicWcid.DeleteTid);
+					if (SetAsicWcid.SetTid != 0xffffffff)
+						MACRValue |=
+						    (SetAsicWcid.SetTid);
+					MACRValue &= 0xffff0000;
+
+					MACValue =
+					    (pAd->MacTab.
+					     Content[SetAsicWcid.WCID].
+					     Addr[5] << 8) +
+					    pAd->MacTab.Content[SetAsicWcid.
+								WCID].Addr[4];
+					MACValue |= MACRValue;
+					RTUSBWriteMACRegister(pAd, offset + 4,
+							      MACValue);
+
+					DBGPRINT_RAW(RT_DEBUG_TRACE,
+						     ("2-MACValue= %x,\n",
+						      MACValue));
+				}
+				break;
+
+			case CMDTHREAD_SET_ASIC_WCID_CIPHER:
+				{
+					struct rt_set_asic_wcid_attri SetAsicWcidAttri;
+					u16 offset;
+					u32 MACRValue = 0;
+					SHAREDKEY_MODE_STRUC csr1;
+					SetAsicWcidAttri =
+					    *((struct rt_set_asic_wcid_attri *)
+					      (pData));
+
+					if (SetAsicWcidAttri.WCID >=
+					    MAX_LEN_OF_MAC_TABLE)
+						return;
+
+					offset =
+					    MAC_WCID_ATTRIBUTE_BASE +
+					    ((u8)SetAsicWcidAttri.WCID) *
+					    HW_WCID_ATTRI_SIZE;
+
+					DBGPRINT_RAW(RT_DEBUG_TRACE,
+						     ("Cmd : CMDTHREAD_SET_ASIC_WCID_CIPHER : WCID = %ld, Cipher = %lx.\n",
+						      SetAsicWcidAttri.WCID,
+						      SetAsicWcidAttri.Cipher));
+					/* Read bitmask */
+					RTUSBReadMACRegister(pAd, offset,
+							     &MACRValue);
+					MACRValue = 0;
+					MACRValue |=
+					    (((u8)SetAsicWcidAttri.
+					      Cipher) << 1);
+
+					RTUSBWriteMACRegister(pAd, offset,
+							      MACRValue);
+					DBGPRINT_RAW(RT_DEBUG_TRACE,
+						     ("2-offset = %x , MACValue= %x,\n",
+						      offset, MACRValue));
+
+					offset =
+					    PAIRWISE_IVEIV_TABLE_BASE +
+					    ((u8)SetAsicWcidAttri.WCID) *
+					    HW_IVEIV_ENTRY_SIZE;
+					MACRValue = 0;
+					if ((SetAsicWcidAttri.Cipher <=
+					     CIPHER_WEP128))
+						MACRValue |=
+						    (pAd->StaCfg.
+						     DefaultKeyId << 30);
+					else
+						MACRValue |= (0x20000000);
+					RTUSBWriteMACRegister(pAd, offset,
+							      MACRValue);
+					DBGPRINT_RAW(RT_DEBUG_TRACE,
+						     ("2-offset = %x , MACValue= %x,\n",
+						      offset, MACRValue));
+
+					/* */
+					/* Update cipher algorithm. WSTA always use BSS0 */
+					/* */
+					/* for adhoc mode only ,because wep status slow than add key, when use zero config */
+					if (pAd->StaCfg.BssType == BSS_ADHOC) {
+						offset =
+						    MAC_WCID_ATTRIBUTE_BASE;
+
+						RTUSBReadMACRegister(pAd,
+								     offset,
+								     &MACRValue);
+						MACRValue &= (~0xe);
+						MACRValue |=
+						    (((u8)SetAsicWcidAttri.
+						      Cipher) << 1);
+
+						RTUSBWriteMACRegister(pAd,
+								      offset,
+								      MACRValue);
+
+						/*Update group key cipher,,because wep status slow than add key, when use zero config */
+						RTUSBReadMACRegister(pAd,
+								     SHARED_KEY_MODE_BASE
+								     +
+								     4 * (0 /
+									  2),
+								     &csr1.
+								     word);
+
+						csr1.field.Bss0Key0CipherAlg =
+						    SetAsicWcidAttri.Cipher;
+						csr1.field.Bss0Key1CipherAlg =
+						    SetAsicWcidAttri.Cipher;
+
+						RTUSBWriteMACRegister(pAd,
+								      SHARED_KEY_MODE_BASE
+								      +
+								      4 * (0 /
+									   2),
+								      csr1.
+								      word);
+					}
+				}
+				break;
+
+/*Benson modified for USB interface, avoid in interrupt when write key, 20080724 --> */
+			case RT_CMD_SET_KEY_TABLE:	/*General call for AsicAddPairwiseKeyEntry() */
+				{
+					struct rt_add_pairwise_key_entry KeyInfo;
+					KeyInfo =
+					    *((struct rt_add_pairwise_key_entry *)
+					      (pData));
+					AsicAddPairwiseKeyEntry(pAd,
+								KeyInfo.MacAddr,
+								(u8)KeyInfo.
+								MacTabMatchWCID,
+								&KeyInfo.
+								CipherKey);
+				}
+				break;
+
+			case RT_CMD_SET_RX_WCID_TABLE:	/*General call for RTMPAddWcidAttributeEntry() */
+				{
+					struct rt_mac_table_entry *pEntry;
+					u8 KeyIdx = 0;
+					u8 CipherAlg = CIPHER_NONE;
+					u8 ApIdx = BSS0;
+
+					pEntry = (struct rt_mac_table_entry *)(pData);
+
+					RTMPAddWcidAttributeEntry(pAd,
+								  ApIdx,
+								  KeyIdx,
+								  CipherAlg,
+								  pEntry);
+				}
+				break;
+/*Benson modified for USB interface, avoid in interrupt when write key, 20080724 <-- */
+
+			case CMDTHREAD_SET_CLIENT_MAC_ENTRY:
+				{
+					struct rt_mac_table_entry *pEntry;
+					pEntry = (struct rt_mac_table_entry *)pData;
+
 					{
-						RT_SET_ASIC_WCID	SetAsicWcid;
-						USHORT		offset;
-						UINT32		MACValue, MACRValue = 0;
-						SetAsicWcid = *((PRT_SET_ASIC_WCID)(pData));
-
-						if (SetAsicWcid.WCID >= MAX_LEN_OF_MAC_TABLE)
-							return;
-
-						offset = MAC_WCID_BASE + ((UCHAR)SetAsicWcid.WCID)*HW_WCID_ENTRY_SIZE;
-
-						DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_SET_ASIC_WCID : WCID = %ld, SetTid  = %lx, DeleteTid = %lx.\n", SetAsicWcid.WCID, SetAsicWcid.SetTid, SetAsicWcid.DeleteTid));
-						MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[3]<<24)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[2]<<16)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[1]<<8)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[0]);
-						DBGPRINT_RAW(RT_DEBUG_TRACE, ("1-MACValue= %x,\n", MACValue));
-						RTUSBWriteMACRegister(pAd, offset, MACValue);
-						// Read bitmask
-						RTUSBReadMACRegister(pAd, offset+4, &MACRValue);
-						if ( SetAsicWcid.DeleteTid != 0xffffffff)
-							MACRValue &= (~SetAsicWcid.DeleteTid);
-						if (SetAsicWcid.SetTid != 0xffffffff)
-							MACRValue |= (SetAsicWcid.SetTid);
-						MACRValue &= 0xffff0000;
-
-						MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[5]<<8)+pAd->MacTab.Content[SetAsicWcid.WCID].Addr[4];
-						MACValue |= MACRValue;
-						RTUSBWriteMACRegister(pAd, offset+4, MACValue);
-
-						DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-MACValue= %x,\n", MACValue));
-					}
-					break;
-
-				case CMDTHREAD_SET_ASIC_WCID_CIPHER:
-					{
-						RT_SET_ASIC_WCID_ATTRI	SetAsicWcidAttri;
-						USHORT		offset;
-						UINT32		MACRValue = 0;
-						SHAREDKEY_MODE_STRUC csr1;
-						SetAsicWcidAttri = *((PRT_SET_ASIC_WCID_ATTRI)(pData));
-
-						if (SetAsicWcidAttri.WCID >= MAX_LEN_OF_MAC_TABLE)
-							return;
-
-						offset = MAC_WCID_ATTRIBUTE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_WCID_ATTRI_SIZE;
-
-						DBGPRINT_RAW(RT_DEBUG_TRACE, ("Cmd : CMDTHREAD_SET_ASIC_WCID_CIPHER : WCID = %ld, Cipher = %lx.\n", SetAsicWcidAttri.WCID, SetAsicWcidAttri.Cipher));
-						// Read bitmask
-						RTUSBReadMACRegister(pAd, offset, &MACRValue);
-						MACRValue = 0;
-						MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1);
-
-						RTUSBWriteMACRegister(pAd, offset, MACRValue);
-						DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue));
-
-						offset = PAIRWISE_IVEIV_TABLE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_IVEIV_ENTRY_SIZE;
-						MACRValue = 0;
-						if ( (SetAsicWcidAttri.Cipher <= CIPHER_WEP128))
-							MACRValue |= ( pAd->StaCfg.DefaultKeyId << 30);
-						else
-							MACRValue |= (0x20000000);
-						RTUSBWriteMACRegister(pAd, offset, MACRValue);
-						DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue));
-
-						//
-						// Update cipher algorithm. WSTA always use BSS0
-						//
-						// for adhoc mode only ,because wep status slow than add key, when use zero config
-						if (pAd->StaCfg.BssType == BSS_ADHOC )
+						AsicRemovePairwiseKeyEntry(pAd,
+									   pEntry->
+									   apidx,
+									   (u8)
+									   pEntry->
+									   Aid);
+						if ((pEntry->AuthMode <=
+						     Ndis802_11AuthModeAutoSwitch)
+						    && (pEntry->WepStatus ==
+							Ndis802_11Encryption1Enabled))
 						{
-							offset = MAC_WCID_ATTRIBUTE_BASE;
+							u32 uIV = 1;
+							u8 *ptr;
 
-							RTUSBReadMACRegister(pAd, offset, &MACRValue);
-							MACRValue &= (~0xe);
-							MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1);
+							ptr = (u8 *)& uIV;
+							*(ptr + 3) =
+							    (pAd->StaCfg.
+							     DefaultKeyId << 6);
+							AsicUpdateWCIDIVEIV(pAd,
+									    pEntry->
+									    Aid,
+									    uIV,
+									    0);
+							AsicUpdateWCIDAttribute
+							    (pAd, pEntry->Aid,
+							     BSS0,
+							     pAd->
+							     SharedKey[BSS0]
+							     [pAd->StaCfg.
+							      DefaultKeyId].
+							     CipherAlg, FALSE);
+						} else if (pEntry->AuthMode ==
+							   Ndis802_11AuthModeWPANone)
+						{
+							u32 uIV = 1;
+							u8 *ptr;
 
-							RTUSBWriteMACRegister(pAd, offset, MACRValue);
-
-							//Update group key cipher,,because wep status slow than add key, when use zero config
-							RTUSBReadMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), &csr1.word);
-
-							csr1.field.Bss0Key0CipherAlg = SetAsicWcidAttri.Cipher;
-							csr1.field.Bss0Key1CipherAlg = SetAsicWcidAttri.Cipher;
-
-							RTUSBWriteMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), csr1.word);
+							ptr = (u8 *)& uIV;
+							*(ptr + 3) =
+							    (pAd->StaCfg.
+							     DefaultKeyId << 6);
+							AsicUpdateWCIDIVEIV(pAd,
+									    pEntry->
+									    Aid,
+									    uIV,
+									    0);
+							AsicUpdateWCIDAttribute
+							    (pAd, pEntry->Aid,
+							     BSS0,
+							     pAd->
+							     SharedKey[BSS0]
+							     [pAd->StaCfg.
+							      DefaultKeyId].
+							     CipherAlg, FALSE);
+						} else {
+							/* */
+							/* Other case, disable engine. */
+							/* Don't worry WPA key, we will add WPA Key after 4-Way handshaking. */
+							/* */
+							u16 offset;
+							offset =
+							    MAC_WCID_ATTRIBUTE_BASE
+							    +
+							    (pEntry->Aid *
+							     HW_WCID_ATTRI_SIZE);
+							/* RX_PKEY_MODE:0 for no security; RX_KEY_TAB:0 for shared key table; BSS_IDX:0 */
+							RTUSBWriteMACRegister
+							    (pAd, offset, 0);
 						}
 					}
-					break;
-				case CMDTHREAD_SET_CLIENT_MAC_ENTRY:
-					{
-						MAC_TABLE_ENTRY *pEntry;
-						pEntry = (MAC_TABLE_ENTRY *)pData;
 
-						{
-							AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)pEntry->Aid);
-							if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) && (pEntry->WepStatus == Ndis802_11Encryption1Enabled))
-							{
-								UINT32 uIV = 0;
-								PUCHAR  ptr;
+					AsicUpdateRxWCIDTable(pAd, pEntry->Aid,
+							      pEntry->Addr);
+					DBGPRINT(RT_DEBUG_TRACE,
+						 ("UpdateRxWCIDTable(): Aid=%d, Addr=%02x:%02x:%02x:%02x:%02x:%02x!\n",
+						  pEntry->Aid, pEntry->Addr[0],
+						  pEntry->Addr[1],
+						  pEntry->Addr[2],
+						  pEntry->Addr[3],
+						  pEntry->Addr[4],
+						  pEntry->Addr[5]));
+				}
+				break;
 
-								ptr = (PUCHAR) &uIV;
-								*(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6);
-								AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0);
-								AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE);
-							}
-							else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone)
-							{
-								UINT32 uIV = 0;
-								PUCHAR  ptr;
+/* add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet */
+			case CMDTHREAD_UPDATE_PROTECT:
+				{
+					AsicUpdateProtect(pAd, 0,
+							  (ALLN_SETPROTECT),
+							  TRUE, 0);
+				}
+				break;
+/* end johnli */
 
-								ptr = (PUCHAR) &uIV;
-								*(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6);
-								AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0);
-								AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE);
-							}
-							else
-							{
-								//
-								// Other case, disable engine.
-								// Don't worry WPA key, we will add WPA Key after 4-Way handshaking.
-								//
-								USHORT   offset;
-								offset = MAC_WCID_ATTRIBUTE_BASE + (pEntry->Aid * HW_WCID_ATTRI_SIZE);
-								// RX_PKEY_MODE:0 for no security; RX_KEY_TAB:0 for shared key table; BSS_IDX:0
-								RTUSBWriteMACRegister(pAd, offset, 0);
-							}
+			case OID_802_11_ADD_WEP:
+				{
+					u32 i;
+					u32 KeyIdx;
+					struct rt_ndis_802_11_wep *pWepKey;
+
+					DBGPRINT(RT_DEBUG_TRACE,
+						 ("CmdThread::OID_802_11_ADD_WEP  \n"));
+
+					pWepKey = (struct rt_ndis_802_11_wep *)pData;
+					KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
+
+					/* it is a shared key */
+					if ((KeyIdx >= 4)
+					    || ((pWepKey->KeyLength != 5)
+						&& (pWepKey->KeyLength !=
+						    13))) {
+						NdisStatus =
+						    NDIS_STATUS_INVALID_DATA;
+						DBGPRINT(RT_DEBUG_ERROR,
+							 ("CmdThread::OID_802_11_ADD_WEP, INVALID_DATA!!\n"));
+					} else {
+						u8 CipherAlg;
+						pAd->SharedKey[BSS0][KeyIdx].
+						    KeyLen =
+						    (u8)pWepKey->KeyLength;
+						NdisMoveMemory(pAd->
+							       SharedKey[BSS0]
+							       [KeyIdx].Key,
+							       &pWepKey->
+							       KeyMaterial,
+							       pWepKey->
+							       KeyLength);
+						CipherAlg =
+						    (pAd->
+						     SharedKey[BSS0][KeyIdx].
+						     KeyLen ==
+						     5) ? CIPHER_WEP64 :
+						    CIPHER_WEP128;
+
+						/* */
+						/* Change the WEP cipher to CKIP cipher if CKIP KP on. */
+						/* Funk UI or Meetinghouse UI will add ckip key from this path. */
+						/* */
+
+						if (pAd->OpMode == OPMODE_STA) {
+							pAd->MacTab.
+							    Content[BSSID_WCID].
+							    PairwiseKey.
+							    CipherAlg =
+							    pAd->
+							    SharedKey[BSS0]
+							    [KeyIdx].CipherAlg;
+							pAd->MacTab.
+							    Content[BSSID_WCID].
+							    PairwiseKey.KeyLen =
+							    pAd->
+							    SharedKey[BSS0]
+							    [KeyIdx].KeyLen;
 						}
+						pAd->SharedKey[BSS0][KeyIdx].
+						    CipherAlg = CipherAlg;
+						if (pWepKey->
+						    KeyIndex & 0x80000000) {
+							/* Default key for tx (shared key) */
+							u8 IVEIV[8];
+							u32 WCIDAttri, Value;
+							u16 offset, offset2;
+							NdisZeroMemory(IVEIV,
+								       8);
+							pAd->StaCfg.
+							    DefaultKeyId =
+							    (u8)KeyIdx;
+							/* Add BSSID to WCTable. because this is Tx wep key. */
+							/* WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0 */
+							WCIDAttri =
+							    (CipherAlg << 1) |
+							    SHAREDKEYTABLE;
 
-						AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr);
-						printk("UpdateRxWCIDTable(): Aid=%d, Addr=%02x:%02x:%02x:%02x:%02x:%02x!\n", pEntry->Aid,
-								pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
-					}
-					break;
-				case CMDTHREAD_UPDATE_PROTECT:
-					{
-						AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0);
-					}
-					break;
-				case OID_802_11_ADD_WEP:
-					{
-						UINT	i;
-						UINT32	KeyIdx;
-						PNDIS_802_11_WEP	pWepKey;
-
-						DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP  \n"));
-
-						pWepKey = (PNDIS_802_11_WEP)pData;
-						KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
-
-						// it is a shared key
-						if ((KeyIdx >= 4) || ((pWepKey->KeyLength != 5) && (pWepKey->KeyLength != 13)))
-						{
-							NdisStatus = NDIS_STATUS_INVALID_DATA;
-							DBGPRINT(RT_DEBUG_ERROR, ("CmdThread::OID_802_11_ADD_WEP, INVALID_DATA!!\n"));
-						}
-						else
-						{
-							UCHAR CipherAlg;
-							pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
-							NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
-							CipherAlg = (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 5)? CIPHER_WEP64 : CIPHER_WEP128;
-
-							//
-							// Change the WEP cipher to CKIP cipher if CKIP KP on.
-							// Funk UI or Meetinghouse UI will add ckip key from this path.
-							//
-
-							if (pAd->OpMode == OPMODE_STA)
-						 	{
-								pAd->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
-								pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen = pAd->SharedKey[BSS0][KeyIdx].KeyLen;
-						 	}
-							pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
-							if (pWepKey->KeyIndex & 0x80000000)
-							{
-								// Default key for tx (shared key)
-								UCHAR	IVEIV[8];
-								UINT32	WCIDAttri, Value;
-								USHORT	offset, offset2;
-								NdisZeroMemory(IVEIV, 8);
-								pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
-								// Add BSSID to WCTable. because this is Tx wep key.
-								// WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0
-								WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
-
-								offset = MAC_WCID_ATTRIBUTE_BASE + (BSSID_WCID* HW_WCID_ATTRI_SIZE);
-								RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
-								// 1. IV/EIV
-								// Specify key index to find shared key.
-								IVEIV[3] = (UCHAR)(KeyIdx<< 6);	//WEP Eiv bit off. groupkey index is not 0
-								offset = PAIRWISE_IVEIV_TABLE_BASE + (BSS0Mcast_WCID * HW_IVEIV_ENTRY_SIZE);
-								offset2 = PAIRWISE_IVEIV_TABLE_BASE + (BSSID_WCID* HW_IVEIV_ENTRY_SIZE);
-								for (i=0; i<8;)
-								{
-									Value = IVEIV[i];
-									Value += (IVEIV[i+1]<<8);
-									Value += (IVEIV[i+2]<<16);
-									Value += (IVEIV[i+3]<<24);
-									RTUSBWriteMACRegister(pAd, offset+i, Value);
-									RTUSBWriteMACRegister(pAd, offset2+i, Value);
-									i+=4;
-								}
-
-								// 2. WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:use share key, BSSIdx is 0
-								WCIDAttri = (pAd->SharedKey[BSS0][KeyIdx].CipherAlg<<1)|SHAREDKEYTABLE;
-								offset = MAC_WCID_ATTRIBUTE_BASE + (BSS0Mcast_WCID* HW_WCID_ATTRI_SIZE);
-							        DBGPRINT(RT_DEBUG_TRACE, ("BSS0Mcast_WCID : offset = %x, WCIDAttri = %x\n", offset, WCIDAttri));
-								RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
-
+							offset =
+							    MAC_WCID_ATTRIBUTE_BASE
+							    +
+							    (BSSID_WCID *
+							     HW_WCID_ATTRI_SIZE);
+							RTUSBWriteMACRegister
+							    (pAd, offset,
+							     WCIDAttri);
+							/* 1. IV/EIV */
+							/* Specify key index to find shared key. */
+							IVEIV[3] = (u8)(KeyIdx << 6);	/*WEP Eiv bit off. groupkey index is not 0 */
+							offset =
+							    PAIRWISE_IVEIV_TABLE_BASE
+							    +
+							    (BSS0Mcast_WCID *
+							     HW_IVEIV_ENTRY_SIZE);
+							offset2 =
+							    PAIRWISE_IVEIV_TABLE_BASE
+							    +
+							    (BSSID_WCID *
+							     HW_IVEIV_ENTRY_SIZE);
+							for (i = 0; i < 8;) {
+								Value =
+								    IVEIV[i];
+								Value +=
+								    (IVEIV
+								     [i +
+								      1] << 8);
+								Value +=
+								    (IVEIV
+								     [i +
+								      2] << 16);
+								Value +=
+								    (IVEIV
+								     [i +
+								      3] << 24);
+								RTUSBWriteMACRegister
+								    (pAd,
+								     offset + i,
+								     Value);
+								RTUSBWriteMACRegister
+								    (pAd,
+								     offset2 +
+								     i, Value);
+								i += 4;
 							}
-							AsicAddSharedKeyEntry(pAd, BSS0, (UCHAR)KeyIdx, CipherAlg, pWepKey->KeyMaterial, NULL, NULL);
-							DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP (KeyIdx=%d, Len=%d-byte)\n", KeyIdx, pWepKey->KeyLength));
-						}
-					}
-					break;
 
-				case CMDTHREAD_802_11_COUNTER_MEASURE:
-					break;
-				default:
-					DBGPRINT(RT_DEBUG_ERROR, ("--> Control Thread !! ERROR !! Unknown(cmdqelmt->command=0x%x) !! \n", cmdqelmt->command));
-					break;
+							/* 2. WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:use share key, BSSIdx is 0 */
+							WCIDAttri =
+							    (pAd->
+							     SharedKey[BSS0]
+							     [KeyIdx].
+							     CipherAlg << 1) |
+							    SHAREDKEYTABLE;
+							offset =
+							    MAC_WCID_ATTRIBUTE_BASE
+							    +
+							    (BSS0Mcast_WCID *
+							     HW_WCID_ATTRI_SIZE);
+							DBGPRINT(RT_DEBUG_TRACE,
+								 ("BSS0Mcast_WCID : offset = %x, WCIDAttri = %x\n",
+								  offset,
+								  WCIDAttri));
+							RTUSBWriteMACRegister
+							    (pAd, offset,
+							     WCIDAttri);
+
+						}
+						AsicAddSharedKeyEntry(pAd, BSS0,
+								      (u8)
+								      KeyIdx,
+								      CipherAlg,
+								      pWepKey->
+								      KeyMaterial,
+								      NULL,
+								      NULL);
+						DBGPRINT(RT_DEBUG_TRACE,
+							 ("CmdThread::OID_802_11_ADD_WEP (KeyIdx=%d, Len=%d-byte)\n",
+							  KeyIdx,
+							  pWepKey->KeyLength));
+					}
+				}
+				break;
+
+			case CMDTHREAD_802_11_COUNTER_MEASURE:
+				break;
+
+			case CMDTHREAD_SET_GROUP_KEY:
+				WpaStaGroupKeySetting(pAd);
+				break;
+
+			case CMDTHREAD_SET_PAIRWISE_KEY:
+				WpaStaPairwiseKeySetting(pAd);
+				break;
+
+			case CMDTHREAD_SET_PSM_BIT:
+				{
+					u16 *pPsm = (u16 *) pData;
+					MlmeSetPsmBit(pAd, *pPsm);
+				}
+				break;
+			case CMDTHREAD_FORCE_WAKE_UP:
+				AsicForceWakeup(pAd, TRUE);
+				break;
+
+			default:
+				DBGPRINT(RT_DEBUG_ERROR,
+					 ("--> Control Thread !! ERROR !! Unknown(cmdqelmt->command=0x%x) !! \n",
+					  cmdqelmt->command));
+				break;
 			}
 		}
 
-		if (cmdqelmt->CmdFromNdis == TRUE)
-		{
-				if (cmdqelmt->buffer != NULL)
-					NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
-
-			NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
+		if (cmdqelmt->CmdFromNdis == TRUE) {
+			if (cmdqelmt->buffer != NULL)
+				os_free_mem(pAd, cmdqelmt->buffer);
+			os_free_mem(pAd, cmdqelmt);
+		} else {
+			if ((cmdqelmt->buffer != NULL)
+			    && (cmdqelmt->bufferlength != 0))
+				os_free_mem(pAd, cmdqelmt->buffer);
+			os_free_mem(pAd, cmdqelmt);
 		}
-		else
-		{
-			if ((cmdqelmt->buffer != NULL) && (cmdqelmt->bufferlength != 0))
-				NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
-            {
-				NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
-			}
-		}
-	}	/* end of while */
+	}			/* end of while */
 }
 
+#endif /* RTMP_MAC_USB // */
diff --git a/drivers/staging/rt2870/rt2870.h b/drivers/staging/rt2870/rt2870.h
deleted file mode 100644
index 4c67baf..0000000
--- a/drivers/staging/rt2870/rt2870.h
+++ /dev/null
@@ -1,583 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
- */
-
-#ifndef __RT2870_H__
-#define __RT2870_H__
-
-//usb header files
-#include <linux/usb.h>
-
-/* rtmp_def.h */
-//
-#define BULKAGGRE_ZISE          100
-#define RT28XX_DRVDATA_SET(_a)                                             usb_set_intfdata(_a, pAd);
-#define RT28XX_PUT_DEVICE                                                  usb_put_dev
-#define RTUSB_ALLOC_URB(iso)                                               usb_alloc_urb(iso, GFP_ATOMIC)
-#define RTUSB_SUBMIT_URB(pUrb)                                             usb_submit_urb(pUrb, GFP_ATOMIC)
-#define	RTUSB_URB_ALLOC_BUFFER(pUsb_Dev, BufSize, pDma_addr)               usb_buffer_alloc(pUsb_Dev, BufSize, GFP_ATOMIC, pDma_addr)
-#define	RTUSB_URB_FREE_BUFFER(pUsb_Dev, BufSize, pTransferBuf, Dma_addr)   usb_buffer_free(pUsb_Dev, BufSize, pTransferBuf, Dma_addr)
-
-#define RXBULKAGGRE_ZISE        12
-#define MAX_TXBULK_LIMIT        (LOCAL_TXBUF_SIZE*(BULKAGGRE_ZISE-1))
-#define MAX_TXBULK_SIZE         (LOCAL_TXBUF_SIZE*BULKAGGRE_ZISE)
-#define MAX_RXBULK_SIZE         (LOCAL_TXBUF_SIZE*RXBULKAGGRE_ZISE)
-#define MAX_MLME_HANDLER_MEMORY 20
-#define	RETRY_LIMIT             10
-#define BUFFER_SIZE				2400	//2048
-#define	TX_RING					0xa
-#define	PRIO_RING				0xc
-
-
-// Flags for Bulkflags control for bulk out data
-//
-#define	fRTUSB_BULK_OUT_DATA_NULL				0x00000001
-#define fRTUSB_BULK_OUT_RTS						0x00000002
-#define	fRTUSB_BULK_OUT_MLME					0x00000004
-
-#define	fRTUSB_BULK_OUT_DATA_NORMAL				0x00010000
-#define	fRTUSB_BULK_OUT_DATA_NORMAL_2			0x00020000
-#define	fRTUSB_BULK_OUT_DATA_NORMAL_3			0x00040000
-#define	fRTUSB_BULK_OUT_DATA_NORMAL_4			0x00080000
-#define	fRTUSB_BULK_OUT_DATA_NORMAL_5			0x00100000
-
-#define	fRTUSB_BULK_OUT_PSPOLL					0x00000020
-#define	fRTUSB_BULK_OUT_DATA_FRAG				0x00000040
-#define	fRTUSB_BULK_OUT_DATA_FRAG_2				0x00000080
-#define	fRTUSB_BULK_OUT_DATA_FRAG_3				0x00000100
-#define	fRTUSB_BULK_OUT_DATA_FRAG_4				0x00000200
-
-#define	FREE_HTTX_RING(_p, _b, _t)			\
-{										\
-	if ((_t)->ENextBulkOutPosition == (_t)->CurWritePosition)				\
-	{																	\
-		(_t)->bRingEmpty = TRUE;			\
-	}																	\
-	/*NdisInterlockedDecrement(&(_p)->TxCount); */\
-}
-
-//
-// RXINFO appends at the end of each rx packet.
-//
-typedef	struct	PACKED _RXINFO_STRUC {
-	UINT32		BA:1;
-	UINT32		DATA:1;
-	UINT32		NULLDATA:1;
-	UINT32		FRAG:1;
-	UINT32		U2M:1;              // 1: this RX frame is unicast to me
-	UINT32		Mcast:1;            // 1: this is a multicast frame
-	UINT32		Bcast:1;            // 1: this is a broadcast frame
-	UINT32		MyBss:1;  	// 1: this frame belongs to the same BSSID
-	UINT32		Crc:1;              // 1: CRC error
-	UINT32		CipherErr:2;        // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid
-	UINT32		AMSDU:1;		// rx with 802.3 header, not 802.11 header.
-	UINT32		HTC:1;
-	UINT32		RSSI:1;
-	UINT32		L2PAD:1;
-	UINT32		AMPDU:1;		// To be moved
-	UINT32		Decrypted:1;
-	UINT32		PlcpRssil:1;
-	UINT32		CipherAlg:1;
-	UINT32		LastAMSDU:1;
-	UINT32		PlcpSignal:12;
-}	RXINFO_STRUC, *PRXINFO_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
-
-//
-// TXINFO
-//
-typedef	struct	_TXINFO_STRUC {
-	// Word	0
-	UINT32		USBDMATxPktLen:16;	//used ONLY in USB bulk Aggregation,  Total byte counts of all sub-frame.
-	UINT32		rsv:8;
-	UINT32		WIV:1;	// Wireless Info Valid. 1 if Driver already fill WI,  o if DMA needs to copy WI to correctposition
-	UINT32		QSEL:2;	// select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
-	UINT32		SwUseLastRound:1; // Software use.
-	UINT32		rsv2:2;  // Software use.
-	UINT32		USBDMANextVLD:1;	//used ONLY in USB bulk Aggregation, NextValid
-	UINT32		USBDMATxburst:1;//used ONLY in USB bulk Aggre. Force USB DMA transmit frame from current selected endpoint
-}	TXINFO_STRUC, *PTXINFO_STRUC;
-
-#define TXINFO_SIZE				4
-#define RXINFO_SIZE				4
-#define TXPADDING_SIZE			11
-
-//
-// Management ring buffer format
-//
-typedef	struct	_MGMT_STRUC	{
-	BOOLEAN		Valid;
-	PUCHAR		pBuffer;
-	ULONG		Length;
-}	MGMT_STRUC, *PMGMT_STRUC;
-
-
-/* ----------------- EEPROM Related MACRO ----------------- */
-#define RT28xx_EEPROM_READ16(pAd, offset, var)					\
-	do {														\
-		RTUSBReadEEPROM(pAd, offset, (PUCHAR)&(var), 2);		\
-		if(!pAd->bUseEfuse)										\
-		var = le2cpu16(var);									\
-	}while(0)
-
-#define RT28xx_EEPROM_WRITE16(pAd, offset, var)					\
-	do{															\
-		USHORT _tmpVar=var;										\
-		if(!pAd->bUseEfuse)									\
-		_tmpVar = cpu2le16(var);								\
-		RTUSBWriteEEPROM(pAd, offset, (PUCHAR)&(_tmpVar), 2);	\
-	}while(0)
-
-/* ----------------- TASK/THREAD Related MACRO ----------------- */
-#define RT28XX_TASK_THREAD_INIT(pAd, Status)		\
-	Status = CreateThreads(net_dev);
-
-
-/* ----------------- Frimware Related MACRO ----------------- */
-#define RT28XX_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen)		\
-	RTUSBFirmwareWrite(_pAd, _pFwImage, _FwLen)
-
-/* ----------------- TX Related MACRO ----------------- */
-#define RT28XX_START_DEQUEUE(pAd, QueIdx, irqFlags)				\
-			{													\
-				RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags);		\
-				if (pAd->DeQueueRunning[QueIdx])						\
-				{														\
-					RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\
-					printk("DeQueueRunning[%d]= TRUE!\n", QueIdx);		\
-					continue;											\
-				}														\
-				else													\
-				{														\
-					pAd->DeQueueRunning[QueIdx] = TRUE;					\
-					RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\
-				}														\
-			}
-#define RT28XX_STOP_DEQUEUE(pAd, QueIdx, irqFlags)						\
-			do{															\
-				RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags);		\
-				pAd->DeQueueRunning[QueIdx] = FALSE;					\
-				RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);	\
-			}while(0)
-
-
-#define	RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \
-		(RTUSBFreeDescriptorRequest(pAd, pTxBlk->QueIdx, (pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))) == NDIS_STATUS_SUCCESS)
-
-#define RT28XX_RELEASE_DESC_RESOURCE(pAd, QueIdx)			\
-		do{}while(0)
-
-#define NEED_QUEUE_BACK_FOR_AGG(_pAd, _QueIdx, _freeNum, _TxFrameType) 		\
-		((_TxFrameType == TX_RALINK_FRAME) && (RTUSBNeedQueueBackForAgg(_pAd, _QueIdx)))
-
-
-
-#define fRTMP_ADAPTER_NEED_STOP_TX		\
-		(fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS |	\
-		 fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_BULKOUT_RESET | \
-		 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
-
-
-#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)	\
-			RtmpUSB_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)
-
-#define HAL_WriteTxResource(pAd, pTxBlk,bIsLast, pFreeNumber)	\
-			RtmpUSB_WriteSingleTxResource(pAd, pTxBlk,bIsLast, pFreeNumber)
-
-#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \
-			RtmpUSB_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber)
-
-#define HAL_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber)	\
-			RtmpUSB_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber)
-
-#define HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx)	\
-			RtmpUSB_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx)
-
-#define HAL_LastTxIdx(pAd, QueIdx,TxIdx) \
-			/*RtmpUSBDataLastTxIdx(pAd, QueIdx,TxIdx)*/
-
-#define HAL_KickOutTx(pAd, pTxBlk, QueIdx)	\
-			RtmpUSBDataKickOut(pAd, pTxBlk, QueIdx)
-
-
-#define HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen)	\
-			RtmpUSBMgmtKickOut(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen)
-
-#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen)	\
-			RtmpUSBNullFrameKickOut(_pAd, _QueIdx, _pNullFrame, _frameLen)
-
-#define RTMP_PKT_TAIL_PADDING 	11 // 3(max 4 byte padding) + 4 (last packet padding) + 4 (MaxBulkOutsize align padding)
-
-extern UCHAR EpToQueue[6];
-
-
-#ifdef RT2870
-#define GET_TXRING_FREENO(_pAd, _QueIdx) 	(_QueIdx) //(_pAd->TxRing[_QueIdx].TxSwFreeIdx)
-#define GET_MGMTRING_FREENO(_pAd) 			(_pAd->MgmtRing.TxSwFreeIdx)
-#endif // RT2870 //
-
-
-/* ----------------- RX Related MACRO ----------------- */
-//#define RT28XX_RX_ERROR_CHECK				RTMPCheckRxWI
-
-#define RT28XX_RV_ALL_BUF_END(bBulkReceive)		\
-	/* We return STATUS_MORE_PROCESSING_REQUIRED so that the completion */	\
-	/* routine (IofCompleteRequest) will stop working on the irp. */		\
-	if (bBulkReceive == TRUE)	RTUSBBulkReceive(pAd);
-
-
-/* ----------------- ASIC Related MACRO ----------------- */
-
-// reset MAC of a station entry to 0xFFFFFFFFFFFF
-#define RT28XX_STA_ENTRY_MAC_RESET(pAd, Wcid)					\
-	{	RT_SET_ASIC_WCID	SetAsicWcid;						\
-		SetAsicWcid.WCID = Wcid;								\
-		SetAsicWcid.SetTid = 0xffffffff;						\
-		SetAsicWcid.DeleteTid = 0xffffffff;						\
-		RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID, 	\
-				&SetAsicWcid, sizeof(RT_SET_ASIC_WCID));	}
-
-// add this entry into ASIC RX WCID search table
-#define RT28XX_STA_ENTRY_ADD(pAd, pEntry)							\
-	RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_CLIENT_MAC_ENTRY, 	\
-							pEntry, sizeof(MAC_TABLE_ENTRY));
-
-// remove Pair-wise key material from ASIC
-// yet implement
-#define RT28XX_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid)
-
-// add Client security information into ASIC WCID table and IVEIV table
-#define RT28XX_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry)						\
-	{	RT28XX_STA_ENTRY_MAC_RESET(pAd, pEntry->Aid);								\
-		if (pEntry->Aid >= 1) {														\
-			RT_SET_ASIC_WCID_ATTRI	SetAsicWcidAttri;								\
-			SetAsicWcidAttri.WCID = pEntry->Aid;									\
-			if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) &&				\
-				(pEntry->WepStatus == Ndis802_11Encryption1Enabled))				\
-			{																		\
-				SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg;	\
-			}																		\
-			else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone)					\
-			{																		\
-				SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg;	\
-			}																		\
-			else SetAsicWcidAttri.Cipher = 0;										\
-            DBGPRINT(RT_DEBUG_TRACE, ("aid cipher = %ld\n",SetAsicWcidAttri.Cipher));       \
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID_CIPHER, 			\
-							&SetAsicWcidAttri, sizeof(RT_SET_ASIC_WCID_ATTRI)); } }
-
-// Insert the BA bitmap to ASIC for the Wcid entry
-#define RT28XX_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID)					\
-		do{																\
-			RT_SET_ASIC_WCID	SetAsicWcid;							\
-			SetAsicWcid.WCID = (_Aid);									\
-			SetAsicWcid.SetTid = (0x10000<<(_TID));						\
-			SetAsicWcid.DeleteTid = 0xffffffff;							\
-			RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(RT_SET_ASIC_WCID));	\
-		}while(0)
-
-// Remove the BA bitmap from ASIC for the Wcid entry
-#define RT28XX_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID)				\
-		do{																\
-			RT_SET_ASIC_WCID	SetAsicWcid;							\
-			SetAsicWcid.WCID = (_Wcid);									\
-			SetAsicWcid.SetTid = (0xffffffff);							\
-			SetAsicWcid.DeleteTid = (0x10000<<(_TID) );					\
-			RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(RT_SET_ASIC_WCID));	\
-		}while(0)
-
-
-/* ----------------- PCI/USB Related MACRO ----------------- */
-#define RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p)			\
-	((POS_COOKIE)handle)->pUsb_Dev = dev_p;
-
-// no use
-#define RT28XX_UNMAP()
-#define RT28XX_IRQ_REQUEST(net_dev)
-#define RT28XX_IRQ_RELEASE(net_dev)
-#define RT28XX_IRQ_INIT(pAd)
-#define RT28XX_IRQ_ENABLE(pAd)
-
-
-/* ----------------- MLME Related MACRO ----------------- */
-#define RT28XX_MLME_HANDLER(pAd)			RTUSBMlmeUp(pAd)
-
-#define RT28XX_MLME_PRE_SANITY_CHECK(pAd)								\
-	{	if ((pAd->CommonCfg.bHardwareRadio == TRUE) && 					\
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&		\
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) {	\
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_CHECK_GPIO, NULL, 0); } }
-
-#define RT28XX_MLME_STA_QUICK_RSP_WAKE_UP(pAd)	\
-	{	RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_QKERIODIC_EXECUT, NULL, 0);	\
-		RTUSBMlmeUp(pAd); }
-
-#define RT28XX_MLME_RESET_STATE_MACHINE(pAd)	\
-		        MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_RESET_CONF, 0, NULL);	\
-		        RTUSBMlmeUp(pAd);
-
-#define RT28XX_HANDLE_COUNTER_MEASURE(_pAd, _pEntry)		\
-	{	RTUSBEnqueueInternalCmd(_pAd, CMDTHREAD_802_11_COUNTER_MEASURE, _pEntry, sizeof(MAC_TABLE_ENTRY));	\
-		RTUSBMlmeUp(_pAd);									\
-	}
-
-
-/* ----------------- Power Save Related MACRO ----------------- */
-#define RT28XX_PS_POLL_ENQUEUE(pAd)						\
-	{	RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);	\
-		RTUSBKickBulkOut(pAd); }
-
-#define RT28xx_CHIP_NAME            "RTxx70"
-
-#define USB_CYC_CFG                 0x02a4
-#define STATUS_SUCCESS				0x00
-#define STATUS_UNSUCCESSFUL 		0x01
-#define NT_SUCCESS(status)			(((status) > 0) ? (1):(0))
-#define InterlockedIncrement 	 	atomic_inc
-#define NdisInterlockedIncrement 	atomic_inc
-#define InterlockedDecrement		atomic_dec
-#define NdisInterlockedDecrement 	atomic_dec
-#define InterlockedExchange			atomic_set
-//#define NdisMSendComplete			RTMP_SendComplete
-#define NdisMCancelTimer			RTMPCancelTimer
-#define NdisAllocMemory(_ptr, _size, _flag)	\
-									do{_ptr = kmalloc((_size),(_flag));}while(0)
-#define NdisFreeMemory(a, b, c) 	kfree((a))
-#define NdisMSleep					RTMPusecDelay		/* unit: microsecond */
-
-
-#define USBD_TRANSFER_DIRECTION_OUT		0
-#define USBD_TRANSFER_DIRECTION_IN		0
-#define USBD_SHORT_TRANSFER_OK			0
-#define PURB			purbb_t
-
-#define RTUSB_FREE_URB(pUrb)	usb_free_urb(pUrb)
-
-//#undef MlmeAllocateMemory
-//#undef MlmeFreeMemory
-
-typedef struct usb_device	* PUSB_DEV;
-
-/* MACRO for linux usb */
-typedef struct urb *purbb_t;
-typedef struct usb_ctrlrequest devctrlrequest;
-#define PIRP		PVOID
-#define PMDL		PVOID
-#define NDIS_OID	UINT
-#ifndef USB_ST_NOERROR
-#define USB_ST_NOERROR     0
-#endif
-
-// vendor-specific control operations
-#define CONTROL_TIMEOUT_JIFFIES ( (100 * HZ) / 1000)
-#define UNLINK_TIMEOUT_MS		3
-
-/* unlink urb	*/
-#define RTUSB_UNLINK_URB(pUrb)		usb_kill_urb(pUrb)
-
-// Prototypes of completion funuc.
-VOID RTUSBBulkOutDataPacketComplete(purbb_t purb, struct pt_regs *pt_regs);
-VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs);
-VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs);
-VOID RTUSBBulkOutRTSFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs);
-VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb, struct pt_regs *pt_regs);
-VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs);
-
-#define RTUSBMlmeUp(pAd)	        \
-{								    \
-	POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;	\
-	if (pid_nr(pObj->MLMEThr_pid) > 0) \
-        up(&(pAd->mlme_semaphore)); \
-}
-
-#define RTUSBCMDUp(pAd)	                \
-{									    \
-	POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;	\
-	if (pid_nr(pObj->RTUSBCmdThr_pid) > 0) \
-	    up(&(pAd->RTUSBCmd_semaphore)); \
-}
-
-static inline NDIS_STATUS RTMPAllocateMemory(
-	OUT PVOID *ptr,
-	IN size_t size)
-{
-	*ptr = kmalloc(size, GFP_ATOMIC);
-	if(*ptr)
-		return NDIS_STATUS_SUCCESS;
-	else
-		return NDIS_STATUS_RESOURCES;
-}
-
-/* rtmp.h */
-#define	BEACON_RING_SIZE                2
-#define DEVICE_VENDOR_REQUEST_OUT       0x40
-#define DEVICE_VENDOR_REQUEST_IN        0xc0
-#define INTERFACE_VENDOR_REQUEST_OUT    0x41
-#define INTERFACE_VENDOR_REQUEST_IN     0xc1
-#define MGMTPIPEIDX						0	// EP6 is highest priority
-
-#define BULKOUT_MGMT_RESET_FLAG				0x80
-
-#define RTUSB_SET_BULK_FLAG(_M, _F)				((_M)->BulkFlags |= (_F))
-#define RTUSB_CLEAR_BULK_FLAG(_M, _F)			((_M)->BulkFlags &= ~(_F))
-#define RTUSB_TEST_BULK_FLAG(_M, _F)			(((_M)->BulkFlags & (_F)) != 0)
-
-#define EnqueueCmd(cmdq, cmdqelmt)		\
-{										\
-	if (cmdq->size == 0)				\
-		cmdq->head = cmdqelmt;			\
-	else								\
-		cmdq->tail->next = cmdqelmt;	\
-	cmdq->tail = cmdqelmt;				\
-	cmdqelmt->next = NULL;				\
-	cmdq->size++;						\
-}
-
-typedef struct   _RT_SET_ASIC_WCID {
-	ULONG WCID;          // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based
-	ULONG SetTid;        // time-based: seconds, packet-based: kilo-packets
-	ULONG DeleteTid;        // time-based: seconds, packet-based: kilo-packets
-	UCHAR Addr[MAC_ADDR_LEN];	// avoid in interrupt when write key
-} RT_SET_ASIC_WCID,*PRT_SET_ASIC_WCID;
-
-typedef struct   _RT_SET_ASIC_WCID_ATTRI {
-	ULONG	WCID;          // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based
-	ULONG	Cipher;        // ASIC Cipher definition
-	UCHAR	Addr[ETH_LENGTH_OF_ADDRESS];
-} RT_SET_ASIC_WCID_ATTRI,*PRT_SET_ASIC_WCID_ATTRI;
-
-typedef struct _MLME_MEMORY_STRUCT {
-	PVOID                           AllocVa;    //Pointer to the base virtual address of the allocated memory
-	struct _MLME_MEMORY_STRUCT      *Next;      //Pointer to the next virtual address of the allocated memory
-}   MLME_MEMORY_STRUCT, *PMLME_MEMORY_STRUCT;
-
-typedef struct  _MLME_MEMORY_HANDLER {
-	BOOLEAN                 MemRunning;         //The flag of the Mlme memory handler's status
-	UINT                    MemoryCount;        //Total nonpaged system-space memory not size
-	UINT                    InUseCount;         //Nonpaged system-space memory in used counts
-	UINT                    UnUseCount;         //Nonpaged system-space memory available counts
-	INT                    PendingCount;       //Nonpaged system-space memory for free counts
-	PMLME_MEMORY_STRUCT     pInUseHead;         //Pointer to the first nonpaed memory not used
-	PMLME_MEMORY_STRUCT     pInUseTail;         //Pointer to the last nonpaged memory not used
-	PMLME_MEMORY_STRUCT     pUnUseHead;         //Pointer to the first nonpaged memory in used
-	PMLME_MEMORY_STRUCT     pUnUseTail;         //Pointer to the last nonpaged memory in used
-	PULONG                  MemFreePending[MAX_MLME_HANDLER_MEMORY];   //an array to keep pending free-memory's pointer (32bits)
-}   MLME_MEMORY_HANDLER, *PMLME_MEMORY_HANDLER;
-
-typedef	struct _CmdQElmt	{
-	UINT				command;
-	PVOID				buffer;
-	ULONG				bufferlength;
-	BOOLEAN				CmdFromNdis;
-	BOOLEAN				SetOperation;
-	struct _CmdQElmt	*next;
-}	CmdQElmt, *PCmdQElmt;
-
-typedef	struct	_CmdQ	{
-	UINT		size;
-	CmdQElmt	*head;
-	CmdQElmt	*tail;
-	UINT32		CmdQState;
-}CmdQ, *PCmdQ;
-
-/* oid.h */
-// Cipher suite type for mixed mode group cipher, P802.11i-2004
-typedef enum _RT_802_11_CIPHER_SUITE_TYPE {
-	Cipher_Type_NONE,
-	Cipher_Type_WEP40,
-	Cipher_Type_TKIP,
-	Cipher_Type_RSVD,
-	Cipher_Type_CCMP,
-	Cipher_Type_WEP104
-} RT_802_11_CIPHER_SUITE_TYPE, *PRT_802_11_CIPHER_SUITE_TYPE;
-
-//CMDTHREAD_MULTI_READ_MAC
-//CMDTHREAD_MULTI_WRITE_MAC
-//CMDTHREAD_VENDOR_EEPROM_READ
-//CMDTHREAD_VENDOR_EEPROM_WRITE
-typedef	struct	_CMDHandler_TLV	{
-	USHORT		Offset;
-	USHORT		Length;
-	UCHAR		DataFirst;
-}	CMDHandler_TLV, *PCMDHandler_TLV;
-
-// New for MeetingHouse Api support
-#define CMDTHREAD_VENDOR_RESET                      0x0D730101	// cmd
-#define CMDTHREAD_VENDOR_UNPLUG                     0x0D730102	// cmd
-#define CMDTHREAD_VENDOR_SWITCH_FUNCTION            0x0D730103	// cmd
-#define CMDTHREAD_MULTI_WRITE_MAC                   0x0D730107	// cmd
-#define CMDTHREAD_MULTI_READ_MAC                    0x0D730108	// cmd
-#define CMDTHREAD_VENDOR_EEPROM_WRITE               0x0D73010A	// cmd
-#define CMDTHREAD_VENDOR_EEPROM_READ                0x0D73010B	// cmd
-#define CMDTHREAD_VENDOR_ENTER_TESTMODE             0x0D73010C	// cmd
-#define CMDTHREAD_VENDOR_EXIT_TESTMODE              0x0D73010D	// cmd
-#define CMDTHREAD_VENDOR_WRITE_BBP                  0x0D730119	// cmd
-#define CMDTHREAD_VENDOR_READ_BBP                   0x0D730118	// cmd
-#define CMDTHREAD_VENDOR_WRITE_RF                   0x0D73011A	// cmd
-#define CMDTHREAD_VENDOR_FLIP_IQ                    0x0D73011D	// cmd
-#define CMDTHREAD_RESET_BULK_OUT                    0x0D730210	// cmd
-#define CMDTHREAD_RESET_BULK_IN                     0x0D730211	// cmd
-#define CMDTHREAD_SET_PSM_BIT_SAVE                  0x0D730212	// cmd
-#define CMDTHREAD_SET_RADIO                         0x0D730214	// cmd
-#define CMDTHREAD_UPDATE_TX_RATE                    0x0D730216	// cmd
-#define CMDTHREAD_802_11_ADD_KEY_WEP                0x0D730218	// cmd
-#define CMDTHREAD_RESET_FROM_ERROR                  0x0D73021A	// cmd
-#define CMDTHREAD_LINK_DOWN                         0x0D73021B	// cmd
-#define CMDTHREAD_RESET_FROM_NDIS                   0x0D73021C	// cmd
-#define CMDTHREAD_CHECK_GPIO                        0x0D730215	// cmd
-#define CMDTHREAD_FORCE_WAKE_UP                     0x0D730222	// cmd
-#define CMDTHREAD_SET_BW                            0x0D730225	// cmd
-#define CMDTHREAD_SET_ASIC_WCID                     0x0D730226	// cmd
-#define CMDTHREAD_SET_ASIC_WCID_CIPHER              0x0D730227	// cmd
-#define CMDTHREAD_QKERIODIC_EXECUT                  0x0D73023D	// cmd
-#define CMDTHREAD_SET_CLIENT_MAC_ENTRY              0x0D73023E	// cmd
-#define CMDTHREAD_802_11_QUERY_HARDWARE_REGISTER    0x0D710105	// cmd
-#define CMDTHREAD_802_11_SET_PHY_MODE               0x0D79010C	// cmd
-#define CMDTHREAD_802_11_SET_STA_CONFIG             0x0D790111	// cmd
-#define CMDTHREAD_802_11_SET_PREAMBLE               0x0D790101	// cmd
-#define CMDTHREAD_802_11_COUNTER_MEASURE			0x0D790102	// cmd
-#define CMDTHREAD_UPDATE_PROTECT					0x0D790103	// cmd
-
-#define WPA1AKMBIT	    0x01
-#define WPA2AKMBIT	    0x02
-#define WPA1PSKAKMBIT   0x04
-#define WPA2PSKAKMBIT   0x08
-#define TKIPBIT         0x01
-#define CCMPBIT         0x02
-
-
-#define RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx) \
-    RT28xxUsbStaAsicForceWakeup(pAd, bFromTx);
-
-#define RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \
-    RT28xxUsbStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
-
-#define RT28XX_MLME_RADIO_ON(pAd) \
-    RT28xxUsbMlmeRadioOn(pAd);
-
-#define RT28XX_MLME_RADIO_OFF(pAd) \
-    RT28xxUsbMlmeRadioOFF(pAd);
-
-#endif //__RT2870_H__
diff --git a/drivers/staging/rt2870/rt_usb.c b/drivers/staging/rt2870/rt_usb.c
new file mode 100644
index 0000000..5e02d4c
--- /dev/null
+++ b/drivers/staging/rt2870/rt_usb.c
@@ -0,0 +1 @@
+#include "../rt2860/rt_usb.c"
diff --git a/drivers/staging/rt2870/usb_main_dev.c b/drivers/staging/rt2870/usb_main_dev.c
new file mode 100644
index 0000000..6e63bc5
--- /dev/null
+++ b/drivers/staging/rt2870/usb_main_dev.c
@@ -0,0 +1 @@
+#include "../rt2860/usb_main_dev.c"
diff --git a/drivers/staging/rt3070/firmware.h b/drivers/staging/rt3070/firmware.h
index b07783e..5cf9cbc 100644
--- a/drivers/staging/rt3070/firmware.h
+++ b/drivers/staging/rt3070/firmware.h
@@ -43,7 +43,7 @@
 /* AUTO GEN PLEASE DO NOT MODIFY IT */
 
 
-UCHAR FirmwareImage [] = {
+u8 FirmwareImage_2870 [] = {
 0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x12, 0x67, 0x02,
 0x12, 0x68, 0x02, 0x12, 0x87, 0x02, 0x12, 0x8c, 0x12, 0x12, 0x88, 0x22, 0x02, 0x16, 0x49, 0x02,
 0x17, 0x1f, 0x02, 0x13, 0x77, 0x02, 0x12, 0x8d, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x17,
diff --git a/drivers/staging/rt3070/md4.h b/drivers/staging/rt3070/md4.h
index f1e5b52..a9cc7b0 100644
--- a/drivers/staging/rt3070/md4.h
+++ b/drivers/staging/rt3070/md4.h
@@ -30,13 +30,13 @@
 
 /* MD4 context. */
 typedef	struct	_MD4_CTX_	{
-	ULONG	state[4];        /* state (ABCD) */
-	ULONG	count[2];        /* number of bits, modulo 2^64 (lsb first) */
-	UCHAR	buffer[64];      /* input buffer */
+	unsigned long	state[4];        /* state (ABCD) */
+	unsigned long	count[2];        /* number of bits, modulo 2^64 (lsb first) */
+	u8	buffer[64];      /* input buffer */
 }	MD4_CTX;
 
-VOID MD4Init (MD4_CTX *);
-VOID MD4Update (MD4_CTX *, PUCHAR, UINT);
-VOID MD4Final (UCHAR [16], MD4_CTX *);
+void MD4Init (MD4_CTX *);
+void MD4Update (MD4_CTX *, u8 *, UINT);
+void MD4Final (u8 [16], MD4_CTX *);
 
 #endif //__MD4_H__
\ No newline at end of file
diff --git a/drivers/staging/rt3090/Kconfig b/drivers/staging/rt3090/Kconfig
deleted file mode 100644
index 2b3f745..0000000
--- a/drivers/staging/rt3090/Kconfig
+++ /dev/null
@@ -1,5 +0,0 @@
-config RT3090
-	tristate "Ralink 3090 wireless support"
-	depends on PCI && X86 && WLAN
-	---help---
-	  This is an experimental driver for the Ralink 3090 wireless chip.
diff --git a/drivers/staging/rt3090/Makefile b/drivers/staging/rt3090/Makefile
deleted file mode 100644
index 995491c..0000000
--- a/drivers/staging/rt3090/Makefile
+++ /dev/null
@@ -1,80 +0,0 @@
-obj-$(CONFIG_RT3090)	+= rt3090sta.o
-
-include drivers/staging/rt3090/config.mk
-
-rt3090sta-objs := \
-	common/crypt_md5.o \
-	common/crypt_sha2.o \
-	common/crypt_hmac.o \
-	common/mlme.o \
-	common/cmm_wep.o \
-	common/action.o \
-	common/cmm_data.o \
-	common/rtmp_init.o \
-	common/cmm_tkip.o \
-	common/cmm_aes.o \
-	common/cmm_sync.o \
-	common/eeprom.o \
-	common/cmm_sanity.o \
-	common/cmm_info.o \
-	common/cmm_cfg.o \
-	common/cmm_wpa.o \
-	common/dfs.o \
-	common/spectrum.o \
-	common/rtmp_timer.o \
-	common/rt_channel.o \
-	common/cmm_profile.o \
-	common/cmm_asic.o \
-	sta/assoc.o \
-	sta/auth.o \
-	sta/auth_rsp.o \
-	sta/sync.o \
-	sta/sanity.o \
-	sta/rtmp_data.o \
-	sta/connect.o \
-	sta/wpa.o \
-	rt_linux.o \
-	rt_profile.o \
-	rt_main_dev.o \
-	sta_ioctl.o
-
-#ifdef DOT11_N_SUPPORT
-ifeq ($(HAS_DOT11_N_SUPPORT),y)
-rt3090sta-objs += \
-	common/ba_action.o
-endif
-#endif // DOT11_N_SUPPORT //
-
-#ifdef ETH_CONVERT
-ifeq ($(HAS_ETH_CONVERT_SUPPORT), y)
-rt3090sta-objs += \
-	common/cmm_mat.o \
-	common/cmm_mat_iparp.o \
-	common/cmm_mat_pppoe.o \
-	common/cmm_mat_ipv6.o
-endif
-#endif // ETH_CONVERT //
-
-ifeq ($(HAS_BLOCK_NET_IF),y)
-rt3090sta-objs += common/netif_block.o
-endif
-
-ifeq ($(HAS_QOS_DLS_SUPPORT),y)
-rt3090sta-objs += sta/dls.o
-endif
-
-rt3090sta-objs += \
-	pci_main_dev.o \
-	rt_pci_rbus.o \
-	common/cmm_mac_pci.o \
-	common/cmm_data_pci.o \
-	common/ee_prom.o \
-	common/ee_efuse.o \
-	common/rtmp_mcu.o \
-	chips/rt30xx.o \
-	common/rt_rf.o \
-	chips/rt3090.o
-
-ifeq ($(HAS_ATE),y)
-rt3090sta-objs += rt_ate.o
-endif
diff --git a/drivers/staging/rt3090/action.h b/drivers/staging/rt3090/action.h
deleted file mode 100644
index ac0a0a3..0000000
--- a/drivers/staging/rt3090/action.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	aironet.h
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Name		Date			Modification logs
-	Paul Lin	04-06-15		Initial
-*/
-
-#ifndef	__ACTION_H__
-#define	__ACTION_H__
-
-typedef struct PACKED __HT_INFO_OCTET
-{
-#ifdef RT_BIG_ENDIAN
-	UCHAR	Reserved:5;
-	UCHAR	STA_Channel_Width:1;
-	UCHAR	Forty_MHz_Intolerant:1;
-	UCHAR	Request:1;
-#else
-	UCHAR	Request:1;
-	UCHAR	Forty_MHz_Intolerant:1;
-	UCHAR	STA_Channel_Width:1;
-	UCHAR	Reserved:5;
-#endif
-} HT_INFORMATION_OCTET;
-
-
-typedef struct PACKED __FRAME_HT_INFO
-{
-	HEADER_802_11			Hdr;
-	UCHAR					Category;
-	UCHAR					Action;
-	HT_INFORMATION_OCTET	HT_Info;
-}   FRAME_HT_INFO, *PFRAME_HT_INFO;
-
-#endif /* __ACTION_H__ */
diff --git a/drivers/staging/rt3090/ap.h b/drivers/staging/rt3090/ap.h
deleted file mode 100644
index e894303..0000000
--- a/drivers/staging/rt3090/ap.h
+++ /dev/null
@@ -1,512 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    ap.h
-
-    Abstract:
-    Miniport generic portion header file
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-    Paul Lin    08-01-2002    created
-    James Tan   09-06-2002    modified (Revise NTCRegTable)
-    John Chang  12-22-2004    modified for RT2561/2661. merge with STA driver
-*/
-#ifndef __AP_H__
-#define __AP_H__
-
-
-// =============================================================
-//      Function Prototypes
-// =============================================================
-
-// ap_data.c
-
-BOOLEAN APBridgeToWirelessSta(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PUCHAR          pHeader,
-    IN  UINT            HdrLen,
-    IN  PUCHAR          pData,
-    IN  UINT            DataLen,
-    IN  ULONG           fromwdsidx);
-
-
-VOID	APSendPackets(
-	IN	NDIS_HANDLE		MiniportAdapterContext,
-	IN	PPNDIS_PACKET	ppPacketArray,
-	IN	UINT			NumberOfPackets);
-
-NDIS_STATUS APSendPacket(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PNDIS_PACKET    pPacket);
-
-
-NDIS_STATUS APHardTransmit(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	UCHAR			QueIdx);
-
-VOID APRxEAPOLFrameIndicate(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MAC_TABLE_ENTRY	*pEntry,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID);
-
-NDIS_STATUS APCheckRxError(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PRT28XX_RXD_STRUC		pRxD,
-	IN	UCHAR			Wcid);
-
-BOOLEAN APCheckClass2Class3Error(
-    IN  PRTMP_ADAPTER   pAd,
-	IN ULONG Wcid,
-	IN  PHEADER_802_11  pHeader);
-
-VOID APHandleRxPsPoll(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pAddr,
-	IN	USHORT			Aid,
-    IN	BOOLEAN			isActive);
-
-VOID    RTMPDescriptorEndianChange(
-    IN  PUCHAR          pData,
-    IN  ULONG           DescriptorType);
-
-VOID    RTMPFrameEndianChange(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PUCHAR          pData,
-    IN  ULONG           Dir,
-    IN  BOOLEAN         FromRxDoneInt);
-
-// ap_assoc.c
-
-VOID APAssocStateMachineInit(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  STATE_MACHINE *S,
-    OUT STATE_MACHINE_FUNC Trans[]);
-
-VOID  APPeerAssocReqAction(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  MLME_QUEUE_ELEM *Elem);
-
-VOID  APPeerReassocReqAction(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  MLME_QUEUE_ELEM *Elem);
-
-VOID  APPeerDisassocReqAction(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  MLME_QUEUE_ELEM *Elem);
-
-VOID MbssKickOutStas(
-	IN PRTMP_ADAPTER pAd,
-	IN INT apidx,
-	IN USHORT Reason);
-
-VOID APMlmeKickOutSta(
-    IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pStaAddr,
-	IN UCHAR Wcid,
-	IN USHORT Reason);
-
-VOID APMlmeDisassocReqAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
-
-VOID  APCls3errAction(
-    IN  PRTMP_ADAPTER   pAd,
-	IN	ULONG Wcid,
-    IN	PHEADER_802_11	pHeader);
-
-
-USHORT APBuildAssociation(
-    IN PRTMP_ADAPTER pAd,
-    IN MAC_TABLE_ENTRY *pEntry,
-    IN USHORT CapabilityInfo,
-    IN UCHAR  MaxSupportedRateIn500Kbps,
-    IN UCHAR  *RSN,
-    IN UCHAR  *pRSNLen,
-    IN BOOLEAN bWmmCapable,
-    IN ULONG  RalinkIe,
-#ifdef DOT11N_DRAFT3
-    IN EXT_CAP_INFO_ELEMENT ExtCapInfo,
-#endif // DOT11N_DRAFT3 //
-	IN HT_CAPABILITY_IE		*pHtCapability,
-	IN UCHAR		 HtCapabilityLen,
-    OUT USHORT *pAid);
-
-/*
-VOID	RTMPAddClientSec(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR	BssIdx,
-	IN UCHAR		 KeyIdx,
-	IN UCHAR		 CipherAlg,
-	IN PUCHAR		 pKey,
-	IN PUCHAR		 pTxMic,
-	IN PUCHAR		 pRxMic,
-	IN MAC_TABLE_ENTRY *pEntry);
-*/
-
-// ap_auth.c
-
-void APAuthStateMachineInit(
-    IN PRTMP_ADAPTER pAd,
-    IN STATE_MACHINE *Sm,
-    OUT STATE_MACHINE_FUNC Trans[]);
-
-VOID APCls2errAction(
-    IN PRTMP_ADAPTER pAd,
-	IN	ULONG Wcid,
-    IN	PHEADER_802_11	pHeader);
-
-// ap_connect.c
-
-
-VOID APMakeBssBeacon(
-    IN  PRTMP_ADAPTER   pAd,
-	IN	INT				apidx);
-
-VOID  APUpdateBeaconFrame(
-    IN  PRTMP_ADAPTER   pAd,
-	IN	INT				apidx);
-
-VOID APMakeAllBssBeacon(
-    IN  PRTMP_ADAPTER   pAd);
-
-VOID  APUpdateAllBeaconFrame(
-    IN  PRTMP_ADAPTER   pAd);
-
-
-// ap_sync.c
-
-VOID APSyncStateMachineInit(
-    IN PRTMP_ADAPTER pAd,
-    IN STATE_MACHINE *Sm,
-    OUT STATE_MACHINE_FUNC Trans[]);
-
-VOID APScanTimeout(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
-
-VOID APInvalidStateWhenScan(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
-
-VOID APScanTimeoutAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
-
-VOID APPeerProbeReqAction(
-    IN  PRTMP_ADAPTER pAd,
-    IN  MLME_QUEUE_ELEM *Elem);
-
-VOID APPeerBeaconAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
-
-VOID APMlmeScanReqAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
-
-VOID APPeerBeaconAtScanAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
-
-VOID APScanCnclAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
-
-VOID ApSiteSurvey(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	PNDIS_802_11_SSID	pSsid,
-	IN	UCHAR				ScanType);
-
-VOID SupportRate(
-	IN PUCHAR SupRate,
-	IN UCHAR SupRateLen,
-	IN PUCHAR ExtRate,
-	IN UCHAR ExtRateLen,
-	OUT PUCHAR *Rates,
-	OUT PUCHAR RatesLen,
-	OUT PUCHAR pMaxSupportRate);
-
-
-BOOLEAN ApScanRunning(
-	IN PRTMP_ADAPTER pAd);
-
-#ifdef DOT11N_DRAFT3
-VOID APOverlappingBSSScan(
-	IN RTMP_ADAPTER *pAd);
-#endif // DOT11N_DRAFT3 //
-
-// ap_wpa.c
-VOID WpaStateMachineInit(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  STATE_MACHINE *Sm,
-    OUT STATE_MACHINE_FUNC Trans[]);
-
-// ap_mlme.c
-VOID APMlmePeriodicExec(
-    IN  PRTMP_ADAPTER   pAd);
-
-VOID APMlmeSelectTxRateTable(
-	IN PRTMP_ADAPTER		pAd,
-	IN PMAC_TABLE_ENTRY		pEntry,
-	IN PUCHAR				*ppTable,
-	IN PUCHAR				pTableSize,
-	IN PUCHAR				pInitTxRateIdx);
-
-VOID APMlmeSetTxRate(
-	IN PRTMP_ADAPTER		pAd,
-	IN PMAC_TABLE_ENTRY		pEntry,
-	IN PRTMP_TX_RATE_SWITCH	pTxRate);
-
-VOID APMlmeDynamicTxRateSwitching(
-    IN PRTMP_ADAPTER pAd);
-
-VOID APQuickResponeForRateUpExec(
-    IN PVOID SystemSpecific1,
-    IN PVOID FunctionContext,
-    IN PVOID SystemSpecific2,
-    IN PVOID SystemSpecific3);
-
-BOOLEAN APMsgTypeSubst(
-    IN PRTMP_ADAPTER pAd,
-    IN PFRAME_802_11 pFrame,
-    OUT INT *Machine,
-    OUT INT *MsgType);
-
-VOID APQuickResponeForRateUpExec(
-    IN PVOID SystemSpecific1,
-    IN PVOID FunctionContext,
-    IN PVOID SystemSpecific2,
-    IN PVOID SystemSpecific3);
-
-
-VOID RTMPSetPiggyBack(
-	IN PRTMP_ADAPTER	pAd,
-	IN BOOLEAN			bPiggyBack);
-
-VOID APAsicEvaluateRxAnt(
-	IN PRTMP_ADAPTER	pAd);
-
-VOID APAsicRxAntEvalTimeout(
-	IN PRTMP_ADAPTER	pAd);
-
-// ap.c
-
-VOID APSwitchChannel(
-	IN PRTMP_ADAPTER pAd,
-	IN INT Channel);
-
-NDIS_STATUS APInitialize(
-    IN  PRTMP_ADAPTER   pAd);
-
-VOID APShutdown(
-    IN PRTMP_ADAPTER    pAd);
-
-VOID APStartUp(
-    IN  PRTMP_ADAPTER   pAd);
-
-VOID APStop(
-    IN  PRTMP_ADAPTER   pAd);
-
-VOID APCleanupPsQueue(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PQUEUE_HEADER   pQueue);
-
-VOID MacTableReset(
-    IN  PRTMP_ADAPTER   pAd);
-
-MAC_TABLE_ENTRY *MacTableInsertEntry(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PUCHAR          pAddr,
-	IN	UCHAR			apidx,
-	IN BOOLEAN	CleanAll);
-
-BOOLEAN MacTableDeleteEntry(
-    IN  PRTMP_ADAPTER   pAd,
-	IN USHORT wcid,
-    IN  PUCHAR          pAddr);
-
-MAC_TABLE_ENTRY *MacTableLookup(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PUCHAR          pAddr);
-
-VOID MacTableMaintenance(
-    IN PRTMP_ADAPTER pAd);
-
-UINT32 MacTableAssocStaNumGet(
-	IN PRTMP_ADAPTER pAd);
-
-MAC_TABLE_ENTRY *APSsPsInquiry(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PUCHAR          pAddr,
-    OUT SST             *Sst,
-    OUT USHORT          *Aid,
-    OUT UCHAR           *PsMode,
-    OUT UCHAR           *Rate);
-
-BOOLEAN APPsIndicate(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PUCHAR          pAddr,
-	IN ULONG Wcid,
-    IN  UCHAR           Psm);
-
-VOID ApLogEvent(
-    IN PRTMP_ADAPTER    pAd,
-    IN PUCHAR           pAddr,
-    IN USHORT           Event);
-
-#ifdef DOT11_N_SUPPORT
-VOID APUpdateOperationMode(
-    IN PRTMP_ADAPTER pAd);
-#endif // DOT11_N_SUPPORT //
-
-VOID APUpdateCapabilityAndErpIe(
-	IN PRTMP_ADAPTER pAd);
-
-BOOLEAN ApCheckAccessControlList(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR        pAddr,
-	IN UCHAR         Apidx);
-
-VOID ApUpdateAccessControlList(
-    IN PRTMP_ADAPTER pAd,
-    IN UCHAR         Apidx);
-
-VOID ApEnqueueNullFrame(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR        pAddr,
-	IN UCHAR         TxRate,
-	IN UCHAR         PID,
-	IN UCHAR         apidx,
-    IN BOOLEAN       bQosNull,
-    IN BOOLEAN       bEOSP,
-    IN UCHAR         OldUP);
-
-VOID ApSendFrame(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PVOID           pBuffer,
-    IN  ULONG           Length,
-    IN  UCHAR           TxRate,
-    IN  UCHAR           PID);
-
-VOID ApEnqueueAckFrame(
-    IN PRTMP_ADAPTER pAd,
-    IN PUCHAR        pAddr,
-    IN UCHAR         TxRate,
-	IN UCHAR         apidx);
-
-// ap_sanity.c
-
-
-BOOLEAN PeerAssocReqCmmSanity(
-    IN PRTMP_ADAPTER pAd,
-	IN BOOLEAN isRessoc,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pAddr2,
-    OUT USHORT *pCapabilityInfo,
-    OUT USHORT *pListenInterval,
-    OUT PUCHAR pApAddr,
-    OUT UCHAR *pSsidLen,
-    OUT char *Ssid,
-    OUT UCHAR *pRatesLen,
-    OUT UCHAR Rates[],
-    OUT UCHAR *RSN,
-    OUT UCHAR *pRSNLen,
-    OUT BOOLEAN *pbWmmCapable,
-    OUT ULONG  *pRalinkIe,
-#ifdef DOT11N_DRAFT3
-    OUT EXT_CAP_INFO_ELEMENT	*pExtCapInfo,
-#endif // DOT11N_DRAFT3 //
-    OUT UCHAR		 *pHtCapabilityLen,
-    OUT HT_CAPABILITY_IE *pHtCapability);
-
-
-BOOLEAN PeerDisassocReqSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pAddr2,
-    OUT USHORT *Reason);
-
-BOOLEAN PeerDeauthReqSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pAddr2,
-    OUT USHORT *Reason);
-
-BOOLEAN APPeerAuthSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-	OUT PUCHAR pAddr1,
-    OUT PUCHAR pAddr2,
-    OUT USHORT *Alg,
-    OUT USHORT *Seq,
-    OUT USHORT *Status,
-    OUT CHAR *ChlgText
-	);
-
-BOOLEAN APPeerProbeReqSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pAddr2,
-    OUT CHAR Ssid[],
-    OUT UCHAR *SsidLen);
-
-BOOLEAN APPeerBeaconAndProbeRspSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pAddr2,
-    OUT PUCHAR pBssid,
-    OUT CHAR Ssid[],
-    OUT UCHAR *SsidLen,
-    OUT UCHAR *BssType,
-    OUT USHORT *BeaconPeriod,
-    OUT UCHAR *Channel,
-    OUT LARGE_INTEGER *Timestamp,
-    OUT USHORT *CapabilityInfo,
-    OUT UCHAR Rate[],
-    OUT UCHAR *RateLen,
-    OUT BOOLEAN *ExtendedRateIeExist,
-    OUT UCHAR *Erp);
-#if defined(RT30xx) || defined(RT305x)
-VOID EnableAPMIMOPS(
-    IN PRTMP_ADAPTER pAd);
-
-VOID DisableAPMIMOPS(
-    IN PRTMP_ADAPTER pAd);
-#endif
-#endif  // __AP_H__
diff --git a/drivers/staging/rt3090/ap_apcli.h b/drivers/staging/rt3090/ap_apcli.h
deleted file mode 100644
index d363c36..0000000
--- a/drivers/staging/rt3090/ap_apcli.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    ap_apcli.h
-
-    Abstract:
-    Miniport generic portion header file
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-    Shiang, Fonchi    02-13-2007      created
-*/
-
-#ifndef _AP_APCLI_H_
-#define _AP_APCLI_H_
-
-#ifdef APCLI_SUPPORT
-
-#include "rtmp.h"
-
-#define AUTH_TIMEOUT	300         // unit: msec
-#define ASSOC_TIMEOUT	300         // unit: msec
-//#define JOIN_TIMEOUT	2000        // unit: msec // not used in Ap-client mode, remove it
-#define PROBE_TIMEOUT	1000        // unit: msec
-
-#define APCLI_ROOT_BSSID_GET(pAd, wcid) ((pAd)->MacTab.Content[(wcid)].Addr)
-#define APCLI_IF_UP_CHECK(pAd, ifidx) ((pAd)->ApCfg.ApCliTab[(ifidx)].dev->flags & IFF_UP)
-
-/* sanity check for apidx */
-#define APCLI_MR_APIDX_SANITY_CHECK(idx) \
-{ \
-	if ((idx) >= MAX_APCLI_NUM) \
-	{ \
-		(idx) = 0; \
-		DBGPRINT(RT_DEBUG_ERROR, ("%s> Error! apcli-idx > MAX_APCLI_NUM!\n", __FUNCTION__)); \
-	} \
-}
-
-typedef struct _APCLI_MLME_JOIN_REQ_STRUCT {
-	UCHAR	Bssid[MAC_ADDR_LEN];
-	UCHAR	SsidLen;
-	UCHAR	Ssid[MAX_LEN_OF_SSID];
-} APCLI_MLME_JOIN_REQ_STRUCT;
-
-typedef struct _STA_CTRL_JOIN_REQ_STRUCT {
-	USHORT	Status;
-} APCLI_CTRL_MSG_STRUCT, *PSTA_CTRL_MSG_STRUCT;
-
-BOOLEAN isValidApCliIf(
-	SHORT ifIndex);
-
-//
-// Private routines in apcli_ctrl.c
-//
-VOID ApCliCtrlStateMachineInit(
-	IN PRTMP_ADAPTER pAd,
-	IN STATE_MACHINE_EX *Sm,
-	OUT STATE_MACHINE_FUNC_EX Trans[]);
-
-//
-// Private routines in apcli_sync.c
-//
-VOID ApCliSyncStateMachineInit(
-    IN PRTMP_ADAPTER pAd,
-    IN STATE_MACHINE_EX *Sm,
-    OUT STATE_MACHINE_FUNC_EX Trans[]);
-
-//
-// Private routines in apcli_auth.c
-//
-VOID ApCliAuthStateMachineInit(
-    IN PRTMP_ADAPTER pAd,
-    IN STATE_MACHINE_EX *Sm,
-    OUT STATE_MACHINE_FUNC_EX Trans[]);
-
-//
-// Private routines in apcli_assoc.c
-//
-VOID ApCliAssocStateMachineInit(
-    IN PRTMP_ADAPTER pAd,
-    IN STATE_MACHINE_EX *Sm,
-    OUT STATE_MACHINE_FUNC_EX Trans[]);
-
-MAC_TABLE_ENTRY *ApCliTableLookUpByWcid(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR wcid,
-	IN PUCHAR pAddrs);
-
-
-BOOLEAN ApCliAllowToSendPacket(
-	IN RTMP_ADAPTER *pAd,
-	IN PNDIS_PACKET pPacket,
-	OUT UCHAR		*pWcid);
-
-BOOLEAN		ApCliValidateRSNIE(
-	IN		PRTMP_ADAPTER	pAd,
-	IN		PEID_STRUCT	pEid_ptr,
-	IN		USHORT			eid_len,
-	IN		USHORT			idx);
-
-VOID RT28xx_ApCli_Init(
-	IN PRTMP_ADAPTER	pAd,
-	IN PNET_DEV			pPhyNetDev);
-
-VOID RT28xx_ApCli_Close(
-	IN PRTMP_ADAPTER	pAd);
-
-VOID RT28xx_ApCli_Remove(
-	IN PRTMP_ADAPTER	pAd);
-
-
-VOID RT28xx_ApCli_Remove(
-	IN PRTMP_ADAPTER ad_p);
-
-INT ApCliIfLookUp(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pAddr);
-
-INT ApCli_VirtualIF_Open(
-	IN	PNET_DEV	dev_p);
-
-INT ApCli_VirtualIF_Close(
-	IN	PNET_DEV	dev_p);
-
-INT ApCli_VirtualIF_PacketSend(
-	IN PNDIS_PACKET		skb_p,
-	IN PNET_DEV			dev_p);
-
-INT ApCli_VirtualIF_Ioctl(
-	IN PNET_DEV				dev_p,
-	IN OUT struct ifreq	*rq_p,
-	IN INT cmd);
-
-
-VOID ApCliMgtMacHeaderInit(
-    IN	PRTMP_ADAPTER	pAd,
-    IN OUT PHEADER_802_11 pHdr80211,
-    IN UCHAR SubType,
-    IN UCHAR ToDs,
-    IN PUCHAR pDA,
-    IN PUCHAR pBssid,
-    IN USHORT ifIndex);
-
-#ifdef DOT11_N_SUPPORT
-BOOLEAN ApCliCheckHt(
-	IN		PRTMP_ADAPTER		pAd,
-	IN		USHORT				IfIndex,
-	IN OUT	HT_CAPABILITY_IE	*pHtCapability,
-	IN OUT	ADD_HT_INFO_IE		*pAddHtInfo);
-#endif // DOT11_N_SUPPORT //
-
-BOOLEAN ApCliLinkUp(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR ifIndex);
-
-VOID ApCliLinkDown(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR ifIndex);
-
-VOID ApCliIfUp(
-	IN PRTMP_ADAPTER pAd);
-
-VOID ApCliIfDown(
-	IN PRTMP_ADAPTER pAd);
-
-VOID ApCliIfMonitor(
-	IN PRTMP_ADAPTER pAd);
-
-BOOLEAN ApCliMsgTypeSubst(
-	IN PRTMP_ADAPTER  pAd,
-	IN PFRAME_802_11 pFrame,
-	OUT INT *Machine,
-	OUT INT *MsgType);
-
-BOOLEAN preCheckMsgTypeSubset(
-	IN PRTMP_ADAPTER  pAd,
-	IN PFRAME_802_11 pFrame,
-	OUT INT *Machine,
-	OUT INT *MsgType);
-
-BOOLEAN ApCliPeerAssocRspSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *pMsg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pAddr2,
-    OUT USHORT *pCapabilityInfo,
-    OUT USHORT *pStatus,
-    OUT USHORT *pAid,
-    OUT UCHAR SupRate[],
-    OUT UCHAR *pSupRateLen,
-    OUT UCHAR ExtRate[],
-    OUT UCHAR *pExtRateLen,
-    OUT HT_CAPABILITY_IE *pHtCapability,
-    OUT ADD_HT_INFO_IE *pAddHtInfo,	// AP might use this additional ht info IE
-    OUT UCHAR *pHtCapabilityLen,
-    OUT UCHAR *pAddHtInfoLen,
-    OUT UCHAR *pNewExtChannelOffset,
-    OUT PEDCA_PARM pEdcaParm,
-    OUT UCHAR *pCkipFlag);
-
-VOID	ApCliPeerPairMsg1Action(
-	IN PRTMP_ADAPTER    pAd,
-    IN MAC_TABLE_ENTRY  *pEntry,
-    IN MLME_QUEUE_ELEM  *Elem);
-
-VOID	ApCliPeerPairMsg3Action(
-	IN PRTMP_ADAPTER    pAd,
-    IN MAC_TABLE_ENTRY  *pEntry,
-    IN MLME_QUEUE_ELEM  *Elem);
-
-VOID	ApCliPeerGroupMsg1Action(
-	IN PRTMP_ADAPTER    pAd,
-    IN MAC_TABLE_ENTRY  *pEntry,
-    IN MLME_QUEUE_ELEM  *Elem);
-
-BOOLEAN ApCliCheckRSNIE(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pData,
-	IN  UCHAR           DataLen,
-	IN  MAC_TABLE_ENTRY *pEntry,
-	OUT	UCHAR			*Offset);
-
-BOOLEAN ApCliParseKeyData(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pKeyData,
-	IN  UCHAR           KeyDataLen,
-	IN  MAC_TABLE_ENTRY *pEntry,
-	IN	UCHAR			IfIdx,
-	IN	UCHAR			bPairewise);
-
-BOOLEAN  ApCliHandleRxBroadcastFrame(
-	IN  PRTMP_ADAPTER   pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN  MAC_TABLE_ENTRY *pEntry,
-	IN	UCHAR			FromWhichBSSID);
-
-VOID APCliUpdatePairwiseKeyTable(
-	IN  PRTMP_ADAPTER   pAd,
-	IN	UCHAR			*KeyRsc,
-	IN  MAC_TABLE_ENTRY *pEntry);
-
-BOOLEAN APCliUpdateSharedKeyTable(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pKey,
-	IN  UCHAR           KeyLen,
-	IN	UCHAR			DefaultKeyIdx,
-	IN  MAC_TABLE_ENTRY *pEntry);
-
-#endif // APCLI_SUPPORT //
-
-#endif /* _AP_APCLI_H_ */
diff --git a/drivers/staging/rt3090/ap_autoChSel.h b/drivers/staging/rt3090/ap_autoChSel.h
deleted file mode 100644
index 46881ff..0000000
--- a/drivers/staging/rt3090/ap_autoChSel.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    ap_autoChSel.h
-
-    Abstract:
-    Miniport generic portion header file
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-*/
-
-#include "ap_autoChSel_cmm.h"
-
-#ifndef __AUTOCHSELECT_H__
-#define __AUTOCHSELECT_H__
-
-#ifdef AUTO_CH_SELECT_ENHANCE
-#define AP_AUTO_CH_SEL(__P, __O)	New_APAutoSelectChannel((__P), (__O))
-#else
-#define AP_AUTO_CH_SEL(__P, __O)	APAutoSelectChannel((__P), (__O))
-#endif
-
-
-ULONG AutoChBssInsertEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pBssid,
-	IN CHAR Ssid[],
-	IN UCHAR SsidLen,
-	IN UCHAR ChannelNo,
-	IN UCHAR ExtChOffset,
-	IN CHAR Rssi);
-
-void AutoChBssTableInit(
-	IN PRTMP_ADAPTER pAd);
-
-void ChannelInfoInit(
-	IN PRTMP_ADAPTER pAd);
-
-void AutoChBssTableDestroy(
-	IN PRTMP_ADAPTER pAd);
-
-void ChannelInfoDestroy(
-	IN PRTMP_ADAPTER pAd);
-
-UCHAR New_APAutoSelectChannel(
-	IN PRTMP_ADAPTER pAd,
-	IN BOOLEAN Optimal);
-
-UCHAR APAutoSelectChannel(
-	IN PRTMP_ADAPTER pAd,
-	IN BOOLEAN Optimal);
-
-#endif // __AUTOCHSELECT_H__ //
diff --git a/drivers/staging/rt3090/ap_autoChSel_cmm.h b/drivers/staging/rt3090/ap_autoChSel_cmm.h
deleted file mode 100644
index ad77ec1..0000000
--- a/drivers/staging/rt3090/ap_autoChSel_cmm.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    ap_autoChSel_cmm.h
-
-    Abstract:
-    Miniport generic portion header file
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-*/
-
-
-#ifndef __AUTOCHSELECT_CMM_H__
-#define __AUTOCHSELECT_CMM_H__
-
-#define RSSI_TO_DBM_OFFSET 120 // RSSI-115 = dBm
-
-
-typedef struct {
-	ULONG dirtyness[MAX_NUM_OF_CHANNELS+1];
-	ULONG max_rssi[MAX_NUM_OF_CHANNELS+1];
-	ULONG total_rssi[MAX_NUM_OF_CHANNELS+1];
-	UINT32 FalseCCA[MAX_NUM_OF_CHANNELS+1];
-} CHANNELINFO, *PCHANNELINFO;
-
-typedef struct {
-	UCHAR Bssid[MAC_ADDR_LEN];
-	UCHAR SsidLen;
-	CHAR Ssid[MAX_LEN_OF_SSID];
-	UCHAR Channel;
-	UCHAR ExtChOffset;
-	UCHAR Rssi;
-} BSSENTRY, *PBSSENTRY;
-
-typedef struct {
-	UCHAR BssNr;
-	BSSENTRY BssEntry[MAX_LEN_OF_BSS_TABLE];
-} BSSINFO, *PBSSINFO;
-
-#endif // __AUTOCHSELECT_CMM_H__ //
diff --git a/drivers/staging/rt3090/ap_cfg.h b/drivers/staging/rt3090/ap_cfg.h
deleted file mode 100644
index 7c99423..0000000
--- a/drivers/staging/rt3090/ap_cfg.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    ap_cfg.h
-
-    Abstract:
-    Miniport generic portion header file
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-*/
-#ifndef __AP_CFG_H__
-#define __AP_CFG_H__
-
-
-#include "rt_config.h"
-
-INT RTMPAPPrivIoctlSet(
-	IN RTMP_ADAPTER *pAd,
-	IN struct iwreq *pIoctlCmdStr);
-
-INT RTMPAPPrivIoctlShow(
-	IN RTMP_ADAPTER *pAd,
-	IN struct iwreq *pIoctlCmdStr);
-
-INT RTMPAPSetInformation(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	OUT	struct iwreq	*rq,
-	IN	INT				cmd);
-
-INT RTMPAPQueryInformation(
-	IN	PRTMP_ADAPTER       pAd,
-	IN	OUT	struct iwreq    *rq,
-	IN	INT                 cmd);
-
-VOID RTMPIoctlStatistics(
-	IN PRTMP_ADAPTER pAd,
-	IN struct iwreq *wrq);
-
-VOID RTMPIoctlGetMacTable(
-	IN PRTMP_ADAPTER pAd,
-	IN struct iwreq *wrq);
-
-#ifdef DBG
-VOID RTMPAPIoctlBBP(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  struct iwreq    *wrq);
-
-VOID RTMPAPIoctlMAC(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  struct iwreq    *wrq);
-
-VOID RTMPAPIoctlE2PROM(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  struct iwreq    *wrq);
-
-#ifdef RTMP_RF_RW_SUPPORT
-VOID RTMPAPIoctlRF(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq);
-#endif // RTMP_RF_RW_SUPPORT //
-
-#endif // DBG //
-
-VOID RT28XX_IOCTL_MaxRateGet(
-	IN	RTMP_ADAPTER			*pAd,
-	IN	PHTTRANSMIT_SETTING	pHtPhyMode,
-	OUT	UINT32					*pRate);
-
-
-#ifdef DOT11_N_SUPPORT
-VOID RTMPIoctlQueryBaTable(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	struct iwreq	*wrq);
-#endif // DOT11_N_SUPPORT //
-
-VOID RTMPIoctlStaticWepCopy(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	struct iwreq	*wrq);
-
-VOID RTMPIoctlRadiusData(
-	IN PRTMP_ADAPTER	pAd,
-	IN struct iwreq		*wrq);
-
-VOID RTMPIoctlAddWPAKey(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	struct iwreq	*wrq);
-
-VOID RTMPIoctlAddPMKIDCache(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	struct iwreq	*wrq);
-
-#endif // __AP_CFG_H__ //
diff --git a/drivers/staging/rt3090/ap_ids.h b/drivers/staging/rt3090/ap_ids.h
deleted file mode 100644
index cf8797f..0000000
--- a/drivers/staging/rt3090/ap_ids.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    ap_ids.h
-
-    Abstract:
-    Miniport generic portion header file
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-*/
-
-VOID RTMPIdsPeriodicExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
-
-BOOLEAN RTMPSpoofedMgmtDetection(
-	IN PRTMP_ADAPTER	pAd,
-	IN PHEADER_802_11	pHeader,
-	IN CHAR				Rssi0,
-	IN CHAR				Rssi1,
-	IN CHAR				Rssi2);
-
-VOID RTMPConflictSsidDetection(
-	IN PRTMP_ADAPTER	pAd,
-	IN PUCHAR			pSsid,
-	IN UCHAR			SsidLen,
-	IN CHAR				Rssi0,
-	IN CHAR				Rssi1,
-	IN CHAR				Rssi2);
-
-BOOLEAN RTMPReplayAttackDetection(
-	IN PRTMP_ADAPTER	pAd,
-	IN PUCHAR			pAddr2,
-	IN CHAR				Rssi0,
-	IN CHAR				Rssi1,
-	IN CHAR				Rssi2);
-
-VOID RTMPUpdateStaMgmtCounter(
-	IN PRTMP_ADAPTER	pAd,
-	IN USHORT			type);
-
-VOID RTMPClearAllIdsCounter(
-	IN PRTMP_ADAPTER	pAd);
-
-VOID RTMPIdsStart(
-	IN PRTMP_ADAPTER	pAd);
-
-VOID RTMPIdsStop(
-	IN PRTMP_ADAPTER	pAd);
-
-VOID rtmp_read_ids_from_file(
-			IN  PRTMP_ADAPTER pAd,
-			char *tmpbuf,
-			char *buffer);
diff --git a/drivers/staging/rt3090/ap_mbss.h b/drivers/staging/rt3090/ap_mbss.h
deleted file mode 100644
index f78556c..0000000
--- a/drivers/staging/rt3090/ap_mbss.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    ap_mbss.h
-
-    Abstract:
-    Miniport generic portion header file
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-*/
-
-#ifndef MODULE_MBSS
-
-#define MBSS_EXTERN    extern
-
-#else
-
-#define MBSS_EXTERN
-
-#endif // MODULE_MBSS //
-
-
-/* Public function list */
-MBSS_EXTERN VOID RT28xx_MBSS_Init(
-	IN PRTMP_ADAPTER ad_p,
-	IN PNET_DEV main_dev_p);
-
-MBSS_EXTERN VOID RT28xx_MBSS_Close(
-	IN PRTMP_ADAPTER ad_p);
-
-MBSS_EXTERN VOID RT28xx_MBSS_Remove(
-	IN PRTMP_ADAPTER ad_p);
-
-INT MBSS_VirtualIF_Open(
-	IN	PNET_DEV			dev_p);
-INT MBSS_VirtualIF_Close(
-	IN	PNET_DEV			dev_p);
-INT MBSS_VirtualIF_PacketSend(
-	IN PNDIS_PACKET			skb_p,
-	IN PNET_DEV				dev_p);
-INT MBSS_VirtualIF_Ioctl(
-	IN PNET_DEV				dev_p,
-	IN OUT struct ifreq	*rq_p,
-	IN INT cmd);
-
-/* End of ap_mbss.h */
diff --git a/drivers/staging/rt3090/ap_uapsd.h b/drivers/staging/rt3090/ap_uapsd.h
deleted file mode 100644
index d49a9e7..0000000
--- a/drivers/staging/rt3090/ap_uapsd.h
+++ /dev/null
@@ -1,636 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    ap_uapsd.h
-
-    Abstract:
-    Miniport generic portion header file
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-*/
-
-/* only for UAPSD_TIMING_RECORD */
-
-//#define UAPSD_TIMING_RECORD_FUNC
-
-#define UAPSD_TIMING_RECORD_MAX				1000
-#define UAPSD_TIMING_RECORD_DISPLAY_TIMES	10
-
-#define UAPSD_TIMING_RECORD_ISR				1
-#define UAPSD_TIMING_RECORD_TASKLET			2
-#define UAPSD_TIMING_RECORD_TRG_RCV			3
-#define UAPSD_TIMING_RECORD_MOVE2TX			4
-#define UAPSD_TIMING_RECORD_TX2AIR			5
-
-#define UAPSD_TIMING_CTRL_STOP				0
-#define UAPSD_TIMING_CTRL_START				1
-#define UAPSD_TIMING_CTRL_SUSPEND			2
-
-#define UAPSD_TIMESTAMP_GET(__pAd, __TimeStamp)			\
-	{													\
-		UINT32 __CSR=0;	UINT64 __Value64;				\
-		RTMP_IO_READ32((__pAd), TSF_TIMER_DW0, &__CSR);	\
-		__TimeStamp = (UINT64)__CSR;					\
-		RTMP_IO_READ32((__pAd), TSF_TIMER_DW1, &__CSR);	\
-		__Value64 = (UINT64)__CSR;						\
-		__TimeStamp |= (__Value64 << 32);				\
-	}
-
-#ifdef LINUX
-#define UAPSD_TIME_GET(__pAd, __Time)					\
-		__Time = jiffies
-#endif // LINUX //
-
-
-#ifdef UAPSD_TIMING_RECORD_FUNC
-#define UAPSD_TIMING_RECORD_START()				\
-	UAPSD_TimingRecordCtrl(UAPSD_TIMING_CTRL_START);
-#define UAPSD_TIMING_RECORD_STOP()				\
-	UAPSD_TimingRecordCtrl(UAPSD_TIMING_CTRL_STOP);
-#define UAPSD_TIMING_RECORD(__pAd, __Type)		\
-	UAPSD_TimingRecord(__pAd, __Type);
-#define UAPSD_TIMING_RECORD_INDEX(__LoopIndex)	\
-	UAPSD_TimeingRecordLoopIndex(__LoopIndex);
-#else
-
-#define UAPSD_TIMING_RECORD_START()
-#define UAPSD_TIMING_RECORD_STOP()
-#define UAPSD_TIMING_RECORD(__pAd, __type)
-#define UAPSD_TIMING_RECORD_INDEX(__LoopIndex)
-#endif // UAPSD_TIMING_RECORD_FUNC //
-
-
-#ifndef MODULE_WMM_UAPSD
-
-#define UAPSD_EXTERN			extern
-
-/* Public Marco list */
-
-/*
-	Init some parameters in packet structure for QoS Null frame;
-	purpose: is for management frame tx done use
-*/
-#define UAPSD_MR_QOS_NULL_HANDLE(__pAd, __pData, __pPacket)					\
-	{																		\
-		PHEADER_802_11 __pHeader = (PHEADER_802_11)(__pData);				\
-		MAC_TABLE_ENTRY *__pEntry;											\
-		if (__pHeader->FC.SubType == SUBTYPE_QOS_NULL)						\
-		{																	\
-			RTMP_SET_PACKET_QOS_NULL((__pPacket));							\
-			__pEntry = MacTableLookup((__pAd), __pHeader->Addr1);			\
-			if (__pEntry != NULL)											\
-			{																\
-				RTMP_SET_PACKET_WCID((__pPacket), __pEntry->Aid);			\
-			}																\
-		}																	\
-		else																\
-		{																	\
-			RTMP_SET_PACKET_NON_QOS_NULL((__pPacket));						\
-		}																	\
-	}
-
-/*
-	Init MAC entry UAPSD parameters;
-	purpose: initialize UAPSD PS queue and control parameters
-*/
-#define UAPSD_MR_ENTRY_INIT(__pEntry)										\
-	{																		\
-		UINT16	__IdAc;														\
-		for(__IdAc=0; __IdAc<WMM_NUM_OF_AC; __IdAc++)						\
-			InitializeQueueHeader(&(__pEntry)->UAPSDQueue[__IdAc]);			\
-		(__pEntry)->UAPSDTxNum = 0;											\
-		(__pEntry)->pUAPSDEOSPFrame = NULL;									\
-		(__pEntry)->bAPSDFlagSPStart = 0;									\
-		(__pEntry)->bAPSDFlagEOSPOK = 0;									\
-		(__pEntry)->MaxSPLength = 0;										\
-	}
-
-/*
-	Reset MAC entry UAPSD parameters;
-   purpose: clean all UAPSD PS queue; release the EOSP frame if exists;
-			reset control parameters
-*/
-#define UAPSD_MR_ENTRY_RESET(__pAd, __pEntry)								\
-	{																		\
-		MAC_TABLE_ENTRY *__pSta;											\
-		UINT32 __IdAc;														\
-		__pSta = (__pEntry);												\
-		/* clear all U-APSD queues */										\
-		for(__IdAc=0; __IdAc<WMM_NUM_OF_AC; __IdAc++)						\
-			APCleanupPsQueue((__pAd), &__pSta->UAPSDQueue[__IdAc]);		\
-		/* clear EOSP frame */												\
-		__pSta->UAPSDTxNum = 0;												\
-		if (__pSta->pUAPSDEOSPFrame != NULL) {								\
-			RELEASE_NDIS_PACKET((__pAd),									\
-							QUEUE_ENTRY_TO_PACKET(__pSta->pUAPSDEOSPFrame),	\
-							NDIS_STATUS_FAILURE);							\
-			__pSta->pUAPSDEOSPFrame = NULL; }								\
-		__pSta->bAPSDFlagSPStart = 0;										\
-		__pSta->bAPSDFlagEOSPOK = 0; }
-
-/*
-	Enable or disable UAPSD flag in WMM element in beacon frame;
-	purpose: set UAPSD enable/disable bit
-*/
-#define UAPSD_MR_IE_FILL(__QosCtrlField, __pAd)								\
-		(__QosCtrlField) |= ((__pAd)->CommonCfg.bAPSDCapable) ? 0x80 : 0x00;
-
-/*
-	Check if we do NOT need to control TIM bit for the station;
-	note: we control TIM bit only when all AC are UAPSD AC
-*/
-#define UAPSD_MR_IS_NOT_TIM_BIT_NEEDED_HANDLED(__pMacEntry, __QueIdx)		\
-		(CLIENT_STATUS_TEST_FLAG((__pMacEntry), fCLIENT_STATUS_APSD_CAPABLE) && \
-			(!(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_VO] ||			\
-			!(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_VI] ||			\
-			!(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_BE] ||			\
-			!(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_BK]) &&			\
-		(__pMacEntry)->bAPSDDeliverEnabledPerAC[__QueIdx])
-
-/* check if the AC is UAPSD delivery-enabled AC */
-#define UAPSD_MR_IS_UAPSD_AC(__pMacEntry, __AcId)							\
-		(CLIENT_STATUS_TEST_FLAG((__pMacEntry), fCLIENT_STATUS_APSD_CAPABLE) &&	\
-			((0 <= (__AcId)) && ((__AcId) < WMM_NUM_OF_AC)) && /* 0 ~ 3 */	\
-			(__pMacEntry)->bAPSDDeliverEnabledPerAC[(__AcId)])
-
-/* check if all AC are UAPSD delivery-enabled AC */
-#define UAPSD_MR_IS_ALL_AC_UAPSD(__FlgIsActive, __pMacEntry)				\
-		(((__FlgIsActive) == FALSE) && ((__pMacEntry)->bAPSDAllAC == 1))
-
-/* suspend SP */
-#define UAPSD_MR_SP_SUSPEND(__pAd)											\
-		(__pAd)->bAPSDFlagSPSuspend = 1;
-
-/* resume SP */
-#define UAPSD_MR_SP_RESUME(__pAd)											\
-		(__pAd)->bAPSDFlagSPSuspend = 0;
-
-/* mark PS poll frame sent in mix mode */
-#ifdef RTMP_MAC_PCI
-/*
-	Note:
-	(1) When SP is not started, try to mark a flag to record if the legacy ps
-		packet is handled in statistics handler;
-	(2) When SP is started, increase the UAPSD count number for the legacy PS.
-*/
-#define UAPSD_MR_MIX_PS_POLL_RCV(__pAd, __pMacEntry)						\
-		if ((__pMacEntry)->bAPSDFlagSpRoughUse == 0)						\
-		{																	\
-			if ((__pMacEntry)->bAPSDFlagSPStart == 0)						\
-			{																\
-				if ((__pMacEntry)->bAPSDFlagLegacySent == 1)				\
-					NICUpdateFifoStaCounters((__pAd));						\
-				(__pMacEntry)->bAPSDFlagLegacySent = 1;						\
-			}																\
-			else															\
-			{																\
-				(__pMacEntry)->UAPSDTxNum ++;								\
-			}																\
-		}
-#endif // RTMP_MAC_PCI //
-
-
-#else
-
-#define UAPSD_EXTERN
-#define UAPSD_QOS_NULL_QUE_ID	0x7f
-
-#ifdef RTMP_MAC_PCI
-/*
-	In RT2870, FIFO counter is for all stations, not for per-entry,
-	so we can not use accurate method in RT2870
-*/
-
-/*
-	Note for SP ACCURATE Mechanism:
-	1. When traffic is busy for the PS station
-		Statistics FIFO counter maybe overflow before we read it, so UAPSD
-		counting mechanism will not accurately.
-
-		Solution:
-		We need to avoid the worse case so we suggest a maximum interval for
-		a SP that the interval between last frame from QAP and data frame from
-		QSTA is larger than UAPSD_EPT_SP_INT.
-
-	2. When traffic use CCK/1Mbps from QAP
-		Statistics FIFO will not count the packet. There are 2 cases:
-		(1) We force to downgrage ARP response & DHCP packet to 1Mbps;
-		(2) After rate switch mechanism, tx rate is fixed to 1Mbps.
-
-		Solution:
-		Use old DMA UAPSD mechanism.
-
-	3. When part of AC uses legacy PS mode
-		Statistics count will inclue packet statistics for legacy PS packets
-		so we can not know which one is UAPSD, which one is legacy.
-
-		Solution:
-		Cound the legacy PS packet.
-
-	4. Check FIFO statistics count in Rx Done function
-		We can not to check TX FIFO statistics count in Rx Done function or
-		the real packet tx/rx sequence will be disarranged.
-
-		Solution:
-		Suspend SP handle before rx done and resume SP handle after rx done.
-*/
-#define UAPSD_SP_ACCURATE		/* use more accurate method to send EOSP */
-#endif // RTMP_MAC_PCI //
-
-#define UAPSD_EPT_SP_INT		(100000/(1000000/OS_HZ)) /* 100ms */
-
-#endif // MODULE_WMM_UAPSD //
-
-
-/* max UAPSD buffer queue size */
-#define MAX_PACKETS_IN_UAPSD_QUEUE	16	/* for each AC = 16*4 = 64 */
-
-
-/* Public function list */
-/*
-========================================================================
-Routine Description:
-	UAPSD Module Init.
-
-Arguments:
-	pAd		Pointer to our adapter
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-UAPSD_EXTERN VOID UAPSD_Init(
-	IN	PRTMP_ADAPTER		pAd);
-
-
-/*
-========================================================================
-Routine Description:
-	UAPSD Module Release.
-
-Arguments:
-	pAd		Pointer to our adapter
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-UAPSD_EXTERN VOID UAPSD_Release(
-	IN	PRTMP_ADAPTER		pAd);
-
-
-/*
-========================================================================
-Routine Description:
-	Free all EOSP frames and close all SP.
-
-Arguments:
-	pAd		Pointer to our adapter
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-UAPSD_EXTERN VOID UAPSD_FreeAll(
-	IN	PRTMP_ADAPTER		pAd);
-
-
-/*
-========================================================================
-Routine Description:
-	Close current Service Period.
-
-Arguments:
-	pAd				Pointer to our adapter
-	pEntry			Close the SP of the entry
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-UAPSD_EXTERN VOID UAPSD_SP_Close(
-    IN  PRTMP_ADAPTER       pAd,
-	IN	MAC_TABLE_ENTRY		*pEntry);
-
-
-/*
-========================================================================
-Routine Description:
-	Deliver all queued packets.
-
-Arguments:
-	pAd            Pointer to our adapter
-	*pEntry        STATION
-
-Return Value:
-	None
-
-Note:
-	SMP protection by caller for packet enqueue.
-========================================================================
-*/
-UAPSD_EXTERN VOID UAPSD_AllPacketDeliver(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	MAC_TABLE_ENTRY		*pEntry);
-
-
-/*
-========================================================================
-Routine Description:
-	Parse the UAPSD field in WMM element in (re)association request frame.
-
-Arguments:
-	pAd				Pointer to our adapter
-	*pEntry			STATION
-	*pElm			QoS information field
-
-Return Value:
-	None
-
-Note:
-	No protection is needed.
-
-	1. Association -> TSPEC:
-		use static UAPSD settings in Association
-		update UAPSD settings in TSPEC
-
-	2. Association -> TSPEC(11r) -> Reassociation:
-		update UAPSD settings in TSPEC
-		backup static UAPSD settings in Reassociation
-
-	3. Association -> Reassociation:
-		update UAPSD settings in TSPEC
-		backup static UAPSD settings in Reassociation
-========================================================================
-*/
-UAPSD_EXTERN VOID UAPSD_AssocParse(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	MAC_TABLE_ENTRY		*pEntry,
-	IN	UCHAR				*pElm);
-
-
-/*
-========================================================================
-Routine Description:
-	Enqueue a UAPSD packet.
-
-Arguments:
-	pAd				Pointer to our adapter
-	*pEntry			STATION
-	pPacket			UAPSD dnlink packet
-	IdAc			UAPSD AC ID (0 ~ 3)
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-UAPSD_EXTERN VOID UAPSD_PacketEnqueue(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	MAC_TABLE_ENTRY		*pEntry,
-	IN	PNDIS_PACKET		pPacket,
-	IN	UINT32				IdAc);
-
-
-/*
-========================================================================
-Routine Description:
-	Handle QoS Null Frame Tx Done or Management Tx Done interrupt.
-
-Arguments:
-	pAd				Pointer to our adapter
-	pPacket			Completed TX packet
-	pDstMac			Destinated MAC address
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-UAPSD_EXTERN VOID UAPSD_QoSNullTxMgmtTxDoneHandle(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	PNDIS_PACKET		pPacket,
-	IN	UCHAR				*pDstMac);
-
-
-/*
-========================================================================
-Routine Description:
-	Maintenance our UAPSD PS queue.  Release all queued packet if timeout.
-
-Arguments:
-	pAd				Pointer to our adapter
-	*pEntry			STATION
-
-Return Value:
-	None
-
-Note:
-	If in RT2870, pEntry can not be removed during UAPSD_QueueMaintenance()
-========================================================================
-*/
-UAPSD_EXTERN VOID UAPSD_QueueMaintenance(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	MAC_TABLE_ENTRY		*pEntry);
-
-
-/*
-========================================================================
-Routine Description:
-	Close SP in Tx Done, not Tx DMA Done.
-
-Arguments:
-	pAd            Pointer to our adapter
-	pEntry			destination entry
-	FlgSuccess		0:tx success, 1:tx fail
-
-Return Value:
-    None
-
-Note:
-	For RT28xx series, for packetID=0 or multicast frame, no statistics
-	count can be got, ex: ARP response or DHCP packets, we will use
-	low rate to set (CCK, MCS=0=packetID).
-	So SP will not be close until UAPSD_EPT_SP_INT timeout.
-
-	So if the tx rate is 1Mbps for a entry, we will use DMA done, not
-	use UAPSD_SP_AUE_Handle().
-========================================================================
-*/
-UAPSD_EXTERN VOID UAPSD_SP_AUE_Handle(
-	IN RTMP_ADAPTER		*pAd,
-    IN MAC_TABLE_ENTRY	*pEntry,
-	IN UCHAR			FlgSuccess);
-
-
-/*
-========================================================================
-Routine Description:
-	Close current Service Period.
-
-Arguments:
-	pAd				Pointer to our adapter
-
-Return Value:
-	None
-
-Note:
-	When we receive EOSP frame tx done interrupt and a uplink packet
-	from the station simultaneously, we will regard it as a new trigger
-	frame because the packet is received when EOSP frame tx done interrupt.
-
-	We can not sure the uplink packet is sent after old SP or in the old SP.
-	So we must close the old SP in receive done ISR to avoid the problem.
-========================================================================
-*/
-UAPSD_EXTERN VOID UAPSD_SP_CloseInRVDone(
-	IN	PRTMP_ADAPTER		pAd);
-
-
-/*
-========================================================================
-Routine Description:
-	Check if we need to close current SP.
-
-Arguments:
-	pAd				Pointer to our adapter
-	pPacket			Completed TX packet
-	pDstMac			Destinated MAC address
-
-Return Value:
-	None
-
-Note:
-	1. We need to call the function in TxDone ISR.
-	2. SMP protection by caller for packet enqueue.
-========================================================================
-*/
-UAPSD_EXTERN VOID UAPSD_SP_PacketCheck(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	PNDIS_PACKET		pPacket,
-	IN	UCHAR				*pDstMac);
-
-
-#ifdef UAPSD_TIMING_RECORD_FUNC
-/*
-========================================================================
-Routine Description:
-	Enable/Disable Timing Record Function.
-
-Arguments:
-	pAd				Pointer to our adapter
-	Flag			1 (Enable) or 0 (Disable)
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-UAPSD_EXTERN VOID UAPSD_TimingRecordCtrl(
-	IN	UINT32				Flag);
-
-/*
-========================================================================
-Routine Description:
-	Record some timings.
-
-Arguments:
-	pAd				Pointer to our adapter
-	Type			The timing is for what type
-
-Return Value:
-	None
-
-Note:
-	UAPSD_TIMING_RECORD_ISR
-	UAPSD_TIMING_RECORD_TASKLET
-	UAPSD_TIMING_RECORD_TRG_RCV
-	UAPSD_TIMING_RECORD_MOVE2TX
-	UAPSD_TIMING_RECORD_TX2AIR
-========================================================================
-*/
-UAPSD_EXTERN VOID UAPSD_TimingRecord(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	UINT32				Type);
-
-/*
-========================================================================
-Routine Description:
-	Record the loop index for received packet handle.
-
-Arguments:
-	pAd				Pointer to our adapter
-	LoopIndex		The RxProcessed in APRxDoneInterruptHandle()
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-UAPSD_EXTERN VOID UAPSD_TimeingRecordLoopIndex(
-	IN	UINT32				LoopIndex);
-#endif // UAPSD_TIMING_RECORD_FUNC //
-
-
-/*
-========================================================================
-Routine Description:
-	Handle UAPSD Trigger Frame.
-
-Arguments:
-	pAd				Pointer to our adapter
-	*pEntry			the source STATION
-	UpOfFrame		the UP of the trigger frame
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-UAPSD_EXTERN VOID UAPSD_TriggerFrameHandle(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	MAC_TABLE_ENTRY		*pEntry,
-	IN	UCHAR				UpOfFrame);
-
-
-
-/* End of ap_uapsd.h */
diff --git a/drivers/staging/rt3090/ap_wds.h b/drivers/staging/rt3090/ap_wds.h
deleted file mode 100644
index efcb107..0000000
--- a/drivers/staging/rt3090/ap_wds.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    ap_cfg.h
-
-    Abstract:
-    Miniport generic portion header file
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-    Fonchi    02-13-2007      created
-*/
-
-#ifndef _AP_WDS_H_
-#define _AP_WDS_H_
-
-#define WDS_ENTRY_RETRY_INTERVAL	(100 * OS_HZ / 1000)
-
-
-static inline BOOLEAN WDS_IF_UP_CHECK(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  ULONG ifidx)
-{
-	if ((pAd->flg_wds_init != TRUE) ||
-		(ifidx >= MAX_WDS_ENTRY))
-		return FALSE;
-
-//	if (pAd->WdsTab.WdsEntry[ifidx].dev->flags & IFF_UP)
-// Patch for wds ,when dirver call apmlmeperiod => APMlmeDynamicTxRateSwitching check if wds device ready
-if ((pAd->WdsTab.WdsEntry[ifidx].dev != NULL) && (pAd->WdsTab.WdsEntry[ifidx].dev->flags & IFF_UP))
-		return TRUE;
-
-	return FALSE;
-}
-
-LONG WdsEntryAlloc(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pAddr);
-
-VOID WdsEntryDel(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pAddr);
-
-MAC_TABLE_ENTRY *MacTableInsertWDSEntry(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR pAddr,
-	UINT WdsTabIdx);
-
-BOOLEAN MacTableDeleteWDSEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT wcid,
-	IN PUCHAR pAddr);
-
-
-BOOLEAN ApWdsAllowToSendPacket(
-	IN RTMP_ADAPTER *pAd,
-	IN PNDIS_PACKET pPacket,
-	OUT	UCHAR		*pWcid);
-
-MAC_TABLE_ENTRY *WdsTableLookupByWcid(
-    IN  PRTMP_ADAPTER   pAd,
-	IN UCHAR wcid,
-	IN PUCHAR pAddr,
-	IN BOOLEAN bResetIdelCount);
-
-MAC_TABLE_ENTRY *WdsTableLookup(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PUCHAR          pAddr,
-	IN BOOLEAN bResetIdelCount);
-
-MAC_TABLE_ENTRY *FindWdsEntry(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			Wcid,
-	IN PUCHAR			pAddr,
-	IN UINT32			PhyMode);
-
-VOID WdsTableMaintenance(
-    IN PRTMP_ADAPTER    pAd);
-
-VOID RT28xx_WDS_Init(
-	IN PRTMP_ADAPTER pAd,
-	IN PNET_DEV net_dev);
-
-VOID RT28xx_WDS_Close(
-	IN PRTMP_ADAPTER pAd);
-
-VOID RT28xx_WDS_Remove(
-	IN PRTMP_ADAPTER pAd);
-
-VOID WdsDown(
-	IN PRTMP_ADAPTER pAd);
-
-VOID AsicUpdateWdsRxWCIDTable(
-	IN PRTMP_ADAPTER pAd);
-
-VOID AsicUpdateWdsEncryption(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR wcid);
-
-VOID WdsPeerBeaconProc(
-	IN PRTMP_ADAPTER pAd,
-	IN PMAC_TABLE_ENTRY pEntry,
-	IN USHORT CapabilityInfo,
-	IN UCHAR MaxSupportedRateIn500Kbps,
-	IN UCHAR MaxSupportedRateLen,
-	IN BOOLEAN bWmmCapable,
-	IN ULONG ClientRalinkIe,
-	IN HT_CAPABILITY_IE *pHtCapability,
-	IN UCHAR HtCapabilityLen);
-
-VOID APWdsInitialize(
-	IN PRTMP_ADAPTER pAd);
-
-INT	Show_WdsTable_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-VOID rtmp_read_wds_from_file(
-			IN  PRTMP_ADAPTER pAd,
-			PSTRING tmpbuf,
-			PSTRING buffer);
-
-VOID WdsPrepareWepKeyFromMainBss(
-	IN  PRTMP_ADAPTER pAd);
-
-INT WdsVirtualIFSendPackets(
-	IN PNDIS_PACKET pSkb,
-	IN PNET_DEV dev);
-
-INT WdsVirtualIF_open(
-	IN PNET_DEV dev);
-
-INT WdsVirtualIF_close(
-	IN PNET_DEV dev);
-
-INT WdsVirtualIF_ioctl(
-	IN PNET_DEV net_dev,
-	IN OUT struct ifreq *rq,
-	IN INT cmd);
-
-/*
-	==========================================================================
-	Description:
-		Check the WDS Entry is valid or not.
-	==========================================================================
- */
-static inline BOOLEAN ValidWdsEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR WdsIndex)
-{
-	BOOLEAN result;
-	PMAC_TABLE_ENTRY pMacEntry;
-
-	do
-	{
-		if (WdsIndex >= MAX_WDS_ENTRY)
-		{
-			result = FALSE;
-			break;
-		}
-
-		if (pAd->WdsTab.WdsEntry[WdsIndex].Valid != TRUE)
-		{
-			result = FALSE;
-			break;
-		}
-
-		if ((pAd->WdsTab.WdsEntry[WdsIndex].MacTabMatchWCID==0)
-			|| (pAd->WdsTab.WdsEntry[WdsIndex].MacTabMatchWCID >= MAX_LEN_OF_MAC_TABLE))
-		{
-			result = FALSE;
-			break;
-		}
-
-		pMacEntry = &pAd->MacTab.Content[pAd->WdsTab.WdsEntry[WdsIndex].MacTabMatchWCID];
-		if (pMacEntry->ValidAsWDS != TRUE)
-		{
-			result = FALSE;
-			break;
-		}
-
-		result = TRUE;
-	} while(FALSE);
-
-	return result;
-}
-#endif // _AP_WDS_H_ //
diff --git a/drivers/staging/rt3090/chips/rt3090.c b/drivers/staging/rt3090/chips/rt3090.c
deleted file mode 100644
index 35c549d..0000000
--- a/drivers/staging/rt3090/chips/rt3090.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rt3090.c
-
-	Abstract:
-	Specific funcitons and variables for RT3070
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-*/
-
-#ifdef RT3090
-
-#include "../rt_config.h"
-
-
-#ifndef RTMP_RF_RW_SUPPORT
-#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip"
-#endif // RTMP_RF_RW_SUPPORT //
-
-
-VOID NICInitRT3090RFRegisters(IN PRTMP_ADAPTER pAd)
-{
-		INT i;
-	// Driver must read EEPROM to get RfIcType before initial RF registers
-	// Initialize RF register to default value
-	if (IS_RT3090(pAd))
-	{
-		// Init RF calibration
-		// Driver should toggle RF R30 bit7 before init RF registers
-		UINT32 RfReg = 0, data;
-
-		RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RfReg);
-		RfReg |= 0x80;
-		RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
-		RTMPusecDelay(1000);
-		RfReg &= 0x7F;
-		RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
-
-		// init R24, R31
-		RT30xxWriteRFRegister(pAd, RF_R24, 0x0F);
-		RT30xxWriteRFRegister(pAd, RF_R31, 0x0F);
-
-		// RT309x version E has fixed this issue
-		if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
-		{
-			// patch tx EVM issue temporarily
-			RTMP_IO_READ32(pAd, LDO_CFG0, &data);
-			data = ((data & 0xE0FFFFFF) | 0x0D000000);
-			RTMP_IO_WRITE32(pAd, LDO_CFG0, data);
-		}
-		else
-		{
-			RTMP_IO_READ32(pAd, LDO_CFG0, &data);
-			data = ((data & 0xE0FFFFFF) | 0x01000000);
-			RTMP_IO_WRITE32(pAd, LDO_CFG0, data);
-		}
-
-		// patch LNA_PE_G1 failed issue
-		RTMP_IO_READ32(pAd, GPIO_SWITCH, &data);
-		data &= ~(0x20);
-		RTMP_IO_WRITE32(pAd, GPIO_SWITCH, data);
-
-		// Initialize RF register to default value
-		for (i = 0; i < NUM_RF_REG_PARMS; i++)
-		{
-			RT30xxWriteRFRegister(pAd, RT30xx_RFRegTable[i].Register, RT30xx_RFRegTable[i].Value);
-		}
-
-		// Driver should set RF R6 bit6 on before calibration
-		RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RfReg);
-		RfReg |= 0x40;
-		RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RfReg);
-
-		//For RF filter Calibration
-		RTMPFilterCalibration(pAd);
-
-		// Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration()
-		if ((pAd->MACVersion & 0xffff) < 0x0211)
-			RT30xxWriteRFRegister(pAd, RF_R27, 0x3);
-
-		// set led open drain enable
-		RTMP_IO_READ32(pAd, OPT_14, &data);
-		data |= 0x01;
-		RTMP_IO_WRITE32(pAd, OPT_14, data);
-
-		// set default antenna as main
-		if (pAd->RfIcType == RFIC_3020)
-			AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
-
-		// add by johnli, RF power sequence setup, load RF normal operation-mode setup
-		RT30xxLoadRFNormalModeSetup(pAd);
-	}
-
-}
-
-#endif // RT3090 //
diff --git a/drivers/staging/rt3090/chips/rt30xx.c b/drivers/staging/rt3090/chips/rt30xx.c
deleted file mode 100644
index 9c8ae00..0000000
--- a/drivers/staging/rt3090/chips/rt30xx.c
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rt30xx.c
-
-	Abstract:
-	Specific funcitons and variables for RT30xx.
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-*/
-
-
-#ifdef RT30xx
-
-
-#ifndef RTMP_RF_RW_SUPPORT
-#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip"
-#endif // RTMP_RF_RW_SUPPORT //
-
-#include "../rt_config.h"
-
-
-//
-// RF register initialization set
-//
-REG_PAIR   RT30xx_RFRegTable[] = {
-        {RF_R04,          0x40},
-        {RF_R05,          0x03},
-        {RF_R06,          0x02},
-        {RF_R07,          0x70},
-        {RF_R09,          0x0F},
-        {RF_R10,          0x41},
-        {RF_R11,          0x21},
-        {RF_R12,          0x7B},
-        {RF_R14,          0x90},
-        {RF_R15,          0x58},
-        {RF_R16,          0xB3},
-        {RF_R17,          0x92},
-        {RF_R18,          0x2C},
-        {RF_R19,          0x02},
-        {RF_R20,          0xBA},
-        {RF_R21,          0xDB},
-        {RF_R24,          0x16},
-        {RF_R25,          0x01},
-        {RF_R29,          0x1F},
-};
-
-UCHAR NUM_RF_REG_PARMS = (sizeof(RT30xx_RFRegTable) / sizeof(REG_PAIR));
-
-
-
-// Antenna divesity use GPIO3 and EESK pin for control
-// Antenna and EEPROM access are both using EESK pin,
-// Therefor we should avoid accessing EESK at the same time
-// Then restore antenna after EEPROM access
-// The original name of this function is AsicSetRxAnt(), now change to
-//VOID AsicSetRxAnt(
-VOID RT30xxSetRxAnt(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			Ant)
-{
-	UINT32	Value;
-	UINT32	x;
-
-	if ((pAd->EepromAccess) ||
-		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS))	||
-		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))	||
-		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) ||
-		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
-	{
-		return;
-	}
-
-	// the antenna selection is through firmware and MAC register(GPIO3)
-	if (Ant == 0)
-	{
-		// Main antenna
-#ifdef RTMP_MAC_PCI
-		RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-		x |= (EESK);
-		RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-#else
-		AsicSendCommandToMcu(pAd, 0x73, 0xFF, 0x1, 0x0);
-#endif // RTMP_MAC_PCI //
-
-		RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
-		Value &= ~(0x0808);
-		RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
-		DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to main antenna\n"));
-	}
-	else
-	{
-		// Aux antenna
-#ifdef RTMP_MAC_PCI
-		RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-		x &= ~(EESK);
-		RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-#else
-		AsicSendCommandToMcu(pAd, 0x73, 0xFF, 0x0, 0x0);
-#endif // RTMP_MAC_PCI //
-		RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
-		Value &= ~(0x0808);
-		Value |= 0x08;
-		RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
-		DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to aux antenna\n"));
-	}
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		For RF filter calibration purpose
-
-	Arguments:
-		pAd                          Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	========================================================================
-*/
-VOID RTMPFilterCalibration(
-	IN PRTMP_ADAPTER pAd)
-{
-	UCHAR	R55x = 0, value, FilterTarget = 0x1E, BBPValue=0;
-	UINT	loop = 0, count = 0, loopcnt = 0, ReTry = 0;
-	UCHAR	RF_R24_Value = 0;
-
-	// Give bbp filter initial value
-	pAd->Mlme.CaliBW20RfR24 = 0x1F;
-	pAd->Mlme.CaliBW40RfR24 = 0x2F; //Bit[5] must be 1 for BW 40
-
-	do
-	{
-		if (loop == 1)	//BandWidth = 40 MHz
-		{
-			// Write 0x27 to RF_R24 to program filter
-			RF_R24_Value = 0x27;
-			RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
-			if (IS_RT3090(pAd) || IS_RT3572(pAd)|| IS_RT3390(pAd))
-				FilterTarget = 0x15;
-			else
-				FilterTarget = 0x19;
-
-			// when calibrate BW40, BBP mask must set to BW40.
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-			BBPValue&= (~0x18);
-			BBPValue|= (0x10);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-
-			// set to BW40
-			RT30xxReadRFRegister(pAd, RF_R31, &value);
-			value |= 0x20;
-			RT30xxWriteRFRegister(pAd, RF_R31, value);
-		}
-		else			//BandWidth = 20 MHz
-		{
-			// Write 0x07 to RF_R24 to program filter
-			RF_R24_Value = 0x07;
-			RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
-			if (IS_RT3090(pAd) || IS_RT3572(pAd)|| IS_RT3390(pAd))
-				FilterTarget = 0x13;
-			else
-				FilterTarget = 0x16;
-
-			// set to BW20
-			RT30xxReadRFRegister(pAd, RF_R31, &value);
-			value &= (~0x20);
-			RT30xxWriteRFRegister(pAd, RF_R31, value);
-		}
-
-		// Write 0x01 to RF_R22 to enable baseband loopback mode
-		RT30xxReadRFRegister(pAd, RF_R22, &value);
-		value |= 0x01;
-		RT30xxWriteRFRegister(pAd, RF_R22, value);
-
-		// Write 0x00 to BBP_R24 to set power & frequency of passband test tone
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
-
-		do
-		{
-			// Write 0x90 to BBP_R25 to transmit test tone
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
-
-			RTMPusecDelay(1000);
-			// Read BBP_R55[6:0] for received power, set R55x = BBP_R55[6:0]
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
-			R55x = value & 0xFF;
-
-		} while ((ReTry++ < 100) && (R55x == 0));
-
-		// Write 0x06 to BBP_R24 to set power & frequency of stopband test tone
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0x06);
-
-		while(TRUE)
-		{
-			// Write 0x90 to BBP_R25 to transmit test tone
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
-
-			//We need to wait for calibration
-			RTMPusecDelay(1000);
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
-			value &= 0xFF;
-			if ((R55x - value) < FilterTarget)
-			{
-				RF_R24_Value ++;
-			}
-			else if ((R55x - value) == FilterTarget)
-			{
-				RF_R24_Value ++;
-				count ++;
-			}
-			else
-			{
-				break;
-			}
-
-			// prevent infinite loop cause driver hang.
-			if (loopcnt++ > 100)
-			{
-				DBGPRINT(RT_DEBUG_ERROR, ("RTMPFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating", loopcnt));
-				break;
-			}
-
-			// Write RF_R24 to program filter
-			RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
-		}
-
-		if (count > 0)
-		{
-			RF_R24_Value = RF_R24_Value - ((count) ? (1) : (0));
-		}
-
-		// Store for future usage
-		if (loopcnt < 100)
-		{
-			if (loop++ == 0)
-			{
-				//BandWidth = 20 MHz
-				pAd->Mlme.CaliBW20RfR24 = (UCHAR)RF_R24_Value;
-			}
-			else
-			{
-				//BandWidth = 40 MHz
-				pAd->Mlme.CaliBW40RfR24 = (UCHAR)RF_R24_Value;
-				break;
-			}
-		}
-		else
-			break;
-
-		RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
-
-		// reset count
-		count = 0;
-	} while(TRUE);
-
-	//
-	// Set back to initial state
-	//
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
-
-	RT30xxReadRFRegister(pAd, RF_R22, &value);
-	value &= ~(0x01);
-	RT30xxWriteRFRegister(pAd, RF_R22, value);
-
-	// set BBP back to BW20
-	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-	BBPValue&= (~0x18);
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n", pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24));
-}
-
-
-// add by johnli, RF power sequence setup
-/*
-	==========================================================================
-	Description:
-
-	Load RF normal operation-mode setup
-
-	==========================================================================
- */
-VOID RT30xxLoadRFNormalModeSetup(
-	IN PRTMP_ADAPTER	pAd)
-{
-	UCHAR RFValue;
-
-	// RX0_PD & TX0_PD, RF R1 register Bit 2 & Bit 3 to 0 and RF_BLOCK_en,RX1_PD & TX1_PD, Bit0, Bit 4 & Bit5 to 1
-	RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
-	RFValue = (RFValue & (~0x0C)) | 0x31;
-	RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
-
-	// TX_LO2_en, RF R15 register Bit 3 to 0
-	RT30xxReadRFRegister(pAd, RF_R15, &RFValue);
-	RFValue &= (~0x08);
-	RT30xxWriteRFRegister(pAd, RF_R15, RFValue);
-
-	/* move to NICInitRT30xxRFRegisters
-	// TX_LO1_en, RF R17 register Bit 3 to 0
-	RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
-	RFValue &= (~0x08);
-	// to fix rx long range issue
-	if (((pAd->MACVersion & 0xffff) >= 0x0211) && (pAd->NicConfig2.field.ExternalLNAForG == 0))
-	{
-		RFValue |= 0x20;
-	}
-	// set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h
-	if (pAd->TxMixerGain24G >= 2)
-	{
-		RFValue &= (~0x7);  // clean bit [2:0]
-		RFValue |= pAd->TxMixerGain24G;
-	}
-	RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
-	*/
-
-	// RX_LO1_en, RF R20 register Bit 3 to 0
-	RT30xxReadRFRegister(pAd, RF_R20, &RFValue);
-	RFValue &= (~0x08);
-	RT30xxWriteRFRegister(pAd, RF_R20, RFValue);
-
-	// RX_LO2_en, RF R21 register Bit 3 to 0
-	RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
-	RFValue &= (~0x08);
-	RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
-
-	/* add by johnli, reset RF_R27 when interface down & up to fix throughput problem*/
-	// LDORF_VC, RF R27 register Bit 2 to 0
-	RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
-	// TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F).
-	// Raising RF voltage is no longer needed for RT3070(F)
-	if (IS_RT3090(pAd))	// RT309x and RT3071/72
-	{
-		if ((pAd->MACVersion & 0xffff) < 0x0211)
-			RFValue = (RFValue & (~0x77)) | 0x3;
-		else
-			RFValue = (RFValue & (~0x77));
-		RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
-	}
-	/* end johnli */
-}
-
-/*
-	==========================================================================
-	Description:
-
-	Load RF sleep-mode setup
-
-	==========================================================================
- */
-VOID RT30xxLoadRFSleepModeSetup(
-	IN PRTMP_ADAPTER	pAd)
-{
-	UCHAR RFValue;
-	UINT32 MACValue;
-
-
-	{
-		// RF_BLOCK_en. RF R1 register Bit 0 to 0
-		RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
-		RFValue &= (~0x01);
-		RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
-
-		// VCO_IC, RF R7 register Bit 4 & Bit 5 to 0
-		RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
-		RFValue &= (~0x30);
-		RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
-
-		// Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 0
-		RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
-		RFValue &= (~0x0E);
-		RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
-
-		// RX_CTB_en, RF R21 register Bit 7 to 0
-		RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
-		RFValue &= (~0x80);
-		RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
-	}
-
-	if (IS_RT3090(pAd) ||	// IS_RT3090 including RT309x and RT3071/72
-		IS_RT3572(pAd) ||
-		(IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201)))
-	{
-		{
-			RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
-			RFValue |= 0x77;
-			RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
-		}
-
-		RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
-		MACValue |= 0x1D000000;
-		RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-
-	Reverse RF sleep-mode setup
-
-	==========================================================================
- */
-VOID RT30xxReverseRFSleepModeSetup(
-	IN PRTMP_ADAPTER	pAd)
-{
-	UCHAR RFValue;
-	UINT32 MACValue;
-
-	{
-		// RF_BLOCK_en, RF R1 register Bit 0 to 1
-		RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
-		RFValue |= 0x01;
-		RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
-
-		// VCO_IC, RF R7 register Bit 4 & Bit 5 to 1
-		RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
-		RFValue |= 0x30;
-		RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
-
-		// Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1
-		RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
-		RFValue |= 0x0E;
-		RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
-
-		// RX_CTB_en, RF R21 register Bit 7 to 1
-		RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
-		RFValue |= 0x80;
-		RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
-	}
-
-	if (IS_RT3090(pAd) ||	// IS_RT3090 including RT309x and RT3071/72
-		IS_RT3572(pAd) ||
-		IS_RT3390(pAd) ||
-		(IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201)))
-	{
-		{
-			RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
-			if ((pAd->MACVersion & 0xffff) < 0x0211)
-				RFValue = (RFValue & (~0x77)) | 0x3;
-			else
-				RFValue = (RFValue & (~0x77));
-			RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
-		}
-
-		// RT3071 version E has fixed this issue
-		if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
-		{
-			// patch tx EVM issue temporarily
-			RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
-			MACValue = ((MACValue & 0xE0FFFFFF) | 0x0D000000);
-			RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
-		}
-		else
-		{
-			RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
-			MACValue = ((MACValue & 0xE0FFFFFF) | 0x01000000);
-			RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
-		}
-	}
-
-	if(IS_RT3572(pAd))
-		RT30xxWriteRFRegister(pAd, RF_R08, 0x80);
-}
-// end johnli
-
-VOID RT30xxHaltAction(
-	IN PRTMP_ADAPTER	pAd)
-{
-	UINT32		TxPinCfg = 0x00050F0F;
-
-	//
-	// Turn off LNA_PE or TRSW_POL
-	//
-	if (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3572(pAd))
-	{
-		if ((IS_RT3071(pAd) || IS_RT3572(pAd))
-#ifdef RTMP_EFUSE_SUPPORT
-			&& (pAd->bUseEfuse)
-#endif // RTMP_EFUSE_SUPPORT //
-			)
-		{
-			TxPinCfg &= 0xFFFBF0F0; // bit18 off
-		}
-		else
-		{
-			TxPinCfg &= 0xFFFFF0F0;
-		}
-
-		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
-	}
-}
-
-#endif // RT30xx //
diff --git a/drivers/staging/rt3090/chips/rt3370.c b/drivers/staging/rt3090/chips/rt3370.c
deleted file mode 100644
index 38ecb06..0000000
--- a/drivers/staging/rt3090/chips/rt3370.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rt3370.c
-
-	Abstract:
-	Specific funcitons and variables for RT30xx.
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-*/
-
-#ifdef RT3370
-
-#include "../rt_config.h"
-
-
-#ifndef RTMP_RF_RW_SUPPORT
-#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip"
-#endif // RTMP_RF_RW_SUPPORT //
-
-
-VOID NICInitRT3370RFRegisters(IN PRTMP_ADAPTER pAd)
-{
-		INT i;
-	// Driver must read EEPROM to get RfIcType before initial RF registers
-	// Initialize RF register to default value
-	if (IS_RT3090(pAd)||IS_RT3390(pAd)||IS_RT3572(pAd))
-	{
-		// Init RF calibration
-		// Driver should toggle RF R30 bit7 before init RF registers
-		UINT32 RfReg = 0, data;
-
-		RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RfReg);
-		RfReg |= 0x80;
-		RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
-		RTMPusecDelay(1000);
-		RfReg &= 0x7F;
-		RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
-
-		// init R24, R31
-		RT30xxWriteRFRegister(pAd, RF_R24, 0x0F);
-		RT30xxWriteRFRegister(pAd, RF_R31, 0x0F);
-
-		if (IS_RT3390(pAd))
-		{
-			// patch LNA_PE_G1 failed issue
-			RTMP_IO_READ32(pAd, GPIO_SWITCH, &data);
-			data &= ~(0x20);
-			RTMP_IO_WRITE32(pAd, GPIO_SWITCH, data);
-
-			// RF registers initialization
-			for (i = 0; i < NUM_RF_REG_PARMS_OVER_RT3390; i++)
-			{
-				RT30xxWriteRFRegister(pAd, RFRegTableOverRT3390[i].Register, RFRegTableOverRT3390[i].Value);
-			}
-		}
-
-		// patch LNA_PE_G1 failed issue
-		RTMP_IO_READ32(pAd, GPIO_SWITCH, &data);
-		data &= ~(0x20);
-		RTMP_IO_WRITE32(pAd, GPIO_SWITCH, data);
-
-		// Initialize RF register to default value
-		for (i = 0; i < NUM_RF_REG_PARMS_OVER_RT3390; i++)
-		{
-			RT30xxWriteRFRegister(pAd, RT30xx_RFRegTable[i].Register, RT30xx_RFRegTable[i].Value);
-		}
-
-		// Driver should set RF R6 bit6 on before calibration
-		RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RfReg);
-		RfReg |= 0x40;
-		RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RfReg);
-
-		//For RF filter Calibration
-		RTMPFilterCalibration(pAd);
-
-		// Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration()
-		if ((pAd->MACVersion & 0xffff) < 0x0211)
-			RT30xxWriteRFRegister(pAd, RF_R27, 0x3);
-
-		// set led open drain enable
-		RTMP_IO_READ32(pAd, OPT_14, &data);
-		data |= 0x01;
-		RTMP_IO_WRITE32(pAd, OPT_14, data);
-
-		// set default antenna as main
-		if (pAd->RfIcType == RFIC_3020)
-			AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
-
-		// add by johnli, RF power sequence setup, load RF normal operation-mode setup
-		RT30xxLoadRFNormalModeSetup(pAd);
-	}
-
-}
-#endif // RT3070 //
diff --git a/drivers/staging/rt3090/chips/rt3390.c b/drivers/staging/rt3090/chips/rt3390.c
deleted file mode 100644
index afed9e7..0000000
--- a/drivers/staging/rt3090/chips/rt3390.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rt3390.c
-
-	Abstract:
-	Specific funcitons and variables for RT30xx.
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-*/
-
-#ifdef RT3390
-
-#include "../rt_config.h"
-
-
-#ifndef RTMP_RF_RW_SUPPORT
-#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip"
-#endif // RTMP_RF_RW_SUPPORT //
-
-
-VOID NICInitRT3390RFRegisters(IN PRTMP_ADAPTER pAd)
-{
-		INT i;
-	// Driver must read EEPROM to get RfIcType before initial RF registers
-	// Initialize RF register to default value
-	if (IS_RT3090(pAd)||IS_RT3390(pAd)||IS_RT3572(pAd))
-	{
-		// Init RF calibration
-		// Driver should toggle RF R30 bit7 before init RF registers
-		UINT32 RfReg = 0, data;
-
-		RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RfReg);
-		RfReg |= 0x80;
-		RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
-		RTMPusecDelay(1000);
-		RfReg &= 0x7F;
-		RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
-
-		// init R24, R31
-		RT30xxWriteRFRegister(pAd, RF_R24, 0x0F);
-		RT30xxWriteRFRegister(pAd, RF_R31, 0x0F);
-
-		if (IS_RT3390(pAd))
-		{
-			// patch LNA_PE_G1 failed issue
-			RTMP_IO_READ32(pAd, GPIO_SWITCH, &data);
-			data &= ~(0x20);
-			RTMP_IO_WRITE32(pAd, GPIO_SWITCH, data);
-
-			// RF registers initialization
-			for (i = 0; i < NUM_RF_REG_PARMS_OVER_RT3390; i++)
-			{
-				RT30xxWriteRFRegister(pAd, RFRegTableOverRT3390[i].Register, RFRegTableOverRT3390[i].Value);
-			}
-		}
-
-		// patch LNA_PE_G1 failed issue
-		RTMP_IO_READ32(pAd, GPIO_SWITCH, &data);
-		data &= ~(0x20);
-		RTMP_IO_WRITE32(pAd, GPIO_SWITCH, data);
-
-		// Initialize RF register to default value
-		for (i = 0; i < NUM_RF_REG_PARMS_OVER_RT3390; i++)
-		{
-			RT30xxWriteRFRegister(pAd, RFRegTableOverRT3390[i].Register, RFRegTableOverRT3390[i].Value);
-		}
-
-		// Driver should set RF R6 bit6 on before calibration
-		RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RfReg);
-		RfReg |= 0x40;
-		RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RfReg);
-
-		//For RF filter Calibration
-		RTMPFilterCalibration(pAd);
-
-		// Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration()
-		if ((pAd->MACVersion & 0xffff) < 0x0211)
-			RT30xxWriteRFRegister(pAd, RF_R27, 0x3);
-
-		// set led open drain enable
-		RTMP_IO_READ32(pAd, OPT_14, &data);
-		data |= 0x01;
-		RTMP_IO_WRITE32(pAd, OPT_14, data);
-
-		// set default antenna as main
-		if (pAd->RfIcType == RFIC_3020)
-			AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
-
-		// add by johnli, RF power sequence setup, load RF normal operation-mode setup
-		RT33xxLoadRFNormalModeSetup(pAd);
-	}
-
-}
-
-#endif // RT3390 //
diff --git a/drivers/staging/rt3090/chips/rt33xx.c b/drivers/staging/rt3090/chips/rt33xx.c
deleted file mode 100644
index 56f376c..0000000
--- a/drivers/staging/rt3090/chips/rt33xx.c
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rt33xx.c
-
-	Abstract:
-	Specific funcitons and variables for RT30xx.
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-*/
-
-
-#ifdef RT33xx
-
-
-#ifndef RTMP_RF_RW_SUPPORT
-#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip"
-#endif // RTMP_RF_RW_SUPPORT //
-
-#include "../rt_config.h"
-
-
-//
-// RF register initialization set
-//
-REG_PAIR RFRegTableOverRT3390[] = {
-	{RF_R00,		0xA0},
-	{RF_R01,		0xE1},
-	{RF_R02,		0xF1},
-	{RF_R03,		0x62},
-	{RF_R04,		0x40},
-	{RF_R05,		0x8B},
-	{RF_R06,		0x42},
-	{RF_R07,		0x34},
-	{RF_R08,		0x00}, // Read only
-	{RF_R09,		0xC0},
-
-	{RF_R10,		0x61},
-	{RF_R11,		0x21},
-	{RF_R12,		0x3B},
-	{RF_R13,		0xE0},
-	{RF_R14,		0x90},
-	{RF_R15,		0x53},
-	{RF_R16,		0x0E},
-	{RF_R17,		0x94},
-	{RF_R18,		0x5C},
-	{RF_R19,		0x4A},
-
-	{RF_R20,		0xB2},
-	{RF_R21,		0xF6},
-	{RF_R22,		0x00},
-	{RF_R23,		0x14},
-	{RF_R24,		0x08},
-	{RF_R25,		0x3D},
-	{RF_R26,		0x85},
-	{RF_R27,		0x00},
-	{RF_R28,		0x41},
-	{RF_R29,		0x8F},
-	{RF_R30,		0x20},
-	{RF_R31,		0x0F},
-};
-
-UCHAR NUM_RF_REG_PARMS_OVER_RT3390=(sizeof(RFRegTableOverRT3390) / sizeof(REG_PAIR));
-
-
-
-// Antenna divesity use GPIO3 and EESK pin for control
-// Antenna and EEPROM access are both using EESK pin,
-// Therefor we should avoid accessing EESK at the same time
-// Then restore antenna after EEPROM access
-// The original name of this function is AsicSetRxAnt(), now change to
-//VOID AsicSetRxAnt(
-
-VOID RT33xxSetRxAnt(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			Ant)
-{
-	UINT32	Value;
-	UINT32	x;
-
-	if ((pAd->EepromAccess) ||
-		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS))	||
-		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))	||
-		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) ||
-		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
-	{
-		return;
-	}
-
-	// the antenna selection is through firmware and MAC register(GPIO3)
-	if (Ant == 0)
-	{
-		// Main antenna
-		RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-		x |= (EESK);
-		RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-		RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
-		Value &= ~(0x0808);
-		RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
-		DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to main antenna\n"));
-	}
-	else
-	{
-		// Aux antenna
-		RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-		x &= ~(EESK);
-		RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-		RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
-		Value &= ~(0x0808);
-		Value |= 0x08;
-		RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
-		DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to aux antenna\n"));
-	}
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		For RF filter calibration purpose
-
-	Arguments:
-		pAd                          Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	========================================================================
-*/
-VOID RTMPFilterCalibration(
-	IN PRTMP_ADAPTER pAd)
-{
-	UCHAR	R55x = 0, value, FilterTarget = 0x1E, BBPValue=0;
-	UINT	loop = 0, count = 0, loopcnt = 0, ReTry = 0;
-	UCHAR	RF_R24_Value = 0;
-
-	// Give bbp filter initial value
-	pAd->Mlme.CaliBW20RfR24 = 0x1F;
-	pAd->Mlme.CaliBW40RfR24 = 0x2F; //Bit[5] must be 1 for BW 40
-
-	do
-	{
-		if (loop == 1)	//BandWidth = 40 MHz
-		{
-			// Write 0x27 to RF_R24 to program filter
-			RF_R24_Value = 0x27;
-			RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
-			if (IS_RT3090(pAd) || IS_RT3572(pAd)|| IS_RT3390(pAd))
-				FilterTarget = 0x15;
-			else
-				FilterTarget = 0x19;
-
-			// when calibrate BW40, BBP mask must set to BW40.
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-			BBPValue&= (~0x18);
-			BBPValue|= (0x10);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-
-			// set to BW40
-			RT30xxReadRFRegister(pAd, RF_R31, &value);
-			value |= 0x20;
-			RT30xxWriteRFRegister(pAd, RF_R31, value);
-		}
-		else			//BandWidth = 20 MHz
-		{
-			// Write 0x07 to RF_R24 to program filter
-			RF_R24_Value = 0x07;
-			RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
-			if (IS_RT3090(pAd) || IS_RT3572(pAd)|| IS_RT3390(pAd))
-				FilterTarget = 0x13;
-			else
-				FilterTarget = 0x16;
-
-			// set to BW20
-			RT30xxReadRFRegister(pAd, RF_R31, &value);
-			value &= (~0x20);
-			RT30xxWriteRFRegister(pAd, RF_R31, value);
-		}
-
-		// Write 0x01 to RF_R22 to enable baseband loopback mode
-		RT30xxReadRFRegister(pAd, RF_R22, &value);
-		value |= 0x01;
-		RT30xxWriteRFRegister(pAd, RF_R22, value);
-
-		// Write 0x00 to BBP_R24 to set power & frequency of passband test tone
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
-
-		do
-		{
-			// Write 0x90 to BBP_R25 to transmit test tone
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
-
-			RTMPusecDelay(1000);
-			// Read BBP_R55[6:0] for received power, set R55x = BBP_R55[6:0]
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
-			R55x = value & 0xFF;
-
-		} while ((ReTry++ < 100) && (R55x == 0));
-
-		// Write 0x06 to BBP_R24 to set power & frequency of stopband test tone
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0x06);
-
-		while(TRUE)
-		{
-			// Write 0x90 to BBP_R25 to transmit test tone
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
-
-			//We need to wait for calibration
-			RTMPusecDelay(1000);
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
-			value &= 0xFF;
-			if ((R55x - value) < FilterTarget)
-			{
-				RF_R24_Value ++;
-			}
-			else if ((R55x - value) == FilterTarget)
-			{
-				RF_R24_Value ++;
-				count ++;
-			}
-			else
-			{
-				break;
-			}
-
-			// prevent infinite loop cause driver hang.
-			if (loopcnt++ > 100)
-			{
-				DBGPRINT(RT_DEBUG_ERROR, ("RTMPFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating", loopcnt));
-				break;
-			}
-
-			// Write RF_R24 to program filter
-			RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
-		}
-
-		if (count > 0)
-		{
-			RF_R24_Value = RF_R24_Value - ((count) ? (1) : (0));
-		}
-
-		// Store for future usage
-		if (loopcnt < 100)
-		{
-			if (loop++ == 0)
-			{
-				//BandWidth = 20 MHz
-				pAd->Mlme.CaliBW20RfR24 = (UCHAR)RF_R24_Value;
-			}
-			else
-			{
-				//BandWidth = 40 MHz
-				pAd->Mlme.CaliBW40RfR24 = (UCHAR)RF_R24_Value;
-				break;
-			}
-		}
-		else
-			break;
-
-		RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
-
-		// reset count
-		count = 0;
-	} while(TRUE);
-
-	//
-	// Set back to initial state
-	//
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
-
-	RT30xxReadRFRegister(pAd, RF_R22, &value);
-	value &= ~(0x01);
-	RT30xxWriteRFRegister(pAd, RF_R22, value);
-
-	// set BBP back to BW20
-	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-	BBPValue&= (~0x18);
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n", pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24));
-}
-
-
-// add by johnli, RF power sequence setup
-/*
-	==========================================================================
-	Description:
-
-	Load RF normal operation-mode setup
-
-	==========================================================================
- */
-VOID RT33xxLoadRFNormalModeSetup(
-	IN PRTMP_ADAPTER	pAd)
-{
-	UCHAR RFValue;
-
-	// RX0_PD & TX0_PD, RF R1 register Bit 2 & Bit 3 to 0 and RF_BLOCK_en,RX1_PD & TX1_PD, Bit0, Bit 4 & Bit5 to 1
-	RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
-	RFValue = (RFValue & (~0x0C)) | 0x31;
-	RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
-
-	// TX_LO2_en, RF R15 register Bit 3 to 0
-	RT30xxReadRFRegister(pAd, RF_R15, &RFValue);
-	RFValue &= (~0x08);
-	RT30xxWriteRFRegister(pAd, RF_R15, RFValue);
-
-	/* move to NICInitRT30xxRFRegisters
-	// TX_LO1_en, RF R17 register Bit 3 to 0
-	RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
-	RFValue &= (~0x08);
-	// to fix rx long range issue
-	if (((pAd->MACVersion & 0xffff) >= 0x0211) && (pAd->NicConfig2.field.ExternalLNAForG == 0))
-	{
-		RFValue |= 0x20;
-	}
-	// set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h
-	if (pAd->TxMixerGain24G >= 2)
-	{
-		RFValue &= (~0x7);  // clean bit [2:0]
-		RFValue |= pAd->TxMixerGain24G;
-	}
-	RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
-	*/
-
-	// RX_LO1_en, RF R20 register Bit 3 to 0
-	RT30xxReadRFRegister(pAd, RF_R20, &RFValue);
-	RFValue &= (~0x08);
-	RT30xxWriteRFRegister(pAd, RF_R20, RFValue);
-
-	// RX_LO2_en, RF R21 register Bit 3 to 0
-	RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
-	RFValue &= (~0x08);
-	RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
-
-	/* add by johnli, reset RF_R27 when interface down & up to fix throughput problem*/
-	// LDORF_VC, RF R27 register Bit 2 to 0
-	RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
-	// TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F).
-	// Raising RF voltage is no longer needed for RT3070(F)
-	if (IS_RT3090(pAd))	// RT309x and RT3071/72
-	{
-		if ((pAd->MACVersion & 0xffff) < 0x0211)
-			RFValue = (RFValue & (~0x77)) | 0x3;
-		else
-			RFValue = (RFValue & (~0x77));
-		RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
-	}
-	/* end johnli */
-}
-
-/*
-	==========================================================================
-	Description:
-
-	Load RF sleep-mode setup
-
-	==========================================================================
- */
-VOID RT33xxLoadRFSleepModeSetup(
-	IN PRTMP_ADAPTER	pAd)
-{
-	UCHAR RFValue;
-	UINT32 MACValue;
-
-
-	{
-		// RF_BLOCK_en. RF R1 register Bit 0 to 0
-		RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
-		RFValue &= (~0x01);
-		RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
-
-		// VCO_IC, RF R7 register Bit 4 & Bit 5 to 0
-		RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
-		RFValue &= (~0x30);
-		RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
-
-		// Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 0
-		RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
-		RFValue &= (~0x0E);
-		RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
-
-		// RX_CTB_en, RF R21 register Bit 7 to 0
-		RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
-		RFValue &= (~0x80);
-		RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
-	}
-
-	if (IS_RT3090(pAd) ||	// IS_RT3090 including RT309x and RT3071/72
-		IS_RT3572(pAd) ||
-		IS_RT3390(pAd) ||
-		(IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201)))
-	{
-		{
-			RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
-			RFValue |= 0x77;
-			RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
-		}
-
-		RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
-		MACValue |= 0x1D000000;
-		RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-
-	Reverse RF sleep-mode setup
-
-	==========================================================================
- */
-VOID RT33xxReverseRFSleepModeSetup(
-	IN PRTMP_ADAPTER	pAd)
-{
-	UCHAR RFValue;
-	UINT32 MACValue;
-
-	{
-		// RF_BLOCK_en, RF R1 register Bit 0 to 1
-		RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
-		RFValue |= 0x01;
-		RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
-
-		// VCO_IC, RF R7 register Bit 4 & Bit 5 to 1
-		RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
-		RFValue |= 0x30;
-		RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
-
-		// Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1
-		RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
-		RFValue |= 0x0E;
-		RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
-
-		// RX_CTB_en, RF R21 register Bit 7 to 1
-		RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
-		RFValue |= 0x80;
-		RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
-	}
-
-	if (IS_RT3090(pAd) ||	// IS_RT3090 including RT309x and RT3071/72
-		IS_RT3572(pAd) ||
-		IS_RT3390(pAd) ||
-		(IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201)))
-	{
-		{
-			RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
-			if ((pAd->MACVersion & 0xffff) < 0x0211)
-				RFValue = (RFValue & (~0x77)) | 0x3;
-			else
-				RFValue = (RFValue & (~0x77));
-			RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
-		}
-
-		// RT3071 version E has fixed this issue
-		if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
-		{
-			// patch tx EVM issue temporarily
-			RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
-			MACValue = ((MACValue & 0xE0FFFFFF) | 0x0D000000);
-			RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
-		}
-		else
-		{
-			RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
-			MACValue = ((MACValue & 0xE0FFFFFF) | 0x01000000);
-			RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
-		}
-	}
-
-	if(IS_RT3572(pAd))
-		RT30xxWriteRFRegister(pAd, RF_R08, 0x80);
-}
-// end johnli
-
-VOID RT33xxHaltAction(
-	IN PRTMP_ADAPTER	pAd)
-{
-	UINT32		TxPinCfg = 0x00050F0F;
-
-	//
-	// Turn off LNA_PE or TRSW_POL
-	//
-	if (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3390(pAd)||IS_RT3572(pAd))
-	{
-	//KH? Both support 3390 usb and  PCI
-		if ((IS_RT3071(pAd) || IS_RT3572(pAd)||IS_RT3390(pAd))
-#ifdef RTMP_EFUSE_SUPPORT
-			&& (pAd->bUseEfuse)
-#endif // RTMP_EFUSE_SUPPORT //
-			)
-		{
-			TxPinCfg &= 0xFFFBF0F0; // bit18 off
-		}
-		else
-		{
-			TxPinCfg &= 0xFFFFF0F0;
-		}
-
-		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
-	}
-}
-
-#endif // RT30xx //
diff --git a/drivers/staging/rt3090/chlist.h b/drivers/staging/rt3090/chlist.h
deleted file mode 100644
index d03cb47..0000000
--- a/drivers/staging/rt3090/chlist.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    chlist.h
-
-    Abstract:
-    Miniport generic portion header file
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-	Fonchi Wu   2007-12-19    created
-*/
-
-#ifndef __CHLIST_H__
-#define __CHLIST_H__
-
-#include "rtmp_type.h"
-#include "rtmp_def.h"
-
-
-#define ODOR			0
-#define IDOR			1
-#define BOTH			2
-
-#define BAND_5G         0
-#define BAND_24G        1
-#define BAND_BOTH       2
-
-typedef struct _CH_DESP {
-	UCHAR FirstChannel;
-	UCHAR NumOfCh;
-	CHAR MaxTxPwr;			// dBm
-	UCHAR Geography;			// 0:out door, 1:in door, 2:both
-	BOOLEAN DfsReq;			// Dfs require, 0: No, 1: yes.
-} CH_DESP, *PCH_DESP;
-
-typedef struct _CH_REGION {
-	UCHAR CountReg[3];
-	UCHAR DfsType;			// 0: CE, 1: FCC, 2: JAP, 3:JAP_W53, JAP_W56
-	CH_DESP ChDesp[10];
-} CH_REGION, *PCH_REGION;
-
-extern CH_REGION ChRegion[];
-
-typedef struct _CH_FREQ_MAP_{
-	UINT16		channel;
-	UINT16		freqKHz;
-}CH_FREQ_MAP;
-
-extern CH_FREQ_MAP CH_HZ_ID_MAP[];
-extern int CH_HZ_ID_MAP_NUM;
-
-
-#define     MAP_CHANNEL_ID_TO_KHZ(_ch, _khz)					\
-		do{													\
-			int _chIdx;											\
-			for (_chIdx = 0; _chIdx < CH_HZ_ID_MAP_NUM; _chIdx++)\
-			{													\
-				if ((_ch) == CH_HZ_ID_MAP[_chIdx].channel)			\
-				{												\
-					(_khz) = CH_HZ_ID_MAP[_chIdx].freqKHz * 1000;	\
-					break;										\
-				}												\
-			}													\
-			if (_chIdx == CH_HZ_ID_MAP_NUM)					\
-				(_khz) = 2412000;									\
-            }while(0)
-
-#define     MAP_KHZ_TO_CHANNEL_ID(_khz, _ch)                 \
-		do{													\
-			int _chIdx;											\
-			for (_chIdx = 0; _chIdx < CH_HZ_ID_MAP_NUM; _chIdx++)\
-			{													\
-				if ((_khz) == CH_HZ_ID_MAP[_chIdx].freqKHz)			\
-				{												\
-					(_ch) = CH_HZ_ID_MAP[_chIdx].channel;			\
-					break;										\
-				}												\
-			}													\
-			if (_chIdx == CH_HZ_ID_MAP_NUM)					\
-				(_ch) = 1;											\
-		}while(0)
-
-
-VOID BuildChannelListEx(
-	IN PRTMP_ADAPTER pAd);
-
-VOID BuildBeaconChList(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pBuf,
-	OUT	PULONG pBufLen);
-
-#ifdef DOT11_N_SUPPORT
-VOID N_ChannelCheck(
-	IN PRTMP_ADAPTER pAd);
-
-VOID N_SetCenCh(
-	IN PRTMP_ADAPTER pAd);
-#endif // DOT11_N_SUPPORT //
-
-UINT8 GetCuntryMaxTxPwr(
-	IN PRTMP_ADAPTER pAd,
-	IN UINT8 channel);
-
-#endif // __CHLIST_H__
diff --git a/drivers/staging/rt3090/common/action.c b/drivers/staging/rt3090/common/action.c
deleted file mode 100644
index 8e3b0a0..0000000
--- a/drivers/staging/rt3090/common/action.c
+++ /dev/null
@@ -1,1057 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	action.c
-
-    Abstract:
-    Handle association related requests either from WSTA or from local MLME
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-	Jan Lee		2006		created for rt2860
- */
-
-#include "../rt_config.h"
-#include "../action.h"
-
-
-static VOID ReservedAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
-
-
-/*
-    ==========================================================================
-    Description:
-        association state machine init, including state transition and timer init
-    Parameters:
-        S - pointer to the association state machine
-    Note:
-        The state machine looks like the following
-
-                                    ASSOC_IDLE
-        MT2_MLME_DISASSOC_REQ    mlme_disassoc_req_action
-        MT2_PEER_DISASSOC_REQ    peer_disassoc_action
-        MT2_PEER_ASSOC_REQ       drop
-        MT2_PEER_REASSOC_REQ     drop
-        MT2_CLS3ERR              cls3err_action
-    ==========================================================================
- */
-VOID ActionStateMachineInit(
-    IN	PRTMP_ADAPTER	pAd,
-    IN  STATE_MACHINE *S,
-    OUT STATE_MACHINE_FUNC Trans[])
-{
-	StateMachineInit(S, (STATE_MACHINE_FUNC *)Trans, MAX_ACT_STATE, MAX_ACT_MSG, (STATE_MACHINE_FUNC)Drop, ACT_IDLE, ACT_MACHINE_BASE);
-
-	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_SPECTRUM_CATE, (STATE_MACHINE_FUNC)PeerSpectrumAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_QOS_CATE, (STATE_MACHINE_FUNC)PeerQOSAction);
-
-	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE, (STATE_MACHINE_FUNC)ReservedAction);
-#ifdef QOS_DLS_SUPPORT
-		StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE, (STATE_MACHINE_FUNC)PeerDLSAction);
-#endif // QOS_DLS_SUPPORT //
-
-#ifdef DOT11_N_SUPPORT
-	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_BA_CATE, (STATE_MACHINE_FUNC)PeerBAAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_HT_CATE, (STATE_MACHINE_FUNC)PeerHTAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ADD_BA_CATE, (STATE_MACHINE_FUNC)MlmeADDBAAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ORI_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_REC_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction);
-#endif // DOT11_N_SUPPORT //
-
-	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_PUBLIC_CATE, (STATE_MACHINE_FUNC)PeerPublicAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_RM_CATE, (STATE_MACHINE_FUNC)PeerRMAction);
-
-	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_QOS_CATE, (STATE_MACHINE_FUNC)MlmeQOSAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_DLS_CATE, (STATE_MACHINE_FUNC)MlmeDLSAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_ACT_INVALID, (STATE_MACHINE_FUNC)MlmeInvalidAction);
-
-
-}
-
-#ifdef DOT11_N_SUPPORT
-VOID MlmeADDBAAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
-
-{
-	MLME_ADDBA_REQ_STRUCT *pInfo;
-	UCHAR           Addr[6];
-	PUCHAR         pOutBuffer = NULL;
-	NDIS_STATUS     NStatus;
-	ULONG		Idx;
-	FRAME_ADDBA_REQ  Frame;
-	ULONG		FrameLen;
-	BA_ORI_ENTRY			*pBAEntry = NULL;
-
-	pInfo = (MLME_ADDBA_REQ_STRUCT *)Elem->Msg;
-	NdisZeroMemory(&Frame, sizeof(FRAME_ADDBA_REQ));
-
-	if(MlmeAddBAReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr))
-	{
-		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-		if(NStatus != NDIS_STATUS_SUCCESS)
-		{
-			DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeADDBAAction() allocate memory failed \n"));
-			return;
-		}
-		// 1. find entry
-		Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
-		if (Idx == 0)
-		{
-			MlmeFreeMemory(pAd, pOutBuffer);
-			DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() can't find BAOriEntry \n"));
-			return;
-		}
-		else
-		{
-			pBAEntry =&pAd->BATable.BAOriEntry[Idx];
-		}
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			if (ADHOC_ON(pAd))
-				ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
-			else
-#ifdef QOS_DLS_SUPPORT
-			if (pAd->MacTab.Content[pInfo->Wcid].ValidAsDls)
-				ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
-			else
-#endif // QOS_DLS_SUPPORT //
-			ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pInfo->pAddr);
-
-		}
-#endif // CONFIG_STA_SUPPORT //
-
-		Frame.Category = CATEGORY_BA;
-		Frame.Action = ADDBA_REQ;
-		Frame.BaParm.AMSDUSupported = 0;
-		Frame.BaParm.BAPolicy = IMMED_BA;
-		Frame.BaParm.TID = pInfo->TID;
-		Frame.BaParm.BufSize = pInfo->BaBufSize;
-		Frame.Token = pInfo->Token;
-		Frame.TimeOutValue = pInfo->TimeOutValue;
-		Frame.BaStartSeq.field.FragNum = 0;
-		Frame.BaStartSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID];
-
-		*(USHORT *)(&Frame.BaParm) = cpu2le16(*(USHORT *)(&Frame.BaParm));
-		Frame.TimeOutValue = cpu2le16(Frame.TimeOutValue);
-		Frame.BaStartSeq.word = cpu2le16(Frame.BaStartSeq.word);
-
-		MakeOutgoingFrame(pOutBuffer,		   &FrameLen,
-		              sizeof(FRAME_ADDBA_REQ), &Frame,
-		              END_OF_ARGS);
-
-		MiniportMMRequest(pAd, (MGMT_USE_QUEUE_FLAG | MapUserPriorityToAccessCategory[pInfo->TID]), pOutBuffer, FrameLen);
-
-		MlmeFreeMemory(pAd, pOutBuffer);
-
-		DBGPRINT(RT_DEBUG_TRACE, ("BA - Send ADDBA request. StartSeq = %x,  FrameLen = %ld. BufSize = %d\n", Frame.BaStartSeq.field.StartSeq, FrameLen, Frame.BaParm.BufSize));
-    }
-}
-
-/*
-    ==========================================================================
-    Description:
-        send DELBA and delete BaEntry if any
-    Parametrs:
-        Elem - MLME message MLME_DELBA_REQ_STRUCT
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-VOID MlmeDELBAAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
-{
-	MLME_DELBA_REQ_STRUCT *pInfo;
-	PUCHAR         pOutBuffer = NULL;
-	PUCHAR		   pOutBuffer2 = NULL;
-	NDIS_STATUS     NStatus;
-	ULONG		Idx;
-	FRAME_DELBA_REQ  Frame;
-	ULONG		FrameLen;
-	FRAME_BAR	FrameBar;
-
-	pInfo = (MLME_DELBA_REQ_STRUCT *)Elem->Msg;
-	// must send back DELBA
-	NdisZeroMemory(&Frame, sizeof(FRAME_DELBA_REQ));
-	DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo->Initiator));
-
-	if(MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen))
-	{
-		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-		if(NStatus != NDIS_STATUS_SUCCESS)
-		{
-			DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeDELBAAction() allocate memory failed 1. \n"));
-			return;
-		}
-
-		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2);  //Get an unused nonpaged memory
-		if(NStatus != NDIS_STATUS_SUCCESS)
-		{
-			MlmeFreeMemory(pAd, pOutBuffer);
-			DBGPRINT(RT_DEBUG_ERROR, ("BA - MlmeDELBAAction() allocate memory failed 2. \n"));
-			return;
-		}
-
-		// SEND BAR (Send BAR to refresh peer reordering buffer.)
-		Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-			BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress);
-#endif // CONFIG_STA_SUPPORT //
-
-		FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL funciton.
-		FrameBar.StartingSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; // make sure sequence not clear in DEL funciton.
-		FrameBar.BarControl.TID = pInfo->TID; // make sure sequence not clear in DEL funciton.
-		FrameBar.BarControl.ACKPolicy = IMMED_BA; // make sure sequence not clear in DEL funciton.
-		FrameBar.BarControl.Compressed = 1; // make sure sequence not clear in DEL funciton.
-		FrameBar.BarControl.MTID = 0; // make sure sequence not clear in DEL funciton.
-
-		MakeOutgoingFrame(pOutBuffer2,				&FrameLen,
-					  sizeof(FRAME_BAR),	  &FrameBar,
-					  END_OF_ARGS);
-		MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
-		MlmeFreeMemory(pAd, pOutBuffer2);
-		DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n"));
-
-		// SEND DELBA FRAME
-		FrameLen = 0;
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			if (ADHOC_ON(pAd))
-				ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
-			else
-#ifdef QOS_DLS_SUPPORT
-			if (pAd->MacTab.Content[pInfo->Wcid].ValidAsDls)
-				ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
-			else
-#endif // QOS_DLS_SUPPORT //
-			ActHeaderInit(pAd, &Frame.Hdr,  pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[pInfo->Wcid].Addr);
-		}
-#endif // CONFIG_STA_SUPPORT //
-		Frame.Category = CATEGORY_BA;
-		Frame.Action = DELBA;
-		Frame.DelbaParm.Initiator = pInfo->Initiator;
-		Frame.DelbaParm.TID = pInfo->TID;
-		Frame.ReasonCode = 39; // Time Out
-		*(USHORT *)(&Frame.DelbaParm) = cpu2le16(*(USHORT *)(&Frame.DelbaParm));
-		Frame.ReasonCode = cpu2le16(Frame.ReasonCode);
-
-		MakeOutgoingFrame(pOutBuffer,               &FrameLen,
-		              sizeof(FRAME_DELBA_REQ),    &Frame,
-		              END_OF_ARGS);
-		MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-		MlmeFreeMemory(pAd, pOutBuffer);
-		DBGPRINT(RT_DEBUG_TRACE, ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n", pInfo->Initiator));
-	}
-}
-#endif // DOT11_N_SUPPORT //
-
-VOID MlmeQOSAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
-{
-}
-
-VOID MlmeDLSAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
-{
-}
-
-VOID MlmeInvalidAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
-{
-	//PUCHAR		   pOutBuffer = NULL;
-	//Return the receiving frame except the MSB of category filed set to 1.  7.3.1.11
-}
-
-VOID PeerQOSAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-}
-
-#ifdef QOS_DLS_SUPPORT
-VOID PeerDLSAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	UCHAR	Action = Elem->Msg[LENGTH_802_11+1];
-
-	switch(Action)
-	{
-		case ACTION_DLS_REQUEST:
-#ifdef CONFIG_STA_SUPPORT
-			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-			PeerDlsReqAction(pAd, Elem);
-#endif // CONFIG_STA_SUPPORT //
-			break;
-
-		case ACTION_DLS_RESPONSE:
-#ifdef CONFIG_STA_SUPPORT
-			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-			PeerDlsRspAction(pAd, Elem);
-#endif // CONFIG_STA_SUPPORT //
-			break;
-
-		case ACTION_DLS_TEARDOWN:
-#ifdef CONFIG_STA_SUPPORT
-			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-			PeerDlsTearDownAction(pAd, Elem);
-#endif // CONFIG_STA_SUPPORT //
-			break;
-	}
-}
-#endif // QOS_DLS_SUPPORT //
-
-
-
-#ifdef DOT11_N_SUPPORT
-VOID PeerBAAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	UCHAR	Action = Elem->Msg[LENGTH_802_11+1];
-
-	switch(Action)
-	{
-		case ADDBA_REQ:
-			PeerAddBAReqAction(pAd,Elem);
-			break;
-		case ADDBA_RESP:
-			PeerAddBARspAction(pAd,Elem);
-			break;
-		case DELBA:
-			PeerDelBAAction(pAd,Elem);
-			break;
-	}
-}
-
-
-#ifdef DOT11N_DRAFT3
-
-#ifdef CONFIG_STA_SUPPORT
-VOID StaPublicAction(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR Bss2040Coexist)
-{
-	BSS_2040_COEXIST_IE		BssCoexist;
-	MLME_SCAN_REQ_STRUCT			ScanReq;
-
-	BssCoexist.word = Bss2040Coexist;
-	// AP asks Station to return a 20/40 BSS Coexistence mgmt frame.  So we first starts a scan, then send back 20/40 BSS Coexistence mgmt frame
-	if ((BssCoexist.field.InfoReq == 1) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SCAN_2040)))
-	{
-		// Clear record first.  After scan , will update those bit and send back to transmiter.
-		pAd->CommonCfg.BSSCoexist2040.field.InfoReq = 1;
-		pAd->CommonCfg.BSSCoexist2040.field.Intolerant40 = 0;
-		pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq = 0;
-		// Fill out stuff for scan request
-		ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_2040_BSS_COEXIST);
-		MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
-		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
-	}
-}
-
-
-/*
-Description : Build Intolerant Channel Rerpot from Trigger event table.
-return : how many bytes copied.
-*/
-ULONG BuildIntolerantChannelRep(
-	IN	PRTMP_ADAPTER	pAd,
-	IN    PUCHAR  pDest)
-{
-	ULONG			FrameLen = 0;
-	ULONG			ReadOffset = 0;
-	UCHAR			i;
-	UCHAR			LastRegClass = 0xff;
-	PUCHAR			pLen;
-
-	for ( i = 0;i < MAX_TRIGGER_EVENT;i++)
-	{
-		if (pAd->CommonCfg.TriggerEventTab.EventA[i].bValid == TRUE)
-		{
-			if (pAd->CommonCfg.TriggerEventTab.EventA[i].RegClass == LastRegClass)
-			{
-				*(pDest + ReadOffset) = (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel;
-				*pLen++;
-				ReadOffset++;
-				FrameLen++;
-			}
-			else
-			{
-				*(pDest + ReadOffset) = IE_2040_BSS_INTOLERANT_REPORT;  // IE
-				*(pDest + ReadOffset + 1) = 2;	// Len = RegClass byte + channel byte.
-				pLen = pDest + ReadOffset + 1;
-				LastRegClass = pAd->CommonCfg.TriggerEventTab.EventA[i].RegClass;
-				*(pDest + ReadOffset + 2) = LastRegClass;	// Len = RegClass byte + channel byte.
-				*(pDest + ReadOffset + 3) = (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel;
-				FrameLen += 4;
-				ReadOffset += 4;
-			}
-
-		}
-	}
-	return FrameLen;
-}
-
-
-/*
-Description : Send 20/40 BSS Coexistence Action frame If one trigger event is triggered.
-*/
-VOID Send2040CoexistAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN    UCHAR  Wcid,
-	IN	BOOLEAN	bAddIntolerantCha)
-{
-	PUCHAR			pOutBuffer = NULL;
-	NDIS_STATUS	NStatus;
-	FRAME_ACTION_HDR	Frame;
-	ULONG			FrameLen;
-	ULONG			IntolerantChaRepLen;
-
-	IntolerantChaRepLen = 0;
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-	if(NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction() allocate memory failed \n"));
-		return;
-	}
-	ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[Wcid].Addr, pAd->CommonCfg.Bssid);
-	Frame.Category = CATEGORY_PUBLIC;
-	Frame.Action = ACTION_BSS_2040_COEXIST;
-
-	MakeOutgoingFrame(pOutBuffer,				&FrameLen,
-				  sizeof(FRAME_ACTION_HDR),	  &Frame,
-				  END_OF_ARGS);
-
-	*(pOutBuffer + FrameLen) = pAd->CommonCfg.BSSCoexist2040.word;
-	FrameLen++;
-
-	if (bAddIntolerantCha == TRUE)
-		IntolerantChaRepLen = BuildIntolerantChannelRep(pAd, pOutBuffer + FrameLen);
-
-	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen + IntolerantChaRepLen);
-	DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction( BSSCoexist2040 = 0x%x )  \n", pAd->CommonCfg.BSSCoexist2040.word));
-
-}
-
-
-/*
-	==========================================================================
-	Description:
-	After scan, Update 20/40 BSS Coexistence IE and send out.
-	According to 802.11n D3.03 11.14.10
-
-	Parameters:
-	==========================================================================
- */
-VOID Update2040CoexistFrameAndNotify(
-	IN	PRTMP_ADAPTER	pAd,
-	IN    UCHAR  Wcid,
-	IN	BOOLEAN	bAddIntolerantCha)
-{
-	BSS_2040_COEXIST_IE	OldValue;
-
-	OldValue.word = pAd->CommonCfg.BSSCoexist2040.word;
-	if ((pAd->CommonCfg.TriggerEventTab.EventANo > 0) || (pAd->CommonCfg.TriggerEventTab.EventBCountDown > 0))
-		pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq = 1;
-
-	// Need to check !!!!
-	// How STA will set Intolerant40 if implementation dependent. Now we don't set this bit first.!!!!!
-	// So Only check BSS20WidthReq change.
-	if (OldValue.field.BSS20WidthReq != pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq)
-	{
-		Send2040CoexistAction(pAd, Wcid, bAddIntolerantCha);
-	}
-}
-#endif // CONFIG_STA_SUPPORT //
-
-
-BOOLEAN ChannelSwitchSanityCheck(
-	IN	PRTMP_ADAPTER	pAd,
-	IN    UCHAR  Wcid,
-	IN    UCHAR  NewChannel,
-	IN    UCHAR  Secondary)
-{
-	UCHAR		i;
-
-	if (Wcid >= MAX_LEN_OF_MAC_TABLE)
-		return FALSE;
-
-	if ((NewChannel > 7) && (Secondary == 1))
-		return FALSE;
-
-	if ((NewChannel < 5) && (Secondary == 3))
-		return FALSE;
-
-	// 0. Check if new channel is in the channellist.
-	for (i = 0;i < pAd->ChannelListNum;i++)
-	{
-		if (pAd->ChannelList[i].Channel == NewChannel)
-		{
-			break;
-		}
-	}
-
-	if (i == pAd->ChannelListNum)
-		return FALSE;
-
-	return TRUE;
-}
-
-
-VOID ChannelSwitchAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN    UCHAR  Wcid,
-	IN    UCHAR  NewChannel,
-	IN    UCHAR  Secondary)
-{
-	UCHAR		BBPValue = 0;
-	ULONG		MACValue;
-
-	DBGPRINT(RT_DEBUG_TRACE,("SPECTRUM - ChannelSwitchAction(NewChannel = %d , Secondary = %d)  \n", NewChannel, Secondary));
-
-	if (ChannelSwitchSanityCheck(pAd, Wcid, NewChannel, Secondary) == FALSE)
-		return;
-
-	// 1.  Switches to BW = 20.
-	if (Secondary == 0)
-	{
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-		BBPValue&= (~0x18);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-		if (pAd->MACVersion == 0x28600100)
-		{
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
-			DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
-		}
-		pAd->CommonCfg.BBPCurrentBW = BW_20;
-		pAd->CommonCfg.Channel = NewChannel;
-		pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
-		AsicSwitchChannel(pAd, pAd->CommonCfg.Channel,FALSE);
-		AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-		pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 0;
-		DBGPRINT(RT_DEBUG_TRACE, ("!!!20MHz   !!! \n" ));
-	}
-	// 1.  Switches to BW = 40 And Station supports BW = 40.
-	else if (((Secondary == 1) || (Secondary == 3)) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == 1))
-	{
-		pAd->CommonCfg.Channel = NewChannel;
-
-		if (Secondary == 1)
-		{
-			// Secondary above.
-			pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
-			RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue);
-			MACValue &= 0xfe;
-			RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue);
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-			BBPValue&= (~0x18);
-			BBPValue|= (0x10);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue);
-			BBPValue&= (~0x20);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPValue);
-			DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
-		}
-		else
-		{
-			// Secondary below.
-			pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
-			RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue);
-			MACValue &= 0xfe;
-			MACValue |= 0x1;
-			RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue);
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-			BBPValue&= (~0x18);
-			BBPValue|= (0x10);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue);
-			BBPValue&= (~0x20);
-			BBPValue|= (0x20);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPValue);
-			DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
-		}
-		pAd->CommonCfg.BBPCurrentBW = BW_40;
-		AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
-		AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
-		pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 1;
-	}
-}
-#endif // DOT11N_DRAFT3 //
-#endif // DOT11_N_SUPPORT //
-
-VOID PeerPublicAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-#ifdef DOT11_N_SUPPORT
-#ifdef DOT11N_DRAFT3
-	UCHAR	Action = Elem->Msg[LENGTH_802_11+1];
-#endif // DOT11N_DRAFT3 //
-#endif // DOT11_N_SUPPORT //
-	if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
-		return;
-
-#ifdef DOT11_N_SUPPORT
-#ifdef DOT11N_DRAFT3
-	switch(Action)
-	{
-		case ACTION_BSS_2040_COEXIST:	// Format defined in IEEE 7.4.7a.1 in 11n Draf3.03
-			{
-				//UCHAR	BssCoexist;
-				BSS_2040_COEXIST_ELEMENT		*pCoexistInfo;
-				BSS_2040_COEXIST_IE			*pBssCoexistIe;
-				BSS_2040_INTOLERANT_CH_REPORT	*pIntolerantReport = NULL;
-
-				if (Elem->MsgLen <= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT)) )
-				{
-					DBGPRINT(RT_DEBUG_ERROR, ("ACTION - 20/40 BSS Coexistence Management Frame length too short! len = %ld!\n", Elem->MsgLen));
-					break;
-				}
-				DBGPRINT(RT_DEBUG_TRACE, ("ACTION - 20/40 BSS Coexistence Management action----> \n"));
-				hex_dump("CoexistenceMgmtFrame", Elem->Msg, Elem->MsgLen);
-
-
-				pCoexistInfo = (BSS_2040_COEXIST_ELEMENT *) &Elem->Msg[LENGTH_802_11+2];
-				//hex_dump("CoexistInfo", (PUCHAR)pCoexistInfo, sizeof(BSS_2040_COEXIST_ELEMENT));
-				if (Elem->MsgLen >= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT) + sizeof(BSS_2040_INTOLERANT_CH_REPORT)))
-				{
-					pIntolerantReport = (BSS_2040_INTOLERANT_CH_REPORT *)((PUCHAR)pCoexistInfo + sizeof(BSS_2040_COEXIST_ELEMENT));
-				}
-				//hex_dump("IntolerantReport ", (PUCHAR)pIntolerantReport, sizeof(BSS_2040_INTOLERANT_CH_REPORT));
-
-				pBssCoexistIe = (BSS_2040_COEXIST_IE *)(&pCoexistInfo->BssCoexistIe);
-
-#ifdef CONFIG_STA_SUPPORT
-				IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-				{
-					if (INFRA_ON(pAd))
-					{
-						StaPublicAction(pAd, pCoexistInfo);
-					}
-				}
-#endif // CONFIG_STA_SUPPORT //
-
-			}
-			break;
-	}
-
-#endif // DOT11N_DRAFT3 //
-#endif // DOT11_N_SUPPORT //
-
-}
-
-
-static VOID ReservedAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	UCHAR Category;
-
-	if (Elem->MsgLen <= LENGTH_802_11)
-	{
-		return;
-	}
-
-	Category = Elem->Msg[LENGTH_802_11];
-	DBGPRINT(RT_DEBUG_TRACE,("Rcv reserved category(%d) Action Frame\n", Category));
-	hex_dump("Reserved Action Frame", &Elem->Msg[0], Elem->MsgLen);
-}
-
-VOID PeerRMAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-
-{
-	return;
-}
-
-#ifdef DOT11_N_SUPPORT
-static VOID respond_ht_information_exchange_action(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	PUCHAR			pOutBuffer = NULL;
-	NDIS_STATUS		NStatus;
-	ULONG			FrameLen;
-	FRAME_HT_INFO	HTINFOframe, *pFrame;
-	UCHAR			*pAddr;
-
-
-	// 2. Always send back ADDBA Response
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	 //Get an unused nonpaged memory
-
-	if (NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("ACTION - respond_ht_information_exchange_action() allocate memory failed \n"));
-		return;
-	}
-
-	// get RA
-	pFrame = (FRAME_HT_INFO *) &Elem->Msg[0];
-	pAddr = pFrame->Hdr.Addr2;
-
-	NdisZeroMemory(&HTINFOframe, sizeof(FRAME_HT_INFO));
-	// 2-1. Prepare ADDBA Response frame.
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		if (ADHOC_ON(pAd))
-			ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
-		else
-		ActHeaderInit(pAd, &HTINFOframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	HTINFOframe.Category = CATEGORY_HT;
-	HTINFOframe.Action = HT_INFO_EXCHANGE;
-	HTINFOframe.HT_Info.Request = 0;
-	HTINFOframe.HT_Info.Forty_MHz_Intolerant = pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant;
-	HTINFOframe.HT_Info.STA_Channel_Width	 = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
-
-	MakeOutgoingFrame(pOutBuffer,					&FrameLen,
-					  sizeof(FRAME_HT_INFO),	&HTINFOframe,
-					  END_OF_ARGS);
-
-	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-}
-
-
-#ifdef DOT11N_DRAFT3
-VOID SendNotifyBWActionFrame(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR  Wcid,
-	IN UCHAR apidx)
-{
-	PUCHAR			pOutBuffer = NULL;
-	NDIS_STATUS	NStatus;
-	FRAME_ACTION_HDR	Frame;
-	ULONG			FrameLen;
-	PUCHAR			pAddr1;
-
-
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-	if(NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("ACT - SendNotifyBWAction() allocate memory failed \n"));
-		return;
-	}
-
-	if (Wcid == MCAST_WCID)
-		pAddr1 = &BROADCAST_ADDR[0];
-	else
-		pAddr1 = pAd->MacTab.Content[Wcid].Addr;
-	ActHeaderInit(pAd, &Frame.Hdr, pAddr1, pAd->ApCfg.MBSSID[apidx].Bssid, pAd->ApCfg.MBSSID[apidx].Bssid);
-
-	Frame.Category = CATEGORY_HT;
-	Frame.Action = NOTIFY_BW_ACTION;
-
-	MakeOutgoingFrame(pOutBuffer,				&FrameLen,
-				  sizeof(FRAME_ACTION_HDR),	  &Frame,
-				  END_OF_ARGS);
-
-	*(pOutBuffer + FrameLen) = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
-	FrameLen++;
-
-
-	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-	DBGPRINT(RT_DEBUG_TRACE,("ACT - SendNotifyBWAction(NotifyBW= %d)!\n", pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth));
-
-}
-#endif // DOT11N_DRAFT3 //
-
-
-VOID PeerHTAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	UCHAR	Action = Elem->Msg[LENGTH_802_11+1];
-
-	if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
-		return;
-
-	switch(Action)
-	{
-		case NOTIFY_BW_ACTION:
-			DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Notify Channel bandwidth action----> \n"));
-#ifdef CONFIG_STA_SUPPORT
-			if(pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
-			{
-				// Note, this is to patch DIR-1353 AP. When the AP set to Wep, it will use legacy mode. But AP still keeps
-				// sending BW_Notify Action frame, and cause us to linkup and linkdown.
-				// In legacy mode, don't need to parse HT action frame.
-				DBGPRINT(RT_DEBUG_TRACE,("ACTION -Ignore HT Notify Channel BW when link as legacy mode. BW = %d---> \n",
-								Elem->Msg[LENGTH_802_11+2] ));
-				break;
-			}
-#endif // CONFIG_STA_SUPPORT //
-
-			if (Elem->Msg[LENGTH_802_11+2] == 0)	// 7.4.8.2. if value is 1, keep the same as supported channel bandwidth.
-				pAd->MacTab.Content[Elem->Wcid].HTPhyMode.field.BW = 0;
-
-			break;
-
-		case SMPS_ACTION:
-			// 7.3.1.25
-			DBGPRINT(RT_DEBUG_TRACE,("ACTION - SMPS action----> \n"));
-			if (((Elem->Msg[LENGTH_802_11+2]&0x1) == 0))
-			{
-				pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_ENABLE;
-			}
-			else if (((Elem->Msg[LENGTH_802_11+2]&0x2) == 0))
-			{
-				pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_STATIC;
-			}
-			else
-			{
-				pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_DYNAMIC;
-			}
-
-			DBGPRINT(RT_DEBUG_TRACE,("Aid(%d) MIMO PS = %d\n", Elem->Wcid, pAd->MacTab.Content[Elem->Wcid].MmpsMode));
-			// rt2860c : add something for smps change.
-			break;
-
-		case SETPCO_ACTION:
-			break;
-
-		case MIMO_CHA_MEASURE_ACTION:
-			break;
-
-		case HT_INFO_EXCHANGE:
-			{
-				HT_INFORMATION_OCTET	*pHT_info;
-
-				pHT_info = (HT_INFORMATION_OCTET *) &Elem->Msg[LENGTH_802_11+2];
-				// 7.4.8.10
-				DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Information Exchange action----> \n"));
-				if (pHT_info->Request)
-				{
-					respond_ht_information_exchange_action(pAd, Elem);
-				}
-			}
-		break;
-	}
-}
-
-
-/*
-	==========================================================================
-	Description:
-		Retry sending ADDBA Reqest.
-
-	IRQL = DISPATCH_LEVEL
-
-	Parametrs:
-	p8023Header: if this is already 802.3 format, p8023Header is NULL
-
-	Return	: TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
-				FALSE , then continue indicaterx at this moment.
-	==========================================================================
- */
-VOID ORIBATimerTimeout(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	MAC_TABLE_ENTRY	*pEntry;
-	INT			i, total;
-//	FRAME_BAR			FrameBar;
-//	ULONG			FrameLen;
-//	NDIS_STATUS	NStatus;
-//	PUCHAR			pOutBuffer = NULL;
-//	USHORT			Sequence;
-	UCHAR			TID;
-
-#ifdef RALINK_ATE
-	if (ATE_ON(pAd))
-		return;
-#endif // RALINK_ATE //
-
-	total = pAd->MacTab.Size * NUM_OF_TID;
-
-	for (i = 1; ((i <MAX_LEN_OF_BA_ORI_TABLE) && (total > 0)) ; i++)
-	{
-		if  (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done)
-		{
-			pEntry = &pAd->MacTab.Content[pAd->BATable.BAOriEntry[i].Wcid];
-			TID = pAd->BATable.BAOriEntry[i].TID;
-
-			ASSERT(pAd->BATable.BAOriEntry[i].Wcid < MAX_LEN_OF_MAC_TABLE);
-		}
-		total --;
-	}
-}
-
-
-VOID SendRefreshBAR(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MAC_TABLE_ENTRY	*pEntry)
-{
-	FRAME_BAR		FrameBar;
-	ULONG			FrameLen;
-	NDIS_STATUS	NStatus;
-	PUCHAR			pOutBuffer = NULL;
-	USHORT			Sequence;
-	UCHAR			i, TID;
-	USHORT			idx;
-	BA_ORI_ENTRY	*pBAEntry;
-
-	for (i = 0; i <NUM_OF_TID; i++)
-	{
-		idx = pEntry->BAOriWcidArray[i];
-		if (idx == 0)
-		{
-			continue;
-		}
-		pBAEntry = &pAd->BATable.BAOriEntry[idx];
-
-		if  (pBAEntry->ORI_BA_Status == Originator_Done)
-		{
-			TID = pBAEntry->TID;
-
-			ASSERT(pBAEntry->Wcid < MAX_LEN_OF_MAC_TABLE);
-
-			NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-			if(NStatus != NDIS_STATUS_SUCCESS)
-			{
-				DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));
-				return;
-			}
-
-			Sequence = pEntry->TxSeq[TID];
-
-
-#ifdef CONFIG_STA_SUPPORT
-			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-				BarHeaderInit(pAd, &FrameBar, pEntry->Addr, pAd->CurrentAddress);
-#endif // CONFIG_STA_SUPPORT //
-
-			FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL function.
-			FrameBar.StartingSeq.field.StartSeq = Sequence; // make sure sequence not clear in DEL funciton.
-			FrameBar.BarControl.TID = TID; // make sure sequence not clear in DEL funciton.
-
-			MakeOutgoingFrame(pOutBuffer,				&FrameLen,
-							  sizeof(FRAME_BAR),	  &FrameBar,
-							  END_OF_ARGS);
-			//if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET)))
-			if (1)	// Now we always send BAR.
-			{
-				//MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen);
-				MiniportMMRequest(pAd, (MGMT_USE_QUEUE_FLAG | MapUserPriorityToAccessCategory[TID]), pOutBuffer, FrameLen);
-
-			}
-			MlmeFreeMemory(pAd, pOutBuffer);
-		}
-	}
-}
-#endif // DOT11_N_SUPPORT //
-
-VOID ActHeaderInit(
-    IN	PRTMP_ADAPTER	pAd,
-    IN OUT PHEADER_802_11 pHdr80211,
-    IN PUCHAR Addr1,
-    IN PUCHAR Addr2,
-    IN PUCHAR Addr3)
-{
-    NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
-    pHdr80211->FC.Type = BTYPE_MGMT;
-    pHdr80211->FC.SubType = SUBTYPE_ACTION;
-
-    COPY_MAC_ADDR(pHdr80211->Addr1, Addr1);
-	COPY_MAC_ADDR(pHdr80211->Addr2, Addr2);
-    COPY_MAC_ADDR(pHdr80211->Addr3, Addr3);
-}
-
-VOID BarHeaderInit(
-	IN	PRTMP_ADAPTER	pAd,
-	IN OUT PFRAME_BAR pCntlBar,
-	IN PUCHAR pDA,
-	IN PUCHAR pSA)
-{
-//	USHORT	Duration;
-
-	NdisZeroMemory(pCntlBar, sizeof(FRAME_BAR));
-	pCntlBar->FC.Type = BTYPE_CNTL;
-	pCntlBar->FC.SubType = SUBTYPE_BLOCK_ACK_REQ;
-	pCntlBar->BarControl.MTID = 0;
-	pCntlBar->BarControl.Compressed = 1;
-	pCntlBar->BarControl.ACKPolicy = 0;
-
-
-	pCntlBar->Duration = 16 + RTMPCalcDuration(pAd, RATE_1, sizeof(FRAME_BA));
-
-	COPY_MAC_ADDR(pCntlBar->Addr1, pDA);
-	COPY_MAC_ADDR(pCntlBar->Addr2, pSA);
-}
-
-
-/*
-	==========================================================================
-	Description:
-		Insert Category and action code into the action frame.
-
-	Parametrs:
-		1. frame buffer pointer.
-		2. frame length.
-		3. category code of the frame.
-		4. action code of the frame.
-
-	Return	: None.
-	==========================================================================
- */
-VOID InsertActField(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pFrameBuf,
-	OUT PULONG pFrameLen,
-	IN UINT8 Category,
-	IN UINT8 ActCode)
-{
-	ULONG TempLen;
-
-	MakeOutgoingFrame(	pFrameBuf,		&TempLen,
-						1,				&Category,
-						1,				&ActCode,
-						END_OF_ARGS);
-
-	*pFrameLen = *pFrameLen + TempLen;
-
-	return;
-}
diff --git a/drivers/staging/rt3090/common/ba_action.c b/drivers/staging/rt3090/common/ba_action.c
deleted file mode 100644
index c732489..0000000
--- a/drivers/staging/rt3090/common/ba_action.c
+++ /dev/null
@@ -1,1779 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
- */
-
-
-#ifdef DOT11_N_SUPPORT
-
-#include "../rt_config.h"
-
-
-#define BA_ORI_INIT_SEQ		(pEntry->TxSeq[TID]) //1			// inital sequence number of BA session
-
-#define ORI_SESSION_MAX_RETRY	8
-#define ORI_BA_SESSION_TIMEOUT	(2000)	// ms
-#define REC_BA_SESSION_IDLE_TIMEOUT	(1000)	// ms
-
-#define REORDERING_PACKET_TIMEOUT		((100 * OS_HZ)/1000)	// system ticks -- 100 ms
-#define MAX_REORDERING_PACKET_TIMEOUT	((3000 * OS_HZ)/1000)	// system ticks -- 100 ms
-
-#define RESET_RCV_SEQ		(0xFFFF)
-
-static void ba_mpdu_blk_free(PRTMP_ADAPTER pAd, struct reordering_mpdu *mpdu_blk);
-
-
-BA_ORI_ENTRY *BATableAllocOriEntry(
-								  IN  PRTMP_ADAPTER   pAd,
-								  OUT USHORT          *Idx);
-
-BA_REC_ENTRY *BATableAllocRecEntry(
-								  IN  PRTMP_ADAPTER   pAd,
-								  OUT USHORT          *Idx);
-
-VOID BAOriSessionSetupTimeout(
-    IN PVOID SystemSpecific1,
-    IN PVOID FunctionContext,
-    IN PVOID SystemSpecific2,
-    IN PVOID SystemSpecific3);
-
-VOID BARecSessionIdleTimeout(
-    IN PVOID SystemSpecific1,
-    IN PVOID FunctionContext,
-    IN PVOID SystemSpecific2,
-    IN PVOID SystemSpecific3);
-
-
-BUILD_TIMER_FUNCTION(BAOriSessionSetupTimeout);
-BUILD_TIMER_FUNCTION(BARecSessionIdleTimeout);
-
-#define ANNOUNCE_REORDERING_PACKET(_pAd, _mpdu_blk)	\
-			Announce_Reordering_Packet(_pAd, _mpdu_blk);
-
-VOID BA_MaxWinSizeReasign(
-	IN PRTMP_ADAPTER	pAd,
-	IN MAC_TABLE_ENTRY  *pEntryPeer,
-	OUT UCHAR			*pWinSize)
-{
-	UCHAR MaxSize;
-
-
-	if (pAd->MACVersion >= RALINK_2883_VERSION) // 3*3
-	{
-		if (pAd->MACVersion >= RALINK_3070_VERSION)
-		{
-			if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled)
-				MaxSize = 7; // for non-open mode
-			else
-				MaxSize = 13;
-		}
-		else
-			MaxSize = 31;
-	}
-	else if (pAd->MACVersion >= RALINK_2880E_VERSION) // 2880 e
-	{
-		if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled)
-			MaxSize = 7; // for non-open mode
-		else
-			MaxSize = 13;
-	}
-	else
-		MaxSize = 7;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("ba> Win Size = %d, Max Size = %d\n",
-			*pWinSize, MaxSize));
-
-	if ((*pWinSize) > MaxSize)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("ba> reassign max win size from %d to %d\n",
-				*pWinSize, MaxSize));
-
-		*pWinSize = MaxSize;
-	}
-}
-
-void Announce_Reordering_Packet(IN PRTMP_ADAPTER			pAd,
-								IN struct reordering_mpdu	*mpdu)
-{
-	PNDIS_PACKET    pPacket;
-
-	pPacket = mpdu->pPacket;
-
-	if (mpdu->bAMSDU)
-	{
-		ASSERT(0);
-		BA_Reorder_AMSDU_Annnounce(pAd, pPacket);
-	}
-	else
-	{
-		//
-		// pass this 802.3 packet to upper layer or forward this packet to WM directly
-		//
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-			ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket, RTMP_GET_PACKET_IF(pPacket));
-#endif // CONFIG_STA_SUPPORT //
-	}
-}
-
-/*
- * Insert a reordering mpdu into sorted linked list by sequence no.
- */
-BOOLEAN ba_reordering_mpdu_insertsorted(struct reordering_list *list, struct reordering_mpdu *mpdu)
-{
-
-	struct reordering_mpdu **ppScan = &list->next;
-
-	while (*ppScan != NULL)
-	{
-		if (SEQ_SMALLER((*ppScan)->Sequence, mpdu->Sequence, MAXSEQ))
-		{
-			ppScan = &(*ppScan)->next;
-		}
-		else if ((*ppScan)->Sequence == mpdu->Sequence)
-		{
-			/* give up this duplicated frame */
-			return(FALSE);
-		}
-		else
-		{
-			/* find position */
-			break;
-		}
-	}
-
-	mpdu->next = *ppScan;
-	*ppScan = mpdu;
-	list->qlen++;
-	return TRUE;
-}
-
-
-/*
- * caller lock critical section if necessary
- */
-static inline void ba_enqueue(struct reordering_list *list, struct reordering_mpdu *mpdu_blk)
-{
-	list->qlen++;
-	mpdu_blk->next = list->next;
-	list->next = mpdu_blk;
-}
-
-/*
- * caller lock critical section if necessary
- */
-static inline struct reordering_mpdu * ba_dequeue(struct reordering_list *list)
-{
-	struct reordering_mpdu *mpdu_blk = NULL;
-
-	ASSERT(list);
-
-		if (list->qlen)
-		{
-			list->qlen--;
-			mpdu_blk = list->next;
-			if (mpdu_blk)
-			{
-				list->next = mpdu_blk->next;
-				mpdu_blk->next = NULL;
-			}
-		}
-	return mpdu_blk;
-}
-
-
-static inline struct reordering_mpdu  *ba_reordering_mpdu_dequeue(struct reordering_list *list)
-{
-	return(ba_dequeue(list));
-}
-
-
-static inline struct reordering_mpdu  *ba_reordering_mpdu_probe(struct reordering_list *list)
-	{
-	ASSERT(list);
-
-		return(list->next);
-	}
-
-
-/*
- * free all resource for reordering mechanism
- */
-void ba_reordering_resource_release(PRTMP_ADAPTER pAd)
-{
-	BA_TABLE        *Tab;
-	PBA_REC_ENTRY   pBAEntry;
-	struct reordering_mpdu *mpdu_blk;
-	int i;
-
-	Tab = &pAd->BATable;
-
-	/* I.  release all pending reordering packet */
-	NdisAcquireSpinLock(&pAd->BATabLock);
-	for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
-	{
-		pBAEntry = &Tab->BARecEntry[i];
-		if (pBAEntry->REC_BA_Status != Recipient_NONE)
-		{
-			while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list)))
-			{
-				ASSERT(mpdu_blk->pPacket);
-				RELEASE_NDIS_PACKET(pAd, mpdu_blk->pPacket, NDIS_STATUS_FAILURE);
-				ba_mpdu_blk_free(pAd, mpdu_blk);
-			}
-		}
-	}
-	NdisReleaseSpinLock(&pAd->BATabLock);
-
-	ASSERT(pBAEntry->list.qlen == 0);
-	/* II. free memory of reordering mpdu table */
-	NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
-	os_free_mem(pAd, pAd->mpdu_blk_pool.mem);
-	NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
-}
-
-
-
-/*
- * Allocate all resource for reordering mechanism
- */
-BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num)
-{
-	int     i;
-	PUCHAR  mem;
-	struct reordering_mpdu *mpdu_blk;
-	struct reordering_list *freelist;
-
-	/* allocate spinlock */
-	NdisAllocateSpinLock(&pAd->mpdu_blk_pool.lock);
-
-	/* initialize freelist */
-	freelist = &pAd->mpdu_blk_pool.freelist;
-	freelist->next = NULL;
-	freelist->qlen = 0;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Allocate %d memory for BA reordering\n", (UINT32)(num*sizeof(struct reordering_mpdu))));
-
-	/* allocate number of mpdu_blk memory */
-	os_alloc_mem(pAd, (PUCHAR *)&mem, (num*sizeof(struct reordering_mpdu)));
-
-	pAd->mpdu_blk_pool.mem = mem;
-
-	if (mem == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Can't Allocate Memory for BA Reordering\n"));
-		return(FALSE);
-	}
-
-	/* build mpdu_blk free list */
-	for (i=0; i<num; i++)
-	{
-		/* get mpdu_blk */
-		mpdu_blk = (struct reordering_mpdu *) mem;
-		/* initial mpdu_blk */
-		NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu));
-		/* next mpdu_blk */
-		mem += sizeof(struct reordering_mpdu);
-		/* insert mpdu_blk into freelist */
-		ba_enqueue(freelist, mpdu_blk);
-	}
-
-	return(TRUE);
-}
-
-//static int blk_count=0; // sample take off, no use
-
-static struct reordering_mpdu *ba_mpdu_blk_alloc(PRTMP_ADAPTER pAd)
-{
-	struct reordering_mpdu *mpdu_blk;
-
-	NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
-	mpdu_blk = ba_dequeue(&pAd->mpdu_blk_pool.freelist);
-	if (mpdu_blk)
-	{
-//		blk_count++;
-		/* reset mpdu_blk */
-		NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu));
-	}
-	NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
-	return mpdu_blk;
-}
-
-static void ba_mpdu_blk_free(PRTMP_ADAPTER pAd, struct reordering_mpdu *mpdu_blk)
-{
-	ASSERT(mpdu_blk);
-
-	NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
-//	blk_count--;
-	ba_enqueue(&pAd->mpdu_blk_pool.freelist, mpdu_blk);
-	NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
-}
-
-
-static USHORT ba_indicate_reordering_mpdus_in_order(
-												   IN PRTMP_ADAPTER    pAd,
-												   IN PBA_REC_ENTRY    pBAEntry,
-												   IN USHORT           StartSeq)
-{
-	struct reordering_mpdu *mpdu_blk;
-	USHORT  LastIndSeq = RESET_RCV_SEQ;
-
-	NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
-
-	while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list)))
-		{
-			/* find in-order frame */
-		if (!SEQ_STEPONE(mpdu_blk->Sequence, StartSeq, MAXSEQ))
-			{
-				break;
-			}
-			/* dequeue in-order frame from reodering list */
-			mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
-			/* pass this frame up */
-		ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
-		/* move to next sequence */
-			StartSeq = mpdu_blk->Sequence;
-		LastIndSeq = StartSeq;
-		/* free mpdu_blk */
-			ba_mpdu_blk_free(pAd, mpdu_blk);
-	}
-
-	NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
-
-	/* update last indicated sequence */
-	return LastIndSeq;
-}
-
-static void ba_indicate_reordering_mpdus_le_seq(
-											   IN PRTMP_ADAPTER    pAd,
-											   IN PBA_REC_ENTRY    pBAEntry,
-											   IN USHORT           Sequence)
-{
-	struct reordering_mpdu *mpdu_blk;
-
-	NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
-	while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list)))
-		{
-			/* find in-order frame */
-		if ((mpdu_blk->Sequence == Sequence) || SEQ_SMALLER(mpdu_blk->Sequence, Sequence, MAXSEQ))
-		{
-			/* dequeue in-order frame from reodering list */
-			mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
-			/* pass this frame up */
-			ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
-			/* free mpdu_blk */
-			ba_mpdu_blk_free(pAd, mpdu_blk);
-		}
-		else
-			{
-				break;
-			}
-	}
-	NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
-}
-
-
-static void ba_refresh_reordering_mpdus(
-									   IN PRTMP_ADAPTER    pAd,
-									   PBA_REC_ENTRY       pBAEntry)
-{
-	struct reordering_mpdu *mpdu_blk;
-
-	NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
-
-			/* dequeue in-order frame from reodering list */
-	while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list)))
-	{
-			/* pass this frame up */
-		ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
-
-		pBAEntry->LastIndSeq = mpdu_blk->Sequence;
-			ba_mpdu_blk_free(pAd, mpdu_blk);
-
-		/* update last indicated sequence */
-	}
-	ASSERT(pBAEntry->list.qlen == 0);
-	pBAEntry->LastIndSeq = RESET_RCV_SEQ;
-	NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
-}
-
-
-//static
-void ba_flush_reordering_timeout_mpdus(
-									IN PRTMP_ADAPTER    pAd,
-									IN PBA_REC_ENTRY    pBAEntry,
-									IN ULONG            Now32)
-
-{
-	USHORT Sequence;
-
-//	if ((RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+REORDERING_PACKET_TIMEOUT)) &&
-//		 (pBAEntry->list.qlen > ((pBAEntry->BAWinSize*7)/8))) //||
-//		(RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(10*REORDERING_PACKET_TIMEOUT))) &&
-//		 (pBAEntry->list.qlen > (pBAEntry->BAWinSize/8)))
-	if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(MAX_REORDERING_PACKET_TIMEOUT/6)))
-		 &&(pBAEntry->list.qlen > 1)
-		)
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("timeout[%d] (%08lx-%08lx = %d > %d): %x, flush all!\n ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer),
-			   (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), MAX_REORDERING_PACKET_TIMEOUT,
-			   pBAEntry->LastIndSeq));
-		ba_refresh_reordering_mpdus(pAd, pBAEntry);
-		pBAEntry->LastIndSeqAtTimer = Now32;
-	}
-	else
-	if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
-		&& (pBAEntry->list.qlen > 0)
-	   )
-		{
-//		DBGPRINT(RT_DEBUG_OFF, ("timeout[%d] (%lx-%lx = %d > %d): %x, ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer),
-//			   (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), REORDERING_PACKET_TIMEOUT,
-//			   pBAEntry->LastIndSeq));
-		//
-		// force LastIndSeq to shift to LastIndSeq+1
-		//
-		Sequence = (pBAEntry->LastIndSeq+1) & MAXSEQ;
-		ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
-		pBAEntry->LastIndSeqAtTimer = Now32;
-			pBAEntry->LastIndSeq = Sequence;
-		//
-		// indicate in-order mpdus
-		//
-		Sequence = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, Sequence);
-		if (Sequence != RESET_RCV_SEQ)
-		{
-			pBAEntry->LastIndSeq = Sequence;
-		}
-
-		DBGPRINT(RT_DEBUG_OFF, ("%x, flush one!\n", pBAEntry->LastIndSeq));
-
-	}
-}
-
-
-/*
- * generate ADDBA request to
- * set up BA agreement
- */
-VOID BAOriSessionSetUp(
-					  IN PRTMP_ADAPTER    pAd,
-					  IN MAC_TABLE_ENTRY  *pEntry,
-					  IN UCHAR            TID,
-					  IN USHORT           TimeOut,
-					  IN ULONG            DelayTime,
-					  IN BOOLEAN          isForced)
-
-{
-	//MLME_ADDBA_REQ_STRUCT	AddbaReq;
-	BA_ORI_ENTRY            *pBAEntry = NULL;
-	USHORT                  Idx;
-	BOOLEAN                 Cancelled;
-
-	if ((pAd->CommonCfg.BACapability.field.AutoBA != TRUE)  &&  (isForced == FALSE))
-		return;
-
-	// if this entry is limited to use legacy tx mode, it doesn't generate BA.
-	if (RTMPStaFixedTxMode(pAd, pEntry) != FIXED_TXMODE_HT)
-		return;
-
-	if ((pEntry->BADeclineBitmap & (1<<TID)) && (isForced == FALSE))
-	{
-		// try again after 3 secs
-		DelayTime = 3000;
-//		DBGPRINT(RT_DEBUG_TRACE, ("DeCline BA from Peer\n"));
-//		return;
-	}
-
-
-	Idx = pEntry->BAOriWcidArray[TID];
-	if (Idx == 0)
-	{
-		// allocate a BA session
-		pBAEntry = BATableAllocOriEntry(pAd, &Idx);
-		if (pBAEntry == NULL)
-		{
-			DBGPRINT(RT_DEBUG_TRACE,("ADDBA - MlmeADDBAAction() allocate BA session failed \n"));
-			return;
-		}
-	}
-	else
-	{
-		pBAEntry =&pAd->BATable.BAOriEntry[Idx];
-	}
-
-	if (pBAEntry->ORI_BA_Status >= Originator_WaitRes)
-	{
-		return;
-	}
-
-	pEntry->BAOriWcidArray[TID] = Idx;
-
-	// Initialize BA session
-	pBAEntry->ORI_BA_Status = Originator_WaitRes;
-	pBAEntry->Wcid = pEntry->Aid;
-	pBAEntry->BAWinSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit;
-	pBAEntry->Sequence = BA_ORI_INIT_SEQ;
-	pBAEntry->Token = 1;	// (2008-01-21) Jan Lee recommends it - this token can't be 0
-	pBAEntry->TID = TID;
-	pBAEntry->TimeOutValue = TimeOut;
-	pBAEntry->pAdapter = pAd;
-
-	if (!(pEntry->TXBAbitmap & (1<<TID)))
-	{
-		RTMPInitTimer(pAd, &pBAEntry->ORIBATimer, GET_TIMER_FUNCTION(BAOriSessionSetupTimeout), pBAEntry, FALSE);
-	}
-	else
-		RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
-
-	// set timer to send ADDBA request
-	RTMPSetTimer(&pBAEntry->ORIBATimer, DelayTime);
-}
-
-VOID BAOriSessionAdd(
-			IN PRTMP_ADAPTER    pAd,
-					IN MAC_TABLE_ENTRY  *pEntry,
-			IN PFRAME_ADDBA_RSP pFrame)
-{
-	BA_ORI_ENTRY  *pBAEntry = NULL;
-	BOOLEAN       Cancelled;
-	UCHAR         TID;
-	USHORT        Idx;
-	PUCHAR          pOutBuffer2 = NULL;
-	NDIS_STATUS     NStatus;
-	ULONG           FrameLen;
-	FRAME_BAR       FrameBar;
-
-	TID = pFrame->BaParm.TID;
-	Idx = pEntry->BAOriWcidArray[TID];
-	pBAEntry =&pAd->BATable.BAOriEntry[Idx];
-
-	// Start fill in parameters.
-	if ((Idx !=0) && (pBAEntry->TID == TID) && (pBAEntry->ORI_BA_Status == Originator_WaitRes))
-	{
-		pBAEntry->BAWinSize = min(pBAEntry->BAWinSize, ((UCHAR)pFrame->BaParm.BufSize));
-		BA_MaxWinSizeReasign(pAd, pEntry, &pBAEntry->BAWinSize);
-
-		pBAEntry->TimeOutValue = pFrame->TimeOutValue;
-		pBAEntry->ORI_BA_Status = Originator_Done;
-		pAd->BATable.numDoneOriginator ++;
-
-		// reset sequence number
-		pBAEntry->Sequence = BA_ORI_INIT_SEQ;
-		// Set Bitmap flag.
-		pEntry->TXBAbitmap |= (1<<TID);
-				RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
-
-		pBAEntry->ORIBATimer.TimerValue = 0;	//pFrame->TimeOutValue;
-
-		DBGPRINT(RT_DEBUG_TRACE,("%s : TXBAbitmap = %x, BAWinSize = %d, TimeOut = %ld\n", __FUNCTION__, pEntry->TXBAbitmap,
-								 pBAEntry->BAWinSize, pBAEntry->ORIBATimer.TimerValue));
-
-		// SEND BAR ;
-		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2);  //Get an unused nonpaged memory
-		if (NStatus != NDIS_STATUS_SUCCESS)
-		{
-			DBGPRINT(RT_DEBUG_TRACE,("BA - BAOriSessionAdd() allocate memory failed \n"));
-			return;
-		}
-
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-			BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pBAEntry->Wcid].Addr, pAd->CurrentAddress);
-#endif // CONFIG_STA_SUPPORT //
-
-		FrameBar.StartingSeq.field.FragNum = 0;	// make sure sequence not clear in DEL function.
-		FrameBar.StartingSeq.field.StartSeq = pBAEntry->Sequence; // make sure sequence not clear in DEL funciton.
-		FrameBar.BarControl.TID = pBAEntry->TID; // make sure sequence not clear in DEL funciton.
-		MakeOutgoingFrame(pOutBuffer2,              &FrameLen,
-						  sizeof(FRAME_BAR),      &FrameBar,
-					  END_OF_ARGS);
-		MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
-		MlmeFreeMemory(pAd, pOutBuffer2);
-
-
-		if (pBAEntry->ORIBATimer.TimerValue)
-			RTMPSetTimer(&pBAEntry->ORIBATimer, pBAEntry->ORIBATimer.TimerValue); // in mSec
-	}
-}
-
-BOOLEAN BARecSessionAdd(
-					   IN PRTMP_ADAPTER    pAd,
-					   IN MAC_TABLE_ENTRY  *pEntry,
-					   IN PFRAME_ADDBA_REQ pFrame)
-{
-	BA_REC_ENTRY            *pBAEntry = NULL;
-	BOOLEAN                 Status = TRUE;
-	BOOLEAN                 Cancelled;
-	USHORT                  Idx;
-	UCHAR                   TID;
-	UCHAR                   BAWinSize;
-	//UINT32                  Value;
-	//UINT                    offset;
-
-
-	ASSERT(pEntry);
-
-	// find TID
-	TID = pFrame->BaParm.TID;
-
-	BAWinSize = min(((UCHAR)pFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
-
-	// Intel patch
-	if (BAWinSize == 0)
-	{
-		BAWinSize = 64;
-	}
-
-	Idx = pEntry->BARecWcidArray[TID];
-
-
-	if (Idx == 0)
-	{
-		pBAEntry = BATableAllocRecEntry(pAd, &Idx);
-	}
-	else
-	{
-		pBAEntry = &pAd->BATable.BARecEntry[Idx];
-		// flush all pending reordering mpdus
-		ba_refresh_reordering_mpdus(pAd, pBAEntry);
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,("%s(%ld): Idx = %d, BAWinSize(req %d) = %d\n", __FUNCTION__, pAd->BATable.numAsRecipient, Idx,
-							 pFrame->BaParm.BufSize, BAWinSize));
-
-	// Start fill in parameters.
-	if (pBAEntry != NULL)
-	{
-		ASSERT(pBAEntry->list.qlen == 0);
-
-		pBAEntry->REC_BA_Status = Recipient_HandleRes;
-		pBAEntry->BAWinSize = BAWinSize;
-		pBAEntry->Wcid = pEntry->Aid;
-		pBAEntry->TID = TID;
-		pBAEntry->TimeOutValue = pFrame->TimeOutValue;
-		pBAEntry->REC_BA_Status = Recipient_Accept;
-		// initial sequence number
-		pBAEntry->LastIndSeq = RESET_RCV_SEQ; //pFrame->BaStartSeq.field.StartSeq;
-
-		DBGPRINT(RT_DEBUG_OFF, ("Start Seq = %08x\n",  pFrame->BaStartSeq.field.StartSeq));
-
-		if (pEntry->RXBAbitmap & (1<<TID))
-		{
-			RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
-		}
-		else
-		{
-			RTMPInitTimer(pAd, &pBAEntry->RECBATimer, GET_TIMER_FUNCTION(BARecSessionIdleTimeout), pBAEntry, TRUE);
-		}
-
-
-		// Set Bitmap flag.
-		pEntry->RXBAbitmap |= (1<<TID);
-		pEntry->BARecWcidArray[TID] = Idx;
-
-		pEntry->BADeclineBitmap &= ~(1<<TID);
-
-		// Set BA session mask in WCID table.
-		RTMP_ADD_BA_SESSION_TO_ASIC(pAd, pEntry->Aid, TID);
-
-		DBGPRINT(RT_DEBUG_TRACE,("MACEntry[%d]RXBAbitmap = 0x%x. BARecWcidArray=%d\n",
-				pEntry->Aid, pEntry->RXBAbitmap, pEntry->BARecWcidArray[TID]));
-	}
-	else
-	{
-		Status = FALSE;
-		DBGPRINT(RT_DEBUG_TRACE,("Can't Accept ADDBA for %02x:%02x:%02x:%02x:%02x:%02x TID = %d\n",
-				PRINT_MAC(pEntry->Addr), TID));
-	}
-	return(Status);
-}
-
-
-BA_REC_ENTRY *BATableAllocRecEntry(
-								  IN  PRTMP_ADAPTER   pAd,
-								  OUT USHORT          *Idx)
-{
-	int             i;
-	BA_REC_ENTRY    *pBAEntry = NULL;
-
-
-	NdisAcquireSpinLock(&pAd->BATabLock);
-
-	if (pAd->BATable.numAsRecipient >= MAX_BARECI_SESSION)
-	{
-		DBGPRINT(RT_DEBUG_OFF, ("BA Recipeint Session (%ld) > %d\n",
-							pAd->BATable.numAsRecipient, MAX_BARECI_SESSION));
-		goto done;
-	}
-
-	// reserve idx 0 to identify BAWcidArray[TID] as empty
-	for (i=1; i < MAX_LEN_OF_BA_REC_TABLE; i++)
-	{
-		pBAEntry =&pAd->BATable.BARecEntry[i];
-		if ((pBAEntry->REC_BA_Status == Recipient_NONE))
-		{
-			// get one
-			pAd->BATable.numAsRecipient++;
-			pBAEntry->REC_BA_Status = Recipient_USED;
-			*Idx = i;
-			break;
-		}
-	}
-
-done:
-	NdisReleaseSpinLock(&pAd->BATabLock);
-	return pBAEntry;
-}
-
-BA_ORI_ENTRY *BATableAllocOriEntry(
-								  IN  PRTMP_ADAPTER   pAd,
-								  OUT USHORT          *Idx)
-{
-	int             i;
-	BA_ORI_ENTRY    *pBAEntry = NULL;
-
-	NdisAcquireSpinLock(&pAd->BATabLock);
-
-	if (pAd->BATable.numAsOriginator >= (MAX_LEN_OF_BA_ORI_TABLE))
-	{
-		goto done;
-	}
-
-	// reserve idx 0 to identify BAWcidArray[TID] as empty
-	for (i=1; i<MAX_LEN_OF_BA_ORI_TABLE; i++)
-	{
-		pBAEntry =&pAd->BATable.BAOriEntry[i];
-		if ((pBAEntry->ORI_BA_Status == Originator_NONE))
-		{
-			// get one
-			pAd->BATable.numAsOriginator++;
-			pBAEntry->ORI_BA_Status = Originator_USED;
-			pBAEntry->pAdapter = pAd;
-			*Idx = i;
-			break;
-		}
-	}
-
-done:
-	NdisReleaseSpinLock(&pAd->BATabLock);
-	return pBAEntry;
-}
-
-
-VOID BATableFreeOriEntry(
-						IN  PRTMP_ADAPTER   pAd,
-						IN  ULONG           Idx)
-{
-	BA_ORI_ENTRY    *pBAEntry = NULL;
-	MAC_TABLE_ENTRY *pEntry;
-
-
-	if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE))
-		return;
-
-	pBAEntry =&pAd->BATable.BAOriEntry[Idx];
-
-	if (pBAEntry->ORI_BA_Status != Originator_NONE)
-	{
-		pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
-		pEntry->BAOriWcidArray[pBAEntry->TID] = 0;
-
-
-		NdisAcquireSpinLock(&pAd->BATabLock);
-		if (pBAEntry->ORI_BA_Status == Originator_Done)
-		{
-			pAd->BATable.numDoneOriginator -= 1;
-			pEntry->TXBAbitmap &= (~(1<<(pBAEntry->TID) ));
-			DBGPRINT(RT_DEBUG_TRACE, ("BATableFreeOriEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
-			// Erase Bitmap flag.
-		}
-
-		ASSERT(pAd->BATable.numAsOriginator != 0);
-
-		pAd->BATable.numAsOriginator -= 1;
-
-		pBAEntry->ORI_BA_Status = Originator_NONE;
-		pBAEntry->Token = 0;
-		NdisReleaseSpinLock(&pAd->BATabLock);
-	}
-}
-
-
-VOID BATableFreeRecEntry(
-						IN  PRTMP_ADAPTER   pAd,
-						IN  ULONG           Idx)
-{
-	BA_REC_ENTRY    *pBAEntry = NULL;
-	MAC_TABLE_ENTRY *pEntry;
-
-
-	if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_REC_TABLE))
-		return;
-
-	pBAEntry =&pAd->BATable.BARecEntry[Idx];
-
-	if (pBAEntry->REC_BA_Status != Recipient_NONE)
-	{
-		pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
-		pEntry->BARecWcidArray[pBAEntry->TID] = 0;
-
-		NdisAcquireSpinLock(&pAd->BATabLock);
-
-		ASSERT(pAd->BATable.numAsRecipient != 0);
-
-		pAd->BATable.numAsRecipient -= 1;
-
-		pBAEntry->REC_BA_Status = Recipient_NONE;
-		NdisReleaseSpinLock(&pAd->BATabLock);
-	}
-}
-
-
-VOID BAOriSessionTearDown(
-						 IN OUT  PRTMP_ADAPTER   pAd,
-						 IN      UCHAR           Wcid,
-						 IN      UCHAR           TID,
-						 IN      BOOLEAN         bPassive,
-						 IN      BOOLEAN         bForceSend)
-{
-	ULONG           Idx = 0;
-	BA_ORI_ENTRY    *pBAEntry;
-	BOOLEAN         Cancelled;
-
-	if (Wcid >= MAX_LEN_OF_MAC_TABLE)
-	{
-		return;
-	}
-
-	//
-	// Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID).
-	//
-	Idx = pAd->MacTab.Content[Wcid].BAOriWcidArray[TID];
-	if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE))
-	{
-		if (bForceSend == TRUE)
-		{
-			// force send specified TID DelBA
-			MLME_DELBA_REQ_STRUCT   DelbaReq;
-			MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
-			if (Elem != NULL)
-			{
-				NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
-				NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
-
-				COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
-				DelbaReq.Wcid = Wcid;
-				DelbaReq.TID = TID;
-				DelbaReq.Initiator = ORIGINATOR;
-				Elem->MsgLen  = sizeof(DelbaReq);
-				NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
-				MlmeDELBAAction(pAd, Elem);
-				kfree(Elem);
-			}
-			else
-			{
-				DBGPRINT(RT_DEBUG_ERROR, ("%s(bForceSend):alloc memory failed!\n", __FUNCTION__));
-			}
-		}
-
-		return;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID));
-
-	pBAEntry = &pAd->BATable.BAOriEntry[Idx];
-	DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, ORI_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->ORI_BA_Status));
-	//
-	// Prepare DelBA action frame and send to the peer.
-	//
-	if ((bPassive == FALSE) && (TID == pBAEntry->TID) && (pBAEntry->ORI_BA_Status == Originator_Done))
-	{
-		MLME_DELBA_REQ_STRUCT   DelbaReq;
-		MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
-		if (Elem != NULL)
-		{
-			NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
-			NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
-
-			COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
-			DelbaReq.Wcid = Wcid;
-			DelbaReq.TID = pBAEntry->TID;
-			DelbaReq.Initiator = ORIGINATOR;
-			Elem->MsgLen  = sizeof(DelbaReq);
-			NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
-			MlmeDELBAAction(pAd, Elem);
-			kfree(Elem);
-		}
-		else
-		{
-			DBGPRINT(RT_DEBUG_ERROR, ("%s():alloc memory failed!\n", __FUNCTION__));
-			return;
-		}
-	}
-	RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
-	BATableFreeOriEntry(pAd, Idx);
-
-	if (bPassive)
-	{
-		//BAOriSessionSetUp(pAd, &pAd->MacTab.Content[Wcid], TID, 0, 10000, TRUE);
-	}
-}
-
-VOID BARecSessionTearDown(
-						 IN OUT  PRTMP_ADAPTER   pAd,
-						 IN      UCHAR           Wcid,
-						 IN      UCHAR           TID,
-						 IN      BOOLEAN         bPassive)
-{
-	ULONG           Idx = 0;
-	BA_REC_ENTRY    *pBAEntry;
-
-	if (Wcid >= MAX_LEN_OF_MAC_TABLE)
-	{
-		return;
-	}
-
-	//
-	//  Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID).
-	//
-	Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
-	if (Idx == 0)
-		return;
-
-	DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID));
-
-
-	pBAEntry = &pAd->BATable.BARecEntry[Idx];
-	DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, REC_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->REC_BA_Status));
-	//
-	// Prepare DelBA action frame and send to the peer.
-	//
-	if ((TID == pBAEntry->TID) && (pBAEntry->REC_BA_Status == Recipient_Accept))
-	{
-		MLME_DELBA_REQ_STRUCT   DelbaReq;
-		BOOLEAN					Cancelled;
-		//ULONG   offset;
-		//UINT32  VALUE;
-
-		RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
-
-		//
-		// 1. Send DELBA Action Frame
-		//
-		if (bPassive == FALSE)
-		{
-			MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
-			if (Elem != NULL)
-			{
-				NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
-				NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
-
-				COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
-				DelbaReq.Wcid = Wcid;
-				DelbaReq.TID = TID;
-				DelbaReq.Initiator = RECIPIENT;
-				Elem->MsgLen  = sizeof(DelbaReq);
-				NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
-				MlmeDELBAAction(pAd, Elem);
-				kfree(Elem);
-			}
-			else
-			{
-				DBGPRINT(RT_DEBUG_ERROR, ("%s():alloc memory failed!\n", __FUNCTION__));
-				return;
-			}
-		}
-
-
-		//
-		// 2. Free resource of BA session
-		//
-		// flush all pending reordering mpdus
-		ba_refresh_reordering_mpdus(pAd, pBAEntry);
-
-		NdisAcquireSpinLock(&pAd->BATabLock);
-
-		// Erase Bitmap flag.
-		pBAEntry->LastIndSeq = RESET_RCV_SEQ;
-		pBAEntry->BAWinSize = 0;
-		// Erase Bitmap flag at software mactable
-		pAd->MacTab.Content[Wcid].RXBAbitmap &= (~(1<<(pBAEntry->TID)));
-		pAd->MacTab.Content[Wcid].BARecWcidArray[TID] = 0;
-
-		RTMP_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID);
-
-		NdisReleaseSpinLock(&pAd->BATabLock);
-
-	}
-
-	BATableFreeRecEntry(pAd, Idx);
-}
-
-VOID BASessionTearDownALL(
-						 IN OUT  PRTMP_ADAPTER pAd,
-						 IN      UCHAR Wcid)
-{
-	int i;
-
-	for (i=0; i<NUM_OF_TID; i++)
-	{
-		BAOriSessionTearDown(pAd, Wcid, i, FALSE, FALSE);
-		BARecSessionTearDown(pAd, Wcid, i, FALSE);
-	}
-}
-
-
-/*
-	==========================================================================
-	Description:
-		Retry sending ADDBA Reqest.
-
-	IRQL = DISPATCH_LEVEL
-
-	Parametrs:
-	p8023Header: if this is already 802.3 format, p8023Header is NULL
-
-	Return	: TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
-				FALSE , then continue indicaterx at this moment.
-	==========================================================================
- */
-VOID BAOriSessionSetupTimeout(
-    IN PVOID SystemSpecific1,
-    IN PVOID FunctionContext,
-    IN PVOID SystemSpecific2,
-    IN PVOID SystemSpecific3)
-{
-	BA_ORI_ENTRY    *pBAEntry = (BA_ORI_ENTRY *)FunctionContext;
-	MAC_TABLE_ENTRY *pEntry;
-	PRTMP_ADAPTER   pAd;
-
-	if (pBAEntry == NULL)
-		return;
-
-	pAd = pBAEntry->pAdapter;
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		// Do nothing if monitor mode is on
-		if (MONITOR_ON(pAd))
-			return;
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef RALINK_ATE
-	// Nothing to do in ATE mode.
-	if (ATE_ON(pAd))
-		return;
-#endif // RALINK_ATE //
-
-	pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
-
-	if ((pBAEntry->ORI_BA_Status == Originator_WaitRes) && (pBAEntry->Token < ORI_SESSION_MAX_RETRY))
-	{
-		MLME_ADDBA_REQ_STRUCT    AddbaReq;
-
-		NdisZeroMemory(&AddbaReq, sizeof(AddbaReq));
-		COPY_MAC_ADDR(AddbaReq.pAddr, pEntry->Addr);
-		AddbaReq.Wcid = (UCHAR)(pEntry->Aid);
-		AddbaReq.TID = pBAEntry->TID;
-		AddbaReq.BaBufSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit;
-		AddbaReq.TimeOutValue = 0;
-		AddbaReq.Token = pBAEntry->Token;
-		MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ADD_BA_CATE, sizeof(MLME_ADDBA_REQ_STRUCT), (PVOID)&AddbaReq);
-		RTMP_MLME_HANDLER(pAd);
-		DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) : Send ADD BA again\n", pBAEntry->Token));
-
-		pBAEntry->Token++;
-		RTMPSetTimer(&pBAEntry->ORIBATimer, ORI_BA_SESSION_TIMEOUT);
-	}
-	else
-	{
-		BATableFreeOriEntry(pAd, pEntry->BAOriWcidArray[pBAEntry->TID]);
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-		Retry sending ADDBA Reqest.
-
-	IRQL = DISPATCH_LEVEL
-
-	Parametrs:
-	p8023Header: if this is already 802.3 format, p8023Header is NULL
-
-	Return	: TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
-				FALSE , then continue indicaterx at this moment.
-	==========================================================================
- */
-VOID BARecSessionIdleTimeout(
-    IN PVOID SystemSpecific1,
-    IN PVOID FunctionContext,
-    IN PVOID SystemSpecific2,
-    IN PVOID SystemSpecific3)
-{
-
-	BA_REC_ENTRY    *pBAEntry = (BA_REC_ENTRY *)FunctionContext;
-	PRTMP_ADAPTER   pAd;
-	ULONG           Now32;
-
-	if (pBAEntry == NULL)
-		return;
-
-	if ((pBAEntry->REC_BA_Status == Recipient_Accept))
-	{
-		NdisGetSystemUpTime(&Now32);
-
-		if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer + REC_BA_SESSION_IDLE_TIMEOUT)))
-		{
-			pAd = pBAEntry->pAdapter;
-			// flush all pending reordering mpdus
-			ba_refresh_reordering_mpdus(pAd, pBAEntry);
-			DBGPRINT(RT_DEBUG_OFF, ("%ld: REC BA session Timeout\n", Now32));
-		}
-	}
-}
-
-
-VOID PeerAddBAReqAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-
-{
-	//	7.4.4.1
-	//ULONG	Idx;
-	UCHAR   Status = 1;
-	UCHAR   pAddr[6];
-	FRAME_ADDBA_RSP ADDframe;
-	PUCHAR         pOutBuffer = NULL;
-	NDIS_STATUS     NStatus;
-	PFRAME_ADDBA_REQ  pAddreqFrame = NULL;
-	//UCHAR		BufSize;
-	ULONG       FrameLen;
-	PULONG      ptemp;
-	PMAC_TABLE_ENTRY	pMacEntry;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("%s ==> (Wcid = %d)\n", __FUNCTION__, Elem->Wcid));
-
-	//hex_dump("AddBAReq", Elem->Msg, Elem->MsgLen);
-
-	//ADDBA Request from unknown peer, ignore this.
-	if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
-		return;
-
-	pMacEntry = &pAd->MacTab.Content[Elem->Wcid];
-	DBGPRINT(RT_DEBUG_TRACE,("BA - PeerAddBAReqAction----> \n"));
-	ptemp = (PULONG)Elem->Msg;
-	//DBGPRINT_RAW(RT_DEBUG_EMU, ("%08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x\n", *(ptemp), *(ptemp+1), *(ptemp+2), *(ptemp+3), *(ptemp+4), *(ptemp+5), *(ptemp+6), *(ptemp+7), *(ptemp+8)));
-
-	if (PeerAddBAReqActionSanity(pAd, Elem->Msg, Elem->MsgLen, pAddr))
-	{
-
-		if ((pAd->CommonCfg.bBADecline == FALSE) && IS_HT_STA(pMacEntry))
-		{
-			pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]);
-			DBGPRINT(RT_DEBUG_OFF, ("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid));
-			if (BARecSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pAddreqFrame))
-				Status = 0;
-			else
-				Status = 38; // more parameters have invalid values
-		}
-		else
-		{
-			Status = 37; // the request has been declined.
-		}
-	}
-
-	if (pAd->MacTab.Content[Elem->Wcid].ValidAsCLI)
-		ASSERT(pAd->MacTab.Content[Elem->Wcid].Sst == SST_ASSOC);
-
-	pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]);
-	// 2. Always send back ADDBA Response
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	 //Get an unused nonpaged memory
-	if (NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("ACTION - PeerBAAction() allocate memory failed \n"));
-		return;
-	}
-
-	NdisZeroMemory(&ADDframe, sizeof(FRAME_ADDBA_RSP));
-	// 2-1. Prepare ADDBA Response frame.
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		if (ADHOC_ON(pAd))
-			ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
-		else
-#ifdef QOS_DLS_SUPPORT
-		if (pAd->MacTab.Content[Elem->Wcid].ValidAsDls)
-			ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
-		else
-#endif // QOS_DLS_SUPPORT //
-		ActHeaderInit(pAd, &ADDframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
-	}
-#endif // CONFIG_STA_SUPPORT //
-	ADDframe.Category = CATEGORY_BA;
-	ADDframe.Action = ADDBA_RESP;
-	ADDframe.Token = pAddreqFrame->Token;
-	// What is the Status code??  need to check.
-	ADDframe.StatusCode = Status;
-	ADDframe.BaParm.BAPolicy = IMMED_BA;
-	ADDframe.BaParm.AMSDUSupported = 0;
-	ADDframe.BaParm.TID = pAddreqFrame->BaParm.TID;
-	ADDframe.BaParm.BufSize = min(((UCHAR)pAddreqFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
-	if (ADDframe.BaParm.BufSize == 0)
-	{
-		ADDframe.BaParm.BufSize = 64;
-	}
-	ADDframe.TimeOutValue = 0; //pAddreqFrame->TimeOutValue;
-
-	*(USHORT *)(&ADDframe.BaParm) = cpu2le16(*(USHORT *)(&ADDframe.BaParm));
-	ADDframe.StatusCode = cpu2le16(ADDframe.StatusCode);
-	ADDframe.TimeOutValue = cpu2le16(ADDframe.TimeOutValue);
-
-	MakeOutgoingFrame(pOutBuffer,               &FrameLen,
-					  sizeof(FRAME_ADDBA_RSP),  &ADDframe,
-			  END_OF_ARGS);
-	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("%s(%d): TID(%d), BufSize(%d) <== \n", __FUNCTION__, Elem->Wcid, ADDframe.BaParm.TID,
-							  ADDframe.BaParm.BufSize));
-}
-
-
-VOID PeerAddBARspAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-
-{
-	//UCHAR		Idx, i;
-	//PUCHAR		   pOutBuffer = NULL;
-	PFRAME_ADDBA_RSP    pFrame = NULL;
-	//PBA_ORI_ENTRY		pBAEntry;
-
-	//ADDBA Response from unknown peer, ignore this.
-	if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
-		return;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("%s ==> Wcid(%d)\n", __FUNCTION__, Elem->Wcid));
-
-	//hex_dump("PeerAddBARspAction()", Elem->Msg, Elem->MsgLen);
-
-	if (PeerAddBARspActionSanity(pAd, Elem->Msg, Elem->MsgLen))
-	{
-		pFrame = (PFRAME_ADDBA_RSP)(&Elem->Msg[0]);
-
-		DBGPRINT(RT_DEBUG_TRACE, ("\t\t StatusCode = %d\n", pFrame->StatusCode));
-		switch (pFrame->StatusCode)
-		{
-			case 0:
-				// I want a BAsession with this peer as an originator.
-				BAOriSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pFrame);
-				break;
-			default:
-				// check status == USED ???
-				BAOriSessionTearDown(pAd, Elem->Wcid, pFrame->BaParm.TID, TRUE, FALSE);
-				break;
-		}
-		// Rcv Decline StatusCode
-		if ((pFrame->StatusCode == 37)
-#ifdef CONFIG_STA_SUPPORT
-            || ((pAd->OpMode == OPMODE_STA) && STA_TGN_WIFI_ON(pAd) && (pFrame->StatusCode != 0))
-#endif // CONFIG_STA_SUPPORT //
-            )
-		{
-			pAd->MacTab.Content[Elem->Wcid].BADeclineBitmap |= 1<<pFrame->BaParm.TID;
-		}
-	}
-}
-
-VOID PeerDelBAAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-
-{
-	//UCHAR				Idx;
-	//PUCHAR				pOutBuffer = NULL;
-	PFRAME_DELBA_REQ    pDelFrame = NULL;
-
-	DBGPRINT(RT_DEBUG_TRACE,("%s ==>\n", __FUNCTION__));
-	//DELBA Request from unknown peer, ignore this.
-	if (PeerDelBAActionSanity(pAd, Elem->Wcid, Elem->Msg, Elem->MsgLen))
-	{
-		pDelFrame = (PFRAME_DELBA_REQ)(&Elem->Msg[0]);
-		if (pDelFrame->DelbaParm.Initiator == ORIGINATOR)
-		{
-			DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> ORIGINATOR\n"));
-			BARecSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE);
-		}
-		else
-		{
-			DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> RECIPIENT, Reason = %d\n",  pDelFrame->ReasonCode));
-			//hex_dump("DelBA Frame", pDelFrame, Elem->MsgLen);
-			BAOriSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE, FALSE);
-		}
-	}
-}
-
-
-BOOLEAN CntlEnqueueForRecv(
-						  IN PRTMP_ADAPTER		pAd,
-						  IN ULONG				Wcid,
-						  IN ULONG				MsgLen,
-						  IN PFRAME_BA_REQ		pMsg)
-{
-	PFRAME_BA_REQ   pFrame = pMsg;
-	//PRTMP_REORDERBUF	pBuffer;
-	//PRTMP_REORDERBUF	pDmaBuf;
-	PBA_REC_ENTRY pBAEntry;
-	//BOOLEAN	Result;
-	ULONG   Idx;
-	//UCHAR	NumRxPkt;
-	UCHAR	TID;//, i;
-
-	TID = (UCHAR)pFrame->BARControl.TID;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("%s(): BAR-Wcid(%ld), Tid (%d)\n", __FUNCTION__, Wcid, TID));
-	//hex_dump("BAR", (PCHAR) pFrame, MsgLen);
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return FALSE;
-
-	// First check the size, it MUST not exceed the mlme queue size
-	if (MsgLen > MGMT_DMA_BUFFER_SIZE)
-	{
-		DBGPRINT_ERR(("CntlEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
-		return FALSE;
-	}
-	else if (MsgLen != sizeof(FRAME_BA_REQ))
-	{
-		DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen));
-		return FALSE;
-	}
-	else if (MsgLen != sizeof(FRAME_BA_REQ))
-	{
-		DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen));
-		return FALSE;
-	}
-
-	if ((Wcid < MAX_LEN_OF_MAC_TABLE) && (TID < 8))
-		{
-		// if this receiving packet is from SA that is in our OriEntry. Since WCID <9 has direct mapping. no need search.
-		Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
-		pBAEntry = &pAd->BATable.BARecEntry[Idx];
-		}
-		else
-		{
-		return FALSE;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("BAR(%ld) : Tid (%d) - %04x:%04x\n", Wcid, TID, pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq ));
-
-	if (SEQ_SMALLER(pBAEntry->LastIndSeq, pFrame->BAStartingSeq.field.StartSeq, MAXSEQ))
-	{
-		//DBGPRINT(RT_DEBUG_TRACE, ("BAR Seq = %x, LastIndSeq = %x\n", pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq));
-		ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, pFrame->BAStartingSeq.field.StartSeq);
-		pBAEntry->LastIndSeq = (pFrame->BAStartingSeq.field.StartSeq == 0) ? MAXSEQ :(pFrame->BAStartingSeq.field.StartSeq -1);
-	}
-	//ba_refresh_reordering_mpdus(pAd, pBAEntry);
-	return TRUE;
-}
-
-/*
-Description : Send PSMP Action frame If PSMP mode switches.
-*/
-VOID SendPSMPAction(
-				   IN PRTMP_ADAPTER		pAd,
-				   IN UCHAR				Wcid,
-				   IN UCHAR				Psmp)
-{
-	PUCHAR          pOutBuffer = NULL;
-	NDIS_STATUS     NStatus;
-	//ULONG           Idx;
-	FRAME_PSMP_ACTION   Frame;
-	ULONG           FrameLen;
-
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	 //Get an unused nonpaged memory
-	if (NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));
-		return;
-	}
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[Wcid].Addr);
-#endif // CONFIG_STA_SUPPORT //
-
-	Frame.Category = CATEGORY_HT;
-	Frame.Action = SMPS_ACTION;
-	switch (Psmp)
-	{
-		case MMPS_ENABLE:
-#ifdef RT30xx
-			if (IS_RT30xx(pAd)
-				&&(pAd->Antenna.field.RxPath>1||pAd->Antenna.field.TxPath>1))
-			{
-				RTMP_ASIC_MMPS_DISABLE(pAd);
-			}
-#endif // RT30xx //
-			Frame.Psmp = 0;
-			break;
-		case MMPS_DYNAMIC:
-			Frame.Psmp = 3;
-			break;
-		case MMPS_STATIC:
-#ifdef RT30xx
-			if (IS_RT30xx(pAd)
-				&&(pAd->Antenna.field.RxPath>1||pAd->Antenna.field.TxPath>1))
-			{
-				RTMP_ASIC_MMPS_ENABLE(pAd);
-			}
-#endif // RT30xx //
-			Frame.Psmp = 1;
-			break;
-	}
-	MakeOutgoingFrame(pOutBuffer,               &FrameLen,
-					  sizeof(FRAME_PSMP_ACTION),      &Frame,
-					  END_OF_ARGS);
-	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-	DBGPRINT(RT_DEBUG_ERROR,("HT - SendPSMPAction( %d )  \n", Frame.Psmp));
-}
-
-
-#define RADIO_MEASUREMENT_REQUEST_ACTION	0
-
-typedef struct PACKED
-{
-	UCHAR	RegulatoryClass;
-	UCHAR	ChannelNumber;
-	USHORT	RandomInterval;
-	USHORT	MeasurementDuration;
-	UCHAR	MeasurementMode;
-	UCHAR   BSSID[MAC_ADDR_LEN];
-	UCHAR	ReportingCondition;
-	UCHAR	Threshold;
-	UCHAR   SSIDIE[2];			// 2 byte
-} BEACON_REQUEST;
-
-typedef struct PACKED
-{
-	UCHAR	ID;
-	UCHAR	Length;
-	UCHAR	Token;
-	UCHAR	RequestMode;
-	UCHAR	Type;
-} MEASUREMENT_REQ;
-
-
-
-
-void convert_reordering_packet_to_preAMSDU_or_802_3_packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN  UCHAR			FromWhichBSSID)
-{
-	PNDIS_PACKET	pRxPkt;
-	UCHAR			Header802_3[LENGTH_802_3];
-
-	// 1. get 802.3 Header
-	// 2. remove LLC
-	//		a. pointer pRxBlk->pData to payload
-	//      b. modify pRxBlk->DataSize
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
-#endif // CONFIG_STA_SUPPORT //
-
-	ASSERT(pRxBlk->pRxPacket);
-	pRxPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
-
-	SET_OS_PKT_NETDEV(pRxPkt, get_netdev_from_bssid(pAd, FromWhichBSSID));
-	SET_OS_PKT_DATAPTR(pRxPkt, pRxBlk->pData);
-	SET_OS_PKT_LEN(pRxPkt, pRxBlk->DataSize);
-	SET_OS_PKT_DATATAIL(pRxPkt, pRxBlk->pData, pRxBlk->DataSize);
-
-	//
-	// copy 802.3 header, if necessary
-	//
-	if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
-	{
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-#ifdef LINUX
-			NdisMoveMemory(skb_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3);
-#endif
-		}
-#endif // CONFIG_STA_SUPPORT //
-	}
-}
-
-
-#define INDICATE_LEGACY_OR_AMSDU(_pAd, _pRxBlk, _fromWhichBSSID)		\
-	do																	\
-	{																	\
-	if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_AMSDU))						\
-	{																\
-		Indicate_AMSDU_Packet(_pAd, _pRxBlk, _fromWhichBSSID);		\
-	}																\
-		else if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_EAP))					\
-		{																\
-			Indicate_EAPOL_Packet(_pAd, _pRxBlk, _fromWhichBSSID);		\
-		}																\
-	else															\
-	{																\
-		Indicate_Legacy_Packet(_pAd, _pRxBlk, _fromWhichBSSID);		\
-	}																\
-	} while (0);
-
-
-
-static VOID ba_enqueue_reordering_packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PBA_REC_ENTRY	pBAEntry,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID)
-{
-	struct reordering_mpdu *mpdu_blk;
-	UINT16	Sequence = (UINT16) pRxBlk->pHeader->Sequence;
-
-	mpdu_blk = ba_mpdu_blk_alloc(pAd);
-	if ((mpdu_blk != NULL) &&
-		(!RX_BLK_TEST_FLAG(pRxBlk, fRX_EAP)))
-	{
-		// Write RxD buffer address & allocated buffer length
-		NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
-
-		mpdu_blk->Sequence = Sequence;
-
-		mpdu_blk->bAMSDU = RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU);
-
-		convert_reordering_packet_to_preAMSDU_or_802_3_packet(pAd, pRxBlk, FromWhichBSSID);
-
-		STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
-
-        //
-		// it is necessary for reordering packet to record
-		// which BSS it come from
-		//
-		RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
-
-		mpdu_blk->pPacket = pRxBlk->pRxPacket;
-
-		if (ba_reordering_mpdu_insertsorted(&pBAEntry->list, mpdu_blk) == FALSE)
-		{
-			// had been already within reordering list
-			// don't indicate
-			RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_SUCCESS);
-			ba_mpdu_blk_free(pAd, mpdu_blk);
-		}
-
-		ASSERT((0<= pBAEntry->list.qlen)  && (pBAEntry->list.qlen <= pBAEntry->BAWinSize));
-		NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_ERROR,  ("!!! (%d) Can't allocate reordering mpdu blk\n",
-								   pBAEntry->list.qlen));
-		/*
-		 * flush all pending reordering mpdus
-		 * and receving mpdu to upper layer
-		 * make tcp/ip to take care reordering mechanism
-		 */
-		//ba_refresh_reordering_mpdus(pAd, pBAEntry);
-		ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
-
-		pBAEntry->LastIndSeq = Sequence;
-		INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
-	}
-}
-
-
-/*
-	==========================================================================
-	Description:
-		Indicate this packet to upper layer or put it into reordering buffer
-
-	Parametrs:
-		pRxBlk         : carry necessary packet info 802.11 format
-		FromWhichBSSID : the packet received from which BSS
-
-	Return	:
-			  none
-
-	Note    :
-	          the packet queued into reordering buffer need to cover to 802.3 format
-			  or pre_AMSDU format
-	==========================================================================
- */
-
-VOID Indicate_AMPDU_Packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID)
-{
-	USHORT				Idx;
-	PBA_REC_ENTRY		pBAEntry = NULL;
-	UINT16				Sequence = pRxBlk->pHeader->Sequence;
-	ULONG				Now32;
-	UCHAR				Wcid = pRxBlk->pRxWI->WirelessCliID;
-	UCHAR				TID = pRxBlk->pRxWI->TID;
-
-
-	if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU) &&  (pRxBlk->DataSize > MAX_RX_PKT_LEN))
-	{
-		// release packet
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
-		return;
-	}
-
-
-
-	if (Wcid < MAX_LEN_OF_MAC_TABLE)
-	{
-		Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
-		if (Idx == 0)
-		{
-			/* Rec BA Session had been torn down */
-			INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
-			return;
-		}
-		pBAEntry = &pAd->BATable.BARecEntry[Idx];
-	}
-	else
-	{
-		// impossible !!!
-		ASSERT(0);
-		// release packet
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
-		return;
-	}
-
-	ASSERT(pBAEntry);
-
-	// update last rx time
-	NdisGetSystemUpTime(&Now32);
-
-	pBAEntry->rcvSeq = Sequence;
-
-
-	ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
-	pBAEntry->LastIndSeqAtTimer = Now32;
-
-	//
-	// Reset Last Indicate Sequence
-	//
-	if (pBAEntry->LastIndSeq == RESET_RCV_SEQ)
-	{
-		ASSERT((pBAEntry->list.qlen == 0) && (pBAEntry->list.next == NULL));
-
-		// reset rcv sequence of BA session
-		pBAEntry->LastIndSeq = Sequence;
-		pBAEntry->LastIndSeqAtTimer = Now32;
-		INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
-		return;
-	}
-
-	//
-	// I. Check if in order.
-	//
-	if (SEQ_STEPONE(Sequence, pBAEntry->LastIndSeq, MAXSEQ))
-	{
-		USHORT  LastIndSeq;
-
-		pBAEntry->LastIndSeq = Sequence;
-		INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
-		LastIndSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq);
-		if (LastIndSeq != RESET_RCV_SEQ)
-		{
-			pBAEntry->LastIndSeq = LastIndSeq;
-		}
-		pBAEntry->LastIndSeqAtTimer = Now32;
-	}
-	//
-	// II. Drop Duplicated Packet
-	//
-	else if (Sequence == pBAEntry->LastIndSeq)
-	{
-
-		// drop and release packet
-		pBAEntry->nDropPacket++;
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
-	}
-	//
-	// III. Drop Old Received Packet
-	//
-	else if (SEQ_SMALLER(Sequence, pBAEntry->LastIndSeq, MAXSEQ))
-	{
-
-		// drop and release packet
-		pBAEntry->nDropPacket++;
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
-	}
-	//
-	// IV. Receive Sequence within Window Size
-	//
-	else if (SEQ_SMALLER(Sequence, (((pBAEntry->LastIndSeq+pBAEntry->BAWinSize+1)) & MAXSEQ), MAXSEQ))
-	{
-		ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID);
-	}
-	//
-	// V. Receive seq surpasses Win(lastseq + nMSDU). So refresh all reorder buffer
-	//
-	else
-	{
-		LONG WinStartSeq, TmpSeq;
-
-
-		TmpSeq = Sequence - (pBAEntry->BAWinSize) -1;
-		if (TmpSeq < 0)
-		{
-			TmpSeq = (MAXSEQ+1) + TmpSeq;
-		}
-		WinStartSeq = (TmpSeq+1) & MAXSEQ;
-		ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, WinStartSeq);
-		pBAEntry->LastIndSeq = WinStartSeq; //TmpSeq;
-
-		pBAEntry->LastIndSeqAtTimer = Now32;
-
-		ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID);
-
-		TmpSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq);
-		if (TmpSeq != RESET_RCV_SEQ)
-		{
-			pBAEntry->LastIndSeq = TmpSeq;
-		}
-	}
-}
-
-#endif // DOT11_N_SUPPORT //
diff --git a/drivers/staging/rt3090/common/cmm_aes.c b/drivers/staging/rt3090/common/cmm_aes.c
deleted file mode 100644
index 4ccbbbf..0000000
--- a/drivers/staging/rt3090/common/cmm_aes.c
+++ /dev/null
@@ -1,1560 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	cmm_aes.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Paul Wu		02-25-02		Initial
-*/
-
-#include "../rt_config.h"
-
-
-typedef	struct
-{
-    UINT32 erk[64];     /* encryption round keys */
-    UINT32 drk[64];     /* decryption round keys */
-    int nr;             /* number of rounds */
-}
-aes_context;
-
-/*****************************/
-/******** SBOX Table *********/
-/*****************************/
-
-UCHAR SboxTable[256] =
-{
-	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
-	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
-	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
-	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
-	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
-	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
-	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
-	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
-	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
-	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
-	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
-	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
-	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
-	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
-	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
-	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
-	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
-	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
-	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
-	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
-	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
-	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
-	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
-	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
-	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
-	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
-	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
-	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
-	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
-	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
-	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
-	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-};
-
-VOID xor_32(
-	IN  PUCHAR  a,
-	IN  PUCHAR  b,
-	OUT PUCHAR  out)
-{
-	INT i;
-
-	for (i=0;i<4; i++)
-	{
-		out[i] = a[i] ^ b[i];
-	}
-}
-
-VOID xor_128(
-	IN  PUCHAR  a,
-	IN  PUCHAR  b,
-	OUT PUCHAR  out)
-{
-	INT i;
-
-	for (i=0;i<16; i++)
-	{
-		out[i] = a[i] ^ b[i];
-	}
-}
-
-UCHAR RTMPCkipSbox(
-	IN  UCHAR   a)
-{
-	return SboxTable[(int)a];
-}
-
-VOID next_key(
-	IN  PUCHAR  key,
-	IN  INT     round)
-{
-	UCHAR       rcon;
-	UCHAR       sbox_key[4];
-	UCHAR       rcon_table[12] =
-	{
-		0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
-		0x1b, 0x36, 0x36, 0x36
-	};
-
-	sbox_key[0] = RTMPCkipSbox(key[13]);
-	sbox_key[1] = RTMPCkipSbox(key[14]);
-	sbox_key[2] = RTMPCkipSbox(key[15]);
-	sbox_key[3] = RTMPCkipSbox(key[12]);
-
-	rcon = rcon_table[round];
-
-	xor_32(&key[0], sbox_key, &key[0]);
-	key[0] = key[0] ^ rcon;
-
-	xor_32(&key[4], &key[0], &key[4]);
-	xor_32(&key[8], &key[4], &key[8]);
-	xor_32(&key[12], &key[8], &key[12]);
-}
-
-VOID byte_sub(
-	IN  PUCHAR  in,
-	OUT PUCHAR  out)
-{
-	INT i;
-
-	for (i=0; i< 16; i++)
-	{
-		out[i] = RTMPCkipSbox(in[i]);
-	}
-}
-
-/************************************/
-/* bitwise_xor()                    */
-/* A 128 bit, bitwise exclusive or  */
-/************************************/
-
-void bitwise_xor(unsigned char *ina, unsigned char *inb, unsigned char *out)
-{
-	int i;
-	for (i=0; i<16; i++)
-	{
-		out[i] = ina[i] ^ inb[i];
-	}
-}
-
-VOID shift_row(
-	IN  PUCHAR  in,
-	OUT PUCHAR  out)
-{
-	out[0] =  in[0];
-	out[1] =  in[5];
-	out[2] =  in[10];
-	out[3] =  in[15];
-	out[4] =  in[4];
-	out[5] =  in[9];
-	out[6] =  in[14];
-	out[7] =  in[3];
-	out[8] =  in[8];
-	out[9] =  in[13];
-	out[10] = in[2];
-	out[11] = in[7];
-	out[12] = in[12];
-	out[13] = in[1];
-	out[14] = in[6];
-	out[15] = in[11];
-}
-
-VOID mix_column(
-	IN  PUCHAR  in,
-	OUT PUCHAR  out)
-{
-	INT         i;
-	UCHAR       add1b[4];
-	UCHAR       add1bf7[4];
-	UCHAR       rotl[4];
-	UCHAR       swap_halfs[4];
-	UCHAR       andf7[4];
-	UCHAR       rotr[4];
-	UCHAR       temp[4];
-	UCHAR       tempb[4];
-
-	for (i=0 ; i<4; i++)
-	{
-		if ((in[i] & 0x80)== 0x80)
-			add1b[i] = 0x1b;
-		else
-			add1b[i] = 0x00;
-	}
-
-	swap_halfs[0] = in[2];    /* Swap halfs */
-	swap_halfs[1] = in[3];
-	swap_halfs[2] = in[0];
-	swap_halfs[3] = in[1];
-
-	rotl[0] = in[3];        /* Rotate left 8 bits */
-	rotl[1] = in[0];
-	rotl[2] = in[1];
-	rotl[3] = in[2];
-
-	andf7[0] = in[0] & 0x7f;
-	andf7[1] = in[1] & 0x7f;
-	andf7[2] = in[2] & 0x7f;
-	andf7[3] = in[3] & 0x7f;
-
-	for (i = 3; i>0; i--)    /* logical shift left 1 bit */
-	{
-		andf7[i] = andf7[i] << 1;
-		if ((andf7[i-1] & 0x80) == 0x80)
-		{
-			andf7[i] = (andf7[i] | 0x01);
-		}
-	}
-	andf7[0] = andf7[0] << 1;
-	andf7[0] = andf7[0] & 0xfe;
-
-	xor_32(add1b, andf7, add1bf7);
-
-	xor_32(in, add1bf7, rotr);
-
-	temp[0] = rotr[0];         /* Rotate right 8 bits */
-	rotr[0] = rotr[1];
-	rotr[1] = rotr[2];
-	rotr[2] = rotr[3];
-	rotr[3] = temp[0];
-
-	xor_32(add1bf7, rotr, temp);
-	xor_32(swap_halfs, rotl,tempb);
-	xor_32(temp, tempb, out);
-}
-
-
-/************************************************/
-/* construct_mic_header1()                      */
-/* Builds the first MIC header block from       */
-/* header fields.                               */
-/************************************************/
-
-void construct_mic_header1(
-	unsigned char *mic_header1,
-	int header_length,
-	unsigned char *mpdu)
-{
-	mic_header1[0] = (unsigned char)((header_length - 2) / 256);
-	mic_header1[1] = (unsigned char)((header_length - 2) % 256);
-	mic_header1[2] = mpdu[0] & 0xcf;    /* Mute CF poll & CF ack bits */
-	mic_header1[3] = mpdu[1] & 0xc7;    /* Mute retry, more data and pwr mgt bits */
-	mic_header1[4] = mpdu[4];       /* A1 */
-	mic_header1[5] = mpdu[5];
-	mic_header1[6] = mpdu[6];
-	mic_header1[7] = mpdu[7];
-	mic_header1[8] = mpdu[8];
-	mic_header1[9] = mpdu[9];
-	mic_header1[10] = mpdu[10];     /* A2 */
-	mic_header1[11] = mpdu[11];
-	mic_header1[12] = mpdu[12];
-	mic_header1[13] = mpdu[13];
-	mic_header1[14] = mpdu[14];
-	mic_header1[15] = mpdu[15];
-}
-
-/************************************************/
-/* construct_mic_header2()                      */
-/* Builds the last MIC header block from        */
-/* header fields.                               */
-/************************************************/
-
-void construct_mic_header2(
-	unsigned char *mic_header2,
-	unsigned char *mpdu,
-	int a4_exists,
-	int qc_exists)
-{
-	int i;
-
-	for (i = 0; i<16; i++) mic_header2[i]=0x00;
-
-	mic_header2[0] = mpdu[16];    /* A3 */
-	mic_header2[1] = mpdu[17];
-	mic_header2[2] = mpdu[18];
-	mic_header2[3] = mpdu[19];
-	mic_header2[4] = mpdu[20];
-	mic_header2[5] = mpdu[21];
-
-	// In Sequence Control field, mute sequence numer bits (12-bit)
-	mic_header2[6] = mpdu[22] & 0x0f;   /* SC */
-	mic_header2[7] = 0x00; /* mpdu[23]; */
-
-	if ((!qc_exists) & a4_exists)
-	{
-		for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i];   /* A4 */
-
-	}
-
-	if (qc_exists && (!a4_exists))
-	{
-		mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
-		mic_header2[9] = mpdu[25] & 0x00;
-	}
-
-	if (qc_exists && a4_exists)
-	{
-		for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i];   /* A4 */
-
-		mic_header2[14] = mpdu[30] & 0x0f;
-		mic_header2[15] = mpdu[31] & 0x00;
-	}
-}
-
-
-/************************************************/
-/* construct_mic_iv()                           */
-/* Builds the MIC IV from header fields and PN  */
-/************************************************/
-
-void construct_mic_iv(
-	unsigned char *mic_iv,
-	int qc_exists,
-	int a4_exists,
-	unsigned char *mpdu,
-	unsigned int payload_length,
-	unsigned char *pn_vector)
-{
-	int i;
-
-	mic_iv[0] = 0x59;
-	if (qc_exists && a4_exists)
-		mic_iv[1] = mpdu[30] & 0x0f;    /* QoS_TC           */
-	if (qc_exists && !a4_exists)
-		mic_iv[1] = mpdu[24] & 0x0f;   /* mute bits 7-4    */
-	if (!qc_exists)
-		mic_iv[1] = 0x00;
-	for (i = 2; i < 8; i++)
-		mic_iv[i] = mpdu[i + 8];                    /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
-#ifdef CONSISTENT_PN_ORDER
-		for (i = 8; i < 14; i++)
-			mic_iv[i] = pn_vector[i - 8];           /* mic_iv[8:13] = PN[0:5] */
-#else
-		for (i = 8; i < 14; i++)
-			mic_iv[i] = pn_vector[13 - i];          /* mic_iv[8:13] = PN[5:0] */
-#endif
-	i = (payload_length / 256);
-	i = (payload_length % 256);
-	mic_iv[14] = (unsigned char) (payload_length / 256);
-	mic_iv[15] = (unsigned char) (payload_length % 256);
-
-}
-
-/****************************************/
-/* aes128k128d()                        */
-/* Performs a 128 bit AES encrypt with  */
-/* 128 bit data.                        */
-/****************************************/
-void aes128k128d(unsigned char *key, unsigned char *data, unsigned char *ciphertext)
-{
-	int round;
-	int i;
-	unsigned char intermediatea[16];
-	unsigned char intermediateb[16];
-	unsigned char round_key[16];
-
-	for(i=0; i<16; i++) round_key[i] = key[i];
-
-	for (round = 0; round < 11; round++)
-	{
-		if (round == 0)
-		{
-			xor_128(round_key, data, ciphertext);
-			next_key(round_key, round);
-		}
-		else if (round == 10)
-		{
-			byte_sub(ciphertext, intermediatea);
-			shift_row(intermediatea, intermediateb);
-			xor_128(intermediateb, round_key, ciphertext);
-		}
-		else    /* 1 - 9 */
-		{
-			byte_sub(ciphertext, intermediatea);
-			shift_row(intermediatea, intermediateb);
-			mix_column(&intermediateb[0], &intermediatea[0]);
-			mix_column(&intermediateb[4], &intermediatea[4]);
-			mix_column(&intermediateb[8], &intermediatea[8]);
-			mix_column(&intermediateb[12], &intermediatea[12]);
-			xor_128(intermediatea, round_key, ciphertext);
-			next_key(round_key, round);
-		}
-	}
-
-}
-
-void construct_ctr_preload(
-	unsigned char *ctr_preload,
-	int a4_exists,
-	int qc_exists,
-	unsigned char *mpdu,
-	unsigned char *pn_vector,
-	int c)
-{
-
-	int i = 0;
-	for (i=0; i<16; i++) ctr_preload[i] = 0x00;
-	i = 0;
-
-	ctr_preload[0] = 0x01;                                  /* flag */
-	if (qc_exists && a4_exists) ctr_preload[1] = mpdu[30] & 0x0f;   /* QoC_Control  */
-	if (qc_exists && !a4_exists) ctr_preload[1] = mpdu[24] & 0x0f;
-
-	for (i = 2; i < 8; i++)
-		ctr_preload[i] = mpdu[i + 8];                       /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
-#ifdef CONSISTENT_PN_ORDER
-	  for (i = 8; i < 14; i++)
-			ctr_preload[i] =    pn_vector[i - 8];           /* ctr_preload[8:13] = PN[0:5] */
-#else
-	  for (i = 8; i < 14; i++)
-			ctr_preload[i] =    pn_vector[13 - i];          /* ctr_preload[8:13] = PN[5:0] */
-#endif
-	ctr_preload[14] =  (unsigned char) (c / 256); // Ctr
-	ctr_preload[15] =  (unsigned char) (c % 256);
-
-}
-
-BOOLEAN RTMPSoftDecryptAES(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR	pData,
-	IN ULONG	DataByteCnt,
-	IN PCIPHER_KEY	pWpaKey)
-{
-	UCHAR			KeyID;
-	UINT			HeaderLen;
-	UCHAR			PN[6];
-	UINT			payload_len;
-	UINT			num_blocks;
-	UINT			payload_remainder;
-	USHORT			fc;
-	UCHAR			fc0;
-	UCHAR			fc1;
-	UINT			frame_type;
-	UINT			frame_subtype;
-	UINT			from_ds;
-	UINT			to_ds;
-	INT				a4_exists;
-	INT				qc_exists;
-	UCHAR			aes_out[16];
-	int			payload_index;
-	UINT			i;
-	UCHAR			ctr_preload[16];
-	UCHAR			chain_buffer[16];
-	UCHAR			padded_buffer[16];
-	UCHAR			mic_iv[16];
-	UCHAR			mic_header1[16];
-	UCHAR			mic_header2[16];
-	UCHAR			MIC[8];
-	UCHAR			TrailMIC[8];
-
-#ifdef RT_BIG_ENDIAN
-	RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
-#endif
-
-	fc0 = *pData;
-	fc1 = *(pData + 1);
-
-	fc = *((PUSHORT)pData);
-
-	frame_type = ((fc0 >> 2) & 0x03);
-	frame_subtype = ((fc0 >> 4) & 0x0f);
-
-	from_ds = (fc1 & 0x2) >> 1;
-	to_ds = (fc1 & 0x1);
-
-	a4_exists = (from_ds & to_ds);
-	qc_exists = ((frame_subtype == 0x08) ||    /* Assumed QoS subtypes */
-				  (frame_subtype == 0x09) ||   /* Likely to change.    */
-				  (frame_subtype == 0x0a) ||
-				  (frame_subtype == 0x0b)
-				 );
-
-	HeaderLen = 24;
-	if (a4_exists)
-		HeaderLen += 6;
-
-	KeyID = *((PUCHAR)(pData+ HeaderLen + 3));
-	KeyID = KeyID >> 6;
-
-	if (pWpaKey[KeyID].KeyLen == 0)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptAES failed!(KeyID[%d] Length can not be 0)\n", KeyID));
-		return FALSE;
-	}
-
-	PN[0] = *(pData+ HeaderLen);
-	PN[1] = *(pData+ HeaderLen + 1);
-	PN[2] = *(pData+ HeaderLen + 4);
-	PN[3] = *(pData+ HeaderLen + 5);
-	PN[4] = *(pData+ HeaderLen + 6);
-	PN[5] = *(pData+ HeaderLen + 7);
-
-	payload_len = DataByteCnt - HeaderLen - 8 - 8;	// 8 bytes for CCMP header , 8 bytes for MIC
-	payload_remainder = (payload_len) % 16;
-	num_blocks = (payload_len) / 16;
-
-
-
-	// Find start of payload
-	payload_index = HeaderLen + 8; //IV+EIV
-
-	for (i=0; i< num_blocks; i++)
-	{
-		construct_ctr_preload(ctr_preload,
-								a4_exists,
-								qc_exists,
-								pData,
-								PN,
-								i+1 );
-
-		aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
-
-		bitwise_xor(aes_out, pData + payload_index, chain_buffer);
-		NdisMoveMemory(pData + payload_index - 8, chain_buffer, 16);
-		payload_index += 16;
-	}
-
-	//
-	// If there is a short final block, then pad it
-	// encrypt it and copy the unpadded part back
-	//
-	if (payload_remainder > 0)
-	{
-		construct_ctr_preload(ctr_preload,
-								a4_exists,
-								qc_exists,
-								pData,
-								PN,
-								num_blocks + 1);
-
-		NdisZeroMemory(padded_buffer, 16);
-		NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
-
-		aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
-
-		bitwise_xor(aes_out, padded_buffer, chain_buffer);
-		NdisMoveMemory(pData + payload_index - 8, chain_buffer, payload_remainder);
-		payload_index += payload_remainder;
-	}
-
-	//
-	// Descrypt the MIC
-	//
-	construct_ctr_preload(ctr_preload,
-							a4_exists,
-							qc_exists,
-							pData,
-							PN,
-							0);
-	NdisZeroMemory(padded_buffer, 16);
-	NdisMoveMemory(padded_buffer, pData + payload_index, 8);
-
-	aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
-
-	bitwise_xor(aes_out, padded_buffer, chain_buffer);
-
-	NdisMoveMemory(TrailMIC, chain_buffer, 8);
-
-
-	//
-	// Calculate MIC
-	//
-
-	//Force the protected frame bit on
-	*(pData + 1) = *(pData + 1) | 0x40;
-
-	// Find start of payload
-	// Because the CCMP header has been removed
-	payload_index = HeaderLen;
-
-	construct_mic_iv(
-					mic_iv,
-					qc_exists,
-					a4_exists,
-					pData,
-					payload_len,
-					PN);
-
-	construct_mic_header1(
-						mic_header1,
-						HeaderLen,
-						pData);
-
-	construct_mic_header2(
-						mic_header2,
-						pData,
-						a4_exists,
-						qc_exists);
-
-	aes128k128d(pWpaKey[KeyID].Key, mic_iv, aes_out);
-	bitwise_xor(aes_out, mic_header1, chain_buffer);
-	aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
-	bitwise_xor(aes_out, mic_header2, chain_buffer);
-	aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
-
-	// iterate through each 16 byte payload block
-	for (i = 0; i < num_blocks; i++)
-	{
-		bitwise_xor(aes_out, pData + payload_index, chain_buffer);
-		payload_index += 16;
-		aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
-	}
-
-	// Add on the final payload block if it needs padding
-	if (payload_remainder > 0)
-	{
-		NdisZeroMemory(padded_buffer, 16);
-		NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
-
-		bitwise_xor(aes_out, padded_buffer, chain_buffer);
-		aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
-	}
-
-	// aes_out contains padded mic, discard most significant
-	// 8 bytes to generate 64 bit MIC
-	for (i = 0 ; i < 8; i++) MIC[i] = aes_out[i];
-
-	if (!NdisEqualMemory(MIC, TrailMIC, 8))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptAES, MIC Error !\n"));	 //MIC error.
-		return FALSE;
-	}
-
-#ifdef RT_BIG_ENDIAN
-	RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
-#endif
-
-	return TRUE;
-}
-
-/* =========================  AES En/Decryption ========================== */
-#ifndef	uint8
-#define	uint8  unsigned	char
-#endif
-
-#ifndef	uint32
-#define	uint32 unsigned	int
-#endif
-
-/* forward S-box */
-static uint32 FSb[256] =
-{
-	0x63, 0x7C,	0x77, 0x7B,	0xF2, 0x6B,	0x6F, 0xC5,
-	0x30, 0x01,	0x67, 0x2B,	0xFE, 0xD7,	0xAB, 0x76,
-	0xCA, 0x82,	0xC9, 0x7D,	0xFA, 0x59,	0x47, 0xF0,
-	0xAD, 0xD4,	0xA2, 0xAF,	0x9C, 0xA4,	0x72, 0xC0,
-	0xB7, 0xFD,	0x93, 0x26,	0x36, 0x3F,	0xF7, 0xCC,
-	0x34, 0xA5,	0xE5, 0xF1,	0x71, 0xD8,	0x31, 0x15,
-	0x04, 0xC7,	0x23, 0xC3,	0x18, 0x96,	0x05, 0x9A,
-	0x07, 0x12,	0x80, 0xE2,	0xEB, 0x27,	0xB2, 0x75,
-	0x09, 0x83,	0x2C, 0x1A,	0x1B, 0x6E,	0x5A, 0xA0,
-	0x52, 0x3B,	0xD6, 0xB3,	0x29, 0xE3,	0x2F, 0x84,
-	0x53, 0xD1,	0x00, 0xED,	0x20, 0xFC,	0xB1, 0x5B,
-	0x6A, 0xCB,	0xBE, 0x39,	0x4A, 0x4C,	0x58, 0xCF,
-	0xD0, 0xEF,	0xAA, 0xFB,	0x43, 0x4D,	0x33, 0x85,
-	0x45, 0xF9,	0x02, 0x7F,	0x50, 0x3C,	0x9F, 0xA8,
-	0x51, 0xA3,	0x40, 0x8F,	0x92, 0x9D,	0x38, 0xF5,
-	0xBC, 0xB6,	0xDA, 0x21,	0x10, 0xFF,	0xF3, 0xD2,
-	0xCD, 0x0C,	0x13, 0xEC,	0x5F, 0x97,	0x44, 0x17,
-	0xC4, 0xA7,	0x7E, 0x3D,	0x64, 0x5D,	0x19, 0x73,
-	0x60, 0x81,	0x4F, 0xDC,	0x22, 0x2A,	0x90, 0x88,
-	0x46, 0xEE,	0xB8, 0x14,	0xDE, 0x5E,	0x0B, 0xDB,
-	0xE0, 0x32,	0x3A, 0x0A,	0x49, 0x06,	0x24, 0x5C,
-	0xC2, 0xD3,	0xAC, 0x62,	0x91, 0x95,	0xE4, 0x79,
-	0xE7, 0xC8,	0x37, 0x6D,	0x8D, 0xD5,	0x4E, 0xA9,
-	0x6C, 0x56,	0xF4, 0xEA,	0x65, 0x7A,	0xAE, 0x08,
-	0xBA, 0x78,	0x25, 0x2E,	0x1C, 0xA6,	0xB4, 0xC6,
-	0xE8, 0xDD,	0x74, 0x1F,	0x4B, 0xBD,	0x8B, 0x8A,
-	0x70, 0x3E,	0xB5, 0x66,	0x48, 0x03,	0xF6, 0x0E,
-	0x61, 0x35,	0x57, 0xB9,	0x86, 0xC1,	0x1D, 0x9E,
-	0xE1, 0xF8,	0x98, 0x11,	0x69, 0xD9,	0x8E, 0x94,
-	0x9B, 0x1E,	0x87, 0xE9,	0xCE, 0x55,	0x28, 0xDF,
-	0x8C, 0xA1,	0x89, 0x0D,	0xBF, 0xE6,	0x42, 0x68,
-	0x41, 0x99,	0x2D, 0x0F,	0xB0, 0x54,	0xBB, 0x16
-};
-
-/* forward table */
-#define	FT \
-\
-	V(C6,63,63,A5),	V(F8,7C,7C,84),	V(EE,77,77,99),	V(F6,7B,7B,8D),	\
-	V(FF,F2,F2,0D),	V(D6,6B,6B,BD),	V(DE,6F,6F,B1),	V(91,C5,C5,54),	\
-	V(60,30,30,50),	V(02,01,01,03),	V(CE,67,67,A9),	V(56,2B,2B,7D),	\
-	V(E7,FE,FE,19),	V(B5,D7,D7,62),	V(4D,AB,AB,E6),	V(EC,76,76,9A),	\
-	V(8F,CA,CA,45),	V(1F,82,82,9D),	V(89,C9,C9,40),	V(FA,7D,7D,87),	\
-	V(EF,FA,FA,15),	V(B2,59,59,EB),	V(8E,47,47,C9),	V(FB,F0,F0,0B),	\
-	V(41,AD,AD,EC),	V(B3,D4,D4,67),	V(5F,A2,A2,FD),	V(45,AF,AF,EA),	\
-	V(23,9C,9C,BF),	V(53,A4,A4,F7),	V(E4,72,72,96),	V(9B,C0,C0,5B),	\
-	V(75,B7,B7,C2),	V(E1,FD,FD,1C),	V(3D,93,93,AE),	V(4C,26,26,6A),	\
-	V(6C,36,36,5A),	V(7E,3F,3F,41),	V(F5,F7,F7,02),	V(83,CC,CC,4F),	\
-	V(68,34,34,5C),	V(51,A5,A5,F4),	V(D1,E5,E5,34),	V(F9,F1,F1,08),	\
-	V(E2,71,71,93),	V(AB,D8,D8,73),	V(62,31,31,53),	V(2A,15,15,3F),	\
-	V(08,04,04,0C),	V(95,C7,C7,52),	V(46,23,23,65),	V(9D,C3,C3,5E),	\
-	V(30,18,18,28),	V(37,96,96,A1),	V(0A,05,05,0F),	V(2F,9A,9A,B5),	\
-	V(0E,07,07,09),	V(24,12,12,36),	V(1B,80,80,9B),	V(DF,E2,E2,3D),	\
-	V(CD,EB,EB,26),	V(4E,27,27,69),	V(7F,B2,B2,CD),	V(EA,75,75,9F),	\
-	V(12,09,09,1B),	V(1D,83,83,9E),	V(58,2C,2C,74),	V(34,1A,1A,2E),	\
-	V(36,1B,1B,2D),	V(DC,6E,6E,B2),	V(B4,5A,5A,EE),	V(5B,A0,A0,FB),	\
-	V(A4,52,52,F6),	V(76,3B,3B,4D),	V(B7,D6,D6,61),	V(7D,B3,B3,CE),	\
-	V(52,29,29,7B),	V(DD,E3,E3,3E),	V(5E,2F,2F,71),	V(13,84,84,97),	\
-	V(A6,53,53,F5),	V(B9,D1,D1,68),	V(00,00,00,00),	V(C1,ED,ED,2C),	\
-	V(40,20,20,60),	V(E3,FC,FC,1F),	V(79,B1,B1,C8),	V(B6,5B,5B,ED),	\
-	V(D4,6A,6A,BE),	V(8D,CB,CB,46),	V(67,BE,BE,D9),	V(72,39,39,4B),	\
-	V(94,4A,4A,DE),	V(98,4C,4C,D4),	V(B0,58,58,E8),	V(85,CF,CF,4A),	\
-	V(BB,D0,D0,6B),	V(C5,EF,EF,2A),	V(4F,AA,AA,E5),	V(ED,FB,FB,16),	\
-	V(86,43,43,C5),	V(9A,4D,4D,D7),	V(66,33,33,55),	V(11,85,85,94),	\
-	V(8A,45,45,CF),	V(E9,F9,F9,10),	V(04,02,02,06),	V(FE,7F,7F,81),	\
-	V(A0,50,50,F0),	V(78,3C,3C,44),	V(25,9F,9F,BA),	V(4B,A8,A8,E3),	\
-	V(A2,51,51,F3),	V(5D,A3,A3,FE),	V(80,40,40,C0),	V(05,8F,8F,8A),	\
-	V(3F,92,92,AD),	V(21,9D,9D,BC),	V(70,38,38,48),	V(F1,F5,F5,04),	\
-	V(63,BC,BC,DF),	V(77,B6,B6,C1),	V(AF,DA,DA,75),	V(42,21,21,63),	\
-	V(20,10,10,30),	V(E5,FF,FF,1A),	V(FD,F3,F3,0E),	V(BF,D2,D2,6D),	\
-	V(81,CD,CD,4C),	V(18,0C,0C,14),	V(26,13,13,35),	V(C3,EC,EC,2F),	\
-	V(BE,5F,5F,E1),	V(35,97,97,A2),	V(88,44,44,CC),	V(2E,17,17,39),	\
-	V(93,C4,C4,57),	V(55,A7,A7,F2),	V(FC,7E,7E,82),	V(7A,3D,3D,47),	\
-	V(C8,64,64,AC),	V(BA,5D,5D,E7),	V(32,19,19,2B),	V(E6,73,73,95),	\
-	V(C0,60,60,A0),	V(19,81,81,98),	V(9E,4F,4F,D1),	V(A3,DC,DC,7F),	\
-	V(44,22,22,66),	V(54,2A,2A,7E),	V(3B,90,90,AB),	V(0B,88,88,83),	\
-	V(8C,46,46,CA),	V(C7,EE,EE,29),	V(6B,B8,B8,D3),	V(28,14,14,3C),	\
-	V(A7,DE,DE,79),	V(BC,5E,5E,E2),	V(16,0B,0B,1D),	V(AD,DB,DB,76),	\
-	V(DB,E0,E0,3B),	V(64,32,32,56),	V(74,3A,3A,4E),	V(14,0A,0A,1E),	\
-	V(92,49,49,DB),	V(0C,06,06,0A),	V(48,24,24,6C),	V(B8,5C,5C,E4),	\
-	V(9F,C2,C2,5D),	V(BD,D3,D3,6E),	V(43,AC,AC,EF),	V(C4,62,62,A6),	\
-	V(39,91,91,A8),	V(31,95,95,A4),	V(D3,E4,E4,37),	V(F2,79,79,8B),	\
-	V(D5,E7,E7,32),	V(8B,C8,C8,43),	V(6E,37,37,59),	V(DA,6D,6D,B7),	\
-	V(01,8D,8D,8C),	V(B1,D5,D5,64),	V(9C,4E,4E,D2),	V(49,A9,A9,E0),	\
-	V(D8,6C,6C,B4),	V(AC,56,56,FA),	V(F3,F4,F4,07),	V(CF,EA,EA,25),	\
-	V(CA,65,65,AF),	V(F4,7A,7A,8E),	V(47,AE,AE,E9),	V(10,08,08,18),	\
-	V(6F,BA,BA,D5),	V(F0,78,78,88),	V(4A,25,25,6F),	V(5C,2E,2E,72),	\
-	V(38,1C,1C,24),	V(57,A6,A6,F1),	V(73,B4,B4,C7),	V(97,C6,C6,51),	\
-	V(CB,E8,E8,23),	V(A1,DD,DD,7C),	V(E8,74,74,9C),	V(3E,1F,1F,21),	\
-	V(96,4B,4B,DD),	V(61,BD,BD,DC),	V(0D,8B,8B,86),	V(0F,8A,8A,85),	\
-	V(E0,70,70,90),	V(7C,3E,3E,42),	V(71,B5,B5,C4),	V(CC,66,66,AA),	\
-	V(90,48,48,D8),	V(06,03,03,05),	V(F7,F6,F6,01),	V(1C,0E,0E,12),	\
-	V(C2,61,61,A3),	V(6A,35,35,5F),	V(AE,57,57,F9),	V(69,B9,B9,D0),	\
-	V(17,86,86,91),	V(99,C1,C1,58),	V(3A,1D,1D,27),	V(27,9E,9E,B9),	\
-	V(D9,E1,E1,38),	V(EB,F8,F8,13),	V(2B,98,98,B3),	V(22,11,11,33),	\
-	V(D2,69,69,BB),	V(A9,D9,D9,70),	V(07,8E,8E,89),	V(33,94,94,A7),	\
-	V(2D,9B,9B,B6),	V(3C,1E,1E,22),	V(15,87,87,92),	V(C9,E9,E9,20),	\
-	V(87,CE,CE,49),	V(AA,55,55,FF),	V(50,28,28,78),	V(A5,DF,DF,7A),	\
-	V(03,8C,8C,8F),	V(59,A1,A1,F8),	V(09,89,89,80),	V(1A,0D,0D,17),	\
-	V(65,BF,BF,DA),	V(D7,E6,E6,31),	V(84,42,42,C6),	V(D0,68,68,B8),	\
-	V(82,41,41,C3),	V(29,99,99,B0),	V(5A,2D,2D,77),	V(1E,0F,0F,11),	\
-	V(7B,B0,B0,CB),	V(A8,54,54,FC),	V(6D,BB,BB,D6),	V(2C,16,16,3A)
-
-#define	V(a,b,c,d) 0x##a##b##c##d
-static uint32 FT0[256] = { FT };
-#undef V
-
-#define	V(a,b,c,d) 0x##d##a##b##c
-static uint32 FT1[256] = { FT };
-#undef V
-
-#define	V(a,b,c,d) 0x##c##d##a##b
-static uint32 FT2[256] = { FT };
-#undef V
-
-#define	V(a,b,c,d) 0x##b##c##d##a
-static uint32 FT3[256] = { FT };
-#undef V
-
-#undef FT
-
-/* reverse S-box */
-
-static uint32 RSb[256] =
-{
-	0x52, 0x09,	0x6A, 0xD5,	0x30, 0x36,	0xA5, 0x38,
-	0xBF, 0x40,	0xA3, 0x9E,	0x81, 0xF3,	0xD7, 0xFB,
-	0x7C, 0xE3,	0x39, 0x82,	0x9B, 0x2F,	0xFF, 0x87,
-	0x34, 0x8E,	0x43, 0x44,	0xC4, 0xDE,	0xE9, 0xCB,
-	0x54, 0x7B,	0x94, 0x32,	0xA6, 0xC2,	0x23, 0x3D,
-	0xEE, 0x4C,	0x95, 0x0B,	0x42, 0xFA,	0xC3, 0x4E,
-	0x08, 0x2E,	0xA1, 0x66,	0x28, 0xD9,	0x24, 0xB2,
-	0x76, 0x5B,	0xA2, 0x49,	0x6D, 0x8B,	0xD1, 0x25,
-	0x72, 0xF8,	0xF6, 0x64,	0x86, 0x68,	0x98, 0x16,
-	0xD4, 0xA4,	0x5C, 0xCC,	0x5D, 0x65,	0xB6, 0x92,
-	0x6C, 0x70,	0x48, 0x50,	0xFD, 0xED,	0xB9, 0xDA,
-	0x5E, 0x15,	0x46, 0x57,	0xA7, 0x8D,	0x9D, 0x84,
-	0x90, 0xD8,	0xAB, 0x00,	0x8C, 0xBC,	0xD3, 0x0A,
-	0xF7, 0xE4,	0x58, 0x05,	0xB8, 0xB3,	0x45, 0x06,
-	0xD0, 0x2C,	0x1E, 0x8F,	0xCA, 0x3F,	0x0F, 0x02,
-	0xC1, 0xAF,	0xBD, 0x03,	0x01, 0x13,	0x8A, 0x6B,
-	0x3A, 0x91,	0x11, 0x41,	0x4F, 0x67,	0xDC, 0xEA,
-	0x97, 0xF2,	0xCF, 0xCE,	0xF0, 0xB4,	0xE6, 0x73,
-	0x96, 0xAC,	0x74, 0x22,	0xE7, 0xAD,	0x35, 0x85,
-	0xE2, 0xF9,	0x37, 0xE8,	0x1C, 0x75,	0xDF, 0x6E,
-	0x47, 0xF1,	0x1A, 0x71,	0x1D, 0x29,	0xC5, 0x89,
-	0x6F, 0xB7,	0x62, 0x0E,	0xAA, 0x18,	0xBE, 0x1B,
-	0xFC, 0x56,	0x3E, 0x4B,	0xC6, 0xD2,	0x79, 0x20,
-	0x9A, 0xDB,	0xC0, 0xFE,	0x78, 0xCD,	0x5A, 0xF4,
-	0x1F, 0xDD,	0xA8, 0x33,	0x88, 0x07,	0xC7, 0x31,
-	0xB1, 0x12,	0x10, 0x59,	0x27, 0x80,	0xEC, 0x5F,
-	0x60, 0x51,	0x7F, 0xA9,	0x19, 0xB5,	0x4A, 0x0D,
-	0x2D, 0xE5,	0x7A, 0x9F,	0x93, 0xC9,	0x9C, 0xEF,
-	0xA0, 0xE0,	0x3B, 0x4D,	0xAE, 0x2A,	0xF5, 0xB0,
-	0xC8, 0xEB,	0xBB, 0x3C,	0x83, 0x53,	0x99, 0x61,
-	0x17, 0x2B,	0x04, 0x7E,	0xBA, 0x77,	0xD6, 0x26,
-	0xE1, 0x69,	0x14, 0x63,	0x55, 0x21,	0x0C, 0x7D
-};
-
-/* reverse table */
-
-#define	RT \
-\
-	V(51,F4,A7,50),	V(7E,41,65,53),	V(1A,17,A4,C3),	V(3A,27,5E,96),	\
-	V(3B,AB,6B,CB),	V(1F,9D,45,F1),	V(AC,FA,58,AB),	V(4B,E3,03,93),	\
-	V(20,30,FA,55),	V(AD,76,6D,F6),	V(88,CC,76,91),	V(F5,02,4C,25),	\
-	V(4F,E5,D7,FC),	V(C5,2A,CB,D7),	V(26,35,44,80),	V(B5,62,A3,8F),	\
-	V(DE,B1,5A,49),	V(25,BA,1B,67),	V(45,EA,0E,98),	V(5D,FE,C0,E1),	\
-	V(C3,2F,75,02),	V(81,4C,F0,12),	V(8D,46,97,A3),	V(6B,D3,F9,C6),	\
-	V(03,8F,5F,E7),	V(15,92,9C,95),	V(BF,6D,7A,EB),	V(95,52,59,DA),	\
-	V(D4,BE,83,2D),	V(58,74,21,D3),	V(49,E0,69,29),	V(8E,C9,C8,44),	\
-	V(75,C2,89,6A),	V(F4,8E,79,78),	V(99,58,3E,6B),	V(27,B9,71,DD),	\
-	V(BE,E1,4F,B6),	V(F0,88,AD,17),	V(C9,20,AC,66),	V(7D,CE,3A,B4),	\
-	V(63,DF,4A,18),	V(E5,1A,31,82),	V(97,51,33,60),	V(62,53,7F,45),	\
-	V(B1,64,77,E0),	V(BB,6B,AE,84),	V(FE,81,A0,1C),	V(F9,08,2B,94),	\
-	V(70,48,68,58),	V(8F,45,FD,19),	V(94,DE,6C,87),	V(52,7B,F8,B7),	\
-	V(AB,73,D3,23),	V(72,4B,02,E2),	V(E3,1F,8F,57),	V(66,55,AB,2A),	\
-	V(B2,EB,28,07),	V(2F,B5,C2,03),	V(86,C5,7B,9A),	V(D3,37,08,A5),	\
-	V(30,28,87,F2),	V(23,BF,A5,B2),	V(02,03,6A,BA),	V(ED,16,82,5C),	\
-	V(8A,CF,1C,2B),	V(A7,79,B4,92),	V(F3,07,F2,F0),	V(4E,69,E2,A1),	\
-	V(65,DA,F4,CD),	V(06,05,BE,D5),	V(D1,34,62,1F),	V(C4,A6,FE,8A),	\
-	V(34,2E,53,9D),	V(A2,F3,55,A0),	V(05,8A,E1,32),	V(A4,F6,EB,75),	\
-	V(0B,83,EC,39),	V(40,60,EF,AA),	V(5E,71,9F,06),	V(BD,6E,10,51),	\
-	V(3E,21,8A,F9),	V(96,DD,06,3D),	V(DD,3E,05,AE),	V(4D,E6,BD,46),	\
-	V(91,54,8D,B5),	V(71,C4,5D,05),	V(04,06,D4,6F),	V(60,50,15,FF),	\
-	V(19,98,FB,24),	V(D6,BD,E9,97),	V(89,40,43,CC),	V(67,D9,9E,77),	\
-	V(B0,E8,42,BD),	V(07,89,8B,88),	V(E7,19,5B,38),	V(79,C8,EE,DB),	\
-	V(A1,7C,0A,47),	V(7C,42,0F,E9),	V(F8,84,1E,C9),	V(00,00,00,00),	\
-	V(09,80,86,83),	V(32,2B,ED,48),	V(1E,11,70,AC),	V(6C,5A,72,4E),	\
-	V(FD,0E,FF,FB),	V(0F,85,38,56),	V(3D,AE,D5,1E),	V(36,2D,39,27),	\
-	V(0A,0F,D9,64),	V(68,5C,A6,21),	V(9B,5B,54,D1),	V(24,36,2E,3A),	\
-	V(0C,0A,67,B1),	V(93,57,E7,0F),	V(B4,EE,96,D2),	V(1B,9B,91,9E),	\
-	V(80,C0,C5,4F),	V(61,DC,20,A2),	V(5A,77,4B,69),	V(1C,12,1A,16),	\
-	V(E2,93,BA,0A),	V(C0,A0,2A,E5),	V(3C,22,E0,43),	V(12,1B,17,1D),	\
-	V(0E,09,0D,0B),	V(F2,8B,C7,AD),	V(2D,B6,A8,B9),	V(14,1E,A9,C8),	\
-	V(57,F1,19,85),	V(AF,75,07,4C),	V(EE,99,DD,BB),	V(A3,7F,60,FD),	\
-	V(F7,01,26,9F),	V(5C,72,F5,BC),	V(44,66,3B,C5),	V(5B,FB,7E,34),	\
-	V(8B,43,29,76),	V(CB,23,C6,DC),	V(B6,ED,FC,68),	V(B8,E4,F1,63),	\
-	V(D7,31,DC,CA),	V(42,63,85,10),	V(13,97,22,40),	V(84,C6,11,20),	\
-	V(85,4A,24,7D),	V(D2,BB,3D,F8),	V(AE,F9,32,11),	V(C7,29,A1,6D),	\
-	V(1D,9E,2F,4B),	V(DC,B2,30,F3),	V(0D,86,52,EC),	V(77,C1,E3,D0),	\
-	V(2B,B3,16,6C),	V(A9,70,B9,99),	V(11,94,48,FA),	V(47,E9,64,22),	\
-	V(A8,FC,8C,C4),	V(A0,F0,3F,1A),	V(56,7D,2C,D8),	V(22,33,90,EF),	\
-	V(87,49,4E,C7),	V(D9,38,D1,C1),	V(8C,CA,A2,FE),	V(98,D4,0B,36),	\
-	V(A6,F5,81,CF),	V(A5,7A,DE,28),	V(DA,B7,8E,26),	V(3F,AD,BF,A4),	\
-	V(2C,3A,9D,E4),	V(50,78,92,0D),	V(6A,5F,CC,9B),	V(54,7E,46,62),	\
-	V(F6,8D,13,C2),	V(90,D8,B8,E8),	V(2E,39,F7,5E),	V(82,C3,AF,F5),	\
-	V(9F,5D,80,BE),	V(69,D0,93,7C),	V(6F,D5,2D,A9),	V(CF,25,12,B3),	\
-	V(C8,AC,99,3B),	V(10,18,7D,A7),	V(E8,9C,63,6E),	V(DB,3B,BB,7B),	\
-	V(CD,26,78,09),	V(6E,59,18,F4),	V(EC,9A,B7,01),	V(83,4F,9A,A8),	\
-	V(E6,95,6E,65),	V(AA,FF,E6,7E),	V(21,BC,CF,08),	V(EF,15,E8,E6),	\
-	V(BA,E7,9B,D9),	V(4A,6F,36,CE),	V(EA,9F,09,D4),	V(29,B0,7C,D6),	\
-	V(31,A4,B2,AF),	V(2A,3F,23,31),	V(C6,A5,94,30),	V(35,A2,66,C0),	\
-	V(74,4E,BC,37),	V(FC,82,CA,A6),	V(E0,90,D0,B0),	V(33,A7,D8,15),	\
-	V(F1,04,98,4A),	V(41,EC,DA,F7),	V(7F,CD,50,0E),	V(17,91,F6,2F),	\
-	V(76,4D,D6,8D),	V(43,EF,B0,4D),	V(CC,AA,4D,54),	V(E4,96,04,DF),	\
-	V(9E,D1,B5,E3),	V(4C,6A,88,1B),	V(C1,2C,1F,B8),	V(46,65,51,7F),	\
-	V(9D,5E,EA,04),	V(01,8C,35,5D),	V(FA,87,74,73),	V(FB,0B,41,2E),	\
-	V(B3,67,1D,5A),	V(92,DB,D2,52),	V(E9,10,56,33),	V(6D,D6,47,13),	\
-	V(9A,D7,61,8C),	V(37,A1,0C,7A),	V(59,F8,14,8E),	V(EB,13,3C,89),	\
-	V(CE,A9,27,EE),	V(B7,61,C9,35),	V(E1,1C,E5,ED),	V(7A,47,B1,3C),	\
-	V(9C,D2,DF,59),	V(55,F2,73,3F),	V(18,14,CE,79),	V(73,C7,37,BF),	\
-	V(53,F7,CD,EA),	V(5F,FD,AA,5B),	V(DF,3D,6F,14),	V(78,44,DB,86),	\
-	V(CA,AF,F3,81),	V(B9,68,C4,3E),	V(38,24,34,2C),	V(C2,A3,40,5F),	\
-	V(16,1D,C3,72),	V(BC,E2,25,0C),	V(28,3C,49,8B),	V(FF,0D,95,41),	\
-	V(39,A8,01,71),	V(08,0C,B3,DE),	V(D8,B4,E4,9C),	V(64,56,C1,90),	\
-	V(7B,CB,84,61),	V(D5,32,B6,70),	V(48,6C,5C,74),	V(D0,B8,57,42)
-
-#define	V(a,b,c,d) 0x##a##b##c##d
-static uint32 RT0[256] = { RT };
-#undef V
-
-#define	V(a,b,c,d) 0x##d##a##b##c
-static uint32 RT1[256] = { RT };
-#undef V
-
-#define	V(a,b,c,d) 0x##c##d##a##b
-static uint32 RT2[256] = { RT };
-#undef V
-
-#define	V(a,b,c,d) 0x##b##c##d##a
-static uint32 RT3[256] = { RT };
-#undef V
-
-#undef RT
-
-/* round constants */
-
-static uint32 RCON[10] =
-{
-	0x01000000,	0x02000000,	0x04000000,	0x08000000,
-	0x10000000,	0x20000000,	0x40000000,	0x80000000,
-	0x1B000000,	0x36000000
-};
-
-/* key schedule	tables */
-
-static int KT_init = 1;
-
-static uint32 KT0[256];
-static uint32 KT1[256];
-static uint32 KT2[256];
-static uint32 KT3[256];
-
-/* platform-independant	32-bit integer manipulation	macros */
-
-#define	GET_UINT32(n,b,i)						\
-{												\
-	(n)	= (	(uint32) (b)[(i)	] << 24	)		\
-		| (	(uint32) (b)[(i) + 1] << 16	)		\
-		| (	(uint32) (b)[(i) + 2] <<  8	)		\
-		| (	(uint32) (b)[(i) + 3]		);		\
-}
-
-#define	PUT_UINT32(n,b,i)						\
-{												\
-	(b)[(i)	   ] = (uint8) ( (n) >>	24 );		\
-	(b)[(i)	+ 1] = (uint8) ( (n) >>	16 );		\
-	(b)[(i)	+ 2] = (uint8) ( (n) >>	 8 );		\
-	(b)[(i)	+ 3] = (uint8) ( (n)	   );		\
-}
-
-
-int	rt_aes_set_key( aes_context *ctx, uint8 *key, int nbits )
-{
-	int	i;
-	uint32 *RK,	*SK;
-
-	switch(	nbits )
-	{
-		case 128: ctx->nr =	10;	break;
-		case 192: ctx->nr =	12;	break;
-		case 256: ctx->nr =	14;	break;
-		default	: return( 1	);
-	}
-
-	RK = (uint32 *) ctx->erk;
-
-	for( i = 0;	i <	(nbits >> 5); i++ )
-	{
-		GET_UINT32(	RK[i], key,	i *	4 );
-	}
-
-	/* setup encryption	round keys */
-
-	switch(	nbits )
-	{
-	case 128:
-
-		for( i = 0;	i <	10;	i++, RK	+= 4 )
-		{
-			RK[4]  = RK[0] ^ RCON[i] ^
-						( FSb[ (uint8) ( RK[3] >> 16 ) ] <<	24 ) ^
-						( FSb[ (uint8) ( RK[3] >>  8 ) ] <<	16 ) ^
-						( FSb[ (uint8) ( RK[3]		 ) ] <<	 8 ) ^
-						( FSb[ (uint8) ( RK[3] >> 24 ) ]	   );
-
-			RK[5]  = RK[1] ^ RK[4];
-			RK[6]  = RK[2] ^ RK[5];
-			RK[7]  = RK[3] ^ RK[6];
-		}
-		break;
-
-	case 192:
-
-		for( i = 0;	i <	8; i++,	RK += 6	)
-		{
-			RK[6]  = RK[0] ^ RCON[i] ^
-						( FSb[ (uint8) ( RK[5] >> 16 ) ] <<	24 ) ^
-						( FSb[ (uint8) ( RK[5] >>  8 ) ] <<	16 ) ^
-						( FSb[ (uint8) ( RK[5]		 ) ] <<	 8 ) ^
-						( FSb[ (uint8) ( RK[5] >> 24 ) ]	   );
-
-			RK[7]  = RK[1] ^ RK[6];
-			RK[8]  = RK[2] ^ RK[7];
-			RK[9]  = RK[3] ^ RK[8];
-			RK[10] = RK[4] ^ RK[9];
-			RK[11] = RK[5] ^ RK[10];
-		}
-		break;
-
-	case 256:
-
-		for( i = 0;	i <	7; i++,	RK += 8	)
-		{
-			RK[8]  = RK[0] ^ RCON[i] ^
-						( FSb[ (uint8) ( RK[7] >> 16 ) ] <<	24 ) ^
-						( FSb[ (uint8) ( RK[7] >>  8 ) ] <<	16 ) ^
-						( FSb[ (uint8) ( RK[7]		 ) ] <<	 8 ) ^
-						( FSb[ (uint8) ( RK[7] >> 24 ) ]	   );
-
-			RK[9]  = RK[1] ^ RK[8];
-			RK[10] = RK[2] ^ RK[9];
-			RK[11] = RK[3] ^ RK[10];
-
-			RK[12] = RK[4] ^
-						( FSb[ (uint8) ( RK[11]	>> 24 )	] << 24	) ^
-						( FSb[ (uint8) ( RK[11]	>> 16 )	] << 16	) ^
-						( FSb[ (uint8) ( RK[11]	>>	8 )	] <<  8	) ^
-						( FSb[ (uint8) ( RK[11]		  )	]		);
-
-			RK[13] = RK[5] ^ RK[12];
-			RK[14] = RK[6] ^ RK[13];
-			RK[15] = RK[7] ^ RK[14];
-		}
-		break;
-	}
-
-	/* setup decryption	round keys */
-
-	if(	KT_init	)
-	{
-		for( i = 0;	i <	256; i++ )
-		{
-			KT0[i] = RT0[ FSb[i] ];
-			KT1[i] = RT1[ FSb[i] ];
-			KT2[i] = RT2[ FSb[i] ];
-			KT3[i] = RT3[ FSb[i] ];
-		}
-
-		KT_init	= 0;
-	}
-
-	SK = (uint32 *) ctx->drk;
-
-	*SK++ =	*RK++;
-	*SK++ =	*RK++;
-	*SK++ =	*RK++;
-	*SK++ =	*RK++;
-
-	for( i = 1;	i <	ctx->nr; i++ )
-	{
-		RK -= 8;
-
-		*SK++ =	KT0[ (uint8) ( *RK >> 24 ) ] ^
-				KT1[ (uint8) ( *RK >> 16 ) ] ^
-				KT2[ (uint8) ( *RK >>  8 ) ] ^
-				KT3[ (uint8) ( *RK		 ) ]; RK++;
-
-		*SK++ =	KT0[ (uint8) ( *RK >> 24 ) ] ^
-				KT1[ (uint8) ( *RK >> 16 ) ] ^
-				KT2[ (uint8) ( *RK >>  8 ) ] ^
-				KT3[ (uint8) ( *RK		 ) ]; RK++;
-
-		*SK++ =	KT0[ (uint8) ( *RK >> 24 ) ] ^
-				KT1[ (uint8) ( *RK >> 16 ) ] ^
-				KT2[ (uint8) ( *RK >>  8 ) ] ^
-				KT3[ (uint8) ( *RK		 ) ]; RK++;
-
-		*SK++ =	KT0[ (uint8) ( *RK >> 24 ) ] ^
-				KT1[ (uint8) ( *RK >> 16 ) ] ^
-				KT2[ (uint8) ( *RK >>  8 ) ] ^
-				KT3[ (uint8) ( *RK		 ) ]; RK++;
-	}
-
-	RK -= 8;
-
-	*SK++ =	*RK++;
-	*SK++ =	*RK++;
-	*SK++ =	*RK++;
-	*SK++ =	*RK++;
-
-	return(	0 );
-}
-
-/* AES 128-bit block encryption	routine	*/
-
-void rt_aes_encrypt(aes_context *ctx, uint8 input[16],	uint8 output[16] )
-{
-	uint32 *RK,	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3;
-
-	RK = (uint32 *) ctx->erk;
-	GET_UINT32(	X0,	input,	0 ); X0	^= RK[0];
-	GET_UINT32(	X1,	input,	4 ); X1	^= RK[1];
-	GET_UINT32(	X2,	input,	8 ); X2	^= RK[2];
-	GET_UINT32(	X3,	input, 12 ); X3	^= RK[3];
-
-#define	AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)		\
-{												\
-	RK += 4;									\
-												\
-	X0 = RK[0] ^ FT0[ (uint8) (	Y0 >> 24 ) ] ^	\
-				 FT1[ (uint8) (	Y1 >> 16 ) ] ^	\
-				 FT2[ (uint8) (	Y2 >>  8 ) ] ^	\
-				 FT3[ (uint8) (	Y3		 ) ];	\
-												\
-	X1 = RK[1] ^ FT0[ (uint8) (	Y1 >> 24 ) ] ^	\
-				 FT1[ (uint8) (	Y2 >> 16 ) ] ^	\
-				 FT2[ (uint8) (	Y3 >>  8 ) ] ^	\
-				 FT3[ (uint8) (	Y0		 ) ];	\
-												\
-	X2 = RK[2] ^ FT0[ (uint8) (	Y2 >> 24 ) ] ^	\
-				 FT1[ (uint8) (	Y3 >> 16 ) ] ^	\
-				 FT2[ (uint8) (	Y0 >>  8 ) ] ^	\
-				 FT3[ (uint8) (	Y1		 ) ];	\
-												\
-	X3 = RK[3] ^ FT0[ (uint8) (	Y3 >> 24 ) ] ^	\
-				 FT1[ (uint8) (	Y0 >> 16 ) ] ^	\
-				 FT2[ (uint8) (	Y1 >>  8 ) ] ^	\
-				 FT3[ (uint8) (	Y2		 ) ];	\
-}
-
-	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 1 */
-	AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 2 */
-	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 3 */
-	AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 4 */
-	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 5 */
-	AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 6 */
-	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 7 */
-	AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 8 */
-	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 9 */
-
-	if(	ctx->nr	> 10 )
-	{
-		AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );	/* round 10	*/
-		AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );	/* round 11	*/
-	}
-
-	if(	ctx->nr	> 12 )
-	{
-		AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );	/* round 12	*/
-		AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );	/* round 13	*/
-	}
-
-	/* last	round */
-
-	RK += 4;
-
-	X0 = RK[0] ^ ( FSb[	(uint8)	( Y0 >>	24 ) ] << 24 ) ^
-				 ( FSb[	(uint8)	( Y1 >>	16 ) ] << 16 ) ^
-				 ( FSb[	(uint8)	( Y2 >>	 8 ) ] <<  8 ) ^
-				 ( FSb[	(uint8)	( Y3	   ) ]		 );
-
-	X1 = RK[1] ^ ( FSb[	(uint8)	( Y1 >>	24 ) ] << 24 ) ^
-				 ( FSb[	(uint8)	( Y2 >>	16 ) ] << 16 ) ^
-				 ( FSb[	(uint8)	( Y3 >>	 8 ) ] <<  8 ) ^
-				 ( FSb[	(uint8)	( Y0	   ) ]		 );
-
-	X2 = RK[2] ^ ( FSb[	(uint8)	( Y2 >>	24 ) ] << 24 ) ^
-				 ( FSb[	(uint8)	( Y3 >>	16 ) ] << 16 ) ^
-				 ( FSb[	(uint8)	( Y0 >>	 8 ) ] <<  8 ) ^
-				 ( FSb[	(uint8)	( Y1	   ) ]		 );
-
-	X3 = RK[3] ^ ( FSb[	(uint8)	( Y3 >>	24 ) ] << 24 ) ^
-				 ( FSb[	(uint8)	( Y0 >>	16 ) ] << 16 ) ^
-				 ( FSb[	(uint8)	( Y1 >>	 8 ) ] <<  8 ) ^
-				 ( FSb[	(uint8)	( Y2	   ) ]		 );
-
-	PUT_UINT32(	X0,	output,	 0 );
-	PUT_UINT32(	X1,	output,	 4 );
-	PUT_UINT32(	X2,	output,	 8 );
-	PUT_UINT32(	X3,	output,	12 );
-}
-
-/* AES 128-bit block decryption	routine	*/
-
-void rt_aes_decrypt( aes_context *ctx,	uint8 input[16], uint8 output[16] )
-{
-	uint32 *RK,	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3;
-
-	RK = (uint32 *) ctx->drk;
-
-	GET_UINT32(	X0,	input,	0 ); X0	^= RK[0];
-	GET_UINT32(	X1,	input,	4 ); X1	^= RK[1];
-	GET_UINT32(	X2,	input,	8 ); X2	^= RK[2];
-	GET_UINT32(	X3,	input, 12 ); X3	^= RK[3];
-
-#define	AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)		\
-{												\
-	RK += 4;									\
-												\
-	X0 = RK[0] ^ RT0[ (uint8) (	Y0 >> 24 ) ] ^	\
-				 RT1[ (uint8) (	Y3 >> 16 ) ] ^	\
-				 RT2[ (uint8) (	Y2 >>  8 ) ] ^	\
-				 RT3[ (uint8) (	Y1		 ) ];	\
-												\
-	X1 = RK[1] ^ RT0[ (uint8) (	Y1 >> 24 ) ] ^	\
-				 RT1[ (uint8) (	Y0 >> 16 ) ] ^	\
-				 RT2[ (uint8) (	Y3 >>  8 ) ] ^	\
-				 RT3[ (uint8) (	Y2		 ) ];	\
-												\
-	X2 = RK[2] ^ RT0[ (uint8) (	Y2 >> 24 ) ] ^	\
-				 RT1[ (uint8) (	Y1 >> 16 ) ] ^	\
-				 RT2[ (uint8) (	Y0 >>  8 ) ] ^	\
-				 RT3[ (uint8) (	Y3		 ) ];	\
-												\
-	X3 = RK[3] ^ RT0[ (uint8) (	Y3 >> 24 ) ] ^	\
-				 RT1[ (uint8) (	Y2 >> 16 ) ] ^	\
-				 RT2[ (uint8) (	Y1 >>  8 ) ] ^	\
-				 RT3[ (uint8) (	Y0		 ) ];	\
-}
-
-	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 1 */
-	AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 2 */
-	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 3 */
-	AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 4 */
-	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 5 */
-	AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 6 */
-	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 7 */
-	AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 8 */
-	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 9 */
-
-	if(	ctx->nr	> 10 )
-	{
-		AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );	/* round 10	*/
-		AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );	/* round 11	*/
-	}
-
-	if(	ctx->nr	> 12 )
-	{
-		AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );	/* round 12	*/
-		AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );	/* round 13	*/
-	}
-
-	/* last	round */
-
-	RK += 4;
-
-	X0 = RK[0] ^ ( RSb[	(uint8)	( Y0 >>	24 ) ] << 24 ) ^
-				 ( RSb[	(uint8)	( Y3 >>	16 ) ] << 16 ) ^
-				 ( RSb[	(uint8)	( Y2 >>	 8 ) ] <<  8 ) ^
-				 ( RSb[	(uint8)	( Y1	   ) ]		 );
-
-	X1 = RK[1] ^ ( RSb[	(uint8)	( Y1 >>	24 ) ] << 24 ) ^
-				 ( RSb[	(uint8)	( Y0 >>	16 ) ] << 16 ) ^
-				 ( RSb[	(uint8)	( Y3 >>	 8 ) ] <<  8 ) ^
-				 ( RSb[	(uint8)	( Y2	   ) ]		 );
-
-	X2 = RK[2] ^ ( RSb[	(uint8)	( Y2 >>	24 ) ] << 24 ) ^
-				 ( RSb[	(uint8)	( Y1 >>	16 ) ] << 16 ) ^
-				 ( RSb[	(uint8)	( Y0 >>	 8 ) ] <<  8 ) ^
-				 ( RSb[	(uint8)	( Y3	   ) ]		 );
-
-	X3 = RK[3] ^ ( RSb[	(uint8)	( Y3 >>	24 ) ] << 24 ) ^
-				 ( RSb[	(uint8)	( Y2 >>	16 ) ] << 16 ) ^
-				 ( RSb[	(uint8)	( Y1 >>	 8 ) ] <<  8 ) ^
-				 ( RSb[	(uint8)	( Y0	   ) ]		 );
-
-	PUT_UINT32(	X0,	output,	 0 );
-	PUT_UINT32(	X1,	output,	 4 );
-	PUT_UINT32(	X2,	output,	 8 );
-	PUT_UINT32(	X3,	output,	12 );
-}
-
-/*
-    ==========================================================================
-    Description:
-        ENCRYPT AES GTK before sending in EAPOL frame.
-        AES GTK length = 128 bit,  so fix blocks for aes-key-wrap as 2 in this function.
-        This function references to RFC 3394 for aes key wrap algorithm.
-    Return:
-    ==========================================================================
-*/
-VOID AES_GTK_KEY_WRAP(
-    IN UCHAR    *key,
-    IN UCHAR    *plaintext,
-    IN UINT32    p_len,
-    OUT UCHAR   *ciphertext)
-{
-    UCHAR       A[8], BIN[16], BOUT[16];
-    UCHAR       R[512];
-    INT         num_blocks = p_len/8;   // unit:64bits
-    INT         i, j;
-    aes_context aesctx;
-    UCHAR       xor;
-
-    rt_aes_set_key(&aesctx, key, 128);
-
-    // Init IA
-    for (i = 0; i < 8; i++)
-        A[i] = 0xa6;
-
-    //Input plaintext
-    for (i = 0; i < num_blocks; i++)
-    {
-        for (j = 0 ; j < 8; j++)
-            R[8 * (i + 1) + j] = plaintext[8 * i + j];
-    }
-
-    // Key Mix
-    for (j = 0; j < 6; j++)
-    {
-        for(i = 1; i <= num_blocks; i++)
-        {
-            //phase 1
-            NdisMoveMemory(BIN, A, 8);
-            NdisMoveMemory(&BIN[8], &R[8 * i], 8);
-            rt_aes_encrypt(&aesctx, BIN, BOUT);
-
-            NdisMoveMemory(A, &BOUT[0], 8);
-            xor = num_blocks * j + i;
-            A[7] = BOUT[7] ^ xor;
-            NdisMoveMemory(&R[8 * i], &BOUT[8], 8);
-        }
-    }
-
-    // Output ciphertext
-    NdisMoveMemory(ciphertext, A, 8);
-
-    for (i = 1; i <= num_blocks; i++)
-    {
-        for (j = 0 ; j < 8; j++)
-            ciphertext[8 * i + j] = R[8 * i + j];
-    }
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Misc function to decrypt AES body
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-		This function references to	RFC	3394 for aes key unwrap algorithm.
-
-	========================================================================
-*/
-VOID	AES_GTK_KEY_UNWRAP(
-	IN	UCHAR	*key,
-	OUT	UCHAR	*plaintext,
-	IN	UINT32   c_len,
-	IN	UCHAR	*ciphertext)
-
-{
-	UCHAR       A[8], BIN[16], BOUT[16];
-	UCHAR       xor;
-	INT         i, j;
-	aes_context aesctx;
-	UCHAR       *R;
-	INT         num_blocks = c_len/8;	// unit:64bits
-
-
-	os_alloc_mem(NULL, (PUCHAR *)&R, 512);
-
-	if (R == NULL)
-    {
-        DBGPRINT(RT_DEBUG_ERROR, ("!!!AES_GTK_KEY_UNWRAP: no memory!!!\n"));
-        return;
-    } /* End of if */
-
-	// Initialize
-	NdisMoveMemory(A, ciphertext, 8);
-	//Input plaintext
-	for(i = 0; i < (c_len-8); i++)
-	{
-		R[ i] = ciphertext[i + 8];
-	}
-
-	rt_aes_set_key(&aesctx, key, 128);
-
-	for(j = 5; j >= 0; j--)
-	{
-		for(i = (num_blocks-1); i > 0; i--)
-		{
-			xor = (num_blocks -1 )* j + i;
-			NdisMoveMemory(BIN, A, 8);
-			BIN[7] = A[7] ^ xor;
-			NdisMoveMemory(&BIN[8], &R[(i-1)*8], 8);
-			rt_aes_decrypt(&aesctx, BIN, BOUT);
-			NdisMoveMemory(A, &BOUT[0], 8);
-			NdisMoveMemory(&R[(i-1)*8], &BOUT[8], 8);
-		}
-	}
-
-	// OUTPUT
-	for(i = 0; i < c_len; i++)
-	{
-		plaintext[i] = R[i];
-	}
-
-
-	os_free_mem(NULL, R);
-}
-
-
-/* =======  The related function of AES-128-CMAC  ======= */
-VOID leftshift_onebit(
-	IN  PUCHAR	input,
-	OUT PUCHAR	output)
-{
-	INT i;
-	UCHAR overflow = 0;
-
-	for (i=15; i>=0; i--)
-	{
-		output[i] = input[i] << 1;
-		output[i] |= overflow;
-		overflow = (input[i] & 0x80) ? 1 : 0;
-	}
-}
-
-VOID do_padding(
-	IN	PUCHAR	lastb,
-	OUT	PUCHAR	pad,
-	IN  INT		len)
-{
-	INT	j;
-
-	for (j=0; j<16; j++)
-	{
-		if (j < len)
-			pad[j] = lastb[j];
-		else if (j == len)
-			pad[j] = 0x80;
-		else
-			pad[j] = 0x00;
-	}
-
-
-}
-
-/*
- *	The Subkey Generation Algorithm
- */
-VOID generate_subkey(
-	IN	PUCHAR key,
-	OUT	PUCHAR K1,
-	OUT PUCHAR K2)
-{
-	aes_context aesctx;
-	UCHAR aes_128_key[16];
-	UCHAR const_Zero[16];
-	UCHAR tmp[16];
-	UCHAR const_Rb[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-					      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87};
-
-	// initial the key material
-	memset(const_Zero, 0, 16);
-	memset(aes_128_key, 0, 16);
-
-	// AES-128 with key is applied to an all-zero input block
-	rt_aes_set_key(&aesctx, key, 128);
-	rt_aes_encrypt(&aesctx, const_Zero, aes_128_key);
-
-	// derive K1(128-bit first subkey) and K2(128-bit second subkey), refer to rfc-4493 ch 2.3
-	if ((aes_128_key[0] & 0x80) == 0)
-	{
-		leftshift_onebit(aes_128_key, K1);
-	}
-	else
-	{
-		leftshift_onebit(aes_128_key, tmp);
-		xor_128(tmp, const_Rb, K1);
-	}
-
-	if ((K1[0] & 0x80) == 0)
-	{
-		leftshift_onebit(K1, K2);
-	}
-	else
-	{
-		leftshift_onebit(K1, tmp);
-		xor_128(tmp, const_Rb, K2);
-	}
-
-}
-
-/*
- *	AES-CMAC Algorithm. (refer to rfc-4493 and SP800-38B)
- *
- *	Input : key		(128-bit key)
- *			input		(message to be authenticated)
- *			len			(length of the message in octets)
- *
- *	output: mac			(message authentication code)
- */
-VOID AES_128_CMAC(
-	IN	PUCHAR	key,
-	IN	PUCHAR	input,
-	IN	INT		len,
-	OUT	PUCHAR	mac)
-{
-	UCHAR	X[16], Y[16], M_last[16], padded[16];
-	UCHAR	K1[16], K2[16];
-	aes_context aesctx;
-	INT		n, i, flag;
-
-	generate_subkey(key, K1, K2);
-
-	n = (len+15) / 16;		// n is number of rounds
-
-	if (n == 0)
-	{
-		n = 1;
-		flag = 0;
-	}
-	else
-	{
-		if ((len%16) == 0)
-			flag = 1;			// indicate that last block is a complete block
-		else
-			flag = 0;			// indicate that last block is not a complete block
-	}
-
-	if (flag)
-	{
-		xor_128(&input[16*(n-1)], K1, M_last);
-	}
-	else
-	{
-		do_padding(&input[16*(n-1)], padded, len%16);
-		xor_128(padded, K2, M_last);
-	}
-
-	memset(X, 0, 16);
-	for (i=0; i<n-1; i++)
-	{
-		xor_128(X, &input[16*i], Y);
-		rt_aes_set_key(&aesctx, key, 128);
-		rt_aes_encrypt(&aesctx, Y, X);
-	}
-
-	xor_128(X, M_last, Y);
-	rt_aes_set_key(&aesctx, key, 128);
-	rt_aes_encrypt(&aesctx, Y, X);
-
-	for (i=0; i<16; i++)
-	{
-		mac[i] = X[i];
-	}
-
-}
-/* =======  The related function of AES-128-CMAC  ======= */
diff --git a/drivers/staging/rt3090/common/cmm_asic.c b/drivers/staging/rt3090/common/cmm_asic.c
deleted file mode 100644
index 3d1c808..0000000
--- a/drivers/staging/rt3090/common/cmm_asic.c
+++ /dev/null
@@ -1,2753 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	cmm_asic.c
-
-	Abstract:
-	Functions used to communicate with ASIC
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-*/
-
-#include "../rt_config.h"
-
-
-// Reset the RFIC setting to new series
-RTMP_RF_REGS RF2850RegTable[] = {
-//		ch	 R1		 R2		 R3(TX0~4=0) R4
-		{1,  0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b},
-		{2,  0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f},
-		{3,  0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b},
-		{4,  0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f},
-		{5,  0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b},
-		{6,  0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f},
-		{7,  0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b},
-		{8,  0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f},
-		{9,  0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b},
-		{10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f},
-		{11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b},
-		{12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f},
-		{13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b},
-		{14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193},
-
-		// 802.11 UNI / HyperLan 2
-		{36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3},
-		{38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193},
-		{40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183},
-		{44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3},
-		{46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b},
-		{48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b},
-		{52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193},
-		{54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3},
-		{56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b},
-		{60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183},
-		{62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193},
-		{64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}, // Plugfest#4, Day4, change RFR3 left4th 9->5.
-
-		// 802.11 HyperLan 2
-		{100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783},
-
-		// 2008.04.30 modified
-		// The system team has AN to improve the EVM value
-		// for channel 102 to 108 for the RT2850/RT2750 dual band solution.
-		{102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793},
-		{104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3},
-		{108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193},
-
-		{110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183},
-		{112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b},
-		{116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3},
-		{118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193},
-		{120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183},
-		{124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193},
-		{126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}, // 0x980ed1bb->0x980ed15b required by Rory 20070927
-		{128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3},
-		{132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b},
-		{134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193},
-		{136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b},
-		{140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183},
-
-		// 802.11 UNII
-		{149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7},
-		{151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187},
-		{153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f},
-		{157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f},
-		{159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7},
-		{161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187},
-		{165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197},
-		{167, 0x98402ec4, 0x984c03d2, 0x98179855, 0x9815531f},
-		{169, 0x98402ec4, 0x984c03d2, 0x98179855, 0x98155327},
-		{171, 0x98402ec4, 0x984c03d6, 0x98179855, 0x98155307},
-		{173, 0x98402ec4, 0x984c03d6, 0x98179855, 0x9815530f},
-
-		// Japan
-		{184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b},
-		{188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13},
-		{192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b},
-		{196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23},
-		{208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13},
-		{212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b},
-		{216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23},
-
-		// still lack of MMAC(Japan) ch 34,38,42,46
-};
-UCHAR	NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(RTMP_RF_REGS));
-
-FREQUENCY_ITEM FreqItems3020[] =
-{
-	/**************************************************/
-	// ISM : 2.4 to 2.483 GHz                         //
-	/**************************************************/
-	// 11g
-	/**************************************************/
-	//-CH---N-------R---K-----------
-	{1,    241,  2,  2},
-	{2,    241,	 2,  7},
-	{3,    242,	 2,  2},
-	{4,    242,	 2,  7},
-	{5,    243,	 2,  2},
-	{6,    243,	 2,  7},
-	{7,    244,	 2,  2},
-	{8,    244,	 2,  7},
-	{9,    245,	 2,  2},
-	{10,   245,	 2,  7},
-	{11,   246,	 2,  2},
-	{12,   246,	 2,  7},
-	{13,   247,	 2,  2},
-	{14,   248,	 2,  4},
-};
-UCHAR	NUM_OF_3020_CHNL = (sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM));
-
-
-VOID AsicUpdateAutoFallBackTable(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pRateTable)
-{
-	UCHAR					i;
-	HT_FBK_CFG0_STRUC		HtCfg0;
-	HT_FBK_CFG1_STRUC		HtCfg1;
-	LG_FBK_CFG0_STRUC		LgCfg0;
-	LG_FBK_CFG1_STRUC		LgCfg1;
-	PRTMP_TX_RATE_SWITCH	pCurrTxRate, pNextTxRate;
-
-	// set to initial value
-	HtCfg0.word = 0x65432100;
-	HtCfg1.word = 0xedcba988;
-	LgCfg0.word = 0xedcba988;
-	LgCfg1.word = 0x00002100;
-
-	pNextTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1;
-	for (i = 1; i < *((PUCHAR) pRateTable); i++)
-	{
-		pCurrTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1+i;
-		switch (pCurrTxRate->Mode)
-		{
-			case 0:		//CCK
-				break;
-			case 1:		//OFDM
-				{
-					switch(pCurrTxRate->CurrMCS)
-					{
-						case 0:
-							LgCfg0.field.OFDMMCS0FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
-							break;
-						case 1:
-							LgCfg0.field.OFDMMCS1FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
-							break;
-						case 2:
-							LgCfg0.field.OFDMMCS2FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
-							break;
-						case 3:
-							LgCfg0.field.OFDMMCS3FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
-							break;
-						case 4:
-							LgCfg0.field.OFDMMCS4FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
-							break;
-						case 5:
-							LgCfg0.field.OFDMMCS5FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
-							break;
-						case 6:
-							LgCfg0.field.OFDMMCS6FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
-							break;
-						case 7:
-							LgCfg0.field.OFDMMCS7FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
-							break;
-					}
-				}
-				break;
-#ifdef DOT11_N_SUPPORT
-			case 2:		//HT-MIX
-			case 3:		//HT-GF
-				{
-					if ((pNextTxRate->Mode >= MODE_HTMIX) && (pCurrTxRate->CurrMCS != pNextTxRate->CurrMCS))
-					{
-						switch(pCurrTxRate->CurrMCS)
-						{
-							case 0:
-								HtCfg0.field.HTMCS0FBK = pNextTxRate->CurrMCS;
-								break;
-							case 1:
-								HtCfg0.field.HTMCS1FBK = pNextTxRate->CurrMCS;
-								break;
-							case 2:
-								HtCfg0.field.HTMCS2FBK = pNextTxRate->CurrMCS;
-								break;
-							case 3:
-								HtCfg0.field.HTMCS3FBK = pNextTxRate->CurrMCS;
-								break;
-							case 4:
-								HtCfg0.field.HTMCS4FBK = pNextTxRate->CurrMCS;
-								break;
-							case 5:
-								HtCfg0.field.HTMCS5FBK = pNextTxRate->CurrMCS;
-								break;
-							case 6:
-								HtCfg0.field.HTMCS6FBK = pNextTxRate->CurrMCS;
-								break;
-							case 7:
-								HtCfg0.field.HTMCS7FBK = pNextTxRate->CurrMCS;
-								break;
-							case 8:
-								HtCfg1.field.HTMCS8FBK = pNextTxRate->CurrMCS;
-								break;
-							case 9:
-								HtCfg1.field.HTMCS9FBK = pNextTxRate->CurrMCS;
-								break;
-							case 10:
-								HtCfg1.field.HTMCS10FBK = pNextTxRate->CurrMCS;
-								break;
-							case 11:
-								HtCfg1.field.HTMCS11FBK = pNextTxRate->CurrMCS;
-								break;
-							case 12:
-								HtCfg1.field.HTMCS12FBK = pNextTxRate->CurrMCS;
-								break;
-							case 13:
-								HtCfg1.field.HTMCS13FBK = pNextTxRate->CurrMCS;
-								break;
-							case 14:
-								HtCfg1.field.HTMCS14FBK = pNextTxRate->CurrMCS;
-								break;
-							case 15:
-								HtCfg1.field.HTMCS15FBK = pNextTxRate->CurrMCS;
-								break;
-							default:
-								DBGPRINT(RT_DEBUG_ERROR, ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n", pCurrTxRate->CurrMCS));
-						}
-					}
-				}
-				break;
-#endif // DOT11_N_SUPPORT //
-		}
-
-		pNextTxRate = pCurrTxRate;
-	}
-
-	RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word);
-	RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word);
-	RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word);
-	RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word);
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Set MAC register value according operation mode.
-		OperationMode AND bNonGFExist are for MM and GF Proteciton.
-		If MM or GF mask is not set, those passing argument doesn't not take effect.
-
-		Operation mode meaning:
-		= 0 : Pure HT, no preotection.
-		= 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
-		= 0x10: No Transmission in 40M is protected.
-		= 0x11: Transmission in both 40M and 20M shall be protected
-		if (bNonGFExist)
-			we should choose not to use GF. But still set correct ASIC registers.
-	========================================================================
-*/
-VOID	AsicUpdateProtect(
-	IN		PRTMP_ADAPTER	pAd,
-	IN		USHORT			OperationMode,
-	IN		UCHAR			SetMask,
-	IN		BOOLEAN			bDisableBGProtect,
-	IN		BOOLEAN			bNonGFExist)
-{
-	PROT_CFG_STRUC	ProtCfg, ProtCfg4;
-	UINT32 Protect[6];
-	USHORT			offset;
-	UCHAR			i;
-	UINT32 MacReg = 0;
-
-#ifdef RALINK_ATE
-	if (ATE_ON(pAd))
-		return;
-#endif // RALINK_ATE //
-
-#ifdef DOT11_N_SUPPORT
-	if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8))
-	{
-		return;
-	}
-
-	if (pAd->BATable.numDoneOriginator)
-	{
-		//
-		// enable the RTS/CTS to avoid channel collision
-		//
-		SetMask = ALLN_SETPROTECT;
-		OperationMode = 8;
-	}
-#endif // DOT11_N_SUPPORT //
-
-	// Config ASIC RTS threshold register
-	RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
-	MacReg &= 0xFF0000FF;
-	// If the user want disable RtsThreshold and enbale Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
-        if ((
-#ifdef DOT11_N_SUPPORT
-			(pAd->CommonCfg.BACapability.field.AmsduEnable) ||
-#endif // DOT11_N_SUPPORT //
-			(pAd->CommonCfg.bAggregationCapable == TRUE))
-            && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD)
-        {
-			MacReg |= (0x1000 << 8);
-        }
-        else
-        {
-			MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
-        }
-
-	RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
-
-	// Initial common protection settings
-	RTMPZeroMemory(Protect, sizeof(Protect));
-	ProtCfg4.word = 0;
-	ProtCfg.word = 0;
-	ProtCfg.field.TxopAllowGF40 = 1;
-	ProtCfg.field.TxopAllowGF20 = 1;
-	ProtCfg.field.TxopAllowMM40 = 1;
-	ProtCfg.field.TxopAllowMM20 = 1;
-	ProtCfg.field.TxopAllowOfdm = 1;
-	ProtCfg.field.TxopAllowCck = 1;
-	ProtCfg.field.RTSThEn = 1;
-	ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
-
-	// update PHY mode and rate
-	if (pAd->CommonCfg.Channel > 14)
-		ProtCfg.field.ProtectRate = 0x4000;
-	ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate;
-
-	// Handle legacy(B/G) protection
-	if (bDisableBGProtect)
-	{
-		//ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
-		ProtCfg.field.ProtectCtrl = 0;
-		Protect[0] = ProtCfg.word;
-		Protect[1] = ProtCfg.word;
-		pAd->FlgCtsEnabled = 0; /* CTS-self is not used */
-	}
-	else
-	{
-		//ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
-		ProtCfg.field.ProtectCtrl = 0;			// CCK do not need to be protected
-		Protect[0] = ProtCfg.word;
-		ProtCfg.field.ProtectCtrl = ASIC_CTS;	// OFDM needs using CCK to protect
-		Protect[1] = ProtCfg.word;
-		pAd->FlgCtsEnabled = 1; /* CTS-self is used */
-	}
-
-#ifdef DOT11_N_SUPPORT
-	// Decide HT frame protection.
-	if ((SetMask & ALLN_SETPROTECT) != 0)
-	{
-		switch(OperationMode)
-		{
-			case 0x0:
-				// NO PROTECT
-				// 1.All STAs in the BSS are 20/40 MHz HT
-				// 2. in ai 20/40MHz BSS
-				// 3. all STAs are 20MHz in a 20MHz BSS
-				// Pure HT. no protection.
-
-				// MM20_PROT_CFG
-				//	Reserved (31:27)
-				//	PROT_TXOP(25:20) -- 010111
-				//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
-				//  PROT_CTRL(17:16) -- 00 (None)
-				//	PROT_RATE(15:0)  -- 0x4004 (OFDM 24M)
-				Protect[2] = 0x01744004;
-
-				// MM40_PROT_CFG
-				//	Reserved (31:27)
-				//	PROT_TXOP(25:20) -- 111111
-				//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
-				//  PROT_CTRL(17:16) -- 00 (None)
-				//	PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M)
-				Protect[3] = 0x03f44084;
-
-				// CF20_PROT_CFG
-				//	Reserved (31:27)
-				//	PROT_TXOP(25:20) -- 010111
-				//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
-				//  PROT_CTRL(17:16) -- 00 (None)
-				//	PROT_RATE(15:0)  -- 0x4004 (OFDM 24M)
-				Protect[4] = 0x01744004;
-
-				// CF40_PROT_CFG
-				//	Reserved (31:27)
-				//	PROT_TXOP(25:20) -- 111111
-				//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
-				//  PROT_CTRL(17:16) -- 00 (None)
-				//	PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M)
-				Protect[5] = 0x03f44084;
-
-				if (bNonGFExist)
-				{
-					// PROT_NAV(19:18)  -- 01 (Short NAV protectiion)
-					// PROT_CTRL(17:16) -- 01 (RTS/CTS)
-					Protect[4] = 0x01754004;
-					Protect[5] = 0x03f54084;
-				}
-				pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
-				break;
-
-			case 1:
-				// This is "HT non-member protection mode."
-				// If there may be non-HT STAs my BSS
-				ProtCfg.word = 0x01744004;	// PROT_CTRL(17:16) : 0 (None)
-				ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
-				if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
-				{
-					ProtCfg.word = 0x01740003;	//ERP use Protection bit is set, use protection rate at Clause 18..
-					ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083;
-				}
-				//Assign Protection method for 20&40 MHz packets
-				ProtCfg.field.ProtectCtrl = ASIC_RTS;
-				ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
-				ProtCfg4.field.ProtectCtrl = ASIC_RTS;
-				ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
-				Protect[2] = ProtCfg.word;
-				Protect[3] = ProtCfg4.word;
-				Protect[4] = ProtCfg.word;
-				Protect[5] = ProtCfg4.word;
-				pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
-				break;
-
-			case 2:
-				// If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets
-				ProtCfg.word = 0x01744004;  // PROT_CTRL(17:16) : 0 (None)
-				ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
-
-				//Assign Protection method for 40MHz packets
-				ProtCfg4.field.ProtectCtrl = ASIC_RTS;
-				ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
-				Protect[2] = ProtCfg.word;
-				Protect[3] = ProtCfg4.word;
-				if (bNonGFExist)
-				{
-					ProtCfg.field.ProtectCtrl = ASIC_RTS;
-					ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
-				}
-				Protect[4] = ProtCfg.word;
-				Protect[5] = ProtCfg4.word;
-
-				pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
-				break;
-
-			case 3:
-				// HT mixed mode.	 PROTECT ALL!
-				// Assign Rate
-				ProtCfg.word = 0x01744004;	//duplicaet legacy 24M. BW set 1.
-				ProtCfg4.word = 0x03f44084;
-				// both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the
-				if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
-				{
-					ProtCfg.word = 0x01740003;	//ERP use Protection bit is set, use protection rate at Clause 18..
-					ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083
-				}
-				//Assign Protection method for 20&40 MHz packets
-				ProtCfg.field.ProtectCtrl = ASIC_RTS;
-				ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
-				ProtCfg4.field.ProtectCtrl = ASIC_RTS;
-				ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
-				Protect[2] = ProtCfg.word;
-				Protect[3] = ProtCfg4.word;
-				Protect[4] = ProtCfg.word;
-				Protect[5] = ProtCfg4.word;
-				pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
-				break;
-
-			case 8:
-				// Special on for Atheros problem n chip.
-				Protect[2] = 0x01754004;
-				Protect[3] = 0x03f54084;
-				Protect[4] = 0x01754004;
-				Protect[5] = 0x03f54084;
-				pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
-				break;
-		}
-	}
-#endif // DOT11_N_SUPPORT //
-
-	offset = CCK_PROT_CFG;
-	for (i = 0;i < 6;i++)
-	{
-			if ((SetMask & (1<< i)))
-		{
-		RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
-	}
-}
-}
-
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AsicSwitchChannel(
-					  IN PRTMP_ADAPTER pAd,
-	IN	UCHAR			Channel,
-	IN	BOOLEAN			bScan)
-{
-	ULONG			R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0;
-	CHAR    TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; //Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER;
-	UCHAR	index;
-	UINT32	Value = 0; //BbpReg, Value;
-	RTMP_RF_REGS *RFRegTable;
-	UCHAR	RFValue;
-
-	RFValue = 0;
-	// Search Tx power value
-	// We can't use ChannelList to search channel, since some central channl's txpowr doesn't list
-	// in ChannelList, so use TxPower array instead.
-	//
-	for (index = 0; index < MAX_NUM_OF_CHANNELS; index++)
-	{
-		if (Channel == pAd->TxPower[index].Channel)
-		{
-			TxPwer = pAd->TxPower[index].Power;
-			TxPwer2 = pAd->TxPower[index].Power2;
-			break;
-		}
-	}
-
-	if (index == MAX_NUM_OF_CHANNELS)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel));
-	}
-
-#ifdef RT30xx
-	// The RF programming sequence is difference between 3xxx and 2xxx
-	if ((IS_RT3070(pAd) || IS_RT3090(pAd)||IS_RT3390(pAd)) && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020) ||
-		(pAd->RfIcType == RFIC_3021) || (pAd->RfIcType == RFIC_3022)))
-	{
-		/* modify by WY for Read RF Reg. error */
-
-		for (index = 0; index < NUM_OF_3020_CHNL; index++)
-		{
-			if (Channel == FreqItems3020[index].Channel)
-			{
-				// Programming channel parameters
-				RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N);
-				RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3020[index].K);
-				RT30xxReadRFRegister(pAd, RF_R06, &RFValue);
-				RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
-				RT30xxWriteRFRegister(pAd, RF_R06, RFValue);
-
-				// Set Tx0 Power
-				RT30xxReadRFRegister(pAd, RF_R12, &RFValue);
-				RFValue = (RFValue & 0xE0) | TxPwer;
-				RT30xxWriteRFRegister(pAd, RF_R12, RFValue);
-
-				// Set Tx1 Power
-				RT30xxReadRFRegister(pAd, RF_R13, &RFValue);
-				RFValue = (RFValue & 0xE0) | TxPwer2;
-				RT30xxWriteRFRegister(pAd, RF_R13, RFValue);
-
-				// Tx/Rx Stream setting
-				RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
-				//if (IS_RT3090(pAd))
-				//	RFValue |= 0x01; // Enable RF block.
-				RFValue &= 0x03;	//clear bit[7~2]
-				if (pAd->Antenna.field.TxPath == 1)
-					RFValue |= 0xA0;
-				else if (pAd->Antenna.field.TxPath == 2)
-					RFValue |= 0x80;
-				if (pAd->Antenna.field.RxPath == 1)
-					RFValue |= 0x50;
-				else if (pAd->Antenna.field.RxPath == 2)
-					RFValue |= 0x40;
-				RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
-
-				// Set RF offset
-				RT30xxReadRFRegister(pAd, RF_R23, &RFValue);
-				RFValue = (RFValue & 0x80) | pAd->RfFreqOffset;
-				RT30xxWriteRFRegister(pAd, RF_R23, RFValue);
-
-				// Set BW
-				if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
-				{
-					RFValue = pAd->Mlme.CaliBW40RfR24;
-					//DISABLE_11N_CHECK(pAd);
-				}
-				else
-				{
-					RFValue = pAd->Mlme.CaliBW20RfR24;
-				}
-				RT30xxWriteRFRegister(pAd, RF_R24, RFValue);
-				RT30xxWriteRFRegister(pAd, RF_R31, RFValue);
-
-				// Enable RF tuning
-				RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
-				RFValue = RFValue | 0x1;
-				RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
-
-				// latch channel for future usage.
-				pAd->LatchRfRegs.Channel = Channel;
-
-		DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
-			Channel,
-			pAd->RfIcType,
-			TxPwer,
-			TxPwer2,
-			pAd->Antenna.field.TxPath,
-			FreqItems3020[index].N,
-			FreqItems3020[index].K,
-			FreqItems3020[index].R));
-
-				break;
-			}
-		}
-	}
-	else
-#endif // RT30xx //
-	{
-		RFRegTable = RF2850RegTable;
-		switch (pAd->RfIcType)
-		{
-			case RFIC_2820:
-			case RFIC_2850:
-			case RFIC_2720:
-			case RFIC_2750:
-
-				for (index = 0; index < NUM_OF_2850_CHNL; index++)
-				{
-					if (Channel == RFRegTable[index].Channel)
-					{
-						R2 = RFRegTable[index].R2;
-						if (pAd->Antenna.field.TxPath == 1)
-						{
-							R2 |= 0x4000;	// If TXpath is 1, bit 14 = 1;
-						}
-
-						if (pAd->Antenna.field.RxPath == 2)
-						{
-							R2 |= 0x40;	// write 1 to off Rxpath.
-						}
-						else if (pAd->Antenna.field.RxPath == 1)
-						{
-							R2 |= 0x20040;	// write 1 to off RxPath
-						}
-
-						if (Channel > 14)
-						{
-							// initialize R3, R4
-							R3 = (RFRegTable[index].R3 & 0xffffc1ff);
-							R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15);
-
-							// 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
-							// R3
-							if ((TxPwer >= -7) && (TxPwer < 0))
-							{
-								TxPwer = (7+TxPwer);
-								TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
-								R3 |= (TxPwer << 10);
-								DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer=%d \n", TxPwer));
-							}
-							else
-							{
-								TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
-								R3 |= (TxPwer << 10) | (1 << 9);
-							}
-
-							// R4
-							if ((TxPwer2 >= -7) && (TxPwer2 < 0))
-							{
-								TxPwer2 = (7+TxPwer2);
-								TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
-								R4 |= (TxPwer2 << 7);
-								DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer2=%d \n", TxPwer2));
-							}
-							else
-							{
-								TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
-								R4 |= (TxPwer2 << 7) | (1 << 6);
-							}
-						}
-						else
-						{
-							R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0
-						R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 <<6);// Set freq Offset & TxPwr1
-						}
-
-						// Based on BBP current mode before changing RF channel.
-						if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
-						{
-							R4 |=0x200000;
-						}
-
-						// Update variables
-						pAd->LatchRfRegs.Channel = Channel;
-						pAd->LatchRfRegs.R1 = RFRegTable[index].R1;
-						pAd->LatchRfRegs.R2 = R2;
-						pAd->LatchRfRegs.R3 = R3;
-						pAd->LatchRfRegs.R4 = R4;
-
-#ifdef DFS_DEBUG
-#ifdef DFS_FCC_BW40_FIX
-						if (pAd->infType == RTMP_DEV_INF_PCI) // RT2880 PCI
-						{
-							/* only for RT2880 */
-							// FCC DFS test
-							pAd->LatchRfRegs.R1 |= 0x100;
-							pAd->LatchRfRegs.R4 |= 0x00400000;
-						}
-#endif // DFS_FCC_BW40_FIX //
-#endif // DFS_DEBUG //
-
-						// Set RF value 1's set R3[bit2] = [0]
-						RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
-						RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
-						RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
-						RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
-
-						RTMPusecDelay(200);
-
-						// Set RF value 2's set R3[bit2] = [1]
-						RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
-						RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
-						RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04));
-						RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
-
-						RTMPusecDelay(200);
-
-						// Set RF value 3's set R3[bit2] = [0]
-						RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
-						RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
-						RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
-						RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
-
-						break;
-					}
-				}
-				break;
-
-			default:
-				break;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%lu, Pwr1=%lu, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
-							  Channel,
-							  pAd->RfIcType,
-							  (R3 & 0x00003e00) >> 9,
-							  (R4 & 0x000007c0) >> 6,
-							  pAd->Antenna.field.TxPath,
-							  pAd->LatchRfRegs.R1,
-							  pAd->LatchRfRegs.R2,
-							  pAd->LatchRfRegs.R3,
-							  pAd->LatchRfRegs.R4));
-	}
-
-	// Change BBP setting during siwtch from a->g, g->a
-	if (Channel <= 14)
-	{
-		ULONG	TxPinCfg = 0x00050F0A;//Gary 2007/08/09 0x050A0A
-
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);//(0x44 - GET_LNA_GAIN(pAd)));	// According the Rory's suggestion to solve the middle range issue.
-		//RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
-
-		// Rx High power VGA offset for LNA select
-		if (pAd->NicConfig2.field.ExternalLNAForG)
-		{
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
-		}
-		else
-		{
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
-		}
-
-		// 5G band selection PIN, bit1 and bit2 are complement
-		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
-		Value &= (~0x6);
-		Value |= (0x04);
-		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
-
-		// Turn off unused PA or LNA when only 1T or 1R
-		if (pAd->Antenna.field.TxPath == 1)
-		{
-			TxPinCfg &= 0xFFFFFFF3;
-		}
-		if (pAd->Antenna.field.RxPath == 1)
-		{
-			TxPinCfg &= 0xFFFFF3FF;
-		}
-
-
-		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
-
-#if defined(RT3090) || defined(RT3390)
-		// PCIe PHY Transmit attenuation adjustment
-		if (IS_RT3090A(pAd) || IS_RT3390(pAd))
-		{
-			TX_ATTENUATION_CTRL_STRUC TxAttenuationCtrl = {0};
-
-			RTMP_IO_READ32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL, &TxAttenuationCtrl.word);
-
-			if (Channel == 14) // Channel #14
-			{
-				TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 1; // Enable PCIe PHY Tx attenuation
-				TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 4; // 9/16 full drive level
-			}
-			else // Channel #1~#13
-			{
-				TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 0; // Disable PCIe PHY Tx attenuation
-				TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 0; // n/a
-			}
-
-			RTMP_IO_WRITE32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL, TxAttenuationCtrl.word);
-		}
-#endif
-	}
-	else
-	{
-		ULONG	TxPinCfg = 0x00050F05;//Gary 2007/8/9 0x050505
-
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);//(0x44 - GET_LNA_GAIN(pAd)));   // According the Rory's suggestion to solve the middle range issue.
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
-
-		// Rx High power VGA offset for LNA select
-		if (pAd->NicConfig2.field.ExternalLNAForA)
-		{
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
-		}
-		else
-		{
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
-		}
-
-		// 5G band selection PIN, bit1 and bit2 are complement
-		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
-		Value &= (~0x6);
-		Value |= (0x02);
-		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
-
-		// Turn off unused PA or LNA when only 1T or 1R
-		if (pAd->Antenna.field.TxPath == 1)
-		{
-			TxPinCfg &= 0xFFFFFFF3;
-		}
-		if (pAd->Antenna.field.RxPath == 1)
-		{
-			TxPinCfg &= 0xFFFFF3FF;
-		}
-
-
-		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
-
-	}
-
-	// R66 should be set according to Channel and use 20MHz when scanning
-	//RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd)));
-	if (bScan)
-		RTMPSetAGCInitValue(pAd, BW_20);
-	else
-		RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
-
-	//
-	// On 11A, We should delay and wait RF/BBP to be stable
-	// and the appropriate time should be 1000 micro seconds
-	// 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
-	//
-	RTMPusecDelay(1000);
-}
-
-/*
-	==========================================================================
-	Description:
-		This function is required for 2421 only, and should not be used during
-		site survey. It's only required after NIC decided to stay at a channel
-		for a longer period.
-		When this function is called, it's always after AsicSwitchChannel().
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AsicLockChannel(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR Channel)
-{
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-#ifdef ANT_DIVERSITY_SUPPORT
-VOID	AsicAntennaSelect(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Channel)
-{
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	if (pAd->Mlme.OneSecPeriodicRound % 2 == 1)
-#endif // CONFIG_STA_SUPPORT //
-	{
-		// patch for AsicSetRxAnt failed
-		pAd->RxAnt.EvaluatePeriod = 0;
-
-		// check every 2 second. If rcv-beacon less than 5 in the past 2 second, then AvgRSSI is no longer a
-		// valid indication of the distance between this AP and its clients.
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-		{
-			SHORT	realavgrssi1;
-
-			// if no traffic then reset average rssi to trigger evaluation
-#ifdef CONFIG_STA_SUPPORT
-			if (pAd->StaCfg.NumOfAvgRssiSample < 5)
-			{
-				pAd->RxAnt.Pair1LastAvgRssi = (-99);
-				pAd->RxAnt.Pair2LastAvgRssi = (-99);
-				DBGPRINT(RT_DEBUG_TRACE, ("MlmePeriodicExec: no traffic/beacon, reset RSSI\n"));
-			}
-
-			pAd->StaCfg.NumOfAvgRssiSample = 0;
-			realavgrssi1 = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt] >> 3);
-#endif // CONFIG_STA_SUPPORT //
-
-			DBGPRINT(RT_DEBUG_TRACE,("Ant-realrssi0(%d), Lastrssi0(%d), EvaluateStableCnt=%d\n", realavgrssi1, pAd->RxAnt.Pair1LastAvgRssi, pAd->RxAnt.EvaluateStableCnt));
-
-			// if the difference between two rssi is larger or less than 5, then evaluate the other antenna
-			if ((pAd->RxAnt.EvaluateStableCnt < 2) || (realavgrssi1 > (pAd->RxAnt.Pair1LastAvgRssi + 5)) || (realavgrssi1 < (pAd->RxAnt.Pair1LastAvgRssi - 5)))
-				AsicEvaluateRxAnt(pAd);
-
-				pAd->RxAnt.Pair1LastAvgRssi = realavgrssi1;
-		}
-		else
-		{
-			// if not connected, always switch antenna to try to connect
-			UCHAR	temp;
-
-			temp = pAd->RxAnt.Pair1PrimaryRxAnt;
-			pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt;
-			pAd->RxAnt.Pair1SecondaryRxAnt = temp;
-
-			DBGPRINT(RT_DEBUG_TRACE, ("MlmePeriodicExec: no connect, switch to another one to try connection\n"));
-
-			AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
-		}
-	}
-}
-#endif // ANT_DIVERSITY_SUPPORT //
-
-/*
-	========================================================================
-
-	Routine Description:
-		Antenna miscellaneous setting.
-
-	Arguments:
-		pAd						Pointer to our adapter
-		BandState				Indicate current Band State.
-
-	Return Value:
-		None
-
-	IRQL <= DISPATCH_LEVEL
-
-	Note:
-		1.) Frame End type control
-			only valid for G only (RF_2527 & RF_2529)
-			0: means DPDT, set BBP R4 bit 5 to 1
-			1: means SPDT, set BBP R4 bit 5 to 0
-
-
-	========================================================================
-*/
-VOID	AsicAntennaSetting(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	ABGBAND_STATE	BandState)
-{
-}
-
-VOID AsicRfTuningExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3)
-{
-}
-
-/*
-	==========================================================================
-	Description:
-		Gives CCK TX rate 2 more dB TX power.
-		This routine works only in LINK UP in INFRASTRUCTURE mode.
-
-		calculate desired Tx power in RF R3.Tx0~5,	should consider -
-		0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
-		1. TxPowerPercentage
-		2. auto calibration based on TSSI feedback
-		3. extra 2 db for CCK
-		4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
-
-	NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
-		it should be called AFTER MlmeDynamicTxRatSwitching()
-	==========================================================================
- */
-VOID AsicAdjustTxPower(
-	IN PRTMP_ADAPTER pAd)
-{
-	INT			i, j;
-	CHAR		DeltaPwr = 0;
-	BOOLEAN		bAutoTxAgc = FALSE;
-	UCHAR		TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
-	UCHAR		BbpR1 = 0, BbpR49 = 0, idx;
-	PCHAR		pTxAgcCompensate;
-	ULONG		TxPwr[5];
-	CHAR		Value;
-#ifdef CONFIG_STA_SUPPORT
-	CHAR		Rssi = -127;
-#endif // CONFIG_STA_SUPPORT //
-#ifdef CARRIER_SENSE_NEW_ALGO
-	unsigned long flags; //KH Add to Fix PCIe Power-Saving bug
-#endif // CARRIER_SENSE_NEW_ALGO //
-
-
-#ifdef CARRIER_SENSE_NEW_ALGO
-	//KH Add to Fix PCIe Power-Saving bug<--
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	//KH Add to Fix PCIe Power-Saving bug-->
-#endif // CARRIER_SENSE_NEW_ALGO //
-
-#ifdef CONFIG_STA_SUPPORT
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
-#ifdef RTMP_MAC_PCI
-		(pAd->bPCIclkOff == TRUE) ||
-#endif // RTMP_MAC_PCI //
-		RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF) ||
-		RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-{
-
-#ifdef CARRIER_SENSE_NEW_ALGO
-	//KH Add to Fix PCIe Power-Saving bug<--
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-	//KH add to fix PCIe-Power Saving -->
-#endif // CARRIER_SENSE_NEW_ALGO //
-		return;
-}
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		Rssi = RTMPMaxRssi(pAd,
-						   pAd->StaCfg.RssiSample.AvgRssi0,
-						   pAd->StaCfg.RssiSample.AvgRssi1,
-						   pAd->StaCfg.RssiSample.AvgRssi2);
-#endif // CONFIG_STA_SUPPORT //
-
-	if (pAd->CommonCfg.BBPCurrentBW == BW_40)
-	{
-		if (pAd->CommonCfg.CentralChannel > 14)
-		{
-			TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
-			TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
-			TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
-			TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
-			TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
-		}
-		else
-		{
-			TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
-			TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
-			TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
-			TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
-			TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
-		}
-	}
-	else
-	{
-		if (pAd->CommonCfg.Channel > 14)
-		{
-			TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
-			TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
-			TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
-			TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
-			TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
-		}
-		else
-		{
-			TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
-			TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
-			TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
-			TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
-			TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
-		}
-	}
-
-	// TX power compensation for temperature variation based on TSSI. try every 4 second
-	if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
-	{
-		if (pAd->CommonCfg.Channel <= 14)
-		{
-			/* bg channel */
-			bAutoTxAgc         = pAd->bAutoTxAgcG;
-			TssiRef            = pAd->TssiRefG;
-			pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
-			pTssiPlusBoundary  = &pAd->TssiPlusBoundaryG[0];
-			TxAgcStep          = pAd->TxAgcStepG;
-			pTxAgcCompensate   = &pAd->TxAgcCompensateG;
-		}
-		else
-		{
-			/* a channel */
-			bAutoTxAgc         = pAd->bAutoTxAgcA;
-			TssiRef            = pAd->TssiRefA;
-			pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
-			pTssiPlusBoundary  = &pAd->TssiPlusBoundaryA[0];
-			TxAgcStep          = pAd->TxAgcStepA;
-			pTxAgcCompensate   = &pAd->TxAgcCompensateA;
-		}
-
-		if (bAutoTxAgc)
-		{
-			/* BbpR1 is unsigned char */
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
-
-			/* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
-			/* compensate: +4     +3   +2   +1    0   -1   -2   -3   -4 * steps */
-			/* step value is defined in pAd->TxAgcStepG for tx power value */
-
-			/* [4]+1+[4]   p4     p3   p2   p1   o1   m1   m2   m3   m4 */
-			/* ex:         0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
-			   above value are examined in mass factory production */
-			/*             [4]    [3]  [2]  [1]  [0]  [1]  [2]  [3]  [4] */
-
-			/* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
-			/* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
-			/* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
-
-			if (BbpR49 > pTssiMinusBoundary[1])
-			{
-				// Reading is larger than the reference value
-				// check for how large we need to decrease the Tx power
-				for (idx = 1; idx < 5; idx++)
-				{
-					if (BbpR49 <= pTssiMinusBoundary[idx])  // Found the range
-						break;
-				}
-				// The index is the step we should decrease, idx = 0 means there is nothing to compensate
-//				if (R3 > (ULONG) (TxAgcStep * (idx-1)))
-					*pTxAgcCompensate = -(TxAgcStep * (idx-1));
-//				else
-//					*pTxAgcCompensate = -((UCHAR)R3);
-
-				DeltaPwr += (*pTxAgcCompensate);
-				DBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
-					BbpR49, TssiRef, TxAgcStep, idx-1));
-			}
-			else if (BbpR49 < pTssiPlusBoundary[1])
-			{
-				// Reading is smaller than the reference value
-				// check for how large we need to increase the Tx power
-				for (idx = 1; idx < 5; idx++)
-				{
-					if (BbpR49 >= pTssiPlusBoundary[idx])   // Found the range
-						break;
-				}
-				// The index is the step we should increase, idx = 0 means there is nothing to compensate
-				*pTxAgcCompensate = TxAgcStep * (idx-1);
-				DeltaPwr += (*pTxAgcCompensate);
-				DBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
-					BbpR49, TssiRef, TxAgcStep, idx-1));
-			}
-			else
-			{
-				*pTxAgcCompensate = 0;
-				DBGPRINT(RT_DEBUG_TRACE, ("   Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
-					BbpR49, TssiRef, TxAgcStep, 0));
-			}
-		}
-	}
-	else
-	{
-		if (pAd->CommonCfg.Channel <= 14)
-		{
-			bAutoTxAgc         = pAd->bAutoTxAgcG;
-			pTxAgcCompensate   = &pAd->TxAgcCompensateG;
-		}
-		else
-		{
-			bAutoTxAgc         = pAd->bAutoTxAgcA;
-			pTxAgcCompensate   = &pAd->TxAgcCompensateA;
-		}
-
-		if (bAutoTxAgc)
-			DeltaPwr += (*pTxAgcCompensate);
-	}
-
-	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1);
-	BbpR1 &= 0xFC;
-
-#ifdef SINGLE_SKU
-	// Handle regulatory max tx power constrain
-	do
-	{
-		UCHAR    TxPwrInEEPROM = 0xFF, CountryTxPwr = 0xFF, criterion;
-		UCHAR    AdjustMaxTxPwr[40];
-
-		if (pAd->CommonCfg.Channel > 14) // 5G band
-			TxPwrInEEPROM = ((pAd->CommonCfg.DefineMaxTxPwr & 0xFF00) >> 8);
-		else // 2.4G band
-			TxPwrInEEPROM = (pAd->CommonCfg.DefineMaxTxPwr & 0x00FF);
-		CountryTxPwr = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel);
-
-		// error handling, range check
-		if ((TxPwrInEEPROM > 0x50) || (CountryTxPwr > 0x50))
-		{
-			DBGPRINT(RT_DEBUG_ERROR,("AsicAdjustTxPower - Invalid max tx power (=0x%02x), CountryTxPwr=%d\n", TxPwrInEEPROM, CountryTxPwr));
-			break;
-		}
-
-		criterion = *((PUCHAR)TxPwr + 2) & 0xF;        // FAE use OFDM 6M as criterion
-
-		DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (criterion=%d, TxPwrInEEPROM=%d, CountryTxPwr=%d)\n", criterion, TxPwrInEEPROM, CountryTxPwr));
-
-		// Adjust max tx power according to the relationship of tx power in E2PROM
-		for (i=0; i<5; i++)
-		{
-			// CCK will have 4dBm larger than OFDM
-			// Therefore, we should separate to parse the tx power field
-			if (i == 0)
-			{
-				for (j=0; j<8; j++)
-				{
-					Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
-
-					if (j < 4)
-					{
-						// CCK will have 4dBm larger than OFDM
-						AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion) + 4;
-					}
-					else
-					{
-						AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion);
-					}
-					DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
-				}
-			}
-			else
-			{
-				for (j=0; j<8; j++)
-				{
-					Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
-
-					AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion);
-					DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
-				}
-			}
-		}
-
-		// Adjust tx power according to the relationship
-		for (i=0; i<5; i++)
-		{
-			if (TxPwr[i] != 0xffffffff)
-			{
-				for (j=0; j<8; j++)
-				{
-					Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
-
-					// The system tx power is larger than the regulatory, the power should be restrain
-					if (AdjustMaxTxPwr[i*8+j] > CountryTxPwr)
-					{
-						// decrease to zero and don't need to take care BBPR1
-						if ((Value - (AdjustMaxTxPwr[i*8+j] - CountryTxPwr)) > 0)
-							Value -= (AdjustMaxTxPwr[i*8+j] - CountryTxPwr);
-						else
-							Value = 0;
-
-						DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
-					}
-					else
-						DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d, no change)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
-
-						TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
-				}
-			}
-		}
-	} while (FALSE);
-#endif // SINGLE_SKU //
-
-	/* calculate delta power based on the percentage specified from UI */
-	// E2PROM setting is calibrated for maximum TX power (i.e. 100%)
-	// We lower TX power here according to the percentage specified from UI
-	if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff)       // AUTO TX POWER control
-	{
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			// to patch high power issue with some APs, like Belkin N1.
-			if (Rssi > -35)
-			{
-				BbpR1 |= 0x02;		// DeltaPwr -= 12;
-			}
-			else if (Rssi > -40)
-			{
-				BbpR1 |= 0x01;		// DeltaPwr -= 6;
-			}
-			else
-		;
-		}
-#endif // CONFIG_STA_SUPPORT //
-	}
-	else if (pAd->CommonCfg.TxPowerPercentage > 90)  // 91 ~ 100% & AUTO, treat as 100% in terms of mW
-		;
-	else if (pAd->CommonCfg.TxPowerPercentage > 60)  // 61 ~ 90%, treat as 75% in terms of mW		// DeltaPwr -= 1;
-	{
-		DeltaPwr -= 1;
-	}
-	else if (pAd->CommonCfg.TxPowerPercentage > 30)  // 31 ~ 60%, treat as 50% in terms of mW		// DeltaPwr -= 3;
-	{
-		DeltaPwr -= 3;
-	}
-	else if (pAd->CommonCfg.TxPowerPercentage > 15)  // 16 ~ 30%, treat as 25% in terms of mW		// DeltaPwr -= 6;
-	{
-		BbpR1 |= 0x01;
-	}
-	else if (pAd->CommonCfg.TxPowerPercentage > 9)   // 10 ~ 15%, treat as 12.5% in terms of mW		// DeltaPwr -= 9;
-	{
-		BbpR1 |= 0x01;
-		DeltaPwr -= 3;
-	}
-	else                                           // 0 ~ 9 %, treat as MIN(~3%) in terms of mW		// DeltaPwr -= 12;
-	{
-		BbpR1 |= 0x02;
-	}
-
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
-
-	/* reset different new tx power for different TX rate */
-	for(i=0; i<5; i++)
-	{
-		if (TxPwr[i] != 0xffffffff)
-		{
-			for (j=0; j<8; j++)
-			{
-				Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */
-
-				if ((Value + DeltaPwr) < 0)
-				{
-					Value = 0; /* min */
-				}
-				else if ((Value + DeltaPwr) > 0xF)
-				{
-					Value = 0xF; /* max */
-				}
-				else
-				{
-					Value += DeltaPwr; /* temperature compensation */
-				}
-
-				/* fill new value to CSR offset */
-				TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
-			}
-
-			/* write tx power value to CSR */
-			/* TX_PWR_CFG_0 (8 tx rate) for	TX power for OFDM 12M/18M
-											TX power for OFDM 6M/9M
-											TX power for CCK5.5M/11M
-											TX power for CCK1M/2M */
-			/* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
-			RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);
-		}
-	}
-
-#ifdef CARRIER_SENSE_NEW_ALGO
-	//KH Add to Fix PCIe Power-Saving bug<--
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-	//KH add to fix PCIe-Power Saving -->
-#endif // CARRIER_SENSE_NEW_ALGO //
-
-}
-
-
-#ifdef CONFIG_STA_SUPPORT
-VOID AsicResetBBPAgent(
-IN PRTMP_ADAPTER pAd)
-{
-	BBP_CSR_CFG_STRUC	BbpCsr;
-	DBGPRINT(RT_DEBUG_ERROR, ("Reset BBP Agent busy bit.!! \n"));
-	// Still need to find why BBP agent keeps busy, but in fact, hardware still function ok. Now clear busy first.
-	RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word);
-	BbpCsr.field.Busy = 0;
-	RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word);
-}
-/*
-	==========================================================================
-	Description:
-		put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup
-		automatically. Instead, MCU will issue a TwakeUpInterrupt to host after
-		the wakeup timer timeout. Driver has to issue a separate command to wake
-		PHY up.
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AsicSleepThenAutoWakeup(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT TbttNumToNextWakeUp)
-{
-	RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp);
-}
-
-/*
-	==========================================================================
-	Description:
-		AsicForceWakeup() is used whenever manual wakeup is required
-		AsicForceSleep() should only be used when not in INFRA BSS. When
-		in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead.
-	==========================================================================
- */
-VOID AsicForceSleep(
-	IN PRTMP_ADAPTER pAd)
-{
-
-}
-
-/*
-	==========================================================================
-	Description:
-		AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
-		expired.
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-	==========================================================================
- */
-VOID AsicForceWakeup(
-	IN PRTMP_ADAPTER pAd,
-	IN BOOLEAN    bFromTx)
-{
-    DBGPRINT(RT_DEBUG_INFO, ("--> AsicForceWakeup \n"));
-    RTMP_STA_FORCE_WAKEUP(pAd, bFromTx);
-}
-#endif // CONFIG_STA_SUPPORT //
-
-
-/*
-	==========================================================================
-	Description:
-		Set My BSSID
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AsicSetBssid(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pBssid)
-{
-	ULONG		  Addr4;
-	DBGPRINT(RT_DEBUG_TRACE, ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n",
-		pBssid[0],pBssid[1],pBssid[2],pBssid[3], pBssid[4],pBssid[5]));
-
-	Addr4 = (ULONG)(pBssid[0])		 |
-			(ULONG)(pBssid[1] << 8)  |
-			(ULONG)(pBssid[2] << 16) |
-			(ULONG)(pBssid[3] << 24);
-	RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
-
-	Addr4 = 0;
-	// always one BSSID in STA mode
-	Addr4 = (ULONG)(pBssid[4]) | (ULONG)(pBssid[5] << 8);
-
-	RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
-}
-
-VOID AsicSetMcastWC(
-	IN PRTMP_ADAPTER pAd)
-{
-	MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[MCAST_WCID];
-	USHORT		offset;
-
-	pEntry->Sst        = SST_ASSOC;
-	pEntry->Aid        = MCAST_WCID;	// Softap supports 1 BSSID and use WCID=0 as multicast Wcid index
-	pEntry->PsMode     = PWR_ACTIVE;
-	pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate;
-	offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE;
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AsicDelWcidTab(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR	Wcid)
-{
-	ULONG		  Addr0 = 0x0, Addr1 = 0x0;
-	ULONG		offset;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n",Wcid));
-	offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE;
-	RTMP_IO_WRITE32(pAd, offset, Addr0);
-	offset += 4;
-	RTMP_IO_WRITE32(pAd, offset, Addr1);
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AsicEnableRDG(
-	IN PRTMP_ADAPTER pAd)
-{
-	TX_LINK_CFG_STRUC	TxLinkCfg;
-	UINT32				Data = 0;
-
-	RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
-	TxLinkCfg.field.TxRDGEn = 1;
-	RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
-
-	RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
-	Data  &= 0xFFFFFF00;
-	Data  |= 0x80;
-	RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
-
-	//OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AsicDisableRDG(
-	IN PRTMP_ADAPTER pAd)
-{
-	TX_LINK_CFG_STRUC	TxLinkCfg;
-	UINT32				Data = 0;
-
-
-	RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
-	TxLinkCfg.field.TxRDGEn = 0;
-	RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
-
-	RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
-
-	Data  &= 0xFFFFFF00;
-	//Data  |= 0x20;
-#ifndef WIFI_TEST
-	//if ( pAd->CommonCfg.bEnableTxBurst )
-	//	Data |= 0x60; // for performance issue not set the TXOP to 0
-#endif
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)
-#ifdef DOT11_N_SUPPORT
-		&& (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE)
-#endif // DOT11_N_SUPPORT //
-	)
-	{
-		// For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
-		if (pAd->CommonCfg.bEnableTxBurst)
-		Data |= 0x20;
-	}
-	RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AsicDisableSync(
-	IN PRTMP_ADAPTER pAd)
-{
-	BCN_TIME_CFG_STRUC csr;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n"));
-
-	// 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect
-	//			  that NIC will never wakes up because TSF stops and no more
-	//			  TBTT interrupts
-	pAd->TbttTickCount = 0;
-	RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
-	csr.field.bBeaconGen = 0;
-	csr.field.bTBTTEnable = 0;
-	csr.field.TsfSyncMode = 0;
-	csr.field.bTsfTicking = 0;
-	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
-
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AsicEnableBssSync(
-	IN PRTMP_ADAPTER pAd)
-{
-	BCN_TIME_CFG_STRUC csr;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n"));
-
-	RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
-//	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, 0x00000000);
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
-		csr.field.bTsfTicking = 1;
-		csr.field.TsfSyncMode = 1; // sync TSF in INFRASTRUCTURE mode
-		csr.field.bBeaconGen  = 0; // do NOT generate BEACON
-		csr.field.bTBTTEnable = 1;
-	}
-#endif // CONFIG_STA_SUPPORT //
-	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
-}
-
-/*
-	==========================================================================
-	Description:
-	Note:
-		BEACON frame in shared memory should be built ok before this routine
-		can be called. Otherwise, a garbage frame maybe transmitted out every
-		Beacon period.
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AsicEnableIbssSync(
-	IN PRTMP_ADAPTER pAd)
-{
-	BCN_TIME_CFG_STRUC csr9;
-	PUCHAR			ptr;
-	UINT i;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", pAd->BeaconTxWI.MPDUtotalByteCount));
-
-	RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
-	csr9.field.bBeaconGen = 0;
-	csr9.field.bTBTTEnable = 0;
-	csr9.field.bTsfTicking = 0;
-	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
-
-#ifdef RTMP_MAC_PCI
-	// move BEACON TXD and frame content to on-chip memory
-	ptr = (PUCHAR)&pAd->BeaconTxWI;
-	for (i=0; i<TXWI_SIZE; i+=4)  // 16-byte TXWI field
-	{
-		UINT32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
-		RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
-		ptr += 4;
-	}
-
-	// start right after the 16-byte TXWI field
-	ptr = pAd->BeaconBuf;
-	for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=4)
-	{
-		UINT32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
-		RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
-		ptr +=4;
-	}
-#endif // RTMP_MAC_PCI //
-
-
-	//
-	// For Wi-Fi faily generated beacons between participating stations.
-	// Set TBTT phase adaptive adjustment step to 8us (default 16us)
-	// don't change settings 2006-5- by Jerry
-	//RTMP_IO_WRITE32(pAd, TBTT_SYNC_CFG, 0x00001010);
-
-	// start sending BEACON
-	csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
-	csr9.field.bTsfTicking = 1;
-	csr9.field.TsfSyncMode = 2; // sync TSF in IBSS mode
-	csr9.field.bTBTTEnable = 1;
-	csr9.field.bBeaconGen = 1;
-	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AsicSetEdcaParm(
-	IN PRTMP_ADAPTER pAd,
-	IN PEDCA_PARM	 pEdcaParm)
-{
-	EDCA_AC_CFG_STRUC   Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg;
-	AC_TXOP_CSR0_STRUC csr0;
-	AC_TXOP_CSR1_STRUC csr1;
-	AIFSN_CSR_STRUC    AifsnCsr;
-	CWMIN_CSR_STRUC    CwminCsr;
-	CWMAX_CSR_STRUC    CwmaxCsr;
-	int i;
-
-	Ac0Cfg.word = 0;
-	Ac1Cfg.word = 0;
-	Ac2Cfg.word = 0;
-	Ac3Cfg.word = 0;
-	if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE))
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("AsicSetEdcaParm\n"));
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED);
-		for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
-		{
-			if (pAd->MacTab.Content[i].ValidAsCLI || pAd->MacTab.Content[i].ValidAsApCli)
-				CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[i], fCLIENT_STATUS_WMM_CAPABLE);
-		}
-
-		//========================================================
-		//      MAC Register has a copy .
-		//========================================================
-//#ifndef WIFI_TEST
-		if( pAd->CommonCfg.bEnableTxBurst )
-		{
-			// For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
-			Ac0Cfg.field.AcTxop = 0x20; // Suggest by John for TxBurst in HT Mode
-		}
-		else
-			Ac0Cfg.field.AcTxop = 0;	// QID_AC_BE
-//#else
-//		Ac0Cfg.field.AcTxop = 0;	// QID_AC_BE
-//#endif
-		Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS;
-		Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS;
-		Ac0Cfg.field.Aifsn = 2;
-		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
-
-		Ac1Cfg.field.AcTxop = 0;	// QID_AC_BK
-		Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS;
-		Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS;
-		Ac1Cfg.field.Aifsn = 2;
-		RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
-
-		if (pAd->CommonCfg.PhyMode == PHY_11B)
-		{
-			Ac2Cfg.field.AcTxop = 192;	// AC_VI: 192*32us ~= 6ms
-			Ac3Cfg.field.AcTxop = 96;	// AC_VO: 96*32us  ~= 3ms
-		}
-		else
-		{
-			Ac2Cfg.field.AcTxop = 96;	// AC_VI: 96*32us ~= 3ms
-			Ac3Cfg.field.AcTxop = 48;	// AC_VO: 48*32us ~= 1.5ms
-		}
-		Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS;
-		Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS;
-		Ac2Cfg.field.Aifsn = 2;
-		RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
-		Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS;
-		Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS;
-		Ac3Cfg.field.Aifsn = 2;
-		RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
-
-		//========================================================
-		//      DMA Register has a copy too.
-		//========================================================
-		csr0.field.Ac0Txop = 0;		// QID_AC_BE
-		csr0.field.Ac1Txop = 0;		// QID_AC_BK
-		RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
-		if (pAd->CommonCfg.PhyMode == PHY_11B)
-		{
-			csr1.field.Ac2Txop = 192;		// AC_VI: 192*32us ~= 6ms
-			csr1.field.Ac3Txop = 96;		// AC_VO: 96*32us  ~= 3ms
-		}
-		else
-		{
-			csr1.field.Ac2Txop = 96;		// AC_VI: 96*32us ~= 3ms
-			csr1.field.Ac3Txop = 48;		// AC_VO: 48*32us ~= 1.5ms
-		}
-		RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
-
-		CwminCsr.word = 0;
-		CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS;
-		CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS;
-		CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS;
-		CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS;
-		RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
-
-		CwmaxCsr.word = 0;
-		CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS;
-		CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS;
-		CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS;
-		CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS;
-		RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
-
-		RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222);
-
-		NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(EDCA_PARM));
-	}
-	else
-	{
-		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED);
-		//========================================================
-		//      MAC Register has a copy.
-		//========================================================
-		//
-		// Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27
-		// To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue.
-		//
-		//pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this
-
-		Ac0Cfg.field.AcTxop =  pEdcaParm->Txop[QID_AC_BE];
-		Ac0Cfg.field.Cwmin= pEdcaParm->Cwmin[QID_AC_BE];
-		Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE];
-		Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]; //+1;
-
-		Ac1Cfg.field.AcTxop =  pEdcaParm->Txop[QID_AC_BK];
-		Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK]; //+2;
-		Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK];
-		Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; //+1;
-
-		Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10;
-		if(pAd->Antenna.field.TxPath == 1)
-		{
-			Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI] + 1;
-			Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI] + 1;
-		}
-		else
-		{
-		Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI];
-		Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI];
-		}
-		Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 1;
-#ifdef CONFIG_STA_SUPPORT
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef INF_AMAZON_SE
-#endif // INF_AMAZON_SE //
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			// Tuning for Wi-Fi WMM S06
-			if (pAd->CommonCfg.bWiFiTest &&
-				pEdcaParm->Aifsn[QID_AC_VI] == 10)
-				Ac2Cfg.field.Aifsn -= 1;
-
-			// Tuning for TGn Wi-Fi 5.2.32
-			// STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta
-			if (STA_TGN_WIFI_ON(pAd) &&
-				pEdcaParm->Aifsn[QID_AC_VI] == 10)
-			{
-				Ac0Cfg.field.Aifsn = 3;
-				Ac2Cfg.field.AcTxop = 5;
-			}
-
-#ifdef RT30xx
-			if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
-			{
-				// Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta.
-				Ac2Cfg.field.Aifsn = 5;
-			}
-#endif // RT30xx //
-		}
-#endif // CONFIG_STA_SUPPORT //
-
-		Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO];
-		Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO];
-		Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO];
-		Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO];
-
-//#ifdef WIFI_TEST
-		if (pAd->CommonCfg.bWiFiTest)
-		{
-			if (Ac3Cfg.field.AcTxop == 102)
-			{
-			Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->Txop[QID_AC_BE] : 10;
-				Ac0Cfg.field.Aifsn  = pEdcaParm->Aifsn[QID_AC_BE]-1; /* AIFSN must >= 1 */
-			Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
-				Ac1Cfg.field.Aifsn  = pEdcaParm->Aifsn[QID_AC_BK];
-			Ac2Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VI];
-			} /* End of if */
-		}
-//#endif // WIFI_TEST //
-
-		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
-		RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
-		RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
-		RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
-
-
-		//========================================================
-		//      DMA Register has a copy too.
-		//========================================================
-		csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop;
-		csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop;
-		RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
-
-		csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop;
-		csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop;
-		RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
-
-		CwminCsr.word = 0;
-		CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE];
-		CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK];
-		CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI];
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-			CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1; //for TGn wifi test
-#endif // CONFIG_STA_SUPPORT //
-		RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
-
-		CwmaxCsr.word = 0;
-		CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE];
-		CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK];
-		CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI];
-		CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO];
-		RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
-
-		AifsnCsr.word = 0;
-		AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BE];
-		AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BK];
-		AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_VI];
-#ifdef INF_AMAZON_SE
-#endif // INF_AMAZON_SE //
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			// Tuning for Wi-Fi WMM S06
-			if (pAd->CommonCfg.bWiFiTest &&
-				pEdcaParm->Aifsn[QID_AC_VI] == 10)
-				AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4;
-
-			// Tuning for TGn Wi-Fi 5.2.32
-			// STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta
-			if (STA_TGN_WIFI_ON(pAd) &&
-				pEdcaParm->Aifsn[QID_AC_VI] == 10)
-			{
-				AifsnCsr.field.Aifsn0 = 3;
-				AifsnCsr.field.Aifsn2 = 7;
-			}
-
-			if (INFRA_ON(pAd))
-				CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_WMM_CAPABLE);
-		}
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test
-#ifdef RT30xx
-			// TODO: Shiang, this modification also suitable for RT3052/RT3050 ???
-			if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
-			{
-				IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-					AifsnCsr.field.Aifsn2 = 0x2; //pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04.
-			}
-#endif // RT30xx //
-		}
-#endif // CONFIG_STA_SUPPORT //
-		RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
-
-		NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
-		if (!ADHOC_ON(pAd))
-		{
-			DBGPRINT(RT_DEBUG_TRACE,("EDCA [#%d]: AIFSN CWmin CWmax  TXOP(us)  ACM\n", pEdcaParm->EdcaUpdateCount));
-			DBGPRINT(RT_DEBUG_TRACE,("     AC_BE      %2d     %2d     %2d      %4d     %d\n",
-									 pEdcaParm->Aifsn[0],
-									 pEdcaParm->Cwmin[0],
-									 pEdcaParm->Cwmax[0],
-									 pEdcaParm->Txop[0]<<5,
-									 pEdcaParm->bACM[0]));
-			DBGPRINT(RT_DEBUG_TRACE,("     AC_BK      %2d     %2d     %2d      %4d     %d\n",
-									 pEdcaParm->Aifsn[1],
-									 pEdcaParm->Cwmin[1],
-									 pEdcaParm->Cwmax[1],
-									 pEdcaParm->Txop[1]<<5,
-									 pEdcaParm->bACM[1]));
-			DBGPRINT(RT_DEBUG_TRACE,("     AC_VI      %2d     %2d     %2d      %4d     %d\n",
-									 pEdcaParm->Aifsn[2],
-									 pEdcaParm->Cwmin[2],
-									 pEdcaParm->Cwmax[2],
-									 pEdcaParm->Txop[2]<<5,
-									 pEdcaParm->bACM[2]));
-			DBGPRINT(RT_DEBUG_TRACE,("     AC_VO      %2d     %2d     %2d      %4d     %d\n",
-									 pEdcaParm->Aifsn[3],
-									 pEdcaParm->Cwmin[3],
-									 pEdcaParm->Cwmax[3],
-									 pEdcaParm->Txop[3]<<5,
-									 pEdcaParm->bACM[3]));
-		}
-	}
-
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID	AsicSetSlotTime(
-	IN PRTMP_ADAPTER pAd,
-	IN BOOLEAN bUseShortSlotTime)
-{
-	ULONG	SlotTime;
-	UINT32	RegValue = 0;
-
-#ifdef CONFIG_STA_SUPPORT
-	if (pAd->CommonCfg.Channel > 14)
-		bUseShortSlotTime = TRUE;
-#endif // CONFIG_STA_SUPPORT //
-
-	if (bUseShortSlotTime && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))
-		return;
-	else if ((!bUseShortSlotTime) && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED)))
-		return;
-
-	if (bUseShortSlotTime)
-		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
-	else
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
-
-	SlotTime = (bUseShortSlotTime)? 9 : 20;
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		// force using short SLOT time for FAE to demo performance when TxBurst is ON
-		if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
-#ifdef DOT11_N_SUPPORT
-			|| ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))
-#endif // DOT11_N_SUPPORT //
-			)
-		{
-			// In this case, we will think it is doing Wi-Fi test
-			// And we will not set to short slot when bEnableTxBurst is TRUE.
-		}
-		else if (pAd->CommonCfg.bEnableTxBurst)
-		{
-			OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
-			SlotTime = 9;
-		}
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	//
-	// For some reasons, always set it to short slot time.
-	//
-	// ToDo: Should consider capability with 11B
-	//
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		if (pAd->StaCfg.BssType == BSS_ADHOC)
-		{
-			OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
-			SlotTime = 20;
-		}
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
-	RegValue = RegValue & 0xFFFFFF00;
-
-	RegValue |= SlotTime;
-
-	RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue);
-}
-
-/*
-	========================================================================
-	Description:
-		Add Shared key information into ASIC.
-		Update shared key, TxMic and RxMic to Asic Shared key table
-		Update its cipherAlg to Asic Shared key Mode.
-
-    Return:
-	========================================================================
-*/
-VOID AsicAddSharedKeyEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR		 BssIndex,
-	IN UCHAR		 KeyIdx,
-	IN UCHAR		 CipherAlg,
-	IN PUCHAR		 pKey,
-	IN PUCHAR		 pTxMic,
-	IN PUCHAR		 pRxMic)
-{
-	ULONG offset; //, csr0;
-	SHAREDKEY_MODE_STRUC csr1;
-#ifdef RTMP_MAC_PCI
-	INT   i;
-#endif // RTMP_MAC_PCI //
-
-	DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx));
-//============================================================================================
-
-	DBGPRINT(RT_DEBUG_TRACE,("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg], BssIndex*4 + KeyIdx));
-	DBGPRINT_RAW(RT_DEBUG_TRACE, ("		Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-		pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15]));
-	if (pRxMic)
-	{
-		DBGPRINT_RAW(RT_DEBUG_TRACE, ("		Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-			pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
-	}
-	if (pTxMic)
-	{
-		DBGPRINT_RAW(RT_DEBUG_TRACE, ("		Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-			pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
-	}
-//============================================================================================
-	//
-	// fill key material - key + TX MIC + RX MIC
-	//
-#ifdef RTMP_MAC_PCI
-	offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
-	for (i=0; i<MAX_LEN_OF_SHARE_KEY; i++)
-	{
-		RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
-	}
-
-	offset += MAX_LEN_OF_SHARE_KEY;
-	if (pTxMic)
-	{
-		for (i=0; i<8; i++)
-		{
-			RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
-		}
-	}
-
-	offset += 8;
-	if (pRxMic)
-	{
-		for (i=0; i<8; i++)
-		{
-			RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
-		}
-	}
-#endif // RTMP_MAC_PCI //
-
-
-	//
-	// Update cipher algorithm. WSTA always use BSS0
-	//
-	RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
-	DBGPRINT(RT_DEBUG_TRACE,("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n", BssIndex,KeyIdx, csr1.word));
-	if ((BssIndex%2) == 0)
-	{
-		if (KeyIdx == 0)
-			csr1.field.Bss0Key0CipherAlg = CipherAlg;
-		else if (KeyIdx == 1)
-			csr1.field.Bss0Key1CipherAlg = CipherAlg;
-		else if (KeyIdx == 2)
-			csr1.field.Bss0Key2CipherAlg = CipherAlg;
-		else
-			csr1.field.Bss0Key3CipherAlg = CipherAlg;
-	}
-	else
-	{
-		if (KeyIdx == 0)
-			csr1.field.Bss1Key0CipherAlg = CipherAlg;
-		else if (KeyIdx == 1)
-			csr1.field.Bss1Key1CipherAlg = CipherAlg;
-		else if (KeyIdx == 2)
-			csr1.field.Bss1Key2CipherAlg = CipherAlg;
-		else
-			csr1.field.Bss1Key3CipherAlg = CipherAlg;
-	}
-	DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
-	RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
-
-}
-
-//	IRQL = DISPATCH_LEVEL
-VOID AsicRemoveSharedKeyEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR		 BssIndex,
-	IN UCHAR		 KeyIdx)
-{
-	//ULONG SecCsr0;
-	SHAREDKEY_MODE_STRUC csr1;
-
-	DBGPRINT(RT_DEBUG_TRACE,("AsicRemoveSharedKeyEntry: #%d \n", BssIndex*4 + KeyIdx));
-
-	RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
-	if ((BssIndex%2) == 0)
-	{
-		if (KeyIdx == 0)
-			csr1.field.Bss0Key0CipherAlg = 0;
-		else if (KeyIdx == 1)
-			csr1.field.Bss0Key1CipherAlg = 0;
-		else if (KeyIdx == 2)
-			csr1.field.Bss0Key2CipherAlg = 0;
-		else
-			csr1.field.Bss0Key3CipherAlg = 0;
-	}
-	else
-	{
-		if (KeyIdx == 0)
-			csr1.field.Bss1Key0CipherAlg = 0;
-		else if (KeyIdx == 1)
-			csr1.field.Bss1Key1CipherAlg = 0;
-		else if (KeyIdx == 2)
-			csr1.field.Bss1Key2CipherAlg = 0;
-		else
-			csr1.field.Bss1Key3CipherAlg = 0;
-	}
-	DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
-	RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
-	ASSERT(BssIndex < 4);
-	ASSERT(KeyIdx < 4);
-
-}
-
-
-VOID AsicUpdateWCIDAttribute(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT		WCID,
-	IN UCHAR		BssIndex,
-	IN UCHAR        CipherAlg,
-	IN BOOLEAN		bUsePairewiseKeyTable)
-{
-	ULONG   WCIDAttri = 0, offset;
-
-	//
-	// Update WCID attribute.
-	// Only TxKey could update WCID attribute.
-	//
-	offset = MAC_WCID_ATTRIBUTE_BASE + (WCID * HW_WCID_ATTRI_SIZE);
-	WCIDAttri = (BssIndex << 4) | (CipherAlg << 1) | (bUsePairewiseKeyTable);
-	RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
-}
-
-VOID AsicUpdateWCIDIVEIV(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT		WCID,
-	IN ULONG        uIV,
-	IN ULONG        uEIV)
-{
-	ULONG	offset;
-
-	offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
-
-	RTMP_IO_WRITE32(pAd, offset, uIV);
-	RTMP_IO_WRITE32(pAd, offset + 4, uEIV);
-}
-
-VOID AsicUpdateRxWCIDTable(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT		WCID,
-	IN PUCHAR        pAddr)
-{
-	ULONG offset;
-	ULONG Addr;
-
-	offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE);
-	Addr = pAddr[0] + (pAddr[1] << 8) +(pAddr[2] << 16) +(pAddr[3] << 24);
-	RTMP_IO_WRITE32(pAd, offset, Addr);
-	Addr = pAddr[4] + (pAddr[5] << 8);
-	RTMP_IO_WRITE32(pAd, offset + 4, Addr);
-}
-
-
-/*
-    ========================================================================
-
-    Routine Description:
-        Set Cipher Key, Cipher algorithm, IV/EIV to Asic
-
-    Arguments:
-        pAd                     Pointer to our adapter
-        WCID                    WCID Entry number.
-        BssIndex                BSSID index, station or none multiple BSSID support
-                                this value should be 0.
-        KeyIdx                  This KeyIdx will set to IV's KeyID if bTxKey enabled
-        pCipherKey              Pointer to Cipher Key.
-        bUsePairewiseKeyTable   TRUE means saved the key in SharedKey table,
-                                otherwise PairewiseKey table
-        bTxKey                  This is the transmit key if enabled.
-
-    Return Value:
-        None
-
-    Note:
-        This routine will set the relative key stuff to Asic including WCID attribute,
-        Cipher Key, Cipher algorithm and IV/EIV.
-
-        IV/EIV will be update if this CipherKey is the transmission key because
-        ASIC will base on IV's KeyID value to select Cipher Key.
-
-        If bTxKey sets to FALSE, this is not the TX key, but it could be
-        RX key
-
-	For AP mode bTxKey must be always set to TRUE.
-    ========================================================================
-*/
-VOID AsicAddKeyEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT		WCID,
-	IN UCHAR		BssIndex,
-	IN UCHAR		KeyIdx,
-	IN PCIPHER_KEY	pCipherKey,
-	IN BOOLEAN		bUsePairewiseKeyTable,
-	IN BOOLEAN		bTxKey)
-{
-	ULONG	offset;
-//	ULONG   WCIDAttri = 0;
-	UCHAR	IV4 = 0;
-	PUCHAR		pKey = pCipherKey->Key;
-//	ULONG		KeyLen = pCipherKey->KeyLen;
-	PUCHAR		pTxMic = pCipherKey->TxMic;
-	PUCHAR		pRxMic = pCipherKey->RxMic;
-	PUCHAR		pTxtsc = pCipherKey->TxTsc;
-	UCHAR		CipherAlg = pCipherKey->CipherAlg;
-	SHAREDKEY_MODE_STRUC csr1;
-#ifdef RTMP_MAC_PCI
-	UCHAR		i;
-#endif // RTMP_MAC_PCI //
-
-//	ASSERT(KeyLen <= MAX_LEN_OF_PEER_KEY);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
-	//
-	// 1.) decide key table offset
-	//
-	if (bUsePairewiseKeyTable)
-		offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
-	else
-		offset = SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE;
-
-	//
-	// 2.) Set Key to Asic
-	//
-	//for (i = 0; i < KeyLen; i++)
-#ifdef RTMP_MAC_PCI
-	for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++)
-	{
-		RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
-	}
-	offset += MAX_LEN_OF_PEER_KEY;
-
-	//
-	// 3.) Set MIC key if available
-	//
-	if (pTxMic)
-	{
-		for (i = 0; i < 8; i++)
-		{
-			RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
-		}
-	}
-	offset += LEN_TKIP_TXMICK;
-
-	if (pRxMic)
-	{
-		for (i = 0; i < 8; i++)
-		{
-			RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
-		}
-	}
-#endif // RTMP_MAC_PCI //
-
-
-	//
-	// 4.) Modify IV/EIV if needs
-	//     This will force Asic to use this key ID by setting IV.
-	//
-	if (bTxKey)
-	{
-#ifdef RTMP_MAC_PCI
-		offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
-		//
-		// Write IV
-		//
-		RTMP_IO_WRITE8(pAd, offset, pTxtsc[1]);
-		RTMP_IO_WRITE8(pAd, offset + 1, ((pTxtsc[1] | 0x20) & 0x7f));
-		RTMP_IO_WRITE8(pAd, offset + 2, pTxtsc[0]);
-
-		IV4 = (KeyIdx << 6);
-		if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
-			IV4 |= 0x20;  // turn on extension bit means EIV existence
-
-		RTMP_IO_WRITE8(pAd, offset + 3, IV4);
-
-		//
-		// Write EIV
-		//
-		offset += 4;
-		for (i = 0; i < 4; i++)
-		{
-			RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]);
-		}
-#endif // RTMP_MAC_PCI //
-
-		AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, bUsePairewiseKeyTable);
-	}
-
-	if (!bUsePairewiseKeyTable)
-	{
-		//
-		// Only update the shared key security mode
-		//
-		RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), &csr1.word);
-		if ((BssIndex % 2) == 0)
-		{
-			if (KeyIdx == 0)
-				csr1.field.Bss0Key0CipherAlg = CipherAlg;
-			else if (KeyIdx == 1)
-				csr1.field.Bss0Key1CipherAlg = CipherAlg;
-			else if (KeyIdx == 2)
-				csr1.field.Bss0Key2CipherAlg = CipherAlg;
-			else
-				csr1.field.Bss0Key3CipherAlg = CipherAlg;
-		}
-		else
-		{
-			if (KeyIdx == 0)
-				csr1.field.Bss1Key0CipherAlg = CipherAlg;
-			else if (KeyIdx == 1)
-				csr1.field.Bss1Key1CipherAlg = CipherAlg;
-			else if (KeyIdx == 2)
-				csr1.field.Bss1Key2CipherAlg = CipherAlg;
-			else
-				csr1.field.Bss1Key3CipherAlg = CipherAlg;
-		}
-		RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), csr1.word);
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n"));
-}
-
-
-/*
-	========================================================================
-	Description:
-		Add Pair-wise key material into ASIC.
-		Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
-
-    Return:
-	========================================================================
-*/
-VOID AsicAddPairwiseKeyEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR        pAddr,
-	IN UCHAR		WCID,
-	IN CIPHER_KEY		 *pCipherKey)
-{
-	INT i;
-	ULONG		offset;
-	PUCHAR		 pKey = pCipherKey->Key;
-	PUCHAR		 pTxMic = pCipherKey->TxMic;
-	PUCHAR		 pRxMic = pCipherKey->RxMic;
-#ifdef DBG
-	UCHAR		CipherAlg = pCipherKey->CipherAlg;
-#endif // DBG //
-
-	// EKEY
-	offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
-#ifdef RTMP_MAC_PCI
-	for (i=0; i<MAX_LEN_OF_PEER_KEY; i++)
-	{
-		RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
-	}
-#endif // RTMP_MAC_PCI //
-	for (i=0; i<MAX_LEN_OF_PEER_KEY; i+=4)
-	{
-		UINT32 Value;
-		RTMP_IO_READ32(pAd, offset + i, &Value);
-	}
-
-	offset += MAX_LEN_OF_PEER_KEY;
-
-	//  MIC KEY
-	if (pTxMic)
-	{
-#ifdef RTMP_MAC_PCI
-		for (i=0; i<8; i++)
-		{
-			RTMP_IO_WRITE8(pAd, offset+i, pTxMic[i]);
-		}
-#endif // RTMP_MAC_PCI //
-	}
-	offset += 8;
-	if (pRxMic)
-	{
-#ifdef RTMP_MAC_PCI
-		for (i=0; i<8; i++)
-		{
-			RTMP_IO_WRITE8(pAd, offset+i, pRxMic[i]);
-		}
-#endif // RTMP_MAC_PCI //
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID, CipherName[CipherAlg]));
-	DBGPRINT(RT_DEBUG_TRACE,("	Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-		pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15]));
-	if (pRxMic)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("	Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-			pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
-	}
-	if (pTxMic)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("	Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-			pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
-	}
-}
-/*
-	========================================================================
-	Description:
-		Remove Pair-wise key material from ASIC.
-
-    Return:
-	========================================================================
-*/
-VOID AsicRemovePairwiseKeyEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR		 BssIdx,
-	IN UCHAR		 Wcid)
-{
-	ULONG		WCIDAttri;
-	USHORT		offset;
-
-	// re-set the entry's WCID attribute as OPEN-NONE.
-	offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
-	WCIDAttri = (BssIdx<<4) | PAIRWISEKEYTABLE;
-	RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
-}
-
-BOOLEAN AsicSendCommandToMcu(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR		 Command,
-	IN UCHAR		 Token,
-	IN UCHAR		 Arg0,
-	IN UCHAR		 Arg1)
-{
-
-
-	if (pAd->chipOps.sendCommandToMcu)
-		pAd->chipOps.sendCommandToMcu(pAd, Command, Token, Arg0, Arg1);
-
-	return TRUE;
-}
-
-
-VOID AsicSetRxAnt(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			Ant)
-{
-#ifdef RT33xx
-	RT33xxSetRxAnt(pAd, Ant);
-#else
-#ifdef RT30xx
-	/* RT3572 ATE need not to do this. */
-	RT30xxSetRxAnt(pAd, Ant);
-#endif // RT30xx //
-#endif // RT33xx //
-}
-
-
-VOID AsicTurnOffRFClk(
-	IN PRTMP_ADAPTER pAd,
-	IN	UCHAR		Channel)
-{
-	if (pAd->chipOps.AsicRfTurnOff)
-	{
-		pAd->chipOps.AsicRfTurnOff(pAd);
-	}
-	else
-	{
-		// RF R2 bit 18 = 0
-		UINT32			R1 = 0, R2 = 0, R3 = 0;
-		UCHAR			index;
-		RTMP_RF_REGS	*RFRegTable;
-
-		RFRegTable = RF2850RegTable;
-
-		switch (pAd->RfIcType)
-		{
-			case RFIC_2820:
-			case RFIC_2850:
-			case RFIC_2720:
-			case RFIC_2750:
-
-				for (index = 0; index < NUM_OF_2850_CHNL; index++)
-				{
-					if (Channel == RFRegTable[index].Channel)
-					{
-						R1 = RFRegTable[index].R1 & 0xffffdfff;
-						R2 = RFRegTable[index].R2 & 0xfffbffff;
-						R3 = RFRegTable[index].R3 & 0xfff3ffff;
-
-						RTMP_RF_IO_WRITE32(pAd, R1);
-						RTMP_RF_IO_WRITE32(pAd, R2);
-
-						// Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0.
-						// Set RF R2 bit18=0, R3 bit[18:19]=0
-						//if (pAd->StaCfg.bRadio == FALSE)
-						if (1)
-						{
-							RTMP_RF_IO_WRITE32(pAd, R3);
-
-							DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x,  R3 = 0x%08x \n",
-								Channel, pAd->RfIcType, R2, R3));
-						}
-						else
-							DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
-								Channel, pAd->RfIcType, R2));
-						break;
-					}
-				}
-				break;
-
-			default:
-				break;
-		}
-	}
-}
-
-
-VOID AsicTurnOnRFClk(
-	IN PRTMP_ADAPTER pAd,
-	IN	UCHAR			Channel)
-{
-	// RF R2 bit 18 = 0
-	UINT32			R1 = 0, R2 = 0, R3 = 0;
-	UCHAR			index;
-	RTMP_RF_REGS	*RFRegTable;
-
-#ifdef PCIE_PS_SUPPORT
-	// The RF programming sequence is difference between 3xxx and 2xxx
-	if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)))
-	{
-		return;
-	}
-#endif // PCIE_PS_SUPPORT //
-
-	RFRegTable = RF2850RegTable;
-
-	switch (pAd->RfIcType)
-	{
-		case RFIC_2820:
-		case RFIC_2850:
-		case RFIC_2720:
-		case RFIC_2750:
-
-			for (index = 0; index < NUM_OF_2850_CHNL; index++)
-			{
-				if (Channel == RFRegTable[index].Channel)
-				{
-					R3 = pAd->LatchRfRegs.R3;
-					R3 &= 0xfff3ffff;
-					R3 |= 0x00080000;
-					RTMP_RF_IO_WRITE32(pAd, R3);
-
-					R1 = RFRegTable[index].R1;
-					RTMP_RF_IO_WRITE32(pAd, R1);
-
-					R2 = RFRegTable[index].R2;
-					if (pAd->Antenna.field.TxPath == 1)
-					{
-						R2 |= 0x4000;	// If TXpath is 1, bit 14 = 1;
-					}
-
-					if (pAd->Antenna.field.RxPath == 2)
-					{
-						R2 |= 0x40;	// write 1 to off Rxpath.
-					}
-					else if (pAd->Antenna.field.RxPath == 1)
-					{
-						R2 |= 0x20040;	// write 1 to off RxPath
-					}
-					RTMP_RF_IO_WRITE32(pAd, R2);
-
-					break;
-				}
-			}
-			break;
-
-		default:
-			break;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n",
-		Channel,
-		pAd->RfIcType,
-		R2));
-}
diff --git a/drivers/staging/rt3090/common/cmm_cfg.c b/drivers/staging/rt3090/common/cmm_cfg.c
deleted file mode 100644
index d8be979..0000000
--- a/drivers/staging/rt3090/common/cmm_cfg.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	cmm_cfg.c
-
-    Abstract:
-    Ralink WiFi Driver configuration related subroutines
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
-*/
-
-#include "../rt_config.h"
-
-
-char* GetPhyMode(
-	int Mode)
-{
-	switch(Mode)
-	{
-		case MODE_CCK:
-			return "CCK";
-
-		case MODE_OFDM:
-			return "OFDM";
-#ifdef DOT11_N_SUPPORT
-		case MODE_HTMIX:
-			return "HTMIX";
-
-		case MODE_HTGREENFIELD:
-			return "GREEN";
-#endif // DOT11_N_SUPPORT //
-		default:
-			return "N/A";
-	}
-}
-
-
-char* GetBW(
-	int BW)
-{
-	switch(BW)
-	{
-		case BW_10:
-			return "10M";
-
-		case BW_20:
-			return "20M";
-#ifdef DOT11_N_SUPPORT
-		case BW_40:
-			return "40M";
-#endif // DOT11_N_SUPPORT //
-		default:
-			return "N/A";
-	}
-}
-
-
-/*
-    ==========================================================================
-    Description:
-        Set Country Region to pAd->CommonCfg.CountryRegion.
-        This command will not work, if the field of CountryRegion in eeprom is programmed.
-
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT RT_CfgSetCountryRegion(
-	IN PRTMP_ADAPTER	pAd,
-	IN PSTRING			arg,
-	IN INT				band)
-{
-	LONG region, regionMax;
-	UCHAR *pCountryRegion;
-
-	region = simple_strtol(arg, 0, 10);
-
-	if (band == BAND_24G)
-	{
-		pCountryRegion = &pAd->CommonCfg.CountryRegion;
-		regionMax = REGION_MAXIMUM_BG_BAND;
-	}
-	else
-	{
-		pCountryRegion = &pAd->CommonCfg.CountryRegionForABand;
-		regionMax = REGION_MAXIMUM_A_BAND;
-	}
-
-	// TODO: Is it neccesay for following check???
-	// Country can be set only when EEPROM not programmed
-	if (*pCountryRegion & 0x80)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("CfgSetCountryRegion():CountryRegion in eeprom was programmed\n"));
-		return FALSE;
-	}
-
-	if((region >= 0) && (region <= REGION_MAXIMUM_BG_BAND))
-	{
-		*pCountryRegion= (UCHAR) region;
-	}
-	else if ((region == REGION_31_BG_BAND) && (band == BAND_24G))
-	{
-		*pCountryRegion = (UCHAR) region;
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("CfgSetCountryRegion():region(%ld) out of range!\n", region));
-		return FALSE;
-	}
-
-	return TRUE;
-
-}
-
-
-/*
-    ==========================================================================
-    Description:
-        Set Wireless Mode
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT RT_CfgSetWirelessMode(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	INT		MaxPhyMode = PHY_11G;
-	LONG	WirelessMode;
-
-#ifdef DOT11_N_SUPPORT
-	MaxPhyMode = PHY_11N_5G;
-#endif // DOT11_N_SUPPORT //
-
-	WirelessMode = simple_strtol(arg, 0, 10);
-	if (WirelessMode <= MaxPhyMode)
-	{
-		pAd->CommonCfg.PhyMode = WirelessMode;
-		pAd->CommonCfg.DesiredPhyMode = WirelessMode;
-		return TRUE;
-	}
-
-	return FALSE;
-
-}
-
-
-INT RT_CfgSetShortSlot(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	LONG ShortSlot;
-
-	ShortSlot = simple_strtol(arg, 0, 10);
-
-	if (ShortSlot == 1)
-		pAd->CommonCfg.bUseShortSlotTime = TRUE;
-	else if (ShortSlot == 0)
-		pAd->CommonCfg.bUseShortSlotTime = FALSE;
-	else
-		return FALSE;  //Invalid argument
-
-	return TRUE;
-}
-
-
-/*
-    ==========================================================================
-    Description:
-        Set WEP KEY base on KeyIdx
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	RT_CfgSetWepKey(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			keyString,
-	IN	CIPHER_KEY		*pSharedKey,
-	IN	INT				keyIdx)
-{
-	INT				KeyLen;
-	INT				i;
-	UCHAR			CipherAlg = CIPHER_NONE;
-	BOOLEAN			bKeyIsHex = FALSE;
-
-	// TODO: Shall we do memset for the original key info??
-	memset(pSharedKey, 0, sizeof(CIPHER_KEY));
-	KeyLen = strlen(keyString);
-	switch (KeyLen)
-	{
-		case 5: //wep 40 Ascii type
-		case 13: //wep 104 Ascii type
-			bKeyIsHex = FALSE;
-			pSharedKey->KeyLen = KeyLen;
-			NdisMoveMemory(pSharedKey->Key, keyString, KeyLen);
-			break;
-
-		case 10: //wep 40 Hex type
-		case 26: //wep 104 Hex type
-			for(i=0; i < KeyLen; i++)
-			{
-				if( !isxdigit(*(keyString+i)) )
-					return FALSE;  //Not Hex value;
-			}
-			bKeyIsHex = TRUE;
-			pSharedKey->KeyLen = KeyLen/2 ;
-			AtoH(keyString, pSharedKey->Key, pSharedKey->KeyLen);
-			break;
-
-		default: //Invalid argument
-			DBGPRINT(RT_DEBUG_TRACE, ("RT_CfgSetWepKey(keyIdx=%d):Invalid argument (arg=%s)\n", keyIdx, keyString));
-			return FALSE;
-	}
-
-	pSharedKey->CipherAlg = ((KeyLen % 5) ? CIPHER_WEP128 : CIPHER_WEP64);
-	DBGPRINT(RT_DEBUG_TRACE, ("RT_CfgSetWepKey:(KeyIdx=%d,type=%s, Alg=%s)\n",
-						keyIdx, (bKeyIsHex == FALSE ? "Ascii" : "Hex"), CipherName[CipherAlg]));
-
-	return TRUE;
-}
-
-
-/*
-    ==========================================================================
-    Description:
-        Set WPA PSK key
-
-    Arguments:
-        pAdapter	Pointer to our adapter
-        keyString	WPA pre-shared key string
-        pHashStr	String used for password hash function
-        hashStrLen	Lenght of the hash string
-        pPMKBuf		Output buffer of WPAPSK key
-
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT RT_CfgSetWPAPSKKey(
-	IN RTMP_ADAPTER	*pAd,
-	IN PSTRING		keyString,
-	IN UCHAR		*pHashStr,
-	IN INT			hashStrLen,
-	OUT PUCHAR		pPMKBuf)
-{
-	int keyLen;
-	UCHAR keyMaterial[40];
-
-	keyLen = strlen(keyString);
-	if ((keyLen < 8) || (keyLen > 64))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("WPAPSK Key length(%d) error, required 8 ~ 64 characters!(keyStr=%s)\n",
-									keyLen, keyString));
-		return FALSE;
-	}
-
-	memset(pPMKBuf, 0, 32);
-	if (keyLen == 64)
-	{
-	    AtoH(keyString, pPMKBuf, 32);
-	}
-	else
-	{
-	    PasswordHash(keyString, pHashStr, hashStrLen, keyMaterial);
-	    NdisMoveMemory(pPMKBuf, keyMaterial, 32);
-	}
-
-	return TRUE;
-}
diff --git a/drivers/staging/rt3090/common/cmm_data.c b/drivers/staging/rt3090/common/cmm_data.c
deleted file mode 100644
index 6340071..0000000
--- a/drivers/staging/rt3090/common/cmm_data.c
+++ /dev/null
@@ -1,2763 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	cmm_data.c
-
-    Abstract:
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
- */
-
-#include "../rt_config.h"
-
-
-UCHAR	SNAP_802_1H[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
-UCHAR	SNAP_BRIDGE_TUNNEL[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};
-// Add Cisco Aironet SNAP heade for CCX2 support
-UCHAR	SNAP_AIRONET[] = {0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x00};
-UCHAR	CKIP_LLC_SNAP[] = {0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02};
-UCHAR	EAPOL_LLC_SNAP[]= {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e};
-UCHAR	EAPOL[] = {0x88, 0x8e};
-UCHAR   TPID[] = {0x81, 0x00}; /* VLAN related */
-
-UCHAR	IPX[] = {0x81, 0x37};
-UCHAR	APPLE_TALK[] = {0x80, 0xf3};
-UCHAR	RateIdToPlcpSignal[12] = {
-	 0, /* RATE_1 */	1, /* RATE_2 */		2, /* RATE_5_5 */	3, /* RATE_11 */	// see BBP spec
-	11, /* RATE_6 */   15, /* RATE_9 */    10, /* RATE_12 */   14, /* RATE_18 */	// see IEEE802.11a-1999 p.14
-	 9, /* RATE_24 */  13, /* RATE_36 */	8, /* RATE_48 */   12  /* RATE_54 */ }; // see IEEE802.11a-1999 p.14
-
-UCHAR	 OfdmSignalToRateId[16] = {
-	RATE_54,  RATE_54,	RATE_54,  RATE_54,	// OFDM PLCP Signal = 0,  1,  2,  3 respectively
-	RATE_54,  RATE_54,	RATE_54,  RATE_54,	// OFDM PLCP Signal = 4,  5,  6,  7 respectively
-	RATE_48,  RATE_24,	RATE_12,  RATE_6,	// OFDM PLCP Signal = 8,  9,  10, 11 respectively
-	RATE_54,  RATE_36,	RATE_18,  RATE_9,	// OFDM PLCP Signal = 12, 13, 14, 15 respectively
-};
-
-UCHAR	 OfdmRateToRxwiMCS[12] = {
-	0,  0,	0,  0,
-	0,  1,	2,  3,	// OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3
-	4,  5,	6,  7,	// OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7
-};
-UCHAR	 RxwiMCSToOfdmRate[12] = {
-	RATE_6,  RATE_9,	RATE_12,  RATE_18,
-	RATE_24,  RATE_36,	RATE_48,  RATE_54,	// OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3
-	4,  5,	6,  7,	// OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7
-};
-
-char*   MCSToMbps[] = {"1Mbps","2Mbps","5.5Mbps","11Mbps","06Mbps","09Mbps","12Mbps","18Mbps","24Mbps","36Mbps","48Mbps","54Mbps","MM-0","MM-1","MM-2","MM-3","MM-4","MM-5","MM-6","MM-7","MM-8","MM-9","MM-10","MM-11","MM-12","MM-13","MM-14","MM-15","MM-32","ee1","ee2","ee3"};
-
-UCHAR default_cwmin[]={CW_MIN_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1, CW_MIN_IN_BITS-2};
-//UCHAR default_cwmax[]={CW_MAX_IN_BITS, CW_MAX_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1};
-UCHAR default_sta_aifsn[]={3,7,2,2};
-
-UCHAR MapUserPriorityToAccessCategory[8] = {QID_AC_BE, QID_AC_BK, QID_AC_BK, QID_AC_BE, QID_AC_VI, QID_AC_VI, QID_AC_VO, QID_AC_VO};
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		API for MLME to transmit management frame to AP (BSS Mode)
-	or station (IBSS Mode)
-
-	Arguments:
-		pAd Pointer to our adapter
-		pData		Pointer to the outgoing 802.11 frame
-		Length		Size of outgoing management frame
-
-	Return Value:
-		NDIS_STATUS_FAILURE
-		NDIS_STATUS_PENDING
-		NDIS_STATUS_SUCCESS
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-NDIS_STATUS MiniportMMRequest(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			QueIdx,
-	IN	PUCHAR			pData,
-	IN	UINT			Length)
-{
-	PNDIS_PACKET	pPacket;
-	NDIS_STATUS	Status = NDIS_STATUS_SUCCESS;
-	ULONG			FreeNum;
-	UCHAR			rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
-#ifdef RTMP_MAC_PCI
-	unsigned long	IrqFlags = 0;
-	UCHAR			IrqState;
-#endif // RTMP_MAC_PCI //
-	BOOLEAN			bUseDataQ = FALSE;
-	int			retryCnt = 0;
-
-	ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
-
-	if ((QueIdx & MGMT_USE_QUEUE_FLAG) == MGMT_USE_QUEUE_FLAG)
-	{
-		bUseDataQ = TRUE;
-		QueIdx &= (~MGMT_USE_QUEUE_FLAG);
-	}
-
-#ifdef RTMP_MAC_PCI
-	// 2860C use Tx Ring
-	IrqState = pAd->irq_disabled;
-	if (pAd->MACVersion == 0x28600100)
-	{
-		QueIdx = (bUseDataQ ==TRUE ? QueIdx : 3);
-		bUseDataQ = TRUE;
-	}
-	if (bUseDataQ && (!IrqState))
-		RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-#endif // RTMP_MAC_PCI //
-
-	do
-	{
-		// Reset is in progress, stop immediately
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
-			 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
-			 !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
-		{
-			Status = NDIS_STATUS_FAILURE;
-			break;
-		}
-
-		// Check Free priority queue
-		// Since we use PBF Queue2 for management frame.  Its corresponding DMA ring should be using TxRing.
-#ifdef RTMP_MAC_PCI
-		if (bUseDataQ)
-		{
-			retryCnt = MAX_DATAMM_RETRY;
-			// free Tx(QueIdx) resources
-			RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);
-			FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
-		}
-		else
-#endif // RTMP_MAC_PCI //
-		{
-			FreeNum = GET_MGMTRING_FREENO(pAd);
-		}
-
-		if ((FreeNum > 0))
-		{
-			// We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870
-			NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE));
-			Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE), pData, Length);
-			if (Status != NDIS_STATUS_SUCCESS)
-			{
-				DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
-				break;
-			}
-
-			//pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
-			//pAd->CommonCfg.MlmeRate = RATE_2;
-
-
-#ifdef RTMP_MAC_PCI
-			if (bUseDataQ)
-			{
-				Status = MlmeDataHardTransmit(pAd, QueIdx, pPacket);
-				retryCnt--;
-			}
-			else
-#endif // RTMP_MAC_PCI //
-				Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
-			if (Status == NDIS_STATUS_SUCCESS)
-				retryCnt = 0;
-			else
-				RTMPFreeNdisPacket(pAd, pPacket);
-		}
-		else
-		{
-			pAd->RalinkCounters.MgmtRingFullCount++;
-#ifdef RTMP_MAC_PCI
-			if (bUseDataQ)
-			{
-				retryCnt--;
-				DBGPRINT(RT_DEBUG_TRACE, ("retryCnt %d\n", retryCnt));
-				if (retryCnt == 0)
-				{
-					DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in DataRing, MgmtRingFullCount=%ld!\n",
-											QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
-				}
-			}
-#endif // RTMP_MAC_PCI //
-			DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n",
-										QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
-
-
-
-		}
-	} while (retryCnt > 0);
-
-
-#ifdef RTMP_MAC_PCI
-	if (bUseDataQ && (!IrqState))
-		RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-#endif // RTMP_MAC_PCI //
-
-	return Status;
-}
-
-
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Copy frame from waiting queue into relative ring buffer and set
-	appropriate ASIC register to kick hardware transmit function
-
-	Arguments:
-		pAd Pointer to our adapter
-		pBuffer		Pointer to	memory of outgoing frame
-		Length		Size of outgoing management frame
-
-	Return Value:
-		NDIS_STATUS_FAILURE
-		NDIS_STATUS_PENDING
-		NDIS_STATUS_SUCCESS
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-NDIS_STATUS MlmeHardTransmit(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			QueIdx,
-	IN	PNDIS_PACKET	pPacket)
-{
-	PACKET_INFO	PacketInfo;
-	PUCHAR			pSrcBufVA;
-	UINT			SrcBufLen;
-	PHEADER_802_11	pHeader_802_11;
-
-	if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
-#ifdef CARRIER_DETECTION_SUPPORT
-#endif // CARRIER_DETECTION_SUPPORT //
-		)
-	{
-		return NDIS_STATUS_FAILURE;
-	}
-
-	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
-	if (pSrcBufVA == NULL)
-		return NDIS_STATUS_FAILURE;
-
-	pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE);
-
-
-#ifdef RTMP_MAC_PCI
-	if ( pAd->MACVersion == 0x28600100 )
-		return MlmeHardTransmitTxRing(pAd,QueIdx,pPacket);
-	else
-#endif // RTMP_MAC_PCI //
-		return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
-
-}
-
-
-NDIS_STATUS MlmeHardTransmitMgmtRing(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR	QueIdx,
-	IN	PNDIS_PACKET	pPacket)
-{
-	PACKET_INFO	PacketInfo;
-	PUCHAR			pSrcBufVA;
-	UINT			SrcBufLen;
-	PHEADER_802_11	pHeader_802_11;
-	BOOLEAN			bAckRequired, bInsertTimestamp;
-	UCHAR			MlmeRate;
-	PTXWI_STRUC	pFirstTxWI;
-	MAC_TABLE_ENTRY	*pMacEntry = NULL;
-	UCHAR			PID;
-
-	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
-
-	// Make sure MGMT ring resource won't be used by other threads
-	RTMP_SEM_LOCK(&pAd->MgmtRingLock);
-	if (pSrcBufVA == NULL)
-	{
-		// The buffer shouldn't be NULL
-			RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
-		return NDIS_STATUS_FAILURE;
-	}
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		// outgoing frame always wakeup PHY to prevent frame lost
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-			AsicForceWakeup(pAd, TRUE);
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	pFirstTxWI = (PTXWI_STRUC)(pSrcBufVA +  TXINFO_SIZE);
-	pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); //TXWI_SIZE);
-
-	if (pHeader_802_11->Addr1[0] & 0x01)
-	{
-		MlmeRate = pAd->CommonCfg.BasicMlmeRate;
-	}
-	else
-	{
-		MlmeRate = pAd->CommonCfg.MlmeRate;
-	}
-
-	// Verify Mlme rate for a / g bands.
-	if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
-		MlmeRate = RATE_6;
-
-	if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
-		(pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
-	{
-		pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
-	}
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		// Fixed W52 with Activity scan issue in ABG_MIXED and ABGN_MIXED mode.
-		if (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED
-#ifdef DOT11_N_SUPPORT
-			|| pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED
-#endif // DOT11_N_SUPPORT //
-		)
-		{
-			if (pAd->LatchRfRegs.Channel > 14)
-				pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
-			else
-				pAd->CommonCfg.MlmeTransmit.field.MODE = 0;
-		}
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	//
-	// Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
-	// Snice it's been set to 0 while on MgtMacHeaderInit
-	// By the way this will cause frame to be send on PWR_SAVE failed.
-	//
-	pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE; // (pAd->StaCfg.Psm == PWR_SAVE);
-
-#ifdef CONFIG_STA_SUPPORT
-	//
-	// In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
-	// Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
-//	if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL))
-	{
-		if ((pHeader_802_11->FC.SubType == SUBTYPE_ACTION) ||
-			((pHeader_802_11->FC.Type == BTYPE_DATA) &&
-			((pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL) ||
-			(pHeader_802_11->FC.SubType == SUBTYPE_NULL_FUNC))))
-		{
-			if (pAd->StaCfg.Psm == PWR_SAVE)
-				pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
-			else
-				pHeader_802_11->FC.PwrMgmt = pAd->CommonCfg.bAPSDForcePowerSave;
-		}
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-
-
-
-
-	bInsertTimestamp = FALSE;
-	if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
-	{
-#ifdef CONFIG_STA_SUPPORT
-		//Set PM bit in ps-poll, to fix WLK 1.2  PowerSaveMode_ext failure issue.
-		if ((pAd->OpMode == OPMODE_STA) && (pHeader_802_11->FC.SubType == SUBTYPE_PS_POLL))
-		{
-			pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
-		}
-#endif // CONFIG_STA_SUPPORT //
-		bAckRequired = FALSE;
-	}
-	else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
-	{
-		//pAd->Sequence++;
-		//pHeader_802_11->Sequence = pAd->Sequence;
-
-		if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
-		{
-			bAckRequired = FALSE;
-			pHeader_802_11->Duration = 0;
-		}
-		else
-		{
-			bAckRequired = TRUE;
-			pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
-			if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP) && (pHeader_802_11->FC.Type == BTYPE_MGMT))
-			{
-				bInsertTimestamp = TRUE;
-				bAckRequired = FALSE; // Disable ACK to prevent retry 0x1f for Probe Response
-			}
-			else if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) && (pHeader_802_11->FC.Type == BTYPE_MGMT))
-			{
-				bAckRequired = FALSE; // Disable ACK to prevent retry 0x1f for Probe Request
-			}
-		}
-	}
-
-	pHeader_802_11->Sequence = pAd->Sequence++;
-	if (pAd->Sequence >0xfff)
-		pAd->Sequence = 0;
-
-	// Before radar detection done, mgmt frame can not be sent but probe req
-	// Because we need to use probe req to trigger driver to send probe req in passive scan
-	if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
-		&& (pAd->CommonCfg.bIEEE80211H == 1)
-		&& (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
-//		if (!IrqState)
-		RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
-		return (NDIS_STATUS_FAILURE);
-	}
-
-#ifdef RT_BIG_ENDIAN
-	RTMPFrameEndianChange(pAd, (PUCHAR)pHeader_802_11, DIR_WRITE, FALSE);
-#endif
-
-	//
-	// fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
-	// should always has only one physical buffer, and the whole frame size equals
-	// to the first scatter buffer size
-	//
-
-	// Initialize TX Descriptor
-	// For inter-frame gap, the number is for this frame and next frame
-	// For MLME rate, we will fix as 2Mb to match other vendor's implement
-//	pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
-
-// management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
-	PID = PID_MGMT;
-
-
-	if (pMacEntry == NULL)
-	{
-		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
-		0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID, 0,  (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
-	}
-	else
-	{
-		/* dont use low rate to send QoS Null data frame */
-		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
-					bInsertTimestamp, FALSE, bAckRequired, FALSE,
-					0, pMacEntry->Aid, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE),
-					pMacEntry->MaxHTPhyMode.field.MCS, 0,
-					(UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
-					IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
-	}
-
-#ifdef RT_BIG_ENDIAN
-	RTMPWIEndianChange((PUCHAR)pFirstTxWI, TYPE_TXWI);
-#endif
-
-	// Now do hardware-depened kick out.
-	HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen);
-
-	// Make sure to release MGMT ring resource
-//	if (!IrqState)
-		RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-/********************************************************************************
-
-	New DeQueue Procedures.
-
- ********************************************************************************/
-
-#define DEQUEUE_LOCK(lock, bIntContext, IrqFlags)				\
-			do{													\
-				if (bIntContext == FALSE)						\
-				RTMP_IRQ_LOCK((lock), IrqFlags);		\
-			}while(0)
-
-#define DEQUEUE_UNLOCK(lock, bIntContext, IrqFlags)				\
-			do{													\
-				if (bIntContext == FALSE)						\
-					RTMP_IRQ_UNLOCK((lock), IrqFlags);	\
-			}while(0)
-
-
-
-
-/*
-	========================================================================
-	Tx Path design algorithm:
-		Basically, we divide the packets into four types, Broadcast/Multicast, 11N Rate(AMPDU, AMSDU, Normal), B/G Rate(ARALINK, Normal),
-		Specific Packet Type. Following show the classification rule and policy for each kinds of packets.
-				Classification Rule=>
-					Multicast: (*addr1 & 0x01) == 0x01
-					Specific : bDHCPFrame, bARPFrame, bEAPOLFrame, etc.
-					11N Rate : If peer support HT
-								(1).AMPDU  -- If TXBA is negotiated.
-								(2).AMSDU  -- If AMSDU is capable for both peer and ourself.
-											*). AMSDU can embedded in a AMPDU, but now we didn't support it.
-								(3).Normal -- Other packets which send as 11n rate.
-
-					B/G Rate : If peer is b/g only.
-								(1).ARALINK-- If both of peer/us supprot Ralink proprietary Aggregation and the TxRate is large than RATE_6
-								(2).Normal -- Other packets which send as b/g rate.
-					Fragment:
-								The packet must be unicast, NOT A-RALINK, NOT A-MSDU, NOT 11n, then can consider about fragment.
-
-				Classified Packet Handle Rule=>
-					Multicast:
-								No ACK,			//pTxBlk->bAckRequired = FALSE;
-								No WMM,			//pTxBlk->bWMM = FALSE;
-								No piggyback,   //pTxBlk->bPiggyBack = FALSE;
-								Force LowRate,  //pTxBlk->bForceLowRate = TRUE;
-					Specific :	Basically, for specific packet, we should handle it specifically, but now all specific packets are use
-									the same policy to handle it.
-								Force LowRate,  //pTxBlk->bForceLowRate = TRUE;
-
-					11N Rate :
-								No piggyback,	//pTxBlk->bPiggyBack = FALSE;
-
-								(1).AMSDU
-									pTxBlk->bWMM = TRUE;
-								(2).AMPDU
-									pTxBlk->bWMM = TRUE;
-								(3).Normal
-
-					B/G Rate :
-								(1).ARALINK
-
-								(2).Normal
-	========================================================================
-*/
-static UCHAR TxPktClassification(
-	IN RTMP_ADAPTER *pAd,
-	IN PNDIS_PACKET  pPacket)
-{
-	UCHAR			TxFrameType = TX_UNKOWN_FRAME;
-	UCHAR			Wcid;
-	MAC_TABLE_ENTRY	*pMacEntry = NULL;
-#ifdef DOT11_N_SUPPORT
-	BOOLEAN			bHTRate = FALSE;
-#endif // DOT11_N_SUPPORT //
-
-	Wcid = RTMP_GET_PACKET_WCID(pPacket);
-	if (Wcid == MCAST_WCID)
-	{	// Handle for RA is Broadcast/Multicast Address.
-		return TX_MCAST_FRAME;
-	}
-
-	// Handle for unicast packets
-	pMacEntry = &pAd->MacTab.Content[Wcid];
-	if (RTMP_GET_PACKET_LOWRATE(pPacket))
-	{	// It's a specific packet need to force low rate, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame
-		TxFrameType = TX_LEGACY_FRAME;
-	}
-#ifdef DOT11_N_SUPPORT
-	else if (IS_HT_RATE(pMacEntry))
-	{	// it's a 11n capable packet
-
-		// Depends on HTPhyMode to check if the peer support the HTRate transmission.
-		//	Currently didn't support A-MSDU embedded in A-MPDU
-		bHTRate = TRUE;
-		if (RTMP_GET_PACKET_MOREDATA(pPacket) || (pMacEntry->PsMode == PWR_SAVE))
-			TxFrameType = TX_LEGACY_FRAME;
-#ifdef UAPSD_AP_SUPPORT
-		else if (RTMP_GET_PACKET_EOSP(pPacket))
-			TxFrameType = TX_LEGACY_FRAME;
-#endif // UAPSD_AP_SUPPORT //
-		else if((pMacEntry->TXBAbitmap & (1<<(RTMP_GET_PACKET_UP(pPacket)))) != 0)
-			return TX_AMPDU_FRAME;
-		else if(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AMSDU_INUSED))
-			return TX_AMSDU_FRAME;
-		else
-			TxFrameType = TX_LEGACY_FRAME;
-	}
-#endif // DOT11_N_SUPPORT //
-	else
-	{	// it's a legacy b/g packet.
-		if ((CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE) && pAd->CommonCfg.bAggregationCapable) &&
-			(RTMP_GET_PACKET_TXRATE(pPacket) >= RATE_6) &&
-			(!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
-		{	// if peer support Ralink Aggregation, we use it.
-			TxFrameType = TX_RALINK_FRAME;
-		}
-		else
-		{
-			TxFrameType = TX_LEGACY_FRAME;
-		}
-	}
-
-	// Currently, our fragment only support when a unicast packet send as NOT-ARALINK, NOT-AMSDU and NOT-AMPDU.
-	if ((RTMP_GET_PACKET_FRAGMENTS(pPacket) > 1) && (TxFrameType == TX_LEGACY_FRAME))
-		TxFrameType = TX_FRAG_FRAME;
-
-	return TxFrameType;
-}
-
-
-BOOLEAN RTMP_FillTxBlkInfo(
-	IN RTMP_ADAPTER *pAd,
-	IN TX_BLK *pTxBlk)
-{
-	PACKET_INFO			PacketInfo;
-	PNDIS_PACKET		pPacket;
-	PMAC_TABLE_ENTRY	pMacEntry = NULL;
-
-	pPacket = pTxBlk->pPacket;
-	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
-
-	pTxBlk->Wcid				= RTMP_GET_PACKET_WCID(pPacket);
-	pTxBlk->apidx				= RTMP_GET_PACKET_IF(pPacket);
-	pTxBlk->UserPriority		= RTMP_GET_PACKET_UP(pPacket);
-	pTxBlk->FrameGap = IFS_HTTXOP;		// ASIC determine Frame Gap
-
-	if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pTxBlk->pPacket))
-		TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame);
-	else
-		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bClearEAPFrame);
-
-	// Default to clear this flag
-	TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bForceNonQoS);
-
-
-	if (pTxBlk->Wcid == MCAST_WCID)
-	{
-		pTxBlk->pMacEntry = NULL;
-		{
-#ifdef MCAST_RATE_SPECIFIC
-			PUCHAR pDA = GET_OS_PKT_DATAPTR(pPacket);
-			if (((*pDA & 0x01) == 0x01) && (*pDA != 0xff))
-				pTxBlk->pTransmit = &pAd->CommonCfg.MCastPhyMode;
-			else
-#endif // MCAST_RATE_SPECIFIC //
-				pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
-		}
-
-		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);	// AckRequired = FALSE, when broadcast packet in Adhoc mode.
-		//TX_BLK_SET_FLAG(pTxBlk, fTX_bForceLowRate);
-		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAllowFrag);
-		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
-		if (RTMP_GET_PACKET_MOREDATA(pPacket))
-		{
-			TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
-		}
-
-	}
-	else
-	{
-		pTxBlk->pMacEntry = &pAd->MacTab.Content[pTxBlk->Wcid];
-		pTxBlk->pTransmit = &pTxBlk->pMacEntry->HTPhyMode;
-
-		pMacEntry = pTxBlk->pMacEntry;
-
-
-		// For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK.
-		if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx] != NORMAL_ACK)
-			TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
-		else
-			TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired);
-
-#ifdef CONFIG_STA_SUPPORT
-		if ((pAd->OpMode == OPMODE_STA) &&
-			(ADHOC_ON(pAd)) &&
-			(RX_FILTER_TEST_FLAG(pAd, fRX_FILTER_ACCEPT_PROMISCUOUS)))
-		{
-			if(pAd->CommonCfg.PSPXlink)
-				TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
-		}
-#endif // CONFIG_STA_SUPPORT //
-
-		{
-
-#ifdef CONFIG_STA_SUPPORT
-			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-			{
-
-				// If support WMM, enable it.
-				if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
-					CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))
-					TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM);
-
-//				if (pAd->StaCfg.bAutoTxRateSwitch)
-//					TX_BLK_SET_FLAG(pTxBlk, fTX_AutoRateSwitch);
-			}
-#endif // CONFIG_STA_SUPPORT //
-		}
-
-		if (pTxBlk->TxFrameType == TX_LEGACY_FRAME)
-		{
-			if ( (RTMP_GET_PACKET_LOWRATE(pPacket)) ||
-                ((pAd->OpMode == OPMODE_AP) && (pMacEntry->MaxHTPhyMode.field.MODE == MODE_CCK) && (pMacEntry->MaxHTPhyMode.field.MCS == RATE_1)))
-			{	// Specific packet, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame, need force low rate.
-				pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
-#ifdef DOT11_N_SUPPORT
-				// Modify the WMM bit for ICV issue. If we have a packet with EOSP field need to set as 1, how to handle it???
-				if (IS_HT_STA(pTxBlk->pMacEntry) &&
-					(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET)) &&
-					((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RDG_CAPABLE)))
-				{
-					TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
-					TX_BLK_SET_FLAG(pTxBlk, fTX_bForceNonQoS);
-				}
-#endif // DOT11_N_SUPPORT //
-			}
-
-#ifdef DOT11_N_SUPPORT
-			if ( (IS_HT_RATE(pMacEntry) == FALSE) &&
-				(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE)))
-			{	// Currently piggy-back only support when peer is operate in b/g mode.
-				TX_BLK_SET_FLAG(pTxBlk, fTX_bPiggyBack);
-			}
-#endif // DOT11_N_SUPPORT //
-
-			if (RTMP_GET_PACKET_MOREDATA(pPacket))
-			{
-				TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
-			}
-#ifdef UAPSD_AP_SUPPORT
-			if (RTMP_GET_PACKET_EOSP(pPacket))
-			{
-				TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP);
-			}
-#endif // UAPSD_AP_SUPPORT //
-		}
-		else if (pTxBlk->TxFrameType == TX_FRAG_FRAME)
-		{
-			TX_BLK_SET_FLAG(pTxBlk, fTX_bAllowFrag);
-		}
-
-		pMacEntry->DebugTxCount++;
-	}
-
-	return TRUE;
-}
-
-
-BOOLEAN CanDoAggregateTransmit(
-	IN RTMP_ADAPTER *pAd,
-	IN NDIS_PACKET *pPacket,
-	IN TX_BLK		*pTxBlk)
-{
-
-	//DBGPRINT(RT_DEBUG_TRACE, ("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType));
-
-	if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID)
-		return FALSE;
-
-	if (RTMP_GET_PACKET_DHCP(pPacket) ||
-		RTMP_GET_PACKET_EAPOL(pPacket) ||
-		RTMP_GET_PACKET_WAI(pPacket))
-		return FALSE;
-
-	if ((pTxBlk->TxFrameType == TX_AMSDU_FRAME) &&
-		((pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))> (RX_BUFFER_AGGRESIZE - 100)))
-	{	// For AMSDU, allow the packets with total length < max-amsdu size
-		return FALSE;
-	}
-
-	if ((pTxBlk->TxFrameType == TX_RALINK_FRAME) &&
-		(pTxBlk->TxPacketList.Number == 2))
-	{	// For RALINK-Aggregation, allow two frames in one batch.
-		return FALSE;
-	}
-
-#ifdef CONFIG_STA_SUPPORT
-	if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) // must be unicast to AP
-		return TRUE;
-	else
-#endif // CONFIG_STA_SUPPORT //
-		return FALSE;
-
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		To do the enqueue operation and extract the first item of waiting
-		list. If a number of available shared memory segments could meet
-		the request of extracted item, the extracted item will be fragmented
-		into shared memory segments.
-
-	Arguments:
-		pAd Pointer to our adapter
-		pQueue		Pointer to Waiting Queue
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID RTMPDeQueuePacket(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  BOOLEAN         bIntContext,
-	IN  UCHAR			QIdx, /* BulkOutPipeId */
-	IN  UCHAR           Max_Tx_Packets)
-{
-	PQUEUE_ENTRY    pEntry = NULL;
-	PNDIS_PACKET	pPacket;
-	NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;
-	UCHAR           Count=0;
-	PQUEUE_HEADER   pQueue;
-	ULONG           FreeNumber[NUM_OF_TX_RING];
-	UCHAR			QueIdx, sQIdx, eQIdx;
-	unsigned long	IrqFlags = 0;
-	BOOLEAN			hasTxDesc = FALSE;
-	TX_BLK			TxBlk;
-	TX_BLK			*pTxBlk;
-
-#ifdef DBG_DIAGNOSE
-	BOOLEAN			firstRound;
-	RtmpDiagStruct	*pDiagStruct = &pAd->DiagStruct;
-#endif
-
-
-	if (QIdx == NUM_OF_TX_RING)
-	{
-		sQIdx = 0;
-		eQIdx = 3;	// 4 ACs, start from 0.
-	}
-	else
-	{
-		sQIdx = eQIdx = QIdx;
-	}
-
-	for (QueIdx=sQIdx; QueIdx <= eQIdx; QueIdx++)
-	{
-		Count=0;
-
-		RTMP_START_DEQUEUE(pAd, QueIdx, IrqFlags);
-
-#ifdef DBG_DIAGNOSE
-		firstRound = ((QueIdx == 0) ? TRUE : FALSE);
-#endif // DBG_DIAGNOSE //
-
-		while (1)
-		{
-			if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS |
-										fRTMP_ADAPTER_RADIO_OFF |
-										fRTMP_ADAPTER_RESET_IN_PROGRESS |
-										fRTMP_ADAPTER_HALT_IN_PROGRESS |
-										fRTMP_ADAPTER_NIC_NOT_EXIST))))
-			{
-				RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
-				return;
-			}
-
-			if (Count >= Max_Tx_Packets)
-				break;
-
-			DEQUEUE_LOCK(&pAd->irq_lock, bIntContext, IrqFlags);
-			if (&pAd->TxSwQueue[QueIdx] == NULL)
-			{
-#ifdef DBG_DIAGNOSE
-				if (firstRound == TRUE)
-					pDiagStruct->TxSWQueCnt[pDiagStruct->ArrayCurIdx][0]++;
-#endif // DBG_DIAGNOSE //
-				DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
-				break;
-			}
-
-#ifdef RTMP_MAC_PCI
-			FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
-
-#ifdef DBG_DIAGNOSE
-			if (firstRound == TRUE)
-			{
-				UCHAR	txDescNumLevel, txSwQNumLevel;
-
-				txDescNumLevel = (TX_RING_SIZE - FreeNumber[QueIdx]); // Number of occupied hw desc.
-				txDescNumLevel = ((txDescNumLevel <=15) ? txDescNumLevel : 15);
-				pDiagStruct->TxDescCnt[pDiagStruct->ArrayCurIdx][txDescNumLevel]++;
-
-				txSwQNumLevel = ((pAd->TxSwQueue[QueIdx].Number <=7) ? pAd->TxSwQueue[QueIdx].Number : 8);
-				pDiagStruct->TxSWQueCnt[pDiagStruct->ArrayCurIdx][txSwQNumLevel]++;
-
-				firstRound = FALSE;
-			}
-#endif // DBG_DIAGNOSE //
-
-			if (FreeNumber[QueIdx] <= 5)
-			{
-				// free Tx(QueIdx) resources
-				RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);
-				FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
-			}
-#endif // RTMP_MAC_PCI //
-
-			// probe the Queue Head
-			pQueue = &pAd->TxSwQueue[QueIdx];
-			if ((pEntry = pQueue->Head) == NULL)
-			{
-				DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
-				break;
-			}
-
-			pTxBlk = &TxBlk;
-			NdisZeroMemory((PUCHAR)pTxBlk, sizeof(TX_BLK));
-			//InitializeQueueHeader(&pTxBlk->TxPacketList);		// Didn't need it because we already memzero it.
-			pTxBlk->QueIdx = QueIdx;
-
-			pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
-
-
-			// Early check to make sure we have enoguh Tx Resource.
-			hasTxDesc = RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
-			if (!hasTxDesc)
-			{
-				pAd->PrivateInfo.TxRingFullCnt++;
-
-				DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
-
-				break;
-			}
-
-			pTxBlk->TxFrameType = TxPktClassification(pAd, pPacket);
-			pEntry = RemoveHeadQueue(pQueue);
-			pTxBlk->TotalFrameNum++;
-			pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket);	// The real fragment number maybe vary
-			pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
-			pTxBlk->pPacket = pPacket;
-			InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
-
-			if (pTxBlk->TxFrameType == TX_RALINK_FRAME || pTxBlk->TxFrameType == TX_AMSDU_FRAME)
-			{
-				// Enhance SW Aggregation Mechanism
-				if (NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, FreeNumber[QueIdx], pTxBlk->TxFrameType))
-				{
-					InsertHeadQueue(pQueue, PACKET_TO_QUEUE_ENTRY(pPacket));
-					DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
-					break;
-				}
-
-				do{
-					if((pEntry = pQueue->Head) == NULL)
-						break;
-
-					// For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation.
-					pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
-					FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
-					hasTxDesc = RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
-					if ((hasTxDesc == FALSE) || (CanDoAggregateTransmit(pAd, pPacket, pTxBlk) == FALSE))
-						break;
-
-					//Remove the packet from the TxSwQueue and insert into pTxBlk
-					pEntry = RemoveHeadQueue(pQueue);
-					ASSERT(pEntry);
-					pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
-					pTxBlk->TotalFrameNum++;
-					pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket);	// The real fragment number maybe vary
-					pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
-					InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
-				}while(1);
-
-				if (pTxBlk->TxPacketList.Number == 1)
-					pTxBlk->TxFrameType = TX_LEGACY_FRAME;
-			}
-
-
-			Count += pTxBlk->TxPacketList.Number;
-
-
-				// Do HardTransmit now.
-#ifdef CONFIG_STA_SUPPORT
-			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-				Status = STAHardTransmit(pAd, pTxBlk, QueIdx);
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef RTMP_MAC_PCI
-			DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
-			// static rate also need NICUpdateFifoStaCounters() function.
-			//if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
-				NICUpdateFifoStaCounters(pAd);
-#endif // RTMP_MAC_PCI //
-
-		}
-
-		RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
-
-
-#ifdef BLOCK_NET_IF
-		if ((pAd->blockQueueTab[QueIdx].SwTxQueueBlockFlag == TRUE)
-			&& (pAd->TxSwQueue[QueIdx].Number < 1))
-		{
-			releaseNetIf(&pAd->blockQueueTab[QueIdx]);
-		}
-#endif // BLOCK_NET_IF //
-
-	}
-
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Calculates the duration which is required to transmit out frames
-	with given size and specified rate.
-
-	Arguments:
-		pAd	Pointer to our adapter
-		Rate			Transmit rate
-		Size			Frame size in units of byte
-
-	Return Value:
-		Duration number in units of usec
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-USHORT	RTMPCalcDuration(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Rate,
-	IN	ULONG			Size)
-{
-	ULONG	Duration = 0;
-
-	if (Rate < RATE_FIRST_OFDM_RATE) // CCK
-	{
-		if ((Rate > RATE_1) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED))
-			Duration = 96;	// 72+24 preamble+plcp
-		else
-			Duration = 192; // 144+48 preamble+plcp
-
-		Duration += (USHORT)((Size << 4) / RateIdTo500Kbps[Rate]);
-		if ((Size << 4) % RateIdTo500Kbps[Rate])
-			Duration ++;
-	}
-	else if (Rate <= RATE_LAST_OFDM_RATE)// OFDM rates
-	{
-		Duration = 20 + 6;		// 16+4 preamble+plcp + Signal Extension
-		Duration += 4 * (USHORT)((11 + Size * 4) / RateIdTo500Kbps[Rate]);
-		if ((11 + Size * 4) % RateIdTo500Kbps[Rate])
-			Duration += 4;
-	}
-	else	//mimo rate
-	{
-		Duration = 20 + 6;		// 16+4 preamble+plcp + Signal Extension
-	}
-
-	return (USHORT)Duration;
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Calculates the duration which is required to transmit out frames
-	with given size and specified rate.
-
-	Arguments:
-		pTxWI		Pointer to head of each MPDU to HW.
-		Ack		Setting for Ack requirement bit
-		Fragment	Setting for Fragment bit
-		RetryMode	Setting for retry mode
-		Ifs		Setting for IFS gap
-		Rate		Setting for transmit rate
-		Service		Setting for service
-		Length		Frame length
-		TxPreamble	Short or Long preamble when using CCK rates
-		QueIdx - 0-3, according to 802.11e/d4.4 June/2003
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-    See also : BASmartHardTransmit()    !!!
-
-	========================================================================
-*/
-VOID RTMPWriteTxWI(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PTXWI_STRUC	pOutTxWI,
-	IN	BOOLEAN			FRAG,
-	IN	BOOLEAN			CFACK,
-	IN	BOOLEAN			InsTimestamp,
-	IN	BOOLEAN			AMPDU,
-	IN	BOOLEAN			Ack,
-	IN	BOOLEAN			NSeq,		// HW new a sequence.
-	IN	UCHAR			BASize,
-	IN	UCHAR			WCID,
-	IN	ULONG			Length,
-	IN	UCHAR			PID,
-	IN	UCHAR			TID,
-	IN	UCHAR			TxRate,
-	IN	UCHAR			Txopmode,
-	IN	BOOLEAN			CfAck,
-	IN	HTTRANSMIT_SETTING	*pTransmit)
-{
-	PMAC_TABLE_ENTRY	pMac = NULL;
-	TXWI_STRUC		TxWI;
-	PTXWI_STRUC	pTxWI;
-
-	if (WCID < MAX_LEN_OF_MAC_TABLE)
-		pMac = &pAd->MacTab.Content[WCID];
-
-	//
-	// Always use Long preamble before verifiation short preamble functionality works well.
-	// Todo: remove the following line if short preamble functionality works
-	//
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
-	NdisZeroMemory(&TxWI, TXWI_SIZE);
-	pTxWI = &TxWI;
-
-	pTxWI->FRAG= FRAG;
-
-	pTxWI->CFACK = CFACK;
-	pTxWI->TS= InsTimestamp;
-	pTxWI->AMPDU = AMPDU;
-	pTxWI->ACK = Ack;
-	pTxWI->txop= Txopmode;
-
-	pTxWI->NSEQ = NSeq;
-	// John tune the performace with Intel Client in 20 MHz performance
-#ifdef DOT11_N_SUPPORT
-	BASize = pAd->CommonCfg.TxBASize;
-	if (pAd->MACVersion == 0x28720200)
-	{
-		if( BASize >13 )
-			BASize =13;
-	}
-	else
-	{
-		if( BASize >7 )
-			BASize =7;
-	}
-	pTxWI->BAWinSize = BASize;
-	pTxWI->ShortGI = pTransmit->field.ShortGI;
-	pTxWI->STBC = pTransmit->field.STBC;
-#endif // DOT11_N_SUPPORT //
-
-	pTxWI->WirelessCliID = WCID;
-	pTxWI->MPDUtotalByteCount = Length;
-	pTxWI->PacketId = PID;
-
-	// If CCK or OFDM, BW must be 20
-	pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
-#ifdef DOT11_N_SUPPORT
-#ifdef DOT11N_DRAFT3
-	if (pTxWI->BW)
-		pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
-#endif // DOT11N_DRAFT3 //
-#endif // DOT11_N_SUPPORT //
-
-	pTxWI->MCS = pTransmit->field.MCS;
-	pTxWI->PHYMODE = pTransmit->field.MODE;
-	pTxWI->CFACK = CfAck;
-
-#ifdef DOT11_N_SUPPORT
-	if (pMac)
-	{
-        if (pAd->CommonCfg.bMIMOPSEnable)
-        {
-		if ((pMac->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
-			{
-				// Dynamic MIMO Power Save Mode
-				pTxWI->MIMOps = 1;
-			}
-			else if (pMac->MmpsMode == MMPS_STATIC)
-			{
-				// Static MIMO Power Save Mode
-				if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
-				{
-					pTxWI->MCS = 7;
-					pTxWI->MIMOps = 0;
-				}
-			}
-        }
-		//pTxWI->MIMOps = (pMac->PsMode == PWR_MMPS)? 1:0;
-		if (pMac->bIAmBadAtheros && (pMac->WepStatus != Ndis802_11WEPDisabled))
-		{
-			pTxWI->MpduDensity = 7;
-		}
-		else
-		{
-		pTxWI->MpduDensity = pMac->MpduDensity;
-	}
-	}
-#endif // DOT11_N_SUPPORT //
-
-	pTxWI->PacketId = pTxWI->MCS;
-	NdisMoveMemory(pOutTxWI, &TxWI, sizeof(TXWI_STRUC));
-}
-
-
-VOID RTMPWriteTxWI_Data(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	OUT PTXWI_STRUC		pTxWI,
-	IN	TX_BLK				*pTxBlk)
-{
-	HTTRANSMIT_SETTING	*pTransmit;
-	PMAC_TABLE_ENTRY	pMacEntry;
-#ifdef DOT11_N_SUPPORT
-	UCHAR				BASize;
-#endif // DOT11_N_SUPPORT //
-
-
-	ASSERT(pTxWI);
-
-	pTransmit = pTxBlk->pTransmit;
-	pMacEntry = pTxBlk->pMacEntry;
-
-
-	//
-	// Always use Long preamble before verifiation short preamble functionality works well.
-	// Todo: remove the following line if short preamble functionality works
-	//
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
-	NdisZeroMemory(pTxWI, TXWI_SIZE);
-
-	pTxWI->FRAG		= TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag);
-	pTxWI->ACK		= TX_BLK_TEST_FLAG(pTxBlk, fTX_bAckRequired);
-	pTxWI->txop		= pTxBlk->FrameGap;
-
-#ifdef CONFIG_STA_SUPPORT
-#ifdef QOS_DLS_SUPPORT
-	if (pMacEntry &&
-		(pAd->StaCfg.BssType == BSS_INFRA) &&
-		(pMacEntry->ValidAsDls == TRUE))
-		pTxWI->WirelessCliID = BSSID_WCID;
-	else
-#endif // QOS_DLS_SUPPORT //
-#endif // CONFIG_STA_SUPPORT //
-	pTxWI->WirelessCliID		= pTxBlk->Wcid;
-
-	pTxWI->MPDUtotalByteCount	= pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
-	pTxWI->CFACK				= TX_BLK_TEST_FLAG(pTxBlk, fTX_bPiggyBack);
-
-	// If CCK or OFDM, BW must be 20
-	pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
-#ifdef DOT11_N_SUPPORT
-#ifdef DOT11N_DRAFT3
-	if (pTxWI->BW)
-		pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
-#endif // DOT11N_DRAFT3 //
-	pTxWI->AMPDU	= ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) ? TRUE : FALSE);
-
-	// John tune the performace with Intel Client in 20 MHz performance
-	BASize = pAd->CommonCfg.TxBASize;
-	if((pTxBlk->TxFrameType == TX_AMPDU_FRAME) && (pMacEntry))
-	{
-		UCHAR		RABAOriIdx = 0;	//The RA's BA Originator table index.
-
-		RABAOriIdx = pTxBlk->pMacEntry->BAOriWcidArray[pTxBlk->UserPriority];
-		BASize = pAd->BATable.BAOriEntry[RABAOriIdx].BAWinSize;
-	}
-
-
-	pTxWI->TxBF = pTransmit->field.TxBF;
-	pTxWI->BAWinSize = BASize;
-	pTxWI->ShortGI = pTransmit->field.ShortGI;
-	pTxWI->STBC = pTransmit->field.STBC;
-#endif // DOT11_N_SUPPORT //
-
-	pTxWI->MCS = pTransmit->field.MCS;
-	pTxWI->PHYMODE = pTransmit->field.MODE;
-
-
-#ifdef DOT11_N_SUPPORT
-	if (pMacEntry)
-	{
-		if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
-		{
-			// Dynamic MIMO Power Save Mode
-			pTxWI->MIMOps = 1;
-		}
-		else if (pMacEntry->MmpsMode == MMPS_STATIC)
-		{
-			// Static MIMO Power Save Mode
-			if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
-			{
-				pTxWI->MCS = 7;
-				pTxWI->MIMOps = 0;
-			}
-		}
-
-		if (pMacEntry->bIAmBadAtheros && (pMacEntry->WepStatus != Ndis802_11WEPDisabled))
-		{
-			pTxWI->MpduDensity = 7;
-		}
-		else
-		{
-		pTxWI->MpduDensity = pMacEntry->MpduDensity;
-	}
-	}
-#endif // DOT11_N_SUPPORT //
-
-#ifdef DBG_DIAGNOSE
-		if (pTxBlk->QueIdx== 0)
-		{
-			pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
-			pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
-		}
-#endif // DBG_DIAGNOSE //
-
-	// for rate adapation
-	pTxWI->PacketId = pTxWI->MCS;
-#ifdef INF_AMAZON_SE
-/*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate */
-	if( RTMP_GET_PACKET_NOBULKOUT(pTxBlk->pPacket))
-	{
-		if(pTxWI->PHYMODE == MODE_CCK)
-		{
-			pTxWI->PacketId = 6;
-		}
-	}
-#endif // INF_AMAZON_SE //
-}
-
-
-VOID RTMPWriteTxWI_Cache(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	OUT PTXWI_STRUC		pTxWI,
-	IN	TX_BLK				*pTxBlk)
-{
-	PHTTRANSMIT_SETTING	/*pTxHTPhyMode,*/ pTransmit;
-	PMAC_TABLE_ENTRY	pMacEntry;
-
-	//
-	// update TXWI
-	//
-	pMacEntry = pTxBlk->pMacEntry;
-	pTransmit = pTxBlk->pTransmit;
-
-	//if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
-	//if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pMacEntry))
-	//if (TX_BLK_TEST_FLAG(pTxBlk, fTX_AutoRateSwitch))
-	if (pMacEntry->bAutoTxRateSwitch)
-	{
-		pTxWI->txop = IFS_HTTXOP;
-
-		// If CCK or OFDM, BW must be 20
-		pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
-		pTxWI->ShortGI = pTransmit->field.ShortGI;
-		pTxWI->STBC = pTransmit->field.STBC;
-
-		pTxWI->MCS = pTransmit->field.MCS;
-		pTxWI->PHYMODE = pTransmit->field.MODE;
-
-		// set PID for TxRateSwitching
-		pTxWI->PacketId = pTransmit->field.MCS;
-	}
-
-#ifdef DOT11_N_SUPPORT
-	pTxWI->AMPDU = ((pMacEntry->NoBADataCountDown == 0) ? TRUE: FALSE);
-	pTxWI->MIMOps = 0;
-
-#ifdef DOT11N_DRAFT3
-	if (pTxWI->BW)
-		pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
-#endif // DOT11N_DRAFT3 //
-
-    if (pAd->CommonCfg.bMIMOPSEnable)
-    {
-		// MIMO Power Save Mode
-		if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
-		{
-			// Dynamic MIMO Power Save Mode
-			pTxWI->MIMOps = 1;
-		}
-		else if (pMacEntry->MmpsMode == MMPS_STATIC)
-		{
-			// Static MIMO Power Save Mode
-			if ((pTransmit->field.MODE >= MODE_HTMIX) && (pTransmit->field.MCS > 7))
-			{
-				pTxWI->MCS = 7;
-				pTxWI->MIMOps = 0;
-			}
-		}
-    }
-#endif // DOT11_N_SUPPORT //
-
-#ifdef DBG_DIAGNOSE
-	if (pTxBlk->QueIdx== 0)
-	{
-		pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
-		pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
-	}
-#endif // DBG_DIAGNOSE //
-
-	pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
-
-}
-
-
-// should be called only when -
-// 1. MEADIA_CONNECTED
-// 2. AGGREGATION_IN_USED
-// 3. Fragmentation not in used
-// 4. either no previous frame (pPrevAddr1=NULL) .OR. previoud frame is aggregatible
-BOOLEAN TxFrameIsAggregatible(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pPrevAddr1,
-	IN	PUCHAR			p8023hdr)
-{
-
-	// can't aggregate EAPOL (802.1x) frame
-	if ((p8023hdr[12] == 0x88) && (p8023hdr[13] == 0x8e))
-		return FALSE;
-
-	// can't aggregate multicast/broadcast frame
-	if (p8023hdr[0] & 0x01)
-		return FALSE;
-
-	if (INFRA_ON(pAd)) // must be unicast to AP
-		return TRUE;
-	else if ((pPrevAddr1 == NULL) || MAC_ADDR_EQUAL(pPrevAddr1, p8023hdr)) // unicast to same STA
-		return TRUE;
-	else
-		return FALSE;
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-	   Check the MSDU Aggregation policy
-	1.HT aggregation is A-MSDU
-	2.legaacy rate aggregation is software aggregation by Ralink.
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-BOOLEAN PeerIsAggreOn(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	ULONG		   TxRate,
-	IN	PMAC_TABLE_ENTRY pMacEntry)
-{
-	ULONG	AFlags = (fCLIENT_STATUS_AMSDU_INUSED | fCLIENT_STATUS_AGGREGATION_CAPABLE);
-
-	if (pMacEntry != NULL && CLIENT_STATUS_TEST_FLAG(pMacEntry, AFlags))
-	{
-#ifdef DOT11_N_SUPPORT
-		if (pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
-		{
-			return TRUE;
-		}
-#endif // DOT11_N_SUPPORT //
-
-#ifdef AGGREGATION_SUPPORT
-		if (TxRate >= RATE_6 && pAd->CommonCfg.bAggregationCapable && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
-		{	// legacy  Ralink Aggregation support
-			return TRUE;
-		}
-#endif // AGGREGATION_SUPPORT //
-	}
-
-	return FALSE;
-
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Check and fine the packet waiting in SW queue with highest priority
-
-	Arguments:
-		pAd Pointer to our adapter
-
-	Return Value:
-		pQueue		Pointer to Waiting Queue
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-PQUEUE_HEADER	RTMPCheckTxSwQueue(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT PUCHAR			pQueIdx)
-{
-
-	ULONG	Number;
-	// 2004-11-15 to be removed. test aggregation only
-//	if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)) && (*pNumber < 2))
-//		 return NULL;
-
-	Number = pAd->TxSwQueue[QID_AC_BK].Number
-			 + pAd->TxSwQueue[QID_AC_BE].Number
-			 + pAd->TxSwQueue[QID_AC_VI].Number
-			 + pAd->TxSwQueue[QID_AC_VO].Number;
-			 /*+ pAd->TxSwQueue[QID_HCCA].Number;*/
-
-	if (pAd->TxSwQueue[QID_AC_VO].Head != NULL)
-	{
-		*pQueIdx = QID_AC_VO;
-		return (&pAd->TxSwQueue[QID_AC_VO]);
-	}
-	else if (pAd->TxSwQueue[QID_AC_VI].Head != NULL)
-	{
-		*pQueIdx = QID_AC_VI;
-		return (&pAd->TxSwQueue[QID_AC_VI]);
-	}
-	else if (pAd->TxSwQueue[QID_AC_BE].Head != NULL)
-	{
-		*pQueIdx = QID_AC_BE;
-		return (&pAd->TxSwQueue[QID_AC_BE]);
-	}
-	else if (pAd->TxSwQueue[QID_AC_BK].Head != NULL)
-	{
-		*pQueIdx = QID_AC_BK;
-		return (&pAd->TxSwQueue[QID_AC_BK]);
-	}
-	/*
-	else if (pAd->TxSwQueue[QID_HCCA].Head != NULL)
-	{
-		*pQueIdx = QID_HCCA;
-		return (&pAd->TxSwQueue[QID_HCCA]);
-	}
-	*/
-
-	// No packet pending in Tx Sw queue
-	*pQueIdx = QID_AC_BK;
-
-	return (NULL);
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Suspend MSDU transmission
-
-	Arguments:
-		pAd	Pointer to our adapter
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPSuspendMsduTransmission(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	DBGPRINT(RT_DEBUG_TRACE,("SCANNING, suspend MSDU transmission ...\n"));
-
-
-	//
-	// Before BSS_SCAN_IN_PROGRESS, we need to keep Current R66 value and
-	// use Lowbound as R66 value on ScanNextChannel(...)
-	//
-	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
-
-	// set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning)
-	//RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd)));
-	RTMPSetAGCInitValue(pAd, BW_20);
-
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
-	//RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x000f0000);		// abort all TX rings
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Resume MSDU transmission
-
-	Arguments:
-		pAd	Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID RTMPResumeMsduTransmission(
-	IN	PRTMP_ADAPTER	pAd)
-{
-//    UCHAR			IrqState;
-
-	DBGPRINT(RT_DEBUG_TRACE,("SCAN done, resume MSDU transmission ...\n"));
-
-
-	// After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value
-	// R66 should not be 0
-	if (pAd->BbpTuning.R66CurrentValue == 0)
-	{
-		pAd->BbpTuning.R66CurrentValue = 0x38;
-		DBGPRINT_ERR(("RTMPResumeMsduTransmission, R66CurrentValue=0...\n"));
-	}
-
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, pAd->BbpTuning.R66CurrentValue);
-
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
-// sample, for IRQ LOCK to SEM LOCK
-//    IrqState = pAd->irq_disabled;
-//	if (IrqState)
-//		RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
-//    else
-	RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
-}
-
-
-UINT deaggregate_AMSDU_announce(
-	IN	PRTMP_ADAPTER	pAd,
-	PNDIS_PACKET		pPacket,
-	IN	PUCHAR			pData,
-	IN	ULONG			DataSize)
-{
-	USHORT			PayloadSize;
-	USHORT			SubFrameSize;
-	PHEADER_802_3	pAMSDUsubheader;
-	UINT			nMSDU;
-    UCHAR			Header802_3[14];
-
-	PUCHAR			pPayload, pDA, pSA, pRemovedLLCSNAP;
-	PNDIS_PACKET	pClonePacket;
-
-
-
-	nMSDU = 0;
-
-	while (DataSize > LENGTH_802_3)
-	{
-
-		nMSDU++;
-
-		//hex_dump("subheader", pData, 64);
-		pAMSDUsubheader = (PHEADER_802_3)pData;
-		//pData += LENGTH_802_3;
-		PayloadSize = pAMSDUsubheader->Octet[1] + (pAMSDUsubheader->Octet[0]<<8);
-		SubFrameSize = PayloadSize + LENGTH_802_3;
-
-
-		if ((DataSize < SubFrameSize) || (PayloadSize > 1518 ))
-		{
-			break;
-		}
-
-		//DBGPRINT(RT_DEBUG_TRACE,("%d subframe: Size = %d\n",  nMSDU, PayloadSize));
-
-		pPayload = pData + LENGTH_802_3;
-		pDA = pData;
-		pSA = pData + MAC_ADDR_LEN;
-
-		// convert to 802.3 header
-        CONVERT_TO_802_3(Header802_3, pDA, pSA, pPayload, PayloadSize, pRemovedLLCSNAP);
-
-#ifdef CONFIG_STA_SUPPORT
-		if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E) )
-		{
-			/* avoid local heap overflow, use dyanamic allocation */
-		   MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
-			if (Elem != NULL)
-			{
-				memmove(Elem->Msg+(LENGTH_802_11 + LENGTH_802_1_H), pPayload, PayloadSize);
-				Elem->MsgLen = LENGTH_802_11 + LENGTH_802_1_H + PayloadSize;
-				//WpaEAPOLKeyAction(pAd, Elem);
-				REPORT_MGMT_FRAME_TO_MLME(pAd, BSSID_WCID, Elem->Msg, Elem->MsgLen, 0, 0, 0, 0);
-				kfree(Elem);
-			}
-		}
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			if (pRemovedLLCSNAP)
-			{
-				pPayload -= LENGTH_802_3;
-				PayloadSize += LENGTH_802_3;
-				NdisMoveMemory(pPayload, &Header802_3[0], LENGTH_802_3);
-			}
-		}
-#endif // CONFIG_STA_SUPPORT //
-
-		pClonePacket = ClonePacket(pAd, pPacket, pPayload, PayloadSize);
-		if (pClonePacket)
-		{
-#ifdef CONFIG_STA_SUPPORT
-			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-				ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pClonePacket, RTMP_GET_PACKET_IF(pPacket));
-#endif // CONFIG_STA_SUPPORT //
-		}
-
-
-		// A-MSDU has padding to multiple of 4 including subframe header.
-		// align SubFrameSize up to multiple of 4
-		SubFrameSize = (SubFrameSize+3)&(~0x3);
-
-
-		if (SubFrameSize > 1528 || SubFrameSize < 32)
-		{
-			break;
-		}
-
-		if (DataSize > SubFrameSize)
-		{
-			pData += SubFrameSize;
-			DataSize -= SubFrameSize;
-		}
-		else
-		{
-			// end of A-MSDU
-			DataSize = 0;
-		}
-	}
-
-	// finally release original rx packet
-	RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-
-	return nMSDU;
-}
-
-
-UINT BA_Reorder_AMSDU_Annnounce(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket)
-{
-	PUCHAR			pData;
-	USHORT			DataSize;
-	UINT			nMSDU = 0;
-
-	pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
-	DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
-
-	nMSDU = deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
-
-	return nMSDU;
-}
-
-
-/*
-	==========================================================================
-	Description:
-		Look up the MAC address in the MAC table. Return NULL if not found.
-	Return:
-		pEntry - pointer to the MAC entry; NULL is not found
-	==========================================================================
-*/
-MAC_TABLE_ENTRY *MacTableLookup(
-	IN PRTMP_ADAPTER pAd,
-	PUCHAR pAddr)
-{
-	ULONG HashIdx;
-	MAC_TABLE_ENTRY *pEntry = NULL;
-
-	HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
-	pEntry = pAd->MacTab.Hash[HashIdx];
-
-	while (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsWDS || pEntry->ValidAsApCli || pEntry->ValidAsMesh))
-	{
-		if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
-		{
-			break;
-		}
-		else
-			pEntry = pEntry->pNext;
-	}
-
-	return pEntry;
-}
-
-MAC_TABLE_ENTRY *MacTableInsertEntry(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR			pAddr,
-	IN	UCHAR			apidx,
-	IN BOOLEAN	CleanAll)
-{
-	UCHAR HashIdx;
-	int i, FirstWcid;
-	MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
-//	USHORT	offset;
-//	ULONG	addr;
-
-	// if FULL, return
-	if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
-		return NULL;
-
-	FirstWcid = 1;
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	if (pAd->StaCfg.BssType == BSS_INFRA)
-		FirstWcid = 2;
-#endif // CONFIG_STA_SUPPORT //
-
-	// allocate one MAC entry
-	NdisAcquireSpinLock(&pAd->MacTabLock);
-	for (i = FirstWcid; i< MAX_LEN_OF_MAC_TABLE; i++)   // skip entry#0 so that "entry index == AID" for fast lookup
-	{
-		// pick up the first available vacancy
-		if ((pAd->MacTab.Content[i].ValidAsCLI == FALSE) &&
-			(pAd->MacTab.Content[i].ValidAsWDS == FALSE) &&
-			(pAd->MacTab.Content[i].ValidAsApCli== FALSE) &&
-			(pAd->MacTab.Content[i].ValidAsMesh == FALSE)
-#ifdef CONFIG_STA_SUPPORT
-#ifdef QOS_DLS_SUPPORT
-			&& (pAd->MacTab.Content[i].ValidAsDls == FALSE)
-#endif // QOS_DLS_SUPPORT //
-#endif // CONFIG_STA_SUPPORT //
-			)
-		{
-			pEntry = &pAd->MacTab.Content[i];
-			if (CleanAll == TRUE)
-			{
-				pEntry->MaxSupportedRate = RATE_11;
-				pEntry->CurrTxRate = RATE_11;
-				NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
-				pEntry->PairwiseKey.KeyLen = 0;
-				pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
-			}
-#ifdef CONFIG_STA_SUPPORT
-#ifdef QOS_DLS_SUPPORT
-			if (apidx >= MIN_NET_DEVICE_FOR_DLS)
-			{
-				pEntry->ValidAsCLI = FALSE;
-				pEntry->ValidAsWDS = FALSE;
-				pEntry->ValidAsApCli = FALSE;
-				pEntry->ValidAsMesh = FALSE;
-				pEntry->ValidAsDls = TRUE;
-				pEntry->isCached = FALSE;
-			}
-			else
-#endif // QOS_DLS_SUPPORT //
-#endif // CONFIG_STA_SUPPORT //
-			{
-
-#ifdef CONFIG_STA_SUPPORT
-				IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-				{
-					pEntry->ValidAsCLI = TRUE;
-					pEntry->ValidAsWDS = FALSE;
-					pEntry->ValidAsApCli = FALSE;
-					pEntry->ValidAsMesh = FALSE;
-					pEntry->ValidAsDls = FALSE;
-				}
-#endif // CONFIG_STA_SUPPORT //
-			}
-
-			pEntry->bIAmBadAtheros = FALSE;
-			pEntry->pAd = pAd;
-			pEntry->CMTimerRunning = FALSE;
-			pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
-			pEntry->RSNIE_Len = 0;
-			NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter));
-			pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
-
-			if (pEntry->ValidAsMesh)
-				pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_MESH);
-			else if (pEntry->ValidAsApCli)
-				pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_APCLI);
-			else if (pEntry->ValidAsWDS)
-				pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_WDS);
-#ifdef CONFIG_STA_SUPPORT
-#ifdef QOS_DLS_SUPPORT
-			else if (pEntry->ValidAsDls)
-				pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_DLS);
-#endif // QOS_DLS_SUPPORT //
-#endif // CONFIG_STA_SUPPORT //
-			else
-				pEntry->apidx = apidx;
-
-
-			{
-
-#ifdef CONFIG_STA_SUPPORT
-				IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-				{
-					pEntry->AuthMode = pAd->StaCfg.AuthMode;
-					pEntry->WepStatus = pAd->StaCfg.WepStatus;
-					pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
-#ifdef RTMP_MAC_PCI
-					AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)i);
-#endif // RTMP_MAC_PCI //
-				}
-#endif // CONFIG_STA_SUPPORT //
-			}
-
-			pEntry->GTKState = REKEY_NEGOTIATING;
-			pEntry->PairwiseKey.KeyLen = 0;
-			pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
-#ifdef CONFIG_STA_SUPPORT
-#ifdef QOS_DLS_SUPPORT
-			if (pEntry->ValidAsDls == TRUE)
-				pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
-			else
-#endif //QOS_DLS_SUPPORT
-#endif // CONFIG_STA_SUPPORT //
-				pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-
-			pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
-			COPY_MAC_ADDR(pEntry->Addr, pAddr);
-			pEntry->Sst = SST_NOT_AUTH;
-			pEntry->AuthState = AS_NOT_AUTH;
-			pEntry->Aid = (USHORT)i;  //0;
-			pEntry->CapabilityInfo = 0;
-			pEntry->PsMode = PWR_ACTIVE;
-			pEntry->PsQIdleCount = 0;
-			pEntry->NoDataIdleCount = 0;
-			pEntry->AssocDeadLine = MAC_TABLE_ASSOC_TIMEOUT;
-			pEntry->ContinueTxFailCnt = 0;
-#ifdef WDS_SUPPORT
-			pEntry->LockEntryTx = FALSE;
-			pEntry->TimeStamp_toTxRing = 0;
-#endif // WDS_SUPPORT //
-			InitializeQueueHeader(&pEntry->PsQueue);
-
-
-			pAd->MacTab.Size ++;
-			// Add this entry into ASIC RX WCID search table
-			RTMP_STA_ENTRY_ADD(pAd, pEntry);
-
-
-
-			DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertEntry - allocate entry #%d, Total= %d\n",i, pAd->MacTab.Size));
-			break;
-		}
-	}
-
-	// add this MAC entry into HASH table
-	if (pEntry)
-	{
-		HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
-		if (pAd->MacTab.Hash[HashIdx] == NULL)
-		{
-			pAd->MacTab.Hash[HashIdx] = pEntry;
-		}
-		else
-		{
-			pCurrEntry = pAd->MacTab.Hash[HashIdx];
-			while (pCurrEntry->pNext != NULL)
-				pCurrEntry = pCurrEntry->pNext;
-			pCurrEntry->pNext = pEntry;
-		}
-	}
-
-	NdisReleaseSpinLock(&pAd->MacTabLock);
-	return pEntry;
-}
-
-/*
-	==========================================================================
-	Description:
-		Delete a specified client from MAC table
-	==========================================================================
- */
-BOOLEAN MacTableDeleteEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT wcid,
-	IN PUCHAR pAddr)
-{
-	USHORT HashIdx;
-	MAC_TABLE_ENTRY *pEntry, *pPrevEntry, *pProbeEntry;
-	BOOLEAN Cancelled;
-	//USHORT	offset;	// unused variable
-	//UCHAR	j;			// unused variable
-
-	if (wcid >= MAX_LEN_OF_MAC_TABLE)
-		return FALSE;
-
-	NdisAcquireSpinLock(&pAd->MacTabLock);
-
-	HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
-	//pEntry = pAd->MacTab.Hash[HashIdx];
-	pEntry = &pAd->MacTab.Content[wcid];
-
-	if (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS || pEntry->ValidAsMesh
-#ifdef CONFIG_STA_SUPPORT
-#ifdef QOS_DLS_SUPPORT
-		|| pEntry->ValidAsDls
-#endif // QOS_DLS_SUPPORT //
-#endif // CONFIG_STA_SUPPORT //
-		))
-	{
-		if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
-		{
-
-			// Delete this entry from ASIC on-chip WCID Table
-			RTMP_STA_ENTRY_MAC_RESET(pAd, wcid);
-
-#ifdef DOT11_N_SUPPORT
-			// free resources of BA
-			BASessionTearDownALL(pAd, pEntry->Aid);
-#endif // DOT11_N_SUPPORT //
-
-
-			pPrevEntry = NULL;
-			pProbeEntry = pAd->MacTab.Hash[HashIdx];
-			ASSERT(pProbeEntry);
-
-			// update Hash list
-			do
-			{
-				if (pProbeEntry == pEntry)
-				{
-					if (pPrevEntry == NULL)
-					{
-						pAd->MacTab.Hash[HashIdx] = pEntry->pNext;
-					}
-					else
-					{
-						pPrevEntry->pNext = pEntry->pNext;
-					}
-					break;
-				}
-
-				pPrevEntry = pProbeEntry;
-				pProbeEntry = pProbeEntry->pNext;
-			} while (pProbeEntry);
-
-			// not found !!!
-			ASSERT(pProbeEntry != NULL);
-
-			RTMP_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid);
-
-
-		if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
-		{
-            RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
-			pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
-        }
-
-
-			NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
-			pAd->MacTab.Size --;
-			DBGPRINT(RT_DEBUG_TRACE, ("MacTableDeleteEntry1 - Total= %d\n", pAd->MacTab.Size));
-		}
-		else
-		{
-			DBGPRINT(RT_DEBUG_OFF, ("\n%s: Impossible Wcid = %d !!!!!\n", __FUNCTION__, wcid));
-		}
-	}
-
-	NdisReleaseSpinLock(&pAd->MacTabLock);
-
-	//Reset operating mode when no Sta.
-	if (pAd->MacTab.Size == 0)
-	{
-#ifdef DOT11_N_SUPPORT
-		pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0;
-#endif // DOT11_N_SUPPORT //
-		//AsicUpdateProtect(pAd, 0 /*pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode*/, (ALLN_SETPROTECT), TRUE, 0 /*pAd->MacTab.fAnyStationNonGF*/);
-		RTMP_UPDATE_PROTECT(pAd);  // edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
-	}
-
-	return TRUE;
-}
-
-
-/*
-	==========================================================================
-	Description:
-		This routine reset the entire MAC table. All packets pending in
-		the power-saving queues are freed here.
-	==========================================================================
- */
-VOID MacTableReset(
-	IN  PRTMP_ADAPTER  pAd)
-{
-	int         i;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n"));
-	//NdisAcquireSpinLock(&pAd->MacTabLock);
-
-
-	for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
-	{
-#ifdef RTMP_MAC_PCI
-		RTMP_STA_ENTRY_MAC_RESET(pAd, i);
-#endif // RTMP_MAC_PCI //
-		if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
-	   {
-
-
-#ifdef DOT11_N_SUPPORT
-			// free resources of BA
-			BASessionTearDownALL(pAd, i);
-#endif // DOT11_N_SUPPORT //
-
-			pAd->MacTab.Content[i].ValidAsCLI = FALSE;
-
-
-
-
-			//AsicDelWcidTab(pAd, i);
-		}
-	}
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-VOID AssocParmFill(
-	IN PRTMP_ADAPTER pAd,
-	IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
-	IN PUCHAR                     pAddr,
-	IN USHORT                     CapabilityInfo,
-	IN ULONG                      Timeout,
-	IN USHORT                     ListenIntv)
-{
-	COPY_MAC_ADDR(AssocReq->Addr, pAddr);
-	// Add mask to support 802.11b mode only
-	AssocReq->CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; // not cf-pollable, not cf-poll-request
-	AssocReq->Timeout = Timeout;
-	AssocReq->ListenIntv = ListenIntv;
-}
-
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-VOID DisassocParmFill(
-	IN PRTMP_ADAPTER pAd,
-	IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
-	IN PUCHAR pAddr,
-	IN USHORT Reason)
-{
-	COPY_MAC_ADDR(DisassocReq->Addr, pAddr);
-	DisassocReq->Reason = Reason;
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Check the out going frame, if this is an DHCP or ARP datagram
-	will be duplicate another frame at low data rate transmit.
-
-	Arguments:
-		pAd		Pointer to our adapter
-		pPacket		Pointer to outgoing Ndis frame
-
-	Return Value:
-		TRUE		To be duplicate at Low data rate transmit. (1mb)
-		FALSE		Do nothing.
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-		MAC header + IP Header + UDP Header
-		  14 Bytes	  20 Bytes
-
-		UDP Header
-		00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|
-						Source Port
-		16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|
-					Destination Port
-
-		port 0x43 means Bootstrap Protocol, server.
-		Port 0x44 means Bootstrap Protocol, client.
-
-	========================================================================
-*/
-
-BOOLEAN RTMPCheckDHCPFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket)
-{
-	PACKET_INFO	PacketInfo;
-	ULONG			NumberOfBytesRead = 0;
-	ULONG			CurrentOffset = 0;
-	PVOID			pVirtualAddress = NULL;
-	UINT			NdisBufferLength;
-	PUCHAR			pSrc;
-	USHORT			Protocol;
-	UCHAR			ByteOffset36 = 0;
-	UCHAR			ByteOffset38 = 0;
-	BOOLEAN			ReadFirstParm = TRUE;
-
-	RTMP_QueryPacketInfo(pPacket, &PacketInfo, (PUCHAR *)&pVirtualAddress, &NdisBufferLength);
-
-	NumberOfBytesRead += NdisBufferLength;
-	pSrc = (PUCHAR) pVirtualAddress;
-	Protocol = *(pSrc + 12) * 256 + *(pSrc + 13);
-
-	//
-	// Check DHCP & BOOTP protocol
-	//
-	while (NumberOfBytesRead <= PacketInfo.TotalPacketLength)
-	{
-		if ((NumberOfBytesRead >= 35) && (ReadFirstParm == TRUE))
-		{
-			CurrentOffset = 35 - (NumberOfBytesRead - NdisBufferLength);
-			ByteOffset36 = *(pSrc + CurrentOffset);
-			ReadFirstParm = FALSE;
-		}
-
-		if (NumberOfBytesRead >= 37)
-		{
-			CurrentOffset = 37 - (NumberOfBytesRead - NdisBufferLength);
-			ByteOffset38 = *(pSrc + CurrentOffset);
-			//End of Read
-			break;
-		}
-		return FALSE;
-	}
-
-	// Check for DHCP & BOOTP protocol
-	if ((ByteOffset36 != 0x44) || (ByteOffset38 != 0x43))
-		{
-		//
-		// 2054 (hex 0806) for ARP datagrams
-		// if this packet is not ARP datagrams, then do nothing
-		// ARP datagrams will also be duplicate at 1mb broadcast frames
-		//
-		if (Protocol != 0x0806 )
-			return FALSE;
-		}
-
-	return TRUE;
-}
-
-
-BOOLEAN RTMPCheckEtherType(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket)
-{
-	USHORT	TypeLen;
-	UCHAR	Byte0, Byte1;
-	PUCHAR	pSrcBuf;
-	UINT32	pktLen;
-	UINT16	srcPort, dstPort;
-	BOOLEAN	status = TRUE;
-
-
-	pSrcBuf = GET_OS_PKT_DATAPTR(pPacket);
-	pktLen = GET_OS_PKT_LEN(pPacket);
-
-	ASSERT(pSrcBuf);
-
-	RTMP_SET_PACKET_SPECIFIC(pPacket, 0);
-
-	// get Ethernet protocol field
-	TypeLen = (pSrcBuf[12] << 8) + pSrcBuf[13];
-
-	pSrcBuf += LENGTH_802_3;	// Skip the Ethernet Header.
-
-	if (TypeLen <= 1500)
-	{	// 802.3, 802.3 LLC
-		/*
-			DestMAC(6) + SrcMAC(6) + Lenght(2) +
-			DSAP(1) + SSAP(1) + Control(1) +
-			if the DSAP = 0xAA, SSAP=0xAA, Contorl = 0x03, it has a 5-bytes SNAP header.
-				=> + SNAP (5, OriginationID(3) + etherType(2))
-		*/
-		if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA && pSrcBuf[2] == 0x03)
-		{
-			Sniff2BytesFromNdisBuffer((PNDIS_BUFFER)pSrcBuf, 6, &Byte0, &Byte1);
-			RTMP_SET_PACKET_LLCSNAP(pPacket, 1);
-			TypeLen = (USHORT)((Byte0 << 8) + Byte1);
-			pSrcBuf += 8; // Skip this LLC/SNAP header
-		}
-		else
-		{
-			//It just has 3-byte LLC header, maybe a legacy ether type frame. we didn't handle it.
-		}
-	}
-
-	// If it's a VLAN packet, get the real Type/Length field.
-	if (TypeLen == 0x8100)
-	{
-		/* 0x8100 means VLAN packets */
-
-		/* Dest. MAC Address (6-bytes) +
-		   Source MAC Address (6-bytes) +
-		   Length/Type = 802.1Q Tag Type (2-byte) +
-		   Tag Control Information (2-bytes) +
-		   Length / Type (2-bytes) +
-		   data payload (0-n bytes) +
-		   Pad (0-p bytes) +
-		   Frame Check Sequence (4-bytes) */
-
-		RTMP_SET_PACKET_VLAN(pPacket, 1);
-		Sniff2BytesFromNdisBuffer((PNDIS_BUFFER)pSrcBuf, 2, &Byte0, &Byte1);
-		TypeLen = (USHORT)((Byte0 << 8) + Byte1);
-
-		pSrcBuf += 4; // Skip the VLAN Header.
-	}
-
-	switch (TypeLen)
-	{
-		case 0x0800:
-			{
-				ASSERT((pktLen > 34));
-				if (*(pSrcBuf + 9) == 0x11)
-				{	// udp packet
-					ASSERT((pktLen > 34));	// 14 for ethernet header, 20 for IP header
-
-					pSrcBuf += 20;	// Skip the IP header
-					srcPort = OS_NTOHS(get_unaligned((PUINT16)(pSrcBuf)));
-					dstPort = OS_NTOHS(get_unaligned((PUINT16)(pSrcBuf+2)));
-
-					if ((srcPort==0x44 && dstPort==0x43) || (srcPort==0x43 && dstPort==0x44))
-					{	//It's a BOOTP/DHCP packet
-						RTMP_SET_PACKET_DHCP(pPacket, 1);
-					}
-				}
-			}
-			break;
-		case 0x0806:
-			{
-				//ARP Packet.
-				RTMP_SET_PACKET_DHCP(pPacket, 1);
-			}
-			break;
-		case 0x888e:
-			{
-				// EAPOL Packet.
-				RTMP_SET_PACKET_EAPOL(pPacket, 1);
-			}
-			break;
-		default:
-			status = FALSE;
-			break;
-	}
-
-	return status;
-
-}
-
-
-
-VOID Update_Rssi_Sample(
-	IN PRTMP_ADAPTER	pAd,
-	IN RSSI_SAMPLE		*pRssi,
-	IN PRXWI_STRUC		pRxWI)
-		{
-	CHAR	rssi0 = pRxWI->RSSI0;
-	CHAR	rssi1 = pRxWI->RSSI1;
-	CHAR	rssi2 = pRxWI->RSSI2;
-
-	if (rssi0 != 0)
-	{
-		pRssi->LastRssi0	= ConvertToRssi(pAd, (CHAR)rssi0, RSSI_0);
-		pRssi->AvgRssi0X8	= (pRssi->AvgRssi0X8 - pRssi->AvgRssi0) + pRssi->LastRssi0;
-		pRssi->AvgRssi0	= pRssi->AvgRssi0X8 >> 3;
-	}
-
-	if (rssi1 != 0)
-	{
-		pRssi->LastRssi1	= ConvertToRssi(pAd, (CHAR)rssi1, RSSI_1);
-		pRssi->AvgRssi1X8	= (pRssi->AvgRssi1X8 - pRssi->AvgRssi1) + pRssi->LastRssi1;
-		pRssi->AvgRssi1	= pRssi->AvgRssi1X8 >> 3;
-	}
-
-	if (rssi2 != 0)
-	{
-		pRssi->LastRssi2	= ConvertToRssi(pAd, (CHAR)rssi2, RSSI_2);
-		pRssi->AvgRssi2X8  = (pRssi->AvgRssi2X8 - pRssi->AvgRssi2) + pRssi->LastRssi2;
-		pRssi->AvgRssi2 = pRssi->AvgRssi2X8 >> 3;
-	}
-}
-
-
-
-// Normal legacy Rx packet indication
-VOID Indicate_Legacy_Packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID)
-{
-	PNDIS_PACKET	pRxPacket = pRxBlk->pRxPacket;
-	UCHAR			Header802_3[LENGTH_802_3];
-
-	// 1. get 802.3 Header
-	// 2. remove LLC
-	//		a. pointer pRxBlk->pData to payload
-	//      b. modify pRxBlk->DataSize
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
-#endif // CONFIG_STA_SUPPORT //
-
-	if (pRxBlk->DataSize > MAX_RX_PKT_LEN)
-	{
-
-		// release packet
-		RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
-		return;
-	}
-
-
-	STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
-
-
-	wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
-
-	//
-	// pass this 802.3 packet to upper layer or forward this packet to WM directly
-	//
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxPacket, FromWhichBSSID);
-#endif // CONFIG_STA_SUPPORT //
-
-}
-
-
-// Normal, AMPDU or AMSDU
-VOID CmmRxnonRalinkFrameIndicate(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID)
-{
-#ifdef DOT11_N_SUPPORT
-	if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
-	{
-		Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
-	}
-	else
-#endif // DOT11_N_SUPPORT //
-	{
-#ifdef DOT11_N_SUPPORT
-		if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
-		{
-			// handle A-MSDU
-			Indicate_AMSDU_Packet(pAd, pRxBlk, FromWhichBSSID);
-		}
-		else
-#endif // DOT11_N_SUPPORT //
-		{
-			Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
-		}
-	}
-}
-
-
-VOID CmmRxRalinkFrameIndicate(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MAC_TABLE_ENTRY	*pEntry,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID)
-{
-	UCHAR			Header802_3[LENGTH_802_3];
-	UINT16			Msdu2Size;
-	UINT16			Payload1Size, Payload2Size;
-	PUCHAR			pData2;
-	PNDIS_PACKET	pPacket2 = NULL;
-
-
-
-	Msdu2Size = *(pRxBlk->pData) + (*(pRxBlk->pData+1) << 8);
-
-	if ((Msdu2Size <= 1536) && (Msdu2Size < pRxBlk->DataSize))
-	{
-		/* skip two byte MSDU2 len */
-		pRxBlk->pData += 2;
-		pRxBlk->DataSize -= 2;
-	}
-	else
-	{
-		// release packet
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
-		return;
-	}
-
-	// get 802.3 Header and  remove LLC
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
-#endif // CONFIG_STA_SUPPORT //
-
-
-	ASSERT(pRxBlk->pRxPacket);
-
-	// Ralink Aggregation frame
-	pAd->RalinkCounters.OneSecRxAggregationCount ++;
-	Payload1Size = pRxBlk->DataSize - Msdu2Size;
-	Payload2Size = Msdu2Size - LENGTH_802_3;
-
-	pData2 = pRxBlk->pData + Payload1Size + LENGTH_802_3;
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		pPacket2 = duplicate_pkt(pAd, (pData2-LENGTH_802_3), LENGTH_802_3, pData2, Payload2Size, FromWhichBSSID);
-#endif // CONFIG_STA_SUPPORT //
-
-	if (!pPacket2)
-	{
-		// release packet
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
-		return;
-	}
-
-	// update payload size of 1st packet
-	pRxBlk->DataSize = Payload1Size;
-	wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxBlk->pRxPacket, FromWhichBSSID);
-#endif // CONFIG_STA_SUPPORT //
-
-	if (pPacket2)
-	{
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-			ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket2, FromWhichBSSID);
-#endif // CONFIG_STA_SUPPORT //
-	}
-}
-
-
-#define RESET_FRAGFRAME(_fragFrame) \
-	{								\
-		_fragFrame.RxSize = 0;		\
-		_fragFrame.Sequence = 0;	\
-		_fragFrame.LastFrag = 0;	\
-		_fragFrame.Flags = 0;		\
-	}
-
-
-PNDIS_PACKET RTMPDeFragmentDataFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk)
-{
-	PHEADER_802_11	pHeader = pRxBlk->pHeader;
-	PNDIS_PACKET	pRxPacket = pRxBlk->pRxPacket;
-	UCHAR			*pData = pRxBlk->pData;
-	USHORT			DataSize = pRxBlk->DataSize;
-	PNDIS_PACKET	pRetPacket = NULL;
-	UCHAR			*pFragBuffer = NULL;
-	BOOLEAN			bReassDone = FALSE;
-	UCHAR			HeaderRoom = 0;
-
-
-	ASSERT(pHeader);
-
-	HeaderRoom = pData - (UCHAR *)pHeader;
-
-	// Re-assemble the fragmented packets
-	if (pHeader->Frag == 0)		// Frag. Number is 0 : First frag or only one pkt
-	{
-		// the first pkt of fragment, record it.
-		if (pHeader->FC.MoreFrag)
-		{
-			ASSERT(pAd->FragFrame.pFragPacket);
-			pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
-			pAd->FragFrame.RxSize   = DataSize + HeaderRoom;
-			NdisMoveMemory(pFragBuffer,	 pHeader, pAd->FragFrame.RxSize);
-			pAd->FragFrame.Sequence = pHeader->Sequence;
-			pAd->FragFrame.LastFrag = pHeader->Frag;	   // Should be 0
-			ASSERT(pAd->FragFrame.LastFrag == 0);
-			goto done;	// end of processing this frame
-		}
-	}
-	else	//Middle & End of fragment
-	{
-		if ((pHeader->Sequence != pAd->FragFrame.Sequence) ||
-			(pHeader->Frag != (pAd->FragFrame.LastFrag + 1)))
-		{
-			// Fragment is not the same sequence or out of fragment number order
-			// Reset Fragment control blk
-			RESET_FRAGFRAME(pAd->FragFrame);
-			DBGPRINT(RT_DEBUG_ERROR, ("Fragment is not the same sequence or out of fragment number order.\n"));
-			goto done; // give up this frame
-		}
-		else if ((pAd->FragFrame.RxSize + DataSize) > MAX_FRAME_SIZE)
-		{
-			// Fragment frame is too large, it exeeds the maximum frame size.
-			// Reset Fragment control blk
-			RESET_FRAGFRAME(pAd->FragFrame);
-			DBGPRINT(RT_DEBUG_ERROR, ("Fragment frame is too large, it exeeds the maximum frame size.\n"));
-			goto done; // give up this frame
-		}
-
-        //
-		// Broadcom AP(BCM94704AGR) will send out LLC in fragment's packet, LLC only can accpet at first fragment.
-		// In this case, we will dropt it.
-		//
-		if (NdisEqualMemory(pData, SNAP_802_1H, sizeof(SNAP_802_1H)))
-		{
-			DBGPRINT(RT_DEBUG_ERROR, ("Find another LLC at Middle or End fragment(SN=%d, Frag=%d)\n", pHeader->Sequence, pHeader->Frag));
-			goto done; // give up this frame
-		}
-
-		pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
-
-		// concatenate this fragment into the re-assembly buffer
-		NdisMoveMemory((pFragBuffer + pAd->FragFrame.RxSize), pData, DataSize);
-		pAd->FragFrame.RxSize  += DataSize;
-		pAd->FragFrame.LastFrag = pHeader->Frag;	   // Update fragment number
-
-		// Last fragment
-		if (pHeader->FC.MoreFrag == FALSE)
-		{
-			bReassDone = TRUE;
-		}
-	}
-
-done:
-	// always release rx fragmented packet
-	RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
-
-	// return defragmented packet if packet is reassembled completely
-	// otherwise return NULL
-	if (bReassDone)
-	{
-		PNDIS_PACKET pNewFragPacket;
-
-		// allocate a new packet buffer for fragment
-		pNewFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
-		if (pNewFragPacket)
-		{
-			// update RxBlk
-			pRetPacket = pAd->FragFrame.pFragPacket;
-			pAd->FragFrame.pFragPacket = pNewFragPacket;
-			pRxBlk->pHeader = (PHEADER_802_11) GET_OS_PKT_DATAPTR(pRetPacket);
-			pRxBlk->pData = (UCHAR *)pRxBlk->pHeader + HeaderRoom;
-			pRxBlk->DataSize = pAd->FragFrame.RxSize - HeaderRoom;
-			pRxBlk->pRxPacket = pRetPacket;
-		}
-		else
-		{
-			RESET_FRAGFRAME(pAd->FragFrame);
-		}
-	}
-
-	return pRetPacket;
-}
-
-
-VOID Indicate_AMSDU_Packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID)
-{
-	UINT			nMSDU;
-
-	update_os_packet_info(pAd, pRxBlk, FromWhichBSSID);
-	RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
-	nMSDU = deaggregate_AMSDU_announce(pAd, pRxBlk->pRxPacket, pRxBlk->pData, pRxBlk->DataSize);
-}
-
-VOID Indicate_EAPOL_Packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID)
-{
-	MAC_TABLE_ENTRY *pEntry = NULL;
-
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		pEntry = &pAd->MacTab.Content[BSSID_WCID];
-		STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
-		return;
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	if (pEntry == NULL)
-	{
-		DBGPRINT(RT_DEBUG_WARN, ("Indicate_EAPOL_Packet: drop and release the invalid packet.\n"));
-		// release packet
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
-		return;
-	}
-}
-
-#define BCN_TBTT_OFFSET		64	//defer 64 us
-VOID ReSyncBeaconTime(
-	IN  PRTMP_ADAPTER   pAd)
-{
-
-	UINT32  Offset;
-
-
-	Offset = (pAd->TbttTickCount) % (BCN_TBTT_OFFSET);
-
-	pAd->TbttTickCount++;
-
-	//
-	// The updated BeaconInterval Value will affect Beacon Interval after two TBTT
-	// beacasue the original BeaconInterval had been loaded into next TBTT_TIMER
-	//
-	if (Offset == (BCN_TBTT_OFFSET-2))
-	{
-		BCN_TIME_CFG_STRUC csr;
-		RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
-		csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod << 4) - 1 ;	// ASIC register in units of 1/16 TU = 64us
-		RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
-	}
-	else
-	{
-		if (Offset == (BCN_TBTT_OFFSET-1))
-		{
-			BCN_TIME_CFG_STRUC csr;
-
-			RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
-			csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod) << 4; // ASIC register in units of 1/16 TU
-			RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
-		}
-	}
-}
diff --git a/drivers/staging/rt3090/common/cmm_data_pci.c b/drivers/staging/rt3090/common/cmm_data_pci.c
deleted file mode 100644
index 084f819..0000000
--- a/drivers/staging/rt3090/common/cmm_data_pci.c
+++ /dev/null
@@ -1,1576 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-*/
-
-/*
-   All functions in this file must be PCI-depended, or you should out your function
-	in other files.
-
-*/
-#include "../rt_config.h"
-
-
-USHORT RtmpPCI_WriteTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	BOOLEAN			bIsLast,
-	OUT	USHORT			*FreeNumber)
-{
-
-	UCHAR			*pDMAHeaderBufVA;
-	USHORT			TxIdx, RetTxIdx;
-	PTXD_STRUC		pTxD;
-	UINT32			BufBasePaLow;
-	PRTMP_TX_RING	pTxRing;
-	USHORT			hwHeaderLen;
-
-	//
-	// get Tx Ring Resource
-	//
-	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
-	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
-	pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
-	BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
-
-	// copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
-	if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
-	{
-		//hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD;
-		hwHeaderLen = pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
-	}
-	else
-	{
-		//hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
-		hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
-	}
-	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
-
-	pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
-	pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
-
-	//
-	// build Tx Descriptor
-	//
-
-	pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
-	NdisZeroMemory(pTxD, TXD_SIZE);
-
-	pTxD->SDPtr0 = BufBasePaLow;
-	pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; // include padding
-	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
-	pTxD->SDLen1 = pTxBlk->SrcBufLen;
-	pTxD->LastSec0 = 0;
-	pTxD->LastSec1 = (bIsLast) ? 1 : 0;
-
-	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
-
-	RetTxIdx = TxIdx;
-	//
-	// Update Tx index
-	//
-	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
-	pTxRing->TxCpuIdx = TxIdx;
-
-	*FreeNumber -= 1;
-
-	return RetTxIdx;
-}
-
-
-USHORT RtmpPCI_WriteSingleTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	BOOLEAN			bIsLast,
-	OUT	USHORT			*FreeNumber)
-{
-
-	UCHAR			*pDMAHeaderBufVA;
-	USHORT			TxIdx, RetTxIdx;
-	PTXD_STRUC		pTxD;
-#ifdef RT_BIG_ENDIAN
-    PTXD_STRUC      pDestTxD;
-    TXD_STRUC       TxD;
-#endif
-	UINT32			BufBasePaLow;
-	PRTMP_TX_RING	pTxRing;
-	USHORT			hwHeaderLen;
-
-	//
-	// get Tx Ring Resource
-	//
-	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
-	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
-	pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
-	BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
-
-	// copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
-	//hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
-	hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
-
-	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
-
-	pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
-	pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
-
-	//
-	// build Tx Descriptor
-	//
-#ifndef RT_BIG_ENDIAN
-	pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
-#else
-	pDestTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
-	TxD = *pDestTxD;
-	pTxD = &TxD;
-#endif
-	NdisZeroMemory(pTxD, TXD_SIZE);
-
-	pTxD->SDPtr0 = BufBasePaLow;
-	pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; // include padding
-	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);;
-	pTxD->SDLen1 = pTxBlk->SrcBufLen;
-	pTxD->LastSec0 = 0;
-	pTxD->LastSec1 = (bIsLast) ? 1 : 0;
-
-	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
-#ifdef RT_BIG_ENDIAN
-	RTMPWIEndianChange((PUCHAR)(pDMAHeaderBufVA + TXINFO_SIZE), TYPE_TXWI);
-	RTMPFrameEndianChange(pAd, (PUCHAR)(pDMAHeaderBufVA + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
-	RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-	WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
-#endif // RT_BIG_ENDIAN //
-
-	RetTxIdx = TxIdx;
-	//
-	// Update Tx index
-	//
-	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
-	pTxRing->TxCpuIdx = TxIdx;
-
-	*FreeNumber -= 1;
-
-	return RetTxIdx;
-}
-
-
-USHORT RtmpPCI_WriteMultiTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	UCHAR			frameNum,
-	OUT	USHORT			*FreeNumber)
-{
-	BOOLEAN bIsLast;
-	UCHAR			*pDMAHeaderBufVA;
-	USHORT			TxIdx, RetTxIdx;
-	PTXD_STRUC		pTxD;
-#ifdef RT_BIG_ENDIAN
-    PTXD_STRUC      pDestTxD;
-    TXD_STRUC       TxD;
-#endif
-	UINT32			BufBasePaLow;
-	PRTMP_TX_RING	pTxRing;
-	USHORT			hwHdrLen;
-	UINT32			firstDMALen;
-
-	bIsLast = ((frameNum == (pTxBlk->TotalFrameNum - 1)) ? 1 : 0);
-
-	//
-	// get Tx Ring Resource
-	//
-	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
-	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
-	pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
-	BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
-
-	if (frameNum == 0)
-	{
-		// copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
-		if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
-			//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD;
-			hwHdrLen = pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
-		else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
-			//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD;
-			hwHdrLen = pTxBlk->MpduHeaderLen - LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + LENGTH_ARALINK_HEADER_FIELD;
-		else
-			//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
-			hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
-
-		firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
-	}
-	else
-	{
-		firstDMALen = pTxBlk->MpduHeaderLen;
-	}
-
-	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen);
-
-	pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
-	pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
-
-	//
-	// build Tx Descriptor
-	//
-#ifndef RT_BIG_ENDIAN
-	pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
-#else
-	pDestTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
-	TxD = *pDestTxD;
-	pTxD = &TxD;
-#endif
-	NdisZeroMemory(pTxD, TXD_SIZE);
-
-	pTxD->SDPtr0 = BufBasePaLow;
-	pTxD->SDLen0 = firstDMALen; // include padding
-	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);;
-	pTxD->SDLen1 = pTxBlk->SrcBufLen;
-	pTxD->LastSec0 = 0;
-	pTxD->LastSec1 = (bIsLast) ? 1 : 0;
-
-	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
-
-#ifdef RT_BIG_ENDIAN
-	if (frameNum == 0)
-		RTMPFrameEndianChange(pAd, (PUCHAR)(pDMAHeaderBufVA+ TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
-
-	if (frameNum != 0)
-		RTMPWIEndianChange((PUCHAR)(pDMAHeaderBufVA + TXINFO_SIZE), TYPE_TXWI);
-
-	RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-	WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
-#endif // RT_BIG_ENDIAN //
-
-	RetTxIdx = TxIdx;
-	//
-	// Update Tx index
-	//
-	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
-	pTxRing->TxCpuIdx = TxIdx;
-
-	*FreeNumber -= 1;
-
-	return RetTxIdx;
-
-}
-
-
-VOID RtmpPCI_FinalWriteTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	USHORT			totalMPDUSize,
-	IN	USHORT			FirstTxIdx)
-{
-
-	PTXWI_STRUC		pTxWI;
-	PRTMP_TX_RING	pTxRing;
-
-	//
-	// get Tx Ring Resource
-	//
-	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
-	pTxWI = (PTXWI_STRUC) pTxRing->Cell[FirstTxIdx].DmaBuf.AllocVa;
-	pTxWI->MPDUtotalByteCount = totalMPDUSize;
-#ifdef RT_BIG_ENDIAN
-	RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
-#endif // RT_BIG_ENDIAN //
-
-}
-
-
-VOID RtmpPCIDataLastTxIdx(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			QueIdx,
-	IN	USHORT			LastTxIdx)
-{
-	PTXD_STRUC		pTxD;
-#ifdef RT_BIG_ENDIAN
-    PTXD_STRUC      pDestTxD;
-    TXD_STRUC       TxD;
-#endif
-	PRTMP_TX_RING	pTxRing;
-
-	//
-	// get Tx Ring Resource
-	//
-	pTxRing = &pAd->TxRing[QueIdx];
-
-	//
-	// build Tx Descriptor
-	//
-#ifndef RT_BIG_ENDIAN
-	pTxD = (PTXD_STRUC) pTxRing->Cell[LastTxIdx].AllocVa;
-#else
-	pDestTxD = (PTXD_STRUC) pTxRing->Cell[LastTxIdx].AllocVa;
-	TxD = *pDestTxD;
-	pTxD = &TxD;
-#endif
-
-	pTxD->LastSec1 = 1;
-
-#ifdef RT_BIG_ENDIAN
-	RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-	WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
-#endif // RT_BIG_ENDIAN //
-
-}
-
-
-USHORT	RtmpPCI_WriteFragTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	UCHAR			fragNum,
-	OUT	USHORT			*FreeNumber)
-{
-	UCHAR			*pDMAHeaderBufVA;
-	USHORT			TxIdx, RetTxIdx;
-	PTXD_STRUC		pTxD;
-#ifdef RT_BIG_ENDIAN
-    PTXD_STRUC      pDestTxD;
-    TXD_STRUC       TxD;
-#endif
-	UINT32			BufBasePaLow;
-	PRTMP_TX_RING	pTxRing;
-	USHORT			hwHeaderLen;
-	UINT32			firstDMALen;
-
-	//
-	// Get Tx Ring Resource
-	//
-	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
-	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
-	pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
-	BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
-
-	//
-	// Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
-	//
-	//hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
-	hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
-
-	firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen;
-	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen);
-
-
-	//
-	// Build Tx Descriptor
-	//
-#ifndef RT_BIG_ENDIAN
-	pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
-#else
-	pDestTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
-	TxD = *pDestTxD;
-	pTxD = &TxD;
-#endif
-	NdisZeroMemory(pTxD, TXD_SIZE);
-
-	if (fragNum == pTxBlk->TotalFragNum)
-	{
-		pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
-		pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
-	}
-
-	pTxD->SDPtr0 = BufBasePaLow;
-	pTxD->SDLen0 = firstDMALen; // include padding
-	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
-	pTxD->SDLen1 = pTxBlk->SrcBufLen;
-	pTxD->LastSec0 = 0;
-	pTxD->LastSec1 = 1;
-
-	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
-
-#ifdef RT_BIG_ENDIAN
-	RTMPWIEndianChange((PUCHAR)(pDMAHeaderBufVA + TXINFO_SIZE), TYPE_TXWI);
-	RTMPFrameEndianChange(pAd, (PUCHAR)(pDMAHeaderBufVA + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
-	RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-    WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
-#endif // RT_BIG_ENDIAN //
-
-	RetTxIdx = TxIdx;
-	pTxBlk->Priv += pTxBlk->SrcBufLen;
-
-	//
-	// Update Tx index
-	//
-	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
-	pTxRing->TxCpuIdx = TxIdx;
-
-	*FreeNumber -= 1;
-
-	return RetTxIdx;
-
-}
-
-
-/*
-	Must be run in Interrupt context
-	This function handle PCI specific TxDesc and cpu index update and kick the packet out.
- */
-int RtmpPCIMgmtKickOut(
-	IN RTMP_ADAPTER		*pAd,
-	IN UCHAR			QueIdx,
-	IN PNDIS_PACKET		pPacket,
-	IN PUCHAR			pSrcBufVA,
-	IN UINT				SrcBufLen)
-{
-	PTXD_STRUC		pTxD;
-#ifdef RT_BIG_ENDIAN
-    PTXD_STRUC      pDestTxD;
-    TXD_STRUC       TxD;
-#endif
-	ULONG			SwIdx = pAd->MgmtRing.TxCpuIdx;
-
-#ifdef RT_BIG_ENDIAN
-    pDestTxD  = (PTXD_STRUC)pAd->MgmtRing.Cell[SwIdx].AllocVa;
-    TxD = *pDestTxD;
-    pTxD = &TxD;
-    RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-#else
-	pTxD  = (PTXD_STRUC) pAd->MgmtRing.Cell[SwIdx].AllocVa;
-#endif
-
-	pAd->MgmtRing.Cell[SwIdx].pNdisPacket = pPacket;
-	pAd->MgmtRing.Cell[SwIdx].pNextNdisPacket = NULL;
-
-	RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_MGMT);
-	pTxD->LastSec0 = 1;
-	pTxD->LastSec1 = 1;
-	pTxD->DMADONE = 0;
-	pTxD->SDLen1 = 0;
-	pTxD->SDPtr0 = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
-	pTxD->SDLen0 = SrcBufLen;
-
-#ifdef RT_BIG_ENDIAN
-	RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-    WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
-#endif
-
-//==================================================================
-/*	DBGPRINT_RAW(RT_DEBUG_TRACE, ("MLMEHardTransmit\n"));
-	for (i = 0; i < (TXWI_SIZE+24); i++)
-	{
-
-		DBGPRINT_RAW(RT_DEBUG_TRACE, ("%x:", *(pSrcBufVA+i)));
-		if ( i%4 == 3)
-			DBGPRINT_RAW(RT_DEBUG_TRACE, (" :: "));
-		if ( i%16 == 15)
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n      "));
-	}
-	DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n      "));*/
-//=======================================================================
-
-	pAd->RalinkCounters.KickTxCount++;
-	pAd->RalinkCounters.OneSecTxDoneCount++;
-
-	// Increase TX_CTX_IDX, but write to register later.
-	INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
-
-	RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX,  pAd->MgmtRing.TxCpuIdx);
-
-	return 0;
-}
-
-
-#ifdef CONFIG_STA_SUPPORT
-/*
-	========================================================================
-
-	Routine Description:
-		Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
-
-	Arguments:
-		pRxD		Pointer to the Rx descriptor
-
-	Return Value:
-		NDIS_STATUS_SUCCESS	No err
-		NDIS_STATUS_FAILURE	Error
-
-	Note:
-
-	========================================================================
-*/
-NDIS_STATUS RTMPCheckRxError(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	PHEADER_802_11		pHeader,
-	IN	PRXWI_STRUC		pRxWI,
-	IN  PRT28XX_RXD_STRUC	pRxD)
-{
-	PCIPHER_KEY pWpaKey;
-	INT dBm;
-
-	// Phy errors & CRC errors
-	if (/*(pRxD->PhyErr) ||*/ (pRxD->Crc))
-	{
-		// Check RSSI for Noise Hist statistic collection.
-		dBm = (INT) (pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
-		if (dBm <= -87)
-			pAd->StaCfg.RPIDensity[0] += 1;
-		else if (dBm <= -82)
-			pAd->StaCfg.RPIDensity[1] += 1;
-		else if (dBm <= -77)
-			pAd->StaCfg.RPIDensity[2] += 1;
-		else if (dBm <= -72)
-			pAd->StaCfg.RPIDensity[3] += 1;
-		else if (dBm <= -67)
-			pAd->StaCfg.RPIDensity[4] += 1;
-		else if (dBm <= -62)
-			pAd->StaCfg.RPIDensity[5] += 1;
-		else if (dBm <= -57)
-			pAd->StaCfg.RPIDensity[6] += 1;
-		else if (dBm > -57)
-			pAd->StaCfg.RPIDensity[7] += 1;
-
-		return(NDIS_STATUS_FAILURE);
-	}
-
-	// Add Rx size to channel load counter, we should ignore error counts
-	pAd->StaCfg.CLBusyBytes += (pRxD->SDL0 + 14);
-
-	// Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics
-	if (pHeader != NULL)
-	{
-		if (pHeader->FC.ToDs)
-		{
-			return(NDIS_STATUS_FAILURE);
-		}
-	}
-
-	// Drop not U2M frames, cant's drop here because we will drop beacon in this case
-	// I am kind of doubting the U2M bit operation
-	// if (pRxD->U2M == 0)
-	//	return(NDIS_STATUS_FAILURE);
-
-	// drop decyption fail frame
-	if (pRxD->CipherErr)
-	{
-		if (pRxD->CipherErr == 2)
-			{DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: ICV ok but MICErr "));}
-		else if (pRxD->CipherErr == 1)
-			{DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: ICV Err "));}
-		else if (pRxD->CipherErr == 3)
-			DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: Key not valid "));
-
-        if (((pRxD->CipherErr & 1) == 1) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
-            RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-
-		DBGPRINT_RAW(RT_DEBUG_TRACE,(" %d (len=%d, Mcast=%d, MyBss=%d, Wcid=%d, KeyId=%d)\n",
-			pRxD->CipherErr,
-			pRxD->SDL0,
-			pRxD->Mcast | pRxD->Bcast,
-			pRxD->MyBss,
-			pRxWI->WirelessCliID,
-//			CipherName[pRxD->CipherAlg],
-			pRxWI->KeyIndex));
-
-		//
-		// MIC Error
-		//
-		if (pRxD->CipherErr == 2)
-		{
-			pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
-#ifdef WPA_SUPPLICANT_SUPPORT
-            if (pAd->StaCfg.WpaSupplicantUP)
-                WpaSendMicFailureToWpaSupplicant(pAd,
-                                   (pWpaKey->Type == PAIRWISEKEY) ? TRUE:FALSE);
-            else
-#endif // WPA_SUPPLICANT_SUPPORT //
-			    RTMPReportMicError(pAd, pWpaKey);
-
-            if (((pRxD->CipherErr & 2) == 2) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
-                RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-
-			DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n"));
-		}
-
-		if (pHeader == NULL)
-			return(NDIS_STATUS_SUCCESS);
-		/*if ((pRxD->CipherAlg == CIPHER_AES) &&
-			(pHeader->Sequence == pAd->FragFrame.Sequence))
-		{
-			//
-			// Acceptable since the First FragFrame no CipherErr problem.
-			//
-			return(NDIS_STATUS_SUCCESS);
-		}*/
-
-		return(NDIS_STATUS_FAILURE);
-	}
-
-	return(NDIS_STATUS_SUCCESS);
-}
-#endif // CONFIG_STA_SUPPORT //
-
-
-BOOLEAN  RTMPFreeTXDUponTxDmaDone(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			QueIdx)
-{
-	PRTMP_TX_RING pTxRing;
-	PTXD_STRUC	  pTxD;
-#ifdef	RT_BIG_ENDIAN
-    PTXD_STRUC      pDestTxD;
-#endif
-	PNDIS_PACKET  pPacket;
-	UCHAR	FREE = 0;
-	TXD_STRUC	TxD, *pOriTxD;
-	//ULONG		IrqFlags;
-	BOOLEAN			bReschedule = FALSE;
-
-
-	ASSERT(QueIdx < NUM_OF_TX_RING);
-	pTxRing = &pAd->TxRing[QueIdx];
-
-	RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF, &pTxRing->TxDmaIdx);
-	while (pTxRing->TxSwFreeIdx != pTxRing->TxDmaIdx)
-	{
-//		RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-#ifdef RALINK_ATE
-#ifdef RALINK_28xx_QA
-		PHEADER_802_11	pHeader80211;
-
-		if ((ATE_ON(pAd)) && (pAd->ate.bQATxStart == TRUE))
-		{
-			if (pAd->ate.QID == QueIdx)
-			{
-				pAd->ate.TxDoneCount++;
-				pAd->RalinkCounters.KickTxCount++;
-
-				/* always use QID_AC_BE and FIFO_EDCA */
-				ASSERT(pAd->ate.QID == 0);
-				pAd->ate.TxAc0++;
-
-				FREE++;
-#ifndef RT_BIG_ENDIAN
-				pTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
-				pOriTxD = pTxD;
-		        NdisMoveMemory(&TxD, pTxD, sizeof(TXD_STRUC));
-				pTxD = &TxD;
-#else
-		        pDestTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
-		        pOriTxD = pDestTxD ;
-		        TxD = *pDestTxD;
-		        pTxD = &TxD;
-		        RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-#endif
-				pTxD->DMADONE = 0;
-
-				pHeader80211 = pTxRing->Cell[pTxRing->TxSwFreeIdx].DmaBuf.AllocVa + sizeof(TXWI_STRUC);
-#ifdef RT_BIG_ENDIAN
-				RTMPFrameEndianChange(pAd, (PUCHAR)pHeader80211, DIR_READ, FALSE);
-#endif
-				pHeader80211->Sequence = ++pAd->ate.seq;
-#ifdef RT_BIG_ENDIAN
-				RTMPFrameEndianChange(pAd, (PUCHAR)pHeader80211, DIR_WRITE, FALSE);
-#endif
-
-				if  ((pAd->ate.bQATxStart == TRUE) && (pAd->ate.Mode & ATE_TXFRAME) && (pAd->ate.TxDoneCount < pAd->ate.TxCount))
-				{
-					pAd->RalinkCounters.TransmittedByteCount +=  (pTxD->SDLen1 + pTxD->SDLen0);
-					pAd->RalinkCounters.OneSecTransmittedByteCount += (pTxD->SDLen1 + pTxD->SDLen0);
-					pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx] ++;
-					INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
-
-					/* get TX_DTX_IDX again */
-					RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF ,  &pTxRing->TxDmaIdx);
-					goto kick_out;
-				}
-				else if ((pAd->ate.TxStatus == 1)/* or (pAd->ate.bQATxStart == TRUE) ??? */ && (pAd->ate.TxDoneCount == pAd->ate.TxCount))
-				{
-					DBGPRINT(RT_DEBUG_TRACE,("all Tx is done\n"));
-
-					// Tx status enters idle mode.
-					pAd->ate.TxStatus = 0;
-				}
-				else if (!(pAd->ate.Mode & ATE_TXFRAME))
-				{
-					/* not complete sending yet, but someone press the Stop TX botton */
-					DBGPRINT(RT_DEBUG_ERROR,("not complete sending yet, but someone pressed the Stop TX bottom\n"));
-					DBGPRINT(RT_DEBUG_ERROR,("pAd->ate.Mode = 0x%02x\n", pAd->ate.Mode));
-				}
-				else
-				{
-					DBGPRINT(RT_DEBUG_OFF,("pTxRing->TxSwFreeIdx = %d\n", pTxRing->TxSwFreeIdx));
-				}
-
-#ifndef RT_BIG_ENDIAN
-			NdisMoveMemory(pOriTxD, pTxD, sizeof(TXD_STRUC));
-#else
-			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-			*pDestTxD = TxD;
-#endif // RT_BIG_ENDIAN //
-
-				INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
-				continue;
-			}
-		}
-#endif // RALINK_28xx_QA //
-#endif // RALINK_ATE //
-
-		// static rate also need NICUpdateFifoStaCounters() function.
-		//if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
-			NICUpdateFifoStaCounters(pAd);
-
-		/* Note : If (pAd->ate.bQATxStart == TRUE), we will never reach here. */
-		FREE++;
-#ifndef RT_BIG_ENDIAN
-                pTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
-		pOriTxD = pTxD;
-                NdisMoveMemory(&TxD, pTxD, sizeof(TXD_STRUC));
-		pTxD = &TxD;
-#else
-        pDestTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
-        pOriTxD = pDestTxD ;
-        TxD = *pDestTxD;
-        pTxD = &TxD;
-        RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-#endif
-
-		pTxD->DMADONE = 0;
-
-
-#ifdef RALINK_ATE
-		/* Execution of this block is not allowed when ATE is running. */
-		if (!(ATE_ON(pAd)))
-#endif // RALINK_ATE //
-		{
-			pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket;
-			if (pPacket)
-			{
-#ifdef CONFIG_5VT_ENHANCE
-				if (RTMP_GET_PACKET_5VT(pPacket))
-					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE);
-				else
-#endif // CONFIG_5VT_ENHANCE //
-					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-			}
-			//Always assign pNdisPacket as NULL after clear
-			pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket = NULL;
-
-			pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket;
-
-			ASSERT(pPacket == NULL);
-			if (pPacket)
-			{
-#ifdef CONFIG_5VT_ENHANCE
-				if (RTMP_GET_PACKET_5VT(pPacket))
-					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE);
-				else
-#endif // CONFIG_5VT_ENHANCE //
-					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-			}
-			//Always assign pNextNdisPacket as NULL after clear
-			pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL;
-		}
-
-		pAd->RalinkCounters.TransmittedByteCount +=  (pTxD->SDLen1 + pTxD->SDLen0);
-		pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx] ++;
-		INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
-		/* get tx_tdx_idx again */
-		RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF ,  &pTxRing->TxDmaIdx);
-#ifdef RT_BIG_ENDIAN
-        RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-        *pDestTxD = TxD;
-#else
-        NdisMoveMemory(pOriTxD, pTxD, sizeof(TXD_STRUC));
-#endif
-
-#ifdef RALINK_ATE
-#ifdef RALINK_28xx_QA
-kick_out:
-#endif // RALINK_28xx_QA //
-
-		/*
-			ATE_TXCONT mode also need to send some normal frames, so let it in.
-			ATE_STOP must be changed not to be 0xff
-			to prevent it from running into this block.
-		*/
-		if ((pAd->ate.Mode & ATE_TXFRAME) && (pAd->ate.QID == QueIdx))
-		{
-			// TxDoneCount++ has been done if QA is used.
-			if (pAd->ate.bQATxStart == FALSE)
-			{
-				pAd->ate.TxDoneCount++;
-			}
-			if (((pAd->ate.TxCount - pAd->ate.TxDoneCount + 1) >= TX_RING_SIZE))
-			{
-				/* Note : We increase TxCpuIdx here, not TxSwFreeIdx ! */
-				INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE);
-#ifndef RT_BIG_ENDIAN
-				pTxD = (PTXD_STRUC) (pTxRing->Cell[pAd->TxRing[QueIdx].TxCpuIdx].AllocVa);
-				pOriTxD = pTxD;
-		        NdisMoveMemory(&TxD, pTxD, sizeof(TXD_STRUC));
-				pTxD = &TxD;
-#else
-		        pDestTxD = (PTXD_STRUC) (pTxRing->Cell[pAd->TxRing[QueIdx].TxCpuIdx].AllocVa);
-		        pOriTxD = pDestTxD ;
-		        TxD = *pDestTxD;
-		        pTxD = &TxD;
-		        RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-#endif
-				pTxD->DMADONE = 0;
-#ifndef RT_BIG_ENDIAN
-			NdisMoveMemory(pOriTxD, pTxD, sizeof(TXD_STRUC));
-#else
-			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-			*pDestTxD = TxD;
-#endif
-				// kick Tx-Ring
-				RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx * RINGREG_DIFF, pAd->TxRing[QueIdx].TxCpuIdx);
-				pAd->RalinkCounters.KickTxCount++;
-			}
-		}
-#endif // RALINK_ATE //
-//         RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-	}
-
-
-	return  bReschedule;
-
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Process TX Rings DMA Done interrupt, running in DPC level
-
-	Arguments:
-		Adapter		Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-BOOLEAN	RTMPHandleTxRingDmaDoneInterrupt(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	INT_SOURCE_CSR_STRUC TxRingBitmap)
-{
-//	UCHAR			Count = 0;
-    unsigned long	IrqFlags;
-	BOOLEAN			bReschedule = FALSE;
-
-	// Make sure Tx ring resource won't be used by other threads
-	//NdisAcquireSpinLock(&pAd->TxRingLock);
-
-	RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-
-	if (TxRingBitmap.field.Ac0DmaDone)
-		bReschedule = RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BE);
-/*
-	if (TxRingBitmap.field.HccaDmaDone)
-		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_HCCA);
-*/
-
-	if (TxRingBitmap.field.Ac3DmaDone)
-		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VO);
-
-	if (TxRingBitmap.field.Ac2DmaDone)
-		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VI);
-
-	if (TxRingBitmap.field.Ac1DmaDone)
-		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BK);
-
-	// Make sure to release Tx ring resource
-	//NdisReleaseSpinLock(&pAd->TxRingLock);
-	RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-
-	// Dequeue outgoing frames from TxSwQueue[] and process it
-	RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
-
-	return  bReschedule;
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Process MGMT ring DMA done interrupt, running in DPC level
-
-	Arguments:
-		pAd	Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPHandleMgmtRingDmaDoneInterrupt(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	PTXD_STRUC	 pTxD;
-#ifdef RT_BIG_ENDIAN
-    PTXD_STRUC      pDestTxD;
-    TXD_STRUC       TxD;
-#endif
-	PNDIS_PACKET pPacket;
-//	int		 i;
-	UCHAR	FREE = 0;
-	PRTMP_MGMT_RING pMgmtRing = &pAd->MgmtRing;
-
-	NdisAcquireSpinLock(&pAd->MgmtRingLock);
-
-	RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx);
-	while (pMgmtRing->TxSwFreeIdx!= pMgmtRing->TxDmaIdx)
-	{
-		FREE++;
-#ifdef RT_BIG_ENDIAN
-        pDestTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa);
-        TxD = *pDestTxD;
-        pTxD = &TxD;
-		RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-#else
-		pTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa);
-#endif
-		pTxD->DMADONE = 0;
-		pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket;
-
-
-		if (pPacket)
-		{
-			PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
-			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-		}
-		pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL;
-
-		pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket;
-		if (pPacket)
-		{
-			PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
-			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-		}
-		pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket = NULL;
-		INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE);
-
-#ifdef RT_BIG_ENDIAN
-        RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-        WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, TRUE, TYPE_TXD);
-#endif
-	}
-	NdisReleaseSpinLock(&pAd->MgmtRingLock);
-
-#ifdef CONFIG_STA_SUPPORT
-#endif // CONFIG_STA_SUPPORT //
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-	Arguments:
-		Adapter		Pointer to our adapter. Dequeue all power safe delayed braodcast frames after beacon.
-
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-VOID	RTMPHandleTBTTInterrupt(
-	IN PRTMP_ADAPTER pAd)
-{
-	{
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-		{
-		}
-	}
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-	Arguments:
-		pAd		Pointer to our adapter. Rewrite beacon content before next send-out.
-
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-VOID	RTMPHandlePreTBTTInterrupt(
-	IN PRTMP_ADAPTER pAd)
-{
-	{
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("RTMPHandlePreTBTTInterrupt...\n"));
-		}
-	}
-
-
-}
-
-VOID	RTMPHandleRxCoherentInterrupt(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	WPDMA_GLO_CFG_STRUC	GloCfg;
-
-	if (pAd == NULL)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("====> pAd is NULL, return.\n"));
-		return;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleRxCoherentInterrupt \n"));
-
-	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG , &GloCfg.word);
-
-	GloCfg.field.EnTXWriteBackDDONE = 0;
-	GloCfg.field.EnableRxDMA = 0;
-	GloCfg.field.EnableTxDMA = 0;
-	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
-
-	RTMPRingCleanUp(pAd, QID_AC_BE);
-	RTMPRingCleanUp(pAd, QID_AC_BK);
-	RTMPRingCleanUp(pAd, QID_AC_VI);
-	RTMPRingCleanUp(pAd, QID_AC_VO);
-	/*RTMPRingCleanUp(pAd, QID_HCCA);*/
-	RTMPRingCleanUp(pAd, QID_MGMT);
-	RTMPRingCleanUp(pAd, QID_RX);
-
-	RTMPEnableRxTx(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleRxCoherentInterrupt \n"));
-}
-
-
-
-
-VOID DBGPRINT_TX_RING(
-	IN PRTMP_ADAPTER  pAd,
-	IN UCHAR          QueIdx)
-{
-	UINT32		Ac0Base;
-	UINT32		Ac0HwIdx = 0, Ac0SwIdx = 0, AC0freeIdx;
-	int			i;
-//	PULONG		pTxD;
-	PULONG	ptemp;
-
-	DBGPRINT_RAW(RT_DEBUG_TRACE, ("=====================================================\n "  ));
-	switch (QueIdx)
-	{
-		case QID_AC_BE:
-			RTMP_IO_READ32(pAd, TX_BASE_PTR0, &Ac0Base);
-			RTMP_IO_READ32(pAd, TX_CTX_IDX0, &Ac0SwIdx);
-			RTMP_IO_READ32(pAd, TX_DTX_IDX0, &Ac0HwIdx);
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_BE DESCRIPTOR  \n "  ));
-			for (i=0;i<TX_RING_SIZE;i++)
-			{
-				ptemp= (PULONG)pAd->TxRing[QID_AC_BE].Cell[i].AllocVa;
-				DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
-			}
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
-			break;
-		case QID_AC_BK:
-			RTMP_IO_READ32(pAd, TX_BASE_PTR1, &Ac0Base);
-			RTMP_IO_READ32(pAd, TX_CTX_IDX1, &Ac0SwIdx);
-			RTMP_IO_READ32(pAd, TX_DTX_IDX1, &Ac0HwIdx);
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_BK DESCRIPTOR  \n "  ));
-			for (i=0;i<TX_RING_SIZE;i++)
-			{
-				ptemp= (PULONG)pAd->TxRing[QID_AC_BK].Cell[i].AllocVa;
-				DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
-			}
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
-			break;
-		case QID_AC_VI:
-			RTMP_IO_READ32(pAd, TX_BASE_PTR2, &Ac0Base);
-			RTMP_IO_READ32(pAd, TX_CTX_IDX2, &Ac0SwIdx);
-			RTMP_IO_READ32(pAd, TX_DTX_IDX2, &Ac0HwIdx);
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_VI DESCRIPTOR \n "  ));
-			for (i=0;i<TX_RING_SIZE;i++)
-			{
-				ptemp= (PULONG)pAd->TxRing[QID_AC_VI].Cell[i].AllocVa;
-				DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
-			}
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
-			break;
-		case QID_AC_VO:
-			RTMP_IO_READ32(pAd, TX_BASE_PTR3, &Ac0Base);
-			RTMP_IO_READ32(pAd, TX_CTX_IDX3, &Ac0SwIdx);
-			RTMP_IO_READ32(pAd, TX_DTX_IDX3, &Ac0HwIdx);
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_VO DESCRIPTOR \n "  ));
-			for (i=0;i<TX_RING_SIZE;i++)
-			{
-				ptemp= (PULONG)pAd->TxRing[QID_AC_VO].Cell[i].AllocVa;
-				DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
-			}
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
-			break;
-		case QID_MGMT:
-			RTMP_IO_READ32(pAd, TX_BASE_PTR5, &Ac0Base);
-			RTMP_IO_READ32(pAd, TX_CTX_IDX5, &Ac0SwIdx);
-			RTMP_IO_READ32(pAd, TX_DTX_IDX5, &Ac0HwIdx);
-			DBGPRINT_RAW(RT_DEBUG_TRACE, (" All QID_MGMT  DESCRIPTOR \n "  ));
-			for (i=0;i<MGMT_RING_SIZE;i++)
-			{
-				ptemp= (PULONG)pAd->MgmtRing.Cell[i].AllocVa;
-				DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
-			}
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
-			break;
-
-		default:
-			DBGPRINT_ERR(("DBGPRINT_TX_RING(Ring %d) not supported\n", QueIdx));
-			break;
-	}
-	AC0freeIdx = pAd->TxRing[QueIdx].TxSwFreeIdx;
-
-	DBGPRINT(RT_DEBUG_TRACE,("TxRing%d, TX_DTX_IDX=%d, TX_CTX_IDX=%d\n", QueIdx, Ac0HwIdx, Ac0SwIdx));
-	DBGPRINT_RAW(RT_DEBUG_TRACE,("	TxSwFreeIdx[%d]", AC0freeIdx));
-	DBGPRINT_RAW(RT_DEBUG_TRACE,("	pending-NDIS=%ld\n", pAd->RalinkCounters.PendingNdisPacketCount));
-
-
-}
-
-
-VOID DBGPRINT_RX_RING(
-	IN PRTMP_ADAPTER  pAd)
-{
-	UINT32		Ac0Base;
-	UINT32		Ac0HwIdx = 0, Ac0SwIdx = 0, AC0freeIdx;
-//	PULONG	 pTxD;
-	int			i;
-	UINT32	*ptemp;
-//	PRXD_STRUC		pRxD;
-
-	DBGPRINT_RAW(RT_DEBUG_TRACE, ("=====================================================\n "  ));
-	RTMP_IO_READ32(pAd, RX_BASE_PTR, &Ac0Base);
-	RTMP_IO_READ32(pAd, RX_CRX_IDX, &Ac0SwIdx);
-	RTMP_IO_READ32(pAd, RX_DRX_IDX, &Ac0HwIdx);
-	AC0freeIdx = pAd->RxRing.RxSwReadIdx;
-
-	DBGPRINT_RAW(RT_DEBUG_TRACE, ("All RX DSP  \n "  ));
-	for (i=0;i<RX_RING_SIZE;i++)
-	{
-		ptemp = (UINT32 *)pAd->RxRing.Cell[i].AllocVa;
-		DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08x: %08x: %08x: %08x\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
-	}
-	DBGPRINT(RT_DEBUG_TRACE,("RxRing, RX_DRX_IDX=%d, RX_CRX_IDX=%d \n", Ac0HwIdx, Ac0SwIdx));
-	DBGPRINT_RAW(RT_DEBUG_TRACE,("	RxSwReadIdx [%d]=", AC0freeIdx));
-	DBGPRINT_RAW(RT_DEBUG_TRACE,("	pending-NDIS=%ld\n", pAd->RalinkCounters.PendingNdisPacketCount));
-}
-
-
-PNDIS_PACKET GetPacketFromRxRing(
-	IN		PRTMP_ADAPTER	pAd,
-	OUT		PRT28XX_RXD_STRUC	pSaveRxD,
-	OUT		BOOLEAN			*pbReschedule,
-	IN OUT	UINT32			*pRxPending)
-{
-	PRXD_STRUC				pRxD;
-#ifdef RT_BIG_ENDIAN
-	PRXD_STRUC				pDestRxD;
-	RXD_STRUC				RxD;
-#endif
-	PNDIS_PACKET			pRxPacket = NULL;
-	PNDIS_PACKET			pNewPacket;
-	PVOID					AllocVa;
-	NDIS_PHYSICAL_ADDRESS	AllocPa;
-	BOOLEAN					bReschedule = FALSE;
-
-	RTMP_SEM_LOCK(&pAd->RxRingLock);
-
-	if (*pRxPending == 0)
-	{
-		// Get how may packets had been received
-		RTMP_IO_READ32(pAd, RX_DRX_IDX , &pAd->RxRing.RxDmaIdx);
-
-		if (pAd->RxRing.RxSwReadIdx == pAd->RxRing.RxDmaIdx)
-		{
-			// no more rx packets
-			bReschedule = FALSE;
-			goto done;
-		}
-
-		// get rx pending count
-		if (pAd->RxRing.RxDmaIdx > pAd->RxRing.RxSwReadIdx)
-			*pRxPending = pAd->RxRing.RxDmaIdx - pAd->RxRing.RxSwReadIdx;
-		else
-			*pRxPending	= pAd->RxRing.RxDmaIdx + RX_RING_SIZE - pAd->RxRing.RxSwReadIdx;
-
-	}
-
-#ifdef RT_BIG_ENDIAN
-	pDestRxD = (PRXD_STRUC) pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].AllocVa;
-	RxD = *pDestRxD;
-	pRxD = &RxD;
-	RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
-#else
-	// Point to Rx indexed rx ring descriptor
-	pRxD = (PRXD_STRUC) pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].AllocVa;
-#endif
-
-	if (pRxD->DDONE == 0)
-	{
-		*pRxPending = 0;
-		// DMAIndx had done but DDONE bit not ready
-		bReschedule = TRUE;
-		goto done;
-	}
-
-
-	// return rx descriptor
-	NdisMoveMemory(pSaveRxD, pRxD, RXD_SIZE);
-
-	pNewPacket = RTMP_AllocateRxPacketBuffer(pAd, RX_BUFFER_AGGRESIZE, FALSE, &AllocVa, &AllocPa);
-
-	if (pNewPacket)
-	{
-		// unmap the rx buffer
-		PCI_UNMAP_SINGLE(pAd, pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocPa,
-					 pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
-		pRxPacket = pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].pNdisPacket;
-
-		pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocSize	= RX_BUFFER_AGGRESIZE;
-		pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].pNdisPacket		= (PNDIS_PACKET) pNewPacket;
-		pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocVa	= AllocVa;
-		pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocPa	= AllocPa;
-		/* update SDP0 to new buffer of rx packet */
-		pRxD->SDP0 = AllocPa;
-	}
-	else
-	{
-		//DBGPRINT(RT_DEBUG_TRACE,("No Rx Buffer\n"));
-		pRxPacket = NULL;
-		bReschedule = TRUE;
-	}
-
-	pRxD->DDONE = 0;
-
-	// had handled one rx packet
-	*pRxPending = *pRxPending - 1;
-
-	// update rx descriptor and kick rx
-#ifdef RT_BIG_ENDIAN
-	RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
-	WriteBackToDescriptor((PUCHAR)pDestRxD, (PUCHAR)pRxD, FALSE, TYPE_RXD);
-#endif
-	INC_RING_INDEX(pAd->RxRing.RxSwReadIdx, RX_RING_SIZE);
-
-	pAd->RxRing.RxCpuIdx = (pAd->RxRing.RxSwReadIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxSwReadIdx-1);
-	RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
-
-done:
-	RTMP_SEM_UNLOCK(&pAd->RxRingLock);
-	*pbReschedule = bReschedule;
-	return pRxPacket;
-}
-
-
-NDIS_STATUS MlmeHardTransmitTxRing(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR	QueIdx,
-	IN	PNDIS_PACKET	pPacket)
-{
-	PACKET_INFO	PacketInfo;
-	PUCHAR			pSrcBufVA;
-	UINT			SrcBufLen;
-	PTXD_STRUC		pTxD;
-#ifdef RT_BIG_ENDIAN
-    PTXD_STRUC      pDestTxD;
-    TXD_STRUC       TxD;
-#endif
-	PHEADER_802_11	pHeader_802_11;
-	BOOLEAN			bAckRequired, bInsertTimestamp;
-	ULONG			SrcBufPA;
-	//UCHAR			TxBufIdx;
-	UCHAR			MlmeRate;
-	ULONG			SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
-	PTXWI_STRUC	pFirstTxWI;
-	//ULONG	i;
-	//HTTRANSMIT_SETTING	MlmeTransmit;   //Rate for this MGMT frame.
-	ULONG	 FreeNum;
-	MAC_TABLE_ENTRY	*pMacEntry = NULL;
-
-
-	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
-
-
-	if (pSrcBufVA == NULL)
-	{
-		// The buffer shouldn't be NULL
-		return NDIS_STATUS_FAILURE;
-	}
-
-	// Make sure MGMT ring resource won't be used by other threads
-	//NdisAcquireSpinLock(&pAd->TxRingLock);
-
-	FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
-
-	if (FreeNum == 0)
-	{
-		//NdisReleaseSpinLock(&pAd->TxRingLock);
-		return NDIS_STATUS_FAILURE;
-	}
-
-	SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
-
-#ifndef RT_BIG_ENDIAN
-	pTxD  = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa;
-#else
-    pDestTxD  = (PTXD_STRUC)pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa;
-    TxD = *pDestTxD;
-    pTxD = &TxD;
-    RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-#endif
-
-	if (pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket)
-	{
-		DBGPRINT(RT_DEBUG_OFF, ("MlmeHardTransmit Error\n"));
-		//NdisReleaseSpinLock(&pAd->TxRingLock);
-		return NDIS_STATUS_FAILURE;
-	}
-
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		// outgoing frame always wakeup PHY to prevent frame lost
-		// if (pAd->StaCfg.Psm == PWR_SAVE)
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-			AsicForceWakeup(pAd, TRUE);
-	}
-#endif // CONFIG_STA_SUPPORT //
-	pFirstTxWI	=(PTXWI_STRUC)pSrcBufVA;
-
-	pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXWI_SIZE);
-	if (pHeader_802_11->Addr1[0] & 0x01)
-	{
-		MlmeRate = pAd->CommonCfg.BasicMlmeRate;
-	}
-	else
-	{
-		MlmeRate = pAd->CommonCfg.MlmeRate;
-	}
-
-	if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
-		(pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
-	{
-		pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
-	}
-
-	// Verify Mlme rate for a / g bands.
-	if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
-		MlmeRate = RATE_6;
-
-	//
-	// Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
-	// Snice it's been set to 0 while on MgtMacHeaderInit
-	// By the way this will cause frame to be send on PWR_SAVE failed.
-	//
-	//
-	// In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
-#ifdef CONFIG_STA_SUPPORT
-    // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
-	if (pHeader_802_11->FC.Type != BTYPE_DATA)
-    {
-	if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) || !(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
-	{
-		pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
-	}
-	else
-	{
-		pHeader_802_11->FC.PwrMgmt = pAd->CommonCfg.bAPSDForcePowerSave;
-	}
-    }
-#endif // CONFIG_STA_SUPPORT //
-
-	bInsertTimestamp = FALSE;
-	if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
-	{
-		bAckRequired = FALSE;
-	}
-	else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
-	{
-		if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
-		{
-			bAckRequired = FALSE;
-			pHeader_802_11->Duration = 0;
-		}
-		else
-		{
-			bAckRequired = TRUE;
-			pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
-			if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
-			{
-				bInsertTimestamp = TRUE;
-			}
-		}
-	}
-	pHeader_802_11->Sequence = pAd->Sequence++;
-	if (pAd->Sequence > 0xfff)
-		pAd->Sequence = 0;
-	// Before radar detection done, mgmt frame can not be sent but probe req
-	// Because we need to use probe req to trigger driver to send probe req in passive scan
-	if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
-		&& (pAd->CommonCfg.bIEEE80211H == 1)
-		&& (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
-		//NdisReleaseSpinLock(&pAd->TxRingLock);
-		return (NDIS_STATUS_FAILURE);
-	}
-
-#ifdef RT_BIG_ENDIAN
-	RTMPFrameEndianChange(pAd, (PUCHAR)pHeader_802_11, DIR_WRITE, FALSE);
-#endif
-	//
-	// fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
-	// should always has only one ohysical buffer, and the whole frame size equals
-	// to the first scatter buffer size
-	//
-
-	// Initialize TX Descriptor
-	// For inter-frame gap, the number is for this frame and next frame
-	// For MLME rate, we will fix as 2Mb to match other vendor's implement
-//	pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
-
-// management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
-	// Only beacon use Nseq=TRUE. So here we use Nseq=FALSE.
-	if (pMacEntry == NULL)
-	{
-	RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
-		0, RESERVED_WCID, (SrcBufLen - TXWI_SIZE), PID_MGMT, 0,  (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
-	}
-	else
-	{
-		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
-					bInsertTimestamp, FALSE, bAckRequired, FALSE,
-					0, pMacEntry->Aid, (SrcBufLen - TXWI_SIZE),
-					pMacEntry->MaxHTPhyMode.field.MCS, 0,
-					(UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
-					IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
-	}
-
-	pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket;
-	pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL;
-//	pFirstTxWI->MPDUtotalByteCount = SrcBufLen - TXWI_SIZE;
-#ifdef RT_BIG_ENDIAN
-	RTMPWIEndianChange((PUCHAR)pFirstTxWI, TYPE_TXWI);
-#endif
-	SrcBufPA = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
-
-
-	RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_EDCA);
-	pTxD->LastSec0 = 1;
-	pTxD->LastSec1 = 1;
-	pTxD->SDLen0 = SrcBufLen;
-	pTxD->SDLen1 = 0;
-	pTxD->SDPtr0 = SrcBufPA;
-	pTxD->DMADONE = 0;
-
-#ifdef RT_BIG_ENDIAN
-    RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-    WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
-#endif
-
-	pAd->RalinkCounters.KickTxCount++;
-	pAd->RalinkCounters.OneSecTxDoneCount++;
-
-	// Increase TX_CTX_IDX, but write to register later.
-	INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE);
-
-	RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx*0x10,  pAd->TxRing[QueIdx].TxCpuIdx);
-
-	// Make sure to release MGMT ring resource
-//	NdisReleaseSpinLock(&pAd->TxRingLock);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-NDIS_STATUS MlmeDataHardTransmit(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR	QueIdx,
-	IN	PNDIS_PACKET	pPacket)
-{
-	if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
-		)
-	{
-		return NDIS_STATUS_FAILURE;
-	}
-
-	return MlmeHardTransmitTxRing(pAd,QueIdx,pPacket);
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Calculates the duration which is required to transmit out frames
-	with given size and specified rate.
-
-	Arguments:
-		pTxD		Pointer to transmit descriptor
-		Ack		Setting for Ack requirement bit
-		Fragment	Setting for Fragment bit
-		RetryMode	Setting for retry mode
-		Ifs		Setting for IFS gap
-		Rate		Setting for transmit rate
-		Service		Setting for service
-		Length		Frame length
-		TxPreamble	Short or Long preamble when using CCK rates
-		QueIdx - 0-3, according to 802.11e/d4.4 June/2003
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-VOID RTMPWriteTxDescriptor(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PTXD_STRUC		pTxD,
-	IN	BOOLEAN			bWIV,
-	IN	UCHAR			QueueSEL)
-{
-	//
-	// Always use Long preamble before verifiation short preamble functionality works well.
-	// Todo: remove the following line if short preamble functionality works
-	//
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
-
-	pTxD->WIV	= (bWIV) ? 1: 0;
-	pTxD->QSEL= (QueueSEL);
-	//RT2860c??  fixed using EDCA queue for test...  We doubt Queue1 has problem.  2006-09-26 Jan
-	//pTxD->QSEL= FIFO_EDCA;
-	/*
-	if (pAd->bGenOneHCCA == TRUE)
-		pTxD->QSEL= FIFO_HCCA;
-	*/
-	pTxD->DMADONE = 0;
-}
diff --git a/drivers/staging/rt3090/common/cmm_info.c b/drivers/staging/rt3090/common/cmm_info.c
deleted file mode 100644
index 3e51e98..0000000
--- a/drivers/staging/rt3090/common/cmm_info.c
+++ /dev/null
@@ -1,3718 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	cmm_info.c
-
-    Abstract:
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
- */
-
-#include <linux/sched.h>
-#include "../rt_config.h"
-
-
-INT	Show_SSID_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_WirelessMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_TxBurst_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_TxPreamble_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_TxPower_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_Channel_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_BGProtection_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_RTSThreshold_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_FragThreshold_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-#ifdef DOT11_N_SUPPORT
-INT	Show_HtBw_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_HtMcs_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_HtGi_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_HtOpMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_HtExtcha_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_HtMpduDensity_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_HtBaWinSize_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_HtRdg_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_HtAmsdu_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_HtAutoBa_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-#endif // DOT11_N_SUPPORT //
-
-INT	Show_CountryRegion_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_CountryRegionABand_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_CountryCode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-#ifdef AGGREGATION_SUPPORT
-INT	Show_PktAggregate_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-#endif // AGGREGATION_SUPPORT //
-
-#ifdef WMM_SUPPORT
-INT	Show_WmmCapable_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-#endif // WMM_SUPPORT //
-
-INT	Show_IEEE80211H_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-#ifdef CONFIG_STA_SUPPORT
-INT	Show_NetworkType_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-#endif // CONFIG_STA_SUPPORT //
-
-INT	Show_AuthMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_EncrypType_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_DefaultKeyID_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_Key1_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_Key2_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_Key3_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_Key4_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-INT	Show_WPAPSK_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf);
-
-static struct {
-	PSTRING name;
-	INT (*show_proc)(PRTMP_ADAPTER pAdapter, PSTRING arg);
-} *PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC, RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC[] = {
-	{"SSID",					Show_SSID_Proc},
-	{"WirelessMode",			Show_WirelessMode_Proc},
-	{"TxBurst",					Show_TxBurst_Proc},
-	{"TxPreamble",				Show_TxPreamble_Proc},
-	{"TxPower",					Show_TxPower_Proc},
-	{"Channel",					Show_Channel_Proc},
-	{"BGProtection",			Show_BGProtection_Proc},
-	{"RTSThreshold",			Show_RTSThreshold_Proc},
-	{"FragThreshold",			Show_FragThreshold_Proc},
-#ifdef DOT11_N_SUPPORT
-	{"HtBw",					Show_HtBw_Proc},
-	{"HtMcs",					Show_HtMcs_Proc},
-	{"HtGi",					Show_HtGi_Proc},
-	{"HtOpMode",				Show_HtOpMode_Proc},
-	{"HtExtcha",				Show_HtExtcha_Proc},
-	{"HtMpduDensity",			Show_HtMpduDensity_Proc},
-	{"HtBaWinSize",		        Show_HtBaWinSize_Proc},
-	{"HtRdg",				Show_HtRdg_Proc},
-	{"HtAmsdu",				Show_HtAmsdu_Proc},
-	{"HtAutoBa",		        Show_HtAutoBa_Proc},
-#endif // DOT11_N_SUPPORT //
-	{"CountryRegion",			Show_CountryRegion_Proc},
-	{"CountryRegionABand",		Show_CountryRegionABand_Proc},
-	{"CountryCode",				Show_CountryCode_Proc},
-#ifdef AGGREGATION_SUPPORT
-	{"PktAggregate",			Show_PktAggregate_Proc},
-#endif
-
-#ifdef WMM_SUPPORT
-	{"WmmCapable",				Show_WmmCapable_Proc},
-#endif
-	{"IEEE80211H",				Show_IEEE80211H_Proc},
-#ifdef CONFIG_STA_SUPPORT
-    {"NetworkType",				Show_NetworkType_Proc},
-#endif // CONFIG_STA_SUPPORT //
-	{"AuthMode",				Show_AuthMode_Proc},
-	{"EncrypType",				Show_EncrypType_Proc},
-	{"DefaultKeyID",			Show_DefaultKeyID_Proc},
-	{"Key1",					Show_Key1_Proc},
-	{"Key2",					Show_Key2_Proc},
-	{"Key3",					Show_Key3_Proc},
-	{"Key4",					Show_Key4_Proc},
-	{"WPAPSK",					Show_WPAPSK_Proc},
-	{NULL, NULL}
-};
-
-/*
-    ==========================================================================
-    Description:
-        Get Driver version.
-
-    Return:
-    ==========================================================================
-*/
-INT Set_DriverVersion_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		DBGPRINT(RT_DEBUG_TRACE, ("Driver version-%s\n", STA_DRIVER_VERSION));
-#endif // CONFIG_STA_SUPPORT //
-
-
-    return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set Country Region.
-        This command will not work, if the field of CountryRegion in eeprom is programmed.
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_CountryRegion_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	int retval;
-
-#ifdef EXT_BUILD_CHANNEL_LIST
-	return -EOPNOTSUPP;
-#endif // EXT_BUILD_CHANNEL_LIST //
-
-	retval = RT_CfgSetCountryRegion(pAd, arg, BAND_24G);
-	if (retval == FALSE)
-		return FALSE;
-
-	// if set country region, driver needs to be reset
-	BuildChannelList(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_CountryRegion_Proc::(CountryRegion=%d)\n", pAd->CommonCfg.CountryRegion));
-
-	return TRUE;
-}
-
-
-/*
-    ==========================================================================
-    Description:
-        Set Country Region for A band.
-        This command will not work, if the field of CountryRegion in eeprom is programmed.
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_CountryRegionABand_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	int retval;
-
-#ifdef EXT_BUILD_CHANNEL_LIST
-	return -EOPNOTSUPP;
-#endif // EXT_BUILD_CHANNEL_LIST //
-
-	retval = RT_CfgSetCountryRegion(pAd, arg, BAND_5G);
-	if (retval == FALSE)
-		return FALSE;
-
-	// if set country region, driver needs to be reset
-	BuildChannelList(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_CountryRegionABand_Proc::(CountryRegion=%d)\n", pAd->CommonCfg.CountryRegionForABand));
-
-	return TRUE;
-}
-
-
-/*
-    ==========================================================================
-    Description:
-        Set Wireless Mode
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_WirelessMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	INT	success = TRUE;
-
-	success = RT_CfgSetWirelessMode(pAd, arg);
-	if (success)
-	{
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			LONG	WirelessMode = pAd->CommonCfg.PhyMode;
-
-			RTMPSetPhyMode(pAd, WirelessMode);
-#ifdef DOT11_N_SUPPORT
-			if (WirelessMode >= PHY_11ABGN_MIXED)
-			{
-				pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
-				pAd->CommonCfg.REGBACapability.field.AutoBA = TRUE;
-			}
-			else
-			{
-				pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
-				pAd->CommonCfg.REGBACapability.field.AutoBA = FALSE;
-			}
-#endif // DOT11_N_SUPPORT //
-			// Set AdhocMode rates
-			if (pAd->StaCfg.BssType == BSS_ADHOC)
-			{
-				MlmeUpdateTxRates(pAd, FALSE, 0);
-				MakeIbssBeacon(pAd);           // re-build BEACON frame
-				AsicEnableIbssSync(pAd);       // copy to on-chip memory
-			}
-		}
-#endif // CONFIG_STA_SUPPORT //
-
-		// it is needed to set SSID to take effect
-#ifdef DOT11_N_SUPPORT
-		SetCommonHT(pAd);
-#endif // DOT11_N_SUPPORT //
-		DBGPRINT(RT_DEBUG_TRACE, ("Set_WirelessMode_Proc::(=%d)\n", pAd->CommonCfg.PhyMode));
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Set_WirelessMode_Proc::parameters out of range\n"));
-	}
-
-	return success;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set Channel
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_Channel_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	INT		success = TRUE;
-	UCHAR	Channel;
-
-	Channel = (UCHAR) simple_strtol(arg, 0, 10);
-
-	// check if this channel is valid
-	if (ChannelSanity(pAd, Channel) == TRUE)
-	{
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			pAd->CommonCfg.Channel = Channel;
-
-			if (MONITOR_ON(pAd))
-			{
-#ifdef DOT11_N_SUPPORT
-				N_ChannelCheck(pAd);
-				if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
-					pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
-				{
-					N_SetCenCh(pAd);
-						AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
-						AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
-					DBGPRINT(RT_DEBUG_TRACE, ("BW_40, control_channel(%d), CentralChannel(%d) \n",
-								pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
-				}
-				else
-#endif // DOT11_N_SUPPORT //
-				{
-					AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-					AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-					DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAd->CommonCfg.Channel));
-				}
-			}
-		}
-#endif // CONFIG_STA_SUPPORT //
-		success = TRUE;
-	}
-	else
-	{
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-			success = FALSE;
-#endif // CONFIG_STA_SUPPORT //
-	}
-
-
-	if (success == TRUE)
-		DBGPRINT(RT_DEBUG_TRACE, ("Set_Channel_Proc::(Channel=%d)\n", pAd->CommonCfg.Channel));
-
-	return success;
-}
-
-
-/*
-    ==========================================================================
-    Description:
-        Set Short Slot Time Enable or Disable
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_ShortSlot_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	int retval;
-
-	retval = RT_CfgSetShortSlot(pAd, arg);
-	if (retval == TRUE)
-		DBGPRINT(RT_DEBUG_TRACE, ("Set_ShortSlot_Proc::(ShortSlot=%d)\n", pAd->CommonCfg.bUseShortSlotTime));
-
-	return retval;
-}
-
-
-/*
-    ==========================================================================
-    Description:
-        Set Tx power
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_TxPower_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	LONG TxPower;
-	INT   success = FALSE;
-
-	TxPower = simple_strtol(arg, 0, 10);
-	if (TxPower <= 100)
-	{
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			pAd->CommonCfg.TxPowerDefault = TxPower;
-			pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
-		}
-#endif // CONFIG_STA_SUPPORT //
-		success = TRUE;
-	}
-	else
-		success = FALSE;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_TxPower_Proc::(TxPowerPercentage=%ld)\n", pAd->CommonCfg.TxPowerPercentage));
-
-	return success;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set 11B/11G Protection
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_BGProtection_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	switch (simple_strtol(arg, 0, 10))
-	{
-		case 0: //AUTO
-			pAd->CommonCfg.UseBGProtection = 0;
-			break;
-		case 1: //Always On
-			pAd->CommonCfg.UseBGProtection = 1;
-			break;
-		case 2: //Always OFF
-			pAd->CommonCfg.UseBGProtection = 2;
-			break;
-		default:  //Invalid argument
-			return FALSE;
-	}
-
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_BGProtection_Proc::(BGProtection=%ld)\n", pAd->CommonCfg.UseBGProtection));
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set TxPreamble
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_TxPreamble_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	RT_802_11_PREAMBLE	Preamble;
-
-	Preamble = simple_strtol(arg, 0, 10);
-
-
-	switch (Preamble)
-	{
-		case Rt802_11PreambleShort:
-			pAd->CommonCfg.TxPreamble = Preamble;
-#ifdef CONFIG_STA_SUPPORT
-			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-				MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
-#endif // CONFIG_STA_SUPPORT //
-			break;
-		case Rt802_11PreambleLong:
-#ifdef CONFIG_STA_SUPPORT
-		case Rt802_11PreambleAuto:
-			// if user wants AUTO, initialize to LONG here, then change according to AP's
-			// capability upon association.
-#endif // CONFIG_STA_SUPPORT //
-			pAd->CommonCfg.TxPreamble = Preamble;
-#ifdef CONFIG_STA_SUPPORT
-			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-				MlmeSetTxPreamble(pAd, Rt802_11PreambleLong);
-#endif // CONFIG_STA_SUPPORT //
-			break;
-		default: //Invalid argument
-			return FALSE;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_TxPreamble_Proc::(TxPreamble=%ld)\n", pAd->CommonCfg.TxPreamble));
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set RTS Threshold
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_RTSThreshold_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	 NDIS_802_11_RTS_THRESHOLD           RtsThresh;
-
-	RtsThresh = simple_strtol(arg, 0, 10);
-
-	if((RtsThresh > 0) && (RtsThresh <= MAX_RTS_THRESHOLD))
-		pAd->CommonCfg.RtsThreshold  = (USHORT)RtsThresh;
-#ifdef CONFIG_STA_SUPPORT
-	else if (RtsThresh == 0)
-		pAd->CommonCfg.RtsThreshold = MAX_RTS_THRESHOLD;
-#endif // CONFIG_STA_SUPPORT //
-	else
-		return FALSE; //Invalid argument
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_RTSThreshold_Proc::(RTSThreshold=%d)\n", pAd->CommonCfg.RtsThreshold));
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set Fragment Threshold
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_FragThreshold_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	 NDIS_802_11_FRAGMENTATION_THRESHOLD     FragThresh;
-
-	FragThresh = simple_strtol(arg, 0, 10);
-
-	if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
-	{
-		//Illegal FragThresh so we set it to default
-		pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
-	}
-	else if (FragThresh % 2 == 1)
-	{
-		// The length of each fragment shall always be an even number of octets, except for the last fragment
-		// of an MSDU or MMPDU, which may be either an even or an odd number of octets.
-		pAd->CommonCfg.FragmentThreshold = (USHORT)(FragThresh - 1);
-	}
-	else
-	{
-		pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
-	}
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		if (pAd->CommonCfg.FragmentThreshold == MAX_FRAG_THRESHOLD)
-			pAd->CommonCfg.bUseZeroToDisableFragment = TRUE;
-		else
-			pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_FragThreshold_Proc::(FragThreshold=%d)\n", pAd->CommonCfg.FragmentThreshold));
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set TxBurst
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_TxBurst_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	LONG TxBurst;
-
-	TxBurst = simple_strtol(arg, 0, 10);
-	if (TxBurst == 1)
-		pAd->CommonCfg.bEnableTxBurst = TRUE;
-	else if (TxBurst == 0)
-		pAd->CommonCfg.bEnableTxBurst = FALSE;
-	else
-		return FALSE;  //Invalid argument
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_TxBurst_Proc::(TxBurst=%d)\n", pAd->CommonCfg.bEnableTxBurst));
-
-	return TRUE;
-}
-
-#ifdef AGGREGATION_SUPPORT
-/*
-    ==========================================================================
-    Description:
-        Set TxBurst
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_PktAggregate_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	LONG aggre;
-
-	aggre = simple_strtol(arg, 0, 10);
-
-	if (aggre == 1)
-		pAd->CommonCfg.bAggregationCapable = TRUE;
-	else if (aggre == 0)
-		pAd->CommonCfg.bAggregationCapable = FALSE;
-	else
-		return FALSE;  //Invalid argument
-
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_PktAggregate_Proc::(AGGRE=%d)\n", pAd->CommonCfg.bAggregationCapable));
-
-	return TRUE;
-}
-#endif
-
-
-#ifdef INF_AMAZON_PPA
-INT	Set_INF_AMAZON_SE_PPA_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	ULONG aggre;
-	UINT status;
-
-	aggre = simple_strtol(arg, 0, 10);
-
-	if (aggre == 1)
-	{
-		if(pAd->PPAEnable==TRUE)
-		{
-			printk("INF_AMAZON_SE_PPA already enabled \n");
-		}
-		else
-		{
-			if (ppa_hook_directpath_register_dev_fn)
-			{
-				UINT32 g_if_id;
-
-				if (pAd->pDirectpathCb == NULL)
-				{
-					 pAd->pDirectpathCb = (PPA_DIRECTPATH_CB *) kmalloc (sizeof(PPA_DIRECTPATH_CB), GFP_ATOMIC);
-				        printk("Realloc memory for  pDirectpathCb ??\n");
-				}
-
-				/* register callback */
-				pAd->pDirectpathCb->rx_fn = NULL;
-				pAd->pDirectpathCb->stop_tx_fn = NULL;
-				pAd->pDirectpathCb->start_tx_fn = NULL;
-
-				status = ppa_hook_directpath_register_dev_fn(&g_if_id, pAd->net_dev, pAd->pDirectpathCb, PPA_F_DIRECTPATH_ETH_IF);
-
-				if(status==1)
-				{
-					pAd->g_if_id=g_if_id;
-					printk("register INF_AMAZON_SE_PPA success :ret:%d id:%d:%d\n",status,pAd->g_if_id,g_if_id);
-					pAd->PPAEnable=TRUE;
-				}
-				else
-				{
-					printk("register INF_AMAZON_SE_PPA fail :ret:%d\n",status);
-				}
-
-			}
-			else
-			{
-				printk("INF_AMAZON_SE_PPA enable fail : there is no INF_AMAZON_SE_PPA module . \n");
-			}
-		}
-
-
-	}
-	else if (aggre == 0)
-	{
-		if(pAd->PPAEnable==FALSE)
-		{
-
-printk("INF_AMAZON_SE_PPA already disable \n");
-		}
-		else
-		{
-			if (ppa_hook_directpath_register_dev_fn)
-			{
-				UINT32 g_if_id;
-				g_if_id=pAd->g_if_id;
-				printk("g_if_id=%d \n",pAd->g_if_id);
-				status=ppa_hook_directpath_register_dev_fn(&g_if_id, pAd->net_dev, NULL, PPA_F_DIRECTPATH_DEREGISTER);
-
-				if(status==1)
-				{
-					pAd->g_if_id=0;
-					printk("unregister INF_AMAZON_SE_PPA success :ret:%d\n",status);
-					pAd->PPAEnable=FALSE;
-				}
-				else
-				{
-					printk("unregister INF_AMAZON_SE_PPA fail :ret:%d\n",status);
-				}
-
-			}
-			else
-			{
-				printk("INF_AMAZON_SE_PPA enable fail : there is no INF_AMAZON_SE_PPA module . \n");
-			}
-		}
-
-	}
-	else
-	{
-		printk("Invalid argument %d \n",aggre);
-		return FALSE;  //Invalid argument
-	}
-
-	return TRUE;
-
-}
-#endif // INF_AMAZON_PPA //
-
-
-/*
-    ==========================================================================
-    Description:
-        Set IEEE80211H.
-        This parameter is 1 when needs radar detection, otherwise 0
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_IEEE80211H_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-    LONG ieee80211h;
-
-	ieee80211h = simple_strtol(arg, 0, 10);
-
-	if (ieee80211h == 1)
-		pAd->CommonCfg.bIEEE80211H = TRUE;
-	else if (ieee80211h == 0)
-		pAd->CommonCfg.bIEEE80211H = FALSE;
-	else
-		return FALSE;  //Invalid argument
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_IEEE80211H_Proc::(IEEE80211H=%d)\n", pAd->CommonCfg.bIEEE80211H));
-
-	return TRUE;
-}
-
-
-#ifdef DBG
-/*
-    ==========================================================================
-    Description:
-        For Debug information
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_Debug_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	DBGPRINT(RT_DEBUG_TRACE, ("==> Set_Debug_Proc *******************\n"));
-
-    if(simple_strtol(arg, 0, 10) <= RT_DEBUG_LOUD)
-        RTDebugLevel = simple_strtol(arg, 0, 10);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<== Set_Debug_Proc(RTDebugLevel = %ld)\n", RTDebugLevel));
-
-	return TRUE;
-}
-#endif
-
-INT	Show_DescInfo_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-#ifdef RTMP_MAC_PCI
-	INT i, QueIdx=0;
-//  ULONG	RegValue;
-        PRT28XX_RXD_STRUC pRxD;
-        PTXD_STRUC pTxD;
-	PRTMP_TX_RING	pTxRing = &pAd->TxRing[QueIdx];
-	PRTMP_MGMT_RING	pMgmtRing = &pAd->MgmtRing;
-	PRTMP_RX_RING	pRxRing = &pAd->RxRing;
-
-	for(i=0;i<TX_RING_SIZE;i++)
-	{
-	    pTxD = (PTXD_STRUC) pTxRing->Cell[i].AllocVa;
-	    DBGPRINT(RT_DEBUG_OFF, ("Desc #%d\n",i));
-	    hex_dump("Tx Descriptor", (PUCHAR)pTxD, 16);
-	    DBGPRINT(RT_DEBUG_OFF, ("pTxD->DMADONE = %x\n", pTxD->DMADONE));
-	}
-	DBGPRINT(RT_DEBUG_OFF, ("---------------------------------------------------\n"));
-	for(i=0;i<MGMT_RING_SIZE;i++)
-	{
-	    pTxD = (PTXD_STRUC) pMgmtRing->Cell[i].AllocVa;
-	    DBGPRINT(RT_DEBUG_OFF, ("Desc #%d\n",i));
-	    hex_dump("Mgmt Descriptor", (PUCHAR)pTxD, 16);
-	    DBGPRINT(RT_DEBUG_OFF, ("pMgmt->DMADONE = %x\n", pTxD->DMADONE));
-	}
-	DBGPRINT(RT_DEBUG_OFF, ("---------------------------------------------------\n"));
-	for(i=0;i<RX_RING_SIZE;i++)
-	{
-	    pRxD = (PRT28XX_RXD_STRUC) pRxRing->Cell[i].AllocVa;
-	    DBGPRINT(RT_DEBUG_OFF, ("Desc #%d\n",i));
-	    hex_dump("Rx Descriptor", (PUCHAR)pRxD, 16);
-	    DBGPRINT(RT_DEBUG_OFF, ("pRxD->DDONE = %x\n", pRxD->DDONE));
-	}
-#endif // RTMP_MAC_PCI //
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Reset statistics counter
-
-    Arguments:
-        pAdapter            Pointer to our adapter
-        arg
-
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_ResetStatCounter_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	//UCHAR           i;
-	//MAC_TABLE_ENTRY *pEntry;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("==>Set_ResetStatCounter_Proc\n"));
-
-	// add the most up-to-date h/w raw counters into software counters
-	NICUpdateRawCounters(pAd);
-
-	NdisZeroMemory(&pAd->WlanCounters, sizeof(COUNTER_802_11));
-	NdisZeroMemory(&pAd->Counters8023, sizeof(COUNTER_802_3));
-	NdisZeroMemory(&pAd->RalinkCounters, sizeof(COUNTER_RALINK));
-
-	// Reset HotSpot counter
-
-
-	return TRUE;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Add WPA key process.
-		In Adhoc WPANONE, bPairwise = 0;  KeyIdx = 0;
-
-	Arguments:
-		pAd					Pointer to our adapter
-		pBuf							Pointer to the where the key stored
-
-	Return Value:
-		NDIS_SUCCESS					Add key successfully
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-
-BOOLEAN RTMPCheckStrPrintAble(
-    IN  CHAR *pInPutStr,
-    IN  UCHAR strLen)
-{
-    UCHAR i=0;
-
-    for (i=0; i<strLen; i++)
-    {
-        if ((pInPutStr[i] < 0x21) ||
-            (pInPutStr[i] > 0x7E))
-            return FALSE;
-    }
-
-    return TRUE;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Remove WPA Key process
-
-	Arguments:
-		pAd					Pointer to our adapter
-		pBuf							Pointer to the where the key stored
-
-	Return Value:
-		NDIS_SUCCESS					Add key successfully
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-#ifdef CONFIG_STA_SUPPORT
-VOID    RTMPSetDesiredRates(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  LONG            Rates)
-{
-    NDIS_802_11_RATES aryRates;
-
-    memset(&aryRates, 0x00, sizeof(NDIS_802_11_RATES));
-    switch (pAdapter->CommonCfg.PhyMode)
-    {
-        case PHY_11A: // A only
-            switch (Rates)
-            {
-                case 6000000: //6M
-                    aryRates[0] = 0x0c; // 6M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
-                    break;
-                case 9000000: //9M
-                    aryRates[0] = 0x12; // 9M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
-                    break;
-                case 12000000: //12M
-                    aryRates[0] = 0x18; // 12M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
-                    break;
-                case 18000000: //18M
-                    aryRates[0] = 0x24; // 18M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
-                    break;
-                case 24000000: //24M
-                    aryRates[0] = 0x30; // 24M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_4;
-                    break;
-                case 36000000: //36M
-                    aryRates[0] = 0x48; // 36M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_5;
-                    break;
-                case 48000000: //48M
-                    aryRates[0] = 0x60; // 48M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_6;
-                    break;
-                case 54000000: //54M
-                    aryRates[0] = 0x6c; // 54M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_7;
-                    break;
-                case -1: //Auto
-                default:
-                    aryRates[0] = 0x6c; // 54Mbps
-                    aryRates[1] = 0x60; // 48Mbps
-                    aryRates[2] = 0x48; // 36Mbps
-                    aryRates[3] = 0x30; // 24Mbps
-                    aryRates[4] = 0x24; // 18M
-                    aryRates[5] = 0x18; // 12M
-                    aryRates[6] = 0x12; // 9M
-                    aryRates[7] = 0x0c; // 6M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
-                    break;
-            }
-            break;
-        case PHY_11BG_MIXED: // B/G Mixed
-        case PHY_11B: // B only
-        case PHY_11ABG_MIXED: // A/B/G Mixed
-        default:
-            switch (Rates)
-            {
-                case 1000000: //1M
-                    aryRates[0] = 0x02;
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
-                    break;
-                case 2000000: //2M
-                    aryRates[0] = 0x04;
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
-                    break;
-                case 5000000: //5.5M
-                    aryRates[0] = 0x0b; // 5.5M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
-                    break;
-                case 11000000: //11M
-                    aryRates[0] = 0x16; // 11M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
-                    break;
-                case 6000000: //6M
-                    aryRates[0] = 0x0c; // 6M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
-                    break;
-                case 9000000: //9M
-                    aryRates[0] = 0x12; // 9M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
-                    break;
-                case 12000000: //12M
-                    aryRates[0] = 0x18; // 12M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
-                    break;
-                case 18000000: //18M
-                    aryRates[0] = 0x24; // 18M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
-                    break;
-                case 24000000: //24M
-                    aryRates[0] = 0x30; // 24M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_4;
-                    break;
-                case 36000000: //36M
-                    aryRates[0] = 0x48; // 36M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_5;
-                    break;
-                case 48000000: //48M
-                    aryRates[0] = 0x60; // 48M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_6;
-                    break;
-                case 54000000: //54M
-                    aryRates[0] = 0x6c; // 54M
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_7;
-                    break;
-                case -1: //Auto
-                default:
-                    if (pAdapter->CommonCfg.PhyMode == PHY_11B)
-                    { //B Only
-                        aryRates[0] = 0x16; // 11Mbps
-                        aryRates[1] = 0x0b; // 5.5Mbps
-                        aryRates[2] = 0x04; // 2Mbps
-                        aryRates[3] = 0x02; // 1Mbps
-                    }
-                    else
-                    { //(B/G) Mixed or (A/B/G) Mixed
-                        aryRates[0] = 0x6c; // 54Mbps
-                        aryRates[1] = 0x60; // 48Mbps
-                        aryRates[2] = 0x48; // 36Mbps
-                        aryRates[3] = 0x30; // 24Mbps
-                        aryRates[4] = 0x16; // 11Mbps
-                        aryRates[5] = 0x0b; // 5.5Mbps
-                        aryRates[6] = 0x04; // 2Mbps
-                        aryRates[7] = 0x02; // 1Mbps
-                    }
-                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
-                    break;
-            }
-            break;
-    }
-
-    NdisZeroMemory(pAdapter->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
-    NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES));
-    DBGPRINT(RT_DEBUG_TRACE, (" RTMPSetDesiredRates (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
-        pAdapter->CommonCfg.DesireRate[0],pAdapter->CommonCfg.DesireRate[1],
-        pAdapter->CommonCfg.DesireRate[2],pAdapter->CommonCfg.DesireRate[3],
-        pAdapter->CommonCfg.DesireRate[4],pAdapter->CommonCfg.DesireRate[5],
-        pAdapter->CommonCfg.DesireRate[6],pAdapter->CommonCfg.DesireRate[7] ));
-    // Changing DesiredRate may affect the MAX TX rate we used to TX frames out
-    MlmeUpdateTxRates(pAdapter, FALSE, 0);
-}
-
-NDIS_STATUS RTMPWPARemoveKeyProc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PVOID			pBuf)
-{
-	PNDIS_802_11_REMOVE_KEY pKey;
-	ULONG					KeyIdx;
-	NDIS_STATUS			Status = NDIS_STATUS_FAILURE;
-	BOOLEAN		bTxKey;			// Set the key as transmit key
-	BOOLEAN		bPairwise;		// Indicate the key is pairwise key
-	BOOLEAN		bKeyRSC;		// indicate the receive  SC set by KeyRSC value.
-								// Otherwise, it will set by the NIC.
-	BOOLEAN		bAuthenticator; // indicate key is set by authenticator.
-	INT		i;
-
-	DBGPRINT(RT_DEBUG_TRACE,("---> RTMPWPARemoveKeyProc\n"));
-
-	pKey = (PNDIS_802_11_REMOVE_KEY) pBuf;
-	KeyIdx = pKey->KeyIndex & 0xff;
-	// Bit 31 of Add-key, Tx Key
-	bTxKey		   = (pKey->KeyIndex & 0x80000000) ? TRUE : FALSE;
-	// Bit 30 of Add-key PairwiseKey
-	bPairwise	   = (pKey->KeyIndex & 0x40000000) ? TRUE : FALSE;
-	// Bit 29 of Add-key KeyRSC
-	bKeyRSC		   = (pKey->KeyIndex & 0x20000000) ? TRUE : FALSE;
-	// Bit 28 of Add-key Authenticator
-	bAuthenticator = (pKey->KeyIndex & 0x10000000) ? TRUE : FALSE;
-
-	// 1. If bTx is TRUE, return failure information
-	if (bTxKey == TRUE)
-		return(NDIS_STATUS_INVALID_DATA);
-
-	// 2. Check Pairwise Key
-	if (bPairwise)
-	{
-		// a. If BSSID is broadcast, remove all pairwise keys.
-		// b. If not broadcast, remove the pairwise specified by BSSID
-		for (i = 0; i < SHARE_KEY_NUM; i++)
-		{
-			if (MAC_ADDR_EQUAL(pAd->SharedKey[BSS0][i].BssId, pKey->BSSID))
-			{
-				DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveKeyProc(KeyIdx=%d)\n", i));
-				pAd->SharedKey[BSS0][i].KeyLen = 0;
-				pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_NONE;
-				AsicRemoveSharedKeyEntry(pAd, BSS0, (UCHAR)i);
-				Status = NDIS_STATUS_SUCCESS;
-				break;
-			}
-		}
-	}
-	// 3. Group Key
-	else
-	{
-		// a. If BSSID is broadcast, remove all group keys indexed
-		// b. If BSSID matched, delete the group key indexed.
-		DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveKeyProc(KeyIdx=%ld)\n", KeyIdx));
-		pAd->SharedKey[BSS0][KeyIdx].KeyLen = 0;
-		pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
-		AsicRemoveSharedKeyEntry(pAd, BSS0, (UCHAR)KeyIdx);
-		Status = NDIS_STATUS_SUCCESS;
-	}
-
-	return (Status);
-}
-#endif // CONFIG_STA_SUPPORT //
-
-
-#ifdef CONFIG_STA_SUPPORT
-/*
-	========================================================================
-
-	Routine Description:
-		Remove All WPA Keys
-
-	Arguments:
-		pAd					Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPWPARemoveAllKeys(
-	IN	PRTMP_ADAPTER	pAd)
-{
-
-	UCHAR	i;
-
-	DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveAllKeys(AuthMode=%d, WepStatus=%d)\n", pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus));
-	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-	// For WEP/CKIP, there is no need to remove it, since WinXP won't set it again after
-	// Link up. And it will be replaced if user changed it.
-	if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
-		return;
-
-	// For WPA-None, there is no need to remove it, since WinXP won't set it again after
-	// Link up. And it will be replaced if user changed it.
-	if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
-		return;
-
-	// set BSSID wcid entry of the Pair-wise Key table as no-security mode
-	AsicRemovePairwiseKeyEntry(pAd, BSS0, BSSID_WCID);
-
-	// set all shared key mode as no-security.
-	for (i = 0; i < SHARE_KEY_NUM; i++)
-    {
-		DBGPRINT(RT_DEBUG_TRACE,("remove %s key #%d\n", CipherName[pAd->SharedKey[BSS0][i].CipherAlg], i));
-		NdisZeroMemory(&pAd->SharedKey[BSS0][i], sizeof(CIPHER_KEY));
-
-		AsicRemoveSharedKeyEntry(pAd, BSS0, i);
-	}
-	RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-
-}
-#endif // CONFIG_STA_SUPPORT //
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		As STA's BSSID is a WC too, it uses shared key table.
-		This function write correct unicast TX key to ASIC WCID.
-		And we still make a copy in our MacTab.Content[BSSID_WCID].PairwiseKey.
-		Caller guarantee TKIP/AES always has keyidx = 0. (pairwise key)
-		Caller guarantee WEP calls this function when set Txkey,  default key index=0~3.
-
-	Arguments:
-		pAd					Pointer to our adapter
-		pKey							Pointer to the where the key stored
-
-	Return Value:
-		NDIS_SUCCESS					Add key successfully
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-/*
-	========================================================================
-	Routine Description:
-		Change NIC PHY mode. Re-association may be necessary. possible settings
-		include - PHY_11B, PHY_11BG_MIXED, PHY_11A, and PHY_11ABG_MIXED
-
-	Arguments:
-		pAd - Pointer to our adapter
-		phymode  -
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-VOID	RTMPSetPhyMode(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	ULONG phymode)
-{
-	INT i;
-	// the selected phymode must be supported by the RF IC encoded in E2PROM
-
-	// if no change, do nothing
-	/* bug fix
-	if (pAd->CommonCfg.PhyMode == phymode)
-		return;
-    */
-	pAd->CommonCfg.PhyMode = (UCHAR)phymode;
-
-	DBGPRINT(RT_DEBUG_TRACE,("RTMPSetPhyMode : PhyMode=%d, channel=%d \n", pAd->CommonCfg.PhyMode, pAd->CommonCfg.Channel));
-#ifdef EXT_BUILD_CHANNEL_LIST
-	BuildChannelListEx(pAd);
-#else
-	BuildChannelList(pAd);
-#endif // EXT_BUILD_CHANNEL_LIST //
-
-	// sanity check user setting
-	for (i = 0; i < pAd->ChannelListNum; i++)
-	{
-		if (pAd->CommonCfg.Channel == pAd->ChannelList[i].Channel)
-			break;
-	}
-
-	if (i == pAd->ChannelListNum)
-	{
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-			pAd->CommonCfg.Channel = FirstChannel(pAd);
-#endif // CONFIG_STA_SUPPORT //
-		DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetPhyMode: channel is out of range, use first channel=%d \n", pAd->CommonCfg.Channel));
-	}
-
-	NdisZeroMemory(pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
-	NdisZeroMemory(pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
-	NdisZeroMemory(pAd->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
-	switch (phymode) {
-		case PHY_11B:
-			pAd->CommonCfg.SupRate[0]  = 0x82;	  // 1 mbps, in units of 0.5 Mbps, basic rate
-			pAd->CommonCfg.SupRate[1]  = 0x84;	  // 2 mbps, in units of 0.5 Mbps, basic rate
-			pAd->CommonCfg.SupRate[2]  = 0x8B;	  // 5.5 mbps, in units of 0.5 Mbps, basic rate
-			pAd->CommonCfg.SupRate[3]  = 0x96;	  // 11 mbps, in units of 0.5 Mbps, basic rate
-			pAd->CommonCfg.SupRateLen  = 4;
-			pAd->CommonCfg.ExtRateLen  = 0;
-			pAd->CommonCfg.DesireRate[0]  = 2;	   // 1 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[1]  = 4;	   // 2 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[2]  = 11;    // 5.5 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[3]  = 22;    // 11 mbps, in units of 0.5 Mbps
-			//pAd->CommonCfg.HTPhyMode.field.MODE = MODE_CCK; // This MODE is only FYI. not use
-			break;
-
-		case PHY_11G:
-		case PHY_11BG_MIXED:
-		case PHY_11ABG_MIXED:
-#ifdef DOT11_N_SUPPORT
-		case PHY_11N_2_4G:
-		case PHY_11ABGN_MIXED:
-		case PHY_11BGN_MIXED:
-		case PHY_11GN_MIXED:
-#endif // DOT11_N_SUPPORT //
-			pAd->CommonCfg.SupRate[0]  = 0x82;	  // 1 mbps, in units of 0.5 Mbps, basic rate
-			pAd->CommonCfg.SupRate[1]  = 0x84;	  // 2 mbps, in units of 0.5 Mbps, basic rate
-			pAd->CommonCfg.SupRate[2]  = 0x8B;	  // 5.5 mbps, in units of 0.5 Mbps, basic rate
-			pAd->CommonCfg.SupRate[3]  = 0x96;	  // 11 mbps, in units of 0.5 Mbps, basic rate
-			pAd->CommonCfg.SupRate[4]  = 0x12;	  // 9 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.SupRate[5]  = 0x24;	  // 18 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.SupRate[6]  = 0x48;	  // 36 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.SupRate[7]  = 0x6c;	  // 54 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.SupRateLen  = 8;
-			pAd->CommonCfg.ExtRate[0]  = 0x0C;	  // 6 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.ExtRate[1]  = 0x18;	  // 12 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.ExtRate[2]  = 0x30;	  // 24 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.ExtRate[3]  = 0x60;	  // 48 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.ExtRateLen  = 4;
-			pAd->CommonCfg.DesireRate[0]  = 2;	   // 1 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[1]  = 4;	   // 2 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[2]  = 11;    // 5.5 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[3]  = 22;    // 11 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[4]  = 12;    // 6 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[5]  = 18;    // 9 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[6]  = 24;    // 12 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[7]  = 36;    // 18 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[8]  = 48;    // 24 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[9]  = 72;    // 36 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[10] = 96;    // 48 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[11] = 108;   // 54 mbps, in units of 0.5 Mbps
-			break;
-
-		case PHY_11A:
-#ifdef DOT11_N_SUPPORT
-		case PHY_11AN_MIXED:
-		case PHY_11AGN_MIXED:
-		case PHY_11N_5G:
-#endif // DOT11_N_SUPPORT //
-			pAd->CommonCfg.SupRate[0]  = 0x8C;	  // 6 mbps, in units of 0.5 Mbps, basic rate
-			pAd->CommonCfg.SupRate[1]  = 0x12;	  // 9 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.SupRate[2]  = 0x98;	  // 12 mbps, in units of 0.5 Mbps, basic rate
-			pAd->CommonCfg.SupRate[3]  = 0x24;	  // 18 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.SupRate[4]  = 0xb0;	  // 24 mbps, in units of 0.5 Mbps, basic rate
-			pAd->CommonCfg.SupRate[5]  = 0x48;	  // 36 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.SupRate[6]  = 0x60;	  // 48 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.SupRate[7]  = 0x6c;	  // 54 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.SupRateLen  = 8;
-			pAd->CommonCfg.ExtRateLen  = 0;
-			pAd->CommonCfg.DesireRate[0]  = 12;    // 6 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[1]  = 18;    // 9 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[2]  = 24;    // 12 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[3]  = 36;    // 18 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[4]  = 48;    // 24 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[5]  = 72;    // 36 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[6]  = 96;    // 48 mbps, in units of 0.5 Mbps
-			pAd->CommonCfg.DesireRate[7]  = 108;   // 54 mbps, in units of 0.5 Mbps
-			//pAd->CommonCfg.HTPhyMode.field.MODE = MODE_OFDM; // This MODE is only FYI. not use
-			break;
-
-		default:
-			break;
-	}
-
-
-	pAd->CommonCfg.BandState = UNKNOWN_BAND;
-}
-
-
-#ifdef DOT11_N_SUPPORT
-/*
-	========================================================================
-	Routine Description:
-		Caller ensures we has 802.11n support.
-		Calls at setting HT from AP/STASetinformation
-
-	Arguments:
-		pAd - Pointer to our adapter
-		phymode  -
-
-	========================================================================
-*/
-VOID	RTMPSetHT(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	OID_SET_HT_PHYMODE *pHTPhyMode)
-{
-	//ULONG	*pmcs;
-	UINT32	Value = 0;
-	UCHAR	BBPValue = 0;
-	UCHAR	BBP3Value = 0;
-	UCHAR	RxStream = pAd->CommonCfg.RxStream;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : HT_mode(%d), ExtOffset(%d), MCS(%d), BW(%d), STBC(%d), SHORTGI(%d)\n",
-										pHTPhyMode->HtMode, pHTPhyMode->ExtOffset,
-										pHTPhyMode->MCS, pHTPhyMode->BW,
-										pHTPhyMode->STBC, pHTPhyMode->SHORTGI));
-
-	// Don't zero supportedHyPhy structure.
-	RTMPZeroMemory(&pAd->CommonCfg.HtCapability, sizeof(pAd->CommonCfg.HtCapability));
-	RTMPZeroMemory(&pAd->CommonCfg.AddHTInfo, sizeof(pAd->CommonCfg.AddHTInfo));
-	RTMPZeroMemory(&pAd->CommonCfg.NewExtChanOffset, sizeof(pAd->CommonCfg.NewExtChanOffset));
-	RTMPZeroMemory(&pAd->CommonCfg.DesiredHtPhy, sizeof(pAd->CommonCfg.DesiredHtPhy));
-
-	if (pAd->CommonCfg.bRdg)
-	{
-		pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 1;
-		pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 1;
-	}
-	else
-	{
-		pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 0;
-		pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 0;
-	}
-
-	pAd->CommonCfg.HtCapability.HtCapParm.MaxRAmpduFactor = 3;
-	pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor = 3;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : RxBAWinLimit = %d\n", pAd->CommonCfg.BACapability.field.RxBAWinLimit));
-
-	// Mimo power save, A-MSDU size,
-	pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable;
-	pAd->CommonCfg.DesiredHtPhy.AmsduSize = (UCHAR)pAd->CommonCfg.BACapability.field.AmsduSize;
-	pAd->CommonCfg.DesiredHtPhy.MimoPs = (UCHAR)pAd->CommonCfg.BACapability.field.MMPSmode;
-	pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
-
-	pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
-	pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
-	pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : AMsduSize = %d, MimoPs = %d, MpduDensity = %d, MaxRAmpduFactor = %d\n",
-													pAd->CommonCfg.DesiredHtPhy.AmsduSize,
-													pAd->CommonCfg.DesiredHtPhy.MimoPs,
-													pAd->CommonCfg.DesiredHtPhy.MpduDensity,
-													pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor));
-
-	if(pHTPhyMode->HtMode == HTMODE_GF)
-	{
-		pAd->CommonCfg.HtCapability.HtCapInfo.GF = 1;
-		pAd->CommonCfg.DesiredHtPhy.GF = 1;
-	}
-	else
-		pAd->CommonCfg.DesiredHtPhy.GF = 0;
-
-	// Decide Rx MCSSet
-	switch (RxStream)
-	{
-		case 1:
-			pAd->CommonCfg.HtCapability.MCSSet[0] =  0xff;
-			pAd->CommonCfg.HtCapability.MCSSet[1] =  0x00;
-			break;
-
-		case 2:
-			pAd->CommonCfg.HtCapability.MCSSet[0] =  0xff;
-			pAd->CommonCfg.HtCapability.MCSSet[1] =  0xff;
-			break;
-
-		case 3: // 3*3
-			pAd->CommonCfg.HtCapability.MCSSet[0] =  0xff;
-			pAd->CommonCfg.HtCapability.MCSSet[1] =  0xff;
-			pAd->CommonCfg.HtCapability.MCSSet[2] =  0xff;
-			break;
-	}
-
-	if (pAd->CommonCfg.bForty_Mhz_Intolerant && (pAd->CommonCfg.Channel <= 14) && (pHTPhyMode->BW == BW_40) )
-	{
-		pHTPhyMode->BW = BW_20;
-		pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant = 1;
-	}
-
-	if(pHTPhyMode->BW == BW_40)
-	{
-		pAd->CommonCfg.HtCapability.MCSSet[4] = 0x1; // MCS 32
-		pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 1;
-		if (pAd->CommonCfg.Channel <= 14)
-			pAd->CommonCfg.HtCapability.HtCapInfo.CCKmodein40 = 1;
-
-		pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 1;
-		pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 1;
-		pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = (pHTPhyMode->ExtOffset == EXTCHA_BELOW)? (EXTCHA_BELOW): EXTCHA_ABOVE;
-		// Set Regsiter for extension channel position.
-		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBP3Value);
-		if ((pHTPhyMode->ExtOffset == EXTCHA_BELOW))
-		{
-			Value |= 0x1;
-			BBP3Value |= (0x20);
-			RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
-		}
-		else if ((pHTPhyMode->ExtOffset == EXTCHA_ABOVE))
-		{
-			Value &= 0xfe;
-			BBP3Value &= (~0x20);
-			RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
-		}
-
-		// Turn on BBP 40MHz mode now only as AP .
-		// Sta can turn on BBP 40MHz after connection with 40MHz AP. Sta only broadcast 40MHz capability before connection.
-		if ((pAd->OpMode == OPMODE_AP) || INFRA_ON(pAd) || ADHOC_ON(pAd)
-			)
-		{
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-			BBPValue &= (~0x18);
-			BBPValue |= 0x10;
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBP3Value);
-			pAd->CommonCfg.BBPCurrentBW = BW_40;
-		}
-	}
-	else
-	{
-		pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 0;
-		pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 0;
-		pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0;
-		pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = EXTCHA_NONE;
-		pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
-		// Turn on BBP 20MHz mode by request here.
-		{
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-			BBPValue &= (~0x18);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-			pAd->CommonCfg.BBPCurrentBW = BW_20;
-		}
-	}
-
-	if(pHTPhyMode->STBC == STBC_USE)
-	{
-		pAd->CommonCfg.HtCapability.HtCapInfo.TxSTBC = 1;
-		pAd->CommonCfg.DesiredHtPhy.TxSTBC = 1;
-		pAd->CommonCfg.HtCapability.HtCapInfo.RxSTBC = 1;
-		pAd->CommonCfg.DesiredHtPhy.RxSTBC = 1;
-	}
-	else
-	{
-		pAd->CommonCfg.DesiredHtPhy.TxSTBC = 0;
-		pAd->CommonCfg.DesiredHtPhy.RxSTBC = 0;
-	}
-
-	if(pHTPhyMode->SHORTGI == GI_400)
-	{
-		pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 1;
-		pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 1;
-		pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 1;
-		pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 1;
-	}
-	else
-	{
-		pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 0;
-		pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 0;
-		pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 0;
-		pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 0;
-	}
-
-	// We support link adaptation for unsolicit MCS feedback, set to 2.
-	pAd->CommonCfg.HtCapability.ExtHtCapInfo.MCSFeedback = MCSFBK_NONE; //MCSFBK_UNSOLICIT;
-	pAd->CommonCfg.AddHTInfo.ControlChan = pAd->CommonCfg.Channel;
-	// 1, the extension channel above the control channel.
-
-	// EDCA parameters used for AP's own transmission
-	if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
-	{
-		pAd->CommonCfg.APEdcaParm.bValid = TRUE;
-		pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
-		pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
-		pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
-		pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
-
-		pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
-		pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
-		pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
-		pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
-
-		pAd->CommonCfg.APEdcaParm.Cwmax[0] = 6;
-		pAd->CommonCfg.APEdcaParm.Cwmax[1] = 10;
-		pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
-		pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
-
-		pAd->CommonCfg.APEdcaParm.Txop[0]  = 0;
-		pAd->CommonCfg.APEdcaParm.Txop[1]  = 0;
-		pAd->CommonCfg.APEdcaParm.Txop[2]  = 94;
-		pAd->CommonCfg.APEdcaParm.Txop[3]  = 47;
-	}
-	AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
-
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-		RTMPSetIndividualHT(pAd, 0);
-		}
-#endif // CONFIG_STA_SUPPORT //
-
-}
-
-/*
-	========================================================================
-	Routine Description:
-		Caller ensures we has 802.11n support.
-		Calls at setting HT from AP/STASetinformation
-
-	Arguments:
-		pAd - Pointer to our adapter
-		phymode  -
-
-	========================================================================
-*/
-VOID	RTMPSetIndividualHT(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	UCHAR				apidx)
-{
-	PRT_HT_PHY_INFO		pDesired_ht_phy = NULL;
-	UCHAR	TxStream = pAd->CommonCfg.TxStream;
-	UCHAR	DesiredMcs	= MCS_AUTO;
-
-	do
-	{
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			pDesired_ht_phy = &pAd->StaCfg.DesiredHtPhyInfo;
-			DesiredMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
-			//pAd->StaCfg.bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE;
-				break;
-		}
-#endif // CONFIG_STA_SUPPORT //
-	} while (FALSE);
-
-	if (pDesired_ht_phy == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx));
-		return;
-	}
-	RTMPZeroMemory(pDesired_ht_phy, sizeof(RT_HT_PHY_INFO));
-
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetIndividualHT : Desired MCS = %d\n", DesiredMcs));
-	// Check the validity of MCS
-	if ((TxStream == 1) && ((DesiredMcs >= MCS_8) && (DesiredMcs <= MCS_15)))
-	{
-		DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS(%d) is invalid in 1S, reset it as MCS_7\n", DesiredMcs));
-		DesiredMcs = MCS_7;
-	}
-
-	if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_20) && (DesiredMcs == MCS_32))
-	{
-		DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS_32 is only supported in 40-MHz, reset it as MCS_0\n"));
-		DesiredMcs = MCS_0;
-	}
-
-	pDesired_ht_phy->bHtEnable = TRUE;
-
-	// Decide desired Tx MCS
-	switch (TxStream)
-	{
-		case 1:
-			if (DesiredMcs == MCS_AUTO)
-			{
-				pDesired_ht_phy->MCSSet[0]= 0xff;
-				pDesired_ht_phy->MCSSet[1]= 0x00;
-			}
-			else if (DesiredMcs <= MCS_7)
-			{
-				pDesired_ht_phy->MCSSet[0]= 1<<DesiredMcs;
-				pDesired_ht_phy->MCSSet[1]= 0x00;
-			}
-			break;
-
-		case 2:
-			if (DesiredMcs == MCS_AUTO)
-			{
-				pDesired_ht_phy->MCSSet[0]= 0xff;
-				pDesired_ht_phy->MCSSet[1]= 0xff;
-			}
-			else if (DesiredMcs <= MCS_15)
-			{
-				ULONG mode;
-
-				mode = DesiredMcs / 8;
-				if (mode < 2)
-					pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8));
-			}
-			break;
-
-		case 3: // 3*3
-			if (DesiredMcs == MCS_AUTO)
-			{
-				/* MCS0 ~ MCS23, 3 bytes */
-				pDesired_ht_phy->MCSSet[0]= 0xff;
-				pDesired_ht_phy->MCSSet[1]= 0xff;
-				pDesired_ht_phy->MCSSet[2]= 0xff;
-			}
-			else if (DesiredMcs <= MCS_23)
-			{
-				ULONG mode;
-
-				mode = DesiredMcs / 8;
-				if (mode < 3)
-					pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8));
-			}
-			break;
-	}
-
-	if(pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_40)
-	{
-		if (DesiredMcs == MCS_AUTO || DesiredMcs == MCS_32)
-			pDesired_ht_phy->MCSSet[4] = 0x1;
-	}
-
-	// update HT Rate setting
-    if (pAd->OpMode == OPMODE_STA)
-        MlmeUpdateHtTxRates(pAd, BSS0);
-    else
-	    MlmeUpdateHtTxRates(pAd, apidx);
-}
-
-
-/*
-	========================================================================
-	Routine Description:
-		Update HT IE from our capability.
-
-	Arguments:
-		Send all HT IE in beacon/probe rsp/assoc rsp/action frame.
-
-
-	========================================================================
-*/
-VOID	RTMPUpdateHTIE(
-	IN	RT_HT_CAPABILITY	*pRtHt,
-	IN		UCHAR				*pMcsSet,
-	OUT		HT_CAPABILITY_IE *pHtCapability,
-	OUT		ADD_HT_INFO_IE		*pAddHtInfo)
-{
-	RTMPZeroMemory(pHtCapability, sizeof(HT_CAPABILITY_IE));
-	RTMPZeroMemory(pAddHtInfo, sizeof(ADD_HT_INFO_IE));
-
-		pHtCapability->HtCapInfo.ChannelWidth = pRtHt->ChannelWidth;
-		pHtCapability->HtCapInfo.MimoPs = pRtHt->MimoPs;
-		pHtCapability->HtCapInfo.GF = pRtHt->GF;
-		pHtCapability->HtCapInfo.ShortGIfor20 = pRtHt->ShortGIfor20;
-		pHtCapability->HtCapInfo.ShortGIfor40 = pRtHt->ShortGIfor40;
-		pHtCapability->HtCapInfo.TxSTBC = pRtHt->TxSTBC;
-		pHtCapability->HtCapInfo.RxSTBC = pRtHt->RxSTBC;
-		pHtCapability->HtCapInfo.AMsduSize = pRtHt->AmsduSize;
-		pHtCapability->HtCapParm.MaxRAmpduFactor = pRtHt->MaxRAmpduFactor;
-		pHtCapability->HtCapParm.MpduDensity = pRtHt->MpduDensity;
-
-		pAddHtInfo->AddHtInfo.ExtChanOffset = pRtHt->ExtChanOffset ;
-		pAddHtInfo->AddHtInfo.RecomWidth = pRtHt->RecomWidth;
-		pAddHtInfo->AddHtInfo2.OperaionMode = pRtHt->OperaionMode;
-		pAddHtInfo->AddHtInfo2.NonGfPresent = pRtHt->NonGfPresent;
-		RTMPMoveMemory(pAddHtInfo->MCSSet, /*pRtHt->MCSSet*/pMcsSet, 4); // rt2860 only support MCS max=32, no need to copy all 16 uchar.
-
-        DBGPRINT(RT_DEBUG_TRACE,("RTMPUpdateHTIE <== \n"));
-}
-#endif // DOT11_N_SUPPORT //
-
-/*
-	========================================================================
-	Description:
-		Add Client security information into ASIC WCID table and IVEIV table.
-    Return:
-	========================================================================
-*/
-VOID	RTMPAddWcidAttributeEntry(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			BssIdx,
-	IN	UCHAR			KeyIdx,
-	IN	UCHAR			CipherAlg,
-	IN	MAC_TABLE_ENTRY *pEntry)
-{
-	UINT32		WCIDAttri = 0;
-	USHORT		offset;
-	UCHAR		IVEIV = 0;
-	USHORT		Wcid = 0;
-
-	{
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			if (BssIdx > BSS0)
-			{
-				DBGPRINT(RT_DEBUG_ERROR, ("RTMPAddWcidAttributeEntry: The BSS-index(%d) is out of range for Infra link. \n", BssIdx));
-				return;
-			}
-
-			// 1.	In ADHOC mode, the AID is wcid number. And NO mesh link exists.
-			// 2.	In Infra mode, the AID:1 MUST be wcid of infra STA.
-			//					   the AID:2~ assign to mesh link entry.
-			if (pEntry)
-				Wcid = pEntry->Aid;
-			else
-				Wcid = MCAST_WCID;
-		}
-#endif // CONFIG_STA_SUPPORT //
-	}
-
-	// Update WCID attribute table
-	offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		if (pEntry && pEntry->ValidAsMesh)
-			WCIDAttri = (CipherAlg<<1) | PAIRWISEKEYTABLE;
-#ifdef QOS_DLS_SUPPORT
-		else if ((pEntry) && (pEntry->ValidAsDls) &&
-					((CipherAlg == CIPHER_TKIP) ||
-					(CipherAlg == CIPHER_TKIP_NO_MIC) ||
-					(CipherAlg == CIPHER_AES) ||
-					(CipherAlg == CIPHER_NONE)))
-			WCIDAttri = (CipherAlg<<1) | PAIRWISEKEYTABLE;
-#endif // QOS_DLS_SUPPORT //
-		else
-		WCIDAttri = (CipherAlg<<1) | SHAREDKEYTABLE;
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
-
-
-	// Update IV/EIV table
-	offset = MAC_IVEIV_TABLE_BASE + (Wcid * HW_IVEIV_ENTRY_SIZE);
-
-	// WPA mode
-	if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) || (CipherAlg == CIPHER_AES))
-	{
-		// Eiv bit on. keyid always is 0 for pairwise key
-		IVEIV = (KeyIdx <<6) | 0x20;
-	}
-	else
-	{
-		// WEP KeyIdx is default tx key.
-		IVEIV = (KeyIdx << 6);
-	}
-
-	// For key index and ext IV bit, so only need to update the position(offset+3).
-#ifdef RTMP_MAC_PCI
-	RTMP_IO_WRITE8(pAd, offset+3, IVEIV);
-#endif // RTMP_MAC_PCI //
-
-	DBGPRINT(RT_DEBUG_TRACE,("RTMPAddWcidAttributeEntry: WCID #%d, KeyIndex #%d, Alg=%s\n",Wcid, KeyIdx, CipherName[CipherAlg]));
-	DBGPRINT(RT_DEBUG_TRACE,("	WCIDAttri = 0x%x \n",  WCIDAttri));
-
-}
-
-/*
-    ==========================================================================
-    Description:
-        Parse encryption type
-Arguments:
-    pAdapter                    Pointer to our adapter
-    wrq                         Pointer to the ioctl argument
-
-    Return Value:
-        None
-
-    Note:
-    ==========================================================================
-*/
-PSTRING GetEncryptType(CHAR enc)
-{
-    if(enc == Ndis802_11WEPDisabled)
-        return "NONE";
-    if(enc == Ndis802_11WEPEnabled)
-	return "WEP";
-    if(enc == Ndis802_11Encryption2Enabled)
-	return "TKIP";
-    if(enc == Ndis802_11Encryption3Enabled)
-	return "AES";
-	if(enc == Ndis802_11Encryption4Enabled)
-	return "TKIPAES";
-    else
-	return "UNKNOW";
-}
-
-PSTRING GetAuthMode(CHAR auth)
-{
-    if(auth == Ndis802_11AuthModeOpen)
-	return "OPEN";
-    if(auth == Ndis802_11AuthModeShared)
-	return "SHARED";
-	if(auth == Ndis802_11AuthModeAutoSwitch)
-	return "AUTOWEP";
-    if(auth == Ndis802_11AuthModeWPA)
-	return "WPA";
-    if(auth == Ndis802_11AuthModeWPAPSK)
-	return "WPAPSK";
-    if(auth == Ndis802_11AuthModeWPANone)
-	return "WPANONE";
-    if(auth == Ndis802_11AuthModeWPA2)
-	return "WPA2";
-    if(auth == Ndis802_11AuthModeWPA2PSK)
-	return "WPA2PSK";
-	if(auth == Ndis802_11AuthModeWPA1WPA2)
-	return "WPA1WPA2";
-	if(auth == Ndis802_11AuthModeWPA1PSKWPA2PSK)
-	return "WPA1PSKWPA2PSK";
-
-	return "UNKNOW";
-}
-
-
-/*
-    ==========================================================================
-    Description:
-        Get site survey results
-	Arguments:
-	    pAdapter                    Pointer to our adapter
-	    wrq                         Pointer to the ioctl argument
-
-    Return Value:
-        None
-
-    Note:
-        Usage:
-			1.) UI needs to wait 4 seconds after issue a site survey command
-			2.) iwpriv ra0 get_site_survey
-			3.) UI needs to prepare at least 4096bytes to get the results
-    ==========================================================================
-*/
-#define	LINE_LEN	(4+33+20+23+9+7+3)	// Channel+SSID+Bssid+Security+Signal+WiressMode+NetworkType
-#ifdef CONFIG_STA_SUPPORT
-#endif // CONFIG_STA_SUPPORT //
-VOID	RTMPCommSiteSurveyData(
-	IN  PSTRING		msg,
-	IN  PBSS_ENTRY	pBss)
-{
-	INT         Rssi = 0;
-	UINT        Rssi_Quality = 0;
-	NDIS_802_11_NETWORK_TYPE    wireless_mode;
-	CHAR		Ssid[MAX_LEN_OF_SSID +1];
-	STRING		SecurityStr[32] = {0};
-	NDIS_802_11_ENCRYPTION_STATUS	ap_cipher = Ndis802_11EncryptionDisabled;
-	NDIS_802_11_AUTHENTICATION_MODE	ap_auth_mode = Ndis802_11AuthModeOpen;
-
-	memset(Ssid, 0 ,(MAX_LEN_OF_SSID +1));
-
-		//Channel
-		sprintf(msg+strlen(msg),"%-4d", pBss->Channel);
-		//SSID
-		memcpy(Ssid, pBss->Ssid, pBss->SsidLen);
-		Ssid[pBss->SsidLen] = '\0';
-		sprintf(msg+strlen(msg),"%-33s", Ssid);
-		//BSSID
-		sprintf(msg+strlen(msg),"%02x:%02x:%02x:%02x:%02x:%02x   ",
-			pBss->Bssid[0],
-			pBss->Bssid[1],
-			pBss->Bssid[2],
-			pBss->Bssid[3],
-			pBss->Bssid[4],
-			pBss->Bssid[5]);
-
-	//Security
-	if ((Ndis802_11AuthModeWPA <= pBss->AuthMode) &&
-		(pBss->AuthMode <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
-	{
-		if (pBss->AuthModeAux == Ndis802_11AuthModeWPANone)
-		{
-			ap_auth_mode = pBss->AuthMode;
-			if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
-				ap_cipher = pBss->WPA.PairCipher;
-			else
-				ap_cipher = Ndis802_11Encryption4Enabled;
-		}
-		else if (pBss->AuthModeAux == Ndis802_11AuthModeOpen)
-		{
-			ap_auth_mode = pBss->AuthMode;
-			if ((ap_auth_mode == Ndis802_11AuthModeWPA) ||
-				(ap_auth_mode == Ndis802_11AuthModeWPAPSK))
-			{
-				if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
-					ap_cipher = pBss->WPA.PairCipher;
-				else
-					ap_cipher = Ndis802_11Encryption4Enabled;
-			}
-			else if ((ap_auth_mode == Ndis802_11AuthModeWPA2) ||
-					 (ap_auth_mode == Ndis802_11AuthModeWPA2PSK))
-			{
-				if (pBss->WPA2.PairCipherAux == Ndis802_11WEPDisabled)
-					ap_cipher = pBss->WPA2.PairCipher;
-				else
-					ap_cipher = Ndis802_11Encryption4Enabled;
-			}
-		}
-		else if ((pBss->AuthMode == Ndis802_11AuthModeWPAPSK) ||
-				 (pBss->AuthMode == Ndis802_11AuthModeWPA2PSK))
-		{
-			if ((pBss->AuthModeAux == Ndis802_11AuthModeWPAPSK) ||
-				(pBss->AuthModeAux == Ndis802_11AuthModeWPA2PSK))
-				ap_auth_mode = Ndis802_11AuthModeWPA1PSKWPA2PSK;
-			else
-				ap_auth_mode = pBss->AuthMode;
-
-			if (pBss->WPA.PairCipher != pBss->WPA2.PairCipher)
-				ap_cipher = Ndis802_11Encryption4Enabled;
-			else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
-					 (pBss->WPA.PairCipherAux != pBss->WPA2.PairCipherAux))
-				ap_cipher = Ndis802_11Encryption4Enabled;
-			else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
-					 (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) &&
-					 (pBss->WPA.PairCipherAux != Ndis802_11WEPDisabled))
-				ap_cipher = Ndis802_11Encryption4Enabled;
-			else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
-					 (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) &&
-					 (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled))
-				ap_cipher = pBss->WPA.PairCipher;
-		}
-		else if ((pBss->AuthMode == Ndis802_11AuthModeWPA) ||
-				 (pBss->AuthMode == Ndis802_11AuthModeWPA2))
-		{
-			if ((pBss->AuthModeAux == Ndis802_11AuthModeWPA) ||
-				(pBss->AuthMode == Ndis802_11AuthModeWPA2))
-				ap_auth_mode = Ndis802_11AuthModeWPA1WPA2;
-			else
-				ap_auth_mode = pBss->AuthMode;
-
-			if (pBss->WPA.PairCipher != pBss->WPA2.PairCipher)
-				ap_cipher = Ndis802_11Encryption4Enabled;
-			else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
-					 (pBss->WPA.PairCipherAux != pBss->WPA2.PairCipherAux))
-				ap_cipher = Ndis802_11Encryption4Enabled;
-			else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
-					 (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) &&
-					 (pBss->WPA.PairCipherAux != Ndis802_11WEPDisabled))
-				ap_cipher = Ndis802_11Encryption4Enabled;
-			else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
-					 (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) &&
-					 (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled))
-				ap_cipher = pBss->WPA.PairCipher;
-		}
-
-		sprintf(SecurityStr, "%s/%s", GetAuthMode((CHAR)ap_auth_mode), GetEncryptType((CHAR)ap_cipher));
-	}
-	else
-	{
-		ap_auth_mode = pBss->AuthMode;
-		ap_cipher = pBss->WepStatus;
-		if (ap_cipher == Ndis802_11WEPDisabled)
-			sprintf(SecurityStr, "NONE");
-		else if (ap_cipher == Ndis802_11WEPEnabled)
-			sprintf(SecurityStr, "WEP");
-		else
-			sprintf(SecurityStr, "%s/%s", GetAuthMode((CHAR)ap_auth_mode), GetEncryptType((CHAR)ap_cipher));
-	}
-
-	sprintf(msg+strlen(msg), "%-23s", SecurityStr);
-
-		// Rssi
-		Rssi = (INT)pBss->Rssi;
-		if (Rssi >= -50)
-			Rssi_Quality = 100;
-		else if (Rssi >= -80)    // between -50 ~ -80dbm
-			Rssi_Quality = (UINT)(24 + ((Rssi + 80) * 26)/10);
-		else if (Rssi >= -90)   // between -80 ~ -90dbm
-			Rssi_Quality = (UINT)(((Rssi + 90) * 26)/10);
-		else    // < -84 dbm
-			Rssi_Quality = 0;
-		sprintf(msg+strlen(msg),"%-9d", Rssi_Quality);
-		// Wireless Mode
-		wireless_mode = NetworkTypeInUseSanity(pBss);
-		if (wireless_mode == Ndis802_11FH ||
-			wireless_mode == Ndis802_11DS)
-			sprintf(msg+strlen(msg),"%-7s", "11b");
-		else if (wireless_mode == Ndis802_11OFDM5)
-			sprintf(msg+strlen(msg),"%-7s", "11a");
-		else if (wireless_mode == Ndis802_11OFDM5_N)
-			sprintf(msg+strlen(msg),"%-7s", "11a/n");
-		else if (wireless_mode == Ndis802_11OFDM24)
-			sprintf(msg+strlen(msg),"%-7s", "11b/g");
-		else if (wireless_mode == Ndis802_11OFDM24_N)
-			sprintf(msg+strlen(msg),"%-7s", "11b/g/n");
-		else
-			sprintf(msg+strlen(msg),"%-7s", "unknow");
-		//Network Type
-		if (pBss->BssType == BSS_ADHOC)
-			sprintf(msg+strlen(msg),"%-3s", " Ad");
-		else
-			sprintf(msg+strlen(msg),"%-3s", " In");
-
-        sprintf(msg+strlen(msg),"\n");
-
-	return;
-}
-
-VOID RTMPIoctlGetSiteSurvey(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq)
-{
-	PSTRING		msg;
-	INT		i=0;
-	INT			WaitCnt;
-	INT		Status=0;
-    INT         max_len = LINE_LEN;
-	PBSS_ENTRY	pBss;
-
-#ifdef CONFIG_STA_SUPPORT
-#endif // CONFIG_STA_SUPPORT //
-
-	os_alloc_mem(NULL, (PUCHAR *)&msg, sizeof(CHAR)*((MAX_LEN_OF_BSS_TABLE)*max_len));
-
-	if (msg == NULL)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - msg memory alloc fail.\n"));
-		return;
-	}
-
-	memset(msg, 0 ,(MAX_LEN_OF_BSS_TABLE)*max_len );
-	sprintf(msg,"%s","\n");
-	sprintf(msg+strlen(msg),"%-4s%-33s%-20s%-23s%-9s%-7s%-3s\n",
-	    "Ch", "SSID", "BSSID", "Security", "Siganl(%)", "W-Mode", " NT");
-
-#ifdef CONFIG_STA_SUPPORT
-
-#endif // CONFIG_STA_SUPPORT //
-
-	WaitCnt = 0;
-#ifdef CONFIG_STA_SUPPORT
-	pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
-	while ((ScanRunning(pAdapter) == TRUE) && (WaitCnt++ < 200))
-		OS_WAIT(500);
-#endif // CONFIG_STA_SUPPORT //
-
-	for(i=0; i<pAdapter->ScanTab.BssNr ;i++)
-	{
-		pBss = &pAdapter->ScanTab.BssEntry[i];
-
-		if( pBss->Channel==0)
-			break;
-
-		if((strlen(msg)+max_len ) >= IW_SCAN_MAX_DATA)
-			break;
-
-
-		RTMPCommSiteSurveyData(msg, pBss);
-
-#ifdef CONFIG_STA_SUPPORT
-
-#endif // CONFIG_STA_SUPPORT //
-	}
-
-#ifdef CONFIG_STA_SUPPORT
-	pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
-#endif // CONFIG_STA_SUPPORT //
-	wrq->u.data.length = strlen(msg);
-	Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - wrq->u.data.length = %d\n", wrq->u.data.length));
-	os_free_mem(NULL, (PUCHAR)msg);
-}
-
-#define	MAC_LINE_LEN	(14+4+4+10+10+10+6+6)	// Addr+aid+psm+datatime+rxbyte+txbyte+current tx rate+last tx rate
-VOID RTMPIoctlGetMacTable(
-	IN PRTMP_ADAPTER pAd,
-	IN struct iwreq *wrq)
-{
-	INT i;
-	RT_802_11_MAC_TABLE MacTab;
-	char *msg;
-
-	MacTab.Num = 0;
-	for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
-	{
-		if (pAd->MacTab.Content[i].ValidAsCLI && (pAd->MacTab.Content[i].Sst == SST_ASSOC))
-		{
-			COPY_MAC_ADDR(MacTab.Entry[MacTab.Num].Addr, &pAd->MacTab.Content[i].Addr);
-			MacTab.Entry[MacTab.Num].Aid = (UCHAR)pAd->MacTab.Content[i].Aid;
-			MacTab.Entry[MacTab.Num].Psm = pAd->MacTab.Content[i].PsMode;
-#ifdef DOT11_N_SUPPORT
-			MacTab.Entry[MacTab.Num].MimoPs = pAd->MacTab.Content[i].MmpsMode;
-#endif // DOT11_N_SUPPORT //
-
-			// Fill in RSSI per entry
-			MacTab.Entry[MacTab.Num].AvgRssi0 = pAd->MacTab.Content[i].RssiSample.AvgRssi0;
-			MacTab.Entry[MacTab.Num].AvgRssi1 = pAd->MacTab.Content[i].RssiSample.AvgRssi1;
-			MacTab.Entry[MacTab.Num].AvgRssi2 = pAd->MacTab.Content[i].RssiSample.AvgRssi2;
-
-			// the connected time per entry
-			MacTab.Entry[MacTab.Num].ConnectedTime = pAd->MacTab.Content[i].StaConnectTime;
-			MacTab.Entry[MacTab.Num].TxRate.field.MCS = pAd->MacTab.Content[i].HTPhyMode.field.MCS;
-			MacTab.Entry[MacTab.Num].TxRate.field.BW = pAd->MacTab.Content[i].HTPhyMode.field.BW;
-			MacTab.Entry[MacTab.Num].TxRate.field.ShortGI = pAd->MacTab.Content[i].HTPhyMode.field.ShortGI;
-			MacTab.Entry[MacTab.Num].TxRate.field.STBC = pAd->MacTab.Content[i].HTPhyMode.field.STBC;
-			MacTab.Entry[MacTab.Num].TxRate.field.rsv = pAd->MacTab.Content[i].HTPhyMode.field.rsv;
-			MacTab.Entry[MacTab.Num].TxRate.field.MODE = pAd->MacTab.Content[i].HTPhyMode.field.MODE;
-			MacTab.Entry[MacTab.Num].TxRate.word = pAd->MacTab.Content[i].HTPhyMode.word;
-
-			MacTab.Num += 1;
-		}
-	}
-	wrq->u.data.length = sizeof(RT_802_11_MAC_TABLE);
-	if (copy_to_user(wrq->u.data.pointer, &MacTab, wrq->u.data.length))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __FUNCTION__));
-	}
-
-	msg = kmalloc(sizeof(CHAR)*(MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN), MEM_ALLOC_FLAG);
-	if (msg == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s():Alloc memory failed\n", __FUNCTION__));
-		return;
-	}
-	memset(msg, 0 ,MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN );
-	sprintf(msg,"%s","\n");
-	sprintf(msg+strlen(msg),"%-14s%-4s%-4s%-10s%-10s%-10s%-6s%-6s\n",
-		"MAC", "AID", "PSM", "LDT", "RxB", "TxB","CTxR", "LTxR");
-
-	for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
-	{
-		PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
-		if (pEntry->ValidAsCLI && (pEntry->Sst == SST_ASSOC))
-		{
-			if((strlen(msg)+MAC_LINE_LEN ) >= (MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN) )
-				break;
-			sprintf(msg+strlen(msg),"%02x%02x%02x%02x%02x%02x  ",
-				pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
-				pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
-			sprintf(msg+strlen(msg),"%-4d", (int)pEntry->Aid);
-			sprintf(msg+strlen(msg),"%-4d", (int)pEntry->PsMode);
-			sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.LastDataPacketTime*/); // ToDo
-			sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.TotalRxByteCount*/); // ToDo
-			sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.TotalTxByteCount*/); // ToDo
-			sprintf(msg+strlen(msg),"%-6d",RateIdToMbps[pAd->MacTab.Content[i].CurrTxRate]);
-			sprintf(msg+strlen(msg),"%-6d\n",0/*RateIdToMbps[pAd->MacTab.Content[i].LastTxRate]*/); // ToDo
-		}
-	}
-	// for compatible with old API just do the printk to console
-	//wrq->u.data.length = strlen(msg);
-	//if (copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("%s", msg));
-	}
-
-	kfree(msg);
-}
-
-
-#ifdef DOT11_N_SUPPORT
-INT	Set_BASetup_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-    UCHAR mac[6], tid;
-	PSTRING token;
-	STRING sepValue[] = ":", DASH = '-';
-	INT i;
-    MAC_TABLE_ENTRY *pEntry;
-
-/*
-	The BASetup inupt string format should be xx:xx:xx:xx:xx:xx-d,
-		=>The six 2 digit hex-decimal number previous are the Mac address,
-		=>The seventh decimal number is the tid value.
-*/
-	//DBGPRINT(RT_DEBUG_TRACE,("\n%s\n", arg));
-
-	if(strlen(arg) < 19)  //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
-		return FALSE;
-
-	token = strchr(arg, DASH);
-	if ((token != NULL) && (strlen(token)>1))
-	{
-		tid = (UCHAR) simple_strtol((token+1), 0, 10);
-		if (tid > 15)
-			return FALSE;
-
-		*token = '\0';
-		for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
-		{
-			if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
-				return FALSE;
-			AtoH(token, (&mac[i]), 1);
-		}
-		if(i != 6)
-			return FALSE;
-
-		DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x\n",
-								mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], tid));
-
-	    pEntry = MacTableLookup(pAd, (PUCHAR) mac);
-
-	if (pEntry) {
-		DBGPRINT(RT_DEBUG_OFF, ("\nSetup BA Session: Tid = %d\n", tid));
-	        BAOriSessionSetUp(pAd, pEntry, tid, 0, 100, TRUE);
-	}
-
-		return TRUE;
-	}
-
-	return FALSE;
-
-}
-
-INT	Set_BADecline_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	ULONG bBADecline;
-
-	bBADecline = simple_strtol(arg, 0, 10);
-
-	if (bBADecline == 0)
-	{
-		pAd->CommonCfg.bBADecline = FALSE;
-	}
-	else if (bBADecline == 1)
-	{
-		pAd->CommonCfg.bBADecline = TRUE;
-	}
-	else
-	{
-		return FALSE; //Invalid argument
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_BADecline_Proc::(BADecline=%d)\n", pAd->CommonCfg.bBADecline));
-
-	return TRUE;
-}
-
-INT	Set_BAOriTearDown_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-    UCHAR mac[6], tid;
-	PSTRING token;
-	STRING sepValue[] = ":", DASH = '-';
-	INT i;
-    MAC_TABLE_ENTRY *pEntry;
-
-    //DBGPRINT(RT_DEBUG_TRACE,("\n%s\n", arg));
-/*
-	The BAOriTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
-		=>The six 2 digit hex-decimal number previous are the Mac address,
-		=>The seventh decimal number is the tid value.
-*/
-    if(strlen(arg) < 19)  //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
-		return FALSE;
-
-	token = strchr(arg, DASH);
-	if ((token != NULL) && (strlen(token)>1))
-	{
-		tid = simple_strtol((token+1), 0, 10);
-		if (tid > NUM_OF_TID)
-			return FALSE;
-
-		*token = '\0';
-		for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
-		{
-			if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
-				return FALSE;
-			AtoH(token, (&mac[i]), 1);
-		}
-		if(i != 6)
-			return FALSE;
-
-	    DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x",
-								mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], tid));
-
-	    pEntry = MacTableLookup(pAd, (PUCHAR) mac);
-
-	    if (pEntry) {
-	        DBGPRINT(RT_DEBUG_OFF, ("\nTear down Ori BA Session: Tid = %d\n", tid));
-	        BAOriSessionTearDown(pAd, pEntry->Aid, tid, FALSE, TRUE);
-	    }
-
-		return TRUE;
-	}
-
-	return FALSE;
-
-}
-
-INT	Set_BARecTearDown_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-    UCHAR mac[6], tid;
-	PSTRING token;
-	STRING sepValue[] = ":", DASH = '-';
-	INT i;
-    MAC_TABLE_ENTRY *pEntry;
-
-    //DBGPRINT(RT_DEBUG_TRACE,("\n%s\n", arg));
-/*
-	The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
-		=>The six 2 digit hex-decimal number previous are the Mac address,
-		=>The seventh decimal number is the tid value.
-*/
-    if(strlen(arg) < 19)  //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
-		return FALSE;
-
-	token = strchr(arg, DASH);
-	if ((token != NULL) && (strlen(token)>1))
-	{
-		tid = simple_strtol((token+1), 0, 10);
-		if (tid > NUM_OF_TID)
-			return FALSE;
-
-		*token = '\0';
-		for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
-		{
-			if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
-				return FALSE;
-			AtoH(token, (&mac[i]), 1);
-		}
-		if(i != 6)
-			return FALSE;
-
-		DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x",
-								mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], tid));
-
-		pEntry = MacTableLookup(pAd, (PUCHAR) mac);
-
-		if (pEntry) {
-		    DBGPRINT(RT_DEBUG_OFF, ("\nTear down Rec BA Session: Tid = %d\n", tid));
-		    BARecSessionTearDown(pAd, pEntry->Aid, tid, FALSE);
-		}
-
-		return TRUE;
-	}
-
-	return FALSE;
-
-}
-
-INT	Set_HtBw_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	ULONG HtBw;
-
-	HtBw = simple_strtol(arg, 0, 10);
-	if (HtBw == BW_40)
-		pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_40;
-	else if (HtBw == BW_20)
-		pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_20;
-	else
-		return FALSE;  //Invalid argument
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtBw_Proc::(HtBw=%d)\n", pAd->CommonCfg.RegTransmitSetting.field.BW));
-
-	return TRUE;
-}
-
-INT	Set_HtMcs_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	ULONG HtMcs, Mcs_tmp;
-#ifdef CONFIG_STA_SUPPORT
-    BOOLEAN bAutoRate = FALSE;
-#endif // CONFIG_STA_SUPPORT //
-
-	Mcs_tmp = simple_strtol(arg, 0, 10);
-
-	if (Mcs_tmp <= 15 || Mcs_tmp == 32)
-		HtMcs = Mcs_tmp;
-	else
-		HtMcs = MCS_AUTO;
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		pAd->StaCfg.DesiredTransmitSetting.field.MCS = HtMcs;
-		pAd->StaCfg.bAutoTxRateSwitch = (HtMcs == MCS_AUTO) ? TRUE:FALSE;
-		DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMcs_Proc::(HtMcs=%d, bAutoTxRateSwitch = %d)\n",
-						pAd->StaCfg.DesiredTransmitSetting.field.MCS, pAd->StaCfg.bAutoTxRateSwitch));
-
-		if ((pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED) ||
-			(pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE < MODE_HTMIX))
-		{
-	        if ((pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) &&
-				(HtMcs >= 0 && HtMcs <= 3) &&
-	            (pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode == FIXED_TXMODE_CCK))
-			{
-				RTMPSetDesiredRates(pAd, (LONG) (RateIdToMbps[HtMcs] * 1000000));
-			}
-	        else if ((pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) &&
-					(HtMcs >= 0 && HtMcs <= 7) &&
-			(pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode == FIXED_TXMODE_OFDM))
-			{
-				RTMPSetDesiredRates(pAd, (LONG) (RateIdToMbps[HtMcs+4] * 1000000));
-			}
-			else
-				bAutoRate = TRUE;
-
-			if (bAutoRate)
-			{
-	            pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
-				RTMPSetDesiredRates(pAd, -1);
-			}
-	        DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMcs_Proc::(FixedTxMode=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode));
-		}
-        if (ADHOC_ON(pAd))
-            return TRUE;
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	SetCommonHT(pAd);
-
-	return TRUE;
-}
-
-INT	Set_HtGi_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	ULONG HtGi;
-
-	HtGi = simple_strtol(arg, 0, 10);
-
-	if ( HtGi == GI_400)
-		pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400;
-	else if ( HtGi == GI_800 )
-		pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800;
-	else
-		return FALSE; //Invalid argument
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtGi_Proc::(ShortGI=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.ShortGI));
-
-	return TRUE;
-}
-
-
-INT	Set_HtTxBASize_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	UCHAR Size;
-
-	Size = simple_strtol(arg, 0, 10);
-
-	if (Size <=0 || Size >=64)
-	{
-		Size = 8;
-	}
-	pAd->CommonCfg.TxBASize = Size-1;
-	DBGPRINT(RT_DEBUG_ERROR, ("Set_HtTxBASize ::(TxBASize= %d)\n", Size));
-
-	return TRUE;
-}
-
-INT	Set_HtDisallowTKIP_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-
-	if (Value == 1)
-	{
-		pAd->CommonCfg.HT_DisallowTKIP = TRUE;
-	}
-	else
-	{
-		pAd->CommonCfg.HT_DisallowTKIP = FALSE;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtDisallowTKIP_Proc ::%s\n",
-				(pAd->CommonCfg.HT_DisallowTKIP == TRUE) ? "enabled" : "disabled"));
-
-	return TRUE;
-}
-
-INT	Set_HtOpMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-
-	if (Value == HTMODE_GF)
-		pAd->CommonCfg.RegTransmitSetting.field.HTMODE  = HTMODE_GF;
-	else if ( Value == HTMODE_MM )
-		pAd->CommonCfg.RegTransmitSetting.field.HTMODE  = HTMODE_MM;
-	else
-		return FALSE; //Invalid argument
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtOpMode_Proc::(HtOpMode=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.HTMODE));
-
-	return TRUE;
-
-}
-
-INT	Set_HtStbc_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-
-	if (Value == STBC_USE)
-		pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE;
-	else if ( Value == STBC_NONE )
-		pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE;
-	else
-		return FALSE; //Invalid argument
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_Stbc_Proc::(HtStbc=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.STBC));
-
-	return TRUE;
-}
-
-INT	Set_HtHtc_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-	if (Value == 0)
-		pAd->HTCEnable = FALSE;
-	else if ( Value ==1 )
-        pAd->HTCEnable = TRUE;
-	else
-		return FALSE; //Invalid argument
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtHtc_Proc::(HtHtc=%d)\n",pAd->HTCEnable));
-
-	return TRUE;
-}
-
-INT	Set_HtExtcha_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-
-	if (Value == 0)
-		pAd->CommonCfg.RegTransmitSetting.field.EXTCHA  = EXTCHA_BELOW;
-	else if ( Value ==1 )
-        pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
-	else
-		return FALSE; //Invalid argument
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtExtcha_Proc::(HtExtcha=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.EXTCHA));
-
-	return TRUE;
-}
-
-INT	Set_HtMpduDensity_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-
-	if (Value <=7 && Value >= 0)
-		pAd->CommonCfg.BACapability.field.MpduDensity = Value;
-	else
-		pAd->CommonCfg.BACapability.field.MpduDensity = 4;
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMpduDensity_Proc::(HtMpduDensity=%d)\n",pAd->CommonCfg.BACapability.field.MpduDensity));
-
-	return TRUE;
-}
-
-INT	Set_HtBaWinSize_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-
-
-	if (Value >=1 && Value <= 64)
-	{
-		pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value;
-		pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value;
-	}
-	else
-	{
-        pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64;
-		pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;
-	}
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtBaWinSize_Proc::(HtBaWinSize=%d)\n",pAd->CommonCfg.BACapability.field.RxBAWinLimit));
-
-	return TRUE;
-}
-
-INT	Set_HtRdg_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-
-	if (Value == 0)
-		pAd->CommonCfg.bRdg = FALSE;
-	else if ( Value ==1 )
-	{
-		pAd->HTCEnable = TRUE;
-        pAd->CommonCfg.bRdg = TRUE;
-	}
-	else
-		return FALSE; //Invalid argument
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtRdg_Proc::(HtRdg=%d)\n",pAd->CommonCfg.bRdg));
-
-	return TRUE;
-}
-
-INT	Set_HtLinkAdapt_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-	if (Value == 0)
-		pAd->bLinkAdapt = FALSE;
-	else if ( Value ==1 )
-	{
-			pAd->HTCEnable = TRUE;
-			pAd->bLinkAdapt = TRUE;
-	}
-	else
-		return FALSE; //Invalid argument
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtLinkAdapt_Proc::(HtLinkAdapt=%d)\n",pAd->bLinkAdapt));
-
-	return TRUE;
-}
-
-INT	Set_HtAmsdu_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-	if (Value == 0)
-		pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE;
-	else if ( Value == 1 )
-        pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE;
-	else
-		return FALSE; //Invalid argument
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtAmsdu_Proc::(HtAmsdu=%d)\n",pAd->CommonCfg.BACapability.field.AmsduEnable));
-
-	return TRUE;
-}
-
-INT	Set_HtAutoBa_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-	if (Value == 0)
-	{
-		pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
-		pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
-	}
-    else if (Value == 1)
-    {
-		pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
-		pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
-    }
-	else
-		return FALSE; //Invalid argument
-
-    pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
-	pAd->CommonCfg.REGBACapability.field.Policy = pAd->CommonCfg.BACapability.field.Policy;
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtAutoBa_Proc::(HtAutoBa=%d)\n",pAd->CommonCfg.BACapability.field.AutoBA));
-
-	return TRUE;
-
-}
-
-INT	Set_HtProtect_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-	if (Value == 0)
-		pAd->CommonCfg.bHTProtect = FALSE;
-    else if (Value == 1)
-		pAd->CommonCfg.bHTProtect = TRUE;
-	else
-		return FALSE; //Invalid argument
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtProtect_Proc::(HtProtect=%d)\n",pAd->CommonCfg.bHTProtect));
-
-	return TRUE;
-}
-
-INT	Set_SendPSMPAction_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-    UCHAR mac[6], mode;
-	PSTRING token;
-	STRING sepValue[] = ":", DASH = '-';
-	INT i;
-    MAC_TABLE_ENTRY *pEntry;
-
-    //DBGPRINT(RT_DEBUG_TRACE,("\n%s\n", arg));
-/*
-	The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
-		=>The six 2 digit hex-decimal number previous are the Mac address,
-		=>The seventh decimal number is the mode value.
-*/
-    if(strlen(arg) < 19)  //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and mode value in decimal format.
-		return FALSE;
-
-	token = strchr(arg, DASH);
-	if ((token != NULL) && (strlen(token)>1))
-	{
-		mode = simple_strtol((token+1), 0, 10);
-		if (mode > MMPS_ENABLE)
-			return FALSE;
-
-		*token = '\0';
-		for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
-		{
-			if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
-				return FALSE;
-			AtoH(token, (&mac[i]), 1);
-		}
-		if(i != 6)
-			return FALSE;
-
-		DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x",
-								mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], mode));
-
-		pEntry = MacTableLookup(pAd, mac);
-
-		if (pEntry) {
-		    DBGPRINT(RT_DEBUG_OFF, ("\nSendPSMPAction MIPS mode = %d\n", mode));
-		    SendPSMPAction(pAd, pEntry->Aid, mode);
-		}
-
-		return TRUE;
-	}
-
-	return FALSE;
-
-
-}
-
-INT	Set_HtMIMOPSmode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-
-	if (Value <=3 && Value >= 0)
-		pAd->CommonCfg.BACapability.field.MMPSmode = Value;
-	else
-		pAd->CommonCfg.BACapability.field.MMPSmode = 3;
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMIMOPSmode_Proc::(MIMOPS mode=%d)\n",pAd->CommonCfg.BACapability.field.MMPSmode));
-
-	return TRUE;
-}
-
-
-INT	Set_ForceShortGI_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-	if (Value == 0)
-		pAd->WIFItestbed.bShortGI = FALSE;
-	else if (Value == 1)
-		pAd->WIFItestbed.bShortGI = TRUE;
-	else
-		return FALSE; //Invalid argument
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_ForceShortGI_Proc::(ForceShortGI=%d)\n", pAd->WIFItestbed.bShortGI));
-
-	return TRUE;
-}
-
-
-
-INT	Set_ForceGF_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-	if (Value == 0)
-		pAd->WIFItestbed.bGreenField = FALSE;
-	else if (Value == 1)
-		pAd->WIFItestbed.bGreenField = TRUE;
-	else
-		return FALSE; //Invalid argument
-
-	SetCommonHT(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_ForceGF_Proc::(ForceGF=%d)\n", pAd->WIFItestbed.bGreenField));
-
-	return TRUE;
-}
-
-INT	Set_HtMimoPs_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-	if (Value == 0)
-		pAd->CommonCfg.bMIMOPSEnable = FALSE;
-	else if (Value == 1)
-		pAd->CommonCfg.bMIMOPSEnable = TRUE;
-	else
-		return FALSE; //Invalid argument
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMimoPs_Proc::(HtMimoPs=%d)\n",pAd->CommonCfg.bMIMOPSEnable));
-
-	return TRUE;
-}
-#endif // DOT11_N_SUPPORT //
-
-
-#ifdef DOT11_N_SUPPORT
-INT	SetCommonHT(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	OID_SET_HT_PHYMODE		SetHT;
-
-	if (pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED)
-		return FALSE;
-
-	SetHT.PhyMode = pAd->CommonCfg.PhyMode;
-	SetHT.TransmitNo = ((UCHAR)pAd->Antenna.field.TxPath);
-	SetHT.HtMode = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.HTMODE;
-	SetHT.ExtOffset = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
-	SetHT.MCS = MCS_AUTO;
-	SetHT.BW = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.BW;
-	SetHT.STBC = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.STBC;
-	SetHT.SHORTGI = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.ShortGI;
-
-	RTMPSetHT(pAd, &SetHT);
-
-	return TRUE;
-}
-#endif // DOT11_N_SUPPORT //
-
-INT	Set_FixedTxMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	UCHAR	fix_tx_mode = FIXED_TXMODE_HT;
-
-	if (strcmp(arg, "OFDM") == 0 || strcmp(arg, "ofdm") == 0)
-	{
-		fix_tx_mode = FIXED_TXMODE_OFDM;
-	}
-	else if (strcmp(arg, "CCK") == 0 || strcmp(arg, "cck") == 0)
-	{
-        fix_tx_mode = FIXED_TXMODE_CCK;
-	}
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode;
-#endif // CONFIG_STA_SUPPORT //
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_FixedTxMode_Proc::(FixedTxMode=%d)\n", fix_tx_mode));
-
-	return TRUE;
-}
-
-#ifdef CONFIG_APSTA_MIXED_SUPPORT
-INT	Set_OpMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	ULONG Value;
-
-	Value = simple_strtol(arg, 0, 10);
-
-#ifdef RTMP_MAC_PCI
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-#endif // RTMP_MAC_PCI //
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Can not switch operate mode on interface up !! \n"));
-		return FALSE;
-	}
-
-	if (Value == 0)
-		pAd->OpMode = OPMODE_STA;
-	else if (Value == 1)
-		pAd->OpMode = OPMODE_AP;
-	else
-		return FALSE; //Invalid argument
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_OpMode_Proc::(OpMode=%s)\n", pAd->OpMode == 1 ? "AP Mode" : "STA Mode"));
-
-	return TRUE;
-}
-#endif // CONFIG_APSTA_MIXED_SUPPORT //
-
-
-
-INT Set_LongRetryLimit_Proc(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	PSTRING			arg)
-{
-	TX_RTY_CFG_STRUC	tx_rty_cfg;
-	UCHAR				LongRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
-
-	RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
-	tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
-	RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
-	DBGPRINT(RT_DEBUG_TRACE, ("IF Set_LongRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
-	return TRUE;
-}
-
-INT Set_ShortRetryLimit_Proc(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	PSTRING			arg)
-{
-	TX_RTY_CFG_STRUC	tx_rty_cfg;
-	UCHAR				ShortRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
-
-	RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
-	tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
-	RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
-	DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
-	return TRUE;
-}
-
-
-/////////////////////////////////////////////////////////////////////////
-PSTRING RTMPGetRalinkAuthModeStr(
-    IN  NDIS_802_11_AUTHENTICATION_MODE authMode)
-{
-	switch(authMode)
-	{
-		case Ndis802_11AuthModeOpen:
-			return "OPEN";
-		case Ndis802_11AuthModeWPAPSK:
-			return "WPAPSK";
-		case Ndis802_11AuthModeShared:
-			return "SHARED";
-		case Ndis802_11AuthModeWPA:
-			return "WPA";
-		case Ndis802_11AuthModeWPA2:
-			return "WPA2";
-		case Ndis802_11AuthModeWPA2PSK:
-			return "WPA2PSK";
-        case Ndis802_11AuthModeWPA1PSKWPA2PSK:
-			return "WPAPSKWPA2PSK";
-        case Ndis802_11AuthModeWPA1WPA2:
-			return "WPA1WPA2";
-		case Ndis802_11AuthModeWPANone:
-			return "WPANONE";
-		default:
-			return "UNKNOW";
-	}
-}
-
-PSTRING RTMPGetRalinkEncryModeStr(
-    IN  USHORT encryMode)
-{
-	switch(encryMode)
-	{
-		case Ndis802_11WEPDisabled:
-			return "NONE";
-		case Ndis802_11WEPEnabled:
-			return "WEP";
-		case Ndis802_11Encryption2Enabled:
-			return "TKIP";
-		case Ndis802_11Encryption3Enabled:
-			return "AES";
-        case Ndis802_11Encryption4Enabled:
-			return "TKIPAES";
-		default:
-			return "UNKNOW";
-	}
-}
-
-INT RTMPShowCfgValue(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			pName,
-	IN	PSTRING			pBuf)
-{
-	INT	Status = 0;
-
-	for (PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC = RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC++)
-	{
-		if (!strcmp(pName, PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name))
-		{
-			if(PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->show_proc(pAd, pBuf))
-				Status = -EINVAL;
-			break;  //Exit for loop.
-		}
-	}
-
-	if(PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name == NULL)
-	{
-		sprintf(pBuf, "\n");
-		for (PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC = RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC++)
-			sprintf(pBuf, "%s%s\n", pBuf, PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name);
-	}
-
-	return Status;
-}
-
-INT	Show_SSID_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		sprintf(pBuf, "\t%s", pAd->CommonCfg.Ssid);
-#endif // CONFIG_STA_SUPPORT //
-	return 0;
-}
-
-INT	Show_WirelessMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	switch(pAd->CommonCfg.PhyMode)
-	{
-		case PHY_11BG_MIXED:
-			sprintf(pBuf, "\t11B/G");
-			break;
-		case PHY_11B:
-			sprintf(pBuf, "\t11B");
-			break;
-		case PHY_11A:
-			sprintf(pBuf, "\t11A");
-			break;
-		case PHY_11ABG_MIXED:
-			sprintf(pBuf, "\t11A/B/G");
-			break;
-		case PHY_11G:
-			sprintf(pBuf, "\t11G");
-			break;
-#ifdef DOT11_N_SUPPORT
-		case PHY_11ABGN_MIXED:
-			sprintf(pBuf, "\t11A/B/G/N");
-			break;
-		case PHY_11N_2_4G:
-			sprintf(pBuf, "\t11N only with 2.4G");
-			break;
-		case PHY_11GN_MIXED:
-			sprintf(pBuf, "\t11G/N");
-			break;
-		case PHY_11AN_MIXED:
-			sprintf(pBuf, "\t11A/N");
-			break;
-		case PHY_11BGN_MIXED:
-			sprintf(pBuf, "\t11B/G/N");
-			break;
-		case PHY_11AGN_MIXED:
-			sprintf(pBuf, "\t11A/G/N");
-			break;
-		case PHY_11N_5G:
-			sprintf(pBuf, "\t11N only with 5G");
-			break;
-#endif // DOT11_N_SUPPORT //
-		default:
-			sprintf(pBuf, "\tUnknow Value(%d)", pAd->CommonCfg.PhyMode);
-			break;
-	}
-	return 0;
-}
-
-
-INT	Show_TxBurst_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	sprintf(pBuf, "\t%s", pAd->CommonCfg.bEnableTxBurst ? "TRUE":"FALSE");
-	return 0;
-}
-
-INT	Show_TxPreamble_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	switch(pAd->CommonCfg.TxPreamble)
-	{
-		case Rt802_11PreambleShort:
-			sprintf(pBuf, "\tShort");
-			break;
-		case Rt802_11PreambleLong:
-			sprintf(pBuf, "\tLong");
-			break;
-		case Rt802_11PreambleAuto:
-			sprintf(pBuf, "\tAuto");
-			break;
-		default:
-			sprintf(pBuf, "\tUnknow Value(%lu)", pAd->CommonCfg.TxPreamble);
-			break;
-	}
-
-	return 0;
-}
-
-INT	Show_TxPower_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	sprintf(pBuf, "\t%lu", pAd->CommonCfg.TxPowerPercentage);
-	return 0;
-}
-
-INT	Show_Channel_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	sprintf(pBuf, "\t%d", pAd->CommonCfg.Channel);
-	return 0;
-}
-
-INT	Show_BGProtection_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	switch(pAd->CommonCfg.UseBGProtection)
-	{
-		case 1: //Always On
-			sprintf(pBuf, "\tON");
-			break;
-		case 2: //Always OFF
-			sprintf(pBuf, "\tOFF");
-			break;
-		case 0: //AUTO
-			sprintf(pBuf, "\tAuto");
-			break;
-		default:
-			sprintf(pBuf, "\tUnknow Value(%lu)", pAd->CommonCfg.UseBGProtection);
-			break;
-	}
-	return 0;
-}
-
-INT	Show_RTSThreshold_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	sprintf(pBuf, "\t%u", pAd->CommonCfg.RtsThreshold);
-	return 0;
-}
-
-INT	Show_FragThreshold_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	sprintf(pBuf, "\t%u", pAd->CommonCfg.FragmentThreshold);
-	return 0;
-}
-
-#ifdef DOT11_N_SUPPORT
-INT	Show_HtBw_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
-	{
-		sprintf(pBuf, "\t40 MHz");
-	}
-	else
-	{
-        sprintf(pBuf, "\t20 MHz");
-	}
-	return 0;
-}
-
-INT	Show_HtMcs_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		sprintf(pBuf, "\t%u", pAd->StaCfg.DesiredTransmitSetting.field.MCS);
-#endif // CONFIG_STA_SUPPORT //
-	return 0;
-}
-
-INT	Show_HtGi_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	switch(pAd->CommonCfg.RegTransmitSetting.field.ShortGI)
-	{
-		case GI_400:
-			sprintf(pBuf, "\tGI_400");
-			break;
-		case GI_800:
-			sprintf(pBuf, "\tGI_800");
-			break;
-		default:
-			sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.ShortGI);
-			break;
-	}
-	return 0;
-}
-
-INT	Show_HtOpMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	switch(pAd->CommonCfg.RegTransmitSetting.field.HTMODE)
-	{
-		case HTMODE_GF:
-			sprintf(pBuf, "\tGF");
-			break;
-		case HTMODE_MM:
-			sprintf(pBuf, "\tMM");
-			break;
-		default:
-			sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.HTMODE);
-			break;
-	}
-	return 0;
-}
-
-INT	Show_HtExtcha_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	switch(pAd->CommonCfg.RegTransmitSetting.field.EXTCHA)
-	{
-		case EXTCHA_BELOW:
-			sprintf(pBuf, "\tBelow");
-			break;
-		case EXTCHA_ABOVE:
-			sprintf(pBuf, "\tAbove");
-			break;
-		default:
-			sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.EXTCHA);
-			break;
-	}
-	return 0;
-}
-
-
-INT	Show_HtMpduDensity_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.MpduDensity);
-	return 0;
-}
-
-INT	Show_HtBaWinSize_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.RxBAWinLimit);
-	return 0;
-}
-
-INT	Show_HtRdg_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	sprintf(pBuf, "\t%s", pAd->CommonCfg.bRdg ? "TRUE":"FALSE");
-	return 0;
-}
-
-INT	Show_HtAmsdu_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AmsduEnable ? "TRUE":"FALSE");
-	return 0;
-}
-
-INT	Show_HtAutoBa_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AutoBA ? "TRUE":"FALSE");
-	return 0;
-}
-#endif // DOT11_N_SUPPORT //
-
-INT	Show_CountryRegion_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegion);
-	return 0;
-}
-
-INT	Show_CountryRegionABand_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegionForABand);
-	return 0;
-}
-
-INT	Show_CountryCode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	sprintf(pBuf, "\t%s", pAd->CommonCfg.CountryCode);
-	return 0;
-}
-
-#ifdef AGGREGATION_SUPPORT
-INT	Show_PktAggregate_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	sprintf(pBuf, "\t%s", pAd->CommonCfg.bAggregationCapable ? "TRUE":"FALSE");
-	return 0;
-}
-#endif // AGGREGATION_SUPPORT //
-
-#ifdef WMM_SUPPORT
-INT	Show_WmmCapable_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		sprintf(pBuf, "\t%s", pAd->CommonCfg.bWmmCapable ? "TRUE":"FALSE");
-#endif // CONFIG_STA_SUPPORT //
-
-	return 0;
-}
-#endif // WMM_SUPPORT //
-
-INT	Show_IEEE80211H_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	sprintf(pBuf, "\t%s", pAd->CommonCfg.bIEEE80211H ? "TRUE":"FALSE");
-	return 0;
-}
-
-#ifdef CONFIG_STA_SUPPORT
-INT	Show_NetworkType_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	switch(pAd->StaCfg.BssType)
-	{
-		case BSS_ADHOC:
-			sprintf(pBuf, "\tAdhoc");
-			break;
-		case BSS_INFRA:
-			sprintf(pBuf, "\tInfra");
-			break;
-		case BSS_ANY:
-			sprintf(pBuf, "\tAny");
-			break;
-		case BSS_MONITOR:
-			sprintf(pBuf, "\tMonitor");
-			break;
-		default:
-			sprintf(pBuf, "\tUnknow Value(%d)", pAd->StaCfg.BssType);
-			break;
-	}
-	return 0;
-}
-
-
-#endif // CONFIG_STA_SUPPORT //
-
-INT	Show_AuthMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	NDIS_802_11_AUTHENTICATION_MODE	AuthMode = Ndis802_11AuthModeOpen;
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		AuthMode = pAd->StaCfg.AuthMode;
-#endif // CONFIG_STA_SUPPORT //
-
-	if ((AuthMode >= Ndis802_11AuthModeOpen) &&
-		(AuthMode <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
-		sprintf(pBuf, "\t%s", RTMPGetRalinkAuthModeStr(AuthMode));
-	else
-		sprintf(pBuf, "\tUnknow Value(%d)", AuthMode);
-
-	return 0;
-}
-
-INT	Show_EncrypType_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	NDIS_802_11_WEP_STATUS	WepStatus = Ndis802_11WEPDisabled;
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		WepStatus = pAd->StaCfg.WepStatus;
-#endif // CONFIG_STA_SUPPORT //
-
-	if ((WepStatus >= Ndis802_11WEPEnabled) &&
-		(WepStatus <= Ndis802_11Encryption4KeyAbsent))
-		sprintf(pBuf, "\t%s", RTMPGetRalinkEncryModeStr(WepStatus));
-	else
-		sprintf(pBuf, "\tUnknow Value(%d)", WepStatus);
-
-	return 0;
-}
-
-INT	Show_DefaultKeyID_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	UCHAR DefaultKeyId = 0;
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		DefaultKeyId = pAd->StaCfg.DefaultKeyId;
-#endif // CONFIG_STA_SUPPORT //
-
-	sprintf(pBuf, "\t%d", DefaultKeyId);
-
-	return 0;
-}
-
-INT	Show_WepKey_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN  INT				KeyIdx,
-	OUT	PSTRING			pBuf)
-{
-	UCHAR   Key[16] = {0}, KeyLength = 0;
-	INT		index = BSS0;
-
-	KeyLength = pAd->SharedKey[index][KeyIdx].KeyLen;
-	NdisMoveMemory(Key, pAd->SharedKey[index][KeyIdx].Key, KeyLength);
-
-	//check key string is ASCII or not
-    if (RTMPCheckStrPrintAble((PCHAR)Key, KeyLength))
-        sprintf(pBuf, "\t%s", Key);
-    else
-    {
-        int idx;
-        sprintf(pBuf, "\t");
-        for (idx = 0; idx < KeyLength; idx++)
-            sprintf(pBuf+strlen(pBuf), "%02X", Key[idx]);
-    }
-	return 0;
-}
-
-INT	Show_Key1_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	Show_WepKey_Proc(pAd, 0, pBuf);
-	return 0;
-}
-
-INT	Show_Key2_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	Show_WepKey_Proc(pAd, 1, pBuf);
-	return 0;
-}
-
-INT	Show_Key3_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	Show_WepKey_Proc(pAd, 2, pBuf);
-	return 0;
-}
-
-INT	Show_Key4_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	Show_WepKey_Proc(pAd, 3, pBuf);
-	return 0;
-}
-
-INT	Show_WPAPSK_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT	PSTRING			pBuf)
-{
-	INT	idx;
-	UCHAR	PMK[32] = {0};
-
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		NdisMoveMemory(PMK, pAd->StaCfg.PMK, 32);
-#endif // CONFIG_STA_SUPPORT //
-
-    sprintf(pBuf, "\tPMK = ");
-    for (idx = 0; idx < 32; idx++)
-        sprintf(pBuf+strlen(pBuf), "%02X", PMK[idx]);
-
-	return 0;
-}
diff --git a/drivers/staging/rt3090/common/cmm_mac_pci.c b/drivers/staging/rt3090/common/cmm_mac_pci.c
deleted file mode 100644
index 8e16363..0000000
--- a/drivers/staging/rt3090/common/cmm_mac_pci.c
+++ /dev/null
@@ -1,1757 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-*/
-
-#ifdef RTMP_MAC_PCI
-
-#include "../rt_config.h"
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Allocate DMA memory blocks for send, receive
-
-	Arguments:
-		Adapter		Pointer to our adapter
-
-	Return Value:
-		NDIS_STATUS_SUCCESS
-		NDIS_STATUS_FAILURE
-		NDIS_STATUS_RESOURCES
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-NDIS_STATUS	RTMPAllocTxRxRingMemory(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	NDIS_STATUS		Status = NDIS_STATUS_SUCCESS;
-	ULONG			RingBasePaHigh;
-	ULONG			RingBasePaLow;
-	PVOID			RingBaseVa;
-	INT				index, num;
-	PTXD_STRUC		pTxD;
-	PRXD_STRUC		pRxD;
-	ULONG			ErrorValue = 0;
-	PRTMP_TX_RING	pTxRing;
-	PRTMP_DMABUF	pDmaBuf;
-	PNDIS_PACKET	pPacket;
-//	PRTMP_REORDERBUF	pReorderBuf;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
-	do
-	{
-		//
-		// Allocate all ring descriptors, include TxD, RxD, MgmtD.
-		// Although each size is different, to prevent cacheline and alignment
-		// issue, I intentional set them all to 64 bytes.
-		//
-		for (num=0; num<NUM_OF_TX_RING; num++)
-		{
-			ULONG  BufBasePaHigh;
-			ULONG  BufBasePaLow;
-			PVOID  BufBaseVa;
-
-			//
-			// Allocate Tx ring descriptor's memory (5 TX rings = 4 ACs + 1 HCCA)
-			//
-			pAd->TxDescRing[num].AllocSize = TX_RING_SIZE * TXD_SIZE;
-			RTMP_AllocateTxDescMemory(
-				pAd,
-				num,
-				pAd->TxDescRing[num].AllocSize,
-				FALSE,
-				&pAd->TxDescRing[num].AllocVa,
-				&pAd->TxDescRing[num].AllocPa);
-
-			if (pAd->TxDescRing[num].AllocVa == NULL)
-			{
-				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
-				DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
-				Status = NDIS_STATUS_RESOURCES;
-				break;
-			}
-
-			// Zero init this memory block
-			NdisZeroMemory(pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocSize);
-
-			// Save PA & VA for further operation
-			RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxDescRing[num].AllocPa);
-			RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->TxDescRing[num].AllocPa);
-			RingBaseVa     = pAd->TxDescRing[num].AllocVa;
-
-			//
-			// Allocate all 1st TXBuf's memory for this TxRing
-			//
-			pAd->TxBufSpace[num].AllocSize = TX_RING_SIZE * TX_DMA_1ST_BUFFER_SIZE;
-			RTMP_AllocateFirstTxBuffer(
-				pAd,
-				num,
-				pAd->TxBufSpace[num].AllocSize,
-				FALSE,
-				&pAd->TxBufSpace[num].AllocVa,
-				&pAd->TxBufSpace[num].AllocPa);
-
-			if (pAd->TxBufSpace[num].AllocVa == NULL)
-			{
-				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
-				DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
-				Status = NDIS_STATUS_RESOURCES;
-				break;
-			}
-
-			// Zero init this memory block
-			NdisZeroMemory(pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocSize);
-
-			// Save PA & VA for further operation
-			BufBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxBufSpace[num].AllocPa);
-			BufBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->TxBufSpace[num].AllocPa);
-			BufBaseVa     = pAd->TxBufSpace[num].AllocVa;
-
-			//
-			// Initialize Tx Ring Descriptor and associated buffer memory
-			//
-			pTxRing = &pAd->TxRing[num];
-			for (index = 0; index < TX_RING_SIZE; index++)
-			{
-				pTxRing->Cell[index].pNdisPacket = NULL;
-				pTxRing->Cell[index].pNextNdisPacket = NULL;
-				// Init Tx Ring Size, Va, Pa variables
-				pTxRing->Cell[index].AllocSize = TXD_SIZE;
-				pTxRing->Cell[index].AllocVa = RingBaseVa;
-				RTMP_SetPhysicalAddressHigh(pTxRing->Cell[index].AllocPa, RingBasePaHigh);
-				RTMP_SetPhysicalAddressLow (pTxRing->Cell[index].AllocPa, RingBasePaLow);
-
-				// Setup Tx Buffer size & address. only 802.11 header will store in this space
-				pDmaBuf = &pTxRing->Cell[index].DmaBuf;
-				pDmaBuf->AllocSize = TX_DMA_1ST_BUFFER_SIZE;
-				pDmaBuf->AllocVa = BufBaseVa;
-				RTMP_SetPhysicalAddressHigh(pDmaBuf->AllocPa, BufBasePaHigh);
-				RTMP_SetPhysicalAddressLow(pDmaBuf->AllocPa, BufBasePaLow);
-
-				// link the pre-allocated TxBuf to TXD
-				pTxD = (PTXD_STRUC) pTxRing->Cell[index].AllocVa;
-				pTxD->SDPtr0 = BufBasePaLow;
-				// advance to next ring descriptor address
-				pTxD->DMADONE = 1;
-#ifdef RT_BIG_ENDIAN
-				RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-#endif
-				RingBasePaLow += TXD_SIZE;
-				RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE;
-
-				// advance to next TxBuf address
-				BufBasePaLow += TX_DMA_1ST_BUFFER_SIZE;
-				BufBaseVa = (PUCHAR) BufBaseVa + TX_DMA_1ST_BUFFER_SIZE;
-			}
-			DBGPRINT(RT_DEBUG_TRACE, ("TxRing[%d]: total %d entry allocated\n", num, index));
-		}
-		if (Status == NDIS_STATUS_RESOURCES)
-			break;
-
-		//
-		// Allocate MGMT ring descriptor's memory except Tx ring which allocated eariler
-		//
-		pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * TXD_SIZE;
-		RTMP_AllocateMgmtDescMemory(
-			pAd,
-			pAd->MgmtDescRing.AllocSize,
-			FALSE,
-			&pAd->MgmtDescRing.AllocVa,
-			&pAd->MgmtDescRing.AllocPa);
-
-		if (pAd->MgmtDescRing.AllocVa == NULL)
-		{
-			ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
-			DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
-			Status = NDIS_STATUS_RESOURCES;
-			break;
-		}
-
-		// Zero init this memory block
-		NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
-
-		// Save PA & VA for further operation
-		RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->MgmtDescRing.AllocPa);
-		RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->MgmtDescRing.AllocPa);
-		RingBaseVa     = pAd->MgmtDescRing.AllocVa;
-
-		//
-		// Initialize MGMT Ring and associated buffer memory
-		//
-		for (index = 0; index < MGMT_RING_SIZE; index++)
-		{
-			pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
-			pAd->MgmtRing.Cell[index].pNextNdisPacket = NULL;
-			// Init MGMT Ring Size, Va, Pa variables
-			pAd->MgmtRing.Cell[index].AllocSize = TXD_SIZE;
-			pAd->MgmtRing.Cell[index].AllocVa = RingBaseVa;
-			RTMP_SetPhysicalAddressHigh(pAd->MgmtRing.Cell[index].AllocPa, RingBasePaHigh);
-			RTMP_SetPhysicalAddressLow (pAd->MgmtRing.Cell[index].AllocPa, RingBasePaLow);
-
-			// Offset to next ring descriptor address
-			RingBasePaLow += TXD_SIZE;
-			RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE;
-
-			// link the pre-allocated TxBuf to TXD
-			pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[index].AllocVa;
-			pTxD->DMADONE = 1;
-
-#ifdef RT_BIG_ENDIAN
-			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-#endif
-			// no pre-allocated buffer required in MgmtRing for scatter-gather case
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", index));
-
-		//
-		// Allocate RX ring descriptor's memory except Tx ring which allocated eariler
-		//
-		pAd->RxDescRing.AllocSize = RX_RING_SIZE * RXD_SIZE;
-		RTMP_AllocateRxDescMemory(
-			pAd,
-			pAd->RxDescRing.AllocSize,
-			FALSE,
-			&pAd->RxDescRing.AllocVa,
-			&pAd->RxDescRing.AllocPa);
-
-		if (pAd->RxDescRing.AllocVa == NULL)
-		{
-			ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
-			DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
-			Status = NDIS_STATUS_RESOURCES;
-			break;
-		}
-
-		// Zero init this memory block
-		NdisZeroMemory(pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize);
-
-
-		DBGPRINT(RT_DEBUG_OFF,
-					("RX DESC %p  size = %ld\n", pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize));
-
-		// Save PA & VA for further operation
-		RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->RxDescRing.AllocPa);
-		RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->RxDescRing.AllocPa);
-		RingBaseVa     = pAd->RxDescRing.AllocVa;
-
-		//
-		// Initialize Rx Ring and associated buffer memory
-		//
-		for (index = 0; index < RX_RING_SIZE; index++)
-		{
-			// Init RX Ring Size, Va, Pa variables
-			pAd->RxRing.Cell[index].AllocSize = RXD_SIZE;
-			pAd->RxRing.Cell[index].AllocVa = RingBaseVa;
-			RTMP_SetPhysicalAddressHigh(pAd->RxRing.Cell[index].AllocPa, RingBasePaHigh);
-			RTMP_SetPhysicalAddressLow (pAd->RxRing.Cell[index].AllocPa, RingBasePaLow);
-
-			//NdisZeroMemory(RingBaseVa, RXD_SIZE);
-
-			// Offset to next ring descriptor address
-			RingBasePaLow += RXD_SIZE;
-			RingBaseVa = (PUCHAR) RingBaseVa + RXD_SIZE;
-
-			// Setup Rx associated Buffer size & allocate share memory
-			pDmaBuf = &pAd->RxRing.Cell[index].DmaBuf;
-			pDmaBuf->AllocSize = RX_BUFFER_AGGRESIZE;
-			pPacket = RTMP_AllocateRxPacketBuffer(
-				pAd,
-				pDmaBuf->AllocSize,
-				FALSE,
-				&pDmaBuf->AllocVa,
-				&pDmaBuf->AllocPa);
-
-			/* keep allocated rx packet */
-			pAd->RxRing.Cell[index].pNdisPacket = pPacket;
-
-			// Error handling
-			if (pDmaBuf->AllocVa == NULL)
-			{
-				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
-				DBGPRINT_ERR(("Failed to allocate RxRing's 1st buffer\n"));
-				Status = NDIS_STATUS_RESOURCES;
-				break;
-			}
-
-			// Zero init this memory block
-			NdisZeroMemory(pDmaBuf->AllocVa, pDmaBuf->AllocSize);
-
-			// Write RxD buffer address & allocated buffer length
-			pRxD = (PRXD_STRUC) pAd->RxRing.Cell[index].AllocVa;
-			pRxD->SDP0 = RTMP_GetPhysicalAddressLow(pDmaBuf->AllocPa);
-			pRxD->DDONE = 0;
-
-#ifdef RT_BIG_ENDIAN
-			RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
-#endif
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("Rx Ring: total %d entry allocated\n", index));
-
-	}	while (FALSE);
-
-
-	NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));
-	pAd->FragFrame.pFragPacket =  RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
-
-	if (pAd->FragFrame.pFragPacket == NULL)
-	{
-		Status = NDIS_STATUS_RESOURCES;
-	}
-
-	if (Status != NDIS_STATUS_SUCCESS)
-	{
-		// Log error inforamtion
-		NdisWriteErrorLogEntry(
-			pAd->AdapterHandle,
-			NDIS_ERROR_CODE_OUT_OF_RESOURCES,
-			1,
-			ErrorValue);
-	}
-
-	// Following code segment get from original func:NICInitTxRxRingAndBacklogQueue(), now should integrate it to here.
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTxRxRingAndBacklogQueue\n"));
-
-/*
-		// Disable DMA.
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-		GloCfg.word &= 0xff0;
-		GloCfg.field.EnTXWriteBackDDONE =1;
-		RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
-*/
-
-		// Initialize all transmit related software queues
-		for(index = 0; index < NUM_OF_TX_RING; index++)
-		{
-			InitializeQueueHeader(&pAd->TxSwQueue[index]);
-			// Init TX rings index pointer
-			pAd->TxRing[index].TxSwFreeIdx = 0;
-			pAd->TxRing[index].TxCpuIdx = 0;
-			//RTMP_IO_WRITE32(pAd, (TX_CTX_IDX0 + i * 0x10) ,  pAd->TxRing[i].TX_CTX_IDX);
-		}
-
-		// Init RX Ring index pointer
-		pAd->RxRing.RxSwReadIdx = 0;
-		pAd->RxRing.RxCpuIdx = RX_RING_SIZE - 1;
-		//RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RX_CRX_IDX0);
-
-
-		// init MGMT ring index pointer
-		pAd->MgmtRing.TxSwFreeIdx = 0;
-		pAd->MgmtRing.TxCpuIdx = 0;
-
-		pAd->PrivateInfo.TxRingFullCnt = 0;
-
-		DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTxRxRingAndBacklogQueue\n"));
-	}
-
-	DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
-	return Status;
-}
-
-
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Reset NIC Asics. Call after rest DMA. So reset TX_CTX_IDX to zero.
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-		Reset NIC to initial state AS IS system boot up time.
-
-	========================================================================
-*/
-VOID	RTMPRingCleanUp(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			RingType)
-{
-	PTXD_STRUC		pTxD;
-	PRXD_STRUC		pRxD;
-	PQUEUE_ENTRY	pEntry;
-	PNDIS_PACKET	pPacket;
-	int				i;
-	PRTMP_TX_RING	pTxRing;
-	unsigned long	IrqFlags;
-	//UINT32			RxSwReadIdx;
-
-
-	DBGPRINT(RT_DEBUG_TRACE,("RTMPRingCleanUp(RingIdx=%d, Pending-NDIS=%ld)\n", RingType, pAd->RalinkCounters.PendingNdisPacketCount));
-	switch (RingType)
-	{
-		case QID_AC_BK:
-		case QID_AC_BE:
-		case QID_AC_VI:
-		case QID_AC_VO:
-		/*case QID_HCCA:*/
-
-			pTxRing = &pAd->TxRing[RingType];
-
-			RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-			// We have to clean all descriptors in case some error happened with reset
-			for (i=0; i<TX_RING_SIZE; i++) // We have to scan all TX ring
-			{
-				pTxD  = (PTXD_STRUC) pTxRing->Cell[i].AllocVa;
-
-				pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNdisPacket;
-				// release scatter-and-gather NDIS_PACKET
-				if (pPacket)
-				{
-					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-					pTxRing->Cell[i].pNdisPacket = NULL;
-				}
-
-				pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNextNdisPacket;
-				// release scatter-and-gather NDIS_PACKET
-				if (pPacket)
-				{
-					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-					pTxRing->Cell[i].pNextNdisPacket = NULL;
-				}
-			}
-
-			RTMP_IO_READ32(pAd, TX_DTX_IDX0 + RingType * 0x10, &pTxRing->TxDmaIdx);
-			pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx;
-			pTxRing->TxCpuIdx = pTxRing->TxDmaIdx;
-			RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + RingType * 0x10, pTxRing->TxCpuIdx);
-
-			RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-
-			RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-			while (pAd->TxSwQueue[RingType].Head != NULL)
-			{
-				pEntry = RemoveHeadQueue(&pAd->TxSwQueue[RingType]);
-				pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
-				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-				DBGPRINT(RT_DEBUG_TRACE,("Release 1 NDIS packet from s/w backlog queue\n"));
-			}
-			RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-			break;
-
-		case QID_MGMT:
-			// We have to clean all descriptors in case some error happened with reset
-			NdisAcquireSpinLock(&pAd->MgmtRingLock);
-
-			for (i=0; i<MGMT_RING_SIZE; i++)
-			{
-				pTxD  = (PTXD_STRUC) pAd->MgmtRing.Cell[i].AllocVa;
-
-				pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNdisPacket;
-				// rlease scatter-and-gather NDIS_PACKET
-				if (pPacket)
-				{
-					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
-					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-				}
-				pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
-
-				pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNextNdisPacket;
-				// release scatter-and-gather NDIS_PACKET
-				if (pPacket)
-				{
-					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
-					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-			}
-				pAd->MgmtRing.Cell[i].pNextNdisPacket = NULL;
-
-			}
-
-			RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pAd->MgmtRing.TxDmaIdx);
-			pAd->MgmtRing.TxSwFreeIdx = pAd->MgmtRing.TxDmaIdx;
-			pAd->MgmtRing.TxCpuIdx = pAd->MgmtRing.TxDmaIdx;
-			RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
-
-			NdisReleaseSpinLock(&pAd->MgmtRingLock);
-			pAd->RalinkCounters.MgmtRingFullCount = 0;
-			break;
-
-		case QID_RX:
-			// We have to clean all descriptors in case some error happened with reset
-			NdisAcquireSpinLock(&pAd->RxRingLock);
-
-			for (i=0; i<RX_RING_SIZE; i++)
-			{
-				pRxD  = (PRXD_STRUC) pAd->RxRing.Cell[i].AllocVa;
-                pRxD->DDONE = 0 ;
-			}
-
-			RTMP_IO_READ32(pAd, RX_DRX_IDX, &pAd->RxRing.RxDmaIdx);
-			pAd->RxRing.RxSwReadIdx = pAd->RxRing.RxDmaIdx;
-			pAd->RxRing.RxCpuIdx = ((pAd->RxRing.RxDmaIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxDmaIdx-1));
-			RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
-
-			NdisReleaseSpinLock(&pAd->RxRingLock);
-			break;
-
-		default:
-			break;
-	}
-}
-
-
-VOID RTMPFreeTxRxRingMemory(
-    IN  PRTMP_ADAPTER   pAd)
-{
-	int index, num , j;
-	PRTMP_TX_RING pTxRing;
-	PTXD_STRUC	  pTxD;
-	PNDIS_PACKET  pPacket;
-	unsigned int  IrqFlags;
-
-	//POS_COOKIE pObj =(POS_COOKIE) pAd->OS_Cookie;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPFreeTxRxRingMemory\n"));
-
-	// Free TxSwQueue Packet
-	for (index=0; index <NUM_OF_TX_RING; index++)
-	{
-		PQUEUE_ENTRY pEntry;
-		PNDIS_PACKET pPacket;
-		PQUEUE_HEADER   pQueue;
-
-		RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-		pQueue = &pAd->TxSwQueue[index];
-		while (pQueue->Head)
-		{
-			pEntry = RemoveHeadQueue(pQueue);
-			pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
-			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-		}
-		RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-	}
-
-	// Free Tx Ring Packet
-	for (index=0;index< NUM_OF_TX_RING;index++)
-	{
-		pTxRing = &pAd->TxRing[index];
-
-		for (j=0; j< TX_RING_SIZE; j++)
-		{
-			pTxD = (PTXD_STRUC) (pTxRing->Cell[j].AllocVa);
-			pPacket = pTxRing->Cell[j].pNdisPacket;
-
-			if (pPacket)
-			{
-				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-			}
-			//Always assign pNdisPacket as NULL after clear
-			pTxRing->Cell[j].pNdisPacket = NULL;
-
-			pPacket = pTxRing->Cell[j].pNextNdisPacket;
-
-			if (pPacket)
-			{
-				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-			}
-			//Always assign pNextNdisPacket as NULL after clear
-			pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL;
-
-		}
-	}
-
-	for (index = RX_RING_SIZE - 1 ; index >= 0; index--)
-	{
-		if ((pAd->RxRing.Cell[index].DmaBuf.AllocVa) && (pAd->RxRing.Cell[index].pNdisPacket))
-		{
-			PCI_UNMAP_SINGLE(pAd, pAd->RxRing.Cell[index].DmaBuf.AllocPa, pAd->RxRing.Cell[index].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
-			RELEASE_NDIS_PACKET(pAd, pAd->RxRing.Cell[index].pNdisPacket, NDIS_STATUS_SUCCESS);
-		}
-	}
-	NdisZeroMemory(pAd->RxRing.Cell, RX_RING_SIZE * sizeof(RTMP_DMACB));
-
-	if (pAd->RxDescRing.AllocVa)
-    {
-		RTMP_FreeDescMemory(pAd, pAd->RxDescRing.AllocSize, pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocPa);
-    }
-    NdisZeroMemory(&pAd->RxDescRing, sizeof(RTMP_DMABUF));
-
-	if (pAd->MgmtDescRing.AllocVa)
-	{
-		RTMP_FreeDescMemory(pAd, pAd->MgmtDescRing.AllocSize, pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocPa);
-	}
-	NdisZeroMemory(&pAd->MgmtDescRing, sizeof(RTMP_DMABUF));
-
-	for (num = 0; num < NUM_OF_TX_RING; num++)
-	{
-	if (pAd->TxBufSpace[num].AllocVa)
-		{
-			RTMP_FreeFirstTxBuffer(pAd, pAd->TxBufSpace[num].AllocSize, FALSE, pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocPa);
-	    }
-	    NdisZeroMemory(&pAd->TxBufSpace[num], sizeof(RTMP_DMABUF));
-
-	if (pAd->TxDescRing[num].AllocVa)
-		{
-			RTMP_FreeDescMemory(pAd, pAd->TxDescRing[num].AllocSize, pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocPa);
-	    }
-	    NdisZeroMemory(&pAd->TxDescRing[num], sizeof(RTMP_DMABUF));
-	}
-
-	if (pAd->FragFrame.pFragPacket)
-		RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- RTMPFreeTxRxRingMemory\n"));
-}
-
-
-/***************************************************************************
-  *
-  *	register related procedures.
-  *
-  **************************************************************************/
-/*
-========================================================================
-Routine Description:
-    Disable DMA.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-VOID RT28XXDMADisable(
-	IN RTMP_ADAPTER			*pAd)
-{
-	WPDMA_GLO_CFG_STRUC     GloCfg;
-
-
-	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-	GloCfg.word &= 0xff0;
-	GloCfg.field.EnTXWriteBackDDONE =1;
-	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Enable DMA.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-VOID RT28XXDMAEnable(
-	IN RTMP_ADAPTER			*pAd)
-{
-	WPDMA_GLO_CFG_STRUC	GloCfg;
-	int i = 0;
-
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
-	do
-	{
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-		if ((GloCfg.field.TxDMABusy == 0)  && (GloCfg.field.RxDMABusy == 0))
-			break;
-
-		DBGPRINT(RT_DEBUG_TRACE, ("==>  DMABusy\n"));
-		RTMPusecDelay(1000);
-		i++;
-	}while ( i <200);
-
-	RTMPusecDelay(50);
-
-	GloCfg.field.EnTXWriteBackDDONE = 1;
-	GloCfg.field.WPDMABurstSIZE = 2;
-	GloCfg.field.EnableRxDMA = 1;
-	GloCfg.field.EnableTxDMA = 1;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
-	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
-
-}
-
-
-BOOLEAN AsicCheckCommanOk(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR		 Command)
-{
-	UINT32	CmdStatus = 0, CID = 0, i;
-	UINT32	ThisCIDMask = 0;
-
-	i = 0;
-	do
-	{
-		RTMP_IO_READ32(pAd, H2M_MAILBOX_CID, &CID);
-		// Find where the command is. Because this is randomly specified by firmware.
-		if ((CID & CID0MASK) == Command)
-		{
-			ThisCIDMask = CID0MASK;
-			break;
-		}
-		else if ((((CID & CID1MASK)>>8) & 0xff) == Command)
-		{
-			ThisCIDMask = CID1MASK;
-			break;
-		}
-		else if ((((CID & CID2MASK)>>16) & 0xff) == Command)
-		{
-			ThisCIDMask = CID2MASK;
-			break;
-		}
-		else if ((((CID & CID3MASK)>>24) & 0xff) == Command)
-		{
-			ThisCIDMask = CID3MASK;
-			break;
-		}
-
-		RTMPusecDelay(100);
-		i++;
-	}while (i < 200);
-
-	// Get CommandStatus Value
-	RTMP_IO_READ32(pAd, H2M_MAILBOX_STATUS, &CmdStatus);
-
-	// This command's status is at the same position as command. So AND command position's bitmask to read status.
-	if (i < 200)
-	{
-		// If Status is 1, the comamnd is success.
-		if (((CmdStatus & ThisCIDMask) == 0x1) || ((CmdStatus & ThisCIDMask) == 0x100)
-			|| ((CmdStatus & ThisCIDMask) == 0x10000) || ((CmdStatus & ThisCIDMask) == 0x1000000))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanOk CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus));
-			RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
-			RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
-			return TRUE;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail1 CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus));
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail2 Timeout Command = %d, CmdStatus= 0x%x \n", Command, CmdStatus));
-	}
-	// Clear Command and Status.
-	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
-	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
-
-	return FALSE;
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Write Beacon buffer to Asic.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-VOID RT28xx_UpdateBeaconToAsic(
-	IN RTMP_ADAPTER		*pAd,
-	IN INT				apidx,
-	IN ULONG			FrameLen,
-	IN ULONG			UpdatePos)
-{
-	ULONG				CapInfoPos = 0;
-	UCHAR			*ptr, *ptr_update, *ptr_capinfo;
-	UINT			i;
-	BOOLEAN			bBcnReq = FALSE;
-	UCHAR			bcn_idx = 0;
-
-
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s() : No valid Interface be found.\n", __FUNCTION__));
-		return;
-	}
-
-	//if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE)
-	//	|| ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL)
-	//		|| !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP))
-	//	)
-	if (bBcnReq == FALSE)
-	{
-		/* when the ra interface is down, do not send its beacon frame */
-		/* clear all zero */
-		for(i=0; i<TXWI_SIZE; i+=4)
-			RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, 0x00);
-	}
-	else
-	{
-		ptr = (PUCHAR)&pAd->BeaconTxWI;
-#ifdef RT_BIG_ENDIAN
-		RTMPWIEndianChange(ptr, TYPE_TXWI);
-#endif
-		for (i=0; i<TXWI_SIZE; i+=4)  // 16-byte TXWI field
-		{
-			UINT32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
-			RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longptr);
-			ptr += 4;
-		}
-
-		// Update CapabilityInfo in Beacon
-		for (i = CapInfoPos; i < (CapInfoPos+2); i++)
-		{
-			RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, *ptr_capinfo);
-			ptr_capinfo ++;
-		}
-
-		if (FrameLen > UpdatePos)
-		{
-			for (i= UpdatePos; i< (FrameLen); i++)
-			{
-				RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, *ptr_update);
-				ptr_update ++;
-			}
-		}
-
-	}
-
-}
-
-
-#ifdef CONFIG_STA_SUPPORT
-VOID RT28xxPciStaAsicForceWakeup(
-	IN PRTMP_ADAPTER pAd,
-	IN BOOLEAN       bFromTx)
-{
-    AUTO_WAKEUP_STRUC	AutoWakeupCfg;
-
-    if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-        return;
-
-    if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW))
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n"));
-        return;
-    }
-
-    OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
-
-    RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
-
-    if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
-		&&pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
-    {
-        // Support PCIe Advance Power Save
-	if (bFromTx == TRUE
-			&&(pAd->Mlme.bPsPollTimerRunning == TRUE))
-	{
-            pAd->Mlme.bPsPollTimerRunning = FALSE;
-		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
-		RTMPusecDelay(3000);
-            DBGPRINT(RT_DEBUG_TRACE, ("=======AsicForceWakeup===bFromTx\n"));
-	}
-
-		AutoWakeupCfg.word = 0;
-		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-
-        if (RT28xxPciAsicRadioOn(pAd, DOT11POWERSAVE))
-        {
-#ifdef PCIE_PS_SUPPORT
-			// add by johnli, RF power sequence setup, load RF normal operation-mode setup
-			if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd))
-			{
-				RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
-
-				if (pChipOps->AsicReverseRfFromSleepMode)
-					pChipOps->AsicReverseRfFromSleepMode(pAd);
-			}
-			else
-#endif // PCIE_PS_SUPPORT //
-			{
-			// end johnli
-				// In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
-				if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
-					&& (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
-				{
-					// Must using 40MHz.
-					AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
-					AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
-				}
-				else
-				{
-					// Must using 20MHz.
-					AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-					AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-				}
-			}
-        }
-#ifdef PCIE_PS_SUPPORT
-		// 3090 MCU Wakeup command needs more time to be stable.
-		// Before stable, don't issue other MCU command to prevent from firmware error.
-		if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
-			&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
-			&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))
-			{
-			DBGPRINT(RT_DEBUG_TRACE, ("<==RT28xxPciStaAsicForceWakeup::Release the MCU Lock(3090)\n"));
-			RTMP_SEM_LOCK(&pAd->McuCmdLock);
-			pAd->brt30xxBanMcuCmd = FALSE;
-			RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
-			}
-#endif // PCIE_PS_SUPPORT //
-    }
-    else
-    {
-        // PCI, 2860-PCIe
-         DBGPRINT(RT_DEBUG_TRACE, ("<==RT28xxPciStaAsicForceWakeup::Original PCI Power Saving\n"));
-        AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
-        AutoWakeupCfg.word = 0;
-	    RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-    }
-
-    OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-    OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
-    DBGPRINT(RT_DEBUG_TRACE, ("<=======RT28xxPciStaAsicForceWakeup\n"));
-}
-
-
-VOID RT28xxPciStaAsicSleepThenAutoWakeup(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT TbttNumToNextWakeUp)
-{
-	BOOLEAN brc;
-
-	if (pAd->StaCfg.bRadio == FALSE)
-	{
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-		return;
-	}
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
-		&&pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
-	{
-		ULONG	Now = 0;
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n"));
-			OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-			return;
-		}
-
-		NdisGetSystemUpTime(&Now);
-		// If last send NULL fram time is too close to this receiving beacon (within 8ms), don't go to sleep for this DTM.
-		// Because Some AP can't queuing outgoing frames immediately.
-		if (((pAd->Mlme.LastSendNULLpsmTime + 8) >= Now) && (pAd->Mlme.LastSendNULLpsmTime <= Now))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("Now = %lu, LastSendNULLpsmTime=%lu :  RxCountSinceLastNULL = %lu. \n", Now, pAd->Mlme.LastSendNULLpsmTime, pAd->RalinkCounters.RxCountSinceLastNULL));
-			return;
-		}
-		else if ((pAd->RalinkCounters.RxCountSinceLastNULL > 0) && ((pAd->Mlme.LastSendNULLpsmTime + pAd->CommonCfg.BeaconPeriod) >= Now))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("Now = %lu, LastSendNULLpsmTime=%lu: RxCountSinceLastNULL = %lu > 0 \n", Now, pAd->Mlme.LastSendNULLpsmTime,  pAd->RalinkCounters.RxCountSinceLastNULL));
-			return;
-		}
-
-		brc = RT28xxPciAsicRadioOff(pAd, DOT11POWERSAVE, TbttNumToNextWakeUp);
-		if (brc==TRUE)
-			OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
-	}
-	else
-	{
-		AUTO_WAKEUP_STRUC	AutoWakeupCfg;
-		// we have decided to SLEEP, so at least do it for a BEACON period.
-		if (TbttNumToNextWakeUp == 0)
-			TbttNumToNextWakeUp = 1;
-
-		//RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt);
-
-		AutoWakeupCfg.word = 0;
-		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-		AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
-		AutoWakeupCfg.field.EnableAutoWakeup = 1;
-		AutoWakeupCfg.field.AutoLeadTime = 5;
-		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-		AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x00);   // send POWER-SAVE command to MCU. Timeout 40us.
-		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
-		DBGPRINT(RT_DEBUG_TRACE, ("<-- %s, TbttNumToNextWakeUp=%d \n", __FUNCTION__, TbttNumToNextWakeUp));
-	}
-
-}
-
-
-VOID PsPollWakeExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3)
-{
-	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
-	unsigned long flags;
-
-    DBGPRINT(RT_DEBUG_TRACE,("-->PsPollWakeExec \n"));
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-    if (pAd->Mlme.bPsPollTimerRunning)
-    {
-	    RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
-    }
-    pAd->Mlme.bPsPollTimerRunning = FALSE;
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-#ifdef PCIE_PS_SUPPORT
-	// For rt30xx power solution 3, Use software timer to wake up in psm. So call
-	// AsicForceWakeup here instead of handling twakeup interrupt.
-	if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd))
-	&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
-	&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("<--PsPollWakeExec::3090 calls AsicForceWakeup(pAd, DOT11POWERSAVE) in advance \n"));
-		AsicForceWakeup(pAd, DOT11POWERSAVE);
-	}
-
-#endif // PCIE_PS_SUPPORT //
-}
-
-VOID  RadioOnExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3)
-{
-	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
-	RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
-	WPDMA_GLO_CFG_STRUC	DmaCfg;
-	BOOLEAN				Cancelled;
-
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("-->RadioOnExec() return on fOP_STATUS_DOZE == TRUE; \n"));
-//KH Debug: Add the compile flag "RT2860 and condition
-#ifdef RTMP_PCI_SUPPORT
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
-			&&pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
-		RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
-#endif // RTMP_PCI_SUPPORT //
-		return;
-	}
-
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("-->RadioOnExec() return on SCAN_IN_PROGRESS; \n"));
-
-
-#ifdef RTMP_PCI_SUPPORT
-if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
-	&&pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
-		RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
-#endif // RTMP_PCI_SUPPORT //
-		return;
-	}
-//KH Debug: need to check. I add the compile flag "CONFIG_STA_SUPPORT" to enclose the following codes.
-#ifdef RTMP_PCI_SUPPORT
-if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
-	&&pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
-	{
-	pAd->Mlme.bPsPollTimerRunning = FALSE;
-	RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
-	}
-#endif // RTMP_PCI_SUPPORT //
-	if (pAd->StaCfg.bRadio == TRUE)
-	{
-		pAd->bPCIclkOff = FALSE;
-		RTMPRingCleanUp(pAd, QID_AC_BK);
-		RTMPRingCleanUp(pAd, QID_AC_BE);
-		RTMPRingCleanUp(pAd, QID_AC_VI);
-		RTMPRingCleanUp(pAd, QID_AC_VO);
-		/*RTMPRingCleanUp(pAd, QID_HCCA);*/
-		RTMPRingCleanUp(pAd, QID_MGMT);
-		RTMPRingCleanUp(pAd, QID_RX);
-
-		// 2. Send wake up command.
-		AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02);
-		// 2-1. wait command ok.
-		AsicCheckCommanOk(pAd, PowerWakeCID);
-
-		// When PCI clock is off, don't want to service interrupt. So when back to clock on, enable interrupt.
-		//RTMP_IO_WRITE32(pAd, INT_MASK_CSR, (DELAYINTMASK|RxINT));
-		RTMP_ASIC_INTERRUPT_ENABLE(pAd);
-
-		// 3. Enable Tx DMA.
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
-		DmaCfg.field.EnableTxDMA = 1;
-		RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
-
-		// In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
-		if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
-			&& (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
-		{
-			// Must using 40MHz.
-			AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
-			AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
-		}
-		else
-		{
-			// Must using 20MHz.
-			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-		}
-//KH Debug:The following codes should be enclosed by RT3090 compile flag
-		if (pChipOps->AsicReverseRfFromSleepMode)
-			pChipOps->AsicReverseRfFromSleepMode(pAd);
-#ifdef PCIE_PS_SUPPORT
-#ifdef CONFIG_STA_SUPPORT
-// 3090 MCU Wakeup command needs more time to be stable.
-// Before stable, don't issue other MCU command to prevent from firmware error.
-if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)
-	&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
-	&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))
-	{
-	RTMP_SEM_LOCK(&pAd->McuCmdLock);
-	pAd->brt30xxBanMcuCmd = FALSE;
-	RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
-	}
-#endif // CONFIG_STA_SUPPORT //
-#endif // PCIE_PS_SUPPORT //
-		// Clear Radio off flag
-		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-		// Set LED
-		RTMPSetLED(pAd, LED_RADIO_ON);
-
-        if (pAd->StaCfg.Psm == PWR_ACTIVE)
-        {
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
-        }
-	}
-	else
-	{
-		RT28xxPciAsicRadioOff(pAd, GUIRADIO_OFF, 0);
-	}
-}
-#endif // CONFIG_STA_SUPPORT //
-
-
-/*
-	==========================================================================
-	Description:
-		This routine sends command to firmware and turn our chip to wake up mode from power save mode.
-		Both RadioOn and .11 power save function needs to call this routine.
-	Input:
-		Level = GUIRADIO_OFF : call this function is from Radio Off to Radio On.  Need to restore PCI host value.
-		Level = other value : normal wake up function.
-
-	==========================================================================
- */
-BOOLEAN RT28xxPciAsicRadioOn(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR     Level)
-{
-    //WPDMA_GLO_CFG_STRUC	DmaCfg;
-#ifdef CONFIG_STA_SUPPORT
-	BOOLEAN				Cancelled;
-#endif // CONFIG_STA_SUPPORT //
-    //UINT32			    MACValue;
-
-	if (pAd->OpMode == OPMODE_AP && Level==DOT11POWERSAVE)
-		return FALSE;
-
-#ifdef CONFIG_STA_SUPPORT
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
-	{
-		if (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
-		{
-	    pAd->Mlme.bPsPollTimerRunning = FALSE;
-		RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
-		}
-		if ((pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)&&
-		((Level == GUIRADIO_OFF) || (Level == GUI_IDLE_POWER_SAVE))
-		||(RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND)))
-		{
-			// Some chips don't need to delay 6ms, so copy RTMPPCIePowerLinkCtrlRestore
-			// return condition here.
-			/*
-			if (((pAd->MACVersion&0xffff0000) != 0x28600000)
-				&& ((pAd->DeviceID == NIC2860_PCIe_DEVICE_ID)
-				||(pAd->DeviceID == NIC2790_PCIe_DEVICE_ID)))
-			*/
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("RT28xxPciAsicRadioOn ()\n"));
-			// 1. Set PCI Link Control in Configuration Space.
-			RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
-			RTMPusecDelay(6000);
-		}
-	}
-	}
-
-#ifdef PCIE_PS_SUPPORT
-if (!(((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)
-	&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
-	&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))))
-#endif // PCIE_PS_SUPPORT //
-	{
-    pAd->bPCIclkOff = FALSE;
-		DBGPRINT(RT_DEBUG_TRACE, ("PSM :309xbPCIclkOff == %d\n", pAd->bPCIclkOff));
-
-	}
-#endif // CONFIG_STA_SUPPORT //
-	// 2. Send wake up command.
-	AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02);
-	pAd->bPCIclkOff = FALSE;
-	// 2-1. wait command ok.
-	AsicCheckCommanOk(pAd, PowerWakeCID);
-	RTMP_ASIC_INTERRUPT_ENABLE(pAd);
-
-
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
-	if (Level == GUI_IDLE_POWER_SAVE)
-	{
-#ifdef  PCIE_PS_SUPPORT
-
-			// add by johnli, RF power sequence setup, load RF normal operation-mode setup
-			if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)))
-			{
-				RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
-
-				if (pChipOps->AsicReverseRfFromSleepMode)
-					pChipOps->AsicReverseRfFromSleepMode(pAd);
-#ifdef CONFIG_STA_SUPPORT
-				// 3090 MCU Wakeup command needs more time to be stable.
-				// Before stable, don't issue other MCU command to prevent from firmware error.
-				if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)
-					&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
-					&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))
-					{
-						RTMP_SEM_LOCK(&pAd->McuCmdLock);
-						pAd->brt30xxBanMcuCmd = FALSE;
-						RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
-					}
-#endif // CONFIG_STA_SUPPORT //
-			}
-			else
-			// end johnli
-#endif // PCIE_PS_SUPPORT //
-			{
-			// In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
-#ifdef CONFIG_STA_SUPPORT
-			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-				{
-				if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
-					&& (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
-				{
-					// Must using 40MHz.
-					AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
-					AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
-				}
-				else
-				{
-					// Must using 20MHz.
-					AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-					AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-				}
-				}
-#endif // CONFIG_STA_SUPPORT //
-			}
-	}
-        return TRUE;
-
-}
-
-
-/*
-	==========================================================================
-	Description:
-		This routine sends command to firmware and turn our chip to power save mode.
-		Both RadioOff and .11 power save function needs to call this routine.
-	Input:
-		Level = GUIRADIO_OFF  : GUI Radio Off mode
-		Level = DOT11POWERSAVE  : 802.11 power save mode
-		Level = RTMP_HALT  : When Disable device.
-
-	==========================================================================
- */
-BOOLEAN RT28xxPciAsicRadioOff(
-	IN PRTMP_ADAPTER    pAd,
-	IN UCHAR            Level,
-	IN USHORT           TbttNumToNextWakeUp)
-{
-#ifdef CONFIG_STA_SUPPORT
-	WPDMA_GLO_CFG_STRUC	DmaCfg;
-	UCHAR		i, tempBBP_R3 = 0;
-#endif // CONFIG_STA_SUPPORT //
-	BOOLEAN		brc = FALSE, Cancelled;
-    UINT32		TbTTTime = 0;
-	UINT32		PsPollTime = 0/*, MACValue*/;
-    ULONG		BeaconPeriodTime;
-    UINT32		RxDmaIdx, RxCpuIdx;
-	DBGPRINT(RT_DEBUG_TRACE, ("AsicRadioOff ===> Lv= %d, TxCpuIdx = %d, TxDmaIdx = %d. RxCpuIdx = %d, RxDmaIdx = %d.\n", Level,pAd->TxRing[0].TxCpuIdx, pAd->TxRing[0].TxDmaIdx, pAd->RxRing.RxCpuIdx, pAd->RxRing.RxDmaIdx));
-
-	if (pAd->OpMode == OPMODE_AP && Level==DOT11POWERSAVE)
-		return FALSE;
-
-    // Check Rx DMA busy status, if more than half is occupied, give up this radio off.
-	RTMP_IO_READ32(pAd, RX_DRX_IDX , &RxDmaIdx);
-	RTMP_IO_READ32(pAd, RX_CRX_IDX , &RxCpuIdx);
-	if ((RxDmaIdx > RxCpuIdx) && ((RxDmaIdx - RxCpuIdx) > RX_RING_SIZE/3))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("AsicRadioOff ===> return1. RxDmaIdx = %d ,  RxCpuIdx = %d. \n", RxDmaIdx, RxCpuIdx));
-		return FALSE;
-	}
-	else if ((RxCpuIdx >= RxDmaIdx) && ((RxCpuIdx - RxDmaIdx) < RX_RING_SIZE/3))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("AsicRadioOff ===> return2.  RxCpuIdx = %d. RxDmaIdx = %d ,  \n", RxCpuIdx, RxDmaIdx));
-		return FALSE;
-	}
-
-    // Once go into this function, disable tx because don't want too many packets in queue to prevent HW stops.
-	//pAd->bPCIclkOffDisableTx = TRUE;
-	RTMP_SET_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
-		&& pAd->OpMode == OPMODE_STA
-#ifdef CONFIG_STA_SUPPORT
-		&&pAd->StaCfg.PSControl.field.EnableNewPS == TRUE
-#endif // CONFIG_STA_SUPPORT //
-		)
-	{
-
-	    RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer,	&Cancelled);
-	    RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
-
-	    if (Level == DOT11POWERSAVE)
-		{
-			RTMP_IO_READ32(pAd, TBTT_TIMER, &TbTTTime);
-			TbTTTime &= 0x1ffff;
-			// 00. check if need to do sleep in this DTIM period.   If next beacon will arrive within 30ms , ...doesn't necessarily sleep.
-			// TbTTTime uint = 64us, LEAD_TIME unit = 1024us, PsPollTime unit = 1ms
-	        if  (((64*TbTTTime) <((LEAD_TIME*1024) + 40000)) && (TbttNumToNextWakeUp == 0))
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("TbTTTime = 0x%x , give up this sleep. \n", TbTTTime));
-	            OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-	            //pAd->bPCIclkOffDisableTx = FALSE;
-	            RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
-				return FALSE;
-			}
-			else
-			{
-				PsPollTime = (64*TbTTTime- LEAD_TIME*1024)/1000;
-#ifdef PCIE_PS_SUPPORT
-#ifdef CONFIG_STA_SUPPORT
-				if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)
-				&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
-				&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))
-				{
-							PsPollTime -= 5;
-				}
-				else
-#endif // CONFIG_STA_SUPPORT //
-#endif // PCIE_PS_SUPPORT //
-				PsPollTime -= 3;
-
-	            BeaconPeriodTime = pAd->CommonCfg.BeaconPeriod*102/100;
-				if (TbttNumToNextWakeUp > 0)
-					PsPollTime += ((TbttNumToNextWakeUp -1) * BeaconPeriodTime);
-
-	            pAd->Mlme.bPsPollTimerRunning = TRUE;
-				RTMPSetTimer(&pAd->Mlme.PsPollTimer, PsPollTime);
-			}
-		}
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("RT28xxPciAsicRadioOff::Level!=DOT11POWERSAVE \n"));
-	}
-
-	pAd->bPCIclkOffDisableTx = FALSE;
-    RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
-
-#ifdef CONFIG_STA_SUPPORT
-    // Set to 1R.
-	if (pAd->Antenna.field.RxPath > 1 && pAd->OpMode == OPMODE_STA)
-	{
-    tempBBP_R3 = (pAd->StaCfg.BBPR3 & 0xE7);
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, tempBBP_R3);
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	// In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
-	if ((INFRA_ON(pAd) || pAd->OpMode == OPMODE_AP) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
-		&& (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
-	{
-		// Must using 40MHz.
-		AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
-	}
-	else
-	{
-		// Must using 20MHz.
-		AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
-	}
-
-	if (Level != RTMP_HALT)
-	{
-		// Change Interrupt bitmask.
-    // When PCI clock is off, don't want to service interrupt.
-	RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt);
-	}
-	else
-	{
-		RTMP_ASIC_INTERRUPT_DISABLE(pAd);
-	}
-
-
-	RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
-	//  2. Send Sleep command
-	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
-	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
-	// send POWER-SAVE command to MCU. high-byte = 1 save power as much as possible. high byte = 0 save less power
-	AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x1);
-	//  2-1. Wait command success
-	// Status = 1 : success, Status = 2, already sleep, Status = 3, Maybe MAC is busy so can't finish this task.
-	brc = AsicCheckCommanOk(pAd, PowerSafeCID);
-
-	//  3. After 0x30 command is ok, send radio off command. lowbyte = 0 for power safe.
-	// If 0x30 command is not ok this time, we can ignore 0x35 command. It will make sure not cause firmware'r problem.
-	if ((Level == DOT11POWERSAVE) && (brc == TRUE))
-	{
-		AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 0, 0x00);	// lowbyte = 0 means to do power safe, NOT turn off radio.
-		//  3-1. Wait command success
-		AsicCheckCommanOk(pAd, PowerRadioOffCID);
-	}
-	else if (brc == TRUE)
-	{
-		AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 1, 0x00);	// lowbyte = 0 means to do power safe, NOT turn off radio.
-		//  3-1. Wait command success
-		AsicCheckCommanOk(pAd, PowerRadioOffCID);
-	}
-
-#ifdef CONFIG_STA_SUPPORT
-	// 1. Wait DMA not busy
-	i = 0;
-	do
-	{
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
-		if ((DmaCfg.field.RxDMABusy == 0) && (DmaCfg.field.TxDMABusy == 0))
-			break;
-		RTMPusecDelay(20);
-		i++;
-	}while(i < 50);
-
-	/*
-	if (i >= 50)
-	{
-		pAd->CheckDmaBusyCount++;
-		DBGPRINT(RT_DEBUG_TRACE, ("DMA Rx keeps busy.  return on AsicRadioOff () CheckDmaBusyCount = %d \n", pAd->CheckDmaBusyCount));
-	}
-	else
-	{
-		pAd->CheckDmaBusyCount = 0;
-	}
-	*/
-#endif // CONFIG_STA_SUPPORT //
-//KH Debug:My original codes have the follwoing codes, but currecnt codes do not have it.
-// Disable for stability. If PCIE Link Control is modified for advance power save, re-covery this code segment.
-RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x1280);
-//OPSTATUS_SET_FLAG(pAd, fOP_STATUS_CLKSELECT_40MHZ);
-
-#ifdef PCIE_PS_SUPPORT
-#ifdef CONFIG_STA_SUPPORT
-if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)
-	&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
-	&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))
-	{
-	DBGPRINT(RT_DEBUG_TRACE, ("RT28xxPciAsicRadioOff::3090 return to skip the following TbttNumToNextWakeUp setting for 279x\n"));
-	pAd->bPCIclkOff = TRUE;
-	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
-	// For this case, doesn't need to below actions, so return here.
-	return brc;
-	}
-#endif // CONFIG_STA_SUPPORT //
-#endif // PCIE_PS_SUPPORT //
-	if (Level == DOT11POWERSAVE)
-	{
-		AUTO_WAKEUP_STRUC	AutoWakeupCfg;
-		//RTMPSetTimer(&pAd->Mlme.PsPollTimer, 90);
-
-		// we have decided to SLEEP, so at least do it for a BEACON period.
-		if (TbttNumToNextWakeUp == 0)
-			TbttNumToNextWakeUp = 1;
-
-		AutoWakeupCfg.word = 0;
-		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-
-		// 1. Set auto wake up timer.
-		AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
-		AutoWakeupCfg.field.EnableAutoWakeup = 1;
-		AutoWakeupCfg.field.AutoLeadTime = LEAD_TIME;
-		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-	}
-
-#ifdef CONFIG_STA_SUPPORT
-	//  4-1. If it's to disable our device. Need to restore PCI Configuration Space to its original value.
-	if (Level == RTMP_HALT && pAd->OpMode == OPMODE_STA)
-	{
-		if ((brc == TRUE) && (i < 50))
-			RTMPPCIeLinkCtrlSetting(pAd, 1);
-	}
-	//  4. Set PCI configuration Space Link Comtrol fields.  Only Radio Off needs to call this function
-	else if (pAd->OpMode == OPMODE_STA)
-	{
-		if ((brc == TRUE) && (i < 50))
-			RTMPPCIeLinkCtrlSetting(pAd, 3);
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	//pAd->bPCIclkOffDisableTx = FALSE;
-	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
-	return TRUE;
-}
-
-
-
-
-VOID RT28xxPciMlmeRadioOn(
-	IN PRTMP_ADAPTER pAd)
-{
-    if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
-		return;
-
-    DBGPRINT(RT_DEBUG_TRACE,("%s===>\n", __FUNCTION__));
-
-    if ((pAd->OpMode == OPMODE_AP) ||
-        ((pAd->OpMode == OPMODE_STA)
-        && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
-#ifdef CONFIG_STA_SUPPORT
-        ||pAd->StaCfg.PSControl.field.EnableNewPS == FALSE
-#endif // CONFIG_STA_SUPPORT //
-        )))
-    {
-	RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
-	//NICResetFromError(pAd);
-
-	RTMPRingCleanUp(pAd, QID_AC_BK);
-	RTMPRingCleanUp(pAd, QID_AC_BE);
-	RTMPRingCleanUp(pAd, QID_AC_VI);
-	RTMPRingCleanUp(pAd, QID_AC_VO);
-	/*RTMPRingCleanUp(pAd, QID_HCCA);*/
-	RTMPRingCleanUp(pAd, QID_MGMT);
-	RTMPRingCleanUp(pAd, QID_RX);
-
-	// Enable Tx/Rx
-	RTMPEnableRxTx(pAd);
-
-	// Clear Radio off flag
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
-	    // Set LED
-	    RTMPSetLED(pAd, LED_RADIO_ON);
-    }
-
-#ifdef CONFIG_STA_SUPPORT
-    if ((pAd->OpMode == OPMODE_STA) &&
-        (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
-        &&(pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))
-    {
-        BOOLEAN		Cancelled;
-
-	RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
-
-        pAd->Mlme.bPsPollTimerRunning = FALSE;
-	RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
-	RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer,	&Cancelled);
-	RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 40);
-    }
-#endif // CONFIG_STA_SUPPORT //
-}
-
-
-VOID RT28xxPciMlmeRadioOFF(
-	IN PRTMP_ADAPTER pAd)
-{
-	BOOLEAN brc=TRUE;
-
-    if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
-	return;
-
-#ifdef CONFIG_STA_SUPPORT
-	// Link down first if any association exists
-	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
-	{
-		if (INFRA_ON(pAd) || ADHOC_ON(pAd))
-		{
-			MLME_DISASSOC_REQ_STRUCT DisReq;
-			MLME_QUEUE_ELEM *pMsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
-
-			if (pMsgElem)
-			{
-				COPY_MAC_ADDR(&DisReq.Addr, pAd->CommonCfg.Bssid);
-				DisReq.Reason =  REASON_DISASSOC_STA_LEAVING;
-
-				pMsgElem->Machine = ASSOC_STATE_MACHINE;
-				pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
-				pMsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
-				NdisMoveMemory(pMsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
-
-				MlmeDisassocReqAction(pAd, pMsgElem);
-				kfree(pMsgElem);
-
-				RTMPusecDelay(1000);
-			}
-		}
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-    DBGPRINT(RT_DEBUG_TRACE,("%s===>\n", __FUNCTION__));
-
-	// Set LED
-	//RTMPSetLED(pAd, LED_RADIO_OFF);
-	// Set Radio off flag
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-    {
-	BOOLEAN		Cancelled;
-	if (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
-		{
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-	{
-			RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
-			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
-	}
-			// If during power safe mode.
-			if (pAd->StaCfg.bRadio == TRUE)
-			{
-				DBGPRINT(RT_DEBUG_TRACE,("-->MlmeRadioOff() return on bRadio == TRUE; \n"));
-				return;
-			}
-			// Always radio on since the NIC needs to set the MCU command (LED_RADIO_OFF).
-			if (IDLE_ON(pAd) &&
-				(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
-			{
-				RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
-			}
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
-        {
-            BOOLEAN Cancelled;
-            pAd->Mlme.bPsPollTimerRunning = FALSE;
-            RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
-	        RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer,	&Cancelled);
-        }
-		}
-
-        // Link down first if any association exists
-        if (INFRA_ON(pAd) || ADHOC_ON(pAd))
-            LinkDown(pAd, FALSE);
-        RTMPusecDelay(10000);
-        //==========================================
-        // Clean up old bss table
-        BssTableInit(&pAd->ScanTab);
-
-        /*
-        if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
-        {
-            RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
-            return;
-        }
-        */
-    }
-#endif // CONFIG_STA_SUPPORT //
-	// Set LED.Move to here for fixing LED bug. This flag must be called after LinkDown
-	RTMPSetLED(pAd, LED_RADIO_OFF);
-
-#ifdef CONFIG_STA_SUPPORT
-//KH Debug:All PCIe devices need to use timer to execute radio off function, or the PCIe&&EnableNewPS needs.
-//KH Ans:It is right, because only when the PCIe and EnableNewPs is true, we need to delay the RadioOffTimer
-//to avoid the deadlock with PCIe Power saving function.
-if (pAd->OpMode == OPMODE_STA&&
-	OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)&&
-	pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
-	{
-	RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
-	}
-else
-#endif // CONFIG_STA_SUPPORT //
-{
-
-
-	brc=RT28xxPciAsicRadioOff(pAd, GUIRADIO_OFF, 0);
-
-	if (brc==FALSE)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("%s call RT28xxPciAsicRadioOff fail !!\n", __FUNCTION__));
-	}
-}
-/*
-	// Disable Tx/Rx DMA
-	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);	   // disable DMA
-	GloCfg.field.EnableTxDMA = 0;
-	GloCfg.field.EnableRxDMA = 0;
-	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);	   // abort all TX rings
-
-
-	// MAC_SYS_CTRL => value = 0x0 => 40mA
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0);
-
-	// PWR_PIN_CFG => value = 0x0 => 40mA
-	RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0);
-
-	// TX_PIN_CFG => value = 0x0 => 20mA
-	RTMP_IO_WRITE32(pAd, TX_PIN_CFG, 0);
-
-	if (pAd->CommonCfg.BBPCurrentBW == BW_40)
-	{
-		// Must using 40MHz.
-		AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
-	}
-	else
-	{
-		// Must using 20MHz.
-		AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
-	}
-
-	// Waiting for DMA idle
-	i = 0;
-	do
-	{
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-		if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
-			break;
-
-		RTMPusecDelay(1000);
-	}while (i++ < 100);
-*/
-}
-
-#endif // RTMP_MAC_PCI //
diff --git a/drivers/staging/rt3090/common/cmm_profile.c b/drivers/staging/rt3090/common/cmm_profile.c
deleted file mode 100644
index 5803f42..0000000
--- a/drivers/staging/rt3090/common/cmm_profile.c
+++ /dev/null
@@ -1,2321 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	cmm_profile.c
-
-    Abstract:
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
- */
-
-#include "../rt_config.h"
-
-
-#define ETH_MAC_ADDR_STR_LEN 17  // in format of xx:xx:xx:xx:xx:xx
-
-// We assume the s1 is a sting, s2 is a memory space with 6 bytes. and content of s1 will be changed.
-BOOLEAN rtstrmactohex(PSTRING s1, PSTRING s2)
-{
-	int i = 0;
-	PSTRING ptokS = s1, ptokE = s1;
-
-	if (strlen(s1) != ETH_MAC_ADDR_STR_LEN)
-		return FALSE;
-
-	while((*ptokS) != '\0')
-	{
-		if((ptokE = strchr(ptokS, ':')) != NULL)
-			*ptokE++ = '\0';
-		if ((strlen(ptokS) != 2) || (!isxdigit(*ptokS)) || (!isxdigit(*(ptokS+1))))
-			break; // fail
-		AtoH(ptokS, (PUCHAR)&s2[i++], 1);
-		ptokS = ptokE;
-		if (i == 6)
-			break; // parsing finished
-	}
-
-	return ( i == 6 ? TRUE : FALSE);
-
-}
-
-
-// we assume the s1 and s2 both are strings.
-BOOLEAN rtstrcasecmp(PSTRING s1, PSTRING s2)
-{
-	PSTRING p1 = s1, p2 = s2;
-
-	if (strlen(s1) != strlen(s2))
-		return FALSE;
-
-	while(*p1 != '\0')
-	{
-		if((*p1 != *p2) && ((*p1 ^ *p2) != 0x20))
-			return FALSE;
-		p1++;
-		p2++;
-	}
-
-	return TRUE;
-}
-
-// we assume the s1 (buffer) and s2 (key) both are strings.
-PSTRING rtstrstruncasecmp(PSTRING s1, PSTRING s2)
-{
-	INT l1, l2, i;
-	char temp1, temp2;
-
-	l2 = strlen(s2);
-	if (!l2)
-		return (char *) s1;
-
-	l1 = strlen(s1);
-
-	while (l1 >= l2)
-	{
-		l1--;
-
-		for(i=0; i<l2; i++)
-		{
-			temp1 = *(s1+i);
-			temp2 = *(s2+i);
-
-			if (('a' <= temp1) && (temp1 <= 'z'))
-				temp1 = 'A'+(temp1-'a');
-			if (('a' <= temp2) && (temp2 <= 'z'))
-				temp2 = 'A'+(temp2-'a');
-
-			if (temp1 != temp2)
-				break;
-		}
-
-		if (i == l2)
-			return (char *) s1;
-
-		s1++;
-	}
-
-	return NULL; // not found
-}
-
-//add by kathy
-
- /**
-  * strstr - Find the first substring in a %NUL terminated string
-  * @s1: The string to be searched
-  * @s2: The string to search for
-  */
-PSTRING rtstrstr(PSTRING s1,const PSTRING s2)
-{
-	INT l1, l2;
-
-	l2 = strlen(s2);
-	if (!l2)
-		return s1;
-
-	l1 = strlen(s1);
-
-	while (l1 >= l2)
-	{
-		l1--;
-		if (!memcmp(s1,s2,l2))
-			return s1;
-		s1++;
-	}
-
-	return NULL;
-}
-
-/**
- * rstrtok - Split a string into tokens
- * @s: The string to be searched
- * @ct: The characters to search for
- * * WARNING: strtok is deprecated, use strsep instead. However strsep is not compatible with old architecture.
- */
-PSTRING __rstrtok;
-PSTRING rstrtok(PSTRING s,const PSTRING ct)
-{
-	PSTRING sbegin, send;
-
-	sbegin  = s ? s : __rstrtok;
-	if (!sbegin)
-	{
-		return NULL;
-	}
-
-	sbegin += strspn(sbegin,ct);
-	if (*sbegin == '\0')
-	{
-		__rstrtok = NULL;
-		return( NULL );
-	}
-
-	send = strpbrk( sbegin, ct);
-	if (send && *send != '\0')
-		*send++ = '\0';
-
-	__rstrtok = send;
-
-	return (sbegin);
-}
-
-/**
- * delimitcnt - return the count of a given delimiter in a given string.
- * @s: The string to be searched.
- * @ct: The delimiter to search for.
- * Notice : We suppose the delimiter is a single-char string(for example : ";").
- */
-INT delimitcnt(PSTRING s,PSTRING ct)
-{
-	INT count = 0;
-	/* point to the beginning of the line */
-	PSTRING token = s;
-
-	for ( ;; )
-	{
-		token = strpbrk(token, ct); /* search for delimiters */
-
-        if ( token == NULL )
-		{
-			/* advanced to the terminating null character */
-			break;
-		}
-		/* skip the delimiter */
-	    ++token;
-
-		/*
-		 * Print the found text: use len with %.*s to specify field width.
-		 */
-
-		/* accumulate delimiter count */
-	    ++count;
-	}
-    return count;
-}
-
-/*
-  * converts the Internet host address from the standard numbers-and-dots notation
-  * into binary data.
-  * returns nonzero if the address is valid, zero if not.
-  */
-int rtinet_aton(PSTRING cp, unsigned int *addr)
-{
-	unsigned int	val;
-	int		base, n;
-	STRING		c;
-	unsigned int    parts[4];
-	unsigned int    *pp = parts;
-
-	for (;;)
-    {
-         /*
-          * Collect number up to ``.''.
-          * Values are specified as for C:
-          *	0x=hex, 0=octal, other=decimal.
-          */
-         val = 0;
-         base = 10;
-         if (*cp == '0')
-         {
-             if (*++cp == 'x' || *cp == 'X')
-                 base = 16, cp++;
-             else
-                 base = 8;
-         }
-         while ((c = *cp) != '\0')
-         {
-             if (isdigit((unsigned char) c))
-             {
-                 val = (val * base) + (c - '0');
-                 cp++;
-                 continue;
-             }
-             if (base == 16 && isxdigit((unsigned char) c))
-             {
-                 val = (val << 4) +
-                     (c + 10 - (islower((unsigned char) c) ? 'a' : 'A'));
-                 cp++;
-                 continue;
-             }
-             break;
-         }
-         if (*cp == '.')
-         {
-             /*
-              * Internet format: a.b.c.d a.b.c   (with c treated as 16-bits)
-              * a.b     (with b treated as 24 bits)
-              */
-             if (pp >= parts + 3 || val > 0xff)
-                 return 0;
-             *pp++ = val, cp++;
-         }
-         else
-             break;
-     }
-
-     /*
-      * Check for trailing junk.
-      */
-     while (*cp)
-         if (!isspace((unsigned char) *cp++))
-             return 0;
-
-     /*
-      * Concoct the address according to the number of parts specified.
-      */
-     n = pp - parts + 1;
-     switch (n)
-     {
-
-         case 1:         /* a -- 32 bits */
-             break;
-
-         case 2:         /* a.b -- 8.24 bits */
-             if (val > 0xffffff)
-                 return 0;
-             val |= parts[0] << 24;
-             break;
-
-         case 3:         /* a.b.c -- 8.8.16 bits */
-             if (val > 0xffff)
-                 return 0;
-             val |= (parts[0] << 24) | (parts[1] << 16);
-             break;
-
-         case 4:         /* a.b.c.d -- 8.8.8.8 bits */
-             if (val > 0xff)
-                 return 0;
-             val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
-             break;
-     }
-
-     *addr = htonl(val);
-     return 1;
-
-}
-
-/*
-    ========================================================================
-
-    Routine Description:
-        Find key section for Get key parameter.
-
-    Arguments:
-        buffer                      Pointer to the buffer to start find the key section
-        section                     the key of the secion to be find
-
-    Return Value:
-        NULL                        Fail
-        Others                      Success
-    ========================================================================
-*/
-PSTRING RTMPFindSection(
-    IN  PSTRING   buffer)
-{
-    STRING temp_buf[32];
-    PSTRING  ptr;
-
-    strcpy(temp_buf, "Default");
-
-    if((ptr = rtstrstr(buffer, temp_buf)) != NULL)
-            return (ptr+strlen("\n"));
-        else
-            return NULL;
-}
-
-/*
-    ========================================================================
-
-    Routine Description:
-        Get key parameter.
-
-    Arguments:
-	key			Pointer to key string
-	dest			Pointer to destination
-	destsize		The datasize of the destination
-	buffer		Pointer to the buffer to start find the key
-	bTrimSpace	Set true if you want to strip the space character of the result pattern
-
-    Return Value:
-        TRUE                        Success
-        FALSE                       Fail
-
-    Note:
-	This routine get the value with the matched key (case case-sensitive)
-	For SSID and security key related parameters, we SHALL NOT trim the space(' ') character.
-    ========================================================================
-*/
-INT RTMPGetKeyParameter(
-    IN PSTRING key,
-    OUT PSTRING dest,
-    IN INT destsize,
-    IN PSTRING buffer,
-    IN BOOLEAN bTrimSpace)
-{
-	PSTRING pMemBuf, temp_buf1 = NULL, temp_buf2 = NULL;
-	PSTRING start_ptr, end_ptr;
-	PSTRING ptr;
-	PSTRING offset = NULL;
-	INT  len, keyLen;
-
-
-	keyLen = strlen(key);
-	os_alloc_mem(NULL, (PUCHAR *)&pMemBuf, MAX_PARAM_BUFFER_SIZE  * 2);
-	if (pMemBuf == NULL)
-		return (FALSE);
-
-	memset(pMemBuf, 0, MAX_PARAM_BUFFER_SIZE * 2);
-	temp_buf1 = pMemBuf;
-	temp_buf2 = (PSTRING)(pMemBuf + MAX_PARAM_BUFFER_SIZE);
-
-
-	//find section
-	if((offset = RTMPFindSection(buffer)) == NULL)
-	{
-		os_free_mem(NULL, (PUCHAR)pMemBuf);
-		return (FALSE);
-	}
-
-	strcpy(temp_buf1, "\n");
-	strcat(temp_buf1, key);
-	strcat(temp_buf1, "=");
-
-	//search key
-	if((start_ptr=rtstrstr(offset, temp_buf1)) == NULL)
-	{
-		os_free_mem(NULL, (PUCHAR)pMemBuf);
-		return (FALSE);
-	}
-
-	start_ptr += strlen("\n");
-	if((end_ptr = rtstrstr(start_ptr, "\n"))==NULL)
-		end_ptr = start_ptr+strlen(start_ptr);
-
-	if (end_ptr<start_ptr)
-	{
-		os_free_mem(NULL, (PUCHAR)pMemBuf);
-		return (FALSE);
-	}
-
-	NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
-	temp_buf2[end_ptr-start_ptr]='\0';
-	if((start_ptr=rtstrstr(temp_buf2, "=")) == NULL)
-	{
-		os_free_mem(NULL, (PUCHAR)pMemBuf);
-		return (FALSE);
-	}
-	ptr = (start_ptr +1);
-	//trim special characters, i.e.,  TAB or space
-	while(*start_ptr != 0x00)
-	{
-		if( ((*ptr == ' ') && bTrimSpace) || (*ptr == '\t') )
-			ptr++;
-		else
-			break;
-	}
-	len = strlen(start_ptr);
-
-	memset(dest, 0x00, destsize);
-	strncpy(dest, ptr, ((len >= destsize) ? destsize: len));
-
-	os_free_mem(NULL, (PUCHAR)pMemBuf);
-
-	return TRUE;
-}
-
-
-/*
-    ========================================================================
-
-    Routine Description:
-        Get multiple key parameter.
-
-    Arguments:
-        key                         Pointer to key string
-        dest                        Pointer to destination
-        destsize                    The datasize of the destination
-        buffer                      Pointer to the buffer to start find the key
-
-    Return Value:
-        TRUE                        Success
-        FALSE                       Fail
-
-    Note:
-        This routine get the value with the matched key (case case-sensitive)
-    ========================================================================
-*/
-INT RTMPGetKeyParameterWithOffset(
-    IN  PSTRING   key,
-    OUT PSTRING   dest,
-    OUT	USHORT	*end_offset,
-    IN  INT     destsize,
-    IN  PSTRING   buffer,
-    IN	BOOLEAN	bTrimSpace)
-{
-    PSTRING temp_buf1 = NULL;
-    PSTRING temp_buf2 = NULL;
-    PSTRING start_ptr;
-    PSTRING end_ptr;
-    PSTRING ptr;
-    PSTRING offset = 0;
-    INT  len;
-
-	if (*end_offset >= MAX_INI_BUFFER_SIZE)
-		return (FALSE);
-
-	os_alloc_mem(NULL, (PUCHAR *)&temp_buf1, MAX_PARAM_BUFFER_SIZE);
-
-	if(temp_buf1 == NULL)
-        return (FALSE);
-
-	os_alloc_mem(NULL, (PUCHAR *)&temp_buf2, MAX_PARAM_BUFFER_SIZE);
-	if(temp_buf2 == NULL)
-	{
-		os_free_mem(NULL, (PUCHAR)temp_buf1);
-        return (FALSE);
-	}
-
-    //find section
-	if(*end_offset == 0)
-    {
-		if ((offset = RTMPFindSection(buffer)) == NULL)
-		{
-			os_free_mem(NULL, (PUCHAR)temp_buf1);
-		os_free_mem(NULL, (PUCHAR)temp_buf2);
-	    return (FALSE);
-		}
-    }
-	else
-		offset = buffer + (*end_offset);
-
-    strcpy(temp_buf1, "\n");
-    strcat(temp_buf1, key);
-    strcat(temp_buf1, "=");
-
-    //search key
-    if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
-    {
-		os_free_mem(NULL, (PUCHAR)temp_buf1);
-	os_free_mem(NULL, (PUCHAR)temp_buf2);
-        return (FALSE);
-    }
-
-    start_ptr+=strlen("\n");
-    if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
-       end_ptr=start_ptr+strlen(start_ptr);
-
-    if (end_ptr<start_ptr)
-    {
-		os_free_mem(NULL, (PUCHAR)temp_buf1);
-	os_free_mem(NULL, (PUCHAR)temp_buf2);
-        return (FALSE);
-    }
-
-	*end_offset = end_ptr - buffer;
-
-    NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
-    temp_buf2[end_ptr-start_ptr]='\0';
-    len = strlen(temp_buf2);
-    strcpy(temp_buf1, temp_buf2);
-    if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
-    {
-		os_free_mem(NULL, (PUCHAR)temp_buf1);
-	os_free_mem(NULL, (PUCHAR)temp_buf2);
-        return (FALSE);
-    }
-
-    strcpy(temp_buf2, start_ptr+1);
-    ptr = temp_buf2;
-    //trim space or tab
-    while(*ptr != 0x00)
-    {
-        if((bTrimSpace && (*ptr == ' ')) || (*ptr == '\t') )
-            ptr++;
-        else
-           break;
-    }
-
-    len = strlen(ptr);
-    memset(dest, 0x00, destsize);
-    strncpy(dest, ptr, len >= destsize ?  destsize: len);
-
-	os_free_mem(NULL, (PUCHAR)temp_buf1);
-    os_free_mem(NULL, (PUCHAR)temp_buf2);
-    return TRUE;
-}
-
-
-static int rtmp_parse_key_buffer_from_file(IN  PRTMP_ADAPTER pAd,IN  PSTRING buffer,IN  ULONG KeyType,IN  INT BSSIdx,IN  INT KeyIdx)
-{
-	PSTRING		keybuff;
-	//INT			i = BSSIdx, idx = KeyIdx, retVal;
-	ULONG		KeyLen;
-	//UCHAR		CipherAlg = CIPHER_WEP64;
-	CIPHER_KEY	*pSharedKey;
-
-	keybuff = buffer;
-	KeyLen = strlen(keybuff);
-	pSharedKey = &pAd->SharedKey[BSSIdx][KeyIdx];
-
-	if(((KeyType != 0) && (KeyType != 1)) ||
-	    ((KeyType == 0) && (KeyLen != 10) && (KeyLen != 26)) ||
-	    ((KeyType== 1) && (KeyLen != 5) && (KeyLen != 13)))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Key%dStr is Invalid key length(%ld) or Type(%ld)\n",
-								KeyIdx+1, KeyLen, KeyType));
-		return FALSE;
-	}
-	else
-	{
-		return RT_CfgSetWepKey(pAd, buffer, pSharedKey, KeyIdx);
-	}
-
-}
-
-
-static void rtmp_read_key_parms_from_file(IN  PRTMP_ADAPTER pAd, PSTRING tmpbuf, PSTRING buffer)
-{
-	STRING		tok_str[16];
-	PSTRING		macptr;
-	INT			i = 0, idx;
-	ULONG		KeyType[MAX_MBSSID_NUM];
-	ULONG		KeyIdx;
-
-	NdisZeroMemory(KeyType, sizeof(KeyType));
-
-	//DefaultKeyID
-	if(RTMPGetKeyParameter("DefaultKeyID", tmpbuf, 25, buffer, TRUE))
-	{
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			KeyIdx = simple_strtol(tmpbuf, 0, 10);
-			if((KeyIdx >= 1 ) && (KeyIdx <= 4))
-				pAd->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1);
-			else
-				pAd->StaCfg.DefaultKeyId = 0;
-
-			DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyID(0~3)=%d\n", pAd->StaCfg.DefaultKeyId));
-		}
-#endif // CONFIG_STA_SUPPORT //
-	}
-
-
-	for (idx = 0; idx < 4; idx++)
-	{
-		sprintf(tok_str, "Key%dType", idx + 1);
-		//Key1Type
-		if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer, TRUE))
-		{
-		    for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
-		    {
-				/*
-					do sanity check for KeyType length;
-					or in station mode, the KeyType length > 1,
-					the code will overwrite the stack of caller
-					(RTMPSetProfileParameters) and cause srcbuf = NULL
-				*/
-				if (i < MAX_MBSSID_NUM)
-					KeyType[i] = simple_strtol(macptr, 0, 10);
-		    }
-
-#ifdef CONFIG_STA_SUPPORT
-			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-			{
-				sprintf(tok_str, "Key%dStr", idx + 1);
-				if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer, FALSE))
-				{
-					rtmp_parse_key_buffer_from_file(pAd, tmpbuf, KeyType[BSS0], BSS0, idx);
-				}
-			}
-#endif // CONFIG_STA_SUPPORT //
-		}
-	}
-}
-
-
-
-#ifdef CONFIG_STA_SUPPORT
-static void rtmp_read_sta_wmm_parms_from_file(IN  PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer)
-{
-	PSTRING					macptr;
-	INT						i=0;
-	BOOLEAN					bWmmEnable = FALSE;
-
-	//WmmCapable
-	if(RTMPGetKeyParameter("WmmCapable", tmpbuf, 32, buffer, TRUE))
-	{
-		if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
-		{
-			pAd->CommonCfg.bWmmCapable = TRUE;
-			bWmmEnable = TRUE;
-		}
-		else //Disable
-		{
-			pAd->CommonCfg.bWmmCapable = FALSE;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("WmmCapable=%d\n", pAd->CommonCfg.bWmmCapable));
-	}
-
-#ifdef QOS_DLS_SUPPORT
-	//DLSCapable
-	if(RTMPGetKeyParameter("DLSCapable", tmpbuf, 32, buffer, TRUE))
-	{
-		if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
-		{
-			pAd->CommonCfg.bDLSCapable = TRUE;
-		}
-		else //Disable
-		{
-			pAd->CommonCfg.bDLSCapable = FALSE;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("bDLSCapable=%d\n", pAd->CommonCfg.bDLSCapable));
-	}
-#endif // QOS_DLS_SUPPORT //
-
-	//AckPolicy for AC_BK, AC_BE, AC_VI, AC_VO
-	if(RTMPGetKeyParameter("AckPolicy", tmpbuf, 32, buffer, TRUE))
-	{
-		for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
-		{
-			pAd->CommonCfg.AckPolicy[i] = (UCHAR)simple_strtol(macptr, 0, 10);
-
-			DBGPRINT(RT_DEBUG_TRACE, ("AckPolicy[%d]=%d\n", i, pAd->CommonCfg.AckPolicy[i]));
-		}
-	}
-
-	if (bWmmEnable)
-	{
-		//APSDCapable
-		if(RTMPGetKeyParameter("APSDCapable", tmpbuf, 10, buffer, TRUE))
-		{
-			if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
-				pAd->CommonCfg.bAPSDCapable = TRUE;
-			else
-				pAd->CommonCfg.bAPSDCapable = FALSE;
-
-			DBGPRINT(RT_DEBUG_TRACE, ("APSDCapable=%d\n", pAd->CommonCfg.bAPSDCapable));
-		}
-
-		//MaxSPLength
-		if(RTMPGetKeyParameter("MaxSPLength", tmpbuf, 10, buffer, TRUE))
-		{
-			pAd->CommonCfg.MaxSPLength = simple_strtol(tmpbuf, 0, 10);
-
-			DBGPRINT(RT_DEBUG_TRACE, ("MaxSPLength=%d\n", pAd->CommonCfg.MaxSPLength));
-		}
-
-		//APSDAC for AC_BE, AC_BK, AC_VI, AC_VO
-		if(RTMPGetKeyParameter("APSDAC", tmpbuf, 32, buffer, TRUE))
-		{
-			BOOLEAN apsd_ac[4];
-
-			for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
-			{
-				apsd_ac[i] = (BOOLEAN)simple_strtol(macptr, 0, 10);
-
-				DBGPRINT(RT_DEBUG_TRACE, ("APSDAC%d  %d\n", i,  apsd_ac[i]));
-			}
-
-			pAd->CommonCfg.bAPSDAC_BE = apsd_ac[0];
-			pAd->CommonCfg.bAPSDAC_BK = apsd_ac[1];
-			pAd->CommonCfg.bAPSDAC_VI = apsd_ac[2];
-			pAd->CommonCfg.bAPSDAC_VO = apsd_ac[3];
-
-			pAd->CommonCfg.bACMAPSDTr[0] = apsd_ac[0];
-			pAd->CommonCfg.bACMAPSDTr[1] = apsd_ac[1];
-			pAd->CommonCfg.bACMAPSDTr[2] = apsd_ac[2];
-			pAd->CommonCfg.bACMAPSDTr[3] = apsd_ac[3];
-		}
-	}
-
-}
-#endif // CONFIG_STA_SUPPORT //
-
-
-#ifdef DOT11_N_SUPPORT
-static void HTParametersHook(
-	IN	PRTMP_ADAPTER pAd,
-	IN	PSTRING		  pValueStr,
-	IN	PSTRING		  pInput)
-{
-
-	long Value;
-
-    if (RTMPGetKeyParameter("HT_PROTECT", pValueStr, 25, pInput, TRUE))
-    {
-        Value = simple_strtol(pValueStr, 0, 10);
-        if (Value == 0)
-        {
-            pAd->CommonCfg.bHTProtect = FALSE;
-        }
-        else
-        {
-            pAd->CommonCfg.bHTProtect = TRUE;
-        }
-        DBGPRINT(RT_DEBUG_TRACE, ("HT: Protection  = %s\n", (Value==0) ? "Disable" : "Enable"));
-    }
-
-    if (RTMPGetKeyParameter("HT_MIMOPSEnable", pValueStr, 25, pInput, TRUE))
-    {
-        Value = simple_strtol(pValueStr, 0, 10);
-        if (Value == 0)
-        {
-            pAd->CommonCfg.bMIMOPSEnable = FALSE;
-        }
-        else
-        {
-            pAd->CommonCfg.bMIMOPSEnable = TRUE;
-        }
-        DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPSEnable  = %s\n", (Value==0) ? "Disable" : "Enable"));
-    }
-
-
-    if (RTMPGetKeyParameter("HT_MIMOPSMode", pValueStr, 25, pInput, TRUE))
-    {
-        Value = simple_strtol(pValueStr, 0, 10);
-        if (Value > MMPS_ENABLE)
-        {
-			pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
-        }
-        else
-        {
-            //TODO: add mimo power saving mechanism
-            pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
-			//pAd->CommonCfg.BACapability.field.MMPSmode = Value;
-        }
-        DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPS Mode  = %d\n", (INT) Value));
-    }
-
-    if (RTMPGetKeyParameter("HT_BADecline", pValueStr, 25, pInput, TRUE))
-    {
-        Value = simple_strtol(pValueStr, 0, 10);
-        if (Value == 0)
-        {
-            pAd->CommonCfg.bBADecline = FALSE;
-        }
-        else
-        {
-            pAd->CommonCfg.bBADecline = TRUE;
-        }
-        DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Decline  = %s\n", (Value==0) ? "Disable" : "Enable"));
-    }
-
-
-    if (RTMPGetKeyParameter("HT_DisableReordering", pValueStr, 25, pInput, TRUE))
-    {
-        Value = simple_strtol(pValueStr, 0, 10);
-        if (Value == 0)
-        {
-            pAd->CommonCfg.bDisableReordering = FALSE;
-        }
-        else
-        {
-            pAd->CommonCfg.bDisableReordering = TRUE;
-        }
-        DBGPRINT(RT_DEBUG_TRACE, ("HT: DisableReordering  = %s\n", (Value==0) ? "Disable" : "Enable"));
-    }
-
-    if (RTMPGetKeyParameter("HT_AutoBA", pValueStr, 25, pInput, TRUE))
-    {
-        Value = simple_strtol(pValueStr, 0, 10);
-        if (Value == 0)
-        {
-            pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
-			pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
-        }
-        else
-        {
-            pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
-			pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
-        }
-        pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
-        DBGPRINT(RT_DEBUG_TRACE, ("HT: Auto BA  = %s\n", (Value==0) ? "Disable" : "Enable"));
-    }
-
-	// Tx_+HTC frame
-    if (RTMPGetKeyParameter("HT_HTC", pValueStr, 25, pInput, TRUE))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-		if (Value == 0)
-		{
-			pAd->HTCEnable = FALSE;
-		}
-		else
-		{
-            pAd->HTCEnable = TRUE;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx +HTC frame = %s\n", (Value==0) ? "Disable" : "Enable"));
-	}
-
-	// Enable HT Link Adaptation Control
-	if (RTMPGetKeyParameter("HT_LinkAdapt", pValueStr, 25, pInput, TRUE))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-		if (Value == 0)
-		{
-			pAd->bLinkAdapt = FALSE;
-		}
-		else
-		{
-			pAd->HTCEnable = TRUE;
-			pAd->bLinkAdapt = TRUE;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Link Adaptation Control = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
-	}
-
-	// Reverse Direction Mechanism
-    if (RTMPGetKeyParameter("HT_RDG", pValueStr, 25, pInput, TRUE))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-		if (Value == 0)
-		{
-			pAd->CommonCfg.bRdg = FALSE;
-		}
-		else
-		{
-			pAd->HTCEnable = TRUE;
-            pAd->CommonCfg.bRdg = TRUE;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: RDG = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
-	}
-
-
-
-
-	// Tx A-MSUD ?
-    if (RTMPGetKeyParameter("HT_AMSDU", pValueStr, 25, pInput, TRUE))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-		if (Value == 0)
-		{
-			pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE;
-		}
-		else
-		{
-            pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx A-MSDU = %s\n", (Value==0) ? "Disable" : "Enable"));
-	}
-
-	// MPDU Density
-    if (RTMPGetKeyParameter("HT_MpduDensity", pValueStr, 25, pInput, TRUE))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-		if (Value <=7 && Value >= 0)
-		{
-			pAd->CommonCfg.BACapability.field.MpduDensity = Value;
-			DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d\n", (INT) Value));
-		}
-		else
-		{
-			pAd->CommonCfg.BACapability.field.MpduDensity = 4;
-			DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d (Default)\n", 4));
-		}
-	}
-
-	// Max Rx BA Window Size
-    if (RTMPGetKeyParameter("HT_BAWinSize", pValueStr, 25, pInput, TRUE))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-
-		if (Value >=1 && Value <= 64)
-		{
-			pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value;
-			pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value;
-			DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = %d\n", (INT) Value));
-		}
-		else
-		{
-            pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64;
-			pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;
-			DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = 64 (Defualt)\n"));
-		}
-
-	}
-
-	// Guard Interval
-	if (RTMPGetKeyParameter("HT_GI", pValueStr, 25, pInput, TRUE))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-
-		if (Value == GI_400)
-		{
-			pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400;
-		}
-		else
-		{
-			pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Guard Interval = %s\n", (Value==GI_400) ? "400" : "800" ));
-	}
-
-	// HT Operation Mode : Mixed Mode , Green Field
-	if (RTMPGetKeyParameter("HT_OpMode", pValueStr, 25, pInput, TRUE))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-
-		if (Value == HTMODE_GF)
-		{
-
-			pAd->CommonCfg.RegTransmitSetting.field.HTMODE  = HTMODE_GF;
-		}
-		else
-		{
-			pAd->CommonCfg.RegTransmitSetting.field.HTMODE  = HTMODE_MM;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Operate Mode = %s\n", (Value==HTMODE_GF) ? "Green Field" : "Mixed Mode" ));
-	}
-
-	// Fixed Tx mode : CCK, OFDM
-	if (RTMPGetKeyParameter("FixedTxMode", pValueStr, 25, pInput, TRUE))
-	{
-		UCHAR	fix_tx_mode;
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			fix_tx_mode = FIXED_TXMODE_HT;
-
-			if (strcmp(pValueStr, "OFDM") == 0 || strcmp(pValueStr, "ofdm") == 0)
-			{
-				fix_tx_mode = FIXED_TXMODE_OFDM;
-			}
-			else if (strcmp(pValueStr, "CCK") == 0 || strcmp(pValueStr, "cck") == 0)
-			{
-		        fix_tx_mode = FIXED_TXMODE_CCK;
-			}
-			else if (strcmp(pValueStr, "HT") == 0 || strcmp(pValueStr, "ht") == 0)
-			{
-		        fix_tx_mode = FIXED_TXMODE_HT;
-		}
-		else
-		{
-				Value = simple_strtol(pValueStr, 0, 10);
-				// 1 : CCK
-				// 2 : OFDM
-				// otherwise : HT
-				if (Value == FIXED_TXMODE_CCK || Value == FIXED_TXMODE_OFDM)
-					fix_tx_mode = Value;
-				else
-					fix_tx_mode = FIXED_TXMODE_HT;
-		}
-
-			pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode;
-			DBGPRINT(RT_DEBUG_TRACE, ("Fixed Tx Mode = %d\n", fix_tx_mode));
-
-		}
-#endif // CONFIG_STA_SUPPORT //
-	}
-
-
-	// Channel Width
-	if (RTMPGetKeyParameter("HT_BW", pValueStr, 25, pInput, TRUE))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-
-		if (Value == BW_40)
-		{
-			pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_40;
-		}
-		else
-		{
-            pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_20;
-		}
-
-#ifdef MCAST_RATE_SPECIFIC
-		pAd->CommonCfg.MCastPhyMode.field.BW = pAd->CommonCfg.RegTransmitSetting.field.BW;
-#endif // MCAST_RATE_SPECIFIC //
-
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Channel Width = %s\n", (Value==BW_40) ? "40 MHz" : "20 MHz" ));
-	}
-
-	if (RTMPGetKeyParameter("HT_EXTCHA", pValueStr, 25, pInput, TRUE))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-
-		if (Value == 0)
-		{
-
-			pAd->CommonCfg.RegTransmitSetting.field.EXTCHA  = EXTCHA_BELOW;
-		}
-		else
-		{
-            pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Ext Channel = %s\n", (Value==0) ? "BELOW" : "ABOVE" ));
-	}
-
-	// MSC
-	if (RTMPGetKeyParameter("HT_MCS", pValueStr, 50, pInput, TRUE))
-	{
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			Value = simple_strtol(pValueStr, 0, 10);
-
-//			if ((Value >= 0 && Value <= 15) || (Value == 32))
-			if ((Value >= 0 && Value <= 23) || (Value == 32)) // 3*3
-		{
-				pAd->StaCfg.DesiredTransmitSetting.field.MCS  = Value;
-				pAd->StaCfg.bAutoTxRateSwitch = FALSE;
-				DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = %d\n", pAd->StaCfg.DesiredTransmitSetting.field.MCS));
-		}
-		else
-		{
-				pAd->StaCfg.DesiredTransmitSetting.field.MCS  = MCS_AUTO;
-				pAd->StaCfg.bAutoTxRateSwitch = TRUE;
-				DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = AUTO\n"));
-		}
-	}
-#endif // CONFIG_STA_SUPPORT //
-	}
-
-	// STBC
-    if (RTMPGetKeyParameter("HT_STBC", pValueStr, 25, pInput, TRUE))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-		if (Value == STBC_USE)
-		{
-			pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE;
-		}
-		else
-		{
-			pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: STBC = %d\n", pAd->CommonCfg.RegTransmitSetting.field.STBC));
-	}
-
-	// 40_Mhz_Intolerant
-	if (RTMPGetKeyParameter("HT_40MHZ_INTOLERANT", pValueStr, 25, pInput, TRUE))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-		if (Value == 0)
-		{
-			pAd->CommonCfg.bForty_Mhz_Intolerant = FALSE;
-		}
-		else
-		{
-			pAd->CommonCfg.bForty_Mhz_Intolerant = TRUE;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: 40MHZ INTOLERANT = %d\n", pAd->CommonCfg.bForty_Mhz_Intolerant));
-	}
-	//HT_TxStream
-	if(RTMPGetKeyParameter("HT_TxStream", pValueStr, 10, pInput, TRUE))
-	{
-		switch (simple_strtol(pValueStr, 0, 10))
-		{
-			case 1:
-				pAd->CommonCfg.TxStream = 1;
-				break;
-			case 2:
-				pAd->CommonCfg.TxStream = 2;
-				break;
-			case 3: // 3*3
-			default:
-				pAd->CommonCfg.TxStream = 3;
-
-				if (pAd->MACVersion < RALINK_2883_VERSION)
-					pAd->CommonCfg.TxStream = 2; // only 2 tx streams for RT2860 series
-				break;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx Stream = %d\n", pAd->CommonCfg.TxStream));
-	}
-	//HT_RxStream
-	if(RTMPGetKeyParameter("HT_RxStream", pValueStr, 10, pInput, TRUE))
-	{
-		switch (simple_strtol(pValueStr, 0, 10))
-		{
-			case 1:
-				pAd->CommonCfg.RxStream = 1;
-				break;
-			case 2:
-				pAd->CommonCfg.RxStream = 2;
-				break;
-			case 3:
-			default:
-				pAd->CommonCfg.RxStream = 3;
-
-				if (pAd->MACVersion < RALINK_2883_VERSION)
-					pAd->CommonCfg.RxStream = 2; // only 2 rx streams for RT2860 series
-				break;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Rx Stream = %d\n", pAd->CommonCfg.RxStream));
-	}
-	//2008/11/05: KH add to support Antenna power-saving of AP<--
-	//Green AP
-	if(RTMPGetKeyParameter("GreenAP", pValueStr, 10, pInput, TRUE))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-		if (Value == 0)
-		{
-			pAd->CommonCfg.bGreenAPEnable = FALSE;
-		}
-		else
-		{
-			pAd->CommonCfg.bGreenAPEnable = TRUE;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Green AP= %d\n", pAd->CommonCfg.bGreenAPEnable));
-	}
-
-	// HT_DisallowTKIP
-	if (RTMPGetKeyParameter("HT_DisallowTKIP", pValueStr, 25, pInput, TRUE))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-
-		if (Value == 1)
-		{
-			pAd->CommonCfg.HT_DisallowTKIP = TRUE;
-		}
-		else
-		{
-			pAd->CommonCfg.HT_DisallowTKIP = FALSE;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Disallow TKIP mode = %s\n", (pAd->CommonCfg.HT_DisallowTKIP == TRUE) ? "ON" : "OFF" ));
-	}
-
-
-	//2008/11/05:KH add to support Antenna power-saving of AP-->
-}
-#endif // DOT11_N_SUPPORT //
-
-
-NDIS_STATUS	RTMPSetProfileParameters(
-	IN RTMP_ADAPTER *pAd,
-	IN PSTRING	pBuffer)
-{
-	PSTRING					tmpbuf;
-	ULONG					RtsThresh;
-	ULONG					FragThresh;
-	PSTRING					macptr;
-	INT						i = 0, retval;
-	tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
-	if(tmpbuf == NULL)
-		return NDIS_STATUS_FAILURE;
-
-	do
-	{
-		// set file parameter to portcfg
-		//CountryRegion
-		if(RTMPGetKeyParameter("CountryRegion", tmpbuf, 25, pBuffer, TRUE))
-		{
-			retval = RT_CfgSetCountryRegion(pAd, tmpbuf, BAND_24G);
-			DBGPRINT(RT_DEBUG_TRACE, ("CountryRegion=%d\n", pAd->CommonCfg.CountryRegion));
-		}
-		//CountryRegionABand
-		if(RTMPGetKeyParameter("CountryRegionABand", tmpbuf, 25, pBuffer, TRUE))
-		{
-			retval = RT_CfgSetCountryRegion(pAd, tmpbuf, BAND_5G);
-			DBGPRINT(RT_DEBUG_TRACE, ("CountryRegionABand=%d\n", pAd->CommonCfg.CountryRegionForABand));
-		}
-#ifdef RTMP_EFUSE_SUPPORT
-#ifdef RT30xx
-		//EfuseBufferMode
-		if(RTMPGetKeyParameter("EfuseBufferMode", tmpbuf, 25, pBuffer, TRUE))
-		{
-			pAd->bEEPROMFile = (UCHAR) simple_strtol(tmpbuf, 0, 10);
-			DBGPRINT(RT_DEBUG_TRACE, ("EfuseBufferMode=%d\n", pAd->bUseEfuse));
-		}
-#endif // RT30xx //
-#endif // RTMP_EFUSE_SUPPORT //
-		//CountryCode
-		if(RTMPGetKeyParameter("CountryCode", tmpbuf, 25, pBuffer, TRUE))
-		{
-			NdisMoveMemory(pAd->CommonCfg.CountryCode, tmpbuf , 2);
-#ifdef CONFIG_STA_SUPPORT
-#ifdef EXT_BUILD_CHANNEL_LIST
-			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-				NdisMoveMemory(pAd->StaCfg.StaOriCountryCode, tmpbuf , 2);
-#endif // EXT_BUILD_CHANNEL_LIST //
-#endif // CONFIG_STA_SUPPORT //
-			if (strlen((PSTRING) pAd->CommonCfg.CountryCode) != 0)
-			{
-				pAd->CommonCfg.bCountryFlag = TRUE;
-			}
-			DBGPRINT(RT_DEBUG_TRACE, ("CountryCode=%s\n", pAd->CommonCfg.CountryCode));
-		}
-		//ChannelGeography
-		if(RTMPGetKeyParameter("ChannelGeography", tmpbuf, 25, pBuffer, TRUE))
-		{
-			UCHAR Geography = (UCHAR) simple_strtol(tmpbuf, 0, 10);
-			if (Geography <= BOTH)
-			{
-				pAd->CommonCfg.Geography = Geography;
-				pAd->CommonCfg.CountryCode[2] =
-					(pAd->CommonCfg.Geography == BOTH) ? ' ' : ((pAd->CommonCfg.Geography == IDOR) ? 'I' : 'O');
-#ifdef CONFIG_STA_SUPPORT
-#ifdef EXT_BUILD_CHANNEL_LIST
-				IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-					pAd->StaCfg.StaOriGeography = pAd->CommonCfg.Geography;
-#endif // EXT_BUILD_CHANNEL_LIST //
-#endif // CONFIG_STA_SUPPORT //
-				DBGPRINT(RT_DEBUG_TRACE, ("ChannelGeography=%d\n", pAd->CommonCfg.Geography));
-			}
-		}
-		else
-		{
-			pAd->CommonCfg.Geography = BOTH;
-			pAd->CommonCfg.CountryCode[2] = ' ';
-		}
-
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			//SSID
-			if (RTMPGetKeyParameter("SSID", tmpbuf, 256, pBuffer, FALSE))
-			{
-				if (strlen(tmpbuf) <= 32)
-				{
-						pAd->CommonCfg.SsidLen = (UCHAR) strlen(tmpbuf);
-					NdisZeroMemory(pAd->CommonCfg.Ssid, NDIS_802_11_LENGTH_SSID);
-					NdisMoveMemory(pAd->CommonCfg.Ssid, tmpbuf, pAd->CommonCfg.SsidLen);
-					pAd->MlmeAux.AutoReconnectSsidLen = pAd->CommonCfg.SsidLen;
-					NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, NDIS_802_11_LENGTH_SSID);
-					NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, tmpbuf, pAd->MlmeAux.AutoReconnectSsidLen);
-					pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen;
-					NdisZeroMemory(pAd->MlmeAux.Ssid, NDIS_802_11_LENGTH_SSID);
-					NdisMoveMemory(pAd->MlmeAux.Ssid, tmpbuf, pAd->MlmeAux.SsidLen);
-					DBGPRINT(RT_DEBUG_TRACE, ("%s::(SSID=%s)\n", __FUNCTION__, tmpbuf));
-				}
-			}
-		}
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			//NetworkType
-			if (RTMPGetKeyParameter("NetworkType", tmpbuf, 25, pBuffer, TRUE))
-			{
-				pAd->bConfigChanged = TRUE;
-				if (strcmp(tmpbuf, "Adhoc") == 0)
-					pAd->StaCfg.BssType = BSS_ADHOC;
-				else //Default Infrastructure mode
-					pAd->StaCfg.BssType = BSS_INFRA;
-				// Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
-				pAd->StaCfg.WpaState = SS_NOTUSE;
-				DBGPRINT(RT_DEBUG_TRACE, ("%s::(NetworkType=%d)\n", __FUNCTION__, pAd->StaCfg.BssType));
-			}
-		}
-#ifdef RTMP_MAC_PCI
-		//NewPCIePS
-		if(RTMPGetKeyParameter("NewPCIePS", tmpbuf, 10, pBuffer, TRUE))
-		{
-			UCHAR temp_buffer = (UCHAR) simple_strtol(tmpbuf, 0, 10);
-			if(temp_buffer>0)
-				pAd->StaCfg.PSControl.field.EnableNewPS=TRUE;
-				else
-					pAd->StaCfg.PSControl.field.EnableNewPS=FALSE;
-			DBGPRINT(RT_DEBUG_TRACE, ("NewPCIePS=%d\n", pAd->StaCfg.PSControl.field.EnableNewPS));
-		}
-#endif // RTMP_MAC_PCI //
-#ifdef RT3090
-		//PCIePowerLevel
-
-		if(RTMPGetKeyParameter("PCIePowerLevel", tmpbuf, 10, pBuffer, TRUE))
-		{
-			pAd->StaCfg.PSControl.field.rt30xxPowerMode = (UCHAR) simple_strtol(tmpbuf, 0, 10);
-			DBGPRINT(RT_DEBUG_TRACE, ("PCIePowerLevel=%d\n", pAd->StaCfg.PSControl.field.rt30xxPowerMode));
-		}
-		//FollowHostASPM
-		if(RTMPGetKeyParameter("FollowHostASPM", tmpbuf, 10, pBuffer, TRUE))
-		{
-			UCHAR temp_buffer = (UCHAR) simple_strtol(tmpbuf, 0, 10);
-
-			if(temp_buffer>0)
-				pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM=TRUE;
-				else
-					pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM=FALSE;
-			DBGPRINT(RT_DEBUG_TRACE, ("rt30xxFollowHostASPM=%d\n", pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM));
-		}
-		//ForceTestASPM
-		if(RTMPGetKeyParameter("ForceTestASPM", tmpbuf, 10, pBuffer, TRUE))
-		{
-			UCHAR temp_buffer = (UCHAR) simple_strtol(tmpbuf, 0, 10);
-
-			if(temp_buffer>0)
-				pAd->StaCfg.PSControl.field.rt30xxForceASPMTest=TRUE;
-				else
-					pAd->StaCfg.PSControl.field.rt30xxForceASPMTest=FALSE;
-			DBGPRINT(RT_DEBUG_TRACE, ("rt30xxForceASPM=%d\n", pAd->StaCfg.PSControl.field.rt30xxForceASPMTest));
-		}
-#endif // RT3090 //
-#endif // CONFIG_STA_SUPPORT //
-		//Channel
-		if(RTMPGetKeyParameter("Channel", tmpbuf, 10, pBuffer, TRUE))
-		{
-			pAd->CommonCfg.Channel = (UCHAR) simple_strtol(tmpbuf, 0, 10);
-			DBGPRINT(RT_DEBUG_TRACE, ("Channel=%d\n", pAd->CommonCfg.Channel));
-		}
-		//WirelessMode
-		if(RTMPGetKeyParameter("WirelessMode", tmpbuf, 10, pBuffer, TRUE))
-		{
-			RT_CfgSetWirelessMode(pAd, tmpbuf);
-			DBGPRINT(RT_DEBUG_TRACE, ("PhyMode=%d\n", pAd->CommonCfg.PhyMode));
-		}
-	    //BasicRate
-		if(RTMPGetKeyParameter("BasicRate", tmpbuf, 10, pBuffer, TRUE))
-		{
-			pAd->CommonCfg.BasicRateBitmap = (ULONG) simple_strtol(tmpbuf, 0, 10);
-			DBGPRINT(RT_DEBUG_TRACE, ("BasicRate=%ld\n", pAd->CommonCfg.BasicRateBitmap));
-		}
-		//BeaconPeriod
-		if(RTMPGetKeyParameter("BeaconPeriod", tmpbuf, 10, pBuffer, TRUE))
-		{
-			pAd->CommonCfg.BeaconPeriod = (USHORT) simple_strtol(tmpbuf, 0, 10);
-			DBGPRINT(RT_DEBUG_TRACE, ("BeaconPeriod=%d\n", pAd->CommonCfg.BeaconPeriod));
-		}
-	    //TxPower
-		if(RTMPGetKeyParameter("TxPower", tmpbuf, 10, pBuffer, TRUE))
-		{
-			pAd->CommonCfg.TxPowerPercentage = (ULONG) simple_strtol(tmpbuf, 0, 10);
-#ifdef CONFIG_STA_SUPPORT
-			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-				pAd->CommonCfg.TxPowerDefault = pAd->CommonCfg.TxPowerPercentage;
-#endif // CONFIG_STA_SUPPORT //
-			DBGPRINT(RT_DEBUG_TRACE, ("TxPower=%ld\n", pAd->CommonCfg.TxPowerPercentage));
-		}
-		//BGProtection
-		if(RTMPGetKeyParameter("BGProtection", tmpbuf, 10, pBuffer, TRUE))
-		{
-	//#if 0	//#ifndef WIFI_TEST
-	//		pAd->CommonCfg.UseBGProtection = 2;// disable b/g protection for throughput test
-	//#else
-			switch (simple_strtol(tmpbuf, 0, 10))
-			{
-				case 1: //Always On
-					pAd->CommonCfg.UseBGProtection = 1;
-					break;
-				case 2: //Always OFF
-					pAd->CommonCfg.UseBGProtection = 2;
-					break;
-				case 0: //AUTO
-				default:
-					pAd->CommonCfg.UseBGProtection = 0;
-					break;
-			}
-	//#endif
-			DBGPRINT(RT_DEBUG_TRACE, ("BGProtection=%ld\n", pAd->CommonCfg.UseBGProtection));
-		}
-		//OLBCDetection
-		if(RTMPGetKeyParameter("DisableOLBC", tmpbuf, 10, pBuffer, TRUE))
-		{
-			switch (simple_strtol(tmpbuf, 0, 10))
-			{
-				case 1: //disable OLBC Detection
-					pAd->CommonCfg.DisableOLBCDetect = 1;
-					break;
-				case 0: //enable OLBC Detection
-					pAd->CommonCfg.DisableOLBCDetect = 0;
-					break;
-				default:
-					pAd->CommonCfg.DisableOLBCDetect= 0;
-					break;
-			}
-			DBGPRINT(RT_DEBUG_TRACE, ("OLBCDetection=%ld\n", pAd->CommonCfg.DisableOLBCDetect));
-		}
-		//TxPreamble
-		if(RTMPGetKeyParameter("TxPreamble", tmpbuf, 10, pBuffer, TRUE))
-		{
-			switch (simple_strtol(tmpbuf, 0, 10))
-			{
-				case Rt802_11PreambleShort:
-					pAd->CommonCfg.TxPreamble = Rt802_11PreambleShort;
-					break;
-				case Rt802_11PreambleLong:
-				default:
-					pAd->CommonCfg.TxPreamble = Rt802_11PreambleLong;
-					break;
-			}
-			DBGPRINT(RT_DEBUG_TRACE, ("TxPreamble=%ld\n", pAd->CommonCfg.TxPreamble));
-		}
-		//RTSThreshold
-		if(RTMPGetKeyParameter("RTSThreshold", tmpbuf, 10, pBuffer, TRUE))
-		{
-			RtsThresh = simple_strtol(tmpbuf, 0, 10);
-			if( (RtsThresh >= 1) && (RtsThresh <= MAX_RTS_THRESHOLD) )
-				pAd->CommonCfg.RtsThreshold  = (USHORT)RtsThresh;
-			else
-				pAd->CommonCfg.RtsThreshold = MAX_RTS_THRESHOLD;
-
-			DBGPRINT(RT_DEBUG_TRACE, ("RTSThreshold=%d\n", pAd->CommonCfg.RtsThreshold));
-		}
-		//FragThreshold
-		if(RTMPGetKeyParameter("FragThreshold", tmpbuf, 10, pBuffer, TRUE))
-		{
-			FragThresh = simple_strtol(tmpbuf, 0, 10);
-			pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
-
-			if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
-			{ //illegal FragThresh so we set it to default
-				pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
-				pAd->CommonCfg.bUseZeroToDisableFragment = TRUE;
-			}
-			else if (FragThresh % 2 == 1)
-			{
-				// The length of each fragment shall always be an even number of octets, except for the last fragment
-				// of an MSDU or MMPDU, which may be either an even or an odd number of octets.
-				pAd->CommonCfg.FragmentThreshold = (USHORT)(FragThresh - 1);
-			}
-			else
-			{
-				pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
-			}
-			//pAd->CommonCfg.AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
-			DBGPRINT(RT_DEBUG_TRACE, ("FragThreshold=%d\n", pAd->CommonCfg.FragmentThreshold));
-		}
-		//TxBurst
-		if(RTMPGetKeyParameter("TxBurst", tmpbuf, 10, pBuffer, TRUE))
-		{
-	//#ifdef WIFI_TEST
-	//						pAd->CommonCfg.bEnableTxBurst = FALSE;
-	//#else
-			if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
-				pAd->CommonCfg.bEnableTxBurst = TRUE;
-			else //Disable
-				pAd->CommonCfg.bEnableTxBurst = FALSE;
-	//#endif
-			DBGPRINT(RT_DEBUG_TRACE, ("TxBurst=%d\n", pAd->CommonCfg.bEnableTxBurst));
-		}
-
-#ifdef AGGREGATION_SUPPORT
-		//PktAggregate
-		if(RTMPGetKeyParameter("PktAggregate", tmpbuf, 10, pBuffer, TRUE))
-		{
-			if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
-				pAd->CommonCfg.bAggregationCapable = TRUE;
-			else //Disable
-				pAd->CommonCfg.bAggregationCapable = FALSE;
-#ifdef PIGGYBACK_SUPPORT
-			pAd->CommonCfg.bPiggyBackCapable = pAd->CommonCfg.bAggregationCapable;
-#endif // PIGGYBACK_SUPPORT //
-			DBGPRINT(RT_DEBUG_TRACE, ("PktAggregate=%d\n", pAd->CommonCfg.bAggregationCapable));
-		}
-#else
-		pAd->CommonCfg.bAggregationCapable = FALSE;
-		pAd->CommonCfg.bPiggyBackCapable = FALSE;
-#endif // AGGREGATION_SUPPORT //
-
-		// WmmCapable
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-			rtmp_read_sta_wmm_parms_from_file(pAd, tmpbuf, pBuffer);
-#endif // CONFIG_STA_SUPPORT //
-
-		//ShortSlot
-		if(RTMPGetKeyParameter("ShortSlot", tmpbuf, 10, pBuffer, TRUE))
-		{
-			RT_CfgSetShortSlot(pAd, tmpbuf);
-			DBGPRINT(RT_DEBUG_TRACE, ("ShortSlot=%d\n", pAd->CommonCfg.bUseShortSlotTime));
-		}
-		//IEEE80211H
-		if(RTMPGetKeyParameter("IEEE80211H", tmpbuf, 10, pBuffer, TRUE))
-		{
-		    for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
-		    {
-				if(simple_strtol(macptr, 0, 10) != 0)  //Enable
-					pAd->CommonCfg.bIEEE80211H = TRUE;
-				else //Disable
-					pAd->CommonCfg.bIEEE80211H = FALSE;
-
-				DBGPRINT(RT_DEBUG_TRACE, ("IEEE80211H=%d\n", pAd->CommonCfg.bIEEE80211H));
-		    }
-		}
-		//CSPeriod
-		if(RTMPGetKeyParameter("CSPeriod", tmpbuf, 10, pBuffer, TRUE))
-		{
-		    if(simple_strtol(tmpbuf, 0, 10) != 0)
-				pAd->CommonCfg.RadarDetect.CSPeriod = simple_strtol(tmpbuf, 0, 10);
-			else
-				pAd->CommonCfg.RadarDetect.CSPeriod = 0;
-
-				DBGPRINT(RT_DEBUG_TRACE, ("CSPeriod=%d\n", pAd->CommonCfg.RadarDetect.CSPeriod));
-		}
-
-#ifdef MERGE_ARCH_TEAM
-		// DfsLowerLimit
-		if(RTMPGetKeyParameter("DfsLowerLimit", tmpbuf, 10, pBuffer, TRUE))
-		{
-			if(simple_strtol(tmpbuf, 0, 10) != 0)
-				pAd->CommonCfg.RadarDetect.DfsLowerLimit = simple_strtol(tmpbuf, 0, 10);
-
-			DBGPRINT(RT_DEBUG_TRACE, ("DfsLowerLimit=%ld\n", pAd->CommonCfg.RadarDetect.DfsLowerLimit));
-		}
-
-		// DfsUpperLimit
-		if(RTMPGetKeyParameter("DfsUpperLimit", tmpbuf, 10, pBuffer, TRUE))
-		{
-			if(simple_strtol(tmpbuf, 0, 10) != 0)
-				pAd->CommonCfg.RadarDetect.DfsUpperLimit = simple_strtol(tmpbuf, 0, 10);
-
-			DBGPRINT(RT_DEBUG_TRACE, ("DfsUpperLimit=%ld\n", pAd->CommonCfg.RadarDetect.DfsUpperLimit));
-		}
-
-		// FixDfsLimit
-		if(RTMPGetKeyParameter("FixDfsLimit", tmpbuf, 10, pBuffer, TRUE))
-		{
-		    if(simple_strtol(tmpbuf, 0, 10) != 0)
-				pAd->CommonCfg.RadarDetect.FixDfsLimit = TRUE;
-			else
-				pAd->CommonCfg.RadarDetect.FixDfsLimit = FALSE;
-
-			DBGPRINT(RT_DEBUG_TRACE, ("FixDfsLimit=%d\n", pAd->CommonCfg.RadarDetect.FixDfsLimit));
-		}
-
-		// LongPulseRadarTh
-		if(RTMPGetKeyParameter("LongPulseRadarTh", tmpbuf, 10, pBuffer, TRUE))
-		{
-		    if(simple_strtol(tmpbuf, 0, 10) != 0)
-				pAd->CommonCfg.RadarDetect.LongPulseRadarTh = simple_strtol(tmpbuf, 0, 10);
-
-			DBGPRINT(RT_DEBUG_TRACE, ("LongPulseRadarTh=%d\n", pAd->CommonCfg.RadarDetect.LongPulseRadarTh));
-		}
-
-		// AvgRssiReq
-		if(RTMPGetKeyParameter("AvgRssiReq", tmpbuf, 10, pBuffer, TRUE))
-		{
-			if(simple_strtol(tmpbuf, 0, 10) != 0)
-				pAd->CommonCfg.RadarDetect.AvgRssiReq = simple_strtol(tmpbuf, 0, 10);
-
-			DBGPRINT(RT_DEBUG_TRACE, ("AvgRssiReq=%d\n", pAd->CommonCfg.RadarDetect.AvgRssiReq));
-		}
-
-#endif // MERGE_ARCH_TEAM //
-
-		//RDRegion
-		if(RTMPGetKeyParameter("RDRegion", tmpbuf, 128, pBuffer, TRUE))
-		{
-						RADAR_DETECT_STRUCT	*pRadarDetect = &pAd->CommonCfg.RadarDetect;
-			if ((strncmp(tmpbuf, "JAP_W53", 7) == 0) || (strncmp(tmpbuf, "jap_w53", 7) == 0))
-			{
-							pRadarDetect->RDDurRegion = JAP_W53;
-							pRadarDetect->DfsSessionTime = 15;
-			}
-			else if ((strncmp(tmpbuf, "JAP_W56", 7) == 0) || (strncmp(tmpbuf, "jap_w56", 7) == 0))
-			{
-							pRadarDetect->RDDurRegion = JAP_W56;
-							pRadarDetect->DfsSessionTime = 13;
-			}
-			else if ((strncmp(tmpbuf, "JAP", 3) == 0) || (strncmp(tmpbuf, "jap", 3) == 0))
-			{
-							pRadarDetect->RDDurRegion = JAP;
-							pRadarDetect->DfsSessionTime = 5;
-			}
-			else  if ((strncmp(tmpbuf, "FCC", 3) == 0) || (strncmp(tmpbuf, "fcc", 3) == 0))
-			{
-							pRadarDetect->RDDurRegion = FCC;
-							pRadarDetect->DfsSessionTime = 5;
-#ifdef DFS_FCC_BW40_FIX
-							pRadarDetect->DfsSessionFccOff = 0;
-#endif // DFS_FCC_BW40_FIX //
-			}
-			else if ((strncmp(tmpbuf, "CE", 2) == 0) || (strncmp(tmpbuf, "ce", 2) == 0))
-			{
-							pRadarDetect->RDDurRegion = CE;
-							pRadarDetect->DfsSessionTime = 13;
-			}
-			else
-			{
-							pRadarDetect->RDDurRegion = CE;
-							pRadarDetect->DfsSessionTime = 13;
-			}
-
-						DBGPRINT(RT_DEBUG_TRACE, ("RDRegion=%d\n", pRadarDetect->RDDurRegion));
-		}
-		else
-		{
-			pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
-			pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
-		}
-
-		//WirelessEvent
-		if(RTMPGetKeyParameter("WirelessEvent", tmpbuf, 10, pBuffer, TRUE))
-		{
-#if WIRELESS_EXT >= 15
-		    if(simple_strtol(tmpbuf, 0, 10) != 0)
-				pAd->CommonCfg.bWirelessEvent = simple_strtol(tmpbuf, 0, 10);
-			else
-				pAd->CommonCfg.bWirelessEvent = 0;	// disable
-#else
-			pAd->CommonCfg.bWirelessEvent = 0;	// disable
-#endif
-				DBGPRINT(RT_DEBUG_TRACE, ("WirelessEvent=%d\n", pAd->CommonCfg.bWirelessEvent));
-		}
-		if(RTMPGetKeyParameter("WiFiTest", tmpbuf, 10, pBuffer, TRUE))
-		{
-		    if(simple_strtol(tmpbuf, 0, 10) != 0)
-				pAd->CommonCfg.bWiFiTest= simple_strtol(tmpbuf, 0, 10);
-			else
-				pAd->CommonCfg.bWiFiTest = 0;	// disable
-
-				DBGPRINT(RT_DEBUG_TRACE, ("WiFiTest=%d\n", pAd->CommonCfg.bWiFiTest));
-		}
-		//AuthMode
-		if(RTMPGetKeyParameter("AuthMode", tmpbuf, 128, pBuffer, TRUE))
-		{
-#ifdef CONFIG_STA_SUPPORT
-			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-			{
-				if ((strcmp(tmpbuf, "WEPAUTO") == 0) || (strcmp(tmpbuf, "wepauto") == 0))
-	                            pAd->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
-	                        else if ((strcmp(tmpbuf, "SHARED") == 0) || (strcmp(tmpbuf, "shared") == 0))
-	                            pAd->StaCfg.AuthMode = Ndis802_11AuthModeShared;
-	                        else if ((strcmp(tmpbuf, "WPAPSK") == 0) || (strcmp(tmpbuf, "wpapsk") == 0))
-	                            pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
-	                        else if ((strcmp(tmpbuf, "WPANONE") == 0) || (strcmp(tmpbuf, "wpanone") == 0))
-	                            pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
-	                        else if ((strcmp(tmpbuf, "WPA2PSK") == 0) || (strcmp(tmpbuf, "wpa2psk") == 0))
-							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
-#ifdef WPA_SUPPLICANT_SUPPORT
-							else if ((strcmp(tmpbuf, "WPA") == 0) || (strcmp(tmpbuf, "wpa") == 0))
-			                    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
-							else if ((strcmp(tmpbuf, "WPA2") == 0) || (strcmp(tmpbuf, "wpa2") == 0))
-							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
-#endif // WPA_SUPPLICANT_SUPPORT //
-	                        else
-	                            pAd->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
-
-	                        pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-
-				DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __FUNCTION__, pAd->StaCfg.WepStatus));
-			}
-#endif // CONFIG_STA_SUPPORT //
-		}
-		//EncrypType
-		if(RTMPGetKeyParameter("EncrypType", tmpbuf, 128, pBuffer, TRUE))
-		{
-
-#ifdef CONFIG_STA_SUPPORT
-			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-			{
-				if ((strcmp(tmpbuf, "WEP") == 0) || (strcmp(tmpbuf, "wep") == 0))
-					pAd->StaCfg.WepStatus	= Ndis802_11WEPEnabled;
-				else if ((strcmp(tmpbuf, "TKIP") == 0) || (strcmp(tmpbuf, "tkip") == 0))
-					pAd->StaCfg.WepStatus	= Ndis802_11Encryption2Enabled;
-				else if ((strcmp(tmpbuf, "AES") == 0) || (strcmp(tmpbuf, "aes") == 0))
-					pAd->StaCfg.WepStatus	= Ndis802_11Encryption3Enabled;
-				else
-					pAd->StaCfg.WepStatus	= Ndis802_11WEPDisabled;
-
-				// Update all wepstatus related
-				pAd->StaCfg.PairCipher		= pAd->StaCfg.WepStatus;
-				pAd->StaCfg.GroupCipher		= pAd->StaCfg.WepStatus;
-				pAd->StaCfg.OrigWepStatus	= pAd->StaCfg.WepStatus;
-				pAd->StaCfg.bMixCipher		= FALSE;
-
-				//RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
-				DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __FUNCTION__, pAd->StaCfg.WepStatus));
-			}
-#endif // CONFIG_STA_SUPPORT //
-		}
-
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			if(RTMPGetKeyParameter("WPAPSK", tmpbuf, 512, pBuffer, FALSE))
-			{
-				int     ret = TRUE;
-
-				tmpbuf[strlen(tmpbuf)] = '\0'; // make STA can process .$^& for WPAPSK input
-
-				if ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
-					(pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
-					(pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
-					)
-				{
-					ret = FALSE;
-				}
-				else
-				{
-					ret = RT_CfgSetWPAPSKKey(pAd, tmpbuf, (PUCHAR)pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->StaCfg.PMK);
-				}
-
-				if (ret == TRUE)
-				{
-			RTMPZeroMemory(pAd->StaCfg.WpaPassPhrase, 64);
-			RTMPMoveMemory(pAd->StaCfg.WpaPassPhrase, tmpbuf, strlen(tmpbuf));
-					pAd->StaCfg.WpaPassPhraseLen= strlen(tmpbuf);
-
-					if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
-						(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
-					{
-						// Start STA supplicant state machine
-						pAd->StaCfg.WpaState = SS_START;
-					}
-					else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
-					{
-						pAd->StaCfg.WpaState = SS_NOTUSE;
-					}
-					DBGPRINT(RT_DEBUG_TRACE, ("%s::(WPAPSK=%s)\n", __FUNCTION__, tmpbuf));
-				}
-			}
-		}
-#endif // CONFIG_STA_SUPPORT //
-
-		//DefaultKeyID, KeyType, KeyStr
-		rtmp_read_key_parms_from_file(pAd, tmpbuf, pBuffer);
-
-
-		//HSCounter
-		/*if(RTMPGetKeyParameter("HSCounter", tmpbuf, 10, pBuffer, TRUE))
-		{
-			switch (simple_strtol(tmpbuf, 0, 10))
-			{
-				case 1: //Enable
-					pAd->CommonCfg.bEnableHSCounter = TRUE;
-					break;
-				case 0: //Disable
-				default:
-					pAd->CommonCfg.bEnableHSCounter = FALSE;
-					break;
-			}
-			DBGPRINT(RT_DEBUG_TRACE, "HSCounter=%d\n", pAd->CommonCfg.bEnableHSCounter);
-		}*/
-
-#ifdef DOT11_N_SUPPORT
-		HTParametersHook(pAd, tmpbuf, pBuffer);
-#endif // DOT11_N_SUPPORT //
-
-
-#ifdef CARRIER_DETECTION_SUPPORT
-			//CarrierDetect
-			if(RTMPGetKeyParameter("CarrierDetect", tmpbuf, 128, pBuffer, TRUE))
-			{
-				if ((strncmp(tmpbuf, "0", 1) == 0))
-					pAd->CommonCfg.CarrierDetect.Enable = FALSE;
-				else if ((strncmp(tmpbuf, "1", 1) == 0))
-					pAd->CommonCfg.CarrierDetect.Enable = TRUE;
-				else
-					pAd->CommonCfg.CarrierDetect.Enable = FALSE;
-
-				DBGPRINT(RT_DEBUG_TRACE, ("CarrierDetect.Enable=%d\n", pAd->CommonCfg.CarrierDetect.Enable));
-			}
-			else
-				pAd->CommonCfg.CarrierDetect.Enable = FALSE;
-#endif // CARRIER_DETECTION_SUPPORT //
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			//PSMode
-			if (RTMPGetKeyParameter("PSMode", tmpbuf, 10, pBuffer, TRUE))
-			{
-				if (pAd->StaCfg.BssType == BSS_INFRA)
-				{
-					if ((strcmp(tmpbuf, "MAX_PSP") == 0) || (strcmp(tmpbuf, "max_psp") == 0))
-					{
-						// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
-						// to exclude certain situations.
-						//	   MlmeSetPsm(pAd, PWR_SAVE);
-						OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
-						if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
-							pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
-						pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
-						pAd->StaCfg.DefaultListenCount = 5;
-					}
-					else if ((strcmp(tmpbuf, "Fast_PSP") == 0) || (strcmp(tmpbuf, "fast_psp") == 0)
-						|| (strcmp(tmpbuf, "FAST_PSP") == 0))
-					{
-						// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
-						// to exclude certain situations.
-						//	   MlmeSetPsmBit(pAd, PWR_SAVE);
-						OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
-						if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
-							pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
-						pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
-						pAd->StaCfg.DefaultListenCount = 3;
-					}
-					else if ((strcmp(tmpbuf, "Legacy_PSP") == 0) || (strcmp(tmpbuf, "legacy_psp") == 0)
-						|| (strcmp(tmpbuf, "LEGACY_PSP") == 0))
-					{
-						// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
-						// to exclude certain situations.
-						//	   MlmeSetPsmBit(pAd, PWR_SAVE);
-						OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
-						if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
-							pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
-						pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
-						pAd->StaCfg.DefaultListenCount = 3;
-					}
-					else
-					{ //Default Ndis802_11PowerModeCAM
-						// clear PSM bit immediately
-						RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
-						OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
-						if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
-							pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
-						pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
-					}
-					DBGPRINT(RT_DEBUG_TRACE, ("PSMode=%ld\n", pAd->StaCfg.WindowsPowerMode));
-				}
-			}
-			// AutoRoaming by RSSI
-			if (RTMPGetKeyParameter("AutoRoaming", tmpbuf, 32, pBuffer, TRUE))
-			{
-				if (simple_strtol(tmpbuf, 0, 10) == 0)
-					pAd->StaCfg.bAutoRoaming = FALSE;
-				else
-					pAd->StaCfg.bAutoRoaming = TRUE;
-
-				DBGPRINT(RT_DEBUG_TRACE, ("AutoRoaming=%d\n", pAd->StaCfg.bAutoRoaming));
-			}
-			// RoamThreshold
-			if (RTMPGetKeyParameter("RoamThreshold", tmpbuf, 32, pBuffer, TRUE))
-			{
-				long lInfo = simple_strtol(tmpbuf, 0, 10);
-
-				if (lInfo > 90 || lInfo < 60)
-					pAd->StaCfg.dBmToRoam = -70;
-				else
-					pAd->StaCfg.dBmToRoam = (CHAR)(-1)*lInfo;
-
-				DBGPRINT(RT_DEBUG_TRACE, ("RoamThreshold=%d  dBm\n", pAd->StaCfg.dBmToRoam));
-			}
-
-			if(RTMPGetKeyParameter("TGnWifiTest", tmpbuf, 10, pBuffer, TRUE))
-			{
-				if(simple_strtol(tmpbuf, 0, 10) == 0)
-					pAd->StaCfg.bTGnWifiTest = FALSE;
-				else
-					pAd->StaCfg.bTGnWifiTest = TRUE;
-					DBGPRINT(RT_DEBUG_TRACE, ("TGnWifiTest=%d\n", pAd->StaCfg.bTGnWifiTest));
-			}
-
-			// Beacon Lost Time
-			if (RTMPGetKeyParameter("BeaconLostTime", tmpbuf, 32, pBuffer, TRUE))
-			{
-				ULONG lInfo = (ULONG)simple_strtol(tmpbuf, 0, 10);
-
-				if ((lInfo != 0) && (lInfo <= 60))
-					pAd->StaCfg.BeaconLostTime = (lInfo * OS_HZ);
-				DBGPRINT(RT_DEBUG_TRACE, ("BeaconLostTime=%ld \n", pAd->StaCfg.BeaconLostTime));
-			}
-
-
-		}
-#endif // CONFIG_STA_SUPPORT //
-
-
-
-#ifdef RT30xx
-#ifdef ANT_DIVERSITY_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			if(RTMPGetKeyParameter("AntDiversity", tmpbuf, 10, pBuffer, TRUE))
-			{
-				for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
-				{
-					UCHAR Ant = simple_strtol(tmpbuf, 0, 10);
-					if(Ant < 3)
-						pAd->CommonCfg.bRxAntDiversity = Ant;
-					else
-						pAd->CommonCfg.bRxAntDiversity = ANT_DIVERSITY_DISABLE;
-
-					DBGPRINT(RT_DEBUG_ERROR, ("AntDiversity=%d\n", pAd->CommonCfg.bRxAntDiversity));
-				}
-			}
-		}
-#endif // ANT_DIVERSITY_SUPPORT //
-#endif // RT30xx //
-
-	}while(0);
-
-
-	kfree(tmpbuf);
-
-	return NDIS_STATUS_SUCCESS;
-
-}
-
-
-#ifdef MULTIPLE_CARD_SUPPORT
-// record whether the card in the card list is used in the card file
-UINT8  MC_CardUsed[MAX_NUM_OF_MULTIPLE_CARD];
-// record used card mac address in the card list
-static UINT8  MC_CardMac[MAX_NUM_OF_MULTIPLE_CARD][6];
-
-/*
-========================================================================
-Routine Description:
-    Get card profile path.
-
-Arguments:
-    pAd
-
-Return Value:
-    TRUE		- Find a card profile
-	FALSE		- use default profile
-
-Note:
-========================================================================
-*/
-BOOLEAN RTMP_CardInfoRead(
-	IN	PRTMP_ADAPTER pAd)
-{
-#define MC_SELECT_CARDID		0	/* use CARD ID (0 ~ 31) to identify different cards */
-#define MC_SELECT_MAC			1	/* use CARD MAC to identify different cards */
-#define MC_SELECT_CARDTYPE		2	/* use CARD type (abgn or bgn) to identify different cards */
-
-#define LETTER_CASE_TRANSLATE(txt_p, card_id)			\
-	{	UINT32 _len; char _char;						\
-		for(_len=0; _len<strlen(card_id); _len++) {		\
-			_char = *(txt_p + _len);					\
-			if (('A' <= _char) && (_char <= 'Z'))		\
-				*(txt_p+_len) = 'a'+(_char-'A');		\
-		} }
-
-	RTMP_OS_FD srcf;
-	INT retval;
-	PSTRING buffer, tmpbuf;
-	STRING card_id_buf[30], RFIC_word[30];
-	BOOLEAN flg_match_ok = FALSE;
-	INT32 card_select_method;
-	INT32 card_free_id, card_nouse_id, card_same_mac_id, card_match_id;
-	EEPROM_ANTENNA_STRUC antenna;
-	USHORT addr01, addr23, addr45;
-	UINT8 mac[6];
-	UINT32 data, card_index;
-	UCHAR *start_ptr;
-	RTMP_OS_FS_INFO osFSInfo;
-
-	// init
-	buffer = kmalloc(MAX_INI_BUFFER_SIZE, MEM_ALLOC_FLAG);
-	if (buffer == NULL)
-		return FALSE;
-
-	tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
-	if(tmpbuf == NULL)
-	{
-		kfree(buffer);
-		return NDIS_STATUS_FAILURE;
-	}
-
-	// get RF IC type
-	RTMP_IO_READ32(pAd, E2PROM_CSR, &data);
-
-	if ((data & 0x30) == 0)
-		pAd->EEPROMAddressNum = 6;	// 93C46
-	else if ((data & 0x30) == 0x10)
-		pAd->EEPROMAddressNum = 8;	// 93C66
-	else
-		pAd->EEPROMAddressNum = 8;	// 93C86
-
-	RT28xx_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET, antenna.word);
-
-	if ((antenna.field.RfIcType == RFIC_2850) ||
-		(antenna.field.RfIcType == RFIC_2750))
-	{
-		/* ABGN card */
-		strcpy(RFIC_word, "abgn");
-	}
-	else
-	{
-		/* BGN card */
-		strcpy(RFIC_word, "bgn");
-	}
-
-	// get MAC address
-	RT28xx_EEPROM_READ16(pAd, 0x04, addr01);
-	RT28xx_EEPROM_READ16(pAd, 0x06, addr23);
-	RT28xx_EEPROM_READ16(pAd, 0x08, addr45);
-
-	mac[0] = (UCHAR)(addr01 & 0xff);
-	mac[1] = (UCHAR)(addr01 >> 8);
-	mac[2] = (UCHAR)(addr23 & 0xff);
-	mac[3] = (UCHAR)(addr23 >> 8);
-	mac[4] = (UCHAR)(addr45 & 0xff);
-	mac[5] = (UCHAR)(addr45 >> 8);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("mac addr=%02x:%02x:%02x:%02x:%02x:%02x!\n", PRINT_MAC(mac)));
-
-	RtmpOSFSInfoChange(&osFSInfo, TRUE);
-	// open card information file
-	srcf = RtmpOSFileOpen(CARD_INFO_PATH, O_RDONLY, 0);
-	if (IS_FILE_OPEN_ERR(srcf))
-	{
-		/* card information file does not exist */
-			DBGPRINT(RT_DEBUG_TRACE,
-				("--> Error opening %s\n", CARD_INFO_PATH));
-		goto  free_resource;
-	}
-
-	/* card information file exists so reading the card information */
-	memset(buffer, 0x00, MAX_INI_BUFFER_SIZE);
-	retval = RtmpOSFileRead(srcf, buffer, MAX_INI_BUFFER_SIZE);
-	if (retval < 0)
-	{
-		/* read fail */
-			DBGPRINT(RT_DEBUG_TRACE,
-				("--> Read %s error %d\n", CARD_INFO_PATH, -retval));
-	}
-	else
-	{
-		/* get card selection method */
-		memset(tmpbuf, 0x00, MAX_PARAM_BUFFER_SIZE);
-		card_select_method = MC_SELECT_CARDTYPE; // default
-
-		if (RTMPGetKeyParameter("SELECT", tmpbuf, 256, buffer, TRUE))
-		{
-			if (strcmp(tmpbuf, "CARDID") == 0)
-				card_select_method = MC_SELECT_CARDID;
-			else if (strcmp(tmpbuf, "MAC") == 0)
-				card_select_method = MC_SELECT_MAC;
-			else if (strcmp(tmpbuf, "CARDTYPE") == 0)
-				card_select_method = MC_SELECT_CARDTYPE;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE,
-				("MC> Card Selection = %d\n", card_select_method));
-
-		// init
-		card_free_id = -1;
-		card_nouse_id = -1;
-		card_same_mac_id = -1;
-		card_match_id = -1;
-
-		// search current card information records
-		for(card_index=0;
-			card_index<MAX_NUM_OF_MULTIPLE_CARD;
-			card_index++)
-		{
-			if ((*(UINT32 *)&MC_CardMac[card_index][0] == 0) &&
-				(*(UINT16 *)&MC_CardMac[card_index][4] == 0))
-			{
-				// MAC is all-0 so the entry is available
-				MC_CardUsed[card_index] = 0;
-
-				if (card_free_id < 0)
-					card_free_id = card_index; // 1st free entry
-			}
-			else
-			{
-				if (memcmp(MC_CardMac[card_index], mac, 6) == 0)
-				{
-					// we find the entry with same MAC
-					if (card_same_mac_id < 0)
-						card_same_mac_id = card_index; // 1st same entry
-				}
-				else
-				{
-					// MAC is not all-0 but used flag == 0
-					if ((MC_CardUsed[card_index] == 0) &&
-						(card_nouse_id < 0))
-					{
-						card_nouse_id = card_index; // 1st available entry
-					}
-				}
-			}
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE,
-				("MC> Free = %d, Same = %d, NOUSE = %d\n",
-				card_free_id, card_same_mac_id, card_nouse_id));
-
-		if ((card_same_mac_id >= 0) &&
-			((card_select_method == MC_SELECT_CARDID) ||
-			(card_select_method == MC_SELECT_CARDTYPE)))
-		{
-			// same MAC entry is found
-			card_match_id = card_same_mac_id;
-
-			if (card_select_method == MC_SELECT_CARDTYPE)
-			{
-				// for CARDTYPE
-				sprintf(card_id_buf, "%02dCARDTYPE%s",
-						card_match_id, RFIC_word);
-
-				if ((start_ptr = (PUCHAR)rtstrstruncasecmp(buffer, card_id_buf)) != NULL)
-				{
-					// we found the card ID
-					LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
-				}
-			}
-		}
-		else
-		{
-			// the card is 1st plug-in, try to find the match card profile
-			switch(card_select_method)
-			{
-				case MC_SELECT_CARDID: // CARDID
-				default:
-					if (card_free_id >= 0)
-						card_match_id = card_free_id;
-					else
-						card_match_id = card_nouse_id;
-					break;
-
-				case MC_SELECT_MAC: // MAC
-					sprintf(card_id_buf, "MAC%02x:%02x:%02x:%02x:%02x:%02x",
-							mac[0], mac[1], mac[2],
-							mac[3], mac[4], mac[5]);
-
-					/* try to find the key word in the card file */
-					if ((start_ptr = (PUCHAR)rtstrstruncasecmp(buffer, card_id_buf)) != NULL)
-					{
-						LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
-
-						/* get the row ID (2 ASCII characters) */
-						start_ptr -= 2;
-						card_id_buf[0] = *(start_ptr);
-						card_id_buf[1] = *(start_ptr+1);
-						card_id_buf[2] = 0x00;
-
-						card_match_id = simple_strtol(card_id_buf, 0, 10);
-					}
-					break;
-
-				case MC_SELECT_CARDTYPE: // CARDTYPE
-					card_nouse_id = -1;
-
-					for(card_index=0;
-						card_index<MAX_NUM_OF_MULTIPLE_CARD;
-						card_index++)
-					{
-						sprintf(card_id_buf, "%02dCARDTYPE%s",
-								card_index, RFIC_word);
-
-						if ((start_ptr = (PUCHAR)rtstrstruncasecmp(buffer,
-													card_id_buf)) != NULL)
-						{
-							LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
-
-							if (MC_CardUsed[card_index] == 0)
-							{
-								/* current the card profile is not used */
-								if ((*(UINT32 *)&MC_CardMac[card_index][0] == 0) &&
-									(*(UINT16 *)&MC_CardMac[card_index][4] == 0))
-								{
-									// find it and no previous card use it
-									card_match_id = card_index;
-									break;
-								}
-								else
-								{
-									// ever a card use it
-									if (card_nouse_id < 0)
-										card_nouse_id = card_index;
-								}
-							}
-						}
-					}
-
-					// if not find a free one, use the available one
-					if (card_match_id < 0)
-						card_match_id = card_nouse_id;
-					break;
-			}
-		}
-
-		if (card_match_id >= 0)
-		{
-			// make up search keyword
-			switch(card_select_method)
-			{
-				case MC_SELECT_CARDID: // CARDID
-					sprintf(card_id_buf, "%02dCARDID", card_match_id);
-					break;
-
-				case MC_SELECT_MAC: // MAC
-					sprintf(card_id_buf,
-							"%02dmac%02x:%02x:%02x:%02x:%02x:%02x",
-							card_match_id,
-							mac[0], mac[1], mac[2],
-							mac[3], mac[4], mac[5]);
-					break;
-
-				case MC_SELECT_CARDTYPE: // CARDTYPE
-				default:
-					sprintf(card_id_buf, "%02dcardtype%s",
-							card_match_id, RFIC_word);
-					break;
-			}
-
-			DBGPRINT(RT_DEBUG_TRACE, ("Search Keyword = %s\n", card_id_buf));
-
-			// read card file path
-			if (RTMPGetKeyParameter(card_id_buf, tmpbuf, 256, buffer, TRUE))
-			{
-				if (strlen(tmpbuf) < sizeof(pAd->MC_FileName))
-				{
-					// backup card information
-					pAd->MC_RowID = card_match_id; /* base 0 */
-					MC_CardUsed[card_match_id] = 1;
-					memcpy(MC_CardMac[card_match_id], mac, sizeof(mac));
-
-					// backup card file path
-					NdisMoveMemory(pAd->MC_FileName, tmpbuf , strlen(tmpbuf));
-					pAd->MC_FileName[strlen(tmpbuf)] = '\0';
-					flg_match_ok = TRUE;
-
-					DBGPRINT(RT_DEBUG_TRACE,
-							("Card Profile Name = %s\n", pAd->MC_FileName));
-				}
-				else
-				{
-					DBGPRINT(RT_DEBUG_ERROR,
-							("Card Profile Name length too large!\n"));
-				}
-			}
-			else
-			{
-				DBGPRINT(RT_DEBUG_ERROR,
-						("Can not find search key word in card.dat!\n"));
-			}
-
-			if ((flg_match_ok != TRUE) &&
-				(card_match_id < MAX_NUM_OF_MULTIPLE_CARD))
-			{
-				MC_CardUsed[card_match_id] = 0;
-				memset(MC_CardMac[card_match_id], 0, sizeof(mac));
-			}
-		} // if (card_match_id >= 0)
-	}
-
-
-	// close file
-	retval = RtmpOSFileClose(srcf);
-
-free_resource:
-	RtmpOSFSInfoChange(&osFSInfo, FALSE);
-	kfree(buffer);
-	kfree(tmpbuf);
-
-	return flg_match_ok;
-}
-#endif // MULTIPLE_CARD_SUPPORT //
diff --git a/drivers/staging/rt3090/common/cmm_sanity.c b/drivers/staging/rt3090/common/cmm_sanity.c
deleted file mode 100644
index de631c3..0000000
--- a/drivers/staging/rt3090/common/cmm_sanity.c
+++ /dev/null
@@ -1,1718 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	sanity.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	John Chang  2004-09-01      add WMM support
-*/
-
-#include "../rt_config.h"
-
-
-extern UCHAR	CISCO_OUI[];
-
-extern UCHAR	WPA_OUI[];
-extern UCHAR	RSN_OUI[];
-extern UCHAR	WME_INFO_ELEM[];
-extern UCHAR	WME_PARM_ELEM[];
-extern UCHAR	Ccx2QosInfo[];
-extern UCHAR	RALINK_OUI[];
-extern UCHAR	BROADCOM_OUI[];
-extern UCHAR    WPS_OUI[];
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-BOOLEAN MlmeAddBAReqSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pAddr2)
-{
-    PMLME_ADDBA_REQ_STRUCT   pInfo;
-
-    pInfo = (MLME_ADDBA_REQ_STRUCT *)Msg;
-
-    if ((MsgLen != sizeof(MLME_ADDBA_REQ_STRUCT)))
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - message lenght not correct.\n"));
-        return FALSE;
-    }
-
-    if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE))
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - The peer Mac is not associated yet.\n"));
-        return FALSE;
-    }
-
-	/*
-    if ((pInfo->BaBufSize > MAX_RX_REORDERBUF) || (pInfo->BaBufSize < 2))
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - Rx Reordering buffer too big or too small\n"));
-        return FALSE;
-    }
-	*/
-
-    if ((pInfo->pAddr[0]&0x01) == 0x01)
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - broadcast address not support BA\n"));
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-BOOLEAN MlmeDelBAReqSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen)
-{
-	MLME_DELBA_REQ_STRUCT *pInfo;
-	pInfo = (MLME_DELBA_REQ_STRUCT *)Msg;
-
-    if ((MsgLen != sizeof(MLME_DELBA_REQ_STRUCT)))
-    {
-        DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - message lenght not correct.\n"));
-        return FALSE;
-    }
-
-    if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE))
-    {
-        DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer Mac is not associated yet.\n"));
-        return FALSE;
-    }
-
-    if ((pInfo->TID & 0xf0))
-    {
-        DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer TID is incorrect.\n"));
-        return FALSE;
-    }
-
-	if (NdisEqualMemory(pAd->MacTab.Content[pInfo->Wcid].Addr, pInfo->Addr, MAC_ADDR_LEN) == 0)
-    {
-        DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - the peer addr dosen't exist.\n"));
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-BOOLEAN PeerAddBAReqActionSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *pMsg,
-    IN ULONG MsgLen,
-	OUT PUCHAR pAddr2)
-{
-	PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
-	PFRAME_ADDBA_REQ pAddFrame;
-	pAddFrame = (PFRAME_ADDBA_REQ)(pMsg);
-	if (MsgLen < (sizeof(FRAME_ADDBA_REQ)))
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request frame length size = %ld incorrect\n", MsgLen));
-		return FALSE;
-	}
-	// we support immediate BA.
-#ifdef UNALIGNMENT_SUPPORT
-	{
-		BA_PARM		tmpBaParm;
-
-		NdisMoveMemory((PUCHAR)(&tmpBaParm), (PUCHAR)(&pAddFrame->BaParm), sizeof(BA_PARM));
-		*(USHORT *)(&tmpBaParm) = cpu2le16(*(USHORT *)(&tmpBaParm));
-		NdisMoveMemory((PUCHAR)(&pAddFrame->BaParm), (PUCHAR)(&tmpBaParm), sizeof(BA_PARM));
-	}
-#else
-	*(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm));
-#endif
-	pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue);
-	pAddFrame->BaStartSeq.word = cpu2le16(pAddFrame->BaStartSeq.word);
-
-	if (pAddFrame->BaParm.BAPolicy != IMMED_BA)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request Ba Policy[%d] not support\n", pAddFrame->BaParm.BAPolicy));
-		DBGPRINT(RT_DEBUG_ERROR,("ADDBA Request. tid=%x, Bufsize=%x, AMSDUSupported=%x \n", pAddFrame->BaParm.TID, pAddFrame->BaParm.BufSize, pAddFrame->BaParm.AMSDUSupported));
-		return FALSE;
-	}
-
-	// we support immediate BA.
-	if (pAddFrame->BaParm.TID &0xfff0)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request incorrect TID = %d\n", pAddFrame->BaParm.TID));
-		return FALSE;
-	}
-	COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
-	return TRUE;
-}
-
-BOOLEAN PeerAddBARspActionSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *pMsg,
-    IN ULONG MsgLen)
-{
-	//PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
-	PFRAME_ADDBA_RSP pAddFrame;
-
-	pAddFrame = (PFRAME_ADDBA_RSP)(pMsg);
-	if (MsgLen < (sizeof(FRAME_ADDBA_RSP)))
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("PeerAddBARspActionSanity: ADDBA Response frame length size = %ld incorrect\n", MsgLen));
-		return FALSE;
-	}
-	// we support immediate BA.
-#ifdef UNALIGNMENT_SUPPORT
-	{
-		BA_PARM		tmpBaParm;
-
-		NdisMoveMemory((PUCHAR)(&tmpBaParm), (PUCHAR)(&pAddFrame->BaParm), sizeof(BA_PARM));
-		*(USHORT *)(&tmpBaParm) = cpu2le16(*(USHORT *)(&tmpBaParm));
-		NdisMoveMemory((PUCHAR)(&pAddFrame->BaParm), (PUCHAR)(&tmpBaParm), sizeof(BA_PARM));
-	}
-#else
-	*(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm));
-#endif
-	pAddFrame->StatusCode = cpu2le16(pAddFrame->StatusCode);
-	pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue);
-
-	if (pAddFrame->BaParm.BAPolicy != IMMED_BA)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Response Ba Policy[%d] not support\n", pAddFrame->BaParm.BAPolicy));
-		return FALSE;
-	}
-
-	// we support immediate BA.
-	if (pAddFrame->BaParm.TID &0xfff0)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("PeerAddBARspActionSanity: ADDBA Response incorrect TID = %d\n", pAddFrame->BaParm.TID));
-		return FALSE;
-	}
-	return TRUE;
-
-}
-
-BOOLEAN PeerDelBAActionSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN UCHAR Wcid,
-    IN VOID *pMsg,
-    IN ULONG MsgLen )
-{
-	//PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
-	PFRAME_DELBA_REQ  pDelFrame;
-	if (MsgLen != (sizeof(FRAME_DELBA_REQ)))
-		return FALSE;
-
-	if (Wcid >= MAX_LEN_OF_MAC_TABLE)
-		return FALSE;
-
-	pDelFrame = (PFRAME_DELBA_REQ)(pMsg);
-
-	*(USHORT *)(&pDelFrame->DelbaParm) = cpu2le16(*(USHORT *)(&pDelFrame->DelbaParm));
-	pDelFrame->ReasonCode = cpu2le16(pDelFrame->ReasonCode);
-
-	if (pDelFrame->DelbaParm.TID &0xfff0)
-		return FALSE;
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-BOOLEAN PeerBeaconAndProbeRspSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    IN UCHAR  MsgChannel,
-    OUT PUCHAR pAddr2,
-    OUT PUCHAR pBssid,
-    OUT CHAR Ssid[],
-    OUT UCHAR *pSsidLen,
-    OUT UCHAR *pBssType,
-    OUT USHORT *pBeaconPeriod,
-    OUT UCHAR *pChannel,
-    OUT UCHAR *pNewChannel,
-    OUT LARGE_INTEGER *pTimestamp,
-    OUT CF_PARM *pCfParm,
-    OUT USHORT *pAtimWin,
-    OUT USHORT *pCapabilityInfo,
-    OUT UCHAR *pErp,
-    OUT UCHAR *pDtimCount,
-    OUT UCHAR *pDtimPeriod,
-    OUT UCHAR *pBcastFlag,
-    OUT UCHAR *pMessageToMe,
-    OUT UCHAR SupRate[],
-    OUT UCHAR *pSupRateLen,
-    OUT UCHAR ExtRate[],
-    OUT UCHAR *pExtRateLen,
-    OUT	UCHAR *pCkipFlag,
-    OUT	UCHAR *pAironetCellPowerLimit,
-    OUT PEDCA_PARM       pEdcaParm,
-    OUT PQBSS_LOAD_PARM  pQbssLoad,
-    OUT PQOS_CAPABILITY_PARM pQosCapability,
-    OUT ULONG *pRalinkIe,
-    OUT UCHAR		 *pHtCapabilityLen,
-#ifdef CONFIG_STA_SUPPORT
-    OUT UCHAR		 *pPreNHtCapabilityLen,
-#endif // CONFIG_STA_SUPPORT //
-    OUT HT_CAPABILITY_IE *pHtCapability,
-	OUT UCHAR		 *AddHtInfoLen,
-	OUT ADD_HT_INFO_IE *AddHtInfo,
-	OUT UCHAR *NewExtChannelOffset,		// Ht extension channel offset(above or below)
-    OUT USHORT *LengthVIE,
-    OUT	PNDIS_802_11_VARIABLE_IEs pVIE)
-{
-    UCHAR				*Ptr;
-#ifdef CONFIG_STA_SUPPORT
-	UCHAR				TimLen;
-#endif // CONFIG_STA_SUPPORT //
-    PFRAME_802_11		pFrame;
-    PEID_STRUCT         pEid;
-    UCHAR				SubType;
-    UCHAR				Sanity;
-    //UCHAR				ECWMin, ECWMax;
-    //MAC_CSR9_STRUC		Csr9;
-    ULONG				Length = 0;
-
-	// For some 11a AP which didn't have DS_IE, we use two conditions to decide the channel
-	//	1. If the AP is 11n enabled, then check the control channel.
-	//	2. If the AP didn't have any info about channel, use the channel we received this frame as the channel. (May inaccuracy!!)
-	UCHAR			CtrlChannel = 0;
-
-    // Add for 3 necessary EID field check
-    Sanity = 0;
-
-    *pAtimWin = 0;
-    *pErp = 0;
-    *pDtimCount = 0;
-    *pDtimPeriod = 0;
-    *pBcastFlag = 0;
-    *pMessageToMe = 0;
-    *pExtRateLen = 0;
-    *pCkipFlag = 0;			        // Default of CkipFlag is 0
-    *pAironetCellPowerLimit = 0xFF;  // Default of AironetCellPowerLimit is 0xFF
-    *LengthVIE = 0;					// Set the length of VIE to init value 0
-    *pHtCapabilityLen = 0;					// Set the length of VIE to init value 0
-#ifdef CONFIG_STA_SUPPORT
-	if (pAd->OpMode == OPMODE_STA)
-		*pPreNHtCapabilityLen = 0;					// Set the length of VIE to init value 0
-#endif // CONFIG_STA_SUPPORT //
-    *AddHtInfoLen = 0;					// Set the length of VIE to init value 0
-    *pRalinkIe = 0;
-    *pNewChannel = 0;
-    *NewExtChannelOffset = 0xff;	//Default 0xff means no such IE
-    pCfParm->bValid = FALSE;        // default: no IE_CF found
-    pQbssLoad->bValid = FALSE;      // default: no IE_QBSS_LOAD found
-    pEdcaParm->bValid = FALSE;      // default: no IE_EDCA_PARAMETER found
-    pQosCapability->bValid = FALSE; // default: no IE_QOS_CAPABILITY found
-
-    pFrame = (PFRAME_802_11)Msg;
-
-    // get subtype from header
-    SubType = (UCHAR)pFrame->Hdr.FC.SubType;
-
-    // get Addr2 and BSSID from header
-    COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
-    COPY_MAC_ADDR(pBssid, pFrame->Hdr.Addr3);
-
-//	hex_dump("Beacon", Msg, MsgLen);
-
-    Ptr = pFrame->Octet;
-    Length += LENGTH_802_11;
-
-    // get timestamp from payload and advance the pointer
-    NdisMoveMemory(pTimestamp, Ptr, TIMESTAMP_LEN);
-
-	pTimestamp->u.LowPart = cpu2le32(pTimestamp->u.LowPart);
-	pTimestamp->u.HighPart = cpu2le32(pTimestamp->u.HighPart);
-
-    Ptr += TIMESTAMP_LEN;
-    Length += TIMESTAMP_LEN;
-
-    // get beacon interval from payload and advance the pointer
-    NdisMoveMemory(pBeaconPeriod, Ptr, 2);
-    Ptr += 2;
-    Length += 2;
-
-    // get capability info from payload and advance the pointer
-    NdisMoveMemory(pCapabilityInfo, Ptr, 2);
-    Ptr += 2;
-    Length += 2;
-
-    if (CAP_IS_ESS_ON(*pCapabilityInfo))
-        *pBssType = BSS_INFRA;
-    else
-        *pBssType = BSS_ADHOC;
-
-    pEid = (PEID_STRUCT) Ptr;
-
-    // get variable fields from payload and advance the pointer
-    while ((Length + 2 + pEid->Len) <= MsgLen)
-    {
-        //
-        // Secure copy VIE to VarIE[MAX_VIE_LEN] didn't overflow.
-        //
-        if ((*LengthVIE + pEid->Len + 2) >= MAX_VIE_LEN)
-        {
-            DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - Variable IEs out of resource [len(=%d) > MAX_VIE_LEN(=%d)]\n",
-                    (*LengthVIE + pEid->Len + 2), MAX_VIE_LEN));
-            break;
-        }
-
-        switch(pEid->Eid)
-        {
-            case IE_SSID:
-                // Already has one SSID EID in this beacon, ignore the second one
-                if (Sanity & 0x1)
-                    break;
-                if(pEid->Len <= MAX_LEN_OF_SSID)
-                {
-                    NdisMoveMemory(Ssid, pEid->Octet, pEid->Len);
-                    *pSsidLen = pEid->Len;
-                    Sanity |= 0x1;
-                }
-                else
-                {
-                    DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",pEid->Len));
-                    return FALSE;
-                }
-                break;
-
-            case IE_SUPP_RATES:
-                if(pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
-                {
-                    Sanity |= 0x2;
-                    NdisMoveMemory(SupRate, pEid->Octet, pEid->Len);
-                    *pSupRateLen = pEid->Len;
-
-                    // TODO: 2004-09-14 not a good design here, cause it exclude extra rates
-                    // from ScanTab. We should report as is. And filter out unsupported
-                    // rates in MlmeAux.
-                    // Check against the supported rates
-                    // RTMPCheckRates(pAd, SupRate, pSupRateLen);
-                }
-                else
-                {
-                    DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SUPP_RATES (len=%d)\n",pEid->Len));
-                    return FALSE;
-                }
-                break;
-
-            case IE_HT_CAP:
-			if (pEid->Len >= SIZE_HT_CAP_IE)  //Note: allow extension.!!
-			{
-				NdisMoveMemory(pHtCapability, pEid->Octet, sizeof(HT_CAPABILITY_IE));
-				*pHtCapabilityLen = SIZE_HT_CAP_IE;	// Nnow we only support 26 bytes.
-
-				*(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
-#ifdef UNALIGNMENT_SUPPORT
-				{
-					EXT_HT_CAP_INFO extHtCapInfo;
-					NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&pHtCapability->ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO));
-					*(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo));
-					NdisMoveMemory((PUCHAR)(&pHtCapability->ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO));
-				}
-#else
-				*(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
-#endif // UNALIGNMENT_SUPPORT //
-
-#ifdef CONFIG_STA_SUPPORT
-				IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-				{
-					*pPreNHtCapabilityLen = 0;	// Now we only support 26 bytes.
-
-					Ptr = (PUCHAR) pVIE;
-					NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
-					*LengthVIE += (pEid->Len + 2);
-				}
-#endif // CONFIG_STA_SUPPORT //
-			}
-			else
-			{
-				DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_HT_CAP. pEid->Len = %d\n", pEid->Len));
-			}
-
-		break;
-            case IE_ADD_HT:
-			if (pEid->Len >= sizeof(ADD_HT_INFO_IE))
-			{
-				// This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only
-				// copy first sizeof(ADD_HT_INFO_IE)
-				NdisMoveMemory(AddHtInfo, pEid->Octet, sizeof(ADD_HT_INFO_IE));
-				*AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
-
-				CtrlChannel = AddHtInfo->ControlChan;
-
-				*(USHORT *)(&AddHtInfo->AddHtInfo2) = cpu2le16(*(USHORT *)(&AddHtInfo->AddHtInfo2));
-				*(USHORT *)(&AddHtInfo->AddHtInfo3) = cpu2le16(*(USHORT *)(&AddHtInfo->AddHtInfo3));
-
-#ifdef CONFIG_STA_SUPPORT
-				IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-				{
-			                Ptr = (PUCHAR) pVIE;
-			                NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
-			                *LengthVIE += (pEid->Len + 2);
-				}
-#endif // CONFIG_STA_SUPPORT //
-			}
-			else
-			{
-				DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_ADD_HT. \n"));
-			}
-
-		break;
-            case IE_SECONDARY_CH_OFFSET:
-			if (pEid->Len == 1)
-			{
-				*NewExtChannelOffset = pEid->Octet[0];
-			}
-			else
-			{
-				DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
-			}
-
-		break;
-            case IE_FH_PARM:
-                DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity(IE_FH_PARM) \n"));
-                break;
-
-            case IE_DS_PARM:
-                if(pEid->Len == 1)
-                {
-                    *pChannel = *pEid->Octet;
-#ifdef CONFIG_STA_SUPPORT
-					IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-					{
-						if (ChannelSanity(pAd, *pChannel) == 0)
-						{
-
-							return FALSE;
-						}
-					}
-#endif // CONFIG_STA_SUPPORT //
-                    Sanity |= 0x4;
-                }
-                else
-                {
-                    DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_DS_PARM (len=%d)\n",pEid->Len));
-                    return FALSE;
-                }
-                break;
-
-            case IE_CF_PARM:
-                if(pEid->Len == 6)
-                {
-                    pCfParm->bValid = TRUE;
-                    pCfParm->CfpCount = pEid->Octet[0];
-                    pCfParm->CfpPeriod = pEid->Octet[1];
-                    pCfParm->CfpMaxDuration = pEid->Octet[2] + 256 * pEid->Octet[3];
-                    pCfParm->CfpDurRemaining = pEid->Octet[4] + 256 * pEid->Octet[5];
-                }
-                else
-                {
-                    DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_CF_PARM\n"));
-                    return FALSE;
-                }
-                break;
-
-            case IE_IBSS_PARM:
-                if(pEid->Len == 2)
-                {
-                    NdisMoveMemory(pAtimWin, pEid->Octet, pEid->Len);
-                }
-                else
-                {
-                    DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_IBSS_PARM\n"));
-                    return FALSE;
-                }
-                break;
-
-#ifdef CONFIG_STA_SUPPORT
-            case IE_TIM:
-                if(INFRA_ON(pAd) && SubType == SUBTYPE_BEACON)
-                {
-                    GetTimBit((PCHAR)pEid, pAd->StaActive.Aid, &TimLen, pBcastFlag, pDtimCount, pDtimPeriod, pMessageToMe);
-                }
-                break;
-#endif // CONFIG_STA_SUPPORT //
-            case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
-                if(pEid->Len == 3)
-                {
-			*pNewChannel = pEid->Octet[1];	//extract new channel number
-                }
-                break;
-
-            // New for WPA
-            // CCX v2 has the same IE, we need to parse that too
-            // Wifi WMM use the same IE vale, need to parse that too
-            // case IE_WPA:
-            case IE_VENDOR_SPECIFIC:
-                // Check Broadcom/Atheros 802.11n OUI version, for HT Capability IE.
-                // This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan.
-                /*if (NdisEqualMemory(pEid->Octet, BROADCOM_OUI, 3) && (pEid->Len >= 4))
-                {
-			if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 30))
-			{
-				{
-					NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(HT_CAPABILITY_IE));
-					*pHtCapabilityLen = SIZE_HT_CAP_IE;	// Nnow we only support 26 bytes.
-				}
-			}
-			if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 26))
-			{
-				{
-					NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(ADD_HT_INFO_IE));
-					*AddHtInfoLen = SIZE_ADD_HT_INFO_IE;	// Nnow we only support 26 bytes.
-				}
-			}
-                }
-				*/
-                // Check the OUI version, filter out non-standard usage
-                if (NdisEqualMemory(pEid->Octet, RALINK_OUI, 3) && (pEid->Len == 7))
-                {
-                    //*pRalinkIe = pEid->Octet[3];
-                    if (pEid->Octet[3] != 0)
-					*pRalinkIe = pEid->Octet[3];
-				else
-					*pRalinkIe = 0xf0000000; // Set to non-zero value (can't set bit0-2) to represent this is Ralink Chip. So at linkup, we will set ralinkchip flag.
-                }
-#ifdef CONFIG_STA_SUPPORT
-#ifdef DOT11_N_SUPPORT
-		// This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan.
-
-                // Other vendors had production before IE_HT_CAP value is assigned. To backward support those old-firmware AP,
-                // Check broadcom-defiend pre-802.11nD1.0 OUI for HT related IE, including HT Capatilities IE and HT Information IE
-                else if ((*pHtCapabilityLen == 0) && NdisEqualMemory(pEid->Octet, PRE_N_HT_OUI, 3) && (pEid->Len >= 4) && (pAd->OpMode == OPMODE_STA))
-                {
-                    if ((pEid->Octet[3] == OUI_PREN_HT_CAP) && (pEid->Len >= 30) && (*pHtCapabilityLen == 0))
-                    {
-                        NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(HT_CAPABILITY_IE));
-                        *pPreNHtCapabilityLen = SIZE_HT_CAP_IE;
-                    }
-
-                    if ((pEid->Octet[3] == OUI_PREN_ADD_HT) && (pEid->Len >= 26))
-                    {
-                        NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(ADD_HT_INFO_IE));
-                        *AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
-                    }
-                }
-#endif // DOT11_N_SUPPORT //
-#endif // CONFIG_STA_SUPPORT //
-                else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
-                {
-                    // Copy to pVIE which will report to microsoft bssid list.
-                    Ptr = (PUCHAR) pVIE;
-                    NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
-                    *LengthVIE += (pEid->Len + 2);
-                }
-                else if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) && (pEid->Len == 24))
-                {
-                    PUCHAR ptr;
-                    int i;
-
-                    // parsing EDCA parameters
-                    pEdcaParm->bValid          = TRUE;
-                    pEdcaParm->bQAck           = FALSE; // pEid->Octet[0] & 0x10;
-                    pEdcaParm->bQueueRequest   = FALSE; // pEid->Octet[0] & 0x20;
-                    pEdcaParm->bTxopRequest    = FALSE; // pEid->Octet[0] & 0x40;
-                    pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
-                    pEdcaParm->bAPSDCapable    = (pEid->Octet[6] & 0x80) ? 1 : 0;
-                    ptr = &pEid->Octet[8];
-                    for (i=0; i<4; i++)
-                    {
-                        UCHAR aci = (*ptr & 0x60) >> 5; // b5~6 is AC INDEX
-                        pEdcaParm->bACM[aci]  = (((*ptr) & 0x10) == 0x10);   // b5 is ACM
-                        pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f;               // b0~3 is AIFSN
-                        pEdcaParm->Cwmin[aci] = *(ptr+1) & 0x0f;             // b0~4 is Cwmin
-                        pEdcaParm->Cwmax[aci] = *(ptr+1) >> 4;               // b5~8 is Cwmax
-                        pEdcaParm->Txop[aci]  = *(ptr+2) + 256 * (*(ptr+3)); // in unit of 32-us
-                        ptr += 4; // point to next AC
-                    }
-                }
-                else if (NdisEqualMemory(pEid->Octet, WME_INFO_ELEM, 6) && (pEid->Len == 7))
-                {
-                    // parsing EDCA parameters
-                    pEdcaParm->bValid          = TRUE;
-                    pEdcaParm->bQAck           = FALSE; // pEid->Octet[0] & 0x10;
-                    pEdcaParm->bQueueRequest   = FALSE; // pEid->Octet[0] & 0x20;
-                    pEdcaParm->bTxopRequest    = FALSE; // pEid->Octet[0] & 0x40;
-                    pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
-                    pEdcaParm->bAPSDCapable    = (pEid->Octet[6] & 0x80) ? 1 : 0;
-
-                    // use default EDCA parameter
-                    pEdcaParm->bACM[QID_AC_BE]  = 0;
-                    pEdcaParm->Aifsn[QID_AC_BE] = 3;
-                    pEdcaParm->Cwmin[QID_AC_BE] = CW_MIN_IN_BITS;
-                    pEdcaParm->Cwmax[QID_AC_BE] = CW_MAX_IN_BITS;
-                    pEdcaParm->Txop[QID_AC_BE]  = 0;
-
-                    pEdcaParm->bACM[QID_AC_BK]  = 0;
-                    pEdcaParm->Aifsn[QID_AC_BK] = 7;
-                    pEdcaParm->Cwmin[QID_AC_BK] = CW_MIN_IN_BITS;
-                    pEdcaParm->Cwmax[QID_AC_BK] = CW_MAX_IN_BITS;
-                    pEdcaParm->Txop[QID_AC_BK]  = 0;
-
-                    pEdcaParm->bACM[QID_AC_VI]  = 0;
-                    pEdcaParm->Aifsn[QID_AC_VI] = 2;
-                    pEdcaParm->Cwmin[QID_AC_VI] = CW_MIN_IN_BITS-1;
-                    pEdcaParm->Cwmax[QID_AC_VI] = CW_MAX_IN_BITS;
-                    pEdcaParm->Txop[QID_AC_VI]  = 96;   // AC_VI: 96*32us ~= 3ms
-
-                    pEdcaParm->bACM[QID_AC_VO]  = 0;
-                    pEdcaParm->Aifsn[QID_AC_VO] = 2;
-                    pEdcaParm->Cwmin[QID_AC_VO] = CW_MIN_IN_BITS-2;
-                    pEdcaParm->Cwmax[QID_AC_VO] = CW_MAX_IN_BITS-1;
-                    pEdcaParm->Txop[QID_AC_VO]  = 48;   // AC_VO: 48*32us ~= 1.5ms
-                }
-#ifdef CONFIG_STA_SUPPORT
-#endif // CONFIG_STA_SUPPORT //
-
-
-                break;
-
-            case IE_EXT_SUPP_RATES:
-                if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
-                {
-                    NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
-                    *pExtRateLen = pEid->Len;
-
-                    // TODO: 2004-09-14 not a good design here, cause it exclude extra rates
-                    // from ScanTab. We should report as is. And filter out unsupported
-                    // rates in MlmeAux.
-                    // Check against the supported rates
-                    // RTMPCheckRates(pAd, ExtRate, pExtRateLen);
-                }
-                break;
-
-            case IE_ERP:
-                if (pEid->Len == 1)
-                {
-                    *pErp = (UCHAR)pEid->Octet[0];
-                }
-                break;
-
-            case IE_AIRONET_CKIP:
-                // 0. Check Aironet IE length, it must be larger or equal to 28
-                // Cisco AP350 used length as 28
-                // Cisco AP12XX used length as 30
-                if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2))
-                    break;
-
-                // 1. Copy CKIP flag byte to buffer for process
-                *pCkipFlag = *(pEid->Octet + 8);
-                break;
-
-            case IE_AP_TX_POWER:
-                // AP Control of Client Transmit Power
-                //0. Check Aironet IE length, it must be 6
-                if (pEid->Len != 0x06)
-                    break;
-
-                // Get cell power limit in dBm
-                if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1)
-                    *pAironetCellPowerLimit = *(pEid->Octet + 4);
-                break;
-
-            // WPA2 & 802.11i RSN
-            case IE_RSN:
-                // There is no OUI for version anymore, check the group cipher OUI before copying
-                if (RTMPEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
-                {
-                    // Copy to pVIE which will report to microsoft bssid list.
-                    Ptr = (PUCHAR) pVIE;
-                    NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
-                    *LengthVIE += (pEid->Len + 2);
-                }
-                break;
-#ifdef CONFIG_STA_SUPPORT
-#ifdef EXT_BUILD_CHANNEL_LIST
-			case IE_COUNTRY:
-				Ptr = (PUCHAR) pVIE;
-                NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
-                *LengthVIE += (pEid->Len + 2);
-				break;
-#endif // EXT_BUILD_CHANNEL_LIST //
-#endif // CONFIG_STA_SUPPORT //
-
-
-            default:
-                break;
-        }
-
-        Length = Length + 2 + pEid->Len;  // Eid[1] + Len[1]+ content[Len]
-        pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
-    }
-
-    // For some 11a AP. it did not have the channel EID, patch here
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		UCHAR LatchRfChannel = MsgChannel;
-		if ((pAd->LatchRfRegs.Channel > 14) && ((Sanity & 0x4) == 0))
-		{
-			if (CtrlChannel != 0)
-				*pChannel = CtrlChannel;
-			else
-				*pChannel = LatchRfChannel;
-			Sanity |= 0x4;
-		}
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	if (Sanity != 0x7)
-	{
-		DBGPRINT(RT_DEBUG_LOUD, ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", Sanity));
-		return FALSE;
-	}
-	else
-	{
-		return TRUE;
-	}
-
-}
-
-#ifdef DOT11N_DRAFT3
-/*
-	==========================================================================
-	Description:
-		MLME message sanity check for some IE addressed  in 802.11n d3.03.
-	Return:
-		TRUE if all parameters are OK, FALSE otherwise
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-BOOLEAN PeerBeaconAndProbeRspSanity2(
-	IN PRTMP_ADAPTER pAd,
-	IN VOID *Msg,
-	IN ULONG MsgLen,
-	OUT UCHAR	*RegClass)
-{
-	CHAR				*Ptr;
-	PFRAME_802_11		pFrame;
-	PEID_STRUCT			pEid;
-	ULONG				Length = 0;
-
-	pFrame = (PFRAME_802_11)Msg;
-
-	*RegClass = 0;
-	Ptr = (PCHAR) pFrame->Octet;
-	Length += LENGTH_802_11;
-
-	// get timestamp from payload and advance the pointer
-	Ptr += TIMESTAMP_LEN;
-	Length += TIMESTAMP_LEN;
-
-	// get beacon interval from payload and advance the pointer
-	Ptr += 2;
-	Length += 2;
-
-	// get capability info from payload and advance the pointer
-	Ptr += 2;
-	Length += 2;
-
-	pEid = (PEID_STRUCT) Ptr;
-
-	// get variable fields from payload and advance the pointer
-	while ((Length + 2 + pEid->Len) <= MsgLen)
-	{
-		switch(pEid->Eid)
-		{
-			case IE_SUPP_REG_CLASS:
-				if(pEid->Len > 0)
-				{
-					*RegClass = *pEid->Octet;
-				}
-				else
-				{
-					DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",pEid->Len));
-					return FALSE;
-				}
-				break;
-		}
-
-		Length = Length + 2 + pEid->Len;  // Eid[1] + Len[1]+ content[Len]
-		pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
-	}
-
-	return TRUE;
-
-}
-#endif // DOT11N_DRAFT3 //
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
- */
-BOOLEAN MlmeScanReqSanity(
-	IN PRTMP_ADAPTER pAd,
-	IN VOID *Msg,
-	IN ULONG MsgLen,
-	OUT UCHAR *pBssType,
-	OUT CHAR Ssid[],
-	OUT UCHAR *pSsidLen,
-	OUT UCHAR *pScanType)
-{
-	MLME_SCAN_REQ_STRUCT *Info;
-
-	Info = (MLME_SCAN_REQ_STRUCT *)(Msg);
-	*pBssType = Info->BssType;
-	*pSsidLen = Info->SsidLen;
-	NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen);
-	*pScanType = Info->ScanType;
-
-	if ((*pBssType == BSS_INFRA || *pBssType == BSS_ADHOC || *pBssType == BSS_ANY)
-		&& (*pScanType == SCAN_ACTIVE || *pScanType == SCAN_PASSIVE
-#ifdef CONFIG_STA_SUPPORT
-#endif // CONFIG_STA_SUPPORT //
-		))
-	{
-		return TRUE;
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqSanity fail - wrong BssType or ScanType\n"));
-		return FALSE;
-	}
-}
-
-// IRQL = DISPATCH_LEVEL
-UCHAR ChannelSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN UCHAR channel)
-{
-    int i;
-
-    for (i = 0; i < pAd->ChannelListNum; i ++)
-    {
-        if (channel == pAd->ChannelList[i].Channel)
-            return 1;
-    }
-    return 0;
-}
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-BOOLEAN PeerDeauthSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pAddr2,
-    OUT USHORT *pReason)
-{
-    PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
-
-    COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
-    NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
-
-    return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-BOOLEAN PeerAuthSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pAddr,
-    OUT USHORT *pAlg,
-    OUT USHORT *pSeq,
-    OUT USHORT *pStatus,
-    CHAR *pChlgText)
-{
-    PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
-
-    COPY_MAC_ADDR(pAddr,   pFrame->Hdr.Addr2);
-    NdisMoveMemory(pAlg,    &pFrame->Octet[0], 2);
-    NdisMoveMemory(pSeq,    &pFrame->Octet[2], 2);
-    NdisMoveMemory(pStatus, &pFrame->Octet[4], 2);
-
-    if (*pAlg == AUTH_MODE_OPEN)
-    {
-        if (*pSeq == 1 || *pSeq == 2)
-        {
-            return TRUE;
-        }
-        else
-        {
-            DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n"));
-            return FALSE;
-        }
-    }
-    else if (*pAlg == AUTH_MODE_KEY)
-    {
-        if (*pSeq == 1 || *pSeq == 4)
-        {
-            return TRUE;
-        }
-        else if (*pSeq == 2 || *pSeq == 3)
-        {
-            NdisMoveMemory(pChlgText, &pFrame->Octet[8], CIPHER_TEXT_LEN);
-            return TRUE;
-        }
-        else
-        {
-            DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n"));
-            return FALSE;
-        }
-    }
-    else
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong algorithm\n"));
-        return FALSE;
-    }
-}
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
- */
-BOOLEAN MlmeAuthReqSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pAddr,
-    OUT ULONG *pTimeout,
-    OUT USHORT *pAlg)
-{
-    MLME_AUTH_REQ_STRUCT *pInfo;
-
-    pInfo  = (MLME_AUTH_REQ_STRUCT *)Msg;
-    COPY_MAC_ADDR(pAddr, pInfo->Addr);
-    *pTimeout = pInfo->Timeout;
-    *pAlg = pInfo->Alg;
-
-    if (((*pAlg == AUTH_MODE_KEY) ||(*pAlg == AUTH_MODE_OPEN)
-	) &&
-        ((*pAddr & 0x01) == 0))
-    {
-        return TRUE;
-    }
-    else
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("MlmeAuthReqSanity fail - wrong algorithm\n"));
-        return FALSE;
-    }
-}
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-BOOLEAN MlmeAssocReqSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pApAddr,
-    OUT USHORT *pCapabilityInfo,
-    OUT ULONG *pTimeout,
-    OUT USHORT *pListenIntv)
-{
-    MLME_ASSOC_REQ_STRUCT *pInfo;
-
-    pInfo = (MLME_ASSOC_REQ_STRUCT *)Msg;
-    *pTimeout = pInfo->Timeout;                             // timeout
-    COPY_MAC_ADDR(pApAddr, pInfo->Addr);                   // AP address
-    *pCapabilityInfo = pInfo->CapabilityInfo;               // capability info
-    *pListenIntv = pInfo->ListenIntv;
-
-    return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-BOOLEAN PeerDisassocSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pAddr2,
-    OUT USHORT *pReason)
-{
-    PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
-
-    COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
-    NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
-
-    return TRUE;
-}
-
-/*
-	========================================================================
-	Routine Description:
-		Sanity check NetworkType (11b, 11g or 11a)
-
-	Arguments:
-		pBss - Pointer to BSS table.
-
-	Return Value:
-        Ndis802_11DS .......(11b)
-        Ndis802_11OFDM24....(11g)
-        Ndis802_11OFDM5.....(11a)
-
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(
-    IN PBSS_ENTRY pBss)
-{
-	NDIS_802_11_NETWORK_TYPE	NetWorkType;
-	UCHAR						rate, i;
-
-	NetWorkType = Ndis802_11DS;
-
-	if (pBss->Channel <= 14)
-	{
-		//
-		// First check support Rate.
-		//
-		for (i = 0; i < pBss->SupRateLen; i++)
-		{
-			rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit
-			if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22))
-			{
-				continue;
-			}
-			else
-			{
-				//
-				// Otherwise (even rate > 108) means Ndis802_11OFDM24
-				//
-				NetWorkType = Ndis802_11OFDM24;
-				break;
-			}
-		}
-
-		//
-		// Second check Extend Rate.
-		//
-		if (NetWorkType != Ndis802_11OFDM24)
-		{
-			for (i = 0; i < pBss->ExtRateLen; i++)
-			{
-				rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit
-				if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22))
-				{
-					continue;
-				}
-				else
-				{
-					//
-					// Otherwise (even rate > 108) means Ndis802_11OFDM24
-					//
-					NetWorkType = Ndis802_11OFDM24;
-					break;
-				}
-			}
-		}
-	}
-	else
-	{
-		NetWorkType = Ndis802_11OFDM5;
-	}
-
-    if (pBss->HtCapabilityLen != 0)
-    {
-        if (NetWorkType == Ndis802_11OFDM5)
-            NetWorkType = Ndis802_11OFDM5_N;
-        else
-            NetWorkType = Ndis802_11OFDM24_N;
-    }
-
-	return NetWorkType;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Check the validity of the received EAPoL frame
-    Return:
-        TRUE if all parameters are OK,
-        FALSE otherwise
-    ==========================================================================
- */
-BOOLEAN PeerWpaMessageSanity(
-    IN	PRTMP_ADAPTER		pAd,
-    IN	PEAPOL_PACKET		pMsg,
-    IN	ULONG				MsgLen,
-    IN	UCHAR				MsgType,
-    IN	MAC_TABLE_ENTRY		*pEntry)
-{
-	UCHAR			mic[LEN_KEY_DESC_MIC], digest[80], KEYDATA[MAX_LEN_OF_RSNIE];
-	BOOLEAN			bReplayDiff = FALSE;
-	BOOLEAN			bWPA2 = FALSE;
-	KEY_INFO		EapolKeyInfo;
-	UCHAR			GroupKeyIndex = 0;
-
-
-	NdisZeroMemory(mic, sizeof(mic));
-	NdisZeroMemory(digest, sizeof(digest));
-	NdisZeroMemory(KEYDATA, sizeof(KEYDATA));
-	NdisZeroMemory((PUCHAR)&EapolKeyInfo, sizeof(EapolKeyInfo));
-
-	NdisMoveMemory((PUCHAR)&EapolKeyInfo, (PUCHAR)&pMsg->KeyDesc.KeyInfo, sizeof(KEY_INFO));
-
-	*((USHORT *)&EapolKeyInfo) = cpu2le16(*((USHORT *)&EapolKeyInfo));
-
-	// Choose WPA2 or not
-	if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
-		bWPA2 = TRUE;
-
-	// 0. Check MsgType
-	if ((MsgType > EAPOL_GROUP_MSG_2) || (MsgType < EAPOL_PAIR_MSG_1))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("The message type is invalid(%d)! \n", MsgType));
-		return FALSE;
-	}
-
-	// 1. Replay counter check
-	if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1)	// For supplicant
-    {
-	// First validate replay counter, only accept message with larger replay counter.
-		// Let equal pass, some AP start with all zero replay counter
-		UCHAR	ZeroReplay[LEN_KEY_DESC_REPLAY];
-
-        NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
-		if ((RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY) != 1) &&
-			(RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
-	{
-			bReplayDiff = TRUE;
-	}
-	}
-	else if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2)	// For authenticator
-	{
-		// check Replay Counter coresponds to MSG from authenticator, otherwise discard
-	if (!NdisEqualMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY))
-	{
-			bReplayDiff = TRUE;
-	}
-	}
-
-	// Replay Counter different condition
-	if (bReplayDiff)
-	{
-		// send wireless event - for replay counter different
-		if (pAd->CommonCfg.bWirelessEvent)
-			RTMPSendWirelessEvent(pAd, IW_REPLAY_COUNTER_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
-
-		if (MsgType < EAPOL_GROUP_MSG_1)
-		{
-		DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in pairwise msg %d of 4-way handshake!\n", MsgType));
-		}
-		else
-		{
-			DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4)));
-		}
-
-		hex_dump("Receive replay counter ", pMsg->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
-		hex_dump("Current replay counter ", pEntry->R_Counter, LEN_KEY_DESC_REPLAY);
-        return FALSE;
-	}
-
-	// 2. Verify MIC except Pairwise Msg1
-	if (MsgType != EAPOL_PAIR_MSG_1)
-	{
-		UCHAR			rcvd_mic[LEN_KEY_DESC_MIC];
-
-		// Record the received MIC for check later
-		NdisMoveMemory(rcvd_mic, pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
-		NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
-
-        if (EapolKeyInfo.KeyDescVer == DESC_TYPE_TKIP)	// TKIP
-        {
-            HMAC_MD5(pEntry->PTK, LEN_EAP_MICK, (PUCHAR)pMsg, MsgLen, mic, MD5_DIGEST_SIZE);
-        }
-        else if (EapolKeyInfo.KeyDescVer == DESC_TYPE_AES)	// AES
-        {
-            HMAC_SHA1(pEntry->PTK, LEN_EAP_MICK, (PUCHAR)pMsg, MsgLen, digest, SHA1_DIGEST_SIZE);
-            NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
-        }
-
-        if (!NdisEqualMemory(rcvd_mic, mic, LEN_KEY_DESC_MIC))
-        {
-			// send wireless event - for MIC different
-			if (pAd->CommonCfg.bWirelessEvent)
-				RTMPSendWirelessEvent(pAd, IW_MIC_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
-
-			if (MsgType < EAPOL_GROUP_MSG_1)
-			{
-		DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in pairwise msg %d of 4-way handshake!\n", MsgType));
-			}
-			else
-			{
-				DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4)));
-			}
-
-			hex_dump("Received MIC", rcvd_mic, LEN_KEY_DESC_MIC);
-			hex_dump("Desired  MIC", mic, LEN_KEY_DESC_MIC);
-
-			return FALSE;
-        }
-	}
-
-	// 1. Decrypt the Key Data field if GTK is included.
-	// 2. Extract the context of the Key Data field if it exist.
-	// The field in pairwise_msg_2_WPA1(WPA2) & pairwise_msg_3_WPA1 is clear.
-	// The field in group_msg_1_WPA1(WPA2) & pairwise_msg_3_WPA2 is encrypted.
-	if (CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen) > 0)
-	{
-		// Decrypt this field
-		if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1))
-		{
-			if(
-				(EapolKeyInfo.KeyDescVer == DESC_TYPE_AES))
-			{
-				// AES
-				AES_GTK_KEY_UNWRAP(&pEntry->PTK[16], KEYDATA,
-									CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen),
-									pMsg->KeyDesc.KeyData);
-			}
-			else
-			{
-				INT	i;
-				UCHAR   Key[32];
-				// Decrypt TKIP GTK
-				// Construct 32 bytes RC4 Key
-				NdisMoveMemory(Key, pMsg->KeyDesc.KeyIv, 16);
-				NdisMoveMemory(&Key[16], &pEntry->PTK[16], 16);
-				ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
-				//discard first 256 bytes
-				for(i = 0; i < 256; i++)
-					ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
-				// Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
-				ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA,
-								pMsg->KeyDesc.KeyData,
-								CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen));
-			}
-
-			if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))
-				GroupKeyIndex = EapolKeyInfo.KeyIndex;
-
-		}
-		else if ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3 && !bWPA2))
-		{
-			NdisMoveMemory(KEYDATA, pMsg->KeyDesc.KeyData, CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen));
-		}
-		else
-		{
-
-			return TRUE;
-		}
-
-		// Parse Key Data field to
-		// 1. verify RSN IE for pairwise_msg_2_WPA1(WPA2) ,pairwise_msg_3_WPA1(WPA2)
-		// 2. verify KDE format for pairwise_msg_3_WPA2, group_msg_1_WPA2
-		// 3. update shared key for pairwise_msg_3_WPA2, group_msg_1_WPA1(WPA2)
-		if (!RTMPParseEapolKeyData(pAd, KEYDATA,
-								  CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen),
-								  GroupKeyIndex, MsgType, bWPA2, pEntry))
-		{
-			return FALSE;
-		}
-	}
-
-	return TRUE;
-
-}
-
-#ifdef CONFIG_STA_SUPPORT
-#ifdef QOS_DLS_SUPPORT
-BOOLEAN MlmeDlsReqSanity(
-	IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PRT_802_11_DLS *pDLS,
-    OUT PUSHORT pReason)
-{
-	MLME_DLS_REQ_STRUCT *pInfo;
-
-    pInfo = (MLME_DLS_REQ_STRUCT *)Msg;
-
-	*pDLS = pInfo->pDLS;
-	*pReason = pInfo->Reason;
-
-	return TRUE;
-}
-#endif // QOS_DLS_SUPPORT //
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef QOS_DLS_SUPPORT
-BOOLEAN PeerDlsReqSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pDA,
-    OUT PUCHAR pSA,
-    OUT USHORT *pCapabilityInfo,
-    OUT USHORT *pDlsTimeout,
-    OUT UCHAR *pRatesLen,
-    OUT UCHAR Rates[],
-	OUT UCHAR *pHtCapabilityLen,
-    OUT HT_CAPABILITY_IE *pHtCapability)
-{
-	CHAR            *Ptr;
-    PFRAME_802_11	Fr = (PFRAME_802_11)Msg;
-	PEID_STRUCT  eid_ptr;
-
-    // to prevent caller from using garbage output value
-    *pCapabilityInfo	= 0;
-    *pDlsTimeout	= 0;
-	*pHtCapabilityLen = 0;
-
-    Ptr = (PCHAR)Fr->Octet;
-
-	// offset to destination MAC address (Category and Action field)
-    Ptr += 2;
-
-    // get DA from payload and advance the pointer
-    NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
-    Ptr += MAC_ADDR_LEN;
-
-    // get SA from payload and advance the pointer
-    NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
-    Ptr += MAC_ADDR_LEN;
-
-    // get capability info from payload and advance the pointer
-    NdisMoveMemory(pCapabilityInfo, Ptr, 2);
-    Ptr += 2;
-
-    // get capability info from payload and advance the pointer
-    NdisMoveMemory(pDlsTimeout, Ptr, 2);
-    Ptr += 2;
-
-	// Category and Action field + DA + SA + capability + Timeout
-	eid_ptr = (PEID_STRUCT) &Fr->Octet[18];
-
-	while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((UCHAR*)Fr + MsgLen))
-	{
-		switch(eid_ptr->Eid)
-		{
-			case IE_SUPP_RATES:
-                if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) && (eid_ptr->Len > 0))
-                {
-                    NdisMoveMemory(Rates, eid_ptr->Octet, eid_ptr->Len);
-                    DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - IE_SUPP_RATES., Len=%d. Rates[0]=%x\n",eid_ptr->Len, Rates[0]));
-                    DBGPRINT(RT_DEBUG_TRACE, ("Rates[1]=%x %x %x %x %x %x %x\n", Rates[1], Rates[2], Rates[3], Rates[4], Rates[5], Rates[6], Rates[7]));
-                    *pRatesLen = eid_ptr->Len;
-                }
-                else
-                {
-                    *pRatesLen = 8;
-					Rates[0] = 0x82;
-					Rates[1] = 0x84;
-					Rates[2] = 0x8b;
-					Rates[3] = 0x96;
-					Rates[4] = 0x12;
-					Rates[5] = 0x24;
-					Rates[6] = 0x48;
-					Rates[7] = 0x6c;
-                    DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - wrong IE_SUPP_RATES., Len=%d\n",eid_ptr->Len));
-                }
-				break;
-
-			case IE_EXT_SUPP_RATES:
-                if (eid_ptr->Len + *pRatesLen <= MAX_LEN_OF_SUPPORTED_RATES)
-                {
-                    NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, eid_ptr->Len);
-                    *pRatesLen = (*pRatesLen) + eid_ptr->Len;
-                }
-                else
-                {
-                    NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, MAX_LEN_OF_SUPPORTED_RATES - (*pRatesLen));
-                    *pRatesLen = MAX_LEN_OF_SUPPORTED_RATES;
-                }
-				break;
-
-			case IE_HT_CAP:
-				if (eid_ptr->Len >= sizeof(HT_CAPABILITY_IE))
-				{
-					NdisMoveMemory(pHtCapability, eid_ptr->Octet, sizeof(HT_CAPABILITY_IE));
-
-					*(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
-#ifdef UNALIGNMENT_SUPPORT
-					{
-						EXT_HT_CAP_INFO extHtCapInfo;
-
-						NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&pHtCapability->ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO));
-						*(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo));
-						NdisMoveMemory((PUCHAR)(&pHtCapability->ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO));
-					}
-#else
-					*(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
-#endif // UNALIGNMENT_SUPPORT //
-					*pHtCapabilityLen = sizeof(HT_CAPABILITY_IE);
-
-					DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - IE_HT_CAP\n"));
-				}
-				else
-				{
-					DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr->Len));
-				}
-				break;
-
-			default:
-				break;
-		}
-
-		eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
-	}
-
-    return TRUE;
-}
-
-BOOLEAN PeerDlsRspSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pDA,
-    OUT PUCHAR pSA,
-    OUT USHORT *pCapabilityInfo,
-    OUT USHORT *pStatus,
-    OUT UCHAR *pRatesLen,
-    OUT UCHAR Rates[],
-    OUT UCHAR *pHtCapabilityLen,
-    OUT HT_CAPABILITY_IE *pHtCapability)
-{
-    CHAR            *Ptr;
-    PFRAME_802_11	Fr = (PFRAME_802_11)Msg;
-	PEID_STRUCT  eid_ptr;
-
-    // to prevent caller from using garbage output value
-    *pStatus		= 0;
-    *pCapabilityInfo	= 0;
-	*pHtCapabilityLen = 0;
-
-    Ptr = (PCHAR)Fr->Octet;
-
-	// offset to destination MAC address (Category and Action field)
-    Ptr += 2;
-
-	// get status code from payload and advance the pointer
-    NdisMoveMemory(pStatus, Ptr, 2);
-    Ptr += 2;
-
-    // get DA from payload and advance the pointer
-    NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
-    Ptr += MAC_ADDR_LEN;
-
-    // get SA from payload and advance the pointer
-    NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
-    Ptr += MAC_ADDR_LEN;
-
-	if (pStatus == 0)
-	{
-	    // get capability info from payload and advance the pointer
-	    NdisMoveMemory(pCapabilityInfo, Ptr, 2);
-	    Ptr += 2;
-	}
-
-	// Category and Action field + status code + DA + SA + capability
-	eid_ptr = (PEID_STRUCT) &Fr->Octet[18];
-
-	while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((UCHAR*)Fr + MsgLen))
-	{
-		switch(eid_ptr->Eid)
-		{
-			case IE_SUPP_RATES:
-                if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) && (eid_ptr->Len > 0))
-                {
-                    NdisMoveMemory(Rates, eid_ptr->Octet, eid_ptr->Len);
-                    DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - IE_SUPP_RATES., Len=%d. Rates[0]=%x\n",eid_ptr->Len, Rates[0]));
-                    DBGPRINT(RT_DEBUG_TRACE, ("Rates[1]=%x %x %x %x %x %x %x\n", Rates[1], Rates[2], Rates[3], Rates[4], Rates[5], Rates[6], Rates[7]));
-                    *pRatesLen = eid_ptr->Len;
-                }
-                else
-                {
-                    *pRatesLen = 8;
-					Rates[0] = 0x82;
-					Rates[1] = 0x84;
-					Rates[2] = 0x8b;
-					Rates[3] = 0x96;
-					Rates[4] = 0x12;
-					Rates[5] = 0x24;
-					Rates[6] = 0x48;
-					Rates[7] = 0x6c;
-                    DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - wrong IE_SUPP_RATES., Len=%d\n",eid_ptr->Len));
-                }
-				break;
-
-			case IE_EXT_SUPP_RATES:
-                if (eid_ptr->Len + *pRatesLen <= MAX_LEN_OF_SUPPORTED_RATES)
-                {
-                    NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, eid_ptr->Len);
-                    *pRatesLen = (*pRatesLen) + eid_ptr->Len;
-                }
-                else
-                {
-                    NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, MAX_LEN_OF_SUPPORTED_RATES - (*pRatesLen));
-                    *pRatesLen = MAX_LEN_OF_SUPPORTED_RATES;
-                }
-				break;
-
-			case IE_HT_CAP:
-				if (eid_ptr->Len >= sizeof(HT_CAPABILITY_IE))
-				{
-					NdisMoveMemory(pHtCapability, eid_ptr->Octet, sizeof(HT_CAPABILITY_IE));
-
-					*(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
-#ifdef UNALIGNMENT_SUPPORT
-					{
-						EXT_HT_CAP_INFO extHtCapInfo;
-
-						NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&pHtCapability->ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO));
-						*(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo));
-						NdisMoveMemory((PUCHAR)(&pHtCapability->ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO));
-					}
-#else
-					*(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
-#endif // UNALIGNMENT_SUPPORT //
-					*pHtCapabilityLen = sizeof(HT_CAPABILITY_IE);
-
-					DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - IE_HT_CAP\n"));
-				}
-				else
-				{
-					DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr->Len));
-				}
-				break;
-
-			default:
-				break;
-		}
-
-		eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
-	}
-
-    return TRUE;
-}
-
-BOOLEAN PeerDlsTearDownSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pDA,
-    OUT PUCHAR pSA,
-    OUT USHORT *pReason)
-{
-    CHAR            *Ptr;
-    PFRAME_802_11	Fr = (PFRAME_802_11)Msg;
-
-    // to prevent caller from using garbage output value
-    *pReason	= 0;
-
-    Ptr = (PCHAR)Fr->Octet;
-
-	// offset to destination MAC address (Category and Action field)
-    Ptr += 2;
-
-    // get DA from payload and advance the pointer
-    NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
-    Ptr += MAC_ADDR_LEN;
-
-    // get SA from payload and advance the pointer
-    NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
-    Ptr += MAC_ADDR_LEN;
-
-	// get reason code from payload and advance the pointer
-    NdisMoveMemory(pReason, Ptr, 2);
-    Ptr += 2;
-
-    return TRUE;
-}
-#endif // QOS_DLS_SUPPORT //
diff --git a/drivers/staging/rt3090/common/cmm_sync.c b/drivers/staging/rt3090/common/cmm_sync.c
deleted file mode 100644
index 6d7b974..0000000
--- a/drivers/staging/rt3090/common/cmm_sync.c
+++ /dev/null
@@ -1,734 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	cmm_sync.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	John Chang	2004-09-01      modified for rt2561/2661
-*/
-
-#include "../rt_config.h"
-
-
-// 2.4 Ghz channel plan index in the TxPower arrays.
-#define	BG_BAND_REGION_0_START	0			// 1,2,3,4,5,6,7,8,9,10,11
-#define	BG_BAND_REGION_0_SIZE	11
-#define	BG_BAND_REGION_1_START	0			// 1,2,3,4,5,6,7,8,9,10,11,12,13
-#define	BG_BAND_REGION_1_SIZE	13
-#define	BG_BAND_REGION_2_START	9			// 10,11
-#define	BG_BAND_REGION_2_SIZE	2
-#define	BG_BAND_REGION_3_START	9			// 10,11,12,13
-#define	BG_BAND_REGION_3_SIZE	4
-#define	BG_BAND_REGION_4_START	13			// 14
-#define	BG_BAND_REGION_4_SIZE	1
-#define	BG_BAND_REGION_5_START	0			// 1,2,3,4,5,6,7,8,9,10,11,12,13,14
-#define	BG_BAND_REGION_5_SIZE	14
-#define	BG_BAND_REGION_6_START	2			// 3,4,5,6,7,8,9
-#define	BG_BAND_REGION_6_SIZE	7
-#define	BG_BAND_REGION_7_START	4			// 5,6,7,8,9,10,11,12,13
-#define	BG_BAND_REGION_7_SIZE	9
-#define	BG_BAND_REGION_31_START	0			// 1,2,3,4,5,6,7,8,9,10,11,12,13,14
-#define	BG_BAND_REGION_31_SIZE	14
-
-// 5 Ghz channel plan index in the TxPower arrays.
-UCHAR A_BAND_REGION_0_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165};
-UCHAR A_BAND_REGION_1_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
-UCHAR A_BAND_REGION_2_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64};
-UCHAR A_BAND_REGION_3_CHANNEL_LIST[]={52, 56, 60, 64, 149, 153, 157, 161};
-UCHAR A_BAND_REGION_4_CHANNEL_LIST[]={149, 153, 157, 161, 165};
-UCHAR A_BAND_REGION_5_CHANNEL_LIST[]={149, 153, 157, 161};
-UCHAR A_BAND_REGION_6_CHANNEL_LIST[]={36, 40, 44, 48};
-UCHAR A_BAND_REGION_7_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, 169, 173};
-UCHAR A_BAND_REGION_8_CHANNEL_LIST[]={52, 56, 60, 64};
-UCHAR A_BAND_REGION_9_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165};
-UCHAR A_BAND_REGION_10_CHANNEL_LIST[]={36, 40, 44, 48, 149, 153, 157, 161, 165};
-UCHAR A_BAND_REGION_11_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161};
-UCHAR A_BAND_REGION_12_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
-UCHAR A_BAND_REGION_13_CHANNEL_LIST[]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161};
-UCHAR A_BAND_REGION_14_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165};
-UCHAR A_BAND_REGION_15_CHANNEL_LIST[]={149, 153, 157, 161, 165, 169, 173};
-
-
-//BaSizeArray follows the 802.11n definition as MaxRxFactor.  2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8.
-UCHAR BaSizeArray[4] = {8,16,32,64};
-
-/*
-	==========================================================================
-	Description:
-		Update StaCfg->ChannelList[] according to 1) Country Region 2) RF IC type,
-		and 3) PHY-mode user selected.
-		The outcome is used by driver when doing site survey.
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID BuildChannelList(
-	IN PRTMP_ADAPTER pAd)
-{
-	UCHAR i, j, index=0, num=0;
-	PUCHAR	pChannelList = NULL;
-
-	NdisZeroMemory(pAd->ChannelList, MAX_NUM_OF_CHANNELS * sizeof(CHANNEL_TX_POWER));
-
-	// if not 11a-only mode, channel list starts from 2.4Ghz band
-	if ((pAd->CommonCfg.PhyMode != PHY_11A)
-#ifdef DOT11_N_SUPPORT
-		&& (pAd->CommonCfg.PhyMode != PHY_11AN_MIXED) && (pAd->CommonCfg.PhyMode != PHY_11N_5G)
-#endif // DOT11_N_SUPPORT //
-	)
-	{
-		switch (pAd->CommonCfg.CountryRegion  & 0x7f)
-		{
-			case REGION_0_BG_BAND:	// 1 -11
-				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_0_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_0_SIZE);
-				index += BG_BAND_REGION_0_SIZE;
-				break;
-			case REGION_1_BG_BAND:	// 1 - 13
-				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_1_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_1_SIZE);
-				index += BG_BAND_REGION_1_SIZE;
-				break;
-			case REGION_2_BG_BAND:	// 10 - 11
-				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_2_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_2_SIZE);
-				index += BG_BAND_REGION_2_SIZE;
-				break;
-			case REGION_3_BG_BAND:	// 10 - 13
-				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_3_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_3_SIZE);
-				index += BG_BAND_REGION_3_SIZE;
-				break;
-			case REGION_4_BG_BAND:	// 14
-				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_4_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_4_SIZE);
-				index += BG_BAND_REGION_4_SIZE;
-				break;
-			case REGION_5_BG_BAND:	// 1 - 14
-				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_5_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_5_SIZE);
-				index += BG_BAND_REGION_5_SIZE;
-				break;
-			case REGION_6_BG_BAND:	// 3 - 9
-				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_6_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_6_SIZE);
-				index += BG_BAND_REGION_6_SIZE;
-				break;
-			case REGION_7_BG_BAND:  // 5 - 13
-				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_7_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_7_SIZE);
-				index += BG_BAND_REGION_7_SIZE;
-				break;
-			case REGION_31_BG_BAND:	// 1 - 14
-				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_31_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_31_SIZE);
-				index += BG_BAND_REGION_31_SIZE;
-				break;
-			default:            // Error. should never happen
-				break;
-		}
-		for (i=0; i<index; i++)
-			pAd->ChannelList[i].MaxTxPwr = 20;
-	}
-
-	if ((pAd->CommonCfg.PhyMode == PHY_11A) || (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
-#ifdef DOT11_N_SUPPORT
-		|| (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED)
-		|| (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)
-#endif // DOT11_N_SUPPORT //
-	)
-	{
-		switch (pAd->CommonCfg.CountryRegionForABand & 0x7f)
-		{
-			case REGION_0_A_BAND:
-				num = sizeof(A_BAND_REGION_0_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_0_CHANNEL_LIST;
-				break;
-			case REGION_1_A_BAND:
-				num = sizeof(A_BAND_REGION_1_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_1_CHANNEL_LIST;
-				break;
-			case REGION_2_A_BAND:
-				num = sizeof(A_BAND_REGION_2_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_2_CHANNEL_LIST;
-				break;
-			case REGION_3_A_BAND:
-				num = sizeof(A_BAND_REGION_3_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_3_CHANNEL_LIST;
-				break;
-			case REGION_4_A_BAND:
-				num = sizeof(A_BAND_REGION_4_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_4_CHANNEL_LIST;
-				break;
-			case REGION_5_A_BAND:
-				num = sizeof(A_BAND_REGION_5_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_5_CHANNEL_LIST;
-				break;
-			case REGION_6_A_BAND:
-				num = sizeof(A_BAND_REGION_6_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_6_CHANNEL_LIST;
-				break;
-			case REGION_7_A_BAND:
-				num = sizeof(A_BAND_REGION_7_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_7_CHANNEL_LIST;
-				break;
-			case REGION_8_A_BAND:
-				num = sizeof(A_BAND_REGION_8_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_8_CHANNEL_LIST;
-				break;
-			case REGION_9_A_BAND:
-				num = sizeof(A_BAND_REGION_9_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_9_CHANNEL_LIST;
-				break;
-			case REGION_10_A_BAND:
-				num = sizeof(A_BAND_REGION_10_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_10_CHANNEL_LIST;
-				break;
-			case REGION_11_A_BAND:
-				num = sizeof(A_BAND_REGION_11_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_11_CHANNEL_LIST;
-				break;
-			case REGION_12_A_BAND:
-				num = sizeof(A_BAND_REGION_12_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_12_CHANNEL_LIST;
-				break;
-			case REGION_13_A_BAND:
-				num = sizeof(A_BAND_REGION_13_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_13_CHANNEL_LIST;
-				break;
-			case REGION_14_A_BAND:
-				num = sizeof(A_BAND_REGION_14_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_14_CHANNEL_LIST;
-				break;
-			case REGION_15_A_BAND:
-				num = sizeof(A_BAND_REGION_15_CHANNEL_LIST)/sizeof(UCHAR);
-				pChannelList = A_BAND_REGION_15_CHANNEL_LIST;
-				break;
-			default:            // Error. should never happen
-				DBGPRINT(RT_DEBUG_WARN,("countryregion=%d not support", pAd->CommonCfg.CountryRegionForABand));
-				break;
-		}
-
-		if (num != 0)
-		{
-			UCHAR RadarCh[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
-			for (i=0; i<num; i++)
-			{
-				for (j=0; j<MAX_NUM_OF_CHANNELS; j++)
-				{
-					if (pChannelList[i] == pAd->TxPower[j].Channel)
-						NdisMoveMemory(&pAd->ChannelList[index+i], &pAd->TxPower[j], sizeof(CHANNEL_TX_POWER));
-					}
-				for (j=0; j<15; j++)
-				{
-					if (pChannelList[i] == RadarCh[j])
-						pAd->ChannelList[index+i].DfsReq = TRUE;
-				}
-				pAd->ChannelList[index+i].MaxTxPwr = 20;
-			}
-			index += num;
-		}
-	}
-
-	pAd->ChannelListNum = index;
-	DBGPRINT(RT_DEBUG_TRACE,("country code=%d/%d, RFIC=%d, PHY mode=%d, support %d channels\n",
-		pAd->CommonCfg.CountryRegion, pAd->CommonCfg.CountryRegionForABand, pAd->RfIcType, pAd->CommonCfg.PhyMode, pAd->ChannelListNum));
-#ifdef DBG
-	for (i=0;i<pAd->ChannelListNum;i++)
-	{
-		DBGPRINT_RAW(RT_DEBUG_TRACE,("BuildChannel # %d :: Pwr0 = %d, Pwr1 =%d, \n ", pAd->ChannelList[i].Channel, pAd->ChannelList[i].Power, pAd->ChannelList[i].Power2));
-	}
-#endif
-}
-
-/*
-	==========================================================================
-	Description:
-		This routine return the first channel number according to the country
-		code selection and RF IC selection (signal band or dual band). It is called
-		whenever driver need to start a site survey of all supported channels.
-	Return:
-		ch - the first channel number of current country code setting
-
-	IRQL = PASSIVE_LEVEL
-
-	==========================================================================
- */
-UCHAR FirstChannel(
-	IN PRTMP_ADAPTER pAd)
-{
-	return pAd->ChannelList[0].Channel;
-}
-
-/*
-	==========================================================================
-	Description:
-		This routine returns the next channel number. This routine is called
-		during driver need to start a site survey of all supported channels.
-	Return:
-		next_channel - the next channel number valid in current country code setting.
-	Note:
-		return 0 if no more next channel
-	==========================================================================
- */
-UCHAR NextChannel(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR channel)
-{
-	int i;
-	UCHAR next_channel = 0;
-
-	for (i = 0; i < (pAd->ChannelListNum - 1); i++)
-		if (channel == pAd->ChannelList[i].Channel)
-		{
-			next_channel = pAd->ChannelList[i+1].Channel;
-			break;
-	}
-	return next_channel;
-}
-
-/*
-	==========================================================================
-	Description:
-		This routine is for Cisco Compatible Extensions 2.X
-		Spec31. AP Control of Client Transmit Power
-	Return:
-		None
-	Note:
-	   Required by Aironet dBm(mW)
-		   0dBm(1mW),   1dBm(5mW), 13dBm(20mW), 15dBm(30mW),
-		  17dBm(50mw), 20dBm(100mW)
-
-	   We supported
-		   3dBm(Lowest), 6dBm(10%), 9dBm(25%), 12dBm(50%),
-		  14dBm(75%),   15dBm(100%)
-
-		The client station's actual transmit power shall be within +/- 5dB of
-		the minimum value or next lower value.
-	==========================================================================
- */
-VOID ChangeToCellPowerLimit(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR         AironetCellPowerLimit)
-{
-	//valud 0xFF means that hasn't found power limit information
-	//from the AP's Beacon/Probe response.
-	if (AironetCellPowerLimit == 0xFF)
-		return;
-
-	if (AironetCellPowerLimit < 6) //Used Lowest Power Percentage.
-		pAd->CommonCfg.TxPowerPercentage = 6;
-	else if (AironetCellPowerLimit < 9)
-		pAd->CommonCfg.TxPowerPercentage = 10;
-	else if (AironetCellPowerLimit < 12)
-		pAd->CommonCfg.TxPowerPercentage = 25;
-	else if (AironetCellPowerLimit < 14)
-		pAd->CommonCfg.TxPowerPercentage = 50;
-	else if (AironetCellPowerLimit < 15)
-		pAd->CommonCfg.TxPowerPercentage = 75;
-	else
-		pAd->CommonCfg.TxPowerPercentage = 100; //else used maximum
-
-	if (pAd->CommonCfg.TxPowerPercentage > pAd->CommonCfg.TxPowerDefault)
-		pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
-
-}
-
-CHAR	ConvertToRssi(
-	IN PRTMP_ADAPTER	pAd,
-	IN CHAR				Rssi,
-	IN UCHAR			RssiNumber)
-{
-	UCHAR	RssiOffset, LNAGain;
-
-	// Rssi equals to zero should be an invalid value
-	if (Rssi == 0)
-		return -99;
-
-	LNAGain = GET_LNA_GAIN(pAd);
-    if (pAd->LatchRfRegs.Channel > 14)
-    {
-        if (RssiNumber == 0)
-			RssiOffset = pAd->ARssiOffset0;
-		else if (RssiNumber == 1)
-			RssiOffset = pAd->ARssiOffset1;
-		else
-			RssiOffset = pAd->ARssiOffset2;
-    }
-    else
-    {
-        if (RssiNumber == 0)
-			RssiOffset = pAd->BGRssiOffset0;
-		else if (RssiNumber == 1)
-			RssiOffset = pAd->BGRssiOffset1;
-		else
-			RssiOffset = pAd->BGRssiOffset2;
-    }
-
-    return (-12 - RssiOffset - LNAGain - Rssi);
-}
-
-/*
-	==========================================================================
-	Description:
-		Scan next channel
-	==========================================================================
- */
-VOID ScanNextChannel(
-	IN PRTMP_ADAPTER pAd)
-{
-	HEADER_802_11   Hdr80211;
-	PUCHAR          pOutBuffer = NULL;
-	NDIS_STATUS     NStatus;
-	ULONG           FrameLen = 0;
-	UCHAR           SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0;
-#ifdef CONFIG_STA_SUPPORT
-	USHORT          Status;
-	PHEADER_802_11  pHdr80211;
-#endif // CONFIG_STA_SUPPORT //
-	UINT			ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		if (MONITOR_ON(pAd))
-			return;
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef RALINK_ATE
-	// Nothing to do in ATE mode.
-	if (ATE_ON(pAd))
-		return;
-#endif // RALINK_ATE //
-
-	if (pAd->MlmeAux.Channel == 0)
-	{
-		if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
-#ifdef CONFIG_STA_SUPPORT
-			&& (INFRA_ON(pAd)
-				|| (pAd->OpMode == OPMODE_AP))
-#endif // CONFIG_STA_SUPPORT //
-			)
-		{
-			AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
-			AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-			BBPValue &= (~0x18);
-			BBPValue |= 0x10;
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-			DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
-		}
-		else
-		{
-			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-			DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
-		}
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			//
-			// To prevent data lost.
-			// Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
-			// Now, we need to send an NULL data with turned PSM bit off to AP, when scan progress done
-			//
-			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)))
-			{
-				NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);
-				if (NStatus	== NDIS_STATUS_SUCCESS)
-				{
-					pHdr80211 = (PHEADER_802_11) pOutBuffer;
-					MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
-					pHdr80211->Duration = 0;
-					pHdr80211->FC.Type = BTYPE_DATA;
-					pHdr80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
-
-					// Send using priority queue
-					MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
-					DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame\n"));
-					MlmeFreeMemory(pAd, pOutBuffer);
-					RTMPusecDelay(5000);
-				}
-			}
-
-			pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
-			Status = MLME_SUCCESS;
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
-		}
-#endif // CONFIG_STA_SUPPORT //
-
-
-		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
-	}
-	else
-	{
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-		// BBP and RF are not accessible in PS mode, we has to wake them up first
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-			AsicForceWakeup(pAd, TRUE);
-
-			// leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON
-			if (pAd->StaCfg.Psm == PWR_SAVE)
-				RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
-		}
-#endif // CONFIG_STA_SUPPORT //
-
-		AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE);
-		AsicLockChannel(pAd, pAd->MlmeAux.Channel);
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			if (pAd->MlmeAux.Channel > 14)
-			{
-				if ((pAd->CommonCfg.bIEEE80211H == 1) && RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
-				{
-					ScanType = SCAN_PASSIVE;
-					ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
-				}
-			}
-
-#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
-			// carrier detection
-			if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
-			{
-				ScanType = SCAN_PASSIVE;
-				ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
-			}
-#endif // CARRIER_DETECTION_SUPPORT //
-		}
-
-#endif // CONFIG_STA_SUPPORT //
-
-		//Global country domain(ch1-11:active scan, ch12-14 passive scan)
-		if ((pAd->MlmeAux.Channel <= 14) && (pAd->MlmeAux.Channel >= 12) && ((pAd->CommonCfg.CountryRegion & 0x7f) == REGION_31_BG_BAND))
-		{
-			ScanType = SCAN_PASSIVE;
-		}
-
-		// We need to shorten active scan time in order for WZC connect issue
-		// Chnage the channel scan time for CISCO stuff based on its IAPP announcement
-		if (ScanType == FAST_SCAN_ACTIVE)
-			RTMPSetTimer(&pAd->MlmeAux.ScanTimer, FAST_ACTIVE_SCAN_TIME);
-		else // must be SCAN_PASSIVE or SCAN_ACTIVE
-		{
-			if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
-#ifdef DOT11_N_SUPPORT
-				|| (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)
-#endif // DOT11_N_SUPPORT //
-			)
-			{
-				if (pAd->MlmeAux.Channel > 14)
-					RTMPSetTimer(&pAd->MlmeAux.ScanTimer, ScanTimeIn5gChannel);
-				else
-				RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MIN_CHANNEL_TIME);
-			}
-			else
-				RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MAX_CHANNEL_TIME);
-		}
-
-		if ((ScanType == SCAN_ACTIVE)
-			|| (ScanType == FAST_SCAN_ACTIVE)
-			)
-		{
-			NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-			if (NStatus != NDIS_STATUS_SUCCESS)
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("SYNC - ScanNextChannel() allocate memory fail\n"));
-#ifdef CONFIG_STA_SUPPORT
-				IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-				{
-					pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
-					Status = MLME_FAIL_NO_RESOURCE;
-					MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
-				}
-#endif // CONFIG_STA_SUPPORT //
-
-				return;
-			}
-
-			// There is no need to send broadcast probe request if active scan is in effect.
-			if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE)
-				)
-				SsidLen = pAd->MlmeAux.SsidLen;
-			else
-				SsidLen = 0;
-
-#ifdef CONFIG_STA_SUPPORT
-			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-				MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
-#endif // CONFIG_STA_SUPPORT //
-
-
-			MakeOutgoingFrame(pOutBuffer,               &FrameLen,
-							  sizeof(HEADER_802_11),    &Hdr80211,
-							  1,                        &SsidIe,
-							  1,                        &SsidLen,
-							  SsidLen,			        pAd->MlmeAux.Ssid,
-							  1,                        &SupRateIe,
-							  1,                        &pAd->CommonCfg.SupRateLen,
-							  pAd->CommonCfg.SupRateLen,  pAd->CommonCfg.SupRate,
-							  END_OF_ARGS);
-
-			if (pAd->CommonCfg.ExtRateLen)
-			{
-				ULONG Tmp;
-				MakeOutgoingFrame(pOutBuffer + FrameLen,            &Tmp,
-								  1,                                &ExtRateIe,
-								  1,                                &pAd->CommonCfg.ExtRateLen,
-								  pAd->CommonCfg.ExtRateLen,          pAd->CommonCfg.ExtRate,
-								  END_OF_ARGS);
-				FrameLen += Tmp;
-			}
-
-#ifdef DOT11_N_SUPPORT
-			if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
-			{
-				ULONG	Tmp;
-				UCHAR	HtLen;
-				UCHAR	BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
-#ifdef RT_BIG_ENDIAN
-				HT_CAPABILITY_IE HtCapabilityTmp;
-#endif
-				if (pAd->bBroadComHT == TRUE)
-				{
-					HtLen = pAd->MlmeAux.HtCapabilityLen + 4;
-#ifdef RT_BIG_ENDIAN
-					NdisMoveMemory(&HtCapabilityTmp, &pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
-					*(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
-#ifdef UNALIGNMENT_SUPPORT
-					{
-						EXT_HT_CAP_INFO extHtCapInfo;
-
-						NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO));
-						*(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo));
-						NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO));
-					}
-#else
-					*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
-#endif // UNALIGNMENT_SUPPORT //
-
-					MakeOutgoingFrame(pOutBuffer + FrameLen,          &Tmp,
-									1,                                &WpaIe,
-									1,                                &HtLen,
-									4,                                &BROADCOM[0],
-									pAd->MlmeAux.HtCapabilityLen,     &HtCapabilityTmp,
-									END_OF_ARGS);
-#else
-					MakeOutgoingFrame(pOutBuffer + FrameLen,          &Tmp,
-									1,                                &WpaIe,
-									1,                                &HtLen,
-									4,                                &BROADCOM[0],
-									pAd->MlmeAux.HtCapabilityLen,     &pAd->MlmeAux.HtCapability,
-									END_OF_ARGS);
-#endif // RT_BIG_ENDIAN //
-				}
-				else
-				{
-					HtLen = pAd->MlmeAux.HtCapabilityLen;
-#ifdef RT_BIG_ENDIAN
-					NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, SIZE_HT_CAP_IE);
-					*(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
-#ifdef UNALIGNMENT_SUPPORT
-					{
-						EXT_HT_CAP_INFO extHtCapInfo;
-
-						NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO));
-						*(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo));
-						NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO));
-					}
-#else
-					*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
-#endif // UNALIGNMENT_SUPPORT //
-
-					MakeOutgoingFrame(pOutBuffer + FrameLen,          &Tmp,
-									1,                                &HtCapIe,
-									1,                                &HtLen,
-									HtLen,                            &HtCapabilityTmp,
-									END_OF_ARGS);
-#else
-					MakeOutgoingFrame(pOutBuffer + FrameLen,          &Tmp,
-									1,                                &HtCapIe,
-									1,                                &HtLen,
-									HtLen,                            &pAd->CommonCfg.HtCapability,
-									END_OF_ARGS);
-#endif // RT_BIG_ENDIAN //
-				}
-				FrameLen += Tmp;
-
-#ifdef DOT11N_DRAFT3
-				if (pAd->CommonCfg.BACapability.field.b2040CoexistScanSup == 1)
-				{
-					ULONG		Tmp;
-					HtLen = 1;
-					MakeOutgoingFrame(pOutBuffer + FrameLen,            &Tmp,
-									  1,					&ExtHtCapIe,
-									  1,					&HtLen,
-									  1,				&pAd->CommonCfg.BSSCoexist2040.word,
-									  END_OF_ARGS);
-
-					FrameLen += Tmp;
-				}
-#endif // DOT11N_DRAFT3 //
-			}
-#endif // DOT11_N_SUPPORT //
-
-
-			MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-			MlmeFreeMemory(pAd, pOutBuffer);
-		}
-
-		// For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-			pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN;
-#endif // CONFIG_STA_SUPPORT //
-
-	}
-}
-
-VOID MgtProbReqMacHeaderInit(
-	IN	PRTMP_ADAPTER	pAd,
-	IN OUT PHEADER_802_11 pHdr80211,
-	IN UCHAR SubType,
-	IN UCHAR ToDs,
-	IN PUCHAR pDA,
-	IN PUCHAR pBssid)
-{
-	NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
-
-	pHdr80211->FC.Type = BTYPE_MGMT;
-	pHdr80211->FC.SubType = SubType;
-	if (SubType == SUBTYPE_ACK)
-		pHdr80211->FC.Type = BTYPE_CNTL;
-	pHdr80211->FC.ToDs = ToDs;
-	COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
-	COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
-	COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
-}
diff --git a/drivers/staging/rt3090/common/cmm_tkip.c b/drivers/staging/rt3090/common/cmm_tkip.c
deleted file mode 100644
index 0b474f2..0000000
--- a/drivers/staging/rt3090/common/cmm_tkip.c
+++ /dev/null
@@ -1,966 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	cmm_tkip.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Paul Wu		02-25-02		Initial
-*/
-
-#include "../rt_config.h"
-
-
-// Rotation functions on 32 bit values
-#define ROL32( A, n ) \
-	( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) )
-#define ROR32( A, n ) ROL32( (A), 32-(n) )
-
-UINT Tkip_Sbox_Lower[256] =
-{
-	0xA5,0x84,0x99,0x8D,0x0D,0xBD,0xB1,0x54,
-	0x50,0x03,0xA9,0x7D,0x19,0x62,0xE6,0x9A,
-	0x45,0x9D,0x40,0x87,0x15,0xEB,0xC9,0x0B,
-	0xEC,0x67,0xFD,0xEA,0xBF,0xF7,0x96,0x5B,
-	0xC2,0x1C,0xAE,0x6A,0x5A,0x41,0x02,0x4F,
-	0x5C,0xF4,0x34,0x08,0x93,0x73,0x53,0x3F,
-	0x0C,0x52,0x65,0x5E,0x28,0xA1,0x0F,0xB5,
-	0x09,0x36,0x9B,0x3D,0x26,0x69,0xCD,0x9F,
-	0x1B,0x9E,0x74,0x2E,0x2D,0xB2,0xEE,0xFB,
-	0xF6,0x4D,0x61,0xCE,0x7B,0x3E,0x71,0x97,
-	0xF5,0x68,0x00,0x2C,0x60,0x1F,0xC8,0xED,
-	0xBE,0x46,0xD9,0x4B,0xDE,0xD4,0xE8,0x4A,
-	0x6B,0x2A,0xE5,0x16,0xC5,0xD7,0x55,0x94,
-	0xCF,0x10,0x06,0x81,0xF0,0x44,0xBA,0xE3,
-	0xF3,0xFE,0xC0,0x8A,0xAD,0xBC,0x48,0x04,
-	0xDF,0xC1,0x75,0x63,0x30,0x1A,0x0E,0x6D,
-	0x4C,0x14,0x35,0x2F,0xE1,0xA2,0xCC,0x39,
-	0x57,0xF2,0x82,0x47,0xAC,0xE7,0x2B,0x95,
-	0xA0,0x98,0xD1,0x7F,0x66,0x7E,0xAB,0x83,
-	0xCA,0x29,0xD3,0x3C,0x79,0xE2,0x1D,0x76,
-	0x3B,0x56,0x4E,0x1E,0xDB,0x0A,0x6C,0xE4,
-	0x5D,0x6E,0xEF,0xA6,0xA8,0xA4,0x37,0x8B,
-	0x32,0x43,0x59,0xB7,0x8C,0x64,0xD2,0xE0,
-	0xB4,0xFA,0x07,0x25,0xAF,0x8E,0xE9,0x18,
-	0xD5,0x88,0x6F,0x72,0x24,0xF1,0xC7,0x51,
-	0x23,0x7C,0x9C,0x21,0xDD,0xDC,0x86,0x85,
-	0x90,0x42,0xC4,0xAA,0xD8,0x05,0x01,0x12,
-	0xA3,0x5F,0xF9,0xD0,0x91,0x58,0x27,0xB9,
-	0x38,0x13,0xB3,0x33,0xBB,0x70,0x89,0xA7,
-	0xB6,0x22,0x92,0x20,0x49,0xFF,0x78,0x7A,
-	0x8F,0xF8,0x80,0x17,0xDA,0x31,0xC6,0xB8,
-	0xC3,0xB0,0x77,0x11,0xCB,0xFC,0xD6,0x3A
-};
-
-UINT Tkip_Sbox_Upper[256] =
-{
-	0xC6,0xF8,0xEE,0xF6,0xFF,0xD6,0xDE,0x91,
-	0x60,0x02,0xCE,0x56,0xE7,0xB5,0x4D,0xEC,
-	0x8F,0x1F,0x89,0xFA,0xEF,0xB2,0x8E,0xFB,
-	0x41,0xB3,0x5F,0x45,0x23,0x53,0xE4,0x9B,
-	0x75,0xE1,0x3D,0x4C,0x6C,0x7E,0xF5,0x83,
-	0x68,0x51,0xD1,0xF9,0xE2,0xAB,0x62,0x2A,
-	0x08,0x95,0x46,0x9D,0x30,0x37,0x0A,0x2F,
-	0x0E,0x24,0x1B,0xDF,0xCD,0x4E,0x7F,0xEA,
-	0x12,0x1D,0x58,0x34,0x36,0xDC,0xB4,0x5B,
-	0xA4,0x76,0xB7,0x7D,0x52,0xDD,0x5E,0x13,
-	0xA6,0xB9,0x00,0xC1,0x40,0xE3,0x79,0xB6,
-	0xD4,0x8D,0x67,0x72,0x94,0x98,0xB0,0x85,
-	0xBB,0xC5,0x4F,0xED,0x86,0x9A,0x66,0x11,
-	0x8A,0xE9,0x04,0xFE,0xA0,0x78,0x25,0x4B,
-	0xA2,0x5D,0x80,0x05,0x3F,0x21,0x70,0xF1,
-	0x63,0x77,0xAF,0x42,0x20,0xE5,0xFD,0xBF,
-	0x81,0x18,0x26,0xC3,0xBE,0x35,0x88,0x2E,
-	0x93,0x55,0xFC,0x7A,0xC8,0xBA,0x32,0xE6,
-	0xC0,0x19,0x9E,0xA3,0x44,0x54,0x3B,0x0B,
-	0x8C,0xC7,0x6B,0x28,0xA7,0xBC,0x16,0xAD,
-	0xDB,0x64,0x74,0x14,0x92,0x0C,0x48,0xB8,
-	0x9F,0xBD,0x43,0xC4,0x39,0x31,0xD3,0xF2,
-	0xD5,0x8B,0x6E,0xDA,0x01,0xB1,0x9C,0x49,
-	0xD8,0xAC,0xF3,0xCF,0xCA,0xF4,0x47,0x10,
-	0x6F,0xF0,0x4A,0x5C,0x38,0x57,0x73,0x97,
-	0xCB,0xA1,0xE8,0x3E,0x96,0x61,0x0D,0x0F,
-	0xE0,0x7C,0x71,0xCC,0x90,0x06,0xF7,0x1C,
-	0xC2,0x6A,0xAE,0x69,0x17,0x99,0x3A,0x27,
-	0xD9,0xEB,0x2B,0x22,0xD2,0xA9,0x07,0x33,
-	0x2D,0x3C,0x15,0xC9,0x87,0xAA,0x50,0xA5,
-	0x03,0x59,0x09,0x1A,0x65,0xD7,0x84,0xD0,
-	0x82,0x29,0x5A,0x1E,0x7B,0xA8,0x6D,0x2C
-};
-
-//
-// Expanded IV for TKIP function.
-//
-typedef	struct	PACKED _IV_CONTROL_
-{
-	union PACKED
-	{
-		struct PACKED
-		{
-			UCHAR		rc0;
-			UCHAR		rc1;
-			UCHAR		rc2;
-
-			union PACKED
-			{
-				struct PACKED
-				{
-#ifdef RT_BIG_ENDIAN
-					UCHAR	KeyID:2;
-					UCHAR	ExtIV:1;
-					UCHAR	Rsvd:5;
-#else
-					UCHAR	Rsvd:5;
-					UCHAR	ExtIV:1;
-					UCHAR	KeyID:2;
-#endif
-				}	field;
-				UCHAR		Byte;
-			}	CONTROL;
-		}	field;
-
-		ULONG	word;
-	}	IV16;
-
-	ULONG	IV32;
-}	TKIP_IV, *PTKIP_IV;
-
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Convert from UCHAR[] to ULONG in a portable way
-
-	Arguments:
-      pMICKey		pointer to MIC Key
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-ULONG	RTMPTkipGetUInt32(
-	IN	PUCHAR	pMICKey)
-{
-	ULONG	res = 0;
-	INT		i;
-
-	for (i = 0; i < 4; i++)
-	{
-		res |= (*pMICKey++) << (8 * i);
-	}
-
-	return res;
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Convert from ULONG to UCHAR[] in a portable way
-
-	Arguments:
-      pDst			pointer to destination for convert ULONG to UCHAR[]
-      val			the value for convert
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPTkipPutUInt32(
-	IN OUT	PUCHAR		pDst,
-	IN		ULONG		val)
-{
-	INT i;
-
-	for(i = 0; i < 4; i++)
-	{
-		*pDst++ = (UCHAR) (val & 0xff);
-		val >>= 8;
-	}
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Set the MIC Key.
-
-	Arguments:
-      pAd		Pointer to our adapter
-      pMICKey		pointer to MIC Key
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID RTMPTkipSetMICKey(
-	IN	PTKIP_KEY_INFO	pTkip,
-	IN	PUCHAR			pMICKey)
-{
-	// Set the key
-	pTkip->K0 = RTMPTkipGetUInt32(pMICKey);
-	pTkip->K1 = RTMPTkipGetUInt32(pMICKey + 4);
-	// and reset the message
-	pTkip->L = pTkip->K0;
-	pTkip->R = pTkip->K1;
-	pTkip->nBytesInM = 0;
-	pTkip->M = 0;
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Calculate the MIC Value.
-
-	Arguments:
-      pAd		Pointer to our adapter
-      uChar			Append this uChar
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPTkipAppendByte(
-	IN	PTKIP_KEY_INFO	pTkip,
-	IN	UCHAR			uChar)
-{
-	// Append the byte to our word-sized buffer
-	pTkip->M |= (uChar << (8* pTkip->nBytesInM));
-	pTkip->nBytesInM++;
-	// Process the word if it is full.
-	if( pTkip->nBytesInM >= 4 )
-	{
-		pTkip->L ^= pTkip->M;
-		pTkip->R ^= ROL32( pTkip->L, 17 );
-		pTkip->L += pTkip->R;
-		pTkip->R ^= ((pTkip->L & 0xff00ff00) >> 8) | ((pTkip->L & 0x00ff00ff) << 8);
-		pTkip->L += pTkip->R;
-		pTkip->R ^= ROL32( pTkip->L, 3 );
-		pTkip->L += pTkip->R;
-		pTkip->R ^= ROR32( pTkip->L, 2 );
-		pTkip->L += pTkip->R;
-		// Clear the buffer
-		pTkip->M = 0;
-		pTkip->nBytesInM = 0;
-	}
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Calculate the MIC Value.
-
-	Arguments:
-      pAd		Pointer to our adapter
-      pSrc			Pointer to source data for Calculate MIC Value
-      Len			Indicate the length of the source data
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPTkipAppend(
-	IN	PTKIP_KEY_INFO	pTkip,
-	IN	PUCHAR			pSrc,
-	IN	UINT			nBytes)
-{
-	// This is simple
-	while(nBytes > 0)
-	{
-		RTMPTkipAppendByte(pTkip, *pSrc++);
-		nBytes--;
-	}
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Get the MIC Value.
-
-	Arguments:
-      pAd		Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-		the MIC Value is store in pAd->PrivateInfo.MIC
-	========================================================================
-*/
-VOID	RTMPTkipGetMIC(
-	IN	PTKIP_KEY_INFO	pTkip)
-{
-	// Append the minimum padding
-	RTMPTkipAppendByte(pTkip, 0x5a );
-	RTMPTkipAppendByte(pTkip, 0 );
-	RTMPTkipAppendByte(pTkip, 0 );
-	RTMPTkipAppendByte(pTkip, 0 );
-	RTMPTkipAppendByte(pTkip, 0 );
-	// and then zeroes until the length is a multiple of 4
-	while( pTkip->nBytesInM != 0 )
-	{
-		RTMPTkipAppendByte(pTkip, 0 );
-	}
-	// The appendByte function has already computed the result.
-	RTMPTkipPutUInt32(pTkip->MIC, pTkip->L);
-	RTMPTkipPutUInt32(pTkip->MIC + 4, pTkip->R);
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Init Tkip function.
-
-	Arguments:
-      pAd		Pointer to our adapter
-		pTKey       Pointer to the Temporal Key (TK), TK shall be 128bits.
-		KeyId		TK Key ID
-		pTA			Pointer to transmitter address
-		pMICKey		pointer to MIC Key
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPInitTkipEngine(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pKey,
-	IN	UCHAR			KeyId,
-	IN	PUCHAR			pTA,
-	IN	PUCHAR			pMICKey,
-	IN	PUCHAR			pTSC,
-	OUT	PULONG			pIV16,
-	OUT	PULONG			pIV32)
-{
-	TKIP_IV	tkipIv;
-
-	// Prepare 8 bytes TKIP encapsulation for MPDU
-	NdisZeroMemory(&tkipIv, sizeof(TKIP_IV));
-	tkipIv.IV16.field.rc0 = *(pTSC + 1);
-	tkipIv.IV16.field.rc1 = (tkipIv.IV16.field.rc0 | 0x20) & 0x7f;
-	tkipIv.IV16.field.rc2 = *pTSC;
-	tkipIv.IV16.field.CONTROL.field.ExtIV = 1;  // 0: non-extended IV, 1: an extended IV
-	tkipIv.IV16.field.CONTROL.field.KeyID = KeyId;
-//	tkipIv.IV32 = *(PULONG)(pTSC + 2);
-	NdisMoveMemory(&tkipIv.IV32, (pTSC + 2), 4);   // Copy IV
-
-	*pIV16 = tkipIv.IV16.word;
-	*pIV32 = tkipIv.IV32;
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Init MIC Value calculation function which include set MIC key &
-		calculate first 16 bytes (DA + SA + priority +  0)
-
-	Arguments:
-      pAd		Pointer to our adapter
-		pTKey       Pointer to the Temporal Key (TK), TK shall be 128bits.
-		pDA			Pointer to DA address
-		pSA			Pointer to SA address
-		pMICKey		pointer to MIC Key
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPInitMICEngine(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pKey,
-	IN	PUCHAR			pDA,
-	IN	PUCHAR			pSA,
-	IN  UCHAR           UserPriority,
-	IN	PUCHAR			pMICKey)
-{
-	ULONG Priority = UserPriority;
-
-	// Init MIC value calculation
-	RTMPTkipSetMICKey(&pAd->PrivateInfo.Tx, pMICKey);
-	// DA
-	RTMPTkipAppend(&pAd->PrivateInfo.Tx, pDA, MAC_ADDR_LEN);
-	// SA
-	RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSA, MAC_ADDR_LEN);
-	// Priority + 3 bytes of 0
-	RTMPTkipAppend(&pAd->PrivateInfo.Tx, (PUCHAR)&Priority, 4);
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Compare MIC value of received MSDU
-
-	Arguments:
-		pAd	Pointer to our adapter
-		pSrc        Pointer to the received Plain text data
-		pDA			Pointer to DA address
-		pSA			Pointer to SA address
-		pMICKey		pointer to MIC Key
-		Len         the length of the received plain text data exclude MIC value
-
-	Return Value:
-		TRUE        MIC value matched
-		FALSE       MIC value mismatched
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-BOOLEAN	RTMPTkipCompareMICValue(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pSrc,
-	IN	PUCHAR			pDA,
-	IN	PUCHAR			pSA,
-	IN	PUCHAR			pMICKey,
-	IN	UCHAR			UserPriority,
-	IN	UINT			Len)
-{
-	UCHAR	OldMic[8];
-	ULONG	Priority = UserPriority;
-
-	// Init MIC value calculation
-	RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
-	// DA
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
-	// SA
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
-	// Priority + 3 bytes of 0
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
-
-	// Calculate MIC value from plain text data
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
-
-	// Get MIC valude from received frame
-	NdisMoveMemory(OldMic, pSrc + Len, 8);
-
-	// Get MIC value from decrypted plain data
-	RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
-
-	// Move MIC value from MSDU, this steps should move to data path.
-	// Since the MIC value might cross MPDUs.
-	if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8))
-	{
-		DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValue(): TKIP MIC Error !\n"));  //MIC error.
-
-
-		return (FALSE);
-	}
-	return (TRUE);
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Compare MIC value of received MSDU
-
-	Arguments:
-		pAd	Pointer to our adapter
-		pLLC		LLC header
-		pSrc        Pointer to the received Plain text data
-		pDA			Pointer to DA address
-		pSA			Pointer to SA address
-		pMICKey		pointer to MIC Key
-		Len         the length of the received plain text data exclude MIC value
-
-	Return Value:
-		TRUE        MIC value matched
-		FALSE       MIC value mismatched
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-BOOLEAN	RTMPTkipCompareMICValueWithLLC(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pLLC,
-	IN	PUCHAR			pSrc,
-	IN	PUCHAR			pDA,
-	IN	PUCHAR			pSA,
-	IN	PUCHAR			pMICKey,
-	IN	UINT			Len)
-{
-	UCHAR	OldMic[8];
-	ULONG	Priority = 0;
-
-	// Init MIC value calculation
-	RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
-	// DA
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
-	// SA
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
-	// Priority + 3 bytes of 0
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
-
-	// Start with LLC header
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pLLC, 8);
-
-	// Calculate MIC value from plain text data
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
-
-	// Get MIC valude from received frame
-	NdisMoveMemory(OldMic, pSrc + Len, 8);
-
-	// Get MIC value from decrypted plain data
-	RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
-
-	// Move MIC value from MSDU, this steps should move to data path.
-	// Since the MIC value might cross MPDUs.
-	if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8))
-	{
-		DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValueWithLLC(): TKIP MIC Error !\n"));  //MIC error.
-
-
-		return (FALSE);
-	}
-	return (TRUE);
-}
-/*
-	========================================================================
-
-	Routine	Description:
-		Copy frame from waiting queue into relative ring buffer and set
-	appropriate ASIC register to kick hardware transmit function
-
-	Arguments:
-		pAd		Pointer	to our adapter
-		PNDIS_PACKET	Pointer to Ndis Packet for MIC calculation
-		pEncap			Pointer to LLC encap data
-		LenEncap		Total encap length, might be 0 which indicates no encap
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPCalculateMICValue(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket,
-	IN	PUCHAR			pEncap,
-	IN	PCIPHER_KEY		pKey,
-	IN	UCHAR			apidx)
-{
-	PACKET_INFO		PacketInfo;
-	PUCHAR			pSrcBufVA;
-	UINT			SrcBufLen;
-	PUCHAR			pSrc;
-    UCHAR           UserPriority;
-	UCHAR			vlan_offset = 0;
-
-	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
-
-	UserPriority = RTMP_GET_PACKET_UP(pPacket);
-	pSrc = pSrcBufVA;
-
-	// determine if this is a vlan packet
-	if (((*(pSrc + 12) << 8) + *(pSrc + 13)) == 0x8100)
-		vlan_offset = 4;
-
-#ifdef CONFIG_STA_SUPPORT
-#endif // CONFIG_STA_SUPPORT //
-	{
-		RTMPInitMICEngine(
-			pAd,
-			pKey->Key,
-			pSrc,
-			pSrc + 6,
-			UserPriority,
-			pKey->TxMic);
-	}
-
-
-	if (pEncap != NULL)
-	{
-		// LLC encapsulation
-		RTMPTkipAppend(&pAd->PrivateInfo.Tx, pEncap, 6);
-		// Protocol Type
-		RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc + 12 + vlan_offset, 2);
-	}
-	SrcBufLen -= (14 + vlan_offset);
-	pSrc += (14 + vlan_offset);
-	do
-	{
-		if (SrcBufLen > 0)
-		{
-			RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc, SrcBufLen);
-		}
-
-		break;	// No need handle next packet
-
-	}	while (TRUE);		// End of copying payload
-
-	// Compute the final MIC Value
-	RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
-}
-
-
-/************************************************************/
-/* tkip_sbox()																*/
-/* Returns a 16 bit value from a 64K entry table. The Table */
-/* is synthesized from two 256 entry byte wide tables.		*/
-/************************************************************/
-
-UINT tkip_sbox(UINT index)
-{
-	UINT index_low;
-	UINT index_high;
-	UINT left, right;
-
-	index_low = (index % 256);
-	index_high = ((index >> 8) % 256);
-
-	left = Tkip_Sbox_Lower[index_low] + (Tkip_Sbox_Upper[index_low] * 256);
-	right = Tkip_Sbox_Upper[index_high] + (Tkip_Sbox_Lower[index_high] * 256);
-
-	return (left ^ right);
-}
-
-UINT rotr1(UINT a)
-{
-	unsigned int b;
-
-	if ((a & 0x01) == 0x01)
-	{
-		b = (a >> 1) | 0x8000;
-	}
-	else
-	{
-		b = (a >> 1) & 0x7fff;
-	}
-	b = b % 65536;
-	return b;
-}
-
-VOID RTMPTkipMixKey(
-	UCHAR *key,
-	UCHAR *ta,
-	ULONG pnl, /* Least significant 16 bits of PN */
-	ULONG pnh, /* Most significant 32 bits of PN */
-	UCHAR *rc4key,
-	UINT *p1k)
-{
-
-	UINT tsc0;
-	UINT tsc1;
-	UINT tsc2;
-
-	UINT ppk0;
-	UINT ppk1;
-	UINT ppk2;
-	UINT ppk3;
-	UINT ppk4;
-	UINT ppk5;
-
-	INT i;
-	INT j;
-
-	tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
-	tsc1 = (unsigned int)(pnh % 65536);
-	tsc2 = (unsigned int)(pnl % 65536); /* lsb */
-
-	/* Phase 1, step 1 */
-	p1k[0] = tsc1;
-	p1k[1] = tsc0;
-	p1k[2] = (UINT)(ta[0] + (ta[1]*256));
-	p1k[3] = (UINT)(ta[2] + (ta[3]*256));
-	p1k[4] = (UINT)(ta[4] + (ta[5]*256));
-
-	/* Phase 1, step 2 */
-	for (i=0; i<8; i++)
-	{
-		j = 2*(i & 1);
-		p1k[0] = (p1k[0] + tkip_sbox( (p1k[4] ^ ((256*key[1+j]) + key[j])) % 65536 )) % 65536;
-		p1k[1] = (p1k[1] + tkip_sbox( (p1k[0] ^ ((256*key[5+j]) + key[4+j])) % 65536 )) % 65536;
-		p1k[2] = (p1k[2] + tkip_sbox( (p1k[1] ^ ((256*key[9+j]) + key[8+j])) % 65536 )) % 65536;
-		p1k[3] = (p1k[3] + tkip_sbox( (p1k[2] ^ ((256*key[13+j]) + key[12+j])) % 65536 )) % 65536;
-		p1k[4] = (p1k[4] + tkip_sbox( (p1k[3] ^ (((256*key[1+j]) + key[j]))) % 65536 )) % 65536;
-		p1k[4] = (p1k[4] + i) % 65536;
-	}
-
-	/* Phase 2, Step 1 */
-	ppk0 = p1k[0];
-	ppk1 = p1k[1];
-	ppk2 = p1k[2];
-	ppk3 = p1k[3];
-	ppk4 = p1k[4];
-	ppk5 = (p1k[4] + tsc2) % 65536;
-
-	/* Phase2, Step 2 */
-	ppk0 = ppk0 + tkip_sbox( (ppk5 ^ ((256*key[1]) + key[0])) % 65536);
-	ppk1 = ppk1 + tkip_sbox( (ppk0 ^ ((256*key[3]) + key[2])) % 65536);
-	ppk2 = ppk2 + tkip_sbox( (ppk1 ^ ((256*key[5]) + key[4])) % 65536);
-	ppk3 = ppk3 + tkip_sbox( (ppk2 ^ ((256*key[7]) + key[6])) % 65536);
-	ppk4 = ppk4 + tkip_sbox( (ppk3 ^ ((256*key[9]) + key[8])) % 65536);
-	ppk5 = ppk5 + tkip_sbox( (ppk4 ^ ((256*key[11]) + key[10])) % 65536);
-
-	ppk0 = ppk0 + rotr1(ppk5 ^ ((256*key[13]) + key[12]));
-	ppk1 = ppk1 + rotr1(ppk0 ^ ((256*key[15]) + key[14]));
-	ppk2 = ppk2 + rotr1(ppk1);
-	ppk3 = ppk3 + rotr1(ppk2);
-	ppk4 = ppk4 + rotr1(ppk3);
-	ppk5 = ppk5 + rotr1(ppk4);
-
-	/* Phase 2, Step 3 */
-    /* Phase 2, Step 3 */
-
-	tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
-	tsc1 = (unsigned int)(pnh % 65536);
-	tsc2 = (unsigned int)(pnl % 65536); /* lsb */
-
-	rc4key[0] = (tsc2 >> 8) % 256;
-	rc4key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f;
-	rc4key[2] = tsc2 % 256;
-	rc4key[3] = ((ppk5 ^ ((256*key[1]) + key[0])) >> 1) % 256;
-
-	rc4key[4] = ppk0 % 256;
-	rc4key[5] = (ppk0 >> 8) % 256;
-
-	rc4key[6] = ppk1 % 256;
-	rc4key[7] = (ppk1 >> 8) % 256;
-
-	rc4key[8] = ppk2 % 256;
-	rc4key[9] = (ppk2 >> 8) % 256;
-
-	rc4key[10] = ppk3 % 256;
-	rc4key[11] = (ppk3 >> 8) % 256;
-
-	rc4key[12] = ppk4 % 256;
-	rc4key[13] = (ppk4 >> 8) % 256;
-
-	rc4key[14] = ppk5 % 256;
-	rc4key[15] = (ppk5 >> 8) % 256;
-}
-
-
-//
-// TRUE: Success!
-// FALSE: Decrypt Error!
-//
-BOOLEAN RTMPSoftDecryptTKIP(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR	pData,
-	IN ULONG	DataByteCnt,
-	IN UCHAR    UserPriority,
-	IN PCIPHER_KEY	pWpaKey)
-{
-	UCHAR			KeyID;
-	UINT			HeaderLen;
-    UCHAR			fc0;
-	UCHAR			fc1;
-	USHORT			fc;
-	UINT			frame_type;
-	UINT			frame_subtype;
-    UINT			from_ds;
-    UINT			to_ds;
-	INT				a4_exists;
-	INT				qc_exists;
-	USHORT			duration;
-	USHORT			seq_control;
-	USHORT			qos_control;
-	UCHAR			TA[MAC_ADDR_LEN];
-	UCHAR			DA[MAC_ADDR_LEN];
-	UCHAR			SA[MAC_ADDR_LEN];
-	UCHAR			RC4Key[16];
-	UINT			p1k[5]; //for mix_key;
-	ULONG			pnl;/* Least significant 16 bits of PN */
-	ULONG			pnh;/* Most significant 32 bits of PN */
-	UINT			num_blocks;
-	UINT			payload_remainder;
-	ARCFOURCONTEXT	ArcFourContext;
-	UINT			crc32 = 0;
-	UINT			trailfcs = 0;
-	UCHAR			MIC[8];
-	UCHAR			TrailMIC[8];
-
-#ifdef RT_BIG_ENDIAN
-	RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
-#endif
-
-	fc0 = *pData;
-	fc1 = *(pData + 1);
-
-	fc = *((PUSHORT)pData);
-
-	frame_type = ((fc0 >> 2) & 0x03);
-	frame_subtype = ((fc0 >> 4) & 0x0f);
-
-    from_ds = (fc1 & 0x2) >> 1;
-    to_ds = (fc1 & 0x1);
-
-    a4_exists = (from_ds & to_ds);
-    qc_exists = ((frame_subtype == 0x08) ||    /* Assumed QoS subtypes */
-                  (frame_subtype == 0x09) ||   /* Likely to change.    */
-                  (frame_subtype == 0x0a) ||
-                  (frame_subtype == 0x0b)
-                 );
-
-	HeaderLen = 24;
-	if (a4_exists)
-		HeaderLen += 6;
-
-	KeyID = *((PUCHAR)(pData+ HeaderLen + 3));
-	KeyID = KeyID >> 6;
-
-	if (pWpaKey[KeyID].KeyLen == 0)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP failed!(KeyID[%d] Length can not be 0)\n", KeyID));
-		return FALSE;
-	}
-
-	duration = *((PUSHORT)(pData+2));
-
-	seq_control = *((PUSHORT)(pData+22));
-
-	if (qc_exists)
-	{
-		if (a4_exists)
-		{
-			qos_control = *((PUSHORT)(pData+30));
-		}
-		else
-		{
-			qos_control = *((PUSHORT)(pData+24));
-		}
-	}
-
-	if (to_ds == 0 && from_ds == 1)
-	{
-		NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN);
-		NdisMoveMemory(SA, pData+16, MAC_ADDR_LEN);
-		NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);  //BSSID
-	}
-	else if (to_ds == 0 && from_ds == 0 )
-	{
-		NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
-		NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN);
-		NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN);
-	}
-	else if (to_ds == 1 && from_ds == 0)
-	{
-		NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN);
-		NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
-		NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN);
-	}
-	else if (to_ds == 1 && from_ds == 1)
-	{
-		NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
-		NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN);
-		NdisMoveMemory(SA, pData+22, MAC_ADDR_LEN);
-	}
-
-	num_blocks = (DataByteCnt - 16) / 16;
-	payload_remainder = (DataByteCnt - 16) % 16;
-
-	pnl = (*(pData + HeaderLen)) * 256 + *(pData + HeaderLen + 2);
-	pnh = *((PULONG)(pData + HeaderLen + 4));
-	pnh = cpu2le32(pnh);
-	RTMPTkipMixKey(pWpaKey[KeyID].Key, TA, pnl, pnh, RC4Key, p1k);
-
-	ARCFOUR_INIT(&ArcFourContext, RC4Key, 16);
-
-	ARCFOUR_DECRYPT(&ArcFourContext, pData + HeaderLen, pData + HeaderLen + 8, DataByteCnt - HeaderLen - 8);
-	NdisMoveMemory(&trailfcs, pData + DataByteCnt - 8 - 4, 4);
-	crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 4);  //Skip IV+EIV 8 bytes & Skip last 4 bytes(FCS).
-	crc32 ^= 0xffffffff;             /* complement */
-
-    if(crc32 != cpu2le32(trailfcs))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP, WEP Data ICV Error !\n"));	 //ICV error.
-
-		return (FALSE);
-	}
-
-	NdisMoveMemory(TrailMIC, pData + DataByteCnt - 8 - 8 - 4, 8);
-	RTMPInitMICEngine(pAd, pWpaKey[KeyID].Key, DA, SA, UserPriority, pWpaKey[KeyID].RxMic);
-	RTMPTkipAppend(&pAd->PrivateInfo.Tx, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 12);
-	RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
-	NdisMoveMemory(MIC, pAd->PrivateInfo.Tx.MIC, 8);
-
-	if (!NdisEqualMemory(MIC, TrailMIC, 8))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptTKIP, WEP Data MIC Error !\n"));	 //MIC error.
-		//RTMPReportMicError(pAd, &pWpaKey[KeyID]);	// marked by AlbertY @ 20060630
-		return (FALSE);
-	}
-
-#ifdef RT_BIG_ENDIAN
-	RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
-#endif
-	//DBGPRINT(RT_DEBUG_TRACE, "RTMPSoftDecryptTKIP Decript done!!\n");
-	return TRUE;
-}
diff --git a/drivers/staging/rt3090/common/cmm_wep.c b/drivers/staging/rt3090/common/cmm_wep.c
deleted file mode 100644
index d8ddfb2..0000000
--- a/drivers/staging/rt3090/common/cmm_wep.c
+++ /dev/null
@@ -1,500 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtmp_wep.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Paul Wu		10-28-02		Initial
-*/
-
-#include "../rt_config.h"
-
-
-UINT FCSTAB_32[256] =
-{
-	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
-	0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
-	0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
-	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
-	0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
-	0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
-	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
-	0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
-	0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
-	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
-	0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
-	0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
-	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
-	0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
-	0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
-	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
-	0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
-	0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
-	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
-	0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
-	0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
-	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
-	0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
-	0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
-	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
-	0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
-	0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
-	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
-	0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
-	0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
-	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
-	0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
-	0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
-	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
-	0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
-	0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
-	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
-	0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
-	0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
-	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
-	0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
-	0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
-	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
-	0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
-	0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
-	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
-	0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
-	0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
-	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
-	0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
-	0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
-	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
-	0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
-	0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
-	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
-	0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
-	0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
-	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
-	0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
-	0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
-	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
-	0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
-	0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
-	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
-};
-
-/*
-UCHAR   WEPKEY[] = {
-		//IV
-		0x00, 0x11, 0x22,
-		//WEP KEY
-		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
-	};
- */
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Init WEP function.
-
-	Arguments:
-      pAd		Pointer to our adapter
-		pKey        Pointer to the WEP KEY
-		KeyId		   WEP Key ID
-		KeyLen      the length of WEP KEY
-		pDest       Pointer to the destination which Encryption data will store in.
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPInitWepEngine(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pKey,
-	IN	UCHAR			KeyId,
-	IN	UCHAR			KeyLen,
-	IN OUT	PUCHAR		pDest)
-{
-	UINT i;
-	UCHAR   WEPKEY[] = {
-		//IV
-		0x00, 0x11, 0x22,
-		//WEP KEY
-		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
-	};
-
-	pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32;   //Init crc32.
-
-    {
-		NdisMoveMemory(WEPKEY + 3, pKey, KeyLen);
-
-        for(i = 0; i < 3; i++)
-			WEPKEY[i] = RandomByte(pAd);   //Call mlme RandomByte() function.
-		ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, KeyLen + 3);  //INIT SBOX, KEYLEN+3(IV)
-
-		NdisMoveMemory(pDest, WEPKEY, 3);  //Append Init Vector
-    }
-	*(pDest+3) = (KeyId << 6);       //Append KEYID
-
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Encrypt transimitted data
-
-	Arguments:
-      pAd		Pointer to our adapter
-      pSrc        Pointer to the transimitted source data that will be encrypt
-      pDest       Pointer to the destination where entryption data will be store in.
-      Len			Indicate the length of the source data
-
-	Return Value:
-      None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPEncryptData(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pSrc,
-	IN	PUCHAR			pDest,
-	IN	UINT			Len)
-{
-	pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, pSrc, Len);
-	ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, pSrc, Len);
-}
-
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Decrypt received WEP data
-
-	Arguments:
-		pAdapter		Pointer to our adapter
-		pSrc        Pointer to the received data
-		Len         the length of the received data
-
-	Return Value:
-		TRUE        Decrypt WEP data success
-		FALSE       Decrypt WEP data failed
-
-	Note:
-
-	========================================================================
-*/
-BOOLEAN	RTMPSoftDecryptWEP(
-	IN PRTMP_ADAPTER	pAd,
-	IN PUCHAR			pData,
-	IN ULONG			DataByteCnt,
-	IN PCIPHER_KEY		pGroupKey)
-{
-	UINT	trailfcs;
-	UINT    crc32;
-	UCHAR	KeyIdx;
-	UCHAR   WEPKEY[] = {
-		//IV
-		0x00, 0x11, 0x22,
-		//WEP KEY
-		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
-	};
-	UCHAR	*pPayload = (UCHAR *)pData + LENGTH_802_11;
-	ULONG	payload_len = DataByteCnt - LENGTH_802_11;
-
-	NdisMoveMemory(WEPKEY, pPayload, 3);    //Get WEP IV
-
-	KeyIdx = (*(pPayload + 3) & 0xc0) >> 6;
-	if (pGroupKey[KeyIdx].KeyLen == 0)
-		return (FALSE);
-
-	NdisMoveMemory(WEPKEY + 3, pGroupKey[KeyIdx].Key, pGroupKey[KeyIdx].KeyLen);
-	ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, pGroupKey[KeyIdx].KeyLen + 3);
-	ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, pPayload, pPayload + 4, payload_len - 4);
-	NdisMoveMemory(&trailfcs, pPayload + payload_len - 8, 4);
-	crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pPayload, payload_len - 8);  //Skip last 4 bytes(FCS).
-	crc32 ^= 0xffffffff;             /* complement */
-
-    if(crc32 != cpu2le32(trailfcs))
-    {
-		DBGPRINT(RT_DEBUG_TRACE, ("! WEP Data CRC Error !\n"));	 //CRC error.
-		return (FALSE);
-	}
-	return (TRUE);
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		The Stream Cipher Encryption Algorithm "ARCFOUR" initialize
-
-	Arguments:
-	   Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
-		pKey        Pointer to the WEP KEY
-		KeyLen      Indicate the length fo the WEP KEY
-
-	Return Value:
-	   None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	ARCFOUR_INIT(
-	IN	PARCFOURCONTEXT	Ctx,
-	IN	PUCHAR			pKey,
-	IN	UINT			KeyLen)
-{
-	UCHAR	t, u;
-	UINT	keyindex;
-	UINT	stateindex;
-	PUCHAR	state;
-	UINT	counter;
-
-	state = Ctx->STATE;
-	Ctx->X = 0;
-	Ctx->Y = 0;
-	for (counter = 0; counter < 256; counter++)
-		state[counter] = (UCHAR)counter;
-	keyindex = 0;
-	stateindex = 0;
-	for (counter = 0; counter < 256; counter++)
-	{
-		t = state[counter];
-		stateindex = (stateindex + pKey[keyindex] + t) & 0xff;
-		u = state[stateindex];
-		state[stateindex] = t;
-		state[counter] = u;
-		if (++keyindex >= KeyLen)
-			keyindex = 0;
-	}
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Get bytes from ARCFOUR CONTEXT (S-BOX)
-
-	Arguments:
-	   Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
-
-	Return Value:
-	   UCHAR  - the value of the ARCFOUR CONTEXT (S-BOX)
-
-	Note:
-
-	========================================================================
-*/
-UCHAR	ARCFOUR_BYTE(
-	IN	PARCFOURCONTEXT		Ctx)
-{
-  UINT x;
-  UINT y;
-  UCHAR sx, sy;
-  PUCHAR state;
-
-  state = Ctx->STATE;
-  x = (Ctx->X + 1) & 0xff;
-  sx = state[x];
-  y = (sx + Ctx->Y) & 0xff;
-  sy = state[y];
-  Ctx->X = x;
-  Ctx->Y = y;
-  state[y] = sx;
-  state[x] = sy;
-
-  return(state[(sx + sy) & 0xff]);
-
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		The Stream Cipher Decryption Algorithm
-
-	Arguments:
-		Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
-		pDest			Pointer to the Destination
-		pSrc        Pointer to the Source data
-		Len         Indicate the length of the Source data
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	ARCFOUR_DECRYPT(
-	IN	PARCFOURCONTEXT	Ctx,
-	IN	PUCHAR			pDest,
-	IN	PUCHAR			pSrc,
-	IN	UINT			Len)
-{
-	UINT i;
-
-	for (i = 0; i < Len; i++)
-		pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		The Stream Cipher Encryption Algorithm
-
-	Arguments:
-		Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
-		pDest			Pointer to the Destination
-		pSrc        Pointer to the Source data
-		Len         Indicate the length of the Source dta
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	ARCFOUR_ENCRYPT(
-	IN	PARCFOURCONTEXT	Ctx,
-	IN	PUCHAR			pDest,
-	IN	PUCHAR			pSrc,
-	IN	UINT			Len)
-{
-	UINT i;
-
-	for (i = 0; i < Len; i++)
-		pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		The Stream Cipher Encryption Algorithm which conform to the special requirement to encrypt  GTK.
-
-	Arguments:
-		Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
-		pDest			Pointer to the Destination
-		pSrc        Pointer to the Source data
-		Len         Indicate the length of the Source dta
-
-
-	========================================================================
-*/
-
-VOID	WPAARCFOUR_ENCRYPT(
-	IN	PARCFOURCONTEXT	Ctx,
-	IN	PUCHAR			pDest,
-	IN	PUCHAR			pSrc,
-	IN	UINT			Len)
-{
-	UINT i;
-        //discard first 256 bytes
-	for (i = 0; i < 256; i++)
-            ARCFOUR_BYTE(Ctx);
-
-	for (i = 0; i < Len; i++)
-		pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
-}
-
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Calculate a new FCS given the current FCS and the new data.
-
-	Arguments:
-		Fcs	      the original FCS value
-		Cp          pointer to the data which will be calculate the FCS
-		Len         the length of the data
-
-	Return Value:
-		UINT - FCS 32 bits
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-UINT	RTMP_CALC_FCS32(
-	IN	UINT	Fcs,
-	IN	PUCHAR	Cp,
-	IN	INT		Len)
-{
-	while (Len--)
-	   Fcs = (((Fcs) >> 8) ^ FCSTAB_32[((Fcs) ^ (*Cp++)) & 0xff]);
-
-	return (Fcs);
-}
-
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Get last FCS and encrypt it to the destination
-
-	Arguments:
-		pDest			Pointer to the Destination
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPSetICV(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR	pDest)
-{
-	pAd->PrivateInfo.FCSCRC32 ^= 0xffffffff;             /* complement */
-	pAd->PrivateInfo.FCSCRC32 = cpu2le32(pAd->PrivateInfo.FCSCRC32);
-
-	ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, (PUCHAR) &pAd->PrivateInfo.FCSCRC32, 4);
-}
diff --git a/drivers/staging/rt3090/common/cmm_wpa.c b/drivers/staging/rt3090/common/cmm_wpa.c
deleted file mode 100644
index bf68ad8..0000000
--- a/drivers/staging/rt3090/common/cmm_wpa.c
+++ /dev/null
@@ -1,3149 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	wpa.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Jan	Lee		03-07-22		Initial
-	Paul Lin	03-11-28		Modify for supplicant
-*/
-
-#include "../rt_config.h"
-
-
-// WPA OUI
-UCHAR		OUI_WPA_NONE_AKM[4]		= {0x00, 0x50, 0xF2, 0x00};
-UCHAR       OUI_WPA_VERSION[4]      = {0x00, 0x50, 0xF2, 0x01};
-UCHAR       OUI_WPA_WEP40[4]      = {0x00, 0x50, 0xF2, 0x01};
-UCHAR       OUI_WPA_TKIP[4]     = {0x00, 0x50, 0xF2, 0x02};
-UCHAR       OUI_WPA_CCMP[4]     = {0x00, 0x50, 0xF2, 0x04};
-UCHAR       OUI_WPA_WEP104[4]      = {0x00, 0x50, 0xF2, 0x05};
-UCHAR       OUI_WPA_8021X_AKM[4]	= {0x00, 0x50, 0xF2, 0x01};
-UCHAR       OUI_WPA_PSK_AKM[4]      = {0x00, 0x50, 0xF2, 0x02};
-// WPA2 OUI
-UCHAR       OUI_WPA2_WEP40[4]   = {0x00, 0x0F, 0xAC, 0x01};
-UCHAR       OUI_WPA2_TKIP[4]        = {0x00, 0x0F, 0xAC, 0x02};
-UCHAR       OUI_WPA2_CCMP[4]        = {0x00, 0x0F, 0xAC, 0x04};
-UCHAR       OUI_WPA2_8021X_AKM[4]   = {0x00, 0x0F, 0xAC, 0x01};
-UCHAR       OUI_WPA2_PSK_AKM[4]		= {0x00, 0x0F, 0xAC, 0x02};
-UCHAR       OUI_WPA2_WEP104[4]   = {0x00, 0x0F, 0xAC, 0x05};
-
-
-
-static VOID	ConstructEapolKeyData(
-	IN	PMAC_TABLE_ENTRY	pEntry,
-	IN	UCHAR			GroupKeyWepStatus,
-	IN	UCHAR			keyDescVer,
-	IN	UCHAR			MsgType,
-	IN	UCHAR			DefaultKeyIdx,
-	IN	UCHAR			*GTK,
-	IN	UCHAR			*RSNIE,
-	IN	UCHAR			RSNIE_LEN,
-	OUT PEAPOL_PACKET   pMsg);
-
-static VOID	CalculateMIC(
-	IN	UCHAR			KeyDescVer,
-	IN	UCHAR			*PTK,
-	OUT PEAPOL_PACKET   pMsg);
-
-static VOID WpaEAPPacketAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
-
-static VOID WpaEAPOLASFAlertAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
-
-static VOID WpaEAPOLLogoffAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
-
-static VOID WpaEAPOLStartAction(
-    IN PRTMP_ADAPTER    pAd,
-    IN MLME_QUEUE_ELEM  *Elem);
-
-static VOID WpaEAPOLKeyAction(
-    IN PRTMP_ADAPTER    pAd,
-    IN MLME_QUEUE_ELEM  *Elem);
-
-/*
-    ==========================================================================
-    Description:
-        association state machine init, including state transition and timer init
-    Parameters:
-        S - pointer to the association state machine
-    ==========================================================================
- */
-VOID WpaStateMachineInit(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  STATE_MACHINE *S,
-    OUT STATE_MACHINE_FUNC Trans[])
-{
-    StateMachineInit(S, (STATE_MACHINE_FUNC *)Trans, MAX_WPA_PTK_STATE, MAX_WPA_MSG, (STATE_MACHINE_FUNC)Drop, WPA_PTK, WPA_MACHINE_BASE);
-
-    StateMachineSetAction(S, WPA_PTK, MT2_EAPPacket, (STATE_MACHINE_FUNC)WpaEAPPacketAction);
-    StateMachineSetAction(S, WPA_PTK, MT2_EAPOLStart, (STATE_MACHINE_FUNC)WpaEAPOLStartAction);
-    StateMachineSetAction(S, WPA_PTK, MT2_EAPOLLogoff, (STATE_MACHINE_FUNC)WpaEAPOLLogoffAction);
-    StateMachineSetAction(S, WPA_PTK, MT2_EAPOLKey, (STATE_MACHINE_FUNC)WpaEAPOLKeyAction);
-    StateMachineSetAction(S, WPA_PTK, MT2_EAPOLASFAlert, (STATE_MACHINE_FUNC)WpaEAPOLASFAlertAction);
-}
-
-/*
-    ==========================================================================
-    Description:
-        this is state machine function.
-        When receiving EAP packets which is  for 802.1x authentication use.
-        Not use in PSK case
-    Return:
-    ==========================================================================
-*/
-VOID WpaEAPPacketAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
-{
-}
-
-VOID WpaEAPOLASFAlertAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
-{
-}
-
-VOID WpaEAPOLLogoffAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
-{
-}
-
-/*
-    ==========================================================================
-    Description:
-       Start 4-way HS when rcv EAPOL_START which may create by our driver in assoc.c
-    Return:
-    ==========================================================================
-*/
-VOID WpaEAPOLStartAction(
-    IN PRTMP_ADAPTER    pAd,
-    IN MLME_QUEUE_ELEM  *Elem)
-{
-    MAC_TABLE_ENTRY     *pEntry;
-    PHEADER_802_11      pHeader;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLStartAction ===> \n"));
-
-    pHeader = (PHEADER_802_11)Elem->Msg;
-
-    //For normaol PSK, we enqueue an EAPOL-Start command to trigger the process.
-    if (Elem->MsgLen == 6)
-        pEntry = MacTableLookup(pAd, Elem->Msg);
-    else
-    {
-        pEntry = MacTableLookup(pAd, pHeader->Addr2);
-    }
-
-    if (pEntry)
-    {
-		DBGPRINT(RT_DEBUG_TRACE, (" PortSecured(%d), WpaState(%d), AuthMode(%d), PMKID_CacheIdx(%d) \n", pEntry->PortSecured, pEntry->WpaState, pEntry->AuthMode, pEntry->PMKID_CacheIdx));
-
-        if ((pEntry->PortSecured == WPA_802_1X_PORT_NOT_SECURED)
-			&& (pEntry->WpaState < AS_PTKSTART)
-            && ((pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) || ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) && (pEntry->PMKID_CacheIdx != ENTRY_NOT_FOUND))))
-        {
-            pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
-            pEntry->WpaState = AS_INITPSK;
-            pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-            NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter));
-            pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
-
-            WPAStart4WayHS(pAd, pEntry, PEER_MSG1_RETRY_EXEC_INTV);
-        }
-    }
-}
-
-/*
-    ==========================================================================
-    Description:
-        This is state machine function.
-        When receiving EAPOL packets which is  for 802.1x key management.
-        Use both in WPA, and WPAPSK case.
-        In this function, further dispatch to different functions according to the received packet.  3 categories are :
-          1.  normal 4-way pairwisekey and 2-way groupkey handshake
-          2.  MIC error (Countermeasures attack)  report packet from STA.
-          3.  Request for pairwise/group key update from STA
-    Return:
-    ==========================================================================
-*/
-VOID WpaEAPOLKeyAction(
-    IN PRTMP_ADAPTER    pAd,
-    IN MLME_QUEUE_ELEM  *Elem)
-{
-    MAC_TABLE_ENTRY     *pEntry;
-    PHEADER_802_11      pHeader;
-    PEAPOL_PACKET       pEapol_packet;
-	KEY_INFO			peerKeyInfo;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLKeyAction ===>\n"));
-
-    pHeader = (PHEADER_802_11)Elem->Msg;
-    pEapol_packet = (PEAPOL_PACKET)&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
-
-	NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
-	NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pEapol_packet->KeyDesc.KeyInfo, sizeof(KEY_INFO));
-
-	hex_dump("Received Eapol frame", (unsigned char *)pEapol_packet, (Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H));
-
-	*((USHORT *)&peerKeyInfo) = cpu2le16(*((USHORT *)&peerKeyInfo));
-
-    do
-    {
-        pEntry = MacTableLookup(pAd, pHeader->Addr2);
-
-		if (!pEntry || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
-            break;
-
-		if (pEntry->AuthMode < Ndis802_11AuthModeWPA)
-				break;
-
-		DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPoL-Key frame from STA %02X-%02X-%02X-%02X-%02X-%02X\n", PRINT_MAC(pEntry->Addr)));
-
-        if (((pEapol_packet->ProVer != EAPOL_VER) && (pEapol_packet->ProVer != EAPOL_VER2)) ||
-			((pEapol_packet->KeyDesc.Type != WPA1_KEY_DESC) && (pEapol_packet->KeyDesc.Type != WPA2_KEY_DESC)))
-        {
-            DBGPRINT(RT_DEBUG_ERROR, ("Key descripter does not match with WPA rule\n"));
-            break;
-        }
-
-		// The value 1 shall be used for all EAPOL-Key frames to and from a STA when
-		// neither the group nor pairwise ciphers are CCMP for Key Descriptor 1.
-		if ((pEntry->WepStatus == Ndis802_11Encryption2Enabled) && (peerKeyInfo.KeyDescVer != DESC_TYPE_TKIP))
-        {
-	        DBGPRINT(RT_DEBUG_ERROR, ("Key descripter version not match(TKIP) \n"));
-	    break;
-	}
-		// The value 2 shall be used for all EAPOL-Key frames to and from a STA when
-		// either the pairwise or the group cipher is AES-CCMP for Key Descriptor 2.
-	else if ((pEntry->WepStatus == Ndis802_11Encryption3Enabled) && (peerKeyInfo.KeyDescVer != DESC_TYPE_AES))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Key descripter version not match(AES) \n"));
-		break;
-	}
-
-		// Check if this STA is in class 3 state and the WPA state is started
-        if ((pEntry->Sst == SST_ASSOC) && (pEntry->WpaState >= AS_INITPSK))
-        {
-			// Check the Key Ack (bit 7) of the Key Information to determine the Authenticator
-			// or not.
-			// An EAPOL-Key frame that is sent by the Supplicant in response to an EAPOL-
-			// Key frame from the Authenticator must not have the Ack bit set.
-			if (peerKeyInfo.KeyAck == 1)
-			{
-				// The frame is snet by Authenticator.
-				// So the Supplicant side shall handle this.
-
-				if ((peerKeyInfo.Secure == 0) && (peerKeyInfo.Request == 0) &&
-					(peerKeyInfo.Error == 0) && (peerKeyInfo.KeyType == PAIRWISEKEY))
-				{
-					// Process 1. the message 1 of 4-way HS in WPA or WPA2
-					//			  EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1)
-					//		   2. the message 3 of 4-way HS in WPA
-					//			  EAPOL-Key(0,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3)
-					if (peerKeyInfo.KeyMic == 0)
-			PeerPairMsg1Action(pAd, pEntry, Elem);
-	                else
-	                PeerPairMsg3Action(pAd, pEntry, Elem);
-				}
-				else if ((peerKeyInfo.Secure == 1) &&
-						 (peerKeyInfo.KeyMic == 1) &&
-						 (peerKeyInfo.Request == 0) &&
-						 (peerKeyInfo.Error == 0))
-				{
-					// Process 1. the message 3 of 4-way HS in WPA2
-					//			  EAPOL-Key(1,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3)
-					//		   2. the message 1 of group KS in WPA or WPA2
-					//			  EAPOL-Key(1,1,1,0,G,0,Key RSC,0, MIC,GTK[N])
-					if (peerKeyInfo.KeyType == PAIRWISEKEY)
-						PeerPairMsg3Action(pAd, pEntry, Elem);
-					else
-						PeerGroupMsg1Action(pAd, pEntry, Elem);
-				}
-			}
-			else
-			{
-				// The frame is snet by Supplicant.
-				// So the Authenticator side shall handle this.
-				if ((peerKeyInfo.Request == 0) &&
-						 (peerKeyInfo.Error == 0) &&
-						 (peerKeyInfo.KeyMic == 1))
-				{
-					if (peerKeyInfo.Secure == 0 && peerKeyInfo.KeyType == PAIRWISEKEY)
-					{
-						// EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,Data)
-						// Process 1. message 2 of 4-way HS in WPA or WPA2
-						//		   2. message 4 of 4-way HS in WPA
-						if (CONV_ARRARY_TO_UINT16(pEapol_packet->KeyDesc.KeyDataLen) == 0)
-						{
-							PeerPairMsg4Action(pAd, pEntry, Elem);
-			}
-						else
-						{
-							PeerPairMsg2Action(pAd, pEntry, Elem);
-						}
-					}
-					else if (peerKeyInfo.Secure == 1 && peerKeyInfo.KeyType == PAIRWISEKEY)
-					{
-						// EAPOL-Key(1,1,0,0,P,0,0,0,MIC,0)
-						// Process message 4 of 4-way HS in WPA2
-						PeerPairMsg4Action(pAd, pEntry, Elem);
-					}
-					else if (peerKeyInfo.Secure == 1 && peerKeyInfo.KeyType == GROUPKEY)
-					{
-						// EAPOL-Key(1,1,0,0,G,0,0,0,MIC,0)
-						// Process message 2 of Group key HS in WPA or WPA2
-						PeerGroupMsg2Action(pAd, pEntry, &Elem->Msg[LENGTH_802_11], (Elem->MsgLen - LENGTH_802_11));
-					}
-				}
-			}
-        }
-    }while(FALSE);
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Copy frame from waiting queue into relative ring buffer and set
-	appropriate ASIC register to kick hardware encryption before really
-	sent out to air.
-
-	Arguments:
-		pAd		Pointer	to our adapter
-		PNDIS_PACKET	Pointer to outgoing Ndis frame
-		NumberOfFrag	Number of fragment required
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID    RTMPToWirelessSta(
-    IN  PRTMP_ADAPTER		pAd,
-    IN  PMAC_TABLE_ENTRY	pEntry,
-    IN  PUCHAR			pHeader802_3,
-    IN  UINT			HdrLen,
-    IN  PUCHAR			pData,
-    IN  UINT			DataLen,
-    IN	BOOLEAN				bClearFrame)
-{
-    PNDIS_PACKET    pPacket;
-    NDIS_STATUS     Status;
-
-	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
-		return;
-
-    do {
-		// build a NDIS packet
-		Status = RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen, pData, DataLen);
-		if (Status != NDIS_STATUS_SUCCESS)
-		break;
-
-
-			if (bClearFrame)
-				RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1);
-			else
-				RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0);
-		{
-			RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
-
-			RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket, MAIN_MBSSID);	// set a default value
-			if(pEntry->apidx != 0)
-			RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket, pEntry->apidx);
-
-		RTMP_SET_PACKET_WCID(pPacket, (UCHAR)pEntry->Aid);
-			RTMP_SET_PACKET_MOREDATA(pPacket, FALSE);
-		}
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-		    // send out the packet
-	        Status = STASendPacket(pAd, pPacket);
-	    if (Status == NDIS_STATUS_SUCCESS)
-			{
-				UCHAR   Index;
-
-				// Dequeue one frame from TxSwQueue0..3 queue and process it
-				// There are three place calling dequeue for TX ring.
-				// 1. Here, right after queueing the frame.
-				// 2. At the end of TxRingTxDone service routine.
-				// 3. Upon NDIS call RTMPSendPackets
-				if((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
-					(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)))
-				{
-					for(Index = 0; Index < 5; Index ++)
-						if(pAd->TxSwQueue[Index].Number > 0)
-							RTMPDeQueuePacket(pAd, FALSE, Index, MAX_TX_PROCESS);
-				}
-			}
-		}
-#endif // CONFIG_STA_SUPPORT //
-
-    } while (FALSE);
-}
-
-/*
-    ==========================================================================
-    Description:
-        This is a function to initilize 4-way handshake
-
-    Return:
-
-    ==========================================================================
-*/
-VOID WPAStart4WayHS(
-    IN PRTMP_ADAPTER    pAd,
-    IN MAC_TABLE_ENTRY  *pEntry,
-    IN ULONG			TimeInterval)
-{
-    UCHAR           Header802_3[14];
-    EAPOL_PACKET	EAPOLPKT;
-	PUINT8			pBssid = NULL;
-	UCHAR			group_cipher = Ndis802_11WEPDisabled;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart4WayHS\n"));
-
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]WPAStart4WayHS : The interface is closed...\n"));
-		return;
-	}
-
-
-	if (pBssid == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]WPAStart4WayHS : No corresponding Authenticator.\n"));
-		return;
-    }
-
-	// Check the status
-    if ((pEntry->WpaState > AS_PTKSTART) || (pEntry->WpaState < AS_INITPMK))
-    {
-        DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]WPAStart4WayHS : Not expect calling\n"));
-        return;
-    }
-
-
-	// Increment replay counter by 1
-	ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
-
-	// Randomly generate ANonce
-	GenRandom(pAd, (UCHAR *)pBssid, pEntry->ANonce);
-
-	// Construct EAPoL message - Pairwise Msg 1
-	// EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1)
-	NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET));
-	ConstructEapolMsg(pEntry,
-					  group_cipher,
-					  EAPOL_PAIR_MSG_1,
-					  0,					// Default key index
-					  pEntry->ANonce,
-					  NULL,					// TxRSC
-					  NULL,					// GTK
-					  NULL,					// RSNIE
-					  0,					// RSNIE length
-					  &EAPOLPKT);
-
-
-	// Make outgoing frame
-    MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
-    RTMPToWirelessSta(pAd, pEntry, Header802_3,
-					  LENGTH_802_3, (PUCHAR)&EAPOLPKT,
-					  CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4,
-					  (pEntry->PortSecured == WPA_802_1X_PORT_SECURED) ? FALSE : TRUE);
-
-	// Trigger Retry Timer
-    RTMPModTimer(&pEntry->RetryTimer, TimeInterval);
-
-	// Update State
-    pEntry->WpaState = AS_PTKSTART;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== WPAStart4WayHS: send Msg1 of 4-way \n"));
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Process Pairwise key Msg-1 of 4-way handshaking and send Msg-2
-
-	Arguments:
-		pAd			Pointer	to our adapter
-		Elem		Message body
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID PeerPairMsg1Action(
-	IN PRTMP_ADAPTER    pAd,
-    IN MAC_TABLE_ENTRY  *pEntry,
-    IN MLME_QUEUE_ELEM  *Elem)
-{
-	UCHAR				PTK[80];
-	UCHAR               Header802_3[14];
-	PEAPOL_PACKET		pMsg1;
-	UINT			MsgLen;
-	EAPOL_PACKET		EAPOLPKT;
-	PUINT8				pCurrentAddr = NULL;
-	PUINT8				pmk_ptr = NULL;
-	UCHAR				group_cipher = Ndis802_11WEPDisabled;
-	PUINT8				rsnie_ptr = NULL;
-	UCHAR				rsnie_len = 0;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg1Action \n"));
-
-	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
-		return;
-
-    if (Elem->MsgLen < (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE - 2))
-        return;
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		pCurrentAddr = pAd->CurrentAddress;
-		pmk_ptr = pAd->StaCfg.PMK;
-		group_cipher = pAd->StaCfg.GroupCipher;
-		rsnie_ptr = pAd->StaCfg.RSN_IE;
-		rsnie_len = pAd->StaCfg.RSNIE_Len;
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	// Store the received frame
-	pMsg1 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
-	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
-
-	// Sanity Check peer Pairwise message 1 - Replay Counter
-	if (PeerWpaMessageSanity(pAd, pMsg1, MsgLen, EAPOL_PAIR_MSG_1, pEntry) == FALSE)
-		return;
-
-	// Store Replay counter, it will use to verify message 3 and construct message 2
-	NdisMoveMemory(pEntry->R_Counter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
-
-	// Store ANonce
-	NdisMoveMemory(pEntry->ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE);
-
-	// Generate random SNonce
-	GenRandom(pAd, (UCHAR *)pCurrentAddr, pEntry->SNonce);
-
-	{
-	    // Calculate PTK(ANonce, SNonce)
-	    WpaDerivePTK(pAd,
-				pmk_ptr,
-				pEntry->ANonce,
-					pEntry->Addr,
-					pEntry->SNonce,
-					pCurrentAddr,
-				    PTK,
-				    LEN_PTK);
-
-		// Save key to PTK entry
-		NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK);
-	}
-
-	// Update WpaState
-	pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
-
-	// Construct EAPoL message - Pairwise Msg 2
-	//  EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,DataKD_M2)
-	NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET));
-	ConstructEapolMsg(pEntry,
-					  group_cipher,
-					  EAPOL_PAIR_MSG_2,
-					  0,				// DefaultKeyIdx
-					  pEntry->SNonce,
-					  NULL,				// TxRsc
-					  NULL,				// GTK
-					  (UCHAR *)rsnie_ptr,
-					  rsnie_len,
-					  &EAPOLPKT);
-
-	// Make outgoing frame
-	MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
-
-	RTMPToWirelessSta(pAd, pEntry,
-					  Header802_3, sizeof(Header802_3), (PUCHAR)&EAPOLPKT,
-					  CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4, TRUE);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== PeerPairMsg1Action: send Msg2 of 4-way \n"));
-}
-
-
-/*
-    ==========================================================================
-    Description:
-        When receiving the second packet of 4-way pairwisekey handshake.
-    Return:
-    ==========================================================================
-*/
-VOID PeerPairMsg2Action(
-    IN PRTMP_ADAPTER    pAd,
-    IN MAC_TABLE_ENTRY  *pEntry,
-    IN MLME_QUEUE_ELEM  *Elem)
-{
-	UCHAR				PTK[80];
-    BOOLEAN             Cancelled;
-    PHEADER_802_11      pHeader;
-	EAPOL_PACKET        EAPOLPKT;
-	PEAPOL_PACKET       pMsg2;
-	UINT			MsgLen;
-    UCHAR               Header802_3[LENGTH_802_3];
-	UCHAR				TxTsc[6];
-	PUINT8				pBssid = NULL;
-	PUINT8				pmk_ptr = NULL;
-	PUINT8				gtk_ptr = NULL;
-	UCHAR				default_key = 0;
-	UCHAR				group_cipher = Ndis802_11WEPDisabled;
-	PUINT8				rsnie_ptr = NULL;
-	UCHAR				rsnie_len = 0;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg2Action \n"));
-
-    if ((!pEntry) || (!pEntry->ValidAsCLI))
-        return;
-
-    if (Elem->MsgLen < (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE - 2))
-        return;
-
-    // check Entry in valid State
-    if (pEntry->WpaState < AS_PTKSTART)
-        return;
-
-
-
-    // pointer to 802.11 header
-	pHeader = (PHEADER_802_11)Elem->Msg;
-
-	// skip 802.11_header(24-byte) and LLC_header(8)
-	pMsg2 = (PEAPOL_PACKET)&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
-	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
-
-	// Store SNonce
-	NdisMoveMemory(pEntry->SNonce, pMsg2->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE);
-
-	{
-		// Derive PTK
-		WpaDerivePTK(pAd,
-					(UCHAR *)pmk_ptr,
-					pEntry->ANonce,			// ANONCE
-					(UCHAR *)pBssid,
-					pEntry->SNonce,			// SNONCE
-					pEntry->Addr,
-					PTK,
-					LEN_PTK);
-
-	NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK);
-	}
-
-	// Sanity Check peer Pairwise message 2 - Replay Counter, MIC, RSNIE
-	if (PeerWpaMessageSanity(pAd, pMsg2, MsgLen, EAPOL_PAIR_MSG_2, pEntry) == FALSE)
-		return;
-
-    do
-    {
-        // delete retry timer
-		RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
-
-		// Change state
-        pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
-
-		// Increment replay counter by 1
-		ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
-
-		// Construct EAPoL message - Pairwise Msg 3
-		NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET));
-		ConstructEapolMsg(pEntry,
-						  group_cipher,
-						  EAPOL_PAIR_MSG_3,
-						  default_key,
-						  pEntry->ANonce,
-						  TxTsc,
-						  (UCHAR *)gtk_ptr,
-						  (UCHAR *)rsnie_ptr,
-						  rsnie_len,
-						  &EAPOLPKT);
-
-        // Make outgoing frame
-        MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
-        RTMPToWirelessSta(pAd, pEntry, Header802_3, LENGTH_802_3,
-						  (PUCHAR)&EAPOLPKT,
-						  CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4,
-						  (pEntry->PortSecured == WPA_802_1X_PORT_SECURED) ? FALSE : TRUE);
-
-        pEntry->ReTryCounter = PEER_MSG3_RETRY_TIMER_CTR;
-		RTMPSetTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV);
-
-		// Update State
-        pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
-    }while(FALSE);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== PeerPairMsg2Action: send Msg3 of 4-way \n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Process Pairwise key Msg 3 of 4-way handshaking and send Msg 4
-
-	Arguments:
-		pAd	Pointer	to our adapter
-		Elem		Message body
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID PeerPairMsg3Action(
-    IN PRTMP_ADAPTER    pAd,
-    IN MAC_TABLE_ENTRY  *pEntry,
-    IN MLME_QUEUE_ELEM  *Elem)
-{
-	PHEADER_802_11		pHeader;
-	UCHAR               Header802_3[14];
-	EAPOL_PACKET		EAPOLPKT;
-	PEAPOL_PACKET		pMsg3;
-	UINT			MsgLen;
-	PUINT8				pCurrentAddr = NULL;
-	UCHAR				group_cipher = Ndis802_11WEPDisabled;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg3Action \n"));
-
-	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
-		return;
-
-    if (Elem->MsgLen < (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE - 2))
-		return;
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		pCurrentAddr = pAd->CurrentAddress;
-		group_cipher = pAd->StaCfg.GroupCipher;
-
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	// Record 802.11 header & the received EAPOL packet Msg3
-	pHeader	= (PHEADER_802_11) Elem->Msg;
-	pMsg3 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
-	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
-
-	// Sanity Check peer Pairwise message 3 - Replay Counter, MIC, RSNIE
-	if (PeerWpaMessageSanity(pAd, pMsg3, MsgLen, EAPOL_PAIR_MSG_3, pEntry) == FALSE)
-		return;
-
-	// Save Replay counter, it will use construct message 4
-	NdisMoveMemory(pEntry->R_Counter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
-
-	// Double check ANonce
-	if (!NdisEqualMemory(pEntry->ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE))
-	{
-		return;
-	}
-
-	// Construct EAPoL message - Pairwise Msg 4
-	NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET));
-	ConstructEapolMsg(pEntry,
-					  group_cipher,
-					  EAPOL_PAIR_MSG_4,
-					  0,					// group key index not used in message 4
-					  NULL,					// Nonce not used in message 4
-					  NULL,					// TxRSC not used in message 4
-					  NULL,					// GTK not used in message 4
-					  NULL,					// RSN IE not used in message 4
-					  0,
-					  &EAPOLPKT);
-
-	// Update WpaState
-	pEntry->WpaState = AS_PTKINITDONE;
-
-	// Update pairwise key
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		PCIPHER_KEY pSharedKey;
-
-		pSharedKey = &pAd->SharedKey[BSS0][0];
-
-		NdisMoveMemory(pAd->StaCfg.PTK, pEntry->PTK, LEN_PTK);
-
-		// Prepare pair-wise key information into shared key table
-		NdisZeroMemory(pSharedKey, sizeof(CIPHER_KEY));
-		pSharedKey->KeyLen = LEN_TKIP_EK;
-	    NdisMoveMemory(pSharedKey->Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
-		NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
-		NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
-
-		// Decide its ChiperAlg
-		if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
-			pSharedKey->CipherAlg = CIPHER_TKIP;
-		else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
-			pSharedKey->CipherAlg = CIPHER_AES;
-		else
-			pSharedKey->CipherAlg = CIPHER_NONE;
-
-		// Update these related information to MAC_TABLE_ENTRY
-		pEntry = &pAd->MacTab.Content[BSSID_WCID];
-		NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
-		NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
-		NdisMoveMemory(pEntry->PairwiseKey.TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
-		pEntry->PairwiseKey.CipherAlg = pSharedKey->CipherAlg;
-
-		// Update pairwise key information to ASIC Shared Key Table
-		AsicAddSharedKeyEntry(pAd,
-							  BSS0,
-							  0,
-							  pSharedKey->CipherAlg,
-							  pSharedKey->Key,
-							  pSharedKey->TxMic,
-							  pSharedKey->RxMic);
-
-		// Update ASIC WCID attribute table and IVEIV table
-		RTMPAddWcidAttributeEntry(pAd,
-								  BSS0,
-								  0,
-								  pSharedKey->CipherAlg,
-								  pEntry);
-
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	// open 802.1x port control and privacy filter
-	if (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK ||
-		pEntry->AuthMode == Ndis802_11AuthModeWPA2)
-	{
-		pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
-		pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
-
-#ifdef CONFIG_STA_SUPPORT
-		STA_PORT_SECURED(pAd);
-	    // Indicate Connected for GUI
-	    pAd->IndicateMediaState = NdisMediaStateConnected;
-#endif // CONFIG_STA_SUPPORT //
-		DBGPRINT(RT_DEBUG_TRACE, ("PeerPairMsg3Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n",
-									GetAuthMode(pEntry->AuthMode),
-									GetEncryptType(pEntry->WepStatus),
-									GetEncryptType(group_cipher)));
-	}
-	else
-	{
-	}
-
-	// Init 802.3 header and send out
-	MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
-	RTMPToWirelessSta(pAd, pEntry,
-					  Header802_3, sizeof(Header802_3),
-					  (PUCHAR)&EAPOLPKT,
-					  CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4, TRUE);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== PeerPairMsg3Action: send Msg4 of 4-way \n"));
-}
-
-/*
-    ==========================================================================
-    Description:
-        When receiving the last packet of 4-way pairwisekey handshake.
-        Initilize 2-way groupkey handshake following.
-    Return:
-    ==========================================================================
-*/
-VOID PeerPairMsg4Action(
-    IN PRTMP_ADAPTER    pAd,
-    IN MAC_TABLE_ENTRY  *pEntry,
-    IN MLME_QUEUE_ELEM  *Elem)
-{
-	PEAPOL_PACKET		pMsg4;
-    PHEADER_802_11      pHeader;
-    UINT		MsgLen;
-    BOOLEAN             Cancelled;
-	UCHAR				group_cipher = Ndis802_11WEPDisabled;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg4Action\n"));
-
-    do
-    {
-        if ((!pEntry) || (!pEntry->ValidAsCLI))
-            break;
-
-        if (Elem->MsgLen < (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE - 2 ) )
-            break;
-
-        if (pEntry->WpaState < AS_PTKINIT_NEGOTIATING)
-            break;
-
-
-        // pointer to 802.11 header
-        pHeader = (PHEADER_802_11)Elem->Msg;
-
-		// skip 802.11_header(24-byte) and LLC_header(8)
-		pMsg4 = (PEAPOL_PACKET)&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
-		MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
-
-        // Sanity Check peer Pairwise message 4 - Replay Counter, MIC
-		if (PeerWpaMessageSanity(pAd, pMsg4, MsgLen, EAPOL_PAIR_MSG_4, pEntry) == FALSE)
-			break;
-
-        // 3. uses the MLME.SETKEYS.request to configure PTK into MAC
-        NdisZeroMemory(&pEntry->PairwiseKey, sizeof(CIPHER_KEY));
-
-		// reset IVEIV in Asic
-		AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, 1, 0);
-
-        pEntry->PairwiseKey.KeyLen = LEN_TKIP_EK;
-        NdisMoveMemory(pEntry->PairwiseKey.Key, &pEntry->PTK[32], LEN_TKIP_EK);
-        NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pEntry->PTK[TKIP_AP_RXMICK_OFFSET], LEN_TKIP_RXMICK);
-        NdisMoveMemory(pEntry->PairwiseKey.TxMic, &pEntry->PTK[TKIP_AP_TXMICK_OFFSET], LEN_TKIP_TXMICK);
-
-		// Set pairwise key to Asic
-        {
-            pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
-            if (pEntry->WepStatus == Ndis802_11Encryption2Enabled)
-                pEntry->PairwiseKey.CipherAlg = CIPHER_TKIP;
-            else if (pEntry->WepStatus == Ndis802_11Encryption3Enabled)
-                pEntry->PairwiseKey.CipherAlg = CIPHER_AES;
-
-			// Add Pair-wise key to Asic
-            AsicAddPairwiseKeyEntry(
-                pAd,
-                pEntry->Addr,
-                (UCHAR)pEntry->Aid,
-                &pEntry->PairwiseKey);
-
-			// update WCID attribute table and IVEIV table for this entry
-			RTMPAddWcidAttributeEntry(
-				pAd,
-				pEntry->apidx,
-				0,
-				pEntry->PairwiseKey.CipherAlg,
-				pEntry);
-        }
-
-        // 4. upgrade state
-        pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
-        pEntry->WpaState = AS_PTKINITDONE;
-		pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
-
-
-		if (pEntry->AuthMode == Ndis802_11AuthModeWPA2 ||
-			pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)
-		{
-			pEntry->GTKState = REKEY_ESTABLISHED;
-			RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
-
-
-			// send wireless event - for set key done WPA2
-			if (pAd->CommonCfg.bWirelessEvent)
-				RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
-
-	        DBGPRINT(RT_DEBUG_OFF, ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
-									pEntry->AuthMode, GetAuthMode(pEntry->AuthMode),
-									pEntry->WepStatus, GetEncryptType(pEntry->WepStatus),
-									group_cipher,
-									GetEncryptType(group_cipher)));
-		}
-		else
-		{
-		// 5. init Group 2-way handshake if necessary.
-	        WPAStart2WayGroupHS(pAd, pEntry);
-
-		pEntry->ReTryCounter = GROUP_MSG1_RETRY_TIMER_CTR;
-			RTMPModTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV);
-		}
-    }while(FALSE);
-
-}
-
-/*
-    ==========================================================================
-    Description:
-        This is a function to send the first packet of 2-way groupkey handshake
-    Return:
-
-    ==========================================================================
-*/
-VOID WPAStart2WayGroupHS(
-    IN PRTMP_ADAPTER    pAd,
-    IN MAC_TABLE_ENTRY  *pEntry)
-{
-    UCHAR               Header802_3[14];
-	UCHAR				TxTsc[6];
-    EAPOL_PACKET	EAPOLPKT;
-	UCHAR				group_cipher = Ndis802_11WEPDisabled;
-	UCHAR				default_key = 0;
-	PUINT8				gnonce_ptr = NULL;
-	PUINT8				gtk_ptr = NULL;
-	PUINT8				pBssid = NULL;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart2WayGroupHS\n"));
-
-    if ((!pEntry) || (!pEntry->ValidAsCLI))
-        return;
-
-
-    do
-    {
-        // Increment replay counter by 1
-		ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
-
-		// Construct EAPoL message - Group Msg 1
-		NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET));
-		ConstructEapolMsg(pEntry,
-						  group_cipher,
-						  EAPOL_GROUP_MSG_1,
-						  default_key,
-						  (UCHAR *)gnonce_ptr,
-						  TxTsc,
-						  (UCHAR *)gtk_ptr,
-						  NULL,
-						  0,
-						  &EAPOLPKT);
-
-		// Make outgoing frame
-        MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
-        RTMPToWirelessSta(pAd, pEntry,
-						  Header802_3, LENGTH_802_3,
-						  (PUCHAR)&EAPOLPKT,
-						  CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4, FALSE);
-
-
-
-    }while (FALSE);
-
-    DBGPRINT(RT_DEBUG_TRACE, ("<=== WPAStart2WayGroupHS : send out Group Message 1 \n"));
-
-    return;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Process Group key 2-way handshaking
-
-	Arguments:
-		pAd	Pointer	to our adapter
-		Elem		Message body
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	PeerGroupMsg1Action(
-	IN PRTMP_ADAPTER    pAd,
-    IN MAC_TABLE_ENTRY  *pEntry,
-    IN MLME_QUEUE_ELEM  *Elem)
-{
-    UCHAR               Header802_3[14];
-	EAPOL_PACKET		EAPOLPKT;
-	PEAPOL_PACKET		pGroup;
-	UINT			MsgLen;
-	BOOLEAN             Cancelled;
-	UCHAR				default_key = 0;
-	UCHAR				group_cipher = Ndis802_11WEPDisabled;
-	PUINT8				pCurrentAddr = NULL;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg1Action \n"));
-
-	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
-        return;
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		pCurrentAddr = pAd->CurrentAddress;
-		group_cipher = pAd->StaCfg.GroupCipher;
-		default_key = pAd->StaCfg.DefaultKeyId;
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	// Process Group Message 1 frame. skip 802.11 header(24) & LLC_SNAP header(8)
-	pGroup = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
-	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
-
-	// Sanity Check peer group message 1 - Replay Counter, MIC, RSNIE
-	if (PeerWpaMessageSanity(pAd, pGroup, MsgLen, EAPOL_GROUP_MSG_1, pEntry) == FALSE)
-		return;
-
-	// delete retry timer
-	RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
-
-	// Save Replay counter, it will use to construct message 2
-	NdisMoveMemory(pEntry->R_Counter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
-
-	// Construct EAPoL message - Group Msg 2
-	NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET));
-	ConstructEapolMsg(pEntry,
-					  group_cipher,
-					  EAPOL_GROUP_MSG_2,
-					  default_key,
-					  NULL,					// Nonce not used
-					  NULL,					// TxRSC not used
-					  NULL,					// GTK not used
-					  NULL,					// RSN IE not used
-					  0,
-					  &EAPOLPKT);
-
-    // open 802.1x port control and privacy filter
-	pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
-	pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
-
-#ifdef CONFIG_STA_SUPPORT
-	STA_PORT_SECURED(pAd);
-    // Indicate Connected for GUI
-    pAd->IndicateMediaState = NdisMediaStateConnected;
-#endif // CONFIG_STA_SUPPORT //
-
-	DBGPRINT(RT_DEBUG_TRACE, ("PeerGroupMsg1Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n",
-									GetAuthMode(pEntry->AuthMode),
-									GetEncryptType(pEntry->WepStatus),
-									GetEncryptType(group_cipher)));
-
-	// init header and Fill Packet and send Msg 2 to authenticator
-	MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
-	RTMPToWirelessSta(pAd, pEntry,
-					  Header802_3, sizeof(Header802_3),
-					  (PUCHAR)&EAPOLPKT,
-					  CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4, FALSE);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== PeerGroupMsg1Action: sned group message 2\n"));
-}
-
-/*
-    ==========================================================================
-    Description:
-        When receiving the last packet of 2-way groupkey handshake.
-    Return:
-    ==========================================================================
-*/
-VOID PeerGroupMsg2Action(
-    IN PRTMP_ADAPTER    pAd,
-    IN MAC_TABLE_ENTRY  *pEntry,
-    IN VOID             *Msg,
-    IN UINT             MsgLen)
-{
-    UINT		Len;
-    PUCHAR		pData;
-    BOOLEAN		Cancelled;
-	PEAPOL_PACKET       pMsg2;
-	UCHAR				group_cipher = Ndis802_11WEPDisabled;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg2Action \n"));
-
-    do
-    {
-        if ((!pEntry) || (!pEntry->ValidAsCLI))
-            break;
-
-        if (MsgLen < (LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE - 2))
-            break;
-
-        if (pEntry->WpaState != AS_PTKINITDONE)
-            break;
-
-
-        pData = (PUCHAR)Msg;
-		pMsg2 = (PEAPOL_PACKET) (pData + LENGTH_802_1_H);
-        Len = MsgLen - LENGTH_802_1_H;
-
-		// Sanity Check peer group message 2 - Replay Counter, MIC
-		if (PeerWpaMessageSanity(pAd, pMsg2, Len, EAPOL_GROUP_MSG_2, pEntry) == FALSE)
-            break;
-
-        // 3.  upgrade state
-
-		RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
-        pEntry->GTKState = REKEY_ESTABLISHED;
-
-		if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
-		{
-			// send wireless event - for set key done WPA2
-			if (pAd->CommonCfg.bWirelessEvent)
-				RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
-
-			DBGPRINT(RT_DEBUG_OFF, ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
-										pEntry->AuthMode, GetAuthMode(pEntry->AuthMode),
-										pEntry->WepStatus, GetEncryptType(pEntry->WepStatus),
-										group_cipher, GetEncryptType(group_cipher)));
-		}
-		else
-		{
-			// send wireless event - for set key done WPA
-			if (pAd->CommonCfg.bWirelessEvent)
-				RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA1_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
-
-		DBGPRINT(RT_DEBUG_OFF, ("AP SETKEYS DONE - WPA1, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
-										pEntry->AuthMode, GetAuthMode(pEntry->AuthMode),
-										pEntry->WepStatus, GetEncryptType(pEntry->WepStatus),
-										group_cipher, GetEncryptType(group_cipher)));
-		}
-    }while(FALSE);
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Classify WPA EAP message type
-
-	Arguments:
-		EAPType		Value of EAP message type
-		MsgType		Internal Message definition for MLME state machine
-
-	Return Value:
-		TRUE		Found appropriate message type
-		FALSE		No appropriate message type
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-		All these constants are defined in wpa.h
-		For supplicant, there is only EAPOL Key message avaliable
-
-	========================================================================
-*/
-BOOLEAN	WpaMsgTypeSubst(
-	IN	UCHAR	EAPType,
-	OUT	INT		*MsgType)
-{
-	switch (EAPType)
-	{
-		case EAPPacket:
-			*MsgType = MT2_EAPPacket;
-			break;
-		case EAPOLStart:
-			*MsgType = MT2_EAPOLStart;
-			break;
-		case EAPOLLogoff:
-			*MsgType = MT2_EAPOLLogoff;
-			break;
-		case EAPOLKey:
-			*MsgType = MT2_EAPOLKey;
-			break;
-		case EAPOLASFAlert:
-			*MsgType = MT2_EAPOLASFAlert;
-			break;
-		default:
-			return FALSE;
-	}
-	return TRUE;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		The pseudo-random function(PRF) that hashes various inputs to
-		derive a pseudo-random value. To add liveness to the pseudo-random
-		value, a nonce should be one of the inputs.
-
-		It is used to generate PTK, GTK or some specific random value.
-
-	Arguments:
-		UCHAR	*key,		-	the key material for HMAC_SHA1 use
-		INT		key_len		-	the length of key
-		UCHAR	*prefix		-	a prefix label
-		INT		prefix_len	-	the length of the label
-		UCHAR	*data		-	a specific data with variable length
-		INT		data_len	-	the length of a specific data
-		INT		len			-	the output lenght
-
-	Return Value:
-		UCHAR	*output		-	the calculated result
-
-	Note:
-		802.11i-2004	Annex H.3
-
-	========================================================================
-*/
-VOID	PRF(
-	IN	UCHAR	*key,
-	IN	INT		key_len,
-	IN	UCHAR	*prefix,
-	IN	INT		prefix_len,
-	IN	UCHAR	*data,
-	IN	INT		data_len,
-	OUT	UCHAR	*output,
-	IN	INT		len)
-{
-	INT		i;
-    UCHAR   *input;
-	INT		currentindex = 0;
-	INT		total_len;
-
-	// Allocate memory for input
-	os_alloc_mem(NULL, (PUCHAR *)&input, 1024);
-
-    if (input == NULL)
-    {
-        DBGPRINT(RT_DEBUG_ERROR, ("!!!PRF: no memory!!!\n"));
-        return;
-    }
-
-	// Generate concatenation input
-	NdisMoveMemory(input, prefix, prefix_len);
-
-	// Concatenate a single octet containing 0
-	input[prefix_len] =	0;
-
-	// Concatenate specific data
-	NdisMoveMemory(&input[prefix_len + 1], data, data_len);
-	total_len =	prefix_len + 1 + data_len;
-
-	// Concatenate a single octet containing 0
-	// This octet shall be update later
-	input[total_len] = 0;
-	total_len++;
-
-	// Iterate to calculate the result by hmac-sha-1
-	// Then concatenate to last result
-	for	(i = 0;	i <	(len + 19) / 20; i++)
-	{
-		HMAC_SHA1(key, key_len, input, total_len, &output[currentindex], SHA1_DIGEST_SIZE);
-		currentindex +=	20;
-
-		// update the last octet
-		input[total_len - 1]++;
-	}
-    os_free_mem(NULL, input);
-}
-
-/*
-* F(P, S, c, i) = U1 xor U2 xor ... Uc
-* U1 = PRF(P, S || Int(i))
-* U2 = PRF(P, U1)
-* Uc = PRF(P, Uc-1)
-*/
-
-static void F(char *password, unsigned char *ssid, int ssidlength, int iterations, int count, unsigned char *output)
-{
-    unsigned char digest[36], digest1[SHA1_DIGEST_SIZE];
-    int i, j;
-
-    /* U1 = PRF(P, S || int(i)) */
-    memcpy(digest, ssid, ssidlength);
-    digest[ssidlength] = (unsigned char)((count>>24) & 0xff);
-    digest[ssidlength+1] = (unsigned char)((count>>16) & 0xff);
-    digest[ssidlength+2] = (unsigned char)((count>>8) & 0xff);
-    digest[ssidlength+3] = (unsigned char)(count & 0xff);
-    HMAC_SHA1((unsigned char*) password, (int) strlen(password), digest, ssidlength+4, digest1, SHA1_DIGEST_SIZE); // for WPA update
-
-    /* output = U1 */
-    memcpy(output, digest1, SHA1_DIGEST_SIZE);
-
-    for (i = 1; i < iterations; i++)
-    {
-        /* Un = PRF(P, Un-1) */
-        HMAC_SHA1((unsigned char*) password, (int) strlen(password), digest1, SHA1_DIGEST_SIZE, digest, SHA1_DIGEST_SIZE); // for WPA update
-        memcpy(digest1, digest, SHA1_DIGEST_SIZE);
-
-        /* output = output xor Un */
-        for (j = 0; j < SHA1_DIGEST_SIZE; j++)
-        {
-            output[j] ^= digest[j];
-        }
-    }
-}
-
-/*
-* password - ascii string up to 63 characters in length
-* ssid - octet string up to 32 octets
-* ssidlength - length of ssid in octets
-* output must be 40 octets in length and outputs 256 bits of key
-*/
-int PasswordHash(PSTRING password, PUCHAR ssid, INT ssidlength, PUCHAR output)
-{
-    if ((strlen(password) > 63) || (ssidlength > 32))
-        return 0;
-
-    F(password, ssid, ssidlength, 4096, 1, output);
-    F(password, ssid, ssidlength, 4096, 2, &output[SHA1_DIGEST_SIZE]);
-    return 1;
-}
-
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		It utilizes PRF-384 or PRF-512 to derive session-specific keys from a PMK.
-		It shall be called by 4-way handshake processing.
-
-	Arguments:
-		pAd	-	pointer to our pAdapter context
-		PMK		-	pointer to PMK
-		ANonce	-	pointer to ANonce
-		AA		-	pointer to Authenticator Address
-		SNonce	-	pointer to SNonce
-		SA		-	pointer to Supplicant Address
-		len		-	indicate the length of PTK (octet)
-
-	Return Value:
-		Output		pointer to the PTK
-
-	Note:
-		Refer to IEEE 802.11i-2004 8.5.1.2
-
-	========================================================================
-*/
-VOID WpaDerivePTK(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR	*PMK,
-	IN	UCHAR	*ANonce,
-	IN	UCHAR	*AA,
-	IN	UCHAR	*SNonce,
-	IN	UCHAR	*SA,
-	OUT	UCHAR	*output,
-	IN	UINT	len)
-{
-	UCHAR	concatenation[76];
-	UINT	CurrPos = 0;
-	UCHAR	temp[32];
-	UCHAR	Prefix[] = {'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ',
-						'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'};
-
-	// initiate the concatenation input
-	NdisZeroMemory(temp, sizeof(temp));
-	NdisZeroMemory(concatenation, 76);
-
-	// Get smaller address
-	if (RTMPCompareMemory(SA, AA, 6) == 1)
-		NdisMoveMemory(concatenation, AA, 6);
-	else
-		NdisMoveMemory(concatenation, SA, 6);
-	CurrPos += 6;
-
-	// Get larger address
-	if (RTMPCompareMemory(SA, AA, 6) == 1)
-		NdisMoveMemory(&concatenation[CurrPos], SA, 6);
-	else
-		NdisMoveMemory(&concatenation[CurrPos], AA, 6);
-
-	// store the larger mac address for backward compatible of
-	// ralink proprietary STA-key issue
-	NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN);
-	CurrPos += 6;
-
-	// Get smaller Nonce
-	if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
-		NdisMoveMemory(&concatenation[CurrPos], temp, 32);	// patch for ralink proprietary STA-key issue
-	else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
-		NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
-	else
-		NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
-	CurrPos += 32;
-
-	// Get larger Nonce
-	if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
-		NdisMoveMemory(&concatenation[CurrPos], temp, 32);	// patch for ralink proprietary STA-key issue
-	else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
-		NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
-	else
-		NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
-	CurrPos += 32;
-
-	hex_dump("concatenation=", concatenation, 76);
-
-	// Use PRF to generate PTK
-	PRF(PMK, LEN_MASTER_KEY, Prefix, 22, concatenation, 76, output, len);
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Generate random number by software.
-
-	Arguments:
-		pAd		-	pointer to our pAdapter context
-		macAddr	-	pointer to local MAC address
-
-	Return Value:
-
-	Note:
-		802.1ii-2004  Annex H.5
-
-	========================================================================
-*/
-VOID	GenRandom(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			*macAddr,
-	OUT	UCHAR			*random)
-{
-	INT		i, curr;
-	UCHAR	local[80], KeyCounter[32];
-	UCHAR	result[80];
-	ULONG	CurrentTime;
-	UCHAR	prefix[] = {'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r'};
-
-	// Zero the related information
-	NdisZeroMemory(result, 80);
-	NdisZeroMemory(local, 80);
-	NdisZeroMemory(KeyCounter, 32);
-
-	for	(i = 0;	i <	32;	i++)
-	{
-		// copy the local MAC address
-		COPY_MAC_ADDR(local, macAddr);
-		curr =	MAC_ADDR_LEN;
-
-		// concatenate the current time
-		NdisGetSystemUpTime(&CurrentTime);
-		NdisMoveMemory(&local[curr],  &CurrentTime,	sizeof(CurrentTime));
-		curr +=	sizeof(CurrentTime);
-
-		// concatenate the last result
-		NdisMoveMemory(&local[curr],  result, 32);
-		curr +=	32;
-
-		// concatenate a variable
-		NdisMoveMemory(&local[curr],  &i,  2);
-		curr +=	2;
-
-		// calculate the result
-		PRF(KeyCounter, 32, prefix,12, local, curr, result, 32);
-	}
-
-	NdisMoveMemory(random, result,	32);
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Build cipher suite in RSN-IE.
-		It only shall be called by RTMPMakeRSNIE.
-
-	Arguments:
-		pAd			-	pointer to our pAdapter context
-	ElementID	-	indicate the WPA1 or WPA2
-	WepStatus	-	indicate the encryption type
-		bMixCipher	-	a boolean to indicate the pairwise cipher and group
-						cipher are the same or not
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-static VOID RTMPMakeRsnIeCipher(
-	IN  PRTMP_ADAPTER   pAd,
-	IN	UCHAR			ElementID,
-	IN	UINT			WepStatus,
-	IN	BOOLEAN			bMixCipher,
-	IN	UCHAR			FlexibleCipher,
-	OUT	PUCHAR			pRsnIe,
-	OUT	UCHAR			*rsn_len)
-{
-	UCHAR	PairwiseCnt;
-
-	*rsn_len = 0;
-
-	// decide WPA2 or WPA1
-	if (ElementID == Wpa2Ie)
-	{
-		RSNIE2	*pRsnie_cipher = (RSNIE2*)pRsnIe;
-
-		// Assign the verson as 1
-		pRsnie_cipher->version = 1;
-
-        switch (WepStatus)
-        {
-		// TKIP mode
-            case Ndis802_11Encryption2Enabled:
-                NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
-                pRsnie_cipher->ucount = 1;
-                NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4);
-                *rsn_len = sizeof(RSNIE2);
-                break;
-
-			// AES mode
-            case Ndis802_11Encryption3Enabled:
-				if (bMixCipher)
-					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
-				else
-					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_CCMP, 4);
-                pRsnie_cipher->ucount = 1;
-                NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4);
-                *rsn_len = sizeof(RSNIE2);
-                break;
-
-			// TKIP-AES mix mode
-            case Ndis802_11Encryption4Enabled:
-                NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
-
-				PairwiseCnt = 1;
-				// Insert WPA2 TKIP as the first pairwise cipher
-				if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher))
-				{
-			NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4);
-					// Insert WPA2 AES as the secondary pairwise cipher
-					if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher))
-					{
-				NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA2_CCMP, 4);
-						PairwiseCnt = 2;
-					}
-				}
-				else
-				{
-					// Insert WPA2 AES as the first pairwise cipher
-					NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4);
-				}
-
-                pRsnie_cipher->ucount = PairwiseCnt;
-                *rsn_len = sizeof(RSNIE2) + (4 * (PairwiseCnt - 1));
-                break;
-        }
-
-#ifdef CONFIG_STA_SUPPORT
-		if ((pAd->OpMode == OPMODE_STA) &&
-			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
-			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
-		{
-			UINT	GroupCipher = pAd->StaCfg.GroupCipher;
-			switch(GroupCipher)
-			{
-				case Ndis802_11GroupWEP40Enabled:
-					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP40, 4);
-					break;
-				case Ndis802_11GroupWEP104Enabled:
-					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP104, 4);
-					break;
-			}
-		}
-#endif // CONFIG_STA_SUPPORT //
-
-		// swap for big-endian platform
-		pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
-	    pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
-	}
-	else
-	{
-		RSNIE	*pRsnie_cipher = (RSNIE*)pRsnIe;
-
-		// Assign OUI and version
-		NdisMoveMemory(pRsnie_cipher->oui, OUI_WPA_VERSION, 4);
-        pRsnie_cipher->version = 1;
-
-		switch (WepStatus)
-		{
-			// TKIP mode
-            case Ndis802_11Encryption2Enabled:
-                NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
-                pRsnie_cipher->ucount = 1;
-                NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4);
-                *rsn_len = sizeof(RSNIE);
-                break;
-
-			// AES mode
-            case Ndis802_11Encryption3Enabled:
-				if (bMixCipher)
-					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
-				else
-					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_CCMP, 4);
-                pRsnie_cipher->ucount = 1;
-                NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4);
-                *rsn_len = sizeof(RSNIE);
-                break;
-
-			// TKIP-AES mix mode
-            case Ndis802_11Encryption4Enabled:
-                NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
-
-				PairwiseCnt = 1;
-				// Insert WPA TKIP as the first pairwise cipher
-				if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher))
-				{
-			NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4);
-					// Insert WPA AES as the secondary pairwise cipher
-					if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher))
-					{
-				NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA_CCMP, 4);
-						PairwiseCnt = 2;
-					}
-				}
-				else
-				{
-					// Insert WPA AES as the first pairwise cipher
-					NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4);
-				}
-
-                pRsnie_cipher->ucount = PairwiseCnt;
-                *rsn_len = sizeof(RSNIE) + (4 * (PairwiseCnt - 1));
-                break;
-        }
-
-#ifdef CONFIG_STA_SUPPORT
-		if ((pAd->OpMode == OPMODE_STA) &&
-			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
-			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
-		{
-			UINT	GroupCipher = pAd->StaCfg.GroupCipher;
-			switch(GroupCipher)
-			{
-				case Ndis802_11GroupWEP40Enabled:
-					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP40, 4);
-					break;
-				case Ndis802_11GroupWEP104Enabled:
-					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP104, 4);
-					break;
-			}
-		}
-#endif // CONFIG_STA_SUPPORT //
-
-		// swap for big-endian platform
-		pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
-	    pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
-	}
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Build AKM suite in RSN-IE.
-		It only shall be called by RTMPMakeRSNIE.
-
-	Arguments:
-		pAd			-	pointer to our pAdapter context
-	ElementID	-	indicate the WPA1 or WPA2
-	AuthMode	-	indicate the authentication mode
-		apidx		-	indicate the interface index
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-static VOID RTMPMakeRsnIeAKM(
-	IN  PRTMP_ADAPTER   pAd,
-	IN	UCHAR			ElementID,
-	IN	UINT			AuthMode,
-	IN	UCHAR			apidx,
-	OUT	PUCHAR			pRsnIe,
-	OUT	UCHAR			*rsn_len)
-{
-	RSNIE_AUTH		*pRsnie_auth;
-	UCHAR			AkmCnt = 1;		// default as 1
-
-	pRsnie_auth = (RSNIE_AUTH*)(pRsnIe + (*rsn_len));
-
-	// decide WPA2 or WPA1
-	if (ElementID == Wpa2Ie)
-	{
-
-		switch (AuthMode)
-        {
-            case Ndis802_11AuthModeWPA2:
-            case Ndis802_11AuthModeWPA1WPA2:
-			NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_8021X_AKM, 4);
-                break;
-
-            case Ndis802_11AuthModeWPA2PSK:
-            case Ndis802_11AuthModeWPA1PSKWPA2PSK:
-			NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_PSK_AKM, 4);
-                break;
-			default:
-				AkmCnt = 0;
-				break;
-
-        }
-	}
-	else
-	{
-		switch (AuthMode)
-        {
-            case Ndis802_11AuthModeWPA:
-            case Ndis802_11AuthModeWPA1WPA2:
-                NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_8021X_AKM, 4);
-                break;
-
-            case Ndis802_11AuthModeWPAPSK:
-            case Ndis802_11AuthModeWPA1PSKWPA2PSK:
-                NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_PSK_AKM, 4);
-                break;
-
-			case Ndis802_11AuthModeWPANone:
-                NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_NONE_AKM, 4);
-                break;
-			default:
-				AkmCnt = 0;
-				break;
-        }
-	}
-
-	pRsnie_auth->acount = AkmCnt;
-	pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount);
-
-	// update current RSNIE length
-	(*rsn_len) += (sizeof(RSNIE_AUTH) + (4 * (AkmCnt - 1)));
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Build capability in RSN-IE.
-		It only shall be called by RTMPMakeRSNIE.
-
-	Arguments:
-		pAd			-	pointer to our pAdapter context
-	ElementID	-	indicate the WPA1 or WPA2
-		apidx		-	indicate the interface index
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-static VOID RTMPMakeRsnIeCap(
-	IN  PRTMP_ADAPTER   pAd,
-	IN	UCHAR			ElementID,
-	IN	UCHAR			apidx,
-	OUT	PUCHAR			pRsnIe,
-	OUT	UCHAR			*rsn_len)
-{
-	RSN_CAPABILITIES    *pRSN_Cap;
-
-	// it could be ignored in WPA1 mode
-	if (ElementID == WpaIe)
-		return;
-
-	pRSN_Cap = (RSN_CAPABILITIES*)(pRsnIe + (*rsn_len));
-
-
-	pRSN_Cap->word = cpu2le16(pRSN_Cap->word);
-
-	(*rsn_len) += sizeof(RSN_CAPABILITIES);	// update current RSNIE length
-
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Build RSN IE context. It is not included element-ID and length.
-
-	Arguments:
-		pAd			-	pointer to our pAdapter context
-	AuthMode	-	indicate the authentication mode
-	WepStatus	-	indicate the encryption type
-		apidx		-	indicate the interface index
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-VOID RTMPMakeRSNIE(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  UINT            AuthMode,
-    IN  UINT            WepStatus,
-	IN	UCHAR			apidx)
-{
-	PUCHAR		pRsnIe = NULL;			// primary RSNIE
-	UCHAR		*rsnielen_cur_p = 0;	// the length of the primary RSNIE
-	UCHAR		*rsnielen_ex_cur_p = 0;	// the length of the secondary RSNIE
-	UCHAR		PrimaryRsnie;
-	BOOLEAN		bMixCipher = FALSE;	// indicate the pairwise and group cipher are different
-	UCHAR		p_offset;
-	WPA_MIX_PAIR_CIPHER		FlexibleCipher = WPA_TKIPAES_WPA2_TKIPAES;	// it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode
-
-	rsnielen_cur_p = NULL;
-	rsnielen_ex_cur_p = NULL;
-
-	{
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-#ifdef WPA_SUPPLICANT_SUPPORT
-			if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
-			{
-				if (AuthMode < Ndis802_11AuthModeWPA)
-					return;
-			}
-			else
-#endif // WPA_SUPPLICANT_SUPPORT //
-			{
-				// Support WPAPSK or WPA2PSK in STA-Infra mode
-				// Support WPANone in STA-Adhoc mode
-				if ((AuthMode != Ndis802_11AuthModeWPAPSK) &&
-					(AuthMode != Ndis802_11AuthModeWPA2PSK) &&
-					(AuthMode != Ndis802_11AuthModeWPANone)
-					)
-					return;
-			}
-
-			DBGPRINT(RT_DEBUG_TRACE,("==> RTMPMakeRSNIE(STA)\n"));
-
-			// Zero RSNIE context
-			pAd->StaCfg.RSNIE_Len = 0;
-			NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE);
-
-			// Pointer to RSNIE
-			rsnielen_cur_p = &pAd->StaCfg.RSNIE_Len;
-			pRsnIe = pAd->StaCfg.RSN_IE;
-
-			bMixCipher = pAd->StaCfg.bMixCipher;
-		}
-#endif // CONFIG_STA_SUPPORT //
-	}
-
-	// indicate primary RSNIE as WPA or WPA2
-	if ((AuthMode == Ndis802_11AuthModeWPA) ||
-		(AuthMode == Ndis802_11AuthModeWPAPSK) ||
-		(AuthMode == Ndis802_11AuthModeWPANone) ||
-		(AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
-		(AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
-		PrimaryRsnie = WpaIe;
-	else
-		PrimaryRsnie = Wpa2Ie;
-
-	{
-		// Build the primary RSNIE
-		// 1. insert cipher suite
-		RTMPMakeRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher, FlexibleCipher, pRsnIe, &p_offset);
-
-		// 2. insert AKM
-		RTMPMakeRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe, &p_offset);
-
-		// 3. insert capability
-		RTMPMakeRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset);
-	}
-
-	// 4. update the RSNIE length
-	*rsnielen_cur_p = p_offset;
-
-	hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p));
-
-
-}
-
-/*
-    ==========================================================================
-    Description:
-		Check whether the received frame is EAP frame.
-
-	Arguments:
-		pAd				-	pointer to our pAdapter context
-		pEntry			-	pointer to active entry
-		pData			-	the received frame
-		DataByteCount	-	the received frame's length
-		FromWhichBSSID	-	indicate the interface index
-
-    Return:
-         TRUE			-	This frame is EAP frame
-         FALSE			-	otherwise
-    ==========================================================================
-*/
-BOOLEAN RTMPCheckWPAframe(
-    IN PRTMP_ADAPTER    pAd,
-    IN PMAC_TABLE_ENTRY	pEntry,
-    IN PUCHAR           pData,
-    IN ULONG            DataByteCount,
-	IN UCHAR			FromWhichBSSID)
-{
-	ULONG	Body_len;
-	BOOLEAN Cancelled;
-
-
-    if(DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H))
-        return FALSE;
-
-
-	// Skip LLC header
-    if (NdisEqualMemory(SNAP_802_1H, pData, 6) ||
-        // Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL
-        NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6))
-    {
-        pData += 6;
-    }
-	// Skip 2-bytes EAPoL type
-    if (NdisEqualMemory(EAPOL, pData, 2))
-//	if (*(UINT16 *)EAPOL == *(UINT16 *)pData)
-    {
-        pData += 2;
-    }
-    else
-        return FALSE;
-
-    switch (*(pData+1))
-    {
-        case EAPPacket:
-			Body_len = (*(pData+2)<<8) | (*(pData+3));
-            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n", Body_len));
-            break;
-        case EAPOLStart:
-            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Start frame, TYPE = 1 \n"));
-			if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
-            {
-		DBGPRINT(RT_DEBUG_TRACE, ("Cancel the EnqueueEapolStartTimerRunning \n"));
-                RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
-                pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
-            }
-            break;
-        case EAPOLLogoff:
-            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLLogoff frame, TYPE = 2 \n"));
-            break;
-        case EAPOLKey:
-			Body_len = (*(pData+2)<<8) | (*(pData+3));
-            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n", Body_len));
-            break;
-        case EAPOLASFAlert:
-            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLASFAlert frame, TYPE = 4 \n"));
-            break;
-        default:
-            return FALSE;
-
-    }
-    return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-		Report the EAP message type
-
-	Arguments:
-		msg		-	EAPOL_PAIR_MSG_1
-					EAPOL_PAIR_MSG_2
-					EAPOL_PAIR_MSG_3
-					EAPOL_PAIR_MSG_4
-					EAPOL_GROUP_MSG_1
-					EAPOL_GROUP_MSG_2
-
-    Return:
-         message type string
-
-    ==========================================================================
-*/
-PSTRING GetEapolMsgType(CHAR msg)
-{
-    if(msg == EAPOL_PAIR_MSG_1)
-        return "Pairwise Message 1";
-    else if(msg == EAPOL_PAIR_MSG_2)
-        return "Pairwise Message 2";
-	else if(msg == EAPOL_PAIR_MSG_3)
-        return "Pairwise Message 3";
-	else if(msg == EAPOL_PAIR_MSG_4)
-        return "Pairwise Message 4";
-	else if(msg == EAPOL_GROUP_MSG_1)
-        return "Group Message 1";
-	else if(msg == EAPOL_GROUP_MSG_2)
-        return "Group Message 2";
-    else
-	return "Invalid Message";
-}
-
-
-/*
-    ========================================================================
-
-    Routine Description:
-    Check Sanity RSN IE of EAPoL message
-
-    Arguments:
-
-    Return Value:
-
-
-    ========================================================================
-*/
-BOOLEAN RTMPCheckRSNIE(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pData,
-	IN  UCHAR           DataLen,
-	IN  MAC_TABLE_ENTRY *pEntry,
-	OUT	UCHAR			*Offset)
-{
-	PUCHAR              pVIE;
-	UCHAR               len;
-	PEID_STRUCT         pEid;
-	BOOLEAN				result = FALSE;
-
-	pVIE = pData;
-	len	 = DataLen;
-	*Offset = 0;
-
-	while (len > sizeof(RSNIE2))
-	{
-		pEid = (PEID_STRUCT) pVIE;
-		// WPA RSN IE
-		if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)))
-		{
-			if ((pEntry->AuthMode == Ndis802_11AuthModeWPA || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) &&
-				(NdisEqualMemory(pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) &&
-				(pEntry->RSNIE_Len == (pEid->Len + 2)))
-			{
-					result = TRUE;
-			}
-
-			*Offset += (pEid->Len + 2);
-		}
-		// WPA2 RSN IE
-		else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)))
-		{
-			if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2 || pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) &&
-				(pEid->Eid == pEntry->RSN_IE[0]) &&
-				((pEid->Len + 2) >= pEntry->RSNIE_Len) &&
-				(NdisEqualMemory(pEid->Octet, &pEntry->RSN_IE[2], pEntry->RSNIE_Len - 2)))
-			{
-
-					result = TRUE;
-			}
-
-			*Offset += (pEid->Len + 2);
-		}
-		else
-		{
-			break;
-		}
-
-		pVIE += (pEid->Len + 2);
-		len  -= (pEid->Len + 2);
-	}
-
-
-	return result;
-
-}
-
-
-/*
-    ========================================================================
-
-    Routine Description:
-    Parse KEYDATA field.  KEYDATA[] May contain 2 RSN IE and optionally GTK.
-    GTK  is encaptulated in KDE format at  p.83 802.11i D10
-
-    Arguments:
-
-    Return Value:
-
-    Note:
-        802.11i D10
-
-    ========================================================================
-*/
-BOOLEAN RTMPParseEapolKeyData(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pKeyData,
-	IN  UCHAR           KeyDataLen,
-	IN	UCHAR			GroupKeyIndex,
-	IN	UCHAR			MsgType,
-	IN	BOOLEAN			bWPA2,
-	IN  MAC_TABLE_ENTRY *pEntry)
-{
-    PKDE_ENCAP          pKDE = NULL;
-    PUCHAR              pMyKeyData = pKeyData;
-    UCHAR               KeyDataLength = KeyDataLen;
-    UCHAR               GTKLEN = 0;
-	UCHAR				DefaultIdx = 0;
-	UCHAR				skip_offset;
-
-	// Verify The RSN IE contained in pairewise_msg_2 && pairewise_msg_3 and skip it
-	if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_3)
-    {
-		// Check RSN IE whether it is WPA2/WPA2PSK
-		if (!RTMPCheckRSNIE(pAd, pKeyData, KeyDataLen, pEntry, &skip_offset))
-		{
-			// send wireless event - for RSN IE different
-			if (pAd->CommonCfg.bWirelessEvent)
-				RTMPSendWirelessEvent(pAd, IW_RSNIE_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
-
-		DBGPRINT(RT_DEBUG_ERROR, ("RSN_IE Different in msg %d of 4-way handshake!\n", MsgType));
-			hex_dump("Receive RSN_IE ", pKeyData, KeyDataLen);
-			hex_dump("Desired RSN_IE ", pEntry->RSN_IE, pEntry->RSNIE_Len);
-
-			return FALSE;
-	}
-	else
-		{
-			if (bWPA2 && MsgType == EAPOL_PAIR_MSG_3)
-			{
-				WpaShowAllsuite(pMyKeyData, skip_offset);
-
-				// skip RSN IE
-				pMyKeyData += skip_offset;
-				KeyDataLength -= skip_offset;
-				DBGPRINT(RT_DEBUG_TRACE, ("RTMPParseEapolKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset));
-			}
-			else
-				return TRUE;
-		}
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength));
-	//hex_dump("remain data", pMyKeyData, KeyDataLength);
-
-
-	// Parse EKD format in pairwise_msg_3_WPA2 && group_msg_1_WPA2
-	if (bWPA2 && (MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1))
-	{
-		if (KeyDataLength >= 8)	// KDE format exclude GTK length
-	{
-		pKDE = (PKDE_ENCAP) pMyKeyData;
-
-
-			DefaultIdx = pKDE->GTKEncap.Kid;
-
-			// Sanity check - KED length
-			if (KeyDataLength < (pKDE->Len + 2))
-		{
-			DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The len from KDE is too short \n"));
-			return FALSE;
-		}
-
-			// Get GTK length - refer to IEEE 802.11i-2004 p.82
-			GTKLEN = pKDE->Len -6;
-			if (GTKLEN < LEN_AES_KEY)
-			{
-				DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));
-			return FALSE;
-			}
-
-	}
-		else
-	{
-			DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KDE format length is too short \n"));
-	        return FALSE;
-	}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n", DefaultIdx, GTKLEN));
-		// skip it
-		pMyKeyData += 8;
-		KeyDataLength -= 8;
-
-	}
-	else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1)
-	{
-		DefaultIdx = GroupKeyIndex;
-		DBGPRINT(RT_DEBUG_TRACE, ("GTK DefaultKeyID=%d \n", DefaultIdx));
-	}
-
-	// Sanity check - shared key index must be 1 ~ 3
-	if (DefaultIdx < 1 || DefaultIdx > 3)
-    {
-	DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index(%d) is invalid in %s %s \n", DefaultIdx, ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
-        return FALSE;
-    }
-
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		PCIPHER_KEY pSharedKey;
-
-		// set key material, TxMic and RxMic
-		NdisMoveMemory(pAd->StaCfg.GTK, pMyKeyData, 32);
-		pAd->StaCfg.DefaultKeyId = DefaultIdx;
-
-		pSharedKey = &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId];
-
-		// Prepare pair-wise key information into shared key table
-		NdisZeroMemory(pSharedKey, sizeof(CIPHER_KEY));
-		pSharedKey->KeyLen = LEN_TKIP_EK;
-		NdisMoveMemory(pSharedKey->Key, pAd->StaCfg.GTK, LEN_TKIP_EK);
-		NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.GTK[16], LEN_TKIP_RXMICK);
-		NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.GTK[24], LEN_TKIP_TXMICK);
-
-		// Update Shared Key CipherAlg
-		pSharedKey->CipherAlg = CIPHER_NONE;
-		if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
-			pSharedKey->CipherAlg = CIPHER_TKIP;
-		else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
-			pSharedKey->CipherAlg = CIPHER_AES;
-		else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
-			pSharedKey->CipherAlg = CIPHER_WEP64;
-		else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
-			pSharedKey->CipherAlg = CIPHER_WEP128;
-
-
-		// Update group key information to ASIC Shared Key Table
-		AsicAddSharedKeyEntry(pAd,
-							  BSS0,
-							  pAd->StaCfg.DefaultKeyId,
-							  pSharedKey->CipherAlg,
-							  pSharedKey->Key,
-							  pSharedKey->TxMic,
-							  pSharedKey->RxMic);
-
-		// Update ASIC WCID attribute table and IVEIV table
-		RTMPAddWcidAttributeEntry(pAd,
-								  BSS0,
-								  pAd->StaCfg.DefaultKeyId,
-								  pSharedKey->CipherAlg,
-								  NULL);
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	return TRUE;
-
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Construct EAPoL message for WPA handshaking
-		Its format is below,
-
-		+--------------------+
-		| Protocol Version	 |  1 octet
-		+--------------------+
-		| Protocol Type		 |	1 octet
-		+--------------------+
-		| Body Length		 |  2 octets
-		+--------------------+
-		| Descriptor Type	 |	1 octet
-		+--------------------+
-		| Key Information    |	2 octets
-		+--------------------+
-		| Key Length	     |  1 octet
-		+--------------------+
-		| Key Repaly Counter |	8 octets
-		+--------------------+
-		| Key Nonce		     |  32 octets
-		+--------------------+
-		| Key IV			 |  16 octets
-		+--------------------+
-		| Key RSC			 |  8 octets
-		+--------------------+
-		| Key ID or Reserved |	8 octets
-		+--------------------+
-		| Key MIC			 |	16 octets
-		+--------------------+
-		| Key Data Length	 |	2 octets
-		+--------------------+
-		| Key Data			 |	n octets
-		+--------------------+
-
-
-	Arguments:
-		pAd			Pointer	to our adapter
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	ConstructEapolMsg(
-	IN	PMAC_TABLE_ENTRY	pEntry,
-    IN	UCHAR				GroupKeyWepStatus,
-    IN	UCHAR				MsgType,
-    IN	UCHAR				DefaultKeyIdx,
-	IN	UCHAR				*KeyNonce,
-	IN	UCHAR				*TxRSC,
-	IN	UCHAR				*GTK,
-	IN	UCHAR				*RSNIE,
-	IN	UCHAR				RSNIE_Len,
-    OUT PEAPOL_PACKET       pMsg)
-{
-	BOOLEAN	bWPA2 = FALSE;
-	UCHAR	KeyDescVer;
-
-	// Choose WPA2 or not
-	if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
-		(pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
-		bWPA2 = TRUE;
-
-    // Init Packet and Fill header
-    pMsg->ProVer = EAPOL_VER;
-    pMsg->ProType = EAPOLKey;
-
-	// Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field
-	SET_UINT16_TO_ARRARY(pMsg->Body_Len, LEN_EAPOL_KEY_MSG);
-
-	// Fill in EAPoL descriptor
-	if (bWPA2)
-		pMsg->KeyDesc.Type = WPA2_KEY_DESC;
-	else
-		pMsg->KeyDesc.Type = WPA1_KEY_DESC;
-
-	// Key Descriptor Version (bits 0-2) specifies the key descriptor version type
-	{
-		// Fill in Key information, refer to IEEE Std 802.11i-2004 page 78
-		// When either the pairwise or the group cipher is AES, the DESC_TYPE_AES(2) shall be used.
-		KeyDescVer = (((pEntry->WepStatus == Ndis802_11Encryption3Enabled) ||
-					(GroupKeyWepStatus == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
-	}
-
-	pMsg->KeyDesc.KeyInfo.KeyDescVer = KeyDescVer;
-
-	// Specify Key Type as Group(0) or Pairwise(1)
-	if (MsgType >= EAPOL_GROUP_MSG_1)
-		pMsg->KeyDesc.KeyInfo.KeyType = GROUPKEY;
-	else
-		pMsg->KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
-
-	// Specify Key Index, only group_msg1_WPA1
-	if (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))
-		pMsg->KeyDesc.KeyInfo.KeyIndex = DefaultKeyIdx;
-
-	if (MsgType == EAPOL_PAIR_MSG_3)
-		pMsg->KeyDesc.KeyInfo.Install = 1;
-
-	if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1))
-		pMsg->KeyDesc.KeyInfo.KeyAck = 1;
-
-	if (MsgType != EAPOL_PAIR_MSG_1)
-		pMsg->KeyDesc.KeyInfo.KeyMic = 1;
-
-	if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) ||
-		(!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1)))
-    {
-	pMsg->KeyDesc.KeyInfo.Secure = 1;
-    }
-
-	if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) ||
-		(MsgType == EAPOL_GROUP_MSG_1)))
-    {
-        pMsg->KeyDesc.KeyInfo.EKD_DL = 1;
-    }
-
-	// key Information element has done.
-	*(USHORT *)(&pMsg->KeyDesc.KeyInfo) = cpu2le16(*(USHORT *)(&pMsg->KeyDesc.KeyInfo));
-
-	// Fill in Key Length
-	{
-		if (MsgType >= EAPOL_GROUP_MSG_1)
-		{
-			// the length of group key cipher
-			pMsg->KeyDesc.KeyLength[1] = ((GroupKeyWepStatus == Ndis802_11Encryption2Enabled) ? TKIP_GTK_LENGTH : LEN_AES_KEY);
-		}
-		else
-		{
-			// the length of pairwise key cipher
-			pMsg->KeyDesc.KeyLength[1] = ((pEntry->WepStatus == Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY : LEN_AES_KEY);
-		}
-	}
-
-	// Fill in replay counter
-    NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY);
-
-	// Fill Key Nonce field
-	// ANonce : pairwise_msg1 & pairwise_msg3
-	// SNonce : pairwise_msg2
-	// GNonce : group_msg1_wpa1
-	if ((MsgType <= EAPOL_PAIR_MSG_3) || ((!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))))
-	NdisMoveMemory(pMsg->KeyDesc.KeyNonce, KeyNonce, LEN_KEY_DESC_NONCE);
-
-	// Fill key IV - WPA2 as 0, WPA1 as random
-	if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))
-	{
-		// Suggest IV be random number plus some number,
-		NdisMoveMemory(pMsg->KeyDesc.KeyIv, &KeyNonce[16], LEN_KEY_DESC_IV);
-        pMsg->KeyDesc.KeyIv[15] += 2;
-	}
-
-    // Fill Key RSC field
-    // It contains the RSC for the GTK being installed.
-	if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1))
-	{
-        NdisMoveMemory(pMsg->KeyDesc.KeyRsc, TxRSC, 6);
-	}
-
-	// Clear Key MIC field for MIC calculation later
-    NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
-
-	ConstructEapolKeyData(pEntry,
-						  GroupKeyWepStatus,
-						  KeyDescVer,
-						  MsgType,
-						  DefaultKeyIdx,
-						  GTK,
-						  RSNIE,
-						  RSNIE_Len,
-						  pMsg);
-
-	// Calculate MIC and fill in KeyMic Field except Pairwise Msg 1.
-	if (MsgType != EAPOL_PAIR_MSG_1)
-	{
-		CalculateMIC(KeyDescVer, pEntry->PTK, pMsg);
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> ConstructEapolMsg for %s %s\n", ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
-	DBGPRINT(RT_DEBUG_TRACE, ("	     Body length = %d \n", CONV_ARRARY_TO_UINT16(pMsg->Body_Len)));
-	DBGPRINT(RT_DEBUG_TRACE, ("	     Key length  = %d \n", CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyLength)));
-
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Construct the Key Data field of EAPoL message
-
-	Arguments:
-		pAd			Pointer	to our adapter
-		Elem		Message body
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	ConstructEapolKeyData(
-	IN	PMAC_TABLE_ENTRY	pEntry,
-	IN	UCHAR			GroupKeyWepStatus,
-	IN	UCHAR			keyDescVer,
-	IN	UCHAR			MsgType,
-	IN	UCHAR			DefaultKeyIdx,
-	IN	UCHAR			*GTK,
-	IN	UCHAR			*RSNIE,
-	IN	UCHAR			RSNIE_LEN,
-	OUT PEAPOL_PACKET   pMsg)
-{
-	UCHAR		*mpool, *Key_Data, *Rc4GTK;
-	UCHAR       ekey[(LEN_KEY_DESC_IV+LEN_EAP_EK)];
-	ULONG		data_offset;
-	BOOLEAN		bWPA2Capable = FALSE;
-	PRTMP_ADAPTER	pAd = pEntry->pAd;
-	BOOLEAN		GTK_Included = FALSE;
-
-	// Choose WPA2 or not
-	if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
-		(pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
-		bWPA2Capable = TRUE;
-
-	if (MsgType == EAPOL_PAIR_MSG_1 ||
-		MsgType == EAPOL_PAIR_MSG_4 ||
-		MsgType == EAPOL_GROUP_MSG_2)
-		return;
-
-	// allocate memory pool
-	os_alloc_mem(NULL, (PUCHAR *)&mpool, 1500);
-
-    if (mpool == NULL)
-		return;
-
-	/* Rc4GTK Len = 512 */
-	Rc4GTK = (UCHAR *) ROUND_UP(mpool, 4);
-	/* Key_Data Len = 512 */
-	Key_Data = (UCHAR *) ROUND_UP(Rc4GTK + 512, 4);
-
-	NdisZeroMemory(Key_Data, 512);
-	SET_UINT16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, 0);
-	data_offset = 0;
-
-	// Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3
-	if (RSNIE_LEN && ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3)))
-	{
-		PUINT8	pmkid_ptr = NULL;
-		UINT8	pmkid_len = 0;
-
-
-		RTMPInsertRSNIE(&Key_Data[data_offset],
-						(PULONG)&data_offset,
-						RSNIE,
-						RSNIE_LEN,
-						pmkid_ptr,
-						pmkid_len);
-	}
-
-
-	// Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2
-	if (bWPA2Capable && ((MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1)))
-	{
-		// Key Data Encapsulation (KDE) format - 802.11i-2004  Figure-43w and Table-20h
-        Key_Data[data_offset + 0] = 0xDD;
-
-		if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
-		{
-			Key_Data[data_offset + 1] = 0x16;// 4+2+16(OUI+DataType+DataField)
-		}
-		else
-		{
-			Key_Data[data_offset + 1] = 0x26;// 4+2+32(OUI+DataType+DataField)
-		}
-
-        Key_Data[data_offset + 2] = 0x00;
-        Key_Data[data_offset + 3] = 0x0F;
-        Key_Data[data_offset + 4] = 0xAC;
-        Key_Data[data_offset + 5] = 0x01;
-
-		// GTK KDE format - 802.11i-2004  Figure-43x
-        Key_Data[data_offset + 6] = (DefaultKeyIdx & 0x03);
-        Key_Data[data_offset + 7] = 0x00;	// Reserved Byte
-
-		data_offset += 8;
-	}
-
-
-	// Encapsulate GTK
-	// Only for pairwise_msg3_WPA2 and group_msg1
-	if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable) || (MsgType == EAPOL_GROUP_MSG_1))
-	{
-		// Fill in GTK
-		if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
-		{
-			NdisMoveMemory(&Key_Data[data_offset], GTK, LEN_AES_KEY);
-			data_offset += LEN_AES_KEY;
-		}
-		else
-		{
-			NdisMoveMemory(&Key_Data[data_offset], GTK, TKIP_GTK_LENGTH);
-			data_offset += TKIP_GTK_LENGTH;
-		}
-
-		GTK_Included = TRUE;
-	}
-
-
-	// This whole key-data field shall be encrypted if a GTK is included.
-	// Encrypt the data material in key data field with KEK
-	if (GTK_Included)
-	{
-		//hex_dump("GTK_Included", Key_Data, data_offset);
-
-		if (
-			(keyDescVer == DESC_TYPE_AES))
-		{
-			UCHAR	remainder = 0;
-			UCHAR	pad_len = 0;
-
-			// Key Descriptor Version 2 or 3: AES key wrap, defined in IETF RFC 3394,
-			// shall be used to encrypt the Key Data field using the KEK field from
-			// the derived PTK.
-
-			// If the Key Data field uses the NIST AES key wrap, then the Key Data field
-			// shall be padded before encrypting if the key data length is less than 16
-			// octets or if it is not a multiple of 8. The padding consists of appending
-			// a single octet 0xdd followed by zero or more 0x00 octets.
-			if ((remainder = data_offset & 0x07) != 0)
-			{
-				INT		i;
-
-				pad_len = (8 - remainder);
-				Key_Data[data_offset] = 0xDD;
-				for (i = 1; i < pad_len; i++)
-					Key_Data[data_offset + i] = 0;
-
-				data_offset += pad_len;
-			}
-
-			AES_GTK_KEY_WRAP(&pEntry->PTK[16], Key_Data, data_offset, Rc4GTK);
-            // AES wrap function will grow 8 bytes in length
-            data_offset += 8;
-		}
-		else
-		{
-			/*	Key Descriptor Version 1: ARC4 is used to encrypt the Key Data field
-				using the KEK field from the derived PTK. */
-
-			// PREPARE Encrypted  "Key DATA" field.  (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV)
-			// put TxTsc in Key RSC field
-			pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32;   //Init crc32.
-
-			// ekey is the contanetion of IV-field, and PTK[16]->PTK[31]
-			NdisMoveMemory(ekey, pMsg->KeyDesc.KeyIv, LEN_KEY_DESC_IV);
-			NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &pEntry->PTK[16], LEN_EAP_EK);
-			ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, ekey, sizeof(ekey));  //INIT SBOX, KEYLEN+3(IV)
-			pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, Key_Data, data_offset);
-			WPAARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, Rc4GTK, Key_Data, data_offset);
-		}
-
-		NdisMoveMemory(pMsg->KeyDesc.KeyData, Rc4GTK, data_offset);
-	}
-	else
-	{
-		NdisMoveMemory(pMsg->KeyDesc.KeyData, Key_Data, data_offset);
-	}
-
-	// Update key data length field and total body length
-	SET_UINT16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, data_offset);
-	INC_UINT16_TO_ARRARY(pMsg->Body_Len, data_offset);
-
-	os_free_mem(NULL, mpool);
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Calcaulate MIC. It is used during 4-ways handsharking.
-
-	Arguments:
-		pAd				-	pointer to our pAdapter context
-	PeerWepStatus	-	indicate the encryption type
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-static VOID	CalculateMIC(
-	IN	UCHAR			KeyDescVer,
-	IN	UCHAR			*PTK,
-	OUT PEAPOL_PACKET   pMsg)
-{
-    UCHAR   *OutBuffer;
-	ULONG	FrameLen = 0;
-	UCHAR	mic[LEN_KEY_DESC_MIC];
-	UCHAR	digest[80];
-
-	// allocate memory for MIC calculation
-	os_alloc_mem(NULL, (PUCHAR *)&OutBuffer, 512);
-
-    if (OutBuffer == NULL)
-    {
-		DBGPRINT(RT_DEBUG_ERROR, ("!!!CalculateMIC: no memory!!!\n"));
-		return;
-    }
-
-	// make a frame for calculating MIC.
-    MakeOutgoingFrame(OutBuffer,		&FrameLen,
-                      CONV_ARRARY_TO_UINT16(pMsg->Body_Len) + 4,	pMsg,
-                      END_OF_ARGS);
-
-	NdisZeroMemory(mic, sizeof(mic));
-
-	// Calculate MIC
-    if (KeyDescVer == DESC_TYPE_AES)
-	{
-		HMAC_SHA1(PTK, LEN_EAP_MICK, OutBuffer,  FrameLen, digest, SHA1_DIGEST_SIZE);
-		NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
-	}
-	else
-	{
-		HMAC_MD5(PTK,  LEN_EAP_MICK, OutBuffer, FrameLen, mic, MD5_DIGEST_SIZE);
-	}
-
-	// store the calculated MIC
-	NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC);
-
-	os_free_mem(NULL, OutBuffer);
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Some received frames can't decrypt by Asic, so decrypt them by software.
-
-	Arguments:
-		pAd				-	pointer to our pAdapter context
-	PeerWepStatus	-	indicate the encryption type
-
-	Return Value:
-		NDIS_STATUS_SUCCESS		-	decryption successful
-		NDIS_STATUS_FAILURE		-	decryption failure
-
-	========================================================================
-*/
-NDIS_STATUS	RTMPSoftDecryptBroadCastData(
-	IN	PRTMP_ADAPTER					pAd,
-	IN	RX_BLK							*pRxBlk,
-	IN  NDIS_802_11_ENCRYPTION_STATUS	GroupCipher,
-	IN  PCIPHER_KEY						pShard_key)
-{
-	PRXWI_STRUC			pRxWI = pRxBlk->pRxWI;
-
-
-
-	// handle WEP decryption
-	if (GroupCipher == Ndis802_11Encryption1Enabled)
-    {
-		if (RTMPSoftDecryptWEP(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, pShard_key))
-		{
-
-			//Minus IV[4] & ICV[4]
-			pRxWI->MPDUtotalByteCount -= 8;
-		}
-		else
-		{
-			DBGPRINT(RT_DEBUG_ERROR, ("ERROR : Software decrypt WEP data fails.\n"));
-			// give up this frame
-			return NDIS_STATUS_FAILURE;
-		}
-	}
-	// handle TKIP decryption
-	else if (GroupCipher == Ndis802_11Encryption2Enabled)
-	{
-		if (RTMPSoftDecryptTKIP(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, 0, pShard_key))
-		{
-
-			//Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV
-			pRxWI->MPDUtotalByteCount -= 20;
-		}
-        else
-		{
-			DBGPRINT(RT_DEBUG_ERROR, ("ERROR : RTMPSoftDecryptTKIP Failed\n"));
-			// give up this frame
-			return NDIS_STATUS_FAILURE;
-        }
-	}
-	// handle AES decryption
-	else if (GroupCipher == Ndis802_11Encryption3Enabled)
-	{
-		if (RTMPSoftDecryptAES(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount , pShard_key))
-		{
-
-			//8 bytes MIC, 8 bytes IV/EIV (CCMP Header)
-			pRxWI->MPDUtotalByteCount -= 16;
-		}
-		else
-		{
-			DBGPRINT(RT_DEBUG_ERROR, ("ERROR : RTMPSoftDecryptAES Failed\n"));
-			// give up this frame
-			return NDIS_STATUS_FAILURE;
-		}
-	}
-	else
-	{
-		// give up this frame
-		return NDIS_STATUS_FAILURE;
-	}
-
-	return NDIS_STATUS_SUCCESS;
-
-}
-
-
-PUINT8	GetSuiteFromRSNIE(
-		IN	PUINT8	rsnie,
-		IN	UINT	rsnie_len,
-		IN	UINT8	type,
-		OUT	UINT8	*count)
-{
-	PEID_STRUCT pEid;
-	INT			len;
-	PUINT8		pBuf;
-	INT			offset = 0;
-	PRSNIE_AUTH	pAkm;
-	UINT16		acount;
-	BOOLEAN		isWPA2 = FALSE;
-
-	pEid = (PEID_STRUCT)rsnie;
-	len = rsnie_len - 2;	// exclude IE and length
-	pBuf = (PUINT8)&pEid->Octet[0];
-
-
-
-	// set default value
-	*count = 0;
-
-	// Check length
-	if ((len <= 0) || (pEid->Len != len))
-	{
-		DBGPRINT_ERR(("%s : The length is invalid\n", __FUNCTION__));
-		return NULL;
-	}
-
-	// Check WPA or WPA2
-	if (pEid->Eid == IE_WPA)
-	{
-		PRSNIE	pRsnie = (PRSNIE)pBuf;
-		UINT16 ucount;
-
-		if (len < sizeof(RSNIE))
-		{
-			DBGPRINT_ERR(("%s : The length is too short for WPA\n", __FUNCTION__));
-			return NULL;
-		}
-
-		// Get the count of pairwise cipher
-		ucount = cpu2le16(pRsnie->ucount);
-		if (ucount > 2)
-		{
-			DBGPRINT_ERR(("%s : The count(%d) of pairwise cipher is invlaid\n",
-											__FUNCTION__, ucount));
-			return NULL;
-		}
-
-		// Get the group cipher
-		if (type == GROUP_SUITE)
-		{
-			*count = 1;
-			return pRsnie->mcast;
-		}
-		// Get the pairwise cipher suite
-		else if (type == PAIRWISE_SUITE)
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of pairwise cipher is %d\n",
-										__FUNCTION__, ucount));
-			*count = ucount;
-			return pRsnie->ucast[0].oui;
-		}
-
-		offset = sizeof(RSNIE) + (4 * (ucount - 1));
-
-	}
-	else if (pEid->Eid == IE_RSN)
-	{
-		PRSNIE2	pRsnie = (PRSNIE2)pBuf;
-		UINT16 ucount;
-
-		isWPA2 = TRUE;
-
-		if (len < sizeof(RSNIE2))
-		{
-			DBGPRINT_ERR(("%s : The length is too short for WPA2\n", __FUNCTION__));
-			return NULL;
-		}
-
-		// Get the count of pairwise cipher
-		ucount = cpu2le16(pRsnie->ucount);
-		if (ucount > 2)
-		{
-			DBGPRINT_ERR(("%s : The count(%d) of pairwise cipher is invlaid\n",
-											__FUNCTION__, ucount));
-			return NULL;
-		}
-
-		// Get the group cipher
-		if (type == GROUP_SUITE)
-		{
-			*count = 1;
-			return pRsnie->mcast;
-		}
-		// Get the pairwise cipher suite
-		else if (type == PAIRWISE_SUITE)
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of pairwise cipher is %d\n",
-										__FUNCTION__, ucount));
-			*count = ucount;
-			return pRsnie->ucast[0].oui;
-		}
-
-		offset = sizeof(RSNIE2) + (4 * (ucount - 1));
-
-	}
-	else
-	{
-		DBGPRINT_ERR(("%s : Unknown IE (%d)\n", __FUNCTION__, pEid->Eid));
-		return NULL;
-	}
-
-	// skip group cipher and pairwise cipher suite
-	pBuf += offset;
-	len -= offset;
-
-	if (len < sizeof(RSNIE_AUTH))
-	{
-		DBGPRINT_ERR(("%s : The length of RSNIE is too short\n", __FUNCTION__));
-		return NULL;
-	}
-
-	// pointer to AKM count
-	pAkm = (PRSNIE_AUTH)pBuf;
-
-	// Get the count of pairwise cipher
-	acount = cpu2le16(pAkm->acount);
-	if (acount > 2)
-	{
-		DBGPRINT_ERR(("%s : The count(%d) of AKM is invlaid\n",
-										__FUNCTION__, acount));
-		return NULL;
-	}
-
-	// Get the AKM suite
-	if (type == AKM_SUITE)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of AKM is %d\n",
-									__FUNCTION__, acount));
-		*count = acount;
-		return pAkm->auth[0].oui;
-	}
-	offset = sizeof(RSNIE_AUTH) + (4 * (acount - 1));
-
-	pBuf += offset;
-	len -= offset;
-
-	// The remaining length must larger than (RSN-Capability(2) + PMKID-Count(2) + PMKID(16~))
-	if (len >= (sizeof(RSN_CAPABILITIES) + 2 + LEN_PMKID))
-	{
-		// Skip RSN capability and PMKID-Count
-		pBuf += (sizeof(RSN_CAPABILITIES) + 2);
-		len -= (sizeof(RSN_CAPABILITIES) + 2);
-
-		// Get PMKID
-		if (type == PMKID_LIST)
-		{
-			*count = 1;
-			return pBuf;
-		}
-	}
-	else
-	{
-		DBGPRINT_ERR(("%s : it can't get any more information beyond AKM \n", __FUNCTION__));
-		return NULL;
-	}
-
-	*count = 0;
-	//DBGPRINT_ERR(("%s : The type(%d) doesn't support \n", __FUNCTION__, type));
-	return NULL;
-
-}
-
-VOID WpaShowAllsuite(
-	IN	PUINT8	rsnie,
-	IN	UINT	rsnie_len)
-{
-	PUINT8 pSuite = NULL;
-	UINT8 count;
-
-	hex_dump("RSNIE", rsnie, rsnie_len);
-
-	// group cipher
-	if ((pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, GROUP_SUITE, &count)) != NULL)
-	{
-		hex_dump("group cipher", pSuite, 4*count);
-	}
-
-	// pairwise cipher
-	if ((pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PAIRWISE_SUITE, &count)) != NULL)
-	{
-		hex_dump("pairwise cipher", pSuite, 4*count);
-	}
-
-	// AKM
-	if ((pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, AKM_SUITE, &count)) != NULL)
-	{
-		hex_dump("AKM suite", pSuite, 4*count);
-	}
-
-	// PMKID
-	if ((pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PMKID_LIST, &count)) != NULL)
-	{
-		hex_dump("PMKID", pSuite, LEN_PMKID);
-	}
-
-}
-
-VOID RTMPInsertRSNIE(
-	IN PUCHAR pFrameBuf,
-	OUT PULONG pFrameLen,
-	IN PUINT8 rsnie_ptr,
-	IN UINT8  rsnie_len,
-	IN PUINT8 pmkid_ptr,
-	IN UINT8  pmkid_len)
-{
-	PUCHAR	pTmpBuf;
-	ULONG	TempLen = 0;
-	UINT8	extra_len = 0;
-	UINT16	pmk_count = 0;
-	UCHAR	ie_num;
-	UINT8	total_len = 0;
-    UCHAR	WPA2_OUI[3]={0x00,0x0F,0xAC};
-
-	pTmpBuf = pFrameBuf;
-
-	/* PMKID-List Must larger than 0 and the multiple of 16. */
-	if (pmkid_len > 0 && ((pmkid_len & 0x0f) == 0))
-	{
-		extra_len = sizeof(UINT16) + pmkid_len;
-
-		pmk_count = (pmkid_len >> 4);
-		pmk_count = cpu2le16(pmk_count);
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_WARN, ("%s : The length is PMKID-List is invalid (%d), so don't insert it.\n",
-									__FUNCTION__, pmkid_len));
-	}
-
-	if (rsnie_len != 0)
-	{
-		ie_num = IE_WPA;
-		total_len = rsnie_len;
-
-		if (NdisEqualMemory(rsnie_ptr + 2, WPA2_OUI, sizeof(WPA2_OUI)))
-		{
-			ie_num = IE_RSN;
-			total_len += extra_len;
-		}
-
-		/* construct RSNIE body */
-		MakeOutgoingFrame(pTmpBuf,			&TempLen,
-						  1,				&ie_num,
-						  1,				&total_len,
-						  rsnie_len,		rsnie_ptr,
-						  END_OF_ARGS);
-
-		pTmpBuf += TempLen;
-		*pFrameLen = *pFrameLen + TempLen;
-
-		if (ie_num == IE_RSN)
-		{
-			/* Insert PMKID-List field */
-			if (extra_len > 0)
-			{
-				MakeOutgoingFrame(pTmpBuf,					&TempLen,
-								  2,						&pmk_count,
-								  pmkid_len,				pmkid_ptr,
-								  END_OF_ARGS);
-
-				pTmpBuf += TempLen;
-				*pFrameLen = *pFrameLen + TempLen;
-			}
-		}
-	}
-
-	return;
-}
diff --git a/drivers/staging/rt3090/common/crypt_aes.c b/drivers/staging/rt3090/common/crypt_aes.c
deleted file mode 100644
index f400f1e..0000000
--- a/drivers/staging/rt3090/common/crypt_aes.c
+++ /dev/null
@@ -1,1007 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	crypt_aes.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-        Eddy        2009/01/19      Create AES-128, AES-192, AES-256, AES-CBC
-*/
-
-#include "crypt_aes.h"
-
-/* The value given by [x^(i-1),{00},{00},{00}], with x^(i-1) being powers of x in the field GF(2^8). */
-static const UINT32 aes_rcon[] = {
-	0x00000000, 0x01000000, 0x02000000, 0x04000000,
-    0x08000000, 0x10000000, 0x20000000, 0x40000000,
-    0x80000000, 0x1B000000, 0x36000000};
-
-static const UINT8 aes_sbox_enc[] = {
-  /*  0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f    */
-    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7 ,0xab, 0x76, /* 0 */
-    0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4 ,0x72, 0xc0, /* 1 */
-    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8 ,0x31, 0x15, /* 2 */
-    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27 ,0xb2, 0x75, /* 3 */
-    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3 ,0x2f, 0x84, /* 4 */
-    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c ,0x58, 0xcf, /* 5 */
-    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c ,0x9f, 0xa8, /* 6 */
-    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff ,0xf3, 0xd2, /* 7 */
-    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d ,0x19, 0x73, /* 8 */
-    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e ,0x0b, 0xdb, /* 9 */
-    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95 ,0xe4, 0x79, /* a */
-    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a ,0xae, 0x08, /* b */
-    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd ,0x8b, 0x8a, /* c */
-    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1 ,0x1d, 0x9e, /* d */
-    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55 ,0x28, 0xdf, /* e */
-    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54 ,0xbb, 0x16, /* f */
-};
-
-static const UINT8 aes_sbox_dec[] = {
-  /*  0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f    */
-    0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, /* 0 */
-    0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, /* 1 */
-    0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, /* 2 */
-    0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, /* 3 */
-    0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, /* 4 */
-    0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, /* 5 */
-    0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, /* 6 */
-    0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, /* 7 */
-    0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, /* 8 */
-    0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, /* 9 */
-    0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, /* a */
-    0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, /* b */
-    0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, /* c */
-    0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, /* d */
-    0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, /* e */
-    0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d, /* f */
-};
-
-/* ArrayIndex*{02} */
-static const UINT8 aes_mul_2[] = {
-  /*  0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f    */
-    0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, /* 0 */
-    0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, /* 1 */
-    0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, /* 2 */
-    0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, /* 3 */
-    0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, /* 4 */
-    0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, /* 5 */
-    0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, /* 6 */
-    0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, /* 7 */
-    0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05, /* 8 */
-    0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25, /* 9 */
-    0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, /* a */
-    0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65, /* b */
-    0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85, /* c */
-    0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, /* d */
-    0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5, /* e */
-    0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5, /* f */
-};
-
-/* ArrayIndex*{03} */
-static const UINT8 aes_mul_3[] = {
-  /*  0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f    */
-    0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11, /* 0 */
-    0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, /* 1 */
-    0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71, /* 2 */
-    0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41, /* 3 */
-    0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, /* 4 */
-    0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1, /* 5 */
-    0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1, /* 6 */
-    0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, /* 7 */
-    0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a, /* 8 */
-    0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba, /* 9 */
-    0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, /* a */
-    0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda, /* b */
-    0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a, /* c */
-    0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, /* d */
-    0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a, /* e */
-    0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a, /* f */
-};
-
-/* ArrayIndex*{09} */
-static const UINT8 aes_mul_9[] = {
-  /*  0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f    */
-    0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, /* 0 */
-    0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7, /* 1 */
-    0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, /* 2 */
-    0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc, /* 3 */
-    0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49, 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01, /* 4 */
-    0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91, /* 5 */
-    0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a, /* 6 */
-    0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2, 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa, /* 7 */
-    0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b, /* 8 */
-    0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b, /* 9 */
-    0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8, 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0, /* a */
-    0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30, /* b */
-    0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed, /* c */
-    0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d, /* d */
-    0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6, /* e */
-    0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46, /* f */
-};
-
-/* ArrayIndex*{0b} */
-static const UINT8 aes_mul_b[] = {
-  /*  0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f    */
-    0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69, /* 0 */
-    0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9, /* 1 */
-    0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12, /* 2 */
-    0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2, /* 3 */
-    0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7, 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f, /* 4 */
-    0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f, /* 5 */
-    0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4, /* 6 */
-    0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c, 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54, /* 7 */
-    0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e, /* 8 */
-    0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e, /* 9 */
-    0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd, 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5, /* a */
-    0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55, /* b */
-    0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68, /* c */
-    0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8, /* d */
-    0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13, /* e */
-    0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3, /* f */
-};
-
-/* ArrayIndex*{0d} */
-static const UINT8 aes_mul_d[] = {
-  /*  0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f    */
-    0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b, /* 0 */
-    0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b, /* 1 */
-    0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0, /* 2 */
-    0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20, /* 3 */
-    0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e, 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26, /* 4 */
-    0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6, /* 5 */
-    0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d, /* 6 */
-    0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25, 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d, /* 7 */
-    0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91, /* 8 */
-    0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41, /* 9 */
-    0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42, 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a, /* a */
-    0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa, /* b */
-    0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc, /* c */
-    0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c, /* d */
-    0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47, /* e */
-    0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97, /* f */
-};
-
-/* ArrayIndex*{0e} */
-static const UINT8 aes_mul_e[] = {
-  /*  0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f    */
-    0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a, /* 0 */
-    0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba, /* 1 */
-    0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81, /* 2 */
-    0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61, /* 3 */
-    0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87, 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7, /* 4 */
-    0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17, /* 5 */
-    0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c, /* 6 */
-    0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc, 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc, /* 7 */
-    0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b, /* 8 */
-    0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb, /* 9 */
-    0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0, 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0, /* a */
-    0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20, /* b */
-    0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6, /* c */
-    0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56, /* d */
-    0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d, /* e */
-    0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d, /* f */
-};
-
-
-/* For AES_CMAC */
-#define AES_MAC_LENGTH 16 /* 128-bit string */
-static UINT8 Const_Zero[16] = {
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-static UINT8 Const_Rb[16] = {
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87};
-
-
-/*
-========================================================================
-Routine Description:
-    AES key expansion (key schedule)
-
-Arguments:
-    Key              Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
-    KeyLength        The length of cipher key in bytes
-    paes_ctx         Pointer to AES_CTX_STRUC
-
-Return Value:
-    paes_ctx         Retrun the KeyWordExpansion of AES_CTX_STRUC
-
-Note:
-    Pseudo code for key expansion
-    ------------------------------------------
-       Nk = (key length/4);
-
-       while (i < Nk)
-           KeyWordExpansion[i] = word(key[4*i], key[4*i + 1], key[4*i + 2], key[4*i + 3]);
-           i++;
-       end while
-
-       while (i < ((key length/4 + 6 + 1)*4) )
-           temp = KeyWordExpansion[i - 1];
-           if (i % Nk ==0)
-               temp = SubWord(RotWord(temp)) ^ Rcon[i/Nk];
-           else if ((Nk > 6) && (i % 4 == 4))
-               temp = SubWord(temp);
-           end if
-
-           KeyWordExpansion[i] = KeyWordExpansion[i - Nk]^ temp;
-           i++;
-       end while
-========================================================================
-*/
-VOID AES_KeyExpansion (
-    IN UINT8 Key[],
-    IN UINT KeyLength,
-    INOUT AES_CTX_STRUC *paes_ctx)
-{
-    UINT KeyIndex = 0;
-    UINT NumberOfWordOfKey, NumberOfWordOfKeyExpansion;
-    UINT8  TempWord[AES_KEY_ROWS], Temp;
-    UINT32 Temprcon;
-
-    NumberOfWordOfKey = KeyLength >> 2;
-    while (KeyIndex < NumberOfWordOfKey)
-    {
-        paes_ctx->KeyWordExpansion[0][KeyIndex] = Key[4*KeyIndex];
-        paes_ctx->KeyWordExpansion[1][KeyIndex] = Key[4*KeyIndex + 1];
-        paes_ctx->KeyWordExpansion[2][KeyIndex] = Key[4*KeyIndex + 2];
-        paes_ctx->KeyWordExpansion[3][KeyIndex] = Key[4*KeyIndex + 3];
-        KeyIndex++;
-    } /* End of while */
-
-    NumberOfWordOfKeyExpansion = ((UINT) AES_KEY_ROWS) * ((KeyLength >> 2) + 6 + 1);
-    while (KeyIndex < NumberOfWordOfKeyExpansion)
-    {
-        TempWord[0] = paes_ctx->KeyWordExpansion[0][KeyIndex - 1];
-        TempWord[1] = paes_ctx->KeyWordExpansion[1][KeyIndex - 1];
-        TempWord[2] = paes_ctx->KeyWordExpansion[2][KeyIndex - 1];
-        TempWord[3] = paes_ctx->KeyWordExpansion[3][KeyIndex - 1];
-        if ((KeyIndex % NumberOfWordOfKey) == 0) {
-            Temprcon = aes_rcon[KeyIndex/NumberOfWordOfKey];
-            Temp = aes_sbox_enc[TempWord[1]]^((Temprcon >> 24) & 0xff);
-            TempWord[1] = aes_sbox_enc[TempWord[2]]^((Temprcon >> 16) & 0xff);
-            TempWord[2] = aes_sbox_enc[TempWord[3]]^((Temprcon >>  8) & 0xff);
-            TempWord[3] = aes_sbox_enc[TempWord[0]]^((Temprcon      ) & 0xff);
-            TempWord[0] = Temp;
-        } else if ((NumberOfWordOfKey > 6) && ((KeyIndex % NumberOfWordOfKey) == 4)) {
-            Temp = aes_sbox_enc[TempWord[0]];
-            TempWord[1] = aes_sbox_enc[TempWord[1]];
-            TempWord[2] = aes_sbox_enc[TempWord[2]];
-            TempWord[3] = aes_sbox_enc[TempWord[3]];
-            TempWord[0] = Temp;
-        }
-        paes_ctx->KeyWordExpansion[0][KeyIndex] = paes_ctx->KeyWordExpansion[0][KeyIndex - NumberOfWordOfKey]^TempWord[0];
-        paes_ctx->KeyWordExpansion[1][KeyIndex] = paes_ctx->KeyWordExpansion[1][KeyIndex - NumberOfWordOfKey]^TempWord[1];
-        paes_ctx->KeyWordExpansion[2][KeyIndex] = paes_ctx->KeyWordExpansion[2][KeyIndex - NumberOfWordOfKey]^TempWord[2];
-        paes_ctx->KeyWordExpansion[3][KeyIndex] = paes_ctx->KeyWordExpansion[3][KeyIndex - NumberOfWordOfKey]^TempWord[3];
-        KeyIndex++;
-    } /* End of while */
-} /* End of AES_KeyExpansion */
-
-
-/*
-========================================================================
-Routine Description:
-    AES encryption
-
-Arguments:
-    PlainBlock       The block of plain text, 16 bytes(128 bits) each block
-    PlainBlockSize   The length of block of plain text in bytes
-    Key              Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
-    KeyLength        The length of cipher key in bytes
-    CipherBlockSize  The length of allocated cipher block in bytes
-
-Return Value:
-    CipherBlock      Return cipher text
-    CipherBlockSize  Return the length of real used cipher block in bytes
-
-Note:
-    Reference to FIPS-PUB 197
-    1. Check if block size is 16 bytes(128 bits) and if key length is 16, 24, or 32 bytes(128, 192, or 256 bits)
-    2. Transfer the plain block to state block
-    3. Main encryption rounds
-    4. Transfer the state block to cipher block
-    ------------------------------------------
-       NumberOfRound = (key length / 4) + 6;
-       state block = plain block;
-
-       AddRoundKey(state block, key);
-       for round = 1 to NumberOfRound
-           SubBytes(state block)
-           ShiftRows(state block)
-           MixColumns(state block)
-           AddRoundKey(state block, key);
-       end for
-
-       SubBytes(state block)
-       ShiftRows(state block)
-       AddRoundKey(state block, key);
-
-       cipher block = state block;
-========================================================================
-*/
-VOID AES_Encrypt (
-    IN UINT8 PlainBlock[],
-    IN UINT PlainBlockSize,
-    IN UINT8 Key[],
-    IN UINT KeyLength,
-    OUT UINT8 CipherBlock[],
-    INOUT UINT *CipherBlockSize)
-{
-    AES_CTX_STRUC aes_ctx;
-    UINT RowIndex, ColumnIndex;
-    UINT RoundIndex, NumberOfRound = 0;
-    UINT8 Temp, Row0, Row1, Row2, Row3;
-
-    /*
-     * 1. Check if block size is 16 bytes(128 bits) and if key length is 16, 24, or 32 bytes(128, 192, or 256 bits)
-     */
-    if (PlainBlockSize != AES_BLOCK_SIZES) {
-	DBGPRINT(RT_DEBUG_ERROR, ("AES_Encrypt: plain block size is %d bytes, it must be %d bytes(128 bits).\n",
-            PlainBlockSize, AES_BLOCK_SIZES));
-        return;
-    } /* End of if */
-    if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) {
-	DBGPRINT(RT_DEBUG_ERROR, ("AES_Encrypt: key length is %d bytes, it must be %d, %d, or %d bytes(128, 192, or 256 bits).\n",
-            KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH));
-        return;
-    } /* End of if */
-    if (*CipherBlockSize < AES_BLOCK_SIZES) {
-	DBGPRINT(RT_DEBUG_ERROR, ("AES_Encrypt: cipher block size is %d bytes, it must be %d bytes(128 bits).\n",
-            *CipherBlockSize, AES_BLOCK_SIZES));
-        return;
-    } /* End of if */
-
-    /*
-     * 2. Transfer the plain block to state block
-     */
-    for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
-        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
-            aes_ctx.State[RowIndex][ColumnIndex] = PlainBlock[RowIndex + 4*ColumnIndex];
-
-    /*
-     *  3. Main encryption rounds
-     */
-    AES_KeyExpansion(Key, KeyLength, &aes_ctx);
-    NumberOfRound = (KeyLength >> 2) + 6;
-
-    /* AES_AddRoundKey */
-    RoundIndex = 0;
-    for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
-        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
-            aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
-
-    for (RoundIndex = 1; RoundIndex < NumberOfRound;RoundIndex++)
-    {
-        /* AES_SubBytes */
-        for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
-            for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
-                aes_ctx.State[RowIndex][ColumnIndex] = aes_sbox_enc[aes_ctx.State[RowIndex][ColumnIndex]];
-
-        /* AES_ShiftRows */
-        Temp = aes_ctx.State[1][0];
-        aes_ctx.State[1][0] = aes_ctx.State[1][1];
-        aes_ctx.State[1][1] = aes_ctx.State[1][2];
-        aes_ctx.State[1][2] = aes_ctx.State[1][3];
-        aes_ctx.State[1][3] = Temp;
-        Temp = aes_ctx.State[2][0];
-        aes_ctx.State[2][0] = aes_ctx.State[2][2];
-        aes_ctx.State[2][2] = Temp;
-        Temp = aes_ctx.State[2][1];
-        aes_ctx.State[2][1] = aes_ctx.State[2][3];
-        aes_ctx.State[2][3] = Temp;
-        Temp = aes_ctx.State[3][3];
-        aes_ctx.State[3][3] = aes_ctx.State[3][2];
-        aes_ctx.State[3][2] = aes_ctx.State[3][1];
-        aes_ctx.State[3][1] = aes_ctx.State[3][0];
-        aes_ctx.State[3][0] = Temp;
-
-        /* AES_MixColumns */
-        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
-        {
-            Row0 = aes_ctx.State[0][ColumnIndex];
-            Row1 = aes_ctx.State[1][ColumnIndex];
-            Row2 = aes_ctx.State[2][ColumnIndex];
-            Row3 = aes_ctx.State[3][ColumnIndex];
-            aes_ctx.State[0][ColumnIndex] = aes_mul_2[Row0]^aes_mul_3[Row1]^Row2^Row3;
-            aes_ctx.State[1][ColumnIndex] = Row0^aes_mul_2[Row1]^aes_mul_3[Row2]^Row3;
-            aes_ctx.State[2][ColumnIndex] = Row0^Row1^aes_mul_2[Row2]^aes_mul_3[Row3];
-            aes_ctx.State[3][ColumnIndex] = aes_mul_3[Row0]^Row1^Row2^aes_mul_2[Row3];
-        }
-
-        /* AES_AddRoundKey */
-        for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
-            for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
-                aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
-    } /* End of for */
-
-    /* AES_SubBytes */
-    for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
-        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
-            aes_ctx.State[RowIndex][ColumnIndex] = aes_sbox_enc[aes_ctx.State[RowIndex][ColumnIndex]];
-    /* AES_ShiftRows */
-    Temp = aes_ctx.State[1][0];
-    aes_ctx.State[1][0] = aes_ctx.State[1][1];
-    aes_ctx.State[1][1] = aes_ctx.State[1][2];
-    aes_ctx.State[1][2] = aes_ctx.State[1][3];
-    aes_ctx.State[1][3] = Temp;
-    Temp = aes_ctx.State[2][0];
-    aes_ctx.State[2][0] = aes_ctx.State[2][2];
-    aes_ctx.State[2][2] = Temp;
-    Temp = aes_ctx.State[2][1];
-    aes_ctx.State[2][1] = aes_ctx.State[2][3];
-    aes_ctx.State[2][3] = Temp;
-    Temp = aes_ctx.State[3][3];
-    aes_ctx.State[3][3] = aes_ctx.State[3][2];
-    aes_ctx.State[3][2] = aes_ctx.State[3][1];
-    aes_ctx.State[3][1] = aes_ctx.State[3][0];
-    aes_ctx.State[3][0] = Temp;
-    /* AES_AddRoundKey */
-    for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
-        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
-            aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
-
-    /*
-     * 4. Transfer the state block to cipher block
-     */
-    for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
-        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
-            CipherBlock[RowIndex + 4*ColumnIndex] = aes_ctx.State[RowIndex][ColumnIndex];
-
-    *CipherBlockSize = ((UINT) AES_STATE_ROWS)*((UINT) AES_STATE_COLUMNS);
-} /* End of AES_Encrypt */
-
-
-/*
-========================================================================
-Routine Description:
-    AES decryption
-
-Arguments:
-    CipherBlock      The block of cipher text, 16 bytes(128 bits) each block
-    CipherBlockSize  The length of block of cipher text in bytes
-    Key              Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
-    KeyLength        The length of cipher key in bytes
-    PlainBlockSize   The length of allocated plain block in bytes
-
-Return Value:
-    PlainBlock       Return plain text
-    PlainBlockSize  Return the length of real used plain block in bytes
-
-Note:
-    Reference to FIPS-PUB 197
-    1. Check if block size is 16 bytes(128 bits) and if key length is 16, 24, or 32 bytes(128, 192, or 256 bits)
-    2. Transfer the cipher block to state block
-    3. Main decryption rounds
-    4. Transfer the state block to plain block
-    ------------------------------------------
-       NumberOfRound = (key length / 4) + 6;
-       state block = cipher block;
-
-       AddRoundKey(state block, key);
-       for round = NumberOfRound to 1
-           InvSubBytes(state block)
-           InvShiftRows(state block)
-           InvMixColumns(state block)
-           AddRoundKey(state block, key);
-       end for
-
-       InvSubBytes(state block)
-       InvShiftRows(state block)
-       AddRoundKey(state block, key);
-
-       plain block = state block;
-========================================================================
-*/
-VOID AES_Decrypt (
-    IN UINT8 CipherBlock[],
-    IN UINT CipherBlockSize,
-    IN UINT8 Key[],
-    IN UINT KeyLength,
-    OUT UINT8 PlainBlock[],
-    INOUT UINT *PlainBlockSize)
-{
-    AES_CTX_STRUC aes_ctx;
-    UINT RowIndex, ColumnIndex;
-    UINT RoundIndex, NumberOfRound = 0;
-    UINT8 Temp, Row0, Row1, Row2, Row3;
-
-    /*
-     * 1. Check if block size is 16 bytes(128 bits) and if key length is 16, 24, or 32 bytes(128, 192, or 256 bits)
-     */
-    if (*PlainBlockSize < AES_BLOCK_SIZES) {
-	DBGPRINT(RT_DEBUG_ERROR, ("AES_Decrypt: plain block size is %d bytes, it must be %d bytes(128 bits).\n",
-            *PlainBlockSize, AES_BLOCK_SIZES));
-        return;
-    } /* End of if */
-    if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) {
-	DBGPRINT(RT_DEBUG_ERROR, ("AES_Decrypt: key length is %d bytes, it must be %d, %d, or %d bytes(128, 192, or 256 bits).\n",
-            KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH));
-        return;
-    } /* End of if */
-    if (CipherBlockSize != AES_BLOCK_SIZES) {
-	DBGPRINT(RT_DEBUG_ERROR, ("AES_Decrypt: cipher block size is %d bytes, it must be %d bytes(128 bits).\n",
-            CipherBlockSize, AES_BLOCK_SIZES));
-        return;
-    } /* End of if */
-
-    /*
-     * 2. Transfer the cipher block to state block
-     */
-    for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
-        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
-            aes_ctx.State[RowIndex][ColumnIndex] = CipherBlock[RowIndex + 4*ColumnIndex];
-
-    /*
-     *  3. Main decryption rounds
-     */
-    AES_KeyExpansion(Key, KeyLength, &aes_ctx);
-    NumberOfRound = (KeyLength >> 2) + 6;
-
-    /* AES_AddRoundKey */
-    RoundIndex = NumberOfRound;
-    for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
-        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
-            aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
-
-    for (RoundIndex = (NumberOfRound - 1); RoundIndex > 0 ;RoundIndex--)
-    {
-        /* AES_InvShiftRows */
-        Temp = aes_ctx.State[1][3];
-        aes_ctx.State[1][3] = aes_ctx.State[1][2];
-        aes_ctx.State[1][2] = aes_ctx.State[1][1];
-        aes_ctx.State[1][1] = aes_ctx.State[1][0];
-        aes_ctx.State[1][0] = Temp;
-        Temp = aes_ctx.State[2][0];
-        aes_ctx.State[2][0] = aes_ctx.State[2][2];
-        aes_ctx.State[2][2] = Temp;
-        Temp = aes_ctx.State[2][1];
-        aes_ctx.State[2][1] = aes_ctx.State[2][3];
-        aes_ctx.State[2][3] = Temp;
-        Temp = aes_ctx.State[3][0];
-        aes_ctx.State[3][0] = aes_ctx.State[3][1];
-        aes_ctx.State[3][1] = aes_ctx.State[3][2];
-        aes_ctx.State[3][2] = aes_ctx.State[3][3];
-        aes_ctx.State[3][3] = Temp;
-
-        /* AES_InvSubBytes */
-        for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
-            for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
-                aes_ctx.State[RowIndex][ColumnIndex] = aes_sbox_dec[aes_ctx.State[RowIndex][ColumnIndex]];
-
-        /* AES_AddRoundKey */
-        for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
-            for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
-                aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
-
-        /* AES_InvMixColumns */
-        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
-        {
-            Row0 = aes_ctx.State[0][ColumnIndex];
-            Row1 = aes_ctx.State[1][ColumnIndex];
-            Row2 = aes_ctx.State[2][ColumnIndex];
-            Row3 = aes_ctx.State[3][ColumnIndex];
-            aes_ctx.State[0][ColumnIndex] = aes_mul_e[Row0]^aes_mul_b[Row1]^aes_mul_d[Row2]^aes_mul_9[Row3];
-            aes_ctx.State[1][ColumnIndex] = aes_mul_9[Row0]^aes_mul_e[Row1]^aes_mul_b[Row2]^aes_mul_d[Row3];
-            aes_ctx.State[2][ColumnIndex] = aes_mul_d[Row0]^aes_mul_9[Row1]^aes_mul_e[Row2]^aes_mul_b[Row3];
-            aes_ctx.State[3][ColumnIndex] = aes_mul_b[Row0]^aes_mul_d[Row1]^aes_mul_9[Row2]^aes_mul_e[Row3];
-        }
-    } /* End of for */
-
-    /* AES_InvShiftRows */
-    Temp = aes_ctx.State[1][3];
-    aes_ctx.State[1][3] = aes_ctx.State[1][2];
-    aes_ctx.State[1][2] = aes_ctx.State[1][1];
-    aes_ctx.State[1][1] = aes_ctx.State[1][0];
-    aes_ctx.State[1][0] = Temp;
-    Temp = aes_ctx.State[2][0];
-    aes_ctx.State[2][0] = aes_ctx.State[2][2];
-    aes_ctx.State[2][2] = Temp;
-    Temp = aes_ctx.State[2][1];
-    aes_ctx.State[2][1] = aes_ctx.State[2][3];
-    aes_ctx.State[2][3] = Temp;
-    Temp = aes_ctx.State[3][0];
-    aes_ctx.State[3][0] = aes_ctx.State[3][1];
-    aes_ctx.State[3][1] = aes_ctx.State[3][2];
-    aes_ctx.State[3][2] = aes_ctx.State[3][3];
-    aes_ctx.State[3][3] = Temp;
-    /* AES_InvSubBytes */
-    for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
-        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
-            aes_ctx.State[RowIndex][ColumnIndex] = aes_sbox_dec[aes_ctx.State[RowIndex][ColumnIndex]];
-    /* AES_AddRoundKey */
-    for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
-        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
-            aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
-
-    /*
-     * 4. Transfer the state block to plain block
-     */
-    for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
-        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
-            PlainBlock[RowIndex + 4*ColumnIndex] = aes_ctx.State[RowIndex][ColumnIndex];
-
-    *PlainBlockSize = ((UINT) AES_STATE_ROWS)*((UINT) AES_STATE_COLUMNS);
-} /* End of AES_Decrypt */
-
-
-/*
-========================================================================
-Routine Description:
-    AES-CBC encryption
-
-Arguments:
-    PlainText        Plain text
-    PlainTextLength  The length of plain text in bytes
-    Key              Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
-    KeyLength        The length of cipher key in bytes
-    IV               Initialization vector, it may be 16 bytes (128 bits)
-    IVLength         The length of initialization vector in bytes
-    CipherTextLength The length of allocated cipher text in bytes
-
-Return Value:
-    CipherText       Return cipher text
-    CipherTextLength Return the length of real used cipher text in bytes
-
-Note:
-    Reference to RFC 3602 and NIST 800-38A
-========================================================================
-*/
-VOID AES_CBC_Encrypt (
-    IN UINT8 PlainText[],
-    IN UINT PlainTextLength,
-    IN UINT8 Key[],
-    IN UINT KeyLength,
-    IN UINT8 IV[],
-    IN UINT IVLength,
-    OUT UINT8 CipherText[],
-    INOUT UINT *CipherTextLength)
-{
-    UINT PaddingSize, PlainBlockStart, CipherBlockStart, CipherBlockSize;
-    UINT Index;
-    UINT8 Block[AES_BLOCK_SIZES];
-
-    /*
-     * 1. Check the input parameters
-     *    - CipherTextLength > (PlainTextLength + Padding size), Padding size = block size - (PlainTextLength % block size)
-     *    - Key length must be 16, 24, or 32 bytes(128, 192, or 256 bits)
-     *    - IV length must be 16 bytes(128 bits)
-     */
-    PaddingSize = ((UINT) AES_BLOCK_SIZES) - (PlainTextLength % ((UINT)AES_BLOCK_SIZES));
-    if (*CipherTextLength < (PlainTextLength + PaddingSize)) {
-	DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Encrypt: cipher text length is %d bytes < (plain text length %d bytes + padding size %d bytes).\n",
-            *CipherTextLength, PlainTextLength, PaddingSize));
-        return;
-    } /* End of if */
-    if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) {
-	DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Encrypt: key length is %d bytes, it must be %d, %d, or %d bytes(128, 192, or 256 bits).\n",
-            KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH));
-        return;
-    } /* End of if */
-    if (IVLength != AES_CBC_IV_LENGTH) {
-	DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Encrypt: IV length is %d bytes, it must be %d bytes(128bits).\n",
-            IVLength, AES_CBC_IV_LENGTH));
-        return;
-    } /* End of if */
-
-
-    /*
-     * 2. Main algorithm
-     *    - Plain text divide into serveral blocks (16 bytes/block)
-     *    - If plain text is divided with no remainder by block, add a new block and padding size = block(16 bytes)
-     *    - If plain text is not divided with no remainder by block, padding size = (block - remainder plain text)
-     *    - Execute AES_Encrypt procedure.
-     *
-     *    - Padding method: The remainder bytes will be filled with padding size (1 byte)
-     */
-    PlainBlockStart = 0;
-    CipherBlockStart = 0;
-    while ((PlainTextLength - PlainBlockStart) >= AES_BLOCK_SIZES)
-    {
-        if (CipherBlockStart == 0) {
-            for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
-                Block[Index] = PlainText[PlainBlockStart + Index]^IV[Index];
-        } else {
-            for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
-                Block[Index] = PlainText[PlainBlockStart + Index]^CipherText[CipherBlockStart - ((UINT) AES_BLOCK_SIZES) + Index];
-        } /* End of if */
-
-        CipherBlockSize = *CipherTextLength - CipherBlockStart;
-        AES_Encrypt(Block, AES_BLOCK_SIZES , Key, KeyLength, CipherText + CipherBlockStart, &CipherBlockSize);
-
-        PlainBlockStart += ((UINT) AES_BLOCK_SIZES);
-        CipherBlockStart += CipherBlockSize;
-    } /* End of while */
-
-    NdisMoveMemory(Block, (&PlainText[0] + PlainBlockStart), (PlainTextLength - PlainBlockStart));
-    NdisFillMemory((Block + (((UINT) AES_BLOCK_SIZES) -PaddingSize)), PaddingSize, (UINT8) PaddingSize);
-    if (CipherBlockStart == 0) {
-       for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
-           Block[Index] ^= IV[Index];
-    } else {
-       for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
-           Block[Index] ^= CipherText[CipherBlockStart - ((UINT) AES_BLOCK_SIZES) + Index];
-    } /* End of if */
-    CipherBlockSize = *CipherTextLength - CipherBlockStart;
-    AES_Encrypt(Block, AES_BLOCK_SIZES , Key, KeyLength, CipherText + CipherBlockStart, &CipherBlockSize);
-    CipherBlockStart += CipherBlockSize;
-    *CipherTextLength = CipherBlockStart;
-} /* End of AES_CBC_Encrypt */
-
-
-/*
-========================================================================
-Routine Description:
-    AES-CBC decryption
-
-Arguments:
-    CipherText       Cipher text
-    CipherTextLength The length of cipher text in bytes
-    Key              Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
-    KeyLength        The length of cipher key in bytes
-    IV               Initialization vector, it may be 16 bytes (128 bits)
-    IVLength         The length of initialization vector in bytes
-    PlainTextLength  The length of allocated plain text in bytes
-
-Return Value:
-    PlainText        Return plain text
-    PlainTextLength  Return the length of real used plain text in bytes
-
-Note:
-    Reference to RFC 3602 and NIST 800-38A
-========================================================================
-*/
-VOID AES_CBC_Decrypt (
-    IN UINT8 CipherText[],
-    IN UINT CipherTextLength,
-    IN UINT8 Key[],
-    IN UINT KeyLength,
-    IN UINT8 IV[],
-    IN UINT IVLength,
-    OUT UINT8 PlainText[],
-    INOUT UINT *PlainTextLength)
-{
-    UINT PaddingSize, PlainBlockStart, CipherBlockStart, PlainBlockSize;
-    UINT Index;
-
-    /*
-     * 1. Check the input parameters
-     *    - CipherTextLength must be divided with no remainder by block
-     *    - Key length must be 16, 24, or 32 bytes(128, 192, or 256 bits)
-     *    - IV length must be 16 bytes(128 bits)
-     */
-    if ((CipherTextLength % AES_BLOCK_SIZES) != 0) {
-	DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Decrypt: cipher text length is %d bytes, it can't be divided with no remainder by block size(%d).\n",
-            CipherTextLength, AES_BLOCK_SIZES));
-        return;
-    } /* End of if */
-    if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) {
-	DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Decrypt: key length is %d bytes, it must be %d, %d, or %d bytes(128, 192, or 256 bits).\n",
-            KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH));
-        return;
-    } /* End of if */
-    if (IVLength != AES_CBC_IV_LENGTH) {
-	DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Decrypt: IV length is %d bytes, it must be %d bytes(128bits).\n",
-            IVLength, AES_CBC_IV_LENGTH));
-        return;
-    } /* End of if */
-
-
-    /*
-     * 2. Main algorithm
-     *    - Cypher text divide into serveral blocks (16 bytes/block)
-     *    - Execute AES_Decrypt procedure.
-     *    - Remove padding bytes, padding size is the last byte of plain text
-     */
-    CipherBlockStart = 0;
-    PlainBlockStart = 0;
-    while ((CipherTextLength - CipherBlockStart) >= AES_BLOCK_SIZES)
-    {
-        PlainBlockSize = *PlainTextLength - PlainBlockStart;
-        AES_Decrypt(CipherText + CipherBlockStart, AES_BLOCK_SIZES , Key, KeyLength, PlainText + PlainBlockStart, &PlainBlockSize);
-
-        if (PlainBlockStart == 0) {
-            for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
-                PlainText[PlainBlockStart + Index] ^= IV[Index];
-        } else {
-            for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
-                PlainText[PlainBlockStart + Index] ^= CipherText[CipherBlockStart + Index - ((UINT) AES_BLOCK_SIZES)];
-        } /* End of if */
-
-        CipherBlockStart += AES_BLOCK_SIZES;
-        PlainBlockStart += PlainBlockSize;
-    } /* End of while */
-
-    PaddingSize = (UINT8) PlainText[PlainBlockStart -1];
-    *PlainTextLength = PlainBlockStart - PaddingSize;
-
-} /* End of AES_CBC_Encrypt */
-
-
-
-/*
-========================================================================
-Routine Description:
-    AES-CMAC generate subkey
-
-Arguments:
-    Key        Cipher key 128 bits
-    KeyLength  The length of Cipher key in bytes
-
-Return Value:
-    SubKey1    SubKey 1 128 bits
-    SubKey2    SubKey 2 128 bits
-
-Note:
-    Reference to RFC 4493
-
-    Step 1.  L := AES-128(K, const_Zero);
-    Step 2.  if MSB(L) is equal to 0
-                then    K1 := L << 1;
-                else    K1 := (L << 1) XOR const_Rb;
-    Step 3.  if MSB(K1) is equal to 0
-                then    K2 := K1 << 1;
-                else    K2 := (K1 << 1) XOR const_Rb;
-    Step 4.  return K1, K2;
-========================================================================
-*/
-VOID AES_CMAC_GenerateSubKey (
-    IN UINT8 Key[],
-    IN UINT KeyLength,
-    OUT UINT8 SubKey1[],
-    OUT UINT8 SubKey2[])
-{
-    UINT8 MSB_L = 0, MSB_K1 = 0, Top_Bit = 0;
-    UINT  SubKey1_Length = 0;
-    INT   Index = 0;
-
-    if (KeyLength != AES_KEY128_LENGTH) {
-	DBGPRINT(RT_DEBUG_ERROR, ("AES_CMAC_GenerateSubKey: key length is %d bytes, it must be %d bytes(128 bits).\n",
-            KeyLength, AES_KEY128_LENGTH));
-        return;
-    } /* End of if */
-
-    /* Step 1: L := AES-128(K, const_Zero); */
-    SubKey1_Length = 16;
-    AES_Encrypt(Const_Zero, sizeof(Const_Zero), Key, KeyLength, SubKey1, &SubKey1_Length);
-
-    /*
-     * Step 2.  if MSB(L) is equal to 0
-     *           then    K1 := L << 1;
-     *           else    K1 := (L << 1) XOR const_Rb;
-     */
-    MSB_L = SubKey1[0] & 0x80;
-    for(Index = 0; Index < 15; Index++) {
-        Top_Bit = (SubKey1[Index + 1] & 0x80)?1:0;
-        SubKey1[Index] <<= 1;
-        SubKey1[Index] |= Top_Bit;
-    }
-    SubKey1[15] <<= 1;
-    if (MSB_L > 0) {
-        for(Index = 0; Index < 16; Index++)
-            SubKey1[Index] ^= Const_Rb[Index];
-    } /* End of if */
-
-    /*
-     * Step 3.  if MSB(K1) is equal to 0
-     *           then    K2 := K1 << 1;
-     *           else    K2 := (K1 << 1) XOR const_Rb;
-     */
-    MSB_K1 = SubKey1[0] & 0x80;
-    for(Index = 0; Index < 15; Index++) {
-        Top_Bit = (SubKey1[Index + 1] & 0x80)?1:0;
-        SubKey2[Index] = SubKey1[Index] << 1;
-        SubKey2[Index] |= Top_Bit;
-    }
-    SubKey2[15] = SubKey1[15] << 1;
-    if (MSB_K1 > 0) {
-        for(Index = 0; Index < 16; Index++)
-            SubKey2[Index] ^= Const_Rb[Index];
-    } /* End of if */
-} /* End of AES_CMAC_GenerateSubKey */
-
-
-/*
-========================================================================
-Routine Description:
-    AES-CMAC
-
-Arguments:
-    PlainText        Plain text
-    PlainTextLength  The length of plain text in bytes
-    Key              Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
-    KeyLength        The length of cipher key in bytes
-    MACTextLength    The length of allocated memory spaces in bytes
-
-Return Value:
-    MACText       Message authentication code (128-bit string)
-    MACTextLength Return the length of Message authentication code in bytes
-
-Note:
-    Reference to RFC 4493
-========================================================================
-*/
-VOID AES_CMAC (
-    IN UINT8 PlainText[],
-    IN UINT PlainTextLength,
-    IN UINT8 Key[],
-    IN UINT KeyLength,
-    OUT UINT8 MACText[],
-    INOUT UINT *MACTextLength)
-{
-    UINT  PlainBlockStart;
-    UINT8 X[AES_BLOCK_SIZES], Y[AES_BLOCK_SIZES];
-    UINT8 SubKey1[16];
-    UINT8 SubKey2[16];
-    INT X_Length, Index;
-
-    if (*MACTextLength < AES_MAC_LENGTH) {
-	DBGPRINT(RT_DEBUG_ERROR, ("AES_CMAC: MAC text length is less than %d bytes).\n",
-            AES_MAC_LENGTH));
-        return;
-    } /* End of if */
-    if (KeyLength != AES_KEY128_LENGTH) {
-	DBGPRINT(RT_DEBUG_ERROR, ("AES_CMAC: key length is %d bytes, it must be %d bytes(128 bits).\n",
-            KeyLength, AES_KEY128_LENGTH));
-        return;
-    } /* End of if */
-
-    /* Step 1.  (K1,K2) := Generate_Subkey(K); */
-    NdisZeroMemory(SubKey1, 16);
-    NdisZeroMemory(SubKey2, 16);
-    AES_CMAC_GenerateSubKey(Key, KeyLength, SubKey1, SubKey2);
-
-    /*
-     * 2. Main algorithm
-     *    - Plain text divide into serveral blocks (16 bytes/block)
-     *    - If plain text is not divided with no remainder by block, padding size = (block - remainder plain text)
-     *    - Execute AES_Encrypt procedure.
-     */
-    PlainBlockStart = 0;
-    NdisMoveMemory(X, Const_Zero, AES_BLOCK_SIZES);
-    while ((PlainTextLength - PlainBlockStart) > AES_BLOCK_SIZES)
-    {
-        for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
-                Y[Index] = PlainText[PlainBlockStart + Index]^X[Index];
-
-        X_Length = sizeof(X);
-        AES_Encrypt(Y, sizeof(Y) , Key, KeyLength, X, &X_Length);
-        PlainBlockStart += ((UINT) AES_BLOCK_SIZES);
-    } /* End of while */
-    if ((PlainTextLength - PlainBlockStart) == AES_BLOCK_SIZES) {
-        for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
-                Y[Index] = PlainText[PlainBlockStart + Index]^X[Index]^SubKey1[Index];
-    } else {
-        NdisZeroMemory(Y, AES_BLOCK_SIZES);
-        NdisMoveMemory(Y, &PlainText[PlainBlockStart], (PlainTextLength - PlainBlockStart));
-        Y[(PlainTextLength - PlainBlockStart)] = 0x80;
-        for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
-                Y[Index] = Y[Index]^X[Index]^SubKey2[Index];
-    } /* End of if */
-    AES_Encrypt(Y, sizeof(Y) , Key, KeyLength, MACText, MACTextLength);
-} /* End of AES_CMAC */
diff --git a/drivers/staging/rt3090/common/crypt_biginteger.c b/drivers/staging/rt3090/common/crypt_biginteger.c
deleted file mode 100644
index b346c5f..0000000
--- a/drivers/staging/rt3090/common/crypt_biginteger.c
+++ /dev/null
@@ -1,1119 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	cmm_profile.c
-
-    Abstract:
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
- */
-
-#include "crypt_biginteger.h"
-
-#ifdef __KERNEL__
-#define DEBUGPRINT(fmt, args...) printk(KERN_ERR fmt, ## args)
-#else
-#define DEBUGPRINT(fmt, args...) printf(fmt, ## args)
-#endif /* __KERNEL__ */
-
-#define UINT32_HBITS(value)	(((value) >> 0x10) & 0xffff)
-#define UINT32_LBITS(value)	((value) & 0xffff)
-#define UINT32_GETBYTE(value, index)	(((value) >> ((index)*8)) & 0xff)
-#define UINT64_HBITS(value)	(((value) >> 0x20) & 0xffffffff)
-#define UINT64_LBITS(value)	((value) & 0xffffffff)
-
-static UINT8 WPS_DH_P_VALUE[192] =
-{
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-    0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
-    0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
-    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
-    0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
-    0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
-    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
-    0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
-    0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
-    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
-    0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
-    0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
-    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
-    0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
-    0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
-    0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
-    0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
-    0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
-    0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
-    0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
-    0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
-    0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
-    0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x23, 0x73, 0x27,
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-};
-
-static UINT8 WPS_DH_R_VALUE[193] =
-{
-    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00,
-};
-
-static UINT8 WPS_DH_X_VALUE[184] =
-{
-    0x36, 0xf0, 0x25, 0x5d, 0xde, 0x97, 0x3d, 0xcb,
-    0x3b, 0x39, 0x9d, 0x74, 0x7f, 0x23, 0xe3, 0x2e,
-    0xd6, 0xfd, 0xb1, 0xf7, 0x75, 0x98, 0x33, 0x8b,
-    0xfd, 0xf4, 0x41, 0x59, 0xc4, 0xec, 0x64, 0xdd,
-    0xae, 0xb5, 0xf7, 0x86, 0x71, 0xcb, 0xfb, 0x22,
-    0x10, 0x6a, 0xe6, 0x4c, 0x32, 0xc5, 0xbc, 0xe4,
-    0xcf, 0xd4, 0xf5, 0x92, 0x0d, 0xa0, 0xeb, 0xc8,
-    0xb0, 0x1e, 0xca, 0x92, 0x92, 0xae, 0x3d, 0xba,
-    0x1b, 0x7a, 0x4a, 0x89, 0x9d, 0xa1, 0x81, 0x39,
-    0x0b, 0xb3, 0xbd, 0x16, 0x59, 0xc8, 0x12, 0x94,
-    0xf4, 0x00, 0xa3, 0x49, 0x0b, 0xf9, 0x48, 0x12,
-    0x11, 0xc7, 0x94, 0x04, 0xa5, 0x76, 0x60, 0x5a,
-    0x51, 0x60, 0xdb, 0xee, 0x83, 0xb4, 0xe0, 0x19,
-    0xb6, 0xd7, 0x99, 0xae, 0x13, 0x1b, 0xa4, 0xc2,
-    0x3d, 0xff, 0x83, 0x47, 0x5e, 0x9c, 0x40, 0xfa,
-    0x67, 0x25, 0xb7, 0xc9, 0xe3, 0xaa, 0x2c, 0x65,
-    0x96, 0xe9, 0xc0, 0x57, 0x02, 0xdb, 0x30, 0xa0,
-    0x7c, 0x9a, 0xa2, 0xdc, 0x23, 0x5c, 0x52, 0x69,
-    0xe3, 0x9d, 0x0c, 0xa9, 0xdf, 0x7a, 0xad, 0x44,
-    0x61, 0x2a, 0xd6, 0xf8, 0x8f, 0x69, 0x69, 0x92,
-    0x98, 0xf3, 0xca, 0xb1, 0xb5, 0x43, 0x67, 0xfb,
-    0x0e, 0x8b, 0x93, 0xf7, 0x35, 0xdc, 0x8c, 0xd8,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-};
-
-static UINT8 WPS_DH_RRModP_VALUE[192] =
-{
-	0xe3, 0xb3, 0x3c, 0x72, 0x59, 0x54, 0x1c, 0x01,
-	0xee, 0x9c, 0x9a, 0x21, 0x6c, 0xc1, 0xeb, 0xd2,
-	0xae, 0x59, 0x41, 0x04, 0x79, 0x29, 0xa1, 0xc7,
-	0xe9, 0xc3, 0xfa, 0x02, 0xcc, 0x24, 0x56, 0xef,
-	0x10, 0x26, 0x30, 0xfa, 0x9a, 0x36, 0xa5, 0x1f,
-	0x57, 0xb5, 0x93, 0x48, 0x67, 0x98, 0x44, 0x60,
-	0x0b, 0xe4, 0x96, 0x47, 0xa8, 0x7c, 0x7b, 0x37,
-	0xf8, 0x05, 0x65, 0x64, 0x96, 0x9b, 0x7f, 0x02,
-	0xdc, 0x54, 0x1a, 0x4e, 0xd4, 0x05, 0x3f, 0x54,
-	0xd6, 0x2a, 0x0e, 0xea, 0xb2, 0x70, 0x52, 0x1b,
-	0x22, 0xc2, 0x96, 0xe9, 0xd4, 0x6f, 0xec, 0x23,
-	0x8e, 0x1a, 0xbd, 0x78, 0x02, 0x23, 0xb7, 0x6b,
-	0xb8, 0xfe, 0x61, 0x21, 0x19, 0x6b, 0x7e, 0x88,
-	0x1c, 0x72, 0x9c, 0x7e, 0x04, 0xb9, 0xf7, 0x96,
-	0x07, 0xcd, 0x0a, 0x62, 0x8e, 0x43, 0x41, 0x30,
-	0x04, 0xa5, 0x41, 0xff, 0x93, 0xae, 0x1c, 0xeb,
-	0xb0, 0x04, 0xa7, 0x50, 0xdb, 0x10, 0x2d, 0x39,
-	0xb9, 0x05, 0x2b, 0xb4, 0x7a, 0x58, 0xf1, 0x70,
-	0x7e, 0x8c, 0xd2, 0xac, 0x98, 0xb5, 0xfb, 0x62,
-	0x8f, 0x23, 0x31, 0xb1, 0x3b, 0x01, 0xe0, 0x18,
-	0xf4, 0x66, 0xee, 0x5f, 0xbc, 0xd4, 0x9d, 0x68,
-	0xd0, 0xab, 0x92, 0xe1, 0x83, 0x97, 0xf2, 0x45,
-	0x8e, 0x0e, 0x3e, 0x21, 0x67, 0x47, 0x8c, 0x73,
-	0xf1, 0x15, 0xd2, 0x7d, 0x32, 0xc6, 0x95, 0xe0,
-};
-
-static UINT8 Value_0[1] = {0x00};
-static UINT8 Value_1[1] = {0x01};
-static PBIG_INTEGER pBI_U = NULL, pBI_S = NULL, pBI_O = NULL;
-static UINT Bits_Of_R = 0;
-
-
-VOID BigInteger_Print (
-    IN PBIG_INTEGER pBI)
-{
-    int i = 0, j = 0;
-
-    if ((pBI == NULL) || (pBI->pIntegerArray == NULL))
-        return;
-
-    if (strlen(pBI->Name) != 0)
-        DEBUGPRINT("Name=%s\n", pBI->Name);
-    DEBUGPRINT("AllocSize=%d, ArrayLength=%d, IntegerLength=%d, Signed=%d\n", pBI->AllocSize, pBI->ArrayLength, pBI->IntegerLength, pBI->Signed);
-    for (i = (pBI->ArrayLength - 1), j = 0;i >=0;i--,j++) {
-        DEBUGPRINT("%08x, ", pBI->pIntegerArray[i]);
-        if ((j%8) == 7)
-            DEBUGPRINT("\n");
-    } /* End od for */
-    DEBUGPRINT("\n\n");
-} /* End of BigInteger_Print */
-
-
-VOID BigInteger_Init (
-    INOUT PBIG_INTEGER *pBI)
-{
-    if (*pBI != NULL)
-        BigInteger_Free(pBI);
-
-    if ((*pBI = (PBIG_INTEGER) kmalloc(sizeof(BIG_INTEGER), GFP_ATOMIC)) == NULL) {
-        DEBUGPRINT("BigInteger_Init: allocate %d bytes memory failure.\n", (sizeof(BIG_INTEGER)));
-        return;
-    } /* End of if */
-
-    NdisZeroMemory(*pBI, sizeof(BIG_INTEGER));
-    (*pBI)->pIntegerArray = NULL;
-    (*pBI)->Signed = 1;
-} /* End of BigInteger_Init */
-
-
-VOID BigInteger_Free_AllocSize (
-    IN PBIG_INTEGER *pBI)
-{
-    if ((*pBI != NULL) && ((*pBI)->pIntegerArray != NULL)) {
-        kfree((*pBI)->pIntegerArray);
-        NdisZeroMemory(*pBI, sizeof(BIG_INTEGER));
-        (*pBI)->pIntegerArray = NULL;
-        (*pBI)->Signed = 1;
-    } /* End of if */
-} /* End of BigInteger_Free_AllocSize */
-
-
-VOID BigInteger_Free (
-    IN PBIG_INTEGER *pBI)
-{
-    if (*pBI != NULL) {
-        BigInteger_Free_AllocSize(pBI);
-        kfree(*pBI);
-    } /* End of if */
-
-    *pBI = NULL;
-} /* End of BigInteger_Free */
-
-
-VOID BigInteger_AllocSize (
-    IN PBIG_INTEGER *pBI,
-    IN UINT Length)
-{
-    UINT ArrayLength = 0;
-
-    if (Length == 0)
-        return;
-
-    if (*pBI == NULL)
-        BigInteger_Init(pBI);
-
-    /* Caculate array size */
-    ArrayLength = Length >> 0x2;
-    if ((Length & 0x3) != 0)
-        ArrayLength++;
-
-    if (((*pBI)->pIntegerArray != NULL) && ((*pBI)->AllocSize < (sizeof(UINT32)*ArrayLength)))
-        BigInteger_Free_AllocSize(pBI);
-
-    if ((*pBI)->pIntegerArray == NULL) {
-        if (((*pBI)->pIntegerArray = (UINT32 *) kmalloc(sizeof(UINT32)*ArrayLength, GFP_ATOMIC)) == NULL) {
-            DEBUGPRINT("BigInteger_AllocSize: allocate %d bytes memory failure.\n", (sizeof(UINT32)*ArrayLength));
-            return;
-        } /* End of if */
-        (*pBI)->AllocSize = sizeof(UINT32)*ArrayLength;
-    } /* End of if */
-
-    NdisZeroMemory((*pBI)->pIntegerArray, (*pBI)->AllocSize);
-    (*pBI)->ArrayLength = ArrayLength;
-    (*pBI)->IntegerLength = Length;
-} /* End of BigInteger_AllocSize */
-
-
-VOID BigInteger_ClearHighBits (
-    IN PBIG_INTEGER pBI)
-{
-    INT BIArrayIndex, ShiftIndex = 0;
-    UINT8 value;
-
-    if ((pBI == NULL) || (pBI->pIntegerArray == NULL))
-        return;
-
-    BIArrayIndex = pBI->ArrayLength - 1;
-    while ((BIArrayIndex >= 0) && (pBI->pIntegerArray[BIArrayIndex] == 0))
-	BIArrayIndex--;
-
-    if (BIArrayIndex >= 0) {
-        value = 0;
-        ShiftIndex = 4;
-        while (value == 0) {
-            ShiftIndex--;
-            value = UINT32_GETBYTE(pBI->pIntegerArray[BIArrayIndex], ShiftIndex);
-	} /* End of while */
-    } /* End of if */
-
-    if ((BIArrayIndex == -1) && (ShiftIndex == -1)) {
-        pBI->IntegerLength = 1;
-        pBI->ArrayLength = 1;
-        pBI->Signed = 1;
-    } else {
-        pBI->IntegerLength = (BIArrayIndex*4) + ShiftIndex + 1;
-        pBI->ArrayLength = BIArrayIndex + 1;
-    } /* End of if */
-} /* End of BigInteger_ClearHighBits */
-
-
-VOID BigInteger_BI2Bin (
-    IN PBIG_INTEGER pBI,
-    OUT UINT8 *pValue,
-    OUT UINT *Length)
-{
-    INT  ValueIndex, BIArrayIndex, ShiftIndex;
-    UINT32  Number;
-
-    if (pBI == NULL) {
-        DEBUGPRINT("BigInteger_BI2Bin: pBI is NUll\n");
-        *Length = 0;
-        return;
-    } /* End of if */
-
-    if (*Length < (sizeof(UINT8) * pBI->IntegerLength)) {
-        DEBUGPRINT("BigInteger_BI2Bin: length(%d) is not enough.\n", *Length);
-        *Length = 0;
-        return;
-    } /* End of if */
-
-    if (pBI->pIntegerArray == NULL) {
-        *Length = 0;
-        return;
-    } /* End of if */
-
-    BigInteger_ClearHighBits(pBI);
-    if ((ShiftIndex = pBI->IntegerLength & 0x3) == 0)
-       ShiftIndex = 4;
-    BIArrayIndex = pBI->ArrayLength - 1;
-    ValueIndex = 0;
-
-    Number = pBI->pIntegerArray[BIArrayIndex];
-    while (ValueIndex < pBI->IntegerLength)
-    {
-        pValue[ValueIndex++] = (UINT8) UINT32_GETBYTE(Number, ShiftIndex - 1);
-        if ((--ShiftIndex) == 0) {
-            ShiftIndex = 4;
-            BIArrayIndex--;
-            Number = pBI->pIntegerArray[BIArrayIndex];
-        } /* End of if */
-    } /* End of while */
-    *Length = pBI->IntegerLength;
-} /* End of BigInteger_BI2Bin */
-
-
-VOID BigInteger_Bin2BI (
-    IN UINT8 *pValue,
-    IN UINT Length,
-    OUT PBIG_INTEGER *pBI)
-{
-    INT  ValueIndex, BIArrayIndex, ShiftIndex;
-    UINT32  Number;
-
-    BigInteger_AllocSize(pBI, Length);
-
-    if ((*pBI)->pIntegerArray != NULL) {
-        Number = 0;
-        if ((ShiftIndex = Length & 0x3) == 0)
-            ShiftIndex = 4;
-        BIArrayIndex = (*pBI)->ArrayLength - 1;
-        ValueIndex = 0;
-        while (ValueIndex < Length)
-        {
-            Number = (Number << 8) | (UINT8) pValue[ValueIndex++];
-            if ((--ShiftIndex) == 0) {
-                (*pBI)->pIntegerArray[BIArrayIndex] = Number;
-                ShiftIndex = 4;
-                BIArrayIndex--;
-                Number = 0;
-            } /* End of if */
-        } /* End of while */
-    } /* End of if */
-} /* End of BigInteger_Bin2BI */
-
-
-/* Calculate the bits of BigInteger, the highest bit is 1 */
-VOID BigInteger_BitsOfBI (
-    IN PBIG_INTEGER pBI,
-    OUT UINT *Bits_Of_P)
-{
-    UINT32 Number, Index;
-
-    Number = pBI->pIntegerArray[pBI->ArrayLength - 1];
-    Index = 0;
-    while ((!(Number & 0x80000000)) && (Index < 32)) {
-        Number <<= 1;
-        Index++;
-    } /* End of while */
-    *Bits_Of_P = (pBI->ArrayLength*sizeof(UINT32)) - Index;
-} /* End of BigInteger_BitsOfBN */
-
-
-INT BigInteger_GetBitValue (
-    IN PBIG_INTEGER pBI,
-    IN UINT Index)
-{
-    UINT Array = 0;
-    UINT Shift = 0;
-
-    if (Index > 0) {
-        Array = (Index - 1) >> 0x5;
-        Shift = (Index - 1) & 0x1F;
-    }
-    if (Array > pBI->ArrayLength)
-        return 0;
-
-    return ((pBI->pIntegerArray[Array] >> Shift) & 0x1);
-} /* End of BigInteger_GetBitValue */
-
-
-UINT8 BigInteger_GetByteValue (
-    IN PBIG_INTEGER pBI,
-    IN UINT Index)
-{
-    UINT Array = 0;
-    UINT Shift = 0;
-
-    if (Index > 0) {
-        Array = (Index - 1) >> 0x2;
-        Shift = (Index - 1) & 0x3;
-    }
-    if ((Array > pBI->ArrayLength) || (Index > pBI->IntegerLength))
-        return 0;
-
-
-    return (UINT8) UINT32_GETBYTE(pBI->pIntegerArray[Array], Shift - 1);
-} /* End of BigInteger_GetByteValue */
-
-
-VOID BigInteger_Copy (
-    IN PBIG_INTEGER pBI_Copied,
-    OUT PBIG_INTEGER *pBI_Result)
-{
-    BigInteger_AllocSize(pBI_Result, pBI_Copied->IntegerLength);
-    NdisCopyMemory((*pBI_Result)->pIntegerArray, pBI_Copied->pIntegerArray, (sizeof(UINT32)*(*pBI_Result)->ArrayLength));
-    (*pBI_Result)->ArrayLength = pBI_Copied->ArrayLength;
-    (*pBI_Result)->IntegerLength = pBI_Copied->IntegerLength;
-    (*pBI_Result)->Signed = pBI_Copied->Signed;
-} /* End of BigInteger_Copy */
-
-
-INT BigInteger_UnsignedCompare (
-    IN PBIG_INTEGER pFirstOperand,
-    IN PBIG_INTEGER pSecondOperand)
-{
-    INT BIArrayIndex;
-
-    if (pFirstOperand->IntegerLength > pSecondOperand->IntegerLength)
-        return 1;
-
-    if (pFirstOperand->IntegerLength < pSecondOperand->IntegerLength)
-        return -1;
-
-    if (pFirstOperand->IntegerLength == pSecondOperand->IntegerLength) {
-        for(BIArrayIndex = (pFirstOperand->ArrayLength - 1);BIArrayIndex >= 0 ; BIArrayIndex--)
-        {
-            if (pFirstOperand->pIntegerArray[BIArrayIndex] > pSecondOperand->pIntegerArray[BIArrayIndex])
-                return 1;
-            else if (pFirstOperand->pIntegerArray[BIArrayIndex] < pSecondOperand->pIntegerArray[BIArrayIndex])
-                return -1;
-        } /* End of for */
-    } /* End of if */
-
-    return 0;
-} /* End of BigInteger_Compare */
-
-
-VOID BigInteger_Add (
-    IN PBIG_INTEGER pFirstOperand,
-    IN PBIG_INTEGER pSecondOperand,
-    OUT PBIG_INTEGER *pBI_Result)
-{
-    INT CompareResult;
-    UINT32 BIArrayIndex;
-    UINT64 Sum, Carry;
-    PBIG_INTEGER pTempBI = NULL;
-
-    if  ((pFirstOperand == NULL) || (pFirstOperand->pIntegerArray == NULL)
-      || (pSecondOperand == NULL) || (pSecondOperand->pIntegerArray == NULL)) {
-        DEBUGPRINT("BigInteger_Add: first or second operand is NULL.\n");
-        return;
-    } /* End of if */
-
-    if (*pBI_Result == NULL)
-        BigInteger_Init(pBI_Result);
-
-    CompareResult = BigInteger_UnsignedCompare(pFirstOperand, pSecondOperand);
-    if ((CompareResult == 0) & ((pFirstOperand->Signed * pSecondOperand->Signed) < 0)) {
-        BigInteger_AllocSize(pBI_Result, 1);
-        return ;
-    } /* End of if */
-
-    /*
-     *  Singed table
-     *  A + B || A > B || A < B
-     *  ------------------------
-     *  +   + ||   +   ||   +
-     *  +   - ||   +   ||   -
-     *  -   + ||   -   ||   +
-     *  -   - ||   -   ||   -
-     */
-    if ((pFirstOperand->Signed * pSecondOperand->Signed) > 0) {
-        if (pFirstOperand->IntegerLength > pSecondOperand->IntegerLength) {
-                BigInteger_AllocSize(pBI_Result, pFirstOperand->IntegerLength + 1);
-        } else {
-                BigInteger_AllocSize(pBI_Result, pSecondOperand->IntegerLength + 1);
-        } /* End of if */
-
-        Carry = 0;
-        for (BIArrayIndex=0; BIArrayIndex < (*pBI_Result)->ArrayLength; BIArrayIndex++)
-        {
-
-            Sum = 0;
-            if (BIArrayIndex < pFirstOperand->ArrayLength)
-                Sum += (UINT64) pFirstOperand->pIntegerArray[BIArrayIndex];
-
-            if (BIArrayIndex < pSecondOperand->ArrayLength)
-                Sum += (UINT64) pSecondOperand->pIntegerArray[BIArrayIndex];
-
-            Sum += Carry;
-            Carry = Sum  >> 32;
-            (*pBI_Result)->pIntegerArray[BIArrayIndex] = (UINT32) (Sum & 0xffffffffUL);
-        } /* End of for */
-        (*pBI_Result)->Signed = pFirstOperand->Signed;
-        BigInteger_ClearHighBits(*pBI_Result);
-    } else {
-        if  ((pFirstOperand->Signed == 1) & (pSecondOperand->Signed == -1)) {
-            BigInteger_Copy(pSecondOperand, &pTempBI);
-            pTempBI->Signed = 1;
-            BigInteger_Sub(pFirstOperand, pTempBI, pBI_Result);
-        } else if ((pFirstOperand->Signed == -1) & (pSecondOperand->Signed == 1)) {
-            BigInteger_Copy(pFirstOperand, &pTempBI);
-            pTempBI->Signed = 1;
-            BigInteger_Sub(pSecondOperand, pTempBI, pBI_Result);
-        } /* End of if */
-    } /* End of if */
-
-    BigInteger_Free(&pTempBI);
-} /* End of BigInteger_Add */
-
-
-VOID BigInteger_Sub (
-    IN PBIG_INTEGER pFirstOperand,
-    IN PBIG_INTEGER pSecondOperand,
-    OUT PBIG_INTEGER *pBI_Result)
-{
-    INT CompareResult;
-    UINT32 BIArrayIndex, Carry;
-    PBIG_INTEGER pTempBI = NULL, pTempBI2 = NULL;
-
-    if  ((pFirstOperand == NULL) || (pFirstOperand->pIntegerArray == NULL)
-      || (pSecondOperand == NULL) || (pSecondOperand->pIntegerArray == NULL)) {
-        DEBUGPRINT("BigInteger_Sub: first or second operand is NULL.\n");
-        return;
-    } /* End of if */
-
-    if (*pBI_Result == NULL)
-        BigInteger_Init(pBI_Result);
-
-    CompareResult = BigInteger_UnsignedCompare(pFirstOperand, pSecondOperand);
-    if ((CompareResult == 0) & ((pFirstOperand->Signed * pSecondOperand->Signed) > 0)) {
-        BigInteger_AllocSize(pBI_Result, 1);
-        return ;
-    } /* End of if */
-
-    BigInteger_Init(&pTempBI);
-    BigInteger_Init(&pTempBI2);
-
-    /*
-     *  Singed table
-     *  A - B || A > B || A < B
-     *  ------------------------
-     *  +   + ||   +   ||   -
-     *  +   - ||   +   ||   +
-     *  -   + ||   -   ||   -
-     *  -   - ||   -   ||   +
-     */
-    if ((pFirstOperand->Signed * pSecondOperand->Signed) > 0) {
-        if (CompareResult == 1) {
-            BigInteger_Copy(pFirstOperand, &pTempBI);
-            BigInteger_Copy(pSecondOperand, &pTempBI2);
-        } else if (CompareResult == -1) {
-            BigInteger_Copy(pSecondOperand, &pTempBI);
-            BigInteger_Copy(pFirstOperand, &pTempBI2);
-        } /* End of if */
-
-        BigInteger_Copy(pTempBI, pBI_Result);
-        Carry = 0;
-        for (BIArrayIndex=0; BIArrayIndex < (*pBI_Result)->ArrayLength; BIArrayIndex++)
-        {
-            if (BIArrayIndex < pTempBI2->ArrayLength) {
-                if ((*pBI_Result)->pIntegerArray[BIArrayIndex] >= (pTempBI2->pIntegerArray[BIArrayIndex] - Carry)) {
-                    (*pBI_Result)->pIntegerArray[BIArrayIndex] = (*pBI_Result)->pIntegerArray[BIArrayIndex] - pTempBI2->pIntegerArray[BIArrayIndex] - Carry;
-                    Carry = 0;
-                } else {
-                    (*pBI_Result)->pIntegerArray[BIArrayIndex] = 0xffffffffUL - pTempBI2->pIntegerArray[BIArrayIndex] - Carry + (*pBI_Result)->pIntegerArray[BIArrayIndex] + 1;
-                    Carry = 1;
-                } /* End of if */
-            } else {
-                if ((*pBI_Result)->pIntegerArray[BIArrayIndex] >= Carry) {
-                    (*pBI_Result)->pIntegerArray[BIArrayIndex] -= Carry;
-                    Carry = 0;
-                } else {
-                    (*pBI_Result)->pIntegerArray[BIArrayIndex] = 0xffffffffUL - Carry;
-                    Carry = 1;
-                } /* End of if */
-            } /* End of if */
-        } /* End of for */
-
-        if  (((pFirstOperand->Signed == 1) & (pSecondOperand->Signed == 1) & (CompareResult == -1))
-          || ((pFirstOperand->Signed == -1) & (pSecondOperand->Signed == -1) & (CompareResult == 1)))
-            (*pBI_Result)->Signed = -1;
-
-        BigInteger_ClearHighBits(*pBI_Result);
-    } else {
-        if  ((pFirstOperand->Signed == 1) & (pSecondOperand->Signed == -1)) {
-            BigInteger_Copy(pSecondOperand, &pTempBI);
-            pTempBI->Signed = 1;
-            BigInteger_Add(pFirstOperand, pTempBI, pBI_Result);
-        } else if ((pFirstOperand->Signed == -1) & (pSecondOperand->Signed == 1)) {
-            BigInteger_Copy(pFirstOperand, &pTempBI);
-            pTempBI->Signed = 1;
-            BigInteger_Add(pTempBI, pSecondOperand, pBI_Result);
-            (*pBI_Result)->Signed = -1;
-        } /* End of if */
-    } /* End of if */
-
-    BigInteger_Free(&pTempBI);
-    BigInteger_Free(&pTempBI2);
-} /* End of BigInteger_Sub */
-
-
-VOID BigInteger_Mul (
-    IN PBIG_INTEGER pFirstOperand,
-    IN PBIG_INTEGER pSecondOperand,
-    OUT PBIG_INTEGER *pBI_Result)
-{
-
-    UINT32 BIFirstIndex, BISecondIndex;
-    UINT64 FirstValue, SecondValue, Sum, Carry;
-
-    if  ((pFirstOperand == NULL) || (pFirstOperand->pIntegerArray == NULL)
-      || (pSecondOperand == NULL) || (pSecondOperand->pIntegerArray == NULL)) {
-        DEBUGPRINT("BigInteger_Mul: first or second operand is NULL.\n");
-        return;
-    } /* End of if */
-
-    /* The first or second operand is zero */
-    if  (((pFirstOperand->IntegerLength  == 1) && (pFirstOperand->pIntegerArray[0]  == 0))
-       ||((pSecondOperand->IntegerLength == 1) && (pSecondOperand->pIntegerArray[0] == 0))) {
-        BigInteger_AllocSize(pBI_Result, 1);
-        goto output;
-    } /* End of if */
-
-    /* The first or second operand is one */
-    if  ((pFirstOperand->IntegerLength  == 1) && (pFirstOperand->pIntegerArray[0]  == 1)) {
-        BigInteger_Copy(pSecondOperand, pBI_Result);
-        goto output;
-    } /* End of if */
-    if  ((pSecondOperand->IntegerLength  == 1) && (pSecondOperand->pIntegerArray[0]  == 1)) {
-        BigInteger_Copy(pFirstOperand, pBI_Result);
-        goto output;
-    } /* End of if */
-
-    BigInteger_AllocSize(pBI_Result, pFirstOperand->IntegerLength + pSecondOperand->IntegerLength);
-
-    for (BIFirstIndex=0; BIFirstIndex < pFirstOperand->ArrayLength; BIFirstIndex++)
-    {
-        Carry = 0;
-        FirstValue = (UINT64) pFirstOperand->pIntegerArray[BIFirstIndex];
-        if (FirstValue == 0) {
-            continue;
-        } else {
-            for (BISecondIndex=0; BISecondIndex < pSecondOperand->ArrayLength; BISecondIndex++)
-            {
-                SecondValue = ((UINT64) pSecondOperand->pIntegerArray[BISecondIndex])*FirstValue;
-                Sum = (UINT64) ((*pBI_Result)->pIntegerArray[BIFirstIndex + BISecondIndex] + SecondValue + Carry);
-                Carry = Sum >> 32;
-                (*pBI_Result)->pIntegerArray[BIFirstIndex + BISecondIndex] = (UINT32) (Sum & 0xffffffffUL);
-            } /* End of for */
-            while (Carry != 0) {
-                Sum = (UINT64) (*pBI_Result)->pIntegerArray[BIFirstIndex + BISecondIndex];
-                Sum += Carry;
-
-                Carry = Sum >> 32;
-                (*pBI_Result)->pIntegerArray[BIFirstIndex + BISecondIndex] = (UINT32) (Sum & 0xffffffffUL);
-                BISecondIndex++;
-            } /* End of while */
-        } /* End of if */
-    } /* End of for */
-
-output:
-    (*pBI_Result)->Signed = pFirstOperand->Signed * pSecondOperand->Signed;
-    BigInteger_ClearHighBits(*pBI_Result);
-} /* End of BigInteger_Mul */
-
-
-VOID BigInteger_Square (
-    IN PBIG_INTEGER pBI,
-    OUT PBIG_INTEGER *pBI_Result)
-{
-    INT BIFirstIndex, BISecondIndex;
-	UINT32 HBITS_Value, LBITS_Value, Temp1_Value, Temp2_Value, Carry32;
-	UINT32 *Point_Of_S, *Point_Of_Result, *Point_Of_BI;
-    UINT64 Result64_1, Result64_2, Carry64, TempValue64;
-
-    if ((pBI == NULL) || (pBI->pIntegerArray == NULL)) {
-        DEBUGPRINT("\tBigInteger_Square: the operand is NULL.\n");
-        return;
-    } /* End of if */
-
-    /* The operand is zero */
-    if  ((pBI->IntegerLength  == 1) && (pBI->pIntegerArray[0]  ==  0)) {
-        BigInteger_AllocSize(pBI_Result, 1);
-        goto output;
-    } /* End of if */
-
-    BigInteger_AllocSize(pBI_Result, (pBI->IntegerLength*2) + 20);
-    BigInteger_AllocSize(&pBI_S, (pBI->IntegerLength*2) + 20);
-    BigInteger_AllocSize(&pBI_O, (pBI->IntegerLength*2) + 20);
-
-    /*
-     * Input: pBI = {a_0, a_1, a_2, a_3, ..., a_n}
-     * Step1. calculate a_0^2, a_1^2, a_2^2, a_3^2 ... a_n^2
-     */
-	Point_Of_S = pBI_S->pIntegerArray;
-    for (BIFirstIndex=0; BIFirstIndex < pBI->ArrayLength; BIFirstIndex++)
-    {
-	HBITS_Value = UINT32_HBITS(pBI->pIntegerArray[BIFirstIndex]);
-		LBITS_Value = UINT32_LBITS(pBI->pIntegerArray[BIFirstIndex]);
-		Temp1_Value = HBITS_Value*LBITS_Value;
-		Temp2_Value = (Temp1_Value & 0x7fff) << 0x11;
-		Point_Of_S[0] = (LBITS_Value*LBITS_Value) + Temp2_Value;
-		Point_Of_S[1] = (HBITS_Value*HBITS_Value) + ((Temp1_Value >> 0xf) & 0x1ffff);
-		if (Point_Of_S[0] < Temp2_Value)
-			Point_Of_S[1] += 1;
-
-		Point_Of_S += 2;
-    } /* End of for */
-
-    /*
-     * Step2. calculate a_0*{a_1, a_2, a_3, a_4, ..., a_n}
-     */
-    Point_Of_BI = pBI->pIntegerArray;
-    Point_Of_Result = (*pBI_Result)->pIntegerArray;
-    Point_Of_Result[0] = 0;
-    TempValue64 = (UINT64) Point_Of_BI[0];
-    Point_Of_Result++;
-    Carry64 = 0;
-    for (BIFirstIndex=1; BIFirstIndex < pBI->ArrayLength; BIFirstIndex++)
-    {
-        Result64_1 =  (UINT64) Point_Of_BI[BIFirstIndex]*TempValue64;
-        Result64_1 += Carry64;
-        Carry64 = (Result64_1 >> 32);
-        Point_Of_Result[0] = (UINT32) (Result64_1 & 0xffffffffUL);
-        Point_Of_Result++;
-    } /* End of for */
-    if (Carry64 > 0)
-        Point_Of_Result[0] = (UINT32) (Carry64 & 0xffffffffUL);
-
-    /*
-     * Step3. calculate
-     *           a_1*{a_2, a_3, a_4, ..., a_n}
-     *           a_2*{a_3, a_4, a_5, ..., a_n}
-     *           a_3*{a_4, a_5, a_6, ..., a_n}
-     *           a_4*{a_5, a_6, a_7, ..., a_n}
-     *           ...
-     *           a_n-1*{a_n}
-     */
-    Point_Of_BI = pBI->pIntegerArray;
-    for (BIFirstIndex=1; BIFirstIndex < (pBI->ArrayLength - 1); BIFirstIndex++)
-    {
-        Point_Of_Result = (*pBI_Result)->pIntegerArray;
-        Point_Of_Result += (BIFirstIndex*2) + 1;
-        TempValue64 = (UINT64) Point_Of_BI[BIFirstIndex];
-        Carry64 = 0;
-        for (BISecondIndex=(BIFirstIndex + 1); BISecondIndex < pBI->ArrayLength; BISecondIndex++)
-        {
-            Result64_1 = ((UINT64) Point_Of_Result[0]) + Carry64;
-            Result64_2 = (UINT64) Point_Of_BI[BISecondIndex]*TempValue64;
-            Carry64 = (Result64_1 >> 32);
-            Result64_1 = (Result64_1 & 0xffffffffUL);
-            Result64_1 = Result64_1 + Result64_2;
-            Carry64 += (Result64_1 >> 32);
-            Point_Of_Result[0] = (UINT32) (Result64_1 & 0xffffffffUL);
-            Point_Of_Result++;
-        } /* End of for */
-        if (Carry64 > 0)
-            Point_Of_Result[0] += (UINT32) (Carry64 & 0xffffffffUL);
-    } /* End of for */
-
-    BigInteger_ClearHighBits(*pBI_Result);
-    BigInteger_Copy(*pBI_Result, &pBI_O);
-
-    Carry32 = 0;
-	for (BIFirstIndex=0; BIFirstIndex < pBI_O->ArrayLength; BIFirstIndex++) {
-        pBI_O->pIntegerArray[BIFirstIndex] = (pBI_O->pIntegerArray[BIFirstIndex] << 1) | Carry32;
-        if (pBI_O->pIntegerArray[BIFirstIndex] < (*pBI_Result)->pIntegerArray[BIFirstIndex])
-            Carry32 = 1;
-        else
-            Carry32 = 0;
-    } /* End of for */
-    pBI_O->pIntegerArray[BIFirstIndex] = Carry32;
-    pBI_O->IntegerLength++;
-    pBI_O->ArrayLength++;
-    BigInteger_ClearHighBits(pBI_O);
-
-    BigInteger_Add(pBI_O, pBI_S, pBI_Result);
-output:
-    (*pBI_Result)->Signed = 1;
-    BigInteger_ClearHighBits(*pBI_Result);
-} /* End of BigInteger_Square */
-
-
-VOID BigInteger_Div (
-    IN PBIG_INTEGER pFirstOperand,
-    IN PBIG_INTEGER pSecondOperand,
-    OUT PBIG_INTEGER *pBI_Result,
-    OUT PBIG_INTEGER *pBI_Remainder)
-{
-    INT CompareResult;
-    INT Index, MulIndex, ComputeSize;
-    UINT32 MulStart;
-    UINT AllocLength, ArrayIndex, ShiftIndex;
-    PBIG_INTEGER pTempBI = NULL, pTempBI2 = NULL, pMulBI = NULL;
-    UINT8 SecondHighByte;
-
-    if  ((pFirstOperand == NULL) || (pFirstOperand->pIntegerArray == NULL)
-      || (pSecondOperand == NULL) || (pSecondOperand->pIntegerArray == NULL)) {
-        DEBUGPRINT("BigInteger_Div: first or second operand is NULL.\n");
-        return;
-    } /* End of if */
-
-    /* The second operand is zero */
-    if ((pSecondOperand->IntegerLength == 1) && (pSecondOperand->pIntegerArray[0] == 0)) {
-        DEBUGPRINT("BigInteger_Div: second operand is zero.\n");
-        return;
-    } /* End of if */
-
-    if (*pBI_Result == NULL)
-        BigInteger_Init(pBI_Result);
-    if (*pBI_Remainder == NULL)
-        BigInteger_Init(pBI_Remainder);
-
-    /* The second operand is one */
-    if  ((pSecondOperand->IntegerLength  == 1) && (pSecondOperand->pIntegerArray[0]  == 1)) {
-        BigInteger_Copy(pFirstOperand, pBI_Result);
-        BigInteger_Bin2BI(Value_0, 1, pBI_Remainder);
-        goto output;
-    } /* End of if */
-
-    CompareResult = BigInteger_UnsignedCompare(pFirstOperand, pSecondOperand);
-    if (CompareResult == 0) {
-        BigInteger_Bin2BI(Value_1, 1, pBI_Result);
-        BigInteger_Bin2BI(Value_0, 1, pBI_Remainder);
-        goto output;
-    } else if (CompareResult == -1) {
-        BigInteger_Bin2BI(Value_0, 1, pBI_Result);
-        BigInteger_Copy(pFirstOperand, pBI_Remainder);
-        goto output;
-    } /* End of if */
-    BigInteger_AllocSize(pBI_Result, pFirstOperand->IntegerLength - pSecondOperand->IntegerLength + 1);
-    BigInteger_AllocSize(pBI_Remainder, pSecondOperand->IntegerLength);
-
-    AllocLength = (UINT) (pFirstOperand->IntegerLength << 1);
-    BigInteger_AllocSize(&pTempBI, AllocLength);
-    BigInteger_AllocSize(&pTempBI2, AllocLength);
-    BigInteger_AllocSize(&pMulBI, AllocLength);
-
-    BigInteger_Copy(pFirstOperand, pBI_Remainder);
-    SecondHighByte = BigInteger_GetByteValue(pSecondOperand, pSecondOperand->IntegerLength);
-    ComputeSize = (INT) pFirstOperand->IntegerLength - pSecondOperand->IntegerLength + 1;
-    for (Index = (INT) ComputeSize;Index >= 0;Index--) {
-        if (BigInteger_UnsignedCompare(*pBI_Remainder, pSecondOperand) == -1)
-            break;
-
-        if (((pSecondOperand->IntegerLength + Index) - (*pBI_Remainder)->IntegerLength) <= 1) {
-            BigInteger_AllocSize(&pMulBI, Index + 1);
-            ArrayIndex = 0;
-            if (Index > 0)
-                ArrayIndex = (UINT) (Index - 1) >> 2 ;
-            ShiftIndex = (Index & 0x03);
-            if (ShiftIndex == 0)
-                ShiftIndex = 4;
-            ShiftIndex--;
-            MulStart = 0;
-            MulStart = (BigInteger_GetByteValue((*pBI_Remainder), pFirstOperand->IntegerLength + Index - ComputeSize + 1) & 0xFF) << 8;
-            MulStart = MulStart | (BigInteger_GetByteValue((*pBI_Remainder), pFirstOperand->IntegerLength + Index - ComputeSize) & 0xFF);
-            if (MulStart < (UINT32) SecondHighByte)
-                continue;
-
-            MulStart = MulStart / (UINT32) SecondHighByte;
-
-            if (MulStart > 0xFF)
-                MulStart = 0x100;
-
-            for (MulIndex = (INT) MulStart;MulIndex <= 0x101;MulIndex++) { /* 0xFFFF / 0xFF = 0x101 */
-                if ((MulIndex > 0xFF) && (ShiftIndex == 3))
-                        pMulBI->pIntegerArray[ArrayIndex + 1] = 0x01;
-                pMulBI->pIntegerArray[ArrayIndex] = ((UINT) MulIndex << (8*ShiftIndex));
-                BigInteger_Mul(pSecondOperand, pMulBI , &pTempBI);
-                CompareResult = BigInteger_UnsignedCompare(*pBI_Remainder, pTempBI);
-                if (CompareResult < 1) {
-                    if (MulIndex > 1) {
-                        if (CompareResult != 0) {
-                            if ((MulIndex == 0x100) && (ShiftIndex == 3))
-                                   pMulBI->pIntegerArray[ArrayIndex + 1] = 0;
-                            pMulBI->pIntegerArray[ArrayIndex] = ((UINT) (MulIndex - 1) << (8*ShiftIndex));
-                        } /* End of if */
-
-                        BigInteger_Mul(pSecondOperand, pMulBI, &pTempBI);
-                        BigInteger_Sub(*pBI_Remainder, pTempBI, &pTempBI2);
-                        BigInteger_Copy(pTempBI2, pBI_Remainder);
-                        BigInteger_Add(*pBI_Result, pMulBI, &pTempBI2);
-                        BigInteger_Copy(pTempBI2, pBI_Result);
-                    } /* End of if */
-                    break;
-                } /* End of if */
-
-                if ((MulIndex >= 0x100) && (ShiftIndex == 3))
-                   pMulBI->pIntegerArray[ArrayIndex++] = 0;
-                pMulBI->pIntegerArray[ArrayIndex] = 0;
-            } /* End of for */
-        } /* End of if */
-    } /* End of for */
-
-    BigInteger_Free(&pTempBI);
-    BigInteger_Free(&pTempBI2);
-    BigInteger_Free(&pMulBI);
-output:
-    (*pBI_Result)->Signed = pFirstOperand->Signed * pSecondOperand->Signed;
-    (*pBI_Remainder)->Signed = pFirstOperand->Signed * pSecondOperand->Signed;
-    BigInteger_ClearHighBits(*pBI_Result);
-    BigInteger_ClearHighBits(*pBI_Remainder);
-} /* End of BigInteger_Div */
-
-
-VOID BigInteger_Montgomery_Reduction (
-    IN PBIG_INTEGER pBI_A,
-    IN PBIG_INTEGER pBI_P,
-     IN PBIG_INTEGER pBI_R,
-    OUT PBIG_INTEGER *pBI_Result)
-{
-    UINT32 *Point_P, *Point_Result;
-    UINT32 LoopCount;
-    UINT64 Result64_1, Result64_2, Carry64, TempValue64;
-    INT FirstLoop, SecondLoop;
-
-    BigInteger_AllocSize(pBI_Result, pBI_A->IntegerLength+ pBI_P->IntegerLength + 20);
-    BigInteger_Copy(pBI_A, pBI_Result);
-
-    Point_P = pBI_P->pIntegerArray;
-    Point_Result = (*pBI_Result)->pIntegerArray;
-
-    LoopCount = Bits_Of_R >> 0x5;
-    for (FirstLoop = 0;FirstLoop < LoopCount;FirstLoop++) {
-        Carry64 = 0;
-        TempValue64 = (UINT64) Point_Result[0];
-        for (SecondLoop = 0;SecondLoop < pBI_P->ArrayLength;SecondLoop++) {
-            Result64_1 = ((UINT64) Point_Result[SecondLoop]) + Carry64;
-            Result64_2 = (UINT64) Point_P[SecondLoop]*TempValue64;
-            Carry64 = (Result64_1 >> 32);
-            Result64_1 = (Result64_1 & 0xffffffffUL);
-            Result64_1 = Result64_1 + Result64_2;
-            Carry64 += (Result64_1 >> 32);
-            Point_Result[SecondLoop] = (UINT32) (Result64_1 & 0xffffffffUL);
-        } /* End of for */
-        while (Carry64 != 0) {
-          Result64_1 = ((UINT64) Point_Result[SecondLoop]) + Carry64;
-          Carry64 = Result64_1 >> 32;
-          Point_Result[SecondLoop] = (UINT32) (Result64_1 & 0xffffffffUL);
-          SecondLoop++;
-        } /* End of while */
-        Point_Result++;
-    } /* End of for */
-
-    for (FirstLoop = 0;FirstLoop <= LoopCount;FirstLoop++) {
-        (*pBI_Result)->pIntegerArray[FirstLoop] = (*pBI_Result)->pIntegerArray[FirstLoop + LoopCount];
-    } /* End of for */
-    if ((*pBI_Result)->pIntegerArray[LoopCount] != 0)
-        (*pBI_Result)->ArrayLength = LoopCount + 1;
-    else
-        (*pBI_Result)->ArrayLength = LoopCount;
-
-    (*pBI_Result)->IntegerLength = (*pBI_Result)->ArrayLength*4;
-    BigInteger_ClearHighBits(*pBI_Result);
-
-    if (BigInteger_UnsignedCompare(*pBI_Result, pBI_P) >= 0) {
-        BigInteger_Sub(*pBI_Result, pBI_P, &pBI_U);
-        BigInteger_Copy(pBI_U, pBI_Result);
-    } /* End of if */
-    BigInteger_ClearHighBits(*pBI_Result);
-} /* End of BigInteger_Montgomery_Reduction */
-
-
-VOID BigInteger_Montgomery_ExpMod (
-    IN PBIG_INTEGER pBI_G,
-    IN PBIG_INTEGER pBI_E,
-    IN PBIG_INTEGER pBI_P,
-    OUT PBIG_INTEGER *pBI_Result)
-{
-    UINT Bits_Of_P;
-    UINT32 Index, Index2, AllocLength;
-	UINT32 Sliding_Value , Sliding_HighValue, Sliding_LowValue;
-    PBIG_INTEGER pBI_Temp1 = NULL, pBI_Temp2 = NULL;
-    PBIG_INTEGER pBI_X = NULL, pBI_R = NULL, pBI_RR = NULL, pBI_1 = NULL;
-    BIG_INTEGER *pBI_A[SLIDING_WINDOW];
-    UINT8 *pRValue = NULL;
-
-    AllocLength = (pBI_G->IntegerLength + pBI_E->IntegerLength + pBI_P->IntegerLength + 300);
-    BigInteger_AllocSize(&pBI_Temp1, AllocLength);
-    BigInteger_AllocSize(&pBI_Temp2, AllocLength);
-
-    /* Calculate the bits of P and E, the highest bit is 1 */
-    BigInteger_BitsOfBI(pBI_P, &Bits_Of_P);
-
-    if ((pBI_E->IntegerLength == 1) && (pBI_E->pIntegerArray[0] == 1)) {
-        BigInteger_Div(pBI_G, pBI_P, &pBI_Temp1, pBI_Result);
-        goto memory_free;
-    } /* End of if */
-
-    if ((pBI_E->IntegerLength == 1) && (pBI_E->pIntegerArray[0] == 2)) {
-        BigInteger_Mul(pBI_G, pBI_G, &pBI_Temp1);
-        BigInteger_Div(pBI_Temp1, pBI_P, &pBI_Temp2, pBI_Result);
-        goto memory_free;
-    } /* End of if */
-
-    /*
-     * Main algorithm
-     */
-    BigInteger_Init(&pBI_R);
-    BigInteger_Init(&pBI_RR);
-    BigInteger_Bin2BI(Value_1, 1, &pBI_1);
-    BigInteger_AllocSize(&pBI_X, AllocLength);
-    BigInteger_AllocSize(&pBI_U, AllocLength); // for BigInteger_Montgomery_Reduction
-    BigInteger_AllocSize(&pBI_S, AllocLength); // for BigInteger_Square
-    BigInteger_AllocSize(&pBI_O, AllocLength); // for BigInteger_Square
-
-    for (Index = 0; Index < SLIDING_WINDOW; Index++) {
-        pBI_A[Index] = NULL;
-		BigInteger_AllocSize(&pBI_A[Index], 193);
-    } /* End of for */
-    BigInteger_Bin2BI(WPS_DH_P_VALUE, 192, &pBI_Temp1);
-    if (NdisCmpMemory(pBI_P->pIntegerArray, pBI_Temp1->pIntegerArray, pBI_P->IntegerLength) == 0) {
-        BigInteger_Bin2BI(WPS_DH_X_VALUE, 184, &pBI_X);
-        BigInteger_Bin2BI(WPS_DH_R_VALUE, 193, &pBI_R);
-        BigInteger_Bin2BI(WPS_DH_RRModP_VALUE, 192, &pBI_RR);
-        Bits_Of_R = 1537;
-    } else {
-        if ((Bits_Of_P % 8) == 0) {
-            AllocLength = pBI_P->IntegerLength + 1;
-        } else {
-            AllocLength = pBI_P->IntegerLength;
-        } /* End of if */
-        pRValue = (UINT8 *) kmalloc(sizeof(UINT8)*AllocLength, GFP_ATOMIC);
-	if (pRValue == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s():Alloc memory failed\n", __FUNCTION__));
-		goto memory_free;
-	}
-        NdisZeroMemory(pRValue, sizeof(UINT8)*AllocLength);
-        pRValue[0] = (UINT8) (1 << (Bits_Of_P & 0x7));
-        BigInteger_Bin2BI(pRValue, AllocLength , &pBI_R);
-
-        BigInteger_Mul(pBI_R, pBI_R, &pBI_Temp1);
-        BigInteger_Div(pBI_Temp1, pBI_P, &pBI_A[1], &pBI_RR);
-
-        /* X = 1*R (mod P) */
-        BigInteger_Div(pBI_R, pBI_P, &pBI_Temp2, &pBI_X);
-    } /* End of if */
-
-    /* A = G*R (mod P) => A = MonMod(G, R^2 mod P) */
-    BigInteger_Mul(pBI_G, pBI_RR, &pBI_Temp1);
-    BigInteger_Montgomery_Reduction(pBI_Temp1, pBI_P , pBI_R, &pBI_A[1]);
-    for (Index = 2; Index < SLIDING_WINDOW; Index++) {
-        BigInteger_Mul(pBI_A[Index - 1], pBI_A[1], &pBI_Temp1);
-	    BigInteger_Montgomery_Reduction(pBI_Temp1, pBI_P, pBI_R, &pBI_A[Index]);
-    } /* End of for */
-
-    for (Index = pBI_E->IntegerLength ; Index > 0 ; Index--) {
-        for (Index2 = 0; Index2 < 4 ; Index2++) {
-            BigInteger_Square(pBI_X, &pBI_Temp1);
-			BigInteger_Montgomery_Reduction(pBI_Temp1, pBI_P, pBI_R, &pBI_X);
-	    } /* End of for */
-
-		Sliding_Value = BigInteger_GetByteValue(pBI_E, Index);
-		Sliding_HighValue = (Sliding_Value >> 4);
-		if (Sliding_HighValue != 0) {
-            BigInteger_Mul(pBI_A[Sliding_HighValue], pBI_X, &pBI_Temp1);
-			BigInteger_Montgomery_Reduction(pBI_Temp1, pBI_P, pBI_R, &pBI_X);
-		} /* End of if */
-
-        for (Index2 = 0; Index2 < 4 ; Index2++) {
-            BigInteger_Square(pBI_X, &pBI_Temp1);
-			BigInteger_Montgomery_Reduction(pBI_Temp1, pBI_P, pBI_R, &pBI_X);
-	    } /* End of for */
-
-		Sliding_LowValue = Sliding_Value & 0x0f;
-		if (Sliding_LowValue != 0) {
-            BigInteger_Mul(pBI_A[Sliding_LowValue], pBI_X, &pBI_Temp1);
-			BigInteger_Montgomery_Reduction(pBI_Temp1, pBI_P, pBI_R, &pBI_X);
-		} /* End of if */
-    } /* End of for */
-    BigInteger_Montgomery_Reduction(pBI_X, pBI_P , pBI_R, pBI_Result);
-
-    BigInteger_Free(&pBI_X);
-    BigInteger_Free(&pBI_R);
-    BigInteger_Free(&pBI_RR);
-    BigInteger_Free(&pBI_1);
-    BigInteger_Free(&pBI_U);
-    BigInteger_Free(&pBI_S);
-    BigInteger_Free(&pBI_O);
-    for(Index = 0; Index < SLIDING_WINDOW; Index++)
-			BigInteger_Free(&pBI_A[Index]);
-    if (pRValue != NULL)
-        kfree(pRValue);
-
-memory_free:
-    BigInteger_Free(&pBI_Temp1);
-    BigInteger_Free(&pBI_Temp2);
-} /* End of BigInteger_Montgomery_ExpMod */
-
-/* End of crypt_biginteger.c */
diff --git a/drivers/staging/rt3090/common/crypt_dh.c b/drivers/staging/rt3090/common/crypt_dh.c
deleted file mode 100644
index 0f69f2a..0000000
--- a/drivers/staging/rt3090/common/crypt_dh.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	crypt_dh.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Eddy        2009/01/19      Create AES-128, AES-192, AES-256, AES-CBC
-*/
-
-#include "crypt_dh.h"
-#include "crypt_biginteger.h"
-
-/*
-========================================================================
-Routine Description:
-    Diffie-Hellman public key generation
-
-Arguments:
-    GValue           Array in UINT8
-    GValueLength     The length of G in bytes
-    PValue           Array in UINT8
-    PValueLength     The length of P in bytes
-    PrivateKey       Private key
-    PrivateKeyLength The length of Private key in bytes
-
-Return Value:
-    PublicKey       Public key
-    PublicKeyLength The length of public key in bytes
-
-Note:
-    Reference to RFC2631
-    PublicKey = G^PrivateKey (mod P)
-========================================================================
-*/
-void DH_PublicKey_Generate (
-    IN UINT8 GValue[],
-    IN UINT GValueLength,
-    IN UINT8 PValue[],
-    IN UINT PValueLength,
-    IN UINT8 PrivateKey[],
-    IN UINT PrivateKeyLength,
-    OUT UINT8 PublicKey[],
-    INOUT UINT *PublicKeyLength)
-{
-    PBIG_INTEGER pBI_G = NULL;
-    PBIG_INTEGER pBI_P = NULL;
-    PBIG_INTEGER pBI_PrivateKey = NULL;
-    PBIG_INTEGER pBI_PublicKey = NULL;
-
-    /*
-     * 1. Check the input parameters
-     *    - GValueLength, PValueLength and PrivateLength must be large than zero
-     *    - PublicKeyLength must be large or equal than PValueLength
-     *    - PValue must be odd
-     *
-     *    - PValue must be prime number (no implement)
-     *    - GValue must be greater than 0 but less than the PValue (no implement)
-     */
-    if (GValueLength == 0) {
-	DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: G length is (%d)\n", GValueLength));
-        return;
-    } /* End of if */
-    if (PValueLength == 0) {
-	DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: P length is (%d)\n", PValueLength));
-        return;
-    } /* End of if */
-    if (PrivateKeyLength == 0) {
-	DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: private key length is (%d)\n", PrivateKeyLength));
-        return;
-    } /* End of if */
-    if (*PublicKeyLength < PValueLength) {
-	DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: public key length(%d) must be large or equal than P length(%d)\n",
-            *PublicKeyLength, PValueLength));
-        return;
-    } /* End of if */
-    if (!(PValue[PValueLength - 1] & 0x1)) {
-	DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: P value must be odd\n"));
-        return;
-    } /* End of if */
-
-    /*
-     * 2. Transfer parameters to BigInteger structure
-     */
-    BigInteger_Init(&pBI_G);
-    BigInteger_Init(&pBI_P);
-    BigInteger_Init(&pBI_PrivateKey);
-    BigInteger_Init(&pBI_PublicKey);
-    BigInteger_Bin2BI(GValue, GValueLength, &pBI_G);
-    BigInteger_Bin2BI(PValue, PValueLength, &pBI_P);
-    BigInteger_Bin2BI(PrivateKey, PrivateKeyLength, &pBI_PrivateKey);
-
-    /*
-     * 3. Calculate PublicKey = G^PrivateKey (mod P)
-     *    - BigInteger Operation
-     *    - Montgomery reduction
-     */
-    BigInteger_Montgomery_ExpMod(pBI_G, pBI_PrivateKey, pBI_P, &pBI_PublicKey);
-
-    /*
-     * 4. Transfer BigInteger structure to char array
-     */
-    BigInteger_BI2Bin(pBI_PublicKey, PublicKey, PublicKeyLength);
-
-    BigInteger_Free(&pBI_G);
-    BigInteger_Free(&pBI_P);
-    BigInteger_Free(&pBI_PrivateKey);
-    BigInteger_Free(&pBI_PublicKey);
-} /* End of DH_PublicKey_Generate */
-
-
-/*
-========================================================================
-Routine Description:
-    Diffie-Hellman secret key generation
-
-Arguments:
-    PublicKey        Public key
-    PublicKeyLength  The length of Public key in bytes
-    PValue           Array in UINT8
-    PValueLength     The length of P in bytes
-    PrivateKey       Private key
-    PrivateKeyLength The length of Private key in bytes
-
-Return Value:
-    SecretKey        Secret key
-    SecretKeyLength  The length of secret key in bytes
-
-Note:
-    Reference to RFC2631
-    SecretKey = PublicKey^PrivateKey (mod P)
-========================================================================
-*/
-void DH_SecretKey_Generate (
-    IN UINT8 PublicKey[],
-    IN UINT PublicKeyLength,
-    IN UINT8 PValue[],
-    IN UINT PValueLength,
-    IN UINT8 PrivateKey[],
-    IN UINT PrivateKeyLength,
-    OUT UINT8 SecretKey[],
-    INOUT UINT *SecretKeyLength)
-{
-    PBIG_INTEGER pBI_P = NULL;
-    PBIG_INTEGER pBI_SecretKey = NULL;
-    PBIG_INTEGER pBI_PrivateKey = NULL;
-    PBIG_INTEGER pBI_PublicKey = NULL;
-
-    /*
-     * 1. Check the input parameters
-     *    - PublicKeyLength, PValueLength and PrivateLength must be large than zero
-     *    - SecretKeyLength must be large or equal than PValueLength
-     *    - PValue must be odd
-     *
-     *    - PValue must be prime number (no implement)
-     */
-    if (PublicKeyLength == 0) {
-	DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: public key length is (%d)\n", PublicKeyLength));
-        return;
-    } /* End of if */
-    if (PValueLength == 0) {
-	DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: P length is (%d)\n", PValueLength));
-        return;
-    } /* End of if */
-    if (PrivateKeyLength == 0) {
-	DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: private key length is (%d)\n", PrivateKeyLength));
-        return;
-    } /* End of if */
-    if (*SecretKeyLength < PValueLength) {
-	DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: secret key length(%d) must be large or equal than P length(%d)\n",
-            *SecretKeyLength, PValueLength));
-        return;
-    } /* End of if */
-    if (!(PValue[PValueLength - 1] & 0x1)) {
-	DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: P value must be odd\n"));
-        return;
-    } /* End of if */
-
-    /*
-     * 2. Transfer parameters to BigInteger structure
-     */
-    BigInteger_Init(&pBI_P);
-    BigInteger_Init(&pBI_PrivateKey);
-    BigInteger_Init(&pBI_PublicKey);
-    BigInteger_Init(&pBI_SecretKey);
-
-    BigInteger_Bin2BI(PublicKey, PublicKeyLength, &pBI_PublicKey);
-    BigInteger_Bin2BI(PValue, PValueLength, &pBI_P);
-    BigInteger_Bin2BI(PrivateKey, PrivateKeyLength, &pBI_PrivateKey);
-
-    /*
-     * 3. Calculate SecretKey = PublicKey^PrivateKey (mod P)
-     *    - BigInteger Operation
-     *    - Montgomery reduction
-     */
-    BigInteger_Montgomery_ExpMod(pBI_PublicKey, pBI_PrivateKey, pBI_P, &pBI_SecretKey);
-
-    /*
-     * 4. Transfer BigInteger structure to char array
-     */
-    BigInteger_BI2Bin(pBI_SecretKey, SecretKey, SecretKeyLength);
-
-    BigInteger_Free(&pBI_P);
-    BigInteger_Free(&pBI_PrivateKey);
-    BigInteger_Free(&pBI_PublicKey);
-    BigInteger_Free(&pBI_SecretKey);
-} /* End of DH_SecretKey_Generate */
diff --git a/drivers/staging/rt3090/common/crypt_hmac.c b/drivers/staging/rt3090/common/crypt_hmac.c
deleted file mode 100644
index e285408..0000000
--- a/drivers/staging/rt3090/common/crypt_hmac.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************/
-
-#include "../crypt_hmac.h"
-
-
-#ifdef HMAC_SHA1_SUPPORT
-/*
-========================================================================
-Routine Description:
-    HMAC using SHA1 hash function
-
-Arguments:
-    key             Secret key
-    key_len         The length of the key in bytes
-    message         Message context
-    message_len     The length of message in bytes
-    macLen          Request the length of message authentication code
-
-Return Value:
-    mac             Message authentication code
-
-Note:
-    None
-========================================================================
-*/
-VOID HMAC_SHA1 (
-    IN  const UINT8 Key[],
-    IN  UINT KeyLen,
-    IN  const UINT8 Message[],
-    IN  UINT MessageLen,
-    OUT UINT8 MAC[],
-    IN  UINT MACLen)
-{
-    SHA1_CTX_STRUC sha_ctx1;
-    SHA1_CTX_STRUC sha_ctx2;
-    UINT8 K0[SHA1_BLOCK_SIZE];
-    UINT8 Digest[SHA1_DIGEST_SIZE];
-    UINT index;
-
-    NdisZeroMemory(&sha_ctx1, sizeof(SHA1_CTX_STRUC));
-    NdisZeroMemory(&sha_ctx2, sizeof(SHA1_CTX_STRUC));
-    /*
-     * If the length of K = B(Block size): K0 = K.
-     * If the length of K > B: hash K to obtain an L byte string,
-     * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
-     * If the length of K < B: append zeros to the end of K to create a B-byte string K0
-     */
-    NdisZeroMemory(K0, SHA1_BLOCK_SIZE);
-    if (KeyLen <= SHA1_BLOCK_SIZE)
-        NdisMoveMemory(K0, Key, KeyLen);
-    else
-        RT_SHA1(Key, KeyLen, K0);
-    /* End of if */
-
-    /* Exclusive-Or K0 with ipad */
-    /* ipad: Inner pad; the byte x��36�� repeated B times. */
-    for (index = 0; index < SHA1_BLOCK_SIZE; index++)
-        K0[index] ^= 0x36;
-        /* End of for */
-
-    SHA1_Init(&sha_ctx1);
-    /* H(K0^ipad) */
-    SHA1_Append(&sha_ctx1, K0, sizeof(K0));
-    /* H((K0^ipad)||text) */
-    SHA1_Append(&sha_ctx1, Message, MessageLen);
-    SHA1_End(&sha_ctx1, Digest);
-
-    /* Exclusive-Or K0 with opad and remove ipad */
-    /* opad: Outer pad; the byte x��5c�� repeated B times. */
-    for (index = 0; index < SHA1_BLOCK_SIZE; index++)
-        K0[index] ^= 0x36^0x5c;
-        /* End of for */
-
-    SHA1_Init(&sha_ctx2);
-    /* H(K0^opad) */
-    SHA1_Append(&sha_ctx2, K0, sizeof(K0));
-    /* H( (K0^opad) || H((K0^ipad)||text) ) */
-    SHA1_Append(&sha_ctx2, Digest, SHA1_DIGEST_SIZE);
-    SHA1_End(&sha_ctx2, Digest);
-
-    if (MACLen > SHA1_DIGEST_SIZE)
-        NdisMoveMemory(MAC, Digest, SHA1_DIGEST_SIZE);
-    else
-        NdisMoveMemory(MAC, Digest, MACLen);
-} /* End of HMAC_SHA1 */
-#endif /* HMAC_SHA1_SUPPORT */
-
-
-#ifdef HMAC_SHA256_SUPPORT
-/*
-========================================================================
-Routine Description:
-    HMAC using SHA256 hash function
-
-Arguments:
-    key             Secret key
-    key_len         The length of the key in bytes
-    message         Message context
-    message_len     The length of message in bytes
-    macLen          Request the length of message authentication code
-
-Return Value:
-    mac             Message authentication code
-
-Note:
-    None
-========================================================================
-*/
-VOID HMAC_SHA256 (
-    IN  const UINT8 Key[],
-    IN  UINT KeyLen,
-    IN  const UINT8 Message[],
-    IN  UINT MessageLen,
-    OUT UINT8 MAC[],
-    IN  UINT MACLen)
-{
-    SHA256_CTX_STRUC sha_ctx1;
-    SHA256_CTX_STRUC sha_ctx2;
-    UINT8 K0[SHA256_BLOCK_SIZE];
-    UINT8 Digest[SHA256_DIGEST_SIZE];
-    UINT index;
-
-    NdisZeroMemory(&sha_ctx1, sizeof(SHA256_CTX_STRUC));
-    NdisZeroMemory(&sha_ctx2, sizeof(SHA256_CTX_STRUC));
-    /*
-     * If the length of K = B(Block size): K0 = K.
-     * If the length of K > B: hash K to obtain an L byte string,
-     * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
-     * If the length of K < B: append zeros to the end of K to create a B-byte string K0
-     */
-    NdisZeroMemory(K0, SHA256_BLOCK_SIZE);
-    if (KeyLen <= SHA256_BLOCK_SIZE) {
-        NdisMoveMemory(K0, Key, KeyLen);
-    } else {
-        RT_SHA256(Key, KeyLen, K0);
-    }
-
-    /* Exclusive-Or K0 with ipad */
-    /* ipad: Inner pad; the byte x��36�� repeated B times. */
-    for (index = 0; index < SHA256_BLOCK_SIZE; index++)
-        K0[index] ^= 0x36;
-        /* End of for */
-
-    SHA256_Init(&sha_ctx1);
-    /* H(K0^ipad) */
-    SHA256_Append(&sha_ctx1, K0, sizeof(K0));
-    /* H((K0^ipad)||text) */
-    SHA256_Append(&sha_ctx1, Message, MessageLen);
-    SHA256_End(&sha_ctx1, Digest);
-
-    /* Exclusive-Or K0 with opad and remove ipad */
-    /* opad: Outer pad; the byte x��5c�� repeated B times. */
-    for (index = 0; index < SHA256_BLOCK_SIZE; index++)
-        K0[index] ^= 0x36^0x5c;
-        /* End of for */
-
-    SHA256_Init(&sha_ctx2);
-    /* H(K0^opad) */
-    SHA256_Append(&sha_ctx2, K0, sizeof(K0));
-    /* H( (K0^opad) || H((K0^ipad)||text) ) */
-    SHA256_Append(&sha_ctx2, Digest, SHA256_DIGEST_SIZE);
-    SHA256_End(&sha_ctx2, Digest);
-
-    if (MACLen > SHA256_DIGEST_SIZE)
-        NdisMoveMemory(MAC, Digest,SHA256_DIGEST_SIZE);
-    else
-        NdisMoveMemory(MAC, Digest, MACLen);
-
-} /* End of HMAC_SHA256 */
-#endif /* HMAC_SHA256_SUPPORT */
-
-
-#ifdef HMAC_MD5_SUPPORT
-/*
-========================================================================
-Routine Description:
-    HMAC using MD5 hash function
-
-Arguments:
-    key             Secret key
-    key_len         The length of the key in bytes
-    message         Message context
-    message_len     The length of message in bytes
-    macLen          Request the length of message authentication code
-
-Return Value:
-    mac             Message authentication code
-
-Note:
-    None
-========================================================================
-*/
-VOID HMAC_MD5(
-    IN  const UINT8 Key[],
-    IN  UINT KeyLen,
-    IN  const UINT8 Message[],
-    IN  UINT MessageLen,
-    OUT UINT8 MAC[],
-    IN  UINT MACLen)
-{
-    MD5_CTX_STRUC md5_ctx1;
-    MD5_CTX_STRUC md5_ctx2;
-    UINT8 K0[MD5_BLOCK_SIZE];
-    UINT8 Digest[MD5_DIGEST_SIZE];
-    UINT index;
-
-    NdisZeroMemory(&md5_ctx1, sizeof(MD5_CTX_STRUC));
-    NdisZeroMemory(&md5_ctx2, sizeof(MD5_CTX_STRUC));
-    /*
-     * If the length of K = B(Block size): K0 = K.
-     * If the length of K > B: hash K to obtain an L byte string,
-     * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
-     * If the length of K < B: append zeros to the end of K to create a B-byte string K0
-     */
-    NdisZeroMemory(K0, MD5_BLOCK_SIZE);
-    if (KeyLen <= MD5_BLOCK_SIZE) {
-        NdisMoveMemory(K0, Key, KeyLen);
-    } else {
-        RT_MD5(Key, KeyLen, K0);
-    }
-
-    /* Exclusive-Or K0 with ipad */
-    /* ipad: Inner pad; the byte x��36�� repeated B times. */
-    for (index = 0; index < MD5_BLOCK_SIZE; index++)
-        K0[index] ^= 0x36;
-        /* End of for */
-
-    MD5_Init(&md5_ctx1);
-    /* H(K0^ipad) */
-    MD5_Append(&md5_ctx1, K0, sizeof(K0));
-    /* H((K0^ipad)||text) */
-    MD5_Append(&md5_ctx1, Message, MessageLen);
-    MD5_End(&md5_ctx1, Digest);
-
-    /* Exclusive-Or K0 with opad and remove ipad */
-    /* opad: Outer pad; the byte x��5c�� repeated B times. */
-    for (index = 0; index < MD5_BLOCK_SIZE; index++)
-        K0[index] ^= 0x36^0x5c;
-        /* End of for */
-
-    MD5_Init(&md5_ctx2);
-    /* H(K0^opad) */
-    MD5_Append(&md5_ctx2, K0, sizeof(K0));
-    /* H( (K0^opad) || H((K0^ipad)||text) ) */
-    MD5_Append(&md5_ctx2, Digest, MD5_DIGEST_SIZE);
-    MD5_End(&md5_ctx2, Digest);
-
-    if (MACLen > MD5_DIGEST_SIZE)
-        NdisMoveMemory(MAC, Digest, MD5_DIGEST_SIZE);
-    else
-        NdisMoveMemory(MAC, Digest, MACLen);
-} /* End of HMAC_SHA256 */
-#endif /* HMAC_MD5_SUPPORT */
-
-/* End of crypt_hmac.c */
diff --git a/drivers/staging/rt3090/common/crypt_md5.c b/drivers/staging/rt3090/common/crypt_md5.c
deleted file mode 100644
index b093265..0000000
--- a/drivers/staging/rt3090/common/crypt_md5.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************/
-
-#include "../crypt_md5.h"
-
-
-#ifdef MD5_SUPPORT
-/*
- * F, G, H and I are basic MD5 functions.
- */
-#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define I(x, y, z) ((y) ^ ((x) | (~z)))
-
-#define ROTL(x,n,w) ((x << n) | (x >> (w - n)))
-#define ROTL32(x,n) ROTL(x,n,32) /* 32 bits word */
-
-#define ROUND1(a, b, c, d, x, s, ac) {          \
-    (a) += F((b),(c),(d)) + (x) + (UINT32)(ac); \
-    (a)  = ROTL32((a),(s));                     \
-    (a) += (b);                                 \
-}
-#define ROUND2(a, b, c, d, x, s, ac) {          \
-    (a) += G((b),(c),(d)) + (x) + (UINT32)(ac); \
-    (a)  = ROTL32((a),(s));                     \
-    (a) += (b);                                 \
-}
-#define ROUND3(a, b, c, d, x, s, ac) {          \
-    (a) += H((b),(c),(d)) + (x) + (UINT32)(ac); \
-    (a)  = ROTL32((a),(s));                     \
-    (a) += (b);                                 \
-}
-#define ROUND4(a, b, c, d, x, s, ac) {          \
-    (a) += I((b),(c),(d)) + (x) + (UINT32)(ac); \
-    (a)  = ROTL32((a),(s));                     \
-    (a) += (b);                                 \
-}
-static const UINT32 MD5_DefaultHashValue[4] = {
-    0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL
-};
-#endif /* MD5_SUPPORT */
-
-
-#ifdef MD5_SUPPORT
-/*
-========================================================================
-Routine Description:
-    Initial Md5_CTX_STRUC
-
-Arguments:
-    pMD5_CTX        Pointer to Md5_CTX_STRUC
-
-Return Value:
-    None
-
-Note:
-    None
-========================================================================
-*/
-VOID MD5_Init (
-    IN  MD5_CTX_STRUC *pMD5_CTX)
-{
-    NdisMoveMemory(pMD5_CTX->HashValue, MD5_DefaultHashValue,
-        sizeof(MD5_DefaultHashValue));
-    NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE);
-    pMD5_CTX->BlockLen   = 0;
-    pMD5_CTX->MessageLen = 0;
-} /* End of MD5_Init */
-
-
-/*
-========================================================================
-Routine Description:
-    MD5 computation for one block (512 bits)
-
-Arguments:
-    pMD5_CTX        Pointer to Md5_CTX_STRUC
-
-Return Value:
-    None
-
-Note:
-    T[i] := floor(abs(sin(i + 1)) * (2 pow 32)), i is number of round
-========================================================================
-*/
-VOID MD5_Hash (
-    IN  MD5_CTX_STRUC *pMD5_CTX)
-{
-    UINT32 X_i;
-    UINT32 X[16];
-    UINT32 a,b,c,d;
-
-    /* Prepare the message schedule, {X_i} */
-    NdisMoveMemory(X, pMD5_CTX->Block, MD5_BLOCK_SIZE);
-    for (X_i = 0; X_i < 16; X_i++)
-        X[X_i] = cpu2le32(X[X_i]); /* Endian Swap */
-        /* End of for */
-
-    /* MD5 hash computation */
-    /* Initialize the working variables */
-    a = pMD5_CTX->HashValue[0];
-    b = pMD5_CTX->HashValue[1];
-    c = pMD5_CTX->HashValue[2];
-    d = pMD5_CTX->HashValue[3];
-
-    /*
-     *  Round 1
-     *  Let [abcd k s i] denote the operation
-     *  a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s)
-     */
-    ROUND1(a, b, c, d, X[ 0],  7, 0xd76aa478); /* 1 */
-    ROUND1(d, a, b, c, X[ 1], 12, 0xe8c7b756); /* 2 */
-    ROUND1(c, d, a, b, X[ 2], 17, 0x242070db); /* 3 */
-    ROUND1(b, c, d, a, X[ 3], 22, 0xc1bdceee); /* 4 */
-    ROUND1(a, b, c, d, X[ 4],  7, 0xf57c0faf); /* 5 */
-    ROUND1(d, a, b, c, X[ 5], 12, 0x4787c62a); /* 6 */
-    ROUND1(c, d, a, b, X[ 6], 17, 0xa8304613); /* 7 */
-    ROUND1(b, c, d, a, X[ 7], 22, 0xfd469501); /* 8 */
-    ROUND1(a, b, c, d, X[ 8],  7, 0x698098d8); /* 9 */
-    ROUND1(d, a, b, c, X[ 9], 12, 0x8b44f7af); /* 10 */
-    ROUND1(c, d, a, b, X[10], 17, 0xffff5bb1); /* 11 */
-    ROUND1(b, c, d, a, X[11], 22, 0x895cd7be); /* 12 */
-    ROUND1(a, b, c, d, X[12],  7, 0x6b901122); /* 13 */
-    ROUND1(d, a, b, c, X[13], 12, 0xfd987193); /* 14 */
-    ROUND1(c, d, a, b, X[14], 17, 0xa679438e); /* 15 */
-    ROUND1(b, c, d, a, X[15], 22, 0x49b40821); /* 16 */
-
-    /*
-     *  Round 2
-     *  Let [abcd k s i] denote the operation
-     *  a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s)
-     */
-    ROUND2(a, b, c, d, X[ 1],  5, 0xf61e2562); /* 17 */
-    ROUND2(d, a, b, c, X[ 6],  9, 0xc040b340); /* 18 */
-    ROUND2(c, d, a, b, X[11], 14, 0x265e5a51); /* 19 */
-    ROUND2(b, c, d, a, X[ 0], 20, 0xe9b6c7aa); /* 20 */
-    ROUND2(a, b, c, d, X[ 5],  5, 0xd62f105d); /* 21 */
-    ROUND2(d, a, b, c, X[10],  9,  0x2441453); /* 22 */
-    ROUND2(c, d, a, b, X[15], 14, 0xd8a1e681); /* 23 */
-    ROUND2(b, c, d, a, X[ 4], 20, 0xe7d3fbc8); /* 24 */
-    ROUND2(a, b, c, d, X[ 9],  5, 0x21e1cde6); /* 25 */
-    ROUND2(d, a, b, c, X[14],  9, 0xc33707d6); /* 26 */
-    ROUND2(c, d, a, b, X[ 3], 14, 0xf4d50d87); /* 27 */
-    ROUND2(b, c, d, a, X[ 8], 20, 0x455a14ed); /* 28 */
-    ROUND2(a, b, c, d, X[13],  5, 0xa9e3e905); /* 29 */
-    ROUND2(d, a, b, c, X[ 2],  9, 0xfcefa3f8); /* 30 */
-    ROUND2(c, d, a, b, X[ 7], 14, 0x676f02d9); /* 31 */
-    ROUND2(b, c, d, a, X[12], 20, 0x8d2a4c8a); /* 32 */
-
-    /*
-     *  Round 3
-     *  Let [abcd k s t] denote the operation
-     *  a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s)
-     */
-    ROUND3(a, b, c, d, X[ 5],  4, 0xfffa3942); /* 33 */
-    ROUND3(d, a, b, c, X[ 8], 11, 0x8771f681); /* 34 */
-    ROUND3(c, d, a, b, X[11], 16, 0x6d9d6122); /* 35 */
-    ROUND3(b, c, d, a, X[14], 23, 0xfde5380c); /* 36 */
-    ROUND3(a, b, c, d, X[ 1],  4, 0xa4beea44); /* 37 */
-    ROUND3(d, a, b, c, X[ 4], 11, 0x4bdecfa9); /* 38 */
-    ROUND3(c, d, a, b, X[ 7], 16, 0xf6bb4b60); /* 39 */
-    ROUND3(b, c, d, a, X[10], 23, 0xbebfbc70); /* 40 */
-    ROUND3(a, b, c, d, X[13],  4, 0x289b7ec6); /* 41 */
-    ROUND3(d, a, b, c, X[ 0], 11, 0xeaa127fa); /* 42 */
-    ROUND3(c, d, a, b, X[ 3], 16, 0xd4ef3085); /* 43 */
-    ROUND3(b, c, d, a, X[ 6], 23,  0x4881d05); /* 44 */
-    ROUND3(a, b, c, d, X[ 9],  4, 0xd9d4d039); /* 45 */
-    ROUND3(d, a, b, c, X[12], 11, 0xe6db99e5); /* 46 */
-    ROUND3(c, d, a, b, X[15], 16, 0x1fa27cf8); /* 47 */
-    ROUND3(b, c, d, a, X[ 2], 23, 0xc4ac5665); /* 48 */
-
-    /*
-     *  Round 4
-     *  Let [abcd k s t] denote the operation
-     *  a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s)
-     */
-    ROUND4(a, b, c, d, X[ 0],  6, 0xf4292244); /* 49 */
-    ROUND4(d, a, b, c, X[ 7], 10, 0x432aff97); /* 50 */
-    ROUND4(c, d, a, b, X[14], 15, 0xab9423a7); /* 51 */
-    ROUND4(b, c, d, a, X[ 5], 21, 0xfc93a039); /* 52 */
-    ROUND4(a, b, c, d, X[12],  6, 0x655b59c3); /* 53 */
-    ROUND4(d, a, b, c, X[ 3], 10, 0x8f0ccc92); /* 54 */
-    ROUND4(c, d, a, b, X[10], 15, 0xffeff47d); /* 55 */
-    ROUND4(b, c, d, a, X[ 1], 21, 0x85845dd1); /* 56 */
-    ROUND4(a, b, c, d, X[ 8],  6, 0x6fa87e4f); /* 57 */
-    ROUND4(d, a, b, c, X[15], 10, 0xfe2ce6e0); /* 58 */
-    ROUND4(c, d, a, b, X[ 6], 15, 0xa3014314); /* 59 */
-    ROUND4(b, c, d, a, X[13], 21, 0x4e0811a1); /* 60 */
-    ROUND4(a, b, c, d, X[ 4],  6, 0xf7537e82); /* 61 */
-    ROUND4(d, a, b, c, X[11], 10, 0xbd3af235); /* 62 */
-    ROUND4(c, d, a, b, X[ 2], 15, 0x2ad7d2bb); /* 63 */
-    ROUND4(b, c, d, a, X[ 9], 21, 0xeb86d391); /* 64 */
-
-    /* Compute the i^th intermediate hash value H^(i) */
-    pMD5_CTX->HashValue[0] += a;
-    pMD5_CTX->HashValue[1] += b;
-    pMD5_CTX->HashValue[2] += c;
-    pMD5_CTX->HashValue[3] += d;
-
-    NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE);
-    pMD5_CTX->BlockLen = 0;
-} /* End of MD5_Hash */
-
-
-/*
-========================================================================
-Routine Description:
-    The message is appended to block. If block size > 64 bytes, the MD5_Hash
-will be called.
-
-Arguments:
-    pMD5_CTX        Pointer to MD5_CTX_STRUC
-    message         Message context
-    messageLen      The length of message in bytes
-
-Return Value:
-    None
-
-Note:
-    None
-========================================================================
-*/
-VOID MD5_Append (
-    IN  MD5_CTX_STRUC *pMD5_CTX,
-    IN  const UINT8 Message[],
-    IN  UINT MessageLen)
-{
-    UINT appendLen = 0;
-    UINT diffLen = 0;
-
-    while (appendLen != MessageLen) {
-        diffLen = MessageLen - appendLen;
-        if ((pMD5_CTX->BlockLen + diffLen) < MD5_BLOCK_SIZE) {
-            NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen,
-                Message + appendLen, diffLen);
-            pMD5_CTX->BlockLen += diffLen;
-            appendLen += diffLen;
-        }
-        else
-        {
-            NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen,
-                Message + appendLen, MD5_BLOCK_SIZE - pMD5_CTX->BlockLen);
-            appendLen += (MD5_BLOCK_SIZE - pMD5_CTX->BlockLen);
-            pMD5_CTX->BlockLen = MD5_BLOCK_SIZE;
-            MD5_Hash(pMD5_CTX);
-        } /* End of if */
-    } /* End of while */
-    pMD5_CTX->MessageLen += MessageLen;
-} /* End of MD5_Append */
-
-
-/*
-========================================================================
-Routine Description:
-    1. Append bit 1 to end of the message
-    2. Append the length of message in rightmost 64 bits
-    3. Transform the Hash Value to digest message
-
-Arguments:
-    pMD5_CTX        Pointer to MD5_CTX_STRUC
-
-Return Value:
-    digestMessage   Digest message
-
-Note:
-    None
-========================================================================
-*/
-VOID MD5_End (
-    IN  MD5_CTX_STRUC *pMD5_CTX,
-    OUT UINT8 DigestMessage[])
-{
-    UINT index;
-    UINT64 message_length_bits;
-
-    /* append 1 bits to end of the message */
-    NdisFillMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen, 1, 0x80);
-
-    /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
-    if (pMD5_CTX->BlockLen > 55)
-        MD5_Hash(pMD5_CTX);
-        /* End of if */
-
-    /* Append the length of message in rightmost 64 bits */
-    message_length_bits = pMD5_CTX->MessageLen*8;
-    message_length_bits = cpu2le64(message_length_bits);
-    NdisMoveMemory(&pMD5_CTX->Block[56], &message_length_bits, 8);
-    MD5_Hash(pMD5_CTX);
-
-    /* Return message digest, transform the UINT32 hash value to bytes */
-    for (index = 0; index < 4;index++)
-        pMD5_CTX->HashValue[index] = cpu2le32(pMD5_CTX->HashValue[index]);
-        /* End of for */
-    NdisMoveMemory(DigestMessage, pMD5_CTX->HashValue, MD5_DIGEST_SIZE);
-} /* End of MD5_End */
-
-
-/*
-========================================================================
-Routine Description:
-    MD5 algorithm
-
-Arguments:
-    message         Message context
-    messageLen      The length of message in bytes
-
-Return Value:
-    digestMessage   Digest message
-
-Note:
-    None
-========================================================================
-*/
-VOID RT_MD5 (
-    IN  const UINT8 Message[],
-    IN  UINT MessageLen,
-    OUT UINT8 DigestMessage[])
-{
-    MD5_CTX_STRUC md5_ctx;
-
-    NdisZeroMemory(&md5_ctx, sizeof(MD5_CTX_STRUC));
-    MD5_Init(&md5_ctx);
-    MD5_Append(&md5_ctx, Message, MessageLen);
-    MD5_End(&md5_ctx, DigestMessage);
-} /* End of RT_MD5 */
-
-#endif /* MD5_SUPPORT */
-
-/* End of crypt_md5.c */
diff --git a/drivers/staging/rt3090/common/crypt_sha2.c b/drivers/staging/rt3090/common/crypt_sha2.c
deleted file mode 100644
index c7490d0..0000000
--- a/drivers/staging/rt3090/common/crypt_sha2.c
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************/
-
-#include "../crypt_sha2.h"
-
-
-/* Basic operations */
-#define SHR(x,n) (x >> n) /* SHR(x)^n, right shift n bits , x is w-bit word, 0 <= n <= w */
-#define ROTR(x,n,w) ((x >> n) | (x << (w - n))) /* ROTR(x)^n, circular right shift n bits , x is w-bit word, 0 <= n <= w */
-#define ROTL(x,n,w) ((x << n) | (x >> (w - n))) /* ROTL(x)^n, circular left shift n bits , x is w-bit word, 0 <= n <= w */
-#define ROTR32(x,n) ROTR(x,n,32) /* 32 bits word */
-#define ROTL32(x,n) ROTL(x,n,32) /* 32 bits word */
-
-/* Basic functions */
-#define Ch(x,y,z) ((x & y) ^ ((~x) & z))
-#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
-#define Parity(x,y,z) (x ^ y ^ z)
-
-#ifdef SHA1_SUPPORT
-/* SHA1 constants */
-#define SHA1_MASK 0x0000000f
-static const UINT32 SHA1_K[4] = {
-    0x5a827999UL, 0x6ed9eba1UL, 0x8f1bbcdcUL, 0xca62c1d6UL
-};
-static const UINT32 SHA1_DefaultHashValue[5] = {
-    0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL, 0xc3d2e1f0UL
-};
-#endif /* SHA1_SUPPORT */
-
-
-#ifdef SHA256_SUPPORT
-/* SHA256 functions */
-#define Zsigma_256_0(x) (ROTR32(x,2) ^ ROTR32(x,13) ^ ROTR32(x,22))
-#define Zsigma_256_1(x) (ROTR32(x,6) ^ ROTR32(x,11) ^ ROTR32(x,25))
-#define Sigma_256_0(x)  (ROTR32(x,7) ^ ROTR32(x,18) ^ SHR(x,3))
-#define Sigma_256_1(x)  (ROTR32(x,17) ^ ROTR32(x,19) ^ SHR(x,10))
-/* SHA256 constants */
-static const UINT32 SHA256_K[64] = {
-    0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
-    0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
-    0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
-    0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
-    0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
-    0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
-    0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
-    0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
-    0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
-    0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
-    0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
-    0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
-    0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
-    0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
-    0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
-    0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
-};
-static const UINT32 SHA256_DefaultHashValue[8] = {
-    0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL,
-    0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL
-};
-#endif /* SHA256_SUPPORT */
-
-
-#ifdef SHA1_SUPPORT
-/*
-========================================================================
-Routine Description:
-    Initial SHA1_CTX_STRUC
-
-Arguments:
-    pSHA_CTX        Pointer to SHA1_CTX_STRUC
-
-Return Value:
-    None
-
-Note:
-    None
-========================================================================
-*/
-VOID SHA1_Init (
-    IN  SHA1_CTX_STRUC *pSHA_CTX)
-{
-    NdisMoveMemory(pSHA_CTX->HashValue, SHA1_DefaultHashValue,
-        sizeof(SHA1_DefaultHashValue));
-    NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE);
-    pSHA_CTX->MessageLen = 0;
-    pSHA_CTX->BlockLen   = 0;
-} /* End of SHA1_Init */
-
-
-/*
-========================================================================
-Routine Description:
-    SHA1 computation for one block (512 bits)
-
-Arguments:
-    pSHA_CTX        Pointer to SHA1_CTX_STRUC
-
-Return Value:
-    None
-
-Note:
-    None
-========================================================================
-*/
-VOID SHA1_Hash (
-    IN  SHA1_CTX_STRUC *pSHA_CTX)
-{
-    UINT32 W_i,t,s;
-    UINT32 W[16];
-    UINT32 a,b,c,d,e,T,f_t = 0;
-
-    /* Prepare the message schedule, {W_i}, 0 < t < 15 */
-    NdisMoveMemory(W, pSHA_CTX->Block, SHA1_BLOCK_SIZE);
-    for (W_i = 0; W_i < 16; W_i++)
-        W[W_i] = cpu2be32(W[W_i]); /* Endian Swap */
-        /* End of for */
-
-    /* SHA256 hash computation */
-    /* Initialize the working variables */
-    a = pSHA_CTX->HashValue[0];
-    b = pSHA_CTX->HashValue[1];
-    c = pSHA_CTX->HashValue[2];
-    d = pSHA_CTX->HashValue[3];
-    e = pSHA_CTX->HashValue[4];
-
-    /* 80 rounds */
-    for (t = 0;t < 80;t++) {
-        s = t & SHA1_MASK;
-        if (t > 15) { /* Prepare the message schedule, {W_i}, 16 < t < 79 */
-            W[s] = (W[(s+13) & SHA1_MASK]) ^ (W[(s+8) & SHA1_MASK]) ^ (W[(s+2) & SHA1_MASK]) ^ W[s];
-            W[s] = ROTL32(W[s],1);
-        } /* End of if */
-        switch (t / 20) {
-            case 0:
-                 f_t = Ch(b,c,d);
-                 break;
-            case 1:
-                 f_t = Parity(b,c,d);
-                 break;
-            case 2:
-                 f_t = Maj(b,c,d);
-                 break;
-            case 3:
-                 f_t = Parity(b,c,d);
-                 break;
-        } /* End of switch */
-        T = ROTL32(a,5) + f_t + e + SHA1_K[t / 20] + W[s];
-        e = d;
-        d = c;
-        c = ROTL32(b,30);
-        b = a;
-        a = T;
-     } /* End of for */
-
-     /* Compute the i^th intermediate hash value H^(i) */
-     pSHA_CTX->HashValue[0] += a;
-     pSHA_CTX->HashValue[1] += b;
-     pSHA_CTX->HashValue[2] += c;
-     pSHA_CTX->HashValue[3] += d;
-     pSHA_CTX->HashValue[4] += e;
-
-    NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE);
-    pSHA_CTX->BlockLen = 0;
-} /* End of SHA1_Hash */
-
-
-/*
-========================================================================
-Routine Description:
-    The message is appended to block. If block size > 64 bytes, the SHA1_Hash
-will be called.
-
-Arguments:
-    pSHA_CTX        Pointer to SHA1_CTX_STRUC
-    message         Message context
-    messageLen      The length of message in bytes
-
-Return Value:
-    None
-
-Note:
-    None
-========================================================================
-*/
-VOID SHA1_Append (
-    IN  SHA1_CTX_STRUC *pSHA_CTX,
-    IN  const UINT8 Message[],
-    IN  UINT MessageLen)
-{
-    UINT appendLen = 0;
-    UINT diffLen   = 0;
-
-    while (appendLen != MessageLen) {
-        diffLen = MessageLen - appendLen;
-        if ((pSHA_CTX->BlockLen + diffLen) <  SHA1_BLOCK_SIZE) {
-            NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
-                Message + appendLen, diffLen);
-            pSHA_CTX->BlockLen += diffLen;
-            appendLen += diffLen;
-        }
-        else
-        {
-            NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
-                Message + appendLen, SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen);
-            appendLen += (SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen);
-            pSHA_CTX->BlockLen = SHA1_BLOCK_SIZE;
-            SHA1_Hash(pSHA_CTX);
-        } /* End of if */
-    } /* End of while */
-    pSHA_CTX->MessageLen += MessageLen;
-} /* End of SHA1_Append */
-
-
-/*
-========================================================================
-Routine Description:
-    1. Append bit 1 to end of the message
-    2. Append the length of message in rightmost 64 bits
-    3. Transform the Hash Value to digest message
-
-Arguments:
-    pSHA_CTX        Pointer to SHA1_CTX_STRUC
-
-Return Value:
-    digestMessage   Digest message
-
-Note:
-    None
-========================================================================
-*/
-VOID SHA1_End (
-    IN  SHA1_CTX_STRUC *pSHA_CTX,
-    OUT UINT8 DigestMessage[])
-{
-    UINT index;
-    UINT64 message_length_bits;
-
-    /* Append bit 1 to end of the message */
-    NdisFillMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, 1, 0x80);
-
-    /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
-    if (pSHA_CTX->BlockLen > 55)
-        SHA1_Hash(pSHA_CTX);
-        /* End of if */
-
-    /* Append the length of message in rightmost 64 bits */
-    message_length_bits = pSHA_CTX->MessageLen*8;
-    message_length_bits = cpu2be64(message_length_bits);
-    NdisMoveMemory(&pSHA_CTX->Block[56], &message_length_bits, 8);
-    SHA1_Hash(pSHA_CTX);
-
-    /* Return message digest, transform the UINT32 hash value to bytes */
-    for (index = 0; index < 5;index++)
-        pSHA_CTX->HashValue[index] = cpu2be32(pSHA_CTX->HashValue[index]);
-        /* End of for */
-    NdisMoveMemory(DigestMessage, pSHA_CTX->HashValue, SHA1_DIGEST_SIZE);
-} /* End of SHA1_End */
-
-
-/*
-========================================================================
-Routine Description:
-    SHA1 algorithm
-
-Arguments:
-    message         Message context
-    messageLen      The length of message in bytes
-
-Return Value:
-    digestMessage   Digest message
-
-Note:
-    None
-========================================================================
-*/
-VOID RT_SHA1 (
-    IN  const UINT8 Message[],
-    IN  UINT MessageLen,
-    OUT UINT8 DigestMessage[])
-{
-
-    SHA1_CTX_STRUC sha_ctx;
-
-    NdisZeroMemory(&sha_ctx, sizeof(SHA1_CTX_STRUC));
-    SHA1_Init(&sha_ctx);
-    SHA1_Append(&sha_ctx, Message, MessageLen);
-    SHA1_End(&sha_ctx, DigestMessage);
-} /* End of RT_SHA1 */
-#endif /* SHA1_SUPPORT */
-
-
-#ifdef SHA256_SUPPORT
-/*
-========================================================================
-Routine Description:
-    Initial SHA256_CTX_STRUC
-
-Arguments:
-    pSHA_CTX    Pointer to SHA256_CTX_STRUC
-
-Return Value:
-    None
-
-Note:
-    None
-========================================================================
-*/
-VOID SHA256_Init (
-    IN  SHA256_CTX_STRUC *pSHA_CTX)
-{
-    NdisMoveMemory(pSHA_CTX->HashValue, SHA256_DefaultHashValue,
-        sizeof(SHA256_DefaultHashValue));
-    NdisZeroMemory(pSHA_CTX->Block, SHA256_BLOCK_SIZE);
-    pSHA_CTX->MessageLen = 0;
-    pSHA_CTX->BlockLen   = 0;
-} /* End of SHA256_Init */
-
-
-/*
-========================================================================
-Routine Description:
-    SHA256 computation for one block (512 bits)
-
-Arguments:
-    pSHA_CTX    Pointer to SHA256_CTX_STRUC
-
-Return Value:
-    None
-
-Note:
-    None
-========================================================================
-*/
-VOID SHA256_Hash (
-    IN  SHA256_CTX_STRUC *pSHA_CTX)
-{
-    UINT32 W_i,t;
-    UINT32 W[64];
-    UINT32 a,b,c,d,e,f,g,h,T1,T2;
-
-    /* Prepare the message schedule, {W_i}, 0 < t < 15 */
-    NdisMoveMemory(W, pSHA_CTX->Block, SHA256_BLOCK_SIZE);
-    for (W_i = 0; W_i < 16; W_i++)
-        W[W_i] = cpu2be32(W[W_i]); /* Endian Swap */
-        /* End of for */
-
-    /* SHA256 hash computation */
-    /* Initialize the working variables */
-    a = pSHA_CTX->HashValue[0];
-    b = pSHA_CTX->HashValue[1];
-    c = pSHA_CTX->HashValue[2];
-    d = pSHA_CTX->HashValue[3];
-    e = pSHA_CTX->HashValue[4];
-    f = pSHA_CTX->HashValue[5];
-    g = pSHA_CTX->HashValue[6];
-    h = pSHA_CTX->HashValue[7];
-
-    /* 64 rounds */
-    for (t = 0;t < 64;t++) {
-        if (t > 15) /* Prepare the message schedule, {W_i}, 16 < t < 63 */
-            W[t] = Sigma_256_1(W[t-2]) + W[t-7] + Sigma_256_0(W[t-15]) + W[t-16];
-            /* End of if */
-        T1 = h + Zsigma_256_1(e) + Ch(e,f,g) + SHA256_K[t] + W[t];
-        T2 = Zsigma_256_0(a) + Maj(a,b,c);
-        h = g;
-        g = f;
-        f = e;
-        e = d + T1;
-        d = c;
-        c = b;
-        b = a;
-        a = T1 + T2;
-     } /* End of for */
-
-     /* Compute the i^th intermediate hash value H^(i) */
-     pSHA_CTX->HashValue[0] += a;
-     pSHA_CTX->HashValue[1] += b;
-     pSHA_CTX->HashValue[2] += c;
-     pSHA_CTX->HashValue[3] += d;
-     pSHA_CTX->HashValue[4] += e;
-     pSHA_CTX->HashValue[5] += f;
-     pSHA_CTX->HashValue[6] += g;
-     pSHA_CTX->HashValue[7] += h;
-
-    NdisZeroMemory(pSHA_CTX->Block, SHA256_BLOCK_SIZE);
-    pSHA_CTX->BlockLen = 0;
-} /* End of SHA256_Hash */
-
-
-/*
-========================================================================
-Routine Description:
-    The message is appended to block. If block size > 64 bytes, the SHA256_Hash
-will be called.
-
-Arguments:
-    pSHA_CTX    Pointer to SHA256_CTX_STRUC
-    message     Message context
-    messageLen  The length of message in bytes
-
-Return Value:
-    None
-
-Note:
-    None
-========================================================================
-*/
-VOID SHA256_Append (
-    IN  SHA256_CTX_STRUC *pSHA_CTX,
-    IN  const UINT8 Message[],
-    IN  UINT MessageLen)
-{
-    UINT appendLen = 0;
-    UINT diffLen   = 0;
-
-    while (appendLen != MessageLen) {
-        diffLen = MessageLen - appendLen;
-        if ((pSHA_CTX->BlockLen + diffLen) <  SHA256_BLOCK_SIZE) {
-            NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
-                Message + appendLen, diffLen);
-            pSHA_CTX->BlockLen += diffLen;
-            appendLen += diffLen;
-        }
-        else
-        {
-            NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
-                Message + appendLen, SHA256_BLOCK_SIZE - pSHA_CTX->BlockLen);
-            appendLen += (SHA256_BLOCK_SIZE - pSHA_CTX->BlockLen);
-            pSHA_CTX->BlockLen = SHA256_BLOCK_SIZE;
-            SHA256_Hash(pSHA_CTX);
-        } /* End of if */
-    } /* End of while */
-    pSHA_CTX->MessageLen += MessageLen;
-} /* End of SHA256_Append */
-
-
-/*
-========================================================================
-Routine Description:
-    1. Append bit 1 to end of the message
-    2. Append the length of message in rightmost 64 bits
-    3. Transform the Hash Value to digest message
-
-Arguments:
-    pSHA_CTX        Pointer to SHA256_CTX_STRUC
-
-Return Value:
-    digestMessage   Digest message
-
-Note:
-    None
-========================================================================
-*/
-VOID SHA256_End (
-    IN  SHA256_CTX_STRUC *pSHA_CTX,
-    OUT UINT8 DigestMessage[])
-{
-    UINT index;
-    UINT64 message_length_bits;
-
-    /* Append bit 1 to end of the message */
-    NdisFillMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, 1, 0x80);
-
-    /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
-    if (pSHA_CTX->BlockLen > 55)
-        SHA256_Hash(pSHA_CTX);
-        /* End of if */
-
-    /* Append the length of message in rightmost 64 bits */
-    message_length_bits = pSHA_CTX->MessageLen*8;
-    message_length_bits = cpu2be64(message_length_bits);
-    NdisMoveMemory(&pSHA_CTX->Block[56], &message_length_bits, 8);
-    SHA256_Hash(pSHA_CTX);
-
-    /* Return message digest, transform the UINT32 hash value to bytes */
-    for (index = 0; index < 8;index++)
-        pSHA_CTX->HashValue[index] = cpu2be32(pSHA_CTX->HashValue[index]);
-        /* End of for */
-    NdisMoveMemory(DigestMessage, pSHA_CTX->HashValue, SHA256_DIGEST_SIZE);
-} /* End of SHA256_End */
-
-
-/*
-========================================================================
-Routine Description:
-    SHA256 algorithm
-
-Arguments:
-    message         Message context
-    messageLen      The length of message in bytes
-
-Return Value:
-    digestMessage   Digest message
-
-Note:
-    None
-========================================================================
-*/
-VOID RT_SHA256 (
-    IN  const UINT8 Message[],
-    IN  UINT MessageLen,
-    OUT UINT8 DigestMessage[])
-{
-    SHA256_CTX_STRUC sha_ctx;
-
-    NdisZeroMemory(&sha_ctx, sizeof(SHA256_CTX_STRUC));
-    SHA256_Init(&sha_ctx);
-    SHA256_Append(&sha_ctx, Message, MessageLen);
-    SHA256_End(&sha_ctx, DigestMessage);
-} /* End of RT_SHA256 */
-#endif /* SHA256_SUPPORT */
-
-/* End of crypt_sha2.c */
diff --git a/drivers/staging/rt3090/common/dfs.c b/drivers/staging/rt3090/common/dfs.c
deleted file mode 100644
index c15704a..0000000
--- a/drivers/staging/rt3090/common/dfs.c
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    ap_dfs.c
-
-    Abstract:
-    Support DFS function.
-
-    Revision History:
-    Who       When            What
-    --------  ----------      ----------------------------------------------
-*/
-
-#include "../rt_config.h"
-
-
-typedef struct _RADAR_DURATION_TABLE
-{
-	ULONG RDDurRegion;
-	ULONG RadarSignalDuration;
-	ULONG Tolerance;
-} RADAR_DURATION_TABLE, *PRADAR_DURATION_TABLE;
-
-
-
-UCHAR RdIdleTimeTable[MAX_RD_REGION][4] =
-{
-	{9, 250, 250, 250},		// CE
-#ifdef DFS_FCC_BW40_FIX
-	{1, 250, 250, 250},		// FCC
-#else
-	{4, 250, 250, 250},		// FCC
-#endif
-	{4, 250, 250, 250},		// JAP
-	{15, 250, 250, 250},	// JAP_W53
-	{4, 250, 250, 250}		// JAP_W56
-};
-
-#ifdef TONE_RADAR_DETECT_SUPPORT
-static void ToneRadarProgram(PRTMP_ADAPTER pAd);
-static void ToneRadarEnable(PRTMP_ADAPTER pAd);
-#endif // TONE_RADAR_DETECT_SUPPORT //
-
-#ifdef DFS_SUPPORT
-/*
-	========================================================================
-
-	Routine Description:
-		Bbp Radar detection routine
-
-	Arguments:
-		pAd	Pointer to our adapter
-
-	Return Value:
-
-	========================================================================
-*/
-VOID BbpRadarDetectionStart(
-	IN PRTMP_ADAPTER pAd)
-{
-	UINT8 RadarPeriod;
-
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 114, 0x02);
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 121, 0x20);
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 122, 0x00);
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 123, 0x08/*0x80*/);
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 124, 0x28);
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 125, 0xff);
-
-#ifdef MERGE_ARCH_TEAM
-	if ((pAd->CommonCfg.RadarDetect.RDDurRegion == JAP) || (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W53) || (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W56))
-	{
-		pAd->CommonCfg.RadarDetect.RDDurRegion = JAP;
-		pAd->CommonCfg.RadarDetect.RDDurRegion = JapRadarType(pAd);
-		if (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W56)
-		{
-			pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
-		}
-		else if (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W53)
-		{
-			pAd->CommonCfg.RadarDetect.DfsSessionTime = 15;
-		}
-#ifdef CARRIER_DETECTION_SUPPORT
-		pAd->CommonCfg.CarrierDetect.Enable = 1;
-#endif // CARRIER_DETECTION_SUPPORT //
-	}
-#endif // MERGE_ARCH_TEAM //
-
-	RadarPeriod = ((UINT)RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + (UINT)pAd->CommonCfg.RadarDetect.DfsSessionTime) < 250 ?
-			(RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + pAd->CommonCfg.RadarDetect.DfsSessionTime) : 250;
-
-#ifdef MERGE_ARCH_TEAM
-
-
-#else // Original RT28xx source code.
-	RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
-	RTMP_IO_WRITE8(pAd, 0x7021, 0x40);
-#endif // MERGE_ARCH_TEAM //
-
-	RadarDetectionStart(pAd, 0, RadarPeriod);
-	return;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Bbp Radar detection routine
-
-	Arguments:
-		pAd	Pointer to our adapter
-
-	Return Value:
-
-	========================================================================
-*/
-VOID BbpRadarDetectionStop(
-	IN PRTMP_ADAPTER pAd)
-{
-	RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
-	RTMP_IO_WRITE8(pAd, 0x7021, 0x60);
-
-	RadarDetectionStop(pAd);
-	return;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Radar detection routine
-
-	Arguments:
-		pAd	Pointer to our adapter
-
-	Return Value:
-
-	========================================================================
-*/
-VOID RadarDetectionStart(
-	IN PRTMP_ADAPTER pAd,
-	IN BOOLEAN CTSProtect,
-	IN UINT8 CTSPeriod)
-{
-	UINT8 DfsActiveTime = (pAd->CommonCfg.RadarDetect.DfsSessionTime & 0x1f);
-	UINT8 CtsProtect = (CTSProtect == 1) ? 0x02 : 0x01; // CTS protect.
-
-	if (CTSProtect != 0)
-	{
-		switch(pAd->CommonCfg.RadarDetect.RDDurRegion)
-		{
-		case FCC:
-		case JAP_W56:
-			CtsProtect = 0x03;
-			break;
-
-		case JAP:
-			{
-				UCHAR RDDurRegion;
-				RDDurRegion = JapRadarType(pAd);
-				if (RDDurRegion == JAP_W56)
-					CtsProtect = 0x03;
-				else
-					CtsProtect = 0x02;
-				break;
-			}
-
-		case CE:
-		case JAP_W53:
-		default:
-			CtsProtect = 0x02;
-			break;
-		}
-	}
-	else
-		CtsProtect = 0x01;
-
-
-	// send start-RD with CTS protection command to MCU
-	// highbyte [7]		reserve
-	// highbyte [6:5]	0x: stop Carrier/Radar detection
-	// highbyte [10]:	Start Carrier/Radar detection without CTS protection, 11: Start Carrier/Radar detection with CTS protection
-	// highbyte [4:0]	Radar/carrier detection duration. In 1ms.
-
-	// lowbyte [7:0]	Radar/carrier detection period, in 1ms.
-	AsicSendCommandToMcu(pAd, 0x60, 0xff, CTSPeriod, DfsActiveTime | (CtsProtect << 5));
-	//AsicSendCommandToMcu(pAd, 0x63, 0xff, 10, 0);
-
-	return;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Radar detection routine
-
-	Arguments:
-		pAd	Pointer to our adapter
-
-	Return Value:
-		TRUE	Found radar signal
-		FALSE	Not found radar signal
-
-	========================================================================
-*/
-VOID RadarDetectionStop(
-	IN PRTMP_ADAPTER	pAd)
-{
-	DBGPRINT(RT_DEBUG_TRACE,("RadarDetectionStop.\n"));
-	AsicSendCommandToMcu(pAd, 0x60, 0xff, 0x00, 0x00);	// send start-RD with CTS protection command to MCU
-
-	return;
-}
-#endif // DFS_SUPPORT //
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Radar channel check routine
-
-	Arguments:
-		pAd	Pointer to our adapter
-
-	Return Value:
-		TRUE	need to do radar detect
-		FALSE	need not to do radar detect
-
-	========================================================================
-*/
-BOOLEAN RadarChannelCheck(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			Ch)
-{
-	INT		i;
-	BOOLEAN result = FALSE;
-
-	for (i=0; i<pAd->ChannelListNum; i++)
-	{
-		if (Ch == pAd->ChannelList[i].Channel)
-		{
-			result = pAd->ChannelList[i].DfsReq;
-			break;
-		}
-	}
-
-	return result;
-}
-
-#ifdef DFS_SUPPORT
-
-ULONG JapRadarType(
-	IN PRTMP_ADAPTER pAd)
-{
-	ULONG		i;
-	const UCHAR	Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
-
-	if (pAd->CommonCfg.RadarDetect.RDDurRegion != JAP)
-	{
-		return pAd->CommonCfg.RadarDetect.RDDurRegion;
-	}
-
-	for (i=0; i<15; i++)
-	{
-		if (pAd->CommonCfg.Channel == Channel[i])
-		{
-			break;
-		}
-	}
-
-	if (i < 4)
-		return JAP_W53;
-	else if (i < 15)
-		return JAP_W56;
-	else
-		return JAP; // W52
-
-}
-
-ULONG RTMPBbpReadRadarDuration(
-	IN PRTMP_ADAPTER	pAd)
-{
-	UINT8 byteValue = 0;
-	ULONG result;
-
-	BBP_IO_READ8_BY_REG_ID(pAd, BBP_R115, &byteValue);
-
-	result = 0;
-	switch (byteValue)
-	{
-	case 1: // radar signal detected by pulse mode.
-	case 2: // radar signal detected by width mode.
-		result = RTMPReadRadarDuration(pAd);
-		break;
-
-	case 0: // No radar signal.
-	default:
-
-		result = 0;
-		break;
-	}
-
-	return result;
-}
-
-ULONG RTMPReadRadarDuration(
-	IN PRTMP_ADAPTER	pAd)
-{
-	ULONG result = 0;
-
-#ifdef DFS_SUPPORT
-	UINT8 duration1 = 0, duration2 = 0, duration3 = 0;
-
-
-	BBP_IO_READ8_BY_REG_ID(pAd, BBP_R116, &duration1);
-	BBP_IO_READ8_BY_REG_ID(pAd, BBP_R117, &duration2);
-	BBP_IO_READ8_BY_REG_ID(pAd, BBP_R118, &duration3);
-	result = (duration1 << 16) + (duration2 << 8) + duration3;
-#endif // DFS_SUPPORT //
-
-	return result;
-
-}
-
-VOID RTMPCleanRadarDuration(
-	IN PRTMP_ADAPTER	pAd)
-{
-	return;
-}
-
-/*
-    ========================================================================
-    Routine Description:
-        Radar wave detection. The API should be invoke each second.
-
-    Arguments:
-        pAd         - Adapter pointer
-
-    Return Value:
-        None
-
-    ========================================================================
-*/
-VOID ApRadarDetectPeriodic(
-	IN PRTMP_ADAPTER pAd)
-{
-	INT	i;
-
-	pAd->CommonCfg.RadarDetect.InServiceMonitorCount++;
-
-	for (i=0; i<pAd->ChannelListNum; i++)
-	{
-
-		if (pAd->ChannelList[i].RemainingTimeForUse > 0)
-		{
-			pAd->ChannelList[i].RemainingTimeForUse --;
-			if ((pAd->Mlme.PeriodicRound%5) == 0)
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("RadarDetectPeriodic - ch=%d, RemainingTimeForUse=%d\n", pAd->ChannelList[i].Channel, pAd->ChannelList[i].RemainingTimeForUse));
-			}
-		}
-	}
-
-	//radar detect
-	if ((pAd->CommonCfg.Channel > 14)
-		&& (pAd->CommonCfg.bIEEE80211H == 1)
-		&& RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
-	{
-		RadarDetectPeriodic(pAd);
-	}
-
-	return;
-}
-
-// Periodic Radar detection, switch channel will occur in RTMPHandleTBTTInterrupt()
-// Before switch channel, driver needs doing channel switch announcement.
-VOID RadarDetectPeriodic(
-	IN PRTMP_ADAPTER	pAd)
-{
-
-	// need to check channel availability, after switch channel
-	if (pAd->CommonCfg.RadarDetect.RDMode != RD_SILENCE_MODE)
-			return;
-
-
-
-	// channel availability check time is 60sec, use 65 for assurance
-	if (pAd->CommonCfg.RadarDetect.RDCount++ > pAd->CommonCfg.RadarDetect.ChMovingTime)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("Not found radar signal, start send beacon and radar detection in service monitor\n\n"));
-		BbpRadarDetectionStop(pAd);
-
-
-		AsicEnableBssSync(pAd);
-		pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
-
-
-
-		return;
-	}
-
-	return;
-}
-#endif // DFS_SUPPORT //
-
-#ifdef DFS_SUPPORT
-/*
-    ==========================================================================
-    Description:
-		change channel moving time for DFS testing.
-
-	Arguments:
-	    pAdapter                    Pointer to our adapter
-	    wrq                         Pointer to the ioctl argument
-
-    Return Value:
-        None
-
-    Note:
-        Usage:
-               1.) iwpriv ra0 set ChMovTime=[value]
-    ==========================================================================
-*/
-INT Set_ChMovingTime_Proc(
-	IN PRTMP_ADAPTER pAd,
-	IN PSTRING arg)
-{
-	UINT8 Value;
-
-	Value = (UINT8) simple_strtol(arg, 0, 10);
-
-	pAd->CommonCfg.RadarDetect.ChMovingTime = Value;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __FUNCTION__,
-		pAd->CommonCfg.RadarDetect.ChMovingTime));
-
-	return TRUE;
-}
-
-INT Set_LongPulseRadarTh_Proc(
-	IN PRTMP_ADAPTER pAd,
-	IN PSTRING arg)
-{
-	UINT8 Value;
-
-	Value = (UINT8) simple_strtol(arg, 0, 10) > 10 ? 10 : simple_strtol(arg, 0, 10);
-
-	pAd->CommonCfg.RadarDetect.LongPulseRadarTh = Value;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __FUNCTION__,
-		pAd->CommonCfg.RadarDetect.LongPulseRadarTh));
-
-	return TRUE;
-}
-#endif // DFS_SUPPORT //
diff --git a/drivers/staging/rt3090/common/ee_efuse.c b/drivers/staging/rt3090/common/ee_efuse.c
deleted file mode 100644
index c51e305..0000000
--- a/drivers/staging/rt3090/common/ee_efuse.c
+++ /dev/null
@@ -1,1548 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	ee_efuse.c
-
-	Abstract:
-	Miniport generic portion header file
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-*/
-
-#include "../rt_config.h"
-
-
-#define EFUSE_USAGE_MAP_START	0x2d0
-#define EFUSE_USAGE_MAP_END		0x2fc
-#define EFUSE_USAGE_MAP_SIZE	45
-
-
-
-#define EFUSE_EEPROM_DEFULT_FILE	"RT30xxEEPROM.bin"
-#define MAX_EEPROM_BIN_FILE_SIZE	1024
-
-
-
-#define EFUSE_TAG				0x2fe
-
-
-#ifdef RT_BIG_ENDIAN
-typedef	union	_EFUSE_CTRL_STRUC {
-	struct	{
-		UINT32            SEL_EFUSE:1;
-		UINT32            EFSROM_KICK:1;
-		UINT32            RESERVED:4;
-		UINT32            EFSROM_AIN:10;
-		UINT32            EFSROM_LDO_ON_TIME:2;
-		UINT32            EFSROM_LDO_OFF_TIME:6;
-		UINT32            EFSROM_MODE:2;
-		UINT32            EFSROM_AOUT:6;
-	}	field;
-	UINT32			word;
-}	EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC;
-#else
-typedef	union	_EFUSE_CTRL_STRUC {
-	struct	{
-		UINT32            EFSROM_AOUT:6;
-		UINT32            EFSROM_MODE:2;
-		UINT32            EFSROM_LDO_OFF_TIME:6;
-		UINT32            EFSROM_LDO_ON_TIME:2;
-		UINT32            EFSROM_AIN:10;
-		UINT32            RESERVED:4;
-		UINT32            EFSROM_KICK:1;
-		UINT32            SEL_EFUSE:1;
-	}	field;
-	UINT32			word;
-}	EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC;
-#endif // RT_BIG_ENDIAN //
-
-static UCHAR eFuseReadRegisters(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	OUT	USHORT* pData);
-
-static VOID eFuseReadPhysical(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUSHORT lpInBuffer,
-	IN	ULONG nInBufferSize,
-	OUT	PUSHORT lpOutBuffer,
-	IN	ULONG nOutBufferSize);
-
-static VOID eFusePhysicalWriteRegisters(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	OUT	USHORT* pData);
-
-static NTSTATUS eFuseWriteRegisters(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	IN	USHORT* pData);
-
-static VOID eFuseWritePhysical(
-	IN	PRTMP_ADAPTER	pAd,
-	PUSHORT lpInBuffer,
-	ULONG nInBufferSize,
-	PUCHAR lpOutBuffer,
-	ULONG nOutBufferSize);
-
-
-static NTSTATUS eFuseWriteRegistersFromBin(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	IN	USHORT* pData);
-
-
-/*
-========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-========================================================================
-*/
-UCHAR eFuseReadRegisters(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	OUT	USHORT* pData)
-{
-	EFUSE_CTRL_STRUC		eFuseCtrlStruc;
-	int	i;
-	USHORT	efuseDataOffset;
-	UINT32	data;
-
-	RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
-
-	//Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
-	//Use the eeprom logical address and covert to address to block number
-	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
-
-	//Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 0.
-	eFuseCtrlStruc.field.EFSROM_MODE = 0;
-
-	//Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
-	eFuseCtrlStruc.field.EFSROM_KICK = 1;
-
-	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
-	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
-
-	//Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
-	i = 0;
-	while(i < 500)
-	{
-		//rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4);
-		RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
-		if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
-		{
-			break;
-		}
-		RTMPusecDelay(2);
-		i++;
-	}
-
-	//if EFSROM_AOUT is not found in physical address, write 0xffff
-	if (eFuseCtrlStruc.field.EFSROM_AOUT == 0x3f)
-	{
-		for(i=0; i<Length/2; i++)
-			*(pData+2*i) = 0xffff;
-	}
-	else
-	{
-		//Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x590-0x59C)
-		efuseDataOffset =  EFUSE_DATA3 - (Offset & 0xC);
-		//data hold 4 bytes data.
-		//In RTMP_IO_READ32 will automatically execute 32-bytes swapping
-		RTMP_IO_READ32(pAd, efuseDataOffset, &data);
-		//Decide the upper 2 bytes or the bottom 2 bytes.
-		// Little-endian		S	|	S	Big-endian
-		// addr	3	2	1	0	|	0	1	2	3
-		// Ori-V	D	C	B	A	|	A	B	C	D
-		//After swapping
-		//		D	C	B	A	|	D	C	B	A
-		//Return 2-bytes
-		//The return byte statrs from S. Therefore, the little-endian will return BA, the Big-endian will return DC.
-		//For returning the bottom 2 bytes, the Big-endian should shift right 2-bytes.
-#ifdef RT_BIG_ENDIAN
-		data = data << (8*((Offset & 0x3)^0x2));
-#else
-		data = data >> (8*(Offset & 0x3));
-#endif // RT_BIG_ENDIAN //
-
-		NdisMoveMemory(pData, &data, Length);
-	}
-
-	return (UCHAR) eFuseCtrlStruc.field.EFSROM_AOUT;
-
-}
-
-/*
-========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-========================================================================
-*/
-VOID eFusePhysicalReadRegisters(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	OUT	USHORT* pData)
-{
-	EFUSE_CTRL_STRUC		eFuseCtrlStruc;
-	int	i;
-	USHORT	efuseDataOffset;
-	UINT32	data;
-
-	RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
-
-	//Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
-	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
-
-	//Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
-	//Read in physical view
-	eFuseCtrlStruc.field.EFSROM_MODE = 1;
-
-	//Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
-	eFuseCtrlStruc.field.EFSROM_KICK = 1;
-
-	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
-	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
-
-	//Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
-	i = 0;
-	while(i < 500)
-	{
-		RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
-		if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
-			break;
-		RTMPusecDelay(2);
-		i++;
-	}
-
-	//Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
-	//Because the size of each EFUSE_DATA is 4 Bytes, the size of address of each is 2 bits.
-	//The previous 2 bits is the EFUSE_DATA number, the last 2 bits is used to decide which bytes
-	//Decide which EFUSE_DATA to read
-	//590:F E D C
-	//594:B A 9 8
-	//598:7 6 5 4
-	//59C:3 2 1 0
-	efuseDataOffset =  EFUSE_DATA3 - (Offset & 0xC)  ;
-
-	RTMP_IO_READ32(pAd, efuseDataOffset, &data);
-
-#ifdef RT_BIG_ENDIAN
-		data = data << (8*((Offset & 0x3)^0x2));
-#else
-	data = data >> (8*(Offset & 0x3));
-#endif // RT_BIG_ENDIAN //
-
-	NdisMoveMemory(pData, &data, Length);
-
-}
-
-/*
-========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-========================================================================
-*/
-static VOID eFuseReadPhysical(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUSHORT lpInBuffer,
-	IN	ULONG nInBufferSize,
-	OUT	PUSHORT lpOutBuffer,
-	IN	ULONG nOutBufferSize
-)
-{
-	USHORT* pInBuf = (USHORT*)lpInBuffer;
-	USHORT* pOutBuf = (USHORT*)lpOutBuffer;
-
-	USHORT Offset = pInBuf[0];					//addr
-	USHORT Length = pInBuf[1];					//length
-	int		i;
-
-	for(i=0; i<Length; i+=2)
-	{
-		eFusePhysicalReadRegisters(pAd,Offset+i, 2, &pOutBuf[i/2]);
-	}
-}
-
-/*
-========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-========================================================================
-*/
-NTSTATUS eFuseRead(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	OUT	PUCHAR			pData,
-	IN	USHORT			Length)
-{
-	USHORT* pOutBuf = (USHORT*)pData;
-	NTSTATUS Status = STATUS_SUCCESS;
-	UCHAR	EFSROM_AOUT;
-	int	i;
-
-	for(i=0; i<Length; i+=2)
-	{
-		EFSROM_AOUT = eFuseReadRegisters(pAd, Offset+i, 2, &pOutBuf[i/2]);
-	}
-	return Status;
-}
-
-/*
-========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-========================================================================
-*/
-static VOID eFusePhysicalWriteRegisters(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	OUT	USHORT* pData)
-{
-	EFUSE_CTRL_STRUC		eFuseCtrlStruc;
-	int	i;
-	USHORT	efuseDataOffset;
-	UINT32	data, eFuseDataBuffer[4];
-
-	//Step0. Write 16-byte of data to EFUSE_DATA0-3 (0x590-0x59C), where EFUSE_DATA0 is the LSB DW, EFUSE_DATA3 is the MSB DW.
-
-	/////////////////////////////////////////////////////////////////
-	//read current values of 16-byte block
-	RTMP_IO_READ32(pAd, EFUSE_CTRL,  &eFuseCtrlStruc.word);
-
-	//Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
-	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
-
-	//Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
-	eFuseCtrlStruc.field.EFSROM_MODE = 1;
-
-	//Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
-	eFuseCtrlStruc.field.EFSROM_KICK = 1;
-
-	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
-	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
-
-	//Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
-	i = 0;
-	while(i < 500)
-	{
-		RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
-
-		if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
-			break;
-		RTMPusecDelay(2);
-		i++;
-	}
-
-	//Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
-	efuseDataOffset =  EFUSE_DATA3;
-	for(i=0; i< 4; i++)
-	{
-		RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &eFuseDataBuffer[i]);
-		efuseDataOffset -=  4;
-	}
-
-	//Update the value, the offset is multiple of 2, length is 2
-	efuseDataOffset = (Offset & 0xc) >> 2;
-	data = pData[0] & 0xffff;
-	//The offset should be 0x***10 or 0x***00
-	if((Offset % 4) != 0)
-	{
-		eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff) | (data << 16);
-	}
-	else
-	{
-		eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff0000) | data;
-	}
-
-	efuseDataOffset =  EFUSE_DATA3;
-	for(i=0; i< 4; i++)
-	{
-		RTMP_IO_WRITE32(pAd, efuseDataOffset, eFuseDataBuffer[i]);
-		efuseDataOffset -= 4;
-	}
-	/////////////////////////////////////////////////////////////////
-
-	//Step1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
-
-	RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
-
-	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
-
-	//Step2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
-	eFuseCtrlStruc.field.EFSROM_MODE = 3;
-
-	//Step3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
-	eFuseCtrlStruc.field.EFSROM_KICK = 1;
-
-	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
-	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
-
-	//Step4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It��s done.
-	i = 0;
-
-	while(i < 500)
-	{
-		RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
-
-		if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
-			break;
-
-		RTMPusecDelay(2);
-		i++;
-	}
-}
-
-/*
-========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-========================================================================
-*/
-static NTSTATUS eFuseWriteRegisters(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	IN	USHORT* pData)
-{
-	USHORT	i,Loop=0;
-	USHORT	eFuseData;
-	USHORT	LogicalAddress, BlkNum = 0xffff;
-	UCHAR	EFSROM_AOUT;
-
-	USHORT addr,tmpaddr, InBuf[3], tmpOffset;
-	USHORT buffer[8];
-	BOOLEAN		bWriteSuccess = TRUE;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters Offset=%x, pData=%x\n", Offset, *pData));
-
-	//Step 0. find the entry in the mapping table
-	//The address of EEPROM is 2-bytes alignment.
-	//The last bit is used for alignment, so it must be 0.
-	tmpOffset = Offset & 0xfffe;
-	EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
-
-	if( EFSROM_AOUT == 0x3f)
-	{	//find available logical address pointer
-		//the logical address does not exist, find an empty one
-		//from the first address of block 45=16*45=0x2d0 to the last address of block 47
-		//==>48*16-3(reserved)=2FC
-		for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
-		{
-			//Retrive the logical block nubmer form each logical address pointer
-			//It will access two logical address pointer each time.
-			eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
-			if( (LogicalAddress & 0xff) == 0)
-			{//Not used logical address pointer
-				BlkNum = i-EFUSE_USAGE_MAP_START;
-				break;
-			}
-			else if(( (LogicalAddress >> 8) & 0xff) == 0)
-			{//Not used logical address pointer
-				if (i != EFUSE_USAGE_MAP_END)
-				{
-					BlkNum = i-EFUSE_USAGE_MAP_START+1;
-				}
-				break;
-			}
-		}
-	}
-	else
-	{
-		BlkNum = EFSROM_AOUT;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
-
-	if(BlkNum == 0xffff)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
-		return FALSE;
-	}
-
-	//Step 1. Save data of this block	which is pointed by the avaible logical address pointer
-	// read and save the original block data
-	for(i =0; i<8; i++)
-	{
-		addr = BlkNum * 0x10 ;
-
-		InBuf[0] = addr+2*i;
-		InBuf[1] = 2;
-		InBuf[2] = 0x0;
-
-		eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
-
-		buffer[i] = InBuf[2];
-	}
-
-	//Step 2. Update the data in buffer, and write the data to Efuse
-	buffer[ (Offset >> 1) % 8] = pData[0];
-
-	do
-	{	Loop++;
-		//Step 3. Write the data to Efuse
-		if(!bWriteSuccess)
-		{
-			for(i =0; i<8; i++)
-			{
-				addr = BlkNum * 0x10 ;
-
-				InBuf[0] = addr+2*i;
-				InBuf[1] = 2;
-				InBuf[2] = buffer[i];
-
-				eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
-			}
-		}
-		else
-		{
-				addr = BlkNum * 0x10 ;
-
-				InBuf[0] = addr+(Offset % 16);
-				InBuf[1] = 2;
-				InBuf[2] = pData[0];
-
-				eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
-		}
-
-		//Step 4. Write mapping table
-		addr = EFUSE_USAGE_MAP_START+BlkNum;
-
-		tmpaddr = addr;
-
-		if(addr % 2 != 0)
-			addr = addr -1;
-		InBuf[0] = addr;
-		InBuf[1] = 2;
-
-		//convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
-		tmpOffset = Offset;
-		tmpOffset >>= 4;
-		tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^  (tmpOffset >> 2 & 0x01) ^  (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
-		tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
-
-		// write the logical address
-		if(tmpaddr%2 != 0)
-			InBuf[2] = tmpOffset<<8;
-		else
-			InBuf[2] = tmpOffset;
-
-		eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
-
-		//Step 5. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
-		bWriteSuccess = TRUE;
-		for(i =0; i<8; i++)
-		{
-			addr = BlkNum * 0x10 ;
-
-			InBuf[0] = addr+2*i;
-			InBuf[1] = 2;
-			InBuf[2] = 0x0;
-
-			eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
-
-			if(buffer[i] != InBuf[2])
-			{
-				bWriteSuccess = FALSE;
-				break;
-			}
-		}
-
-		//Step 6. invlidate mapping entry and find a free mapping entry if not succeed
-		if (!bWriteSuccess)
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess BlkNum = %d\n", BlkNum));
-
-			// the offset of current mapping entry
-			addr = EFUSE_USAGE_MAP_START+BlkNum;
-
-			//find a new mapping entry
-			BlkNum = 0xffff;
-			for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
-			{
-				eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
-				if( (LogicalAddress & 0xff) == 0)
-				{
-					BlkNum = i-EFUSE_USAGE_MAP_START;
-					break;
-				}
-				else if(( (LogicalAddress >> 8) & 0xff) == 0)
-				{
-					if (i != EFUSE_USAGE_MAP_END)
-					{
-						BlkNum = i+1-EFUSE_USAGE_MAP_START;
-					}
-					break;
-				}
-			}
-			DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess new BlkNum = %d\n", BlkNum));
-			if(BlkNum == 0xffff)
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
-				return FALSE;
-			}
-
-			//invalidate the original mapping entry if new entry is not found
-			tmpaddr = addr;
-
-			if(addr % 2 != 0)
-				addr = addr -1;
-			InBuf[0] = addr;
-			InBuf[1] = 2;
-
-			eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
-
-			// write the logical address
-			if(tmpaddr%2 != 0)
-			{
-				// Invalidate the high byte
-				for (i=8; i<15; i++)
-				{
-					if( ( (InBuf[2] >> i) & 0x01) == 0)
-					{
-						InBuf[2] |= (0x1 <<i);
-						break;
-					}
-				}
-			}
-			else
-			{
-				// invalidate the low byte
-				for (i=0; i<8; i++)
-				{
-					if( ( (InBuf[2] >> i) & 0x01) == 0)
-					{
-						InBuf[2] |= (0x1 <<i);
-						break;
-					}
-				}
-			}
-			eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
-		}
-	}
-	while (!bWriteSuccess&&Loop<2);
-	if(!bWriteSuccess)
-		DBGPRINT(RT_DEBUG_ERROR,("Efsue Write Failed!!\n"));
-	return TRUE;
-}
-
-
-/*
-========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-========================================================================
-*/
-static VOID eFuseWritePhysical(
-	IN	PRTMP_ADAPTER	pAd,
-	PUSHORT lpInBuffer,
-	ULONG nInBufferSize,
-	PUCHAR lpOutBuffer,
-	ULONG nOutBufferSize
-)
-{
-	USHORT* pInBuf = (USHORT*)lpInBuffer;
-	int		i;
-	//USHORT* pOutBuf = (USHORT*)ioBuffer;
-	USHORT Offset = pInBuf[0];					// addr
-	USHORT Length = pInBuf[1];					// length
-	USHORT* pValueX = &pInBuf[2];				// value ...
-
-	DBGPRINT(RT_DEBUG_TRACE, ("eFuseWritePhysical Offset=0x%x, length=%d\n", Offset, Length));
-
-	{
-		// Little-endian		S	|	S	Big-endian
-		// addr	3	2	1	0	|	0	1	2	3
-		// Ori-V	D	C	B	A	|	A	B	C	D
-		// After swapping
-		//		D	C	B	A	|	D	C	B	A
-		// Both the little and big-endian use the same sequence to write  data.
-		// Therefore, we only need swap data when read the data.
-		for (i=0; i<Length; i+=2)
-		{
-			eFusePhysicalWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
-		}
-	}
-}
-
-
-/*
-========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-========================================================================
-*/
-NTSTATUS eFuseWrite(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	IN	PUCHAR			pData,
-	IN	USHORT			length)
-{
-	int i;
-	USHORT* pValueX = (PUSHORT) pData;				//value ...
-
-	// The input value=3070 will be stored as following
-	// Little-endian		S	|	S	Big-endian
-	// addr			1	0	|	0	1
-	// Ori-V			30	70	|	30	70
-	// After swapping
-	//				30	70	|	70	30
-	// Casting
-	//				3070	|	7030 (x)
-	// The swapping should be removed for big-endian
-	for(i=0; i<length; i+=2)
-	{
-		eFuseWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
-	}
-
-	return TRUE;
-}
-
-
-
-
-/*
-========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-========================================================================
-*/
-INT set_eFuseGetFreeBlockCount_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	USHORT i;
-	USHORT	LogicalAddress;
-	USHORT efusefreenum=0;
-	if(!pAd->bUseEfuse)
-		return FALSE;
-	for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i+=2)
-	{
-		eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
-		if( (LogicalAddress & 0xff) == 0)
-		{
-			efusefreenum= (UCHAR) (EFUSE_USAGE_MAP_END-i+1);
-			break;
-		}
-		else if(( (LogicalAddress >> 8) & 0xff) == 0)
-		{
-			efusefreenum = (UCHAR) (EFUSE_USAGE_MAP_END-i);
-			break;
-		}
-
-		if(i == EFUSE_USAGE_MAP_END)
-			efusefreenum = 0;
-	}
-	printk("efuseFreeNumber is %d\n",efusefreenum);
-	return TRUE;
-}
-
-
-INT set_eFusedump_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-USHORT InBuf[3];
-	INT i=0;
-	if(!pAd->bUseEfuse)
-		return FALSE;
-	for(i =0; i<EFUSE_USAGE_MAP_END/2; i++)
-	{
-		InBuf[0] = 2*i;
-		InBuf[1] = 2;
-		InBuf[2] = 0x0;
-
-		eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
-		if(i%4==0)
-		printk("\nBlock %x:",i/8);
-		printk("%04x ",InBuf[2]);
-	}
-	return TRUE;
-}
-
-
-INT	set_eFuseLoadFromBin_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	PSTRING					src;
-	RTMP_OS_FD				srcf;
-	RTMP_OS_FS_INFO			osfsInfo;
-	INT						retval, memSize;
-	PSTRING					buffer, memPtr;
-	INT						i = 0,j=0,k=1;
-	USHORT					*PDATA;
-	USHORT					DATA;
-
-	memSize = 128 + MAX_EEPROM_BIN_FILE_SIZE + sizeof(USHORT) * 8;
-	memPtr = kmalloc(memSize, MEM_ALLOC_FLAG);
-	if (memPtr == NULL)
-		return FALSE;
-
-	NdisZeroMemory(memPtr, memSize);
-	src = memPtr; // kmalloc(128, MEM_ALLOC_FLAG);
-	buffer = src + 128;		// kmalloc(MAX_EEPROM_BIN_FILE_SIZE, MEM_ALLOC_FLAG);
-	PDATA = (USHORT*)(buffer + MAX_EEPROM_BIN_FILE_SIZE);	// kmalloc(sizeof(USHORT)*8,MEM_ALLOC_FLAG);
-
-	if(strlen(arg)>0)
-		NdisMoveMemory(src, arg, strlen(arg));
-	else
-		NdisMoveMemory(src, EFUSE_EEPROM_DEFULT_FILE, strlen(EFUSE_EEPROM_DEFULT_FILE));
-	DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src));
-
-	RtmpOSFSInfoChange(&osfsInfo, TRUE);
-
-	srcf = RtmpOSFileOpen(src, O_RDONLY, 0);
-	if (IS_FILE_OPEN_ERR(srcf))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("--> Error opening file %s\n", src));
-		retval = FALSE;
-		goto recoverFS;
-	}
-	else
-	{
-		// The object must have a read method
-		while(RtmpOSFileRead(srcf, &buffer[i], 1)==1)
-		{
-		i++;
-			if(i>MAX_EEPROM_BIN_FILE_SIZE)
-			{
-				DBGPRINT(RT_DEBUG_ERROR, ("--> Error reading file %s, file size too large[>%d]\n", src, MAX_EEPROM_BIN_FILE_SIZE));
-				retval = FALSE;
-				goto closeFile;
-			}
-		}
-
-		retval = RtmpOSFileClose(srcf);
-		if (retval)
-			DBGPRINT(RT_DEBUG_TRACE, ("--> Error closing file %s\n", src));
-	}
-
-
-	RtmpOSFSInfoChange(&osfsInfo, FALSE);
-
-	for(j=0;j<i;j++)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[j]&0xff));
-		if((j+1)%2==0)
-			PDATA[j/2%8]=((buffer[j]<<8)&0xff00)|(buffer[j-1]&0xff);
-		if(j%16==0)
-		{
-			k=buffer[j];
-		}
-		else
-		{
-			k&=buffer[j];
-			if((j+1)%16==0)
-			{
-				DBGPRINT(RT_DEBUG_TRACE, (" result=%02X,blk=%02x\n",k,j/16));
-				if(k!=0xff)
-					eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
-				else
-				{
-					if(eFuseReadRegisters(pAd,j, 2,(PUSHORT)&DATA)!=0x3f)
-						eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
-				}
-				/*
-				for(l=0;l<8;l++)
-					printk("%04x ",PDATA[l]);
-				printk("\n");
-				*/
-				NdisZeroMemory(PDATA,16);
-			}
-		}
-	}
-
-	return TRUE;
-
-closeFile:
-	if (srcf)
-		RtmpOSFileClose(srcf);
-
-recoverFS:
-	RtmpOSFSInfoChange(&osfsInfo, FALSE);
-
-
-	if (memPtr)
-		kfree(memPtr);
-
-	return retval;
-}
-
-
-static NTSTATUS eFuseWriteRegistersFromBin(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	IN	USHORT* pData)
-{
-	USHORT	i;
-	USHORT	eFuseData;
-	USHORT	LogicalAddress, BlkNum = 0xffff;
-	UCHAR	EFSROM_AOUT,Loop=0;
-	EFUSE_CTRL_STRUC		eFuseCtrlStruc;
-	USHORT	efuseDataOffset;
-	UINT32	data,tempbuffer;
-	USHORT addr,tmpaddr, InBuf[3], tmpOffset;
-	UINT32 buffer[4];
-	BOOLEAN		bWriteSuccess = TRUE;
-	BOOLEAN		bNotWrite=TRUE;
-	BOOLEAN		bAllocateNewBlk=TRUE;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin Offset=%x, pData=%04x:%04x:%04x:%04x\n", Offset, *pData,*(pData+1),*(pData+2),*(pData+3)));
-
-	do
-	{
-	//Step 0. find the entry in the mapping table
-	//The address of EEPROM is 2-bytes alignment.
-	//The last bit is used for alignment, so it must be 0.
-	Loop++;
-	tmpOffset = Offset & 0xfffe;
-	EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
-
-	if( EFSROM_AOUT == 0x3f)
-	{	//find available logical address pointer
-		//the logical address does not exist, find an empty one
-		//from the first address of block 45=16*45=0x2d0 to the last address of block 47
-		//==>48*16-3(reserved)=2FC
-		bAllocateNewBlk=TRUE;
-		for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
-		{
-			//Retrive the logical block nubmer form each logical address pointer
-			//It will access two logical address pointer each time.
-			eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
-			if( (LogicalAddress & 0xff) == 0)
-			{//Not used logical address pointer
-				BlkNum = i-EFUSE_USAGE_MAP_START;
-				break;
-			}
-			else if(( (LogicalAddress >> 8) & 0xff) == 0)
-			{//Not used logical address pointer
-				if (i != EFUSE_USAGE_MAP_END)
-				{
-					BlkNum = i-EFUSE_USAGE_MAP_START+1;
-				}
-				break;
-			}
-		}
-	}
-	else
-	{
-		bAllocateNewBlk=FALSE;
-		BlkNum = EFSROM_AOUT;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
-
-	if(BlkNum == 0xffff)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
-		return FALSE;
-	}
-	//Step 1.1.0
-	//If the block is not existing in mapping table, create one
-	//and write down the 16-bytes data to the new block
-	if(bAllocateNewBlk)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk\n"));
-		efuseDataOffset =  EFUSE_DATA3;
-		for(i=0; i< 4; i++)
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk, Data%d=%04x%04x\n",3-i,pData[2*i+1],pData[2*i]));
-			tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
-
-
-			RTMP_IO_WRITE32(pAd, efuseDataOffset,tempbuffer);
-			efuseDataOffset -= 4;
-
-		}
-		/////////////////////////////////////////////////////////////////
-
-		//Step1.1.1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
-		RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
-		eFuseCtrlStruc.field.EFSROM_AIN = BlkNum* 0x10 ;
-
-		//Step1.1.2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
-		eFuseCtrlStruc.field.EFSROM_MODE = 3;
-
-		//Step1.1.3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
-		eFuseCtrlStruc.field.EFSROM_KICK = 1;
-
-		NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
-
-		RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
-
-		//Step1.1.4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It��s done.
-		i = 0;
-		while(i < 100)
-		{
-			RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
-
-			if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
-				break;
-
-			RTMPusecDelay(2);
-			i++;
-		}
-
-	}
-	else
-	{	//Step1.2.
-		//If the same logical number is existing, check if the writting data and the data
-		//saving in this block are the same.
-		/////////////////////////////////////////////////////////////////
-		//read current values of 16-byte block
-		RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
-
-		//Step1.2.0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
-		eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
-
-		//Step1.2.1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
-		eFuseCtrlStruc.field.EFSROM_MODE = 0;
-
-		//Step1.2.2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
-		eFuseCtrlStruc.field.EFSROM_KICK = 1;
-
-		NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
-		RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
-
-		//Step1.2.3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
-		i = 0;
-		while(i < 500)
-		{
-			RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
-
-			if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
-				break;
-			RTMPusecDelay(2);
-			i++;
-		}
-
-		//Step1.2.4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
-		efuseDataOffset =  EFUSE_DATA3;
-		for(i=0; i< 4; i++)
-		{
-			RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &buffer[i]);
-			efuseDataOffset -=  4;
-		}
-		//Step1.2.5. Check if the data of efuse and the writing data are the same.
-		for(i =0; i<4; i++)
-		{
-			tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
-			DBGPRINT(RT_DEBUG_TRACE, ("buffer[%d]=%x,pData[%d]=%x,pData[%d]=%x,tempbuffer=%x\n",i,buffer[i],2*i,pData[2*i],2*i+1,pData[2*i+1],tempbuffer));
-
-			if(((buffer[i]&0xffff0000)==(pData[2*i+1]<<16))&&((buffer[i]&0xffff)==pData[2*i]))
-				bNotWrite&=TRUE;
-			else
-			{
-				bNotWrite&=FALSE;
-				break;
-			}
-		}
-		if(!bNotWrite)
-		{
-		printk("The data is not the same\n");
-
-			for(i =0; i<8; i++)
-			{
-				addr = BlkNum * 0x10 ;
-
-				InBuf[0] = addr+2*i;
-				InBuf[1] = 2;
-				InBuf[2] = pData[i];
-
-				eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
-			}
-
-		}
-		else
-			return TRUE;
-	     }
-
-
-
-		//Step 2. Write mapping table
-		addr = EFUSE_USAGE_MAP_START+BlkNum;
-
-		tmpaddr = addr;
-
-		if(addr % 2 != 0)
-			addr = addr -1;
-		InBuf[0] = addr;
-		InBuf[1] = 2;
-
-		//convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
-		tmpOffset = Offset;
-		tmpOffset >>= 4;
-		tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^  (tmpOffset >> 2 & 0x01) ^  (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
-		tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
-
-		// write the logical address
-		if(tmpaddr%2 != 0)
-			InBuf[2] = tmpOffset<<8;
-		else
-			InBuf[2] = tmpOffset;
-
-		eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
-
-		//Step 3. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
-		bWriteSuccess = TRUE;
-		for(i =0; i<8; i++)
-		{
-			addr = BlkNum * 0x10 ;
-
-			InBuf[0] = addr+2*i;
-			InBuf[1] = 2;
-			InBuf[2] = 0x0;
-
-			eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
-			DBGPRINT(RT_DEBUG_TRACE, ("addr=%x, buffer[i]=%x,InBuf[2]=%x\n",InBuf[0],pData[i],InBuf[2]));
-			if(pData[i] != InBuf[2])
-			{
-				bWriteSuccess = FALSE;
-				break;
-			}
-		}
-
-		//Step 4. invlidate mapping entry and find a free mapping entry if not succeed
-
-		if (!bWriteSuccess&&Loop<2)
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess BlkNum = %d\n", BlkNum));
-
-			// the offset of current mapping entry
-			addr = EFUSE_USAGE_MAP_START+BlkNum;
-
-			//find a new mapping entry
-			BlkNum = 0xffff;
-			for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
-			{
-				eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
-				if( (LogicalAddress & 0xff) == 0)
-				{
-					BlkNum = i-EFUSE_USAGE_MAP_START;
-					break;
-				}
-				else if(( (LogicalAddress >> 8) & 0xff) == 0)
-				{
-					if (i != EFUSE_USAGE_MAP_END)
-					{
-						BlkNum = i+1-EFUSE_USAGE_MAP_START;
-					}
-					break;
-				}
-			}
-			DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess new BlkNum = %d\n", BlkNum));
-			if(BlkNum == 0xffff)
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin: out of free E-fuse space!!!\n"));
-				return FALSE;
-			}
-
-			//invalidate the original mapping entry if new entry is not found
-			tmpaddr = addr;
-
-			if(addr % 2 != 0)
-				addr = addr -1;
-			InBuf[0] = addr;
-			InBuf[1] = 2;
-
-			eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
-
-			// write the logical address
-			if(tmpaddr%2 != 0)
-			{
-				// Invalidate the high byte
-				for (i=8; i<15; i++)
-				{
-					if( ( (InBuf[2] >> i) & 0x01) == 0)
-					{
-						InBuf[2] |= (0x1 <<i);
-						break;
-					}
-				}
-			}
-			else
-			{
-				// invalidate the low byte
-				for (i=0; i<8; i++)
-				{
-					if( ( (InBuf[2] >> i) & 0x01) == 0)
-					{
-						InBuf[2] |= (0x1 <<i);
-						break;
-					}
-				}
-			}
-			eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
-		}
-
-	}
-	while(!bWriteSuccess&&Loop<2);
-
-	return TRUE;
-}
-
-
-int rtmp_ee_efuse_read16(
-	IN RTMP_ADAPTER *pAd,
-	IN USHORT Offset,
-	OUT USHORT *pValue)
-{
-	if(pAd->bFroceEEPROMBuffer || pAd->bEEPROMFile)
-	{
-	    DBGPRINT(RT_DEBUG_TRACE,  ("Read from EEPROM Buffer\n"));
-	    NdisMoveMemory(pValue, &(pAd->EEPROMImage[Offset]), 2);
-	}
-	else
-	    eFuseReadRegisters(pAd, Offset, 2, pValue);
-	return (*pValue);
-}
-
-
-int rtmp_ee_efuse_write16(
-	IN RTMP_ADAPTER *pAd,
-	IN USHORT Offset,
-	IN USHORT data)
-{
-    if(pAd->bFroceEEPROMBuffer||pAd->bEEPROMFile)
-    {
-        DBGPRINT(RT_DEBUG_TRACE,  ("Write to EEPROM Buffer\n"));
-        NdisMoveMemory(&(pAd->EEPROMImage[Offset]), &data, 2);
-    }
-    else
-        eFuseWriteRegisters(pAd, Offset, 2, &data);
-	return 0;
-}
-
-
-int RtmpEfuseSupportCheck(
-	IN RTMP_ADAPTER *pAd)
-{
-	USHORT value;
-
-	if (IS_RT30xx(pAd))
-	{
-		eFusePhysicalReadRegisters(pAd, EFUSE_TAG, 2, &value);
-		pAd->EFuseTag = (value & 0xff);
-	}
-	return 0;
-}
-
-INT set_eFuseBufferModeWriteBack_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	UINT Enable;
-
-
-	if(strlen(arg)>0)
-	{
-		Enable= simple_strtol(arg, 0, 16);
-	}
-	else
-		return FALSE;
-	if(Enable==1)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("set_eFuseBufferMode_Proc:: Call WRITEEEPROMBUF"));
-		eFuseWriteEeeppromBuf(pAd);
-	}
-	else
-		return FALSE;
-	return TRUE;
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Load EEPROM from bin file for eFuse mode
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		NDIS_STATUS_SUCCESS         firmware image load ok
-		NDIS_STATUS_FAILURE         image not found
-
-	IRQL = PASSIVE_LEVEL
-
-	========================================================================
-*/
-INT eFuseLoadEEPROM(
-	IN PRTMP_ADAPTER pAd)
-{
-	PSTRING					src = NULL;
-	INT						retval;
-	RTMP_OS_FD				srcf;
-	RTMP_OS_FS_INFO			osFSInfo;
-
-
-	src=EFUSE_BUFFER_PATH;
-	DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src));
-
-
-	RtmpOSFSInfoChange(&osFSInfo, TRUE);
-
-	if (src && *src)
-	{
-		srcf = RtmpOSFileOpen(src, O_RDONLY, 0);
-		if (IS_FILE_OPEN_ERR(srcf))
-		{
-			DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
-			return FALSE;
-		}
-		else
-		{
-
-				memset(pAd->EEPROMImage, 0x00, MAX_EEPROM_BIN_FILE_SIZE);
-
-
-			retval =RtmpOSFileRead(srcf, (PSTRING)pAd->EEPROMImage, MAX_EEPROM_BIN_FILE_SIZE);
-			if (retval > 0)
-							{
-				RTMPSetProfileParameters(pAd, (PSTRING)pAd->EEPROMImage);
-				retval = NDIS_STATUS_SUCCESS;
-			}
-			else
-				DBGPRINT(RT_DEBUG_ERROR, ("Read file \"%s\" failed(errCode=%d)!\n", src, retval));
-
-		}
-
-
-	}
-	else
-		{
-					DBGPRINT(RT_DEBUG_ERROR, ("--> Error src  or srcf is null\n"));
-					return FALSE;
-
-		}
-
-	retval=RtmpOSFileClose(srcf);
-
-	if (retval)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
-	}
-
-
-	RtmpOSFSInfoChange(&osFSInfo, FALSE);
-
-	return TRUE;
-}
-
-INT eFuseWriteEeeppromBuf(
-	IN PRTMP_ADAPTER pAd)
-{
-
-	PSTRING					src = NULL;
-	INT						retval;
-	RTMP_OS_FD				srcf;
-	RTMP_OS_FS_INFO			osFSInfo;
-
-
-	src=EFUSE_BUFFER_PATH;
-	DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src));
-
-	RtmpOSFSInfoChange(&osFSInfo, TRUE);
-
-
-
-	if (src && *src)
-	{
-		srcf = RtmpOSFileOpen(src, O_WRONLY|O_CREAT, 0);
-
-		if (IS_FILE_OPEN_ERR(srcf))
-		{
-			DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
-			return FALSE;
-		}
-		else
-		{
-/*
-			// The object must have a read method
-			if (srcf->f_op && srcf->f_op->write)
-			{
-				// The object must have a read method
-                        srcf->f_op->write(srcf, pAd->EEPROMImage, 1024, &srcf->f_pos);
-
-			}
-			else
-			{
-						DBGPRINT(RT_DEBUG_ERROR, ("--> Error!! System doest not support read function\n"));
-						return FALSE;
-			}
-*/
-
-			RtmpOSFileWrite(srcf, (PSTRING)pAd->EEPROMImage,MAX_EEPROM_BIN_FILE_SIZE);
-
-		}
-
-
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("--> Error src  or srcf is null\n"));
-		return FALSE;
-
-	}
-
-	retval=RtmpOSFileClose(srcf);
-
-	if (retval)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
-	}
-
-	RtmpOSFSInfoChange(&osFSInfo, FALSE);
-	return TRUE;
-}
-
-
-VOID eFuseGetFreeBlockCount(IN PRTMP_ADAPTER pAd,
-	PUINT EfuseFreeBlock)
-{
-	USHORT i;
-	USHORT	LogicalAddress;
-	if(!pAd->bUseEfuse)
-		{
-		DBGPRINT(RT_DEBUG_TRACE,("eFuseGetFreeBlockCount Only supports efuse Mode\n"));
-		return ;
-		}
-	for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i+=2)
-	{
-		eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
-		if( (LogicalAddress & 0xff) == 0)
-		{
-			*EfuseFreeBlock= (UCHAR) (EFUSE_USAGE_MAP_END-i+1);
-			break;
-		}
-		else if(( (LogicalAddress >> 8) & 0xff) == 0)
-		{
-			*EfuseFreeBlock = (UCHAR) (EFUSE_USAGE_MAP_END-i);
-			break;
-		}
-
-		if(i == EFUSE_USAGE_MAP_END)
-			*EfuseFreeBlock = 0;
-	}
-	DBGPRINT(RT_DEBUG_TRACE,("eFuseGetFreeBlockCount is 0x%x\n",*EfuseFreeBlock));
-}
-
-INT eFuse_init(
-	IN PRTMP_ADAPTER pAd)
-{
-	UINT	EfuseFreeBlock=0;
-	DBGPRINT(RT_DEBUG_ERROR, ("NVM is Efuse and its size =%x[%x-%x] \n",EFUSE_USAGE_MAP_SIZE,EFUSE_USAGE_MAP_START,EFUSE_USAGE_MAP_END));
-	eFuseGetFreeBlockCount(pAd, &EfuseFreeBlock);
-	//If the used block of efuse is less than 5. We assume the default value
-	// of this efuse is empty and change to the buffer mode in odrder to
-	//bring up interfaces successfully.
-	if(EfuseFreeBlock > (EFUSE_USAGE_MAP_END-5))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("NVM is Efuse and the information is too less to bring up interface. Force to use EEPROM Buffer Mode\n"));
-		pAd->bFroceEEPROMBuffer = TRUE;
-		eFuseLoadEEPROM(pAd);
-	}
-	else
-		pAd->bFroceEEPROMBuffer = FALSE;
-	DBGPRINT(RT_DEBUG_TRACE, ("NVM is Efuse and force to use EEPROM Buffer Mode=%x\n",pAd->bFroceEEPROMBuffer));
-
-	return 0;
-}
diff --git a/drivers/staging/rt3090/common/ee_prom.c b/drivers/staging/rt3090/common/ee_prom.c
deleted file mode 100644
index 051cfde..0000000
--- a/drivers/staging/rt3090/common/ee_prom.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	ee_prom.c
-
-	Abstract:
-	Miniport generic portion header file
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-*/
-
-#include "../rt_config.h"
-
-
-// IRQL = PASSIVE_LEVEL
-static inline VOID RaiseClock(
-    IN	PRTMP_ADAPTER	pAd,
-    IN  UINT32 *x)
-{
-	*x = *x | EESK;
-	RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
-	RTMPusecDelay(1);				// Max frequency = 1MHz in Spec. definition
-}
-
-// IRQL = PASSIVE_LEVEL
-static inline VOID LowerClock(
-    IN	PRTMP_ADAPTER	pAd,
-    IN  UINT32 *x)
-{
-	*x = *x & ~EESK;
-	RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
-	RTMPusecDelay(1);
-}
-
-// IRQL = PASSIVE_LEVEL
-static inline USHORT ShiftInBits(
-	IN PRTMP_ADAPTER	pAd)
-{
-	UINT32		x,i;
-	USHORT      data=0;
-
-	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-
-	x &= ~( EEDO | EEDI);
-
-	for(i=0; i<16; i++)
-	{
-		data = data << 1;
-		RaiseClock(pAd, &x);
-
-		RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-		LowerClock(pAd, &x); //prevent read failed
-
-		x &= ~(EEDI);
-		if(x & EEDO)
-		    data |= 1;
-	}
-
-	return data;
-}
-
-
-// IRQL = PASSIVE_LEVEL
-static inline VOID ShiftOutBits(
-	IN PRTMP_ADAPTER	pAd,
-	IN USHORT			data,
-	IN USHORT			count)
-{
-	UINT32       x,mask;
-
-	mask = 0x01 << (count - 1);
-	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-
-	x &= ~(EEDO | EEDI);
-
-	do
-	{
-	    x &= ~EEDI;
-	    if(data & mask)		x |= EEDI;
-
-	    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-	    RaiseClock(pAd, &x);
-	    LowerClock(pAd, &x);
-
-	    mask = mask >> 1;
-	} while(mask);
-
-	x &= ~EEDI;
-	RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-}
-
-
-// IRQL = PASSIVE_LEVEL
-static inline VOID EEpromCleanup(
-	IN PRTMP_ADAPTER	pAd)
-{
-	UINT32 x;
-
-	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-
-	x &= ~(EECS | EEDI);
-	RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-	RaiseClock(pAd, &x);
-	LowerClock(pAd, &x);
-}
-
-
-static inline VOID EWEN(
-	IN PRTMP_ADAPTER	pAd)
-{
-	UINT32	x;
-
-	// reset bits and set EECS
-	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-	x &= ~(EEDI | EEDO | EESK);
-	x |= EECS;
-	RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-	// kick a pulse
-	RaiseClock(pAd, &x);
-	LowerClock(pAd, &x);
-
-	// output the read_opcode and six pulse in that order
-	ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5);
-	ShiftOutBits(pAd, 0, 6);
-
-	EEpromCleanup(pAd);
-}
-
-
-static inline VOID EWDS(
-	IN PRTMP_ADAPTER	pAd)
-{
-	UINT32	x;
-
-	// reset bits and set EECS
-	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-	x &= ~(EEDI | EEDO | EESK);
-	x |= EECS;
-	RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-	// kick a pulse
-	RaiseClock(pAd, &x);
-	LowerClock(pAd, &x);
-
-	// output the read_opcode and six pulse in that order
-	ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5);
-	ShiftOutBits(pAd, 0, 6);
-
-	EEpromCleanup(pAd);
-}
-
-
-// IRQL = PASSIVE_LEVEL
-int rtmp_ee_prom_read16(
-	IN PRTMP_ADAPTER	pAd,
-	IN USHORT			Offset,
-	OUT USHORT			*pValue)
-{
-	UINT32		x;
-	USHORT		data;
-
-#ifdef RT30xx
-#ifdef ANT_DIVERSITY_SUPPORT
-	if (pAd->NicConfig2.field.AntDiversity)
-	{
-		pAd->EepromAccess = TRUE;
-	}
-#endif // ANT_DIVERSITY_SUPPORT //
-#endif // RT30xx //
-
-	Offset /= 2;
-	// reset bits and set EECS
-	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-	x &= ~(EEDI | EEDO | EESK);
-	x |= EECS;
-	RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-	// patch can not access e-Fuse issue
-	if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)))
-	{
-		// kick a pulse
-		RaiseClock(pAd, &x);
-		LowerClock(pAd, &x);
-	}
-
-	// output the read_opcode and register number in that order
-	ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3);
-	ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
-
-	// Now read the data (16 bits) in from the selected EEPROM word
-	data = ShiftInBits(pAd);
-
-	EEpromCleanup(pAd);
-
-#ifdef RT30xx
-#ifdef ANT_DIVERSITY_SUPPORT
-	// Antenna and EEPROM access are both using EESK pin,
-	// Therefor we should avoid accessing EESK at the same time
-	// Then restore antenna after EEPROM access
-	if ((pAd->NicConfig2.field.AntDiversity)/* || (pAd->RfIcType == RFIC_3020)*/)
-	{
-		pAd->EepromAccess = FALSE;
-		AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
-	}
-#endif // ANT_DIVERSITY_SUPPORT //
-#endif // RT30xx //
-
-	*pValue = data;
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-int rtmp_ee_prom_write16(
-    IN  PRTMP_ADAPTER	pAd,
-    IN  USHORT Offset,
-    IN  USHORT Data)
-{
-	UINT32 x;
-
-#ifdef RT30xx
-#ifdef ANT_DIVERSITY_SUPPORT
-	if (pAd->NicConfig2.field.AntDiversity)
-	{
-		pAd->EepromAccess = TRUE;
-	}
-#endif // ANT_DIVERSITY_SUPPORT //
-#endif // RT30xx //
-
-	Offset /= 2;
-
-	EWEN(pAd);
-
-	// reset bits and set EECS
-	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-	x &= ~(EEDI | EEDO | EESK);
-	x |= EECS;
-	RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-	// patch can not access e-Fuse issue
-	if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)))
-	{
-		// kick a pulse
-		RaiseClock(pAd, &x);
-		LowerClock(pAd, &x);
-	}
-
-	// output the read_opcode ,register number and data in that order
-	ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3);
-	ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
-	ShiftOutBits(pAd, Data, 16);		// 16-bit access
-
-	// read DO status
-	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-
-	EEpromCleanup(pAd);
-
-	RTMPusecDelay(10000);	//delay for twp(MAX)=10ms
-
-	EWDS(pAd);
-
-	EEpromCleanup(pAd);
-
-#ifdef RT30xx
-#ifdef ANT_DIVERSITY_SUPPORT
-	// Antenna and EEPROM access are both using EESK pin,
-	// Therefor we should avoid accessing EESK at the same time
-	// Then restore antenna after EEPROM access
-	if ((pAd->NicConfig2.field.AntDiversity) /*|| (pAd->RfIcType == RFIC_3020)*/)
-	{
-		pAd->EepromAccess = FALSE;
-		AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
-	}
-#endif // ANT_DIVERSITY_SUPPORT //
-#endif // RT30xx //
-
-	return NDIS_STATUS_SUCCESS;
-
-}
diff --git a/drivers/staging/rt3090/common/eeprom.c b/drivers/staging/rt3090/common/eeprom.c
deleted file mode 100644
index 2e83749..0000000
--- a/drivers/staging/rt3090/common/eeprom.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	eeprom.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Name		Date			Modification logs
-*/
-
-#include "../rt_config.h"
-
-
-INT RtmpChipOpsEepromHook(
-	IN RTMP_ADAPTER *pAd,
-	IN INT			infType)
-{
-	RTMP_CHIP_OP	*pChipOps = &pAd->chipOps;
-#ifdef RT30xx
-#ifdef RTMP_EFUSE_SUPPORT
-	UINT32			eFuseCtrl, MacCsr0;
-	int index;
-
-	index = 0;
-	do
-	{
-		RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
-		pAd->MACVersion = MacCsr0;
-
-		if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF))
-			break;
-
-		RTMPusecDelay(10);
-	} while (index++ < 100);
-
-	pAd->bUseEfuse=FALSE;
-	RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrl);
-	pAd->bUseEfuse = ( (eFuseCtrl & 0x80000000) == 0x80000000) ? 1 : 0;
-	if(pAd->bUseEfuse)
-	{
-		pChipOps->eeinit = eFuse_init;
-		pChipOps->eeread = rtmp_ee_efuse_read16;
-		pChipOps->eewrite = rtmp_ee_efuse_write16;
-		return 0 ;
-	}
-	else
-	{
-		pAd->bFroceEEPROMBuffer = FALSE;
-		DBGPRINT(RT_DEBUG_TRACE, ("NVM is EEPROM\n"));
-	}
-#endif // RTMP_EFUSE_SUPPORT //
-#endif // RT30xx //
-
-	switch(infType)
-	{
-#ifdef RTMP_PCI_SUPPORT
-		case RTMP_DEV_INF_PCI:
-			pChipOps->eeinit = NULL;
-			pChipOps->eeread = rtmp_ee_prom_read16;
-			pChipOps->eewrite = rtmp_ee_prom_write16;
-			break;
-#endif // RTMP_PCI_SUPPORT //
-
-
-		default:
-			DBGPRINT(RT_DEBUG_ERROR, ("RtmpChipOpsEepromHook() failed!\n"));
-			break;
-	}
-
-	return 0;
-}
diff --git a/drivers/staging/rt3090/common/igmp_snoop.c b/drivers/staging/rt3090/common/igmp_snoop.c
deleted file mode 100644
index 680658f..0000000
--- a/drivers/staging/rt3090/common/igmp_snoop.c
+++ /dev/null
@@ -1,1365 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
- */
-
-
-#ifdef IGMP_SNOOP_SUPPORT
-
-#include "../rt_config.h"
-#include "../ipv6.h"
-#include "../igmp_snoop.h"
-
-
-static inline void initFreeEntryList(
-	IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
-	IN PLIST_HEADER pList)
-{
-	int i;
-
-	for (i = 0; i < FREE_MEMBER_POOL_SIZE; i++)
-		insertTailList(pList, (PLIST_ENTRY)&(pMulticastFilterTable->freeMemberPool[i]));
-
-	return;
-}
-
-static inline PMEMBER_ENTRY AllocaGrpMemberEntry(
-	IN PMULTICAST_FILTER_TABLE pMulticastFilterTable)
-{
-	PMEMBER_ENTRY pMemberEntry;
-
-	RTMP_SEM_LOCK(&pMulticastFilterTable->FreeMemberPoolTabLock);
-
-	pMemberEntry = (PMEMBER_ENTRY)removeHeadList(&pMulticastFilterTable->freeEntryList);
-
-	RTMP_SEM_UNLOCK(&pMulticastFilterTable->FreeMemberPoolTabLock);
-
-	return (PMEMBER_ENTRY)pMemberEntry;
-}
-
-static inline VOID FreeGrpMemberEntry(
-	IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
-	IN PMEMBER_ENTRY pEntry)
-{
-	RTMP_SEM_LOCK(&pMulticastFilterTable->FreeMemberPoolTabLock);
-
-	insertTailList(&pMulticastFilterTable->freeEntryList, (PLIST_ENTRY)pEntry);
-
-	RTMP_SEM_UNLOCK(&pMulticastFilterTable->FreeMemberPoolTabLock);
-}
-
-static VOID IGMPTableDisplay(
-	IN PRTMP_ADAPTER pAd);
-
-static BOOLEAN isIgmpMacAddr(
-	IN PUCHAR pMacAddr);
-
-static VOID InsertIgmpMember(
-	IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
-	IN PLIST_HEADER pList,
-	IN PUCHAR pMemberAddr);
-
-static VOID DeleteIgmpMember(
-	IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
-	IN PLIST_HEADER pList,
-	IN PUCHAR pMemberAddr);
-
-static VOID DeleteIgmpMemberList(
-	IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
-	IN PLIST_HEADER pList);
-
-
-/*
-    ==========================================================================
-    Description:
-        This routine init the entire IGMP table.
-    ==========================================================================
- */
-VOID MulticastFilterTableInit(
-	IN PMULTICAST_FILTER_TABLE *ppMulticastFilterTable)
-{
-	// Initialize MAC table and allocate spin lock
-	*ppMulticastFilterTable = kmalloc(sizeof(MULTICAST_FILTER_TABLE), MEM_ALLOC_FLAG);
-	if (*ppMulticastFilterTable == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for Multicase filter table, size=%d\n",
-			__FUNCTION__, sizeof(MULTICAST_FILTER_TABLE)));
-		return;
-	}
-
-	NdisZeroMemory(*ppMulticastFilterTable, sizeof(MULTICAST_FILTER_TABLE));
-	NdisAllocateSpinLock(&((*ppMulticastFilterTable)->MulticastFilterTabLock));
-
-	NdisAllocateSpinLock(&((*ppMulticastFilterTable)->FreeMemberPoolTabLock));
-	initList(&((*ppMulticastFilterTable)->freeEntryList));
-	initFreeEntryList(*ppMulticastFilterTable, &((*ppMulticastFilterTable)->freeEntryList));
-	return;
-}
-
-/*
-    ==========================================================================
-    Description:
-        This routine reset the entire IGMP table.
-    ==========================================================================
- */
-VOID MultiCastFilterTableReset(
-	IN PMULTICAST_FILTER_TABLE *ppMulticastFilterTable)
-{
-	if(*ppMulticastFilterTable == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table is not ready.\n", __FUNCTION__));
-		return;
-	}
-
-	NdisFreeSpinLock(&((*ppMulticastFilterTable)->FreeMemberPoolTabLock));
-	NdisFreeSpinLock(&((*ppMulticastFilterTable)->MulticastFilterTabLock));
-	kfree(*ppMulticastFilterTable);
-	*ppMulticastFilterTable = NULL;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Display all entrys in IGMP table
-    ==========================================================================
- */
-static VOID IGMPTableDisplay(
-	IN PRTMP_ADAPTER pAd)
-{
-	int i;
-	MULTICAST_FILTER_TABLE_ENTRY *pEntry = NULL;
-	PMULTICAST_FILTER_TABLE pMulticastFilterTable = pAd->pMulticastFilterTable;
-
-	if (pMulticastFilterTable == NULL)
-	{
-		DBGPRINT(RT_DEBUG_OFF, ("%s Multicase filter table is not ready.\n", __FUNCTION__));
-		return;
-	}
-
-	// if FULL, return
-	if (pMulticastFilterTable->Size == 0)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Table empty.\n"));
-		return;
-	}
-
-	// allocate one MAC entry
-	RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock);
-
-	for (i = 0; i< MAX_LEN_OF_MULTICAST_FILTER_TABLE; i++)
-	{
-		// pick up the first available vacancy
-		if (pMulticastFilterTable->Content[i].Valid == TRUE)
-		{
-			PMEMBER_ENTRY pMemberEntry = NULL;
-			pEntry = &pMulticastFilterTable->Content[i];
-
-			DBGPRINT(RT_DEBUG_OFF, ("IF(%s) entry #%d, type=%s, GrpId=(%02x:%02x:%02x:%02x:%02x:%02x) memberCnt=%d\n",
-				RTMP_OS_NETDEV_GET_DEVNAME(pEntry->net_dev), i, (pEntry->type==0 ? "static":"dynamic"),
-				PRINT_MAC(pEntry->Addr), IgmpMemberCnt(&pEntry->MemberList)));
-
-			pMemberEntry = (PMEMBER_ENTRY)pEntry->MemberList.pHead;
-			while (pMemberEntry)
-			{
-				DBGPRINT(RT_DEBUG_OFF, ("member mac=(%02x:%02x:%02x:%02x:%02x:%02x)\n",
-										PRINT_MAC(pMemberEntry->Addr)));
-
-				pMemberEntry = pMemberEntry->pNext;
-			}
-		}
-	}
-
-	RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock);
-
-	return;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Add and new entry into MAC table
-    ==========================================================================
- */
-BOOLEAN MulticastFilterTableInsertEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pGrpId,
-	IN PUCHAR pMemberAddr,
-	IN PNET_DEV dev,
-	IN MulticastFilterEntryType type)
-{
-	UCHAR HashIdx;
-	int i;
-	MULTICAST_FILTER_TABLE_ENTRY *pEntry = NULL, *pCurrEntry, *pPrevEntry;
-	PMEMBER_ENTRY pMemberEntry;
-	PMULTICAST_FILTER_TABLE pMulticastFilterTable = pAd->pMulticastFilterTable;
-
-	if (pMulticastFilterTable == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table is not ready.\n", __FUNCTION__));
-		return FALSE;
-	}
-
-	// if FULL, return
-	if (pMulticastFilterTable->Size >= MAX_LEN_OF_MULTICAST_FILTER_TABLE)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table full. max-entries = %d\n",
-			__FUNCTION__, MAX_LEN_OF_MULTICAST_FILTER_TABLE));
-		return FALSE;
-	}
-
-	// check the rule is in table already or not.
-	if ((pEntry = MulticastFilterTableLookup(pMulticastFilterTable, pGrpId, dev)))
-	{
-		// doesn't indicate member mac address.
-		if(pMemberAddr == NULL)
-		{
-			return FALSE;
-		}
-
-		pMemberEntry = (PMEMBER_ENTRY)pEntry->MemberList.pHead;
-
-		while (pMemberEntry)
-		{
-			if (MAC_ADDR_EQUAL(pMemberAddr, pMemberEntry->Addr))
-			{
-				DBGPRINT(RT_DEBUG_ERROR, ("%s: already in Members list.\n", __FUNCTION__));
-				return FALSE;
-			}
-
-			pMemberEntry = pMemberEntry->pNext;
-		}
-	}
-
-	RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock);
-	do
-	{
-		ULONG Now;
-		// the multicast entry already exist but doesn't include the member yet.
-		if (pEntry != NULL && pMemberAddr != NULL)
-		{
-			InsertIgmpMember(pMulticastFilterTable, &pEntry->MemberList, pMemberAddr);
-			break;
-		}
-
-		// allocate one MAC entry
-		for (i = 0; i < MAX_LEN_OF_MULTICAST_FILTER_TABLE; i++)
-		{
-			// pick up the first available vacancy
-			pEntry = &pMulticastFilterTable->Content[i];
-			NdisGetSystemUpTime(&Now);
-			if ((pEntry->Valid == TRUE) && (pEntry->type == MCAT_FILTER_DYNAMIC)
-				&& ((Now - pEntry->lastTime) > IGMPMAC_TB_ENTRY_AGEOUT_TIME))
-			{
-				PMULTICAST_FILTER_TABLE_ENTRY pHashEntry;
-
-				HashIdx = MULTICAST_ADDR_HASH_INDEX(pEntry->Addr);
-				pHashEntry = pMulticastFilterTable->Hash[HashIdx];
-
-				if ((pEntry->net_dev == pHashEntry->net_dev)
-					&& MAC_ADDR_EQUAL(pEntry->Addr, pHashEntry->Addr))
-				{
-					pMulticastFilterTable->Hash[HashIdx] = pHashEntry->pNext;
-					pMulticastFilterTable->Size --;
-					DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 1 - Total= %d\n", pMulticastFilterTable->Size));
-				} else
-				{
-					while (pHashEntry->pNext)
-					{
-						pPrevEntry = pHashEntry;
-						pHashEntry = pHashEntry->pNext;
-						if ((pEntry->net_dev == pHashEntry->net_dev)
-							&& MAC_ADDR_EQUAL(pEntry->Addr, pHashEntry->Addr))
-						{
-							pPrevEntry->pNext = pHashEntry->pNext;
-							pMulticastFilterTable->Size --;
-							DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 2 - Total= %d\n", pMulticastFilterTable->Size));
-							break;
-						}
-					}
-				}
-				pEntry->Valid = FALSE;
-				DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList);
-			}
-
-			if (pEntry->Valid == FALSE)
-			{
-				NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY));
-				pEntry->Valid = TRUE;
-
-				COPY_MAC_ADDR(pEntry->Addr, pGrpId);
-				pEntry->net_dev = dev;
-				NdisGetSystemUpTime(&Now);
-				pEntry->lastTime = Now;
-				pEntry->type = type;
-				initList(&pEntry->MemberList);
-				if (pMemberAddr != NULL)
-					InsertIgmpMember(pMulticastFilterTable, &pEntry->MemberList, pMemberAddr);
-
-				pMulticastFilterTable->Size ++;
-
-				DBGPRINT(RT_DEBUG_TRACE, ("MulticastFilterTableInsertEntry -IF(%s) allocate entry #%d, Total= %d\n", RTMP_OS_NETDEV_GET_DEVNAME(dev), i, pMulticastFilterTable->Size));
-				break;
-			}
-		}
-
-		// add this MAC entry into HASH table
-		if (pEntry)
-		{
-			HashIdx = MULTICAST_ADDR_HASH_INDEX(pGrpId);
-			if (pMulticastFilterTable->Hash[HashIdx] == NULL)
-			{
-				pMulticastFilterTable->Hash[HashIdx] = pEntry;
-			} else
-			{
-				pCurrEntry = pMulticastFilterTable->Hash[HashIdx];
-				while (pCurrEntry->pNext != NULL)
-					pCurrEntry = pCurrEntry->pNext;
-				pCurrEntry->pNext = pEntry;
-			}
-		}
-	}while(FALSE);
-
-	RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock);
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Delete a specified client from MAC table
-    ==========================================================================
- */
-BOOLEAN MulticastFilterTableDeleteEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pGrpId,
-	IN PUCHAR pMemberAddr,
-	IN PNET_DEV dev)
-{
-	USHORT HashIdx;
-	MULTICAST_FILTER_TABLE_ENTRY *pEntry, *pPrevEntry;
-	PMULTICAST_FILTER_TABLE pMulticastFilterTable = pAd->pMulticastFilterTable;
-	USHORT Aid = MCAST_WCID;
-	SST	Sst = SST_ASSOC;
-	UCHAR PsMode = PWR_ACTIVE, Rate;
-
-	if (pMulticastFilterTable == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table is not ready.\n", __FUNCTION__));
-		return FALSE;
-	}
-
-	RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock);
-
-	do
-	{
-		HashIdx = MULTICAST_ADDR_HASH_INDEX(pGrpId);
-		pPrevEntry = pEntry = pMulticastFilterTable->Hash[HashIdx];
-
-		while (pEntry && pEntry->Valid)
-		{
-			if ((pEntry->net_dev ==  dev)
-				&& MAC_ADDR_EQUAL(pEntry->Addr, pGrpId))
-				break;
-			else
-			{
-				pPrevEntry = pEntry;
-				pEntry = pEntry->pNext;
-			}
-		}
-
-		// check the rule is in table already or not.
-		if (pEntry && (pMemberAddr != NULL))
-		{
-			if(APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate))
-				DeleteIgmpMember(pMulticastFilterTable, &pEntry->MemberList, pMemberAddr);
-			if (IgmpMemberCnt(&pEntry->MemberList) > 0)
-				break;
-		}
-
-		if (pEntry)
-		{
-			if (pEntry == pMulticastFilterTable->Hash[HashIdx])
-			{
-				pMulticastFilterTable->Hash[HashIdx] = pEntry->pNext;
-				DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList);
-				NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY));
-				pMulticastFilterTable->Size --;
-				DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 1 - Total= %d\n", pMulticastFilterTable->Size));
-			}
-			else
-			{
-				pPrevEntry->pNext = pEntry->pNext;
-				DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList);
-				NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY));
-				pMulticastFilterTable->Size --;
-				DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 2 - Total= %d\n", pMulticastFilterTable->Size));
-			}
-		}
-		else
-		{
-			DBGPRINT(RT_DEBUG_ERROR, ("%s: the Group doesn't exist.\n", __FUNCTION__));
-		}
-	} while(FALSE);
-
-	RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock);
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Look up the MAC address in the IGMP table. Return NULL if not found.
-    Return:
-        pEntry - pointer to the MAC entry; NULL is not found
-    ==========================================================================
-*/
-PMULTICAST_FILTER_TABLE_ENTRY MulticastFilterTableLookup(
-	IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
-	IN PUCHAR pAddr,
-	IN PNET_DEV dev)
-{
-	ULONG HashIdx, Now;
-	PMULTICAST_FILTER_TABLE_ENTRY pEntry = NULL, pPrev = NULL;
-
-	if (pMulticastFilterTable == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table is not ready.\n", __FUNCTION__));
-		return NULL;
-	}
-
-	RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock);
-
-	HashIdx = MULTICAST_ADDR_HASH_INDEX(pAddr);
-	pEntry = pPrev = pMulticastFilterTable->Hash[HashIdx];
-
-	while (pEntry && pEntry->Valid)
-	{
-		if ((pEntry->net_dev ==  dev)
-			&& MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
-		{
-			NdisGetSystemUpTime(&Now);
-			pEntry->lastTime = Now;
-			break;
-		}
-		else
-		{
-			NdisGetSystemUpTime(&Now);
-			if ((pEntry->Valid == TRUE) && (pEntry->type == MCAT_FILTER_DYNAMIC)
-				&& RTMP_TIME_AFTER(Now, pEntry->lastTime+IGMPMAC_TB_ENTRY_AGEOUT_TIME))
-			{
-				// Remove the aged entry
-				if (pEntry == pMulticastFilterTable->Hash[HashIdx])
-				{
-					pMulticastFilterTable->Hash[HashIdx] = pEntry->pNext;
-					pPrev = pMulticastFilterTable->Hash[HashIdx];
-					DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList);
-					NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY));
-					pMulticastFilterTable->Size --;
-					pEntry = pPrev;
-					DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 2 - Total= %d\n", pMulticastFilterTable->Size));
-				}
-				else
-				{
-					pPrev->pNext = pEntry->pNext;
-					DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList);
-					NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY));
-					pMulticastFilterTable->Size --;
-					pEntry = (pPrev == NULL ? NULL: pPrev->pNext);
-					DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 2 - Total= %d\n", pMulticastFilterTable->Size));
-				}
-			}
-			else
-			{
-				pPrev = pEntry;
-				pEntry = pEntry->pNext;
-			}
-		}
-	}
-
-	RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock);
-
-	return pEntry;
-}
-
-VOID IGMPSnooping(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDstMacAddr,
-	IN PUCHAR pSrcMacAddr,
-	IN PUCHAR pIpHeader,
-	IN PNET_DEV pDev)
-{
-	INT i;
-	INT IpHeaderLen;
-	UCHAR GroupType;
-	UINT16 numOfGroup;
-	UCHAR IgmpVerType;
-	PUCHAR pIgmpHeader;
-	PUCHAR pGroup;
-	UCHAR AuxDataLen;
-	UINT16 numOfSources;
-	PUCHAR pGroupIpAddr;
-	UCHAR GroupMacAddr[6];
-	PUCHAR pGroupMacAddr = (PUCHAR)&GroupMacAddr;
-
-	if(isIgmpPkt(pDstMacAddr, pIpHeader))
-	{
-		IpHeaderLen = (*(pIpHeader + 2) & 0x0f) * 4;
-		pIgmpHeader = pIpHeader + 2 + IpHeaderLen;
-		IgmpVerType = (UCHAR)(*(pIgmpHeader));
-
-		DBGPRINT(RT_DEBUG_TRACE, ("IGMP type=%0x\n", IgmpVerType));
-
-		switch(IgmpVerType)
-		{
-		case IGMP_V1_MEMBERSHIP_REPORT: // IGMP version 1 membership report.
-		case IGMP_V2_MEMBERSHIP_REPORT: // IGMP version 2 membership report.
-			pGroupIpAddr = (PUCHAR)(pIgmpHeader + 4);
-				ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP);
-			DBGPRINT(RT_DEBUG_TRACE, ("IGMP Group=%02x:%02x:%02x:%02x:%02x:%02x\n",
-				GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
-			MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
-			break;
-
-		case IGMP_LEAVE_GROUP: // IGMP version 1 and version 2 leave group.
-			pGroupIpAddr = (PUCHAR)(pIgmpHeader + 4);
-				ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP);
-			DBGPRINT(RT_DEBUG_TRACE, ("IGMP Group=%02x:%02x:%02x:%02x:%02x:%02x\n",
-				GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
-			MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev);
-			break;
-
-		case IGMP_V3_MEMBERSHIP_REPORT: // IGMP version 3 membership report.
-			numOfGroup = ntohs(*((UINT16 *)(pIgmpHeader + 6)));
-			pGroup = (PUCHAR)(pIgmpHeader + 8);
-			for (i=0; i < numOfGroup; i++)
-			{
-				GroupType = (UCHAR)(*pGroup);
-				AuxDataLen = (UCHAR)(*(pGroup + 1));
-				numOfSources = ntohs(*((UINT16 *)(pGroup + 2)));
-				pGroupIpAddr = (PUCHAR)(pGroup + 4);
-				DBGPRINT(RT_DEBUG_TRACE, ("IGMPv3 Type=%d, ADL=%d, numOfSource=%d\n", GroupType, AuxDataLen, numOfSources));
-					ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP);
-				DBGPRINT(RT_DEBUG_TRACE, ("IGMP Group=%02x:%02x:%02x:%02x:%02x:%02x\n",
-					GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
-
-				do
-				{
-					if((GroupType == MODE_IS_EXCLUDE) || (GroupType == CHANGE_TO_EXCLUDE_MODE) || (GroupType == ALLOW_NEW_SOURCES))
-					{
-						MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
-						break;
-					}
-
-					if((GroupType == MODE_IS_INCLUDE) || (GroupType == BLOCK_OLD_SOURCES))
-					{
-						MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev);
-						break;
-					}
-
-					if((GroupType == CHANGE_TO_INCLUDE_MODE))
-					{
-						if(numOfSources == 0)
-							MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev);
-						else
-							MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
-						break;
-					}
-				} while(FALSE);
-				pGroup += (8 + (numOfSources * 4) + AuxDataLen);
-			}
-			break;
-
-		default:
-			DBGPRINT(RT_DEBUG_TRACE, ("unknow IGMP Type=%d\n", IgmpVerType));
-			break;
-		}
-	}
-
-	return;
-}
-
-
-static BOOLEAN isIgmpMacAddr(
-	IN PUCHAR pMacAddr)
-{
-	if((pMacAddr[0] == 0x01)
-		&& (pMacAddr[1] == 0x00)
-		&& (pMacAddr[2] == 0x5e))
-		return TRUE;
-	return FALSE;
-}
-
-BOOLEAN isIgmpPkt(
-	IN PUCHAR pDstMacAddr,
-	IN PUCHAR pIpHeader)
-{
-	UINT16 IpProtocol = ntohs(*((UINT16 *)(pIpHeader)));
-	UCHAR IgmpProtocol;
-
-	if(!isIgmpMacAddr(pDstMacAddr))
-		return FALSE;
-
-	if(IpProtocol == ETH_P_IP)
-	{
-		IgmpProtocol = (UCHAR)*(pIpHeader + 11);
-		if(IgmpProtocol == IGMP_PROTOCOL_DESCRIPTOR)
-				return TRUE;
-	}
-
-	return FALSE;
-}
-
-static VOID InsertIgmpMember(
-	IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
-	IN PLIST_HEADER pList,
-	IN PUCHAR pMemberAddr)
-{
-	PMEMBER_ENTRY pMemberEntry;
-
-	if(pList == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: membert list doesn't exist.\n", __FUNCTION__));
-		return;
-	}
-
-	if (pMemberAddr == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: invalid member.\n", __FUNCTION__));
-		return;
-	}
-
-	if((pMemberEntry = (PMEMBER_ENTRY)AllocaGrpMemberEntry(pMulticastFilterTable)) != NULL)
-	{
-		NdisZeroMemory(pMemberEntry, sizeof(MEMBER_ENTRY));
-		COPY_MAC_ADDR(pMemberEntry->Addr, pMemberAddr);
-		insertTailList(pList, (PLIST_ENTRY)pMemberEntry);
-
-		DBGPRINT(RT_DEBUG_TRACE, ("%s Member Mac=%02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__,
-			pMemberEntry->Addr[0], pMemberEntry->Addr[1], pMemberEntry->Addr[2],
-			pMemberEntry->Addr[3], pMemberEntry->Addr[4], pMemberEntry->Addr[5]));
-	}
-	return;
-}
-
-static VOID DeleteIgmpMember(
-	IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
-	IN PLIST_HEADER pList,
-	IN PUCHAR pMemberAddr)
-{
-	PMEMBER_ENTRY pCurEntry;
-
-	if((pList == NULL) || (pList->pHead == NULL))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: membert list doesn't exist.\n", __FUNCTION__));
-		return;
-	}
-
-	if (pMemberAddr == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: invalid member.\n", __FUNCTION__));
-		return;
-	}
-
-	pCurEntry = (PMEMBER_ENTRY)pList->pHead;
-	while (pCurEntry)
-	{
-		if(MAC_ADDR_EQUAL(pMemberAddr, pCurEntry->Addr))
-		{
-			delEntryList(pList, (PLIST_ENTRY)pCurEntry);
-			FreeGrpMemberEntry(pMulticastFilterTable, pCurEntry);
-			break;
-		}
-		pCurEntry = pCurEntry->pNext;
-	}
-
-	return;
-}
-
-static VOID DeleteIgmpMemberList(
-	IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
-	IN PLIST_HEADER pList)
-{
-	PMEMBER_ENTRY pCurEntry, pPrvEntry;
-
-	if((pList == NULL) || (pList->pHead == NULL))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: membert list doesn't exist.\n", __FUNCTION__));
-		return;
-	}
-
-	pPrvEntry = pCurEntry = (PMEMBER_ENTRY)pList->pHead;
-	while (pCurEntry)
-	{
-		delEntryList(pList, (PLIST_ENTRY)pCurEntry);
-		pPrvEntry = pCurEntry;
-		pCurEntry = pCurEntry->pNext;
-		FreeGrpMemberEntry(pMulticastFilterTable, pPrvEntry);
-	}
-
-	initList(pList);
-	return;
-}
-
-
-UCHAR IgmpMemberCnt(
-	IN PLIST_HEADER pList)
-{
-	if(pList == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: membert list doesn't exist.\n", __FUNCTION__));
-		return 0;
-	}
-
-	return getListSize(pList);
-}
-
-VOID IgmpGroupDelMembers(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pMemberAddr,
-	IN PNET_DEV pDev)
-{
-	INT i;
-	MULTICAST_FILTER_TABLE_ENTRY *pEntry = NULL;
-	PMULTICAST_FILTER_TABLE pMulticastFilterTable = pAd->pMulticastFilterTable;
-
-	for (i = 0; i < MAX_LEN_OF_MULTICAST_FILTER_TABLE; i++)
-	{
-		// pick up the first available vacancy
-		pEntry = &pMulticastFilterTable->Content[i];
-		if (pEntry->Valid == TRUE)
-		{
-			if(pMemberAddr != NULL)
-			{
-				RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock);
-				DeleteIgmpMember(pMulticastFilterTable, &pEntry->MemberList, pMemberAddr);
-				RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock);
-			}
-
-			if((pEntry->type == MCAT_FILTER_DYNAMIC)
-				&& (IgmpMemberCnt(&pEntry->MemberList) == 0))
-				MulticastFilterTableDeleteEntry(pAd, pEntry->Addr, pMemberAddr, pDev);
-		}
-	}
-}
-
-INT Set_IgmpSn_Enable_Proc(
-	IN PRTMP_ADAPTER pAd,
-	IN PSTRING arg)
-{
-	UINT Enable;
-	POS_COOKIE pObj;
-	UCHAR ifIndex;
-	PNET_DEV pDev;
-
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-	ifIndex = pObj->ioctl_if;
-
-	pDev = (ifIndex == MAIN_MBSSID) ? (pAd->net_dev) : (pAd->ApCfg.MBSSID[ifIndex].MSSIDDev);
-	Enable = (UINT) simple_strtol(arg, 0, 10);
-
-	pAd->ApCfg.MBSSID[ifIndex].IgmpSnoopEnable = (BOOLEAN)(Enable == 0 ? 0 : 1);
-	DBGPRINT(RT_DEBUG_TRACE, ("%s::(%s) %s\n", __FUNCTION__, RTMP_OS_NETDEV_GET_DEVNAME(pDev), Enable == TRUE ? "Enable IGMP Snooping":"Disable IGMP Snooping"));
-
-	return TRUE;
-}
-
-INT Set_IgmpSn_AddEntry_Proc(
-	IN PRTMP_ADAPTER pAd,
-	IN PSTRING arg)
-{
-	INT i;
-	BOOLEAN bGroupId = 1;
-	PSTRING value;
-	PSTRING thisChar;
-	UCHAR IpAddr[4];
-	UCHAR Addr[ETH_LENGTH_OF_ADDRESS];
-	UCHAR GroupId[ETH_LENGTH_OF_ADDRESS];
-	PUCHAR *pAddr = (PUCHAR *)&Addr;
-	PNET_DEV pDev;
-	POS_COOKIE pObj;
-	UCHAR ifIndex;
-
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-	ifIndex = pObj->ioctl_if;
-
-	pDev = (ifIndex == MAIN_MBSSID) ? (pAd->net_dev) : (pAd->ApCfg.MBSSID[ifIndex].MSSIDDev);
-
-	while ((thisChar = strsep((char **)&arg, "-")) != NULL)
-	{
-		// refuse the Member if it's not a MAC address.
-		if((bGroupId == 0) && (strlen(thisChar) != 17))
-			continue;
-
-		if(strlen(thisChar) == 17)  //Mac address acceptable format 01:02:03:04:05:06 length 17
-		{
-			for (i=0, value = rstrtok(thisChar,":"); value; value = rstrtok(NULL,":"))
-			{
-				if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
-					return FALSE;  //Invalid
-
-				AtoH(value, &Addr[i++], 1);
-			}
-
-			if(i != 6)
-				return FALSE;  //Invalid
-		}
-		else
-		{
-			for (i=0, value = rstrtok(thisChar,"."); value; value = rstrtok(NULL,"."))
-			{
-				if((strlen(value) > 0) && (strlen(value) <= 3))
-				{
-					int ii;
-					for(ii=0; ii<strlen(value); ii++)
-						if (!isxdigit(*(value + ii)))
-							return FALSE;
-				}
-				else
-					return FALSE;  //Invalid
-
-				IpAddr[i] = (UCHAR)simple_strtol(value, NULL, 10);
-				i++;
-			}
-
-			if(i != 4)
-				return FALSE;  //Invalid
-
-			ConvertMulticastIP2MAC(IpAddr, (PUCHAR *)&pAddr, ETH_P_IP);
-		}
-
-		if(bGroupId == 1)
-			COPY_MAC_ADDR(GroupId, Addr);
-
-		// Group-Id must be a MCAST address.
-		if((bGroupId == 1) && IS_MULTICAST_MAC_ADDR(Addr))
-			MulticastFilterTableInsertEntry(pAd, GroupId, NULL, pDev, MCAT_FILTER_STATIC);
-		// Group-Member must be a UCAST address.
-		else if ((bGroupId == 0) && !IS_MULTICAST_MAC_ADDR(Addr))
-			MulticastFilterTableInsertEntry(pAd, GroupId, Addr, pDev, MCAT_FILTER_STATIC);
-		else
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("%s (%2X:%2X:%2X:%2X:%2X:%2X) is not a acceptable address.\n",
-				__FUNCTION__, Addr[0], Addr[1], Addr[2], Addr[3], Addr[4], Addr[5]));
-			return FALSE;
-		}
-
-		bGroupId = 0;
-		DBGPRINT(RT_DEBUG_TRACE, ("%s (%2X:%2X:%2X:%2X:%2X:%2X)\n",
-			__FUNCTION__, Addr[0], Addr[1], Addr[2], Addr[3], Addr[4], Addr[5]));
-
-	}
-
-	return TRUE;
-}
-
-INT Set_IgmpSn_DelEntry_Proc(
-	IN PRTMP_ADAPTER pAd,
-	IN PSTRING arg)
-{
-	INT i, memberCnt = 0;
-	BOOLEAN bGroupId = 1;
-	PSTRING value;
-	PSTRING thisChar;
-	UCHAR IpAddr[4];
-	UCHAR Addr[ETH_LENGTH_OF_ADDRESS];
-	UCHAR GroupId[ETH_LENGTH_OF_ADDRESS];
-	PUCHAR *pAddr = (PUCHAR *)&Addr;
-	PNET_DEV pDev;
-	POS_COOKIE pObj;
-	UCHAR ifIndex;
-
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-	ifIndex = pObj->ioctl_if;
-
-	pDev = (ifIndex == MAIN_MBSSID) ? (pAd->net_dev) : (pAd->ApCfg.MBSSID[ifIndex].MSSIDDev);
-
-	while ((thisChar = strsep((char **)&arg, "-")) != NULL)
-	{
-		// refuse the Member if it's not a MAC address.
-		if((bGroupId == 0) && (strlen(thisChar) != 17))
-			continue;
-
-		if(strlen(thisChar) == 17)  //Mac address acceptable format 01:02:03:04:05:06 length 17
-		{
-			for (i=0, value = rstrtok(thisChar,":"); value; value = rstrtok(NULL,":"))
-			{
-				if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
-					return FALSE;  //Invalid
-
-				AtoH(value, &Addr[i++], 1);
-			}
-
-			if(i != 6)
-				return FALSE;  //Invalid
-		}
-		else
-		{
-			for (i=0, value = rstrtok(thisChar,"."); value; value = rstrtok(NULL,"."))
-			{
-				if((strlen(value) > 0) && (strlen(value) <= 3))
-				{
-					int ii;
-					for(ii=0; ii<strlen(value); ii++)
-						if (!isxdigit(*(value + ii)))
-							return FALSE;
-				}
-				else
-					return FALSE;  //Invalid
-
-				IpAddr[i] = (UCHAR)simple_strtol(value, NULL, 10);
-				i++;
-			}
-
-			if(i != 4)
-				return FALSE;  //Invalid
-
-			ConvertMulticastIP2MAC(IpAddr, (PUCHAR *)&pAddr, ETH_P_IP);
-		}
-
-		if(bGroupId == 1)
-			COPY_MAC_ADDR(GroupId, Addr);
-		else
-			memberCnt++;
-
-		if (memberCnt > 0 )
-			MulticastFilterTableDeleteEntry(pAd, (PUCHAR)GroupId, Addr, pDev);
-
-		bGroupId = 0;
-	}
-
-	if(memberCnt == 0)
-		MulticastFilterTableDeleteEntry(pAd, (PUCHAR)GroupId, NULL, pDev);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("%s (%2X:%2X:%2X:%2X:%2X:%2X)\n",
-		__FUNCTION__, Addr[0], Addr[1], Addr[2], Addr[3], Addr[4], Addr[5]));
-
-	return TRUE;
-}
-
-INT Set_IgmpSn_TabDisplay_Proc(
-	IN PRTMP_ADAPTER pAd,
-	IN PSTRING arg)
-{
-	IGMPTableDisplay(pAd);
-	return TRUE;
-}
-
-void rtmp_read_igmp_snoop_from_file(
-	IN  PRTMP_ADAPTER pAd,
-	PSTRING tmpbuf,
-	PSTRING buffer)
-{
-	PSTRING		macptr;
-	INT			i=0;
-
-	//IgmpSnEnable
-	if(RTMPGetKeyParameter("IgmpSnEnable", tmpbuf, 128, buffer, TRUE))
-	{
-		for (i = 0, macptr = rstrtok(tmpbuf,";"); (macptr && i < pAd->ApCfg.BssidNum); macptr = rstrtok(NULL,";"), i++)
-		{
-			if ((strncmp(macptr, "0", 1) == 0))
-				pAd->ApCfg.MBSSID[i].IgmpSnoopEnable = FALSE;
-			else if ((strncmp(macptr, "1", 1) == 0))
-				pAd->ApCfg.MBSSID[i].IgmpSnoopEnable = TRUE;
-	        else
-				pAd->ApCfg.MBSSID[i].IgmpSnoopEnable = FALSE;
-
-			DBGPRINT(RT_DEBUG_TRACE, ("MBSSID[%d].Enable=%d\n", i, pAd->ApCfg.MBSSID[i].IgmpSnoopEnable));
-	    }
-	}
-}
-
-NDIS_STATUS IgmpPktInfoQuery(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pSrcBufVA,
-	IN PNDIS_PACKET pPacket,
-	IN UCHAR apidx,
-	OUT BOOLEAN *pInIgmpGroup,
-	OUT PMULTICAST_FILTER_TABLE_ENTRY *ppGroupEntry)
-{
-	if(IS_MULTICAST_MAC_ADDR(pSrcBufVA))
-	{
-		BOOLEAN IgmpMldPkt = FALSE;
-		PUCHAR pIpHeader = pSrcBufVA + 12;
-
-		if(ntohs(*((UINT16 *)(pIpHeader))) == ETH_P_IPV6)
-			IgmpMldPkt = isMldPkt(pSrcBufVA, pIpHeader, NULL, NULL);
-		else
-			IgmpMldPkt = isIgmpPkt(pSrcBufVA, pIpHeader);
-
-		if (IgmpMldPkt)
-		{
-			*ppGroupEntry = NULL;
-		}
-		else if ((*ppGroupEntry = MulticastFilterTableLookup(pAd->pMulticastFilterTable, pSrcBufVA,
-									pAd->ApCfg.MBSSID[apidx].MSSIDDev)) == NULL)
-		{
-			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-			return NDIS_STATUS_FAILURE;
-		}
-		*pInIgmpGroup = TRUE;
-	}
-	else if (IS_BROADCAST_MAC_ADDR(pSrcBufVA))
-	{
-		PUCHAR pDstIpAddr = pSrcBufVA + 30; // point to Destination of Ip address of IP header.
-		UCHAR GroupMacAddr[6];
-		PUCHAR pGroupMacAddr = (PUCHAR)&GroupMacAddr;
-
-		ConvertMulticastIP2MAC(pDstIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP);
-		if ((*ppGroupEntry = MulticastFilterTableLookup(pAd->pMulticastFilterTable, pGroupMacAddr,
-								pAd->ApCfg.MBSSID[apidx].MSSIDDev)) != NULL)
-		{
-			*pInIgmpGroup = TRUE;
-		}
-	}
-	return NDIS_STATUS_SUCCESS;
-}
-
-NDIS_STATUS IgmpPktClone(
-	IN PRTMP_ADAPTER pAd,
-	IN PNDIS_PACKET pPacket,
-	IN UCHAR QueIdx,
-	IN PMULTICAST_FILTER_TABLE_ENTRY pGroupEntry)
-{
-	PNDIS_PACKET pSkbClone = NULL;
-	PMEMBER_ENTRY pMemberEntry = (PMEMBER_ENTRY)pGroupEntry->MemberList.pHead;
-	MAC_TABLE_ENTRY *pMacEntry = NULL;
-	USHORT Aid;
-	SST	Sst = SST_ASSOC;
-	UCHAR PsMode = PWR_ACTIVE;
-	UCHAR Rate;
-	unsigned long IrqFlags;
-
-	// check all members of the IGMP group.
-	while(pMemberEntry != NULL)
-	{
-		pMacEntry = APSsPsInquiry(pAd, pMemberEntry->Addr, &Sst, &Aid, &PsMode, &Rate);
-
-		if (pMacEntry && (Sst == SST_ASSOC) && (PsMode != PWR_SAVE))
-		{
-		pSkbClone = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
-		if(pSkbClone)
-		{
-				RTMP_SET_PACKET_WCID(pSkbClone, (UCHAR)Aid);
-				// Pkt type must set to PKTSRC_NDIS.
-				// It cause of the deason that APHardTransmit()
-				// doesn't handle PKTSRC_DRIVER pkt type in version 1.3.0.0.
-				RTMP_SET_PACKET_SOURCE(pSkbClone, PKTSRC_NDIS);
-			}
-			else
-			{
-				pMemberEntry = pMemberEntry->pNext;
-				continue;
-			}
-
-			// insert the pkt to TxSwQueue.
-			if (pAd->TxSwQueue[QueIdx].Number >= MAX_PACKETS_IN_QUEUE)
-			{
-#ifdef BLOCK_NET_IF
-				StopNetIfQueue(pAd, QueIdx, pSkbClone);
-#endif // BLOCK_NET_IF //
-				RELEASE_NDIS_PACKET(pAd, pSkbClone, NDIS_STATUS_FAILURE);
-				return NDIS_STATUS_FAILURE;
-			}
-			else
-			{
-				RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-				InsertTailQueueAc(pAd, pMacEntry, &pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pSkbClone));
-				RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-			}
-		}
-		pMemberEntry = pMemberEntry->pNext;
-	}
-	return NDIS_STATUS_SUCCESS;
-}
-
-static inline BOOLEAN isMldMacAddr(
-	IN PUCHAR pMacAddr)
-{
-	return ((pMacAddr[0] == 0x33) && (pMacAddr[1] == 0x33)) ? TRUE : FALSE;
-}
-
-static inline BOOLEAN IsSupportedMldMsg(
-	IN UINT8 MsgType)
-{
-	BOOLEAN result = FALSE;
-	switch(MsgType)
-	{
-		case MLD_V1_LISTENER_REPORT:
-		case MLD_V1_LISTENER_DONE:
-		case MLD_V2_LISTERNER_REPORT:
-			result = TRUE;
-			break;
-		default:
-			result = FALSE;
-			break;
-	}
-
-	return result;
-}
-
-BOOLEAN isMldPkt(
-	IN PUCHAR pDstMacAddr,
-	IN PUCHAR pIpHeader,
-	OUT UINT8 *pProtoType,
-	OUT PUCHAR *pMldHeader)
-{
-	BOOLEAN result = FALSE;
-	UINT16 IpProtocol = ntohs(*((UINT16 *)(pIpHeader)));
-
-	if(!isMldMacAddr(pDstMacAddr))
-		return FALSE;
-
-	if(IpProtocol != ETH_P_IPV6)
-		return FALSE;
-
-	// skip protocol (2 Bytes).
-	pIpHeader += 2;
-	do
-	{
-		PRT_IPV6_HDR pIpv6Hdr = (PRT_IPV6_HDR)(pIpHeader);
-		UINT8 nextProtocol = pIpv6Hdr->nextHdr;
-		UINT32 offset = IPV6_HDR_LEN;
-
-		while(nextProtocol != IPV6_NEXT_HEADER_ICMPV6)
-		{
-			if(IPv6ExtHdrHandle((RT_IPV6_EXT_HDR *)(pIpHeader + offset), &nextProtocol, &offset) == FALSE)
-				break;
-		}
-
-		if(nextProtocol == IPV6_NEXT_HEADER_ICMPV6)
-		{
-			PRT_ICMPV6_HDR pICMPv6Hdr = (PRT_ICMPV6_HDR)(pIpHeader + offset);
-			if (IsSupportedMldMsg(pICMPv6Hdr->type) == TRUE)
-			{
-				if (pProtoType != NULL)
-					*pProtoType = pICMPv6Hdr->type;
-				if (pMldHeader != NULL)
-					*pMldHeader = (PUCHAR)pICMPv6Hdr;
-				result = TRUE;
-			}
-		}
-	}while(FALSE);
-
-	return result;
-}
-
-/*  MLD v1 messages have the following format:
-	0                   1                   2                   3
-	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 6 7 8 9 0 1
-	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	|     Type      |     Code      |          Checksum             |
-	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	|     Maximum Response Delay    |          Reserved             |
-	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	|                                                               |
-	+                                                               +
-	|                                                               |
-	+                       Multicast Address                       +
-	|                                                               |
-	+                                                               +
-	|                                                               |
-	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-*/
-
-/*	Version 3 Membership Report Message
-	0                   1                   2                   3
-	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 6 7 8 9 0 1
-	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	|  Type = 143   |    Reserved   |           Checksum            |
-	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	|           Reserved            |  Number of Group Records (M)  |
-	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	|                                                               |
-	.                                                               .
-	.               Multicast Address Record [1]                    .
-	.                                                               .
-	|                                                               |
-	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	|                                                               |
-	.                                                               .
-	.               Multicast Address Record [2]                    .
-	.                                                               .
-	|                                                               |
-	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	|                               .                               |
-	.                               .                               .
-	|                               .                               |
-	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	|                                                               |
-	.                                                               .
-	.               Multicast Address Record [M]                    .
-	.                                                               .
-	|                                                               |
-	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-
-	where each Group Record has the following internal format:
-	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	|  Record Type  |  Aux Data Len |     Number of Sources (N)     |
-	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                                                               |
-    *                                                               *
-    |                                                               |
-    *                       Multicast Address                       *
-    |                                                               |
-    *                                                               *
-    |                                                               |
-	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                                                               |
-    *                                                               *
-    |                                                               |
-    *                       Source Address [1]                      *
-    |                                                               |
-    *                                                               *
-    |                                                               |
-    +-                                                             -+
-    |                                                               |
-    *                                                               *
-    |                                                               |
-    *                       Source Address [2]                      *
-    |                                                               |
-    *                                                               *
-    |                                                               |
-    +-                                                             -+
-    .                               .                               .
-    .                               .                               .
-    .                               .                               .
-    +-                                                             -+
-    |                                                               |
-    *                                                               *
-    |                                                               |
-    *                       Source Address [N]                      *
-    |                                                               |
-    *                                                               *
-    |                                                               |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                                                               |
-    .                                                               .
-    .                         Auxiliary Data                        .
-    .                                                               .
-    |                                                               |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-*/
-
-VOID MLDSnooping(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDstMacAddr,
-	IN PUCHAR pSrcMacAddr,
-	IN PUCHAR pIpHeader,
-	IN PNET_DEV pDev)
-{
-	INT i;
-	UCHAR GroupType;
-	UINT16 numOfGroup;
-	PUCHAR pGroup;
-	UCHAR AuxDataLen;
-	UINT16 numOfSources;
-	PUCHAR pGroupIpAddr;
-	UCHAR GroupMacAddr[6];
-	PUCHAR pGroupMacAddr = (PUCHAR)&GroupMacAddr;
-
-	UINT8 MldType;
-	PUCHAR pMldHeader;
-
-	if(isMldPkt(pDstMacAddr, pIpHeader, &MldType, &pMldHeader) == TRUE)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("MLD type=%0x\n", MldType));
-
-		switch(MldType)
-		{
-			case MLD_V1_LISTENER_REPORT:
-				// skip Type(1 Byte), code(1 Byte), checksum(2 Bytes), Maximum Rsp Delay(2 Bytes), Reserve(2 Bytes).
-				pGroupIpAddr = (PUCHAR)(pMldHeader + 8);
-				ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IPV6);
-				DBGPRINT(RT_DEBUG_TRACE, ("Group Id=%02x:%02x:%02x:%02x:%02x:%02x\n",
-						GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
-				MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
-				break;
-
-			case MLD_V1_LISTENER_DONE:
-				// skip Type(1 Byte), code(1 Byte), checksum(2 Bytes), Maximum Rsp Delay(2 Bytes), Reserve(2 Bytes).
-				pGroupIpAddr = (PUCHAR)(pMldHeader + 8);
-				ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IPV6);
-				DBGPRINT(RT_DEBUG_TRACE, ("Group Id=%02x:%02x:%02x:%02x:%02x:%02x\n",
-						GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
-				MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev);
-				break;
-
-			case MLD_V2_LISTERNER_REPORT: // IGMP version 3 membership report.
-				numOfGroup = ntohs(*((UINT16 *)(pMldHeader + 6)));
-				pGroup = (PUCHAR)(pMldHeader + 8);
-				for (i=0; i < numOfGroup; i++)
-				{
-					GroupType = (UCHAR)(*pGroup);
-					AuxDataLen = (UCHAR)(*(pGroup + 1));
-					numOfSources = ntohs(*((UINT16 *)(pGroup + 2)));
-					pGroupIpAddr = (PUCHAR)(pGroup + 4);
-					DBGPRINT(RT_DEBUG_TRACE, ("MLDv2 Type=%d, ADL=%d, numOfSource=%d\n", GroupType, AuxDataLen, numOfSources));
-					ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IPV6);
-					DBGPRINT(RT_DEBUG_TRACE, ("MLD Group=%02x:%02x:%02x:%02x:%02x:%02x\n",
-							GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
-
-					do
-					{
-						if((GroupType == MODE_IS_EXCLUDE) || (GroupType == CHANGE_TO_EXCLUDE_MODE) || (GroupType == ALLOW_NEW_SOURCES))
-						{
-							MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
-							break;
-						}
-
-						if((GroupType == MODE_IS_INCLUDE) || (GroupType == BLOCK_OLD_SOURCES))
-						{
-							MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev);
-							break;
-						}
-
-						if((GroupType == CHANGE_TO_INCLUDE_MODE))
-						{
-							if(numOfSources == 0)
-								MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev);
-							else
-								MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
-							break;
-						}
-					} while(FALSE);
-					// skip 4 Bytes (Record Type, Aux Data Len, Number of Sources) + a IPv6 address.
-					pGroup += (4 + IPV6_ADDR_LEN + (numOfSources * 16) + AuxDataLen);
-				}
-				break;
-
-			default:
-				DBGPRINT(RT_DEBUG_TRACE, ("unknow MLD Type=%d\n", MldType));
-				break;
-		}
-	}
-
-	return;
-}
-
-
-#endif // IGMP_SNOOP_SUPPORT //
diff --git a/drivers/staging/rt3090/common/mlme.c b/drivers/staging/rt3090/common/mlme.c
deleted file mode 100644
index 1613c04..0000000
--- a/drivers/staging/rt3090/common/mlme.c
+++ /dev/null
@@ -1,6550 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	mlme.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	John Chang	2004-08-25		Modify from RT2500 code base
-	John Chang	2004-09-06		modified for RT2600
-*/
-
-#include "../rt_config.h"
-#include <stdarg.h>
-
-UCHAR	CISCO_OUI[] = {0x00, 0x40, 0x96};
-
-UCHAR	WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
-UCHAR	RSN_OUI[] = {0x00, 0x0f, 0xac};
-UCHAR	WAPI_OUI[] = {0x00, 0x14, 0x72};
-UCHAR   WME_INFO_ELEM[]  = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
-UCHAR   WME_PARM_ELEM[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
-UCHAR	Ccx2QosInfo[] = {0x00, 0x40, 0x96, 0x04};
-UCHAR   RALINK_OUI[]  = {0x00, 0x0c, 0x43};
-UCHAR   BROADCOM_OUI[]  = {0x00, 0x90, 0x4c};
-UCHAR   WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
-#ifdef CONFIG_STA_SUPPORT
-#ifdef DOT11_N_SUPPORT
-UCHAR	PRE_N_HT_OUI[]	= {0x00, 0x90, 0x4c};
-#endif // DOT11_N_SUPPORT //
-#endif // CONFIG_STA_SUPPORT //
-
-UCHAR RateSwitchTable[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x11, 0x00,  0,  0,  0,						// Initial used item after association
-    0x00, 0x00,  0, 40, 101,
-    0x01, 0x00,  1, 40, 50,
-    0x02, 0x00,  2, 35, 45,
-    0x03, 0x00,  3, 20, 45,
-    0x04, 0x21,  0, 30, 50,
-    0x05, 0x21,  1, 20, 50,
-    0x06, 0x21,  2, 20, 50,
-    0x07, 0x21,  3, 15, 50,
-    0x08, 0x21,  4, 15, 30,
-    0x09, 0x21,  5, 10, 25,
-    0x0a, 0x21,  6,  8, 25,
-    0x0b, 0x21,  7,  8, 25,
-    0x0c, 0x20, 12,  15, 30,
-    0x0d, 0x20, 13,  8, 20,
-    0x0e, 0x20, 14,  8, 20,
-    0x0f, 0x20, 15,  8, 25,
-    0x10, 0x22, 15,  8, 25,
-    0x11, 0x00,  0,  0,  0,
-    0x12, 0x00,  0,  0,  0,
-    0x13, 0x00,  0,  0,  0,
-    0x14, 0x00,  0,  0,  0,
-    0x15, 0x00,  0,  0,  0,
-    0x16, 0x00,  0,  0,  0,
-    0x17, 0x00,  0,  0,  0,
-    0x18, 0x00,  0,  0,  0,
-    0x19, 0x00,  0,  0,  0,
-    0x1a, 0x00,  0,  0,  0,
-    0x1b, 0x00,  0,  0,  0,
-    0x1c, 0x00,  0,  0,  0,
-    0x1d, 0x00,  0,  0,  0,
-    0x1e, 0x00,  0,  0,  0,
-    0x1f, 0x00,  0,  0,  0,
-};
-
-UCHAR RateSwitchTable11B[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x04, 0x03,  0,  0,  0,						// Initial used item after association
-    0x00, 0x00,  0, 40, 101,
-    0x01, 0x00,  1, 40, 50,
-    0x02, 0x00,  2, 35, 45,
-    0x03, 0x00,  3, 20, 45,
-};
-
-UCHAR RateSwitchTable11BG[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0a, 0x00,  0,  0,  0,						// Initial used item after association
-    0x00, 0x00,  0, 40, 101,
-    0x01, 0x00,  1, 40, 50,
-    0x02, 0x00,  2, 35, 45,
-    0x03, 0x00,  3, 20, 45,
-    0x04, 0x10,  2, 20, 35,
-    0x05, 0x10,  3, 16, 35,
-    0x06, 0x10,  4, 10, 25,
-    0x07, 0x10,  5, 16, 25,
-    0x08, 0x10,  6, 10, 25,
-    0x09, 0x10,  7, 10, 13,
-};
-
-UCHAR RateSwitchTable11G[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x08, 0x00,  0,  0,  0,						// Initial used item after association
-    0x00, 0x10,  0, 20, 101,
-    0x01, 0x10,  1, 20, 35,
-    0x02, 0x10,  2, 20, 35,
-    0x03, 0x10,  3, 16, 35,
-    0x04, 0x10,  4, 10, 25,
-    0x05, 0x10,  5, 16, 25,
-    0x06, 0x10,  6, 10, 25,
-    0x07, 0x10,  7, 10, 13,
-};
-
-#ifdef DOT11_N_SUPPORT
-UCHAR RateSwitchTable11N1S[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0c, 0x0a,  0,  0,  0,						// Initial used item after association
-    0x00, 0x00,  0, 40, 101,
-    0x01, 0x00,  1, 40, 50,
-    0x02, 0x00,  2, 25, 45,
-    0x03, 0x21,  0, 20, 35,
-    0x04, 0x21,  1, 20, 35,
-    0x05, 0x21,  2, 20, 35,
-    0x06, 0x21,  3, 15, 35,
-    0x07, 0x21,  4, 15, 30,
-    0x08, 0x21,  5, 10, 25,
-    0x09, 0x21,  6,  8, 14,
-    0x0a, 0x21,  7,  8, 14,
-    0x0b, 0x23,  7,  8, 14,
-};
-
-UCHAR RateSwitchTable11N2S[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0e, 0x0c,  0,  0,  0,						// Initial used item after association
-    0x00, 0x00,  0, 40, 101,
-    0x01, 0x00,  1, 40, 50,
-    0x02, 0x00,  2, 25, 45,
-    0x03, 0x21,  0, 20, 35,
-    0x04, 0x21,  1, 20, 35,
-    0x05, 0x21,  2, 20, 35,
-    0x06, 0x21,  3, 15, 35,
-    0x07, 0x21,  4, 15, 30,
-    0x08, 0x20, 11, 15, 30,
-    0x09, 0x20, 12, 15, 30,
-    0x0a, 0x20, 13,  8, 20,
-    0x0b, 0x20, 14,  8, 20,
-    0x0c, 0x20, 15,  8, 25,
-    0x0d, 0x22, 15,  8, 15,
-};
-
-UCHAR RateSwitchTable11N3S[] = {
-// Item No.	Mode	Curr-MCS	TrainUp	TrainDown	// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0b, 0x00,  0,  0,  0,	// 0x0a, 0x00,  0,  0,  0,      // Initial used item after association
-    0x00, 0x21,  0, 30, 101,
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 15, 50,
-    0x04, 0x21,  4, 15, 30,
-    0x05, 0x20, 11, 15, 30,	// Required by System-Alan @ 20080812
-    0x06, 0x20, 12, 15, 30,	// 0x05, 0x20, 12, 15, 30,
-    0x07, 0x20, 13,  8, 20,	// 0x06, 0x20, 13,  8, 20,
-    0x08, 0x20, 14,  8, 20,	// 0x07, 0x20, 14,  8, 20,
-    0x09, 0x20, 15,  8, 25,	// 0x08, 0x20, 15,  8, 25,
-    0x0a, 0x22, 15,  8, 25,	// 0x09, 0x22, 15,  8, 25,
-};
-
-UCHAR RateSwitchTable11N2SForABand[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0b, 0x09,  0,  0,  0,						// Initial used item after association
-    0x00, 0x21,  0, 30, 101,
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 15, 50,
-    0x04, 0x21,  4, 15, 30,
-    0x05, 0x21,  5, 15, 30,
-    0x06, 0x20, 12,  15, 30,
-    0x07, 0x20, 13,  8, 20,
-    0x08, 0x20, 14,  8, 20,
-    0x09, 0x20, 15,  8, 25,
-    0x0a, 0x22, 15,  8, 25,
-};
-
-UCHAR RateSwitchTable11N3SForABand[] = { // 3*3
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0b, 0x09,  0,  0,  0,						// Initial used item after association
-    0x00, 0x21,  0, 30, 101,
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 15, 50,
-    0x04, 0x21,  4, 15, 30,
-    0x05, 0x21,  5, 15, 30,
-    0x06, 0x20, 12,  15, 30,
-    0x07, 0x20, 13,  8, 20,
-    0x08, 0x20, 14,  8, 20,
-    0x09, 0x20, 15,  8, 25,
-    0x0a, 0x22, 15,  8, 25,
-};
-
-UCHAR RateSwitchTable11BGN1S[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0c, 0x0a,  0,  0,  0,						// Initial used item after association
-    0x00, 0x00,  0, 40, 101,
-    0x01, 0x00,  1, 40, 50,
-    0x02, 0x00,  2, 25, 45,
-    0x03, 0x21,  0, 20, 35,
-    0x04, 0x21,  1, 20, 35,
-    0x05, 0x21,  2, 20, 35,
-    0x06, 0x21,  3, 15, 35,
-    0x07, 0x21,  4, 15, 30,
-    0x08, 0x21,  5, 10, 25,
-    0x09, 0x21,  6,  8, 14,
-    0x0a, 0x21,  7,  8, 14,
-    0x0b, 0x23,  7,  8, 14,
-};
-
-UCHAR RateSwitchTable11BGN2S[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0e, 0x0c,  0,  0,  0,						// Initial used item after association
-    0x00, 0x00,  0, 40, 101,
-    0x01, 0x00,  1, 40, 50,
-    0x02, 0x00,  2, 25, 45,
-    0x03, 0x21,  0, 20, 35,
-    0x04, 0x21,  1, 20, 35,
-    0x05, 0x21,  2, 20, 35,
-    0x06, 0x21,  3, 15, 35,
-    0x07, 0x21,  4, 15, 30,
-    0x08, 0x20, 11, 15, 30,
-    0x09, 0x20, 12, 15, 30,
-    0x0a, 0x20, 13,  8, 20,
-    0x0b, 0x20, 14,  8, 20,
-    0x0c, 0x20, 15,  8, 25,
-    0x0d, 0x22, 15,  8, 15,
-};
-
-UCHAR RateSwitchTable11BGN3S[] = { // 3*3
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0a, 0x00,  0,  0,  0,						// Initial used item after association
-    0x00, 0x21,  0, 30,101,	//50
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 20, 50,
-    0x04, 0x21,  4, 15, 50,
-    0x05, 0x20, 20, 15, 30,
-    0x06, 0x20, 21,  8, 20,
-    0x07, 0x20, 22,  8, 20,
-    0x08, 0x20, 23,  8, 25,
-    0x09, 0x22, 23,  8, 25,
-};
-
-UCHAR RateSwitchTable11BGN2SForABand[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0b, 0x09,  0,  0,  0,						// Initial used item after association
-    0x00, 0x21,  0, 30,101,	//50
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 15, 50,
-    0x04, 0x21,  4, 15, 30,
-    0x05, 0x21,  5, 15, 30,
-    0x06, 0x20, 12, 15, 30,
-    0x07, 0x20, 13,  8, 20,
-    0x08, 0x20, 14,  8, 20,
-    0x09, 0x20, 15,  8, 25,
-    0x0a, 0x22, 15,  8, 25,
-};
-
-UCHAR RateSwitchTable11BGN3SForABand[] = { // 3*3
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0c, 0x09,  0,  0,  0,						// Initial used item after association
-    0x00, 0x21,  0, 30,101,	//50
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 15, 50,
-    0x04, 0x21,  4, 15, 30,
-    0x05, 0x21,  5, 15, 30,
-    0x06, 0x21, 12, 15, 30,
-    0x07, 0x20, 20, 15, 30,
-    0x08, 0x20, 21,  8, 20,
-    0x09, 0x20, 22,  8, 20,
-    0x0a, 0x20, 23,  8, 25,
-    0x0b, 0x22, 23,  8, 25,
-};
-#endif // DOT11_N_SUPPORT //
-
-
-extern UCHAR	 OfdmRateToRxwiMCS[];
-// since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate.
-// otherwise the WLAN peer may not be able to receive the ACK thus downgrade its data TX rate
-ULONG BasicRateMask[12]				= {0xfffff001 /* 1-Mbps */, 0xfffff003 /* 2 Mbps */, 0xfffff007 /* 5.5 */, 0xfffff00f /* 11 */,
-									  0xfffff01f /* 6 */	 , 0xfffff03f /* 9 */	  , 0xfffff07f /* 12 */ , 0xfffff0ff /* 18 */,
-									  0xfffff1ff /* 24 */	 , 0xfffff3ff /* 36 */	  , 0xfffff7ff /* 48 */ , 0xffffffff /* 54 */};
-
-UCHAR BROADCAST_ADDR[MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN]  = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
-// e.g. RssiSafeLevelForTxRate[RATE_36]" means if the current RSSI is greater than
-//		this value, then it's quaranteed capable of operating in 36 mbps TX rate in
-//		clean environment.
-//								  TxRate: 1   2   5.5	11	 6	  9    12	18	 24   36   48	54	 72  100
-CHAR RssiSafeLevelForTxRate[] ={  -92, -91, -90, -87, -88, -86, -85, -83, -81, -78, -72, -71, -40, -40 };
-
-UCHAR  RateIdToMbps[]	 = { 1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 72, 100};
-USHORT RateIdTo500Kbps[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 144, 200};
-
-UCHAR  SsidIe	 = IE_SSID;
-UCHAR  SupRateIe = IE_SUPP_RATES;
-UCHAR  ExtRateIe = IE_EXT_SUPP_RATES;
-#ifdef DOT11_N_SUPPORT
-UCHAR  HtCapIe = IE_HT_CAP;
-UCHAR  AddHtInfoIe = IE_ADD_HT;
-UCHAR  NewExtChanIe = IE_SECONDARY_CH_OFFSET;
-#ifdef DOT11N_DRAFT3
-UCHAR  ExtHtCapIe = IE_EXT_CAPABILITY;
-#endif // DOT11N_DRAFT3 //
-#endif // DOT11_N_SUPPORT //
-UCHAR  ErpIe	 = IE_ERP;
-UCHAR  DsIe	 = IE_DS_PARM;
-UCHAR  TimIe	 = IE_TIM;
-UCHAR  WpaIe	 = IE_WPA;
-UCHAR  Wpa2Ie	 = IE_WPA2;
-UCHAR  IbssIe	 = IE_IBSS_PARM;
-UCHAR  Ccx2Ie	 = IE_CCX_V2;
-UCHAR  WapiIe	 = IE_WAPI;
-
-extern UCHAR	WPA_OUI[];
-
-UCHAR	SES_OUI[] = {0x00, 0x90, 0x4c};
-
-UCHAR	ZeroSsid[32] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
-
-
-/*
-	==========================================================================
-	Description:
-		initialize the MLME task and its data structure (queue, spinlock,
-		timer, state machines).
-
-	IRQL = PASSIVE_LEVEL
-
-	Return:
-		always return NDIS_STATUS_SUCCESS
-
-	==========================================================================
-*/
-NDIS_STATUS MlmeInit(
-	IN PRTMP_ADAPTER pAd)
-{
-	NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> MLME Initialize\n"));
-
-	do
-	{
-		Status = MlmeQueueInit(&pAd->Mlme.Queue);
-		if(Status != NDIS_STATUS_SUCCESS)
-			break;
-
-		pAd->Mlme.bRunning = FALSE;
-		NdisAllocateSpinLock(&pAd->Mlme.TaskLock);
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			BssTableInit(&pAd->ScanTab);
-
-			// init STA state machines
-			AssocStateMachineInit(pAd, &pAd->Mlme.AssocMachine, pAd->Mlme.AssocFunc);
-			AuthStateMachineInit(pAd, &pAd->Mlme.AuthMachine, pAd->Mlme.AuthFunc);
-			AuthRspStateMachineInit(pAd, &pAd->Mlme.AuthRspMachine, pAd->Mlme.AuthRspFunc);
-			SyncStateMachineInit(pAd, &pAd->Mlme.SyncMachine, pAd->Mlme.SyncFunc);
-
-#ifdef QOS_DLS_SUPPORT
-			DlsStateMachineInit(pAd, &pAd->Mlme.DlsMachine, pAd->Mlme.DlsFunc);
-#endif // QOS_DLS_SUPPORT //
-
-
-
-			// Since we are using switch/case to implement it, the init is different from the above
-			// state machine init
-			MlmeCntlInit(pAd, &pAd->Mlme.CntlMachine, NULL);
-		}
-#endif // CONFIG_STA_SUPPORT //
-
-
-		WpaStateMachineInit(pAd, &pAd->Mlme.WpaMachine, pAd->Mlme.WpaFunc);
-
-
-		ActionStateMachineInit(pAd, &pAd->Mlme.ActMachine, pAd->Mlme.ActFunc);
-
-		// Init mlme periodic timer
-		RTMPInitTimer(pAd, &pAd->Mlme.PeriodicTimer, GET_TIMER_FUNCTION(MlmePeriodicExec), pAd, TRUE);
-
-		// Set mlme periodic timer
-		RTMPSetTimer(&pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
-
-		// software-based RX Antenna diversity
-		RTMPInitTimer(pAd, &pAd->Mlme.RxAntEvalTimer, GET_TIMER_FUNCTION(AsicRxAntEvalTimeout), pAd, FALSE);
-
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-#ifdef RTMP_PCI_SUPPORT
-			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
-			{
-			    // only PCIe cards need these two timers
-				RTMPInitTimer(pAd, &pAd->Mlme.PsPollTimer, GET_TIMER_FUNCTION(PsPollWakeExec), pAd, FALSE);
-				RTMPInitTimer(pAd, &pAd->Mlme.RadioOnOffTimer, GET_TIMER_FUNCTION(RadioOnExec), pAd, FALSE);
-			}
-#endif // RTMP_PCI_SUPPORT //
-
-			RTMPInitTimer(pAd, &pAd->Mlme.LinkDownTimer, GET_TIMER_FUNCTION(LinkDownExec), pAd, FALSE);
-
-		}
-#endif // CONFIG_STA_SUPPORT //
-
-	} while (FALSE);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- MLME Initialize\n"));
-
-	return Status;
-}
-
-/*
-	==========================================================================
-	Description:
-		main loop of the MLME
-	Pre:
-		Mlme has to be initialized, and there are something inside the queue
-	Note:
-		This function is invoked from MPSetInformation and MPReceive;
-		This task guarantee only one MlmeHandler will run.
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID MlmeHandler(
-	IN PRTMP_ADAPTER pAd)
-{
-	MLME_QUEUE_ELEM		   *Elem = NULL;
-#ifdef APCLI_SUPPORT
-	SHORT apcliIfIndex;
-#endif // APCLI_SUPPORT //
-
-	// Only accept MLME and Frame from peer side, no other (control/data) frame should
-	// get into this state machine
-
-	NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
-	if(pAd->Mlme.bRunning)
-	{
-		NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
-		return;
-	}
-	else
-	{
-		pAd->Mlme.bRunning = TRUE;
-	}
-	NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
-
-	while (!MlmeQueueEmpty(&pAd->Mlme.Queue))
-	{
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS) ||
-			RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
-			RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("Device Halted or Removed or MlmeRest, exit MlmeHandler! (queue num = %ld)\n", pAd->Mlme.Queue.Num));
-			break;
-		}
-
-#ifdef RALINK_ATE
-		if(ATE_ON(pAd))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now in MlmeHandler\n"));
-			break;
-		}
-#endif // RALINK_ATE //
-
-		//From message type, determine which state machine I should drive
-		if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
-		{
-
-			// if dequeue success
-			switch (Elem->Machine)
-			{
-				// STA state machines
-#ifdef CONFIG_STA_SUPPORT
-				case ASSOC_STATE_MACHINE:
-					StateMachinePerformAction(pAd, &pAd->Mlme.AssocMachine, Elem);
-					break;
-				case AUTH_STATE_MACHINE:
-					StateMachinePerformAction(pAd, &pAd->Mlme.AuthMachine, Elem);
-					break;
-				case AUTH_RSP_STATE_MACHINE:
-					StateMachinePerformAction(pAd, &pAd->Mlme.AuthRspMachine, Elem);
-					break;
-				case SYNC_STATE_MACHINE:
-					StateMachinePerformAction(pAd, &pAd->Mlme.SyncMachine, Elem);
-					break;
-				case MLME_CNTL_STATE_MACHINE:
-					MlmeCntlMachinePerformAction(pAd, &pAd->Mlme.CntlMachine, Elem);
-					break;
-				case WPA_PSK_STATE_MACHINE:
-					StateMachinePerformAction(pAd, &pAd->Mlme.WpaPskMachine, Elem);
-					break;
-
-#ifdef QOS_DLS_SUPPORT
-				case DLS_STATE_MACHINE:
-					StateMachinePerformAction(pAd, &pAd->Mlme.DlsMachine, Elem);
-					break;
-#endif // QOS_DLS_SUPPORT //
-
-#endif // CONFIG_STA_SUPPORT //
-
-				case ACTION_STATE_MACHINE:
-					StateMachinePerformAction(pAd, &pAd->Mlme.ActMachine, Elem);
-					break;
-
-				case WPA_STATE_MACHINE:
-					StateMachinePerformAction(pAd, &pAd->Mlme.WpaMachine, Elem);
-					break;
-
-
-				default:
-					DBGPRINT(RT_DEBUG_TRACE, ("ERROR: Illegal machine %ld in MlmeHandler()\n", Elem->Machine));
-					break;
-			} // end of switch
-
-			// free MLME element
-			Elem->Occupied = FALSE;
-			Elem->MsgLen = 0;
-
-		}
-		else {
-			DBGPRINT_ERR(("MlmeHandler: MlmeQueue empty\n"));
-		}
-	}
-
-	NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
-	pAd->Mlme.bRunning = FALSE;
-	NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
-}
-
-/*
-	==========================================================================
-	Description:
-		Destructor of MLME (Destroy queue, state machine, spin lock and timer)
-	Parameters:
-		Adapter - NIC Adapter pointer
-	Post:
-		The MLME task will no longer work properly
-
-	IRQL = PASSIVE_LEVEL
-
-	==========================================================================
- */
-VOID MlmeHalt(
-	IN PRTMP_ADAPTER pAd)
-{
-	BOOLEAN		  Cancelled;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeHalt\n"));
-
-	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
-	{
-		// disable BEACON generation and other BEACON related hardware timers
-		AsicDisableSync(pAd);
-	}
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-#ifdef QOS_DLS_SUPPORT
-		UCHAR		i;
-#endif // QOS_DLS_SUPPORT //
-		// Cancel pending timers
-		RTMPCancelTimer(&pAd->MlmeAux.AssocTimer,		&Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer,		&Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer,	&Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.AuthTimer,		&Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer,		&Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.ScanTimer,		&Cancelled);
-
-
-#ifdef RTMP_MAC_PCI
-	    if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
-			&&(pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))
-	    {
-		    RTMPCancelTimer(&pAd->Mlme.PsPollTimer,		&Cancelled);
-		    RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer,		&Cancelled);
-		}
-#endif // RTMP_MAC_PCI //
-
-#ifdef QOS_DLS_SUPPORT
-		for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
-		{
-			RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &Cancelled);
-		}
-#endif // QOS_DLS_SUPPORT //
-		RTMPCancelTimer(&pAd->Mlme.LinkDownTimer,		&Cancelled);
-
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	RTMPCancelTimer(&pAd->Mlme.PeriodicTimer,		&Cancelled);
-	RTMPCancelTimer(&pAd->Mlme.RxAntEvalTimer,		&Cancelled);
-
-
-
-	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
-	{
-		RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
-
-		// Set LED
-		RTMPSetLED(pAd, LED_HALT);
-		RTMPSetSignalLED(pAd, -100);	// Force signal strength Led to be turned off, firmware is not done it.
-
-		if (pChipOps->AsicHaltAction)
-			pChipOps->AsicHaltAction(pAd);
-	}
-
-	RTMPusecDelay(5000);    //  5 msec to gurantee Ant Diversity timer canceled
-
-	MlmeQueueDestroy(&pAd->Mlme.Queue);
-	NdisFreeSpinLock(&pAd->Mlme.TaskLock);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeHalt\n"));
-}
-
-VOID MlmeResetRalinkCounters(
-	IN  PRTMP_ADAPTER   pAd)
-{
-	pAd->RalinkCounters.LastOneSecRxOkDataCnt = pAd->RalinkCounters.OneSecRxOkDataCnt;
-	// clear all OneSecxxx counters.
-	pAd->RalinkCounters.OneSecBeaconSentCnt = 0;
-	pAd->RalinkCounters.OneSecFalseCCACnt = 0;
-	pAd->RalinkCounters.OneSecRxFcsErrCnt = 0;
-	pAd->RalinkCounters.OneSecRxOkCnt = 0;
-	pAd->RalinkCounters.OneSecTxFailCount = 0;
-	pAd->RalinkCounters.OneSecTxNoRetryOkCount = 0;
-	pAd->RalinkCounters.OneSecTxRetryOkCount = 0;
-	pAd->RalinkCounters.OneSecRxOkDataCnt = 0;
-	pAd->RalinkCounters.OneSecReceivedByteCount = 0;
-	pAd->RalinkCounters.OneSecTransmittedByteCount = 0;
-
-	// TODO: for debug only. to be removed
-	pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] = 0;
-	pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BK] = 0;
-	pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VI] = 0;
-	pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VO] = 0;
-	pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BE] = 0;
-	pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BK] = 0;
-	pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VI] = 0;
-	pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VO] = 0;
-	pAd->RalinkCounters.OneSecTxDoneCount = 0;
-	pAd->RalinkCounters.OneSecRxCount = 0;
-	pAd->RalinkCounters.OneSecTxAggregationCount = 0;
-	pAd->RalinkCounters.OneSecRxAggregationCount = 0;
-
-	return;
-}
-
-
-/*
-	==========================================================================
-	Description:
-		This routine is executed periodically to -
-		1. Decide if it's a right time to turn on PwrMgmt bit of all
-		   outgoiing frames
-		2. Calculate ChannelQuality based on statistics of the last
-		   period, so that TX rate won't toggling very frequently between a
-		   successful TX and a failed TX.
-		3. If the calculated ChannelQuality indicated current connection not
-		   healthy, then a ROAMing attempt is tried here.
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-#define ADHOC_BEACON_LOST_TIME		(8*OS_HZ)  // 8 sec
-VOID MlmePeriodicExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3)
-{
-	ULONG			TxTotalCnt;
-	PRTMP_ADAPTER	pAd = (RTMP_ADAPTER *)FunctionContext;
-	SHORT	realavgrssi;
-
-#ifdef CONFIG_STA_SUPPORT
-#ifdef RTMP_MAC_PCI
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-	    // If Hardware controlled Radio enabled, we have to check GPIO pin2 every 2 second.
-		// Move code to here, because following code will return when radio is off
-		if ((pAd->Mlme.PeriodicRound % (MLME_TASK_EXEC_MULTIPLE * 2) == 0) && (pAd->StaCfg.bHardwareRadio == TRUE) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
-			/*&&(pAd->bPCIclkOff == FALSE)*/)
-		{
-			UINT32				data = 0;
-
-			// Read GPIO pin2 as Hardware controlled radio state
-#ifndef RT3090
-			RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
-#endif // RT3090 //
-//KH(PCIE PS):Added based on Jane<--
-#ifdef RT3090
-// Read GPIO pin2 as Hardware controlled radio state
-// We need to Read GPIO if HW said so no mater what advance power saving
-if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd))
-	&& (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
-	&& (pAd->StaCfg.PSControl.field.EnablePSinIdle == TRUE))
-	{
-	// Want to make sure device goes to L0 state before reading register.
-	RTMPPCIeLinkCtrlValueRestore(pAd, 0);
-	RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data);
-	RTMPPCIeLinkCtrlSetting(pAd, 3);
-	}
-else
-	RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data);
-#endif // RT3090 //
-//KH(PCIE PS):Added based on Jane-->
-
-			if (data & 0x04)
-			{
-				pAd->StaCfg.bHwRadio = TRUE;
-			}
-			else
-			{
-				pAd->StaCfg.bHwRadio = FALSE;
-			}
-			if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
-			{
-				pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
-				if (pAd->StaCfg.bRadio == TRUE)
-				{
-					MlmeRadioOn(pAd);
-					// Update extra information
-					pAd->ExtraInfo = EXTRA_INFO_CLEAR;
-				}
-				else
-				{
-					MlmeRadioOff(pAd);
-					// Update extra information
-					pAd->ExtraInfo = HW_RADIO_OFF;
-				}
-			}
-		}
-	}
-#endif // RTMP_MAC_PCI //
-#endif // CONFIG_STA_SUPPORT //
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_HALT_IN_PROGRESS |
-								fRTMP_ADAPTER_RADIO_OFF |
-								fRTMP_ADAPTER_RADIO_MEASUREMENT |
-								fRTMP_ADAPTER_RESET_IN_PROGRESS))))
-		return;
-
-	RTMP_MLME_PRE_SANITY_CHECK(pAd);
-
-#ifdef RALINK_ATE
-	/* Do not show RSSI until "Normal 1 second Mlme PeriodicExec". */
-	if (ATE_ON(pAd))
-	{
-		if (pAd->Mlme.PeriodicRound % MLME_TASK_EXEC_MULTIPLE != (MLME_TASK_EXEC_MULTIPLE - 1))
-	{
-			pAd->Mlme.PeriodicRound ++;
-			return;
-		}
-	}
-#endif // RALINK_ATE //
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		// Do nothing if monitor mode is on
-		if (MONITOR_ON(pAd))
-			return;
-
-		if (pAd->Mlme.PeriodicRound & 0x1)
-		{
-			// This is the fix for wifi 11n extension channel overlapping test case.  for 2860D
-			if (((pAd->MACVersion & 0xffff) == 0x0101) &&
-				(STA_TGN_WIFI_ON(pAd)) &&
-				(pAd->CommonCfg.IOTestParm.bToggle == FALSE))
-
-				{
-					RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x24Bf);
-					pAd->CommonCfg.IOTestParm.bToggle = TRUE;
-				}
-				else if ((STA_TGN_WIFI_ON(pAd)) &&
-						((pAd->MACVersion & 0xffff) == 0x0101))
-				{
-					RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x243f);
-					pAd->CommonCfg.IOTestParm.bToggle = FALSE;
-				}
-		}
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	pAd->bUpdateBcnCntDone = FALSE;
-
-//	RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3);
-	pAd->Mlme.PeriodicRound ++;
-
-
-	// execute every 500ms
-	if ((pAd->Mlme.PeriodicRound % 5 == 0) && RTMPAutoRateSwitchCheck(pAd)/*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))*/)
-	{
-#ifdef CONFIG_STA_SUPPORT
-		// perform dynamic tx rate switching based on past TX history
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
-					)
-				&& (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)))
-				MlmeDynamicTxRateSwitching(pAd);
-		}
-#endif // CONFIG_STA_SUPPORT //
-	}
-
-	// Normal 1 second Mlme PeriodicExec.
-	if (pAd->Mlme.PeriodicRound %MLME_TASK_EXEC_MULTIPLE == 0)
-	{
-                pAd->Mlme.OneSecPeriodicRound ++;
-
-#ifdef RALINK_ATE
-	if (ATE_ON(pAd))
-	{
-			/* request from Baron : move this routine from later to here */
-			/* for showing Rx error count in ATE RXFRAME */
-            NICUpdateRawCounters(pAd);
-			if (pAd->ate.bRxFER == 1)
-			{
-				pAd->ate.RxTotalCnt += pAd->ate.RxCntPerSec;
-			    ate_print(KERN_EMERG "MlmePeriodicExec: Rx packet cnt = %d/%d\n", pAd->ate.RxCntPerSec, pAd->ate.RxTotalCnt);
-				pAd->ate.RxCntPerSec = 0;
-
-				if (pAd->ate.RxAntennaSel == 0)
-					ate_print(KERN_EMERG "MlmePeriodicExec: Rx AvgRssi0=%d, AvgRssi1=%d, AvgRssi2=%d\n\n",
-						pAd->ate.AvgRssi0, pAd->ate.AvgRssi1, pAd->ate.AvgRssi2);
-				else
-					ate_print(KERN_EMERG "MlmePeriodicExec: Rx AvgRssi=%d\n\n", pAd->ate.AvgRssi0);
-			}
-			MlmeResetRalinkCounters(pAd);
-
-
-
-			return;
-	}
-#endif // RALINK_ATE //
-
-
-
-		//ORIBATimerTimeout(pAd);
-
-		// Media status changed, report to NDIS
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE))
-		{
-			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
-			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-			{
-				pAd->IndicateMediaState = NdisMediaStateConnected;
-				RTMP_IndicateMediaState(pAd);
-			}
-			else
-			{
-				pAd->IndicateMediaState = NdisMediaStateDisconnected;
-				RTMP_IndicateMediaState(pAd);
-			}
-		}
-
-		NdisGetSystemUpTime(&pAd->Mlme.Now32);
-
-		// add the most up-to-date h/w raw counters into software variable, so that
-		// the dynamic tuning mechanism below are based on most up-to-date information
-		NICUpdateRawCounters(pAd);
-
-
-#ifdef DOT11_N_SUPPORT
-		// Need statistics after read counter. So put after NICUpdateRawCounters
-		ORIBATimerTimeout(pAd);
-#endif // DOT11_N_SUPPORT //
-
-		// if MGMT RING is full more than twice within 1 second, we consider there's
-		// a hardware problem stucking the TX path. In this case, try a hardware reset
-		// to recover the system
-	//	if (pAd->RalinkCounters.MgmtRingFullCount >= 2)
-	//		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HARDWARE_ERROR);
-	//	else
-	//		pAd->RalinkCounters.MgmtRingFullCount = 0;
-
-		// The time period for checking antenna is according to traffic
-#ifdef ANT_DIVERSITY_SUPPORT
-		if ((pAd->NicConfig2.field.AntDiversity) &&
-			(pAd->CommonCfg.bRxAntDiversity == ANT_DIVERSITY_ENABLE) &&
-			(!pAd->EepromAccess))
-			AsicAntennaSelect(pAd, pAd->MlmeAux.Channel);
-		else if(pAd->CommonCfg.bRxAntDiversity == ANT_FIX_ANT1 || pAd->CommonCfg.bRxAntDiversity == ANT_FIX_ANT2)
-		{
-#ifdef CONFIG_STA_SUPPORT
-			realavgrssi = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt] >> 3);
-#endif // CONFIG_STA_SUPPORT //
-			DBGPRINT(RT_DEBUG_TRACE,("Ant-realrssi0(%d), Lastrssi0(%d), EvaluateStableCnt=%d\n", realavgrssi, pAd->RxAnt.Pair1LastAvgRssi, pAd->RxAnt.EvaluateStableCnt));
-		}
-		else
-#endif // ANT_DIVERSITY_SUPPORT //
-		{
-			if (pAd->Mlme.bEnableAutoAntennaCheck)
-			{
-				TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
-								 pAd->RalinkCounters.OneSecTxRetryOkCount +
-								 pAd->RalinkCounters.OneSecTxFailCount;
-
-				// dynamic adjust antenna evaluation period according to the traffic
-				if (TxTotalCnt > 50)
-				{
-					if (pAd->Mlme.OneSecPeriodicRound % 10 == 0)
-					{
-						AsicEvaluateRxAnt(pAd);
-					}
-				}
-				else
-				{
-					if (pAd->Mlme.OneSecPeriodicRound % 3 == 0)
-					{
-						AsicEvaluateRxAnt(pAd);
-					}
-				}
-			}
-		}
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-			STAMlmePeriodicExec(pAd);
-#endif // CONFIG_STA_SUPPORT //
-
-		MlmeResetRalinkCounters(pAd);
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-#ifdef RTMP_MAC_PCI
-			if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->bPCIclkOff == FALSE))
-#endif // RTMP_MAC_PCI //
-			{
-			// When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock
-			// and sending CTS-to-self over and over.
-			// Software Patch Solution:
-			// 1. Polling debug state register 0x10F4 every one second.
-			// 2. If in 0x10F4 the ((bit29==1) && (bit7==1)) OR ((bit29==1) && (bit5==1)), it means the deadlock has occurred.
-			// 3. If the deadlock occurred, reset MAC/BBP by setting 0x1004 to 0x0001 for a while then setting it back to 0x000C again.
-
-			UINT32	MacReg = 0;
-
-			RTMP_IO_READ32(pAd, 0x10F4, &MacReg);
-			if (((MacReg & 0x20000000) && (MacReg & 0x80)) || ((MacReg & 0x20000000) && (MacReg & 0x20)))
-			{
-				RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
-				RTMPusecDelay(1);
-				RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xC);
-
-				DBGPRINT(RT_DEBUG_WARN,("Warning, MAC specific condition occurs \n"));
-			}
-		}
-		}
-#endif // CONFIG_STA_SUPPORT //
-
-		RTMP_MLME_HANDLER(pAd);
-	}
-
-
-	pAd->bUpdateBcnCntDone = FALSE;
-}
-
-
-/*
-	==========================================================================
-	Validate SSID for connection try and rescan purpose
-	Valid SSID will have visible chars only.
-	The valid length is from 0 to 32.
-	IRQL = DISPATCH_LEVEL
-	==========================================================================
- */
-BOOLEAN MlmeValidateSSID(
-	IN PUCHAR	pSsid,
-	IN UCHAR	SsidLen)
-{
-	int	index;
-
-	if (SsidLen > MAX_LEN_OF_SSID)
-		return (FALSE);
-
-	// Check each character value
-	for (index = 0; index < SsidLen; index++)
-	{
-		if (pSsid[index] < 0x20)
-			return (FALSE);
-	}
-
-	// All checked
-	return (TRUE);
-}
-
-VOID MlmeSelectTxRateTable(
-	IN PRTMP_ADAPTER		pAd,
-	IN PMAC_TABLE_ENTRY		pEntry,
-	IN PUCHAR				*ppTable,
-	IN PUCHAR				pTableSize,
-	IN PUCHAR				pInitTxRateIdx)
-{
-	do
-	{
-		// decide the rate table for tuning
-		if (pAd->CommonCfg.TxRateTableSize > 0)
-		{
-			*ppTable = RateSwitchTable;
-			*pTableSize = RateSwitchTable[0];
-			*pInitTxRateIdx = RateSwitchTable[1];
-
-			break;
-		}
-
-#ifdef CONFIG_STA_SUPPORT
-		if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd))
-		{
-#ifdef DOT11_N_SUPPORT
-			if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
-				(pEntry->HTCapability.MCSSet[0] == 0xff) &&
-				((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
-			{// 11N 1S Adhoc
-				*ppTable = RateSwitchTable11N1S;
-				*pTableSize = RateSwitchTable11N1S[0];
-				*pInitTxRateIdx = RateSwitchTable11N1S[1];
-
-			}
-			else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
-					(pEntry->HTCapability.MCSSet[0] == 0xff) &&
-					(pEntry->HTCapability.MCSSet[1] == 0xff) &&
-					(pAd->Antenna.field.TxPath == 2))
-			{// 11N 2S Adhoc
-				if (pAd->LatchRfRegs.Channel <= 14)
-				{
-					*ppTable = RateSwitchTable11N2S;
-					*pTableSize = RateSwitchTable11N2S[0];
-					*pInitTxRateIdx = RateSwitchTable11N2S[1];
-				}
-				else
-				{
-					*ppTable = RateSwitchTable11N2SForABand;
-					*pTableSize = RateSwitchTable11N2SForABand[0];
-					*pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
-				}
-
-			}
-			else
-#endif // DOT11_N_SUPPORT //
-				if ((pEntry->RateLen == 4)
-#ifdef DOT11_N_SUPPORT
-					&& (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
-#endif // DOT11_N_SUPPORT //
-					)
-			{
-				*ppTable = RateSwitchTable11B;
-				*pTableSize = RateSwitchTable11B[0];
-				*pInitTxRateIdx = RateSwitchTable11B[1];
-
-			}
-			else if (pAd->LatchRfRegs.Channel <= 14)
-			{
-				*ppTable = RateSwitchTable11BG;
-				*pTableSize = RateSwitchTable11BG[0];
-				*pInitTxRateIdx = RateSwitchTable11BG[1];
-
-			}
-			else
-			{
-				*ppTable = RateSwitchTable11G;
-				*pTableSize = RateSwitchTable11G[0];
-				*pInitTxRateIdx = RateSwitchTable11G[1];
-
-			}
-			break;
-		}
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef DOT11_N_SUPPORT
-		//if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
-		//	((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
-		if (((pEntry->RateLen == 12) || (pAd->OpMode == OPMODE_STA)) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
-			((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
-		{// 11BGN 1S AP
-			*ppTable = RateSwitchTable11BGN1S;
-			*pTableSize = RateSwitchTable11BGN1S[0];
-			*pInitTxRateIdx = RateSwitchTable11BGN1S[1];
-
-			break;
-		}
-
-		//else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
-		//	(pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2))
-		if (((pEntry->RateLen == 12) || (pAd->OpMode == OPMODE_STA)) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
-			(pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
-		{// 11BGN 2S AP
-			if (pAd->LatchRfRegs.Channel <= 14)
-			{
-				*ppTable = RateSwitchTable11BGN2S;
-				*pTableSize = RateSwitchTable11BGN2S[0];
-				*pInitTxRateIdx = RateSwitchTable11BGN2S[1];
-
-			}
-			else
-			{
-				*ppTable = RateSwitchTable11BGN2SForABand;
-				*pTableSize = RateSwitchTable11BGN2SForABand[0];
-				*pInitTxRateIdx = RateSwitchTable11BGN2SForABand[1];
-
-			}
-			break;
-		}
-
-		//else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
-		if ((pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
-		{// 11N 1S AP
-			*ppTable = RateSwitchTable11N1S;
-			*pTableSize = RateSwitchTable11N1S[0];
-			*pInitTxRateIdx = RateSwitchTable11N1S[1];
-
-			break;
-		}
-
-		//else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2))
-		if ((pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
-		{// 11N 2S AP
-			if (pAd->LatchRfRegs.Channel <= 14)
-			{
-			*ppTable = RateSwitchTable11N2S;
-			*pTableSize = RateSwitchTable11N2S[0];
-			*pInitTxRateIdx = RateSwitchTable11N2S[1];
-			}
-			else
-			{
-				*ppTable = RateSwitchTable11N2SForABand;
-				*pTableSize = RateSwitchTable11N2SForABand[0];
-				*pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
-			}
-
-			break;
-		}
-#endif // DOT11_N_SUPPORT //
-		//else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
-		if ((pEntry->RateLen == 4 || pAd->CommonCfg.PhyMode==PHY_11B)
-#ifdef DOT11_N_SUPPORT
-		//Iverson mark for Adhoc b mode,sta will use rate 54  Mbps when connect with sta b/g/n mode
-		/* && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)*/
-#endif // DOT11_N_SUPPORT //
-			)
-		{// B only AP
-			*ppTable = RateSwitchTable11B;
-			*pTableSize = RateSwitchTable11B[0];
-			*pInitTxRateIdx = RateSwitchTable11B[1];
-
-			break;
-		}
-
-		//else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
-		if ((pEntry->RateLen > 8)
-#ifdef DOT11_N_SUPPORT
-			&& (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
-#endif // DOT11_N_SUPPORT //
-			)
-		{// B/G  mixed AP
-			*ppTable = RateSwitchTable11BG;
-			*pTableSize = RateSwitchTable11BG[0];
-			*pInitTxRateIdx = RateSwitchTable11BG[1];
-
-			break;
-		}
-
-		//else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
-		if ((pEntry->RateLen == 8)
-#ifdef DOT11_N_SUPPORT
-			&& (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
-#endif // DOT11_N_SUPPORT //
-			)
-		{// G only AP
-			*ppTable = RateSwitchTable11G;
-			*pTableSize = RateSwitchTable11G[0];
-			*pInitTxRateIdx = RateSwitchTable11G[1];
-
-			break;
-		}
-#ifdef DOT11_N_SUPPORT
-#endif // DOT11_N_SUPPORT //
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-#ifdef DOT11_N_SUPPORT
-			//else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
-			if ((pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0))
-#endif // DOT11_N_SUPPORT //
-			{	// Legacy mode
-				if (pAd->CommonCfg.MaxTxRate <= RATE_11)
-				{
-					*ppTable = RateSwitchTable11B;
-					*pTableSize = RateSwitchTable11B[0];
-					*pInitTxRateIdx = RateSwitchTable11B[1];
-				}
-				else if ((pAd->CommonCfg.MaxTxRate > RATE_11) && (pAd->CommonCfg.MinTxRate > RATE_11))
-				{
-					*ppTable = RateSwitchTable11G;
-					*pTableSize = RateSwitchTable11G[0];
-					*pInitTxRateIdx = RateSwitchTable11G[1];
-
-				}
-				else
-				{
-					*ppTable = RateSwitchTable11BG;
-					*pTableSize = RateSwitchTable11BG[0];
-					*pInitTxRateIdx = RateSwitchTable11BG[1];
-				}
-				break;
-			}
-#ifdef DOT11_N_SUPPORT
-			if (pAd->LatchRfRegs.Channel <= 14)
-			{
-				if (pAd->CommonCfg.TxStream == 1)
-				{
-					*ppTable = RateSwitchTable11N1S;
-					*pTableSize = RateSwitchTable11N1S[0];
-					*pInitTxRateIdx = RateSwitchTable11N1S[1];
-					DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
-				}
-				else
-				{
-					*ppTable = RateSwitchTable11N2S;
-					*pTableSize = RateSwitchTable11N2S[0];
-					*pInitTxRateIdx = RateSwitchTable11N2S[1];
-					DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
-				}
-			}
-			else
-			{
-				if (pAd->CommonCfg.TxStream == 1)
-				{
-					*ppTable = RateSwitchTable11N1S;
-					*pTableSize = RateSwitchTable11N1S[0];
-					*pInitTxRateIdx = RateSwitchTable11N1S[1];
-					DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
-				}
-				else
-				{
-					*ppTable = RateSwitchTable11N2SForABand;
-					*pTableSize = RateSwitchTable11N2SForABand[0];
-					*pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
-					DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
-				}
-			}
-#endif // DOT11_N_SUPPORT //
-			DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n",
-				pAd->StaActive.SupRateLen, pAd->StaActive.ExtRateLen, pAd->StaActive.SupportedPhyInfo.MCSSet[0], pAd->StaActive.SupportedPhyInfo.MCSSet[1]));
-		}
-#endif // CONFIG_STA_SUPPORT //
-	} while(FALSE);
-}
-
-
-#ifdef CONFIG_STA_SUPPORT
-VOID STAMlmePeriodicExec(
-	PRTMP_ADAPTER pAd)
-{
-	ULONG			    TxTotalCnt;
-	int	i;
-
-
-
-
-	/*
-		We return here in ATE mode, because the statistics
-		that ATE need are not collected via this routine.
-	*/
-#ifdef RALINK_ATE
-	if (ATE_ON(pAd))
-	return;
-#endif // RALINK_ATE //
-
-#ifdef RALINK_ATE
-	// It is supposed that we will never reach here in ATE mode.
-	ASSERT(!(ATE_ON(pAd)));
-	if (ATE_ON(pAd))
-		return;
-#endif // RALINK_ATE //
-
-#ifdef PCIE_PS_SUPPORT
-// don't perform idle-power-save mechanism within 3 min after driver initialization.
-// This can make rebooter test more robust
-if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
-	{
-	if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd))
-		&& (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE)
-		&& (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
-		&& (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
-		{
-		if (IS_RT3090(pAd)|| IS_RT3572(pAd) || IS_RT3390(pAd))
-			{
-			if (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
-				{
-				DBGPRINT(RT_DEBUG_TRACE, ("%s::%d\n",__FUNCTION__,__LINE__));
-
-				RT28xxPciAsicRadioOff(pAd, GUI_IDLE_POWER_SAVE, 0);
-				}
-			else
-				{
-				DBGPRINT(RT_DEBUG_TRACE, ("%s::%d\n",__FUNCTION__,__LINE__));
-				AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x2);
-				// Wait command success
-				AsicCheckCommanOk(pAd, PowerSafeCID);
-				RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
-				DBGPRINT(RT_DEBUG_TRACE, ("PSM - rt30xx Issue Sleep command)\n"));
-				}
-			}
-		else if (pAd->Mlme.OneSecPeriodicRound > 180)
-			{
-			if (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
-				{
-				DBGPRINT(RT_DEBUG_TRACE, ("%s::%d\n",__FUNCTION__,__LINE__));
-				RT28xxPciAsicRadioOff(pAd, GUI_IDLE_POWER_SAVE, 0);
-				}
-			else
-				{
-				DBGPRINT(RT_DEBUG_TRACE, ("%s::%d\n",__FUNCTION__,__LINE__));
-				AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x02);
-				// Wait command success
-				AsicCheckCommanOk(pAd, PowerSafeCID);
-				RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
-				DBGPRINT(RT_DEBUG_TRACE, ("PSM -  rt28xx Issue Sleep command)\n"));
-				}
-			}
-		}
-	else
-		{
-		DBGPRINT(RT_DEBUG_TRACE,("STAMlmePeriodicExec MMCHK - CommonCfg.Ssid[%d]=%c%c%c%c... MlmeAux.Ssid[%d]=%c%c%c%c...\n",
-			pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid[0], pAd->CommonCfg.Ssid[1], pAd->CommonCfg.Ssid[2], pAd->CommonCfg.Ssid[3],
-			pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid[0], pAd->MlmeAux.Ssid[1], pAd->MlmeAux.Ssid[2], pAd->MlmeAux.Ssid[3]));
-		}
-	}
-#endif // PCIE_PS_SUPPORT //
-
-
-#ifdef WPA_SUPPLICANT_SUPPORT
-    if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)
-#endif // WPA_SUPPLICANT_SUPPORT //
-    {
-	// WPA MIC error should block association attempt for 60 seconds
-		if (pAd->StaCfg.bBlockAssoc &&
-			RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastMicErrorTime + (60*OS_HZ)))
-		pAd->StaCfg.bBlockAssoc = FALSE;
-    }
-
-    if ((pAd->PreMediaState != pAd->IndicateMediaState) && (pAd->CommonCfg.bWirelessEvent))
-	{
-		if (pAd->IndicateMediaState == NdisMediaStateConnected)
-		{
-			RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-		}
-		pAd->PreMediaState = pAd->IndicateMediaState;
-	}
-
-
-
-
-	if (pAd->CommonCfg.PSPXlink && ADHOC_ON(pAd))
-	{
-	}
-	else
-	{
-	AsicStaBbpTuning(pAd);
-	}
-
-	TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
-					 pAd->RalinkCounters.OneSecTxRetryOkCount +
-					 pAd->RalinkCounters.OneSecTxFailCount;
-
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-	{
-		// update channel quality for Roaming and UI LinkQuality display
-		MlmeCalculateChannelQuality(pAd, NULL, pAd->Mlme.Now32);
-	}
-
-	// must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if
-	// Radio is currently in noisy environment
-	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-	AsicAdjustTxPower(pAd);
-
-	if (INFRA_ON(pAd))
-	{
-#ifdef QOS_DLS_SUPPORT
-		// Check DLS time out, then tear down those session
-		RTMPCheckDLSTimeOut(pAd);
-#endif // QOS_DLS_SUPPORT //
-
-		// Is PSM bit consistent with user power management policy?
-		// This is the only place that will set PSM bit ON.
-		if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-		MlmeCheckPsmChange(pAd, pAd->Mlme.Now32);
-
-		pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt;
-
-		if ((RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastBeaconRxTime + (1*OS_HZ))) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
-			(((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt) < 600)))
-		{
-			RTMPSetAGCInitValue(pAd, BW_20);
-			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n", (0x2E + GET_LNA_GAIN(pAd))));
-		}
-
-        //if ((pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
-        //    (pAd->RalinkCounters.OneSecTxRetryOkCount == 0))
-        {
-		if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)
-		{
-		    // When APSD is enabled, the period changes as 20 sec
-			if ((pAd->Mlme.OneSecPeriodicRound % 20) == 8)
-				RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
-		}
-		else
-		{
-		    // Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out)
-			if ((pAd->Mlme.OneSecPeriodicRound % 10) == 8)
-                {
-                    if (pAd->CommonCfg.bWmmCapable)
-					RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
-                    else
-						RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
-                }
-		}
-        }
-
-		if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality))
-			{
-			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
-
-			// Lost AP, send disconnect & link down event
-			LinkDown(pAd, FALSE);
-
-#ifdef WPA_SUPPLICANT_SUPPORT
-#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
-		//send disassociate event to wpa_supplicant
-		if (pAd->StaCfg.WpaSupplicantUP) {
-			RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, RT_DISASSOC_EVENT_FLAG, NULL, NULL, 0);
-		}
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-		RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0);
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-
-			// RTMPPatchMacBbpBug(pAd);
-			MlmeAutoReconnectLastSSID(pAd);
-		}
-		else if (CQI_IS_BAD(pAd->Mlme.ChannelQuality))
-		{
-			pAd->RalinkCounters.BadCQIAutoRecoveryCount ++;
-			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Bad CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
-			MlmeAutoReconnectLastSSID(pAd);
-		}
-
-		if (pAd->StaCfg.bAutoRoaming)
-		{
-			BOOLEAN	rv = FALSE;
-			CHAR	dBmToRoam = pAd->StaCfg.dBmToRoam;
-			CHAR	MaxRssi = RTMPMaxRssi(pAd,
-										  pAd->StaCfg.RssiSample.LastRssi0,
-										  pAd->StaCfg.RssiSample.LastRssi1,
-										  pAd->StaCfg.RssiSample.LastRssi2);
-
-			// Scanning, ignore Roaming
-			if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) &&
-				(pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE) &&
-				(MaxRssi <= dBmToRoam))
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("Rssi=%d, dBmToRoam=%d\n", MaxRssi, (CHAR)dBmToRoam));
-
-
-				// Add auto seamless roaming
-				if (rv == FALSE)
-					rv = MlmeCheckForFastRoaming(pAd);
-
-				if (rv == FALSE)
-				{
-					if ((pAd->StaCfg.LastScanTime + 10 * OS_HZ) < pAd->Mlme.Now32)
-					{
-						DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming, No eligable entry, try new scan!\n"));
-						pAd->StaCfg.ScanCnt = 2;
-						pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
-						MlmeAutoScan(pAd);
-					}
-				}
-			}
-		}
-	}
-	else if (ADHOC_ON(pAd))
-	{
-
-		// If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState
-		// to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can
-		// join later.
-		if (RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME) &&
-			OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-		{
-			MLME_START_REQ_STRUCT     StartReq;
-
-			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n"));
-			LinkDown(pAd, FALSE);
-
-			StartParmFill(pAd, &StartReq, (CHAR *)pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
-			MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
-		}
-
-		for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
-		{
-			MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[i];
-
-			if (pEntry->ValidAsCLI == FALSE)
-				continue;
-
-			if (RTMP_TIME_AFTER(pAd->Mlme.Now32, pEntry->LastBeaconRxTime + ADHOC_BEACON_LOST_TIME))
-				MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
-		}
-	}
-	else // no INFRA nor ADHOC connection
-	{
-
-		if (pAd->StaCfg.bScanReqIsFromWebUI &&
-			RTMP_TIME_BEFORE(pAd->Mlme.Now32, pAd->StaCfg.LastScanTime + (30 * OS_HZ)))
-			goto SKIP_AUTO_SCAN_CONN;
-        else
-            pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
-
-		if ((pAd->StaCfg.bAutoReconnect == TRUE)
-			&& RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)
-			&& (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
-		{
-			if ((pAd->ScanTab.BssNr==0) && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
-			{
-				MLME_SCAN_REQ_STRUCT	   ScanReq;
-
-				if (RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastScanTime + (10 * OS_HZ)))
-				{
-					DBGPRINT(RT_DEBUG_TRACE, ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n", pAd->MlmeAux.AutoReconnectSsid));
-					ScanParmFill(pAd, &ScanReq, (PSTRING) pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen, BSS_ANY, SCAN_ACTIVE);
-					MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
-					pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
-					// Reset Missed scan number
-					pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
-				}
-				else if (pAd->StaCfg.BssType == BSS_ADHOC)	// Quit the forever scan when in a very clean room
-					MlmeAutoReconnectLastSSID(pAd);
-			}
-			else if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
-			{
-				if ((pAd->Mlme.OneSecPeriodicRound % 7) == 0)
-					{
-						MlmeAutoScan(pAd);
-						pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
-					}
-				else
-				{
-#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
-					if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
-					{
-						if ((pAd->Mlme.OneSecPeriodicRound % 5) == 1)
-							MlmeAutoReconnectLastSSID(pAd);
-					}
-					else
-#endif // CARRIER_DETECTION_SUPPORT //
-						MlmeAutoReconnectLastSSID(pAd);
-				}
-			}
-		}
-	}
-
-SKIP_AUTO_SCAN_CONN:
-
-#ifdef DOT11_N_SUPPORT
-    if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap !=0) && (pAd->MacTab.fAnyBASession == FALSE))
-	{
-		pAd->MacTab.fAnyBASession = TRUE;
-		AsicUpdateProtect(pAd, HT_FORCERTSCTS,  ALLN_SETPROTECT, FALSE, FALSE);
-	}
-	else if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap ==0) && (pAd->MacTab.fAnyBASession == TRUE))
-	{
-		pAd->MacTab.fAnyBASession = FALSE;
-		AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode,  ALLN_SETPROTECT, FALSE, FALSE);
-	}
-#endif // DOT11_N_SUPPORT //
-
-
-#ifdef DOT11_N_SUPPORT
-#ifdef DOT11N_DRAFT3
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SCAN_2040))
-		TriEventCounterMaintenance(pAd);
-#endif // DOT11N_DRAFT3 //
-#endif // DOT11_N_SUPPORT //
-
-	return;
-}
-
-// Link down report
-VOID LinkDownExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3)
-{
-	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
-
-	if (pAd != NULL)
-	{
-		MLME_DISASSOC_REQ_STRUCT   DisassocReq;
-
-		if ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) &&
-			(INFRA_ON(pAd)))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("LinkDownExec(): disassociate with current AP...\n"));
-			DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
-			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
-						sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
-
-			pAd->IndicateMediaState = NdisMediaStateDisconnected;
-			RTMP_IndicateMediaState(pAd);
-		    pAd->ExtraInfo = GENERAL_LINK_DOWN;
-		}
-	}
-}
-
-// IRQL = DISPATCH_LEVEL
-VOID MlmeAutoScan(
-	IN PRTMP_ADAPTER pAd)
-{
-	// check CntlMachine.CurrState to avoid collision with NDIS SetOID request
-	if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Driver auto scan\n"));
-		MlmeEnqueue(pAd,
-					MLME_CNTL_STATE_MACHINE,
-					OID_802_11_BSSID_LIST_SCAN,
-					pAd->MlmeAux.AutoReconnectSsidLen,
-					pAd->MlmeAux.AutoReconnectSsid);
-		RTMP_MLME_HANDLER(pAd);
-	}
-}
-
-// IRQL = DISPATCH_LEVEL
-VOID MlmeAutoReconnectLastSSID(
-	IN PRTMP_ADAPTER pAd)
-{
-	if (pAd->StaCfg.bAutoConnectByBssid)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("Driver auto reconnect to last OID_802_11_BSSID setting - %02X:%02X:%02X:%02X:%02X:%02X\n",
-									pAd->MlmeAux.Bssid[0],
-									pAd->MlmeAux.Bssid[1],
-									pAd->MlmeAux.Bssid[2],
-									pAd->MlmeAux.Bssid[3],
-									pAd->MlmeAux.Bssid[4],
-									pAd->MlmeAux.Bssid[5]));
-
-		pAd->MlmeAux.Channel = pAd->CommonCfg.Channel;
-		MlmeEnqueue(pAd,
-			 MLME_CNTL_STATE_MACHINE,
-			 OID_802_11_BSSID,
-			 MAC_ADDR_LEN,
-			 pAd->MlmeAux.Bssid);
-
-		pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-
-		RTMP_MLME_HANDLER(pAd);
-	}
-	// check CntlMachine.CurrState to avoid collision with NDIS SetOID request
-	else if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
-		(MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
-	{
-		NDIS_802_11_SSID OidSsid;
-		OidSsid.SsidLength = pAd->MlmeAux.AutoReconnectSsidLen;
-		NdisMoveMemory(OidSsid.Ssid, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
-
-		DBGPRINT(RT_DEBUG_TRACE, ("Driver auto reconnect to last OID_802_11_SSID setting - %s, len - %d\n", pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen));
-		MlmeEnqueue(pAd,
-					MLME_CNTL_STATE_MACHINE,
-					OID_802_11_SSID,
-					sizeof(NDIS_802_11_SSID),
-					&OidSsid);
-		RTMP_MLME_HANDLER(pAd);
-	}
-}
-
-
-/*
-	==========================================================================
-	Description:
-		This routine checks if there're other APs out there capable for
-		roaming. Caller should call this routine only when Link up in INFRA mode
-		and channel quality is below CQI_GOOD_THRESHOLD.
-
-	IRQL = DISPATCH_LEVEL
-
-	Output:
-	==========================================================================
- */
-VOID MlmeCheckForRoaming(
-	IN PRTMP_ADAPTER pAd,
-	IN ULONG	Now32)
-{
-	USHORT	   i;
-	BSS_TABLE  *pRoamTab = &pAd->MlmeAux.RoamTab;
-	BSS_ENTRY  *pBss;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForRoaming\n"));
-	// put all roaming candidates into RoamTab, and sort in RSSI order
-	BssTableInit(pRoamTab);
-	for (i = 0; i < pAd->ScanTab.BssNr; i++)
-	{
-		pBss = &pAd->ScanTab.BssEntry[i];
-
-		if ((pBss->LastBeaconRxTime + pAd->StaCfg.BeaconLostTime) < Now32)
-			continue;	 // AP disappear
-		if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING)
-			continue;	 // RSSI too weak. forget it.
-		if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
-			continue;	 // skip current AP
-		if (pBss->Rssi < (pAd->StaCfg.RssiSample.LastRssi0 + RSSI_DELTA))
-			continue;	 // only AP with stronger RSSI is eligible for roaming
-
-		// AP passing all above rules is put into roaming candidate table
-		NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
-		pRoamTab->BssNr += 1;
-	}
-
-	if (pRoamTab->BssNr > 0)
-	{
-		// check CntlMachine.CurrState to avoid collision with NDIS SetOID request
-		if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
-		{
-			pAd->RalinkCounters.PoorCQIRoamingCount ++;
-			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
-			RTMP_MLME_HANDLER(pAd);
-		}
-	}
-	DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForRoaming(# of candidate= %d)\n",pRoamTab->BssNr));
-}
-
-/*
-	==========================================================================
-	Description:
-		This routine checks if there're other APs out there capable for
-		roaming. Caller should call this routine only when link up in INFRA mode
-		and channel quality is below CQI_GOOD_THRESHOLD.
-
-	IRQL = DISPATCH_LEVEL
-
-	Output:
-	==========================================================================
- */
-BOOLEAN MlmeCheckForFastRoaming(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	USHORT		i;
-	BSS_TABLE	*pRoamTab = &pAd->MlmeAux.RoamTab;
-	BSS_ENTRY	*pBss;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForFastRoaming\n"));
-	// put all roaming candidates into RoamTab, and sort in RSSI order
-	BssTableInit(pRoamTab);
-	for (i = 0; i < pAd->ScanTab.BssNr; i++)
-	{
-		pBss = &pAd->ScanTab.BssEntry[i];
-
-        if ((pBss->Rssi <= -50) && (pBss->Channel == pAd->CommonCfg.Channel))
-			continue;	 // RSSI too weak. forget it.
-		if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
-			continue;	 // skip current AP
-		if (!SSID_EQUAL(pBss->Ssid, pBss->SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
-			continue;	 // skip different SSID
-        if (pBss->Rssi < (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) + RSSI_DELTA))
-			continue;	 // skip AP without better RSSI
-
-        DBGPRINT(RT_DEBUG_TRACE, ("LastRssi0 = %d, pBss->Rssi = %d\n", RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2), pBss->Rssi));
-		// AP passing all above rules is put into roaming candidate table
-		NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
-		pRoamTab->BssNr += 1;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr));
-	if (pRoamTab->BssNr > 0)
-	{
-		// check CntlMachine.CurrState to avoid collision with NDIS SetOID request
-		if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
-		{
-			pAd->RalinkCounters.PoorCQIRoamingCount ++;
-			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
-			RTMP_MLME_HANDLER(pAd);
-			return TRUE;
-		}
-	}
-
-	return FALSE;
-}
-
-VOID MlmeSetTxRate(
-	IN PRTMP_ADAPTER		pAd,
-	IN PMAC_TABLE_ENTRY		pEntry,
-	IN PRTMP_TX_RATE_SWITCH	pTxRate)
-{
-	UCHAR	MaxMode = MODE_OFDM;
-
-#ifdef DOT11_N_SUPPORT
-	MaxMode = MODE_HTGREENFIELD;
-
-	if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC) && (pAd->Antenna.field.TxPath == 2))
-		pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE;
-	else
-#endif // DOT11_N_SUPPORT //
-		pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
-
-	if (pTxRate->CurrMCS < MCS_AUTO)
-		pAd->StaCfg.HTPhyMode.field.MCS = pTxRate->CurrMCS;
-
-	if (pAd->StaCfg.HTPhyMode.field.MCS > 7)
-		pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
-
-	if (ADHOC_ON(pAd))
-	{
-		// If peer adhoc is b-only mode, we can't send 11g rate.
-		pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
-		pEntry->HTPhyMode.field.STBC	= STBC_NONE;
-
-		//
-		// For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary
-		//
-		pEntry->HTPhyMode.field.MODE	= pTxRate->Mode;
-		pEntry->HTPhyMode.field.ShortGI	= pAd->StaCfg.HTPhyMode.field.ShortGI;
-		pEntry->HTPhyMode.field.MCS		= pAd->StaCfg.HTPhyMode.field.MCS;
-
-		// Patch speed error in status page
-		pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE;
-	}
-	else
-    {
-		if (pTxRate->Mode <= MaxMode)
-		pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode;
-
-#ifdef DOT11_N_SUPPORT
-        if (pTxRate->ShortGI && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI))
-			pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400;
-		else
-#endif // DOT11_N_SUPPORT //
-			pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
-
-#ifdef DOT11_N_SUPPORT
-		// Reexam each bandwidth's SGI support.
-		if (pAd->StaCfg.HTPhyMode.field.ShortGI == GI_400)
-		{
-			if ((pEntry->HTPhyMode.field.BW == BW_20) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE)))
-				pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
-			if ((pEntry->HTPhyMode.field.BW == BW_40) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE)))
-				pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
-		}
-
-        // Turn RTS/CTS rate to 6Mbps.
-		if ((pEntry->HTPhyMode.field.MCS == 0) && (pAd->StaCfg.HTPhyMode.field.MCS != 0))
-		{
-			pEntry->HTPhyMode.field.MCS		= pAd->StaCfg.HTPhyMode.field.MCS;
-			if (pAd->MacTab.fAnyBASession)
-			{
-				AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
-			}
-			else
-			{
-				AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
-			}
-		}
-		else if ((pEntry->HTPhyMode.field.MCS == 8) && (pAd->StaCfg.HTPhyMode.field.MCS != 8))
-		{
-			pEntry->HTPhyMode.field.MCS		= pAd->StaCfg.HTPhyMode.field.MCS;
-			if (pAd->MacTab.fAnyBASession)
-			{
-				AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
-			}
-			else
-			{
-				AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
-			}
-		}
-		else if ((pEntry->HTPhyMode.field.MCS != 0) && (pAd->StaCfg.HTPhyMode.field.MCS == 0))
-		{
-			AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
-
-		}
-		else if ((pEntry->HTPhyMode.field.MCS != 8) && (pAd->StaCfg.HTPhyMode.field.MCS == 8))
-		{
-			AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
-		}
-#endif // DOT11_N_SUPPORT //
-
-		pEntry->HTPhyMode.field.STBC	= pAd->StaCfg.HTPhyMode.field.STBC;
-		pEntry->HTPhyMode.field.ShortGI	= pAd->StaCfg.HTPhyMode.field.ShortGI;
-		pEntry->HTPhyMode.field.MCS		= pAd->StaCfg.HTPhyMode.field.MCS;
-		pEntry->HTPhyMode.field.MODE	= pAd->StaCfg.HTPhyMode.field.MODE;
-#ifdef DOT11_N_SUPPORT
-        if ((pAd->StaCfg.MaxHTPhyMode.field.MODE == MODE_HTGREENFIELD) &&
-            pAd->WIFItestbed.bGreenField)
-            pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD;
-#endif // DOT11_N_SUPPORT //
-    }
-
-    pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
-}
-
-/*
-	==========================================================================
-	Description:
-		This routine calculates the acumulated TxPER of eaxh TxRate. And
-		according to the calculation result, change CommonCfg.TxRate which
-		is the stable TX Rate we expect the Radio situation could sustained.
-
-		CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate}
-	Output:
-		CommonCfg.TxRate -
-
-	IRQL = DISPATCH_LEVEL
-
-	NOTE:
-		call this routine every second
-	==========================================================================
- */
-VOID MlmeDynamicTxRateSwitching(
-	IN PRTMP_ADAPTER pAd)
-{
-	UCHAR					UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx;
-	ULONG					i, AccuTxTotalCnt = 0, TxTotalCnt;
-	ULONG					TxErrorRatio = 0;
-	BOOLEAN					bTxRateChanged = FALSE, bUpgradeQuality = FALSE;
-	PRTMP_TX_RATE_SWITCH	pCurrTxRate, pNextTxRate = NULL;
-	PUCHAR					pTable;
-	UCHAR					TableSize = 0;
-	UCHAR					InitTxRateIdx = 0, TrainUp, TrainDown;
-	CHAR					Rssi, RssiOffset = 0;
-	TX_STA_CNT1_STRUC		StaTx1;
-	TX_STA_CNT0_STRUC		TxStaCnt0;
-	ULONG					TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
-	MAC_TABLE_ENTRY			*pEntry;
-	RSSI_SAMPLE				*pRssi = &pAd->StaCfg.RssiSample;
-
-#ifdef RALINK_ATE
-	if (ATE_ON(pAd))
-	{
-		return;
-	}
-#endif // RALINK_ATE //
-
-	//
-	// walk through MAC table, see if need to change AP's TX rate toward each entry
-	//
-	for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
-	{
-		pEntry = &pAd->MacTab.Content[i];
-
-	// check if this entry need to switch rate automatically
-		if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
-			continue;
-
-		if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls))
-		{
-			Rssi = RTMPMaxRssi(pAd,
-							   pRssi->AvgRssi0,
-							   pRssi->AvgRssi1,
-							   pRssi->AvgRssi2);
-
-			// Update statistic counter
-			RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
-			RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
-			pAd->bUpdateBcnCntDone = TRUE;
-			TxRetransmit = StaTx1.field.TxRetransmit;
-			TxSuccess = StaTx1.field.TxSuccess;
-			TxFailCount = TxStaCnt0.field.TxFailCount;
-			TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
-
-			pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
-			pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
-			pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
-			pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
-			pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
-			pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
-
-			// if no traffic in the past 1-sec period, don't change TX rate,
-			// but clear all bad history. because the bad history may affect the next
-			// Chariot throughput test
-			AccuTxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
-						 pAd->RalinkCounters.OneSecTxRetryOkCount +
-						 pAd->RalinkCounters.OneSecTxFailCount;
-
-			if (TxTotalCnt)
-				TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
-		}
-		else
-		{
-			if (INFRA_ON(pAd) && (i == 1))
-				Rssi = RTMPMaxRssi(pAd,
-								   pRssi->AvgRssi0,
-								   pRssi->AvgRssi1,
-								   pRssi->AvgRssi2);
-			else
-				Rssi = RTMPMaxRssi(pAd,
-								   pEntry->RssiSample.AvgRssi0,
-								   pEntry->RssiSample.AvgRssi1,
-								   pEntry->RssiSample.AvgRssi2);
-
-			TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
-				 pEntry->OneSecTxRetryOkCount +
-				 pEntry->OneSecTxFailCount;
-
-			if (TxTotalCnt)
-				TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
-		}
-
-		if (TxTotalCnt)
-		{
-			/*
-				Three AdHoc connections can not work normally if one AdHoc connection is disappeared from a heavy traffic environment generated by ping tool
-				We force to set LongRtyLimit and ShortRtyLimit to 0 to stop retransmitting packet, after a while, resoring original settings
-			*/
-			if (TxErrorRatio == 100)
-			{
-				TX_RTY_CFG_STRUC	TxRtyCfg,TxRtyCfgtmp;
-				ULONG	Index;
-				ULONG	MACValue;
-
-				RTMP_IO_READ32(pAd, TX_RTY_CFG, &TxRtyCfg.word);
-				TxRtyCfgtmp.word = TxRtyCfg.word;
-				TxRtyCfg.field.LongRtyLimit = 0x0;
-				TxRtyCfg.field.ShortRtyLimit = 0x0;
-				RTMP_IO_WRITE32(pAd, TX_RTY_CFG, TxRtyCfg.word);
-
-				RTMPusecDelay(1);
-
-				Index = 0;
-				MACValue = 0;
-				do
-				{
-					RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
-					if ((MACValue & 0xffffff) == 0)
-						break;
-					Index++;
-					RTMPusecDelay(1000);
-				}while((Index < 330)&&(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)));
-
-				RTMP_IO_READ32(pAd, TX_RTY_CFG, &TxRtyCfg.word);
-				TxRtyCfg.field.LongRtyLimit = TxRtyCfgtmp.field.LongRtyLimit;
-				TxRtyCfg.field.ShortRtyLimit = TxRtyCfgtmp.field.ShortRtyLimit;
-				RTMP_IO_WRITE32(pAd, TX_RTY_CFG, TxRtyCfg.word);
-			}
-		}
-
-		CurrRateIdx = pEntry->CurrTxRateIndex;
-
-		MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
-
-		if (CurrRateIdx >= TableSize)
-		{
-			CurrRateIdx = TableSize - 1;
-		}
-
-		// When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex.
-		// So need to sync here.
-		pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
-		if ((pEntry->HTPhyMode.field.MCS != pCurrTxRate->CurrMCS)
-			//&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
-			)
-		{
-
-			// Need to sync Real Tx rate and our record.
-			// Then return for next DRS.
-			pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(InitTxRateIdx+1)*5];
-			pEntry->CurrTxRateIndex = InitTxRateIdx;
-			MlmeSetTxRate(pAd, pEntry, pCurrTxRate);
-
-			// reset all OneSecTx counters
-			RESET_ONE_SEC_TX_CNT(pEntry);
-			continue;
-		}
-
-		// decide the next upgrade rate and downgrade rate, if any
-		if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
-		{
-			UpRateIdx = CurrRateIdx + 1;
-			DownRateIdx = CurrRateIdx -1;
-		}
-		else if (CurrRateIdx == 0)
-		{
-			UpRateIdx = CurrRateIdx + 1;
-			DownRateIdx = CurrRateIdx;
-		}
-		else if (CurrRateIdx == (TableSize - 1))
-		{
-			UpRateIdx = CurrRateIdx;
-			DownRateIdx = CurrRateIdx - 1;
-		}
-
-		pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
-
-#ifdef DOT11_N_SUPPORT
-		if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
-		{
-			TrainUp		= (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
-			TrainDown	= (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
-		}
-		else
-#endif // DOT11_N_SUPPORT //
-		{
-			TrainUp		= pCurrTxRate->TrainUp;
-			TrainDown	= pCurrTxRate->TrainDown;
-		}
-
-		//pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction;
-
-		//
-		// Keep the last time TxRateChangeAction status.
-		//
-		pEntry->LastTimeTxRateChangeAction = pEntry->LastSecTxRateChangeAction;
-
-
-
-		//
-		// CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
-		//         (criteria copied from RT2500 for Netopia case)
-		//
-		if (TxTotalCnt <= 15)
-		{
-			CHAR	idx = 0;
-			UCHAR	TxRateIdx;
-			UCHAR	MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0,  MCS5 =0, MCS6 = 0, MCS7 = 0;
-	        UCHAR	MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
-			UCHAR	MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0; // 3*3
-
-			// check the existence and index of each needed MCS
-			while (idx < pTable[0])
-			{
-				pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(idx+1)*5];
-
-				if (pCurrTxRate->CurrMCS == MCS_0)
-				{
-					MCS0 = idx;
-				}
-				else if (pCurrTxRate->CurrMCS == MCS_1)
-				{
-					MCS1 = idx;
-				}
-				else if (pCurrTxRate->CurrMCS == MCS_2)
-				{
-					MCS2 = idx;
-				}
-				else if (pCurrTxRate->CurrMCS == MCS_3)
-				{
-					MCS3 = idx;
-				}
-				else if (pCurrTxRate->CurrMCS == MCS_4)
-				{
-					MCS4 = idx;
-				}
-	            else if (pCurrTxRate->CurrMCS == MCS_5)
-	            {
-	                MCS5 = idx;
-	            }
-	            else if (pCurrTxRate->CurrMCS == MCS_6)
-	            {
-	                MCS6 = idx;
-	            }
-				//else if (pCurrTxRate->CurrMCS == MCS_7)
-				else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800))	// prevent the highest MCS using short GI when 1T and low throughput
-				{
-					MCS7 = idx;
-				}
-				else if (pCurrTxRate->CurrMCS == MCS_12)
-				{
-					MCS12 = idx;
-				}
-				else if (pCurrTxRate->CurrMCS == MCS_13)
-				{
-					MCS13 = idx;
-				}
-				else if (pCurrTxRate->CurrMCS == MCS_14)
-				{
-					MCS14 = idx;
-				}
-				//else if ((pCurrTxRate->CurrMCS == MCS_15)/* && (pCurrTxRate->ShortGI == GI_800)*/)	//we hope to use ShortGI as initial rate
-				else if ((pCurrTxRate->CurrMCS == MCS_15) && (pCurrTxRate->ShortGI == GI_800))	//we hope to use ShortGI as initial rate, however Atheros's chip has bugs when short GI
-				{
-					MCS15 = idx;
-				}
-				else if (pCurrTxRate->CurrMCS == MCS_20) // 3*3
-				{
-					MCS20 = idx;
-				}
-				else if (pCurrTxRate->CurrMCS == MCS_21)
-				{
-					MCS21 = idx;
-				}
-				else if (pCurrTxRate->CurrMCS == MCS_22)
-				{
-					MCS22 = idx;
-				}
-				else if (pCurrTxRate->CurrMCS == MCS_23)
-				{
-					MCS23 = idx;
-				}
-				idx ++;
-			}
-
-			if (pAd->LatchRfRegs.Channel <= 14)
-			{
-				if (pAd->NicConfig2.field.ExternalLNAForG)
-				{
-					RssiOffset = 2;
-				}
-				else
-				{
-					RssiOffset = 5;
-				}
-			}
-			else
-			{
-				if (pAd->NicConfig2.field.ExternalLNAForA)
-				{
-					RssiOffset = 5;
-				}
-				else
-				{
-					RssiOffset = 8;
-				}
-			}
-#ifdef DOT11_N_SUPPORT
-			/*if (MCS15)*/
-			if ((pTable == RateSwitchTable11BGN3S) ||
-				(pTable == RateSwitchTable11N3S) ||
-				(pTable == RateSwitchTable))
-			{// N mode with 3 stream // 3*3
-				if (MCS23 && (Rssi >= -70))
-					TxRateIdx = MCS23;
-				else if (MCS22 && (Rssi >= -72))
-					TxRateIdx = MCS22;
-		    else if (MCS21 && (Rssi >= -76))
-					TxRateIdx = MCS21;
-				else if (MCS20 && (Rssi >= -78))
-					TxRateIdx = MCS20;
-			else if (MCS4 && (Rssi >= -82))
-				TxRateIdx = MCS4;
-			else if (MCS3 && (Rssi >= -84))
-				TxRateIdx = MCS3;
-			else if (MCS2 && (Rssi >= -86))
-				TxRateIdx = MCS2;
-			else if (MCS1 && (Rssi >= -88))
-				TxRateIdx = MCS1;
-			else
-				TxRateIdx = MCS0;
-		}
-//		else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand) || (pTable == RateSwitchTable))
-		else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand)) // 3*3
-			{// N mode with 2 stream
-				if (MCS15 && (Rssi >= (-70+RssiOffset)))
-					TxRateIdx = MCS15;
-				else if (MCS14 && (Rssi >= (-72+RssiOffset)))
-					TxRateIdx = MCS14;
-				else if (MCS13 && (Rssi >= (-76+RssiOffset)))
-					TxRateIdx = MCS13;
-				else if (MCS12 && (Rssi >= (-78+RssiOffset)))
-					TxRateIdx = MCS12;
-				else if (MCS4 && (Rssi >= (-82+RssiOffset)))
-					TxRateIdx = MCS4;
-				else if (MCS3 && (Rssi >= (-84+RssiOffset)))
-					TxRateIdx = MCS3;
-				else if (MCS2 && (Rssi >= (-86+RssiOffset)))
-					TxRateIdx = MCS2;
-				else if (MCS1 && (Rssi >= (-88+RssiOffset)))
-					TxRateIdx = MCS1;
-				else
-					TxRateIdx = MCS0;
-			}
-			else if ((pTable == RateSwitchTable11BGN1S) || (pTable == RateSwitchTable11N1S))
-			{// N mode with 1 stream
-				if (MCS7 && (Rssi > (-72+RssiOffset)))
-					TxRateIdx = MCS7;
-				else if (MCS6 && (Rssi > (-74+RssiOffset)))
-					TxRateIdx = MCS6;
-				else if (MCS5 && (Rssi > (-77+RssiOffset)))
-					TxRateIdx = MCS5;
-				else if (MCS4 && (Rssi > (-79+RssiOffset)))
-					TxRateIdx = MCS4;
-				else if (MCS3 && (Rssi > (-81+RssiOffset)))
-					TxRateIdx = MCS3;
-				else if (MCS2 && (Rssi > (-83+RssiOffset)))
-					TxRateIdx = MCS2;
-				else if (MCS1 && (Rssi > (-86+RssiOffset)))
-					TxRateIdx = MCS1;
-				else
-					TxRateIdx = MCS0;
-			}
-			else
-#endif // DOT11_N_SUPPORT //
-			{// Legacy mode
-				if (MCS7 && (Rssi > -70))
-					TxRateIdx = MCS7;
-				else if (MCS6 && (Rssi > -74))
-					TxRateIdx = MCS6;
-				else if (MCS5 && (Rssi > -78))
-					TxRateIdx = MCS5;
-				else if (MCS4 && (Rssi > -82))
-					TxRateIdx = MCS4;
-				else if (MCS4 == 0)	// for B-only mode
-					TxRateIdx = MCS3;
-				else if (MCS3 && (Rssi > -85))
-					TxRateIdx = MCS3;
-				else if (MCS2 && (Rssi > -87))
-					TxRateIdx = MCS2;
-				else if (MCS1 && (Rssi > -90))
-					TxRateIdx = MCS1;
-				else
-					TxRateIdx = MCS0;
-			}
-
-	//		if (TxRateIdx != pAd->CommonCfg.TxRateIndex)
-			{
-				pEntry->CurrTxRateIndex = TxRateIdx;
-				pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
-				MlmeSetTxRate(pAd, pEntry, pNextTxRate);
-			}
-
-			NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
-			NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
-			pEntry->fLastSecAccordingRSSI = TRUE;
-			// reset all OneSecTx counters
-			RESET_ONE_SEC_TX_CNT(pEntry);
-
-			continue;
-		}
-
-		if (pEntry->fLastSecAccordingRSSI == TRUE)
-		{
-			pEntry->fLastSecAccordingRSSI = FALSE;
-			pEntry->LastSecTxRateChangeAction = 0;
-			// reset all OneSecTx counters
-			RESET_ONE_SEC_TX_CNT(pEntry);
-
-			continue;
-		}
-
-		do
-		{
-			BOOLEAN	bTrainUpDown = FALSE;
-
-			pEntry->CurrTxRateStableTime ++;
-
-			// downgrade TX quality if PER >= Rate-Down threshold
-			if (TxErrorRatio >= TrainDown)
-			{
-				bTrainUpDown = TRUE;
-				pEntry->TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
-			}
-			// upgrade TX quality if PER <= Rate-Up threshold
-			else if (TxErrorRatio <= TrainUp)
-			{
-				bTrainUpDown = TRUE;
-				bUpgradeQuality = TRUE;
-				if (pEntry->TxQuality[CurrRateIdx])
-					pEntry->TxQuality[CurrRateIdx] --;  // quality very good in CurrRate
-
-				if (pEntry->TxRateUpPenalty)
-					pEntry->TxRateUpPenalty --;
-				else if (pEntry->TxQuality[UpRateIdx])
-					pEntry->TxQuality[UpRateIdx] --;    // may improve next UP rate's quality
-			}
-
-			pEntry->PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
-
-			if (bTrainUpDown)
-			{
-				// perform DRS - consider TxRate Down first, then rate up.
-				if ((CurrRateIdx != DownRateIdx) && (pEntry->TxQuality[CurrRateIdx] >= DRS_TX_QUALITY_WORST_BOUND))
-				{
-					pEntry->CurrTxRateIndex = DownRateIdx;
-				}
-				else if ((CurrRateIdx != UpRateIdx) && (pEntry->TxQuality[UpRateIdx] <= 0))
-				{
-					pEntry->CurrTxRateIndex = UpRateIdx;
-				}
-			}
-		} while (FALSE);
-
-		// if rate-up happen, clear all bad history of all TX rates
-		if (pEntry->CurrTxRateIndex > CurrRateIdx)
-		{
-			pEntry->CurrTxRateStableTime = 0;
-			pEntry->TxRateUpPenalty = 0;
-			pEntry->LastSecTxRateChangeAction = 1; // rate UP
-			NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
-			NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
-
-			//
-			// For TxRate fast train up
-			//
-			if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
-			{
-				RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
-
-				pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
-			}
-			bTxRateChanged = TRUE;
-		}
-		// if rate-down happen, only clear DownRate's bad history
-		else if (pEntry->CurrTxRateIndex < CurrRateIdx)
-		{
-			pEntry->CurrTxRateStableTime = 0;
-			pEntry->TxRateUpPenalty = 0;           // no penalty
-			pEntry->LastSecTxRateChangeAction = 2; // rate DOWN
-			pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0;
-			pEntry->PER[pEntry->CurrTxRateIndex] = 0;
-
-			//
-			// For TxRate fast train down
-			//
-			if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
-			{
-				RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
-
-				pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
-			}
-			bTxRateChanged = TRUE;
-		}
-		else
-		{
-			pEntry->LastSecTxRateChangeAction = 0; // rate no change
-			bTxRateChanged = FALSE;
-		}
-
-		pEntry->LastTxOkCount = TxSuccess;
-
-		{
-			UCHAR tmpTxRate;
-
-			// to fix tcp ack issue
-			if (!bTxRateChanged && (pAd->RalinkCounters.OneSecReceivedByteCount > (pAd->RalinkCounters.OneSecTransmittedByteCount * 5)))
-			{
-				tmpTxRate = DownRateIdx;
-				DBGPRINT_RAW(RT_DEBUG_TRACE,("DRS: Rx(%d) is 5 times larger than Tx(%d), use low rate (curr=%d, tmp=%d)\n",
-					pAd->RalinkCounters.OneSecReceivedByteCount, pAd->RalinkCounters.OneSecTransmittedByteCount, pEntry->CurrTxRateIndex, tmpTxRate));
-			}
-			else
-			{
-				tmpTxRate = pEntry->CurrTxRateIndex;
-			}
-
-			pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(tmpTxRate+1)*5];
-			if (bTxRateChanged && pNextTxRate)
-			{
-				MlmeSetTxRate(pAd, pEntry, pNextTxRate);
-			}
-		}
-		// reset all OneSecTx counters
-		RESET_ONE_SEC_TX_CNT(pEntry);
-	}
-}
-
-/*
-	========================================================================
-	Routine Description:
-		Station side, Auto TxRate faster train up timer call back function.
-
-	Arguments:
-		SystemSpecific1			- Not used.
-		FunctionContext			- Pointer to our Adapter context.
-		SystemSpecific2			- Not used.
-		SystemSpecific3			- Not used.
-
-	Return Value:
-		None
-
-	========================================================================
-*/
-VOID StaQuickResponeForRateUpExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3)
-{
-	PRTMP_ADAPTER			pAd = (PRTMP_ADAPTER)FunctionContext;
-	UCHAR					UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0;
-	ULONG					TxTotalCnt;
-	ULONG					TxErrorRatio = 0;
-	BOOLEAN					bTxRateChanged; //, bUpgradeQuality = FALSE;
-	PRTMP_TX_RATE_SWITCH	pCurrTxRate, pNextTxRate = NULL;
-	PUCHAR					pTable;
-	UCHAR					TableSize = 0;
-	UCHAR					InitTxRateIdx = 0, TrainUp, TrainDown;
-	TX_STA_CNT1_STRUC		StaTx1;
-	TX_STA_CNT0_STRUC		TxStaCnt0;
-	CHAR					Rssi, ratio;
-	ULONG					TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
-	MAC_TABLE_ENTRY			*pEntry;
-	ULONG					i;
-
-	pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
-
-    //
-    // walk through MAC table, see if need to change AP's TX rate toward each entry
-    //
-	for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
-	{
-		pEntry = &pAd->MacTab.Content[i];
-
-		// check if this entry need to switch rate automatically
-		if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
-			continue;
-
-		if (INFRA_ON(pAd) && (i == 1))
-			Rssi = RTMPMaxRssi(pAd,
-							   pAd->StaCfg.RssiSample.AvgRssi0,
-							   pAd->StaCfg.RssiSample.AvgRssi1,
-							   pAd->StaCfg.RssiSample.AvgRssi2);
-		else
-			Rssi = RTMPMaxRssi(pAd,
-							   pEntry->RssiSample.AvgRssi0,
-							   pEntry->RssiSample.AvgRssi1,
-							   pEntry->RssiSample.AvgRssi2);
-
-	CurrRateIdx = pAd->CommonCfg.TxRateIndex;
-
-			MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
-
-	// decide the next upgrade rate and downgrade rate, if any
-	if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
-	{
-		UpRateIdx = CurrRateIdx + 1;
-		DownRateIdx = CurrRateIdx -1;
-	}
-	else if (CurrRateIdx == 0)
-	{
-		UpRateIdx = CurrRateIdx + 1;
-		DownRateIdx = CurrRateIdx;
-	}
-	else if (CurrRateIdx == (TableSize - 1))
-	{
-		UpRateIdx = CurrRateIdx;
-		DownRateIdx = CurrRateIdx - 1;
-	}
-
-	pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
-
-#ifdef DOT11_N_SUPPORT
-	if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
-	{
-		TrainUp		= (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
-		TrainDown	= (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
-	}
-	else
-#endif // DOT11_N_SUPPORT //
-	{
-		TrainUp		= pCurrTxRate->TrainUp;
-		TrainDown	= pCurrTxRate->TrainDown;
-	}
-
-		if (pAd->MacTab.Size == 1)
-		{
-	// Update statistic counter
-	RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
-	RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
-
-	TxRetransmit = StaTx1.field.TxRetransmit;
-	TxSuccess = StaTx1.field.TxSuccess;
-	TxFailCount = TxStaCnt0.field.TxFailCount;
-	TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
-
-	pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
-	pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
-	pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
-			pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
-			pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
-			pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
-
-	if (TxTotalCnt)
-		TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
-		}
-		else
-		{
-			TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
-				 pEntry->OneSecTxRetryOkCount +
-				 pEntry->OneSecTxFailCount;
-
-			if (TxTotalCnt)
-				TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
-		}
-
-
-	//
-	// CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
-	//         (criteria copied from RT2500 for Netopia case)
-	//
-	if (TxTotalCnt <= 12)
-	{
-		NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
-		NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
-
-		if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
-		{
-			pAd->CommonCfg.TxRateIndex = DownRateIdx;
-			pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
-		}
-		else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
-		{
-			pAd->CommonCfg.TxRateIndex = UpRateIdx;
-		}
-
-		DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: TxTotalCnt <= 15, train back to original rate \n"));
-		return;
-	}
-
-	do
-	{
-		ULONG OneSecTxNoRetryOKRationCount;
-
-		if (pAd->DrsCounters.LastTimeTxRateChangeAction == 0)
-			ratio = 5;
-		else
-			ratio = 4;
-
-		// downgrade TX quality if PER >= Rate-Down threshold
-		if (TxErrorRatio >= TrainDown)
-		{
-			pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
-		}
-
-		pAd->DrsCounters.PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
-
-		OneSecTxNoRetryOKRationCount = (TxSuccess * ratio);
-
-		// perform DRS - consider TxRate Down first, then rate up.
-		if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
-		{
-			if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
-		{
-			pAd->CommonCfg.TxRateIndex = DownRateIdx;
-				pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
-
-			}
-
-		}
-		else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
-		{
-			if ((TxErrorRatio >= 50) || (TxErrorRatio >= TrainDown))
-			{
-
-			}
-			else if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
-			{
-				pAd->CommonCfg.TxRateIndex = UpRateIdx;
-			}
-		}
-	}while (FALSE);
-
-	// if rate-up happen, clear all bad history of all TX rates
-	if (pAd->CommonCfg.TxRateIndex > CurrRateIdx)
-	{
-		pAd->DrsCounters.TxRateUpPenalty = 0;
-		NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
-		NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
-			bTxRateChanged = TRUE;
-	}
-	// if rate-down happen, only clear DownRate's bad history
-	else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx)
-	{
-		DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: --TX rate from %d to %d \n", CurrRateIdx, pAd->CommonCfg.TxRateIndex));
-
-		pAd->DrsCounters.TxRateUpPenalty = 0;           // no penalty
-		pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] = 0;
-		pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0;
-			bTxRateChanged = TRUE;
-	}
-	else
-	{
-		bTxRateChanged = FALSE;
-	}
-
-	pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pAd->CommonCfg.TxRateIndex+1)*5];
-	if (bTxRateChanged && pNextTxRate)
-	{
-			MlmeSetTxRate(pAd, pEntry, pNextTxRate);
-		}
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-		This routine is executed periodically inside MlmePeriodicExec() after
-		association with an AP.
-		It checks if StaCfg.Psm is consistent with user policy (recorded in
-		StaCfg.WindowsPowerMode). If not, enforce user policy. However,
-		there're some conditions to consider:
-		1. we don't support power-saving in ADHOC mode, so Psm=PWR_ACTIVE all
-		   the time when Mibss==TRUE
-		2. When link up in INFRA mode, Psm should not be switch to PWR_SAVE
-		   if outgoing traffic available in TxRing or MgmtRing.
-	Output:
-		1. change pAd->StaCfg.Psm to PWR_SAVE or leave it untouched
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID MlmeCheckPsmChange(
-	IN PRTMP_ADAPTER pAd,
-	IN ULONG	Now32)
-{
-	ULONG	PowerMode;
-
-	// condition -
-	// 1. Psm maybe ON only happen in INFRASTRUCTURE mode
-	// 2. user wants either MAX_PSP or FAST_PSP
-	// 3. but current psm is not in PWR_SAVE
-	// 4. CNTL state machine is not doing SCANning
-	// 5. no TX SUCCESS event for the past 1-sec period
-	PowerMode = pAd->StaCfg.WindowsPowerMode;
-
-	if (INFRA_ON(pAd) &&
-		(PowerMode != Ndis802_11PowerModeCAM) &&
-		(pAd->StaCfg.Psm == PWR_ACTIVE) &&
-//		(! RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-		(pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)&&
-		RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP)
-		 /*&&
-		(pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
-		(pAd->RalinkCounters.OneSecTxRetryOkCount == 0)*/)
-	{
-		NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
-		pAd->RalinkCounters.RxCountSinceLastNULL = 0;
-		RTMP_SET_PSM_BIT(pAd, PWR_SAVE);
-		if (!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
-		{
-			RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
-		}
-		else
-		{
-			RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
-		}
-	}
-}
-
-// IRQL = PASSIVE_LEVEL
-// IRQL = DISPATCH_LEVEL
-VOID MlmeSetPsmBit(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT psm)
-{
-	AUTO_RSP_CFG_STRUC csr4;
-
-	pAd->StaCfg.Psm = psm;
-	RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
-	csr4.field.AckCtsPsmBit = (psm == PWR_SAVE)? 1:0;
-	RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
-	DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetPsmBit = %d\n", psm));
-}
-#endif // CONFIG_STA_SUPPORT //
-
-/*
-	==========================================================================
-	Description:
-		This routine calculates TxPER, RxPER of the past N-sec period. And
-		according to the calculation result, ChannelQuality is calculated here
-		to decide if current AP is still doing the job.
-
-		If ChannelQuality is not good, a ROAMing attempt may be tried later.
-	Output:
-		StaCfg.ChannelQuality - 0..100
-
-	IRQL = DISPATCH_LEVEL
-
-	NOTE: This routine decide channle quality based on RX CRC error ratio.
-		Caller should make sure a function call to NICUpdateRawCounters(pAd)
-		is performed right before this routine, so that this routine can decide
-		channel quality based on the most up-to-date information
-	==========================================================================
- */
-VOID MlmeCalculateChannelQuality(
-	IN PRTMP_ADAPTER pAd,
-	IN PMAC_TABLE_ENTRY pMacEntry,
-	IN ULONG Now32)
-{
-	ULONG TxOkCnt, TxCnt, TxPER, TxPRR;
-	ULONG RxCnt, RxPER;
-	UCHAR NorRssi;
-	CHAR  MaxRssi;
-	RSSI_SAMPLE *pRssiSample = NULL;
-	UINT32 OneSecTxNoRetryOkCount = 0;
-	UINT32 OneSecTxRetryOkCount = 0;
-	UINT32 OneSecTxFailCount = 0;
-	UINT32 OneSecRxOkCnt = 0;
-	UINT32 OneSecRxFcsErrCnt = 0;
-	ULONG ChannelQuality = 0;  // 0..100, Channel Quality Indication for Roaming
-#ifdef CONFIG_STA_SUPPORT
-	ULONG BeaconLostTime = pAd->StaCfg.BeaconLostTime;
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef CONFIG_STA_SUPPORT
-#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
-	// longer beacon lost time when carrier detection enabled
-	if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
-	{
-		BeaconLostTime = pAd->StaCfg.BeaconLostTime + (pAd->StaCfg.BeaconLostTime/2);
-	}
-#endif // CARRIER_DETECTION_SUPPORT //
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef CONFIG_STA_SUPPORT
-	if (pAd->OpMode == OPMODE_STA)
-	{
-		pRssiSample = &pAd->StaCfg.RssiSample;
-		OneSecTxNoRetryOkCount = pAd->RalinkCounters.OneSecTxNoRetryOkCount;
-		OneSecTxRetryOkCount = pAd->RalinkCounters.OneSecTxRetryOkCount;
-		OneSecTxFailCount = pAd->RalinkCounters.OneSecTxFailCount;
-		OneSecRxOkCnt = pAd->RalinkCounters.OneSecRxOkCnt;
-		OneSecRxFcsErrCnt = pAd->RalinkCounters.OneSecRxFcsErrCnt;
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	MaxRssi = RTMPMaxRssi(pAd, pRssiSample->LastRssi0,
-								pRssiSample->LastRssi1,
-								pRssiSample->LastRssi2);
-
-	//
-	// calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics
-	//
-	TxOkCnt = OneSecTxNoRetryOkCount + OneSecTxRetryOkCount;
-	TxCnt = TxOkCnt + OneSecTxFailCount;
-	if (TxCnt < 5)
-	{
-		TxPER = 0;
-		TxPRR = 0;
-	}
-	else
-	{
-		TxPER = (OneSecTxFailCount * 100) / TxCnt;
-		TxPRR = ((TxCnt - OneSecTxNoRetryOkCount) * 100) / TxCnt;
-	}
-
-	//
-	// calculate RX PER - don't take RxPER into consideration if too few sample
-	//
-	RxCnt = OneSecRxOkCnt + OneSecRxFcsErrCnt;
-	if (RxCnt < 5)
-		RxPER = 0;
-	else
-		RxPER = (OneSecRxFcsErrCnt * 100) / RxCnt;
-
-	//
-	// decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER
-	//
-#ifdef CONFIG_STA_SUPPORT
-	if ((pAd->OpMode == OPMODE_STA) &&
-		INFRA_ON(pAd) &&
-		(OneSecTxNoRetryOkCount < 2) && // no heavy traffic
-		((pAd->StaCfg.LastBeaconRxTime + BeaconLostTime) < Now32))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", BeaconLostTime, TxOkCnt));
-		ChannelQuality = 0;
-	}
-	else
-#endif // CONFIG_STA_SUPPORT //
-	{
-		// Normalize Rssi
-		if (MaxRssi > -40)
-			NorRssi = 100;
-		else if (MaxRssi < -90)
-			NorRssi = 0;
-		else
-			NorRssi = (MaxRssi + 90) * 2;
-
-		// ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER	 (RSSI 0..100), (TxPER 100..0), (RxPER 100..0)
-		ChannelQuality = (RSSI_WEIGHTING * NorRssi +
-								   TX_WEIGHTING * (100 - TxPRR) +
-								   RX_WEIGHTING* (100 - RxPER)) / 100;
-	}
-
-
-#ifdef CONFIG_STA_SUPPORT
-	if (pAd->OpMode == OPMODE_STA)
-		pAd->Mlme.ChannelQuality = (ChannelQuality > 100) ? 100 : ChannelQuality;
-#endif // CONFIG_STA_SUPPORT //
-
-
-}
-
-
-// IRQL = DISPATCH_LEVEL
-VOID MlmeSetTxPreamble(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT TxPreamble)
-{
-	AUTO_RSP_CFG_STRUC csr4;
-
-	//
-	// Always use Long preamble before verifiation short preamble functionality works well.
-	// Todo: remove the following line if short preamble functionality works
-	//
-	//TxPreamble = Rt802_11PreambleLong;
-
-	RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
-	if (TxPreamble == Rt802_11PreambleLong)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= LONG PREAMBLE)\n"));
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
-		csr4.field.AutoResponderPreamble = 0;
-	}
-	else
-	{
-		// NOTE: 1Mbps should always use long preamble
-		DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= SHORT PREAMBLE)\n"));
-		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
-		csr4.field.AutoResponderPreamble = 1;
-	}
-
-	RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
-}
-
-/*
-    ==========================================================================
-    Description:
-        Update basic rate bitmap
-    ==========================================================================
- */
-
-VOID UpdateBasicRateBitmap(
-    IN  PRTMP_ADAPTER   pAdapter)
-{
-    INT  i, j;
-                  /* 1  2  5.5, 11,  6,  9, 12, 18, 24, 36, 48,  54 */
-    UCHAR rate[] = { 2, 4,  11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
-    UCHAR *sup_p = pAdapter->CommonCfg.SupRate;
-    UCHAR *ext_p = pAdapter->CommonCfg.ExtRate;
-    ULONG bitmap = pAdapter->CommonCfg.BasicRateBitmap;
-
-
-    /* if A mode, always use fix BasicRateBitMap */
-    //if (pAdapter->CommonCfg.Channel == PHY_11A)
-	if (pAdapter->CommonCfg.Channel > 14)
-        pAdapter->CommonCfg.BasicRateBitmap = 0x150; /* 6, 12, 24M */
-    /* End of if */
-
-    if (pAdapter->CommonCfg.BasicRateBitmap > 4095)
-    {
-        /* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */
-        return;
-    } /* End of if */
-
-    for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
-    {
-        sup_p[i] &= 0x7f;
-        ext_p[i] &= 0x7f;
-    } /* End of for */
-
-    for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
-    {
-        if (bitmap & (1 << i))
-        {
-            for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
-            {
-                if (sup_p[j] == rate[i])
-                    sup_p[j] |= 0x80;
-                /* End of if */
-            } /* End of for */
-
-            for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
-            {
-                if (ext_p[j] == rate[i])
-                    ext_p[j] |= 0x80;
-                /* End of if */
-            } /* End of for */
-        } /* End of if */
-    } /* End of for */
-} /* End of UpdateBasicRateBitmap */
-
-// IRQL = PASSIVE_LEVEL
-// IRQL = DISPATCH_LEVEL
-// bLinkUp is to identify the inital link speed.
-// TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps.
-VOID MlmeUpdateTxRates(
-	IN PRTMP_ADAPTER		pAd,
-	IN	BOOLEAN				bLinkUp,
-	IN	UCHAR				apidx)
-{
-	int i, num;
-	UCHAR Rate = RATE_6, MaxDesire = RATE_1, MaxSupport = RATE_1;
-	UCHAR MinSupport = RATE_54;
-	ULONG BasicRateBitmap = 0;
-	UCHAR CurrBasicRate = RATE_1;
-	UCHAR *pSupRate, SupRateLen, *pExtRate, ExtRateLen;
-	PHTTRANSMIT_SETTING		pHtPhy = NULL;
-	PHTTRANSMIT_SETTING		pMaxHtPhy = NULL;
-	PHTTRANSMIT_SETTING		pMinHtPhy = NULL;
-	BOOLEAN					*auto_rate_cur_p;
-	UCHAR					HtMcs = MCS_AUTO;
-
-	// find max desired rate
-	UpdateBasicRateBitmap(pAd);
-
-	num = 0;
-	auto_rate_cur_p = NULL;
-	for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
-	{
-		switch (pAd->CommonCfg.DesireRate[i] & 0x7f)
-		{
-			case 2:  Rate = RATE_1;   num++;   break;
-			case 4:  Rate = RATE_2;   num++;   break;
-			case 11: Rate = RATE_5_5; num++;   break;
-			case 22: Rate = RATE_11;  num++;   break;
-			case 12: Rate = RATE_6;   num++;   break;
-			case 18: Rate = RATE_9;   num++;   break;
-			case 24: Rate = RATE_12;  num++;   break;
-			case 36: Rate = RATE_18;  num++;   break;
-			case 48: Rate = RATE_24;  num++;   break;
-			case 72: Rate = RATE_36;  num++;   break;
-			case 96: Rate = RATE_48;  num++;   break;
-			case 108: Rate = RATE_54; num++;   break;
-			//default: Rate = RATE_1;   break;
-		}
-		if (MaxDesire < Rate)  MaxDesire = Rate;
-	}
-
-//===========================================================================
-//===========================================================================
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		pHtPhy		= &pAd->StaCfg.HTPhyMode;
-		pMaxHtPhy	= &pAd->StaCfg.MaxHTPhyMode;
-		pMinHtPhy	= &pAd->StaCfg.MinHTPhyMode;
-
-		auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
-		HtMcs		= pAd->StaCfg.DesiredTransmitSetting.field.MCS;
-
-		if ((pAd->StaCfg.BssType == BSS_ADHOC) &&
-			(pAd->CommonCfg.PhyMode == PHY_11B) &&
-		(MaxDesire > RATE_11))
-		{
-			MaxDesire = RATE_11;
-		}
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	pAd->CommonCfg.MaxDesiredRate = MaxDesire;
-	pMinHtPhy->word = 0;
-	pMaxHtPhy->word = 0;
-	pHtPhy->word = 0;
-
-	// Auto rate switching is enabled only if more than one DESIRED RATES are
-	// specified; otherwise disabled
-	if (num <= 1)
-	{
-		//OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
-		//pAd->CommonCfg.bAutoTxRateSwitch	= FALSE;
-		*auto_rate_cur_p = FALSE;
-	}
-	else
-	{
-		//OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
-		//pAd->CommonCfg.bAutoTxRateSwitch	= TRUE;
-		*auto_rate_cur_p = TRUE;
-	}
-
-	if (HtMcs != MCS_AUTO)
-	{
-		//OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
-		//pAd->CommonCfg.bAutoTxRateSwitch	= FALSE;
-		*auto_rate_cur_p = FALSE;
-	}
-	else
-	{
-		//OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
-		//pAd->CommonCfg.bAutoTxRateSwitch	= TRUE;
-		*auto_rate_cur_p = TRUE;
-	}
-
-#ifdef CONFIG_STA_SUPPORT
-	if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
-	{
-		pSupRate = &pAd->StaActive.SupRate[0];
-		pExtRate = &pAd->StaActive.ExtRate[0];
-		SupRateLen = pAd->StaActive.SupRateLen;
-		ExtRateLen = pAd->StaActive.ExtRateLen;
-	}
-	else
-#endif // CONFIG_STA_SUPPORT //
-	{
-		pSupRate = &pAd->CommonCfg.SupRate[0];
-		pExtRate = &pAd->CommonCfg.ExtRate[0];
-		SupRateLen = pAd->CommonCfg.SupRateLen;
-		ExtRateLen = pAd->CommonCfg.ExtRateLen;
-	}
-
-	// find max supported rate
-	for (i=0; i<SupRateLen; i++)
-	{
-		switch (pSupRate[i] & 0x7f)
-		{
-			case 2:   Rate = RATE_1;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0001;	 break;
-			case 4:   Rate = RATE_2;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0002;	 break;
-			case 11:  Rate = RATE_5_5;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0004;	 break;
-			case 22:  Rate = RATE_11;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0008;	 break;
-			case 12:  Rate = RATE_6;	/*if (pSupRate[i] & 0x80)*/  BasicRateBitmap |= 0x0010;  break;
-			case 18:  Rate = RATE_9;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0020;	 break;
-			case 24:  Rate = RATE_12;	/*if (pSupRate[i] & 0x80)*/  BasicRateBitmap |= 0x0040;  break;
-			case 36:  Rate = RATE_18;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0080;	 break;
-			case 48:  Rate = RATE_24;	/*if (pSupRate[i] & 0x80)*/  BasicRateBitmap |= 0x0100;  break;
-			case 72:  Rate = RATE_36;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0200;	 break;
-			case 96:  Rate = RATE_48;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0400;	 break;
-			case 108: Rate = RATE_54;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0800;	 break;
-			default:  Rate = RATE_1;	break;
-		}
-		if (MaxSupport < Rate)	MaxSupport = Rate;
-
-		if (MinSupport > Rate) MinSupport = Rate;
-	}
-
-	for (i=0; i<ExtRateLen; i++)
-	{
-		switch (pExtRate[i] & 0x7f)
-		{
-			case 2:   Rate = RATE_1;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0001;	 break;
-			case 4:   Rate = RATE_2;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0002;	 break;
-			case 11:  Rate = RATE_5_5;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0004;	 break;
-			case 22:  Rate = RATE_11;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0008;	 break;
-			case 12:  Rate = RATE_6;	/*if (pExtRate[i] & 0x80)*/  BasicRateBitmap |= 0x0010;  break;
-			case 18:  Rate = RATE_9;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0020;	 break;
-			case 24:  Rate = RATE_12;	/*if (pExtRate[i] & 0x80)*/  BasicRateBitmap |= 0x0040;  break;
-			case 36:  Rate = RATE_18;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0080;	 break;
-			case 48:  Rate = RATE_24;	/*if (pExtRate[i] & 0x80)*/  BasicRateBitmap |= 0x0100;  break;
-			case 72:  Rate = RATE_36;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0200;	 break;
-			case 96:  Rate = RATE_48;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0400;	 break;
-			case 108: Rate = RATE_54;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0800;	 break;
-			default:  Rate = RATE_1;	break;
-		}
-		if (MaxSupport < Rate)	MaxSupport = Rate;
-
-		if (MinSupport > Rate) MinSupport = Rate;
-	}
-
-	RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap);
-
-	// bug fix
-	// pAd->CommonCfg.BasicRateBitmap = BasicRateBitmap;
-
-	// calculate the exptected ACK rate for each TX rate. This info is used to caculate
-	// the DURATION field of outgoing uniicast DATA/MGMT frame
-	for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
-	{
-		if (BasicRateBitmap & (0x01 << i))
-			CurrBasicRate = (UCHAR)i;
-		pAd->CommonCfg.ExpectedACKRate[i] = CurrBasicRate;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n", RateIdToMbps[MaxSupport], RateIdToMbps[MaxDesire]));
-	// max tx rate = min {max desire rate, max supported rate}
-	if (MaxSupport < MaxDesire)
-		pAd->CommonCfg.MaxTxRate = MaxSupport;
-	else
-		pAd->CommonCfg.MaxTxRate = MaxDesire;
-
-	pAd->CommonCfg.MinTxRate = MinSupport;
-	// 2003-07-31 john - 2500 doesn't have good sensitivity at high OFDM rates. to increase the success
-	// ratio of initial DHCP packet exchange, TX rate starts from a lower rate depending
-	// on average RSSI
-	//	 1. RSSI >= -70db, start at 54 Mbps (short distance)
-	//	 2. -70 > RSSI >= -75, start at 24 Mbps (mid distance)
-	//	 3. -75 > RSSI, start at 11 Mbps (long distance)
-	//if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)/* &&
-	//	OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)*/)
-	if (*auto_rate_cur_p)
-	{
-		short dbm = 0;
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-			dbm = pAd->StaCfg.RssiSample.AvgRssi0 - pAd->BbpRssiToDbmDelta;
-#endif // CONFIG_STA_SUPPORT //
-		if (bLinkUp == TRUE)
-			pAd->CommonCfg.TxRate = RATE_24;
-		else
-			pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
-
-		if (dbm < -75)
-			pAd->CommonCfg.TxRate = RATE_11;
-		else if (dbm < -70)
-			pAd->CommonCfg.TxRate = RATE_24;
-
-		// should never exceed MaxTxRate (consider 11B-only mode)
-		if (pAd->CommonCfg.TxRate > pAd->CommonCfg.MaxTxRate)
-			pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
-
-		pAd->CommonCfg.TxRateIndex = 0;
-	}
-	else
-	{
-		pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
-		pHtPhy->field.MCS	= (pAd->CommonCfg.MaxTxRate > 3) ? (pAd->CommonCfg.MaxTxRate - 4) : pAd->CommonCfg.MaxTxRate;
-		pHtPhy->field.MODE	= (pAd->CommonCfg.MaxTxRate > 3) ? MODE_OFDM : MODE_CCK;
-
-		pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC	= pHtPhy->field.STBC;
-		pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI	= pHtPhy->field.ShortGI;
-		pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS		= pHtPhy->field.MCS;
-		pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE	= pHtPhy->field.MODE;
-	}
-
-	if (pAd->CommonCfg.TxRate <= RATE_11)
-	{
-		pMaxHtPhy->field.MODE = MODE_CCK;
-		pMaxHtPhy->field.MCS = pAd->CommonCfg.TxRate;
-		pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;
-	}
-	else
-	{
-		pMaxHtPhy->field.MODE = MODE_OFDM;
-		pMaxHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.TxRate];
-		if (pAd->CommonCfg.MinTxRate >= RATE_6 && (pAd->CommonCfg.MinTxRate <= RATE_54))
-			{pMinHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MinTxRate];}
-		else
-			{pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;}
-	}
-
-	pHtPhy->word = (pMaxHtPhy->word);
-	if (bLinkUp && (pAd->OpMode == OPMODE_STA))
-	{
-			pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word = pHtPhy->word;
-			pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word = pMaxHtPhy->word;
-			pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word = pMinHtPhy->word;
-	}
-	else
-	{
-		switch (pAd->CommonCfg.PhyMode)
-		{
-			case PHY_11BG_MIXED:
-			case PHY_11B:
-#ifdef DOT11_N_SUPPORT
-			case PHY_11BGN_MIXED:
-#endif // DOT11_N_SUPPORT //
-				pAd->CommonCfg.MlmeRate = RATE_1;
-				pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
-				pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
-
-//#ifdef	WIFI_TEST
-				pAd->CommonCfg.RtsRate = RATE_11;
-//#else
-//				pAd->CommonCfg.RtsRate = RATE_1;
-//#endif
-				break;
-			case PHY_11G:
-			case PHY_11A:
-#ifdef DOT11_N_SUPPORT
-			case PHY_11AGN_MIXED:
-			case PHY_11GN_MIXED:
-			case PHY_11N_2_4G:
-			case PHY_11AN_MIXED:
-			case PHY_11N_5G:
-#endif // DOT11_N_SUPPORT //
-				pAd->CommonCfg.MlmeRate = RATE_6;
-				pAd->CommonCfg.RtsRate = RATE_6;
-				pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
-				pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-				break;
-			case PHY_11ABG_MIXED:
-#ifdef DOT11_N_SUPPORT
-			case PHY_11ABGN_MIXED:
-#endif // DOT11_N_SUPPORT //
-				if (pAd->CommonCfg.Channel <= 14)
-				{
-					pAd->CommonCfg.MlmeRate = RATE_1;
-					pAd->CommonCfg.RtsRate = RATE_1;
-					pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
-					pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
-				}
-				else
-				{
-					pAd->CommonCfg.MlmeRate = RATE_6;
-					pAd->CommonCfg.RtsRate = RATE_6;
-					pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
-					pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-				}
-				break;
-			default: // error
-				pAd->CommonCfg.MlmeRate = RATE_6;
-				pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
-				pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-				pAd->CommonCfg.RtsRate = RATE_1;
-				break;
-		}
-		//
-		// Keep Basic Mlme Rate.
-		//
-		pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word = pAd->CommonCfg.MlmeTransmit.word;
-		if (pAd->CommonCfg.MlmeTransmit.field.MODE == MODE_OFDM)
-			pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[RATE_24];
-		else
-			pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = RATE_1;
-		pAd->CommonCfg.BasicMlmeRate = pAd->CommonCfg.MlmeRate;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n",
-			 RateIdToMbps[MaxDesire], RateIdToMbps[MaxSupport], RateIdToMbps[pAd->CommonCfg.MaxTxRate], RateIdToMbps[pAd->CommonCfg.MinTxRate],
-			 /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)*/*auto_rate_cur_p));
-	DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n",
-			 RateIdToMbps[pAd->CommonCfg.TxRate], RateIdToMbps[pAd->CommonCfg.RtsRate], BasicRateBitmap));
-	DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n",
-			 pAd->CommonCfg.MlmeTransmit.word, pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word ,pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word ,pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word ));
-}
-
-#ifdef DOT11_N_SUPPORT
-/*
-	==========================================================================
-	Description:
-		This function update HT Rate setting.
-		Input Wcid value is valid for 2 case :
-		1. it's used for Station in infra mode that copy AP rate to Mactable.
-		2. OR Station	in adhoc mode to copy peer's HT rate to Mactable.
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID MlmeUpdateHtTxRates(
-	IN PRTMP_ADAPTER		pAd,
-	IN	UCHAR				apidx)
-{
-	UCHAR	StbcMcs; //j, StbcMcs, bitmask;
-	CHAR	i; // 3*3
-	RT_HT_CAPABILITY	*pRtHtCap = NULL;
-	RT_HT_PHY_INFO		*pActiveHtPhy = NULL;
-	ULONG		BasicMCS;
-	UCHAR j, bitmask;
-	PRT_HT_PHY_INFO			pDesireHtPhy = NULL;
-	PHTTRANSMIT_SETTING		pHtPhy = NULL;
-	PHTTRANSMIT_SETTING		pMaxHtPhy = NULL;
-	PHTTRANSMIT_SETTING		pMinHtPhy = NULL;
-	BOOLEAN					*auto_rate_cur_p;
-
-	DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates===> \n"));
-
-	auto_rate_cur_p = NULL;
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		pDesireHtPhy	= &pAd->StaCfg.DesiredHtPhyInfo;
-		pActiveHtPhy	= &pAd->StaCfg.DesiredHtPhyInfo;
-		pHtPhy		= &pAd->StaCfg.HTPhyMode;
-		pMaxHtPhy	= &pAd->StaCfg.MaxHTPhyMode;
-		pMinHtPhy	= &pAd->StaCfg.MinHTPhyMode;
-
-		auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef CONFIG_STA_SUPPORT
-	if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
-	{
-		if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
-			return;
-
-		pRtHtCap = &pAd->StaActive.SupportedHtPhy;
-		pActiveHtPhy = &pAd->StaActive.SupportedPhyInfo;
-		StbcMcs = (UCHAR)pAd->MlmeAux.AddHtInfo.AddHtInfo3.StbcMcs;
-		BasicMCS =pAd->MlmeAux.AddHtInfo.MCSSet[0]+(pAd->MlmeAux.AddHtInfo.MCSSet[1]<<8)+(StbcMcs<<16);
-		if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
-			pMaxHtPhy->field.STBC = STBC_USE;
-		else
-			pMaxHtPhy->field.STBC = STBC_NONE;
-	}
-	else
-#endif // CONFIG_STA_SUPPORT //
-	{
-		if (pDesireHtPhy->bHtEnable == FALSE)
-			return;
-
-		pRtHtCap = &pAd->CommonCfg.DesiredHtPhy;
-		StbcMcs = (UCHAR)pAd->CommonCfg.AddHTInfo.AddHtInfo3.StbcMcs;
-		BasicMCS = pAd->CommonCfg.AddHTInfo.MCSSet[0]+(pAd->CommonCfg.AddHTInfo.MCSSet[1]<<8)+(StbcMcs<<16);
-		if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
-			pMaxHtPhy->field.STBC = STBC_USE;
-		else
-			pMaxHtPhy->field.STBC = STBC_NONE;
-	}
-
-	// Decide MAX ht rate.
-	if ((pRtHtCap->GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
-		pMaxHtPhy->field.MODE = MODE_HTGREENFIELD;
-	else
-		pMaxHtPhy->field.MODE = MODE_HTMIX;
-
-    if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth) && (pRtHtCap->ChannelWidth))
-		pMaxHtPhy->field.BW = BW_40;
-	else
-		pMaxHtPhy->field.BW = BW_20;
-
-    if (pMaxHtPhy->field.BW == BW_20)
-		pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 & pRtHtCap->ShortGIfor20);
-	else
-		pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 & pRtHtCap->ShortGIfor40);
-
-	if (pDesireHtPhy->MCSSet[4] != 0)
-	{
-		pMaxHtPhy->field.MCS = 32;
-	}
-
-	for (i=23; i>=0; i--) // 3*3
-	{
-		j = i/8;
-		bitmask = (1<<(i-(j*8)));
-
-		if ((pActiveHtPhy->MCSSet[j] & bitmask) && (pDesireHtPhy->MCSSet[j] & bitmask))
-		{
-			pMaxHtPhy->field.MCS = i;
-			break;
-		}
-
-		if (i==0)
-			break;
-	}
-
-	// Copy MIN ht rate.  rt2860???
-	pMinHtPhy->field.BW = BW_20;
-	pMinHtPhy->field.MCS = 0;
-	pMinHtPhy->field.STBC = 0;
-	pMinHtPhy->field.ShortGI = 0;
-	//If STA assigns fixed rate. update to fixed here.
-#ifdef CONFIG_STA_SUPPORT
-	if ( (pAd->OpMode == OPMODE_STA) && (pDesireHtPhy->MCSSet[0] != 0xff))
-	{
-		if (pDesireHtPhy->MCSSet[4] != 0)
-		{
-			pMaxHtPhy->field.MCS = 32;
-			pMinHtPhy->field.MCS = 32;
-			DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",pMinHtPhy->field.MCS));
-		}
-
-		for (i=23; (CHAR)i >= 0; i--) // 3*3
-		{
-			j = i/8;
-			bitmask = (1<<(i-(j*8)));
-			if ( (pDesireHtPhy->MCSSet[j] & bitmask) && (pActiveHtPhy->MCSSet[j] & bitmask))
-			{
-				pMaxHtPhy->field.MCS = i;
-				pMinHtPhy->field.MCS = i;
-				break;
-			}
-			if (i==0)
-				break;
-		}
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-
-	// Decide ht rate
-	pHtPhy->field.STBC = pMaxHtPhy->field.STBC;
-	pHtPhy->field.BW = pMaxHtPhy->field.BW;
-	pHtPhy->field.MODE = pMaxHtPhy->field.MODE;
-	pHtPhy->field.MCS = pMaxHtPhy->field.MCS;
-	pHtPhy->field.ShortGI = pMaxHtPhy->field.ShortGI;
-
-	// use default now. rt2860
-	if (pDesireHtPhy->MCSSet[0] != 0xff)
-		*auto_rate_cur_p = FALSE;
-	else
-		*auto_rate_cur_p = TRUE;
-
-	DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateHtTxRates<---.AMsduSize = %d  \n", pAd->CommonCfg.DesiredHtPhy.AmsduSize ));
-	DBGPRINT(RT_DEBUG_TRACE,("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d,  \n", pActiveHtPhy->MCSSet[0],pHtPhy->field.MCS,
-		pHtPhy->field.BW, pHtPhy->field.ShortGI, pHtPhy->field.MODE));
-	DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== \n"));
-}
-
-
-VOID BATableInit(
-	IN PRTMP_ADAPTER pAd,
-    IN BA_TABLE *Tab)
-{
-	int i;
-
-	Tab->numAsOriginator = 0;
-	Tab->numAsRecipient = 0;
-	Tab->numDoneOriginator = 0;
-	NdisAllocateSpinLock(&pAd->BATabLock);
-	for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
-	{
-		Tab->BARecEntry[i].REC_BA_Status = Recipient_NONE;
-		NdisAllocateSpinLock(&(Tab->BARecEntry[i].RxReRingLock));
-	}
-	for (i = 0; i < MAX_LEN_OF_BA_ORI_TABLE; i++)
-	{
-		Tab->BAOriEntry[i].ORI_BA_Status = Originator_NONE;
-	}
-}
-#endif // DOT11_N_SUPPORT //
-
-// IRQL = DISPATCH_LEVEL
-VOID MlmeRadioOff(
-	IN PRTMP_ADAPTER pAd)
-{
-	RTMP_MLME_RADIO_OFF(pAd);
-}
-
-// IRQL = DISPATCH_LEVEL
-VOID MlmeRadioOn(
-	IN PRTMP_ADAPTER pAd)
-{
-	RTMP_MLME_RADIO_ON(pAd);
-}
-
-// ===========================================================================================
-// bss_table.c
-// ===========================================================================================
-
-
-/*! \brief initialize BSS table
- *	\param p_tab pointer to the table
- *	\return none
- *	\pre
- *	\post
-
- IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
-
- */
-VOID BssTableInit(
-	IN BSS_TABLE *Tab)
-{
-	int i;
-
-	Tab->BssNr = 0;
-    Tab->BssOverlapNr = 0;
-	for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++)
-	{
-		NdisZeroMemory(&Tab->BssEntry[i], sizeof(BSS_ENTRY));
-		Tab->BssEntry[i].Rssi = -127;	// initial the rssi as a minimum value
-	}
-}
-
-
-/*! \brief search the BSS table by SSID
- *	\param p_tab pointer to the bss table
- *	\param ssid SSID string
- *	\return index of the table, BSS_NOT_FOUND if not in the table
- *	\pre
- *	\post
- *	\note search by sequential search
-
- IRQL = DISPATCH_LEVEL
-
- */
-ULONG BssTableSearch(
-	IN BSS_TABLE *Tab,
-	IN PUCHAR	 pBssid,
-	IN UCHAR	 Channel)
-{
-	UCHAR i;
-
-	for (i = 0; i < Tab->BssNr; i++)
-	{
-		//
-		// Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
-		// We should distinguish this case.
-		//
-		if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
-			 ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
-			MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid))
-		{
-			return i;
-		}
-	}
-	return (ULONG)BSS_NOT_FOUND;
-}
-
-ULONG BssSsidTableSearch(
-	IN BSS_TABLE *Tab,
-	IN PUCHAR	 pBssid,
-	IN PUCHAR	 pSsid,
-	IN UCHAR	 SsidLen,
-	IN UCHAR	 Channel)
-{
-	UCHAR i;
-
-	for (i = 0; i < Tab->BssNr; i++)
-	{
-		//
-		// Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
-		// We should distinguish this case.
-		//
-		if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
-			 ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
-			MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid) &&
-			SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen))
-		{
-			return i;
-		}
-	}
-	return (ULONG)BSS_NOT_FOUND;
-}
-
-ULONG BssTableSearchWithSSID(
-	IN BSS_TABLE *Tab,
-	IN PUCHAR	 Bssid,
-	IN PUCHAR	 pSsid,
-	IN UCHAR	 SsidLen,
-	IN UCHAR	 Channel)
-{
-	UCHAR i;
-
-	for (i = 0; i < Tab->BssNr; i++)
-	{
-		if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
-			((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
-			MAC_ADDR_EQUAL(&(Tab->BssEntry[i].Bssid), Bssid) &&
-			(SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen) ||
-			(NdisEqualMemory(pSsid, ZeroSsid, SsidLen)) ||
-			(NdisEqualMemory(Tab->BssEntry[i].Ssid, ZeroSsid, Tab->BssEntry[i].SsidLen))))
-		{
-			return i;
-		}
-	}
-	return (ULONG)BSS_NOT_FOUND;
-}
-
-
-ULONG BssSsidTableSearchBySSID(
-	IN BSS_TABLE *Tab,
-	IN PUCHAR	 pSsid,
-	IN UCHAR	 SsidLen)
-{
-	UCHAR i;
-
-	for (i = 0; i < Tab->BssNr; i++)
-	{
-		if (SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen))
-		{
-			return i;
-		}
-	}
-	return (ULONG)BSS_NOT_FOUND;
-}
-
-
-// IRQL = DISPATCH_LEVEL
-VOID BssTableDeleteEntry(
-	IN OUT	BSS_TABLE *Tab,
-	IN		PUCHAR	  pBssid,
-	IN		UCHAR	  Channel)
-{
-	UCHAR i, j;
-
-	for (i = 0; i < Tab->BssNr; i++)
-	{
-		if ((Tab->BssEntry[i].Channel == Channel) &&
-			(MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid)))
-		{
-			for (j = i; j < Tab->BssNr - 1; j++)
-			{
-				NdisMoveMemory(&(Tab->BssEntry[j]), &(Tab->BssEntry[j + 1]), sizeof(BSS_ENTRY));
-			}
-			NdisZeroMemory(&(Tab->BssEntry[Tab->BssNr - 1]), sizeof(BSS_ENTRY));
-			Tab->BssNr -= 1;
-			return;
-		}
-	}
-}
-
-#ifdef DOT11_N_SUPPORT
-/*
-	========================================================================
-	Routine Description:
-		Delete the Originator Entry in BAtable. Or decrease numAs Originator by 1 if needed.
-
-	Arguments:
-	// IRQL = DISPATCH_LEVEL
-	========================================================================
-*/
-VOID BATableDeleteORIEntry(
-	IN OUT	PRTMP_ADAPTER pAd,
-	IN		BA_ORI_ENTRY	*pBAORIEntry)
-{
-
-	if (pBAORIEntry->ORI_BA_Status != Originator_NONE)
-	{
-		NdisAcquireSpinLock(&pAd->BATabLock);
-		if (pBAORIEntry->ORI_BA_Status == Originator_Done)
-		{
-			pAd->BATable.numAsOriginator -= 1;
-			DBGPRINT(RT_DEBUG_TRACE, ("BATableDeleteORIEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
-			// Erase Bitmap flag.
-		}
-		pAd->MacTab.Content[pBAORIEntry->Wcid].TXBAbitmap &= (~(1<<(pBAORIEntry->TID) ));	// If STA mode,  erase flag here
-		pAd->MacTab.Content[pBAORIEntry->Wcid].BAOriWcidArray[pBAORIEntry->TID] = 0;	// If STA mode,  erase flag here
-		pBAORIEntry->ORI_BA_Status = Originator_NONE;
-		pBAORIEntry->Token = 1;
-		// Not clear Sequence here.
-		NdisReleaseSpinLock(&pAd->BATabLock);
-	}
-}
-#endif // DOT11_N_SUPPORT //
-
-/*! \brief
- *	\param
- *	\return
- *	\pre
- *	\post
-
- IRQL = DISPATCH_LEVEL
-
- */
-VOID BssEntrySet(
-	IN PRTMP_ADAPTER	pAd,
-	OUT BSS_ENTRY *pBss,
-	IN PUCHAR pBssid,
-	IN CHAR Ssid[],
-	IN UCHAR SsidLen,
-	IN UCHAR BssType,
-	IN USHORT BeaconPeriod,
-	IN PCF_PARM pCfParm,
-	IN USHORT AtimWin,
-	IN USHORT CapabilityInfo,
-	IN UCHAR SupRate[],
-	IN UCHAR SupRateLen,
-	IN UCHAR ExtRate[],
-	IN UCHAR ExtRateLen,
-	IN HT_CAPABILITY_IE *pHtCapability,
-	IN ADD_HT_INFO_IE *pAddHtInfo,	// AP might use this additional ht info IE
-	IN UCHAR			HtCapabilityLen,
-	IN UCHAR			AddHtInfoLen,
-	IN UCHAR			NewExtChanOffset,
-	IN UCHAR Channel,
-	IN CHAR Rssi,
-	IN LARGE_INTEGER TimeStamp,
-	IN UCHAR CkipFlag,
-	IN PEDCA_PARM pEdcaParm,
-	IN PQOS_CAPABILITY_PARM pQosCapability,
-	IN PQBSS_LOAD_PARM pQbssLoad,
-	IN USHORT LengthVIE,
-	IN PNDIS_802_11_VARIABLE_IEs pVIE)
-{
-	COPY_MAC_ADDR(pBss->Bssid, pBssid);
-	// Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID
-	pBss->Hidden = 1;
-	if (SsidLen > 0)
-	{
-		// For hidden SSID AP, it might send beacon with SSID len equal to 0
-		// Or send beacon /probe response with SSID len matching real SSID length,
-		// but SSID is all zero. such as "00-00-00-00" with length 4.
-		// We have to prevent this case overwrite correct table
-		if (NdisEqualMemory(Ssid, ZeroSsid, SsidLen) == 0)
-		{
-		    NdisZeroMemory(pBss->Ssid, MAX_LEN_OF_SSID);
-			NdisMoveMemory(pBss->Ssid, Ssid, SsidLen);
-			pBss->SsidLen = SsidLen;
-			pBss->Hidden = 0;
-		}
-	}
-	else
-		pBss->SsidLen = 0;
-	pBss->BssType = BssType;
-	pBss->BeaconPeriod = BeaconPeriod;
-	if (BssType == BSS_INFRA)
-	{
-		if (pCfParm->bValid)
-		{
-			pBss->CfpCount = pCfParm->CfpCount;
-			pBss->CfpPeriod = pCfParm->CfpPeriod;
-			pBss->CfpMaxDuration = pCfParm->CfpMaxDuration;
-			pBss->CfpDurRemaining = pCfParm->CfpDurRemaining;
-		}
-	}
-	else
-	{
-		pBss->AtimWin = AtimWin;
-	}
-
-	pBss->CapabilityInfo = CapabilityInfo;
-	// The privacy bit indicate security is ON, it maight be WEP, TKIP or AES
-	// Combine with AuthMode, they will decide the connection methods.
-	pBss->Privacy = CAP_IS_PRIVACY_ON(pBss->CapabilityInfo);
-	ASSERT(SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
-	if (SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES)
-		NdisMoveMemory(pBss->SupRate, SupRate, SupRateLen);
-	else
-		NdisMoveMemory(pBss->SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES);
-	pBss->SupRateLen = SupRateLen;
-	ASSERT(ExtRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
-	NdisMoveMemory(pBss->ExtRate, ExtRate, ExtRateLen);
-	pBss->NewExtChanOffset = NewExtChanOffset;
-	pBss->ExtRateLen = ExtRateLen;
-	pBss->Channel = Channel;
-	pBss->CentralChannel = Channel;
-	pBss->Rssi = Rssi;
-	// Update CkipFlag. if not exists, the value is 0x0
-	pBss->CkipFlag = CkipFlag;
-
-	// New for microsoft Fixed IEs
-	NdisMoveMemory(pBss->FixIEs.Timestamp, &TimeStamp, 8);
-	pBss->FixIEs.BeaconInterval = BeaconPeriod;
-	pBss->FixIEs.Capabilities = CapabilityInfo;
-
-	// New for microsoft Variable IEs
-	if (LengthVIE != 0)
-	{
-		pBss->VarIELen = LengthVIE;
-		NdisMoveMemory(pBss->VarIEs, pVIE, pBss->VarIELen);
-	}
-	else
-	{
-		pBss->VarIELen = 0;
-	}
-
-	pBss->AddHtInfoLen = 0;
-	pBss->HtCapabilityLen = 0;
-#ifdef DOT11_N_SUPPORT
-	if (HtCapabilityLen> 0)
-	{
-		pBss->HtCapabilityLen = HtCapabilityLen;
-		NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
-		if (AddHtInfoLen > 0)
-		{
-			pBss->AddHtInfoLen = AddHtInfoLen;
-			NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
-
-				if ((pAddHtInfo->ControlChan > 2)&& (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
-				{
-					pBss->CentralChannel = pAddHtInfo->ControlChan - 2;
-				}
-				else if ((pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
-				{
-						pBss->CentralChannel = pAddHtInfo->ControlChan + 2;
-				}
-		}
-	}
-#endif // DOT11_N_SUPPORT //
-
-	BssCipherParse(pBss);
-
-	// new for QOS
-	if (pEdcaParm)
-		NdisMoveMemory(&pBss->EdcaParm, pEdcaParm, sizeof(EDCA_PARM));
-	else
-		pBss->EdcaParm.bValid = FALSE;
-	if (pQosCapability)
-		NdisMoveMemory(&pBss->QosCapability, pQosCapability, sizeof(QOS_CAPABILITY_PARM));
-	else
-		pBss->QosCapability.bValid = FALSE;
-	if (pQbssLoad)
-		NdisMoveMemory(&pBss->QbssLoad, pQbssLoad, sizeof(QBSS_LOAD_PARM));
-	else
-		pBss->QbssLoad.bValid = FALSE;
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		PEID_STRUCT     pEid;
-		USHORT          Length = 0;
-
-
-		NdisZeroMemory(&pBss->WpaIE.IE[0], MAX_CUSTOM_LEN);
-		NdisZeroMemory(&pBss->RsnIE.IE[0], MAX_CUSTOM_LEN);
-#ifdef EXT_BUILD_CHANNEL_LIST
-		NdisZeroMemory(&pBss->CountryString[0], 3);
-		pBss->bHasCountryIE = FALSE;
-#endif // EXT_BUILD_CHANNEL_LIST //
-		pEid = (PEID_STRUCT) pVIE;
-		while ((Length + 2 + (USHORT)pEid->Len) <= LengthVIE)
-		{
-			switch(pEid->Eid)
-			{
-				case IE_WPA:
-					if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
-					{
-						if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
-						{
-							pBss->WpaIE.IELen = 0;
-							break;
-						}
-						pBss->WpaIE.IELen = pEid->Len + 2;
-						NdisMoveMemory(pBss->WpaIE.IE, pEid, pBss->WpaIE.IELen);
-					}
-					break;
-                case IE_RSN:
-                    if (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
-					{
-						if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
-                        {
-							pBss->RsnIE.IELen = 0;
-							break;
-					}
-						pBss->RsnIE.IELen = pEid->Len + 2;
-						NdisMoveMemory(pBss->RsnIE.IE, pEid, pBss->RsnIE.IELen);
-			}
-				break;
-#ifdef EXT_BUILD_CHANNEL_LIST
-				case IE_COUNTRY:
-					NdisMoveMemory(&pBss->CountryString[0], pEid->Octet, 3);
-					pBss->bHasCountryIE = TRUE;
-					break;
-#endif // EXT_BUILD_CHANNEL_LIST //
-            }
-			Length = Length + 2 + (USHORT)pEid->Len;  // Eid[1] + Len[1]+ content[Len]
-			pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
-		}
-	}
-#endif // CONFIG_STA_SUPPORT //
-}
-
-/*!
- *	\brief insert an entry into the bss table
- *	\param p_tab The BSS table
- *	\param Bssid BSSID
- *	\param ssid SSID
- *	\param ssid_len Length of SSID
- *	\param bss_type
- *	\param beacon_period
- *	\param timestamp
- *	\param p_cf
- *	\param atim_win
- *	\param cap
- *	\param rates
- *	\param rates_len
- *	\param channel_idx
- *	\return none
- *	\pre
- *	\post
- *	\note If SSID is identical, the old entry will be replaced by the new one
-
- IRQL = DISPATCH_LEVEL
-
- */
-ULONG BssTableSetEntry(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT BSS_TABLE *Tab,
-	IN PUCHAR pBssid,
-	IN CHAR Ssid[],
-	IN UCHAR SsidLen,
-	IN UCHAR BssType,
-	IN USHORT BeaconPeriod,
-	IN CF_PARM *CfParm,
-	IN USHORT AtimWin,
-	IN USHORT CapabilityInfo,
-	IN UCHAR SupRate[],
-	IN UCHAR SupRateLen,
-	IN UCHAR ExtRate[],
-	IN UCHAR ExtRateLen,
-	IN HT_CAPABILITY_IE *pHtCapability,
-	IN ADD_HT_INFO_IE *pAddHtInfo,	// AP might use this additional ht info IE
-	IN UCHAR			HtCapabilityLen,
-	IN UCHAR			AddHtInfoLen,
-	IN UCHAR			NewExtChanOffset,
-	IN UCHAR ChannelNo,
-	IN CHAR Rssi,
-	IN LARGE_INTEGER TimeStamp,
-	IN UCHAR CkipFlag,
-	IN PEDCA_PARM pEdcaParm,
-	IN PQOS_CAPABILITY_PARM pQosCapability,
-	IN PQBSS_LOAD_PARM pQbssLoad,
-	IN USHORT LengthVIE,
-	IN PNDIS_802_11_VARIABLE_IEs pVIE)
-{
-	ULONG	Idx;
-
-	Idx = BssTableSearchWithSSID(Tab, pBssid,  (UCHAR *)Ssid, SsidLen, ChannelNo);
-	if (Idx == BSS_NOT_FOUND)
-	{
-		if (Tab->BssNr >= MAX_LEN_OF_BSS_TABLE)
-	    {
-			//
-			// It may happen when BSS Table was full.
-			// The desired AP will not be added into BSS Table
-			// In this case, if we found the desired AP then overwrite BSS Table.
-			//
-			if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-			{
-				if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, pBssid) ||
-					SSID_EQUAL(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Ssid, SsidLen))
-				{
-					Idx = Tab->BssOverlapNr;
-					BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
-						CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
-						NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
-                    Tab->BssOverlapNr = (Tab->BssOverlapNr++) % MAX_LEN_OF_BSS_TABLE;
-				}
-				return Idx;
-			}
-			else
-			{
-			return BSS_NOT_FOUND;
-			}
-		}
-		Idx = Tab->BssNr;
-		BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
-					CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
-					NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
-		Tab->BssNr++;
-	}
-	else
-	{
-		/* avoid  Hidden SSID form beacon to overwirite correct SSID from probe response */
-		if ((SSID_EQUAL(Ssid, SsidLen, Tab->BssEntry[Idx].Ssid, Tab->BssEntry[Idx].SsidLen)) ||
-			(NdisEqualMemory(Tab->BssEntry[Idx].Ssid, ZeroSsid, Tab->BssEntry[Idx].SsidLen)))
-		{
-			BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod,CfParm, AtimWin,
-						CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
-						NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
-		}
-	}
-
-	return Idx;
-}
-
-#ifdef CONFIG_STA_SUPPORT
-#ifdef DOT11_N_SUPPORT
-#ifdef DOT11N_DRAFT3
-VOID  TriEventInit(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	UCHAR		i;
-
-	for (i = 0;i < MAX_TRIGGER_EVENT;i++)
-		pAd->CommonCfg.TriggerEventTab.EventA[i].bValid = FALSE;
-
-	pAd->CommonCfg.TriggerEventTab.EventANo = 0;
-	pAd->CommonCfg.TriggerEventTab.EventBCountDown = 0;
-}
-
-ULONG TriEventTableSetEntry(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT TRIGGER_EVENT_TAB *Tab,
-	IN PUCHAR pBssid,
-	IN HT_CAPABILITY_IE *pHtCapability,
-	IN UCHAR			HtCapabilityLen,
-	IN UCHAR			RegClass,
-	IN UCHAR ChannelNo)
-{
-	// Event A
-	if (HtCapabilityLen == 0)
-	{
-		if (Tab->EventANo < MAX_TRIGGER_EVENT)
-		{
-			RTMPMoveMemory(Tab->EventA[Tab->EventANo].BSSID, pBssid, 6);
-			Tab->EventA[Tab->EventANo].bValid = TRUE;
-			Tab->EventA[Tab->EventANo].Channel = ChannelNo;
-			Tab->EventA[Tab->EventANo].CDCounter = pAd->CommonCfg.Dot11BssWidthChanTranDelay;
-			if (RegClass != 0)
-			{
-				// Beacon has Regulatory class IE. So use beacon's
-				Tab->EventA[Tab->EventANo].RegClass = RegClass;
-			}
-			else
-			{
-				// Use Station's Regulatory class instead.
-				if (pAd->StaActive.SupportedHtPhy.bHtEnable == TRUE)
-				{
-					if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
-					{
-						Tab->EventA[Tab->EventANo].RegClass = 32;
-					}
-					else if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
-						Tab->EventA[Tab->EventANo].RegClass = 33;
-				}
-				else
-					Tab->EventA[Tab->EventANo].RegClass = ??;
-
-			}
-
-			Tab->EventANo ++;
-		}
-	}
-	else if (pHtCapability->HtCapInfo.Intolerant40)
-	{
-		Tab->EventBCountDown = pAd->CommonCfg.Dot11BssWidthChanTranDelay;
-	}
-
-}
-
-/*
-	========================================================================
-	Routine Description:
-		Trigger Event table Maintainence called once every second.
-
-	Arguments:
-	// IRQL = DISPATCH_LEVEL
-	========================================================================
-*/
-VOID TriEventCounterMaintenance(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	UCHAR		i;
-	BOOLEAN			bNotify = FALSE;
-	for (i = 0;i < MAX_TRIGGER_EVENT;i++)
-	{
-		if (pAd->CommonCfg.TriggerEventTab.EventA[i].bValid && (pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter > 0))
-		{
-			pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter--;
-			if (pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter == 0)
-			{
-				pAd->CommonCfg.TriggerEventTab.EventA[i].bValid = FALSE;
-				pAd->CommonCfg.TriggerEventTab.EventANo --;
-				// Need to send 20/40 Coexistence Notify frame if has status change.
-				bNotify = TRUE;
-			}
-		}
-	}
-	if (pAd->CommonCfg.TriggerEventTab.EventBCountDown > 0)
-	{
-		pAd->CommonCfg.TriggerEventTab.EventBCountDown--;
-		if (pAd->CommonCfg.TriggerEventTab.EventBCountDown == 0)
-			bNotify = TRUE;
-	}
-
-	if (bNotify == TRUE)
-		Update2040CoexistFrameAndNotify(pAd, BSSID_WCID, TRUE);
-}
-#endif // DOT11N_DRAFT3 //
-#endif // DOT11_N_SUPPORT //
-
-// IRQL = DISPATCH_LEVEL
-VOID BssTableSsidSort(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT BSS_TABLE *OutTab,
-	IN	CHAR Ssid[],
-	IN	UCHAR SsidLen)
-{
-	INT i;
-	BssTableInit(OutTab);
-
-	for (i = 0; i < pAd->ScanTab.BssNr; i++)
-	{
-		BSS_ENTRY *pInBss = &pAd->ScanTab.BssEntry[i];
-		BOOLEAN	bIsHiddenApIncluded = FALSE;
-
-		if (((pAd->CommonCfg.bIEEE80211H == 1) &&
-            (pAd->MlmeAux.Channel > 14) &&
-             RadarChannelCheck(pAd, pInBss->Channel))
-#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
-             || (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
-#endif // CARRIER_DETECTION_SUPPORT //
-            )
-{
-			if (pInBss->Hidden)
-				bIsHiddenApIncluded = TRUE;
-}
-
-		if ((pInBss->BssType == pAd->StaCfg.BssType) &&
-			(SSID_EQUAL(Ssid, SsidLen, pInBss->Ssid, pInBss->SsidLen) || bIsHiddenApIncluded))
-		{
-			BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
-
-
-#ifdef EXT_BUILD_CHANNEL_LIST
-			// If no Country IE exists no Connection will be established when IEEE80211dClientMode is strict.
-			if ((pAd->StaCfg.IEEE80211dClientMode == Rt802_11_D_Strict) &&
-				(pInBss->bHasCountryIE == FALSE))
-			{
-				DBGPRINT(RT_DEBUG_TRACE,("StaCfg.IEEE80211dClientMode == Rt802_11_D_Strict, but this AP doesn't have country IE.\n"));
-				continue;
-			}
-#endif // EXT_BUILD_CHANNEL_LIST //
-
-#ifdef DOT11_N_SUPPORT
-			// 2.4G/5G N only mode
-			if ((pInBss->HtCapabilityLen == 0) &&
-				((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
-			{
-				DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
-				continue;
-			}
-#endif // DOT11_N_SUPPORT //
-
-			// New for WPA2
-			// Check the Authmode first
-			if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-			{
-				// Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
-				if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
-					// None matched
-					continue;
-
-				// Check cipher suite, AP must have more secured cipher than station setting
-				if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
-				{
-					// If it's not mixed mode, we should only let BSS pass with the same encryption
-					if (pInBss->WPA.bMixMode == FALSE)
-						if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
-							continue;
-
-					// check group cipher
-					if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) &&
-						(pInBss->WPA.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
-						(pInBss->WPA.GroupCipher != Ndis802_11GroupWEP104Enabled))
-						continue;
-
-					// check pairwise cipher, skip if none matched
-					// If profile set to AES, let it pass without question.
-					// If profile set to TKIP, we must find one mateched
-					if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
-						(pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
-						(pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
-						continue;
-				}
-				else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
-				{
-					// If it's not mixed mode, we should only let BSS pass with the same encryption
-					if (pInBss->WPA2.bMixMode == FALSE)
-						if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
-							continue;
-
-					// check group cipher
-					if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) &&
-						(pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
-						(pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP104Enabled))
-						continue;
-
-					// check pairwise cipher, skip if none matched
-					// If profile set to AES, let it pass without question.
-					// If profile set to TKIP, we must find one mateched
-					if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
-						(pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
-						(pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
-						continue;
-				}
-			}
-			// Bss Type matched, SSID matched.
-			// We will check wepstatus for qualification Bss
-			else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
-			{
-				DBGPRINT(RT_DEBUG_TRACE,("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n", pAd->StaCfg.WepStatus, pInBss->WepStatus));
-				//
-				// For the SESv2 case, we will not qualify WepStatus.
-				//
-				if (!pInBss->bSES)
-					continue;
-			}
-
-			// Since the AP is using hidden SSID, and we are trying to connect to ANY
-			// It definitely will fail. So, skip it.
-			// CCX also require not even try to connect it!!
-			if (SsidLen == 0)
-				continue;
-
-#ifdef DOT11_N_SUPPORT
-			// If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
-			// If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
-			if ((pInBss->CentralChannel != pInBss->Channel) &&
-				(pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
-			{
-				if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
-				{
-					pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
-					SetCommonHT(pAd);
-					pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
-				}
-				else
-				{
-					if (pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BAND_WIDTH_20)
-					{
-						SetCommonHT(pAd);
-					}
-				}
-			}
-#endif // DOT11_N_SUPPORT //
-
-			// copy matching BSS from InTab to OutTab
-			NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
-
-			OutTab->BssNr++;
-		}
-		else if ((pInBss->BssType == pAd->StaCfg.BssType) && (SsidLen == 0))
-		{
-			BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
-
-
-#ifdef DOT11_N_SUPPORT
-			// 2.4G/5G N only mode
-			if ((pInBss->HtCapabilityLen == 0) &&
-				((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
-			{
-				DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
-				continue;
-			}
-#endif // DOT11_N_SUPPORT //
-
-			// New for WPA2
-			// Check the Authmode first
-			if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-			{
-				// Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
-				if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
-					// None matched
-					continue;
-
-				// Check cipher suite, AP must have more secured cipher than station setting
-				if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
-				{
-					// If it's not mixed mode, we should only let BSS pass with the same encryption
-					if (pInBss->WPA.bMixMode == FALSE)
-						if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
-							continue;
-
-					// check group cipher
-					if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
-						continue;
-
-					// check pairwise cipher, skip if none matched
-					// If profile set to AES, let it pass without question.
-					// If profile set to TKIP, we must find one mateched
-					if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
-						(pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
-						(pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
-						continue;
-				}
-				else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
-				{
-					// If it's not mixed mode, we should only let BSS pass with the same encryption
-					if (pInBss->WPA2.bMixMode == FALSE)
-						if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
-							continue;
-
-					// check group cipher
-					if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
-						continue;
-
-					// check pairwise cipher, skip if none matched
-					// If profile set to AES, let it pass without question.
-					// If profile set to TKIP, we must find one mateched
-					if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
-						(pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
-						(pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
-						continue;
-				}
-			}
-			// Bss Type matched, SSID matched.
-			// We will check wepstatus for qualification Bss
-			else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
-					continue;
-
-#ifdef DOT11_N_SUPPORT
-			// If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
-			// If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
-			if ((pInBss->CentralChannel != pInBss->Channel) &&
-				(pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
-			{
-				if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
-				{
-					pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
-					SetCommonHT(pAd);
-					pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
-				}
-			}
-#endif // DOT11_N_SUPPORT //
-
-			// copy matching BSS from InTab to OutTab
-			NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
-
-			OutTab->BssNr++;
-		}
-
-		if (OutTab->BssNr >= MAX_LEN_OF_BSS_TABLE)
-			break;
-	}
-
-	BssTableSortByRssi(OutTab);
-}
-
-
-// IRQL = DISPATCH_LEVEL
-VOID BssTableSortByRssi(
-	IN OUT BSS_TABLE *OutTab)
-{
-	INT	  i, j;
-	BSS_ENTRY TmpBss;
-
-	for (i = 0; i < OutTab->BssNr - 1; i++)
-	{
-		for (j = i+1; j < OutTab->BssNr; j++)
-		{
-			if (OutTab->BssEntry[j].Rssi > OutTab->BssEntry[i].Rssi)
-			{
-				NdisMoveMemory(&TmpBss, &OutTab->BssEntry[j], sizeof(BSS_ENTRY));
-				NdisMoveMemory(&OutTab->BssEntry[j], &OutTab->BssEntry[i], sizeof(BSS_ENTRY));
-				NdisMoveMemory(&OutTab->BssEntry[i], &TmpBss, sizeof(BSS_ENTRY));
-			}
-		}
-	}
-}
-#endif // CONFIG_STA_SUPPORT //
-
-
-VOID BssCipherParse(
-	IN OUT	PBSS_ENTRY	pBss)
-{
-	PEID_STRUCT		 pEid;
-	PUCHAR				pTmp;
-	PRSN_IE_HEADER_STRUCT			pRsnHeader;
-	PCIPHER_SUITE_STRUCT			pCipher;
-	PAKM_SUITE_STRUCT				pAKM;
-	USHORT							Count;
-	INT								Length;
-	NDIS_802_11_ENCRYPTION_STATUS	TmpCipher;
-
-	//
-	// WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame.
-	//
-	if (pBss->Privacy)
-	{
-		pBss->WepStatus		= Ndis802_11WEPEnabled;
-	}
-	else
-	{
-		pBss->WepStatus		= Ndis802_11WEPDisabled;
-	}
-	// Set default to disable & open authentication before parsing variable IE
-	pBss->AuthMode		= Ndis802_11AuthModeOpen;
-	pBss->AuthModeAux	= Ndis802_11AuthModeOpen;
-
-	// Init WPA setting
-	pBss->WPA.PairCipher	= Ndis802_11WEPDisabled;
-	pBss->WPA.PairCipherAux = Ndis802_11WEPDisabled;
-	pBss->WPA.GroupCipher	= Ndis802_11WEPDisabled;
-	pBss->WPA.RsnCapability = 0;
-	pBss->WPA.bMixMode		= FALSE;
-
-	// Init WPA2 setting
-	pBss->WPA2.PairCipher	 = Ndis802_11WEPDisabled;
-	pBss->WPA2.PairCipherAux = Ndis802_11WEPDisabled;
-	pBss->WPA2.GroupCipher	 = Ndis802_11WEPDisabled;
-	pBss->WPA2.RsnCapability = 0;
-	pBss->WPA2.bMixMode	 = FALSE;
-
-
-	Length = (INT) pBss->VarIELen;
-
-	while (Length > 0)
-	{
-		// Parse cipher suite base on WPA1 & WPA2, they should be parsed differently
-		pTmp = ((PUCHAR) pBss->VarIEs) + pBss->VarIELen - Length;
-		pEid = (PEID_STRUCT) pTmp;
-		switch (pEid->Eid)
-		{
-			case IE_WPA:
-				if (NdisEqualMemory(pEid->Octet, SES_OUI, 3) && (pEid->Len == 7))
-				{
-					pBss->bSES = TRUE;
-					break;
-				}
-				else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) != 1)
-				{
-					// if unsupported vendor specific IE
-					break;
-				}
-				// Skip OUI, version, and multicast suite
-				// This part should be improved in the future when AP supported multiple cipher suite.
-				// For now, it's OK since almost all APs have fixed cipher suite supported.
-				// pTmp = (PUCHAR) pEid->Octet;
-				pTmp   += 11;
-
-				// Cipher Suite Selectors from Spec P802.11i/D3.2 P26.
-				//	Value	   Meaning
-				//	0			None
-				//	1			WEP-40
-				//	2			Tkip
-				//	3			WRAP
-				//	4			AES
-				//	5			WEP-104
-				// Parse group cipher
-				switch (*pTmp)
-				{
-					case 1:
-						pBss->WPA.GroupCipher = Ndis802_11GroupWEP40Enabled;
-						break;
-					case 5:
-						pBss->WPA.GroupCipher = Ndis802_11GroupWEP104Enabled;
-						break;
-					case 2:
-						pBss->WPA.GroupCipher = Ndis802_11Encryption2Enabled;
-						break;
-					case 4:
-						pBss->WPA.GroupCipher = Ndis802_11Encryption3Enabled;
-						break;
-					default:
-						break;
-				}
-				// number of unicast suite
-				pTmp   += 1;
-
-				// skip all unicast cipher suites
-				//Count = *(PUSHORT) pTmp;
-				Count = (pTmp[1]<<8) + pTmp[0];
-				pTmp   += sizeof(USHORT);
-
-				// Parsing all unicast cipher suite
-				while (Count > 0)
-				{
-					// Skip OUI
-					pTmp += 3;
-					TmpCipher = Ndis802_11WEPDisabled;
-					switch (*pTmp)
-					{
-						case 1:
-						case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
-							TmpCipher = Ndis802_11Encryption1Enabled;
-							break;
-						case 2:
-							TmpCipher = Ndis802_11Encryption2Enabled;
-							break;
-						case 4:
-							TmpCipher = Ndis802_11Encryption3Enabled;
-							break;
-						default:
-							break;
-					}
-					if (TmpCipher > pBss->WPA.PairCipher)
-					{
-						// Move the lower cipher suite to PairCipherAux
-						pBss->WPA.PairCipherAux = pBss->WPA.PairCipher;
-						pBss->WPA.PairCipher	= TmpCipher;
-					}
-					else
-					{
-						pBss->WPA.PairCipherAux = TmpCipher;
-					}
-					pTmp++;
-					Count--;
-				}
-
-				// 4. get AKM suite counts
-				//Count	= *(PUSHORT) pTmp;
-				Count = (pTmp[1]<<8) + pTmp[0];
-				pTmp   += sizeof(USHORT);
-				pTmp   += 3;
-
-				switch (*pTmp)
-				{
-					case 1:
-						// Set AP support WPA-enterprise mode
-						if (pBss->AuthMode == Ndis802_11AuthModeOpen)
-							pBss->AuthMode = Ndis802_11AuthModeWPA;
-						else
-							pBss->AuthModeAux = Ndis802_11AuthModeWPA;
-						break;
-					case 2:
-						// Set AP support WPA-PSK mode
-						if (pBss->AuthMode == Ndis802_11AuthModeOpen)
-							pBss->AuthMode = Ndis802_11AuthModeWPAPSK;
-						else
-							pBss->AuthModeAux = Ndis802_11AuthModeWPAPSK;
-						break;
-					default:
-						break;
-				}
-				pTmp   += 1;
-
-				// Fixed for WPA-None
-				if (pBss->BssType == BSS_ADHOC)
-				{
-					pBss->AuthMode	  = Ndis802_11AuthModeWPANone;
-					pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
-					pBss->WepStatus   = pBss->WPA.GroupCipher;
-					// Patched bugs for old driver
-					if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
-						pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
-				}
-				else
-					pBss->WepStatus   = pBss->WPA.PairCipher;
-
-				// Check the Pair & Group, if different, turn on mixed mode flag
-				if (pBss->WPA.GroupCipher != pBss->WPA.PairCipher)
-					pBss->WPA.bMixMode = TRUE;
-
-				break;
-
-			case IE_RSN:
-				pRsnHeader = (PRSN_IE_HEADER_STRUCT) pTmp;
-
-				// 0. Version must be 1
-				if (le2cpu16(pRsnHeader->Version) != 1)
-					break;
-				pTmp   += sizeof(RSN_IE_HEADER_STRUCT);
-
-				// 1. Check group cipher
-				pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
-				if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
-					break;
-
-				// Parse group cipher
-				switch (pCipher->Type)
-				{
-					case 1:
-						pBss->WPA2.GroupCipher = Ndis802_11GroupWEP40Enabled;
-						break;
-					case 5:
-						pBss->WPA2.GroupCipher = Ndis802_11GroupWEP104Enabled;
-						break;
-					case 2:
-						pBss->WPA2.GroupCipher = Ndis802_11Encryption2Enabled;
-						break;
-					case 4:
-						pBss->WPA2.GroupCipher = Ndis802_11Encryption3Enabled;
-						break;
-					default:
-						break;
-				}
-				// set to correct offset for next parsing
-				pTmp   += sizeof(CIPHER_SUITE_STRUCT);
-
-				// 2. Get pairwise cipher counts
-				//Count = *(PUSHORT) pTmp;
-				Count = (pTmp[1]<<8) + pTmp[0];
-				pTmp   += sizeof(USHORT);
-
-				// 3. Get pairwise cipher
-				// Parsing all unicast cipher suite
-				while (Count > 0)
-				{
-					// Skip OUI
-					pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
-					TmpCipher = Ndis802_11WEPDisabled;
-					switch (pCipher->Type)
-					{
-						case 1:
-						case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
-							TmpCipher = Ndis802_11Encryption1Enabled;
-							break;
-						case 2:
-							TmpCipher = Ndis802_11Encryption2Enabled;
-							break;
-						case 4:
-							TmpCipher = Ndis802_11Encryption3Enabled;
-							break;
-						default:
-							break;
-					}
-					if (TmpCipher > pBss->WPA2.PairCipher)
-					{
-						// Move the lower cipher suite to PairCipherAux
-						pBss->WPA2.PairCipherAux = pBss->WPA2.PairCipher;
-						pBss->WPA2.PairCipher	 = TmpCipher;
-					}
-					else
-					{
-						pBss->WPA2.PairCipherAux = TmpCipher;
-					}
-					pTmp += sizeof(CIPHER_SUITE_STRUCT);
-					Count--;
-				}
-
-				// 4. get AKM suite counts
-				//Count	= *(PUSHORT) pTmp;
-				Count = (pTmp[1]<<8) + pTmp[0];
-				pTmp   += sizeof(USHORT);
-
-				// 5. Get AKM ciphers
-				// Parsing all AKM ciphers
-				while (Count > 0)
-				{
-					pAKM = (PAKM_SUITE_STRUCT) pTmp;
-					if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
-						break;
-
-					switch (pAKM->Type)
-					{
-						case 1:
-							// Set AP support WPA-enterprise mode
-							if (pBss->AuthMode == Ndis802_11AuthModeOpen)
-								pBss->AuthMode = Ndis802_11AuthModeWPA2;
-							else
-								pBss->AuthModeAux = Ndis802_11AuthModeWPA2;
-							break;
-						case 2:
-							// Set AP support WPA-PSK mode
-							if (pBss->AuthMode == Ndis802_11AuthModeOpen)
-								pBss->AuthMode = Ndis802_11AuthModeWPA2PSK;
-							else
-								pBss->AuthModeAux = Ndis802_11AuthModeWPA2PSK;
-							break;
-						default:
-							if (pBss->AuthMode == Ndis802_11AuthModeOpen)
-								pBss->AuthMode = Ndis802_11AuthModeMax;
-							else
-								pBss->AuthModeAux = Ndis802_11AuthModeMax;
-							break;
-					}
-					pTmp   += (Count * sizeof(AKM_SUITE_STRUCT));
-					Count--;
-				}
-
-				// Fixed for WPA-None
-				if (pBss->BssType == BSS_ADHOC)
-				{
-					pBss->AuthMode = Ndis802_11AuthModeWPANone;
-					pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
-					pBss->WPA.PairCipherAux = pBss->WPA2.PairCipherAux;
-					pBss->WPA.GroupCipher	= pBss->WPA2.GroupCipher;
-					pBss->WepStatus			= pBss->WPA.GroupCipher;
-					// Patched bugs for old driver
-					if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
-						pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
-				}
-				pBss->WepStatus   = pBss->WPA2.PairCipher;
-
-				// 6. Get RSN capability
-				//pBss->WPA2.RsnCapability = *(PUSHORT) pTmp;
-				pBss->WPA2.RsnCapability = (pTmp[1]<<8) + pTmp[0];
-				pTmp += sizeof(USHORT);
-
-				// Check the Pair & Group, if different, turn on mixed mode flag
-				if (pBss->WPA2.GroupCipher != pBss->WPA2.PairCipher)
-					pBss->WPA2.bMixMode = TRUE;
-
-				break;
-			default:
-				break;
-		}
-		Length -= (pEid->Len + 2);
-	}
-}
-
-// ===========================================================================================
-// mac_table.c
-// ===========================================================================================
-
-/*! \brief generates a random mac address value for IBSS BSSID
- *	\param Addr the bssid location
- *	\return none
- *	\pre
- *	\post
- */
-VOID MacAddrRandomBssid(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pAddr)
-{
-	INT i;
-
-	for (i = 0; i < MAC_ADDR_LEN; i++)
-	{
-		pAddr[i] = RandomByte(pAd);
-	}
-
-	pAddr[0] = (pAddr[0] & 0xfe) | 0x02;  // the first 2 bits must be 01xxxxxxxx
-}
-
-/*! \brief init the management mac frame header
- *	\param p_hdr mac header
- *	\param subtype subtype of the frame
- *	\param p_ds destination address, don't care if it is a broadcast address
- *	\return none
- *	\pre the station has the following information in the pAd->StaCfg
- *	 - bssid
- *	 - station address
- *	\post
- *	\note this function initializes the following field
-
- IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
-
- */
-VOID MgtMacHeaderInit(
-	IN	PRTMP_ADAPTER	pAd,
-	IN OUT PHEADER_802_11 pHdr80211,
-	IN UCHAR SubType,
-	IN UCHAR ToDs,
-	IN PUCHAR pDA,
-	IN PUCHAR pBssid)
-{
-	NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
-
-	pHdr80211->FC.Type = BTYPE_MGMT;
-	pHdr80211->FC.SubType = SubType;
-//	if (SubType == SUBTYPE_ACK)	// sample, no use, it will conflict with ACTION frame sub type
-//		pHdr80211->FC.Type = BTYPE_CNTL;
-	pHdr80211->FC.ToDs = ToDs;
-	COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
-#endif // CONFIG_STA_SUPPORT //
-	COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
-}
-
-// ===========================================================================================
-// mem_mgmt.c
-// ===========================================================================================
-
-/*!***************************************************************************
- * This routine build an outgoing frame, and fill all information specified
- * in argument list to the frame body. The actual frame size is the summation
- * of all arguments.
- * input params:
- *		Buffer - pointer to a pre-allocated memory segment
- *		args - a list of <int arg_size, arg> pairs.
- *		NOTE NOTE NOTE!!!! the last argument must be NULL, otherwise this
- *						   function will FAIL!!!
- * return:
- *		Size of the buffer
- * usage:
- *		MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS);
-
- IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
-
- ****************************************************************************/
-ULONG MakeOutgoingFrame(
-	OUT UCHAR *Buffer,
-	OUT ULONG *FrameLen, ...)
-{
-	UCHAR   *p;
-	int	leng;
-	ULONG	TotLeng;
-	va_list Args;
-
-	// calculates the total length
-	TotLeng = 0;
-	va_start(Args, FrameLen);
-	do
-	{
-		leng = va_arg(Args, int);
-		if (leng == END_OF_ARGS)
-		{
-			break;
-		}
-		p = va_arg(Args, PVOID);
-		NdisMoveMemory(&Buffer[TotLeng], p, leng);
-		TotLeng = TotLeng + leng;
-	} while(TRUE);
-
-	va_end(Args); /* clean up */
-	*FrameLen = TotLeng;
-	return TotLeng;
-}
-
-// ===========================================================================================
-// mlme_queue.c
-// ===========================================================================================
-
-/*! \brief	Initialize The MLME Queue, used by MLME Functions
- *	\param	*Queue	   The MLME Queue
- *	\return Always	   Return NDIS_STATE_SUCCESS in this implementation
- *	\pre
- *	\post
- *	\note	Because this is done only once (at the init stage), no need to be locked
-
- IRQL = PASSIVE_LEVEL
-
- */
-NDIS_STATUS MlmeQueueInit(
-	IN MLME_QUEUE *Queue)
-{
-	INT i;
-
-	NdisAllocateSpinLock(&Queue->Lock);
-
-	Queue->Num	= 0;
-	Queue->Head = 0;
-	Queue->Tail = 0;
-
-	for (i = 0; i < MAX_LEN_OF_MLME_QUEUE; i++)
-	{
-		Queue->Entry[i].Occupied = FALSE;
-		Queue->Entry[i].MsgLen = 0;
-		NdisZeroMemory(Queue->Entry[i].Msg, MGMT_DMA_BUFFER_SIZE);
-	}
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-/*! \brief	 Enqueue a message for other threads, if they want to send messages to MLME thread
- *	\param	*Queue	  The MLME Queue
- *	\param	 Machine  The State Machine Id
- *	\param	 MsgType  The Message Type
- *	\param	 MsgLen   The Message length
- *	\param	*Msg	  The message pointer
- *	\return  TRUE if enqueue is successful, FALSE if the queue is full
- *	\pre
- *	\post
- *	\note	 The message has to be initialized
-
- IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
-
- */
-BOOLEAN MlmeEnqueue(
-	IN	PRTMP_ADAPTER	pAd,
-	IN ULONG Machine,
-	IN ULONG MsgType,
-	IN ULONG MsgLen,
-	IN VOID *Msg)
-{
-	INT Tail;
-	MLME_QUEUE	*Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return FALSE;
-
-	// First check the size, it MUST not exceed the mlme queue size
-	if (MsgLen > MGMT_DMA_BUFFER_SIZE)
-	{
-		DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n", MsgLen));
-		return FALSE;
-	}
-
-	if (MlmeQueueFull(Queue))
-	{
-		return FALSE;
-	}
-
-	NdisAcquireSpinLock(&(Queue->Lock));
-	Tail = Queue->Tail;
-	Queue->Tail++;
-	Queue->Num++;
-	if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
-	{
-		Queue->Tail = 0;
-	}
-
-	Queue->Entry[Tail].Wcid = RESERVED_WCID;
-	Queue->Entry[Tail].Occupied = TRUE;
-	Queue->Entry[Tail].Machine = Machine;
-	Queue->Entry[Tail].MsgType = MsgType;
-	Queue->Entry[Tail].MsgLen  = MsgLen;
-
-	if (Msg != NULL)
-	{
-		NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
-	}
-
-	NdisReleaseSpinLock(&(Queue->Lock));
-	return TRUE;
-}
-
-/*! \brief	 This function is used when Recv gets a MLME message
- *	\param	*Queue			 The MLME Queue
- *	\param	 TimeStampHigh	 The upper 32 bit of timestamp
- *	\param	 TimeStampLow	 The lower 32 bit of timestamp
- *	\param	 Rssi			 The receiving RSSI strength
- *	\param	 MsgLen			 The length of the message
- *	\param	*Msg			 The message pointer
- *	\return  TRUE if everything ok, FALSE otherwise (like Queue Full)
- *	\pre
- *	\post
-
- IRQL = DISPATCH_LEVEL
-
- */
-BOOLEAN MlmeEnqueueForRecv(
-	IN	PRTMP_ADAPTER	pAd,
-	IN ULONG Wcid,
-	IN ULONG TimeStampHigh,
-	IN ULONG TimeStampLow,
-	IN UCHAR Rssi0,
-	IN UCHAR Rssi1,
-	IN UCHAR Rssi2,
-	IN ULONG MsgLen,
-	IN VOID *Msg,
-	IN UCHAR Signal)
-{
-	INT		 Tail, Machine;
-	PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
-	INT		 MsgType;
-	MLME_QUEUE	*Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
-
-#ifdef RALINK_ATE
-	/* Nothing to do in ATE mode */
-	if(ATE_ON(pAd))
-		return FALSE;
-#endif // RALINK_ATE //
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-	{
-		DBGPRINT_ERR(("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n"));
-		return FALSE;
-	}
-
-	// First check the size, it MUST not exceed the mlme queue size
-	if (MsgLen > MGMT_DMA_BUFFER_SIZE)
-	{
-		DBGPRINT_ERR(("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
-		return FALSE;
-	}
-
-	if (MlmeQueueFull(Queue))
-	{
-		return FALSE;
-	}
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType))
-		{
-			DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n",pFrame->Hdr.FC.SubType));
-			return FALSE;
-		}
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	// OK, we got all the informations, it is time to put things into queue
-	NdisAcquireSpinLock(&(Queue->Lock));
-	Tail = Queue->Tail;
-	Queue->Tail++;
-	Queue->Num++;
-	if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
-	{
-		Queue->Tail = 0;
-	}
-	Queue->Entry[Tail].Occupied = TRUE;
-	Queue->Entry[Tail].Machine = Machine;
-	Queue->Entry[Tail].MsgType = MsgType;
-	Queue->Entry[Tail].MsgLen  = MsgLen;
-	Queue->Entry[Tail].TimeStamp.u.LowPart = TimeStampLow;
-	Queue->Entry[Tail].TimeStamp.u.HighPart = TimeStampHigh;
-	Queue->Entry[Tail].Rssi0 = Rssi0;
-	Queue->Entry[Tail].Rssi1 = Rssi1;
-	Queue->Entry[Tail].Rssi2 = Rssi2;
-	Queue->Entry[Tail].Signal = Signal;
-	Queue->Entry[Tail].Wcid = (UCHAR)Wcid;
-
-	Queue->Entry[Tail].Channel = pAd->LatchRfRegs.Channel;
-
-	if (Msg != NULL)
-	{
-		NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
-	}
-
-	NdisReleaseSpinLock(&(Queue->Lock));
-
-	RTMP_MLME_HANDLER(pAd);
-
-	return TRUE;
-}
-
-
-/*! \brief	 Dequeue a message from the MLME Queue
- *	\param	*Queue	  The MLME Queue
- *	\param	*Elem	  The message dequeued from MLME Queue
- *	\return  TRUE if the Elem contains something, FALSE otherwise
- *	\pre
- *	\post
-
- IRQL = DISPATCH_LEVEL
-
- */
-BOOLEAN MlmeDequeue(
-	IN MLME_QUEUE *Queue,
-	OUT MLME_QUEUE_ELEM **Elem)
-{
-	NdisAcquireSpinLock(&(Queue->Lock));
-	*Elem = &(Queue->Entry[Queue->Head]);
-	Queue->Num--;
-	Queue->Head++;
-	if (Queue->Head == MAX_LEN_OF_MLME_QUEUE)
-	{
-		Queue->Head = 0;
-	}
-	NdisReleaseSpinLock(&(Queue->Lock));
-	return TRUE;
-}
-
-// IRQL = DISPATCH_LEVEL
-VOID	MlmeRestartStateMachine(
-	IN	PRTMP_ADAPTER	pAd)
-{
-#ifdef RTMP_MAC_PCI
-	MLME_QUEUE_ELEM		*Elem = NULL;
-#endif // RTMP_MAC_PCI //
-#ifdef CONFIG_STA_SUPPORT
-	BOOLEAN				Cancelled;
-#endif // CONFIG_STA_SUPPORT //
-
-	DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n"));
-
-#ifdef RTMP_MAC_PCI
-	NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
-	if(pAd->Mlme.bRunning)
-	{
-		NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
-		return;
-	}
-	else
-	{
-		pAd->Mlme.bRunning = TRUE;
-	}
-	NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
-
-	// Remove all Mlme queues elements
-	while (!MlmeQueueEmpty(&pAd->Mlme.Queue))
-	{
-		//From message type, determine which state machine I should drive
-		if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
-		{
-			// free MLME element
-			Elem->Occupied = FALSE;
-			Elem->MsgLen = 0;
-
-		}
-		else {
-			DBGPRINT_ERR(("MlmeRestartStateMachine: MlmeQueue empty\n"));
-		}
-	}
-#endif // RTMP_MAC_PCI //
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-#ifdef QOS_DLS_SUPPORT
-		UCHAR i;
-#endif // QOS_DLS_SUPPORT //
-		// Cancel all timer events
-		// Be careful to cancel new added timer
-		RTMPCancelTimer(&pAd->MlmeAux.AssocTimer,	  &Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer,   &Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer,  &Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.AuthTimer,	   &Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer,	   &Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.ScanTimer,	   &Cancelled);
-
-#ifdef QOS_DLS_SUPPORT
-		for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
-		{
-			RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &Cancelled);
-		}
-#endif // QOS_DLS_SUPPORT //
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	// Change back to original channel in case of doing scan
-	AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-	AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-
-	// Resume MSDU which is turned off durning scan
-	RTMPResumeMsduTransmission(pAd);
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		// Set all state machines back IDLE
-		pAd->Mlme.CntlMachine.CurrState    = CNTL_IDLE;
-		pAd->Mlme.AssocMachine.CurrState   = ASSOC_IDLE;
-		pAd->Mlme.AuthMachine.CurrState    = AUTH_REQ_IDLE;
-		pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE;
-		pAd->Mlme.SyncMachine.CurrState    = SYNC_IDLE;
-		pAd->Mlme.ActMachine.CurrState    = ACT_IDLE;
-#ifdef QOS_DLS_SUPPORT
-		pAd->Mlme.DlsMachine.CurrState    = DLS_IDLE;
-#endif // QOS_DLS_SUPPORT //
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef RTMP_MAC_PCI
-	// Remove running state
-	NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
-	pAd->Mlme.bRunning = FALSE;
-	NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
-#endif // RTMP_MAC_PCI //
-}
-
-/*! \brief	test if the MLME Queue is empty
- *	\param	*Queue	  The MLME Queue
- *	\return TRUE if the Queue is empty, FALSE otherwise
- *	\pre
- *	\post
-
- IRQL = DISPATCH_LEVEL
-
- */
-BOOLEAN MlmeQueueEmpty(
-	IN MLME_QUEUE *Queue)
-{
-	BOOLEAN Ans;
-
-	NdisAcquireSpinLock(&(Queue->Lock));
-	Ans = (Queue->Num == 0);
-	NdisReleaseSpinLock(&(Queue->Lock));
-
-	return Ans;
-}
-
-/*! \brief	 test if the MLME Queue is full
- *	\param	 *Queue		 The MLME Queue
- *	\return  TRUE if the Queue is empty, FALSE otherwise
- *	\pre
- *	\post
-
- IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
-
- */
-BOOLEAN MlmeQueueFull(
-	IN MLME_QUEUE *Queue)
-{
-	BOOLEAN Ans;
-
-	NdisAcquireSpinLock(&(Queue->Lock));
-	Ans = (Queue->Num == MAX_LEN_OF_MLME_QUEUE || Queue->Entry[Queue->Tail].Occupied);
-	NdisReleaseSpinLock(&(Queue->Lock));
-
-	return Ans;
-}
-
-/*! \brief	 The destructor of MLME Queue
- *	\param
- *	\return
- *	\pre
- *	\post
- *	\note	Clear Mlme Queue, Set Queue->Num to Zero.
-
- IRQL = PASSIVE_LEVEL
-
- */
-VOID MlmeQueueDestroy(
-	IN MLME_QUEUE *pQueue)
-{
-	NdisAcquireSpinLock(&(pQueue->Lock));
-	pQueue->Num  = 0;
-	pQueue->Head = 0;
-	pQueue->Tail = 0;
-	NdisReleaseSpinLock(&(pQueue->Lock));
-	NdisFreeSpinLock(&(pQueue->Lock));
-}
-
-
-/*! \brief	 To substitute the message type if the message is coming from external
- *	\param	pFrame		   The frame received
- *	\param	*Machine	   The state machine
- *	\param	*MsgType	   the message type for the state machine
- *	\return TRUE if the substitution is successful, FALSE otherwise
- *	\pre
- *	\post
-
- IRQL = DISPATCH_LEVEL
-
- */
-#ifdef CONFIG_STA_SUPPORT
-BOOLEAN MsgTypeSubst(
-	IN PRTMP_ADAPTER  pAd,
-	IN PFRAME_802_11 pFrame,
-	OUT INT *Machine,
-	OUT INT *MsgType)
-{
-	USHORT	Seq, Alg;
-	UCHAR	EAPType;
-	PUCHAR	pData;
-
-	// Pointer to start of data frames including SNAP header
-	pData = (PUCHAR) pFrame + LENGTH_802_11;
-
-	// The only data type will pass to this function is EAPOL frame
-	if (pFrame->Hdr.FC.Type == BTYPE_DATA)
-	{
-		{
-	        *Machine = WPA_STATE_MACHINE;
-			EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
-	        return (WpaMsgTypeSubst(EAPType, (INT *) MsgType));
-		}
-	}
-
-	switch (pFrame->Hdr.FC.SubType)
-	{
-		case SUBTYPE_ASSOC_REQ:
-			*Machine = ASSOC_STATE_MACHINE;
-			*MsgType = MT2_PEER_ASSOC_REQ;
-			break;
-		case SUBTYPE_ASSOC_RSP:
-			*Machine = ASSOC_STATE_MACHINE;
-			*MsgType = MT2_PEER_ASSOC_RSP;
-			break;
-		case SUBTYPE_REASSOC_REQ:
-			*Machine = ASSOC_STATE_MACHINE;
-			*MsgType = MT2_PEER_REASSOC_REQ;
-			break;
-		case SUBTYPE_REASSOC_RSP:
-			*Machine = ASSOC_STATE_MACHINE;
-			*MsgType = MT2_PEER_REASSOC_RSP;
-			break;
-		case SUBTYPE_PROBE_REQ:
-			*Machine = SYNC_STATE_MACHINE;
-			*MsgType = MT2_PEER_PROBE_REQ;
-			break;
-		case SUBTYPE_PROBE_RSP:
-			*Machine = SYNC_STATE_MACHINE;
-			*MsgType = MT2_PEER_PROBE_RSP;
-			break;
-		case SUBTYPE_BEACON:
-			*Machine = SYNC_STATE_MACHINE;
-			*MsgType = MT2_PEER_BEACON;
-			break;
-		case SUBTYPE_ATIM:
-			*Machine = SYNC_STATE_MACHINE;
-			*MsgType = MT2_PEER_ATIM;
-			break;
-		case SUBTYPE_DISASSOC:
-			*Machine = ASSOC_STATE_MACHINE;
-			*MsgType = MT2_PEER_DISASSOC_REQ;
-			break;
-		case SUBTYPE_AUTH:
-			// get the sequence number from payload 24 Mac Header + 2 bytes algorithm
-			NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(USHORT));
-			NdisMoveMemory(&Alg, &pFrame->Octet[0], sizeof(USHORT));
-			if (Seq == 1 || Seq == 3)
-			{
-				*Machine = AUTH_RSP_STATE_MACHINE;
-				*MsgType = MT2_PEER_AUTH_ODD;
-			}
-			else if (Seq == 2 || Seq == 4)
-			{
-				if (Alg == AUTH_MODE_OPEN || Alg == AUTH_MODE_KEY)
-				{
-					*Machine = AUTH_STATE_MACHINE;
-					*MsgType = MT2_PEER_AUTH_EVEN;
-				}
-			}
-			else
-			{
-				return FALSE;
-			}
-			break;
-		case SUBTYPE_DEAUTH:
-			*Machine = AUTH_RSP_STATE_MACHINE;
-			*MsgType = MT2_PEER_DEAUTH;
-			break;
-		case SUBTYPE_ACTION:
-			*Machine = ACTION_STATE_MACHINE;
-			//  Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support
-			if ((pFrame->Octet[0]&0x7F) > MAX_PEER_CATE_MSG)
-			{
-				*MsgType = MT2_ACT_INVALID;
-			}
-			else
-			{
-				*MsgType = (pFrame->Octet[0]&0x7F);
-			}
-			break;
-		default:
-			return FALSE;
-			break;
-	}
-
-	return TRUE;
-}
-#endif // CONFIG_STA_SUPPORT //
-
-// ===========================================================================================
-// state_machine.c
-// ===========================================================================================
-
-/*! \brief Initialize the state machine.
- *	\param *S			pointer to the state machine
- *	\param	Trans		State machine transition function
- *	\param	StNr		number of states
- *	\param	MsgNr		number of messages
- *	\param	DefFunc		default function, when there is invalid state/message combination
- *	\param	InitState	initial state of the state machine
- *	\param	Base		StateMachine base, internal use only
- *	\pre p_sm should be a legal pointer
- *	\post
-
- IRQL = PASSIVE_LEVEL
-
- */
-VOID StateMachineInit(
-	IN STATE_MACHINE *S,
-	IN STATE_MACHINE_FUNC Trans[],
-	IN ULONG StNr,
-	IN ULONG MsgNr,
-	IN STATE_MACHINE_FUNC DefFunc,
-	IN ULONG InitState,
-	IN ULONG Base)
-{
-	ULONG i, j;
-
-	// set number of states and messages
-	S->NrState = StNr;
-	S->NrMsg   = MsgNr;
-	S->Base    = Base;
-
-	S->TransFunc  = Trans;
-
-	// init all state transition to default function
-	for (i = 0; i < StNr; i++)
-	{
-		for (j = 0; j < MsgNr; j++)
-		{
-			S->TransFunc[i * MsgNr + j] = DefFunc;
-		}
-	}
-
-	// set the starting state
-	S->CurrState = InitState;
-}
-
-/*! \brief This function fills in the function pointer into the cell in the state machine
- *	\param *S	pointer to the state machine
- *	\param St	state
- *	\param Msg	incoming message
- *	\param f	the function to be executed when (state, message) combination occurs at the state machine
- *	\pre *S should be a legal pointer to the state machine, st, msg, should be all within the range, Base should be set in the initial state
- *	\post
-
- IRQL = PASSIVE_LEVEL
-
- */
-VOID StateMachineSetAction(
-	IN STATE_MACHINE *S,
-	IN ULONG St,
-	IN ULONG Msg,
-	IN STATE_MACHINE_FUNC Func)
-{
-	ULONG MsgIdx;
-
-	MsgIdx = Msg - S->Base;
-
-	if (St < S->NrState && MsgIdx < S->NrMsg)
-	{
-		// boundary checking before setting the action
-		S->TransFunc[St * S->NrMsg + MsgIdx] = Func;
-	}
-}
-
-/*! \brief	 This function does the state transition
- *	\param	 *Adapter the NIC adapter pointer
- *	\param	 *S	  the state machine
- *	\param	 *Elem	  the message to be executed
- *	\return   None
-
- IRQL = DISPATCH_LEVEL
-
- */
-VOID StateMachinePerformAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN STATE_MACHINE *S,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	(*(S->TransFunc[S->CurrState * S->NrMsg + Elem->MsgType - S->Base]))(pAd, Elem);
-}
-
-/*
-	==========================================================================
-	Description:
-		The drop function, when machine executes this, the message is simply
-		ignored. This function does nothing, the message is freed in
-		StateMachinePerformAction()
-	==========================================================================
- */
-VOID Drop(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-}
-
-// ===========================================================================================
-// lfsr.c
-// ===========================================================================================
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = PASSIVE_LEVEL
-
-	==========================================================================
- */
-VOID LfsrInit(
-	IN PRTMP_ADAPTER pAd,
-	IN ULONG Seed)
-{
-	if (Seed == 0)
-		pAd->Mlme.ShiftReg = 1;
-	else
-		pAd->Mlme.ShiftReg = Seed;
-}
-
-/*
-	==========================================================================
-	Description:
-	==========================================================================
- */
-UCHAR RandomByte(
-	IN PRTMP_ADAPTER pAd)
-{
-	ULONG i;
-	UCHAR R, Result;
-
-	R = 0;
-
-	if (pAd->Mlme.ShiftReg == 0)
-	NdisGetSystemUpTime((ULONG *)&pAd->Mlme.ShiftReg);
-
-	for (i = 0; i < 8; i++)
-	{
-		if (pAd->Mlme.ShiftReg & 0x00000001)
-		{
-			pAd->Mlme.ShiftReg = ((pAd->Mlme.ShiftReg ^ LFSR_MASK) >> 1) | 0x80000000;
-			Result = 1;
-		}
-		else
-		{
-			pAd->Mlme.ShiftReg = pAd->Mlme.ShiftReg >> 1;
-			Result = 0;
-		}
-		R = (R << 1) | Result;
-	}
-
-	return R;
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Verify the support rate for different PHY type
-
-	Arguments:
-		pAd				Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	========================================================================
-*/
-VOID	RTMPCheckRates(
-	IN		PRTMP_ADAPTER	pAd,
-	IN OUT	UCHAR			SupRate[],
-	IN OUT	UCHAR			*SupRateLen)
-{
-	UCHAR	RateIdx, i, j;
-	UCHAR	NewRate[12], NewRateLen;
-
-	NewRateLen = 0;
-
-	if (pAd->CommonCfg.PhyMode == PHY_11B)
-		RateIdx = 4;
-	else
-		RateIdx = 12;
-
-	// Check for support rates exclude basic rate bit
-	for (i = 0; i < *SupRateLen; i++)
-		for (j = 0; j < RateIdx; j++)
-			if ((SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
-				NewRate[NewRateLen++] = SupRate[i];
-
-	*SupRateLen = NewRateLen;
-	NdisMoveMemory(SupRate, NewRate, NewRateLen);
-}
-
-#ifdef CONFIG_STA_SUPPORT
-#ifdef DOT11_N_SUPPORT
-BOOLEAN RTMPCheckChannel(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR		CentralChannel,
-	IN UCHAR		Channel)
-{
-	UCHAR		k;
-	UCHAR		UpperChannel = 0, LowerChannel = 0;
-	UCHAR		NoEffectChannelinList = 0;
-
-	// Find upper and lower channel according to 40MHz current operation.
-	if (CentralChannel < Channel)
-	{
-		UpperChannel = Channel;
-		if (CentralChannel > 2)
-			LowerChannel = CentralChannel - 2;
-		else
-			return FALSE;
-	}
-	else if (CentralChannel > Channel)
-	{
-		UpperChannel = CentralChannel + 2;
-		LowerChannel = Channel;
-	}
-
-	for (k = 0;k < pAd->ChannelListNum;k++)
-	{
-		if (pAd->ChannelList[k].Channel == UpperChannel)
-		{
-			NoEffectChannelinList ++;
-		}
-		if (pAd->ChannelList[k].Channel == LowerChannel)
-		{
-			NoEffectChannelinList ++;
-		}
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,("Total Channel in Channel List = [%d]\n", NoEffectChannelinList));
-	if (NoEffectChannelinList == 2)
-		return TRUE;
-	else
-		return FALSE;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Verify the support rate for HT phy type
-
-	Arguments:
-		pAd				Pointer to our adapter
-
-	Return Value:
-		FALSE if pAd->CommonCfg.SupportedHtPhy doesn't accept the pHtCapability.  (AP Mode)
-
-	IRQL = PASSIVE_LEVEL
-
-	========================================================================
-*/
-BOOLEAN		RTMPCheckHt(
-	IN	PRTMP_ADAPTER			pAd,
-	IN	UCHAR					Wcid,
-	IN	HT_CAPABILITY_IE		*pHtCapability,
-	IN	ADD_HT_INFO_IE			*pAddHtInfo)
-{
-	if (Wcid >= MAX_LEN_OF_MAC_TABLE)
-		return FALSE;
-
-	// If use AMSDU, set flag.
-	if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable)
-		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_AMSDU_INUSED);
-	// Save Peer Capability
-	if (pHtCapability->HtCapInfo.ShortGIfor20)
-		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI20_CAPABLE);
-	if (pHtCapability->HtCapInfo.ShortGIfor40)
-		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI40_CAPABLE);
-	if (pHtCapability->HtCapInfo.TxSTBC)
-		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_TxSTBC_CAPABLE);
-	if (pHtCapability->HtCapInfo.RxSTBC)
-		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RxSTBC_CAPABLE);
-	if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport)
-	{
-		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RDG_CAPABLE);
-	}
-
-	if (Wcid < MAX_LEN_OF_MAC_TABLE)
-	{
-		pAd->MacTab.Content[Wcid].MpduDensity = pHtCapability->HtCapParm.MpduDensity;
-	}
-
-	// Will check ChannelWidth for MCSSet[4] below
-	pAd->MlmeAux.HtCapability.MCSSet[4] = 0x1;
-    switch (pAd->CommonCfg.RxStream)
-	{
-		case 1:
-			pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
-			pAd->MlmeAux.HtCapability.MCSSet[1] = 0x00;
-            pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
-            pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
-			break;
-		case 2:
-			pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
-			pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
-            pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
-            pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
-			break;
-		case 3:
-			pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
-			pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
-            pAd->MlmeAux.HtCapability.MCSSet[2] = 0xff;
-            pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
-			break;
-	}
-
-	pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth = pAddHtInfo->AddHtInfo.RecomWidth & pAd->CommonCfg.DesiredHtPhy.ChannelWidth;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("RTMPCheckHt:: HtCapInfo.ChannelWidth=%d, RecomWidth=%d, DesiredHtPhy.ChannelWidth=%d, BW40MAvailForA/G=%d/%d, PhyMode=%d \n",
-		pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth, pAddHtInfo->AddHtInfo.RecomWidth, pAd->CommonCfg.DesiredHtPhy.ChannelWidth,
-		pAd->NicConfig2.field.BW40MAvailForA, pAd->NicConfig2.field.BW40MAvailForG, pAd->CommonCfg.PhyMode));
-
-	pAd->MlmeAux.HtCapability.HtCapInfo.GF =  pHtCapability->HtCapInfo.GF &pAd->CommonCfg.DesiredHtPhy.GF;
-
-	// Send Assoc Req with my HT capability.
-	pAd->MlmeAux.HtCapability.HtCapInfo.AMsduSize =  pAd->CommonCfg.DesiredHtPhy.AmsduSize;
-	pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs =  pAd->CommonCfg.DesiredHtPhy.MimoPs;
-	pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20 =  (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20) & (pHtCapability->HtCapInfo.ShortGIfor20);
-	pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40 =  (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40) & (pHtCapability->HtCapInfo.ShortGIfor40);
-	pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC =  (pAd->CommonCfg.DesiredHtPhy.TxSTBC)&(pHtCapability->HtCapInfo.RxSTBC);
-	pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC =  (pAd->CommonCfg.DesiredHtPhy.RxSTBC)&(pHtCapability->HtCapInfo.TxSTBC);
-	pAd->MlmeAux.HtCapability.HtCapParm.MaxRAmpduFactor = pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor;
-    pAd->MlmeAux.HtCapability.HtCapParm.MpduDensity = pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity;
-	pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC;
-	pAd->MacTab.Content[Wcid].HTCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC;
-	if (pAd->CommonCfg.bRdg)
-	{
-		pAd->MlmeAux.HtCapability.ExtHtCapInfo.RDGSupport = pHtCapability->ExtHtCapInfo.RDGSupport;
-        pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = 1;
-	}
-
-    if (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_20)
-        pAd->MlmeAux.HtCapability.MCSSet[4] = 0x0;  // BW20 can't transmit MCS32
-
-	COPY_AP_HTSETTINGS_FROM_BEACON(pAd, pHtCapability);
-	return TRUE;
-}
-#endif // DOT11_N_SUPPORT //
-#endif // CONFIG_STA_SUPPORT //
-
-/*
-	========================================================================
-
-	Routine Description:
-		Verify the support rate for different PHY type
-
-	Arguments:
-		pAd				Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	========================================================================
-*/
-VOID RTMPUpdateMlmeRate(
-	IN PRTMP_ADAPTER	pAd)
-{
-	UCHAR	MinimumRate;
-	UCHAR	ProperMlmeRate; //= RATE_54;
-	UCHAR	i, j, RateIdx = 12; //1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
-	BOOLEAN	bMatch = FALSE;
-
-	switch (pAd->CommonCfg.PhyMode)
-	{
-		case PHY_11B:
-			ProperMlmeRate = RATE_11;
-			MinimumRate = RATE_1;
-			break;
-		case PHY_11BG_MIXED:
-#ifdef DOT11_N_SUPPORT
-		case PHY_11ABGN_MIXED:
-		case PHY_11BGN_MIXED:
-#endif // DOT11_N_SUPPORT //
-			if ((pAd->MlmeAux.SupRateLen == 4) &&
-				(pAd->MlmeAux.ExtRateLen == 0))
-				// B only AP
-				ProperMlmeRate = RATE_11;
-			else
-				ProperMlmeRate = RATE_24;
-
-			if (pAd->MlmeAux.Channel <= 14)
-			MinimumRate = RATE_1;
-			else
-				MinimumRate = RATE_6;
-			break;
-		case PHY_11A:
-#ifdef DOT11_N_SUPPORT
-		case PHY_11N_2_4G:	// rt2860 need to check mlmerate for 802.11n
-		case PHY_11GN_MIXED:
-		case PHY_11AGN_MIXED:
-		case PHY_11AN_MIXED:
-		case PHY_11N_5G:
-#endif // DOT11_N_SUPPORT //
-			ProperMlmeRate = RATE_24;
-			MinimumRate = RATE_6;
-			break;
-		case PHY_11ABG_MIXED:
-			ProperMlmeRate = RATE_24;
-			if (pAd->MlmeAux.Channel <= 14)
-			   MinimumRate = RATE_1;
-			else
-				MinimumRate = RATE_6;
-			break;
-		default: // error
-			ProperMlmeRate = RATE_1;
-			MinimumRate = RATE_1;
-			break;
-	}
-
-	for (i = 0; i < pAd->MlmeAux.SupRateLen; i++)
-	{
-		for (j = 0; j < RateIdx; j++)
-		{
-			if ((pAd->MlmeAux.SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
-			{
-				if (j == ProperMlmeRate)
-				{
-					bMatch = TRUE;
-					break;
-				}
-			}
-		}
-
-		if (bMatch)
-			break;
-	}
-
-	if (bMatch == FALSE)
-	{
-	for (i = 0; i < pAd->MlmeAux.ExtRateLen; i++)
-	{
-		for (j = 0; j < RateIdx; j++)
-		{
-			if ((pAd->MlmeAux.ExtRate[i] & 0x7f) == RateIdTo500Kbps[j])
-			{
-					if (j == ProperMlmeRate)
-					{
-						bMatch = TRUE;
-						break;
-					}
-			}
-		}
-
-			if (bMatch)
-			break;
-	}
-	}
-
-	if (bMatch == FALSE)
-	{
-		ProperMlmeRate = MinimumRate;
-	}
-
-	pAd->CommonCfg.MlmeRate = MinimumRate;
-	pAd->CommonCfg.RtsRate = ProperMlmeRate;
-	if (pAd->CommonCfg.MlmeRate >= RATE_6)
-	{
-		pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
-		pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
-		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-	}
-	else
-	{
-		pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
-		pAd->CommonCfg.MlmeTransmit.field.MCS = pAd->CommonCfg.MlmeRate;
-		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_CCK;
-		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = pAd->CommonCfg.MlmeRate;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateMlmeRate ==>   MlmeTransmit = 0x%x  \n" , pAd->CommonCfg.MlmeTransmit.word));
-}
-
-CHAR RTMPMaxRssi(
-	IN PRTMP_ADAPTER	pAd,
-	IN CHAR				Rssi0,
-	IN CHAR				Rssi1,
-	IN CHAR				Rssi2)
-{
-	CHAR	larger = -127;
-
-	if ((pAd->Antenna.field.RxPath == 1) && (Rssi0 != 0))
-	{
-		larger = Rssi0;
-	}
-
-	if ((pAd->Antenna.field.RxPath >= 2) && (Rssi1 != 0))
-	{
-		larger = max(Rssi0, Rssi1);
-	}
-
-	if ((pAd->Antenna.field.RxPath == 3) && (Rssi2 != 0))
-	{
-		larger = max(larger, Rssi2);
-	}
-
-	if (larger == -127)
-		larger = 0;
-
-	return larger;
-}
-
-
-/*
-    ========================================================================
-    Routine Description:
-        Periodic evaluate antenna link status
-
-    Arguments:
-        pAd         - Adapter pointer
-
-    Return Value:
-        None
-
-    ========================================================================
-*/
-VOID AsicEvaluateRxAnt(
-	IN PRTMP_ADAPTER	pAd)
-{
-#ifdef CONFIG_STA_SUPPORT
-	UCHAR	BBPR3 = 0;
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef RALINK_ATE
-	if (ATE_ON(pAd))
-		return;
-#endif // RALINK_ATE //
-
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS	|
-							fRTMP_ADAPTER_HALT_IN_PROGRESS	|
-							fRTMP_ADAPTER_RADIO_OFF			|
-							fRTMP_ADAPTER_NIC_NOT_EXIST		|
-							fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) ||
-							OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
-#ifdef RT3090
-							|| (pAd->bPCIclkOff == TRUE)
-#endif // RT3090 //
-#ifdef ANT_DIVERSITY_SUPPORT
-							|| (pAd->EepromAccess)
-#endif // ANT_DIVERSITY_SUPPORT //
-							)
-		return;
-
-#ifdef ANT_DIVERSITY_SUPPORT
-	if ((pAd->NicConfig2.field.AntDiversity) && (pAd->CommonCfg.bRxAntDiversity == ANT_DIVERSITY_ENABLE))
-	{
-		// two antenna selection mechanism- one is antenna diversity, the other is failed antenna remove
-		// one is antenna diversity:there is only one antenna can rx and tx
-		// the other is failed antenna remove:two physical antenna can rx and tx
-			DBGPRINT(RT_DEBUG_TRACE,("AntDiv - before evaluate Pair1-Ant (%d,%d)\n",
-				pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt));
-
-			AsicSetRxAnt(pAd, pAd->RxAnt.Pair1SecondaryRxAnt);
-
-			pAd->RxAnt.EvaluatePeriod = 1; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt
-			pAd->RxAnt.FirstPktArrivedWhenEvaluate = FALSE;
-			pAd->RxAnt.RcvPktNumWhenEvaluate = 0;
-
-			// a one-shot timer to end the evalution
-			// dynamic adjust antenna evaluation period according to the traffic
-			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-				RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 100);
-			else
-				RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
-		}
-		else
-#endif // ANT_DIVERSITY_SUPPORT //
-	{
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-
-			if (pAd->StaCfg.Psm == PWR_SAVE)
-				return;
-
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
-			BBPR3 &= (~0x18);
-			if(pAd->Antenna.field.RxPath == 3)
-			{
-				BBPR3 |= (0x10);
-			}
-			else if(pAd->Antenna.field.RxPath == 2)
-			{
-				BBPR3 |= (0x8);
-			}
-			else if(pAd->Antenna.field.RxPath == 1)
-			{
-				BBPR3 |= (0x0);
-			}
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
-#ifdef RTMP_MAC_PCI
-			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-			pAd->StaCfg.BBPR3 = BBPR3;
-#endif // RTMP_MAC_PCI //
-			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
-			)
-			{
-				ULONG	TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
-									pAd->RalinkCounters.OneSecTxRetryOkCount +
-									pAd->RalinkCounters.OneSecTxFailCount;
-
-				// dynamic adjust antenna evaluation period according to the traffic
-				if (TxTotalCnt > 50)
-				{
-					RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 20);
-					pAd->Mlme.bLowThroughput = FALSE;
-				}
-				else
-				{
-					RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
-					pAd->Mlme.bLowThroughput = TRUE;
-				}
-			}
-		}
-#endif // CONFIG_STA_SUPPORT //
-	}
-}
-
-/*
-    ========================================================================
-    Routine Description:
-        After evaluation, check antenna link status
-
-    Arguments:
-        pAd         - Adapter pointer
-
-    Return Value:
-        None
-
-    ========================================================================
-*/
-VOID AsicRxAntEvalTimeout(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3)
-{
-	RTMP_ADAPTER	*pAd = (RTMP_ADAPTER *)FunctionContext;
-	BOOLEAN			bSwapAnt = FALSE;
-#ifdef CONFIG_STA_SUPPORT
-	UCHAR			BBPR3 = 0;
-	CHAR			larger = -127, rssi0, rssi1, rssi2;
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef RALINK_ATE
-	if (ATE_ON(pAd))
-		return;
-#endif // RALINK_ATE //
-
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS	|
-							fRTMP_ADAPTER_HALT_IN_PROGRESS	|
-							fRTMP_ADAPTER_RADIO_OFF			|
-							fRTMP_ADAPTER_NIC_NOT_EXIST) ||
-							OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
-#ifdef RT3090
-							|| (pAd->bPCIclkOff == TRUE)
-#endif // RT3090 //
-#ifdef ANT_DIVERSITY_SUPPORT
-							|| (pAd->EepromAccess)
-#endif // ANT_DIVERSITY_SUPPORT //
-							)
-		return;
-
-#ifdef ANT_DIVERSITY_SUPPORT
-	if ((pAd->NicConfig2.field.AntDiversity) && (pAd->CommonCfg.bRxAntDiversity == ANT_DIVERSITY_ENABLE))
-	{
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-			if ((pAd->RxAnt.RcvPktNumWhenEvaluate != 0) && (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >= pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt]))
-				bSwapAnt = TRUE;
-#endif // CONFIG_STA_SUPPORT //
-		if (bSwapAnt == TRUE)
-			{
-				UCHAR			temp;
-
-				//
-				// select PrimaryRxAntPair
-				//    Role change, Used Pair1SecondaryRxAnt as PrimaryRxAntPair.
-				//    Since Pair1SecondaryRxAnt Quality good than Pair1PrimaryRxAnt
-				//
-				temp = pAd->RxAnt.Pair1PrimaryRxAnt;
-				pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt;
-				pAd->RxAnt.Pair1SecondaryRxAnt = temp;
-
-#ifdef CONFIG_STA_SUPPORT
-				pAd->RxAnt.Pair1LastAvgRssi = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >> 3);
-#endif // CONFIG_STA_SUPPORT //
-//				pAd->RxAnt.EvaluateStableCnt = 0;
-			}
-			else
-			{
-				// if the evaluated antenna is not better than original, switch back to original antenna
-				AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
-				pAd->RxAnt.EvaluateStableCnt ++;
-			}
-
-			pAd->RxAnt.EvaluatePeriod = 0; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt
-
-#ifdef CONFIG_STA_SUPPORT
-			DBGPRINT(RT_DEBUG_TRACE,("AsicRxAntEvalAction::After Eval(fix in #%d), <%d, %d>, RcvPktNumWhenEvaluate=%ld\n",
-					pAd->RxAnt.Pair1PrimaryRxAnt, (pAd->RxAnt.Pair1AvgRssi[0] >> 3), (pAd->RxAnt.Pair1AvgRssi[1] >> 3), pAd->RxAnt.RcvPktNumWhenEvaluate));
-#endif // CONFIG_STA_SUPPORT //
-		}
-		else
-#endif // ANT_DIVERSITY_SUPPORT //
-	{
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			if (pAd->StaCfg.Psm == PWR_SAVE)
-				return;
-
-
-			// if the traffic is low, use average rssi as the criteria
-			if (pAd->Mlme.bLowThroughput == TRUE)
-			{
-				rssi0 = pAd->StaCfg.RssiSample.LastRssi0;
-				rssi1 = pAd->StaCfg.RssiSample.LastRssi1;
-				rssi2 = pAd->StaCfg.RssiSample.LastRssi2;
-			}
-			else
-			{
-				rssi0 = pAd->StaCfg.RssiSample.AvgRssi0;
-				rssi1 = pAd->StaCfg.RssiSample.AvgRssi1;
-				rssi2 = pAd->StaCfg.RssiSample.AvgRssi2;
-			}
-
-			if(pAd->Antenna.field.RxPath == 3)
-			{
-				larger = max(rssi0, rssi1);
-
-				if (larger > (rssi2 + 20))
-					pAd->Mlme.RealRxPath = 2;
-				else
-					pAd->Mlme.RealRxPath = 3;
-			}
-			else if(pAd->Antenna.field.RxPath == 2)
-			{
-				if (rssi0 > (rssi1 + 20))
-					pAd->Mlme.RealRxPath = 1;
-				else
-					pAd->Mlme.RealRxPath = 2;
-			}
-
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
-			BBPR3 &= (~0x18);
-			if(pAd->Mlme.RealRxPath == 3)
-			{
-				BBPR3 |= (0x10);
-			}
-			else if(pAd->Mlme.RealRxPath == 2)
-			{
-				BBPR3 |= (0x8);
-			}
-			else if(pAd->Mlme.RealRxPath == 1)
-			{
-				BBPR3 |= (0x0);
-			}
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
-#ifdef RTMP_MAC_PCI
-			pAd->StaCfg.BBPR3 = BBPR3;
-#endif // RTMP_MAC_PCI //
-		}
-#endif // CONFIG_STA_SUPPORT //
-	}
-}
-
-
-VOID APSDPeriodicExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3)
-{
-	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
-
-	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-		return;
-
-	pAd->CommonCfg.TriggerTimerCount++;
-
-// Driver should not send trigger frame, it should be send by application layer
-/*
-	if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable
-		&& (pAd->CommonCfg.bNeedSendTriggerFrame ||
-		(((pAd->CommonCfg.TriggerTimerCount%20) == 19) && (!pAd->CommonCfg.bAPSDAC_BE || !pAd->CommonCfg.bAPSDAC_BK || !pAd->CommonCfg.bAPSDAC_VI || !pAd->CommonCfg.bAPSDAC_VO))))
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("Sending trigger frame and enter service period when support APSD\n"));
-		RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
-		pAd->CommonCfg.bNeedSendTriggerFrame = FALSE;
-		pAd->CommonCfg.TriggerTimerCount = 0;
-		pAd->CommonCfg.bInServicePeriod = TRUE;
-	}*/
-}
-
-/*
-    ========================================================================
-    Routine Description:
-        Set/reset MAC registers according to bPiggyBack parameter
-
-    Arguments:
-        pAd         - Adapter pointer
-        bPiggyBack  - Enable / Disable Piggy-Back
-
-    Return Value:
-        None
-
-    ========================================================================
-*/
-VOID RTMPSetPiggyBack(
-    IN PRTMP_ADAPTER    pAd,
-    IN BOOLEAN          bPiggyBack)
-{
-	TX_LINK_CFG_STRUC  TxLinkCfg;
-
-	RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
-
-	TxLinkCfg.field.TxCFAckEn = bPiggyBack;
-	RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
-}
-
-/*
-    ========================================================================
-    Routine Description:
-        check if this entry need to switch rate automatically
-
-    Arguments:
-        pAd
-        pEntry
-
-    Return Value:
-        TURE
-        FALSE
-
-    ========================================================================
-*/
-BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(
-	IN PRTMP_ADAPTER    pAd,
-	IN PMAC_TABLE_ENTRY	pEntry)
-{
-	BOOLEAN		result = TRUE;
-
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		// only associated STA counts
-		if (pEntry && (pEntry->ValidAsCLI) && (pEntry->Sst == SST_ASSOC))
-		{
-		result = pAd->StaCfg.bAutoTxRateSwitch;
-	}
-		else
-			result = FALSE;
-
-#ifdef QOS_DLS_SUPPORT
-		if (pEntry && (pEntry->ValidAsDls))
-			result = pAd->StaCfg.bAutoTxRateSwitch;
-#endif // QOS_DLS_SUPPORT //
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-
-
-	return result;
-}
-
-
-BOOLEAN RTMPAutoRateSwitchCheck(
-	IN PRTMP_ADAPTER    pAd)
-{
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		if (pAd->StaCfg.bAutoTxRateSwitch)
-			return TRUE;
-	}
-#endif // CONFIG_STA_SUPPORT //
-	return FALSE;
-}
-
-
-/*
-    ========================================================================
-    Routine Description:
-        check if this entry need to fix tx legacy rate
-
-    Arguments:
-        pAd
-        pEntry
-
-    Return Value:
-        TURE
-        FALSE
-
-    ========================================================================
-*/
-UCHAR RTMPStaFixedTxMode(
-	IN PRTMP_ADAPTER    pAd,
-	IN PMAC_TABLE_ENTRY	pEntry)
-{
-	UCHAR	tx_mode = FIXED_TXMODE_HT;
-
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		tx_mode = (UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode;
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	return tx_mode;
-}
-
-/*
-    ========================================================================
-    Routine Description:
-        Overwrite HT Tx Mode by Fixed Legency Tx Mode, if specified.
-
-    Arguments:
-        pAd
-        pEntry
-
-    Return Value:
-        TURE
-        FALSE
-
-    ========================================================================
-*/
-VOID RTMPUpdateLegacyTxSetting(
-		UCHAR				fixed_tx_mode,
-		PMAC_TABLE_ENTRY	pEntry)
-{
-	HTTRANSMIT_SETTING TransmitSetting;
-
-	if (fixed_tx_mode == FIXED_TXMODE_HT)
-		return;
-
-	TransmitSetting.word = 0;
-
-	TransmitSetting.field.MODE = pEntry->HTPhyMode.field.MODE;
-	TransmitSetting.field.MCS = pEntry->HTPhyMode.field.MCS;
-
-	if (fixed_tx_mode == FIXED_TXMODE_CCK)
-	{
-		TransmitSetting.field.MODE = MODE_CCK;
-		// CCK mode allow MCS 0~3
-		if (TransmitSetting.field.MCS > MCS_3)
-			TransmitSetting.field.MCS = MCS_3;
-	}
-	else
-	{
-		TransmitSetting.field.MODE = MODE_OFDM;
-		// OFDM mode allow MCS 0~7
-		if (TransmitSetting.field.MCS > MCS_7)
-			TransmitSetting.field.MCS = MCS_7;
-	}
-
-	if (pEntry->HTPhyMode.field.MODE >= TransmitSetting.field.MODE)
-	{
-		pEntry->HTPhyMode.word = TransmitSetting.word;
-		DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateLegacyTxSetting : wcid-%d, MODE=%s, MCS=%d \n",
-				pEntry->Aid, GetPhyMode(pEntry->HTPhyMode.field.MODE), pEntry->HTPhyMode.field.MCS));
-	}
-}
-
-#ifdef CONFIG_STA_SUPPORT
-/*
-	==========================================================================
-	Description:
-		dynamic tune BBP R66 to find a balance between sensibility and
-		noise isolation
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AsicStaBbpTuning(
-	IN PRTMP_ADAPTER pAd)
-{
-	UCHAR	OrigR66Value = 0, R66;//, R66UpperBound = 0x30, R66LowerBound = 0x30;
-	CHAR	Rssi;
-
-	// 2860C did not support Fase CCA, therefore can't tune
-	if (pAd->MACVersion == 0x28600100)
-		return;
-
-	//
-	// work as a STA
-	//
-	if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)  // no R66 tuning when SCANNING
-		return;
-
-	if ((pAd->OpMode == OPMODE_STA)
-		&& (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
-			)
-		&& !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-#ifdef RTMP_MAC_PCI
-		&& (pAd->bPCIclkOff == FALSE)
-#endif // RTMP_MAC_PCI //
-		)
-	{
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &OrigR66Value);
-		R66 = OrigR66Value;
-
-		if (pAd->Antenna.field.RxPath > 1)
-			Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
-		else
-			Rssi = pAd->StaCfg.RssiSample.AvgRssi0;
-
-		if (pAd->LatchRfRegs.Channel <= 14)
-		{	//BG band
-#ifdef RT30xx
-			// RT3070 is a no LNA solution, it should have different control regarding to AGC gain control
-			// Otherwise, it will have some throughput side effect when low RSSI
-
-			if (IS_RT3070(pAd)||IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
-			{
-				if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
-				{
-					R66 = 0x1C + 2*GET_LNA_GAIN(pAd) + 0x20;
-					if (OrigR66Value != R66)
-					{
-							RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-					}
-				}
-				else
-				{
-					R66 = 0x1C + 2*GET_LNA_GAIN(pAd);
-					if (OrigR66Value != R66)
-					{
-							RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-					}
-				}
-			}
-			else
-#endif // RT30xx //
-			{
-				if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
-				{
-					R66 = (0x2E + GET_LNA_GAIN(pAd)) + 0x10;
-					if (OrigR66Value != R66)
-					{
-						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-					}
-				}
-				else
-				{
-					R66 = 0x2E + GET_LNA_GAIN(pAd);
-					if (OrigR66Value != R66)
-					{
-						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-					}
-				}
-			}
-		}
-		else
-		{	//A band
-			if (pAd->CommonCfg.BBPCurrentBW == BW_20)
-			{
-				if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
-				{
-					R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3 + 0x10;
-					if (OrigR66Value != R66)
-					{
-							RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-					}
-				}
-				else
-				{
-					R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3;
-					if (OrigR66Value != R66)
-					{
-							RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-					}
-				}
-			}
-			else
-			{
-				if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
-				{
-					R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3 + 0x10;
-					if (OrigR66Value != R66)
-					{
-							RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-					}
-				}
-				else
-				{
-					R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3;
-					if (OrigR66Value != R66)
-					{
-							RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-					}
-				}
-			}
-		}
-
-
-	}
-}
-#endif // CONFIG_STA_SUPPORT //
-
-VOID RTMPSetAGCInitValue(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			BandWidth)
-{
-	UCHAR	R66 = 0x30;
-
-	if (pAd->LatchRfRegs.Channel <= 14)
-	{	// BG band
-#ifdef RT30xx
-		/* Gary was verified Amazon AP and find that RT307x has BBP_R66 invalid default value */
-
-		if (IS_RT3070(pAd)||IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
-		{
-			R66 = 0x1C + 2*GET_LNA_GAIN(pAd);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-		}
-		else
-#endif // RT30xx //
-		{
-			R66 = 0x2E + GET_LNA_GAIN(pAd);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-		}
-	}
-	else
-	{	//A band
-		{
-			if (BandWidth == BW_20)
-			{
-				R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3);
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-			}
-#ifdef DOT11_N_SUPPORT
-			else
-			{
-				R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3);
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-			}
-#endif // DOT11_N_SUPPORT //
-		}
-	}
-
-}
diff --git a/drivers/staging/rt3090/common/mlme_ex.c b/drivers/staging/rt3090/common/mlme_ex.c
deleted file mode 100644
index d7fb7f5..0000000
--- a/drivers/staging/rt3090/common/mlme_ex.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	mlme_ex.c
-
-	Abstract:
-	Miniport generic portion header file
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-	Fonchi		2007-06-25		Extend original mlme APIs to support multi-entries
-*/
-
-#include "../rt_config.h"
-#include "../mlme_ex_def.h"
-//#include <stdarg.h>
-
-
-// ===========================================================================================
-// state_machine
-// ===========================================================================================
-
-/*! \brief Initialize the state machine.
- *  \param *S           pointer to the state machine
- *  \param  Trans       State machine transition function
- *  \param  StNr        number of states
- *  \param  MsgNr       number of messages
- *  \param  DefFunc     default function, when there is invalid state/message combination
- *  \param  InitState   initial state of the state machine
- *  \param  Base        StateMachine base, internal use only
- *  \pre p_sm should be a legal pointer
- *  \post
- */
-VOID StateMachineInitEx(
-	IN STATE_MACHINE_EX *S,
-	IN STATE_MACHINE_FUNC_EX Trans[],
-	IN ULONG StNr,
-	IN ULONG MsgNr,
-	IN STATE_MACHINE_FUNC_EX DefFunc,
-	IN ULONG InitState,
-	IN ULONG Base)
-{
-	ULONG i, j;
-
-	// set number of states and messages
-	S->NrState = StNr;
-	S->NrMsg   = MsgNr;
-	S->Base    = Base;
-
-	S->TransFunc  = Trans;
-
-	// init all state transition to default function
-	for (i = 0; i < StNr; i++)
-	{
-		for (j = 0; j < MsgNr; j++)
-		{
-			S->TransFunc[i * MsgNr + j] = DefFunc;
-		}
-	}
-
-	// set the starting state
-	S->CurrState = InitState;
-
-	return;
-}
-
-/*! \brief This function fills in the function pointer into the cell in the state machine
- *  \param *S   pointer to the state machine
- *  \param St   state
- *  \param Msg  incoming message
- *  \param f    the function to be executed when (state, message) combination occurs at the state machine
- *  \pre *S should be a legal pointer to the state machine, st, msg, should be all within the range, Base should be set in the initial state
- *  \post
- */
-VOID StateMachineSetActionEx(
-	IN STATE_MACHINE_EX *S,
-	IN ULONG St,
-	IN ULONG Msg,
-	IN STATE_MACHINE_FUNC_EX Func)
-{
-	ULONG MsgIdx;
-
-	MsgIdx = Msg - S->Base;
-
-	if (St < S->NrState && MsgIdx < S->NrMsg)
-	{
-		// boundary checking before setting the action
-		S->TransFunc[St * S->NrMsg + MsgIdx] = Func;
-	}
-
-	return;
-}
-
-/*! \brief   This function does the state transition
- *  \param   *Adapter the NIC adapter pointer
- *  \param   *S       the state machine
- *  \param   *Elem    the message to be executed
- *  \return   None
- */
-VOID StateMachinePerformActionEx(
-	IN PRTMP_ADAPTER	pAd,
-	IN STATE_MACHINE_EX *S,
-	IN MLME_QUEUE_ELEM *Elem,
-	USHORT Idx,
-	PULONG pCurrState)
-{
-	if (S->TransFunc[(*pCurrState) * S->NrMsg + Elem->MsgType - S->Base])
-		(*(S->TransFunc[(*pCurrState) * S->NrMsg + Elem->MsgType - S->Base]))(pAd, Elem, pCurrState, Idx);
-
-	return;
-}
-
-/*! \brief   Enqueue a message for other threads, if they want to send messages to MLME thread
- *  \param  *Queue    The MLME Queue
- *  \param   Machine  The State Machine Id
- *  \param   MsgType  The Message Type
- *  \param   MsgLen   The Message length
- *  \param  *Msg      The message pointer
- *  \return  TRUE if enqueue is successful, FALSE if the queue is full
- *  \pre
- *  \post
- *  \note    The message has to be initialized
- */
-BOOLEAN MlmeEnqueueEx(
-	IN	PRTMP_ADAPTER	pAd,
-	IN ULONG Machine,
-	IN ULONG MsgType,
-	IN ULONG MsgLen,
-	IN VOID *Msg,
-	IN USHORT Idx)
-{
-	INT Tail;
-	MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
-		return FALSE;
-
-
-	// First check the size, it MUST not exceed the mlme queue size
-	if (MsgLen > MAX_LEN_OF_MLME_BUFFER)
-	{
-		DBGPRINT_ERR(("MlmeEnqueueEx: msg too large, size = %ld \n", MsgLen));
-		return FALSE;
-	}
-
-	if (MlmeQueueFull(Queue))
-	{
-
-		return FALSE;
-	}
-
-	RTMP_SEM_LOCK(&Queue->Lock);
-	Tail = Queue->Tail;
-	Queue->Tail++;
-	Queue->Num++;
-	if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
-	{
-		Queue->Tail = 0;
-	}
-	Queue->Entry[Tail].Occupied = TRUE;
-	Queue->Entry[Tail].Machine = Machine;
-	Queue->Entry[Tail].MsgType = MsgType;
-	Queue->Entry[Tail].MsgLen = MsgLen;
-	Queue->Entry[Tail].Idx = Idx;
-	if (Msg != NULL)
-		NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
-
-	RTMP_SEM_UNLOCK(&Queue->Lock);
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        The drop function, when machine executes this, the message is simply
-        ignored. This function does nothing, the message is freed in
-        StateMachinePerformAction()
-    ==========================================================================
- */
-VOID DropEx(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem,
-	PULONG pCurrState,
-	USHORT Idx)
-{
-	return;
-}
diff --git a/drivers/staging/rt3090/common/netif_block.c b/drivers/staging/rt3090/common/netif_block.c
deleted file mode 100644
index 2172957..0000000
--- a/drivers/staging/rt3090/common/netif_block.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
- */
-#ifdef BLOCK_NET_IF
-
-#include "../rt_config.h"
-#include "../netif_block.h"
-
-
-static NETIF_ENTRY freeNetIfEntryPool[FREE_NETIF_POOL_SIZE];
-static LIST_HEADER freeNetIfEntryList;
-
-void initblockQueueTab(
-	IN PRTMP_ADAPTER pAd)
-{
-	int i;
-
-	initList(&freeNetIfEntryList);
-	for (i = 0; i < FREE_NETIF_POOL_SIZE; i++)
-		insertTailList(&freeNetIfEntryList, (PLIST_ENTRY)&freeNetIfEntryPool[i]);
-
-	for (i=0; i < NUM_OF_TX_RING; i++)
-		initList(&pAd->blockQueueTab[i].NetIfList);
-
-	return;
-}
-
-BOOLEAN blockNetIf(
-	IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry,
-	IN PNET_DEV pNetDev)
-{
-	PNETIF_ENTRY pNetIfEntry = NULL;
-
-	if ((pNetIfEntry = (PNETIF_ENTRY)removeHeadList(&freeNetIfEntryList)) != NULL)
-	{
-		RTMP_OS_NETDEV_STOP_QUEUE(pNetDev);
-		pNetIfEntry->pNetDev = pNetDev;
-		insertTailList(&pBlockQueueEntry->NetIfList, (PLIST_ENTRY)pNetIfEntry);
-
-		pBlockQueueEntry->SwTxQueueBlockFlag = TRUE;
-		DBGPRINT(RT_DEBUG_TRACE, ("RTMP_OS_NETDEV_STOP_QUEUE(%s)\n", RTMP_OS_NETDEV_GET_DEVNAME(pNetDev)));
-	}
-	else
-		return FALSE;
-
-	return TRUE;
-}
-
-VOID releaseNetIf(
-	IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry)
-{
-	PNETIF_ENTRY pNetIfEntry = NULL;
-	PLIST_HEADER pNetIfList = &pBlockQueueEntry->NetIfList;
-
-	while((pNetIfEntry = (PNETIF_ENTRY)removeHeadList(pNetIfList)) !=  NULL)
-	{
-		PNET_DEV pNetDev = pNetIfEntry->pNetDev;
-		RTMP_OS_NETDEV_WAKE_QUEUE(pNetDev);
-		insertTailList(&freeNetIfEntryList, (PLIST_ENTRY)pNetIfEntry);
-
-		DBGPRINT(RT_DEBUG_TRACE, ("RTMP_OS_NETDEV_WAKE_QUEUE(%s)\n", RTMP_OS_NETDEV_GET_DEVNAME(pNetDev)));
-	}
-	pBlockQueueEntry->SwTxQueueBlockFlag = FALSE;
-	return;
-}
-
-
-VOID StopNetIfQueue(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR QueIdx,
-	IN PNDIS_PACKET pPacket)
-{
-	PNET_DEV NetDev = NULL;
-	UCHAR IfIdx = 0;
-	BOOLEAN valid = FALSE;
-
-#ifdef APCLI_SUPPORT
-	if (RTMP_GET_PACKET_NET_DEVICE(pPacket) >= MIN_NET_DEVICE_FOR_APCLI)
-	{
-		IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_APCLI) % MAX_APCLI_NUM;
-		NetDev = pAd->ApCfg.ApCliTab[IfIdx].dev;
-	}
-	else
-#endif // APCLI_SUPPORT //
-#ifdef WDS_SUPPORT
-	if (RTMP_GET_PACKET_NET_DEVICE(pPacket) >= MIN_NET_DEVICE_FOR_WDS)
-	{
-		IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_WDS) % MAX_WDS_ENTRY;
-		NetDev = pAd->WdsTab.WdsEntry[IfIdx].dev;
-	}
-	else
-#endif // WDS_SUPPORT //
-	{
-#ifdef MBSS_SUPPORT
-		if (pAd->OpMode == OPMODE_AP)
-		{
-			IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_MBSSID) % MAX_MBSSID_NUM;
-			NetDev = pAd->ApCfg.MBSSID[IfIdx].MSSIDDev;
-		}
-		else
-		{
-			IfIdx = MAIN_MBSSID;
-			NetDev = pAd->net_dev;
-		}
-#else
-		IfIdx = MAIN_MBSSID;
-		NetDev = pAd->net_dev;
-#endif
-	}
-
-	// WMM support 4 software queues.
-	// One software queue full doesn't mean device have no capbility to transmit packet.
-	// So disable block Net-If queue function while WMM enable.
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		valid = (pAd->CommonCfg.bWmmCapable == TRUE) ? FALSE : TRUE;
-#endif // CONFIG_STA_SUPPORT //
-
-	if (valid)
-		blockNetIf(&pAd->blockQueueTab[QueIdx], NetDev);
-	return;
-}
-
-#endif // BLOCK_NET_IF //
diff --git a/drivers/staging/rt3090/common/rt_channel.c b/drivers/staging/rt3090/common/rt_channel.c
deleted file mode 100644
index da2391e..0000000
--- a/drivers/staging/rt3090/common/rt_channel.c
+++ /dev/null
@@ -1,1287 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-*/
-
-#include "../rt_config.h"
-
-
-CH_FREQ_MAP CH_HZ_ID_MAP[]=
-		{
-			{1, 2412},
-			{2, 2417},
-			{3, 2422},
-			{4, 2427},
-			{5, 2432},
-			{6, 2437},
-			{7, 2442},
-			{8, 2447},
-			{9, 2452},
-			{10, 2457},
-			{11, 2462},
-			{12, 2467},
-			{13, 2472},
-			{14, 2484},
-
-			/*  UNII */
-			{36, 5180},
-			{40, 5200},
-			{44, 5220},
-			{48, 5240},
-			{52, 5260},
-			{56, 5280},
-			{60, 5300},
-			{64, 5320},
-			{149, 5745},
-			{153, 5765},
-			{157, 5785},
-			{161, 5805},
-			{165, 5825},
-			{167, 5835},
-			{169, 5845},
-			{171, 5855},
-			{173, 5865},
-
-			/* HiperLAN2 */
-			{100, 5500},
-			{104, 5520},
-			{108, 5540},
-			{112, 5560},
-			{116, 5580},
-			{120, 5600},
-			{124, 5620},
-			{128, 5640},
-			{132, 5660},
-			{136, 5680},
-			{140, 5700},
-
-			/* Japan MMAC */
-			{34, 5170},
-			{38, 5190},
-			{42, 5210},
-			{46, 5230},
-
-			/*  Japan */
-			{184, 4920},
-			{188, 4940},
-			{192, 4960},
-			{196, 4980},
-
-			{208, 5040},	/* Japan, means J08 */
-			{212, 5060},	/* Japan, means J12 */
-			{216, 5080},	/* Japan, means J16 */
-};
-
-INT	CH_HZ_ID_MAP_NUM = (sizeof(CH_HZ_ID_MAP)/sizeof(CH_FREQ_MAP));
-
-CH_REGION ChRegion[] =
-{
-		{	// Antigua and Berbuda
-			"AG",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  23, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Argentina
-			"AR",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149, 4,  30, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Aruba
-			"AW",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  23, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Australia
-			"AU",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149, 5,  30, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Austria
-			"AT",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, IDOR, TRUE},		// 5G, ch 36~48
-				{ 52,  4,  23, IDOR, TRUE},		// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, TRUE},		// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Bahamas
-			"BS",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149, 5,  30, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Barbados
-			"BB",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Bermuda
-			"BM",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Brazil
-			"BR",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11, 24, BOTH, FALSE},	// 5G, ch 100~140
-				{ 149, 5,  30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Belgium
-			"BE",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  18, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  18, IDOR, FALSE},	// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// Bulgaria
-			"BG",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11, 30, ODOR, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Canada
-			"CA",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  23, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149, 5,  30, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Cayman IsLands
-			"KY",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Chile
-			"CL",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  20, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  20, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149, 5,  20, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// China
-			"CN",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 149, 4,  27, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Colombia
-			"CO",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  17, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 149, 5,  30, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Costa Rica
-			"CR",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  17, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149, 4,  30, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Cyprus
-			"CY",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, IDOR, TRUE},		// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, TRUE},		// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Czech_Republic
-			"CZ",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  23, IDOR, TRUE},		// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// Denmark
-			"DK",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  23, IDOR, TRUE},		// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, TRUE},		// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Dominican Republic
-			"DO",
-			CE,
-			{
-				{ 1,   0,  20, BOTH, FALSE},	// 2.4 G, ch 0
-				{ 149, 4,  20, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Equador
-			"EC",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 100, 11,  27, BOTH, FALSE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// El Salvador
-			"SV",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,   23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   30, BOTH, TRUE},	// 5G, ch 52~64
-				{ 149, 4,   36, BOTH, TRUE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Finland
-			"FI",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,   23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// France
-			"FR",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,   23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// Germany
-			"DE",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,   23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Greece
-			"GR",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,   23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, ODOR, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Guam
-			"GU",
-			CE,
-			{
-				{ 1,   11,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 36,  4,   17, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 149,  5,  30, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Guatemala
-			"GT",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,   17, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149,  4,  30, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Haiti
-			"HT",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,   17, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149,  4,  30, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Honduras
-			"HN",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 149,  4,  27, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Hong Kong
-			"HK",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, FALSE},	// 5G, ch 52~64
-				{ 149,  4,  30, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Hungary
-			"HU",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// Iceland
-			"IS",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// India
-			"IN",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 149,	4,  24, IDOR, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Indonesia
-			"ID",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 149,	4,  27, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Ireland
-			"IE",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,	4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, ODOR, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Israel
-			"IL",
-			CE,
-			{
-				{ 1,    3,  20, IDOR, FALSE},	// 2.4 G, ch 1~3
-				{ 4,	6,  20, BOTH, FALSE},	// 2.4 G, ch 4~9
-				{ 10,	4,  20, IDOR, FALSE},	// 2.4 G, ch 10~13
-				{ 0},							// end
-			}
-		},
-
-		{	// Italy
-			"IT",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,	4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, ODOR, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Japan
-			"JP",
-			JAP,
-			{
-				{ 1,   14,  20, BOTH, FALSE},	// 2.4 G, ch 1~14
-				{ 36,	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 0},							// end
-			}
-		},
-
-		{	// Jordan
-			"JO",
-			CE,
-			{
-				{ 1,   13,  20, IDOR, FALSE},	// 2.4 G, ch 1~13
-				{ 36,	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 149,	4,  23, IDOR, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Latvia
-			"LV",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,	4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Liechtenstein
-			"LI",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 52,	4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Lithuania
-			"LT",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,	4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Luxemburg
-			"LU",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,	4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Malaysia
-			"MY",
-			CE,
-			{
-				{ 36,	4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,	4,  23, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149,  5,  20, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Malta
-			"MT",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,	4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Marocco
-			"MA",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,	4,  24, IDOR, FALSE},	// 5G, ch 36~48
-				{ 0},							// end
-			}
-		},
-
-		{	// Mexico
-			"MX",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,	4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,	4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149,  5,  30, IDOR, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Netherlands
-			"NL",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,	4,  24, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// New Zealand
-			"NZ",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,	4,  24, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,	4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149,  4,  30, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Norway
-			"NO",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,	4,  24, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,	4,  24, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Peru
-			"PE",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 149,  4,  27, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Portugal
-			"PT",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Poland
-			"PL",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Romania
-			"RO",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Russia
-			"RU",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 149,  4,  20, IDOR, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Saudi Arabia
-			"SA",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149,  4,  23, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Serbia_and_Montenegro
-			"CS",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 0},							// end
-			}
-		},
-
-		{	// Singapore
-			"SG",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149,  4,  20, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Slovakia
-			"SK",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Slovenia
-			"SI",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// South Africa
-			"ZA",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, FALSE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 149,  4,  30, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// South Korea
-			"KR",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  20, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  20, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100,  8,  20, BOTH, FALSE},	// 5G, ch 100~128
-				{ 149,  4,  20, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Spain
-			"ES",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  17, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Sweden
-			"SE",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Switzerland
-			"CH",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, TRUE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// Taiwan
-			"TW",
-			CE,
-			{
-				{ 1,   11,  30, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 52,   4,  23, IDOR, FALSE},	// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// Turkey
-			"TR",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 36,   4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, BOTH, FALSE},	// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// UK
-			"GB",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 52~64
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Ukraine
-			"UA",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 0},							// end
-			}
-		},
-
-		{	// United_Arab_Emirates
-			"AE",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 0},							// end
-			}
-		},
-
-		{	// United_States
-			"US",
-			CE,
-			{
-				{ 1,   11,  30, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 36,   4,  17, IDOR, FALSE},	// 5G, ch 52~64
-				{ 52,   4,  24, BOTH, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 149,  5,  30, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Venezuela
-			"VE",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 149,  4,  27, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Default
-			"",
-			CE,
-			{
-				{ 1,   11,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 36,   4,  20, BOTH, FALSE},	// 5G, ch 52~64
-				{ 52,   4,  20, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11,  20, BOTH, FALSE},	// 5G, ch 100~140
-				{ 149,  5,  20, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-};
-
-
-static PCH_REGION GetChRegion(
-	IN PUCHAR CntryCode)
-{
-	INT loop = 0;
-	PCH_REGION pChRegion = NULL;
-
-	while (strcmp((PSTRING) ChRegion[loop].CountReg, "") != 0)
-	{
-		if (strncmp((PSTRING) ChRegion[loop].CountReg, (PSTRING) CntryCode, 2) == 0)
-		{
-			pChRegion = &ChRegion[loop];
-			break;
-		}
-		loop++;
-	}
-
-	if (pChRegion == NULL)
-		pChRegion = &ChRegion[loop];
-	return pChRegion;
-}
-
-static VOID ChBandCheck(
-	IN UCHAR PhyMode,
-	OUT PUCHAR pChType)
-{
-	switch(PhyMode)
-	{
-		case PHY_11A:
-#ifdef DOT11_N_SUPPORT
-		case PHY_11AN_MIXED:
-#endif // DOT11_N_SUPPORT //
-			*pChType = BAND_5G;
-			break;
-		case PHY_11ABG_MIXED:
-#ifdef DOT11_N_SUPPORT
-		case PHY_11AGN_MIXED:
-		case PHY_11ABGN_MIXED:
-#endif // DOT11_N_SUPPORT //
-			*pChType = BAND_BOTH;
-			break;
-
-		default:
-			*pChType = BAND_24G;
-			break;
-	}
-}
-
-static UCHAR FillChList(
-	IN PRTMP_ADAPTER pAd,
-	IN PCH_DESP pChDesp,
-	IN UCHAR Offset,
-	IN UCHAR increment)
-{
-	INT i, j, l;
-	UCHAR channel;
-
-	j = Offset;
-	for (i = 0; i < pChDesp->NumOfCh; i++)
-	{
-		channel = pChDesp->FirstChannel + i * increment;
-		for (l=0; l<MAX_NUM_OF_CHANNELS; l++)
-		{
-			if (channel == pAd->TxPower[l].Channel)
-			{
-				pAd->ChannelList[j].Power = pAd->TxPower[l].Power;
-				pAd->ChannelList[j].Power2 = pAd->TxPower[l].Power2;
-				break;
-			}
-		}
-		if (l == MAX_NUM_OF_CHANNELS)
-			continue;
-
-		pAd->ChannelList[j].Channel = pChDesp->FirstChannel + i * increment;
-		pAd->ChannelList[j].MaxTxPwr = pChDesp->MaxTxPwr;
-		pAd->ChannelList[j].DfsReq = pChDesp->DfsReq;
-		j++;
-	}
-	pAd->ChannelListNum = j;
-
-	return j;
-}
-
-
-static inline VOID CreateChList(
-	IN PRTMP_ADAPTER pAd,
-	IN PCH_REGION pChRegion,
-	IN UCHAR Geography)
-{
-	INT i;
-	UCHAR offset = 0;
-	PCH_DESP pChDesp;
-	UCHAR ChType;
-	UCHAR increment;
-
-	if (pChRegion == NULL)
-		return;
-
-	ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
-
-	for (i=0; i<10; i++)
-	{
-		pChDesp = &pChRegion->ChDesp[i];
-		if (pChDesp->FirstChannel == 0)
-			break;
-
-		if (ChType == BAND_5G)
-		{
-			if (pChDesp->FirstChannel <= 14)
-				continue;
-		}
-		else if (ChType == BAND_24G)
-		{
-			if (pChDesp->FirstChannel > 14)
-				continue;
-		}
-
-		if ((pChDesp->Geography == BOTH)
-			|| (pChDesp->Geography == Geography))
-        {
-			if (pChDesp->FirstChannel > 14)
-                increment = 4;
-            else
-                increment = 1;
-			offset = FillChList(pAd, pChDesp, offset, increment);
-        }
-	}
-}
-
-
-VOID BuildChannelListEx(
-	IN PRTMP_ADAPTER pAd)
-{
-	PCH_REGION pChReg;
-
-	pChReg = GetChRegion(pAd->CommonCfg.CountryCode);
-	CreateChList(pAd, pChReg, pAd->CommonCfg.Geography);
-}
-
-
-VOID BuildBeaconChList(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pBuf,
-	OUT	PULONG pBufLen)
-{
-	INT i;
-	ULONG TmpLen;
-	PCH_REGION pChRegion;
-	PCH_DESP pChDesp;
-	UCHAR ChType;
-
-	pChRegion = GetChRegion(pAd->CommonCfg.CountryCode);
-
-	if (pChRegion == NULL)
-		return;
-
-	ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
-	*pBufLen = 0;
-
-	for (i=0; i<10; i++)
-	{
-		pChDesp = &pChRegion->ChDesp[i];
-		if (pChDesp->FirstChannel == 0)
-			break;
-
-		if (ChType == BAND_5G)
-		{
-			if (pChDesp->FirstChannel <= 14)
-				continue;
-		}
-		else if (ChType == BAND_24G)
-		{
-			if (pChDesp->FirstChannel > 14)
-				continue;
-		}
-
-		if ((pChDesp->Geography == BOTH)
-			|| (pChDesp->Geography == pAd->CommonCfg.Geography))
-		{
-			MakeOutgoingFrame(pBuf + *pBufLen,		&TmpLen,
-								1,			&pChDesp->FirstChannel,
-								1,			&pChDesp->NumOfCh,
-								1,			&pChDesp->MaxTxPwr,
-								END_OF_ARGS);
-			*pBufLen += TmpLen;
-		}
-	}
-}
-
-
-#ifdef DOT11_N_SUPPORT
-static BOOLEAN IsValidChannel(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR channel)
-
-{
-	INT i;
-
-	for (i = 0; i < pAd->ChannelListNum; i++)
-	{
-		if (pAd->ChannelList[i].Channel == channel)
-			break;
-	}
-
-	if (i == pAd->ChannelListNum)
-		return FALSE;
-	else
-		return TRUE;
-}
-
-
-static UCHAR GetExtCh(
-	IN UCHAR Channel,
-	IN UCHAR Direction)
-{
-	CHAR ExtCh;
-
-	if (Direction == EXTCHA_ABOVE)
-		ExtCh = Channel + 4;
-	else
-		ExtCh = (Channel - 4) > 0 ? (Channel - 4) : 0;
-
-	return ExtCh;
-}
-
-
-VOID N_ChannelCheck(
-	IN PRTMP_ADAPTER pAd)
-{
-	//UCHAR ChannelNum = pAd->ChannelListNum;
-	UCHAR Channel = pAd->CommonCfg.Channel;
-
-	if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->CommonCfg.RegTransmitSetting.field.BW  == BW_40))
-	{
-		if (Channel > 14)
-		{
-			if ((Channel == 36) || (Channel == 44) || (Channel == 52) || (Channel == 60) || (Channel == 100) || (Channel == 108) ||
-			    (Channel == 116) || (Channel == 124) || (Channel == 132) || (Channel == 149) || (Channel == 157))
-			{
-				pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
-			}
-			else if ((Channel == 40) || (Channel == 48) || (Channel == 56) || (Channel == 64) || (Channel == 104) || (Channel == 112) ||
-					(Channel == 120) || (Channel == 128) || (Channel == 136) || (Channel == 153) || (Channel == 161))
-			{
-				pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
-			}
-			else
-			{
-				pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_20;
-			}
-		}
-		else
-		{
-			do
-			{
-				UCHAR ExtCh;
-				UCHAR Dir = pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
-				ExtCh = GetExtCh(Channel, Dir);
-				if (IsValidChannel(pAd, ExtCh))
-					break;
-
-				Dir = (Dir == EXTCHA_ABOVE) ? EXTCHA_BELOW : EXTCHA_ABOVE;
-				ExtCh = GetExtCh(Channel, Dir);
-				if (IsValidChannel(pAd, ExtCh))
-				{
-					pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = Dir;
-					break;
-				}
-				pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_20;
-			} while(FALSE);
-
-			if (Channel == 14)
-			{
-				pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_20;
-				//pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_NONE;	// We didn't set the ExtCh as NONE due to it'll set in RTMPSetHT()
-			}
-		}
-	}
-
-
-}
-
-
-VOID N_SetCenCh(
-	IN PRTMP_ADAPTER pAd)
-{
-	if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
-	{
-		if (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
-		{
-			pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
-		}
-		else
-		{
-			if (pAd->CommonCfg.Channel == 14)
-				pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 1;
-			else
-				pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
-		}
-	}
-	else
-	{
-		pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
-	}
-}
-#endif // DOT11_N_SUPPORT //
-
-
-UINT8 GetCuntryMaxTxPwr(
-	IN PRTMP_ADAPTER pAd,
-	IN UINT8 channel)
-{
-	int i;
-	for (i = 0; i < pAd->ChannelListNum; i++)
-	{
-		if (pAd->ChannelList[i].Channel == channel)
-			break;
-	}
-
-	if (i == pAd->ChannelListNum)
-		return 0xff;
-	else
-		return pAd->ChannelList[i].MaxTxPwr;
-}
diff --git a/drivers/staging/rt3090/common/rt_rf.c b/drivers/staging/rt3090/common/rt_rf.c
deleted file mode 100644
index 9d638f7..0000000
--- a/drivers/staging/rt3090/common/rt_rf.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rt_rf.c
-
-	Abstract:
-	Ralink Wireless driver RF related functions
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-*/
-
-#include "../rt_config.h"
-
-
-#ifdef RTMP_RF_RW_SUPPORT
-/*
-	========================================================================
-
-	Routine Description: Write RT30xx RF register through MAC
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-NDIS_STATUS RT30xxWriteRFRegister(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			regID,
-	IN	UCHAR			value)
-{
-	RF_CSR_CFG_STRUC	rfcsr;
-	UINT				i = 0;
-
-	do
-	{
-		RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
-
-		if (!rfcsr.field.RF_CSR_KICK)
-			break;
-		i++;
-	}
-	while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
-
-	if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
-	{
-		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
-		return STATUS_UNSUCCESSFUL;
-	}
-
-	rfcsr.field.RF_CSR_WR = 1;
-	rfcsr.field.RF_CSR_KICK = 1;
-	rfcsr.field.TESTCSR_RFACC_REGNUM = regID;
-	rfcsr.field.RF_CSR_DATA = value;
-
-	RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-/*
-	========================================================================
-
-	Routine Description: Read RT30xx RF register through MAC
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-NDIS_STATUS RT30xxReadRFRegister(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			regID,
-	IN	PUCHAR			pValue)
-{
-	RF_CSR_CFG_STRUC	rfcsr;
-	UINT				i=0, k=0;
-
-	for (i=0; i<MAX_BUSY_COUNT; i++)
-	{
-		RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
-
-		if (rfcsr.field.RF_CSR_KICK == BUSY)
-		{
-			continue;
-		}
-		rfcsr.word = 0;
-		rfcsr.field.RF_CSR_WR = 0;
-		rfcsr.field.RF_CSR_KICK = 1;
-		rfcsr.field.TESTCSR_RFACC_REGNUM = regID;
-		RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
-		for (k=0; k<MAX_BUSY_COUNT; k++)
-		{
-			RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
-
-			if (rfcsr.field.RF_CSR_KICK == IDLE)
-				break;
-		}
-		if ((rfcsr.field.RF_CSR_KICK == IDLE) &&
-			(rfcsr.field.TESTCSR_RFACC_REGNUM == regID))
-		{
-			*pValue = (UCHAR)rfcsr.field.RF_CSR_DATA;
-			break;
-		}
-	}
-	if (rfcsr.field.RF_CSR_KICK == BUSY)
-	{
-		DBGPRINT_ERR(("RF read R%d=0x%x fail, i[%d], k[%d]\n", regID, rfcsr.word,i,k));
-		return STATUS_UNSUCCESSFUL;
-	}
-
-	return STATUS_SUCCESS;
-}
-
-
-VOID NICInitRFRegisters(
-	IN RTMP_ADAPTER *pAd)
-{
-	if (pAd->chipOps.AsicRfInit)
-		pAd->chipOps.AsicRfInit(pAd);
-}
-
-
-VOID RtmpChipOpsRFHook(
-	IN RTMP_ADAPTER *pAd)
-{
-	RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
-
-	pChipOps->pRFRegTable = NULL;
-	pChipOps->AsicRfInit = NULL;
-	pChipOps->AsicRfTurnOn = NULL;
-	pChipOps->AsicRfTurnOff = NULL;
-	pChipOps->AsicReverseRfFromSleepMode = NULL;
-	pChipOps->AsicHaltAction = NULL;
-#ifdef RT33xx
-if (IS_RT3390(pAd) && (pAd->infType == RTMP_DEV_INF_PCI))
-		{
-			pChipOps->pRFRegTable = RFRegTableOverRT3390;
-			pChipOps->AsicHaltAction = RT33xxHaltAction;
-			pChipOps->AsicRfTurnOff = RT33xxLoadRFSleepModeSetup;
-			pChipOps->AsicRfInit = NICInitRT3390RFRegisters;
-			pChipOps->AsicReverseRfFromSleepMode = RT33xxReverseRFSleepModeSetup;
-		}
-#else // RT33xx //
-	/* We depends on RfICType and MACVersion to assign the corresponding operation callbacks. */
-
-#ifdef RT30xx
-	if (IS_RT30xx(pAd))
-	{
-		pChipOps->pRFRegTable = RT30xx_RFRegTable;
-		pChipOps->AsicHaltAction = RT30xxHaltAction;
-#ifdef RT3090
-		if (IS_RT3090(pAd) && (pAd->infType == RTMP_DEV_INF_PCI))
-		{
-			pChipOps->AsicRfTurnOff = RT30xxLoadRFSleepModeSetup;
-			pChipOps->AsicRfInit = NICInitRT3090RFRegisters;
-			pChipOps->AsicReverseRfFromSleepMode = RT30xxReverseRFSleepModeSetup;
-		}
-#endif // RT3090 //
-	}
-#endif // RT30xx //
-#endif // RT33xx //
-}
-
-#endif // RTMP_RF_RW_SUPPORT //
diff --git a/drivers/staging/rt3090/common/rtmp_init.c b/drivers/staging/rt3090/common/rtmp_init.c
deleted file mode 100644
index 48b95b7..0000000
--- a/drivers/staging/rt3090/common/rtmp_init.c
+++ /dev/null
@@ -1,3882 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtmp_init.c
-
-	Abstract:
-	Miniport generic portion header file
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-*/
-
-#include "../rt_config.h"
-
-
-UCHAR    BIT8[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
-char*   CipherName[] = {"none","wep64","wep128","TKIP","AES","CKIP64","CKIP128"};
-
-//
-// BBP register initialization set
-//
-REG_PAIR   BBPRegTable[] = {
-	{BBP_R65,		0x2C},		// fix rssi issue
-	{BBP_R66,		0x38},	// Also set this default value to pAd->BbpTuning.R66CurrentValue at initial
-	{BBP_R69,		0x12},
-	{BBP_R70,		0xa},	// BBP_R70 will change to 0x8 in ApStartUp and LinkUp for rt2860C, otherwise value is 0xa
-	{BBP_R73,		0x10},
-	{BBP_R81,		0x37},
-	{BBP_R82,		0x62},
-	{BBP_R83,		0x6A},
-	{BBP_R84,		0x99},	// 0x19 is for rt2860E and after. This is for extension channel overlapping IOT. 0x99 is for rt2860D and before
-	{BBP_R86,		0x00},	// middle range issue, Rory @2008-01-28
-	{BBP_R91,		0x04},	// middle range issue, Rory @2008-01-28
-	{BBP_R92,		0x00},	// middle range issue, Rory @2008-01-28
-	{BBP_R103,		0x00},	// near range high-power issue, requested from Gary @2008-0528
-	{BBP_R105,		0x05},	// 0x05 is for rt2860E to turn on FEQ control. It is safe for rt2860D and before, because Bit 7:2 are reserved in rt2860D and before.
-	{BBP_R106,		0x35},  // for ShortGI throughput
-};
-#define	NUM_BBP_REG_PARMS	(sizeof(BBPRegTable) / sizeof(REG_PAIR))
-
-
-//
-// ASIC register initialization sets
-//
-
-RTMP_REG_PAIR	MACRegTable[] =	{
-#if defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x200)
-	{BCN_OFFSET0,			0xf8f0e8e0}, /* 0x3800(e0), 0x3A00(e8), 0x3C00(f0), 0x3E00(f8), 512B for each beacon */
-	{BCN_OFFSET1,			0x6f77d0c8}, /* 0x3200(c8), 0x3400(d0), 0x1DC0(77), 0x1BC0(6f), 512B for each beacon */
-#elif defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x100)
-	{BCN_OFFSET0,			0xece8e4e0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
-	{BCN_OFFSET1,			0xfcf8f4f0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
-#else
-    #error You must re-calculate new value for BCN_OFFSET0 & BCN_OFFSET1 in MACRegTable[]!!!
-#endif // HW_BEACON_OFFSET //
-
-	{LEGACY_BASIC_RATE,		0x0000013f}, //  Basic rate set bitmap
-	{HT_BASIC_RATE,		0x00008003}, // Basic HT rate set , 20M, MCS=3, MM. Format is the same as in TXWI.
-	{MAC_SYS_CTRL,		0x00}, // 0x1004, , default Disable RX
-	{RX_FILTR_CFG,		0x17f97}, //0x1400  , RX filter control,
-	{BKOFF_SLOT_CFG,	0x209}, // default set short slot time, CC_DELAY_TIME should be 2
-	//{TX_SW_CFG0,		0x40a06}, // Gary,2006-08-23
-	{TX_SW_CFG0,		0x0},		// Gary,2008-05-21 for CWC test
-	{TX_SW_CFG1,		0x80606}, // Gary,2006-08-23
-	{TX_LINK_CFG,		0x1020},		// Gary,2006-08-23
-	//{TX_TIMEOUT_CFG,	0x00182090},	// CCK has some problem. So increase timieout value. 2006-10-09// MArvek RT
-	{TX_TIMEOUT_CFG,	0x000a2090},	// CCK has some problem. So increase timieout value. 2006-10-09// MArvek RT , Modify for 2860E ,2007-08-01
-	{MAX_LEN_CFG,		MAX_AGGREGATION_SIZE | 0x00001000},	// 0x3018, MAX frame length. Max PSDU = 16kbytes.
-	{LED_CFG,		0x7f031e46}, // Gary, 2006-08-23
-
-//#ifdef CONFIG_AP_SUPPORT
-//	{WMM_AIFSN_CFG,		0x00001173},
-//	{WMM_CWMIN_CFG,		0x00002344},
-//	{WMM_CWMAX_CFG,		0x000034a6},
-//	{WMM_TXOP0_CFG,		0x00100020},
-//	{WMM_TXOP1_CFG,		0x002F0038},
-//#endif // CONFIG_AP_SUPPORT //
-
-//#ifdef CONFIG_STA_SUPPORT
-//	{WMM_AIFSN_CFG,		0x00002273},
-//	{WMM_CWMIN_CFG,		0x00002344},
-//	{WMM_CWMAX_CFG,		0x000034aa},
-//#endif // CONFIG_STA_SUPPORT //
-#ifdef INF_AMAZON_SE
-	{PBF_MAX_PCNT,			0x1F3F6F6F},	//iverson modify for usb issue, 2008/09/19
-											// 6F + 6F < total page count FE
-											// so that RX doesn't occupy TX's buffer space when WMM congestion.
-#else
-	{PBF_MAX_PCNT,			0x1F3FBF9F},	//0x1F3f7f9f},		//Jan, 2006/04/20
-#endif // INF_AMAZON_SE //
-	//{TX_RTY_CFG,			0x6bb80408},	// Jan, 2006/11/16
-// WMM_ACM_SUPPORT
-//	{TX_RTY_CFG,			0x6bb80101},	// sample
-	{TX_RTY_CFG,			0x47d01f0f},	// Jan, 2006/11/16, Set TxWI->ACK =0 in Probe Rsp Modify for 2860E ,2007-08-03
-
-	{AUTO_RSP_CFG,			0x00000013},	// Initial Auto_Responder, because QA will turn off Auto-Responder
-	{CCK_PROT_CFG,			0x05740003 /*0x01740003*/},	// Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled.
-	{OFDM_PROT_CFG,			0x05740003 /*0x01740003*/},	// Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled.
-	{GF20_PROT_CFG,			0x01744004},    // set 19:18 --> Short NAV for MIMO PS
-	{GF40_PROT_CFG,			0x03F44084},
-	{MM20_PROT_CFG,			0x01744004},
-#ifdef RTMP_MAC_PCI
-	{MM40_PROT_CFG,			0x03F54084},
-#endif // RTMP_MAC_PCI //
-	{TXOP_CTRL_CFG,			0x0000583f, /*0x0000243f*/ /*0x000024bf*/},	//Extension channel backoff.
-	{TX_RTS_CFG,			0x00092b20},
-//#ifdef WIFI_TEST
-	{EXP_ACK_TIME,			0x002400ca},	// default value
-//#else
-//	{EXP_ACK_TIME,			0x005400ca},	// suggested by Gray @ 20070323 for 11n intel-sta throughput
-//#endif // end - WIFI_TEST //
-//#ifdef CONFIG_AP_SUPPORT
-//	{TBTT_SYNC_CFG,			0x00422000},	// TBTT_ADJUST(7:0) == 0
-//	{TBTT_SYNC_CFG,			0x00012000},	// TBTT_ADJUST(7:0) == 0
-//#endif // CONFIG_AP_SUPPORT //
-	{TXOP_HLDR_ET,			0x00000002},
-
-	/* Jerry comments 2008/01/16: we use SIFS = 10us in CCK defaultly, but it seems that 10us
-		is too small for INTEL 2200bg card, so in MBSS mode, the delta time between beacon0
-		and beacon1 is SIFS (10us), so if INTEL 2200bg card connects to BSS0, the ping
-		will always lost. So we change the SIFS of CCK from 10us to 16us. */
-	{XIFS_TIME_CFG,			0x33a41010},
-	{PWR_PIN_CFG,			0x00000003},	// patch for 2880-E
-};
-
-
-#ifdef CONFIG_STA_SUPPORT
-RTMP_REG_PAIR	STAMACRegTable[] =	{
-	{WMM_AIFSN_CFG,		0x00002273},
-	{WMM_CWMIN_CFG,	0x00002344},
-	{WMM_CWMAX_CFG,	0x000034aa},
-};
-#endif // CONFIG_STA_SUPPORT //
-
-#define	NUM_MAC_REG_PARMS		(sizeof(MACRegTable) / sizeof(RTMP_REG_PAIR))
-#ifdef CONFIG_STA_SUPPORT
-#define	NUM_STA_MAC_REG_PARMS	(sizeof(STAMACRegTable) / sizeof(RTMP_REG_PAIR))
-#endif // CONFIG_STA_SUPPORT //
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Allocate RTMP_ADAPTER data block and do some initialization
-
-	Arguments:
-		Adapter		Pointer to our adapter
-
-	Return Value:
-		NDIS_STATUS_SUCCESS
-		NDIS_STATUS_FAILURE
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-NDIS_STATUS	RTMPAllocAdapterBlock(
-	IN  PVOID	handle,
-	OUT	PRTMP_ADAPTER	*ppAdapter)
-{
-	PRTMP_ADAPTER	pAd;
-	NDIS_STATUS		Status;
-	INT			index;
-	UCHAR			*pBeaconBuf = NULL;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocAdapterBlock\n"));
-
-	*ppAdapter = NULL;
-
-	do
-	{
-		// Allocate RTMP_ADAPTER memory block
-		pBeaconBuf = kmalloc(MAX_BEACON_SIZE, MEM_ALLOC_FLAG);
-		if (pBeaconBuf == NULL)
-		{
-			Status = NDIS_STATUS_FAILURE;
-			DBGPRINT_ERR(("Failed to allocate memory - BeaconBuf!\n"));
-			break;
-		}
-		NdisZeroMemory(pBeaconBuf, MAX_BEACON_SIZE);
-
-		Status = AdapterBlockAllocateMemory(handle, (PVOID *)&pAd);
-		if (Status != NDIS_STATUS_SUCCESS)
-		{
-			DBGPRINT_ERR(("Failed to allocate memory - ADAPTER\n"));
-			break;
-		}
-		pAd->BeaconBuf = pBeaconBuf;
-		DBGPRINT(RT_DEBUG_OFF, ("\n\n=== pAd = %p, size = %d ===\n\n", pAd, (UINT32)sizeof(RTMP_ADAPTER)));
-
-
-		// Init spin locks
-		NdisAllocateSpinLock(&pAd->MgmtRingLock);
-#ifdef RTMP_MAC_PCI
-		NdisAllocateSpinLock(&pAd->RxRingLock);
-#ifdef RT3090
-#ifdef CONFIG_STA_SUPPORT
-	NdisAllocateSpinLock(&pAd->McuCmdLock);
-#endif // CONFIG_STA_SUPPORT //
-#endif // RT3090 //
-#endif // RTMP_MAC_PCI //
-
-		for (index =0 ; index < NUM_OF_TX_RING; index++)
-		{
-			NdisAllocateSpinLock(&pAd->TxSwQueueLock[index]);
-			NdisAllocateSpinLock(&pAd->DeQueueLock[index]);
-			pAd->DeQueueRunning[index] = FALSE;
-		}
-
-		NdisAllocateSpinLock(&pAd->irq_lock);
-
-
-	} while (FALSE);
-
-	if ((Status != NDIS_STATUS_SUCCESS) && (pBeaconBuf))
-		kfree(pBeaconBuf);
-
-	*ppAdapter = pAd;
-
-	DBGPRINT_S(Status, ("<-- RTMPAllocAdapterBlock, Status=%x\n", Status));
-	return Status;
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Read initial Tx power per MCS and BW from EEPROM
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPReadTxPwrPerRate(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	ULONG		data, Adata, Gdata;
-	USHORT		i, value, value2;
-	INT			Apwrdelta, Gpwrdelta;
-	UCHAR		t1,t2,t3,t4;
-	BOOLEAN		bApwrdeltaMinus = TRUE, bGpwrdeltaMinus = TRUE;
-
-	//
-	// Get power delta for 20MHz and 40MHz.
-	//
-	DBGPRINT(RT_DEBUG_TRACE, ("Txpower per Rate\n"));
-	RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_DELTA, value2);
-	Apwrdelta = 0;
-	Gpwrdelta = 0;
-
-	if ((value2 & 0xff) != 0xff)
-	{
-		if ((value2 & 0x80))
-			Gpwrdelta = (value2&0xf);
-
-		if ((value2 & 0x40))
-			bGpwrdeltaMinus = FALSE;
-		else
-			bGpwrdeltaMinus = TRUE;
-	}
-	if ((value2 & 0xff00) != 0xff00)
-	{
-		if ((value2 & 0x8000))
-			Apwrdelta = ((value2&0xf00)>>8);
-
-		if ((value2 & 0x4000))
-			bApwrdeltaMinus = FALSE;
-		else
-			bApwrdeltaMinus = TRUE;
-	}
-	DBGPRINT(RT_DEBUG_TRACE, ("Gpwrdelta = %x, Apwrdelta = %x .\n", Gpwrdelta, Apwrdelta));
-
-	//
-	// Get Txpower per MCS for 20MHz in 2.4G.
-	//
-	for (i=0; i<5; i++)
-	{
-		RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i*4, value);
-		data = value;
-		if (bApwrdeltaMinus == FALSE)
-		{
-			t1 = (value&0xf)+(Apwrdelta);
-			if (t1 > 0xf)
-				t1 = 0xf;
-			t2 = ((value&0xf0)>>4)+(Apwrdelta);
-			if (t2 > 0xf)
-				t2 = 0xf;
-			t3 = ((value&0xf00)>>8)+(Apwrdelta);
-			if (t3 > 0xf)
-				t3 = 0xf;
-			t4 = ((value&0xf000)>>12)+(Apwrdelta);
-			if (t4 > 0xf)
-				t4 = 0xf;
-		}
-		else
-		{
-			if ((value&0xf) > Apwrdelta)
-				t1 = (value&0xf)-(Apwrdelta);
-			else
-				t1 = 0;
-			if (((value&0xf0)>>4) > Apwrdelta)
-				t2 = ((value&0xf0)>>4)-(Apwrdelta);
-			else
-				t2 = 0;
-			if (((value&0xf00)>>8) > Apwrdelta)
-				t3 = ((value&0xf00)>>8)-(Apwrdelta);
-			else
-				t3 = 0;
-			if (((value&0xf000)>>12) > Apwrdelta)
-				t4 = ((value&0xf000)>>12)-(Apwrdelta);
-			else
-				t4 = 0;
-		}
-		Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
-		if (bGpwrdeltaMinus == FALSE)
-		{
-			t1 = (value&0xf)+(Gpwrdelta);
-			if (t1 > 0xf)
-				t1 = 0xf;
-			t2 = ((value&0xf0)>>4)+(Gpwrdelta);
-			if (t2 > 0xf)
-				t2 = 0xf;
-			t3 = ((value&0xf00)>>8)+(Gpwrdelta);
-			if (t3 > 0xf)
-				t3 = 0xf;
-			t4 = ((value&0xf000)>>12)+(Gpwrdelta);
-			if (t4 > 0xf)
-				t4 = 0xf;
-		}
-		else
-		{
-			if ((value&0xf) > Gpwrdelta)
-				t1 = (value&0xf)-(Gpwrdelta);
-			else
-				t1 = 0;
-			if (((value&0xf0)>>4) > Gpwrdelta)
-				t2 = ((value&0xf0)>>4)-(Gpwrdelta);
-			else
-				t2 = 0;
-			if (((value&0xf00)>>8) > Gpwrdelta)
-				t3 = ((value&0xf00)>>8)-(Gpwrdelta);
-			else
-				t3 = 0;
-			if (((value&0xf000)>>12) > Gpwrdelta)
-				t4 = ((value&0xf000)>>12)-(Gpwrdelta);
-			else
-				t4 = 0;
-		}
-		Gdata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
-
-		RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i*4 + 2, value);
-		if (bApwrdeltaMinus == FALSE)
-		{
-			t1 = (value&0xf)+(Apwrdelta);
-			if (t1 > 0xf)
-				t1 = 0xf;
-			t2 = ((value&0xf0)>>4)+(Apwrdelta);
-			if (t2 > 0xf)
-				t2 = 0xf;
-			t3 = ((value&0xf00)>>8)+(Apwrdelta);
-			if (t3 > 0xf)
-				t3 = 0xf;
-			t4 = ((value&0xf000)>>12)+(Apwrdelta);
-			if (t4 > 0xf)
-				t4 = 0xf;
-		}
-		else
-		{
-			if ((value&0xf) > Apwrdelta)
-				t1 = (value&0xf)-(Apwrdelta);
-			else
-				t1 = 0;
-			if (((value&0xf0)>>4) > Apwrdelta)
-				t2 = ((value&0xf0)>>4)-(Apwrdelta);
-			else
-				t2 = 0;
-			if (((value&0xf00)>>8) > Apwrdelta)
-				t3 = ((value&0xf00)>>8)-(Apwrdelta);
-			else
-				t3 = 0;
-			if (((value&0xf000)>>12) > Apwrdelta)
-				t4 = ((value&0xf000)>>12)-(Apwrdelta);
-			else
-				t4 = 0;
-		}
-		Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
-		if (bGpwrdeltaMinus == FALSE)
-		{
-			t1 = (value&0xf)+(Gpwrdelta);
-			if (t1 > 0xf)
-				t1 = 0xf;
-			t2 = ((value&0xf0)>>4)+(Gpwrdelta);
-			if (t2 > 0xf)
-				t2 = 0xf;
-			t3 = ((value&0xf00)>>8)+(Gpwrdelta);
-			if (t3 > 0xf)
-				t3 = 0xf;
-			t4 = ((value&0xf000)>>12)+(Gpwrdelta);
-			if (t4 > 0xf)
-				t4 = 0xf;
-		}
-		else
-		{
-			if ((value&0xf) > Gpwrdelta)
-				t1 = (value&0xf)-(Gpwrdelta);
-			else
-				t1 = 0;
-			if (((value&0xf0)>>4) > Gpwrdelta)
-				t2 = ((value&0xf0)>>4)-(Gpwrdelta);
-			else
-				t2 = 0;
-			if (((value&0xf00)>>8) > Gpwrdelta)
-				t3 = ((value&0xf00)>>8)-(Gpwrdelta);
-			else
-				t3 = 0;
-			if (((value&0xf000)>>12) > Gpwrdelta)
-				t4 = ((value&0xf000)>>12)-(Gpwrdelta);
-			else
-				t4 = 0;
-		}
-		Gdata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
-		data |= (value<<16);
-
-		/* For 20M/40M Power Delta issue */
-		pAd->Tx20MPwrCfgABand[i] = data;
-		pAd->Tx20MPwrCfgGBand[i] = data;
-		pAd->Tx40MPwrCfgABand[i] = Adata;
-		pAd->Tx40MPwrCfgGBand[i] = Gdata;
-
-		if (data != 0xffffffff)
-			RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, data);
-		DBGPRINT_RAW(RT_DEBUG_TRACE, ("20MHz BW, 2.4G band-%lx,  Adata = %lx,  Gdata = %lx \n", data, Adata, Gdata));
-	}
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Read initial channel power parameters from EEPROM
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPReadChannelPwr(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	UCHAR				i, choffset;
-	EEPROM_TX_PWR_STRUC	    Power;
-	EEPROM_TX_PWR_STRUC	    Power2;
-
-	// Read Tx power value for all channels
-	// Value from 1 - 0x7f. Default value is 24.
-	// Power value : 2.4G 0x00 (0) ~ 0x1F (31)
-	//             : 5.5G 0xF9 (-7) ~ 0x0F (15)
-
-	// 0. 11b/g, ch1 - ch 14
-	for (i = 0; i < 7; i++)
-	{
-		RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX_PWR_OFFSET + i * 2, Power.word);
-		RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX2_PWR_OFFSET + i * 2, Power2.word);
-		pAd->TxPower[i * 2].Channel = i * 2 + 1;
-		pAd->TxPower[i * 2 + 1].Channel = i * 2 + 2;
-
-		if ((Power.field.Byte0 > 31) || (Power.field.Byte0 < 0))
-			pAd->TxPower[i * 2].Power = DEFAULT_RF_TX_POWER;
-		else
-			pAd->TxPower[i * 2].Power = Power.field.Byte0;
-
-		if ((Power.field.Byte1 > 31) || (Power.field.Byte1 < 0))
-			pAd->TxPower[i * 2 + 1].Power = DEFAULT_RF_TX_POWER;
-		else
-			pAd->TxPower[i * 2 + 1].Power = Power.field.Byte1;
-
-		if ((Power2.field.Byte0 > 31) || (Power2.field.Byte0 < 0))
-			pAd->TxPower[i * 2].Power2 = DEFAULT_RF_TX_POWER;
-		else
-			pAd->TxPower[i * 2].Power2 = Power2.field.Byte0;
-
-		if ((Power2.field.Byte1 > 31) || (Power2.field.Byte1 < 0))
-			pAd->TxPower[i * 2 + 1].Power2 = DEFAULT_RF_TX_POWER;
-		else
-			pAd->TxPower[i * 2 + 1].Power2 = Power2.field.Byte1;
-	}
-
-	// 1. U-NII lower/middle band: 36, 38, 40; 44, 46, 48; 52, 54, 56; 60, 62, 64 (including central frequency in BW 40MHz)
-	// 1.1 Fill up channel
-	choffset = 14;
-	for (i = 0; i < 4; i++)
-	{
-		pAd->TxPower[3 * i + choffset + 0].Channel	= 36 + i * 8 + 0;
-		pAd->TxPower[3 * i + choffset + 0].Power	= DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 0].Power2	= DEFAULT_RF_TX_POWER;
-
-		pAd->TxPower[3 * i + choffset + 1].Channel	= 36 + i * 8 + 2;
-		pAd->TxPower[3 * i + choffset + 1].Power	= DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 1].Power2	= DEFAULT_RF_TX_POWER;
-
-		pAd->TxPower[3 * i + choffset + 2].Channel	= 36 + i * 8 + 4;
-		pAd->TxPower[3 * i + choffset + 2].Power	= DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 2].Power2	= DEFAULT_RF_TX_POWER;
-	}
-
-	// 1.2 Fill up power
-	for (i = 0; i < 6; i++)
-	{
-		RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + i * 2, Power.word);
-		RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + i * 2, Power2.word);
-
-		if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
-			pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0;
-
-		if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
-			pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1;
-
-		if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
-			pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0;
-
-		if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
-			pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
-	}
-
-	// 2. HipperLAN 2 100, 102 ,104; 108, 110, 112; 116, 118, 120; 124, 126, 128; 132, 134, 136; 140 (including central frequency in BW 40MHz)
-	// 2.1 Fill up channel
-	choffset = 14 + 12;
-	for (i = 0; i < 5; i++)
-	{
-		pAd->TxPower[3 * i + choffset + 0].Channel	= 100 + i * 8 + 0;
-		pAd->TxPower[3 * i + choffset + 0].Power	= DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 0].Power2	= DEFAULT_RF_TX_POWER;
-
-		pAd->TxPower[3 * i + choffset + 1].Channel	= 100 + i * 8 + 2;
-		pAd->TxPower[3 * i + choffset + 1].Power	= DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 1].Power2	= DEFAULT_RF_TX_POWER;
-
-		pAd->TxPower[3 * i + choffset + 2].Channel	= 100 + i * 8 + 4;
-		pAd->TxPower[3 * i + choffset + 2].Power	= DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 2].Power2	= DEFAULT_RF_TX_POWER;
-	}
-	pAd->TxPower[3 * 5 + choffset + 0].Channel		= 140;
-	pAd->TxPower[3 * 5 + choffset + 0].Power		= DEFAULT_RF_TX_POWER;
-	pAd->TxPower[3 * 5 + choffset + 0].Power2		= DEFAULT_RF_TX_POWER;
-
-	// 2.2 Fill up power
-	for (i = 0; i < 8; i++)
-	{
-		RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2, Power.word);
-		RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2, Power2.word);
-
-		if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
-			pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0;
-
-		if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
-			pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1;
-
-		if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
-			pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0;
-
-		if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
-			pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
-	}
-
-	// 3. U-NII upper band: 149, 151, 153; 157, 159, 161; 165, 167, 169; 171, 173 (including central frequency in BW 40MHz)
-	// 3.1 Fill up channel
-	choffset = 14 + 12 + 16;
-	/*for (i = 0; i < 2; i++)*/
-	for (i = 0; i < 3; i++)
-	{
-		pAd->TxPower[3 * i + choffset + 0].Channel	= 149 + i * 8 + 0;
-		pAd->TxPower[3 * i + choffset + 0].Power	= DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 0].Power2	= DEFAULT_RF_TX_POWER;
-
-		pAd->TxPower[3 * i + choffset + 1].Channel	= 149 + i * 8 + 2;
-		pAd->TxPower[3 * i + choffset + 1].Power	= DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 1].Power2	= DEFAULT_RF_TX_POWER;
-
-		pAd->TxPower[3 * i + choffset + 2].Channel	= 149 + i * 8 + 4;
-		pAd->TxPower[3 * i + choffset + 2].Power	= DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 2].Power2	= DEFAULT_RF_TX_POWER;
-	}
-	pAd->TxPower[3 * 3 + choffset + 0].Channel		= 171;
-	pAd->TxPower[3 * 3 + choffset + 0].Power		= DEFAULT_RF_TX_POWER;
-	pAd->TxPower[3 * 3 + choffset + 0].Power2		= DEFAULT_RF_TX_POWER;
-
-	pAd->TxPower[3 * 3 + choffset + 1].Channel		= 173;
-	pAd->TxPower[3 * 3 + choffset + 1].Power		= DEFAULT_RF_TX_POWER;
-	pAd->TxPower[3 * 3 + choffset + 1].Power2		= DEFAULT_RF_TX_POWER;
-
-	// 3.2 Fill up power
-	/*for (i = 0; i < 4; i++)*/
-	for (i = 0; i < 6; i++)
-	{
-		RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2, Power.word);
-		RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2, Power2.word);
-
-		if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
-			pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0;
-
-		if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
-			pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1;
-
-		if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
-			pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0;
-
-		if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
-			pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
-	}
-
-	// 4. Print and Debug
-	/*choffset = 14 + 12 + 16 + 7;*/
-	choffset = 14 + 12 + 16 + 11;
-
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Read the following from the registry
-		1. All the parameters
-		2. NetworkAddres
-
-	Arguments:
-		Adapter						Pointer to our adapter
-		WrapperConfigurationContext	For use by NdisOpenConfiguration
-
-	Return Value:
-		NDIS_STATUS_SUCCESS
-		NDIS_STATUS_FAILURE
-		NDIS_STATUS_RESOURCES
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-NDIS_STATUS	NICReadRegParameters(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	NDIS_HANDLE			WrapperConfigurationContext
-	)
-{
-	NDIS_STATUS						Status = NDIS_STATUS_SUCCESS;
-	DBGPRINT_S(Status, ("<-- NICReadRegParameters, Status=%x\n", Status));
-	return Status;
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Read initial parameters from EEPROM
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	NICReadEEPROMParameters(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			mac_addr)
-{
-	UINT32			data = 0;
-	USHORT			i, value, value2;
-	UCHAR			TmpPhy;
-	EEPROM_TX_PWR_STRUC	    Power;
-	EEPROM_VERSION_STRUC    Version;
-	EEPROM_ANTENNA_STRUC	Antenna;
-	EEPROM_NIC_CONFIG2_STRUC    NicConfig2;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> NICReadEEPROMParameters\n"));
-
-	if (pAd->chipOps.eeinit)
-		pAd->chipOps.eeinit(pAd);
-#ifdef RTMP_EFUSE_SUPPORT
-#ifdef RT30xx
-	if(!pAd->bFroceEEPROMBuffer && pAd->bEEPROMFile)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("--> NICReadEEPROMParameters::(Efuse)Load  to EEPROM Buffer Mode\n"));
-		eFuseLoadEEPROM(pAd);
-	}
-#endif // RT30xx //
-#endif // RTMP_EFUSE_SUPPORT //
-
-	// Init EEPROM Address Number, before access EEPROM; if 93c46, EEPROMAddressNum=6, else if 93c66, EEPROMAddressNum=8
-	RTMP_IO_READ32(pAd, E2PROM_CSR, &data);
-	DBGPRINT(RT_DEBUG_TRACE, ("--> E2PROM_CSR = 0x%x\n", data));
-
-	if((data & 0x30) == 0)
-		pAd->EEPROMAddressNum = 6;		// 93C46
-	else if((data & 0x30) == 0x10)
-		pAd->EEPROMAddressNum = 8;     // 93C66
-	else
-		pAd->EEPROMAddressNum = 8;     // 93C86
-	DBGPRINT(RT_DEBUG_TRACE, ("--> EEPROMAddressNum = %d\n", pAd->EEPROMAddressNum ));
-
-	// RT2860 MAC no longer auto load MAC address from E2PROM. Driver has to intialize
-	// MAC address registers according to E2PROM setting
-	if (mac_addr == NULL ||
-		strlen((PSTRING) mac_addr) != 17 ||
-		mac_addr[2] != ':'  || mac_addr[5] != ':'  || mac_addr[8] != ':' ||
-		mac_addr[11] != ':' || mac_addr[14] != ':')
-	{
-		USHORT  Addr01,Addr23,Addr45 ;
-
-		RT28xx_EEPROM_READ16(pAd, 0x04, Addr01);
-		RT28xx_EEPROM_READ16(pAd, 0x06, Addr23);
-		RT28xx_EEPROM_READ16(pAd, 0x08, Addr45);
-
-		pAd->PermanentAddress[0] = (UCHAR)(Addr01 & 0xff);
-		pAd->PermanentAddress[1] = (UCHAR)(Addr01 >> 8);
-		pAd->PermanentAddress[2] = (UCHAR)(Addr23 & 0xff);
-		pAd->PermanentAddress[3] = (UCHAR)(Addr23 >> 8);
-		pAd->PermanentAddress[4] = (UCHAR)(Addr45 & 0xff);
-		pAd->PermanentAddress[5] = (UCHAR)(Addr45 >> 8);
-
-		DBGPRINT(RT_DEBUG_TRACE, ("Initialize MAC Address from E2PROM \n"));
-	}
-	else
-	{
-		INT		j;
-		PSTRING	macptr;
-
-		macptr = (PSTRING) mac_addr;
-
-		for (j=0; j<MAC_ADDR_LEN; j++)
-		{
-			AtoH(macptr, &pAd->PermanentAddress[j], 1);
-			macptr=macptr+3;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("Initialize MAC Address from module parameter \n"));
-	}
-
-
-	{
-		//more conveninet to test mbssid, so ap's bssid &0xf1
-		if (pAd->PermanentAddress[0] == 0xff)
-			pAd->PermanentAddress[0] = RandomByte(pAd)&0xf8;
-
-		//if (pAd->PermanentAddress[5] == 0xff)
-		//	pAd->PermanentAddress[5] = RandomByte(pAd)&0xf8;
-
-		DBGPRINT_RAW(RT_DEBUG_TRACE,("E2PROM MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n",
-			pAd->PermanentAddress[0], pAd->PermanentAddress[1],
-			pAd->PermanentAddress[2], pAd->PermanentAddress[3],
-			pAd->PermanentAddress[4], pAd->PermanentAddress[5]));
-		if (pAd->bLocalAdminMAC == FALSE)
-		{
-			MAC_DW0_STRUC csr2;
-			MAC_DW1_STRUC csr3;
-			COPY_MAC_ADDR(pAd->CurrentAddress, pAd->PermanentAddress);
-			csr2.field.Byte0 = pAd->CurrentAddress[0];
-			csr2.field.Byte1 = pAd->CurrentAddress[1];
-			csr2.field.Byte2 = pAd->CurrentAddress[2];
-			csr2.field.Byte3 = pAd->CurrentAddress[3];
-			RTMP_IO_WRITE32(pAd, MAC_ADDR_DW0, csr2.word);
-			csr3.word = 0;
-			csr3.field.Byte4 = pAd->CurrentAddress[4];
-			csr3.field.Byte5 = pAd->CurrentAddress[5];
-			csr3.field.U2MeMask = 0xff;
-			RTMP_IO_WRITE32(pAd, MAC_ADDR_DW1, csr3.word);
-			DBGPRINT_RAW(RT_DEBUG_TRACE,("E2PROM MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n",
-							PRINT_MAC(pAd->PermanentAddress)));
-		}
-	}
-
-	// if not return early. cause fail at emulation.
-	// Init the channel number for TX channel power
-	RTMPReadChannelPwr(pAd);
-
-	// if E2PROM version mismatch with driver's expectation, then skip
-	// all subsequent E2RPOM retieval and set a system error bit to notify GUI
-	RT28xx_EEPROM_READ16(pAd, EEPROM_VERSION_OFFSET, Version.word);
-	pAd->EepromVersion = Version.field.Version + Version.field.FaeReleaseNumber * 256;
-	DBGPRINT(RT_DEBUG_TRACE, ("E2PROM: Version = %d, FAE release #%d\n", Version.field.Version, Version.field.FaeReleaseNumber));
-
-	if (Version.field.Version > VALID_EEPROM_VERSION)
-	{
-		DBGPRINT_ERR(("E2PROM: WRONG VERSION 0x%x, should be %d\n",Version.field.Version, VALID_EEPROM_VERSION));
-		/*pAd->SystemErrorBitmap |= 0x00000001;
-
-		// hard-code default value when no proper E2PROM installed
-		pAd->bAutoTxAgcA = FALSE;
-		pAd->bAutoTxAgcG = FALSE;
-
-		// Default the channel power
-		for (i = 0; i < MAX_NUM_OF_CHANNELS; i++)
-			pAd->TxPower[i].Power = DEFAULT_RF_TX_POWER;
-
-		// Default the channel power
-		for (i = 0; i < MAX_NUM_OF_11JCHANNELS; i++)
-			pAd->TxPower11J[i].Power = DEFAULT_RF_TX_POWER;
-
-		for(i = 0; i < NUM_EEPROM_BBP_PARMS; i++)
-			pAd->EEPROMDefaultValue[i] = 0xffff;
-		return;  */
-	}
-
-	// Read BBP default value from EEPROM and store to array(EEPROMDefaultValue) in pAd
-	RT28xx_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET, value);
-	pAd->EEPROMDefaultValue[0] = value;
-
-	RT28xx_EEPROM_READ16(pAd, EEPROM_NIC2_OFFSET, value);
-	pAd->EEPROMDefaultValue[1] = value;
-
-	RT28xx_EEPROM_READ16(pAd, 0x38, value);	// Country Region
-	pAd->EEPROMDefaultValue[2] = value;
-
-	for(i = 0; i < 8; i++)
-	{
-		RT28xx_EEPROM_READ16(pAd, EEPROM_BBP_BASE_OFFSET + i*2, value);
-		pAd->EEPROMDefaultValue[i+3] = value;
-	}
-
-	// We have to parse NIC configuration 0 at here.
-	// If TSSI did not have preloaded value, it should reset the TxAutoAgc to false
-	// Therefore, we have to read TxAutoAgc control beforehand.
-	// Read Tx AGC control bit
-	Antenna.word = pAd->EEPROMDefaultValue[0];
-	if (Antenna.word == 0xFFFF)
-	{
-#ifdef RT30xx
-		if(IS_RT3090(pAd)|| IS_RT3390(pAd))
-		{
-			Antenna.word = 0;
-			Antenna.field.RfIcType = RFIC_3020;
-			Antenna.field.TxPath = 1;
-			Antenna.field.RxPath = 1;
-		}
-		else
-#endif // RT30xx //
-		{
-
-			Antenna.word = 0;
-			Antenna.field.RfIcType = RFIC_2820;
-			Antenna.field.TxPath = 1;
-			Antenna.field.RxPath = 2;
-			DBGPRINT(RT_DEBUG_WARN, ("E2PROM error, hard code as 0x%04x\n", Antenna.word));
-		}
-	}
-
-	// Choose the desired Tx&Rx stream.
-	if ((pAd->CommonCfg.TxStream == 0) || (pAd->CommonCfg.TxStream > Antenna.field.TxPath))
-		pAd->CommonCfg.TxStream = Antenna.field.TxPath;
-
-	if ((pAd->CommonCfg.RxStream == 0) || (pAd->CommonCfg.RxStream > Antenna.field.RxPath))
-	{
-		pAd->CommonCfg.RxStream = Antenna.field.RxPath;
-
-		if ((pAd->MACVersion < RALINK_2883_VERSION) &&
-			(pAd->CommonCfg.RxStream > 2))
-		{
-			// only 2 Rx streams for RT2860 series
-			pAd->CommonCfg.RxStream = 2;
-		}
-	}
-
-	// 3*3
-	// read value from EEPROM and set them to CSR174 ~ 177 in chain0 ~ chain2
-	// yet implement
-	for(i=0; i<3; i++)
-	{
-	}
-
-	NicConfig2.word = pAd->EEPROMDefaultValue[1];
-
-
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		if ((NicConfig2.word & 0x00ff) == 0xff)
-		{
-			NicConfig2.word &= 0xff00;
-		}
-
-		if ((NicConfig2.word >> 8) == 0xff)
-		{
-			NicConfig2.word &= 0x00ff;
-		}
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	if (NicConfig2.field.DynamicTxAgcControl == 1)
-		pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
-	else
-		pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
-
-	DBGPRINT_RAW(RT_DEBUG_TRACE, ("NICReadEEPROMParameters: RxPath = %d, TxPath = %d\n", Antenna.field.RxPath, Antenna.field.TxPath));
-
-	// Save the antenna for future use
-	pAd->Antenna.word = Antenna.word;
-
-	// Set the RfICType here, then we can initialize RFIC related operation callbacks
-	pAd->Mlme.RealRxPath = (UCHAR) Antenna.field.RxPath;
-	pAd->RfIcType = (UCHAR) Antenna.field.RfIcType;
-
-#ifdef RTMP_RF_RW_SUPPORT
-	RtmpChipOpsRFHook(pAd);
-#endif // RTMP_RF_RW_SUPPORT //
-
-	//
-	// Reset PhyMode if we don't support 802.11a
-	// Only RFIC_2850 & RFIC_2750 support 802.11a
-	//
-	if ((Antenna.field.RfIcType != RFIC_2850)
-		&& (Antenna.field.RfIcType != RFIC_2750)
-		&& (Antenna.field.RfIcType != RFIC_3052))
-	{
-		if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED) ||
-			(pAd->CommonCfg.PhyMode == PHY_11A))
-			pAd->CommonCfg.PhyMode = PHY_11BG_MIXED;
-#ifdef DOT11_N_SUPPORT
-		else if ((pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED)	||
-				 (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED)	||
-				 (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)	||
-				 (pAd->CommonCfg.PhyMode == PHY_11N_5G))
-			pAd->CommonCfg.PhyMode = PHY_11BGN_MIXED;
-#endif // DOT11_N_SUPPORT //
-	}
-
-	// Read TSSI reference and TSSI boundary for temperature compensation. This is ugly
-	// 0. 11b/g
-	{
-		/* these are tempature reference value (0x00 ~ 0xFE)
-		   ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
-		   TssiPlusBoundaryG [4] [3] [2] [1] [0] (smaller) +
-		   TssiMinusBoundaryG[0] [1] [2] [3] [4] (larger) */
-		RT28xx_EEPROM_READ16(pAd, 0x6E, Power.word);
-		pAd->TssiMinusBoundaryG[4] = Power.field.Byte0;
-		pAd->TssiMinusBoundaryG[3] = Power.field.Byte1;
-		RT28xx_EEPROM_READ16(pAd, 0x70, Power.word);
-		pAd->TssiMinusBoundaryG[2] = Power.field.Byte0;
-		pAd->TssiMinusBoundaryG[1] = Power.field.Byte1;
-		RT28xx_EEPROM_READ16(pAd, 0x72, Power.word);
-		pAd->TssiRefG   = Power.field.Byte0; /* reference value [0] */
-		pAd->TssiPlusBoundaryG[1] = Power.field.Byte1;
-		RT28xx_EEPROM_READ16(pAd, 0x74, Power.word);
-		pAd->TssiPlusBoundaryG[2] = Power.field.Byte0;
-		pAd->TssiPlusBoundaryG[3] = Power.field.Byte1;
-		RT28xx_EEPROM_READ16(pAd, 0x76, Power.word);
-		pAd->TssiPlusBoundaryG[4] = Power.field.Byte0;
-		pAd->TxAgcStepG = Power.field.Byte1;
-		pAd->TxAgcCompensateG = 0;
-		pAd->TssiMinusBoundaryG[0] = pAd->TssiRefG;
-		pAd->TssiPlusBoundaryG[0]  = pAd->TssiRefG;
-
-		// Disable TxAgc if the based value is not right
-		if (pAd->TssiRefG == 0xff)
-			pAd->bAutoTxAgcG = FALSE;
-
-		DBGPRINT(RT_DEBUG_TRACE,("E2PROM: G Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
-			pAd->TssiMinusBoundaryG[4], pAd->TssiMinusBoundaryG[3], pAd->TssiMinusBoundaryG[2], pAd->TssiMinusBoundaryG[1],
-			pAd->TssiRefG,
-			pAd->TssiPlusBoundaryG[1], pAd->TssiPlusBoundaryG[2], pAd->TssiPlusBoundaryG[3], pAd->TssiPlusBoundaryG[4],
-			pAd->TxAgcStepG, pAd->bAutoTxAgcG));
-	}
-	// 1. 11a
-	{
-		RT28xx_EEPROM_READ16(pAd, 0xD4, Power.word);
-		pAd->TssiMinusBoundaryA[4] = Power.field.Byte0;
-		pAd->TssiMinusBoundaryA[3] = Power.field.Byte1;
-		RT28xx_EEPROM_READ16(pAd, 0xD6, Power.word);
-		pAd->TssiMinusBoundaryA[2] = Power.field.Byte0;
-		pAd->TssiMinusBoundaryA[1] = Power.field.Byte1;
-		RT28xx_EEPROM_READ16(pAd, 0xD8, Power.word);
-		pAd->TssiRefA   = Power.field.Byte0;
-		pAd->TssiPlusBoundaryA[1] = Power.field.Byte1;
-		RT28xx_EEPROM_READ16(pAd, 0xDA, Power.word);
-		pAd->TssiPlusBoundaryA[2] = Power.field.Byte0;
-		pAd->TssiPlusBoundaryA[3] = Power.field.Byte1;
-		RT28xx_EEPROM_READ16(pAd, 0xDC, Power.word);
-		pAd->TssiPlusBoundaryA[4] = Power.field.Byte0;
-		pAd->TxAgcStepA = Power.field.Byte1;
-		pAd->TxAgcCompensateA = 0;
-		pAd->TssiMinusBoundaryA[0] = pAd->TssiRefA;
-		pAd->TssiPlusBoundaryA[0]  = pAd->TssiRefA;
-
-		// Disable TxAgc if the based value is not right
-		if (pAd->TssiRefA == 0xff)
-			pAd->bAutoTxAgcA = FALSE;
-
-		DBGPRINT(RT_DEBUG_TRACE,("E2PROM: A Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
-			pAd->TssiMinusBoundaryA[4], pAd->TssiMinusBoundaryA[3], pAd->TssiMinusBoundaryA[2], pAd->TssiMinusBoundaryA[1],
-			pAd->TssiRefA,
-			pAd->TssiPlusBoundaryA[1], pAd->TssiPlusBoundaryA[2], pAd->TssiPlusBoundaryA[3], pAd->TssiPlusBoundaryA[4],
-			pAd->TxAgcStepA, pAd->bAutoTxAgcA));
-	}
-	pAd->BbpRssiToDbmDelta = 0x0;
-
-	// Read frequency offset setting for RF
-	RT28xx_EEPROM_READ16(pAd, EEPROM_FREQ_OFFSET, value);
-	if ((value & 0x00FF) != 0x00FF)
-		pAd->RfFreqOffset = (ULONG) (value & 0x00FF);
-	else
-		pAd->RfFreqOffset = 0;
-	DBGPRINT(RT_DEBUG_TRACE, ("E2PROM: RF FreqOffset=0x%lx \n", pAd->RfFreqOffset));
-
-	//CountryRegion byte offset (38h)
-	value = pAd->EEPROMDefaultValue[2] >> 8;		// 2.4G band
-	value2 = pAd->EEPROMDefaultValue[2] & 0x00FF;	// 5G band
-
-	if ((value <= REGION_MAXIMUM_BG_BAND) && (value2 <= REGION_MAXIMUM_A_BAND))
-	{
-		pAd->CommonCfg.CountryRegion = ((UCHAR) value) | 0x80;
-		pAd->CommonCfg.CountryRegionForABand = ((UCHAR) value2) | 0x80;
-		TmpPhy = pAd->CommonCfg.PhyMode;
-		pAd->CommonCfg.PhyMode = 0xff;
-		RTMPSetPhyMode(pAd, TmpPhy);
-#ifdef DOT11_N_SUPPORT
-		SetCommonHT(pAd);
-#endif // DOT11_N_SUPPORT //
-	}
-
-	//
-	// Get RSSI Offset on EEPROM 0x9Ah & 0x9Ch.
-	// The valid value are (-10 ~ 10)
-	//
-	RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET, value);
-	pAd->BGRssiOffset0 = value & 0x00ff;
-	pAd->BGRssiOffset1 = (value >> 8);
-	RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET+2, value);
-	pAd->BGRssiOffset2 = value & 0x00ff;
-	pAd->ALNAGain1 = (value >> 8);
-	RT28xx_EEPROM_READ16(pAd, EEPROM_LNA_OFFSET, value);
-	pAd->BLNAGain = value & 0x00ff;
-	pAd->ALNAGain0 = (value >> 8);
-
-	// Validate 11b/g RSSI_0 offset.
-	if ((pAd->BGRssiOffset0 < -10) || (pAd->BGRssiOffset0 > 10))
-		pAd->BGRssiOffset0 = 0;
-
-	// Validate 11b/g RSSI_1 offset.
-	if ((pAd->BGRssiOffset1 < -10) || (pAd->BGRssiOffset1 > 10))
-		pAd->BGRssiOffset1 = 0;
-
-	// Validate 11b/g RSSI_2 offset.
-	if ((pAd->BGRssiOffset2 < -10) || (pAd->BGRssiOffset2 > 10))
-		pAd->BGRssiOffset2 = 0;
-
-	RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_A_OFFSET, value);
-	pAd->ARssiOffset0 = value & 0x00ff;
-	pAd->ARssiOffset1 = (value >> 8);
-	RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET+2), value);
-	pAd->ARssiOffset2 = value & 0x00ff;
-	pAd->ALNAGain2 = (value >> 8);
-
-	if (((UCHAR)pAd->ALNAGain1 == 0xFF) || (pAd->ALNAGain1 == 0x00))
-		pAd->ALNAGain1 = pAd->ALNAGain0;
-	if (((UCHAR)pAd->ALNAGain2 == 0xFF) || (pAd->ALNAGain2 == 0x00))
-		pAd->ALNAGain2 = pAd->ALNAGain0;
-
-	// Validate 11a RSSI_0 offset.
-	if ((pAd->ARssiOffset0 < -10) || (pAd->ARssiOffset0 > 10))
-		pAd->ARssiOffset0 = 0;
-
-	// Validate 11a RSSI_1 offset.
-	if ((pAd->ARssiOffset1 < -10) || (pAd->ARssiOffset1 > 10))
-		pAd->ARssiOffset1 = 0;
-
-	//Validate 11a RSSI_2 offset.
-	if ((pAd->ARssiOffset2 < -10) || (pAd->ARssiOffset2 > 10))
-		pAd->ARssiOffset2 = 0;
-
-#ifdef RT30xx
-	//
-	// Get TX mixer gain setting
-	// 0xff are invalid value
-	// Note: RT30xX default value is 0x00 and will program to RF_R17 only when this value is not zero.
-	//       RT359X default value is 0x02
-	//
-	if (IS_RT30xx(pAd) || IS_RT3572(pAd))
-	{
-		RT28xx_EEPROM_READ16(pAd, EEPROM_TXMIXER_GAIN_2_4G, value);
-		pAd->TxMixerGain24G = 0;
-		value &= 0x00ff;
-		if (value != 0xff)
-		{
-			value &= 0x07;
-			pAd->TxMixerGain24G = (UCHAR)value;
-		}
-	}
-#endif // RT30xx //
-
-	//
-	// Get LED Setting.
-	//
-	RT28xx_EEPROM_READ16(pAd, 0x3a, value);
-	pAd->LedCntl.word = (value>>8);
-	RT28xx_EEPROM_READ16(pAd, EEPROM_LED1_OFFSET, value);
-	pAd->Led1 = value;
-	RT28xx_EEPROM_READ16(pAd, EEPROM_LED2_OFFSET, value);
-	pAd->Led2 = value;
-	RT28xx_EEPROM_READ16(pAd, EEPROM_LED3_OFFSET, value);
-	pAd->Led3 = value;
-
-	RTMPReadTxPwrPerRate(pAd);
-
-#ifdef SINGLE_SKU
-	RT28xx_EEPROM_READ16(pAd, EEPROM_DEFINE_MAX_TXPWR, pAd->CommonCfg.DefineMaxTxPwr);
-#endif // SINGLE_SKU //
-
-#ifdef RT30xx
-#ifdef RTMP_EFUSE_SUPPORT
-	RtmpEfuseSupportCheck(pAd);
-#endif // RTMP_EFUSE_SUPPORT //
-#endif // RT30xx //
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICReadEEPROMParameters\n"));
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Set default value from EEPROM
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	NICInitAsicFromEEPROM(
-	IN	PRTMP_ADAPTER	pAd)
-{
-#ifdef CONFIG_STA_SUPPORT
-	UINT32					data = 0;
-	UCHAR	BBPR1 = 0;
-#endif // CONFIG_STA_SUPPORT //
-	USHORT					i;
-//	EEPROM_ANTENNA_STRUC	Antenna;
-	EEPROM_NIC_CONFIG2_STRUC    NicConfig2;
-	UCHAR	BBPR3 = 0;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitAsicFromEEPROM\n"));
-	for(i = 3; i < NUM_EEPROM_BBP_PARMS; i++)
-	{
-		UCHAR BbpRegIdx, BbpValue;
-
-		if ((pAd->EEPROMDefaultValue[i] != 0xFFFF) && (pAd->EEPROMDefaultValue[i] != 0))
-		{
-			BbpRegIdx = (UCHAR)(pAd->EEPROMDefaultValue[i] >> 8);
-			BbpValue  = (UCHAR)(pAd->EEPROMDefaultValue[i] & 0xff);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BbpRegIdx, BbpValue);
-		}
-	}
-
-
-	NicConfig2.word = pAd->EEPROMDefaultValue[1];
-
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		if ((NicConfig2.word & 0x00ff) == 0xff)
-		{
-			NicConfig2.word &= 0xff00;
-		}
-
-		if ((NicConfig2.word >> 8) == 0xff)
-		{
-			NicConfig2.word &= 0x00ff;
-		}
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	// Save the antenna for future use
-	pAd->NicConfig2.word = NicConfig2.word;
-
-#ifdef RT30xx
-	// set default antenna as main
-	if (pAd->RfIcType == RFIC_3020)
-		AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
-#endif // RT30xx //
-
-	//
-	// Send LED Setting to MCU.
-	//
-	if (pAd->LedCntl.word == 0xFF)
-	{
-		pAd->LedCntl.word = 0x01;
-		pAd->Led1 = 0x5555;
-		pAd->Led2 = 0x2221;
-
-#ifdef RTMP_MAC_PCI
-		pAd->Led3 = 0xA9F8;
-#endif // RTMP_MAC_PCI //
-	}
-
-	AsicSendCommandToMcu(pAd, 0x52, 0xff, (UCHAR)pAd->Led1, (UCHAR)(pAd->Led1 >> 8));
-	AsicSendCommandToMcu(pAd, 0x53, 0xff, (UCHAR)pAd->Led2, (UCHAR)(pAd->Led2 >> 8));
-	AsicSendCommandToMcu(pAd, 0x54, 0xff, (UCHAR)pAd->Led3, (UCHAR)(pAd->Led3 >> 8));
-	AsicSendCommandToMcu(pAd, 0x51, 0xff, 0, pAd->LedCntl.field.Polarity);
-
-	pAd->LedIndicatorStrength = 0xFF;
-	RTMPSetSignalLED(pAd, -100);	// Force signal strength Led to be turned off, before link up
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		// Read Hardware controlled Radio state enable bit
-		if (NicConfig2.field.HardwareRadioControl == 1)
-		{
-			pAd->StaCfg.bHardwareRadio = TRUE;
-
-			// Read GPIO pin2 as Hardware controlled radio state
-			RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
-			if ((data & 0x04) == 0)
-			{
-				pAd->StaCfg.bHwRadio = FALSE;
-				pAd->StaCfg.bRadio = FALSE;
-//				RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818);
-				RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-			}
-		}
-		else
-			pAd->StaCfg.bHardwareRadio = FALSE;
-
-		if (pAd->StaCfg.bRadio == FALSE)
-		{
-			RTMPSetLED(pAd, LED_RADIO_OFF);
-		}
-		else
-		{
-			RTMPSetLED(pAd, LED_RADIO_ON);
-#ifdef RTMP_MAC_PCI
-#ifdef RT3090
-			AsicSendCommandToMcu(pAd, 0x30, PowerRadioOffCID, 0xff, 0x02);
-			AsicCheckCommanOk(pAd, PowerRadioOffCID);
-#endif // RT3090 //
-#ifndef RT3090
-			AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
-#endif // RT3090 //
-			AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x00);
-			// 2-1. wait command ok.
-			AsicCheckCommanOk(pAd, PowerWakeCID);
-#endif // RTMP_MAC_PCI //
-		}
-	}
-#ifdef RTMP_MAC_PCI
-#ifdef RT30xx
-		if (IS_RT3090(pAd)|| IS_RT3572(pAd) || IS_RT3390(pAd))
-		{
-			RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
-			if (pChipOps->AsicReverseRfFromSleepMode)
-				pChipOps->AsicReverseRfFromSleepMode(pAd);
-		}
-		// 3090 MCU Wakeup command needs more time to be stable.
-		// Before stable, don't issue other MCU command to prevent from firmware error.
-
-		if ((IS_RT3090(pAd)|| IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)
-			&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
-			&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))
-		{
-			DBGPRINT(RT_DEBUG_TRACE,("%s::%d,release Mcu Lock\n",__FUNCTION__,__LINE__));
-			RTMP_SEM_LOCK(&pAd->McuCmdLock);
-			pAd->brt30xxBanMcuCmd = FALSE;
-			RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
-		}
-#endif // RT30xx //
-#endif // RTMP_MAC_PCI //
-#endif // CONFIG_STA_SUPPORT //
-
-	// Turn off patching for cardbus controller
-	if (NicConfig2.field.CardbusAcceleration == 1)
-	{
-//		pAd->bTest1 = TRUE;
-	}
-
-	if (NicConfig2.field.DynamicTxAgcControl == 1)
-		pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
-	else
-		pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
-	//
-	// Since BBP has been progamed, to make sure BBP setting will be
-	// upate inside of AsicAntennaSelect, so reset to UNKNOWN_BAND!!
-	//
-	pAd->CommonCfg.BandState = UNKNOWN_BAND;
-
-	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
-	BBPR3 &= (~0x18);
-	if(pAd->Antenna.field.RxPath == 3)
-	{
-		BBPR3 |= (0x10);
-	}
-	else if(pAd->Antenna.field.RxPath == 2)
-	{
-		BBPR3 |= (0x8);
-	}
-	else if(pAd->Antenna.field.RxPath == 1)
-	{
-		BBPR3 |= (0x0);
-	}
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		// Handle the difference when 1T
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BBPR1);
-		if(pAd->Antenna.field.TxPath == 1)
-		{
-		BBPR1 &= (~0x18);
-		}
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BBPR1);
-
-		DBGPRINT(RT_DEBUG_TRACE, ("Use Hw Radio Control Pin=%d; if used Pin=%d;\n",
-					pAd->CommonCfg.bHardwareRadio, pAd->CommonCfg.bHardwareRadio));
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-
-	DBGPRINT(RT_DEBUG_TRACE, ("TxPath = %d, RxPath = %d, RFIC=%d, Polar+LED mode=%x\n",
-				pAd->Antenna.field.TxPath, pAd->Antenna.field.RxPath,
-				pAd->RfIcType, pAd->LedCntl.word));
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitAsicFromEEPROM\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Initialize NIC hardware
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-NDIS_STATUS	NICInitializeAdapter(
-	IN	PRTMP_ADAPTER	pAd,
-	IN   BOOLEAN    bHardReset)
-{
-	NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;
-	WPDMA_GLO_CFG_STRUC	GloCfg;
-#ifdef RTMP_MAC_PCI
-	UINT32			Value;
-	DELAY_INT_CFG_STRUC	IntCfg;
-#endif // RTMP_MAC_PCI //
-//	INT_MASK_CSR_STRUC		IntMask;
-	ULONG	i =0, j=0;
-	AC_TXOP_CSR0_STRUC	csr0;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAdapter\n"));
-
-	// 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits:
-retry:
-	i = 0;
-	do
-	{
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-		if ((GloCfg.field.TxDMABusy == 0)  && (GloCfg.field.RxDMABusy == 0))
-			break;
-
-		RTMPusecDelay(1000);
-		i++;
-	}while ( i<100);
-	DBGPRINT(RT_DEBUG_TRACE, ("<== DMA offset 0x208 = 0x%x\n", GloCfg.word));
-	GloCfg.word &= 0xff0;
-	GloCfg.field.EnTXWriteBackDDONE =1;
-	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
-
-	// Record HW Beacon offset
-	pAd->BeaconOffset[0] = HW_BEACON_BASE0;
-	pAd->BeaconOffset[1] = HW_BEACON_BASE1;
-	pAd->BeaconOffset[2] = HW_BEACON_BASE2;
-	pAd->BeaconOffset[3] = HW_BEACON_BASE3;
-	pAd->BeaconOffset[4] = HW_BEACON_BASE4;
-	pAd->BeaconOffset[5] = HW_BEACON_BASE5;
-	pAd->BeaconOffset[6] = HW_BEACON_BASE6;
-	pAd->BeaconOffset[7] = HW_BEACON_BASE7;
-
-	//
-	// write all shared Ring's base address into ASIC
-	//
-
-	// asic simulation sequence put this ahead before loading firmware.
-	// pbf hardware reset
-#ifdef RTMP_MAC_PCI
-	RTMP_IO_WRITE32(pAd, WPDMA_RST_IDX, 0x1003f);	// 0x10000 for reset rx, 0x3f resets all 6 tx rings.
-	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe1f);
-	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe00);
-#endif // RTMP_MAC_PCI //
-
-	// Initialze ASIC for TX & Rx operation
-	if (NICInitializeAsic(pAd , bHardReset) != NDIS_STATUS_SUCCESS)
-	{
-		if (j++ == 0)
-		{
-			NICLoadFirmware(pAd);
-			goto retry;
-		}
-		return NDIS_STATUS_FAILURE;
-	}
-
-
-#ifdef RTMP_MAC_PCI
-	// Write AC_BK base address register
-	Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BK].Cell[0].AllocPa);
-	RTMP_IO_WRITE32(pAd, TX_BASE_PTR1, Value);
-	DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR1 : 0x%x\n", Value));
-
-	// Write AC_BE base address register
-	Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BE].Cell[0].AllocPa);
-	RTMP_IO_WRITE32(pAd, TX_BASE_PTR0, Value);
-	DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR0 : 0x%x\n", Value));
-
-	// Write AC_VI base address register
-	Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_VI].Cell[0].AllocPa);
-	RTMP_IO_WRITE32(pAd, TX_BASE_PTR2, Value);
-	DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR2 : 0x%x\n", Value));
-
-	// Write AC_VO base address register
-	Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_VO].Cell[0].AllocPa);
-	RTMP_IO_WRITE32(pAd, TX_BASE_PTR3, Value);
-	DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR3 : 0x%x\n", Value));
-
-	// Write HCCA base address register
-	/*
-	Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_HCCA].Cell[0].AllocPa);
-	RTMP_IO_WRITE32(pAd, TX_BASE_PTR4, Value);
-	DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR4 : 0x%x\n", Value));
-	*/
-
-	// Write MGMT_BASE_CSR register
-	Value = RTMP_GetPhysicalAddressLow(pAd->MgmtRing.Cell[0].AllocPa);
-	RTMP_IO_WRITE32(pAd, TX_BASE_PTR5, Value);
-	DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR5 : 0x%x\n", Value));
-
-	// Write RX_BASE_CSR register
-	Value = RTMP_GetPhysicalAddressLow(pAd->RxRing.Cell[0].AllocPa);
-	RTMP_IO_WRITE32(pAd, RX_BASE_PTR, Value);
-	DBGPRINT(RT_DEBUG_TRACE, ("--> RX_BASE_PTR : 0x%x\n", Value));
-
-	// Init RX Ring index pointer
-	pAd->RxRing.RxSwReadIdx = 0;
-	pAd->RxRing.RxCpuIdx = RX_RING_SIZE-1;
-	RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
-
-	// Init TX rings index pointer
-	{
-		for (i=0; i<NUM_OF_TX_RING; i++)
-		{
-			pAd->TxRing[i].TxSwFreeIdx = 0;
-			pAd->TxRing[i].TxCpuIdx = 0;
-			RTMP_IO_WRITE32(pAd, (TX_CTX_IDX0 + i * 0x10) ,  pAd->TxRing[i].TxCpuIdx);
-		}
-	}
-
-	// init MGMT ring index pointer
-	pAd->MgmtRing.TxSwFreeIdx = 0;
-	pAd->MgmtRing.TxCpuIdx = 0;
-	RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX,  pAd->MgmtRing.TxCpuIdx);
-
-	//
-	// set each Ring's SIZE  into ASIC. Descriptor Size is fixed by design.
-	//
-
-	// Write TX_RING_CSR0 register
-	Value = TX_RING_SIZE;
-	RTMP_IO_WRITE32(pAd, TX_MAX_CNT0, Value);
-	RTMP_IO_WRITE32(pAd, TX_MAX_CNT1, Value);
-	RTMP_IO_WRITE32(pAd, TX_MAX_CNT2, Value);
-	RTMP_IO_WRITE32(pAd, TX_MAX_CNT3, Value);
-	RTMP_IO_WRITE32(pAd, TX_MAX_CNT4, Value);
-	Value = MGMT_RING_SIZE;
-	RTMP_IO_WRITE32(pAd, TX_MGMTMAX_CNT, Value);
-
-	// Write RX_RING_CSR register
-	Value = RX_RING_SIZE;
-	RTMP_IO_WRITE32(pAd, RX_MAX_CNT, Value);
-#endif // RTMP_MAC_PCI //
-
-
-	// WMM parameter
-	csr0.word = 0;
-	RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
-	if (pAd->CommonCfg.PhyMode == PHY_11B)
-	{
-		csr0.field.Ac0Txop = 192;	// AC_VI: 192*32us ~= 6ms
-		csr0.field.Ac1Txop = 96;	// AC_VO: 96*32us  ~= 3ms
-	}
-	else
-	{
-		csr0.field.Ac0Txop = 96;	// AC_VI: 96*32us ~= 3ms
-		csr0.field.Ac1Txop = 48;	// AC_VO: 48*32us ~= 1.5ms
-	}
-	RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr0.word);
-
-
-#ifdef RTMP_MAC_PCI
-	// 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits:
-	i = 0;
-	do
-	{
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-		if ((GloCfg.field.TxDMABusy == 0)  && (GloCfg.field.RxDMABusy == 0))
-			break;
-
-		RTMPusecDelay(1000);
-		i++;
-	}while ( i < 100);
-
-	GloCfg.word &= 0xff0;
-	GloCfg.field.EnTXWriteBackDDONE =1;
-	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
-
-	IntCfg.word = 0;
-	RTMP_IO_WRITE32(pAd, DELAY_INT_CFG, IntCfg.word);
-#endif // RTMP_MAC_PCI //
-
-
-	// reset action
-	// Load firmware
-	//  Status = NICLoadFirmware(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAdapter\n"));
-	return Status;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Initialize ASIC
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-NDIS_STATUS	NICInitializeAsic(
-	IN	PRTMP_ADAPTER	pAd,
-	IN  BOOLEAN		bHardReset)
-{
-	ULONG			Index = 0;
-	UCHAR			R0 = 0xff;
-	UINT32			MacCsr12 = 0, Counter = 0;
-#ifdef RT30xx
-	UCHAR			bbpreg=0;
-	UCHAR			RFValue=0;
-#endif // RT30xx //
-	USHORT			KeyIdx;
-	INT				i,apidx;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAsic\n"));
-
-#ifdef RTMP_MAC_PCI
-	RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x3);	// To fix driver disable/enable hang issue when radio off
-	if (bHardReset == TRUE)
-	{
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
-	}
-	else
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
-
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
-	// Initialize MAC register to default value
-	for (Index = 0; Index < NUM_MAC_REG_PARMS; Index++)
-	{
-#ifdef RT30xx
-		if ((MACRegTable[Index].Register == TX_SW_CFG0) && ( IS_RT3090(pAd) ||  IS_RT3390(pAd)))
-		{
-			MACRegTable[Index].Value = 0x00000400;
-		}
-#endif // RT30xx //
-		RTMP_IO_WRITE32(pAd, MACRegTable[Index].Register, MACRegTable[Index].Value);
-	}
-
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++)
-		{
-			RTMP_IO_WRITE32(pAd, STAMACRegTable[Index].Register, STAMACRegTable[Index].Value);
-		}
-	}
-#endif // CONFIG_STA_SUPPORT //
-#endif // RTMP_MAC_PCI //
-
-
-#ifdef RT30xx
-	// Initialize RT3070 serial MAC registers which is different from RT2870 serial
-	if (IS_RT3090(pAd) || IS_RT3572(pAd)||IS_RT3390(pAd))
-	{
-		RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
-
-		// RT3071 version E has fixed this issue
-		if ((pAd->MACVersion & 0xffff) < 0x0211)
-		{
-			if (pAd->NicConfig2.field.DACTestBit == 1)
-			{
-				RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x2C);	// To fix throughput drop drastically
-			}
-			else
-			{
-				RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0F);	// To fix throughput drop drastically
-			}
-		}
-		else
-		{
-			RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0);
-		}
-	}
-	else if (IS_RT3070(pAd))
-	{
-		if (((pAd->MACVersion & 0xffff) < 0x0201))
-		{
-			RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
-			RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x2C);	// To fix throughput drop drastically
-		}
-		else
-		{
-			RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0);
-		}
-	}
-#endif // RT30xx //
-
-	//
-	// Before program BBP, we need to wait BBP/RF get wake up.
-	//
-	Index = 0;
-	do
-	{
-		RTMP_IO_READ32(pAd, MAC_STATUS_CFG, &MacCsr12);
-
-		if ((MacCsr12 & 0x03) == 0)	// if BB.RF is stable
-			break;
-
-		DBGPRINT(RT_DEBUG_TRACE, ("Check MAC_STATUS_CFG  = Busy = %x\n", MacCsr12));
-		RTMPusecDelay(1000);
-	} while (Index++ < 100);
-
-	// The commands to firmware should be after these commands, these commands will init firmware
-	// PCI and USB are not the same because PCI driver needs to wait for PCI bus ready
-	RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, 0);	// initialize BBP R/W access agent
-	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, 0);
-#ifdef RT3090
-	//2008/11/28:KH add to fix the dead rf frequency offset bug<--
-	AsicSendCommandToMcu(pAd, 0x72, 0, 0, 0);
-	//2008/11/28:KH add to fix the dead rf frequency offset bug-->
-#endif // RT3090 //
-	RTMPusecDelay(1000);
-
-	// Read BBP register, make sure BBP is up and running before write new data
-	Index = 0;
-	do
-	{
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R0, &R0);
-		DBGPRINT(RT_DEBUG_TRACE, ("BBP version = %x\n", R0));
-	} while ((++Index < 20) && ((R0 == 0xff) || (R0 == 0x00)));
-	//ASSERT(Index < 20); //this will cause BSOD on Check-build driver
-
-	if ((R0 == 0xff) || (R0 == 0x00))
-		return NDIS_STATUS_FAILURE;
-
-	// Initialize BBP register to default value
-	for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++)
-	{
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, BBPRegTable[Index].Value);
-	}
-
-#ifdef RTMP_MAC_PCI
-	// TODO: shiang, check MACVersion, currently, rbus-based chip use this.
-	if (pAd->MACVersion == 0x28720200)
-	{
-		//UCHAR value;
-		ULONG value2;
-
-		//disable MLD by Bruce 20080704
-		//BBP_IO_READ8_BY_REG_ID(pAd, BBP_R105, &value);
-		//BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R105, value | 4);
-
-		//Maximum PSDU length from 16K to 32K bytes
-		RTMP_IO_READ32(pAd, MAX_LEN_CFG, &value2);
-		value2 &= ~(0x3<<12);
-		value2 |= (0x2<<12);
-		RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, value2);
-	}
-#endif // RTMP_MAC_PCI //
-
-	// for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT.
-	// RT3090 should not program BBP R84 to 0x19, otherwise TX will block.
-	//3070/71/72,3090,3090A( are included in RT30xx),3572,3390
-	if (((pAd->MACVersion & 0xffff) != 0x0101) && !(IS_RT30xx(pAd)|| IS_RT3572(pAd) || IS_RT3390(pAd)))
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19);
-
-#ifdef RT30xx
-// add by johnli, RF power sequence setup
-	if (IS_RT30xx(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
-	{	//update for RT3070/71/72/90/91/92,3572,3390.
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R79, 0x13);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R80, 0x05);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R81, 0x33);
-	}
-
-	if (IS_RT3090(pAd)||IS_RT3390(pAd))	// RT309x, RT3071/72
-	{
-		// enable DC filter
-		if ((pAd->MACVersion & 0xffff) >= 0x0211)
-		{
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0);
-		}
-
-		// improve power consumption
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R138, &bbpreg);
-		if (pAd->Antenna.field.TxPath == 1)
-		{
-			// turn off tx DAC_1
-			bbpreg = (bbpreg | 0x20);
-		}
-
-		if (pAd->Antenna.field.RxPath == 1)
-		{
-			// turn off tx ADC_1
-			bbpreg &= (~0x2);
-		}
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R138, bbpreg);
-
-		// improve power consumption in RT3071 Ver.E
-		if ((pAd->MACVersion & 0xffff) >= 0x0211)
-		{
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg);
-			bbpreg &= (~0x3);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg);
-		}
-	}
-	else if (IS_RT3070(pAd))
-	{
-		if ((pAd->MACVersion & 0xffff) >= 0x0201)
-		{
-			// enable DC filter
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0);
-
-			// improve power consumption in RT3070 Ver.F
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg);
-			bbpreg &= (~0x3);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg);
-		}
-
-		// TX_LO1_en, RF R17 register Bit 3 to 0
-		RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
-		RFValue &= (~0x08);
-		// to fix rx long range issue
-		if (pAd->NicConfig2.field.ExternalLNAForG == 0)
-		{
-			RFValue |= 0x20;
-		}
-		// set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h
-		if (pAd->TxMixerGain24G >= 1)
-		{
-			RFValue &= (~0x7);  // clean bit [2:0]
-			RFValue |= pAd->TxMixerGain24G;
-		}
-		RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
-	}
-// end johnli
-#endif // RT30xx //
-
-	if (pAd->MACVersion == 0x28600100)
-	{
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x12);
-	}
-
-	if (pAd->MACVersion >= RALINK_2880E_VERSION && pAd->MACVersion < RALINK_3070_VERSION) // 3*3
-	{
-		// enlarge MAX_LEN_CFG
-		UINT32 csr;
-		RTMP_IO_READ32(pAd, MAX_LEN_CFG, &csr);
-		csr &= 0xFFF;
-		csr |= 0x2000;
-		RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, csr);
-	}
-
-
-#ifdef CONFIG_STA_SUPPORT
-	// Add radio off control
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		if (pAd->StaCfg.bRadio == FALSE)
-		{
-//			RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818);
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-			DBGPRINT(RT_DEBUG_TRACE, ("Set Radio Off\n"));
-		}
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	// Clear raw counters
-	RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter);
-	RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter);
-	RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter);
-	RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter);
-	RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter);
-	RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter);
-
-	// ASIC will keep garbage value after boot
-	// Clear all shared key table when initial
-	// This routine can be ignored in radio-ON/OFF operation.
-	if (bHardReset)
-	{
-		for (KeyIdx = 0; KeyIdx < 4; KeyIdx++)
-		{
-			RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4*KeyIdx, 0);
-		}
-
-		// Clear all pairwise key table when initial
-		for (KeyIdx = 0; KeyIdx < 256; KeyIdx++)
-		{
-			RTMP_IO_WRITE32(pAd, MAC_WCID_ATTRIBUTE_BASE + (KeyIdx * HW_WCID_ATTRI_SIZE), 1);
-		}
-	}
-
-	// assert HOST ready bit
-//  RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x0); // 2004-09-14 asked by Mark
-//  RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x4);
-
-	// It isn't necessary to clear this space when not hard reset.
-	if (bHardReset == TRUE)
-	{
-		// clear all on-chip BEACON frame space
-		for (apidx = 0; apidx < HW_BEACON_MAX_COUNT; apidx++)
-		{
-			for (i = 0; i < HW_BEACON_OFFSET>>2; i+=4)
-				RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[apidx] + i, 0x00);
-		}
-	}
-
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		// for rt2860E and after, init TXOP_CTRL_CFG with 0x583f. This is for extension channel overlapping IOT.
-		if ((pAd->MACVersion&0xffff) != 0x0101)
-			RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x583f);
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef RT30xx
-#ifdef NEW_FW
-	if (IS_RT3070(pAd) ||  IS_RT3572(pAd)||IS_RT3390(pAd)||IS_RT3090(pAd))
-	{
-		// send 0x36 mcu command after 0x72 for RT3xxx to fix Radio-Off current leakage issue
-		RTMPusecDelay(200);
-		if (pAd->buseEfuse)
-			AsicSendCommandToMcu(pAd, 0x36, 0xff, 0xff, 0);
-		else
-			AsicSendCommandToMcu(pAd, 0x36, 0xff, 0xff, 0x04);
-		RTMPusecDelay(10);
-	}
-#endif // NEW_FW //
-#endif // RT30xx //
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAsic\n"));
-	return NDIS_STATUS_SUCCESS;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Reset NIC Asics
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-		Reset NIC to initial state AS IS system boot up time.
-
-	========================================================================
-*/
-VOID	NICIssueReset(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	UINT32	Value = 0;
-	DBGPRINT(RT_DEBUG_TRACE, ("--> NICIssueReset\n"));
-
-	// Abort Tx, prevent ASIC from writing to Host memory
-	//RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x001f0000);
-
-	// Disable Rx, register value supposed will remain after reset
-	RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
-	Value &= (0xfffffff3);
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-
-	// Issue reset and clear from reset state
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x03); // 2004-09-17 change from 0x01
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x00);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICIssueReset\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Check ASIC registers and find any reason the system might hang
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-BOOLEAN	NICCheckForHang(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	return (FALSE);
-}
-
-VOID NICUpdateFifoStaCounters(
-	IN PRTMP_ADAPTER pAd)
-{
-	TX_STA_FIFO_STRUC	StaFifo;
-	MAC_TABLE_ENTRY		*pEntry;
-	UCHAR				i = 0;
-	UCHAR			pid = 0, wcid = 0;
-	CHAR				reTry;
-	UCHAR				succMCS;
-
-#ifdef RALINK_ATE
-	/* Nothing to do in ATE mode */
-	if (ATE_ON(pAd))
-		return;
-#endif // RALINK_ATE //
-
-		do
-		{
-			RTMP_IO_READ32(pAd, TX_STA_FIFO, &StaFifo.word);
-
-			if (StaFifo.field.bValid == 0)
-				break;
-
-			wcid = (UCHAR)StaFifo.field.wcid;
-
-
-		/* ignore NoACK and MGMT frame use 0xFF as WCID */
-			if ((StaFifo.field.TxAckRequired == 0) || (wcid >= MAX_LEN_OF_MAC_TABLE))
-			{
-				i++;
-				continue;
-			}
-
-			/* PID store Tx MCS Rate */
-			pid = (UCHAR)StaFifo.field.PidType;
-
-			pEntry = &pAd->MacTab.Content[wcid];
-
-			pEntry->DebugFIFOCount++;
-
-#ifdef DOT11_N_SUPPORT
-			if (StaFifo.field.TxBF) // 3*3
-				pEntry->TxBFCount++;
-#endif // DOT11_N_SUPPORT //
-
-#ifdef UAPSD_AP_SUPPORT
-			UAPSD_SP_AUE_Handle(pAd, pEntry, StaFifo.field.TxSuccess);
-#endif // UAPSD_AP_SUPPORT //
-
-			if (!StaFifo.field.TxSuccess)
-			{
-				pEntry->FIFOCount++;
-				pEntry->OneSecTxFailCount++;
-
-				if (pEntry->FIFOCount >= 1)
-				{
-					DBGPRINT(RT_DEBUG_TRACE, ("#"));
-#ifdef DOT11_N_SUPPORT
-					pEntry->NoBADataCountDown = 64;
-#endif // DOT11_N_SUPPORT //
-
-					if(pEntry->PsMode == PWR_ACTIVE)
-					{
-#ifdef DOT11_N_SUPPORT
-						int tid;
-						for (tid=0; tid<NUM_OF_TID; tid++)
-						{
-							BAOriSessionTearDown(pAd, pEntry->Aid,  tid, FALSE, FALSE);
-						}
-#endif // DOT11_N_SUPPORT //
-
-						// Update the continuous transmission counter except PS mode
-						pEntry->ContinueTxFailCnt++;
-
-#ifdef WDS_SUPPORT
-						// fix WDS Jam issue
-						if((pEntry->ValidAsWDS == TRUE)
-							&& (pEntry->LockEntryTx == FALSE)
-							&& (pEntry->ContinueTxFailCnt >= pAd->ApCfg.EntryLifeCheck))
-						{
-							DBGPRINT(RT_DEBUG_TRACE, ("Entry %02x:%02x:%02x:%02x:%02x:%02x Blocked!! (Fail Cnt = %d)\n",
-								pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2],pEntry->Addr[3],
-								pEntry->Addr[4],pEntry->Addr[5],pEntry->ContinueTxFailCnt ));
-
-							pEntry->LockEntryTx = TRUE;
-						}
-#endif // WDS_SUPPORT //
-					}
-					else
-					{
-						// Clear the FIFOCount when sta in Power Save mode. Basically we assume
-						//     this tx error happened due to sta just go to sleep.
-						pEntry->FIFOCount = 0;
-						pEntry->ContinueTxFailCnt = 0;
-					}
-					//pEntry->FIFOCount = 0;
-				}
-				//pEntry->bSendBAR = TRUE;
-			}
-			else
-			{
-#ifdef DOT11_N_SUPPORT
-				if ((pEntry->PsMode != PWR_SAVE) && (pEntry->NoBADataCountDown > 0))
-				{
-					pEntry->NoBADataCountDown--;
-					if (pEntry->NoBADataCountDown==0)
-					{
-						DBGPRINT(RT_DEBUG_TRACE, ("@\n"));
-					}
-				}
-#endif // DOT11_N_SUPPORT //
-				pEntry->FIFOCount = 0;
-				pEntry->OneSecTxNoRetryOkCount++;
-				// update NoDataIdleCount when sucessful send packet to STA.
-				pEntry->NoDataIdleCount = 0;
-				pEntry->ContinueTxFailCnt = 0;
-#ifdef WDS_SUPPORT
-				pEntry->LockEntryTx = FALSE;
-#endif // WDS_SUPPORT //
-			}
-
-			succMCS = StaFifo.field.SuccessRate & 0x7F;
-
-			reTry = pid - succMCS;
-
-			if (StaFifo.field.TxSuccess)
-			{
-				pEntry->TXMCSExpected[pid]++;
-				if (pid == succMCS)
-				{
-					pEntry->TXMCSSuccessful[pid]++;
-				}
-				else
-				{
-					pEntry->TXMCSAutoFallBack[pid][succMCS]++;
-				}
-			}
-			else
-			{
-				pEntry->TXMCSFailed[pid]++;
-			}
-
-			if (reTry > 0)
-			{
-				if ((pid >= 12) && succMCS <=7)
-				{
-					reTry -= 4;
-				}
-				pEntry->OneSecTxRetryOkCount += reTry;
-			}
-
-			i++;
-			// ASIC store 16 stack
-		} while ( i < (TX_RING_SIZE<<1) );
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Read statistical counters from hardware registers and record them
-		in software variables for later on query
-
-	Arguments:
-		pAd					Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-VOID NICUpdateRawCounters(
-	IN PRTMP_ADAPTER pAd)
-{
-	UINT32	OldValue;//, Value2;
-	//ULONG	PageSum, OneSecTransmitCount;
-	//ULONG	TxErrorRatio, Retry, Fail;
-	RX_STA_CNT0_STRUC	 RxStaCnt0;
-	RX_STA_CNT1_STRUC   RxStaCnt1;
-	RX_STA_CNT2_STRUC   RxStaCnt2;
-	TX_STA_CNT0_STRUC	 TxStaCnt0;
-	TX_STA_CNT1_STRUC	 StaTx1;
-	TX_STA_CNT2_STRUC	 StaTx2;
-	TX_AGG_CNT_STRUC	TxAggCnt;
-	TX_AGG_CNT0_STRUC	TxAggCnt0;
-	TX_AGG_CNT1_STRUC	TxAggCnt1;
-	TX_AGG_CNT2_STRUC	TxAggCnt2;
-	TX_AGG_CNT3_STRUC	TxAggCnt3;
-	TX_AGG_CNT4_STRUC	TxAggCnt4;
-	TX_AGG_CNT5_STRUC	TxAggCnt5;
-	TX_AGG_CNT6_STRUC	TxAggCnt6;
-	TX_AGG_CNT7_STRUC	TxAggCnt7;
-	COUNTER_RALINK		*pRalinkCounters;
-
-
-	pRalinkCounters = &pAd->RalinkCounters;
-
-	RTMP_IO_READ32(pAd, RX_STA_CNT0, &RxStaCnt0.word);
-	RTMP_IO_READ32(pAd, RX_STA_CNT2, &RxStaCnt2.word);
-
-	{
-		RTMP_IO_READ32(pAd, RX_STA_CNT1, &RxStaCnt1.word);
-	    // Update RX PLCP error counter
-	    pAd->PrivateInfo.PhyRxErrCnt += RxStaCnt1.field.PlcpErr;
-		// Update False CCA counter
-		pAd->RalinkCounters.OneSecFalseCCACnt += RxStaCnt1.field.FalseCca;
-	}
-
-	// Update FCS counters
-	OldValue= pAd->WlanCounters.FCSErrorCount.u.LowPart;
-	pAd->WlanCounters.FCSErrorCount.u.LowPart += (RxStaCnt0.field.CrcErr); // >> 7);
-	if (pAd->WlanCounters.FCSErrorCount.u.LowPart < OldValue)
-		pAd->WlanCounters.FCSErrorCount.u.HighPart++;
-
-	// Add FCS error count to private counters
-	pRalinkCounters->OneSecRxFcsErrCnt += RxStaCnt0.field.CrcErr;
-	OldValue = pRalinkCounters->RealFcsErrCount.u.LowPart;
-	pRalinkCounters->RealFcsErrCount.u.LowPart += RxStaCnt0.field.CrcErr;
-	if (pRalinkCounters->RealFcsErrCount.u.LowPart < OldValue)
-		pRalinkCounters->RealFcsErrCount.u.HighPart++;
-
-	// Update Duplicate Rcv check
-	pRalinkCounters->DuplicateRcv += RxStaCnt2.field.RxDupliCount;
-	pAd->WlanCounters.FrameDuplicateCount.u.LowPart += RxStaCnt2.field.RxDupliCount;
-	// Update RX Overflow counter
-	pAd->Counters8023.RxNoBuffer += (RxStaCnt2.field.RxFifoOverflowCount);
-
-	//pAd->RalinkCounters.RxCount = 0;
-
-
-	//if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) ||
-	//	(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) && (pAd->MacTab.Size != 1)))
-	if (!pAd->bUpdateBcnCntDone)
-	{
-	// Update BEACON sent count
-	RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
-	RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
-	RTMP_IO_READ32(pAd, TX_STA_CNT2, &StaTx2.word);
-	pRalinkCounters->OneSecBeaconSentCnt += TxStaCnt0.field.TxBeaconCount;
-	pRalinkCounters->OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
-	pRalinkCounters->OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
-	pRalinkCounters->OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
-	pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
-	pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
-	pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
-	}
-
-
-	//if (pAd->bStaFifoTest == TRUE)
-	{
-		RTMP_IO_READ32(pAd, TX_AGG_CNT, &TxAggCnt.word);
-	RTMP_IO_READ32(pAd, TX_AGG_CNT0, &TxAggCnt0.word);
-	RTMP_IO_READ32(pAd, TX_AGG_CNT1, &TxAggCnt1.word);
-	RTMP_IO_READ32(pAd, TX_AGG_CNT2, &TxAggCnt2.word);
-	RTMP_IO_READ32(pAd, TX_AGG_CNT3, &TxAggCnt3.word);
-		RTMP_IO_READ32(pAd, TX_AGG_CNT4, &TxAggCnt4.word);
-		RTMP_IO_READ32(pAd, TX_AGG_CNT5, &TxAggCnt5.word);
-		RTMP_IO_READ32(pAd, TX_AGG_CNT6, &TxAggCnt6.word);
-		RTMP_IO_READ32(pAd, TX_AGG_CNT7, &TxAggCnt7.word);
-		pRalinkCounters->TxAggCount += TxAggCnt.field.AggTxCount;
-		pRalinkCounters->TxNonAggCount += TxAggCnt.field.NonAggTxCount;
-		pRalinkCounters->TxAgg1MPDUCount += TxAggCnt0.field.AggSize1Count;
-		pRalinkCounters->TxAgg2MPDUCount += TxAggCnt0.field.AggSize2Count;
-
-		pRalinkCounters->TxAgg3MPDUCount += TxAggCnt1.field.AggSize3Count;
-		pRalinkCounters->TxAgg4MPDUCount += TxAggCnt1.field.AggSize4Count;
-		pRalinkCounters->TxAgg5MPDUCount += TxAggCnt2.field.AggSize5Count;
-		pRalinkCounters->TxAgg6MPDUCount += TxAggCnt2.field.AggSize6Count;
-
-		pRalinkCounters->TxAgg7MPDUCount += TxAggCnt3.field.AggSize7Count;
-		pRalinkCounters->TxAgg8MPDUCount += TxAggCnt3.field.AggSize8Count;
-		pRalinkCounters->TxAgg9MPDUCount += TxAggCnt4.field.AggSize9Count;
-		pRalinkCounters->TxAgg10MPDUCount += TxAggCnt4.field.AggSize10Count;
-
-		pRalinkCounters->TxAgg11MPDUCount += TxAggCnt5.field.AggSize11Count;
-		pRalinkCounters->TxAgg12MPDUCount += TxAggCnt5.field.AggSize12Count;
-		pRalinkCounters->TxAgg13MPDUCount += TxAggCnt6.field.AggSize13Count;
-		pRalinkCounters->TxAgg14MPDUCount += TxAggCnt6.field.AggSize14Count;
-
-		pRalinkCounters->TxAgg15MPDUCount += TxAggCnt7.field.AggSize15Count;
-		pRalinkCounters->TxAgg16MPDUCount += TxAggCnt7.field.AggSize16Count;
-
-		// Calculate the transmitted A-MPDU count
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += TxAggCnt0.field.AggSize1Count;
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt0.field.AggSize2Count / 2);
-
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize3Count / 3);
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize4Count / 4);
-
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize5Count / 5);
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize6Count / 6);
-
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize7Count / 7);
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize8Count / 8);
-
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize9Count / 9);
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize10Count / 10);
-
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize11Count / 11);
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize12Count / 12);
-
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize13Count / 13);
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize14Count / 14);
-
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize15Count / 15);
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize16Count / 16);
-	}
-
-#ifdef DBG_DIAGNOSE
-	{
-		RtmpDiagStruct	*pDiag;
-		UCHAR			ArrayCurIdx, i;
-
-		pDiag = &pAd->DiagStruct;
-		ArrayCurIdx = pDiag->ArrayCurIdx;
-
-		if (pDiag->inited == 0)
-		{
-			NdisZeroMemory(pDiag, sizeof(struct _RtmpDiagStrcut_));
-			pDiag->ArrayStartIdx = pDiag->ArrayCurIdx = 0;
-			pDiag->inited = 1;
-		}
-		else
-		{
-			// Tx
-			pDiag->TxFailCnt[ArrayCurIdx] = TxStaCnt0.field.TxFailCount;
-			pDiag->TxAggCnt[ArrayCurIdx] = TxAggCnt.field.AggTxCount;
-			pDiag->TxNonAggCnt[ArrayCurIdx] = TxAggCnt.field.NonAggTxCount;
-			pDiag->TxAMPDUCnt[ArrayCurIdx][0] = TxAggCnt0.field.AggSize1Count;
-			pDiag->TxAMPDUCnt[ArrayCurIdx][1] = TxAggCnt0.field.AggSize2Count;
-			pDiag->TxAMPDUCnt[ArrayCurIdx][2] = TxAggCnt1.field.AggSize3Count;
-			pDiag->TxAMPDUCnt[ArrayCurIdx][3] = TxAggCnt1.field.AggSize4Count;
-			pDiag->TxAMPDUCnt[ArrayCurIdx][4] = TxAggCnt2.field.AggSize5Count;
-			pDiag->TxAMPDUCnt[ArrayCurIdx][5] = TxAggCnt2.field.AggSize6Count;
-			pDiag->TxAMPDUCnt[ArrayCurIdx][6] = TxAggCnt3.field.AggSize7Count;
-			pDiag->TxAMPDUCnt[ArrayCurIdx][7] = TxAggCnt3.field.AggSize8Count;
-			pDiag->TxAMPDUCnt[ArrayCurIdx][8] = TxAggCnt4.field.AggSize9Count;
-			pDiag->TxAMPDUCnt[ArrayCurIdx][9] = TxAggCnt4.field.AggSize10Count;
-			pDiag->TxAMPDUCnt[ArrayCurIdx][10] = TxAggCnt5.field.AggSize11Count;
-			pDiag->TxAMPDUCnt[ArrayCurIdx][11] = TxAggCnt5.field.AggSize12Count;
-			pDiag->TxAMPDUCnt[ArrayCurIdx][12] = TxAggCnt6.field.AggSize13Count;
-			pDiag->TxAMPDUCnt[ArrayCurIdx][13] = TxAggCnt6.field.AggSize14Count;
-			pDiag->TxAMPDUCnt[ArrayCurIdx][14] = TxAggCnt7.field.AggSize15Count;
-			pDiag->TxAMPDUCnt[ArrayCurIdx][15] = TxAggCnt7.field.AggSize16Count;
-
-			pDiag->RxCrcErrCnt[ArrayCurIdx] = RxStaCnt0.field.CrcErr;
-
-			INC_RING_INDEX(pDiag->ArrayCurIdx,  DIAGNOSE_TIME);
-			ArrayCurIdx = pDiag->ArrayCurIdx;
-			for (i =0; i < 9; i++)
-			{
-				pDiag->TxDescCnt[ArrayCurIdx][i]= 0;
-				pDiag->TxSWQueCnt[ArrayCurIdx][i] =0;
-				pDiag->TxMcsCnt[ArrayCurIdx][i] = 0;
-				pDiag->RxMcsCnt[ArrayCurIdx][i] = 0;
-			}
-			pDiag->TxDataCnt[ArrayCurIdx] = 0;
-			pDiag->TxFailCnt[ArrayCurIdx] = 0;
-			pDiag->RxDataCnt[ArrayCurIdx] = 0;
-			pDiag->RxCrcErrCnt[ArrayCurIdx]  = 0;
-//			for (i = 9; i < 16; i++)
-			for (i = 9; i < 24; i++) // 3*3
-			{
-				pDiag->TxDescCnt[ArrayCurIdx][i] = 0;
-				pDiag->TxMcsCnt[ArrayCurIdx][i] = 0;
-				pDiag->RxMcsCnt[ArrayCurIdx][i] = 0;
-}
-
-			if (pDiag->ArrayCurIdx == pDiag->ArrayStartIdx)
-				INC_RING_INDEX(pDiag->ArrayStartIdx,  DIAGNOSE_TIME);
-		}
-
-	}
-#endif // DBG_DIAGNOSE //
-
-
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Reset NIC from error
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-		Reset NIC from error state
-
-	========================================================================
-*/
-VOID	NICResetFromError(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	// Reset BBP (according to alex, reset ASIC will force reset BBP
-	// Therefore, skip the reset BBP
-	// RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x2);
-
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
-	// Remove ASIC from reset state
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
-
-	NICInitializeAdapter(pAd, FALSE);
-	NICInitAsicFromEEPROM(pAd);
-
-	// Switch to current channel, since during reset process, the connection should remains on.
-	AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
-	AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
-}
-
-
-NDIS_STATUS NICLoadFirmware(
-	IN PRTMP_ADAPTER pAd)
-{
-	NDIS_STATUS	 status = NDIS_STATUS_SUCCESS;
-	if (pAd->chipOps.loadFirmware)
-		status = pAd->chipOps.loadFirmware(pAd);
-
-	return status;
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		erase 8051 firmware image in MAC ASIC
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	IRQL = PASSIVE_LEVEL
-
-	========================================================================
-*/
-VOID NICEraseFirmware(
-	IN PRTMP_ADAPTER pAd)
-{
-	if (pAd->chipOps.eraseFirmware)
-		pAd->chipOps.eraseFirmware(pAd);
-
-}/* End of NICEraseFirmware */
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Load Tx rate switching parameters
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		NDIS_STATUS_SUCCESS         firmware image load ok
-		NDIS_STATUS_FAILURE         image not found
-
-	IRQL = PASSIVE_LEVEL
-
-	Rate Table Format:
-		1. (B0: Valid Item number) (B1:Initial item from zero)
-		2. Item Number(Dec)      Mode(Hex)     Current MCS(Dec)    TrainUp(Dec)    TrainDown(Dec)
-
-	========================================================================
-*/
-NDIS_STATUS NICLoadRateSwitchingParams(
-	IN PRTMP_ADAPTER pAd)
-{
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Compare two memory block
-
-	Arguments:
-		pSrc1		Pointer to first memory address
-		pSrc2		Pointer to second memory address
-
-	Return Value:
-		0:			memory is equal
-		1:			pSrc1 memory is larger
-		2:			pSrc2 memory is larger
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-ULONG	RTMPCompareMemory(
-	IN	PVOID	pSrc1,
-	IN	PVOID	pSrc2,
-	IN	ULONG	Length)
-{
-	PUCHAR	pMem1;
-	PUCHAR	pMem2;
-	ULONG	Index = 0;
-
-	pMem1 = (PUCHAR) pSrc1;
-	pMem2 = (PUCHAR) pSrc2;
-
-	for (Index = 0; Index < Length; Index++)
-	{
-		if (pMem1[Index] > pMem2[Index])
-			return (1);
-		else if (pMem1[Index] < pMem2[Index])
-			return (2);
-	}
-
-	// Equal
-	return (0);
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Zero out memory block
-
-	Arguments:
-		pSrc1		Pointer to memory address
-		Length		Size
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPZeroMemory(
-	IN	PVOID	pSrc,
-	IN	ULONG	Length)
-{
-	PUCHAR	pMem;
-	ULONG	Index = 0;
-
-	pMem = (PUCHAR) pSrc;
-
-	for (Index = 0; Index < Length; Index++)
-	{
-		pMem[Index] = 0x00;
-	}
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Copy data from memory block 1 to memory block 2
-
-	Arguments:
-		pDest		Pointer to destination memory address
-		pSrc		Pointer to source memory address
-		Length		Copy size
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID RTMPMoveMemory(
-	OUT	PVOID	pDest,
-	IN	PVOID	pSrc,
-	IN	ULONG	Length)
-{
-	PUCHAR	pMem1;
-	PUCHAR	pMem2;
-	UINT	Index;
-
-	ASSERT((Length==0) || (pDest && pSrc));
-
-	pMem1 = (PUCHAR) pDest;
-	pMem2 = (PUCHAR) pSrc;
-
-	for (Index = 0; Index < Length; Index++)
-	{
-		pMem1[Index] = pMem2[Index];
-	}
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Initialize port configuration structure
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	UserCfgInit(
-	IN	PRTMP_ADAPTER pAd)
-{
-//	EDCA_PARM DefaultEdcaParm;
-    UINT key_index, bss_index;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit\n"));
-
-	//
-	//  part I. intialize common configuration
-	//
-
-	for(key_index=0; key_index<SHARE_KEY_NUM; key_index++)
-	{
-		for(bss_index = 0; bss_index < MAX_MBSSID_NUM; bss_index++)
-		{
-			pAd->SharedKey[bss_index][key_index].KeyLen = 0;
-			pAd->SharedKey[bss_index][key_index].CipherAlg = CIPHER_NONE;
-		}
-	}
-
-	pAd->EepromAccess = FALSE;
-
-	pAd->Antenna.word = 0;
-	pAd->CommonCfg.BBPCurrentBW = BW_20;
-
-	pAd->LedCntl.word = 0;
-#ifdef RTMP_MAC_PCI
-	pAd->LedIndicatorStrength = 0;
-	pAd->RLnkCtrlOffset = 0;
-	pAd->HostLnkCtrlOffset = 0;
-#ifdef CONFIG_STA_SUPPORT
-	pAd->StaCfg.PSControl.field.EnableNewPS=TRUE;
-	pAd->CheckDmaBusyCount = 0;
-#endif // CONFIG_STA_SUPPORT //
-#endif // RTMP_MAC_PCI //
-
-	pAd->bAutoTxAgcA = FALSE;			// Default is OFF
-	pAd->bAutoTxAgcG = FALSE;			// Default is OFF
-	pAd->RfIcType = RFIC_2820;
-
-	// Init timer for reset complete event
-	pAd->CommonCfg.CentralChannel = 1;
-	pAd->bForcePrintTX = FALSE;
-	pAd->bForcePrintRX = FALSE;
-	pAd->bStaFifoTest = FALSE;
-	pAd->bProtectionTest = FALSE;
-	/*
-	pAd->bHCCATest = FALSE;
-	pAd->bGenOneHCCA = FALSE;
-	*/
-	pAd->CommonCfg.Dsifs = 10;      // in units of usec
-	pAd->CommonCfg.TxPower = 100; //mW
-	pAd->CommonCfg.TxPowerPercentage = 0xffffffff; // AUTO
-	pAd->CommonCfg.TxPowerDefault = 0xffffffff; // AUTO
-	pAd->CommonCfg.TxPreamble = Rt802_11PreambleAuto; // use Long preamble on TX by defaut
-	pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
-	pAd->CommonCfg.RtsThreshold = 2347;
-	pAd->CommonCfg.FragmentThreshold = 2346;
-	pAd->CommonCfg.UseBGProtection = 0;    // 0: AUTO
-	pAd->CommonCfg.bEnableTxBurst = TRUE; //0;
-	pAd->CommonCfg.PhyMode = 0xff;     // unknown
-	pAd->CommonCfg.BandState = UNKNOWN_BAND;
-	pAd->CommonCfg.RadarDetect.CSPeriod = 10;
-	pAd->CommonCfg.RadarDetect.CSCount = 0;
-	pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
-
-
-
-#ifdef TONE_RADAR_DETECT_SUPPORT
-#ifdef CARRIER_DETECTION_SUPPORT
-	pAd->CommonCfg.CarrierDetect.delta = CARRIER_DETECT_DELTA;
-	pAd->CommonCfg.CarrierDetect.div_flag = CARRIER_DETECT_DIV_FLAG;
-	pAd->CommonCfg.CarrierDetect.criteria = CARRIER_DETECT_CRITIRIA;
-#ifdef RT3090
-	if(IS_RT3090A(pAd))
-	pAd->CommonCfg.CarrierDetect.threshold = CARRIER_DETECT_THRESHOLD_3090A;
-	else
-#endif // RT3090 //
-	pAd->CommonCfg.CarrierDetect.threshold = CARRIER_DETECT_THRESHOLD;
-#endif // CARRIER_DETECTION_SUPPORT //
-#endif // TONE_RADAR_DETECT_SUPPORT //
-
-	pAd->CommonCfg.RadarDetect.ChMovingTime = 65;
-#ifdef MERGE_ARCH_TEAM
-	pAd->CommonCfg.RadarDetect.LongPulseRadarTh = 2;
-	pAd->CommonCfg.RadarDetect.AvgRssiReq = -75;
-#else // original rt28xx source code
-	pAd->CommonCfg.RadarDetect.LongPulseRadarTh = 3;
-#endif // MERGE_ARCH_TEAM //
-	pAd->CommonCfg.bAPSDCapable = FALSE;
-	pAd->CommonCfg.bNeedSendTriggerFrame = FALSE;
-	pAd->CommonCfg.TriggerTimerCount = 0;
-	pAd->CommonCfg.bAPSDForcePowerSave = FALSE;
-	pAd->CommonCfg.bCountryFlag = FALSE;
-	pAd->CommonCfg.TxStream = 0;
-	pAd->CommonCfg.RxStream = 0;
-
-	NdisZeroMemory(&pAd->BeaconTxWI, sizeof(pAd->BeaconTxWI));
-
-#ifdef DOT11_N_SUPPORT
-	NdisZeroMemory(&pAd->CommonCfg.HtCapability, sizeof(pAd->CommonCfg.HtCapability));
-	pAd->HTCEnable = FALSE;
-	pAd->bBroadComHT = FALSE;
-	pAd->CommonCfg.bRdg = FALSE;
-
-#ifdef DOT11N_DRAFT3
-	pAd->CommonCfg.Dot11OBssScanPassiveDwell = dot11OBSSScanPassiveDwell;	// Unit : TU. 5~1000
-	pAd->CommonCfg.Dot11OBssScanActiveDwell = dot11OBSSScanActiveDwell;	// Unit : TU. 10~1000
-	pAd->CommonCfg.Dot11BssWidthTriggerScanInt = dot11BSSWidthTriggerScanInterval;	// Unit : Second
-	pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel = dot11OBSSScanPassiveTotalPerChannel;	// Unit : TU. 200~10000
-	pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel = dot11OBSSScanActiveTotalPerChannel;	// Unit : TU. 20~10000
-	pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor = dot11BSSWidthChannelTransactionDelayFactor;
-	pAd->CommonCfg.Dot11OBssScanActivityThre = dot11BSSScanActivityThreshold;	// Unit : percentage
-	pAd->CommonCfg.Dot11BssWidthChanTranDelay = (pAd->CommonCfg.Dot11BssWidthTriggerScanInt * pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor);
-#endif  // DOT11N_DRAFT3 //
-
-	NdisZeroMemory(&pAd->CommonCfg.AddHTInfo, sizeof(pAd->CommonCfg.AddHTInfo));
-	pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
-	pAd->CommonCfg.BACapability.field.MpduDensity = 0;
-	pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
-	pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64; //32;
-	pAd->CommonCfg.BACapability.field.TxBAWinLimit = 64; //32;
-	DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit. BACapability = 0x%x\n", pAd->CommonCfg.BACapability.word));
-
-	pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
-	BATableInit(pAd, &pAd->BATable);
-
-	pAd->CommonCfg.bExtChannelSwitchAnnouncement = 1;
-	pAd->CommonCfg.bHTProtect = 1;
-	pAd->CommonCfg.bMIMOPSEnable = TRUE;
-	//2008/11/05:KH add to support Antenna power-saving of AP<--
-	pAd->CommonCfg.bGreenAPEnable=FALSE;
-	pAd->CommonCfg.bBlockAntDivforGreenAP=FALSE;
-	//2008/11/05:KH add to support Antenna power-saving of AP-->
-	pAd->CommonCfg.bBADecline = FALSE;
-	pAd->CommonCfg.bDisableReordering = FALSE;
-
-	if (pAd->MACVersion == 0x28720200)
-	{
-		pAd->CommonCfg.TxBASize = 13; //by Jerry recommend
-	}else{
-		pAd->CommonCfg.TxBASize = 7;
-	}
-
-	pAd->CommonCfg.REGBACapability.word = pAd->CommonCfg.BACapability.word;
-#endif // DOT11_N_SUPPORT //
-
-	//pAd->CommonCfg.HTPhyMode.field.BW = BW_20;
-	//pAd->CommonCfg.HTPhyMode.field.MCS = MCS_AUTO;
-	//pAd->CommonCfg.HTPhyMode.field.ShortGI = GI_800;
-	//pAd->CommonCfg.HTPhyMode.field.STBC = STBC_NONE;
-	pAd->CommonCfg.TxRate = RATE_6;
-
-	pAd->CommonCfg.MlmeTransmit.field.MCS = MCS_RATE_6;
-	pAd->CommonCfg.MlmeTransmit.field.BW = BW_20;
-	pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
-
-	pAd->CommonCfg.BeaconPeriod = 100;     // in mSec
-
-
-	//
-	// part II. intialize STA specific configuration
-	//
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_DIRECT);
-		RX_FILTER_CLEAR_FLAG(pAd, fRX_FILTER_ACCEPT_MULTICAST);
-		RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_BROADCAST);
-		RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_ALL_MULTICAST);
-
-		pAd->StaCfg.Psm = PWR_ACTIVE;
-
-		pAd->StaCfg.OrigWepStatus = Ndis802_11EncryptionDisabled;
-		pAd->StaCfg.PairCipher = Ndis802_11EncryptionDisabled;
-		pAd->StaCfg.GroupCipher = Ndis802_11EncryptionDisabled;
-		pAd->StaCfg.bMixCipher = FALSE;
-		pAd->StaCfg.DefaultKeyId = 0;
-
-		// 802.1x port control
-		pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
-		pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-		pAd->StaCfg.LastMicErrorTime = 0;
-		pAd->StaCfg.MicErrCnt        = 0;
-		pAd->StaCfg.bBlockAssoc      = FALSE;
-		pAd->StaCfg.WpaState         = SS_NOTUSE;
-
-		pAd->CommonCfg.NdisRadioStateOff = FALSE;		// New to support microsoft disable radio with OID command
-
-		pAd->StaCfg.RssiTrigger = 0;
-		NdisZeroMemory(&pAd->StaCfg.RssiSample, sizeof(RSSI_SAMPLE));
-		pAd->StaCfg.RssiTriggerMode = RSSI_TRIGGERED_UPON_BELOW_THRESHOLD;
-		pAd->StaCfg.AtimWin = 0;
-		pAd->StaCfg.DefaultListenCount = 3;//default listen count;
-		pAd->StaCfg.BssType = BSS_INFRA;  // BSS_INFRA or BSS_ADHOC or BSS_MONITOR
-		pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
-
-		pAd->StaCfg.bAutoTxRateSwitch = TRUE;
-		pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
-	}
-
-#ifdef EXT_BUILD_CHANNEL_LIST
-	pAd->StaCfg.IEEE80211dClientMode = Rt802_11_D_None;
-#endif // EXT_BUILD_CHANNEL_LIST //
-#ifdef PCIE_PS_SUPPORT
-pAd->brt30xxBanMcuCmd = FALSE;
-pAd->b3090ESpecialChip = FALSE;
-//KH Debug:the following must be removed
-pAd->StaCfg.PSControl.field.rt30xxPowerMode=3;
-pAd->StaCfg.PSControl.field.rt30xxForceASPMTest=0;
-pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM=1;
-#endif // PCIE_PS_SUPPORT //
-#endif // CONFIG_STA_SUPPORT //
-
-	// global variables mXXXX used in MAC protocol state machines
-	OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
-
-	// PHY specification
-	pAd->CommonCfg.PhyMode = PHY_11BG_MIXED;		// default PHY mode
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);  // CCK use LONG preamble
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		// user desired power mode
-		pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
-		pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
-		pAd->StaCfg.bWindowsACCAMEnable = FALSE;
-
-		RTMPInitTimer(pAd, &pAd->StaCfg.StaQuickResponeForRateUpTimer, GET_TIMER_FUNCTION(StaQuickResponeForRateUpExec), pAd, FALSE);
-		pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
-
-		// Patch for Ndtest
-		pAd->StaCfg.ScanCnt = 0;
-
-		pAd->StaCfg.bHwRadio  = TRUE; // Default Hardware Radio status is On
-		pAd->StaCfg.bSwRadio  = TRUE; // Default Software Radio status is On
-		pAd->StaCfg.bRadio    = TRUE; // bHwRadio && bSwRadio
-		pAd->StaCfg.bHardwareRadio = FALSE;		// Default is OFF
-		pAd->StaCfg.bShowHiddenSSID = FALSE;		// Default no show
-
-		// Nitro mode control
-		pAd->StaCfg.bAutoReconnect = TRUE;
-
-		// Save the init time as last scan time, the system should do scan after 2 seconds.
-		// This patch is for driver wake up from standby mode, system will do scan right away.
-		NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime);
-		if (pAd->StaCfg.LastScanTime > 10 * OS_HZ)
-			pAd->StaCfg.LastScanTime -= (10 * OS_HZ);
-
-		NdisZeroMemory(pAd->nickname, IW_ESSID_MAX_SIZE+1);
-#ifdef RTMP_MAC_PCI
-		sprintf((PSTRING) pAd->nickname, "RT2860STA");
-#endif // RTMP_MAC_PCI //
-		RTMPInitTimer(pAd, &pAd->StaCfg.WpaDisassocAndBlockAssocTimer, GET_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc), pAd, FALSE);
-#ifdef WPA_SUPPLICANT_SUPPORT
-		pAd->StaCfg.IEEE8021X = FALSE;
-		pAd->StaCfg.IEEE8021x_required_keys = FALSE;
-		pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
-		pAd->StaCfg.bRSN_IE_FromWpaSupplicant = FALSE;
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-		pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-		NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
-
-
-		pAd->StaCfg.bAutoConnectByBssid = FALSE;
-		pAd->StaCfg.BeaconLostTime = BEACON_LOST_TIME;
-		NdisZeroMemory(pAd->StaCfg.WpaPassPhrase, 64);
-		pAd->StaCfg.WpaPassPhraseLen = 0;
-		pAd->StaCfg.bAutoRoaming = FALSE;
-		pAd->StaCfg.bForceTxBurst = FALSE;
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	// Default for extra information is not valid
-	pAd->ExtraInfo = EXTRA_INFO_CLEAR;
-
-	// Default Config change flag
-	pAd->bConfigChanged = FALSE;
-
-	//
-	// part III. AP configurations
-	//
-
-
-	//
-	// part IV. others
-	//
-	// dynamic BBP R66:sensibity tuning to overcome background noise
-	pAd->BbpTuning.bEnable                = TRUE;
-	pAd->BbpTuning.FalseCcaLowerThreshold = 100;
-	pAd->BbpTuning.FalseCcaUpperThreshold = 512;
-	pAd->BbpTuning.R66Delta               = 4;
-	pAd->Mlme.bEnableAutoAntennaCheck = TRUE;
-
-	//
-	// Also initial R66CurrentValue, RTUSBResumeMsduTransmission might use this value.
-	// if not initial this value, the default value will be 0.
-	//
-	pAd->BbpTuning.R66CurrentValue = 0x38;
-
-	pAd->Bbp94 = BBPR94_DEFAULT;
-	pAd->BbpForCCK = FALSE;
-
-	// Default is FALSE for test bit 1
-	//pAd->bTest1 = FALSE;
-
-	// initialize MAC table and allocate spin lock
-	NdisZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE));
-	InitializeQueueHeader(&pAd->MacTab.McastPsQueue);
-	NdisAllocateSpinLock(&pAd->MacTabLock);
-
-	//RTMPInitTimer(pAd, &pAd->RECBATimer, RECBATimerTimeout, pAd, TRUE);
-	//RTMPSetTimer(&pAd->RECBATimer, REORDER_EXEC_INTV);
-
-#ifdef RALINK_ATE
-	NdisZeroMemory(&pAd->ate, sizeof(ATE_INFO));
-	pAd->ate.Mode = ATE_STOP;
-	pAd->ate.TxCount = 200;/* to exceed TX_RING_SIZE ... */
-	pAd->ate.TxDoneCount = 0;
-	pAd->ate.RFFreqOffset = 0;
-	pAd->ate.TxLength = 1024;
-	pAd->ate.TxWI.ShortGI = 0;// LONG GI : 800 ns
-	pAd->ate.TxWI.PHYMODE = MODE_CCK;
-	pAd->ate.TxWI.MCS = 3;
-	pAd->ate.TxWI.BW = BW_20;
-	pAd->ate.Channel = 1;
-	pAd->ate.QID = QID_AC_BE;
-	pAd->ate.Addr1[0] = 0x00;
-	pAd->ate.Addr1[1] = 0x11;
-	pAd->ate.Addr1[2] = 0x22;
-	pAd->ate.Addr1[3] = 0xAA;
-	pAd->ate.Addr1[4] = 0xBB;
-	pAd->ate.Addr1[5] = 0xCC;
-	NdisMoveMemory(pAd->ate.Addr2, pAd->ate.Addr1, ETH_LENGTH_OF_ADDRESS);
-	NdisMoveMemory(pAd->ate.Addr3, pAd->ate.Addr1, ETH_LENGTH_OF_ADDRESS);
-	pAd->ate.bRxFER = 0;
-	pAd->ate.bQATxStart = FALSE;
-	pAd->ate.bQARxStart = FALSE;
-
-#ifdef RTMP_MAC_PCI
-	pAd->ate.bFWLoading = FALSE;
-#endif // RTMP_MAC_PCI //
-
-
-#ifdef RALINK_28xx_QA
-	pAd->ate.TxStatus = 0;
-	pAd->ate.AtePid = THREAD_PID_INIT_VALUE;
-#endif // RALINK_28xx_QA //
-#endif // RALINK_ATE //
-
-
-	pAd->CommonCfg.bWiFiTest = FALSE;
-#ifdef RTMP_MAC_PCI
-    pAd->bPCIclkOff = FALSE;
-#endif // RTMP_MAC_PCI //
-
-#ifdef CONFIG_STA_SUPPORT
-RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-#endif // CONFIG_STA_SUPPORT //
-#ifdef ANT_DIVERSITY_SUPPORT
-		if ( pAd->CommonCfg.bRxAntDiversity == ANT_FIX_ANT2)
-		{
-			pAd->RxAnt.Pair1PrimaryRxAnt = 1;
-			pAd->RxAnt.Pair1SecondaryRxAnt = 0;
-		}
-		else // Default
-		{
-			pAd->RxAnt.Pair1PrimaryRxAnt = 0;
-			pAd->RxAnt.Pair1SecondaryRxAnt = 1;
-		}
-		pAd->RxAnt.EvaluatePeriod = 0;
-		pAd->RxAnt.RcvPktNumWhenEvaluate = 0;
-#ifdef CONFIG_STA_SUPPORT
-		pAd->RxAnt.Pair1AvgRssi[0] = pAd->RxAnt.Pair1AvgRssi[1] = 0;
-#endif // CONFIG_STA_SUPPORT //
-#endif // AP_ANTENNA_DIVERSITY_SUPPORT //
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- UserCfgInit\n"));
-}
-
-// IRQL = PASSIVE_LEVEL
-UCHAR BtoH(STRING ch)
-{
-	if (ch >= '0' && ch <= '9') return (ch - '0');        // Handle numerals
-	if (ch >= 'A' && ch <= 'F') return (ch - 'A' + 0xA);  // Handle capitol hex digits
-	if (ch >= 'a' && ch <= 'f') return (ch - 'a' + 0xA);  // Handle small hex digits
-	return(255);
-}
-
-//
-//  FUNCTION: AtoH(char *, UCHAR *, int)
-//
-//  PURPOSE:  Converts ascii string to network order hex
-//
-//  PARAMETERS:
-//    src    - pointer to input ascii string
-//    dest   - pointer to output hex
-//    destlen - size of dest
-//
-//  COMMENTS:
-//
-//    2 ascii bytes make a hex byte so must put 1st ascii byte of pair
-//    into upper nibble and 2nd ascii byte of pair into lower nibble.
-//
-// IRQL = PASSIVE_LEVEL
-
-void AtoH(PSTRING src, PUCHAR dest, int destlen)
-{
-	PSTRING srcptr;
-	PUCHAR destTemp;
-
-	srcptr = src;
-	destTemp = (PUCHAR) dest;
-
-	while(destlen--)
-	{
-		*destTemp = BtoH(*srcptr++) << 4;    // Put 1st ascii byte in upper nibble.
-		*destTemp += BtoH(*srcptr++);      // Add 2nd ascii byte to above.
-		destTemp++;
-	}
-}
-
-
-//+++Mark by shiang, not use now, need to remove after confirm
-//---Mark by shiang, not use now, need to remove after confirm
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Init timer objects
-
-	Arguments:
-		pAd			Pointer to our adapter
-		pTimer				Timer structure
-		pTimerFunc			Function to execute when timer expired
-		Repeat				Ture for period timer
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPInitTimer(
-	IN	PRTMP_ADAPTER			pAd,
-	IN	PRALINK_TIMER_STRUCT	pTimer,
-	IN	PVOID					pTimerFunc,
-	IN	PVOID					pData,
-	IN	BOOLEAN					Repeat)
-{
-	//
-	// Set Valid to TRUE for later used.
-	// It will crash if we cancel a timer or set a timer
-	// that we haven't initialize before.
-	//
-	pTimer->Valid      = TRUE;
-
-	pTimer->PeriodicType = Repeat;
-	pTimer->State      = FALSE;
-	pTimer->cookie = (ULONG) pData;
-
-#ifdef RTMP_TIMER_TASK_SUPPORT
-	pTimer->pAd = pAd;
-#endif // RTMP_TIMER_TASK_SUPPORT //
-
-	RTMP_OS_Init_Timer(pAd, &pTimer->TimerObj,	pTimerFunc, (PVOID) pTimer);
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Init timer objects
-
-	Arguments:
-		pTimer				Timer structure
-		Value				Timer value in milliseconds
-
-	Return Value:
-		None
-
-	Note:
-		To use this routine, must call RTMPInitTimer before.
-
-	========================================================================
-*/
-VOID	RTMPSetTimer(
-	IN	PRALINK_TIMER_STRUCT	pTimer,
-	IN	ULONG					Value)
-{
-	if (pTimer->Valid)
-	{
-		pTimer->TimerValue = Value;
-		pTimer->State      = FALSE;
-		if (pTimer->PeriodicType == TRUE)
-		{
-			pTimer->Repeat = TRUE;
-			RTMP_SetPeriodicTimer(&pTimer->TimerObj, Value);
-		}
-		else
-		{
-			pTimer->Repeat = FALSE;
-			RTMP_OS_Add_Timer(&pTimer->TimerObj, Value);
-		}
-	}
-	else
-	{
-		DBGPRINT_ERR(("RTMPSetTimer failed, Timer hasn't been initialize!\n"));
-	}
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Init timer objects
-
-	Arguments:
-		pTimer				Timer structure
-		Value				Timer value in milliseconds
-
-	Return Value:
-		None
-
-	Note:
-		To use this routine, must call RTMPInitTimer before.
-
-	========================================================================
-*/
-VOID	RTMPModTimer(
-	IN	PRALINK_TIMER_STRUCT	pTimer,
-	IN	ULONG					Value)
-{
-	BOOLEAN	Cancel;
-
-	if (pTimer->Valid)
-	{
-		pTimer->TimerValue = Value;
-		pTimer->State      = FALSE;
-		if (pTimer->PeriodicType == TRUE)
-		{
-			RTMPCancelTimer(pTimer, &Cancel);
-			RTMPSetTimer(pTimer, Value);
-		}
-		else
-		{
-			RTMP_OS_Mod_Timer(&pTimer->TimerObj, Value);
-		}
-	}
-	else
-	{
-		DBGPRINT_ERR(("RTMPModTimer failed, Timer hasn't been initialize!\n"));
-	}
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Cancel timer objects
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-		1.) To use this routine, must call RTMPInitTimer before.
-		2.) Reset NIC to initial state AS IS system boot up time.
-
-	========================================================================
-*/
-VOID	RTMPCancelTimer(
-	IN	PRALINK_TIMER_STRUCT	pTimer,
-	OUT	BOOLEAN					*pCancelled)
-{
-	if (pTimer->Valid)
-	{
-		if (pTimer->State == FALSE)
-			pTimer->Repeat = FALSE;
-
-		RTMP_OS_Del_Timer(&pTimer->TimerObj, pCancelled);
-
-		if (*pCancelled == TRUE)
-			pTimer->State = TRUE;
-
-#ifdef RTMP_TIMER_TASK_SUPPORT
-		// We need to go-through the TimerQ to findout this timer handler and remove it if
-		//		it's still waiting for execution.
-		RtmpTimerQRemove(pTimer->pAd, pTimer);
-#endif // RTMP_TIMER_TASK_SUPPORT //
-	}
-	else
-	{
-		DBGPRINT_ERR(("RTMPCancelTimer failed, Timer hasn't been initialize!\n"));
-	}
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Set LED Status
-
-	Arguments:
-		pAd						Pointer to our adapter
-		Status					LED Status
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID RTMPSetLED(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			Status)
-{
-	//ULONG			data;
-	UCHAR			HighByte = 0;
-	UCHAR			LowByte;
-	BOOLEAN			bIgnored = FALSE;
-
-#ifdef RALINK_ATE
-	/*
-		In ATE mode of RT2860 AP/STA, we have erased 8051 firmware.
-		So LED mode is not supported when ATE is running.
-	*/
-	if (!IS_RT3572(pAd))
-	{
-		if (ATE_ON(pAd))
-			return;
-	}
-#endif // RALINK_ATE //
-
-	LowByte = pAd->LedCntl.field.LedMode&0x7f;
-	switch (Status)
-	{
-		case LED_LINK_DOWN:
-			HighByte = 0x20;
-			AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
-			pAd->LedIndicatorStrength = 0;
-			break;
-		case LED_LINK_UP:
-			if (pAd->CommonCfg.Channel > 14)
-				HighByte = 0xa0;
-			else
-				HighByte = 0x60;
-			AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
-			break;
-		case LED_RADIO_ON:
-			HighByte = 0x20;
-			AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
-			break;
-		case LED_HALT:
-			LowByte = 0; // Driver sets MAC register and MAC controls LED
-		case LED_RADIO_OFF:
-			HighByte = 0;
-			AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
-			break;
-		case LED_WPS:
-			HighByte = 0x10;
-			AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
-			break;
-		case LED_ON_SITE_SURVEY:
-			HighByte = 0x08;
-			AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
-			break;
-		case LED_POWER_UP:
-			HighByte = 0x04;
-			AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
-			break;
-#ifdef RALINK_ATE
-#endif // RALINK_ATE //
-		default:
-			DBGPRINT(RT_DEBUG_WARN, ("RTMPSetLED::Unknown Status %d\n", Status));
-			break;
-	}
-
-    //
-	// Keep LED status for LED SiteSurvey mode.
-	// After SiteSurvey, we will set the LED mode to previous status.
-	//
-	if ((Status != LED_ON_SITE_SURVEY) && (Status != LED_POWER_UP) && (bIgnored == FALSE))
-		pAd->LedStatus = Status;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetLED::Mode=%d,HighByte=0x%02x,LowByte=0x%02x\n", pAd->LedCntl.field.LedMode, HighByte, LowByte));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Set LED Signal Stregth
-
-	Arguments:
-		pAd						Pointer to our adapter
-		Dbm						Signal Stregth
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-		Can be run on any IRQL level.
-
-		According to Microsoft Zero Config Wireless Signal Stregth definition as belows.
-		<= -90  No Signal
-		<= -81  Very Low
-		<= -71  Low
-		<= -67  Good
-		<= -57  Very Good
-		 > -57  Excellent
-	========================================================================
-*/
-VOID RTMPSetSignalLED(
-	IN PRTMP_ADAPTER	pAd,
-	IN NDIS_802_11_RSSI Dbm)
-{
-	UCHAR		nLed = 0;
-
-	if (pAd->LedCntl.field.LedMode == LED_MODE_SIGNAL_STREGTH)
-	{
-		if (Dbm <= -90)
-			nLed = 0;
-		else if (Dbm <= -81)
-			nLed = 1;
-		else if (Dbm <= -71)
-			nLed = 3;
-		else if (Dbm <= -67)
-			nLed = 7;
-		else if (Dbm <= -57)
-			nLed = 15;
-		else
-			nLed = 31;
-
-		//
-		// Update Signal Stregth to firmware if changed.
-		//
-		if (pAd->LedIndicatorStrength != nLed)
-		{
-			AsicSendCommandToMcu(pAd, 0x51, 0xff, nLed, pAd->LedCntl.field.Polarity);
-			pAd->LedIndicatorStrength = nLed;
-		}
-	}
-}
-
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Enable RX
-
-	Arguments:
-		pAd						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL <= DISPATCH_LEVEL
-
-	Note:
-		Before Enable RX, make sure you have enabled Interrupt.
-	========================================================================
-*/
-VOID RTMPEnableRxTx(
-	IN PRTMP_ADAPTER	pAd)
-{
-//	WPDMA_GLO_CFG_STRUC	GloCfg;
-//	ULONG	i = 0;
-	UINT32 rx_filter_flag;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPEnableRxTx\n"));
-
-	// Enable Rx DMA.
-	RT28XXDMAEnable(pAd);
-
-	// enable RX of MAC block
-	if (pAd->OpMode == OPMODE_AP)
-	{
-		rx_filter_flag = APNORMAL;
-
-
-		RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag);     // enable RX of DMA block
-	}
-	else
-	{
-		if (pAd->CommonCfg.PSPXlink)
-			rx_filter_flag = PSPXLINK;
-		else
-			rx_filter_flag = STANORMAL;     // Staion not drop control frame will fail WiFi Certification.
-		RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag);
-	}
-
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc);
-	DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPEnableRxTx\n"));
-}
-
-
-//+++Add by shiang, move from os/linux/rt_main_dev.c
-void CfgInitHook(PRTMP_ADAPTER pAd)
-{
-	pAd->bBroadComHT = TRUE;
-}
-
-
-int rt28xx_init(
-	IN PRTMP_ADAPTER pAd,
-	IN PSTRING pDefaultMac,
-	IN PSTRING pHostName)
-{
-	UINT					index;
-	UCHAR					TmpPhy;
-	NDIS_STATUS				Status;
-	UINT32					MacCsr0 = 0;
-
-#ifdef CONFIG_STA_SUPPORT
-#ifdef RTMP_MAC_PCI
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-	// If dirver doesn't wake up firmware here,
-	// NICLoadFirmware will hang forever when interface is up again.
-	// RT2860 PCI
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) &&
-		OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
-	{
-		AUTO_WAKEUP_STRUC AutoWakeupCfg;
-			AsicForceWakeup(pAd, TRUE);
-		AutoWakeupCfg.word = 0;
-		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-	}
-	}
-#endif // RTMP_MAC_PCI //
-#endif // CONFIG_STA_SUPPORT //
-
-
-	// reset Adapter flags
-	RTMP_CLEAR_FLAGS(pAd);
-
-	// Init BssTab & ChannelInfo tabbles for auto channel select.
-
-#ifdef DOT11_N_SUPPORT
-	// Allocate BA Reordering memory
-	ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM);
-#endif // DOT11_N_SUPPORT //
-
-	// Make sure MAC gets ready.
-	index = 0;
-	do
-	{
-		RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
-		pAd->MACVersion = MacCsr0;
-
-		if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF))
-			break;
-
-		RTMPusecDelay(10);
-	} while (index++ < 100);
-	DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0  [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
-
-#ifdef RTMP_MAC_PCI
-#ifdef PCIE_PS_SUPPORT
-	/*Iverson patch PCIE L1 issue to make sure that driver can be read,write ,BBP and RF register  at pcie L.1 level */
-	if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))&&OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
-	{
-		RTMP_IO_READ32(pAd, AUX_CTRL, &MacCsr0);
-		MacCsr0 |= 0x402;
-		RTMP_IO_WRITE32(pAd, AUX_CTRL, MacCsr0);
-		DBGPRINT(RT_DEBUG_TRACE, ("AUX_CTRL = 0x%x\n", MacCsr0));
-	}
-#endif // PCIE_PS_SUPPORT //
-
-	// To fix driver disable/enable hang issue when radio off
-	RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x2);
-#endif // RTMP_MAC_PCI //
-
-	// Disable DMA
-	RT28XXDMADisable(pAd);
-
-
-	// Load 8051 firmware
-	Status = NICLoadFirmware(pAd);
-	if (Status != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", Status));
-		goto err1;
-	}
-
-	NICLoadRateSwitchingParams(pAd);
-
-	// Disable interrupts here which is as soon as possible
-	// This statement should never be true. We might consider to remove it later
-#ifdef RTMP_MAC_PCI
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
-	{
-		RTMP_ASIC_INTERRUPT_DISABLE(pAd);
-	}
-#endif // RTMP_MAC_PCI //
-
-	Status = RTMPAllocTxRxRingMemory(pAd);
-	if (Status != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT_ERR(("RTMPAllocDMAMemory failed, Status[=0x%08x]\n", Status));
-		goto err1;
-	}
-
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
-
-	// initialize MLME
-	//
-
-	Status = RtmpMgmtTaskInit(pAd);
-	if (Status != NDIS_STATUS_SUCCESS)
-		goto err2;
-
-	Status = MlmeInit(pAd);
-	if (Status != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status));
-		goto err2;
-	}
-
-	// Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default
-	//
-	UserCfgInit(pAd);
-	Status = RtmpNetTaskInit(pAd);
-	if (Status != NDIS_STATUS_SUCCESS)
-		goto err3;
-
-//	COPY_MAC_ADDR(pAd->ApCfg.MBSSID[apidx].Bssid, netif->hwaddr);
-//	pAd->bForcePrintTX = TRUE;
-
-	CfgInitHook(pAd);
-
-
-#ifdef BLOCK_NET_IF
-	initblockQueueTab(pAd);
-#endif // BLOCK_NET_IF //
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		NdisAllocateSpinLock(&pAd->MacTabLock);
-#endif // CONFIG_STA_SUPPORT //
-
-	MeasureReqTabInit(pAd);
-	TpcReqTabInit(pAd);
-
-	//
-	// Init the hardware, we need to init asic before read registry, otherwise mac register will be reset
-	//
-	Status = NICInitializeAdapter(pAd, TRUE);
-	if (Status != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n", Status));
-		if (Status != NDIS_STATUS_SUCCESS)
-		goto err3;
-	}
-
-	// Read parameters from Config File
-	Status = RTMPReadParametersHook(pAd);
-
-	DBGPRINT(RT_DEBUG_OFF, ("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode));
-	if (Status != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT_ERR(("NICReadRegParameters failed, Status[=0x%08x]\n",Status));
-		goto err4;
-	}
-
-
-
-#ifdef DOT11_N_SUPPORT
-	//Init Ba Capability parameters.
-//	RT28XX_BA_INIT(pAd);
-	pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
-	pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable;
-	pAd->CommonCfg.DesiredHtPhy.AmsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
-	pAd->CommonCfg.DesiredHtPhy.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
-	// UPdata to HT IE
-	pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
-	pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
-	pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
-#endif // DOT11_N_SUPPORT //
-
-	// after reading Registry, we now know if in AP mode or STA mode
-
-	// Load 8051 firmware; crash when FW image not existent
-	// Status = NICLoadFirmware(pAd);
-	// if (Status != NDIS_STATUS_SUCCESS)
-	//    break;
-
-	DBGPRINT(RT_DEBUG_OFF, ("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode));
-
-	// We should read EEPROM for all cases.  rt2860b
-	NICReadEEPROMParameters(pAd, (PUCHAR)pDefaultMac);
-#ifdef CONFIG_STA_SUPPORT
-#endif // CONFIG_STA_SUPPORT //
-
-	DBGPRINT(RT_DEBUG_OFF, ("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode));
-
-	NICInitAsicFromEEPROM(pAd); //rt2860b
-
-	// Set PHY to appropriate mode
-	TmpPhy = pAd->CommonCfg.PhyMode;
-	pAd->CommonCfg.PhyMode = 0xff;
-	RTMPSetPhyMode(pAd, TmpPhy);
-#ifdef DOT11_N_SUPPORT
-	SetCommonHT(pAd);
-#endif // DOT11_N_SUPPORT //
-
-	// No valid channels.
-	if (pAd->ChannelListNum == 0)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n"));
-		goto err4;
-	}
-
-#ifdef DOT11_N_SUPPORT
-	DBGPRINT(RT_DEBUG_OFF, ("MCS Set = %02x %02x %02x %02x %02x\n", pAd->CommonCfg.HtCapability.MCSSet[0],
-           pAd->CommonCfg.HtCapability.MCSSet[1], pAd->CommonCfg.HtCapability.MCSSet[2],
-           pAd->CommonCfg.HtCapability.MCSSet[3], pAd->CommonCfg.HtCapability.MCSSet[4]));
-#endif // DOT11_N_SUPPORT //
-
-#ifdef RTMP_RF_RW_SUPPORT
-	//Init RT30xx RFRegisters after read RFIC type from EEPROM
-	NICInitRFRegisters(pAd);
-#endif // RTMP_RF_RW_SUPPORT //
-
-
-
-//		APInitialize(pAd);
-
-#ifdef IKANOS_VX_1X0
-	VR_IKANOS_FP_Init(pAd->ApCfg.BssidNum, pAd->PermanentAddress);
-#endif // IKANOS_VX_1X0 //
-
-		//
-	// Initialize RF register to default value
-	//
-	AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-	AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-
-	// 8051 firmware require the signal during booting time.
-	//2008/11/28:KH marked the following codes to patch Frequency offset bug
-	//AsicSendCommandToMcu(pAd, 0x72, 0xFF, 0x00, 0x00);
-
-	if (pAd && (Status != NDIS_STATUS_SUCCESS))
-	{
-		//
-		// Undo everything if it failed
-		//
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-		{
-//			NdisMDeregisterInterrupt(&pAd->Interrupt);
-			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
-		}
-//		RTMPFreeAdapter(pAd); // we will free it in disconnect()
-	}
-	else if (pAd)
-	{
-		// Microsoft HCT require driver send a disconnect event after driver initialization.
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
-//		pAd->IndicateMediaState = NdisMediaStateDisconnected;
-		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
-
-		DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n"));
-
-
-	}// end of else
-
-
-	// Set up the Mac address
-	RtmpOSNetDevAddrSet(pAd->net_dev, &pAd->CurrentAddress[0]);
-
-	// Various AP function init
-
-
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-#ifdef WPA_SUPPLICANT_SUPPORT
-#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
-		// send wireless event to wpa_supplicant for infroming interface up.
-		RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, RT_INTERFACE_UP, NULL, NULL, 0);
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-
-
-	DBGPRINT_S(Status, ("<==== rt28xx_init, Status=%x\n", Status));
-
-	return TRUE;
-
-
-err4:
-err3:
-	MlmeHalt(pAd);
-err2:
-	RTMPFreeTxRxRingMemory(pAd);
-err1:
-
-#ifdef DOT11_N_SUPPORT
-	os_free_mem(pAd, pAd->mpdu_blk_pool.mem); // free BA pool
-#endif // DOT11_N_SUPPORT //
-
-	// shall not set priv to NULL here because the priv didn't been free yet.
-	//net_dev->priv = 0;
-#ifdef INF_AMAZON_SE
-err0:
-#endif // INF_AMAZON_SE //
-#ifdef ST
-err0:
-#endif // ST //
-
-	DBGPRINT(RT_DEBUG_ERROR, ("!!! rt28xx Initialized fail !!!\n"));
-	return FALSE;
-}
-//---Add by shiang, move from os/linux/rt_main_dev.c
-
-
-static INT RtmpChipOpsRegister(
-	IN RTMP_ADAPTER *pAd,
-	IN INT			infType)
-{
-	RTMP_CHIP_OP	*pChipOps = &pAd->chipOps;
-	int status;
-
-	memset(pChipOps, 0, sizeof(RTMP_CHIP_OP));
-
-	/* set eeprom related hook functions */
-	status = RtmpChipOpsEepromHook(pAd, infType);
-
-	/* set mcu related hook functions */
-	switch(infType)
-	{
-#ifdef RTMP_PCI_SUPPORT
-		case RTMP_DEV_INF_PCI:
-			pChipOps->loadFirmware = RtmpAsicLoadFirmware;
-			pChipOps->eraseFirmware = RtmpAsicEraseFirmware;
-			pChipOps->sendCommandToMcu = RtmpAsicSendCommandToMcu;
-			break;
-#endif // RTMP_PCI_SUPPORT //
-
-
-		default:
-			break;
-	}
-
-	return status;
-}
-
-
-INT RtmpRaDevCtrlInit(
-	IN RTMP_ADAPTER *pAd,
-	IN RTMP_INF_TYPE infType)
-{
-	//VOID	*handle;
-
-	// Assign the interface type. We need use it when do register/EEPROM access.
-	pAd->infType = infType;
-
-
-#ifdef CONFIG_STA_SUPPORT
-	pAd->OpMode = OPMODE_STA;
-	DBGPRINT(RT_DEBUG_TRACE, ("STA Driver version-%s\n", STA_DRIVER_VERSION));
-#endif // CONFIG_STA_SUPPORT //
-
-
-
-	RtmpChipOpsRegister(pAd, infType);
-
-#ifdef MULTIPLE_CARD_SUPPORT
-{
-	extern BOOLEAN RTMP_CardInfoRead(PRTMP_ADAPTER pAd);
-
-	// find its profile path
-	pAd->MC_RowID = -1; // use default profile path
-	RTMP_CardInfoRead(pAd);
-
-	if (pAd->MC_RowID == -1)
-#ifdef CONFIG_STA_SUPPORT
-		strcpy(pAd->MC_FileName, STA_PROFILE_PATH);
-#endif // CONFIG_STA_SUPPORT //
-
-	DBGPRINT(RT_DEBUG_TRACE, ("MC> ROW = %d, PATH = %s\n", pAd->MC_RowID, pAd->MC_FileName));
-}
-#endif // MULTIPLE_CARD_SUPPORT //
-
-	return 0;
-}
-
-
-BOOLEAN RtmpRaDevCtrlExit(IN RTMP_ADAPTER *pAd)
-{
-#ifdef MULTIPLE_CARD_SUPPORT
-extern UINT8  MC_CardUsed[MAX_NUM_OF_MULTIPLE_CARD];
-
-	if ((pAd->MC_RowID >= 0) && (pAd->MC_RowID <= MAX_NUM_OF_MULTIPLE_CARD))
-		MC_CardUsed[pAd->MC_RowID] = 0; // not clear MAC address
-#endif // MULTIPLE_CARD_SUPPORT //
-
-
-	RTMPFreeAdapter(pAd);
-
-	return TRUE;
-}
-
-
-// not yet support MBSS
-PNET_DEV get_netdev_from_bssid(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			FromWhichBSSID)
-{
-	PNET_DEV dev_p = NULL;
-
-
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		dev_p = pAd->net_dev;
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	ASSERT(dev_p);
-	return dev_p; /* return one of MBSS */
-}
diff --git a/drivers/staging/rt3090/common/rtmp_mcu.c b/drivers/staging/rt3090/common/rtmp_mcu.c
deleted file mode 100644
index 23f785a9..0000000
--- a/drivers/staging/rt3090/common/rtmp_mcu.c
+++ /dev/null
@@ -1,560 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtmp_mcu.c
-
-	Abstract:
-	Miniport generic portion header file
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-*/
-
-#include "../rt_config.h"
-#include "../firmware.h"
-
-//#define BIN_IN_FILE /* use *.bin firmware */
-
-
-// New 8k byte firmware size for RT3071/RT3072
-#define FIRMWAREIMAGE_MAX_LENGTH	0x2000
-#define FIRMWAREIMAGE_LENGTH			(sizeof (FirmwareImage) / sizeof(UCHAR))
-#define FIRMWARE_MAJOR_VERSION		0
-
-#define FIRMWAREIMAGEV1_LENGTH		0x1000
-#define FIRMWAREIMAGEV2_LENGTH		0x1000
-
-#ifdef RTMP_MAC_PCI
-#define FIRMWARE_MINOR_VERSION		2
-#endif // RTMP_MAC_PCI //
-
-const unsigned short ccitt_16Table[] = {
-	0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
-	0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
-	0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
-	0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
-	0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
-	0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
-	0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
-	0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
-	0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
-	0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
-	0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
-	0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
-	0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
-	0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
-	0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
-	0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
-	0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
-	0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
-	0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
-	0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
-	0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
-	0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
-	0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
-	0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
-	0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
-	0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
-	0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
-	0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
-	0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
-	0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
-	0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
-	0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
-};
-#define ByteCRC16(v, crc) \
-	(unsigned short)((crc << 8) ^  ccitt_16Table[((crc >> 8) ^ (v)) & 255])
-
-unsigned char BitReverse(unsigned char x)
-{
-	int i;
-	unsigned char Temp=0;
-	for(i=0; ; i++)
-	{
-		if(x & 0x80)	Temp |= 0x80;
-		if(i==7)		break;
-		x	<<= 1;
-		Temp >>= 1;
-	}
-	return Temp;
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		erase 8051 firmware image in MAC ASIC
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	IRQL = PASSIVE_LEVEL
-
-	========================================================================
-*/
-INT RtmpAsicEraseFirmware(
-	IN PRTMP_ADAPTER pAd)
-{
-	ULONG i;
-
-	for(i=0; i<MAX_FIRMWARE_IMAGE_SIZE; i+=4)
-		RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, 0);
-
-	return 0;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Load 8051 firmware file into MAC ASIC
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		NDIS_STATUS_SUCCESS         firmware image load ok
-		NDIS_STATUS_FAILURE         image not found
-
-	IRQL = PASSIVE_LEVEL
-
-	========================================================================
-*/
-NDIS_STATUS RtmpAsicLoadFirmware(
-	IN PRTMP_ADAPTER pAd)
-{
-#ifdef BIN_IN_FILE
-#define NICLF_DEFAULT_USE()	\
-	flg_default_firm_use = TRUE; \
-	DBGPRINT(RT_DEBUG_OFF, ("%s - Use default firmware!\n", __FUNCTION__));
-
-	NDIS_STATUS		Status = NDIS_STATUS_SUCCESS;
-	PUCHAR			src;
-	RTMP_OS_FD		srcf;
-	INT				retval, i;
-	PUCHAR			pFirmwareImage;
-	INT				FileLength = 0;
-	UINT32			MacReg;
-	ULONG			Index;
-	ULONG			firm;
-	BOOLEAN			flg_default_firm_use = FALSE;
-	RTMP_OS_FS_INFO	osFSInfo;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> %s\n", __FUNCTION__));
-
-	/* init */
-	pFirmwareImage = NULL;
-	src = RTMP_FIRMWARE_FILE_NAME;
-
-	RtmpOSFSInfoChange(&osFSInfo, TRUE);
-
-	pAd->FirmwareVersion = (FIRMWARE_MAJOR_VERSION << 8) + \
-						   FIRMWARE_MINOR_VERSION;
-
-
-	/* allocate firmware buffer */
-	pFirmwareImage = kmalloc(MAX_FIRMWARE_IMAGE_SIZE, MEM_ALLOC_FLAG);
-	if (pFirmwareImage == NULL)
-	{
-		/* allocate fail, use default firmware array in firmware.h */
-		DBGPRINT(RT_DEBUG_ERROR, ("%s - Allocate memory fail!\n", __FUNCTION__));
-		NICLF_DEFAULT_USE();
-	}
-	else
-	{
-		/* allocate ok! zero the firmware buffer */
-		memset(pFirmwareImage, 0x00, MAX_FIRMWARE_IMAGE_SIZE);
-	} /* End of if */
-
-
-	/* if ok, read firmware file from *.bin file */
-	if (flg_default_firm_use == FALSE)
-	{
-		do
-		{
-			/* open the bin file */
-			srcf = RtmpOSFileOpen(src, O_RDONLY, 0);
-
-			if (IS_FILE_OPEN_ERR(srcf))
-			{
-				DBGPRINT(RT_DEBUG_ERROR, ("%s - Error opening file %s\n", __FUNCTION__, src));
-				NICLF_DEFAULT_USE();
-				break;
-			}
-
-
-			/* read the firmware from the file *.bin */
-			FileLength = RtmpOSFileRead(srcf, pFirmwareImage, MAX_FIRMWARE_IMAGE_SIZE);
-			if (FileLength != MAX_FIRMWARE_IMAGE_SIZE)
-			{
-				DBGPRINT(RT_DEBUG_ERROR, ("%s: error file length (=%d) in RT2860AP.BIN\n",
-					   __FUNCTION__, FileLength));
-				NICLF_DEFAULT_USE();
-				break;
-			}
-			else
-			{
-				PUCHAR ptr = pFirmwareImage;
-				USHORT crc = 0xffff;
-
-
-				/* calculate firmware CRC */
-				for(i=0; i<(MAX_FIRMWARE_IMAGE_SIZE-2); i++, ptr++)
-					crc = ByteCRC16(BitReverse(*ptr), crc);
-				/* End of for */
-
-				if ((pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-2] != \
-								(UCHAR)BitReverse((UCHAR)(crc>>8))) ||
-					(pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-1] != \
-								(UCHAR)BitReverse((UCHAR)crc)))
-				{
-					/* CRC fail */
-					DBGPRINT(RT_DEBUG_ERROR, ("%s: CRC = 0x%02x 0x%02x "
-						   "error, should be 0x%02x 0x%02x\n",
-						   __FUNCTION__,
-						   pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-2],
-						   pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-1],
-						   (UCHAR)(crc>>8), (UCHAR)(crc)));
-					NICLF_DEFAULT_USE();
-					break;
-				}
-				else
-				{
-					/* firmware is ok */
-					pAd->FirmwareVersion = \
-						(pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-4] << 8) +
-						pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-3];
-
-					/* check if firmware version of the file is too old */
-					if ((pAd->FirmwareVersion) < \
-											((FIRMWARE_MAJOR_VERSION << 8) +
-											 FIRMWARE_MINOR_VERSION))
-					{
-						DBGPRINT(RT_DEBUG_ERROR, ("%s: firmware version too old!\n", __FUNCTION__));
-						NICLF_DEFAULT_USE();
-						break;
-					} /* End of if */
-				} /* End of if */
-
-				DBGPRINT(RT_DEBUG_TRACE,
-						 ("NICLoadFirmware: CRC ok, ver=%d.%d\n",
-						  pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-4],
-						  pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-3]));
-			} /* End of if (FileLength == MAX_FIRMWARE_IMAGE_SIZE) */
-			break;
-		} while(TRUE);
-
-		/* close firmware file */
-		if (IS_FILE_OPEN_ERR(srcf))
-			;
-		else
-		{
-			retval = RtmpOSFileClose(srcf);
-			if (retval)
-			{
-				DBGPRINT(RT_DEBUG_ERROR, ("--> Error %d closing %s\n", -retval, src));
-			}
-		}
-	}
-
-
-	/* write firmware to ASIC */
-	if (flg_default_firm_use == TRUE)
-	{
-		/* use default fimeware, free allocated buffer */
-		if (pFirmwareImage != NULL)
-			kfree(pFirmwareImage);
-		/* End of if */
-
-		/* use default *.bin array */
-		pFirmwareImage = FirmwareImage;
-		FileLength = sizeof(FirmwareImage);
-	} /* End of if */
-
-	/* enable Host program ram write selection */
-	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x10000);
-
-	for(i=0; i<FileLength; i+=4)
-	{
-		firm = pFirmwareImage[i] +
-			   (pFirmwareImage[i+3] << 24) +
-			   (pFirmwareImage[i+2] << 16) +
-			   (pFirmwareImage[i+1] << 8);
-
-		RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, firm);
-	} /* End of for */
-
-	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x00000);
-	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x00001);
-
-	/* initialize BBP R/W access agent */
-	RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, 0);
-	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, 0);
-
-	if (flg_default_firm_use == FALSE)
-	{
-		/* use file firmware, free allocated buffer */
-		if (pFirmwareImage != NULL)
-			kfree(pFirmwareImage);
-		/* End of if */
-	} /* End of if */
-
-	RtmpOSFSInfoChange(&osFSInfo, FALSE);
-#else
-
-	NDIS_STATUS		Status = NDIS_STATUS_SUCCESS;
-	PUCHAR			pFirmwareImage;
-	ULONG			FileLength, Index;
-	//ULONG			firm;
-	UINT32			MacReg = 0;
-	UINT32			Version = (pAd->MACVersion >> 16);
-
-	pFirmwareImage = FirmwareImage;
-	FileLength = sizeof(FirmwareImage);
-
-	// New 8k byte firmware size for RT3071/RT3072
-	//DBGPRINT(RT_DEBUG_TRACE, ("Usb Chip\n"));
-	if (FIRMWAREIMAGE_LENGTH == FIRMWAREIMAGE_MAX_LENGTH)
-	//The firmware image consists of two parts. One is the origianl and the other is the new.
-	//Use Second Part
-	{
-#ifdef RTMP_MAC_PCI
-		if ((Version == 0x2860) || IS_RT3090(pAd)||IS_RT3390(pAd))
-		{
-			pFirmwareImage = FirmwareImage;
-			FileLength = FIRMWAREIMAGE_LENGTH;
-		}
-#endif // RTMP_MAC_PCI //
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("KH: bin file should be 8KB.\n"));
-		Status = NDIS_STATUS_FAILURE;
-	}
-
-
-	RTMP_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength);
-
-#endif
-
-	/* check if MCU is ready */
-	Index = 0;
-	do
-	{
-		RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacReg);
-
-		if (MacReg & 0x80)
-			break;
-
-		RTMPusecDelay(1000);
-	} while (Index++ < 1000);
-
-    if (Index >= 1000)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("NICLoadFirmware: MCU is not ready\n\n\n"));
-		Status = NDIS_STATUS_FAILURE;
-	}
-
-    DBGPRINT(RT_DEBUG_TRACE, ("<=== %s (status=%d)\n", __FUNCTION__, Status));
-
-    return Status;
-}
-
-
-INT RtmpAsicSendCommandToMcu(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR		 Command,
-	IN UCHAR		 Token,
-	IN UCHAR		 Arg0,
-	IN UCHAR		 Arg1)
-{
-	HOST_CMD_CSR_STRUC	H2MCmd;
-	H2M_MAILBOX_STRUC	H2MMailbox;
-	ULONG				i = 0;
-#ifdef RTMP_MAC_PCI
-#ifdef RALINK_ATE
-	static UINT32 j = 0;
-#endif // RALINK_ATE //
-#endif // RTMP_MAC_PCI //
-#ifdef PCIE_PS_SUPPORT
-#ifdef CONFIG_STA_SUPPORT
-	// 3090F power solution 3 has hw limitation that needs to ban all mcu command
-	// when firmware is in radio state.  For other chip doesn't have this limitation.
-	if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
-		&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
-		&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))
-	{
-		RTMP_SEM_LOCK(&pAd->McuCmdLock);
-		if ((pAd->brt30xxBanMcuCmd == TRUE)
-			&& (Command != WAKE_MCU_CMD) && (Command != RFOFF_MCU_CMD))
-		{
-			RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
-			DBGPRINT(RT_DEBUG_TRACE, (" Ban Mcu Cmd %x in sleep mode\n",  Command));
-			return FALSE;
-		}
-		else if ((Command == SLEEP_MCU_CMD)
-			||(Command == RFOFF_MCU_CMD))
-		{
-			pAd->brt30xxBanMcuCmd = TRUE;
-		}
-		else if (Command != WAKE_MCU_CMD)
-		{
-			pAd->brt30xxBanMcuCmd = FALSE;
-		}
-
-		RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
-
-	}
-	if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
-		&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
-		&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
-		&& (Command == WAKE_MCU_CMD))
-	{
-
-		do
-		{
-			RTMP_IO_FORCE_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
-			if (H2MMailbox.field.Owner == 0)
-				break;
-
-			RTMPusecDelay(2);
-			DBGPRINT(RT_DEBUG_INFO, ("AsicSendCommanToMcu::Mail box is busy\n"));
-		} while(i++ < 100);
-
-		if (i >= 100)
-		{
-			DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
-			return FALSE;
-		}
-
-		H2MMailbox.field.Owner	  = 1;	   // pass ownership to MCU
-		H2MMailbox.field.CmdToken = Token;
-		H2MMailbox.field.HighByte = Arg1;
-		H2MMailbox.field.LowByte  = Arg0;
-		RTMP_IO_FORCE_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
-
-		H2MCmd.word			  = 0;
-		H2MCmd.field.HostCommand  = Command;
-		RTMP_IO_FORCE_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
-
-
-	}
-	else
-#endif // CONFIG_STA_SUPPORT //
-#endif // PCIE_PS_SUPPORT //
-	{
-	do
-	{
-		RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
-		if (H2MMailbox.field.Owner == 0)
-			break;
-
-		RTMPusecDelay(2);
-	} while(i++ < 100);
-
-	if (i >= 100)
-	{
-#ifdef RTMP_MAC_PCI
-#ifdef RALINK_ATE
-		if (pAd->ate.bFWLoading == TRUE)
-		{
-			/* reloading firmware when received iwpriv cmd "ATE=ATESTOP" */
-			if (j > 0)
-			{
-				if (j % 64 != 0)
-				{
-					ATEDBGPRINT(RT_DEBUG_ERROR, ("#"));
-				}
-				else
-				{
-					ATEDBGPRINT(RT_DEBUG_ERROR, ("\n"));
-				}
-				++j;
-			}
-			else if (j == 0)
-			{
-				ATEDBGPRINT(RT_DEBUG_ERROR, ("Loading firmware. Please wait for a moment...\n"));
-				++j;
-			}
-		}
-		else
-#endif // RALINK_ATE //
-#endif // RTMP_MAC_PCI //
-		{
-		DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
-		}
-		return FALSE;
-	}
-
-#ifdef RTMP_MAC_PCI
-#ifdef RALINK_ATE
-	else if (pAd->ate.bFWLoading == TRUE)
-	{
-		/* reloading of firmware is completed */
-		pAd->ate.bFWLoading = FALSE;
-		ATEDBGPRINT(RT_DEBUG_ERROR, ("\n"));
-		j = 0;
-	}
-#endif // RALINK_ATE //
-#endif // RTMP_MAC_PCI //
-
-	H2MMailbox.field.Owner	  = 1;	   // pass ownership to MCU
-	H2MMailbox.field.CmdToken = Token;
-	H2MMailbox.field.HighByte = Arg1;
-	H2MMailbox.field.LowByte  = Arg0;
-	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
-
-	H2MCmd.word			  = 0;
-	H2MCmd.field.HostCommand  = Command;
-	RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
-
-	if (Command != 0x80)
-	{
-	}
-}
-#ifdef PCIE_PS_SUPPORT
-#ifdef CONFIG_STA_SUPPORT
-	// 3090 MCU Wakeup command needs more time to be stable.
-	// Before stable, don't issue other MCU command to prevent from firmware error.
-	if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
-		&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
-		&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
-		&& (Command == WAKE_MCU_CMD))
-	{
-		RTMPusecDelay(2000);
-		//Put this is after RF programming.
-		//NdisAcquireSpinLock(&pAd->McuCmdLock);
-		//pAd->brt30xxBanMcuCmd = FALSE;
-		//NdisReleaseSpinLock(&pAd->McuCmdLock);
-	}
-#endif // CONFIG_STA_SUPPORT //
-#endif // PCIE_PS_SUPPORT //
-
-	return TRUE;
-}
diff --git a/drivers/staging/rt3090/common/rtmp_timer.c b/drivers/staging/rt3090/common/rtmp_timer.c
deleted file mode 100644
index 5253e87..0000000
--- a/drivers/staging/rt3090/common/rtmp_timer.c
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    rtmp_timer.c
-
-    Abstract:
-    task for timer handling
-
-    Revision History:
-    Who         When            What
-    --------    ----------      ----------------------------------------------
-    Name          Date            Modification logs
-    Shiang Tu	08-28-2008   init version
-
-*/
-
-#include "../rt_config.h"
-
-
-BUILD_TIMER_FUNCTION(MlmePeriodicExec);
-//BUILD_TIMER_FUNCTION(MlmeRssiReportExec);
-BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
-BUILD_TIMER_FUNCTION(APSDPeriodicExec);
-BUILD_TIMER_FUNCTION(AsicRfTuningExec);
-
-
-#ifdef CONFIG_STA_SUPPORT
-BUILD_TIMER_FUNCTION(BeaconTimeout);
-BUILD_TIMER_FUNCTION(ScanTimeout);
-BUILD_TIMER_FUNCTION(AuthTimeout);
-BUILD_TIMER_FUNCTION(AssocTimeout);
-BUILD_TIMER_FUNCTION(ReassocTimeout);
-BUILD_TIMER_FUNCTION(DisassocTimeout);
-BUILD_TIMER_FUNCTION(LinkDownExec);
-BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
-BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
-#ifdef RTMP_MAC_PCI
-BUILD_TIMER_FUNCTION(PsPollWakeExec);
-BUILD_TIMER_FUNCTION(RadioOnExec);
-#endif // RTMP_MAC_PCI //
-#ifdef QOS_DLS_SUPPORT
-BUILD_TIMER_FUNCTION(DlsTimeoutAction);
-#endif // QOS_DLS_SUPPORT //
-
-
-#endif // CONFIG_STA_SUPPORT //
-
-
-
-#if defined(AP_LED) || defined(STA_LED)
-extern void LedCtrlMain(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
-BUILD_TIMER_FUNCTION(LedCtrlMain);
-#endif
-
-
-#ifdef RTMP_TIMER_TASK_SUPPORT
-static void RtmpTimerQHandle(RTMP_ADAPTER *pAd)
-{
-#ifndef KTHREAD_SUPPORT
-	int status;
-#endif
-	RALINK_TIMER_STRUCT	*pTimer;
-	RTMP_TIMER_TASK_ENTRY	*pEntry;
-	unsigned long	irqFlag;
-	RTMP_OS_TASK *pTask;
-
-
-	pTask = &pAd->timerTask;
-	while(!pTask->task_killed)
-	{
-		pTimer = NULL;
-
-#ifdef KTHREAD_SUPPORT
-		RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
-#else
-		RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
-#endif
-
-		if (pAd->TimerQ.status == RTMP_TASK_STAT_STOPED)
-			break;
-
-		// event happened.
-		while(pAd->TimerQ.pQHead)
-		{
-			RTMP_INT_LOCK(&pAd->TimerQLock, irqFlag);
-			pEntry = pAd->TimerQ.pQHead;
-			if (pEntry)
-			{
-				pTimer = pEntry->pRaTimer;
-
-				// update pQHead
-				pAd->TimerQ.pQHead = pEntry->pNext;
-				if (pEntry == pAd->TimerQ.pQTail)
-					pAd->TimerQ.pQTail = NULL;
-
-				// return this queue entry to timerQFreeList.
-				pEntry->pNext = pAd->TimerQ.pQPollFreeList;
-				pAd->TimerQ.pQPollFreeList = pEntry;
-			}
-			RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlag);
-
-			if (pTimer)
-			{
-				if ((pTimer->handle != NULL) && (!pAd->PM_FlgSuspend))
-					pTimer->handle(NULL, (PVOID) pTimer->cookie, NULL, pTimer);
-				if ((pTimer->Repeat) && (pTimer->State == FALSE))
-					RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);
-			}
-		}
-
-#ifndef KTHREAD_SUPPORT
-		if (status != 0)
-		{
-			pAd->TimerQ.status = RTMP_TASK_STAT_STOPED;
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-			break;
-		}
-#endif
-	}
-}
-
-
-INT RtmpTimerQThread(
-	IN OUT PVOID Context)
-{
-	RTMP_OS_TASK	*pTask;
-	PRTMP_ADAPTER	pAd;
-
-
-	pTask = (RTMP_OS_TASK *)Context;
-	pAd = (PRTMP_ADAPTER)pTask->priv;
-
-	RtmpOSTaskCustomize(pTask);
-
-	RtmpTimerQHandle(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__));
-#ifndef KTHREAD_SUPPORT
-	pTask->taskPID = THREAD_PID_INIT_VALUE;
-#endif
-	/* notify the exit routine that we're actually exiting now
-	 *
-	 * complete()/wait_for_completion() is similar to up()/down(),
-	 * except that complete() is safe in the case where the structure
-	 * is getting deleted in a parallel mode of execution (i.e. just
-	 * after the down() -- that's necessary for the thread-shutdown
-	 * case.
-	 *
-	 * complete_and_exit() goes even further than this -- it is safe in
-	 * the case that the thread of the caller is going away (not just
-	 * the structure) -- this is necessary for the module-remove case.
-	 * This is important in preemption kernels, which transfer the flow
-	 * of execution immediately upon a complete().
-	 */
-	RtmpOSTaskNotifyToExit(pTask);
-
-	return 0;
-
-}
-
-
-RTMP_TIMER_TASK_ENTRY *RtmpTimerQInsert(
-	IN RTMP_ADAPTER *pAd,
-	IN RALINK_TIMER_STRUCT *pTimer)
-{
-	RTMP_TIMER_TASK_ENTRY *pQNode = NULL, *pQTail;
-	unsigned long irqFlags;
-	RTMP_OS_TASK	*pTask = &pAd->timerTask;
-
-	RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
-	if (pAd->TimerQ.status & RTMP_TASK_CAN_DO_INSERT)
-	{
-		if(pAd->TimerQ.pQPollFreeList)
-		{
-			pQNode = pAd->TimerQ.pQPollFreeList;
-			pAd->TimerQ.pQPollFreeList = pQNode->pNext;
-
-			pQNode->pRaTimer = pTimer;
-			pQNode->pNext = NULL;
-
-			pQTail = pAd->TimerQ.pQTail;
-			if (pAd->TimerQ.pQTail != NULL)
-				pQTail->pNext = pQNode;
-			pAd->TimerQ.pQTail = pQNode;
-			if (pAd->TimerQ.pQHead == NULL)
-				pAd->TimerQ.pQHead = pQNode;
-		}
-	}
-	RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
-
-	if (pQNode)
-	{
-#ifdef KTHREAD_SUPPORT
-		WAKE_UP(pTask);
-#else
-		RTMP_SEM_EVENT_UP(&pTask->taskSema);
-#endif
-	}
-
-	return pQNode;
-}
-
-
-BOOLEAN RtmpTimerQRemove(
-	IN RTMP_ADAPTER *pAd,
-	IN RALINK_TIMER_STRUCT *pTimer)
-{
-	RTMP_TIMER_TASK_ENTRY *pNode, *pPrev = NULL;
-	unsigned long irqFlags;
-
-	RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
-	if (pAd->TimerQ.status >= RTMP_TASK_STAT_INITED)
-	{
-		pNode = pAd->TimerQ.pQHead;
-		while (pNode)
-		{
-			if (pNode->pRaTimer == pTimer)
-				break;
-			pPrev = pNode;
-			pNode = pNode->pNext;
-		}
-
-		// Now move it to freeList queue.
-		if (pNode)
-		{
-			if (pNode == pAd->TimerQ.pQHead)
-				pAd->TimerQ.pQHead = pNode->pNext;
-			if (pNode == pAd->TimerQ.pQTail)
-				pAd->TimerQ.pQTail = pPrev;
-			if (pPrev != NULL)
-				pPrev->pNext = pNode->pNext;
-
-			// return this queue entry to timerQFreeList.
-			pNode->pNext = pAd->TimerQ.pQPollFreeList;
-			pAd->TimerQ.pQPollFreeList = pNode;
-		}
-	}
-	RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
-
-	return TRUE;
-}
-
-
-void RtmpTimerQExit(RTMP_ADAPTER *pAd)
-{
-	RTMP_TIMER_TASK_ENTRY *pTimerQ;
-	unsigned long irqFlags;
-
-	RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
-	while (pAd->TimerQ.pQHead)
-	{
-		pTimerQ = pAd->TimerQ.pQHead;
-		pAd->TimerQ.pQHead = pTimerQ->pNext;
-		// remove the timeQ
-	}
-	pAd->TimerQ.pQPollFreeList = NULL;
-	os_free_mem(pAd, pAd->TimerQ.pTimerQPoll);
-	pAd->TimerQ.pQTail = NULL;
-	pAd->TimerQ.pQHead = NULL;
-#ifndef KTHREAD_SUPPORT
-	pAd->TimerQ.status = RTMP_TASK_STAT_STOPED;
-#endif
-	RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
-
-}
-
-
-void RtmpTimerQInit(RTMP_ADAPTER *pAd)
-{
-	int	i;
-	RTMP_TIMER_TASK_ENTRY *pQNode, *pEntry;
-	unsigned long irqFlags;
-
-	NdisAllocateSpinLock(&pAd->TimerQLock);
-
-	NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ));
-
-	os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll, sizeof(RTMP_TIMER_TASK_ENTRY) * TIMER_QUEUE_SIZE_MAX);
-	if (pAd->TimerQ.pTimerQPoll)
-	{
-		pEntry = NULL;
-		pQNode = (RTMP_TIMER_TASK_ENTRY *)pAd->TimerQ.pTimerQPoll;
-		NdisZeroMemory(pAd->TimerQ.pTimerQPoll, sizeof(RTMP_TIMER_TASK_ENTRY) * TIMER_QUEUE_SIZE_MAX);
-
-		RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
-		for (i = 0 ;i <TIMER_QUEUE_SIZE_MAX; i++)
-		{
-			pQNode->pNext = pEntry;
-			pEntry = pQNode;
-			pQNode++;
-		}
-		pAd->TimerQ.pQPollFreeList = pEntry;
-		pAd->TimerQ.pQHead = NULL;
-		pAd->TimerQ.pQTail = NULL;
-		pAd->TimerQ.status = RTMP_TASK_STAT_INITED;
-		RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
-	}
-}
-#endif // RTMP_TIMER_TASK_SUPPORT //
diff --git a/drivers/staging/rt3090/common/spectrum.c b/drivers/staging/rt3090/common/spectrum.c
deleted file mode 100644
index 12d2125..0000000
--- a/drivers/staging/rt3090/common/spectrum.c
+++ /dev/null
@@ -1,2221 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	action.c
-
-    Abstract:
-    Handle association related requests either from WSTA or from local MLME
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
-	Fonchi Wu    2008		   created for 802.11h
- */
-
-#include "../rt_config.h"
-#include "../action.h"
-
-
-/* The regulatory information in the USA (US) */
-DOT11_REGULATORY_INFORMATION USARegulatoryInfo[] =
-{
-/*  "regulatory class"  "number of channels"  "Max Tx Pwr"  "channel list" */
-    {0,	                {0,                   0,           {0}}}, // Invlid entry
-    {1,                 {4,                   16,           {36, 40, 44, 48}}},
-    {2,                 {4,                   23,           {52, 56, 60, 64}}},
-    {3,                 {4,                   29,           {149, 153, 157, 161}}},
-    {4,                 {11,                  23,           {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}},
-    {5,                 {5,                   30,           {149, 153, 157, 161, 165}}},
-    {6,                 {10,                  14,           {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}},
-    {7,                 {10,                  27,           {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}},
-    {8,                 {5,                   17,           {11, 13, 15, 17, 19}}},
-    {9,                 {5,                   30,           {11, 13, 15, 17, 19}}},
-    {10,                {2,                   20,           {21, 25}}},
-    {11,                {2,                   33,            {21, 25}}},
-    {12,                {11,                  30,            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}}
-};
-#define USA_REGULATORY_INFO_SIZE (sizeof(USARegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION))
-
-
-/* The regulatory information in Europe */
-DOT11_REGULATORY_INFORMATION EuropeRegulatoryInfo[] =
-{
-/*  "regulatory class"  "number of channels"  "Max Tx Pwr"  "channel list" */
-    {0,                 {0,                   0,           {0}}}, // Invalid entry
-    {1,                 {4,                   20,           {36, 40, 44, 48}}},
-    {2,                 {4,                   20,           {52, 56, 60, 64}}},
-    {3,                 {11,                  30,           {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}},
-    {4,                 {13,                  20,           {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}}
-};
-#define EU_REGULATORY_INFO_SIZE (sizeof(EuropeRegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION))
-
-
-/* The regulatory information in Japan */
-DOT11_REGULATORY_INFORMATION JapanRegulatoryInfo[] =
-{
-/*  "regulatory class"  "number of channels"  "Max Tx Pwr"  "channel list" */
-    {0,                 {0,                   0,           {0}}}, // Invalid entry
-    {1,                 {4,                   22,           {34, 38, 42, 46}}},
-    {2,                 {3,                   24,           {8, 12, 16}}},
-    {3,                 {3,                   24,           {8, 12, 16}}},
-    {4,                 {3,                   24,           {8, 12, 16}}},
-    {5,                 {3,                   24,           {8, 12, 16}}},
-    {6,                 {3,                   22,           {8, 12, 16}}},
-    {7,                 {4,                   24,           {184, 188, 192, 196}}},
-    {8,                 {4,                   24,           {184, 188, 192, 196}}},
-    {9,                 {4,                   24,           {184, 188, 192, 196}}},
-    {10,                {4,                   24,           {184, 188, 192, 196}}},
-    {11,                {4,                   22,           {184, 188, 192, 196}}},
-    {12,                {4,                   24,           {7, 8, 9, 11}}},
-    {13,                {4,                   24,           {7, 8, 9, 11}}},
-    {14,                {4,                   24,           {7, 8, 9, 11}}},
-    {15,                {4,                   24,           {7, 8, 9, 11}}},
-    {16,                {6,                   24,           {183, 184, 185, 187, 188, 189}}},
-    {17,                {6,                   24,           {183, 184, 185, 187, 188, 189}}},
-    {18,                {6,                   24,           {183, 184, 185, 187, 188, 189}}},
-    {19,                {6,                   24,           {183, 184, 185, 187, 188, 189}}},
-    {20,                {6,                   17,           {183, 184, 185, 187, 188, 189}}},
-    {21,                {6,                   24,           {6, 7, 8, 9, 10, 11}}},
-    {22,                {6,                   24,           {6, 7, 8, 9, 10, 11}}},
-    {23,                {6,                   24,           {6, 7, 8, 9, 10, 11}}},
-    {24,                {6,                   24,           {6, 7, 8, 9, 10, 11}}},
-    {25,                {8,                   24,           {182, 183, 184, 185, 186, 187, 188, 189}}},
-    {26,                {8,                   24,           {182, 183, 184, 185, 186, 187, 188, 189}}},
-    {27,                {8,                   24,           {182, 183, 184, 185, 186, 187, 188, 189}}},
-    {28,                {8,                   24,           {182, 183, 184, 185, 186, 187, 188, 189}}},
-    {29,                {8,                   17,           {182, 183, 184, 185, 186, 187, 188, 189}}},
-    {30,                {13,                  23,           {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}},
-    {31,                {1,                   23,           {14}}},
-    {32,                {4,                   22,           {52, 56, 60, 64}}}
-};
-#define JP_REGULATORY_INFO_SIZE (sizeof(JapanRegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION))
-
-
-CHAR RTMP_GetTxPwr(
-	IN PRTMP_ADAPTER pAd,
-	IN HTTRANSMIT_SETTING HTTxMode)
-{
-typedef struct __TX_PWR_CFG
-{
-	UINT8 Mode;
-	UINT8 MCS;
-	UINT16 req;
-	UINT8 shift;
-	UINT32 BitMask;
-} TX_PWR_CFG;
-
-	UINT32 Value;
-	INT Idx;
-	UINT8 PhyMode;
-	CHAR CurTxPwr;
-	UINT8 TxPwrRef = 0;
-	CHAR DaltaPwr;
-	ULONG TxPwr[5];
-
-
-	TX_PWR_CFG TxPwrCfg[] = {
-		{MODE_CCK, 0, 0, 4, 0x000000f0},
-		{MODE_CCK, 1, 0, 0, 0x0000000f},
-		{MODE_CCK, 2, 0, 12, 0x0000f000},
-		{MODE_CCK, 3, 0, 8, 0x00000f00},
-
-		{MODE_OFDM, 0, 0, 20, 0x00f00000},
-		{MODE_OFDM, 1, 0, 16, 0x000f0000},
-		{MODE_OFDM, 2, 0, 28, 0xf0000000},
-		{MODE_OFDM, 3, 0, 24, 0x0f000000},
-		{MODE_OFDM, 4, 1, 4, 0x000000f0},
-		{MODE_OFDM, 5, 1, 0, 0x0000000f},
-		{MODE_OFDM, 6, 1, 12, 0x0000f000},
-		{MODE_OFDM, 7, 1, 8, 0x00000f00}
-#ifdef DOT11_N_SUPPORT
-		,{MODE_HTMIX, 0, 1, 20, 0x00f00000},
-		{MODE_HTMIX, 1, 1, 16, 0x000f0000},
-		{MODE_HTMIX, 2, 1, 28, 0xf0000000},
-		{MODE_HTMIX, 3, 1, 24, 0x0f000000},
-		{MODE_HTMIX, 4, 2, 4, 0x000000f0},
-		{MODE_HTMIX, 5, 2, 0, 0x0000000f},
-		{MODE_HTMIX, 6, 2, 12, 0x0000f000},
-		{MODE_HTMIX, 7, 2, 8, 0x00000f00},
-		{MODE_HTMIX, 8, 2, 20, 0x00f00000},
-		{MODE_HTMIX, 9, 2, 16, 0x000f0000},
-		{MODE_HTMIX, 10, 2, 28, 0xf0000000},
-		{MODE_HTMIX, 11, 2, 24, 0x0f000000},
-		{MODE_HTMIX, 12, 3, 4, 0x000000f0},
-		{MODE_HTMIX, 13, 3, 0, 0x0000000f},
-		{MODE_HTMIX, 14, 3, 12, 0x0000f000},
-		{MODE_HTMIX, 15, 3, 8, 0x00000f00}
-#endif // DOT11_N_SUPPORT //
-	};
-#define MAX_TXPWR_TAB_SIZE (sizeof(TxPwrCfg) / sizeof(TX_PWR_CFG))
-
-#ifdef SINGLE_SKU
-	CurTxPwr = pAd->CommonCfg.DefineMaxTxPwr;
-#else
-	CurTxPwr = 19;
-#endif
-
-	/* check Tx Power setting from UI. */
-	if (pAd->CommonCfg.TxPowerPercentage > 90)
-		;
-	else if (pAd->CommonCfg.TxPowerPercentage > 60)  /* reduce Pwr for 1 dB. */
-		CurTxPwr -= 1;
-	else if (pAd->CommonCfg.TxPowerPercentage > 30)  /* reduce Pwr for 3 dB. */
-		CurTxPwr -= 3;
-	else if (pAd->CommonCfg.TxPowerPercentage > 15)  /* reduce Pwr for 6 dB. */
-		CurTxPwr -= 6;
-	else if (pAd->CommonCfg.TxPowerPercentage > 9)   /* reduce Pwr for 9 dB. */
-		CurTxPwr -= 9;
-	else                                           /* reduce Pwr for 12 dB. */
-		CurTxPwr -= 12;
-
-	if (pAd->CommonCfg.BBPCurrentBW == BW_40)
-	{
-		if (pAd->CommonCfg.CentralChannel > 14)
-		{
-			TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
-			TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
-			TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
-			TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
-			TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
-		}
-		else
-		{
-			TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
-			TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
-			TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
-			TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
-			TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
-		}
-	}
-	else
-	{
-		if (pAd->CommonCfg.Channel > 14)
-		{
-			TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
-			TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
-			TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
-			TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
-			TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
-		}
-		else
-		{
-			TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
-			TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
-			TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
-			TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
-			TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
-		}
-	}
-
-
-	switch(HTTxMode.field.MODE)
-	{
-		case MODE_CCK:
-		case MODE_OFDM:
-			Value = TxPwr[1];
-			TxPwrRef = (Value & 0x00000f00) >> 8;
-
-			break;
-
-#ifdef DOT11_N_SUPPORT
-		case MODE_HTMIX:
-		case MODE_HTGREENFIELD:
-			if (pAd->CommonCfg.TxStream == 1)
-			{
-				Value = TxPwr[2];
-				TxPwrRef = (Value & 0x00000f00) >> 8;
-			}
-			else if (pAd->CommonCfg.TxStream == 2)
-			{
-				Value = TxPwr[3];
-				TxPwrRef = (Value & 0x00000f00) >> 8;
-			}
-			break;
-#endif // DOT11_N_SUPPORT //
-	}
-
-	PhyMode =
-#ifdef DOT11_N_SUPPORT
-				(HTTxMode.field.MODE == MODE_HTGREENFIELD)
-				? MODE_HTMIX :
-#endif // DOT11_N_SUPPORT //
-				HTTxMode.field.MODE;
-
-	for (Idx = 0; Idx < MAX_TXPWR_TAB_SIZE; Idx++)
-	{
-		if ((TxPwrCfg[Idx].Mode == PhyMode)
-			&& (TxPwrCfg[Idx].MCS == HTTxMode.field.MCS))
-		{
-			Value = TxPwr[TxPwrCfg[Idx].req];
-			DaltaPwr = TxPwrRef - (CHAR)((Value & TxPwrCfg[Idx].BitMask)
-											>> TxPwrCfg[Idx].shift);
-			CurTxPwr -= DaltaPwr;
-			break;
-		}
-	}
-
-	return CurTxPwr;
-}
-
-
-VOID MeasureReqTabInit(
-	IN PRTMP_ADAPTER pAd)
-{
-	NdisAllocateSpinLock(&pAd->CommonCfg.MeasureReqTabLock);
-
-	pAd->CommonCfg.pMeasureReqTab = kmalloc(sizeof(MEASURE_REQ_TAB), GFP_ATOMIC);
-	if (pAd->CommonCfg.pMeasureReqTab)
-		NdisZeroMemory(pAd->CommonCfg.pMeasureReqTab, sizeof(MEASURE_REQ_TAB));
-	else
-		DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pMeasureReqTab.\n", __FUNCTION__));
-
-	return;
-}
-
-VOID MeasureReqTabExit(
-	IN PRTMP_ADAPTER pAd)
-{
-	NdisFreeSpinLock(&pAd->CommonCfg.MeasureReqTabLock);
-
-	if (pAd->CommonCfg.pMeasureReqTab)
-		kfree(pAd->CommonCfg.pMeasureReqTab);
-	pAd->CommonCfg.pMeasureReqTab = NULL;
-
-	return;
-}
-
-PMEASURE_REQ_ENTRY MeasureReqLookUp(
-	IN PRTMP_ADAPTER	pAd,
-	IN UINT8			DialogToken)
-{
-	UINT HashIdx;
-	PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
-	PMEASURE_REQ_ENTRY pEntry = NULL;
-	PMEASURE_REQ_ENTRY pPrevEntry = NULL;
-
-	if (pTab == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__));
-		return NULL;
-	}
-
-	RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
-
-	HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
-	pEntry = pTab->Hash[HashIdx];
-
-	while (pEntry)
-	{
-		if (pEntry->DialogToken == DialogToken)
-			break;
-		else
-		{
-			pPrevEntry = pEntry;
-			pEntry = pEntry->pNext;
-		}
-	}
-
-	RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
-
-	return pEntry;
-}
-
-PMEASURE_REQ_ENTRY MeasureReqInsert(
-	IN PRTMP_ADAPTER	pAd,
-	IN UINT8			DialogToken)
-{
-	INT i;
-	ULONG HashIdx;
-	PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
-	PMEASURE_REQ_ENTRY pEntry = NULL, pCurrEntry;
-	ULONG Now;
-
-	if(pTab == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__));
-		return NULL;
-	}
-
-	pEntry = MeasureReqLookUp(pAd, DialogToken);
-	if (pEntry == NULL)
-	{
-		RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
-		for (i = 0; i < MAX_MEASURE_REQ_TAB_SIZE; i++)
-		{
-			NdisGetSystemUpTime(&Now);
-			pEntry = &pTab->Content[i];
-
-			if ((pEntry->Valid == TRUE)
-				&& RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + MQ_REQ_AGE_OUT)))
-			{
-				PMEASURE_REQ_ENTRY pPrevEntry = NULL;
-				ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
-				PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
-
-				// update Hash list
-				do
-				{
-					if (pProbeEntry == pEntry)
-					{
-						if (pPrevEntry == NULL)
-						{
-							pTab->Hash[HashIdx] = pEntry->pNext;
-						}
-						else
-						{
-							pPrevEntry->pNext = pEntry->pNext;
-						}
-						break;
-					}
-
-					pPrevEntry = pProbeEntry;
-					pProbeEntry = pProbeEntry->pNext;
-				} while (pProbeEntry);
-
-				NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY));
-				pTab->Size--;
-
-				break;
-			}
-
-			if (pEntry->Valid == FALSE)
-				break;
-		}
-
-		if (i < MAX_MEASURE_REQ_TAB_SIZE)
-		{
-			NdisGetSystemUpTime(&Now);
-			pEntry->lastTime = Now;
-			pEntry->Valid = TRUE;
-			pEntry->DialogToken = DialogToken;
-			pTab->Size++;
-		}
-		else
-		{
-			pEntry = NULL;
-			DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab tab full.\n", __FUNCTION__));
-		}
-
-		// add this Neighbor entry into HASH table
-		if (pEntry)
-		{
-			HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
-			if (pTab->Hash[HashIdx] == NULL)
-			{
-				pTab->Hash[HashIdx] = pEntry;
-			}
-			else
-			{
-				pCurrEntry = pTab->Hash[HashIdx];
-				while (pCurrEntry->pNext != NULL)
-					pCurrEntry = pCurrEntry->pNext;
-				pCurrEntry->pNext = pEntry;
-			}
-		}
-
-		RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
-	}
-
-	return pEntry;
-}
-
-VOID MeasureReqDelete(
-	IN PRTMP_ADAPTER	pAd,
-	IN UINT8			DialogToken)
-{
-	PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
-	PMEASURE_REQ_ENTRY pEntry = NULL;
-
-	if(pTab == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__));
-		return;
-	}
-
-	// if empty, return
-	if (pTab->Size == 0)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("pMeasureReqTab empty.\n"));
-		return;
-	}
-
-	pEntry = MeasureReqLookUp(pAd, DialogToken);
-	if (pEntry != NULL)
-	{
-		PMEASURE_REQ_ENTRY pPrevEntry = NULL;
-		ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
-		PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
-
-		RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
-		// update Hash list
-		do
-		{
-			if (pProbeEntry == pEntry)
-			{
-				if (pPrevEntry == NULL)
-				{
-					pTab->Hash[HashIdx] = pEntry->pNext;
-				}
-				else
-				{
-					pPrevEntry->pNext = pEntry->pNext;
-				}
-				break;
-			}
-
-			pPrevEntry = pProbeEntry;
-			pProbeEntry = pProbeEntry->pNext;
-		} while (pProbeEntry);
-
-		NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY));
-		pTab->Size--;
-
-		RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
-	}
-
-	return;
-}
-
-VOID TpcReqTabInit(
-	IN PRTMP_ADAPTER pAd)
-{
-	NdisAllocateSpinLock(&pAd->CommonCfg.TpcReqTabLock);
-
-	pAd->CommonCfg.pTpcReqTab = kmalloc(sizeof(TPC_REQ_TAB), GFP_ATOMIC);
-	if (pAd->CommonCfg.pTpcReqTab)
-		NdisZeroMemory(pAd->CommonCfg.pTpcReqTab, sizeof(TPC_REQ_TAB));
-	else
-		DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pTpcReqTab.\n", __FUNCTION__));
-
-	return;
-}
-
-VOID TpcReqTabExit(
-	IN PRTMP_ADAPTER pAd)
-{
-	NdisFreeSpinLock(&pAd->CommonCfg.TpcReqTabLock);
-
-	if (pAd->CommonCfg.pTpcReqTab)
-		kfree(pAd->CommonCfg.pTpcReqTab);
-	pAd->CommonCfg.pTpcReqTab = NULL;
-
-	return;
-}
-
-static PTPC_REQ_ENTRY TpcReqLookUp(
-	IN PRTMP_ADAPTER	pAd,
-	IN UINT8			DialogToken)
-{
-	UINT HashIdx;
-	PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
-	PTPC_REQ_ENTRY pEntry = NULL;
-	PTPC_REQ_ENTRY pPrevEntry = NULL;
-
-	if (pTab == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__));
-		return NULL;
-	}
-
-	RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
-
-	HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
-	pEntry = pTab->Hash[HashIdx];
-
-	while (pEntry)
-	{
-		if (pEntry->DialogToken == DialogToken)
-			break;
-		else
-		{
-			pPrevEntry = pEntry;
-			pEntry = pEntry->pNext;
-		}
-	}
-
-	RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
-
-	return pEntry;
-}
-
-
-static PTPC_REQ_ENTRY TpcReqInsert(
-	IN PRTMP_ADAPTER	pAd,
-	IN UINT8			DialogToken)
-{
-	INT i;
-	ULONG HashIdx;
-	PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
-	PTPC_REQ_ENTRY pEntry = NULL, pCurrEntry;
-	ULONG Now;
-
-	if(pTab == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__));
-		return NULL;
-	}
-
-	pEntry = TpcReqLookUp(pAd, DialogToken);
-	if (pEntry == NULL)
-	{
-		RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
-		for (i = 0; i < MAX_TPC_REQ_TAB_SIZE; i++)
-		{
-			NdisGetSystemUpTime(&Now);
-			pEntry = &pTab->Content[i];
-
-			if ((pEntry->Valid == TRUE)
-				&& RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + TPC_REQ_AGE_OUT)))
-			{
-				PTPC_REQ_ENTRY pPrevEntry = NULL;
-				ULONG HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
-				PTPC_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
-
-				// update Hash list
-				do
-				{
-					if (pProbeEntry == pEntry)
-					{
-						if (pPrevEntry == NULL)
-						{
-							pTab->Hash[HashIdx] = pEntry->pNext;
-						}
-						else
-						{
-							pPrevEntry->pNext = pEntry->pNext;
-						}
-						break;
-					}
-
-					pPrevEntry = pProbeEntry;
-					pProbeEntry = pProbeEntry->pNext;
-				} while (pProbeEntry);
-
-				NdisZeroMemory(pEntry, sizeof(TPC_REQ_ENTRY));
-				pTab->Size--;
-
-				break;
-			}
-
-			if (pEntry->Valid == FALSE)
-				break;
-		}
-
-		if (i < MAX_TPC_REQ_TAB_SIZE)
-		{
-			NdisGetSystemUpTime(&Now);
-			pEntry->lastTime = Now;
-			pEntry->Valid = TRUE;
-			pEntry->DialogToken = DialogToken;
-			pTab->Size++;
-		}
-		else
-		{
-			pEntry = NULL;
-			DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab tab full.\n", __FUNCTION__));
-		}
-
-		// add this Neighbor entry into HASH table
-		if (pEntry)
-		{
-			HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
-			if (pTab->Hash[HashIdx] == NULL)
-			{
-				pTab->Hash[HashIdx] = pEntry;
-			}
-			else
-			{
-				pCurrEntry = pTab->Hash[HashIdx];
-				while (pCurrEntry->pNext != NULL)
-					pCurrEntry = pCurrEntry->pNext;
-				pCurrEntry->pNext = pEntry;
-			}
-		}
-
-		RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
-	}
-
-	return pEntry;
-}
-
-static VOID TpcReqDelete(
-	IN PRTMP_ADAPTER	pAd,
-	IN UINT8			DialogToken)
-{
-	PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
-	PTPC_REQ_ENTRY pEntry = NULL;
-
-	if(pTab == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__));
-		return;
-	}
-
-	// if empty, return
-	if (pTab->Size == 0)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("pTpcReqTab empty.\n"));
-		return;
-	}
-
-	pEntry = TpcReqLookUp(pAd, DialogToken);
-	if (pEntry != NULL)
-	{
-		PTPC_REQ_ENTRY pPrevEntry = NULL;
-		ULONG HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
-		PTPC_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
-
-		RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
-		// update Hash list
-		do
-		{
-			if (pProbeEntry == pEntry)
-			{
-				if (pPrevEntry == NULL)
-				{
-					pTab->Hash[HashIdx] = pEntry->pNext;
-				}
-				else
-				{
-					pPrevEntry->pNext = pEntry->pNext;
-				}
-				break;
-			}
-
-			pPrevEntry = pProbeEntry;
-			pProbeEntry = pProbeEntry->pNext;
-		} while (pProbeEntry);
-
-		NdisZeroMemory(pEntry, sizeof(TPC_REQ_ENTRY));
-		pTab->Size--;
-
-		RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
-	}
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Get Current TimeS tamp.
-
-	Parametrs:
-
-	Return	: Current Time Stamp.
-	==========================================================================
- */
-static UINT64 GetCurrentTimeStamp(
-	IN PRTMP_ADAPTER pAd)
-{
-	// get current time stamp.
-	return 0;
-}
-
-/*
-	==========================================================================
-	Description:
-		Get Current Transmit Power.
-
-	Parametrs:
-
-	Return	: Current Time Stamp.
-	==========================================================================
- */
-static UINT8 GetCurTxPwr(
-	IN PRTMP_ADAPTER pAd,
-	IN UINT8 Wcid)
-{
-	return 16; /* 16 dBm */
-}
-
-/*
-	==========================================================================
-	Description:
-		Get Current Transmit Power.
-
-	Parametrs:
-
-	Return	: Current Time Stamp.
-	==========================================================================
- */
-VOID InsertChannelRepIE(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pFrameBuf,
-	OUT PULONG pFrameLen,
-	IN PSTRING pCountry,
-	IN UINT8 RegulatoryClass)
-{
-	ULONG TempLen;
-	UINT8 Len;
-	UINT8 IEId = IE_AP_CHANNEL_REPORT;
-	PUCHAR pChListPtr = NULL;
-
-	Len = 1;
-	if (strncmp(pCountry, "US", 2) == 0)
-	{
-		if (RegulatoryClass >= USA_REGULATORY_INFO_SIZE)
-		{
-			DBGPRINT(RT_DEBUG_ERROR, ("%s: USA Unknow Requlatory class (%d)\n",
-						__FUNCTION__, RegulatoryClass));
-			return;
-		}
-
-		Len += USARegulatoryInfo[RegulatoryClass].ChannelSet.NumberOfChannels;
-		pChListPtr = USARegulatoryInfo[RegulatoryClass].ChannelSet.ChannelList;
-	}
-	else if (strncmp(pCountry, "JP", 2) == 0)
-	{
-		if (RegulatoryClass >= JP_REGULATORY_INFO_SIZE)
-		{
-			DBGPRINT(RT_DEBUG_ERROR, ("%s: JP Unknow Requlatory class (%d)\n",
-						__FUNCTION__, RegulatoryClass));
-			return;
-		}
-
-		Len += JapanRegulatoryInfo[RegulatoryClass].ChannelSet.NumberOfChannels;
-		pChListPtr = JapanRegulatoryInfo[RegulatoryClass].ChannelSet.ChannelList;
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknow Country (%s)\n",
-					__FUNCTION__, pCountry));
-		return;
-	}
-
-	MakeOutgoingFrame(pFrameBuf,	&TempLen,
-					1,				&IEId,
-					1,				&Len,
-					1,				&RegulatoryClass,
-					Len -1,			pChListPtr,
-					END_OF_ARGS);
-
-	*pFrameLen = *pFrameLen + TempLen;
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Insert Dialog Token into frame.
-
-	Parametrs:
-		1. frame buffer pointer.
-		2. frame length.
-		3. Dialog token.
-
-	Return	: None.
-	==========================================================================
- */
-VOID InsertDialogToken(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pFrameBuf,
-	OUT PULONG pFrameLen,
-	IN UINT8 DialogToken)
-{
-	ULONG TempLen;
-	MakeOutgoingFrame(pFrameBuf,	&TempLen,
-					1,				&DialogToken,
-					END_OF_ARGS);
-
-	*pFrameLen = *pFrameLen + TempLen;
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Insert TPC Request IE into frame.
-
-	Parametrs:
-		1. frame buffer pointer.
-		2. frame length.
-
-	Return	: None.
-	==========================================================================
- */
- static VOID InsertTpcReqIE(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pFrameBuf,
-	OUT PULONG pFrameLen)
-{
-	ULONG TempLen;
-	ULONG Len = 0;
-	UINT8 ElementID = IE_TPC_REQUEST;
-
-	MakeOutgoingFrame(pFrameBuf,					&TempLen,
-						1,							&ElementID,
-						1,							&Len,
-						END_OF_ARGS);
-
-	*pFrameLen = *pFrameLen + TempLen;
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Insert TPC Report IE into frame.
-
-	Parametrs:
-		1. frame buffer pointer.
-		2. frame length.
-		3. Transmit Power.
-		4. Link Margin.
-
-	Return	: None.
-	==========================================================================
- */
-VOID InsertTpcReportIE(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pFrameBuf,
-	OUT PULONG pFrameLen,
-	IN UINT8 TxPwr,
-	IN UINT8 LinkMargin)
-{
-	ULONG TempLen;
-	ULONG Len = sizeof(TPC_REPORT_INFO);
-	UINT8 ElementID = IE_TPC_REPORT;
-	TPC_REPORT_INFO TpcReportIE;
-
-	TpcReportIE.TxPwr = TxPwr;
-	TpcReportIE.LinkMargin = LinkMargin;
-
-	MakeOutgoingFrame(pFrameBuf,					&TempLen,
-						1,							&ElementID,
-						1,							&Len,
-						Len,						&TpcReportIE,
-						END_OF_ARGS);
-
-	*pFrameLen = *pFrameLen + TempLen;
-
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Insert Channel Switch Announcement IE into frame.
-
-	Parametrs:
-		1. frame buffer pointer.
-		2. frame length.
-		3. channel switch announcement mode.
-		4. new selected channel.
-		5. channel switch announcement count.
-
-	Return	: None.
-	==========================================================================
- */
-static VOID InsertChSwAnnIE(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pFrameBuf,
-	OUT PULONG pFrameLen,
-	IN UINT8 ChSwMode,
-	IN UINT8 NewChannel,
-	IN UINT8 ChSwCnt)
-{
-	ULONG TempLen;
-	ULONG Len = sizeof(CH_SW_ANN_INFO);
-	UINT8 ElementID = IE_CHANNEL_SWITCH_ANNOUNCEMENT;
-	CH_SW_ANN_INFO ChSwAnnIE;
-
-	ChSwAnnIE.ChSwMode = ChSwMode;
-	ChSwAnnIE.Channel = NewChannel;
-	ChSwAnnIE.ChSwCnt = ChSwCnt;
-
-	MakeOutgoingFrame(pFrameBuf,				&TempLen,
-						1,						&ElementID,
-						1,						&Len,
-						Len,					&ChSwAnnIE,
-						END_OF_ARGS);
-
-	*pFrameLen = *pFrameLen + TempLen;
-
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Insert Measure Request IE into frame.
-
-	Parametrs:
-		1. frame buffer pointer.
-		2. frame length.
-		3. Measure Token.
-		4. Measure Request Mode.
-		5. Measure Request Type.
-		6. Measure Channel.
-		7. Measure Start time.
-		8. Measure Duration.
-
-
-	Return	: None.
-	==========================================================================
- */
-static VOID InsertMeasureReqIE(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pFrameBuf,
-	OUT PULONG pFrameLen,
-	IN UINT8 Len,
-	IN PMEASURE_REQ_INFO pMeasureReqIE)
-{
-	ULONG TempLen;
-	UINT8 ElementID = IE_MEASUREMENT_REQUEST;
-
-	MakeOutgoingFrame(pFrameBuf,					&TempLen,
-						1,							&ElementID,
-						1,							&Len,
-						sizeof(MEASURE_REQ_INFO),	pMeasureReqIE,
-						END_OF_ARGS);
-
-	*pFrameLen = *pFrameLen + TempLen;
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Insert Measure Report IE into frame.
-
-	Parametrs:
-		1. frame buffer pointer.
-		2. frame length.
-		3. Measure Token.
-		4. Measure Request Mode.
-		5. Measure Request Type.
-		6. Length of Report Infomation
-		7. Pointer of Report Infomation Buffer.
-
-	Return	: None.
-	==========================================================================
- */
-static VOID InsertMeasureReportIE(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pFrameBuf,
-	OUT PULONG pFrameLen,
-	IN PMEASURE_REPORT_INFO pMeasureReportIE,
-	IN UINT8 ReportLnfoLen,
-	IN PUINT8 pReportInfo)
-{
-	ULONG TempLen;
-	ULONG Len;
-	UINT8 ElementID = IE_MEASUREMENT_REPORT;
-
-	Len = sizeof(MEASURE_REPORT_INFO) + ReportLnfoLen;
-
-	MakeOutgoingFrame(pFrameBuf,					&TempLen,
-						1,							&ElementID,
-						1,							&Len,
-						Len,						pMeasureReportIE,
-						END_OF_ARGS);
-
-	*pFrameLen = *pFrameLen + TempLen;
-
-	if ((ReportLnfoLen > 0) && (pReportInfo != NULL))
-	{
-		MakeOutgoingFrame(pFrameBuf + *pFrameLen,		&TempLen,
-							ReportLnfoLen,				pReportInfo,
-							END_OF_ARGS);
-
-		*pFrameLen = *pFrameLen + TempLen;
-	}
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Prepare Measurement request action frame and enqueue it into
-		management queue waiting for transmition.
-
-	Parametrs:
-		1. the destination mac address of the frame.
-
-	Return	: None.
-	==========================================================================
- */
-VOID MakeMeasurementReqFrame(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pOutBuffer,
-	OUT PULONG pFrameLen,
-	IN UINT8 TotalLen,
-	IN UINT8 Category,
-	IN UINT8 Action,
-	IN UINT8 MeasureToken,
-	IN UINT8 MeasureReqMode,
-	IN UINT8 MeasureReqType,
-	IN UINT8 NumOfRepetitions)
-{
-	ULONG TempLen;
-	MEASURE_REQ_INFO MeasureReqIE;
-
-	InsertActField(pAd, (pOutBuffer + *pFrameLen), pFrameLen, Category, Action);
-
-	// fill Dialog Token
-	InsertDialogToken(pAd, (pOutBuffer + *pFrameLen), pFrameLen, MeasureToken);
-
-	/* fill Number of repetitions. */
-	if (Category == CATEGORY_RM)
-	{
-		MakeOutgoingFrame((pOutBuffer+*pFrameLen),	&TempLen,
-						2,							&NumOfRepetitions,
-						END_OF_ARGS);
-
-		*pFrameLen += TempLen;
-	}
-
-	// prepare Measurement IE.
-	NdisZeroMemory(&MeasureReqIE, sizeof(MEASURE_REQ_INFO));
-	MeasureReqIE.Token = MeasureToken;
-	MeasureReqIE.ReqMode.word = MeasureReqMode;
-	MeasureReqIE.ReqType = MeasureReqType;
-	InsertMeasureReqIE(pAd, (pOutBuffer+*pFrameLen), pFrameLen,
-		TotalLen, &MeasureReqIE);
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Prepare Measurement report action frame and enqueue it into
-		management queue waiting for transmition.
-
-	Parametrs:
-		1. the destination mac address of the frame.
-
-	Return	: None.
-	==========================================================================
- */
-VOID EnqueueMeasurementRep(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDA,
-	IN UINT8 DialogToken,
-	IN UINT8 MeasureToken,
-	IN UINT8 MeasureReqMode,
-	IN UINT8 MeasureReqType,
-	IN UINT8 ReportInfoLen,
-	IN PUINT8 pReportInfo)
-{
-	PUCHAR pOutBuffer = NULL;
-	NDIS_STATUS NStatus;
-	ULONG FrameLen;
-	HEADER_802_11 ActHdr;
-	MEASURE_REPORT_INFO MeasureRepIE;
-
-	// build action frame header.
-	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
-						pAd->CurrentAddress);
-
-	NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
-	if(NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
-		return;
-	}
-	NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
-	FrameLen = sizeof(HEADER_802_11);
-
-	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_MRP);
-
-	// fill Dialog Token
-	InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
-
-	// prepare Measurement IE.
-	NdisZeroMemory(&MeasureRepIE, sizeof(MEASURE_REPORT_INFO));
-	MeasureRepIE.Token = MeasureToken;
-	MeasureRepIE.ReportMode = MeasureReqMode;
-	MeasureRepIE.ReportType = MeasureReqType;
-	InsertMeasureReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureRepIE, ReportInfoLen, pReportInfo);
-
-	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Prepare TPC Request action frame and enqueue it into
-		management queue waiting for transmition.
-
-	Parametrs:
-		1. the destination mac address of the frame.
-
-	Return	: None.
-	==========================================================================
- */
-VOID EnqueueTPCReq(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDA,
-	IN UCHAR DialogToken)
-{
-	PUCHAR pOutBuffer = NULL;
-	NDIS_STATUS NStatus;
-	ULONG FrameLen;
-
-	HEADER_802_11 ActHdr;
-
-	// build action frame header.
-	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
-						pAd->CurrentAddress);
-
-	NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
-	if(NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
-		return;
-	}
-	NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
-	FrameLen = sizeof(HEADER_802_11);
-
-	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_TPCRQ);
-
-	// fill Dialog Token
-	InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
-
-	// Insert TPC Request IE.
-	InsertTpcReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen);
-
-	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Prepare TPC Report action frame and enqueue it into
-		management queue waiting for transmition.
-
-	Parametrs:
-		1. the destination mac address of the frame.
-
-	Return	: None.
-	==========================================================================
- */
-VOID EnqueueTPCRep(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDA,
-	IN UINT8 DialogToken,
-	IN UINT8 TxPwr,
-	IN UINT8 LinkMargin)
-{
-	PUCHAR pOutBuffer = NULL;
-	NDIS_STATUS NStatus;
-	ULONG FrameLen;
-
-	HEADER_802_11 ActHdr;
-
-	// build action frame header.
-	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
-						pAd->CurrentAddress);
-
-	NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
-	if(NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
-		return;
-	}
-	NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
-	FrameLen = sizeof(HEADER_802_11);
-
-	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_TPCRP);
-
-	// fill Dialog Token
-	InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
-
-	// Insert TPC Request IE.
-	InsertTpcReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, TxPwr, LinkMargin);
-
-	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Prepare Channel Switch Announcement action frame and enqueue it into
-		management queue waiting for transmition.
-
-	Parametrs:
-		1. the destination mac address of the frame.
-		2. Channel switch announcement mode.
-		2. a New selected channel.
-
-	Return	: None.
-	==========================================================================
- */
-VOID EnqueueChSwAnn(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDA,
-	IN UINT8 ChSwMode,
-	IN UINT8 NewCh)
-{
-	PUCHAR pOutBuffer = NULL;
-	NDIS_STATUS NStatus;
-	ULONG FrameLen;
-
-	HEADER_802_11 ActHdr;
-
-	// build action frame header.
-	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
-						pAd->CurrentAddress);
-
-	NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
-	if(NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
-		return;
-	}
-	NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
-	FrameLen = sizeof(HEADER_802_11);
-
-	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_CHANNEL_SWITCH);
-
-	InsertChSwAnnIE(pAd, (pOutBuffer + FrameLen), &FrameLen, ChSwMode, NewCh, 0);
-
-	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-	return;
-}
-
-static BOOLEAN DfsRequirementCheck(
-	IN PRTMP_ADAPTER pAd,
-	IN UINT8 Channel)
-{
-	BOOLEAN Result = FALSE;
-	INT i;
-
-	do
-	{
-		// check DFS procedure is running.
-		// make sure DFS procedure won't start twice.
-		if (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
-		{
-			Result = FALSE;
-			break;
-		}
-
-		// check the new channel carried from Channel Switch Announcemnet is valid.
-		for (i=0; i<pAd->ChannelListNum; i++)
-		{
-			if ((Channel == pAd->ChannelList[i].Channel)
-				&&(pAd->ChannelList[i].RemainingTimeForUse == 0))
-			{
-				// found radar signal in the channel. the channel can't use at least for 30 minutes.
-				pAd->ChannelList[i].RemainingTimeForUse = 1800;//30 min = 1800 sec
-				Result = TRUE;
-				break;
-			}
-		}
-	} while(FALSE);
-
-	return Result;
-}
-
-VOID NotifyChSwAnnToPeerAPs(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pRA,
-	IN PUCHAR pTA,
-	IN UINT8 ChSwMode,
-	IN UINT8 Channel)
-{
-#ifdef WDS_SUPPORT
-	if (!((pRA[0] & 0xff) == 0xff)) // is pRA a broadcase address.
-	{
-		INT i;
-		// info neighbor APs that Radar signal found throgh WDS link.
-		for (i = 0; i < MAX_WDS_ENTRY; i++)
-		{
-			if (ValidWdsEntry(pAd, i))
-			{
-				PUCHAR pDA = pAd->WdsTab.WdsEntry[i].PeerWdsAddr;
-
-				// DA equal to SA. have no necessary orignal AP which found Radar signal.
-				if (MAC_ADDR_EQUAL(pTA, pDA))
-					continue;
-
-				// send Channel Switch Action frame to info Neighbro APs.
-				EnqueueChSwAnn(pAd, pDA, ChSwMode, Channel);
-			}
-		}
-	}
-#endif // WDS_SUPPORT //
-}
-
-static VOID StartDFSProcedure(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR Channel,
-	IN UINT8 ChSwMode)
-{
-	// start DFS procedure
-	pAd->CommonCfg.Channel = Channel;
-#ifdef DOT11_N_SUPPORT
-	N_ChannelCheck(pAd);
-#endif // DOT11_N_SUPPORT //
-	pAd->CommonCfg.RadarDetect.RDMode = RD_SWITCHING_MODE;
-	pAd->CommonCfg.RadarDetect.CSCount = 0;
-}
-
-/*
-	==========================================================================
-	Description:
-		Channel Switch Announcement action frame sanity check.
-
-	Parametrs:
-		1. MLME message containing the received frame
-		2. message length.
-		3. Channel switch announcement infomation buffer.
-
-
-	Return	: None.
-	==========================================================================
- */
-
-/*
-  Channel Switch Announcement IE.
-  +----+-----+-----------+------------+-----------+
-  | ID | Len |Ch Sw Mode | New Ch Num | Ch Sw Cnt |
-  +----+-----+-----------+------------+-----------+
-    1    1        1           1            1
-*/
-static BOOLEAN PeerChSwAnnSanity(
-	IN PRTMP_ADAPTER pAd,
-	IN VOID *pMsg,
-	IN ULONG MsgLen,
-	OUT PCH_SW_ANN_INFO pChSwAnnInfo)
-{
-	PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
-	PUCHAR pFramePtr = Fr->Octet;
-	BOOLEAN result = FALSE;
-	PEID_STRUCT eid_ptr;
-
-	// skip 802.11 header.
-	MsgLen -= sizeof(HEADER_802_11);
-
-	// skip category and action code.
-	pFramePtr += 2;
-	MsgLen -= 2;
-
-	if (pChSwAnnInfo == NULL)
-		return result;
-
-	eid_ptr = (PEID_STRUCT)pFramePtr;
-	while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
-	{
-		switch(eid_ptr->Eid)
-		{
-			case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
-				NdisMoveMemory(&pChSwAnnInfo->ChSwMode, eid_ptr->Octet, 1);
-				NdisMoveMemory(&pChSwAnnInfo->Channel, eid_ptr->Octet + 1, 1);
-				NdisMoveMemory(&pChSwAnnInfo->ChSwCnt, eid_ptr->Octet + 2, 1);
-
-				result = TRUE;
-                break;
-
-			default:
-				break;
-		}
-		eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
-	}
-
-	return result;
-}
-
-/*
-	==========================================================================
-	Description:
-		Measurement request action frame sanity check.
-
-	Parametrs:
-		1. MLME message containing the received frame
-		2. message length.
-		3. Measurement request infomation buffer.
-
-	Return	: None.
-	==========================================================================
- */
-static BOOLEAN PeerMeasureReqSanity(
-	IN PRTMP_ADAPTER pAd,
-	IN VOID *pMsg,
-	IN ULONG MsgLen,
-	OUT PUINT8 pDialogToken,
-	OUT PMEASURE_REQ_INFO pMeasureReqInfo,
-	OUT PMEASURE_REQ pMeasureReq)
-{
-	PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
-	PUCHAR pFramePtr = Fr->Octet;
-	BOOLEAN result = FALSE;
-	PEID_STRUCT eid_ptr;
-	PUCHAR ptr;
-	UINT64 MeasureStartTime;
-	UINT16 MeasureDuration;
-
-	// skip 802.11 header.
-	MsgLen -= sizeof(HEADER_802_11);
-
-	// skip category and action code.
-	pFramePtr += 2;
-	MsgLen -= 2;
-
-	if (pMeasureReqInfo == NULL)
-		return result;
-
-	NdisMoveMemory(pDialogToken, pFramePtr, 1);
-	pFramePtr += 1;
-	MsgLen -= 1;
-
-	eid_ptr = (PEID_STRUCT)pFramePtr;
-	while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
-	{
-		switch(eid_ptr->Eid)
-		{
-			case IE_MEASUREMENT_REQUEST:
-				NdisMoveMemory(&pMeasureReqInfo->Token, eid_ptr->Octet, 1);
-				NdisMoveMemory(&pMeasureReqInfo->ReqMode.word, eid_ptr->Octet + 1, 1);
-				NdisMoveMemory(&pMeasureReqInfo->ReqType, eid_ptr->Octet + 2, 1);
-				ptr = (PUCHAR)(eid_ptr->Octet + 3);
-				NdisMoveMemory(&pMeasureReq->ChNum, ptr, 1);
-				NdisMoveMemory(&MeasureStartTime, ptr + 1, 8);
-				pMeasureReq->MeasureStartTime = SWAP64(MeasureStartTime);
-				NdisMoveMemory(&MeasureDuration, ptr + 9, 2);
-				pMeasureReq->MeasureDuration = SWAP16(MeasureDuration);
-
-				result = TRUE;
-				break;
-
-			default:
-				break;
-		}
-		eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
-	}
-
-	return result;
-}
-
-/*
-	==========================================================================
-	Description:
-		Measurement report action frame sanity check.
-
-	Parametrs:
-		1. MLME message containing the received frame
-		2. message length.
-		3. Measurement report infomation buffer.
-		4. basic report infomation buffer.
-
-	Return	: None.
-	==========================================================================
- */
-
-/*
-  Measurement Report IE.
-  +----+-----+-------+-------------+--------------+----------------+
-  | ID | Len | Token | Report Mode | Measure Type | Measure Report |
-  +----+-----+-------+-------------+--------------+----------------+
-    1     1      1          1             1            variable
-
-  Basic Report.
-  +--------+------------+----------+-----+
-  | Ch Num | Start Time | Duration | Map |
-  +--------+------------+----------+-----+
-      1          8           2        1
-
-  Map Field Bit Format.
-  +-----+---------------+---------------------+-------+------------+----------+
-  | Bss | OFDM Preamble | Unidentified signal | Radar | Unmeasured | Reserved |
-  +-----+---------------+---------------------+-------+------------+----------+
-     0          1                  2              3         4          5-7
-*/
-static BOOLEAN PeerMeasureReportSanity(
-	IN PRTMP_ADAPTER pAd,
-	IN VOID *pMsg,
-	IN ULONG MsgLen,
-	OUT PUINT8 pDialogToken,
-	OUT PMEASURE_REPORT_INFO pMeasureReportInfo,
-	OUT PUINT8 pReportBuf)
-{
-	PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
-	PUCHAR pFramePtr = Fr->Octet;
-	BOOLEAN result = FALSE;
-	PEID_STRUCT eid_ptr;
-	PUCHAR ptr;
-
-	// skip 802.11 header.
-	MsgLen -= sizeof(HEADER_802_11);
-
-	// skip category and action code.
-	pFramePtr += 2;
-	MsgLen -= 2;
-
-	if (pMeasureReportInfo == NULL)
-		return result;
-
-	NdisMoveMemory(pDialogToken, pFramePtr, 1);
-	pFramePtr += 1;
-	MsgLen -= 1;
-
-	eid_ptr = (PEID_STRUCT)pFramePtr;
-	while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
-	{
-		switch(eid_ptr->Eid)
-		{
-			case IE_MEASUREMENT_REPORT:
-				NdisMoveMemory(&pMeasureReportInfo->Token, eid_ptr->Octet, 1);
-				NdisMoveMemory(&pMeasureReportInfo->ReportMode, eid_ptr->Octet + 1, 1);
-				NdisMoveMemory(&pMeasureReportInfo->ReportType, eid_ptr->Octet + 2, 1);
-				if (pMeasureReportInfo->ReportType == RM_BASIC)
-				{
-					PMEASURE_BASIC_REPORT pReport = (PMEASURE_BASIC_REPORT)pReportBuf;
-					ptr = (PUCHAR)(eid_ptr->Octet + 3);
-					NdisMoveMemory(&pReport->ChNum, ptr, 1);
-					NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
-					NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
-					NdisMoveMemory(&pReport->Map, ptr + 11, 1);
-
-				}
-				else if (pMeasureReportInfo->ReportType == RM_CCA)
-				{
-					PMEASURE_CCA_REPORT pReport = (PMEASURE_CCA_REPORT)pReportBuf;
-					ptr = (PUCHAR)(eid_ptr->Octet + 3);
-					NdisMoveMemory(&pReport->ChNum, ptr, 1);
-					NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
-					NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
-					NdisMoveMemory(&pReport->CCA_Busy_Fraction, ptr + 11, 1);
-
-				}
-				else if (pMeasureReportInfo->ReportType == RM_RPI_HISTOGRAM)
-				{
-					PMEASURE_RPI_REPORT pReport = (PMEASURE_RPI_REPORT)pReportBuf;
-					ptr = (PUCHAR)(eid_ptr->Octet + 3);
-					NdisMoveMemory(&pReport->ChNum, ptr, 1);
-					NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
-					NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
-					NdisMoveMemory(&pReport->RPI_Density, ptr + 11, 8);
-				}
-				result = TRUE;
-                break;
-
-			default:
-				break;
-		}
-		eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
-	}
-
-	return result;
-}
-
-/*
-	==========================================================================
-	Description:
-		TPC Request action frame sanity check.
-
-	Parametrs:
-		1. MLME message containing the received frame
-		2. message length.
-		3. Dialog Token.
-
-	Return	: None.
-	==========================================================================
- */
-static BOOLEAN PeerTpcReqSanity(
-	IN PRTMP_ADAPTER pAd,
-	IN VOID *pMsg,
-	IN ULONG MsgLen,
-	OUT PUINT8 pDialogToken)
-{
-	PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
-	PUCHAR pFramePtr = Fr->Octet;
-	BOOLEAN result = FALSE;
-	PEID_STRUCT eid_ptr;
-
-	MsgLen -= sizeof(HEADER_802_11);
-
-	// skip category and action code.
-	pFramePtr += 2;
-	MsgLen -= 2;
-
-	if (pDialogToken == NULL)
-		return result;
-
-	NdisMoveMemory(pDialogToken, pFramePtr, 1);
-	pFramePtr += 1;
-	MsgLen -= 1;
-
-	eid_ptr = (PEID_STRUCT)pFramePtr;
-	while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
-	{
-		switch(eid_ptr->Eid)
-		{
-			case IE_TPC_REQUEST:
-				result = TRUE;
-                break;
-
-			default:
-				break;
-		}
-		eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
-	}
-
-	return result;
-}
-
-/*
-	==========================================================================
-	Description:
-		TPC Report action frame sanity check.
-
-	Parametrs:
-		1. MLME message containing the received frame
-		2. message length.
-		3. Dialog Token.
-		4. TPC Report IE.
-
-	Return	: None.
-	==========================================================================
- */
-static BOOLEAN PeerTpcRepSanity(
-	IN PRTMP_ADAPTER pAd,
-	IN VOID *pMsg,
-	IN ULONG MsgLen,
-	OUT PUINT8 pDialogToken,
-	OUT PTPC_REPORT_INFO pTpcRepInfo)
-{
-	PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
-	PUCHAR pFramePtr = Fr->Octet;
-	BOOLEAN result = FALSE;
-	PEID_STRUCT eid_ptr;
-
-	MsgLen -= sizeof(HEADER_802_11);
-
-	// skip category and action code.
-	pFramePtr += 2;
-	MsgLen -= 2;
-
-	if (pDialogToken == NULL)
-		return result;
-
-	NdisMoveMemory(pDialogToken, pFramePtr, 1);
-	pFramePtr += 1;
-	MsgLen -= 1;
-
-	eid_ptr = (PEID_STRUCT)pFramePtr;
-	while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
-	{
-		switch(eid_ptr->Eid)
-		{
-			case IE_TPC_REPORT:
-				NdisMoveMemory(&pTpcRepInfo->TxPwr, eid_ptr->Octet, 1);
-				NdisMoveMemory(&pTpcRepInfo->LinkMargin, eid_ptr->Octet + 1, 1);
-				result = TRUE;
-                break;
-
-			default:
-				break;
-		}
-		eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
-	}
-
-	return result;
-}
-
-/*
-	==========================================================================
-	Description:
-		Channel Switch Announcement action frame handler.
-
-	Parametrs:
-		Elme - MLME message containing the received frame
-
-	Return	: None.
-	==========================================================================
- */
-static VOID PeerChSwAnnAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	CH_SW_ANN_INFO ChSwAnnInfo;
-	PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
-#ifdef CONFIG_STA_SUPPORT
-	UCHAR index = 0, Channel = 0, NewChannel = 0;
-	ULONG Bssidx = 0;
-#endif // CONFIG_STA_SUPPORT //
-
-	NdisZeroMemory(&ChSwAnnInfo, sizeof(CH_SW_ANN_INFO));
-	if (! PeerChSwAnnSanity(pAd, Elem->Msg, Elem->MsgLen, &ChSwAnnInfo))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("Invalid Channel Switch Action Frame.\n"));
-		return;
-	}
-
-
-#ifdef CONFIG_STA_SUPPORT
-	if (pAd->OpMode == OPMODE_STA)
-	{
-		Bssidx = BssTableSearch(&pAd->ScanTab, pFr->Hdr.Addr3, pAd->CommonCfg.Channel);
-		if (Bssidx == BSS_NOT_FOUND)
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("PeerChSwAnnAction - Bssidx is not found\n"));
-			return;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("\n****Bssidx is %d, Channel = %d\n", index, pAd->ScanTab.BssEntry[Bssidx].Channel));
-		hex_dump("SSID",pAd->ScanTab.BssEntry[Bssidx].Bssid ,6);
-
-		Channel = pAd->CommonCfg.Channel;
-		NewChannel = ChSwAnnInfo.Channel;
-
-		if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel))
-		{
-			// Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
-			// In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
-			AsicSwitchChannel(pAd, 1, FALSE);
-			AsicLockChannel(pAd, 1);
-		    LinkDown(pAd, FALSE);
-			MlmeQueueInit(&pAd->Mlme.Queue);
-			BssTableInit(&pAd->ScanTab);
-		    RTMPusecDelay(1000000);		// use delay to prevent STA do reassoc
-
-			// channel sanity check
-			for (index = 0 ; index < pAd->ChannelListNum; index++)
-			{
-				if (pAd->ChannelList[index].Channel == NewChannel)
-				{
-					pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel;
-					pAd->CommonCfg.Channel = NewChannel;
-					AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-					AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-					DBGPRINT(RT_DEBUG_TRACE, ("&&&&&&&&&&&&&&&&PeerChSwAnnAction - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel));
-					break;
-				}
-			}
-
-			if (index >= pAd->ChannelListNum)
-			{
-				DBGPRINT_ERR(("&&&&&&&&&&&&&&&&&&&&&&&&&&PeerChSwAnnAction(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum));
-			}
-		}
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	return;
-}
-
-
-/*
-	==========================================================================
-	Description:
-		Measurement Request action frame handler.
-
-	Parametrs:
-		Elme - MLME message containing the received frame
-
-	Return	: None.
-	==========================================================================
- */
-static VOID PeerMeasureReqAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
-	UINT8 DialogToken;
-	MEASURE_REQ_INFO MeasureReqInfo;
-	MEASURE_REQ	MeasureReq;
-	MEASURE_REPORT_MODE ReportMode;
-
-	if(PeerMeasureReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReqInfo, &MeasureReq))
-	{
-		ReportMode.word = 0;
-		ReportMode.field.Incapable = 1;
-		EnqueueMeasurementRep(pAd, pFr->Hdr.Addr2, DialogToken, MeasureReqInfo.Token, ReportMode.word, MeasureReqInfo.ReqType, 0, NULL);
-	}
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Measurement Report action frame handler.
-
-	Parametrs:
-		Elme - MLME message containing the received frame
-
-	Return	: None.
-	==========================================================================
- */
-static VOID PeerMeasureReportAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	MEASURE_REPORT_INFO MeasureReportInfo;
-	PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
-	UINT8 DialogToken;
-	PUINT8 pMeasureReportInfo;
-
-//	if (pAd->CommonCfg.bIEEE80211H != TRUE)
-//		return;
-
-	if ((pMeasureReportInfo = kmalloc(sizeof(MEASURE_RPI_REPORT), GFP_ATOMIC)) == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%d).\n", __FUNCTION__, sizeof(MEASURE_RPI_REPORT)));
-		return;
-	}
-
-	NdisZeroMemory(&MeasureReportInfo, sizeof(MEASURE_REPORT_INFO));
-	NdisZeroMemory(pMeasureReportInfo, sizeof(MEASURE_RPI_REPORT));
-	if (PeerMeasureReportSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReportInfo, pMeasureReportInfo))
-	{
-		do {
-			PMEASURE_REQ_ENTRY pEntry = NULL;
-
-			// Not a autonomous measure report.
-			// check the dialog token field. drop it if the dialog token doesn't match.
-			if ((DialogToken != 0)
-				&& ((pEntry = MeasureReqLookUp(pAd, DialogToken)) == NULL))
-				break;
-
-			if (pEntry != NULL)
-				MeasureReqDelete(pAd, pEntry->DialogToken);
-
-			if (MeasureReportInfo.ReportType == RM_BASIC)
-			{
-				PMEASURE_BASIC_REPORT pBasicReport = (PMEASURE_BASIC_REPORT)pMeasureReportInfo;
-				if ((pBasicReport->Map.field.Radar)
-					&& (DfsRequirementCheck(pAd, pBasicReport->ChNum) == TRUE))
-				{
-					NotifyChSwAnnToPeerAPs(pAd, pFr->Hdr.Addr1, pFr->Hdr.Addr2, 1, pBasicReport->ChNum);
-					StartDFSProcedure(pAd, pBasicReport->ChNum, 1);
-				}
-			}
-		} while (FALSE);
-	}
-	else
-		DBGPRINT(RT_DEBUG_TRACE, ("Invalid Measurement Report Frame.\n"));
-
-	kfree(pMeasureReportInfo);
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		TPC Request action frame handler.
-
-	Parametrs:
-		Elme - MLME message containing the received frame
-
-	Return	: None.
-	==========================================================================
- */
-static VOID PeerTpcReqAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
-	PUCHAR pFramePtr = pFr->Octet;
-	UINT8 DialogToken;
-	UINT8 TxPwr = GetCurTxPwr(pAd, Elem->Wcid);
-	UINT8 LinkMargin = 0;
-	CHAR RealRssi;
-
-	// link margin: Ratio of the received signal power to the minimum desired by the station (STA). The
-	//				STA may incorporate rate information and channel conditions, including interference, into its computation
-	//				of link margin.
-
-	RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
-								ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
-								ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
-
-	// skip Category and action code.
-	pFramePtr += 2;
-
-	// Dialog token.
-	NdisMoveMemory(&DialogToken, pFramePtr, 1);
-
-	LinkMargin = (RealRssi / MIN_RCV_PWR);
-	if (PeerTpcReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken))
-		EnqueueTPCRep(pAd, pFr->Hdr.Addr2, DialogToken, TxPwr, LinkMargin);
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		TPC Report action frame handler.
-
-	Parametrs:
-		Elme - MLME message containing the received frame
-
-	Return	: None.
-	==========================================================================
- */
-static VOID PeerTpcRepAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	UINT8 DialogToken;
-	TPC_REPORT_INFO TpcRepInfo;
-	PTPC_REQ_ENTRY pEntry = NULL;
-
-	NdisZeroMemory(&TpcRepInfo, sizeof(TPC_REPORT_INFO));
-	if (PeerTpcRepSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &TpcRepInfo))
-	{
-		if ((pEntry = TpcReqLookUp(pAd, DialogToken)) != NULL)
-		{
-			TpcReqDelete(pAd, pEntry->DialogToken);
-			DBGPRINT(RT_DEBUG_TRACE, ("%s: DialogToken=%x, TxPwr=%d, LinkMargin=%d\n",
-				__FUNCTION__, DialogToken, TpcRepInfo.TxPwr, TpcRepInfo.LinkMargin));
-		}
-	}
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Spectrun action frames Handler such as channel switch annoucement,
-		measurement report, measurement request actions frames.
-
-	Parametrs:
-		Elme - MLME message containing the received frame
-
-	Return	: None.
-	==========================================================================
- */
-VOID PeerSpectrumAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-
-	UCHAR	Action = Elem->Msg[LENGTH_802_11+1];
-
-	if (pAd->CommonCfg.bIEEE80211H != TRUE)
-		return;
-
-	switch(Action)
-	{
-		case SPEC_MRQ:
-			// current rt2860 unable do such measure specified in Measurement Request.
-			// reject all measurement request.
-			PeerMeasureReqAction(pAd, Elem);
-			break;
-
-		case SPEC_MRP:
-			PeerMeasureReportAction(pAd, Elem);
-			break;
-
-		case SPEC_TPCRQ:
-			PeerTpcReqAction(pAd, Elem);
-			break;
-
-		case SPEC_TPCRP:
-			PeerTpcRepAction(pAd, Elem);
-			break;
-
-		case SPEC_CHANNEL_SWITCH:
-
-#ifdef DOT11N_DRAFT3
-			{
-				SEC_CHA_OFFSET_IE	Secondary;
-				CHA_SWITCH_ANNOUNCE_IE	ChannelSwitch;
-
-				// 802.11h only has Channel Switch Announcement IE.
-				RTMPMoveMemory(&ChannelSwitch, &Elem->Msg[LENGTH_802_11+4], sizeof (CHA_SWITCH_ANNOUNCE_IE));
-
-				// 802.11n D3.03 adds secondary channel offset element in the end.
-				if (Elem->MsgLen ==  (LENGTH_802_11 + 2 + sizeof (CHA_SWITCH_ANNOUNCE_IE) + sizeof (SEC_CHA_OFFSET_IE)))
-				{
-					RTMPMoveMemory(&Secondary, &Elem->Msg[LENGTH_802_11+9], sizeof (SEC_CHA_OFFSET_IE));
-				}
-				else
-				{
-					Secondary.SecondaryChannelOffset = 0;
-				}
-
-				if ((Elem->Msg[LENGTH_802_11+2] == IE_CHANNEL_SWITCH_ANNOUNCEMENT) && (Elem->Msg[LENGTH_802_11+3] == 3))
-				{
-					ChannelSwitchAction(pAd, Elem->Wcid, ChannelSwitch.NewChannel, Secondary.SecondaryChannelOffset);
-				}
-			}
-#endif // DOT11N_DRAFT3 //
-
-			PeerChSwAnnAction(pAd, Elem);
-			break;
-	}
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-
-	Parametrs:
-
-	Return	: None.
-	==========================================================================
- */
-INT Set_MeasureReq_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	UINT Aid = 1;
-	UINT ArgIdx;
-	PSTRING thisChar;
-
-	MEASURE_REQ_MODE MeasureReqMode;
-	UINT8 MeasureReqToken = RandomByte(pAd);
-	UINT8 MeasureReqType = RM_BASIC;
-	UINT8 MeasureCh = 1;
-	UINT64 MeasureStartTime = GetCurrentTimeStamp(pAd);
-	MEASURE_REQ MeasureReq;
-	UINT8 TotalLen;
-
-	HEADER_802_11 ActHdr;
-	PUCHAR pOutBuffer = NULL;
-	NDIS_STATUS NStatus;
-	ULONG FrameLen;
-
-	NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
-	if(NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
-		goto END_OF_MEASURE_REQ;
-	}
-
-	ArgIdx = 1;
-	while ((thisChar = strsep((char **)&arg, "-")) != NULL)
-	{
-		switch(ArgIdx)
-		{
-			case 1:	// Aid.
-				Aid = (UINT8) simple_strtol(thisChar, 0, 16);
-				break;
-
-			case 2: // Measurement Request Type.
-				MeasureReqType = simple_strtol(thisChar, 0, 16);
-				if (MeasureReqType > 3)
-				{
-					DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow MeasureReqType(%d)\n", __FUNCTION__, MeasureReqType));
-					goto END_OF_MEASURE_REQ;
-				}
-				break;
-
-			case 3: // Measurement channel.
-				MeasureCh = (UINT8) simple_strtol(thisChar, 0, 16);
-				break;
-		}
-		ArgIdx++;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d, MeasureReqType=%d MeasureCh=%d\n", __FUNCTION__, Aid, MeasureReqType, MeasureCh));
-	if (!VALID_WCID(Aid))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __FUNCTION__, Aid));
-		goto END_OF_MEASURE_REQ;
-	}
-
-	MeasureReqMode.word = 0;
-	MeasureReqMode.field.Enable = 1;
-
-	MeasureReqInsert(pAd, MeasureReqToken);
-
-	// build action frame header.
-	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pAd->MacTab.Content[Aid].Addr,
-						pAd->CurrentAddress);
-
-	NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
-	FrameLen = sizeof(HEADER_802_11);
-
-	TotalLen = sizeof(MEASURE_REQ_INFO) + sizeof(MEASURE_REQ);
-
-	MakeMeasurementReqFrame(pAd, pOutBuffer, &FrameLen,
-		sizeof(MEASURE_REQ_INFO), CATEGORY_RM, RM_BASIC,
-		MeasureReqToken, MeasureReqMode.word,
-		MeasureReqType, 0);
-
-	MeasureReq.ChNum = MeasureCh;
-	MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime);
-	MeasureReq.MeasureDuration = cpu2le16(2000);
-
-	{
-		ULONG TempLen;
-		MakeOutgoingFrame(	pOutBuffer+FrameLen,	&TempLen,
-							sizeof(MEASURE_REQ),	&MeasureReq,
-							END_OF_ARGS);
-		FrameLen += TempLen;
-	}
-
-	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, (UINT)FrameLen);
-
-END_OF_MEASURE_REQ:
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-	return TRUE;
-}
-
-INT Set_TpcReq_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	UINT Aid;
-
-	UINT8 TpcReqToken = RandomByte(pAd);
-
-	Aid = (UINT) simple_strtol(arg, 0, 16);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d\n", __FUNCTION__, Aid));
-	if (!VALID_WCID(Aid))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __FUNCTION__, Aid));
-		return TRUE;
-	}
-
-	TpcReqInsert(pAd, TpcReqToken);
-
-	EnqueueTPCReq(pAd, pAd->MacTab.Content[Aid].Addr, TpcReqToken);
-
-	return TRUE;
-}
diff --git a/drivers/staging/rt3090/config.mk b/drivers/staging/rt3090/config.mk
deleted file mode 100644
index 4c90c40..0000000
--- a/drivers/staging/rt3090/config.mk
+++ /dev/null
@@ -1,187 +0,0 @@
-# Support ATE function
-HAS_ATE=y
-
-# Support 28xx QA ATE function
-HAS_28xx_QA=n
-
-
-HAS_NINTENDO=n
-
-# Support LLTD function
-HAS_LLTD=n
-
-# Support WDS function
-HAS_WDS=n
-
-# Support AP-Client function
-HAS_APCLI=n
-
-# Support Wpa_Supplicant
-HAS_WPA_SUPPLICANT=y
-
-# Support Native WpaSupplicant for Network Maganger
-HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=y
-
-#Support Net interface block while Tx-Sw queue full
-HAS_BLOCK_NET_IF=n
-
-#Support IGMP-Snooping function.
-HAS_IGMP_SNOOP_SUPPORT=n
-
-#Support DFS function
-HAS_DFS_SUPPORT=n
-
-#Support Carrier-Sense function
-HAS_CS_SUPPORT=n
-
-# Support for STA Ethernet Converter
-HAS_ETH_CONVERT_SUPPORT=n
-
-# Support user specific transmit rate of Multicast packet.
-HAS_MCAST_RATE_SPECIFIC_SUPPORT=n
-
-# Support for Multiple Cards
-HAS_MC_SUPPORT=n
-
-#Support for PCI-MSI
-HAS_MSI_SUPPORT=n
-
-
-#Support for IEEE802.11e DLS
-HAS_QOS_DLS_SUPPORT=n
-
-#Support for EXT_CHANNEL
-HAS_EXT_BUILD_CHANNEL_LIST=n
-
-#Support for IDS
-HAS_IDS_SUPPORT=n
-
-
-#Support for Net-SNMP
-HAS_SNMP_SUPPORT=n
-
-#Support features of 802.11n Draft3
-HAS_DOT11N_DRAFT3_SUPPORT=n
-
-#Support features of Single SKU.
-HAS_SINGLE_SKU_SUPPORT=n
-
-#Support features of 802.11n
-HAS_DOT11_N_SUPPORT=y
-
-
-
-#Support for 2860/2880 co-exist
-HAS_RT2880_RT2860_COEXIST=n
-
-HAS_KTHREAD_SUPPORT=n
-
-
-#Support for Auto channel select enhance
-HAS_AUTO_CH_SELECT_ENHANCE=n
-
-#Support bypass bridge
-HAS_BG_FT_SUPPORT=n
-
-#Support Antenna Diversity
-HAS_ANTENNA_DIVERSITY_SUPPORT=y
-#################################################
-
-WFLAGS := -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT  -DLINUX -Wall -Wstrict-prototypes -Wno-trigraphs -Wpointer-sign
-
-ifeq ($(HAS_KTHREAD_SUPPORT),y)
-WFLAGS += -DKTHREAD_SUPPORT
-endif
-
-
-#################################################
-
-# config for STA mode
-
-WFLAGS += -DCONFIG_STA_SUPPORT -DDBG
-
-ifeq ($(HAS_WPA_SUPPLICANT),y)
-WFLAGS += -DWPA_SUPPLICANT_SUPPORT
-ifeq ($(HAS_NATIVE_WPA_SUPPLICANT_SUPPORT),y)
-WFLAGS += -DNATIVE_WPA_SUPPLICANT_SUPPORT
-endif
-endif
-
-
-ifeq ($(HAS_ETH_CONVERT_SUPPORT), y)
-WFLAGS += -DETH_CONVERT_SUPPORT  -DMAT_SUPPORT
-endif
-
-ifeq ($(HAS_ATE),y)
-WFLAGS += -DRALINK_ATE
-ifeq ($(HAS_28xx_QA),y)
-WFLAGS += -DRALINK_28xx_QA
-endif
-endif
-
-
-ifeq ($(HAS_SNMP_SUPPORT),y)
-WFLAGS += -DSNMP_SUPPORT
-endif
-
-ifeq ($(HAS_QOS_DLS_SUPPORT),y)
-WFLAGS += -DQOS_DLS_SUPPORT
-endif
-
-ifeq ($(HAS_DOT11_N_SUPPORT),y)
-WFLAGS += -DDOT11_N_SUPPORT
-endif
-
-ifeq ($(HAS_CS_SUPPORT),y)
-WFLAGS += -DCARRIER_DETECTION_SUPPORT
-endif
-
-ifeq ($(HAS_ANTENNA_DIVERSITY_SUPPORT),y)
-WFLAGS += -DANT_DIVERSITY_SUPPORT
-endif
-
-#################################################
-
-#################################################
-
-#
-# Common compiler flag
-#
-
-
-
-
-
-ifeq ($(HAS_EXT_BUILD_CHANNEL_LIST),y)
-WFLAGS += -DEXT_BUILD_CHANNEL_LIST
-endif
-
-ifeq ($(HAS_IDS_SUPPORT),y)
-WFLAGS += -DIDS_SUPPORT
-endif
-
-
-#################################################
-# ChipSet specific definitions.
-#
-WFLAGS +=-DRTMP_MAC_PCI -DRT30xx -DRT3090  -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT
-#################################################
-
-
-ifeq ($(HAS_BLOCK_NET_IF),y)
-WFLAGS += -DBLOCK_NET_IF
-endif
-
-ifeq ($(HAS_DFS_SUPPORT),y)
-WFLAGS += -DDFS_SUPPORT
-endif
-
-ifeq ($(HAS_MC_SUPPORT),y)
-WFLAGS += -DMULTIPLE_CARD_SUPPORT
-endif
-
-ifeq ($(HAS_LLTD),y)
-WFLAGS += -DLLTD_SUPPORT
-endif
-
-EXTRA_CFLAGS := $(WFLAGS)
diff --git a/drivers/staging/rt3090/crypt_hmac.h b/drivers/staging/rt3090/crypt_hmac.h
deleted file mode 100644
index 557ca73..0000000
--- a/drivers/staging/rt3090/crypt_hmac.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    crypt_hmac.h
-
-    Abstract:
-    Miniport generic portion header file
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-    Eddy        2008/11/24      Create HMAC-SHA1, HMAC-SHA256
-*/
-
-#ifndef __CRYPT_HMAC_H__
-#define __CRYPT_HMAC_H__
-
-#ifdef CRYPT_TESTPLAN
-#include "crypt_testplan.h"
-#else
-#include "rt_config.h"
-#endif /* CRYPT_TESTPLAN */
-
-#ifdef SHA1_SUPPORT
-#define HMAC_SHA1_SUPPORT
-VOID HMAC_SHA1 (
-    IN  const UINT8 Key[],
-    IN  UINT KeyLen,
-    IN  const UINT8 Message[],
-    IN  UINT MessageLen,
-    OUT UINT8 MAC[],
-    IN  UINT MACLen);
-#endif /* SHA1_SUPPORT */
-
-#ifdef SHA256_SUPPORT
-#define HMAC_SHA256_SUPPORT
-VOID HMAC_SHA256 (
-    IN  const UINT8 Key[],
-    IN  UINT KeyLen,
-    IN  const UINT8 Message[],
-    IN  UINT MessageLen,
-    OUT UINT8 MAC[],
-    IN  UINT MACLen);
-#endif /* SHA256_SUPPORT */
-
-#ifdef MD5_SUPPORT
-#define HMAC_MD5_SUPPORT
-VOID HMAC_MD5 (
-    IN  const UINT8 Key[],
-    IN  UINT KeyLen,
-    IN  const UINT8 Message[],
-    IN  UINT MessageLen,
-    OUT UINT8 MAC[],
-    IN  UINT MACLen);
-#endif /* MD5_SUPPORT */
-
-#endif /* __CRYPT_HMAC_H__ */
diff --git a/drivers/staging/rt3090/crypt_md5.h b/drivers/staging/rt3090/crypt_md5.h
deleted file mode 100644
index 7ee3f42..0000000
--- a/drivers/staging/rt3090/crypt_md5.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    crypt_md5.h
-
-    Abstract:
-    Miniport generic portion header file
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-    Eddy        2008/11/24      Create md5
-*/
-
-#ifndef __CRYPT_MD5_H__
-#define __CRYPT_MD5_H__
-
-#ifdef CRYPT_TESTPLAN
-#include "crypt_testplan.h"
-#else
-#include "rt_config.h"
-#endif /* CRYPT_TESTPLAN */
-
-/* Algorithm options */
-#define MD5_SUPPORT
-
-#ifdef MD5_SUPPORT
-#define MD5_BLOCK_SIZE    64 /* 512 bits = 64 bytes */
-#define MD5_DIGEST_SIZE   16 /* 128 bits = 16 bytes */
-typedef struct {
-    UINT32 HashValue[4];
-    UINT64 MessageLen;
-    UINT8  Block[MD5_BLOCK_SIZE];
-    UINT   BlockLen;
-} MD5_CTX_STRUC, *PMD5_CTX_STRUC;
-
-VOID MD5_Init (
-    IN  MD5_CTX_STRUC *pMD5_CTX);
-VOID MD5_Hash (
-    IN  MD5_CTX_STRUC *pMD5_CTX);
-VOID MD5_Append (
-    IN  MD5_CTX_STRUC *pMD5_CTX,
-    IN  const UINT8 Message[],
-    IN  UINT MessageLen);
-VOID MD5_End (
-    IN  MD5_CTX_STRUC *pMD5_CTX,
-    OUT UINT8 DigestMessage[]);
-VOID RT_MD5 (
-    IN  const UINT8 Message[],
-    IN  UINT MessageLen,
-    OUT UINT8 DigestMessage[]);
-#endif /* MD5_SUPPORT */
-
-#endif /* __CRYPT_MD5_H__ */
diff --git a/drivers/staging/rt3090/crypt_sha2.h b/drivers/staging/rt3090/crypt_sha2.h
deleted file mode 100644
index 85c0403..0000000
--- a/drivers/staging/rt3090/crypt_sha2.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    crypt_sha2.h
-
-    Abstract:
-    Miniport generic portion header file
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-    Eddy        2008/11/24      Create SHA1
-    Eddy        2008/07/23      Create SHA256
-*/
-
-#ifndef __CRYPT_SHA2_H__
-#define __CRYPT_SHA2_H__
-
-#ifdef CRYPT_TESTPLAN
-#include "crypt_testplan.h"
-#else
-#include "rt_config.h"
-#endif /* CRYPT_TESTPLAN */
-
-/* Algorithm options */
-#define SHA1_SUPPORT
-#define SHA256_SUPPORT
-
-#ifdef SHA1_SUPPORT
-#define SHA1_BLOCK_SIZE    64 /* 512 bits = 64 bytes */
-#define SHA1_DIGEST_SIZE   20 /* 160 bits = 20 bytes */
-typedef struct _SHA1_CTX_STRUC {
-    UINT32 HashValue[5];  /* 5 = (SHA1_DIGEST_SIZE / 32) */
-    UINT64 MessageLen;    /* total size */
-    UINT8  Block[SHA1_BLOCK_SIZE];
-    UINT   BlockLen;
-} SHA1_CTX_STRUC, *PSHA1_CTX_STRUC;
-
-VOID SHA1_Init (
-    IN  SHA1_CTX_STRUC *pSHA_CTX);
-VOID SHA1_Hash (
-    IN  SHA1_CTX_STRUC *pSHA_CTX);
-VOID SHA1_Append (
-    IN  SHA1_CTX_STRUC *pSHA_CTX,
-    IN  const UINT8 Message[],
-    IN  UINT MessageLen);
-VOID SHA1_End (
-    IN  SHA1_CTX_STRUC *pSHA_CTX,
-    OUT UINT8 DigestMessage[]);
-VOID RT_SHA1 (
-    IN  const UINT8 Message[],
-    IN  UINT MessageLen,
-    OUT UINT8 DigestMessage[]);
-#endif /* SHA1_SUPPORT */
-
-#ifdef SHA256_SUPPORT
-#define SHA256_BLOCK_SIZE   64 /* 512 bits = 64 bytes */
-#define SHA256_DIGEST_SIZE  32 /* 256 bits = 32 bytes */
-typedef struct _SHA256_CTX_STRUC {
-    UINT32 HashValue[8];  /* 8 = (SHA256_DIGEST_SIZE / 32) */
-    UINT64 MessageLen;    /* total size */
-    UINT8  Block[SHA256_BLOCK_SIZE];
-    UINT   BlockLen;
-} SHA256_CTX_STRUC, *PSHA256_CTX_STRUC;
-
-VOID SHA256_Init (
-    IN  SHA256_CTX_STRUC *pSHA_CTX);
-VOID SHA256_Hash (
-    IN  SHA256_CTX_STRUC *pSHA_CTX);
-VOID SHA256_Append (
-    IN  SHA256_CTX_STRUC *pSHA_CTX,
-    IN  const UINT8 Message[],
-    IN  UINT MessageLen);
-VOID SHA256_End (
-    IN  SHA256_CTX_STRUC *pSHA_CTX,
-    OUT UINT8 DigestMessage[]);
-VOID RT_SHA256 (
-    IN  const UINT8 Message[],
-    IN  UINT MessageLen,
-    OUT UINT8 DigestMessage[]);
-#endif /* SHA256_SUPPORT */
-
-#endif /* __CRYPT_SHA2_H__ */
diff --git a/drivers/staging/rt3090/dfs.h b/drivers/staging/rt3090/dfs.h
deleted file mode 100644
index 506468e..0000000
--- a/drivers/staging/rt3090/dfs.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    dfs.h
-
-    Abstract:
-    Miniport generic portion header file
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-    Fonchi    03-12-2007      created
-*/
-
-#define RADAR_PULSE 1
-#define RADAR_WIDTH 2
-
-#define WIDTH_RD_IDLE 0
-#define WIDTH_RD_CHECK 1
-
-
-
-/*************************************************************************
-  *
-  *	DFS Radar related definitions.
-  *
-  ************************************************************************/
-//#define CARRIER_DETECT_TASK_NUM	6
-//#define RADAR_DETECT_TASK_NUM	7
-
-// McuRadarState && McuCarrierState for 2880-SW-MCU
-#define FREE_FOR_TX				0
-#define WAIT_CTS_BEING_SENT		1
-#define DO_DETECTION			2
-
-// McuRadarEvent
-#define RADAR_EVENT_CTS_SENT			0x01 // Host signal MCU that CTS has been sent
-#define RADAR_EVENT_CTS_CARRIER_SENT	0x02 // Host signal MCU that CTS has been sent (Carrier)
-#define RADAR_EVENT_RADAR_DETECTING		0x04 // Radar detection is on going, carrier detection hold back
-#define RADAR_EVENT_CARRIER_DETECTING	0x08 // Carrier detection is on going, radar detection hold back
-#define RADAR_EVENT_WIDTH_RADAR			0x10 // BBP == 2 radar detected
-#define RADAR_EVENT_CTS_KICKED			0x20 // Radar detection need to sent double CTS, first CTS sent
-
-// McuRadarCmd
-#define DETECTION_STOP			0
-#define RADAR_DETECTION			1
-#define CARRIER_DETECTION		2
-
-
-
-#ifdef TONE_RADAR_DETECT_SUPPORT
-INT Set_CarrierCriteria_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
-int Set_CarrierReCheck_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
-INT Set_CarrierStopCheck_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
-void NewCarrierDetectionStart(PRTMP_ADAPTER pAd);
-void RTMPHandleRadarInterrupt(PRTMP_ADAPTER  pAd);
-VOID CSAsicDisableSync(IN PRTMP_ADAPTER pAd);
-#endif // TONE_RADAR_DETECT_SUPPORT //
-
-
-VOID BbpRadarDetectionStart(
-	IN PRTMP_ADAPTER pAd);
-
-VOID BbpRadarDetectionStop(
-	IN PRTMP_ADAPTER pAd);
-
-VOID RadarDetectionStart(
-	IN PRTMP_ADAPTER pAd,
-	IN BOOLEAN CTS_Protect,
-	IN UINT8 CTSPeriod);
-
-VOID RadarDetectionStop(
-	IN PRTMP_ADAPTER	pAd);
-
-VOID RadarDetectPeriodic(
-	IN PRTMP_ADAPTER	pAd);
-
-
-BOOLEAN RadarChannelCheck(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			Ch);
-
-ULONG JapRadarType(
-	IN PRTMP_ADAPTER pAd);
-
-ULONG RTMPBbpReadRadarDuration(
-	IN PRTMP_ADAPTER	pAd);
-
-ULONG RTMPReadRadarDuration(
-	IN PRTMP_ADAPTER	pAd);
-
-VOID RTMPCleanRadarDuration(
-	IN PRTMP_ADAPTER	pAd);
-
-VOID RTMPPrepareRDCTSFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pDA,
-	IN	ULONG			Duration,
-	IN  UCHAR           RTSRate,
-	IN  ULONG           CTSBaseAddr,
-	IN  UCHAR			FrameGap);
-
-VOID RTMPPrepareRadarDetectParams(
-	IN PRTMP_ADAPTER	pAd);
-
-
-INT Set_ChMovingTime_Proc(
-	IN PRTMP_ADAPTER pAd,
-	IN PSTRING arg);
-
-INT Set_LongPulseRadarTh_Proc(
-	IN PRTMP_ADAPTER pAd,
-	IN PSTRING arg);
diff --git a/drivers/staging/rt3090/eeprom.h b/drivers/staging/rt3090/eeprom.h
deleted file mode 100644
index ee0e807..0000000
--- a/drivers/staging/rt3090/eeprom.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    eeprom.h
-
-    Abstract:
-    Miniport generic portion header file
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-*/
-#ifndef __EEPROM_H__
-#define __EEPROM_H__
-
-
-
-#ifdef RTMP_PCI_SUPPORT
-/*************************************************************************
-  *	Public function declarations for prom-based chipset
-  ************************************************************************/
-int rtmp_ee_prom_read16(
-	IN PRTMP_ADAPTER	pAd,
-	IN USHORT			Offset,
-	OUT USHORT			*pValue);
-
-int rtmp_ee_prom_write16(
-	IN PRTMP_ADAPTER	pAd,
-	IN USHORT			Offset,
-	IN USHORT			value);
-#endif // RTMP_PCI_SUPPORT //
-
-
-
-
-
-#ifdef RT30xx
-#ifdef RTMP_EFUSE_SUPPORT
-int rtmp_ee_efuse_read16(
-	IN RTMP_ADAPTER *pAd,
-	IN USHORT Offset,
-	OUT USHORT *pValue);
-
-int rtmp_ee_efuse_write16(
-	IN RTMP_ADAPTER *pAd,
-	IN USHORT Offset,
-	IN USHORT data);
-#endif // RTMP_EFUSE_SUPPORT //
-#endif // RT30xx //
-
-/*************************************************************************
-  *	Public function declarations for prom operation callback functions setting
-  ************************************************************************/
-INT RtmpChipOpsEepromHook(
-	IN RTMP_ADAPTER *pAd,
-	IN INT			infType);
-
-#endif // __EEPROM_H__ //
diff --git a/drivers/staging/rt3090/firmware.h b/drivers/staging/rt3090/firmware.h
index f2836a2..17056e2 100644
--- a/drivers/staging/rt3090/firmware.h
+++ b/drivers/staging/rt3090/firmware.h
@@ -2,7 +2,7 @@
 /* AUTO GEN PLEASE DO NOT MODIFY IT */
 
 
-UCHAR FirmwareImage [] = {
+u8 FirmwareImage_3090 [] = {
 0x02, 0x02, 0xf3, 0x02, 0x02, 0xa1, 0x22, 0x22, 0xff, 0xff, 0xff, 0x02, 0x01, 0x27, 0xff, 0xff,
 0xff, 0xff, 0xff, 0x02, 0x00, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0xd8, 0xc0, 0xe0,
 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18, 0xc2, 0xaf, 0x30, 0x45, 0x03,
diff --git a/drivers/staging/rt3090/igmp_snoop.h b/drivers/staging/rt3090/igmp_snoop.h
deleted file mode 100644
index 63f9692..0000000
--- a/drivers/staging/rt3090/igmp_snoop.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    igmp_snoop.h
-
-    Abstract:
-    Miniport generic portion header file
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-*/
-
-
-#ifndef __RTMP_IGMP_SNOOP_H__
-#define __RTMP_IGMP_SNOOP_H__
-
-#include "link_list.h"
-
-#define IGMP_PROTOCOL_DESCRIPTOR	0x02
-#define IGMP_V1_MEMBERSHIP_REPORT	0x12
-#define IGMP_V2_MEMBERSHIP_REPORT	0x16
-#define IGMP_LEAVE_GROUP			0x17
-#define IGMP_V3_MEMBERSHIP_REPORT	0x22
-
-#define MLD_V1_LISTENER_REPORT		131
-#define MLD_V1_LISTENER_DONE		132
-#define MLD_V2_LISTERNER_REPORT		143
-
-#define IGMPMAC_TB_ENTRY_AGEOUT_TIME 120 * OS_HZ
-
-#define MULTICAST_ADDR_HASH_INDEX(Addr)      (MAC_ADDR_HASH(Addr) % (MAX_LEN_OF_MULTICAST_FILTER_HASH_TABLE))
-
-#define IS_MULTICAST_MAC_ADDR(Addr)			((((Addr[0]) & 0x01) == 0x01) && ((Addr[0]) != 0xff))
-#define IS_BROADCAST_MAC_ADDR(Addr)			((((Addr[0]) & 0xff) == 0xff))
-
-VOID MulticastFilterTableInit(
-	IN PMULTICAST_FILTER_TABLE *ppMulticastFilterTable);
-
-VOID MultiCastFilterTableReset(
-	IN PMULTICAST_FILTER_TABLE *ppMulticastFilterTable);
-
-BOOLEAN MulticastFilterTableInsertEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pGrpId,
-	IN PUCHAR pMemberAddr,
-	IN PNET_DEV dev,
-	IN MulticastFilterEntryType type);
-
-BOOLEAN MulticastFilterTableDeleteEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pGrpId,
-	IN PUCHAR pMemberAddr,
-	IN PNET_DEV dev);
-
-PMULTICAST_FILTER_TABLE_ENTRY MulticastFilterTableLookup(
-	IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
-	IN PUCHAR pAddr,
-	IN PNET_DEV dev);
-
-BOOLEAN isIgmpPkt(
-	IN PUCHAR pDstMacAddr,
-	IN PUCHAR pIpHeader);
-
-VOID IGMPSnooping(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDstMacAddr,
-	IN PUCHAR pSrcMacAddr,
-	IN PUCHAR pIpHeader,
-	IN PNET_DEV pDev);
-
-BOOLEAN isMldPkt(
-	IN PUCHAR pDstMacAddr,
-	IN PUCHAR pIpHeader,
-	OUT UINT8 *pProtoType,
-	OUT PUCHAR *pMldHeader);
-
-VOID MLDSnooping(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDstMacAddr,
-	IN PUCHAR pSrcMacAddr,
-	IN PUCHAR pIpHeader,
-	IN PNET_DEV pDev);
-
-UCHAR IgmpMemberCnt(
-	IN PLIST_HEADER pList);
-
-VOID IgmpGroupDelMembers(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pMemberAddr,
-	IN PNET_DEV pDev);
-
-INT Set_IgmpSn_Enable_Proc(
-	IN PRTMP_ADAPTER pAd,
-	IN PSTRING arg);
-
-INT Set_IgmpSn_AddEntry_Proc(
-	IN PRTMP_ADAPTER pAd,
-	IN PSTRING arg);
-
-INT Set_IgmpSn_DelEntry_Proc(
-	IN PRTMP_ADAPTER pAd,
-	IN PSTRING arg);
-
-INT Set_IgmpSn_TabDisplay_Proc(
-	IN PRTMP_ADAPTER pAd,
-	IN PSTRING arg);
-
-void rtmp_read_igmp_snoop_from_file(
-	IN  PRTMP_ADAPTER pAd,
-	PSTRING tmpbuf,
-	PSTRING buffer);
-
-NDIS_STATUS IgmpPktInfoQuery(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pSrcBufVA,
-	IN PNDIS_PACKET pPacket,
-	IN UCHAR apidx,
-	OUT BOOLEAN *pInIgmpGroup,
-	OUT PMULTICAST_FILTER_TABLE_ENTRY *ppGroupEntry);
-
-NDIS_STATUS IgmpPktClone(
-	IN PRTMP_ADAPTER pAd,
-	IN PNDIS_PACKET pPacket,
-	IN UCHAR QueIdx,
-	IN PMULTICAST_FILTER_TABLE_ENTRY pGroupEntry);
-
-#endif /* __RTMP_IGMP_SNOOP_H__ */
diff --git a/drivers/staging/rt3090/ipv6.h b/drivers/staging/rt3090/ipv6.h
deleted file mode 100644
index c34a5f2..0000000
--- a/drivers/staging/rt3090/ipv6.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    ipv6.h
-
-    Abstract:
-    Miniport generic portion header file
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-*/
-
-#ifndef __IPV6_HDR_H_
-#define __IPV6_HDR_H_
-
-#define IPV6_ADDR_LEN 16
-#define IPV6_HDR_LEN  40
-
-// IPv6 address definition
-#define IPV6_LINK_LOCAL_ADDR_PREFIX		0xFE8
-#define IPV6_SITE_LOCAL_ADDR_PREFIX		0xFEC
-#define IPV6_LOCAL_ADDR_PREFIX			0xFE8
-#define IPV6_MULTICAST_ADDR_PREFIX		0xFF
-#define IPV6_LOOPBACK_ADDR				0x1
-#define IPV6_UNSPECIFIED_ADDR			0x0
-
-// defined as sequence in IPv6 header
-#define IPV6_NEXT_HEADER_HOP_BY_HOP		0x00	// 0
-#define IPV6_NEXT_HEADER_DESTINATION	0x3c	// 60
-#define IPV6_NEXT_HEADER_ROUTING		0x2b	// 43
-#define IPV6_NEXT_HEADER_FRAGMENT		0x2c	// 44
-#define IPV6_NEXT_HEADER_AUTHENTICATION	0x33	// 51
-#define IPV6_NEXT_HEADER_ENCAPSULATION	0x32	// 50, RFC-2406
-#define IPV6_NEXT_HEADER_NONE			0x3b	// 59
-
-#define IPV6_NEXT_HEADER_TCP			0x06
-#define IPV6_NEXT_HEADER_UDP			0x11
-#define IPV6_NEXT_HEADER_ICMPV6			0x3a
-
-// ICMPv6 msg type definition
-#define ICMPV6_MSG_TYPE_ROUTER_SOLICITATION			0x85 // 133
-#define ROUTER_SOLICITATION_FIXED_LEN				8
-
-#define ICMPV6_MSG_TYPE_ROUTER_ADVERTISEMENT		0x86 // 134
-#define ROUTER_ADVERTISEMENT_FIXED_LEN				16
-
-#define ICMPV6_MSG_TYPE_NEIGHBOR_SOLICITATION		0x87 // 135
-#define NEIGHBOR_SOLICITATION_FIXED_LEN				24
-
-#define ICMPV6_MSG_TYPE_NEIGHBOR_ADVERTISEMENT		0x88 // 136
-#define NEIGHBOR_ADVERTISEMENT_FIXED_LEN			24
-
-#define ICMPV6_MSG_TYPE_REDIRECT					0x89 // 137
-#define REDIRECT_FIXED_LEN							40
-
-/* IPv6 Address related structures */
-typedef struct rt_ipv6_addr_
-{
-	union
-	{
-		UCHAR	ipv6Addr8[16];
-		USHORT	ipv6Addr16[8];
-		UINT32	ipv6Addr32[4];
-	}addr;
-#define ipv6_addr			addr.ipv6Addr8
-#define ipv6_addr16			addr.ipv6Addr16
-#define ipv6_addr32			addr.ipv6Addr32
-}RT_IPV6_ADDR, *PRT_IPV6_ADDR;
-
-
-#define PRINT_IPV6_ADDR(ipv6Addr)	\
-	OS_NTOHS((ipv6Addr).ipv6_addr16[0]), \
-	OS_NTOHS((ipv6Addr).ipv6_addr16[1]), \
-	OS_NTOHS((ipv6Addr).ipv6_addr16[2]), \
-	OS_NTOHS((ipv6Addr).ipv6_addr16[3]), \
-	OS_NTOHS((ipv6Addr).ipv6_addr16[4]), \
-	OS_NTOHS((ipv6Addr).ipv6_addr16[5]), \
-	OS_NTOHS((ipv6Addr).ipv6_addr16[6]), \
-	OS_NTOHS((ipv6Addr).ipv6_addr16[7])
-
-
-/*IPv6 Header related structures */
-typedef struct PACKED _rt_ipv6_hdr_
-{
-	UINT32			ver:4,
-					trafficClass:8,
-				flowLabel:20;
-	USHORT			payload_len;
-	UCHAR			nextHdr;
-	UCHAR			hopLimit;
-	RT_IPV6_ADDR	srcAddr;
-	RT_IPV6_ADDR	dstAddr;
-}RT_IPV6_HDR, *PRT_IPV6_HDR;
-
-
-typedef struct PACKED _rt_ipv6_ext_hdr_
-{
-	UCHAR	nextProto; // Indicate the protocol type of next extension header.
-	UCHAR	extHdrLen; // optional field for msg length of this extension header which didn't include the first "nextProto" field.
-	UCHAR	octets[1]; // hook to extend header message body.
-}RT_IPV6_EXT_HDR, *PRT_IPV6_EXT_HDR;
-
-
-/* ICMPv6 related structures */
-typedef struct PACKED _rt_ipv6_icmpv6_hdr_
-{
-	UCHAR	type;
-	UCHAR	code;
-	USHORT	chksum;
-	UCHAR	octets[1]; //hook to extend header message body.
-}RT_ICMPV6_HDR, *PRT_ICMPV6_HDR;
-
-
-typedef struct PACKED _rt_icmp6_option_hdr_
-{
-	UCHAR type;
-	UCHAR len;
-	UCHAR octet[1];
-}RT_ICMPV6_OPTION_HDR, *PRT_ICMPV6_OPTION_HDR;
-
-typedef enum{
-// Defined ICMPv6 Option Types.
-	TYPE_SRC_LL_ADDR	= 1,
-	TYPE_TGT_LL_ADDR	= 2,
-	TYPE_PREFIX_INFO			= 3,
-	TYPE_REDIRECTED_HDR			= 4,
-	TYPE_MTU					= 5,
-}ICMPV6_OPTIONS_TYPE_DEF;
-
-
-static inline BOOLEAN IPv6ExtHdrHandle(
-	RT_IPV6_EXT_HDR		*pExtHdr,
-	UCHAR				*pProto,
-	UINT32				*pOffset)
-{
-	UCHAR nextProto = 0xff;
-	UINT32 extLen = 0;
-	BOOLEAN status = TRUE;
-
-	//printk("%s(): parsing the Extension Header with Protocol(0x%x):\n", __FUNCTION__, *pProto);
-	switch (*pProto)
-	{
-		case IPV6_NEXT_HEADER_HOP_BY_HOP:
-			// IPv6ExtHopByHopHandle();
-			nextProto = pExtHdr->nextProto;
-			extLen = (pExtHdr->extHdrLen + 1) * 8;
-			break;
-
-		case IPV6_NEXT_HEADER_DESTINATION:
-			// IPv6ExtDestHandle();
-			nextProto = pExtHdr->nextProto;
-			extLen = (pExtHdr->extHdrLen + 1) * 8;
-			break;
-
-		case IPV6_NEXT_HEADER_ROUTING:
-			// IPv6ExtRoutingHandle();
-			nextProto = pExtHdr->nextProto;
-			extLen = (pExtHdr->extHdrLen + 1) * 8;
-			break;
-
-		case IPV6_NEXT_HEADER_FRAGMENT:
-			// IPv6ExtFragmentHandle();
-			nextProto = pExtHdr->nextProto;
-			extLen = 8; // The Fragment header length is fixed to 8 bytes.
-			break;
-
-		case IPV6_NEXT_HEADER_AUTHENTICATION:
-		//   IPV6_NEXT_HEADER_ENCAPSULATION:
-			/*
-				TODO: Not support. For encryption issue.
-			*/
-			nextProto = 0xFF;
-			status = FALSE;
-			break;
-
-		default:
-			nextProto = 0xFF;
-			status = FALSE;
-			break;
-	}
-
-	*pProto = nextProto;
-	*pOffset += extLen;
-	//printk("%s(): nextProto = 0x%x!, offset=0x%x!\n", __FUNCTION__, nextProto, offset);
-
-	return status;
-
-}
-
-#endif // __IPV6_HDR_H_ //
diff --git a/drivers/staging/rt3090/link_list.h b/drivers/staging/rt3090/link_list.h
deleted file mode 100644
index 205b610..0000000
--- a/drivers/staging/rt3090/link_list.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
- */
-
-#ifndef __LINK_LIST_H__
-#define __LINK_LIST_H__
-
-typedef struct _LIST_ENTRY
-{
-	struct _LIST_ENTRY *pNext;
-} LIST_ENTRY, *PLIST_ENTRY;
-
-typedef struct _LIST_HEADR
-{
-	PLIST_ENTRY pHead;
-	PLIST_ENTRY pTail;
-	UCHAR size;
-} LIST_HEADER, *PLIST_HEADER;
-
-static inline VOID initList(
-	IN PLIST_HEADER pList)
-{
-	pList->pHead = pList->pTail = NULL;
-	pList->size = 0;
-	return;
-}
-
-static inline VOID insertTailList(
-	IN PLIST_HEADER pList,
-	IN PLIST_ENTRY pEntry)
-{
-	pEntry->pNext = NULL;
-	if (pList->pTail)
-		pList->pTail->pNext = pEntry;
-	else
-		pList->pHead = pEntry;
-	pList->pTail = pEntry;
-	pList->size++;
-
-	return;
-}
-
-static inline PLIST_ENTRY removeHeadList(
-	IN PLIST_HEADER pList)
-{
-	PLIST_ENTRY pNext;
-	PLIST_ENTRY pEntry;
-
-	pEntry = pList->pHead;
-	if (pList->pHead != NULL)
-	{
-		pNext = pList->pHead->pNext;
-		pList->pHead = pNext;
-		if (pNext == NULL)
-			pList->pTail = NULL;
-		pList->size--;
-	}
-	return pEntry;
-}
-
-static inline int getListSize(
-	IN PLIST_HEADER pList)
-{
-	return pList->size;
-}
-
-static inline PLIST_ENTRY delEntryList(
-	IN PLIST_HEADER pList,
-	IN PLIST_ENTRY pEntry)
-{
-	PLIST_ENTRY pCurEntry;
-	PLIST_ENTRY pPrvEntry;
-
-	if(pList->pHead == NULL)
-		return NULL;
-
-	if(pEntry == pList->pHead)
-	{
-		pCurEntry = pList->pHead;
-		pList->pHead = pCurEntry->pNext;
-
-		if(pList->pHead == NULL)
-			pList->pTail = NULL;
-
-		pList->size--;
-		return pCurEntry;
-	}
-
-	pPrvEntry = pList->pHead;
-	pCurEntry = pPrvEntry->pNext;
-	while(pCurEntry != NULL)
-	{
-		if (pEntry == pCurEntry)
-		{
-			pPrvEntry->pNext = pCurEntry->pNext;
-
-			if(pEntry == pList->pTail)
-				pList->pTail = pPrvEntry;
-
-			pList->size--;
-			break;
-		}
-		pPrvEntry = pCurEntry;
-		pCurEntry = pPrvEntry->pNext;
-	}
-
-	return pCurEntry;
-}
-
-#endif // ___LINK_LIST_H__ //
diff --git a/drivers/staging/rt3090/mac_pci.h b/drivers/staging/rt3090/mac_pci.h
deleted file mode 100644
index bad04d4..0000000
--- a/drivers/staging/rt3090/mac_pci.h
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-        mac_pci.h
-
-    Abstract:
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
- */
-
-#ifndef __MAC_PCI_H__
-#define __MAC_PCI_H__
-
-#include "rtmp_type.h"
-#include "rtmp_mac.h"
-#include "rtmp_phy.h"
-#include "rtmp_iface.h"
-#include "rtmp_dot11.h"
-
-
-//
-// Device ID & Vendor ID related definitions,
-// NOTE: you should not add the new VendorID/DeviceID here unless you not sure it belongs to what chip.
-//
-#define NIC_PCI_VENDOR_ID		0x1814
-#define PCIBUS_INTEL_VENDOR	0x8086
-
-#if !defined(PCI_CAP_ID_EXP)
-#define PCI_CAP_ID_EXP			    0x10
-#endif
-#if !defined(PCI_EXP_LNKCTL)
-#define PCI_EXP_LNKCTL			    0x10
-#endif
-#if !defined(PCI_CLASS_BRIDGE_PCI)
-#define PCI_CLASS_BRIDGE_PCI		0x0604
-#endif
-
-
-
-
-
-#define TXINFO_SIZE						0
-#define RTMP_PKT_TAIL_PADDING			0
-#define fRTMP_ADAPTER_NEED_STOP_TX	0
-
-#define AUX_CTRL           0x10c
-
-//
-// TX descriptor format, Tx	ring, Mgmt Ring
-//
-#ifdef RT_BIG_ENDIAN
-typedef	struct	PACKED _TXD_STRUC {
-	// Word 0
-	UINT32		SDPtr0;
-	// Word 1
-	UINT32		DMADONE:1;
-	UINT32		LastSec0:1;
-	UINT32		SDLen0:14;
-	UINT32		Burst:1;
-	UINT32		LastSec1:1;
-	UINT32		SDLen1:14;
-	// Word 2
-	UINT32		SDPtr1;
-	// Word 3
-	UINT32		ICO:1;
-	UINT32		UCO:1;
-	UINT32		TCO:1;
-	UINT32		rsv:2;
-	UINT32		QSEL:2;	// select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
-	UINT32		WIV:1;	// Wireless Info Valid. 1 if Driver already fill WI,  o if DMA needs to copy WI to correctposition
-	UINT32		rsv2:24;
-}	TXD_STRUC, *PTXD_STRUC;
-#else
-typedef	struct	PACKED _TXD_STRUC {
-	// Word	0
-	UINT32		SDPtr0;
-	// Word	1
-	UINT32		SDLen1:14;
-	UINT32		LastSec1:1;
-	UINT32		Burst:1;
-	UINT32		SDLen0:14;
-	UINT32		LastSec0:1;
-	UINT32		DMADONE:1;
-	//Word2
-	UINT32		SDPtr1;
-	//Word3
-	UINT32		rsv2:24;
-	UINT32		WIV:1;	// Wireless Info Valid. 1 if Driver already fill WI,  o if DMA needs to copy WI to correctposition
-	UINT32		QSEL:2;	// select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
-	UINT32		rsv:2;
-	UINT32		TCO:1;	//
-	UINT32		UCO:1;	//
-	UINT32		ICO:1;	//
-}	TXD_STRUC, *PTXD_STRUC;
-#endif
-
-
-//
-// Rx descriptor format, Rx Ring
-//
-#ifdef RT_BIG_ENDIAN
-typedef	struct	PACKED _RXD_STRUC{
-	// Word 0
-	UINT32		SDP0;
-	// Word 1
-	UINT32		DDONE:1;
-	UINT32		LS0:1;
-	UINT32		SDL0:14;
-	UINT32		Rsv:2;
-	UINT32		SDL1:14;
-	// Word 2
-	UINT32		SDP1;
-	// Word 3
-	UINT32		Rsv1:13;
-	UINT32		PlcpRssil:1;// To be moved
-	UINT32		PlcpSignal:1;		// To be moved
-	UINT32		Decrypted:1;	// this frame is being decrypted.
-	UINT32		AMPDU:1;
-	UINT32		L2PAD:1;
-	UINT32		RSSI:1;
-	UINT32		HTC:1;
-	UINT32		AMSDU:1;		// rx with 802.3 header, not 802.11 header. obsolete.
-	UINT32		CipherErr:2;        // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid
-	UINT32		Crc:1;              // 1: CRC error
-	UINT32		MyBss:1;	// 1: this frame belongs to the same BSSID
-	UINT32		Bcast:1;            // 1: this is a broadcast frame
-	UINT32		Mcast:1;            // 1: this is a multicast frame
-	UINT32		U2M:1;              // 1: this RX frame is unicast to me
-	UINT32		FRAG:1;
-	UINT32		NULLDATA:1;
-	UINT32		DATA:1;
-	UINT32		BA:1;
-
-}	RXD_STRUC, *PRXD_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
-#else
-typedef	struct	PACKED _RXD_STRUC{
-	// Word	0
-	UINT32		SDP0;
-	// Word	1
-	UINT32		SDL1:14;
-	UINT32		Rsv:2;
-	UINT32		SDL0:14;
-	UINT32		LS0:1;
-	UINT32		DDONE:1;
-	// Word	2
-	UINT32		SDP1;
-	// Word	3
-	UINT32		BA:1;
-	UINT32		DATA:1;
-	UINT32		NULLDATA:1;
-	UINT32		FRAG:1;
-	UINT32		U2M:1;              // 1: this RX frame is unicast to me
-	UINT32		Mcast:1;            // 1: this is a multicast frame
-	UINT32		Bcast:1;            // 1: this is a broadcast frame
-	UINT32		MyBss:1;	// 1: this frame belongs to the same BSSID
-	UINT32		Crc:1;              // 1: CRC error
-	UINT32		CipherErr:2;        // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid
-	UINT32		AMSDU:1;		// rx with 802.3 header, not 802.11 header.
-	UINT32		HTC:1;
-	UINT32		RSSI:1;
-	UINT32		L2PAD:1;
-	UINT32		AMPDU:1;
-	UINT32		Decrypted:1;	// this frame is being decrypted.
-	UINT32		PlcpSignal:1;		// To be moved
-	UINT32		PlcpRssil:1;// To be moved
-	UINT32		Rsv1:13;
-}	RXD_STRUC, *PRXD_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
-#endif
-
-#ifdef BIG_ENDIAN
-typedef union _TX_ATTENUATION_CTRL_STRUC
-{
-	struct
-	{
-		ULONG	Reserve1:20;
-		ULONG	PCIE_PHY_TX_ATTEN_EN:1;
-		ULONG	PCIE_PHY_TX_ATTEN_VALUE:3;
-		ULONG	Reserve2:7;
-		ULONG	RF_ISOLATION_ENABLE:1;
-	} field;
-
-	ULONG	word;
-} TX_ATTENUATION_CTRL_STRUC, *PTX_ATTENUATION_CTRL_STRUC;
-#else
-typedef union _TX_ATTENUATION_CTRL_STRUC {
-	struct
-	{
-		ULONG	RF_ISOLATION_ENABLE:1;
-		ULONG	Reserve2:7;
-		ULONG	PCIE_PHY_TX_ATTEN_VALUE:3;
-		ULONG	PCIE_PHY_TX_ATTEN_EN:1;
-		ULONG	Reserve1:20;
-	} field;
-
-	ULONG	word;
-} TX_ATTENUATION_CTRL_STRUC, *PTX_ATTENUATION_CTRL_STRUC;
-#endif
-/* ----------------- EEPROM Related MACRO ----------------- */
-
-// 8051 firmware image for RT2860 - base address = 0x4000
-#define FIRMWARE_IMAGE_BASE     0x2000
-#define MAX_FIRMWARE_IMAGE_SIZE 0x2000    // 8kbyte
-
-
-/* ----------------- Frimware Related MACRO ----------------- */
-#define RTMP_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen)			\
-	do{								\
-		ULONG	_i, _firm;					\
-		RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x10000);		\
-									\
-		for(_i=0; _i<_FwLen; _i+=4)				\
-		{							\
-			_firm = _pFwImage[_i] +				\
-			   (_pFwImage[_i+3] << 24) +			\
-			   (_pFwImage[_i+2] << 16) +			\
-			   (_pFwImage[_i+1] << 8);			\
-			RTMP_IO_WRITE32(_pAd, FIRMWARE_IMAGE_BASE + _i, _firm);	\
-		}							\
-		RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x00000);		\
-		RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x00001);		\
-									\
-		/* initialize BBP R/W access agent */			\
-		RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, 0);		\
-		RTMP_IO_WRITE32(_pAd, H2M_MAILBOX_CSR, 0);		\
-	}while(0)
-
-
-/* ----------------- TX Related MACRO ----------------- */
-#define RTMP_START_DEQUEUE(pAd, QueIdx, irqFlags)		do{}while(0)
-#define RTMP_STOP_DEQUEUE(pAd, QueIdx, irqFlags)		do{}while(0)
-
-
-#define RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \
-		((freeNum) >= (ULONG)(pTxBlk->TotalFragNum + RTMP_GET_PACKET_FRAGMENTS(pPacket) + 3)) /* rough estimate we will use 3 more descriptor. */
-#define RTMP_RELEASE_DESC_RESOURCE(pAd, QueIdx)	\
-		do{}while(0)
-
-#define NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, freeNum, _TxFrameType) \
-		(((freeNum != (TX_RING_SIZE-1)) && (pAd->TxSwQueue[QueIdx].Number == 0)) || (freeNum<3))
-		//(((freeNum) != (TX_RING_SIZE-1)) && (pAd->TxSwQueue[QueIdx].Number == 1 /*0*/))
-
-
-#define HAL_KickOutMgmtTx(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen)	\
-			RtmpPCIMgmtKickOut(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen)
-
-#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)	\
-		/* RtmpPCI_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)*/
-
-#define HAL_WriteTxResource(pAd, pTxBlk,bIsLast, pFreeNumber)	\
-			RtmpPCI_WriteSingleTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)
-
-#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \
-			RtmpPCI_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber)
-
-#define HAL_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber)	\
-			RtmpPCI_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber)
-
-#define HAL_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx)	\
-			RtmpPCI_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx)
-
-#define HAL_LastTxIdx(_pAd, _QueIdx,_LastTxIdx) \
-			/*RtmpPCIDataLastTxIdx(_pAd, _QueIdx,_LastTxIdx)*/
-
-#define HAL_KickOutTx(_pAd, _pTxBlk, _QueIdx)	\
-			RTMP_IO_WRITE32((_pAd), TX_CTX_IDX0+((_QueIdx)*0x10), (_pAd)->TxRing[(_QueIdx)].TxCpuIdx)
-/*			RtmpPCIDataKickOut(_pAd, _pTxBlk, _QueIdx)*/
-
-#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen)	\
-			MiniportMMRequest(_pAd, _QueIdx, _pNullFrame, _frameLen)
-
-#define GET_TXRING_FREENO(_pAd, _QueIdx) \
-	(_pAd->TxRing[_QueIdx].TxSwFreeIdx > _pAd->TxRing[_QueIdx].TxCpuIdx)	? \
-			(_pAd->TxRing[_QueIdx].TxSwFreeIdx - _pAd->TxRing[_QueIdx].TxCpuIdx - 1) \
-			 :	\
-			(_pAd->TxRing[_QueIdx].TxSwFreeIdx + TX_RING_SIZE - _pAd->TxRing[_QueIdx].TxCpuIdx - 1);
-
-
-#define GET_MGMTRING_FREENO(_pAd) \
-	(_pAd->MgmtRing.TxSwFreeIdx > _pAd->MgmtRing.TxCpuIdx)	? \
-			(_pAd->MgmtRing.TxSwFreeIdx - _pAd->MgmtRing.TxCpuIdx - 1) \
-			 :	\
-			(_pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE - _pAd->MgmtRing.TxCpuIdx - 1);
-
-
-/* ----------------- RX Related MACRO ----------------- */
-
-
-/* ----------------- ASIC Related MACRO ----------------- */
-// reset MAC of a station entry to 0x000000000000
-#define RTMP_STA_ENTRY_MAC_RESET(pAd, Wcid)	\
-	AsicDelWcidTab(pAd, Wcid);
-
-// add this entry into ASIC RX WCID search table
-#define RTMP_STA_ENTRY_ADD(pAd, pEntry)		\
-	AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr);
-
-// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
-// Set MAC register value according operation mode
-#define RTMP_UPDATE_PROTECT(pAd)	\
-	AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0);
-// end johnli
-
-// remove Pair-wise key material from ASIC
-#define RTMP_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid)	\
-	AsicRemovePairwiseKeyEntry(pAd, BssIdx, (UCHAR)Wcid);
-
-// add Client security information into ASIC WCID table and IVEIV table
-#define RTMP_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry)		\
-	RTMPAddWcidAttributeEntry(pAd, apidx, KeyID,			\
-							pAd->SharedKey[apidx][KeyID].CipherAlg, pEntry);
-
-#define RTMP_SECURITY_KEY_ADD(pAd, apidx, KeyID, pEntry)		\
-	{	/* update pairwise key information to ASIC Shared Key Table */	\
-		AsicAddSharedKeyEntry(pAd, apidx, KeyID,					\
-						  pAd->SharedKey[apidx][KeyID].CipherAlg,		\
-						  pAd->SharedKey[apidx][KeyID].Key,				\
-						  pAd->SharedKey[apidx][KeyID].TxMic,			\
-						  pAd->SharedKey[apidx][KeyID].RxMic);			\
-		/* update ASIC WCID attribute table and IVEIV table */			\
-		RTMPAddWcidAttributeEntry(pAd, apidx, KeyID,					\
-						  pAd->SharedKey[apidx][KeyID].CipherAlg,		\
-						  pEntry); }
-
-
-// Insert the BA bitmap to ASIC for the Wcid entry
-#define RTMP_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID)	\
-		do{					\
-			UINT32	_Value = 0, _Offset;					\
-			_Offset = MAC_WCID_BASE + (_Aid) * HW_WCID_ENTRY_SIZE + 4;	\
-			RTMP_IO_READ32((_pAd), _Offset, &_Value);\
-			_Value |= (0x10000<<(_TID));	\
-			RTMP_IO_WRITE32((_pAd), _Offset, _Value);\
-		}while(0)
-
-
-// Remove the BA bitmap from ASIC for the Wcid entry
-//		bitmap field starts at 0x10000 in ASIC WCID table
-#define RTMP_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID)				\
-		do{								\
-			UINT32	_Value = 0, _Offset;				\
-			_Offset = MAC_WCID_BASE + (_Wcid) * HW_WCID_ENTRY_SIZE + 4;	\
-			RTMP_IO_READ32((_pAd), _Offset, &_Value);			\
-			_Value &= (~(0x10000 << (_TID)));				\
-			RTMP_IO_WRITE32((_pAd), _Offset, _Value);			\
-		}while(0)
-
-
-/* ----------------- Interface Related MACRO ----------------- */
-
-//
-// Enable & Disable NIC interrupt via writing interrupt mask register
-// Since it use ADAPTER structure, it have to be put after structure definition.
-//
-#define RTMP_ASIC_INTERRUPT_DISABLE(_pAd)		\
-	do{			\
-		RTMP_IO_WRITE32((_pAd), INT_MASK_CSR, 0x0);     /* 0: disable */	\
-		RTMP_CLEAR_FLAG((_pAd), fRTMP_ADAPTER_INTERRUPT_ACTIVE);		\
-	}while(0)
-
-#define RTMP_ASIC_INTERRUPT_ENABLE(_pAd)\
-	do{				\
-		RTMP_IO_WRITE32((_pAd), INT_MASK_CSR, (_pAd)->int_enable_reg /*DELAYINTMASK*/);     /* 1:enable */	\
-		RTMP_SET_FLAG((_pAd), fRTMP_ADAPTER_INTERRUPT_ACTIVE);	\
-	}while(0)
-
-
-#define RTMP_IRQ_INIT(pAd)	\
-	{	pAd->int_enable_reg = ((DELAYINTMASK) |		\
-					(RxINT|TxDataInt|TxMgmtInt)) & ~(0x03);	\
-		pAd->int_disable_mask = 0;						\
-		pAd->int_pending = 0; }
-
-#define RTMP_IRQ_ENABLE(pAd)					\
-	{	/* clear garbage ints */			\
-		RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, 0xffffffff);\
-		RTMP_ASIC_INTERRUPT_ENABLE(pAd); }
-
-
-/* ----------------- MLME Related MACRO ----------------- */
-#define RTMP_MLME_HANDLER(pAd)			MlmeHandler(pAd)
-
-#define RTMP_MLME_PRE_SANITY_CHECK(pAd)
-
-#define RTMP_MLME_STA_QUICK_RSP_WAKE_UP(pAd)	\
-		RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
-
-#define RTMP_MLME_RESET_STATE_MACHINE(pAd)	\
-		MlmeRestartStateMachine(pAd)
-
-#define RTMP_HANDLE_COUNTER_MEASURE(_pAd, _pEntry)\
-		HandleCounterMeasure(_pAd, _pEntry)
-
-/* ----------------- Power Save Related MACRO ----------------- */
-#define RTMP_PS_POLL_ENQUEUE(pAd)				EnqueuePsPoll(pAd)
-
-
-// For RTMPPCIePowerLinkCtrlRestore () function
-#define RESTORE_HALT		1
-#define RESTORE_WAKEUP		2
-#define RESTORE_CLOSE           3
-
-#define PowerSafeCID		1
-#define PowerRadioOffCID	2
-#define PowerWakeCID		3
-#define CID0MASK		0x000000ff
-#define CID1MASK		0x0000ff00
-#define CID2MASK		0x00ff0000
-#define CID3MASK		0xff000000
-
-
-#ifdef CONFIG_STA_SUPPORT
-#define RTMP_STA_FORCE_WAKEUP(pAd, bFromTx) \
-    RT28xxPciStaAsicForceWakeup(pAd, bFromTx);
-
-#define RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \
-    RT28xxPciStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
-
-#define RTMP_SET_PSM_BIT(_pAd, _val) \
-	MlmeSetPsmBit(_pAd, _val);
-#endif // CONFIG_STA_SUPPORT //
-
-#define RTMP_MLME_RADIO_ON(pAd) \
-    RT28xxPciMlmeRadioOn(pAd);
-
-#define RTMP_MLME_RADIO_OFF(pAd) \
-    RT28xxPciMlmeRadioOFF(pAd);
-
-#endif //__MAC_PCI_H__ //
diff --git a/drivers/staging/rt3090/mlme.h b/drivers/staging/rt3090/mlme.h
deleted file mode 100644
index 2336743..0000000
--- a/drivers/staging/rt3090/mlme.h
+++ /dev/null
@@ -1,1360 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    mlme.h
-
-    Abstract:
-    Miniport generic portion header file
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-	John Chang	2003-08-28		Created
-	John Chang  2004-09-06      modified for RT2600
-*/
-#ifndef __MLME_H__
-#define __MLME_H__
-
-#include "rtmp_dot11.h"
-
-#ifdef CONFIG_STA_SUPPORT
-#endif // CONFIG_STA_SUPPORT //
-
-
-// maximum supported capability information -
-// ESS, IBSS, Privacy, Short Preamble, Spectrum mgmt, Short Slot
-#define SUPPORTED_CAPABILITY_INFO   0x0533
-
-#define END_OF_ARGS                 -1
-#define LFSR_MASK                   0x80000057
-#define MLME_TASK_EXEC_INTV         100/*200*/       //
-#define LEAD_TIME                   5
-#define MLME_TASK_EXEC_MULTIPLE       10  /*5*/       // MLME_TASK_EXEC_MULTIPLE * MLME_TASK_EXEC_INTV = 1 sec
-#define REORDER_EXEC_INTV		100       // 0.1 sec
-//#define TBTT_PRELOAD_TIME         384        // usec. LomgPreamble + 24-byte at 1Mbps
-
-// The definition of Radar detection duration region
-#define CE		0
-#define FCC		1
-#define JAP		2
-#define JAP_W53	3
-#define JAP_W56	4
-#define MAX_RD_REGION 5
-
-#define BEACON_LOST_TIME            4 * OS_HZ    // 2048 msec = 2 sec
-
-#define DLS_TIMEOUT                 1200      // unit: msec
-#define AUTH_TIMEOUT                300       // unit: msec
-#define ASSOC_TIMEOUT               300       // unit: msec
-#define JOIN_TIMEOUT                2000        // unit: msec
-#define SHORT_CHANNEL_TIME          90        // unit: msec
-#define MIN_CHANNEL_TIME            110        // unit: msec, for dual band scan
-#define MAX_CHANNEL_TIME            140       // unit: msec, for single band scan
-#define	FAST_ACTIVE_SCAN_TIME	    30		  // Active scan waiting for probe response time
-#define CW_MIN_IN_BITS              4         // actual CwMin = 2^CW_MIN_IN_BITS - 1
-#define LINK_DOWN_TIMEOUT           20000      // unit: msec
-#define AUTO_WAKEUP_TIMEOUT			70			//unit: msec
-
-
-#ifdef CONFIG_STA_SUPPORT
-#define CW_MAX_IN_BITS              10        // actual CwMax = 2^CW_MAX_IN_BITS - 1
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef CONFIG_APSTA_MIXED_SUPPORT
-extern UINT32 CW_MAX_IN_BITS;
-#endif // CONFIG_APSTA_MIXED_SUPPORT //
-
-// Note: RSSI_TO_DBM_OFFSET has been changed to variable for new RF (2004-0720).
-// SHould not refer to this constant anymore
-//#define RSSI_TO_DBM_OFFSET          120 // for RT2530 RSSI-115 = dBm
-#define RSSI_FOR_MID_TX_POWER       -55  // -55 db is considered mid-distance
-#define RSSI_FOR_LOW_TX_POWER       -45  // -45 db is considered very short distance and
-                                        // eligible to use a lower TX power
-#define RSSI_FOR_LOWEST_TX_POWER    -30
-//#define MID_TX_POWER_DELTA          0   // 0 db from full TX power upon mid-distance to AP
-#define LOW_TX_POWER_DELTA          6    // -3 db from full TX power upon very short distance. 1 grade is 0.5 db
-#define LOWEST_TX_POWER_DELTA       16   // -8 db from full TX power upon shortest distance. 1 grade is 0.5 db
-
-#define RSSI_TRIGGERED_UPON_BELOW_THRESHOLD     0
-#define RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD   1
-#define RSSI_THRESHOLD_FOR_ROAMING              25
-#define RSSI_DELTA                              5
-
-// Channel Quality Indication
-#define CQI_IS_GOOD(cqi)            ((cqi) >= 50)
-//#define CQI_IS_FAIR(cqi)          (((cqi) >= 20) && ((cqi) < 50))
-#define CQI_IS_POOR(cqi)            (cqi < 50)  //(((cqi) >= 5) && ((cqi) < 20))
-#define CQI_IS_BAD(cqi)             (cqi < 5)
-#define CQI_IS_DEAD(cqi)            (cqi == 0)
-
-// weighting factor to calculate Channel quality, total should be 100%
-#define RSSI_WEIGHTING                   50
-#define TX_WEIGHTING                     30
-#define RX_WEIGHTING                     20
-
-//#define PEER_KEY_NOT_USED                0
-//#define PEER_KEY_64_BIT                  64
-//#define PEER_KEY_128_BIT                 128
-
-//#define PEER_KEY_64BIT_LEN               8
-//#define PEER_KEY_128BIT_LEN              16
-
-#define BSS_NOT_FOUND                    0xFFFFFFFF
-
-
-#ifdef CONFIG_STA_SUPPORT
-#define MAX_LEN_OF_MLME_QUEUE            40 //10
-#endif // CONFIG_STA_SUPPORT //
-
-#define SCAN_PASSIVE                     18		// scan with no probe request, only wait beacon and probe response
-#define SCAN_ACTIVE                      19		// scan with probe request, and wait beacon and probe response
-#define	SCAN_CISCO_PASSIVE				 20		// Single channel passive scan
-#define	SCAN_CISCO_ACTIVE				 21		// Single channel active scan
-#define	SCAN_CISCO_NOISE				 22		// Single channel passive scan for noise histogram collection
-#define	SCAN_CISCO_CHANNEL_LOAD			 23		// Single channel passive scan for channel load collection
-#define FAST_SCAN_ACTIVE                 24		// scan with probe request, and wait beacon and probe response
-
-#ifdef DOT11N_DRAFT3
-#define SCAN_2040_BSS_COEXIST                  26
-#endif // DOT11N_DRAFT3 //
-
-//#define BSS_TABLE_EMPTY(x)             ((x).BssNr == 0)
-#define MAC_ADDR_IS_GROUP(Addr)       (((Addr[0]) & 0x01))
-#define MAC_ADDR_HASH(Addr)            (Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5])
-#define MAC_ADDR_HASH_INDEX(Addr)      (MAC_ADDR_HASH(Addr) % HASH_TABLE_SIZE)
-#define TID_MAC_HASH(Addr,TID)            (TID^Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5])
-#define TID_MAC_HASH_INDEX(Addr,TID)      (TID_MAC_HASH(Addr,TID) % HASH_TABLE_SIZE)
-
-// LED Control
-// assoiation ON. one LED ON. another blinking when TX, OFF when idle
-// no association, both LED off
-#define ASIC_LED_ACT_ON(pAd)        RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00031e46)
-#define ASIC_LED_ACT_OFF(pAd)       RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00001e46)
-
-// bit definition of the 2-byte pBEACON->Capability field
-#define CAP_IS_ESS_ON(x)                 (((x) & 0x0001) != 0)
-#define CAP_IS_IBSS_ON(x)                (((x) & 0x0002) != 0)
-#define CAP_IS_CF_POLLABLE_ON(x)         (((x) & 0x0004) != 0)
-#define CAP_IS_CF_POLL_REQ_ON(x)         (((x) & 0x0008) != 0)
-#define CAP_IS_PRIVACY_ON(x)             (((x) & 0x0010) != 0)
-#define CAP_IS_SHORT_PREAMBLE_ON(x)      (((x) & 0x0020) != 0)
-#define CAP_IS_PBCC_ON(x)                (((x) & 0x0040) != 0)
-#define CAP_IS_AGILITY_ON(x)             (((x) & 0x0080) != 0)
-#define CAP_IS_SPECTRUM_MGMT(x)          (((x) & 0x0100) != 0)  // 802.11e d9
-#define CAP_IS_QOS(x)                    (((x) & 0x0200) != 0)  // 802.11e d9
-#define CAP_IS_SHORT_SLOT(x)             (((x) & 0x0400) != 0)
-#define CAP_IS_APSD(x)                   (((x) & 0x0800) != 0)  // 802.11e d9
-#define CAP_IS_IMMED_BA(x)               (((x) & 0x1000) != 0)  // 802.11e d9
-#define CAP_IS_DSSS_OFDM(x)              (((x) & 0x2000) != 0)
-#define CAP_IS_DELAY_BA(x)               (((x) & 0x4000) != 0)  // 802.11e d9
-
-#define CAP_GENERATE(ess,ibss,priv,s_pre,s_slot,spectrum)  (((ess) ? 0x0001 : 0x0000) | ((ibss) ? 0x0002 : 0x0000) | ((priv) ? 0x0010 : 0x0000) | ((s_pre) ? 0x0020 : 0x0000) | ((s_slot) ? 0x0400 : 0x0000) | ((spectrum) ? 0x0100 : 0x0000))
-
-//#define STA_QOS_CAPABILITY               0 // 1-byte. see 802.11e d9.0 for bit definition
-
-#define ERP_IS_NON_ERP_PRESENT(x)        (((x) & 0x01) != 0)    // 802.11g
-#define ERP_IS_USE_PROTECTION(x)         (((x) & 0x02) != 0)    // 802.11g
-#define ERP_IS_USE_BARKER_PREAMBLE(x)    (((x) & 0x04) != 0)    // 802.11g
-
-#define DRS_TX_QUALITY_WORST_BOUND       8// 3  // just test by gary
-#define DRS_PENALTY                      8
-
-#define BA_NOTUSE	2
-//BA Policy subfiled value in ADDBA frame
-#define IMMED_BA	1
-#define DELAY_BA	0
-
-// BA Initiator subfield in DELBA frame
-#define ORIGINATOR	1
-#define RECIPIENT	0
-
-// ADDBA Status Code
-#define ADDBA_RESULTCODE_SUCCESS					0
-#define ADDBA_RESULTCODE_REFUSED					37
-#define ADDBA_RESULTCODE_INVALID_PARAMETERS			38
-
-// DELBA Reason Code
-#define DELBA_REASONCODE_QSTA_LEAVING				36
-#define DELBA_REASONCODE_END_BA						37
-#define DELBA_REASONCODE_UNKNOWN_BA					38
-#define DELBA_REASONCODE_TIMEOUT					39
-
-// reset all OneSecTx counters
-#define RESET_ONE_SEC_TX_CNT(__pEntry) \
-if (((__pEntry)) != NULL) \
-{ \
-	(__pEntry)->OneSecTxRetryOkCount = 0; \
-	(__pEntry)->OneSecTxFailCount = 0; \
-	(__pEntry)->OneSecTxNoRetryOkCount = 0; \
-}
-
-//
-// 802.11 frame formats
-//
-//  HT Capability INFO field in HT Cap IE .
-typedef struct PACKED {
-#ifdef RT_BIG_ENDIAN
-	USHORT	LSIGTxopProSup:1;
-	USHORT	Forty_Mhz_Intolerant:1;
-	USHORT	PSMP:1;
-	USHORT	CCKmodein40:1;
-	USHORT	AMsduSize:1;
-	USHORT	DelayedBA:1;	//rt2860c not support
-	USHORT	RxSTBC:2;
-	USHORT	TxSTBC:1;
-	USHORT	ShortGIfor40:1;	//for40MHz
-	USHORT	ShortGIfor20:1;
-	USHORT	GF:1;	//green field
-	USHORT	MimoPs:2;//momi power safe
-	USHORT	ChannelWidth:1;
-	USHORT	AdvCoding:1;
-#else
-	USHORT	AdvCoding:1;
-	USHORT	ChannelWidth:1;
-	USHORT	MimoPs:2;//momi power safe
-	USHORT	GF:1;	//green field
-	USHORT	ShortGIfor20:1;
-	USHORT	ShortGIfor40:1;	//for40MHz
-	USHORT	TxSTBC:1;
-	USHORT	RxSTBC:2;
-	USHORT	DelayedBA:1;	//rt2860c not support
-	USHORT	AMsduSize:1;	// only support as zero
-	USHORT	CCKmodein40:1;
-	USHORT	PSMP:1;
-	USHORT	Forty_Mhz_Intolerant:1;
-	USHORT	LSIGTxopProSup:1;
-#endif	/* !RT_BIG_ENDIAN */
-} HT_CAP_INFO, *PHT_CAP_INFO;
-
-//  HT Capability INFO field in HT Cap IE .
-typedef struct PACKED {
-#ifdef RT_BIG_ENDIAN
-	UCHAR	rsv:3;//momi power safe
-	UCHAR	MpduDensity:3;
-	UCHAR	MaxRAmpduFactor:2;
-#else
-	UCHAR	MaxRAmpduFactor:2;
-	UCHAR	MpduDensity:3;
-	UCHAR	rsv:3;//momi power safe
-#endif /* !RT_BIG_ENDIAN */
-} HT_CAP_PARM, *PHT_CAP_PARM;
-
-//  HT Capability INFO field in HT Cap IE .
-typedef struct PACKED {
-	UCHAR	MCSSet[10];
-	UCHAR	SupRate[2];  // unit : 1Mbps
-#ifdef RT_BIG_ENDIAN
-	UCHAR	rsv:3;
-	UCHAR	MpduDensity:1;
-	UCHAR	TxStream:2;
-	UCHAR	TxRxNotEqual:1;
-	UCHAR	TxMCSSetDefined:1;
-#else
-	UCHAR	TxMCSSetDefined:1;
-	UCHAR	TxRxNotEqual:1;
-	UCHAR	TxStream:2;
-	UCHAR	MpduDensity:1;
-	UCHAR	rsv:3;
-#endif // RT_BIG_ENDIAN //
-	UCHAR	rsv3[3];
-} HT_MCS_SET, *PHT_MCS_SET;
-
-//  HT Capability INFO field in HT Cap IE .
-typedef struct PACKED {
-#ifdef RT_BIG_ENDIAN
-	USHORT	rsv2:4;
-	USHORT	RDGSupport:1;	//reverse Direction Grant  support
-	USHORT	PlusHTC:1;	//+HTC control field support
-	USHORT	MCSFeedback:2;	//0:no MCS feedback, 2:unsolicited MCS feedback, 3:Full MCS feedback,  1:rsv.
-	USHORT	rsv:5;//momi power safe
-	USHORT	TranTime:2;
-	USHORT	Pco:1;
-#else
-	USHORT	Pco:1;
-	USHORT	TranTime:2;
-	USHORT	rsv:5;//momi power safe
-	USHORT	MCSFeedback:2;	//0:no MCS feedback, 2:unsolicited MCS feedback, 3:Full MCS feedback,  1:rsv.
-	USHORT	PlusHTC:1;	//+HTC control field support
-	USHORT	RDGSupport:1;	//reverse Direction Grant  support
-	USHORT	rsv2:4;
-#endif /* RT_BIG_ENDIAN */
-} EXT_HT_CAP_INFO, *PEXT_HT_CAP_INFO;
-
-//  HT Beamforming field in HT Cap IE .
-typedef struct PACKED _HT_BF_CAP{
-#ifdef RT_BIG_ENDIAN
-	ULONG	rsv:3;
-	ULONG	ChanEstimation:2;
-	ULONG	CSIRowBFSup:2;
-	ULONG	ComSteerBFAntSup:2;
-	ULONG	NoComSteerBFAntSup:2;
-	ULONG	CSIBFAntSup:2;
-	ULONG	MinGrouping:2;
-	ULONG	ExpComBF:2;
-	ULONG	ExpNoComBF:2;
-	ULONG	ExpCSIFbk:2;
-	ULONG	ExpComSteerCapable:1;
-	ULONG	ExpNoComSteerCapable:1;
-	ULONG	ExpCSICapable:1;
-	ULONG	Calibration:2;
-	ULONG	ImpTxBFCapable:1;
-	ULONG	TxNDPCapable:1;
-	ULONG	RxNDPCapable:1;
-	ULONG	TxSoundCapable:1;
-	ULONG	RxSoundCapable:1;
-	ULONG	TxBFRecCapable:1;
-#else
-	ULONG	TxBFRecCapable:1;
-	ULONG	RxSoundCapable:1;
-	ULONG	TxSoundCapable:1;
-	ULONG	RxNDPCapable:1;
-	ULONG	TxNDPCapable:1;
-	ULONG	ImpTxBFCapable:1;
-	ULONG	Calibration:2;
-	ULONG	ExpCSICapable:1;
-	ULONG	ExpNoComSteerCapable:1;
-	ULONG	ExpComSteerCapable:1;
-	ULONG	ExpCSIFbk:2;
-	ULONG	ExpNoComBF:2;
-	ULONG	ExpComBF:2;
-	ULONG	MinGrouping:2;
-	ULONG	CSIBFAntSup:2;
-	ULONG	NoComSteerBFAntSup:2;
-	ULONG	ComSteerBFAntSup:2;
-	ULONG	CSIRowBFSup:2;
-	ULONG	ChanEstimation:2;
-	ULONG	rsv:3;
-#endif // RT_BIG_ENDIAN //
-} HT_BF_CAP, *PHT_BF_CAP;
-
-//  HT antenna selection field in HT Cap IE .
-typedef struct PACKED _HT_AS_CAP{
-#ifdef RT_BIG_ENDIAN
-	UCHAR	rsv:1;
-	UCHAR	TxSoundPPDU:1;
-	UCHAR	RxASel:1;
-	UCHAR	AntIndFbk:1;
-	UCHAR	ExpCSIFbk:1;
-	UCHAR	AntIndFbkTxASEL:1;
-	UCHAR	ExpCSIFbkTxASEL:1;
-	UCHAR	AntSelect:1;
-#else
-	UCHAR	AntSelect:1;
-	UCHAR	ExpCSIFbkTxASEL:1;
-	UCHAR	AntIndFbkTxASEL:1;
-	UCHAR	ExpCSIFbk:1;
-	UCHAR	AntIndFbk:1;
-	UCHAR	RxASel:1;
-	UCHAR	TxSoundPPDU:1;
-	UCHAR	rsv:1;
-#endif // RT_BIG_ENDIAN //
-} HT_AS_CAP, *PHT_AS_CAP;
-
-// Draft 1.0 set IE length 26, but is extensible..
-#define SIZE_HT_CAP_IE		26
-// The structure for HT Capability IE.
-typedef struct PACKED _HT_CAPABILITY_IE{
-	HT_CAP_INFO		HtCapInfo;
-	HT_CAP_PARM		HtCapParm;
-//	HT_MCS_SET		HtMCSSet;
-	UCHAR			MCSSet[16];
-	EXT_HT_CAP_INFO	ExtHtCapInfo;
-	HT_BF_CAP		TxBFCap;	// beamforming cap. rt2860c not support beamforming.
-	HT_AS_CAP		ASCap;	//antenna selection.
-} HT_CAPABILITY_IE, *PHT_CAPABILITY_IE;
-
-
-// 802.11n draft3 related structure definitions.
-// 7.3.2.60
-#define dot11OBSSScanPassiveDwell							20	// in TU. min amount of time that the STA continously scans each channel when performing an active OBSS scan.
-#define dot11OBSSScanActiveDwell							10	// in TU.min amount of time that the STA continously scans each channel when performing an passive OBSS scan.
-#define dot11BSSWidthTriggerScanInterval					300  // in sec. max interval between scan operations to be performed to detect BSS channel width trigger events.
-#define dot11OBSSScanPassiveTotalPerChannel					200	// in TU. min total amount of time that the STA scans each channel when performing a passive OBSS scan.
-#define dot11OBSSScanActiveTotalPerChannel					20	//in TU. min total amount of time that the STA scans each channel when performing a active OBSS scan
-#define dot11BSSWidthChannelTransactionDelayFactor			5	// min ratio between the delay time in performing a switch from 20MHz BSS to 20/40 BSS operation and the maximum
-																//	interval between overlapping BSS scan operations.
-#define dot11BSSScanActivityThreshold						25	// in %%, max total time that a STA may be active on the medium during a period of
-																//	(dot11BSSWidthChannelTransactionDelayFactor * dot11BSSWidthTriggerScanInterval) seconds without
-																//	being obligated to perform OBSS Scan operations. default is 25(== 0.25%)
-
-typedef struct PACKED _OVERLAP_BSS_SCAN_IE{
-	USHORT		ScanPassiveDwell;
-	USHORT		ScanActiveDwell;
-	USHORT		TriggerScanInt;				// Trigger scan interval
-	USHORT		PassiveTalPerChannel;		// passive total per channel
-	USHORT		ActiveTalPerChannel;		// active total per channel
-	USHORT		DelayFactor;				// BSS width channel transition delay factor
-	USHORT		ScanActThre;				// Scan Activity threshold
-}OVERLAP_BSS_SCAN_IE, *POVERLAP_BSS_SCAN_IE;
-
-
-//  7.3.2.56. 20/40 Coexistence element used in  Element ID = 72 = IE_2040_BSS_COEXIST
-typedef union PACKED _BSS_2040_COEXIST_IE{
- struct PACKED {
- #ifdef RT_BIG_ENDIAN
-	UCHAR	rsv:5;
-	UCHAR	BSS20WidthReq:1;
-	UCHAR	Intolerant40:1;
-	UCHAR	InfoReq:1;
- #else
-	UCHAR	InfoReq:1;
-	UCHAR	Intolerant40:1;			// Inter-BSS. set 1 when prohibits a receiving BSS from operating as a 20/40 Mhz BSS.
-	UCHAR	BSS20WidthReq:1;		// Intra-BSS set 1 when prohibits a receiving AP from operating its BSS as a 20/40MHz BSS.
-	UCHAR	rsv:5;
-#endif // RT_BIG_ENDIAN //
-    } field;
- UCHAR   word;
-} BSS_2040_COEXIST_IE, *PBSS_2040_COEXIST_IE;
-
-
-typedef struct  _TRIGGER_EVENTA{
-	BOOLEAN			bValid;
-	UCHAR	BSSID[6];
-	UCHAR	RegClass;	// Regulatory Class
-	USHORT	Channel;
-	ULONG	CDCounter;   // Maintain a seperate count down counter for each Event A.
-} TRIGGER_EVENTA, *PTRIGGER_EVENTA;
-
-// 20/40 trigger event table
-// If one Event A delete or created, or if Event B is detected or not detected, STA should send 2040BSSCoexistence to AP.
-#define MAX_TRIGGER_EVENT		64
-typedef struct  _TRIGGER_EVENT_TAB{
-	UCHAR	EventANo;
-	TRIGGER_EVENTA	EventA[MAX_TRIGGER_EVENT];
-	ULONG			EventBCountDown;	// Count down counter for Event B.
-} TRIGGER_EVENT_TAB, *PTRIGGER_EVENT_TAB;
-
-// 7.3.27 20/40 Bss Coexistence Mgmt capability used in extended capabilities information IE( ID = 127 = IE_EXT_CAPABILITY).
-//	This is the first octet and was defined in 802.11n D3.03 and 802.11yD9.0
-typedef struct PACKED _EXT_CAP_INFO_ELEMENT{
-#ifdef RT_BIG_ENDIAN
-	UCHAR	rsv2:5;
-	UCHAR	ExtendChannelSwitch:1;
-	UCHAR	rsv:1;
-	UCHAR	BssCoexistMgmtSupport:1;
-#else
-	UCHAR	BssCoexistMgmtSupport:1;
-	UCHAR	rsv:1;
-	UCHAR	ExtendChannelSwitch:1;
-	UCHAR	rsv2:5;
-#endif // RT_BIG_ENDIAN //
-}EXT_CAP_INFO_ELEMENT, *PEXT_CAP_INFO_ELEMENT;
-
-
-// 802.11n 7.3.2.61
-typedef struct PACKED _BSS_2040_COEXIST_ELEMENT{
-	UCHAR					ElementID;		// ID = IE_2040_BSS_COEXIST = 72
-	UCHAR					Len;
-	BSS_2040_COEXIST_IE		BssCoexistIe;
-}BSS_2040_COEXIST_ELEMENT, *PBSS_2040_COEXIST_ELEMENT;
-
-
-//802.11n 7.3.2.59
-typedef struct PACKED _BSS_2040_INTOLERANT_CH_REPORT{
-	UCHAR				ElementID;		// ID = IE_2040_BSS_INTOLERANT_REPORT = 73
-	UCHAR				Len;
-	UCHAR				RegulatoryClass;
-	UCHAR				ChList[0];
-}BSS_2040_INTOLERANT_CH_REPORT, *PBSS_2040_INTOLERANT_CH_REPORT;
-
-
-// The structure for channel switch annoucement IE. This is in 802.11n D3.03
-typedef struct PACKED _CHA_SWITCH_ANNOUNCE_IE{
-	UCHAR			SwitchMode;	//channel switch mode
-	UCHAR			NewChannel;	//
-	UCHAR			SwitchCount;	//
-} CHA_SWITCH_ANNOUNCE_IE, *PCHA_SWITCH_ANNOUNCE_IE;
-
-
-// The structure for channel switch annoucement IE. This is in 802.11n D3.03
-typedef struct PACKED _SEC_CHA_OFFSET_IE{
-	UCHAR			SecondaryChannelOffset;	 // 1: Secondary above, 3: Secondary below, 0: no Secondary
-} SEC_CHA_OFFSET_IE, *PSEC_CHA_OFFSET_IE;
-
-
-// This structure is extracted from struct RT_HT_CAPABILITY
-typedef struct {
-	BOOLEAN			bHtEnable;	 // If we should use ht rate.
-	BOOLEAN			bPreNHt;	 // If we should use ht rate.
-	//Substract from HT Capability IE
-	UCHAR			MCSSet[16];
-} RT_HT_PHY_INFO, *PRT_HT_PHY_INFO;
-
-//This structure substracts ralink supports from all 802.11n-related features.
-//Features not listed here but contained in 802.11n spec are not supported in rt2860.
-typedef struct {
-#ifdef RT_BIG_ENDIAN
-	USHORT	rsv:5;
-	USHORT	AmsduSize:1;	// Max receiving A-MSDU size
-	USHORT	AmsduEnable:1;	// Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benifit of 802.11n
-	USHORT	RxSTBC:2;	// 2 bits
-	USHORT	TxSTBC:1;
-	USHORT	ShortGIfor40:1;	//for40MHz
-	USHORT	ShortGIfor20:1;
-	USHORT	GF:1;	//green field
-	USHORT	MimoPs:2;//mimo power safe MMPS_
-	USHORT	ChannelWidth:1;
-#else
-	USHORT	ChannelWidth:1;
-	USHORT	MimoPs:2;//mimo power safe MMPS_
-	USHORT	GF:1;	//green field
-	USHORT	ShortGIfor20:1;
-	USHORT	ShortGIfor40:1;	//for40MHz
-	USHORT	TxSTBC:1;
-	USHORT	RxSTBC:2;	// 2 bits
-	USHORT	AmsduEnable:1;	// Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benifit of 802.11n
-	USHORT	AmsduSize:1;	// Max receiving A-MSDU size
-	USHORT	rsv:5;
-#endif
-
-	//Substract from Addiont HT INFO IE
-#ifdef RT_BIG_ENDIAN
-	UCHAR	RecomWidth:1;
-	UCHAR	ExtChanOffset:2;	// Please not the difference with following	UCHAR	NewExtChannelOffset; from 802.11n
-	UCHAR	MpduDensity:3;
-	UCHAR	MaxRAmpduFactor:2;
-#else
-	UCHAR	MaxRAmpduFactor:2;
-	UCHAR	MpduDensity:3;
-	UCHAR	ExtChanOffset:2;	// Please not the difference with following	UCHAR	NewExtChannelOffset; from 802.11n
-	UCHAR	RecomWidth:1;
-#endif
-
-#ifdef RT_BIG_ENDIAN
-	USHORT	rsv2:11;
-	USHORT	OBSS_NonHTExist:1;
-	USHORT	rsv3:1;
-	USHORT	NonGfPresent:1;
-	USHORT	OperaionMode:2;
-#else
-	USHORT	OperaionMode:2;
-	USHORT	NonGfPresent:1;
-	USHORT	rsv3:1;
-	USHORT	OBSS_NonHTExist:1;
-	USHORT	rsv2:11;
-#endif
-
-	// New Extension Channel Offset IE
-	UCHAR	NewExtChannelOffset;
-	// Extension Capability IE = 127
-	UCHAR	BSSCoexist2040;
-} RT_HT_CAPABILITY, *PRT_HT_CAPABILITY;
-
-//   field in Addtional HT Information IE .
-typedef struct PACKED {
-#ifdef RT_BIG_ENDIAN
-	UCHAR	SerInterGranu:3;
-	UCHAR	S_PSMPSup:1;
-	UCHAR	RifsMode:1;
-	UCHAR	RecomWidth:1;
-	UCHAR	ExtChanOffset:2;
-#else
-	UCHAR	ExtChanOffset:2;
-	UCHAR	RecomWidth:1;
-	UCHAR	RifsMode:1;
-	UCHAR	S_PSMPSup:1;	 //Indicate support for scheduled PSMP
-	UCHAR	SerInterGranu:3;	 //service interval granularity
-#endif
-} ADD_HTINFO, *PADD_HTINFO;
-
-typedef struct PACKED{
-#ifdef RT_BIG_ENDIAN
-	USHORT	rsv2:11;
-	USHORT	OBSS_NonHTExist:1;
-	USHORT	rsv:1;
-	USHORT	NonGfPresent:1;
-	USHORT	OperaionMode:2;
-#else
-	USHORT	OperaionMode:2;
-	USHORT	NonGfPresent:1;
-	USHORT	rsv:1;
-	USHORT	OBSS_NonHTExist:1;
-	USHORT	rsv2:11;
-#endif
-} ADD_HTINFO2, *PADD_HTINFO2;
-
-
-// TODO: Need sync with spec about the definition of StbcMcs. In Draft 3.03, it's reserved.
-typedef struct PACKED{
-#ifdef RT_BIG_ENDIAN
-	USHORT	rsv:4;
-	USHORT	PcoPhase:1;
-	USHORT	PcoActive:1;
-	USHORT	LsigTxopProt:1;
-	USHORT	STBCBeacon:1;
-	USHORT	DualCTSProtect:1;
-	USHORT	DualBeacon:1;
-	USHORT	StbcMcs:6;
-#else
-	USHORT	StbcMcs:6;
-	USHORT	DualBeacon:1;
-	USHORT	DualCTSProtect:1;
-	USHORT	STBCBeacon:1;
-	USHORT	LsigTxopProt:1;	// L-SIG TXOP protection full support
-	USHORT	PcoActive:1;
-	USHORT	PcoPhase:1;
-	USHORT	rsv:4;
-#endif // RT_BIG_ENDIAN //
-} ADD_HTINFO3, *PADD_HTINFO3;
-
-#define SIZE_ADD_HT_INFO_IE		22
-typedef struct  PACKED{
-	UCHAR				ControlChan;
-	ADD_HTINFO			AddHtInfo;
-	ADD_HTINFO2			AddHtInfo2;
-	ADD_HTINFO3			AddHtInfo3;
-	UCHAR				MCSSet[16];		// Basic MCS set
-} ADD_HT_INFO_IE, *PADD_HT_INFO_IE;
-
-typedef struct  PACKED{
-	UCHAR				NewExtChanOffset;
-} NEW_EXT_CHAN_IE, *PNEW_EXT_CHAN_IE;
-
-typedef struct PACKED _FRAME_802_11 {
-    HEADER_802_11   Hdr;
-    UCHAR            Octet[1];
-}   FRAME_802_11, *PFRAME_802_11;
-
-// QoSNull embedding of management action. When HT Control MA field set to 1.
-typedef struct PACKED _MA_BODY {
-    UCHAR            Category;
-    UCHAR            Action;
-    UCHAR            Octet[1];
-}   MA_BODY, *PMA_BODY;
-
-typedef	struct	PACKED _HEADER_802_3	{
-    UCHAR           DAAddr1[MAC_ADDR_LEN];
-    UCHAR           SAAddr2[MAC_ADDR_LEN];
-    UCHAR           Octet[2];
-}	HEADER_802_3, *PHEADER_802_3;
-////Block ACK related format
-// 2-byte BA Parameter  field  in	DELBA frames to terminate an already set up bA
-typedef struct PACKED{
-#ifdef RT_BIG_ENDIAN
-    USHORT      TID:4;	// value of TC os TS
-    USHORT      Initiator:1;	// 1: originator    0:recipient
-    USHORT      Rsv:11;	// always set to 0
-#else
-    USHORT      Rsv:11;	// always set to 0
-    USHORT      Initiator:1;	// 1: originator    0:recipient
-    USHORT      TID:4;	// value of TC os TS
-#endif /* !RT_BIG_ENDIAN */
-} DELBA_PARM, *PDELBA_PARM;
-
-// 2-byte BA Parameter Set field  in ADDBA frames to signal parm for setting up a BA
-typedef struct PACKED {
-#ifdef RT_BIG_ENDIAN
-    USHORT      BufSize:10;	// number of buffe of size 2304 octetsr
-    USHORT      TID:4;	// value of TC os TS
-    USHORT      BAPolicy:1;	// 1: immediately BA    0:delayed BA
-    USHORT      AMSDUSupported:1;	// 0: not permitted		1: permitted
-#else
-    USHORT      AMSDUSupported:1;	// 0: not permitted		1: permitted
-    USHORT      BAPolicy:1;	// 1: immediately BA    0:delayed BA
-    USHORT      TID:4;	// value of TC os TS
-    USHORT      BufSize:10;	// number of buffe of size 2304 octetsr
-#endif /* !RT_BIG_ENDIAN */
-} BA_PARM, *PBA_PARM;
-
-// 2-byte BA Starting Seq CONTROL field
-typedef union PACKED {
-    struct PACKED {
-#ifdef RT_BIG_ENDIAN
-    USHORT      StartSeq:12;   // sequence number of the 1st MSDU for which this BAR is sent
-	USHORT      FragNum:4;	// always set to 0
-#else
-    USHORT      FragNum:4;	// always set to 0
-	USHORT      StartSeq:12;   // sequence number of the 1st MSDU for which this BAR is sent
-#endif /* RT_BIG_ENDIAN */
-    }   field;
-    USHORT           word;
-} BASEQ_CONTROL, *PBASEQ_CONTROL;
-
-//BAControl and BARControl are the same
-// 2-byte BA CONTROL field in BA frame
-typedef struct PACKED {
-#ifdef RT_BIG_ENDIAN
-    USHORT      TID:4;
-    USHORT      Rsv:9;
-    USHORT      Compressed:1;
-    USHORT      MTID:1;		//EWC V1.24
-    USHORT      ACKPolicy:1; // only related to N-Delayed BA. But not support in RT2860b. 0:NormalACK  1:No ACK
-#else
-    USHORT      ACKPolicy:1; // only related to N-Delayed BA. But not support in RT2860b. 0:NormalACK  1:No ACK
-    USHORT      MTID:1;		//EWC V1.24
-    USHORT      Compressed:1;
-    USHORT      Rsv:9;
-    USHORT      TID:4;
-#endif /* !RT_BIG_ENDIAN */
-} BA_CONTROL, *PBA_CONTROL;
-
-// 2-byte BAR CONTROL field in BAR frame
-typedef struct PACKED {
-#ifdef RT_BIG_ENDIAN
-    USHORT      TID:4;
-    USHORT      Rsv1:9;
-    USHORT      Compressed:1;
-    USHORT      MTID:1;		//if this bit1, use  FRAME_MTBA_REQ,  if 0, use FRAME_BA_REQ
-    USHORT      ACKPolicy:1;
-#else
-    USHORT      ACKPolicy:1; // 0:normal ack,  1:no ack.
-    USHORT      MTID:1;		//if this bit1, use  FRAME_MTBA_REQ,  if 0, use FRAME_BA_REQ
-    USHORT      Compressed:1;
-    USHORT      Rsv1:9;
-    USHORT      TID:4;
-#endif /* !RT_BIG_ENDIAN */
-} BAR_CONTROL, *PBAR_CONTROL;
-
-// BARControl in MTBAR frame
-typedef struct PACKED {
-#ifdef RT_BIG_ENDIAN
-    USHORT      NumTID:4;
-    USHORT      Rsv1:9;
-    USHORT      Compressed:1;
-    USHORT      MTID:1;
-    USHORT      ACKPolicy:1;
-#else
-    USHORT      ACKPolicy:1;
-    USHORT      MTID:1;
-    USHORT      Compressed:1;
-    USHORT      Rsv1:9;
-    USHORT      NumTID:4;
-#endif /* !RT_BIG_ENDIAN */
-} MTBAR_CONTROL, *PMTBAR_CONTROL;
-
-typedef struct PACKED {
-#ifdef RT_BIG_ENDIAN
-    USHORT      TID:4;
-    USHORT      Rsv1:12;
-#else
-    USHORT      Rsv1:12;
-    USHORT      TID:4;
-#endif /* !RT_BIG_ENDIAN */
-} PER_TID_INFO, *PPER_TID_INFO;
-
-typedef struct {
-	PER_TID_INFO      PerTID;
-	BASEQ_CONTROL	 BAStartingSeq;
-} EACH_TID, *PEACH_TID;
-
-
-// BAREQ AND MTBAREQ have the same subtype BAR, 802.11n BAR use compressed bitmap.
-typedef struct PACKED _FRAME_BA_REQ {
-	FRAME_CONTROL   FC;
-	USHORT          Duration;
-	UCHAR           Addr1[MAC_ADDR_LEN];
-	UCHAR           Addr2[MAC_ADDR_LEN];
-	BAR_CONTROL  BARControl;
-	BASEQ_CONTROL	 BAStartingSeq;
-}   FRAME_BA_REQ, *PFRAME_BA_REQ;
-
-typedef struct PACKED _FRAME_MTBA_REQ {
-	FRAME_CONTROL   FC;
-	USHORT          Duration;
-	UCHAR           Addr1[MAC_ADDR_LEN];
-	UCHAR           Addr2[MAC_ADDR_LEN];
-	MTBAR_CONTROL  MTBARControl;
-	PER_TID_INFO	PerTIDInfo;
-	BASEQ_CONTROL	 BAStartingSeq;
-}   FRAME_MTBA_REQ, *PFRAME_MTBA_REQ;
-
-// Compressed format is mandantory in HT STA
-typedef struct PACKED _FRAME_MTBA {
-	FRAME_CONTROL   FC;
-	USHORT          Duration;
-	UCHAR           Addr1[MAC_ADDR_LEN];
-	UCHAR           Addr2[MAC_ADDR_LEN];
-	BA_CONTROL  BAControl;
-	BASEQ_CONTROL	 BAStartingSeq;
-	UCHAR		BitMap[8];
-}   FRAME_MTBA, *PFRAME_MTBA;
-
-typedef struct PACKED _FRAME_PSMP_ACTION {
-	HEADER_802_11   Hdr;
-	UCHAR	Category;
-	UCHAR	Action;
-	UCHAR	Psmp;	// 7.3.1.25
-}   FRAME_PSMP_ACTION, *PFRAME_PSMP_ACTION;
-
-typedef struct PACKED _FRAME_ACTION_HDR {
-	HEADER_802_11   Hdr;
-	UCHAR	Category;
-	UCHAR	Action;
-}   FRAME_ACTION_HDR, *PFRAME_ACTION_HDR;
-
-//Action Frame
-//Action Frame  Category:Spectrum,  Action:Channel Switch. 7.3.2.20
-typedef struct PACKED _CHAN_SWITCH_ANNOUNCE {
-	UCHAR					ElementID;	// ID = IE_CHANNEL_SWITCH_ANNOUNCEMENT = 37
-	UCHAR					Len;
-	CHA_SWITCH_ANNOUNCE_IE	CSAnnounceIe;
-}   CHAN_SWITCH_ANNOUNCE, *PCHAN_SWITCH_ANNOUNCE;
-
-
-//802.11n : 7.3.2.20a
-typedef struct PACKED _SECOND_CHAN_OFFSET {
-	UCHAR				ElementID;		// ID = IE_SECONDARY_CH_OFFSET = 62
-	UCHAR				Len;
-	SEC_CHA_OFFSET_IE	SecChOffsetIe;
-}   SECOND_CHAN_OFFSET, *PSECOND_CHAN_OFFSET;
-
-
-typedef struct PACKED _FRAME_SPETRUM_CS {
-	HEADER_802_11   Hdr;
-	UCHAR	Category;
-	UCHAR	Action;
-	CHAN_SWITCH_ANNOUNCE	CSAnnounce;
-	SECOND_CHAN_OFFSET		SecondChannel;
-}   FRAME_SPETRUM_CS, *PFRAME_SPETRUM_CS;
-
-
-typedef struct PACKED _FRAME_ADDBA_REQ {
-	HEADER_802_11   Hdr;
-	UCHAR	Category;
-	UCHAR	Action;
-	UCHAR	Token;	// 1
-	BA_PARM		BaParm;	      //  2 - 10
-	USHORT		TimeOutValue;	// 0 - 0
-	BASEQ_CONTROL	BaStartSeq; // 0-0
-}   FRAME_ADDBA_REQ, *PFRAME_ADDBA_REQ;
-
-typedef struct PACKED _FRAME_ADDBA_RSP {
-	HEADER_802_11   Hdr;
-	UCHAR	Category;
-	UCHAR	Action;
-	UCHAR	Token;
-	USHORT	StatusCode;
-	BA_PARM		BaParm; //0 - 2
-	USHORT		TimeOutValue;
-}   FRAME_ADDBA_RSP, *PFRAME_ADDBA_RSP;
-
-typedef struct PACKED _FRAME_DELBA_REQ {
-	HEADER_802_11   Hdr;
-	UCHAR	Category;
-	UCHAR	Action;
-	DELBA_PARM		DelbaParm;
-	USHORT	ReasonCode;
-}   FRAME_DELBA_REQ, *PFRAME_DELBA_REQ;
-
-
-//7.2.1.7
-typedef struct PACKED _FRAME_BAR {
-	FRAME_CONTROL   FC;
-	USHORT          Duration;
-	UCHAR           Addr1[MAC_ADDR_LEN];
-	UCHAR           Addr2[MAC_ADDR_LEN];
-	BAR_CONTROL		BarControl;
-	BASEQ_CONTROL	StartingSeq;
-}   FRAME_BAR, *PFRAME_BAR;
-
-//7.2.1.7
-typedef struct PACKED _FRAME_BA {
-	FRAME_CONTROL   FC;
-	USHORT          Duration;
-	UCHAR           Addr1[MAC_ADDR_LEN];
-	UCHAR           Addr2[MAC_ADDR_LEN];
-	BAR_CONTROL		BarControl;
-	BASEQ_CONTROL	StartingSeq;
-	UCHAR		bitmask[8];
-}   FRAME_BA, *PFRAME_BA;
-
-
-// Radio Measuement Request Frame Format
-typedef struct PACKED _FRAME_RM_REQ_ACTION {
-	HEADER_802_11   Hdr;
-	UCHAR	Category;
-	UCHAR	Action;
-	UCHAR	Token;
-	USHORT	Repetition;
-	UCHAR   data[0];
-}   FRAME_RM_REQ_ACTION, *PFRAME_RM_REQ_ACTION;
-
-typedef struct PACKED {
-	UCHAR		ID;
-	UCHAR		Length;
-	UCHAR		ChannelSwitchMode;
-	UCHAR		NewRegClass;
-	UCHAR		NewChannelNum;
-	UCHAR		ChannelSwitchCount;
-} HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE, *PHT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE;
-
-
-//
-// _Limit must be the 2**n - 1
-// _SEQ1 , _SEQ2 must be within 0 ~ _Limit
-//
-#define SEQ_STEPONE(_SEQ1, _SEQ2, _Limit)	((_SEQ1 == ((_SEQ2+1) & _Limit)))
-#define SEQ_SMALLER(_SEQ1, _SEQ2, _Limit)	(((_SEQ1-_SEQ2) & ((_Limit+1)>>1)))
-#define SEQ_LARGER(_SEQ1, _SEQ2, _Limit)	((_SEQ1 != _SEQ2) && !(((_SEQ1-_SEQ2) & ((_Limit+1)>>1))))
-#define SEQ_WITHIN_WIN(_SEQ1, _SEQ2, _WIN, _Limit) (SEQ_LARGER(_SEQ1, _SEQ2, _Limit) &&  \
-												SEQ_SMALLER(_SEQ1, ((_SEQ2+_WIN+1)&_Limit), _Limit))
-
-//
-// Contention-free parameter (without ID and Length)
-//
-typedef struct PACKED {
-    BOOLEAN     bValid;         // 1: variable contains valid value
-    UCHAR       CfpCount;
-    UCHAR       CfpPeriod;
-    USHORT      CfpMaxDuration;
-    USHORT      CfpDurRemaining;
-} CF_PARM, *PCF_PARM;
-
-typedef	struct	_CIPHER_SUITE	{
-	NDIS_802_11_ENCRYPTION_STATUS	PairCipher;		// Unicast cipher 1, this one has more secured cipher suite
-	NDIS_802_11_ENCRYPTION_STATUS	PairCipherAux;	// Unicast cipher 2 if AP announce two unicast cipher suite
-	NDIS_802_11_ENCRYPTION_STATUS	GroupCipher;	// Group cipher
-	USHORT							RsnCapability;	// RSN capability from beacon
-	BOOLEAN							bMixMode;		// Indicate Pair & Group cipher might be different
-}	CIPHER_SUITE, *PCIPHER_SUITE;
-
-// EDCA configuration from AP's BEACON/ProbeRsp
-typedef struct {
-    BOOLEAN     bValid;         // 1: variable contains valid value
-    BOOLEAN     bAdd;         // 1: variable contains valid value
-    BOOLEAN     bQAck;
-    BOOLEAN     bQueueRequest;
-    BOOLEAN     bTxopRequest;
-    BOOLEAN     bAPSDCapable;
-//  BOOLEAN     bMoreDataAck;
-    UCHAR       EdcaUpdateCount;
-    UCHAR       Aifsn[4];       // 0:AC_BK, 1:AC_BE, 2:AC_VI, 3:AC_VO
-    UCHAR       Cwmin[4];
-    UCHAR       Cwmax[4];
-    USHORT      Txop[4];      // in unit of 32-us
-    BOOLEAN     bACM[4];      // 1: Admission Control of AC_BK is mandattory
-} EDCA_PARM, *PEDCA_PARM;
-
-// QBSS LOAD information from QAP's BEACON/ProbeRsp
-typedef struct {
-    BOOLEAN     bValid;                     // 1: variable contains valid value
-    USHORT      StaNum;
-    UCHAR       ChannelUtilization;
-    USHORT      RemainingAdmissionControl;  // in unit of 32-us
-} QBSS_LOAD_PARM, *PQBSS_LOAD_PARM;
-
-// QBSS Info field in QSTA's assoc req
-typedef struct PACKED {
-#ifdef RT_BIG_ENDIAN
-	UCHAR		Rsv2:1;
-	UCHAR		MaxSPLength:2;
-	UCHAR		Rsv1:1;
-	UCHAR		UAPSD_AC_BE:1;
-	UCHAR		UAPSD_AC_BK:1;
-	UCHAR		UAPSD_AC_VI:1;
-	UCHAR		UAPSD_AC_VO:1;
-#else
-    UCHAR		UAPSD_AC_VO:1;
-	UCHAR		UAPSD_AC_VI:1;
-	UCHAR		UAPSD_AC_BK:1;
-	UCHAR		UAPSD_AC_BE:1;
-	UCHAR		Rsv1:1;
-	UCHAR		MaxSPLength:2;
-	UCHAR		Rsv2:1;
-#endif /* !RT_BIG_ENDIAN */
-} QBSS_STA_INFO_PARM, *PQBSS_STA_INFO_PARM;
-
-// QBSS Info field in QAP's Beacon/ProbeRsp
-typedef struct PACKED {
-#ifdef RT_BIG_ENDIAN
-	UCHAR		UAPSD:1;
-	UCHAR		Rsv:3;
-    UCHAR		ParamSetCount:4;
-#else
-    UCHAR		ParamSetCount:4;
-	UCHAR		Rsv:3;
-	UCHAR		UAPSD:1;
-#endif /* !RT_BIG_ENDIAN */
-} QBSS_AP_INFO_PARM, *PQBSS_AP_INFO_PARM;
-
-// QOS Capability reported in QAP's BEACON/ProbeRsp
-// QOS Capability sent out in QSTA's AssociateReq/ReAssociateReq
-typedef struct {
-    BOOLEAN     bValid;                     // 1: variable contains valid value
-    BOOLEAN     bQAck;
-    BOOLEAN     bQueueRequest;
-    BOOLEAN     bTxopRequest;
-//  BOOLEAN     bMoreDataAck;
-    UCHAR       EdcaUpdateCount;
-} QOS_CAPABILITY_PARM, *PQOS_CAPABILITY_PARM;
-
-#ifdef CONFIG_STA_SUPPORT
-typedef struct {
-    UCHAR       IELen;
-    UCHAR       IE[MAX_CUSTOM_LEN];
-} WPA_IE_;
-#endif // CONFIG_STA_SUPPORT //
-
-
-typedef struct {
-    UCHAR   Bssid[MAC_ADDR_LEN];
-    UCHAR   Channel;
-	UCHAR   CentralChannel;	//Store the wide-band central channel for 40MHz.  .used in 40MHz AP. Or this is the same as Channel.
-    UCHAR   BssType;
-    USHORT  AtimWin;
-    USHORT  BeaconPeriod;
-
-    UCHAR   SupRate[MAX_LEN_OF_SUPPORTED_RATES];
-    UCHAR   SupRateLen;
-    UCHAR   ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-    UCHAR   ExtRateLen;
-	HT_CAPABILITY_IE HtCapability;
-	UCHAR			HtCapabilityLen;
-	ADD_HT_INFO_IE AddHtInfo;	// AP might use this additional ht info IE
-	UCHAR			AddHtInfoLen;
-	UCHAR			NewExtChanOffset;
-	CHAR    Rssi;
-    UCHAR   Privacy;			// Indicate security function ON/OFF. Don't mess up with auth mode.
-	UCHAR	Hidden;
-
-    USHORT  DtimPeriod;
-    USHORT  CapabilityInfo;
-
-    USHORT  CfpCount;
-    USHORT  CfpPeriod;
-    USHORT  CfpMaxDuration;
-    USHORT  CfpDurRemaining;
-    UCHAR   SsidLen;
-    CHAR    Ssid[MAX_LEN_OF_SSID];
-
-    ULONG   LastBeaconRxTime; // OS's timestamp
-
-	BOOLEAN	bSES;
-
-	// New for WPA2
-	CIPHER_SUITE					WPA;			// AP announced WPA cipher suite
-	CIPHER_SUITE					WPA2;			// AP announced WPA2 cipher suite
-
-	// New for microsoft WPA support
-	NDIS_802_11_FIXED_IEs	FixIEs;
-	NDIS_802_11_AUTHENTICATION_MODE	AuthModeAux;	// Addition mode for WPA2 / WPA capable AP
-	NDIS_802_11_AUTHENTICATION_MODE	AuthMode;
-	NDIS_802_11_WEP_STATUS	WepStatus;				// Unicast Encryption Algorithm extract from VAR_IE
-	USHORT					VarIELen;				// Length of next VIE include EID & Length
-	UCHAR					VarIEs[MAX_VIE_LEN];
-
-	// CCX Ckip information
-    UCHAR   CkipFlag;
-
-	// CCX 2 TSF
-	UCHAR	PTSF[4];		// Parent TSF
-	UCHAR	TTSF[8];		// Target TSF
-
-    // 802.11e d9, and WMM
-	EDCA_PARM           EdcaParm;
-	QOS_CAPABILITY_PARM QosCapability;
-	QBSS_LOAD_PARM      QbssLoad;
-#ifdef CONFIG_STA_SUPPORT
-    WPA_IE_     WpaIE;
-    WPA_IE_     RsnIE;
-#ifdef EXT_BUILD_CHANNEL_LIST
-	UCHAR		CountryString[3];
-	BOOLEAN		bHasCountryIE;
-#endif // EXT_BUILD_CHANNEL_LIST //
-#endif // CONFIG_STA_SUPPORT //
-
-} BSS_ENTRY, *PBSS_ENTRY;
-
-typedef struct {
-    UCHAR           BssNr;
-    UCHAR           BssOverlapNr;
-    BSS_ENTRY       BssEntry[MAX_LEN_OF_BSS_TABLE];
-} BSS_TABLE, *PBSS_TABLE;
-
-
-typedef struct _MLME_QUEUE_ELEM {
-    ULONG             Machine;
-    ULONG             MsgType;
-    ULONG             MsgLen;
-    UCHAR             Msg[MGMT_DMA_BUFFER_SIZE];
-    LARGE_INTEGER     TimeStamp;
-    UCHAR             Rssi0;
-    UCHAR             Rssi1;
-    UCHAR             Rssi2;
-    UCHAR             Signal;
-    UCHAR             Channel;
-    UCHAR             Wcid;
-    BOOLEAN           Occupied;
-#ifdef MLME_EX
-	USHORT            Idx;
-#endif // MLME_EX //
-} MLME_QUEUE_ELEM, *PMLME_QUEUE_ELEM;
-
-typedef struct _MLME_QUEUE {
-    ULONG             Num;
-    ULONG             Head;
-    ULONG             Tail;
-    NDIS_SPIN_LOCK   Lock;
-    MLME_QUEUE_ELEM  Entry[MAX_LEN_OF_MLME_QUEUE];
-} MLME_QUEUE, *PMLME_QUEUE;
-
-typedef VOID (*STATE_MACHINE_FUNC)(VOID *Adaptor, MLME_QUEUE_ELEM *Elem);
-
-typedef struct _STATE_MACHINE {
-    ULONG                           Base;
-    ULONG                           NrState;
-    ULONG                           NrMsg;
-    ULONG                           CurrState;
-    STATE_MACHINE_FUNC             *TransFunc;
-} STATE_MACHINE, *PSTATE_MACHINE;
-
-
-// MLME AUX data structure that hold temporarliy settings during a connection attempt.
-// Once this attemp succeeds, all settings will be copy to pAd->StaActive.
-// A connection attempt (user set OID, roaming, CCX fast roaming,..) consists of
-// several steps (JOIN, AUTH, ASSOC or REASSOC) and may fail at any step. We purposely
-// separate this under-trial settings away from pAd->StaActive so that once
-// this new attempt failed, driver can auto-recover back to the active settings.
-typedef struct _MLME_AUX {
-    UCHAR               BssType;
-    UCHAR               Ssid[MAX_LEN_OF_SSID];
-    UCHAR               SsidLen;
-    UCHAR               Bssid[MAC_ADDR_LEN];
-	UCHAR				AutoReconnectSsid[MAX_LEN_OF_SSID];
-	UCHAR				AutoReconnectSsidLen;
-    USHORT              Alg;
-    UCHAR               ScanType;
-    UCHAR               Channel;
-	UCHAR               CentralChannel;
-    USHORT              Aid;
-    USHORT              CapabilityInfo;
-    USHORT              BeaconPeriod;
-    USHORT              CfpMaxDuration;
-    USHORT              CfpPeriod;
-    USHORT              AtimWin;
-
-	// Copy supported rate from desired AP's beacon. We are trying to match
-	// AP's supported and extended rate settings.
-	UCHAR		        SupRate[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR		        ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR		        SupRateLen;
-	UCHAR		        ExtRateLen;
-	HT_CAPABILITY_IE		HtCapability;
-	UCHAR				HtCapabilityLen;
-	ADD_HT_INFO_IE		AddHtInfo;	// AP might use this additional ht info IE
-	UCHAR			NewExtChannelOffset;
-	//RT_HT_CAPABILITY	SupportedHtPhy;
-
-    // new for QOS
-    QOS_CAPABILITY_PARM APQosCapability;    // QOS capability of the current associated AP
-    EDCA_PARM           APEdcaParm;         // EDCA parameters of the current associated AP
-    QBSS_LOAD_PARM      APQbssLoad;         // QBSS load of the current associated AP
-
-    // new to keep Ralink specific feature
-    ULONG               APRalinkIe;
-
-    BSS_TABLE           SsidBssTab;     // AP list for the same SSID
-    BSS_TABLE           RoamTab;        // AP list eligible for roaming
-    ULONG               BssIdx;
-    ULONG               RoamIdx;
-
-	BOOLEAN				CurrReqIsFromNdis;
-
-    RALINK_TIMER_STRUCT BeaconTimer, ScanTimer;
-    RALINK_TIMER_STRUCT AuthTimer;
-    RALINK_TIMER_STRUCT AssocTimer, ReassocTimer, DisassocTimer;
-
-#ifdef CONFIG_STA_SUPPORT
-#endif // CONFIG_STA_SUPPORT //
-} MLME_AUX, *PMLME_AUX;
-
-typedef struct _MLME_ADDBA_REQ_STRUCT{
-	UCHAR   Wcid;	//
-	UCHAR   pAddr[MAC_ADDR_LEN];
-	UCHAR   BaBufSize;
-	USHORT	TimeOutValue;
-	UCHAR   TID;
-	UCHAR   Token;
-	USHORT	BaStartSeq;
-} MLME_ADDBA_REQ_STRUCT, *PMLME_ADDBA_REQ_STRUCT;
-
-
-typedef struct _MLME_DELBA_REQ_STRUCT{
-	UCHAR   Wcid;	//
-	UCHAR     Addr[MAC_ADDR_LEN];
-	UCHAR   TID;
-	UCHAR	Initiator;
-} MLME_DELBA_REQ_STRUCT, *PMLME_DELBA_REQ_STRUCT;
-
-// assoc struct is equal to reassoc
-typedef struct _MLME_ASSOC_REQ_STRUCT{
-    UCHAR     Addr[MAC_ADDR_LEN];
-    USHORT    CapabilityInfo;
-    USHORT    ListenIntv;
-    ULONG     Timeout;
-} MLME_ASSOC_REQ_STRUCT, *PMLME_ASSOC_REQ_STRUCT, MLME_REASSOC_REQ_STRUCT, *PMLME_REASSOC_REQ_STRUCT;
-
-typedef struct _MLME_DISASSOC_REQ_STRUCT{
-    UCHAR     Addr[MAC_ADDR_LEN];
-    USHORT    Reason;
-} MLME_DISASSOC_REQ_STRUCT, *PMLME_DISASSOC_REQ_STRUCT;
-
-typedef struct _MLME_AUTH_REQ_STRUCT {
-    UCHAR        Addr[MAC_ADDR_LEN];
-    USHORT       Alg;
-    ULONG        Timeout;
-} MLME_AUTH_REQ_STRUCT, *PMLME_AUTH_REQ_STRUCT;
-
-typedef struct _MLME_DEAUTH_REQ_STRUCT {
-    UCHAR        Addr[MAC_ADDR_LEN];
-    USHORT       Reason;
-} MLME_DEAUTH_REQ_STRUCT, *PMLME_DEAUTH_REQ_STRUCT;
-
-typedef struct {
-    ULONG      BssIdx;
-} MLME_JOIN_REQ_STRUCT;
-
-typedef struct _MLME_SCAN_REQ_STRUCT {
-    UCHAR      Bssid[MAC_ADDR_LEN];
-    UCHAR      BssType;
-    UCHAR      ScanType;
-    UCHAR      SsidLen;
-    CHAR       Ssid[MAX_LEN_OF_SSID];
-} MLME_SCAN_REQ_STRUCT, *PMLME_SCAN_REQ_STRUCT;
-
-typedef struct _MLME_START_REQ_STRUCT {
-    CHAR        Ssid[MAX_LEN_OF_SSID];
-    UCHAR       SsidLen;
-} MLME_START_REQ_STRUCT, *PMLME_START_REQ_STRUCT;
-
-#ifdef CONFIG_STA_SUPPORT
-#ifdef QOS_DLS_SUPPORT
-// structure for DLS
-typedef struct _RT_802_11_DLS {
-	USHORT						TimeOut;		// Use to time out while slience, unit: second , set by UI
-	USHORT						CountDownTimer;	// Use to time out while slience,unit: second , used by driver only
-	NDIS_802_11_MAC_ADDRESS		MacAddr;		// set by UI
-	UCHAR						Status;			// 0: none , 1: wait STAkey, 2: finish DLS setup , set by driver only
-	BOOLEAN						Valid;			// 1: valid , 0: invalid , set by UI, use to setup or tear down DLS link
-	RALINK_TIMER_STRUCT			Timer;			// Use to time out while handshake
-	USHORT						Sequence;
-	USHORT						MacTabMatchWCID;	// ASIC
-	BOOLEAN						bHTCap;
-	PVOID						pAd;
-} RT_802_11_DLS, *PRT_802_11_DLS;
-
-typedef struct _MLME_DLS_REQ_STRUCT {
-    PRT_802_11_DLS	pDLS;
-    USHORT			Reason;
-} MLME_DLS_REQ_STRUCT, *PMLME_DLS_REQ_STRUCT;
-#endif // QOS_DLS_SUPPORT //
-#endif // CONFIG_STA_SUPPORT //
-
-typedef struct PACKED {
-    UCHAR   Eid;
-    UCHAR   Len;
-    UCHAR   Octet[1];
-} EID_STRUCT,*PEID_STRUCT, BEACON_EID_STRUCT, *PBEACON_EID_STRUCT;
-
-typedef struct PACKED _RTMP_TX_RATE_SWITCH
-{
-	UCHAR   ItemNo;
-#ifdef RT_BIG_ENDIAN
-	UCHAR	Rsv2:2;
-	UCHAR	Mode:2;
-	UCHAR	Rsv1:1;
-	UCHAR	BW:1;
-	UCHAR	ShortGI:1;
-	UCHAR	STBC:1;
-#else
-	UCHAR	STBC:1;
-	UCHAR	ShortGI:1;
-	UCHAR	BW:1;
-	UCHAR	Rsv1:1;
-	UCHAR	Mode:2;
-	UCHAR	Rsv2:2;
-#endif
-	UCHAR   CurrMCS;
-	UCHAR   TrainUp;
-	UCHAR   TrainDown;
-} RRTMP_TX_RATE_SWITCH, *PRTMP_TX_RATE_SWITCH;
-
-// ========================== AP mlme.h ===============================
-#define TBTT_PRELOAD_TIME       384        // usec. LomgPreamble + 24-byte at 1Mbps
-#define DEFAULT_DTIM_PERIOD     1
-
-// weighting factor to calculate Channel quality, total should be 100%
-//#define RSSI_WEIGHTING                   0
-//#define TX_WEIGHTING                     40
-//#define RX_WEIGHTING                     60
-
-#define MAC_TABLE_AGEOUT_TIME			300			// unit: sec
-#define MAC_TABLE_ASSOC_TIMEOUT			5			// unit: sec
-#define MAC_TABLE_FULL(Tab)				((Tab).size == MAX_LEN_OF_MAC_TABLE)
-
-// AP shall drop the sta if contine Tx fail count reach it.
-#define MAC_ENTRY_LIFE_CHECK_CNT		20			// packet cnt.
-
-// Value domain of pMacEntry->Sst
-typedef enum _Sst {
-    SST_NOT_AUTH,   // 0: equivalent to IEEE 802.11/1999 state 1
-    SST_AUTH,       // 1: equivalent to IEEE 802.11/1999 state 2
-    SST_ASSOC       // 2: equivalent to IEEE 802.11/1999 state 3
-} SST;
-
-// value domain of pMacEntry->AuthState
-typedef enum _AuthState {
-    AS_NOT_AUTH,
-    AS_AUTH_OPEN,       // STA has been authenticated using OPEN SYSTEM
-    AS_AUTH_KEY,        // STA has been authenticated using SHARED KEY
-    AS_AUTHENTICATING   // STA is waiting for AUTH seq#3 using SHARED KEY
-} AUTH_STATE;
-
-//for-wpa value domain of pMacEntry->WpaState  802.1i D3   p.114
-typedef enum _ApWpaState {
-    AS_NOTUSE,              // 0
-    AS_DISCONNECT,          // 1
-    AS_DISCONNECTED,        // 2
-    AS_INITIALIZE,          // 3
-    AS_AUTHENTICATION,      // 4
-    AS_AUTHENTICATION2,     // 5
-    AS_INITPMK,             // 6
-    AS_INITPSK,             // 7
-    AS_PTKSTART,            // 8
-    AS_PTKINIT_NEGOTIATING, // 9
-    AS_PTKINITDONE,         // 10
-    AS_UPDATEKEYS,          // 11
-    AS_INTEGRITY_FAILURE,   // 12
-    AS_KEYUPDATE,           // 13
-} AP_WPA_STATE;
-
-// for-wpa value domain of pMacEntry->WpaState  802.1i D3   p.114
-typedef enum _GTKState {
-    REKEY_NEGOTIATING,
-    REKEY_ESTABLISHED,
-    KEYERROR,
-} GTK_STATE;
-
-//  for-wpa  value domain of pMacEntry->WpaState  802.1i D3   p.114
-typedef enum _WpaGTKState {
-    SETKEYS,
-    SETKEYS_DONE,
-} WPA_GTK_STATE;
-// ====================== end of AP mlme.h ============================
-
-
-#endif	// MLME_H__
diff --git a/drivers/staging/rt3090/mlme_ex.h b/drivers/staging/rt3090/mlme_ex.h
deleted file mode 100644
index b3e94dc..0000000
--- a/drivers/staging/rt3090/mlme_ex.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    mlme_ex.h
-
-    Abstract:
-    Miniport generic portion header file
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-	Fonchi		2007-06-25		Extend original mlme APIs to support multi-entries
-*/
-#ifndef __MLME_EX_H__
-#define __MLME_EX_H__
-
-#include "mlme_ex_def.h"
-
-
-VOID StateMachineInitEx(
-	IN STATE_MACHINE_EX *S,
-	IN STATE_MACHINE_FUNC_EX Trans[],
-	IN ULONG StNr,
-	IN ULONG MsgNr,
-	IN STATE_MACHINE_FUNC_EX DefFunc,
-	IN ULONG InitState,
-	IN ULONG Base);
-
-VOID StateMachineSetActionEx(
-	IN STATE_MACHINE_EX *S,
-	IN ULONG St,
-	IN ULONG Msg,
-	IN STATE_MACHINE_FUNC_EX Func);
-
-BOOLEAN isValidApCliIf(
-	SHORT Idx);
-
-VOID StateMachinePerformActionEx(
-	IN PRTMP_ADAPTER pAd,
-	IN STATE_MACHINE_EX *S,
-	IN MLME_QUEUE_ELEM *Elem,
-	USHORT Idx,
-	PULONG pCurrState);
-
-BOOLEAN MlmeEnqueueEx(
-	IN	PRTMP_ADAPTER pAd,
-	IN ULONG Machine,
-	IN ULONG MsgType,
-	IN ULONG MsgLen,
-	IN VOID *Msg,
-	IN USHORT Idx);
-
-VOID DropEx(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem,
-	PULONG pCurrState,
-	USHORT Idx);
-
-#endif /* __MLME_EX_H__ */
diff --git a/drivers/staging/rt3090/mlme_ex_def.h b/drivers/staging/rt3090/mlme_ex_def.h
deleted file mode 100644
index ccd60b4..0000000
--- a/drivers/staging/rt3090/mlme_ex_def.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    mlme_ex_def.h
-
-    Abstract:
-    Miniport generic portion header file
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-	Fonchi		2007-06-25		Extend original mlme APIs to support multi-entries
-*/
-#ifndef __MLME_EX_DEF_H__
-#define __MLME_EX_DEF_H__
-
-
-typedef VOID (*STATE_MACHINE_FUNC_EX)(VOID *Adaptor, MLME_QUEUE_ELEM *Elem, PULONG pCurrState, USHORT Idx);
-
-typedef struct _STA_STATE_MACHINE_EX
-{
-	ULONG					Base;
-	ULONG					NrState;
-	ULONG					NrMsg;
-	ULONG					CurrState;
-	STATE_MACHINE_FUNC_EX	*TransFunc;
-} STATE_MACHINE_EX, *PSTA_STATE_MACHINE_EX;
-
-#endif // __MLME_EX_DEF_H__ //
diff --git a/drivers/staging/rt3090/netif_block.h b/drivers/staging/rt3090/netif_block.h
deleted file mode 100644
index 9e75389..0000000
--- a/drivers/staging/rt3090/netif_block.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
- */
-
-#ifndef __NET_IF_BLOCK_H__
-#define __NET_IF_BLOCK_H__
-
-#include "link_list.h"
-#include "rtmp.h"
-
-#define FREE_NETIF_POOL_SIZE 32
-
-typedef struct _NETIF_ENTRY
-{
-	struct _NETIF_ENTRY *pNext;
-	PNET_DEV pNetDev;
-} NETIF_ENTRY, *PNETIF_ENTRY;
-
-void initblockQueueTab(
-	IN PRTMP_ADAPTER pAd);
-
-BOOLEAN blockNetIf(
-	IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry,
-	IN PNET_DEV pNetDev);
-
-VOID releaseNetIf(
-	IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry);
-
-VOID StopNetIfQueue(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR QueIdx,
-	IN PNDIS_PACKET pPacket);
-#endif // __NET_IF_BLOCK_H__
diff --git a/drivers/staging/rt3090/oid.h b/drivers/staging/rt3090/oid.h
deleted file mode 100644
index 29a4340..0000000
--- a/drivers/staging/rt3090/oid.h
+++ /dev/null
@@ -1,1144 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	oid.h
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Name		Date			Modification logs
-*/
-#ifndef _OID_H_
-#define _OID_H_
-
-//#include <linux/wireless.h>
-
-#ifndef TRUE
-#define TRUE				1
-#endif
-#ifndef FALSE
-#define FALSE				0
-#endif
-//
-// IEEE 802.11 Structures and definitions
-//
-#define MAX_TX_POWER_LEVEL              100   /* mW */
-#define MAX_RSSI_TRIGGER                -10    /* dBm */
-#define MIN_RSSI_TRIGGER                -200   /* dBm */
-#define MAX_FRAG_THRESHOLD              2346  /* byte count */
-#define MIN_FRAG_THRESHOLD              256   /* byte count */
-#define MAX_RTS_THRESHOLD               2347  /* byte count */
-
-// new types for Media Specific Indications
-// Extension channel offset
-#define EXTCHA_NONE			0
-#define EXTCHA_ABOVE		0x1
-#define EXTCHA_BELOW		0x3
-
-// BW
-#define BAND_WIDTH_20		0
-#define BAND_WIDTH_40		1
-#define BAND_WIDTH_BOTH		2
-#define BAND_WIDTH_10		3	// 802.11j has 10MHz. This definition is for internal usage. doesn't fill in the IE or other field.
-// SHORTGI
-#define GAP_INTERVAL_400	1	// only support in HT mode
-#define GAP_INTERVAL_800	0
-#define GAP_INTERVAL_BOTH	2
-
-#define NdisMediaStateConnected			1
-#define NdisMediaStateDisconnected		0
-
-#define NDIS_802_11_LENGTH_SSID         32
-#define NDIS_802_11_LENGTH_RATES        8
-#define NDIS_802_11_LENGTH_RATES_EX     16
-#define MAC_ADDR_LENGTH                 6
-//#define MAX_NUM_OF_CHS					49 // 14 channels @2.4G +  12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL terminationc
-#define MAX_NUM_OF_CHS				54      // 14 channels @2.4G +  12@UNII(lower/middle) + 16@HiperLAN2 + 11@UNII(upper) + 0 @Japan + 1 as NULL termination
-#define MAX_NUMBER_OF_EVENT				10  // entry # in EVENT table
-#define MAX_NUMBER_OF_MAC				32 // if MAX_MBSSID_NUM is 8, this value can't be larger than 211
-#define MAX_NUMBER_OF_ACL				64
-#define MAX_LENGTH_OF_SUPPORT_RATES		12    // 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
-#define MAX_NUMBER_OF_DLS_ENTRY			4
-
-
-#define RT_QUERY_SIGNAL_CONTEXT				0x0402
-#define RT_SET_IAPP_PID				0x0404
-#define RT_SET_APD_PID						0x0405
-#define RT_SET_DEL_MAC_ENTRY				0x0406
-#define RT_QUERY_EVENT_TABLE			0x0407
-//
-// IEEE 802.11 OIDs
-//
-#define	OID_GET_SET_TOGGLE			0x8000
-#define	OID_GET_SET_FROM_UI			0x4000
-
-#define	OID_802_11_NETWORK_TYPES_SUPPORTED			0x0103
-#define	OID_802_11_NETWORK_TYPE_IN_USE				0x0104
-#define	OID_802_11_RSSI_TRIGGER						0x0107
-#define	RT_OID_802_11_RSSI							0x0108 //rt2860	only , kathy
-#define	RT_OID_802_11_RSSI_1						0x0109 //rt2860	only , kathy
-#define	RT_OID_802_11_RSSI_2						0x010A //rt2860	only , kathy
-#define	OID_802_11_NUMBER_OF_ANTENNAS				0x010B
-#define	OID_802_11_RX_ANTENNA_SELECTED				0x010C
-#define	OID_802_11_TX_ANTENNA_SELECTED				0x010D
-#define	OID_802_11_SUPPORTED_RATES					0x010E
-#define	OID_802_11_ADD_WEP							0x0112
-#define	OID_802_11_REMOVE_WEP						0x0113
-#define	OID_802_11_DISASSOCIATE						0x0114
-#define	OID_802_11_PRIVACY_FILTER					0x0118
-#define	OID_802_11_ASSOCIATION_INFORMATION			0x011E
-#define	OID_802_11_TEST								0x011F
-
-
-#define	RT_OID_802_11_COUNTRY_REGION				0x0507
-#define	OID_802_11_BSSID_LIST_SCAN					0x0508
-#define	OID_802_11_SSID								0x0509
-#define	OID_802_11_BSSID							0x050A
-#define	RT_OID_802_11_RADIO							0x050B
-#define	RT_OID_802_11_PHY_MODE						0x050C
-#define	RT_OID_802_11_STA_CONFIG					0x050D
-#define	OID_802_11_DESIRED_RATES					0x050E
-#define	RT_OID_802_11_PREAMBLE						0x050F
-#define	OID_802_11_WEP_STATUS						0x0510
-#define	OID_802_11_AUTHENTICATION_MODE				0x0511
-#define	OID_802_11_INFRASTRUCTURE_MODE				0x0512
-#define	RT_OID_802_11_RESET_COUNTERS				0x0513
-#define	OID_802_11_RTS_THRESHOLD					0x0514
-#define	OID_802_11_FRAGMENTATION_THRESHOLD			0x0515
-#define	OID_802_11_POWER_MODE						0x0516
-#define	OID_802_11_TX_POWER_LEVEL					0x0517
-#define	RT_OID_802_11_ADD_WPA						0x0518
-#define	OID_802_11_REMOVE_KEY						0x0519
-#define	OID_802_11_ADD_KEY							0x0520
-#define	OID_802_11_CONFIGURATION					0x0521
-#define	OID_802_11_TX_PACKET_BURST					0x0522
-#define	RT_OID_802_11_QUERY_NOISE_LEVEL				0x0523
-#define	RT_OID_802_11_EXTRA_INFO					0x0524
-#ifdef	DBG
-#define	RT_OID_802_11_HARDWARE_REGISTER				0x0525
-#endif
-#define OID_802_11_ENCRYPTION_STATUS            OID_802_11_WEP_STATUS
-#define OID_802_11_DEAUTHENTICATION                 0x0526
-#define OID_802_11_DROP_UNENCRYPTED                 0x0527
-#define OID_802_11_MIC_FAILURE_REPORT_FRAME         0x0528
-#define OID_802_11_EAP_METHOD						0x0529
-
-// For 802.1x daemin using to require current driver configuration
-#define OID_802_11_RADIUS_QUERY_SETTING				0x0540
-
-#define	RT_OID_DEVICE_NAME							0x0607
-#define	RT_OID_VERSION_INFO							0x0608
-#define	OID_802_11_BSSID_LIST						0x0609
-#define	OID_802_3_CURRENT_ADDRESS					0x060A
-#define	OID_GEN_MEDIA_CONNECT_STATUS				0x060B
-#define	RT_OID_802_11_QUERY_LINK_STATUS				0x060C
-#define	OID_802_11_RSSI								0x060D
-#define	OID_802_11_STATISTICS						0x060E
-#define	OID_GEN_RCV_OK								0x060F
-#define	OID_GEN_RCV_NO_BUFFER						0x0610
-#define	RT_OID_802_11_QUERY_EEPROM_VERSION			0x0611
-#define	RT_OID_802_11_QUERY_FIRMWARE_VERSION		0x0612
-#define	RT_OID_802_11_QUERY_LAST_RX_RATE			0x0613
-#define	RT_OID_802_11_TX_POWER_LEVEL_1				0x0614
-#define	RT_OID_802_11_QUERY_PIDVID					0x0615
-//for WPA_SUPPLICANT_SUPPORT
-#define OID_SET_COUNTERMEASURES                     0x0616
-#define OID_802_11_SET_IEEE8021X                    0x0617
-#define OID_802_11_SET_IEEE8021X_REQUIRE_KEY        0x0618
-#define OID_802_11_PMKID                            0x0620
-#define RT_OID_WPA_SUPPLICANT_SUPPORT               0x0621
-#define RT_OID_WE_VERSION_COMPILED                  0x0622
-#define RT_OID_NEW_DRIVER                           0x0623
-
-#define	RT_OID_802_11_SNR_0							0x0630
-#define	RT_OID_802_11_SNR_1							0x0631
-#define	RT_OID_802_11_QUERY_LAST_TX_RATE			0x0632
-#define	RT_OID_802_11_QUERY_HT_PHYMODE				0x0633
-#define	RT_OID_802_11_SET_HT_PHYMODE				0x0634
-#define	OID_802_11_RELOAD_DEFAULTS					0x0635
-#define	RT_OID_802_11_QUERY_APSD_SETTING			0x0636
-#define	RT_OID_802_11_SET_APSD_SETTING				0x0637
-#define	RT_OID_802_11_QUERY_APSD_PSM				0x0638
-#define	RT_OID_802_11_SET_APSD_PSM					0x0639
-#define	RT_OID_802_11_QUERY_DLS						0x063A
-#define	RT_OID_802_11_SET_DLS						0x063B
-#define	RT_OID_802_11_QUERY_DLS_PARAM				0x063C
-#define	RT_OID_802_11_SET_DLS_PARAM					0x063D
-#define RT_OID_802_11_QUERY_WMM				0x063E
-#define RT_OID_802_11_SET_WMM						0x063F
-#define RT_OID_802_11_QUERY_IMME_BA_CAP				0x0640
-#define RT_OID_802_11_SET_IMME_BA_CAP				0x0641
-#define RT_OID_802_11_QUERY_BATABLE					0x0642
-#define RT_OID_802_11_ADD_IMME_BA					0x0643
-#define RT_OID_802_11_TEAR_IMME_BA					0x0644
-#define RT_OID_DRIVER_DEVICE_NAME                   0x0645
-#define RT_OID_802_11_QUERY_DAT_HT_PHYMODE          0x0646
-#define RT_OID_QUERY_MULTIPLE_CARD_SUPPORT          0x0647
-#define OID_802_11_SET_PSPXLINK_MODE				0x0648
-/*+++ add by woody +++*/
-#define OID_802_11_SET_PASSPHRASE				0x0649
-// Ralink defined OIDs
-// Dennis Lee move to platform specific
-
-#define	RT_OID_802_11_BSSID					  (OID_GET_SET_TOGGLE |	OID_802_11_BSSID)
-#define	RT_OID_802_11_SSID					  (OID_GET_SET_TOGGLE |	OID_802_11_SSID)
-#define	RT_OID_802_11_INFRASTRUCTURE_MODE	  (OID_GET_SET_TOGGLE |	OID_802_11_INFRASTRUCTURE_MODE)
-#define	RT_OID_802_11_ADD_WEP				  (OID_GET_SET_TOGGLE |	OID_802_11_ADD_WEP)
-#define	RT_OID_802_11_ADD_KEY				  (OID_GET_SET_TOGGLE |	OID_802_11_ADD_KEY)
-#define	RT_OID_802_11_REMOVE_WEP			  (OID_GET_SET_TOGGLE |	OID_802_11_REMOVE_WEP)
-#define	RT_OID_802_11_REMOVE_KEY			  (OID_GET_SET_TOGGLE |	OID_802_11_REMOVE_KEY)
-#define	RT_OID_802_11_DISASSOCIATE			  (OID_GET_SET_TOGGLE |	OID_802_11_DISASSOCIATE)
-#define	RT_OID_802_11_AUTHENTICATION_MODE	  (OID_GET_SET_TOGGLE |	OID_802_11_AUTHENTICATION_MODE)
-#define	RT_OID_802_11_PRIVACY_FILTER		  (OID_GET_SET_TOGGLE |	OID_802_11_PRIVACY_FILTER)
-#define	RT_OID_802_11_BSSID_LIST_SCAN		  (OID_GET_SET_TOGGLE |	OID_802_11_BSSID_LIST_SCAN)
-#define	RT_OID_802_11_WEP_STATUS			  (OID_GET_SET_TOGGLE |	OID_802_11_WEP_STATUS)
-#define	RT_OID_802_11_RELOAD_DEFAULTS		  (OID_GET_SET_TOGGLE |	OID_802_11_RELOAD_DEFAULTS)
-#define	RT_OID_802_11_NETWORK_TYPE_IN_USE	  (OID_GET_SET_TOGGLE |	OID_802_11_NETWORK_TYPE_IN_USE)
-#define	RT_OID_802_11_TX_POWER_LEVEL		  (OID_GET_SET_TOGGLE |	OID_802_11_TX_POWER_LEVEL)
-#define	RT_OID_802_11_RSSI_TRIGGER			  (OID_GET_SET_TOGGLE |	OID_802_11_RSSI_TRIGGER)
-#define	RT_OID_802_11_FRAGMENTATION_THRESHOLD (OID_GET_SET_TOGGLE |	OID_802_11_FRAGMENTATION_THRESHOLD)
-#define	RT_OID_802_11_RTS_THRESHOLD			  (OID_GET_SET_TOGGLE |	OID_802_11_RTS_THRESHOLD)
-#define	RT_OID_802_11_RX_ANTENNA_SELECTED	  (OID_GET_SET_TOGGLE |	OID_802_11_RX_ANTENNA_SELECTED)
-#define	RT_OID_802_11_TX_ANTENNA_SELECTED	  (OID_GET_SET_TOGGLE |	OID_802_11_TX_ANTENNA_SELECTED)
-#define	RT_OID_802_11_SUPPORTED_RATES		  (OID_GET_SET_TOGGLE |	OID_802_11_SUPPORTED_RATES)
-#define	RT_OID_802_11_DESIRED_RATES			  (OID_GET_SET_TOGGLE |	OID_802_11_DESIRED_RATES)
-#define	RT_OID_802_11_CONFIGURATION			  (OID_GET_SET_TOGGLE |	OID_802_11_CONFIGURATION)
-#define	RT_OID_802_11_POWER_MODE			  (OID_GET_SET_TOGGLE |	OID_802_11_POWER_MODE)
-#define RT_OID_802_11_SET_PSPXLINK_MODE		  (OID_GET_SET_TOGGLE |	OID_802_11_SET_PSPXLINK_MODE)
-#define RT_OID_802_11_EAP_METHOD			  (OID_GET_SET_TOGGLE | OID_802_11_EAP_METHOD)
-#define RT_OID_802_11_SET_PASSPHRASE		  (OID_GET_SET_TOGGLE | OID_802_11_SET_PASSPHRASE)
-
-
-
-typedef enum _NDIS_802_11_STATUS_TYPE
-{
-    Ndis802_11StatusType_Authentication,
-    Ndis802_11StatusType_MediaStreamMode,
-    Ndis802_11StatusType_PMKID_CandidateList,
-    Ndis802_11StatusTypeMax    // not a real type, defined as an upper bound
-} NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE;
-
-typedef UCHAR   NDIS_802_11_MAC_ADDRESS[6];
-
-typedef struct _NDIS_802_11_STATUS_INDICATION
-{
-    NDIS_802_11_STATUS_TYPE StatusType;
-} NDIS_802_11_STATUS_INDICATION, *PNDIS_802_11_STATUS_INDICATION;
-
-// mask for authentication/integrity fields
-#define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS        0x0f
-
-#define NDIS_802_11_AUTH_REQUEST_REAUTH             0x01
-#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE          0x02
-#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR     0x06
-#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR        0x0E
-
-typedef struct _NDIS_802_11_AUTHENTICATION_REQUEST
-{
-    ULONG Length;            // Length of structure
-    NDIS_802_11_MAC_ADDRESS Bssid;
-    ULONG Flags;
-} NDIS_802_11_AUTHENTICATION_REQUEST, *PNDIS_802_11_AUTHENTICATION_REQUEST;
-
-//Added new types for PMKID Candidate lists.
-typedef struct _PMKID_CANDIDATE {
-    NDIS_802_11_MAC_ADDRESS BSSID;
-    ULONG Flags;
-} PMKID_CANDIDATE, *PPMKID_CANDIDATE;
-
-typedef struct _NDIS_802_11_PMKID_CANDIDATE_LIST
-{
-    ULONG Version;       // Version of the structure
-    ULONG NumCandidates; // No. of pmkid candidates
-    PMKID_CANDIDATE CandidateList[1];
-} NDIS_802_11_PMKID_CANDIDATE_LIST, *PNDIS_802_11_PMKID_CANDIDATE_LIST;
-
-//Flags for PMKID Candidate list structure
-#define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED	0x01
-
-// Added new types for OFDM 5G and 2.4G
-typedef enum _NDIS_802_11_NETWORK_TYPE
-{
-   Ndis802_11FH,
-   Ndis802_11DS,
-    Ndis802_11OFDM5,
-    Ndis802_11OFDM24,
-	Ndis802_11Automode,
-    Ndis802_11OFDM5_N,
-    Ndis802_11OFDM24_N,
-    Ndis802_11NetworkTypeMax    // not a real type, defined as an upper bound
-} NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE;
-
-typedef struct _NDIS_802_11_NETWORK_TYPE_LIST
-{
-    UINT                       NumberOfItems;  // in list below, at least 1
-   NDIS_802_11_NETWORK_TYPE    NetworkType [1];
-} NDIS_802_11_NETWORK_TYPE_LIST, *PNDIS_802_11_NETWORK_TYPE_LIST;
-
-typedef enum _NDIS_802_11_POWER_MODE
-{
-    Ndis802_11PowerModeCAM,
-    Ndis802_11PowerModeMAX_PSP,
-    Ndis802_11PowerModeFast_PSP,
-    Ndis802_11PowerModeLegacy_PSP,
-    Ndis802_11PowerModeMax      // not a real mode, defined as an upper bound
-} NDIS_802_11_POWER_MODE, *PNDIS_802_11_POWER_MODE;
-
-typedef ULONG   NDIS_802_11_TX_POWER_LEVEL; // in milliwatts
-
-//
-// Received Signal Strength Indication
-//
-typedef LONG    NDIS_802_11_RSSI;           // in dBm
-
-typedef struct _NDIS_802_11_CONFIGURATION_FH
-{
-   ULONG           Length;            // Length of structure
-   ULONG           HopPattern;        // As defined by 802.11, MSB set
-   ULONG           HopSet;            // to one if non-802.11
-   ULONG           DwellTime;         // units are Kusec
-} NDIS_802_11_CONFIGURATION_FH, *PNDIS_802_11_CONFIGURATION_FH;
-
-typedef struct _NDIS_802_11_CONFIGURATION
-{
-   ULONG                           Length;             // Length of structure
-   ULONG                           BeaconPeriod;       // units are Kusec
-   ULONG                           ATIMWindow;         // units are Kusec
-   ULONG                           DSConfig;           // Frequency, units are kHz
-   NDIS_802_11_CONFIGURATION_FH    FHConfig;
-} NDIS_802_11_CONFIGURATION, *PNDIS_802_11_CONFIGURATION;
-
-typedef struct _NDIS_802_11_STATISTICS
-{
-   ULONG           Length;             // Length of structure
-   LARGE_INTEGER   TransmittedFragmentCount;
-   LARGE_INTEGER   MulticastTransmittedFrameCount;
-   LARGE_INTEGER   FailedCount;
-   LARGE_INTEGER   RetryCount;
-   LARGE_INTEGER   MultipleRetryCount;
-   LARGE_INTEGER   RTSSuccessCount;
-   LARGE_INTEGER   RTSFailureCount;
-   LARGE_INTEGER   ACKFailureCount;
-   LARGE_INTEGER   FrameDuplicateCount;
-   LARGE_INTEGER   ReceivedFragmentCount;
-   LARGE_INTEGER   MulticastReceivedFrameCount;
-   LARGE_INTEGER   FCSErrorCount;
-   LARGE_INTEGER   TKIPLocalMICFailures;
-   LARGE_INTEGER   TKIPRemoteMICErrors;
-   LARGE_INTEGER   TKIPICVErrors;
-   LARGE_INTEGER   TKIPCounterMeasuresInvoked;
-   LARGE_INTEGER   TKIPReplays;
-   LARGE_INTEGER   CCMPFormatErrors;
-   LARGE_INTEGER   CCMPReplays;
-   LARGE_INTEGER   CCMPDecryptErrors;
-   LARGE_INTEGER   FourWayHandshakeFailures;
-} NDIS_802_11_STATISTICS, *PNDIS_802_11_STATISTICS;
-
-typedef  ULONG  NDIS_802_11_KEY_INDEX;
-typedef ULONGLONG   NDIS_802_11_KEY_RSC;
-
-#define MAX_RADIUS_SRV_NUM			2	  // 802.1x failover number
-
-typedef struct PACKED _RADIUS_SRV_INFO {
-	UINT32			radius_ip;
-	UINT32			radius_port;
-	UCHAR			radius_key[64];
-	UCHAR			radius_key_len;
-} RADIUS_SRV_INFO, *PRADIUS_SRV_INFO;
-
-typedef struct PACKED _RADIUS_KEY_INFO
-{
-	UCHAR			radius_srv_num;
-	RADIUS_SRV_INFO	radius_srv_info[MAX_RADIUS_SRV_NUM];
-	UCHAR			ieee8021xWEP;		 // dynamic WEP
-    UCHAR           key_index;
-    UCHAR           key_length;          // length of key in bytes
-    UCHAR           key_material[13];
-} RADIUS_KEY_INFO, *PRADIUS_KEY_INFO;
-
-// It's used by 802.1x daemon to require relative configuration
-typedef struct PACKED _RADIUS_CONF
-{
-    UINT32          Length;             // Length of this structure
-    UCHAR			mbss_num;			// indicate multiple BSS number
-	UINT32			own_ip_addr;
-	UINT32			retry_interval;
-	UINT32			session_timeout_interval;
-	UCHAR			EAPifname[8][IFNAMSIZ];
-	UCHAR			EAPifname_len[8];
-	UCHAR			PreAuthifname[8][IFNAMSIZ];
-	UCHAR			PreAuthifname_len[8];
-	RADIUS_KEY_INFO	RadiusInfo[8];
-} RADIUS_CONF, *PRADIUS_CONF;
-
-
-
-#ifdef CONFIG_STA_SUPPORT
-// Key mapping keys require a BSSID
-typedef struct _NDIS_802_11_KEY
-{
-    UINT           Length;             // Length of this structure
-    UINT           KeyIndex;
-    UINT           KeyLength;          // length of key in bytes
-    NDIS_802_11_MAC_ADDRESS BSSID;
-    NDIS_802_11_KEY_RSC KeyRSC;
-    UCHAR           KeyMaterial[1];     // variable length depending on above field
-} NDIS_802_11_KEY, *PNDIS_802_11_KEY;
-
-typedef struct _NDIS_802_11_PASSPHRASE
-{
-    UINT           KeyLength;          // length of key in bytes
-    NDIS_802_11_MAC_ADDRESS BSSID;
-    UCHAR           KeyMaterial[1];     // variable length depending on above field
-} NDIS_802_11_PASSPHRASE, *PNDIS_802_11_PASSPHRASE;
-#endif // CONFIG_STA_SUPPORT //
-
-typedef struct _NDIS_802_11_REMOVE_KEY
-{
-    UINT           Length;             // Length of this structure
-    UINT           KeyIndex;
-    NDIS_802_11_MAC_ADDRESS BSSID;
-} NDIS_802_11_REMOVE_KEY, *PNDIS_802_11_REMOVE_KEY;
-
-typedef struct _NDIS_802_11_WEP
-{
-   UINT     Length;        // Length of this structure
-   UINT     KeyIndex;           // 0 is the per-client key, 1-N are the
-                                        // global keys
-   UINT     KeyLength;     // length of key in bytes
-   UCHAR     KeyMaterial[1];// variable length depending on above field
-} NDIS_802_11_WEP, *PNDIS_802_11_WEP;
-
-
-typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE
-{
-   Ndis802_11IBSS,
-   Ndis802_11Infrastructure,
-   Ndis802_11AutoUnknown,
-   Ndis802_11Monitor,
-   Ndis802_11InfrastructureMax     // Not a real value, defined as upper bound
-} NDIS_802_11_NETWORK_INFRASTRUCTURE, *PNDIS_802_11_NETWORK_INFRASTRUCTURE;
-
-// Add new authentication modes
-typedef enum _NDIS_802_11_AUTHENTICATION_MODE
-{
-   Ndis802_11AuthModeOpen,
-   Ndis802_11AuthModeShared,
-   Ndis802_11AuthModeAutoSwitch,
-    Ndis802_11AuthModeWPA,
-    Ndis802_11AuthModeWPAPSK,
-    Ndis802_11AuthModeWPANone,
-   Ndis802_11AuthModeWPA2,
-   Ndis802_11AuthModeWPA2PSK,
-	Ndis802_11AuthModeWPA1WPA2,
-	Ndis802_11AuthModeWPA1PSKWPA2PSK,
-   Ndis802_11AuthModeMax           // Not a real mode, defined as upper bound
-} NDIS_802_11_AUTHENTICATION_MODE, *PNDIS_802_11_AUTHENTICATION_MODE;
-
-typedef UCHAR   NDIS_802_11_RATES[NDIS_802_11_LENGTH_RATES];        // Set of 8 data rates
-typedef UCHAR   NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX];  // Set of 16 data rates
-
-typedef struct PACKED _NDIS_802_11_SSID
-{
-    UINT   SsidLength;         // length of SSID field below, in bytes;
-                                // this can be zero.
-    UCHAR   Ssid[NDIS_802_11_LENGTH_SSID];           // SSID information field
-} NDIS_802_11_SSID, *PNDIS_802_11_SSID;
-
-
-typedef struct PACKED _NDIS_WLAN_BSSID
-{
-   ULONG                               Length;     // Length of this structure
-   NDIS_802_11_MAC_ADDRESS             MacAddress; // BSSID
-   UCHAR                               Reserved[2];
-   NDIS_802_11_SSID                    Ssid;       // SSID
-   ULONG                               Privacy;    // WEP encryption requirement
-   NDIS_802_11_RSSI                    Rssi;       // receive signal strength in dBm
-   NDIS_802_11_NETWORK_TYPE            NetworkTypeInUse;
-   NDIS_802_11_CONFIGURATION           Configuration;
-   NDIS_802_11_NETWORK_INFRASTRUCTURE  InfrastructureMode;
-   NDIS_802_11_RATES                   SupportedRates;
-} NDIS_WLAN_BSSID, *PNDIS_WLAN_BSSID;
-
-typedef struct PACKED _NDIS_802_11_BSSID_LIST
-{
-   UINT           NumberOfItems;      // in list below, at least 1
-   NDIS_WLAN_BSSID Bssid[1];
-} NDIS_802_11_BSSID_LIST, *PNDIS_802_11_BSSID_LIST;
-
-// Added Capabilities, IELength and IEs for each BSSID
-typedef struct PACKED _NDIS_WLAN_BSSID_EX
-{
-    ULONG                               Length;             // Length of this structure
-    NDIS_802_11_MAC_ADDRESS             MacAddress;         // BSSID
-    UCHAR                               Reserved[2];
-    NDIS_802_11_SSID                    Ssid;               // SSID
-    UINT                                Privacy;            // WEP encryption requirement
-    NDIS_802_11_RSSI                    Rssi;               // receive signal
-                                                            // strength in dBm
-    NDIS_802_11_NETWORK_TYPE            NetworkTypeInUse;
-    NDIS_802_11_CONFIGURATION           Configuration;
-    NDIS_802_11_NETWORK_INFRASTRUCTURE  InfrastructureMode;
-    NDIS_802_11_RATES_EX                SupportedRates;
-    ULONG                               IELength;
-    UCHAR                               IEs[1];
-} NDIS_WLAN_BSSID_EX, *PNDIS_WLAN_BSSID_EX;
-
-typedef struct PACKED _NDIS_802_11_BSSID_LIST_EX
-{
-    UINT                   NumberOfItems;      // in list below, at least 1
-    NDIS_WLAN_BSSID_EX      Bssid[1];
-} NDIS_802_11_BSSID_LIST_EX, *PNDIS_802_11_BSSID_LIST_EX;
-
-typedef struct PACKED _NDIS_802_11_FIXED_IEs
-{
-    UCHAR Timestamp[8];
-    USHORT BeaconInterval;
-    USHORT Capabilities;
-} NDIS_802_11_FIXED_IEs, *PNDIS_802_11_FIXED_IEs;
-
-typedef struct _NDIS_802_11_VARIABLE_IEs
-{
-    UCHAR ElementID;
-    UCHAR Length;    // Number of bytes in data field
-    UCHAR data[1];
-} NDIS_802_11_VARIABLE_IEs, *PNDIS_802_11_VARIABLE_IEs;
-
-typedef  ULONG   NDIS_802_11_FRAGMENTATION_THRESHOLD;
-
-typedef  ULONG   NDIS_802_11_RTS_THRESHOLD;
-
-typedef  ULONG   NDIS_802_11_ANTENNA;
-
-typedef enum _NDIS_802_11_PRIVACY_FILTER
-{
-   Ndis802_11PrivFilterAcceptAll,
-   Ndis802_11PrivFilter8021xWEP
-} NDIS_802_11_PRIVACY_FILTER, *PNDIS_802_11_PRIVACY_FILTER;
-
-// Added new encryption types
-// Also aliased typedef to new name
-typedef enum _NDIS_802_11_WEP_STATUS
-{
-   Ndis802_11WEPEnabled,
-    Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
-   Ndis802_11WEPDisabled,
-    Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
-   Ndis802_11WEPKeyAbsent,
-    Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
-   Ndis802_11WEPNotSupported,
-    Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
-    Ndis802_11Encryption2Enabled,
-    Ndis802_11Encryption2KeyAbsent,
-    Ndis802_11Encryption3Enabled,
-    Ndis802_11Encryption3KeyAbsent,
-    Ndis802_11Encryption4Enabled,	// TKIP or AES mix
-    Ndis802_11Encryption4KeyAbsent,
-    Ndis802_11GroupWEP40Enabled,
-	Ndis802_11GroupWEP104Enabled,
-} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS,
-  NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS;
-
-typedef enum _NDIS_802_11_RELOAD_DEFAULTS
-{
-   Ndis802_11ReloadWEPKeys
-} NDIS_802_11_RELOAD_DEFAULTS, *PNDIS_802_11_RELOAD_DEFAULTS;
-
-#define NDIS_802_11_AI_REQFI_CAPABILITIES      1
-#define NDIS_802_11_AI_REQFI_LISTENINTERVAL    2
-#define NDIS_802_11_AI_REQFI_CURRENTAPADDRESS  4
-
-#define NDIS_802_11_AI_RESFI_CAPABILITIES      1
-#define NDIS_802_11_AI_RESFI_STATUSCODE        2
-#define NDIS_802_11_AI_RESFI_ASSOCIATIONID     4
-
-typedef struct _NDIS_802_11_AI_REQFI
-{
-    USHORT Capabilities;
-    USHORT ListenInterval;
-    NDIS_802_11_MAC_ADDRESS  CurrentAPAddress;
-} NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI;
-
-typedef struct _NDIS_802_11_AI_RESFI
-{
-    USHORT Capabilities;
-    USHORT StatusCode;
-    USHORT AssociationId;
-} NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI;
-
-typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION
-{
-    ULONG                   Length;
-    USHORT                  AvailableRequestFixedIEs;
-    NDIS_802_11_AI_REQFI    RequestFixedIEs;
-    ULONG                   RequestIELength;
-    ULONG                   OffsetRequestIEs;
-    USHORT                  AvailableResponseFixedIEs;
-    NDIS_802_11_AI_RESFI    ResponseFixedIEs;
-    ULONG                   ResponseIELength;
-    ULONG                   OffsetResponseIEs;
-} NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION;
-
-typedef struct _NDIS_802_11_AUTHENTICATION_EVENT
-{
-    NDIS_802_11_STATUS_INDICATION       Status;
-    NDIS_802_11_AUTHENTICATION_REQUEST  Request[1];
-} NDIS_802_11_AUTHENTICATION_EVENT, *PNDIS_802_11_AUTHENTICATION_EVENT;
-
-/*
-typedef struct _NDIS_802_11_TEST
-{
-    ULONG Length;
-    ULONG Type;
-    union
-    {
-        NDIS_802_11_AUTHENTICATION_EVENT AuthenticationEvent;
-        NDIS_802_11_RSSI RssiTrigger;
-    };
-} NDIS_802_11_TEST, *PNDIS_802_11_TEST;
- */
-
-// 802.11 Media stream constraints, associated with OID_802_11_MEDIA_STREAM_MODE
-typedef enum _NDIS_802_11_MEDIA_STREAM_MODE
-{
-    Ndis802_11MediaStreamOff,
-    Ndis802_11MediaStreamOn,
-} NDIS_802_11_MEDIA_STREAM_MODE, *PNDIS_802_11_MEDIA_STREAM_MODE;
-
-// PMKID Structures
-typedef UCHAR   NDIS_802_11_PMKID_VALUE[16];
-
-#ifdef CONFIG_STA_SUPPORT
-typedef struct _BSSID_INFO
-{
-    NDIS_802_11_MAC_ADDRESS BSSID;
-    NDIS_802_11_PMKID_VALUE PMKID;
-} BSSID_INFO, *PBSSID_INFO;
-
-typedef struct _NDIS_802_11_PMKID
-{
-    UINT    Length;
-    UINT    BSSIDInfoCount;
-    BSSID_INFO BSSIDInfo[1];
-} NDIS_802_11_PMKID, *PNDIS_802_11_PMKID;
-#endif // CONFIG_STA_SUPPORT //
-
-
-typedef struct _NDIS_802_11_AUTHENTICATION_ENCRYPTION
-{
-    NDIS_802_11_AUTHENTICATION_MODE AuthModeSupported;
-    NDIS_802_11_ENCRYPTION_STATUS EncryptStatusSupported;
-} NDIS_802_11_AUTHENTICATION_ENCRYPTION, *PNDIS_802_11_AUTHENTICATION_ENCRYPTION;
-
-typedef struct _NDIS_802_11_CAPABILITY
-{
-     ULONG Length;
-     ULONG Version;
-     ULONG NoOfPMKIDs;
-     ULONG NoOfAuthEncryptPairsSupported;
-     NDIS_802_11_AUTHENTICATION_ENCRYPTION AuthenticationEncryptionSupported[1];
-} NDIS_802_11_CAPABILITY, *PNDIS_802_11_CAPABILITY;
-
-#ifdef LINUX
-#if WIRELESS_EXT <= 11
-#ifndef SIOCDEVPRIVATE
-#define SIOCDEVPRIVATE                              0x8BE0
-#endif
-#define SIOCIWFIRSTPRIV								SIOCDEVPRIVATE
-#endif
-#endif // LINUX //
-
-
-#ifdef CONFIG_STA_SUPPORT
-#define RT_PRIV_IOCTL							(SIOCIWFIRSTPRIV + 0x01) // Sync. with AP for wsc upnp daemon
-#define RTPRIV_IOCTL_SET							(SIOCIWFIRSTPRIV + 0x02)
-
-#ifdef DBG
-#define RTPRIV_IOCTL_BBP                            (SIOCIWFIRSTPRIV + 0x03)
-#define RTPRIV_IOCTL_MAC                            (SIOCIWFIRSTPRIV + 0x05)
-
-#ifdef RTMP_RF_RW_SUPPORT
-// TODO: shiang, Need to reassign the oid number. ArchTeam use (SIOCIWFIRSTPRIV + 0x19) for this oid
-#define RTPRIV_IOCTL_RF                             (SIOCIWFIRSTPRIV + 0x13)  // edit by johnli, fix read rf register problem
-#endif // RTMP_RF_RW_SUPPORT //
-
-#define RTPRIV_IOCTL_E2P                            (SIOCIWFIRSTPRIV + 0x07)
-#endif // DBG //
-
-#ifdef RALINK_ATE
-#ifdef RALINK_28xx_QA
-#define RTPRIV_IOCTL_ATE							(SIOCIWFIRSTPRIV + 0x08)
-#endif // RALINK_28xx_QA //
-#endif // RALINK_ATE //
-
-#define RTPRIV_IOCTL_STATISTICS                     (SIOCIWFIRSTPRIV + 0x09)
-#define RTPRIV_IOCTL_ADD_PMKID_CACHE                (SIOCIWFIRSTPRIV + 0x0A)
-#define RTPRIV_IOCTL_RADIUS_DATA                    (SIOCIWFIRSTPRIV + 0x0C)
-#define RTPRIV_IOCTL_GSITESURVEY					(SIOCIWFIRSTPRIV + 0x0D)
-#define RT_PRIV_IOCTL_EXT							(SIOCIWFIRSTPRIV + 0x0E) // Sync. with RT61 (for wpa_supplicant)
-#define RTPRIV_IOCTL_GET_MAC_TABLE					(SIOCIWFIRSTPRIV + 0x0F)
-
-#define RTPRIV_IOCTL_SHOW							(SIOCIWFIRSTPRIV + 0x11)
-enum {
-	SHOW_CONN_STATUS = 4,
-	SHOW_DRVIER_VERION = 5,
-	SHOW_BA_INFO = 6,
-	SHOW_DESC_INFO = 7,
-	RAIO_OFF = 10,
-	RAIO_ON = 11,
-#ifdef QOS_DLS_SUPPORT
-	SHOW_DLS_ENTRY_INFO = 19,
-#endif // QOS_DLS_SUPPORT //
-	SHOW_CFG_VALUE = 20,
-	SHOW_ADHOC_ENTRY_INFO = 21,
-};
-
-
-#endif // CONFIG_STA_SUPPORT //
-
-
-
-#ifdef SNMP_SUPPORT
-//SNMP ieee 802dot11, kathy , 2008_0220
-// dot11res(3)
-#define RT_OID_802_11_MANUFACTUREROUI			0x0700
-#define RT_OID_802_11_MANUFACTURERNAME			0x0701
-#define RT_OID_802_11_RESOURCETYPEIDNAME		0x0702
-
-// dot11smt(1)
-#define RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED	0x0703
-#define RT_OID_802_11_POWERMANAGEMENTMODE		0x0704
-#define OID_802_11_WEPDEFAULTKEYVALUE			0x0705 // read , write
-#define OID_802_11_WEPDEFAULTKEYID				0x0706
-#define RT_OID_802_11_WEPKEYMAPPINGLENGTH		0x0707
-#define OID_802_11_SHORTRETRYLIMIT				0x0708
-#define OID_802_11_LONGRETRYLIMIT				0x0709
-#define RT_OID_802_11_PRODUCTID					0x0710
-#define RT_OID_802_11_MANUFACTUREID				0x0711
-
-// //dot11Phy(4)
-#define OID_802_11_CURRENTCHANNEL				0x0712
-
-//dot11mac
-#define RT_OID_802_11_MAC_ADDRESS				0x0713
-#endif // SNMP_SUPPORT //
-
-#define OID_802_11_BUILD_CHANNEL_EX				0x0714
-#define OID_802_11_GET_CH_LIST					0x0715
-#define OID_802_11_GET_COUNTRY_CODE				0x0716
-#define OID_802_11_GET_CHANNEL_GEOGRAPHY		0x0717
-
-//#define RT_OID_802_11_STATISTICS              (OID_GET_SET_TOGGLE | OID_802_11_STATISTICS)
-
-#ifdef CONFIG_STA_SUPPORT
-#define RT_OID_WSC_SET_PASSPHRASE                   0x0740 // passphrase for wpa(2)-psk
-#define RT_OID_WSC_DRIVER_AUTO_CONNECT              0x0741
-#define RT_OID_WSC_QUERY_DEFAULT_PROFILE            0x0742
-#define RT_OID_WSC_SET_CONN_BY_PROFILE_INDEX        0x0743
-#define RT_OID_WSC_SET_ACTION                       0x0744
-#define RT_OID_WSC_SET_SSID                         0x0745
-#define RT_OID_WSC_SET_PIN_CODE                     0x0746
-#define RT_OID_WSC_SET_MODE                         0x0747 // PIN or PBC
-#define RT_OID_WSC_SET_CONF_MODE                    0x0748 // Enrollee or Registrar
-#define RT_OID_WSC_SET_PROFILE                      0x0749
-#endif // CONFIG_STA_SUPPORT //
-#define	RT_OID_WSC_CONFIG_STATUS					0x074F
-#define RT_OID_802_11_WSC_QUERY_PROFILE				0x0750
-// for consistency with RT61
-#define RT_OID_WSC_QUERY_STATUS						0x0751
-#define RT_OID_WSC_PIN_CODE							0x0752
-#define RT_OID_WSC_UUID								0x0753
-#define RT_OID_WSC_SET_SELECTED_REGISTRAR			0x0754
-#define RT_OID_WSC_EAPMSG							0x0755
-#define RT_OID_WSC_MANUFACTURER						0x0756
-#define RT_OID_WSC_MODEL_NAME						0x0757
-#define RT_OID_WSC_MODEL_NO							0x0758
-#define RT_OID_WSC_SERIAL_NO						0x0759
-#define RT_OID_WSC_MAC_ADDRESS						0x0760
-
-#ifdef LLTD_SUPPORT
-// for consistency with RT61
-#define RT_OID_GET_PHY_MODE                         0x761
-#endif // LLTD_SUPPORT //
-
-#ifdef NINTENDO_AP
-//#define RT_OID_NINTENDO                             0x0D010770
-#define RT_OID_802_11_NINTENDO_GET_TABLE			0x0771 //((RT_OID_NINTENDO + 0x01) & 0xffff)
-#define RT_OID_802_11_NINTENDO_SET_TABLE			0x0772 //((RT_OID_NINTENDO + 0x02) & 0xffff)
-#define RT_OID_802_11_NINTENDO_CAPABLE				0x0773 //((RT_OID_NINTENDO + 0x03) & 0xffff)
-#endif // NINTENDO_AP //
-
-
-// New for MeetingHouse Api support
-#define OID_MH_802_1X_SUPPORTED               0xFFEDC100
-
-// MIMO Tx parameter, ShortGI, MCS, STBC, etc.  these are fields in TXWI. Don't change this definition!!!
-typedef union  _HTTRANSMIT_SETTING {
-#ifdef RT_BIG_ENDIAN
-	struct	{
-	USHORT		MODE:2;	// Use definition MODE_xxx.
-//	USHORT		rsv:3;
-	USHORT		TxBF:1;
-	USHORT		rsv:2;
-	USHORT		STBC:2;	//SPACE
-	USHORT		ShortGI:1;
-	USHORT		BW:1;	//channel bandwidth 20MHz or 40 MHz
-	USHORT		MCS:7;                 // MCS
-	}	field;
-#else
-	struct	{
-	USHORT		MCS:7;                 // MCS
-	USHORT		BW:1;	//channel bandwidth 20MHz or 40 MHz
-	USHORT		ShortGI:1;
-	USHORT		STBC:2;	//SPACE
-//	USHORT		rsv:3;
-	USHORT		rsv:2;
-	USHORT		TxBF:1;
-	USHORT		MODE:2;	// Use definition MODE_xxx.
-	}	field;
-#endif
-	USHORT		word;
- } HTTRANSMIT_SETTING, *PHTTRANSMIT_SETTING;
-
-typedef enum _RT_802_11_PREAMBLE {
-    Rt802_11PreambleLong,
-    Rt802_11PreambleShort,
-    Rt802_11PreambleAuto
-} RT_802_11_PREAMBLE, *PRT_802_11_PREAMBLE;
-
-typedef enum _RT_802_11_PHY_MODE {
-	PHY_11BG_MIXED = 0,
-	PHY_11B,
-	PHY_11A,
-	PHY_11ABG_MIXED,
-	PHY_11G,
-#ifdef DOT11_N_SUPPORT
-	PHY_11ABGN_MIXED,	// both band   5
-	PHY_11N_2_4G,		// 11n-only with 2.4G band	6
-	PHY_11GN_MIXED,	// 2.4G band      7
-	PHY_11AN_MIXED,	// 5G  band       8
-	PHY_11BGN_MIXED,	// if check 802.11b.      9
-	PHY_11AGN_MIXED,	// if check 802.11b.      10
-	PHY_11N_5G,			// 11n-only with 5G band		11
-#endif // DOT11_N_SUPPORT //
-} RT_802_11_PHY_MODE;
-
-
-// put all proprietery for-query objects here to reduce # of Query_OID
-typedef struct _RT_802_11_LINK_STATUS {
-    ULONG   CurrTxRate;         // in units of 0.5Mbps
-    ULONG   ChannelQuality;     // 0..100 %
-    ULONG   TxByteCount;        // both ok and fail
-    ULONG   RxByteCount;        // both ok and fail
-    ULONG	CentralChannel;		// 40MHz central channel number
-} RT_802_11_LINK_STATUS, *PRT_802_11_LINK_STATUS;
-
-typedef struct _RT_802_11_EVENT_LOG {
-    LARGE_INTEGER   SystemTime;  // timestammp via NdisGetCurrentSystemTime()
-    UCHAR           Addr[MAC_ADDR_LENGTH];
-    USHORT          Event;       // EVENT_xxx
-} RT_802_11_EVENT_LOG, *PRT_802_11_EVENT_LOG;
-
-typedef struct _RT_802_11_EVENT_TABLE {
-    ULONG       Num;
-    ULONG       Rsv;     // to align Log[] at LARGE_INEGER boundary
-    RT_802_11_EVENT_LOG   Log[MAX_NUMBER_OF_EVENT];
-} RT_802_11_EVENT_TABLE, PRT_802_11_EVENT_TABLE;
-
-// MIMO Tx parameter, ShortGI, MCS, STBC, etc.  these are fields in TXWI. Don't change this definition!!!
-typedef union  _MACHTTRANSMIT_SETTING {
-	struct	{
-	USHORT		MCS:7;                 // MCS
-	USHORT		BW:1;	//channel bandwidth 20MHz or 40 MHz
-	USHORT		ShortGI:1;
-	USHORT		STBC:2;	//SPACE
-	USHORT		rsv:3;
-	USHORT		MODE:2;	// Use definition MODE_xxx.
-	}	field;
-	USHORT		word;
- } MACHTTRANSMIT_SETTING, *PMACHTTRANSMIT_SETTING;
-
-typedef struct _RT_802_11_MAC_ENTRY {
-    UCHAR       Addr[MAC_ADDR_LENGTH];
-    UCHAR       Aid;
-    UCHAR       Psm;     // 0:PWR_ACTIVE, 1:PWR_SAVE
-    UCHAR		MimoPs;  // 0:MMPS_STATIC, 1:MMPS_DYNAMIC, 3:MMPS_Enabled
-    CHAR		AvgRssi0;
-	CHAR		AvgRssi1;
-	CHAR		AvgRssi2;
-	UINT32		ConnectedTime;
-    MACHTTRANSMIT_SETTING	TxRate;
-} RT_802_11_MAC_ENTRY, *PRT_802_11_MAC_ENTRY;
-
-typedef struct _RT_802_11_MAC_TABLE {
-    ULONG       Num;
-    RT_802_11_MAC_ENTRY Entry[MAX_NUMBER_OF_MAC];
-} RT_802_11_MAC_TABLE, *PRT_802_11_MAC_TABLE;
-
-// structure for query/set hardware register - MAC, BBP, RF register
-typedef struct _RT_802_11_HARDWARE_REGISTER {
-    ULONG   HardwareType;       // 0:MAC, 1:BBP, 2:RF register, 3:EEPROM
-    ULONG   Offset;             // Q/S register offset addr
-    ULONG   Data;               // R/W data buffer
-} RT_802_11_HARDWARE_REGISTER, *PRT_802_11_HARDWARE_REGISTER;
-
-typedef struct _RT_802_11_AP_CONFIG {
-    ULONG   EnableTxBurst;      // 0-disable, 1-enable
-    ULONG   EnableTurboRate;    // 0-disable, 1-enable 72/100mbps turbo rate
-    ULONG   IsolateInterStaTraffic;     // 0-disable, 1-enable isolation
-    ULONG   HideSsid;           // 0-disable, 1-enable hiding
-    ULONG   UseBGProtection;    // 0-AUTO, 1-always ON, 2-always OFF
-    ULONG   UseShortSlotTime;   // 0-no use, 1-use 9-us short slot time
-    ULONG   Rsv1;               // must be 0
-    ULONG   SystemErrorBitmap;  // ignore upon SET, return system error upon QUERY
-} RT_802_11_AP_CONFIG, *PRT_802_11_AP_CONFIG;
-
-// structure to query/set STA_CONFIG
-typedef struct _RT_802_11_STA_CONFIG {
-    ULONG   EnableTxBurst;      // 0-disable, 1-enable
-    ULONG   EnableTurboRate;    // 0-disable, 1-enable 72/100mbps turbo rate
-    ULONG   UseBGProtection;    // 0-AUTO, 1-always ON, 2-always OFF
-    ULONG   UseShortSlotTime;   // 0-no use, 1-use 9-us short slot time when applicable
-    ULONG   AdhocMode;			// 0-11b rates only (WIFI spec), 1 - b/g mixed, 2 - g only
-    ULONG   HwRadioStatus;      // 0-OFF, 1-ON, default is 1, Read-Only
-    ULONG   Rsv1;               // must be 0
-    ULONG   SystemErrorBitmap;  // ignore upon SET, return system error upon QUERY
-} RT_802_11_STA_CONFIG, *PRT_802_11_STA_CONFIG;
-
-//
-//  For OID Query or Set about BA structure
-//
-typedef	struct	_OID_BACAP_STRUC	{
-		UCHAR		RxBAWinLimit;
-		UCHAR		TxBAWinLimit;
-		UCHAR		Policy;	// 0: DELAY_BA 1:IMMED_BA  (//BA Policy subfiled value in ADDBA frame)   2:BA-not use. other value invalid
-		UCHAR		MpduDensity;	// 0: DELAY_BA 1:IMMED_BA  (//BA Policy subfiled value in ADDBA frame)   2:BA-not use. other value invalid
-		UCHAR		AmsduEnable;	//Enable AMSDU transmisstion
-		UCHAR		AmsduSize;	// 0:3839, 1:7935 bytes. UINT  MSDUSizeToBytes[]	= { 3839, 7935};
-		UCHAR		MMPSmode;	// MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable
-		BOOLEAN		AutoBA;	// Auto BA will automatically
-} OID_BACAP_STRUC, *POID_BACAP_STRUC;
-
-typedef struct _RT_802_11_ACL_ENTRY {
-    UCHAR   Addr[MAC_ADDR_LENGTH];
-    USHORT  Rsv;
-} RT_802_11_ACL_ENTRY, *PRT_802_11_ACL_ENTRY;
-
-typedef struct PACKED _RT_802_11_ACL {
-    ULONG   Policy;             // 0-disable, 1-positive list, 2-negative list
-    ULONG   Num;
-    RT_802_11_ACL_ENTRY Entry[MAX_NUMBER_OF_ACL];
-} RT_802_11_ACL, *PRT_802_11_ACL;
-
-typedef struct _RT_802_11_WDS {
-    ULONG						Num;
-    NDIS_802_11_MAC_ADDRESS		Entry[24/*MAX_NUM_OF_WDS_LINK*/];
-	ULONG						KeyLength;
-	UCHAR						KeyMaterial[32];
-} RT_802_11_WDS, *PRT_802_11_WDS;
-
-typedef struct _RT_802_11_TX_RATES_ {
-    UCHAR       SupRateLen;
-    UCHAR       SupRate[MAX_LENGTH_OF_SUPPORT_RATES];
-    UCHAR       ExtRateLen;
-    UCHAR       ExtRate[MAX_LENGTH_OF_SUPPORT_RATES];
-} RT_802_11_TX_RATES, *PRT_802_11_TX_RATES;
-
-
-// Definition of extra information code
-#define	GENERAL_LINK_UP			0x0			// Link is Up
-#define	GENERAL_LINK_DOWN		0x1			// Link is Down
-#define	HW_RADIO_OFF			0x2			// Hardware radio off
-#define	SW_RADIO_OFF			0x3			// Software radio off
-#define	AUTH_FAIL				0x4			// Open authentication fail
-#define	AUTH_FAIL_KEYS			0x5			// Shared authentication fail
-#define	ASSOC_FAIL				0x6			// Association failed
-#define	EAP_MIC_FAILURE			0x7			// Deauthencation because MIC failure
-#define	EAP_4WAY_TIMEOUT		0x8			// Deauthencation on 4-way handshake timeout
-#define	EAP_GROUP_KEY_TIMEOUT	0x9			// Deauthencation on group key handshake timeout
-#define	EAP_SUCCESS				0xa			// EAP succeed
-#define	DETECT_RADAR_SIGNAL		0xb         // Radar signal occur in current channel
-#define EXTRA_INFO_MAX			0xb			// Indicate Last OID
-
-#define EXTRA_INFO_CLEAR		0xffffffff
-
-// This is OID setting structure. So only GF or MM as Mode. This is valid when our wirelss mode has 802.11n in use.
-typedef struct {
-	RT_802_11_PHY_MODE		PhyMode;	//
-	UCHAR		TransmitNo;
-	UCHAR		HtMode;		//HTMODE_GF or HTMODE_MM
-	UCHAR		ExtOffset;	//extension channel above or below
-	UCHAR		MCS;
-	UCHAR		BW;
-	UCHAR		STBC;
-	UCHAR		SHORTGI;
-	UCHAR		rsv;
-} OID_SET_HT_PHYMODE, *POID_SET_HT_PHYMODE;
-
-#ifdef NINTENDO_AP
-#define NINTENDO_MAX_ENTRY 16
-#define NINTENDO_SSID_NAME_LN 8
-#define NINTENDO_SSID_NAME "NWCUSBAP"
-#define NINTENDO_PROBE_REQ_FLAG_MASK 0x03
-#define NINTENDO_PROBE_REQ_ON 0x01
-#define NINTENDO_PROBE_REQ_SIGNAL 0x02
-#define NINTENDO_PROBE_RSP_ON 0x01
-#define NINTENDO_SSID_NICKNAME_LN 20
-
-#define NINTENDO_WEPKEY_LN 13
-
-typedef struct _NINTENDO_SSID
-{
-	UCHAR	NINTENDOFixChar[NINTENDO_SSID_NAME_LN];
-	UCHAR	zero1;
-	UCHAR	registe;
-	UCHAR	ID;
-	UCHAR	zero2;
-	UCHAR	NICKname[NINTENDO_SSID_NICKNAME_LN];
-} RT_NINTENDO_SSID, *PRT_NINTENDO_SSID;
-
-typedef struct _NINTENDO_ENTRY
-{
-	UCHAR	NICKname[NINTENDO_SSID_NICKNAME_LN];
-    UCHAR   DS_Addr[ETH_LENGTH_OF_ADDRESS];
-	UCHAR	registe;
-	UCHAR	UserSpaceAck;
-} RT_NINTENDO_ENTRY, *PRT_NINTENDO_ENTRY;
-
-//RTPRIV_IOCTL_NINTENDO_GET_TABLE
-//RTPRIV_IOCTL_NINTENDO_SET_TABLE
-typedef struct _NINTENDO_TABLE
-{
-	UINT				number;
-	RT_NINTENDO_ENTRY	entry[NINTENDO_MAX_ENTRY];
-} RT_NINTENDO_TABLE, *PRT_NINTENDO_TABLE;
-
-//RTPRIV_IOCTL_NINTENDO_SEED_WEPKEY
-typedef struct _NINTENDO_SEED_WEPKEY
-{
-	UCHAR	seed[NINTENDO_SSID_NICKNAME_LN];
-	UCHAR	wepkey[16];//use 13 for 104 bits wep key
-} RT_NINTENDO_SEED_WEPKEY, *PRT_NINTENDO_SEED_WEPKEY;
-#endif // NINTENDO_AP //
-
-#ifdef LLTD_SUPPORT
-typedef struct _RT_LLTD_ASSOICATION_ENTRY {
-    UCHAR           Addr[ETH_LENGTH_OF_ADDRESS];
-    unsigned short  MOR;        // maximum operational rate
-    UCHAR           phyMode;
-} RT_LLTD_ASSOICATION_ENTRY, *PRT_LLTD_ASSOICATION_ENTRY;
-
-typedef struct _RT_LLTD_ASSOICATION_TABLE {
-    unsigned int                Num;
-    RT_LLTD_ASSOICATION_ENTRY   Entry[MAX_NUMBER_OF_MAC];
-} RT_LLTD_ASSOICATION_TABLE, *PRT_LLTD_ASSOICATION_TABLE;
-#endif // LLTD_SUPPORT //
-
-#ifdef CONFIG_STA_SUPPORT
-#ifdef QOS_DLS_SUPPORT
-//rt2860, kathy 2007-0118
-// structure for DLS
-typedef struct _RT_802_11_DLS_UI {
-	USHORT						TimeOut;		// unit: second , set by UI
-	USHORT						CountDownTimer;	// unit: second , used by driver only
-	NDIS_802_11_MAC_ADDRESS		MacAddr;		// set by UI
-	UCHAR						Status;			// 0: none , 1: wait STAkey, 2: finish DLS setup , set by driver only
-	BOOLEAN						Valid;			// 1: valid , 0: invalid , set by UI, use to setup or tear down DLS link
-} RT_802_11_DLS_UI, *PRT_802_11_DLS_UI;
-
-typedef struct _RT_802_11_DLS_INFO {
-	RT_802_11_DLS_UI	Entry[MAX_NUMBER_OF_DLS_ENTRY];
-	UCHAR				num;
-} RT_802_11_DLS_INFO, *PRT_802_11_DLS_INFO;
-
-typedef enum _RT_802_11_DLS_MODE {
-    DLS_NONE,
-    DLS_WAIT_KEY,
-    DLS_FINISH
-} RT_802_11_DLS_MODE;
-#endif // QOS_DLS_SUPPORT //
-
-#ifdef WPA_SUPPLICANT_SUPPORT
-#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
-#define	RT_ASSOC_EVENT_FLAG                         0x0101
-#define	RT_DISASSOC_EVENT_FLAG                      0x0102
-#define	RT_REQIE_EVENT_FLAG                         0x0103
-#define	RT_RESPIE_EVENT_FLAG                        0x0104
-#define	RT_ASSOCINFO_EVENT_FLAG                     0x0105
-#define RT_PMKIDCAND_FLAG                           0x0106
-#define RT_INTERFACE_DOWN                           0x0107
-#define RT_INTERFACE_UP                             0x0108
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-#endif // WPA_SUPPLICANT_SUPPORT //
-#endif // CONFIG_STA_SUPPORT //
-
-
-
-
-#define MAX_CUSTOM_LEN 128
-
-#ifdef CONFIG_STA_SUPPORT
-typedef enum _RT_802_11_D_CLIENT_MODE
-{
-   Rt802_11_D_None,
-   Rt802_11_D_Flexible,
-   Rt802_11_D_Strict,
-} RT_802_11_D_CLIENT_MODE, *PRT_802_11_D_CLIENT_MODE;
-#endif // CONFIG_STA_SUPPORT //
-
-typedef struct _RT_CHANNEL_LIST_INFO
-{
-	UCHAR ChannelList[MAX_NUM_OF_CHS];   // list all supported channels for site survey
-	UCHAR ChannelListNum; // number of channel in ChannelList[]
-} RT_CHANNEL_LIST_INFO, *PRT_CHANNEL_LIST_INFO;
-
-// WSC configured credential
-typedef	struct	_WSC_CREDENTIAL
-{
-	NDIS_802_11_SSID	SSID;				// mandatory
-	USHORT				AuthType;			// mandatory, 1: open, 2: wpa-psk, 4: shared, 8:wpa, 0x10: wpa2, 0x20: wpa2-psk
-	USHORT				EncrType;			// mandatory, 1: none, 2: wep, 4: tkip, 8: aes
-	UCHAR				Key[64];			// mandatory, Maximum 64 byte
-	USHORT				KeyLength;
-	UCHAR				MacAddr[6];			// mandatory, AP MAC address
-	UCHAR				KeyIndex;			// optional, default is 1
-	UCHAR				Rsvd[3];			// Make alignment
-}	WSC_CREDENTIAL, *PWSC_CREDENTIAL;
-
-// WSC configured profiles
-typedef	struct	_WSC_PROFILE
-{
-	UINT			ProfileCnt;
-	UINT			ApplyProfileIdx;  // add by johnli, fix WPS test plan 5.1.1
-	WSC_CREDENTIAL	Profile[8];				// Support up to 8 profiles
-}	WSC_PROFILE, *PWSC_PROFILE;
-
-
-
-#endif // _OID_H_
diff --git a/drivers/staging/rt3090/pci_main_dev.c b/drivers/staging/rt3090/pci_main_dev.c
deleted file mode 100644
index 1410156..0000000
--- a/drivers/staging/rt3090/pci_main_dev.c
+++ /dev/null
@@ -1,1195 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	pci_main_dev.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Name		Date			Modification logs
-*/
-
-
-#include "rt_config.h"
-#include <linux/pci.h>
-
-// Following information will be show when you run 'modinfo'
-// *** If you have a solution for the bug in current version of driver, please mail to me.
-// Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. ***
-MODULE_AUTHOR("Jett Chen <jett_chen@ralinktech.com>");
-MODULE_DESCRIPTION("RT3090 Wireless Lan Linux Driver");
-MODULE_LICENSE("GPL");
-
-//
-// Function declarations
-//
-extern int rt28xx_close(IN struct net_device *net_dev);
-extern int rt28xx_open(struct net_device *net_dev);
-
-static VOID __devexit rt2860_remove_one(struct pci_dev *pci_dev);
-static INT __devinit rt2860_probe(struct pci_dev *pci_dev, const struct pci_device_id  *ent);
-static void __exit rt2860_cleanup_module(void);
-static int __init rt2860_init_module(void);
-
-
- static VOID RTMPInitPCIeDevice(
-    IN  struct pci_dev   *pci_dev,
-    IN PRTMP_ADAPTER     pAd);
-
-
-#ifdef CONFIG_PM
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
-#define pm_message_t u32
-#endif
-
-static int rt2860_suspend(struct pci_dev *pci_dev, pm_message_t state);
-static int rt2860_resume(struct pci_dev *pci_dev);
-#endif
-#endif // CONFIG_PM //
-
-//
-// Ralink PCI device table, include all supported chipsets
-//
-static struct pci_device_id rt2860_pci_tbl[] __devinitdata =
-{
-#ifdef RT3090
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3090_PCIe_DEVICE_ID)},
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3091_PCIe_DEVICE_ID)},
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3092_PCIe_DEVICE_ID)},
-	{PCI_DEVICE(0x1462, 0x891A)},
-#endif // RT3090 //
-#ifdef RT3390
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3390_PCIe_DEVICE_ID)},
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3391_PCIe_DEVICE_ID)},
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3392_PCIe_DEVICE_ID)},
-#endif // RT3390 //
-    {0,}		// terminate list
-};
-
-MODULE_DEVICE_TABLE(pci, rt2860_pci_tbl);
-#ifdef CONFIG_STA_SUPPORT
-#ifdef MODULE_VERSION
-MODULE_VERSION(STA_DRIVER_VERSION);
-#endif
-#endif // CONFIG_STA_SUPPORT //
-
-
-//
-// Our PCI driver structure
-//
-static struct pci_driver rt2860_driver =
-{
-    name:       "rt3090",
-    id_table:   rt2860_pci_tbl,
-    probe:      rt2860_probe,
-#if LINUX_VERSION_CODE >= 0x20412
-    remove:     __devexit_p(rt2860_remove_one),
-#else
-    remove:     __devexit(rt2860_remove_one),
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#ifdef CONFIG_PM
-	suspend:	rt2860_suspend,
-	resume:		rt2860_resume,
-#endif
-#endif
-};
-
-
-/***************************************************************************
- *
- *	PCI device initialization related procedures.
- *
- ***************************************************************************/
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#ifdef CONFIG_PM
-
-VOID RT2860RejectPendingPackets(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	// clear PS packets
-	// clear TxSw packets
-}
-
-static int rt2860_suspend(
-	struct pci_dev *pci_dev,
-	pm_message_t state)
-{
-	struct net_device *net_dev = pci_get_drvdata(pci_dev);
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL;
-	INT32 retval = 0;
-
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_suspend()\n"));
-
-	if (net_dev == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n"));
-	}
-	else
-	{
-		pAd = (PRTMP_ADAPTER)RTMP_OS_NETDEV_GET_PRIV(net_dev);
-
-		/* we can not use IFF_UP because ra0 down but ra1 up */
-		/* and 1 suspend/resume function for 1 module, not for each interface */
-		/* so Linux will call suspend/resume function once */
-		if (VIRTUAL_IF_NUM(pAd) > 0)
-		{
-			// avoid users do suspend after interface is down
-
-			// stop interface
-			netif_carrier_off(net_dev);
-			netif_stop_queue(net_dev);
-
-			// mark device as removed from system and therefore no longer available
-			netif_device_detach(net_dev);
-
-			// mark halt flag
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-			// take down the device
-			rt28xx_close((PNET_DEV)net_dev);
-
-			RT_MOD_DEC_USE_COUNT();
-		}
-	}
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
-	// reference to http://vovo2000.com/type-lab/linux/kernel-api/linux-kernel-api.html
-	// enable device to generate PME# when suspended
-	// pci_choose_state(): Choose the power state of a PCI device to be suspended
-	retval = pci_enable_wake(pci_dev, pci_choose_state(pci_dev, state), 1);
-	// save the PCI configuration space of a device before suspending
-	pci_save_state(pci_dev);
-	// disable PCI device after use
-	pci_disable_device(pci_dev);
-
-	retval = pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
-#endif
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_suspend()\n"));
-	return retval;
-}
-
-static int rt2860_resume(
-	struct pci_dev *pci_dev)
-{
-	struct net_device *net_dev = pci_get_drvdata(pci_dev);
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL;
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
-	INT32 retval;
-
-
-	// set the power state of a PCI device
-	// PCI has 4 power states, DO (normal) ~ D3(less power)
-	// in include/linux/pci.h, you can find that
-	// #define PCI_D0          ((pci_power_t __force) 0)
-	// #define PCI_D1          ((pci_power_t __force) 1)
-	// #define PCI_D2          ((pci_power_t __force) 2)
-	// #define PCI_D3hot       ((pci_power_t __force) 3)
-	// #define PCI_D3cold      ((pci_power_t __force) 4)
-	// #define PCI_UNKNOWN     ((pci_power_t __force) 5)
-	// #define PCI_POWER_ERROR ((pci_power_t __force) -1)
-	retval = pci_set_power_state(pci_dev, PCI_D0);
-
-	// restore the saved state of a PCI device
-	pci_restore_state(pci_dev);
-
-	// initialize device before it's used by a driver
-	if (pci_enable_device(pci_dev))
-	{
-		printk("pci enable fail!\n");
-		return 0;
-	}
-#endif
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_resume()\n"));
-
-	if (net_dev == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n"));
-	}
-	else
-		pAd = (PRTMP_ADAPTER)RTMP_OS_NETDEV_GET_PRIV(net_dev);
-
-	if (pAd != NULL)
-	{
-		/* we can not use IFF_UP because ra0 down but ra1 up */
-		/* and 1 suspend/resume function for 1 module, not for each interface */
-		/* so Linux will call suspend/resume function once */
-		if (VIRTUAL_IF_NUM(pAd) > 0)
-		{
-			// mark device as attached from system and restart if needed
-			netif_device_attach(net_dev);
-
-			if (rt28xx_open((PNET_DEV)net_dev) != 0)
-			{
-				// open fail
-				DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_resume()\n"));
-				return 0;
-			}
-
-			// increase MODULE use count
-			RT_MOD_INC_USE_COUNT();
-
-			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-			netif_start_queue(net_dev);
-			netif_carrier_on(net_dev);
-			netif_wake_queue(net_dev);
-		}
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_resume()\n"));
-	return 0;
-}
-#endif // CONFIG_PM //
-#endif
-
-
-static INT __init rt2860_init_module(VOID)
-{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-	return pci_register_driver(&rt2860_driver);
-#else
-    return pci_module_init(&rt2860_driver);
-#endif
-}
-
-
-//
-// Driver module unload function
-//
-static VOID __exit rt2860_cleanup_module(VOID)
-{
-    pci_unregister_driver(&rt2860_driver);
-}
-
-module_init(rt2860_init_module);
-module_exit(rt2860_cleanup_module);
-
-
-//
-// PCI device probe & initialization function
-//
-static INT __devinit   rt2860_probe(
-    IN  struct pci_dev              *pci_dev,
-    IN  const struct pci_device_id  *pci_id)
-{
-	PRTMP_ADAPTER		pAd = (PRTMP_ADAPTER)NULL;
-	struct  net_device		*net_dev;
-	PVOID				handle;
-	PSTRING				print_name;
-	ULONG				csr_addr;
-	INT rv = 0;
-	RTMP_OS_NETDEV_OP_HOOK	netDevHook;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_probe\n"));
-
-//PCIDevInit==============================================
-	// wake up and enable device
-	if ((rv = pci_enable_device(pci_dev))!= 0)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Enable PCI device failed, errno=%d!\n", rv));
-		return rv;
-	}
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-	print_name = pci_dev ? pci_name(pci_dev) : "rt3090";
-#else
-	print_name = pci_dev ? pci_dev->slot_name : "rt3090";
-#endif // LINUX_VERSION_CODE //
-
-	if ((rv = pci_request_regions(pci_dev, print_name)) != 0)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Request PCI resource failed, errno=%d!\n", rv));
-		goto err_out;
-	}
-
-	// map physical address to virtual address for accessing register
-	csr_addr = (unsigned long) ioremap(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
-	if (!csr_addr)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("ioremap failed for device %s, region 0x%lX @ 0x%lX\n",
-					print_name, (ULONG)pci_resource_len(pci_dev, 0), (ULONG)pci_resource_start(pci_dev, 0)));
-		goto err_out_free_res;
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("%s: at 0x%lx, VA 0x%lx, IRQ %d. \n",  print_name,
-					(ULONG)pci_resource_start(pci_dev, 0), (ULONG)csr_addr, pci_dev->irq));
-	}
-
-	// Set DMA master
-	pci_set_master(pci_dev);
-
-
-//RtmpDevInit==============================================
-	// Allocate RTMP_ADAPTER adapter structure
-	handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL);
-	if (handle == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s(): Allocate memory for os handle failed!\n", __FUNCTION__));
-		goto err_out_iounmap;
-	}
-
-	((POS_COOKIE)handle)->pci_dev = pci_dev;
-
-	rv = RTMPAllocAdapterBlock(handle, &pAd);	//shiang: we may need the pci_dev for allocate structure of "RTMP_ADAPTER"
-	if (rv != NDIS_STATUS_SUCCESS)
-		goto err_out_iounmap;
-	// Here are the RTMP_ADAPTER structure with pci-bus specific parameters.
-	pAd->CSRBaseAddress = (PUCHAR)csr_addr;
-	DBGPRINT(RT_DEBUG_ERROR, ("pAd->CSRBaseAddress =0x%lx, csr_addr=0x%lx!\n", (ULONG)pAd->CSRBaseAddress, csr_addr));
-	RtmpRaDevCtrlInit(pAd, RTMP_DEV_INF_PCI);
-
-
-//NetDevInit==============================================
-	net_dev = RtmpPhyNetDevInit(pAd, &netDevHook);
-	if (net_dev == NULL)
-		goto err_out_free_radev;
-
-	// Here are the net_device structure with pci-bus specific parameters.
-	net_dev->irq = pci_dev->irq;		// Interrupt IRQ number
-	net_dev->base_addr = csr_addr;		// Save CSR virtual address and irq to device structure
-	pci_set_drvdata(pci_dev, net_dev);	// Set driver data
-
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-/* for supporting Network Manager */
-	/* Set the sysfs physical device reference for the network logical device
-	  * if set prior to registration will cause a symlink during initialization.
-	 */
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
-	SET_NETDEV_DEV(net_dev, &(pci_dev->dev));
-#endif
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-
-
-//All done, it's time to register the net device to linux kernel.
-	// Register this device
-	rv = RtmpOSNetDevAttach(net_dev, &netDevHook);
-	if (rv)
-		goto err_out_free_netdev;
-
-#ifdef CONFIG_STA_SUPPORT
-	pAd->StaCfg.OriDevType = net_dev->type;
-#endif // CONFIG_STA_SUPPORT //
-RTMPInitPCIeDevice(pci_dev, pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_probe\n"));
-
-	return 0; // probe ok
-
-
-	/* --------------------------- ERROR HANDLE --------------------------- */
-err_out_free_netdev:
-	RtmpOSNetDevFree(net_dev);
-
-err_out_free_radev:
-	/* free RTMP_ADAPTER strcuture and os_cookie*/
-	RTMPFreeAdapter(pAd);
-
-err_out_iounmap:
-	iounmap((void *)(csr_addr));
-	release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
-
-err_out_free_res:
-	pci_release_regions(pci_dev);
-
-err_out:
-	pci_disable_device(pci_dev);
-
-	DBGPRINT(RT_DEBUG_ERROR, ("<=== rt2860_probe failed with rv = %d!\n", rv));
-
-	return -ENODEV; /* probe fail */
-}
-
-
-static VOID __devexit rt2860_remove_one(
-    IN  struct pci_dev  *pci_dev)
-{
-	PNET_DEV	net_dev = pci_get_drvdata(pci_dev);
-	RTMP_ADAPTER	*pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
-	ULONG			csr_addr = net_dev->base_addr; // pAd->CSRBaseAddress;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_remove_one\n"));
-
-	if (pAd != NULL)
-	{
-		// Unregister/Free all allocated net_device.
-		RtmpPhyNetDevExit(pAd, net_dev);
-
-		// Unmap CSR base address
-		iounmap((char *)(csr_addr));
-
-		// release memory region
-		release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
-
-		// Free RTMP_ADAPTER related structures.
-		RtmpRaDevCtrlExit(pAd);
-
-	}
-	else
-	{
-		// Unregister network device
-		RtmpOSNetDevDetach(net_dev);
-
-		// Unmap CSR base address
-		iounmap((char *)(net_dev->base_addr));
-
-		// release memory region
-		release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
-	}
-
-	// Free the root net_device
-	RtmpOSNetDevFree(net_dev);
-
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Check the chipset vendor/product ID.
-
-Arguments:
-    _dev_p				Point to the PCI or USB device
-
-Return Value:
-    TRUE				Check ok
-	FALSE				Check fail
-
-Note:
-========================================================================
-*/
-BOOLEAN RT28XXChipsetCheck(
-	IN void *_dev_p)
-{
-	/* always TRUE */
-	return TRUE;
-}
-
-
-
-/***************************************************************************
- *
- *	PCIe device initialization related procedures.
- *
- ***************************************************************************/
- static VOID RTMPInitPCIeDevice(
-    IN  struct pci_dev   *pci_dev,
-    IN PRTMP_ADAPTER     pAd)
-{
-	USHORT  device_id;
-	POS_COOKIE pObj;
-
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-	pci_read_config_word(pci_dev, PCI_DEVICE_ID, &device_id);
-	device_id = le2cpu16(device_id);
-	pObj->DeviceID = device_id;
-	if (
-#ifdef RT3090
-		(device_id == NIC3090_PCIe_DEVICE_ID) ||
-		(device_id == NIC3091_PCIe_DEVICE_ID) ||
-		(device_id == NIC3092_PCIe_DEVICE_ID) ||
-#endif // RT3090 //
-		 0)
-	{
-		UINT32 MacCsr0 = 0, Index= 0;
-		do
-		{
-			RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
-
-			if ((MacCsr0 != 0x00) && (MacCsr0 != 0xFFFFFFFF))
-				break;
-
-			RTMPusecDelay(10);
-		} while (Index++ < 100);
-
-		// Support advanced power save after 2892/2790.
-		// MAC version at offset 0x1000 is 0x2872XXXX/0x2870XXXX(PCIe, USB, SDIO).
-		if ((MacCsr0&0xffff0000) != 0x28600000)
-		{
-			OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PCIE_DEVICE);
-		}
-	}
-}
-
-#ifdef CONFIG_STA_SUPPORT
-VOID RTMPInitPCIeLinkCtrlValue(
-	IN	PRTMP_ADAPTER	pAd)
-{
-    INT     pos;
-    USHORT	reg16, data2, PCIePowerSaveLevel, Configuration;
-	UINT32 MacValue;
-    BOOLEAN	bFindIntel = FALSE;
-	POS_COOKIE pObj;
-
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
-		return;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __FUNCTION__));
-	// Init EEPROM, and save settings
-	if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)))
-	{
-		RT28xx_EEPROM_READ16(pAd, 0x22, PCIePowerSaveLevel);
-		pAd->PCIePowerSaveLevel = PCIePowerSaveLevel & 0xff;
-		pAd->LnkCtrlBitMask = 0;
-		if ((PCIePowerSaveLevel&0xff) == 0xff)
-		{
-			OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PCIE_DEVICE);
-			DBGPRINT(RT_DEBUG_TRACE, ("====> PCIePowerSaveLevel = 0x%x.\n", PCIePowerSaveLevel));
-			return;
-		}
-	else
-	{
-		PCIePowerSaveLevel &= 0x3;
-		RT28xx_EEPROM_READ16(pAd, 0x24, data2);
-
-		if( !(((data2&0xff00) == 0x9200) && ((data2&0x80) !=0)) )
-		{
-			if (PCIePowerSaveLevel > 1 )
-				PCIePowerSaveLevel = 1;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("====> Write 0x83 = 0x%x.\n", PCIePowerSaveLevel));
-		AsicSendCommandToMcu(pAd, 0x83, 0xff, (UCHAR)PCIePowerSaveLevel, 0x00);
-		RT28xx_EEPROM_READ16(pAd, 0x22, PCIePowerSaveLevel);
-		PCIePowerSaveLevel &= 0xff;
-		PCIePowerSaveLevel = PCIePowerSaveLevel >> 6;
-		switch(PCIePowerSaveLevel)
-		{
-				case 0:	// Only support L0
-					pAd->LnkCtrlBitMask = 0;
-				break;
-				case 1:	// Only enable L0s
-					pAd->LnkCtrlBitMask = 1;
-				break;
-				case 2:	// enable L1, L0s
-					pAd->LnkCtrlBitMask = 3;
-				break;
-				case 3:	// sync with host clk and enable L1, L0s
-				pAd->LnkCtrlBitMask = 0x103;
-				break;
-		}
-			RT28xx_EEPROM_READ16(pAd, 0x24, data2);
-			if ((PCIePowerSaveLevel&0xff) != 0xff)
-			{
-				PCIePowerSaveLevel &= 0x3;
-
-				if( !(((data2&0xff00) == 0x9200) && ((data2&0x80) !=0)) )
-				{
-					if (PCIePowerSaveLevel > 1 )
-						PCIePowerSaveLevel = 1;
-				}
-
-				DBGPRINT(RT_DEBUG_TRACE, ("====> rt28xx Write 0x83 Command = 0x%x.\n", PCIePowerSaveLevel));
-					       printk("\n\n\n%s:%d\n",__FUNCTION__,__LINE__);
-
-				AsicSendCommandToMcu(pAd, 0x83, 0xff, (UCHAR)PCIePowerSaveLevel, 0x00);
-			}
-		DBGPRINT(RT_DEBUG_TRACE, ("====> LnkCtrlBitMask = 0x%x.\n", pAd->LnkCtrlBitMask));
-	}
-	}
-	else if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
-	{
-		UCHAR	LinkCtrlSetting = 0;
-
-		// Check 3090E special setting chip.
-			RT28xx_EEPROM_READ16(pAd, 0x24, data2);
-		if ((data2 == 0x9280) && ((pAd->MACVersion&0xffff) == 0x0211))
-		{
-			pAd->b3090ESpecialChip = TRUE;
-			DBGPRINT_RAW(RT_DEBUG_ERROR,("Special 3090E chip \n"));
-		}
-
-		RTMP_IO_READ32(pAd, AUX_CTRL, &MacValue);
-		//enable WAKE_PCIE function, which forces to enable PCIE clock when mpu interrupt asserting.
-		//Force PCIE 125MHz CLK to toggle
-		MacValue |= 0x402;
-		RTMP_IO_WRITE32(pAd, AUX_CTRL, MacValue);
-		DBGPRINT_RAW(RT_DEBUG_ERROR,(" AUX_CTRL = 0x%32x\n", MacValue));
-
-
-
-		// for RT30xx F and after, PCIe infterface, and for power solution 3
-		if ((IS_VERSION_AFTER_F(pAd))
-			&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode >= 2)
-			&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode <= 3))
-		{
-			RTMP_IO_READ32(pAd, AUX_CTRL, &MacValue);
-			DBGPRINT_RAW(RT_DEBUG_ERROR,(" Read AUX_CTRL = 0x%x\n", MacValue));
-			// turn on bit 12.
-			//enable 32KHz clock mode for power saving
-			MacValue |= 0x1000;
-			if (MacValue != 0xffffffff)
-			{
-				RTMP_IO_WRITE32(pAd, AUX_CTRL, MacValue);
-				DBGPRINT_RAW(RT_DEBUG_ERROR,(" Write AUX_CTRL = 0x%x\n", MacValue));
-				// 1. if use PCIePowerSetting is 2 or 3, need to program OSC_CTRL to 0x3ff11.
-				MacValue = 0x3ff11;
-				RTMP_IO_WRITE32(pAd, OSC_CTRL, MacValue);
-				DBGPRINT_RAW(RT_DEBUG_ERROR,(" OSC_CTRL = 0x%x\n", MacValue));
-				// 2. Write PCI register Clk ref bit
-				RTMPrt3xSetPCIePowerLinkCtrl(pAd);
-			}
-			else
-			{
-				// Error read Aux_Ctrl value.  Force to use solution 1
-				DBGPRINT(RT_DEBUG_ERROR,(" Error Value in AUX_CTRL = 0x%x\n", MacValue));
-				pAd->StaCfg.PSControl.field.rt30xxPowerMode = 1;
-				DBGPRINT(RT_DEBUG_ERROR,(" Force to use power solution1 \n"));
-			}
-		}
-		// 1. read setting from inf file.
-
-		PCIePowerSaveLevel = (USHORT)pAd->StaCfg.PSControl.field.rt30xxPowerMode;
-		DBGPRINT(RT_DEBUG_ERROR, ("====> rt30xx Read PowerLevelMode =  0x%x.\n", PCIePowerSaveLevel));
-		// 2. Check EnableNewPS.
-		if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE)
-			PCIePowerSaveLevel = 1;
-
-		if (IS_VERSION_BEFORE_F(pAd) && (pAd->b3090ESpecialChip == FALSE))
-		{
-			// Chip Version E only allow 1, So force set 1.
-			PCIePowerSaveLevel &= 0x1;
-			pAd->PCIePowerSaveLevel = (USHORT)PCIePowerSaveLevel;
-			DBGPRINT(RT_DEBUG_TRACE, ("====> rt30xx E Write 0x83 Command = 0x%x.\n", PCIePowerSaveLevel));
-
-			AsicSendCommandToMcu(pAd, 0x83, 0xff, (UCHAR)PCIePowerSaveLevel, 0x00);
-		}
-		else
-		{
-			// Chip Version F and after only allow 1 or 2 or 3. This might be modified after new chip version come out.
-			if (!((PCIePowerSaveLevel == 1) || (PCIePowerSaveLevel == 3)))
-				PCIePowerSaveLevel = 1;
-			DBGPRINT(RT_DEBUG_ERROR, ("====> rt30xx F Write 0x83 Command = 0x%x.\n", PCIePowerSaveLevel));
-			pAd->PCIePowerSaveLevel = (USHORT)PCIePowerSaveLevel;
-			// for 3090F , we need to add high-byte arg for 0x83 command to indicate the link control setting in
-			// PCI Configuration Space. Because firmware can't read PCI Configuration Space
-			if ((pAd->Rt3xxRalinkLinkCtrl & 0x2) && (pAd->Rt3xxHostLinkCtrl & 0x2))
-			{
-				LinkCtrlSetting = 1;
-			}
-			DBGPRINT(RT_DEBUG_TRACE, ("====> rt30xxF LinkCtrlSetting = 0x%x.\n", LinkCtrlSetting));
-			AsicSendCommandToMcu(pAd, 0x83, 0xff, (UCHAR)PCIePowerSaveLevel, LinkCtrlSetting);
-		}
-
-	}
-
-    // Find Ralink PCIe Device's Express Capability Offset
-	pos = pci_find_capability(pObj->pci_dev, PCI_CAP_ID_EXP);
-
-    if (pos != 0)
-    {
-        // Ralink PCIe Device's Link Control Register Offset
-        pAd->RLnkCtrlOffset = pos + PCI_EXP_LNKCTL;
-	pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, &reg16);
-        Configuration = le2cpu16(reg16);
-        DBGPRINT(RT_DEBUG_TRACE, ("Read (Ralink PCIe Link Control Register) offset 0x%x = 0x%x\n",
-                                    pAd->RLnkCtrlOffset, Configuration));
-        pAd->RLnkCtrlConfiguration = (Configuration & 0x103);
-        Configuration &= 0xfefc;
-        Configuration |= (0x0);
-
-        RTMPFindHostPCIDev(pAd);
-        if (pObj->parent_pci_dev)
-        {
-		USHORT  vendor_id;
-
-		pci_read_config_word(pObj->parent_pci_dev, PCI_VENDOR_ID, &vendor_id);
-		vendor_id = le2cpu16(vendor_id);
-		if (vendor_id == PCIBUS_INTEL_VENDOR)
-                 {
-			bFindIntel = TRUE;
-                        RTMP_SET_PSFLAG(pAd, fRTMP_PS_TOGGLE_L1);
-                 }
-		/*
-		else if ((vendor_id == PCIBUS_AMD_VENDOR1)
-					&& (DeviceID == 0x96000000))
-				{
-					//Verified 2792 Aspire 8530 AMD NB (S3/S4/CBoot/WBoot/Chariot) by customer and ourselves.
-					// So use L1 Toggle method in this NB.
-			bFindIntel = TRUE;
-					RTMP_SET_PSFLAG(pAd, fRTMP_PS_TOGGLE_L1);
-					DBGPRINT(RT_DEBUG_TRACE, ("PSM : Aspire 8530 AMD NB. Use L1 Toggle. \n"));
-				}
-		*/
-		// Find PCI-to-PCI Bridge Express Capability Offset
-		pos = pci_find_capability(pObj->parent_pci_dev, PCI_CAP_ID_EXP);
-
-		if (pos != 0)
-		{
-			BOOLEAN		bChange = FALSE;
-			// PCI-to-PCI Bridge Link Control Register Offset
-			pAd->HostLnkCtrlOffset = pos + PCI_EXP_LNKCTL;
-			pci_read_config_word(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, &reg16);
-			Configuration = le2cpu16(reg16);
-			DBGPRINT(RT_DEBUG_TRACE, ("Read (Host PCI-to-PCI Bridge Link Control Register) offset 0x%x = 0x%x\n",
-			                            pAd->HostLnkCtrlOffset, Configuration));
-			pAd->HostLnkCtrlConfiguration = (Configuration & 0x103);
-			Configuration &= 0xfefc;
-			Configuration |= (0x0);
-
-			switch (pObj->DeviceID)
-			{
-#ifdef RT3090
-				case NIC3090_PCIe_DEVICE_ID:
-				case NIC3091_PCIe_DEVICE_ID:
-				case NIC3092_PCIe_DEVICE_ID:
-					if (bFindIntel == FALSE)
-						bChange = TRUE;
-					break;
-#endif // RT3090 //
-				default:
-					break;
-			}
-
-			if (bChange)
-			{
-				reg16 = cpu2le16(Configuration);
-				pci_write_config_word(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, reg16);
-				DBGPRINT(RT_DEBUG_TRACE, ("Write (Host PCI-to-PCI Bridge Link Control Register) offset 0x%x = 0x%x\n",
-						pAd->HostLnkCtrlOffset, Configuration));
-			}
-		}
-		else
-		{
-			pAd->HostLnkCtrlOffset = 0;
-			DBGPRINT(RT_DEBUG_ERROR, ("%s: cannot find PCI-to-PCI Bridge PCI Express Capability!\n", __FUNCTION__));
-		}
-        }
-    }
-    else
-    {
-        pAd->RLnkCtrlOffset = 0;
-        pAd->HostLnkCtrlOffset = 0;
-        DBGPRINT(RT_DEBUG_ERROR, ("%s: cannot find Ralink PCIe Device's PCI Express Capability!\n", __FUNCTION__));
-    }
-
-    if (bFindIntel == FALSE)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("Doesn't find Intel PCI host controller. \n"));
-		// Doesn't switch L0, L1, So set PCIePowerSaveLevel to 0xff
-		pAd->PCIePowerSaveLevel = 0xff;
-		if ((pAd->RLnkCtrlOffset != 0)
-#ifdef RT3090
-			&& ((pObj->DeviceID == NIC3090_PCIe_DEVICE_ID)
-				||(pObj->DeviceID == NIC3091_PCIe_DEVICE_ID)
-				||(pObj->DeviceID == NIC3092_PCIe_DEVICE_ID))
-#endif // RT3090 //
-		)
-		{
-			pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, &reg16);
-			Configuration = le2cpu16(reg16);
-			DBGPRINT(RT_DEBUG_TRACE, ("Read (Ralink 30xx PCIe Link Control Register) offset 0x%x = 0x%x\n",
-			                        pAd->RLnkCtrlOffset, Configuration));
-			pAd->RLnkCtrlConfiguration = (Configuration & 0x103);
-			Configuration &= 0xfefc;
-			Configuration |= (0x0);
-			reg16 = cpu2le16(Configuration);
-			pci_write_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, reg16);
-			DBGPRINT(RT_DEBUG_TRACE, ("Write (Ralink PCIe Link Control Register)  offset 0x%x = 0x%x\n",
-			                        pos + PCI_EXP_LNKCTL, Configuration));
-		}
-	}
-}
-
-VOID RTMPFindHostPCIDev(
-    IN	PRTMP_ADAPTER	pAd)
-{
-    USHORT  reg16;
-    UCHAR   reg8;
-	UINT	DevFn;
-    PPCI_DEV    pPci_dev;
-	POS_COOKIE	pObj;
-
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
-		return;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __FUNCTION__));
-
-    pObj->parent_pci_dev = NULL;
-    if (pObj->pci_dev->bus->parent)
-    {
-        for (DevFn = 0; DevFn < 255; DevFn++)
-        {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-            pPci_dev = pci_get_slot(pObj->pci_dev->bus->parent, DevFn);
-#else
-            pPci_dev = pci_find_slot(pObj->pci_dev->bus->parent->number, DevFn);
-#endif
-            if (pPci_dev)
-            {
-                pci_read_config_word(pPci_dev, PCI_CLASS_DEVICE, &reg16);
-                reg16 = le2cpu16(reg16);
-                pci_read_config_byte(pPci_dev, PCI_CB_CARD_BUS, &reg8);
-                if ((reg16 == PCI_CLASS_BRIDGE_PCI) &&
-                    (reg8 == pObj->pci_dev->bus->number))
-                {
-                    pObj->parent_pci_dev = pPci_dev;
-                }
-            }
-        }
-    }
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-		Level = RESTORE_HALT : Restore PCI host and Ralink PCIe Link Control field to its default value.
-		Level = Other Value : Restore from dot11 power save or radio off status. And force PCI host Link Control fields to 0x1
-
-	========================================================================
-*/
-VOID RTMPPCIeLinkCtrlValueRestore(
-	IN	PRTMP_ADAPTER	pAd,
-	IN   UCHAR		Level)
-{
-	USHORT  PCIePowerSaveLevel, reg16;
-	USHORT	Configuration;
-	POS_COOKIE	pObj;
-
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
-		return;
-
-	// Check PSControl Configuration
-	if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE)
-		return TRUE;
-
-	//3090 will not execute the following codes.
-	// Check interface : If not PCIe interface, return.
-
-#ifdef RT3090
-	if ((pObj->DeviceID == NIC3090_PCIe_DEVICE_ID)
-		||(pObj->DeviceID == NIC3091_PCIe_DEVICE_ID)
-		||(pObj->DeviceID == NIC3092_PCIe_DEVICE_ID))
-		return;
-#endif // RT3090 //
-	DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __FUNCTION__));
-	PCIePowerSaveLevel = pAd->PCIePowerSaveLevel;
-	if ((PCIePowerSaveLevel&0xff) == 0xff)
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("return  \n"));
-		return;
-	}
-
-	if (pObj->parent_pci_dev && (pAd->HostLnkCtrlOffset != 0))
-    {
-        PCI_REG_READ_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, Configuration);
-        if ((Configuration != 0) &&
-            (Configuration != 0xFFFF))
-        {
-		Configuration &= 0xfefc;
-		// If call from interface down, restore to orginial setting.
-		if (Level == RESTORE_CLOSE)
-		{
-			Configuration |= pAd->HostLnkCtrlConfiguration;
-		}
-		else
-			Configuration |= 0x0;
-            PCI_REG_WIRTE_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, Configuration);
-		DBGPRINT(RT_DEBUG_TRACE, ("Restore PCI host : offset 0x%x = 0x%x\n", pAd->HostLnkCtrlOffset, Configuration));
-        }
-        else
-            DBGPRINT(RT_DEBUG_ERROR, ("Restore PCI host : PCI_REG_READ_WORD failed (Configuration = 0x%x)\n", Configuration));
-    }
-
-    if (pObj->pci_dev && (pAd->RLnkCtrlOffset != 0))
-    {
-        PCI_REG_READ_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset, Configuration);
-        if ((Configuration != 0) &&
-            (Configuration != 0xFFFF))
-        {
-		Configuration &= 0xfefc;
-			// If call from interface down, restore to orginial setting.
-			if (Level == RESTORE_CLOSE)
-		Configuration |= pAd->RLnkCtrlConfiguration;
-			else
-				Configuration |= 0x0;
-            PCI_REG_WIRTE_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset, Configuration);
-		DBGPRINT(RT_DEBUG_TRACE, ("Restore Ralink : offset 0x%x = 0x%x\n", pAd->RLnkCtrlOffset, Configuration));
-        }
-        else
-            DBGPRINT(RT_DEBUG_ERROR, ("Restore Ralink : PCI_REG_READ_WORD failed (Configuration = 0x%x)\n", Configuration));
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,("%s <===\n", __FUNCTION__));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-		Max : limit Host PCI and Ralink PCIe device's LINK CONTROL field's value.
-		Because now frequently set our device to mode 1 or mode 3 will cause problem.
-
-	========================================================================
-*/
-VOID RTMPPCIeLinkCtrlSetting(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT		Max)
-{
-	USHORT  PCIePowerSaveLevel, reg16;
-	USHORT	Configuration;
-	POS_COOKIE	pObj;
-
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
-		return;
-
-	// Check PSControl Configuration
-	if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE)
-		return TRUE;
-
-	// Check interface : If not PCIe interface, return.
-	//Block 3090 to enter the following function
-
-#ifdef RT3090
-	if ((pObj->DeviceID == NIC3090_PCIe_DEVICE_ID)
-		||(pObj->DeviceID == NIC3091_PCIe_DEVICE_ID)
-		||(pObj->DeviceID == NIC3092_PCIe_DEVICE_ID))
-		return;
-#endif // RT3090 //
-	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP))
-	{
-		DBGPRINT(RT_DEBUG_INFO, ("RTMPPCIePowerLinkCtrl return on fRTMP_PS_CAN_GO_SLEEP flag\n"));
-		return;
-	}
-	DBGPRINT(RT_DEBUG_TRACE,("%s===>\n", __FUNCTION__));
-	PCIePowerSaveLevel = pAd->PCIePowerSaveLevel;
-	if ((PCIePowerSaveLevel&0xff) == 0xff)
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("return  \n"));
-		return;
-	}
-	PCIePowerSaveLevel = PCIePowerSaveLevel>>6;
-
-    // Skip non-exist deice right away
-	if (pObj->parent_pci_dev && (pAd->HostLnkCtrlOffset != 0))
-	{
-        PCI_REG_READ_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, Configuration);
-		switch (PCIePowerSaveLevel)
-		{
-			case 0:
-				// Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 00
-				Configuration &= 0xfefc;
-				break;
-			case 1:
-				// Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 01
-				Configuration &= 0xfefc;
-				Configuration |= 0x1;
-				break;
-			case 2:
-				//  Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11
-				Configuration &= 0xfefc;
-				Configuration |= 0x3;
-				break;
-			case 3:
-				// Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 and bit 8 of LinkControl of 2892 to 1
-				Configuration &= 0xfefc;
-				Configuration |= 0x103;
-				break;
-		}
-        PCI_REG_WIRTE_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, Configuration);
-		DBGPRINT(RT_DEBUG_TRACE, ("Write PCI host offset 0x%x = 0x%x\n", pAd->HostLnkCtrlOffset, Configuration));
-	}
-
-	if (pObj->pci_dev && (pAd->RLnkCtrlOffset != 0))
-	{
-		// first 2892 chip not allow to frequently set mode 3. will cause hang problem.
-		if (PCIePowerSaveLevel > Max)
-			PCIePowerSaveLevel = Max;
-
-        PCI_REG_READ_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset, Configuration);
-		switch (PCIePowerSaveLevel)
-		{
-			case 0:
-				// No PCI power safe
-				// Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 00 .
-				Configuration &= 0xfefc;
-				break;
-			case 1:
-				//  L0
-				// Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 01 .
-				Configuration &= 0xfefc;
-				Configuration |= 0x1;
-				break;
-			case 2:
-				// L0 and L1
-				//  Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11
-				Configuration &= 0xfefc;
-				Configuration |= 0x3;
-				break;
-			case 3:
-				// L0 , L1 and clock management.
-				// Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 and bit 8 of LinkControl of 2892 to 1
-				Configuration &= 0xfefc;
-				Configuration |= 0x103;
-		              pAd->bPCIclkOff = TRUE;
-				break;
-		}
-        PCI_REG_WIRTE_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset, Configuration);
-		DBGPRINT(RT_DEBUG_TRACE, ("Write Ralink device : offset 0x%x = 0x%x\n", pAd->RLnkCtrlOffset, Configuration));
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,("RTMPPCIePowerLinkCtrl <==============\n"));
-}
-/*
-	========================================================================
-
-	Routine Description:
-		1. Write a PCI register for rt30xx power solution 3
-
-	========================================================================
-*/
-VOID RTMPrt3xSetPCIePowerLinkCtrl(
-	IN	PRTMP_ADAPTER	pAd)
-{
-
-	ULONG	HostConfiguration;
-	ULONG	Configuration;
-	ULONG	Vendor;
-	ULONG	offset;
-	POS_COOKIE	pObj;
-	INT     pos;
-	USHORT	reg16;
-
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	DBGPRINT(RT_DEBUG_INFO, ("RTMPrt3xSetPCIePowerLinkCtrl.===> %x\n", pAd->StaCfg.PSControl.word));
-
-	// Check PSControl Configuration
-	if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE)
-		return;
-	RTMPFindHostPCIDev(pAd);
-        if (pObj->parent_pci_dev)
-        {
-		USHORT  vendor_id;
-		// Find PCI-to-PCI Bridge Express Capability Offset
-		pos = pci_find_capability(pObj->parent_pci_dev, PCI_CAP_ID_EXP);
-
-		if (pos != 0)
-		{
-			pAd->HostLnkCtrlOffset = pos + PCI_EXP_LNKCTL;
-		}
-	// If configurared to turn on L1.
-	HostConfiguration = 0;
-		if (pAd->StaCfg.PSControl.field.rt30xxForceASPMTest == 1)
-		{
-						DBGPRINT(RT_DEBUG_TRACE, ("Enter,PSM : Force ASPM \n"));
-
-			// Skip non-exist deice right away
-			if ((pAd->HostLnkCtrlOffset != 0))
-			{
-			 PCI_REG_READ_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, HostConfiguration);
-				// Prepare Configuration to write to Host
-				HostConfiguration |= 0x3;
-				PCI_REG_WIRTE_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, HostConfiguration);
-				pAd->Rt3xxHostLinkCtrl = HostConfiguration;
-				// Because in rt30xxForceASPMTest Mode, Force turn on L0s, L1.
-				// Fix HostConfiguration bit0:1 = 0x3 for later use.
-				HostConfiguration = 0x3;
-				DBGPRINT(RT_DEBUG_TRACE, ("PSM : Force ASPM : Host device L1/L0s Value =  0x%x\n", HostConfiguration));
-			}
-		}
-		else if (pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM == 1)
-		{
-
-			// Skip non-exist deice right away
-			if ((pAd->HostLnkCtrlOffset != 0))
-			{
-			 PCI_REG_READ_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, HostConfiguration);
-				pAd->Rt3xxHostLinkCtrl = HostConfiguration;
-				HostConfiguration &= 0x3;
-				DBGPRINT(RT_DEBUG_TRACE, ("PSM : Follow Host ASPM : Host device L1/L0s Value =  0x%x\n", HostConfiguration));
-			}
-		}
-        }
-	// Prepare to write Ralink setting.
-	// Find Ralink PCIe Device's Express Capability Offset
-	pos = pci_find_capability(pObj->pci_dev, PCI_CAP_ID_EXP);
-
-    if (pos != 0)
-    {
-        // Ralink PCIe Device's Link Control Register Offset
-       pAd->RLnkCtrlOffset = pos + PCI_EXP_LNKCTL;
-	pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, &reg16);
-        Configuration = le2cpu16(reg16);
-	DBGPRINT(RT_DEBUG_TRACE, ("Read (Ralink PCIe Link Control Register) offset 0x%x = 0x%x\n",
-			                                    pAd->RLnkCtrlOffset, Configuration));
-		Configuration |= 0x100;
-		if ((pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM == 1)
-			|| (pAd->StaCfg.PSControl.field.rt30xxForceASPMTest == 1))
-		{
-			switch(HostConfiguration)
-			{
-				case 0:
-					Configuration &= 0xffffffc;
-					break;
-				case 1:
-					Configuration &= 0xffffffc;
-					Configuration |= 0x1;
-					break;
-				case 2:
-					Configuration &= 0xffffffc;
-					Configuration |= 0x2;
-					break;
-				case 3:
-					Configuration |= 0x3;
-					break;
-			}
-		}
-		reg16 = cpu2le16(Configuration);
-		pci_write_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, reg16);
-		pAd->Rt3xxRalinkLinkCtrl = Configuration;
-		DBGPRINT(RT_DEBUG_TRACE, ("PSM :Write Ralink device L1/L0s Value =  0x%x\n", Configuration));
-	}
-	DBGPRINT(RT_DEBUG_INFO,("PSM :RTMPrt3xSetPCIePowerLinkCtrl <==============\n"));
-
-}
-
-#endif // CONFIG_STA_SUPPORT //
diff --git a/drivers/staging/rt3090/rt3090.h b/drivers/staging/rt3090/rt3090.h
deleted file mode 100644
index d325cb0..0000000
--- a/drivers/staging/rt3090/rt3090.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	rt3090.h
-
-    Abstract:
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
- */
-
-#ifndef __RT3090_H__
-#define __RT3090_H__
-
-#ifdef RT3090
-
-#ifndef RTMP_PCI_SUPPORT
-#error "For RT3090, you should define the compile flag -DRTMP_PCI_SUPPORT"
-#endif
-
-#ifndef RTMP_MAC_PCI
-#error "For RT3090, you should define the compile flag -DRTMP_MAC_PCI"
-#endif
-
-#ifndef RTMP_RF_RW_SUPPORT
-#error "For RT3090, you should define the compile flag -DRTMP_RF_RW_SUPPORT"
-#endif
-
-#ifndef RT30xx
-#error "For RT3090, you should define the compile flag -DRT30xx"
-#endif
-
-#ifdef CARRIER_DETECTION_SUPPORT
-#define TONE_RADAR_DETECT_SUPPORT
-#define CARRIER_SENSE_NEW_ALGO
-#endif // CARRIER_DETECTION_SUPPORT //
-
-#define PCIE_PS_SUPPORT
-
-#include "mac_pci.h"
-#include "rt30xx.h"
-
-//
-// Device ID & Vendor ID, these values should match EEPROM value
-//
-#define NIC3090_PCIe_DEVICE_ID  0x3090		// 1T/1R miniCard
-#define NIC3091_PCIe_DEVICE_ID  0x3091		// 1T/2R miniCard
-#define NIC3092_PCIe_DEVICE_ID  0x3092		// 2T/2R miniCard
-
-#endif // RT3090 //
-
-#endif //__RT3090_H__ //
diff --git a/drivers/staging/rt3090/rt30xx.h b/drivers/staging/rt3090/rt30xx.h
deleted file mode 100644
index 70971a0..0000000
--- a/drivers/staging/rt3090/rt30xx.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	rt30xx.h
-
-    Abstract:
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
- */
-
-#ifndef __RT30XX_H__
-#define __RT30XX_H__
-
-#ifdef RT30xx
-
-
-extern REG_PAIR RT30xx_RFRegTable[];
-extern UCHAR NUM_RF_REG_PARMS;
-
-#endif // RT30xx //
-
-#endif //__RT30XX_H__ //
diff --git a/drivers/staging/rt3090/rt3370.h b/drivers/staging/rt3090/rt3370.h
deleted file mode 100644
index bfa9006..0000000
--- a/drivers/staging/rt3090/rt3370.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    rt3370.h
-
-    Abstract:
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
- */
-
-#ifndef __RT3370_H__
-#define __RT3370_H__
-
-#ifdef RT3370
-
-
-#error "For RT3070, you should define the compile flag -DRTMP_USB_SUPPORT"
-
-#error "For RT3070, you should define the compile flag -DRTMP_MAC_USB"
-
-#ifndef RTMP_RF_RW_SUPPORT
-#error "For RT3070, you should define the compile flag -DRTMP_RF_RW_SUPPORT"
-#endif
-
-#ifndef RT33xx
-#error "For RT3070, you should define the compile flag -DRT30xx"
-#endif
-
-#include "mac_usb.h"
-#include "rt33xx.h"
-
-//
-// Device ID & Vendor ID, these values should match EEPROM value
-//
-
-#endif // RT3370 //
-
-#endif //__RT3370_H__ //
diff --git a/drivers/staging/rt3090/rt3390.h b/drivers/staging/rt3090/rt3390.h
deleted file mode 100644
index 412ab3d..0000000
--- a/drivers/staging/rt3090/rt3390.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    rt3390.h
-
-    Abstract:
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
- */
-
-#ifndef __RT3390_H__
-#define __RT3390_H__
-
-#ifdef RT3390
-
-#ifndef RTMP_PCI_SUPPORT
-#error "For RT3390, you should define the compile flag -DRTMP_PCI_SUPPORT"
-#endif
-
-#ifndef RTMP_MAC_PCI
-#error "For RT3390, you should define the compile flag -DRTMP_MAC_PCI"
-#endif
-
-#ifndef RTMP_RF_RW_SUPPORT
-#error "For RT3390, you should define the compile flag -DRTMP_RF_RW_SUPPORT"
-#endif
-
-#ifndef RT30xx
-#error "For RT3390, you should define the compile flag -DRT30xx"
-#endif
-
-#ifdef CARRIER_DETECTION_SUPPORT
-#define TONE_RADAR_DETECT_SUPPORT
-#define CARRIER_SENSE_NEW_ALGO
-#endif // CARRIER_DETECTION_SUPPORT //
-
-#define PCIE_PS_SUPPORT
-
-#include "mac_pci.h"
-#include "rt33xx.h"
-
-//
-// Device ID & Vendor ID, these values should match EEPROM value
-//
-#define NIC3390_PCIe_DEVICE_ID  0x3090		// 1T/1R miniCard
-#define NIC3391_PCIe_DEVICE_ID  0x3091		// 1T/2R miniCard
-#define NIC3392_PCIe_DEVICE_ID  0x3092		// 2T/2R miniCard
-
-#endif // RT3390 //
-
-#endif //__RT3390_H__ //
diff --git a/drivers/staging/rt3090/rt33xx.h b/drivers/staging/rt3090/rt33xx.h
deleted file mode 100644
index 6eb9388..0000000
--- a/drivers/staging/rt3090/rt33xx.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    rt33xx.h
-
-    Abstract:
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
- */
-
-#ifndef __RT33XX_H__
-#define __RT33XX_H__
-
-#ifdef RT33xx
-
-
-extern REG_PAIR RFRegTableOverRT3390[];
-extern UCHAR NUM_RF_REG_PARMS_OVER_RT3390;
-
-#endif // RT33xx //
-
-#endif //__RT33XX_H__ //
diff --git a/drivers/staging/rt3090/rt_ate.c b/drivers/staging/rt3090/rt_ate.c
deleted file mode 100644
index 259aae4..0000000
--- a/drivers/staging/rt3090/rt_ate.c
+++ /dev/null
@@ -1,6089 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
- */
-
-#include "rt_config.h"
-
-#ifdef RALINK_ATE
-
-#ifdef RT30xx
-#define ATE_BBP_REG_NUM	168
-UCHAR restore_BBP[ATE_BBP_REG_NUM]={0};
-#endif // RT30xx //
-
-// 802.11 MAC Header, Type:Data, Length:24bytes
-UCHAR TemplateFrame[24] = {0x08,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-		0x00,0xAA,0xBB,0x12,0x34,0x56,0x00,0x11,0x22,0xAA,0xBB,0xCC,0x00,0x00};
-
-extern RTMP_RF_REGS RF2850RegTable[];
-extern UCHAR NUM_OF_2850_CHNL;
-
-extern FREQUENCY_ITEM FreqItems3020[];
-extern UCHAR NUM_OF_3020_CHNL;
-
-
-
-
-static CHAR CCKRateTable[] = {0, 1, 2, 3, 8, 9, 10, 11, -1}; /* CCK Mode. */
-static CHAR OFDMRateTable[] = {0, 1, 2, 3, 4, 5, 6, 7, -1}; /* OFDM Mode. */
-static CHAR HTMIXRateTable[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}; /* HT Mix Mode. */
-
-static INT TxDmaBusy(
-	IN PRTMP_ADAPTER pAd);
-
-static INT RxDmaBusy(
-	IN PRTMP_ADAPTER pAd);
-
-static VOID RtmpDmaEnable(
-	IN PRTMP_ADAPTER pAd,
-	IN INT Enable);
-
-static VOID BbpSoftReset(
-	IN PRTMP_ADAPTER pAd);
-
-static VOID RtmpRfIoWrite(
-	IN PRTMP_ADAPTER pAd);
-
-static INT ATESetUpFrame(
-	IN PRTMP_ADAPTER pAd,
-	IN UINT32 TxIdx);
-
-static INT ATETxPwrHandler(
-	IN PRTMP_ADAPTER pAd,
-	IN char index);
-
-static INT ATECmdHandler(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-#ifndef RT30xx
-static int CheckMCSValid(
-	IN UCHAR Mode,
-	IN UCHAR Mcs);
-#endif // RT30xx //
-
-#ifdef RT30xx
-static int CheckMCSValid(
-	IN UCHAR Mode,
-	IN UCHAR Mcs,
-	IN BOOLEAN bRT2070);
-#endif // RT30xx //
-
-#ifdef RTMP_MAC_PCI
-static VOID ATEWriteTxWI(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PTXWI_STRUC	pOutTxWI,
-	IN	BOOLEAN			FRAG,
-	IN	BOOLEAN			CFACK,
-	IN	BOOLEAN			InsTimestamp,
-	IN	BOOLEAN			AMPDU,
-	IN	BOOLEAN			Ack,
-	IN	BOOLEAN			NSeq,		// HW new a sequence.
-	IN	UCHAR			BASize,
-	IN	UCHAR			WCID,
-	IN	ULONG			Length,
-	IN	UCHAR			PID,
-	IN	UCHAR			TID,
-	IN	UCHAR			TxRate,
-	IN	UCHAR			Txopmode,
-	IN	BOOLEAN			CfAck,
-	IN	HTTRANSMIT_SETTING	*pTransmit);
-#endif // RTMP_MAC_PCI //
-
-
-static VOID SetJapanFilter(
-	IN	PRTMP_ADAPTER	pAd);
-
-
-#ifdef RALINK_28xx_QA
-static inline INT	DO_RACFG_CMD_ATE_START(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_STOP(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_RF_WRITE_ALL(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_E2PROM_READ16(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_E2PROM_WRITE16(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_E2PROM_READ_ALL
-(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_E2PROM_WRITE_ALL(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_IO_READ(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_IO_WRITE(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_IO_READ_BULK(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_BBP_READ8(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_BBP_WRITE8(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_BBP_READ_ALL(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_GET_NOISE_LEVEL(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_GET_COUNTER(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_CLEAR_COUNTER(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_TX_START(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_GET_TX_STATUS(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_TX_STOP(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_RX_START(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_RX_STOP(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_RX_STOP(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_START_TX_CARRIER(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_START_TX_CONT(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_START_TX_FRAME(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_SET_BW(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_SET_TX_POWER0(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_SET_TX_POWER1(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_SET_FREQ_OFFSET(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_GET_STATISTICS(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_RESET_COUNTER(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_SEL_TX_ANTENNA(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_SEL_RX_ANTENNA(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_SET_PREAMBLE(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_SET_CHANNEL(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_SET_ADDR1(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_SET_ADDR2(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_SET_ADDR3(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_SET_RATE(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_SET_TX_FRAME_LEN(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_SET_TX_FRAME_COUNT(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_START_RX_FRAME(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_E2PROM_READ_BULK(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_E2PROM_WRITE_BULK(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_IO_WRITE_BULK(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_BBP_READ_BULK(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-static inline INT DO_RACFG_CMD_ATE_BBP_WRITE_BULK(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN struct ate_racfghdr *pRaCfg
-);
-
-#endif // RALINK_28xx_QA //
-
-
-#ifdef RTMP_MAC_PCI
-static INT TxDmaBusy(
-	IN PRTMP_ADAPTER pAd)
-{
-	INT result;
-	WPDMA_GLO_CFG_STRUC GloCfg;
-
-	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);	// disable DMA
-	if (GloCfg.field.TxDMABusy)
-		result = 1;
-	else
-		result = 0;
-
-	return result;
-}
-
-
-static INT RxDmaBusy(
-	IN PRTMP_ADAPTER pAd)
-{
-	INT result;
-	WPDMA_GLO_CFG_STRUC GloCfg;
-
-	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);	// disable DMA
-	if (GloCfg.field.RxDMABusy)
-		result = 1;
-	else
-		result = 0;
-
-	return result;
-}
-
-
-static VOID RtmpDmaEnable(
-	IN PRTMP_ADAPTER pAd,
-	IN INT Enable)
-{
-	BOOLEAN value;
-	ULONG WaitCnt;
-	WPDMA_GLO_CFG_STRUC GloCfg;
-
-	value = Enable > 0 ? 1 : 0;
-
-	// check DMA is in busy mode.
-	WaitCnt = 0;
-
-	while (TxDmaBusy(pAd) || RxDmaBusy(pAd))
-	{
-		RTMPusecDelay(10);
-		if (WaitCnt++ > 100)
-			break;
-	}
-
-	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);	// disable DMA
-	GloCfg.field.EnableTxDMA = value;
-	GloCfg.field.EnableRxDMA = value;
-	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);	// abort all TX rings
-	RTMPusecDelay(5000);
-
-	return;
-}
-#endif // RTMP_MAC_PCI //
-
-
-
-
-static VOID BbpSoftReset(
-	IN PRTMP_ADAPTER pAd)
-{
-	UCHAR BbpData = 0;
-
-	// Soft reset, set BBP R21 bit0=1->0
-	ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R21, &BbpData);
-	BbpData |= 0x00000001; //set bit0=1
-	ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, BbpData);
-
-	ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R21, &BbpData);
-	BbpData &= ~(0x00000001); //set bit0=0
-	ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, BbpData);
-
-	return;
-}
-
-
-static VOID RtmpRfIoWrite(
-	IN PRTMP_ADAPTER pAd)
-{
-	// Set RF value 1's set R3[bit2] = [0]
-	RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
-	RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
-	RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
-	RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
-
-	RTMPusecDelay(200);
-
-	// Set RF value 2's set R3[bit2] = [1]
-	RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
-	RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
-	RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04));
-	RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
-
-	RTMPusecDelay(200);
-
-	// Set RF value 3's set R3[bit2] = [0]
-	RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
-	RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
-	RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
-	RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
-
-	return;
-}
-
-
-#ifdef RT30xx
-static int CheckMCSValid(
-	UCHAR Mode,
-	UCHAR Mcs,
-	BOOLEAN bRT2070)
-#endif // RT30xx //
-#ifndef RT30xx
-static int CheckMCSValid(
-	IN UCHAR Mode,
-	IN UCHAR Mcs)
-#endif // RT30xx //
-{
-	INT i;
-	PCHAR pRateTab;
-
-	switch (Mode)
-	{
-		case 0:
-			pRateTab = CCKRateTable;
-			break;
-		case 1:
-			pRateTab = OFDMRateTable;
-			break;
-		case 2:
-		case 3:
-#ifdef RT30xx
-			if (bRT2070)
-				pRateTab = OFDMRateTable;
-			else
-#endif // RT30xx //
-			pRateTab = HTMIXRateTable;
-			break;
-		default:
-			ATEDBGPRINT(RT_DEBUG_ERROR, ("unrecognizable Tx Mode %d\n", Mode));
-			return -1;
-			break;
-	}
-
-	i = 0;
-	while (pRateTab[i] != -1)
-	{
-		if (pRateTab[i] == Mcs)
-			return 0;
-		i++;
-	}
-
-	return -1;
-}
-
-
-static INT ATETxPwrHandler(
-	IN PRTMP_ADAPTER pAd,
-	IN char index)
-{
-	ULONG R;
-	CHAR TxPower;
-	UCHAR Bbp94 = 0;
-	BOOLEAN bPowerReduce = FALSE;
-#ifdef RTMP_RF_RW_SUPPORT
-	UCHAR RFValue;
-#endif // RTMP_RF_RW_SUPPORT //
-#ifdef RALINK_28xx_QA
-	if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))
-	{
-		/*
-			When QA is used for Tx, pAd->ate.TxPower0/1 and real tx power
-			are not synchronized.
-		*/
-		return 0;
-	}
-	else
-#endif // RALINK_28xx_QA //
-	{
-		TxPower = index == 0 ? pAd->ate.TxPower0 : pAd->ate.TxPower1;
-
-		if (pAd->ate.Channel <= 14)
-		{
-			if (TxPower > 31)
-			{
-
-				// R3, R4 can't large than 31 (0x24), 31 ~ 36 used by BBP 94
-				R = 31;
-				if (TxPower <= 36)
-					Bbp94 = BBPR94_DEFAULT + (UCHAR)(TxPower - 31);
-			}
-			else if (TxPower < 0)
-			{
-
-				// R3, R4 can't less than 0, -1 ~ -6 used by BBP 94
-				R = 0;
-				if (TxPower >= -6)
-					Bbp94 = BBPR94_DEFAULT + TxPower;
-			}
-			else
-			{
-				// 0 ~ 31
-				R = (ULONG) TxPower;
-				Bbp94 = BBPR94_DEFAULT;
-			}
-
-			ATEDBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R=%ld, BBP_R94=%d)\n", __FUNCTION__, TxPower, R, Bbp94));
-		}
-		else /* 5.5 GHz */
-		{
-			if (TxPower > 15)
-			{
-
-				// R3, R4 can't large than 15 (0x0F)
-				R = 15;
-			}
-			else if (TxPower < 0)
-			{
-
-				// R3, R4 can't less than 0
-				// -1 ~ -7
-				ASSERT((TxPower >= -7));
-				R = (ULONG)(TxPower + 7);
-				bPowerReduce = TRUE;
-			}
-			else
-			{
-				// 0 ~ 15
-				R = (ULONG) TxPower;
-			}
-
-			ATEDBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R=%lu)\n", __FUNCTION__, TxPower, R));
-		}
-//2008/09/10:KH adds to support 3070 ATE TX Power tunning real time<--
-#ifdef RTMP_RF_RW_SUPPORT
-		if (IS_RT30xx(pAd))
-		{
-			// Set Tx Power
-			ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R12, (PUCHAR)&RFValue);
-			RFValue = (RFValue & 0xE0) | TxPower;
-			ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R12, (UCHAR)RFValue);
-			ATEDBGPRINT(RT_DEBUG_TRACE, ("3070 or 2070:%s (TxPower=%d, RFValue=%x)\n", __FUNCTION__, TxPower, RFValue));
-		}
-		else
-#endif // RTMP_RF_RW_SUPPORT //
-		{
-		if (pAd->ate.Channel <= 14)
-		{
-			if (index == 0)
-			{
-				// shift TX power control to correct RF(R3) register bit position
-				R = R << 9;
-				R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
-				pAd->LatchRfRegs.R3 = R;
-			}
-			else
-			{
-				// shift TX power control to correct RF(R4) register bit position
-				R = R << 6;
-				R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
-				pAd->LatchRfRegs.R4 = R;
-			}
-		}
-		else /* 5.5GHz */
-		{
-			if (bPowerReduce == FALSE)
-			{
-				if (index == 0)
-				{
-					// shift TX power control to correct RF(R3) register bit position
-					R = (R << 10) | (1 << 9);
-					R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
-					pAd->LatchRfRegs.R3 = R;
-				}
-				else
-				{
-					// shift TX power control to correct RF(R4) register bit position
-					R = (R << 7) | (1 << 6);
-					R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
-					pAd->LatchRfRegs.R4 = R;
-				}
-			}
-			else
-			{
-				if (index == 0)
-				{
-					// shift TX power control to correct RF(R3) register bit position
-					R = (R << 10);
-					R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
-
-					/* Clear bit 9 of R3 to reduce 7dB. */
-					pAd->LatchRfRegs.R3 = (R & (~(1 << 9)));
-				}
-				else
-				{
-					// shift TX power control to correct RF(R4) register bit position
-					R = (R << 7);
-					R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
-
-					/* Clear bit 6 of R4 to reduce 7dB. */
-					pAd->LatchRfRegs.R4 = (R & (~(1 << 6)));
-				}
-			}
-		}
-		RtmpRfIoWrite(pAd);
-	}
-//2008/09/10:KH adds to support 3070 ATE TX Power tunning real time-->
-
-		return 0;
-	}
-}
-
-
-/*
-==========================================================================
-    Description:
-        Set ATE operation mode to
-        0. ATESTART  = Start ATE Mode
-        1. ATESTOP   = Stop ATE Mode
-        2. TXCONT    = Continuous Transmit
-        3. TXCARR    = Transmit Carrier
-        4. TXFRAME   = Transmit Frames
-        5. RXFRAME   = Receive Frames
-#ifdef RALINK_28xx_QA
-        6. TXSTOP    = Stop Any Type of Transmition
-        7. RXSTOP    = Stop Receiving Frames
-#endif // RALINK_28xx_QA //
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-==========================================================================
-*/
-#ifdef RTMP_MAC_PCI
-static INT	ATECmdHandler(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	UINT32			Value = 0;
-	UCHAR			BbpData;
-	UINT32			MacData = 0;
-	PTXD_STRUC		pTxD;
-	INT				index;
-	UINT			i = 0, atemode = 0;
-	PRXD_STRUC		pRxD;
-	PRTMP_TX_RING	pTxRing = &pAd->TxRing[QID_AC_BE];
-	NDIS_STATUS		Status = NDIS_STATUS_SUCCESS;
-#ifdef	RT_BIG_ENDIAN
-    PTXD_STRUC      pDestTxD;
-    TXD_STRUC       TxD;
-#endif
-
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("===> ATECmdHandler()\n"));
-
-	ATEAsicSwitchChannel(pAd);
-
-	/* empty function */
-	AsicLockChannel(pAd, pAd->ate.Channel);
-
-	RTMPusecDelay(5000);
-
-	// read MAC_SYS_CTRL and backup MAC_SYS_CTRL value.
-	RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
-
-	// Default value in BBP R22 is 0x0.
-	BbpData = 0;
-
-	// clean bit4 to stop continuous Tx production test.
-	MacData &= 0xFFFFFFEF;
-
-	// Enter ATE mode and set Tx/Rx Idle
-	if (!strcmp(arg, "ATESTART"))
-	{
-		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: ATESTART\n"));
-
-#if defined(LINUX) || defined(VXWORKS)
-		// check if we have removed the firmware
-		if (!(ATE_ON(pAd)))
-		{
-			NICEraseFirmware(pAd);
-		}
-#endif // defined(LINUX) || defined(VXWORKS) //
-
-		atemode = pAd->ate.Mode;
-		pAd->ate.Mode = ATE_START;
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
-
-		if (atemode == ATE_TXCARR)
-		{
-			// No Carrier Test set BBP R22 bit7=0, bit6=0, bit[5~0]=0x0
-			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
-			BbpData &= 0xFFFFFF00; // clear bit7, bit6, bit[5~0]
-		    ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
-		}
-		else if (atemode == ATE_TXCARRSUPP)
-		{
-			// No Cont. TX set BBP R22 bit7=0
-			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
-			BbpData &= ~(1 << 7); // set bit7=0
-			ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
-
-			// No Carrier Suppression set BBP R24 bit0=0
-			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R24, &BbpData);
-			BbpData &= 0xFFFFFFFE; // clear bit0
-		    ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, BbpData);
-		}
-
-		/*
-			We should free some resource which was allocated
-			when ATE_TXFRAME , ATE_STOP, and ATE_TXCONT.
-		*/
-		else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP))
-		{
-			PRTMP_TX_RING pTxRing = &pAd->TxRing[QID_AC_BE];
-
-			if (atemode == ATE_TXCONT)
-			{
-				// No Cont. TX set BBP R22 bit7=0
-				ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
-				BbpData &= ~(1 << 7); // set bit7=0
-				ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
-			}
-
-			// Abort Tx, Rx DMA.
-			RtmpDmaEnable(pAd, 0);
-			for (i=0; i<TX_RING_SIZE; i++)
-			{
-				PNDIS_PACKET  pPacket;
-
-#ifndef RT_BIG_ENDIAN
-			    pTxD = (PTXD_STRUC)pAd->TxRing[QID_AC_BE].Cell[i].AllocVa;
-#else
-			pDestTxD = (PTXD_STRUC)pAd->TxRing[QID_AC_BE].Cell[i].AllocVa;
-			TxD = *pDestTxD;
-			pTxD = &TxD;
-			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-#endif
-				pTxD->DMADONE = 0;
-				pPacket = pTxRing->Cell[i].pNdisPacket;
-
-				if (pPacket)
-				{
-					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
-					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-				}
-
-				// Always assign pNdisPacket as NULL after clear
-				pTxRing->Cell[i].pNdisPacket = NULL;
-
-				pPacket = pTxRing->Cell[i].pNextNdisPacket;
-
-				if (pPacket)
-				{
-					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
-					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-				}
-
-				// Always assign pNextNdisPacket as NULL after clear
-				pTxRing->Cell[i].pNextNdisPacket = NULL;
-#ifdef RT_BIG_ENDIAN
-				RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-				WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
-#endif
-			}
-
-			// Start Tx, RX DMA
-			RtmpDmaEnable(pAd, 1);
-		}
-
-		// reset Rx statistics.
-		pAd->ate.LastSNR0 = 0;
-		pAd->ate.LastSNR1 = 0;
-		pAd->ate.LastRssi0 = 0;
-		pAd->ate.LastRssi1 = 0;
-		pAd->ate.LastRssi2 = 0;
-		pAd->ate.AvgRssi0 = 0;
-		pAd->ate.AvgRssi1 = 0;
-		pAd->ate.AvgRssi2 = 0;
-		pAd->ate.AvgRssi0X8 = 0;
-		pAd->ate.AvgRssi1X8 = 0;
-		pAd->ate.AvgRssi2X8 = 0;
-		pAd->ate.NumOfAvgRssiSample = 0;
-
-#ifdef RALINK_28xx_QA
-		// Tx frame
-		pAd->ate.bQATxStart = FALSE;
-		pAd->ate.bQARxStart = FALSE;
-		pAd->ate.seq = 0;
-
-		// counters
-		pAd->ate.U2M = 0;
-		pAd->ate.OtherData = 0;
-		pAd->ate.Beacon = 0;
-		pAd->ate.OtherCount = 0;
-		pAd->ate.TxAc0 = 0;
-		pAd->ate.TxAc1 = 0;
-		pAd->ate.TxAc2 = 0;
-		pAd->ate.TxAc3 = 0;
-		/*pAd->ate.TxHCCA = 0;*/
-		pAd->ate.TxMgmt = 0;
-		pAd->ate.RSSI0 = 0;
-		pAd->ate.RSSI1 = 0;
-		pAd->ate.RSSI2 = 0;
-		pAd->ate.SNR0 = 0;
-		pAd->ate.SNR1 = 0;
-
-		// control
-		pAd->ate.TxDoneCount = 0;
-		// TxStatus : 0 --> task is idle, 1 --> task is running
-		pAd->ate.TxStatus = 0;
-#endif // RALINK_28xx_QA //
-
-		// Soft reset BBP.
-		BbpSoftReset(pAd);
-
-
-#ifdef CONFIG_STA_SUPPORT
-		/* LinkDown() has "AsicDisableSync();" and "RTMP_BBP_IO_R/W8_BY_REG_ID();" inside. */
-//      LinkDown(pAd, FALSE);
-//		AsicEnableBssSync(pAd);
-
-#if defined(LINUX) || defined(VXWORKS)
-		RTMP_OS_NETDEV_STOP_QUEUE(pAd->net_dev);
-#endif // defined(LINUX) || defined(VXWORKS) //
-
-		/*
-			If we skip "LinkDown()", we should disable protection
-			to prevent from sending out RTS or CTS-to-self.
-		*/
-		ATEDisableAsicProtect(pAd);
-		RTMPStationStop(pAd);
-#endif // CONFIG_STA_SUPPORT //
-
-		/* Disable Tx */
-		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
-		Value &= ~(1 << 2);
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-
-		/* Disable Rx */
-		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
-		Value &= ~(1 << 3);
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-	}
-	else if (!strcmp(arg, "ATESTOP"))
-	{
-		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: ATESTOP\n"));
-
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
-
-		// recover the MAC_SYS_CTRL register back
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
-
-		// disable Tx, Rx
-		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
-		Value &= (0xfffffff3);
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-
-		// abort Tx, RX DMA
-		RtmpDmaEnable(pAd, 0);
-
-#ifdef LINUX
-		pAd->ate.bFWLoading = TRUE;
-
-		Status = NICLoadFirmware(pAd);
-
-		if (Status != NDIS_STATUS_SUCCESS)
-		{
-			ATEDBGPRINT(RT_DEBUG_ERROR, ("NICLoadFirmware failed, Status[=0x%08x]\n", Status));
-			return FALSE;
-		}
-#endif // LINUX //
-		pAd->ate.Mode = ATE_STOP;
-
-		/*
-			Even the firmware has been loaded,
-			we still could use ATE_BBP_IO_READ8_BY_REG_ID().
-			But this is not suggested.
-		*/
-		BbpSoftReset(pAd);
-
-		RTMP_ASIC_INTERRUPT_DISABLE(pAd);
-
-		NICInitializeAdapter(pAd, TRUE);
-
-		/*
-			Reinitialize Rx Ring before Rx DMA is enabled.
-			>>>RxCoherent<<< was gone !
-		*/
-		for (index = 0; index < RX_RING_SIZE; index++)
-		{
-			pRxD = (PRXD_STRUC) pAd->RxRing.Cell[index].AllocVa;
-			pRxD->DDONE = 0;
-		}
-
-		// We should read EEPROM for all cases.
-		NICReadEEPROMParameters(pAd, NULL);
-		NICInitAsicFromEEPROM(pAd);
-
-		AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-
-		/* empty function */
-		AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-
-		/* clear garbage interrupts */
-		RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, 0xffffffff);
-		/* Enable Interrupt */
-		RTMP_ASIC_INTERRUPT_ENABLE(pAd);
-
-		/* restore RX_FILTR_CFG */
-
-#ifdef CONFIG_STA_SUPPORT
-		/* restore RX_FILTR_CFG due to that QA maybe set it to 0x3 */
-		RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL);
-#endif // CONFIG_STA_SUPPORT //
-
-		// Enable Tx
-		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
-		Value |= (1 << 2);
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-
-		// Enable Tx, Rx DMA.
-		RtmpDmaEnable(pAd, 1);
-
-		// Enable Rx
-		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
-		Value |= (1 << 3);
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-
-
-#ifdef CONFIG_STA_SUPPORT
-		RTMPStationStart(pAd);
-#endif // CONFIG_STA_SUPPORT //
-
-#if defined(LINUX) || defined(VXWORKS)
-		RTMP_OS_NETDEV_START_QUEUE(pAd->net_dev);
-#endif // defined(LINUX) || defined(VXWORKS) //
-	}
-	else if (!strcmp(arg, "TXCARR"))
-	{
-		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXCARR\n"));
-		pAd->ate.Mode = ATE_TXCARR;
-
-		// QA has done the following steps if it is used.
-		if (pAd->ate.bQATxStart == FALSE)
-		{
-			// Soft reset BBP.
-			BbpSoftReset(pAd);
-
-			// Carrier Test set BBP R22 bit7=1, bit6=1, bit[5~0]=0x01
-			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
-			BbpData &= 0xFFFFFF00; //clear bit7, bit6, bit[5~0]
-			BbpData |= 0x000000C1; //set bit7=1, bit6=1, bit[5~0]=0x01
-			ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
-
-			// set MAC_SYS_CTRL(0x1004) Continuous Tx Production Test (bit4) = 1
-			RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
-			Value = Value | 0x00000010;
-			RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-		}
-	}
-	else if (!strcmp(arg, "TXCONT"))
-	{
-		if (pAd->ate.bQATxStart == TRUE)
-		{
-			/*
-				set MAC_SYS_CTRL(0x1004) bit4(Continuous Tx Production Test)
-				and bit2(MAC TX enable) back to zero.
-			*/
-			RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
-			MacData &= 0xFFFFFFEB;
-			RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
-
-			// set BBP R22 bit7=0
-			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
-			BbpData &= 0xFFFFFF7F; //set bit7=0
-			ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
-		}
-
-		/*
-			for TxCont mode.
-			Step 1: Send 50 packets first then wait for a moment.
-			Step 2: Send more 50 packet then start continue mode.
-		*/
-		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXCONT\n"));
-
-		// Step 1: send 50 packets first.
-		pAd->ate.Mode = ATE_TXCONT;
-		pAd->ate.TxCount = 50;
-
-		/* Do it after Tx/Rx DMA is aborted. */
-//		pAd->ate.TxDoneCount = 0;
-
-		// Soft reset BBP.
-		BbpSoftReset(pAd);
-
-		// Abort Tx, RX DMA.
-		RtmpDmaEnable(pAd, 0);
-
-		// Fix can't smooth kick
-		{
-			RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QID_AC_BE * 0x10,  &pTxRing->TxDmaIdx);
-			pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx;
-			pTxRing->TxCpuIdx = pTxRing->TxDmaIdx;
-			RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QID_AC_BE * 0x10, pTxRing->TxCpuIdx);
-		}
-
-		pAd->ate.TxDoneCount = 0;
-
-		/* Only needed if we have to send some normal frames. */
-		SetJapanFilter(pAd);
-
-		for (i = 0; (i < TX_RING_SIZE-1) && (i < pAd->ate.TxCount); i++)
-		{
-			PNDIS_PACKET pPacket;
-			UINT32 TxIdx = pTxRing->TxCpuIdx;
-
-#ifndef RT_BIG_ENDIAN
-			pTxD = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
-#else
-			pDestTxD = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
-			TxD = *pDestTxD;
-			pTxD = &TxD;
-			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-#endif
-			// Clean current cell.
-			pPacket = pTxRing->Cell[TxIdx].pNdisPacket;
-
-			if (pPacket)
-			{
-				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-			}
-
-			// Always assign pNdisPacket as NULL after clear
-			pTxRing->Cell[TxIdx].pNdisPacket = NULL;
-
-			pPacket = pTxRing->Cell[TxIdx].pNextNdisPacket;
-
-			if (pPacket)
-			{
-				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-			}
-
-			// Always assign pNextNdisPacket as NULL after clear
-			pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
-
-#ifdef RT_BIG_ENDIAN
-			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-			WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
-#endif
-
-			if (ATESetUpFrame(pAd, TxIdx) != 0)
-				break;
-
-			INC_RING_INDEX(pTxRing->TxCpuIdx, TX_RING_SIZE);
-		}
-
-		// Setup frame format.
-		ATESetUpFrame(pAd, pTxRing->TxCpuIdx);
-
-		// Start Tx, RX DMA.
-		RtmpDmaEnable(pAd, 1);
-
-		// Enable Tx
-		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
-		Value |= (1 << 2);
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-
-		// Disable Rx
-		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
-		Value &= ~(1 << 3);
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-
-#ifdef RALINK_28xx_QA
-		if (pAd->ate.bQATxStart == TRUE)
-		{
-			pAd->ate.TxStatus = 1;
-		}
-#endif // RALINK_28xx_QA //
-
-		// kick Tx-Ring
-		RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QID_AC_BE * RINGREG_DIFF, pAd->TxRing[QID_AC_BE].TxCpuIdx);
-
-		RTMPusecDelay(5000);
-
-
-		// Step 2: send more 50 packets then start continue mode.
-		// Abort Tx, RX DMA.
-		RtmpDmaEnable(pAd, 0);
-
-		// Cont. TX set BBP R22 bit7=1
-		ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
-		BbpData |= 0x00000080; //set bit7=1
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
-
-		pAd->ate.TxCount = 50;
-
-		// Fix can't smooth kick
-		{
-			RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QID_AC_BE * 0x10,  &pTxRing->TxDmaIdx);
-			pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx;
-			pTxRing->TxCpuIdx = pTxRing->TxDmaIdx;
-			RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QID_AC_BE * 0x10, pTxRing->TxCpuIdx);
-		}
-
-		pAd->ate.TxDoneCount = 0;
-
-		SetJapanFilter(pAd);
-
-		for (i = 0; (i < TX_RING_SIZE-1) && (i < pAd->ate.TxCount); i++)
-		{
-			PNDIS_PACKET pPacket;
-			UINT32 TxIdx = pTxRing->TxCpuIdx;
-
-#ifndef RT_BIG_ENDIAN
-			pTxD = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
-#else
-			pDestTxD = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
-			TxD = *pDestTxD;
-			pTxD = &TxD;
-			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-#endif
-			// clean current cell.
-			pPacket = pTxRing->Cell[TxIdx].pNdisPacket;
-
-			if (pPacket)
-			{
-				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-			}
-
-			// Always assign pNdisPacket as NULL after clear
-			pTxRing->Cell[TxIdx].pNdisPacket = NULL;
-
-			pPacket = pTxRing->Cell[TxIdx].pNextNdisPacket;
-
-			if (pPacket)
-			{
-				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-			}
-
-			// Always assign pNextNdisPacket as NULL after clear
-			pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
-
-#ifdef RT_BIG_ENDIAN
-			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-			WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
-#endif
-
-			if (ATESetUpFrame(pAd, TxIdx) != 0)
-				break;
-
-			INC_RING_INDEX(pTxRing->TxCpuIdx, TX_RING_SIZE);
-		}
-
-		ATESetUpFrame(pAd, pTxRing->TxCpuIdx);
-
-		// Start Tx, RX DMA.
-		RtmpDmaEnable(pAd, 1);
-
-		// Enable Tx
-		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
-		Value |= (1 << 2);
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-
-		// Disable Rx
-		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
-		Value &= ~(1 << 3);
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-
-#ifdef RALINK_28xx_QA
-		if (pAd->ate.bQATxStart == TRUE)
-		{
-			pAd->ate.TxStatus = 1;
-		}
-#endif // RALINK_28xx_QA //
-
-		// kick Tx-Ring.
-		RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QID_AC_BE * RINGREG_DIFF, pAd->TxRing[QID_AC_BE].TxCpuIdx);
-
-		RTMPusecDelay(500);
-
-		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
-		MacData |= 0x00000010;
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
-	}
-	else if (!strcmp(arg, "TXFRAME"))
-	{
-		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXFRAME(Count=%d)\n", pAd->ate.TxCount));
-		pAd->ate.Mode |= ATE_TXFRAME;
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
-
-		// Soft reset BBP.
-		BbpSoftReset(pAd);
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
-
-		// Abort Tx, RX DMA.
-		RtmpDmaEnable(pAd, 0);
-
-		// Fix can't smooth kick
-		{
-			RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QID_AC_BE * 0x10,  &pTxRing->TxDmaIdx);
-			pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx;
-			pTxRing->TxCpuIdx = pTxRing->TxDmaIdx;
-			RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QID_AC_BE * 0x10, pTxRing->TxCpuIdx);
-		}
-
-		pAd->ate.TxDoneCount = 0;
-
-		SetJapanFilter(pAd);
-
-		for (i = 0; (i < TX_RING_SIZE-1) && (i < pAd->ate.TxCount); i++)
-		{
-			PNDIS_PACKET pPacket;
-			UINT32 TxIdx = pTxRing->TxCpuIdx;
-
-#ifndef RT_BIG_ENDIAN
-			pTxD = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
-#else
-			pDestTxD = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
-			TxD = *pDestTxD;
-			pTxD = &TxD;
-			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-#endif
-			// Clean current cell.
-			pPacket = pTxRing->Cell[TxIdx].pNdisPacket;
-
-			if (pPacket)
-			{
-				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-			}
-
-			// Always assign pNdisPacket as NULL after clear
-			pTxRing->Cell[TxIdx].pNdisPacket = NULL;
-
-			pPacket = pTxRing->Cell[TxIdx].pNextNdisPacket;
-
-			if (pPacket)
-			{
-				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-			}
-
-			// Always assign pNextNdisPacket as NULL after clear
-			pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
-
-#ifdef RT_BIG_ENDIAN
-			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-			WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
-#endif
-
-			if (ATESetUpFrame(pAd, TxIdx) != 0)
-				break;
-
-			INC_RING_INDEX(pTxRing->TxCpuIdx, TX_RING_SIZE);
-
-		}
-
-		ATESetUpFrame(pAd, pTxRing->TxCpuIdx);
-
-		// Start Tx, Rx DMA.
-		RtmpDmaEnable(pAd, 1);
-
-		// Enable Tx
-		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
-		Value |= (1 << 2);
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-
-#ifdef RALINK_28xx_QA
-		// add this for LoopBack mode
-		if (pAd->ate.bQARxStart == FALSE)
-		{
-			// Disable Rx
-			RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
-			Value &= ~(1 << 3);
-			RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-		}
-
-		if (pAd->ate.bQATxStart == TRUE)
-		{
-			pAd->ate.TxStatus = 1;
-		}
-#else
-		// Disable Rx
-		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
-		Value &= ~(1 << 3);
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-#endif // RALINK_28xx_QA //
-
-		RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QID_AC_BE * RINGREG_DIFF, &pAd->TxRing[QID_AC_BE].TxDmaIdx);
-		// kick Tx-Ring.
-		RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QID_AC_BE * RINGREG_DIFF, pAd->TxRing[QID_AC_BE].TxCpuIdx);
-
-		pAd->RalinkCounters.KickTxCount++;
-	}
-#ifdef RALINK_28xx_QA
-	else if (!strcmp(arg, "TXSTOP"))
-	{
-		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXSTOP\n"));
-		atemode = pAd->ate.Mode;
-		pAd->ate.Mode &= ATE_TXSTOP;
-		pAd->ate.bQATxStart = FALSE;
-//		pAd->ate.TxDoneCount = pAd->ate.TxCount;
-
-		if (atemode == ATE_TXCARR)
-		{
-			// No Carrier Test set BBP R22 bit7=0, bit6=0, bit[5~0]=0x0
-			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
-			BbpData &= 0xFFFFFF00; //clear bit7, bit6, bit[5~0]
-		    ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
-		}
-		else if (atemode == ATE_TXCARRSUPP)
-		{
-			// No Cont. TX set BBP R22 bit7=0
-			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
-			BbpData &= ~(1 << 7); //set bit7=0
-			ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
-
-			// No Carrier Suppression set BBP R24 bit0=0
-			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R24, &BbpData);
-			BbpData &= 0xFFFFFFFE; //clear bit0
-		    ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, BbpData);
-		}
-
-		/*
-			We should free some resource which was allocated
-			when ATE_TXFRAME, ATE_STOP, and ATE_TXCONT.
-		*/
-		else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP))
-		{
-			PRTMP_TX_RING pTxRing = &pAd->TxRing[QID_AC_BE];
-
-			if (atemode == ATE_TXCONT)
-			{
-				// No Cont. TX set BBP R22 bit7=0
-				ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
-				BbpData &= ~(1 << 7); //set bit7=0
-				ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
-			}
-
-			// Abort Tx, Rx DMA.
-			RtmpDmaEnable(pAd, 0);
-
-			for (i=0; i<TX_RING_SIZE; i++)
-			{
-				PNDIS_PACKET  pPacket;
-
-#ifndef RT_BIG_ENDIAN
-			    pTxD = (PTXD_STRUC)pAd->TxRing[QID_AC_BE].Cell[i].AllocVa;
-#else
-			pDestTxD = (PTXD_STRUC)pAd->TxRing[QID_AC_BE].Cell[i].AllocVa;
-			TxD = *pDestTxD;
-			pTxD = &TxD;
-			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-#endif
-				pTxD->DMADONE = 0;
-				pPacket = pTxRing->Cell[i].pNdisPacket;
-
-				if (pPacket)
-				{
-					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
-					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-				}
-
-				// Always assign pNdisPacket as NULL after clear
-				pTxRing->Cell[i].pNdisPacket = NULL;
-
-				pPacket = pTxRing->Cell[i].pNextNdisPacket;
-
-				if (pPacket)
-				{
-					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
-					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-				}
-
-				// Always assign pNextNdisPacket as NULL after clear
-				pTxRing->Cell[i].pNextNdisPacket = NULL;
-#ifdef RT_BIG_ENDIAN
-				RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-				WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
-#endif
-			}
-			// Enable Tx, Rx DMA
-			RtmpDmaEnable(pAd, 1);
-
-		}
-
-		// TxStatus : 0 --> task is idle, 1 --> task is running
-		pAd->ate.TxStatus = 0;
-
-		// Soft reset BBP.
-		BbpSoftReset(pAd);
-
-		// Disable Tx
-		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
-		Value &= ~(1 << 2);
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-	}
-	else if (!strcmp(arg, "RXSTOP"))
-	{
-		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: RXSTOP\n"));
-		atemode = pAd->ate.Mode;
-		pAd->ate.Mode &= ATE_RXSTOP;
-		pAd->ate.bQARxStart = FALSE;
-//		pAd->ate.TxDoneCount = pAd->ate.TxCount;
-
-		if (atemode == ATE_TXCARR)
-		{
-			;
-		}
-		else if (atemode == ATE_TXCARRSUPP)
-		{
-			;
-		}
-
-		/*
-			We should free some resource which was allocated
-			when ATE_TXFRAME, ATE_STOP, and ATE_TXCONT.
-		*/
-		else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP))
-		{
-			if (atemode == ATE_TXCONT)
-			{
-				;
-			}
-		}
-
-		// Soft reset BBP.
-		BbpSoftReset(pAd);
-
-		// Disable Rx
-		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
-		Value &= ~(1 << 3);
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-	}
-#endif // RALINK_28xx_QA //
-	else if (!strcmp(arg, "RXFRAME"))
-	{
-		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: RXFRAME\n"));
-
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
-
-		pAd->ate.Mode |= ATE_RXFRAME;
-
-		// Disable Tx of MAC block.
-		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
-		Value &= ~(1 << 2);
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-
-		// Enable Rx of MAC block.
-		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
-		Value |= (1 << 3);
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-	}
-	else
-	{
-		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: Invalid arg!\n"));
-		return FALSE;
-	}
-	RTMPusecDelay(5000);
-
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("<=== ATECmdHandler()\n"));
-
-	return TRUE;
-}
-/*=======================End of RTMP_MAC_PCI =======================*/
-#endif // RTMP_MAC_PCI //
-
-
-
-
-INT	Set_ATE_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	if (ATECmdHandler(pAd, arg))
-	{
-		ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_Proc Success\n"));
-
-
-		return TRUE;
-	}
-	else
-	{
-		ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_Proc Failed\n"));
-		return FALSE;
-	}
-}
-
-
-/*
-==========================================================================
-    Description:
-        Set ATE ADDR1=DA for TxFrame(AP  : To DS = 0 ; From DS = 1)
-        or
-        Set ATE ADDR3=DA for TxFrame(STA : To DS = 1 ; From DS = 0)
-
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-==========================================================================
-*/
-INT	Set_ATE_DA_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	PSTRING				value;
-	INT					i;
-
-	// Mac address acceptable format 01:02:03:04:05:06 length 17
-	if (strlen(arg) != 17)
-		return FALSE;
-
-    for (i = 0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
-	{
-		/* sanity check */
-		if ((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))))
-		{
-			return FALSE;
-		}
-
-#ifdef CONFIG_STA_SUPPORT
-		AtoH(value, &pAd->ate.Addr3[i++], 1);
-#endif // CONFIG_STA_SUPPORT //
-	}
-
-	/* sanity check */
-	if (i != 6)
-	{
-		return FALSE;
-	}
-
-#ifdef CONFIG_STA_SUPPORT
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_DA_Proc (DA = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAd->ate.Addr3[0],
-		pAd->ate.Addr3[1], pAd->ate.Addr3[2], pAd->ate.Addr3[3], pAd->ate.Addr3[4], pAd->ate.Addr3[5]));
-#endif // CONFIG_STA_SUPPORT //
-
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_DA_Proc Success\n"));
-
-	return TRUE;
-}
-
-
-/*
-==========================================================================
-    Description:
-        Set ATE ADDR3=SA for TxFrame(AP  : To DS = 0 ; From DS = 1)
-        or
-        Set ATE ADDR2=SA for TxFrame(STA : To DS = 1 ; From DS = 0)
-
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-==========================================================================
-*/
-INT	Set_ATE_SA_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	PSTRING				value;
-	INT					i;
-
-	// Mac address acceptable format 01:02:03:04:05:06 length 17
-	if (strlen(arg) != 17)
-		return FALSE;
-
-    for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
-	{
-		/* sanity check */
-		if ((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))))
-		{
-			return FALSE;
-		}
-
-#ifdef CONFIG_STA_SUPPORT
-		AtoH(value, &pAd->ate.Addr2[i++], 1);
-#endif // CONFIG_STA_SUPPORT //
-	}
-
-	/* sanity check */
-	if (i != 6)
-	{
-		return FALSE;
-	}
-
-#ifdef CONFIG_STA_SUPPORT
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_SA_Proc (SA = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAd->ate.Addr2[0],
-		pAd->ate.Addr2[1], pAd->ate.Addr2[2], pAd->ate.Addr2[3], pAd->ate.Addr2[4], pAd->ate.Addr2[5]));
-#endif // CONFIG_STA_SUPPORT //
-
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_SA_Proc Success\n"));
-
-	return TRUE;
-}
-
-
-/*
-==========================================================================
-    Description:
-        Set ATE ADDR2=BSSID for TxFrame(AP  : To DS = 0 ; From DS = 1)
-        or
-        Set ATE ADDR1=BSSID for TxFrame(STA : To DS = 1 ; From DS = 0)
-
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-==========================================================================
-*/
-INT	Set_ATE_BSSID_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	PSTRING				value;
-	INT					i;
-
-	// Mac address acceptable format 01:02:03:04:05:06 length 17
-	if (strlen(arg) != 17)
-		return FALSE;
-
-    for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
-	{
-		/* sanity check */
-		if ((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))))
-		{
-			return FALSE;
-		}
-
-#ifdef CONFIG_STA_SUPPORT
-		AtoH(value, &pAd->ate.Addr1[i++], 1);
-#endif // CONFIG_STA_SUPPORT //
-	}
-
-	/* sanity check */
-	if(i != 6)
-	{
-		return FALSE;
-	}
-
-#ifdef CONFIG_STA_SUPPORT
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_BSSID_Proc (BSSID = %2X:%2X:%2X:%2X:%2X:%2X)\n",	pAd->ate.Addr1[0],
-		pAd->ate.Addr1[1], pAd->ate.Addr1[2], pAd->ate.Addr1[3], pAd->ate.Addr1[4], pAd->ate.Addr1[5]));
-#endif // CONFIG_STA_SUPPORT //
-
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_BSSID_Proc Success\n"));
-
-	return TRUE;
-}
-
-
-/*
-==========================================================================
-    Description:
-        Set ATE Tx Channel
-
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-==========================================================================
-*/
-INT	Set_ATE_CHANNEL_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	UCHAR channel;
-
-	channel = simple_strtol(arg, 0, 10);
-
-	// to allow A band channel : ((channel < 1) || (channel > 14))
-	if ((channel < 1) || (channel > 216))
-	{
-		ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_CHANNEL_Proc::Out of range, it should be in range of 1~14.\n"));
-		return FALSE;
-	}
-	pAd->ate.Channel = channel;
-
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_CHANNEL_Proc (ATE Channel = %d)\n", pAd->ate.Channel));
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_CHANNEL_Proc Success\n"));
-
-
-	return TRUE;
-}
-
-
-/*
-==========================================================================
-    Description:
-        Set ATE Tx Power0
-
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-==========================================================================
-*/
-INT	Set_ATE_TX_POWER0_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	CHAR TxPower;
-
-	TxPower = simple_strtol(arg, 0, 10);
-
-	if (pAd->ate.Channel <= 14)
-	{
-		if ((TxPower > 31) || (TxPower < 0))
-		{
-			ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER0_Proc::Out of range (Value=%d)\n", TxPower));
-			return FALSE;
-		}
-	}
-	else/* 5.5 GHz */
-	{
-		if ((TxPower > 15) || (TxPower < -7))
-		{
-			ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER0_Proc::Out of range (Value=%d)\n", TxPower));
-			return FALSE;
-		}
-	}
-
-	pAd->ate.TxPower0 = TxPower;
-	ATETxPwrHandler(pAd, 0);
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_POWER0_Proc Success\n"));
-
-
-	return TRUE;
-}
-
-
-/*
-==========================================================================
-    Description:
-        Set ATE Tx Power1
-
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-==========================================================================
-*/
-INT	Set_ATE_TX_POWER1_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	CHAR TxPower;
-
-	TxPower = simple_strtol(arg, 0, 10);
-
-	if (pAd->ate.Channel <= 14)
-	{
-		if ((TxPower > 31) || (TxPower < 0))
-		{
-			ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER1_Proc::Out of range (Value=%d)\n", TxPower));
-			return FALSE;
-		}
-	}
-	else
-	{
-		if ((TxPower > 15) || (TxPower < -7))
-		{
-			ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER1_Proc::Out of range (Value=%d)\n", TxPower));
-			return FALSE;
-		}
-	}
-
-	pAd->ate.TxPower1 = TxPower;
-	ATETxPwrHandler(pAd, 1);
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_POWER1_Proc Success\n"));
-
-
-	return TRUE;
-}
-
-
-/*
-==========================================================================
-    Description:
-        Set ATE Tx Antenna
-
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-==========================================================================
-*/
-INT	Set_ATE_TX_Antenna_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	CHAR value;
-
-	value = simple_strtol(arg, 0, 10);
-
-	if ((value > 2) || (value < 0))
-	{
-		ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_Antenna_Proc::Out of range (Value=%d)\n", value));
-		return FALSE;
-	}
-
-	pAd->ate.TxAntennaSel = value;
-
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_Antenna_Proc (Antenna = %d)\n", pAd->ate.TxAntennaSel));
-	ATEDBGPRINT(RT_DEBUG_TRACE,("Ralink: Set_ATE_TX_Antenna_Proc Success\n"));
-
-	// calibration power unbalance issues, merged from Arch Team
-	ATEAsicSwitchChannel(pAd);
-
-
-	return TRUE;
-}
-
-
-/*
-==========================================================================
-    Description:
-        Set ATE Rx Antenna
-
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-==========================================================================
-*/
-INT	Set_ATE_RX_Antenna_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	CHAR value;
-
-	value = simple_strtol(arg, 0, 10);
-
-	if ((value > 3) || (value < 0))
-	{
-		ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_RX_Antenna_Proc::Out of range (Value=%d)\n", value));
-		return FALSE;
-	}
-
-	pAd->ate.RxAntennaSel = value;
-
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_RX_Antenna_Proc (Antenna = %d)\n", pAd->ate.RxAntennaSel));
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_RX_Antenna_Proc Success\n"));
-
-	// calibration power unbalance issues, merged from Arch Team
-	ATEAsicSwitchChannel(pAd);
-
-
-	return TRUE;
-}
-
-
-/*
-==========================================================================
-    Description:
-        Set ATE RF frequence offset
-
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-==========================================================================
-*/
-INT	Set_ATE_TX_FREQOFFSET_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	UCHAR RFFreqOffset = 0;
-	ULONG R4 = 0;
-
-	RFFreqOffset = simple_strtol(arg, 0, 10);
-#ifndef RTMP_RF_RW_SUPPORT
-	if (RFFreqOffset >= 64)
-#endif // RTMP_RF_RW_SUPPORT //
-	/* RT35xx ATE will reuse this code segment. */
-#ifdef RTMP_RF_RW_SUPPORT
-//2008/08/06: KH modified the limit of offset value from 65 to 95(0x5F)
-	if (RFFreqOffset >= 95)
-#endif // RTMP_RF_RW_SUPPORT //
-	{
-		ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_FREQOFFSET_Proc::Out of range, it should be in range of 0~63.\n"));
-		return FALSE;
-	}
-
-	pAd->ate.RFFreqOffset = RFFreqOffset;
-#ifdef RTMP_RF_RW_SUPPORT
-	if (IS_RT30xx(pAd) || IS_RT3572(pAd))
-	{
-		// Set RF offset
-		UCHAR RFValue;
-		ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R23, (PUCHAR)&RFValue);
-//2008/08/06: KH modified "pAd->RFFreqOffset" to "pAd->ate.RFFreqOffset"
-		RFValue = ((RFValue & 0x80) | pAd->ate.RFFreqOffset);
-		ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R23, (UCHAR)RFValue);
-	}
-	else
-#endif // RTMP_RF_RW_SUPPORT //
-	{
-		// RT28xx
-		// shift TX power control to correct RF register bit position
-		R4 = pAd->ate.RFFreqOffset << 15;
-		R4 |= (pAd->LatchRfRegs.R4 & ((~0x001f8000)));
-		pAd->LatchRfRegs.R4 = R4;
-
-		RtmpRfIoWrite(pAd);
-	}
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_FREQOFFSET_Proc (RFFreqOffset = %d)\n", pAd->ate.RFFreqOffset));
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_FREQOFFSET_Proc Success\n"));
-
-
-	return TRUE;
-}
-
-
-/*
-==========================================================================
-    Description:
-        Set ATE RF BW
-
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-==========================================================================
-*/
-INT	Set_ATE_TX_BW_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	INT i;
-	UCHAR value = 0;
-	UCHAR BBPCurrentBW;
-
-	BBPCurrentBW = simple_strtol(arg, 0, 10);
-
-	if ((BBPCurrentBW == 0)
-#ifdef RT30xx
-		|| IS_RT2070(pAd)
-#endif // RT30xx //
-		)
-	{
-		pAd->ate.TxWI.BW = BW_20;
-	}
-	else
-	{
-		pAd->ate.TxWI.BW = BW_40;
-	}
-
-	/* RT35xx ATE will reuse this code segment. */
-	// Fix the error spectrum of CCK-40MHZ
-	// Turn on BBP 20MHz mode by request here.
-	if ((pAd->ate.TxWI.PHYMODE == MODE_CCK) && (pAd->ate.TxWI.BW == BW_40))
-	{
-		ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_BW_Proc!! Warning!! CCK only supports 20MHZ!!\nBandwidth switch to 20\n"));
-		pAd->ate.TxWI.BW = BW_20;
-	}
-
-	if (pAd->ate.TxWI.BW == BW_20)
-	{
-		if (pAd->ate.Channel <= 14)
-		{
-			for (i=0; i<5; i++)
-			{
-				if (pAd->Tx20MPwrCfgGBand[i] != 0xffffffff)
-				{
-					RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx20MPwrCfgGBand[i]);
-					RTMPusecDelay(5000);
-				}
-			}
-		}
-		else
-		{
-			for (i=0; i<5; i++)
-			{
-				if (pAd->Tx20MPwrCfgABand[i] != 0xffffffff)
-				{
-					RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx20MPwrCfgABand[i]);
-					RTMPusecDelay(5000);
-				}
-			}
-		}
-
-		// Set BBP R4 bit[4:3]=0:0
-		ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
-		value &= (~0x18);
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
-
-
-		// Set BBP R66=0x3C
-		value = 0x3C;
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, value);
-
-		// Set BBP R68=0x0B
-		// to improve Rx sensitivity.
-		value = 0x0B;
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R68, value);
-		// Set BBP R69=0x16
-		value = 0x16;
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value);
-		// Set BBP R70=0x08
-		value = 0x08;
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value);
-		// Set BBP R73=0x11
-		value = 0x11;
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value);
-
-	    /*
-			If Channel=14, Bandwidth=20M and Mode=CCK, Set BBP R4 bit5=1
-			(to set Japan filter coefficients).
-			This segment of code will only works when ATETXMODE and ATECHANNEL
-			were set to MODE_CCK and 14 respectively before ATETXBW is set to 0.
-	    */
-		if (pAd->ate.Channel == 14)
-		{
-			INT TxMode = pAd->ate.TxWI.PHYMODE;
-
-			if (TxMode == MODE_CCK)
-			{
-				// when Channel==14 && Mode==CCK && BandWidth==20M, BBP R4 bit5=1
-				ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
-				value |= 0x20; //set bit5=1
-				ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
-			}
-		}
-
-#ifdef RT30xx
-		// set BW = 20 MHz
-		if (IS_RT30xx(pAd))
-			ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R24, (UCHAR) pAd->Mlme.CaliBW20RfR24);
-		else
-#endif // RT30xx //
-		// set BW = 20 MHz
-		{
-			pAd->LatchRfRegs.R4 &= ~0x00200000;
-			RtmpRfIoWrite(pAd);
-		}
-
-	}
-	// If bandwidth = 40M, set RF Reg4 bit 21 = 0.
-	else if (pAd->ate.TxWI.BW == BW_40)
-	{
-		if (pAd->ate.Channel <= 14)
-		{
-			for (i=0; i<5; i++)
-			{
-				if (pAd->Tx40MPwrCfgGBand[i] != 0xffffffff)
-				{
-					RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx40MPwrCfgGBand[i]);
-					RTMPusecDelay(5000);
-				}
-			}
-		}
-		else
-		{
-			for (i=0; i<5; i++)
-			{
-				if (pAd->Tx40MPwrCfgABand[i] != 0xffffffff)
-				{
-					RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx40MPwrCfgABand[i]);
-					RTMPusecDelay(5000);
-				}
-			}
-#ifdef DOT11_N_SUPPORT
-			if ((pAd->ate.TxWI.PHYMODE >= MODE_HTMIX) && (pAd->ate.TxWI.MCS == 7))
-			{
-			value = 0x28;
-			ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R67, value);
-			}
-#endif // DOT11_N_SUPPORT //
-		}
-
-		// Set BBP R4 bit[4:3]=1:0
-		ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
-		value &= (~0x18);
-		value |= 0x10;
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
-
-
-		// Set BBP R66=0x3C
-		value = 0x3C;
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, value);
-
-		// Set BBP R68=0x0C
-		// to improve Rx sensitivity
-		value = 0x0C;
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R68, value);
-		// Set BBP R69=0x1A
-		value = 0x1A;
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value);
-		// Set BBP R70=0x0A
-		value = 0x0A;
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value);
-		// Set BBP R73=0x16
-		value = 0x16;
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value);
-
-		// If bandwidth = 40M, set RF Reg4 bit 21 = 1.
-#ifdef RT30xx
-		// set BW = 40 MHz
-		if(IS_RT30xx(pAd))
-			ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R24, (UCHAR) pAd->Mlme.CaliBW40RfR24);
-		else
-#endif // RT30xx //
-		// set BW = 40 MHz
-		{
-		pAd->LatchRfRegs.R4 |= 0x00200000;
-		RtmpRfIoWrite(pAd);
-		}
-	}
-
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_BW_Proc (BBPCurrentBW = %d)\n", pAd->ate.TxWI.BW));
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_BW_Proc Success\n"));
-
-
-	return TRUE;
-}
-
-
-/*
-==========================================================================
-    Description:
-        Set ATE Tx frame length
-
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-==========================================================================
-*/
-INT	Set_ATE_TX_LENGTH_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	pAd->ate.TxLength = simple_strtol(arg, 0, 10);
-
-	if ((pAd->ate.TxLength < 24) || (pAd->ate.TxLength > (MAX_FRAME_SIZE - 34/* == 2312 */)))
-	{
-		pAd->ate.TxLength = (MAX_FRAME_SIZE - 34/* == 2312 */);
-		ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_LENGTH_Proc::Out of range, it should be in range of 24~%d.\n", (MAX_FRAME_SIZE - 34/* == 2312 */)));
-		return FALSE;
-	}
-
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_LENGTH_Proc (TxLength = %d)\n", pAd->ate.TxLength));
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_LENGTH_Proc Success\n"));
-
-
-	return TRUE;
-}
-
-
-/*
-==========================================================================
-    Description:
-        Set ATE Tx frame count
-
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-==========================================================================
-*/
-INT	Set_ATE_TX_COUNT_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	pAd->ate.TxCount = simple_strtol(arg, 0, 10);
-
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_COUNT_Proc (TxCount = %d)\n", pAd->ate.TxCount));
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_COUNT_Proc Success\n"));
-
-
-	return TRUE;
-}
-
-
-/*
-==========================================================================
-    Description:
-        Set ATE Tx frame MCS
-
-        Return:
-		TRUE if all parameters are OK, FALSE otherwise
-==========================================================================
-*/
-INT	Set_ATE_TX_MCS_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	UCHAR MCS;
-	INT result;
-
-	MCS = simple_strtol(arg, 0, 10);
-#ifndef RT30xx
-	result = CheckMCSValid(pAd->ate.TxWI.PHYMODE, MCS);
-#endif // RT30xx //
-
-	/* RT35xx ATE will reuse this code segment. */
-#ifdef RT30xx
-	result = CheckMCSValid(pAd->ate.TxWI.PHYMODE, MCS, IS_RT2070(pAd));
-#endif // RT30xx //
-
-
-	if (result != -1)
-	{
-		pAd->ate.TxWI.MCS = (UCHAR)MCS;
-	}
-	else
-	{
-		ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_MCS_Proc::Out of range, refer to rate table.\n"));
-		return FALSE;
-	}
-
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_MCS_Proc (MCS = %d)\n", pAd->ate.TxWI.MCS));
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_MCS_Proc Success\n"));
-
-
-	return TRUE;
-}
-
-
-/*
-==========================================================================
-    Description:
-        Set ATE Tx frame Mode
-        0: MODE_CCK
-        1: MODE_OFDM
-        2: MODE_HTMIX
-        3: MODE_HTGREENFIELD
-
-        Return:
-		TRUE if all parameters are OK, FALSE otherwise
-==========================================================================
-*/
-INT	Set_ATE_TX_MODE_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	UCHAR BbpData = 0;
-
-	pAd->ate.TxWI.PHYMODE = simple_strtol(arg, 0, 10);
-
-	if (pAd->ate.TxWI.PHYMODE > 3)
-	{
-		pAd->ate.TxWI.PHYMODE = 0;
-		ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_MODE_Proc::Out of range.\nIt should be in range of 0~3\n"));
-		ATEDBGPRINT(RT_DEBUG_ERROR, ("0: CCK, 1: OFDM, 2: HT_MIX, 3: HT_GREEN_FIELD.\n"));
-		return FALSE;
-	}
-
-	// Turn on BBP 20MHz mode by request here.
-	if (pAd->ate.TxWI.PHYMODE == MODE_CCK)
-	{
-		ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BbpData);
-		BbpData &= (~0x18);
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BbpData);
-		pAd->ate.TxWI.BW = BW_20;
-		ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_MODE_Proc::CCK Only support 20MHZ. Switch to 20MHZ.\n"));
-	}
-
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_MODE_Proc (TxMode = %d)\n", pAd->ate.TxWI.PHYMODE));
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_MODE_Proc Success\n"));
-
-
-	return TRUE;
-}
-
-
-/*
-==========================================================================
-    Description:
-        Set ATE Tx frame GI
-
-        Return:
-		TRUE if all parameters are OK, FALSE otherwise
-==========================================================================
-*/
-INT	Set_ATE_TX_GI_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	pAd->ate.TxWI.ShortGI = simple_strtol(arg, 0, 10);
-
-	if (pAd->ate.TxWI.ShortGI > 1)
-	{
-		pAd->ate.TxWI.ShortGI = 0;
-		ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_GI_Proc::Out of range\n"));
-		return FALSE;
-	}
-
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_GI_Proc (GI = %d)\n", pAd->ate.TxWI.ShortGI));
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_GI_Proc Success\n"));
-
-
-	return TRUE;
-}
-
-
-INT	Set_ATE_RX_FER_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	pAd->ate.bRxFER = simple_strtol(arg, 0, 10);
-
-	if (pAd->ate.bRxFER == 1)
-	{
-		pAd->ate.RxCntPerSec = 0;
-		pAd->ate.RxTotalCnt = 0;
-	}
-
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_RX_FER_Proc (bRxFER = %d)\n", pAd->ate.bRxFER));
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_RX_FER_Proc Success\n"));
-
-
-	return TRUE;
-}
-
-
-INT Set_ATE_Read_RF_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-#ifdef RTMP_RF_RW_SUPPORT
-//2008/07/10:KH add to support RT30xx ATE<--
-	if (IS_RT30xx(pAd) || IS_RT3572(pAd))
-	{
-		/* modify by WY for Read RF Reg. error */
-		UCHAR RFValue;
-		INT index=0;
-
-		for (index = 0; index < 32; index++)
-		{
-			ATE_RF_IO_READ8_BY_REG_ID(pAd, index, (PUCHAR)&RFValue);
-			ate_print("R%d=%d\n",index,RFValue);
-		}
-	}
-	else
-//2008/07/10:KH add to support RT30xx ATE-->
-#endif // RTMP_RF_RW_SUPPORT //
-	{
-		ate_print(KERN_EMERG "R1 = %lx\n", pAd->LatchRfRegs.R1);
-		ate_print(KERN_EMERG "R2 = %lx\n", pAd->LatchRfRegs.R2);
-		ate_print(KERN_EMERG "R3 = %lx\n", pAd->LatchRfRegs.R3);
-		ate_print(KERN_EMERG "R4 = %lx\n", pAd->LatchRfRegs.R4);
-	}
-	return TRUE;
-}
-
-
-INT Set_ATE_Write_RF1_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	UINT32 value = (UINT32) simple_strtol(arg, 0, 16);
-
-#ifdef RTMP_RF_RW_SUPPORT
-//2008/07/10:KH add to support 3070 ATE<--
-	if (IS_RT30xx(pAd) || IS_RT3572(pAd))
-	{
-		ate_print("Warning!! RT3xxx Don't Support !\n");
-		return FALSE;
-
-	}
-	else
-//2008/07/10:KH add to support 3070 ATE-->
-#endif // RTMP_RF_RW_SUPPORT //
-	{
-		pAd->LatchRfRegs.R1 = value;
-		RtmpRfIoWrite(pAd);
-	}
-	return TRUE;
-}
-
-
-INT Set_ATE_Write_RF2_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	UINT32 value = (UINT32) simple_strtol(arg, 0, 16);
-
-#ifdef RTMP_RF_RW_SUPPORT
-//2008/07/10:KH add to support 3070 ATE<--
-	if (IS_RT30xx(pAd) || IS_RT3572(pAd))
-	{
-		ate_print("Warning!! RT3xxx Don't Support !\n");
-		return FALSE;
-
-	}
-	else
-//2008/07/10:KH add to support 3070 ATE-->
-#endif // RTMP_RF_RW_SUPPORT //
-	{
-		pAd->LatchRfRegs.R2 = value;
-		RtmpRfIoWrite(pAd);
-	}
-	return TRUE;
-}
-
-
-INT Set_ATE_Write_RF3_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	UINT32 value = simple_strtol(arg, 0, 16);
-
-#ifdef RTMP_RF_RW_SUPPORT
-//2008/07/10:KH add to support 3070 ATE<--
-	if (IS_RT30xx(pAd) || IS_RT3572(pAd))
-	{
-		ate_print("Warning!! RT3xxx Don't Support !\n");
-		return FALSE;
-
-	}
-	else
-//2008/07/10:KH add to support 3070 ATE-->
-#endif // RTMP_RF_RW_SUPPORT //
-	{
-		pAd->LatchRfRegs.R3 = value;
-		RtmpRfIoWrite(pAd);
-	}
-	return TRUE;
-}
-
-
-INT Set_ATE_Write_RF4_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	UINT32 value = (UINT32) simple_strtol(arg, 0, 16);
-
-#ifdef RTMP_RF_RW_SUPPORT
-//2008/07/10:KH add to support 3070 ATE<--
-	if (IS_RT30xx(pAd) || IS_RT3572(pAd))
-	{
-		ate_print("Warning!! RT3xxx Don't Support !\n");
-		return FALSE;
-
-	}
-	else
-//2008/07/10:KH add to support 3070 ATE-->
-#endif // RTMP_RF_RW_SUPPORT //
-	{
-		pAd->LatchRfRegs.R4 = value;
-		RtmpRfIoWrite(pAd);
-	}
-	return TRUE;
-}
-
-
-/*
-==========================================================================
-    Description:
-        Load and Write EEPROM from a binary file prepared in advance.
-
-        Return:
-		TRUE if all parameters are OK, FALSE otherwise
-==========================================================================
-*/
-#if defined(LINUX) || defined(VXWORKS)
-INT Set_ATE_Load_E2P_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	BOOLEAN			ret = FALSE;
-	PSTRING			src = EEPROM_BIN_FILE_NAME;
-	RTMP_OS_FD		srcf;
-	INT32			retval;
-	USHORT			WriteEEPROM[(EEPROM_SIZE/2)];
-	INT				FileLength = 0;
-	UINT32			value = (UINT32) simple_strtol(arg, 0, 10);
-	RTMP_OS_FS_INFO	osFSInfo;
-
-	ATEDBGPRINT(RT_DEBUG_ERROR, ("===> %s (value=%d)\n\n", __FUNCTION__, value));
-
-	if (value > 0)
-	{
-		/* zero the e2p buffer */
-		NdisZeroMemory((PUCHAR)WriteEEPROM, EEPROM_SIZE);
-
-		RtmpOSFSInfoChange(&osFSInfo, TRUE);
-
-		do
-		{
-			/* open the bin file */
-			srcf = RtmpOSFileOpen(src, O_RDONLY, 0);
-
-			if (IS_FILE_OPEN_ERR(srcf))
-			{
-				ate_print("%s - Error opening file %s\n", __FUNCTION__, src);
-				break;
-			}
-
-			/* read the firmware from the file *.bin */
-			FileLength = RtmpOSFileRead(srcf, (PSTRING)WriteEEPROM, EEPROM_SIZE);
-
-			if (FileLength != EEPROM_SIZE)
-			{
-				ate_print("%s: error file length (=%d) in e2p.bin\n",
-					   __FUNCTION__, FileLength);
-				break;
-			}
-			else
-			{
-				/* write the content of .bin file to EEPROM */
-				rt_ee_write_all(pAd, WriteEEPROM);
-				ret = TRUE;
-			}
-			break;
-		} while(TRUE);
-
-		/* close firmware file */
-		if (IS_FILE_OPEN_ERR(srcf))
-		{
-				;
-		}
-		else
-		{
-			retval = RtmpOSFileClose(srcf);
-
-			if (retval)
-			{
-				ATEDBGPRINT(RT_DEBUG_ERROR, ("--> Error %d closing %s\n", -retval, src));
-
-			}
-		}
-
-		/* restore */
-		RtmpOSFSInfoChange(&osFSInfo, FALSE);
-	}
-
-    ATEDBGPRINT(RT_DEBUG_ERROR, ("<=== %s (ret=%d)\n", __FUNCTION__, ret));
-
-    return ret;
-
-}
-#endif // defined(LINUX) || defined(VXWORKS) //
-
-
-
-
-INT Set_ATE_Read_E2P_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	USHORT buffer[EEPROM_SIZE/2];
-	USHORT *p;
-	int i;
-
-	rt_ee_read_all(pAd, (USHORT *)buffer);
-	p = buffer;
-	for (i = 0; i < (EEPROM_SIZE/2); i++)
-	{
-		ate_print("%4.4x ", *p);
-		if (((i+1) % 16) == 0)
-			ate_print("\n");
-		p++;
-	}
-	return TRUE;
-}
-
-
-
-
-INT	Set_ATE_Show_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	ate_print("Mode=%d\n", pAd->ate.Mode);
-	ate_print("TxPower0=%d\n", pAd->ate.TxPower0);
-	ate_print("TxPower1=%d\n", pAd->ate.TxPower1);
-	ate_print("TxAntennaSel=%d\n", pAd->ate.TxAntennaSel);
-	ate_print("RxAntennaSel=%d\n", pAd->ate.RxAntennaSel);
-	ate_print("BBPCurrentBW=%d\n", pAd->ate.TxWI.BW);
-	ate_print("GI=%d\n", pAd->ate.TxWI.ShortGI);
-	ate_print("MCS=%d\n", pAd->ate.TxWI.MCS);
-	ate_print("TxMode=%d\n", pAd->ate.TxWI.PHYMODE);
-	ate_print("Addr1=%02x:%02x:%02x:%02x:%02x:%02x\n",
-		pAd->ate.Addr1[0], pAd->ate.Addr1[1], pAd->ate.Addr1[2], pAd->ate.Addr1[3], pAd->ate.Addr1[4], pAd->ate.Addr1[5]);
-	ate_print("Addr2=%02x:%02x:%02x:%02x:%02x:%02x\n",
-		pAd->ate.Addr2[0], pAd->ate.Addr2[1], pAd->ate.Addr2[2], pAd->ate.Addr2[3], pAd->ate.Addr2[4], pAd->ate.Addr2[5]);
-	ate_print("Addr3=%02x:%02x:%02x:%02x:%02x:%02x\n",
-		pAd->ate.Addr3[0], pAd->ate.Addr3[1], pAd->ate.Addr3[2], pAd->ate.Addr3[3], pAd->ate.Addr3[4], pAd->ate.Addr3[5]);
-	ate_print("Channel=%d\n", pAd->ate.Channel);
-	ate_print("TxLength=%d\n", pAd->ate.TxLength);
-	ate_print("TxCount=%u\n", pAd->ate.TxCount);
-	ate_print("RFFreqOffset=%d\n", pAd->ate.RFFreqOffset);
-	ate_print(KERN_EMERG "Set_ATE_Show_Proc Success\n");
-	return TRUE;
-}
-
-
-INT	Set_ATE_Help_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	ate_print("ATE=ATESTART, ATESTOP, TXCONT, TXCARR, TXFRAME, RXFRAME\n");
-	ate_print("ATEDA\n");
-	ate_print("ATESA\n");
-	ate_print("ATEBSSID\n");
-	ate_print("ATECHANNEL, range:0~14(unless A band !)\n");
-	ate_print("ATETXPOW0, set power level of antenna 1.\n");
-	ate_print("ATETXPOW1, set power level of antenna 2.\n");
-	ate_print("ATETXANT, set TX antenna. 0:all, 1:antenna one, 2:antenna two.\n");
-	ate_print("ATERXANT, set RX antenna.0:all, 1:antenna one, 2:antenna two, 3:antenna three.\n");
-	ate_print("ATETXFREQOFFSET, set frequency offset, range 0~63\n");
-	ate_print("ATETXBW, set BandWidth, 0:20MHz, 1:40MHz.\n");
-	ate_print("ATETXLEN, set Frame length, range 24~%d\n", (MAX_FRAME_SIZE - 34/* == 2312 */));
-	ate_print("ATETXCNT, set how many frame going to transmit.\n");
-	ate_print("ATETXMCS, set MCS, reference to rate table.\n");
-	ate_print("ATETXMODE, set Mode 0:CCK, 1:OFDM, 2:HT-Mix, 3:GreenField, reference to rate table.\n");
-	ate_print("ATETXGI, set GI interval, 0:Long, 1:Short\n");
-	ate_print("ATERXFER, 0:disable Rx Frame error rate. 1:enable Rx Frame error rate.\n");
-	ate_print("ATERRF, show all RF registers.\n");
-	ate_print("ATEWRF1, set RF1 register.\n");
-	ate_print("ATEWRF2, set RF2 register.\n");
-	ate_print("ATEWRF3, set RF3 register.\n");
-	ate_print("ATEWRF4, set RF4 register.\n");
-	ate_print("ATELDE2P, load EEPROM from .bin file.\n");
-	ate_print("ATERE2P, display all EEPROM content.\n");
-	ate_print("ATESHOW, display all parameters of ATE.\n");
-	ate_print("ATEHELP, online help.\n");
-
-	return TRUE;
-}
-
-
-
-
-/*
-==========================================================================
-    Description:
-
-	AsicSwitchChannel() dedicated for ATE.
-
-==========================================================================
-*/
-VOID ATEAsicSwitchChannel(
-    IN PRTMP_ADAPTER pAd)
-{
-	UINT32 R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0, Value = 0;
-	CHAR TxPwer = 0, TxPwer2 = 0;
-	UCHAR index = 0, BbpValue = 0, R66 = 0x30;
-	RTMP_RF_REGS *RFRegTable;
-	UCHAR Channel = 0;
-
-	RFRegTable = NULL;
-
-#ifdef RALINK_28xx_QA
-	// for QA mode, TX power values are passed from UI
-	if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))
-	{
-		if (pAd->ate.Channel != pAd->LatchRfRegs.Channel)
-		{
-			pAd->ate.Channel = pAd->LatchRfRegs.Channel;
-		}
-		return;
-	}
-	else
-#endif // RALINK_28xx_QA //
-	Channel = pAd->ate.Channel;
-
-	// select antenna for RT3090
-	AsicAntennaSelect(pAd, Channel);
-
-	// fill Tx power value
-	TxPwer = pAd->ate.TxPower0;
-	TxPwer2 = pAd->ate.TxPower1;
-#ifdef RT30xx
-//2008/07/10:KH add to support 3070 ATE<--
-
-	/*
-		The RF programming sequence is difference between 3xxx and 2xxx.
-		The 3070 is 1T1R. Therefore, we don't need to set the number of Tx/Rx path
-		and the only job is to set the parameters of channels.
-	*/
-	if (IS_RT30xx(pAd) && ((pAd->RfIcType == RFIC_3020) ||
-			(pAd->RfIcType == RFIC_3021) || (pAd->RfIcType == RFIC_3022) ||
-			(pAd->RfIcType == RFIC_2020)))
-	{
-		/* modify by WY for Read RF Reg. error */
-		UCHAR RFValue = 0;
-
-		for (index = 0; index < NUM_OF_3020_CHNL; index++)
-		{
-			if (Channel == FreqItems3020[index].Channel)
-			{
-				// Programming channel parameters.
-				ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R02, FreqItems3020[index].N);
-				ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R03, FreqItems3020[index].K);
-
-				ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R06, (PUCHAR)&RFValue);
-				RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
-				ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R06, (UCHAR)RFValue);
-
-				// Set Tx Power.
-				ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R12, (PUCHAR)&RFValue);
-				RFValue = (RFValue & 0xE0) | TxPwer;
-				ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R12, (UCHAR)RFValue);
-
-				// Set RF offset.
-				ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R23, (PUCHAR)&RFValue);
-				//2008/08/06: KH modified "pAd->RFFreqOffset" to "pAd->ate.RFFreqOffset"
-				RFValue = (RFValue & 0x80) | pAd->ate.RFFreqOffset;
-				ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R23, (UCHAR)RFValue);
-
-				// Set BW.
-				if (pAd->ate.TxWI.BW == BW_40)
-				{
-					RFValue = pAd->Mlme.CaliBW40RfR24;
-//					DISABLE_11N_CHECK(pAd);
-				}
-				else
-				{
-					RFValue = pAd->Mlme.CaliBW20RfR24;
-				}
-				ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R24, (UCHAR)RFValue);
-
-				// Enable RF tuning
-				ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R07, (PUCHAR)&RFValue);
-				RFValue = RFValue | 0x1;
-				ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R07, (UCHAR)RFValue);
-
-				// latch channel for future usage
-				pAd->LatchRfRegs.Channel = Channel;
-
-				break;
-			}
-		}
-
-		ATEDBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
-			Channel,
-			pAd->RfIcType,
-			TxPwer,
-			TxPwer2,
-			pAd->Antenna.field.TxPath,
-			FreqItems3020[index].N,
-			FreqItems3020[index].K,
-			FreqItems3020[index].R));
-	}
-	else
-//2008/07/10:KH add to support 3070 ATE-->
-#endif // RT30xx //
-	{
-		/* RT28xx */
-		RFRegTable = RF2850RegTable;
-
-		switch (pAd->RfIcType)
-		{
-			/* But only 2850 and 2750 support 5.5GHz band... */
-			case RFIC_2820:
-			case RFIC_2850:
-			case RFIC_2720:
-			case RFIC_2750:
-
-				for (index = 0; index < NUM_OF_2850_CHNL; index++)
-				{
-					if (Channel == RFRegTable[index].Channel)
-					{
-						R2 = RFRegTable[index].R2;
-
-						// If TX path is 1, bit 14 = 1;
-						if (pAd->Antenna.field.TxPath == 1)
-						{
-							R2 |= 0x4000;
-						}
-
-						if (pAd->Antenna.field.RxPath == 2)
-						{
-							switch (pAd->ate.RxAntennaSel)
-							{
-								case 1:
-									R2 |= 0x20040;
-									ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
-									BbpValue &= 0xE4;
-									BbpValue |= 0x00;
-									ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
-									break;
-								case 2:
-									R2 |= 0x10040;
-									ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
-									BbpValue &= 0xE4;
-									BbpValue |= 0x01;
-									ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
-									break;
-								default:
-									R2 |= 0x40;
-									ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
-									BbpValue &= 0xE4;
-									/* Only enable two Antenna to receive. */
-									BbpValue |= 0x08;
-									ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
-									break;
-							}
-						}
-						else if (pAd->Antenna.field.RxPath == 1)
-						{
-							// write 1 to off RxPath
-							R2 |= 0x20040;
-						}
-
-						if (pAd->Antenna.field.TxPath == 2)
-						{
-							if (pAd->ate.TxAntennaSel == 1)
-							{
-								// If TX Antenna select is 1 , bit 14 = 1; Disable Ant 2
-								R2 |= 0x4000;
-								ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
-								BbpValue &= 0xE7;		// 11100111B
-								ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
-							}
-							else if (pAd->ate.TxAntennaSel == 2)
-							{
-								// If TX Antenna select is 2 , bit 15 = 1; Disable Ant 1
-								R2 |= 0x8000;
-								ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
-								BbpValue &= 0xE7;
-								BbpValue |= 0x08;
-								ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
-							}
-							else
-							{
-								ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
-								BbpValue &= 0xE7;
-								BbpValue |= 0x10;
-								ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
-							}
-						}
-						if (pAd->Antenna.field.RxPath == 3)
-						{
-							switch (pAd->ate.RxAntennaSel)
-							{
-								case 1:
-									R2 |= 0x20040;
-									ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
-									BbpValue &= 0xE4;
-									BbpValue |= 0x00;
-									ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
-									break;
-								case 2:
-									R2 |= 0x10040;
-									ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
-									BbpValue &= 0xE4;
-									BbpValue |= 0x01;
-									ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
-									break;
-								case 3:
-									R2 |= 0x30000;
-									ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
-									BbpValue &= 0xE4;
-									BbpValue |= 0x02;
-									ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
-									break;
-								default:
-									ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
-									BbpValue &= 0xE4;
-									BbpValue |= 0x10;
-									ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
-									break;
-							}
-						}
-
-						if (Channel > 14)
-						{
-							// initialize R3, R4
-							R3 = (RFRegTable[index].R3 & 0xffffc1ff);
-							R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->ate.RFFreqOffset << 15);
-
-		                    /*
-			                    According the Rory's suggestion to solve the middle range issue.
-
-								5.5G band power range : 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0"
-														means the TX power reduce 7dB.
-							*/
-							// R3
-							if ((TxPwer >= -7) && (TxPwer < 0))
-							{
-								TxPwer = (7+TxPwer);
-								TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
-								R3 |= (TxPwer << 10);
-								ATEDBGPRINT(RT_DEBUG_TRACE, ("ATEAsicSwitchChannel: TxPwer=%d \n", TxPwer));
-							}
-							else
-							{
-								TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
-								R3 |= (TxPwer << 10) | (1 << 9);
-							}
-
-							// R4
-							if ((TxPwer2 >= -7) && (TxPwer2 < 0))
-							{
-								TxPwer2 = (7+TxPwer2);
-								TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
-								R4 |= (TxPwer2 << 7);
-								ATEDBGPRINT(RT_DEBUG_TRACE, ("ATEAsicSwitchChannel: TxPwer2=%d \n", TxPwer2));
-							}
-							else
-							{
-								TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
-								R4 |= (TxPwer2 << 7) | (1 << 6);
-							}
-						}
-						else
-						{
-							// Set TX power0.
-							R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9);
-							// Set frequency offset and TX power1.
-							R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->ate.RFFreqOffset << 15) | (TxPwer2 <<6);
-						}
-
-						// based on BBP current mode before changing RF channel
-						if (pAd->ate.TxWI.BW == BW_40)
-						{
-							R4 |=0x200000;
-						}
-
-						// Update variables.
-						pAd->LatchRfRegs.Channel = Channel;
-						pAd->LatchRfRegs.R1 = RFRegTable[index].R1;
-						pAd->LatchRfRegs.R2 = R2;
-						pAd->LatchRfRegs.R3 = R3;
-						pAd->LatchRfRegs.R4 = R4;
-
-						RtmpRfIoWrite(pAd);
-
-						break;
-					}
-				}
-				break;
-
-			default:
-				break;
-		}
-	}
-
-	// Change BBP setting during switch from a->g, g->a
-	if (Channel <= 14)
-	{
-	    UINT32 TxPinCfg = 0x00050F0A;// 2007.10.09 by Brian : 0x0005050A ==> 0x00050F0A
-
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
-
-		/* For 1T/2R chip only... */
-	    if (pAd->NicConfig2.field.ExternalLNAForG)
-	    {
-	        ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
-	    }
-	    else
-	    {
-	        ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
-	    }
-
-        // According the Rory's suggestion to solve the middle range issue.
-		ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R86, &BbpValue);// may be removed for RT35xx ++
-
-		ASSERT((BbpValue == 0x00));
-		if ((BbpValue != 0x00))
-		{
-			ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x00);
-		}// may be removed for RT35xx --
-
-		// 5.5 GHz band selection PIN, bit1 and bit2 are complement
-		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
-		Value &= (~0x6);
-		Value |= (0x04);
-		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
-
-        // Turn off unused PA or LNA when only 1T or 1R.
-		if (pAd->Antenna.field.TxPath == 1)
-		{
-			TxPinCfg &= 0xFFFFFFF3;
-		}
-		if (pAd->Antenna.field.RxPath == 1)
-		{
-			TxPinCfg &= 0xFFFFF3FF;
-		}
-
-		// calibration power unbalance issues
-		if (pAd->Antenna.field.TxPath == 2)
-		{
-			if (pAd->ate.TxAntennaSel == 1)
-			{
-				TxPinCfg &= 0xFFFFFFF7;
-			}
-			else if (pAd->ate.TxAntennaSel == 2)
-			{
-				TxPinCfg &= 0xFFFFFFFD;
-			}
-		}
-
-		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
-	}
-	else
-	{
-	    UINT32	TxPinCfg = 0x00050F05;// 2007.10.09 by Brian : 0x00050505 ==> 0x00050F05
-
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
-
-        // According the Rory's suggestion to solve the middle range issue.
-		ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R86, &BbpValue);// may be removed for RT35xx ++
-
-		ASSERT((BbpValue == 0x00));
-		if ((BbpValue != 0x00))
-		{
-			ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x00);
-		}
-
-		ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R91, &BbpValue);
-		ASSERT((BbpValue == 0x04));
-
-		ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R92, &BbpValue);
-		ASSERT((BbpValue == 0x00));// may be removed for RT35xx --
-
-		// 5.5 GHz band selection PIN, bit1 and bit2 are complement
-		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
-		Value &= (~0x6);
-		Value |= (0x02);
-		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
-
-		// Turn off unused PA or LNA when only 1T or 1R.
-		if (pAd->Antenna.field.TxPath == 1)
-		{
-			TxPinCfg &= 0xFFFFFFF3;
-		}
-		if (pAd->Antenna.field.RxPath == 1)
-		{
-			TxPinCfg &= 0xFFFFF3FF;
-		}
-
-		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
-	}
-
-
-    // R66 should be set according to Channel and use 20MHz when scanning
-	if (Channel <= 14)
-	{
-		// BG band
-		R66 = 0x2E + GET_LNA_GAIN(pAd);
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-	}
-	else
-	{
-		// 5.5 GHz band
-		if (pAd->ate.TxWI.BW == BW_20)
-		{
-			R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3);
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-		}
-		else
-		{
-			R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3);
-			ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-		}
-	}
-
-	/*
-		On 11A, We should delay and wait RF/BBP to be stable
-		and the appropriate time should be 1000 micro seconds.
-
-		2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
-	*/
-	RTMPusecDelay(1000);
-
-#ifndef RTMP_RF_RW_SUPPORT
-	if (Channel > 14)
-	{
-		// When 5.5GHz band the LSB of TxPwr will be used to reduced 7dB or not.
-		ATEDBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
-								  Channel,
-								  pAd->RfIcType,
-								  pAd->Antenna.field.TxPath,
-								  pAd->LatchRfRegs.R1,
-								  pAd->LatchRfRegs.R2,
-								  pAd->LatchRfRegs.R3,
-								  pAd->LatchRfRegs.R4));
-	}
-	else
-	{
-		ATEDBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%u, Pwr1=%u, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
-								  Channel,
-								  pAd->RfIcType,
-								  (R3 & 0x00003e00) >> 9,
-								  (R4 & 0x000007c0) >> 6,
-								  pAd->Antenna.field.TxPath,
-								  pAd->LatchRfRegs.R1,
-								  pAd->LatchRfRegs.R2,
-								  pAd->LatchRfRegs.R3,
-								  pAd->LatchRfRegs.R4));
-    }
-#endif // RTMP_RF_RW_SUPPORT //
-}
-
-
-
-/* In fact, no one will call this routine so far ! */
-
-/*
-==========================================================================
-	Description:
-		Gives CCK TX rate 2 more dB TX power.
-		This routine works only in ATE mode.
-
-		calculate desired Tx power in RF R3.Tx0~5,	should consider -
-		0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
-		1. TxPowerPercentage
-		2. auto calibration based on TSSI feedback
-		3. extra 2 db for CCK
-		4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
-
-	NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
-		it should be called AFTER MlmeDynamicTxRateSwitching()
-==========================================================================
-*/
-VOID ATEAsicAdjustTxPower(
-	IN PRTMP_ADAPTER pAd)
-{
-	INT			i, j;
-	CHAR		DeltaPwr = 0;
-	BOOLEAN		bAutoTxAgc = FALSE;
-	UCHAR		TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
-	UCHAR		BbpR49 = 0, idx;
-	PCHAR		pTxAgcCompensate;
-	ULONG		TxPwr[5];
-	CHAR		Value;
-
-	/* no one calls this procedure so far */
-	if (pAd->ate.TxWI.BW == BW_40)
-	{
-		if (pAd->ate.Channel > 14)
-		{
-			TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
-			TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
-			TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
-			TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
-			TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
-		}
-		else
-		{
-			TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
-			TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
-			TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
-			TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
-			TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
-		}
-	}
-	else
-	{
-		if (pAd->ate.Channel > 14)
-		{
-			TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
-			TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
-			TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
-			TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
-			TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
-		}
-		else
-		{
-			TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
-			TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
-			TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
-			TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
-			TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
-		}
-	}
-
-	// TX power compensation for temperature variation based on TSSI.
-	// Do it per 4 seconds.
-	if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
-	{
-		if (pAd->ate.Channel <= 14)
-		{
-			/* bg channel */
-			bAutoTxAgc         = pAd->bAutoTxAgcG;
-			TssiRef            = pAd->TssiRefG;
-			pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
-			pTssiPlusBoundary  = &pAd->TssiPlusBoundaryG[0];
-			TxAgcStep          = pAd->TxAgcStepG;
-			pTxAgcCompensate   = &pAd->TxAgcCompensateG;
-		}
-		else
-		{
-			/* a channel */
-			bAutoTxAgc         = pAd->bAutoTxAgcA;
-			TssiRef            = pAd->TssiRefA;
-			pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
-			pTssiPlusBoundary  = &pAd->TssiPlusBoundaryA[0];
-			TxAgcStep          = pAd->TxAgcStepA;
-			pTxAgcCompensate   = &pAd->TxAgcCompensateA;
-		}
-
-		if (bAutoTxAgc)
-		{
-			/* BbpR49 is unsigned char. */
-			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
-
-			/* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
-			/* compensate: +4     +3   +2   +1    0   -1   -2   -3   -4 * steps */
-			/* step value is defined in pAd->TxAgcStepG for tx power value */
-
-			/* [4]+1+[4]   p4     p3   p2   p1   o1   m1   m2   m3   m4 */
-			/* ex:         0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
-			   above value are examined in mass factory production */
-			/*             [4]    [3]  [2]  [1]  [0]  [1]  [2]  [3]  [4] */
-
-			/* plus is 0x10 ~ 0x40, minus is 0x60 ~ 0x90 */
-			/* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
-			/* if value is 0x65, tx power will be -= TxAgcStep*(2-1) */
-
-			if (BbpR49 > pTssiMinusBoundary[1])
-			{
-				// Reading is larger than the reference value.
-				// Check for how large we need to decrease the Tx power.
-				for (idx = 1; idx < 5; idx++)
-				{
-					// Found the range.
-					if (BbpR49 <= pTssiMinusBoundary[idx])
-						break;
-				}
-
-				// The index is the step we should decrease, idx = 0 means there is nothing to compensate.
-//				if (R3 > (ULONG) (TxAgcStep * (idx-1)))
-					*pTxAgcCompensate = -(TxAgcStep * (idx-1));
-//				else
-//					*pTxAgcCompensate = -((UCHAR)R3);
-
-				DeltaPwr += (*pTxAgcCompensate);
-				ATEDBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
-					BbpR49, TssiRef, TxAgcStep, idx-1));
-			}
-			else if (BbpR49 < pTssiPlusBoundary[1])
-			{
-				// Reading is smaller than the reference value.
-				// Check for how large we need to increase the Tx power.
-				for (idx = 1; idx < 5; idx++)
-				{
-					// Found the range.
-					if (BbpR49 >= pTssiPlusBoundary[idx])
-						break;
-				}
-
-				// The index is the step we should increase, idx = 0 means there is nothing to compensate.
-				*pTxAgcCompensate = TxAgcStep * (idx-1);
-				DeltaPwr += (*pTxAgcCompensate);
-				ATEDBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
-					BbpR49, TssiRef, TxAgcStep, idx-1));
-			}
-			else
-			{
-				*pTxAgcCompensate = 0;
-				ATEDBGPRINT(RT_DEBUG_TRACE, ("   Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
-					BbpR49, TssiRef, TxAgcStep, 0));
-			}
-		}
-	}
-	else
-	{
-		if (pAd->ate.Channel <= 14)
-		{
-			bAutoTxAgc         = pAd->bAutoTxAgcG;
-			pTxAgcCompensate   = &pAd->TxAgcCompensateG;
-		}
-		else
-		{
-			bAutoTxAgc         = pAd->bAutoTxAgcA;
-			pTxAgcCompensate   = &pAd->TxAgcCompensateA;
-		}
-
-		if (bAutoTxAgc)
-			DeltaPwr += (*pTxAgcCompensate);
-	}
-
-	/* Calculate delta power based on the percentage specified from UI. */
-	// E2PROM setting is calibrated for maximum TX power (i.e. 100%)
-	// We lower TX power here according to the percentage specified from UI.
-	if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff)       // AUTO TX POWER control
-		;
-	else if (pAd->CommonCfg.TxPowerPercentage > 90)  // 91 ~ 100% & AUTO, treat as 100% in terms of mW
-		;
-	else if (pAd->CommonCfg.TxPowerPercentage > 60)  // 61 ~ 90%, treat as 75% in terms of mW
-	{
-		DeltaPwr -= 1;
-	}
-	else if (pAd->CommonCfg.TxPowerPercentage > 30)  // 31 ~ 60%, treat as 50% in terms of mW
-	{
-		DeltaPwr -= 3;
-	}
-	else if (pAd->CommonCfg.TxPowerPercentage > 15)  // 16 ~ 30%, treat as 25% in terms of mW
-	{
-		DeltaPwr -= 6;
-	}
-	else if (pAd->CommonCfg.TxPowerPercentage > 9)   // 10 ~ 15%, treat as 12.5% in terms of mW
-	{
-		DeltaPwr -= 9;
-	}
-	else                                           // 0 ~ 9 %, treat as MIN(~3%) in terms of mW
-	{
-		DeltaPwr -= 12;
-	}
-
-	/* Reset different new tx power for different TX rate. */
-	for (i=0; i<5; i++)
-	{
-		if (TxPwr[i] != 0xffffffff)
-		{
-			for (j=0; j<8; j++)
-			{
-				Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */
-
-				if ((Value + DeltaPwr) < 0)
-				{
-					Value = 0; /* min */
-				}
-				else if ((Value + DeltaPwr) > 0xF)
-				{
-					Value = 0xF; /* max */
-				}
-				else
-				{
-					Value += DeltaPwr; /* temperature compensation */
-				}
-
-				/* fill new value to CSR offset */
-				TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
-			}
-
-			/* write tx power value to CSR */
-			/* TX_PWR_CFG_0 (8 tx rate) for	TX power for OFDM 12M/18M
-											TX power for OFDM 6M/9M
-											TX power for CCK5.5M/11M
-											TX power for CCK1M/2M */
-			/* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
-			RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);
-
-
-		}
-	}
-
-}
-
-
-/*
-========================================================================
-	Routine Description:
-		Write TxWI for ATE mode.
-
-	Return Value:
-		None
-========================================================================
-*/
-#ifdef RTMP_MAC_PCI
-static VOID ATEWriteTxWI(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PTXWI_STRUC	pOutTxWI,
-	IN	BOOLEAN			FRAG,
-	IN	BOOLEAN			CFACK,
-	IN	BOOLEAN			InsTimestamp,
-	IN	BOOLEAN			AMPDU,
-	IN	BOOLEAN			Ack,
-	IN	BOOLEAN			NSeq,		// HW new a sequence.
-	IN	UCHAR			BASize,
-	IN	UCHAR			WCID,
-	IN	ULONG			Length,
-	IN	UCHAR			PID,
-	IN	UCHAR			TID,
-	IN	UCHAR			TxRate,
-	IN	UCHAR			Txopmode,
-	IN	BOOLEAN			CfAck,
-	IN	HTTRANSMIT_SETTING	*pTransmit)
-{
-	TXWI_STRUC		TxWI;
-	PTXWI_STRUC	pTxWI;
-
-	//
-	// Always use Long preamble before verifiation short preamble functionality works well.
-	// Todo: remove the following line if short preamble functionality works
-	//
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
-	NdisZeroMemory(&TxWI, TXWI_SIZE);
-	pTxWI = &TxWI;
-
-	pTxWI->FRAG= FRAG;
-
-	pTxWI->CFACK = CFACK;
-	pTxWI->TS= InsTimestamp;
-	pTxWI->AMPDU = AMPDU;
-	pTxWI->ACK = Ack;
-	pTxWI->txop= Txopmode;
-
-	pTxWI->NSEQ = NSeq;
-
-	// John tune the performace with Intel Client in 20 MHz performance
-	if ( BASize >7 )
-		BASize =7;
-
-	pTxWI->BAWinSize = BASize;
-	pTxWI->WirelessCliID = WCID;
-	pTxWI->MPDUtotalByteCount = Length;
-	pTxWI->PacketId = PID;
-
-	// If CCK or OFDM, BW must be 20
-	pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
-	pTxWI->ShortGI = pTransmit->field.ShortGI;
-	pTxWI->STBC = pTransmit->field.STBC;
-
-	pTxWI->MCS = pTransmit->field.MCS;
-	pTxWI->PHYMODE = pTransmit->field.MODE;
-	pTxWI->CFACK = CfAck;
-	pTxWI->MIMOps = 0;
-	pTxWI->MpduDensity = 0;
-
-	pTxWI->PacketId = pTxWI->MCS;
-	NdisMoveMemory(pOutTxWI, &TxWI, sizeof(TXWI_STRUC));
-
-    return;
-}
-#endif // RTMP_MAC_PCI //
-
-
-
-
-/*
-========================================================================
-
-	Routine Description:
-		Disable protection for ATE.
-========================================================================
-*/
-VOID ATEDisableAsicProtect(
-	IN		PRTMP_ADAPTER	pAd)
-{
-	PROT_CFG_STRUC	ProtCfg, ProtCfg4;
-	UINT32 Protect[6];
-	USHORT			offset;
-	UCHAR			i;
-	UINT32 MacReg = 0;
-
-	// Config ASIC RTS threshold register
-	RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
-	MacReg &= 0xFF0000FF;
-	MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
-	RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
-
-	// Initial common protection settings
-	RTMPZeroMemory(Protect, sizeof(Protect));
-	ProtCfg4.word = 0;
-	ProtCfg.word = 0;
-	ProtCfg.field.TxopAllowGF40 = 1;
-	ProtCfg.field.TxopAllowGF20 = 1;
-	ProtCfg.field.TxopAllowMM40 = 1;
-	ProtCfg.field.TxopAllowMM20 = 1;
-	ProtCfg.field.TxopAllowOfdm = 1;
-	ProtCfg.field.TxopAllowCck = 1;
-	ProtCfg.field.RTSThEn = 1;
-	ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
-
-	// Handle legacy(B/G) protection
-	ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
-	ProtCfg.field.ProtectCtrl = 0;
-	Protect[0] = ProtCfg.word;
-	Protect[1] = ProtCfg.word;
-
-	// NO PROTECT
-	// 1.All STAs in the BSS are 20/40 MHz HT
-	// 2. in ai 20/40MHz BSS
-	// 3. all STAs are 20MHz in a 20MHz BSS
-	// Pure HT. no protection.
-
-	// MM20_PROT_CFG
-	//	Reserved (31:27)
-	//	PROT_TXOP(25:20) -- 010111
-	//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
-	//  PROT_CTRL(17:16) -- 00 (None)
-	//	PROT_RATE(15:0)  -- 0x4004 (OFDM 24M)
-	Protect[2] = 0x01744004;
-
-	// MM40_PROT_CFG
-	//	Reserved (31:27)
-	//	PROT_TXOP(25:20) -- 111111
-	//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
-	//  PROT_CTRL(17:16) -- 00 (None)
-	//	PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M)
-	Protect[3] = 0x03f44084;
-
-	// CF20_PROT_CFG
-	//	Reserved (31:27)
-	//	PROT_TXOP(25:20) -- 010111
-	//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
-	//  PROT_CTRL(17:16) -- 00 (None)
-	//	PROT_RATE(15:0)  -- 0x4004 (OFDM 24M)
-	Protect[4] = 0x01744004;
-
-	// CF40_PROT_CFG
-	//	Reserved (31:27)
-	//	PROT_TXOP(25:20) -- 111111
-	//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
-	//  PROT_CTRL(17:16) -- 00 (None)
-	//	PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M)
-	Protect[5] = 0x03f44084;
-
-	pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
-
-	offset = CCK_PROT_CFG;
-	for (i = 0;i < 6;i++)
-		RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
-
-}
-
-
-
-
-/* There are two ways to convert Rssi */
-/* the way used with GET_LNA_GAIN() */
-CHAR ATEConvertToRssi(
-	IN PRTMP_ADAPTER pAd,
-	IN	CHAR	Rssi,
-	IN  UCHAR   RssiNumber)
-{
-	UCHAR	RssiOffset, LNAGain;
-
-	// Rssi equals to zero should be an invalid value
-	if (Rssi == 0)
-		return -99;
-
-	LNAGain = GET_LNA_GAIN(pAd);
-	if (pAd->LatchRfRegs.Channel > 14)
-	{
-		if (RssiNumber == 0)
-			RssiOffset = pAd->ARssiOffset0;
-		else if (RssiNumber == 1)
-			RssiOffset = pAd->ARssiOffset1;
-		else
-			RssiOffset = pAd->ARssiOffset2;
-	}
-	else
-	{
-		if (RssiNumber == 0)
-			RssiOffset = pAd->BGRssiOffset0;
-		else if (RssiNumber == 1)
-			RssiOffset = pAd->BGRssiOffset1;
-		else
-			RssiOffset = pAd->BGRssiOffset2;
-	}
-
-	return (-12 - RssiOffset - LNAGain - Rssi);
-}
-
-
-/*
-========================================================================
-
-	Routine Description:
-		Set Japan filter coefficients if needed.
-	Note:
-		This routine should only be called when
-		entering TXFRAME mode or TXCONT mode.
-
-========================================================================
-*/
-static VOID SetJapanFilter(
-	IN		PRTMP_ADAPTER	pAd)
-{
-	UCHAR			BbpData = 0;
-
-	//
-	// If Channel=14 and Bandwidth=20M and Mode=CCK, set BBP R4 bit5=1
-	// (Japan Tx filter coefficients)when (TXFRAME or TXCONT).
-	//
-	ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BbpData);
-
-    if ((pAd->ate.TxWI.PHYMODE == MODE_CCK) && (pAd->ate.Channel == 14) && (pAd->ate.TxWI.BW == BW_20))
-    {
-        BbpData |= 0x20;    // turn on
-        ATEDBGPRINT(RT_DEBUG_TRACE, ("SetJapanFilter!!!\n"));
-    }
-    else
-    {
-		BbpData &= 0xdf;    // turn off
-		ATEDBGPRINT(RT_DEBUG_TRACE, ("ClearJapanFilter!!!\n"));
-    }
-
-	ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BbpData);
-}
-
-
-VOID ATESampleRssi(
-	IN PRTMP_ADAPTER	pAd,
-	IN PRXWI_STRUC		pRxWI)
-{
-	/* There are two ways to collect RSSI. */
-//	pAd->LastRxRate = (USHORT)((pRxWI->MCS) + (pRxWI->BW <<7) + (pRxWI->ShortGI <<8)+ (pRxWI->PHYMODE <<14)) ;
-	if (pRxWI->RSSI0 != 0)
-	{
-		pAd->ate.LastRssi0	= ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI0, RSSI_0);
-		pAd->ate.AvgRssi0X8	= (pAd->ate.AvgRssi0X8 - pAd->ate.AvgRssi0) + pAd->ate.LastRssi0;
-		pAd->ate.AvgRssi0	= pAd->ate.AvgRssi0X8 >> 3;
-	}
-	if (pRxWI->RSSI1 != 0)
-	{
-		pAd->ate.LastRssi1	= ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI1, RSSI_1);
-		pAd->ate.AvgRssi1X8	= (pAd->ate.AvgRssi1X8 - pAd->ate.AvgRssi1) + pAd->ate.LastRssi1;
-		pAd->ate.AvgRssi1	= pAd->ate.AvgRssi1X8 >> 3;
-	}
-	if (pRxWI->RSSI2 != 0)
-	{
-		pAd->ate.LastRssi2	= ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI2, RSSI_2);
-		pAd->ate.AvgRssi2X8	= (pAd->ate.AvgRssi2X8 - pAd->ate.AvgRssi2) + pAd->ate.LastRssi2;
-		pAd->ate.AvgRssi2	= pAd->ate.AvgRssi2X8 >> 3;
-	}
-
-	pAd->ate.LastSNR0 = (CHAR)(pRxWI->SNR0);// CHAR ==> UCHAR ?
-	pAd->ate.LastSNR1 = (CHAR)(pRxWI->SNR1);// CHAR ==> UCHAR ?
-
-	pAd->ate.NumOfAvgRssiSample ++;
-}
-
-
-#ifdef CONFIG_STA_SUPPORT
-VOID RTMPStationStop(
-    IN  PRTMP_ADAPTER   pAd)
-{
-//	BOOLEAN       Cancelled;
-
-    ATEDBGPRINT(RT_DEBUG_TRACE, ("==> RTMPStationStop\n"));
-
-	// For rx statistics, we need to keep this timer running.
-//	RTMPCancelTimer(&pAd->Mlme.PeriodicTimer,      &Cancelled);
-
-    ATEDBGPRINT(RT_DEBUG_TRACE, ("<== RTMPStationStop\n"));
-}
-
-
-VOID RTMPStationStart(
-    IN  PRTMP_ADAPTER   pAd)
-{
-    ATEDBGPRINT(RT_DEBUG_TRACE, ("==> RTMPStationStart\n"));
-
-#ifdef RTMP_MAC_PCI
-	pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-
-	/* We did not cancel this timer when entering ATE mode. */
-//	RTMPSetTimer(&pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
-#endif // RTMP_MAC_PCI //
-
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("<== RTMPStationStart\n"));
-}
-#endif // CONFIG_STA_SUPPORT //
-
-
-/*
-==========================================================================
-	Description:
-		Setup Frame format.
-	NOTE:
-		This routine should only be used in ATE mode.
-==========================================================================
-*/
-#ifdef RTMP_MAC_PCI
-static INT ATESetUpFrame(
-	IN PRTMP_ADAPTER pAd,
-	IN UINT32 TxIdx)
-{
-	UINT j;
-	PTXD_STRUC pTxD;
-#ifdef RT_BIG_ENDIAN
-    PTXD_STRUC      pDestTxD;
-    TXD_STRUC       TxD;
-#endif
-	PNDIS_PACKET pPacket;
-	PUCHAR pDest;
-	PVOID AllocVa;
-	NDIS_PHYSICAL_ADDRESS AllocPa;
-	HTTRANSMIT_SETTING	TxHTPhyMode;
-
-	PRTMP_TX_RING pTxRing = &pAd->TxRing[QID_AC_BE];
-	PTXWI_STRUC pTxWI = (PTXWI_STRUC) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
-	PUCHAR pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
-
-#ifdef RALINK_28xx_QA
-	PHEADER_802_11	pHeader80211;
-#endif // RALINK_28xx_QA //
-
-	if (pAd->ate.bQATxStart == TRUE)
-	{
-		// always use QID_AC_BE and FIFO_EDCA
-
-		// fill TxWI
-		TxHTPhyMode.field.BW = pAd->ate.TxWI.BW;
-		TxHTPhyMode.field.ShortGI = pAd->ate.TxWI.ShortGI;
-		TxHTPhyMode.field.STBC = 0;
-		TxHTPhyMode.field.MCS = pAd->ate.TxWI.MCS;
-		TxHTPhyMode.field.MODE = pAd->ate.TxWI.PHYMODE;
-
-		ATEWriteTxWI(pAd, pTxWI, pAd->ate.TxWI.FRAG, pAd->ate.TxWI.CFACK,
-			pAd->ate.TxWI.TS,  pAd->ate.TxWI.AMPDU, pAd->ate.TxWI.ACK, pAd->ate.TxWI.NSEQ,
-			pAd->ate.TxWI.BAWinSize, 0, pAd->ate.TxWI.MPDUtotalByteCount, pAd->ate.TxWI.PacketId, 0, 0,
-			pAd->ate.TxWI.txop/*IFS_HTTXOP*/, pAd->ate.TxWI.CFACK/*FALSE*/, &TxHTPhyMode);
-	}
-	else
-	{
-		TxHTPhyMode.field.BW = pAd->ate.TxWI.BW;
-		TxHTPhyMode.field.ShortGI = pAd->ate.TxWI.ShortGI;
-		TxHTPhyMode.field.STBC = 0;
-		TxHTPhyMode.field.MCS = pAd->ate.TxWI.MCS;
-		TxHTPhyMode.field.MODE = pAd->ate.TxWI.PHYMODE;
-		ATEWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE,  FALSE, FALSE, FALSE,
-			4, 0, pAd->ate.TxLength, 0, 0, 0, IFS_HTTXOP, FALSE, &TxHTPhyMode);
-	}
-
-	// fill 802.11 header
-#ifdef RALINK_28xx_QA
-	if (pAd->ate.bQATxStart == TRUE)
-	{
-		NdisMoveMemory(pDMAHeaderBufVA+TXWI_SIZE, pAd->ate.Header, pAd->ate.HLen);
-	}
-	else
-#endif // RALINK_28xx_QA //
-	{
-		NdisMoveMemory(pDMAHeaderBufVA+TXWI_SIZE, TemplateFrame, LENGTH_802_11);
-		NdisMoveMemory(pDMAHeaderBufVA+TXWI_SIZE+4, pAd->ate.Addr1, ETH_LENGTH_OF_ADDRESS);
-		NdisMoveMemory(pDMAHeaderBufVA+TXWI_SIZE+10, pAd->ate.Addr2, ETH_LENGTH_OF_ADDRESS);
-		NdisMoveMemory(pDMAHeaderBufVA+TXWI_SIZE+16, pAd->ate.Addr3, ETH_LENGTH_OF_ADDRESS);
-	}
-
-#ifdef RT_BIG_ENDIAN
-	RTMPFrameEndianChange(pAd, (((PUCHAR)pDMAHeaderBufVA)+TXWI_SIZE), DIR_READ, FALSE);
-#endif // RT_BIG_ENDIAN //
-
-	/* alloc buffer for payload */
-#ifdef RALINK_28xx_QA
-	if (pAd->ate.bQATxStart == TRUE)
-	{
-		pPacket = RTMP_AllocateRxPacketBuffer(pAd, pAd->ate.DLen + 0x100, FALSE, &AllocVa, &AllocPa);
-	}
-	else
-#endif // RALINK_28xx_QA //
-	{
-		pPacket = RTMP_AllocateRxPacketBuffer(pAd, pAd->ate.TxLength, FALSE, &AllocVa, &AllocPa);
-	}
-
-	if (pPacket == NULL)
-	{
-		pAd->ate.TxCount = 0;
-		ATEDBGPRINT(RT_DEBUG_TRACE, ("%s fail to alloc packet space.\n", __FUNCTION__));
-		return -1;
-	}
-	pTxRing->Cell[TxIdx].pNextNdisPacket = pPacket;
-
-	pDest = (PUCHAR) AllocVa;
-
-#ifdef RALINK_28xx_QA
-	if (pAd->ate.bQATxStart == TRUE)
-	{
-		RTPKT_TO_OSPKT(pPacket)->len = pAd->ate.DLen;
-	}
-	else
-#endif // RALINK_28xx_QA //
-	{
-		RTPKT_TO_OSPKT(pPacket)->len = pAd->ate.TxLength - LENGTH_802_11;
-	}
-
-	// prepare frame payload
-#ifdef RALINK_28xx_QA
-	if (pAd->ate.bQATxStart == TRUE)
-	{
-		// copy pattern
-		if ((pAd->ate.PLen != 0))
-		{
-			int j;
-
-			for (j = 0; j < pAd->ate.DLen; j+=pAd->ate.PLen)
-			{
-				memcpy(RTPKT_TO_OSPKT(pPacket)->data + j, pAd->ate.Pattern, pAd->ate.PLen);
-			}
-		}
-	}
-	else
-#endif // RALINK_28xx_QA //
-	{
-		for (j = 0; j < RTPKT_TO_OSPKT(pPacket)->len; j++)
-		{
-			pDest[j] = 0xA5;
-		}
-	}
-
-	/* build Tx Descriptor */
-#ifndef RT_BIG_ENDIAN
-	pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
-#else
-    pDestTxD  = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
-    TxD = *pDestTxD;
-    pTxD = &TxD;
-#endif // !RT_BIG_ENDIAN //
-
-#ifdef RALINK_28xx_QA
-	if (pAd->ate.bQATxStart == TRUE)
-	{
-		// prepare TxD
-		NdisZeroMemory(pTxD, TXD_SIZE);
-		RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
-		// build TX DESC
-		pTxD->SDPtr0 = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
-		pTxD->SDLen0 = TXWI_SIZE + pAd->ate.HLen;
-		pTxD->LastSec0 = 0;
-		pTxD->SDPtr1 = AllocPa;
-		pTxD->SDLen1 = RTPKT_TO_OSPKT(pPacket)->len;
-		pTxD->LastSec1 = 1;
-
-		pDest = (PUCHAR)pTxWI;
-		pDest += TXWI_SIZE;
-		pHeader80211 = (PHEADER_802_11)pDest;
-
-		// modify sequence number...
-		if (pAd->ate.TxDoneCount == 0)
-		{
-			pAd->ate.seq = pHeader80211->Sequence;
-		}
-		else
-			pHeader80211->Sequence = ++pAd->ate.seq;
-	}
-	else
-#endif // RALINK_28xx_QA //
-	{
-		NdisZeroMemory(pTxD, TXD_SIZE);
-		RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
-		// build TX DESC
-		pTxD->SDPtr0 = RTMP_GetPhysicalAddressLow (pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
-		pTxD->SDLen0 = TXWI_SIZE + LENGTH_802_11;
-		pTxD->LastSec0 = 0;
-		pTxD->SDPtr1 = AllocPa;
-		pTxD->SDLen1 = RTPKT_TO_OSPKT(pPacket)->len;
-		pTxD->LastSec1 = 1;
-	}
-
-#ifdef RT_BIG_ENDIAN
-	RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
-	RTMPFrameEndianChange(pAd, (((PUCHAR)pDMAHeaderBufVA)+TXWI_SIZE), DIR_WRITE, FALSE);
-    RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
-    WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
-#endif // RT_BIG_ENDIAN //
-
-	return 0;
-}
-/*=======================End of RTMP_MAC_PCI =======================*/
-#endif // RTMP_MAC_PCI //
-
-
-
-
-VOID rt_ee_read_all(PRTMP_ADAPTER pAd, USHORT *Data)
-{
-	USHORT i;
-	USHORT value;
-
-
-	for (i = 0 ; i < EEPROM_SIZE/2 ; )
-	{
-		/* "value" is especially for some compilers... */
-		RT28xx_EEPROM_READ16(pAd, i*2, value);
-		Data[i] = value;
-		i++;
-	}
-}
-
-
-VOID rt_ee_write_all(PRTMP_ADAPTER pAd, USHORT *Data)
-{
-	USHORT i;
-	USHORT value;
-
-
-	for (i = 0 ; i < EEPROM_SIZE/2 ; )
-	{
-		/* "value" is especially for some compilers... */
-		value = Data[i];
-		RT28xx_EEPROM_WRITE16(pAd, i*2, value);
-		i++;
-	}
-}
-
-
-#ifdef RALINK_28xx_QA
-VOID ATE_QA_Statistics(
-	IN PRTMP_ADAPTER			pAd,
-	IN PRXWI_STRUC				pRxWI,
-	IN PRT28XX_RXD_STRUC		pRxD,
-	IN PHEADER_802_11			pHeader)
-{
-	// update counter first
-	if (pHeader != NULL)
-	{
-		if (pHeader->FC.Type == BTYPE_DATA)
-		{
-			if (pRxD->U2M)
-				pAd->ate.U2M++;
-			else
-				pAd->ate.OtherData++;
-		}
-		else if (pHeader->FC.Type == BTYPE_MGMT)
-		{
-			if (pHeader->FC.SubType == SUBTYPE_BEACON)
-				pAd->ate.Beacon++;
-			else
-				pAd->ate.OtherCount++;
-		}
-		else if (pHeader->FC.Type == BTYPE_CNTL)
-		{
-			pAd->ate.OtherCount++;
-		}
-	}
-	pAd->ate.RSSI0 = pRxWI->RSSI0;
-	pAd->ate.RSSI1 = pRxWI->RSSI1;
-	pAd->ate.RSSI2 = pRxWI->RSSI2;
-	pAd->ate.SNR0 = pRxWI->SNR0;
-	pAd->ate.SNR1 = pRxWI->SNR1;
-}
-
-
-/* command id with Cmd Type == 0x0008(for 28xx)/0x0005(for iNIC) */
-#define RACFG_CMD_RF_WRITE_ALL		0x0000
-#define RACFG_CMD_E2PROM_READ16		0x0001
-#define RACFG_CMD_E2PROM_WRITE16	0x0002
-#define RACFG_CMD_E2PROM_READ_ALL	0x0003
-#define RACFG_CMD_E2PROM_WRITE_ALL	0x0004
-#define RACFG_CMD_IO_READ			0x0005
-#define RACFG_CMD_IO_WRITE			0x0006
-#define RACFG_CMD_IO_READ_BULK		0x0007
-#define RACFG_CMD_BBP_READ8			0x0008
-#define RACFG_CMD_BBP_WRITE8		0x0009
-#define RACFG_CMD_BBP_READ_ALL		0x000a
-#define RACFG_CMD_GET_COUNTER		0x000b
-#define RACFG_CMD_CLEAR_COUNTER		0x000c
-
-#define RACFG_CMD_RSV1				0x000d
-#define RACFG_CMD_RSV2				0x000e
-#define RACFG_CMD_RSV3				0x000f
-
-#define RACFG_CMD_TX_START			0x0010
-#define RACFG_CMD_GET_TX_STATUS		0x0011
-#define RACFG_CMD_TX_STOP			0x0012
-#define RACFG_CMD_RX_START			0x0013
-#define RACFG_CMD_RX_STOP			0x0014
-#define RACFG_CMD_GET_NOISE_LEVEL	0x0015
-
-#define RACFG_CMD_ATE_START			0x0080
-#define RACFG_CMD_ATE_STOP			0x0081
-
-#define RACFG_CMD_ATE_START_TX_CARRIER		0x0100
-#define RACFG_CMD_ATE_START_TX_CONT			0x0101
-#define RACFG_CMD_ATE_START_TX_FRAME		0x0102
-#define RACFG_CMD_ATE_SET_BW	            0x0103
-#define RACFG_CMD_ATE_SET_TX_POWER0	        0x0104
-#define RACFG_CMD_ATE_SET_TX_POWER1			0x0105
-#define RACFG_CMD_ATE_SET_FREQ_OFFSET		0x0106
-#define RACFG_CMD_ATE_GET_STATISTICS		0x0107
-#define RACFG_CMD_ATE_RESET_COUNTER			0x0108
-#define RACFG_CMD_ATE_SEL_TX_ANTENNA		0x0109
-#define RACFG_CMD_ATE_SEL_RX_ANTENNA		0x010a
-#define RACFG_CMD_ATE_SET_PREAMBLE			0x010b
-#define RACFG_CMD_ATE_SET_CHANNEL			0x010c
-#define RACFG_CMD_ATE_SET_ADDR1				0x010d
-#define RACFG_CMD_ATE_SET_ADDR2				0x010e
-#define RACFG_CMD_ATE_SET_ADDR3				0x010f
-#define RACFG_CMD_ATE_SET_RATE				0x0110
-#define RACFG_CMD_ATE_SET_TX_FRAME_LEN		0x0111
-#define RACFG_CMD_ATE_SET_TX_FRAME_COUNT	0x0112
-#define RACFG_CMD_ATE_START_RX_FRAME		0x0113
-#define RACFG_CMD_ATE_E2PROM_READ_BULK	0x0114
-#define RACFG_CMD_ATE_E2PROM_WRITE_BULK	0x0115
-#define RACFG_CMD_ATE_IO_WRITE_BULK		0x0116
-#define RACFG_CMD_ATE_BBP_READ_BULK		0x0117
-#define RACFG_CMD_ATE_BBP_WRITE_BULK	0x0118
-#define RACFG_CMD_ATE_RF_READ_BULK		0x0119
-#define RACFG_CMD_ATE_RF_WRITE_BULK		0x011a
-
-
-static VOID memcpy_exl(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len);
-static VOID memcpy_exs(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len);
-static VOID RTMP_IO_READ_BULK(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, UINT32 len);
-
-
-
-VOID RtmpDoAte(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq)
-{
-	USHORT Command_Id;
-	INT	Status = NDIS_STATUS_SUCCESS;
-	struct ate_racfghdr *pRaCfg;
-
-
-	if ((pRaCfg = kmalloc(sizeof(struct ate_racfghdr), GFP_KERNEL)) == NULL)
-	{
-		Status = -EINVAL;
-		return;
-	}
-
-	NdisZeroMemory(pRaCfg, sizeof(struct ate_racfghdr));
-
-    if (copy_from_user((PUCHAR)pRaCfg, wrq->u.data.pointer, wrq->u.data.length))
-	{
-		Status = -EFAULT;
-		kfree(pRaCfg);
-		return;
-	}
-
-	Command_Id = ntohs(pRaCfg->command_id);
-
-	ATEDBGPRINT(RT_DEBUG_TRACE,("\n%s: Command_Id = 0x%04x !\n", __FUNCTION__, Command_Id));
-
-	switch (Command_Id)
-	{
-		/* We will get this command when QA starts. */
-		case RACFG_CMD_ATE_START:
-			Status=DO_RACFG_CMD_ATE_START(pAdapter,wrq,pRaCfg);
-			break;
-
-		/* We will get this command either QA is closed or ated is killed by user. */
-		case RACFG_CMD_ATE_STOP:
-			Status=DO_RACFG_CMD_ATE_STOP(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_RF_WRITE_ALL:
-			Status=DO_RACFG_CMD_RF_WRITE_ALL(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_E2PROM_READ16:
-			Status=DO_RACFG_CMD_E2PROM_READ16(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_E2PROM_WRITE16:
-			Status=DO_RACFG_CMD_E2PROM_WRITE16(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_E2PROM_READ_ALL:
-			Status=DO_RACFG_CMD_E2PROM_READ_ALL(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_E2PROM_WRITE_ALL:
-			Status=DO_RACFG_CMD_E2PROM_WRITE_ALL(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_IO_READ:
-			Status=DO_RACFG_CMD_IO_READ(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_IO_WRITE:
-			Status=DO_RACFG_CMD_IO_WRITE(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_IO_READ_BULK:
-			Status=DO_RACFG_CMD_IO_READ_BULK(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_BBP_READ8:
-			Status=DO_RACFG_CMD_BBP_READ8(pAdapter,wrq,pRaCfg);
-			break;
-		case RACFG_CMD_BBP_WRITE8:
-			Status=DO_RACFG_CMD_BBP_WRITE8(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_BBP_READ_ALL:
-			Status=DO_RACFG_CMD_BBP_READ_ALL(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_E2PROM_READ_BULK:
-			Status=DO_RACFG_CMD_ATE_E2PROM_READ_BULK(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_E2PROM_WRITE_BULK:
-			Status=DO_RACFG_CMD_ATE_E2PROM_WRITE_BULK(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_IO_WRITE_BULK:
-			Status=DO_RACFG_CMD_ATE_IO_WRITE_BULK(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_BBP_READ_BULK:
-			Status=DO_RACFG_CMD_ATE_BBP_READ_BULK(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_BBP_WRITE_BULK:
-			Status=DO_RACFG_CMD_ATE_BBP_WRITE_BULK(pAdapter,wrq,pRaCfg);
-			break;
-
-
-		case RACFG_CMD_GET_NOISE_LEVEL:
-			Status=DO_RACFG_CMD_GET_NOISE_LEVEL(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_GET_COUNTER:
-			Status=DO_RACFG_CMD_GET_COUNTER(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_CLEAR_COUNTER:
-			Status=DO_RACFG_CMD_CLEAR_COUNTER(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_TX_START:
-			Status=DO_RACFG_CMD_TX_START(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_GET_TX_STATUS:
-			Status=DO_RACFG_CMD_GET_TX_STATUS(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_TX_STOP:
-			Status=DO_RACFG_CMD_TX_STOP(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_RX_START:
-			Status=DO_RACFG_CMD_RX_START(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_RX_STOP:
-			Status=DO_RACFG_CMD_RX_STOP(pAdapter,wrq,pRaCfg);
-			break;
-
-		/* The following cases are for new ATE GUI(not QA). */
-		/*==================================================*/
-		case RACFG_CMD_ATE_START_TX_CARRIER:
-			Status=DO_RACFG_CMD_ATE_START_TX_CARRIER(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_START_TX_CONT:
-			Status=DO_RACFG_CMD_ATE_START_TX_CONT(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_START_TX_FRAME:
-			Status=DO_RACFG_CMD_ATE_START_TX_FRAME(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_SET_BW:
-			Status=DO_RACFG_CMD_ATE_SET_BW(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_SET_TX_POWER0:
-			Status=DO_RACFG_CMD_ATE_SET_TX_POWER0(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_SET_TX_POWER1:
-			Status=DO_RACFG_CMD_ATE_SET_TX_POWER1(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_SET_FREQ_OFFSET:
-			Status=DO_RACFG_CMD_ATE_SET_TX_POWER1(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_GET_STATISTICS:
-			Status=DO_RACFG_CMD_ATE_GET_STATISTICS(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_RESET_COUNTER:
-			Status=DO_RACFG_CMD_ATE_RESET_COUNTER(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_SEL_TX_ANTENNA:
-			Status=DO_RACFG_CMD_ATE_SEL_TX_ANTENNA(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_SEL_RX_ANTENNA:
-			Status=DO_RACFG_CMD_ATE_SEL_TX_ANTENNA(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_SET_PREAMBLE:
-			Status=DO_RACFG_CMD_ATE_SET_PREAMBLE(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_SET_CHANNEL:
-			Status=DO_RACFG_CMD_ATE_SET_CHANNEL(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_SET_ADDR1:
-			Status=DO_RACFG_CMD_ATE_SET_ADDR1(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_SET_ADDR2:
-			Status=DO_RACFG_CMD_ATE_SET_ADDR2(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_SET_ADDR3:
-			Status=DO_RACFG_CMD_ATE_SET_ADDR3(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_SET_RATE:
-			Status=DO_RACFG_CMD_ATE_SET_RATE(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_SET_TX_FRAME_LEN:
-			Status=DO_RACFG_CMD_ATE_SET_TX_FRAME_LEN(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_SET_TX_FRAME_COUNT:
-			Status=DO_RACFG_CMD_ATE_SET_TX_FRAME_COUNT(pAdapter,wrq,pRaCfg);
-			break;
-
-		case RACFG_CMD_ATE_START_RX_FRAME:
-			Status=DO_RACFG_CMD_ATE_START_RX_FRAME(pAdapter,wrq,pRaCfg);
-			break;
-		default:
-			break;
-	}
-
-    ASSERT(pRaCfg != NULL);
-
-    if (pRaCfg != NULL)
-	    kfree(pRaCfg);
-
-	return;
-}
-
-
-VOID BubbleSort(INT32 n, INT32 a[])
-{
-	INT32 k, j, temp;
-
-	for (k = n-1;  k>0;  k--)
-	{
-		for (j = 0; j<k; j++)
-		{
-			if (a[j] > a[j+1])
-			{
-				temp = a[j];
-				a[j]=a[j+1];
-				a[j+1]=temp;
-			}
-		}
-	}
-}
-
-
-VOID CalNoiseLevel(PRTMP_ADAPTER pAd, UCHAR channel, INT32 RSSI[3][10])
-{
-	INT32		RSSI0, RSSI1, RSSI2;
-	CHAR		Rssi0Offset, Rssi1Offset, Rssi2Offset;
-	UCHAR		BbpR50Rssi0 = 0, BbpR51Rssi1 = 0, BbpR52Rssi2 = 0;
-	UCHAR		Org_BBP66value = 0, Org_BBP69value = 0, Org_BBP70value = 0, data = 0;
-	USHORT		LNA_Gain = 0;
-	INT32       j = 0;
-	UCHAR		Org_Channel = pAd->ate.Channel;
-	USHORT	    GainValue = 0, OffsetValue = 0;
-
-	ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &Org_BBP66value);
-	ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R69, &Org_BBP69value);
-	ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R70, &Org_BBP70value);
-
-	//**********************************************************************
-	// Read the value of LNA gain and Rssi offset
-	//**********************************************************************
-	RT28xx_EEPROM_READ16(pAd, EEPROM_LNA_OFFSET, GainValue);
-
-	// for Noise Level
-	if (channel <= 14)
-	{
-		LNA_Gain = GainValue & 0x00FF;
-
-		RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET, OffsetValue);
-		Rssi0Offset = OffsetValue & 0x00FF;
-		Rssi1Offset = (OffsetValue & 0xFF00) >> 8;
-		RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_BG_OFFSET + 2)/* 0x48 */, OffsetValue);
-		Rssi2Offset = OffsetValue & 0x00FF;
-	}
-	else
-	{
-		LNA_Gain = (GainValue & 0xFF00) >> 8;
-
-		RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_A_OFFSET, OffsetValue);
-		Rssi0Offset = OffsetValue & 0x00FF;
-		Rssi1Offset = (OffsetValue & 0xFF00) >> 8;
-		RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET + 2)/* 0x4C */, OffsetValue);
-		Rssi2Offset = OffsetValue & 0x00FF;
-	}
-	//**********************************************************************
-	{
-		pAd->ate.Channel = channel;
-		ATEAsicSwitchChannel(pAd);
-		mdelay(5);
-
-		data = 0x10;
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, data);
-		data = 0x40;
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, data);
-		data = 0x40;
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, data);
-		mdelay(5);
-
-		// start Rx
-		pAd->ate.bQARxStart = TRUE;
-		Set_ATE_Proc(pAd, "RXFRAME");
-
-		mdelay(5);
-
-		for (j = 0; j < 10; j++)
-		{
-			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R50, &BbpR50Rssi0);
-			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R51, &BbpR51Rssi1);
-			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R52, &BbpR52Rssi2);
-
-			mdelay(10);
-
-			// calculate RSSI 0
-			if (BbpR50Rssi0 == 0)
-			{
-				RSSI0 = -100;
-			}
-			else
-			{
-				RSSI0 = (INT32)(-12 - BbpR50Rssi0 - LNA_Gain - Rssi0Offset);
-			}
-			RSSI[0][j] = RSSI0;
-
-			if ( pAd->Antenna.field.RxPath >= 2 ) // 2R
-			{
-				// calculate RSSI 1
-				if (BbpR51Rssi1 == 0)
-				{
-					RSSI1 = -100;
-				}
-				else
-				{
-					RSSI1 = (INT32)(-12 - BbpR51Rssi1 - LNA_Gain - Rssi1Offset);
-				}
-				RSSI[1][j] = RSSI1;
-			}
-
-			if ( pAd->Antenna.field.RxPath >= 3 ) // 3R
-			{
-				// calculate RSSI 2
-				if (BbpR52Rssi2 == 0)
-					RSSI2 = -100;
-				else
-					RSSI2 = (INT32)(-12 - BbpR52Rssi2 - LNA_Gain - Rssi2Offset);
-
-				RSSI[2][j] = RSSI2;
-			}
-		}
-
-		// stop Rx
-		Set_ATE_Proc(pAd, "RXSTOP");
-
-		mdelay(5);
-
-		BubbleSort(10, RSSI[0]);	// 1R
-
-		if ( pAd->Antenna.field.RxPath >= 2 ) // 2R
-		{
-			BubbleSort(10, RSSI[1]);
-		}
-
-		if ( pAd->Antenna.field.RxPath >= 3 ) // 3R
-		{
-			BubbleSort(10, RSSI[2]);
-		}
-	}
-
-	pAd->ate.Channel = Org_Channel;
-	ATEAsicSwitchChannel(pAd);
-
-	// restore original value
-    ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, Org_BBP66value);
-    ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, Org_BBP69value);
-    ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, Org_BBP70value);
-
-	return;
-}
-
-
-BOOLEAN SyncTxRxConfig(PRTMP_ADAPTER pAd, USHORT offset, UCHAR value)
-{
-	UCHAR tmp = 0, bbp_data = 0;
-
-	if (ATE_ON(pAd))
-	{
-		ATE_BBP_IO_READ8_BY_REG_ID(pAd, offset, &bbp_data);
-	}
-	else
-	{
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, offset, &bbp_data);
-	}
-
-	/* confirm again */
-	ASSERT(bbp_data == value);
-
-	switch (offset)
-	{
-		case BBP_R1:
-			/* Need to synchronize tx configuration with legacy ATE. */
-			tmp = (bbp_data & ((1 << 4) | (1 << 3))/* 0x18 */) >> 3;
-		    switch (tmp)
-		    {
-				/* The BBP R1 bit[4:3] = 2 :: Both DACs will be used by QA. */
-		        case 2:
-					/* All */
-					pAd->ate.TxAntennaSel = 0;
-		            break;
-				/* The BBP R1 bit[4:3] = 0 :: DAC 0 will be used by QA. */
-		        case 0:
-					/* Antenna one */
-					pAd->ate.TxAntennaSel = 1;
-		            break;
-				/* The BBP R1 bit[4:3] = 1 :: DAC 1 will be used by QA. */
-		        case 1:
-					/* Antenna two */
-					pAd->ate.TxAntennaSel = 2;
-		            break;
-		        default:
-		            DBGPRINT(RT_DEBUG_TRACE, ("%s -- Sth. wrong!  : return FALSE; \n", __FUNCTION__));
-		            return FALSE;
-		    }
-			break;/* case BBP_R1 */
-
-		case BBP_R3:
-			/* Need to synchronize rx configuration with legacy ATE. */
-			tmp = (bbp_data & ((1 << 1) | (1 << 0))/* 0x03 */);
-		    switch(tmp)
-		    {
-				/* The BBP R3 bit[1:0] = 3 :: All ADCs will be used by QA. */
-		        case 3:
-					/* All */
-					pAd->ate.RxAntennaSel = 0;
-		            break;
-				/*
-					The BBP R3 bit[1:0] = 0 :: ADC 0 will be used by QA,
-					unless the BBP R3 bit[4:3] = 2
-				*/
-		        case 0:
-					/* Antenna one */
-					pAd->ate.RxAntennaSel = 1;
-					tmp = ((bbp_data & ((1 << 4) | (1 << 3))/* 0x03 */) >> 3);
-					if (tmp == 2)// 3R
-					{
-						/* Default : All ADCs will be used by QA */
-						pAd->ate.RxAntennaSel = 0;
-					}
-		            break;
-				/* The BBP R3 bit[1:0] = 1 :: ADC 1 will be used by QA. */
-		        case 1:
-					/* Antenna two */
-					pAd->ate.RxAntennaSel = 2;
-		            break;
-				/* The BBP R3 bit[1:0] = 2 :: ADC 2 will be used by QA. */
-		        case 2:
-					/* Antenna three */
-					pAd->ate.RxAntennaSel = 3;
-		            break;
-		        default:
-		            DBGPRINT(RT_DEBUG_ERROR, ("%s -- Impossible!  : return FALSE; \n", __FUNCTION__));
-		            return FALSE;
-		    }
-			break;/* case BBP_R3 */
-
-        default:
-            DBGPRINT(RT_DEBUG_ERROR, ("%s -- Sth. wrong!  : return FALSE; \n", __FUNCTION__));
-            return FALSE;
-
-	}
-	return TRUE;
-}
-
-
-static VOID memcpy_exl(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len)
-{
-	ULONG i, Value = 0;
-	ULONG *pDst, *pSrc;
-	UCHAR *p8;
-
-	p8 = src;
-	pDst = (ULONG *) dst;
-	pSrc = (ULONG *) src;
-
-	for (i = 0 ; i < (len/4); i++)
-	{
-		/* For alignment issue, we need a variable "Value". */
-		memmove(&Value, pSrc, 4);
-		Value = htonl(Value);
-		memmove(pDst, &Value, 4);
-		pDst++;
-		pSrc++;
-	}
-	if ((len % 4) != 0)
-	{
-		/* wish that it will never reach here */
-		memmove(&Value, pSrc, (len % 4));
-		Value = htonl(Value);
-		memmove(pDst, &Value, (len % 4));
-	}
-}
-
-
-static VOID memcpy_exs(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len)
-{
-	ULONG i;
-	UCHAR *pDst, *pSrc;
-
-	pDst = dst;
-	pSrc = src;
-
-	for (i = 0; i < (len/2); i++)
-	{
-		memmove(pDst, pSrc, 2);
-		*((USHORT *)pDst) = htons(*((USHORT *)pDst));
-		pDst+=2;
-		pSrc+=2;
-	}
-
-	if ((len % 2) != 0)
-	{
-		memmove(pDst, pSrc, 1);
-	}
-}
-
-
-static VOID RTMP_IO_READ_BULK(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, UINT32 len)
-{
-	UINT32 i, Value;
-	UINT32 *pDst, *pSrc;
-
-	pDst = (UINT32 *) dst;
-	pSrc = (UINT32 *) src;
-
-	for (i = 0 ; i < (len/4); i++)
-	{
-		RTMP_IO_READ32(pAd, (ULONG)pSrc, &Value);
-		Value = htonl(Value);
-		memmove(pDst, &Value, 4);
-		pDst++;
-		pSrc++;
-	}
-	return;
-}
-
-
-INT Set_TxStop_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	ATEDBGPRINT(RT_DEBUG_TRACE,("Set_TxStop_Proc\n"));
-
-	if (Set_ATE_Proc(pAd, "TXSTOP"))
-	{
-		return TRUE;
-	}
-	else
-	{
-		return FALSE;
-	}
-}
-
-
-INT Set_RxStop_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	ATEDBGPRINT(RT_DEBUG_TRACE,("Set_RxStop_Proc\n"));
-
-	if (Set_ATE_Proc(pAd, "RXSTOP"))
-	{
-		return TRUE;
-	}
-	else
-	{
-		return FALSE;
-	}
-}
-
-
-#ifdef DBG
-INT Set_EERead_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	USHORT buffer[EEPROM_SIZE/2];
-	USHORT *p;
-	INT i;
-
-	rt_ee_read_all(pAd, (USHORT *)buffer);
-	p = buffer;
-
-	for (i = 0; i < (EEPROM_SIZE/2); i++)
-	{
-		ate_print(KERN_EMERG "%4.4x ", *p);
-		if (((i+1) % 16) == 0)
-			ate_print(KERN_EMERG "\n");
-		p++;
-	}
-
-	return TRUE;
-}
-
-
-INT Set_EEWrite_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	USHORT offset = 0, value;
-	PSTRING p2 = arg;
-
-	while ((*p2 != ':') && (*p2 != '\0'))
-	{
-		p2++;
-	}
-
-	if (*p2 == ':')
-	{
-		A2Hex(offset, arg);
-		A2Hex(value, p2 + 1);
-	}
-	else
-	{
-		A2Hex(value, arg);
-	}
-
-	if (offset >= EEPROM_SIZE)
-	{
-		ate_print(KERN_EMERG "Offset can not exceed EEPROM_SIZE( == 0x%04x)\n", EEPROM_SIZE);
-		return FALSE;
-	}
-
-	RT28xx_EEPROM_WRITE16(pAd, offset, value);
-
-	return TRUE;
-}
-
-
-INT Set_BBPRead_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	UCHAR value = 0, offset;
-
-	A2Hex(offset, arg);
-
-	if (ATE_ON(pAd))
-	{
-		ATE_BBP_IO_READ8_BY_REG_ID(pAd, offset,  &value);
-	}
-	else
-	{
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, offset,  &value);
-	}
-
-	ate_print(KERN_EMERG "%x\n", value);
-
-	return TRUE;
-}
-
-
-INT Set_BBPWrite_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	USHORT offset = 0;
-	PSTRING p2 = arg;
-	UCHAR value;
-
-	while ((*p2 != ':') && (*p2 != '\0'))
-	{
-		p2++;
-	}
-
-	if (*p2 == ':')
-	{
-		A2Hex(offset, arg);
-		A2Hex(value, p2 + 1);
-	}
-	else
-	{
-		A2Hex(value, arg);
-	}
-
-	if (ATE_ON(pAd))
-	{
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, offset,  value);
-	}
-	else
-	{
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, offset,  value);
-	}
-
-	return TRUE;
-}
-
-
-INT Set_RFWrite_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	PSTRING p2, p3, p4;
-	UINT32 R1, R2, R3, R4;
-
-	p2 = arg;
-
-	while ((*p2 != ':') && (*p2 != '\0'))
-	{
-		p2++;
-	}
-
-	if (*p2 != ':')
-		return FALSE;
-
-	p3 = p2 + 1;
-
-	while((*p3 != ':') && (*p3 != '\0'))
-	{
-		p3++;
-	}
-
-	if (*p3 != ':')
-		return FALSE;
-
-	p4 = p3 + 1;
-
-	while ((*p4 != ':') && (*p4 != '\0'))
-	{
-		p4++;
-	}
-
-	if (*p4 != ':')
-		return FALSE;
-
-
-	A2Hex(R1, arg);
-	A2Hex(R2, p2 + 1);
-	A2Hex(R3, p3 + 1);
-	A2Hex(R4, p4 + 1);
-
-	RTMP_RF_IO_WRITE32(pAd, R1);
-	RTMP_RF_IO_WRITE32(pAd, R2);
-	RTMP_RF_IO_WRITE32(pAd, R3);
-	RTMP_RF_IO_WRITE32(pAd, R4);
-
-	return TRUE;
-}
-#endif // DBG //
-#endif // RALINK_28xx_QA //
-
-
-
-
-#ifdef RALINK_28xx_QA
-#define	LEN_OF_ARG 16
-
-#define RESPONSE_TO_GUI(__pRaCfg, __pwrq, __Length, __Status)									\
-	(__pRaCfg)->length = htons((__Length));														\
-	(__pRaCfg)->status = htons((__Status));														\
-	(__pwrq)->u.data.length = sizeof((__pRaCfg)->magic_no) + sizeof((__pRaCfg)->command_type)	\
-							+ sizeof((__pRaCfg)->command_id) + sizeof((__pRaCfg)->length)		\
-							+ sizeof((__pRaCfg)->sequence) + ntohs((__pRaCfg)->length);			\
-	ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", (__pwrq)->u.data.length));		\
-	if (copy_to_user((__pwrq)->u.data.pointer, (UCHAR *)(__pRaCfg), (__pwrq)->u.data.length))	\
-	{																							\
-		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in %s\n", __FUNCTION__));				\
-		return (-EFAULT);																		\
-	}																							\
-	else																						\
-	{																							\
-		ATEDBGPRINT(RT_DEBUG_TRACE, ("%s is done !\n", __FUNCTION__));							\
-	}
-
-static inline INT	DO_RACFG_CMD_ATE_START(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START\n"));
-
-	/* Prepare feedback as soon as we can to avoid QA timeout. */
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-	Set_ATE_Proc(pAdapter, "ATESTART");
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_STOP(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	INT32 ret;
-
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_STOP\n"));
-
-	/*
-		Distinguish this command came from QA(via ate agent)
-		or ate agent according to the existence of pid in payload.
-
-		No need to prepare feedback if this cmd came directly from ate agent,
-		not from QA.
-	*/
-	pRaCfg->length = ntohs(pRaCfg->length);
-
-	if (pRaCfg->length == sizeof(pAdapter->ate.AtePid))
-	{
-		/*
-			This command came from QA.
-			Get the pid of ATE agent.
-		*/
-		memcpy((UCHAR *)&pAdapter->ate.AtePid,
-						(&pRaCfg->data[0]) - 2/* == sizeof(pRaCfg->status) */,
-						sizeof(pAdapter->ate.AtePid));
-
-		/* Prepare feedback as soon as we can to avoid QA timeout. */
-		RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-		/*
-			Kill ATE agent when leaving ATE mode.
-
-			We must kill ATE agent first before setting ATESTOP,
-			or Microsoft will report sth. wrong.
-		*/
-		ret = KILL_THREAD_PID(pAdapter->ate.AtePid, SIGTERM, 1);
-
-		if (ret)
-		{
-			ATEDBGPRINT(RT_DEBUG_ERROR, ("%s: unable to kill ate thread\n", pAdapter->net_dev->name));
-		}
-	}
-
-
-	/* AP/STA might have in ATE_STOP mode due to cmd from QA. */
-	if (ATE_ON(pAdapter))
-	{
-		/* Someone has killed ate agent while QA GUI is still open. */
-		Set_ATE_Proc(pAdapter, "ATESTOP");
-		ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_AP_START is done !\n"));
-	}
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_RF_WRITE_ALL(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	UINT32 R1, R2, R3, R4;
-	USHORT channel;
-
-	memcpy(&R1, pRaCfg->data-2, 4);
-	memcpy(&R2, pRaCfg->data+2, 4);
-	memcpy(&R3, pRaCfg->data+6, 4);
-	memcpy(&R4, pRaCfg->data+10, 4);
-	memcpy(&channel, pRaCfg->data+14, 2);
-
-	pAdapter->LatchRfRegs.R1 = ntohl(R1);
-	pAdapter->LatchRfRegs.R2 = ntohl(R2);
-	pAdapter->LatchRfRegs.R3 = ntohl(R3);
-	pAdapter->LatchRfRegs.R4 = ntohl(R4);
-	pAdapter->LatchRfRegs.Channel = ntohs(channel);
-
-	RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R1);
-	RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R2);
-	RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R3);
-	RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R4);
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return  NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_E2PROM_READ16(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	UINT16	offset=0, value=0;
-	USHORT  tmp=0;
-
-	offset = ntohs(pRaCfg->status);
-
-	/* "tmp" is especially for some compilers... */
-	RT28xx_EEPROM_READ16(pAdapter, offset, tmp);
-	value = tmp;
-	value = htons(value);
-
-	ATEDBGPRINT(RT_DEBUG_TRACE,("EEPROM Read offset = 0x%04x, value = 0x%04x\n", offset, value));
-	memcpy(pRaCfg->data, &value, 2);
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+2, NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_E2PROM_WRITE16(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	USHORT	offset, value;
-
-	offset = ntohs(pRaCfg->status);
-	memcpy(&value, pRaCfg->data, 2);
-	value = ntohs(value);
-	RT28xx_EEPROM_WRITE16(pAdapter, offset, value);
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_E2PROM_READ_ALL(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	USHORT buffer[EEPROM_SIZE/2];
-
-	rt_ee_read_all(pAdapter,(USHORT *)buffer);
-	memcpy_exs(pAdapter, pRaCfg->data, (UCHAR *)buffer, EEPROM_SIZE);
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+EEPROM_SIZE, NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_E2PROM_WRITE_ALL(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	USHORT buffer[EEPROM_SIZE/2];
-
-	NdisZeroMemory((UCHAR *)buffer, EEPROM_SIZE);
-	memcpy_exs(pAdapter, (UCHAR *)buffer, (UCHAR *)&pRaCfg->status, EEPROM_SIZE);
-	rt_ee_write_all(pAdapter,(USHORT *)buffer);
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_IO_READ(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	UINT32	offset;
-	UINT32	value;
-
-	memcpy(&offset, &pRaCfg->status, 4);
-	offset = ntohl(offset);
-
-	/*
-		We do not need the base address.
-		So just extract the offset out.
-	*/
-	offset &= 0x0000FFFF;
-	RTMP_IO_READ32(pAdapter, offset, &value);
-	value = htonl(value);
-	memcpy(pRaCfg->data, &value, 4);
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+4, NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_IO_WRITE(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	UINT32	offset, value;
-
-	memcpy(&offset, pRaCfg->data-2, 4);
-	memcpy(&value, pRaCfg->data+2, 4);
-
-	offset = ntohl(offset);
-
-	/*
-		We do not need the base address.
-		So just extract the offset out.
-	*/
-	offset &= 0x0000FFFF;
-	value = ntohl(value);
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_IO_WRITE: offset = %x, value = %x\n", offset, value));
-	RTMP_IO_WRITE32(pAdapter, offset, value);
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_IO_READ_BULK(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	UINT32	offset;
-	USHORT	len;
-
-	memcpy(&offset, &pRaCfg->status, 4);
-	offset = ntohl(offset);
-
-	/*
-		We do not need the base address.
-		So just extract the offset out.
-	*/
-	offset &= 0x0000FFFF;
-	memcpy(&len, pRaCfg->data+2, 2);
-	len = ntohs(len);
-
-	if (len > 371)
-	{
-		ATEDBGPRINT(RT_DEBUG_TRACE,("length requested is too large, make it smaller\n"));
-		pRaCfg->length = htons(2);
-		pRaCfg->status = htons(1);
-		return -EFAULT;
-	}
-
-	RTMP_IO_READ_BULK(pAdapter, pRaCfg->data, (UCHAR *)offset, len*4);// unit in four bytes
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+(len*4), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_BBP_READ8(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	USHORT	offset;
-	UCHAR	value;
-
-	value = 0;
-	offset = ntohs(pRaCfg->status);
-
-	if (ATE_ON(pAdapter))
-	{
-		ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, offset, &value);
-	}
-	else
-	{
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, offset, &value);
-	}
-
-	pRaCfg->data[0] = value;
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+1, NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_BBP_WRITE8(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	USHORT	offset;
-	UCHAR	value;
-
-	offset = ntohs(pRaCfg->status);
-	memcpy(&value, pRaCfg->data, 1);
-
-	if (ATE_ON(pAdapter))
-	{
-		ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, offset, value);
-	}
-	else
-	{
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, offset, value);
-	}
-
-	if ((offset == BBP_R1) || (offset == BBP_R3))
-	{
-		SyncTxRxConfig(pAdapter, offset, value);
-	}
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_BBP_READ_ALL(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	USHORT bbp_reg_index;
-
-	for (bbp_reg_index = 0; bbp_reg_index < MAX_BBP_ID+1; bbp_reg_index++)
-	{
-		pRaCfg->data[bbp_reg_index] = 0;
-
-		if (ATE_ON(pAdapter))
-		{
-			ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbp_reg_index, &pRaCfg->data[bbp_reg_index]);
-		}
-		else
-		{
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbp_reg_index, &pRaCfg->data[bbp_reg_index]);
-		}
-	}
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+MAX_BBP_ID+1, NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_GET_NOISE_LEVEL(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	UCHAR	channel;
-	INT32   buffer[3][10];/* 3 : RxPath ; 10 : no. of per rssi samples */
-
-	channel = (ntohs(pRaCfg->status) & 0x00FF);
-	CalNoiseLevel(pAdapter, channel, buffer);
-	memcpy_exl(pAdapter, (UCHAR *)pRaCfg->data, (UCHAR *)&(buffer[0][0]), (sizeof(INT32)*3*10));
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+(sizeof(INT32)*3*10), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_GET_COUNTER(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	memcpy_exl(pAdapter, &pRaCfg->data[0], (UCHAR *)&pAdapter->ate.U2M, 4);
-	memcpy_exl(pAdapter, &pRaCfg->data[4], (UCHAR *)&pAdapter->ate.OtherData, 4);
-	memcpy_exl(pAdapter, &pRaCfg->data[8], (UCHAR *)&pAdapter->ate.Beacon, 4);
-	memcpy_exl(pAdapter, &pRaCfg->data[12], (UCHAR *)&pAdapter->ate.OtherCount, 4);
-	memcpy_exl(pAdapter, &pRaCfg->data[16], (UCHAR *)&pAdapter->ate.TxAc0, 4);
-	memcpy_exl(pAdapter, &pRaCfg->data[20], (UCHAR *)&pAdapter->ate.TxAc1, 4);
-	memcpy_exl(pAdapter, &pRaCfg->data[24], (UCHAR *)&pAdapter->ate.TxAc2, 4);
-	memcpy_exl(pAdapter, &pRaCfg->data[28], (UCHAR *)&pAdapter->ate.TxAc3, 4);
-	/*memcpy_exl(pAdapter, &pRaCfg->data[32], (UCHAR *)&pAdapter->ate.TxHCCA, 4);*/
-	memcpy_exl(pAdapter, &pRaCfg->data[36], (UCHAR *)&pAdapter->ate.TxMgmt, 4);
-	memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&pAdapter->ate.RSSI0, 4);
-	memcpy_exl(pAdapter, &pRaCfg->data[44], (UCHAR *)&pAdapter->ate.RSSI1, 4);
-	memcpy_exl(pAdapter, &pRaCfg->data[48], (UCHAR *)&pAdapter->ate.RSSI2, 4);
-	memcpy_exl(pAdapter, &pRaCfg->data[52], (UCHAR *)&pAdapter->ate.SNR0, 4);
-	memcpy_exl(pAdapter, &pRaCfg->data[56], (UCHAR *)&pAdapter->ate.SNR1, 4);
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+60, NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_CLEAR_COUNTER(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	pAdapter->ate.U2M = 0;
-	pAdapter->ate.OtherData = 0;
-	pAdapter->ate.Beacon = 0;
-	pAdapter->ate.OtherCount = 0;
-	pAdapter->ate.TxAc0 = 0;
-	pAdapter->ate.TxAc1 = 0;
-	pAdapter->ate.TxAc2 = 0;
-	pAdapter->ate.TxAc3 = 0;
-	/*pAdapter->ate.TxHCCA = 0;*/
-	pAdapter->ate.TxMgmt = 0;
-	pAdapter->ate.TxDoneCount = 0;
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_TX_START(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	USHORT *p;
-	USHORT	err = 1;
-	UCHAR   Bbp22Value = 0, Bbp24Value = 0;
-
-	if ((pAdapter->ate.TxStatus != 0) && (pAdapter->ate.Mode & ATE_TXFRAME))
-	{
-		ATEDBGPRINT(RT_DEBUG_TRACE,("Ate Tx is already running, to run next Tx, you must stop it first\n"));
-		err = 2;
-		goto TX_START_ERROR;
-	}
-	else if ((pAdapter->ate.TxStatus != 0) && !(pAdapter->ate.Mode & ATE_TXFRAME))
-	{
-		int i = 0;
-
-		while ((i++ < 10) && (pAdapter->ate.TxStatus != 0))
-		{
-			RTMPusecDelay(5000);
-		}
-
-		/* force it to stop */
-		pAdapter->ate.TxStatus = 0;
-		pAdapter->ate.TxDoneCount = 0;
-		pAdapter->ate.bQATxStart = FALSE;
-	}
-
-	/*
-		If pRaCfg->length == 0, this "RACFG_CMD_TX_START"
-		is for Carrier test or Carrier Suppression.
-	*/
-	if (ntohs(pRaCfg->length) != 0)
-	{
-		/* get frame info */
-
-		NdisMoveMemory(&pAdapter->ate.TxWI, pRaCfg->data + 2, 16);
-#ifdef RT_BIG_ENDIAN
-		RTMPWIEndianChange((PUCHAR)&pAdapter->ate.TxWI, TYPE_TXWI);
-#endif // RT_BIG_ENDIAN //
-
-		NdisMoveMemory(&pAdapter->ate.TxCount, pRaCfg->data + 18, 4);
-		pAdapter->ate.TxCount = ntohl(pAdapter->ate.TxCount);
-
-		p = (USHORT *)(&pRaCfg->data[22]);
-
-		/* always use QID_AC_BE */
-		pAdapter->ate.QID = 0;
-
-		p = (USHORT *)(&pRaCfg->data[24]);
-		pAdapter->ate.HLen = ntohs(*p);
-
-		if (pAdapter->ate.HLen > 32)
-		{
-			ATEDBGPRINT(RT_DEBUG_ERROR,("pAdapter->ate.HLen > 32\n"));
-			err = 3;
-			goto TX_START_ERROR;
-		}
-
-		NdisMoveMemory(&pAdapter->ate.Header, pRaCfg->data + 26, pAdapter->ate.HLen);
-
-		pAdapter->ate.PLen = ntohs(pRaCfg->length) - (pAdapter->ate.HLen + 28);
-
-		if (pAdapter->ate.PLen > 32)
-		{
-			ATEDBGPRINT(RT_DEBUG_ERROR,("pAdapter->ate.PLen > 32\n"));
-			err = 4;
-			goto TX_START_ERROR;
-		}
-
-		NdisMoveMemory(&pAdapter->ate.Pattern, pRaCfg->data + 26 + pAdapter->ate.HLen, pAdapter->ate.PLen);
-		pAdapter->ate.DLen = pAdapter->ate.TxWI.MPDUtotalByteCount - pAdapter->ate.HLen;
-	}
-
-	ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R22, &Bbp22Value);
-
-	switch (Bbp22Value)
-	{
-		case BBP22_TXFRAME:
-			{
-				if (pAdapter->ate.TxCount == 0)
-				{
-#ifdef RTMP_MAC_PCI
-					pAdapter->ate.TxCount = 0xFFFFFFFF;
-#endif // RTMP_MAC_PCI //
-				}
-				ATEDBGPRINT(RT_DEBUG_TRACE,("START TXFRAME\n"));
-				pAdapter->ate.bQATxStart = TRUE;
-				Set_ATE_Proc(pAdapter, "TXFRAME");
-			}
-			break;
-
-		case BBP22_TXCONT_OR_CARRSUPP:
-			{
-				ATEDBGPRINT(RT_DEBUG_TRACE,("BBP22_TXCONT_OR_CARRSUPP\n"));
-				ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R24, &Bbp24Value);
-
-				switch (Bbp24Value)
-				{
-					case BBP24_TXCONT:
-						{
-							ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCONT\n"));
-							pAdapter->ate.bQATxStart = TRUE;
-							Set_ATE_Proc(pAdapter, "TXCONT");
-						}
-						break;
-
-					case BBP24_CARRSUPP:
-						{
-							ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCARRSUPP\n"));
-							pAdapter->ate.bQATxStart = TRUE;
-							pAdapter->ate.Mode |= ATE_TXCARRSUPP;
-						}
-						break;
-
-					default:
-						{
-							ATEDBGPRINT(RT_DEBUG_ERROR,("Unknown TX subtype !"));
-						}
-						break;
-				}
-			}
-			break;
-
-		case BBP22_TXCARR:
-			{
-				ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCARR\n"));
-				pAdapter->ate.bQATxStart = TRUE;
-				Set_ATE_Proc(pAdapter, "TXCARR");
-			}
-			break;
-
-		default:
-			{
-				ATEDBGPRINT(RT_DEBUG_ERROR,("Unknown Start TX subtype !"));
-			}
-			break;
-	}
-
-	if (pAdapter->ate.bQATxStart == TRUE)
-	{
-		RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-		return NDIS_STATUS_SUCCESS;
-	}
-
-TX_START_ERROR:
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), err);
-
-	return err;
-}
-
-
-static inline INT DO_RACFG_CMD_GET_TX_STATUS(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	UINT32 count=0;
-
-	count = htonl(pAdapter->ate.TxDoneCount);
-	NdisMoveMemory(pRaCfg->data, &count, 4);
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+4, NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_TX_STOP(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_TX_STOP\n"));
-
-	Set_ATE_Proc(pAdapter, "TXSTOP");
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_RX_START(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_START\n"));
-
-	pAdapter->ate.bQARxStart = TRUE;
-	Set_ATE_Proc(pAdapter, "RXFRAME");
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_RX_STOP(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_STOP\n"));
-
-	Set_ATE_Proc(pAdapter, "RXSTOP");
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_START_TX_CARRIER(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_CARRIER\n"));
-
-	Set_ATE_Proc(pAdapter, "TXCARR");
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_START_TX_CONT(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_CONT\n"));
-
-	Set_ATE_Proc(pAdapter, "TXCONT");
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_START_TX_FRAME(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_FRAME\n"));
-
-	Set_ATE_Proc(pAdapter, "TXFRAME");
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_SET_BW(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	SHORT    value = 0;
-	STRING    str[LEN_OF_ARG];
-
-	NdisZeroMemory(str, LEN_OF_ARG);
-
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_BW\n"));
-
-	memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
-	value = ntohs(value);
-	sprintf((char *)str, "%d", value);
-
-	Set_ATE_TX_BW_Proc(pAdapter, str);
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_SET_TX_POWER0(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	SHORT    value = 0;
-	STRING    str[LEN_OF_ARG];
-
-	NdisZeroMemory(str, LEN_OF_ARG);
-
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_POWER0\n"));
-
-	memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
-	value = ntohs(value);
-	sprintf((char *)str, "%d", value);
-	Set_ATE_TX_POWER0_Proc(pAdapter, str);
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_SET_TX_POWER1(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	SHORT    value = 0;
-	STRING    str[LEN_OF_ARG];
-
-	NdisZeroMemory(str, LEN_OF_ARG);
-
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_POWER1\n"));
-
-	memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
-	value = ntohs(value);
-	sprintf((char *)str, "%d", value);
-	Set_ATE_TX_POWER1_Proc(pAdapter, str);
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_SET_FREQ_OFFSET(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	SHORT    value = 0;
-	STRING    str[LEN_OF_ARG];
-
-	NdisZeroMemory(str, LEN_OF_ARG);
-
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_FREQ_OFFSET\n"));
-
-	memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
-	value = ntohs(value);
-	sprintf((char *)str, "%d", value);
-	Set_ATE_TX_FREQOFFSET_Proc(pAdapter, str);
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_GET_STATISTICS(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_GET_STATISTICS\n"));
-
-	memcpy_exl(pAdapter, &pRaCfg->data[0], (UCHAR *)&pAdapter->ate.TxDoneCount, 4);
-	memcpy_exl(pAdapter, &pRaCfg->data[4], (UCHAR *)&pAdapter->WlanCounters.RetryCount.u.LowPart, 4);
-	memcpy_exl(pAdapter, &pRaCfg->data[8], (UCHAR *)&pAdapter->WlanCounters.FailedCount.u.LowPart, 4);
-	memcpy_exl(pAdapter, &pRaCfg->data[12], (UCHAR *)&pAdapter->WlanCounters.RTSSuccessCount.u.LowPart, 4);
-	memcpy_exl(pAdapter, &pRaCfg->data[16], (UCHAR *)&pAdapter->WlanCounters.RTSFailureCount.u.LowPart, 4);
-	memcpy_exl(pAdapter, &pRaCfg->data[20], (UCHAR *)&pAdapter->WlanCounters.ReceivedFragmentCount.QuadPart, 4);
-	memcpy_exl(pAdapter, &pRaCfg->data[24], (UCHAR *)&pAdapter->WlanCounters.FCSErrorCount.u.LowPart, 4);
-	memcpy_exl(pAdapter, &pRaCfg->data[28], (UCHAR *)&pAdapter->Counters8023.RxNoBuffer, 4);
-	memcpy_exl(pAdapter, &pRaCfg->data[32], (UCHAR *)&pAdapter->WlanCounters.FrameDuplicateCount.u.LowPart, 4);
-	memcpy_exl(pAdapter, &pRaCfg->data[36], (UCHAR *)&pAdapter->RalinkCounters.OneSecFalseCCACnt, 4);
-
-	if (pAdapter->ate.RxAntennaSel == 0)
-	{
-		INT32 RSSI0 = 0;
-		INT32 RSSI1 = 0;
-		INT32 RSSI2 = 0;
-
-		RSSI0 = (INT32)(pAdapter->ate.LastRssi0 - pAdapter->BbpRssiToDbmDelta);
-		RSSI1 = (INT32)(pAdapter->ate.LastRssi1 - pAdapter->BbpRssiToDbmDelta);
-		RSSI2 = (INT32)(pAdapter->ate.LastRssi2 - pAdapter->BbpRssiToDbmDelta);
-		memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&RSSI0, 4);
-		memcpy_exl(pAdapter, &pRaCfg->data[44], (UCHAR *)&RSSI1, 4);
-		memcpy_exl(pAdapter, &pRaCfg->data[48], (UCHAR *)&RSSI2, 4);
-		RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+52, NDIS_STATUS_SUCCESS);
-	}
-	else
-	{
-		INT32 RSSI0 = 0;
-
-		RSSI0 = (INT32)(pAdapter->ate.LastRssi0 - pAdapter->BbpRssiToDbmDelta);
-		memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&RSSI0, 4);
-		RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+44, NDIS_STATUS_SUCCESS);
-	}
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_RESET_COUNTER(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	SHORT    value = 1;
-	STRING    str[LEN_OF_ARG];
-
-	NdisZeroMemory(str, LEN_OF_ARG);
-
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_RESET_COUNTER\n"));
-
-	sprintf((char *)str, "%d", value);
-	Set_ResetStatCounter_Proc(pAdapter, str);
-
-	pAdapter->ate.TxDoneCount = 0;
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_SEL_TX_ANTENNA(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	SHORT    value = 0;
-	STRING    str[LEN_OF_ARG];
-
-	NdisZeroMemory(str, LEN_OF_ARG);
-
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SEL_TX_ANTENNA\n"));
-
-	memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
-	value = ntohs(value);
-	sprintf((char *)str, "%d", value);
-	Set_ATE_TX_Antenna_Proc(pAdapter, str);
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_SEL_RX_ANTENNA(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	SHORT    value = 0;
-	STRING    str[LEN_OF_ARG];
-
-	NdisZeroMemory(str, LEN_OF_ARG);
-
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SEL_RX_ANTENNA\n"));
-
-	memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
-	value = ntohs(value);
-	sprintf((char *)str, "%d", value);
-	Set_ATE_RX_Antenna_Proc(pAdapter, str);
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_SET_PREAMBLE(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	SHORT    value = 0;
-	STRING    str[LEN_OF_ARG];
-
-	NdisZeroMemory(str, LEN_OF_ARG);
-
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_PREAMBLE\n"));
-
-	memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
-	value = ntohs(value);
-	sprintf((char *)str, "%d", value);
-	Set_ATE_TX_MODE_Proc(pAdapter, str);
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_SET_CHANNEL(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	SHORT    value = 0;
-	STRING    str[LEN_OF_ARG];
-
-	NdisZeroMemory(str, LEN_OF_ARG);
-
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_CHANNEL\n"));
-
-	memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
-	value = ntohs(value);
-	sprintf((char *)str, "%d", value);
-	Set_ATE_CHANNEL_Proc(pAdapter, str);
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_SET_ADDR1(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR1\n"));
-
-	/*
-		Addr is an array of UCHAR,
-		so no need to perform endian swap.
-	*/
-	memcpy(pAdapter->ate.Addr1, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_SET_ADDR2(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR2\n"));
-
-	/*
-		Addr is an array of UCHAR,
-		so no need to perform endian swap.
-	*/
-	memcpy(pAdapter->ate.Addr2, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_SET_ADDR3(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR3\n"));
-
-	/*
-		Addr is an array of UCHAR,
-		so no need to perform endian swap.
-	*/
-	memcpy(pAdapter->ate.Addr3, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_SET_RATE(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	SHORT    value = 0;
-	STRING    str[LEN_OF_ARG];
-
-	NdisZeroMemory(str, LEN_OF_ARG);
-
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_RATE\n"));
-
-	memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
-	value = ntohs(value);
-	sprintf((char *)str, "%d", value);
-	Set_ATE_TX_MCS_Proc(pAdapter, str);
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_SET_TX_FRAME_LEN(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	SHORT    value = 0;
-	STRING    str[LEN_OF_ARG];
-
-	NdisZeroMemory(str, LEN_OF_ARG);
-
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_FRAME_LEN\n"));
-
-	memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
-	value = ntohs(value);
-	sprintf((char *)str, "%d", value);
-	Set_ATE_TX_LENGTH_Proc(pAdapter, str);
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_SET_TX_FRAME_COUNT(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	USHORT    value = 0;
-	STRING    str[LEN_OF_ARG];
-
-	NdisZeroMemory(str, LEN_OF_ARG);
-
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_FRAME_COUNT\n"));
-
-	memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
-	value = ntohs(value);
-
-#ifdef RTMP_MAC_PCI
-	/* TX_FRAME_COUNT == 0 means tx infinitely */
-	if (value == 0)
-	{
-		/* Use TxCount = 0xFFFFFFFF to approximate the infinity. */
-		pAdapter->ate.TxCount = 0xFFFFFFFF;
-		ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_COUNT_Proc (TxCount = %d)\n", pAdapter->ate.TxCount));
-		ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_COUNT_Proc Success\n"));
-
-
-	}
-	else
-#endif // RTMP_MAC_PCI //
-	{
-		sprintf((char *)str, "%d", value);
-		Set_ATE_TX_COUNT_Proc(pAdapter, str);
-	}
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_START_RX_FRAME(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_START\n"));
-
-	Set_ATE_Proc(pAdapter, "RXFRAME");
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_E2PROM_READ_BULK(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	USHORT offset;
-	USHORT len;
-	USHORT buffer[EEPROM_SIZE/2];
-
-	offset = ntohs(pRaCfg->status);
-	memcpy(&len, pRaCfg->data, 2);
-	len = ntohs(len);
-
-	rt_ee_read_all(pAdapter, (USHORT *)buffer);
-
-	if (offset + len <= EEPROM_SIZE)
-		memcpy_exs(pAdapter, pRaCfg->data, (UCHAR *)buffer+offset, len);
-	else
-		ATEDBGPRINT(RT_DEBUG_ERROR, ("exceed EEPROM size\n"));
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+len, NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_E2PROM_WRITE_BULK(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	USHORT offset;
-	USHORT len;
-	USHORT buffer[EEPROM_SIZE/2];
-
-	offset = ntohs(pRaCfg->status);
-	memcpy(&len, pRaCfg->data, 2);
-	len = ntohs(len);
-
-	rt_ee_read_all(pAdapter,(USHORT *)buffer);
-	memcpy_exs(pAdapter, (UCHAR *)buffer + offset, (UCHAR *)pRaCfg->data + 2, len);
-	rt_ee_write_all(pAdapter,(USHORT *)buffer);
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_IO_WRITE_BULK(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	UINT32 offset, i, value;
-	USHORT len;
-
-	memcpy(&offset, &pRaCfg->status, 4);
-	offset = ntohl(offset);
-	memcpy(&len, pRaCfg->data+2, 2);
-	len = ntohs(len);
-
-	for (i = 0; i < len; i += 4)
-	{
-		memcpy_exl(pAdapter, (UCHAR *)&value, pRaCfg->data+4+i, 4);
-		ATEDBGPRINT(RT_DEBUG_TRACE,("Write %x %x\n", offset + i, value));
-		RTMP_IO_WRITE32(pAdapter, ((offset+i) & (0xffff)), value);
-	}
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_BBP_READ_BULK(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	USHORT offset;
-	USHORT len;
-	USHORT j;
-
-	offset = ntohs(pRaCfg->status);
-	memcpy(&len, pRaCfg->data, 2);
-	len = ntohs(len);
-
-	for (j = offset; j < (offset+len); j++)
-	{
-		pRaCfg->data[j - offset] = 0;
-
-		if (pAdapter->ate.Mode == ATE_STOP)
-		{
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j - offset]);
-		}
-		else
-		{
-			ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j - offset]);
-		}
-	}
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+len, NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-static inline INT DO_RACFG_CMD_ATE_BBP_WRITE_BULK(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq,
-	IN  struct ate_racfghdr *pRaCfg)
-{
-	USHORT offset;
-	USHORT len;
-	USHORT j;
-	UCHAR *value;
-
-	offset = ntohs(pRaCfg->status);
-	memcpy(&len, pRaCfg->data, 2);
-	len = ntohs(len);
-
-	for (j = offset; j < (offset+len); j++)
-	{
-		value = pRaCfg->data + 2 + (j - offset);
-		if (pAdapter->ate.Mode == ATE_STOP)
-		{
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, j,  *value);
-		}
-		else
-		{
-			ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, j,  *value);
-		}
-	}
-
-	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-#endif // RALINK_28xx_QA //
-#endif	// RALINK_ATE //
diff --git a/drivers/staging/rt3090/rt_ate.h b/drivers/staging/rt3090/rt_ate.h
deleted file mode 100644
index 38d5961..0000000
--- a/drivers/staging/rt3090/rt_ate.h
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
- */
-
-#ifndef __ATE_H__
-#define __ATE_H__
-
-
-#ifdef LINUX
-#define ate_print printk
-#define ATEDBGPRINT DBGPRINT
-#ifdef RTMP_MAC_PCI
-#define EEPROM_SIZE								0x200
-#ifdef CONFIG_STA_SUPPORT
-#define EEPROM_BIN_FILE_NAME  "/etc/Wireless/RT2860STA/e2p.bin"
-#endif // CONFIG_STA_SUPPORT //
-#endif // RTMP_MAC_PCI //
-#endif // LINUX //
-
-
-#define ATE_ON(_p)              (((_p)->ate.Mode) != ATE_STOP)
-
-#ifdef RTMP_MAC_PCI
-#define ATE_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)        \
-{                                                       \
-    BBP_CSR_CFG_STRUC  BbpCsr;                             \
-    int             j, k;                               \
-    for (j=0; j<MAX_BUSY_COUNT; j++)                    \
-    {                                                   \
-        RTMP_IO_READ32(_A, BBP_CSR_CFG, &BbpCsr.word);     \
-        if (BbpCsr.field.Busy == BUSY)                  \
-        {                                               \
-            continue;                                   \
-        }                                               \
-        BbpCsr.word = 0;                                \
-        BbpCsr.field.fRead = 1;                         \
-        BbpCsr.field.BBP_RW_MODE = 1;                         \
-        BbpCsr.field.Busy = 1;                          \
-        BbpCsr.field.RegNum = _I;                       \
-        RTMP_IO_WRITE32(_A, BBP_CSR_CFG, BbpCsr.word);     \
-        for (k=0; k<MAX_BUSY_COUNT; k++)                \
-        {                                               \
-            RTMP_IO_READ32(_A, BBP_CSR_CFG, &BbpCsr.word); \
-            if (BbpCsr.field.Busy == IDLE)              \
-                break;                                  \
-        }                                               \
-        if ((BbpCsr.field.Busy == IDLE) &&              \
-            (BbpCsr.field.RegNum == _I))                \
-        {                                               \
-            *(_pV) = (UCHAR)BbpCsr.field.Value;         \
-            break;                                      \
-        }                                               \
-    }                                                   \
-    if (BbpCsr.field.Busy == BUSY)                      \
-    {                                                   \
-        ATEDBGPRINT(RT_DEBUG_ERROR, ("BBP read R%d fail\n", _I));      \
-        *(_pV) = (_A)->BbpWriteLatch[_I];               \
-    }                                                   \
-}
-
-#define ATE_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)        \
-{                                                       \
-    BBP_CSR_CFG_STRUC  BbpCsr;                             \
-    int             BusyCnt;                            \
-    for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++)  \
-    {                                                   \
-        RTMP_IO_READ32(_A, BBP_CSR_CFG, &BbpCsr.word);     \
-        if (BbpCsr.field.Busy == BUSY)                  \
-            continue;                                   \
-        BbpCsr.word = 0;                                \
-        BbpCsr.field.fRead = 0;                         \
-        BbpCsr.field.BBP_RW_MODE = 1;                         \
-        BbpCsr.field.Busy = 1;                          \
-        BbpCsr.field.Value = _V;                        \
-        BbpCsr.field.RegNum = _I;                       \
-        RTMP_IO_WRITE32(_A, BBP_CSR_CFG, BbpCsr.word);     \
-        (_A)->BbpWriteLatch[_I] = _V;                   \
-        break;                                          \
-    }                                                   \
-    if (BusyCnt == MAX_BUSY_COUNT)                      \
-    {                                                   \
-        ATEDBGPRINT(RT_DEBUG_ERROR, ("BBP write R%d fail\n", _I));     \
-    }                                                   \
-}
-#endif // RTMP_MAC_PCI //
-
-
-#ifdef RT30xx
-#define ATE_RF_IO_READ8_BY_REG_ID(_A, _I, _pV)     RTMP_RF_IO_READ8_BY_REG_ID(_A, _I, _pV)
-#define ATE_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V)     RTMP_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V)
-#endif // RT30xx //
-
-
-VOID rt_ee_read_all(
-	IN  PRTMP_ADAPTER   pAd,
-	OUT USHORT *Data);
-
-VOID rt_ee_write_all(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  USHORT *Data);
-
-INT Set_ATE_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_ATE_DA_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_ATE_SA_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_ATE_BSSID_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_ATE_CHANNEL_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_ATE_TX_POWER0_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_ATE_TX_POWER1_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_ATE_TX_Antenna_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_ATE_RX_Antenna_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_ATE_TX_FREQOFFSET_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_ATE_TX_BW_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_ATE_TX_LENGTH_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_ATE_TX_COUNT_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_ATE_TX_MCS_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_ATE_TX_MODE_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_ATE_TX_GI_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-
-INT	Set_ATE_RX_FER_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT Set_ATE_Read_RF_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT Set_ATE_Write_RF1_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT Set_ATE_Write_RF2_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT Set_ATE_Write_RF3_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT Set_ATE_Write_RF4_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT Set_ATE_Load_E2P_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT Set_ATE_Read_E2P_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-
-INT	Set_ATE_Show_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_ATE_Help_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-#ifdef RALINK_28xx_QA
-VOID ATE_QA_Statistics(
-	IN PRTMP_ADAPTER		pAd,
-	IN PRXWI_STRUC			pRxWI,
-	IN PRT28XX_RXD_STRUC    p28xxRxD,
-	IN PHEADER_802_11		pHeader);
-
-VOID RtmpDoAte(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq);
-
-VOID BubbleSort(
-	IN  INT32 n,
-	IN  INT32 a[]);
-
-VOID CalNoiseLevel(
-	IN  PRTMP_ADAPTER   pAdapter,
-	IN  UCHAR           channel,
-	OUT INT32           buffer[3][10]);
-
-BOOLEAN SyncTxRxConfig(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	USHORT			offset,
-	IN	UCHAR			value);
-
-INT Set_TxStop_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT Set_RxStop_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-#ifdef DBG
-INT Set_EERead_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT Set_EEWrite_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT Set_BBPRead_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT Set_BBPWrite_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT Set_RFWrite_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-#endif // DBG //
-#endif // RALINK_28xx_QA //
-
-
-VOID ATEAsicSwitchChannel(
-	IN PRTMP_ADAPTER pAd);
-
-VOID ATEAsicAdjustTxPower(
-	IN PRTMP_ADAPTER pAd);
-
-VOID ATEDisableAsicProtect(
-	IN		PRTMP_ADAPTER	pAd);
-
-CHAR ATEConvertToRssi(
-	IN PRTMP_ADAPTER  pAd,
-	IN CHAR				Rssi,
-	IN UCHAR    RssiNumber);
-
-VOID ATESampleRssi(
-	IN PRTMP_ADAPTER	pAd,
-	IN PRXWI_STRUC		pRxWI);
-
-
-#ifdef CONFIG_STA_SUPPORT
-VOID RTMPStationStop(
-    IN  PRTMP_ADAPTER   pAd);
-
-VOID RTMPStationStart(
-    IN  PRTMP_ADAPTER   pAd);
-#endif // CONFIG_STA_SUPPORT //
-#endif // __ATE_H__ //
diff --git a/drivers/staging/rt3090/rt_config.h b/drivers/staging/rt3090/rt_config.h
deleted file mode 100644
index 005142d..0000000
--- a/drivers/staging/rt3090/rt_config.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rt_config.h
-
-	Abstract:
-	Central header file to maintain all include files for all NDIS
-	miniport driver routines.
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-	Paul Lin    08-01-2002    created
-
-*/
-#ifndef	__RT_CONFIG_H__
-#define	__RT_CONFIG_H__
-
-#include "rtmp_type.h"
-#include "rtmp_os.h"
-
-#include "rtmp_def.h"
-#include "rtmp_chip.h"
-#include "rtmp_timer.h"
-
-#include "oid.h"
-#include "mlme.h"
-#include "wpa.h"
-#include "crypt_md5.h"
-#include "crypt_sha2.h"
-#include "crypt_hmac.h"
-#include "rtmp.h"
-#include "ap.h"
-#include "dfs.h"
-#include "chlist.h"
-#include "spectrum.h"
-
-#ifdef MLME_EX
-#include	"mlme_ex_def.h"
-#include	"mlme_ex.h"
-#endif // MLME_EX //
-
-#include "eeprom.h"
-#if defined(RTMP_PCI_SUPPORT) || defined(RTMP_USB_SUPPORT)
-#include "rtmp_mcu.h"
-#endif
-
-
-
-#undef AP_WSC_INCLUDED
-#undef STA_WSC_INCLUDED
-#undef WSC_INCLUDED
-
-
-
-#ifdef CONFIG_STA_SUPPORT
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef BLOCK_NET_IF
-#include "netif_block.h"
-#endif // BLOCK_NET_IF //
-
-#ifdef IGMP_SNOOP_SUPPORT
-#include "igmp_snoop.h"
-#endif // IGMP_SNOOP_SUPPORT //
-
-#ifdef RALINK_ATE
-#include "rt_ate.h"
-#endif // RALINK_ATE //
-
-#ifdef RALINK_28xx_QA
-#ifndef RALINK_ATE
-#error "For supporting QA GUI, please set HAS_ATE=y and HAS_28xx_QA=y."
-#endif // RALINK_ATE //
-#endif // RALINK_28xx_QA //
-
-
-
-
-#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
-#define WSC_INCLUDED
-#endif
-
-
-#ifdef CONFIG_STA_SUPPORT
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-#ifndef WPA_SUPPLICANT_SUPPORT
-#error "Build for being controlled by NetworkManager or wext, please set HAS_WPA_SUPPLICANT=y and HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=y"
-#endif // WPA_SUPPLICANT_SUPPORT //
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-
-#endif // CONFIG_STA_SUPPORT //
-
-
-
-#ifdef IKANOS_VX_1X0
-#include "vr_ikans.h"
-#endif // IKANOS_VX_1X0 //
-
-
-
-#endif	// __RT_CONFIG_H__
diff --git a/drivers/staging/rt3090/rt_linux.c b/drivers/staging/rt3090/rt_linux.c
deleted file mode 100644
index 9b94aa6..0000000
--- a/drivers/staging/rt3090/rt_linux.c
+++ /dev/null
@@ -1,1624 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
- */
-
-#include <linux/sched.h>
-#include "rt_config.h"
-
-ULONG	RTDebugLevel = RT_DEBUG_ERROR;
-
-
-// for wireless system event message
-char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
-	// system status event
-    "had associated successfully",							/* IW_ASSOC_EVENT_FLAG */
-    "had disassociated",									/* IW_DISASSOC_EVENT_FLAG */
-    "had deauthenticated",									/* IW_DEAUTH_EVENT_FLAG */
-    "had been aged-out and disassociated",					/* IW_AGEOUT_EVENT_FLAG */
-    "occurred CounterMeasures attack",						/* IW_COUNTER_MEASURES_EVENT_FLAG */
-    "occurred replay counter different in Key Handshaking",	/* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
-    "occurred RSNIE different in Key Handshaking",			/* IW_RSNIE_DIFF_EVENT_FLAG */
-    "occurred MIC different in Key Handshaking",			/* IW_MIC_DIFF_EVENT_FLAG */
-    "occurred ICV error in RX",								/* IW_ICV_ERROR_EVENT_FLAG */
-    "occurred MIC error in RX",								/* IW_MIC_ERROR_EVENT_FLAG */
-	"Group Key Handshaking timeout",						/* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
-	"Pairwise Key Handshaking timeout",						/* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
-	"RSN IE sanity check failure",							/* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
-	"set key done in WPA/WPAPSK",							/* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
-	"set key done in WPA2/WPA2PSK",                         /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
-	"connects with our wireless client",                    /* IW_STA_LINKUP_EVENT_FLAG */
-	"disconnects with our wireless client",                 /* IW_STA_LINKDOWN_EVENT_FLAG */
-	"scan completed"										/* IW_SCAN_COMPLETED_EVENT_FLAG */
-	"scan terminate!! Busy!! Enqueue fail!!"				/* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
-	};
-
-// for wireless IDS_spoof_attack event message
-char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
-    "detected conflict SSID",								/* IW_CONFLICT_SSID_EVENT_FLAG */
-    "detected spoofed association response",				/* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
-    "detected spoofed reassociation responses",				/* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
-    "detected spoofed probe response",						/* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
-    "detected spoofed beacon",								/* IW_SPOOF_BEACON_EVENT_FLAG */
-    "detected spoofed disassociation",						/* IW_SPOOF_DISASSOC_EVENT_FLAG */
-    "detected spoofed authentication",						/* IW_SPOOF_AUTH_EVENT_FLAG */
-    "detected spoofed deauthentication",					/* IW_SPOOF_DEAUTH_EVENT_FLAG */
-    "detected spoofed unknown management frame",			/* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
-	"detected replay attack"								/* IW_REPLAY_ATTACK_EVENT_FLAG */
-	};
-
-// for wireless IDS_flooding_attack event message
-char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
-	"detected authentication flooding",						/* IW_FLOOD_AUTH_EVENT_FLAG */
-    "detected association request flooding",				/* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
-    "detected reassociation request flooding",				/* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
-    "detected probe request flooding",						/* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
-    "detected disassociation flooding",						/* IW_FLOOD_DISASSOC_EVENT_FLAG */
-    "detected deauthentication flooding",					/* IW_FLOOD_DEAUTH_EVENT_FLAG */
-    "detected 802.1x eap-request flooding"					/* IW_FLOOD_EAP_REQ_EVENT_FLAG */
-	};
-
-
-/* timeout -- ms */
-VOID RTMP_SetPeriodicTimer(
-	IN	NDIS_MINIPORT_TIMER *pTimer,
-	IN	unsigned long timeout)
-{
-	timeout = ((timeout*OS_HZ) / 1000);
-	pTimer->expires = jiffies + timeout;
-	add_timer(pTimer);
-}
-
-/* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
-VOID RTMP_OS_Init_Timer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	NDIS_MINIPORT_TIMER *pTimer,
-	IN	TIMER_FUNCTION function,
-	IN	PVOID data)
-{
-	init_timer(pTimer);
-    pTimer->data = (unsigned long)data;
-    pTimer->function = function;
-}
-
-
-VOID RTMP_OS_Add_Timer(
-	IN	NDIS_MINIPORT_TIMER		*pTimer,
-	IN	unsigned long timeout)
-{
-	if (timer_pending(pTimer))
-		return;
-
-	timeout = ((timeout*OS_HZ) / 1000);
-	pTimer->expires = jiffies + timeout;
-	add_timer(pTimer);
-}
-
-VOID RTMP_OS_Mod_Timer(
-	IN	NDIS_MINIPORT_TIMER		*pTimer,
-	IN	unsigned long timeout)
-{
-	timeout = ((timeout*OS_HZ) / 1000);
-	mod_timer(pTimer, jiffies + timeout);
-}
-
-VOID RTMP_OS_Del_Timer(
-	IN	NDIS_MINIPORT_TIMER		*pTimer,
-	OUT	BOOLEAN					*pCancelled)
-{
-	if (timer_pending(pTimer))
-	{
-		*pCancelled = del_timer_sync(pTimer);
-	}
-	else
-	{
-		*pCancelled = TRUE;
-	}
-
-}
-
-VOID RTMP_OS_Release_Packet(
-	IN	PRTMP_ADAPTER pAd,
-	IN	PQUEUE_ENTRY  pEntry)
-{
-	//RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry);
-}
-
-// Unify all delay routine by using udelay
-VOID RTMPusecDelay(
-	IN	ULONG	usec)
-{
-	ULONG	i;
-
-	for (i = 0; i < (usec / 50); i++)
-		udelay(50);
-
-	if (usec % 50)
-		udelay(usec % 50);
-}
-
-void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
-{
-	time->u.LowPart = jiffies;
-}
-
-// pAd MUST allow to be NULL
-NDIS_STATUS os_alloc_mem(
-	IN	RTMP_ADAPTER *pAd,
-	OUT	UCHAR **mem,
-	IN	ULONG  size)
-{
-	*mem = (PUCHAR) kmalloc(size, GFP_ATOMIC);
-	if (*mem)
-		return (NDIS_STATUS_SUCCESS);
-	else
-		return (NDIS_STATUS_FAILURE);
-}
-
-// pAd MUST allow to be NULL
-NDIS_STATUS os_free_mem(
-	IN	PRTMP_ADAPTER pAd,
-	IN	PVOID mem)
-{
-
-	ASSERT(mem);
-	kfree(mem);
-	return (NDIS_STATUS_SUCCESS);
-}
-
-
-
-
-PNDIS_PACKET RtmpOSNetPktAlloc(
-	IN RTMP_ADAPTER *pAd,
-	IN int size)
-{
-	struct sk_buff *skb;
-	/* Add 2 more bytes for ip header alignment*/
-	skb = dev_alloc_skb(size+2);
-
-	return ((PNDIS_PACKET)skb);
-}
-
-
-PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length)
-{
-	struct sk_buff *pkt;
-
-	pkt = dev_alloc_skb(Length);
-
-	if (pkt == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("can't allocate frag rx %ld size packet\n",Length));
-	}
-
-	if (pkt)
-	{
-		RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
-	}
-
-	return (PNDIS_PACKET) pkt;
-}
-
-
-PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress)
-{
-	struct sk_buff *pkt;
-
-	pkt = dev_alloc_skb(Length);
-
-	if (pkt == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("can't allocate tx %ld size packet\n",Length));
-	}
-
-	if (pkt)
-	{
-		RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
-		*VirtualAddress = (PVOID) pkt->data;
-	}
-	else
-	{
-		*VirtualAddress = (PVOID) NULL;
-	}
-
-	return (PNDIS_PACKET) pkt;
-}
-
-
-VOID build_tx_packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket,
-	IN	PUCHAR	pFrame,
-	IN	ULONG	FrameLen)
-{
-
-	struct sk_buff	*pTxPkt;
-
-	ASSERT(pPacket);
-	pTxPkt = RTPKT_TO_OSPKT(pPacket);
-
-	NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
-}
-
-VOID	RTMPFreeAdapter(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	POS_COOKIE os_cookie;
-	int index;
-
-	os_cookie=(POS_COOKIE)pAd->OS_Cookie;
-
-	if (pAd->BeaconBuf)
-		kfree(pAd->BeaconBuf);
-
-
-	NdisFreeSpinLock(&pAd->MgmtRingLock);
-
-#ifdef RTMP_MAC_PCI
-	NdisFreeSpinLock(&pAd->RxRingLock);
-#ifdef RT3090
-NdisFreeSpinLock(&pAd->McuCmdLock);
-#endif // RT3090 //
-#endif // RTMP_MAC_PCI //
-
-	for (index =0 ; index < NUM_OF_TX_RING; index++)
-	{
-		NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
-		NdisFreeSpinLock(&pAd->DeQueueLock[index]);
-		pAd->DeQueueRunning[index] = FALSE;
-	}
-
-	NdisFreeSpinLock(&pAd->irq_lock);
-
-
-	vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
-	if (os_cookie)
-		kfree(os_cookie);
-}
-
-BOOLEAN OS_Need_Clone_Packet(void)
-{
-	return (FALSE);
-}
-
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
-		must have only one NDIS BUFFER
-		return - byte copied. 0 means can't create NDIS PACKET
-		NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket
-
-	Arguments:
-		pAd	Pointer to our adapter
-		pInsAMSDUHdr	EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
-		*pSrcTotalLen			return total packet length. This lenght is calculated with 802.3 format packet.
-
-	Return Value:
-		NDIS_STATUS_SUCCESS
-		NDIS_STATUS_FAILURE
-
-	Note:
-
-	========================================================================
-*/
-NDIS_STATUS RTMPCloneNdisPacket(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	BOOLEAN			pInsAMSDUHdr,
-	IN	PNDIS_PACKET	pInPacket,
-	OUT PNDIS_PACKET   *ppOutPacket)
-{
-
-	struct sk_buff *pkt;
-
-	ASSERT(pInPacket);
-	ASSERT(ppOutPacket);
-
-	// 1. Allocate a packet
-	pkt = dev_alloc_skb(2048);
-
-	if (pkt == NULL)
-	{
-		return NDIS_STATUS_FAILURE;
-	}
-
-	skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
-	NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket));
-	*ppOutPacket = OSPKT_TO_RTPKT(pkt);
-
-
-	RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
-
-	printk("###Clone###\n");
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-// the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
-NDIS_STATUS RTMPAllocateNdisPacket(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT PNDIS_PACKET   *ppPacket,
-	IN	PUCHAR			pHeader,
-	IN	UINT			HeaderLen,
-	IN	PUCHAR			pData,
-	IN	UINT			DataLen)
-{
-	PNDIS_PACKET	pPacket;
-	ASSERT(pData);
-	ASSERT(DataLen);
-
-	// 1. Allocate a packet
-	pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + RTMP_PKT_TAIL_PADDING);
-	if (pPacket == NULL)
-	{
-		*ppPacket = NULL;
-#ifdef DEBUG
-		printk("RTMPAllocateNdisPacket Fail\n\n");
-#endif
-		return NDIS_STATUS_FAILURE;
-	}
-
-	// 2. clone the frame content
-	if (HeaderLen > 0)
-		NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
-	if (DataLen > 0)
-		NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen);
-
-	// 3. update length of packet
-	skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen);
-
-	RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
-//	printk("%s : pPacket = %p, len = %d\n", __FUNCTION__, pPacket, GET_OS_PKT_LEN(pPacket));
-	*ppPacket = pPacket;
-	return NDIS_STATUS_SUCCESS;
-}
-
-/*
-  ========================================================================
-  Description:
-	This routine frees a miniport internally allocated NDIS_PACKET and its
-	corresponding NDIS_BUFFER and allocated memory.
-  ========================================================================
-*/
-VOID RTMPFreeNdisPacket(
-	IN PRTMP_ADAPTER pAd,
-	IN PNDIS_PACKET  pPacket)
-{
-	dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
-}
-
-
-// IRQL = DISPATCH_LEVEL
-// NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same
-//			 scatter gather buffer
-NDIS_STATUS Sniff2BytesFromNdisBuffer(
-	IN	PNDIS_BUFFER	pFirstBuffer,
-	IN	UCHAR			DesiredOffset,
-	OUT PUCHAR			pByte0,
-	OUT PUCHAR			pByte1)
-{
-    *pByte0 = *(PUCHAR)(pFirstBuffer + DesiredOffset);
-    *pByte1 = *(PUCHAR)(pFirstBuffer + DesiredOffset + 1);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-void RTMP_QueryPacketInfo(
-	IN  PNDIS_PACKET pPacket,
-	OUT PACKET_INFO  *pPacketInfo,
-	OUT PUCHAR		 *pSrcBufVA,
-	OUT	UINT		 *pSrcBufLen)
-{
-	pPacketInfo->BufferCount = 1;
-	pPacketInfo->pFirstBuffer = (PNDIS_BUFFER)GET_OS_PKT_DATAPTR(pPacket);
-	pPacketInfo->PhysicalBufferCount = 1;
-	pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
-
-	*pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
-	*pSrcBufLen = GET_OS_PKT_LEN(pPacket);
-}
-
-void RTMP_QueryNextPacketInfo(
-	IN  PNDIS_PACKET *ppPacket,
-	OUT PACKET_INFO  *pPacketInfo,
-	OUT PUCHAR		 *pSrcBufVA,
-	OUT	UINT		 *pSrcBufLen)
-{
-	PNDIS_PACKET pPacket = NULL;
-
-	if (*ppPacket)
-		pPacket = GET_OS_PKT_NEXT(*ppPacket);
-
-	if (pPacket)
-	{
-		pPacketInfo->BufferCount = 1;
-		pPacketInfo->pFirstBuffer = (PNDIS_BUFFER)GET_OS_PKT_DATAPTR(pPacket);
-		pPacketInfo->PhysicalBufferCount = 1;
-		pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
-
-		*pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
-		*pSrcBufLen = GET_OS_PKT_LEN(pPacket);
-		*ppPacket = GET_OS_PKT_NEXT(pPacket);
-	}
-	else
-	{
-		pPacketInfo->BufferCount = 0;
-		pPacketInfo->pFirstBuffer = NULL;
-		pPacketInfo->PhysicalBufferCount = 0;
-		pPacketInfo->TotalPacketLength = 0;
-
-		*pSrcBufVA = NULL;
-		*pSrcBufLen = 0;
-		*ppPacket = NULL;
-	}
-}
-
-
-PNDIS_PACKET DuplicatePacket(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket,
-	IN	UCHAR			FromWhichBSSID)
-{
-	struct sk_buff	*skb;
-	PNDIS_PACKET	pRetPacket = NULL;
-	USHORT			DataSize;
-	UCHAR			*pData;
-
-	DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
-	pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
-
-
-	skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
-	if (skb)
-	{
-		skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
-		pRetPacket = OSPKT_TO_RTPKT(skb);
-	}
-
-
-	return pRetPacket;
-
-}
-
-PNDIS_PACKET duplicate_pkt(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pHeader802_3,
-    IN  UINT            HdrLen,
-	IN	PUCHAR			pData,
-	IN	ULONG			DataSize,
-	IN	UCHAR			FromWhichBSSID)
-{
-	struct sk_buff	*skb;
-	PNDIS_PACKET	pPacket = NULL;
-
-
-	if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
-	{
-		skb_reserve(skb, 2);
-		NdisMoveMemory(skb_tail_pointer(skb), pHeader802_3, HdrLen);
-		skb_put(skb, HdrLen);
-		NdisMoveMemory(skb_tail_pointer(skb), pData, DataSize);
-		skb_put(skb, DataSize);
-		skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
-		pPacket = OSPKT_TO_RTPKT(skb);
-	}
-
-	return pPacket;
-}
-
-
-#define TKIP_TX_MIC_SIZE		8
-PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket)
-{
-	struct sk_buff	*skb, *newskb;
-
-
-	skb = RTPKT_TO_OSPKT(pPacket);
-	if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
-	{
-		// alloc a new skb and copy the packet
-		newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
-		dev_kfree_skb_any(skb);
-		if (newskb == NULL)
-		{
-			DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
-			return NULL;
-		}
-		skb = newskb;
-	}
-
-	return OSPKT_TO_RTPKT(skb);
-
-
-}
-
-
-
-
-PNDIS_PACKET ClonePacket(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket,
-	IN	PUCHAR			pData,
-	IN	ULONG			DataSize)
-{
-	struct sk_buff	*pRxPkt;
-	struct sk_buff	*pClonedPkt;
-
-	ASSERT(pPacket);
-	pRxPkt = RTPKT_TO_OSPKT(pPacket);
-
-	// clone the packet
-	pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
-
-	if (pClonedPkt)
-	{
-	// set the correct dataptr and data len
-	pClonedPkt->dev = pRxPkt->dev;
-	pClonedPkt->data = pData;
-	pClonedPkt->len = DataSize;
-	pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
-		ASSERT(DataSize < 1530);
-	}
-	return pClonedPkt;
-}
-
-//
-// change OS packet DataPtr and DataLen
-//
-void  update_os_packet_info(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN  UCHAR			FromWhichBSSID)
-{
-	struct sk_buff	*pOSPkt;
-
-	ASSERT(pRxBlk->pRxPacket);
-	pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
-
-	pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
-	pOSPkt->data = pRxBlk->pData;
-	pOSPkt->len = pRxBlk->DataSize;
-	pOSPkt->tail = pOSPkt->data + pOSPkt->len;
-}
-
-
-void wlan_802_11_to_802_3_packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	PUCHAR			pHeader802_3,
-	IN  UCHAR			FromWhichBSSID)
-{
-	struct sk_buff	*pOSPkt;
-
-	ASSERT(pRxBlk->pRxPacket);
-	ASSERT(pHeader802_3);
-
-	pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
-
-	pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
-	pOSPkt->data = pRxBlk->pData;
-	pOSPkt->len = pRxBlk->DataSize;
-	pOSPkt->tail = pOSPkt->data + pOSPkt->len;
-
-	//
-	// copy 802.3 header
-	//
-	//
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
-#endif // CONFIG_STA_SUPPORT //
-	}
-
-
-
-void announce_802_3_packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket)
-{
-
-	struct sk_buff	*pRxPkt;
-#ifdef INF_AMAZON_PPA
-        int             ret = 0;
-        unsigned int ppa_flags = 0; /* reserved for now */
-#endif // INF_AMAZON_PPA //
-
-	ASSERT(pPacket);
-
-	pRxPkt = RTPKT_TO_OSPKT(pPacket);
-
-#ifdef CONFIG_STA_SUPPORT
-#endif // CONFIG_STA_SUPPORT //
-
-    /* Push up the protocol stack */
-#ifdef IKANOS_VX_1X0
-	IKANOS_DataFrameRx(pAd, pRxPkt->dev, pRxPkt, pRxPkt->len);
-#else
-#ifdef INF_AMAZON_SE
-#ifdef BG_FT_SUPPORT
-            BG_FTPH_PacketFromApHandle(pRxPkt);
-            return;
-#endif // BG_FT_SUPPORT //
-#endif // INF_AMAZON_SE //
-	pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
-
-#ifdef INF_AMAZON_PPA
-	if (ppa_hook_directpath_send_fn && pAd->PPAEnable==TRUE )
-	{
-		memset(pRxPkt->head,0,pRxPkt->data-pRxPkt->head-14);
-		DBGPRINT(RT_DEBUG_TRACE, ("ppa_hook_directpath_send_fn rx :ret:%d headroom:%d dev:%s pktlen:%d<===\n",ret,skb_headroom(pRxPkt)
-			,pRxPkt->dev->name,pRxPkt->len));
-		hex_dump("rx packet", pRxPkt->data, 32);
-		ret = ppa_hook_directpath_send_fn(pAd->g_if_id, pRxPkt, pRxPkt->len, ppa_flags);
-		pRxPkt=NULL;
-		return;
-
-	}
-#endif // INF_AMAZON_PPA //
-
-//#ifdef CONFIG_5VT_ENHANCE
-//	*(int*)(pRxPkt->cb) = BRIDGE_TAG;
-//#endif
-
-	{
-		netif_rx(pRxPkt);
-	}
-
-#endif // IKANOS_VX_1X0 //
-}
-
-
-PRTMP_SCATTER_GATHER_LIST
-rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
-{
-	sg->NumberOfElements = 1;
-	sg->Elements[0].Address =  GET_OS_PKT_DATAPTR(pPacket);
-	sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
-	return (sg);
-}
-
-void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
-{
-	unsigned char *pt;
-	int x;
-
-	if (RTDebugLevel < RT_DEBUG_TRACE)
-		return;
-
-	pt = pSrcBufVA;
-	printk("%s: %p, len = %d\n",str,  pSrcBufVA, SrcBufLen);
-	for (x=0; x<SrcBufLen; x++)
-	{
-		if (x % 16 == 0)
-			printk("0x%04x : ", x);
-		printk("%02x ", ((unsigned char)pt[x]));
-		if (x%16 == 15) printk("\n");
-	}
-	printk("\n");
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Send log message through wireless event
-
-		Support standard iw_event with IWEVCUSTOM. It is used below.
-
-		iwreq_data.data.flags is used to store event_flag that is defined by user.
-		iwreq_data.data.length is the length of the event log.
-
-		The format of the event log is composed of the entry's MAC address and
-		the desired log message (refer to pWirelessEventText).
-
-			ex: 11:22:33:44:55:66 has associated successfully
-
-		p.s. The requirement of Wireless Extension is v15 or newer.
-
-	========================================================================
-*/
-VOID RTMPSendWirelessEvent(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Event_flag,
-	IN	PUCHAR			pAddr,
-	IN	UCHAR			BssIdx,
-	IN	CHAR			Rssi)
-{
-#if WIRELESS_EXT >= 15
-
-	//union		iwreq_data      wrqu;
-	PSTRING	pBuf = NULL, pBufPtr = NULL;
-	USHORT	event, type, BufLen;
-	UCHAR	event_table_len = 0;
-
-	type = Event_flag & 0xFF00;
-	event = Event_flag & 0x00FF;
-
-	switch (type)
-	{
-		case IW_SYS_EVENT_FLAG_START:
-			event_table_len = IW_SYS_EVENT_TYPE_NUM;
-			break;
-
-		case IW_SPOOF_EVENT_FLAG_START:
-			event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
-			break;
-
-		case IW_FLOOD_EVENT_FLAG_START:
-			event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
-			break;
-	}
-
-	if (event_table_len == 0)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __FUNCTION__, type));
-		return;
-	}
-
-	if (event >= event_table_len)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __FUNCTION__, event));
-		return;
-	}
-
-	//Allocate memory and copy the msg.
-	if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
-	{
-		//Prepare the payload
-		memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
-
-		pBufPtr = pBuf;
-
-		if (pAddr)
-			pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
-		else if (BssIdx < MAX_MBSSID_NUM)
-			pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(ra%d) ", BssIdx);
-		else
-			pBufPtr += sprintf(pBufPtr, "(RT2860) ");
-
-		if (type == IW_SYS_EVENT_FLAG_START)
-			pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
-		else if (type == IW_SPOOF_EVENT_FLAG_START)
-			pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
-		else if (type == IW_FLOOD_EVENT_FLAG_START)
-			pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
-		else
-			pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
-
-		pBufPtr[pBufPtr - pBuf] = '\0';
-		BufLen = pBufPtr - pBuf;
-
-		RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, Event_flag, NULL, (PUCHAR)pBuf, BufLen);
-		//DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __FUNCTION__, pBuf));
-
-		kfree(pBuf);
-	}
-	else
-		DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __FUNCTION__));
-#else
-	DBGPRINT(RT_DEBUG_ERROR, ("%s : The Wireless Extension MUST be v15 or newer.\n", __FUNCTION__));
-#endif  /* WIRELESS_EXT >= 15 */
-}
-
-
-
-
-#ifdef CONFIG_STA_SUPPORT
-void send_monitor_packets(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk)
-{
-    struct sk_buff	*pOSPkt;
-    wlan_ng_prism2_header *ph;
-    int rate_index = 0;
-    USHORT header_len = 0;
-    UCHAR temp_header[40] = {0};
-
-    u_int32_t ralinkrate[256] = {2,4,11,22, 12,18,24,36,48,72,96,  108,   109, 110, 111, 112, 13, 26, 39, 52,78,104, 117, 130, 26, 52, 78,104, 156, 208, 234, 260, 27, 54,81,108,162, 216, 243, 270, // Last 38
-	54, 108, 162, 216, 324, 432, 486, 540,  14, 29, 43, 57, 87, 115, 130, 144, 29, 59,87,115, 173, 230,260, 288, 30, 60,90,120,180,240,270,300,60,120,180,240,360,480,540,600, 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,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80};
-
-
-    ASSERT(pRxBlk->pRxPacket);
-    if (pRxBlk->DataSize < 10)
-    {
-        DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __FUNCTION__, pRxBlk->DataSize));
-		goto err_free_sk_buff;
-    }
-
-    if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
-    {
-        DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __FUNCTION__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
-		goto err_free_sk_buff;
-    }
-
-    pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
-	pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
-    if (pRxBlk->pHeader->FC.Type == BTYPE_DATA)
-    {
-        pRxBlk->DataSize -= LENGTH_802_11;
-        if ((pRxBlk->pHeader->FC.ToDs == 1) &&
-            (pRxBlk->pHeader->FC.FrDs == 1))
-            header_len = LENGTH_802_11_WITH_ADDR4;
-        else
-            header_len = LENGTH_802_11;
-
-        // QOS
-	if (pRxBlk->pHeader->FC.SubType & 0x08)
-	{
-	    header_len += 2;
-		// Data skip QOS contorl field
-		pRxBlk->DataSize -=2;
-	}
-
-	// Order bit: A-Ralink or HTC+
-	if (pRxBlk->pHeader->FC.Order)
-	{
-	    header_len += 4;
-			// Data skip HTC contorl field
-			pRxBlk->DataSize -= 4;
-	}
-
-        // Copy Header
-        if (header_len <= 40)
-            NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
-
-        // skip HW padding
-	if (pRxBlk->RxD.L2PAD)
-	    pRxBlk->pData += (header_len + 2);
-        else
-            pRxBlk->pData += header_len;
-    } //end if
-
-
-	if (pRxBlk->DataSize < pOSPkt->len) {
-        skb_trim(pOSPkt,pRxBlk->DataSize);
-    } else {
-        skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len));
-    } //end if
-
-    if ((pRxBlk->pData - pOSPkt->data) > 0) {
-	    skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data));
-	    skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data));
-    } //end if
-
-    if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) {
-        if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) {
-	        DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __FUNCTION__));
-			goto err_free_sk_buff;
-	    } //end if
-    } //end if
-
-    if (header_len > 0)
-        NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len);
-
-    ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header));
-	NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header));
-
-    ph->msgcode		    = DIDmsg_lnxind_wlansniffrm;
-	ph->msglen		    = sizeof(wlan_ng_prism2_header);
-	strcpy((PSTRING) ph->devname, (PSTRING) pAd->net_dev->name);
-
-    ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
-	ph->hosttime.status = 0;
-	ph->hosttime.len = 4;
-	ph->hosttime.data = jiffies;
-
-	ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
-	ph->mactime.status = 0;
-	ph->mactime.len = 0;
-	ph->mactime.data = 0;
-
-    ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
-	ph->istx.status = 0;
-	ph->istx.len = 0;
-	ph->istx.data = 0;
-
-    ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
-	ph->channel.status = 0;
-	ph->channel.len = 4;
-
-    ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel;
-
-    ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
-	ph->rssi.status = 0;
-	ph->rssi.len = 4;
-    ph->rssi.data = (u_int32_t)RTMPMaxRssi(pAd, ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0, RSSI_0), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI1, RSSI_1), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2, RSSI_2));;
-
-	ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
-	ph->signal.status = 0;
-	ph->signal.len = 4;
-	ph->signal.data = 0; //rssi + noise;
-
-	ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
-	ph->noise.status = 0;
-	ph->noise.len = 4;
-	ph->noise.data = 0;
-
-#ifdef DOT11_N_SUPPORT
-    if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX)
-    {
-	rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS);
-    }
-    else
-#endif // DOT11_N_SUPPORT //
-	if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
-	rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4;
-    else
-	rate_index = (UCHAR)(pRxBlk->pRxWI->MCS);
-    if (rate_index < 0)
-        rate_index = 0;
-    if (rate_index > 255)
-        rate_index = 255;
-
-	ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
-	ph->rate.status = 0;
-	ph->rate.len = 4;
-    ph->rate.data = ralinkrate[rate_index];
-
-	ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
-    ph->frmlen.status = 0;
-	ph->frmlen.len = 4;
-	ph->frmlen.data	= (u_int32_t)pRxBlk->DataSize;
-
-
-    pOSPkt->pkt_type = PACKET_OTHERHOST;
-    pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
-    pOSPkt->ip_summed = CHECKSUM_NONE;
-    netif_rx(pOSPkt);
-
-    return;
-
-err_free_sk_buff:
-	RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
-	return;
-
-}
-#endif // CONFIG_STA_SUPPORT //
-
-
-
-/*******************************************************************************
-
-	File open/close related functions.
-
- *******************************************************************************/
-RTMP_OS_FD RtmpOSFileOpen(char *pPath,  int flag, int mode)
-{
-	struct file	*filePtr;
-
-	filePtr = filp_open(pPath, flag, 0);
-	if (IS_ERR(filePtr))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s(): Error %ld opening %s\n", __FUNCTION__, -PTR_ERR(filePtr), pPath));
-	}
-
-	return (RTMP_OS_FD)filePtr;
-}
-
-int RtmpOSFileClose(RTMP_OS_FD osfd)
-{
-	filp_close(osfd, NULL);
-	return 0;
-}
-
-
-void RtmpOSFileSeek(RTMP_OS_FD osfd, int offset)
-{
-	osfd->f_pos = offset;
-}
-
-
-int RtmpOSFileRead(RTMP_OS_FD osfd, char *pDataPtr, int readLen)
-{
-	// The object must have a read method
-	if (osfd->f_op && osfd->f_op->read)
-	{
-		return osfd->f_op->read(osfd,  pDataPtr, readLen, &osfd->f_pos);
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("no file read method\n"));
-		return -1;
-	}
-}
-
-
-int RtmpOSFileWrite(RTMP_OS_FD osfd, char *pDataPtr, int writeLen)
-{
-	return osfd->f_op->write(osfd, pDataPtr, (size_t)writeLen, &osfd->f_pos);
-}
-
-
-void RtmpOSFSInfoChange(RTMP_OS_FS_INFO *pOSFSInfo, BOOLEAN bSet)
-{
-	if (bSet)
-	{
-		// Save uid and gid used for filesystem access.
-		// Set user and group to 0 (root)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
-		pOSFSInfo->fsuid= current->fsuid;
-		pOSFSInfo->fsgid = current->fsgid;
-		current->fsuid = current->fsgid = 0;
-#else
-		pOSFSInfo->fsuid = current_fsuid();
-		pOSFSInfo->fsgid = current_fsgid();
-#endif
-		pOSFSInfo->fs = get_fs();
-		set_fs(KERNEL_DS);
-	}
-	else
-	{
-		set_fs(pOSFSInfo->fs);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
-		current->fsuid = pOSFSInfo->fsuid;
-		current->fsgid = pOSFSInfo->fsgid;
-#endif
-	}
-}
-
-
-
-/*******************************************************************************
-
-	Task create/management/kill related functions.
-
- *******************************************************************************/
-NDIS_STATUS RtmpOSTaskKill(
-	IN RTMP_OS_TASK *pTask)
-{
-	RTMP_ADAPTER *pAd;
-	int ret = NDIS_STATUS_FAILURE;
-
-	pAd = (RTMP_ADAPTER *)pTask->priv;
-
-#ifdef KTHREAD_SUPPORT
-	if (pTask->kthread_task)
-	{
-		kthread_stop(pTask->kthread_task);
-		ret = NDIS_STATUS_SUCCESS;
-	}
-#else
-	CHECK_PID_LEGALITY(pTask->taskPID)
-	{
-		printk("Terminate the task(%s) with pid(%d)!\n", pTask->taskName, GET_PID_NUMBER(pTask->taskPID));
-		mb();
-		pTask->task_killed = 1;
-		mb();
-		ret = KILL_THREAD_PID(pTask->taskPID, SIGTERM, 1);
-		if (ret)
-		{
-			printk(KERN_WARNING "kill task(%s) with pid(%d) failed(retVal=%d)!\n",
-				pTask->taskName, GET_PID_NUMBER(pTask->taskPID), ret);
-		}
-		else
-		{
-			wait_for_completion(&pTask->taskComplete);
-			pTask->taskPID = THREAD_PID_INIT_VALUE;
-			pTask->task_killed = 0;
-			ret = NDIS_STATUS_SUCCESS;
-		}
-	}
-#endif
-
-	return ret;
-
-}
-
-
-INT RtmpOSTaskNotifyToExit(
-	IN RTMP_OS_TASK *pTask)
-{
-
-#ifndef KTHREAD_SUPPORT
-	complete_and_exit(&pTask->taskComplete, 0);
-#endif
-
-	return 0;
-}
-
-
-void RtmpOSTaskCustomize(
-	IN RTMP_OS_TASK *pTask)
-{
-
-#ifndef KTHREAD_SUPPORT
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-	daemonize((PSTRING)&pTask->taskName[0]/*"%s",pAd->net_dev->name*/);
-
-	allow_signal(SIGTERM);
-	allow_signal(SIGKILL);
-	current->flags |= PF_NOFREEZE;
-#else
-	unsigned long flags;
-
-	daemonize();
-	reparent_to_init();
-	strcpy(current->comm, &pTask->taskName[0]);
-
-	siginitsetinv(&current->blocked, sigmask(SIGTERM) | sigmask(SIGKILL));
-
-	/* Allow interception of SIGKILL only
-	 * Don't allow other signals to interrupt the transmission */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)
-	spin_lock_irqsave(&current->sigmask_lock, flags);
-	flush_signals(current);
-	recalc_sigpending(current);
-	spin_unlock_irqrestore(&current->sigmask_lock, flags);
-#endif
-#endif
-
-    /* signal that we've started the thread */
-	complete(&pTask->taskComplete);
-
-#endif
-}
-
-
-NDIS_STATUS RtmpOSTaskAttach(
-	IN RTMP_OS_TASK *pTask,
-	IN int (*fn)(void *),
-	IN void *arg)
-{
-	NDIS_STATUS status = NDIS_STATUS_SUCCESS;
-	pid_t pid_number = -1;
-
-#ifdef KTHREAD_SUPPORT
-	pTask->task_killed = 0;
-	pTask->kthread_task = NULL;
-	pTask->kthread_task = kthread_run(fn, arg, pTask->taskName);
-	if (IS_ERR(pTask->kthread_task))
-		status = NDIS_STATUS_FAILURE;
-#else
-	pid_number = kernel_thread(fn, arg, RTMP_OS_MGMT_TASK_FLAGS);
-	if (pid_number < 0)
-	{
-		DBGPRINT (RT_DEBUG_ERROR, ("Attach task(%s) failed!\n", pTask->taskName));
-		status = NDIS_STATUS_FAILURE;
-	}
-	else
-	{
-		pTask->taskPID = GET_PID(pid_number);
-
-		// Wait for the thread to start
-		wait_for_completion(&pTask->taskComplete);
-		status = NDIS_STATUS_SUCCESS;
-	}
-#endif
-	return status;
-}
-
-
-NDIS_STATUS RtmpOSTaskInit(
-	IN RTMP_OS_TASK *pTask,
-	IN PSTRING		pTaskName,
-	IN VOID			*pPriv)
-{
-	int len;
-
-	ASSERT(pTask);
-
-#ifndef KTHREAD_SUPPORT
-	NdisZeroMemory((PUCHAR)(pTask), sizeof(RTMP_OS_TASK));
-#endif
-
-	len = strlen(pTaskName);
-	len = len > (RTMP_OS_TASK_NAME_LEN -1) ? (RTMP_OS_TASK_NAME_LEN-1) : len;
-	NdisMoveMemory(&pTask->taskName[0], pTaskName, len);
-	pTask->priv = pPriv;
-
-#ifndef KTHREAD_SUPPORT
-	RTMP_SEM_EVENT_INIT_LOCKED(&(pTask->taskSema));
-	pTask->taskPID = THREAD_PID_INIT_VALUE;
-
-	init_completion (&pTask->taskComplete);
-#endif
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-void RTMP_IndicateMediaState(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	if (pAd->CommonCfg.bWirelessEvent)
-	{
-		if (pAd->IndicateMediaState == NdisMediaStateConnected)
-		{
-			RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-		}
-		else
-		{
-			RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-		}
-	}
-}
-
-
-#if LINUX_VERSION_CODE <= 0x20402	// Red Hat 7.1
-//static struct net_device *alloc_netdev(int sizeof_priv, const char *mask, void (*setup)(struct net_device *)) //sample
-struct net_device *alloc_netdev(
-	int sizeof_priv,
-	const char *mask,
-	void (*setup)(struct net_device *))
-{
-    struct net_device	*dev;
-    INT					alloc_size;
-
-
-    /* ensure 32-byte alignment of the private area */
-    alloc_size = sizeof (*dev) + sizeof_priv + 31;
-
-    dev = (struct net_device *) kmalloc(alloc_size, GFP_KERNEL);
-    if (dev == NULL)
-    {
-        DBGPRINT(RT_DEBUG_ERROR,
-				("alloc_netdev: Unable to allocate device memory.\n"));
-        return NULL;
-    }
-
-    memset(dev, 0, alloc_size);
-
-    if (sizeof_priv)
-        dev->priv = (void *) (((long)(dev + 1) + 31) & ~31);
-
-    setup(dev);
-    strcpy(dev->name, mask);
-
-    return dev;
-}
-#endif // LINUX_VERSION_CODE //
-
-
-int RtmpOSWrielessEventSend(
-	IN RTMP_ADAPTER *pAd,
-	IN UINT32		eventType,
-	IN INT			flags,
-	IN PUCHAR		pSrcMac,
-	IN PUCHAR		pData,
-	IN UINT32		dataLen)
-{
-	union iwreq_data    wrqu;
-
-       memset(&wrqu, 0, sizeof(wrqu));
-
-	if (flags>-1)
-	       wrqu.data.flags = flags;
-
-	if (pSrcMac)
-		memcpy(wrqu.ap_addr.sa_data, pSrcMac, MAC_ADDR_LEN);
-
-	if ((pData!= NULL) && (dataLen > 0))
-		wrqu.data.length = dataLen;
-
-       wireless_send_event(pAd->net_dev, eventType, &wrqu, (char *)pData);
-	return 0;
-}
-
-
-int RtmpOSNetDevAddrSet(
-	IN PNET_DEV pNetDev,
-	IN PUCHAR	pMacAddr)
-{
-	struct net_device *net_dev;
-	RTMP_ADAPTER *pAd;
-
-	net_dev = pNetDev;
-	//pAd = (RTMP_ADAPTER *)net_dev->priv;
-	pAd=RTMP_OS_NETDEV_GET_PRIV(pNetDev);
-
-#ifdef CONFIG_STA_SUPPORT
-	// work-around for the SuSE due to it has it's own interface name management system.
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		NdisZeroMemory(pAd->StaCfg.dev_name, 16);
-		NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name, strlen(net_dev->name));
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	NdisMoveMemory(net_dev->dev_addr, pMacAddr, 6);
-
-	return 0;
-}
-
-
-
-/*
-  *	Assign the network dev name for created Ralink WiFi interface.
-  */
-static int RtmpOSNetDevRequestName(
-	IN RTMP_ADAPTER *pAd,
-	IN PNET_DEV dev,
-	IN PSTRING pPrefixStr,
-	IN INT	devIdx)
-{
-	PNET_DEV		existNetDev;
-	STRING		suffixName[IFNAMSIZ];
-	STRING		desiredName[IFNAMSIZ];
-	int	ifNameIdx, prefixLen, slotNameLen;
-	int Status;
-
-
-	prefixLen = strlen(pPrefixStr);
-	ASSERT((prefixLen < IFNAMSIZ));
-
-	for (ifNameIdx = devIdx; ifNameIdx < 32; ifNameIdx++)
-	{
-		memset(suffixName, 0, IFNAMSIZ);
-		memset(desiredName, 0, IFNAMSIZ);
-		strncpy(&desiredName[0], pPrefixStr, prefixLen);
-
-#ifdef MULTIPLE_CARD_SUPPORT
-		if (pAd->MC_RowID >= 0)
-			sprintf(suffixName, "%02d_%d", pAd->MC_RowID, ifNameIdx);
-		else
-#endif // MULTIPLE_CARD_SUPPORT //
-		sprintf(suffixName, "%d", ifNameIdx);
-
-		slotNameLen = strlen(suffixName);
-		ASSERT(((slotNameLen + prefixLen) < IFNAMSIZ));
-		strcat(desiredName, suffixName);
-
-		existNetDev = RtmpOSNetDevGetByName(dev, &desiredName[0]);
-		if (existNetDev == NULL)
-			break;
-		else
-			RtmpOSNetDeviceRefPut(existNetDev);
-	}
-
-	if(ifNameIdx < 32)
-	{
-		strcpy(&dev->name[0], &desiredName[0]);
-		Status = NDIS_STATUS_SUCCESS;
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_ERROR,
-					("Cannot request DevName with preifx(%s) and in range(0~32) as suffix from OS!\n", pPrefixStr));
-		Status = NDIS_STATUS_FAILURE;
-	}
-
-	return Status;
-}
-
-
-void RtmpOSNetDevClose(
-	IN PNET_DEV pNetDev)
-{
-	dev_close(pNetDev);
-}
-
-
-void RtmpOSNetDevFree(PNET_DEV pNetDev)
-{
-	ASSERT(pNetDev);
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-	free_netdev(pNetDev);
-#else
-	kfree(pNetDev);
-#endif
-}
-
-
-INT RtmpOSNetDevAlloc(
-	IN PNET_DEV *new_dev_p,
-	IN UINT32	privDataSize)
-{
-	// assign it as null first.
-	*new_dev_p = NULL;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Allocate a net device with private data size=%d!\n", privDataSize));
-#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
-	*new_dev_p = alloc_netdev(privDataSize, "eth%d", ether_setup);
-#else
-	*new_dev_p = alloc_etherdev(privDataSize);
-#endif // LINUX_VERSION_CODE //
-
-	if (*new_dev_p)
-		return NDIS_STATUS_SUCCESS;
-	else
-		return NDIS_STATUS_FAILURE;
-}
-
-
-PNET_DEV RtmpOSNetDevGetByName(PNET_DEV pNetDev, PSTRING pDevName)
-{
-	PNET_DEV	pTargetNetDev = NULL;
-
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
-	pTargetNetDev = dev_get_by_name(dev_net(pNetDev), pDevName);
-#else
-	ASSERT(pNetDev);
-	pTargetNetDev = dev_get_by_name(pNetDev->nd_net, pDevName);
-#endif
-#else
-	pTargetNetDev = dev_get_by_name(pDevName);
-#endif // KERNEL_VERSION(2,6,24) //
-
-#else
-	int	devNameLen;
-
-	devNameLen = strlen(pDevName);
-	ASSERT((devNameLen <= IFNAMSIZ));
-
-	for(pTargetNetDev=dev_base; pTargetNetDev!=NULL; pTargetNetDev=pTargetNetDev->next)
-	{
-		if (strncmp(pTargetNetDev->name, pDevName, devNameLen) == 0)
-			break;
-	}
-#endif // KERNEL_VERSION(2,5,0) //
-
-	return pTargetNetDev;
-}
-
-
-void RtmpOSNetDeviceRefPut(PNET_DEV pNetDev)
-{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-	/*
-		every time dev_get_by_name is called, and it has returned a valid struct
-		net_device*, dev_put should be called afterwards, because otherwise the
-		machine hangs when the device is unregistered (since dev->refcnt > 1).
-	*/
-	if(pNetDev)
-		dev_put(pNetDev);
-#endif // LINUX_VERSION_CODE //
-}
-
-
-INT RtmpOSNetDevDestory(
-	IN RTMP_ADAPTER *pAd,
-	IN PNET_DEV		pNetDev)
-{
-
-	// TODO: Need to fix this
-	printk("WARNING: This function(%s) not implement yet!!!\n", __FUNCTION__);
-	return 0;
-}
-
-
-void RtmpOSNetDevDetach(PNET_DEV pNetDev)
-{
-	unregister_netdev(pNetDev);
-}
-
-
-int RtmpOSNetDevAttach(
-	IN PNET_DEV pNetDev,
-	IN RTMP_OS_NETDEV_OP_HOOK *pDevOpHook)
-{
-	int ret, rtnl_locked = FALSE;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("RtmpOSNetDevAttach()--->\n"));
-	// If we need hook some callback function to the net device structrue, now do it.
-	if (pDevOpHook)
-	{
-		PRTMP_ADAPTER pAd = RTMP_OS_NETDEV_GET_PRIV(pNetDev);
-
-		pNetDev->netdev_ops = pDevOpHook->netdev_ops;
-
-		/* OS specific flags, here we used to indicate if we are virtual interface */
-		pNetDev->priv_flags = pDevOpHook->priv_flags;
-
-#if (WIRELESS_EXT < 21) && (WIRELESS_EXT >= 12)
-		pNetDev->get_wireless_stats = rt28xx_get_wireless_stats;
-#endif
-
-#ifdef CONFIG_STA_SUPPORT
-#if WIRELESS_EXT >= 12
-		if (pAd->OpMode == OPMODE_STA)
-		{
-			pNetDev->wireless_handlers = &rt28xx_iw_handler_def;
-		}
-#endif //WIRELESS_EXT >= 12
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef CONFIG_APSTA_MIXED_SUPPORT
-#if WIRELESS_EXT >= 12
-		if (pAd->OpMode == OPMODE_AP)
-		{
-			pNetDev->wireless_handlers = &rt28xx_ap_iw_handler_def;
-		}
-#endif //WIRELESS_EXT >= 12
-#endif // CONFIG_APSTA_MIXED_SUPPORT //
-
-		// copy the net device mac address to the net_device structure.
-		NdisMoveMemory(pNetDev->dev_addr, &pDevOpHook->devAddr[0], MAC_ADDR_LEN);
-
-		rtnl_locked = pDevOpHook->needProtcted;
-	}
-
-	if (rtnl_locked)
-		ret = register_netdevice(pNetDev);
-	else
-		ret = register_netdev(pNetDev);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<---RtmpOSNetDevAttach(), ret=%d\n", ret));
-	if (ret == 0)
-		return NDIS_STATUS_SUCCESS;
-	else
-		return NDIS_STATUS_FAILURE;
-}
-
-
-PNET_DEV RtmpOSNetDevCreate(
-	IN RTMP_ADAPTER *pAd,
-	IN INT			devType,
-	IN INT			devNum,
-	IN INT			privMemSize,
-	IN PSTRING		pNamePrefix)
-{
-	struct net_device *pNetDev = NULL;
-	int status;
-
-
-	/* allocate a new network device */
-	status = RtmpOSNetDevAlloc(&pNetDev, 0 /*privMemSize*/);
-	if (status != NDIS_STATUS_SUCCESS)
-	{
-		/* allocation fail, exit */
-		DBGPRINT(RT_DEBUG_ERROR, ("Allocate network device fail (%s)...\n", pNamePrefix));
-		return NULL;
-	}
-
-
-	/* find a available interface name, max 32 interfaces */
-	status = RtmpOSNetDevRequestName(pAd, pNetDev, pNamePrefix, devNum);
-	if (status != NDIS_STATUS_SUCCESS)
-	{
-		/* error! no any available ra name can be used! */
-		DBGPRINT(RT_DEBUG_ERROR, ("Assign interface name (%s with suffix 0~32) failed...\n", pNamePrefix));
-		RtmpOSNetDevFree(pNetDev);
-
-		return NULL;
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("The name of the new %s interface is %s...\n", pNamePrefix, pNetDev->name));
-	}
-
-	return pNetDev;
-}
diff --git a/drivers/staging/rt3090/rt_linux.h b/drivers/staging/rt3090/rt_linux.h
deleted file mode 100644
index a970e78..0000000
--- a/drivers/staging/rt3090/rt_linux.h
+++ /dev/null
@@ -1,1034 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	rt_linux.h
-
-    Abstract:
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
-*/
-
-#ifndef __RT_LINUX_H__
-#define __RT_LINUX_H__
-
-#include <linux/module.h>
-#include <linux/version.h>
-#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/ethtool.h>
-#include <linux/wireless.h>
-#include <linux/proc_fs.h>
-#include <linux/delay.h>
-#include <linux/if_arp.h>
-#include <linux/ctype.h>
-#include <linux/vmalloc.h>
-#include <linux/wireless.h>
-#include <net/iw_handler.h>
-
-#ifdef INF_AMAZON_PPA
-#include <asm/amazon_se/ifx_ppa_interface.h>
-#include <asm/amazon_se/ifx_ppa_hook.h>
-#endif // INF_AMAZON_PPA //
-
-// load firmware
-#define __KERNEL_SYSCALLS__
-#include <linux/unistd.h>
-#include <asm/uaccess.h>
-#include <asm/types.h>
-#include <asm/unaligned.h>	// for get_unaligned()
-
-#ifdef KTHREAD_SUPPORT
-#include <linux/err.h>
-#include <linux/kthread.h>
-#endif // KTHREAD_SUPPORT //
-
-#undef AP_WSC_INCLUDED
-#undef STA_WSC_INCLUDED
-#undef WSC_INCLUDED
-
-
-#ifdef CONFIG_STA_SUPPORT
-#endif // CONFIG_STA_SUPPORT //
-
-
-#ifdef KTHREAD_SUPPORT
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4)
-#error "This kerne version doesn't support kthread!!"
-#endif
-#endif // KTHREAD_SUPPORT //
-
-/***********************************************************************************
- *	Profile related sections
- ***********************************************************************************/
-
-
-#ifdef CONFIG_STA_SUPPORT
-#ifdef RTMP_MAC_PCI
-#define STA_PROFILE_PATH			"/etc/Wireless/RT2860STA/RT2860STA.dat"
-#define STA_DRIVER_VERSION			"2.1.0.0"
-#ifdef MULTIPLE_CARD_SUPPORT
-#define CARD_INFO_PATH			"/etc/Wireless/RT2860STA/RT2860STACard.dat"
-#endif // MULTIPLE_CARD_SUPPORT //
-#endif // RTMP_MAC_PCI //
-
-
-
-extern	const struct iw_handler_def rt28xx_iw_handler_def;
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef CONFIG_APSTA_MIXED_SUPPORT
-extern	const struct iw_handler_def rt28xx_ap_iw_handler_def;
-#endif // CONFIG_APSTA_MIXED_SUPPORT //
-
-/***********************************************************************************
- *	Compiler related definitions
- ***********************************************************************************/
-#undef __inline
-#define __inline		static inline
-#define IN
-#define OUT
-#define INOUT
-#define NDIS_STATUS		INT
-
-
-/***********************************************************************************
- *	OS Specific definitions and data structures
- ***********************************************************************************/
-typedef struct pci_dev		* PPCI_DEV;
-typedef struct net_device	* PNET_DEV;
-typedef void				* PNDIS_PACKET;
-typedef char				NDIS_PACKET;
-typedef PNDIS_PACKET		* PPNDIS_PACKET;
-typedef	dma_addr_t			NDIS_PHYSICAL_ADDRESS;
-typedef	dma_addr_t			* PNDIS_PHYSICAL_ADDRESS;
-typedef void				* NDIS_HANDLE;
-typedef char				* PNDIS_BUFFER;
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
-typedef	struct pid *	RTMP_OS_PID;
-#else
-typedef pid_t				RTMP_OS_PID;
-#endif
-
-typedef struct semaphore	RTMP_OS_SEM;
-
-#ifdef RTMP_MAC_PCI
-#ifndef PCI_DEVICE
-#define PCI_DEVICE(vend,dev) \
-	.vendor = (vend), .device = (dev), \
-	.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
-#endif // PCI_DEVICE //
-#endif // RTMP_MAC_PCI //
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#define RT_MOD_INC_USE_COUNT() \
-	if (!try_module_get(THIS_MODULE)) \
-	{ \
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: cannot reserve module\n", __FUNCTION__)); \
-		return -1; \
-	}
-
-#define RT_MOD_DEC_USE_COUNT() module_put(THIS_MODULE);
-#else
-#define RT_MOD_INC_USE_COUNT()	MOD_INC_USE_COUNT;
-#define RT_MOD_DEC_USE_COUNT() MOD_DEC_USE_COUNT;
-#endif
-
-#define RTMP_INC_REF(_A)		0
-#define RTMP_DEC_REF(_A)		0
-#define RTMP_GET_REF(_A)		0
-
-
-#if WIRELESS_EXT >= 12
-// This function will be called when query /proc
-struct iw_statistics *rt28xx_get_wireless_stats(
-    IN struct net_device *net_dev);
-#endif
-
-
-/***********************************************************************************
- *	Network related constant definitions
- ***********************************************************************************/
-#ifndef IFNAMSIZ
-#define IFNAMSIZ 16
-#endif
-
-#define ETH_LENGTH_OF_ADDRESS	6
-
-#define NDIS_STATUS_SUCCESS                     0x00
-#define NDIS_STATUS_FAILURE                     0x01
-#define NDIS_STATUS_INVALID_DATA				0x02
-#define NDIS_STATUS_RESOURCES                   0x03
-
-#define NDIS_SET_PACKET_STATUS(_p, _status)			do{} while(0)
-#define NdisWriteErrorLogEntry(_a, _b, _c, _d)		do{} while(0)
-
-/* statistics counter */
-#define STATS_INC_RX_PACKETS(_pAd, _dev)
-#define STATS_INC_TX_PACKETS(_pAd, _dev)
-
-#define STATS_INC_RX_BYTESS(_pAd, _dev, len)
-#define STATS_INC_TX_BYTESS(_pAd, _dev, len)
-
-#define STATS_INC_RX_ERRORS(_pAd, _dev)
-#define STATS_INC_TX_ERRORS(_pAd, _dev)
-
-#define STATS_INC_RX_DROPPED(_pAd, _dev)
-#define STATS_INC_TX_DROPPED(_pAd, _dev)
-
-
-/***********************************************************************************
- *	Ralink Specific network related constant definitions
- ***********************************************************************************/
-#define MIN_NET_DEVICE_FOR_AID			0x00		//0x00~0x3f
-#define MIN_NET_DEVICE_FOR_MBSSID		0x00		//0x00,0x10,0x20,0x30
-#define MIN_NET_DEVICE_FOR_WDS			0x10		//0x40,0x50,0x60,0x70
-#define MIN_NET_DEVICE_FOR_APCLI		0x20
-#define MIN_NET_DEVICE_FOR_MESH			0x30
-#ifdef CONFIG_STA_SUPPORT
-#define MIN_NET_DEVICE_FOR_DLS			0x40
-#endif // CONFIG_STA_SUPPORT //
-#define NET_DEVICE_REAL_IDX_MASK		0x0f		// for each operation mode, we maximum support 15 entities.
-
-
-#ifdef CONFIG_STA_SUPPORT
-#define NDIS_PACKET_TYPE_DIRECTED		0
-#define NDIS_PACKET_TYPE_MULTICAST		1
-#define NDIS_PACKET_TYPE_BROADCAST		2
-#define NDIS_PACKET_TYPE_ALL_MULTICAST	3
-#define NDIS_PACKET_TYPE_PROMISCUOUS	4
-#endif // CONFIG_STA_SUPPORT //
-
-
-/***********************************************************************************
- *	OS signaling related constant definitions
- ***********************************************************************************/
-
-
-/***********************************************************************************
- *	OS file operation related data structure definitions
- ***********************************************************************************/
-typedef struct file* RTMP_OS_FD;
-
-typedef struct _RTMP_OS_FS_INFO_
-{
-	int				fsuid;
-	int				fsgid;
-	mm_segment_t	fs;
-}RTMP_OS_FS_INFO;
-
-#define IS_FILE_OPEN_ERR(_fd)	IS_ERR((_fd))
-
-
-/***********************************************************************************
- *	OS semaphore related data structure and definitions
- ***********************************************************************************/
-struct os_lock  {
-	spinlock_t		lock;
-	unsigned long	flags;
-};
-
-typedef spinlock_t			NDIS_SPIN_LOCK;
-
-//
-//  spin_lock enhanced for Nested spin lock
-//
-#define NdisAllocateSpinLock(__lock)      \
-{                                       \
-    spin_lock_init((spinlock_t *)(__lock));               \
-}
-
-#define NdisFreeSpinLock(lock)          \
-	do{}while(0)
-
-
-#define RTMP_SEM_LOCK(__lock)					\
-{												\
-	spin_lock_bh((spinlock_t *)(__lock));		\
-}
-
-#define RTMP_SEM_UNLOCK(__lock)					\
-{												\
-	spin_unlock_bh((spinlock_t *)(__lock));		\
-}
-
-
-// sample, use semaphore lock to replace IRQ lock, 2007/11/15
-#define RTMP_IRQ_LOCK(__lock, __irqflags)			\
-{													\
-	__irqflags = 0;									\
-	spin_lock_bh((spinlock_t *)(__lock));			\
-	pAd->irq_disabled |= 1; \
-}
-
-#define RTMP_IRQ_UNLOCK(__lock, __irqflag)			\
-{													\
-	pAd->irq_disabled &= 0;							\
-	spin_unlock_bh((spinlock_t *)(__lock));			\
-}
-
-#define RTMP_INT_LOCK(__lock, __irqflags)			\
-{													\
-	spin_lock_irqsave((spinlock_t *)__lock, __irqflags);	\
-}
-
-#define RTMP_INT_UNLOCK(__lock, __irqflag)			\
-{													\
-	spin_unlock_irqrestore((spinlock_t *)(__lock), ((unsigned long)__irqflag));	\
-}
-
-#define NdisAcquireSpinLock		RTMP_SEM_LOCK
-#define NdisReleaseSpinLock		RTMP_SEM_UNLOCK
-
-#ifndef wait_event_interruptible_timeout
-#define __wait_event_interruptible_timeout(wq, condition, ret) \
-do { \
-        wait_queue_t __wait; \
-        init_waitqueue_entry(&__wait, current); \
-        add_wait_queue(&wq, &__wait); \
-        for (;;) { \
-                set_current_state(TASK_INTERRUPTIBLE); \
-                if (condition) \
-                        break; \
-                if (!signal_pending(current)) { \
-                        ret = schedule_timeout(ret); \
-                        if (!ret) \
-                                break; \
-                        continue; \
-                } \
-                ret = -ERESTARTSYS; \
-                break; \
-        } \
-        current->state = TASK_RUNNING; \
-        remove_wait_queue(&wq, &__wait); \
-} while (0)
-
-#define wait_event_interruptible_timeout(wq, condition, timeout) \
-({ \
-        long __ret = timeout; \
-        if (!(condition)) \
-                __wait_event_interruptible_timeout(wq, condition, __ret); \
-        __ret; \
-})
-#endif
-
-#define RTMP_SEM_EVENT_INIT_LOCKED(_pSema)	sema_init((_pSema), 0)
-#define RTMP_SEM_EVENT_INIT(_pSema)			sema_init((_pSema), 1)
-#define RTMP_SEM_EVENT_WAIT(_pSema, _status)	((_status) = down_interruptible((_pSema)))
-#define RTMP_SEM_EVENT_UP(_pSema)			up(_pSema)
-
-#ifdef KTHREAD_SUPPORT
-#define RTMP_WAIT_EVENT_INTERRUPTIBLE(_pAd, _pTask) \
-{ \
-		wait_event_interruptible(_pTask->kthread_q, \
-								 _pTask->kthread_running || kthread_should_stop()); \
-		_pTask->kthread_running = FALSE; \
-		if (kthread_should_stop()) \
-		{ \
-			RTMP_SET_FLAG(_pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); \
-			break; \
-		} \
-}
-#endif
-
-#ifdef KTHREAD_SUPPORT
-#define WAKE_UP(_pTask) \
-	do{ \
-		if ((_pTask)->kthread_task) \
-        { \
-			(_pTask)->kthread_running = TRUE; \
-	        wake_up(&(_pTask)->kthread_q); \
-		} \
-	}while(0)
-#endif
-
-/***********************************************************************************
- *	OS Memory Access related data structure and definitions
- ***********************************************************************************/
-#define MEM_ALLOC_FLAG      (GFP_ATOMIC) //(GFP_DMA | GFP_ATOMIC)
-
-#define NdisMoveMemory(Destination, Source, Length) memmove(Destination, Source, Length)
-#define NdisCopyMemory(Destination, Source, Length) memcpy(Destination, Source, Length)
-#define NdisZeroMemory(Destination, Length)         memset(Destination, 0, Length)
-#define NdisFillMemory(Destination, Length, Fill)   memset(Destination, Fill, Length)
-#define NdisCmpMemory(Destination, Source, Length)  memcmp(Destination, Source, Length)
-#define NdisEqualMemory(Source1, Source2, Length)   (!memcmp(Source1, Source2, Length))
-#define RTMPEqualMemory(Source1, Source2, Length)	(!memcmp(Source1, Source2, Length))
-
-#define MlmeAllocateMemory(_pAd, _ppVA)		os_alloc_mem(_pAd, _ppVA, MGMT_DMA_BUFFER_SIZE)
-#define MlmeFreeMemory(_pAd, _pVA)			os_free_mem(_pAd, _pVA)
-
-#define COPY_MAC_ADDR(Addr1, Addr2)             memcpy((Addr1), (Addr2), MAC_ADDR_LEN)
-
-
-/***********************************************************************************
- *	OS task related data structure and definitions
- ***********************************************************************************/
-#define RTMP_OS_MGMT_TASK_FLAGS	CLONE_VM
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
-typedef	struct pid *	THREAD_PID;
-#define	THREAD_PID_INIT_VALUE	NULL
-#define	GET_PID(_v)	find_get_pid((_v))
-#define	GET_PID_NUMBER(_v)	pid_nr((_v))
-#define CHECK_PID_LEGALITY(_pid)	if (pid_nr((_pid)) >= 0)
-#define KILL_THREAD_PID(_A, _B, _C)	kill_pid((_A), (_B), (_C))
-#else
-typedef	pid_t	THREAD_PID;
-#define	THREAD_PID_INIT_VALUE	-1
-#define	GET_PID(_v)	(_v)
-#define	GET_PID_NUMBER(_v)	(_v)
-#define CHECK_PID_LEGALITY(_pid)	if ((_pid) >= 0)
-#define KILL_THREAD_PID(_A, _B, _C)	kill_proc((_A), (_B), (_C))
-#endif
-
-typedef struct tasklet_struct  RTMP_NET_TASK_STRUCT;
-typedef struct tasklet_struct  *PRTMP_NET_TASK_STRUCT;
-
-
-/***********************************************************************************
- * Timer related definitions and data structures.
- **********************************************************************************/
-#define OS_HZ			HZ
-
-typedef struct timer_list	NDIS_MINIPORT_TIMER;
-typedef struct timer_list	RTMP_OS_TIMER;
-typedef void (*TIMER_FUNCTION)(unsigned long);
-
-
-#define OS_WAIT(_time) \
-{	int _i; \
-	long _loop = ((_time)/(1000/OS_HZ)) > 0 ? ((_time)/(1000/OS_HZ)) : 1;\
-	wait_queue_head_t _wait; \
-	init_waitqueue_head(&_wait); \
-	for (_i=0; _i<(_loop); _i++) \
-		wait_event_interruptible_timeout(_wait, 0, ONE_TICK); }
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#define RTMP_TIME_AFTER(a,b)		\
-	(typecheck(unsigned long, (unsigned long)a) && \
-	 typecheck(unsigned long, (unsigned long)b) && \
-	 ((long)(b) - (long)(a) < 0))
-
-#define RTMP_TIME_AFTER_EQ(a,b)	\
-	(typecheck(unsigned long, (unsigned long)a) && \
-	 typecheck(unsigned long, (unsigned long)b) && \
-	 ((long)(a) - (long)(b) >= 0))
-#define RTMP_TIME_BEFORE(a,b)	RTMP_TIME_AFTER_EQ(b,a)
-#else
-#define typecheck(type,x) \
-({      type __dummy; \
-        typeof(x) __dummy2; \
-        (void)(&__dummy == &__dummy2); \
-        1; \
-})
-#define RTMP_TIME_AFTER_EQ(a,b)	\
-	(typecheck(unsigned long, (unsigned long)a) && \
-	 typecheck(unsigned long, (unsigned long)b) && \
-	 ((long)(a) - (long)(b) >= 0))
-#define RTMP_TIME_BEFORE(a,b)	RTMP_TIME_AFTER_EQ(b,a)
-#define RTMP_TIME_AFTER(a,b) time_after(a, b)
-#endif
-
-#define ONE_TICK 1
-
-static inline void NdisGetSystemUpTime(ULONG *time)
-{
-	*time = jiffies;
-}
-
-
-/***********************************************************************************
- *	OS specific cookie data structure binding to RTMP_ADAPTER
- ***********************************************************************************/
-
-struct os_cookie {
-#ifdef RTMP_MAC_PCI
-	struct pci_dev			*pci_dev;
-	struct pci_dev			*parent_pci_dev;
-	USHORT                  DeviceID;
-	dma_addr_t				pAd_pa;
-#endif // RTMP_MAC_PCI //
-
-
-	RTMP_NET_TASK_STRUCT rx_done_task;
-	RTMP_NET_TASK_STRUCT mgmt_dma_done_task;
-	RTMP_NET_TASK_STRUCT ac0_dma_done_task;
-	RTMP_NET_TASK_STRUCT ac1_dma_done_task;
-	RTMP_NET_TASK_STRUCT ac2_dma_done_task;
-	RTMP_NET_TASK_STRUCT ac3_dma_done_task;
-	/*RTMP_NET_TASK_STRUCT hcca_dma_done_task;*/
-	RTMP_NET_TASK_STRUCT tbtt_task;
-#ifdef RTMP_MAC_PCI
-	RTMP_NET_TASK_STRUCT fifo_statistic_full_task;
-#endif // RTMP_MAC_PCI //
-
-
-
-	unsigned long			apd_pid; //802.1x daemon pid
-	INT						ioctl_if_type;
-	INT					ioctl_if;
-};
-
-typedef struct os_cookie	* POS_COOKIE;
-
-
-
-/***********************************************************************************
- *	OS debugging and printing related definitions and data structure
- ***********************************************************************************/
-#define PRINT_MAC(addr)	\
-	addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
-
-#ifdef DBG
-extern ULONG		RTDebugLevel;
-
-#define DBGPRINT_RAW(Level, Fmt)    \
-do{                                   \
-    if (Level <= RTDebugLevel)      \
-    {                               \
-        printk Fmt;               \
-    }                               \
-}while(0)
-
-#define DBGPRINT(Level, Fmt)    DBGPRINT_RAW(Level, Fmt)
-
-
-#define DBGPRINT_ERR(Fmt)           \
-{                                   \
-    printk("ERROR!!! ");          \
-    printk Fmt;                  \
-}
-
-#define DBGPRINT_S(Status, Fmt)		\
-{									\
-	printk Fmt;					\
-}
-#else
-#define DBGPRINT(Level, Fmt)
-#define DBGPRINT_RAW(Level, Fmt)
-#define DBGPRINT_S(Status, Fmt)
-#define DBGPRINT_ERR(Fmt)
-#endif
-
-#undef  ASSERT
-#define ASSERT(x)                                                               \
-{                                                                               \
-    if (!(x))                                                                   \
-    {                                                                           \
-        printk(KERN_WARNING __FILE__ ":%d assert " #x "failed\n", __LINE__);    \
-    }                                                                           \
-}
-
-void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen);
-
-
-/*********************************************************************************************************
-	The following code are not revised, temporary put it here.
-  *********************************************************************************************************/
-
-
-/***********************************************************************************
- * Device DMA Access related definitions and data structures.
- **********************************************************************************/
-#ifdef RTMP_MAC_PCI
-dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, int sd_idx, int direction);
-void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, int direction);
-
-#define PCI_MAP_SINGLE(_handle, _ptr, _size, _sd_idx, _dir) \
-	linux_pci_map_single(_handle, _ptr, _size, _sd_idx, _dir)
-
-#define PCI_UNMAP_SINGLE(_handle, _ptr, _size, _dir) \
-	linux_pci_unmap_single(_handle, _ptr, _size, _dir)
-
-#define PCI_ALLOC_CONSISTENT(_pci_dev, _size, _ptr) \
-	pci_alloc_consistent(_pci_dev, _size, _ptr)
-
-#define PCI_FREE_CONSISTENT(_pci_dev, _size, _virtual_addr, _physical_addr) \
-	pci_free_consistent(_pci_dev, _size, _virtual_addr, _physical_addr)
-
-#define DEV_ALLOC_SKB(_length) \
-	dev_alloc_skb(_length)
-#endif // RTMP_MAC_PCI //
-
-
-
-/*
- * ULONG
- * RTMP_GetPhysicalAddressLow(
- *   IN NDIS_PHYSICAL_ADDRESS  PhysicalAddress);
- */
-#define RTMP_GetPhysicalAddressLow(PhysicalAddress)		(PhysicalAddress)
-
-/*
- * ULONG
- * RTMP_GetPhysicalAddressHigh(
- *   IN NDIS_PHYSICAL_ADDRESS  PhysicalAddress);
- */
-#define RTMP_GetPhysicalAddressHigh(PhysicalAddress)		(0)
-
-/*
- * VOID
- * RTMP_SetPhysicalAddressLow(
- *   IN NDIS_PHYSICAL_ADDRESS  PhysicalAddress,
- *   IN ULONG  Value);
- */
-#define RTMP_SetPhysicalAddressLow(PhysicalAddress, Value)	\
-			PhysicalAddress = Value;
-
-/*
- * VOID
- * RTMP_SetPhysicalAddressHigh(
- *   IN NDIS_PHYSICAL_ADDRESS  PhysicalAddress,
- *   IN ULONG  Value);
- */
-#define RTMP_SetPhysicalAddressHigh(PhysicalAddress, Value)
-
-#define NdisMIndicateStatus(_w, _x, _y, _z)
-
-
-
-/***********************************************************************************
- * Device Register I/O Access related definitions and data structures.
- **********************************************************************************/
-#ifdef RTMP_MAC_PCI
-#if defined(INF_TWINPASS) || defined(INF_DANUBE) || defined(IKANOS_VX_1X0)
-//Patch for ASIC turst read/write bug, needs to remove after metel fix
-#define RTMP_IO_READ32(_A, _R, _pV)									\
-{																	\
-    if ((_A)->bPCIclkOff == FALSE)                                      \
-    {                                                                   \
-	(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)));		\
-	(*_pV = readl((void *)((_A)->CSRBaseAddress + (_R))));			\
-	(*_pV = SWAP32(*((UINT32 *)(_pV))));                           \
-    }                                                                   \
-}
-
-#define RTMP_IO_READ8(_A, _R, _pV)									\
-{																	\
-	(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)));		\
-	(*_pV = readb((void *)((_A)->CSRBaseAddress + (_R))));			\
-}
-
-#define RTMP_IO_WRITE32(_A, _R, _V)									\
-{																	\
-    if ((_A)->bPCIclkOff == FALSE)                                      \
-    {                                                                   \
-	UINT32	_Val;													\
-	_Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));		\
-	_Val = SWAP32(_V);												\
-	writel(_Val, (void *)((_A)->CSRBaseAddress + (_R)));			\
-    }                                                                   \
-}
-
-#define RTMP_IO_WRITE8(_A, _R, _V)									\
-{																	\
-	UINT	Val;													\
-	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));		\
-	writeb((_V), (PUCHAR)((_A)->CSRBaseAddress + (_R)));			\
-}
-
-#define RTMP_IO_WRITE16(_A, _R, _V)									\
-{																	\
-	UINT	Val;													\
-	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));		\
-	writew(SWAP16((_V)), (PUSHORT)((_A)->CSRBaseAddress + (_R)));	\
-}
-#else
-//Patch for ASIC turst read/write bug, needs to remove after metel fix
-#define RTMP_IO_READ32(_A, _R, _pV)								\
-{																\
-    if ((_A)->bPCIclkOff == FALSE)                                  \
-    {                                                               \
-		(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)));		\
-		(*_pV = readl((void *)((_A)->CSRBaseAddress + (_R))));			\
-    }                                                               \
-    else															\
-		*_pV = 0;													\
-}
-
-#define RTMP_IO_FORCE_READ32(_A, _R, _pV)							\
-{																	\
-	(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)));		\
-	(*_pV = readl((void *)((_A)->CSRBaseAddress + (_R))));			\
-}
-
-#define RTMP_IO_READ8(_A, _R, _pV)								\
-{																\
-	(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)));			\
-	(*_pV = readb((void *)((_A)->CSRBaseAddress + (_R))));				\
-}
-
-#define RTMP_IO_WRITE32(_A, _R, _V)												\
-{																				\
-    if ((_A)->bPCIclkOff == FALSE)                                  \
-    {                                                               \
-	UINT	Val;																\
-	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));			\
-	writel((_V), (void *)((_A)->CSRBaseAddress + (_R)));								\
-    }                                                               \
-}
-
-#define RTMP_IO_FORCE_WRITE32(_A, _R, _V)												\
-{																				\
-	UINT	Val;																\
-	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));			\
-	writel(_V, (void *)((_A)->CSRBaseAddress + (_R)));								\
-}
-
-
-
-#if defined(BRCM_6358) || defined(RALINK_2880) || defined(RALINK_3052)
-#define RTMP_IO_WRITE8(_A, _R, _V)            \
-{                    \
-	ULONG Val;                \
-	UCHAR _i;                \
-	_i = ((_R) & 0x3);             \
-	Val = readl((void *)((_A)->CSRBaseAddress + ((_R) - _i)));   \
-	Val = Val & (~(0x000000ff << ((_i)*8)));         \
-	Val = Val | ((ULONG)(_V) << ((_i)*8));         \
-	writel((Val), (void *)((_A)->CSRBaseAddress + ((_R) - _i)));    \
-}
-#else
-#define RTMP_IO_WRITE8(_A, _R, _V)							\
-{															\
-	UINT	Val;												\
-	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));	\
-	writeb((_V), (PUCHAR)((_A)->CSRBaseAddress + (_R)));		\
-}
-#endif // #if defined(BRCM_6358) || defined(RALINK_2880) //
-
-#define RTMP_IO_WRITE16(_A, _R, _V)							\
-{															\
-	UINT	Val;											\
-	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));	\
-	writew((_V), (PUSHORT)((_A)->CSRBaseAddress + (_R)));	\
-}
-#endif // #if defined(INF_TWINPASS) || defined(INF_DANUBE) || defined(IKANOS_VX_1X0) //
-#endif // RTMP_MAC_PCI //
-
-
-
-/***********************************************************************************
- *	Network Related data structure and marco definitions
- ***********************************************************************************/
-#define PKTSRC_NDIS             0x7f
-#define PKTSRC_DRIVER           0x0f
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
-#define RTMP_OS_NETDEV_SET_PRIV(_pNetDev, _pPriv)	((_pNetDev)->priv = (_pPriv))
-#define RTMP_OS_NETDEV_GET_PRIV(_pNetDev)		((_pNetDev)->priv)
-#else
-#define RTMP_OS_NETDEV_SET_PRIV(_pNetDev, _pPriv)	((_pNetDev)->ml_priv = (_pPriv))
-#define RTMP_OS_NETDEV_GET_PRIV(_pNetDev)		((_pNetDev)->ml_priv)
-#endif
-#define RTMP_OS_NETDEV_GET_DEVNAME(_pNetDev)	((_pNetDev)->name)
-#define RTMP_OS_NETDEV_GET_PHYADDR(_PNETDEV)	((_PNETDEV)->dev_addr)
-
-#define RTMP_OS_NETDEV_START_QUEUE(_pNetDev)	netif_start_queue((_pNetDev))
-#define RTMP_OS_NETDEV_STOP_QUEUE(_pNetDev)	netif_stop_queue((_pNetDev))
-#define RTMP_OS_NETDEV_WAKE_QUEUE(_pNetDev)	netif_wake_queue((_pNetDev))
-#define RTMP_OS_NETDEV_CARRIER_OFF(_pNetDev)	netif_carrier_off((_pNetDev))
-
-#define QUEUE_ENTRY_TO_PACKET(pEntry) \
-	(PNDIS_PACKET)(pEntry)
-
-#define PACKET_TO_QUEUE_ENTRY(pPacket) \
-	(PQUEUE_ENTRY)(pPacket)
-
-#ifdef CONFIG_5VT_ENHANCE
-#define BRIDGE_TAG 0x35564252    // depends on 5VT define in br_input.c
-#endif
-
-#define GET_SG_LIST_FROM_PACKET(_p, _sc)	\
-    rt_get_sg_list_from_packet(_p, _sc)
-
-#define RELEASE_NDIS_PACKET(_pAd, _pPacket, _Status)                    \
-{                                                                       \
-        RTMPFreeNdisPacket(_pAd, _pPacket);                             \
-}
-
-/*
- * packet helper
- *	- convert internal rt packet to os packet or
- *             os packet to rt packet
- */
-#define RTPKT_TO_OSPKT(_p)		((struct sk_buff *)(_p))
-#define OSPKT_TO_RTPKT(_p)		((PNDIS_PACKET)(_p))
-
-#define GET_OS_PKT_DATAPTR(_pkt) \
-		(RTPKT_TO_OSPKT(_pkt)->data)
-#define SET_OS_PKT_DATAPTR(_pkt, _dataPtr)	\
-		(RTPKT_TO_OSPKT(_pkt)->data) = (_dataPtr)
-
-#define GET_OS_PKT_LEN(_pkt) \
-		(RTPKT_TO_OSPKT(_pkt)->len)
-#define SET_OS_PKT_LEN(_pkt, _len)	\
-		(RTPKT_TO_OSPKT(_pkt)->len) = (_len)
-
-#define GET_OS_PKT_DATATAIL(_pkt) \
-		(RTPKT_TO_OSPKT(_pkt)->tail)
-#define SET_OS_PKT_DATATAIL(_pkt, _start, _len)	\
-		((RTPKT_TO_OSPKT(_pkt))->tail) = (PUCHAR)((_start) + (_len))
-
-#define GET_OS_PKT_HEAD(_pkt) \
-		(RTPKT_TO_OSPKT(_pkt)->head)
-
-#define GET_OS_PKT_END(_pkt) \
-		(RTPKT_TO_OSPKT(_pkt)->end)
-
-#define GET_OS_PKT_NETDEV(_pkt) \
-		(RTPKT_TO_OSPKT(_pkt)->dev)
-#define SET_OS_PKT_NETDEV(_pkt, _pNetDev)	\
-		(RTPKT_TO_OSPKT(_pkt)->dev) = (_pNetDev)
-
-#define GET_OS_PKT_TYPE(_pkt) \
-		(RTPKT_TO_OSPKT(_pkt))
-
-#define GET_OS_PKT_NEXT(_pkt) \
-		(RTPKT_TO_OSPKT(_pkt)->next)
-
-
-#define OS_PKT_CLONED(_pkt)		skb_cloned(RTPKT_TO_OSPKT(_pkt))
-
-#define OS_NTOHS(_Val) \
-		(ntohs(_Val))
-#define OS_HTONS(_Val) \
-		(htons(_Val))
-#define OS_NTOHL(_Val) \
-		(ntohl(_Val))
-#define OS_HTONL(_Val) \
-		(htonl(_Val))
-
-#define CB_OFF  10
-
-// User Priority
-#define RTMP_SET_PACKET_UP(_p, _prio)			(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0] = _prio)
-#define RTMP_GET_PACKET_UP(_p)					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0])
-
-// Fragment #
-#define RTMP_SET_PACKET_FRAGMENTS(_p, _num)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1] = _num)
-#define RTMP_GET_PACKET_FRAGMENTS(_p)			(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1])
-
-// 0x0 ~0x7f: TX to AP's own BSS which has the specified AID. if AID>127, set bit 7 in RTMP_SET_PACKET_EMACTAB too.
-//(this value also as MAC(on-chip WCID) table index)
-// 0x80~0xff: TX to a WDS link. b0~6: WDS index
-#define RTMP_SET_PACKET_WCID(_p, _wdsidx)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2] = _wdsidx)
-#define RTMP_GET_PACKET_WCID(_p)			((UCHAR)(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2]))
-
-// 0xff: PKTSRC_NDIS, others: local TX buffer index. This value affects how to a packet
-#define RTMP_SET_PACKET_SOURCE(_p, _pktsrc)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3] = _pktsrc)
-#define RTMP_GET_PACKET_SOURCE(_p)			(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3])
-
-// RTS/CTS-to-self protection method
-#define RTMP_SET_PACKET_RTS(_p, _num)			(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4] = _num)
-#define RTMP_GET_PACKET_RTS(_p)				(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4])
-// see RTMP_S(G)ET_PACKET_EMACTAB
-
-// TX rate index
-#define RTMP_SET_PACKET_TXRATE(_p, _rate)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5] = _rate)
-#define RTMP_GET_PACKET_TXRATE(_p)				(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5])
-
-// From which Interface
-#define RTMP_SET_PACKET_IF(_p, _ifdx)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6] = _ifdx)
-#define RTMP_GET_PACKET_IF(_p)				(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6])
-#define RTMP_SET_PACKET_NET_DEVICE_MBSSID(_p, _bss)		RTMP_SET_PACKET_IF((_p), (_bss))
-#define RTMP_SET_PACKET_NET_DEVICE_WDS(_p, _bss)		RTMP_SET_PACKET_IF((_p), ((_bss) + MIN_NET_DEVICE_FOR_WDS))
-#define RTMP_SET_PACKET_NET_DEVICE_APCLI(_p, _idx)	RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_APCLI))
-#define RTMP_SET_PACKET_NET_DEVICE_MESH(_p, _idx)	RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_MESH))
-#define RTMP_GET_PACKET_NET_DEVICE_MBSSID(_p)			RTMP_GET_PACKET_IF((_p))
-#define RTMP_GET_PACKET_NET_DEVICE(_p)					RTMP_GET_PACKET_IF((_p))
-
-#define RTMP_SET_PACKET_MOREDATA(_p, _morebit)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7] = _morebit)
-#define RTMP_GET_PACKET_MOREDATA(_p)				(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7])
-
-
-
-
-
-//
-//	Sepcific Pakcet Type definition
-//
-#define RTMP_PACKET_SPECIFIC_CB_OFFSET	11
-
-#define RTMP_PACKET_SPECIFIC_DHCP		0x01
-#define RTMP_PACKET_SPECIFIC_EAPOL		0x02
-#define RTMP_PACKET_SPECIFIC_IPV4		0x04
-#define RTMP_PACKET_SPECIFIC_WAI		0x08
-#define RTMP_PACKET_SPECIFIC_VLAN		0x10
-#define RTMP_PACKET_SPECIFIC_LLCSNAP	0x20
-
-//Specific
-#define RTMP_SET_PACKET_SPECIFIC(_p, _flg)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] = _flg)
-
-//DHCP
-#define RTMP_SET_PACKET_DHCP(_p, _flg)														\
-			do{																				\
-				if (_flg)																	\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_DHCP);		\
-				else																		\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_DHCP);	\
-			}while(0)
-#define RTMP_GET_PACKET_DHCP(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_DHCP)
-
-//EAPOL
-#define RTMP_SET_PACKET_EAPOL(_p, _flg)														\
-			do{																				\
-				if (_flg)																	\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_EAPOL);		\
-				else																		\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_EAPOL);	\
-			}while(0)
-#define RTMP_GET_PACKET_EAPOL(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_EAPOL)
-
-//WAI
-#define RTMP_SET_PACKET_WAI(_p, _flg)														\
-			do{																				\
-				if (_flg)																	\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_WAI);		\
-				else																		\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_WAI);	\
-			}while(0)
-#define RTMP_GET_PACKET_WAI(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_WAI)
-
-#define RTMP_GET_PACKET_LOWRATE(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & (RTMP_PACKET_SPECIFIC_EAPOL | RTMP_PACKET_SPECIFIC_DHCP | RTMP_PACKET_SPECIFIC_WAI))
-
-//VLAN
-#define RTMP_SET_PACKET_VLAN(_p, _flg)														\
-			do{																				\
-				if (_flg)																	\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_VLAN);		\
-				else																		\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_VLAN);	\
-			}while(0)
-#define RTMP_GET_PACKET_VLAN(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_VLAN)
-
-//LLC/SNAP
-#define RTMP_SET_PACKET_LLCSNAP(_p, _flg)													\
-			do{																				\
-				if (_flg)																	\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_LLCSNAP);		\
-				else																		\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_LLCSNAP);		\
-			}while(0)
-
-#define RTMP_GET_PACKET_LLCSNAP(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_LLCSNAP)
-
-// IP
-#define RTMP_SET_PACKET_IPV4(_p, _flg)														\
-			do{																				\
-				if (_flg)																	\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_IPV4);		\
-				else																		\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_IPV4);	\
-			}while(0)
-
-#define RTMP_GET_PACKET_IPV4(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_IPV4)
-
-
-// If this flag is set, it indicates that this EAPoL frame MUST be clear.
-#define RTMP_SET_PACKET_CLEAR_EAP_FRAME(_p, _flg)   (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12] = _flg)
-#define RTMP_GET_PACKET_CLEAR_EAP_FRAME(_p)         (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12])
-
-
-
-/* use bit3 of cb[CB_OFF+16] */
-
-#define RTMP_SET_PACKET_5VT(_p, _flg)   (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22] = _flg)
-#define RTMP_GET_PACKET_5VT(_p)         (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22])
-
-#ifdef INF_AMAZON_SE
-/* [CB_OFF+28], 1B, Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate */
-#define RTMP_SET_PACKET_NOBULKOUT(_p, _morebit)			(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+28] = _morebit)
-#define RTMP_GET_PACKET_NOBULKOUT(_p)					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+28])
-#endif // INF_AMAZON_SE //
-/* Max skb->cb = 48B = [CB_OFF+38] */
-
-
-
-/***********************************************************************************
- *	Other function prototypes definitions
- ***********************************************************************************/
-void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time);
-int rt28xx_packet_xmit(struct sk_buff *skb);
-
-
-void FlashWrite(UCHAR * p, ULONG a, ULONG b);
-void FlashRead(UCHAR * p, ULONG a, ULONG b);
-
-#if LINUX_VERSION_CODE <= 0x20402	// Red Hat 7.1
-struct net_device *alloc_netdev(int sizeof_priv, const char *mask, void (*setup)(struct net_device *));
-#endif // LINUX_VERSION_CODE //
-
-
-#ifdef RTMP_MAC_PCI
-/* function declarations */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#define IRQ_HANDLE_TYPE  irqreturn_t
-#else
-#define IRQ_HANDLE_TYPE  void
-#endif
-
-IRQ_HANDLE_TYPE
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19))
-rt2860_interrupt(int irq, void *dev_instance);
-#else
-rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
-#endif
-
-#endif // RTMP_MAC_PCI //
-
-INT rt28xx_ioctl(
-	IN	PNET_DEV		net_dev,
-	IN	OUT	struct ifreq	*rq,
-	IN	INT			cmd);
-
-
-#ifdef CONFIG_STA_SUPPORT
-INT rt28xx_sta_ioctl(
-	IN	PNET_DEV		net_dev,
-	IN	OUT	struct ifreq	*rq,
-	IN	INT			cmd);
-#endif // CONFIG_STA_SUPPORT //
-
-extern int ra_mtd_write(int num, loff_t to, size_t len, const u_char *buf);
-extern int ra_mtd_read(int num, loff_t from, size_t len, u_char *buf);
-
-#endif // __RT_LINUX_H__ //
diff --git a/drivers/staging/rt3090/rt_main_dev.c b/drivers/staging/rt3090/rt_main_dev.c
deleted file mode 100644
index 3307a5f..0000000
--- a/drivers/staging/rt3090/rt_main_dev.c
+++ /dev/null
@@ -1,897 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    rt_main_dev.c
-
-    Abstract:
-    Create and register network interface.
-
-    Revision History:
-    Who         When            What
-    --------    ----------      ----------------------------------------------
-*/
-
-#include "rt_config.h"
-
-
-#ifdef CONFIG_APSTA_MIXED_SUPPORT
-UINT32 CW_MAX_IN_BITS;
-#endif // CONFIG_APSTA_MIXED_SUPPORT //
-
-/*---------------------------------------------------------------------*/
-/* Private Variables Used                                              */
-/*---------------------------------------------------------------------*/
-
-PSTRING mac = "";		   // default 00:00:00:00:00:00
-PSTRING hostname = "";		   // default CMPC
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
-MODULE_PARM (mac, "s");
-#else
-module_param (mac, charp, 0);
-#endif
-MODULE_PARM_DESC (mac, "rt28xx: wireless mac addr");
-
-
-/*---------------------------------------------------------------------*/
-/* Prototypes of Functions Used                                        */
-/*---------------------------------------------------------------------*/
-
-// public function prototype
-int rt28xx_close(IN struct net_device *net_dev);
-int rt28xx_open(struct net_device *net_dev);
-
-// private function prototype
-static INT rt28xx_send_packets(IN struct sk_buff *skb_p, IN struct net_device *net_dev);
-
-
-static struct net_device_stats *RT28xx_get_ether_stats(
-    IN  struct net_device *net_dev);
-
-/*
-========================================================================
-Routine Description:
-    Close raxx interface.
-
-Arguments:
-	*net_dev			the raxx interface pointer
-
-Return Value:
-    0					Open OK
-	otherwise			Open Fail
-
-Note:
-	1. if open fail, kernel will not call the close function.
-	2. Free memory for
-		(1) Mlme Memory Handler:		MlmeHalt()
-		(2) TX & RX:					RTMPFreeTxRxRingMemory()
-		(3) BA Reordering:				ba_reordering_resource_release()
-========================================================================
-*/
-int MainVirtualIF_close(IN struct net_device *net_dev)
-{
-    RTMP_ADAPTER *pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
-
-	// Sanity check for pAd
-	if (pAd == NULL)
-		return 0; // close ok
-
-	netif_carrier_off(pAd->net_dev);
-	netif_stop_queue(pAd->net_dev);
-
-
-
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		BOOLEAN			Cancelled;
-#ifdef QOS_DLS_SUPPORT
-		// send DLS-TEAR_DOWN message,
-		if (pAd->CommonCfg.bDLSCapable)
-		{
-			UCHAR i;
-
-			// tear down local dls table entry
-			for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
-			{
-				if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
-				{
-					RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
-					pAd->StaCfg.DLSEntry[i].Status	= DLS_NONE;
-					pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
-				}
-			}
-
-			// tear down peer dls table entry
-			for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
-			{
-				if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
-				{
-					RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
-					pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
-					pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
-				}
-			}
-			RTMP_MLME_HANDLER(pAd);
-		}
-#endif // QOS_DLS_SUPPORT //
-
-		if (INFRA_ON(pAd) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
-		{
-			MLME_DISASSOC_REQ_STRUCT	DisReq;
-			MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
-
-			if (MsgElem)
-			{
-			COPY_MAC_ADDR(DisReq.Addr, pAd->CommonCfg.Bssid);
-			DisReq.Reason =  REASON_DEAUTH_STA_LEAVING;
-
-			MsgElem->Machine = ASSOC_STATE_MACHINE;
-			MsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
-			MsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
-			NdisMoveMemory(MsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
-
-			// Prevent to connect AP again in STAMlmePeriodicExec
-			pAd->MlmeAux.AutoReconnectSsidLen= 32;
-			NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
-
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
-			MlmeDisassocReqAction(pAd, MsgElem);
-			kfree(MsgElem);
-			}
-
-			RTMPusecDelay(1000);
-		}
-
-		RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, &Cancelled);
-		RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, &Cancelled);
-
-#ifdef WPA_SUPPLICANT_SUPPORT
-#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
-		// send wireless event to wpa_supplicant for infroming interface down.
-		RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, RT_INTERFACE_DOWN, NULL, NULL, 0);
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	VIRTUAL_IF_DOWN(pAd);
-
-	RT_MOD_DEC_USE_COUNT();
-
-	return 0; // close ok
-}
-
-/*
-========================================================================
-Routine Description:
-    Open raxx interface.
-
-Arguments:
-	*net_dev			the raxx interface pointer
-
-Return Value:
-    0					Open OK
-	otherwise			Open Fail
-
-Note:
-	1. if open fail, kernel will not call the close function.
-	2. Free memory for
-		(1) Mlme Memory Handler:		MlmeHalt()
-		(2) TX & RX:					RTMPFreeTxRxRingMemory()
-		(3) BA Reordering:				ba_reordering_resource_release()
-========================================================================
-*/
-int MainVirtualIF_open(IN struct net_device *net_dev)
-{
-    RTMP_ADAPTER *pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
-
-	// Sanity check for pAd
-	if (pAd == NULL)
-		return 0; // close ok
-
-	if (VIRTUAL_IF_UP(pAd) != 0)
-		return -1;
-
-	// increase MODULE use count
-	RT_MOD_INC_USE_COUNT();
-
-	netif_start_queue(net_dev);
-	netif_carrier_on(net_dev);
-	netif_wake_queue(net_dev);
-
-	return 0;
-}
-
-/*
-========================================================================
-Routine Description:
-    Close raxx interface.
-
-Arguments:
-	*net_dev			the raxx interface pointer
-
-Return Value:
-    0					Open OK
-	otherwise			Open Fail
-
-Note:
-	1. if open fail, kernel will not call the close function.
-	2. Free memory for
-		(1) Mlme Memory Handler:		MlmeHalt()
-		(2) TX & RX:					RTMPFreeTxRxRingMemory()
-		(3) BA Reordering:				ba_reordering_resource_release()
-========================================================================
-*/
-int rt28xx_close(IN PNET_DEV dev)
-{
-	struct net_device * net_dev = (struct net_device *)dev;
-    RTMP_ADAPTER	*pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
-	BOOLEAN			Cancelled;
-	UINT32			i = 0;
-
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n"));
-
-	Cancelled = FALSE;
-	// Sanity check for pAd
-	if (pAd == NULL)
-		return 0; // close ok
-
-
-
-#ifdef WDS_SUPPORT
-	WdsDown(pAd);
-#endif // WDS_SUPPORT //
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-#ifdef RTMP_MAC_PCI
-		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_CLOSE);
-#endif // RTMP_MAC_PCI //
-
-		// If dirver doesn't wake up firmware here,
-		// NICLoadFirmware will hang forever when interface is up again.
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-        {
-		    AsicForceWakeup(pAd, TRUE);
-        }
-
-
-		MlmeRadioOff(pAd);
-#ifdef RTMP_MAC_PCI
-		pAd->bPCIclkOff = FALSE;
-#endif // RTMP_MAC_PCI //
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-
-	for (i = 0 ; i < NUM_OF_TX_RING; i++)
-	{
-		while (pAd->DeQueueRunning[i] == TRUE)
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("Waiting for TxQueue[%d] done..........\n", i));
-			RTMPusecDelay(1000);
-		}
-	}
-
-
-
-	// Stop Mlme state machine
-	MlmeHalt(pAd);
-
-	// Close net tasklets
-	RtmpNetTaskExit(pAd);
-
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		MacTableReset(pAd);
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-
-	MeasureReqTabExit(pAd);
-	TpcReqTabExit(pAd);
-
-
-	// Close kernel threads
-	RtmpMgmtTaskExit(pAd);
-
-#ifdef RTMP_MAC_PCI
-	{
-			BOOLEAN brc;
-			//	ULONG			Value;
-
-			if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
-			{
-				RTMP_ASIC_INTERRUPT_DISABLE(pAd);
-			}
-
-			// Receive packets to clear DMA index after disable interrupt.
-			//RTMPHandleRxDoneInterrupt(pAd);
-			// put to radio off to save power when driver unload.  After radiooff, can't write /read register.  So need to finish all
-			// register access before Radio off.
-
-
-			brc=RT28xxPciAsicRadioOff(pAd, RTMP_HALT, 0);
-
-//In  solution 3 of 3090F, the bPCIclkOff will be set to TRUE after calling RT28xxPciAsicRadioOff
-			pAd->bPCIclkOff = FALSE;
-
-			if (brc==FALSE)
-			{
-				DBGPRINT(RT_DEBUG_ERROR,("%s call RT28xxPciAsicRadioOff fail !!\n", __FUNCTION__));
-			}
-	}
-
-
-/*
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
-	{
-		RTMP_ASIC_INTERRUPT_DISABLE(pAd);
-	}
-
-	// Disable Rx, register value supposed will remain after reset
-	NICIssueReset(pAd);
-*/
-#endif // RTMP_MAC_PCI //
-
-	// Free IRQ
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
-#ifdef RTMP_MAC_PCI
-		// Deregister interrupt function
-		RTMP_IRQ_RELEASE(net_dev)
-#endif // RTMP_MAC_PCI //
-		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
-	}
-
-	// Free Ring or USB buffers
-	RTMPFreeTxRxRingMemory(pAd);
-
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-
-#ifdef DOT11_N_SUPPORT
-	// Free BA reorder resource
-	ba_reordering_resource_release(pAd);
-#endif // DOT11_N_SUPPORT //
-
-#ifdef CONFIG_STA_SUPPORT
-#endif // CONFIG_STA_SUPPORT //
-
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP);
-
-/*+++Modify by woody to solve the bulk fail+++*/
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt28xx_close\n"));
-	return 0; // close ok
-} /* End of rt28xx_close */
-
-
-/*
-========================================================================
-Routine Description:
-    Open raxx interface.
-
-Arguments:
-	*net_dev			the raxx interface pointer
-
-Return Value:
-    0					Open OK
-	otherwise			Open Fail
-
-Note:
-========================================================================
-*/
-int rt28xx_open(IN PNET_DEV dev)
-{
-	struct net_device * net_dev = (struct net_device *)dev;
-	PRTMP_ADAPTER pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
-	int retval = 0;
-	//POS_COOKIE pObj;
-
-
-	// Sanity check for pAd
-	if (pAd == NULL)
-	{
-		/* if 1st open fail, pAd will be free;
-		   So the net_dev->priv will be NULL in 2rd open */
-		return -1;
-	}
-
-#ifdef CONFIG_APSTA_MIXED_SUPPORT
-	if (pAd->OpMode == OPMODE_AP)
-	{
-		CW_MAX_IN_BITS = 6;
-	}
-	else if (pAd->OpMode == OPMODE_STA)
-	{
-		CW_MAX_IN_BITS = 10;
-	}
-#endif // CONFIG_APSTA_MIXED_SUPPORT //
-
-#if WIRELESS_EXT >= 12
-	if (net_dev->priv_flags == INT_MAIN)
-	{
-#ifdef CONFIG_APSTA_MIXED_SUPPORT
-		if (pAd->OpMode == OPMODE_AP)
-			net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_ap_iw_handler_def;
-#endif // CONFIG_APSTA_MIXED_SUPPORT //
-#ifdef CONFIG_STA_SUPPORT
-		if (pAd->OpMode == OPMODE_STA)
-			net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_iw_handler_def;
-#endif // CONFIG_STA_SUPPORT //
-	}
-#endif // WIRELESS_EXT >= 12 //
-
-	// Request interrupt service routine for PCI device
-	// register the interrupt routine with the os
-	RTMP_IRQ_REQUEST(net_dev);
-
-	// Init IRQ parameters stored in pAd
-	RTMP_IRQ_INIT(pAd);
-
-	// Chip & other init
-	if (rt28xx_init(pAd, mac, hostname) == FALSE)
-		goto err;
-
-#ifdef CONFIG_STA_SUPPORT
-#endif // CONFIG_STA_SUPPORT //
-
-	// Enable Interrupt
-	RTMP_IRQ_ENABLE(pAd);
-
-	// Now Enable RxTx
-	RTMPEnableRxTx(pAd);
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP);
-
-	{
-	UINT32 reg = 0;
-	RTMP_IO_READ32(pAd, 0x1300, &reg);  // clear garbage interrupts
-	printk("0x1300 = %08x\n", reg);
-	}
-
-	{
-//	u32 reg;
-//	UINT8  byte;
-//	u16 tmp;
-
-//	RTMP_IO_READ32(pAd, XIFS_TIME_CFG, &reg);
-
-//	tmp = 0x0805;
-//	reg  = (reg & 0xffff0000) | tmp;
-//	RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg);
-
-	}
-
-
-#ifdef CONFIG_STA_SUPPORT
-#ifdef RTMP_MAC_PCI
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-        RTMPInitPCIeLinkCtrlValue(pAd);
-#endif // RTMP_MAC_PCI //
-#endif // CONFIG_STA_SUPPORT //
-
-	return (retval);
-
-err:
-//+++Add by shiang, move from rt28xx_init() to here.
-	RTMP_IRQ_RELEASE(net_dev);
-//---Add by shiang, move from rt28xx_init() to here.
-	return (-1);
-} /* End of rt28xx_open */
-
-static const struct net_device_ops rt3090_netdev_ops = {
-	.ndo_open		= MainVirtualIF_open,
-	.ndo_stop		= MainVirtualIF_close,
-	.ndo_do_ioctl		= rt28xx_ioctl,
-	.ndo_get_stats		= RT28xx_get_ether_stats,
-	.ndo_set_mac_address	= eth_mac_addr,
-	.ndo_change_mtu		= eth_change_mtu,
-#ifdef IKANOS_VX_1X0
-	.ndo_start_xmit		= IKANOS_DataFramesTx,
-#else
-	.ndo_start_xmit		= rt28xx_send_packets,
-#endif
-};
-
-PNET_DEV RtmpPhyNetDevInit(
-	IN RTMP_ADAPTER *pAd,
-	IN RTMP_OS_NETDEV_OP_HOOK *pNetDevHook)
-{
-	struct net_device	*net_dev = NULL;
-//	NDIS_STATUS		Status;
-
-	net_dev = RtmpOSNetDevCreate(pAd, INT_MAIN, 0, sizeof(PRTMP_ADAPTER), INF_MAIN_DEV_NAME);
-	if (net_dev == NULL)
-	{
-		printk("RtmpPhyNetDevInit(): creation failed for main physical net device!\n");
-		return NULL;
-	}
-
-	NdisZeroMemory((unsigned char *)pNetDevHook, sizeof(RTMP_OS_NETDEV_OP_HOOK));
-	pNetDevHook->netdev_ops = &rt3090_netdev_ops;
-	pNetDevHook->priv_flags = INT_MAIN;
-	pNetDevHook->needProtcted = FALSE;
-
-	RTMP_OS_NETDEV_SET_PRIV(net_dev, pAd);
-	//net_dev->priv = (PVOID)pAd;
-	pAd->net_dev = net_dev;
-
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
-	SET_MODULE_OWNER(net_dev);
-#endif
-
-	netif_stop_queue(net_dev);
-
-	return net_dev;
-
-}
-
-
-/*
-========================================================================
-Routine Description:
-    The entry point for Linux kernel sent packet to our driver.
-
-Arguments:
-    sk_buff *skb		the pointer refer to a sk_buffer.
-
-Return Value:
-    0
-
-Note:
-	This function is the entry point of Tx Path for Os delivery packet to
-	our driver. You only can put OS-depened & STA/AP common handle procedures
-	in here.
-========================================================================
-*/
-int rt28xx_packet_xmit(struct sk_buff *skb)
-{
-	struct net_device *net_dev = skb->dev;
-	PRTMP_ADAPTER pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
-	int status = 0;
-	PNDIS_PACKET pPacket = (PNDIS_PACKET) skb;
-
-	/* RT2870STA does this in RTMPSendPackets() */
-#ifdef RALINK_ATE
-	if (ATE_ON(pAd))
-	{
-		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_RESOURCES);
-		return 0;
-	}
-#endif // RALINK_ATE //
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		// Drop send request since we are in monitor mode
-		if (MONITOR_ON(pAd))
-		{
-			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-			goto done;
-		}
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-        // EapolStart size is 18
-	if (skb->len < 14)
-	{
-		//printk("bad packet size: %d\n", pkt->len);
-		hex_dump("bad packet", skb->data, skb->len);
-		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-		goto done;
-	}
-
-
-
-	RTMP_SET_PACKET_5VT(pPacket, 0);
-//	MiniportMMRequest(pAd, pkt->data, pkt->len);
-#ifdef CONFIG_5VT_ENHANCE
-    if (*(int*)(skb->cb) == BRIDGE_TAG) {
-		RTMP_SET_PACKET_5VT(pPacket, 1);
-    }
-#endif
-
-
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-
-		STASendPackets((NDIS_HANDLE)pAd, (PPNDIS_PACKET) &pPacket, 1);
-	}
-
-#endif // CONFIG_STA_SUPPORT //
-
-	status = 0;
-done:
-
-	return status;
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Send a packet to WLAN.
-
-Arguments:
-    skb_p           points to our adapter
-    dev_p           which WLAN network interface
-
-Return Value:
-    0: transmit successfully
-    otherwise: transmit fail
-
-Note:
-========================================================================
-*/
-static int rt28xx_send_packets(
-	IN struct sk_buff		*skb_p,
-	IN struct net_device	*net_dev)
-{
-	RTMP_ADAPTER *pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
-
-	if (!(net_dev->flags & IFF_UP))
-	{
-		RELEASE_NDIS_PACKET(pAd, (PNDIS_PACKET)skb_p, NDIS_STATUS_FAILURE);
-		return 0;
-	}
-
-	NdisZeroMemory((PUCHAR)&skb_p->cb[CB_OFF], 15);
-	RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p, MAIN_MBSSID);
-
-	return rt28xx_packet_xmit(skb_p);
-}
-
-
-#if WIRELESS_EXT >= 12
-// This function will be called when query /proc
-struct iw_statistics *rt28xx_get_wireless_stats(
-    IN struct net_device *net_dev)
-{
-	PRTMP_ADAPTER pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
-
-
-
-	DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n"));
-
-	pAd->iw_stats.status = 0; // Status - device dependent for now
-
-	// link quality
-#ifdef CONFIG_STA_SUPPORT
-	if (pAd->OpMode == OPMODE_STA)
-	pAd->iw_stats.qual.qual = ((pAd->Mlme.ChannelQuality * 12)/10 + 10);
-#endif // CONFIG_STA_SUPPORT //
-
-	if(pAd->iw_stats.qual.qual > 100)
-		pAd->iw_stats.qual.qual = 100;
-
-#ifdef CONFIG_STA_SUPPORT
-	if (pAd->OpMode == OPMODE_STA)
-	{
-		pAd->iw_stats.qual.level =
-			RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0,
-							pAd->StaCfg.RssiSample.LastRssi1,
-							pAd->StaCfg.RssiSample.LastRssi2);
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	pAd->iw_stats.qual.noise = pAd->BbpWriteLatch[66]; // noise level (dBm)
-
-	pAd->iw_stats.qual.noise += 256 - 143;
-	pAd->iw_stats.qual.updated = 1;     // Flags to know if updated
-#ifdef IW_QUAL_DBM
-	pAd->iw_stats.qual.updated |= IW_QUAL_DBM;	// Level + Noise are dBm
-#endif // IW_QUAL_DBM //
-
-	pAd->iw_stats.discard.nwid = 0;     // Rx : Wrong nwid/essid
-	pAd->iw_stats.miss.beacon = 0;      // Missed beacons/superframe
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n"));
-	return &pAd->iw_stats;
-}
-#endif // WIRELESS_EXT //
-
-
-void tbtt_tasklet(unsigned long data)
-{
-//#define MAX_TX_IN_TBTT		(16)
-
-}
-
-INT rt28xx_ioctl(
-	IN	PNET_DEV	net_dev,
-	IN	OUT	struct ifreq	*rq,
-	IN	INT					cmd)
-{
-	RTMP_ADAPTER	*pAd = NULL;
-	INT				ret = 0;
-
-	pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
-	if (pAd == NULL)
-	{
-		/* if 1st open fail, pAd will be free;
-		   So the net_dev->priv will be NULL in 2rd open */
-		return -ENETDOWN;
-	}
-
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		ret = rt28xx_sta_ioctl(net_dev, rq, cmd);
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-	return ret;
-}
-
-
-/*
-    ========================================================================
-
-    Routine Description:
-        return ethernet statistics counter
-
-    Arguments:
-        net_dev                     Pointer to net_device
-
-    Return Value:
-        net_device_stats*
-
-    Note:
-
-    ========================================================================
-*/
-static struct net_device_stats *RT28xx_get_ether_stats(
-    IN  struct net_device *net_dev)
-{
-    RTMP_ADAPTER *pAd = NULL;
-
-	if (net_dev)
-		pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
-
-	if (pAd)
-	{
-
-		pAd->stats.rx_packets = pAd->WlanCounters.ReceivedFragmentCount.QuadPart;
-		pAd->stats.tx_packets = pAd->WlanCounters.TransmittedFragmentCount.QuadPart;
-
-		pAd->stats.rx_bytes = pAd->RalinkCounters.ReceivedByteCount;
-		pAd->stats.tx_bytes = pAd->RalinkCounters.TransmittedByteCount;
-
-		pAd->stats.rx_errors = pAd->Counters8023.RxErrors;
-		pAd->stats.tx_errors = pAd->Counters8023.TxErrors;
-
-		pAd->stats.rx_dropped = 0;
-		pAd->stats.tx_dropped = 0;
-
-	    pAd->stats.multicast = pAd->WlanCounters.MulticastReceivedFrameCount.QuadPart;   // multicast packets received
-	    pAd->stats.collisions = pAd->Counters8023.OneCollision + pAd->Counters8023.MoreCollisions;  // Collision packets
-
-	    pAd->stats.rx_length_errors = 0;
-	    pAd->stats.rx_over_errors = pAd->Counters8023.RxNoBuffer;                   // receiver ring buff overflow
-	    pAd->stats.rx_crc_errors = 0;//pAd->WlanCounters.FCSErrorCount;     // recved pkt with crc error
-	    pAd->stats.rx_frame_errors = pAd->Counters8023.RcvAlignmentErrors;          // recv'd frame alignment error
-	    pAd->stats.rx_fifo_errors = pAd->Counters8023.RxNoBuffer;                   // recv'r fifo overrun
-	    pAd->stats.rx_missed_errors = 0;                                            // receiver missed packet
-
-	    // detailed tx_errors
-	    pAd->stats.tx_aborted_errors = 0;
-	    pAd->stats.tx_carrier_errors = 0;
-	    pAd->stats.tx_fifo_errors = 0;
-	    pAd->stats.tx_heartbeat_errors = 0;
-	    pAd->stats.tx_window_errors = 0;
-
-	    // for cslip etc
-	    pAd->stats.rx_compressed = 0;
-	    pAd->stats.tx_compressed = 0;
-
-		return &pAd->stats;
-	}
-	else
-	return NULL;
-}
-
-
-BOOLEAN RtmpPhyNetDevExit(
-	IN RTMP_ADAPTER *pAd,
-	IN PNET_DEV net_dev)
-{
-
-
-
-#ifdef INF_AMAZON_PPA
-	if (ppa_hook_directpath_register_dev_fn && pAd->PPAEnable==TRUE)
-	{
-		UINT status;
-		status=ppa_hook_directpath_register_dev_fn(&pAd->g_if_id, pAd->net_dev, NULL, PPA_F_DIRECTPATH_DEREGISTER);
-		printk("unregister PPA:g_if_id=%d status=%d\n",pAd->g_if_id,status);
-	}
-	kfree(pAd->pDirectpathCb);
-#endif // INF_AMAZON_PPA //
-
-	// Unregister network device
-	if (net_dev != NULL)
-	{
-		printk("RtmpOSNetDevDetach(): RtmpOSNetDeviceDetach(), dev->name=%s!\n", net_dev->name);
-		RtmpOSNetDevDetach(net_dev);
-	}
-
-	return TRUE;
-
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Allocate memory for adapter control block.
-
-Arguments:
-    pAd					Pointer to our adapter
-
-Return Value:
-	NDIS_STATUS_SUCCESS
-	NDIS_STATUS_FAILURE
-	NDIS_STATUS_RESOURCES
-
-Note:
-========================================================================
-*/
-NDIS_STATUS AdapterBlockAllocateMemory(
-	IN PVOID	handle,
-	OUT	PVOID	*ppAd)
-{
-
-	*ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER)); //pci_alloc_consistent(pci_dev, sizeof(RTMP_ADAPTER), phy_addr);
-
-	if (*ppAd)
-	{
-		NdisZeroMemory(*ppAd, sizeof(RTMP_ADAPTER));
-		((PRTMP_ADAPTER)*ppAd)->OS_Cookie = handle;
-		return (NDIS_STATUS_SUCCESS);
-	} else {
-		return (NDIS_STATUS_FAILURE);
-	}
-}
diff --git a/drivers/staging/rt3090/rt_pci_rbus.c b/drivers/staging/rt3090/rt_pci_rbus.c
deleted file mode 100644
index 2991319..0000000
--- a/drivers/staging/rt3090/rt_pci_rbus.c
+++ /dev/null
@@ -1,989 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    rt_pci_rbus.c
-
-    Abstract:
-    Create and register network interface.
-
-    Revision History:
-    Who         When            What
-    --------    ----------      ----------------------------------------------
-*/
-
-#include "rt_config.h"
-#include <linux/pci.h>
-
-
-IRQ_HANDLE_TYPE
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19))
-rt2860_interrupt(int irq, void *dev_instance);
-#else
-rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
-#endif
-
-
-static void rx_done_tasklet(unsigned long data);
-static void mgmt_dma_done_tasklet(unsigned long data);
-static void ac0_dma_done_tasklet(unsigned long data);
-static void ac1_dma_done_tasklet(unsigned long data);
-static void ac2_dma_done_tasklet(unsigned long data);
-static void ac3_dma_done_tasklet(unsigned long data);
-/*static void hcca_dma_done_tasklet(unsigned long data);*/
-static void fifo_statistic_full_tasklet(unsigned long data);
-
-
-
-/*---------------------------------------------------------------------*/
-/* Symbol & Macro Definitions                                          */
-/*---------------------------------------------------------------------*/
-#define RT2860_INT_RX_DLY				(1<<0)		// bit 0
-#define RT2860_INT_TX_DLY				(1<<1)		// bit 1
-#define RT2860_INT_RX_DONE				(1<<2)		// bit 2
-#define RT2860_INT_AC0_DMA_DONE			(1<<3)		// bit 3
-#define RT2860_INT_AC1_DMA_DONE			(1<<4)		// bit 4
-#define RT2860_INT_AC2_DMA_DONE			(1<<5)		// bit 5
-#define RT2860_INT_AC3_DMA_DONE			(1<<6)		// bit 6
-#define RT2860_INT_HCCA_DMA_DONE		(1<<7)		// bit 7
-#define RT2860_INT_MGMT_DONE			(1<<8)		// bit 8
-#ifdef TONE_RADAR_DETECT_SUPPORT
-#define RT2860_INT_TONE_RADAR			(1<<20)		// bit 20
-#endif // TONE_RADAR_DETECT_SUPPORT //
-
-#define INT_RX			RT2860_INT_RX_DONE
-
-#define INT_AC0_DLY		(RT2860_INT_AC0_DMA_DONE) //| RT2860_INT_TX_DLY)
-#define INT_AC1_DLY		(RT2860_INT_AC1_DMA_DONE) //| RT2860_INT_TX_DLY)
-#define INT_AC2_DLY		(RT2860_INT_AC2_DMA_DONE) //| RT2860_INT_TX_DLY)
-#define INT_AC3_DLY		(RT2860_INT_AC3_DMA_DONE) //| RT2860_INT_TX_DLY)
-#define INT_HCCA_DLY	(RT2860_INT_HCCA_DMA_DONE) //| RT2860_INT_TX_DLY)
-#define INT_MGMT_DLY	RT2860_INT_MGMT_DONE
-#ifdef TONE_RADAR_DETECT_SUPPORT
-#define INT_TONE_RADAR	(RT2860_INT_TONE_RADAR)
-#endif // TONE_RADAR_DETECT_SUPPORT //
-
-
-/***************************************************************************
-  *
-  *	Interface-depended memory allocation/Free related procedures.
-  *		Mainly for Hardware TxDesc/RxDesc/MgmtDesc, DMA Memory for TxData/RxData, etc.,
-  *
-  **************************************************************************/
-// Function for TxDesc Memory allocation.
-void RTMP_AllocateTxDescMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	UINT	Index,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
-{
-	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	*VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
-
-}
-
-
-// Function for MgmtDesc Memory allocation.
-void RTMP_AllocateMgmtDescMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
-{
-	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	*VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
-
-}
-
-
-// Function for RxDesc Memory allocation.
-void RTMP_AllocateRxDescMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
-{
-	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	*VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
-
-}
-
-
-// Function for free allocated Desc Memory.
-void RTMP_FreeDescMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	PVOID	VirtualAddress,
-	IN	NDIS_PHYSICAL_ADDRESS PhysicalAddress)
-{
-	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	pci_free_consistent(pObj->pci_dev, Length, VirtualAddress, PhysicalAddress);
-}
-
-
-// Function for TxData DMA Memory allocation.
-void RTMP_AllocateFirstTxBuffer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	UINT	Index,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
-{
-	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	*VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
-}
-
-
-void RTMP_FreeFirstTxBuffer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	IN	PVOID	VirtualAddress,
-	IN	NDIS_PHYSICAL_ADDRESS PhysicalAddress)
-{
-	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	pci_free_consistent(pObj->pci_dev, Length, VirtualAddress, PhysicalAddress);
-}
-
-
-/*
- * FUNCTION: Allocate a common buffer for DMA
- * ARGUMENTS:
- *     AdapterHandle:  AdapterHandle
- *     Length:  Number of bytes to allocate
- *     Cached:  Whether or not the memory can be cached
- *     VirtualAddress:  Pointer to memory is returned here
- *     PhysicalAddress:  Physical address corresponding to virtual address
- */
-void RTMP_AllocateSharedMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
-{
-	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	*VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
-}
-
-
-/*
- * FUNCTION: Allocate a packet buffer for DMA
- * ARGUMENTS:
- *     AdapterHandle:  AdapterHandle
- *     Length:  Number of bytes to allocate
- *     Cached:  Whether or not the memory can be cached
- *     VirtualAddress:  Pointer to memory is returned here
- *     PhysicalAddress:  Physical address corresponding to virtual address
- * Notes:
- *     Cached is ignored: always cached memory
- */
-PNDIS_PACKET RTMP_AllocateRxPacketBuffer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
-{
-	struct sk_buff *pkt;
-
-	pkt = dev_alloc_skb(Length);
-
-	if (pkt == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR, ("can't allocate rx %ld size packet\n",Length));
-	}
-
-	if (pkt) {
-		RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
-		*VirtualAddress = (PVOID) pkt->data;
-//#ifdef CONFIG_5VT_ENHANCE
-//		*PhysicalAddress = PCI_MAP_SINGLE(pAd, *VirtualAddress, 1600, PCI_DMA_FROMDEVICE);
-//#else
-		*PhysicalAddress = PCI_MAP_SINGLE(pAd, *VirtualAddress, Length,  -1, PCI_DMA_FROMDEVICE);
-//#endif
-	} else {
-		*VirtualAddress = (PVOID) NULL;
-		*PhysicalAddress = (NDIS_PHYSICAL_ADDRESS) NULL;
-	}
-
-	return (PNDIS_PACKET) pkt;
-}
-
-
-VOID Invalid_Remaining_Packet(
-	IN	PRTMP_ADAPTER pAd,
-	IN	 ULONG VirtualAddress)
-{
-	NDIS_PHYSICAL_ADDRESS PhysicalAddress;
-
-	PhysicalAddress = PCI_MAP_SINGLE(pAd, (void *)(VirtualAddress+1600), RX_BUFFER_NORMSIZE-1600, -1, PCI_DMA_FROMDEVICE);
-}
-
-
-int RtmpOSIRQRequest(IN struct net_device *net_dev)
-{
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)(RTMP_OS_NETDEV_GET_PRIV(net_dev));
-	int retval = 0;
-
-	ASSERT(pAd);
-
-	if (pAd->infType != RTMP_DEV_INF_RBUS)
-	{
-		POS_COOKIE _pObj = (POS_COOKIE)(pAd->OS_Cookie);
-		RTMP_MSI_ENABLE(pAd);
-		retval = request_irq(_pObj->pci_dev->irq,  rt2860_interrupt, SA_SHIRQ, (net_dev)->name, (net_dev));
-		if (retval != 0)
-			printk("RT2860: request_irq  ERROR(%d)\n", retval);
-	}
-	else
-	{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-		if ((retval = request_irq(net_dev->irq, rt2860_interrupt, IRQF_SHARED, net_dev->name ,net_dev)))
-#else
-		if ((retval = request_irq(net_dev->irq,rt2860_interrupt, SA_INTERRUPT, net_dev->name ,net_dev)))
-#endif
-		{
-			printk("RT2860: request_irq  ERROR(%d)\n", retval);
-		}
-	}
-
-	return retval;
-
-}
-
-
-int RtmpOSIRQRelease(IN struct net_device *net_dev)
-{
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)(RTMP_OS_NETDEV_GET_PRIV(net_dev));
-
-	ASSERT(pAd);
-	if (pAd->infType != RTMP_DEV_INF_RBUS)
-	{
-		POS_COOKIE pObj = (POS_COOKIE)(pAd->OS_Cookie);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-		synchronize_irq(pObj->pci_dev->irq);
-#endif
-		free_irq(pObj->pci_dev->irq, (net_dev));
-		RTMP_MSI_DISABLE(pAd);
-	}
-	else
-	{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-		synchronize_irq(net_dev->irq);
-#endif
-		free_irq(net_dev->irq, (net_dev));
-	}
-
-	return 0;
-}
-
-
-NDIS_STATUS RtmpNetTaskInit(IN RTMP_ADAPTER *pAd)
-{
-	POS_COOKIE pObj;
-
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->mgmt_dma_done_task, mgmt_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->ac0_dma_done_task, ac0_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->ac1_dma_done_task, ac1_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->ac2_dma_done_task, ac2_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->ac3_dma_done_task, ac3_dma_done_tasklet, (unsigned long)pAd);
-	/*tasklet_init(&pObj->hcca_dma_done_task, hcca_dma_done_tasklet, (unsigned long)pAd);*/
-	tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->fifo_statistic_full_task, fifo_statistic_full_tasklet, (unsigned long)pAd);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-void RtmpNetTaskExit(IN RTMP_ADAPTER *pAd)
-{
-	POS_COOKIE pObj;
-
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	tasklet_kill(&pObj->rx_done_task);
-	tasklet_kill(&pObj->mgmt_dma_done_task);
-	tasklet_kill(&pObj->ac0_dma_done_task);
-	tasklet_kill(&pObj->ac1_dma_done_task);
-	tasklet_kill(&pObj->ac2_dma_done_task);
-	tasklet_kill(&pObj->ac3_dma_done_task);
-	/*tasklet_kill(&pObj->hcca_dma_done_task);*/
-	tasklet_kill(&pObj->tbtt_task);
-	tasklet_kill(&pObj->fifo_statistic_full_task);
-}
-
-
-NDIS_STATUS RtmpMgmtTaskInit(IN RTMP_ADAPTER *pAd)
-{
-
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Close kernel threads.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-    NONE
-
-Note:
-========================================================================
-*/
-VOID RtmpMgmtTaskExit(
-	IN RTMP_ADAPTER *pAd)
-{
-
-
-	return;
-}
-
-
-static inline void rt2860_int_enable(PRTMP_ADAPTER pAd, unsigned int mode)
-{
-	u32 regValue;
-
-	pAd->int_disable_mask &= ~(mode);
-	regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask);
-	//if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-	{
-		RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue);     // 1:enable
-	}
-	//else
-	//	DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_DOZE !\n"));
-
-	if (regValue != 0)
-		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
-}
-
-
-static inline void rt2860_int_disable(PRTMP_ADAPTER pAd, unsigned int mode)
-{
-	u32 regValue;
-
-	pAd->int_disable_mask |= mode;
-	regValue =	pAd->int_enable_reg & ~(pAd->int_disable_mask);
-	RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue);     // 0: disable
-
-	if (regValue == 0)
-	{
-		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
-	}
-}
-
-
-/***************************************************************************
-  *
-  *	tasklet related procedures.
-  *
-  **************************************************************************/
-static void mgmt_dma_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
-    INT_SOURCE_CSR_STRUC	IntSource;
-	POS_COOKIE pObj;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-    pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-//	printk("mgmt_dma_done_process\n");
-	IntSource.word = 0;
-	IntSource.field.MgmtDmaDone = 1;
-	pAd->int_pending &= ~INT_MGMT_DLY;
-
-	RTMPHandleMgmtRingDmaDoneInterrupt(pAd);
-
-	// if you use RTMP_SEM_LOCK, sometimes kernel will hang up, no any
-	// bug report output
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid lose of interrupts
-	 */
-	if (pAd->int_pending & INT_MGMT_DLY)
-	{
-		tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable TxDataInt again */
-	rt2860_int_enable(pAd, INT_MGMT_DLY);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-}
-
-
-static void rx_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
-	BOOLEAN	bReschedule = 0;
-	POS_COOKIE pObj;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-#ifdef UAPSD_AP_SUPPORT
-	UAPSD_TIMING_RECORD(pAd, UAPSD_TIMING_RECORD_TASKLET);
-#endif // UAPSD_AP_SUPPORT //
-
-    pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	pAd->int_pending &= ~(INT_RX);
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		bReschedule = STARxDoneInterruptHandle(pAd, 0);
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef UAPSD_AP_SUPPORT
-	UAPSD_TIMING_RECORD_STOP();
-#endif // UAPSD_AP_SUPPORT //
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid rotting packet
-	 */
-	if (pAd->int_pending & INT_RX || bReschedule)
-	{
-		tasklet_hi_schedule(&pObj->rx_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable RxINT again */
-	rt2860_int_enable(pAd, INT_RX);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-
-}
-
-
-void fifo_statistic_full_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
-	POS_COOKIE pObj;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-    pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	pAd->int_pending &= ~(FifoStaFullInt);
-	NICUpdateFifoStaCounters(pAd);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid rotting packet
-	 */
-	if (pAd->int_pending & FifoStaFullInt)
-	{
-		tasklet_hi_schedule(&pObj->fifo_statistic_full_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable RxINT again */
-
-	rt2860_int_enable(pAd, FifoStaFullInt);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-
-}
-
-
-
-
-static void ac3_dma_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
-    INT_SOURCE_CSR_STRUC	IntSource;
-	POS_COOKIE pObj;
-	BOOLEAN bReschedule = 0;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-    pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-//	printk("ac0_dma_done_process\n");
-	IntSource.word = 0;
-	IntSource.field.Ac3DmaDone = 1;
-	pAd->int_pending &= ~INT_AC3_DLY;
-
-	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid lose of interrupts
-	 */
-	if ((pAd->int_pending & INT_AC3_DLY) || bReschedule)
-	{
-		tasklet_hi_schedule(&pObj->ac3_dma_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable TxDataInt again */
-	rt2860_int_enable(pAd, INT_AC3_DLY);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-}
-
-
-static void ac2_dma_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
-    INT_SOURCE_CSR_STRUC	IntSource;
-	POS_COOKIE pObj;
-	BOOLEAN bReschedule = 0;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-    pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	IntSource.word = 0;
-	IntSource.field.Ac2DmaDone = 1;
-	pAd->int_pending &= ~INT_AC2_DLY;
-
-	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-
-	/*
-	 * double check to avoid lose of interrupts
-	 */
-	if ((pAd->int_pending & INT_AC2_DLY) || bReschedule)
-	{
-		tasklet_hi_schedule(&pObj->ac2_dma_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable TxDataInt again */
-	rt2860_int_enable(pAd, INT_AC2_DLY);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-}
-
-
-static void ac1_dma_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
-    INT_SOURCE_CSR_STRUC	IntSource;
-	POS_COOKIE pObj;
-	BOOLEAN bReschedule = 0;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-    pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-//	printk("ac0_dma_done_process\n");
-	IntSource.word = 0;
-	IntSource.field.Ac1DmaDone = 1;
-	pAd->int_pending &= ~INT_AC1_DLY;
-
-	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid lose of interrupts
-	 */
-	if ((pAd->int_pending & INT_AC1_DLY) || bReschedule)
-	{
-		tasklet_hi_schedule(&pObj->ac1_dma_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable TxDataInt again */
-	rt2860_int_enable(pAd, INT_AC1_DLY);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-}
-
-
-static void ac0_dma_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
-	INT_SOURCE_CSR_STRUC	IntSource;
-	POS_COOKIE pObj;
-	BOOLEAN bReschedule = 0;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-//	printk("ac0_dma_done_process\n");
-	IntSource.word = 0;
-	IntSource.field.Ac0DmaDone = 1;
-	pAd->int_pending &= ~INT_AC0_DLY;
-
-//	RTMPHandleMgmtRingDmaDoneInterrupt(pAd);
-	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid lose of interrupts
-	 */
-	if ((pAd->int_pending & INT_AC0_DLY) || bReschedule)
-	{
-		tasklet_hi_schedule(&pObj->ac0_dma_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable TxDataInt again */
-	rt2860_int_enable(pAd, INT_AC0_DLY);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-}
-
-
-
-
-/***************************************************************************
-  *
-  *	interrupt handler related procedures.
-  *
-  **************************************************************************/
-int print_int_count;
-
-IRQ_HANDLE_TYPE
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19))
-rt2860_interrupt(int irq, void *dev_instance)
-#else
-rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
-#endif
-{
-	struct net_device *net_dev = (struct net_device *) dev_instance;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) RTMP_OS_NETDEV_GET_PRIV(net_dev);
-	INT_SOURCE_CSR_STRUC	IntSource;
-	POS_COOKIE pObj;
-
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-
-	/* Note 03312008: we can not return here before
-		RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
-		RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word);
-		Or kernel will panic after ifconfig ra0 down sometimes */
-
-
-	//
-	// Inital the Interrupt source.
-	//
-	IntSource.word = 0x00000000L;
-//	McuIntSource.word = 0x00000000L;
-
-	//
-	// Get the interrupt sources & saved to local variable
-	//
-	//RTMP_IO_READ32(pAd, where, &McuIntSource.word);
-	//RTMP_IO_WRITE32(pAd, , McuIntSource.word);
-
-	//
-	// Flag fOP_STATUS_DOZE On, means ASIC put to sleep, elase means ASICK WakeUp
-	// And at the same time, clock maybe turned off that say there is no DMA service.
-	// when ASIC get to sleep.
-	// To prevent system hang on power saving.
-	// We need to check it before handle the INT_SOURCE_CSR, ASIC must be wake up.
-	//
-	// RT2661 => when ASIC is sleeping, MAC register cannot be read and written.
-	// RT2860 => when ASIC is sleeping, MAC register can be read and written.
-//	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-	{
-		RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
-		RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word); // write 1 to clear
-	}
-//	else
-//		DBGPRINT(RT_DEBUG_TRACE, (">>>fOP_STATUS_DOZE<<<\n"));
-
-//	RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IsrAfterClear);
-//	RTMP_IO_READ32(pAd, MCU_INT_SOURCE_CSR, &McuIsrAfterClear);
-//	DBGPRINT(RT_DEBUG_INFO, ("====> RTMPHandleInterrupt(ISR=%08x,Mcu ISR=%08x, After clear ISR=%08x, MCU ISR=%08x)\n",
-//			IntSource.word, McuIntSource.word, IsrAfterClear, McuIsrAfterClear));
-
-	// Do nothing if Reset in progress
-	if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |fRTMP_ADAPTER_HALT_IN_PROGRESS)))
-	{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-        return  IRQ_HANDLED;
-#else
-        return;
-#endif
-	}
-
-	//
-	// Handle interrupt, walk through all bits
-	// Should start from highest priority interrupt
-	// The priority can be adjust by altering processing if statement
-	//
-
-#ifdef DBG
-
-#endif
-
-
-	pAd->bPCIclkOff = FALSE;
-
-	// If required spinlock, each interrupt service routine has to acquire
-	// and release itself.
-	//
-
-	// Do nothing if NIC doesn't exist
-	if (IntSource.word == 0xffffffff)
-	{
-		RTMP_SET_FLAG(pAd, (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS));
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-        return  IRQ_HANDLED;
-#else
-        return;
-#endif
-	}
-
-	if (IntSource.word & TxCoherent)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, (">>>TxCoherent<<<\n"));
-		RTMPHandleRxCoherentInterrupt(pAd);
-	}
-
-	if (IntSource.word & RxCoherent)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, (">>>RxCoherent<<<\n"));
-		RTMPHandleRxCoherentInterrupt(pAd);
-	}
-
-	if (IntSource.word & FifoStaFullInt)
-	{
-		if ((pAd->int_disable_mask & FifoStaFullInt) == 0)
-		{
-			/* mask FifoStaFullInt */
-			rt2860_int_disable(pAd, FifoStaFullInt);
-			tasklet_hi_schedule(&pObj->fifo_statistic_full_task);
-		}
-		pAd->int_pending |= FifoStaFullInt;
-	}
-
-	if (IntSource.word & INT_MGMT_DLY)
-	{
-		if ((pAd->int_disable_mask & INT_MGMT_DLY) ==0 )
-		{
-			rt2860_int_disable(pAd, INT_MGMT_DLY);
-			tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
-		}
-		pAd->int_pending |= INT_MGMT_DLY ;
-	}
-
-	if (IntSource.word & INT_RX)
-	{
-		if ((pAd->int_disable_mask & INT_RX) == 0)
-		{
-
-			/* mask RxINT */
-			rt2860_int_disable(pAd, INT_RX);
-			tasklet_hi_schedule(&pObj->rx_done_task);
-		}
-		pAd->int_pending |= INT_RX;
-	}
-
-
-	if (IntSource.word & INT_AC3_DLY)
-	{
-
-		if ((pAd->int_disable_mask & INT_AC3_DLY) == 0)
-		{
-			/* mask TxDataInt */
-			rt2860_int_disable(pAd, INT_AC3_DLY);
-			tasklet_hi_schedule(&pObj->ac3_dma_done_task);
-		}
-		pAd->int_pending |= INT_AC3_DLY;
-	}
-
-	if (IntSource.word & INT_AC2_DLY)
-	{
-
-		if ((pAd->int_disable_mask & INT_AC2_DLY) == 0)
-		{
-			/* mask TxDataInt */
-			rt2860_int_disable(pAd, INT_AC2_DLY);
-			tasklet_hi_schedule(&pObj->ac2_dma_done_task);
-		}
-		pAd->int_pending |= INT_AC2_DLY;
-	}
-
-	if (IntSource.word & INT_AC1_DLY)
-	{
-
-		pAd->int_pending |= INT_AC1_DLY;
-
-		if ((pAd->int_disable_mask & INT_AC1_DLY) == 0)
-		{
-			/* mask TxDataInt */
-			rt2860_int_disable(pAd, INT_AC1_DLY);
-			tasklet_hi_schedule(&pObj->ac1_dma_done_task);
-		}
-
-	}
-
-	if (IntSource.word & INT_AC0_DLY)
-	{
-
-/*
-		if (IntSource.word & 0x2) {
-			u32 reg;
-			RTMP_IO_READ32(pAd, DELAY_INT_CFG, &reg);
-			printk("IntSource.word = %08x, DELAY_REG = %08x\n", IntSource.word, reg);
-		}
-*/
-		pAd->int_pending |= INT_AC0_DLY;
-
-		if ((pAd->int_disable_mask & INT_AC0_DLY) == 0)
-		{
-			/* mask TxDataInt */
-			rt2860_int_disable(pAd, INT_AC0_DLY);
-			tasklet_hi_schedule(&pObj->ac0_dma_done_task);
-		}
-
-	}
-
-
-	if (IntSource.word & PreTBTTInt)
-	{
-		RTMPHandlePreTBTTInterrupt(pAd);
-	}
-
-	if (IntSource.word & TBTTInt)
-	{
-		RTMPHandleTBTTInterrupt(pAd);
-	}
-
-
-
-
-#ifdef CONFIG_STA_SUPPORT
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-		if (IntSource.word & AutoWakeupInt)
-			RTMPHandleTwakeupInterrupt(pAd);
-	}
-#endif // CONFIG_STA_SUPPORT //
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-	return  IRQ_HANDLED;
-#endif
-
-}
-
-/*
- * invaild or writeback cache
- * and convert virtual address to physical address
- */
-dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, int sd_idx, int direction)
-{
-	PRTMP_ADAPTER pAd;
-	POS_COOKIE pObj;
-
-	/*
-		------ Porting Information ------
-		> For Tx Alloc:
-			mgmt packets => sd_idx = 0
-			SwIdx: pAd->MgmtRing.TxCpuIdx
-			pTxD : pAd->MgmtRing.Cell[SwIdx].AllocVa;
-
-			data packets => sd_idx = 1
-			TxIdx : pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx
-			QueIdx: pTxBlk->QueIdx
-			pTxD  : pAd->TxRing[pTxBlk->QueIdx].Cell[TxIdx].AllocVa;
-
-		> For Rx Alloc:
-			sd_idx = -1
-	*/
-
-	pAd = (PRTMP_ADAPTER)handle;
-	pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	if (sd_idx == 1)
-	{
-		PTX_BLK		pTxBlk;
-		pTxBlk = (PTX_BLK)ptr;
-		return pci_map_single(pObj->pci_dev, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, direction);
-	}
-	else
-	{
-		return pci_map_single(pObj->pci_dev, ptr, size, direction);
-	}
-
-}
-
-void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, int direction)
-{
-	PRTMP_ADAPTER pAd;
-	POS_COOKIE pObj;
-
-	pAd=(PRTMP_ADAPTER)handle;
-	pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	pci_unmap_single(pObj->pci_dev, dma_addr, size, direction);
-
-}
diff --git a/drivers/staging/rt3090/rt_profile.c b/drivers/staging/rt3090/rt_profile.c
deleted file mode 100644
index 49a0590..0000000
--- a/drivers/staging/rt3090/rt_profile.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	rt_profile.c
-
-    Abstract:
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
- */
-
-#include "rt_config.h"
-
-
-NDIS_STATUS	RTMPReadParametersHook(
-	IN	PRTMP_ADAPTER pAd)
-{
-	PSTRING					src = NULL;
-	RTMP_OS_FD				srcf;
-	RTMP_OS_FS_INFO			osFSInfo;
-	INT						retval = NDIS_STATUS_FAILURE;
-	PSTRING					buffer;
-
-	buffer = kmalloc(MAX_INI_BUFFER_SIZE, MEM_ALLOC_FLAG);
-	if(buffer == NULL)
-		return NDIS_STATUS_FAILURE;
-	memset(buffer, 0x00, MAX_INI_BUFFER_SIZE);
-
-	{
-
-#ifdef CONFIG_STA_SUPPORT
-		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-		{
-			src = STA_PROFILE_PATH;
-		}
-#endif // CONFIG_STA_SUPPORT //
-#ifdef MULTIPLE_CARD_SUPPORT
-		src = (PSTRING)pAd->MC_FileName;
-#endif // MULTIPLE_CARD_SUPPORT //
-	}
-
-	if (src && *src)
-	{
-		RtmpOSFSInfoChange(&osFSInfo, TRUE);
-		srcf = RtmpOSFileOpen(src, O_RDONLY, 0);
-		if (IS_FILE_OPEN_ERR(srcf))
-		{
-			DBGPRINT(RT_DEBUG_ERROR, ("Open file \"%s\" failed!\n", src));
-		}
-		else
-		{
-			retval =RtmpOSFileRead(srcf, buffer, MAX_INI_BUFFER_SIZE);
-			if (retval > 0)
-			{
-				RTMPSetProfileParameters(pAd, buffer);
-				retval = NDIS_STATUS_SUCCESS;
-			}
-			else
-				DBGPRINT(RT_DEBUG_ERROR, ("Read file \"%s\" failed(errCode=%d)!\n", src, retval));
-
-			retval = RtmpOSFileClose(srcf);
-			if ( retval != 0)
-			{
-				retval = NDIS_STATUS_FAILURE;
-				DBGPRINT(RT_DEBUG_ERROR, ("Close file \"%s\" failed(errCode=%d)!\n", src, retval));
-			}
-		}
-
-		RtmpOSFSInfoChange(&osFSInfo, FALSE);
-	}
-
-	kfree(buffer);
-
-	return (retval);
-
-}
diff --git a/drivers/staging/rt3090/rtmp.h b/drivers/staging/rt3090/rtmp.h
deleted file mode 100644
index 8ef6d0b..0000000
--- a/drivers/staging/rt3090/rtmp.h
+++ /dev/null
@@ -1,6873 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    rtmp.h
-
-    Abstract:
-    Miniport generic portion header file
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-    Paul Lin    2002-08-01    created
-    James Tan   2002-09-06    modified (Revise NTCRegTable)
-    John Chang  2004-09-06    modified for RT2600
-*/
-#ifndef __RTMP_H__
-#define __RTMP_H__
-
-#include "link_list.h"
-#include "spectrum_def.h"
-
-#include "rtmp_dot11.h"
-
-#ifdef MLME_EX
-#include "mlme_ex_def.h"
-#endif // MLME_EX //
-
-#ifdef CONFIG_STA_SUPPORT
-#endif // CONFIG_STA_SUPPORT //
-
-#undef AP_WSC_INCLUDED
-#undef STA_WSC_INCLUDED
-#undef WSC_INCLUDED
-
-
-#ifdef CONFIG_STA_SUPPORT
-#endif // CONFIG_STA_SUPPORT //
-
-#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
-#define WSC_INCLUDED
-#endif
-
-
-
-
-
-#include "rtmp_chip.h"
-
-
-
-typedef struct _RTMP_ADAPTER		RTMP_ADAPTER;
-typedef struct _RTMP_ADAPTER		*PRTMP_ADAPTER;
-
-typedef struct _RTMP_CHIP_OP_ RTMP_CHIP_OP;
-
-
-//#define DBG		1
-
-//#define DBG_DIAGNOSE		1
-
-
-//+++Add by shiang for merge MiniportMMRequest() and MiniportDataMMRequest() into one function
-#define MAX_DATAMM_RETRY	3
-#define MGMT_USE_QUEUE_FLAG	0x80
-//---Add by shiang for merge MiniportMMRequest() and MiniportDataMMRequest() into one function
-
-#define	MAXSEQ		(0xFFF)
-
-
-#if defined(CONFIG_AP_SUPPORT) && defined(CONFIG_STA_SUPPORT)
-#define IF_DEV_CONFIG_OPMODE_ON_AP(_pAd)	if(_pAd->OpMode == OPMODE_AP)
-#define IF_DEV_CONFIG_OPMODE_ON_STA(_pAd)	if(_pAd->OpMode == OPMODE_STA)
-#else
-#define IF_DEV_CONFIG_OPMODE_ON_AP(_pAd)
-#define IF_DEV_CONFIG_OPMODE_ON_STA(_pAd)
-#endif
-
-extern  unsigned char   SNAP_AIRONET[];
-extern  unsigned char   CISCO_OUI[];
-extern  UCHAR	BaSizeArray[4];
-
-extern UCHAR BROADCAST_ADDR[MAC_ADDR_LEN];
-extern UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN];
-extern ULONG BIT32[32];
-extern UCHAR BIT8[8];
-extern char* CipherName[];
-extern char* MCSToMbps[];
-extern UCHAR	 RxwiMCSToOfdmRate[12];
-extern UCHAR SNAP_802_1H[6];
-extern UCHAR SNAP_BRIDGE_TUNNEL[6];
-extern UCHAR SNAP_AIRONET[8];
-extern UCHAR CKIP_LLC_SNAP[8];
-extern UCHAR EAPOL_LLC_SNAP[8];
-extern UCHAR EAPOL[2];
-extern UCHAR IPX[2];
-extern UCHAR APPLE_TALK[2];
-extern UCHAR RateIdToPlcpSignal[12]; // see IEEE802.11a-1999 p.14
-extern UCHAR	 OfdmRateToRxwiMCS[];
-extern UCHAR OfdmSignalToRateId[16] ;
-extern UCHAR default_cwmin[4];
-extern UCHAR default_cwmax[4];
-extern UCHAR default_sta_aifsn[4];
-extern UCHAR MapUserPriorityToAccessCategory[8];
-
-extern USHORT RateUpPER[];
-extern USHORT RateDownPER[];
-extern UCHAR  Phy11BNextRateDownward[];
-extern UCHAR  Phy11BNextRateUpward[];
-extern UCHAR  Phy11BGNextRateDownward[];
-extern UCHAR  Phy11BGNextRateUpward[];
-extern UCHAR  Phy11ANextRateDownward[];
-extern UCHAR  Phy11ANextRateUpward[];
-extern CHAR   RssiSafeLevelForTxRate[];
-extern UCHAR  RateIdToMbps[];
-extern USHORT RateIdTo500Kbps[];
-
-extern UCHAR  CipherSuiteWpaNoneTkip[];
-extern UCHAR  CipherSuiteWpaNoneTkipLen;
-
-extern UCHAR  CipherSuiteWpaNoneAes[];
-extern UCHAR  CipherSuiteWpaNoneAesLen;
-
-extern UCHAR  SsidIe;
-extern UCHAR  SupRateIe;
-extern UCHAR  ExtRateIe;
-
-#ifdef DOT11_N_SUPPORT
-extern UCHAR  HtCapIe;
-extern UCHAR  AddHtInfoIe;
-extern UCHAR  NewExtChanIe;
-#ifdef DOT11N_DRAFT3
-extern UCHAR  ExtHtCapIe;
-#endif // DOT11N_DRAFT3 //
-#endif // DOT11_N_SUPPORT //
-
-extern UCHAR  ErpIe;
-extern UCHAR  DsIe;
-extern UCHAR  TimIe;
-extern UCHAR  WpaIe;
-extern UCHAR  Wpa2Ie;
-extern UCHAR  IbssIe;
-extern UCHAR  Ccx2Ie;
-extern UCHAR  WapiIe;
-
-extern UCHAR  WPA_OUI[];
-extern UCHAR  RSN_OUI[];
-extern UCHAR  WAPI_OUI[];
-extern UCHAR  WME_INFO_ELEM[];
-extern UCHAR  WME_PARM_ELEM[];
-extern UCHAR  Ccx2QosInfo[];
-extern UCHAR  Ccx2IeInfo[];
-extern UCHAR  RALINK_OUI[];
-extern UCHAR  PowerConstraintIE[];
-
-
-extern UCHAR  RateSwitchTable[];
-extern UCHAR  RateSwitchTable11B[];
-extern UCHAR  RateSwitchTable11G[];
-extern UCHAR  RateSwitchTable11BG[];
-
-#ifdef DOT11_N_SUPPORT
-extern UCHAR  RateSwitchTable11BGN1S[];
-extern UCHAR  RateSwitchTable11BGN2S[];
-extern UCHAR  RateSwitchTable11BGN2SForABand[];
-extern UCHAR  RateSwitchTable11N1S[];
-extern UCHAR  RateSwitchTable11N2S[];
-extern UCHAR  RateSwitchTable11N2SForABand[];
-
-#ifdef CONFIG_STA_SUPPORT
-extern UCHAR  PRE_N_HT_OUI[];
-#endif // CONFIG_STA_SUPPORT //
-#endif // DOT11_N_SUPPORT //
-
-
-#ifdef RALINK_ATE
-typedef	struct _ATE_INFO {
-	UCHAR	Mode;
-	CHAR	TxPower0;
-	CHAR	TxPower1;
-	CHAR    TxAntennaSel;
-	CHAR    RxAntennaSel;
-	TXWI_STRUC  TxWI;	  // TXWI
-	USHORT	QID;
-	UCHAR	Addr1[MAC_ADDR_LEN];
-	UCHAR	Addr2[MAC_ADDR_LEN];
-	UCHAR	Addr3[MAC_ADDR_LEN];
-	UCHAR	Channel;
-	UINT32	TxLength;
-	UINT32	TxCount;
-	UINT32	TxDoneCount; // Tx DMA Done
-	UINT32	RFFreqOffset;
-	BOOLEAN	bRxFER;		// Show Rx Frame Error Rate
-	BOOLEAN	bQATxStart; // Have compiled QA in and use it to ATE tx.
-	BOOLEAN	bQARxStart;	// Have compiled QA in and use it to ATE rx.
-#ifdef RTMP_MAC_PCI
-	BOOLEAN	bFWLoading;	// Reload firmware when ATE is done.
-#endif // RTMP_MAC_PCI //
-	UINT32	RxTotalCnt;
-	UINT32	RxCntPerSec;
-
-	CHAR	LastSNR0;             // last received SNR
-	CHAR    LastSNR1;             // last received SNR for 2nd  antenna
-	CHAR    LastRssi0;            // last received RSSI
-	CHAR    LastRssi1;            // last received RSSI for 2nd  antenna
-	CHAR    LastRssi2;            // last received RSSI for 3rd  antenna
-	CHAR    AvgRssi0;             // last 8 frames' average RSSI
-	CHAR    AvgRssi1;             // last 8 frames' average RSSI
-	CHAR    AvgRssi2;             // last 8 frames' average RSSI
-	SHORT   AvgRssi0X8;           // sum of last 8 frames' RSSI
-	SHORT   AvgRssi1X8;           // sum of last 8 frames' RSSI
-	SHORT   AvgRssi2X8;           // sum of last 8 frames' RSSI
-
-	UINT32	NumOfAvgRssiSample;
-
-
-#ifdef RALINK_28xx_QA
-	// Tx frame
-	USHORT		HLen; // Header Length
-	USHORT		PLen; // Pattern Length
-	UCHAR		Header[32]; // Header buffer
-	UCHAR		Pattern[32]; // Pattern buffer
-	USHORT		DLen; // Data Length
-	USHORT		seq;
-	UINT32		CID;
-	RTMP_OS_PID	AtePid;
-	// counters
-	UINT32		U2M;
-	UINT32		OtherData;
-	UINT32		Beacon;
-	UINT32		OtherCount;
-	UINT32		TxAc0;
-	UINT32		TxAc1;
-	UINT32		TxAc2;
-	UINT32		TxAc3;
-	/*UINT32		TxHCCA;*/
-	UINT32		TxMgmt;
-	UINT32		RSSI0;
-	UINT32		RSSI1;
-	UINT32		RSSI2;
-	UINT32		SNR0;
-	UINT32		SNR1;
-	// TxStatus : 0 --> task is idle, 1 --> task is running
-	UCHAR		TxStatus;
-#endif // RALINK_28xx_QA //
-}	ATE_INFO, *PATE_INFO;
-
-#ifdef RALINK_28xx_QA
-struct ate_racfghdr {
-	UINT32		magic_no;
-	USHORT		command_type;
-	USHORT		command_id;
-	USHORT		length;
-	USHORT		sequence;
-	USHORT		status;
-	UCHAR		data[2046];
-}  __attribute__((packed));
-#endif // RALINK_28xx_QA //
-#endif // RALINK_ATE //
-
-
-typedef struct	_RSSI_SAMPLE {
-	CHAR			LastRssi0;             // last received RSSI
-	CHAR			LastRssi1;             // last received RSSI
-	CHAR			LastRssi2;             // last received RSSI
-	CHAR			AvgRssi0;
-	CHAR			AvgRssi1;
-	CHAR			AvgRssi2;
-	SHORT			AvgRssi0X8;
-	SHORT			AvgRssi1X8;
-	SHORT			AvgRssi2X8;
-} RSSI_SAMPLE;
-
-//
-//  Queue structure and macros
-//
-typedef struct  _QUEUE_ENTRY    {
-	struct _QUEUE_ENTRY     *Next;
-}   QUEUE_ENTRY, *PQUEUE_ENTRY;
-
-// Queue structure
-typedef struct  _QUEUE_HEADER   {
-	PQUEUE_ENTRY    Head;
-	PQUEUE_ENTRY    Tail;
-	ULONG           Number;
-}   QUEUE_HEADER, *PQUEUE_HEADER;
-
-#define InitializeQueueHeader(QueueHeader)              \
-{                                                       \
-	(QueueHeader)->Head = (QueueHeader)->Tail = NULL;   \
-	(QueueHeader)->Number = 0;                          \
-}
-
-#define RemoveHeadQueue(QueueHeader)                \
-(QueueHeader)->Head;                                \
-{                                                   \
-	PQUEUE_ENTRY pNext;                             \
-	if ((QueueHeader)->Head != NULL)				\
-	{												\
-		pNext = (QueueHeader)->Head->Next;          \
-		(QueueHeader)->Head->Next = NULL;		\
-		(QueueHeader)->Head = pNext;                \
-		if (pNext == NULL)                          \
-			(QueueHeader)->Tail = NULL;             \
-		(QueueHeader)->Number--;                    \
-	}												\
-}
-
-#define InsertHeadQueue(QueueHeader, QueueEntry)            \
-{                                                           \
-		((PQUEUE_ENTRY)QueueEntry)->Next = (QueueHeader)->Head; \
-		(QueueHeader)->Head = (PQUEUE_ENTRY)(QueueEntry);       \
-		if ((QueueHeader)->Tail == NULL)                        \
-			(QueueHeader)->Tail = (PQUEUE_ENTRY)(QueueEntry);   \
-		(QueueHeader)->Number++;                                \
-}
-
-#define InsertTailQueue(QueueHeader, QueueEntry)				\
-{                                                               \
-	((PQUEUE_ENTRY)QueueEntry)->Next = NULL;                    \
-	if ((QueueHeader)->Tail)                                    \
-		(QueueHeader)->Tail->Next = (PQUEUE_ENTRY)(QueueEntry); \
-	else                                                        \
-		(QueueHeader)->Head = (PQUEUE_ENTRY)(QueueEntry);       \
-	(QueueHeader)->Tail = (PQUEUE_ENTRY)(QueueEntry);           \
-	(QueueHeader)->Number++;                                    \
-}
-
-#define InsertTailQueueAc(pAd, pEntry, QueueHeader, QueueEntry)			\
-{																		\
-	((PQUEUE_ENTRY)QueueEntry)->Next = NULL;							\
-	if ((QueueHeader)->Tail)											\
-		(QueueHeader)->Tail->Next = (PQUEUE_ENTRY)(QueueEntry);			\
-	else																\
-		(QueueHeader)->Head = (PQUEUE_ENTRY)(QueueEntry);				\
-	(QueueHeader)->Tail = (PQUEUE_ENTRY)(QueueEntry);					\
-	(QueueHeader)->Number++;											\
-}
-
-
-
-//
-//  Macros for flag and ref count operations
-//
-#define RTMP_SET_FLAG(_M, _F)       ((_M)->Flags |= (_F))
-#define RTMP_CLEAR_FLAG(_M, _F)     ((_M)->Flags &= ~(_F))
-#define RTMP_CLEAR_FLAGS(_M)        ((_M)->Flags = 0)
-#define RTMP_TEST_FLAG(_M, _F)      (((_M)->Flags & (_F)) != 0)
-#define RTMP_TEST_FLAGS(_M, _F)     (((_M)->Flags & (_F)) == (_F))
-// Macro for power save flag.
-#define RTMP_SET_PSFLAG(_M, _F)       ((_M)->PSFlags |= (_F))
-#define RTMP_CLEAR_PSFLAG(_M, _F)     ((_M)->PSFlags &= ~(_F))
-#define RTMP_CLEAR_PSFLAGS(_M)        ((_M)->PSFlags = 0)
-#define RTMP_TEST_PSFLAG(_M, _F)      (((_M)->PSFlags & (_F)) != 0)
-#define RTMP_TEST_PSFLAGS(_M, _F)     (((_M)->PSFlags & (_F)) == (_F))
-
-#define OPSTATUS_SET_FLAG(_pAd, _F)     ((_pAd)->CommonCfg.OpStatusFlags |= (_F))
-#define OPSTATUS_CLEAR_FLAG(_pAd, _F)   ((_pAd)->CommonCfg.OpStatusFlags &= ~(_F))
-#define OPSTATUS_TEST_FLAG(_pAd, _F)    (((_pAd)->CommonCfg.OpStatusFlags & (_F)) != 0)
-
-#define CLIENT_STATUS_SET_FLAG(_pEntry,_F)      ((_pEntry)->ClientStatusFlags |= (_F))
-#define CLIENT_STATUS_CLEAR_FLAG(_pEntry,_F)    ((_pEntry)->ClientStatusFlags &= ~(_F))
-#define CLIENT_STATUS_TEST_FLAG(_pEntry,_F)     (((_pEntry)->ClientStatusFlags & (_F)) != 0)
-
-#define RX_FILTER_SET_FLAG(_pAd, _F)    ((_pAd)->CommonCfg.PacketFilter |= (_F))
-#define RX_FILTER_CLEAR_FLAG(_pAd, _F)  ((_pAd)->CommonCfg.PacketFilter &= ~(_F))
-#define RX_FILTER_TEST_FLAG(_pAd, _F)   (((_pAd)->CommonCfg.PacketFilter & (_F)) != 0)
-
-#ifdef CONFIG_STA_SUPPORT
-#define STA_NO_SECURITY_ON(_p)          (_p->StaCfg.WepStatus == Ndis802_11EncryptionDisabled)
-#define STA_WEP_ON(_p)                  (_p->StaCfg.WepStatus == Ndis802_11Encryption1Enabled)
-#define STA_TKIP_ON(_p)                 (_p->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
-#define STA_AES_ON(_p)                  (_p->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
-
-#define STA_TGN_WIFI_ON(_p)             (_p->StaCfg.bTGnWifiTest == TRUE)
-#endif // CONFIG_STA_SUPPORT //
-
-#define CKIP_KP_ON(_p)				((((_p)->StaCfg.CkipFlag) & 0x10) && ((_p)->StaCfg.bCkipCmicOn == TRUE))
-#define CKIP_CMIC_ON(_p)			((((_p)->StaCfg.CkipFlag) & 0x08) && ((_p)->StaCfg.bCkipCmicOn == TRUE))
-
-
-#define INC_RING_INDEX(_idx, _RingSize)    \
-{                                          \
-    (_idx) = (_idx+1) % (_RingSize);       \
-}
-
-
-#ifdef DOT11_N_SUPPORT
-// StaActive.SupportedHtPhy.MCSSet is copied from AP beacon.  Don't need to update here.
-#define COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd)                                 \
-{                                                                                       \
-	_pAd->StaActive.SupportedHtPhy.ChannelWidth = _pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth;      \
-	_pAd->StaActive.SupportedHtPhy.MimoPs = _pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs;      \
-	_pAd->StaActive.SupportedHtPhy.GF = _pAd->MlmeAux.HtCapability.HtCapInfo.GF;      \
-	_pAd->StaActive.SupportedHtPhy.ShortGIfor20 = _pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20;      \
-	_pAd->StaActive.SupportedHtPhy.ShortGIfor40 = _pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40;      \
-	_pAd->StaActive.SupportedHtPhy.TxSTBC = _pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC;      \
-	_pAd->StaActive.SupportedHtPhy.RxSTBC = _pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC;      \
-	_pAd->StaActive.SupportedHtPhy.ExtChanOffset = _pAd->MlmeAux.AddHtInfo.AddHtInfo.ExtChanOffset;      \
-	_pAd->StaActive.SupportedHtPhy.RecomWidth = _pAd->MlmeAux.AddHtInfo.AddHtInfo.RecomWidth;      \
-	_pAd->StaActive.SupportedHtPhy.OperaionMode = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode;      \
-	_pAd->StaActive.SupportedHtPhy.NonGfPresent = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent;      \
-	NdisMoveMemory((_pAd)->MacTab.Content[BSSID_WCID].HTCapability.MCSSet, (_pAd)->StaActive.SupportedPhyInfo.MCSSet, sizeof(UCHAR) * 16);\
-}
-
-#define COPY_AP_HTSETTINGS_FROM_BEACON(_pAd, _pHtCapability)                                 \
-{                                                                                       \
-	_pAd->MacTab.Content[BSSID_WCID].AMsduSize = (UCHAR)(_pHtCapability->HtCapInfo.AMsduSize);	\
-	_pAd->MacTab.Content[BSSID_WCID].MmpsMode= (UCHAR)(_pHtCapability->HtCapInfo.MimoPs);	\
-	_pAd->MacTab.Content[BSSID_WCID].MaxRAmpduFactor = (UCHAR)(_pHtCapability->HtCapParm.MaxRAmpduFactor);	\
-}
-#endif // DOT11_N_SUPPORT //
-
-//
-// MACRO for 32-bit PCI register read / write
-//
-// Usage : RTMP_IO_READ32(
-//              PRTMP_ADAPTER pAd,
-//              ULONG Register_Offset,
-//              PULONG  pValue)
-//
-//         RTMP_IO_WRITE32(
-//              PRTMP_ADAPTER pAd,
-//              ULONG Register_Offset,
-//              ULONG Value)
-//
-
-
-//
-// Common fragment list structure -  Identical to the scatter gather frag list structure
-//
-//#define RTMP_SCATTER_GATHER_ELEMENT         SCATTER_GATHER_ELEMENT
-//#define PRTMP_SCATTER_GATHER_ELEMENT        PSCATTER_GATHER_ELEMENT
-#define NIC_MAX_PHYS_BUF_COUNT              8
-
-typedef struct _RTMP_SCATTER_GATHER_ELEMENT {
-    PVOID		Address;
-    ULONG		Length;
-    PULONG		Reserved;
-} RTMP_SCATTER_GATHER_ELEMENT, *PRTMP_SCATTER_GATHER_ELEMENT;
-
-
-typedef struct _RTMP_SCATTER_GATHER_LIST {
-    ULONG  NumberOfElements;
-    PULONG Reserved;
-    RTMP_SCATTER_GATHER_ELEMENT Elements[NIC_MAX_PHYS_BUF_COUNT];
-} RTMP_SCATTER_GATHER_LIST, *PRTMP_SCATTER_GATHER_LIST;
-
-
-//
-//  Some utility macros
-//
-#ifndef min
-#define min(_a, _b)     (((_a) < (_b)) ? (_a) : (_b))
-#endif
-
-#ifndef max
-#define max(_a, _b)     (((_a) > (_b)) ? (_a) : (_b))
-#endif
-
-#define GET_LNA_GAIN(_pAd)	((_pAd->LatchRfRegs.Channel <= 14) ? (_pAd->BLNAGain) : ((_pAd->LatchRfRegs.Channel <= 64) ? (_pAd->ALNAGain0) : ((_pAd->LatchRfRegs.Channel <= 128) ? (_pAd->ALNAGain1) : (_pAd->ALNAGain2))))
-
-#define INC_COUNTER64(Val)          (Val.QuadPart++)
-
-#define INFRA_ON(_p)                (OPSTATUS_TEST_FLAG(_p, fOP_STATUS_INFRA_ON))
-#define ADHOC_ON(_p)                (OPSTATUS_TEST_FLAG(_p, fOP_STATUS_ADHOC_ON))
-#define MONITOR_ON(_p)              (((_p)->StaCfg.BssType) == BSS_MONITOR)
-#define IDLE_ON(_p)                 (!INFRA_ON(_p) && !ADHOC_ON(_p))
-
-// Check LEAP & CCKM flags
-#define LEAP_ON(_p)                 (((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP)
-#define LEAP_CCKM_ON(_p)            ((((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP) && ((_p)->StaCfg.LeapAuthInfo.CCKM == TRUE))
-
-// if orginal Ethernet frame contains no LLC/SNAP, then an extra LLC/SNAP encap is required
-#define EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(_pBufVA, _pExtraLlcSnapEncap)		\
-{																\
-	if (((*(_pBufVA + 12) << 8) + *(_pBufVA + 13)) > 1500)		\
-	{															\
-		_pExtraLlcSnapEncap = SNAP_802_1H;						\
-		if (NdisEqualMemory(IPX, _pBufVA + 12, 2) ||			\
-			NdisEqualMemory(APPLE_TALK, _pBufVA + 12, 2))		\
-		{														\
-			_pExtraLlcSnapEncap = SNAP_BRIDGE_TUNNEL;			\
-		}														\
-	}															\
-	else														\
-	{															\
-		_pExtraLlcSnapEncap = NULL;								\
-	}															\
-}
-
-// New Define for new Tx Path.
-#define EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(_pBufVA, _pExtraLlcSnapEncap)	\
-{																\
-	if (((*(_pBufVA) << 8) + *(_pBufVA + 1)) > 1500)			\
-	{															\
-		_pExtraLlcSnapEncap = SNAP_802_1H;						\
-		if (NdisEqualMemory(IPX, _pBufVA, 2) ||					\
-			NdisEqualMemory(APPLE_TALK, _pBufVA, 2))			\
-		{														\
-			_pExtraLlcSnapEncap = SNAP_BRIDGE_TUNNEL;			\
-		}														\
-	}															\
-	else														\
-	{															\
-		_pExtraLlcSnapEncap = NULL;								\
-	}															\
-}
-
-
-#define MAKE_802_3_HEADER(_p, _pMac1, _pMac2, _pType)                   \
-{                                                                       \
-    NdisMoveMemory(_p, _pMac1, MAC_ADDR_LEN);                           \
-    NdisMoveMemory((_p + MAC_ADDR_LEN), _pMac2, MAC_ADDR_LEN);          \
-    NdisMoveMemory((_p + MAC_ADDR_LEN * 2), _pType, LENGTH_802_3_TYPE); \
-}
-
-// if pData has no LLC/SNAP (neither RFC1042 nor Bridge tunnel), keep it that way.
-// else if the received frame is LLC/SNAP-encaped IPX or APPLETALK, preserve the LLC/SNAP field
-// else remove the LLC/SNAP field from the result Ethernet frame
-// Patch for WHQL only, which did not turn on Netbios but use IPX within its payload
-// Note:
-//     _pData & _DataSize may be altered (remove 8-byte LLC/SNAP) by this MACRO
-//     _pRemovedLLCSNAP: pointer to removed LLC/SNAP; NULL is not removed
-#define CONVERT_TO_802_3(_p8023hdr, _pDA, _pSA, _pData, _DataSize, _pRemovedLLCSNAP)      \
-{                                                                       \
-    char LLC_Len[2];                                                    \
-                                                                        \
-    _pRemovedLLCSNAP = NULL;                                            \
-    if (NdisEqualMemory(SNAP_802_1H, _pData, 6)  ||                     \
-        NdisEqualMemory(SNAP_BRIDGE_TUNNEL, _pData, 6))                 \
-    {                                                                   \
-        PUCHAR pProto = _pData + 6;                                     \
-                                                                        \
-        if ((NdisEqualMemory(IPX, pProto, 2) || NdisEqualMemory(APPLE_TALK, pProto, 2)) &&  \
-            NdisEqualMemory(SNAP_802_1H, _pData, 6))                    \
-        {                                                               \
-            LLC_Len[0] = (UCHAR)(_DataSize / 256);                      \
-            LLC_Len[1] = (UCHAR)(_DataSize % 256);                      \
-            MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len);          \
-        }                                                               \
-        else                                                            \
-        {                                                               \
-            MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, pProto);           \
-            _pRemovedLLCSNAP = _pData;                                  \
-            _DataSize -= LENGTH_802_1_H;                                \
-            _pData += LENGTH_802_1_H;                                   \
-        }                                                               \
-    }                                                                   \
-    else                                                                \
-    {                                                                   \
-        LLC_Len[0] = (UCHAR)(_DataSize / 256);                          \
-        LLC_Len[1] = (UCHAR)(_DataSize % 256);                          \
-        MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len);              \
-    }                                                                   \
-}
-
-
-// Enqueue this frame to MLME engine
-// We need to enqueue the whole frame because MLME need to pass data type
-// information from 802.11 header
-#ifdef RTMP_MAC_PCI
-#define REPORT_MGMT_FRAME_TO_MLME(_pAd, Wcid, _pFrame, _FrameSize, _Rssi0, _Rssi1, _Rssi2, _PlcpSignal)        \
-{                                                                                       \
-    UINT32 High32TSF, Low32TSF;                                                          \
-    RTMP_IO_READ32(_pAd, TSF_TIMER_DW1, &High32TSF);                                       \
-    RTMP_IO_READ32(_pAd, TSF_TIMER_DW0, &Low32TSF);                                        \
-    MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (UCHAR)_Rssi0, (UCHAR)_Rssi1,(UCHAR)_Rssi2,_FrameSize, _pFrame, (UCHAR)_PlcpSignal);   \
-}
-#endif // RTMP_MAC_PCI //
-
-#define MAC_ADDR_EQUAL(pAddr1,pAddr2)           RTMPEqualMemory((PVOID)(pAddr1), (PVOID)(pAddr2), MAC_ADDR_LEN)
-#define SSID_EQUAL(ssid1, len1, ssid2, len2)    ((len1==len2) && (RTMPEqualMemory(ssid1, ssid2, len1)))
-
-//
-// Check if it is Japan W53(ch52,56,60,64) channel.
-//
-#define JapanChannelCheck(channel)  ((channel == 52) || (channel == 56) || (channel == 60) || (channel == 64))
-
-#ifdef CONFIG_STA_SUPPORT
-#define STA_EXTRA_SETTING(_pAd)
-
-#define STA_PORT_SECURED(_pAd) \
-{ \
-	BOOLEAN	Cancelled; \
-	(_pAd)->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; \
-	NdisAcquireSpinLock(&((_pAd)->MacTabLock)); \
-	(_pAd)->MacTab.Content[BSSID_WCID].PortSecured = (_pAd)->StaCfg.PortSecured; \
-	(_pAd)->MacTab.Content[BSSID_WCID].PrivacyFilter = Ndis802_11PrivFilterAcceptAll;\
-	NdisReleaseSpinLock(&(_pAd)->MacTabLock); \
-	RTMPCancelTimer(&((_pAd)->Mlme.LinkDownTimer), &Cancelled);\
-	STA_EXTRA_SETTING(_pAd); \
-}
-#endif // CONFIG_STA_SUPPORT //
-
-
-
-//
-//  Data buffer for DMA operation, the buffer must be contiguous physical memory
-//  Both DMA to / from CPU use the same structure.
-//
-typedef struct  _RTMP_DMABUF
-{
-	ULONG                   AllocSize;
-	PVOID                   AllocVa;            // TxBuf virtual address
-	NDIS_PHYSICAL_ADDRESS   AllocPa;            // TxBuf physical address
-} RTMP_DMABUF, *PRTMP_DMABUF;
-
-
-//
-// Control block (Descriptor) for all ring descriptor DMA operation, buffer must be
-// contiguous physical memory. NDIS_PACKET stored the binding Rx packet descriptor
-// which won't be released, driver has to wait until upper layer return the packet
-// before giveing up this rx ring descriptor to ASIC. NDIS_BUFFER is assocaited pair
-// to describe the packet buffer. For Tx, NDIS_PACKET stored the tx packet descriptor
-// which driver should ACK upper layer when the tx is physically done or failed.
-//
-typedef struct _RTMP_DMACB
-{
-	ULONG                   AllocSize;          // Control block size
-	PVOID                   AllocVa;            // Control block virtual address
-	NDIS_PHYSICAL_ADDRESS   AllocPa;            // Control block physical address
-	PNDIS_PACKET pNdisPacket;
-	PNDIS_PACKET pNextNdisPacket;
-
-	RTMP_DMABUF             DmaBuf;             // Associated DMA buffer structure
-} RTMP_DMACB, *PRTMP_DMACB;
-
-
-typedef struct _RTMP_TX_RING
-{
-	RTMP_DMACB  Cell[TX_RING_SIZE];
-	UINT32		TxCpuIdx;
-	UINT32		TxDmaIdx;
-	UINT32		TxSwFreeIdx;	// software next free tx index
-} RTMP_TX_RING, *PRTMP_TX_RING;
-
-typedef struct _RTMP_RX_RING
-{
-	RTMP_DMACB  Cell[RX_RING_SIZE];
-	UINT32		RxCpuIdx;
-	UINT32		RxDmaIdx;
-	INT32		RxSwReadIdx;	// software next read index
-} RTMP_RX_RING, *PRTMP_RX_RING;
-
-typedef struct _RTMP_MGMT_RING
-{
-	RTMP_DMACB  Cell[MGMT_RING_SIZE];
-	UINT32		TxCpuIdx;
-	UINT32		TxDmaIdx;
-	UINT32		TxSwFreeIdx; // software next free tx index
-} RTMP_MGMT_RING, *PRTMP_MGMT_RING;
-
-
-//
-//  Statistic counter structure
-//
-typedef struct _COUNTER_802_3
-{
-	// General Stats
-	ULONG       GoodTransmits;
-	ULONG       GoodReceives;
-	ULONG       TxErrors;
-	ULONG       RxErrors;
-	ULONG       RxNoBuffer;
-
-	// Ethernet Stats
-	ULONG       RcvAlignmentErrors;
-	ULONG       OneCollision;
-	ULONG       MoreCollisions;
-
-} COUNTER_802_3, *PCOUNTER_802_3;
-
-typedef struct _COUNTER_802_11 {
-	ULONG           Length;
-	LARGE_INTEGER   LastTransmittedFragmentCount;
-	LARGE_INTEGER   TransmittedFragmentCount;
-	LARGE_INTEGER   MulticastTransmittedFrameCount;
-	LARGE_INTEGER   FailedCount;
-	LARGE_INTEGER   RetryCount;
-	LARGE_INTEGER   MultipleRetryCount;
-	LARGE_INTEGER   RTSSuccessCount;
-	LARGE_INTEGER   RTSFailureCount;
-	LARGE_INTEGER   ACKFailureCount;
-	LARGE_INTEGER   FrameDuplicateCount;
-	LARGE_INTEGER   ReceivedFragmentCount;
-	LARGE_INTEGER   MulticastReceivedFrameCount;
-	LARGE_INTEGER   FCSErrorCount;
-} COUNTER_802_11, *PCOUNTER_802_11;
-
-typedef struct _COUNTER_RALINK {
-	ULONG           TransmittedByteCount;   // both successful and failure, used to calculate TX throughput
-	ULONG           ReceivedByteCount;      // both CRC okay and CRC error, used to calculate RX throughput
-	ULONG           BeenDisassociatedCount;
-	ULONG           BadCQIAutoRecoveryCount;
-	ULONG           PoorCQIRoamingCount;
-	ULONG           MgmtRingFullCount;
-	ULONG           RxCountSinceLastNULL;
-	ULONG           RxCount;
-	ULONG           RxRingErrCount;
-	ULONG           KickTxCount;
-	ULONG           TxRingErrCount;
-	LARGE_INTEGER   RealFcsErrCount;
-	ULONG           PendingNdisPacketCount;
-
-	ULONG           OneSecOsTxCount[NUM_OF_TX_RING];
-	ULONG           OneSecDmaDoneCount[NUM_OF_TX_RING];
-	UINT32          OneSecTxDoneCount;
-	ULONG           OneSecRxCount;
-	UINT32          OneSecTxAggregationCount;
-	UINT32          OneSecRxAggregationCount;
-	UINT32          OneSecReceivedByteCount;
-	UINT32			OneSecFrameDuplicateCount;
-
-	UINT32          OneSecTransmittedByteCount;   // both successful and failure, used to calculate TX throughput
-	UINT32          OneSecTxNoRetryOkCount;
-	UINT32          OneSecTxRetryOkCount;
-	UINT32          OneSecTxFailCount;
-	UINT32          OneSecFalseCCACnt;      // CCA error count, for debug purpose, might move to global counter
-	UINT32          OneSecRxOkCnt;          // RX without error
-	UINT32          OneSecRxOkDataCnt;      // unicast-to-me DATA frame count
-	UINT32          OneSecRxFcsErrCnt;      // CRC error
-	UINT32          OneSecBeaconSentCnt;
-	UINT32          LastOneSecTotalTxCount; // OneSecTxNoRetryOkCount + OneSecTxRetryOkCount + OneSecTxFailCount
-	UINT32          LastOneSecRxOkDataCnt;  // OneSecRxOkDataCnt
-	ULONG		DuplicateRcv;
-	ULONG		TxAggCount;
-	ULONG		TxNonAggCount;
-	ULONG		TxAgg1MPDUCount;
-	ULONG		TxAgg2MPDUCount;
-	ULONG		TxAgg3MPDUCount;
-	ULONG		TxAgg4MPDUCount;
-	ULONG		TxAgg5MPDUCount;
-	ULONG		TxAgg6MPDUCount;
-	ULONG		TxAgg7MPDUCount;
-	ULONG		TxAgg8MPDUCount;
-	ULONG		TxAgg9MPDUCount;
-	ULONG		TxAgg10MPDUCount;
-	ULONG		TxAgg11MPDUCount;
-	ULONG		TxAgg12MPDUCount;
-	ULONG		TxAgg13MPDUCount;
-	ULONG		TxAgg14MPDUCount;
-	ULONG		TxAgg15MPDUCount;
-	ULONG		TxAgg16MPDUCount;
-
-	LARGE_INTEGER       TransmittedOctetsInAMSDU;
-	LARGE_INTEGER       TransmittedAMSDUCount;
-	LARGE_INTEGER       ReceivedOctesInAMSDUCount;
-	LARGE_INTEGER       ReceivedAMSDUCount;
-	LARGE_INTEGER       TransmittedAMPDUCount;
-	LARGE_INTEGER       TransmittedMPDUsInAMPDUCount;
-	LARGE_INTEGER       TransmittedOctetsInAMPDUCount;
-	LARGE_INTEGER       MPDUInReceivedAMPDUCount;
-} COUNTER_RALINK, *PCOUNTER_RALINK;
-
-
-typedef struct _COUNTER_DRS {
-	// to record the each TX rate's quality. 0 is best, the bigger the worse.
-	USHORT          TxQuality[MAX_STEP_OF_TX_RATE_SWITCH];
-	UCHAR           PER[MAX_STEP_OF_TX_RATE_SWITCH];
-	UCHAR           TxRateUpPenalty;      // extra # of second penalty due to last unstable condition
-	ULONG           CurrTxRateStableTime; // # of second in current TX rate
-	BOOLEAN         fNoisyEnvironment;
-	BOOLEAN         fLastSecAccordingRSSI;
-	UCHAR           LastSecTxRateChangeAction; // 0: no change, 1:rate UP, 2:rate down
-	UCHAR			LastTimeTxRateChangeAction; //Keep last time value of LastSecTxRateChangeAction
-	ULONG			LastTxOkCount;
-} COUNTER_DRS, *PCOUNTER_DRS;
-
-
-
-
-/***************************************************************************
-  *	security key related data structure
-  **************************************************************************/
-typedef struct _CIPHER_KEY {
-	UCHAR   Key[16];            // right now we implement 4 keys, 128 bits max
-	UCHAR   RxMic[8];			// make alignment
-	UCHAR   TxMic[8];
-	UCHAR   TxTsc[6];           // 48bit TSC value
-	UCHAR   RxTsc[6];           // 48bit TSC value
-	UCHAR   CipherAlg;          // 0-none, 1:WEP64, 2:WEP128, 3:TKIP, 4:AES, 5:CKIP64, 6:CKIP128
-	UCHAR   KeyLen;
-#ifdef CONFIG_STA_SUPPORT
-	UCHAR   BssId[6];
-#endif // CONFIG_STA_SUPPORT //
-            // Key length for each key, 0: entry is invalid
-	UCHAR   Type;               // Indicate Pairwise/Group when reporting MIC error
-} CIPHER_KEY, *PCIPHER_KEY;
-
-
-// structure to define WPA Group Key Rekey Interval
-typedef struct PACKED _RT_802_11_WPA_REKEY {
-	ULONG ReKeyMethod;          // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based
-	ULONG ReKeyInterval;        // time-based: seconds, packet-based: kilo-packets
-} RT_WPA_REKEY,*PRT_WPA_REKEY, RT_802_11_WPA_REKEY, *PRT_802_11_WPA_REKEY;
-
-
-
-typedef struct {
-	UCHAR        Addr[MAC_ADDR_LEN];
-	UCHAR        ErrorCode[2];  //00 01-Invalid authentication type
-							//00 02-Authentication timeout
-							//00 03-Challenge from AP failed
-							//00 04-Challenge to AP failed
-	BOOLEAN      Reported;
-} ROGUEAP_ENTRY, *PROGUEAP_ENTRY;
-
-typedef struct {
-	UCHAR               RogueApNr;
-	ROGUEAP_ENTRY       RogueApEntry[MAX_LEN_OF_BSS_TABLE];
-} ROGUEAP_TABLE, *PROGUEAP_TABLE;
-
-//
-// Cisco IAPP format
-//
-typedef struct  _CISCO_IAPP_CONTENT_
-{
-	USHORT     Length;        //IAPP Length
-	UCHAR      MessageType;      //IAPP type
-	UCHAR      FunctionCode;     //IAPP function type
-	UCHAR      DestinaionMAC[MAC_ADDR_LEN];
-	UCHAR      SourceMAC[MAC_ADDR_LEN];
-	USHORT     Tag;           //Tag(element IE) - Adjacent AP report
-	USHORT     TagLength;     //Length of element not including 4 byte header
-	UCHAR      OUI[4];           //0x00, 0x40, 0x96, 0x00
-	UCHAR      PreviousAP[MAC_ADDR_LEN];       //MAC Address of access point
-	USHORT     Channel;
-	USHORT     SsidLen;
-	UCHAR      Ssid[MAX_LEN_OF_SSID];
-	USHORT     Seconds;          //Seconds that the client has been disassociated.
-} CISCO_IAPP_CONTENT, *PCISCO_IAPP_CONTENT;
-
-
-/*
-  *	Fragment Frame structure
-  */
-typedef struct  _FRAGMENT_FRAME {
-	PNDIS_PACKET    pFragPacket;
-	ULONG       RxSize;
-	USHORT      Sequence;
-	USHORT      LastFrag;
-	ULONG       Flags;          // Some extra frame information. bit 0: LLC presented
-} FRAGMENT_FRAME, *PFRAGMENT_FRAME;
-
-
-//
-// Packet information for NdisQueryPacket
-//
-typedef struct  _PACKET_INFO    {
-	UINT            PhysicalBufferCount;    // Physical breaks of buffer descripor chained
-	UINT            BufferCount ;           // Number of Buffer descriptor chained
-	UINT            TotalPacketLength ;     // Self explained
-	PNDIS_BUFFER    pFirstBuffer;           // Pointer to first buffer descriptor
-} PACKET_INFO, *PPACKET_INFO;
-
-
-//
-//  Arcfour Structure Added by PaulWu
-//
-typedef struct  _ARCFOUR
-{
-	UINT            X;
-	UINT            Y;
-	UCHAR           STATE[256];
-} ARCFOURCONTEXT, *PARCFOURCONTEXT;
-
-
-//
-// Tkip Key structure which RC4 key & MIC calculation
-//
-typedef struct  _TKIP_KEY_INFO  {
-	UINT        nBytesInM;  // # bytes in M for MICKEY
-	ULONG       IV16;
-	ULONG       IV32;
-	ULONG       K0;         // for MICKEY Low
-	ULONG       K1;         // for MICKEY Hig
-	ULONG       L;          // Current state for MICKEY
-	ULONG       R;          // Current state for MICKEY
-	ULONG       M;          // Message accumulator for MICKEY
-	UCHAR       RC4KEY[16];
-	UCHAR       MIC[8];
-} TKIP_KEY_INFO, *PTKIP_KEY_INFO;
-
-
-//
-// Private / Misc data, counters for driver internal use
-//
-typedef struct  __PRIVATE_STRUC {
-	UINT       SystemResetCnt;         // System reset counter
-	UINT       TxRingFullCnt;          // Tx ring full occurrance number
-	UINT       PhyRxErrCnt;            // PHY Rx error count, for debug purpose, might move to global counter
-	// Variables for WEP encryption / decryption in rtmp_wep.c
-	UINT       FCSCRC32;
-	ARCFOURCONTEXT  WEPCONTEXT;
-	// Tkip stuff
-	TKIP_KEY_INFO   Tx;
-	TKIP_KEY_INFO   Rx;
-} PRIVATE_STRUC, *PPRIVATE_STRUC;
-
-
-/***************************************************************************
-  *	Channel and BBP related data structures
-  **************************************************************************/
-// structure to tune BBP R66 (BBP TUNING)
-typedef struct _BBP_R66_TUNING {
-	BOOLEAN     bEnable;
-	USHORT      FalseCcaLowerThreshold;  // default 100
-	USHORT      FalseCcaUpperThreshold;  // default 512
-	UCHAR       R66Delta;
-	UCHAR       R66CurrentValue;
-	BOOLEAN		R66LowerUpperSelect; //Before LinkUp, Used LowerBound or UpperBound as R66 value.
-} BBP_R66_TUNING, *PBBP_R66_TUNING;
-
-// structure to store channel TX power
-typedef struct _CHANNEL_TX_POWER {
-	USHORT     RemainingTimeForUse;		//unit: sec
-	UCHAR      Channel;
-#ifdef DOT11N_DRAFT3
-	BOOLEAN       bEffectedChannel;	// For BW 40 operating in 2.4GHz , the "effected channel" is the channel that is covered in 40Mhz.
-#endif // DOT11N_DRAFT3 //
-	CHAR       Power;
-	CHAR       Power2;
-	UCHAR      MaxTxPwr;
-	UCHAR      DfsReq;
-} CHANNEL_TX_POWER, *PCHANNEL_TX_POWER;
-
-// structure to store 802.11j channel TX power
-typedef struct _CHANNEL_11J_TX_POWER {
-	UCHAR      Channel;
-	UCHAR      BW;	// BW_10 or BW_20
-	CHAR       Power;
-	CHAR       Power2;
-	USHORT     RemainingTimeForUse;		//unit: sec
-} CHANNEL_11J_TX_POWER, *PCHANNEL_11J_TX_POWER;
-
-typedef struct _SOFT_RX_ANT_DIVERSITY_STRUCT {
-	UCHAR     EvaluatePeriod;		 // 0:not evalute status, 1: evaluate status, 2: switching status
-	UCHAR     EvaluateStableCnt;
-	UCHAR     Pair1PrimaryRxAnt;     // 0:Ant-E1, 1:Ant-E2
-	UCHAR     Pair1SecondaryRxAnt;   // 0:Ant-E1, 1:Ant-E2
-	UCHAR     Pair2PrimaryRxAnt;     // 0:Ant-E3, 1:Ant-E4
-	UCHAR     Pair2SecondaryRxAnt;   // 0:Ant-E3, 1:Ant-E4
-#ifdef CONFIG_STA_SUPPORT
-	SHORT     Pair1AvgRssi[2];       // AvgRssi[0]:E1, AvgRssi[1]:E2
-	SHORT     Pair2AvgRssi[2];       // AvgRssi[0]:E3, AvgRssi[1]:E4
-#endif // CONFIG_STA_SUPPORT //
-	SHORT     Pair1LastAvgRssi;      //
-	SHORT     Pair2LastAvgRssi;      //
-	ULONG     RcvPktNumWhenEvaluate;
-	BOOLEAN   FirstPktArrivedWhenEvaluate;
-	RALINK_TIMER_STRUCT    RxAntDiversityTimer;
-} SOFT_RX_ANT_DIVERSITY, *PSOFT_RX_ANT_DIVERSITY;
-
-
-/***************************************************************************
-  *	structure for radar detection and channel switch
-  **************************************************************************/
-typedef struct _RADAR_DETECT_STRUCT {
-    //BOOLEAN		IEEE80211H;			// 0: disable, 1: enable IEEE802.11h
-	UCHAR		CSCount;			//Channel switch counter
-	UCHAR		CSPeriod;			//Channel switch period (beacon count)
-	UCHAR		RDCount;			//Radar detection counter
-	UCHAR		RDMode;				//Radar Detection mode
-	UCHAR		RDDurRegion;		//Radar detection duration region
-	UCHAR		BBPR16;
-	UCHAR		BBPR17;
-	UCHAR		BBPR18;
-	UCHAR		BBPR21;
-	UCHAR		BBPR22;
-	UCHAR		BBPR64;
-	ULONG		InServiceMonitorCount; // unit: sec
-	UINT8		DfsSessionTime;
-#ifdef DFS_FCC_BW40_FIX
-	CHAR		DfsSessionFccOff;
-#endif
-	BOOLEAN		bFastDfs;
-	UINT8		ChMovingTime;
-	UINT8		LongPulseRadarTh;
-#ifdef MERGE_ARCH_TEAM
-	CHAR		AvgRssiReq;
-	ULONG		DfsLowerLimit;
-	ULONG		DfsUpperLimit;
-	UINT8		FixDfsLimit;
-	ULONG		upperlimit;
-	ULONG		lowerlimit;
-#endif // MERGE_ARCH_TEAM //
-} RADAR_DETECT_STRUCT, *PRADAR_DETECT_STRUCT;
-
-#ifdef CARRIER_DETECTION_SUPPORT
-typedef enum CD_STATE_n
-{
-	CD_NORMAL,
-	CD_SILENCE,
-	CD_MAX_STATE
-} CD_STATE;
-
-#ifdef TONE_RADAR_DETECT_SUPPORT
-#define CARRIER_DETECT_RECHECK_TIME			3
-
-
-#ifdef CARRIER_SENSE_NEW_ALGO
-#define CARRIER_DETECT_CRITIRIA				400
-#define CARRIER_DETECT_STOP_RATIO				0x11
-#define	CARRIER_DETECT_STOP_RATIO_OLD_3090			2
-#endif // CARRIER_SENSE_NEW_ALGO //
-
-
-#define CARRIER_DETECT_STOP_RECHECK_TIME		4
-#define CARRIER_DETECT_CRITIRIA_A				230
-#define CARRIER_DETECT_DELTA					7
-#define CARRIER_DETECT_DIV_FLAG				0
-#ifdef RT3090
-#define CARRIER_DETECT_THRESHOLD_3090A			0x1fffffff
-#endif // RT3090 //
-#ifdef RT3390
-#define CARRIER_DETECT_THRESHOLD			0x0fffffff
-#endif // RT3390 //
-#ifndef RT3390
-#define CARRIER_DETECT_THRESHOLD			0x0fffffff
-#endif // RT3390 //
-#endif // TONE_RADAR_DETECT_SUPPORT //
-
-typedef struct CARRIER_DETECTION_s
-{
-	BOOLEAN					Enable;
-	UINT8					CDSessionTime;
-	UINT8					CDPeriod;
-	CD_STATE				CD_State;
-#ifdef TONE_RADAR_DETECT_SUPPORT
-	UINT8					delta;
-	UINT8					div_flag;
-	UINT32					threshold;
-	UINT8					recheck;
-	UINT8					recheck1;
-	UINT8					recheck2;
-	UINT32					TimeStamp;
-	UINT32					criteria;
-	UINT32					CarrierDebug;
-	ULONG					idle_time;
-	ULONG					busy_time;
-	ULONG					Debug;
-#endif // TONE_RADAR_DETECT_SUPPORT //
-}CARRIER_DETECTION_STRUCT, *PCARRIER_DETECTION_STRUCT;
-#endif // CARRIER_DETECTION_SUPPORT //
-
-
-#ifdef NEW_DFS
-typedef struct _NewDFSDebug
-{
-	UCHAR channel;
-	ULONG wait_time;
-	UCHAR delta_delay_range;
-	UCHAR delta_delay_step;
-	UCHAR EL_range;
-	UCHAR EL_step;
-	UCHAR EH_range;
-	UCHAR EH_step;
-	UCHAR WL_range;
-	UCHAR WL_step;
-	UCHAR WH_range;
-	UCHAR WH_step;
-	ULONG T_expected;
-	ULONG T_margin;
-	UCHAR start;
-	ULONG count;
-	ULONG idx;
-
-}NewDFSDebug, *pNewDFSDebug;
-
-#define NEW_DFS_FCC_5_ENT_NUM		5
-#define NEW_DFS_DBG_PORT_ENT_NUM_POWER	8
-#define NEW_DFS_DBG_PORT_ENT_NUM		(1 << NEW_DFS_DBG_PORT_ENT_NUM_POWER)  // CE Debug Port entry number, 256
-#define NEW_DFS_DBG_PORT_MASK	0xff
-
-// Matched Period definition
-#define NEW_DFS_MPERIOD_ENT_NUM_POWER		8
-#define NEW_DFS_MPERIOD_ENT_NUM		(1 << NEW_DFS_MPERIOD_ENT_NUM_POWER)	 // CE Period Table entry number, 512
-#define NEW_DFS_MAX_CHANNEL	4
-
-typedef struct _NewDFSDebugPort{
-	ULONG counter;
-	ULONG timestamp;
-	USHORT width;
-	USHORT start_idx; // start index to period table
-	USHORT end_idx; // end index to period table
-}NewDFSDebugPort, *pNewDFSDebugPort;
-
-// Matched Period Table
-typedef struct _NewDFSMPeriod{
-	USHORT	idx;
-	USHORT width;
-	USHORT	idx2;
-	USHORT width2;
-	ULONG period;
-}NewDFSMPeriod, *pNewDFSMPeriod;
-
-#endif // NEW_DFS //
-
-
-typedef enum _ABGBAND_STATE_ {
-	UNKNOWN_BAND,
-	BG_BAND,
-	A_BAND,
-} ABGBAND_STATE;
-
-#ifdef RTMP_MAC_PCI
-#ifdef CONFIG_STA_SUPPORT
-// Power save method control
-typedef	union	_PS_CONTROL	{
-	struct	{
-		ULONG		EnablePSinIdle:1;			// Enable radio off when not connect to AP. radio on only when sitesurvey,
-		ULONG		EnableNewPS:1;		// Enable new  Chip power save fucntion . New method can only be applied in chip version after 2872. and PCIe.
-		ULONG		rt30xxPowerMode:2;			// Power Level Mode for rt30xx chip
-		ULONG		rt30xxFollowHostASPM:1;			// Card Follows Host's setting for rt30xx chip.
-		ULONG		rt30xxForceASPMTest:1;			// Force enable L1 for rt30xx chip. This has higher priority than rt30xxFollowHostASPM Mode.
-		ULONG		rsv:26;			// Radio Measurement Enable
-	}	field;
-	ULONG			word;
-}	PS_CONTROL, *PPS_CONTROL;
-#endif // CONFIG_STA_SUPPORT //
-#endif // RTMP_MAC_PCI //
-/***************************************************************************
-  *	structure for MLME state machine
-  **************************************************************************/
-typedef struct _MLME_STRUCT {
-#ifdef CONFIG_STA_SUPPORT
-	// STA state machines
-	STATE_MACHINE           CntlMachine;
-	STATE_MACHINE           AssocMachine;
-	STATE_MACHINE           AuthMachine;
-	STATE_MACHINE           AuthRspMachine;
-	STATE_MACHINE           SyncMachine;
-	STATE_MACHINE           WpaPskMachine;
-	STATE_MACHINE           LeapMachine;
-	STATE_MACHINE_FUNC      AssocFunc[ASSOC_FUNC_SIZE];
-	STATE_MACHINE_FUNC      AuthFunc[AUTH_FUNC_SIZE];
-	STATE_MACHINE_FUNC      AuthRspFunc[AUTH_RSP_FUNC_SIZE];
-	STATE_MACHINE_FUNC      SyncFunc[SYNC_FUNC_SIZE];
-#endif // CONFIG_STA_SUPPORT //
-	STATE_MACHINE_FUNC      ActFunc[ACT_FUNC_SIZE];
-	// Action
-	STATE_MACHINE           ActMachine;
-
-
-#ifdef QOS_DLS_SUPPORT
-	STATE_MACHINE			DlsMachine;
-	STATE_MACHINE_FUNC      DlsFunc[DLS_FUNC_SIZE];
-#endif // QOS_DLS_SUPPORT //
-
-
-	// common WPA state machine
-	STATE_MACHINE           WpaMachine;
-	STATE_MACHINE_FUNC      WpaFunc[WPA_FUNC_SIZE];
-
-
-
-	ULONG                   ChannelQuality;  // 0..100, Channel Quality Indication for Roaming
-	ULONG                   Now32;           // latch the value of NdisGetSystemUpTime()
-	ULONG                   LastSendNULLpsmTime;
-
-	BOOLEAN                 bRunning;
-	NDIS_SPIN_LOCK          TaskLock;
-	MLME_QUEUE              Queue;
-
-	UINT                    ShiftReg;
-
-	RALINK_TIMER_STRUCT     PeriodicTimer;
-	RALINK_TIMER_STRUCT     APSDPeriodicTimer;
-	RALINK_TIMER_STRUCT     LinkDownTimer;
-	RALINK_TIMER_STRUCT     LinkUpTimer;
-#ifdef RTMP_MAC_PCI
-    UCHAR                   bPsPollTimerRunning;
-    RALINK_TIMER_STRUCT     PsPollTimer;
-	RALINK_TIMER_STRUCT     RadioOnOffTimer;
-#endif // RTMP_MAC_PCI //
-	ULONG                   PeriodicRound;
-	ULONG                   OneSecPeriodicRound;
-
-	UCHAR					RealRxPath;
-	BOOLEAN					bLowThroughput;
-	BOOLEAN					bEnableAutoAntennaCheck;
-	RALINK_TIMER_STRUCT		RxAntEvalTimer;
-
-#ifdef RT30xx
-	UCHAR CaliBW40RfR24;
-	UCHAR CaliBW20RfR24;
-#endif // RT30xx //
-
-} MLME_STRUCT, *PMLME_STRUCT;
-
-
-#ifdef DOT11_N_SUPPORT
-/***************************************************************************
-  *	802.11 N related data structures
-  **************************************************************************/
-struct reordering_mpdu
-{
-	struct reordering_mpdu	*next;
-	PNDIS_PACKET			pPacket;		/* coverted to 802.3 frame */
-	int						Sequence;		/* sequence number of MPDU */
-	BOOLEAN					bAMSDU;
-};
-
-struct reordering_list
-{
-	struct reordering_mpdu *next;
-	int	qlen;
-};
-
-struct reordering_mpdu_pool
-{
-	PVOID					mem;
-	NDIS_SPIN_LOCK			lock;
-	struct reordering_list	freelist;
-};
-
-typedef enum _REC_BLOCKACK_STATUS
-{
-    Recipient_NONE=0,
-	Recipient_USED,
-	Recipient_HandleRes,
-    Recipient_Accept
-} REC_BLOCKACK_STATUS, *PREC_BLOCKACK_STATUS;
-
-typedef enum _ORI_BLOCKACK_STATUS
-{
-    Originator_NONE=0,
-	Originator_USED,
-    Originator_WaitRes,
-    Originator_Done
-} ORI_BLOCKACK_STATUS, *PORI_BLOCKACK_STATUS;
-
-typedef struct _BA_ORI_ENTRY{
-	UCHAR   Wcid;
-	UCHAR   TID;
-	UCHAR   BAWinSize;
-	UCHAR   Token;
-// Sequence is to fill every outgoing QoS DATA frame's sequence field in 802.11 header.
-	USHORT	Sequence;
-	USHORT	TimeOutValue;
-	ORI_BLOCKACK_STATUS  ORI_BA_Status;
-	RALINK_TIMER_STRUCT ORIBATimer;
-	PVOID	pAdapter;
-} BA_ORI_ENTRY, *PBA_ORI_ENTRY;
-
-typedef struct _BA_REC_ENTRY {
-	UCHAR   Wcid;
-	UCHAR   TID;
-	UCHAR   BAWinSize;	// 7.3.1.14. each buffer is capable of holding a max AMSDU or MSDU.
-	//UCHAR	NumOfRxPkt;
-	//UCHAR    Curindidx; // the head in the RX reordering buffer
-	USHORT		LastIndSeq;
-//	USHORT		LastIndSeqAtTimer;
-	USHORT		TimeOutValue;
-	RALINK_TIMER_STRUCT RECBATimer;
-	ULONG		LastIndSeqAtTimer;
-	ULONG		nDropPacket;
-	ULONG		rcvSeq;
-	REC_BLOCKACK_STATUS  REC_BA_Status;
-//	UCHAR	RxBufIdxUsed;
-	// corresponding virtual address for RX reordering packet storage.
-	//RTMP_REORDERDMABUF MAP_RXBuf[MAX_RX_REORDERBUF];
-	NDIS_SPIN_LOCK          RxReRingLock;                 // Rx Ring spinlock
-//	struct _BA_REC_ENTRY *pNext;
-	PVOID	pAdapter;
-	struct reordering_list	list;
-} BA_REC_ENTRY, *PBA_REC_ENTRY;
-
-
-typedef struct {
-	ULONG		numAsRecipient;		// I am recipient of numAsRecipient clients. These client are in the BARecEntry[]
-	ULONG		numAsOriginator;	// I am originator of	numAsOriginator clients. These clients are in the BAOriEntry[]
-	ULONG		numDoneOriginator;	// count Done Originator sessions
-	BA_ORI_ENTRY       BAOriEntry[MAX_LEN_OF_BA_ORI_TABLE];
-	BA_REC_ENTRY       BARecEntry[MAX_LEN_OF_BA_REC_TABLE];
-} BA_TABLE, *PBA_TABLE;
-
-//For QureyBATableOID use;
-typedef struct  PACKED _OID_BA_REC_ENTRY{
-	UCHAR   MACAddr[MAC_ADDR_LEN];
-	UCHAR   BaBitmap;   // if (BaBitmap&(1<<TID)), this session with{MACAddr, TID}exists, so read BufSize[TID] for BufferSize
-	UCHAR   rsv;
-	UCHAR   BufSize[8];
-	REC_BLOCKACK_STATUS	REC_BA_Status[8];
-} OID_BA_REC_ENTRY, *POID_BA_REC_ENTRY;
-
-//For QureyBATableOID use;
-typedef struct  PACKED _OID_BA_ORI_ENTRY{
-	UCHAR   MACAddr[MAC_ADDR_LEN];
-	UCHAR   BaBitmap;  // if (BaBitmap&(1<<TID)), this session with{MACAddr, TID}exists, so read BufSize[TID] for BufferSize, read ORI_BA_Status[TID] for status
-	UCHAR   rsv;
-	UCHAR   BufSize[8];
-	ORI_BLOCKACK_STATUS  ORI_BA_Status[8];
-} OID_BA_ORI_ENTRY, *POID_BA_ORI_ENTRY;
-
-typedef struct _QUERYBA_TABLE{
-	OID_BA_ORI_ENTRY       BAOriEntry[32];
-	OID_BA_REC_ENTRY       BARecEntry[32];
-	UCHAR   OriNum;// Number of below BAOriEntry
-	UCHAR   RecNum;// Number of below BARecEntry
-} QUERYBA_TABLE, *PQUERYBA_TABLE;
-
-typedef	union	_BACAP_STRUC	{
-#ifdef RT_BIG_ENDIAN
-	struct	{
-		UINT32     :4;
-		UINT32     b2040CoexistScanSup:1;		//As Sta, support do 2040 coexistence scan for AP. As Ap, support monitor trigger event to check if can use BW 40MHz.
-		UINT32     bHtAdhoc:1;			// adhoc can use ht rate.
-		UINT32     MMPSmode:2;	// MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable
-		UINT32     AmsduSize:1;	// 0:3839, 1:7935 bytes. UINT  MSDUSizeToBytes[]	= { 3839, 7935};
-		UINT32     AmsduEnable:1;	//Enable AMSDU transmisstion
-		UINT32		MpduDensity:3;
-		UINT32		Policy:2;	// 0: DELAY_BA 1:IMMED_BA  (//BA Policy subfiled value in ADDBA frame)   2:BA-not use
-		UINT32		AutoBA:1;	// automatically BA
-		UINT32		TxBAWinLimit:8;
-		UINT32		RxBAWinLimit:8;
-	}	field;
-#else
-	struct	{
-		UINT32		RxBAWinLimit:8;
-		UINT32		TxBAWinLimit:8;
-		UINT32		AutoBA:1;	// automatically BA
-		UINT32		Policy:2;	// 0: DELAY_BA 1:IMMED_BA  (//BA Policy subfiled value in ADDBA frame)   2:BA-not use
-		UINT32		MpduDensity:3;
-		UINT32		AmsduEnable:1;	//Enable AMSDU transmisstion
-		UINT32		AmsduSize:1;	// 0:3839, 1:7935 bytes. UINT  MSDUSizeToBytes[]	= { 3839, 7935};
-		UINT32		MMPSmode:2;	// MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable
-		UINT32		bHtAdhoc:1;			// adhoc can use ht rate.
-		UINT32		b2040CoexistScanSup:1;		//As Sta, support do 2040 coexistence scan for AP. As Ap, support monitor trigger event to check if can use BW 40MHz.
-		UINT32		:4;
-	}	field;
-#endif
-	UINT32			word;
-} BACAP_STRUC, *PBACAP_STRUC;
-
-
-typedef struct {
-	BOOLEAN		IsRecipient;
-	UCHAR   MACAddr[MAC_ADDR_LEN];
-	UCHAR   TID;
-	UCHAR   nMSDU;
-	USHORT   TimeOut;
-	BOOLEAN bAllTid;  // If True, delete all TID for BA sessions with this MACaddr.
-} OID_ADD_BA_ENTRY, *POID_ADD_BA_ENTRY;
-
-
-#ifdef DOT11N_DRAFT3
-typedef enum _BSS2040COEXIST_FLAG{
-	BSS_2040_COEXIST_DISABLE = 0,
-	BSS_2040_COEXIST_TIMER_FIRED  = 1,
-	BSS_2040_COEXIST_INFO_SYNC = 2,
-	BSS_2040_COEXIST_INFO_NOTIFY = 4,
-}BSS2040COEXIST_FLAG;
-#endif // DOT11N_DRAFT3 //
-
-#define IS_HT_STA(_pMacEntry)	\
-	(_pMacEntry->MaxHTPhyMode.field.MODE >= MODE_HTMIX)
-
-#define IS_HT_RATE(_pMacEntry)	\
-	(_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
-
-#define PEER_IS_HT_RATE(_pMacEntry)	\
-	(_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
-
-#endif // DOT11_N_SUPPORT //
-
-
-//This structure is for all 802.11n card InterOptibilityTest action. Reset all Num every n second.  (Details see MLMEPeriodic)
-typedef	struct	_IOT_STRUC	{
-	UCHAR			Threshold[2];
-	UCHAR			ReorderTimeOutNum[MAX_LEN_OF_BA_REC_TABLE];	// compare with threshold[0]
-	UCHAR			RefreshNum[MAX_LEN_OF_BA_REC_TABLE];	// compare with threshold[1]
-	ULONG			OneSecInWindowCount;
-	ULONG			OneSecFrameDuplicateCount;
-	ULONG			OneSecOutWindowCount;
-	UCHAR			DelOriAct;
-	UCHAR			DelRecAct;
-	UCHAR			RTSShortProt;
-	UCHAR			RTSLongProt;
-	BOOLEAN			bRTSLongProtOn;
-#ifdef CONFIG_STA_SUPPORT
-	BOOLEAN			bLastAtheros;
-    BOOLEAN			bCurrentAtheros;
-    BOOLEAN         bNowAtherosBurstOn;
-	BOOLEAN			bNextDisableRxBA;
-    BOOLEAN			bToggle;
-#endif // CONFIG_STA_SUPPORT //
-} IOT_STRUC, *PIOT_STRUC;
-
-
-// This is the registry setting for 802.11n transmit setting.  Used in advanced page.
-typedef union _REG_TRANSMIT_SETTING {
-#ifdef RT_BIG_ENDIAN
- struct {
-         UINT32  rsv:13;
-		 UINT32  EXTCHA:2;
-		 UINT32  HTMODE:1;
-		 UINT32  TRANSNO:2;
-		 UINT32  STBC:1; //SPACE
-		 UINT32  ShortGI:1;
-		 UINT32  BW:1; //channel bandwidth 20MHz or 40 MHz
-		 UINT32  TxBF:1; // 3*3
-		 UINT32  rsv0:10;
-		 //UINT32  MCS:7;                 // MCS
-         //UINT32  PhyMode:4;
-    } field;
-#else
- struct {
-         //UINT32  PhyMode:4;
-         //UINT32  MCS:7;                 // MCS
-		 UINT32  rsv0:10;
-		 UINT32  TxBF:1;
-         UINT32  BW:1; //channel bandwidth 20MHz or 40 MHz
-         UINT32  ShortGI:1;
-         UINT32  STBC:1; //SPACE
-         UINT32  TRANSNO:2;
-         UINT32  HTMODE:1;
-         UINT32  EXTCHA:2;
-         UINT32  rsv:13;
-    } field;
-#endif
- UINT32   word;
-} REG_TRANSMIT_SETTING, *PREG_TRANSMIT_SETTING;
-
-
-typedef union  _DESIRED_TRANSMIT_SETTING {
-#ifdef RT_BIG_ENDIAN
-	struct	{
-			USHORT		rsv:3;
-			USHORT		FixedTxMode:2;			// If MCS isn't AUTO, fix rate in CCK, OFDM or HT mode.
-			USHORT		PhyMode:4;
-			USHORT		MCS:7;                 // MCS
-	}	field;
-#else
-	struct	{
-			USHORT		MCS:7;			// MCS
-			USHORT		PhyMode:4;
-			USHORT		FixedTxMode:2;			// If MCS isn't AUTO, fix rate in CCK, OFDM or HT mode.
-			USHORT		rsv:3;
-	}	field;
-#endif
-	USHORT		word;
- } DESIRED_TRANSMIT_SETTING, *PDESIRED_TRANSMIT_SETTING;
-
-
-
-
-/***************************************************************************
-  *	Multiple SSID related data structures
-  **************************************************************************/
-#define WLAN_MAX_NUM_OF_TIM			((MAX_LEN_OF_MAC_TABLE >> 3) + 1) /* /8 + 1 */
-#define WLAN_CT_TIM_BCMC_OFFSET		0 /* unit: 32B */
-
-/* clear bcmc TIM bit */
-#define WLAN_MR_TIM_BCMC_CLEAR(apidx) \
-	pAd->ApCfg.MBSSID[apidx].TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] &= ~BIT8[0];
-
-/* set bcmc TIM bit */
-#define WLAN_MR_TIM_BCMC_SET(apidx) \
-	pAd->ApCfg.MBSSID[apidx].TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] |= BIT8[0];
-
-/* clear a station PS TIM bit */
-#define WLAN_MR_TIM_BIT_CLEAR(ad_p, apidx, wcid) \
-	{	UCHAR tim_offset = wcid >> 3; \
-		UCHAR bit_offset = wcid & 0x7; \
-		ad_p->ApCfg.MBSSID[apidx].TimBitmaps[tim_offset] &= (~BIT8[bit_offset]); }
-
-/* set a station PS TIM bit */
-#define WLAN_MR_TIM_BIT_SET(ad_p, apidx, wcid) \
-	{	UCHAR tim_offset = wcid >> 3; \
-		UCHAR bit_offset = wcid & 0x7; \
-		ad_p->ApCfg.MBSSID[apidx].TimBitmaps[tim_offset] |= BIT8[bit_offset]; }
-
-
-// configuration common to OPMODE_AP as well as OPMODE_STA
-typedef struct _COMMON_CONFIG {
-
-	BOOLEAN		bCountryFlag;
-	UCHAR		CountryCode[3];
-	UCHAR		Geography;
-	UCHAR       CountryRegion;      // Enum of country region, 0:FCC, 1:IC, 2:ETSI, 3:SPAIN, 4:France, 5:MKK, 6:MKK1, 7:Israel
-	UCHAR       CountryRegionForABand;	// Enum of country region for A band
-	UCHAR       PhyMode;            // PHY_11A, PHY_11B, PHY_11BG_MIXED, PHY_ABG_MIXED
-	UCHAR       DesiredPhyMode;            // PHY_11A, PHY_11B, PHY_11BG_MIXED, PHY_ABG_MIXED
-	USHORT      Dsifs;              // in units of usec
-	ULONG       PacketFilter;       // Packet filter for receiving
-	UINT8		RegulatoryClass[MAX_NUM_OF_REGULATORY_CLASS];
-
-	CHAR        Ssid[MAX_LEN_OF_SSID]; // NOT NULL-terminated
-	UCHAR       SsidLen;               // the actual ssid length in used
-	UCHAR       LastSsidLen;               // the actual ssid length in used
-	CHAR        LastSsid[MAX_LEN_OF_SSID]; // NOT NULL-terminated
-	UCHAR		LastBssid[MAC_ADDR_LEN];
-
-	UCHAR       Bssid[MAC_ADDR_LEN];
-	USHORT      BeaconPeriod;
-	UCHAR       Channel;
-	UCHAR       CentralChannel;	// Central Channel when using 40MHz is indicating. not real channel.
-
-	UCHAR       SupRate[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR       SupRateLen;
-	UCHAR       ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR       ExtRateLen;
-	UCHAR       DesireRate[MAX_LEN_OF_SUPPORTED_RATES];      // OID_802_11_DESIRED_RATES
-	UCHAR       MaxDesiredRate;
-	UCHAR       ExpectedACKRate[MAX_LEN_OF_SUPPORTED_RATES];
-
-	ULONG       BasicRateBitmap;        // backup basic ratebitmap
-
-	BOOLEAN		bAPSDCapable;
-	BOOLEAN		bInServicePeriod;
-	BOOLEAN		bAPSDAC_BE;
-	BOOLEAN		bAPSDAC_BK;
-	BOOLEAN		bAPSDAC_VI;
-	BOOLEAN		bAPSDAC_VO;
-
-	/* because TSPEC can modify the APSD flag, we need to keep the APSD flag
-		requested in association stage from the station;
-		we need to recover the APSD flag after the TSPEC is deleted. */
-	BOOLEAN		bACMAPSDBackup[4]; /* for delivery-enabled & trigger-enabled both */
-	BOOLEAN		bACMAPSDTr[4]; /* no use */
-
-	BOOLEAN		bNeedSendTriggerFrame;
-	BOOLEAN		bAPSDForcePowerSave;	// Force power save mode, should only use in APSD-STAUT
-	ULONG		TriggerTimerCount;
-	UCHAR		MaxSPLength;
-	UCHAR		BBPCurrentBW;	// BW_10,	BW_20, BW_40
-	// move to MULTISSID_STRUCT for MBSS
-	//HTTRANSMIT_SETTING	HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
-	REG_TRANSMIT_SETTING        RegTransmitSetting; //registry transmit setting. this is for reading registry setting only. not useful.
-	//UCHAR       FixedTxMode;              // Fixed Tx Mode (CCK, OFDM), for HT fixed tx mode (GF, MIX) , refer to RegTransmitSetting.field.HTMode
-	UCHAR       TxRate;                 // Same value to fill in TXD. TxRate is 6-bit
-	UCHAR       MaxTxRate;              // RATE_1, RATE_2, RATE_5_5, RATE_11
-	UCHAR       TxRateIndex;            // Tx rate index in RateSwitchTable
-	UCHAR       TxRateTableSize;        // Valid Tx rate table size in RateSwitchTable
-	//BOOLEAN		bAutoTxRateSwitch;
-	UCHAR       MinTxRate;              // RATE_1, RATE_2, RATE_5_5, RATE_11
-	UCHAR       RtsRate;                // RATE_xxx
-	HTTRANSMIT_SETTING	MlmeTransmit;   // MGMT frame PHY rate setting when operatin at Ht rate.
-	UCHAR       MlmeRate;               // RATE_xxx, used to send MLME frames
-	UCHAR       BasicMlmeRate;          // Default Rate for sending MLME frames
-
-	USHORT      RtsThreshold;           // in unit of BYTE
-	USHORT      FragmentThreshold;      // in unit of BYTE
-
-	UCHAR       TxPower;                // in unit of mW
-	ULONG       TxPowerPercentage;      // 0~100 %
-	ULONG       TxPowerDefault;         // keep for TxPowerPercentage
-	UINT8		PwrConstraint;
-
-#ifdef DOT11_N_SUPPORT
-	BACAP_STRUC        BACapability; //   NO USE = 0XFF  ;  IMMED_BA =1  ;  DELAY_BA=0
-	BACAP_STRUC        REGBACapability; //   NO USE = 0XFF  ;  IMMED_BA =1  ;  DELAY_BA=0
-#endif // DOT11_N_SUPPORT //
-	IOT_STRUC		IOTestParm;	// 802.11n InterOpbility Test Parameter;
-	ULONG       TxPreamble;             // Rt802_11PreambleLong, Rt802_11PreambleShort, Rt802_11PreambleAuto
-	BOOLEAN     bUseZeroToDisableFragment;     // Microsoft use 0 as disable
-	ULONG       UseBGProtection;        // 0: auto, 1: always use, 2: always not use
-	BOOLEAN     bUseShortSlotTime;      // 0: disable, 1 - use short slot (9us)
-	BOOLEAN     bEnableTxBurst;         // 1: enble TX PACKET BURST (when BA is established or AP is not a legacy WMM AP), 0: disable TX PACKET BURST
-	BOOLEAN     bAggregationCapable;      // 1: enable TX aggregation when the peer supports it
-	BOOLEAN     bPiggyBackCapable;		// 1: enable TX piggy-back according MAC's version
-	BOOLEAN     bIEEE80211H;			// 1: enable IEEE802.11h spec.
-	ULONG		DisableOLBCDetect;		// 0: enable OLBC detect; 1 disable OLBC detect
-
-#ifdef DOT11_N_SUPPORT
-	BOOLEAN				bRdg;
-#endif // DOT11_N_SUPPORT //
-	BOOLEAN             bWmmCapable;        // 0:disable WMM, 1:enable WMM
-	QOS_CAPABILITY_PARM APQosCapability;    // QOS capability of the current associated AP
-	EDCA_PARM           APEdcaParm;         // EDCA parameters of the current associated AP
-	QBSS_LOAD_PARM      APQbssLoad;         // QBSS load of the current associated AP
-	UCHAR               AckPolicy[4];       // ACK policy of the specified AC. see ACK_xxx
-#ifdef CONFIG_STA_SUPPORT
-	BOOLEAN				bDLSCapable;		// 0:disable DLS, 1:enable DLS
-#endif // CONFIG_STA_SUPPORT //
-	// a bitmap of BOOLEAN flags. each bit represent an operation status of a particular
-	// BOOLEAN control, either ON or OFF. These flags should always be accessed via
-	// OPSTATUS_TEST_FLAG(), OPSTATUS_SET_FLAG(), OP_STATUS_CLEAR_FLAG() macros.
-	// see fOP_STATUS_xxx in RTMP_DEF.C for detail bit definition
-	ULONG               OpStatusFlags;
-
-	BOOLEAN				NdisRadioStateOff; //For HCT 12.0, set this flag to TRUE instead of called MlmeRadioOff.
-	ABGBAND_STATE		BandState;		// For setting BBP used on B/G or A mode.
-#ifdef ANT_DIVERSITY_SUPPORT
-	UCHAR				bRxAntDiversity; // 0:disable, 1:enable Software Rx Antenna Diversity.
-#endif // ANT_DIVERSITY_SUPPORT //
-
-	// IEEE802.11H--DFS.
-	RADAR_DETECT_STRUCT	RadarDetect;
-
-#ifdef CARRIER_DETECTION_SUPPORT
-	CARRIER_DETECTION_STRUCT		CarrierDetect;
-#endif // CARRIER_DETECTION_SUPPORT //
-
-#ifdef DOT11_N_SUPPORT
-	// HT
-	UCHAR			BASize;		// USer desired BAWindowSize. Should not exceed our max capability
-	//RT_HT_CAPABILITY	SupportedHtPhy;
-	RT_HT_CAPABILITY	DesiredHtPhy;
-	HT_CAPABILITY_IE		HtCapability;
-	ADD_HT_INFO_IE		AddHTInfo;	// Useful as AP.
-	//This IE is used with channel switch announcement element when changing to a new 40MHz.
-	//This IE is included in channel switch ammouncement frames 7.4.1.5, beacons, probe Rsp.
-	NEW_EXT_CHAN_IE	NewExtChanOffset;	//7.3.2.20A, 1 if extension channel is above the control channel, 3 if below, 0 if not present
-
-#ifdef DOT11N_DRAFT3
-	UCHAR					Bss2040CoexistFlag;		// bit 0: bBssCoexistTimerRunning, bit 1: NeedSyncAddHtInfo.
-	RALINK_TIMER_STRUCT	Bss2040CoexistTimer;
-
-	//This IE is used for 20/40 BSS Coexistence.
-	BSS_2040_COEXIST_IE		BSS2040CoexistInfo;
-	// ====== 11n D3.0 =======================>
-	USHORT					Dot11OBssScanPassiveDwell;				// Unit : TU. 5~1000
-	USHORT					Dot11OBssScanActiveDwell;				// Unit : TU. 10~1000
-	USHORT					Dot11BssWidthTriggerScanInt;			// Unit : Second
-	USHORT					Dot11OBssScanPassiveTotalPerChannel;	// Unit : TU. 200~10000
-	USHORT					Dot11OBssScanActiveTotalPerChannel;	// Unit : TU. 20~10000
-	USHORT					Dot11BssWidthChanTranDelayFactor;
-	USHORT					Dot11OBssScanActivityThre;				// Unit : percentage
-
-	ULONG					Dot11BssWidthChanTranDelay;			// multiple of (Dot11BssWidthTriggerScanInt * Dot11BssWidthChanTranDelayFactor)
-	ULONG					CountDownCtr;	// CountDown Counter from (Dot11BssWidthTriggerScanInt * Dot11BssWidthChanTranDelayFactor)
-
-	NDIS_SPIN_LOCK          TriggerEventTabLock;
-	BSS_2040_COEXIST_IE		LastBSSCoexist2040;
-	BSS_2040_COEXIST_IE		BSSCoexist2040;
-	TRIGGER_EVENT_TAB		TriggerEventTab;
-	UCHAR					ChannelListIdx;
-	// <====== 11n D3.0 =======================
-	BOOLEAN					bOverlapScanning;
-#endif // DOT11N_DRAFT3 //
-
-    BOOLEAN                 bHTProtect;
-    BOOLEAN                 bMIMOPSEnable;
-    BOOLEAN					bBADecline;
-//2008/11/05: KH add to support Antenna power-saving of AP<--
-	BOOLEAN					bGreenAPEnable;
-	BOOLEAN					bBlockAntDivforGreenAP;
-//2008/11/05: KH add to support Antenna power-saving of AP-->
-	BOOLEAN					bDisableReordering;
-	BOOLEAN					bForty_Mhz_Intolerant;
-	BOOLEAN					bExtChannelSwitchAnnouncement;
-	BOOLEAN					bRcvBSSWidthTriggerEvents;
-	ULONG					LastRcvBSSWidthTriggerEventsTime;
-
-	UCHAR					TxBASize;
-#endif // DOT11_N_SUPPORT //
-
-	// Enable wireless event
-	BOOLEAN				bWirelessEvent;
-	BOOLEAN				bWiFiTest;				// Enable this parameter for WiFi test
-
-	// Tx & Rx Stream number selection
-	UCHAR				TxStream;
-	UCHAR				RxStream;
-
-	// transmit phy mode, trasmit rate for Multicast.
-#ifdef MCAST_RATE_SPECIFIC
-	UCHAR				McastTransmitMcs;
-	UCHAR				McastTransmitPhyMode;
-#endif // MCAST_RATE_SPECIFIC //
-
-	BOOLEAN			bHardwareRadio;     // Hardware controlled Radio enabled
-
-
-
-	NDIS_SPIN_LOCK			MeasureReqTabLock;
-	PMEASURE_REQ_TAB		pMeasureReqTab;
-
-	NDIS_SPIN_LOCK			TpcReqTabLock;
-	PTPC_REQ_TAB			pTpcReqTab;
-
-	// transmit phy mode, trasmit rate for Multicast.
-#ifdef MCAST_RATE_SPECIFIC
-	HTTRANSMIT_SETTING		MCastPhyMode;
-#endif // MCAST_RATE_SPECIFIC //
-
-#ifdef SINGLE_SKU
-	UINT16					DefineMaxTxPwr;
-#endif // SINGLE_SKU //
-
-
-	BOOLEAN				PSPXlink;  // 0: Disable. 1: Enable
-
-
-#if defined(RT305x)||defined(RT30xx)
-	// request by Gary, for High Power issue
-	UCHAR	HighPowerPatchDisabled;
-#endif
-
-	BOOLEAN		HT_DisallowTKIP;		/* Restrict the encryption type in 11n HT mode */
-} COMMON_CONFIG, *PCOMMON_CONFIG;
-
-
-#ifdef CONFIG_STA_SUPPORT
-/* Modified by Wu Xi-Kun 4/21/2006 */
-// STA configuration and status
-typedef struct _STA_ADMIN_CONFIG {
-	// GROUP 1 -
-	//   User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe
-	//   the user intended configuration, but not necessary fully equal to the final
-	//   settings in ACTIVE BSS after negotiation/compromize with the BSS holder (either
-	//   AP or IBSS holder).
-	//   Once initialized, user configuration can only be changed via OID_xxx
-	UCHAR       BssType;              // BSS_INFRA or BSS_ADHOC
-	USHORT      AtimWin;          // used when starting a new IBSS
-
-	// GROUP 2 -
-	//   User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe
-	//   the user intended configuration, and should be always applied to the final
-	//   settings in ACTIVE BSS without compromising with the BSS holder.
-	//   Once initialized, user configuration can only be changed via OID_xxx
-	UCHAR       RssiTrigger;
-	UCHAR       RssiTriggerMode;      // RSSI_TRIGGERED_UPON_BELOW_THRESHOLD or RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD
-	USHORT      DefaultListenCount;   // default listen count;
-	ULONG       WindowsPowerMode;           // Power mode for AC power
-	ULONG       WindowsBatteryPowerMode;    // Power mode for battery if exists
-	BOOLEAN     bWindowsACCAMEnable;        // Enable CAM power mode when AC on
-	BOOLEAN     bAutoReconnect;         // Set to TRUE when setting OID_802_11_SSID with no matching BSSID
-	ULONG       WindowsPowerProfile;    // Windows power profile, for NDIS5.1 PnP
-
-	// MIB:ieee802dot11.dot11smt(1).dot11StationConfigTable(1)
-	USHORT      Psm;                  // power management mode   (PWR_ACTIVE|PWR_SAVE)
-	USHORT      DisassocReason;
-	UCHAR       DisassocSta[MAC_ADDR_LEN];
-	USHORT      DeauthReason;
-	UCHAR       DeauthSta[MAC_ADDR_LEN];
-	USHORT      AuthFailReason;
-	UCHAR       AuthFailSta[MAC_ADDR_LEN];
-
-	NDIS_802_11_PRIVACY_FILTER          PrivacyFilter;  // PrivacyFilter enum for 802.1X
-	NDIS_802_11_AUTHENTICATION_MODE     AuthMode;       // This should match to whatever microsoft defined
-	NDIS_802_11_WEP_STATUS              WepStatus;
-	NDIS_802_11_WEP_STATUS				OrigWepStatus;	// Original wep status set from OID
-
-	// Add to support different cipher suite for WPA2/WPA mode
-	NDIS_802_11_ENCRYPTION_STATUS		GroupCipher;		// Multicast cipher suite
-	NDIS_802_11_ENCRYPTION_STATUS		PairCipher;			// Unicast cipher suite
-	BOOLEAN								bMixCipher;			// Indicate current Pair & Group use different cipher suites
-	USHORT								RsnCapability;
-
-	NDIS_802_11_WEP_STATUS              GroupKeyWepStatus;
-
-	UCHAR		WpaPassPhrase[64];		// WPA PSK pass phrase
-	UINT		WpaPassPhraseLen;		// the length of WPA PSK pass phrase
-	UCHAR		PMK[32];                // WPA PSK mode PMK
-	UCHAR       PTK[64];                // WPA PSK mode PTK
-	UCHAR		GTK[32];				// GTK from authenticator
-	BSSID_INFO	SavedPMK[PMKID_NO];
-	UINT		SavedPMKNum;			// Saved PMKID number
-
-	UCHAR		DefaultKeyId;
-
-
-	// WPA 802.1x port control, WPA_802_1X_PORT_SECURED, WPA_802_1X_PORT_NOT_SECURED
-	UCHAR       PortSecured;
-
-	// For WPA countermeasures
-	ULONG       LastMicErrorTime;   // record last MIC error time
-	ULONG       MicErrCnt;          // Should be 0, 1, 2, then reset to zero (after disassoiciation).
-	BOOLEAN     bBlockAssoc;        // Block associate attempt for 60 seconds after counter measure occurred.
-	// For WPA-PSK supplicant state
-	WPA_STATE   WpaState;           // Default is SS_NOTUSE and handled by microsoft 802.1x
-	UCHAR       ReplayCounter[8];
-	UCHAR       ANonce[32];         // ANonce for WPA-PSK from aurhenticator
-	UCHAR       SNonce[32];         // SNonce for WPA-PSK
-
-	UCHAR       LastSNR0;             // last received BEACON's SNR
-	UCHAR       LastSNR1;            // last received BEACON's SNR for 2nd  antenna
-	RSSI_SAMPLE RssiSample;
-	ULONG       NumOfAvgRssiSample;
-
-	ULONG       LastBeaconRxTime;     // OS's timestamp of the last BEACON RX time
-	ULONG       Last11bBeaconRxTime;  // OS's timestamp of the last 11B BEACON RX time
-	ULONG		Last11gBeaconRxTime;	// OS's timestamp of the last 11G BEACON RX time
-	ULONG		Last20NBeaconRxTime;	// OS's timestamp of the last 20MHz N BEACON RX time
-
-	ULONG       LastScanTime;       // Record last scan time for issue BSSID_SCAN_LIST
-	ULONG       ScanCnt;            // Scan counts since most recent SSID, BSSID, SCAN OID request
-	BOOLEAN     bSwRadio;           // Software controlled Radio On/Off, TRUE: On
-	BOOLEAN     bHwRadio;           // Hardware controlled Radio On/Off, TRUE: On
-	BOOLEAN     bRadio;             // Radio state, And of Sw & Hw radio state
-	BOOLEAN     bHardwareRadio;     // Hardware controlled Radio enabled
-	BOOLEAN     bShowHiddenSSID;    // Show all known SSID in SSID list get operation
-
-	// New for WPA, windows want us to to keep association information and
-	// Fixed IEs from last association response
-	NDIS_802_11_ASSOCIATION_INFORMATION     AssocInfo;
-	USHORT       ReqVarIELen;                // Length of next VIE include EID & Length
-	UCHAR       ReqVarIEs[MAX_VIE_LEN];		// The content saved here should be little-endian format.
-	USHORT       ResVarIELen;                // Length of next VIE include EID & Length
-	UCHAR       ResVarIEs[MAX_VIE_LEN];
-
-	UCHAR       RSNIE_Len;
-	UCHAR       RSN_IE[MAX_LEN_OF_RSNIE];	// The content saved here should be little-endian format.
-
-	ULONG               CLBusyBytes;                // Save the total bytes received durning channel load scan time
-	USHORT              RPIDensity[8];              // Array for RPI density collection
-
-	UCHAR               RMReqCnt;                   // Number of measurement request saved.
-	UCHAR               CurrentRMReqIdx;            // Number of measurement request saved.
-	BOOLEAN             ParallelReq;                // Parallel measurement, only one request performed,
-													// It must be the same channel with maximum duration
-	USHORT              ParallelDuration;           // Maximum duration for parallel measurement
-	UCHAR               ParallelChannel;            // Only one channel with parallel measurement
-	USHORT              IAPPToken;                  // IAPP dialog token
-	// Hack for channel load and noise histogram parameters
-	UCHAR               NHFactor;                   // Parameter for Noise histogram
-	UCHAR               CLFactor;                   // Parameter for channel load
-
-	RALINK_TIMER_STRUCT	StaQuickResponeForRateUpTimer;
-	BOOLEAN				StaQuickResponeForRateUpTimerRunning;
-
-	UCHAR			DtimCount;      // 0.. DtimPeriod-1
-	UCHAR			DtimPeriod;     // default = 3
-
-#ifdef QOS_DLS_SUPPORT
-	RT_802_11_DLS		DLSEntry[MAX_NUM_OF_DLS_ENTRY];
-	UCHAR				DlsReplayCounter[8];
-#endif // QOS_DLS_SUPPORT //
-	////////////////////////////////////////////////////////////////////////////////////////
-	// This is only for WHQL test.
-	BOOLEAN				WhqlTest;
-	////////////////////////////////////////////////////////////////////////////////////////
-
-    RALINK_TIMER_STRUCT WpaDisassocAndBlockAssocTimer;
-    // Fast Roaming
-	BOOLEAN		        bAutoRoaming;       // 0:disable auto roaming by RSSI, 1:enable auto roaming by RSSI
-	CHAR		        dBmToRoam;          // the condition to roam when receiving Rssi less than this value. It's negative value.
-
-#ifdef WPA_SUPPLICANT_SUPPORT
-    BOOLEAN             IEEE8021X;
-    BOOLEAN             IEEE8021x_required_keys;
-    CIPHER_KEY	        DesireSharedKey[4];	// Record user desired WEP keys
-    UCHAR               DesireSharedKeyId;
-
-    // 0: driver ignores wpa_supplicant
-    // 1: wpa_supplicant initiates scanning and AP selection
-    // 2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters
-    UCHAR               WpaSupplicantUP;
-	UCHAR				WpaSupplicantScanCount;
-	BOOLEAN				bRSN_IE_FromWpaSupplicant;
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-    CHAR                dev_name[16];
-    USHORT              OriDevType;
-
-    BOOLEAN             bTGnWifiTest;
-	BOOLEAN			    bScanReqIsFromWebUI;
-
-	HTTRANSMIT_SETTING				HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
-	DESIRED_TRANSMIT_SETTING	DesiredTransmitSetting;
-	RT_HT_PHY_INFO					DesiredHtPhyInfo;
-	BOOLEAN							bAutoTxRateSwitch;
-
-#ifdef RTMP_MAC_PCI
-    UCHAR       BBPR3;
-	// PS Control has 2 meanings for advanced power save function.
-	// 1. EnablePSinIdle : When no connection, always radio off except need to do site survey.
-	// 2. EnableNewPS  : will save more current in sleep or radio off mode.
-	PS_CONTROL				PSControl;
-#endif // RTMP_MAC_PCI //
-
-#ifdef EXT_BUILD_CHANNEL_LIST
-	UCHAR				IEEE80211dClientMode;
-	UCHAR				StaOriCountryCode[3];
-	UCHAR				StaOriGeography;
-#endif // EXT_BUILD_CHANNEL_LIST //
-
-
-
-	BOOLEAN				bAutoConnectByBssid;
-	ULONG				BeaconLostTime;	// seconds
-	BOOLEAN			bForceTxBurst;          // 1: force enble TX PACKET BURST, 0: disable
-} STA_ADMIN_CONFIG, *PSTA_ADMIN_CONFIG;
-
-// This data structure keep the current active BSS/IBSS's configuration that this STA
-// had agreed upon joining the network. Which means these parameters are usually decided
-// by the BSS/IBSS creator instead of user configuration. Data in this data structurre
-// is valid only when either ADHOC_ON(pAd) or INFRA_ON(pAd) is TRUE.
-// Normally, after SCAN or failed roaming attempts, we need to recover back to
-// the current active settings.
-typedef struct _STA_ACTIVE_CONFIG {
-	USHORT      Aid;
-	USHORT      AtimWin;                // in kusec; IBSS parameter set element
-	USHORT      CapabilityInfo;
-	USHORT      CfpMaxDuration;
-	USHORT      CfpPeriod;
-
-	// Copy supported rate from desired AP's beacon. We are trying to match
-	// AP's supported and extended rate settings.
-	UCHAR       SupRate[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR       ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR       SupRateLen;
-	UCHAR       ExtRateLen;
-	// Copy supported ht from desired AP's beacon. We are trying to match
-	RT_HT_PHY_INFO		SupportedPhyInfo;
-	RT_HT_CAPABILITY	SupportedHtPhy;
-} STA_ACTIVE_CONFIG, *PSTA_ACTIVE_CONFIG;
-
-
-
-#endif // CONFIG_STA_SUPPORT //
-
-
-
-typedef struct _MAC_TABLE_ENTRY {
-	//Choose 1 from ValidAsWDS and ValidAsCLI  to validize.
-	BOOLEAN		ValidAsCLI;		// Sta mode, set this TRUE after Linkup,too.
-	BOOLEAN		ValidAsWDS;	// This is WDS Entry. only for AP mode.
-	BOOLEAN		ValidAsApCli;   //This is a AP-Client entry, only for AP mode which enable AP-Client functions.
-	BOOLEAN		ValidAsMesh;
-	BOOLEAN		ValidAsDls;	// This is DLS Entry. only for STA mode.
-	BOOLEAN		isCached;
-	BOOLEAN		bIAmBadAtheros;	// Flag if this is Atheros chip that has IOT problem.  We need to turn on RTS/CTS protection.
-
-	UCHAR		EnqueueEapolStartTimerRunning;  // Enqueue EAPoL-Start for triggering EAP SM
-	//jan for wpa
-	// record which entry revoke MIC Failure , if it leaves the BSS itself, AP won't update aMICFailTime MIB
-	UCHAR           CMTimerRunning;
-	UCHAR           apidx;			// MBSS number
-	UCHAR           RSNIE_Len;
-	UCHAR           RSN_IE[MAX_LEN_OF_RSNIE];
-	UCHAR           ANonce[LEN_KEY_DESC_NONCE];
-	UCHAR           SNonce[LEN_KEY_DESC_NONCE];
-	UCHAR           R_Counter[LEN_KEY_DESC_REPLAY];
-	UCHAR           PTK[64];
-	UCHAR           ReTryCounter;
-	RALINK_TIMER_STRUCT                 RetryTimer;
-	RALINK_TIMER_STRUCT					EnqueueStartForPSKTimer;	// A timer which enqueue EAPoL-Start for triggering PSK SM
-	NDIS_802_11_AUTHENTICATION_MODE     AuthMode;   // This should match to whatever microsoft defined
-	NDIS_802_11_WEP_STATUS              WepStatus;
-	NDIS_802_11_WEP_STATUS              GroupKeyWepStatus;
-	AP_WPA_STATE    WpaState;
-	GTK_STATE       GTKState;
-	USHORT          PortSecured;
-	NDIS_802_11_PRIVACY_FILTER  PrivacyFilter;      // PrivacyFilter enum for 802.1X
-	CIPHER_KEY      PairwiseKey;
-	PVOID           pAd;
-	INT				PMKID_CacheIdx;
-	UCHAR			PMKID[LEN_PMKID];
-
-
-	UCHAR           Addr[MAC_ADDR_LEN];
-	UCHAR           PsMode;
-	SST             Sst;
-	AUTH_STATE      AuthState; // for SHARED KEY authentication state machine used only
-	BOOLEAN			IsReassocSta;	// Indicate whether this is a reassociation procedure
-	USHORT          Aid;
-	USHORT          CapabilityInfo;
-	UCHAR           LastRssi;
-	ULONG           NoDataIdleCount;
-	UINT16			StationKeepAliveCount; // unit: second
-	ULONG           PsQIdleCount;
-	QUEUE_HEADER    PsQueue;
-
-	UINT32			StaConnectTime;		// the live time of this station since associated with AP
-
-
-#ifdef DOT11_N_SUPPORT
-	BOOLEAN			bSendBAR;
-	USHORT			NoBADataCountDown;
-
-	UINT32			CachedBuf[16];		// UINT (4 bytes) for alignment
-	UINT			TxBFCount; // 3*3
-#endif // DOT11_N_SUPPORT //
-	UINT			FIFOCount;
-	UINT			DebugFIFOCount;
-	UINT			DebugTxCount;
-    BOOLEAN			bDlsInit;
-
-
-//====================================================
-//WDS entry needs these
-// if ValidAsWDS==TRUE, MatchWDSTabIdx is the index in WdsTab.MacTab
-	UINT			MatchWDSTabIdx;
-	UCHAR           MaxSupportedRate;
-	UCHAR           CurrTxRate;
-	UCHAR           CurrTxRateIndex;
-	// to record the each TX rate's quality. 0 is best, the bigger the worse.
-	USHORT          TxQuality[MAX_STEP_OF_TX_RATE_SWITCH];
-//	USHORT          OneSecTxOkCount;
-	UINT32			OneSecTxNoRetryOkCount;
-	UINT32          OneSecTxRetryOkCount;
-	UINT32          OneSecTxFailCount;
-	UINT32			ContinueTxFailCnt;
-	UINT32          CurrTxRateStableTime; // # of second in current TX rate
-	UCHAR           TxRateUpPenalty;      // extra # of second penalty due to last unstable condition
-#ifdef WDS_SUPPORT
-	BOOLEAN		LockEntryTx; // TRUE = block to WDS Entry traffic, FALSE = not.
-	UINT32		TimeStamp_toTxRing;
-#endif // WDS_SUPPORT //
-
-//====================================================
-
-
-
-#ifdef CONFIG_STA_SUPPORT
-#ifdef QOS_DLS_SUPPORT
-	UINT			MatchDlsEntryIdx; // indicate the index in pAd->StaCfg.DLSEntry
-#endif // QOS_DLS_SUPPORT //
-#endif // CONFIG_STA_SUPPORT //
-
-	BOOLEAN         fNoisyEnvironment;
-	BOOLEAN			fLastSecAccordingRSSI;
-	UCHAR           LastSecTxRateChangeAction; // 0: no change, 1:rate UP, 2:rate down
-	CHAR			LastTimeTxRateChangeAction; //Keep last time value of LastSecTxRateChangeAction
-	ULONG			LastTxOkCount;
-	UCHAR           PER[MAX_STEP_OF_TX_RATE_SWITCH];
-
-	// a bitmap of BOOLEAN flags. each bit represent an operation status of a particular
-	// BOOLEAN control, either ON or OFF. These flags should always be accessed via
-	// CLIENT_STATUS_TEST_FLAG(), CLIENT_STATUS_SET_FLAG(), CLIENT_STATUS_CLEAR_FLAG() macros.
-	// see fOP_STATUS_xxx in RTMP_DEF.C for detail bit definition. fCLIENT_STATUS_AMSDU_INUSED
-	ULONG           ClientStatusFlags;
-
-	HTTRANSMIT_SETTING	HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
-
-#ifdef DOT11_N_SUPPORT
-	// HT EWC MIMO-N used parameters
-	USHORT		RXBAbitmap;	// fill to on-chip  RXWI_BA_BITMASK in 8.1.3RX attribute entry format
-	USHORT		TXBAbitmap;	// This bitmap as originator, only keep in software used to mark AMPDU bit in TXWI
-	USHORT		TXAutoBAbitmap;
-	USHORT		BADeclineBitmap;
-	USHORT		BARecWcidArray[NUM_OF_TID];	// The mapping wcid of recipient session. if RXBAbitmap bit is masked
-	USHORT		BAOriWcidArray[NUM_OF_TID]; // The mapping wcid of originator session. if TXBAbitmap bit is masked
-	USHORT		BAOriSequence[NUM_OF_TID]; // The mapping wcid of originator session. if TXBAbitmap bit is masked
-
-	// 802.11n features.
-	UCHAR		MpduDensity;
-	UCHAR		MaxRAmpduFactor;
-	UCHAR		AMsduSize;
-	UCHAR		MmpsMode;	// MIMO power save more.
-
-	HT_CAPABILITY_IE		HTCapability;
-
-#ifdef DOT11N_DRAFT3
-	UCHAR		BSS2040CoexistenceMgmtSupport;
-#endif // DOT11N_DRAFT3 //
-#endif // DOT11_N_SUPPORT //
-
-	BOOLEAN		bAutoTxRateSwitch;
-
-	UCHAR       RateLen;
-	struct _MAC_TABLE_ENTRY *pNext;
-    USHORT      TxSeq[NUM_OF_TID];
-	USHORT		NonQosDataSeq;
-
-	RSSI_SAMPLE	RssiSample;
-
-	UINT32			TXMCSExpected[16];
-	UINT32			TXMCSSuccessful[16];
-	UINT32			TXMCSFailed[16];
-	UINT32			TXMCSAutoFallBack[16][16];
-
-#ifdef CONFIG_STA_SUPPORT
-	ULONG			LastBeaconRxTime;
-#endif // CONFIG_STA_SUPPORT //
-
-
-
-	ULONG AssocDeadLine;
-
-
-
-	ULONG ChannelQuality;  // 0..100, Channel Quality Indication for Roaming
-
-} MAC_TABLE_ENTRY, *PMAC_TABLE_ENTRY;
-
-typedef struct _MAC_TABLE {
-	USHORT			Size;
-	MAC_TABLE_ENTRY *Hash[HASH_TABLE_SIZE];
-	MAC_TABLE_ENTRY Content[MAX_LEN_OF_MAC_TABLE];
-	QUEUE_HEADER    McastPsQueue;
-	ULONG           PsQIdleCount;
-	BOOLEAN         fAnyStationInPsm;
-	BOOLEAN         fAnyStationBadAtheros;	// Check if any Station is atheros 802.11n Chip.  We need to use RTS/CTS with Atheros 802,.11n chip.
-	BOOLEAN			fAnyTxOPForceDisable;	// Check if it is necessary to disable BE TxOP
-	BOOLEAN			fAllStationAsRalink;	// Check if all stations are ralink-chipset
-#ifdef DOT11_N_SUPPORT
-	BOOLEAN         fAnyStationIsLegacy;	// Check if I use legacy rate to transmit to my BSS Station/
-	BOOLEAN         fAnyStationNonGF;		// Check if any Station can't support GF.
-	BOOLEAN         fAnyStation20Only;		// Check if any Station can't support GF.
-	BOOLEAN			fAnyStationMIMOPSDynamic; // Check if any Station is MIMO Dynamic
-	BOOLEAN         fAnyBASession;   // Check if there is BA session.  Force turn on RTS/CTS
-//2008/10/28: KH add to support Antenna power-saving of AP<--
-//2008/10/28: KH add to support Antenna power-saving of AP-->
-#endif // DOT11_N_SUPPORT //
-} MAC_TABLE, *PMAC_TABLE;
-
-
-
-
-#ifdef BLOCK_NET_IF
-typedef struct _BLOCK_QUEUE_ENTRY
-{
-	BOOLEAN SwTxQueueBlockFlag;
-	LIST_HEADER NetIfList;
-} BLOCK_QUEUE_ENTRY, *PBLOCK_QUEUE_ENTRY;
-#endif // BLOCK_NET_IF //
-
-
-struct wificonf
-{
-	BOOLEAN	bShortGI;
-	BOOLEAN bGreenField;
-};
-
-
-typedef struct _RTMP_DEV_INFO_
-{
-	UCHAR			chipName[16];
-	RTMP_INF_TYPE	infType;
-}RTMP_DEV_INFO;
-
-
-#ifdef DBG_DIAGNOSE
-#define DIAGNOSE_TIME	10   // 10 sec
-typedef struct _RtmpDiagStrcut_
-{	// Diagnosis Related element
-	unsigned char		inited;
-	unsigned char	qIdx;
-	unsigned char	ArrayStartIdx;
-	unsigned char		ArrayCurIdx;
-	// Tx Related Count
-	USHORT			TxDataCnt[DIAGNOSE_TIME];
-	USHORT			TxFailCnt[DIAGNOSE_TIME];
-//	USHORT			TxDescCnt[DIAGNOSE_TIME][16];		// TxDesc queue length in scale of 0~14, >=15
-	USHORT			TxDescCnt[DIAGNOSE_TIME][24]; // 3*3	// TxDesc queue length in scale of 0~14, >=15
-//	USHORT			TxMcsCnt[DIAGNOSE_TIME][16];			// TxDate MCS Count in range from 0 to 15, step in 1.
-	USHORT			TxMcsCnt[DIAGNOSE_TIME][24]; // 3*3
-	USHORT			TxSWQueCnt[DIAGNOSE_TIME][9];		// TxSwQueue length in scale of 0, 1, 2, 3, 4, 5, 6, 7, >=8
-
-	USHORT			TxAggCnt[DIAGNOSE_TIME];
-	USHORT			TxNonAggCnt[DIAGNOSE_TIME];
-//	USHORT			TxAMPDUCnt[DIAGNOSE_TIME][16];		// 10 sec, TxDMA APMDU Aggregation count in range from 0 to 15, in setp of 1.
-	USHORT			TxAMPDUCnt[DIAGNOSE_TIME][24]; // 3*3 // 10 sec, TxDMA APMDU Aggregation count in range from 0 to 15, in setp of 1.
-	USHORT			TxRalinkCnt[DIAGNOSE_TIME];			// TxRalink Aggregation Count in 1 sec scale.
-	USHORT			TxAMSDUCnt[DIAGNOSE_TIME];			// TxAMSUD Aggregation Count in 1 sec scale.
-
-	// Rx Related Count
-	USHORT			RxDataCnt[DIAGNOSE_TIME];			// Rx Total Data count.
-	USHORT			RxCrcErrCnt[DIAGNOSE_TIME];
-//	USHORT			RxMcsCnt[DIAGNOSE_TIME][16];		// Rx MCS Count in range from 0 to 15, step in 1.
-	USHORT			RxMcsCnt[DIAGNOSE_TIME][24]; // 3*3
-}RtmpDiagStruct;
-#endif // DBG_DIAGNOSE //
-
-
-struct _RTMP_CHIP_OP_
-{
-	/*  Calibration access related callback functions */
-	int (*eeinit)(RTMP_ADAPTER *pAd);										/* int (*eeinit)(RTMP_ADAPTER *pAd); */
-	int (*eeread)(RTMP_ADAPTER *pAd, USHORT offset, PUSHORT pValue);				/* int (*eeread)(RTMP_ADAPTER *pAd, int offset, PUSHORT pValue); */
-	int (*eewrite)(RTMP_ADAPTER *pAd, USHORT offset, USHORT value);;				/* int (*eewrite)(RTMP_ADAPTER *pAd, int offset, USHORT value); */
-
-	/* MCU related callback functions */
-	int (*loadFirmware)(RTMP_ADAPTER *pAd);								/* int (*loadFirmware)(RTMP_ADAPTER *pAd); */
-	int (*eraseFirmware)(RTMP_ADAPTER *pAd);								/* int (*eraseFirmware)(RTMP_ADAPTER *pAd); */
-	int (*sendCommandToMcu)(RTMP_ADAPTER *pAd, UCHAR cmd, UCHAR token, UCHAR arg0, UCHAR arg1);;	/* int (*sendCommandToMcu)(RTMP_ADAPTER *pAd, UCHAR cmd, UCHAR token, UCHAR arg0, UCHAR arg1); */
-
-	/* RF access related callback functions */
-	REG_PAIR *pRFRegTable;
-	void (*AsicRfInit)(RTMP_ADAPTER *pAd);
-	void (*AsicRfTurnOn)(RTMP_ADAPTER *pAd);
-	void (*AsicRfTurnOff)(RTMP_ADAPTER *pAd);
-	void (*AsicReverseRfFromSleepMode)(RTMP_ADAPTER *pAd);
-	void (*AsicHaltAction)(RTMP_ADAPTER *pAd);
-};
-
-
-//
-//  The miniport adapter structure
-//
-struct _RTMP_ADAPTER
-{
-	PVOID					OS_Cookie;	// save specific structure relative to OS
-	PNET_DEV				net_dev;
-	ULONG					VirtualIfCnt;
-
-	RTMP_CHIP_OP			chipOps;
-	USHORT					ThisTbttNumToNextWakeUp;
-
-#ifdef INF_AMAZON_PPA
-	UINT32  g_if_id;
-	BOOLEAN	PPAEnable;
-	PPA_DIRECTPATH_CB       *pDirectpathCb;
-#endif // INF_AMAZON_PPA //
-
-#ifdef RTMP_MAC_PCI
-/*****************************************************************************************/
-/*      PCI related parameters																  */
-/*****************************************************************************************/
-	PUCHAR                  CSRBaseAddress;     // PCI MMIO Base Address, all access will use
-	unsigned int			irq_num;
-
-	USHORT		            LnkCtrlBitMask;
-	USHORT		            RLnkCtrlConfiguration;
-	USHORT                  RLnkCtrlOffset;
-	USHORT		            HostLnkCtrlConfiguration;
-	USHORT                  HostLnkCtrlOffset;
-	USHORT		            PCIePowerSaveLevel;
-	ULONG				Rt3xxHostLinkCtrl;	// USed for 3090F chip
-	ULONG				Rt3xxRalinkLinkCtrl;	// USed for 3090F chip
-	USHORT				DeviceID;           // Read from PCI config
-	ULONG				AccessBBPFailCount;
-	BOOLEAN					bPCIclkOff;						// flag that indicate if the PICE power status in Configuration SPace..
-	BOOLEAN					bPCIclkOffDisableTx;			//
-
-	BOOLEAN					brt30xxBanMcuCmd;	//when = 0xff means all commands are ok to set .
-	BOOLEAN					b3090ESpecialChip;	//3090E special chip that write EEPROM 0x24=0x9280.
-	ULONG					CheckDmaBusyCount;  // Check Interrupt Status Register Count.
-
-	UINT					int_enable_reg;
-	UINT					int_disable_mask;
-	UINT					int_pending;
-
-
-	RTMP_DMABUF             TxBufSpace[NUM_OF_TX_RING]; // Shared memory of all 1st pre-allocated TxBuf associated with each TXD
-	RTMP_DMABUF             RxDescRing;                 // Shared memory for RX descriptors
-	RTMP_DMABUF             TxDescRing[NUM_OF_TX_RING];	// Shared memory for Tx descriptors
-	RTMP_TX_RING            TxRing[NUM_OF_TX_RING];		// AC0~4 + HCCA
-#endif // RTMP_MAC_PCI //
-
-
-	NDIS_SPIN_LOCK		irq_lock;
-	UCHAR				irq_disabled;
-
-
-/*****************************************************************************************/
-/*      RBUS related parameters																  */
-/*****************************************************************************************/
-
-
-/*****************************************************************************************/
-/*      Both PCI/USB related parameters														  */
-/*****************************************************************************************/
-	//RTMP_DEV_INFO			chipInfo;
-	RTMP_INF_TYPE			infType;
-
-/*****************************************************************************************/
-/*      Driver Mgmt related parameters														  */
-/*****************************************************************************************/
-	RTMP_OS_TASK			mlmeTask;
-#ifdef RTMP_TIMER_TASK_SUPPORT
-	// If you want use timer task to handle the timer related jobs, enable this.
-	RTMP_TIMER_TASK_QUEUE	TimerQ;
-	NDIS_SPIN_LOCK			TimerQLock;
-	RTMP_OS_TASK			timerTask;
-#endif // RTMP_TIMER_TASK_SUPPORT //
-
-
-/*****************************************************************************************/
-/*      Tx related parameters                                                           */
-/*****************************************************************************************/
-	BOOLEAN                 DeQueueRunning[NUM_OF_TX_RING];  // for ensuring RTUSBDeQueuePacket get call once
-	NDIS_SPIN_LOCK          DeQueueLock[NUM_OF_TX_RING];
-
-
-	// resource for software backlog queues
-	QUEUE_HEADER            TxSwQueue[NUM_OF_TX_RING];  // 4 AC + 1 HCCA
-	NDIS_SPIN_LOCK          TxSwQueueLock[NUM_OF_TX_RING];	// TxSwQueue spinlock
-
-	RTMP_DMABUF             MgmtDescRing;			// Shared memory for MGMT descriptors
-	RTMP_MGMT_RING          MgmtRing;
-	NDIS_SPIN_LOCK          MgmtRingLock;			// Prio Ring spinlock
-
-
-/*****************************************************************************************/
-/*      Rx related parameters                                                           */
-/*****************************************************************************************/
-
-#ifdef RTMP_MAC_PCI
-	RTMP_RX_RING            RxRing;
-	NDIS_SPIN_LOCK          RxRingLock;                 // Rx Ring spinlock
-#ifdef RT3090
-	NDIS_SPIN_LOCK          McuCmdLock;              //MCU Command Queue spinlock
-#endif // RT3090 //
-#endif // RTMP_MAC_PCI //
-
-
-
-/*****************************************************************************************/
-/*      ASIC related parameters                                                          */
-/*****************************************************************************************/
-	UINT32			MACVersion;		// MAC version. Record rt2860C(0x28600100) or rt2860D (0x28600101)..
-
-	// ---------------------------
-	// E2PROM
-	// ---------------------------
-	ULONG				EepromVersion;          // byte 0: version, byte 1: revision, byte 2~3: unused
-	ULONG				FirmwareVersion;        // byte 0: Minor version, byte 1: Major version, otherwise unused.
-	USHORT				EEPROMDefaultValue[NUM_EEPROM_BBP_PARMS];
-	UCHAR				EEPROMAddressNum;       // 93c46=6  93c66=8
-	BOOLEAN				EepromAccess;
-	UCHAR				EFuseTag;
-
-
-	// ---------------------------
-	// BBP Control
-	// ---------------------------
-#ifdef MERGE_ARCH_TEAM
-	UCHAR                   BbpWriteLatch[256];     // record last BBP register value written via BBP_IO_WRITE/BBP_IO_WRITE_VY_REG_ID
-#else
-	UCHAR                   BbpWriteLatch[140];     // record last BBP register value written via BBP_IO_WRITE/BBP_IO_WRITE_VY_REG_ID
-#endif // MERGE_ARCH_TEAM //
-	CHAR					BbpRssiToDbmDelta;		// change from UCHAR to CHAR for high power
-	BBP_R66_TUNING          BbpTuning;
-
-	// ----------------------------
-	// RFIC control
-	// ----------------------------
-	UCHAR                   RfIcType;       // RFIC_xxx
-	ULONG                   RfFreqOffset;   // Frequency offset for channel switching
-	RTMP_RF_REGS            LatchRfRegs;    // latch th latest RF programming value since RF IC doesn't support READ
-
-	EEPROM_ANTENNA_STRUC    Antenna;                            // Since ANtenna definition is different for a & g. We need to save it for future reference.
-	EEPROM_NIC_CONFIG2_STRUC    NicConfig2;
-
-	// This soft Rx Antenna Diversity mechanism is used only when user set
-	// RX Antenna = DIVERSITY ON
-	SOFT_RX_ANT_DIVERSITY   RxAnt;
-
-	UCHAR                   RFProgSeq;
-	CHANNEL_TX_POWER        TxPower[MAX_NUM_OF_CHANNELS];       // Store Tx power value for all channels.
-	CHANNEL_TX_POWER        ChannelList[MAX_NUM_OF_CHANNELS];   // list all supported channels for site survey
-	CHANNEL_11J_TX_POWER    TxPower11J[MAX_NUM_OF_11JCHANNELS];       // 802.11j channel and bw
-	CHANNEL_11J_TX_POWER    ChannelList11J[MAX_NUM_OF_11JCHANNELS];   // list all supported channels for site survey
-
-	UCHAR                   ChannelListNum;                     // number of channel in ChannelList[]
-	UCHAR					Bbp94;
-	BOOLEAN					BbpForCCK;
-	ULONG		Tx20MPwrCfgABand[5];
-	ULONG		Tx20MPwrCfgGBand[5];
-	ULONG		Tx40MPwrCfgABand[5];
-	ULONG		Tx40MPwrCfgGBand[5];
-
-	BOOLEAN     bAutoTxAgcA;                // Enable driver auto Tx Agc control
-	UCHAR	    TssiRefA;					// Store Tssi reference value as 25 temperature.
-	UCHAR	    TssiPlusBoundaryA[5];		// Tssi boundary for increase Tx power to compensate.
-	UCHAR	    TssiMinusBoundaryA[5];		// Tssi boundary for decrease Tx power to compensate.
-	UCHAR	    TxAgcStepA;					// Store Tx TSSI delta increment / decrement value
-	CHAR		TxAgcCompensateA;			// Store the compensation (TxAgcStep * (idx-1))
-
-	BOOLEAN     bAutoTxAgcG;                // Enable driver auto Tx Agc control
-	UCHAR	    TssiRefG;					// Store Tssi reference value as 25 temperature.
-	UCHAR	    TssiPlusBoundaryG[5];		// Tssi boundary for increase Tx power to compensate.
-	UCHAR	    TssiMinusBoundaryG[5];		// Tssi boundary for decrease Tx power to compensate.
-	UCHAR	    TxAgcStepG;					// Store Tx TSSI delta increment / decrement value
-	CHAR		TxAgcCompensateG;			// Store the compensation (TxAgcStep * (idx-1))
-
-	CHAR		BGRssiOffset0;				// Store B/G RSSI#0 Offset value on EEPROM 0x46h
-	CHAR		BGRssiOffset1;				// Store B/G RSSI#1 Offset value
-	CHAR		BGRssiOffset2;				// Store B/G RSSI#2 Offset value
-
-	CHAR		ARssiOffset0;				// Store A RSSI#0 Offset value on EEPROM 0x4Ah
-	CHAR		ARssiOffset1;				// Store A RSSI#1 Offset value
-	CHAR		ARssiOffset2;				// Store A RSSI#2 Offset value
-
-	CHAR		BLNAGain;					// Store B/G external LNA#0 value on EEPROM 0x44h
-	CHAR		ALNAGain0;					// Store A external LNA#0 value for ch36~64
-	CHAR		ALNAGain1;					// Store A external LNA#1 value for ch100~128
-	CHAR		ALNAGain2;					// Store A external LNA#2 value for ch132~165
-#ifdef RT30xx
-	// for 3572
-	UCHAR		Bbp25;
-	UCHAR		Bbp26;
-
-	UCHAR		TxMixerGain24G;				// Tx mixer gain value from EEPROM to improve Tx EVM / Tx DAC, 2.4G
-	UCHAR		TxMixerGain5G;
-#endif // RT30xx //
-	// ----------------------------
-	// LED control
-	// ----------------------------
-	MCU_LEDCS_STRUC		LedCntl;
-	USHORT				Led1;	// read from EEPROM 0x3c
-	USHORT				Led2;	// EEPROM 0x3e
-	USHORT				Led3;	// EEPROM 0x40
-	UCHAR				LedIndicatorStrength;
-	UCHAR				RssiSingalstrengthOffet;
-	BOOLEAN				bLedOnScanning;
-	UCHAR				LedStatus;
-
-/*****************************************************************************************/
-/*      802.11 related parameters                                                        */
-/*****************************************************************************************/
-	// outgoing BEACON frame buffer and corresponding TXD
-	TXWI_STRUC			BeaconTxWI;
-	PUCHAR						BeaconBuf;
-	USHORT						BeaconOffset[HW_BEACON_MAX_COUNT];
-
-	// pre-build PS-POLL and NULL frame upon link up. for efficiency purpose.
-	PSPOLL_FRAME			PsPollFrame;
-	HEADER_802_11			NullFrame;
-
-
-
-
-//=========AP===========
-
-
-//=======STA===========
-#ifdef CONFIG_STA_SUPPORT
-	// -----------------------------------------------
-	// STA specific configuration & operation status
-	// used only when pAd->OpMode == OPMODE_STA
-	// -----------------------------------------------
-	STA_ADMIN_CONFIG        StaCfg;		// user desired settings
-	STA_ACTIVE_CONFIG       StaActive;		// valid only when ADHOC_ON(pAd) || INFRA_ON(pAd)
-	CHAR                    nickname[IW_ESSID_MAX_SIZE+1]; // nickname, only used in the iwconfig i/f
-	NDIS_MEDIA_STATE        PreMediaState;
-#endif // CONFIG_STA_SUPPORT //
-
-//=======Common===========
-	// OP mode: either AP or STA
-	UCHAR                   OpMode;                     // OPMODE_STA, OPMODE_AP
-
-	NDIS_MEDIA_STATE        IndicateMediaState;			// Base on Indication state, default is NdisMediaStateDisConnected
-
-
-	/* MAT related parameters */
-
-	// configuration: read from Registry & E2PROM
-	BOOLEAN                 bLocalAdminMAC;             // Use user changed MAC
-	UCHAR                   PermanentAddress[MAC_ADDR_LEN];    // Factory default MAC address
-	UCHAR                   CurrentAddress[MAC_ADDR_LEN];      // User changed MAC address
-
-	// ------------------------------------------------------
-	// common configuration to both OPMODE_STA and OPMODE_AP
-	// ------------------------------------------------------
-	COMMON_CONFIG           CommonCfg;
-	MLME_STRUCT             Mlme;
-
-	// AP needs those vaiables for site survey feature.
-	MLME_AUX                MlmeAux;           // temporary settings used during MLME state machine
-	BSS_TABLE               ScanTab;           // store the latest SCAN result
-
-	//About MacTab, the sta driver will use #0 and #1 for multicast and AP.
-	MAC_TABLE                 MacTab;     // ASIC on-chip WCID entry table.  At TX, ASIC always use key according to this on-chip table.
-	NDIS_SPIN_LOCK          MacTabLock;
-
-#ifdef DOT11_N_SUPPORT
-	BA_TABLE			BATable;
-	NDIS_SPIN_LOCK          BATabLock;
-	RALINK_TIMER_STRUCT RECBATimer;
-#endif // DOT11_N_SUPPORT //
-
-	// encryption/decryption KEY tables
-	CIPHER_KEY              SharedKey[MAX_MBSSID_NUM][4]; // STA always use SharedKey[BSS0][0..3]
-
-	// RX re-assembly buffer for fragmentation
-	FRAGMENT_FRAME          FragFrame;                  // Frame storage for fragment frame
-
-	// various Counters
-	COUNTER_802_3           Counters8023;               // 802.3 counters
-	COUNTER_802_11          WlanCounters;               // 802.11 MIB counters
-	COUNTER_RALINK          RalinkCounters;             // Ralink propriety counters
-	COUNTER_DRS             DrsCounters;                // counters for Dynamic TX Rate Switching
-	PRIVATE_STRUC           PrivateInfo;                // Private information & counters
-
-	// flags, see fRTMP_ADAPTER_xxx flags
-	ULONG                   Flags;                      // Represent current device status
-	ULONG                   PSFlags;                    // Power Save operation flag.
-
-	// current TX sequence #
-	USHORT                  Sequence;
-
-	// Control disconnect / connect event generation
-	//+++Didn't used anymore
-	ULONG                   LinkDownTime;
-	//---
-	ULONG                   LastRxRate;
-	ULONG                   LastTxRate;
-	//+++Used only for Station
-	BOOLEAN                 bConfigChanged;         // Config Change flag for the same SSID setting
-	//---
-
-	ULONG                   ExtraInfo;              // Extra information for displaying status
-	ULONG                   SystemErrorBitmap;      // b0: E2PROM version error
-
-	//+++Didn't used anymore
-	ULONG                   MacIcVersion;           // MAC/BBP serial interface issue solved after ver.D
-	//---
-
-	// ---------------------------
-	// System event log
-	// ---------------------------
-	RT_802_11_EVENT_TABLE   EventTab;
-
-
-	BOOLEAN		HTCEnable;
-
-	/*****************************************************************************************/
-	/*      Statistic related parameters                                                     */
-	/*****************************************************************************************/
-
-	BOOLEAN						bUpdateBcnCntDone;
-	ULONG						watchDogMacDeadlock;	// prevent MAC/BBP into deadlock condition
-	// ----------------------------
-	// DEBUG paramerts
-	// ----------------------------
-	//ULONG		DebugSetting[4];
-	BOOLEAN		bBanAllBaSetup;
-	BOOLEAN		bPromiscuous;
-
-	// ----------------------------
-	// rt2860c emulation-use Parameters
-	// ----------------------------
-	//ULONG		rtsaccu[30];
-	//ULONG		ctsaccu[30];
-	//ULONG		cfendaccu[30];
-	//ULONG		bacontent[16];
-	//ULONG		rxint[RX_RING_SIZE+1];
-	//UCHAR		rcvba[60];
-	BOOLEAN		bLinkAdapt;
-	BOOLEAN		bForcePrintTX;
-	BOOLEAN		bForcePrintRX;
-	//BOOLEAN		bDisablescanning;		//defined in RT2870 USB
-	BOOLEAN		bStaFifoTest;
-	BOOLEAN		bProtectionTest;
-	/*
-	BOOLEAN		bHCCATest;
-	BOOLEAN		bGenOneHCCA;
-	*/
-	BOOLEAN		bBroadComHT;
-	//+++Following add from RT2870 USB.
-	ULONG		BulkOutReq;
-	ULONG		BulkOutComplete;
-	ULONG		BulkOutCompleteOther;
-	ULONG		BulkOutCompleteCancel;	// seems not use now?
-	ULONG		BulkInReq;
-	ULONG		BulkInComplete;
-	ULONG		BulkInCompleteFail;
-	//---
-
-    struct wificonf			WIFItestbed;
-
-#ifdef RALINK_ATE
-	ATE_INFO				ate;
-#endif // RALINK_ATE //
-
-#ifdef DOT11_N_SUPPORT
-	struct reordering_mpdu_pool mpdu_blk_pool;
-#endif // DOT11_N_SUPPORT //
-
-	ULONG					OneSecondnonBEpackets;		// record non BE packets per second
-
-#ifdef LINUX
-#if WIRELESS_EXT >= 12
-    struct iw_statistics    iw_stats;
-#endif
-
-	struct net_device_stats	stats;
-#endif // LINUX //
-
-#ifdef BLOCK_NET_IF
-	BLOCK_QUEUE_ENTRY		blockQueueTab[NUM_OF_TX_RING];
-#endif // BLOCK_NET_IF //
-
-
-
-#ifdef MULTIPLE_CARD_SUPPORT
-	INT32					MC_RowID;
-	STRING					MC_FileName[256];
-#endif // MULTIPLE_CARD_SUPPORT //
-
-	ULONG					TbttTickCount;
-#ifdef PCI_MSI_SUPPORT
-	BOOLEAN					HaveMsi;
-#endif // PCI_MSI_SUPPORT //
-
-
-	UCHAR					is_on;
-
-#define TIME_BASE			(1000000/OS_HZ)
-#define TIME_ONE_SECOND		(1000000/TIME_BASE)
-	UCHAR					flg_be_adjust;
-	ULONG					be_adjust_last_time;
-
-#ifdef NINTENDO_AP
-	NINDO_CTRL_BLOCK		nindo_ctrl_block;
-#endif // NINTENDO_AP //
-
-
-#ifdef IKANOS_VX_1X0
-	struct IKANOS_TX_INFO	IkanosTxInfo;
-	struct IKANOS_TX_INFO	IkanosRxInfo[MAX_MBSSID_NUM + MAX_WDS_ENTRY + MAX_APCLI_NUM + MAX_MESH_NUM];
-#endif // IKANOS_VX_1X0 //
-
-
-#ifdef DBG_DIAGNOSE
-	RtmpDiagStruct	DiagStruct;
-#endif // DBG_DIAGNOSE //
-
-
-	UINT8					FlgCtsEnabled;
-	UINT8					PM_FlgSuspend;
-
-#ifdef RT30xx
-#ifdef RTMP_EFUSE_SUPPORT
-	BOOLEAN		bUseEfuse;
-	BOOLEAN		bEEPROMFile;
-	BOOLEAN		bFroceEEPROMBuffer;
-	UCHAR		EEPROMImage[1024];
-#endif // RTMP_EFUSE_SUPPORT //
-#endif // RT30xx //
-
-#ifdef CONFIG_STA_SUPPORT
-#endif // CONFIG_STA_SUPPORT //
-
-};
-
-
-
-#ifdef TONE_RADAR_DETECT_SUPPORT
-#define DELAYINTMASK		0x0013fffb
-#define INTMASK				0x0013fffb
-#define IndMask				0x0013fffc
-#define RadarInt			0x00100000
-#else
-#define DELAYINTMASK		0x0003fffb
-#define INTMASK				0x0003fffb
-#define IndMask				0x0003fffc
-#endif // TONE_RADAR_DETECT_SUPPORT //
-
-#define RxINT				0x00000005	// Delayed Rx or indivi rx
-#define TxDataInt			0x000000fa	// Delayed Tx or indivi tx
-#define TxMgmtInt			0x00000102	// Delayed Tx or indivi tx
-#define TxCoherent			0x00020000	// tx coherent
-#define RxCoherent			0x00010000	// rx coherent
-#define McuCommand			0x00000200	// mcu
-#define PreTBTTInt			0x00001000	// Pre-TBTT interrupt
-#define TBTTInt				0x00000800		// TBTT interrupt
-#define GPTimeOutInt			0x00008000		// GPtimeout interrupt
-#define AutoWakeupInt		0x00004000		// AutoWakeupInt interrupt
-#define FifoStaFullInt			0x00002000	//  fifo statistics full interrupt
-
-
-/***************************************************************************
-  *	Rx Path software control block related data structures
-  **************************************************************************/
-typedef struct _RX_BLK_
-{
-//	RXD_STRUC		RxD; // sample
-	RT28XX_RXD_STRUC	RxD;
-	PRXWI_STRUC			pRxWI;
-	PHEADER_802_11		pHeader;
-	PNDIS_PACKET		pRxPacket;
-	UCHAR				*pData;
-	USHORT				DataSize;
-	USHORT				Flags;
-	UCHAR				UserPriority;	// for calculate TKIP MIC using
-} RX_BLK;
-
-
-#define RX_BLK_SET_FLAG(_pRxBlk, _flag)		(_pRxBlk->Flags |= _flag)
-#define RX_BLK_TEST_FLAG(_pRxBlk, _flag)	(_pRxBlk->Flags & _flag)
-#define RX_BLK_CLEAR_FLAG(_pRxBlk, _flag)	(_pRxBlk->Flags &= ~(_flag))
-
-
-#define fRX_WDS			0x0001
-#define fRX_AMSDU		0x0002
-#define fRX_ARALINK		0x0004
-#define fRX_HTC			0x0008
-#define fRX_PAD			0x0010
-#define fRX_AMPDU		0x0020
-#define fRX_QOS			0x0040
-#define fRX_INFRA		0x0080
-#define fRX_EAP			0x0100
-#define fRX_MESH		0x0200
-#define fRX_APCLI		0x0400
-#define fRX_DLS			0x0800
-#define fRX_WPI			0x1000
-
-#define LENGTH_AMSDU_SUBFRAMEHEAD	14
-#define LENGTH_ARALINK_SUBFRAMEHEAD	14
-#define LENGTH_ARALINK_HEADER_FIELD	 2
-
-
-/***************************************************************************
-  *	Tx Path software control block related data structures
-  **************************************************************************/
-#define TX_UNKOWN_FRAME		0x00
-#define TX_MCAST_FRAME			0x01
-#define TX_LEGACY_FRAME		0x02
-#define TX_AMPDU_FRAME		0x04
-#define TX_AMSDU_FRAME		0x08
-#define TX_RALINK_FRAME		0x10
-#define TX_FRAG_FRAME			0x20
-
-
-//	Currently the sizeof(TX_BLK) is 148 bytes.
-typedef struct _TX_BLK_
-{
-	UCHAR				QueIdx;
-	UCHAR				TxFrameType;				// Indicate the Transmission type of the all frames in one batch
-	UCHAR				TotalFrameNum;				// Total frame number want to send-out in one batch
-	USHORT				TotalFragNum;				// Total frame fragments required in one batch
-	USHORT				TotalFrameLen;				// Total length of all frames want to send-out in one batch
-
-	QUEUE_HEADER		TxPacketList;
-	MAC_TABLE_ENTRY		*pMacEntry;					// NULL: packet with 802.11 RA field is multicast/broadcast address
-	HTTRANSMIT_SETTING	*pTransmit;
-
-	// Following structure used for the characteristics of a specific packet.
-	PNDIS_PACKET		pPacket;
-	PUCHAR				pSrcBufHeader;				// Reference to the head of sk_buff->data
-	PUCHAR				pSrcBufData;				// Reference to the sk_buff->data, will changed depends on hanlding progresss
-	UINT				SrcBufLen;					// Length of packet payload which not including Layer 2 header
-	PUCHAR				pExtraLlcSnapEncap;			// NULL means no extra LLC/SNAP is required
-	UCHAR				HeaderBuf[96];				// TempBuffer for TX_INFO + TX_WI + 802.11 Header + padding + AMSDU SubHeader + LLC/SNAP
-	UCHAR				MpduHeaderLen;				// 802.11 header length NOT including the padding
-	UCHAR				HdrPadLen;					// recording Header Padding Length;
-	UCHAR				apidx;						// The interface associated to this packet
-	UCHAR				Wcid;						// The MAC entry associated to this packet
-	UCHAR				UserPriority;				// priority class of packet
-	UCHAR				FrameGap;					// what kind of IFS this packet use
-	UCHAR				MpduReqNum;					// number of fragments of this frame
-	UCHAR				TxRate;						// TODO: Obsoleted? Should change to MCS?
-	UCHAR				CipherAlg;					// cipher alogrithm
-	PCIPHER_KEY			pKey;
-
-
-
-	USHORT				Flags;						//See following definitions for detail.
-
-	//YOU SHOULD NOT TOUCH IT! Following parameters are used for hardware-depended layer.
-	ULONG				Priv;						// Hardware specific value saved in here.
-
-} TX_BLK, *PTX_BLK;
-
-
-#define fTX_bRtsRequired			0x0001	// Indicate if need send RTS frame for protection. Not used in RT2860/RT2870.
-#define fTX_bAckRequired			0x0002	// the packet need ack response
-#define fTX_bPiggyBack			0x0004	// Legacy device use Piggback or not
-#define fTX_bHTRate				0x0008	// allow to use HT rate
-#define fTX_bForceNonQoS		0x0010	// force to transmit frame without WMM-QoS in HT mode
-#define fTX_bAllowFrag			0x0020	// allow to fragment the packet, A-MPDU, A-MSDU, A-Ralink is not allowed to fragment
-#define fTX_bMoreData			0x0040	// there are more data packets in PowerSave Queue
-#define fTX_bWMM				0x0080	// QOS Data
-#define fTX_bClearEAPFrame		0x0100
-
-
-
-#ifdef CONFIG_STA_SUPPORT
-#endif // CONFIG_STA_SUPPORT //
-
-
-
-
-#define TX_BLK_SET_FLAG(_pTxBlk, _flag)		(_pTxBlk->Flags |= _flag)
-#define TX_BLK_TEST_FLAG(_pTxBlk, _flag)	(((_pTxBlk->Flags & _flag) == _flag) ? 1 : 0)
-#define TX_BLK_CLEAR_FLAG(_pTxBlk, _flag)	(_pTxBlk->Flags &= ~(_flag))
-
-
-
-
-#ifdef RT_BIG_ENDIAN
-/***************************************************************************
-  *	Endian conversion related functions
-  **************************************************************************/
-/*
-	========================================================================
-
-	Routine Description:
-		Endian conversion of Tx/Rx descriptor .
-
-	Arguments:
-		pAd	Pointer to our adapter
-		pData			Pointer to Tx/Rx descriptor
-		DescriptorType	Direction of the frame
-
-	Return Value:
-		None
-
-	Note:
-		Call this function when read or update descriptor
-	========================================================================
-*/
-static inline VOID	RTMPWIEndianChange(
-	IN	PUCHAR			pData,
-	IN	ULONG			DescriptorType)
-{
-	int size;
-	int i;
-
-	size = ((DescriptorType == TYPE_TXWI) ? TXWI_SIZE : RXWI_SIZE);
-
-	if(DescriptorType == TYPE_TXWI)
-	{
-		*((UINT32 *)(pData)) = SWAP32(*((UINT32 *)(pData)));		// Byte 0~3
-		*((UINT32 *)(pData + 4)) = SWAP32(*((UINT32 *)(pData+4)));	// Byte 4~7
-	}
-	else
-	{
-		for(i=0; i < size/4 ; i++)
-			*(((UINT32 *)pData) +i) = SWAP32(*(((UINT32 *)pData)+i));
-	}
-}
-
-
-#ifdef RTMP_MAC_PCI
-static inline VOID	WriteBackToDescriptor(
-	IN  PUCHAR			Dest,
-	IN	PUCHAR			Src,
-    IN  BOOLEAN			DoEncrypt,
-	IN  ULONG           DescriptorType)
-{
-	UINT32 *p1, *p2;
-
-	p1 = ((UINT32 *)Dest);
-	p2 = ((UINT32 *)Src);
-
-	*p1 = *p2;
-	*(p1+2) = *(p2+2);
-	*(p1+3) = *(p2+3);
-	*(p1+1) = *(p2+1); // Word 1; this must be written back last
-}
-#endif // RTMP_MAC_PCI //
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Endian conversion of Tx/Rx descriptor .
-
-	Arguments:
-		pAd	Pointer to our adapter
-		pData			Pointer to Tx/Rx descriptor
-		DescriptorType	Direction of the frame
-
-	Return Value:
-		None
-
-	Note:
-		Call this function when read or update descriptor
-	========================================================================
-*/
-#ifdef RTMP_MAC_PCI
-static inline VOID	RTMPDescriptorEndianChange(
-	IN	PUCHAR			pData,
-	IN	ULONG			DescriptorType)
-{
-	*((UINT32 *)(pData)) = SWAP32(*((UINT32 *)(pData)));		// Byte 0~3
-	*((UINT32 *)(pData + 8)) = SWAP32(*((UINT32 *)(pData+8)));	// Byte 8~11
-	*((UINT32 *)(pData +12)) = SWAP32(*((UINT32 *)(pData + 12)));	// Byte 12~15
-	*((UINT32 *)(pData + 4)) = SWAP32(*((UINT32 *)(pData + 4)));				// Byte 4~7, this must be swapped last
-}
-#endif // RTMP_MAC_PCI //
-
-/*
-	========================================================================
-
-	Routine Description:
-		Endian conversion of all kinds of 802.11 frames .
-
-	Arguments:
-		pAd	Pointer to our adapter
-		pData			Pointer to the 802.11 frame structure
-		Dir			Direction of the frame
-		FromRxDoneInt	Caller is from RxDone interrupt
-
-	Return Value:
-		None
-
-	Note:
-		Call this function when read or update buffer data
-	========================================================================
-*/
-static inline VOID	RTMPFrameEndianChange(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pData,
-	IN	ULONG			Dir,
-	IN	BOOLEAN			FromRxDoneInt)
-{
-	PHEADER_802_11 pFrame;
-	PUCHAR	pMacHdr;
-
-	// swab 16 bit fields - Frame Control field
-	if(Dir == DIR_READ)
-	{
-		*(USHORT *)pData = SWAP16(*(USHORT *)pData);
-	}
-
-	pFrame = (PHEADER_802_11) pData;
-	pMacHdr = (PUCHAR) pFrame;
-
-	// swab 16 bit fields - Duration/ID field
-	*(USHORT *)(pMacHdr + 2) = SWAP16(*(USHORT *)(pMacHdr + 2));
-
-	// swab 16 bit fields - Sequence Control field
-	*(USHORT *)(pMacHdr + 22) = SWAP16(*(USHORT *)(pMacHdr + 22));
-
-	if(pFrame->FC.Type == BTYPE_MGMT)
-	{
-		switch(pFrame->FC.SubType)
-		{
-			case SUBTYPE_ASSOC_REQ:
-			case SUBTYPE_REASSOC_REQ:
-				// swab 16 bit fields - CapabilityInfo field
-				pMacHdr += sizeof(HEADER_802_11);
-				*(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
-
-				// swab 16 bit fields - Listen Interval field
-				pMacHdr += 2;
-				*(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
-				break;
-
-			case SUBTYPE_ASSOC_RSP:
-			case SUBTYPE_REASSOC_RSP:
-				// swab 16 bit fields - CapabilityInfo field
-				pMacHdr += sizeof(HEADER_802_11);
-				*(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
-
-				// swab 16 bit fields - Status Code field
-				pMacHdr += 2;
-				*(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
-
-				// swab 16 bit fields - AID field
-				pMacHdr += 2;
-				*(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
-				break;
-
-			case SUBTYPE_AUTH:
-				// If from APHandleRxDoneInterrupt routine, it is still a encrypt format.
-				// The convertion is delayed to RTMPHandleDecryptionDoneInterrupt.
-				if(!FromRxDoneInt && pFrame->FC.Wep == 1)
-					break;
-				else
-				{
-					// swab 16 bit fields - Auth Alg No. field
-					pMacHdr += sizeof(HEADER_802_11);
-					*(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
-
-					// swab 16 bit fields - Auth Seq No. field
-					pMacHdr += 2;
-					*(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
-
-					// swab 16 bit fields - Status Code field
-					pMacHdr += 2;
-					*(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
-				}
-				break;
-
-			case SUBTYPE_BEACON:
-			case SUBTYPE_PROBE_RSP:
-				// swab 16 bit fields - BeaconInterval field
-				pMacHdr += (sizeof(HEADER_802_11) + TIMESTAMP_LEN);
-				*(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
-
-				// swab 16 bit fields - CapabilityInfo field
-				pMacHdr += sizeof(USHORT);
-				*(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
-				break;
-
-			case SUBTYPE_DEAUTH:
-			case SUBTYPE_DISASSOC:
-				// swab 16 bit fields - Reason code field
-				pMacHdr += sizeof(HEADER_802_11);
-				*(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
-				break;
-		}
-	}
-	else if( pFrame->FC.Type == BTYPE_DATA )
-	{
-	}
-	else if(pFrame->FC.Type == BTYPE_CNTL)
-	{
-		switch(pFrame->FC.SubType)
-		{
-			case SUBTYPE_BLOCK_ACK_REQ:
-				{
-					PFRAME_BA_REQ pBAReq = (PFRAME_BA_REQ)pFrame;
-					*(USHORT *)(&pBAReq->BARControl) = SWAP16(*(USHORT *)(&pBAReq->BARControl));
-					pBAReq->BAStartingSeq.word = SWAP16(pBAReq->BAStartingSeq.word);
-				}
-				break;
-			case SUBTYPE_BLOCK_ACK:
-				// For Block Ack packet, the HT_CONTROL field is in the same offset with Addr3
-				*(UINT32 *)(&pFrame->Addr3[0]) = SWAP32(*(UINT32 *)(&pFrame->Addr3[0]));
-				break;
-
-			case SUBTYPE_ACK:
-				//For ACK packet, the HT_CONTROL field is in the same offset with Addr2
-				*(UINT32 *)(&pFrame->Addr2[0])=	SWAP32(*(UINT32 *)(&pFrame->Addr2[0]));
-				break;
-		}
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("Invalid Frame Type!!!\n"));
-	}
-
-	// swab 16 bit fields - Frame Control
-	if(Dir == DIR_WRITE)
-	{
-		*(USHORT *)pData = SWAP16(*(USHORT *)pData);
-	}
-}
-#endif // RT_BIG_ENDIAN //
-
-
-/***************************************************************************
-  *	Other static inline function definitions
-  **************************************************************************/
-static inline VOID ConvertMulticastIP2MAC(
-	IN PUCHAR pIpAddr,
-	IN PUCHAR *ppMacAddr,
-	IN UINT16 ProtoType)
-{
-	if (pIpAddr == NULL)
-		return;
-
-	if (ppMacAddr == NULL || *ppMacAddr == NULL)
-		return;
-
-	switch (ProtoType)
-	{
-		case ETH_P_IPV6:
-//			memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS);
-			*(*ppMacAddr) = 0x33;
-			*(*ppMacAddr + 1) = 0x33;
-			*(*ppMacAddr + 2) = pIpAddr[12];
-			*(*ppMacAddr + 3) = pIpAddr[13];
-			*(*ppMacAddr + 4) = pIpAddr[14];
-			*(*ppMacAddr + 5) = pIpAddr[15];
-			break;
-
-		case ETH_P_IP:
-		default:
-//			memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS);
-			*(*ppMacAddr) = 0x01;
-			*(*ppMacAddr + 1) = 0x00;
-			*(*ppMacAddr + 2) = 0x5e;
-			*(*ppMacAddr + 3) = pIpAddr[1] & 0x7f;
-			*(*ppMacAddr + 4) = pIpAddr[2];
-			*(*ppMacAddr + 5) = pIpAddr[3];
-			break;
-	}
-
-	return;
-}
-
-
-char *GetPhyMode(int Mode);
-char* GetBW(int BW);
-
-
-
-BOOLEAN RTMPCheckForHang(
-	IN  NDIS_HANDLE MiniportAdapterContext);
-
-VOID  RTMPHalt(
-	IN  NDIS_HANDLE MiniportAdapterContext);
-
-//
-//  Private routines in rtmp_init.c
-//
-NDIS_STATUS RTMPAllocAdapterBlock(
-	IN PVOID			handle,
-	OUT PRTMP_ADAPTER   *ppAdapter);
-
-NDIS_STATUS RTMPAllocTxRxRingMemory(
-	IN  PRTMP_ADAPTER   pAd);
-
-NDIS_STATUS RTMPFindAdapter(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  NDIS_HANDLE     WrapperConfigurationContext);
-
-NDIS_STATUS	RTMPReadParametersHook(
-	IN	PRTMP_ADAPTER pAd);
-
-NDIS_STATUS	RTMPSetProfileParameters(
-	IN RTMP_ADAPTER *pAd,
-	IN PSTRING		pBuffer);
-
-INT RTMPGetKeyParameter(
-    IN PSTRING key,
-    OUT PSTRING dest,
-    IN INT destsize,
-    IN PSTRING buffer,
-    IN BOOLEAN bTrimSpace);
-
-VOID RTMPFreeAdapter(
-	IN  PRTMP_ADAPTER   pAd);
-
-NDIS_STATUS NICReadRegParameters(
-	IN  PRTMP_ADAPTER       pAd,
-	IN  NDIS_HANDLE         WrapperConfigurationContext);
-
-#ifdef RTMP_RF_RW_SUPPORT
-VOID NICInitRFRegisters(
-	IN PRTMP_ADAPTER pAd);
-
-VOID RtmpChipOpsRFHook(
-	IN RTMP_ADAPTER *pAd);
-
-NDIS_STATUS	RT30xxWriteRFRegister(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			regID,
-	IN	UCHAR			value);
-
-NDIS_STATUS	RT30xxReadRFRegister(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			regID,
-	IN	PUCHAR			pValue);
-#endif // RTMP_RF_RW_SUPPORT //
-
-VOID NICReadEEPROMParameters(
-	IN  PRTMP_ADAPTER       pAd,
-	IN	PUCHAR				mac_addr);
-
-VOID NICInitAsicFromEEPROM(
-	IN  PRTMP_ADAPTER       pAd);
-
-
-NDIS_STATUS NICInitializeAdapter(
-	IN  PRTMP_ADAPTER   pAd,
-	IN   BOOLEAN    bHardReset);
-
-NDIS_STATUS NICInitializeAsic(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  BOOLEAN		bHardReset);
-
-VOID NICIssueReset(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID RTMPRingCleanUp(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR           RingType);
-
-VOID RxTest(
-	IN  PRTMP_ADAPTER   pAd);
-
-NDIS_STATUS DbgSendPacket(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PNDIS_PACKET    pPacket);
-
-VOID UserCfgInit(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID NICResetFromError(
-	IN  PRTMP_ADAPTER   pAd);
-
-NDIS_STATUS NICLoadFirmware(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID NICEraseFirmware(
-	IN PRTMP_ADAPTER pAd);
-
-NDIS_STATUS NICLoadRateSwitchingParams(
-	IN PRTMP_ADAPTER pAd);
-
-BOOLEAN NICCheckForHang(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID NICUpdateFifoStaCounters(
-	IN PRTMP_ADAPTER pAd);
-
-VOID NICUpdateRawCounters(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID RTMPZeroMemory(
-	IN  PVOID   pSrc,
-	IN  ULONG   Length);
-
-ULONG RTMPCompareMemory(
-	IN  PVOID   pSrc1,
-	IN  PVOID   pSrc2,
-	IN  ULONG   Length);
-
-VOID RTMPMoveMemory(
-	OUT PVOID   pDest,
-	IN  PVOID   pSrc,
-	IN  ULONG   Length);
-
-VOID AtoH(
-	PSTRING	src,
-	PUCHAR dest,
-	int		destlen);
-
-UCHAR BtoH(
-	char ch);
-
-VOID RTMPPatchMacBbpBug(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID RTMPPatchCardBus(
-	IN	PRTMP_ADAPTER	pAdapter);
-
-VOID RTMPPatchRalinkCardBus(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	ULONG			Bus);
-
-ULONG RTMPReadCBConfig(
-	IN	ULONG	Bus,
-	IN	ULONG	Slot,
-	IN	ULONG	Func,
-	IN	ULONG	Offset);
-
-VOID RTMPWriteCBConfig(
-	IN	ULONG	Bus,
-	IN	ULONG	Slot,
-	IN	ULONG	Func,
-	IN	ULONG	Offset,
-	IN	ULONG	Value);
-
-VOID RTMPInitTimer(
-	IN  PRTMP_ADAPTER           pAd,
-	IN  PRALINK_TIMER_STRUCT    pTimer,
-	IN  PVOID                   pTimerFunc,
-	IN	PVOID					pData,
-	IN  BOOLEAN                 Repeat);
-
-VOID RTMPSetTimer(
-	IN  PRALINK_TIMER_STRUCT    pTimer,
-	IN  ULONG                   Value);
-
-
-VOID RTMPModTimer(
-	IN	PRALINK_TIMER_STRUCT	pTimer,
-	IN	ULONG					Value);
-
-VOID RTMPCancelTimer(
-	IN  PRALINK_TIMER_STRUCT    pTimer,
-	OUT BOOLEAN                 *pCancelled);
-
-VOID RTMPSetLED(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			Status);
-
-VOID RTMPSetSignalLED(
-	IN PRTMP_ADAPTER	pAd,
-	IN NDIS_802_11_RSSI Dbm);
-
-
-VOID RTMPEnableRxTx(
-	IN PRTMP_ADAPTER	pAd);
-
-//
-// prototype in action.c
-//
-VOID ActionStateMachineInit(
-    IN	PRTMP_ADAPTER	pAd,
-    IN  STATE_MACHINE *S,
-    OUT STATE_MACHINE_FUNC Trans[]);
-
-VOID MlmeADDBAAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
-
-VOID MlmeDELBAAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
-
-VOID MlmeDLSAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
-
-VOID MlmeInvalidAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
-
-VOID MlmeQOSAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
-
-#ifdef DOT11_N_SUPPORT
-VOID PeerAddBAReqAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
-
-VOID PeerAddBARspAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
-
-VOID PeerDelBAAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
-
-VOID PeerBAAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
-#endif // DOT11_N_SUPPORT //
-
-VOID SendPSMPAction(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			Wcid,
-	IN UCHAR			Psmp);
-
-
-VOID PeerRMAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
-
-VOID PeerPublicAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
-
-#ifdef CONFIG_STA_SUPPORT
-VOID StaPublicAction(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR Bss2040Coexist);
-#endif // CONFIG_STA_SUPPORT //
-
-
-VOID PeerBSSTranAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
-
-#ifdef DOT11_N_SUPPORT
-VOID PeerHTAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
-#endif // DOT11_N_SUPPORT //
-
-VOID PeerQOSAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
-
-#ifdef QOS_DLS_SUPPORT
-VOID PeerDLSAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
-#endif // QOS_DLS_SUPPORT //
-
-#ifdef CONFIG_STA_SUPPORT
-#ifdef QOS_DLS_SUPPORT
-VOID DlsParmFill(
-	IN PRTMP_ADAPTER pAd,
-	IN OUT MLME_DLS_REQ_STRUCT *pDlsReq,
-	IN PRT_802_11_DLS pDls,
-	IN USHORT reason);
-#endif // QOS_DLS_SUPPORT //
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef DOT11_N_SUPPORT
-VOID RECBATimerTimeout(
-    IN PVOID SystemSpecific1,
-    IN PVOID FunctionContext,
-    IN PVOID SystemSpecific2,
-    IN PVOID SystemSpecific3);
-
-VOID ORIBATimerTimeout(
-	IN	PRTMP_ADAPTER	pAd);
-
-VOID SendRefreshBAR(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MAC_TABLE_ENTRY	*pEntry);
-
-#ifdef DOT11N_DRAFT3
-VOID SendBSS2040CoexistMgmtAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR	Wcid,
-	IN	UCHAR	apidx,
-	IN	UCHAR	InfoReq);
-
-VOID SendNotifyBWActionFrame(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR  Wcid,
-	IN UCHAR apidx);
-
-BOOLEAN ChannelSwitchSanityCheck(
-	IN	PRTMP_ADAPTER	pAd,
-	IN    UCHAR  Wcid,
-	IN    UCHAR  NewChannel,
-	IN    UCHAR  Secondary);
-
-VOID ChannelSwitchAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN    UCHAR  Wcid,
-	IN    UCHAR  Channel,
-	IN    UCHAR  Secondary);
-
-ULONG BuildIntolerantChannelRep(
-	IN	PRTMP_ADAPTER	pAd,
-	IN    PUCHAR  pDest);
-
-VOID Update2040CoexistFrameAndNotify(
-	IN	PRTMP_ADAPTER	pAd,
-	IN    UCHAR  Wcid,
-	IN	BOOLEAN	bAddIntolerantCha);
-
-VOID Send2040CoexistAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN    UCHAR  Wcid,
-	IN	BOOLEAN	bAddIntolerantCha);
-#endif // DOT11N_DRAFT3 //
-#endif // DOT11_N_SUPPORT //
-
-VOID ActHeaderInit(
-    IN	PRTMP_ADAPTER	pAd,
-    IN OUT PHEADER_802_11 pHdr80211,
-    IN PUCHAR Addr1,
-    IN PUCHAR Addr2,
-    IN PUCHAR Addr3);
-
-VOID BarHeaderInit(
-	IN	PRTMP_ADAPTER	pAd,
-	IN OUT PFRAME_BAR pCntlBar,
-	IN PUCHAR pDA,
-	IN PUCHAR pSA);
-
-VOID InsertActField(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pFrameBuf,
-	OUT PULONG pFrameLen,
-	IN UINT8 Category,
-	IN UINT8 ActCode);
-
-BOOLEAN QosBADataParse(
-	IN PRTMP_ADAPTER	pAd,
-	IN BOOLEAN bAMSDU,
-	IN PUCHAR p8023Header,
-	IN UCHAR	WCID,
-	IN UCHAR	TID,
-	IN USHORT Sequence,
-	IN UCHAR DataOffset,
-	IN USHORT Datasize,
-	IN UINT   CurRxIndex);
-
-#ifdef DOT11_N_SUPPORT
-BOOLEAN CntlEnqueueForRecv(
-    IN	PRTMP_ADAPTER	pAd,
-	IN ULONG Wcid,
-    IN ULONG MsgLen,
-	IN PFRAME_BA_REQ pMsg);
-
-VOID BaAutoManSwitch(
-	IN	PRTMP_ADAPTER	pAd);
-#endif // DOT11_N_SUPPORT //
-
-VOID HTIOTCheck(
-	IN	PRTMP_ADAPTER	pAd,
-	IN    UCHAR     BatRecIdx);
-
-//
-// Private routines in rtmp_data.c
-//
-BOOLEAN RTMPHandleRxDoneInterrupt(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID RTMPHandleTxDoneInterrupt(
-	IN  PRTMP_ADAPTER   pAd);
-
-BOOLEAN RTMPHandleTxRingDmaDoneInterrupt(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  INT_SOURCE_CSR_STRUC TxRingBitmap);
-
-VOID RTMPHandleMgmtRingDmaDoneInterrupt(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID RTMPHandleTBTTInterrupt(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID RTMPHandlePreTBTTInterrupt(
-	IN  PRTMP_ADAPTER   pAd);
-
-void RTMPHandleTwakeupInterrupt(
-	IN PRTMP_ADAPTER pAd);
-
-VOID	RTMPHandleRxCoherentInterrupt(
-	IN	PRTMP_ADAPTER	pAd);
-
-
-BOOLEAN TxFrameIsAggregatible(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pPrevAddr1,
-	IN  PUCHAR          p8023hdr);
-
-BOOLEAN PeerIsAggreOn(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  ULONG          TxRate,
-    IN  PMAC_TABLE_ENTRY pMacEntry);
-
-
-NDIS_STATUS Sniff2BytesFromNdisBuffer(
-	IN  PNDIS_BUFFER    pFirstBuffer,
-	IN  UCHAR           DesiredOffset,
-	OUT PUCHAR          pByte0,
-	OUT PUCHAR          pByte1);
-
-NDIS_STATUS STASendPacket(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PNDIS_PACKET    pPacket);
-
-VOID STASendPackets(
-	IN  NDIS_HANDLE     MiniportAdapterContext,
-	IN  PPNDIS_PACKET   ppPacketArray,
-	IN  UINT            NumberOfPackets);
-
-VOID RTMPDeQueuePacket(
-	IN  PRTMP_ADAPTER   pAd,
-	IN	BOOLEAN			bIntContext,
-	IN  UCHAR			QueIdx,
-	IN	UCHAR			Max_Tx_Packets);
-
-NDIS_STATUS	RTMPHardTransmit(
-	IN PRTMP_ADAPTER	pAd,
-	IN PNDIS_PACKET		pPacket,
-	IN  UCHAR			QueIdx,
-	OUT	PULONG			pFreeTXDLeft);
-
-NDIS_STATUS	STAHardTransmit(
-	IN PRTMP_ADAPTER	pAd,
-	IN TX_BLK			*pTxBlk,
-	IN  UCHAR			QueIdx);
-
-VOID STARxEAPOLFrameIndicate(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MAC_TABLE_ENTRY	*pEntry,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID);
-
-NDIS_STATUS RTMPFreeTXDRequest(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR           RingType,
-	IN  UCHAR           NumberRequired,
-	IN	PUCHAR          FreeNumberIs);
-
-NDIS_STATUS MlmeHardTransmit(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR	QueIdx,
-	IN  PNDIS_PACKET    pPacket);
-
-NDIS_STATUS MlmeHardTransmitMgmtRing(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR	QueIdx,
-	IN  PNDIS_PACKET    pPacket);
-
-#ifdef RTMP_MAC_PCI
-NDIS_STATUS MlmeHardTransmitTxRing(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR	QueIdx,
-	IN  PNDIS_PACKET    pPacket);
-
-NDIS_STATUS MlmeDataHardTransmit(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR	QueIdx,
-	IN	PNDIS_PACKET	pPacket);
-
-VOID RTMPWriteTxDescriptor(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PTXD_STRUC		pTxD,
-	IN	BOOLEAN			bWIV,
-	IN	UCHAR			QSEL);
-#endif // RTMP_MAC_PCI //
-
-USHORT  RTMPCalcDuration(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR           Rate,
-	IN  ULONG           Size);
-
-VOID RTMPWriteTxWI(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PTXWI_STRUC		pTxWI,
-	IN  BOOLEAN		FRAG,
-	IN  BOOLEAN		CFACK,
-	IN  BOOLEAN		InsTimestamp,
-	IN	BOOLEAN			AMPDU,
-	IN	BOOLEAN			Ack,
-	IN	BOOLEAN			NSeq,		// HW new a sequence.
-	IN	UCHAR			BASize,
-	IN	UCHAR			WCID,
-	IN	ULONG			Length,
-	IN  UCHAR		PID,
-	IN	UCHAR			TID,
-	IN	UCHAR			TxRate,
-	IN	UCHAR			Txopmode,
-	IN	BOOLEAN			CfAck,
-	IN	HTTRANSMIT_SETTING	*pTransmit);
-
-
-VOID RTMPWriteTxWI_Data(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	OUT PTXWI_STRUC		pTxWI,
-	IN	TX_BLK				*pTxBlk);
-
-
-VOID RTMPWriteTxWI_Cache(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	OUT PTXWI_STRUC		pTxWI,
-	IN	TX_BLK				*pTxBlk);
-
-VOID RTMPSuspendMsduTransmission(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID RTMPResumeMsduTransmission(
-	IN  PRTMP_ADAPTER   pAd);
-
-NDIS_STATUS MiniportMMRequest(
-	IN  PRTMP_ADAPTER   pAd,
-	IN	UCHAR			QueIdx,
-	IN	PUCHAR			pData,
-	IN  UINT            Length);
-
-//+++mark by shiang, now this function merge to MiniportMMRequest()
-//---mark by shiang, now this function merge to MiniportMMRequest()
-
-VOID RTMPSendNullFrame(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR           TxRate,
-	IN	BOOLEAN			bQosNull);
-
-VOID RTMPSendDisassociationFrame(
-	IN	PRTMP_ADAPTER	pAd);
-
-VOID RTMPSendRTSFrame(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pDA,
-	IN	unsigned int	NextMpduSize,
-	IN  UCHAR           TxRate,
-	IN  UCHAR           RTSRate,
-	IN  USHORT          AckDuration,
-	IN  UCHAR           QueIdx,
-	IN  UCHAR			FrameGap);
-
-
-NDIS_STATUS RTMPApplyPacketFilter(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PRT28XX_RXD_STRUC      pRxD,
-	IN  PHEADER_802_11  pHeader);
-
-PQUEUE_HEADER   RTMPCheckTxSwQueue(
-	IN  PRTMP_ADAPTER   pAd,
-	OUT UCHAR           *QueIdx);
-
-#ifdef CONFIG_STA_SUPPORT
-VOID RTMPReportMicError(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PCIPHER_KEY     pWpaKey);
-
-VOID	WpaMicFailureReportFrame(
-	IN  PRTMP_ADAPTER    pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID    WpaDisassocApAndBlockAssoc(
-    IN  PVOID SystemSpecific1,
-    IN  PVOID FunctionContext,
-    IN  PVOID SystemSpecific2,
-    IN  PVOID SystemSpecific3);
-
-VOID WpaStaPairwiseKeySetting(
-	IN	PRTMP_ADAPTER	pAd);
-
-VOID WpaStaGroupKeySetting(
-	IN	PRTMP_ADAPTER	pAd);
-
-#endif // CONFIG_STA_SUPPORT //
-
-NDIS_STATUS RTMPCloneNdisPacket(
-	IN  PRTMP_ADAPTER   pAd,
-	IN	BOOLEAN    pInsAMSDUHdr,
-	IN  PNDIS_PACKET    pInPacket,
-	OUT PNDIS_PACKET   *ppOutPacket);
-
-NDIS_STATUS RTMPAllocateNdisPacket(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PNDIS_PACKET    *pPacket,
-	IN  PUCHAR          pHeader,
-	IN  UINT            HeaderLen,
-	IN  PUCHAR          pData,
-	IN  UINT            DataLen);
-
-VOID RTMPFreeNdisPacket(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PNDIS_PACKET    pPacket);
-
-BOOLEAN RTMPFreeTXDUponTxDmaDone(
-	IN PRTMP_ADAPTER    pAd,
-	IN UCHAR            QueIdx);
-
-BOOLEAN RTMPCheckDHCPFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket);
-
-
-BOOLEAN RTMPCheckEtherType(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket);
-
-
-VOID RTMPCckBbpTuning(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UINT			TxRate);
-
-//
-// Private routines in rtmp_wep.c
-//
-VOID RTMPInitWepEngine(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pKey,
-	IN  UCHAR           KeyId,
-	IN  UCHAR           KeyLen,
-	IN  PUCHAR          pDest);
-
-VOID RTMPEncryptData(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pSrc,
-	IN  PUCHAR          pDest,
-	IN  UINT            Len);
-
-BOOLEAN	RTMPDecryptData(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	PUCHAR			pSrc,
-	IN	UINT			Len,
-	IN	UINT			idx);
-
-BOOLEAN	RTMPSoftDecryptWEP(
-	IN PRTMP_ADAPTER	pAd,
-	IN PUCHAR			pData,
-	IN ULONG			DataByteCnt,
-	IN PCIPHER_KEY		pGroupKey);
-
-VOID RTMPSetICV(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pDest);
-
-VOID ARCFOUR_INIT(
-	IN  PARCFOURCONTEXT Ctx,
-	IN  PUCHAR          pKey,
-	IN  UINT            KeyLen);
-
-UCHAR   ARCFOUR_BYTE(
-	IN  PARCFOURCONTEXT     Ctx);
-
-VOID ARCFOUR_DECRYPT(
-	IN  PARCFOURCONTEXT Ctx,
-	IN  PUCHAR          pDest,
-	IN  PUCHAR          pSrc,
-	IN  UINT            Len);
-
-VOID ARCFOUR_ENCRYPT(
-	IN  PARCFOURCONTEXT Ctx,
-	IN  PUCHAR          pDest,
-	IN  PUCHAR          pSrc,
-	IN  UINT            Len);
-
-VOID WPAARCFOUR_ENCRYPT(
-	IN  PARCFOURCONTEXT Ctx,
-	IN  PUCHAR          pDest,
-	IN  PUCHAR          pSrc,
-	IN  UINT            Len);
-
-UINT RTMP_CALC_FCS32(
-	IN  UINT   Fcs,
-	IN  PUCHAR  Cp,
-	IN  INT     Len);
-
-//
-// MLME routines
-//
-
-// Asic/RF/BBP related functions
-
-VOID AsicAdjustTxPower(
-	IN PRTMP_ADAPTER pAd);
-
-VOID	AsicUpdateProtect(
-	IN		PRTMP_ADAPTER	pAd,
-	IN		USHORT			OperaionMode,
-	IN		UCHAR			SetMask,
-	IN		BOOLEAN			bDisableBGProtect,
-	IN		BOOLEAN			bNonGFExist);
-
-VOID AsicSwitchChannel(
-	IN  PRTMP_ADAPTER   pAd,
-	IN	UCHAR			Channel,
-	IN	BOOLEAN			bScan);
-
-VOID AsicLockChannel(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR Channel) ;
-
-VOID AsicAntennaSelect(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR           Channel);
-
-VOID AsicAntennaSetting(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	ABGBAND_STATE	BandState);
-
-VOID AsicRfTuningExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
-
-#ifdef CONFIG_STA_SUPPORT
-
-VOID AsicResetBBPAgent(
-	IN PRTMP_ADAPTER pAd);
-
-VOID AsicSleepThenAutoWakeup(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  USHORT TbttNumToNextWakeUp);
-
-VOID AsicForceSleep(
-	IN PRTMP_ADAPTER pAd);
-
-VOID AsicForceWakeup(
-	IN PRTMP_ADAPTER pAd,
-	IN BOOLEAN    bFromTx);
-#endif // CONFIG_STA_SUPPORT //
-
-VOID AsicSetBssid(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR pBssid);
-
-VOID AsicSetMcastWC(
-	IN PRTMP_ADAPTER pAd);
-
-
-VOID AsicDelWcidTab(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR	Wcid);
-
-VOID AsicEnableRDG(
-	IN PRTMP_ADAPTER pAd);
-
-VOID AsicDisableRDG(
-	IN PRTMP_ADAPTER pAd);
-
-VOID AsicDisableSync(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID AsicEnableBssSync(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID AsicEnableIbssSync(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID AsicSetEdcaParm(
-	IN PRTMP_ADAPTER pAd,
-	IN PEDCA_PARM    pEdcaParm);
-
-VOID AsicSetSlotTime(
-	IN PRTMP_ADAPTER pAd,
-	IN BOOLEAN bUseShortSlotTime);
-
-
-VOID AsicAddSharedKeyEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR         BssIndex,
-	IN UCHAR         KeyIdx,
-	IN UCHAR         CipherAlg,
-	IN PUCHAR        pKey,
-	IN PUCHAR        pTxMic,
-	IN PUCHAR        pRxMic);
-
-VOID AsicRemoveSharedKeyEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR         BssIndex,
-	IN UCHAR         KeyIdx);
-
-VOID AsicUpdateWCIDAttribute(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT		WCID,
-	IN UCHAR		BssIndex,
-	IN UCHAR        CipherAlg,
-	IN BOOLEAN		bUsePairewiseKeyTable);
-
-VOID AsicUpdateWCIDIVEIV(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT		WCID,
-	IN ULONG        uIV,
-	IN ULONG        uEIV);
-
-VOID AsicUpdateRxWCIDTable(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT		WCID,
-	IN PUCHAR        pAddr);
-
-VOID AsicAddKeyEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT		WCID,
-	IN UCHAR		BssIndex,
-	IN UCHAR		KeyIdx,
-	IN PCIPHER_KEY	pCipherKey,
-	IN BOOLEAN		bUsePairewiseKeyTable,
-	IN BOOLEAN		bTxKey);
-
-VOID AsicAddPairwiseKeyEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR        pAddr,
-	IN UCHAR		WCID,
-	IN CIPHER_KEY		 *pCipherKey);
-
-VOID AsicRemovePairwiseKeyEntry(
-	IN PRTMP_ADAPTER  pAd,
-	IN UCHAR		 BssIdx,
-	IN UCHAR		 Wcid);
-
-BOOLEAN AsicSendCommandToMcu(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR         Command,
-	IN UCHAR         Token,
-	IN UCHAR         Arg0,
-	IN UCHAR         Arg1);
-
-
-#ifdef RTMP_MAC_PCI
-BOOLEAN AsicCheckCommanOk(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR		 Command);
-#endif // RTMP_MAC_PCI //
-
-VOID MacAddrRandomBssid(
-	IN  PRTMP_ADAPTER   pAd,
-	OUT PUCHAR pAddr);
-
-VOID MgtMacHeaderInit(
-	IN  PRTMP_ADAPTER     pAd,
-	IN OUT PHEADER_802_11 pHdr80211,
-	IN UCHAR SubType,
-	IN UCHAR ToDs,
-	IN PUCHAR pDA,
-	IN PUCHAR pBssid);
-
-VOID MlmeRadioOff(
-	IN PRTMP_ADAPTER pAd);
-
-VOID MlmeRadioOn(
-	IN PRTMP_ADAPTER pAd);
-
-
-VOID BssTableInit(
-	IN BSS_TABLE *Tab);
-
-#ifdef DOT11_N_SUPPORT
-VOID BATableInit(
-	IN PRTMP_ADAPTER pAd,
-    IN BA_TABLE *Tab);
-#endif // DOT11_N_SUPPORT //
-
-ULONG BssTableSearch(
-	IN BSS_TABLE *Tab,
-	IN PUCHAR pBssid,
-	IN UCHAR Channel);
-
-ULONG BssSsidTableSearch(
-	IN BSS_TABLE *Tab,
-	IN PUCHAR    pBssid,
-	IN PUCHAR    pSsid,
-	IN UCHAR     SsidLen,
-	IN UCHAR     Channel);
-
-ULONG BssTableSearchWithSSID(
-	IN BSS_TABLE *Tab,
-	IN PUCHAR    Bssid,
-	IN PUCHAR    pSsid,
-	IN UCHAR     SsidLen,
-	IN UCHAR     Channel);
-
-ULONG BssSsidTableSearchBySSID(
-	IN BSS_TABLE *Tab,
-	IN PUCHAR	 pSsid,
-	IN UCHAR	 SsidLen);
-
-VOID BssTableDeleteEntry(
-	IN OUT  PBSS_TABLE pTab,
-	IN      PUCHAR pBssid,
-	IN      UCHAR Channel);
-
-#ifdef DOT11_N_SUPPORT
-VOID BATableDeleteORIEntry(
-	IN OUT	PRTMP_ADAPTER pAd,
-	IN		BA_ORI_ENTRY	*pBAORIEntry);
-
-VOID BATableDeleteRECEntry(
-	IN OUT	PRTMP_ADAPTER pAd,
-	IN		BA_REC_ENTRY	*pBARECEntry);
-
-VOID BATableTearORIEntry(
-	IN OUT	PRTMP_ADAPTER pAd,
-	IN		UCHAR TID,
-	IN		UCHAR Wcid,
-	IN		BOOLEAN bForceDelete,
-	IN		BOOLEAN ALL);
-
-VOID BATableTearRECEntry(
-	IN OUT	PRTMP_ADAPTER pAd,
-	IN		UCHAR TID,
-	IN		UCHAR WCID,
-	IN		BOOLEAN ALL);
-#endif // DOT11_N_SUPPORT //
-
-VOID  BssEntrySet(
-	IN  PRTMP_ADAPTER   pAd,
-	OUT PBSS_ENTRY pBss,
-	IN PUCHAR pBssid,
-	IN CHAR Ssid[],
-	IN UCHAR SsidLen,
-	IN UCHAR BssType,
-	IN USHORT BeaconPeriod,
-	IN PCF_PARM CfParm,
-	IN USHORT AtimWin,
-	IN USHORT CapabilityInfo,
-	IN UCHAR SupRate[],
-	IN UCHAR SupRateLen,
-	IN UCHAR ExtRate[],
-	IN UCHAR ExtRateLen,
-	IN HT_CAPABILITY_IE *pHtCapability,
-	IN ADD_HT_INFO_IE *pAddHtInfo,	// AP might use this additional ht info IE
-	IN UCHAR			HtCapabilityLen,
-	IN UCHAR			AddHtInfoLen,
-	IN UCHAR			NewExtChanOffset,
-	IN UCHAR Channel,
-	IN CHAR Rssi,
-	IN LARGE_INTEGER TimeStamp,
-	IN UCHAR CkipFlag,
-	IN PEDCA_PARM pEdcaParm,
-	IN PQOS_CAPABILITY_PARM pQosCapability,
-	IN PQBSS_LOAD_PARM pQbssLoad,
-	IN USHORT LengthVIE,
-	IN PNDIS_802_11_VARIABLE_IEs pVIE);
-
-ULONG  BssTableSetEntry(
-	IN  PRTMP_ADAPTER   pAd,
-	OUT PBSS_TABLE pTab,
-	IN PUCHAR pBssid,
-	IN CHAR Ssid[],
-	IN UCHAR SsidLen,
-	IN UCHAR BssType,
-	IN USHORT BeaconPeriod,
-	IN CF_PARM *CfParm,
-	IN USHORT AtimWin,
-	IN USHORT CapabilityInfo,
-	IN UCHAR SupRate[],
-	IN UCHAR SupRateLen,
-	IN UCHAR ExtRate[],
-	IN UCHAR ExtRateLen,
-	IN HT_CAPABILITY_IE *pHtCapability,
-	IN ADD_HT_INFO_IE *pAddHtInfo,	// AP might use this additional ht info IE
-	IN UCHAR			HtCapabilityLen,
-	IN UCHAR			AddHtInfoLen,
-	IN UCHAR			NewExtChanOffset,
-	IN UCHAR Channel,
-	IN CHAR Rssi,
-	IN LARGE_INTEGER TimeStamp,
-	IN UCHAR CkipFlag,
-	IN PEDCA_PARM pEdcaParm,
-	IN PQOS_CAPABILITY_PARM pQosCapability,
-	IN PQBSS_LOAD_PARM pQbssLoad,
-	IN USHORT LengthVIE,
-	IN PNDIS_802_11_VARIABLE_IEs pVIE);
-
-#ifdef DOT11_N_SUPPORT
-VOID BATableInsertEntry(
-    IN	PRTMP_ADAPTER	pAd,
-	IN USHORT Aid,
-    IN USHORT		TimeOutValue,
-	IN USHORT		StartingSeq,
-    IN UCHAR TID,
-	IN UCHAR BAWinSize,
-	IN UCHAR OriginatorStatus,
-    IN BOOLEAN IsRecipient);
-
-#ifdef DOT11N_DRAFT3
-VOID Bss2040CoexistTimeOut(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
-
-
-VOID  TriEventInit(
-	IN	PRTMP_ADAPTER	pAd);
-
-ULONG TriEventTableSetEntry(
-	IN	PRTMP_ADAPTER	pAd,
-	OUT TRIGGER_EVENT_TAB *Tab,
-	IN PUCHAR pBssid,
-	IN HT_CAPABILITY_IE *pHtCapability,
-	IN UCHAR			HtCapabilityLen,
-	IN UCHAR			RegClass,
-	IN UCHAR ChannelNo);
-
-VOID TriEventCounterMaintenance(
-	IN	PRTMP_ADAPTER	pAd);
-#endif // DOT11N_DRAFT3 //
-#endif // DOT11_N_SUPPORT //
-
-VOID BssTableSsidSort(
-	IN  PRTMP_ADAPTER   pAd,
-	OUT BSS_TABLE *OutTab,
-	IN  CHAR Ssid[],
-	IN  UCHAR SsidLen);
-
-VOID  BssTableSortByRssi(
-	IN OUT BSS_TABLE *OutTab);
-
-VOID BssCipherParse(
-	IN OUT  PBSS_ENTRY  pBss);
-
-NDIS_STATUS  MlmeQueueInit(
-	IN MLME_QUEUE *Queue);
-
-VOID  MlmeQueueDestroy(
-	IN MLME_QUEUE *Queue);
-
-BOOLEAN MlmeEnqueue(
-	IN PRTMP_ADAPTER pAd,
-	IN ULONG Machine,
-	IN ULONG MsgType,
-	IN ULONG MsgLen,
-	IN VOID *Msg);
-
-BOOLEAN MlmeEnqueueForRecv(
-	IN  PRTMP_ADAPTER   pAd,
-	IN ULONG Wcid,
-	IN ULONG TimeStampHigh,
-	IN ULONG TimeStampLow,
-	IN UCHAR Rssi0,
-	IN UCHAR Rssi1,
-	IN UCHAR Rssi2,
-	IN ULONG MsgLen,
-	IN PVOID Msg,
-	IN UCHAR Signal);
-
-
-BOOLEAN MlmeDequeue(
-	IN MLME_QUEUE *Queue,
-	OUT MLME_QUEUE_ELEM **Elem);
-
-VOID    MlmeRestartStateMachine(
-	IN  PRTMP_ADAPTER   pAd);
-
-BOOLEAN  MlmeQueueEmpty(
-	IN MLME_QUEUE *Queue);
-
-BOOLEAN  MlmeQueueFull(
-	IN MLME_QUEUE *Queue);
-
-BOOLEAN  MsgTypeSubst(
-	IN PRTMP_ADAPTER pAd,
-	IN PFRAME_802_11 pFrame,
-	OUT INT *Machine,
-	OUT INT *MsgType);
-
-VOID StateMachineInit(
-	IN STATE_MACHINE *Sm,
-	IN STATE_MACHINE_FUNC Trans[],
-	IN ULONG StNr,
-	IN ULONG MsgNr,
-	IN STATE_MACHINE_FUNC DefFunc,
-	IN ULONG InitState,
-	IN ULONG Base);
-
-VOID StateMachineSetAction(
-	IN STATE_MACHINE *S,
-	IN ULONG St,
-	ULONG Msg,
-	IN STATE_MACHINE_FUNC F);
-
-VOID StateMachinePerformAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN STATE_MACHINE *S,
-	IN MLME_QUEUE_ELEM *Elem);
-
-VOID Drop(
-	IN  PRTMP_ADAPTER   pAd,
-	IN MLME_QUEUE_ELEM *Elem);
-
-VOID AssocStateMachineInit(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  STATE_MACHINE *Sm,
-	OUT STATE_MACHINE_FUNC Trans[]);
-
-VOID ReassocTimeout(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
-
-VOID AssocTimeout(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
-
-VOID DisassocTimeout(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
-
-//----------------------------------------------
-VOID MlmeDisassocReqAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID MlmeAssocReqAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID MlmeReassocReqAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID MlmeDisassocReqAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID PeerAssocRspAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID PeerReassocRspAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID PeerDisassocAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID DisassocTimeoutAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID AssocTimeoutAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID  ReassocTimeoutAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID  Cls3errAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR pAddr);
-
-VOID  InvalidStateWhenAssoc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID  InvalidStateWhenReassoc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID InvalidStateWhenDisassociate(
-	IN  PRTMP_ADAPTER pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-
-VOID  ComposePsPoll(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID  ComposeNullFrame(
-	IN  PRTMP_ADAPTER pAd);
-
-VOID  AssocPostProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR pAddr2,
-	IN  USHORT CapabilityInfo,
-	IN  USHORT Aid,
-	IN  UCHAR SupRate[],
-	IN  UCHAR SupRateLen,
-	IN  UCHAR ExtRate[],
-	IN  UCHAR ExtRateLen,
-	IN PEDCA_PARM pEdcaParm,
-	IN HT_CAPABILITY_IE		*pHtCapability,
-	IN  UCHAR HtCapabilityLen,
-	IN ADD_HT_INFO_IE		*pAddHtInfo);
-
-VOID AuthStateMachineInit(
-	IN  PRTMP_ADAPTER   pAd,
-	IN PSTATE_MACHINE sm,
-	OUT STATE_MACHINE_FUNC Trans[]);
-
-VOID AuthTimeout(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
-
-VOID MlmeAuthReqAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID PeerAuthRspAtSeq2Action(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID PeerAuthRspAtSeq4Action(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID AuthTimeoutAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID Cls2errAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR pAddr);
-
-VOID MlmeDeauthReqAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID InvalidStateWhenAuth(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-//=============================================
-
-VOID AuthRspStateMachineInit(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PSTATE_MACHINE Sm,
-	IN  STATE_MACHINE_FUNC Trans[]);
-
-VOID PeerDeauthAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
-
-VOID PeerAuthSimpleRspGenAndSend(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PHEADER_802_11  pHdr80211,
-	IN  USHORT Alg,
-	IN  USHORT Seq,
-	IN  USHORT Reason,
-	IN  USHORT Status);
-
-//
-// Private routines in dls.c
-//
-
-#ifdef CONFIG_STA_SUPPORT
-#ifdef QOS_DLS_SUPPORT
-void DlsStateMachineInit(
-    IN PRTMP_ADAPTER pAd,
-    IN STATE_MACHINE *Sm,
-    OUT STATE_MACHINE_FUNC Trans[]);
-
-VOID MlmeDlsReqAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
-
-VOID PeerDlsReqAction(
-    IN PRTMP_ADAPTER	pAd,
-    IN MLME_QUEUE_ELEM	*Elem);
-
-VOID PeerDlsRspAction(
-    IN PRTMP_ADAPTER	pAd,
-    IN MLME_QUEUE_ELEM	*Elem);
-
-VOID MlmeDlsTearDownAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
-
-VOID PeerDlsTearDownAction(
-    IN PRTMP_ADAPTER	pAd,
-    IN MLME_QUEUE_ELEM	*Elem);
-
-VOID RTMPCheckDLSTimeOut(
-	IN PRTMP_ADAPTER	pAd);
-
-BOOLEAN RTMPRcvFrameDLSCheck(
-	IN PRTMP_ADAPTER	pAd,
-	IN PHEADER_802_11	pHeader,
-	IN ULONG			Len,
-	IN PRT28XX_RXD_STRUC	pRxD);
-
-INT	RTMPCheckDLSFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN  PUCHAR          pDA);
-
-VOID RTMPSendDLSTearDownFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN  PUCHAR          pDA);
-
-NDIS_STATUS RTMPSendSTAKeyRequest(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pDA);
-
-NDIS_STATUS RTMPSendSTAKeyHandShake(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pDA);
-
-VOID DlsTimeoutAction(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
-
-BOOLEAN MlmeDlsReqSanity(
-	IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PRT_802_11_DLS *pDLS,
-    OUT PUSHORT pReason);
-
-INT Set_DlsEntryInfo_Display_Proc(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR arg);
-
-MAC_TABLE_ENTRY *MacTableInsertDlsEntry(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR	pAddr,
-	IN  UINT	DlsEntryIdx);
-
-BOOLEAN MacTableDeleteDlsEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT wcid,
-	IN PUCHAR pAddr);
-
-MAC_TABLE_ENTRY *DlsEntryTableLookup(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR	pAddr,
-	IN BOOLEAN	bResetIdelCount);
-
-MAC_TABLE_ENTRY *DlsEntryTableLookupByWcid(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR	wcid,
-	IN PUCHAR	pAddr,
-	IN BOOLEAN	bResetIdelCount);
-
-INT	Set_DlsAddEntry_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_DlsTearDownEntry_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-#endif // QOS_DLS_SUPPORT //
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef QOS_DLS_SUPPORT
-BOOLEAN PeerDlsReqSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pDA,
-    OUT PUCHAR pSA,
-    OUT USHORT *pCapabilityInfo,
-    OUT USHORT *pDlsTimeout,
-    OUT UCHAR *pRatesLen,
-    OUT UCHAR Rates[],
-    OUT UCHAR *pHtCapabilityLen,
-    OUT HT_CAPABILITY_IE *pHtCapability);
-
-BOOLEAN PeerDlsRspSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pDA,
-    OUT PUCHAR pSA,
-    OUT USHORT *pCapabilityInfo,
-    OUT USHORT *pStatus,
-    OUT UCHAR *pRatesLen,
-    OUT UCHAR Rates[],
-    OUT UCHAR *pHtCapabilityLen,
-    OUT HT_CAPABILITY_IE *pHtCapability);
-
-BOOLEAN PeerDlsTearDownSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pDA,
-    OUT PUCHAR pSA,
-    OUT USHORT *pReason);
-#endif // QOS_DLS_SUPPORT //
-
-//========================================
-
-VOID SyncStateMachineInit(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  STATE_MACHINE *Sm,
-	OUT STATE_MACHINE_FUNC Trans[]);
-
-VOID BeaconTimeout(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
-
-VOID ScanTimeout(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
-
-VOID MlmeScanReqAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID InvalidStateWhenScan(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID InvalidStateWhenJoin(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID InvalidStateWhenStart(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID PeerBeacon(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID EnqueueProbeRequest(
-	IN PRTMP_ADAPTER pAd);
-
-BOOLEAN ScanRunning(
-		IN PRTMP_ADAPTER pAd);
-//=========================================
-
-VOID MlmeCntlInit(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  STATE_MACHINE *S,
-	OUT STATE_MACHINE_FUNC Trans[]);
-
-VOID MlmeCntlMachinePerformAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  STATE_MACHINE *S,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID CntlIdleProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID CntlOidScanProc(
-	IN  PRTMP_ADAPTER pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID CntlOidSsidProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM * Elem);
-
-VOID CntlOidRTBssidProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM * Elem);
-
-VOID CntlMlmeRoamingProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM * Elem);
-
-VOID CntlWaitDisassocProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID CntlWaitJoinProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID CntlWaitReassocProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID CntlWaitStartProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID CntlWaitAuthProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID CntlWaitAuthProc2(
-	IN  PRTMP_ADAPTER pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID CntlWaitAssocProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-#ifdef QOS_DLS_SUPPORT
-VOID CntlOidDLSSetupProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
-#endif // QOS_DLS_SUPPORT //
-
-VOID LinkUp(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR BssType);
-
-VOID LinkDown(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  BOOLEAN         IsReqFromAP);
-
-VOID IterateOnBssTab(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID IterateOnBssTab2(
-	IN  PRTMP_ADAPTER   pAd);;
-
-VOID JoinParmFill(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  OUT MLME_JOIN_REQ_STRUCT *JoinReq,
-	IN  ULONG BssIdx);
-
-VOID AssocParmFill(
-	IN  PRTMP_ADAPTER   pAd,
-	IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
-	IN  PUCHAR pAddr,
-	IN  USHORT CapabilityInfo,
-	IN  ULONG Timeout,
-	IN  USHORT ListenIntv);
-
-VOID ScanParmFill(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  OUT MLME_SCAN_REQ_STRUCT *ScanReq,
-	IN  STRING Ssid[],
-	IN  UCHAR SsidLen,
-	IN  UCHAR BssType,
-	IN  UCHAR ScanType);
-
-VOID DisassocParmFill(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
-	IN  PUCHAR pAddr,
-	IN  USHORT Reason);
-
-VOID StartParmFill(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  OUT MLME_START_REQ_STRUCT *StartReq,
-	IN  CHAR Ssid[],
-	IN  UCHAR SsidLen);
-
-VOID AuthParmFill(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  OUT MLME_AUTH_REQ_STRUCT *AuthReq,
-	IN  PUCHAR pAddr,
-	IN  USHORT Alg);
-
-VOID EnqueuePsPoll(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID EnqueueBeaconFrame(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID MlmeJoinReqAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID MlmeScanReqAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID MlmeStartReqAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID ScanTimeoutAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID BeaconTimeoutAtJoinAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID PeerBeaconAtScanAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID PeerBeaconAtJoinAction(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID PeerBeacon(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID PeerProbeReqAction(
-	IN  PRTMP_ADAPTER pAd,
-	IN  MLME_QUEUE_ELEM *Elem);
-
-VOID ScanNextChannel(
-	IN  PRTMP_ADAPTER   pAd);
-
-ULONG MakeIbssBeacon(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID CCXAdjacentAPReport(
-	IN  PRTMP_ADAPTER   pAd);
-
-BOOLEAN MlmeScanReqSanity(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  VOID *Msg,
-	IN  ULONG MsgLen,
-	OUT UCHAR *BssType,
-	OUT CHAR ssid[],
-	OUT UCHAR *SsidLen,
-	OUT UCHAR *ScanType);
-
-BOOLEAN PeerBeaconAndProbeRspSanity(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  VOID *Msg,
-	IN  ULONG MsgLen,
-	IN  UCHAR MsgChannel,
-	OUT PUCHAR pAddr2,
-	OUT PUCHAR pBssid,
-	OUT CHAR Ssid[],
-	OUT UCHAR *pSsidLen,
-	OUT UCHAR *pBssType,
-	OUT USHORT *pBeaconPeriod,
-	OUT UCHAR *pChannel,
-	OUT UCHAR *pNewChannel,
-	OUT LARGE_INTEGER *pTimestamp,
-	OUT CF_PARM *pCfParm,
-	OUT USHORT *pAtimWin,
-	OUT USHORT *pCapabilityInfo,
-	OUT UCHAR *pErp,
-	OUT UCHAR *pDtimCount,
-	OUT UCHAR *pDtimPeriod,
-	OUT UCHAR *pBcastFlag,
-	OUT UCHAR *pMessageToMe,
-	OUT UCHAR SupRate[],
-	OUT UCHAR *pSupRateLen,
-	OUT UCHAR ExtRate[],
-	OUT UCHAR *pExtRateLen,
-	OUT	UCHAR *pCkipFlag,
-	OUT	UCHAR *pAironetCellPowerLimit,
-	OUT PEDCA_PARM       pEdcaParm,
-	OUT PQBSS_LOAD_PARM  pQbssLoad,
-	OUT PQOS_CAPABILITY_PARM pQosCapability,
-	OUT ULONG *pRalinkIe,
-	OUT UCHAR		 *pHtCapabilityLen,
-#ifdef CONFIG_STA_SUPPORT
-	OUT UCHAR		 *pPreNHtCapabilityLen,
-#endif // CONFIG_STA_SUPPORT //
-	OUT HT_CAPABILITY_IE *pHtCapability,
-	OUT UCHAR		 *AddHtInfoLen,
-	OUT ADD_HT_INFO_IE *AddHtInfo,
-	OUT UCHAR *NewExtChannel,
-	OUT USHORT *LengthVIE,
-	OUT PNDIS_802_11_VARIABLE_IEs pVIE);
-
-BOOLEAN PeerAddBAReqActionSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *pMsg,
-    IN ULONG MsgLen,
-	OUT PUCHAR pAddr2);
-
-BOOLEAN PeerAddBARspActionSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *pMsg,
-    IN ULONG MsgLen);
-
-BOOLEAN PeerDelBAActionSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN UCHAR Wcid,
-    IN VOID *pMsg,
-    IN ULONG MsgLen);
-
-BOOLEAN MlmeAssocReqSanity(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  VOID *Msg,
-	IN  ULONG MsgLen,
-	OUT PUCHAR pApAddr,
-	OUT USHORT *CapabilityInfo,
-	OUT ULONG *Timeout,
-	OUT USHORT *ListenIntv);
-
-BOOLEAN MlmeAuthReqSanity(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  VOID *Msg,
-	IN  ULONG MsgLen,
-	OUT PUCHAR pAddr,
-	OUT ULONG *Timeout,
-	OUT USHORT *Alg);
-
-BOOLEAN MlmeStartReqSanity(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  VOID *Msg,
-	IN  ULONG MsgLen,
-	OUT CHAR Ssid[],
-	OUT UCHAR *Ssidlen);
-
-BOOLEAN PeerAuthSanity(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  VOID *Msg,
-	IN  ULONG MsgLen,
-	OUT PUCHAR pAddr,
-	OUT USHORT *Alg,
-	OUT USHORT *Seq,
-	OUT USHORT *Status,
-	OUT CHAR ChlgText[]);
-
-BOOLEAN PeerAssocRspSanity(
-	IN  PRTMP_ADAPTER   pAd,
-    IN VOID *pMsg,
-	IN  ULONG MsgLen,
-	OUT PUCHAR pAddr2,
-	OUT USHORT *pCapabilityInfo,
-	OUT USHORT *pStatus,
-	OUT USHORT *pAid,
-	OUT UCHAR SupRate[],
-	OUT UCHAR *pSupRateLen,
-	OUT UCHAR ExtRate[],
-	OUT UCHAR *pExtRateLen,
-    OUT HT_CAPABILITY_IE		*pHtCapability,
-    OUT ADD_HT_INFO_IE		*pAddHtInfo,	// AP might use this additional ht info IE
-    OUT UCHAR			*pHtCapabilityLen,
-    OUT UCHAR			*pAddHtInfoLen,
-    OUT UCHAR			*pNewExtChannelOffset,
-	OUT PEDCA_PARM pEdcaParm,
-	OUT UCHAR *pCkipFlag);
-
-BOOLEAN PeerDisassocSanity(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  VOID *Msg,
-	IN  ULONG MsgLen,
-	OUT PUCHAR pAddr2,
-	OUT USHORT *Reason);
-
-BOOLEAN PeerWpaMessageSanity(
-    IN	PRTMP_ADAPTER		pAd,
-    IN	PEAPOL_PACKET		pMsg,
-    IN	ULONG				MsgLen,
-    IN	UCHAR				MsgType,
-    IN	MAC_TABLE_ENTRY		*pEntry);
-
-BOOLEAN PeerDeauthSanity(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  VOID *Msg,
-	IN  ULONG MsgLen,
-	OUT PUCHAR pAddr2,
-	OUT USHORT *Reason);
-
-BOOLEAN PeerProbeReqSanity(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  VOID *Msg,
-	IN  ULONG MsgLen,
-	OUT PUCHAR pAddr2,
-	OUT CHAR Ssid[],
-	OUT UCHAR *pSsidLen);
-
-BOOLEAN GetTimBit(
-	IN  CHAR *Ptr,
-	IN  USHORT Aid,
-	OUT UCHAR *TimLen,
-	OUT UCHAR *BcastFlag,
-	OUT UCHAR *DtimCount,
-	OUT UCHAR *DtimPeriod,
-	OUT UCHAR *MessageToMe);
-
-UCHAR ChannelSanity(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR channel);
-
-NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(
-	IN PBSS_ENTRY pBss);
-
-
-BOOLEAN MlmeDelBAReqSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen);
-
-BOOLEAN MlmeAddBAReqSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pAddr2);
-
-ULONG MakeOutgoingFrame(
-	OUT UCHAR *Buffer,
-	OUT ULONG *Length, ...);
-
-VOID  LfsrInit(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  ULONG Seed);
-
-UCHAR RandomByte(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID AsicUpdateAutoFallBackTable(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pTxRate);
-
-VOID  MlmePeriodicExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
-
-VOID LinkDownExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
-
-VOID LinkUpExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
-
-VOID STAMlmePeriodicExec(
-	PRTMP_ADAPTER pAd);
-
-VOID MlmeAutoScan(
-	IN PRTMP_ADAPTER pAd);
-
-VOID MlmeAutoReconnectLastSSID(
-	IN PRTMP_ADAPTER pAd);
-
-BOOLEAN MlmeValidateSSID(
-	IN PUCHAR pSsid,
-	IN UCHAR  SsidLen);
-
-VOID MlmeCheckForRoaming(
-	IN PRTMP_ADAPTER pAd,
-	IN ULONG    Now32);
-
-BOOLEAN MlmeCheckForFastRoaming(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID MlmeDynamicTxRateSwitching(
-	IN PRTMP_ADAPTER pAd);
-
-VOID MlmeSetTxRate(
-	IN PRTMP_ADAPTER		pAd,
-	IN PMAC_TABLE_ENTRY		pEntry,
-	IN PRTMP_TX_RATE_SWITCH	pTxRate);
-
-VOID MlmeSelectTxRateTable(
-	IN PRTMP_ADAPTER		pAd,
-	IN PMAC_TABLE_ENTRY		pEntry,
-	IN PUCHAR				*ppTable,
-	IN PUCHAR				pTableSize,
-	IN PUCHAR				pInitTxRateIdx);
-
-VOID MlmeCalculateChannelQuality(
-	IN PRTMP_ADAPTER pAd,
-	IN PMAC_TABLE_ENTRY pMacEntry,
-	IN ULONG Now);
-
-VOID MlmeCheckPsmChange(
-	IN PRTMP_ADAPTER pAd,
-	IN ULONG    Now32);
-
-VOID MlmeSetPsmBit(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT psm);
-
-VOID MlmeSetTxPreamble(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT TxPreamble);
-
-VOID UpdateBasicRateBitmap(
-	IN	PRTMP_ADAPTER	pAd);
-
-VOID MlmeUpdateTxRates(
-	IN PRTMP_ADAPTER	pAd,
-	IN	BOOLEAN			bLinkUp,
-	IN	UCHAR			apidx);
-
-#ifdef DOT11_N_SUPPORT
-VOID MlmeUpdateHtTxRates(
-	IN PRTMP_ADAPTER		pAd,
-	IN	UCHAR				apidx);
-#endif // DOT11_N_SUPPORT //
-
-VOID    RTMPCheckRates(
-	IN      PRTMP_ADAPTER   pAd,
-	IN OUT  UCHAR           SupRate[],
-	IN OUT  UCHAR           *SupRateLen);
-
-#ifdef CONFIG_STA_SUPPORT
-BOOLEAN RTMPCheckChannel(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR		CentralChannel,
-	IN UCHAR		Channel);
-#endif // CONFIG_STA_SUPPORT //
-
-BOOLEAN		RTMPCheckHt(
-	IN		PRTMP_ADAPTER	pAd,
-	IN		UCHAR	Wcid,
-	IN OUT	HT_CAPABILITY_IE			*pHtCapability,
-	IN OUT	ADD_HT_INFO_IE			*pAddHtInfo);
-
-VOID StaQuickResponeForRateUpExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
-
-VOID AsicBbpTuning1(
-	IN PRTMP_ADAPTER pAd);
-
-VOID AsicBbpTuning2(
-	IN PRTMP_ADAPTER pAd);
-
-VOID RTMPUpdateMlmeRate(
-	IN PRTMP_ADAPTER	pAd);
-
-CHAR RTMPMaxRssi(
-	IN PRTMP_ADAPTER	pAd,
-	IN CHAR				Rssi0,
-	IN CHAR				Rssi1,
-	IN CHAR				Rssi2);
-
-#ifdef RT30xx
-VOID AsicSetRxAnt(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			Ant);
-
-VOID RTMPFilterCalibration(
-	IN PRTMP_ADAPTER pAd);
-
-#ifdef RTMP_EFUSE_SUPPORT
-//2008/09/11:KH add to support efuse<--
-INT set_eFuseGetFreeBlockCount_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT set_eFusedump_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT set_eFuseLoadFromBin_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-VOID eFusePhysicalReadRegisters(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	OUT	USHORT* pData);
-
-int RtmpEfuseSupportCheck(
-	IN RTMP_ADAPTER *pAd);
-
-INT set_eFuseBufferModeWriteBack_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT eFuseLoadEEPROM(
-	IN PRTMP_ADAPTER pAd);
-
-INT eFuseWriteEeeppromBuf(
-	IN PRTMP_ADAPTER pAd);
-
-VOID eFuseGetFreeBlockCount(IN PRTMP_ADAPTER pAd,
-	PUINT EfuseFreeBlock);
-
-INT eFuse_init(
-	IN PRTMP_ADAPTER pAd);
-
-NTSTATUS eFuseRead(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	OUT	PUCHAR			pData,
-	IN	USHORT			Length);
-
-NTSTATUS eFuseWrite(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	IN	PUCHAR			pData,
-	IN	USHORT			length);
-//2008/09/11:KH add to support efuse-->
-#endif // RTMP_EFUSE_SUPPORT //
-
-// add by johnli, RF power sequence setup
-VOID RT30xxLoadRFNormalModeSetup(
-	IN PRTMP_ADAPTER	pAd);
-
-VOID RT30xxLoadRFSleepModeSetup(
-	IN PRTMP_ADAPTER	pAd);
-
-VOID RT30xxReverseRFSleepModeSetup(
-	IN PRTMP_ADAPTER	pAd);
-// end johnli
-
-
-#ifdef RT3090
-VOID NICInitRT3090RFRegisters(
-	IN RTMP_ADAPTER *pAd);
-#endif // RT3090 //
-
-VOID RT30xxHaltAction(
-	IN PRTMP_ADAPTER	pAd);
-
-VOID RT30xxSetRxAnt(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			Ant);
-#endif // RT30xx //
-#ifdef RT33xx
-VOID RT33xxLoadRFNormalModeSetup(
-	IN PRTMP_ADAPTER	pAd);
-
-VOID RT33xxLoadRFSleepModeSetup(
-	IN PRTMP_ADAPTER	pAd);
-
-VOID RT33xxReverseRFSleepModeSetup(
-	IN PRTMP_ADAPTER	pAd);
-
-#ifdef RT3370
-VOID NICInitRT3370RFRegisters(
-	IN RTMP_ADAPTER *pAd);
-#endif // RT3070 //
-
-#ifdef RT3390
-VOID NICInitRT3390RFRegisters(
-	IN RTMP_ADAPTER *pAd);
-#endif // RT3090 //
-
-VOID RT33xxHaltAction(
-	IN PRTMP_ADAPTER	pAd);
-
-VOID RT33xxSetRxAnt(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			Ant);
-
-#endif // RT33xx //
-
-
-
-VOID AsicEvaluateRxAnt(
-	IN PRTMP_ADAPTER	pAd);
-
-VOID AsicRxAntEvalTimeout(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
-
-VOID APSDPeriodicExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
-
-BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(
-	IN PRTMP_ADAPTER    pAd,
-	IN PMAC_TABLE_ENTRY	pEntry);
-
-UCHAR RTMPStaFixedTxMode(
-	IN PRTMP_ADAPTER    pAd,
-	IN PMAC_TABLE_ENTRY	pEntry);
-
-VOID RTMPUpdateLegacyTxSetting(
-		UCHAR				fixed_tx_mode,
-		PMAC_TABLE_ENTRY	pEntry);
-
-BOOLEAN RTMPAutoRateSwitchCheck(
-	IN PRTMP_ADAPTER    pAd);
-
-NDIS_STATUS MlmeInit(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID MlmeHandler(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID MlmeHalt(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID MlmeResetRalinkCounters(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID BuildChannelList(
-	IN PRTMP_ADAPTER pAd);
-
-UCHAR FirstChannel(
-	IN  PRTMP_ADAPTER   pAd);
-
-UCHAR NextChannel(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR channel);
-
-VOID ChangeToCellPowerLimit(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR         AironetCellPowerLimit);
-
-//
-// Prototypes of function definition in rtmp_tkip.c
-//
-VOID    RTMPInitTkipEngine(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pTKey,
-	IN  UCHAR           KeyId,
-	IN  PUCHAR          pTA,
-	IN  PUCHAR          pMICKey,
-	IN  PUCHAR          pTSC,
-	OUT PULONG          pIV16,
-	OUT PULONG          pIV32);
-
-VOID    RTMPInitMICEngine(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pKey,
-	IN  PUCHAR          pDA,
-	IN  PUCHAR          pSA,
-	IN  UCHAR           UserPriority,
-	IN  PUCHAR          pMICKey);
-
-BOOLEAN RTMPTkipCompareMICValue(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pSrc,
-	IN  PUCHAR          pDA,
-	IN  PUCHAR          pSA,
-	IN  PUCHAR          pMICKey,
-	IN	UCHAR			UserPriority,
-	IN  UINT            Len);
-
-VOID    RTMPCalculateMICValue(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PNDIS_PACKET    pPacket,
-	IN  PUCHAR          pEncap,
-	IN  PCIPHER_KEY     pKey,
-	IN	UCHAR			apidx);
-
-BOOLEAN RTMPTkipCompareMICValueWithLLC(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pLLC,
-	IN  PUCHAR          pSrc,
-	IN  PUCHAR          pDA,
-	IN  PUCHAR          pSA,
-	IN  PUCHAR          pMICKey,
-	IN  UINT            Len);
-
-VOID    RTMPTkipAppendByte(
-	IN  PTKIP_KEY_INFO  pTkip,
-	IN  UCHAR           uChar);
-
-VOID    RTMPTkipAppend(
-	IN  PTKIP_KEY_INFO  pTkip,
-	IN  PUCHAR          pSrc,
-	IN  UINT            nBytes);
-
-VOID    RTMPTkipGetMIC(
-	IN  PTKIP_KEY_INFO  pTkip);
-
-BOOLEAN RTMPSoftDecryptTKIP(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR	pData,
-	IN ULONG	DataByteCnt,
-	IN UCHAR    UserPriority,
-	IN PCIPHER_KEY	pWpaKey);
-
-BOOLEAN RTMPSoftDecryptAES(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR	pData,
-	IN ULONG	DataByteCnt,
-	IN PCIPHER_KEY	pWpaKey);
-
-
-
-//
-// Prototypes of function definition in cmm_info.c
-//
-INT RT_CfgSetCountryRegion(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg,
-	IN INT				band);
-
-INT RT_CfgSetWirelessMode(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT RT_CfgSetShortSlot(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	RT_CfgSetWepKey(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			keyString,
-	IN	CIPHER_KEY		*pSharedKey,
-	IN	INT				keyIdx);
-
-INT RT_CfgSetWPAPSKKey(
-	IN RTMP_ADAPTER	*pAd,
-	IN PSTRING		keyString,
-	IN UCHAR		*pHashStr,
-	IN INT			hashStrLen,
-	OUT PUCHAR		pPMKBuf);
-
-
-
-//
-// Prototypes of function definition in cmm_info.c
-//
-NDIS_STATUS RTMPWPARemoveKeyProc(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PVOID           pBuf);
-
-VOID    RTMPWPARemoveAllKeys(
-	IN  PRTMP_ADAPTER   pAd);
-
-BOOLEAN RTMPCheckStrPrintAble(
-    IN  CHAR *pInPutStr,
-    IN  UCHAR strLen);
-
-VOID    RTMPSetPhyMode(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  ULONG phymode);
-
-VOID	RTMPUpdateHTIE(
-	IN	RT_HT_CAPABILITY	*pRtHt,
-	IN		UCHAR				*pMcsSet,
-	OUT		HT_CAPABILITY_IE *pHtCapability,
-	OUT		ADD_HT_INFO_IE		*pAddHtInfo);
-
-VOID	RTMPAddWcidAttributeEntry(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			BssIdx,
-	IN	UCHAR			KeyIdx,
-	IN	UCHAR			CipherAlg,
-	IN	MAC_TABLE_ENTRY *pEntry);
-
-PSTRING GetEncryptType(
-	CHAR enc);
-
-PSTRING GetAuthMode(
-	CHAR auth);
-
-
-VOID RTMPIndicateWPA2Status(
-	IN  PRTMP_ADAPTER  pAdapter);
-
-VOID	RTMPOPModeSwitching(
-	IN	PRTMP_ADAPTER	pAd);
-
-
-#ifdef DOT11_N_SUPPORT
-VOID	RTMPSetHT(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	OID_SET_HT_PHYMODE *pHTPhyMode);
-
-VOID	RTMPSetIndividualHT(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	UCHAR				apidx);
-#endif // DOT11_N_SUPPORT //
-
-VOID RTMPSendWirelessEvent(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Event_flag,
-	IN	PUCHAR			pAddr,
-	IN  UCHAR			BssIdx,
-	IN	CHAR			Rssi);
-
-VOID	NICUpdateCntlCounters(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PHEADER_802_11	pHeader,
-	IN    UCHAR			SubType,
-	IN	PRXWI_STRUC	pRxWI);
-
-VOID    DBGPRINT_TX_RING(
-	IN PRTMP_ADAPTER  pAd,
-	IN UCHAR          QueIdx);
-
-VOID DBGPRINT_RX_RING(
-	IN PRTMP_ADAPTER  pAd);
-
-CHAR    ConvertToRssi(
-	IN PRTMP_ADAPTER  pAd,
-	IN CHAR				Rssi,
-	IN UCHAR    RssiNumber);
-
-
-#ifdef DOT11N_DRAFT3
-VOID BuildEffectedChannelList(
-	IN PRTMP_ADAPTER pAd);
-#endif // DOT11N_DRAFT3 //
-
-
-VOID APAsicEvaluateRxAnt(
-	IN PRTMP_ADAPTER	pAd);
-
-#ifdef ANT_DIVERSITY_SUPPORT
-VOID	APAsicAntennaAvg(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR	              AntSelect,
-	IN	SHORT	              *RssiAvg);
-#endif // ANT_DIVERSITY_SUPPORT //
-
-VOID APAsicRxAntEvalTimeout(
-	IN PRTMP_ADAPTER	pAd);
-
-/*===================================
-	Function prototype in cmm_wpa.c
-  =================================== */
-VOID	RTMPToWirelessSta(
-    IN  PRTMP_ADAPTER		pAd,
-    IN  PMAC_TABLE_ENTRY	pEntry,
-    IN  PUCHAR			pHeader802_3,
-    IN  UINT			HdrLen,
-    IN  PUCHAR			pData,
-    IN  UINT			DataLen,
-    IN	BOOLEAN				bClearFrame);
-
-VOID WpaDerivePTK(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UCHAR   *PMK,
-	IN  UCHAR   *ANonce,
-	IN  UCHAR   *AA,
-	IN  UCHAR   *SNonce,
-	IN  UCHAR   *SA,
-	OUT UCHAR   *output,
-	IN  UINT    len);
-
-VOID    GenRandom(
-	IN  PRTMP_ADAPTER   pAd,
-	IN	UCHAR			*macAddr,
-	OUT	UCHAR			*random);
-
-BOOLEAN RTMPCheckWPAframe(
-	IN PRTMP_ADAPTER pAd,
-	IN PMAC_TABLE_ENTRY	pEntry,
-	IN PUCHAR			pData,
-	IN ULONG			DataByteCount,
-	IN UCHAR			FromWhichBSSID);
-
-VOID AES_GTK_KEY_UNWRAP(
-	IN  UCHAR   *key,
-	OUT UCHAR   *plaintext,
-	IN	UINT32	c_len,
-	IN  UCHAR   *ciphertext);
-
-BOOLEAN RTMPParseEapolKeyData(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR          pKeyData,
-	IN  UCHAR           KeyDataLen,
-	IN	UCHAR			GroupKeyIndex,
-	IN	UCHAR			MsgType,
-	IN	BOOLEAN			bWPA2,
-	IN  MAC_TABLE_ENTRY *pEntry);
-
-VOID	ConstructEapolMsg(
-	IN	PMAC_TABLE_ENTRY	pEntry,
-    IN	UCHAR				GroupKeyWepStatus,
-    IN	UCHAR				MsgType,
-    IN	UCHAR				DefaultKeyIdx,
-	IN	UCHAR				*KeyNonce,
-	IN	UCHAR				*TxRSC,
-	IN	UCHAR				*GTK,
-	IN	UCHAR				*RSNIE,
-	IN	UCHAR				RSNIE_Len,
-    OUT PEAPOL_PACKET       pMsg);
-
-NDIS_STATUS	RTMPSoftDecryptBroadCastData(
-	IN	PRTMP_ADAPTER					pAd,
-	IN	RX_BLK							*pRxBlk,
-	IN  NDIS_802_11_ENCRYPTION_STATUS	GroupCipher,
-	IN  PCIPHER_KEY						pShard_key);
-
-VOID RTMPMakeRSNIE(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  UINT            AuthMode,
-	IN  UINT            WepStatus,
-	IN	UCHAR			apidx);
-
-//
-// function prototype in ap_wpa.c
-//
-VOID RTMPGetTxTscFromAsic(
-	IN  PRTMP_ADAPTER   pAd,
-	IN	UCHAR			apidx,
-	OUT	PUCHAR			pTxTsc);
-
-VOID APInstallPairwiseKey(
-	PRTMP_ADAPTER		pAd,
-	PMAC_TABLE_ENTRY	pEntry);
-
-MAC_TABLE_ENTRY *PACInquiry(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  ULONG           Wcid);
-
-UINT	APValidateRSNIE(
-	IN PRTMP_ADAPTER    pAd,
-	IN PMAC_TABLE_ENTRY pEntry,
-	IN PUCHAR			pRsnIe,
-	IN UCHAR			rsnie_len);
-
-VOID HandleCounterMeasure(
-	IN PRTMP_ADAPTER pAd,
-	IN MAC_TABLE_ENTRY  *pEntry);
-
-VOID WPAStart4WayHS(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MAC_TABLE_ENTRY *pEntry,
-	IN	ULONG			TimeInterval);
-
-VOID WPAStart2WayGroupHS(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  MAC_TABLE_ENTRY *pEntry);
-
-VOID PeerPairMsg1Action(
-	IN PRTMP_ADAPTER pAd,
-	IN MAC_TABLE_ENTRY  *pEntry,
-	IN MLME_QUEUE_ELEM *Elem);
-
-VOID PeerPairMsg2Action(
-	IN PRTMP_ADAPTER pAd,
-	IN MAC_TABLE_ENTRY  *pEntry,
-	IN MLME_QUEUE_ELEM *Elem);
-
-VOID PeerPairMsg3Action(
-	IN PRTMP_ADAPTER pAd,
-	IN MAC_TABLE_ENTRY  *pEntry,
-	IN MLME_QUEUE_ELEM *Elem);
-
-VOID PeerPairMsg4Action(
-	IN PRTMP_ADAPTER pAd,
-	IN MAC_TABLE_ENTRY  *pEntry,
-	IN MLME_QUEUE_ELEM *Elem);
-
-VOID PeerGroupMsg1Action(
-	IN  PRTMP_ADAPTER    pAd,
-	IN  PMAC_TABLE_ENTRY pEntry,
-    IN  MLME_QUEUE_ELEM  *Elem);
-
-VOID PeerGroupMsg2Action(
-	IN  PRTMP_ADAPTER    pAd,
-	IN  PMAC_TABLE_ENTRY pEntry,
-	IN  VOID             *Msg,
-	IN  UINT             MsgLen);
-
-VOID CMTimerExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
-
-VOID WPARetryExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
-
-VOID EnqueueStartForPSKExec(
-    IN PVOID SystemSpecific1,
-    IN PVOID FunctionContext,
-    IN PVOID SystemSpecific2,
-    IN PVOID SystemSpecific3);
-
-VOID RTMPHandleSTAKey(
-    IN PRTMP_ADAPTER    pAdapter,
-    IN MAC_TABLE_ENTRY  *pEntry,
-    IN MLME_QUEUE_ELEM  *Elem);
-
-VOID PairDisAssocAction(
-	IN  PRTMP_ADAPTER    pAd,
-	IN  PMAC_TABLE_ENTRY pEntry,
-	IN  USHORT           Reason);
-
-VOID MlmeDeAuthAction(
-	IN  PRTMP_ADAPTER    pAd,
-	IN  PMAC_TABLE_ENTRY pEntry,
-	IN  USHORT           Reason);
-
-VOID GREKEYPeriodicExec(
-	IN  PVOID   SystemSpecific1,
-	IN  PVOID   FunctionContext,
-	IN  PVOID   SystemSpecific2,
-	IN  PVOID   SystemSpecific3);
-
-VOID WpaDeriveGTK(
-	IN  UCHAR   *PMK,
-	IN  UCHAR   *GNonce,
-	IN  UCHAR   *AA,
-	OUT UCHAR   *output,
-	IN  UINT    len);
-
-VOID AES_GTK_KEY_WRAP(
-	IN UCHAR *key,
-	IN UCHAR *plaintext,
-	IN UINT32 p_len,
-	OUT UCHAR *ciphertext);
-
-VOID AES_128_CMAC(
-	IN	PUCHAR	key,
-	IN	PUCHAR	input,
-	IN	INT		len,
-	OUT	PUCHAR	mac);
-
-VOID    WpaSend(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PUCHAR          pPacket,
-    IN  ULONG           Len);
-
-VOID RTMPAddPMKIDCache(
-	IN  PRTMP_ADAPTER		pAd,
-	IN	INT						apidx,
-	IN	PUCHAR				pAddr,
-	IN	UCHAR					*PMKID,
-	IN	UCHAR					*PMK);
-
-INT RTMPSearchPMKIDCache(
-	IN  PRTMP_ADAPTER   pAd,
-	IN	INT				apidx,
-	IN	PUCHAR		pAddr);
-
-VOID RTMPDeletePMKIDCache(
-	IN  PRTMP_ADAPTER   pAd,
-	IN	INT				apidx,
-	IN  INT				idx);
-
-VOID RTMPMaintainPMKIDCache(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID	RTMPSendTriggerFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PVOID			pBuffer,
-	IN	ULONG			Length,
-	IN  UCHAR           TxRate,
-	IN	BOOLEAN			bQosNull);
-
-//typedef void (*TIMER_FUNCTION)(unsigned long);
-
-
-/* timeout -- ms */
-VOID RTMP_SetPeriodicTimer(
-	IN	NDIS_MINIPORT_TIMER *pTimer,
-	IN	unsigned long timeout);
-
-VOID RTMP_OS_Init_Timer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	NDIS_MINIPORT_TIMER *pTimer,
-	IN	TIMER_FUNCTION function,
-	IN	PVOID data);
-
-VOID RTMP_OS_Add_Timer(
-	IN	NDIS_MINIPORT_TIMER	*pTimer,
-	IN	unsigned long timeout);
-
-VOID RTMP_OS_Mod_Timer(
-	IN	NDIS_MINIPORT_TIMER	*pTimer,
-	IN	unsigned long timeout);
-
-
-VOID RTMP_OS_Del_Timer(
-	IN	NDIS_MINIPORT_TIMER	*pTimer,
-	OUT	BOOLEAN				 *pCancelled);
-
-
-VOID RTMP_OS_Release_Packet(
-	IN	PRTMP_ADAPTER pAd,
-	IN	PQUEUE_ENTRY  pEntry);
-
-VOID RTMPusecDelay(
-	IN	ULONG	usec);
-
-NDIS_STATUS os_alloc_mem(
-	IN	RTMP_ADAPTER *pAd,
-	OUT	UCHAR **mem,
-	IN	ULONG  size);
-
-NDIS_STATUS os_free_mem(
-	IN	PRTMP_ADAPTER pAd,
-	IN	PVOID mem);
-
-
-void RTMP_AllocateSharedMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
-
-VOID RTMPFreeTxRxRingMemory(
-    IN  PRTMP_ADAPTER   pAd);
-
-NDIS_STATUS AdapterBlockAllocateMemory(
-	IN PVOID	handle,
-	OUT	PVOID	*ppAd);
-
-void RTMP_AllocateTxDescMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	UINT	Index,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
-
-void RTMP_AllocateFirstTxBuffer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	UINT	Index,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
-
-void RTMP_FreeFirstTxBuffer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	IN	PVOID	VirtualAddress,
-	IN	NDIS_PHYSICAL_ADDRESS PhysicalAddress);
-
-void RTMP_AllocateMgmtDescMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
-
-void RTMP_AllocateRxDescMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
-
-void RTMP_FreeDescMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	PVOID	VirtualAddress,
-	IN	NDIS_PHYSICAL_ADDRESS PhysicalAddress);
-
-PNDIS_PACKET RtmpOSNetPktAlloc(
-	IN RTMP_ADAPTER *pAd,
-	IN int size);
-
-PNDIS_PACKET RTMP_AllocateRxPacketBuffer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
-
-PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress);
-
-PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length);
-
-void RTMP_QueryPacketInfo(
-	IN  PNDIS_PACKET pPacket,
-	OUT PACKET_INFO  *pPacketInfo,
-	OUT PUCHAR		 *pSrcBufVA,
-	OUT	UINT		 *pSrcBufLen);
-
-void RTMP_QueryNextPacketInfo(
-	IN  PNDIS_PACKET *ppPacket,
-	OUT PACKET_INFO  *pPacketInfo,
-	OUT PUCHAR		 *pSrcBufVA,
-	OUT	UINT		 *pSrcBufLen);
-
-
-BOOLEAN RTMP_FillTxBlkInfo(
-	IN RTMP_ADAPTER *pAd,
-	IN TX_BLK *pTxBlk);
-
-
-PRTMP_SCATTER_GATHER_LIST
-rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg);
-
-
- void announce_802_3_packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket);
-
-
-UINT BA_Reorder_AMSDU_Annnounce(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket);
-
-
-UINT Handle_AMSDU_Packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pData,
-	IN	ULONG			DataSize,
-	IN  UCHAR			FromWhichBSSID);
-
-
-void convert_802_11_to_802_3_packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket,
-	IN	PUCHAR			p8023hdr,
-	IN	PUCHAR			pData,
-	IN	ULONG			DataSize,
-	IN  UCHAR			FromWhichBSSID);
-
-
-PNET_DEV get_netdev_from_bssid(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			FromWhichBSSID);
-
-
-PNDIS_PACKET duplicate_pkt(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pHeader802_3,
-    IN  UINT            HdrLen,
-	IN	PUCHAR			pData,
-	IN	ULONG			DataSize,
-	IN	UCHAR			FromWhichBSSID);
-
-
-PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pOldPkt);
-
-PNDIS_PACKET duplicate_pkt_with_VLAN(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pHeader802_3,
-    IN  UINT            HdrLen,
-	IN	PUCHAR			pData,
-	IN	ULONG			DataSize,
-	IN	UCHAR			FromWhichBSSID);
-
-
-UCHAR VLAN_8023_Header_Copy(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pHeader802_3,
-	IN	UINT            HdrLen,
-	OUT PUCHAR			pData,
-	IN	UCHAR			FromWhichBSSID);
-
-#ifdef DOT11_N_SUPPORT
-void ba_flush_reordering_timeout_mpdus(
-	IN PRTMP_ADAPTER	pAd,
-	IN PBA_REC_ENTRY	pBAEntry,
-	IN ULONG			Now32);
-
-
-VOID BAOriSessionSetUp(
-			IN PRTMP_ADAPTER    pAd,
-			IN MAC_TABLE_ENTRY	*pEntry,
-			IN UCHAR			TID,
-			IN USHORT			TimeOut,
-			IN ULONG			DelayTime,
-			IN BOOLEAN		isForced);
-
-VOID BASessionTearDownALL(
-	IN OUT	PRTMP_ADAPTER pAd,
-	IN		UCHAR Wcid);
-#endif // DOT11_N_SUPPORT //
-
-BOOLEAN OS_Need_Clone_Packet(void);
-
-
-VOID build_tx_packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket,
-	IN	PUCHAR	pFrame,
-	IN	ULONG	FrameLen);
-
-
-VOID BAOriSessionTearDown(
-	IN OUT	PRTMP_ADAPTER	pAd,
-	IN		UCHAR			Wcid,
-	IN		UCHAR			TID,
-	IN		BOOLEAN			bPassive,
-	IN		BOOLEAN			bForceSend);
-
-VOID BARecSessionTearDown(
-	IN OUT	PRTMP_ADAPTER	pAd,
-	IN		UCHAR			Wcid,
-	IN		UCHAR			TID,
-	IN		BOOLEAN			bPassive);
-
-BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num);
-void ba_reordering_resource_release(PRTMP_ADAPTER pAd);
-
-
-
-#ifdef NINTENDO_AP
-VOID	InitNINTENDO_TABLE(
-	IN PRTMP_ADAPTER pAd);
-
-UCHAR	CheckNINTENDO_TABLE(
-	IN PRTMP_ADAPTER pAd,
-	PCHAR pDS_Ssid,
-	UCHAR DS_SsidLen,
-	PUCHAR pDS_Addr);
-
-UCHAR	DelNINTENDO_ENTRY(
-	IN	PRTMP_ADAPTER pAd,
-	UCHAR * pDS_Addr);
-
-VOID	RTMPIoctlNintendoCapable(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	struct iwreq	*wrq);
-
-VOID	RTMPIoctlNintendoGetTable(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	struct iwreq	*wrq);
-
-VOID	RTMPIoctlNintendoSetTable(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	struct iwreq	*wrq);
-
-#endif // NINTENDO_AP //
-
-BOOLEAN rtstrmactohex(
-	IN PSTRING s1,
-	IN PSTRING s2);
-
-BOOLEAN rtstrcasecmp(
-	IN PSTRING s1,
-	IN PSTRING s2);
-
-PSTRING rtstrstruncasecmp(
-	IN PSTRING s1,
-	IN PSTRING s2);
-
-PSTRING rtstrstr(
-	IN	const PSTRING s1,
-	IN	const PSTRING s2);
-
-PSTRING rstrtok(
-	IN PSTRING s,
-	IN const PSTRING ct);
-
-int rtinet_aton(
-	const PSTRING cp,
-	unsigned int *addr);
-
-////////// common ioctl functions //////////
-INT Set_DriverVersion_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT Set_CountryRegion_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT Set_CountryRegionABand_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT Set_WirelessMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT Set_Channel_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_ShortSlot_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_TxPower_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT Set_BGProtection_Proc(
-	IN  PRTMP_ADAPTER		pAd,
-	IN  PSTRING			arg);
-
-INT Set_TxPreamble_Proc(
-	IN  PRTMP_ADAPTER		pAd,
-	IN  PSTRING			arg);
-
-INT Set_RTSThreshold_Proc(
-	IN  PRTMP_ADAPTER		pAd,
-	IN  PSTRING			arg);
-
-INT Set_FragThreshold_Proc(
-	IN  PRTMP_ADAPTER		pAd,
-	IN  PSTRING			arg);
-
-INT Set_TxBurst_Proc(
-	IN  PRTMP_ADAPTER		pAd,
-	IN  PSTRING			arg);
-
-#ifdef AGGREGATION_SUPPORT
-INT	Set_PktAggregate_Proc(
-	IN  PRTMP_ADAPTER		pAd,
-	IN  PSTRING			arg);
-#endif // AGGREGATION_SUPPORT //
-
-#ifdef INF_AMAZON_PPA
-INT	Set_INF_AMAZON_SE_PPA_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-
-#endif // INF_AMAZON_PPA //
-
-INT	Set_IEEE80211H_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-#ifdef DBG
-INT	Set_Debug_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-#endif
-
-INT	Show_DescInfo_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_ResetStatCounter_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-#ifdef DOT11_N_SUPPORT
-INT	Set_BASetup_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_BADecline_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_BAOriTearDown_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_BARecTearDown_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_HtBw_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_HtMcs_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_HtGi_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_HtOpMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_HtStbc_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_HtHtc_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_HtExtcha_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_HtMpduDensity_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_HtBaWinSize_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_HtRdg_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_HtLinkAdapt_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_HtAmsdu_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_HtAutoBa_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_HtProtect_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_HtMimoPs_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-
-INT	Set_ForceShortGI_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_ForceGF_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	SetCommonHT(
-	IN	PRTMP_ADAPTER	pAd);
-
-INT	Set_SendPSMPAction_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_HtMIMOPSmode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-
-INT	Set_HtTxBASize_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT	Set_HtDisallowTKIP_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-#endif // DOT11_N_SUPPORT //
-
-
-
-#ifdef CONFIG_STA_SUPPORT
-//Dls ,	kathy
-VOID RTMPSendDLSTearDownFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pDA);
-
-#ifdef DOT11_N_SUPPORT
-//Block ACK
-VOID QueryBATABLE(
-	IN  PRTMP_ADAPTER pAd,
-	OUT PQUERYBA_TABLE pBAT);
-#endif // DOT11_N_SUPPORT //
-
-#ifdef WPA_SUPPLICANT_SUPPORT
-INT	    WpaCheckEapCode(
-	IN  PRTMP_ADAPTER	pAd,
-	IN  PUCHAR				pFrame,
-	IN  USHORT				FrameLen,
-	IN  USHORT				OffSet);
-
-VOID    WpaSendMicFailureToWpaSupplicant(
-    IN  PRTMP_ADAPTER       pAd,
-    IN  BOOLEAN             bUnicast);
-
-VOID    SendAssocIEsToWpaSupplicant(
-    IN  PRTMP_ADAPTER       pAd);
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-int wext_notify_event_assoc(
-	IN  RTMP_ADAPTER *pAd);
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-
-#endif // CONFIG_STA_SUPPORT //
-
-
-
-#ifdef DOT11_N_SUPPORT
-VOID Handle_BSS_Width_Trigger_Events(
-	IN PRTMP_ADAPTER pAd);
-
-void build_ext_channel_switch_ie(
-	IN PRTMP_ADAPTER pAd,
-	IN HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE *pIE);
-#endif // DOT11_N_SUPPORT //
-
-
-BOOLEAN APRxDoneInterruptHandle(
-	IN	PRTMP_ADAPTER	pAd);
-
-BOOLEAN STARxDoneInterruptHandle(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	BOOLEAN			argc);
-
-#ifdef DOT11_N_SUPPORT
-// AMPDU packet indication
-VOID Indicate_AMPDU_Packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID);
-
-// AMSDU packet indication
-VOID Indicate_AMSDU_Packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID);
-#endif // DOT11_N_SUPPORT //
-
-// Normal legacy Rx packet indication
-VOID Indicate_Legacy_Packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID);
-
-VOID Indicate_EAPOL_Packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID);
-
-void  update_os_packet_info(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID);
-
-void wlan_802_11_to_802_3_packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	PUCHAR			pHeader802_3,
-	IN  UCHAR			FromWhichBSSID);
-
-UINT deaggregate_AMSDU_announce(
-	IN	PRTMP_ADAPTER	pAd,
-	PNDIS_PACKET		pPacket,
-	IN	PUCHAR			pData,
-	IN	ULONG			DataSize);
-
-
-#ifdef CONFIG_STA_SUPPORT
-// remove LLC and get 802_3 Header
-#define  RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(_pRxBlk, _pHeader802_3)	\
-{																				\
-	PUCHAR _pRemovedLLCSNAP = NULL, _pDA, _pSA;                                 \
-																				\
-	if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_MESH))                                    \
-	{                                                                           \
-		_pDA = _pRxBlk->pHeader->Addr3;                                         \
-		_pSA = (PUCHAR)_pRxBlk->pHeader + sizeof(HEADER_802_11);                \
-	}                                                                           \
-	else                                                                        \
-	{                                                                           \
-		if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_INFRA))				\
-		{                                                                       \
-			_pDA = _pRxBlk->pHeader->Addr1;                                     \
-		if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_DLS))									\
-			_pSA = _pRxBlk->pHeader->Addr2;										\
-		else																	\
-			_pSA = _pRxBlk->pHeader->Addr3;                                     \
-		}                                                                       \
-		else                                                                    \
-		{                                                                       \
-			_pDA = _pRxBlk->pHeader->Addr1;                                     \
-			_pSA = _pRxBlk->pHeader->Addr2;                                     \
-		}                                                                       \
-	}                                                                           \
-																				\
-	CONVERT_TO_802_3(_pHeader802_3, _pDA, _pSA, _pRxBlk->pData,				\
-		_pRxBlk->DataSize, _pRemovedLLCSNAP);                                   \
-}
-#endif // CONFIG_STA_SUPPORT //
-
-
-BOOLEAN APFowardWirelessStaToWirelessSta(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket,
-	IN	ULONG			FromWhichBSSID);
-
-VOID Announce_or_Forward_802_3_Packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket,
-	IN	UCHAR			FromWhichBSSID);
-
-VOID Sta_Announce_or_Forward_802_3_Packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket,
-	IN	UCHAR			FromWhichBSSID);
-
-
-#ifdef CONFIG_STA_SUPPORT
-#define ANNOUNCE_OR_FORWARD_802_3_PACKET(_pAd, _pPacket, _FromWhichBSS)\
-			Sta_Announce_or_Forward_802_3_Packet(_pAd, _pPacket, _FromWhichBSS);
-			//announce_802_3_packet(_pAd, _pPacket);
-#endif // CONFIG_STA_SUPPORT //
-
-
-PNDIS_PACKET DuplicatePacket(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket,
-	IN	UCHAR			FromWhichBSSID);
-
-
-PNDIS_PACKET ClonePacket(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket,
-	IN	PUCHAR			pData,
-	IN	ULONG			DataSize);
-
-
-// Normal, AMPDU or AMSDU
-VOID CmmRxnonRalinkFrameIndicate(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID);
-
-VOID CmmRxRalinkFrameIndicate(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MAC_TABLE_ENTRY	*pEntry,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID);
-
-VOID Update_Rssi_Sample(
-	IN PRTMP_ADAPTER	pAd,
-	IN RSSI_SAMPLE		*pRssi,
-	IN PRXWI_STRUC		pRxWI);
-
-PNDIS_PACKET GetPacketFromRxRing(
-	IN		PRTMP_ADAPTER	pAd,
-	OUT		PRT28XX_RXD_STRUC		pSaveRxD,
-	OUT		BOOLEAN			*pbReschedule,
-	IN OUT	UINT32			*pRxPending);
-
-PNDIS_PACKET RTMPDeFragmentDataFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk);
-
-////////////////////////////////////////
-
-VOID RTMPIoctlGetSiteSurvey(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq);
-
-
-
-
-
-#ifdef SNMP_SUPPORT
-//for snmp , kathy
-typedef struct _DefaultKeyIdxValue
-{
-	UCHAR	KeyIdx;
-	UCHAR	Value[16];
-} DefaultKeyIdxValue, *PDefaultKeyIdxValue;
-#endif
-
-
-#ifdef CONFIG_STA_SUPPORT
-enum {
-	DIDmsg_lnxind_wlansniffrm		= 0x00000044,
-	DIDmsg_lnxind_wlansniffrm_hosttime	= 0x00010044,
-	DIDmsg_lnxind_wlansniffrm_mactime	= 0x00020044,
-	DIDmsg_lnxind_wlansniffrm_channel	= 0x00030044,
-	DIDmsg_lnxind_wlansniffrm_rssi		= 0x00040044,
-	DIDmsg_lnxind_wlansniffrm_sq		= 0x00050044,
-	DIDmsg_lnxind_wlansniffrm_signal	= 0x00060044,
-	DIDmsg_lnxind_wlansniffrm_noise		= 0x00070044,
-	DIDmsg_lnxind_wlansniffrm_rate		= 0x00080044,
-	DIDmsg_lnxind_wlansniffrm_istx		= 0x00090044,
-	DIDmsg_lnxind_wlansniffrm_frmlen	= 0x000A0044
-};
-enum {
-	P80211ENUM_msgitem_status_no_value	= 0x00
-};
-enum {
-	P80211ENUM_truth_false			= 0x00,
-	P80211ENUM_truth_true			= 0x01
-};
-
-/* Definition from madwifi */
-typedef struct {
-        UINT32 did;
-        UINT16 status;
-        UINT16 len;
-        UINT32 data;
-} p80211item_uint32_t;
-
-typedef struct {
-        UINT32 msgcode;
-        UINT32 msglen;
-#define WLAN_DEVNAMELEN_MAX 16
-        UINT8 devname[WLAN_DEVNAMELEN_MAX];
-        p80211item_uint32_t hosttime;
-        p80211item_uint32_t mactime;
-        p80211item_uint32_t channel;
-        p80211item_uint32_t rssi;
-        p80211item_uint32_t sq;
-        p80211item_uint32_t signal;
-        p80211item_uint32_t noise;
-        p80211item_uint32_t rate;
-        p80211item_uint32_t istx;
-        p80211item_uint32_t frmlen;
-} wlan_ng_prism2_header;
-
-/* The radio capture header precedes the 802.11 header. */
-typedef struct PACKED _ieee80211_radiotap_header {
-    UINT8	it_version;	/* Version 0. Only increases
-				 * for drastic changes,
-				 * introduction of compatible
-				 * new fields does not count.
-				 */
-    UINT8	it_pad;
-    UINT16     it_len;         /* length of the whole
-				 * header in bytes, including
-				 * it_version, it_pad,
-				 * it_len, and data fields.
-				 */
-    UINT32   it_present;	/* A bitmap telling which
-					 * fields are present. Set bit 31
-					 * (0x80000000) to extend the
-					 * bitmap by another 32 bits.
-					 * Additional extensions are made
-					 * by setting bit 31.
-					 */
-}ieee80211_radiotap_header ;
-
-enum ieee80211_radiotap_type {
-    IEEE80211_RADIOTAP_TSFT = 0,
-    IEEE80211_RADIOTAP_FLAGS = 1,
-    IEEE80211_RADIOTAP_RATE = 2,
-    IEEE80211_RADIOTAP_CHANNEL = 3,
-    IEEE80211_RADIOTAP_FHSS = 4,
-    IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
-    IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
-    IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
-    IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
-    IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
-    IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
-    IEEE80211_RADIOTAP_ANTENNA = 11,
-    IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
-    IEEE80211_RADIOTAP_DB_ANTNOISE = 13
-};
-
-#define WLAN_RADIOTAP_PRESENT (			\
-	(1 << IEEE80211_RADIOTAP_TSFT)	|	\
-	(1 << IEEE80211_RADIOTAP_FLAGS) |	\
-	(1 << IEEE80211_RADIOTAP_RATE)  |	\
-	 0)
-
-typedef struct _wlan_radiotap_header {
-	ieee80211_radiotap_header wt_ihdr;
-	INT64 wt_tsft;
-	UINT8 wt_flags;
-	UINT8 wt_rate;
-} wlan_radiotap_header;
-/* Definition from madwifi */
-
-void send_monitor_packets(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk);
-
-
-VOID    RTMPSetDesiredRates(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  LONG            Rates);
-#endif // CONFIG_STA_SUPPORT //
-
-INT	Set_FixedTxMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-#ifdef CONFIG_APSTA_MIXED_SUPPORT
-INT	Set_OpMode_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-#endif // CONFIG_APSTA_MIXED_SUPPORT //
-
-INT Set_LongRetryLimit_Proc(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	PSTRING			arg);
-
-INT Set_ShortRetryLimit_Proc(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	PSTRING			arg);
-
-BOOLEAN RT28XXChipsetCheck(
-	IN void *_dev_p);
-
-
-VOID RT28XXDMADisable(
-	IN RTMP_ADAPTER			*pAd);
-
-VOID RT28XXDMAEnable(
-	IN RTMP_ADAPTER			*pAd);
-
-VOID RT28xx_UpdateBeaconToAsic(
-	IN RTMP_ADAPTER * pAd,
-	IN INT apidx,
-	IN ULONG BeaconLen,
-	IN ULONG UpdatePos);
-
-int rt28xx_init(
-	IN PRTMP_ADAPTER pAd,
-	IN PSTRING pDefaultMac,
-	IN PSTRING pHostName);
-
-BOOLEAN RT28XXSecurityKeyAdd(
-	IN		PRTMP_ADAPTER		pAd,
-	IN		ULONG				apidx,
-	IN		ULONG				KeyIdx,
-	IN		MAC_TABLE_ENTRY		*pEntry);
-
-NDIS_STATUS RtmpNetTaskInit(
-	IN RTMP_ADAPTER *pAd);
-
-VOID RtmpNetTaskExit(
-	IN PRTMP_ADAPTER pAd);
-
-NDIS_STATUS RtmpMgmtTaskInit(
-	IN RTMP_ADAPTER *pAd);
-
-VOID RtmpMgmtTaskExit(
-	IN RTMP_ADAPTER *pAd);
-
-void tbtt_tasklet(unsigned long data);
-
-
-PNET_DEV RtmpPhyNetDevInit(
-	IN RTMP_ADAPTER *pAd,
-	IN RTMP_OS_NETDEV_OP_HOOK *pNetHook);
-
-BOOLEAN RtmpPhyNetDevExit(
-	IN RTMP_ADAPTER *pAd,
-	IN PNET_DEV net_dev);
-
-INT RtmpRaDevCtrlInit(
-	IN RTMP_ADAPTER *pAd,
-	IN RTMP_INF_TYPE infType);
-
-BOOLEAN RtmpRaDevCtrlExit(
-	IN RTMP_ADAPTER *pAd);
-
-
-#ifdef RTMP_MAC_PCI
-//
-// Function Prototype in cmm_data_pci.c
-//
-USHORT RtmpPCI_WriteTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	BOOLEAN			bIsLast,
-	OUT	USHORT			*FreeNumber);
-
-USHORT RtmpPCI_WriteSingleTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	BOOLEAN			bIsLast,
-	OUT	USHORT			*FreeNumber);
-
-USHORT RtmpPCI_WriteMultiTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	UCHAR			frameNum,
-	OUT	USHORT			*FreeNumber);
-
-USHORT	RtmpPCI_WriteFragTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	UCHAR			fragNum,
-	OUT	USHORT			*FreeNumber);
-
-USHORT RtmpPCI_WriteSubTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	BOOLEAN			bIsLast,
-	OUT	USHORT			*FreeNumber);
-
-VOID RtmpPCI_FinalWriteTxResource(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	USHORT			totalMPDUSize,
-	IN	USHORT			FirstTxIdx);
-
-VOID RtmpPCIDataLastTxIdx(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			QueIdx,
-	IN	USHORT			LastTxIdx);
-
-VOID RtmpPCIDataKickOut(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk,
-	IN	UCHAR			QueIdx);
-
-
-int RtmpPCIMgmtKickOut(
-	IN RTMP_ADAPTER		*pAd,
-	IN UCHAR			QueIdx,
-	IN PNDIS_PACKET		pPacket,
-	IN PUCHAR			pSrcBufVA,
-	IN UINT				SrcBufLen);
-
-
-NDIS_STATUS RTMPCheckRxError(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PHEADER_802_11  pHeader,
-	IN	PRXWI_STRUC	pRxWI,
-	IN  PRT28XX_RXD_STRUC      pRxD);
-
-BOOLEAN RT28xxPciAsicRadioOff(
-	IN PRTMP_ADAPTER    pAd,
-	IN UCHAR            Level,
-	IN USHORT           TbttNumToNextWakeUp);
-
-BOOLEAN RT28xxPciAsicRadioOn(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR     Level);
-
-#ifdef CONFIG_STA_SUPPORT
-VOID RTMPInitPCIeLinkCtrlValue(
-	IN	PRTMP_ADAPTER	pAd);
-
-VOID RTMPFindHostPCIDev(
-    IN	PRTMP_ADAPTER	pAd);
-
-VOID RTMPPCIeLinkCtrlValueRestore(
-	IN	PRTMP_ADAPTER	pAd,
-	IN   UCHAR		Level);
-
-VOID RTMPPCIeLinkCtrlSetting(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT		Max);
-
-VOID RTMPrt3xSetPCIePowerLinkCtrl(
-	IN	PRTMP_ADAPTER	pAd);
-
-
-VOID RT28xxPciStaAsicForceWakeup(
-	IN PRTMP_ADAPTER pAd,
-	IN BOOLEAN       bFromTx);
-
-VOID RT28xxPciStaAsicSleepThenAutoWakeup(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT TbttNumToNextWakeUp);
-
-VOID PsPollWakeExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
-
-VOID  RadioOnExec(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3);
-#endif // CONFIG_STA_SUPPORT //
-
-VOID RT28xxPciMlmeRadioOn(
-	IN PRTMP_ADAPTER pAd);
-
-VOID RT28xxPciMlmeRadioOFF(
-	IN PRTMP_ADAPTER pAd);
-#endif // RTMP_MAC_PCI //
-
-VOID AsicTurnOffRFClk(
-	IN PRTMP_ADAPTER    pAd,
-	IN	UCHAR           Channel);
-
-VOID AsicTurnOnRFClk(
-	IN PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Channel);
-
-
-
-#ifdef RTMP_TIMER_TASK_SUPPORT
-INT RtmpTimerQThread(
-	IN OUT PVOID Context);
-
-RTMP_TIMER_TASK_ENTRY *RtmpTimerQInsert(
-	IN RTMP_ADAPTER *pAd,
-	IN RALINK_TIMER_STRUCT *pTimer);
-
-BOOLEAN RtmpTimerQRemove(
-	IN RTMP_ADAPTER *pAd,
-	IN RALINK_TIMER_STRUCT *pTimer);
-
-void RtmpTimerQExit(
-	IN RTMP_ADAPTER *pAd);
-
-void RtmpTimerQInit(
-	IN RTMP_ADAPTER *pAd);
-#endif // RTMP_TIMER_TASK_SUPPORT //
-
-
-
-////////////////////////////////////////
-
-VOID QBSS_LoadInit(
-	IN		RTMP_ADAPTER	*pAd);
-
-UINT32 QBSS_LoadElementAppend(
-	IN		RTMP_ADAPTER	*pAd,
-	OUT		UINT8			*buf_p);
-
-VOID QBSS_LoadUpdate(
-	IN		RTMP_ADAPTER	*pAd);
-
-///////////////////////////////////////
-INT RTMPShowCfgValue(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			pName,
-	IN	PSTRING			pBuf);
-
-PSTRING RTMPGetRalinkAuthModeStr(
-    IN  NDIS_802_11_AUTHENTICATION_MODE authMode);
-
-PSTRING RTMPGetRalinkEncryModeStr(
-    IN  USHORT encryMode);
-//////////////////////////////////////
-
-#ifdef CONFIG_STA_SUPPORT
-VOID AsicStaBbpTuning(
-	IN PRTMP_ADAPTER pAd);
-
-BOOLEAN StaAddMacTableEntry(
-	IN  PRTMP_ADAPTER		pAd,
-	IN  PMAC_TABLE_ENTRY	pEntry,
-	IN  UCHAR				MaxSupportedRateIn500Kbps,
-	IN  HT_CAPABILITY_IE	*pHtCapability,
-	IN  UCHAR				HtCapabilityLen,
-	IN  ADD_HT_INFO_IE		*pAddHtInfo,
-	IN  UCHAR				AddHtInfoLen,
-	IN  USHORT			CapabilityInfo);
-
-
-BOOLEAN	AUTH_ReqSend(
-	IN  PRTMP_ADAPTER		pAd,
-	IN  PMLME_QUEUE_ELEM	pElem,
-	IN  PRALINK_TIMER_STRUCT pAuthTimer,
-	IN  PSTRING				pSMName,
-	IN  USHORT				SeqNo,
-	IN  PUCHAR				pNewElement,
-	IN  ULONG				ElementLen);
-#endif // CONFIG_STA_SUPPORT //
-
-void RTMP_IndicateMediaState(
-	IN	PRTMP_ADAPTER	pAd);
-
-VOID ReSyncBeaconTime(
-	IN  PRTMP_ADAPTER   pAd);
-
-VOID RTMPSetAGCInitValue(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			BandWidth);
-
-int rt28xx_close(IN PNET_DEV dev);
-int rt28xx_open(IN PNET_DEV dev);
-
-
-#define VIRTUAL_IF_INC(__pAd) ((__pAd)->VirtualIfCnt++)
-#define VIRTUAL_IF_DEC(__pAd) ((__pAd)->VirtualIfCnt--)
-#define VIRTUAL_IF_NUM(__pAd) ((__pAd)->VirtualIfCnt)
-
-
-#ifdef LINUX
-__inline INT VIRTUAL_IF_UP(PRTMP_ADAPTER pAd)
-{
-	if (VIRTUAL_IF_NUM(pAd) == 0)
-	{
-		if (rt28xx_open(pAd->net_dev) != 0)
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_open return fail!\n"));
-			return -1;
-		}
-	}
-	else
-	{
-	}
-	VIRTUAL_IF_INC(pAd);
-	return 0;
-}
-
-__inline VOID VIRTUAL_IF_DOWN(PRTMP_ADAPTER pAd)
-{
-	VIRTUAL_IF_DEC(pAd);
-	if (VIRTUAL_IF_NUM(pAd) == 0)
-		rt28xx_close(pAd->net_dev);
-	return;
-}
-#endif // LINUX //
-
-
-
-
-/*
-	OS Related funciton prototype definitions.
-	TODO: Maybe we need to move these function prototypes to other proper place.
-*/
-int RtmpOSWrielessEventSend(
-	IN RTMP_ADAPTER *pAd,
-	IN UINT32		eventType,
-	IN INT			flags,
-	IN PUCHAR		pSrcMac,
-	IN PUCHAR		pData,
-	IN UINT32		dataLen);
-
-int RtmpOSNetDevAddrSet(
-	IN PNET_DEV pNetDev,
-	IN PUCHAR	pMacAddr);
-
-int RtmpOSNetDevAttach(
-	IN PNET_DEV pNetDev,
-	IN RTMP_OS_NETDEV_OP_HOOK *pDevOpHook);
-
-void RtmpOSNetDevClose(
-	IN PNET_DEV pNetDev);
-
-void RtmpOSNetDevDetach(
-	IN PNET_DEV pNetDev);
-
-INT RtmpOSNetDevAlloc(
-	IN PNET_DEV *pNewNetDev,
-	IN UINT32	privDataSize);
-
-void RtmpOSNetDevFree(
-	IN PNET_DEV pNetDev);
-
-PNET_DEV RtmpOSNetDevGetByName(
-	IN PNET_DEV pNetDev,
-	IN PSTRING	pDevName);
-
-void RtmpOSNetDeviceRefPut(
-	IN PNET_DEV pNetDev);
-
-PNET_DEV RtmpOSNetDevCreate(
-	IN RTMP_ADAPTER *pAd,
-	IN INT			devType,
-	IN INT			devNum,
-	IN INT			privMemSize,
-	IN PSTRING		pNamePrefix);
-
-/*
-	Task operation related function prototypes
-*/
-void RtmpOSTaskCustomize(
-	IN RTMP_OS_TASK *pTask);
-
-INT RtmpOSTaskNotifyToExit(
-	IN RTMP_OS_TASK *pTask);
-
-NDIS_STATUS RtmpOSTaskKill(
-	IN RTMP_OS_TASK *pTask);
-
-NDIS_STATUS RtmpOSTaskInit(
-	IN RTMP_OS_TASK *pTask,
-	PSTRING			 pTaskName,
-	VOID			 *pPriv);
-
-NDIS_STATUS RtmpOSTaskAttach(
-	IN RTMP_OS_TASK *pTask,
-	IN int (*fn)(void *),
-	IN void *arg);
-
-
-/*
-	File operation related function prototypes
-*/
-RTMP_OS_FD RtmpOSFileOpen(
-	IN char *pPath,
-	IN int flag,
-	IN int mode);
-
-int RtmpOSFileClose(
-	IN RTMP_OS_FD osfd);
-
-void RtmpOSFileSeek(
-	IN RTMP_OS_FD osfd,
-	IN int offset);
-
-int RtmpOSFileRead(
-	IN RTMP_OS_FD osfd,
-	IN char *pDataPtr,
-	IN int readLen);
-
-int RtmpOSFileWrite(
-	IN RTMP_OS_FD osfd,
-	IN char *pDataPtr,
-	IN int writeLen);
-
-void RtmpOSFSInfoChange(
-	IN RTMP_OS_FS_INFO *pOSFSInfo,
-	IN BOOLEAN bSet);
-
-
-#endif  // __RTMP_H__
diff --git a/drivers/staging/rt3090/rtmp_chip.h b/drivers/staging/rt3090/rtmp_chip.h
deleted file mode 100644
index a0b4bf0..0000000
--- a/drivers/staging/rt3090/rtmp_chip.h
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtmp_chip.h
-
-	Abstract:
-	Ralink Wireless Chip related definition & structures
-
-	Revision History:
-	Who			When		  What
-	--------	----------	  ----------------------------------------------
-*/
-
-#ifndef	__RTMP_CHIP_H__
-#define	__RTMP_CHIP_H__
-
-#include "rtmp_type.h"
-
-#ifdef RT3090
-#include "rt3090.h"
-#endif // RT3090 //
-
-#ifdef RT3370
-#include "rt3370.h"
-#endif // RT3370 //
-
-#ifdef RT3390
-#include "rt3390.h"
-#endif // RT3390 //
-
-// We will have a cost down version which mac version is 0x3090xxxx
-//
-// RT3090A facts
-//
-// a) 2.4 GHz
-// b) Replacement for RT3090
-// c) Internal LNA
-// d) Interference over channel #14
-// e) New BBP features (e.g., SIG re-modulation)
-//
-#define IS_RT3090A(_pAd)				((((_pAd)->MACVersion & 0xffff0000) == 0x30900000))
-
-// We will have a cost down version which mac version is 0x3090xxxx
-#define IS_RT3090(_pAd)				((((_pAd)->MACVersion & 0xffff0000) == 0x30710000) || (IS_RT3090A(_pAd)))
-
-#define IS_RT3070(_pAd)		(((_pAd)->MACVersion & 0xffff0000) == 0x30700000)
-#define IS_RT3071(_pAd)		(((_pAd)->MACVersion & 0xffff0000) == 0x30710000)
-#define IS_RT2070(_pAd)		(((_pAd)->RfIcType == RFIC_2020) || ((_pAd)->EFuseTag == 0x27))
-
-#define IS_RT30xx(_pAd)		(((_pAd)->MACVersion & 0xfff00000) == 0x30700000||IS_RT3090A(_pAd))
-//#define IS_RT305X(_pAd)		((_pAd)->MACVersion == 0x28720200)
-
-/* RT3572, 3592, 3562, 3062 share the same MAC version */
-#define IS_RT3572(_pAd)		(((_pAd)->MACVersion & 0xffff0000) == 0x35720000)
-#define IS_VERSION_BEFORE_F(_pAd)			(((_pAd)->MACVersion&0xffff) <= 0x0211)
-// F version is 0x0212, E version is 0x0211. 309x can save more power after F version.
-#define IS_VERSION_AFTER_F(_pAd)			((((_pAd)->MACVersion&0xffff) >= 0x0212) || (((_pAd)->b3090ESpecialChip == TRUE)))
-//
-// RT3390 facts
-//
-// a) Base on RT3090 (RF IC: RT3020)
-// b) 2.4 GHz
-// c) 1x1
-// d) Single chip
-// e) Internal components: PA and LNA
-//
-//RT3390,RT3370
-#define IS_RT3390(_pAd)				(((_pAd)->MACVersion & 0xFFFF0000) == 0x33900000)
-
-// ------------------------------------------------------
-// PCI registers - base address 0x0000
-// ------------------------------------------------------
-#define CHIP_PCI_CFG		0x0000
-#define CHIP_PCI_EECTRL		0x0004
-#define CHIP_PCI_MCUCTRL	0x0008
-
-#define OPT_14			0x114
-
-#define RETRY_LIMIT		10
-
-
-
-// ------------------------------------------------------
-// BBP & RF	definition
-// ------------------------------------------------------
-#define	BUSY		                1
-#define	IDLE		                0
-
-
-//-------------------------------------------------------------------------
-// EEPROM definition
-//-------------------------------------------------------------------------
-#define EEDO                        0x08
-#define EEDI                        0x04
-#define EECS                        0x02
-#define EESK                        0x01
-#define EERL                        0x80
-
-#define EEPROM_WRITE_OPCODE         0x05
-#define EEPROM_READ_OPCODE          0x06
-#define EEPROM_EWDS_OPCODE          0x10
-#define EEPROM_EWEN_OPCODE          0x13
-
-#define NUM_EEPROM_BBP_PARMS		19			// Include NIC Config 0, 1, CR, TX ALC step, BBPs
-#define NUM_EEPROM_TX_G_PARMS		7
-#define EEPROM_NIC1_OFFSET          0x34		// The address is from NIC config 0, not BBP register ID
-#define EEPROM_NIC2_OFFSET          0x36		// The address is from NIC config 0, not BBP register ID
-#define EEPROM_BBP_BASE_OFFSET		0xf0		// The address is from NIC config 0, not BBP register ID
-#define EEPROM_G_TX_PWR_OFFSET		0x52
-#define EEPROM_G_TX2_PWR_OFFSET		0x60
-#define EEPROM_LED1_OFFSET			0x3c
-#define EEPROM_LED2_OFFSET			0x3e
-#define EEPROM_LED3_OFFSET			0x40
-#define EEPROM_LNA_OFFSET			0x44
-#define EEPROM_RSSI_BG_OFFSET		0x46
-#define EEPROM_TXMIXER_GAIN_2_4G	0x48
-#define EEPROM_RSSI_A_OFFSET		0x4a
-#define EEPROM_TXMIXER_GAIN_5G		0x4c
-#define EEPROM_DEFINE_MAX_TXPWR		0x4e
-#define EEPROM_TXPOWER_BYRATE_20MHZ_2_4G	0xde	// 20MHZ 2.4G tx power.
-#define EEPROM_TXPOWER_BYRATE_40MHZ_2_4G	0xee	// 40MHZ 2.4G tx power.
-#define EEPROM_TXPOWER_BYRATE_20MHZ_5G		0xfa	// 20MHZ 5G tx power.
-#define EEPROM_TXPOWER_BYRATE_40MHZ_5G		0x10a	// 40MHZ 5G tx power.
-#define EEPROM_A_TX_PWR_OFFSET      0x78
-#define EEPROM_A_TX2_PWR_OFFSET      0xa6
-//#define EEPROM_Japan_TX_PWR_OFFSET      0x90 // 802.11j
-//#define EEPROM_Japan_TX2_PWR_OFFSET      0xbe
-//#define EEPROM_TSSI_REF_OFFSET	0x54
-//#define EEPROM_TSSI_DELTA_OFFSET	0x24
-//#define EEPROM_CCK_TX_PWR_OFFSET  0x62
-//#define EEPROM_CALIBRATE_OFFSET	0x7c
-#define EEPROM_VERSION_OFFSET       0x02
-#define EEPROM_FREQ_OFFSET			0x3a
-#define EEPROM_TXPOWER_BYRATE	0xde	// 20MHZ power.
-#define EEPROM_TXPOWER_DELTA		0x50	// 20MHZ AND 40 MHZ use different power. This is delta in 40MHZ.
-#define VALID_EEPROM_VERSION        1
-
-
-/*
-  *   EEPROM operation related marcos
-  */
-#define RT28xx_EEPROM_READ16(_pAd, _offset, _value)			\
-	(_pAd)->chipOps.eeread((RTMP_ADAPTER *)(_pAd), (USHORT)(_offset), (PUSHORT)&(_value))
-
-#define RT28xx_EEPROM_WRITE16(_pAd, _offset, _value)		\
-	(_pAd)->chipOps.eewrite((RTMP_ADAPTER *)(_pAd), (USHORT)(_offset), (USHORT)(_value))
-
-
-
-// -------------------------------------------------------------------
-//  E2PROM data layout
-// -------------------------------------------------------------------
-
-//
-// MCU_LEDCS: MCU LED Control Setting.
-//
-typedef union  _MCU_LEDCS_STRUC {
-	struct	{
-#ifdef RT_BIG_ENDIAN
-		UCHAR		Polarity:1;
-		UCHAR		LedMode:7;
-#else
-		UCHAR		LedMode:7;
-		UCHAR		Polarity:1;
-#endif // RT_BIG_ENDIAN //
-	} field;
-	UCHAR				word;
-} MCU_LEDCS_STRUC, *PMCU_LEDCS_STRUC;
-
-
-//
-// EEPROM antenna select format
-//
-#ifdef RT_BIG_ENDIAN
-typedef	union	_EEPROM_ANTENNA_STRUC	{
-	struct	{
-		USHORT      Rsv:4;
-		USHORT      RfIcType:4;             // see E2PROM document
-		USHORT		TxPath:4;	// 1: 1T, 2: 2T
-		USHORT		RxPath:4;	// 1: 1R, 2: 2R, 3: 3R
-	}	field;
-	USHORT			word;
-}	EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC;
-#else
-typedef	union	_EEPROM_ANTENNA_STRUC	{
-	struct	{
-		USHORT		RxPath:4;	// 1: 1R, 2: 2R, 3: 3R
-		USHORT		TxPath:4;	// 1: 1T, 2: 2T
-		USHORT      RfIcType:4;             // see E2PROM document
-		USHORT      Rsv:4;
-	}	field;
-	USHORT			word;
-}	EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC;
-#endif
-
-#ifdef RT_BIG_ENDIAN
-typedef	union _EEPROM_NIC_CINFIG2_STRUC	{
-	struct	{
-		USHORT		DACTestBit:1;			// control if driver should patch the DAC issue
-		USHORT		Rsv2:3;					// must be 0
-		USHORT		AntDiversity:1;			// Antenna diversity
-		USHORT		Rsv1:1;					// must be 0
-		USHORT		BW40MAvailForA:1;			// 0:enable, 1:disable
-		USHORT		BW40MAvailForG:1;			// 0:enable, 1:disable
-		USHORT		EnableWPSPBC:1;                 // WPS PBC Control bit
-		USHORT		BW40MSidebandForA:1;
-		USHORT		BW40MSidebandForG:1;
-		USHORT		CardbusAcceleration:1;	// !!! NOTE: 0 - enable, 1 - disable
-		USHORT		ExternalLNAForA:1;			// external LNA enable for 5G
-		USHORT		ExternalLNAForG:1;			// external LNA enable for 2.4G
-		USHORT		DynamicTxAgcControl:1;			//
-		USHORT		HardwareRadioControl:1;	// Whether RF is controlled by driver or HW. 1:enable hw control, 0:disable
-	}	field;
-	USHORT			word;
-}	EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC;
-#else
-typedef	union _EEPROM_NIC_CINFIG2_STRUC	{
-	struct {
-		USHORT		HardwareRadioControl:1;	// 1:enable, 0:disable
-		USHORT		DynamicTxAgcControl:1;			//
-		USHORT		ExternalLNAForG:1;				//
-		USHORT		ExternalLNAForA:1;			// external LNA enable for 2.4G
-		USHORT		CardbusAcceleration:1;	// !!! NOTE: 0 - enable, 1 - disable
-		USHORT		BW40MSidebandForG:1;
-		USHORT		BW40MSidebandForA:1;
-		USHORT		EnableWPSPBC:1;                 // WPS PBC Control bit
-		USHORT		BW40MAvailForG:1;			// 0:enable, 1:disable
-		USHORT		BW40MAvailForA:1;			// 0:enable, 1:disable
-		USHORT		Rsv1:1;					// must be 0
-		USHORT		AntDiversity:1;			// Antenna diversity
-		USHORT		Rsv2:3;					// must be 0
-		USHORT		DACTestBit:1;			// control if driver should patch the DAC issue
-	}	field;
-	USHORT			word;
-}	EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC;
-#endif
-
-//
-// TX_PWR Value valid range 0xFA(-6) ~ 0x24(36)
-//
-#ifdef RT_BIG_ENDIAN
-typedef	union	_EEPROM_TX_PWR_STRUC	{
-	struct	{
-		CHAR	Byte1;				// High Byte
-		CHAR	Byte0;				// Low Byte
-	}	field;
-	USHORT	word;
-}	EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC;
-#else
-typedef	union	_EEPROM_TX_PWR_STRUC	{
-	struct	{
-		CHAR	Byte0;				// Low Byte
-		CHAR	Byte1;				// High Byte
-	}	field;
-	USHORT	word;
-}	EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC;
-#endif
-
-#ifdef RT_BIG_ENDIAN
-typedef	union	_EEPROM_VERSION_STRUC	{
-	struct	{
-		UCHAR	Version;			// High Byte
-		UCHAR	FaeReleaseNumber;	// Low Byte
-	}	field;
-	USHORT	word;
-}	EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC;
-#else
-typedef	union	_EEPROM_VERSION_STRUC	{
-	struct	{
-		UCHAR	FaeReleaseNumber;	// Low Byte
-		UCHAR	Version;			// High Byte
-	}	field;
-	USHORT	word;
-}	EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC;
-#endif
-
-#ifdef RT_BIG_ENDIAN
-typedef	union	_EEPROM_LED_STRUC	{
-	struct	{
-		USHORT	Rsvd:3;				// Reserved
-		USHORT	LedMode:5;			// Led mode.
-		USHORT	PolarityGPIO_4:1;	// Polarity GPIO#4 setting.
-		USHORT	PolarityGPIO_3:1;	// Polarity GPIO#3 setting.
-		USHORT	PolarityGPIO_2:1;	// Polarity GPIO#2 setting.
-		USHORT	PolarityGPIO_1:1;	// Polarity GPIO#1 setting.
-		USHORT	PolarityGPIO_0:1;	// Polarity GPIO#0 setting.
-		USHORT	PolarityACT:1;		// Polarity ACT setting.
-		USHORT	PolarityRDY_A:1;		// Polarity RDY_A setting.
-		USHORT	PolarityRDY_G:1;		// Polarity RDY_G setting.
-	}	field;
-	USHORT	word;
-}	EEPROM_LED_STRUC, *PEEPROM_LED_STRUC;
-#else
-typedef	union	_EEPROM_LED_STRUC	{
-	struct	{
-		USHORT	PolarityRDY_G:1;		// Polarity RDY_G setting.
-		USHORT	PolarityRDY_A:1;		// Polarity RDY_A setting.
-		USHORT	PolarityACT:1;		// Polarity ACT setting.
-		USHORT	PolarityGPIO_0:1;	// Polarity GPIO#0 setting.
-		USHORT	PolarityGPIO_1:1;	// Polarity GPIO#1 setting.
-		USHORT	PolarityGPIO_2:1;	// Polarity GPIO#2 setting.
-		USHORT	PolarityGPIO_3:1;	// Polarity GPIO#3 setting.
-		USHORT	PolarityGPIO_4:1;	// Polarity GPIO#4 setting.
-		USHORT	LedMode:5;			// Led mode.
-		USHORT	Rsvd:3;				// Reserved
-	}	field;
-	USHORT	word;
-}	EEPROM_LED_STRUC, *PEEPROM_LED_STRUC;
-#endif
-
-#ifdef RT_BIG_ENDIAN
-typedef	union	_EEPROM_TXPOWER_DELTA_STRUC	{
-	struct	{
-		UCHAR	TxPowerEnable:1;// Enable
-		UCHAR	Type:1;			// 1: plus the delta value, 0: minus the delta value
-		UCHAR	DeltaValue:6;	// Tx Power dalta value (MAX=4)
-	}	field;
-	UCHAR	value;
-}	EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC;
-#else
-typedef	union	_EEPROM_TXPOWER_DELTA_STRUC	{
-	struct	{
-		UCHAR	DeltaValue:6;	// Tx Power dalta value (MAX=4)
-		UCHAR	Type:1;			// 1: plus the delta value, 0: minus the delta value
-		UCHAR	TxPowerEnable:1;// Enable
-	}	field;
-	UCHAR	value;
-}	EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC;
-#endif
-
-#endif	// __RTMP_CHIP_H__ //
diff --git a/drivers/staging/rt3090/rtmp_def.h b/drivers/staging/rt3090/rtmp_def.h
deleted file mode 100644
index aeb739d..0000000
--- a/drivers/staging/rt3090/rtmp_def.h
+++ /dev/null
@@ -1,1650 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    rtmp_def.h
-
-    Abstract:
-    Miniport related definition header
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-    Paul Lin    08-01-2002    created
-    John Chang  08-05-2003    add definition for 11g & other drafts
-*/
-#ifndef __RTMP_DEF_H__
-#define __RTMP_DEF_H__
-
-#include "oid.h"
-
-#undef AP_WSC_INCLUDED
-#undef STA_WSC_INCLUDED
-#undef WSC_INCLUDED
-
-
-#ifdef CONFIG_STA_SUPPORT
-#endif // CONFIG_STA_SUPPORT //
-
-#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
-#define WSC_INCLUDED
-#endif
-//
-//  Debug information verbosity: lower values indicate higher urgency
-//
-#define RT_DEBUG_OFF        0
-#define RT_DEBUG_ERROR      1
-#define RT_DEBUG_WARN       2
-#define RT_DEBUG_TRACE      3
-#define RT_DEBUG_INFO       4
-#define RT_DEBUG_LOUD       5
-
-#define NIC_TAG             ((ULONG)'0682')
-#define NIC_DBG_STRING      ("**RT28xx**")
-
-#ifdef SNMP_SUPPORT
-// for snmp
-// to get manufacturer OUI, kathy, 2008_0220
-#define ManufacturerOUI_LEN			3
-#define ManufacturerNAME			("Ralink Technology Company.")
-#define	ResourceTypeIdName			("Ralink_ID")
-#endif
-
-
-//#define PACKED
-
-#define RALINK_2883_VERSION		((UINT32)0x28830300)
-#define RALINK_2880E_VERSION	((UINT32)0x28720200)
-#define RALINK_3070_VERSION		((UINT32)0x30700200)
-
-#define MAX_RX_PKT_LEN	1520
-
-//
-// Entry number for each DMA descriptor ring
-//
-
-#ifdef RTMP_MAC_PCI
-#define TX_RING_SIZE            64 //64
-#define MGMT_RING_SIZE          128
-#define RX_RING_SIZE            128 //64
-#define MAX_TX_PROCESS          TX_RING_SIZE //8
-#define MAX_DMA_DONE_PROCESS    TX_RING_SIZE
-#define MAX_TX_DONE_PROCESS     TX_RING_SIZE //8
-#define LOCAL_TXBUF_SIZE        2
-#endif // RTMP_MAC_PCI //
-
-#define PCI_VIRT_TO_PHYS(__Addr)	(((UINT32)(__Addr)) & 0x0FFFFFFF)
-
-
-#ifdef MULTIPLE_CARD_SUPPORT
-// MC: Multple Cards
-#define MAX_NUM_OF_MULTIPLE_CARD		32
-#endif // MULTIPLE_CARD_SUPPORT //
-
-#define MAX_RX_PROCESS          128 //64 //32
-#define NUM_OF_LOCAL_TXBUF      2
-#define TXD_SIZE                16
-#define TXWI_SIZE               16
-#define RXD_SIZE		16
-#define RXWI_SIZE		16
-// TXINFO_SIZE + TXWI_SIZE + 802.11 Header Size + AMSDU sub frame header
-#define TX_DMA_1ST_BUFFER_SIZE  96    // only the 1st physical buffer is pre-allocated
-#define MGMT_DMA_BUFFER_SIZE    1536 //2048
-#define RX_BUFFER_AGGRESIZE     3840 //3904 //3968 //4096 //2048 //4096
-#define RX_BUFFER_NORMSIZE      3840 //3904 //3968 //4096 //2048 //4096
-#define TX_BUFFER_NORMSIZE		RX_BUFFER_NORMSIZE
-#define MAX_FRAME_SIZE          2346                    // Maximum 802.11 frame size
-#define MAX_AGGREGATION_SIZE    3840 //3904 //3968 //4096
-#define MAX_NUM_OF_TUPLE_CACHE  2
-#define MAX_MCAST_LIST_SIZE     32
-#define MAX_LEN_OF_VENDOR_DESC  64
-//#define MAX_SIZE_OF_MCAST_PSQ   (NUM_OF_LOCAL_TXBUF >> 2) // AP won't spend more than 1/4 of total buffers on M/BCAST PSQ
-#define MAX_SIZE_OF_MCAST_PSQ               32
-
-#define MAX_RX_PROCESS_CNT	(RX_RING_SIZE)
-
-
-/*
-	WMM Note: If memory of your system is not much, please reduce the definition;
-	or when you do WMM test, the queue for low priority AC will be full, i.e.
-	TX_RING_SIZE + MAX_PACKETS_IN_QUEUE packets for the AC will be buffered in
-	WLAN, maybe no any packet buffer can be got in Ethernet driver.
-
-	Sometimes no packet buffer can be got in Ethernet driver, the system will
-	send flow control packet to the sender to slow down its sending rate.
-	So no WMM can be saw in the air.
-*/
-
-/*
-	Need to use 64 in vxworks for test case WMM A5-T07
-	Two dnlink (10Mbps) from a WMM station to a non-WMM station.
-	If use 256, queue is not enough.
-	And in rt_main_end.c, clConfig.clNum = RX_RING_SIZE * 3; is changed to
-	clConfig.clNum = RX_RING_SIZE * 4;
-*/
-// TODO: For VxWorks the size is 256. Shall we cahnge the value as 256 for all OS?????
-#define MAX_PACKETS_IN_QUEUE				(512) //(512)    // to pass WMM A5-WPAPSK
-
-#define MAX_PACKETS_IN_MCAST_PS_QUEUE		32
-#define MAX_PACKETS_IN_PS_QUEUE				128	//32
-#define WMM_NUM_OF_AC                       4  /* AC0, AC1, AC2, and AC3 */
-
-
-#ifdef RTMP_EFUSE_SUPPORT
-//2008/09/11:KH add to support efuse<--
-#define MAX_EEPROM_BIN_FILE_SIZE				1024
-#define EFUSE_BUFFER_PATH						"/tmp/RT30xxEEPROM.bin"
-//2008/09/11:KH add to support efuse-->
-#endif // RTMP_EFUSE_SUPPORT //
-
-// RxFilter
-#define STANORMAL	 0x17f97
-#define APNORMAL	 0x15f97
-#define PSPXLINK	 0x17f93
-//
-//  RTMP_ADAPTER flags
-//
-#define fRTMP_ADAPTER_MAP_REGISTER          0x00000001
-#define fRTMP_ADAPTER_INTERRUPT_IN_USE      0x00000002
-#define fRTMP_ADAPTER_HARDWARE_ERROR        0x00000004
-#define fRTMP_ADAPTER_SCATTER_GATHER        0x00000008
-#define fRTMP_ADAPTER_SEND_PACKET_ERROR     0x00000010
-#define fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS 0x00000020
-#define fRTMP_ADAPTER_HALT_IN_PROGRESS      0x00000040
-#define fRTMP_ADAPTER_RESET_IN_PROGRESS     0x00000080
-#define fRTMP_ADAPTER_NIC_NOT_EXIST         0x00000100
-#define fRTMP_ADAPTER_TX_RING_ALLOCATED     0x00000200
-#define fRTMP_ADAPTER_REMOVE_IN_PROGRESS    0x00000400
-#define fRTMP_ADAPTER_MIMORATE_INUSED       0x00000800
-#define fRTMP_ADAPTER_RX_RING_ALLOCATED     0x00001000
-#define fRTMP_ADAPTER_INTERRUPT_ACTIVE      0x00002000
-#define fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS  0x00004000
-#define	fRTMP_ADAPTER_REASSOC_IN_PROGRESS	0x00008000
-#define	fRTMP_ADAPTER_MEDIA_STATE_PENDING	0x00010000
-#define	fRTMP_ADAPTER_RADIO_OFF				0x00020000
-#define fRTMP_ADAPTER_BULKOUT_RESET			0x00040000
-#define	fRTMP_ADAPTER_BULKIN_RESET			0x00080000
-#define fRTMP_ADAPTER_RDG_ACTIVE			0x00100000
-#define fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE 0x00200000
-#define fRTMP_ADAPTER_SCAN_2040				0x04000000
-#define	fRTMP_ADAPTER_RADIO_MEASUREMENT		0x08000000
-
-#define fRTMP_ADAPTER_START_UP			0x10000000	//Devive already initialized and enabled Tx/Rx.
-#define fRTMP_ADAPTER_MEDIA_STATE_CHANGE    0x20000000
-#define fRTMP_ADAPTER_IDLE_RADIO_OFF        0x40000000
-
-// Lock bit for accessing different ring buffers
-//#define fRTMP_ADAPTER_TX_RING_BUSY        0x80000000
-//#define fRTMP_ADAPTER_MGMT_RING_BUSY      0x40000000
-//#define fRTMP_ADAPTER_ATIM_RING_BUSY      0x20000000
-//#define fRTMP_ADAPTER_RX_RING_BUSY        0x10000000
-
-// Lock bit for accessing different queue
-//#define   fRTMP_ADAPTER_TX_QUEUE_BUSY     0x08000000
-//#define   fRTMP_ADAPTER_MGMT_QUEUE_BUSY   0x04000000
-
-//
-//  STA operation status flags
-//
-#define fOP_STATUS_INFRA_ON                 0x00000001
-#define fOP_STATUS_ADHOC_ON                 0x00000002
-#define fOP_STATUS_BG_PROTECTION_INUSED     0x00000004
-#define fOP_STATUS_SHORT_SLOT_INUSED        0x00000008
-#define fOP_STATUS_SHORT_PREAMBLE_INUSED    0x00000010
-#define fOP_STATUS_RECEIVE_DTIM             0x00000020
-//#define fOP_STATUS_TX_RATE_SWITCH_ENABLED   0x00000040
-#define fOP_STATUS_MEDIA_STATE_CONNECTED    0x00000080
-#define fOP_STATUS_WMM_INUSED               0x00000100
-#define fOP_STATUS_AGGREGATION_INUSED       0x00000200
-#define fOP_STATUS_DOZE                     0x00000400  // debug purpose
-#define fOP_STATUS_PIGGYBACK_INUSED         0x00000800  // piggy-back, and aggregation
-#define fOP_STATUS_APSD_INUSED				0x00001000
-#define fOP_STATUS_TX_AMSDU_INUSED			0x00002000
-#define fOP_STATUS_MAX_RETRY_ENABLED		0x00004000
-#define fOP_STATUS_WAKEUP_NOW               0x00008000
-#define fOP_STATUS_PCIE_DEVICE       0x00020000
-
-//
-//  RTMP_ADAPTER PSFlags : related to advanced power save.
-//
-// Indicate whether driver can go to sleep mode from now. This flag is useful AFTER link up
-#define fRTMP_PS_CAN_GO_SLEEP          0x00000001
-// Indicate whether driver has issue a LinkControl command to PCIe L1
-#define fRTMP_PS_SET_PCI_CLK_OFF_COMMAND          0x00000002
-// Indicate driver should disable kick off hardware to send packets from now.
-#define fRTMP_PS_DISABLE_TX         0x00000004
-// Indicate driver should IMMEDIATELY fo to sleep after receiving AP's beacon in which  doesn't indicate unicate nor multicast packets for me
-//. This flag is used ONLY in RTMPHandleRxDoneInterrupt routine.
-#define fRTMP_PS_GO_TO_SLEEP_NOW         0x00000008
-#define fRTMP_PS_TOGGLE_L1		0x00000010	// Use Toggle L1 mechanism for rt28xx PCIe
-#ifdef RT3090
-#define WAKE_MCU_CMD				0x31
-#define SLEEP_MCU_CMD					0x30
-#define RFOFF_MCU_CMD				0x35
-#endif // RT3090 //
-#ifdef DOT11N_DRAFT3
-#define fOP_STATUS_SCAN_2040			    0x00040000
-#endif // DOT11N_DRAFT3 //
-
-#define CCKSETPROTECT		0x1
-#define OFDMSETPROTECT		0x2
-#define MM20SETPROTECT		0x4
-#define MM40SETPROTECT		0x8
-#define GF20SETPROTECT		0x10
-#define GR40SETPROTECT		0x20
-#define ALLN_SETPROTECT		(GR40SETPROTECT | GF20SETPROTECT | MM40SETPROTECT | MM20SETPROTECT)
-
-//
-//  AP's client table operation status flags
-//
-#define fCLIENT_STATUS_WMM_CAPABLE          0x00000001  // CLIENT can parse QOS DATA frame
-#define fCLIENT_STATUS_AGGREGATION_CAPABLE  0x00000002  // CLIENT can receive Ralink's proprietary TX aggregation frame
-#define fCLIENT_STATUS_PIGGYBACK_CAPABLE    0x00000004  // CLIENT support piggy-back
-#define fCLIENT_STATUS_AMSDU_INUSED			0x00000008
-#define fCLIENT_STATUS_SGI20_CAPABLE		0x00000010
-#define fCLIENT_STATUS_SGI40_CAPABLE		0x00000020
-#define fCLIENT_STATUS_TxSTBC_CAPABLE		0x00000040
-#define fCLIENT_STATUS_RxSTBC_CAPABLE		0x00000080
-#define fCLIENT_STATUS_HTC_CAPABLE			0x00000100
-#define fCLIENT_STATUS_RDG_CAPABLE			0x00000200
-#define fCLIENT_STATUS_MCSFEEDBACK_CAPABLE  0x00000400
-#define fCLIENT_STATUS_APSD_CAPABLE         0x00000800  /* UAPSD STATION */
-
-#ifdef DOT11N_DRAFT3
-#define fCLIENT_STATUS_BSSCOEXIST_CAPABLE	0x00001000
-#endif // DOT11N_DRAFT3 //
-
-#define fCLIENT_STATUS_RALINK_CHIPSET		0x00100000
-//
-//  STA configuration flags
-//
-//#define fSTA_CFG_ENABLE_TX_BURST          0x00000001
-
-// 802.11n Operating Mode Definition. 0-3 also used in ASICUPdateProtect switch case
-#define HT_NO_PROTECT	0
-#define HT_LEGACY_PROTECT	1
-#define HT_40_PROTECT	2
-#define HT_2040_PROTECT	3
-#define HT_RTSCTS_6M	7
-//following is our own definition in order to turn on our ASIC protection register in INFRASTRUCTURE.
-#define HT_ATHEROS	8	// rt2860c has problem with atheros chip. we need to turn on RTS/CTS .
-#define HT_FORCERTSCTS	9	// Force turn on RTS/CTS first. then go to evaluate if this force RTS is necessary.
-
-//
-// RX Packet Filter control flags. Apply on pAd->PacketFilter
-//
-#define fRX_FILTER_ACCEPT_DIRECT            NDIS_PACKET_TYPE_DIRECTED
-#define fRX_FILTER_ACCEPT_MULTICAST         NDIS_PACKET_TYPE_MULTICAST
-#define fRX_FILTER_ACCEPT_BROADCAST         NDIS_PACKET_TYPE_BROADCAST
-#define fRX_FILTER_ACCEPT_ALL_MULTICAST     NDIS_PACKET_TYPE_ALL_MULTICAST
-#define fRX_FILTER_ACCEPT_PROMISCUOUS       NDIS_PACKET_TYPE_PROMISCUOUS
-
-//
-// Error code section
-//
-// NDIS_ERROR_CODE_ADAPTER_NOT_FOUND
-#define ERRLOG_READ_PCI_SLOT_FAILED     0x00000101L
-#define ERRLOG_WRITE_PCI_SLOT_FAILED    0x00000102L
-#define ERRLOG_VENDOR_DEVICE_NOMATCH    0x00000103L
-
-// NDIS_ERROR_CODE_ADAPTER_DISABLED
-#define ERRLOG_BUS_MASTER_DISABLED      0x00000201L
-
-// NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION
-#define ERRLOG_INVALID_SPEED_DUPLEX     0x00000301L
-#define ERRLOG_SET_SECONDARY_FAILED     0x00000302L
-
-// NDIS_ERROR_CODE_OUT_OF_RESOURCES
-#define ERRLOG_OUT_OF_MEMORY            0x00000401L
-#define ERRLOG_OUT_OF_SHARED_MEMORY     0x00000402L
-#define ERRLOG_OUT_OF_MAP_REGISTERS     0x00000403L
-#define ERRLOG_OUT_OF_BUFFER_POOL       0x00000404L
-#define ERRLOG_OUT_OF_NDIS_BUFFER       0x00000405L
-#define ERRLOG_OUT_OF_PACKET_POOL       0x00000406L
-#define ERRLOG_OUT_OF_NDIS_PACKET       0x00000407L
-#define ERRLOG_OUT_OF_LOOKASIDE_MEMORY  0x00000408L
-
-// NDIS_ERROR_CODE_HARDWARE_FAILURE
-#define ERRLOG_SELFTEST_FAILED          0x00000501L
-#define ERRLOG_INITIALIZE_ADAPTER       0x00000502L
-#define ERRLOG_REMOVE_MINIPORT          0x00000503L
-
-// NDIS_ERROR_CODE_RESOURCE_CONFLICT
-#define ERRLOG_MAP_IO_SPACE             0x00000601L
-#define ERRLOG_QUERY_ADAPTER_RESOURCES  0x00000602L
-#define ERRLOG_NO_IO_RESOURCE           0x00000603L
-#define ERRLOG_NO_INTERRUPT_RESOURCE    0x00000604L
-#define ERRLOG_NO_MEMORY_RESOURCE       0x00000605L
-
-
-// WDS definition
-#define	MAX_WDS_ENTRY               4
-#define WDS_PAIRWISE_KEY_OFFSET     60    // WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table
-
-#define	WDS_DISABLE_MODE            0
-#define	WDS_RESTRICT_MODE           1
-#define	WDS_BRIDGE_MODE             2
-#define	WDS_REPEATER_MODE           3
-#define	WDS_LAZY_MODE               4
-
-
-#define MAX_MESH_NUM				0
-
-#define MAX_APCLI_NUM				0
-#ifdef APCLI_SUPPORT
-#undef	MAX_APCLI_NUM
-#define MAX_APCLI_NUM				1
-#endif // APCLI_SUPPORT //
-
-#define MAX_MBSSID_NUM				1
-#ifdef MBSS_SUPPORT
-#undef	MAX_MBSSID_NUM
-#define MAX_MBSSID_NUM				(8 - MAX_MESH_NUM - MAX_APCLI_NUM)
-#endif // MBSS_SUPPORT //
-
-/* sanity check for apidx */
-#define MBSS_MR_APIDX_SANITY_CHECK(apidx) \
-    { if (apidx > MAX_MBSSID_NUM) { \
-          DBGPRINT(RT_DEBUG_ERROR, ("%s> Error! apidx = %d > MAX_MBSSID_NUM!\n", __FUNCTION__, apidx)); \
-	  apidx = MAIN_MBSSID; } }
-
-#define VALID_WCID(_wcid)	((_wcid) > 0 && (_wcid) < MAX_LEN_OF_MAC_TABLE )
-
-#define MAIN_MBSSID                 0
-#define FIRST_MBSSID                1
-
-
-#define MAX_BEACON_SIZE				512
-// If the MAX_MBSSID_NUM is larger than 6,
-// it shall reserve some WCID space(wcid 222~253) for beacon frames.
-// -	these wcid 238~253 are reserved for beacon#6(ra6).
-// -	these wcid 222~237 are reserved for beacon#7(ra7).
-#if defined(MAX_MBSSID_NUM) && (MAX_MBSSID_NUM == 8)
-#define HW_RESERVED_WCID	222
-#elif defined(MAX_MBSSID_NUM) && (MAX_MBSSID_NUM == 7)
-#define HW_RESERVED_WCID	238
-#else
-#define HW_RESERVED_WCID	255
-#endif
-
-// Then dedicate wcid of DFS and Carrier-Sense.
-#define DFS_CTS_WCID		(HW_RESERVED_WCID - 1)
-#define CS_CTS_WCID		(HW_RESERVED_WCID - 2)
-#define LAST_SPECIFIC_WCID	(HW_RESERVED_WCID - 2)
-
-// If MAX_MBSSID_NUM is 8, the maximum available wcid for the associated STA is 211.
-// If MAX_MBSSID_NUM is 7, the maximum available wcid for the associated STA is 228.
-#define MAX_AVAILABLE_CLIENT_WCID	(LAST_SPECIFIC_WCID - MAX_MBSSID_NUM - 1)
-
-// TX need WCID to find Cipher Key
-// these wcid 212 ~ 219 are reserved for bc/mc packets if MAX_MBSSID_NUM is 8.
-#define GET_GroupKey_WCID(__wcid, __bssidx) \
-	{										\
-		__wcid = LAST_SPECIFIC_WCID - (MAX_MBSSID_NUM) + __bssidx;	\
-	}
-
-#define IsGroupKeyWCID(__wcid) (((__wcid) < LAST_SPECIFIC_WCID) && ((__wcid) >= (LAST_SPECIFIC_WCID - (MAX_MBSSID_NUM))))
-
-
-// definition to support multiple BSSID
-#define BSS0                            0
-#define BSS1                            1
-#define BSS2                            2
-#define BSS3                            3
-#define BSS4                            4
-#define BSS5                            5
-#define BSS6                            6
-#define BSS7                            7
-
-
-//============================================================
-// Length definitions
-#define PEER_KEY_NO                     2
-#define MAC_ADDR_LEN                    6
-#define TIMESTAMP_LEN                   8
-#define MAX_LEN_OF_SUPPORTED_RATES      MAX_LENGTH_OF_SUPPORT_RATES // 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
-#define MAX_NUM_OF_REGULATORY_CLASS		16
-#define MAX_LEN_OF_KEY                  32      // 32 octets == 256 bits, Redefine for WPA
-#define MAX_NUM_OF_CHANNELS             MAX_NUM_OF_CHS      // 14 channels @2.4G +  12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination
-#define MAX_NUM_OF_11JCHANNELS             20      // 14 channels @2.4G +  12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination
-#define MAX_LEN_OF_SSID                 32
-#define CIPHER_TEXT_LEN                 128
-#define HASH_TABLE_SIZE                 256
-#define MAX_VIE_LEN                     1024   // New for WPA cipher suite variable IE sizes.
-#define MAX_SUPPORT_MCS             32
-#define MAX_NUM_OF_BBP_LATCH             140
-//============================================================
-// ASIC WCID Table definition.
-//============================================================
-#define BSSID_WCID		1	// in infra mode, always put bssid with this WCID
-#define MCAST_WCID	0x0
-#define BSS0Mcast_WCID	0x0
-#define BSS1Mcast_WCID	0xf8
-#define BSS2Mcast_WCID	0xf9
-#define BSS3Mcast_WCID	0xfa
-#define BSS4Mcast_WCID	0xfb
-#define BSS5Mcast_WCID	0xfc
-#define BSS6Mcast_WCID	0xfd
-#define BSS7Mcast_WCID	0xfe
-#define RESERVED_WCID		0xff
-
-#define MAX_NUM_OF_ACL_LIST				MAX_NUMBER_OF_ACL
-
-#define MAX_LEN_OF_MAC_TABLE            MAX_NUMBER_OF_MAC // if MAX_MBSSID_NUM is 8, this value can't be larger than 211
-
-#if MAX_LEN_OF_MAC_TABLE>MAX_AVAILABLE_CLIENT_WCID
-#error MAX_LEN_OF_MAC_TABLE can not be larger than MAX_AVAILABLE_CLIENT_WCID!!!!
-#endif
-
-#define MAX_NUM_OF_WDS_LINK_PERBSSID	            3
-#define MAX_NUM_OF_WDS_LINK	            (MAX_NUM_OF_WDS_LINK_PERBSSID*MAX_MBSSID_NUM)
-#define MAX_NUM_OF_EVENT                MAX_NUMBER_OF_EVENT
-#define WDS_LINK_START_WCID				(MAX_LEN_OF_MAC_TABLE-1)
-
-#define NUM_OF_TID			8
-#define MAX_AID_BA                    4
-#define MAX_LEN_OF_BA_REC_TABLE          ((NUM_OF_TID * MAX_LEN_OF_MAC_TABLE)/2)//   (NUM_OF_TID*MAX_AID_BA + 32)	 //Block ACK recipient
-#define MAX_LEN_OF_BA_ORI_TABLE          ((NUM_OF_TID * MAX_LEN_OF_MAC_TABLE)/2)//   (NUM_OF_TID*MAX_AID_BA + 32)   // Block ACK originator
-#define MAX_LEN_OF_BSS_TABLE             64
-#define MAX_REORDERING_MPDU_NUM			 512
-
-// key related definitions
-#define SHARE_KEY_NUM                   4
-#define MAX_LEN_OF_SHARE_KEY            16    // byte count
-#define MAX_LEN_OF_PEER_KEY             16    // byte count
-#define PAIRWISE_KEY_NUM                64    // in MAC ASIC pairwise key table
-#define GROUP_KEY_NUM                   4
-#define PMK_LEN                         32
-#define WDS_PAIRWISE_KEY_OFFSET         60    // WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table
-#define	PMKID_NO                        4     // Number of PMKID saved supported
-#define MAX_LEN_OF_MLME_BUFFER          2048
-
-// power status related definitions
-#define PWR_ACTIVE                      0
-#define PWR_SAVE                        1
-#define PWR_MMPS                        2			//MIMO power save
-//#define PWR_UNKNOWN                   2
-
-// Auth and Assoc mode related definitions
-#define AUTH_MODE_OPEN                  0x00
-#define AUTH_MODE_KEY                   0x01
-//#define AUTH_MODE_AUTO_SWITCH         0x03
-//#define AUTH_MODE_DEAUTH              0x04
-//#define AUTH_MODE_UPLAYER             0x05 // reserved for 802.11i use
-
-// BSS Type definitions
-#define BSS_ADHOC                       0  // = Ndis802_11IBSS
-#define BSS_INFRA                       1  // = Ndis802_11Infrastructure
-#define BSS_ANY                         2  // = Ndis802_11AutoUnknown
-#define BSS_MONITOR			            3  // = Ndis802_11Monitor
-
-
-// Reason code definitions
-#define REASON_RESERVED                 0
-#define REASON_UNSPECIFY                1
-#define REASON_NO_LONGER_VALID          2
-#define REASON_DEAUTH_STA_LEAVING       3
-#define REASON_DISASSOC_INACTIVE        4
-#define REASON_DISASSPC_AP_UNABLE       5
-#define REASON_CLS2ERR                  6
-#define REASON_CLS3ERR                  7
-#define REASON_DISASSOC_STA_LEAVING     8
-#define REASON_STA_REQ_ASSOC_NOT_AUTH   9
-#define REASON_INVALID_IE               13
-#define REASON_MIC_FAILURE              14
-#define REASON_4_WAY_TIMEOUT            15
-#define REASON_GROUP_KEY_HS_TIMEOUT     16
-#define REASON_IE_DIFFERENT             17
-#define REASON_MCIPHER_NOT_VALID        18
-#define REASON_UCIPHER_NOT_VALID        19
-#define REASON_AKMP_NOT_VALID           20
-#define REASON_UNSUPPORT_RSNE_VER       21
-#define REASON_INVALID_RSNE_CAP         22
-#define REASON_8021X_AUTH_FAIL          23
-#define REASON_CIPHER_SUITE_REJECTED    24
-#define REASON_DECLINED                 37
-
-#define REASON_QOS_UNSPECIFY              32
-#define REASON_QOS_LACK_BANDWIDTH         33
-#define REASON_POOR_CHANNEL_CONDITION     34
-#define REASON_QOS_OUTSIDE_TXOP_LIMITION  35
-#define REASON_QOS_QSTA_LEAVING_QBSS      36
-#define REASON_QOS_UNWANTED_MECHANISM     37
-#define REASON_QOS_MECH_SETUP_REQUIRED    38
-#define REASON_QOS_REQUEST_TIMEOUT        39
-#define REASON_QOS_CIPHER_NOT_SUPPORT     45
-
-// Status code definitions
-#define MLME_SUCCESS                    0
-#define MLME_UNSPECIFY_FAIL             1
-#define MLME_CANNOT_SUPPORT_CAP         10
-#define MLME_REASSOC_DENY_ASSOC_EXIST   11
-#define MLME_ASSOC_DENY_OUT_SCOPE       12
-#define MLME_ALG_NOT_SUPPORT            13
-#define MLME_SEQ_NR_OUT_OF_SEQUENCE     14
-#define MLME_REJ_CHALLENGE_FAILURE      15
-#define MLME_REJ_TIMEOUT                  16
-#define MLME_ASSOC_REJ_UNABLE_HANDLE_STA  17
-#define MLME_ASSOC_REJ_DATA_RATE          18
-
-#define MLME_ASSOC_REJ_NO_EXT_RATE        22
-#define MLME_ASSOC_REJ_NO_EXT_RATE_PBCC   23
-#define MLME_ASSOC_REJ_NO_CCK_OFDM        24
-
-#define MLME_QOS_UNSPECIFY                32
-#define MLME_REQUEST_DECLINED             37
-#define MLME_REQUEST_WITH_INVALID_PARAM   38
-#define MLME_INVALID_GROUP_CIPHER	  41
-#define MLME_INVALID_PAIRWISE_CIPHER	  42
-#define MLME_INVALID_AKMP			  43
-#define MLME_DLS_NOT_ALLOW_IN_QBSS        48
-#define MLME_DEST_STA_NOT_IN_QBSS         49
-#define MLME_DEST_STA_IS_NOT_A_QSTA       50
-
-#define MLME_INVALID_FORMAT             0x51
-#define MLME_FAIL_NO_RESOURCE           0x52
-#define MLME_STATE_MACHINE_REJECT       0x53
-#define MLME_MAC_TABLE_FAIL             0x54
-
-// IE code
-#define IE_SSID                         0
-#define IE_SUPP_RATES                   1
-#define IE_FH_PARM                      2
-#define IE_DS_PARM                      3
-#define IE_CF_PARM                      4
-#define IE_TIM                          5
-#define IE_IBSS_PARM                    6
-#define IE_COUNTRY                      7     // 802.11d
-#define IE_802_11D_REQUEST              10    // 802.11d
-#define IE_QBSS_LOAD                    11    // 802.11e d9
-#define IE_EDCA_PARAMETER               12    // 802.11e d9
-#define IE_TSPEC                        13    // 802.11e d9
-#define IE_TCLAS                        14    // 802.11e d9
-#define IE_SCHEDULE                     15    // 802.11e d9
-#define IE_CHALLENGE_TEXT               16
-#define IE_POWER_CONSTRAINT             32    // 802.11h d3.3
-#define IE_POWER_CAPABILITY             33    // 802.11h d3.3
-#define IE_TPC_REQUEST                  34    // 802.11h d3.3
-#define IE_TPC_REPORT                   35    // 802.11h d3.3
-#define IE_SUPP_CHANNELS                36    // 802.11h d3.3
-#define IE_CHANNEL_SWITCH_ANNOUNCEMENT  37    // 802.11h d3.3
-#define IE_MEASUREMENT_REQUEST          38    // 802.11h d3.3
-#define IE_MEASUREMENT_REPORT           39    // 802.11h d3.3
-#define IE_QUIET                        40    // 802.11h d3.3
-#define IE_IBSS_DFS                     41    // 802.11h d3.3
-#define IE_ERP                          42    // 802.11g
-#define IE_TS_DELAY                     43    // 802.11e d9
-#define IE_TCLAS_PROCESSING             44    // 802.11e d9
-#define IE_QOS_CAPABILITY               46    // 802.11e d6
-#define IE_HT_CAP                       45    // 802.11n d1. HT CAPABILITY. ELEMENT ID TBD
-#define IE_AP_CHANNEL_REPORT			51    // 802.11k d6
-#define IE_HT_CAP2                         52    // 802.11n d1. HT CAPABILITY. ELEMENT ID TBD
-#define IE_RSN                          48    // 802.11i d3.0
-#define IE_WPA2                         48    // WPA2
-#define IE_EXT_SUPP_RATES               50    // 802.11g
-#define IE_SUPP_REG_CLASS               59    // 802.11y. Supported regulatory classes.
-#define IE_EXT_CHANNEL_SWITCH_ANNOUNCEMENT	60	// 802.11n
-#define IE_ADD_HT                         61    // 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD
-#define IE_ADD_HT2                        53    // 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD
-
-
-// For 802.11n D3.03
-//#define IE_NEW_EXT_CHA_OFFSET             62    // 802.11n d1. New extension channel offset elemet
-#define IE_SECONDARY_CH_OFFSET		62	// 802.11n D3.03	Secondary Channel Offset element
-#define IE_WAPI							68		// WAPI information element
-#define IE_2040_BSS_COEXIST               72    // 802.11n D3.0.3
-#define IE_2040_BSS_INTOLERANT_REPORT     73    // 802.11n D3.03
-#define IE_OVERLAPBSS_SCAN_PARM           74    // 802.11n D3.03
-#define IE_EXT_CAPABILITY                127   // 802.11n D3.03
-
-
-#define IE_WPA                          221   // WPA
-#define IE_VENDOR_SPECIFIC              221   // Wifi WMM (WME)
-
-#define OUI_BROADCOM_HT              51   //
-#define OUI_BROADCOM_HTADD              52   //
-#define OUI_PREN_HT_CAP              51   //
-#define OUI_PREN_ADD_HT              52   //
-
-// CCX information
-#define IE_AIRONET_CKIP                 133   // CCX1.0 ID 85H for CKIP
-#define IE_AP_TX_POWER                  150   // CCX 2.0 for AP transmit power
-#define IE_MEASUREMENT_CAPABILITY       221   // CCX 2.0
-#define IE_CCX_V2                       221
-#define IE_AIRONET_IPADDRESS            149   // CCX ID 95H for IP Address
-#define IE_AIRONET_CCKMREASSOC          156   // CCX ID 9CH for CCKM Reassociation Request element
-#define CKIP_NEGOTIATION_LENGTH         30
-#define AIRONET_IPADDRESS_LENGTH        10
-#define AIRONET_CCKMREASSOC_LENGTH      24
-
-// ========================================================
-// MLME state machine definition
-// ========================================================
-
-// STA MLME state mahcines
-#define ASSOC_STATE_MACHINE             1
-#define AUTH_STATE_MACHINE              2
-#define AUTH_RSP_STATE_MACHINE          3
-#define SYNC_STATE_MACHINE              4
-#define MLME_CNTL_STATE_MACHINE         5
-#define WPA_PSK_STATE_MACHINE           6
-//#define LEAP_STATE_MACHINE              7
-#define AIRONET_STATE_MACHINE           8
-#define ACTION_STATE_MACHINE           9
-
-// AP MLME state machines
-#define AP_ASSOC_STATE_MACHINE          11
-#define AP_AUTH_STATE_MACHINE           12
-#define AP_SYNC_STATE_MACHINE           14
-#define AP_CNTL_STATE_MACHINE           15
-#define WSC_STATE_MACHINE            17
-#define WSC_UPNP_STATE_MACHINE		    18
-
-
-#define WPA_STATE_MACHINE			23
-
-
-#ifdef QOS_DLS_SUPPORT
-#define DLS_STATE_MACHINE               26
-#endif // QOS_DLS_SUPPORT //
-
-//
-// STA's CONTROL/CONNECT state machine: states, events, total function #
-//
-#define CNTL_IDLE                       0
-#define CNTL_WAIT_DISASSOC              1
-#define CNTL_WAIT_JOIN                  2
-#define CNTL_WAIT_REASSOC               3
-#define CNTL_WAIT_START                 4
-#define CNTL_WAIT_AUTH                  5
-#define CNTL_WAIT_ASSOC                 6
-#define CNTL_WAIT_AUTH2                 7
-#define CNTL_WAIT_OID_LIST_SCAN         8
-#define CNTL_WAIT_OID_DISASSOC          9
-
-#define MT2_ASSOC_CONF                  34
-#define MT2_AUTH_CONF                   35
-#define MT2_DEAUTH_CONF                 36
-#define MT2_DISASSOC_CONF               37
-#define MT2_REASSOC_CONF                38
-#define MT2_PWR_MGMT_CONF               39
-#define MT2_JOIN_CONF                   40
-#define MT2_SCAN_CONF                   41
-#define MT2_START_CONF                  42
-#define MT2_GET_CONF                    43
-#define MT2_SET_CONF                    44
-#define MT2_RESET_CONF                  45
-#define MT2_FT_OTD_CONF					46
-#define MT2_MLME_ROAMING_REQ            52
-
-#define CNTL_FUNC_SIZE                  1
-
-//
-// STA's ASSOC state machine: states, events, total function #
-//
-#define ASSOC_IDLE                      0
-#define ASSOC_WAIT_RSP                  1
-#define REASSOC_WAIT_RSP                2
-#define DISASSOC_WAIT_RSP               3
-#define MAX_ASSOC_STATE                 4
-
-#define ASSOC_MACHINE_BASE              0
-#define MT2_MLME_ASSOC_REQ              0
-#define MT2_MLME_REASSOC_REQ            1
-#define MT2_MLME_DISASSOC_REQ           2
-#define MT2_PEER_DISASSOC_REQ           3
-#define MT2_PEER_ASSOC_REQ              4
-#define MT2_PEER_ASSOC_RSP              5
-#define MT2_PEER_REASSOC_REQ            6
-#define MT2_PEER_REASSOC_RSP            7
-#define MT2_DISASSOC_TIMEOUT            8
-#define MT2_ASSOC_TIMEOUT               9
-#define MT2_REASSOC_TIMEOUT             10
-#define MAX_ASSOC_MSG                   11
-
-#define ASSOC_FUNC_SIZE                 (MAX_ASSOC_STATE * MAX_ASSOC_MSG)
-
-//
-// ACT state machine: states, events, total function #
-//
-#define ACT_IDLE                      0
-#define MAX_ACT_STATE                 1
-
-#define ACT_MACHINE_BASE              0
-
-//Those PEER_xx_CATE number is based on real Categary value in IEEE spec. Please don'es modify it by your self.
-//Category
-#define MT2_PEER_SPECTRUM_CATE              0
-#define MT2_PEER_QOS_CATE              1
-#define MT2_PEER_DLS_CATE             2
-#define MT2_PEER_BA_CATE             3
-#define MT2_PEER_PUBLIC_CATE             4
-#define MT2_PEER_RM_CATE             5
-/* "FT_CATEGORY_BSS_TRANSITION equal to 6" is defined file of "dot11r_ft.h" */
-#define MT2_PEER_HT_CATE             7	//	7.4.7
-#define MAX_PEER_CATE_MSG                   7
-
-
-#define MT2_MLME_ADD_BA_CATE             8
-#define MT2_MLME_ORI_DELBA_CATE             9
-#define MT2_MLME_REC_DELBA_CATE             10
-#define MT2_MLME_QOS_CATE              11
-#define MT2_MLME_DLS_CATE             12
-#define MT2_ACT_INVALID             13
-
-#define MAX_ACT_MSG                   14
-
-
-//Category field
-#define CATEGORY_SPECTRUM		0
-#define CATEGORY_QOS			1
-#define CATEGORY_DLS			2
-#define CATEGORY_BA			3
-#define CATEGORY_PUBLIC		4
-#define CATEGORY_RM			5
-#define CATEGORY_HT			7
-
-
-// DLS Action frame definition
-#define ACTION_DLS_REQUEST			0
-#define ACTION_DLS_RESPONSE			1
-#define ACTION_DLS_TEARDOWN			2
-
-//Spectrum  Action field value 802.11h 7.4.1
-#define SPEC_MRQ	0	// Request
-#define SPEC_MRP	1	//Report
-#define SPEC_TPCRQ	2
-#define SPEC_TPCRP	3
-#define SPEC_CHANNEL_SWITCH	4
-
-
-//BA  Action field value
-#define ADDBA_REQ	0
-#define ADDBA_RESP	1
-#define DELBA   2
-
-//Public's  Action field value in Public Category.  Some in 802.11y and some in 11n
-#define ACTION_BSS_2040_COEXIST				0	// 11n
-#define ACTION_DSE_ENABLEMENT					1	// 11y D9.0
-#define ACTION_DSE_DEENABLEMENT				2	// 11y D9.0
-#define ACTION_DSE_REG_LOCATION_ANNOUNCE	3	// 11y D9.0
-#define ACTION_EXT_CH_SWITCH_ANNOUNCE		4	// 11y D9.0
-#define ACTION_DSE_MEASUREMENT_REQ			5	// 11y D9.0
-#define ACTION_DSE_MEASUREMENT_REPORT		6	// 11y D9.0
-#define ACTION_MEASUREMENT_PILOT_ACTION		7	// 11y D9.0
-#define ACTION_DSE_POWER_CONSTRAINT			8	// 11y D9.0
-
-
-//HT  Action field value
-#define NOTIFY_BW_ACTION				0
-#define SMPS_ACTION						1
-#define PSMP_ACTION					2
-#define SETPCO_ACTION					3
-#define MIMO_CHA_MEASURE_ACTION			4
-#define MIMO_N_BEACONFORM				5
-#define MIMO_BEACONFORM					6
-#define ANTENNA_SELECT					7
-#define HT_INFO_EXCHANGE				8
-
-#define ACT_FUNC_SIZE                 (MAX_ACT_STATE * MAX_ACT_MSG)
-//
-// STA's AUTHENTICATION state machine: states, evvents, total function #
-//
-#define AUTH_REQ_IDLE                   0
-#define AUTH_WAIT_SEQ2                  1
-#define AUTH_WAIT_SEQ4                  2
-#define MAX_AUTH_STATE                  3
-
-#define AUTH_MACHINE_BASE               0
-#define MT2_MLME_AUTH_REQ               0
-#define MT2_PEER_AUTH_EVEN              1
-#define MT2_AUTH_TIMEOUT                2
-#define MAX_AUTH_MSG                    3
-
-#define AUTH_FUNC_SIZE                  (MAX_AUTH_STATE * MAX_AUTH_MSG)
-
-//
-// STA's AUTH_RSP state machine: states, events, total function #
-//
-#define AUTH_RSP_IDLE                   0
-#define AUTH_RSP_WAIT_CHAL              1
-#define MAX_AUTH_RSP_STATE              2
-
-#define AUTH_RSP_MACHINE_BASE           0
-#define MT2_AUTH_CHALLENGE_TIMEOUT      0
-#define MT2_PEER_AUTH_ODD               1
-#define MT2_PEER_DEAUTH                 2
-#define MAX_AUTH_RSP_MSG                3
-
-#define AUTH_RSP_FUNC_SIZE              (MAX_AUTH_RSP_STATE * MAX_AUTH_RSP_MSG)
-
-//
-// STA's SYNC state machine: states, events, total function #
-//
-#define SYNC_IDLE                       0  // merge NO_BSS,IBSS_IDLE,IBSS_ACTIVE and BSS in to 1 state
-#define JOIN_WAIT_BEACON                1
-#define SCAN_LISTEN                     2
-#define MAX_SYNC_STATE                  3
-
-#define SYNC_MACHINE_BASE               0
-#define MT2_MLME_SCAN_REQ               0
-#define MT2_MLME_JOIN_REQ               1
-#define MT2_MLME_START_REQ              2
-#define MT2_PEER_BEACON                 3
-#define MT2_PEER_PROBE_RSP              4
-#define MT2_PEER_ATIM                   5
-#define MT2_SCAN_TIMEOUT                6
-#define MT2_BEACON_TIMEOUT              7
-#define MT2_ATIM_TIMEOUT                8
-#define MT2_PEER_PROBE_REQ              9
-#define MAX_SYNC_MSG                    10
-
-#define SYNC_FUNC_SIZE                  (MAX_SYNC_STATE * MAX_SYNC_MSG)
-
-//Messages for the DLS state machine
-#define DLS_IDLE						0
-#define MAX_DLS_STATE					1
-
-#define DLS_MACHINE_BASE				0
-#define MT2_MLME_DLS_REQ			    0
-#define MT2_PEER_DLS_REQ			    1
-#define MT2_PEER_DLS_RSP			    2
-#define MT2_MLME_DLS_TEAR_DOWN		    3
-#define MT2_PEER_DLS_TEAR_DOWN		    4
-#define MAX_DLS_MSG				        5
-
-#define DLS_FUNC_SIZE					(MAX_DLS_STATE * MAX_DLS_MSG)
-
-//
-// WSC State machine: states, events, total function #
-//
-
-//
-// AP's CONTROL/CONNECT state machine: states, events, total function #
-//
-#define AP_CNTL_FUNC_SIZE               1
-
-//
-// AP's ASSOC state machine: states, events, total function #
-//
-#define AP_ASSOC_IDLE                   0
-#define AP_MAX_ASSOC_STATE              1
-
-#define AP_ASSOC_MACHINE_BASE           0
-#define APMT2_MLME_DISASSOC_REQ         0
-#define APMT2_PEER_DISASSOC_REQ         1
-#define APMT2_PEER_ASSOC_REQ            2
-#define APMT2_PEER_REASSOC_REQ          3
-#define APMT2_CLS3ERR                   4
-#define AP_MAX_ASSOC_MSG                5
-
-#define AP_ASSOC_FUNC_SIZE              (AP_MAX_ASSOC_STATE * AP_MAX_ASSOC_MSG)
-
-//
-// AP's AUTHENTICATION state machine: states, events, total function #
-//
-#define AP_AUTH_REQ_IDLE                0
-#define AP_MAX_AUTH_STATE               1
-
-#define AP_AUTH_MACHINE_BASE            0
-#define APMT2_MLME_DEAUTH_REQ           0
-#define APMT2_CLS2ERR                   1
-#define APMT2_PEER_DEAUTH				2
-#define APMT2_PEER_AUTH_REQ				3
-#define APMT2_PEER_AUTH_CONFIRM			4
-#define AP_MAX_AUTH_MSG                 5
-
-#define AP_AUTH_FUNC_SIZE               (AP_MAX_AUTH_STATE * AP_MAX_AUTH_MSG)
-
-//
-// AP's SYNC state machine: states, events, total function #
-//
-#define AP_SYNC_IDLE                    0
-#define AP_SCAN_LISTEN					1
-#define AP_MAX_SYNC_STATE               2
-
-#define AP_SYNC_MACHINE_BASE            0
-#define APMT2_PEER_PROBE_REQ            0
-#define APMT2_PEER_BEACON               1
-#define APMT2_MLME_SCAN_REQ				2
-#define APMT2_PEER_PROBE_RSP			3
-#define APMT2_SCAN_TIMEOUT				4
-#define APMT2_MLME_SCAN_CNCL			5
-#define AP_MAX_SYNC_MSG                 6
-
-#define AP_SYNC_FUNC_SIZE               (AP_MAX_SYNC_STATE * AP_MAX_SYNC_MSG)
-
-//
-// Common WPA state machine: states, events, total function #
-//
-#define WPA_PTK                      0
-#define MAX_WPA_PTK_STATE            1
-
-#define WPA_MACHINE_BASE             0
-#define MT2_EAPPacket                0
-#define MT2_EAPOLStart               1
-#define MT2_EAPOLLogoff              2
-#define MT2_EAPOLKey                 3
-#define MT2_EAPOLASFAlert            4
-#define MAX_WPA_MSG                  5
-
-#define WPA_FUNC_SIZE                (MAX_WPA_PTK_STATE * MAX_WPA_MSG)
-
-#ifdef APCLI_SUPPORT
-//ApCli authentication state machine
-#define APCLI_AUTH_REQ_IDLE                0
-#define APCLI_AUTH_WAIT_SEQ2               1
-#define APCLI_AUTH_WAIT_SEQ4               2
-#define APCLI_MAX_AUTH_STATE               3
-
-#define APCLI_AUTH_MACHINE_BASE            0
-#define APCLI_MT2_MLME_AUTH_REQ            0
-#define APCLI_MT2_MLME_DEAUTH_REQ          1
-#define APCLI_MT2_PEER_AUTH_EVEN           2
-#define APCLI_MT2_PEER_DEAUTH              3
-#define APCLI_MT2_AUTH_TIMEOUT             4
-#define APCLI_MAX_AUTH_MSG                 5
-
-#define APCLI_AUTH_FUNC_SIZE               (APCLI_MAX_AUTH_STATE * APCLI_MAX_AUTH_MSG)
-
-//ApCli association state machine
-#define APCLI_ASSOC_IDLE                   0
-#define APCLI_ASSOC_WAIT_RSP               1
-#define APCLI_MAX_ASSOC_STATE              2
-
-#define APCLI_ASSOC_MACHINE_BASE           0
-#define APCLI_MT2_MLME_ASSOC_REQ           0
-#define APCLI_MT2_MLME_DISASSOC_REQ        1
-#define APCLI_MT2_PEER_DISASSOC_REQ        2
-#define APCLI_MT2_PEER_ASSOC_RSP           3
-#define APCLI_MT2_ASSOC_TIMEOUT            4
-#define APCLI_MAX_ASSOC_MSG                5
-
-#define APCLI_ASSOC_FUNC_SIZE              (APCLI_MAX_ASSOC_STATE * APCLI_MAX_ASSOC_MSG)
-
-//ApCli sync state machine
-#define APCLI_SYNC_IDLE                   0  // merge NO_BSS,IBSS_IDLE,IBSS_ACTIVE and BSS in to 1 state
-#define APCLI_JOIN_WAIT_PROBE_RSP         1
-#define APCLI_MAX_SYNC_STATE              2
-
-#define APCLI_SYNC_MACHINE_BASE           0
-#define APCLI_MT2_MLME_PROBE_REQ          0
-#define APCLI_MT2_PEER_PROBE_RSP          1
-#define APCLI_MT2_PROBE_TIMEOUT           2
-#define APCLI_MAX_SYNC_MSG                3
-
-#define APCLI_SYNC_FUNC_SIZE              (APCLI_MAX_SYNC_STATE * APCLI_MAX_SYNC_MSG)
-
-//ApCli ctrl state machine
-#define APCLI_CTRL_DISCONNECTED           0  // merge NO_BSS,IBSS_IDLE,IBSS_ACTIVE and BSS in to 1 state
-#define APCLI_CTRL_PROBE                  1
-#define APCLI_CTRL_AUTH                   2
-#define APCLI_CTRL_AUTH_2                 3
-#define APCLI_CTRL_ASSOC                  4
-#define APCLI_CTRL_DEASSOC                5
-#define APCLI_CTRL_CONNECTED              6
-#define APCLI_MAX_CTRL_STATE              7
-
-#define APCLI_CTRL_MACHINE_BASE           0
-#define APCLI_CTRL_JOIN_REQ               0
-#define APCLI_CTRL_PROBE_RSP              1
-#define APCLI_CTRL_AUTH_RSP               2
-#define APCLI_CTRL_DISCONNECT_REQ         3
-#define APCLI_CTRL_PEER_DISCONNECT_REQ    4
-#define APCLI_CTRL_ASSOC_RSP              5
-#define APCLI_CTRL_DEASSOC_RSP            6
-#define APCLI_CTRL_JOIN_REQ_TIMEOUT       7
-#define APCLI_CTRL_AUTH_REQ_TIMEOUT       8
-#define APCLI_CTRL_ASSOC_REQ_TIMEOUT      9
-#define APCLI_MAX_CTRL_MSG                10
-
-#define APCLI_CTRL_FUNC_SIZE              (APCLI_MAX_CTRL_STATE * APCLI_MAX_CTRL_MSG)
-
-
-#endif // APCLI_SUPPORT //
-
-
-// =============================================================================
-
-// value domain of 802.11 header FC.Tyte, which is b3..b2 of the 1st-byte of MAC header
-#define BTYPE_MGMT                  0
-#define BTYPE_CNTL                  1
-#define BTYPE_DATA                  2
-
-// value domain of 802.11 MGMT frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
-#define SUBTYPE_ASSOC_REQ           0
-#define SUBTYPE_ASSOC_RSP           1
-#define SUBTYPE_REASSOC_REQ         2
-#define SUBTYPE_REASSOC_RSP         3
-#define SUBTYPE_PROBE_REQ           4
-#define SUBTYPE_PROBE_RSP           5
-#define SUBTYPE_BEACON              8
-#define SUBTYPE_ATIM                9
-#define SUBTYPE_DISASSOC            10
-#define SUBTYPE_AUTH                11
-#define SUBTYPE_DEAUTH              12
-#define SUBTYPE_ACTION              13
-#define SUBTYPE_ACTION_NO_ACK              14
-
-// value domain of 802.11 CNTL frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
-#define SUBTYPE_WRAPPER		7
-#define SUBTYPE_BLOCK_ACK_REQ       8
-#define SUBTYPE_BLOCK_ACK           9
-#define SUBTYPE_PS_POLL             10
-#define SUBTYPE_RTS                 11
-#define SUBTYPE_CTS                 12
-#define SUBTYPE_ACK                 13
-#define SUBTYPE_CFEND               14
-#define SUBTYPE_CFEND_CFACK         15
-
-// value domain of 802.11 DATA frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
-#define SUBTYPE_DATA                0
-#define SUBTYPE_DATA_CFACK          1
-#define SUBTYPE_DATA_CFPOLL         2
-#define SUBTYPE_DATA_CFACK_CFPOLL   3
-#define SUBTYPE_NULL_FUNC           4
-#define SUBTYPE_CFACK               5
-#define SUBTYPE_CFPOLL              6
-#define SUBTYPE_CFACK_CFPOLL        7
-#define SUBTYPE_QDATA               8
-#define SUBTYPE_QDATA_CFACK         9
-#define SUBTYPE_QDATA_CFPOLL        10
-#define SUBTYPE_QDATA_CFACK_CFPOLL  11
-#define SUBTYPE_QOS_NULL            12
-#define SUBTYPE_QOS_CFACK           13
-#define SUBTYPE_QOS_CFPOLL          14
-#define SUBTYPE_QOS_CFACK_CFPOLL    15
-
-// ACK policy of QOS Control field bit 6:5
-#define NORMAL_ACK                  0x00  // b6:5 = 00
-#define NO_ACK                      0x20  // b6:5 = 01
-#define NO_EXPLICIT_ACK             0x40  // b6:5 = 10
-#define BLOCK_ACK                   0x60  // b6:5 = 11
-
-//
-// rtmp_data.c use these definition
-//
-#define LENGTH_802_11               24
-#define LENGTH_802_11_AND_H         30
-#define LENGTH_802_11_CRC_H         34
-#define LENGTH_802_11_CRC           28
-#define LENGTH_802_11_WITH_ADDR4    30
-#define LENGTH_802_3                14
-#define LENGTH_802_3_TYPE           2
-#define LENGTH_802_1_H              8
-#define LENGTH_EAPOL_H              4
-#define LENGTH_WMMQOS_H				2
-#define LENGTH_CRC                  4
-#define MAX_SEQ_NUMBER              0x0fff
-#define LENGTH_802_3_NO_TYPE		12
-#define LENGTH_802_1Q				4 /* VLAN related */
-
-// STA_CSR4.field.TxResult
-#define TX_RESULT_SUCCESS           0
-#define TX_RESULT_ZERO_LENGTH       1
-#define TX_RESULT_UNDER_RUN         2
-#define TX_RESULT_OHY_ERROR         4
-#define TX_RESULT_RETRY_FAIL        6
-
-// All PHY rate summary in TXD
-// Preamble MODE in TxD
-#define MODE_CCK	0
-#define MODE_OFDM   1
-#ifdef DOT11_N_SUPPORT
-#define MODE_HTMIX	2
-#define MODE_HTGREENFIELD	3
-#endif // DOT11_N_SUPPORT //
-// MCS for CCK.  BW.SGI.STBC are reserved
-#define MCS_LONGP_RATE_1                      0	 // long preamble CCK 1Mbps
-#define MCS_LONGP_RATE_2                      1	// long preamble CCK 1Mbps
-#define MCS_LONGP_RATE_5_5                    2
-#define MCS_LONGP_RATE_11                     3
-#define MCS_SHORTP_RATE_1                      4	 // long preamble CCK 1Mbps. short is forbidden in 1Mbps
-#define MCS_SHORTP_RATE_2                      5	// short preamble CCK 2Mbps
-#define MCS_SHORTP_RATE_5_5                    6
-#define MCS_SHORTP_RATE_11                     7
-// To send duplicate legacy OFDM. set BW=BW_40.  SGI.STBC are reserved
-#define MCS_RATE_6                      0   // legacy OFDM
-#define MCS_RATE_9                      1   // OFDM
-#define MCS_RATE_12                     2   // OFDM
-#define MCS_RATE_18                     3   // OFDM
-#define MCS_RATE_24                     4  // OFDM
-#define MCS_RATE_36                     5   // OFDM
-#define MCS_RATE_48                     6  // OFDM
-#define MCS_RATE_54                     7 // OFDM
-// HT
-#define MCS_0		0	// 1S
-#define MCS_1		1
-#define MCS_2		2
-#define MCS_3		3
-#define MCS_4		4
-#define MCS_5		5
-#define MCS_6		6
-#define MCS_7		7
-#define MCS_8		8	// 2S
-#define MCS_9		9
-#define MCS_10		10
-#define MCS_11		11
-#define MCS_12		12
-#define MCS_13		13
-#define MCS_14		14
-#define MCS_15		15
-#define MCS_16		16	// 3*3
-#define MCS_17		17
-#define MCS_18		18
-#define MCS_19		19
-#define MCS_20		20
-#define MCS_21		21
-#define MCS_22		22
-#define MCS_23		23
-#define MCS_32		32
-#define MCS_AUTO		33
-
-#ifdef DOT11_N_SUPPORT
-// OID_HTPHYMODE
-// MODE
-#define HTMODE_MM	0
-#define HTMODE_GF	1
-#endif // DOT11_N_SUPPORT //
-
-// Fixed Tx MODE - HT, CCK or OFDM
-#define FIXED_TXMODE_HT		0
-#define FIXED_TXMODE_CCK	1
-#define FIXED_TXMODE_OFDM	2
-// BW
-#define BW_20		BAND_WIDTH_20
-#define BW_40		BAND_WIDTH_40
-#define BW_BOTH		BAND_WIDTH_BOTH
-#define BW_10		BAND_WIDTH_10	// 802.11j has 10MHz. This definition is for internal usage. doesn't fill in the IE or other field.
-
-#ifdef DOT11_N_SUPPORT
-// SHORTGI
-#define GI_400		GAP_INTERVAL_400	// only support in HT mode
-#define GI_BOTH		GAP_INTERVAL_BOTH
-#endif // DOT11_N_SUPPORT //
-#define GI_800		GAP_INTERVAL_800
-// STBC
-#define STBC_NONE	0
-#ifdef DOT11_N_SUPPORT
-#define STBC_USE	1	// limited use in rt2860b phy
-#define RXSTBC_ONE	1	// rx support of one spatial stream
-#define RXSTBC_TWO	2	// rx support of 1 and 2 spatial stream
-#define RXSTBC_THR	3	// rx support of 1~3 spatial stream
-// MCS FEEDBACK
-#define MCSFBK_NONE	0  // not support mcs feedback /
-#define MCSFBK_RSV	1	// reserved
-#define MCSFBK_UNSOLICIT	2	// only support unsolict mcs feedback
-#define MCSFBK_MRQ	3	// response to both MRQ and unsolict mcs feedback
-
-// MIMO power safe
-#define	MMPS_STATIC	0
-#define	MMPS_DYNAMIC		1
-#define   MMPS_RSV		2
-#define MMPS_ENABLE		3
-
-
-// A-MSDU size
-#define	AMSDU_0	0
-#define	AMSDU_1		1
-
-#endif // DOT11_N_SUPPORT //
-
-// MCS use 7 bits
-#define TXRATEMIMO		0x80
-#define TXRATEMCS		0x7F
-#define TXRATEOFDM		0x7F
-#define RATE_1                      0
-#define RATE_2                      1
-#define RATE_5_5                    2
-#define RATE_11                     3
-#define RATE_6                      4   // OFDM
-#define RATE_9                      5   // OFDM
-#define RATE_12                     6   // OFDM
-#define RATE_18                     7   // OFDM
-#define RATE_24                     8   // OFDM
-#define RATE_36                     9   // OFDM
-#define RATE_48                     10  // OFDM
-#define RATE_54                     11  // OFDM
-#define RATE_FIRST_OFDM_RATE        RATE_6
-#define RATE_LAST_OFDM_RATE		RATE_54
-#define RATE_6_5                    12  // HT mix
-#define RATE_13                     13  // HT mix
-#define RATE_19_5                   14  // HT mix
-#define RATE_26                     15  // HT mix
-#define RATE_39                     16  // HT mix
-#define RATE_52                     17  // HT mix
-#define RATE_58_5                   18  // HT mix
-#define RATE_65                     19  // HT mix
-#define RATE_78                     20  // HT mix
-#define RATE_104                    21  // HT mix
-#define RATE_117                    22  // HT mix
-#define RATE_130                    23  // HT mix
-//#define RATE_AUTO_SWITCH            255 // for StaCfg.FixedTxRate only
-#define HTRATE_0                      12
-#define RATE_FIRST_MM_RATE        HTRATE_0
-#define RATE_FIRST_HT_RATE        HTRATE_0
-#define RATE_LAST_HT_RATE        HTRATE_0
-
-// pTxWI->txop
-#define IFS_HTTXOP                 0	// The txop will be handles by ASIC.
-#define IFS_PIFS                    1
-#define IFS_SIFS                    2
-#define IFS_BACKOFF                 3
-
-// pTxD->RetryMode
-#define LONG_RETRY                  1
-#define SHORT_RETRY                 0
-
-// Country Region definition
-#define REGION_MINIMUM_BG_BAND            0
-#define REGION_0_BG_BAND                  0       // 1-11
-#define REGION_1_BG_BAND                  1       // 1-13
-#define REGION_2_BG_BAND                  2       // 10-11
-#define REGION_3_BG_BAND                  3       // 10-13
-#define REGION_4_BG_BAND                  4       // 14
-#define REGION_5_BG_BAND                  5       // 1-14
-#define REGION_6_BG_BAND                  6       // 3-9
-#define REGION_7_BG_BAND                  7       // 5-13
-#define REGION_31_BG_BAND                 31       // 5-13
-#define REGION_MAXIMUM_BG_BAND            7
-
-#define REGION_MINIMUM_A_BAND             0
-#define REGION_0_A_BAND                   0       // 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165
-#define REGION_1_A_BAND                   1       // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
-#define REGION_2_A_BAND                   2       // 36, 40, 44, 48, 52, 56, 60, 64
-#define REGION_3_A_BAND                   3       // 52, 56, 60, 64, 149, 153, 157, 161
-#define REGION_4_A_BAND                   4       // 149, 153, 157, 161, 165
-#define REGION_5_A_BAND                   5       // 149, 153, 157, 161
-#define REGION_6_A_BAND                   6       // 36, 40, 44, 48
-#define REGION_7_A_BAND                   7       // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, 169, 173
-#define REGION_8_A_BAND                   8       // 52, 56, 60, 64
-#define REGION_9_A_BAND                   9       // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165
-#define REGION_10_A_BAND                  10	  // 36, 40, 44, 48, 149, 153, 157, 161, 165
-#define REGION_11_A_BAND                  11	  // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161
-#define REGION_12_A_BAND                  12       // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
-#define REGION_13_A_BAND                  13       // 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161
-#define REGION_14_A_BAND                  14       // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165
-#define REGION_15_A_BAND                  15       // 149, 153, 157, 161, 165, 169, 173
-#define REGION_MAXIMUM_A_BAND             15
-
-// pTxD->CipherAlg
-#define CIPHER_NONE                 0
-#define CIPHER_WEP64                1
-#define CIPHER_WEP128               2
-#define CIPHER_TKIP                 3
-#define CIPHER_AES                  4
-#define CIPHER_CKIP64               5
-#define CIPHER_CKIP128              6
-#define CIPHER_TKIP_NO_MIC          7       // MIC appended by driver: not a valid value in hardware key table
-#define CIPHER_SMS4					8
-
-
-// LED Status.
-#define LED_LINK_DOWN               0
-#define LED_LINK_UP                 1
-#define LED_RADIO_OFF               2
-#define LED_RADIO_ON                3
-#define LED_HALT                    4
-#define LED_WPS                     5
-#define LED_ON_SITE_SURVEY          6
-#define LED_POWER_UP                7
-
-
-// value domain of pAd->LedCntl.LedMode and E2PROM
-#define LED_MODE_DEFAULT            0
-#define LED_MODE_TWO_LED			1
-//#define LED_MODE_SIGNAL_STREGTH		8  // EEPROM define =8
-#define LED_MODE_SIGNAL_STREGTH		0x40 // EEPROM define = 64
-
-// RC4 init value, used fro WEP & TKIP
-#define PPPINITFCS32                0xffffffff   /* Initial FCS value */
-
-// value domain of pAd->StaCfg.PortSecured. 802.1X controlled port definition
-#define WPA_802_1X_PORT_SECURED     1
-#define WPA_802_1X_PORT_NOT_SECURED 2
-
-#define PAIRWISE_KEY                1
-#define GROUP_KEY                   2
-
-//definition of DRS
-#define MAX_STEP_OF_TX_RATE_SWITCH	32
-
-
-// pre-allocated free NDIS PACKET/BUFFER poll for internal usage
-#define MAX_NUM_OF_FREE_NDIS_PACKET 128
-
-//Block ACK
-#define MAX_TX_REORDERBUF   64
-#define MAX_RX_REORDERBUF   64
-#define DEFAULT_TX_TIMEOUT   30
-#define DEFAULT_RX_TIMEOUT   30
-
-// definition of Recipient or Originator
-#define I_RECIPIENT                  TRUE
-#define I_ORIGINATOR                   FALSE
-
-#define DEFAULT_BBP_TX_POWER        0
-#define DEFAULT_RF_TX_POWER         5
-
-#define MAX_INI_BUFFER_SIZE		4096
-#define MAX_PARAM_BUFFER_SIZE		(2048) // enough for ACL (18*64)
-											//18 : the length of Mac address acceptable format "01:02:03:04:05:06;")
-											//64 : MAX_NUM_OF_ACL_LIST
-// definition of pAd->OpMode
-#define OPMODE_STA                  0
-#define OPMODE_AP                   1
-//#define OPMODE_L3_BRG               2       // as AP and STA at the same time
-
-#ifdef RT_BIG_ENDIAN
-#define DIR_READ                    0
-#define DIR_WRITE                   1
-#define TYPE_TXD                    0
-#define TYPE_RXD                    1
-#define TYPE_TXINFO					0
-#define TYPE_RXINFO					1
-#define TYPE_TXWI					0
-#define TYPE_RXWI					1
-#endif
-
-// ========================= AP rtmp_def.h ===========================
-// value domain for pAd->EventTab.Log[].Event
-#define EVENT_RESET_ACCESS_POINT    0 // Log = "hh:mm:ss   Restart Access Point"
-#define EVENT_ASSOCIATED            1 // Log = "hh:mm:ss   STA 00:01:02:03:04:05 associated"
-#define EVENT_DISASSOCIATED         2 // Log = "hh:mm:ss   STA 00:01:02:03:04:05 left this BSS"
-#define EVENT_AGED_OUT              3 // Log = "hh:mm:ss   STA 00:01:02:03:04:05 was aged-out and removed from this BSS"
-#define EVENT_COUNTER_M             4
-#define EVENT_INVALID_PSK           5
-#define EVENT_MAX_EVENT_TYPE        6
-// ==== end of AP rtmp_def.h ============
-
-// definition RSSI Number
-#define RSSI_0					0
-#define RSSI_1					1
-#define RSSI_2					2
-
-// definition of radar detection
-#define RD_NORMAL_MODE				0	// Not found radar signal
-#define RD_SWITCHING_MODE			1	// Found radar signal, and doing channel switch
-#define RD_SILENCE_MODE				2	// After channel switch, need to be silence a while to ensure radar not found
-
-//Driver defined cid for mapping status and command.
-#define  SLEEPCID	0x11
-#define  WAKECID	0x22
-#define  QUERYPOWERCID	0x33
-#define  OWNERMCU	0x1
-#define  OWNERCPU	0x0
-
-// MBSSID definition
-#define ENTRY_NOT_FOUND             0xFF
-
-
-/* After Linux 2.6.9,
- * VLAN module use Private (from user) interface flags (netdevice->priv_flags).
- * #define IFF_802_1Q_VLAN 0x1         --    802.1Q VLAN device.  in if.h
- * ref to ip_sabotage_out() [ out->priv_flags & IFF_802_1Q_VLAN ] in br_netfilter.c
- *
- * For this reason, we MUST use EVEN value in priv_flags
- */
-#define INT_MAIN			0x0100
-#define INT_MBSSID			0x0200
-#define INT_WDS				0x0300
-#define INT_APCLI			0x0400
-#define INT_MESH			0x0500
-
-#define INF_MAIN_DEV_NAME		"wlan"
-#define INF_MBSSID_DEV_NAME		"wlan"
-#define INF_WDS_DEV_NAME		"wds"
-#define INF_APCLI_DEV_NAME		"apcli"
-#define INF_MESH_DEV_NAME		"mesh"
-
-// Use bitmap to allow coexist of ATE_TXFRAME and ATE_RXFRAME(i.e.,to support LoopBack mode).
-#ifdef RALINK_ATE
-#define	ATE_START                   0x00   // Start ATE
-#define	ATE_STOP                    0x80   // Stop ATE
-#define	ATE_TXCONT                  0x05   // Continuous Transmit
-#define	ATE_TXCARR                  0x09   // Transmit Carrier
-#define	ATE_TXCARRSUPP              0x11   // Transmit Carrier Suppression
-#define	ATE_TXFRAME                 0x01   // Transmit Frames
-#define	ATE_RXFRAME                 0x02   // Receive Frames
-#ifdef RALINK_28xx_QA
-#define ATE_TXSTOP                  0xe2   // Stop Transmition(i.e., TXCONT, TXCARR, TXCARRSUPP, and TXFRAME)
-#define ATE_RXSTOP					0xfd   // Stop receiving Frames
-#define	BBP22_TXFRAME				0x00   // Transmit Frames
-#define	BBP22_TXCONT_OR_CARRSUPP    0x80   // Continuous Transmit or Carrier Suppression
-#define	BBP22_TXCARR                0xc1   // Transmit Carrier
-#define	BBP24_TXCONT                0x00   // Continuous Transmit
-#define	BBP24_CARRSUPP              0x01   // Carrier Suppression
-#endif // RALINK_28xx_QA //
-#endif // RALINK_ATE //
-
-// WEP Key TYPE
-#define WEP_HEXADECIMAL_TYPE    0
-#define WEP_ASCII_TYPE          1
-
-
-
-// WIRELESS EVENTS definition
-/* Max number of char in custom event, refer to wireless_tools.28/wireless.20.h */
-#define IW_CUSTOM_MAX_LEN							255	/* In bytes */
-
-// For system event - start
-#define	IW_SYS_EVENT_FLAG_START                     0x0200
-#define	IW_ASSOC_EVENT_FLAG                         0x0200
-#define	IW_DISASSOC_EVENT_FLAG                      0x0201
-#define	IW_DEAUTH_EVENT_FLAG				0x0202
-#define	IW_AGEOUT_EVENT_FLAG				0x0203
-#define	IW_COUNTER_MEASURES_EVENT_FLAG              0x0204
-#define	IW_REPLAY_COUNTER_DIFF_EVENT_FLAG           0x0205
-#define	IW_RSNIE_DIFF_EVENT_FLAG				0x0206
-#define	IW_MIC_DIFF_EVENT_FLAG					0x0207
-#define IW_ICV_ERROR_EVENT_FLAG						0x0208
-#define IW_MIC_ERROR_EVENT_FLAG						0x0209
-#define IW_GROUP_HS_TIMEOUT_EVENT_FLAG				0x020A
-#define	IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG			0x020B
-#define IW_RSNIE_SANITY_FAIL_EVENT_FLAG				0x020C
-#define IW_SET_KEY_DONE_WPA1_EVENT_FLAG				0x020D
-#define IW_SET_KEY_DONE_WPA2_EVENT_FLAG				0x020E
-#define IW_STA_LINKUP_EVENT_FLAG					0x020F
-#define IW_STA_LINKDOWN_EVENT_FLAG					0x0210
-#define IW_SCAN_COMPLETED_EVENT_FLAG				0x0211
-#define IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG				0x0212
-// if add new system event flag, please upadte the IW_SYS_EVENT_FLAG_END
-#define	IW_SYS_EVENT_FLAG_END                       0x0212
-#define	IW_SYS_EVENT_TYPE_NUM						(IW_SYS_EVENT_FLAG_END - IW_SYS_EVENT_FLAG_START + 1)
-// For system event - end
-
-// For spoof attack event - start
-#define	IW_SPOOF_EVENT_FLAG_START                   0x0300
-#define IW_CONFLICT_SSID_EVENT_FLAG					0x0300
-#define IW_SPOOF_ASSOC_RESP_EVENT_FLAG				0x0301
-#define IW_SPOOF_REASSOC_RESP_EVENT_FLAG			0x0302
-#define IW_SPOOF_PROBE_RESP_EVENT_FLAG				0x0303
-#define IW_SPOOF_BEACON_EVENT_FLAG					0x0304
-#define IW_SPOOF_DISASSOC_EVENT_FLAG				0x0305
-#define IW_SPOOF_AUTH_EVENT_FLAG					0x0306
-#define IW_SPOOF_DEAUTH_EVENT_FLAG					0x0307
-#define IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG			0x0308
-#define IW_REPLAY_ATTACK_EVENT_FLAG					0x0309
-// if add new spoof attack event flag, please upadte the IW_SPOOF_EVENT_FLAG_END
-#define	IW_SPOOF_EVENT_FLAG_END                     0x0309
-#define	IW_SPOOF_EVENT_TYPE_NUM						(IW_SPOOF_EVENT_FLAG_END - IW_SPOOF_EVENT_FLAG_START + 1)
-// For spoof attack event - end
-
-// For flooding attack event - start
-#define	IW_FLOOD_EVENT_FLAG_START                   0x0400
-#define IW_FLOOD_AUTH_EVENT_FLAG					0x0400
-#define IW_FLOOD_ASSOC_REQ_EVENT_FLAG				0x0401
-#define IW_FLOOD_REASSOC_REQ_EVENT_FLAG				0x0402
-#define IW_FLOOD_PROBE_REQ_EVENT_FLAG				0x0403
-#define IW_FLOOD_DISASSOC_EVENT_FLAG				0x0404
-#define IW_FLOOD_DEAUTH_EVENT_FLAG					0x0405
-#define IW_FLOOD_EAP_REQ_EVENT_FLAG					0x0406
-// if add new flooding attack event flag, please upadte the IW_FLOOD_EVENT_FLAG_END
-#define	IW_FLOOD_EVENT_FLAG_END				0x0406
-#define	IW_FLOOD_EVENT_TYPE_NUM						(IW_FLOOD_EVENT_FLAG_END - IW_FLOOD_EVENT_FLAG_START + 1)
-// For flooding attack - end
-
-// End - WIRELESS EVENTS definition
-
-#ifdef CONFIG_STA_SUPPORT
-// definition for DLS, kathy
-#define	MAX_NUM_OF_INIT_DLS_ENTRY   1
-#define	MAX_NUM_OF_DLS_ENTRY        MAX_NUMBER_OF_DLS_ENTRY
-
-//Block ACK, kathy
-#define MAX_TX_REORDERBUF		64
-#define MAX_RX_REORDERBUF		64
-#define DEFAULT_TX_TIMEOUT		30
-#define DEFAULT_RX_TIMEOUT		30
-#define MAX_BARECI_SESSION		8
-
-#ifndef IW_ESSID_MAX_SIZE
-/* Maximum size of the ESSID and pAd->nickname strings */
-#define IW_ESSID_MAX_SIZE		32
-#endif
-#endif // CONFIG_STA_SUPPORT //
-
-#ifdef MCAST_RATE_SPECIFIC
-#define MCAST_DISABLE	0
-#define MCAST_CCK		1
-#define MCAST_OFDM		2
-#define MCAST_HTMIX		3
-#endif // MCAST_RATE_SPECIFIC //
-
-// For AsicRadioOff/AsicRadioOn function
-#define DOT11POWERSAVE		0
-#define GUIRADIO_OFF		1
-#define RTMP_HALT		    2
-#define GUI_IDLE_POWER_SAVE		3
-// --
-
-
-// definition for WpaSupport flag
-#define WPA_SUPPLICANT_DISABLE				0
-#define WPA_SUPPLICANT_ENABLE				1
-#define	WPA_SUPPLICANT_ENABLE_WITH_WEB_UI	2
-
-// definition for Antenna Diversity flag
-#ifdef ANT_DIVERSITY_SUPPORT
-enum ANT_DIVERSITY_TYPE {
-    ANT_DIVERSITY_DISABLE = 0,
-    ANT_DIVERSITY_ENABLE = 1,
-    ANT_FIX_ANT1 = 2,
-    ANT_FIX_ANT2 = 3
-};
-#endif // ANT_DIVERSITY_SUPPORT //
-
-// Endian byte swapping codes
-#define SWAP16(x) \
-    ((UINT16)( \
-    (((UINT16)(x) & (UINT16) 0x00ffU) << 8) | \
-    (((UINT16)(x) & (UINT16) 0xff00U) >> 8) ))
-
-#define SWAP32(x) \
-    ((UINT32)( \
-    (((UINT32)(x) & (UINT32) 0x000000ffUL) << 24) | \
-    (((UINT32)(x) & (UINT32) 0x0000ff00UL) <<  8) | \
-    (((UINT32)(x) & (UINT32) 0x00ff0000UL) >>  8) | \
-    (((UINT32)(x) & (UINT32) 0xff000000UL) >> 24) ))
-
-#define SWAP64(x) \
-    ((UINT64)( \
-    (UINT64)(((UINT64)(x) & (UINT64) 0x00000000000000ffULL) << 56) | \
-    (UINT64)(((UINT64)(x) & (UINT64) 0x000000000000ff00ULL) << 40) | \
-    (UINT64)(((UINT64)(x) & (UINT64) 0x0000000000ff0000ULL) << 24) | \
-    (UINT64)(((UINT64)(x) & (UINT64) 0x00000000ff000000ULL) <<  8) | \
-    (UINT64)(((UINT64)(x) & (UINT64) 0x000000ff00000000ULL) >>  8) | \
-    (UINT64)(((UINT64)(x) & (UINT64) 0x0000ff0000000000ULL) >> 24) | \
-    (UINT64)(((UINT64)(x) & (UINT64) 0x00ff000000000000ULL) >> 40) | \
-    (UINT64)(((UINT64)(x) & (UINT64) 0xff00000000000000ULL) >> 56) ))
-
-#ifdef RT_BIG_ENDIAN
-
-#define cpu2le64(x) SWAP64((x))
-#define le2cpu64(x) SWAP64((x))
-#define cpu2le32(x) SWAP32((x))
-#define le2cpu32(x) SWAP32((x))
-#define cpu2le16(x) SWAP16((x))
-#define le2cpu16(x) SWAP16((x))
-#define cpu2be64(x) ((UINT64)(x))
-#define be2cpu64(x) ((UINT64)(x))
-#define cpu2be32(x) ((UINT32)(x))
-#define be2cpu32(x) ((UINT32)(x))
-#define cpu2be16(x) ((UINT16)(x))
-#define be2cpu16(x) ((UINT16)(x))
-
-#else   // Little_Endian
-
-#define cpu2le64(x) ((UINT64)(x))
-#define le2cpu64(x) ((UINT64)(x))
-#define cpu2le32(x) ((UINT32)(x))
-#define le2cpu32(x) ((UINT32)(x))
-#define cpu2le16(x) ((UINT16)(x))
-#define le2cpu16(x) ((UINT16)(x))
-#define cpu2be64(x) SWAP64((x))
-#define be2cpu64(x) SWAP64((x))
-#define cpu2be32(x) SWAP32((x))
-#define be2cpu32(x) SWAP32((x))
-#define cpu2be16(x) SWAP16((x))
-#define be2cpu16(x) SWAP16((x))
-
-#endif  // RT_BIG_ENDIAN
-
-#define ABS(_x, _y) ((_x) > (_y)) ? ((_x) -(_y)) : ((_y) -(_x))
-
-
-#define A2Dec(_X, _p)				\
-{									\
-	UCHAR *p;						\
-	_X = 0;							\
-	p = _p;							\
-	while (((*p >= '0') && (*p <= '9')))		\
-	{												\
-		if ((*p >= '0') && (*p <= '9'))		\
-			_X = _X * 10 + *p - 48;					\
-		p++;										\
-	}												\
-}
-
-
-#define A2Hex(_X, _p)				\
-do{									\
-	char *__p;						\
-	(_X) = 0;							\
-	__p = (char *)(_p);							\
-	while (((*__p >= 'a') && (*__p <= 'f')) || ((*__p >= 'A') && (*__p <= 'F')) || ((*__p >= '0') && (*__p <= '9')))		\
-	{												\
-		if ((*__p >= 'a') && (*__p <= 'f'))				\
-			(_X) = (_X) * 16 + *__p - 87;					\
-		else if ((*__p >= 'A') && (*__p <= 'F'))		\
-			(_X) = (_X) * 16 + *__p - 55;					\
-		else if ((*__p >= '0') && (*__p <= '9'))		\
-			(_X) = (_X) * 16 + *__p - 48;					\
-		__p++;										\
-	}												\
-}while(0)
-
-#endif  // __RTMP_DEF_H__
diff --git a/drivers/staging/rt3090/rtmp_dot11.h b/drivers/staging/rt3090/rtmp_dot11.h
deleted file mode 100644
index a637825..0000000
--- a/drivers/staging/rt3090/rtmp_dot11.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-*/
-
-#ifndef __DOT11_BASE_H__
-#define __DOT11_BASE_H__
-
-#include "rtmp_type.h"
-
-
-// 4-byte HTC field.  maybe included in any frame except non-QOS data frame.  The Order bit must set 1.
-typedef struct PACKED {
-#ifdef RT_BIG_ENDIAN
-    UINT32		RDG:1;	//RDG / More PPDU
-    UINT32		ACConstraint:1;	//feedback request
-    UINT32		rsv:5;  //calibration sequence
-    UINT32		ZLFAnnouce:1;	// ZLF announcement
-    UINT32		CSISTEERING:2;	//CSI/ STEERING
-    UINT32		FBKReq:2;	//feedback request
-    UINT32		CalSeq:2;  //calibration sequence
-    UINT32		CalPos:2;	// calibration position
-    UINT32		MFBorASC:7;	//Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available
-    UINT32		MFS:3;	//SET to the received value of MRS. 0x111 for unsolicited MFB.
-    UINT32		MRSorASI:3;	// MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110.
-    UINT32		MRQ:1;	//MCS feedback. Request for a MCS feedback
-    UINT32		TRQ:1;	//sounding request
-    UINT32		MA:1;	//management action payload exist in (QoS Null+HTC)
-#else
-    UINT32		MA:1;	//management action payload exist in (QoS Null+HTC)
-    UINT32		TRQ:1;	//sounding request
-    UINT32		MRQ:1;	//MCS feedback. Request for a MCS feedback
-    UINT32		MRSorASI:3;	// MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110.
-    UINT32		MFS:3;	//SET to the received value of MRS. 0x111 for unsolicited MFB.
-    UINT32		MFBorASC:7;	//Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available
-    UINT32		CalPos:2;	// calibration position
-    UINT32		CalSeq:2;  //calibration sequence
-    UINT32		FBKReq:2;	//feedback request
-    UINT32		CSISTEERING:2;	//CSI/ STEERING
-    UINT32		ZLFAnnouce:1;	// ZLF announcement
-    UINT32		rsv:5;  //calibration sequence
-    UINT32		ACConstraint:1;	//feedback request
-    UINT32		RDG:1;	//RDG / More PPDU
-#endif /* !RT_BIG_ENDIAN */
-} HT_CONTROL, *PHT_CONTROL;
-
-// 2-byte QOS CONTROL field
-typedef struct PACKED {
-#ifdef RT_BIG_ENDIAN
-    USHORT      Txop_QueueSize:8;
-    USHORT      AMsduPresent:1;
-    USHORT      AckPolicy:2;  //0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP  3: BA
-    USHORT      EOSP:1;
-    USHORT      TID:4;
-#else
-    USHORT      TID:4;
-    USHORT      EOSP:1;
-    USHORT      AckPolicy:2;  //0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP  3: BA
-    USHORT      AMsduPresent:1;
-    USHORT      Txop_QueueSize:8;
-#endif /* !RT_BIG_ENDIAN */
-} QOS_CONTROL, *PQOS_CONTROL;
-
-
-// 2-byte Frame control field
-typedef	struct	PACKED {
-#ifdef RT_BIG_ENDIAN
-	USHORT		Order:1;			// Strict order expected
-	USHORT		Wep:1;				// Wep data
-	USHORT		MoreData:1;			// More data bit
-	USHORT		PwrMgmt:1;			// Power management bit
-	USHORT		Retry:1;			// Retry status bit
-	USHORT		MoreFrag:1;			// More fragment bit
-	USHORT		FrDs:1;				// From DS indication
-	USHORT		ToDs:1;				// To DS indication
-	USHORT		SubType:4;			// MSDU subtype
-	USHORT		Type:2;				// MSDU type
-	USHORT		Ver:2;				// Protocol version
-#else
-	USHORT		Ver:2;				// Protocol version
-	USHORT		Type:2;				// MSDU type
-	USHORT		SubType:4;			// MSDU subtype
-	USHORT		ToDs:1;				// To DS indication
-	USHORT		FrDs:1;				// From DS indication
-	USHORT		MoreFrag:1;			// More fragment bit
-	USHORT		Retry:1;			// Retry status bit
-	USHORT		PwrMgmt:1;			// Power management bit
-	USHORT		MoreData:1;			// More data bit
-	USHORT		Wep:1;				// Wep data
-	USHORT		Order:1;			// Strict order expected
-#endif /* !RT_BIG_ENDIAN */
-} FRAME_CONTROL, *PFRAME_CONTROL;
-
-typedef	struct	PACKED _HEADER_802_11	{
-    FRAME_CONTROL   FC;
-    USHORT          Duration;
-    UCHAR           Addr1[MAC_ADDR_LEN];
-    UCHAR           Addr2[MAC_ADDR_LEN];
-	UCHAR			Addr3[MAC_ADDR_LEN];
-#ifdef RT_BIG_ENDIAN
-	USHORT			Sequence:12;
-	USHORT			Frag:4;
-#else
-	USHORT			Frag:4;
-	USHORT			Sequence:12;
-#endif /* !RT_BIG_ENDIAN */
-	UCHAR			Octet[0];
-}	HEADER_802_11, *PHEADER_802_11;
-
-typedef struct PACKED _PSPOLL_FRAME {
-    FRAME_CONTROL   FC;
-    USHORT          Aid;
-    UCHAR           Bssid[MAC_ADDR_LEN];
-    UCHAR           Ta[MAC_ADDR_LEN];
-}   PSPOLL_FRAME, *PPSPOLL_FRAME;
-
-typedef	struct	PACKED _RTS_FRAME	{
-    FRAME_CONTROL   FC;
-    USHORT          Duration;
-    UCHAR           Addr1[MAC_ADDR_LEN];
-    UCHAR           Addr2[MAC_ADDR_LEN];
-}RTS_FRAME, *PRTS_FRAME;
-
-#endif // __DOT11_BASE_H__ //
diff --git a/drivers/staging/rt3090/rtmp_iface.h b/drivers/staging/rt3090/rtmp_iface.h
deleted file mode 100644
index 168d079..0000000
--- a/drivers/staging/rt3090/rtmp_iface.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	rt_iface.h
-
-    Abstract:
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
- */
-
-#ifndef __RTMP_IFACE_H__
-#define __RTMP_IFACE_H__
-
-#ifdef RTMP_PCI_SUPPORT
-#include "rtmp_pci.h"
-#endif // RTMP_PCI_SUPPORT //
-
-
-typedef struct _INF_PCI_CONFIG_
-{
-	unsigned long	CSRBaseAddress;     // PCI MMIO Base Address, all access will use
-	unsigned int	irq_num;
-}INF_PCI_CONFIG;
-
-
-typedef struct _INF_USB_CONFIG_
-{
-	UINT8                BulkInEpAddr;		// bulk-in endpoint address
-	UINT8                BulkOutEpAddr[6];	// bulk-out endpoint address
-}INF_USB_CONFIG;
-
-
-typedef struct _INF_RBUS_CONFIG_
-{
-	unsigned long		csr_addr;
-	unsigned int		irq;
-}INF_RBUS_CONFIG;
-
-
-typedef enum _RTMP_INF_TYPE_
-{
-	RTMP_DEV_INF_UNKNOWN = 0,
-	RTMP_DEV_INF_PCI = 1,
-	RTMP_DEV_INF_USB = 2,
-	RTMP_DEV_INF_RBUS = 4,
-}RTMP_INF_TYPE;
-
-
-typedef union _RTMP_INF_CONFIG_{
-	struct _INF_PCI_CONFIG_			pciConfig;
-	struct _INF_USB_CONFIG_			usbConfig;
-	struct _INF_RBUS_CONFIG_		rbusConfig;
-}RTMP_INF_CONFIG;
-
-#endif // __RTMP_IFACE_H__ //
diff --git a/drivers/staging/rt3090/rtmp_mac.h b/drivers/staging/rt3090/rtmp_mac.h
deleted file mode 100644
index c57b295..0000000
--- a/drivers/staging/rt3090/rtmp_mac.h
+++ /dev/null
@@ -1,2304 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtmp_mac.h
-
-	Abstract:
-	Ralink Wireless Chip MAC related definition & structures
-
-	Revision History:
-	Who			When		  What
-	--------	----------	  ----------------------------------------------
-*/
-
-#ifndef __RTMP_MAC_H__
-#define __RTMP_MAC_H__
-
-
-
-// =================================================================================
-// TX / RX ring descriptor format
-// =================================================================================
-
-// the first 24-byte in TXD is called TXINFO and will be DMAed to MAC block through TXFIFO.
-// MAC block use this TXINFO to control the transmission behavior of this frame.
-#define FIFO_MGMT                 0
-#define FIFO_HCCA                 1
-#define FIFO_EDCA                 2
-
-
-//
-// TXD Wireless Information format for Tx ring and Mgmt Ring
-//
-//txop : for txop mode
-// 0:txop for the MPDU frame will be handles by ASIC by register
-// 1/2/3:the MPDU frame is send after PIFS/backoff/SIFS
-#ifdef RT_BIG_ENDIAN
-typedef	struct	PACKED _TXWI_STRUC {
-	// Word 0
-	UINT32		PHYMODE:2;
-	UINT32		TxBF:1;	// 3*3
-	UINT32		rsv2:1;
-//	UINT32		rsv2:2;
-	UINT32		Ifs:1;	//
-	UINT32		STBC:2;	//channel bandwidth 20MHz or 40 MHz
-	UINT32		ShortGI:1;
-	UINT32		BW:1;	//channel bandwidth 20MHz or 40 MHz
-	UINT32		MCS:7;
-
-	UINT32		rsv:6;
-	UINT32		txop:2;	//tx back off mode 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs only when previous frame exchange is successful.
-	UINT32		MpduDensity:3;
-	UINT32		AMPDU:1;
-
-	UINT32		TS:1;
-	UINT32		CFACK:1;
-	UINT32		MIMOps:1;	// the remote peer is in dynamic MIMO-PS mode
-	UINT32		FRAG:1;		// 1 to inform TKIP engine this is a fragment.
-	// Word 1
-	UINT32		PacketId:4;
-	UINT32		MPDUtotalByteCount:12;
-	UINT32		WirelessCliID:8;
-	UINT32		BAWinSize:6;
-	UINT32		NSEQ:1;
-	UINT32		ACK:1;
-	// Word 2
-	UINT32		IV;
-	// Word 3
-	UINT32		EIV;
-}	TXWI_STRUC, *PTXWI_STRUC;
-#else
-typedef	struct	PACKED _TXWI_STRUC {
-	// Word	0
-	// ex: 00 03 00 40 means txop = 3, PHYMODE = 1
-	UINT32		FRAG:1;		// 1 to inform TKIP engine this is a fragment.
-	UINT32		MIMOps:1;	// the remote peer is in dynamic MIMO-PS mode
-	UINT32		CFACK:1;
-	UINT32		TS:1;
-
-	UINT32		AMPDU:1;
-	UINT32		MpduDensity:3;
-	UINT32		txop:2;	//FOR "THIS" frame. 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs only when previous frame exchange is successful.
-	UINT32		rsv:6;
-
-	UINT32		MCS:7;
-	UINT32		BW:1;	//channel bandwidth 20MHz or 40 MHz
-	UINT32		ShortGI:1;
-	UINT32		STBC:2;	// 1: STBC support MCS =0-7,   2,3 : RESERVE
-	UINT32		Ifs:1;	//
-//	UINT32		rsv2:2;	//channel bandwidth 20MHz or 40 MHz
-	UINT32		rsv2:1;
-	UINT32		TxBF:1;	// 3*3
-	UINT32		PHYMODE:2;
-	// Word1
-	// ex:  1c ff 38 00 means ACK=0, BAWinSize=7, MPDUtotalByteCount = 0x38
-	UINT32		ACK:1;
-	UINT32		NSEQ:1;
-	UINT32		BAWinSize:6;
-	UINT32		WirelessCliID:8;
-	UINT32		MPDUtotalByteCount:12;
-	UINT32		PacketId:4;
-	//Word2
-	UINT32		IV;
-	//Word3
-	UINT32		EIV;
-}	TXWI_STRUC, *PTXWI_STRUC;
-#endif
-
-
-//
-// RXWI wireless information format, in PBF. invisible in driver.
-//
-#ifdef RT_BIG_ENDIAN
-typedef	struct	PACKED _RXWI_STRUC {
-	// Word 0
-	UINT32		TID:4;
-	UINT32		MPDUtotalByteCount:12;
-	UINT32		UDF:3;
-	UINT32		BSSID:3;
-	UINT32		KeyIndex:2;
-	UINT32		WirelessCliID:8;
-	// Word 1
-	UINT32		PHYMODE:2;              // 1: this RX frame is unicast to me
-	UINT32		rsv:3;
-	UINT32		STBC:2;
-	UINT32		ShortGI:1;
-	UINT32		BW:1;
-	UINT32		MCS:7;
-	UINT32		SEQUENCE:12;
-	UINT32		FRAG:4;
-	// Word 2
-	UINT32		rsv1:8;
-	UINT32		RSSI2:8;
-	UINT32		RSSI1:8;
-	UINT32		RSSI0:8;
-	// Word 3
-	/*UINT32		rsv2:16;*/
-	UINT32		rsv2:8;
-	UINT32		FOFFSET:8;	// RT35xx
-	UINT32		SNR1:8;
-	UINT32		SNR0:8;
-}	RXWI_STRUC, *PRXWI_STRUC;
-#else
-typedef	struct	PACKED _RXWI_STRUC {
-	// Word	0
-	UINT32		WirelessCliID:8;
-	UINT32		KeyIndex:2;
-	UINT32		BSSID:3;
-	UINT32		UDF:3;
-	UINT32		MPDUtotalByteCount:12;
-	UINT32		TID:4;
-	// Word	1
-	UINT32		FRAG:4;
-	UINT32		SEQUENCE:12;
-	UINT32		MCS:7;
-	UINT32		BW:1;
-	UINT32		ShortGI:1;
-	UINT32		STBC:2;
-	UINT32		rsv:3;
-	UINT32		PHYMODE:2;              // 1: this RX frame is unicast to me
-	//Word2
-	UINT32		RSSI0:8;
-	UINT32		RSSI1:8;
-	UINT32		RSSI2:8;
-	UINT32		rsv1:8;
-	//Word3
-	UINT32		SNR0:8;
-	UINT32		SNR1:8;
-	UINT32		FOFFSET:8;	// RT35xx
-	UINT32		rsv2:8;
-	/*UINT32		rsv2:16;*/
-}	RXWI_STRUC, *PRXWI_STRUC;
-#endif
-
-
-// =================================================================================
-// Register format
-// =================================================================================
-
-
-//
-// SCH/DMA registers - base address 0x0200
-//
-// INT_SOURCE_CSR: Interrupt source register. Write one to clear corresponding bit
-//
-#define DMA_CSR0		0x200
-#define INT_SOURCE_CSR		0x200
-#ifdef RT_BIG_ENDIAN
-typedef	union	_INT_SOURCE_CSR_STRUC	{
-	struct	{
-#ifdef TONE_RADAR_DETECT_SUPPORT
-		UINT32			:11;
-		UINT32			RadarINT:1;
-		UINT32		rsv:2;
-#else // original source code
-		UINT32		:14;
-#endif // TONE_RADAR_DETECT_SUPPORT //
-		UINT32		TxCoherent:1;
-		UINT32		RxCoherent:1;
-		UINT32		GPTimer:1;
-		UINT32		AutoWakeup:1;//bit14
-		UINT32		TXFifoStatusInt:1;//FIFO Statistics is full, sw should read 0x171c
-		UINT32		PreTBTT:1;
-		UINT32		TBTTInt:1;
-		UINT32		RxTxCoherent:1;
-		UINT32		MCUCommandINT:1;
-		UINT32		MgmtDmaDone:1;
-		UINT32		HccaDmaDone:1;
-		UINT32		Ac3DmaDone:1;
-		UINT32		Ac2DmaDone:1;
-		UINT32		Ac1DmaDone:1;
-		UINT32		Ac0DmaDone:1;
-		UINT32		RxDone:1;
-		UINT32		TxDelayINT:1;	//delayed interrupt, not interrupt until several int or time limit hit
-		UINT32		RxDelayINT:1; //dealyed interrupt
-	}	field;
-	UINT32			word;
-}	INT_SOURCE_CSR_STRUC, *PINT_SOURCE_CSR_STRUC;
-#else
-typedef	union	_INT_SOURCE_CSR_STRUC	{
-	struct	{
-		UINT32		RxDelayINT:1;
-		UINT32		TxDelayINT:1;
-		UINT32		RxDone:1;
-		UINT32		Ac0DmaDone:1;//4
-		UINT32		Ac1DmaDone:1;
-		UINT32		Ac2DmaDone:1;
-		UINT32		Ac3DmaDone:1;
-		UINT32		HccaDmaDone:1; // bit7
-		UINT32		MgmtDmaDone:1;
-		UINT32		MCUCommandINT:1;//bit 9
-		UINT32		RxTxCoherent:1;
-		UINT32		TBTTInt:1;
-		UINT32		PreTBTT:1;
-		UINT32		TXFifoStatusInt:1;//FIFO Statistics is full, sw should read 0x171c
-		UINT32		AutoWakeup:1;//bit14
-		UINT32		GPTimer:1;
-		UINT32		RxCoherent:1;//bit16
-		UINT32		TxCoherent:1;
-#ifdef TONE_RADAR_DETECT_SUPPORT
-		UINT32		rsv:2;
-		UINT32			RadarINT:1;
-		UINT32			:11;
-#else
-		UINT32		:14;
-#endif // TONE_RADAR_DETECT_SUPPORT //
-	}	field;
-	UINT32			word;
-} INT_SOURCE_CSR_STRUC, *PINT_SOURCE_CSR_STRUC;
-#endif
-
-//
-// INT_MASK_CSR:   Interrupt MASK register.   1: the interrupt is mask OFF
-//
-#define INT_MASK_CSR        0x204
-#ifdef RT_BIG_ENDIAN
-typedef	union	_INT_MASK_CSR_STRUC	{
-	struct	{
-		UINT32		TxCoherent:1;
-		UINT32		RxCoherent:1;
-#ifdef TONE_RADAR_DETECT_SUPPORT
-		UINT32			:9;
-		UINT32			RadarINT:1;
-		UINT32		rsv:10;
-#else
-		UINT32		:20;
-#endif // TONE_RADAR_DETECT_SUPPORT //
-		UINT32		MCUCommandINT:1;
-		UINT32		MgmtDmaDone:1;
-		UINT32		HccaDmaDone:1;
-		UINT32		Ac3DmaDone:1;
-		UINT32		Ac2DmaDone:1;
-		UINT32		Ac1DmaDone:1;
-		UINT32		Ac0DmaDone:1;
-		UINT32		RxDone:1;
-		UINT32		TxDelay:1;
-		UINT32		RXDelay_INT_MSK:1;
-	}	field;
-	UINT32			word;
-}INT_MASK_CSR_STRUC, *PINT_MASK_CSR_STRUC;
-#else
-typedef	union	_INT_MASK_CSR_STRUC	{
-	struct	{
-		UINT32		RXDelay_INT_MSK:1;
-		UINT32		TxDelay:1;
-		UINT32		RxDone:1;
-		UINT32		Ac0DmaDone:1;
-		UINT32		Ac1DmaDone:1;
-		UINT32		Ac2DmaDone:1;
-		UINT32		Ac3DmaDone:1;
-		UINT32		HccaDmaDone:1;
-		UINT32		MgmtDmaDone:1;
-		UINT32		MCUCommandINT:1;
-#ifdef TONE_RADAR_DETECT_SUPPORT
-		UINT32		rsv:10;
-		UINT32			RadarINT:1;
-		UINT32			:9;
-#else
-		UINT32		:20;
-#endif // TONE_RADAR_DETECT_SUPPORT //
-		UINT32		RxCoherent:1;
-		UINT32		TxCoherent:1;
-	}	field;
-	UINT32			word;
-} INT_MASK_CSR_STRUC, *PINT_MASK_CSR_STRUC;
-#endif
-
-#define WPDMA_GLO_CFG	0x208
-#ifdef RT_BIG_ENDIAN
-typedef	union	_WPDMA_GLO_CFG_STRUC	{
-	struct	{
-		UINT32		HDR_SEG_LEN:16;
-		UINT32		RXHdrScater:8;
-		UINT32		BigEndian:1;
-		UINT32		EnTXWriteBackDDONE:1;
-		UINT32		WPDMABurstSIZE:2;
-		UINT32		RxDMABusy:1;
-		UINT32		EnableRxDMA:1;
-		UINT32		TxDMABusy:1;
-		UINT32		EnableTxDMA:1;
-	}	field;
-	UINT32			word;
-}WPDMA_GLO_CFG_STRUC, *PWPDMA_GLO_CFG_STRUC;
-#else
-typedef	union	_WPDMA_GLO_CFG_STRUC	{
-	struct	{
-		UINT32		EnableTxDMA:1;
-		UINT32		TxDMABusy:1;
-		UINT32		EnableRxDMA:1;
-		UINT32		RxDMABusy:1;
-		UINT32		WPDMABurstSIZE:2;
-		UINT32		EnTXWriteBackDDONE:1;
-		UINT32		BigEndian:1;
-		UINT32		RXHdrScater:8;
-		UINT32		HDR_SEG_LEN:16;
-	}	field;
-	UINT32			word;
-} WPDMA_GLO_CFG_STRUC, *PWPDMA_GLO_CFG_STRUC;
-#endif
-
-#define WPDMA_RST_IDX	0x20c
-#ifdef RT_BIG_ENDIAN
-typedef	union	_WPDMA_RST_IDX_STRUC	{
-	struct	{
-		UINT32		:15;
-		UINT32		RST_DRX_IDX0:1;
-		UINT32		rsv:10;
-		UINT32		RST_DTX_IDX5:1;
-		UINT32		RST_DTX_IDX4:1;
-		UINT32		RST_DTX_IDX3:1;
-		UINT32		RST_DTX_IDX2:1;
-		UINT32		RST_DTX_IDX1:1;
-		UINT32		RST_DTX_IDX0:1;
-	}	field;
-	UINT32			word;
-}WPDMA_RST_IDX_STRUC, *PWPDMA_RST_IDX_STRUC;
-#else
-typedef	union	_WPDMA_RST_IDX_STRUC	{
-	struct	{
-		UINT32		RST_DTX_IDX0:1;
-		UINT32		RST_DTX_IDX1:1;
-		UINT32		RST_DTX_IDX2:1;
-		UINT32		RST_DTX_IDX3:1;
-		UINT32		RST_DTX_IDX4:1;
-		UINT32		RST_DTX_IDX5:1;
-		UINT32		rsv:10;
-		UINT32		RST_DRX_IDX0:1;
-		UINT32		:15;
-	}	field;
-	UINT32			word;
-} WPDMA_RST_IDX_STRUC, *PWPDMA_RST_IDX_STRUC;
-#endif
-#define DELAY_INT_CFG  0x0210
-#ifdef RT_BIG_ENDIAN
-typedef	union	_DELAY_INT_CFG_STRUC	{
-	struct	{
-		UINT32		TXDLY_INT_EN:1;
-		UINT32		TXMAX_PINT:7;
-		UINT32		TXMAX_PTIME:8;
-		UINT32		RXDLY_INT_EN:1;
-		UINT32		RXMAX_PINT:7;
-		UINT32		RXMAX_PTIME:8;
-	}	field;
-	UINT32			word;
-}DELAY_INT_CFG_STRUC, *PDELAY_INT_CFG_STRUC;
-#else
-typedef	union	_DELAY_INT_CFG_STRUC	{
-	struct	{
-		UINT32		RXMAX_PTIME:8;
-		UINT32		RXMAX_PINT:7;
-		UINT32		RXDLY_INT_EN:1;
-		UINT32		TXMAX_PTIME:8;
-		UINT32		TXMAX_PINT:7;
-		UINT32		TXDLY_INT_EN:1;
-	}	field;
-	UINT32			word;
-} DELAY_INT_CFG_STRUC, *PDELAY_INT_CFG_STRUC;
-#endif
-#define WMM_AIFSN_CFG   0x0214
-#ifdef RT_BIG_ENDIAN
-typedef	union	_AIFSN_CSR_STRUC	{
-	struct	{
-	    UINT32   Rsv:16;
-	    UINT32   Aifsn3:4;       // for AC_VO
-	    UINT32   Aifsn2:4;       // for AC_VI
-	    UINT32   Aifsn1:4;       // for AC_BK
-	    UINT32   Aifsn0:4;       // for AC_BE
-	}	field;
-	UINT32			word;
-}	AIFSN_CSR_STRUC, *PAIFSN_CSR_STRUC;
-#else
-typedef	union	_AIFSN_CSR_STRUC	{
-	struct	{
-	    UINT32   Aifsn0:4;       // for AC_BE
-	    UINT32   Aifsn1:4;       // for AC_BK
-	    UINT32   Aifsn2:4;       // for AC_VI
-	    UINT32   Aifsn3:4;       // for AC_VO
-	    UINT32   Rsv:16;
-	}	field;
-	UINT32			word;
-}	AIFSN_CSR_STRUC, *PAIFSN_CSR_STRUC;
-#endif
-//
-// CWMIN_CSR: CWmin for each EDCA AC
-//
-#define WMM_CWMIN_CFG   0x0218
-#ifdef RT_BIG_ENDIAN
-typedef	union	_CWMIN_CSR_STRUC	{
-	struct	{
-	    UINT32   Rsv:16;
-	    UINT32   Cwmin3:4;       // for AC_VO
-	    UINT32   Cwmin2:4;       // for AC_VI
-	    UINT32   Cwmin1:4;       // for AC_BK
-	    UINT32   Cwmin0:4;       // for AC_BE
-	}	field;
-	UINT32			word;
-}	CWMIN_CSR_STRUC, *PCWMIN_CSR_STRUC;
-#else
-typedef	union	_CWMIN_CSR_STRUC	{
-	struct	{
-	    UINT32   Cwmin0:4;       // for AC_BE
-	    UINT32   Cwmin1:4;       // for AC_BK
-	    UINT32   Cwmin2:4;       // for AC_VI
-	    UINT32   Cwmin3:4;       // for AC_VO
-	    UINT32   Rsv:16;
-	}	field;
-	UINT32			word;
-}	CWMIN_CSR_STRUC, *PCWMIN_CSR_STRUC;
-#endif
-
-//
-// CWMAX_CSR: CWmin for each EDCA AC
-//
-#define WMM_CWMAX_CFG   0x021c
-#ifdef RT_BIG_ENDIAN
-typedef	union	_CWMAX_CSR_STRUC	{
-	struct	{
-	    UINT32   Rsv:16;
-	    UINT32   Cwmax3:4;       // for AC_VO
-	    UINT32   Cwmax2:4;       // for AC_VI
-	    UINT32   Cwmax1:4;       // for AC_BK
-	    UINT32   Cwmax0:4;       // for AC_BE
-	}	field;
-	UINT32			word;
-}	CWMAX_CSR_STRUC, *PCWMAX_CSR_STRUC;
-#else
-typedef	union	_CWMAX_CSR_STRUC	{
-	struct	{
-	    UINT32   Cwmax0:4;       // for AC_BE
-	    UINT32   Cwmax1:4;       // for AC_BK
-	    UINT32   Cwmax2:4;       // for AC_VI
-	    UINT32   Cwmax3:4;       // for AC_VO
-	    UINT32   Rsv:16;
-	}	field;
-	UINT32			word;
-}	CWMAX_CSR_STRUC, *PCWMAX_CSR_STRUC;
-#endif
-
-
-//
-// AC_TXOP_CSR0: AC_BK/AC_BE TXOP register
-//
-#define WMM_TXOP0_CFG    0x0220
-#ifdef RT_BIG_ENDIAN
-typedef	union	_AC_TXOP_CSR0_STRUC	{
-	struct	{
-	    USHORT  Ac1Txop;        // for AC_BE, in unit of 32us
-	    USHORT  Ac0Txop;        // for AC_BK, in unit of 32us
-	}	field;
-	UINT32			word;
-}	AC_TXOP_CSR0_STRUC, *PAC_TXOP_CSR0_STRUC;
-#else
-typedef	union	_AC_TXOP_CSR0_STRUC	{
-	struct	{
-	    USHORT  Ac0Txop;        // for AC_BK, in unit of 32us
-	    USHORT  Ac1Txop;        // for AC_BE, in unit of 32us
-	}	field;
-	UINT32			word;
-}	AC_TXOP_CSR0_STRUC, *PAC_TXOP_CSR0_STRUC;
-#endif
-
-//
-// AC_TXOP_CSR1: AC_VO/AC_VI TXOP register
-//
-#define WMM_TXOP1_CFG    0x0224
-#ifdef RT_BIG_ENDIAN
-typedef	union	_AC_TXOP_CSR1_STRUC	{
-	struct	{
-	    USHORT  Ac3Txop;        // for AC_VO, in unit of 32us
-	    USHORT  Ac2Txop;        // for AC_VI, in unit of 32us
-	}	field;
-	UINT32			word;
-}	AC_TXOP_CSR1_STRUC, *PAC_TXOP_CSR1_STRUC;
-#else
-typedef	union	_AC_TXOP_CSR1_STRUC	{
-	struct	{
-	    USHORT  Ac2Txop;        // for AC_VI, in unit of 32us
-	    USHORT  Ac3Txop;        // for AC_VO, in unit of 32us
-	}	field;
-	UINT32			word;
-}	AC_TXOP_CSR1_STRUC, *PAC_TXOP_CSR1_STRUC;
-#endif
-
-
-#define RINGREG_DIFF			0x10
-#define GPIO_CTRL_CFG    0x0228	//MAC_CSR13
-#define MCU_CMD_CFG    0x022c
-#define TX_BASE_PTR0     0x0230	//AC_BK base address
-#define TX_MAX_CNT0      0x0234
-#define TX_CTX_IDX0       0x0238
-#define TX_DTX_IDX0      0x023c
-#define TX_BASE_PTR1     0x0240		//AC_BE base address
-#define TX_MAX_CNT1      0x0244
-#define TX_CTX_IDX1       0x0248
-#define TX_DTX_IDX1      0x024c
-#define TX_BASE_PTR2     0x0250		//AC_VI base address
-#define TX_MAX_CNT2      0x0254
-#define TX_CTX_IDX2       0x0258
-#define TX_DTX_IDX2      0x025c
-#define TX_BASE_PTR3     0x0260		//AC_VO base address
-#define TX_MAX_CNT3      0x0264
-#define TX_CTX_IDX3       0x0268
-#define TX_DTX_IDX3      0x026c
-#define TX_BASE_PTR4     0x0270		//HCCA base address
-#define TX_MAX_CNT4      0x0274
-#define TX_CTX_IDX4       0x0278
-#define TX_DTX_IDX4      0x027c
-#define TX_BASE_PTR5     0x0280		//MGMT base address
-#define  TX_MAX_CNT5     0x0284
-#define TX_CTX_IDX5       0x0288
-#define TX_DTX_IDX5      0x028c
-#define TX_MGMTMAX_CNT      TX_MAX_CNT5
-#define TX_MGMTCTX_IDX       TX_CTX_IDX5
-#define TX_MGMTDTX_IDX      TX_DTX_IDX5
-#define RX_BASE_PTR     0x0290	//RX base address
-#define RX_MAX_CNT      0x0294
-#define RX_CRX_IDX       0x0298
-#define RX_DRX_IDX      0x029c
-
-
-#define USB_DMA_CFG      0x02a0
-#ifdef RT_BIG_ENDIAN
-typedef	union	_USB_DMA_CFG_STRUC	{
-	struct	{
-	    UINT32  TxBusy:1;		//USB DMA TX FSM busy . debug only
-	    UINT32  RxBusy:1;        //USB DMA RX FSM busy . debug only
-	    UINT32  EpoutValid:6;        //OUT endpoint data valid. debug only
-	    UINT32  TxBulkEn:1;        //Enable USB DMA Tx
-	    UINT32  RxBulkEn:1;        //Enable USB DMA Rx
-	    UINT32  RxBulkAggEn:1;        //Enable Rx Bulk Aggregation
-	    UINT32  TxopHalt:1;        //Halt TXOP count down when TX buffer is full.
-	    UINT32  TxClear:1;        //Clear USB DMA TX path
-	    UINT32  rsv:2;
-	    UINT32  phyclear:1;			//phy watch dog enable. write 1
-	    UINT32  RxBulkAggLmt:8;        //Rx Bulk Aggregation Limit  in unit of 1024 bytes
-	    UINT32  RxBulkAggTOut:8;        //Rx Bulk Aggregation TimeOut  in unit of 33ns
-	}	field;
-	UINT32			word;
-}	USB_DMA_CFG_STRUC, *PUSB_DMA_CFG_STRUC;
-#else
-typedef	union	_USB_DMA_CFG_STRUC	{
-	struct	{
-	    UINT32  RxBulkAggTOut:8;        //Rx Bulk Aggregation TimeOut  in unit of 33ns
-	    UINT32  RxBulkAggLmt:8;        //Rx Bulk Aggregation Limit  in unit of 256 bytes
-	    UINT32  phyclear:1;			//phy watch dog enable. write 1
-	    UINT32  rsv:2;
-	    UINT32  TxClear:1;        //Clear USB DMA TX path
-	    UINT32  TxopHalt:1;        //Halt TXOP count down when TX buffer is full.
-	    UINT32  RxBulkAggEn:1;        //Enable Rx Bulk Aggregation
-	    UINT32  RxBulkEn:1;        //Enable USB DMA Rx
-	    UINT32  TxBulkEn:1;        //Enable USB DMA Tx
-	    UINT32  EpoutValid:6;        //OUT endpoint data valid
-	    UINT32  RxBusy:1;        //USB DMA RX FSM busy
-	    UINT32  TxBusy:1;		//USB DMA TX FSM busy
-	}	field;
-	UINT32			word;
-}	USB_DMA_CFG_STRUC, *PUSB_DMA_CFG_STRUC;
-#endif
-
-
-//
-//  3  PBF  registers
-//
-//
-// Most are for debug. Driver doesn't touch PBF register.
-#define PBF_SYS_CTRL	 0x0400
-#define PBF_CFG                 0x0408
-#define PBF_MAX_PCNT	 0x040C
-#define PBF_CTRL		0x0410
-#define PBF_INT_STA	 0x0414
-#define PBF_INT_ENA	 0x0418
-#define TXRXQ_PCNT	 0x0438
-#define PBF_DBG			 0x043c
-#define PBF_CAP_CTRL     0x0440
-
-#ifdef RT30xx
-#ifdef RTMP_EFUSE_SUPPORT
-// eFuse registers
-#define EFUSE_CTRL				0x0580
-#define EFUSE_DATA0				0x0590
-#define EFUSE_DATA1				0x0594
-#define EFUSE_DATA2				0x0598
-#define EFUSE_DATA3				0x059c
-#endif // RTMP_EFUSE_SUPPORT //
-#endif // RT30xx //
-
-#define OSC_CTRL		0x5a4
-#define PCIE_PHY_TX_ATTENUATION_CTRL	0x05C8
-#define LDO_CFG0				0x05d4
-#define GPIO_SWITCH				0x05dc
-
-
-//
-//  4  MAC  registers
-//
-//
-//  4.1 MAC SYSTEM  configuration registers (offset:0x1000)
-//
-#define MAC_CSR0            0x1000
-#ifdef RT_BIG_ENDIAN
-typedef	union	_ASIC_VER_ID_STRUC	{
-	struct	{
-	    USHORT  ASICVer;        // version : 2860
-	    USHORT  ASICRev;        // reversion  : 0
-	}	field;
-	UINT32			word;
-}	ASIC_VER_ID_STRUC, *PASIC_VER_ID_STRUC;
-#else
-typedef	union	_ASIC_VER_ID_STRUC	{
-	struct	{
-	    USHORT  ASICRev;        // reversion  : 0
-	    USHORT  ASICVer;        // version : 2860
-	}	field;
-	UINT32			word;
-}	ASIC_VER_ID_STRUC, *PASIC_VER_ID_STRUC;
-#endif
-#define MAC_SYS_CTRL            0x1004		//MAC_CSR1
-#define MAC_ADDR_DW0				0x1008		// MAC ADDR DW0
-#define MAC_ADDR_DW1			 0x100c		// MAC ADDR DW1
-//
-// MAC_CSR2: STA MAC register 0
-//
-#ifdef RT_BIG_ENDIAN
-typedef	union	_MAC_DW0_STRUC	{
-	struct	{
-		UCHAR		Byte3;		// MAC address byte 3
-		UCHAR		Byte2;		// MAC address byte 2
-		UCHAR		Byte1;		// MAC address byte 1
-		UCHAR		Byte0;		// MAC address byte 0
-	}	field;
-	UINT32			word;
-}	MAC_DW0_STRUC, *PMAC_DW0_STRUC;
-#else
-typedef	union	_MAC_DW0_STRUC	{
-	struct	{
-		UCHAR		Byte0;		// MAC address byte 0
-		UCHAR		Byte1;		// MAC address byte 1
-		UCHAR		Byte2;		// MAC address byte 2
-		UCHAR		Byte3;		// MAC address byte 3
-	}	field;
-	UINT32			word;
-}	MAC_DW0_STRUC, *PMAC_DW0_STRUC;
-#endif
-
-//
-// MAC_CSR3: STA MAC register 1
-//
-#ifdef RT_BIG_ENDIAN
-typedef	union	_MAC_DW1_STRUC	{
-	struct	{
-		UCHAR		Rsvd1;
-		UCHAR		U2MeMask;
-		UCHAR		Byte5;		// MAC address byte 5
-		UCHAR		Byte4;		// MAC address byte 4
-	}	field;
-	UINT32			word;
-}	MAC_DW1_STRUC, *PMAC_DW1_STRUC;
-#else
-typedef	union	_MAC_DW1_STRUC	{
-	struct	{
-		UCHAR		Byte4;		// MAC address byte 4
-		UCHAR		Byte5;		// MAC address byte 5
-		UCHAR		U2MeMask;
-		UCHAR		Rsvd1;
-	}	field;
-	UINT32			word;
-}	MAC_DW1_STRUC, *PMAC_DW1_STRUC;
-#endif
-
-#define MAC_BSSID_DW0				0x1010		// MAC BSSID DW0
-#define MAC_BSSID_DW1				0x1014		// MAC BSSID DW1
-
-//
-// MAC_CSR5: BSSID register 1
-//
-#ifdef RT_BIG_ENDIAN
-typedef	union	_MAC_CSR5_STRUC	{
-	struct	{
-		USHORT		Rsvd:11;
-		USHORT		MBssBcnNum:3;
-		USHORT		BssIdMode:2; // 0: one BSSID, 10: 4 BSSID,  01: 2 BSSID , 11: 8BSSID
-		UCHAR		Byte5;		 // BSSID byte 5
-		UCHAR		Byte4;		 // BSSID byte 4
-	}	field;
-	UINT32			word;
-}	MAC_CSR5_STRUC, *PMAC_CSR5_STRUC;
-#else
-typedef	union	_MAC_CSR5_STRUC	{
-	struct	{
-		UCHAR		Byte4;		 // BSSID byte 4
-		UCHAR		Byte5;		 // BSSID byte 5
-		USHORT		BssIdMask:2; // 0: one BSSID, 10: 4 BSSID,  01: 2 BSSID , 11: 8BSSID
-		USHORT		MBssBcnNum:3;
-		USHORT		Rsvd:11;
-	}	field;
-	UINT32			word;
-}	MAC_CSR5_STRUC, *PMAC_CSR5_STRUC;
-#endif
-
-#define MAX_LEN_CFG              0x1018		// rt2860b max 16k bytes. bit12:13 Maximum PSDU length (power factor) 0:2^13, 1:2^14, 2:2^15, 3:2^16
-#define BBP_CSR_CFG			0x101c		//
-//
-// BBP_CSR_CFG: BBP serial control register
-//
-#ifdef RT_BIG_ENDIAN
-typedef	union	_BBP_CSR_CFG_STRUC	{
-	struct	{
-		UINT32		:12;
-		UINT32		BBP_RW_MODE:1;		// 0: use serial mode  1:parallel
-		UINT32		BBP_PAR_DUR:1;		    // 0: 4 MAC clock cycles  1: 8 MAC clock cycles
-		UINT32		Busy:1;				// 1: ASIC is busy execute BBP programming.
-		UINT32		fRead:1;		    // 0: Write	BBP, 1:	Read BBP
-		UINT32		RegNum:8;			// Selected	BBP	register
-		UINT32		Value:8;			// Register	value to program into BBP
-	}	field;
-	UINT32			word;
-}	BBP_CSR_CFG_STRUC, *PBBP_CSR_CFG_STRUC;
-#else
-typedef	union	_BBP_CSR_CFG_STRUC	{
-	struct	{
-		UINT32		Value:8;			// Register	value to program into BBP
-		UINT32		RegNum:8;			// Selected	BBP	register
-		UINT32		fRead:1;		    // 0: Write	BBP, 1:	Read BBP
-		UINT32		Busy:1;				// 1: ASIC is busy execute BBP programming.
-		UINT32		BBP_PAR_DUR:1;		     // 0: 4 MAC clock cycles  1: 8 MAC clock cycles
-		UINT32		BBP_RW_MODE:1;		// 0: use serial mode  1:parallel
-		UINT32		:12;
-	}	field;
-	UINT32			word;
-}	BBP_CSR_CFG_STRUC, *PBBP_CSR_CFG_STRUC;
-#endif
-#define RF_CSR_CFG0			0x1020
-//
-// RF_CSR_CFG: RF control register
-//
-#ifdef RT_BIG_ENDIAN
-typedef	union	_RF_CSR_CFG0_STRUC	{
-	struct	{
-		UINT32		Busy:1;		    // 0: idle 1: 8busy
-		UINT32		Sel:1;				// 0:RF_LE0 activate  1:RF_LE1 activate
-		UINT32		StandbyMode:1;		    // 0: high when stand by 1:	low when standby
-		UINT32		bitwidth:5;			// Selected	BBP	register
-		UINT32		RegIdAndContent:24;			// Register	value to program into BBP
-	}	field;
-	UINT32			word;
-}	RF_CSR_CFG0_STRUC, *PRF_CSR_CFG0_STRUC;
-#else
-typedef	union	_RF_CSR_CFG0_STRUC	{
-	struct	{
-		UINT32		RegIdAndContent:24;			// Register	value to program into BBP
-		UINT32		bitwidth:5;			// Selected	BBP	register
-		UINT32		StandbyMode:1;		    // 0: high when stand by 1:	low when standby
-		UINT32		Sel:1;				// 0:RF_LE0 activate  1:RF_LE1 activate
-		UINT32		Busy:1;		    // 0: idle 1: 8busy
-	}	field;
-	UINT32			word;
-}	RF_CSR_CFG0_STRUC, *PRF_CSR_CFG0_STRUC;
-#endif
-#define RF_CSR_CFG1			0x1024
-#ifdef RT_BIG_ENDIAN
-typedef	union	_RF_CSR_CFG1_STRUC	{
-	struct	{
-		UINT32		rsv:7;		    // 0: idle 1: 8busy
-		UINT32		RFGap:5;			// Gap between BB_CONTROL_RF and RF_LE. 0: 3 system clock cycle (37.5usec) 1: 5 system clock cycle (62.5usec)
-		UINT32		RegIdAndContent:24;			// Register	value to program into BBP
-	}	field;
-	UINT32			word;
-}	RF_CSR_CFG1_STRUC, *PRF_CSR_CFG1_STRUC;
-#else
-typedef	union	_RF_CSR_CFG1_STRUC	{
-	struct	{
-		UINT32		RegIdAndContent:24;			// Register	value to program into BBP
-		UINT32		RFGap:5;			// Gap between BB_CONTROL_RF and RF_LE. 0: 3 system clock cycle (37.5usec) 1: 5 system clock cycle (62.5usec)
-		UINT32		rsv:7;		    // 0: idle 1: 8busy
-	}	field;
-	UINT32			word;
-}	RF_CSR_CFG1_STRUC, *PRF_CSR_CFG1_STRUC;
-#endif
-#define RF_CSR_CFG2			0x1028		//
-#ifdef RT_BIG_ENDIAN
-typedef	union	_RF_CSR_CFG2_STRUC	{
-	struct	{
-		UINT32		rsv:8;		    // 0: idle 1: 8busy
-		UINT32		RegIdAndContent:24;			// Register	value to program into BBP
-	}	field;
-	UINT32			word;
-}	RF_CSR_CFG2_STRUC, *PRF_CSR_CFG2_STRUC;
-#else
-typedef	union	_RF_CSR_CFG2_STRUC	{
-	struct	{
-		UINT32		RegIdAndContent:24;			// Register	value to program into BBP
-		UINT32		rsv:8;		    // 0: idle 1: 8busy
-	}	field;
-	UINT32			word;
-}	RF_CSR_CFG2_STRUC, *PRF_CSR_CFG2_STRUC;
-#endif
-#define LED_CFG				0x102c		//  MAC_CSR14
-#ifdef RT_BIG_ENDIAN
-typedef	union	_LED_CFG_STRUC	{
-	struct	{
-		UINT32		:1;
-		UINT32		LedPolar:1;			// Led Polarity.  0: active low1: active high
-		UINT32		YLedMode:2;			// yellow Led Mode
-		UINT32		GLedMode:2;			// green Led Mode
-		UINT32		RLedMode:2;			// red Led Mode    0: off1: blinking upon TX2: periodic slow blinking3: always on
-		UINT32		rsv:2;
-		UINT32		SlowBlinkPeriod:6;			// slow blinking period. unit:1ms
-		UINT32		OffPeriod:8;			// blinking off period unit 1ms
-		UINT32		OnPeriod:8;			// blinking on period unit 1ms
-	}	field;
-	UINT32			word;
-}	LED_CFG_STRUC, *PLED_CFG_STRUC;
-#else
-typedef	union	_LED_CFG_STRUC	{
-	struct	{
-		UINT32		OnPeriod:8;			// blinking on period unit 1ms
-		UINT32		OffPeriod:8;			// blinking off period unit 1ms
-		UINT32		SlowBlinkPeriod:6;			// slow blinking period. unit:1ms
-		UINT32		rsv:2;
-		UINT32		RLedMode:2;			// red Led Mode    0: off1: blinking upon TX2: periodic slow blinking3: always on
-		UINT32		GLedMode:2;			// green Led Mode
-		UINT32		YLedMode:2;			// yellow Led Mode
-		UINT32		LedPolar:1;			// Led Polarity.  0: active low1: active high
-		UINT32		:1;
-	}	field;
-	UINT32			word;
-}	LED_CFG_STRUC, *PLED_CFG_STRUC;
-#endif
-//
-//  4.2 MAC TIMING  configuration registers (offset:0x1100)
-//
-#define XIFS_TIME_CFG             0x1100		 // MAC_CSR8  MAC_CSR9
-#ifdef RT_BIG_ENDIAN
-typedef	union	_IFS_SLOT_CFG_STRUC	{
-	struct	{
-	    UINT32  rsv:2;
-	    UINT32  BBRxendEnable:1;        //  reference RXEND signal to begin XIFS defer
-	    UINT32  EIFS:9;        //  unit 1us
-	    UINT32  OfdmXifsTime:4;        //OFDM SIFS. unit 1us. Applied after OFDM RX when MAC doesn't reference BBP signal BBRXEND
-	    UINT32  OfdmSifsTime:8;        //  unit 1us. Applied after OFDM RX/TX
-	    UINT32  CckmSifsTime:8;        //  unit 1us. Applied after CCK RX/TX
-	}	field;
-	UINT32			word;
-}	IFS_SLOT_CFG_STRUC, *PIFS_SLOT_CFG_STRUC;
-#else
-typedef	union	_IFS_SLOT_CFG_STRUC	{
-	struct	{
-	    UINT32  CckmSifsTime:8;        //  unit 1us. Applied after CCK RX/TX
-	    UINT32  OfdmSifsTime:8;        //  unit 1us. Applied after OFDM RX/TX
-	    UINT32  OfdmXifsTime:4;        //OFDM SIFS. unit 1us. Applied after OFDM RX when MAC doesn't reference BBP signal BBRXEND
-	    UINT32  EIFS:9;        //  unit 1us
-	    UINT32  BBRxendEnable:1;        //  reference RXEND signal to begin XIFS defer
-	    UINT32  rsv:2;
-	}	field;
-	UINT32			word;
-}	IFS_SLOT_CFG_STRUC, *PIFS_SLOT_CFG_STRUC;
-#endif
-
-#define BKOFF_SLOT_CFG             0x1104		 //  mac_csr9 last 8 bits
-#define NAV_TIME_CFG             0x1108		 // NAV  (MAC_CSR15)
-#define CH_TIME_CFG             0x110C			// Count as channel busy
-#define PBF_LIFE_TIMER             0x1110		 //TX/RX MPDU timestamp timer (free run)Unit: 1us
-#define BCN_TIME_CFG             0x1114		 // TXRX_CSR9
-
-#define BCN_OFFSET0				0x042C
-#define BCN_OFFSET1				0x0430
-
-//
-// BCN_TIME_CFG : Synchronization control register
-//
-#ifdef RT_BIG_ENDIAN
-typedef	union	_BCN_TIME_CFG_STRUC	{
-	struct	{
-		UINT32		TxTimestampCompensate:8;
-        UINT32       :3;
-		UINT32		bBeaconGen:1;		// Enable beacon generator
-        UINT32       bTBTTEnable:1;
-		UINT32		TsfSyncMode:2;		// Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode
-		UINT32		bTsfTicking:1;		// Enable TSF auto counting
-		UINT32       BeaconInterval:16;  // in unit of 1/16 TU
-	}	field;
-	UINT32			word;
-}	BCN_TIME_CFG_STRUC, *PBCN_TIME_CFG_STRUC;
-#else
-typedef	union	_BCN_TIME_CFG_STRUC	{
-	struct	{
-		UINT32       BeaconInterval:16;  // in unit of 1/16 TU
-		UINT32		bTsfTicking:1;		// Enable TSF auto counting
-		UINT32		TsfSyncMode:2;		// Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode
-        UINT32       bTBTTEnable:1;
-		UINT32		bBeaconGen:1;		// Enable beacon generator
-        UINT32       :3;
-		UINT32		TxTimestampCompensate:8;
-	}	field;
-	UINT32			word;
-}	BCN_TIME_CFG_STRUC, *PBCN_TIME_CFG_STRUC;
-#endif
-#define TBTT_SYNC_CFG            0x1118			// txrx_csr10
-#define TSF_TIMER_DW0             0x111C		// Local TSF timer lsb 32 bits. Read-only
-#define TSF_TIMER_DW1             0x1120		// msb 32 bits. Read-only.
-#define TBTT_TIMER		0x1124			// TImer remains till next TBTT. Read-only.  TXRX_CSR14
-#define INT_TIMER_CFG			0x1128			//
-#define INT_TIMER_EN			0x112c			//  GP-timer and pre-tbtt Int enable
-#define CH_IDLE_STA			0x1130			//  channel idle time
-#define CH_BUSY_STA			0x1134			//  channle busy time
-//
-//  4.2 MAC POWER  configuration registers (offset:0x1200)
-//
-#define MAC_STATUS_CFG             0x1200		 // old MAC_CSR12
-#define PWR_PIN_CFG             0x1204		 // old MAC_CSR12
-#define AUTO_WAKEUP_CFG             0x1208		 // old MAC_CSR10
-//
-// AUTO_WAKEUP_CFG: Manual power control / status register
-//
-#ifdef RT_BIG_ENDIAN
-typedef	union	_AUTO_WAKEUP_STRUC	{
-	struct	{
-		UINT32		:16;
-		UINT32		EnableAutoWakeup:1;	// 0:sleep, 1:awake
-		UINT32       NumofSleepingTbtt:7;          // ForceWake has high privilege than PutToSleep when both set
-		UINT32       AutoLeadTime:8;
-	}	field;
-	UINT32			word;
-}	AUTO_WAKEUP_STRUC, *PAUTO_WAKEUP_STRUC;
-#else
-typedef	union	_AUTO_WAKEUP_STRUC	{
-	struct	{
-		UINT32       AutoLeadTime:8;
-		UINT32       NumofSleepingTbtt:7;          // ForceWake has high privilege than PutToSleep when both set
-		UINT32		EnableAutoWakeup:1;	// 0:sleep, 1:awake
-		UINT32		:16;
-	}	field;
-	UINT32			word;
-}	AUTO_WAKEUP_STRUC, *PAUTO_WAKEUP_STRUC;
-#endif
-//
-//  4.3 MAC TX  configuration registers (offset:0x1300)
-//
-
-#define EDCA_AC0_CFG	0x1300		//AC_TXOP_CSR0 0x3474
-#define EDCA_AC1_CFG	0x1304
-#define EDCA_AC2_CFG	0x1308
-#define EDCA_AC3_CFG	0x130c
-#ifdef RT_BIG_ENDIAN
-typedef	union	_EDCA_AC_CFG_STRUC	{
-	struct	{
-	    UINT32  :12;        //
-	    UINT32  Cwmax:4;        //unit power of 2
-	    UINT32  Cwmin:4;        //
-	    UINT32  Aifsn:4;        // # of slot time
-	    UINT32  AcTxop:8;        //  in unit of 32us
-	}	field;
-	UINT32			word;
-}	EDCA_AC_CFG_STRUC, *PEDCA_AC_CFG_STRUC;
-#else
-typedef	union	_EDCA_AC_CFG_STRUC	{
-	struct	{
-	    UINT32  AcTxop:8;        //  in unit of 32us
-	    UINT32  Aifsn:4;        // # of slot time
-	    UINT32  Cwmin:4;        //
-	    UINT32  Cwmax:4;        //unit power of 2
-	    UINT32  :12;       //
-	}	field;
-	UINT32			word;
-}	EDCA_AC_CFG_STRUC, *PEDCA_AC_CFG_STRUC;
-#endif
-
-#define EDCA_TID_AC_MAP	0x1310
-#define TX_PWR_CFG_0	0x1314
-#define TX_PWR_CFG_1	0x1318
-#define TX_PWR_CFG_2	0x131C
-#define TX_PWR_CFG_3	0x1320
-#define TX_PWR_CFG_4	0x1324
-#define TX_PIN_CFG		0x1328
-#define TX_BAND_CFG	0x132c		// 0x1 use upper 20MHz. 0 juse lower 20MHz
-#define TX_SW_CFG0		0x1330
-#define TX_SW_CFG1		0x1334
-#define TX_SW_CFG2		0x1338
-#define TXOP_THRES_CFG		0x133c
-#define TXOP_CTRL_CFG		0x1340
-#define TX_RTS_CFG		0x1344
-
-#ifdef RT_BIG_ENDIAN
-typedef	union	_TX_RTS_CFG_STRUC	{
-	struct	{
-	    UINT32       rsv:7;
-	    UINT32       RtsFbkEn:1;    // enable rts rate fallback
-	    UINT32       RtsThres:16;    // unit:byte
-	    UINT32       AutoRtsRetryLimit:8;
-	}	field;
-	UINT32			word;
-}	TX_RTS_CFG_STRUC, *PTX_RTS_CFG_STRUC;
-#else
-typedef	union	_TX_RTS_CFG_STRUC	{
-	struct	{
-	    UINT32       AutoRtsRetryLimit:8;
-	    UINT32       RtsThres:16;    // unit:byte
-	    UINT32       RtsFbkEn:1;    // enable rts rate fallback
-	    UINT32       rsv:7;     // 1: HT non-STBC control frame enable
-	}	field;
-	UINT32			word;
-}	TX_RTS_CFG_STRUC, *PTX_RTS_CFG_STRUC;
-#endif
-#define TX_TIMEOUT_CFG	0x1348
-#ifdef RT_BIG_ENDIAN
-typedef	union	_TX_TIMEOUT_CFG_STRUC	{
-	struct	{
-	    UINT32       rsv2:8;
-	    UINT32       TxopTimeout:8;	//TXOP timeout value for TXOP truncation.  It is recommended that (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT)
-	    UINT32       RxAckTimeout:8;	// unit:slot. Used for TX precedure
-	    UINT32       MpduLifeTime:4;    //  expiration time = 2^(9+MPDU LIFE TIME)  us
-	    UINT32       rsv:4;
-	}	field;
-	UINT32			word;
-}	TX_TIMEOUT_CFG_STRUC, *PTX_TIMEOUT_CFG_STRUC;
-#else
-typedef	union	_TX_TIMEOUT_CFG_STRUC	{
-	struct	{
-	    UINT32       rsv:4;
-	    UINT32       MpduLifeTime:4;    //  expiration time = 2^(9+MPDU LIFE TIME)  us
-	    UINT32       RxAckTimeout:8;	// unit:slot. Used for TX precedure
-	    UINT32       TxopTimeout:8;	//TXOP timeout value for TXOP truncation.  It is recommended that (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT)
-	    UINT32       rsv2:8;     // 1: HT non-STBC control frame enable
-	}	field;
-	UINT32			word;
-}	TX_TIMEOUT_CFG_STRUC, *PTX_TIMEOUT_CFG_STRUC;
-#endif
-#define TX_RTY_CFG	0x134c
-#ifdef RT_BIG_ENDIAN
-typedef	union PACKED _TX_RTY_CFG_STRUC	{
-	struct	{
-	    UINT32       rsv:1;
-	    UINT32       TxautoFBEnable:1;    // Tx retry PHY rate auto fallback enable
-	    UINT32       AggRtyMode:1;	// Aggregate MPDU retry mode.  0:expired by retry limit, 1: expired by mpdu life timer
-	    UINT32       NonAggRtyMode:1;	// Non-Aggregate MPDU retry mode.  0:expired by retry limit, 1: expired by mpdu life timer
-	    UINT32       LongRtyThre:12;	// Long retry threshoold
-	    UINT32       LongRtyLimit:8;	//long retry limit
-	    UINT32       ShortRtyLimit:8;	//  short retry limit
-
-	}	field;
-	UINT32			word;
-}	TX_RTY_CFG_STRUC, *PTX_RTY_CFG_STRUC;
-#else
-typedef	union PACKED _TX_RTY_CFG_STRUC	{
-	struct	{
-	    UINT32       ShortRtyLimit:8;	//  short retry limit
-	    UINT32       LongRtyLimit:8;	//long retry limit
-	    UINT32       LongRtyThre:12;	// Long retry threshoold
-	    UINT32       NonAggRtyMode:1;	// Non-Aggregate MPDU retry mode.  0:expired by retry limit, 1: expired by mpdu life timer
-	    UINT32       AggRtyMode:1;	// Aggregate MPDU retry mode.  0:expired by retry limit, 1: expired by mpdu life timer
-	    UINT32       TxautoFBEnable:1;    // Tx retry PHY rate auto fallback enable
-	    UINT32       rsv:1;     // 1: HT non-STBC control frame enable
-	}	field;
-	UINT32			word;
-}	TX_RTY_CFG_STRUC, *PTX_RTY_CFG_STRUC;
-#endif
-#define TX_LINK_CFG	0x1350
-#ifdef RT_BIG_ENDIAN
-typedef	union	PACKED _TX_LINK_CFG_STRUC	{
-	struct PACKED {
-	    UINT32       RemotMFS:8;	//remote MCS feedback sequence number
-	    UINT32       RemotMFB:8;    //  remote MCS feedback
-	    UINT32       rsv:3;	//
-	    UINT32       TxCFAckEn:1;	//   Piggyback CF-ACK enable
-	    UINT32       TxRDGEn:1;	// RDG TX enable
-	    UINT32       TxMRQEn:1;	//  MCS request TX enable
-	    UINT32       RemoteUMFSEnable:1;	//  remote unsolicit  MFB enable.  0: not apply remote remote unsolicit (MFS=7)
-	    UINT32       MFBEnable:1;	//  TX apply remote MFB 1:enable
-	    UINT32       RemoteMFBLifeTime:8;	//remote MFB life time. unit : 32us
-	}	field;
-	UINT32			word;
-}	TX_LINK_CFG_STRUC, *PTX_LINK_CFG_STRUC;
-#else
-typedef	union	PACKED _TX_LINK_CFG_STRUC	{
-	struct PACKED {
-	    UINT32       RemoteMFBLifeTime:8;	//remote MFB life time. unit : 32us
-	    UINT32       MFBEnable:1;	//  TX apply remote MFB 1:enable
-	    UINT32       RemoteUMFSEnable:1;	//  remote unsolicit  MFB enable.  0: not apply remote remote unsolicit (MFS=7)
-	    UINT32       TxMRQEn:1;	//  MCS request TX enable
-	    UINT32       TxRDGEn:1;	// RDG TX enable
-	    UINT32       TxCFAckEn:1;	//   Piggyback CF-ACK enable
-	    UINT32       rsv:3;	//
-	    UINT32       RemotMFB:8;    //  remote MCS feedback
-	    UINT32       RemotMFS:8;	//remote MCS feedback sequence number
-	}	field;
-	UINT32			word;
-}	TX_LINK_CFG_STRUC, *PTX_LINK_CFG_STRUC;
-#endif
-#define HT_FBK_CFG0	0x1354
-#ifdef RT_BIG_ENDIAN
-typedef	union PACKED _HT_FBK_CFG0_STRUC	{
-	struct	{
-	    UINT32       HTMCS7FBK:4;
-	    UINT32       HTMCS6FBK:4;
-	    UINT32       HTMCS5FBK:4;
-	    UINT32       HTMCS4FBK:4;
-	    UINT32       HTMCS3FBK:4;
-	    UINT32       HTMCS2FBK:4;
-	    UINT32       HTMCS1FBK:4;
-	    UINT32       HTMCS0FBK:4;
-	}	field;
-	UINT32			word;
-}	HT_FBK_CFG0_STRUC, *PHT_FBK_CFG0_STRUC;
-#else
-typedef	union PACKED _HT_FBK_CFG0_STRUC	{
-	struct	{
-	    UINT32       HTMCS0FBK:4;
-	    UINT32       HTMCS1FBK:4;
-	    UINT32       HTMCS2FBK:4;
-	    UINT32       HTMCS3FBK:4;
-	    UINT32       HTMCS4FBK:4;
-	    UINT32       HTMCS5FBK:4;
-	    UINT32       HTMCS6FBK:4;
-	    UINT32       HTMCS7FBK:4;
-	}	field;
-	UINT32			word;
-}	HT_FBK_CFG0_STRUC, *PHT_FBK_CFG0_STRUC;
-#endif
-#define HT_FBK_CFG1	0x1358
-#ifdef RT_BIG_ENDIAN
-typedef	union	_HT_FBK_CFG1_STRUC	{
-	struct	{
-	    UINT32       HTMCS15FBK:4;
-	    UINT32       HTMCS14FBK:4;
-	    UINT32       HTMCS13FBK:4;
-	    UINT32       HTMCS12FBK:4;
-	    UINT32       HTMCS11FBK:4;
-	    UINT32       HTMCS10FBK:4;
-	    UINT32       HTMCS9FBK:4;
-	    UINT32       HTMCS8FBK:4;
-	}	field;
-	UINT32			word;
-}	HT_FBK_CFG1_STRUC, *PHT_FBK_CFG1_STRUC;
-#else
-typedef	union	_HT_FBK_CFG1_STRUC	{
-	struct	{
-	    UINT32       HTMCS8FBK:4;
-	    UINT32       HTMCS9FBK:4;
-	    UINT32       HTMCS10FBK:4;
-	    UINT32       HTMCS11FBK:4;
-	    UINT32       HTMCS12FBK:4;
-	    UINT32       HTMCS13FBK:4;
-	    UINT32       HTMCS14FBK:4;
-	    UINT32       HTMCS15FBK:4;
-	}	field;
-	UINT32			word;
-}	HT_FBK_CFG1_STRUC, *PHT_FBK_CFG1_STRUC;
-#endif
-#define LG_FBK_CFG0	0x135c
-#ifdef RT_BIG_ENDIAN
-typedef	union	_LG_FBK_CFG0_STRUC	{
-	struct	{
-	    UINT32       OFDMMCS7FBK:4;	//initial value is 6
-	    UINT32       OFDMMCS6FBK:4;	//initial value is 5
-	    UINT32       OFDMMCS5FBK:4;	//initial value is 4
-	    UINT32       OFDMMCS4FBK:4;	//initial value is 3
-	    UINT32       OFDMMCS3FBK:4;	//initial value is 2
-	    UINT32       OFDMMCS2FBK:4;	//initial value is 1
-	    UINT32       OFDMMCS1FBK:4;	//initial value is 0
-	    UINT32       OFDMMCS0FBK:4;	//initial value is 0
-	}	field;
-	UINT32			word;
-}	LG_FBK_CFG0_STRUC, *PLG_FBK_CFG0_STRUC;
-#else
-typedef	union	_LG_FBK_CFG0_STRUC	{
-	struct	{
-	    UINT32       OFDMMCS0FBK:4;	//initial value is 0
-	    UINT32       OFDMMCS1FBK:4;	//initial value is 0
-	    UINT32       OFDMMCS2FBK:4;	//initial value is 1
-	    UINT32       OFDMMCS3FBK:4;	//initial value is 2
-	    UINT32       OFDMMCS4FBK:4;	//initial value is 3
-	    UINT32       OFDMMCS5FBK:4;	//initial value is 4
-	    UINT32       OFDMMCS6FBK:4;	//initial value is 5
-	    UINT32       OFDMMCS7FBK:4;	//initial value is 6
-	}	field;
-	UINT32			word;
-}	LG_FBK_CFG0_STRUC, *PLG_FBK_CFG0_STRUC;
-#endif
-#define LG_FBK_CFG1		0x1360
-#ifdef RT_BIG_ENDIAN
-typedef	union	_LG_FBK_CFG1_STRUC	{
-	struct	{
-	    UINT32       rsv:16;
-	    UINT32       CCKMCS3FBK:4;	//initial value is 2
-	    UINT32       CCKMCS2FBK:4;	//initial value is 1
-	    UINT32       CCKMCS1FBK:4;	//initial value is 0
-	    UINT32       CCKMCS0FBK:4;	//initial value is 0
-	}	field;
-	UINT32			word;
-}	LG_FBK_CFG1_STRUC, *PLG_FBK_CFG1_STRUC;
-#else
-typedef	union	_LG_FBK_CFG1_STRUC	{
-	struct	{
-	    UINT32       CCKMCS0FBK:4;	//initial value is 0
-	    UINT32       CCKMCS1FBK:4;	//initial value is 0
-	    UINT32       CCKMCS2FBK:4;	//initial value is 1
-	    UINT32       CCKMCS3FBK:4;	//initial value is 2
-	    UINT32       rsv:16;
-	}	field;
-	UINT32			word;
-}	LG_FBK_CFG1_STRUC, *PLG_FBK_CFG1_STRUC;
-#endif
-
-
-//=======================================================
-//================ Protection Paramater================================
-//=======================================================
-#define CCK_PROT_CFG	0x1364		//CCK Protection
-#define ASIC_SHORTNAV		1
-#define ASIC_LONGNAV		2
-#define ASIC_RTS		1
-#define ASIC_CTS		2
-#ifdef RT_BIG_ENDIAN
-typedef	union	_PROT_CFG_STRUC	{
-	struct	{
-	    UINT32       rsv:5;
-	    UINT32       RTSThEn:1;	//RTS threshold enable on CCK TX
-	    UINT32       TxopAllowGF40:1;	//CCK TXOP allowance.0:disallow.
-	    UINT32       TxopAllowGF20:1;	//CCK TXOP allowance.0:disallow.
-	    UINT32       TxopAllowMM40:1;	//CCK TXOP allowance.0:disallow.
-	    UINT32       TxopAllowMM20:1;	//CCK TXOP allowance. 0:disallow.
-	    UINT32       TxopAllowOfdm:1;	//CCK TXOP allowance.0:disallow.
-	    UINT32       TxopAllowCck:1;	//CCK TXOP allowance.0:disallow.
-	    UINT32       ProtectNav:2;	//TXOP protection type for CCK TX. 0:None, 1:ShortNAVprotect,  2:LongNAVProtect, 3:rsv
-	    UINT32       ProtectCtrl:2;	//Protection control frame type for CCK TX. 1:RTS/CTS, 2:CTS-to-self, 0:None, 3:rsv
-	    UINT32       ProtectRate:16;	//Protection control frame rate for CCK TX(RTS/CTS/CFEnd).
-	}	field;
-	UINT32			word;
-}	PROT_CFG_STRUC, *PPROT_CFG_STRUC;
-#else
-typedef	union	_PROT_CFG_STRUC	{
-	struct	{
-	    UINT32       ProtectRate:16;	//Protection control frame rate for CCK TX(RTS/CTS/CFEnd).
-	    UINT32       ProtectCtrl:2;	//Protection control frame type for CCK TX. 1:RTS/CTS, 2:CTS-to-self, 0:None, 3:rsv
-	    UINT32       ProtectNav:2;	//TXOP protection type for CCK TX. 0:None, 1:ShortNAVprotect,  2:LongNAVProtect, 3:rsv
-	    UINT32       TxopAllowCck:1;	//CCK TXOP allowance.0:disallow.
-	    UINT32       TxopAllowOfdm:1;	//CCK TXOP allowance.0:disallow.
-	    UINT32       TxopAllowMM20:1;	//CCK TXOP allowance. 0:disallow.
-	    UINT32       TxopAllowMM40:1;	//CCK TXOP allowance.0:disallow.
-	    UINT32       TxopAllowGF20:1;	//CCK TXOP allowance.0:disallow.
-	    UINT32       TxopAllowGF40:1;	//CCK TXOP allowance.0:disallow.
-	    UINT32       RTSThEn:1;	//RTS threshold enable on CCK TX
-	    UINT32       rsv:5;
-	}	field;
-	UINT32			word;
-}	PROT_CFG_STRUC, *PPROT_CFG_STRUC;
-#endif
-
-#define OFDM_PROT_CFG	0x1368		//OFDM Protection
-#define MM20_PROT_CFG	0x136C		//MM20 Protection
-#define MM40_PROT_CFG	0x1370		//MM40 Protection
-#define GF20_PROT_CFG	0x1374		//GF20 Protection
-#define GF40_PROT_CFG	0x1378		//GR40 Protection
-#define EXP_CTS_TIME	0x137C		//
-#define EXP_ACK_TIME	0x1380		//
-
-//
-//  4.4 MAC RX configuration registers (offset:0x1400)
-//
-#define RX_FILTR_CFG	0x1400			//TXRX_CSR0
-#define AUTO_RSP_CFG	0x1404			//TXRX_CSR4
-//
-// TXRX_CSR4: Auto-Responder/
-//
-#ifdef RT_BIG_ENDIAN
-typedef union _AUTO_RSP_CFG_STRUC {
- struct {
-     UINT32        :24;
-     UINT32       AckCtsPsmBit:1;   // Power bit value in conrtrol frame
-     UINT32       DualCTSEn:1;   // Power bit value in conrtrol frame
-     UINT32       rsv:1;   // Power bit value in conrtrol frame
-     UINT32       AutoResponderPreamble:1;    // 0:long, 1:short preamble
-     UINT32       CTS40MRef:1;  // Response CTS 40MHz duplicate mode
-     UINT32       CTS40MMode:1;  // Response CTS 40MHz duplicate mode
-     UINT32       BACAckPolicyEnable:1;    // 0:long, 1:short preamble
-     UINT32       AutoResponderEnable:1;
- } field;
- UINT32   word;
-} AUTO_RSP_CFG_STRUC, *PAUTO_RSP_CFG_STRUC;
-#else
-typedef union _AUTO_RSP_CFG_STRUC {
- struct {
-     UINT32       AutoResponderEnable:1;
-     UINT32       BACAckPolicyEnable:1;    // 0:long, 1:short preamble
-     UINT32       CTS40MMode:1;  // Response CTS 40MHz duplicate mode
-     UINT32       CTS40MRef:1;  // Response CTS 40MHz duplicate mode
-     UINT32       AutoResponderPreamble:1;    // 0:long, 1:short preamble
-     UINT32       rsv:1;   // Power bit value in conrtrol frame
-     UINT32       DualCTSEn:1;   // Power bit value in conrtrol frame
-     UINT32       AckCtsPsmBit:1;   // Power bit value in conrtrol frame
-     UINT32        :24;
- } field;
- UINT32   word;
-} AUTO_RSP_CFG_STRUC, *PAUTO_RSP_CFG_STRUC;
-#endif
-
-#define LEGACY_BASIC_RATE	0x1408	//  TXRX_CSR5           0x3054
-#define HT_BASIC_RATE		0x140c
-#define HT_CTRL_CFG		0x1410
-#define SIFS_COST_CFG		0x1414
-#define RX_PARSER_CFG		0x1418	//Set NAV for all received frames
-
-//
-//  4.5 MAC Security configuration (offset:0x1500)
-//
-#define TX_SEC_CNT0		0x1500		//
-#define RX_SEC_CNT0		0x1504		//
-#define CCMP_FC_MUTE		0x1508		//
-//
-//  4.6 HCCA/PSMP (offset:0x1600)
-//
-#define TXOP_HLDR_ADDR0		0x1600
-#define TXOP_HLDR_ADDR1		0x1604
-#define TXOP_HLDR_ET		0x1608
-#define QOS_CFPOLL_RA_DW0		0x160c
-#define QOS_CFPOLL_A1_DW1		0x1610
-#define QOS_CFPOLL_QC		0x1614
-//
-//  4.7 MAC Statistis registers (offset:0x1700)
-//
-#define RX_STA_CNT0		0x1700		//
-#define RX_STA_CNT1		0x1704		//
-#define RX_STA_CNT2		0x1708		//
-
-//
-// RX_STA_CNT0_STRUC: RX PLCP error count & RX CRC error count
-//
-#ifdef RT_BIG_ENDIAN
-typedef	union	_RX_STA_CNT0_STRUC	{
-	struct	{
-	    USHORT  PhyErr;
-	    USHORT  CrcErr;
-	}	field;
-	UINT32			word;
-}	RX_STA_CNT0_STRUC, *PRX_STA_CNT0_STRUC;
-#else
-typedef	union	_RX_STA_CNT0_STRUC	{
-	struct	{
-	    USHORT  CrcErr;
-	    USHORT  PhyErr;
-	}	field;
-	UINT32			word;
-}	RX_STA_CNT0_STRUC, *PRX_STA_CNT0_STRUC;
-#endif
-
-//
-// RX_STA_CNT1_STRUC: RX False CCA count & RX LONG frame count
-//
-#ifdef RT_BIG_ENDIAN
-typedef	union	_RX_STA_CNT1_STRUC	{
-	struct	{
-	    USHORT  PlcpErr;
-	    USHORT  FalseCca;
-	}	field;
-	UINT32			word;
-}	RX_STA_CNT1_STRUC, *PRX_STA_CNT1_STRUC;
-#else
-typedef	union	_RX_STA_CNT1_STRUC	{
-	struct	{
-	    USHORT  FalseCca;
-	    USHORT  PlcpErr;
-	}	field;
-	UINT32			word;
-}	RX_STA_CNT1_STRUC, *PRX_STA_CNT1_STRUC;
-#endif
-
-//
-// RX_STA_CNT2_STRUC:
-//
-#ifdef RT_BIG_ENDIAN
-typedef	union	_RX_STA_CNT2_STRUC	{
-	struct	{
-	    USHORT  RxFifoOverflowCount;
-	    USHORT  RxDupliCount;
-	}	field;
-	UINT32			word;
-}	RX_STA_CNT2_STRUC, *PRX_STA_CNT2_STRUC;
-#else
-typedef	union	_RX_STA_CNT2_STRUC	{
-	struct	{
-	    USHORT  RxDupliCount;
-	    USHORT  RxFifoOverflowCount;
-	}	field;
-	UINT32			word;
-}	RX_STA_CNT2_STRUC, *PRX_STA_CNT2_STRUC;
-#endif
-#define TX_STA_CNT0		0x170C		//
-//
-// STA_CSR3: TX Beacon count
-//
-#ifdef RT_BIG_ENDIAN
-typedef	union	_TX_STA_CNT0_STRUC	{
-	struct	{
-	    USHORT  TxBeaconCount;
-	    USHORT  TxFailCount;
-	}	field;
-	UINT32			word;
-}	TX_STA_CNT0_STRUC, *PTX_STA_CNT0_STRUC;
-#else
-typedef	union	_TX_STA_CNT0_STRUC	{
-	struct	{
-	    USHORT  TxFailCount;
-	    USHORT  TxBeaconCount;
-	}	field;
-	UINT32			word;
-}	TX_STA_CNT0_STRUC, *PTX_STA_CNT0_STRUC;
-#endif
-#define TX_STA_CNT1		0x1710		//
-//
-// TX_STA_CNT1: TX tx count
-//
-#ifdef RT_BIG_ENDIAN
-typedef	union	_TX_STA_CNT1_STRUC	{
-	struct	{
-	    USHORT  TxRetransmit;
-	    USHORT  TxSuccess;
-	}	field;
-	UINT32			word;
-}	TX_STA_CNT1_STRUC, *PTX_STA_CNT1_STRUC;
-#else
-typedef	union	_TX_STA_CNT1_STRUC	{
-	struct	{
-	    USHORT  TxSuccess;
-	    USHORT  TxRetransmit;
-	}	field;
-	UINT32			word;
-}	TX_STA_CNT1_STRUC, *PTX_STA_CNT1_STRUC;
-#endif
-#define TX_STA_CNT2		0x1714		//
-//
-// TX_STA_CNT2: TX tx count
-//
-#ifdef RT_BIG_ENDIAN
-typedef	union	_TX_STA_CNT2_STRUC	{
-	struct	{
-	    USHORT  TxUnderFlowCount;
-	    USHORT  TxZeroLenCount;
-	}	field;
-	UINT32			word;
-}	TX_STA_CNT2_STRUC, *PTX_STA_CNT2_STRUC;
-#else
-typedef	union	_TX_STA_CNT2_STRUC	{
-	struct	{
-	    USHORT  TxZeroLenCount;
-	    USHORT  TxUnderFlowCount;
-	}	field;
-	UINT32			word;
-}	TX_STA_CNT2_STRUC, *PTX_STA_CNT2_STRUC;
-#endif
-#define TX_STA_FIFO		0x1718		//
-//
-// TX_STA_FIFO_STRUC: TX Result for specific PID status fifo register
-//
-#ifdef RT_BIG_ENDIAN
-typedef	union PACKED _TX_STA_FIFO_STRUC	{
-	struct	{
-		UINT32		Reserve:2;
-		UINT32		TxBF:1; // 3*3
-		UINT32		SuccessRate:13;	//include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
-//		UINT32		SuccessRate:16;	//include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
-		UINT32		wcid:8;		//wireless client index
-		UINT32		TxAckRequired:1;    // ack required
-		UINT32		TxAggre:1;    // Tx is aggregated
-		UINT32		TxSuccess:1;   // Tx success. whether success or not
-		UINT32		PidType:4;
-		UINT32		bValid:1;   // 1:This register contains a valid TX result
-	}	field;
-	UINT32			word;
-}	TX_STA_FIFO_STRUC, *PTX_STA_FIFO_STRUC;
-#else
-typedef	union PACKED _TX_STA_FIFO_STRUC	{
-	struct	{
-		UINT32		bValid:1;   // 1:This register contains a valid TX result
-		UINT32		PidType:4;
-		UINT32		TxSuccess:1;   // Tx No retry success
-		UINT32		TxAggre:1;    // Tx Retry Success
-		UINT32		TxAckRequired:1;    // Tx fail
-		UINT32		wcid:8;		//wireless client index
-//		UINT32		SuccessRate:16;	//include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
-		UINT32		SuccessRate:13;	//include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
-		UINT32		TxBF:1;
-		UINT32		Reserve:2;
-	}	field;
-	UINT32			word;
-}	TX_STA_FIFO_STRUC, *PTX_STA_FIFO_STRUC;
-#endif
-// Debug counter
-#define TX_AGG_CNT	0x171c
-#ifdef RT_BIG_ENDIAN
-typedef	union	_TX_AGG_CNT_STRUC	{
-	struct	{
-	    USHORT  AggTxCount;
-	    USHORT  NonAggTxCount;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT_STRUC, *PTX_AGG_CNT_STRUC;
-#else
-typedef	union	_TX_AGG_CNT_STRUC	{
-	struct	{
-	    USHORT  NonAggTxCount;
-	    USHORT  AggTxCount;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT_STRUC, *PTX_AGG_CNT_STRUC;
-#endif
-// Debug counter
-#define TX_AGG_CNT0	0x1720
-#ifdef RT_BIG_ENDIAN
-typedef	union	_TX_AGG_CNT0_STRUC	{
-	struct	{
-	    USHORT  AggSize2Count;
-	    USHORT  AggSize1Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT0_STRUC, *PTX_AGG_CNT0_STRUC;
-#else
-typedef	union	_TX_AGG_CNT0_STRUC	{
-	struct	{
-	    USHORT  AggSize1Count;
-	    USHORT  AggSize2Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT0_STRUC, *PTX_AGG_CNT0_STRUC;
-#endif
-// Debug counter
-#define TX_AGG_CNT1	0x1724
-#ifdef RT_BIG_ENDIAN
-typedef	union	_TX_AGG_CNT1_STRUC	{
-	struct	{
-	    USHORT  AggSize4Count;
-	    USHORT  AggSize3Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT1_STRUC, *PTX_AGG_CNT1_STRUC;
-#else
-typedef	union	_TX_AGG_CNT1_STRUC	{
-	struct	{
-	    USHORT  AggSize3Count;
-	    USHORT  AggSize4Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT1_STRUC, *PTX_AGG_CNT1_STRUC;
-#endif
-#define TX_AGG_CNT2	0x1728
-#ifdef RT_BIG_ENDIAN
-typedef	union	_TX_AGG_CNT2_STRUC	{
-	struct	{
-	    USHORT  AggSize6Count;
-	    USHORT  AggSize5Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT2_STRUC, *PTX_AGG_CNT2_STRUC;
-#else
-typedef	union	_TX_AGG_CNT2_STRUC	{
-	struct	{
-	    USHORT  AggSize5Count;
-	    USHORT  AggSize6Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT2_STRUC, *PTX_AGG_CNT2_STRUC;
-#endif
-// Debug counter
-#define TX_AGG_CNT3	0x172c
-#ifdef RT_BIG_ENDIAN
-typedef	union	_TX_AGG_CNT3_STRUC	{
-	struct	{
-	    USHORT  AggSize8Count;
-	    USHORT  AggSize7Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT3_STRUC, *PTX_AGG_CNT3_STRUC;
-#else
-typedef	union	_TX_AGG_CNT3_STRUC	{
-	struct	{
-	    USHORT  AggSize7Count;
-	    USHORT  AggSize8Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT3_STRUC, *PTX_AGG_CNT3_STRUC;
-#endif
-// Debug counter
-#define TX_AGG_CNT4	0x1730
-#ifdef RT_BIG_ENDIAN
-typedef	union	_TX_AGG_CNT4_STRUC	{
-	struct	{
-	    USHORT  AggSize10Count;
-	    USHORT  AggSize9Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT4_STRUC, *PTX_AGG_CNT4_STRUC;
-#else
-typedef	union	_TX_AGG_CNT4_STRUC	{
-	struct	{
-	    USHORT  AggSize9Count;
-	    USHORT  AggSize10Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT4_STRUC, *PTX_AGG_CNT4_STRUC;
-#endif
-#define TX_AGG_CNT5	0x1734
-#ifdef RT_BIG_ENDIAN
-typedef	union	_TX_AGG_CNT5_STRUC	{
-	struct	{
-	    USHORT  AggSize12Count;
-	    USHORT  AggSize11Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT5_STRUC, *PTX_AGG_CNT5_STRUC;
-#else
-typedef	union	_TX_AGG_CNT5_STRUC	{
-	struct	{
-	    USHORT  AggSize11Count;
-	    USHORT  AggSize12Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT5_STRUC, *PTX_AGG_CNT5_STRUC;
-#endif
-#define TX_AGG_CNT6		0x1738
-#ifdef RT_BIG_ENDIAN
-typedef	union	_TX_AGG_CNT6_STRUC	{
-	struct	{
-	    USHORT  AggSize14Count;
-	    USHORT  AggSize13Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT6_STRUC, *PTX_AGG_CNT6_STRUC;
-#else
-typedef	union	_TX_AGG_CNT6_STRUC	{
-	struct	{
-	    USHORT  AggSize13Count;
-	    USHORT  AggSize14Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT6_STRUC, *PTX_AGG_CNT6_STRUC;
-#endif
-#define TX_AGG_CNT7		0x173c
-#ifdef RT_BIG_ENDIAN
-typedef	union	_TX_AGG_CNT7_STRUC	{
-	struct	{
-	    USHORT  AggSize16Count;
-	    USHORT  AggSize15Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT7_STRUC, *PTX_AGG_CNT7_STRUC;
-#else
-typedef	union	_TX_AGG_CNT7_STRUC	{
-	struct	{
-	    USHORT  AggSize15Count;
-	    USHORT  AggSize16Count;
-	}	field;
-	UINT32			word;
-}	TX_AGG_CNT7_STRUC, *PTX_AGG_CNT7_STRUC;
-#endif
-#define MPDU_DENSITY_CNT		0x1740
-#ifdef RT_BIG_ENDIAN
-typedef	union	_MPDU_DEN_CNT_STRUC	{
-	struct	{
-	    USHORT  RXZeroDelCount;	//RX zero length delimiter count
-	    USHORT  TXZeroDelCount;	//TX zero length delimiter count
-	}	field;
-	UINT32			word;
-}	MPDU_DEN_CNT_STRUC, *PMPDU_DEN_CNT_STRUC;
-#else
-typedef	union	_MPDU_DEN_CNT_STRUC	{
-	struct	{
-	    USHORT  TXZeroDelCount;	//TX zero length delimiter count
-	    USHORT  RXZeroDelCount;	//RX zero length delimiter count
-	}	field;
-	UINT32			word;
-}	MPDU_DEN_CNT_STRUC, *PMPDU_DEN_CNT_STRUC;
-#endif
-//
-// TXRX control registers - base address 0x3000
-//
-// rt2860b  UNKNOWN reg use R/O Reg Addr 0x77d0 first..
-#define TXRX_CSR1           0x77d0
-
-//
-// Security key table memory, base address = 0x1000
-//
-#define MAC_WCID_BASE		0x1800 //8-bytes(use only 6-bytes) * 256 entry =
-#define HW_WCID_ENTRY_SIZE   8
-#define PAIRWISE_KEY_TABLE_BASE     0x4000      // 32-byte * 256-entry =  -byte
-#define HW_KEY_ENTRY_SIZE           0x20
-#define PAIRWISE_IVEIV_TABLE_BASE     0x6000      // 8-byte * 256-entry =  -byte
-#define MAC_IVEIV_TABLE_BASE     0x6000      // 8-byte * 256-entry =  -byte
-#define HW_IVEIV_ENTRY_SIZE   8
-#define MAC_WCID_ATTRIBUTE_BASE     0x6800      // 4-byte * 256-entry =  -byte
-#define HW_WCID_ATTRI_SIZE   4
-#define WCID_RESERVED			0x6bfc
-#define SHARED_KEY_TABLE_BASE       0x6c00      // 32-byte * 16-entry = 512-byte
-#define SHARED_KEY_MODE_BASE       0x7000      // 32-byte * 16-entry = 512-byte
-#define HW_SHARED_KEY_MODE_SIZE   4
-#define SHAREDKEYTABLE			0
-#define PAIRWISEKEYTABLE			1
-
-
-#ifdef RT_BIG_ENDIAN
-typedef	union	_SHAREDKEY_MODE_STRUC	{
-	struct	{
-		UINT32       :1;
-		UINT32       Bss1Key3CipherAlg:3;
-		UINT32       :1;
-		UINT32       Bss1Key2CipherAlg:3;
-		UINT32       :1;
-		UINT32       Bss1Key1CipherAlg:3;
-		UINT32       :1;
-		UINT32       Bss1Key0CipherAlg:3;
-		UINT32       :1;
-		UINT32       Bss0Key3CipherAlg:3;
-		UINT32       :1;
-		UINT32       Bss0Key2CipherAlg:3;
-		UINT32       :1;
-		UINT32       Bss0Key1CipherAlg:3;
-		UINT32       :1;
-		UINT32       Bss0Key0CipherAlg:3;
-	}	field;
-	UINT32			word;
-}	SHAREDKEY_MODE_STRUC, *PSHAREDKEY_MODE_STRUC;
-#else
-typedef	union	_SHAREDKEY_MODE_STRUC	{
-	struct	{
-		UINT32       Bss0Key0CipherAlg:3;
-		UINT32       :1;
-		UINT32       Bss0Key1CipherAlg:3;
-		UINT32       :1;
-		UINT32       Bss0Key2CipherAlg:3;
-		UINT32       :1;
-		UINT32       Bss0Key3CipherAlg:3;
-		UINT32       :1;
-		UINT32       Bss1Key0CipherAlg:3;
-		UINT32       :1;
-		UINT32       Bss1Key1CipherAlg:3;
-		UINT32       :1;
-		UINT32       Bss1Key2CipherAlg:3;
-		UINT32       :1;
-		UINT32       Bss1Key3CipherAlg:3;
-		UINT32       :1;
-	}	field;
-	UINT32			word;
-}	SHAREDKEY_MODE_STRUC, *PSHAREDKEY_MODE_STRUC;
-#endif
-// 64-entry for pairwise key table
-typedef struct _HW_WCID_ENTRY {  // 8-byte per entry
-    UCHAR   Address[6];
-    UCHAR   Rsv[2];
-} HW_WCID_ENTRY, PHW_WCID_ENTRY;
-
-
-// =================================================================================
-// WCID  format
-// =================================================================================
-//7.1	WCID  ENTRY  format  : 8bytes
-typedef	struct	_WCID_ENTRY_STRUC {
-	UCHAR		RXBABitmap7;    // bit0 for TID8, bit7 for TID 15
-	UCHAR		RXBABitmap0;    // bit0 for TID0, bit7 for TID 7
-	UCHAR		MAC[6];	// 0 for shared key table.  1 for pairwise key table
-}	WCID_ENTRY_STRUC, *PWCID_ENTRY_STRUC;
-
-//8.1.1	SECURITY  KEY  format  : 8DW
-// 32-byte per entry, total 16-entry for shared key table, 64-entry for pairwise key table
-typedef struct _HW_KEY_ENTRY {          // 32-byte per entry
-    UCHAR   Key[16];
-    UCHAR   TxMic[8];
-    UCHAR   RxMic[8];
-} HW_KEY_ENTRY, *PHW_KEY_ENTRY;
-
-//8.1.2	IV/EIV  format  : 2DW
-
-//8.1.3	RX attribute entry format  : 1DW
-#ifdef RT_BIG_ENDIAN
-typedef	struct	_MAC_ATTRIBUTE_STRUC {
-	UINT32		rsv:22;
-	UINT32		RXWIUDF:3;
-	UINT32		BSSIDIdx:3; //multipleBSS index for the WCID
-	UINT32		PairKeyMode:3;
-	UINT32		KeyTab:1;	// 0 for shared key table.  1 for pairwise key table
-}	MAC_ATTRIBUTE_STRUC, *PMAC_ATTRIBUTE_STRUC;
-#else
-typedef	struct	_MAC_ATTRIBUTE_STRUC {
-	UINT32		KeyTab:1;	// 0 for shared key table.  1 for pairwise key table
-	UINT32		PairKeyMode:3;
-	UINT32		BSSIDIdx:3; //multipleBSS index for the WCID
-	UINT32		RXWIUDF:3;
-	UINT32		rsv:22;
-}	MAC_ATTRIBUTE_STRUC, *PMAC_ATTRIBUTE_STRUC;
-#endif
-
-
-// =================================================================================
-// HOST-MCU communication data structure
-// =================================================================================
-
-//
-// H2M_MAILBOX_CSR: Host-to-MCU Mailbox
-//
-#ifdef RT_BIG_ENDIAN
-typedef union  _H2M_MAILBOX_STRUC {
-    struct {
-        UINT32       Owner:8;
-        UINT32       CmdToken:8;    // 0xff tells MCU not to report CmdDoneInt after excuting the command
-        UINT32       HighByte:8;
-        UINT32       LowByte:8;
-    }   field;
-    UINT32           word;
-} H2M_MAILBOX_STRUC, *PH2M_MAILBOX_STRUC;
-#else
-typedef union  _H2M_MAILBOX_STRUC {
-    struct {
-        UINT32       LowByte:8;
-        UINT32       HighByte:8;
-        UINT32       CmdToken:8;
-        UINT32       Owner:8;
-    }   field;
-    UINT32           word;
-} H2M_MAILBOX_STRUC, *PH2M_MAILBOX_STRUC;
-#endif
-
-//
-// M2H_CMD_DONE_CSR: MCU-to-Host command complete indication
-//
-#ifdef RT_BIG_ENDIAN
-typedef union _M2H_CMD_DONE_STRUC {
-    struct  {
-        UINT32       CmdToken3;
-        UINT32       CmdToken2;
-        UINT32       CmdToken1;
-        UINT32       CmdToken0;
-    } field;
-    UINT32           word;
-} M2H_CMD_DONE_STRUC, *PM2H_CMD_DONE_STRUC;
-#else
-typedef union _M2H_CMD_DONE_STRUC {
-    struct  {
-        UINT32       CmdToken0;
-        UINT32       CmdToken1;
-        UINT32       CmdToken2;
-        UINT32       CmdToken3;
-    } field;
-    UINT32           word;
-} M2H_CMD_DONE_STRUC, *PM2H_CMD_DONE_STRUC;
-#endif
-
-
-//NAV_TIME_CFG :NAV
-#ifdef RT_BIG_ENDIAN
-typedef	union	_NAV_TIME_CFG_STRUC	{
-	struct	{
-		USHORT		rsv:6;
-		USHORT		ZeroSifs:1;               // Applied zero SIFS timer after OFDM RX 0: disable
-		USHORT		Eifs:9;               // in unit of 1-us
-		UCHAR       SlotTime;    // in unit of 1-us
-		UCHAR		Sifs;               // in unit of 1-us
-	}	field;
-	UINT32			word;
-}	NAV_TIME_CFG_STRUC, *PNAV_TIME_CFG_STRUC;
-#else
-typedef	union	_NAV_TIME_CFG_STRUC	{
-	struct	{
-		UCHAR		Sifs;               // in unit of 1-us
-		UCHAR       SlotTime;    // in unit of 1-us
-		USHORT		Eifs:9;               // in unit of 1-us
-		USHORT		ZeroSifs:1;               // Applied zero SIFS timer after OFDM RX 0: disable
-		USHORT		rsv:6;
-	}	field;
-	UINT32			word;
-}	NAV_TIME_CFG_STRUC, *PNAV_TIME_CFG_STRUC;
-#endif
-
-
-//
-// RX_FILTR_CFG:  /RX configuration register
-//
-#ifdef RT_BIG_ENDIAN
-typedef	union	RX_FILTR_CFG_STRUC	{
-	struct	{
-		UINT32		:15;
-		UINT32       DropRsvCntlType:1;
-
-		UINT32		DropBAR:1;       //
-		UINT32		DropBA:1;		//
-		UINT32		DropPsPoll:1;		// Drop Ps-Poll
-		UINT32		DropRts:1;		// Drop Ps-Poll
-
-		UINT32		DropCts:1;		// Drop Ps-Poll
-		UINT32		DropAck:1;		// Drop Ps-Poll
-		UINT32		DropCFEnd:1;		// Drop Ps-Poll
-		UINT32		DropCFEndAck:1;		// Drop Ps-Poll
-
-		UINT32		DropDuplicate:1;		// Drop duplicate frame
-		UINT32		DropBcast:1;		// Drop broadcast frames
-		UINT32		DropMcast:1;		// Drop multicast frames
-		UINT32		DropVerErr:1;	    // Drop version error frame
-
-		UINT32		DropNotMyBSSID:1;			// Drop fram ToDs bit is true
-		UINT32		DropNotToMe:1;		// Drop not to me unicast frame
-		UINT32		DropPhyErr:1;		// Drop physical error
-		UINT32		DropCRCErr:1;		// Drop CRC error
-	}	field;
-	UINT32			word;
-}	RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC;
-#else
-typedef	union	_RX_FILTR_CFG_STRUC	{
-	struct	{
-		UINT32		DropCRCErr:1;		// Drop CRC error
-		UINT32		DropPhyErr:1;		// Drop physical error
-		UINT32		DropNotToMe:1;		// Drop not to me unicast frame
-		UINT32		DropNotMyBSSID:1;			// Drop fram ToDs bit is true
-
-		UINT32		DropVerErr:1;	    // Drop version error frame
-		UINT32		DropMcast:1;		// Drop multicast frames
-		UINT32		DropBcast:1;		// Drop broadcast frames
-		UINT32		DropDuplicate:1;		// Drop duplicate frame
-
-		UINT32		DropCFEndAck:1;		// Drop Ps-Poll
-		UINT32		DropCFEnd:1;		// Drop Ps-Poll
-		UINT32		DropAck:1;		// Drop Ps-Poll
-		UINT32		DropCts:1;		// Drop Ps-Poll
-
-		UINT32		DropRts:1;		// Drop Ps-Poll
-		UINT32		DropPsPoll:1;		// Drop Ps-Poll
-		UINT32		DropBA:1;		//
-		UINT32		DropBAR:1;       //
-
-		UINT32		DropRsvCntlType:1;
-		UINT32		:15;
-	}	field;
-	UINT32			word;
-}	RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC;
-#endif
-
-
-
-
-//
-// PHY_CSR4: RF serial control register
-//
-#ifdef RT_BIG_ENDIAN
-typedef	union	_PHY_CSR4_STRUC	{
-	struct	{
-		UINT32		Busy:1;				// 1: ASIC is busy execute RF programming.
-		UINT32		PLL_LD:1;			// RF PLL_LD status
-		UINT32		IFSelect:1;			// 1: select IF	to program,	0: select RF to	program
-		UINT32		NumberOfBits:5;		// Number of bits used in RFRegValue (I:20,	RFMD:22)
-		UINT32		RFRegValue:24;		// Register	value (include register	id)	serial out to RF/IF	chip.
-	}	field;
-	UINT32			word;
-}	PHY_CSR4_STRUC, *PPHY_CSR4_STRUC;
-#else
-typedef	union	_PHY_CSR4_STRUC	{
-	struct	{
-		UINT32		RFRegValue:24;		// Register	value (include register	id)	serial out to RF/IF	chip.
-		UINT32		NumberOfBits:5;		// Number of bits used in RFRegValue (I:20,	RFMD:22)
-		UINT32		IFSelect:1;			// 1: select IF	to program,	0: select RF to	program
-		UINT32		PLL_LD:1;			// RF PLL_LD status
-		UINT32		Busy:1;				// 1: ASIC is busy execute RF programming.
-	}	field;
-	UINT32			word;
-}	PHY_CSR4_STRUC, *PPHY_CSR4_STRUC;
-#endif
-
-
-//
-// SEC_CSR5: shared key table security mode register
-//
-#ifdef RT_BIG_ENDIAN
-typedef	union	_SEC_CSR5_STRUC	{
-	struct	{
-        UINT32       :1;
-        UINT32       Bss3Key3CipherAlg:3;
-        UINT32       :1;
-        UINT32       Bss3Key2CipherAlg:3;
-        UINT32       :1;
-        UINT32       Bss3Key1CipherAlg:3;
-        UINT32       :1;
-        UINT32       Bss3Key0CipherAlg:3;
-        UINT32       :1;
-        UINT32       Bss2Key3CipherAlg:3;
-        UINT32       :1;
-        UINT32       Bss2Key2CipherAlg:3;
-        UINT32       :1;
-        UINT32       Bss2Key1CipherAlg:3;
-        UINT32       :1;
-        UINT32       Bss2Key0CipherAlg:3;
-	}	field;
-	UINT32			word;
-}	SEC_CSR5_STRUC, *PSEC_CSR5_STRUC;
-#else
-typedef	union	_SEC_CSR5_STRUC	{
-	struct	{
-        UINT32       Bss2Key0CipherAlg:3;
-        UINT32       :1;
-        UINT32       Bss2Key1CipherAlg:3;
-        UINT32       :1;
-        UINT32       Bss2Key2CipherAlg:3;
-        UINT32       :1;
-        UINT32       Bss2Key3CipherAlg:3;
-        UINT32       :1;
-        UINT32       Bss3Key0CipherAlg:3;
-        UINT32       :1;
-        UINT32       Bss3Key1CipherAlg:3;
-        UINT32       :1;
-        UINT32       Bss3Key2CipherAlg:3;
-        UINT32       :1;
-        UINT32       Bss3Key3CipherAlg:3;
-        UINT32       :1;
-	}	field;
-	UINT32			word;
-}	SEC_CSR5_STRUC, *PSEC_CSR5_STRUC;
-#endif
-
-
-//
-// HOST_CMD_CSR: For HOST to interrupt embedded processor
-//
-#ifdef RT_BIG_ENDIAN
-typedef	union	_HOST_CMD_CSR_STRUC	{
-	struct	{
-	    UINT32   Rsv:24;
-	    UINT32   HostCommand:8;
-	}	field;
-	UINT32			word;
-}	HOST_CMD_CSR_STRUC, *PHOST_CMD_CSR_STRUC;
-#else
-typedef	union	_HOST_CMD_CSR_STRUC	{
-	struct	{
-	    UINT32   HostCommand:8;
-	    UINT32   Rsv:24;
-	}	field;
-	UINT32			word;
-}	HOST_CMD_CSR_STRUC, *PHOST_CMD_CSR_STRUC;
-#endif
-
-
-//
-// AIFSN_CSR: AIFSN for each EDCA AC
-//
-
-
-
-//
-// E2PROM_CSR: EEPROM control register
-//
-#ifdef RT_BIG_ENDIAN
-typedef	union	_E2PROM_CSR_STRUC	{
-	struct	{
-		UINT32		Rsvd:25;
-		UINT32       LoadStatus:1;   // 1:loading, 0:done
-		UINT32		Type:1;			// 1: 93C46, 0:93C66
-		UINT32		EepromDO:1;
-		UINT32		EepromDI:1;
-		UINT32		EepromCS:1;
-		UINT32		EepromSK:1;
-		UINT32		Reload:1;		// Reload EEPROM content, write one to reload, self-cleared.
-	}	field;
-	UINT32			word;
-}	E2PROM_CSR_STRUC, *PE2PROM_CSR_STRUC;
-#else
-typedef	union	_E2PROM_CSR_STRUC	{
-	struct	{
-		UINT32		Reload:1;		// Reload EEPROM content, write one to reload, self-cleared.
-		UINT32		EepromSK:1;
-		UINT32		EepromCS:1;
-		UINT32		EepromDI:1;
-		UINT32		EepromDO:1;
-		UINT32		Type:1;			// 1: 93C46, 0:93C66
-		UINT32       LoadStatus:1;   // 1:loading, 0:done
-		UINT32		Rsvd:25;
-	}	field;
-	UINT32			word;
-}	E2PROM_CSR_STRUC, *PE2PROM_CSR_STRUC;
-#endif
-
-//
-// QOS_CSR0: TXOP holder address0 register
-//
-#ifdef RT_BIG_ENDIAN
-typedef	union	_QOS_CSR0_STRUC	{
-	struct	{
-		UCHAR		Byte3;		// MAC address byte 3
-		UCHAR		Byte2;		// MAC address byte 2
-		UCHAR		Byte1;		// MAC address byte 1
-		UCHAR		Byte0;		// MAC address byte 0
-	}	field;
-	UINT32			word;
-}	QOS_CSR0_STRUC, *PQOS_CSR0_STRUC;
-#else
-typedef	union	_QOS_CSR0_STRUC	{
-	struct	{
-		UCHAR		Byte0;		// MAC address byte 0
-		UCHAR		Byte1;		// MAC address byte 1
-		UCHAR		Byte2;		// MAC address byte 2
-		UCHAR		Byte3;		// MAC address byte 3
-	}	field;
-	UINT32			word;
-}	QOS_CSR0_STRUC, *PQOS_CSR0_STRUC;
-#endif
-
-//
-// QOS_CSR1: TXOP holder address1 register
-//
-#ifdef RT_BIG_ENDIAN
-typedef	union	_QOS_CSR1_STRUC	{
-	struct	{
-		UCHAR		Rsvd1;
-		UCHAR		Rsvd0;
-		UCHAR		Byte5;		// MAC address byte 5
-		UCHAR		Byte4;		// MAC address byte 4
-	}	field;
-	UINT32			word;
-}	QOS_CSR1_STRUC, *PQOS_CSR1_STRUC;
-#else
-typedef	union	_QOS_CSR1_STRUC	{
-	struct	{
-		UCHAR		Byte4;		// MAC address byte 4
-		UCHAR		Byte5;		// MAC address byte 5
-		UCHAR		Rsvd0;
-		UCHAR		Rsvd1;
-	}	field;
-	UINT32			word;
-}	QOS_CSR1_STRUC, *PQOS_CSR1_STRUC;
-#endif
-
-#define	RF_CSR_CFG	0x500
-#ifdef RT_BIG_ENDIAN
-typedef	union	_RF_CSR_CFG_STRUC	{
-	struct	{
-		UINT	Rsvd1:14;				// Reserved
-		UINT	RF_CSR_KICK:1;			// kick RF register read/write
-		UINT	RF_CSR_WR:1;			// 0: read  1: write
-		UINT	Rsvd2:3;				// Reserved
-		UINT	TESTCSR_RFACC_REGNUM:5;	// RF register ID
-		UINT	RF_CSR_DATA:8;			// DATA
-	}	field;
-	UINT	word;
-}	RF_CSR_CFG_STRUC, *PRF_CSR_CFG_STRUC;
-#else
-typedef	union	_RF_CSR_CFG_STRUC	{
-	struct	{
-		UINT	RF_CSR_DATA:8;			// DATA
-		UINT	TESTCSR_RFACC_REGNUM:5;	// RF register ID
-		UINT	Rsvd2:3;				// Reserved
-		UINT	RF_CSR_WR:1;			// 0: read  1: write
-		UINT	RF_CSR_KICK:1;			// kick RF register read/write
-		UINT	Rsvd1:14;				// Reserved
-	}	field;
-	UINT	word;
-}	RF_CSR_CFG_STRUC, *PRF_CSR_CFG_STRUC;
-#endif
-
-
-//
-// Other on-chip shared memory space, base = 0x2000
-//
-
-// CIS space - base address = 0x2000
-#define HW_CIS_BASE             0x2000
-
-// Carrier-sense CTS frame base address. It's where mac stores carrier-sense frame for carrier-sense function.
-#define HW_CS_CTS_BASE			0x7700
-// DFS CTS frame base address. It's where mac stores CTS frame for DFS.
-#define HW_DFS_CTS_BASE			0x7780
-#define HW_CTS_FRAME_SIZE		0x80
-
-// 2004-11-08 john - since NULL frame won't be that long (256 byte). We steal 16 tail bytes
-// to save debugging settings
-#define HW_DEBUG_SETTING_BASE   0x77f0  // 0x77f0~0x77ff total 16 bytes
-#define HW_DEBUG_SETTING_BASE2   0x7770  // 0x77f0~0x77ff total 16 bytes
-
-// In order to support maximum 8 MBSS and its maximum length is 512 for each beacon
-// Three section discontinue memory segments will be used.
-// 1. The original region for BCN 0~3
-// 2. Extract memory from FCE table for BCN 4~5
-// 3. Extract memory from Pair-wise key table for BCN 6~7
-//	  It occupied those memory of wcid 238~253 for BCN 6
-//						      and wcid 222~237 for BCN 7
-#define HW_BEACON_MAX_SIZE      0x1000 /* unit: byte */
-#define HW_BEACON_BASE0         0x7800
-#define HW_BEACON_BASE1         0x7A00
-#define HW_BEACON_BASE2         0x7C00
-#define HW_BEACON_BASE3         0x7E00
-#define HW_BEACON_BASE4         0x7200
-#define HW_BEACON_BASE5         0x7400
-#define HW_BEACON_BASE6         0x5DC0
-#define HW_BEACON_BASE7         0x5BC0
-
-#define HW_BEACON_MAX_COUNT     8
-#define HW_BEACON_OFFSET		0x0200
-#define HW_BEACON_CONTENT_LEN	(HW_BEACON_OFFSET - TXWI_SIZE)
-
-// HOST-MCU shared memory - base address = 0x2100
-#define HOST_CMD_CSR		0x404
-#define H2M_MAILBOX_CSR         0x7010
-#define H2M_MAILBOX_CID         0x7014
-#define H2M_MAILBOX_STATUS      0x701c
-#define H2M_INT_SRC             0x7024
-#define H2M_BBP_AGENT           0x7028
-#define M2H_CMD_DONE_CSR        0x000c
-#define MCU_TXOP_ARRAY_BASE     0x000c   // TODO: to be provided by Albert
-#define MCU_TXOP_ENTRY_SIZE     32       // TODO: to be provided by Albert
-#define MAX_NUM_OF_TXOP_ENTRY   16       // TODO: must be same with 8051 firmware
-#define MCU_MBOX_VERSION        0x01     // TODO: to be confirmed by Albert
-#define MCU_MBOX_VERSION_OFFSET 5        // TODO: to be provided by Albert
-
-//
-// Host DMA registers - base address 0x200 .  TX0-3=EDCAQid0-3, TX4=HCCA, TX5=MGMT,
-//
-//
-//  DMA RING DESCRIPTOR
-//
-#define E2PROM_CSR          0x0004
-#define IO_CNTL_CSR         0x77d0
-
-
-
-// ================================================================
-// Tx /	Rx / Mgmt ring descriptor definition
-// ================================================================
-
-// the following PID values are used to mark outgoing frame type in TXD->PID so that
-// proper TX statistics can be collected based on these categories
-// b3-2 of PID field -
-#define PID_MGMT			0x05
-#define PID_BEACON			0x0c
-#define PID_DATA_NORMALUCAST		0x02
-#define PID_DATA_AMPDU		0x04
-#define PID_DATA_NO_ACK		0x08
-#define PID_DATA_NOT_NORM_ACK		0x03
-// value domain of pTxD->HostQId (4-bit: 0~15)
-#define QID_AC_BK               1   // meet ACI definition in 802.11e
-#define QID_AC_BE               0   // meet ACI definition in 802.11e
-#define QID_AC_VI               2
-#define QID_AC_VO               3
-#define QID_HCCA                4
-//#define NUM_OF_TX_RING          5
-#define NUM_OF_TX_RING          4
-#define QID_MGMT                13
-#define QID_RX                  14
-#define QID_OTHER               15
-
-#endif // __RTMP_MAC_H__ //
diff --git a/drivers/staging/rt3090/rtmp_mcu.h b/drivers/staging/rt3090/rtmp_mcu.h
deleted file mode 100644
index e1b2fee..0000000
--- a/drivers/staging/rt3090/rtmp_mcu.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtmp_mcu.h
-
-	Abstract:
-	Miniport header file for mcu related information
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-*/
-
-#ifndef __RTMP_MCU_H__
-#define __RTMP_MCU_H__
-
-
-INT RtmpAsicEraseFirmware(
-	IN PRTMP_ADAPTER pAd);
-
-NDIS_STATUS RtmpAsicLoadFirmware(
-	IN PRTMP_ADAPTER pAd);
-
-INT RtmpAsicSendCommandToMcu(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR		 Command,
-	IN UCHAR		 Token,
-	IN UCHAR		 Arg0,
-	IN UCHAR		 Arg1);
-
-#endif // __RTMP_MCU_H__ //
diff --git a/drivers/staging/rt3090/rtmp_os.h b/drivers/staging/rt3090/rtmp_os.h
deleted file mode 100644
index 5646b2d..0000000
--- a/drivers/staging/rt3090/rtmp_os.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	rtmp_os.h
-
-    Abstract:
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
- */
-
-
-#ifndef __RTMP_OS_H__
-#define __RTMP_OS_H__
-
-#ifdef LINUX
-#include "rt_linux.h"
-#endif // LINUX //
-
-
-/*
-	This data structure mainly strip some callback function defined in
-	"struct net_device" in kernel source "include/linux/netdevice.h".
-
-	The definition of this data structure may various depends on different
-	OS. Use it carefully.
-*/
-typedef struct _RTMP_OS_NETDEV_OP_HOOK_
-{
-	const struct net_device_ops *netdev_ops;
-	void			*priv;
-	int			priv_flags;
-	unsigned char devAddr[6];
-	unsigned char	devName[16];
-	unsigned char	needProtcted;
-}RTMP_OS_NETDEV_OP_HOOK, *PRTMP_OS_NETDEV_OP_HOOK;
-
-
-typedef enum _RTMP_TASK_STATUS_
-{
-	RTMP_TASK_STAT_UNKNOWN = 0,
-	RTMP_TASK_STAT_INITED = 1,
-	RTMP_TASK_STAT_RUNNING = 2,
-	RTMP_TASK_STAT_STOPED = 4,
-}RTMP_TASK_STATUS;
-#define RTMP_TASK_CAN_DO_INSERT		(RTMP_TASK_STAT_INITED |RTMP_TASK_STAT_RUNNING)
-
-#define RTMP_OS_TASK_NAME_LEN	16
-typedef struct _RTMP_OS_TASK_
-{
-	char					taskName[RTMP_OS_TASK_NAME_LEN];
-	void					*priv;
-	//unsigned long		taskFlags;
-	RTMP_TASK_STATUS	taskStatus;
-#ifndef KTHREAD_SUPPORT
-	RTMP_OS_SEM			taskSema;
-	RTMP_OS_PID			taskPID;
-	struct completion		taskComplete;
-#endif
-	unsigned char			task_killed;
-#ifdef KTHREAD_SUPPORT
-	struct task_struct	*kthread_task;
-	wait_queue_head_t		kthread_q;
-	BOOLEAN					kthread_running;
-#endif
-}RTMP_OS_TASK;
-
-#endif // __RMTP_OS_H__ //
diff --git a/drivers/staging/rt3090/rtmp_pci.h b/drivers/staging/rt3090/rtmp_pci.h
deleted file mode 100644
index c2fed29..0000000
--- a/drivers/staging/rt3090/rtmp_pci.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-*/
-
-
-#ifndef __RTMP_PCI_H__
-#define __RTMP_PCI_H__
-
-#define RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p)				\
-	((POS_COOKIE)handle)->pci_dev = dev_p;
-
-
-#ifdef LINUX
-// set driver data
-#define RT28XX_DRVDATA_SET(_a)			pci_set_drvdata(_a, net_dev);
-
-#define RT28XX_PUT_DEVICE(dev_p)
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-#define SA_SHIRQ IRQF_SHARED
-#endif
-
-#ifdef PCI_MSI_SUPPORT
-#define RTMP_MSI_ENABLE(_pAd) \
-{	POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
-	(_pAd)->HaveMsi =	pci_enable_msi(_pObj->pci_dev) == 0 ? TRUE : FALSE; }
-
-#define RTMP_MSI_DISABLE(_pAd) \
-{	POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
-	if (_pAd->HaveMsi == TRUE) \
-		pci_disable_msi(_pObj->pci_dev); \
-	_pAd->HaveMsi = FALSE;	}
-#else
-#define RTMP_MSI_ENABLE(_pAd)
-#define RTMP_MSI_DISABLE(_pAd)
-#endif // PCI_MSI_SUPPORT //
-
-
-#define RTMP_PCI_DEV_UNMAP()										\
-{	if (net_dev->base_addr)	{								\
-		iounmap((void *)(net_dev->base_addr));				\
-		release_mem_region(pci_resource_start(dev_p, 0),	\
-							pci_resource_len(dev_p, 0)); }	\
-	if (net_dev->irq) pci_release_regions(dev_p); }
-
-
-#define RTMP_IRQ_REQUEST(net_dev)							\
-{	PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)(RTMP_OS_NETDEV_GET_PRIV(net_dev));	\
-	POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie);		\
-	RTMP_MSI_ENABLE(_pAd);									\
-	if ((retval = request_irq(_pObj->pci_dev->irq,		\
-							rt2860_interrupt, SA_SHIRQ,		\
-							(net_dev)->name, (net_dev)))) {	\
-		DBGPRINT(RT_DEBUG_ERROR, ("request_irq  error(%d)\n", retval));	\
-	return retval; } }
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#define RTMP_IRQ_RELEASE(net_dev)								\
-{	PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)(RTMP_OS_NETDEV_GET_PRIV(net_dev));		\
-	POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie);			\
-	synchronize_irq(_pObj->pci_dev->irq);						\
-	free_irq(_pObj->pci_dev->irq, (net_dev));					\
-	RTMP_MSI_DISABLE(_pAd); }
-#else
-#define RTMP_IRQ_RELEASE(net_dev)								\
-{	PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)(RTMP_OS_NETDEV_GET_PRIV(net_dev));		\
-	POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie);			\
-	free_irq(_pObj->pci_dev->irq, (net_dev));					\
-	RTMP_MSI_DISABLE(_pAd); }
-#endif
-
-#define PCI_REG_READ_WORD(pci_dev, offset, Configuration)   \
-    if (pci_read_config_word(pci_dev, offset, &reg16) == 0)     \
-        Configuration = le2cpu16(reg16);                        \
-    else                                                        \
-        Configuration = 0;
-
-#define PCI_REG_WIRTE_WORD(pci_dev, offset, Configuration)  \
-    reg16 = cpu2le16(Configuration);                        \
-    pci_write_config_word(pci_dev, offset, reg16);          \
-
-#endif // LINUX //
-
-
-
-
-#endif // __RTMP_PCI_H__ //
diff --git a/drivers/staging/rt3090/rtmp_phy.h b/drivers/staging/rt3090/rtmp_phy.h
deleted file mode 100644
index b9848ca..0000000
--- a/drivers/staging/rt3090/rtmp_phy.h
+++ /dev/null
@@ -1,631 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtmp_phy.h
-
-	Abstract:
-	Ralink Wireless Chip PHY(BBP/RF) related definition & structures
-
-	Revision History:
-	Who			When		  What
-	--------	----------	  ----------------------------------------------
-*/
-
-#ifndef __RTMP_PHY_H__
-#define __RTMP_PHY_H__
-
-
-/*
-	RF sections
-*/
-#define RF_R00			0
-#define RF_R01			1
-#define RF_R02			2
-#define RF_R03			3
-#define RF_R04			4
-#define RF_R05			5
-#define RF_R06			6
-#define RF_R07			7
-#define RF_R08			8
-#define RF_R09			9
-#define RF_R10			10
-#define RF_R11			11
-#define RF_R12			12
-#define RF_R13			13
-#define RF_R14			14
-#define RF_R15			15
-#define RF_R16			16
-#define RF_R17			17
-#define RF_R18			18
-#define RF_R19			19
-#define RF_R20			20
-#define RF_R21			21
-#define RF_R22			22
-#define RF_R23			23
-#define RF_R24			24
-#define RF_R25			25
-#define RF_R26			26
-#define RF_R27			27
-#define RF_R28			28
-#define RF_R29			29
-#define RF_R30			30
-#define RF_R31			31
-
-
-// value domain of pAd->RfIcType
-#define RFIC_2820                   1       // 2.4G 2T3R
-#define RFIC_2850                   2       // 2.4G/5G 2T3R
-#define RFIC_2720                   3       // 2.4G 1T2R
-#define RFIC_2750                   4       // 2.4G/5G 1T2R
-#define RFIC_3020                   5       // 2.4G 1T1R
-#define RFIC_2020                   6       // 2.4G B/G
-#define RFIC_3021                   7       // 2.4G 1T2R
-#define RFIC_3022                   8       // 2.4G 2T2R
-#define RFIC_3052                   9       // 2.4G/5G 2T2R
-
-/*
-	BBP sections
-*/
-#define BBP_R0			0  // version
-#define BBP_R1			1  // TSSI
-#define BBP_R2			2  // TX configure
-#define BBP_R3			3
-#define BBP_R4			4
-#define BBP_R5			5
-#define BBP_R6			6
-#define BBP_R14			14 // RX configure
-#define BBP_R16			16
-#define BBP_R17			17 // RX sensibility
-#define BBP_R18			18
-#define BBP_R21			21
-#define BBP_R22			22
-#define BBP_R24			24
-#define BBP_R25			25
-#define BBP_R26			26
-#define BBP_R27			27
-#define BBP_R31			31
-#define BBP_R49			49 //TSSI
-#define BBP_R50			50
-#define BBP_R51			51
-#define BBP_R52			52
-#define BBP_R55			55
-#define BBP_R62			62 // Rx SQ0 Threshold HIGH
-#define BBP_R63			63
-#define BBP_R64			64
-#define BBP_R65			65
-#define BBP_R66			66
-#define BBP_R67			67
-#define BBP_R68			68
-#define BBP_R69			69
-#define BBP_R70			70 // Rx AGC SQ CCK Xcorr threshold
-#define BBP_R73			73
-#define BBP_R75			75
-#define BBP_R77			77
-#define BBP_R78			78
-#define BBP_R79			79
-#define BBP_R80			80
-#define BBP_R81			81
-#define BBP_R82			82
-#define BBP_R83			83
-#define BBP_R84			84
-#define BBP_R86			86
-#define BBP_R91			91
-#define BBP_R92			92
-#define BBP_R94			94 // Tx Gain Control
-#define BBP_R103		103
-#define BBP_R105		105
-#define BBP_R106		106
-#define BBP_R113		113
-#define BBP_R114		114
-#define BBP_R115		115
-#define BBP_R116		116
-#define BBP_R117		117
-#define BBP_R118		118
-#define BBP_R119		119
-#define BBP_R120		120
-#define BBP_R121		121
-#define BBP_R122		122
-#define BBP_R123		123
-#ifdef RT30xx
-#define BBP_R138		138 // add by johnli, RF power sequence setup, ADC dynamic on/off control
-#endif // RT30xx //
-
-
-#define BBPR94_DEFAULT	0x06 // Add 1 value will gain 1db
-
-
-#ifdef MERGE_ARCH_TEAM
-	#define MAX_BBP_ID	200
-	#define MAX_BBP_MSG_SIZE	4096
-#else
-#ifdef RT30xx
-	// edit by johnli, RF power sequence setup, add BBP R138 for ADC dynamic on/off control
-	#define MAX_BBP_ID	138
-#endif // RT30xx //
-#ifndef RT30xx
-	#define MAX_BBP_ID	136
-#endif // RT30xx //
-	#define MAX_BBP_MSG_SIZE	2048
-#endif // MERGE_ARCH_TEAM //
-
-
-//
-// BBP & RF are using indirect access. Before write any value into it.
-// We have to make sure there is no outstanding command pending via checking busy bit.
-//
-#define MAX_BUSY_COUNT  100         // Number of retry before failing access BBP & RF indirect register
-
-//#define PHY_TR_SWITCH_TIME          5  // usec
-
-//#define BBP_R17_LOW_SENSIBILITY     0x50
-//#define BBP_R17_MID_SENSIBILITY     0x41
-//#define BBP_R17_DYNAMIC_UP_BOUND    0x40
-
-#define RSSI_FOR_VERY_LOW_SENSIBILITY   -35
-#define RSSI_FOR_LOW_SENSIBILITY		-58
-#define RSSI_FOR_MID_LOW_SENSIBILITY	-80
-#define RSSI_FOR_MID_SENSIBILITY		-90
-
-/*****************************************************************************
-	RF register Read/Write marco definition
- *****************************************************************************/
-#ifdef RTMP_MAC_PCI
-#define RTMP_RF_IO_WRITE32(_A, _V)                  \
-{											\
-	if ((_A)->bPCIclkOff == FALSE)	                \
-	{												\
-		PHY_CSR4_STRUC  _value;                          \
-		ULONG           _busyCnt = 0;                    \
-											\
-		do {                                            \
-			RTMP_IO_READ32((_A), RF_CSR_CFG0, &_value.word);  \
-			if (_value.field.Busy == IDLE)               \
-				break;                                  \
-			_busyCnt++;                                  \
-		}while (_busyCnt < MAX_BUSY_COUNT);			\
-		if(_busyCnt < MAX_BUSY_COUNT)                   \
-		{                                               \
-			RTMP_IO_WRITE32((_A), RF_CSR_CFG0, (_V));          \
-		}                                               \
-	}								\
-}
-#endif // RTMP_MAC_PCI //
-
-
-
-#ifdef RT30xx
-#define RTMP_RF_IO_READ8_BY_REG_ID(_A, _I, _pV)    RT30xxReadRFRegister(_A, _I, _pV)
-#define RTMP_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V)    RT30xxWriteRFRegister(_A, _I, _V)
-#endif // RT30xx //
-
-
-/*****************************************************************************
-	BBP register Read/Write marco definitions.
-	we read/write the bbp value by register's ID.
-	Generate PER to test BA
- *****************************************************************************/
-#ifdef RTMP_MAC_PCI
-/*
-	basic marco for BBP read operation.
-	_pAd: the data structure pointer of RTMP_ADAPTER
-	_bbpID : the bbp register ID
-	_pV: data pointer used to save the value of queried bbp register.
-	_bViaMCU: if we need access the bbp via the MCU.
-*/
-#define RTMP_BBP_IO_READ8(_pAd, _bbpID, _pV, _bViaMCU)			\
-	do{															\
-		BBP_CSR_CFG_STRUC  BbpCsr;								\
-		int   _busyCnt, _secCnt, _regID;						\
-																\
-		_regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG);	\
-		for (_busyCnt=0; _busyCnt<MAX_BUSY_COUNT; _busyCnt++)      \
-		{													\
-			RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word);		\
-			if (BbpCsr.field.Busy == BUSY)                  \
-				continue;                                               \
-			BbpCsr.word = 0;                                \
-			BbpCsr.field.fRead = 1;                         \
-			BbpCsr.field.BBP_RW_MODE = 1;                         \
-			BbpCsr.field.Busy = 1;                          \
-			BbpCsr.field.RegNum = _bbpID;                       \
-			RTMP_IO_WRITE32(_pAd, _regID, BbpCsr.word);     \
-			if ((_bViaMCU) == TRUE)							\
-			{													\
-				AsicSendCommandToMcu(_pAd, 0x80, 0xff, 0x0, 0x0); \
-				RTMPusecDelay(1000);	\
-			}							\
-			for (_secCnt=0; _secCnt<MAX_BUSY_COUNT; _secCnt++)       \
-			{                                               \
-				RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word); \
-				if (BbpCsr.field.Busy == IDLE)              \
-					break;                                  \
-			}                                               \
-			if ((BbpCsr.field.Busy == IDLE) &&              \
-				(BbpCsr.field.RegNum == _bbpID))                \
-			{                                               \
-				*(_pV) = (UCHAR)BbpCsr.field.Value;         \
-				break;                                      \
-			}                                               \
-		}                                                   \
-		if (BbpCsr.field.Busy == BUSY)                      \
-		{                                                   \
-			DBGPRINT_ERR(("BBP(viaMCU=%d) read R%d fail\n", (_bViaMCU), _bbpID));      \
-			*(_pV) = (_pAd)->BbpWriteLatch[_bbpID];               \
-			if ((_bViaMCU) == TRUE)				\
-			{									\
-				RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word);				\
-				BbpCsr.field.Busy = 0;                          \
-				RTMP_IO_WRITE32(_pAd, _regID, BbpCsr.word);				\
-			}				\
-		}													\
-	}while(0)
-
-/*
-	This marco used for the BBP read operation which didn't need via MCU.
-*/
-#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)			\
-	RTMP_BBP_IO_READ8((_A), (_I), (_pV), FALSE)
-
-/*
-	This marco used for the BBP read operation which need via MCU.
-	But for some chipset which didn't have mcu (e.g., RBUS based chipset), we
-	will use this function too and didn't access the bbp register via the MCU.
-*/
-#ifndef CONFIG_STA_SUPPORT
-#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)			\
-	do{														\
-		if ((_A)->bPCIclkOff == FALSE)							\
-		{													\
-			if ((_A)->infType == RTMP_DEV_INF_RBUS)			\
-				RTMP_BBP_IO_READ8((_A), (_I), (_pV), FALSE);	\
-			else												\
-				RTMP_BBP_IO_READ8((_A), (_I), (_pV), TRUE);	\
-		}													\
-	}while(0)
-#endif // CONFIG_STA_SUPPORT //
-#ifdef CONFIG_STA_SUPPORT
-// Read BBP register by register's ID. Generate PER to test BA
-#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)						\
-{																		\
-	BBP_CSR_CFG_STRUC	BbpCsr;											\
-	int					i, k;			\
-	BOOLEAN					brc;			\
-	BbpCsr.field.Busy = IDLE;			\
-	if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3)	\
-		&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE)	\
-		&& ((_A)->bPCIclkOff == FALSE)	\
-		&& ((_A)->brt30xxBanMcuCmd == FALSE))	\
-	{																	\
-		for (i=0; i<MAX_BUSY_COUNT; i++)									\
-		{																	\
-			RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);				\
-			if (BbpCsr.field.Busy == BUSY)									\
-			{																\
-				continue;													\
-			}																\
-			BbpCsr.word = 0;												\
-			BbpCsr.field.fRead = 1;											\
-			BbpCsr.field.BBP_RW_MODE = 1;									\
-			BbpCsr.field.Busy = 1;											\
-			BbpCsr.field.RegNum = _I;										\
-			RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
-			brc = AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0);					\
-			if (brc == TRUE)																\
-			{																\
-				for (k=0; k<MAX_BUSY_COUNT; k++)								\
-				{																\
-					RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);			\
-					if (BbpCsr.field.Busy == IDLE)								\
-						break;													\
-				}																\
-				if ((BbpCsr.field.Busy == IDLE) &&								\
-					(BbpCsr.field.RegNum == _I))								\
-				{																\
-					*(_pV) = (UCHAR)BbpCsr.field.Value;							\
-					break;														\
-				}																\
-			}																\
-			else																\
-			{																\
-				BbpCsr.field.Busy = 0;											\
-				RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
-			}																\
-		}																	\
-	}	\
-	else if (!((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3)	\
-		&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE))	\
-		&& ((_A)->bPCIclkOff == FALSE))	\
-	{																	\
-		for (i=0; i<MAX_BUSY_COUNT; i++)									\
-		{																	\
-			RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);				\
-			if (BbpCsr.field.Busy == BUSY)									\
-			{																\
-				continue;													\
-			}																\
-			BbpCsr.word = 0;												\
-			BbpCsr.field.fRead = 1;											\
-			BbpCsr.field.BBP_RW_MODE = 1;									\
-			BbpCsr.field.Busy = 1;											\
-			BbpCsr.field.RegNum = _I;										\
-			RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
-			AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0);					\
-			for (k=0; k<MAX_BUSY_COUNT; k++)								\
-			{																\
-				RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);			\
-				if (BbpCsr.field.Busy == IDLE)								\
-					break;													\
-			}																\
-			if ((BbpCsr.field.Busy == IDLE) &&								\
-				(BbpCsr.field.RegNum == _I))								\
-			{																\
-				*(_pV) = (UCHAR)BbpCsr.field.Value;							\
-				break;														\
-			}																\
-		}																	\
-	}																	\
-	else										\
-	{																	\
-		DBGPRINT_ERR((" , brt30xxBanMcuCmd = %d, Read BBP %d \n", (_A)->brt30xxBanMcuCmd, (_I)));	\
-		*(_pV) = (_A)->BbpWriteLatch[_I];								\
-	}																	\
-	if ((BbpCsr.field.Busy == BUSY) || ((_A)->bPCIclkOff == TRUE))										\
-	{																	\
-		DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", _I, BbpCsr.word));	\
-		*(_pV) = (_A)->BbpWriteLatch[_I];								\
-	}																	\
-}
-#endif // CONFIG_STA_SUPPORT //
-
-/*
-	basic marco for BBP write operation.
-	_pAd: the data structure pointer of RTMP_ADAPTER
-	_bbpID : the bbp register ID
-	_pV: data used to save the value of queried bbp register.
-	_bViaMCU: if we need access the bbp via the MCU.
-*/
-#define RTMP_BBP_IO_WRITE8(_pAd, _bbpID, _pV, _bViaMCU)			\
-	do{															\
-		BBP_CSR_CFG_STRUC  BbpCsr;                             \
-		int             _busyCnt, _regID;							\
-																\
-		_regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG);	\
-		for (_busyCnt=0; _busyCnt<MAX_BUSY_COUNT; _busyCnt++)  \
-		{                                                   \
-			RTMP_IO_READ32((_pAd), BBP_CSR_CFG, &BbpCsr.word);     \
-			if (BbpCsr.field.Busy == BUSY)                  \
-				continue;                                   \
-			BbpCsr.word = 0;                                \
-			BbpCsr.field.fRead = 0;                         \
-			BbpCsr.field.BBP_RW_MODE = 1;                         \
-			BbpCsr.field.Busy = 1;                          \
-			BbpCsr.field.Value = _pV;                        \
-			BbpCsr.field.RegNum = _bbpID;                       \
-			RTMP_IO_WRITE32((_pAd), BBP_CSR_CFG, BbpCsr.word);     \
-			if ((_bViaMCU) == TRUE)									\
-			{														\
-				AsicSendCommandToMcu(_pAd, 0x80, 0xff, 0x0, 0x0);		\
-				if ((_pAd)->OpMode == OPMODE_AP)						\
-					RTMPusecDelay(1000);							\
-			}														\
-			(_pAd)->BbpWriteLatch[_bbpID] = _pV;					\
-			break;													\
-		}														\
-		if (_busyCnt == MAX_BUSY_COUNT)								\
-		{														\
-			DBGPRINT_ERR(("BBP write R%d fail\n", _bbpID));				\
-			if((_bViaMCU) == TRUE)									\
-			{														\
-				RTMP_IO_READ32(_pAd, H2M_BBP_AGENT, &BbpCsr.word);	\
-				BbpCsr.field.Busy = 0;									\
-				RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, BbpCsr.word);	\
-			}														\
-		}														\
-	}while(0)
-
-
-/*
-	This marco used for the BBP write operation which didn't need via MCU.
-*/
-#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _pV)			\
-	RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), FALSE)
-
-/*
-	This marco used for the BBP write operation which need via MCU.
-	But for some chipset which didn't have mcu (e.g., RBUS based chipset), we
-	will use this function too and didn't access the bbp register via the MCU.
-*/
-#ifndef CONFIG_STA_SUPPORT
-#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _pV)			\
-	do{														\
-		if ((_A)->bPCIclkOff == FALSE)							\
-		{													\
-			if ((_A)->infType == RTMP_DEV_INF_RBUS)			\
-				RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), FALSE);	\
-			else												\
-				RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), TRUE);	\
-		}													\
-	}while(0)
-#endif // CONFIG_STA_SUPPORT //
-#ifdef CONFIG_STA_SUPPORT
-// Write BBP register by register's ID & value
-#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)						\
-{																		\
-	BBP_CSR_CFG_STRUC	BbpCsr;											\
-	INT					BusyCnt = 0;										\
-	BOOLEAN					brc;			\
-	if (_I < MAX_NUM_OF_BBP_LATCH)										\
-	{																	\
-		if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3)	\
-			&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE)	\
-			&& ((_A)->bPCIclkOff == FALSE)	\
-			&& ((_A)->brt30xxBanMcuCmd == FALSE))	\
-		{																	\
-			if (_A->AccessBBPFailCount > 20)									\
-			{																	\
-				AsicResetBBPAgent(_A);				\
-				_A->AccessBBPFailCount = 0;											\
-			}																	\
-			for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++)					\
-			{																	\
-				RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);				\
-				if (BbpCsr.field.Busy == BUSY)									\
-					continue;													\
-				BbpCsr.word = 0;												\
-				BbpCsr.field.fRead = 0;											\
-				BbpCsr.field.BBP_RW_MODE = 1;									\
-				BbpCsr.field.Busy = 1;											\
-				BbpCsr.field.Value = _V;										\
-				BbpCsr.field.RegNum = _I;										\
-				RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
-				brc = AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0);					\
-				if (brc == TRUE)																\
-				{																\
-					(_A)->BbpWriteLatch[_I] = _V;									\
-				}																\
-				else																\
-				{																\
-					BbpCsr.field.Busy = 0;											\
-					RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
-				}																\
-				break;															\
-			}																	\
-		}																	\
-		else if (!((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3)	\
-			&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE))	\
-			&& ((_A)->bPCIclkOff == FALSE))	\
-		{																	\
-			if (_A->AccessBBPFailCount > 20)									\
-			{																	\
-				AsicResetBBPAgent(_A);				\
-				_A->AccessBBPFailCount = 0;											\
-			}																	\
-			for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++)					\
-			{																	\
-				RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);				\
-				if (BbpCsr.field.Busy == BUSY)									\
-					continue;													\
-				BbpCsr.word = 0;												\
-				BbpCsr.field.fRead = 0;											\
-				BbpCsr.field.BBP_RW_MODE = 1;									\
-				BbpCsr.field.Busy = 1;											\
-				BbpCsr.field.Value = _V;										\
-				BbpCsr.field.RegNum = _I;										\
-				RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
-				AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0);					\
-				(_A)->BbpWriteLatch[_I] = _V;									\
-				break;															\
-			}																	\
-		}																	\
-		else										\
-		{																	\
-			DBGPRINT_ERR(("  brt30xxBanMcuCmd = %d. Write BBP %d \n",  (_A)->brt30xxBanMcuCmd, (_I)));	\
-		}																	\
-		if ((BusyCnt == MAX_BUSY_COUNT) || ((_A)->bPCIclkOff == TRUE))			\
-		{																	\
-			if (BusyCnt == MAX_BUSY_COUNT)					\
-				(_A)->AccessBBPFailCount++;					\
-			DBGPRINT_ERR(("BBP write R%d=0x%x fail. BusyCnt= %d.bPCIclkOff = %d. \n", _I, BbpCsr.word, BusyCnt, (_A)->bPCIclkOff ));	\
-		}																	\
-	}																		\
-	else																		\
-	{																		\
-		DBGPRINT_ERR(("****** BBP_Write_Latch Buffer exceeds max boundry ****** \n"));	\
-	}																		\
-}
-#endif // CONFIG_STA_SUPPORT //
-#endif // RTMP_MAC_PCI //
-
-
-
-#ifdef RT30xx
-//Need to collect each ant's rssi concurrently
-//rssi1 is report to pair2 Ant and rss2 is reprot to pair1 Ant when 4 Ant
-#define COLLECT_RX_ANTENNA_AVERAGE_RSSI(_pAd, _rssi1, _rssi2)					\
-{																				\
-	SHORT	AvgRssi;															\
-	UCHAR	UsedAnt;															\
-	if (_pAd->RxAnt.EvaluatePeriod == 0)									\
-	{																		\
-		UsedAnt = _pAd->RxAnt.Pair1PrimaryRxAnt;							\
-		AvgRssi = _pAd->RxAnt.Pair1AvgRssi[UsedAnt];						\
-		if (AvgRssi < 0)													\
-			AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi1;					\
-		else																\
-			AvgRssi = _rssi1 << 3;											\
-		_pAd->RxAnt.Pair1AvgRssi[UsedAnt] = AvgRssi;						\
-	}																		\
-	else																	\
-	{																		\
-		UsedAnt = _pAd->RxAnt.Pair1SecondaryRxAnt;							\
-		AvgRssi = _pAd->RxAnt.Pair1AvgRssi[UsedAnt];						\
-		if ((AvgRssi < 0) && (_pAd->RxAnt.FirstPktArrivedWhenEvaluate))		\
-			AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi1;					\
-		else																\
-		{																	\
-			_pAd->RxAnt.FirstPktArrivedWhenEvaluate = TRUE;					\
-			AvgRssi = _rssi1 << 3;											\
-		}																	\
-		_pAd->RxAnt.Pair1AvgRssi[UsedAnt] = AvgRssi;						\
-		_pAd->RxAnt.RcvPktNumWhenEvaluate++;								\
-	}																		\
-}
-
-#define RTMP_ASIC_MMPS_DISABLE(_pAd)							\
-	do{															\
-		UCHAR _bbpData;											\
-		UINT32 _macData;											\
-		/* disable MMPS BBP control register */						\
-		RTMP_BBP_IO_READ8_BY_REG_ID(_pAd, BBP_R3, &_bbpData);	\
-		_bbpData &= ~(0x04);	/*bit 2*/								\
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData);	\
-																\
-		/* disable MMPS MAC control register */						\
-		RTMP_IO_READ32(_pAd, 0x1210, &_macData);				\
-		_macData &= ~(0x09);	/*bit 0, 3*/							\
-		RTMP_IO_WRITE32(_pAd, 0x1210, _macData);				\
-	}while(0)
-
-
-#define RTMP_ASIC_MMPS_ENABLE(_pAd)							\
-	do{															\
-		UCHAR _bbpData;											\
-		UINT32 _macData;											\
-		/* enable MMPS BBP control register */						\
-		RTMP_BBP_IO_READ8_BY_REG_ID(_pAd, BBP_R3, &_bbpData);	\
-		_bbpData |= (0x04);	/*bit 2*/								\
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData);	\
-																\
-		/* enable MMPS MAC control register */						\
-		RTMP_IO_READ32(_pAd, 0x1210, &_macData);				\
-		_macData |= (0x09);	/*bit 0, 3*/							\
-		RTMP_IO_WRITE32(_pAd, 0x1210, _macData);				\
-	}while(0)
-
-#endif // RT30xx //
-
-#endif // __RTMP_PHY_H__ //
diff --git a/drivers/staging/rt3090/rtmp_timer.h b/drivers/staging/rt3090/rtmp_timer.h
deleted file mode 100644
index dfac124..0000000
--- a/drivers/staging/rt3090/rtmp_timer.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	rtmp_timer.h
-
-    Abstract:
-	Ralink Wireless Driver timer related data structures and delcarations
-
-    Revision History:
-	Who           When                What
-	--------    ----------      ----------------------------------------------
-	Name          Date                 Modification logs
-	Shiang Tu    Aug-28-2008	init version
-
-*/
-
-#ifndef __RTMP_TIMER_H__
-#define  __RTMP_TIMER_H__
-
-#include "rtmp_os.h"
-
-
-#define DECLARE_TIMER_FUNCTION(_func)			\
-	void rtmp_timer_##_func(unsigned long data)
-
-#define GET_TIMER_FUNCTION(_func)				\
-	rtmp_timer_##_func
-
-
-/* ----------------- Timer Related MARCO ---------------*/
-// In some os or chipset, we have a lot of timer functions and will read/write register,
-//   it's not allowed in Linux USB sub-system to do it ( because of sleep issue when
-//  submit to ctrl pipe). So we need a wrapper function to take care it.
-
-#ifdef RTMP_TIMER_TASK_SUPPORT
-typedef VOID (*RTMP_TIMER_TASK_HANDLE)(
-	IN  PVOID   SystemSpecific1,
-	IN  PVOID   FunctionContext,
-	IN  PVOID   SystemSpecific2,
-	IN  PVOID   SystemSpecific3);
-#endif // RTMP_TIMER_TASK_SUPPORT //
-
-typedef struct  _RALINK_TIMER_STRUCT    {
-	RTMP_OS_TIMER		TimerObj;       // Ndis Timer object
-	BOOLEAN				Valid;			// Set to True when call RTMPInitTimer
-	BOOLEAN				State;          // True if timer cancelled
-	BOOLEAN				PeriodicType;	// True if timer is periodic timer
-	BOOLEAN				Repeat;         // True if periodic timer
-	ULONG				TimerValue;     // Timer value in milliseconds
-	ULONG				cookie;			// os specific object
-#ifdef RTMP_TIMER_TASK_SUPPORT
-	RTMP_TIMER_TASK_HANDLE	handle;
-	void					*pAd;
-#endif // RTMP_TIMER_TASK_SUPPORT //
-}RALINK_TIMER_STRUCT, *PRALINK_TIMER_STRUCT;
-
-
-#ifdef RTMP_TIMER_TASK_SUPPORT
-typedef struct _RTMP_TIMER_TASK_ENTRY_
-{
-	RALINK_TIMER_STRUCT			*pRaTimer;
-	struct _RTMP_TIMER_TASK_ENTRY_	*pNext;
-}RTMP_TIMER_TASK_ENTRY;
-
-
-#define TIMER_QUEUE_SIZE_MAX	128
-typedef struct _RTMP_TIMER_TASK_QUEUE_
-{
-	unsigned int				status;
-	unsigned char				*pTimerQPoll;
-	RTMP_TIMER_TASK_ENTRY	*pQPollFreeList;
-	RTMP_TIMER_TASK_ENTRY	*pQHead;
-	RTMP_TIMER_TASK_ENTRY	*pQTail;
-}RTMP_TIMER_TASK_QUEUE;
-
-#define BUILD_TIMER_FUNCTION(_func)										\
-void rtmp_timer_##_func(unsigned long data)										\
-{																			\
-	PRALINK_TIMER_STRUCT	_pTimer = (PRALINK_TIMER_STRUCT)data;				\
-	RTMP_TIMER_TASK_ENTRY	*_pQNode;										\
-	RTMP_ADAPTER			*_pAd;											\
-																			\
-	_pTimer->handle = _func;													\
-	_pAd = (RTMP_ADAPTER *)_pTimer->pAd;										\
-	_pQNode = RtmpTimerQInsert(_pAd, _pTimer);								\
-	if ((_pQNode == NULL) && (_pAd->TimerQ.status & RTMP_TASK_CAN_DO_INSERT))	\
-		RTMP_OS_Add_Timer(&_pTimer->TimerObj, OS_HZ);							\
-}
-#else
-#define BUILD_TIMER_FUNCTION(_func)										\
-void rtmp_timer_##_func(unsigned long data)										\
-{																			\
-	PRALINK_TIMER_STRUCT	pTimer = (PRALINK_TIMER_STRUCT) data;				\
-																			\
-	_func(NULL, (PVOID) pTimer->cookie, NULL, pTimer);							\
-	if (pTimer->Repeat)														\
-		RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);			\
-}
-#endif // RTMP_TIMER_TASK_SUPPORT //
-
-
-DECLARE_TIMER_FUNCTION(MlmePeriodicExec);
-DECLARE_TIMER_FUNCTION(MlmeRssiReportExec);
-DECLARE_TIMER_FUNCTION(AsicRxAntEvalTimeout);
-DECLARE_TIMER_FUNCTION(APSDPeriodicExec);
-DECLARE_TIMER_FUNCTION(AsicRfTuningExec);
-
-
-#ifdef CONFIG_STA_SUPPORT
-DECLARE_TIMER_FUNCTION(BeaconTimeout);
-DECLARE_TIMER_FUNCTION(ScanTimeout);
-DECLARE_TIMER_FUNCTION(AuthTimeout);
-DECLARE_TIMER_FUNCTION(AssocTimeout);
-DECLARE_TIMER_FUNCTION(ReassocTimeout);
-DECLARE_TIMER_FUNCTION(DisassocTimeout);
-DECLARE_TIMER_FUNCTION(LinkDownExec);
-DECLARE_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
-DECLARE_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
-DECLARE_TIMER_FUNCTION(PsPollWakeExec);
-DECLARE_TIMER_FUNCTION(RadioOnExec);
-
-#ifdef QOS_DLS_SUPPORT
-DECLARE_TIMER_FUNCTION(DlsTimeoutAction);
-#endif // QOS_DLS_SUPPORT //
-
-
-#endif // CONFIG_STA_SUPPORT //
-
-
-
-
-#if defined(AP_LED) || defined(STA_LED)
-DECLARE_TIMER_FUNCTION(LedCtrlMain);
-#endif
-
-
-
-#endif // __RTMP_TIMER_H__ //
diff --git a/drivers/staging/rt3090/rtmp_type.h b/drivers/staging/rt3090/rtmp_type.h
deleted file mode 100644
index d8b571e..0000000
--- a/drivers/staging/rt3090/rtmp_type.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    rtmp_type.h
-
-    Abstract:
-
-    Revision History:
-    Who         When            What
-    --------    ----------      ----------------------------------------------
-    Name        Date            Modification logs
-    Paul Lin    1-2-2004
-*/
-
-#ifndef __RTMP_TYPE_H__
-#define __RTMP_TYPE_H__
-
-
-#define PACKED  __attribute__ ((packed))
-
-#ifdef LINUX
-// Put platform dependent declaration here
-// For example, linux type definition
-typedef unsigned char			UINT8;
-typedef unsigned short			UINT16;
-typedef unsigned int			UINT32;
-typedef unsigned long long		UINT64;
-typedef int					INT32;
-typedef long long				INT64;
-#endif // LINUX //
-
-typedef unsigned char *		PUINT8;
-typedef unsigned short *		PUINT16;
-typedef unsigned int *			PUINT32;
-typedef unsigned long long *	PUINT64;
-typedef int	*				PINT32;
-typedef long long *			PINT64;
-
-// modified for fixing compile warning on Sigma 8634 platform
-typedef char					STRING;
-typedef signed char			CHAR;
-
-typedef signed short			SHORT;
-typedef signed int				INT;
-typedef signed long			LONG;
-typedef signed long long		LONGLONG;
-
-
-#ifdef LINUX
-typedef unsigned char			UCHAR;
-typedef unsigned short			USHORT;
-typedef unsigned int			UINT;
-typedef unsigned long			ULONG;
-#endif // LINUX //
-typedef unsigned long long		ULONGLONG;
-
-typedef unsigned char			BOOLEAN;
-#ifdef LINUX
-typedef void					VOID;
-#endif // LINUX //
-
-typedef char *				PSTRING;
-typedef VOID *				PVOID;
-typedef CHAR *				PCHAR;
-typedef UCHAR *					PUCHAR;
-typedef USHORT *			PUSHORT;
-typedef LONG *				PLONG;
-typedef ULONG *				PULONG;
-typedef UINT *				PUINT;
-
-typedef unsigned int			NDIS_MEDIA_STATE;
-
-typedef union _LARGE_INTEGER {
-    struct {
-        UINT LowPart;
-        INT32 HighPart;
-    } u;
-    INT64 QuadPart;
-} LARGE_INTEGER;
-
-
-//
-// Register set pair for initialzation register set definition
-//
-typedef struct  _RTMP_REG_PAIR
-{
-	ULONG   Register;
-	ULONG   Value;
-} RTMP_REG_PAIR, *PRTMP_REG_PAIR;
-
-typedef struct  _REG_PAIR
-{
-	UCHAR   Register;
-	UCHAR   Value;
-} REG_PAIR, *PREG_PAIR;
-
-//
-// Register set pair for initialzation register set definition
-//
-typedef struct  _RTMP_RF_REGS
-{
-	UCHAR   Channel;
-	ULONG   R1;
-	ULONG   R2;
-	ULONG   R3;
-	ULONG   R4;
-} RTMP_RF_REGS, *PRTMP_RF_REGS;
-
-typedef struct _FREQUENCY_ITEM {
-	UCHAR	Channel;
-	UCHAR	N;
-	UCHAR	R;
-	UCHAR	K;
-} FREQUENCY_ITEM, *PFREQUENCY_ITEM;
-
-
-typedef int				NTSTATUS;
-
-
-#define STATUS_SUCCESS				0x00
-#define STATUS_UNSUCCESSFUL		0x01
-
-#endif  // __RTMP_TYPE_H__ //
diff --git a/drivers/staging/rt3090/spectrum.h b/drivers/staging/rt3090/spectrum.h
deleted file mode 100644
index be9bae5..0000000
--- a/drivers/staging/rt3090/spectrum.h
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
- */
-
-#ifndef __SPECTRUM_H__
-#define __SPECTRUM_H__
-
-#include "rtmp_type.h"
-#include "spectrum_def.h"
-
-
-CHAR RTMP_GetTxPwr(
-	IN PRTMP_ADAPTER pAd,
-	IN HTTRANSMIT_SETTING HTTxMode);
-
-/*
-	==========================================================================
-	Description:
-		Prepare Measurement request action frame and enqueue it into
-		management queue waiting for transmition.
-
-	Parametrs:
-		1. the destination mac address of the frame.
-
-	Return	: None.
-	==========================================================================
- */
-VOID MakeMeasurementReqFrame(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pOutBuffer,
-	OUT PULONG pFrameLen,
-	IN UINT8 TotalLen,
-	IN UINT8 Category,
-	IN UINT8 Action,
-	IN UINT8 MeasureToken,
-	IN UINT8 MeasureReqMode,
-	IN UINT8 MeasureReqType,
-	IN UINT8 NumOfRepetitions);
-
-/*
-	==========================================================================
-	Description:
-		Prepare Measurement report action frame and enqueue it into
-		management queue waiting for transmition.
-
-	Parametrs:
-		1. the destination mac address of the frame.
-
-	Return	: None.
-	==========================================================================
- */
-VOID EnqueueMeasurementRep(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDA,
-	IN UINT8 DialogToken,
-	IN UINT8 MeasureToken,
-	IN UINT8 MeasureReqMode,
-	IN UINT8 MeasureReqType,
-	IN UINT8 ReportInfoLen,
-	IN PUINT8 pReportInfo);
-
-/*
-	==========================================================================
-	Description:
-		Prepare TPC Request action frame and enqueue it into
-		management queue waiting for transmition.
-
-	Parametrs:
-		1. the destination mac address of the frame.
-
-	Return	: None.
-	==========================================================================
- */
-VOID EnqueueTPCReq(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDA,
-	IN UCHAR DialogToken);
-
-/*
-	==========================================================================
-	Description:
-		Prepare TPC Report action frame and enqueue it into
-		management queue waiting for transmition.
-
-	Parametrs:
-		1. the destination mac address of the frame.
-
-	Return	: None.
-	==========================================================================
- */
-VOID EnqueueTPCRep(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDA,
-	IN UINT8 DialogToken,
-	IN UINT8 TxPwr,
-	IN UINT8 LinkMargin);
-
-/*
-	==========================================================================
-	Description:
-		Prepare Channel Switch Announcement action frame and enqueue it into
-		management queue waiting for transmition.
-
-	Parametrs:
-		1. the destination mac address of the frame.
-		2. Channel switch announcement mode.
-		2. a New selected channel.
-
-	Return	: None.
-	==========================================================================
- */
-VOID EnqueueChSwAnn(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDA,
-	IN UINT8 ChSwMode,
-	IN UINT8 NewCh);
-
-/*
-	==========================================================================
-	Description:
-		Spectrun action frames Handler such as channel switch annoucement,
-		measurement report, measurement request actions frames.
-
-	Parametrs:
-		Elme - MLME message containing the received frame
-
-	Return	: None.
-	==========================================================================
- */
-VOID PeerSpectrumAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem);
-
-/*
-	==========================================================================
-	Description:
-
-	Parametrs:
-
-	Return	: None.
-	==========================================================================
- */
-INT Set_MeasureReq_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT Set_TpcReq_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT Set_PwrConstraint(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-
-VOID MeasureReqTabInit(
-	IN PRTMP_ADAPTER pAd);
-
-VOID MeasureReqTabExit(
-	IN PRTMP_ADAPTER pAd);
-
-PMEASURE_REQ_ENTRY MeasureReqLookUp(
-	IN PRTMP_ADAPTER	pAd,
-	IN UINT8			DialogToken);
-
-PMEASURE_REQ_ENTRY MeasureReqInsert(
-	IN PRTMP_ADAPTER	pAd,
-	IN UINT8			DialogToken);
-
-VOID MeasureReqDelete(
-	IN PRTMP_ADAPTER	pAd,
-	IN UINT8			DialogToken);
-
-VOID InsertChannelRepIE(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pFrameBuf,
-	OUT PULONG pFrameLen,
-	IN PSTRING pCountry,
-	IN UINT8 RegulatoryClass);
-
-VOID InsertTpcReportIE(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pFrameBuf,
-	OUT PULONG pFrameLen,
-	IN UINT8 TxPwr,
-	IN UINT8 LinkMargin);
-
-VOID InsertDialogToken(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pFrameBuf,
-	OUT PULONG pFrameLen,
-	IN UINT8 DialogToken);
-
-VOID TpcReqTabInit(
-	IN PRTMP_ADAPTER pAd);
-
-VOID TpcReqTabExit(
-	IN PRTMP_ADAPTER pAd);
-
-VOID NotifyChSwAnnToPeerAPs(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pRA,
-	IN PUCHAR pTA,
-	IN UINT8 ChSwMode,
-	IN UINT8 Channel);
-
-VOID RguClass_BuildBcnChList(
-	IN PRTMP_ADAPTER pAd,
-	OUT PUCHAR pBuf,
-	OUT	PULONG pBufLen);
-#endif // __SPECTRUM_H__ //
diff --git a/drivers/staging/rt3090/spectrum_def.h b/drivers/staging/rt3090/spectrum_def.h
deleted file mode 100644
index 0389b09..0000000
--- a/drivers/staging/rt3090/spectrum_def.h
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	spectrum_def.h
-
-    Abstract:
-    Handle association related requests either from WSTA or from local MLME
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
-	Fonchi Wu    2008		   created for 802.11h
- */
-
-#ifndef __SPECTRUM_DEF_H__
-#define __SPECTRUM_DEF_H__
-
-
-#define MAX_MEASURE_REQ_TAB_SIZE		32
-#define MAX_HASH_MEASURE_REQ_TAB_SIZE	MAX_MEASURE_REQ_TAB_SIZE
-
-#define MAX_TPC_REQ_TAB_SIZE			32
-#define MAX_HASH_TPC_REQ_TAB_SIZE		MAX_TPC_REQ_TAB_SIZE
-
-#define MIN_RCV_PWR				100		/* Negative value ((dBm) */
-
-#define TPC_REQ_AGE_OUT			500		/* ms */
-#define MQ_REQ_AGE_OUT			500		/* ms */
-
-#define TPC_DIALOGTOKEN_HASH_INDEX(_DialogToken)	((_DialogToken) % MAX_HASH_TPC_REQ_TAB_SIZE)
-#define MQ_DIALOGTOKEN_HASH_INDEX(_DialogToken)		((_DialogToken) % MAX_MEASURE_REQ_TAB_SIZE)
-
-typedef struct _MEASURE_REQ_ENTRY
-{
-	struct _MEASURE_REQ_ENTRY *pNext;
-	ULONG lastTime;
-	BOOLEAN	Valid;
-	UINT8 DialogToken;
-	UINT8 MeasureDialogToken[3];	// 0:basic measure, 1: CCA measure, 2: RPI_Histogram measure.
-} MEASURE_REQ_ENTRY, *PMEASURE_REQ_ENTRY;
-
-typedef struct _MEASURE_REQ_TAB
-{
-	UCHAR Size;
-	PMEASURE_REQ_ENTRY Hash[MAX_HASH_MEASURE_REQ_TAB_SIZE];
-	MEASURE_REQ_ENTRY Content[MAX_MEASURE_REQ_TAB_SIZE];
-} MEASURE_REQ_TAB, *PMEASURE_REQ_TAB;
-
-typedef struct _TPC_REQ_ENTRY
-{
-	struct _TPC_REQ_ENTRY *pNext;
-	ULONG lastTime;
-	BOOLEAN Valid;
-	UINT8 DialogToken;
-} TPC_REQ_ENTRY, *PTPC_REQ_ENTRY;
-
-typedef struct _TPC_REQ_TAB
-{
-	UCHAR Size;
-	PTPC_REQ_ENTRY Hash[MAX_HASH_TPC_REQ_TAB_SIZE];
-	TPC_REQ_ENTRY Content[MAX_TPC_REQ_TAB_SIZE];
-} TPC_REQ_TAB, *PTPC_REQ_TAB;
-
-
-/* The regulatory information */
-typedef struct _DOT11_CHANNEL_SET
-{
-	UCHAR NumberOfChannels;
-	UINT8 MaxTxPwr;
-	UCHAR ChannelList[16];
-} DOT11_CHANNEL_SET, *PDOT11_CHANNEL_SET;
-
-typedef struct _DOT11_REGULATORY_INFORMATION
-{
-	UCHAR RegulatoryClass;
-	DOT11_CHANNEL_SET ChannelSet;
-} DOT11_REGULATORY_INFORMATION, *PDOT11_REGULATORY_INFORMATION;
-
-
-
-#define RM_TPC_REQ				0
-#define RM_MEASURE_REQ			1
-
-#define RM_BASIC				0
-#define RM_CCA					1
-#define RM_RPI_HISTOGRAM		2
-#define RM_CH_LOAD				3
-#define RM_NOISE_HISTOGRAM		4
-
-
-typedef struct PACKED _TPC_REPORT_INFO
-{
-	UINT8 TxPwr;
-	UINT8 LinkMargin;
-} TPC_REPORT_INFO, *PTPC_REPORT_INFO;
-
-typedef struct PACKED _CH_SW_ANN_INFO
-{
-	UINT8 ChSwMode;
-	UINT8 Channel;
-	UINT8 ChSwCnt;
-} CH_SW_ANN_INFO, *PCH_SW_ANN_INFO;
-
-typedef union PACKED _MEASURE_REQ_MODE
-{
-#ifdef RT_BIG_ENDIAN
-	struct PACKED
-	{
-
-		UINT8 :3;
-		UINT8 DurationMandatory:1;
-		UINT8 Report:1;
-		UINT8 Request:1;
-		UINT8 Enable:1;
-		UINT8 Parallel:1;
-	} field;
-#else
-	struct PACKED
-	{
-		UINT8 Parallel:1;
-		UINT8 Enable:1;
-		UINT8 Request:1;
-		UINT8 Report:1;
-		UINT8 DurationMandatory:1;
-		UINT8 :3;
-	} field;
-#endif // RT_BIG_ENDIAN //
-	UINT8 word;
-} MEASURE_REQ_MODE, *PMEASURE_REQ_MODE;
-
-typedef struct PACKED _MEASURE_REQ
-{
-	UINT8 ChNum;
-	UINT64 MeasureStartTime;
-	UINT16 MeasureDuration;
-} MEASURE_REQ, *PMEASURE_REQ;
-
-typedef struct PACKED _MEASURE_REQ_INFO
-{
-	UINT8 Token;
-	MEASURE_REQ_MODE ReqMode;
-	UINT8 ReqType;
-	UINT8 Oct[0];
-} MEASURE_REQ_INFO, *PMEASURE_REQ_INFO;
-
-typedef union PACKED _MEASURE_BASIC_REPORT_MAP
-{
-#ifdef RT_BIG_ENDIAN
-	struct PACKED
-	{
-		UINT8 Rev:3;
-
-		UINT8 Unmeasure:1;
-		UINT8 Radar:1;
-		UINT8 UnidentifiedSignal:1;
-		UINT8 OfdmPreamble:1;
-		UINT8 BSS:1;
-	} field;
-#else
-	struct PACKED
-	{
-		UINT8 BSS:1;
-
-		UINT8 OfdmPreamble:1;
-		UINT8 UnidentifiedSignal:1;
-		UINT8 Radar:1;
-		UINT8 Unmeasure:1;
-		UINT8 Rev:3;
-	} field;
-#endif // RT_BIG_ENDIAN //
-	UINT8 word;
-} MEASURE_BASIC_REPORT_MAP, *PMEASURE_BASIC_REPORT_MAP;
-
-typedef struct PACKED _MEASURE_BASIC_REPORT
-{
-	UINT8 ChNum;
-	UINT64 MeasureStartTime;
-	UINT16 MeasureDuration;
-	MEASURE_BASIC_REPORT_MAP Map;
-} MEASURE_BASIC_REPORT, *PMEASURE_BASIC_REPORT;
-
-typedef struct PACKED _MEASURE_CCA_REPORT
-{
-	UINT8 ChNum;
-	UINT64 MeasureStartTime;
-	UINT16 MeasureDuration;
-	UINT8 CCA_Busy_Fraction;
-} MEASURE_CCA_REPORT, *PMEASURE_CCA_REPORT;
-
-typedef struct PACKED _MEASURE_RPI_REPORT
-{
-	UINT8 ChNum;
-	UINT64 MeasureStartTime;
-	UINT16 MeasureDuration;
-	UINT8 RPI_Density[8];
-} MEASURE_RPI_REPORT, *PMEASURE_RPI_REPORT;
-
-typedef union PACKED _MEASURE_REPORT_MODE
-{
-	struct PACKED
-	{
-#ifdef RT_BIG_ENDIAN
-		UINT8 Rev:5;
-		UINT8 Refused:1;
-		UINT8 Incapable:1;
-		UINT8 Late:1;
-#else
-		UINT8 Late:1;
-		UINT8 Incapable:1;
-		UINT8 Refused:1;
-		UINT8 Rev:5;
-#endif // RT_BIG_ENDIAN //
-	} field;
-	UINT8 word;
-} MEASURE_REPORT_MODE, *PMEASURE_REPORT_MODE;
-
-typedef struct PACKED _MEASURE_REPORT_INFO
-{
-	UINT8 Token;
-	UINT8 ReportMode;
-	UINT8 ReportType;
-	UINT8 Octect[0];
-} MEASURE_REPORT_INFO, *PMEASURE_REPORT_INFO;
-
-typedef struct PACKED _QUIET_INFO
-{
-	UINT8 QuietCnt;
-	UINT8 QuietPeriod;
-	UINT16 QuietDuration;
-	UINT16 QuietOffset;
-} QUIET_INFO, *PQUIET_INFO;
-
-#endif // __SPECTRUM_DEF_H__ //
diff --git a/drivers/staging/rt3090/sta/assoc.c b/drivers/staging/rt3090/sta/assoc.c
deleted file mode 100644
index 012ed2b..0000000
--- a/drivers/staging/rt3090/sta/assoc.c
+++ /dev/null
@@ -1,1673 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	assoc.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	John		2004-9-3		porting from RT2500
-*/
-
-#include "../rt_config.h"
-
-
-UCHAR	CipherWpaTemplate[] = {
-		0xdd,					// WPA IE
-		0x16,					// Length
-		0x00, 0x50, 0xf2, 0x01,	// oui
-		0x01, 0x00,				// Version
-		0x00, 0x50, 0xf2, 0x02,	// Multicast
-		0x01, 0x00,				// Number of unicast
-		0x00, 0x50, 0xf2, 0x02,	// unicast
-		0x01, 0x00,				// number of authentication method
-		0x00, 0x50, 0xf2, 0x01	// authentication
-		};
-
-UCHAR	CipherWpa2Template[] = {
-		0x30,					// RSN IE
-		0x14,					// Length
-		0x01, 0x00,				// Version
-		0x00, 0x0f, 0xac, 0x02,	// group cipher, TKIP
-		0x01, 0x00,				// number of pairwise
-		0x00, 0x0f, 0xac, 0x02,	// unicast
-		0x01, 0x00,				// number of authentication method
-		0x00, 0x0f, 0xac, 0x02,	// authentication
-		0x00, 0x00,				// RSN capability
-		};
-
-UCHAR	Ccx2IeInfo[] = { 0x00, 0x40, 0x96, 0x03, 0x02};
-
-/*
-	==========================================================================
-	Description:
-		association state machine init, including state transition and timer init
-	Parameters:
-		S - pointer to the association state machine
-
-	IRQL = PASSIVE_LEVEL
-
-	==========================================================================
- */
-VOID AssocStateMachineInit(
-	IN	PRTMP_ADAPTER	pAd,
-	IN  STATE_MACHINE *S,
-	OUT STATE_MACHINE_FUNC Trans[])
-{
-	StateMachineInit(S, Trans, MAX_ASSOC_STATE, MAX_ASSOC_MSG, (STATE_MACHINE_FUNC)Drop, ASSOC_IDLE, ASSOC_MACHINE_BASE);
-
-	// first column
-	StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)MlmeAssocReqAction);
-	StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)MlmeReassocReqAction);
-	StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)MlmeDisassocReqAction);
-	StateMachineSetAction(S, ASSOC_IDLE, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
-
-	// second column
-	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
-	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
-	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
-	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
-	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP, (STATE_MACHINE_FUNC)PeerAssocRspAction);
-	//
-	// Patch 3Com AP MOde:3CRWE454G72
-	// We send Assoc request frame to this AP, it always send Reassoc Rsp not Associate Rsp.
-	//
-	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP, (STATE_MACHINE_FUNC)PeerAssocRspAction);
-	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_ASSOC_TIMEOUT, (STATE_MACHINE_FUNC)AssocTimeoutAction);
-
-	// third column
-	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
-	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
-	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
-	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
-	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP, (STATE_MACHINE_FUNC)PeerReassocRspAction);
-	//
-	// Patch, AP doesn't send Reassociate Rsp frame to Station.
-	//
-	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP, (STATE_MACHINE_FUNC)PeerReassocRspAction);
-	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_REASSOC_TIMEOUT, (STATE_MACHINE_FUNC)ReassocTimeoutAction);
-
-	// fourth column
-	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
-	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
-	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
-	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
-	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_DISASSOC_TIMEOUT, (STATE_MACHINE_FUNC)DisassocTimeoutAction);
-
-	// initialize the timer
-	RTMPInitTimer(pAd, &pAd->MlmeAux.AssocTimer, GET_TIMER_FUNCTION(AssocTimeout), pAd, FALSE);
-	RTMPInitTimer(pAd, &pAd->MlmeAux.ReassocTimer, GET_TIMER_FUNCTION(ReassocTimeout), pAd, FALSE);
-	RTMPInitTimer(pAd, &pAd->MlmeAux.DisassocTimer, GET_TIMER_FUNCTION(DisassocTimeout), pAd, FALSE);
-}
-
-/*
-	==========================================================================
-	Description:
-		Association timeout procedure. After association timeout, this function
-		will be called and it will put a message into the MLME queue
-	Parameters:
-		Standard timer parameters
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AssocTimeout(IN PVOID SystemSpecific1,
-				 IN PVOID FunctionContext,
-				 IN PVOID SystemSpecific2,
-				 IN PVOID SystemSpecific3)
-{
-	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-	MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_ASSOC_TIMEOUT, 0, NULL);
-	RTMP_MLME_HANDLER(pAd);
-}
-
-/*
-	==========================================================================
-	Description:
-		Reassociation timeout procedure. After reassociation timeout, this
-		function will be called and put a message into the MLME queue
-	Parameters:
-		Standard timer parameters
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID ReassocTimeout(IN PVOID SystemSpecific1,
-					IN PVOID FunctionContext,
-					IN PVOID SystemSpecific2,
-					IN PVOID SystemSpecific3)
-{
-	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-	MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_REASSOC_TIMEOUT, 0, NULL);
-	RTMP_MLME_HANDLER(pAd);
-}
-
-/*
-	==========================================================================
-	Description:
-		Disassociation timeout procedure. After disassociation timeout, this
-		function will be called and put a message into the MLME queue
-	Parameters:
-		Standard timer parameters
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID DisassocTimeout(IN PVOID SystemSpecific1,
-					IN PVOID FunctionContext,
-					IN PVOID SystemSpecific2,
-					IN PVOID SystemSpecific3)
-{
-	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-	MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_DISASSOC_TIMEOUT, 0, NULL);
-	RTMP_MLME_HANDLER(pAd);
-}
-
-/*
-	==========================================================================
-	Description:
-		mlme assoc req handling procedure
-	Parameters:
-		Adapter - Adapter pointer
-		Elem - MLME Queue Element
-	Pre:
-		the station has been authenticated and the following information is stored in the config
-			-# SSID
-			-# supported rates and their length
-			-# listen interval (Adapter->StaCfg.default_listen_count)
-			-# Transmit power  (Adapter->StaCfg.tx_power)
-	Post  :
-		-# An association request frame is generated and sent to the air
-		-# Association timer starts
-		-# Association state -> ASSOC_WAIT_RSP
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID MlmeAssocReqAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	UCHAR			ApAddr[6];
-	HEADER_802_11	AssocHdr;
-	UCHAR			WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
-	USHORT			ListenIntv;
-	ULONG			Timeout;
-	USHORT			CapabilityInfo;
-	BOOLEAN			TimerCancelled;
-	PUCHAR			pOutBuffer = NULL;
-	NDIS_STATUS		NStatus;
-	ULONG			FrameLen = 0;
-	ULONG			tmp;
-	USHORT			VarIesOffset;
-	USHORT			Status;
-
-	// Block all authentication request durning WPA block period
-	if (pAd->StaCfg.bBlockAssoc == TRUE)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Block Assoc request durning WPA block period!\n"));
-		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-		Status = MLME_STATE_MACHINE_REJECT;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
-	}
-	// check sanity first
-	else if (MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, &Timeout, &ListenIntv))
-	{
-		RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &TimerCancelled);
-		COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr);
-
-		// Get an unused nonpaged memory
-		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
-		if (NStatus != NDIS_STATUS_SUCCESS)
-		{
-			DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeAssocReqAction() allocate memory failed \n"));
-			pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-			Status = MLME_FAIL_NO_RESOURCE;
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
-			return;
-		}
-
-		// Add by James 03/06/27
-		pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
-		// Association don't need to report MAC address
-		pAd->StaCfg.AssocInfo.AvailableRequestFixedIEs =
-			NDIS_802_11_AI_REQFI_CAPABILITIES | NDIS_802_11_AI_REQFI_LISTENINTERVAL;
-		pAd->StaCfg.AssocInfo.RequestFixedIEs.Capabilities = CapabilityInfo;
-		pAd->StaCfg.AssocInfo.RequestFixedIEs.ListenInterval = ListenIntv;
-		// Only reassociate need this
-		//COPY_MAC_ADDR(pAd->StaCfg.AssocInfo.RequestFixedIEs.CurrentAPAddress, ApAddr);
-		pAd->StaCfg.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
-
-        NdisZeroMemory(pAd->StaCfg.ReqVarIEs, MAX_VIE_LEN);
-		// First add SSID
-		VarIesOffset = 0;
-		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SsidIe, 1);
-		VarIesOffset += 1;
-		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->MlmeAux.SsidLen, 1);
-		VarIesOffset += 1;
-		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
-		VarIesOffset += pAd->MlmeAux.SsidLen;
-
-		// Second add Supported rates
-		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SupRateIe, 1);
-		VarIesOffset += 1;
-		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->MlmeAux.SupRateLen, 1);
-		VarIesOffset += 1;
-		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->MlmeAux.SupRate, pAd->MlmeAux.SupRateLen);
-		VarIesOffset += pAd->MlmeAux.SupRateLen;
-		// End Add by James
-
-        if ((pAd->CommonCfg.Channel > 14) &&
-            (pAd->CommonCfg.bIEEE80211H == TRUE))
-            CapabilityInfo |= 0x0100;
-
-		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send ASSOC request...\n"));
-		MgtMacHeaderInit(pAd, &AssocHdr, SUBTYPE_ASSOC_REQ, 0, ApAddr, ApAddr);
-
-		// Build basic frame first
-		MakeOutgoingFrame(pOutBuffer,				&FrameLen,
-						  sizeof(HEADER_802_11),	&AssocHdr,
-						  2,						&CapabilityInfo,
-						  2,						&ListenIntv,
-						  1,						&SsidIe,
-						  1,						&pAd->MlmeAux.SsidLen,
-						  pAd->MlmeAux.SsidLen,		pAd->MlmeAux.Ssid,
-						  1,						&SupRateIe,
-						  1,						&pAd->MlmeAux.SupRateLen,
-						  pAd->MlmeAux.SupRateLen,  pAd->MlmeAux.SupRate,
-						  END_OF_ARGS);
-
-		if (pAd->MlmeAux.ExtRateLen != 0)
-		{
-			MakeOutgoingFrame(pOutBuffer + FrameLen,    &tmp,
-							  1,                        &ExtRateIe,
-							  1,                        &pAd->MlmeAux.ExtRateLen,
-							  pAd->MlmeAux.ExtRateLen,  pAd->MlmeAux.ExtRate,
-							  END_OF_ARGS);
-			FrameLen += tmp;
-		}
-
-
-#ifdef DOT11_N_SUPPORT
-		// HT
-		if ((pAd->MlmeAux.HtCapabilityLen > 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
-		{
-			ULONG TmpLen;
-			UCHAR HtLen;
-			UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
-			if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE)
-			{
-				HtLen = SIZE_HT_CAP_IE + 4;
-				MakeOutgoingFrame(pOutBuffer + FrameLen,            &TmpLen,
-							  1,                                &WpaIe,
-							  1,                                &HtLen,
-							  4,                                &BROADCOM[0],
-							 pAd->MlmeAux.HtCapabilityLen,          &pAd->MlmeAux.HtCapability,
-							  END_OF_ARGS);
-			}
-			else
-			{
-#ifdef RT_BIG_ENDIAN
-		        HT_CAPABILITY_IE HtCapabilityTmp;
-#endif
-
-#ifndef RT_BIG_ENDIAN
-				MakeOutgoingFrame(pOutBuffer + FrameLen,            &TmpLen,
-							  1,                                &HtCapIe,
-							  1,                                &pAd->MlmeAux.HtCapabilityLen,
-							 pAd->MlmeAux.HtCapabilityLen,          &pAd->MlmeAux.HtCapability,
-							  END_OF_ARGS);
-#else
-                NdisZeroMemory(&HtCapabilityTmp, sizeof(HT_CAPABILITY_IE));
-                NdisMoveMemory(&HtCapabilityTmp, &pAd->MlmeAux.HtCapability, pAd->MlmeAux.HtCapabilityLen);
-			*(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
-			*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
-
-			MakeOutgoingFrame(pOutBuffer + FrameLen,         &TmpLen,
-								1,                           &HtCapIe,
-								1,                           &pAd->MlmeAux.HtCapabilityLen,
-								pAd->MlmeAux.HtCapabilityLen,&HtCapabilityTmp,
-								END_OF_ARGS);
-#endif
-			}
-			FrameLen += TmpLen;
-		}
-#endif // DOT11_N_SUPPORT //
-
-		// add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION
-		// Case I: (Aggregation + Piggy-Back)
-		// 1. user enable aggregation, AND
-		// 2. Mac support piggy-back
-		// 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON
-		// Case II: (Aggregation)
-		// 1. user enable aggregation, AND
-		// 2. AP annouces it's AGGREGATION-capable in BEACON
-		if (pAd->CommonCfg.bAggregationCapable)
-		{
-			if ((pAd->CommonCfg.bPiggyBackCapable) && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3))
-			{
-				ULONG TmpLen;
-				UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x03, 0x00, 0x00, 0x00};
-				MakeOutgoingFrame(pOutBuffer+FrameLen,           &TmpLen,
-								  9,                             RalinkIe,
-								  END_OF_ARGS);
-				FrameLen += TmpLen;
-			}
-			else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
-			{
-				ULONG TmpLen;
-				UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00};
-				MakeOutgoingFrame(pOutBuffer+FrameLen,           &TmpLen,
-								  9,                             RalinkIe,
-								  END_OF_ARGS);
-				FrameLen += TmpLen;
-			}
-		}
-		else
-		{
-			ULONG TmpLen;
-			UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x06, 0x00, 0x00, 0x00};
-			MakeOutgoingFrame(pOutBuffer+FrameLen,		 &TmpLen,
-							  9,						 RalinkIe,
-							  END_OF_ARGS);
-			FrameLen += TmpLen;
-		}
-
-		if (pAd->MlmeAux.APEdcaParm.bValid)
-		{
-			if (pAd->CommonCfg.bAPSDCapable && pAd->MlmeAux.APEdcaParm.bAPSDCapable)
-			{
-				QBSS_STA_INFO_PARM QosInfo;
-
-				NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM));
-				QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE;
-				QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK;
-				QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI;
-				QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO;
-				QosInfo.MaxSPLength = pAd->CommonCfg.MaxSPLength;
-				WmeIe[8] |= *(PUCHAR)&QosInfo;
-			}
-			else
-			{
-                // The Parameter Set Count is set to ��0�� in the association request frames
-                // WmeIe[8] |= (pAd->MlmeAux.APEdcaParm.EdcaUpdateCount & 0x0f);
-			}
-
-			MakeOutgoingFrame(pOutBuffer + FrameLen,    &tmp,
-							  9,                        &WmeIe[0],
-							  END_OF_ARGS);
-			FrameLen += tmp;
-		}
-
-		//
-		// Let WPA(#221) Element ID on the end of this association frame.
-		// Otherwise some AP will fail on parsing Element ID and set status fail on Assoc Rsp.
-		// For example: Put Vendor Specific IE on the front of WPA IE.
-		// This happens on AP (Model No:Linksys WRK54G)
-		//
-		if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
-            (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
-            (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
-            (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
-			)
-            )
-		{
-			UCHAR RSNIe = IE_WPA;
-
-			if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
-                (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
-			{
-				RSNIe = IE_WPA2;
-			}
-
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-#ifdef SIOCSIWGENIE
-			if ((pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE) &&
-				(pAd->StaCfg.bRSN_IE_FromWpaSupplicant == FALSE))
-#endif // SIOCSIWGENIE //
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-            RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
-
-            // Check for WPA PMK cache list
-			if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
-			{
-			    INT     idx;
-                BOOLEAN FoundPMK = FALSE;
-				// Search chched PMKID, append it if existed
-				for (idx = 0; idx < PMKID_NO; idx++)
-				{
-					if (NdisEqualMemory(ApAddr, &pAd->StaCfg.SavedPMK[idx].BSSID, 6))
-					{
-						FoundPMK = TRUE;
-						break;
-					}
-				}
-
-				if (FoundPMK)
-				{
-					// Set PMK number
-					*(PUSHORT) &pAd->StaCfg.RSN_IE[pAd->StaCfg.RSNIE_Len] = 1;
-					NdisMoveMemory(&pAd->StaCfg.RSN_IE[pAd->StaCfg.RSNIE_Len + 2], &pAd->StaCfg.SavedPMK[idx].PMKID, 16);
-                    pAd->StaCfg.RSNIE_Len += 18;
-				}
-			}
-
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-#ifdef SIOCSIWGENIE
-			if ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) &&
-				(pAd->StaCfg.bRSN_IE_FromWpaSupplicant == TRUE))
-			{
-				MakeOutgoingFrame(pOutBuffer + FrameLen,		&tmp,
-						pAd->StaCfg.RSNIE_Len,			pAd->StaCfg.RSN_IE,
-						END_OF_ARGS);
-			}
-			else
-#endif
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-			{
-			MakeOutgoingFrame(pOutBuffer + FrameLen,		&tmp,
-						1,                              &RSNIe,
-					1,                              &pAd->StaCfg.RSNIE_Len,
-					pAd->StaCfg.RSNIE_Len,			pAd->StaCfg.RSN_IE,
-					END_OF_ARGS);
-			}
-
-			FrameLen += tmp;
-
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-#ifdef SIOCSIWGENIE
-			if ((pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE) ||
-				(pAd->StaCfg.bRSN_IE_FromWpaSupplicant == FALSE))
-#endif
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-			{
-            // Append Variable IE
-            NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &RSNIe, 1);
-            VarIesOffset += 1;
-            NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->StaCfg.RSNIE_Len, 1);
-            VarIesOffset += 1;
-			}
-			NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
-			VarIesOffset += pAd->StaCfg.RSNIE_Len;
-
-			// Set Variable IEs Length
-			pAd->StaCfg.ReqVarIELen = VarIesOffset;
-		}
-
-
-		MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-		MlmeFreeMemory(pAd, pOutBuffer);
-
-		RTMPSetTimer(&pAd->MlmeAux.AssocTimer, Timeout);
-		pAd->Mlme.AssocMachine.CurrState = ASSOC_WAIT_RSP;
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeAssocReqAction() sanity check failed. BUG!!!!!! \n"));
-		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-		Status = MLME_INVALID_FORMAT;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
-	}
-
-}
-
-/*
-	==========================================================================
-	Description:
-		mlme reassoc req handling procedure
-	Parameters:
-		Elem -
-	Pre:
-		-# SSID  (Adapter->StaCfg.ssid[])
-		-# BSSID (AP address, Adapter->StaCfg.bssid)
-		-# Supported rates (Adapter->StaCfg.supported_rates[])
-		-# Supported rates length (Adapter->StaCfg.supported_rates_len)
-		-# Tx power (Adapter->StaCfg.tx_power)
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID MlmeReassocReqAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	UCHAR			ApAddr[6];
-	HEADER_802_11	ReassocHdr;
-	UCHAR			WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
-	USHORT			CapabilityInfo, ListenIntv;
-	ULONG			Timeout;
-	ULONG			FrameLen = 0;
-	BOOLEAN			TimerCancelled;
-	NDIS_STATUS		NStatus;
-	ULONG			tmp;
-	PUCHAR			pOutBuffer = NULL;
-	USHORT			Status;
-
-	// Block all authentication request durning WPA block period
-	if (pAd->StaCfg.bBlockAssoc == TRUE)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Block ReAssoc request durning WPA block period!\n"));
-		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-		Status = MLME_STATE_MACHINE_REJECT;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
-	}
-	// the parameters are the same as the association
-	else if(MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, &Timeout, &ListenIntv))
-	{
-		RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &TimerCancelled);
-
-		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-		if(NStatus != NDIS_STATUS_SUCCESS)
-		{
-			DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeReassocReqAction() allocate memory failed \n"));
-			pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-			Status = MLME_FAIL_NO_RESOURCE;
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
-			return;
-		}
-
-		COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr);
-
-		// make frame, use bssid as the AP address??
-		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send RE-ASSOC request...\n"));
-		MgtMacHeaderInit(pAd, &ReassocHdr, SUBTYPE_REASSOC_REQ, 0, ApAddr, ApAddr);
-		MakeOutgoingFrame(pOutBuffer,               &FrameLen,
-						  sizeof(HEADER_802_11),    &ReassocHdr,
-						  2,                        &CapabilityInfo,
-						  2,                        &ListenIntv,
-						  MAC_ADDR_LEN,             ApAddr,
-						  1,                        &SsidIe,
-						  1,                        &pAd->MlmeAux.SsidLen,
-						  pAd->MlmeAux.SsidLen,     pAd->MlmeAux.Ssid,
-						  1,                        &SupRateIe,
-						  1,						&pAd->MlmeAux.SupRateLen,
-						  pAd->MlmeAux.SupRateLen,  pAd->MlmeAux.SupRate,
-						  END_OF_ARGS);
-
-		if (pAd->MlmeAux.ExtRateLen != 0)
-		{
-			MakeOutgoingFrame(pOutBuffer + FrameLen,        &tmp,
-							  1,                            &ExtRateIe,
-							  1,                            &pAd->MlmeAux.ExtRateLen,
-							  pAd->MlmeAux.ExtRateLen,	    pAd->MlmeAux.ExtRate,
-							  END_OF_ARGS);
-			FrameLen += tmp;
-		}
-
-
-		if (pAd->MlmeAux.APEdcaParm.bValid)
-		{
-			if (pAd->CommonCfg.bAPSDCapable && pAd->MlmeAux.APEdcaParm.bAPSDCapable)
-			{
-				QBSS_STA_INFO_PARM QosInfo;
-
-				NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM));
-				QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE;
-				QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK;
-				QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI;
-				QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO;
-				QosInfo.MaxSPLength = pAd->CommonCfg.MaxSPLength;
-				WmeIe[8] |= *(PUCHAR)&QosInfo;
-			}
-
-			MakeOutgoingFrame(pOutBuffer + FrameLen,    &tmp,
-							  9,                        &WmeIe[0],
-							  END_OF_ARGS);
-			FrameLen += tmp;
-		}
-
-#ifdef DOT11_N_SUPPORT
-		// HT
-		if ((pAd->MlmeAux.HtCapabilityLen > 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
-		{
-			ULONG TmpLen;
-			UCHAR HtLen;
-			UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
-			if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE)
-			{
-				HtLen = SIZE_HT_CAP_IE + 4;
-				MakeOutgoingFrame(pOutBuffer + FrameLen,            &TmpLen,
-							  1,                                &WpaIe,
-							  1,                                &HtLen,
-							  4,                                &BROADCOM[0],
-							 pAd->MlmeAux.HtCapabilityLen,          &pAd->MlmeAux.HtCapability,
-							  END_OF_ARGS);
-			}
-			else
-			{
-				MakeOutgoingFrame(pOutBuffer + FrameLen,            &TmpLen,
-							  1,                                &HtCapIe,
-							  1,                                &pAd->MlmeAux.HtCapabilityLen,
-							 pAd->MlmeAux.HtCapabilityLen,          &pAd->MlmeAux.HtCapability,
-							  END_OF_ARGS);
-			}
-			FrameLen += TmpLen;
-		}
-#endif // DOT11_N_SUPPORT //
-
-		// add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION
-		// Case I: (Aggregation + Piggy-Back)
-		// 1. user enable aggregation, AND
-		// 2. Mac support piggy-back
-		// 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON
-		// Case II: (Aggregation)
-		// 1. user enable aggregation, AND
-		// 2. AP annouces it's AGGREGATION-capable in BEACON
-		if (pAd->CommonCfg.bAggregationCapable)
-		{
-			if ((pAd->CommonCfg.bPiggyBackCapable) && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3))
-			{
-				ULONG TmpLen;
-				UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x03, 0x00, 0x00, 0x00};
-				MakeOutgoingFrame(pOutBuffer+FrameLen,           &TmpLen,
-								  9,                             RalinkIe,
-								  END_OF_ARGS);
-				FrameLen += TmpLen;
-			}
-			else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
-			{
-				ULONG TmpLen;
-				UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00};
-				MakeOutgoingFrame(pOutBuffer+FrameLen,           &TmpLen,
-								  9,                             RalinkIe,
-								  END_OF_ARGS);
-				FrameLen += TmpLen;
-			}
-		}
-		else
-		{
-			ULONG TmpLen;
-			UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x04, 0x00, 0x00, 0x00};
-			MakeOutgoingFrame(pOutBuffer+FrameLen,		 &TmpLen,
-							  9,						 RalinkIe,
-							  END_OF_ARGS);
-			FrameLen += TmpLen;
-		}
-
-		MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-		MlmeFreeMemory(pAd, pOutBuffer);
-
-		RTMPSetTimer(&pAd->MlmeAux.ReassocTimer, Timeout); /* in mSec */
-		pAd->Mlme.AssocMachine.CurrState = REASSOC_WAIT_RSP;
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeReassocReqAction() sanity check failed. BUG!!!! \n"));
-		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-		Status = MLME_INVALID_FORMAT;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-		Upper layer issues disassoc request
-	Parameters:
-		Elem -
-
-	IRQL = PASSIVE_LEVEL
-
-	==========================================================================
- */
-VOID MlmeDisassocReqAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	PMLME_DISASSOC_REQ_STRUCT pDisassocReq;
-	HEADER_802_11         DisassocHdr;
-	PHEADER_802_11        pDisassocHdr;
-	PUCHAR                pOutBuffer = NULL;
-	ULONG                 FrameLen = 0;
-	NDIS_STATUS           NStatus;
-	BOOLEAN               TimerCancelled;
-	ULONG                 Timeout = 500;
-	USHORT                Status;
-
-#ifdef QOS_DLS_SUPPORT
-	// send DLS-TEAR_DOWN message,
-	if (pAd->CommonCfg.bDLSCapable)
-	{
-		UCHAR i;
-
-		// tear down local dls table entry
-		for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
-		{
-			if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
-			{
-				RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
-				pAd->StaCfg.DLSEntry[i].Status	= DLS_NONE;
-				pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
-			}
-		}
-
-		// tear down peer dls table entry
-		for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
-		{
-			if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
-			{
-				RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
-				pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
-				pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
-			}
-		}
-	}
-#endif // QOS_DLS_SUPPORT //
-
-	// skip sanity check
-	pDisassocReq = (PMLME_DISASSOC_REQ_STRUCT)(Elem->Msg);
-
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-	if (NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - MlmeDisassocReqAction() allocate memory failed\n"));
-		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-		Status = MLME_FAIL_NO_RESOURCE;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
-		return;
-	}
-
-
-
-
-	RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &TimerCancelled);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send DISASSOC request[BSSID::%02x:%02x:%02x:%02x:%02x:%02x (Reason=%d)\n",
-				pDisassocReq->Addr[0], pDisassocReq->Addr[1], pDisassocReq->Addr[2],
-				pDisassocReq->Addr[3], pDisassocReq->Addr[4], pDisassocReq->Addr[5], pDisassocReq->Reason));
-	MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pDisassocReq->Addr, pDisassocReq->Addr);	// patch peap ttls switching issue
-	MakeOutgoingFrame(pOutBuffer,           &FrameLen,
-					  sizeof(HEADER_802_11),&DisassocHdr,
-					  2,                    &pDisassocReq->Reason,
-					  END_OF_ARGS);
-	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-
-	// To patch Instance and Buffalo(N) AP
-	// Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine
-	// Therefore, we send both of them.
-	pDisassocHdr = (PHEADER_802_11)pOutBuffer;
-	pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH;
-	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-	pAd->StaCfg.DisassocReason = REASON_DISASSOC_STA_LEAVING;
-	COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pDisassocReq->Addr);
-
-	RTMPSetTimer(&pAd->MlmeAux.DisassocTimer, Timeout); /* in mSec */
-	pAd->Mlme.AssocMachine.CurrState = DISASSOC_WAIT_RSP;
-
-#ifdef WPA_SUPPLICANT_SUPPORT
-#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
-	if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
-	{
-		//send disassociate event to wpa_supplicant
-		RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, RT_DISASSOC_EVENT_FLAG, NULL, NULL, 0);
-	}
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-	RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0);
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-
-}
-
-/*
-	==========================================================================
-	Description:
-		peer sends assoc rsp back
-	Parameters:
-		Elme - MLME message containing the received frame
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID PeerAssocRspAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	USHORT        CapabilityInfo, Status, Aid;
-	UCHAR         SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
-	UCHAR         ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
-	UCHAR         Addr2[MAC_ADDR_LEN];
-	BOOLEAN       TimerCancelled;
-	UCHAR         CkipFlag;
-	EDCA_PARM     EdcaParm;
-	HT_CAPABILITY_IE		HtCapability;
-	ADD_HT_INFO_IE		AddHtInfo;	// AP might use this additional ht info IE
-	UCHAR			HtCapabilityLen;
-	UCHAR			AddHtInfoLen;
-	UCHAR			NewExtChannelOffset = 0xff;
-
-	if (PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen,
-		&HtCapability,&AddHtInfo, &HtCapabilityLen,&AddHtInfoLen,&NewExtChannelOffset, &EdcaParm, &CkipFlag))
-	{
-		// The frame is for me ?
-		if(MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspAction():ASSOC - receive ASSOC_RSP to me (status=%d)\n", Status));
-#ifdef DOT11_N_SUPPORT
-			DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspAction():MacTable [%d].AMsduSize = %d. ClientStatusFlags = 0x%lx \n",Elem->Wcid, pAd->MacTab.Content[BSSID_WCID].AMsduSize, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
-#endif // DOT11_N_SUPPORT //
-			RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &TimerCancelled);
-
-
-			if(Status == MLME_SUCCESS)
-			{
-				UCHAR			MaxSupportedRateIn500Kbps = 0;
-				UCHAR			idx;
-
-				// supported rates array may not be sorted. sort it and find the maximum rate
-			    for (idx=0; idx<SupRateLen; idx++)
-			    {
-			        if (MaxSupportedRateIn500Kbps < (SupRate[idx] & 0x7f))
-			            MaxSupportedRateIn500Kbps = SupRate[idx] & 0x7f;
-			    }
-
-				for (idx=0; idx<ExtRateLen; idx++)
-			    {
-			        if (MaxSupportedRateIn500Kbps < (ExtRate[idx] & 0x7f))
-			            MaxSupportedRateIn500Kbps = ExtRate[idx] & 0x7f;
-			    }
-				// go to procedure listed on page 376
-				AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen,
-					&EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo);
-
-				StaAddMacTableEntry(pAd,
-									&pAd->MacTab.Content[BSSID_WCID],
-									MaxSupportedRateIn500Kbps,
-									&HtCapability,
-									HtCapabilityLen,
-									&AddHtInfo,
-									AddHtInfoLen,
-									CapabilityInfo);
-			}
-			pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
-		}
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerAssocRspAction() sanity check fail\n"));
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-		peer sends reassoc rsp
-	Parametrs:
-		Elem - MLME message cntaining the received frame
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID PeerReassocRspAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	USHORT      CapabilityInfo;
-	USHORT      Status;
-	USHORT      Aid;
-	UCHAR       SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
-	UCHAR       ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
-	UCHAR       Addr2[MAC_ADDR_LEN];
-	UCHAR       CkipFlag;
-	BOOLEAN     TimerCancelled;
-	EDCA_PARM   EdcaParm;
-	HT_CAPABILITY_IE		HtCapability;
-	ADD_HT_INFO_IE		AddHtInfo;	// AP might use this additional ht info IE
-	UCHAR			HtCapabilityLen;
-	UCHAR			AddHtInfoLen;
-	UCHAR			NewExtChannelOffset = 0xff;
-
-	if(PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen,
-								&HtCapability,	&AddHtInfo, &HtCapabilityLen, &AddHtInfoLen,&NewExtChannelOffset, &EdcaParm, &CkipFlag))
-	{
-		if(MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid)) // The frame is for me ?
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - receive REASSOC_RSP to me (status=%d)\n", Status));
-			RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &TimerCancelled);
-
-			if(Status == MLME_SUCCESS)
-			{
-				// go to procedure listed on page 376
-				AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen,
-					 &EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo);
-
-#ifdef WPA_SUPPLICANT_SUPPORT
-#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
-                if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
-			{
-				SendAssocIEsToWpaSupplicant(pAd);
-				RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, RT_ASSOC_EVENT_FLAG, NULL, NULL, 0);
-			}
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-                {
-                    wext_notify_event_assoc(pAd);
-                    RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, &pAd->MlmeAux.Bssid[0], NULL, 0);
-                }
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-
-			}
-
-			// CkipFlag is no use for reassociate
-			pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
-		}
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerReassocRspAction() sanity check fail\n"));
-	}
-
-}
-
-/*
-	==========================================================================
-	Description:
-		procedures on IEEE 802.11/1999 p.376
-	Parametrs:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AssocPostProc(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pAddr2,
-	IN USHORT CapabilityInfo,
-	IN USHORT Aid,
-	IN UCHAR SupRate[],
-	IN UCHAR SupRateLen,
-	IN UCHAR ExtRate[],
-	IN UCHAR ExtRateLen,
-	IN PEDCA_PARM pEdcaParm,
-	IN HT_CAPABILITY_IE		*pHtCapability,
-	IN UCHAR HtCapabilityLen,
-	IN ADD_HT_INFO_IE		*pAddHtInfo)	// AP might use this additional ht info IE
-{
-	ULONG Idx;
-
-	pAd->MlmeAux.BssType = BSS_INFRA;
-	COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pAddr2);
-	pAd->MlmeAux.Aid = Aid;
-	pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
-
-#ifdef DOT11_N_SUPPORT
-	// Some HT AP might lost WMM IE. We add WMM ourselves. beacuase HT requires QoS on.
-	if ((HtCapabilityLen > 0) && (pEdcaParm->bValid == FALSE))
-	{
-		pEdcaParm->bValid = TRUE;
-		pEdcaParm->Aifsn[0] = 3;
-		pEdcaParm->Aifsn[1] = 7;
-		pEdcaParm->Aifsn[2] = 2;
-		pEdcaParm->Aifsn[3] = 2;
-
-		pEdcaParm->Cwmin[0] = 4;
-		pEdcaParm->Cwmin[1] = 4;
-		pEdcaParm->Cwmin[2] = 3;
-		pEdcaParm->Cwmin[3] = 2;
-
-		pEdcaParm->Cwmax[0] = 10;
-		pEdcaParm->Cwmax[1] = 10;
-		pEdcaParm->Cwmax[2] = 4;
-		pEdcaParm->Cwmax[3] = 3;
-
-		pEdcaParm->Txop[0]  = 0;
-		pEdcaParm->Txop[1]  = 0;
-		pEdcaParm->Txop[2]  = 96;
-		pEdcaParm->Txop[3]  = 48;
-
-	}
-#endif // DOT11_N_SUPPORT //
-
-	NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
-
-	// filter out un-supported rates
-	pAd->MlmeAux.SupRateLen = SupRateLen;
-	NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen);
-	RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
-
-	// filter out un-supported rates
-	pAd->MlmeAux.ExtRateLen = ExtRateLen;
-	NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen);
-	RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
-
-#ifdef DOT11_N_SUPPORT
-	if (HtCapabilityLen > 0)
-	{
-		RTMPCheckHt(pAd, BSSID_WCID, pHtCapability, pAddHtInfo);
-	}
-	DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===>  AP.AMsduSize = %d. ClientStatusFlags = 0x%lx \n", pAd->MacTab.Content[BSSID_WCID].AMsduSize, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
-
-	DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===>    (Mmps=%d, AmsduSize=%d, )\n",
-		pAd->MacTab.Content[BSSID_WCID].MmpsMode, pAd->MacTab.Content[BSSID_WCID].AMsduSize));
-#endif // DOT11_N_SUPPORT //
-
-	// Set New WPA information
-	Idx = BssTableSearch(&pAd->ScanTab, pAddr2, pAd->MlmeAux.Channel);
-	if (Idx == BSS_NOT_FOUND)
-	{
-		DBGPRINT_ERR(("ASSOC - Can't find BSS after receiving Assoc response\n"));
-	}
-	else
-	{
-		// Init variable
-		pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = 0;
-		NdisZeroMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, MAX_LEN_OF_RSNIE);
-
-		// Store appropriate RSN_IE for WPA SM negotiation later
-		if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAd->ScanTab.BssEntry[Idx].VarIELen != 0))
-		{
-			PUCHAR              pVIE;
-			USHORT              len;
-			PEID_STRUCT         pEid;
-
-			pVIE = pAd->ScanTab.BssEntry[Idx].VarIEs;
-			len	 = pAd->ScanTab.BssEntry[Idx].VarIELen;
-			//KH need to check again
-			// Don't allow to go to sleep mode if authmode is WPA-related.
-			//This can make Authentication process more smoothly.
-			RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-
-			while (len > 0)
-			{
-				pEid = (PEID_STRUCT) pVIE;
-				// For WPA/WPAPSK
-				if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
-					&& (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
-				{
-					NdisMoveMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, pVIE, (pEid->Len + 2));
-					pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = (pEid->Len + 2);
-					DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> Store RSN_IE for WPA SM negotiation \n"));
-				}
-				// For WPA2/WPA2PSK
-				else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
-					&& (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2 || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
-				{
-					NdisMoveMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, pVIE, (pEid->Len + 2));
-					pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = (pEid->Len + 2);
-					DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> Store RSN_IE for WPA2 SM negotiation \n"));
-				}
-
-				pVIE += (pEid->Len + 2);
-				len  -= (pEid->Len + 2);
-			}
-
-
-		}
-
-		if (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == 0)
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> no RSN_IE \n"));
-		}
-		else
-		{
-			hex_dump("RSN_IE", pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len);
-		}
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-		left part of IEEE 802.11/1999 p.374
-	Parameters:
-		Elem - MLME message containing the received frame
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID PeerDisassocAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	UCHAR         Addr2[MAC_ADDR_LEN];
-	USHORT        Reason;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction()\n"));
-	if(PeerDisassocSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction() Reason = %d\n", Reason));
-		if (INFRA_ON(pAd) && MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, Addr2))
-		{
-
-			if (pAd->CommonCfg.bWirelessEvent)
-			{
-				RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-			}
-
-
-			LinkDown(pAd, TRUE);
-			pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-
-#ifdef WPA_SUPPLICANT_SUPPORT
-#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
-            if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
-			{
-				//send disassociate event to wpa_supplicant
-				RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, RT_DISASSOC_EVENT_FLAG, NULL, NULL, 0);
-			}
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-			RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0);
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-		}
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction() sanity check fail\n"));
-	}
-
-}
-
-/*
-	==========================================================================
-	Description:
-		what the state machine will do after assoc timeout
-	Parameters:
-		Elme -
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID AssocTimeoutAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	USHORT  Status;
-	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - AssocTimeoutAction\n"));
-	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-	Status = MLME_REJ_TIMEOUT;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
-}
-
-/*
-	==========================================================================
-	Description:
-		what the state machine will do after reassoc timeout
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID ReassocTimeoutAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	USHORT  Status;
-	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - ReassocTimeoutAction\n"));
-	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-	Status = MLME_REJ_TIMEOUT;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
-}
-
-/*
-	==========================================================================
-	Description:
-		what the state machine will do after disassoc timeout
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID DisassocTimeoutAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	USHORT  Status;
-	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - DisassocTimeoutAction\n"));
-	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-	Status = MLME_SUCCESS;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
-}
-
-VOID InvalidStateWhenAssoc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	USHORT  Status;
-	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenAssoc(state=%ld), reset ASSOC state machine\n",
-		pAd->Mlme.AssocMachine.CurrState));
-	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-	Status = MLME_STATE_MACHINE_REJECT;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
-}
-
-VOID InvalidStateWhenReassoc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	USHORT Status;
-	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenReassoc(state=%ld), reset ASSOC state machine\n",
-		pAd->Mlme.AssocMachine.CurrState));
-	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-	Status = MLME_STATE_MACHINE_REJECT;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
-}
-
-VOID InvalidStateWhenDisassociate(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	USHORT Status;
-	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenDisassoc(state=%ld), reset ASSOC state machine\n",
-		pAd->Mlme.AssocMachine.CurrState));
-	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-	Status = MLME_STATE_MACHINE_REJECT;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
-}
-
-/*
-	==========================================================================
-	Description:
-		right part of IEEE 802.11/1999 page 374
-	Note:
-		This event should never cause ASSOC state machine perform state
-		transition, and has no relationship with CNTL machine. So we separate
-		this routine as a service outside of ASSOC state transition table.
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID Cls3errAction(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR        pAddr)
-{
-	HEADER_802_11         DisassocHdr;
-	PHEADER_802_11        pDisassocHdr;
-	PUCHAR                pOutBuffer = NULL;
-	ULONG                 FrameLen = 0;
-	NDIS_STATUS           NStatus;
-	USHORT                Reason = REASON_CLS3ERR;
-
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-	if (NStatus != NDIS_STATUS_SUCCESS)
-		return;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Class 3 Error, Send DISASSOC frame\n"));
-	MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pAddr, pAd->CommonCfg.Bssid);	// patch peap ttls switching issue
-	MakeOutgoingFrame(pOutBuffer,           &FrameLen,
-					  sizeof(HEADER_802_11),&DisassocHdr,
-					  2,                    &Reason,
-					  END_OF_ARGS);
-	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-
-	// To patch Instance and Buffalo(N) AP
-	// Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine
-	// Therefore, we send both of them.
-	pDisassocHdr = (PHEADER_802_11)pOutBuffer;
-	pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH;
-	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-	pAd->StaCfg.DisassocReason = REASON_CLS3ERR;
-	COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pAddr);
-}
-
-#ifdef WPA_SUPPLICANT_SUPPORT
-#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
-VOID    SendAssocIEsToWpaSupplicant(
-    IN  PRTMP_ADAPTER pAd)
-{
-	STRING custom[IW_CUSTOM_MAX] = {0};
-
-	if ((pAd->StaCfg.ReqVarIELen + 17) <= IW_CUSTOM_MAX)
-	{
-		sprintf(custom, "ASSOCINFO_ReqIEs=");
-		NdisMoveMemory(custom+17, pAd->StaCfg.ReqVarIEs, pAd->StaCfg.ReqVarIELen);
-		RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, RT_REQIE_EVENT_FLAG, NULL, (PUCHAR)custom, pAd->StaCfg.ReqVarIELen + 17);
-
-		RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, RT_ASSOCINFO_EVENT_FLAG, NULL, NULL, 0);
-	}
-	else
-		DBGPRINT(RT_DEBUG_TRACE, ("pAd->StaCfg.ReqVarIELen + 17 > MAX_CUSTOM_LEN\n"));
-
-	return;
-}
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-int wext_notify_event_assoc(
-	IN  RTMP_ADAPTER *pAd)
-{
-	char custom[IW_CUSTOM_MAX] = {0};
-
-#if WIRELESS_EXT > 17
-	if (pAd->StaCfg.ReqVarIELen <= IW_CUSTOM_MAX)
-	{
-		NdisMoveMemory(custom, pAd->StaCfg.ReqVarIEs, pAd->StaCfg.ReqVarIELen);
-		RtmpOSWrielessEventSend(pAd, IWEVASSOCREQIE, -1, NULL, custom, pAd->StaCfg.ReqVarIELen);
-	}
-	else
-	    DBGPRINT(RT_DEBUG_TRACE, ("pAd->StaCfg.ReqVarIELen > MAX_CUSTOM_LEN\n"));
-#else
-	int len;
-
-	len = (pAd->StaCfg.ReqVarIELen*2) + 17;
-	if (len <= IW_CUSTOM_MAX)
-	{
-		UCHAR   idx;
-		sprintf(custom, "ASSOCINFO(ReqIEs=");
-		for (idx=0; idx<pAd->StaCfg.ReqVarIELen; idx++)
-		        sprintf(custom, "%s%02x", custom, pAd->StaCfg.ReqVarIEs[idx]);
-		RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, -1, NULL, custom, len);
-	}
-	else
-		DBGPRINT(RT_DEBUG_TRACE, ("len(%d) > MAX_CUSTOM_LEN\n", len));
-#endif
-
-	return 0;
-
-}
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-
-
-BOOLEAN StaAddMacTableEntry(
-	IN  PRTMP_ADAPTER		pAd,
-	IN  PMAC_TABLE_ENTRY	pEntry,
-	IN  UCHAR				MaxSupportedRateIn500Kbps,
-	IN  HT_CAPABILITY_IE	*pHtCapability,
-	IN  UCHAR				HtCapabilityLen,
-	IN  ADD_HT_INFO_IE		*pAddHtInfo,
-	IN  UCHAR				AddHtInfoLen,
-	IN  USHORT			CapabilityInfo)
-{
-	UCHAR            MaxSupportedRate = RATE_11;
-
-	if (ADHOC_ON(pAd))
-		CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
-
-	switch (MaxSupportedRateIn500Kbps)
-    {
-        case 108: MaxSupportedRate = RATE_54;   break;
-        case 96:  MaxSupportedRate = RATE_48;   break;
-        case 72:  MaxSupportedRate = RATE_36;   break;
-        case 48:  MaxSupportedRate = RATE_24;   break;
-        case 36:  MaxSupportedRate = RATE_18;   break;
-        case 24:  MaxSupportedRate = RATE_12;   break;
-        case 18:  MaxSupportedRate = RATE_9;    break;
-        case 12:  MaxSupportedRate = RATE_6;    break;
-        case 22:  MaxSupportedRate = RATE_11;   break;
-        case 11:  MaxSupportedRate = RATE_5_5;  break;
-        case 4:   MaxSupportedRate = RATE_2;    break;
-        case 2:   MaxSupportedRate = RATE_1;    break;
-        default:  MaxSupportedRate = RATE_11;   break;
-    }
-
-    if ((pAd->CommonCfg.PhyMode == PHY_11G) && (MaxSupportedRate < RATE_FIRST_OFDM_RATE))
-        return FALSE;
-
-#ifdef DOT11_N_SUPPORT
-	// 11n only
-	if (((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G))&& (HtCapabilityLen == 0))
-		return FALSE;
-#endif // DOT11_N_SUPPORT //
-
-	if (!pEntry)
-        return FALSE;
-
-	NdisAcquireSpinLock(&pAd->MacTabLock);
-	if (pEntry)
-	{
-		pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
-		if ((MaxSupportedRate < RATE_FIRST_OFDM_RATE) ||
-			(pAd->CommonCfg.PhyMode == PHY_11B))
-		{
-			pEntry->RateLen = 4;
-			if (MaxSupportedRate >= RATE_FIRST_OFDM_RATE)
-				MaxSupportedRate = RATE_11;
-		}
-		else
-			pEntry->RateLen = 12;
-
-		pEntry->MaxHTPhyMode.word = 0;
-		pEntry->MinHTPhyMode.word = 0;
-		pEntry->HTPhyMode.word = 0;
-		pEntry->MaxSupportedRate = MaxSupportedRate;
-		if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
-		{
-			pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
-			pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
-			pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
-			pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
-			pEntry->HTPhyMode.field.MODE = MODE_CCK;
-			pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
-		}
-		else
-		{
-			pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
-			pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
-			pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
-			pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
-			pEntry->HTPhyMode.field.MODE = MODE_OFDM;
-			pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
-		}
-		pEntry->CapabilityInfo = CapabilityInfo;
-		CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE);
-		CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE);
-	}
-
-#ifdef DOT11_N_SUPPORT
-	NdisZeroMemory(&pEntry->HTCapability, sizeof(pEntry->HTCapability));
-	// If this Entry supports 802.11n, upgrade to HT rate.
-	if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
-	{
-		UCHAR	j, bitmask; //k,bitmask;
-		CHAR    i;
-
-		if (ADHOC_ON(pAd))
-			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
-		if ((pHtCapability->HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
-		{
-			pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
-		}
-		else
-		{
-			pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
-			pAd->MacTab.fAnyStationNonGF = TRUE;
-			pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
-		}
-
-		if ((pHtCapability->HtCapInfo.ChannelWidth) &&
-			(pAd->CommonCfg.DesiredHtPhy.ChannelWidth) &&
-			((pAd->StaCfg.BssType == BSS_INFRA) || ((pAd->StaCfg.BssType == BSS_ADHOC) && (pAddHtInfo->AddHtInfo.ExtChanOffset == pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset))))
-		{
-			pEntry->MaxHTPhyMode.field.BW= BW_40;
-			pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(pHtCapability->HtCapInfo.ShortGIfor40));
-		}
-		else
-		{
-			pEntry->MaxHTPhyMode.field.BW = BW_20;
-			pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(pHtCapability->HtCapInfo.ShortGIfor20));
-			pAd->MacTab.fAnyStation20Only = TRUE;
-		}
-
-		// 3*3
-		if (pAd->MACVersion >= RALINK_2883_VERSION && pAd->MACVersion < RALINK_3070_VERSION)
-			pEntry->MaxHTPhyMode.field.TxBF = pAd->CommonCfg.RegTransmitSetting.field.TxBF;
-
-		// find max fixed rate
-		for (i=23; i>=0; i--) // 3*3
-		{
-			j = i/8;
-			bitmask = (1<<(i-(j*8)));
-			if ((pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j] & bitmask) && (pHtCapability->MCSSet[j] & bitmask))
-			{
-				pEntry->MaxHTPhyMode.field.MCS = i;
-				break;
-			}
-			if (i==0)
-				break;
-		}
-
-
-		if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
-		{
-			if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
-			{
-				// Fix MCS as HT Duplicated Mode
-				pEntry->MaxHTPhyMode.field.BW = 1;
-				pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
-				pEntry->MaxHTPhyMode.field.STBC = 0;
-				pEntry->MaxHTPhyMode.field.ShortGI = 0;
-				pEntry->MaxHTPhyMode.field.MCS = 32;
-			}
-			else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
-			{
-				// STA supports fixed MCS
-				pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
-			}
-		}
-
-		pEntry->MaxHTPhyMode.field.STBC = (pHtCapability->HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
-		pEntry->MpduDensity = pHtCapability->HtCapParm.MpduDensity;
-		pEntry->MaxRAmpduFactor = pHtCapability->HtCapParm.MaxRAmpduFactor;
-		pEntry->MmpsMode = (UCHAR)pHtCapability->HtCapInfo.MimoPs;
-		pEntry->AMsduSize = (UCHAR)pHtCapability->HtCapInfo.AMsduSize;
-		pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
-
-		if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE))
-			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED);
-		if (pHtCapability->HtCapInfo.ShortGIfor20)
-			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
-		if (pHtCapability->HtCapInfo.ShortGIfor40)
-			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
-		if (pHtCapability->HtCapInfo.TxSTBC)
-			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
-		if (pHtCapability->HtCapInfo.RxSTBC)
-			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
-		if (pHtCapability->ExtHtCapInfo.PlusHTC)
-			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
-		if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport)
-			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
-		if (pHtCapability->ExtHtCapInfo.MCSFeedback == 0x03)
-			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
-		NdisMoveMemory(&pEntry->HTCapability, pHtCapability, HtCapabilityLen);
-	}
-	else
-	{
-		pAd->MacTab.fAnyStationIsLegacy = TRUE;
-	}
-#endif // DOT11_N_SUPPORT //
-
-	pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
-	pEntry->CurrTxRate = pEntry->MaxSupportedRate;
-
-	// Set asic auto fall back
-	if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
-	{
-		PUCHAR					pTable;
-		UCHAR					TableSize = 0;
-
-		MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
-		pEntry->bAutoTxRateSwitch = TRUE;
-	}
-	else
-	{
-		pEntry->HTPhyMode.field.MODE	= pAd->StaCfg.HTPhyMode.field.MODE;
-		pEntry->HTPhyMode.field.MCS	= pAd->StaCfg.HTPhyMode.field.MCS;
-		pEntry->bAutoTxRateSwitch = FALSE;
-
-		// If the legacy mode is set, overwrite the transmit setting of this entry.
-		RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
-	}
-
-	pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
-	pEntry->Sst = SST_ASSOC;
-	pEntry->AuthState = AS_AUTH_OPEN;
-	pEntry->AuthMode = pAd->StaCfg.AuthMode;
-	pEntry->WepStatus = pAd->StaCfg.WepStatus;
-
-	NdisReleaseSpinLock(&pAd->MacTabLock);
-
-#ifdef WPA_SUPPLICANT_SUPPORT
-#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
-    if (pAd->StaCfg.WpaSupplicantUP)
-    {
-        union iwreq_data    wrqu;
-
-        SendAssocIEsToWpaSupplicant(pAd);
-        memset(&wrqu, 0, sizeof(wrqu));
-        wrqu.data.flags = RT_ASSOC_EVENT_FLAG;
-        wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
-    }
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-    {
-        union iwreq_data    wrqu;
-        wext_notify_event_assoc(pAd);
-
-        memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
-        memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
-        wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
-
-    }
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-	return TRUE;
-}
diff --git a/drivers/staging/rt3090/sta/auth.c b/drivers/staging/rt3090/sta/auth.c
deleted file mode 100644
index 157e299..0000000
--- a/drivers/staging/rt3090/sta/auth.c
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	auth.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	John		2004-9-3		porting from RT2500
-*/
-
-#include "../rt_config.h"
-
-
-/*
-    ==========================================================================
-    Description:
-        authenticate state machine init, including state transition and timer init
-    Parameters:
-        Sm - pointer to the auth state machine
-    Note:
-        The state machine looks like this
-
-                        AUTH_REQ_IDLE           AUTH_WAIT_SEQ2                   AUTH_WAIT_SEQ4
-    MT2_MLME_AUTH_REQ   mlme_auth_req_action    invalid_state_when_auth          invalid_state_when_auth
-    MT2_PEER_AUTH_EVEN  drop                    peer_auth_even_at_seq2_action    peer_auth_even_at_seq4_action
-    MT2_AUTH_TIMEOUT    Drop                    auth_timeout_action              auth_timeout_action
-
-	IRQL = PASSIVE_LEVEL
-
-    ==========================================================================
- */
-
-void AuthStateMachineInit(
-    IN PRTMP_ADAPTER pAd,
-    IN STATE_MACHINE *Sm,
-    OUT STATE_MACHINE_FUNC Trans[])
-{
-    StateMachineInit(Sm, Trans, MAX_AUTH_STATE, MAX_AUTH_MSG, (STATE_MACHINE_FUNC)Drop, AUTH_REQ_IDLE, AUTH_MACHINE_BASE);
-
-    // the first column
-    StateMachineSetAction(Sm, AUTH_REQ_IDLE, MT2_MLME_AUTH_REQ, (STATE_MACHINE_FUNC)MlmeAuthReqAction);
-
-    // the second column
-    StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_MLME_AUTH_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAuth);
-    StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_PEER_AUTH_EVEN, (STATE_MACHINE_FUNC)PeerAuthRspAtSeq2Action);
-    StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_AUTH_TIMEOUT, (STATE_MACHINE_FUNC)AuthTimeoutAction);
-
-    // the third column
-    StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_MLME_AUTH_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAuth);
-    StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_PEER_AUTH_EVEN, (STATE_MACHINE_FUNC)PeerAuthRspAtSeq4Action);
-    StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_AUTH_TIMEOUT, (STATE_MACHINE_FUNC)AuthTimeoutAction);
-
-	RTMPInitTimer(pAd, &pAd->MlmeAux.AuthTimer, GET_TIMER_FUNCTION(AuthTimeout), pAd, FALSE);
-}
-
-/*
-    ==========================================================================
-    Description:
-        function to be executed at timer thread when auth timer expires
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-VOID AuthTimeout(
-    IN PVOID SystemSpecific1,
-    IN PVOID FunctionContext,
-    IN PVOID SystemSpecific2,
-    IN PVOID SystemSpecific3)
-{
-    RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
-
-    DBGPRINT(RT_DEBUG_TRACE,("AUTH - AuthTimeout\n"));
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-	// send a de-auth to reset AP's state machine (Patch AP-Dir635)
-	if (pAd->Mlme.AuthMachine.CurrState == AUTH_WAIT_SEQ2)
-		Cls2errAction(pAd, pAd->MlmeAux.Bssid);
-
-
-    MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_AUTH_TIMEOUT, 0, NULL);
-    RTMP_MLME_HANDLER(pAd);
-}
-
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-VOID MlmeAuthReqAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
-{
-	if (AUTH_ReqSend(pAd, Elem, &pAd->MlmeAux.AuthTimer, "AUTH", 1, NULL, 0))
-        pAd->Mlme.AuthMachine.CurrState = AUTH_WAIT_SEQ2;
-    else
-    {
-		USHORT Status;
-
-        pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-        Status = MLME_INVALID_FORMAT;
-        MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
-    }
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-VOID PeerAuthRspAtSeq2Action(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
-{
-    UCHAR         Addr2[MAC_ADDR_LEN];
-    USHORT        Seq, Status, RemoteStatus, Alg;
-    UCHAR         ChlgText[CIPHER_TEXT_LEN];
-    UCHAR         CyperChlgText[CIPHER_TEXT_LEN + 8 + 8];
-    UCHAR         Element[2];
-    HEADER_802_11 AuthHdr;
-    BOOLEAN       TimerCancelled;
-    PUCHAR        pOutBuffer = NULL;
-    NDIS_STATUS   NStatus;
-    ULONG         FrameLen = 0;
-    USHORT        Status2;
-
-    if (PeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, (PCHAR)ChlgText))
-    {
-        if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 2)
-        {
-            DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Receive AUTH_RSP seq#2 to me (Alg=%d, Status=%d)\n", Alg, Status));
-            RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &TimerCancelled);
-
-            if (Status == MLME_SUCCESS)
-            {
-                // Authentication Mode "LEAP" has allow for CCX 1.X
-                if (pAd->MlmeAux.Alg == Ndis802_11AuthModeOpen)
-                {
-                    pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-                    MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
-                }
-                else
-                {
-                    // 2. shared key, need to be challenged
-                    Seq++;
-                    RemoteStatus = MLME_SUCCESS;
-
-					// Get an unused nonpaged memory
-                    NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
-                    if(NStatus != NDIS_STATUS_SUCCESS)
-                    {
-                        DBGPRINT(RT_DEBUG_TRACE, ("AUTH - PeerAuthRspAtSeq2Action() allocate memory fail\n"));
-                        pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-                        Status2 = MLME_FAIL_NO_RESOURCE;
-                        MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status2);
-                        return;
-                    }
-
-                    DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send AUTH request seq#3...\n"));
-                    MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr2, pAd->MlmeAux.Bssid);
-                    AuthHdr.FC.Wep = 1;
-                    // Encrypt challenge text & auth information
-                    RTMPInitWepEngine(
-			pAd,
-			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
-			pAd->StaCfg.DefaultKeyId,
-			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen,
-			CyperChlgText);
-
-					Alg = cpu2le16(*(USHORT *)&Alg);
-					Seq = cpu2le16(*(USHORT *)&Seq);
-					RemoteStatus= cpu2le16(*(USHORT *)&RemoteStatus);
-
-					RTMPEncryptData(pAd, (PUCHAR) &Alg, CyperChlgText + 4, 2);
-					RTMPEncryptData(pAd, (PUCHAR) &Seq, CyperChlgText + 6, 2);
-					RTMPEncryptData(pAd, (PUCHAR) &RemoteStatus, CyperChlgText + 8, 2);
-					Element[0] = 16;
-					Element[1] = 128;
-					RTMPEncryptData(pAd, Element, CyperChlgText + 10, 2);
-					RTMPEncryptData(pAd, ChlgText, CyperChlgText + 12, 128);
-					RTMPSetICV(pAd, CyperChlgText + 140);
-                    MakeOutgoingFrame(pOutBuffer,               &FrameLen,
-                                      sizeof(HEADER_802_11),    &AuthHdr,
-                                      CIPHER_TEXT_LEN + 16,     CyperChlgText,
-                                      END_OF_ARGS);
-                    MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-			MlmeFreeMemory(pAd, pOutBuffer);
-
-                    RTMPSetTimer(&pAd->MlmeAux.AuthTimer, AUTH_TIMEOUT);
-                    pAd->Mlme.AuthMachine.CurrState = AUTH_WAIT_SEQ4;
-                }
-            }
-            else
-            {
-                pAd->StaCfg.AuthFailReason = Status;
-                COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2);
-                pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-                MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
-            }
-        }
-    }
-    else
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("AUTH - PeerAuthSanity() sanity check fail\n"));
-    }
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-VOID PeerAuthRspAtSeq4Action(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
-{
-    UCHAR         Addr2[MAC_ADDR_LEN];
-    USHORT        Alg, Seq, Status;
-    CHAR          ChlgText[CIPHER_TEXT_LEN];
-    BOOLEAN       TimerCancelled;
-
-    if(PeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, ChlgText))
-    {
-        if(MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 4)
-        {
-            DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Receive AUTH_RSP seq#4 to me\n"));
-            RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &TimerCancelled);
-
-            if (Status != MLME_SUCCESS)
-            {
-                pAd->StaCfg.AuthFailReason = Status;
-                COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2);
-            }
-
-            pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-            MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
-        }
-    }
-    else
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("AUTH - PeerAuthRspAtSeq4Action() sanity check fail\n"));
-    }
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-VOID MlmeDeauthReqAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
-{
-    MLME_DEAUTH_REQ_STRUCT *pInfo;
-    HEADER_802_11 DeauthHdr;
-    PUCHAR        pOutBuffer = NULL;
-    NDIS_STATUS   NStatus;
-    ULONG         FrameLen = 0;
-    USHORT        Status;
-
-    pInfo = (MLME_DEAUTH_REQ_STRUCT *)Elem->Msg;
-
-    NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-    if (NStatus != NDIS_STATUS_SUCCESS)
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("AUTH - MlmeDeauthReqAction() allocate memory fail\n"));
-        pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-        Status = MLME_FAIL_NO_RESOURCE;
-        MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, &Status);
-        return;
-    }
-
-
-    DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send DE-AUTH request (Reason=%d)...\n", pInfo->Reason));
-    MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pInfo->Addr, pAd->MlmeAux.Bssid);
-    MakeOutgoingFrame(pOutBuffer,           &FrameLen,
-                      sizeof(HEADER_802_11),&DeauthHdr,
-                      2,                    &pInfo->Reason,
-                      END_OF_ARGS);
-    MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-    pAd->StaCfg.DeauthReason = pInfo->Reason;
-    COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pInfo->Addr);
-    pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-    Status = MLME_SUCCESS;
-    MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, &Status);
-
-	// send wireless event - for deauthentication
-	if (pAd->CommonCfg.bWirelessEvent)
-		RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-VOID AuthTimeoutAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
-{
-    USHORT Status;
-    DBGPRINT(RT_DEBUG_TRACE, ("AUTH - AuthTimeoutAction\n"));
-    pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-    Status = MLME_REJ_TIMEOUT;
-    MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-VOID InvalidStateWhenAuth(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
-{
-    USHORT Status;
-    DBGPRINT(RT_DEBUG_TRACE, ("AUTH - InvalidStateWhenAuth (state=%ld), reset AUTH state machine\n", pAd->Mlme.AuthMachine.CurrState));
-    pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-    Status = MLME_STATE_MACHINE_REJECT;
-    MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
-}
-
-/*
-    ==========================================================================
-    Description:
-        Some STA/AP
-    Note:
-        This action should never trigger AUTH state transition, therefore we
-        separate it from AUTH state machine, and make it as a standalone service
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-VOID Cls2errAction(
-    IN PRTMP_ADAPTER pAd,
-    IN PUCHAR pAddr)
-{
-    HEADER_802_11 DeauthHdr;
-    PUCHAR        pOutBuffer = NULL;
-    NDIS_STATUS   NStatus;
-    ULONG         FrameLen = 0;
-    USHORT        Reason = REASON_CLS2ERR;
-
-    NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-    if (NStatus != NDIS_STATUS_SUCCESS)
-        return;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Class 2 error, Send DEAUTH frame...\n"));
-    MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pAddr, pAd->MlmeAux.Bssid);
-    MakeOutgoingFrame(pOutBuffer,           &FrameLen,
-                      sizeof(HEADER_802_11),&DeauthHdr,
-                      2,                    &Reason,
-                      END_OF_ARGS);
-    MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-    pAd->StaCfg.DeauthReason = Reason;
-    COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pAddr);
-}
-
-BOOLEAN	AUTH_ReqSend(
-	IN  PRTMP_ADAPTER		pAd,
-	IN  PMLME_QUEUE_ELEM	pElem,
-	IN  PRALINK_TIMER_STRUCT pAuthTimer,
-	IN  PSTRING				pSMName,
-	IN  USHORT				SeqNo,
-	IN  PUCHAR				pNewElement,
-	IN  ULONG				ElementLen)
-{
-	USHORT             Alg, Seq, Status;
-	UCHAR              Addr[6];
-    ULONG              Timeout;
-    HEADER_802_11      AuthHdr;
-    BOOLEAN            TimerCancelled;
-    NDIS_STATUS        NStatus;
-    PUCHAR             pOutBuffer = NULL;
-    ULONG              FrameLen = 0, tmp = 0;
-
-	// Block all authentication request durning WPA block period
-	if (pAd->StaCfg.bBlockAssoc == TRUE)
-	{
-        DBGPRINT(RT_DEBUG_TRACE, ("%s - Block Auth request durning WPA block period!\n", pSMName));
-        pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-        Status = MLME_STATE_MACHINE_REJECT;
-        MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
-	}
-    else if(MlmeAuthReqSanity(pAd, pElem->Msg, pElem->MsgLen, Addr, &Timeout, &Alg))
-    {
-	/* reset timer */
-		RTMPCancelTimer(pAuthTimer, &TimerCancelled);
-
-        COPY_MAC_ADDR(pAd->MlmeAux.Bssid, Addr);
-        pAd->MlmeAux.Alg  = Alg;
-        Seq = SeqNo;
-        Status = MLME_SUCCESS;
-
-        NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-        if(NStatus != NDIS_STATUS_SUCCESS)
-        {
-            DBGPRINT(RT_DEBUG_TRACE, ("%s - MlmeAuthReqAction(Alg:%d) allocate memory failed\n", pSMName, Alg));
-            pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-            Status = MLME_FAIL_NO_RESOURCE;
-            MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
-            return FALSE;
-        }
-
-        DBGPRINT(RT_DEBUG_TRACE, ("%s - Send AUTH request seq#1 (Alg=%d)...\n", pSMName, Alg));
-        MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr, pAd->MlmeAux.Bssid);
-        MakeOutgoingFrame(pOutBuffer,           &FrameLen,
-                          sizeof(HEADER_802_11),&AuthHdr,
-                          2,                    &Alg,
-                          2,                    &Seq,
-                          2,                    &Status,
-                          END_OF_ARGS);
-
-		if (pNewElement && ElementLen)
-		{
-			MakeOutgoingFrame(pOutBuffer+FrameLen,	&tmp,
-							  ElementLen,			pNewElement,
-				  END_OF_ARGS);
-			FrameLen += tmp;
-		}
-
-        MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-		RTMPSetTimer(pAuthTimer, Timeout);
-		return TRUE;
-    }
-    else
-    {
-        DBGPRINT_ERR(("%s - MlmeAuthReqAction() sanity check failed\n", pSMName));
-		return FALSE;
-    }
-
-	return TRUE;
-}
diff --git a/drivers/staging/rt3090/sta/auth_rsp.c b/drivers/staging/rt3090/sta/auth_rsp.c
deleted file mode 100644
index 207bfea..0000000
--- a/drivers/staging/rt3090/sta/auth_rsp.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	auth_rsp.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	John		2004-10-1		copy from RT2560
-*/
-
-#include "../rt_config.h"
-
-
-/*
-    ==========================================================================
-    Description:
-        authentication state machine init procedure
-    Parameters:
-        Sm - the state machine
-
-	IRQL = PASSIVE_LEVEL
-
-    ==========================================================================
- */
-VOID AuthRspStateMachineInit(
-    IN PRTMP_ADAPTER pAd,
-    IN PSTATE_MACHINE Sm,
-    IN STATE_MACHINE_FUNC Trans[])
-{
-    StateMachineInit(Sm, Trans, MAX_AUTH_RSP_STATE, MAX_AUTH_RSP_MSG, (STATE_MACHINE_FUNC)Drop, AUTH_RSP_IDLE, AUTH_RSP_MACHINE_BASE);
-
-    // column 1
-    StateMachineSetAction(Sm, AUTH_RSP_IDLE, MT2_PEER_DEAUTH, (STATE_MACHINE_FUNC)PeerDeauthAction);
-
-    // column 2
-    StateMachineSetAction(Sm, AUTH_RSP_WAIT_CHAL, MT2_PEER_DEAUTH, (STATE_MACHINE_FUNC)PeerDeauthAction);
-
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
-*/
-VOID PeerAuthSimpleRspGenAndSend(
-    IN PRTMP_ADAPTER pAd,
-    IN PHEADER_802_11 pHdr80211,
-    IN USHORT Alg,
-    IN USHORT Seq,
-    IN USHORT Reason,
-    IN USHORT Status)
-{
-    HEADER_802_11     AuthHdr;
-    ULONG             FrameLen = 0;
-    PUCHAR            pOutBuffer = NULL;
-    NDIS_STATUS       NStatus;
-
-    if (Reason != MLME_SUCCESS)
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("Peer AUTH fail...\n"));
-        return;
-    }
-
-	//Get an unused nonpaged memory
-    NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
-    if (NStatus != NDIS_STATUS_SUCCESS)
-        return;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("Send AUTH response (seq#2)...\n"));
-    MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, pHdr80211->Addr2, pAd->MlmeAux.Bssid);
-    MakeOutgoingFrame(pOutBuffer,               &FrameLen,
-                      sizeof(HEADER_802_11),    &AuthHdr,
-                      2,                        &Alg,
-                      2,                        &Seq,
-                      2,                        &Reason,
-                      END_OF_ARGS);
-    MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
-*/
-VOID PeerDeauthAction(
-    IN PRTMP_ADAPTER pAd,
-    IN PMLME_QUEUE_ELEM Elem)
-{
-    UCHAR       Addr2[MAC_ADDR_LEN];
-    USHORT      Reason;
-
-    if (PeerDeauthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason))
-    {
-        if (INFRA_ON(pAd)
-			&& MAC_ADDR_EQUAL(Addr2, pAd->CommonCfg.Bssid)
-			)
-        {
-            DBGPRINT(RT_DEBUG_TRACE,("AUTH_RSP - receive DE-AUTH from our AP (Reason=%d)\n", Reason));
-
-
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-		RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0);
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-
-
-			// send wireless event - for deauthentication
-			if (pAd->CommonCfg.bWirelessEvent)
-				RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-
-            LinkDown(pAd, TRUE);
-        }
-    }
-    else
-    {
-        DBGPRINT(RT_DEBUG_TRACE,("AUTH_RSP - PeerDeauthAction() sanity check fail\n"));
-    }
-}
diff --git a/drivers/staging/rt3090/sta/connect.c b/drivers/staging/rt3090/sta/connect.c
deleted file mode 100644
index 4aa35ee..0000000
--- a/drivers/staging/rt3090/sta/connect.c
+++ /dev/null
@@ -1,2759 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	connect.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	John			2004-08-08			Major modification from RT2560
-*/
-
-#include "../rt_config.h"
-
-
-UCHAR	CipherSuiteWpaNoneTkip[] = {
-		0x00, 0x50, 0xf2, 0x01,	// oui
-		0x01, 0x00,				// Version
-		0x00, 0x50, 0xf2, 0x02,	// Multicast
-		0x01, 0x00,				// Number of unicast
-		0x00, 0x50, 0xf2, 0x02,	// unicast
-		0x01, 0x00,				// number of authentication method
-		0x00, 0x50, 0xf2, 0x00	// authentication
-		};
-UCHAR	CipherSuiteWpaNoneTkipLen = (sizeof(CipherSuiteWpaNoneTkip) / sizeof(UCHAR));
-
-UCHAR	CipherSuiteWpaNoneAes[] = {
-		0x00, 0x50, 0xf2, 0x01,	// oui
-		0x01, 0x00,				// Version
-		0x00, 0x50, 0xf2, 0x04,	// Multicast
-		0x01, 0x00,				// Number of unicast
-		0x00, 0x50, 0xf2, 0x04,	// unicast
-		0x01, 0x00,				// number of authentication method
-		0x00, 0x50, 0xf2, 0x00	// authentication
-		};
-UCHAR	CipherSuiteWpaNoneAesLen = (sizeof(CipherSuiteWpaNoneAes) / sizeof(UCHAR));
-
-// The following MACRO is called after 1. starting an new IBSS, 2. succesfully JOIN an IBSS,
-// or 3. succesfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS
-// All settings successfuly negotiated furing MLME state machines become final settings
-// and are copied to pAd->StaActive
-#define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd)                                 \
-{                                                                                       \
-	NdisZeroMemory((_pAd)->CommonCfg.Ssid, MAX_LEN_OF_SSID);							\
-	(_pAd)->CommonCfg.SsidLen = (_pAd)->MlmeAux.SsidLen;                                \
-	NdisMoveMemory((_pAd)->CommonCfg.Ssid, (_pAd)->MlmeAux.Ssid, (_pAd)->MlmeAux.SsidLen); \
-	COPY_MAC_ADDR((_pAd)->CommonCfg.Bssid, (_pAd)->MlmeAux.Bssid);                      \
-	(_pAd)->CommonCfg.Channel = (_pAd)->MlmeAux.Channel;                                \
-	(_pAd)->CommonCfg.CentralChannel = (_pAd)->MlmeAux.CentralChannel;                  \
-	(_pAd)->StaActive.Aid = (_pAd)->MlmeAux.Aid;                                        \
-	(_pAd)->StaActive.AtimWin = (_pAd)->MlmeAux.AtimWin;                                \
-	(_pAd)->StaActive.CapabilityInfo = (_pAd)->MlmeAux.CapabilityInfo;                  \
-	(_pAd)->CommonCfg.BeaconPeriod = (_pAd)->MlmeAux.BeaconPeriod;                      \
-	(_pAd)->StaActive.CfpMaxDuration = (_pAd)->MlmeAux.CfpMaxDuration;                  \
-	(_pAd)->StaActive.CfpPeriod = (_pAd)->MlmeAux.CfpPeriod;                            \
-	(_pAd)->StaActive.SupRateLen = (_pAd)->MlmeAux.SupRateLen;                          \
-	NdisMoveMemory((_pAd)->StaActive.SupRate, (_pAd)->MlmeAux.SupRate, (_pAd)->MlmeAux.SupRateLen);\
-	(_pAd)->StaActive.ExtRateLen = (_pAd)->MlmeAux.ExtRateLen;                          \
-	NdisMoveMemory((_pAd)->StaActive.ExtRate, (_pAd)->MlmeAux.ExtRate, (_pAd)->MlmeAux.ExtRateLen);\
-	NdisMoveMemory(&(_pAd)->CommonCfg.APEdcaParm, &(_pAd)->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));\
-	NdisMoveMemory(&(_pAd)->CommonCfg.APQosCapability, &(_pAd)->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));\
-	NdisMoveMemory(&(_pAd)->CommonCfg.APQbssLoad, &(_pAd)->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));\
-	COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].Addr, (_pAd)->MlmeAux.Bssid);      \
-	(_pAd)->MacTab.Content[BSSID_WCID].Aid = (_pAd)->MlmeAux.Aid;                       \
-	(_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = (_pAd)->StaCfg.PairCipher;\
-	COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.BssId, (_pAd)->MlmeAux.Bssid);\
-	(_pAd)->MacTab.Content[BSSID_WCID].RateLen = (_pAd)->StaActive.SupRateLen + (_pAd)->StaActive.ExtRateLen;\
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = PASSIVE_LEVEL
-
-	==========================================================================
-*/
-VOID MlmeCntlInit(
-	IN PRTMP_ADAPTER pAd,
-	IN STATE_MACHINE *S,
-	OUT STATE_MACHINE_FUNC Trans[])
-{
-	// Control state machine differs from other state machines, the interface
-	// follows the standard interface
-	pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-VOID MlmeCntlMachinePerformAction(
-	IN PRTMP_ADAPTER pAd,
-	IN STATE_MACHINE *S,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	switch(pAd->Mlme.CntlMachine.CurrState)
-	{
-		case CNTL_IDLE:
-			CntlIdleProc(pAd, Elem);
-			break;
-		case CNTL_WAIT_DISASSOC:
-			CntlWaitDisassocProc(pAd, Elem);
-			break;
-		case CNTL_WAIT_JOIN:
-			CntlWaitJoinProc(pAd, Elem);
-			break;
-
-		// CNTL_WAIT_REASSOC is the only state in CNTL machine that does
-		// not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)".
-		// Therefore not protected by NDIS's "only one outstanding OID request"
-		// rule. Which means NDIS may SET OID in the middle of ROAMing attempts.
-		// Current approach is to block new SET request at RTMPSetInformation()
-		// when CntlMachine.CurrState is not CNTL_IDLE
-		case CNTL_WAIT_REASSOC:
-			CntlWaitReassocProc(pAd, Elem);
-			break;
-
-		case CNTL_WAIT_START:
-			CntlWaitStartProc(pAd, Elem);
-			break;
-		case CNTL_WAIT_AUTH:
-			CntlWaitAuthProc(pAd, Elem);
-			break;
-		case CNTL_WAIT_AUTH2:
-			CntlWaitAuthProc2(pAd, Elem);
-			break;
-		case CNTL_WAIT_ASSOC:
-			CntlWaitAssocProc(pAd, Elem);
-			break;
-
-		case CNTL_WAIT_OID_LIST_SCAN:
-			if(Elem->MsgType == MT2_SCAN_CONF)
-			{
-				// Resume TxRing after SCANING complete. We hope the out-of-service time
-				// won't be too long to let upper layer time-out the waiting frames
-				RTMPResumeMsduTransmission(pAd);
-
-				pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-
-                //
-				// Set LED status to previous status.
-				//
-				if (pAd->bLedOnScanning)
-				{
-					pAd->bLedOnScanning = FALSE;
-					RTMPSetLED(pAd, pAd->LedStatus);
-				}
-#ifdef DOT11N_DRAFT3
-				// AP sent a 2040Coexistence mgmt frame, then station perform a scan, and then send back the respone.
-				if (pAd->CommonCfg.BSSCoexist2040.field.InfoReq == 1)
-				{
-					Update2040CoexistFrameAndNotify(pAd, BSSID_WCID, TRUE);
-				}
-#endif // DOT11N_DRAFT3 //
-			}
-			break;
-
-		case CNTL_WAIT_OID_DISASSOC:
-			if (Elem->MsgType == MT2_DISASSOC_CONF)
-			{
-				LinkDown(pAd, FALSE);
-				pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-			}
-			break;
-		default:
-			DBGPRINT_ERR(("!ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType));
-			break;
-	}
-}
-
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-VOID CntlIdleProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	MLME_DISASSOC_REQ_STRUCT   DisassocReq;
-
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
-		return;
-
-	switch(Elem->MsgType)
-	{
-		case OID_802_11_SSID:
-			CntlOidSsidProc(pAd, Elem);
-			break;
-
-		case OID_802_11_BSSID:
-			CntlOidRTBssidProc(pAd,Elem);
-			break;
-
-		case OID_802_11_BSSID_LIST_SCAN:
-			CntlOidScanProc(pAd,Elem);
-			break;
-
-		case OID_802_11_DISASSOCIATE:
-			DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
-			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
-#ifdef WPA_SUPPLICANT_SUPPORT
-            if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI)
-#endif // WPA_SUPPLICANT_SUPPORT //
-            {
-			// Set the AutoReconnectSsid to prevent it reconnect to old SSID
-			// Since calling this indicate user don't want to connect to that SSID anymore.
-			pAd->MlmeAux.AutoReconnectSsidLen= 32;
-			NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
-            }
-			break;
-
-		case MT2_MLME_ROAMING_REQ:
-			CntlMlmeRoamingProc(pAd, Elem);
-			break;
-
-        case OID_802_11_MIC_FAILURE_REPORT_FRAME:
-            WpaMicFailureReportFrame(pAd, Elem);
-            break;
-
-#ifdef QOS_DLS_SUPPORT
-		case RT_OID_802_11_SET_DLS_PARAM:
-			CntlOidDLSSetupProc(pAd, Elem);
-			break;
-#endif // QOS_DLS_SUPPORT //
-
-		default:
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",Elem->MsgType));
-			break;
-	}
-}
-
-VOID CntlOidScanProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	MLME_SCAN_REQ_STRUCT       ScanReq;
-	ULONG                      BssIdx = BSS_NOT_FOUND;
-	BSS_ENTRY                  CurrBss;
-
-#ifdef RALINK_ATE
-/* Disable scanning when ATE is running. */
-	if (ATE_ON(pAd))
-		return;
-#endif // RALINK_ATE //
-
-
-	// record current BSS if network is connected.
-	// 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-	{
-		BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, (PUCHAR)pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel);
-		if (BssIdx != BSS_NOT_FOUND)
-		{
-			NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
-		}
-	}
-
-	// clean up previous SCAN result, add current BSS back to table if any
-	BssTableInit(&pAd->ScanTab);
-	if (BssIdx != BSS_NOT_FOUND)
-	{
-		// DDK Note: If the NIC is associated with a particular BSSID and SSID
-		//    that are not contained in the list of BSSIDs generated by this scan, the
-		//    BSSID description of the currently associated BSSID and SSID should be
-		//    appended to the list of BSSIDs in the NIC's database.
-		// To ensure this, we append this BSS as the first entry in SCAN result
-		NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
-		pAd->ScanTab.BssNr = 1;
-	}
-
-	ScanParmFill(pAd, &ScanReq, (PSTRING) Elem->Msg, Elem->MsgLen, BSS_ANY, SCAN_ACTIVE);
-	MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
-		sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
-	pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
-}
-
-/*
-	==========================================================================
-	Description:
-		Before calling this routine, user desired SSID should already been
-		recorded in CommonCfg.Ssid[]
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-VOID CntlOidSsidProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM * Elem)
-{
-	PNDIS_802_11_SSID          pOidSsid = (NDIS_802_11_SSID *)Elem->Msg;
-	MLME_DISASSOC_REQ_STRUCT   DisassocReq;
-	ULONG					   Now;
-
-
-	// Step 1. record the desired user settings to MlmeAux
-	NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
-	NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
-	pAd->MlmeAux.SsidLen = (UCHAR)pOidSsid->SsidLength;
-	NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
-	pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
-
-	pAd->StaCfg.bAutoConnectByBssid = FALSE;
-
-	//
-	// Update Reconnect Ssid, that user desired to connect.
-	//
-	NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
-	NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
-	pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
-
-	// step 2. find all matching BSS in the lastest SCAN result (inBssTab)
-	//    & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order
-	BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, (PCHAR)pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
-			pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
-	NdisGetSystemUpTime(&Now);
-
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
-		(pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) &&
-		NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) &&
-		MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid))
-	{
-		// Case 1. already connected with an AP who has the desired SSID
-		//         with highest RSSI
-
-		// Add checking Mode "LEAP" for CCX 1.0
-		if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
-			 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
-			 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
-			 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
-			 ) &&
-			(pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
-		{
-			// case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo
-			//          connection process
-			DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
-			DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
-			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
-						sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
-		}
-		else if (pAd->bConfigChanged == TRUE)
-		{
-			// case 1.2 Important Config has changed, we have to reconnect to the same AP
-			DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
-			DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
-			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
-						sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
-		}
-		else
-		{
-			// case 1.3. already connected to the SSID with highest RSSI.
-			DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
-			//
-			// (HCT 12.1) 1c_wlan_mediaevents required
-			// media connect events are indicated when associating with the same AP
-			//
-			if (INFRA_ON(pAd))
-			{
-				//
-				// Since MediaState already is NdisMediaStateConnected
-				// We just indicate the connect event again to meet the WHQL required.
-				//
-				pAd->IndicateMediaState = NdisMediaStateConnected;
-				RTMP_IndicateMediaState(pAd);
-                pAd->ExtraInfo = GENERAL_LINK_UP;   // Update extra information to link is up
-			}
-
-			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-			RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, &pAd->MlmeAux.Bssid[0], NULL, 0);
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-		}
-	}
-	else if (INFRA_ON(pAd))
-	{
-		//
-		// For RT61
-		// [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
-		// RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect
-		// But media status is connected, so the SSID not report correctly.
-		//
-		if (!SSID_EQUAL(pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen))
-		{
-			//
-			// Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event.
-			//
-			pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
-		}
-		// case 2. active INFRA association existent
-		//    roaming is done within miniport driver, nothing to do with configuration
-		//    utility. so upon a new SET(OID_802_11_SSID) is received, we just
-		//    disassociate with the current associated AP,
-		//    then perform a new association with this new SSID, no matter the
-		//    new/old SSID are the same or not.
-		DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
-		DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
-		MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
-					sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
-		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
-	}
-	else
-	{
-		if (ADHOC_ON(pAd))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
-			LinkDown(pAd, FALSE);
-			OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
-			pAd->IndicateMediaState = NdisMediaStateDisconnected;
-			RTMP_IndicateMediaState(pAd);
-            pAd->ExtraInfo = GENERAL_LINK_DOWN;
-			DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
-		}
-
-		if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
-			(pAd->StaCfg.bAutoReconnect == TRUE) &&
-			(pAd->MlmeAux.BssType == BSS_INFRA) &&
-			(MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) == TRUE)
-			)
-		{
-			MLME_SCAN_REQ_STRUCT       ScanReq;
-
-			DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
-			ScanParmFill(pAd, &ScanReq, (PSTRING) pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
-			MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
-			// Reset Missed scan number
-			pAd->StaCfg.LastScanTime = Now;
-		}
-		else
-		{
-
-			pAd->MlmeAux.BssIdx = 0;
-			IterateOnBssTab(pAd);
-		}
-	}
-}
-
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-VOID CntlOidRTBssidProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM * Elem)
-{
-	ULONG       BssIdx;
-	PUCHAR      pOidBssid = (PUCHAR)Elem->Msg;
-	MLME_DISASSOC_REQ_STRUCT    DisassocReq;
-	MLME_JOIN_REQ_STRUCT        JoinReq;
-
-#ifdef RALINK_ATE
-/* No need to perform this routine when ATE is running. */
-	if (ATE_ON(pAd))
-		return;
-#endif // RALINK_ATE //
-
-	// record user desired settings
-	COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
-	pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
-
-	// find the desired BSS in the latest SCAN result table
-	BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
-	if (BssIdx == BSS_NOT_FOUND)
-	{
-		MLME_SCAN_REQ_STRUCT       ScanReq;
-
-		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
-		//pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-
-		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. start a new scan\n"));
-		ScanParmFill(pAd, &ScanReq, (PSTRING) pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
-		MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
-		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
-		// Reset Missed scan number
-		NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime);
-		return;
-	}
-
-	//
-	// Update Reconnect Ssid, that user desired to connect.
-	//
-	NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
-	pAd->MlmeAux.AutoReconnectSsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
-	NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->ScanTab.BssEntry[BssIdx].SsidLen);
-
-	// copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why?
-	// Because we need this entry to become the JOIN target in later on SYNC state machine
-	pAd->MlmeAux.BssIdx = 0;
-	pAd->MlmeAux.SsidBssTab.BssNr = 1;
-	NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
-
-	// Add SSID into MlmeAux for site surey joining hidden SSID
-	pAd->MlmeAux.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
-	NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->MlmeAux.SsidLen);
-
-	{
-		if (INFRA_ON(pAd))
-		{
-			// disassoc from current AP first
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
-			DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
-			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
-						sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
-
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
-		}
-		else
-		{
-			if (ADHOC_ON(pAd))
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
-				LinkDown(pAd, FALSE);
-				OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
-				pAd->IndicateMediaState = NdisMediaStateDisconnected;
-				RTMP_IndicateMediaState(pAd);
-                pAd->ExtraInfo = GENERAL_LINK_DOWN;
-				DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
-			}
-
-			// Change the wepstatus to original wepstatus
-			pAd->StaCfg.WepStatus   = pAd->StaCfg.OrigWepStatus;
-			pAd->StaCfg.PairCipher  = pAd->StaCfg.OrigWepStatus;
-			pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
-
-			// Check cipher suite, AP must have more secured cipher than station setting
-			// Set the Pairwise and Group cipher to match the intended AP setting
-			// We can only connect to AP with less secured cipher setting
-			if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
-			{
-				pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
-
-				if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
-					pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
-				else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
-					pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
-				else	// There is no PairCipher Aux, downgrade our capability to TKIP
-					pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
-			}
-			else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
-			{
-				pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
-
-				if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
-					pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
-				else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
-					pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
-				else	// There is no PairCipher Aux, downgrade our capability to TKIP
-					pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
-
-				// RSN capability
-				pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
-			}
-
-			// Set Mix cipher flag
-			pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
-			/*if (pAd->StaCfg.bMixCipher == TRUE)
-			{
-				// If mix cipher, re-build RSNIE
-				RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
-			}*/
-			// No active association, join the BSS immediately
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
-				pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
-
-			JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
-			MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
-
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
-		}
-	}
-}
-
-// Roaming is the only external request triggering CNTL state machine
-// despite of other "SET OID" operation. All "SET OID" related oerations
-// happen in sequence, because no other SET OID will be sent to this device
-// until the the previous SET operation is complete (successful o failed).
-// So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
-// or been corrupted by other "SET OID"?
-//
-// IRQL = DISPATCH_LEVEL
-VOID CntlMlmeRoamingProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	UCHAR BBPValue = 0;
-
-	DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
-
-	{
-		//Let BBP register at 20MHz to do (fast) roaming.
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-		BBPValue &= (~0x18);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-
-		NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
-		pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
-
-		BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
-		pAd->MlmeAux.BssIdx = 0;
-		IterateOnBssTab(pAd);
-	}
-}
-
-#ifdef QOS_DLS_SUPPORT
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-VOID CntlOidDLSSetupProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	PRT_802_11_DLS		pDLS = (PRT_802_11_DLS)Elem->Msg;
-	MLME_DLS_REQ_STRUCT	MlmeDlsReq;
-	INT					i;
-	USHORT				reason = REASON_UNSPECIFY;
-
-	DBGPRINT(RT_DEBUG_TRACE,("CNTL - (OID set %02x:%02x:%02x:%02x:%02x:%02x with Valid=%d, Status=%d, TimeOut=%d, CountDownTimer=%d)\n",
-		pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5],
-		pDLS->Valid, pDLS->Status, pDLS->TimeOut, pDLS->CountDownTimer));
-
-	if (!pAd->CommonCfg.bDLSCapable)
-		return;
-
-	// DLS will not be supported when Adhoc mode
-	if (INFRA_ON(pAd))
-	{
-		for (i = 0; i < MAX_NUM_OF_DLS_ENTRY; i++)
-		{
-			if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
-				(pDLS->TimeOut == pAd->StaCfg.DLSEntry[i].TimeOut) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
-			{
-				// 1. Same setting, just drop it
-				DBGPRINT(RT_DEBUG_TRACE,("CNTL - setting unchanged\n"));
-				break;
-			}
-			else if (!pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
-				MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
-			{
-				// 2. Disable DLS link case, just tear down DLS link
-				reason = REASON_QOS_UNWANTED_MECHANISM;
-				pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
-				pAd->StaCfg.DLSEntry[i].Status	= DLS_NONE;
-				DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
-				MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
-				DBGPRINT(RT_DEBUG_TRACE,("CNTL - start tear down procedure\n"));
-				break;
-			}
-			else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && !pAd->StaCfg.DLSEntry[i].Valid)
-			{
-				// 3. Enable case, start DLS setup procedure
-				NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
-
-				//Update countdown timer
-				pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
-				DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
-				MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
-				DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS setup case\n"));
-				break;
-			}
-			else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
-				(pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) && !MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
-			{
-				// 4. update mac case, tear down old DLS and setup new DLS
-				reason = REASON_QOS_UNWANTED_MECHANISM;
-				pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
-				pAd->StaCfg.DLSEntry[i].Status	= DLS_NONE;
-				DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
-				MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
-				NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
-				DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
-				MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
-				DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS tear down and restart case\n"));
-				break;
-			}
-			else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
-				MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr) && (pAd->StaCfg.DLSEntry[i].TimeOut != pDLS->TimeOut))
-			{
-				// 5. update timeout case, start DLS setup procedure (no tear down)
-				pAd->StaCfg.DLSEntry[i].TimeOut	= pDLS->TimeOut;
-				//Update countdown timer
-				pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
-				DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
-				MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
-				DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS update timeout case\n"));
-				break;
-			}
-			else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
-				(pAd->StaCfg.DLSEntry[i].Status != DLS_FINISH) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
-			{
-				// 6. re-setup case, start DLS setup procedure (no tear down)
-				DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
-				MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
-				DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS retry setup procedure\n"));
-				break;
-			}
-			else
-			{
-				DBGPRINT(RT_DEBUG_WARN,("CNTL - DLS not changed in entry - %d - Valid=%d, Status=%d, TimeOut=%d\n",
-					i, pAd->StaCfg.DLSEntry[i].Valid, pAd->StaCfg.DLSEntry[i].Status, pAd->StaCfg.DLSEntry[i].TimeOut));
-			}
-		}
-	}
-}
-#endif // QOS_DLS_SUPPORT //
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-VOID CntlWaitDisassocProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	MLME_START_REQ_STRUCT     StartReq;
-
-	if (Elem->MsgType == MT2_DISASSOC_CONF)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
-
-	    if (pAd->CommonCfg.bWirelessEvent)
-		{
-			RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-		}
-
-		LinkDown(pAd, FALSE);
-
-		// case 1. no matching BSS, and user wants ADHOC, so we just start a new one
-		if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
-			StartParmFill(pAd, &StartReq, (PCHAR)pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
-			MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
-		}
-		// case 2. try each matched BSS
-		else
-		{
-			pAd->MlmeAux.BssIdx = 0;
-
-			IterateOnBssTab(pAd);
-		}
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-VOID CntlWaitJoinProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	USHORT                      Reason;
-	MLME_AUTH_REQ_STRUCT        AuthReq;
-
-	if (Elem->MsgType == MT2_JOIN_CONF)
-	{
-		NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
-		if (Reason == MLME_SUCCESS)
-		{
-			// 1. joined an IBSS, we are pretty much done here
-			if (pAd->MlmeAux.BssType == BSS_ADHOC)
-			{
-			    //
-				// 5G bands rules of Japan:
-				// Ad hoc must be disabled in W53(ch52,56,60,64) channels.
-				//
-				if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
-                      RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
-				   )
-				{
-					pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-					DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
-					return;
-				}
-
-				LinkUp(pAd, BSS_ADHOC);
-				pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-				DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
-				pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
-				pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
-
-                pAd->IndicateMediaState = NdisMediaStateConnected;
-                pAd->ExtraInfo = GENERAL_LINK_UP;
-			}
-			// 2. joined a new INFRA network, start from authentication
-			else
-			{
-				{
-					// either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
-					if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
-						(pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
-					{
-						AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, AUTH_MODE_KEY);
-					}
-					else
-					{
-						AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, AUTH_MODE_OPEN);
-					}
-					MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
-							sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
-				}
-
-				pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
-			}
-		}
-		else
-		{
-			// 3. failed, try next BSS
-			pAd->MlmeAux.BssIdx++;
-			IterateOnBssTab(pAd);
-		}
-	}
-}
-
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-VOID CntlWaitStartProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	USHORT      Result;
-
-	if (Elem->MsgType == MT2_START_CONF)
-	{
-		NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
-		if (Result == MLME_SUCCESS)
-		{
-		    //
-			// 5G bands rules of Japan:
-			// Ad hoc must be disabled in W53(ch52,56,60,64) channels.
-			//
-			if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
-                  RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
-			   )
-			{
-				pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-				DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
-				return;
-			}
-#ifdef DOT11_N_SUPPORT
-			NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
-			if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
-			{
-				N_ChannelCheck(pAd);
-				SetCommonHT(pAd);
-				NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
-				RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
-				pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
-				NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
-				COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
-
-				if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth  == BW_40) &&
-					(pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
-				{
-					pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
-				}
-				else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth  == BW_40) &&
-						 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
-				{
-					pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
-				}
-			}
-			else
-#endif // DOT11_N_SUPPORT //
-			{
-				pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
-			}
-			LinkUp(pAd, BSS_ADHOC);
-			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-			// Before send beacon, driver need do radar detection
-			if ((pAd->CommonCfg.Channel > 14 )
-				&& (pAd->CommonCfg.bIEEE80211H == 1)
-				&& RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
-			{
-				pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
-				pAd->CommonCfg.RadarDetect.RDCount = 0;
-#ifdef DFS_SUPPORT
-				BbpRadarDetectionStart(pAd);
-#endif // DFS_SUPPORT //
-			}
-
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
-				pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
-				pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
-		}
-		else
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
-			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-		}
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-VOID CntlWaitAuthProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	USHORT                       Reason;
-	MLME_ASSOC_REQ_STRUCT        AssocReq;
-	MLME_AUTH_REQ_STRUCT         AuthReq;
-
-	if (Elem->MsgType == MT2_AUTH_CONF)
-	{
-		NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
-		if (Reason == MLME_SUCCESS)
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
-			AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
-						  ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
-
-			{
-				MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
-							sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
-
-				pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
-			}
-		}
-		else
-		{
-			// This fail may because of the AP already keep us in its MAC table without
-			// ageing-out. The previous authentication attempt must have let it remove us.
-			// so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
-			{
-				if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
-					(pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
-				{
-					// either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
-					AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, AUTH_MODE_KEY);
-				}
-				else
-				{
-					AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, AUTH_MODE_OPEN);
-				}
-				MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
-							sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
-
-			}
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
-		}
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-VOID CntlWaitAuthProc2(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	USHORT                       Reason;
-	MLME_ASSOC_REQ_STRUCT        AssocReq;
-	MLME_AUTH_REQ_STRUCT         AuthReq;
-
-	if (Elem->MsgType == MT2_AUTH_CONF)
-	{
-		NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
-		if (Reason == MLME_SUCCESS)
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
-			AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
-							  ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
-			{
-				MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
-							sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
-
-				pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
-			}
-		}
-		else
-		{
-			if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
-				 (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
-				AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
-				MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
-							sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
-
-				pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
-			}
-			else
-			{
-				// not success, try next BSS
-				DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
-				pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
-				pAd->MlmeAux.BssIdx++;
-				IterateOnBssTab(pAd);
-			}
-		}
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-VOID CntlWaitAssocProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	USHORT      Reason;
-
-	if (Elem->MsgType == MT2_ASSOC_CONF)
-	{
-		NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
-		if (Reason == MLME_SUCCESS)
-		{
-			if (pAd->CommonCfg.bWirelessEvent)
-			{
-				RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-			}
-
-			LinkUp(pAd, BSS_INFRA);
-			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
-		}
-		else
-		{
-			// not success, try next BSS
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
-			pAd->MlmeAux.BssIdx++;
-			IterateOnBssTab(pAd);
-		}
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-VOID CntlWaitReassocProc(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	USHORT      Result;
-
-	if (Elem->MsgType == MT2_REASSOC_CONF)
-	{
-		NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
-		if (Result == MLME_SUCCESS)
-		{
-			// send wireless event - for association
-			if (pAd->CommonCfg.bWirelessEvent)
-				RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-
-			//
-			// NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
-			//
-			LinkUp(pAd, BSS_INFRA);
-
-			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
-		}
-		else
-		{
-			// reassoc failed, try to pick next BSS in the BSS Table
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
-			{
-				pAd->MlmeAux.RoamIdx++;
-				IterateOnBssTab2(pAd);
-			}
-		}
-	}
-}
-
-
-VOID	AdhocTurnOnQos(
-	IN  PRTMP_ADAPTER pAd)
-{
-#define AC0_DEF_TXOP		0
-#define AC1_DEF_TXOP		0
-#define AC2_DEF_TXOP		94
-#define AC3_DEF_TXOP		47
-
-	// Turn on QOs if use HT rate.
-	if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
-	{
-		pAd->CommonCfg.APEdcaParm.bValid = TRUE;
-		pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
-		pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
-		pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
-		pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
-
-		pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
-		pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
-		pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
-		pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
-
-		pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10;
-		pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6;
-		pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
-		pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
-
-		pAd->CommonCfg.APEdcaParm.Txop[0]  = 0;
-		pAd->CommonCfg.APEdcaParm.Txop[1]  = 0;
-		pAd->CommonCfg.APEdcaParm.Txop[2]  = AC2_DEF_TXOP;
-		pAd->CommonCfg.APEdcaParm.Txop[3]  = AC3_DEF_TXOP;
-	}
-	AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-VOID LinkUp(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR BssType)
-{
-	ULONG	Now;
-	UINT32	Data;
-	BOOLEAN	Cancelled;
-	UCHAR	Value = 0, idx = 0, HashIdx = 0;
-	MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry = NULL;
-
-	// Init ChannelQuality to prevent DEAD_CQI at initial LinkUp
-	pAd->Mlme.ChannelQuality = 50;
-
-	pEntry = MacTableLookup(pAd, pAd->CommonCfg.Bssid);
-	if (pEntry)
-	{
-		MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
-		pEntry = NULL;
-	}
-
-
-	pEntry = &pAd->MacTab.Content[BSSID_WCID];
-
-	//
-	// ASSOC - DisassocTimeoutAction
-	// CNTL - Dis-associate successful
-	// !!! LINK DOWN !!!
-	// [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
-	//
-	// To prevent DisassocTimeoutAction to call Link down after we link up,
-	// cancel the DisassocTimer no matter what it start or not.
-	//
-	RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer,  &Cancelled);
-
-	COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
-
-#ifdef DOT11_N_SUPPORT
-	COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
-#endif // DOT11_N_SUPPORT //
-
-#ifdef RTMP_MAC_PCI
-	// Before power save before link up function, We will force use 1R.
-	// So after link up, check Rx antenna # again.
-	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
-	if(pAd->Antenna.field.RxPath == 3)
-	{
-		Value |= (0x10);
-	}
-	else if(pAd->Antenna.field.RxPath == 2)
-	{
-		Value |= (0x8);
-	}
-	else if(pAd->Antenna.field.RxPath == 1)
-	{
-		Value |= (0x0);
-	}
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
-	pAd->StaCfg.BBPR3 = Value;
-#endif // RTMP_MAC_PCI //
-
-	if (BssType == BSS_ADHOC)
-	{
-		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
-
-#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
-		// No carrier detection when adhoc
-		// CarrierDetectionStop(pAd);
-		pAd->CommonCfg.CarrierDetect.CD_State = CD_NORMAL;
-#endif // CARRIER_DETECTION_SUPPORT //
-
-#ifdef DOT11_N_SUPPORT
-		if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
-			AdhocTurnOnQos(pAd);
-#endif // DOT11_N_SUPPORT //
-
-		DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
-	}
-	else
-	{
-		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
-
-		DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
-	}
-
-		// 3*3
-		// reset Tx beamforming bit
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
-		Value &= (~0x01);
-		Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
-
-#ifdef DOT11_N_SUPPORT
-	// Change to AP channel
-        if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
-	{
-		// Must using 40MHz.
-		pAd->CommonCfg.BBPCurrentBW = BW_40;
-		AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
-		AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
-
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
-		Value &= (~0x18);
-		Value |= 0x10;
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
-
-		//  RX : control channel at lower
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
-		Value &= (~0x20);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
-#ifdef RTMP_MAC_PCI
-            pAd->StaCfg.BBPR3 = Value;
-#endif // RTMP_MAC_PCI //
-
-		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
-		Data &= 0xfffffffe;
-		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
-
-		if (pAd->MACVersion == 0x28600100)
-		{
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
-                DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
-	}
-		else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
-	    {
-		    // Must using 40MHz.
-			pAd->CommonCfg.BBPCurrentBW = BW_40;
-			AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
-		    AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
-
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
-		Value &= (~0x18);
-		Value |= 0x10;
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
-
-		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
-		Data |= 0x1;
-		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
-
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
-		    Value |= (0x20);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
-#ifdef RTMP_MAC_PCI
-            pAd->StaCfg.BBPR3 = Value;
-#endif // RTMP_MAC_PCI //
-
-		if (pAd->MACVersion == 0x28600100)
-		{
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
-			    DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
-		}
-
-		    DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
-	    }
-	    else
-#endif // DOT11_N_SUPPORT //
-	    {
-		    pAd->CommonCfg.BBPCurrentBW = BW_20;
-		pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
-			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
-			Value &= (~0x18);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
-
-			RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
-			Data &= 0xfffffffe;
-			RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
-
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
-			Value &= (~0x20);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
-#ifdef RTMP_MAC_PCI
-            pAd->StaCfg.BBPR3 = Value;
-#endif // RTMP_MAC_PCI //
-
-			if (pAd->MACVersion == 0x28600100)
-			{
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
-				DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
-			}
-
-		    DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
-	}
-
-	RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
-	//
-	// Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
-	//
-	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
-		BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
-
-#ifdef DOT11_N_SUPPORT
-	DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
-#endif // DOT11_N_SUPPORT //
-
-		AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
-
-	AsicSetSlotTime(pAd, TRUE);
-	AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
-
-
-	// Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
-	AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
-
-#ifdef DOT11_N_SUPPORT
-	if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
-	{
-		// Update HT protectionfor based on AP's operating mode.
-	if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
-	{
-		AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode,  ALLN_SETPROTECT, FALSE, TRUE);
-	}
-	else
-			AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode,  ALLN_SETPROTECT, FALSE, FALSE);
-	}
-#endif // DOT11_N_SUPPORT //
-
-	NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
-
-	NdisGetSystemUpTime(&Now);
-	pAd->StaCfg.LastBeaconRxTime = Now;   // last RX timestamp
-
-	if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
-		CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
-	{
-		MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
-	}
-
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
-
-	if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
-	{
-#ifdef DFS_SUPPORT
-		RadarDetectionStop(pAd);
-#endif // DFS_SUPPORT //
-	}
-	pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
-
-	if (BssType == BSS_ADHOC)
-	{
-		MakeIbssBeacon(pAd);
-		if ((pAd->CommonCfg.Channel > 14)
-			&& (pAd->CommonCfg.bIEEE80211H == 1)
-			&& RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
-		{
-			; //Do nothing
-		}
-		else
-		{
-			AsicEnableIbssSync(pAd);
-		}
-
-		// In ad hoc mode, use MAC table from index 1.
-		// p.s ASIC use all 0xff as termination of WCID table search.To prevent it's 0xff-ff-ff-ff-ff-ff, Write 0 here.
-		RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
-		RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
-
-		// If WEP is enabled, add key material and cipherAlg into Asic
-		// Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
-
-		if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
-		{
-			PUCHAR	Key;
-			UCHAR	CipherAlg;
-
-			for (idx=0; idx < SHARE_KEY_NUM; idx++)
-		{
-				CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
-			Key = pAd->SharedKey[BSS0][idx].Key;
-
-				if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
-				{
-					// Set key material and cipherAlg to Asic
-				AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
-
-                    if (idx == pAd->StaCfg.DefaultKeyId)
-					{
-						// Update WCID attribute table and IVEIV table for this group key table
-						RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
-					}
-				}
-
-
-			}
-		}
-		// If WPANone is enabled, add key material and cipherAlg into Asic
-		// Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
-		else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
-		{
-			pAd->StaCfg.DefaultKeyId = 0;	// always be zero
-
-            NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
-							pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
-			NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
-
-            if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
-            {
-			NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
-			NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
-            }
-
-			// Decide its ChiperAlg
-			if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
-				pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
-			else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
-				pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
-			else
-            {
-                DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
-				pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
-            }
-
-			// Set key material and cipherAlg to Asic
-			AsicAddSharedKeyEntry(pAd,
-								  BSS0,
-								  0,
-								  pAd->SharedKey[BSS0][0].CipherAlg,
-								  pAd->SharedKey[BSS0][0].Key,
-								  pAd->SharedKey[BSS0][0].TxMic,
-								  pAd->SharedKey[BSS0][0].RxMic);
-
-            // Update WCID attribute table and IVEIV table for this group key table
-			RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
-
-		}
-
-	}
-	else // BSS_INFRA
-	{
-		// Check the new SSID with last SSID
-		while (Cancelled == TRUE)
-		{
-			if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
-			{
-				if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
-				{
-					// Link to the old one no linkdown is required.
-					break;
-				}
-			}
-			// Send link down event before set to link up
-			pAd->IndicateMediaState = NdisMediaStateDisconnected;
-			RTMP_IndicateMediaState(pAd);
-            pAd->ExtraInfo = GENERAL_LINK_DOWN;
-			DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
-			break;
-		}
-
-		//
-		// On WPA mode, Remove All Keys if not connect to the last BSSID
-		// Key will be set after 4-way handshake.
-		//
-		if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-		{
-			ULONG		IV;
-
-			// Remove all WPA keys
-			RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-			RTMPWPARemoveAllKeys(pAd);
-			pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-			pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
-
-			// Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
-			// If IV related values are too large in GroupMsg2, AP would ignore this message.
-			IV = 1;
-			IV |= (pAd->StaCfg.DefaultKeyId << 30);
-			AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
-			//RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-		}
-
-		// NOTE:
-		// the decision of using "short slot time" or not may change dynamically due to
-		// new STA association to the AP. so we have to decide that upon parsing BEACON, not here
-
-		// NOTE:
-		// the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
-		// due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
-
-		ComposePsPoll(pAd);
-		ComposeNullFrame(pAd);
-
-			AsicEnableBssSync(pAd);
-
-		// Add BSSID to WCID search table
-		AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
-
-		// If WEP is enabled, add paiewise and shared key
-#ifdef WPA_SUPPLICANT_SUPPORT
-        if (((pAd->StaCfg.WpaSupplicantUP)&&
-             (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
-             (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
-            ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
-              (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
-#else
-		if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
-#endif // WPA_SUPPLICANT_SUPPORT //
-		{
-			PUCHAR	Key;
-			UCHAR	CipherAlg;
-
-			for (idx=0; idx < SHARE_KEY_NUM; idx++)
-		{
-				CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
-			Key = pAd->SharedKey[BSS0][idx].Key;
-
-				if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
-				{
-					// Set key material and cipherAlg to Asic
-				AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
-
-					if (idx == pAd->StaCfg.DefaultKeyId)
-					{
-						// Assign group key info
-						RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
-
-						pEntry->Aid = BSSID_WCID;
-						// Assign pairwise key info
-						RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
-					}
-				}
-			}
-		}
-
-		// only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
-		// should wait until at least 2 active nodes in this BSSID.
-		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
-
-        // For GUI ++
-		if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
-		{
-			pAd->IndicateMediaState = NdisMediaStateConnected;
-			pAd->ExtraInfo = GENERAL_LINK_UP;
-			RTMP_IndicateMediaState(pAd);
-		}
-		else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
-				 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
-		{
-#ifdef WPA_SUPPLICANT_SUPPORT
-			if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)
-#endif // WPA_SUPPLICANT_SUPPORT //
-				RTMPSetTimer(&pAd->Mlme.LinkDownTimer, LINK_DOWN_TIMEOUT);
-		}
-        // --
-
-		// Add BSSID in my MAC Table.
-        NdisAcquireSpinLock(&pAd->MacTabLock);
-		// add this MAC entry into HASH table
-		if (pEntry)
-		{
-			HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
-			if (pAd->MacTab.Hash[HashIdx] == NULL)
-			{
-				pAd->MacTab.Hash[HashIdx] = pEntry;
-			}
-			else
-			{
-				pCurrEntry = pAd->MacTab.Hash[HashIdx];
-				while (pCurrEntry->pNext != NULL)
-				{
-					pCurrEntry = pCurrEntry->pNext;
-				}
-				pCurrEntry->pNext = pEntry;
-			}
-		}
-		RTMPMoveMemory(pEntry->Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
-		pEntry->Aid = BSSID_WCID;
-		pEntry->pAd = pAd;
-		pEntry->ValidAsCLI = TRUE;	//Although this is bssid..still set ValidAsCl
-		pAd->MacTab.Size = 1;	// infra mode always set MACtab size =1.
-		pEntry->Sst = SST_ASSOC;
-		pEntry->AuthState = SST_ASSOC;
-		pEntry->AuthMode = pAd->StaCfg.AuthMode;
-		pEntry->WepStatus = pAd->StaCfg.WepStatus;
-		if (pEntry->AuthMode < Ndis802_11AuthModeWPA)
-		{
-			pEntry->WpaState = AS_NOTUSE;
-			pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
-		}
-		else
-		{
-			pEntry->WpaState = AS_PTKSTART;
-			pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
-		}
-		NdisReleaseSpinLock(&pAd->MacTabLock);
-
-		DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!!  ClientStatusFlags=%lx)\n",
-			pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
-
-
-		MlmeUpdateTxRates(pAd, TRUE, BSS0);
-#ifdef DOT11_N_SUPPORT
-		MlmeUpdateHtTxRates(pAd, BSS0);
-		DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
-#endif // DOT11_N_SUPPORT //
-
-
-		if (pAd->CommonCfg.bAggregationCapable)
-		{
-			if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
-			{
-
-				OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
-				OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
-				CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE);
-				CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE);
-				RTMPSetPiggyBack(pAd, TRUE);
-				DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
-			}
-			else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
-			{
-				CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE);
-				OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
-			}
-		}
-
-		if (pAd->MlmeAux.APRalinkIe != 0x0)
-		{
-#ifdef DOT11_N_SUPPORT
-			if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
-			{
-				AsicEnableRDG(pAd);
-			}
-#endif // DOT11_N_SUPPORT //
-			OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
-			CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
-		}
-		else
-		{
-			OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
-			CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
-		}
-	}
-
-
-#ifdef DOT11_N_SUPPORT
-	DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_CONNECT Event B!.BACapability = %x. ClientStatusFlags = %lx\n", pAd->CommonCfg.BACapability.word, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
-#endif // DOT11_N_SUPPORT //
-
-	// Set LED
-	RTMPSetLED(pAd, LED_LINK_UP);
-
-	pAd->Mlme.PeriodicRound = 0;
-	pAd->Mlme.OneSecPeriodicRound = 0;
-	pAd->bConfigChanged = FALSE;        // Reset config flag
-	pAd->ExtraInfo = GENERAL_LINK_UP;   // Update extra information to link is up
-
-	// Set asic auto fall back
-	{
-		PUCHAR					pTable;
-		UCHAR					TableSize = 0;
-
-		MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
-		AsicUpdateAutoFallBackTable(pAd, pTable);
-	}
-
-	NdisAcquireSpinLock(&pAd->MacTabLock);
-    pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
-    pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
-	if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
-	{
-		pEntry->bAutoTxRateSwitch = FALSE;
-#ifdef DOT11_N_SUPPORT
-		if (pEntry->HTPhyMode.field.MCS == 32)
-			pEntry->HTPhyMode.field.ShortGI = GI_800;
-
-		if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
-			pEntry->HTPhyMode.field.STBC = STBC_NONE;
-#endif // DOT11_N_SUPPORT //
-		// If the legacy mode is set, overwrite the transmit setting of this entry.
-		if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
-			RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
-	}
-	else
-		pEntry->bAutoTxRateSwitch = TRUE;
-	NdisReleaseSpinLock(&pAd->MacTabLock);
-
-	//  Let Link Status Page display first initial rate.
-	pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
-	// Select DAC according to HT or Legacy
-	if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
-	{
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
-		Value &= (~0x18);
-		if (pAd->Antenna.field.TxPath == 2)
-		{
-		    Value |= 0x10;
-		}
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
-	}
-	else
-	{
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
-		Value &= (~0x18);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
-	}
-
-#ifdef DOT11_N_SUPPORT
-	if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
-	{
-	}
-	else if (pEntry->MaxRAmpduFactor == 0)
-	{
-	    // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
-	    // Because our Init value is 1 at MACRegTable.
-		RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
-	}
-#endif // DOT11_N_SUPPORT //
-
-	// Patch for Marvel AP to gain high throughput
-	// Need to set as following,
-	// 1. Set txop in register-EDCA_AC0_CFG as 0x60
-	// 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
-	// 3. PBF_MAX_PCNT as 0x1F3FBF9F
-	// 4. kick per two packets when dequeue
-	//
-	// Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
-	//
-	// if 1. Legacy AP WMM on,  or 2. 11n AP, AMPDU disable.  Force turn off burst no matter what bEnableTxBurst is.
-#ifdef DOT11_N_SUPPORT
-	if (!((pAd->CommonCfg.RxStream == 1)&&(pAd->CommonCfg.TxStream == 1)) &&
-		(pAd->StaCfg.bForceTxBurst == FALSE) &&
-		(((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
-		|| ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))))
-	{
-		RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
-		Data  &= 0xFFFFFF00;
-		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
-
-		RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
-		DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
-	}
-	else
-#endif // DOT11_N_SUPPORT //
-	if (pAd->CommonCfg.bEnableTxBurst)
-	{
-		RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
-		Data  &= 0xFFFFFF00;
-		Data  |= 0x60;
-		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
-		pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
-
-		RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
-		DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
-	}
-	else
-	{
-		RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
-		Data  &= 0xFFFFFF00;
-		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
-
-		RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
-		DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
-	}
-
-#ifdef DOT11_N_SUPPORT
-	// Re-check to turn on TX burst or not.
-	if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
-	{
-		pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
-		if (pAd->CommonCfg.bEnableTxBurst)
-		{
-		    UINT32 MACValue = 0;
-			// Force disable  TXOP value in this case. The same action in MLMEUpdateProtect too.
-			// I didn't change PBF_MAX_PCNT setting.
-			RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
-			MACValue  &= 0xFFFFFF00;
-			RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
-			pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
-		}
-	}
-	else
-	{
-		pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
-	}
-#endif // DOT11_N_SUPPORT //
-
-	pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
-	COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
-	DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
-	// BSSID add in one MAC entry too.  Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
-	// Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
-	// Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
-
-	if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
-	{
-#ifdef WPA_SUPPLICANT_SUPPORT
-		if (pAd->StaCfg.WpaSupplicantUP &&
-			(pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
-			(pAd->StaCfg.IEEE8021X == TRUE))
-			;
-		else
-#endif // WPA_SUPPLICANT_SUPPORT //
-		{
-			pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
-			pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
-		}
-	}
-
-	NdisAcquireSpinLock(&pAd->MacTabLock);
-	pEntry->PortSecured = pAd->StaCfg.PortSecured;
-	NdisReleaseSpinLock(&pAd->MacTabLock);
-
-    //
-	// Patch Atheros AP TX will breakdown issue.
-	// AP Model: DLink DWL-8200AP
-	//
-	if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
-	{
-		RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
-	}
-	else
-	{
-		RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
-	}
-
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
-	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
-
-#ifdef DOT11_N_SUPPORT
-#ifdef DOT11N_DRAFT3
-	if ((pAd->CommonCfg.BACapability.field.b2040CoexistScanSup) && (pAd->CommonCfg.Channel <= 11))
-	{
-		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SCAN_2040);
-		BuildEffectedChannelList(pAd);
-	}
-#endif // DOT11N_DRAFT3 //
-#endif // DOT11_N_SUPPORT //
-}
-
-/*
-	==========================================================================
-
-	Routine	Description:
-		Disconnect current BSSID
-
-	Arguments:
-		pAd				- Pointer to our adapter
-		IsReqFromAP		- Request from AP
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-		We need more information to know it's this requst from AP.
-		If yes! we need to do extra handling, for example, remove the WPA key.
-		Otherwise on 4-way handshaking will faied, since the WPA key didn't be
-		remove while auto reconnect.
-		Disconnect request from AP, it means we will start afresh 4-way handshaking
-		on WPA mode.
-
-	==========================================================================
-*/
-VOID LinkDown(
-	IN PRTMP_ADAPTER pAd,
-	IN  BOOLEAN      IsReqFromAP)
-{
-	UCHAR			    i, ByteValue = 0;
-
-	BOOLEAN		Cancelled;
-
-	// Do nothing if monitor mode is on
-	if (MONITOR_ON(pAd))
-		return;
-
-#ifdef RALINK_ATE
-	// Nothing to do in ATE mode.
-	if (ATE_ON(pAd))
-		return;
-#endif // RALINK_ATE //
-	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
-	//Comment the codes, beasue the line 2291 call the same function.
-	//RTMPCancelTimer(&pAd->Mlme.PsPollTimer,		&Cancelled);
-	// Not allow go to sleep within linkdown function.
-	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-
-    if (pAd->CommonCfg.bWirelessEvent)
-	{
-		RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
-
-#ifdef RTMP_MAC_PCI
-    if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
-    {
-	    BOOLEAN Cancelled;
-        pAd->Mlme.bPsPollTimerRunning = FALSE;
-        RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
-    }
-
-	pAd->bPCIclkOff = FALSE;
-#endif // RTMP_MAC_PCI //
-
-    if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
-||	RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND)
-		|| RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
-    {
-        AUTO_WAKEUP_STRUC AutoWakeupCfg;
-		AsicForceWakeup(pAd, TRUE);
-        AutoWakeupCfg.word = 0;
-	    RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-        OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-    }
-#ifdef RTMP_MAC_PCI
-	pAd->bPCIclkOff = FALSE;
-#endif // RTMP_MAC_PCI //
-	if (ADHOC_ON(pAd))		// Adhoc mode link down
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
-
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
-			OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
-			pAd->IndicateMediaState = NdisMediaStateDisconnected;
-		RTMP_IndicateMediaState(pAd);
-            pAd->ExtraInfo = GENERAL_LINK_DOWN;
-			BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
-		DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
-	}
-	else					// Infra structure mode
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
-
-#ifdef QOS_DLS_SUPPORT
-		// DLS tear down frame must be sent before link down
-		// send DLS-TEAR_DOWN message
-		if (pAd->CommonCfg.bDLSCapable)
-		{
-			// tear down local dls table entry
-			for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
-			{
-				if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
-				{
-					pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
-					RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
-				}
-			}
-
-			// tear down peer dls table entry
-			for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
-			{
-				if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status ==  DLS_FINISH))
-				{
-					pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
-					RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
-				}
-			}
-		}
-#endif // QOS_DLS_SUPPORT //
-
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
-
-		// Saved last SSID for linkup comparison
-		pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
-		NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
-		COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
-		if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
-		{
-			pAd->IndicateMediaState = NdisMediaStateDisconnected;
-			RTMP_IndicateMediaState(pAd);
-            pAd->ExtraInfo = GENERAL_LINK_DOWN;
-			DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
-			pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
-		}
-		else
-		{
-            //
-			// If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
-			// Otherwise lost beacon or receive De-Authentication from AP,
-			// then we should delete BSSID from BssTable.
-			// If we don't delete from entry, roaming will fail.
-			//
-			BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
-		}
-
-		// restore back to -
-		//      1. long slot (20 us) or short slot (9 us) time
-		//      2. turn on/off RTS/CTS and/or CTS-to-self protection
-		//      3. short preamble
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
-
-#ifdef EXT_BUILD_CHANNEL_LIST
-		// Country IE of the AP will be evaluated and will be used.
-		if (pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None)
-		{
-			NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pAd->StaCfg.StaOriCountryCode[0], 2);
-			pAd->CommonCfg.Geography = pAd->StaCfg.StaOriGeography;
-			BuildChannelListEx(pAd);
-		}
-#endif // EXT_BUILD_CHANNEL_LIST //
-
-	}
-
-
-	for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
-	{
-		if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
-			MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
-	}
-
-	AsicSetSlotTime(pAd, TRUE); //FALSE);
-	AsicSetEdcaParm(pAd, NULL);
-
-	// Set LED
-	RTMPSetLED(pAd, LED_LINK_DOWN);
-    pAd->LedIndicatorStrength = 0xF0;
-    RTMPSetSignalLED(pAd, -100);	// Force signal strength Led to be turned off, firmware is not done it.
-
-		AsicDisableSync(pAd);
-
-	pAd->Mlme.PeriodicRound = 0;
-	pAd->Mlme.OneSecPeriodicRound = 0;
-
-	if (pAd->StaCfg.BssType == BSS_INFRA)
-	{
-	// Remove StaCfg Information after link down
-	NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
-	NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
-		pAd->CommonCfg.SsidLen = 0;
-	}
-#ifdef DOT11_N_SUPPORT
-	NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
-	NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
-	pAd->MlmeAux.HtCapabilityLen = 0;
-	pAd->MlmeAux.NewExtChannelOffset = 0xff;
-#endif // DOT11_N_SUPPORT //
-
-	// Reset WPA-PSK state. Only reset when supplicant enabled
-	if (pAd->StaCfg.WpaState != SS_NOTUSE)
-	{
-		pAd->StaCfg.WpaState = SS_START;
-		// Clear Replay counter
-		NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
-
-#ifdef QOS_DLS_SUPPORT
-		if (pAd->CommonCfg.bDLSCapable)
-			NdisZeroMemory(pAd->StaCfg.DlsReplayCounter, 8);
-#endif // QOS_DLS_SUPPORT //
-	}
-
-	//
-	// if link down come from AP, we need to remove all WPA keys on WPA mode.
-	// otherwise will cause 4-way handshaking failed, since the WPA key not empty.
-	//
-	if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
-	{
-		// Remove all WPA keys
-		RTMPWPARemoveAllKeys(pAd);
-	}
-
-	// 802.1x port control
-#ifdef WPA_SUPPLICANT_SUPPORT
-	// Prevent clear PortSecured here with static WEP
-	// NetworkManger set security policy first then set SSID to connect AP.
-	if (pAd->StaCfg.WpaSupplicantUP &&
-		(pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
-		(pAd->StaCfg.IEEE8021X == FALSE))
-	{
-		pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
-	}
-	else
-#endif // WPA_SUPPLICANT_SUPPORT //
-	{
-		pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-		pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
-	}
-
-	NdisAcquireSpinLock(&pAd->MacTabLock);
-	NdisZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE));
-	pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
-	NdisReleaseSpinLock(&pAd->MacTabLock);
-
-	pAd->StaCfg.MicErrCnt = 0;
-
-    pAd->IndicateMediaState = NdisMediaStateDisconnected;
-	// Update extra information to link is up
-	pAd->ExtraInfo = GENERAL_LINK_DOWN;
-
-    pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
-
-
-	// Clean association information
-	NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
-	pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
-	pAd->StaCfg.ReqVarIELen = 0;
-	pAd->StaCfg.ResVarIELen = 0;
-
-	//
-	// Reset RSSI value after link down
-	//
-	pAd->StaCfg.RssiSample.AvgRssi0 = 0;
-	pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
-	pAd->StaCfg.RssiSample.AvgRssi1 = 0;
-	pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
-	pAd->StaCfg.RssiSample.AvgRssi2 = 0;
-	pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
-
-	// Restore MlmeRate
-	pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
-	pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
-
-#ifdef DOT11_N_SUPPORT
-	//
-	// After Link down, reset piggy-back setting in ASIC. Disable RDG.
-	//
-	if (pAd->CommonCfg.BBPCurrentBW == BW_40)
-	{
-		pAd->CommonCfg.BBPCurrentBW = BW_20;
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
-		ByteValue &= (~0x18);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
-	}
-#endif // DOT11_N_SUPPORT //
-	// Reset DAC
-	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
-	ByteValue &= (~0x18);
-	if (pAd->Antenna.field.TxPath == 2)
-	{
-	ByteValue |= 0x10;
-	}
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
-
-		RTMPSetPiggyBack(pAd,FALSE);
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
-
-#ifdef DOT11_N_SUPPORT
-	pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
-#endif // DOT11_N_SUPPORT //
-
-	// Restore all settings in the following.
-	AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
-	AsicDisableRDG(pAd);
-	pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
-	pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
-
-#ifdef DOT11_N_SUPPORT
-#ifdef DOT11N_DRAFT3
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SCAN_2040);
-	pAd->CommonCfg.BSSCoexist2040.word = 0;
-	TriEventInit(pAd);
-	for (i = 0; i < (pAd->ChannelListNum - 1); i++)
-	{
-		pAd->ChannelList[i].bEffectedChannel = FALSE;
-	}
-#endif // DOT11N_DRAFT3 //
-#endif // DOT11_N_SUPPORT //
-
-	RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
-// Allow go to sleep after linkdown steps.
-	RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-#ifdef WPA_SUPPLICANT_SUPPORT
-#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
-	if (pAd->StaCfg.WpaSupplicantUP) {
-		//send disassociate event to wpa_supplicant
-		RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, RT_DISASSOC_EVENT_FLAG, NULL, NULL, 0);
-	}
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-	RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0);
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-
-#ifdef RT30xx
-	if ((IS_RT30xx(pAd) || IS_RT3090(pAd)||IS_RT3390(pAd))
-		&&(pAd->Antenna.field.RxPath>1||pAd->Antenna.field.TxPath>1))
-	{
-		RTMP_ASIC_MMPS_DISABLE(pAd);
-	}
-#endif // RT30xx //
-
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-VOID IterateOnBssTab(
-	IN PRTMP_ADAPTER pAd)
-{
-	MLME_START_REQ_STRUCT   StartReq;
-	MLME_JOIN_REQ_STRUCT    JoinReq;
-	ULONG                   BssIdx;
-
-	// Change the wepstatus to original wepstatus
-	pAd->StaCfg.WepStatus   = pAd->StaCfg.OrigWepStatus;
-	pAd->StaCfg.PairCipher  = pAd->StaCfg.OrigWepStatus;
-	pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
-
-	BssIdx = pAd->MlmeAux.BssIdx;
-	if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
-	{
-		// Check cipher suite, AP must have more secured cipher than station setting
-		// Set the Pairwise and Group cipher to match the intended AP setting
-		// We can only connect to AP with less secured cipher setting
-		if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
-		{
-			pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
-
-			if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
-				pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
-			else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
-				pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
-			else	// There is no PairCipher Aux, downgrade our capability to TKIP
-				pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
-		}
-		else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
-		{
-			pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
-
-			if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
-				pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
-			else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
-				pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
-			else	// There is no PairCipher Aux, downgrade our capability to TKIP
-				pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
-
-			// RSN capability
-			pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
-		}
-
-		// Set Mix cipher flag
-		pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
-		/*if (pAd->StaCfg.bMixCipher == TRUE)
-		{
-			// If mix cipher, re-build RSNIE
-			RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
-		}*/
-
-		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
-		JoinParmFill(pAd, &JoinReq, BssIdx);
-		MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
-					&JoinReq);
-		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
-	}
-	else if (pAd->StaCfg.BssType == BSS_ADHOC)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
-		StartParmFill(pAd, &StartReq, (PCHAR)pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
-		MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
-		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
-	}
-	else // no more BSS
-	{
-
-#ifdef DOT11_N_SUPPORT
-#endif // DOT11_N_SUPPORT //
-		{
-			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
-		}
-
-		pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-	}
-}
-
-// for re-association only
-// IRQL = DISPATCH_LEVEL
-VOID IterateOnBssTab2(
-	IN PRTMP_ADAPTER pAd)
-{
-	MLME_REASSOC_REQ_STRUCT ReassocReq;
-	ULONG                   BssIdx;
-	BSS_ENTRY               *pBss;
-
-	BssIdx = pAd->MlmeAux.RoamIdx;
-	pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
-
-	if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
-
-		AsicSwitchChannel(pAd, pBss->Channel, FALSE);
-		AsicLockChannel(pAd, pBss->Channel);
-
-		// reassociate message has the same structure as associate message
-		AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
-					  ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
-		MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
-					sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
-
-		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
-	}
-	else // no more BSS
-	{
-
-#ifdef DOT11_N_SUPPORT
-#endif // DOT11_N_SUPPORT //
-		{
-			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
-		}
-
-		pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-VOID JoinParmFill(
-	IN PRTMP_ADAPTER pAd,
-	IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
-	IN ULONG BssIdx)
-{
-	JoinReq->BssIdx = BssIdx;
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-VOID ScanParmFill(
-	IN PRTMP_ADAPTER pAd,
-	IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
-	IN STRING Ssid[],
-	IN UCHAR SsidLen,
-	IN UCHAR BssType,
-	IN UCHAR ScanType)
-{
-    NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
-	ScanReq->SsidLen = SsidLen;
-	NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
-	ScanReq->BssType = BssType;
-	ScanReq->ScanType = ScanType;
-}
-
-#ifdef QOS_DLS_SUPPORT
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-VOID DlsParmFill(
-	IN PRTMP_ADAPTER pAd,
-	IN OUT MLME_DLS_REQ_STRUCT *pDlsReq,
-	IN PRT_802_11_DLS pDls,
-	IN USHORT reason)
-{
-	pDlsReq->pDLS = pDls;
-	pDlsReq->Reason = reason;
-}
-#endif // QOS_DLS_SUPPORT //
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-VOID StartParmFill(
-	IN PRTMP_ADAPTER pAd,
-	IN OUT MLME_START_REQ_STRUCT *StartReq,
-	IN CHAR Ssid[],
-	IN UCHAR SsidLen)
-{
-	ASSERT(SsidLen <= MAX_LEN_OF_SSID);
-	NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
-	StartReq->SsidLen = SsidLen;
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-VOID AuthParmFill(
-	IN PRTMP_ADAPTER pAd,
-	IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
-	IN PUCHAR pAddr,
-	IN USHORT Alg)
-{
-	COPY_MAC_ADDR(AuthReq->Addr, pAddr);
-	AuthReq->Alg = Alg;
-	AuthReq->Timeout = AUTH_TIMEOUT;
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-#ifdef RTMP_MAC_PCI
-VOID ComposePsPoll(
-	IN PRTMP_ADAPTER pAd)
-{
-	NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
-	pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
-	pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
-	pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
-	COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
-	COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
-}
-
-// IRQL = DISPATCH_LEVEL
-VOID ComposeNullFrame(
-	IN PRTMP_ADAPTER pAd)
-{
-	NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
-	pAd->NullFrame.FC.Type = BTYPE_DATA;
-	pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
-	pAd->NullFrame.FC.ToDs = 1;
-	COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
-	COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
-	COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
-}
-#endif // RTMP_MAC_PCI //
-
-
-
-
-/*
-	==========================================================================
-	Description:
-		Pre-build a BEACON frame in the shared memory
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-ULONG MakeIbssBeacon(
-	IN PRTMP_ADAPTER pAd)
-{
-	UCHAR         DsLen = 1, IbssLen = 2;
-	UCHAR         LocalErpIe[3] = {IE_ERP, 1, 0x04};
-	HEADER_802_11 BcnHdr;
-	USHORT        CapabilityInfo;
-	LARGE_INTEGER FakeTimestamp;
-	ULONG         FrameLen = 0;
-	PTXWI_STRUC	  pTxWI = &pAd->BeaconTxWI;
-	UCHAR         *pBeaconFrame = pAd->BeaconBuf;
-	BOOLEAN       Privacy;
-	UCHAR         SupRate[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR         SupRateLen = 0;
-	UCHAR         ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR         ExtRateLen = 0;
-	UCHAR         RSNIe = IE_WPA;
-
-	if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
-	{
-		SupRate[0] = 0x82; // 1 mbps
-		SupRate[1] = 0x84; // 2 mbps
-		SupRate[2] = 0x8b; // 5.5 mbps
-		SupRate[3] = 0x96; // 11 mbps
-		SupRateLen = 4;
-		ExtRateLen = 0;
-	}
-	else if (pAd->CommonCfg.Channel > 14)
-	{
-		SupRate[0]  = 0x8C;    // 6 mbps, in units of 0.5 Mbps, basic rate
-		SupRate[1]  = 0x12;    // 9 mbps, in units of 0.5 Mbps
-		SupRate[2]  = 0x98;    // 12 mbps, in units of 0.5 Mbps, basic rate
-		SupRate[3]  = 0x24;    // 18 mbps, in units of 0.5 Mbps
-		SupRate[4]  = 0xb0;    // 24 mbps, in units of 0.5 Mbps, basic rate
-		SupRate[5]  = 0x48;    // 36 mbps, in units of 0.5 Mbps
-		SupRate[6]  = 0x60;    // 48 mbps, in units of 0.5 Mbps
-		SupRate[7]  = 0x6c;    // 54 mbps, in units of 0.5 Mbps
-		SupRateLen  = 8;
-		ExtRateLen  = 0;
-
-		//
-		// Also Update MlmeRate & RtsRate for G only & A only
-		//
-		pAd->CommonCfg.MlmeRate = RATE_6;
-		pAd->CommonCfg.RtsRate = RATE_6;
-		pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
-		pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
-		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-	}
-	else
-	{
-		SupRate[0] = 0x82; // 1 mbps
-		SupRate[1] = 0x84; // 2 mbps
-		SupRate[2] = 0x8b; // 5.5 mbps
-		SupRate[3] = 0x96; // 11 mbps
-		SupRateLen = 4;
-
-		ExtRate[0]  = 0x0C;    // 6 mbps, in units of 0.5 Mbps,
-		ExtRate[1]  = 0x12;    // 9 mbps, in units of 0.5 Mbps
-		ExtRate[2]  = 0x18;    // 12 mbps, in units of 0.5 Mbps,
-		ExtRate[3]  = 0x24;    // 18 mbps, in units of 0.5 Mbps
-		ExtRate[4]  = 0x30;    // 24 mbps, in units of 0.5 Mbps,
-		ExtRate[5]  = 0x48;    // 36 mbps, in units of 0.5 Mbps
-		ExtRate[6]  = 0x60;    // 48 mbps, in units of 0.5 Mbps
-		ExtRate[7]  = 0x6c;    // 54 mbps, in units of 0.5 Mbps
-		ExtRateLen  = 8;
-	}
-
-	pAd->StaActive.SupRateLen = SupRateLen;
-	NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
-	pAd->StaActive.ExtRateLen = ExtRateLen;
-	NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
-
-	// compose IBSS beacon frame
-	MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
-	Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
-			  (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
-			  (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
-	CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
-
-	MakeOutgoingFrame(pBeaconFrame,                &FrameLen,
-					  sizeof(HEADER_802_11),           &BcnHdr,
-					  TIMESTAMP_LEN,                   &FakeTimestamp,
-					  2,                               &pAd->CommonCfg.BeaconPeriod,
-					  2,                               &CapabilityInfo,
-					  1,                               &SsidIe,
-					  1,                               &pAd->CommonCfg.SsidLen,
-					  pAd->CommonCfg.SsidLen,          pAd->CommonCfg.Ssid,
-					  1,                               &SupRateIe,
-					  1,                               &SupRateLen,
-					  SupRateLen,                      SupRate,
-					  1,                               &DsIe,
-					  1,                               &DsLen,
-					  1,                               &pAd->CommonCfg.Channel,
-					  1,                               &IbssIe,
-					  1,                               &IbssLen,
-					  2,                               &pAd->StaActive.AtimWin,
-					  END_OF_ARGS);
-
-	// add ERP_IE and EXT_RAE IE of in 802.11g
-	if (ExtRateLen)
-	{
-		ULONG	tmp;
-
-		MakeOutgoingFrame(pBeaconFrame + FrameLen,         &tmp,
-						  3,                               LocalErpIe,
-						  1,                               &ExtRateIe,
-						  1,                               &ExtRateLen,
-						  ExtRateLen,                      ExtRate,
-						  END_OF_ARGS);
-		FrameLen += tmp;
-	}
-
-	// If adhoc secruity is set for WPA-None, append the cipher suite IE
-	if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
-	{
-		ULONG tmp;
-        RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
-
-		MakeOutgoingFrame(pBeaconFrame + FrameLen,		&tmp,
-						  1,					&RSNIe,
-						  1,					&pAd->StaCfg.RSNIE_Len,
-						  pAd->StaCfg.RSNIE_Len,		pAd->StaCfg.RSN_IE,
-						  END_OF_ARGS);
-		FrameLen += tmp;
-	}
-
-#ifdef DOT11_N_SUPPORT
-	if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
-	{
-		ULONG TmpLen;
-		UCHAR HtLen, HtLen1;
-
-#ifdef RT_BIG_ENDIAN
-		HT_CAPABILITY_IE HtCapabilityTmp;
-		ADD_HT_INFO_IE	addHTInfoTmp;
-		USHORT	b2lTmp, b2lTmp2;
-#endif
-
-		// add HT Capability IE
-		HtLen = sizeof(pAd->CommonCfg.HtCapability);
-		HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
-#ifndef RT_BIG_ENDIAN
-		MakeOutgoingFrame(pBeaconFrame+FrameLen,	&TmpLen,
-						  1,						&HtCapIe,
-						  1,						&HtLen,
-						  HtLen,					&pAd->CommonCfg.HtCapability,
-						  1,						&AddHtInfoIe,
-						  1,						&HtLen1,
-						  HtLen1,					&pAd->CommonCfg.AddHTInfo,
-						  END_OF_ARGS);
-#else
-		NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
-		*(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
-		*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
-
-		NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, HtLen1);
-		*(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
-		*(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));
-
-		MakeOutgoingFrame(pBeaconFrame+FrameLen,	&TmpLen,
-						  1,						&HtCapIe,
-						  1,						&HtLen,
-						  HtLen,					&HtCapabilityTmp,
-						  1,						&AddHtInfoIe,
-						  1,						&HtLen1,
-						  HtLen1,					&addHTInfoTmp,
-						  END_OF_ARGS);
-#endif
-		FrameLen += TmpLen;
-	}
-#endif // DOT11_N_SUPPORT //
-
-	//beacon use reserved WCID 0xff
-    if (pAd->CommonCfg.Channel > 14)
-    {
-	RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE,  TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
-		PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
-    }
-    else
-    {
-        // Set to use 1Mbps for Adhoc beacon.
-		HTTRANSMIT_SETTING Transmit;
-        Transmit.word = 0;
-        RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE,  TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
-		PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
-    }
-
-#ifdef RT_BIG_ENDIAN
-	RTMPFrameEndianChange(pAd, pBeaconFrame, DIR_WRITE, FALSE);
-	RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
-#endif
-
-    DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
-					FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));
-	return FrameLen;
-}
diff --git a/drivers/staging/rt3090/sta/dls.c b/drivers/staging/rt3090/sta/dls.c
deleted file mode 100644
index 306e16f..0000000
--- a/drivers/staging/rt3090/sta/dls.c
+++ /dev/null
@@ -1,2207 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    dls.c
-
-    Abstract:
-    Handle WMM-DLS state machine
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-    Rory Chen   02-14-2006
-	Arvin Tai	06-03-2008	  Modified for RT28xx
- */
-
-#include "../rt_config.h"
-
-
-/*
-    ==========================================================================
-    Description:
-        dls state machine init, including state transition and timer init
-    Parameters:
-        Sm - pointer to the dls state machine
-    Note:
-        The state machine looks like this
-
-                            DLS_IDLE
-    MT2_MLME_DLS_REQUEST   MlmeDlsReqAction
-    MT2_PEER_DLS_REQUEST   PeerDlsReqAction
-    MT2_PEER_DLS_RESPONSE  PeerDlsRspAction
-    MT2_MLME_DLS_TEARDOWN  MlmeTearDownAction
-    MT2_PEER_DLS_TEARDOWN  PeerTearDownAction
-
-	IRQL = PASSIVE_LEVEL
-
-    ==========================================================================
- */
-void DlsStateMachineInit(
-    IN PRTMP_ADAPTER pAd,
-    IN STATE_MACHINE *Sm,
-    OUT STATE_MACHINE_FUNC Trans[])
-{
-	UCHAR	i;
-
-    StateMachineInit(Sm, (STATE_MACHINE_FUNC*)Trans, MAX_DLS_STATE, MAX_DLS_MSG, (STATE_MACHINE_FUNC)Drop, DLS_IDLE, DLS_MACHINE_BASE);
-
-    // the first column
-    StateMachineSetAction(Sm, DLS_IDLE, MT2_MLME_DLS_REQ, (STATE_MACHINE_FUNC)MlmeDlsReqAction);
-    StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_REQ, (STATE_MACHINE_FUNC)PeerDlsReqAction);
-    StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_RSP, (STATE_MACHINE_FUNC)PeerDlsRspAction);
-    StateMachineSetAction(Sm, DLS_IDLE, MT2_MLME_DLS_TEAR_DOWN, (STATE_MACHINE_FUNC)MlmeDlsTearDownAction);
-    StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_TEAR_DOWN, (STATE_MACHINE_FUNC)PeerDlsTearDownAction);
-
-	for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
-	{
-		pAd->StaCfg.DLSEntry[i].pAd = pAd;
-		RTMPInitTimer(pAd, &pAd->StaCfg.DLSEntry[i].Timer, GET_TIMER_FUNCTION(DlsTimeoutAction), pAd, FALSE);
-	}
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-VOID MlmeDlsReqAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
-{
-	PUCHAR			pOutBuffer = NULL;
-	NDIS_STATUS		NStatus;
-	ULONG			FrameLen = 0;
-	HEADER_802_11	DlsReqHdr;
-	PRT_802_11_DLS	pDLS = NULL;
-	UCHAR			Category = CATEGORY_DLS;
-	UCHAR			Action = ACTION_DLS_REQUEST;
-	ULONG			tmp;
-	USHORT			reason;
-	ULONG			Timeout;
-	BOOLEAN			TimerCancelled;
-
-	if(!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &reason))
-		return;
-
-	DBGPRINT(RT_DEBUG_TRACE,("DLS - MlmeDlsReqAction() \n"));
-
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-	if (NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("DLS - MlmeDlsReqAction() allocate memory failed \n"));
-		return;
-	}
-
-	ActHeaderInit(pAd, &DlsReqHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
-
-	// Build basic frame first
-	MakeOutgoingFrame(pOutBuffer,				&FrameLen,
-					sizeof(HEADER_802_11),		&DlsReqHdr,
-					1,							&Category,
-					1,							&Action,
-					6,							&pDLS->MacAddr,
-					6,							pAd->CurrentAddress,
-					2,							&pAd->StaActive.CapabilityInfo,
-					2,							&pDLS->TimeOut,
-					1,							&SupRateIe,
-					1,							&pAd->MlmeAux.SupRateLen,
-					pAd->MlmeAux.SupRateLen,	pAd->MlmeAux.SupRate,
-					END_OF_ARGS);
-
-	if (pAd->MlmeAux.ExtRateLen != 0)
-	{
-		MakeOutgoingFrame(pOutBuffer + FrameLen,	&tmp,
-						  1,						&ExtRateIe,
-						  1,						&pAd->MlmeAux.ExtRateLen,
-						  pAd->MlmeAux.ExtRateLen,	pAd->MlmeAux.ExtRate,
-						  END_OF_ARGS);
-		FrameLen += tmp;
-	}
-
-#ifdef DOT11_N_SUPPORT
-	if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
-	{
-		UCHAR HtLen;
-
-#ifdef RT_BIG_ENDIAN
-		HT_CAPABILITY_IE HtCapabilityTmp;
-#endif
-
-		// add HT Capability IE
-		HtLen = sizeof(HT_CAPABILITY_IE);
-#ifndef RT_BIG_ENDIAN
-		MakeOutgoingFrame(pOutBuffer + FrameLen,	&tmp,
-							1,						&HtCapIe,
-							1,						&HtLen,
-							HtLen,					&pAd->CommonCfg.HtCapability,
-							END_OF_ARGS);
-#else
-		NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
-							*(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
-							*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
-
-		MakeOutgoingFrame(pOutBuffer + FrameLen,	&tmp,
-							1,						&HtCapIe,
-							1,						&HtLen,
-							HtLen,					&HtCapabilityTmp,
-							END_OF_ARGS);
-#endif
-		FrameLen = FrameLen + tmp;
-	}
-#endif // DOT11_N_SUPPORT //
-
-	RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
-	Timeout = DLS_TIMEOUT;
-	RTMPSetTimer(&pDLS->Timer, Timeout);
-
-	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-VOID PeerDlsReqAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
-{
-	PUCHAR			pOutBuffer = NULL;
-	NDIS_STATUS		NStatus;
-	ULONG			FrameLen = 0;
-	USHORT			StatusCode = MLME_SUCCESS;
-	HEADER_802_11	DlsRspHdr;
-	UCHAR			Category = CATEGORY_DLS;
-	UCHAR			Action = ACTION_DLS_RESPONSE;
-	ULONG			tmp;
-	USHORT			CapabilityInfo;
-	UCHAR			DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
-	USHORT			DLSTimeOut;
-	SHORT			i;
-	ULONG			Timeout;
-	BOOLEAN			TimerCancelled;
-	PRT_802_11_DLS	pDLS = NULL;
-	UCHAR			MaxSupportedRateIn500Kbps = 0;
-    UCHAR			SupportedRatesLen;
-    UCHAR			SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR			HtCapabilityLen;
-	HT_CAPABILITY_IE	HtCapability;
-
-	if (!PeerDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &DLSTimeOut,
-							&SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability))
-		return;
-
-    // supported rates array may not be sorted. sort it and find the maximum rate
-    for (i = 0; i < SupportedRatesLen; i++)
-    {
-        if (MaxSupportedRateIn500Kbps < (SupportedRates[i] & 0x7f))
-            MaxSupportedRateIn500Kbps = SupportedRates[i] & 0x7f;
-    }
-
-	DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() from %02x:%02x:%02x:%02x:%02x:%02x\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
-
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-	if (NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsReqAction() allocate memory failed \n"));
-		return;
-	}
-
-	if (!INFRA_ON(pAd))
-	{
-		StatusCode = MLME_REQUEST_DECLINED;
-	}
-	else if (!pAd->CommonCfg.bWmmCapable)
-	{
-		StatusCode = MLME_DEST_STA_IS_NOT_A_QSTA;
-	}
-	else if (!pAd->CommonCfg.bDLSCapable)
-	{
-		StatusCode = MLME_REQUEST_DECLINED;
-	}
-	else
-	{
-		// find table to update parameters
-		for (i = (MAX_NUM_OF_DLS_ENTRY-1); i >= 0; i--)
-		{
-			if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
-			{
-				if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-					pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
-				else
-				{
-					RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
-					pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
-				}
-
-				pAd->StaCfg.DLSEntry[i].Sequence = 0;
-				pAd->StaCfg.DLSEntry[i].TimeOut = DLSTimeOut;
-				pAd->StaCfg.DLSEntry[i].CountDownTimer = DLSTimeOut;
-				if (HtCapabilityLen != 0)
-					pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
-				else
-					pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
-				pDLS = &pAd->StaCfg.DLSEntry[i];
-				break;
-			}
-		}
-
-		// can not find in table, create a new one
-		if (i < 0)
-		{
-			DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() can not find same entry \n"));
-			for (i=(MAX_NUM_OF_DLS_ENTRY - 1); i >= MAX_NUM_OF_INIT_DLS_ENTRY; i--)
-			{
-				if (!pAd->StaCfg.DLSEntry[i].Valid)
-				{
-					MAC_TABLE_ENTRY *pEntry;
-					UCHAR MaxSupportedRate = RATE_11;
-
-					if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-					{
-						pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
-					}
-					else
-					{
-						RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
-						pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
-					}
-
-					pAd->StaCfg.DLSEntry[i].Sequence = 0;
-					pAd->StaCfg.DLSEntry[i].Valid = TRUE;
-					pAd->StaCfg.DLSEntry[i].TimeOut = DLSTimeOut;
-					pAd->StaCfg.DLSEntry[i].CountDownTimer = DLSTimeOut;
-					NdisMoveMemory(pAd->StaCfg.DLSEntry[i].MacAddr, SA, MAC_ADDR_LEN);
-					if (HtCapabilityLen != 0)
-						pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
-					else
-						pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
-					pDLS = &pAd->StaCfg.DLSEntry[i];
-					pEntry = MacTableInsertDlsEntry(pAd, SA, i);
-
-					switch (MaxSupportedRateIn500Kbps)
-					{
-						case 108: MaxSupportedRate = RATE_54;   break;
-						case 96:  MaxSupportedRate = RATE_48;   break;
-						case 72:  MaxSupportedRate = RATE_36;   break;
-						case 48:  MaxSupportedRate = RATE_24;   break;
-						case 36:  MaxSupportedRate = RATE_18;   break;
-						case 24:  MaxSupportedRate = RATE_12;   break;
-						case 18:  MaxSupportedRate = RATE_9;    break;
-						case 12:  MaxSupportedRate = RATE_6;    break;
-						case 22:  MaxSupportedRate = RATE_11;   break;
-						case 11:  MaxSupportedRate = RATE_5_5;  break;
-						case 4:   MaxSupportedRate = RATE_2;    break;
-						case 2:   MaxSupportedRate = RATE_1;    break;
-						default:  MaxSupportedRate = RATE_11;   break;
-					}
-
-					pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
-
-					if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
-					{
-						pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
-						pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
-						pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
-						pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
-						pEntry->HTPhyMode.field.MODE = MODE_CCK;
-						pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
-					}
-					else
-					{
-						pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
-						pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
-						pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
-						pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
-						pEntry->HTPhyMode.field.MODE = MODE_OFDM;
-						pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
-					}
-
-					pEntry->MaxHTPhyMode.field.BW = BW_20;
-					pEntry->MinHTPhyMode.field.BW = BW_20;
-
-#ifdef DOT11_N_SUPPORT
-					pEntry->HTCapability.MCSSet[0] = 0;
-					pEntry->HTCapability.MCSSet[1] = 0;
-
-					// If this Entry supports 802.11n, upgrade to HT rate.
-					if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
-					{
-						UCHAR	j, bitmask; //k,bitmask;
-						CHAR    ii;
-
-						DBGPRINT(RT_DEBUG_TRACE, ("DLS - PeerDlsReqAction() Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n",
-									SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
-
-						if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
-						{
-							pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
-						}
-						else
-						{
-							pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
-							pAd->MacTab.fAnyStationNonGF = TRUE;
-							pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
-						}
-
-						if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
-						{
-							pEntry->MaxHTPhyMode.field.BW= BW_40;
-							pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
-						}
-						else
-						{
-							pEntry->MaxHTPhyMode.field.BW = BW_20;
-							pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
-							pAd->MacTab.fAnyStation20Only = TRUE;
-						}
-
-						// find max fixed rate
-						for (ii=15; ii>=0; ii--)
-						{
-							j = ii/8;
-							bitmask = (1<<(ii-(j*8)));
-							if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
-							{
-								pEntry->MaxHTPhyMode.field.MCS = ii;
-								break;
-							}
-							if (ii==0)
-								break;
-						}
-
-
-						if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
-						{
-
-							DBGPRINT(RT_DEBUG_OFF, ("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n",
-										pAd->StaCfg.DesiredTransmitSetting.field.MCS));
-							if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
-							{
-								// Fix MCS as HT Duplicated Mode
-								pEntry->MaxHTPhyMode.field.BW = 1;
-								pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
-								pEntry->MaxHTPhyMode.field.STBC = 0;
-								pEntry->MaxHTPhyMode.field.ShortGI = 0;
-								pEntry->MaxHTPhyMode.field.MCS = 32;
-							}
-							else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
-							{
-								// STA supports fixed MCS
-								pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
-							}
-						}
-
-						pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
-						pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
-						pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
-						pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
-						pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
-						pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
-
-						if (HtCapability.HtCapInfo.ShortGIfor20)
-							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
-						if (HtCapability.HtCapInfo.ShortGIfor40)
-							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
-						if (HtCapability.HtCapInfo.TxSTBC)
-							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
-						if (HtCapability.HtCapInfo.RxSTBC)
-							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
-						if (HtCapability.ExtHtCapInfo.PlusHTC)
-							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
-						if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
-							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
-						if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
-							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
-
-						NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
-					}
-#endif // DOT11_N_SUPPORT //
-
-					pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
-					pEntry->CurrTxRate = pEntry->MaxSupportedRate;
-					CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
-
-					if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
-					{
-						PUCHAR pTable;
-						UCHAR TableSize = 0;
-
-						MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
-						pEntry->bAutoTxRateSwitch = TRUE;
-					}
-					else
-					{
-						pEntry->HTPhyMode.field.MODE	= pAd->StaCfg.HTPhyMode.field.MODE;
-						pEntry->HTPhyMode.field.MCS	= pAd->StaCfg.HTPhyMode.field.MCS;
-						pEntry->bAutoTxRateSwitch = FALSE;
-
-						RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
-					}
-					pEntry->RateLen = SupportedRatesLen;
-
-					break;
-				}
-			}
-		}
-		StatusCode = MLME_SUCCESS;
-
-		// can not find in table, create a new one
-		if (i < 0)
-		{
-			StatusCode = MLME_QOS_UNSPECIFY;
-			DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsReqAction() DLSEntry table full(only can support %d DLS session) \n", MAX_NUM_OF_DLS_ENTRY - MAX_NUM_OF_INIT_DLS_ENTRY));
-		}
-		else
-		{
-			DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() use entry(%d) %02x:%02x:%02x:%02x:%02x:%02x\n",
-				i, SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
-		}
-	}
-
-	ActHeaderInit(pAd, &DlsRspHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
-
-	// Build basic frame first
-	if (StatusCode == MLME_SUCCESS)
-	{
-		MakeOutgoingFrame(pOutBuffer,				&FrameLen,
-						sizeof(HEADER_802_11),		&DlsRspHdr,
-						1,							&Category,
-						1,							&Action,
-						2,							&StatusCode,
-						6,							SA,
-						6,							pAd->CurrentAddress,
-						2,							&pAd->StaActive.CapabilityInfo,
-						1,							&SupRateIe,
-						1,							&pAd->MlmeAux.SupRateLen,
-						pAd->MlmeAux.SupRateLen,	pAd->MlmeAux.SupRate,
-						END_OF_ARGS);
-
-		if (pAd->MlmeAux.ExtRateLen != 0)
-		{
-			MakeOutgoingFrame(pOutBuffer + FrameLen,	&tmp,
-							  1,						&ExtRateIe,
-							  1,						&pAd->MlmeAux.ExtRateLen,
-							  pAd->MlmeAux.ExtRateLen,	pAd->MlmeAux.ExtRate,
-							  END_OF_ARGS);
-			FrameLen += tmp;
-		}
-
-#ifdef DOT11_N_SUPPORT
-		if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
-		{
-			UCHAR HtLen;
-
-#ifdef RT_BIG_ENDIAN
-			HT_CAPABILITY_IE HtCapabilityTmp;
-#endif
-
-			// add HT Capability IE
-			HtLen = sizeof(HT_CAPABILITY_IE);
-#ifndef RT_BIG_ENDIAN
-			MakeOutgoingFrame(pOutBuffer + FrameLen,	&tmp,
-								1,						&HtCapIe,
-								1,						&HtLen,
-								HtLen,					&pAd->CommonCfg.HtCapability,
-								END_OF_ARGS);
-#else
-			NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
-								*(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
-								*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
-
-			MakeOutgoingFrame(pOutBuffer + FrameLen,	&tmp,
-								1,						&HtCapIe,
-								1,						&HtLen,
-								HtLen,					&HtCapabilityTmp,
-								END_OF_ARGS);
-#endif
-			FrameLen = FrameLen + tmp;
-		}
-#endif // DOT11_N_SUPPORT //
-
-		if (pDLS && (pDLS->Status != DLS_FINISH))
-		{
-			RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
-			Timeout = DLS_TIMEOUT;
-			RTMPSetTimer(&pDLS->Timer, Timeout);
-		}
-	}
-	else
-	{
-		MakeOutgoingFrame(pOutBuffer,				&FrameLen,
-						sizeof(HEADER_802_11),		&DlsRspHdr,
-						1,							&Category,
-						1,							&Action,
-						2,							&StatusCode,
-						6,							SA,
-						6,							pAd->CurrentAddress,
-						END_OF_ARGS);
-	}
-
-	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-VOID PeerDlsRspAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
-{
-	USHORT		CapabilityInfo;
-	UCHAR		DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
-	USHORT		StatusCode;
-	SHORT		i;
-	BOOLEAN		TimerCancelled;
-	UCHAR		MaxSupportedRateIn500Kbps = 0;
-    UCHAR		SupportedRatesLen;
-    UCHAR		SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR		HtCapabilityLen;
-	HT_CAPABILITY_IE	HtCapability;
-
-	if (!pAd->CommonCfg.bDLSCapable)
-		return;
-
-	if (!INFRA_ON(pAd))
-		return;
-
-	if (!PeerDlsRspSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &StatusCode,
-							&SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability))
-		return;
-
-    // supported rates array may not be sorted. sort it and find the maximum rate
-    for (i=0; i<SupportedRatesLen; i++)
-    {
-        if (MaxSupportedRateIn500Kbps < (SupportedRates[i] & 0x7f))
-            MaxSupportedRateIn500Kbps = SupportedRates[i] & 0x7f;
-    }
-
-	DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x with StatusCode=%d, CapabilityInfo=0x%x\n",
-		SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], StatusCode, CapabilityInfo));
-
-	for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
-	{
-		if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
-		{
-			if (StatusCode == MLME_SUCCESS)
-			{
-				MAC_TABLE_ENTRY *pEntry;
-				UCHAR MaxSupportedRate = RATE_11;
-
-				pEntry = MacTableInsertDlsEntry(pAd, SA, i);
-
-				switch (MaxSupportedRateIn500Kbps)
-				{
-					case 108: MaxSupportedRate = RATE_54;   break;
-					case 96:  MaxSupportedRate = RATE_48;   break;
-					case 72:  MaxSupportedRate = RATE_36;   break;
-					case 48:  MaxSupportedRate = RATE_24;   break;
-					case 36:  MaxSupportedRate = RATE_18;   break;
-					case 24:  MaxSupportedRate = RATE_12;   break;
-					case 18:  MaxSupportedRate = RATE_9;    break;
-					case 12:  MaxSupportedRate = RATE_6;    break;
-					case 22:  MaxSupportedRate = RATE_11;   break;
-					case 11:  MaxSupportedRate = RATE_5_5;  break;
-					case 4:   MaxSupportedRate = RATE_2;    break;
-					case 2:   MaxSupportedRate = RATE_1;    break;
-					default:  MaxSupportedRate = RATE_11;   break;
-				}
-
-				pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
-
-				if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
-				{
-					pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
-					pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
-					pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
-					pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
-					pEntry->HTPhyMode.field.MODE = MODE_CCK;
-					pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
-				}
-				else
-				{
-					pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
-					pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
-					pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
-					pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
-					pEntry->HTPhyMode.field.MODE = MODE_OFDM;
-					pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
-				}
-
-				pEntry->MaxHTPhyMode.field.BW = BW_20;
-				pEntry->MinHTPhyMode.field.BW = BW_20;
-
-#ifdef DOT11_N_SUPPORT
-				pEntry->HTCapability.MCSSet[0] = 0;
-				pEntry->HTCapability.MCSSet[1] = 0;
-
-				// If this Entry supports 802.11n, upgrade to HT rate.
-				if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
-				{
-					UCHAR	j, bitmask; //k,bitmask;
-					CHAR    ii;
-
-					DBGPRINT(RT_DEBUG_OFF, ("DLS - PeerDlsRspAction Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n",
-								SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
-
-					if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
-					{
-						pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
-					}
-					else
-					{
-						pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
-						pAd->MacTab.fAnyStationNonGF = TRUE;
-						pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
-					}
-
-					if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
-					{
-						pEntry->MaxHTPhyMode.field.BW= BW_40;
-						pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
-					}
-					else
-					{
-						pEntry->MaxHTPhyMode.field.BW = BW_20;
-						pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
-						pAd->MacTab.fAnyStation20Only = TRUE;
-					}
-
-					// find max fixed rate
-					for (ii=15; ii>=0; ii--)
-					{
-						j = ii/8;
-						bitmask = (1<<(ii-(j*8)));
-						if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
-						{
-							pEntry->MaxHTPhyMode.field.MCS = ii;
-							break;
-						}
-						if (ii==0)
-							break;
-					}
-
-					if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
-					{
-						if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
-						{
-							// Fix MCS as HT Duplicated Mode
-							pEntry->MaxHTPhyMode.field.BW = 1;
-							pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
-							pEntry->MaxHTPhyMode.field.STBC = 0;
-							pEntry->MaxHTPhyMode.field.ShortGI = 0;
-							pEntry->MaxHTPhyMode.field.MCS = 32;
-						}
-						else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
-						{
-							// STA supports fixed MCS
-							pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
-						}
-					}
-
-					pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
-					pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
-					pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
-					pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
-					pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
-					pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
-
-					if (HtCapability.HtCapInfo.ShortGIfor20)
-						CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
-					if (HtCapability.HtCapInfo.ShortGIfor40)
-						CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
-					if (HtCapability.HtCapInfo.TxSTBC)
-						CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
-					if (HtCapability.HtCapInfo.RxSTBC)
-						CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
-					if (HtCapability.ExtHtCapInfo.PlusHTC)
-						CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
-					if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
-						CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
-					if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
-						CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
-
-					NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
-				}
-#endif // DOT11_N_SUPPORT //
-				pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
-				pEntry->CurrTxRate = pEntry->MaxSupportedRate;
-				CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
-
-				if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
-				{
-					PUCHAR pTable;
-					UCHAR TableSize = 0;
-
-					MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
-					pEntry->bAutoTxRateSwitch = TRUE;
-				}
-				else
-				{
-					pEntry->HTPhyMode.field.MODE	= pAd->StaCfg.HTPhyMode.field.MODE;
-					pEntry->HTPhyMode.field.MCS	= pAd->StaCfg.HTPhyMode.field.MCS;
-					pEntry->bAutoTxRateSwitch = FALSE;
-
-					RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
-				}
-				pEntry->RateLen = SupportedRatesLen;
-
-				if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-				{
-					// If support WPA or WPA2, start STAKey hand shake,
-					// If failed hand shake, just tear down peer DLS
-					if (RTMPSendSTAKeyRequest(pAd, pAd->StaCfg.DLSEntry[i].MacAddr) != NDIS_STATUS_SUCCESS)
-					{
-						MLME_DLS_REQ_STRUCT	MlmeDlsReq;
-						USHORT				reason = REASON_QOS_CIPHER_NOT_SUPPORT;
-
-						DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
-						MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
-						pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
-						pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
-						DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n"));
-					}
-					else
-					{
-						pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
-						DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n"));
-					}
-				}
-				else
-				{
-					RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
-					pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
-					DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x Succeed with WEP or no security\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
-				}
-
-				//initialize seq no for DLS frames.
-				pAd->StaCfg.DLSEntry[i].Sequence = 0;
-				if (HtCapabilityLen != 0)
-					pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
-				else
-					pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
-			}
-			else
-			{
-				// DLS setup procedure failed.
-				pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
-				pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
-				RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
-				DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode));
-			}
-		}
-	}
-
-	if (i >= MAX_NUM_OF_INIT_DLS_ENTRY)
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() update timeout value \n"));
-		for (i=(MAX_NUM_OF_DLS_ENTRY-1); i>=MAX_NUM_OF_INIT_DLS_ENTRY; i--)
-		{
-			if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
-			{
-				if (StatusCode == MLME_SUCCESS)
-				{
-					MAC_TABLE_ENTRY *pEntry;
-					UCHAR MaxSupportedRate = RATE_11;
-
-					pEntry = MacTableInsertDlsEntry(pAd, SA, i);
-
-					switch (MaxSupportedRateIn500Kbps)
-					{
-						case 108: MaxSupportedRate = RATE_54;   break;
-						case 96:  MaxSupportedRate = RATE_48;   break;
-						case 72:  MaxSupportedRate = RATE_36;   break;
-						case 48:  MaxSupportedRate = RATE_24;   break;
-						case 36:  MaxSupportedRate = RATE_18;   break;
-						case 24:  MaxSupportedRate = RATE_12;   break;
-						case 18:  MaxSupportedRate = RATE_9;    break;
-						case 12:  MaxSupportedRate = RATE_6;    break;
-						case 22:  MaxSupportedRate = RATE_11;   break;
-						case 11:  MaxSupportedRate = RATE_5_5;  break;
-						case 4:   MaxSupportedRate = RATE_2;    break;
-						case 2:   MaxSupportedRate = RATE_1;    break;
-						default:  MaxSupportedRate = RATE_11;   break;
-					}
-
-					pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
-
-					if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
-					{
-						pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
-						pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
-						pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
-						pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
-						pEntry->HTPhyMode.field.MODE = MODE_CCK;
-						pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
-					}
-					else
-					{
-						pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
-						pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
-						pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
-						pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
-						pEntry->HTPhyMode.field.MODE = MODE_OFDM;
-						pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
-					}
-
-					pEntry->MaxHTPhyMode.field.BW = BW_20;
-					pEntry->MinHTPhyMode.field.BW = BW_20;
-
-#ifdef DOT11_N_SUPPORT
-					pEntry->HTCapability.MCSSet[0] = 0;
-					pEntry->HTCapability.MCSSet[1] = 0;
-
-					// If this Entry supports 802.11n, upgrade to HT rate.
-					if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
-					{
-						UCHAR	j, bitmask; //k,bitmask;
-						CHAR    ii;
-
-						DBGPRINT(RT_DEBUG_TRACE, ("DLS - PeerDlsRspAction Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n",
-									SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
-
-						if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
-						{
-							pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
-						}
-						else
-						{
-							pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
-							pAd->MacTab.fAnyStationNonGF = TRUE;
-							pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
-						}
-
-						if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
-						{
-							pEntry->MaxHTPhyMode.field.BW= BW_40;
-							pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
-						}
-						else
-						{
-							pEntry->MaxHTPhyMode.field.BW = BW_20;
-							pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
-							pAd->MacTab.fAnyStation20Only = TRUE;
-						}
-
-						// find max fixed rate
-						for (ii=15; ii>=0; ii--)
-						{
-							j = ii/8;
-							bitmask = (1<<(ii-(j*8)));
-							if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
-							{
-								pEntry->MaxHTPhyMode.field.MCS = ii;
-								break;
-							}
-							if (ii==0)
-								break;
-						}
-
-						if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
-						{
-							DBGPRINT(RT_DEBUG_OFF, ("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n",
-													pAd->StaCfg.DesiredTransmitSetting.field.MCS));
-							if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
-							{
-								// Fix MCS as HT Duplicated Mode
-								pEntry->MaxHTPhyMode.field.BW = 1;
-								pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
-								pEntry->MaxHTPhyMode.field.STBC = 0;
-								pEntry->MaxHTPhyMode.field.ShortGI = 0;
-								pEntry->MaxHTPhyMode.field.MCS = 32;
-							}
-							else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
-							{
-								// STA supports fixed MCS
-								pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
-							}
-						}
-
-						pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
-						pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
-						pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
-						pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
-						pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
-						pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
-
-						if (HtCapability.HtCapInfo.ShortGIfor20)
-							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
-						if (HtCapability.HtCapInfo.ShortGIfor40)
-							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
-						if (HtCapability.HtCapInfo.TxSTBC)
-							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
-						if (HtCapability.HtCapInfo.RxSTBC)
-							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
-						if (HtCapability.ExtHtCapInfo.PlusHTC)
-							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
-						if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
-							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
-						if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
-							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
-
-						NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
-					}
-#endif // DOT11_N_SUPPORT //
-
-					pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
-					pEntry->CurrTxRate = pEntry->MaxSupportedRate;
-					CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
-
-					if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
-					{
-						PUCHAR pTable;
-						UCHAR TableSize = 0;
-
-						MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
-						pEntry->bAutoTxRateSwitch = TRUE;
-					}
-					else
-					{
-						pEntry->HTPhyMode.field.MODE	= pAd->StaCfg.HTPhyMode.field.MODE;
-						pEntry->HTPhyMode.field.MCS	= pAd->StaCfg.HTPhyMode.field.MCS;
-						pEntry->bAutoTxRateSwitch = FALSE;
-
-						RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
-					}
-					pEntry->RateLen = SupportedRatesLen;
-
-					if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-					{
-						// If support WPA or WPA2, start STAKey hand shake,
-						// If failed hand shake, just tear down peer DLS
-						if (RTMPSendSTAKeyRequest(pAd, pAd->StaCfg.DLSEntry[i].MacAddr) != NDIS_STATUS_SUCCESS)
-						{
-							MLME_DLS_REQ_STRUCT	MlmeDlsReq;
-							USHORT				reason = REASON_QOS_CIPHER_NOT_SUPPORT;
-
-							DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
-							MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
-							pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
-							pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
-							DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n"));
-						}
-						else
-						{
-							pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
-							DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n"));
-						}
-					}
-					else
-					{
-						RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
-						pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
-						DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x Succeed with WEP or no security\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
-					}
-					pAd->StaCfg.DLSEntry[i].Sequence = 0;
-					if (HtCapabilityLen != 0)
-						pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
-					else
-						pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
-				}
-				else
-				{
-					// DLS setup procedure failed.
-					pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
-					pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
-					RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
-					DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode));
-				}
-			}
-		}
-	}
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-VOID MlmeDlsTearDownAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
-{
-	PUCHAR			pOutBuffer = NULL;
-	NDIS_STATUS		NStatus;
-	ULONG			FrameLen = 0;
-	UCHAR			Category = CATEGORY_DLS;
-	UCHAR			Action = ACTION_DLS_TEARDOWN;
-	USHORT			ReasonCode = REASON_QOS_UNSPECIFY;
-	HEADER_802_11	DlsTearDownHdr;
-	PRT_802_11_DLS	pDLS;
-	BOOLEAN			TimerCancelled;
-	UCHAR			i;
-
-	if(!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &ReasonCode))
-		return;
-
-	DBGPRINT(RT_DEBUG_TRACE,("DLS - MlmeDlsTearDownAction() with ReasonCode=%d \n", ReasonCode));
-
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-	if (NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("DLS - MlmeDlsTearDownAction() allocate memory failed \n"));
-		return;
-	}
-
-	ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
-
-	// Build basic frame first
-	MakeOutgoingFrame(pOutBuffer,				&FrameLen,
-					sizeof(HEADER_802_11),		&DlsTearDownHdr,
-					1,							&Category,
-					1,							&Action,
-					6,							&pDLS->MacAddr,
-					6,							pAd->CurrentAddress,
-					2,							&ReasonCode,
-					END_OF_ARGS);
-
-	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-	RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
-
-	// Remove key in local dls table entry
-	for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
-	{
-		if (MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
-		{
-			MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
-		}
-	}
-
-	// clear peer dls table entry
-	for (i = MAX_NUM_OF_INIT_DLS_ENTRY; i < MAX_NUM_OF_DLS_ENTRY; i++)
-	{
-		if (MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
-		{
-			pAd->StaCfg.DLSEntry[i].Status	= DLS_NONE;
-			pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
-			RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
-			MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
-		}
-	}
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-VOID PeerDlsTearDownAction(
-    IN PRTMP_ADAPTER pAd,
-    IN MLME_QUEUE_ELEM *Elem)
-{
-	UCHAR			DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
-	USHORT			ReasonCode;
-	UINT			i;
-	BOOLEAN			TimerCancelled;
-
-	if (!pAd->CommonCfg.bDLSCapable)
-		return;
-
-	if (!INFRA_ON(pAd))
-		return;
-
-	if (!PeerDlsTearDownSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &ReasonCode))
-		return;
-
-	DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsTearDownAction() from %02x:%02x:%02x:%02x:%02x:%02x with ReasonCode=%d\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], ReasonCode));
-
-	// clear local dls table entry
-	for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
-	{
-		if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
-		{
-			pAd->StaCfg.DLSEntry[i].Status	= DLS_NONE;
-			pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
-			RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
-			//AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
-			//AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
-			MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
-		}
-	}
-
-	// clear peer dls table entry
-	for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
-	{
-		if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
-		{
-			pAd->StaCfg.DLSEntry[i].Status	= DLS_NONE;
-			pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
-			RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
-			//AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
-			//AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
-			MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
-		}
-	}
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-VOID RTMPCheckDLSTimeOut(
-	IN PRTMP_ADAPTER	pAd)
-{
-	ULONG				i;
-	MLME_DLS_REQ_STRUCT	MlmeDlsReq;
-	USHORT				reason = REASON_QOS_UNSPECIFY;
-
-	if (! pAd->CommonCfg.bDLSCapable)
-		return;
-
-	if (! INFRA_ON(pAd))
-		return;
-
-	// If timeout value is equaled to zero, it means always not be timeout.
-
-	// update local dls table entry
-	for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
-	{
-		if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
-			&& (pAd->StaCfg.DLSEntry[i].TimeOut != 0))
-		{
-			pAd->StaCfg.DLSEntry[i].CountDownTimer --;
-
-			if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0)
-			{
-				reason = REASON_QOS_REQUEST_TIMEOUT;
-				pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
-				pAd->StaCfg.DLSEntry[i].Status	= DLS_NONE;
-				DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
-				MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
-			}
-		}
-	}
-
-	// update peer dls table entry
-	for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
-	{
-		if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
-			&& (pAd->StaCfg.DLSEntry[i].TimeOut != 0))
-		{
-			pAd->StaCfg.DLSEntry[i].CountDownTimer --;
-
-			if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0)
-			{
-				reason = REASON_QOS_REQUEST_TIMEOUT;
-				pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
-				pAd->StaCfg.DLSEntry[i].Status	= DLS_NONE;
-				DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
-				MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
-			}
-		}
-	}
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-BOOLEAN RTMPRcvFrameDLSCheck(
-	IN PRTMP_ADAPTER	pAd,
-	IN PHEADER_802_11	pHeader,
-	IN ULONG			Len,
-	IN PRT28XX_RXD_STRUC	pRxD)
-{
-	ULONG			i;
-	BOOLEAN			bFindEntry = FALSE;
-	BOOLEAN			bSTAKeyFrame = FALSE;
-	PEAPOL_PACKET	pEap;
-	PUCHAR			pProto, pAddr = NULL;
-	PUCHAR			pSTAKey = NULL;
-	UCHAR			ZeroReplay[LEN_KEY_DESC_REPLAY];
-	UCHAR			Mic[16], OldMic[16];
-	UCHAR			digest[80];
-	UCHAR			DlsPTK[80];
-	UCHAR			temp[64];
-	BOOLEAN			TimerCancelled;
-	CIPHER_KEY		PairwiseKey;
-
-
-	if (! pAd->CommonCfg.bDLSCapable)
-		return bSTAKeyFrame;
-
-	if (! INFRA_ON(pAd))
-		return bSTAKeyFrame;
-
-	if (Len < LENGTH_802_11 + 6 + 2) /* LENGTH_802_11 + LLC + EAPOL protocol type */
-		return bSTAKeyFrame;
-
-	pProto	= (PUCHAR)pHeader + LENGTH_802_11;
-
-	if ((pHeader->FC.SubType & 0x08))
-		pProto	+= 2;	/* QOS Control field */
-
-     /* Skip 4-bytes for HTC */
-     if (pHeader->FC.Order && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)))
-     {
-          pProto += 4;
-     }
-
-	/* L2PAD bit on will pad 2 bytes at LLC */
-	if (pRxD->L2PAD)
-	{
-		pProto += 2;
-	}
-
-	pProto	+= 6;	/* 0xAA 0xAA 0xAA 0x00 0x00 0x00 */
-
-	if ((!(pHeader->FC.SubType & 0x08)) && (!RTMPEqualMemory(EAPOL, pProto, 2)))
-		return bSTAKeyFrame;
-
-	pAddr	= pHeader->Addr2;
-
-	if (RTMPEqualMemory(EAPOL, pProto, 2) && (pAd->StaCfg.AuthMode >=  Ndis802_11AuthModeWPA))
-	{
-		pEap = (PEAPOL_PACKET) (pProto + 2);
-
-		DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff Len=%ld, DataLen=%d, KeyMic=%d, Install=%d, KeyAck=%d, Secure=%d, EKD_DL=%d, Error=%d, Request=%d\n", Len,
-			                                                             (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE + 16),
-			                                                             pEap->KeyDesc.KeyInfo.KeyMic,
-			                                                             pEap->KeyDesc.KeyInfo.Install,
-			                                                             pEap->KeyDesc.KeyInfo.KeyAck,
-			                                                             pEap->KeyDesc.KeyInfo.Secure,
-			                                                             pEap->KeyDesc.KeyInfo.EKD_DL,
-			                                                             pEap->KeyDesc.KeyInfo.Error,
-			                                                             pEap->KeyDesc.KeyInfo.Request));
-
-		if ((Len >= (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE + 16)) && pEap->KeyDesc.KeyInfo.KeyMic
-			&& pEap->KeyDesc.KeyInfo.Install && pEap->KeyDesc.KeyInfo.KeyAck && pEap->KeyDesc.KeyInfo.Secure
-			&& pEap->KeyDesc.KeyInfo.EKD_DL && !pEap->KeyDesc.KeyInfo.Error && !pEap->KeyDesc.KeyInfo.Request)
-		{
-			// First validate replay counter, only accept message with larger replay counter
-			// Let equal pass, some AP start with all zero replay counter
-			NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
-			if ((RTMPCompareMemory(pEap->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1) &&
-				(RTMPCompareMemory(pEap->KeyDesc.ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
-				return bSTAKeyFrame;
-
-			//RTMPMoveMemory(pAd->StaCfg.ReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
-			RTMPMoveMemory(pAd->StaCfg.DlsReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
-			DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff replay counter (%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n",
-				pAd->StaCfg.ReplayCounter[0], pAd->StaCfg.ReplayCounter[1], pAd->StaCfg.ReplayCounter[2],
-				pAd->StaCfg.ReplayCounter[3], pAd->StaCfg.ReplayCounter[4],	pAd->StaCfg.ReplayCounter[5],
-				pAd->StaCfg.ReplayCounter[6], pAd->StaCfg.ReplayCounter[7], Len, pEap->KeyDesc.KeyData[1]));
-
-			// put these code segment to get the replay counter
-			if (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)
-				return bSTAKeyFrame;
-
-			// Check MIC value
-			// Save the MIC and replace with zero
-			// use proprietary PTK
-			NdisZeroMemory(temp, 64);
-			NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
-			WpaDerivePTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
-
-			NdisMoveMemory(OldMic, pEap->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
-			NdisZeroMemory(pEap->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
-			if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
-			{
-				// AES
-				HMAC_SHA1(DlsPTK, LEN_EAP_MICK, (PUCHAR) pEap, pEap->Body_Len[1] + 4, digest, SHA1_DIGEST_SIZE);
-				NdisMoveMemory(Mic,	digest,	LEN_KEY_DESC_MIC);
-			}
-			else
-			{
-				HMAC_MD5(DlsPTK, LEN_EAP_MICK, (PUCHAR) pEap, pEap->Body_Len[1] + 4, Mic, MD5_DIGEST_SIZE);
-			}
-
-			if (!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
-			{
-				DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in Msg1 of STAKey handshake! \n"));
-				return bSTAKeyFrame;
-			}
-			else
-				DBGPRINT(RT_DEBUG_TRACE, ("MIC VALID in Msg1 of STAKey handshake! \n"));
-			if ((pEap->KeyDesc.KeyData[0] == 0xDD) && (pEap->KeyDesc.KeyData[2] == 0x00) && (pEap->KeyDesc.KeyData[3] == 0x0C)
-				&& (pEap->KeyDesc.KeyData[4] == 0x43) && (pEap->KeyDesc.KeyData[5] == 0x02))
-			{
-				pAddr			= pEap->KeyDesc.KeyData + 8;		// Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2)
-				pSTAKey			= pEap->KeyDesc.KeyData + 14;	// Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2), STAKey_Mac_Addr(6)
-
-				DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 from %02x:%02x:%02x:%02x:%02x:%02x Len=%ld, KeyDataLen=%d\n",
-					pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5], Len, pEap->KeyDesc.KeyData[1]));
-
-				bSTAKeyFrame = TRUE;
-			}
-
-		}
-		else if (Len >= (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE))
-		{
-			RTMPMoveMemory(pAd->StaCfg.DlsReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
-			DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff replay counter 2(%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n",
-				pAd->StaCfg.ReplayCounter[0], pAd->StaCfg.ReplayCounter[1], pAd->StaCfg.ReplayCounter[2],
-				pAd->StaCfg.ReplayCounter[3], pAd->StaCfg.ReplayCounter[4],	pAd->StaCfg.ReplayCounter[5],
-				pAd->StaCfg.ReplayCounter[6], pAd->StaCfg.ReplayCounter[7], Len, pEap->KeyDesc.KeyData[1]));
-		}
-	}
-
-	// If timeout value is equaled to zero, it means always not be timeout.
-	// update local dls table entry
-	for (i= 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
-	{
-		if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
-		{
-			if (bSTAKeyFrame)
-			{
-				PMAC_TABLE_ENTRY pEntry;
-
-				// STAKey frame, add pairwise key table
-				pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
-				RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
-
-				PairwiseKey.KeyLen = LEN_TKIP_EK;
-				NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], LEN_TKIP_EK);
-				NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], LEN_TKIP_RXMICK);
-				NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], LEN_TKIP_TXMICK);
-
-				//PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg;
-				if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
-					PairwiseKey.CipherAlg = CIPHER_TKIP;
-				else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
-					PairwiseKey.CipherAlg = CIPHER_AES;
-
-				pEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
-				//AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE);	// reserve 0 for multicast, 1 for unicast
-				//AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
-				// Add Pair-wise key to Asic
-#ifdef RTMP_MAC_PCI
-				AsicAddPairwiseKeyEntry(pAd,
-										pAd->StaCfg.DLSEntry[i].MacAddr,
-										(UCHAR)pAd->StaCfg.DLSEntry[i].MacTabMatchWCID,
-										&PairwiseKey);
-
-				RTMPAddWcidAttributeEntry(pAd,
-										  BSS0,
-										  0,
-										  PairwiseKey.CipherAlg,
-										  pEntry);
-
-#endif // RTMP_MAC_PCI //
-				NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
-				DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Peer STA MAC Address STAKey) \n"));
-
-				RTMPSendSTAKeyHandShake(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
-
-				DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Initiator side)\n"));
-			}
-			else
-			{
-				// Data frame, update timeout value
-				if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
-				{
-					pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
-					//AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
-				}
-			}
-
-			bFindEntry = TRUE;
-		}
-	}
-
-	// update peer dls table entry
-	for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
-	{
-		if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
-		{
-			if (bSTAKeyFrame)
-			{
-				PMAC_TABLE_ENTRY pEntry = NULL;
-
-				// STAKey frame, add pairwise key table, and send STAkey Msg-2
-				pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
-				RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
-
-				PairwiseKey.KeyLen = LEN_TKIP_EK;
-				NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], LEN_TKIP_EK);
-				NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], LEN_TKIP_RXMICK);
-				NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], LEN_TKIP_TXMICK);
-
-				//PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg;
-				if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
-					PairwiseKey.CipherAlg = CIPHER_TKIP;
-				else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
-					PairwiseKey.CipherAlg = CIPHER_AES;
-
-				pEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
-				//AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE);	// reserve 0 for multicast, 1 for unicast
-				//AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
-				// Add Pair-wise key to Asic
-#ifdef RTMP_MAC_PCI
-		AsicAddPairwiseKeyEntry(pAd,
-										pAd->StaCfg.DLSEntry[i].MacAddr,
-										(UCHAR)pAd->StaCfg.DLSEntry[i].MacTabMatchWCID,
-										&PairwiseKey);
-
-				RTMPAddWcidAttributeEntry(pAd,
-										  BSS0,
-										  0,
-										  PairwiseKey.CipherAlg,
-										  pEntry);
-#endif // RTMP_MAC_PCI //
-				NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
-				DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Initiator STA MAC Address STAKey)\n"));
-
-				// If support WPA or WPA2, start STAKey hand shake,
-				// If failed hand shake, just tear down peer DLS
-				if (RTMPSendSTAKeyHandShake(pAd, pAddr) != NDIS_STATUS_SUCCESS)
-				{
-					MLME_DLS_REQ_STRUCT	MlmeDlsReq;
-					USHORT				reason = REASON_QOS_CIPHER_NOT_SUPPORT;
-
-					pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
-					pAd->StaCfg.DLSEntry[i].Status	= DLS_NONE;
-					DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
-					MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
-				}
-				else
-				{
-					DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Peer side)\n"));
-				}
-			}
-			else
-			{
-				// Data frame, update timeout value
-				if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
-				{
-					pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
-				}
-			}
-
-			bFindEntry = TRUE;
-		}
-	}
-
-
-	return bSTAKeyFrame;
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Check if the frame can be sent through DLS direct link interface
-
-	Arguments:
-		pAd		Pointer	to adapter
-
-	Return Value:
-		DLS entry index
-
-	Note:
-
-	========================================================================
-*/
-INT	RTMPCheckDLSFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN  PUCHAR          pDA)
-{
-	INT rval = -1;
-	INT	i;
-
-	if (!pAd->CommonCfg.bDLSCapable)
-		return rval;
-
-	if (!INFRA_ON(pAd))
-		return rval;
-
-	do{
-		// check local dls table entry
-		for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
-		{
-			if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
-				MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
-			{
-				rval = i;
-				break;
-			}
-		}
-
-		// check peer dls table entry
-		for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
-		{
-			if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
-				MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
-			{
-				rval = i;
-				break;
-			}
-		}
-	} while (FALSE);
-
-	return rval;
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-VOID RTMPSendDLSTearDownFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN  PUCHAR          pDA)
-{
-	PUCHAR			pOutBuffer = NULL;
-	NDIS_STATUS		NStatus;
-	HEADER_802_11	DlsTearDownHdr;
-	ULONG			FrameLen = 0;
-	USHORT			Reason = REASON_QOS_QSTA_LEAVING_QBSS;
-	UCHAR			Category = CATEGORY_DLS;
-	UCHAR			Action = ACTION_DLS_TEARDOWN;
-	UCHAR			i = 0;
-
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
-		RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
-		return;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame \n"));
-
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-	if (NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("ASSOC - RTMPSendDLSTearDownFrame() allocate memory failed \n"));
-		return;
-	}
-
-	ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
-	MakeOutgoingFrame(pOutBuffer,				&FrameLen,
-					sizeof(HEADER_802_11),		&DlsTearDownHdr,
-					1,							&Category,
-					1,							&Action,
-					6,							pDA,
-					6,							pAd->CurrentAddress,
-					2,							&Reason,
-					END_OF_ARGS);
-
-	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-	// Remove key in local dls table entry
-	for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
-	{
-		if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
-			&& MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
-		{
-			MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
-		}
-	}
-
-	// Remove key in peer dls table entry
-	for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
-	{
-		if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
-			&& MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
-		{
-			MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
-		}
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame and remove key in (i=%d) \n", i));
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-NDIS_STATUS RTMPSendSTAKeyRequest(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pDA)
-{
-	UCHAR				Header802_3[14];
-	NDIS_STATUS			NStatus;
-	ULONG				FrameLen = 0;
-	EAPOL_PACKET		Packet;
-	UCHAR				Mic[16];
-	UCHAR				digest[80];
-	PUCHAR				pOutBuffer = NULL;
-	PNDIS_PACKET		pNdisPacket;
-	UCHAR				temp[64];
-	UCHAR				DlsPTK[80];
-
-	DBGPRINT(RT_DEBUG_TRACE,("DLS - RTMPSendSTAKeyRequest() to %02x:%02x:%02x:%02x:%02x:%02x\n", pDA[0], pDA[1], pDA[2], pDA[3], pDA[4], pDA[5]));
-
-	pAd->Sequence ++;
-	MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
-
-	// Zero message body
-	NdisZeroMemory(&Packet, sizeof(Packet));
-	Packet.ProVer = EAPOL_VER;
-	Packet.ProType    = EAPOLKey;
-	Packet.Body_Len[1]  = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN;		// data field contain KDE andPeer MAC address
-
-	// STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
-	if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
-    {
-        Packet.KeyDesc.Type = WPA1_KEY_DESC;
-    }
-    else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
-    {
-        Packet.KeyDesc.Type = WPA2_KEY_DESC;
-    }
-
-	// Key descriptor version
-	Packet.KeyDesc.KeyInfo.KeyDescVer =
-		(((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
-
-	Packet.KeyDesc.KeyInfo.KeyMic	= 1;
-	Packet.KeyDesc.KeyInfo.Secure	= 1;
-	Packet.KeyDesc.KeyInfo.Request	= 1;
-
-	Packet.KeyDesc.KeyDataLen[1]	= 12;
-
-	// use our own OUI to distinguish proprietary with standard.
-	Packet.KeyDesc.KeyData[0]		= 0xDD;
-	Packet.KeyDesc.KeyData[1]		= 0x0A;
-	Packet.KeyDesc.KeyData[2]		= 0x00;
-	Packet.KeyDesc.KeyData[3]		= 0x0C;
-	Packet.KeyDesc.KeyData[4]		= 0x43;
-	Packet.KeyDesc.KeyData[5]		= 0x03;
-	NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
-
-	NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
-
-	// Allocate buffer for transmitting message
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
-	if (NStatus	!= NDIS_STATUS_SUCCESS)
-		return NStatus;
-
-	// Prepare EAPOL frame for MIC calculation
-	// Be careful, only EAPOL frame is counted for MIC calculation
-	MakeOutgoingFrame(pOutBuffer,           &FrameLen,
-		              Packet.Body_Len[1] + 4,    &Packet,
-		              END_OF_ARGS);
-
-	// use proprietary PTK
-	NdisZeroMemory(temp, 64);
-	NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
-	WpaDerivePTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
-
-	// calculate MIC
-	if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
-	{
-		// AES
-		NdisZeroMemory(digest,	sizeof(digest));
-		HMAC_SHA1(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE);
-		NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
-	}
-	else
-	{
-		NdisZeroMemory(Mic,	sizeof(Mic));
-		HMAC_MD5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic, MD5_DIGEST_SIZE);
-		NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
-	}
-
-	MakeOutgoingFrame(pOutBuffer,           &FrameLen,
-	                  sizeof(Header802_3),	Header802_3,
-		              Packet.Body_Len[1] + 4,	&Packet,
-		              END_OF_ARGS);
-
-	NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
-	if (NStatus == NDIS_STATUS_SUCCESS)
-	{
-		RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
-		STASendPacket(pAd, pNdisPacket);
-		RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
-	}
-
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyRequest- Send STAKey request (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
-
-	return NStatus;
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-NDIS_STATUS RTMPSendSTAKeyHandShake(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pDA)
-{
-	UCHAR				Header802_3[14];
-	NDIS_STATUS			NStatus;
-	ULONG				FrameLen = 0;
-	EAPOL_PACKET		Packet;
-	UCHAR				Mic[16];
-	UCHAR				digest[80];
-	PUCHAR				pOutBuffer = NULL;
-	PNDIS_PACKET		pNdisPacket;
-	UCHAR				temp[64];
-	UCHAR				DlsPTK[80];			// Due to dirver can not get PTK, use proprietary PTK
-
-	DBGPRINT(RT_DEBUG_TRACE,("DLS - RTMPSendSTAKeyHandShake() to %02x:%02x:%02x:%02x:%02x:%02x\n", pDA[0], pDA[1], pDA[2], pDA[3], pDA[4], pDA[5]));
-
-	pAd->Sequence ++;
-	MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
-
-	// Zero message body
-	NdisZeroMemory(&Packet, sizeof(Packet));
-	Packet.ProVer = EAPOL_VER;
-	Packet.ProType    = EAPOLKey;
-	Packet.Body_Len[1]  = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN;		// data field contain KDE and Peer MAC address
-
-	// STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
-	if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
-    {
-        Packet.KeyDesc.Type = WPA1_KEY_DESC;
-    }
-    else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
-    {
-        Packet.KeyDesc.Type = WPA2_KEY_DESC;
-    }
-
-	// Key descriptor version
-	Packet.KeyDesc.KeyInfo.KeyDescVer =
-		(((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
-
-	Packet.KeyDesc.KeyInfo.KeyMic	= 1;
-	Packet.KeyDesc.KeyInfo.Secure	= 1;
-
-	Packet.KeyDesc.KeyDataLen[1]	= 12;
-
-	// use our own OUI to distinguish proprietary with standard.
-	Packet.KeyDesc.KeyData[0]		= 0xDD;
-	Packet.KeyDesc.KeyData[1]		= 0x0A;
-	Packet.KeyDesc.KeyData[2]		= 0x00;
-	Packet.KeyDesc.KeyData[3]		= 0x0C;
-	Packet.KeyDesc.KeyData[4]		= 0x43;
-	Packet.KeyDesc.KeyData[5]		= 0x03;
-	NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
-
-	NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
-
-	// Allocate buffer for transmitting message
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
-	if (NStatus	!= NDIS_STATUS_SUCCESS)
-		return NStatus;
-
-	// Prepare EAPOL frame for MIC calculation
-	// Be careful, only EAPOL frame is counted for MIC calculation
-	MakeOutgoingFrame(pOutBuffer,           &FrameLen,
-		              Packet.Body_Len[1] + 4,    &Packet,
-		              END_OF_ARGS);
-
-	// use proprietary PTK
-	NdisZeroMemory(temp, 64);
-	NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
-	WpaDerivePTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
-
-	// calculate MIC
-	if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
-	{
-		// AES
-		NdisZeroMemory(digest,	sizeof(digest));
-		HMAC_SHA1(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE);
-		NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
-	}
-	else
-	{
-		NdisZeroMemory(Mic,	sizeof(Mic));
-		HMAC_MD5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic, MD5_DIGEST_SIZE);
-		NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
-	}
-
-	MakeOutgoingFrame(pOutBuffer,           &FrameLen,
-	                  sizeof(Header802_3),	Header802_3,
-		              Packet.Body_Len[1] + 4,	&Packet,
-		              END_OF_ARGS);
-
-	NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
-	if (NStatus == NDIS_STATUS_SUCCESS)
-	{
-		RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
-		STASendPacket(pAd, pNdisPacket);
-		RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
-	}
-
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyHandShake- Send STAKey Message-2 (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
-
-	return NStatus;
-}
-
-VOID DlsTimeoutAction(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3)
-{
-	MLME_DLS_REQ_STRUCT		MlmeDlsReq;
-	USHORT					reason;
-	PRT_802_11_DLS			pDLS = (PRT_802_11_DLS)FunctionContext;
-	PRTMP_ADAPTER			pAd = pDLS->pAd;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("DlsTimeout - Tear down DLS links (%02x:%02x:%02x:%02x:%02x:%02x)\n",
-		pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5]));
-
-	if ((pDLS) && (pDLS->Valid))
-	{
-		reason			= REASON_QOS_REQUEST_TIMEOUT;
-		pDLS->Valid		= FALSE;
-		pDLS->Status	= DLS_NONE;
-		DlsParmFill(pAd, &MlmeDlsReq, pDLS, reason);
-		MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
-		RTMP_MLME_HANDLER(pAd);
-	}
-}
-
-/*
-================================================================
-Description : because DLS and CLI share the same WCID table in ASIC.
-Mesh entry also insert to pAd->MacTab.content[].  Such is marked as ValidAsDls = TRUE.
-Also fills the pairwise key.
-Because front MAX_AID_BA entries have direct mapping to BAEntry, which is only used as CLI. So we insert Dls
-from index MAX_AID_BA.
-================================================================
-*/
-MAC_TABLE_ENTRY *MacTableInsertDlsEntry(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  PUCHAR	pAddr,
-	IN  UINT	DlsEntryIdx)
-{
-	PMAC_TABLE_ENTRY pEntry = NULL;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableInsertDlsEntry\n"));
-	// if FULL, return
-	if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
-		return NULL;
-
-	do
-	{
-		if((pEntry = DlsEntryTableLookup(pAd, pAddr, TRUE)) != NULL)
-			break;
-
-		// allocate one MAC entry
-		pEntry = MacTableInsertEntry(pAd, pAddr, DlsEntryIdx + MIN_NET_DEVICE_FOR_DLS, TRUE);
-		if (pEntry)
-		{
-			pAd->StaCfg.DLSEntry[DlsEntryIdx].MacTabMatchWCID = pEntry->Aid;
-			pEntry->MatchDlsEntryIdx = DlsEntryIdx;
-			pEntry->AuthMode = pAd->StaCfg.AuthMode;
-			pEntry->WepStatus = pAd->StaCfg.WepStatus;
-			pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
-
-			DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertDlsEntry - allocate entry #%d, Total= %d\n",pEntry->Aid, pAd->MacTab.Size));
-
-			// If legacy WEP is used, set pair-wise cipherAlg into WCID attribute table for this entry
-			if ((pEntry->ValidAsDls) && (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled))
-			{
-				UCHAR KeyIdx = 0;
-				UCHAR CipherAlg = 0;
-
-				KeyIdx	= pAd->StaCfg.DefaultKeyId;
-
-				CipherAlg	= pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
-
-				RTMPAddWcidAttributeEntry(pAd,
-											BSS0,
-											pAd->StaCfg.DefaultKeyId,
-											pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
-											pEntry);
-			}
-
-			break;
-		}
-	} while(FALSE);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableInsertDlsEntry\n"));
-
-	return pEntry;
-}
-
-
-/*
-	==========================================================================
-	Description:
-		Delete all Mesh Entry in pAd->MacTab
-	==========================================================================
- */
-BOOLEAN MacTableDeleteDlsEntry(
-	IN PRTMP_ADAPTER pAd,
-	IN USHORT wcid,
-	IN PUCHAR pAddr)
-{
-	DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableDeleteDlsEntry\n"));
-
-	if (!VALID_WCID(wcid))
-		return FALSE;
-
-	MacTableDeleteEntry(pAd, wcid, pAddr);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableDeleteDlsEntry\n"));
-
-	return TRUE;
-}
-
-MAC_TABLE_ENTRY *DlsEntryTableLookup(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR	pAddr,
-	IN BOOLEAN	bResetIdelCount)
-{
-	ULONG HashIdx;
-	MAC_TABLE_ENTRY *pEntry = NULL;
-
-	RTMP_SEM_LOCK(&pAd->MacTabLock);
-	HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
-	pEntry = pAd->MacTab.Hash[HashIdx];
-
-	while (pEntry)
-	{
-		if ((pEntry->ValidAsDls == TRUE)
-			&& MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
-		{
-			if(bResetIdelCount)
-				pEntry->NoDataIdleCount = 0;
-			break;
-		}
-		else
-			pEntry = pEntry->pNext;
-	}
-
-	RTMP_SEM_UNLOCK(&pAd->MacTabLock);
-	return pEntry;
-}
-
-MAC_TABLE_ENTRY *DlsEntryTableLookupByWcid(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR	wcid,
-	IN PUCHAR	pAddr,
-	IN BOOLEAN	bResetIdelCount)
-{
-	ULONG DLsIndex;
-	PMAC_TABLE_ENTRY pCurEntry = NULL;
-	PMAC_TABLE_ENTRY pEntry = NULL;
-
-	if (!VALID_WCID(wcid))
-		return NULL;
-
-	RTMP_SEM_LOCK(&pAd->MacTabLock);
-
-	do
-	{
-		pCurEntry = &pAd->MacTab.Content[wcid];
-
-		DLsIndex = 0xff;
-		if ((pCurEntry) && (pCurEntry->ValidAsDls== TRUE))
-		{
-			DLsIndex = pCurEntry->MatchDlsEntryIdx;
-		}
-
-		if (DLsIndex == 0xff)
-			break;
-
-		if (MAC_ADDR_EQUAL(pCurEntry->Addr, pAddr))
-		{
-			if(bResetIdelCount)
-				pCurEntry->NoDataIdleCount = 0;
-			pEntry = pCurEntry;
-			break;
-		}
-	} while(FALSE);
-
-	RTMP_SEM_UNLOCK(&pAd->MacTabLock);
-
-	return pEntry;
-}
-
-INT Set_DlsEntryInfo_Display_Proc(
-	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR arg)
-{
-	INT i;
-
-	DBGPRINT(RT_DEBUG_OFF, ("\n%-19s%-8s\n", "MAC", "TIMEOUT\n"));
-	for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
-	{
-		if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
-		{
-			PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[pAd->StaCfg.DLSEntry[i].MacTabMatchWCID];
-
-			DBGPRINT(RT_DEBUG_OFF, ("%02x:%02x:%02x:%02x:%02x:%02x  ",
-				pAd->StaCfg.DLSEntry[i].MacAddr[0], pAd->StaCfg.DLSEntry[i].MacAddr[1], pAd->StaCfg.DLSEntry[i].MacAddr[2],
-				pAd->StaCfg.DLSEntry[i].MacAddr[3], pAd->StaCfg.DLSEntry[i].MacAddr[4], pAd->StaCfg.DLSEntry[i].MacAddr[5]));
-			DBGPRINT(RT_DEBUG_OFF, ("%-8d\n", pAd->StaCfg.DLSEntry[i].TimeOut));
-
-			DBGPRINT(RT_DEBUG_OFF, ("\n"));
-			DBGPRINT(RT_DEBUG_OFF, ("\n%-19s%-4s%-4s%-4s%-4s%-7s%-7s%-7s","MAC", "AID", "BSS", "PSM", "WMM", "RSSI0", "RSSI1", "RSSI2"));
-#ifdef DOT11_N_SUPPORT
-			DBGPRINT(RT_DEBUG_OFF, ("%-8s%-10s%-6s%-6s%-6s%-6s", "MIMOPS", "PhMd", "BW", "MCS", "SGI", "STBC"));
-#endif // DOT11_N_SUPPORT //
-			DBGPRINT(RT_DEBUG_OFF, ("\n%02X:%02X:%02X:%02X:%02X:%02X  ",
-				pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
-				pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]));
-			DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)pEntry->Aid));
-			DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)pEntry->apidx));
-			DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)pEntry->PsMode));
-			DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE)));
-			DBGPRINT(RT_DEBUG_OFF, ("%-7d", pEntry->RssiSample.AvgRssi0));
-			DBGPRINT(RT_DEBUG_OFF, ("%-7d", pEntry->RssiSample.AvgRssi1));
-			DBGPRINT(RT_DEBUG_OFF, ("%-7d", pEntry->RssiSample.AvgRssi2));
-#ifdef DOT11_N_SUPPORT
-			DBGPRINT(RT_DEBUG_OFF, ("%-8d", (int)pEntry->MmpsMode));
-			DBGPRINT(RT_DEBUG_OFF, ("%-10s", GetPhyMode(pEntry->HTPhyMode.field.MODE)));
-			DBGPRINT(RT_DEBUG_OFF, ("%-6s", GetBW(pEntry->HTPhyMode.field.BW)));
-			DBGPRINT(RT_DEBUG_OFF, ("%-6d", pEntry->HTPhyMode.field.MCS));
-			DBGPRINT(RT_DEBUG_OFF, ("%-6d", pEntry->HTPhyMode.field.ShortGI));
-			DBGPRINT(RT_DEBUG_OFF, ("%-6d", pEntry->HTPhyMode.field.STBC));
-#endif // DOT11_N_SUPPORT //
-			DBGPRINT(RT_DEBUG_OFF, ("%-10d, %d, %d%%\n", pEntry->DebugFIFOCount, pEntry->DebugTxCount,
-						(pEntry->DebugTxCount) ? ((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount) : 0));
-			DBGPRINT(RT_DEBUG_OFF, ("\n"));
-
-		}
-	}
-
-	return TRUE;
-}
-
-INT	Set_DlsAddEntry_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-    UCHAR	mac[MAC_ADDR_LEN];
-	USHORT	Timeout;
-	PSTRING token;
-	STRING sepValue[] = ":", DASH = '-';
-	INT i;
-    RT_802_11_DLS	Dls;
-
-    if(strlen(arg) < 19)  //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and timeout value in decimal format.
-		return FALSE;
-
-	token = strchr(arg, DASH);
-	if ((token != NULL) && (strlen(token)>1))
-	{
-		Timeout = (USHORT) simple_strtol((token+1), 0, 10);
-
-		*token = '\0';
-		for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
-		{
-			if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
-				return FALSE;
-			AtoH(token, (&mac[i]), 1);
-		}
-		if(i != 6)
-			return FALSE;
-
-	    DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%d", mac[0], mac[1],
-	           mac[2], mac[3], mac[4], mac[5], (int)Timeout));
-
-		NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
-		Dls.TimeOut = Timeout;
-		COPY_MAC_ADDR(Dls.MacAddr, mac);
-		Dls.Valid = 1;
-
-		MlmeEnqueue(pAd,
-					MLME_CNTL_STATE_MACHINE,
-					RT_OID_802_11_SET_DLS_PARAM,
-					sizeof(RT_802_11_DLS),
-					&Dls);
-
-		return TRUE;
-	}
-
-	return FALSE;
-
-}
-
-INT	Set_DlsTearDownEntry_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	UCHAR			macAddr[MAC_ADDR_LEN];
-	PSTRING			value;
-	INT				i;
-	RT_802_11_DLS	Dls;
-
-	if(strlen(arg) != 17)  //Mac address acceptable format 01:02:03:04:05:06 length 17
-		return FALSE;
-
-	for (i=0, value = rstrtok(arg,":"); value; value = rstrtok(NULL,":"))
-	{
-		if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
-			return FALSE;  //Invalid
-
-		AtoH(value, &macAddr[i++], 2);
-	}
-
-	DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x", macAddr[0], macAddr[1],
-	           macAddr[2], macAddr[3], macAddr[4], macAddr[5]));
-
-	NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
-	COPY_MAC_ADDR(Dls.MacAddr, macAddr);
-	Dls.Valid = 0;
-
-	MlmeEnqueue(pAd,
-				MLME_CNTL_STATE_MACHINE,
-				RT_OID_802_11_SET_DLS_PARAM,
-				sizeof(RT_802_11_DLS),
-				&Dls);
-
-	return TRUE;
-}
diff --git a/drivers/staging/rt3090/sta/rtmp_ckipmic.c b/drivers/staging/rt3090/sta/rtmp_ckipmic.c
deleted file mode 100644
index 5f6dbd7..0000000
--- a/drivers/staging/rt3090/sta/rtmp_ckipmic.c
+++ /dev/null
@@ -1,579 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtmp_ckipmic.c
-
-	Abstract:
-	Data path subroutines
-
-	Revision History:
-	Who		When			What
-	--------	----------		----------------------------------------------
-*/
-
-#include "../rt_config.h"
-#include "../rtmp_ckipmic.h"
-
-
-#define MIC_ACCUM(v)            pContext->accum += (ULONGLONG)v * RTMPMicGetCoefficient(pContext)
-#define GB(p,i,s)               ( ((ULONG) *((UCHAR*)(p)+i) ) << (s) )
-#define GETBIG32(p)             GB(p,0,24)|GB(p,1,16)|GB(p,2,8)|GB(p,3,0)
-
-/*****************************/
-/******** SBOX Table *********/
-/*****************************/
-
-UCHAR SboxTable[256] =
-{
-    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
-    0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
-    0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
-    0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
-    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
-    0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
-    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
-    0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
-    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
-    0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
-    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
-    0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
-    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
-    0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
-    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
-    0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
-    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
-    0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
-    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
-    0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
-    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
-    0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
-    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
-    0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
-    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
-    0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
-    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
-    0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
-    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
-    0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
-    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
-    0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-};
-
-/*===========================================================================*/
-/*=================== CKIP KEY PERMUTATION ==================================*/
-/*===========================================================================*/
-
-/* 2-byte by 2-byte subset of the full AES table */
-static const USHORT 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
-    };
-
-#define Lo8(v16)     ((v16)       & 0xFF)
-#define Hi8(v16)    (((v16) >> 8) & 0xFF)
-#define u16Swap(i)  ( (((i) >> 8) & 0xFF) | (((i) << 8) & 0xFF00) )
-#define _S_(i)      (Sbox[Lo8(i)] ^ u16Swap(Sbox[Hi8(i)]))
-
-#define rotLeft_1(x) ((((x) << 1) | ((x) >> 15)) & 0xFFFF)
-VOID CKIP_key_permute
-    (
-     OUT UCHAR  *PK,           /* output permuted key */
-     IN UCHAR *CK,           /* input CKIP key */
-     IN UCHAR  toDsFromDs,    /* input toDs/FromDs bits */
-     IN UCHAR *piv           /* input pointer to IV */
-     )
-{
-    int i;
-    USHORT H[2], tmp;          /* H=32-bits of per-packet hash value */
-    USHORT L[8], R[8];         /* L=u16 array of CK, R=u16 array of PK */
-
-    /* build L from input key */
-    memset(L, 0, sizeof(L));
-    for (i=0; i<16; i++) {
-        L[i>>1] |= ( ((USHORT)(CK[i])) << ( i & 1 ? 8 : 0) );
-    }
-
-    H[0] = (((USHORT)piv[0]) << 8) + piv[1];
-    H[1] = ( ((USHORT)toDsFromDs) << 8) | piv[2];
-
-    for (i=0; i<8; i++) {
-        H[0] ^= L[i];           /* 16-bits of key material */
-        tmp   = _S_(H[0]);      /* 16x16 permutation */
-        H[0]  = tmp ^ H[1];     /* set up for next round */
-        H[1]  = tmp;
-        R[i]  = H[0];           /* store into key array  */
-    }
-
-    /* sweep in the other direction */
-    tmp=L[0];
-    for (i=7; i>0; i--) {
-        R[i] = tmp = rotLeft_1(tmp) + R[i];
-    }
-
-    /* IV of the permuted key is unchanged */
-    PK[0] = piv[0];
-    PK[1] = piv[1];
-    PK[2] = piv[2];
-
-    /* key portion of the permuted key is changed */
-    for (i=3; i<16; i++) {
-        PK[i] = (UCHAR) (R[i>>1] >> (i & 1 ? 8 : 0));
-    }
-}
-
-/* prepare for calculation of a new mic */
-VOID RTMPCkipMicInit(
-    IN  PMIC_CONTEXT        pContext,
-    IN  PUCHAR              CK)
-{
-    /* prepare for new mic calculation */
-    NdisMoveMemory(pContext->CK, CK, sizeof(pContext->CK));
-    pContext->accum = 0;
-    pContext->position = 0;
-}
-
-/* add some bytes to the mic calculation */
-VOID RTMPMicUpdate(
-    IN  PMIC_CONTEXT        pContext,
-    IN  PUCHAR              pOctets,
-    IN  INT                 len)
-{
-    INT     byte_position;
-    ULONG   val;
-
-    byte_position = (pContext->position & 3);
-    while (len > 0) {
-        /* build a 32-bit word for MIC multiply accumulate */
-        do {
-            if (len == 0) return;
-            pContext->part[byte_position++] = *pOctets++;
-            pContext->position++;
-            len--;
-        } while (byte_position < 4);
-        /* have a full 32-bit word to process */
-        val = GETBIG32(&pContext->part[0]);
-        MIC_ACCUM(val);
-        byte_position = 0;
-    }
-}
-
-ULONG RTMPMicGetCoefficient(
-    IN  PMIC_CONTEXT         pContext)
-{
-    UCHAR   aes_counter[16];
-    INT     coeff_position;
-    UCHAR   *p;
-
-    coeff_position = (pContext->position - 1) >> 2;
-    if ( (coeff_position & 3) == 0) {
-        /* fetching the first coefficient -- get new 16-byte aes counter output */
-        u32 counter = (coeff_position >> 2);
-
-        /* new counter value */
-        memset(&aes_counter[0], 0, sizeof(aes_counter));
-        aes_counter[15] = (UINT8)(counter >> 0);
-        aes_counter[14] = (UINT8)(counter >> 8);
-        aes_counter[13] = (UINT8)(counter >> 16);
-        aes_counter[12] = (UINT8)(counter >> 24);
-
-        RTMPAesEncrypt(&pContext->CK[0], &aes_counter[0], pContext->coefficient);
-    }
-    p = &(pContext->coefficient[ (coeff_position & 3) << 2 ]);
-    return GETBIG32(p);
-}
-
-/****************************************/
-/* aes128k128d()                        */
-/* Performs a 128 bit AES encrypt with  */
-/* 128 bit data.                        */
-/****************************************/
-VOID xor_128(
-    IN  PUCHAR  a,
-    IN  PUCHAR  b,
-    OUT PUCHAR  out)
-{
-    INT i;
-
-    for (i=0;i<16; i++)
-    {
-        out[i] = a[i] ^ b[i];
-    }
-}
-
-UCHAR RTMPCkipSbox(
-    IN  UCHAR   a)
-{
-    return SboxTable[(int)a];
-}
-
-VOID xor_32(
-    IN  PUCHAR  a,
-    IN  PUCHAR  b,
-    OUT PUCHAR  out)
-{
-    INT i;
-
-    for (i=0;i<4; i++)
-    {
-        out[i] = a[i] ^ b[i];
-    }
-}
-
-VOID next_key(
-    IN  PUCHAR  key,
-    IN  INT     round)
-{
-    UCHAR       rcon;
-    UCHAR       sbox_key[4];
-    UCHAR       rcon_table[12] =
-    {
-        0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
-        0x1b, 0x36, 0x36, 0x36
-    };
-
-    sbox_key[0] = RTMPCkipSbox(key[13]);
-    sbox_key[1] = RTMPCkipSbox(key[14]);
-    sbox_key[2] = RTMPCkipSbox(key[15]);
-    sbox_key[3] = RTMPCkipSbox(key[12]);
-
-    rcon = rcon_table[round];
-
-    xor_32(&key[0], sbox_key, &key[0]);
-    key[0] = key[0] ^ rcon;
-
-    xor_32(&key[4], &key[0], &key[4]);
-    xor_32(&key[8], &key[4], &key[8]);
-    xor_32(&key[12], &key[8], &key[12]);
-}
-
-VOID byte_sub(
-    IN  PUCHAR  in,
-    OUT PUCHAR  out)
-{
-    INT i;
-
-    for (i=0; i< 16; i++)
-    {
-        out[i] = RTMPCkipSbox(in[i]);
-    }
-}
-
-VOID shift_row(
-    IN  PUCHAR  in,
-    OUT PUCHAR  out)
-{
-    out[0] =  in[0];
-    out[1] =  in[5];
-    out[2] =  in[10];
-    out[3] =  in[15];
-    out[4] =  in[4];
-    out[5] =  in[9];
-    out[6] =  in[14];
-    out[7] =  in[3];
-    out[8] =  in[8];
-    out[9] =  in[13];
-    out[10] = in[2];
-    out[11] = in[7];
-    out[12] = in[12];
-    out[13] = in[1];
-    out[14] = in[6];
-    out[15] = in[11];
-}
-
-VOID mix_column(
-    IN  PUCHAR  in,
-    OUT PUCHAR  out)
-{
-    INT         i;
-    UCHAR       add1b[4];
-    UCHAR       add1bf7[4];
-    UCHAR       rotl[4];
-    UCHAR       swap_halfs[4];
-    UCHAR       andf7[4];
-    UCHAR       rotr[4];
-    UCHAR       temp[4];
-    UCHAR       tempb[4];
-
-    for (i=0 ; i<4; i++)
-    {
-        if ((in[i] & 0x80)== 0x80)
-            add1b[i] = 0x1b;
-        else
-            add1b[i] = 0x00;
-    }
-
-    swap_halfs[0] = in[2];    /* Swap halfs */
-    swap_halfs[1] = in[3];
-    swap_halfs[2] = in[0];
-    swap_halfs[3] = in[1];
-
-    rotl[0] = in[3];        /* Rotate left 8 bits */
-    rotl[1] = in[0];
-    rotl[2] = in[1];
-    rotl[3] = in[2];
-
-    andf7[0] = in[0] & 0x7f;
-    andf7[1] = in[1] & 0x7f;
-    andf7[2] = in[2] & 0x7f;
-    andf7[3] = in[3] & 0x7f;
-
-    for (i = 3; i>0; i--)    /* logical shift left 1 bit */
-    {
-        andf7[i] = andf7[i] << 1;
-        if ((andf7[i-1] & 0x80) == 0x80)
-        {
-            andf7[i] = (andf7[i] | 0x01);
-        }
-    }
-    andf7[0] = andf7[0] << 1;
-    andf7[0] = andf7[0] & 0xfe;
-
-    xor_32(add1b, andf7, add1bf7);
-
-    xor_32(in, add1bf7, rotr);
-
-    temp[0] = rotr[0];         /* Rotate right 8 bits */
-    rotr[0] = rotr[1];
-    rotr[1] = rotr[2];
-    rotr[2] = rotr[3];
-    rotr[3] = temp[0];
-
-    xor_32(add1bf7, rotr, temp);
-    xor_32(swap_halfs, rotl,tempb);
-    xor_32(temp, tempb, out);
-}
-
-VOID RTMPAesEncrypt(
-    IN  PUCHAR  key,
-    IN  PUCHAR  data,
-    IN  PUCHAR  ciphertext)
-{
-    INT             round;
-    INT             i;
-    UCHAR           intermediatea[16];
-    UCHAR           intermediateb[16];
-    UCHAR           round_key[16];
-
-    for(i=0; i<16; i++) round_key[i] = key[i];
-
-    for (round = 0; round < 11; round++)
-    {
-        if (round == 0)
-        {
-            xor_128(round_key, data, ciphertext);
-            next_key(round_key, round);
-        }
-        else if (round == 10)
-        {
-            byte_sub(ciphertext, intermediatea);
-            shift_row(intermediatea, intermediateb);
-            xor_128(intermediateb, round_key, ciphertext);
-        }
-        else    /* 1 - 9 */
-        {
-            byte_sub(ciphertext, intermediatea);
-            shift_row(intermediatea, intermediateb);
-            mix_column(&intermediateb[0], &intermediatea[0]);
-            mix_column(&intermediateb[4], &intermediatea[4]);
-            mix_column(&intermediateb[8], &intermediatea[8]);
-            mix_column(&intermediateb[12], &intermediatea[12]);
-            xor_128(intermediatea, round_key, ciphertext);
-            next_key(round_key, round);
-        }
-    }
-
-}
-
-/* calculate the mic */
-VOID RTMPMicFinal(
-    IN  PMIC_CONTEXT    pContext,
-    OUT UCHAR           digest[4])
-{
-    INT             byte_position;
-    ULONG           val;
-    ULONGLONG       sum, utmp;
-    LONGLONG        stmp;
-
-    /* deal with partial 32-bit word left over from last update */
-    if ( (byte_position = (pContext->position & 3)) != 0) {
-        /* have a partial word in part to deal with -- zero unused bytes */
-        do {
-            pContext->part[byte_position++] = 0;
-            pContext->position++;
-        } while (byte_position < 4);
-        val = GETBIG32(&pContext->part[0]);
-        MIC_ACCUM(val);
-    }
-
-    /* reduce the accumulated u64 to a 32-bit MIC */
-    sum = pContext->accum;
-    stmp = (sum  & 0xffffffffL) - ((sum >> 32)  * 15);
-    utmp = (stmp & 0xffffffffL) - ((stmp >> 32) * 15);
-    sum = utmp & 0xffffffffL;
-    if (utmp > 0x10000000fL)
-        sum -= 15;
-
-    val = (ULONG)sum;
-    digest[0] = (UCHAR)((val>>24) & 0xFF);
-    digest[1] = (UCHAR) ((val>>16) & 0xFF);
-    digest[2] = (UCHAR) ((val>>8) & 0xFF);
-    digest[3] = (UCHAR)((val>>0) & 0xFF);
-}
-
-VOID RTMPCkipInsertCMIC(
-    IN  PRTMP_ADAPTER   pAd,
-    OUT PUCHAR          pMIC,
-    IN  PUCHAR          p80211hdr,
-    IN  PNDIS_PACKET    pPacket,
-    IN  PCIPHER_KEY     pKey,
-    IN  PUCHAR          mic_snap)
-{
-	PACKET_INFO		PacketInfo;
-	PUCHAR			pSrcBufVA;
-	ULONG			SrcBufLen;
-    PUCHAR          pDA, pSA, pProto;
-    UCHAR           bigethlen[2];
-	UCHAR			ckip_ck[16];
-    MIC_CONTEXT     mic_ctx;
-    USHORT          payloadlen;
-	UCHAR			i;
-
-	if (pKey == NULL)
-	{
-		DBGPRINT_ERR(("RTMPCkipInsertCMIC, Before to form the CKIP key (CK), pKey can't be NULL\n"));
-		return;
-	}
-
-    switch (*(p80211hdr+1) & 3)
-    {
-        case 0: /* FromDs=0, ToDs=0 */
-            pDA = p80211hdr+4;
-            pSA = p80211hdr+10;
-            break;
-        case 1: /* FromDs=0, ToDs=1 */
-            pDA = p80211hdr+16;
-            pSA = p80211hdr+10;
-            break;
-        case 2: /* FromDs=1, ToDs=0 */
-            pDA = p80211hdr+4;
-            pSA = p80211hdr+16;
-            break;
-        case 3: /* FromDs=1, ToDs=1 */
-            pDA = p80211hdr+16;
-            pSA = p80211hdr+24;
-            break;
-    }
-
-	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
-
-    if (SrcBufLen < LENGTH_802_3)
-        return;
-
-    pProto = pSrcBufVA + 12;
-    payloadlen = PacketInfo.TotalPacketLength - LENGTH_802_3 + 18; // CKIP_LLC(8)+CMIC(4)+TxSEQ(4)+PROTO(2)=18
-
-    bigethlen[0] = (unsigned char)(payloadlen >> 8);
-    bigethlen[1] = (unsigned char)payloadlen;
-
-	//
-	// Encryption Key expansion to form the CKIP Key (CKIP_CK).
-	//
-	if (pKey->KeyLen < 16)
-	{
-		for(i = 0; i < (16 / pKey->KeyLen); i++)
-		{
-			NdisMoveMemory(ckip_ck + i * pKey->KeyLen,
-							pKey->Key,
-							pKey->KeyLen);
-		}
-		NdisMoveMemory(ckip_ck + i * pKey->KeyLen,
-						pKey->Key,
-						16 - (i * pKey->KeyLen));
-	}
-	else
-	{
-		NdisMoveMemory(ckip_ck, pKey->Key, pKey->KeyLen);
-	}
-    RTMPCkipMicInit(&mic_ctx, ckip_ck);
-    RTMPMicUpdate(&mic_ctx, pDA, MAC_ADDR_LEN);            // MIC <-- DA
-    RTMPMicUpdate(&mic_ctx, pSA, MAC_ADDR_LEN);            // MIC <-- SA
-    RTMPMicUpdate(&mic_ctx, bigethlen, 2);                 // MIC <-- payload length starting from CKIP SNAP
-    RTMPMicUpdate(&mic_ctx, mic_snap, 8);                  // MIC <-- snap header
-    RTMPMicUpdate(&mic_ctx, pAd->StaCfg.TxSEQ, 4);   // MIC <-- TxSEQ
-    RTMPMicUpdate(&mic_ctx, pProto, 2);                    // MIC <-- Protocol
-
-    pSrcBufVA += LENGTH_802_3;
-    SrcBufLen -= LENGTH_802_3;
-
-    // Mic <-- original payload. loop until all payload processed
-    do
-    {
-        if (SrcBufLen > 0)
-            RTMPMicUpdate(&mic_ctx, pSrcBufVA, SrcBufLen);
-
-		NdisGetNextBuffer(PacketInfo.pFirstBuffer, &PacketInfo.pFirstBuffer);
-        if (PacketInfo.pFirstBuffer)
-        {
-            NDIS_QUERY_BUFFER(PacketInfo.pFirstBuffer, &pSrcBufVA, &SrcBufLen);
-        }
-        else
-            break;
-    } while (TRUE);
-
-    RTMPMicFinal(&mic_ctx, pMIC);                          // update MIC
-}
diff --git a/drivers/staging/rt3090/sta/rtmp_data.c b/drivers/staging/rt3090/sta/rtmp_data.c
deleted file mode 100644
index 5591364..0000000
--- a/drivers/staging/rt3090/sta/rtmp_data.c
+++ /dev/null
@@ -1,2661 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtmp_data.c
-
-	Abstract:
-	Data path subroutines
-
-	Revision History:
-	Who		When			What
-	--------	----------		----------------------------------------------
-*/
-
-#include "../rt_config.h"
-
-
-VOID STARxEAPOLFrameIndicate(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MAC_TABLE_ENTRY	*pEntry,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID)
-{
-	PRT28XX_RXD_STRUC	pRxD = &(pRxBlk->RxD);
-	PRXWI_STRUC		pRxWI = pRxBlk->pRxWI;
-	UCHAR			*pTmpBuf;
-
-
-#ifdef WPA_SUPPLICANT_SUPPORT
-	if (pAd->StaCfg.WpaSupplicantUP)
-	{
-		// All EAPoL frames have to pass to upper layer (ex. WPA_SUPPLICANT daemon)
-		// TBD : process fragmented EAPol frames
-		{
-			// In 802.1x mode, if the received frame is EAP-SUCCESS packet, turn on the PortSecured variable
-			if ( pAd->StaCfg.IEEE8021X == TRUE &&
-				 (EAP_CODE_SUCCESS == WpaCheckEapCode(pAd, pRxBlk->pData, pRxBlk->DataSize, LENGTH_802_1_H)))
-			{
-				PUCHAR	Key;
-				UCHAR	CipherAlg;
-				int     idx = 0;
-
-				DBGPRINT_RAW(RT_DEBUG_TRACE, ("Receive EAP-SUCCESS Packet\n"));
-				//pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
-				STA_PORT_SECURED(pAd);
-
-                if (pAd->StaCfg.IEEE8021x_required_keys == FALSE)
-                {
-                    idx = pAd->StaCfg.DesireSharedKeyId;
-                    CipherAlg = pAd->StaCfg.DesireSharedKey[idx].CipherAlg;
-					Key = pAd->StaCfg.DesireSharedKey[idx].Key;
-
-                    if (pAd->StaCfg.DesireSharedKey[idx].KeyLen > 0)
-				{
-#ifdef RTMP_MAC_PCI
-						MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[BSSID_WCID];
-
-						// Set key material and cipherAlg to Asic
-						AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
-
-						// Assign group key info
-						RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
-
-						// Assign pairwise key info
-						RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
-
-                        pAd->IndicateMediaState = NdisMediaStateConnected;
-                        pAd->ExtraInfo = GENERAL_LINK_UP;
-#endif // RTMP_MAC_PCI //
-						// For Preventing ShardKey Table is cleared by remove key procedure.
-					pAd->SharedKey[BSS0][idx].CipherAlg = CipherAlg;
-						pAd->SharedKey[BSS0][idx].KeyLen = pAd->StaCfg.DesireSharedKey[idx].KeyLen;
-						NdisMoveMemory(pAd->SharedKey[BSS0][idx].Key,
-									   pAd->StaCfg.DesireSharedKey[idx].Key,
-									   pAd->StaCfg.DesireSharedKey[idx].KeyLen);
-				}
-				}
-			}
-
-			Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
-			return;
-		}
-	}
-	else
-#endif // WPA_SUPPLICANT_SUPPORT //
-	{
-		// Special DATA frame that has to pass to MLME
-		//	 1. Cisco Aironet frames for CCX2. We need pass it to MLME for special process
-		//	 2. EAPOL handshaking frames when driver supplicant enabled, pass to MLME for special process
-		{
-			pTmpBuf = pRxBlk->pData - LENGTH_802_11;
-			NdisMoveMemory(pTmpBuf, pRxBlk->pHeader, LENGTH_802_11);
-			REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pTmpBuf, pRxBlk->DataSize + LENGTH_802_11, pRxWI->RSSI0, pRxWI->RSSI1, pRxWI->RSSI2, pRxD->PlcpSignal);
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! report EAPOL/AIRONET DATA to MLME (len=%d) !!!\n", pRxBlk->DataSize));
-		}
-	}
-
-	RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
-	return;
-
-}
-
-VOID STARxDataFrameAnnounce(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MAC_TABLE_ENTRY	*pEntry,
-	IN	RX_BLK			*pRxBlk,
-	IN	UCHAR			FromWhichBSSID)
-{
-
-	// non-EAP frame
-	if (!RTMPCheckWPAframe(pAd, pEntry, pRxBlk->pData, pRxBlk->DataSize, FromWhichBSSID))
-	{
-
-		{
-			// drop all non-EAP DATA frame before
-			// this client's Port-Access-Control is secured
-			if (pRxBlk->pHeader->FC.Wep)
-			{
-				// unsupported cipher suite
-				if (pAd->StaCfg.WepStatus == Ndis802_11EncryptionDisabled)
-				{
-					// release packet
-					RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
-					return;
-				}
-			}
-			else
-			{
-				// encryption in-use but receive a non-EAPOL clear text frame, drop it
-				if ((pAd->StaCfg.WepStatus != Ndis802_11EncryptionDisabled) &&
-					(pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
-				{
-					// release packet
-					RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
-					return;
-				}
-			}
-		}
-		RX_BLK_CLEAR_FLAG(pRxBlk, fRX_EAP);
-
-
-		if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_ARALINK))
-		{
-			// Normal legacy, AMPDU or AMSDU
-			CmmRxnonRalinkFrameIndicate(pAd, pRxBlk, FromWhichBSSID);
-
-		}
-		else
-		{
-			// ARALINK
-			CmmRxRalinkFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
-		}
-#ifdef QOS_DLS_SUPPORT
-		RX_BLK_CLEAR_FLAG(pRxBlk, fRX_DLS);
-#endif // QOS_DLS_SUPPORT //
-	}
-	else
-	{
-		RX_BLK_SET_FLAG(pRxBlk, fRX_EAP);
-#ifdef DOT11_N_SUPPORT
-		if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
-		{
-			Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
-		}
-		else
-#endif // DOT11_N_SUPPORT //
-		{
-			// Determin the destination of the EAP frame
-			//  to WPA state machine or upper layer
-			STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
-		}
-	}
-}
-
-
-// For TKIP frame, calculate the MIC value
-BOOLEAN STACheckTkipMICValue(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MAC_TABLE_ENTRY	*pEntry,
-	IN	RX_BLK			*pRxBlk)
-{
-	PHEADER_802_11	pHeader = pRxBlk->pHeader;
-	UCHAR			*pData = pRxBlk->pData;
-	USHORT			DataSize = pRxBlk->DataSize;
-	UCHAR			UserPriority = pRxBlk->UserPriority;
-	PCIPHER_KEY		pWpaKey;
-	UCHAR			*pDA, *pSA;
-
-	pWpaKey = &pAd->SharedKey[BSS0][pRxBlk->pRxWI->KeyIndex];
-
-	pDA = pHeader->Addr1;
-	if (RX_BLK_TEST_FLAG(pRxBlk, fRX_INFRA))
-	{
-		pSA = pHeader->Addr3;
-	}
-	else
-	{
-		pSA = pHeader->Addr2;
-	}
-
-	if (RTMPTkipCompareMICValue(pAd,
-								pData,
-								pDA,
-								pSA,
-								pWpaKey->RxMic,
-								UserPriority,
-								DataSize) == FALSE)
-	{
-		DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error 2\n"));
-
-#ifdef WPA_SUPPLICANT_SUPPORT
-		if (pAd->StaCfg.WpaSupplicantUP)
-		{
-			WpaSendMicFailureToWpaSupplicant(pAd, (pWpaKey->Type == PAIRWISEKEY) ? TRUE : FALSE);
-		}
-		else
-#endif // WPA_SUPPLICANT_SUPPORT //
-		{
-			RTMPReportMicError(pAd, pWpaKey);
-		}
-
-		// release packet
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-
-//
-// All Rx routines use RX_BLK structure to hande rx events
-// It is very important to build pRxBlk attributes
-//  1. pHeader pointer to 802.11 Header
-//  2. pData pointer to payload including LLC (just skip Header)
-//  3. set payload size including LLC to DataSize
-//  4. set some flags with RX_BLK_SET_FLAG()
-//
-VOID STAHandleRxDataFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk)
-{
-	PRT28XX_RXD_STRUC				pRxD = &(pRxBlk->RxD);
-	PRXWI_STRUC						pRxWI = pRxBlk->pRxWI;
-	PHEADER_802_11					pHeader = pRxBlk->pHeader;
-	PNDIS_PACKET					pRxPacket = pRxBlk->pRxPacket;
-	BOOLEAN							bFragment = FALSE;
-	MAC_TABLE_ENTRY				*pEntry = NULL;
-	UCHAR							FromWhichBSSID = BSS0;
-	UCHAR                           UserPriority = 0;
-
-	{
-		// before LINK UP, all DATA frames are rejected
-		if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-		{
-			// release packet
-			RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
-			return;
-		}
-
-#ifdef QOS_DLS_SUPPORT
-		//if ((pHeader->FC.FrDs == 0) && (pHeader->FC.ToDs == 0))
-		if (RTMPRcvFrameDLSCheck(pAd, pHeader, pRxWI->MPDUtotalByteCount, pRxD))
-		{
-			return;
-		}
-#endif // QOS_DLS_SUPPORT //
-
-		// Drop not my BSS frames
-		if (pRxD->MyBss == 0)
-		{
-			{
-				// release packet
-				RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
-				return;
-			}
-		}
-
-		pAd->RalinkCounters.RxCountSinceLastNULL++;
-		if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable && (pHeader->FC.SubType & 0x08))
-		{
-			UCHAR *pData;
-			DBGPRINT(RT_DEBUG_INFO,("bAPSDCapable\n"));
-
-			// Qos bit 4
-			pData = (PUCHAR)pHeader + LENGTH_802_11;
-			if ((*pData >> 4) & 0x01)
-			{
-				DBGPRINT(RT_DEBUG_INFO,("RxDone- Rcv EOSP frame, driver may fall into sleep\n"));
-				pAd->CommonCfg.bInServicePeriod = FALSE;
-
-				// Force driver to fall into sleep mode when rcv EOSP frame
-				if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-				{
-					USHORT  TbttNumToNextWakeUp;
-					USHORT  NextDtim = pAd->StaCfg.DtimPeriod;
-					ULONG   Now;
-
-					NdisGetSystemUpTime(&Now);
-					NextDtim -= (USHORT)(Now - pAd->StaCfg.LastBeaconRxTime)/pAd->CommonCfg.BeaconPeriod;
-
-					TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
-					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
-						TbttNumToNextWakeUp = NextDtim;
-
-					RTMP_SET_PSM_BIT(pAd, PWR_SAVE);
-					// if WMM-APSD is failed, try to disable following line
-					AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
-				}
-			}
-
-			if ((pHeader->FC.MoreData) && (pAd->CommonCfg.bInServicePeriod))
-			{
-				DBGPRINT(RT_DEBUG_TRACE,("Sending another trigger frame when More Data bit is set to 1\n"));
-			}
-		}
-
-		// Drop NULL, CF-ACK(no data), CF-POLL(no data), and CF-ACK+CF-POLL(no data) data frame
-		if ((pHeader->FC.SubType & 0x04)) // bit 2 : no DATA
-		{
-			// release packet
-			RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
-			return;
-		}
-
-	    // Drop not my BSS frame (we can not only check the MyBss bit in RxD)
-#ifdef QOS_DLS_SUPPORT
-	    if (!pAd->CommonCfg.bDLSCapable)
-	    {
-#endif // QOS_DLS_SUPPORT //
-		if (INFRA_ON(pAd))
-		{
-			// Infrastructure mode, check address 2 for BSSID
-			if (!RTMPEqualMemory(&pHeader->Addr2, &pAd->CommonCfg.Bssid, 6))
-			{
-				// Receive frame not my BSSID
-	            // release packet
-	            RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
-				return;
-			}
-		}
-		else	// Ad-Hoc mode or Not associated
-		{
-			// Ad-Hoc mode, check address 3 for BSSID
-			if (!RTMPEqualMemory(&pHeader->Addr3, &pAd->CommonCfg.Bssid, 6))
-			{
-				// Receive frame not my BSSID
-	            // release packet
-	            RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
-				return;
-			}
-		}
-#ifdef QOS_DLS_SUPPORT
-	    }
-#endif // QOS_DLS_SUPPORT //
-
-		//
-		// find pEntry
-		//
-		if (pRxWI->WirelessCliID < MAX_LEN_OF_MAC_TABLE)
-		{
-			pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
-
-		}
-		else
-		{
-			// 1. release packet if infra mode
-			// 2. new a pEntry if ad-hoc mode
-			RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
-			return;
-		}
-
-		// infra or ad-hoc
-		if (INFRA_ON(pAd))
-		{
-			RX_BLK_SET_FLAG(pRxBlk, fRX_INFRA);
-#ifdef QOS_DLS_SUPPORT
-			if ((pHeader->FC.FrDs == 0) && (pHeader->FC.ToDs == 0))
-				RX_BLK_SET_FLAG(pRxBlk, fRX_DLS);
-			else
-#endif // QOS_DLS_SUPPORT //
-			ASSERT(pRxWI->WirelessCliID == BSSID_WCID);
-		}
-
-		// check Atheros Client
-		if ((pEntry->bIAmBadAtheros == FALSE) &&  (pRxD->AMPDU == 1) && (pHeader->FC.Retry ))
-		{
-			pEntry->bIAmBadAtheros = TRUE;
-			pAd->CommonCfg.IOTestParm.bCurrentAtheros = TRUE;
-			pAd->CommonCfg.IOTestParm.bLastAtheros = TRUE;
-			if (!STA_AES_ON(pAd))
-			{
-				AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, TRUE, FALSE);
-			}
-		}
-	}
-
-	pRxBlk->pData = (UCHAR *)pHeader;
-
-	//
-	// update RxBlk->pData, DataSize
-	// 802.11 Header, QOS, HTC, Hw Padding
-	//
-
-	// 1. skip 802.11 HEADER
-	{
-		pRxBlk->pData += LENGTH_802_11;
-		pRxBlk->DataSize -= LENGTH_802_11;
-	}
-
-	// 2. QOS
-	if (pHeader->FC.SubType & 0x08)
-	{
-		RX_BLK_SET_FLAG(pRxBlk, fRX_QOS);
-		UserPriority = *(pRxBlk->pData) & 0x0f;
-		// bit 7 in QoS Control field signals the HT A-MSDU format
-		if ((*pRxBlk->pData) & 0x80)
-		{
-			RX_BLK_SET_FLAG(pRxBlk, fRX_AMSDU);
-		}
-
-		// skip QOS contorl field
-		pRxBlk->pData += 2;
-		pRxBlk->DataSize -=2;
-	}
-	pRxBlk->UserPriority = UserPriority;
-
-	/* check if need to resend PS Poll when received packet with MoreData = 1 */
-	if ((pAd->StaCfg.Psm == PWR_SAVE) && (pHeader->FC.MoreData == 1))
-	{
-		if ((((UserPriority == 0) || (UserPriority == 3)) &&
-			pAd->CommonCfg.bAPSDAC_BE == 0) ||
-			(((UserPriority == 1) || (UserPriority == 2)) &&
-			pAd->CommonCfg.bAPSDAC_BK == 0) ||
-			(((UserPriority == 4) || (UserPriority == 5)) &&
-			pAd->CommonCfg.bAPSDAC_VI == 0) ||
-			(((UserPriority == 6) || (UserPriority == 7)) &&
-			pAd->CommonCfg.bAPSDAC_VO == 0))
-		{
-			/* non-UAPSD delivery-enabled AC */
-			RTMP_PS_POLL_ENQUEUE(pAd);
-		}
-	}
-
-	// 3. Order bit: A-Ralink or HTC+
-	if (pHeader->FC.Order)
-	{
-#ifdef AGGREGATION_SUPPORT
-		if ((pRxWI->PHYMODE <= MODE_OFDM) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)))
-		{
-			RX_BLK_SET_FLAG(pRxBlk, fRX_ARALINK);
-		}
-		else
-#endif // AGGREGATION_SUPPORT //
-		{
-#ifdef DOT11_N_SUPPORT
-			RX_BLK_SET_FLAG(pRxBlk, fRX_HTC);
-			// skip HTC contorl field
-			pRxBlk->pData += 4;
-			pRxBlk->DataSize -= 4;
-#endif // DOT11_N_SUPPORT //
-		}
-	}
-
-	// 4. skip HW padding
-	if (pRxD->L2PAD)
-	{
-		// just move pData pointer
-		// because DataSize excluding HW padding
-		RX_BLK_SET_FLAG(pRxBlk, fRX_PAD);
-		pRxBlk->pData += 2;
-	}
-
-#ifdef DOT11_N_SUPPORT
-	if (pRxD->BA)
-	{
-		RX_BLK_SET_FLAG(pRxBlk, fRX_AMPDU);
-	}
-#endif // DOT11_N_SUPPORT //
-
-
-	//
-	// Case I  Process Broadcast & Multicast data frame
-	//
-	if (pRxD->Bcast || pRxD->Mcast)
-	{
-		INC_COUNTER64(pAd->WlanCounters.MulticastReceivedFrameCount);
-
-		// Drop Mcast/Bcast frame with fragment bit on
-		if (pHeader->FC.MoreFrag)
-		{
-			// release packet
-			RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
-			return;
-		}
-
-		// Filter out Bcast frame which AP relayed for us
-		if (pHeader->FC.FrDs && MAC_ADDR_EQUAL(pHeader->Addr3, pAd->CurrentAddress))
-		{
-			// release packet
-			RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
-			return;
-		}
-
-		Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
-		return;
-	}
-	else if (pRxD->U2M)
-	{
-		pAd->LastRxRate = (USHORT)((pRxWI->MCS) + (pRxWI->BW <<7) + (pRxWI->ShortGI <<8)+ (pRxWI->PHYMODE <<14)) ;
-
-
-#ifdef QOS_DLS_SUPPORT
-        if (RX_BLK_TEST_FLAG(pRxBlk, fRX_DLS))
-		{
-			MAC_TABLE_ENTRY *pDlsEntry = NULL;
-
-			pDlsEntry = DlsEntryTableLookupByWcid(pAd, pRxWI->WirelessCliID, pHeader->Addr2, TRUE);
-										                        if(pDlsEntry)
-			Update_Rssi_Sample(pAd, &pDlsEntry->RssiSample, pRxWI);
-		}
-		else
-#endif // QOS_DLS_SUPPORT //
-		if (ADHOC_ON(pAd))
-		{
-			pEntry = MacTableLookup(pAd, pHeader->Addr2);
-			if (pEntry)
-				Update_Rssi_Sample(pAd, &pEntry->RssiSample, pRxWI);
-		}
-
-
-		Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
-
-		pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0);
-		pAd->StaCfg.LastSNR1 = (UCHAR)(pRxWI->SNR1);
-
-		pAd->RalinkCounters.OneSecRxOkDataCnt++;
-
-
-	if (!((pHeader->Frag == 0) && (pHeader->FC.MoreFrag == 0)))
-	{
-		// re-assemble the fragmented packets
-		// return complete frame (pRxPacket) or NULL
-		bFragment = TRUE;
-		pRxPacket = RTMPDeFragmentDataFrame(pAd, pRxBlk);
-	}
-
-	if (pRxPacket)
-	{
-		pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
-
-		// process complete frame
-		if (bFragment && (pRxD->Decrypted) && (pEntry->WepStatus == Ndis802_11Encryption2Enabled))
-		{
-			// Minus MIC length
-			pRxBlk->DataSize -= 8;
-
-			// For TKIP frame, calculate the MIC value
-			if (STACheckTkipMICValue(pAd, pEntry, pRxBlk) == FALSE)
-			{
-				return;
-			}
-		}
-
-		STARxDataFrameAnnounce(pAd, pEntry, pRxBlk, FromWhichBSSID);
-			return;
-	}
-	else
-	{
-		// just return
-		// because RTMPDeFragmentDataFrame() will release rx packet,
-		// if packet is fragmented
-		return;
-	}
-	}
-
-	ASSERT(0);
-	// release packet
-	RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
-}
-
-VOID STAHandleRxMgmtFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk)
-{
-	PRT28XX_RXD_STRUC	pRxD = &(pRxBlk->RxD);
-	PRXWI_STRUC		pRxWI = pRxBlk->pRxWI;
-	PHEADER_802_11	pHeader = pRxBlk->pHeader;
-	PNDIS_PACKET	pRxPacket = pRxBlk->pRxPacket;
-
-	do
-	{
-
-
-		/* check if need to resend PS Poll when received packet with MoreData = 1 */
-		if ((pAd->StaCfg.Psm == PWR_SAVE) && (pHeader->FC.MoreData == 1))
-		{
-			/* for UAPSD, all management frames will be VO priority */
-			if (pAd->CommonCfg.bAPSDAC_VO == 0)
-			{
-				/* non-UAPSD delivery-enabled AC */
-				RTMP_PS_POLL_ENQUEUE(pAd);
-			}
-		}
-
-		/* TODO: if MoreData == 0, station can go to sleep */
-
-
-		// We should collect RSSI not only U2M data but also my beacon
-		if ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2))
-			&& (pAd->RxAnt.EvaluatePeriod == 0))
-		{
-			Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
-
-			pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0);
-			pAd->StaCfg.LastSNR1 = (UCHAR)(pRxWI->SNR1);
-		}
-
-#ifdef RT30xx
-#ifdef ANT_DIVERSITY_SUPPORT
-		// collect rssi information for antenna diversity
-		if ((pAd->NicConfig2.field.AntDiversity) &&
-			(pAd->CommonCfg.bRxAntDiversity != ANT_DIVERSITY_DISABLE))
-		{
-			if ((pRxD->U2M) || ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2))))
-			{
-					COLLECT_RX_ANTENNA_AVERAGE_RSSI(pAd, ConvertToRssi(pAd, (UCHAR)pRxWI->RSSI0, RSSI_0), 0); //Note: RSSI2 not used on RT73
-					pAd->StaCfg.NumOfAvgRssiSample ++;
-			}
-		}
-#endif // ANT_DIVERSITY_SUPPORT //
-#endif // RT30xx //
-
-		// First check the size, it MUST not exceed the mlme queue size
-		if (pRxWI->MPDUtotalByteCount > MGMT_DMA_BUFFER_SIZE)
-		{
-			DBGPRINT_ERR(("STAHandleRxMgmtFrame: frame too large, size = %d \n", pRxWI->MPDUtotalByteCount));
-			break;
-		}
-
-		REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pHeader, pRxWI->MPDUtotalByteCount,
-									pRxWI->RSSI0, pRxWI->RSSI1, pRxWI->RSSI2, pRxD->PlcpSignal);
-	} while (FALSE);
-
-	RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
-}
-
-VOID STAHandleRxControlFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	RX_BLK			*pRxBlk)
-{
-#ifdef DOT11_N_SUPPORT
-	PRXWI_STRUC		pRxWI = pRxBlk->pRxWI;
-#endif // DOT11_N_SUPPORT //
-	PHEADER_802_11	pHeader = pRxBlk->pHeader;
-	PNDIS_PACKET	pRxPacket = pRxBlk->pRxPacket;
-
-	switch (pHeader->FC.SubType)
-	{
-		case SUBTYPE_BLOCK_ACK_REQ:
-#ifdef DOT11_N_SUPPORT
-			{
-				CntlEnqueueForRecv(pAd, pRxWI->WirelessCliID, (pRxWI->MPDUtotalByteCount), (PFRAME_BA_REQ)pHeader);
-			}
-			break;
-#endif // DOT11_N_SUPPORT //
-		case SUBTYPE_BLOCK_ACK:
-		case SUBTYPE_ACK:
-		default:
-			break;
-	}
-
-	RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Process RxDone interrupt, running in DPC level
-
-	Arguments:
-		pAd Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-		This routine has to maintain Rx ring read pointer.
-		Need to consider QOS DATA format when converting to 802.3
-	========================================================================
-*/
-BOOLEAN STARxDoneInterruptHandle(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	BOOLEAN			argc)
-{
-	NDIS_STATUS			Status;
-	UINT32			RxProcessed, RxPending;
-	BOOLEAN			bReschedule = FALSE;
-	RT28XX_RXD_STRUC	*pRxD;
-	UCHAR			*pData;
-	PRXWI_STRUC		pRxWI;
-	PNDIS_PACKET	pRxPacket;
-	PHEADER_802_11	pHeader;
-	RX_BLK			RxCell;
-
-	RxProcessed = RxPending = 0;
-
-	// process whole rx ring
-	while (1)
-	{
-
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF |
-								fRTMP_ADAPTER_RESET_IN_PROGRESS |
-								fRTMP_ADAPTER_HALT_IN_PROGRESS |
-								fRTMP_ADAPTER_NIC_NOT_EXIST) ||
-			!RTMP_TEST_FLAG(pAd,fRTMP_ADAPTER_START_UP))
-		{
-			break;
-		}
-
-#ifdef RTMP_MAC_PCI
-		if (RxProcessed++ > MAX_RX_PROCESS_CNT)
-		{
-			// need to reschedule rx handle
-			bReschedule = TRUE;
-			break;
-		}
-#endif // RTMP_MAC_PCI //
-
-		RxProcessed ++; // test
-
-		// 1. allocate a new data packet into rx ring to replace received packet
-		//    then processing the received packet
-		// 2. the callee must take charge of release of packet
-		// 3. As far as driver is concerned ,
-		//    the rx packet must
-		//      a. be indicated to upper layer or
-		//      b. be released if it is discarded
-		pRxPacket = GetPacketFromRxRing(pAd, &(RxCell.RxD), &bReschedule, &RxPending);
-		if (pRxPacket == NULL)
-		{
-			// no more packet to process
-			break;
-		}
-
-		// get rx ring descriptor
-		pRxD = &(RxCell.RxD);
-		// get rx data buffer
-		pData	= GET_OS_PKT_DATAPTR(pRxPacket);
-		pRxWI	= (PRXWI_STRUC) pData;
-		pHeader = (PHEADER_802_11) (pData+RXWI_SIZE) ;
-
-#ifdef RT_BIG_ENDIAN
-	    RTMPFrameEndianChange(pAd, (PUCHAR)pHeader, DIR_READ, TRUE);
-		RTMPWIEndianChange((PUCHAR)pRxWI, TYPE_RXWI);
-#endif
-
-		// build RxCell
-		RxCell.pRxWI = pRxWI;
-		RxCell.pHeader = pHeader;
-		RxCell.pRxPacket = pRxPacket;
-		RxCell.pData = (UCHAR *) pHeader;
-		RxCell.DataSize = pRxWI->MPDUtotalByteCount;
-		RxCell.Flags = 0;
-
-		// Increase Total receive byte counter after real data received no mater any error or not
-		pAd->RalinkCounters.ReceivedByteCount +=  pRxWI->MPDUtotalByteCount;
-		pAd->RalinkCounters.OneSecReceivedByteCount +=  pRxWI->MPDUtotalByteCount;
-		pAd->RalinkCounters.RxCount ++;
-
-		INC_COUNTER64(pAd->WlanCounters.ReceivedFragmentCount);
-
-		if (pRxWI->MPDUtotalByteCount < 14)
-			Status = NDIS_STATUS_FAILURE;
-
-        if (MONITOR_ON(pAd))
-		{
-            send_monitor_packets(pAd, &RxCell);
-			break;
-		}
-
-		/* STARxDoneInterruptHandle() is called in rtusb_bulk.c */
-#ifdef RALINK_ATE
-		if (ATE_ON(pAd))
-		{
-			pAd->ate.RxCntPerSec++;
-			ATESampleRssi(pAd, pRxWI);
-#ifdef RALINK_28xx_QA
-			if (pAd->ate.bQARxStart == TRUE)
-			{
-				/* (*pRxD) has been swapped in GetPacketFromRxRing() */
-				ATE_QA_Statistics(pAd, pRxWI, pRxD,	pHeader);
-			}
-#endif // RALINK_28xx_QA //
-			RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
-			continue;
-		}
-#endif // RALINK_ATE //
-
-		// Check for all RxD errors
-		Status = RTMPCheckRxError(pAd, pHeader, pRxWI, pRxD);
-
-		// Handle the received frame
-		if (Status == NDIS_STATUS_SUCCESS)
-		{
-			switch (pHeader->FC.Type)
-			{
-				// CASE I, receive a DATA frame
-				case BTYPE_DATA:
-				{
-					// process DATA frame
-					STAHandleRxDataFrame(pAd, &RxCell);
-				}
-				break;
-				// CASE II, receive a MGMT frame
-				case BTYPE_MGMT:
-				{
-					STAHandleRxMgmtFrame(pAd, &RxCell);
-				}
-				break;
-				// CASE III. receive a CNTL frame
-				case BTYPE_CNTL:
-				{
-					STAHandleRxControlFrame(pAd, &RxCell);
-				}
-				break;
-				// discard other type
-				default:
-					RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
-					break;
-			}
-		}
-		else
-		{
-			pAd->Counters8023.RxErrors++;
-			// discard this frame
-			RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
-		}
-	}
-
-	return bReschedule;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-	Arguments:
-		pAd	Pointer to our adapter
-
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-VOID	RTMPHandleTwakeupInterrupt(
-	IN PRTMP_ADAPTER pAd)
-{
-	AsicForceWakeup(pAd, FALSE);
-}
-
-/*
-========================================================================
-Routine Description:
-    Early checking and OS-depened parsing for Tx packet send to our STA driver.
-
-Arguments:
-    NDIS_HANDLE		MiniportAdapterContext	Pointer refer to the device handle, i.e., the pAd.
-	PPNDIS_PACKET	ppPacketArray			The packet array need to do transmission.
-	UINT			NumberOfPackets			Number of packet in packet array.
-
-Return Value:
-	NONE
-
-Note:
-	This function do early checking and classification for send-out packet.
-	You only can put OS-depened & STA related code in here.
-========================================================================
-*/
-VOID STASendPackets(
-	IN	NDIS_HANDLE		MiniportAdapterContext,
-	IN	PPNDIS_PACKET	ppPacketArray,
-	IN	UINT			NumberOfPackets)
-{
-	UINT			Index;
-	PRTMP_ADAPTER	pAd = (PRTMP_ADAPTER) MiniportAdapterContext;
-	PNDIS_PACKET	pPacket;
-	BOOLEAN			allowToSend = FALSE;
-
-
-	for (Index = 0; Index < NumberOfPackets; Index++)
-	{
-		pPacket = ppPacketArray[Index];
-
-		do
-		{
-
-			if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
-				RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
-				RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
-			{
-				// Drop send request since hardware is in reset state
-					break;
-			}
-			else if (!INFRA_ON(pAd) && !ADHOC_ON(pAd))
-			{
-				// Drop send request since there are no physical connection yet
-					break;
-			}
-			else
-			{
-				// Record that orignal packet source is from NDIS layer,so that
-				// later on driver knows how to release this NDIS PACKET
-#ifdef QOS_DLS_SUPPORT
-				MAC_TABLE_ENTRY *pEntry;
-				PUCHAR pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
-
-				pEntry = MacTableLookup(pAd, pSrcBufVA);
-				if (pEntry && (pEntry->ValidAsDls == TRUE))
-				{
-					RTMP_SET_PACKET_WCID(pPacket, pEntry->Aid);
-				}
-				else
-#endif // QOS_DLS_SUPPORT //
-				RTMP_SET_PACKET_WCID(pPacket, 0); // this field is useless when in STA mode
-				RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
-				NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_PENDING);
-				pAd->RalinkCounters.PendingNdisPacketCount++;
-
-				allowToSend = TRUE;
-			}
-		} while(FALSE);
-
-		if (allowToSend == TRUE)
-			STASendPacket(pAd, pPacket);
-		else
-			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-	}
-
-	// Dequeue outgoing frames from TxSwQueue[] and process it
-	RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
-
-}
-
-
-/*
-========================================================================
-Routine Description:
-	This routine is used to do packet parsing and classification for Tx packet
-	to STA device, and it will en-queue packets to our TxSwQueue depends on AC
-	class.
-
-Arguments:
-	pAd		Pointer to our adapter
-	pPacket		Pointer to send packet
-
-Return Value:
-	NDIS_STATUS_SUCCESS			If succes to queue the packet into TxSwQueue.
-	NDIS_STATUS_FAILURE			If failed to do en-queue.
-
-Note:
-	You only can put OS-indepened & STA related code in here.
-========================================================================
-*/
-NDIS_STATUS STASendPacket(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket)
-{
-	PACKET_INFO	PacketInfo;
-	PUCHAR			pSrcBufVA;
-	UINT			SrcBufLen;
-	UINT			AllowFragSize;
-	UCHAR			NumberOfFrag;
-	UCHAR			RTSRequired;
-	UCHAR			QueIdx, UserPriority;
-	MAC_TABLE_ENTRY *pEntry = NULL;
-	unsigned int	IrqFlags;
-	UCHAR			FlgIsIP = 0;
-	UCHAR			Rate;
-
-	// Prepare packet information structure for buffer descriptor
-	// chained within a single NDIS packet.
-	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
-
-	if (pSrcBufVA == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("STASendPacket --> pSrcBufVA == NULL !!!SrcBufLen=%x\n",SrcBufLen));
-		// Resourece is low, system did not allocate virtual address
-		// return NDIS_STATUS_FAILURE directly to upper layer
-		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-		return NDIS_STATUS_FAILURE;
-	}
-
-
-	if (SrcBufLen < 14)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("STASendPacket --> Ndis Packet buffer error !!!\n"));
-		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-		return (NDIS_STATUS_FAILURE);
-	}
-
-	// In HT rate adhoc mode, A-MPDU is often used. So need to lookup BA Table and MAC Entry.
-	// Note multicast packets in adhoc also use BSSID_WCID index.
-	{
-		if(INFRA_ON(pAd))
-		{
-#ifdef QOS_DLS_SUPPORT
-			USHORT	tmpWcid;
-
-			tmpWcid = RTMP_GET_PACKET_WCID(pPacket);
-			if (VALID_WCID(tmpWcid) &&
-				(pAd->MacTab.Content[tmpWcid].ValidAsDls== TRUE))
-			{
-				pEntry = &pAd->MacTab.Content[tmpWcid];
-				Rate = pAd->MacTab.Content[tmpWcid].CurrTxRate;
-			}
-			else
-#endif // QOS_DLS_SUPPORT //
-			{
-			pEntry = &pAd->MacTab.Content[BSSID_WCID];
-			RTMP_SET_PACKET_WCID(pPacket, BSSID_WCID);
-			Rate = pAd->CommonCfg.TxRate;
-		}
-		}
-		else if (ADHOC_ON(pAd))
-		{
-			if (*pSrcBufVA & 0x01)
-			{
-				RTMP_SET_PACKET_WCID(pPacket, MCAST_WCID);
-				pEntry = &pAd->MacTab.Content[MCAST_WCID];
-			}
-			else
-			{
-				pEntry = MacTableLookup(pAd, pSrcBufVA);
-			}
-			Rate = pAd->CommonCfg.TxRate;
-		}
-	}
-
-	if (!pEntry)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("STASendPacket->Cannot find pEntry(%2x:%2x:%2x:%2x:%2x:%2x) in MacTab!\n", PRINT_MAC(pSrcBufVA)));
-		// Resourece is low, system did not allocate virtual address
-		// return NDIS_STATUS_FAILURE directly to upper layer
-		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-		return NDIS_STATUS_FAILURE;
-	}
-
-	if (ADHOC_ON(pAd)
-		)
-	{
-		RTMP_SET_PACKET_WCID(pPacket, (UCHAR)pEntry->Aid);
-	}
-
-	//
-	// Check the Ethernet Frame type of this packet, and set the RTMP_SET_PACKET_SPECIFIC flags.
-	//		Here we set the PACKET_SPECIFIC flags(LLC, VLAN, DHCP/ARP, EAPOL).
-	RTMPCheckEtherType(pAd, pPacket);
-
-
-
-	//
-	// WPA 802.1x secured port control - drop all non-802.1x frame before port secured
-	//
-	if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
-		 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
-		 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
-		 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
-#ifdef WPA_SUPPLICANT_SUPPORT
-		  || (pAd->StaCfg.IEEE8021X == TRUE)
-#endif // WPA_SUPPLICANT_SUPPORT //
-		  )
-		  && ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) || (pAd->StaCfg.MicErrCnt >= 2))
-		  && (RTMP_GET_PACKET_EAPOL(pPacket)== FALSE)
-		  )
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("STASendPacket --> Drop packet before port secured !!!\n"));
-		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-
-		return (NDIS_STATUS_FAILURE);
-	}
-
-
-	// STEP 1. Decide number of fragments required to deliver this MSDU.
-	//	   The estimation here is not very accurate because difficult to
-	//	   take encryption overhead into consideration here. The result
-	//	   "NumberOfFrag" is then just used to pre-check if enough free
-	//	   TXD are available to hold this MSDU.
-
-
-	if (*pSrcBufVA & 0x01)	// fragmentation not allowed on multicast & broadcast
-		NumberOfFrag = 1;
-	else if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED))
-		NumberOfFrag = 1;	// Aggregation overwhelms fragmentation
-	else if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED))
-		NumberOfFrag = 1;	// Aggregation overwhelms fragmentation
-#ifdef DOT11_N_SUPPORT
-	else if ((pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTMIX) || (pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTGREENFIELD))
-		NumberOfFrag = 1;	// MIMO RATE overwhelms fragmentation
-#endif // DOT11_N_SUPPORT //
-	else
-	{
-		// The calculated "NumberOfFrag" is a rough estimation because of various
-		// encryption/encapsulation overhead not taken into consideration. This number is just
-		// used to make sure enough free TXD are available before fragmentation takes place.
-		// In case the actual required number of fragments of an NDIS packet
-		// excceeds "NumberOfFrag"caculated here and not enough free TXD available, the
-		// last fragment (i.e. last MPDU) will be dropped in RTMPHardTransmit() due to out of
-		// resource, and the NDIS packet will be indicated NDIS_STATUS_FAILURE. This should
-		// rarely happen and the penalty is just like a TX RETRY fail. Affordable.
-
-		AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
-		NumberOfFrag = ((PacketInfo.TotalPacketLength - LENGTH_802_3 + LENGTH_802_1_H) / AllowFragSize) + 1;
-		// To get accurate number of fragmentation, Minus 1 if the size just match to allowable fragment size
-		if (((PacketInfo.TotalPacketLength - LENGTH_802_3 + LENGTH_802_1_H) % AllowFragSize) == 0)
-		{
-			NumberOfFrag--;
-		}
-	}
-
-	// Save fragment number to Ndis packet reserved field
-	RTMP_SET_PACKET_FRAGMENTS(pPacket, NumberOfFrag);
-
-
-	// STEP 2. Check the requirement of RTS:
-	//	   If multiple fragment required, RTS is required only for the first fragment
-	//	   if the fragment size large than RTS threshold
-	//     For RT28xx, Let ASIC send RTS/CTS
-//	RTMP_SET_PACKET_RTS(pPacket, 0);
-	if (NumberOfFrag > 1)
-		RTSRequired = (pAd->CommonCfg.FragmentThreshold > pAd->CommonCfg.RtsThreshold) ? 1 : 0;
-	else
-		RTSRequired = (PacketInfo.TotalPacketLength > pAd->CommonCfg.RtsThreshold) ? 1 : 0;
-
-	// Save RTS requirement to Ndis packet reserved field
-	RTMP_SET_PACKET_RTS(pPacket, RTSRequired);
-	RTMP_SET_PACKET_TXRATE(pPacket, pAd->CommonCfg.TxRate);
-
-	//
-	// STEP 3. Traffic classification. outcome = <UserPriority, QueIdx>
-	//
-	UserPriority = 0;
-	QueIdx		 = QID_AC_BE;
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
-		CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE))
-	{
-		USHORT Protocol;
-		UCHAR  LlcSnapLen = 0, Byte0, Byte1;
-		do
-		{
-			// get Ethernet protocol field
-			Protocol = (USHORT)((pSrcBufVA[12] << 8) + pSrcBufVA[13]);
-			if (Protocol <= 1500)
-			{
-				// get Ethernet protocol field from LLC/SNAP
-				if (Sniff2BytesFromNdisBuffer(PacketInfo.pFirstBuffer, LENGTH_802_3 + 6, &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
-					break;
-
-				Protocol = (USHORT)((Byte0 << 8) + Byte1);
-				LlcSnapLen = 8;
-			}
-
-			// always AC_BE for non-IP packet
-			if (Protocol != 0x0800)
-				break;
-
-			// get IP header
-			if (Sniff2BytesFromNdisBuffer(PacketInfo.pFirstBuffer, LENGTH_802_3 + LlcSnapLen, &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
-				break;
-
-			// return AC_BE if packet is not IPv4
-			if ((Byte0 & 0xf0) != 0x40)
-				break;
-
-			FlgIsIP = 1;
-			UserPriority = (Byte1 & 0xe0) >> 5;
-			QueIdx = MapUserPriorityToAccessCategory[UserPriority];
-
-			// TODO: have to check ACM bit. apply TSPEC if ACM is ON
-			// TODO: downgrade UP & QueIdx before passing ACM
-			/*
-				Under WMM ACM control, we dont need to check the bit;
-				Or when a TSPEC is built for VO but we will change to issue
-				BA session for BE here, so we will not use BA to send VO packets.
-			*/
-			if (pAd->CommonCfg.APEdcaParm.bACM[QueIdx])
-			{
-				UserPriority = 0;
-				QueIdx		 = QID_AC_BE;
-			}
-		} while (FALSE);
-	}
-
-	RTMP_SET_PACKET_UP(pPacket, UserPriority);
-
-
-
-	// Make sure SendTxWait queue resource won't be used by other threads
-	RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-	if (pAd->TxSwQueue[QueIdx].Number >= MAX_PACKETS_IN_QUEUE)
-	{
-		RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-#ifdef BLOCK_NET_IF
-		StopNetIfQueue(pAd, QueIdx, pPacket);
-#endif // BLOCK_NET_IF //
-		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-
-		return NDIS_STATUS_FAILURE;
-	}
-	else
-	{
-		InsertTailQueueAc(pAd, pEntry, &pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pPacket));
-	}
-	RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-
-#ifdef DOT11_N_SUPPORT
-    if ((pAd->CommonCfg.BACapability.field.AutoBA == TRUE)&&
-        IS_HT_STA(pEntry))
-	{
-	    //PMAC_TABLE_ENTRY pMacEntry = &pAd->MacTab.Content[BSSID_WCID];
-		if (((pEntry->TXBAbitmap & (1<<UserPriority)) == 0) &&
-            ((pEntry->BADeclineBitmap & (1<<UserPriority)) == 0) &&
-            (pEntry->PortSecured == WPA_802_1X_PORT_SECURED)
-			 // For IOT compatibility, if
-			 // 1. It is Ralink chip or
-			 // 2. It is OPEN or AES mode,
-			 // then BA session can be bulit.
-			 && ((pEntry->ValidAsCLI && pAd->MlmeAux.APRalinkIe != 0x0) ||
-				 (pEntry->WepStatus != Ndis802_11WEPEnabled && pEntry->WepStatus != Ndis802_11Encryption2Enabled))
-			)
-		{
-			BAOriSessionSetUp(pAd, pEntry, UserPriority, 0, 10, FALSE);
-		}
-	}
-#endif // DOT11_N_SUPPORT //
-
-	pAd->RalinkCounters.OneSecOsTxCount[QueIdx]++; // TODO: for debug only. to be removed
-	return NDIS_STATUS_SUCCESS;
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		This subroutine will scan through releative ring descriptor to find
-		out avaliable free ring descriptor and compare with request size.
-
-	Arguments:
-		pAd Pointer to our adapter
-		QueIdx		Selected TX Ring
-
-	Return Value:
-		NDIS_STATUS_FAILURE	Not enough free descriptor
-		NDIS_STATUS_SUCCESS	Enough free descriptor
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-#ifdef RTMP_MAC_PCI
-NDIS_STATUS RTMPFreeTXDRequest(
-	IN		PRTMP_ADAPTER	pAd,
-	IN		UCHAR			QueIdx,
-	IN		UCHAR			NumberRequired,
-	IN		PUCHAR			FreeNumberIs)
-{
-	ULONG		FreeNumber = 0;
-	NDIS_STATUS	Status = NDIS_STATUS_FAILURE;
-
-	switch (QueIdx)
-	{
-		case QID_AC_BK:
-		case QID_AC_BE:
-		case QID_AC_VI:
-		case QID_AC_VO:
-		/*case QID_HCCA:*/
-			if (pAd->TxRing[QueIdx].TxSwFreeIdx > pAd->TxRing[QueIdx].TxCpuIdx)
-				FreeNumber = pAd->TxRing[QueIdx].TxSwFreeIdx - pAd->TxRing[QueIdx].TxCpuIdx - 1;
-			else
-				FreeNumber = pAd->TxRing[QueIdx].TxSwFreeIdx + TX_RING_SIZE - pAd->TxRing[QueIdx].TxCpuIdx - 1;
-
-			if (FreeNumber >= NumberRequired)
-				Status = NDIS_STATUS_SUCCESS;
-			break;
-
-		case QID_MGMT:
-			if (pAd->MgmtRing.TxSwFreeIdx > pAd->MgmtRing.TxCpuIdx)
-				FreeNumber = pAd->MgmtRing.TxSwFreeIdx - pAd->MgmtRing.TxCpuIdx - 1;
-			else
-				FreeNumber = pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE - pAd->MgmtRing.TxCpuIdx - 1;
-
-			if (FreeNumber >= NumberRequired)
-				Status = NDIS_STATUS_SUCCESS;
-			break;
-
-		default:
-			DBGPRINT(RT_DEBUG_ERROR,("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx));
-			break;
-	}
-	*FreeNumberIs = (UCHAR)FreeNumber;
-
-	return (Status);
-}
-#endif // RTMP_MAC_PCI //
-
-
-
-VOID RTMPSendDisassociationFrame(
-	IN	PRTMP_ADAPTER	pAd)
-{
-}
-
-VOID	RTMPSendNullFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			TxRate,
-	IN	BOOLEAN			bQosNull)
-{
-	UCHAR	NullFrame[48];
-	ULONG	Length;
-	PHEADER_802_11	pHeader_802_11;
-
-
-#ifdef RALINK_ATE
-	if(ATE_ON(pAd))
-	{
-		return;
-	}
-#endif // RALINK_ATE //
-
-    // WPA 802.1x secured port control
-    if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
-         (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
-         (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
-         (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
-#ifdef WPA_SUPPLICANT_SUPPORT
-			  || (pAd->StaCfg.IEEE8021X == TRUE)
-#endif
-        ) &&
-       (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
-	{
-		return;
-	}
-
-	NdisZeroMemory(NullFrame, 48);
-	Length = sizeof(HEADER_802_11);
-
-	pHeader_802_11 = (PHEADER_802_11) NullFrame;
-
-	pHeader_802_11->FC.Type = BTYPE_DATA;
-	pHeader_802_11->FC.SubType = SUBTYPE_NULL_FUNC;
-	pHeader_802_11->FC.ToDs = 1;
-	COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid);
-	COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
-	COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
-
-	if (pAd->CommonCfg.bAPSDForcePowerSave)
-	{
-		pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
-	}
-	else
-	{
-		pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE) ? 1: 0;
-	}
-	pHeader_802_11->Duration = pAd->CommonCfg.Dsifs + RTMPCalcDuration(pAd, TxRate, 14);
-
-	pAd->Sequence++;
-	pHeader_802_11->Sequence = pAd->Sequence;
-
-	// Prepare QosNull function frame
-	if (bQosNull)
-	{
-		pHeader_802_11->FC.SubType = SUBTYPE_QOS_NULL;
-
-		// copy QOS control bytes
-		NullFrame[Length]	=  0;
-		NullFrame[Length+1] =  0;
-		Length += 2;// if pad with 2 bytes for alignment, APSD will fail
-	}
-
-	HAL_KickOutNullFrameTx(pAd, 0, NullFrame, Length);
-
-}
-
-// IRQL = DISPATCH_LEVEL
-VOID	RTMPSendRTSFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pDA,
-	IN	unsigned int	NextMpduSize,
-	IN	UCHAR			TxRate,
-	IN	UCHAR			RTSRate,
-	IN	USHORT			AckDuration,
-	IN	UCHAR			QueIdx,
-	IN	UCHAR			FrameGap)
-{
-}
-
-
-
-// --------------------------------------------------------
-//  FIND ENCRYPT KEY AND DECIDE CIPHER ALGORITHM
-//		Find the WPA key, either Group or Pairwise Key
-//		LEAP + TKIP also use WPA key.
-// --------------------------------------------------------
-// Decide WEP bit and cipher suite to be used. Same cipher suite should be used for whole fragment burst
-// In Cisco CCX 2.0 Leap Authentication
-//		   WepStatus is Ndis802_11Encryption1Enabled but the key will use PairwiseKey
-//		   Instead of the SharedKey, SharedKey Length may be Zero.
-VOID STAFindCipherAlgorithm(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk)
-{
-	NDIS_802_11_ENCRYPTION_STATUS	Cipher;				// To indicate cipher used for this packet
-	UCHAR							CipherAlg = CIPHER_NONE;		// cipher alogrithm
-	UCHAR							KeyIdx = 0xff;
-	PUCHAR							pSrcBufVA;
-	PCIPHER_KEY						pKey = NULL;
-
-	pSrcBufVA = GET_OS_PKT_DATAPTR(pTxBlk->pPacket);
-
-	{
-	    // Select Cipher
-	    if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))
-	        Cipher = pAd->StaCfg.GroupCipher; // Cipher for Multicast or Broadcast
-	    else
-	        Cipher = pAd->StaCfg.PairCipher; // Cipher for Unicast
-
-		if (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
-		{
-			ASSERT(pAd->SharedKey[BSS0][0].CipherAlg <= CIPHER_CKIP128);
-
-			// 4-way handshaking frame must be clear
-			if (!(TX_BLK_TEST_FLAG(pTxBlk, fTX_bClearEAPFrame)) && (pAd->SharedKey[BSS0][0].CipherAlg) &&
-				(pAd->SharedKey[BSS0][0].KeyLen))
-			{
-				CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
-				KeyIdx = 0;
-			}
-		}
-		else if (Cipher == Ndis802_11Encryption1Enabled)
-		{
-				KeyIdx = pAd->StaCfg.DefaultKeyId;
-		}
-		else if ((Cipher == Ndis802_11Encryption2Enabled) ||
-				 (Cipher == Ndis802_11Encryption3Enabled))
-		{
-			if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))) // multicast
-				KeyIdx = pAd->StaCfg.DefaultKeyId;
-			else if (pAd->SharedKey[BSS0][0].KeyLen)
-				KeyIdx = 0;
-			else
-				KeyIdx = pAd->StaCfg.DefaultKeyId;
-		}
-
-		if (KeyIdx == 0xff)
-			CipherAlg = CIPHER_NONE;
-		else if ((Cipher == Ndis802_11EncryptionDisabled) || (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 0))
-			CipherAlg = CIPHER_NONE;
-#ifdef WPA_SUPPLICANT_SUPPORT
-	    else if ( pAd->StaCfg.WpaSupplicantUP &&
-	             (Cipher == Ndis802_11Encryption1Enabled) &&
-	             (pAd->StaCfg.IEEE8021X == TRUE) &&
-	             (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
-	        CipherAlg = CIPHER_NONE;
-#endif // WPA_SUPPLICANT_SUPPORT //
-		else
-		{
-			//Header_802_11.FC.Wep = 1;
-			CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
-			pKey = &pAd->SharedKey[BSS0][KeyIdx];
-		}
-	}
-
-	pTxBlk->CipherAlg = CipherAlg;
-	pTxBlk->pKey = pKey;
-}
-
-
-VOID STABuildCommon802_11Header(
-	IN  PRTMP_ADAPTER   pAd,
-	IN  TX_BLK          *pTxBlk)
-{
-
-	HEADER_802_11	*pHeader_802_11;
-#ifdef QOS_DLS_SUPPORT
-	BOOLEAN	bDLSFrame = FALSE;
-	INT	DlsEntryIndex = 0;
-#endif // QOS_DLS_SUPPORT //
-
-	//
-	// MAKE A COMMON 802.11 HEADER
-	//
-
-	// normal wlan header size : 24 octets
-	pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11);
-
-	pHeader_802_11 = (HEADER_802_11 *) &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
-
-	NdisZeroMemory(pHeader_802_11, sizeof(HEADER_802_11));
-
-	pHeader_802_11->FC.FrDs = 0;
-	pHeader_802_11->FC.Type = BTYPE_DATA;
-	pHeader_802_11->FC.SubType = ((TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) ? SUBTYPE_QDATA : SUBTYPE_DATA);
-
-#ifdef QOS_DLS_SUPPORT
-	if (INFRA_ON(pAd))
-	{
-		// Check if the frame can be sent through DLS direct link interface
-		// If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability)
-		DlsEntryIndex = RTMPCheckDLSFrame(pAd, pTxBlk->pSrcBufHeader);
-		if (DlsEntryIndex >= 0)
-			bDLSFrame = TRUE;
-		else
-			bDLSFrame = FALSE;
-	}
-#endif // QOS_DLS_SUPPORT //
-
-    if (pTxBlk->pMacEntry)
-	{
-		if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bForceNonQoS))
-		{
-			pHeader_802_11->Sequence = pTxBlk->pMacEntry->NonQosDataSeq;
-			pTxBlk->pMacEntry->NonQosDataSeq = (pTxBlk->pMacEntry->NonQosDataSeq+1) & MAXSEQ;
-		}
-		else
-		{
-			{
-	    pHeader_802_11->Sequence = pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority];
-	    pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority] = (pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ;
-	}
-	}
-	}
-	else
-	{
-		pHeader_802_11->Sequence = pAd->Sequence;
-		pAd->Sequence = (pAd->Sequence+1) & MAXSEQ; // next sequence
-	}
-
-	pHeader_802_11->Frag = 0;
-
-	pHeader_802_11->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
-
-	{
-		if (INFRA_ON(pAd))
-		{
-#ifdef QOS_DLS_SUPPORT
-			if (bDLSFrame)
-			{
-				COPY_MAC_ADDR(pHeader_802_11->Addr1, pTxBlk->pSrcBufHeader);
-				COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
-				COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
-				pHeader_802_11->FC.ToDs = 0;
-			}
-			else
-#endif // QOS_DLS_SUPPORT //
-			{
-			COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid);
-			COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
-			COPY_MAC_ADDR(pHeader_802_11->Addr3, pTxBlk->pSrcBufHeader);
-			pHeader_802_11->FC.ToDs = 1;
-		}
-		}
-		else if (ADHOC_ON(pAd))
-		{
-			COPY_MAC_ADDR(pHeader_802_11->Addr1, pTxBlk->pSrcBufHeader);
-			COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
-			COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
-			pHeader_802_11->FC.ToDs = 0;
-		}
-	}
-
-	if (pTxBlk->CipherAlg != CIPHER_NONE)
-		pHeader_802_11->FC.Wep = 1;
-
-	// -----------------------------------------------------------------
-	// STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later.
-	// -----------------------------------------------------------------
-	if (pAd->CommonCfg.bAPSDForcePowerSave)
-	pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
-	else
-	pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
-}
-
-#ifdef DOT11_N_SUPPORT
-VOID STABuildCache802_11Header(
-	IN RTMP_ADAPTER		*pAd,
-	IN TX_BLK			*pTxBlk,
-	IN UCHAR			*pHeader)
-{
-	MAC_TABLE_ENTRY	*pMacEntry;
-	PHEADER_802_11	pHeader80211;
-
-	pHeader80211 = (PHEADER_802_11)pHeader;
-	pMacEntry = pTxBlk->pMacEntry;
-
-	//
-	// Update the cached 802.11 HEADER
-	//
-
-	// normal wlan header size : 24 octets
-	pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11);
-
-	// More Bit
-	pHeader80211->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
-
-	// Sequence
-	pHeader80211->Sequence = pMacEntry->TxSeq[pTxBlk->UserPriority];
-    pMacEntry->TxSeq[pTxBlk->UserPriority] = (pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ;
-
-	{
-		// Check if the frame can be sent through DLS direct link interface
-		// If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability)
-#ifdef QOS_DLS_SUPPORT
-		BOOLEAN	bDLSFrame = FALSE;
-		INT	DlsEntryIndex = 0;
-
-		DlsEntryIndex = RTMPCheckDLSFrame(pAd, pTxBlk->pSrcBufHeader);
-		if (DlsEntryIndex >= 0)
-			bDLSFrame = TRUE;
-		else
-			bDLSFrame = FALSE;
-#endif // QOS_DLS_SUPPORT //
-
-		// The addr3 of normal packet send from DS is Dest Mac address.
-#ifdef QOS_DLS_SUPPORT
-		if (bDLSFrame)
-		{
-			COPY_MAC_ADDR(pHeader80211->Addr1, pTxBlk->pSrcBufHeader);
-			COPY_MAC_ADDR(pHeader80211->Addr3, pAd->CommonCfg.Bssid);
-			pHeader80211->FC.ToDs = 0;
-		}
-		else
-#endif // QOS_DLS_SUPPORT //
-		if (ADHOC_ON(pAd))
-			COPY_MAC_ADDR(pHeader80211->Addr3, pAd->CommonCfg.Bssid);
-		else
-		COPY_MAC_ADDR(pHeader80211->Addr3, pTxBlk->pSrcBufHeader);
-	}
-
-	// -----------------------------------------------------------------
-	// STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later.
-	// -----------------------------------------------------------------
-	if (pAd->CommonCfg.bAPSDForcePowerSave)
-	pHeader80211->FC.PwrMgmt = PWR_SAVE;
-	else
-	pHeader80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
-}
-#endif // DOT11_N_SUPPORT //
-
-static inline PUCHAR STA_Build_ARalink_Frame_Header(
-	IN RTMP_ADAPTER *pAd,
-	IN TX_BLK		*pTxBlk)
-{
-	PUCHAR			pHeaderBufPtr;
-	HEADER_802_11	*pHeader_802_11;
-	PNDIS_PACKET	pNextPacket;
-	UINT32			nextBufLen;
-	PQUEUE_ENTRY	pQEntry;
-
-	STAFindCipherAlgorithm(pAd, pTxBlk);
-	STABuildCommon802_11Header(pAd, pTxBlk);
-
-
-	pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
-	pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
-
-	// steal "order" bit to mark "aggregation"
-	pHeader_802_11->FC.Order = 1;
-
-	// skip common header
-	pHeaderBufPtr += pTxBlk->MpduHeaderLen;
-
-	if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
-	{
-		//
-		// build QOS Control bytes
-		//
-		*pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
-
-		*(pHeaderBufPtr+1) = 0;
-		pHeaderBufPtr +=2;
-		pTxBlk->MpduHeaderLen += 2;
-	}
-
-	// padding at front of LLC header. LLC header should at 4-bytes aligment.
-	pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
-	pHeaderBufPtr = (PUCHAR)ROUND_UP(pHeaderBufPtr, 4);
-	pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
-
-	// For RA Aggregation,
-	// put the 2nd MSDU length(extra 2-byte field) after QOS_CONTROL in little endian format
-	pQEntry = pTxBlk->TxPacketList.Head;
-	pNextPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
-	nextBufLen = GET_OS_PKT_LEN(pNextPacket);
-	if (RTMP_GET_PACKET_VLAN(pNextPacket))
-		nextBufLen -= LENGTH_802_1Q;
-
-	*pHeaderBufPtr = (UCHAR)nextBufLen & 0xff;
-	*(pHeaderBufPtr+1) = (UCHAR)(nextBufLen >> 8);
-
-	pHeaderBufPtr += 2;
-	pTxBlk->MpduHeaderLen += 2;
-
-	return pHeaderBufPtr;
-
-}
-
-#ifdef DOT11_N_SUPPORT
-static inline PUCHAR STA_Build_AMSDU_Frame_Header(
-	IN RTMP_ADAPTER *pAd,
-	IN TX_BLK		*pTxBlk)
-{
-	PUCHAR			pHeaderBufPtr;//, pSaveBufPtr;
-	HEADER_802_11	*pHeader_802_11;
-
-
-	STAFindCipherAlgorithm(pAd, pTxBlk);
-	STABuildCommon802_11Header(pAd, pTxBlk);
-
-	pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
-	pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
-
-	// skip common header
-	pHeaderBufPtr += pTxBlk->MpduHeaderLen;
-
-	//
-	// build QOS Control bytes
-	//
-	*pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
-
-	//
-	// A-MSDU packet
-	//
-	*pHeaderBufPtr |= 0x80;
-
-	*(pHeaderBufPtr+1) = 0;
-	pHeaderBufPtr +=2;
-	pTxBlk->MpduHeaderLen += 2;
-
-	//pSaveBufPtr = pHeaderBufPtr;
-
-	//
-	// padding at front of LLC header
-	// LLC header should locate at 4-octets aligment
-	//
-	// @@@ MpduHeaderLen excluding padding @@@
-	//
-	pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
-	pHeaderBufPtr = (PUCHAR) ROUND_UP(pHeaderBufPtr, 4);
-	pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
-
-	return pHeaderBufPtr;
-
-}
-
-
-VOID STA_AMPDU_Frame_Tx(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk)
-{
-	HEADER_802_11	*pHeader_802_11;
-	PUCHAR			pHeaderBufPtr;
-	USHORT			FreeNumber;
-	MAC_TABLE_ENTRY	*pMacEntry;
-	BOOLEAN			bVLANPkt;
-	PQUEUE_ENTRY	pQEntry;
-
-	ASSERT(pTxBlk);
-
-	while(pTxBlk->TxPacketList.Head)
-	{
-		pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
-		pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
-		if ( RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
-		{
-			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
-			continue;
-		}
-
-		bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
-
-		pMacEntry = pTxBlk->pMacEntry;
-		if (pMacEntry->isCached)
-		{
-			// NOTE: Please make sure the size of pMacEntry->CachedBuf[] is smaller than pTxBlk->HeaderBuf[]!!!!
-			NdisMoveMemory((PUCHAR)&pTxBlk->HeaderBuf[TXINFO_SIZE], (PUCHAR)&pMacEntry->CachedBuf[0], TXWI_SIZE + sizeof(HEADER_802_11));
-			pHeaderBufPtr = (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]);
-			STABuildCache802_11Header(pAd, pTxBlk, pHeaderBufPtr);
-		}
-		else
-		{
-			STAFindCipherAlgorithm(pAd, pTxBlk);
-			STABuildCommon802_11Header(pAd, pTxBlk);
-
-			pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
-		}
-
-
-		pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
-
-		// skip common header
-		pHeaderBufPtr += pTxBlk->MpduHeaderLen;
-
-		//
-		// build QOS Control bytes
-		//
-		*pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
-		*(pHeaderBufPtr+1) = 0;
-		pHeaderBufPtr +=2;
-		pTxBlk->MpduHeaderLen += 2;
-
-		//
-		// build HTC+
-		// HTC control filed following QoS field
-		//
-		if ((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry, fCLIENT_STATUS_RDG_CAPABLE))
-		{
-			if (pMacEntry->isCached == FALSE)
-			{
-				// mark HTC bit
-				pHeader_802_11->FC.Order = 1;
-
-				NdisZeroMemory(pHeaderBufPtr, 4);
-				*(pHeaderBufPtr+3) |= 0x80;
-			}
-			pHeaderBufPtr += 4;
-			pTxBlk->MpduHeaderLen += 4;
-		}
-
-		//pTxBlk->MpduHeaderLen = pHeaderBufPtr - pTxBlk->HeaderBuf - TXWI_SIZE - TXINFO_SIZE;
-		ASSERT(pTxBlk->MpduHeaderLen >= 24);
-
-		// skip 802.3 header
-		pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
-		pTxBlk->SrcBufLen  -= LENGTH_802_3;
-
-		// skip vlan tag
-		if (bVLANPkt)
-		{
-			pTxBlk->pSrcBufData	+= LENGTH_802_1Q;
-			pTxBlk->SrcBufLen	-= LENGTH_802_1Q;
-		}
-
-		//
-		// padding at front of LLC header
-		// LLC header should locate at 4-octets aligment
-		//
-		// @@@ MpduHeaderLen excluding padding @@@
-		//
-		pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
-		pHeaderBufPtr = (PUCHAR) ROUND_UP(pHeaderBufPtr, 4);
-		pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
-
-		{
-
-			//
-			// Insert LLC-SNAP encapsulation - 8 octets
-			//
-			EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
-			if (pTxBlk->pExtraLlcSnapEncap)
-			{
-				NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
-				pHeaderBufPtr += 6;
-				// get 2 octets (TypeofLen)
-				NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
-				pHeaderBufPtr += 2;
-				pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
-			}
-
-		}
-
-		if (pMacEntry->isCached)
-		{
-            RTMPWriteTxWI_Cache(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
-		}
-		else
-		{
-			RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
-
-			NdisZeroMemory((PUCHAR)(&pMacEntry->CachedBuf[0]), sizeof(pMacEntry->CachedBuf));
-			NdisMoveMemory((PUCHAR)(&pMacEntry->CachedBuf[0]), (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), (pHeaderBufPtr - (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE])));
-			pMacEntry->isCached = TRUE;
-		}
-
-		// calculate Transmitted AMPDU count and ByteCount
-		{
-			pAd->RalinkCounters.TransmittedMPDUsInAMPDUCount.u.LowPart ++;
-			pAd->RalinkCounters.TransmittedOctetsInAMPDUCount.QuadPart += pTxBlk->SrcBufLen;
-		}
-
-		//FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
-
-		HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
-
-		//
-		// Kick out Tx
-		//
-                if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
-		HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
-
-		pAd->RalinkCounters.KickTxCount++;
-		pAd->RalinkCounters.OneSecTxDoneCount++;
-	}
-
-}
-
-
-VOID STA_AMSDU_Frame_Tx(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk)
-{
-	PUCHAR			pHeaderBufPtr;
-	USHORT			FreeNumber;
-	USHORT			subFramePayloadLen = 0;	// AMSDU Subframe length without AMSDU-Header / Padding.
-	USHORT			totalMPDUSize=0;
-	UCHAR			*subFrameHeader;
-	UCHAR			padding = 0;
-	USHORT			FirstTx = 0, LastTxIdx = 0;
-	BOOLEAN			bVLANPkt;
-	int			frameNum = 0;
-	PQUEUE_ENTRY	pQEntry;
-
-
-	ASSERT(pTxBlk);
-
-	ASSERT((pTxBlk->TxPacketList.Number > 1));
-
-	while(pTxBlk->TxPacketList.Head)
-	{
-		pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
-		pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
-		if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
-		{
-			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
-			continue;
-		}
-
-		bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
-
-		// skip 802.3 header
-		pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
-		pTxBlk->SrcBufLen  -= LENGTH_802_3;
-
-		// skip vlan tag
-		if (bVLANPkt)
-		{
-			pTxBlk->pSrcBufData	+= LENGTH_802_1Q;
-			pTxBlk->SrcBufLen	-= LENGTH_802_1Q;
-		}
-
-		if (frameNum == 0)
-		{
-			pHeaderBufPtr = STA_Build_AMSDU_Frame_Header(pAd, pTxBlk);
-
-			// NOTE: TxWI->MPDUtotalByteCount will be updated after final frame was handled.
-			RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
-		}
-		else
-		{
-			pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
-			padding = ROUND_UP(LENGTH_AMSDU_SUBFRAMEHEAD + subFramePayloadLen, 4) - (LENGTH_AMSDU_SUBFRAMEHEAD + subFramePayloadLen);
-			NdisZeroMemory(pHeaderBufPtr, padding + LENGTH_AMSDU_SUBFRAMEHEAD);
-			pHeaderBufPtr += padding;
-			pTxBlk->MpduHeaderLen = padding;
-		}
-
-		//
-		// A-MSDU subframe
-		//   DA(6)+SA(6)+Length(2) + LLC/SNAP Encap
-		//
-		subFrameHeader = pHeaderBufPtr;
-		subFramePayloadLen = pTxBlk->SrcBufLen;
-
-		NdisMoveMemory(subFrameHeader, pTxBlk->pSrcBufHeader, 12);
-
-
-		pHeaderBufPtr += LENGTH_AMSDU_SUBFRAMEHEAD;
-		pTxBlk->MpduHeaderLen += LENGTH_AMSDU_SUBFRAMEHEAD;
-
-
-		//
-		// Insert LLC-SNAP encapsulation - 8 octets
-		//
-		EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
-
-		subFramePayloadLen = pTxBlk->SrcBufLen;
-
-		if (pTxBlk->pExtraLlcSnapEncap)
-		{
-			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
-			pHeaderBufPtr += 6;
-			// get 2 octets (TypeofLen)
-			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
-			pHeaderBufPtr += 2;
-			pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
-			subFramePayloadLen += LENGTH_802_1_H;
-		}
-
-		// update subFrame Length field
-		subFrameHeader[12] = (subFramePayloadLen & 0xFF00) >> 8;
-		subFrameHeader[13] = subFramePayloadLen & 0xFF;
-
-		totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
-
-		if (frameNum ==0)
-			FirstTx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
-		else
-			LastTxIdx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
-
-		frameNum++;
-
-		pAd->RalinkCounters.KickTxCount++;
-		pAd->RalinkCounters.OneSecTxDoneCount++;
-
-		// calculate Transmitted AMSDU Count and ByteCount
-		{
-			pAd->RalinkCounters.TransmittedAMSDUCount.u.LowPart ++;
-			pAd->RalinkCounters.TransmittedOctetsInAMSDU.QuadPart += totalMPDUSize;
-		}
-
-	}
-
-	HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
-	HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
-
-	//
-	// Kick out Tx
-	//
-        if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
-	HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
-}
-#endif // DOT11_N_SUPPORT //
-
-VOID STA_Legacy_Frame_Tx(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk)
-{
-	HEADER_802_11	*pHeader_802_11;
-	PUCHAR			pHeaderBufPtr;
-	USHORT			FreeNumber;
-	BOOLEAN			bVLANPkt;
-	PQUEUE_ENTRY	pQEntry;
-
-	ASSERT(pTxBlk);
-
-
-	pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
-	pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
-	if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
-	{
-		RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
-		return;
-	}
-
-	if (pTxBlk->TxFrameType == TX_MCAST_FRAME)
-	{
-		INC_COUNTER64(pAd->WlanCounters.MulticastTransmittedFrameCount);
-	}
-
-	if (RTMP_GET_PACKET_RTS(pTxBlk->pPacket))
-		TX_BLK_SET_FLAG(pTxBlk, fTX_bRtsRequired);
-	else
-		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bRtsRequired);
-
-	bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
-
-	if (pTxBlk->TxRate < pAd->CommonCfg.MinTxRate)
-		pTxBlk->TxRate = pAd->CommonCfg.MinTxRate;
-
-	STAFindCipherAlgorithm(pAd, pTxBlk);
-	STABuildCommon802_11Header(pAd, pTxBlk);
-
-
-	// skip 802.3 header
-	pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
-	pTxBlk->SrcBufLen  -= LENGTH_802_3;
-
-	// skip vlan tag
-	if (bVLANPkt)
-	{
-		pTxBlk->pSrcBufData	+= LENGTH_802_1Q;
-		pTxBlk->SrcBufLen	-= LENGTH_802_1Q;
-	}
-
-	pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
-	pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
-
-	// skip common header
-	pHeaderBufPtr += pTxBlk->MpduHeaderLen;
-
-	if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
-	{
-		//
-		// build QOS Control bytes
-		//
-		*(pHeaderBufPtr) = ((pTxBlk->UserPriority & 0x0F) | (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx]<<5));
-		*(pHeaderBufPtr+1) = 0;
-		pHeaderBufPtr +=2;
-		pTxBlk->MpduHeaderLen += 2;
-	}
-
-	// The remaining content of MPDU header should locate at 4-octets aligment
-	pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
-	pHeaderBufPtr = (PUCHAR) ROUND_UP(pHeaderBufPtr, 4);
-	pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
-
-	{
-
-		//
-		// Insert LLC-SNAP encapsulation - 8 octets
-		//
-		//
-		// if original Ethernet frame contains no LLC/SNAP,
-		// then an extra LLC/SNAP encap is required
-		//
-		EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader, pTxBlk->pExtraLlcSnapEncap);
-		if (pTxBlk->pExtraLlcSnapEncap)
-		{
-			UCHAR vlan_size;
-
-			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
-			pHeaderBufPtr += 6;
-			// skip vlan tag
-			vlan_size =  (bVLANPkt) ? LENGTH_802_1Q : 0;
-			// get 2 octets (TypeofLen)
-			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader+12+vlan_size, 2);
-			pHeaderBufPtr += 2;
-			pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
-		}
-
-	}
-
-	//
-	// prepare for TXWI
-	// use Wcid as Key Index
-	//
-
-	RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
-
-	//FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
-
-	HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
-
-	pAd->RalinkCounters.KickTxCount++;
-	pAd->RalinkCounters.OneSecTxDoneCount++;
-
-	//
-	// Kick out Tx
-	//
-	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
-	HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
-}
-
-
-VOID STA_ARalink_Frame_Tx(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	TX_BLK			*pTxBlk)
-{
-	PUCHAR			pHeaderBufPtr;
-	USHORT			FreeNumber;
-	USHORT			totalMPDUSize=0;
-	USHORT			FirstTx, LastTxIdx;
-	int			frameNum = 0;
-	BOOLEAN			bVLANPkt;
-	PQUEUE_ENTRY	pQEntry;
-
-
-	ASSERT(pTxBlk);
-
-	ASSERT((pTxBlk->TxPacketList.Number== 2));
-
-
-	FirstTx = LastTxIdx = 0;  // Is it ok init they as 0?
-	while(pTxBlk->TxPacketList.Head)
-	{
-		pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
-		pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
-
-		if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
-		{
-			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
-			continue;
-		}
-
-		bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
-
-		// skip 802.3 header
-		pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
-		pTxBlk->SrcBufLen  -= LENGTH_802_3;
-
-		// skip vlan tag
-		if (bVLANPkt)
-		{
-			pTxBlk->pSrcBufData	+= LENGTH_802_1Q;
-			pTxBlk->SrcBufLen	-= LENGTH_802_1Q;
-		}
-
-		if (frameNum == 0)
-		{	// For first frame, we need to create the 802.11 header + padding(optional) + RA-AGG-LEN + SNAP Header
-
-			pHeaderBufPtr = STA_Build_ARalink_Frame_Header(pAd, pTxBlk);
-
-			// It's ok write the TxWI here, because the TxWI->MPDUtotalByteCount
-			//	will be updated after final frame was handled.
-			RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
-
-
-			//
-			// Insert LLC-SNAP encapsulation - 8 octets
-			//
-			EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
-
-			if (pTxBlk->pExtraLlcSnapEncap)
-			{
-				NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
-				pHeaderBufPtr += 6;
-				// get 2 octets (TypeofLen)
-				NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
-				pHeaderBufPtr += 2;
-				pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
-			}
-		}
-		else
-		{	// For second aggregated frame, we need create the 802.3 header to headerBuf, because PCI will copy it to SDPtr0.
-
-			pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
-			pTxBlk->MpduHeaderLen = 0;
-
-			// A-Ralink sub-sequent frame header is the same as 802.3 header.
-			//   DA(6)+SA(6)+FrameType(2)
-			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader, 12);
-			pHeaderBufPtr += 12;
-			// get 2 octets (TypeofLen)
-			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
-			pHeaderBufPtr += 2;
-			pTxBlk->MpduHeaderLen = LENGTH_ARALINK_SUBFRAMEHEAD;
-		}
-
-		totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
-
-		//FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
-		if (frameNum ==0)
-			FirstTx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
-		else
-			LastTxIdx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
-
-		frameNum++;
-
-		pAd->RalinkCounters.OneSecTxAggregationCount++;
-		pAd->RalinkCounters.KickTxCount++;
-		pAd->RalinkCounters.OneSecTxDoneCount++;
-
-	}
-
-	HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
-	HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
-
-	//
-	// Kick out Tx
-	//
-	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
-	HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
-
-}
-
-
-VOID STA_Fragment_Frame_Tx(
-	IN RTMP_ADAPTER *pAd,
-	IN TX_BLK		*pTxBlk)
-{
-	HEADER_802_11	*pHeader_802_11;
-	PUCHAR			pHeaderBufPtr;
-	USHORT			FreeNumber;
-	UCHAR			fragNum = 0;
-	PACKET_INFO		PacketInfo;
-	USHORT			EncryptionOverhead = 0;
-	UINT32			FreeMpduSize, SrcRemainingBytes;
-	USHORT			AckDuration;
-	UINT			NextMpduSize;
-	BOOLEAN			bVLANPkt;
-	PQUEUE_ENTRY	pQEntry;
-	HTTRANSMIT_SETTING	*pTransmit;
-
-
-	ASSERT(pTxBlk);
-
-	pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
-	pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
-	if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
-	{
-		RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
-		return;
-	}
-
-	ASSERT(TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag));
-	bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
-
-	STAFindCipherAlgorithm(pAd, pTxBlk);
-	STABuildCommon802_11Header(pAd, pTxBlk);
-
-	if (pTxBlk->CipherAlg == CIPHER_TKIP)
-	{
-		pTxBlk->pPacket = duplicate_pkt_with_TKIP_MIC(pAd, pTxBlk->pPacket);
-		if (pTxBlk->pPacket == NULL)
-			return;
-		RTMP_QueryPacketInfo(pTxBlk->pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
-	}
-
-	// skip 802.3 header
-	pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
-	pTxBlk->SrcBufLen  -= LENGTH_802_3;
-
-
-	// skip vlan tag
-	if (bVLANPkt)
-	{
-		pTxBlk->pSrcBufData	+= LENGTH_802_1Q;
-		pTxBlk->SrcBufLen	-= LENGTH_802_1Q;
-	}
-
-	pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
-	pHeader_802_11 = (HEADER_802_11 *)pHeaderBufPtr;
-
-
-	// skip common header
-	pHeaderBufPtr += pTxBlk->MpduHeaderLen;
-
-	if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
-	{
-		//
-		// build QOS Control bytes
-		//
-		*pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
-
-		*(pHeaderBufPtr+1) = 0;
-		pHeaderBufPtr +=2;
-		pTxBlk->MpduHeaderLen += 2;
-	}
-
-	//
-	// padding at front of LLC header
-	// LLC header should locate at 4-octets aligment
-	//
-	pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
-	pHeaderBufPtr = (PUCHAR) ROUND_UP(pHeaderBufPtr, 4);
-	pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
-
-
-
-	//
-	// Insert LLC-SNAP encapsulation - 8 octets
-	//
-	//
-	// if original Ethernet frame contains no LLC/SNAP,
-	// then an extra LLC/SNAP encap is required
-	//
-	EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader, pTxBlk->pExtraLlcSnapEncap);
-	if (pTxBlk->pExtraLlcSnapEncap)
-	{
-		UCHAR vlan_size;
-
-		NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
-		pHeaderBufPtr += 6;
-		// skip vlan tag
-		vlan_size =  (bVLANPkt) ? LENGTH_802_1Q : 0;
-		// get 2 octets (TypeofLen)
-		NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader+12+vlan_size, 2);
-		pHeaderBufPtr += 2;
-		pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
-	}
-
-
-	// If TKIP is used and fragmentation is required. Driver has to
-	//	append TKIP MIC at tail of the scatter buffer
-	//	MAC ASIC will only perform IV/EIV/ICV insertion but no TKIP MIC
-	if (pTxBlk->CipherAlg == CIPHER_TKIP)
-	{
-		RTMPCalculateMICValue(pAd, pTxBlk->pPacket, pTxBlk->pExtraLlcSnapEncap, pTxBlk->pKey, 0);
-
-		// NOTE: DON'T refer the skb->len directly after following copy. Becasue the length is not adjust
-		//			to correct lenght, refer to pTxBlk->SrcBufLen for the packet length in following progress.
-		NdisMoveMemory(pTxBlk->pSrcBufData + pTxBlk->SrcBufLen, &pAd->PrivateInfo.Tx.MIC[0], 8);
-		//skb_put((RTPKT_TO_OSPKT(pTxBlk->pPacket))->tail, 8);
-		pTxBlk->SrcBufLen += 8;
-		pTxBlk->TotalFrameLen += 8;
-		pTxBlk->CipherAlg = CIPHER_TKIP_NO_MIC;
-	}
-
-	//
-	// calcuate the overhead bytes that encryption algorithm may add. This
-	// affects the calculate of "duration" field
-	//
-	if ((pTxBlk->CipherAlg == CIPHER_WEP64) || (pTxBlk->CipherAlg == CIPHER_WEP128))
-		EncryptionOverhead = 8; //WEP: IV[4] + ICV[4];
-	else if (pTxBlk->CipherAlg == CIPHER_TKIP_NO_MIC)
-		EncryptionOverhead = 12;//TKIP: IV[4] + EIV[4] + ICV[4], MIC will be added to TotalPacketLength
-	else if (pTxBlk->CipherAlg == CIPHER_TKIP)
-		EncryptionOverhead = 20;//TKIP: IV[4] + EIV[4] + ICV[4] + MIC[8]
-	else if (pTxBlk->CipherAlg == CIPHER_AES)
-		EncryptionOverhead = 16;	// AES: IV[4] + EIV[4] + MIC[8]
-	else
-		EncryptionOverhead = 0;
-
-	pTransmit = pTxBlk->pTransmit;
-	// Decide the TX rate
-	if (pTransmit->field.MODE == MODE_CCK)
-		pTxBlk->TxRate = pTransmit->field.MCS;
-	else if (pTransmit->field.MODE == MODE_OFDM)
-		pTxBlk->TxRate = pTransmit->field.MCS + RATE_FIRST_OFDM_RATE;
-	else
-		pTxBlk->TxRate = RATE_6_5;
-
-	// decide how much time an ACK/CTS frame will consume in the air
-	if (pTxBlk->TxRate <= RATE_LAST_OFDM_RATE)
-		AckDuration = RTMPCalcDuration(pAd, pAd->CommonCfg.ExpectedACKRate[pTxBlk->TxRate], 14);
-	else
-		AckDuration = RTMPCalcDuration(pAd, RATE_6_5, 14);
-
-	// Init the total payload length of this frame.
-	SrcRemainingBytes = pTxBlk->SrcBufLen;
-
-	pTxBlk->TotalFragNum = 0xff;
-
-	do {
-
-		FreeMpduSize = pAd->CommonCfg.FragmentThreshold - LENGTH_CRC;
-
-		FreeMpduSize -= pTxBlk->MpduHeaderLen;
-
-		if (SrcRemainingBytes <= FreeMpduSize)
-		{	// this is the last or only fragment
-
-			pTxBlk->SrcBufLen = SrcRemainingBytes;
-
-			pHeader_802_11->FC.MoreFrag = 0;
-			pHeader_802_11->Duration = pAd->CommonCfg.Dsifs + AckDuration;
-
-			// Indicate the lower layer that this's the last fragment.
-			pTxBlk->TotalFragNum = fragNum;
-		}
-		else
-		{	// more fragment is required
-
-			pTxBlk->SrcBufLen = FreeMpduSize;
-
-			NextMpduSize = min(((UINT)SrcRemainingBytes - pTxBlk->SrcBufLen), ((UINT)pAd->CommonCfg.FragmentThreshold));
-			pHeader_802_11->FC.MoreFrag = 1;
-			pHeader_802_11->Duration = (3 * pAd->CommonCfg.Dsifs) + (2 * AckDuration) + RTMPCalcDuration(pAd, pTxBlk->TxRate, NextMpduSize + EncryptionOverhead);
-		}
-
-		if (fragNum == 0)
-			pTxBlk->FrameGap = IFS_HTTXOP;
-		else
-			pTxBlk->FrameGap = IFS_SIFS;
-
-		RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
-
-		HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, &FreeNumber);
-
-		pAd->RalinkCounters.KickTxCount++;
-		pAd->RalinkCounters.OneSecTxDoneCount++;
-
-		// Update the frame number, remaining size of the NDIS packet payload.
-
-		// space for 802.11 header.
-		if (fragNum == 0 && pTxBlk->pExtraLlcSnapEncap)
-			pTxBlk->MpduHeaderLen -= LENGTH_802_1_H;
-
-		fragNum++;
-		SrcRemainingBytes -= pTxBlk->SrcBufLen;
-		pTxBlk->pSrcBufData += pTxBlk->SrcBufLen;
-
-		pHeader_802_11->Frag++;	 // increase Frag #
-
-	}while(SrcRemainingBytes > 0);
-
-	//
-	// Kick out Tx
-	//
-	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
-	HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
-}
-
-
-#define RELEASE_FRAMES_OF_TXBLK(_pAd, _pTxBlk, _pQEntry, _Status)										\
-		while(_pTxBlk->TxPacketList.Head)														\
-		{																						\
-			_pQEntry = RemoveHeadQueue(&_pTxBlk->TxPacketList);									\
-			RELEASE_NDIS_PACKET(_pAd, QUEUE_ENTRY_TO_PACKET(_pQEntry), _Status);	\
-		}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Copy frame from waiting queue into relative ring buffer and set
-	appropriate ASIC register to kick hardware encryption before really
-	sent out to air.
-
-	Arguments:
-		pAd	Pointer to our adapter
-		PNDIS_PACKET	Pointer to outgoing Ndis frame
-		NumberOfFrag	Number of fragment required
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-NDIS_STATUS STAHardTransmit(
-	IN PRTMP_ADAPTER	pAd,
-	IN TX_BLK			*pTxBlk,
-	IN	UCHAR			QueIdx)
-{
-	NDIS_PACKET		*pPacket;
-	PQUEUE_ENTRY	pQEntry;
-
-	// ---------------------------------------------
-	// STEP 0. DO SANITY CHECK AND SOME EARLY PREPARATION.
-	// ---------------------------------------------
-	//
-	ASSERT(pTxBlk->TxPacketList.Number);
-	if (pTxBlk->TxPacketList.Head == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("pTxBlk->TotalFrameNum == %ld!\n", pTxBlk->TxPacketList.Number));
-		return NDIS_STATUS_FAILURE;
-	}
-
-	pPacket = QUEUE_ENTRY_TO_PACKET(pTxBlk->TxPacketList.Head);
-
-
-	// ------------------------------------------------------------------
-	// STEP 1. WAKE UP PHY
-	//		outgoing frame always wakeup PHY to prevent frame lost and
-	//		turn off PSM bit to improve performance
-	// ------------------------------------------------------------------
-	// not to change PSM bit, just send this frame out?
-	if ((pAd->StaCfg.Psm == PWR_SAVE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-	{
-	    DBGPRINT_RAW(RT_DEBUG_INFO, ("AsicForceWakeup At HardTx\n"));
-#ifdef RTMP_MAC_PCI
-		AsicForceWakeup(pAd, TRUE);
-#endif // RTMP_MAC_PCI //
-	}
-
-	// It should not change PSM bit, when APSD turn on.
-	if ((!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable) && (pAd->CommonCfg.bAPSDForcePowerSave == FALSE))
-		|| (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
-		|| (RTMP_GET_PACKET_WAI(pTxBlk->pPacket)))
-	{
-		if ((pAd->StaCfg.Psm == PWR_SAVE) &&
-            (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeFast_PSP))
-			RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
-	}
-
-	switch (pTxBlk->TxFrameType)
-	{
-#ifdef DOT11_N_SUPPORT
-		case TX_AMPDU_FRAME:
-				STA_AMPDU_Frame_Tx(pAd, pTxBlk);
-			break;
-		case TX_AMSDU_FRAME:
-				STA_AMSDU_Frame_Tx(pAd, pTxBlk);
-			break;
-#endif // DOT11_N_SUPPORT //
-		case TX_LEGACY_FRAME:
-				STA_Legacy_Frame_Tx(pAd, pTxBlk);
-			break;
-		case TX_MCAST_FRAME:
-				STA_Legacy_Frame_Tx(pAd, pTxBlk);
-			break;
-		case TX_RALINK_FRAME:
-				STA_ARalink_Frame_Tx(pAd, pTxBlk);
-			break;
-		case TX_FRAG_FRAME:
-				STA_Fragment_Frame_Tx(pAd, pTxBlk);
-			break;
-		default:
-			{
-				// It should not happened!
-				DBGPRINT(RT_DEBUG_ERROR, ("Send a pacekt was not classified!! It should not happen!\n"));
-				while(pTxBlk->TxPacketList.Number)
-				{
-					pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
-					pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
-					if (pPacket)
-						RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-				}
-			}
-			break;
-	}
-
-	return (NDIS_STATUS_SUCCESS);
-
-}
-
-ULONG  HashBytesPolynomial(UCHAR *value, unsigned int len)
-{
-   unsigned char *word = value;
-   unsigned int ret = 0;
-   unsigned int i;
-
-   for(i=0; i < len; i++)
-   {
-	  int mod = i % 32;
-	  ret ^=(unsigned int) (word[i]) << mod;
-	  ret ^=(unsigned int) (word[i]) >> (32 - mod);
-   }
-   return ret;
-}
-
-VOID Sta_Announce_or_Forward_802_3_Packet(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PNDIS_PACKET	pPacket,
-	IN	UCHAR			FromWhichBSSID)
-{
-	if (TRUE
-		)
-	{
-		announce_802_3_packet(pAd, pPacket);
-	}
-	else
-	{
-		// release packet
-		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-	}
-}
diff --git a/drivers/staging/rt3090/sta/sanity.c b/drivers/staging/rt3090/sta/sanity.c
deleted file mode 100644
index aeda15b..0000000
--- a/drivers/staging/rt3090/sta/sanity.c
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	sanity.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	John Chang  2004-09-01      add WMM support
-*/
-
-#include "../rt_config.h"
-
-
-extern UCHAR	CISCO_OUI[];
-
-extern UCHAR	WPA_OUI[];
-extern UCHAR	RSN_OUI[];
-extern UCHAR	WME_INFO_ELEM[];
-extern UCHAR	WME_PARM_ELEM[];
-extern UCHAR	Ccx2QosInfo[];
-extern UCHAR	RALINK_OUI[];
-extern UCHAR	BROADCOM_OUI[];
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
- */
-BOOLEAN MlmeStartReqSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT CHAR Ssid[],
-    OUT UCHAR *pSsidLen)
-{
-    MLME_START_REQ_STRUCT *Info;
-
-    Info = (MLME_START_REQ_STRUCT *)(Msg);
-
-    if (Info->SsidLen > MAX_LEN_OF_SSID)
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqSanity fail - wrong SSID length\n"));
-        return FALSE;
-    }
-
-    *pSsidLen = Info->SsidLen;
-    NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen);
-
-    return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-
-    IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-BOOLEAN PeerAssocRspSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *pMsg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pAddr2,
-    OUT USHORT *pCapabilityInfo,
-    OUT USHORT *pStatus,
-    OUT USHORT *pAid,
-    OUT UCHAR SupRate[],
-    OUT UCHAR *pSupRateLen,
-    OUT UCHAR ExtRate[],
-    OUT UCHAR *pExtRateLen,
-    OUT HT_CAPABILITY_IE		*pHtCapability,
-    OUT ADD_HT_INFO_IE		*pAddHtInfo,	// AP might use this additional ht info IE
-    OUT UCHAR			*pHtCapabilityLen,
-    OUT UCHAR			*pAddHtInfoLen,
-    OUT UCHAR			*pNewExtChannelOffset,
-    OUT PEDCA_PARM pEdcaParm,
-    OUT UCHAR *pCkipFlag)
-{
-    CHAR          IeType, *Ptr;
-    PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
-    PEID_STRUCT   pEid;
-    ULONG         Length = 0;
-
-	*pNewExtChannelOffset = 0xff;
-	*pHtCapabilityLen = 0;
-	*pAddHtInfoLen = 0;
-    COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
-    Ptr = (PCHAR)pFrame->Octet;
-    Length += LENGTH_802_11;
-
-    NdisMoveMemory(pCapabilityInfo, &pFrame->Octet[0], 2);
-    Length += 2;
-    NdisMoveMemory(pStatus,         &pFrame->Octet[2], 2);
-    Length += 2;
-    *pCkipFlag = 0;
-    *pExtRateLen = 0;
-    pEdcaParm->bValid = FALSE;
-
-    if (*pStatus != MLME_SUCCESS)
-        return TRUE;
-
-    NdisMoveMemory(pAid, &pFrame->Octet[4], 2);
-    Length += 2;
-
-    // Aid already swaped byte order in RTMPFrameEndianChange() for big endian platform
-    *pAid = (*pAid) & 0x3fff; // AID is low 14-bit
-
-    // -- get supported rates from payload and advance the pointer
-    IeType = pFrame->Octet[6];
-    *pSupRateLen = pFrame->Octet[7];
-    if ((IeType != IE_SUPP_RATES) || (*pSupRateLen > MAX_LEN_OF_SUPPORTED_RATES))
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspSanity fail - wrong SupportedRates IE\n"));
-        return FALSE;
-    }
-    else
-        NdisMoveMemory(SupRate, &pFrame->Octet[8], *pSupRateLen);
-
-
-    Length = Length + 2 + *pSupRateLen;
-
-    // many AP implement proprietary IEs in non-standard order, we'd better
-    // tolerate mis-ordered IEs to get best compatibility
-    pEid = (PEID_STRUCT) &pFrame->Octet[8 + (*pSupRateLen)];
-
-    // get variable fields from payload and advance the pointer
-    while ((Length + 2 + pEid->Len) <= MsgLen)
-    {
-        switch (pEid->Eid)
-        {
-            case IE_EXT_SUPP_RATES:
-                if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
-                {
-                    NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
-                    *pExtRateLen = pEid->Len;
-                }
-                break;
-
-             case IE_HT_CAP:
-            case IE_HT_CAP2:
-			if (pEid->Len >= SIZE_HT_CAP_IE)  //Note: allow extension.!!
-			{
-				NdisMoveMemory(pHtCapability, pEid->Octet, SIZE_HT_CAP_IE);
-
-				*(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
-				*(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
-
-				*pHtCapabilityLen = SIZE_HT_CAP_IE;
-			}
-			else
-			{
-				DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_HT_CAP. \n"));
-			}
-
-		break;
-#ifdef DOT11_N_SUPPORT
-            case IE_ADD_HT:
-            case IE_ADD_HT2:
-			if (pEid->Len >= sizeof(ADD_HT_INFO_IE))
-			{
-				// This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only
-				// copy first sizeof(ADD_HT_INFO_IE)
-				NdisMoveMemory(pAddHtInfo, pEid->Octet, sizeof(ADD_HT_INFO_IE));
-
-				*(USHORT *)(&pAddHtInfo->AddHtInfo2) = cpu2le16(*(USHORT *)(&pAddHtInfo->AddHtInfo2));
-				*(USHORT *)(&pAddHtInfo->AddHtInfo3) = cpu2le16(*(USHORT *)(&pAddHtInfo->AddHtInfo3));
-
-				*pAddHtInfoLen = SIZE_ADD_HT_INFO_IE;
-			}
-			else
-			{
-				DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_ADD_HT. \n"));
-			}
-
-		break;
-            case IE_SECONDARY_CH_OFFSET:
-			if (pEid->Len == 1)
-			{
-				*pNewExtChannelOffset = pEid->Octet[0];
-			}
-			else
-			{
-				DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
-			}
-#endif // DOT11_N_SUPPORT //
-		break;
-
-            case IE_VENDOR_SPECIFIC:
-                // handle WME PARAMTER ELEMENT
-                if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) && (pEid->Len == 24))
-                {
-                    PUCHAR ptr;
-                    int i;
-
-                    // parsing EDCA parameters
-                    pEdcaParm->bValid          = TRUE;
-                    pEdcaParm->bQAck           = FALSE; // pEid->Octet[0] & 0x10;
-                    pEdcaParm->bQueueRequest   = FALSE; // pEid->Octet[0] & 0x20;
-                    pEdcaParm->bTxopRequest    = FALSE; // pEid->Octet[0] & 0x40;
-                    //pEdcaParm->bMoreDataAck    = FALSE; // pEid->Octet[0] & 0x80;
-                    pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
-                    pEdcaParm->bAPSDCapable    = (pEid->Octet[6] & 0x80) ? 1 : 0;
-                    ptr = (PUCHAR)&pEid->Octet[8];
-                    for (i=0; i<4; i++)
-                    {
-                        UCHAR aci = (*ptr & 0x60) >> 5; // b5~6 is AC INDEX
-                        pEdcaParm->bACM[aci]  = (((*ptr) & 0x10) == 0x10);   // b5 is ACM
-                        pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f;               // b0~3 is AIFSN
-                        pEdcaParm->Cwmin[aci] = *(ptr+1) & 0x0f;             // b0~4 is Cwmin
-                        pEdcaParm->Cwmax[aci] = *(ptr+1) >> 4;               // b5~8 is Cwmax
-                        pEdcaParm->Txop[aci]  = *(ptr+2) + 256 * (*(ptr+3)); // in unit of 32-us
-                        ptr += 4; // point to next AC
-                    }
-                }
-                break;
-            default:
-                DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspSanity - ignore unrecognized EID = %d\n", pEid->Eid));
-                break;
-        }
-
-        Length = Length + 2 + pEid->Len;
-        pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
-    }
-
-
-    return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-BOOLEAN PeerProbeReqSanity(
-    IN PRTMP_ADAPTER pAd,
-    IN VOID *Msg,
-    IN ULONG MsgLen,
-    OUT PUCHAR pAddr2,
-    OUT CHAR Ssid[],
-    OUT UCHAR *pSsidLen)
-{
-    UCHAR         Idx;
-    UCHAR	      RateLen;
-    CHAR          IeType;
-    PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
-
-    COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
-
-    if ((pFrame->Octet[0] != IE_SSID) || (pFrame->Octet[1] > MAX_LEN_OF_SSID))
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("PeerProbeReqSanity fail - wrong SSID IE(Type=%d,Len=%d)\n",pFrame->Octet[0],pFrame->Octet[1]));
-        return FALSE;
-    }
-
-    *pSsidLen = pFrame->Octet[1];
-    NdisMoveMemory(Ssid, &pFrame->Octet[2], *pSsidLen);
-
-    Idx = *pSsidLen + 2;
-
-    // -- get supported rates from payload and advance the pointer
-    IeType = pFrame->Octet[Idx];
-    RateLen = pFrame->Octet[Idx + 1];
-    if (IeType != IE_SUPP_RATES)
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("PeerProbeReqSanity fail - wrong SupportRates IE(Type=%d,Len=%d)\n",pFrame->Octet[Idx],pFrame->Octet[Idx+1]));
-        return FALSE;
-    }
-    else
-    {
-        if ((pAd->CommonCfg.PhyMode == PHY_11G) && (RateLen < 8))
-            return (FALSE);
-    }
-
-    return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-BOOLEAN GetTimBit(
-    IN CHAR *Ptr,
-    IN USHORT Aid,
-    OUT UCHAR *TimLen,
-    OUT UCHAR *BcastFlag,
-    OUT UCHAR *DtimCount,
-    OUT UCHAR *DtimPeriod,
-    OUT UCHAR *MessageToMe)
-{
-    UCHAR          BitCntl, N1, N2, MyByte, MyBit;
-    CHAR          *IdxPtr;
-
-    IdxPtr = Ptr;
-
-    IdxPtr ++;
-    *TimLen = *IdxPtr;
-
-    // get DTIM Count from TIM element
-    IdxPtr ++;
-    *DtimCount = *IdxPtr;
-
-    // get DTIM Period from TIM element
-    IdxPtr++;
-    *DtimPeriod = *IdxPtr;
-
-    // get Bitmap Control from TIM element
-    IdxPtr++;
-    BitCntl = *IdxPtr;
-
-    if ((*DtimCount == 0) && (BitCntl & 0x01))
-        *BcastFlag = TRUE;
-    else
-        *BcastFlag = FALSE;
-
-    // Parse Partial Virtual Bitmap from TIM element
-    N1 = BitCntl & 0xfe;    // N1 is the first bitmap byte#
-    N2 = *TimLen - 4 + N1;  // N2 is the last bitmap byte#
-
-    if ((Aid < (N1 << 3)) || (Aid >= ((N2 + 1) << 3)))
-        *MessageToMe = FALSE;
-    else
-    {
-        MyByte = (Aid >> 3) - N1;                       // my byte position in the bitmap byte-stream
-        MyBit = Aid % 16 - ((MyByte & 0x01)? 8:0);
-
-        IdxPtr += (MyByte + 1);
-
-        //if (*IdxPtr)
-        //    DBGPRINT(RT_DEBUG_WARN, ("TIM bitmap = 0x%02x\n", *IdxPtr));
-
-        if (*IdxPtr & (0x01 << MyBit))
-            *MessageToMe = TRUE;
-        else
-            *MessageToMe = FALSE;
-    }
-
-    return TRUE;
-}
diff --git a/drivers/staging/rt3090/sta/sync.c b/drivers/staging/rt3090/sta/sync.c
deleted file mode 100644
index 2520e03..0000000
--- a/drivers/staging/rt3090/sta/sync.c
+++ /dev/null
@@ -1,1840 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	sync.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	John Chang	2004-09-01      modified for rt2561/2661
-	Jan Lee		2006-08-01      modified for rt2860 for 802.11n
-*/
-
-#include "../rt_config.h"
-
-
-#define ADHOC_ENTRY_BEACON_LOST_TIME	(2*OS_HZ)	// 2 sec
-
-/*
-	==========================================================================
-	Description:
-		The sync state machine,
-	Parameters:
-		Sm - pointer to the state machine
-	Note:
-		the state machine looks like the following
-
-	==========================================================================
- */
-VOID SyncStateMachineInit(
-	IN PRTMP_ADAPTER pAd,
-	IN STATE_MACHINE *Sm,
-	OUT STATE_MACHINE_FUNC Trans[])
-{
-	StateMachineInit(Sm, Trans, MAX_SYNC_STATE, MAX_SYNC_MSG, (STATE_MACHINE_FUNC)Drop, SYNC_IDLE, SYNC_MACHINE_BASE);
-
-	// column 1
-	StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)MlmeScanReqAction);
-	StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)MlmeJoinReqAction);
-	StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)MlmeStartReqAction);
-	StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeacon);
-	StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_PROBE_REQ, (STATE_MACHINE_FUNC)PeerProbeReqAction);
-
-	//column 2
-	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan);
-	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin);
-	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart);
-	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtJoinAction);
-	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_BEACON_TIMEOUT, (STATE_MACHINE_FUNC)BeaconTimeoutAtJoinAction);
-
-	// column 3
-	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan);
-	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin);
-	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart);
-	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction);
-	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_PROBE_RSP, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction);
-	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_SCAN_TIMEOUT, (STATE_MACHINE_FUNC)ScanTimeoutAction);
-
-	// timer init
-	RTMPInitTimer(pAd, &pAd->MlmeAux.BeaconTimer, GET_TIMER_FUNCTION(BeaconTimeout), pAd, FALSE);
-	RTMPInitTimer(pAd, &pAd->MlmeAux.ScanTimer, GET_TIMER_FUNCTION(ScanTimeout), pAd, FALSE);
-}
-
-/*
-	==========================================================================
-	Description:
-		Beacon timeout handler, executed in timer thread
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID BeaconTimeout(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3)
-{
-	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
-
-	DBGPRINT(RT_DEBUG_TRACE,("SYNC - BeaconTimeout\n"));
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
-		return;
-
-#ifdef DOT11_N_SUPPORT
-	if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
-		)
-	{
-		UCHAR        BBPValue = 0;
-		AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
-		AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-		BBPValue &= (~0x18);
-		BBPValue |= 0x10;
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-		DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
-	}
-#endif // DOT11_N_SUPPORT //
-
-	MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_BEACON_TIMEOUT, 0, NULL);
-	RTMP_MLME_HANDLER(pAd);
-}
-
-/*
-	==========================================================================
-	Description:
-		Scan timeout handler, executed in timer thread
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID ScanTimeout(
-	IN PVOID SystemSpecific1,
-	IN PVOID FunctionContext,
-	IN PVOID SystemSpecific2,
-	IN PVOID SystemSpecific3)
-{
-	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
-
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
-		return;
-
-	if (MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_SCAN_TIMEOUT, 0, NULL))
-	{
-	RTMP_MLME_HANDLER(pAd);
-}
-	else
-	{
-		// To prevent SyncMachine.CurrState is SCAN_LISTEN forever.
-		pAd->MlmeAux.Channel = 0;
-		ScanNextChannel(pAd);
-		if (pAd->CommonCfg.bWirelessEvent)
-		{
-			RTMPSendWirelessEvent(pAd, IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-		}
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-		MLME SCAN req state machine procedure
-	==========================================================================
- */
-VOID MlmeScanReqAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	UCHAR          Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType, BBPValue = 0;
-	BOOLEAN        TimerCancelled;
-	ULONG		   Now;
-	USHORT         Status;
-	PHEADER_802_11 pHdr80211;
-	PUCHAR         pOutBuffer = NULL;
-	NDIS_STATUS    NStatus;
-
-	// Check the total scan tries for one single OID command
-	// If this is the CCX 2.0 Case, skip that!
-	if ( !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeScanReqAction before Startup\n"));
-		return;
-	}
-
-	// Increase the scan retry counters.
-	pAd->StaCfg.ScanCnt++;
-
-#ifdef RTMP_MAC_PCI
-    if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) &&
-        (IDLE_ON(pAd)) &&
-		(pAd->StaCfg.bRadio == TRUE) &&
-		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
-	{
-	        if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE)
-		{
-			AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02);
-			AsicCheckCommanOk(pAd, PowerWakeCID);
-			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
-			DBGPRINT(RT_DEBUG_TRACE, ("PSM - Issue Wake up command \n"));
-		}
-		else
-		{
-		RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
-	}
-	}
-#endif // RTMP_MAC_PCI //
-
-	// first check the parameter sanity
-	if (MlmeScanReqSanity(pAd,
-						  Elem->Msg,
-						  Elem->MsgLen,
-						  &BssType,
-						  (PCHAR)Ssid,
-						  &SsidLen,
-						  &ScanType))
-	{
-
-		// Check for channel load and noise hist request
-		// Suspend MSDU only at scan request, not the last two mentioned
-		// Suspend MSDU transmission here
-		RTMPSuspendMsduTransmission(pAd);
-
-		//
-		// To prevent data lost.
-		// Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
-		// And should send an NULL data with turned PSM bit off to AP, when scan progress done
-		//
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)))
-		{
-			NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);
-			if (NStatus	== NDIS_STATUS_SUCCESS)
-			{
-				pHdr80211 = (PHEADER_802_11) pOutBuffer;
-				MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
-				pHdr80211->Duration = 0;
-				pHdr80211->FC.Type = BTYPE_DATA;
-				pHdr80211->FC.PwrMgmt = PWR_SAVE;
-
-				// Send using priority queue
-				MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
-				DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame for off channel RM\n"));
-				MlmeFreeMemory(pAd, pOutBuffer);
-				RTMPusecDelay(5000);
-			}
-		}
-
-		NdisGetSystemUpTime(&Now);
-		pAd->StaCfg.LastScanTime = Now;
-		// reset all the timers
-		RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
-
-		// record desired BSS parameters
-		pAd->MlmeAux.BssType = BssType;
-		pAd->MlmeAux.ScanType = ScanType;
-		pAd->MlmeAux.SsidLen = SsidLen;
-        NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
-		NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
-
-		// start from the first channel
-		pAd->MlmeAux.Channel = FirstChannel(pAd);
-
-		// Let BBP register at 20MHz to do scan
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-		BBPValue &= (~0x18);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-		DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
-		ScanNextChannel(pAd);
-	}
-	else
-	{
-		DBGPRINT_ERR(("SYNC - MlmeScanReqAction() sanity check fail\n"));
-		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
-		Status = MLME_INVALID_FORMAT;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-		MLME JOIN req state machine procedure
-	==========================================================================
- */
-VOID MlmeJoinReqAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	UCHAR        BBPValue = 0;
-	BSS_ENTRY    *pBss;
-	BOOLEAN       TimerCancelled;
-	HEADER_802_11 Hdr80211;
-	NDIS_STATUS   NStatus;
-	ULONG         FrameLen = 0;
-	PUCHAR        pOutBuffer = NULL;
-	PUCHAR        pSupRate = NULL;
-	UCHAR         SupRateLen;
-	PUCHAR        pExtRate = NULL;
-	UCHAR         ExtRateLen;
-	UCHAR         ASupRate[] = {0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C};
-	UCHAR         ASupRateLen = sizeof(ASupRate)/sizeof(UCHAR);
-	MLME_JOIN_REQ_STRUCT *pInfo = (MLME_JOIN_REQ_STRUCT *)(Elem->Msg);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx));
-
-#ifdef RTMP_MAC_PCI
-    if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) &&
-        (IDLE_ON(pAd)) &&
-		(pAd->StaCfg.bRadio == TRUE) &&
-		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
-	{
-		RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
-	}
-#endif // RTMP_MAC_PCI //
-
-	// reset all the timers
-	RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
-	RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
-
-	pBss = &pAd->MlmeAux.SsidBssTab.BssEntry[pInfo->BssIdx];
-
-	// record the desired SSID & BSSID we're waiting for
-	COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pBss->Bssid);
-
-	// If AP's SSID is not hidden, it is OK for updating ssid to MlmeAux again.
-	if (pBss->Hidden == 0)
-	{
-		RTMPZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
-		NdisMoveMemory(pAd->MlmeAux.Ssid, pBss->Ssid, pBss->SsidLen);
-	pAd->MlmeAux.SsidLen = pBss->SsidLen;
-	}
-
-	pAd->MlmeAux.BssType = pBss->BssType;
-	pAd->MlmeAux.Channel = pBss->Channel;
-	pAd->MlmeAux.CentralChannel = pBss->CentralChannel;
-
-#ifdef EXT_BUILD_CHANNEL_LIST
-	// Country IE of the AP will be evaluated and will be used.
-	if ((pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None) &&
-		(pBss->bHasCountryIE == TRUE))
-	{
-		NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pBss->CountryString[0], 2);
-		if (pBss->CountryString[2] == 'I')
-			pAd->CommonCfg.Geography = IDOR;
-		else if (pBss->CountryString[2] == 'O')
-			pAd->CommonCfg.Geography = ODOR;
-		else
-			pAd->CommonCfg.Geography = BOTH;
-		BuildChannelListEx(pAd);
-	}
-#endif // EXT_BUILD_CHANNEL_LIST //
-
-	// Let BBP register at 20MHz to do scan
-	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-	BBPValue &= (~0x18);
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-	DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
-
-	// switch channel and waiting for beacon timer
-	AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
-	AsicLockChannel(pAd, pAd->MlmeAux.Channel);
-
-
-	RTMPSetTimer(&pAd->MlmeAux.BeaconTimer, JOIN_TIMEOUT);
-
-    do
-	{
-		if (((pAd->CommonCfg.bIEEE80211H == 1) &&
-            (pAd->MlmeAux.Channel > 14) &&
-             RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
-#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
-             || (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
-#endif // CARRIER_DETECTION_SUPPORT //
-            )
-		{
-			//
-			// We can't send any Probe request frame to meet 802.11h.
-			//
-			if (pBss->Hidden == 0)
-			break;
-		}
-
-	//
-	// send probe request
-	//
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
-	if (NStatus == NDIS_STATUS_SUCCESS)
-	{
-		if (pAd->MlmeAux.Channel <= 14)
-		{
-			pSupRate = pAd->CommonCfg.SupRate;
-			SupRateLen = pAd->CommonCfg.SupRateLen;
-			pExtRate = pAd->CommonCfg.ExtRate;
-			ExtRateLen = pAd->CommonCfg.ExtRateLen;
-		}
-		else
-		{
-			//
-			// Overwrite Support Rate, CCK rate are not allowed
-			//
-			pSupRate = ASupRate;
-			SupRateLen = ASupRateLen;
-			ExtRateLen = 0;
-		}
-
-		if (pAd->MlmeAux.BssType == BSS_INFRA)
-			MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, pAd->MlmeAux.Bssid, pAd->MlmeAux.Bssid);
-		else
-			MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
-
-		MakeOutgoingFrame(pOutBuffer,               &FrameLen,
-						  sizeof(HEADER_802_11),    &Hdr80211,
-						  1,                        &SsidIe,
-						  1,                        &pAd->MlmeAux.SsidLen,
-						  pAd->MlmeAux.SsidLen,	    pAd->MlmeAux.Ssid,
-						  1,                        &SupRateIe,
-						  1,                        &SupRateLen,
-						  SupRateLen,               pSupRate,
-						  END_OF_ARGS);
-
-		if (ExtRateLen)
-		{
-			ULONG Tmp;
-			MakeOutgoingFrame(pOutBuffer + FrameLen,            &Tmp,
-							  1,                                &ExtRateIe,
-							  1,                                &ExtRateLen,
-							  ExtRateLen,                       pExtRate,
-							  END_OF_ARGS);
-			FrameLen += Tmp;
-		}
-
-
-		MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-		MlmeFreeMemory(pAd, pOutBuffer);
-	}
-    } while (FALSE);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("SYNC - Switch to ch %d, Wait BEACON from %02x:%02x:%02x:%02x:%02x:%02x\n",
-		pBss->Channel, pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2], pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
-
-	pAd->Mlme.SyncMachine.CurrState = JOIN_WAIT_BEACON;
-}
-
-/*
-	==========================================================================
-	Description:
-		MLME START Request state machine procedure, starting an IBSS
-	==========================================================================
- */
-VOID MlmeStartReqAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	UCHAR         Ssid[MAX_LEN_OF_SSID], SsidLen;
-	BOOLEAN       TimerCancelled;
-
-	// New for WPA security suites
-	UCHAR						VarIE[MAX_VIE_LEN];	// Total VIE length = MAX_VIE_LEN - -5
-	NDIS_802_11_VARIABLE_IEs	*pVIE = NULL;
-	LARGE_INTEGER				TimeStamp;
-	BOOLEAN Privacy;
-	USHORT Status;
-
-	// Init Variable IE structure
-	pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
-	pVIE->Length = 0;
-	TimeStamp.u.LowPart  = 0;
-	TimeStamp.u.HighPart = 0;
-
-	if (MlmeStartReqSanity(pAd, Elem->Msg, Elem->MsgLen, (PCHAR)Ssid, &SsidLen))
-	{
-		// reset all the timers
-		RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
-
-		//
-		// Start a new IBSS. All IBSS parameters are decided now....
-		//
-		DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqAction - Start a new IBSS. All IBSS parameters are decided now.... \n"));
-		pAd->MlmeAux.BssType           = BSS_ADHOC;
-		NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
-		pAd->MlmeAux.SsidLen           = SsidLen;
-
-		// generate a radom number as BSSID
-		MacAddrRandomBssid(pAd, pAd->MlmeAux.Bssid);
-		DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqAction - generate a radom number as BSSID \n"));
-
-		Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
-				  (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
-				  (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
-		pAd->MlmeAux.CapabilityInfo    = CAP_GENERATE(0,1,Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 1, 0);
-		pAd->MlmeAux.BeaconPeriod      = pAd->CommonCfg.BeaconPeriod;
-		pAd->MlmeAux.AtimWin           = pAd->StaCfg.AtimWin;
-		pAd->MlmeAux.Channel           = pAd->CommonCfg.Channel;
-
-		pAd->CommonCfg.CentralChannel  = pAd->CommonCfg.Channel;
-		pAd->MlmeAux.CentralChannel    = pAd->CommonCfg.CentralChannel;
-
-		pAd->MlmeAux.SupRateLen= pAd->CommonCfg.SupRateLen;
-		NdisMoveMemory(pAd->MlmeAux.SupRate, pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
-		RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
-		pAd->MlmeAux.ExtRateLen = pAd->CommonCfg.ExtRateLen;
-		NdisMoveMemory(pAd->MlmeAux.ExtRate, pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
-		RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
-#ifdef DOT11_N_SUPPORT
-		if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
-		{
-			RTMPUpdateHTIE(&pAd->CommonCfg.DesiredHtPhy, &pAd->StaCfg.DesiredHtPhyInfo.MCSSet[0], &pAd->MlmeAux.HtCapability, &pAd->MlmeAux.AddHtInfo);
-			pAd->MlmeAux.HtCapabilityLen = sizeof(HT_CAPABILITY_IE);
-			// Not turn pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE here.
-			DBGPRINT(RT_DEBUG_TRACE, ("SYNC -pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE\n"));
-		}
-		else
-#endif // DOT11_N_SUPPORT //
-		{
-			pAd->MlmeAux.HtCapabilityLen = 0;
-			pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
-			NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
-		}
-		// temporarily not support QOS in IBSS
-		NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));
-		NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));
-		NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));
-
-		AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
-		AsicLockChannel(pAd, pAd->MlmeAux.Channel);
-
-		DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeStartReqAction(ch= %d,sup rates= %d, ext rates=%d)\n",
-			pAd->MlmeAux.Channel, pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen));
-
-		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
-		Status = MLME_SUCCESS;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
-	}
-	else
-	{
-		DBGPRINT_ERR(("SYNC - MlmeStartReqAction() sanity check fail.\n"));
-		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
-		Status = MLME_INVALID_FORMAT;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-		peer sends beacon back when scanning
-	==========================================================================
- */
-VOID PeerBeaconAtScanAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	UCHAR           Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
-	UCHAR           Ssid[MAX_LEN_OF_SSID], BssType, Channel, NewChannel,
-					SsidLen, DtimCount, DtimPeriod, BcastFlag, MessageToMe;
-	CF_PARM         CfParm;
-	USHORT          BeaconPeriod, AtimWin, CapabilityInfo;
-	PFRAME_802_11   pFrame;
-	LARGE_INTEGER   TimeStamp;
-	UCHAR           Erp;
-	UCHAR		SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR			SupRateLen, ExtRateLen;
-	USHORT			LenVIE;
-	UCHAR			CkipFlag;
-	UCHAR			AironetCellPowerLimit;
-	EDCA_PARM       EdcaParm;
-	QBSS_LOAD_PARM  QbssLoad;
-	QOS_CAPABILITY_PARM QosCapability;
-	ULONG						RalinkIe;
-	UCHAR						VarIE[MAX_VIE_LEN];		// Total VIE length = MAX_VIE_LEN - -5
-	NDIS_802_11_VARIABLE_IEs	*pVIE = NULL;
-	HT_CAPABILITY_IE		HtCapability;
-	ADD_HT_INFO_IE		AddHtInfo;	// AP might use this additional ht info IE
-	UCHAR			HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
-	UCHAR			AddHtInfoLen;
-	UCHAR			NewExtChannelOffset = 0xff;
-
-
-	// NdisFillMemory(Ssid, MAX_LEN_OF_SSID, 0x00);
-	pFrame = (PFRAME_802_11) Elem->Msg;
-	// Init Variable IE structure
-	pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
-	pVIE->Length = 0;
-#ifdef DOT11_N_SUPPORT
-    RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
-	RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
-#endif // DOT11_N_SUPPORT //
-
-	if (PeerBeaconAndProbeRspSanity(pAd,
-								Elem->Msg,
-								Elem->MsgLen,
-								Elem->Channel,
-								Addr2,
-								Bssid,
-								(PCHAR)Ssid,
-								&SsidLen,
-								&BssType,
-								&BeaconPeriod,
-								&Channel,
-								&NewChannel,
-								&TimeStamp,
-								&CfParm,
-								&AtimWin,
-								&CapabilityInfo,
-								&Erp,
-								&DtimCount,
-								&DtimPeriod,
-								&BcastFlag,
-								&MessageToMe,
-								SupRate,
-								&SupRateLen,
-								ExtRate,
-								&ExtRateLen,
-								&CkipFlag,
-								&AironetCellPowerLimit,
-								&EdcaParm,
-								&QbssLoad,
-								&QosCapability,
-								&RalinkIe,
-								&HtCapabilityLen,
-								&PreNHtCapabilityLen,
-								&HtCapability,
-								&AddHtInfoLen,
-								&AddHtInfo,
-								&NewExtChannelOffset,
-								&LenVIE,
-								pVIE))
-	{
-		ULONG Idx;
-		CHAR Rssi = 0;
-
-		Idx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
-		if (Idx != BSS_NOT_FOUND)
-			Rssi = pAd->ScanTab.BssEntry[Idx].Rssi;
-
-		Rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
-
-
-#ifdef DOT11_N_SUPPORT
-		if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
-			HtCapabilityLen = SIZE_HT_CAP_IE;
-#endif // DOT11_N_SUPPORT //
-
-		Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, (PCHAR)Ssid, SsidLen, BssType, BeaconPeriod,
-					  &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,  &HtCapability,
-					 &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag,
-					 &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
-#ifdef DOT11_N_SUPPORT
-#ifdef DOT11N_DRAFT3
-		if (pAd->ChannelList[pAd->CommonCfg.ChannelListIdx].bEffectedChannel == TRUE)
-		{
-			UCHAR		RegClass;
-			PeerBeaconAndProbeRspSanity2(pAd, Elem->Msg, Elem->MsgLen, &RegClass);
-			TriEventTableSetEntry(pAd, &pAd->CommonCfg.TriggerEventTab, Bssid, &HtCapability, HtCapabilityLen, RegClass, Channel);
-		}
-#endif // DOT11N_DRAFT3 //
-#endif // DOT11_N_SUPPORT //
-		if (Idx != BSS_NOT_FOUND)
-		{
-			NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4);
-			NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
-			NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
-		}
-
-	}
-	// sanity check fail, ignored
-}
-
-/*
-	==========================================================================
-	Description:
-		When waiting joining the (I)BSS, beacon received from external
-	==========================================================================
- */
-VOID PeerBeaconAtJoinAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	UCHAR         Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
-	UCHAR         Ssid[MAX_LEN_OF_SSID], SsidLen, BssType, Channel, MessageToMe,
-				  DtimCount, DtimPeriod, BcastFlag, NewChannel;
-	LARGE_INTEGER TimeStamp;
-	USHORT        BeaconPeriod, AtimWin, CapabilityInfo;
-	CF_PARM       Cf;
-	BOOLEAN       TimerCancelled;
-	UCHAR         Erp;
-	UCHAR         SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR		  SupRateLen, ExtRateLen;
-	UCHAR         CkipFlag;
-	USHORT		  LenVIE;
-	UCHAR		  AironetCellPowerLimit;
-	EDCA_PARM       EdcaParm;
-	QBSS_LOAD_PARM  QbssLoad;
-	QOS_CAPABILITY_PARM QosCapability;
-	USHORT        Status;
-	UCHAR						VarIE[MAX_VIE_LEN];		// Total VIE length = MAX_VIE_LEN - -5
-	NDIS_802_11_VARIABLE_IEs	*pVIE = NULL;
-	ULONG           RalinkIe;
-	ULONG         Idx;
-	HT_CAPABILITY_IE		HtCapability;
-	ADD_HT_INFO_IE		AddHtInfo;	// AP might use this additional ht info IE
-	UCHAR				HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
-	UCHAR			AddHtInfoLen;
-	UCHAR			NewExtChannelOffset = 0xff;
-#ifdef DOT11_N_SUPPORT
-	UCHAR			CentralChannel;
-	BOOLEAN			bAllowNrate = FALSE;
-#endif // DOT11_N_SUPPORT //
-
-	// Init Variable IE structure
-	pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
-	pVIE->Length = 0;
-    RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
-	RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
-
-
-	if (PeerBeaconAndProbeRspSanity(pAd,
-								Elem->Msg,
-								Elem->MsgLen,
-								Elem->Channel,
-								Addr2,
-								Bssid,
-								(PCHAR)Ssid,
-								&SsidLen,
-								&BssType,
-								&BeaconPeriod,
-								&Channel,
-								&NewChannel,
-								&TimeStamp,
-								&Cf,
-								&AtimWin,
-								&CapabilityInfo,
-								&Erp,
-								&DtimCount,
-								&DtimPeriod,
-								&BcastFlag,
-								&MessageToMe,
-								SupRate,
-								&SupRateLen,
-								ExtRate,
-								&ExtRateLen,
-								&CkipFlag,
-								&AironetCellPowerLimit,
-								&EdcaParm,
-								&QbssLoad,
-								&QosCapability,
-								&RalinkIe,
-								&HtCapabilityLen,
-								&PreNHtCapabilityLen,
-								&HtCapability,
-								&AddHtInfoLen,
-								&AddHtInfo,
-								&NewExtChannelOffset,
-								&LenVIE,
-								pVIE))
-	{
-		// Disqualify 11b only adhoc when we are in 11g only adhoc mode
-		if ((BssType == BSS_ADHOC) && (pAd->CommonCfg.PhyMode == PHY_11G) && ((SupRateLen+ExtRateLen)< 12))
-			return;
-
-		// BEACON from desired BSS/IBSS found. We should be able to decide most
-		// BSS parameters here.
-		// Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION?
-		//    Do we need to receover back all parameters belonging to previous BSS?
-		// A. Should be not. There's no back-door recover to previous AP. It still need
-		//    a new JOIN-AUTH-ASSOC sequence.
-		if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Bssid))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n", Channel));
-			RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
-
-			// Update RSSI to prevent No signal display when cards first initialized
-			pAd->StaCfg.RssiSample.LastRssi0	= ConvertToRssi(pAd, Elem->Rssi0, RSSI_0);
-			pAd->StaCfg.RssiSample.LastRssi1	= ConvertToRssi(pAd, Elem->Rssi1, RSSI_1);
-			pAd->StaCfg.RssiSample.LastRssi2	= ConvertToRssi(pAd, Elem->Rssi2, RSSI_2);
-			pAd->StaCfg.RssiSample.AvgRssi0	= pAd->StaCfg.RssiSample.LastRssi0;
-			pAd->StaCfg.RssiSample.AvgRssi0X8	= pAd->StaCfg.RssiSample.AvgRssi0 << 3;
-			pAd->StaCfg.RssiSample.AvgRssi1	= pAd->StaCfg.RssiSample.LastRssi1;
-			pAd->StaCfg.RssiSample.AvgRssi1X8	= pAd->StaCfg.RssiSample.AvgRssi1 << 3;
-			pAd->StaCfg.RssiSample.AvgRssi2	= pAd->StaCfg.RssiSample.LastRssi2;
-			pAd->StaCfg.RssiSample.AvgRssi2X8	= pAd->StaCfg.RssiSample.AvgRssi2 << 3;
-
-			//
-			// We need to check if SSID only set to any, then we can record the current SSID.
-			// Otherwise will cause hidden SSID association failed.
-			//
-			if (pAd->MlmeAux.SsidLen == 0)
-			{
-				NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
-				pAd->MlmeAux.SsidLen = SsidLen;
-			}
-			else
-			{
-				Idx = BssSsidTableSearch(&pAd->ScanTab, Bssid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Channel);
-
-				if (Idx == BSS_NOT_FOUND)
-				{
-					CHAR Rssi = 0;
-					Rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
-					Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, (CHAR *) Ssid, SsidLen, BssType, BeaconPeriod,
-										&Cf, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,  &HtCapability,
-										&AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag,
-										&EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
-					if (Idx != BSS_NOT_FOUND)
-					{
-						NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4);
-						NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
-						NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
-						CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo;
-					}
-				}
-				else
-				{
-					//
-					// Multiple SSID case, used correct CapabilityInfo
-					//
-					CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo;
-				}
-			}
-			NdisMoveMemory(pAd->MlmeAux.Bssid, Bssid, MAC_ADDR_LEN);
-			pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
-			pAd->MlmeAux.BssType = BssType;
-			pAd->MlmeAux.BeaconPeriod = BeaconPeriod;
-			pAd->MlmeAux.Channel = Channel;
-			pAd->MlmeAux.AtimWin = AtimWin;
-			pAd->MlmeAux.CfpPeriod = Cf.CfpPeriod;
-			pAd->MlmeAux.CfpMaxDuration = Cf.CfpMaxDuration;
-			pAd->MlmeAux.APRalinkIe = RalinkIe;
-
-			// Copy AP's supported rate to MlmeAux for creating assoication request
-			// Also filter out not supported rate
-			pAd->MlmeAux.SupRateLen = SupRateLen;
-			NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen);
-			RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
-			pAd->MlmeAux.ExtRateLen = ExtRateLen;
-			NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen);
-			RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
-
-            NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, 16);
-
-
-#ifdef DOT11_N_SUPPORT
-			if (((pAd->StaCfg.WepStatus != Ndis802_11WEPEnabled) && (pAd->StaCfg.WepStatus != Ndis802_11Encryption2Enabled))
-				|| (pAd->CommonCfg.HT_DisallowTKIP == FALSE))
-			{
-				bAllowNrate = TRUE;
-			}
-
-			pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
-			pAd->MlmeAux.HtCapabilityLen = HtCapabilityLen;
-
-			RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
-			// filter out un-supported ht rates
-			if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) &&
-				((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (bAllowNrate)))
-			{
-				RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo, &AddHtInfo, SIZE_ADD_HT_INFO_IE);
-
-				// StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability
-				NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, HtCapability.MCSSet, 16);
-				pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
-				pAd->MlmeAux.HtCapabilityLen = SIZE_HT_CAP_IE;
-				pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
-				if (PreNHtCapabilityLen > 0)
-					pAd->StaActive.SupportedPhyInfo.bPreNHt = TRUE;
-				RTMPCheckHt(pAd, BSSID_WCID, &HtCapability, &AddHtInfo);
-				// Copy AP Parameter to StaActive.  This is also in LinkUp.
-				DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n",
-					pAd->StaActive.SupportedHtPhy.MpduDensity, pAd->StaActive.SupportedHtPhy.MaxRAmpduFactor, HtCapability.HtCapInfo.ChannelWidth));
-
-				if (AddHtInfoLen > 0)
-				{
-					CentralChannel = AddHtInfo.ControlChan;
-					// Check again the Bandwidth capability of this AP.
-					if ((AddHtInfo.ControlChan > 2)&& (AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (HtCapability.HtCapInfo.ChannelWidth == BW_40))
-					{
-						CentralChannel = AddHtInfo.ControlChan - 2;
-					}
-					else if ((AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (HtCapability.HtCapInfo.ChannelWidth == BW_40))
-					{
-						CentralChannel = AddHtInfo.ControlChan + 2;
-					}
-
-                    // Check Error .
-					if (pAd->MlmeAux.CentralChannel != CentralChannel)
-						DBGPRINT(RT_DEBUG_ERROR, ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n", CentralChannel, AddHtInfo.ControlChan, pAd->MlmeAux.CentralChannel));
-
-					DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d,  .\n", CentralChannel, AddHtInfo.ControlChan));
-
-				}
-
-			}
-			else
-#endif // DOT11_N_SUPPORT //
-			{
-				// To prevent error, let legacy AP must have same CentralChannel and Channel.
-				if ((HtCapabilityLen == 0) && (PreNHtCapabilityLen == 0))
-					pAd->MlmeAux.CentralChannel = pAd->MlmeAux.Channel;
-
-				pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
-				pAd->MlmeAux.NewExtChannelOffset = 0xff;
-				RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
-				pAd->MlmeAux.HtCapabilityLen = 0;
-				RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE);
-			}
-
-			RTMPUpdateMlmeRate(pAd);
-
-			// copy QOS related information
-			if ((pAd->CommonCfg.bWmmCapable)
-#ifdef DOT11_N_SUPPORT
-				 || (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
-#endif // DOT11_N_SUPPORT //
-				)
-			{
-				NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, &EdcaParm, sizeof(EDCA_PARM));
-				NdisMoveMemory(&pAd->MlmeAux.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM));
-				NdisMoveMemory(&pAd->MlmeAux.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM));
-			}
-			else
-			{
-				NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));
-				NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));
-				NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));
-			}
-
-			DBGPRINT(RT_DEBUG_TRACE, ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n",
-				pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen));
-
-			if (AironetCellPowerLimit != 0xFF)
-			{
-				//We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power
-				ChangeToCellPowerLimit(pAd, AironetCellPowerLimit);
-			}
-			else  //Used the default TX Power Percentage.
-				pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
-
-			pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
-			Status = MLME_SUCCESS;
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
-		}
-		// not to me BEACON, ignored
-	}
-	// sanity check fail, ignore this frame
-}
-
-/*
-	==========================================================================
-	Description:
-		receive BEACON from peer
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID PeerBeacon(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	UCHAR         Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
-	CHAR          Ssid[MAX_LEN_OF_SSID];
-	CF_PARM       CfParm;
-	UCHAR         SsidLen, MessageToMe=0, BssType, Channel, NewChannel, index=0;
-	UCHAR         DtimCount=0, DtimPeriod=0, BcastFlag=0;
-	USHORT        CapabilityInfo, AtimWin, BeaconPeriod;
-	LARGE_INTEGER TimeStamp;
-	USHORT        TbttNumToNextWakeUp;
-	UCHAR         Erp;
-	UCHAR         SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-	UCHAR		  SupRateLen, ExtRateLen;
-	UCHAR		  CkipFlag;
-	USHORT        LenVIE;
-	UCHAR		  AironetCellPowerLimit;
-	EDCA_PARM       EdcaParm;
-	QBSS_LOAD_PARM  QbssLoad;
-	QOS_CAPABILITY_PARM QosCapability;
-	ULONG           RalinkIe;
-	// New for WPA security suites
-	UCHAR						VarIE[MAX_VIE_LEN];		// Total VIE length = MAX_VIE_LEN - -5
-	NDIS_802_11_VARIABLE_IEs	*pVIE = NULL;
-	HT_CAPABILITY_IE		HtCapability;
-	ADD_HT_INFO_IE		AddHtInfo;	// AP might use this additional ht info IE
-	UCHAR			HtCapabilityLen, PreNHtCapabilityLen;
-	UCHAR			AddHtInfoLen;
-	UCHAR			NewExtChannelOffset = 0xff;
-
-
-#ifdef RALINK_ATE
-    if (ATE_ON(pAd))
-    {
-		return;
-    }
-#endif // RALINK_ATE //
-
-	if (!(INFRA_ON(pAd) || ADHOC_ON(pAd)
-		))
-		return;
-
-	// Init Variable IE structure
-	pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
-	pVIE->Length = 0;
-    RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
-	RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
-
-	if (PeerBeaconAndProbeRspSanity(pAd,
-								Elem->Msg,
-								Elem->MsgLen,
-								Elem->Channel,
-								Addr2,
-								Bssid,
-								Ssid,
-								&SsidLen,
-								&BssType,
-								&BeaconPeriod,
-								&Channel,
-								&NewChannel,
-								&TimeStamp,
-								&CfParm,
-								&AtimWin,
-								&CapabilityInfo,
-								&Erp,
-								&DtimCount,
-								&DtimPeriod,
-								&BcastFlag,
-								&MessageToMe,
-								SupRate,
-								&SupRateLen,
-								ExtRate,
-								&ExtRateLen,
-								&CkipFlag,
-								&AironetCellPowerLimit,
-								&EdcaParm,
-								&QbssLoad,
-								&QosCapability,
-								&RalinkIe,
-								&HtCapabilityLen,
-								&PreNHtCapabilityLen,
-								&HtCapability,
-								&AddHtInfoLen,
-								&AddHtInfo,
-								&NewExtChannelOffset,
-								&LenVIE,
-								pVIE))
-	{
-		BOOLEAN is_my_bssid, is_my_ssid;
-		ULONG   Bssidx, Now;
-		BSS_ENTRY *pBss;
-		CHAR		RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
-
-		is_my_bssid = MAC_ADDR_EQUAL(Bssid, pAd->CommonCfg.Bssid)? TRUE : FALSE;
-		is_my_ssid = SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)? TRUE:FALSE;
-
-
-		// ignore BEACON not for my SSID
-		if ((! is_my_ssid) && (! is_my_bssid))
-			return;
-
-		// It means STA waits disassoc completely from this AP, ignores this beacon.
-		if (pAd->Mlme.CntlMachine.CurrState == CNTL_WAIT_DISASSOC)
-			return;
-
-#ifdef DOT11_N_SUPPORT
-		// Copy Control channel for this BSSID.
-		if (AddHtInfoLen != 0)
-			Channel = AddHtInfo.ControlChan;
-
-		if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
-			HtCapabilityLen = SIZE_HT_CAP_IE;
-#endif // DOT11_N_SUPPORT //
-
-		//
-		// Housekeeping "SsidBssTab" table for later-on ROAMing usage.
-		//
-		Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
-		if (Bssidx == BSS_NOT_FOUND)
-		{
-			// discover new AP of this network, create BSS entry
-			Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
-						 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,
-						&HtCapability, &AddHtInfo,HtCapabilityLen,AddHtInfoLen,NewExtChannelOffset, Channel,
-						RealRssi, TimeStamp, CkipFlag, &EdcaParm, &QosCapability,
-						&QbssLoad, LenVIE, pVIE);
-			if (Bssidx == BSS_NOT_FOUND) // return if BSS table full
-				return;
-
-			NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, &Elem->Msg[24], 4);
-			NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
-			NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
-
-
-
-		}
-
-		if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel))
-		{
-			// Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
-			// In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
-			AsicSwitchChannel(pAd, 1, FALSE);
-			AsicLockChannel(pAd, 1);
-		    LinkDown(pAd, FALSE);
-			MlmeQueueInit(&pAd->Mlme.Queue);
-			BssTableInit(&pAd->ScanTab);
-		    RTMPusecDelay(1000000);		// use delay to prevent STA do reassoc
-
-			// channel sanity check
-			for (index = 0 ; index < pAd->ChannelListNum; index++)
-			{
-				if (pAd->ChannelList[index].Channel == NewChannel)
-				{
-					pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel;
-					pAd->CommonCfg.Channel = NewChannel;
-					AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-					AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-					DBGPRINT(RT_DEBUG_TRACE, ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel));
-					break;
-				}
-			}
-
-			if (index >= pAd->ChannelListNum)
-			{
-				DBGPRINT_ERR(("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum));
-			}
-		}
-
-		// if the ssid matched & bssid unmatched, we should select the bssid with large value.
-		// This might happened when two STA start at the same time
-		if ((! is_my_bssid) && ADHOC_ON(pAd))
-		{
-			INT	i;
-
-			// Add the safeguard against the mismatch of adhoc wep status
-			if (pAd->StaCfg.WepStatus != pAd->ScanTab.BssEntry[Bssidx].WepStatus)
-			{
-				return;
-			}
-
-			// collapse into the ADHOC network which has bigger BSSID value.
-			for (i = 0; i < 6; i++)
-			{
-				if (Bssid[i] > pAd->CommonCfg.Bssid[i])
-				{
-					DBGPRINT(RT_DEBUG_TRACE, ("SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n",
-						Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
-					AsicDisableSync(pAd);
-					COPY_MAC_ADDR(pAd->CommonCfg.Bssid, Bssid);
-					AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
-					MakeIbssBeacon(pAd);        // re-build BEACON frame
-					AsicEnableIbssSync(pAd);    // copy BEACON frame to on-chip memory
-					is_my_bssid = TRUE;
-					break;
-				}
-				else if (Bssid[i] < pAd->CommonCfg.Bssid[i])
-					break;
-			}
-		}
-
-
-		NdisGetSystemUpTime(&Now);
-		pBss = &pAd->ScanTab.BssEntry[Bssidx];
-		pBss->Rssi = RealRssi;       // lastest RSSI
-		pBss->LastBeaconRxTime = Now;   // last RX timestamp
-
-		//
-		// BEACON from my BSSID - either IBSS or INFRA network
-		//
-		if (is_my_bssid)
-		{
-			RXWI_STRUC	RxWI;
-
-			pAd->StaCfg.DtimCount = DtimCount;
-			pAd->StaCfg.DtimPeriod = DtimPeriod;
-			pAd->StaCfg.LastBeaconRxTime = Now;
-
-
-			RxWI.RSSI0 = Elem->Rssi0;
-			RxWI.RSSI1 = Elem->Rssi1;
-			RxWI.RSSI2 = Elem->Rssi2;
-
-			Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, &RxWI);
-			if (AironetCellPowerLimit != 0xFF)
-			{
-				//
-				// We get the Cisco (ccx) "TxPower Limit" required
-				// Changed to appropriate TxPower Limit for Ciso Compatible Extensions
-				//
-				ChangeToCellPowerLimit(pAd, AironetCellPowerLimit);
-			}
-			else
-			{
-				//
-				// AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist.
-				// Used the default TX Power Percentage, that set from UI.
-				//
-				pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
-			}
-
-			if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo)))
-			{
-				UCHAR			MaxSupportedRateIn500Kbps = 0;
-				UCHAR			idx;
-				MAC_TABLE_ENTRY *pEntry;
-
-				// supported rates array may not be sorted. sort it and find the maximum rate
-			    for (idx=0; idx<SupRateLen; idx++)
-				{
-			        if (MaxSupportedRateIn500Kbps < (SupRate[idx] & 0x7f))
-			            MaxSupportedRateIn500Kbps = SupRate[idx] & 0x7f;
-						}
-
-				for (idx=0; idx<ExtRateLen; idx++)
-			    {
-			        if (MaxSupportedRateIn500Kbps < (ExtRate[idx] & 0x7f))
-			            MaxSupportedRateIn500Kbps = ExtRate[idx] & 0x7f;
-					}
-
-				// look up the existing table
-				pEntry = MacTableLookup(pAd, Addr2);
-
-				// Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon.
-				// To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station.
-				if ((ADHOC_ON(pAd) && (Elem->Wcid == RESERVED_WCID)) ||
-					(pEntry && ((pEntry->LastBeaconRxTime + ADHOC_ENTRY_BEACON_LOST_TIME) < Now)))
-						{
-					if (pEntry == NULL)
-						// Another adhoc joining, add to our MAC table.
-						pEntry = MacTableInsertEntry(pAd, Addr2, BSS0, FALSE);
-
-					if (StaAddMacTableEntry(pAd,
-											pEntry,
-											MaxSupportedRateIn500Kbps,
-											&HtCapability,
-											HtCapabilityLen,
-											&AddHtInfo,
-											AddHtInfoLen,
-											CapabilityInfo) == FALSE)
-					{
-						DBGPRINT(RT_DEBUG_TRACE, ("ADHOC - Add Entry failed.\n"));
-						return;
-					}
-
-					if (pEntry &&
-						(Elem->Wcid == RESERVED_WCID))
-				{
-						idx = pAd->StaCfg.DefaultKeyId;
-						RTMP_STA_SECURITY_INFO_ADD(pAd, BSS0, idx, pEntry);
-				}
-				}
-
-				if (pEntry && pEntry->ValidAsCLI)
-					pEntry->LastBeaconRxTime = Now;
-
-				// At least another peer in this IBSS, declare MediaState as CONNECTED
-				if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-				{
-					OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
-
-					pAd->IndicateMediaState = NdisMediaStateConnected;
-					RTMP_IndicateMediaState(pAd);
-	                pAd->ExtraInfo = GENERAL_LINK_UP;
-					AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
-
-					// 2003/03/12 - john
-					// Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that
-					// "site survey" result should always include the current connected network.
-					//
-					Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
-					if (Bssidx == BSS_NOT_FOUND)
-					{
-						Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
-									&CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability,
-									&AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, RealRssi, TimeStamp, 0,
-									&EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
-					}
-					DBGPRINT(RT_DEBUG_TRACE, ("ADHOC  fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
-				}
-			}
-
-			if (INFRA_ON(pAd))
-			{
-				BOOLEAN bUseShortSlot, bUseBGProtection;
-
-				// decide to use/change to -
-				//      1. long slot (20 us) or short slot (9 us) time
-				//      2. turn on/off RTS/CTS and/or CTS-to-self protection
-				//      3. short preamble
-
-				//bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo);
-				bUseShortSlot = CAP_IS_SHORT_SLOT(CapabilityInfo);
-				if (bUseShortSlot != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))
-					AsicSetSlotTime(pAd, bUseShortSlot);
-
-				bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) ||    // always use
-								   ((pAd->CommonCfg.UseBGProtection == 0) && ERP_IS_USE_PROTECTION(Erp));
-
-				if (pAd->CommonCfg.Channel > 14) // always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP
-					bUseBGProtection = FALSE;
-
-				if (bUseBGProtection != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
-				{
-					if (bUseBGProtection)
-					{
-						OPSTATUS_SET_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
-						AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),FALSE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
-					}
-					else
-					{
-						OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
-						AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),TRUE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
-					}
-
-					DBGPRINT(RT_DEBUG_WARN, ("SYNC - AP changed B/G protection to %d\n", bUseBGProtection));
-				}
-
-#ifdef DOT11_N_SUPPORT
-				// check Ht protection mode. and adhere to the Non-GF device indication by AP.
-				if ((AddHtInfoLen != 0) &&
-					((AddHtInfo.AddHtInfo2.OperaionMode != pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode) ||
-					(AddHtInfo.AddHtInfo2.NonGfPresent != pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent)))
-				{
-					pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent = AddHtInfo.AddHtInfo2.NonGfPresent;
-					pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode = AddHtInfo.AddHtInfo2.OperaionMode;
-					if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
-				{
-						AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
-					}
-					else
-						AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
-
-					DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP changed N OperaionMode to %d\n", pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode));
-				}
-#endif // DOT11_N_SUPPORT //
-
-				if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED) &&
-					ERP_IS_USE_BARKER_PREAMBLE(Erp))
-				{
-					MlmeSetTxPreamble(pAd, Rt802_11PreambleLong);
-					DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP forced to use LONG preamble\n"));
-				}
-
-				if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)    &&
-					(EdcaParm.bValid == TRUE)                          &&
-					(EdcaParm.EdcaUpdateCount != pAd->CommonCfg.APEdcaParm.EdcaUpdateCount))
-				{
-					DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP change EDCA parameters(from %d to %d)\n",
-						pAd->CommonCfg.APEdcaParm.EdcaUpdateCount,
-						EdcaParm.EdcaUpdateCount));
-					AsicSetEdcaParm(pAd, &EdcaParm);
-				}
-
-				// copy QOS related information
-				NdisMoveMemory(&pAd->CommonCfg.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM));
-				NdisMoveMemory(&pAd->CommonCfg.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM));
-			}
-
-			// only INFRASTRUCTURE mode support power-saving feature
-			if ((INFRA_ON(pAd) && (pAd->StaCfg.Psm == PWR_SAVE)) || (pAd->CommonCfg.bAPSDForcePowerSave))
-			{
-				UCHAR FreeNumber;
-				//  1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL
-				//  2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE
-				//  3. we have outgoing frames in TxRing or MgmtRing, better stay AWAKE
-				//  4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE
-				//  5. otherwise, put PHY back to sleep to save battery.
-				if (MessageToMe)
-				{
-#ifdef RTMP_MAC_PCI
-					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
-					{
-						// Restore to correct BBP R3 value
-						if (pAd->Antenna.field.RxPath > 1)
-						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
-						// Turn clk to 80Mhz.
-					}
-#endif // RTMP_MAC_PCI //
-					if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable &&
-						pAd->CommonCfg.bAPSDAC_BE && pAd->CommonCfg.bAPSDAC_BK && pAd->CommonCfg.bAPSDAC_VI && pAd->CommonCfg.bAPSDAC_VO)
-					{
-						pAd->CommonCfg.bNeedSendTriggerFrame = TRUE;
-					}
-					else
-						RTMP_PS_POLL_ENQUEUE(pAd);
-				}
-				else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM))
-				{
-#ifdef RTMP_MAC_PCI
-					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
-					{
-						if (pAd->Antenna.field.RxPath > 1)
-						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
-					}
-#endif // RTMP_MAC_PCI //
-				}
-				else if ((pAd->TxSwQueue[QID_AC_BK].Number != 0)													||
-						(pAd->TxSwQueue[QID_AC_BE].Number != 0)														||
-						(pAd->TxSwQueue[QID_AC_VI].Number != 0)														||
-						(pAd->TxSwQueue[QID_AC_VO].Number != 0)														||
-						(RTMPFreeTXDRequest(pAd, QID_AC_BK, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS)	||
-						(RTMPFreeTXDRequest(pAd, QID_AC_BE, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS)	||
-						(RTMPFreeTXDRequest(pAd, QID_AC_VI, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS)	||
-						(RTMPFreeTXDRequest(pAd, QID_AC_VO, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS)	||
-						(RTMPFreeTXDRequest(pAd, QID_MGMT, MGMT_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS))
-				{
-					// TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme
-					// can we cheat here (i.e. just check MGMT & AC_BE) for better performance?
-#ifdef RTMP_MAC_PCI
-					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
-					{
-						if (pAd->Antenna.field.RxPath > 1)
-						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
-					}
-#endif // RTMP_MAC_PCI //
-				}
-				else
-				{
-					if ((pAd->CommonCfg.bACMAPSDTr[QID_AC_VO]) ||
-						(pAd->CommonCfg.bACMAPSDTr[QID_AC_VI]) ||
-						(pAd->CommonCfg.bACMAPSDTr[QID_AC_BK]) ||
-						(pAd->CommonCfg.bACMAPSDTr[QID_AC_BE]))
-					{
-						/*
-							WMM Spec v1.0 3.6.2.4,
-							The WMM STA shall remain awake until it receives a
-							QoS Data or Null frame addressed to it, with the
-							EOSP subfield in QoS Control field set to 1.
-
-							So we can not sleep here or we will suffer a case:
-
-							PS Management Frame -->
-							Trigger frame -->
-							Beacon (TIM=0) (Beacon is closer to Trig frame) -->
-							Station goes to sleep -->
-							AP delivery queued UAPSD packets -->
-							Station can NOT receive the reply
-
-							Maybe we need a timeout timer to avoid that we do
-							NOT receive the EOSP frame.
-
-							We can not use More Data to check if SP is ended
-							due to MaxSPLength.
-						*/
-					}
-					else
-					{
-						USHORT NextDtim = DtimCount;
-
-
-						if (NextDtim == 0)
-							NextDtim = DtimPeriod;
-
-						TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
-						if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
-							TbttNumToNextWakeUp = NextDtim;
-
-						if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-						{
-							// Set a flag to go to sleep . Then after parse this RxDoneInterrupt, will go to sleep mode.
-							pAd->ThisTbttNumToNextWakeUp = TbttNumToNextWakeUp;
-		                                        AsicSleepThenAutoWakeup(pAd, pAd->ThisTbttNumToNextWakeUp);
-
-						}
-					}
-				}
-			}
-		}
-		// not my BSSID, ignore it
-	}
-	// sanity check fail, ignore this frame
-}
-
-/*
-	==========================================================================
-	Description:
-		Receive PROBE REQ from remote peer when operating in IBSS mode
-	==========================================================================
- */
-VOID PeerProbeReqAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	UCHAR         Addr2[MAC_ADDR_LEN];
-	CHAR          Ssid[MAX_LEN_OF_SSID];
-	UCHAR         SsidLen;
-#ifdef DOT11_N_SUPPORT
-	UCHAR		  HtLen, AddHtLen, NewExtLen;
-#endif // DOT11_N_SUPPORT //
-	HEADER_802_11 ProbeRspHdr;
-	NDIS_STATUS   NStatus;
-	PUCHAR        pOutBuffer = NULL;
-	ULONG         FrameLen = 0;
-	LARGE_INTEGER FakeTimestamp;
-	UCHAR         DsLen = 1, IbssLen = 2;
-	UCHAR         LocalErpIe[3] = {IE_ERP, 1, 0};
-	BOOLEAN       Privacy;
-	USHORT        CapabilityInfo;
-	UCHAR		  RSNIe = IE_WPA;
-
-	if (! ADHOC_ON(pAd))
-		return;
-
-	if (PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen))
-	{
-		if ((SsidLen == 0) || SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
-		{
-			// allocate and send out ProbeRsp frame
-			NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-			if (NStatus != NDIS_STATUS_SUCCESS)
-				return;
-
-			//pAd->StaCfg.AtimWin = 0;  // ??????
-
-			Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
-					  (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
-					  (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
-			CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
-
-			MakeOutgoingFrame(pOutBuffer,                   &FrameLen,
-							  sizeof(HEADER_802_11),        &ProbeRspHdr,
-							  TIMESTAMP_LEN,                &FakeTimestamp,
-							  2,                            &pAd->CommonCfg.BeaconPeriod,
-							  2,                            &CapabilityInfo,
-							  1,                            &SsidIe,
-							  1,                            &pAd->CommonCfg.SsidLen,
-							  pAd->CommonCfg.SsidLen,       pAd->CommonCfg.Ssid,
-							  1,                            &SupRateIe,
-							  1,                            &pAd->StaActive.SupRateLen,
-							  pAd->StaActive.SupRateLen,    pAd->StaActive.SupRate,
-							  1,                            &DsIe,
-							  1,                            &DsLen,
-							  1,                            &pAd->CommonCfg.Channel,
-							  1,                            &IbssIe,
-							  1,                            &IbssLen,
-							  2,                            &pAd->StaActive.AtimWin,
-							  END_OF_ARGS);
-
-			if (pAd->StaActive.ExtRateLen)
-			{
-				ULONG tmp;
-				MakeOutgoingFrame(pOutBuffer + FrameLen,        &tmp,
-								  3,                            LocalErpIe,
-								  1,                            &ExtRateIe,
-								  1,                            &pAd->StaActive.ExtRateLen,
-								  pAd->StaActive.ExtRateLen,    &pAd->StaActive.ExtRate,
-								  END_OF_ARGS);
-				FrameLen += tmp;
-			}
-
-			// If adhoc secruity is set for WPA-None, append the cipher suite IE
-			if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
-			{
-				ULONG tmp;
-				MakeOutgoingFrame(pOutBuffer + FrameLen,		&tmp,
-									1,                              &RSNIe,
-									1,				&pAd->StaCfg.RSNIE_Len,
-									pAd->StaCfg.RSNIE_Len,		pAd->StaCfg.RSN_IE,
-									END_OF_ARGS);
-				FrameLen += tmp;
-			}
-#ifdef DOT11_N_SUPPORT
-			if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
-			{
-				ULONG TmpLen;
-				UCHAR	BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
-				HtLen = sizeof(pAd->CommonCfg.HtCapability);
-				AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo);
-				NewExtLen = 1;
-				//New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame
-				if (pAd->bBroadComHT == TRUE)
-				{
-					MakeOutgoingFrame(pOutBuffer + FrameLen,            &TmpLen,
-								  1,                                &WpaIe,
-								  4,                                &BROADCOM[0],
-								 pAd->MlmeAux.HtCapabilityLen,          &pAd->MlmeAux.HtCapability,
-								  END_OF_ARGS);
-				}
-				else
-				{
-				MakeOutgoingFrame(pOutBuffer + FrameLen,            &TmpLen,
-								  1,                                &HtCapIe,
-								  1,                                &HtLen,
-								 sizeof(HT_CAPABILITY_IE),          &pAd->CommonCfg.HtCapability,
-								  1,                                &AddHtInfoIe,
-								  1,                                &AddHtLen,
-								 sizeof(ADD_HT_INFO_IE),          &pAd->CommonCfg.AddHTInfo,
-								  1,                                &NewExtChanIe,
-								  1,                                &NewExtLen,
-								 sizeof(NEW_EXT_CHAN_IE),          &pAd->CommonCfg.NewExtChanOffset,
-								  END_OF_ARGS);
-				}
-				FrameLen += TmpLen;
-			}
-#endif // DOT11_N_SUPPORT //
-			MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-			MlmeFreeMemory(pAd, pOutBuffer);
-		}
-	}
-}
-
-VOID BeaconTimeoutAtJoinAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	USHORT Status;
-	DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeoutAtJoinAction\n"));
-	pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
-	Status = MLME_REJ_TIMEOUT;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
-}
-
-/*
-	==========================================================================
-	Description:
-		Scan timeout procedure. basically add channel index by 1 and rescan
-	==========================================================================
- */
-VOID ScanTimeoutAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	pAd->MlmeAux.Channel = NextChannel(pAd, pAd->MlmeAux.Channel);
-
-	// Only one channel scanned for CISCO beacon request
-	if ((pAd->MlmeAux.ScanType == SCAN_CISCO_ACTIVE) ||
-		(pAd->MlmeAux.ScanType == SCAN_CISCO_PASSIVE) ||
-		(pAd->MlmeAux.ScanType == SCAN_CISCO_NOISE) ||
-		(pAd->MlmeAux.ScanType == SCAN_CISCO_CHANNEL_LOAD))
-		pAd->MlmeAux.Channel = 0;
-
-	// this routine will stop if pAd->MlmeAux.Channel == 0
-	ScanNextChannel(pAd);
-}
-
-/*
-	==========================================================================
-	Description:
-	==========================================================================
- */
-VOID InvalidStateWhenScan(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	USHORT Status;
-	DBGPRINT(RT_DEBUG_TRACE, ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
-	pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
-	Status = MLME_STATE_MACHINE_REJECT;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
-}
-
-/*
-	==========================================================================
-	Description:
-	==========================================================================
- */
-VOID InvalidStateWhenJoin(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	USHORT Status;
-	DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenJoin(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
-	pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
-	Status = MLME_STATE_MACHINE_REJECT;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
-}
-
-/*
-	==========================================================================
-	Description:
-	==========================================================================
- */
-VOID InvalidStateWhenStart(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	USHORT Status;
-	DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenStart(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
-	pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
-	Status = MLME_STATE_MACHINE_REJECT;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID EnqueuePsPoll(
-	IN PRTMP_ADAPTER pAd)
-{
-#ifdef RALINK_ATE
-    if (ATE_ON(pAd))
-    {
-		return;
-    }
-#endif // RALINK_ATE //
-
-
-	if (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeLegacy_PSP)
-	pAd->PsPollFrame.FC.PwrMgmt = PWR_SAVE;
-	MiniportMMRequest(pAd, 0, (PUCHAR)&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
-}
-
-
-/*
-	==========================================================================
-	Description:
-	==========================================================================
- */
-VOID EnqueueProbeRequest(
-	IN PRTMP_ADAPTER pAd)
-{
-	NDIS_STATUS     NState;
-	PUCHAR          pOutBuffer;
-	ULONG           FrameLen = 0;
-	HEADER_802_11   Hdr80211;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("force out a ProbeRequest ...\n"));
-
-	NState = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-	if (NState == NDIS_STATUS_SUCCESS)
-	{
-		MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
-
-		// this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse
-		MakeOutgoingFrame(pOutBuffer,                     &FrameLen,
-						  sizeof(HEADER_802_11),          &Hdr80211,
-						  1,                              &SsidIe,
-						  1,                              &pAd->CommonCfg.SsidLen,
-						  pAd->CommonCfg.SsidLen,		  pAd->CommonCfg.Ssid,
-						  1,                              &SupRateIe,
-						  1,                              &pAd->StaActive.SupRateLen,
-						  pAd->StaActive.SupRateLen,      pAd->StaActive.SupRate,
-						  END_OF_ARGS);
-		MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-		MlmeFreeMemory(pAd, pOutBuffer);
-	}
-
-}
-
-#ifdef DOT11_N_SUPPORT
-#ifdef DOT11N_DRAFT3
-VOID BuildEffectedChannelList(
-	IN PRTMP_ADAPTER pAd)
-{
-	UCHAR		EChannel[11];
-	UCHAR		i, j, k;
-	UCHAR		UpperChannel = 0, LowerChannel = 0;
-
-	RTMPZeroMemory(EChannel, 11);
-	i = 0;
-	// Find upper channel and lower channel.
-	if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
-	{
-		UpperChannel = pAd->CommonCfg.Channel;
-		LowerChannel = pAd->CommonCfg.CentralChannel;
-	}
-	else if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
-	{
-		UpperChannel = pAd->CommonCfg.CentralChannel;
-		LowerChannel = pAd->CommonCfg.Channel;
-	}
-	else
-	{
-		return;
-	}
-
-	// Record channels that is below lower channel..
-	if (LowerChannel > 1)
-	{
-		EChannel[0] = LowerChannel - 1;
-		i = 1;
-		if (LowerChannel > 2)
-		{
-			EChannel[1] = LowerChannel - 2;
-			i = 2;
-			if (LowerChannel > 3)
-			{
-				EChannel[2] = LowerChannel - 3;
-				i = 3;
-			}
-		}
-	}
-	// Record channels that is between  lower channel and upper channel.
-	for (k = LowerChannel;k < UpperChannel;k++)
-	{
-		EChannel[i] = k;
-		i++;
-	}
-	// Record channels that is above upper channel..
-	if (LowerChannel < 11)
-	{
-		EChannel[i] = UpperChannel + 1;
-		i++;
-		if (LowerChannel < 10)
-		{
-			EChannel[i] = LowerChannel + 2;
-			i++;
-			if (LowerChannel < 9)
-			{
-				EChannel[i] = LowerChannel + 3;
-				i++;
-			}
-		}
-	}
-	//
-	for (j = 0;j < i;j++)
-	{
-		for (k = 0;k < pAd->ChannelListNum;k++)
-		{
-			if (pAd->ChannelList[k].Channel == EChannel[j])
-			{
-				pAd->ChannelList[k].bEffectedChannel = TRUE;
-				DBGPRINT(RT_DEBUG_TRACE,(" EffectedChannel( =%d)\n", EChannel[j]));
-				break;
-			}
-		}
-	}
-}
-#endif // DOT11N_DRAFT3 //
-#endif // DOT11_N_SUPPORT //
-
-BOOLEAN ScanRunning(
-		IN PRTMP_ADAPTER pAd)
-{
-	return (pAd->Mlme.SyncMachine.CurrState == SCAN_LISTEN) ? TRUE : FALSE;
-}
diff --git a/drivers/staging/rt3090/sta/wpa.c b/drivers/staging/rt3090/sta/wpa.c
deleted file mode 100644
index 2dbdba5..0000000
--- a/drivers/staging/rt3090/sta/wpa.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	wpa.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Jan	Lee		03-07-22		Initial
-	Paul Lin	03-11-28		Modify for supplicant
-*/
-
-#include "../rt_config.h"
-
-
-void inc_byte_array(UCHAR *counter, int len);
-
-/*
-	========================================================================
-
-	Routine Description:
-		Process MIC error indication and record MIC error timer.
-
-	Arguments:
-		pAd	Pointer to our adapter
-		pWpaKey			Pointer to the WPA key structure
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPReportMicError(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PCIPHER_KEY	pWpaKey)
-{
-	ULONG	Now;
-    UCHAR   unicastKey = (pWpaKey->Type == PAIRWISE_KEY ? 1:0);
-
-	// Record Last MIC error time and count
-	NdisGetSystemUpTime(&Now);
-	if (pAd->StaCfg.MicErrCnt == 0)
-	{
-		pAd->StaCfg.MicErrCnt++;
-		pAd->StaCfg.LastMicErrorTime = Now;
-        NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
-	}
-	else if (pAd->StaCfg.MicErrCnt == 1)
-	{
-		if ((pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ)) < Now)
-		{
-			// Update Last MIC error time, this did not violate two MIC errors within 60 seconds
-			pAd->StaCfg.LastMicErrorTime = Now;
-		}
-		else
-		{
-
-			if (pAd->CommonCfg.bWirelessEvent)
-				RTMPSendWirelessEvent(pAd, IW_COUNTER_MEASURES_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-
-			pAd->StaCfg.LastMicErrorTime = Now;
-			// Violate MIC error counts, MIC countermeasures kicks in
-			pAd->StaCfg.MicErrCnt++;
-			// We shall block all reception
-			// We shall clean all Tx ring and disassoicate from AP after next EAPOL frame
-			//
-			// No necessary to clean all Tx ring, on RTMPHardTransmit will stop sending non-802.1X EAPOL packets
-			// if pAd->StaCfg.MicErrCnt greater than 2.
-			//
-			// RTMPRingCleanUp(pAd, QID_AC_BK);
-			// RTMPRingCleanUp(pAd, QID_AC_BE);
-			// RTMPRingCleanUp(pAd, QID_AC_VI);
-			// RTMPRingCleanUp(pAd, QID_AC_VO);
-			// RTMPRingCleanUp(pAd, QID_HCCA);
-		}
-	}
-	else
-	{
-		// MIC error count >= 2
-		// This should not happen
-		;
-	}
-    MlmeEnqueue(pAd,
-				MLME_CNTL_STATE_MACHINE,
-				OID_802_11_MIC_FAILURE_REPORT_FRAME,
-				1,
-				&unicastKey);
-
-    if (pAd->StaCfg.MicErrCnt == 2)
-    {
-        RTMPSetTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, 100);
-    }
-}
-
-
-#ifdef WPA_SUPPLICANT_SUPPORT
-#define	LENGTH_EAP_H    4
-// If the received frame is EAP-Packet ,find out its EAP-Code (Request(0x01), Response(0x02), Success(0x03), Failure(0x04)).
-INT	    WpaCheckEapCode(
-	IN  PRTMP_ADAPTER		pAd,
-	IN  PUCHAR				pFrame,
-	IN  USHORT				FrameLen,
-	IN  USHORT				OffSet)
-{
-
-	PUCHAR	pData;
-	INT	result = 0;
-
-	if( FrameLen < OffSet + LENGTH_EAPOL_H + LENGTH_EAP_H )
-		return result;
-
-	pData = pFrame + OffSet; // skip offset bytes
-
-	if(*(pData+1) == EAPPacket)	// 802.1x header - Packet Type
-	{
-		 result = *(pData+4);		// EAP header - Code
-	}
-
-	return result;
-}
-
-VOID    WpaSendMicFailureToWpaSupplicant(
-    IN  PRTMP_ADAPTER    pAd,
-    IN  BOOLEAN          bUnicast)
-{
-	char custom[IW_CUSTOM_MAX] = {0};
-
-	sprintf(custom, "MLME-MICHAELMICFAILURE.indication");
-	if(bUnicast)
-		sprintf(custom, "%s unicast", custom);
-
-	RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, -1, NULL, (PUCHAR)custom, strlen(custom));
-
-	return;
-}
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-VOID	WpaMicFailureReportFrame(
-	IN  PRTMP_ADAPTER   pAd,
-	IN MLME_QUEUE_ELEM *Elem)
-{
-	PUCHAR              pOutBuffer = NULL;
-	UCHAR               Header802_3[14];
-	ULONG               FrameLen = 0;
-	EAPOL_PACKET        Packet;
-	UCHAR               Mic[16];
-    BOOLEAN             bUnicast;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame ----->\n"));
-
-    bUnicast = (Elem->Msg[0] == 1 ? TRUE:FALSE);
-	pAd->Sequence = ((pAd->Sequence) + 1) & (MAX_SEQ_NUMBER);
-
-	// init 802.3 header and Fill Packet
-	MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
-
-	NdisZeroMemory(&Packet, sizeof(Packet));
-	Packet.ProVer	= EAPOL_VER;
-	Packet.ProType	= EAPOLKey;
-
-	Packet.KeyDesc.Type = WPA1_KEY_DESC;
-
-    // Request field presented
-    Packet.KeyDesc.KeyInfo.Request = 1;
-
-	if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
-	{
-		Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
-	}
-	else	  // TKIP
-	{
-		Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
-	}
-
-    Packet.KeyDesc.KeyInfo.KeyType = (bUnicast ? PAIRWISEKEY : GROUPKEY);
-
-	// KeyMic field presented
-	Packet.KeyDesc.KeyInfo.KeyMic  = 1;
-
-    // Error field presented
-	Packet.KeyDesc.KeyInfo.Error  = 1;
-
-	// Update packet length after decide Key data payload
-	SET_UINT16_TO_ARRARY(Packet.Body_Len, LEN_EAPOL_KEY_MSG)
-
-	// Key Replay Count
-	NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
-    inc_byte_array(pAd->StaCfg.ReplayCounter, 8);
-
-	// Convert to little-endian format.
-	*((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
-
-
-	MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer);  // allocate memory
-	if(pOutBuffer == NULL)
-	{
-		return;
-	}
-
-	// Prepare EAPOL frame for MIC calculation
-	// Be careful, only EAPOL frame is counted for MIC calculation
-	MakeOutgoingFrame(pOutBuffer,               &FrameLen,
-		              CONV_ARRARY_TO_UINT16(Packet.Body_Len) + 4,   &Packet,
-		              END_OF_ARGS);
-
-	// Prepare and Fill MIC value
-	NdisZeroMemory(Mic, sizeof(Mic));
-	if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
-	{	// AES
-        UCHAR digest[20] = {0};
-		HMAC_SHA1(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE);
-		NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
-	}
-	else
-	{	// TKIP
-		HMAC_MD5(pAd->StaCfg.PTK,  LEN_EAP_MICK, pOutBuffer, FrameLen, Mic, MD5_DIGEST_SIZE);
-	}
-	NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
-
-	// copy frame to Tx ring and send MIC failure report frame to authenticator
-	RTMPToWirelessSta(pAd, &pAd->MacTab.Content[BSSID_WCID],
-					  Header802_3, LENGTH_802_3,
-					  (PUCHAR)&Packet,
-					  CONV_ARRARY_TO_UINT16(Packet.Body_Len) + 4, FALSE);
-
-	MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame <-----\n"));
-}
-
-/** from wpa_supplicant
- * inc_byte_array - Increment arbitrary length byte array by one
- * @counter: Pointer to byte array
- * @len: Length of the counter in bytes
- *
- * This function increments the last byte of the counter by one and continues
- * rolling over to more significant bytes if the byte was incremented from
- * 0xff to 0x00.
- */
-void inc_byte_array(UCHAR *counter, int len)
-{
-	int pos = len - 1;
-	while (pos >= 0) {
-		counter[pos]++;
-		if (counter[pos] != 0)
-			break;
-		pos--;
-	}
-}
-
-VOID WpaDisassocApAndBlockAssoc(
-    IN PVOID SystemSpecific1,
-    IN PVOID FunctionContext,
-    IN PVOID SystemSpecific2,
-    IN PVOID SystemSpecific3)
-{
-    RTMP_ADAPTER                *pAd = (PRTMP_ADAPTER)FunctionContext;
-    MLME_DISASSOC_REQ_STRUCT    DisassocReq;
-
-	// disassoc from current AP first
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPReportMicError - disassociate with current AP after sending second continuous EAPOL frame\n"));
-	DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_MIC_FAILURE);
-	MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
-
-	pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
-	pAd->StaCfg.bBlockAssoc = TRUE;
-}
-
-VOID WpaStaPairwiseKeySetting(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	PCIPHER_KEY pSharedKey;
-	PMAC_TABLE_ENTRY pEntry;
-
-	pEntry = &pAd->MacTab.Content[BSSID_WCID];
-
-	// Pairwise key shall use key#0
-	pSharedKey = &pAd->SharedKey[BSS0][0];
-
-	NdisMoveMemory(pAd->StaCfg.PTK, pEntry->PTK, LEN_PTK);
-
-	// Prepare pair-wise key information into shared key table
-	NdisZeroMemory(pSharedKey, sizeof(CIPHER_KEY));
-	pSharedKey->KeyLen = LEN_TKIP_EK;
-    NdisMoveMemory(pSharedKey->Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
-	NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
-	NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
-
-	// Decide its ChiperAlg
-	if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
-		pSharedKey->CipherAlg = CIPHER_TKIP;
-	else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
-		pSharedKey->CipherAlg = CIPHER_AES;
-	else
-		pSharedKey->CipherAlg = CIPHER_NONE;
-
-	// Update these related information to MAC_TABLE_ENTRY
-	NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
-	NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
-	NdisMoveMemory(pEntry->PairwiseKey.TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
-	pEntry->PairwiseKey.CipherAlg = pSharedKey->CipherAlg;
-
-	// Update pairwise key information to ASIC Shared Key Table
-	AsicAddSharedKeyEntry(pAd,
-						  BSS0,
-						  0,
-						  pSharedKey->CipherAlg,
-						  pSharedKey->Key,
-						  pSharedKey->TxMic,
-						  pSharedKey->RxMic);
-
-	// Update ASIC WCID attribute table and IVEIV table
-	RTMPAddWcidAttributeEntry(pAd,
-							  BSS0,
-							  0,
-							  pSharedKey->CipherAlg,
-							  pEntry);
-	STA_PORT_SECURED(pAd);
-	pAd->IndicateMediaState = NdisMediaStateConnected;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("%s : AID(%d) port secured\n", __FUNCTION__, pEntry->Aid));
-
-}
-
-VOID WpaStaGroupKeySetting(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	PCIPHER_KEY		pSharedKey;
-
-	pSharedKey = &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId];
-
-	// Prepare pair-wise key information into shared key table
-	NdisZeroMemory(pSharedKey, sizeof(CIPHER_KEY));
-	pSharedKey->KeyLen = LEN_TKIP_EK;
-	NdisMoveMemory(pSharedKey->Key, pAd->StaCfg.GTK, LEN_TKIP_EK);
-	NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.GTK[16], LEN_TKIP_RXMICK);
-	NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.GTK[24], LEN_TKIP_TXMICK);
-
-	// Update Shared Key CipherAlg
-	pSharedKey->CipherAlg = CIPHER_NONE;
-	if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
-		pSharedKey->CipherAlg = CIPHER_TKIP;
-	else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
-		pSharedKey->CipherAlg = CIPHER_AES;
-	else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
-		pSharedKey->CipherAlg = CIPHER_WEP64;
-	else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
-		pSharedKey->CipherAlg = CIPHER_WEP128;
-
-	// Update group key information to ASIC Shared Key Table
-	AsicAddSharedKeyEntry(pAd,
-						  BSS0,
-						  pAd->StaCfg.DefaultKeyId,
-						  pSharedKey->CipherAlg,
-						  pSharedKey->Key,
-						  pSharedKey->TxMic,
-						  pSharedKey->RxMic);
-
-	// Update ASIC WCID attribute table and IVEIV table
-	RTMPAddWcidAttributeEntry(pAd,
-							  BSS0,
-							  pAd->StaCfg.DefaultKeyId,
-							  pSharedKey->CipherAlg,
-							  NULL);
-
-}
diff --git a/drivers/staging/rt3090/sta_ioctl.c b/drivers/staging/rt3090/sta_ioctl.c
deleted file mode 100644
index b8ab84a..0000000
--- a/drivers/staging/rt3090/sta_ioctl.c
+++ /dev/null
@@ -1,7557 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    sta_ioctl.c
-
-    Abstract:
-    IOCTL related subroutines
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-    Rory Chen   01-03-2003    created
-	Rory Chen   02-14-2005    modify to support RT61
-*/
-
-#include	"rt_config.h"
-
-#ifdef DBG
-extern ULONG    RTDebugLevel;
-#endif
-
-#define NR_WEP_KEYS				4
-#define WEP_SMALL_KEY_LEN			(40/8)
-#define WEP_LARGE_KEY_LEN			(104/8)
-
-#define GROUP_KEY_NO                4
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
-#define IWE_STREAM_ADD_EVENT(_A, _B, _C, _D, _E)		iwe_stream_add_event(_A, _B, _C, _D, _E)
-#define IWE_STREAM_ADD_POINT(_A, _B, _C, _D, _E)		iwe_stream_add_point(_A, _B, _C, _D, _E)
-#define IWE_STREAM_ADD_VALUE(_A, _B, _C, _D, _E, _F)	iwe_stream_add_value(_A, _B, _C, _D, _E, _F)
-#else
-#define IWE_STREAM_ADD_EVENT(_A, _B, _C, _D, _E)		iwe_stream_add_event(_B, _C, _D, _E)
-#define IWE_STREAM_ADD_POINT(_A, _B, _C, _D, _E)		iwe_stream_add_point(_B, _C, _D, _E)
-#define IWE_STREAM_ADD_VALUE(_A, _B, _C, _D, _E, _F)	iwe_stream_add_value(_B, _C, _D, _E, _F)
-#endif
-
-extern UCHAR    CipherWpa2Template[];
-
-typedef struct PACKED _RT_VERSION_INFO{
-    UCHAR       DriverVersionW;
-    UCHAR       DriverVersionX;
-    UCHAR       DriverVersionY;
-    UCHAR       DriverVersionZ;
-    UINT        DriverBuildYear;
-    UINT        DriverBuildMonth;
-    UINT        DriverBuildDay;
-} RT_VERSION_INFO, *PRT_VERSION_INFO;
-
-struct iw_priv_args privtab[] = {
-{ RTPRIV_IOCTL_SET,
-  IW_PRIV_TYPE_CHAR | 1024, 0,
-  "set"},
-
-{ RTPRIV_IOCTL_SHOW, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
-  ""},
-/* --- sub-ioctls definitions --- */
-    { SHOW_CONN_STATUS,
-	  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "connStatus" },
-	{ SHOW_DRVIER_VERION,
-	  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "driverVer" },
-    { SHOW_BA_INFO,
-	  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "bainfo" },
-	{ SHOW_DESC_INFO,
-	  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "descinfo" },
-    { RAIO_OFF,
-	  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_off" },
-	{ RAIO_ON,
-	  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_on" },
-#ifdef QOS_DLS_SUPPORT
-	{ SHOW_DLS_ENTRY_INFO,
-	  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "dlsentryinfo" },
-#endif // QOS_DLS_SUPPORT //
-	{ SHOW_CFG_VALUE,
-	  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "show" },
-	{ SHOW_ADHOC_ENTRY_INFO,
-	  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "adhocEntry" },
-/* --- sub-ioctls relations --- */
-
-#ifdef DBG
-{ RTPRIV_IOCTL_BBP,
-  IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
-  "bbp"},
-{ RTPRIV_IOCTL_MAC,
-  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
-  "mac"},
-#ifdef RTMP_RF_RW_SUPPORT
-{ RTPRIV_IOCTL_RF,
-  IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
-  "rf"},
-#endif // RTMP_RF_RW_SUPPORT //
-{ RTPRIV_IOCTL_E2P,
-  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
-  "e2p"},
-#endif  /* DBG */
-
-{ RTPRIV_IOCTL_STATISTICS,
-  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
-  "stat"},
-{ RTPRIV_IOCTL_GSITESURVEY,
-  0, IW_PRIV_TYPE_CHAR | 1024,
-  "get_site_survey"},
-
-
-};
-
-static __s32 ralinkrate[] =
-	{2,  4,   11,  22, // CCK
-	12, 18,   24,  36, 48, 72, 96, 108, // OFDM
-	13, 26,   39,  52,  78, 104, 117, 130, 26,  52,  78, 104, 156, 208, 234, 260, // 20MHz, 800ns GI, MCS: 0 ~ 15
-	39, 78,  117, 156, 234, 312, 351, 390,										  // 20MHz, 800ns GI, MCS: 16 ~ 23
-	27, 54,   81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, // 40MHz, 800ns GI, MCS: 0 ~ 15
-	81, 162, 243, 324, 486, 648, 729, 810,										  // 40MHz, 800ns GI, MCS: 16 ~ 23
-	14, 29,   43,  57,  87, 115, 130, 144, 29, 59,   87, 115, 173, 230, 260, 288, // 20MHz, 400ns GI, MCS: 0 ~ 15
-	43, 87,  130, 173, 260, 317, 390, 433,										  // 20MHz, 400ns GI, MCS: 16 ~ 23
-	30, 60,   90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, // 40MHz, 400ns GI, MCS: 0 ~ 15
-	90, 180, 270, 360, 540, 720, 810, 900};
-
-
-
-INT Set_SSID_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg);
-
-#ifdef WMM_SUPPORT
-INT	Set_WmmCapable_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-#endif
-
-INT Set_NetworkType_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg);
-
-INT Set_AuthMode_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg);
-
-INT Set_EncrypType_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg);
-
-INT Set_DefaultKeyID_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg);
-
-INT Set_Key1_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg);
-
-INT Set_Key2_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg);
-
-INT Set_Key3_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg);
-
-INT Set_Key4_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg);
-
-INT Set_WPAPSK_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg);
-
-
-INT Set_PSMode_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg);
-
-#ifdef RT3090
-INT Set_PCIePSLevel_Proc(
-IN  PRTMP_ADAPTER   pAdapter,
-IN  PUCHAR          arg);
-#endif // RT3090 //
-#ifdef WPA_SUPPLICANT_SUPPORT
-INT Set_Wpa_Support(
-    IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-#ifdef DBG
-
-VOID RTMPIoctlMAC(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq);
-
-VOID RTMPIoctlE2PROM(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  struct iwreq    *wrq);
-#endif // DBG //
-
-
-NDIS_STATUS RTMPWPANoneAddKeyProc(
-    IN  PRTMP_ADAPTER   pAd,
-    IN	PVOID			pBuf);
-
-INT Set_FragTest_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg);
-
-#ifdef DOT11_N_SUPPORT
-INT Set_TGnWifiTest_Proc(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PSTRING          arg);
-#endif // DOT11_N_SUPPORT //
-
-INT Set_LongRetryLimit_Proc(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	PSTRING			arg);
-
-INT Set_ShortRetryLimit_Proc(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	PSTRING			arg);
-
-#ifdef EXT_BUILD_CHANNEL_LIST
-INT Set_Ieee80211dClientMode_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg);
-#endif // EXT_BUILD_CHANNEL_LIST //
-
-#ifdef CARRIER_DETECTION_SUPPORT
-INT Set_CarrierDetect_Proc(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PSTRING          arg);
-#endif // CARRIER_DETECTION_SUPPORT //
-
-INT	Show_Adhoc_MacTable_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			extra);
-
-#ifdef RTMP_RF_RW_SUPPORT
-VOID RTMPIoctlRF(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq);
-#endif // RTMP_RF_RW_SUPPORT //
-
-
-INT Set_BeaconLostTime_Proc(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PSTRING         arg);
-
-INT Set_AutoRoaming_Proc(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PSTRING         arg);
-
-INT Set_SiteSurvey_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg);
-
-INT Set_ForceTxBurst_Proc(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PSTRING         arg);
-
-#ifdef ANT_DIVERSITY_SUPPORT
-INT	Set_Antenna_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
-#endif // ANT_DIVERSITY_SUPPORT //
-
-static struct {
-	PSTRING name;
-	INT (*set_proc)(PRTMP_ADAPTER pAdapter, PSTRING arg);
-} *PRTMP_PRIVATE_SET_PROC, RTMP_PRIVATE_SUPPORT_PROC[] = {
-	{"DriverVersion",				Set_DriverVersion_Proc},
-	{"CountryRegion",				Set_CountryRegion_Proc},
-	{"CountryRegionABand",			Set_CountryRegionABand_Proc},
-	{"SSID",						Set_SSID_Proc},
-	{"WirelessMode",				Set_WirelessMode_Proc},
-	{"TxBurst",					Set_TxBurst_Proc},
-	{"TxPreamble",				Set_TxPreamble_Proc},
-	{"TxPower",					Set_TxPower_Proc},
-	{"Channel",					Set_Channel_Proc},
-	{"BGProtection",				Set_BGProtection_Proc},
-	{"RTSThreshold",				Set_RTSThreshold_Proc},
-	{"FragThreshold",				Set_FragThreshold_Proc},
-#ifdef DOT11_N_SUPPORT
-	{"HtBw",		                Set_HtBw_Proc},
-	{"HtMcs",		                Set_HtMcs_Proc},
-	{"HtGi",		                Set_HtGi_Proc},
-	{"HtOpMode",		            Set_HtOpMode_Proc},
-	{"HtExtcha",		            Set_HtExtcha_Proc},
-	{"HtMpduDensity",		        Set_HtMpduDensity_Proc},
-	{"HtBaWinSize",				Set_HtBaWinSize_Proc},
-	{"HtRdg",					Set_HtRdg_Proc},
-	{"HtAmsdu",					Set_HtAmsdu_Proc},
-	{"HtAutoBa",				Set_HtAutoBa_Proc},
-	{"HtBaDecline",					Set_BADecline_Proc},
-	{"HtProtect",				Set_HtProtect_Proc},
-	{"HtMimoPs",				Set_HtMimoPs_Proc},
-	{"HtDisallowTKIP",				Set_HtDisallowTKIP_Proc},
-#endif // DOT11_N_SUPPORT //
-
-#ifdef AGGREGATION_SUPPORT
-	{"PktAggregate",				Set_PktAggregate_Proc},
-#endif // AGGREGATION_SUPPORT //
-
-#ifdef WMM_SUPPORT
-	{"WmmCapable",					Set_WmmCapable_Proc},
-#endif
-	{"IEEE80211H",					Set_IEEE80211H_Proc},
-    {"NetworkType",                 Set_NetworkType_Proc},
-	{"AuthMode",					Set_AuthMode_Proc},
-	{"EncrypType",					Set_EncrypType_Proc},
-	{"DefaultKeyID",				Set_DefaultKeyID_Proc},
-	{"Key1",						Set_Key1_Proc},
-	{"Key2",						Set_Key2_Proc},
-	{"Key3",						Set_Key3_Proc},
-	{"Key4",						Set_Key4_Proc},
-	{"WPAPSK",						Set_WPAPSK_Proc},
-	{"ResetCounter",				Set_ResetStatCounter_Proc},
-	{"PSMode",                      Set_PSMode_Proc},
-#ifdef DBG
-	{"Debug",						Set_Debug_Proc},
-#endif // DBG //
-
-#ifdef RALINK_ATE
-	{"ATE",							Set_ATE_Proc},
-	{"ATEDA",						Set_ATE_DA_Proc},
-	{"ATESA",						Set_ATE_SA_Proc},
-	{"ATEBSSID",					Set_ATE_BSSID_Proc},
-	{"ATECHANNEL",					Set_ATE_CHANNEL_Proc},
-	{"ATETXPOW0",					Set_ATE_TX_POWER0_Proc},
-	{"ATETXPOW1",					Set_ATE_TX_POWER1_Proc},
-	{"ATETXANT",					Set_ATE_TX_Antenna_Proc},
-	{"ATERXANT",					Set_ATE_RX_Antenna_Proc},
-	{"ATETXFREQOFFSET",				Set_ATE_TX_FREQOFFSET_Proc},
-	{"ATETXBW",						Set_ATE_TX_BW_Proc},
-	{"ATETXLEN",					Set_ATE_TX_LENGTH_Proc},
-	{"ATETXCNT",					Set_ATE_TX_COUNT_Proc},
-	{"ATETXMCS",					Set_ATE_TX_MCS_Proc},
-	{"ATETXMODE",					Set_ATE_TX_MODE_Proc},
-	{"ATETXGI",						Set_ATE_TX_GI_Proc},
-	{"ATERXFER",					Set_ATE_RX_FER_Proc},
-	{"ATERRF",						Set_ATE_Read_RF_Proc},
-	{"ATEWRF1",						Set_ATE_Write_RF1_Proc},
-	{"ATEWRF2",						Set_ATE_Write_RF2_Proc},
-	{"ATEWRF3",						Set_ATE_Write_RF3_Proc},
-	{"ATEWRF4",						Set_ATE_Write_RF4_Proc},
-	{"ATELDE2P",				    Set_ATE_Load_E2P_Proc},
-	{"ATERE2P",						Set_ATE_Read_E2P_Proc},
-	{"ATESHOW",						Set_ATE_Show_Proc},
-	{"ATEHELP",						Set_ATE_Help_Proc},
-
-#ifdef RALINK_28xx_QA
-	{"TxStop",						Set_TxStop_Proc},
-	{"RxStop",						Set_RxStop_Proc},
-#endif // RALINK_28xx_QA //
-#endif // RALINK_ATE //
-
-#ifdef WPA_SUPPLICANT_SUPPORT
-    {"WpaSupport",                  Set_Wpa_Support},
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-
-
-
-
-	{"FixedTxMode",                 Set_FixedTxMode_Proc},
-#ifdef CONFIG_APSTA_MIXED_SUPPORT
-	{"OpMode",						Set_OpMode_Proc},
-#endif // CONFIG_APSTA_MIXED_SUPPORT //
-#ifdef DOT11_N_SUPPORT
-    {"TGnWifiTest",                 Set_TGnWifiTest_Proc},
-    {"ForceGF",					Set_ForceGF_Proc},
-#endif // DOT11_N_SUPPORT //
-#ifdef QOS_DLS_SUPPORT
-	{"DlsAddEntry",					Set_DlsAddEntry_Proc},
-	{"DlsTearDownEntry",			Set_DlsTearDownEntry_Proc},
-#endif // QOS_DLS_SUPPORT //
-	{"LongRetry",				Set_LongRetryLimit_Proc},
-	{"ShortRetry",				Set_ShortRetryLimit_Proc},
-#ifdef EXT_BUILD_CHANNEL_LIST
-	{"11dClientMode",				Set_Ieee80211dClientMode_Proc},
-#endif // EXT_BUILD_CHANNEL_LIST //
-#ifdef CARRIER_DETECTION_SUPPORT
-	{"CarrierDetect",				Set_CarrierDetect_Proc},
-#endif // CARRIER_DETECTION_SUPPORT //
-
-
-//2008/09/11:KH add to support efuse<--
-#ifdef RT30xx
-#ifdef RTMP_EFUSE_SUPPORT
-	{"efuseFreeNumber",				set_eFuseGetFreeBlockCount_Proc},
-	{"efuseDump",					set_eFusedump_Proc},
-	{"efuseLoadFromBin",				set_eFuseLoadFromBin_Proc},
-	{"efuseBufferModeWriteBack",		set_eFuseBufferModeWriteBack_Proc},
-#endif // RTMP_EFUSE_SUPPORT //
-#ifdef ANT_DIVERSITY_SUPPORT
-	{"ant",					Set_Antenna_Proc},
-#endif // ANT_DIVERSITY_SUPPORT //
-#endif // RT30xx //
-//2008/09/11:KH add to support efuse-->
-
-	{"BeaconLostTime",				Set_BeaconLostTime_Proc},
-	{"AutoRoaming",					Set_AutoRoaming_Proc},
-	{"SiteSurvey",					Set_SiteSurvey_Proc},
-	{"ForceTxBurst",				Set_ForceTxBurst_Proc},
-
-	{NULL,}
-};
-
-
-VOID RTMPAddKey(
-	IN	PRTMP_ADAPTER	    pAd,
-	IN	PNDIS_802_11_KEY    pKey)
-{
-	ULONG				KeyIdx;
-	MAC_TABLE_ENTRY		*pEntry;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey ------>\n"));
-
-	if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-	{
-		if (pKey->KeyIndex & 0x80000000)
-		{
-		    if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
-            {
-                NdisZeroMemory(pAd->StaCfg.PMK, 32);
-                NdisMoveMemory(pAd->StaCfg.PMK, pKey->KeyMaterial, pKey->KeyLength);
-                goto end;
-            }
-		    // Update PTK
-		    NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
-            pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
-            NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pKey->KeyMaterial, LEN_TKIP_EK);
-#ifdef WPA_SUPPLICANT_SUPPORT
-            if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
-            {
-                NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
-                NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
-            }
-            else
-#endif // WPA_SUPPLICANT_SUPPORT //
-            {
-		NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
-                NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
-            }
-
-            // Decide its ChiperAlg
-		if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
-			pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
-		else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
-			pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
-		else
-			pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
-
-            // Update these related information to MAC_TABLE_ENTRY
-		pEntry = &pAd->MacTab.Content[BSSID_WCID];
-            NdisMoveMemory(pEntry->PairwiseKey.Key, pAd->SharedKey[BSS0][0].Key, LEN_TKIP_EK);
-		NdisMoveMemory(pEntry->PairwiseKey.RxMic, pAd->SharedKey[BSS0][0].RxMic, LEN_TKIP_RXMICK);
-		NdisMoveMemory(pEntry->PairwiseKey.TxMic, pAd->SharedKey[BSS0][0].TxMic, LEN_TKIP_TXMICK);
-		pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
-
-		// Update pairwise key information to ASIC Shared Key Table
-		AsicAddSharedKeyEntry(pAd,
-							  BSS0,
-							  0,
-							  pAd->SharedKey[BSS0][0].CipherAlg,
-							  pAd->SharedKey[BSS0][0].Key,
-							  pAd->SharedKey[BSS0][0].TxMic,
-							  pAd->SharedKey[BSS0][0].RxMic);
-
-		// Update ASIC WCID attribute table and IVEIV table
-		RTMPAddWcidAttributeEntry(pAd,
-								  BSS0,
-								  0,
-								  pAd->SharedKey[BSS0][0].CipherAlg,
-								  pEntry);
-
-            if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
-            {
-                // set 802.1x port control
-	            //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
-				STA_PORT_SECURED(pAd);
-
-                // Indicate Connected for GUI
-                pAd->IndicateMediaState = NdisMediaStateConnected;
-            }
-		}
-        else
-        {
-            // Update GTK
-            pAd->StaCfg.DefaultKeyId = (pKey->KeyIndex & 0xFF);
-            NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
-            pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
-            NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKey->KeyMaterial, LEN_TKIP_EK);
-#ifdef WPA_SUPPLICANT_SUPPORT
-            if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
-            {
-                NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
-                NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
-            }
-            else
-#endif // WPA_SUPPLICANT_SUPPORT //
-            {
-		NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
-                NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
-            }
-
-            // Update Shared Key CipherAlg
-		pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
-		if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
-			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
-		else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
-			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
-
-            // Update group key information to ASIC Shared Key Table
-		AsicAddSharedKeyEntry(pAd,
-							  BSS0,
-							  pAd->StaCfg.DefaultKeyId,
-							  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
-							  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
-							  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
-							  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
-
-		// Update ASIC WCID attribute table and IVEIV table
-		RTMPAddWcidAttributeEntry(pAd,
-								  BSS0,
-								  pAd->StaCfg.DefaultKeyId,
-								  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
-								  NULL);
-
-            // set 802.1x port control
-	        //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
-			STA_PORT_SECURED(pAd);
-
-            // Indicate Connected for GUI
-            pAd->IndicateMediaState = NdisMediaStateConnected;
-        }
-	}
-	else	// dynamic WEP from wpa_supplicant
-	{
-		UCHAR	CipherAlg;
-	PUCHAR	Key;
-
-		if(pKey->KeyLength == 32)
-			goto end;
-
-		KeyIdx = pKey->KeyIndex & 0x0fffffff;
-
-		if (KeyIdx < 4)
-		{
-			// it is a default shared key, for Pairwise key setting
-			if (pKey->KeyIndex & 0x80000000)
-			{
-				pEntry = MacTableLookup(pAd, pKey->BSSID);
-
-				if (pEntry)
-				{
-					DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey: Set Pair-wise Key\n"));
-
-					// set key material and key length
-					pEntry->PairwiseKey.KeyLen = (UCHAR)pKey->KeyLength;
-					NdisMoveMemory(pEntry->PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
-
-					// set Cipher type
-					if (pKey->KeyLength == 5)
-						pEntry->PairwiseKey.CipherAlg = CIPHER_WEP64;
-					else
-						pEntry->PairwiseKey.CipherAlg = CIPHER_WEP128;
-
-					// Add Pair-wise key to Asic
-					AsicAddPairwiseKeyEntry(
-						pAd,
-						pEntry->Addr,
-						(UCHAR)pEntry->Aid,
-				&pEntry->PairwiseKey);
-
-					// update WCID attribute table and IVEIV table for this entry
-					RTMPAddWcidAttributeEntry(
-						pAd,
-						BSS0,
-						KeyIdx, // The value may be not zero
-						pEntry->PairwiseKey.CipherAlg,
-						pEntry);
-
-				}
-			}
-			else
-            {
-				// Default key for tx (shared key)
-				pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
-
-				// set key material and key length
-				pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pKey->KeyLength;
-				NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pKey->KeyMaterial, pKey->KeyLength);
-
-				// Set Ciper type
-				if (pKey->KeyLength == 5)
-					pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP64;
-				else
-					pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP128;
-
-			CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
-			Key = pAd->SharedKey[BSS0][KeyIdx].Key;
-
-				// Set Group key material to Asic
-			AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
-
-				// Update WCID attribute table and IVEIV table for this group key table
-				RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx, CipherAlg, NULL);
-
-			}
-		}
-	}
-end:
-	return;
-}
-
-char * rtstrchr(const char * s, int c)
-{
-    for(; *s != (char) c; ++s)
-        if (*s == '\0')
-            return NULL;
-    return (char *) s;
-}
-
-/*
-This is required for LinEX2004/kernel2.6.7 to provide iwlist scanning function
-*/
-
-int
-rt_ioctl_giwname(struct net_device *dev,
-		   struct iw_request_info *info,
-		   char *name, char *extra)
-{
-
-#ifdef RTMP_MAC_PCI
-    strncpy(name, "RT2860 Wireless", IFNAMSIZ);
-#endif // RTMP_MAC_PCI //
-	return 0;
-}
-
-int rt_ioctl_siwfreq(struct net_device *dev,
-			struct iw_request_info *info,
-			struct iw_freq *freq, char *extra)
-{
-	PRTMP_ADAPTER pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-	int	chan = -1;
-
-    //check if the interface is down
-    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-        return -ENETDOWN;
-    }
-
-
-	if (freq->e > 1)
-		return -EINVAL;
-
-	if((freq->e == 0) && (freq->m <= 1000))
-		chan = freq->m;	// Setting by channel number
-	else
-		MAP_KHZ_TO_CHANNEL_ID( (freq->m /100) , chan); // Setting by frequency - search the table , like 2.412G, 2.422G,
-
-    if (ChannelSanity(pAdapter, chan) == TRUE)
-    {
-	pAdapter->CommonCfg.Channel = chan;
-	DBGPRINT(RT_DEBUG_ERROR, ("==>rt_ioctl_siwfreq::SIOCSIWFREQ[cmd=0x%x] (Channel=%d)\n", SIOCSIWFREQ, pAdapter->CommonCfg.Channel));
-    }
-    else
-        return -EINVAL;
-
-	return 0;
-}
-
-
-int rt_ioctl_giwfreq(struct net_device *dev,
-		   struct iw_request_info *info,
-		   struct iw_freq *freq, char *extra)
-{
-	PRTMP_ADAPTER pAdapter = NULL;
-	UCHAR ch;
-	ULONG	m = 2412000;
-
-	pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-	if (pAdapter == NULL)
-	{
-		/* if 1st open fail, pAd will be free;
-		   So the net_dev->priv will be NULL in 2rd open */
-		return -ENETDOWN;
-	}
-
-		ch = pAdapter->CommonCfg.Channel;
-
-	DBGPRINT(RT_DEBUG_TRACE,("==>rt_ioctl_giwfreq  %d\n", ch));
-
-	MAP_CHANNEL_ID_TO_KHZ(ch, m);
-	freq->m = m * 100;
-	freq->e = 1;
-	return 0;
-}
-
-
-int rt_ioctl_siwmode(struct net_device *dev,
-		   struct iw_request_info *info,
-		   __u32 *mode, char *extra)
-{
-	PRTMP_ADAPTER pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-
-	//check if the interface is down
-    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-    {
-	DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-	return -ENETDOWN;
-    }
-
-	switch (*mode)
-	{
-		case IW_MODE_ADHOC:
-			Set_NetworkType_Proc(pAdapter, "Adhoc");
-			break;
-		case IW_MODE_INFRA:
-			Set_NetworkType_Proc(pAdapter, "Infra");
-			break;
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
-        case IW_MODE_MONITOR:
-			Set_NetworkType_Proc(pAdapter, "Monitor");
-			break;
-#endif
-		default:
-			DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_siwmode::SIOCSIWMODE (unknown %d)\n", *mode));
-			return -EINVAL;
-	}
-
-	// Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
-	pAdapter->StaCfg.WpaState = SS_NOTUSE;
-
-	return 0;
-}
-
-
-int rt_ioctl_giwmode(struct net_device *dev,
-		   struct iw_request_info *info,
-		   __u32 *mode, char *extra)
-{
-	PRTMP_ADAPTER pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-
-	if (pAdapter == NULL)
-	{
-		/* if 1st open fail, pAd will be free;
-		   So the net_dev->priv will be NULL in 2rd open */
-		return -ENETDOWN;
-	}
-
-	if (ADHOC_ON(pAdapter))
-		*mode = IW_MODE_ADHOC;
-    else if (INFRA_ON(pAdapter))
-		*mode = IW_MODE_INFRA;
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
-    else if (MONITOR_ON(pAdapter))
-    {
-        *mode = IW_MODE_MONITOR;
-    }
-#endif
-    else
-        *mode = IW_MODE_AUTO;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("==>rt_ioctl_giwmode(mode=%d)\n", *mode));
-	return 0;
-}
-
-int rt_ioctl_siwsens(struct net_device *dev,
-		   struct iw_request_info *info,
-		   char *name, char *extra)
-{
-	PRTMP_ADAPTER pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-
-	//check if the interface is down
-	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	return 0;
-}
-
-int rt_ioctl_giwsens(struct net_device *dev,
-		   struct iw_request_info *info,
-		   char *name, char *extra)
-{
-	return 0;
-}
-
-int rt_ioctl_giwrange(struct net_device *dev,
-		   struct iw_request_info *info,
-		   struct iw_point *data, char *extra)
-{
-	PRTMP_ADAPTER pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-	struct iw_range *range = (struct iw_range *) extra;
-	u16 val;
-	int i;
-
-	if (pAdapter == NULL)
-	{
-		/* if 1st open fail, pAd will be free;
-		   So the net_dev->priv will be NULL in 2rd open */
-		return -ENETDOWN;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE ,("===>rt_ioctl_giwrange\n"));
-	data->length = sizeof(struct iw_range);
-	memset(range, 0, sizeof(struct iw_range));
-
-	range->txpower_capa = IW_TXPOW_DBM;
-
-	if (INFRA_ON(pAdapter)||ADHOC_ON(pAdapter))
-	{
-		range->min_pmp = 1 * 1024;
-		range->max_pmp = 65535 * 1024;
-		range->min_pmt = 1 * 1024;
-		range->max_pmt = 1000 * 1024;
-		range->pmp_flags = IW_POWER_PERIOD;
-		range->pmt_flags = IW_POWER_TIMEOUT;
-		range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT |
-			IW_POWER_UNICAST_R | IW_POWER_ALL_R;
-	}
-
-	range->we_version_compiled = WIRELESS_EXT;
-	range->we_version_source = 14;
-
-	range->retry_capa = IW_RETRY_LIMIT;
-	range->retry_flags = IW_RETRY_LIMIT;
-	range->min_retry = 0;
-	range->max_retry = 255;
-
-	range->num_channels =  pAdapter->ChannelListNum;
-
-	val = 0;
-	for (i = 1; i <= range->num_channels; i++)
-	{
-		u32 m = 2412000;
-		range->freq[val].i = pAdapter->ChannelList[i-1].Channel;
-		MAP_CHANNEL_ID_TO_KHZ(pAdapter->ChannelList[i-1].Channel, m);
-		range->freq[val].m = m * 100; /* OS_HZ */
-
-		range->freq[val].e = 1;
-		val++;
-		if (val == IW_MAX_FREQUENCIES)
-			break;
-	}
-	range->num_frequency = val;
-
-	range->max_qual.qual = 100; /* what is correct max? This was not
-					* documented exactly. At least
-					* 69 has been observed. */
-	range->max_qual.level = 0; /* dB */
-	range->max_qual.noise = 0; /* dB */
-
-	/* What would be suitable values for "average/typical" qual? */
-	range->avg_qual.qual = 20;
-	range->avg_qual.level = -60;
-	range->avg_qual.noise = -95;
-	range->sensitivity = 3;
-
-	range->max_encoding_tokens = NR_WEP_KEYS;
-	range->num_encoding_sizes = 2;
-	range->encoding_size[0] = 5;
-	range->encoding_size[1] = 13;
-
-	range->min_rts = 0;
-	range->max_rts = 2347;
-	range->min_frag = 256;
-	range->max_frag = 2346;
-
-#if WIRELESS_EXT > 17
-	/* IW_ENC_CAPA_* bit field */
-	range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
-					IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
-#endif
-
-	return 0;
-}
-
-int rt_ioctl_siwap(struct net_device *dev,
-		      struct iw_request_info *info,
-		      struct sockaddr *ap_addr, char *extra)
-{
-	PRTMP_ADAPTER pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-    NDIS_802_11_MAC_ADDRESS Bssid;
-
-	//check if the interface is down
-	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
-	DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-	return -ENETDOWN;
-    }
-
-	if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
-    {
-        RTMP_MLME_RESET_STATE_MACHINE(pAdapter);
-        DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
-    }
-
-    // tell CNTL state machine to call NdisMSetInformationComplete() after completing
-    // this request, because this request is initiated by NDIS.
-    pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
-	// Prevent to connect AP again in STAMlmePeriodicExec
-	pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
-
-    memset(Bssid, 0, MAC_ADDR_LEN);
-    memcpy(Bssid, ap_addr->sa_data, MAC_ADDR_LEN);
-    MlmeEnqueue(pAdapter,
-                MLME_CNTL_STATE_MACHINE,
-                OID_802_11_BSSID,
-                sizeof(NDIS_802_11_MAC_ADDRESS),
-                (VOID *)&Bssid);
-
-    DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCSIWAP %02x:%02x:%02x:%02x:%02x:%02x\n",
-        Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
-
-	return 0;
-}
-
-int rt_ioctl_giwap(struct net_device *dev,
-		      struct iw_request_info *info,
-		      struct sockaddr *ap_addr, char *extra)
-{
-	PRTMP_ADAPTER pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-
-	if (pAdapter == NULL)
-	{
-		/* if 1st open fail, pAd will be free;
-		   So the net_dev->priv will be NULL in 2rd open */
-		return -ENETDOWN;
-	}
-
-	if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
-	{
-		ap_addr->sa_family = ARPHRD_ETHER;
-		memcpy(ap_addr->sa_data, &pAdapter->CommonCfg.Bssid, ETH_ALEN);
-	}
-#ifdef WPA_SUPPLICANT_SUPPORT
-    // Add for RT2870
-    else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
-    {
-        ap_addr->sa_family = ARPHRD_ETHER;
-        memcpy(ap_addr->sa_data, &pAdapter->MlmeAux.Bssid, ETH_ALEN);
-    }
-#endif // WPA_SUPPLICANT_SUPPORT //
-	else
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIWAP(=EMPTY)\n"));
-		return -ENOTCONN;
-	}
-
-	return 0;
-}
-
-/*
- * Units are in db above the noise floor. That means the
- * rssi values reported in the tx/rx descriptors in the
- * driver are the SNR expressed in db.
- *
- * If you assume that the noise floor is -95, which is an
- * excellent assumption 99.5 % of the time, then you can
- * derive the absolute signal level (i.e. -95 + rssi).
- * There are some other slight factors to take into account
- * depending on whether the rssi measurement is from 11b,
- * 11g, or 11a.   These differences are at most 2db and
- * can be documented.
- *
- * NB: various calculations are based on the orinoco/wavelan
- *     drivers for compatibility
- */
-static void set_quality(PRTMP_ADAPTER pAdapter,
-                        struct iw_quality *iq,
-                        signed char rssi)
-{
-	__u8 ChannelQuality;
-
-	// Normalize Rssi
-	if (rssi >= -50)
-        ChannelQuality = 100;
-	else if (rssi >= -80) // between -50 ~ -80dbm
-		ChannelQuality = (__u8)(24 + ((rssi + 80) * 26)/10);
-	else if (rssi >= -90)   // between -80 ~ -90dbm
-        ChannelQuality = (__u8)((rssi + 90) * 26)/10;
-	else
-		ChannelQuality = 0;
-
-    iq->qual = (__u8)ChannelQuality;
-
-    iq->level = (__u8)(rssi);
-    iq->noise = (pAdapter->BbpWriteLatch[66] > pAdapter->BbpTuning.FalseCcaUpperThreshold) ? ((__u8)pAdapter->BbpTuning.FalseCcaUpperThreshold) : ((__u8) pAdapter->BbpWriteLatch[66]);		// noise level (dBm)
-    iq->noise += 256 - 143;
-    iq->updated = pAdapter->iw_stats.qual.updated;
-}
-
-int rt_ioctl_iwaplist(struct net_device *dev,
-			struct iw_request_info *info,
-			struct iw_point *data, char *extra)
-{
-	PRTMP_ADAPTER pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-
-	struct sockaddr addr[IW_MAX_AP];
-	struct iw_quality qual[IW_MAX_AP];
-	int i;
-
-	//check if the interface is down
-    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-    {
-	DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		data->length = 0;
-		return 0;
-        //return -ENETDOWN;
-	}
-
-	for (i = 0; i <IW_MAX_AP ; i++)
-	{
-		if (i >=  pAdapter->ScanTab.BssNr)
-			break;
-		addr[i].sa_family = ARPHRD_ETHER;
-			memcpy(addr[i].sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
-		set_quality(pAdapter, &qual[i], pAdapter->ScanTab.BssEntry[i].Rssi);
-	}
-	data->length = i;
-	memcpy(extra, &addr, i*sizeof(addr[0]));
-	data->flags = 1;		/* signal quality present (sort of) */
-	memcpy(extra + i*sizeof(addr[0]), &qual, i*sizeof(qual[i]));
-
-	return 0;
-}
-
-#ifdef SIOCGIWSCAN
-int rt_ioctl_siwscan(struct net_device *dev,
-			struct iw_request_info *info,
-			struct iw_point *data, char *extra)
-{
-	PRTMP_ADAPTER pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-
-	ULONG								Now;
-	int Status = NDIS_STATUS_SUCCESS;
-
-	//check if the interface is down
-	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	if (MONITOR_ON(pAdapter))
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
-        return -EINVAL;
-    }
-
-
-#ifdef WPA_SUPPLICANT_SUPPORT
-	if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
-	{
-		pAdapter->StaCfg.WpaSupplicantScanCount++;
-	}
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-    pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
-	if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-		return NDIS_STATUS_SUCCESS;
-	do{
-		Now = jiffies;
-
-#ifdef WPA_SUPPLICANT_SUPPORT
-		if ((pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) &&
-			(pAdapter->StaCfg.WpaSupplicantScanCount > 3))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("!!! WpaSupplicantScanCount > 3\n"));
-			Status = NDIS_STATUS_SUCCESS;
-			break;
-		}
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-		if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
-			((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
-			(pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) &&
-			(pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
-			Status = NDIS_STATUS_SUCCESS;
-			break;
-		}
-
-		if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
-		{
-			RTMP_MLME_RESET_STATE_MACHINE(pAdapter);
-			DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
-		}
-
-		// tell CNTL state machine to call NdisMSetInformationComplete() after completing
-		// this request, because this request is initiated by NDIS.
-		pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
-		// Reset allowed scan retries
-		pAdapter->StaCfg.ScanCnt = 0;
-		pAdapter->StaCfg.LastScanTime = Now;
-
-		MlmeEnqueue(pAdapter,
-			MLME_CNTL_STATE_MACHINE,
-			OID_802_11_BSSID_LIST_SCAN,
-			0,
-			NULL);
-
-		Status = NDIS_STATUS_SUCCESS;
-		RTMP_MLME_HANDLER(pAdapter);
-	}while(0);
-	return NDIS_STATUS_SUCCESS;
-}
-
-int rt_ioctl_giwscan(struct net_device *dev,
-			struct iw_request_info *info,
-			struct iw_point *data, char *extra)
-{
-
-	PRTMP_ADAPTER pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-	int i=0;
-	PSTRING current_ev = extra, previous_ev = extra;
-	PSTRING end_buf;
-	PSTRING current_val;
-	STRING custom[MAX_CUSTOM_LEN] = {0};
-#ifndef IWEVGENIE
-	unsigned char idx;
-#endif // IWEVGENIE //
-	struct iw_event iwe;
-
-	if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-    {
-		/*
-		 * Still scanning, indicate the caller should try again.
-		 */
-		return -EAGAIN;
-	}
-
-
-#ifdef WPA_SUPPLICANT_SUPPORT
-	if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
-	{
-		pAdapter->StaCfg.WpaSupplicantScanCount = 0;
-	}
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-	if (pAdapter->ScanTab.BssNr == 0)
-	{
-		data->length = 0;
-		return 0;
-	}
-
-#if WIRELESS_EXT >= 17
-    if (data->length > 0)
-        end_buf = extra + data->length;
-    else
-        end_buf = extra + IW_SCAN_MAX_DATA;
-#else
-    end_buf = extra + IW_SCAN_MAX_DATA;
-#endif
-
-	for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
-	{
-		if (current_ev >= end_buf)
-        {
-#if WIRELESS_EXT >= 17
-            return -E2BIG;
-#else
-			break;
-#endif
-        }
-
-		//MAC address
-		//================================
-		memset(&iwe, 0, sizeof(iwe));
-		iwe.cmd = SIOCGIWAP;
-		iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
-				memcpy(iwe.u.ap_addr.sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, ETH_ALEN);
-
-        previous_ev = current_ev;
-		current_ev = IWE_STREAM_ADD_EVENT(info, current_ev,end_buf, &iwe, IW_EV_ADDR_LEN);
-        if (current_ev == previous_ev)
-#if WIRELESS_EXT >= 17
-            return -E2BIG;
-#else
-			break;
-#endif
-
-		/*
-		Protocol:
-			it will show scanned AP's WirelessMode .
-			it might be
-					802.11a
-					802.11a/n
-					802.11g/n
-					802.11b/g/n
-					802.11g
-					802.11b/g
-		*/
-		memset(&iwe, 0, sizeof(iwe));
-		iwe.cmd = SIOCGIWNAME;
-
-
-	{
-		PBSS_ENTRY pBssEntry=&pAdapter->ScanTab.BssEntry[i];
-		BOOLEAN isGonly=FALSE;
-		int rateCnt=0;
-
-		if (pBssEntry->Channel>14)
-		{
-			if (pBssEntry->HtCapabilityLen!=0)
-				strcpy(iwe.u.name,"802.11a/n");
-			else
-				strcpy(iwe.u.name,"802.11a");
-		}
-		else
-		{
-			/*
-				if one of non B mode rate is set supported rate . it mean G only.
-			*/
-			for (rateCnt=0;rateCnt<pBssEntry->SupRateLen;rateCnt++)
-			{
-				/*
-					6Mbps(140) 9Mbps(146) and >=12Mbps(152) are supported rate , it mean G only.
-				*/
-				if (pBssEntry->SupRate[rateCnt]==140 || pBssEntry->SupRate[rateCnt]==146 || pBssEntry->SupRate[rateCnt]>=152)
-					isGonly=TRUE;
-			}
-
-			for (rateCnt=0;rateCnt<pBssEntry->ExtRateLen;rateCnt++)
-			{
-				if (pBssEntry->ExtRate[rateCnt]==140 || pBssEntry->ExtRate[rateCnt]==146 || pBssEntry->ExtRate[rateCnt]>=152)
-					isGonly=TRUE;
-			}
-
-
-			if (pBssEntry->HtCapabilityLen!=0)
-			{
-				if (isGonly==TRUE)
-					strcpy(iwe.u.name,"802.11g/n");
-				else
-					strcpy(iwe.u.name,"802.11b/g/n");
-			}
-			else
-			{
-				if (isGonly==TRUE)
-					strcpy(iwe.u.name,"802.11g");
-				else
-				{
-					if (pBssEntry->SupRateLen==4 && pBssEntry->ExtRateLen==0)
-						strcpy(iwe.u.name,"802.11b");
-					else
-						strcpy(iwe.u.name,"802.11b/g");
-				}
-			}
-		}
-	}
-
-		previous_ev = current_ev;
-		current_ev = IWE_STREAM_ADD_EVENT(info, current_ev,end_buf, &iwe, IW_EV_ADDR_LEN);
-		if (current_ev == previous_ev)
-#if WIRELESS_EXT >= 17
-			return -E2BIG;
-#else
-			break;
-#endif
-
-		//ESSID
-		//================================
-		memset(&iwe, 0, sizeof(iwe));
-		iwe.cmd = SIOCGIWESSID;
-		iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].SsidLen;
-		iwe.u.data.flags = 1;
-
-        previous_ev = current_ev;
-		current_ev = IWE_STREAM_ADD_POINT(info, current_ev,end_buf, &iwe, (PSTRING) pAdapter->ScanTab.BssEntry[i].Ssid);
-        if (current_ev == previous_ev)
-#if WIRELESS_EXT >= 17
-            return -E2BIG;
-#else
-			break;
-#endif
-
-		//Network Type
-		//================================
-		memset(&iwe, 0, sizeof(iwe));
-		iwe.cmd = SIOCGIWMODE;
-		if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11IBSS)
-		{
-			iwe.u.mode = IW_MODE_ADHOC;
-		}
-		else if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11Infrastructure)
-		{
-			iwe.u.mode = IW_MODE_INFRA;
-		}
-		else
-		{
-			iwe.u.mode = IW_MODE_AUTO;
-		}
-		iwe.len = IW_EV_UINT_LEN;
-
-        previous_ev = current_ev;
-		current_ev = IWE_STREAM_ADD_EVENT(info, current_ev, end_buf, &iwe,  IW_EV_UINT_LEN);
-        if (current_ev == previous_ev)
-#if WIRELESS_EXT >= 17
-            return -E2BIG;
-#else
-			break;
-#endif
-
-		//Channel and Frequency
-		//================================
-		memset(&iwe, 0, sizeof(iwe));
-		iwe.cmd = SIOCGIWFREQ;
-		if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
-			iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
-		else
-			iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
-		iwe.u.freq.e = 0;
-		iwe.u.freq.i = 0;
-
-		previous_ev = current_ev;
-		current_ev = IWE_STREAM_ADD_EVENT(info, current_ev,end_buf, &iwe, IW_EV_FREQ_LEN);
-        if (current_ev == previous_ev)
-#if WIRELESS_EXT >= 17
-            return -E2BIG;
-#else
-			break;
-#endif
-
-        //Add quality statistics
-        //================================
-        memset(&iwe, 0, sizeof(iwe));
-	iwe.cmd = IWEVQUAL;
-	iwe.u.qual.level = 0;
-	iwe.u.qual.noise = 0;
-	set_quality(pAdapter, &iwe.u.qual, pAdapter->ScanTab.BssEntry[i].Rssi);
-	current_ev = IWE_STREAM_ADD_EVENT(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
-	if (current_ev == previous_ev)
-#if WIRELESS_EXT >= 17
-            return -E2BIG;
-#else
-			break;
-#endif
-
-		//Encyption key
-		//================================
-		memset(&iwe, 0, sizeof(iwe));
-		iwe.cmd = SIOCGIWENCODE;
-		if (CAP_IS_PRIVACY_ON (pAdapter->ScanTab.BssEntry[i].CapabilityInfo ))
-			iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
-		else
-			iwe.u.data.flags = IW_ENCODE_DISABLED;
-
-        previous_ev = current_ev;
-        current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf,&iwe, (char *)pAdapter->SharedKey[BSS0][(iwe.u.data.flags & IW_ENCODE_INDEX)-1].Key);
-        if (current_ev == previous_ev)
-#if WIRELESS_EXT >= 17
-            return -E2BIG;
-#else
-			break;
-#endif
-
-		//Bit Rate
-		//================================
-		if (pAdapter->ScanTab.BssEntry[i].SupRateLen)
-        {
-            UCHAR tmpRate = pAdapter->ScanTab.BssEntry[i].SupRate[pAdapter->ScanTab.BssEntry[i].SupRateLen-1];
-			memset(&iwe, 0, sizeof(iwe));
-			iwe.cmd = SIOCGIWRATE;
-		current_val = current_ev + IW_EV_LCP_LEN;
-            if (tmpRate == 0x82)
-                iwe.u.bitrate.value =  1 * 1000000;
-            else if (tmpRate == 0x84)
-                iwe.u.bitrate.value =  2 * 1000000;
-            else if (tmpRate == 0x8B)
-                iwe.u.bitrate.value =  5.5 * 1000000;
-            else if (tmpRate == 0x96)
-                iwe.u.bitrate.value =  11 * 1000000;
-            else
-		    iwe.u.bitrate.value =  (tmpRate/2) * 1000000;
-
-			if (tmpRate == 0x6c && pAdapter->ScanTab.BssEntry[i].HtCapabilityLen > 0)
-			{
-				int rate_count = sizeof(ralinkrate)/sizeof(__s32);
-				HT_CAP_INFO capInfo = pAdapter->ScanTab.BssEntry[i].HtCapability.HtCapInfo;
-				int shortGI = capInfo.ChannelWidth ? capInfo.ShortGIfor40 : capInfo.ShortGIfor20;
-				int maxMCS = pAdapter->ScanTab.BssEntry[i].HtCapability.MCSSet[1] ?  15 : 7;
-				int rate_index = 12 + ((UCHAR)capInfo.ChannelWidth * 24) + ((UCHAR)shortGI *48) + ((UCHAR)maxMCS);
-				if (rate_index < 0)
-					rate_index = 0;
-				if (rate_index > rate_count)
-					rate_index = rate_count;
-				iwe.u.bitrate.value	=  ralinkrate[rate_index] * 500000;
-			}
-
-			iwe.u.bitrate.disabled = 0;
-			current_val = IWE_STREAM_ADD_VALUE(info, current_ev,
-				current_val, end_buf, &iwe,
-			IW_EV_PARAM_LEN);
-
-		if((current_val-current_ev)>IW_EV_LCP_LEN)
-		current_ev = current_val;
-		else
-#if WIRELESS_EXT >= 17
-                return -E2BIG;
-#else
-			    break;
-#endif
-        }
-
-#ifdef IWEVGENIE
-        //WPA IE
-		if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
-        {
-			memset(&iwe, 0, sizeof(iwe));
-			memset(&custom[0], 0, MAX_CUSTOM_LEN);
-			memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].WpaIE.IE[0]),
-						   pAdapter->ScanTab.BssEntry[i].WpaIE.IELen);
-			iwe.cmd = IWEVGENIE;
-			iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].WpaIE.IELen;
-			current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, custom);
-			if (current_ev == previous_ev)
-#if WIRELESS_EXT >= 17
-                return -E2BIG;
-#else
-			    break;
-#endif
-		}
-
-		//WPA2 IE
-        if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
-        {
-		memset(&iwe, 0, sizeof(iwe));
-			memset(&custom[0], 0, MAX_CUSTOM_LEN);
-			memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].RsnIE.IE[0]),
-						   pAdapter->ScanTab.BssEntry[i].RsnIE.IELen);
-			iwe.cmd = IWEVGENIE;
-			iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].RsnIE.IELen;
-			current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, custom);
-			if (current_ev == previous_ev)
-#if WIRELESS_EXT >= 17
-                return -E2BIG;
-#else
-			    break;
-#endif
-        }
-#else
-        //WPA IE
-		//================================
-        if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
-        {
-		NdisZeroMemory(&iwe, sizeof(iwe));
-			memset(&custom[0], 0, MAX_CUSTOM_LEN);
-		iwe.cmd = IWEVCUSTOM;
-            iwe.u.data.length = (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen * 2) + 7;
-            NdisMoveMemory(custom, "wpa_ie=", 7);
-            for (idx = 0; idx < pAdapter->ScanTab.BssEntry[i].WpaIE.IELen; idx++)
-                sprintf(custom, "%s%02x", custom, pAdapter->ScanTab.BssEntry[i].WpaIE.IE[idx]);
-            previous_ev = current_ev;
-		current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe,  custom);
-            if (current_ev == previous_ev)
-#if WIRELESS_EXT >= 17
-                return -E2BIG;
-#else
-			    break;
-#endif
-        }
-
-        //WPA2 IE
-        if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
-        {
-		NdisZeroMemory(&iwe, sizeof(iwe));
-			memset(&custom[0], 0, MAX_CUSTOM_LEN);
-		iwe.cmd = IWEVCUSTOM;
-            iwe.u.data.length = (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen * 2) + 7;
-            NdisMoveMemory(custom, "rsn_ie=", 7);
-			for (idx = 0; idx < pAdapter->ScanTab.BssEntry[i].RsnIE.IELen; idx++)
-                sprintf(custom, "%s%02x", custom, pAdapter->ScanTab.BssEntry[i].RsnIE.IE[idx]);
-            previous_ev = current_ev;
-		current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe,  custom);
-            if (current_ev == previous_ev)
-#if WIRELESS_EXT >= 17
-                return -E2BIG;
-#else
-			    break;
-#endif
-        }
-#endif // IWEVGENIE //
-	}
-
-	data->length = current_ev - extra;
-    pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
-	DBGPRINT(RT_DEBUG_ERROR ,("===>rt_ioctl_giwscan. %d(%d) BSS returned, data->length = %d\n",i , pAdapter->ScanTab.BssNr, data->length));
-	return 0;
-}
-#endif
-
-int rt_ioctl_siwessid(struct net_device *dev,
-			 struct iw_request_info *info,
-			 struct iw_point *data, char *essid)
-{
-	PRTMP_ADAPTER pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-
-	//check if the interface is down
-    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-    {
-	DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-	return -ENETDOWN;
-    }
-
-	if (data->flags)
-	{
-		PSTRING	pSsidString = NULL;
-
-		// Includes null character.
-		if (data->length > (IW_ESSID_MAX_SIZE + 1))
-			return -E2BIG;
-
-		pSsidString = kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
-		if (pSsidString)
-        {
-			NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
-			NdisMoveMemory(pSsidString, essid, data->length);
-			if (Set_SSID_Proc(pAdapter, pSsidString) == FALSE)
-				return -EINVAL;
-		}
-		else
-			return -ENOMEM;
-		}
-	else
-    {
-		// ANY ssid
-		if (Set_SSID_Proc(pAdapter, "") == FALSE)
-			return -EINVAL;
-    }
-	return 0;
-}
-
-int rt_ioctl_giwessid(struct net_device *dev,
-			 struct iw_request_info *info,
-			 struct iw_point *data, char *essid)
-{
-	PRTMP_ADAPTER pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-
-	if (pAdapter == NULL)
-	{
-		/* if 1st open fail, pAd will be free;
-		   So the net_dev->priv will be NULL in 2rd open */
-		return -ENETDOWN;
-	}
-
-	data->flags = 1;
-    if (MONITOR_ON(pAdapter))
-    {
-        data->length  = 0;
-        return 0;
-    }
-
-	if (OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED))
-	{
-		DBGPRINT(RT_DEBUG_TRACE ,("MediaState is connected\n"));
-		data->length = pAdapter->CommonCfg.SsidLen;
-		memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
-	}
-	else
-	{//the ANY ssid was specified
-		data->length  = 0;
-		DBGPRINT(RT_DEBUG_TRACE ,("MediaState is not connected, ess\n"));
-	}
-
-	return 0;
-
-}
-
-int rt_ioctl_siwnickn(struct net_device *dev,
-			 struct iw_request_info *info,
-			 struct iw_point *data, char *nickname)
-{
-	PRTMP_ADAPTER pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-
-    //check if the interface is down
-    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-    {
-        DBGPRINT(RT_DEBUG_TRACE ,("INFO::Network is down!\n"));
-        return -ENETDOWN;
-    }
-
-	if (data->length > IW_ESSID_MAX_SIZE)
-		return -EINVAL;
-
-	memset(pAdapter->nickname, 0, IW_ESSID_MAX_SIZE + 1);
-	memcpy(pAdapter->nickname, nickname, data->length);
-
-
-	return 0;
-}
-
-int rt_ioctl_giwnickn(struct net_device *dev,
-			 struct iw_request_info *info,
-			 struct iw_point *data, char *nickname)
-{
-	PRTMP_ADAPTER pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-
-	if (pAdapter == NULL)
-	{
-		/* if 1st open fail, pAd will be free;
-		   So the net_dev->priv will be NULL in 2rd open */
-		return -ENETDOWN;
-	}
-
-	if (data->length > strlen((PSTRING) pAdapter->nickname) + 1)
-		data->length = strlen((PSTRING) pAdapter->nickname) + 1;
-	if (data->length > 0) {
-		memcpy(nickname, pAdapter->nickname, data->length-1);
-		nickname[data->length-1] = '\0';
-	}
-	return 0;
-}
-
-int rt_ioctl_siwrts(struct net_device *dev,
-		       struct iw_request_info *info,
-		       struct iw_param *rts, char *extra)
-{
-	PRTMP_ADAPTER pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-	u16 val;
-
-    //check if the interface is down
-    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-        return -ENETDOWN;
-    }
-
-	if (rts->disabled)
-		val = MAX_RTS_THRESHOLD;
-	else if (rts->value < 0 || rts->value > MAX_RTS_THRESHOLD)
-		return -EINVAL;
-	else if (rts->value == 0)
-	    val = MAX_RTS_THRESHOLD;
-	else
-		val = rts->value;
-
-	if (val != pAdapter->CommonCfg.RtsThreshold)
-		pAdapter->CommonCfg.RtsThreshold = val;
-
-	return 0;
-}
-
-int rt_ioctl_giwrts(struct net_device *dev,
-		       struct iw_request_info *info,
-		       struct iw_param *rts, char *extra)
-{
-	PRTMP_ADAPTER pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-
-	if (pAdapter == NULL)
-	{
-		/* if 1st open fail, pAd will be free;
-		   So the net_dev->priv will be NULL in 2rd open */
-		return -ENETDOWN;
-	}
-
-	//check if the interface is down
-	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	rts->value = pAdapter->CommonCfg.RtsThreshold;
-	rts->disabled = (rts->value == MAX_RTS_THRESHOLD);
-	rts->fixed = 1;
-
-	return 0;
-}
-
-int rt_ioctl_siwfrag(struct net_device *dev,
-			struct iw_request_info *info,
-			struct iw_param *frag, char *extra)
-{
-	PRTMP_ADAPTER pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-	u16 val;
-
-	//check if the interface is down
-	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	if (frag->disabled)
-		val = MAX_FRAG_THRESHOLD;
-	else if (frag->value >= MIN_FRAG_THRESHOLD || frag->value <= MAX_FRAG_THRESHOLD)
-        val = __cpu_to_le16(frag->value & ~0x1); /* even numbers only */
-	else if (frag->value == 0)
-	    val = MAX_FRAG_THRESHOLD;
-	else
-		return -EINVAL;
-
-	pAdapter->CommonCfg.FragmentThreshold = val;
-	return 0;
-}
-
-int rt_ioctl_giwfrag(struct net_device *dev,
-			struct iw_request_info *info,
-			struct iw_param *frag, char *extra)
-{
-	PRTMP_ADAPTER pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-
-	if (pAdapter == NULL)
-	{
-		/* if 1st open fail, pAd will be free;
-		   So the net_dev->priv will be NULL in 2rd open */
-		return -ENETDOWN;
-	}
-
-	//check if the interface is down
-	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	frag->value = pAdapter->CommonCfg.FragmentThreshold;
-	frag->disabled = (frag->value == MAX_FRAG_THRESHOLD);
-	frag->fixed = 1;
-
-	return 0;
-}
-
-#define MAX_WEP_KEY_SIZE 13
-#define MIN_WEP_KEY_SIZE 5
-int rt_ioctl_siwencode(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_point *erq, char *extra)
-{
-	PRTMP_ADAPTER pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-
-	//check if the interface is down
-	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	if ((erq->length == 0) &&
-        (erq->flags & IW_ENCODE_DISABLED))
-	{
-		pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
-		pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
-		pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
-        pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
-        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
-        goto done;
-	}
-	else if (erq->flags & IW_ENCODE_RESTRICTED || erq->flags & IW_ENCODE_OPEN)
-	{
-	    //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
-		STA_PORT_SECURED(pAdapter);
-		pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
-		pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
-		pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
-        pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
-		if (erq->flags & IW_ENCODE_RESTRICTED)
-			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
-	else
-			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
-	}
-
-    if (erq->length > 0)
-	{
-		int keyIdx = (erq->flags & IW_ENCODE_INDEX) - 1;
-		/* Check the size of the key */
-		if (erq->length > MAX_WEP_KEY_SIZE)
-		{
-			return -EINVAL;
-		}
-		/* Check key index */
-		if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
-        {
-            DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::Wrong keyIdx=%d! Using default key instead (%d)\n",
-                                        keyIdx, pAdapter->StaCfg.DefaultKeyId));
-
-            //Using default key
-			keyIdx = pAdapter->StaCfg.DefaultKeyId;
-        }
-		else
-			pAdapter->StaCfg.DefaultKeyId = keyIdx;
-
-        NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,  16);
-
-		if (erq->length == MAX_WEP_KEY_SIZE)
-        {
-			pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
-            pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
-		}
-		else if (erq->length == MIN_WEP_KEY_SIZE)
-        {
-            pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
-            pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
-		}
-		else
-			/* Disable the key */
-			pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
-
-		/* Check if the key is not marked as invalid */
-		if(!(erq->flags & IW_ENCODE_NOKEY))
-		{
-			/* Copy the key in the driver */
-			NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, extra, erq->length);
-        }
-	}
-    else
-			{
-		/* Do we want to just set the transmit key index ? */
-		int index = (erq->flags & IW_ENCODE_INDEX) - 1;
-		if ((index >= 0) && (index < 4))
-        {
-			pAdapter->StaCfg.DefaultKeyId = index;
-            }
-        else
-			/* Don't complain if only change the mode */
-		if (!(erq->flags & IW_ENCODE_MODE))
-			return -EINVAL;
-	}
-
-done:
-    DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::erq->flags=%x\n",erq->flags));
-	DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::AuthMode=%x\n",pAdapter->StaCfg.AuthMode));
-	DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::DefaultKeyId=%x, KeyLen = %d\n",pAdapter->StaCfg.DefaultKeyId , pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen));
-	DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::WepStatus=%x\n",pAdapter->StaCfg.WepStatus));
-	return 0;
-}
-
-int
-rt_ioctl_giwencode(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_point *erq, char *key)
-{
-	int kid;
-	PRTMP_ADAPTER pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-
-	if (pAdapter == NULL)
-	{
-		/* if 1st open fail, pAd will be free;
-		   So the net_dev->priv will be NULL in 2rd open */
-		return -ENETDOWN;
-	}
-
-	//check if the interface is down
-	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-	return -ENETDOWN;
-	}
-
-	kid = erq->flags & IW_ENCODE_INDEX;
-	DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_giwencode %d\n", erq->flags & IW_ENCODE_INDEX));
-
-	if (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled)
-	{
-		erq->length = 0;
-		erq->flags = IW_ENCODE_DISABLED;
-	}
-	else if ((kid > 0) && (kid <=4))
-	{
-		// copy wep key
-		erq->flags = kid ;			/* NB: base 1 */
-		if (erq->length > pAdapter->SharedKey[BSS0][kid-1].KeyLen)
-			erq->length = pAdapter->SharedKey[BSS0][kid-1].KeyLen;
-		memcpy(key, pAdapter->SharedKey[BSS0][kid-1].Key, erq->length);
-		//if ((kid == pAdapter->PortCfg.DefaultKeyId))
-		//erq->flags |= IW_ENCODE_ENABLED;	/* XXX */
-		if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
-			erq->flags |= IW_ENCODE_RESTRICTED;		/* XXX */
-		else
-			erq->flags |= IW_ENCODE_OPEN;		/* XXX */
-
-	}
-	else if (kid == 0)
-	{
-		if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
-			erq->flags |= IW_ENCODE_RESTRICTED;		/* XXX */
-		else
-			erq->flags |= IW_ENCODE_OPEN;		/* XXX */
-		erq->length = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
-		memcpy(key, pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, erq->length);
-		// copy default key ID
-		if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
-			erq->flags |= IW_ENCODE_RESTRICTED;		/* XXX */
-		else
-			erq->flags |= IW_ENCODE_OPEN;		/* XXX */
-		erq->flags = pAdapter->StaCfg.DefaultKeyId + 1;			/* NB: base 1 */
-		erq->flags |= IW_ENCODE_ENABLED;	/* XXX */
-	}
-
-	return 0;
-
-}
-
-static int
-rt_ioctl_setparam(struct net_device *dev, struct iw_request_info *info,
-			 void *w, char *extra)
-{
-	PRTMP_ADAPTER pAdapter;
-	POS_COOKIE pObj;
-	PSTRING this_char = extra;
-	PSTRING value;
-	int  Status=0;
-
-	pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-	if (pAdapter == NULL)
-	{
-		/* if 1st open fail, pAd will be free;
-		   So the net_dev->priv will be NULL in 2rd open */
-		return -ENETDOWN;
-	}
-
-	pObj = (POS_COOKIE) pAdapter->OS_Cookie;
-	{
-		pObj->ioctl_if_type = INT_MAIN;
-        pObj->ioctl_if = MAIN_MBSSID;
-	}
-
-	//check if the interface is down
-	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-			return -ENETDOWN;
-	}
-
-	if (!*this_char)
-		return -EINVAL;
-
-	if ((value = rtstrchr(this_char, '=')) != NULL)
-	    *value++ = 0;
-
-	if (!value && (strcmp(this_char, "SiteSurvey") != 0))
-	    return -EINVAL;
-	else
-		goto SET_PROC;
-
-	// reject setting nothing besides ANY ssid(ssidLen=0)
-    if (!*value && (strcmp(this_char, "SSID") != 0))
-        return -EINVAL;
-
-SET_PROC:
-	for (PRTMP_PRIVATE_SET_PROC = RTMP_PRIVATE_SUPPORT_PROC; PRTMP_PRIVATE_SET_PROC->name; PRTMP_PRIVATE_SET_PROC++)
-	{
-	    if (strcmp(this_char, PRTMP_PRIVATE_SET_PROC->name) == 0)
-	    {
-	        if(!PRTMP_PRIVATE_SET_PROC->set_proc(pAdapter, value))
-	        {	//FALSE:Set private failed then return Invalid argument
-			    Status = -EINVAL;
-	        }
-		    break;	//Exit for loop.
-	    }
-	}
-
-	if(PRTMP_PRIVATE_SET_PROC->name == NULL)
-	{  //Not found argument
-	    Status = -EINVAL;
-	    DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_setparam:: (iwpriv) Not Support Set Command [%s=%s]\n", this_char, value));
-	}
-
-    return Status;
-}
-
-
-static int
-rt_private_get_statistics(struct net_device *dev, struct iw_request_info *info,
-		struct iw_point *wrq, char *extra)
-{
-	INT				Status = 0;
-    PRTMP_ADAPTER   pAd = RTMP_OS_NETDEV_GET_PRIV(dev);
-
-    if (extra == NULL)
-    {
-        wrq->length = 0;
-        return -EIO;
-    }
-
-    memset(extra, 0x00, IW_PRIV_SIZE_MASK);
-    sprintf(extra, "\n\n");
-
-#ifdef RALINK_ATE
-	if (ATE_ON(pAd))
-	{
-	    sprintf(extra+strlen(extra), "Tx success                      = %ld\n", (ULONG)pAd->ate.TxDoneCount);
-	    //sprintf(extra+strlen(extra), "Tx success without retry        = %ld\n", (ULONG)pAd->ate.TxDoneCount);
-	}
-	else
-#endif // RALINK_ATE //
-	{
-    sprintf(extra+strlen(extra), "Tx success                      = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart);
-    sprintf(extra+strlen(extra), "Tx success without retry        = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart - (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
-	}
-    sprintf(extra+strlen(extra), "Tx success after retry          = %ld\n", (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
-    sprintf(extra+strlen(extra), "Tx fail to Rcv ACK after retry  = %ld\n", (ULONG)pAd->WlanCounters.FailedCount.QuadPart);
-    sprintf(extra+strlen(extra), "RTS Success Rcv CTS             = %ld\n", (ULONG)pAd->WlanCounters.RTSSuccessCount.QuadPart);
-    sprintf(extra+strlen(extra), "RTS Fail Rcv CTS                = %ld\n", (ULONG)pAd->WlanCounters.RTSFailureCount.QuadPart);
-
-    sprintf(extra+strlen(extra), "Rx success                      = %ld\n", (ULONG)pAd->WlanCounters.ReceivedFragmentCount.QuadPart);
-    sprintf(extra+strlen(extra), "Rx with CRC                     = %ld\n", (ULONG)pAd->WlanCounters.FCSErrorCount.QuadPart);
-    sprintf(extra+strlen(extra), "Rx drop due to out of resource  = %ld\n", (ULONG)pAd->Counters8023.RxNoBuffer);
-    sprintf(extra+strlen(extra), "Rx duplicate frame              = %ld\n", (ULONG)pAd->WlanCounters.FrameDuplicateCount.QuadPart);
-
-    sprintf(extra+strlen(extra), "False CCA (one second)          = %ld\n", (ULONG)pAd->RalinkCounters.OneSecFalseCCACnt);
-
-#ifdef RALINK_ATE
-	if (ATE_ON(pAd))
-	{
-		if (pAd->ate.RxAntennaSel == 0)
-		{
-		sprintf(extra+strlen(extra), "RSSI-A                          = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
-			sprintf(extra+strlen(extra), "RSSI-B (if available)           = %ld\n", (LONG)(pAd->ate.LastRssi1 - pAd->BbpRssiToDbmDelta));
-			sprintf(extra+strlen(extra), "RSSI-C (if available)           = %ld\n\n", (LONG)(pAd->ate.LastRssi2 - pAd->BbpRssiToDbmDelta));
-		}
-		else
-		{
-		sprintf(extra+strlen(extra), "RSSI                            = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
-		}
-	}
-	else
-#endif // RALINK_ATE //
-	{
-	sprintf(extra+strlen(extra), "RSSI-A                          = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi0 - pAd->BbpRssiToDbmDelta));
-        sprintf(extra+strlen(extra), "RSSI-B (if available)           = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi1 - pAd->BbpRssiToDbmDelta));
-        sprintf(extra+strlen(extra), "RSSI-C (if available)           = %ld\n\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi2 - pAd->BbpRssiToDbmDelta));
-	}
-#ifdef WPA_SUPPLICANT_SUPPORT
-    sprintf(extra+strlen(extra), "WpaSupplicantUP                 = %d\n\n", pAd->StaCfg.WpaSupplicantUP);
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-
-
-    wrq->length = strlen(extra) + 1; // 1: size of '\0'
-    DBGPRINT(RT_DEBUG_TRACE, ("<== rt_private_get_statistics, wrq->length = %d\n", wrq->length));
-
-    return Status;
-}
-
-#ifdef DOT11_N_SUPPORT
-void	getBaInfo(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			pOutBuf)
-{
-	INT i, j;
-	BA_ORI_ENTRY *pOriBAEntry;
-	BA_REC_ENTRY *pRecBAEntry;
-
-	for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
-	{
-		PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
-		if (((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
-			|| (pEntry->ValidAsWDS) || (pEntry->ValidAsMesh))
-		{
-			sprintf(pOutBuf, "%s\n%02X:%02X:%02X:%02X:%02X:%02X (Aid = %d) (AP) -\n",
-                pOutBuf,
-				pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
-				pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5], pEntry->Aid);
-
-			sprintf(pOutBuf, "%s[Recipient]\n", pOutBuf);
-			for (j=0; j < NUM_OF_TID; j++)
-			{
-				if (pEntry->BARecWcidArray[j] != 0)
-				{
-					pRecBAEntry =&pAd->BATable.BARecEntry[pEntry->BARecWcidArray[j]];
-					sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, LastIndSeq=%d, ReorderingPkts=%d\n", pOutBuf, j, pRecBAEntry->BAWinSize, pRecBAEntry->LastIndSeq, pRecBAEntry->list.qlen);
-				}
-			}
-			sprintf(pOutBuf, "%s\n", pOutBuf);
-
-			sprintf(pOutBuf, "%s[Originator]\n", pOutBuf);
-			for (j=0; j < NUM_OF_TID; j++)
-			{
-				if (pEntry->BAOriWcidArray[j] != 0)
-				{
-					pOriBAEntry =&pAd->BATable.BAOriEntry[pEntry->BAOriWcidArray[j]];
-					sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, StartSeq=%d, CurTxSeq=%d\n", pOutBuf, j, pOriBAEntry->BAWinSize, pOriBAEntry->Sequence, pEntry->TxSeq[j]);
-				}
-			}
-			sprintf(pOutBuf, "%s\n\n", pOutBuf);
-		}
-        if (strlen(pOutBuf) > (IW_PRIV_SIZE_MASK - 30))
-                break;
-	}
-
-	return;
-}
-#endif // DOT11_N_SUPPORT //
-
-static int
-rt_private_show(struct net_device *dev, struct iw_request_info *info,
-		struct iw_point *wrq, PSTRING extra)
-{
-	INT				Status = 0;
-	PRTMP_ADAPTER   pAd;
-	POS_COOKIE		pObj;
-	u32             subcmd = wrq->flags;
-
-	pAd = RTMP_OS_NETDEV_GET_PRIV(dev);
-	if (pAd == NULL)
-	{
-		/* if 1st open fail, pAd will be free;
-		   So the net_dev->priv will be NULL in 2rd open */
-		return -ENETDOWN;
-	}
-
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-	if (extra == NULL)
-	{
-		wrq->length = 0;
-		return -EIO;
-	}
-	memset(extra, 0x00, IW_PRIV_SIZE_MASK);
-
-	{
-		pObj->ioctl_if_type = INT_MAIN;
-		pObj->ioctl_if = MAIN_MBSSID;
-	}
-
-    switch(subcmd)
-    {
-
-        case SHOW_CONN_STATUS:
-            if (MONITOR_ON(pAd))
-            {
-#ifdef DOT11_N_SUPPORT
-                if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
-                    pAd->CommonCfg.RegTransmitSetting.field.BW)
-                    sprintf(extra, "Monitor Mode(CentralChannel %d)\n", pAd->CommonCfg.CentralChannel);
-                else
-#endif // DOT11_N_SUPPORT //
-                    sprintf(extra, "Monitor Mode(Channel %d)\n", pAd->CommonCfg.Channel);
-            }
-            else
-            {
-                if (pAd->IndicateMediaState == NdisMediaStateConnected)
-		{
-		    if (INFRA_ON(pAd))
-                    {
-                    sprintf(extra, "Connected(AP: %s[%02X:%02X:%02X:%02X:%02X:%02X])\n",
-                                    pAd->CommonCfg.Ssid,
-                                    pAd->CommonCfg.Bssid[0],
-                                    pAd->CommonCfg.Bssid[1],
-                                    pAd->CommonCfg.Bssid[2],
-                                    pAd->CommonCfg.Bssid[3],
-                                    pAd->CommonCfg.Bssid[4],
-                                    pAd->CommonCfg.Bssid[5]);
-			DBGPRINT(RT_DEBUG_TRACE ,("Ssid=%s ,Ssidlen = %d\n",pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen));
-		}
-                    else if (ADHOC_ON(pAd))
-                        sprintf(extra, "Connected\n");
-		}
-		else
-		{
-		    sprintf(extra, "Disconnected\n");
-			DBGPRINT(RT_DEBUG_TRACE ,("ConnStatus is not connected\n"));
-		}
-            }
-            wrq->length = strlen(extra) + 1; // 1: size of '\0'
-            break;
-        case SHOW_DRVIER_VERION:
-            sprintf(extra, "Driver version-%s, %s %s\n", STA_DRIVER_VERSION, __DATE__, __TIME__ );
-            wrq->length = strlen(extra) + 1; // 1: size of '\0'
-            break;
-#ifdef DOT11_N_SUPPORT
-        case SHOW_BA_INFO:
-            getBaInfo(pAd, extra);
-            wrq->length = strlen(extra) + 1; // 1: size of '\0'
-            break;
-#endif // DOT11_N_SUPPORT //
-		case SHOW_DESC_INFO:
-			{
-				Show_DescInfo_Proc(pAd, NULL);
-				wrq->length = 0; // 1: size of '\0'
-			}
-			break;
-        case RAIO_OFF:
-            if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-            {
-                if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)
-		        {
-		            RTMP_MLME_RESET_STATE_MACHINE(pAd);
-		            DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
-		        }
-            }
-            pAd->StaCfg.bSwRadio = FALSE;
-            if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
-            {
-                pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
-                if (pAd->StaCfg.bRadio == FALSE)
-                {
-                    MlmeRadioOff(pAd);
-                    // Update extra information
-					pAd->ExtraInfo = SW_RADIO_OFF;
-                }
-            }
-            sprintf(extra, "Radio Off\n");
-            wrq->length = strlen(extra) + 1; // 1: size of '\0'
-            break;
-        case RAIO_ON:
-            pAd->StaCfg.bSwRadio = TRUE;
-            //if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
-            {
-                pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
-                if (pAd->StaCfg.bRadio == TRUE)
-                {
-                    MlmeRadioOn(pAd);
-                    // Update extra information
-					pAd->ExtraInfo = EXTRA_INFO_CLEAR;
-                }
-            }
-            sprintf(extra, "Radio On\n");
-            wrq->length = strlen(extra) + 1; // 1: size of '\0'
-            break;
-
-
-#ifdef QOS_DLS_SUPPORT
-		case SHOW_DLS_ENTRY_INFO:
-			{
-				Set_DlsEntryInfo_Display_Proc(pAd, NULL);
-				wrq->length = 0; // 1: size of '\0'
-			}
-			break;
-#endif // QOS_DLS_SUPPORT //
-
-		case SHOW_CFG_VALUE:
-			{
-				Status = RTMPShowCfgValue(pAd, (PSTRING) wrq->pointer, extra);
-				if (Status == 0)
-					wrq->length = strlen(extra) + 1; // 1: size of '\0'
-			}
-			break;
-		case SHOW_ADHOC_ENTRY_INFO:
-			Show_Adhoc_MacTable_Proc(pAd, extra);
-			wrq->length = strlen(extra) + 1; // 1: size of '\0'
-			break;
-        default:
-            DBGPRINT(RT_DEBUG_TRACE, ("%s - unknow subcmd = %d\n", __FUNCTION__, subcmd));
-            break;
-    }
-
-    return Status;
-}
-
-#ifdef SIOCSIWMLME
-int rt_ioctl_siwmlme(struct net_device *dev,
-			   struct iw_request_info *info,
-			   union iwreq_data *wrqu,
-			   char *extra)
-{
-	PRTMP_ADAPTER   pAd = RTMP_OS_NETDEV_GET_PRIV(dev);
-	struct iw_mlme *pMlme = (struct iw_mlme *)wrqu->data.pointer;
-	MLME_QUEUE_ELEM				MsgElem;
-	MLME_DISASSOC_REQ_STRUCT	DisAssocReq;
-	MLME_DEAUTH_REQ_STRUCT      DeAuthReq;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __FUNCTION__));
-
-	if (pMlme == NULL)
-		return -EINVAL;
-
-	switch(pMlme->cmd)
-	{
-#ifdef IW_MLME_DEAUTH
-		case IW_MLME_DEAUTH:
-			DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DEAUTH\n", __FUNCTION__));
-			COPY_MAC_ADDR(DeAuthReq.Addr, pAd->CommonCfg.Bssid);
-			DeAuthReq.Reason = pMlme->reason_code;
-			MsgElem.MsgLen = sizeof(MLME_DEAUTH_REQ_STRUCT);
-			NdisMoveMemory(MsgElem.Msg, &DeAuthReq, sizeof(MLME_DEAUTH_REQ_STRUCT));
-			MlmeDeauthReqAction(pAd, &MsgElem);
-			if (INFRA_ON(pAd))
-			{
-			    LinkDown(pAd, FALSE);
-			    pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-			}
-			break;
-#endif // IW_MLME_DEAUTH //
-#ifdef IW_MLME_DISASSOC
-		case IW_MLME_DISASSOC:
-			DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DISASSOC\n", __FUNCTION__));
-			COPY_MAC_ADDR(DisAssocReq.Addr, pAd->CommonCfg.Bssid);
-			DisAssocReq.Reason =  pMlme->reason_code;
-
-			MsgElem.Machine = ASSOC_STATE_MACHINE;
-			MsgElem.MsgType = MT2_MLME_DISASSOC_REQ;
-			MsgElem.MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
-			NdisMoveMemory(MsgElem.Msg, &DisAssocReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
-
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
-			MlmeDisassocReqAction(pAd, &MsgElem);
-			break;
-#endif // IW_MLME_DISASSOC //
-		default:
-			DBGPRINT(RT_DEBUG_TRACE, ("====> %s - Unknow Command\n", __FUNCTION__));
-			break;
-	}
-
-	return 0;
-}
-#endif // SIOCSIWMLME //
-
-#if WIRELESS_EXT > 17
-int rt_ioctl_siwauth(struct net_device *dev,
-			  struct iw_request_info *info,
-			  union iwreq_data *wrqu, char *extra)
-{
-	PRTMP_ADAPTER   pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-	struct iw_param *param = &wrqu->param;
-
-    //check if the interface is down
-	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-	return -ENETDOWN;
-	}
-	switch (param->flags & IW_AUTH_INDEX) {
-	case IW_AUTH_WPA_VERSION:
-            if (param->value == IW_AUTH_WPA_VERSION_WPA)
-            {
-                pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
-				if (pAdapter->StaCfg.BssType == BSS_ADHOC)
-					pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
-            }
-            else if (param->value == IW_AUTH_WPA_VERSION_WPA2)
-                pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
-
-            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __FUNCTION__, param->value));
-            break;
-	case IW_AUTH_CIPHER_PAIRWISE:
-            if (param->value == IW_AUTH_CIPHER_NONE)
-            {
-                pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
-                pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
-                pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
-            }
-            else if (param->value == IW_AUTH_CIPHER_WEP40 ||
-                     param->value == IW_AUTH_CIPHER_WEP104)
-            {
-                pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
-                pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
-                pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
-#ifdef WPA_SUPPLICANT_SUPPORT
-                pAdapter->StaCfg.IEEE8021X = FALSE;
-#endif // WPA_SUPPLICANT_SUPPORT //
-            }
-            else if (param->value == IW_AUTH_CIPHER_TKIP)
-            {
-                pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
-                pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
-                pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
-            }
-            else if (param->value == IW_AUTH_CIPHER_CCMP)
-            {
-                pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
-                pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
-                pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
-            }
-            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_PAIRWISE - param->value = %d!\n", __FUNCTION__, param->value));
-            break;
-	case IW_AUTH_CIPHER_GROUP:
-            if (param->value == IW_AUTH_CIPHER_NONE)
-            {
-                pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
-            }
-            else if (param->value == IW_AUTH_CIPHER_WEP40 ||
-                     param->value == IW_AUTH_CIPHER_WEP104)
-            {
-                pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
-            }
-            else if (param->value == IW_AUTH_CIPHER_TKIP)
-            {
-                pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
-            }
-            else if (param->value == IW_AUTH_CIPHER_CCMP)
-            {
-                pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
-            }
-            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_GROUP - param->value = %d!\n", __FUNCTION__, param->value));
-            break;
-	case IW_AUTH_KEY_MGMT:
-            if (param->value == IW_AUTH_KEY_MGMT_802_1X)
-            {
-                if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
-                {
-                    pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
-#ifdef WPA_SUPPLICANT_SUPPORT
-                    pAdapter->StaCfg.IEEE8021X = FALSE;
-#endif // WPA_SUPPLICANT_SUPPORT //
-                }
-                else if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
-                {
-                    pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
-#ifdef WPA_SUPPLICANT_SUPPORT
-                    pAdapter->StaCfg.IEEE8021X = FALSE;
-#endif // WPA_SUPPLICANT_SUPPORT //
-                }
-#ifdef WPA_SUPPLICANT_SUPPORT
-                else
-                    // WEP 1x
-                    pAdapter->StaCfg.IEEE8021X = TRUE;
-#endif // WPA_SUPPLICANT_SUPPORT //
-            }
-            else if (param->value == 0)
-            {
-                //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
-				STA_PORT_SECURED(pAdapter);
-            }
-            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_KEY_MGMT - param->value = %d!\n", __FUNCTION__, param->value));
-            break;
-	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
-            break;
-	case IW_AUTH_PRIVACY_INVOKED:
-            /*if (param->value == 0)
-			{
-                pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
-                pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
-                pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
-                pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
-		    pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
-            }*/
-            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_PRIVACY_INVOKED - param->value = %d!\n", __FUNCTION__, param->value));
-		break;
-	case IW_AUTH_DROP_UNENCRYPTED:
-            if (param->value != 0)
-                pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-			else
-			{
-                //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
-				STA_PORT_SECURED(pAdapter);
-			}
-            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __FUNCTION__, param->value));
-		break;
-	case IW_AUTH_80211_AUTH_ALG:
-			if (param->value & IW_AUTH_ALG_SHARED_KEY)
-            {
-				pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
-			}
-            else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
-            {
-				pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
-			}
-            else
-				return -EINVAL;
-            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_80211_AUTH_ALG - param->value = %d!\n", __FUNCTION__, param->value));
-			break;
-	case IW_AUTH_WPA_ENABLED:
-		DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_ENABLED - Driver supports WPA!(param->value = %d)\n", __FUNCTION__, param->value));
-		break;
-	default:
-		return -EOPNOTSUPP;
-}
-
-	return 0;
-}
-
-int rt_ioctl_giwauth(struct net_device *dev,
-			       struct iw_request_info *info,
-			       union iwreq_data *wrqu, char *extra)
-{
-	PRTMP_ADAPTER   pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-	struct iw_param *param = &wrqu->param;
-
-    //check if the interface is down
-	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-    {
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-	return -ENETDOWN;
-    }
-
-	switch (param->flags & IW_AUTH_INDEX) {
-	case IW_AUTH_DROP_UNENCRYPTED:
-        param->value = (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled) ? 0 : 1;
-		break;
-
-	case IW_AUTH_80211_AUTH_ALG:
-        param->value = (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared) ? IW_AUTH_ALG_SHARED_KEY : IW_AUTH_ALG_OPEN_SYSTEM;
-		break;
-
-	case IW_AUTH_WPA_ENABLED:
-		param->value = (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) ? 1 : 0;
-		break;
-
-	default:
-		return -EOPNOTSUPP;
-	}
-    DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_giwauth::param->value = %d!\n", param->value));
-	return 0;
-}
-
-void fnSetCipherKey(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  INT             keyIdx,
-    IN  UCHAR           CipherAlg,
-    IN  BOOLEAN         bGTK,
-    IN  struct iw_encode_ext *ext)
-{
-    NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
-    pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK;
-    NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, LEN_TKIP_EK);
-    NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].TxMic, ext->key + LEN_TKIP_EK, LEN_TKIP_TXMICK);
-    NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].RxMic, ext->key + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
-    pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CipherAlg;
-
-    // Update group key information to ASIC Shared Key Table
-	AsicAddSharedKeyEntry(pAdapter,
-						  BSS0,
-						  keyIdx,
-						  pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
-						  pAdapter->SharedKey[BSS0][keyIdx].Key,
-						  pAdapter->SharedKey[BSS0][keyIdx].TxMic,
-						  pAdapter->SharedKey[BSS0][keyIdx].RxMic);
-
-    if (bGTK)
-        // Update ASIC WCID attribute table and IVEIV table
-	RTMPAddWcidAttributeEntry(pAdapter,
-							  BSS0,
-							  keyIdx,
-							  pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
-							  NULL);
-    else
-        // Update ASIC WCID attribute table and IVEIV table
-	RTMPAddWcidAttributeEntry(pAdapter,
-							  BSS0,
-							  keyIdx,
-							  pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
-							  &pAdapter->MacTab.Content[BSSID_WCID]);
-}
-
-int rt_ioctl_siwencodeext(struct net_device *dev,
-			   struct iw_request_info *info,
-			   union iwreq_data *wrqu,
-			   char *extra)
-			{
-    PRTMP_ADAPTER   pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-	struct iw_point *encoding = &wrqu->encoding;
-	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-    int keyIdx, alg = ext->alg;
-
-    //check if the interface is down
-	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-	return -ENETDOWN;
-	}
-
-    if (encoding->flags & IW_ENCODE_DISABLED)
-	{
-        keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
-        // set BSSID wcid entry of the Pair-wise Key table as no-security mode
-	    AsicRemovePairwiseKeyEntry(pAdapter, BSS0, BSSID_WCID);
-        pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
-		pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_NONE;
-		AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)keyIdx);
-        NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
-        DBGPRINT(RT_DEBUG_TRACE, ("%s::Remove all keys!(encoding->flags = %x)\n", __FUNCTION__, encoding->flags));
-    }
-					else
-    {
-        // Get Key Index and convet to our own defined key index
-	keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
-	if((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
-		return -EINVAL;
-
-        if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
-        {
-            pAdapter->StaCfg.DefaultKeyId = keyIdx;
-            DBGPRINT(RT_DEBUG_TRACE, ("%s::DefaultKeyId = %d\n", __FUNCTION__, pAdapter->StaCfg.DefaultKeyId));
-        }
-
-        switch (alg) {
-		case IW_ENCODE_ALG_NONE:
-                DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_NONE\n", __FUNCTION__));
-			break;
-		case IW_ENCODE_ALG_WEP:
-                DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_WEP - ext->key_len = %d, keyIdx = %d\n", __FUNCTION__, ext->key_len, keyIdx));
-			if (ext->key_len == MAX_WEP_KEY_SIZE)
-                {
-				pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
-                    pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
-				}
-			else if (ext->key_len == MIN_WEP_KEY_SIZE)
-                {
-                    pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
-                    pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
-			}
-			else
-                    return -EINVAL;
-
-                NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,  16);
-			    NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, ext->key_len);
-
-				if (pAdapter->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled ||
-					pAdapter->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
-				{
-					// Set Group key material to Asic
-					AsicAddSharedKeyEntry(pAdapter, BSS0, keyIdx, pAdapter->SharedKey[BSS0][keyIdx].CipherAlg, pAdapter->SharedKey[BSS0][keyIdx].Key, NULL, NULL);
-					// Update WCID attribute table and IVEIV table for this group key table
-					RTMPAddWcidAttributeEntry(pAdapter, BSS0, keyIdx, pAdapter->SharedKey[BSS0][keyIdx].CipherAlg, NULL);
-					STA_PORT_SECURED(pAdapter);
-					// Indicate Connected for GUI
-					pAdapter->IndicateMediaState = NdisMediaStateConnected;
-				}
-			break;
-            case IW_ENCODE_ALG_TKIP:
-                DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n", __FUNCTION__, keyIdx, ext->key_len));
-                if (ext->key_len == 32)
-                {
-                    if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
-                    {
-                        fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, FALSE, ext);
-                        if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
-                        {
-                            //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
-                            STA_PORT_SECURED(pAdapter);
-                            pAdapter->IndicateMediaState = NdisMediaStateConnected;
-                        }
-		}
-                    else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
-                    {
-                        fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, TRUE, ext);
-
-                        // set 802.1x port control
-		        //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
-		        STA_PORT_SECURED(pAdapter);
-		        pAdapter->IndicateMediaState = NdisMediaStateConnected;
-                    }
-                }
-                else
-                    return -EINVAL;
-                break;
-            case IW_ENCODE_ALG_CCMP:
-                if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
-		{
-                    fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, FALSE, ext);
-                    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
-			//pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
-			STA_PORT_SECURED(pAdapter);
-			pAdapter->IndicateMediaState = NdisMediaStateConnected;
-                }
-                else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
-                {
-                    fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, TRUE, ext);
-
-                    // set 802.1x port control
-		        //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
-		        STA_PORT_SECURED(pAdapter);
-		        pAdapter->IndicateMediaState = NdisMediaStateConnected;
-                }
-                break;
-		default:
-			return -EINVAL;
-		}
-    }
-
-    return 0;
-}
-
-int
-rt_ioctl_giwencodeext(struct net_device *dev,
-			  struct iw_request_info *info,
-			  union iwreq_data *wrqu, char *extra)
-{
-	PRTMP_ADAPTER pAd = RTMP_OS_NETDEV_GET_PRIV(dev);
-	PCHAR pKey = NULL;
-	struct iw_point *encoding = &wrqu->encoding;
-	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-	int idx, max_key_len;
-
-	DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_giwencodeext\n"));
-
-	max_key_len = encoding->length - sizeof(*ext);
-	if (max_key_len < 0)
-		return -EINVAL;
-
-	idx = encoding->flags & IW_ENCODE_INDEX;
-	if (idx)
-	{
-		if (idx < 1 || idx > 4)
-			return -EINVAL;
-		idx--;
-
-		if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
-			(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled))
-		{
-			if (idx != pAd->StaCfg.DefaultKeyId)
-			{
-				ext->key_len = 0;
-				return 0;
-			}
-		}
-	}
-	else
-		idx = pAd->StaCfg.DefaultKeyId;
-
-	encoding->flags = idx + 1;
-	memset(ext, 0, sizeof(*ext));
-
-	ext->key_len = 0;
-	switch(pAd->StaCfg.WepStatus) {
-		case Ndis802_11WEPDisabled:
-			ext->alg = IW_ENCODE_ALG_NONE;
-			encoding->flags |= IW_ENCODE_DISABLED;
-			break;
-		case Ndis802_11WEPEnabled:
-			ext->alg = IW_ENCODE_ALG_WEP;
-			if (pAd->SharedKey[BSS0][idx].KeyLen > max_key_len)
-				return -E2BIG;
-			else
-			{
-				ext->key_len = pAd->SharedKey[BSS0][idx].KeyLen;
-				pKey = (PCHAR)&(pAd->SharedKey[BSS0][idx].Key[0]);
-			}
-			break;
-		case Ndis802_11Encryption2Enabled:
-		case Ndis802_11Encryption3Enabled:
-			if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
-				ext->alg = IW_ENCODE_ALG_TKIP;
-			else
-				ext->alg = IW_ENCODE_ALG_CCMP;
-
-			if (max_key_len < 32)
-				return -E2BIG;
-			else
-			{
-				ext->key_len = 32;
-				pKey = (PCHAR)&pAd->StaCfg.PMK[0];
-			}
-			break;
-		default:
-			return -EINVAL;
-	}
-
-	if (ext->key_len && pKey)
-	{
-		encoding->flags |= IW_ENCODE_ENABLED;
-		memcpy(ext->key, pKey, ext->key_len);
-	}
-
-	return 0;
-}
-
-#ifdef SIOCSIWGENIE
-int rt_ioctl_siwgenie(struct net_device *dev,
-			  struct iw_request_info *info,
-			  union iwreq_data *wrqu, char *extra)
-{
-	PRTMP_ADAPTER   pAd = RTMP_OS_NETDEV_GET_PRIV(dev);
-
-	DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_siwgenie\n"));
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-	pAd->StaCfg.bRSN_IE_FromWpaSupplicant = FALSE;
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-	if (wrqu->data.length > MAX_LEN_OF_RSNIE ||
-	    (wrqu->data.length && extra == NULL))
-		return -EINVAL;
-
-	if (wrqu->data.length)
-	{
-		pAd->StaCfg.RSNIE_Len = wrqu->data.length;
-		NdisMoveMemory(&pAd->StaCfg.RSN_IE[0], extra, pAd->StaCfg.RSNIE_Len);
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-		pAd->StaCfg.bRSN_IE_FromWpaSupplicant = TRUE;
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-	}
-	else
-	{
-		pAd->StaCfg.RSNIE_Len = 0;
-		NdisZeroMemory(&pAd->StaCfg.RSN_IE[0], MAX_LEN_OF_RSNIE);
-	}
-
-	return 0;
-}
-#endif // SIOCSIWGENIE //
-
-int rt_ioctl_giwgenie(struct net_device *dev,
-			       struct iw_request_info *info,
-			       union iwreq_data *wrqu, char *extra)
-{
-	PRTMP_ADAPTER   pAd = RTMP_OS_NETDEV_GET_PRIV(dev);
-
-	if ((pAd->StaCfg.RSNIE_Len == 0) ||
-		(pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA))
-	{
-		wrqu->data.length = 0;
-		return 0;
-	}
-
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-#ifdef SIOCSIWGENIE
-	if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
-	{
-	if (wrqu->data.length < pAd->StaCfg.RSNIE_Len)
-		return -E2BIG;
-
-	wrqu->data.length = pAd->StaCfg.RSNIE_Len;
-	memcpy(extra, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
-	}
-	else
-#endif // SIOCSIWGENIE //
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-	{
-		UCHAR RSNIe = IE_WPA;
-
-		if (wrqu->data.length < (pAd->StaCfg.RSNIE_Len + 2)) // ID, Len
-			return -E2BIG;
-		wrqu->data.length = pAd->StaCfg.RSNIE_Len + 2;
-
-		if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
-            (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
-			RSNIe = IE_RSN;
-
-		extra[0] = (char)RSNIe;
-		extra[1] = pAd->StaCfg.RSNIE_Len;
-		memcpy(extra+2, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
-	}
-
-	return 0;
-}
-
-int rt_ioctl_siwpmksa(struct net_device *dev,
-			   struct iw_request_info *info,
-			   union iwreq_data *wrqu,
-			   char *extra)
-{
-	PRTMP_ADAPTER   pAd = RTMP_OS_NETDEV_GET_PRIV(dev);
-	struct iw_pmksa *pPmksa = (struct iw_pmksa *)wrqu->data.pointer;
-	INT	CachedIdx = 0, idx = 0;
-
-	if (pPmksa == NULL)
-		return -EINVAL;
-
-	DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_siwpmksa\n"));
-	switch(pPmksa->cmd)
-	{
-		case IW_PMKSA_FLUSH:
-			NdisZeroMemory(pAd->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
-			DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_FLUSH\n"));
-			break;
-		case IW_PMKSA_REMOVE:
-			for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
-			{
-		        // compare the BSSID
-		        if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
-		        {
-				NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN);
-					NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].PMKID, 16);
-					for (idx = CachedIdx; idx < (pAd->StaCfg.SavedPMKNum - 1); idx++)
-					{
-						NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].BSSID[0], &pAd->StaCfg.SavedPMK[idx+1].BSSID[0], MAC_ADDR_LEN);
-						NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].PMKID[0], &pAd->StaCfg.SavedPMK[idx+1].PMKID[0], 16);
-					}
-					pAd->StaCfg.SavedPMKNum--;
-			        break;
-		        }
-	        }
-
-			DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_REMOVE\n"));
-			break;
-		case IW_PMKSA_ADD:
-			for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
-			{
-		        // compare the BSSID
-		        if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
-			        break;
-	        }
-
-	        // Found, replace it
-	        if (CachedIdx < PMKID_NO)
-	        {
-		        DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
-		        NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
-				NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
-		        pAd->StaCfg.SavedPMKNum++;
-	        }
-	        // Not found, replace the last one
-	        else
-	        {
-		        // Randomly replace one
-		        CachedIdx = (pPmksa->bssid.sa_data[5] % PMKID_NO);
-		        DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
-		        NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
-				NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
-	        }
-
-			DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_ADD\n"));
-			break;
-		default:
-			DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - Unknow Command!!\n"));
-			break;
-	}
-
-	return 0;
-}
-#endif // #if WIRELESS_EXT > 17
-
-#ifdef DBG
-static int
-rt_private_ioctl_bbp(struct net_device *dev, struct iw_request_info *info,
-		struct iw_point *wrq, char *extra)
-			{
-	PSTRING				this_char;
-	PSTRING				value = NULL;
-	UCHAR				regBBP = 0;
-//	CHAR				arg[255]={0};
-	UINT32				bbpId;
-	UINT32				bbpValue;
-	BOOLEAN				bIsPrintAllBBP = FALSE;
-	INT					Status = 0;
-    PRTMP_ADAPTER       pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
-
-
-	memset(extra, 0x00, IW_PRIV_SIZE_MASK);
-
-	if (wrq->length > 1) //No parameters.
-				{
-		sprintf(extra, "\n");
-
-		//Parsing Read or Write
-		this_char = wrq->pointer;
-		DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s\n", this_char));
-		if (!*this_char)
-			goto next;
-
-		if ((value = rtstrchr(this_char, '=')) != NULL)
-			*value++ = 0;
-
-		if (!value || !*value)
-		{ //Read
-			DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s, value=%s\n", this_char, value));
-			if (sscanf(this_char, "%d", &(bbpId)) == 1)
-			{
-				if (bbpId <= MAX_BBP_ID)
-				{
-#ifdef RALINK_ATE
-					if (ATE_ON(pAdapter))
-					{
-						ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
-					}
-					else
-#endif // RALINK_ATE //
-					{
-					RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
-					}
-					sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId, regBBP);
-                    wrq->length = strlen(extra) + 1; // 1: size of '\0'
-					DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
-				}
-				else
-				{//Invalid parametes, so default printk all bbp
-					bIsPrintAllBBP = TRUE;
-					goto next;
-				}
-			}
-			else
-			{ //Invalid parametes, so default printk all bbp
-				bIsPrintAllBBP = TRUE;
-				goto next;
-			}
-		}
-		else
-		{ //Write
-			if ((sscanf(this_char, "%d", &(bbpId)) == 1) && (sscanf(value, "%x", &(bbpValue)) == 1))
-			{
-				if (bbpId <= MAX_BBP_ID)
-				{
-#ifdef RALINK_ATE
-					if (ATE_ON(pAdapter))
-					{
-						ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
-						/* read it back for showing */
-						ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
-					}
-					else
-#endif // RALINK_ATE //
-					{
-					    RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
-					/* read it back for showing */
-					RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
-			}
-					sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId, regBBP);
-                    wrq->length = strlen(extra) + 1; // 1: size of '\0'
-					DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
-				}
-				else
-				{//Invalid parametes, so default printk all bbp
-					bIsPrintAllBBP = TRUE;
-					goto next;
-				}
-			}
-			else
-			{ //Invalid parametes, so default printk all bbp
-				bIsPrintAllBBP = TRUE;
-				goto next;
-			}
-		}
-		}
-	else
-		bIsPrintAllBBP = TRUE;
-
-next:
-	if (bIsPrintAllBBP)
-	{
-		memset(extra, 0x00, IW_PRIV_SIZE_MASK);
-		sprintf(extra, "\n");
-		for (bbpId = 0; bbpId <= MAX_BBP_ID; bbpId++)
-		{
-		    if (strlen(extra) >= (IW_PRIV_SIZE_MASK - 20))
-                break;
-#ifdef RALINK_ATE
-			if (ATE_ON(pAdapter))
-			{
-				ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
-			}
-			else
-#endif // RALINK_ATE //
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
-			sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X    ", bbpId, bbpId, regBBP);
-			if (bbpId%5 == 4)
-			sprintf(extra+strlen(extra), "%03d = %02X\n", bbpId, regBBP);  // edit by johnli, change display format
-		}
-
-        wrq->length = strlen(extra) + 1; // 1: size of '\0'
-        DBGPRINT(RT_DEBUG_TRACE, ("wrq->length = %d\n", wrq->length));
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<==rt_private_ioctl_bbp\n\n"));
-
-    return Status;
-}
-#endif // DBG //
-
-int rt_ioctl_siwrate(struct net_device *dev,
-			struct iw_request_info *info,
-			union iwreq_data *wrqu, char *extra)
-{
-    PRTMP_ADAPTER   pAd = RTMP_OS_NETDEV_GET_PRIV(dev);
-    UINT32          rate = wrqu->bitrate.value, fixed = wrqu->bitrate.fixed;
-
-    //check if the interface is down
-	if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::Network is down!\n"));
-	return -ENETDOWN;
-	}
-
-    DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(rate = %d, fixed = %d)\n", rate, fixed));
-    /* rate = -1 => auto rate
-       rate = X, fixed = 1 => (fixed rate X)
-    */
-    if (rate == -1)
-    {
-        //Auto Rate
-        pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
-		pAd->StaCfg.bAutoTxRateSwitch = TRUE;
-		if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
-		    (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
-            RTMPSetDesiredRates(pAd, -1);
-
-#ifdef DOT11_N_SUPPORT
-            SetCommonHT(pAd);
-#endif // DOT11_N_SUPPORT //
-    }
-    else
-    {
-        if (fixed)
-        {
-		pAd->StaCfg.bAutoTxRateSwitch = FALSE;
-            if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
-                (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
-                RTMPSetDesiredRates(pAd, rate);
-            else
-            {
-                pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
-#ifdef DOT11_N_SUPPORT
-                SetCommonHT(pAd);
-#endif // DOT11_N_SUPPORT //
-            }
-            DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(HtMcs=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.MCS));
-        }
-        else
-        {
-            // TODO: rate = X, fixed = 0 => (rates <= X)
-            return -EOPNOTSUPP;
-        }
-    }
-
-    return 0;
-}
-
-int rt_ioctl_giwrate(struct net_device *dev,
-			       struct iw_request_info *info,
-			       union iwreq_data *wrqu, char *extra)
-{
-    PRTMP_ADAPTER   pAd = RTMP_OS_NETDEV_GET_PRIV(dev);
-    int rate_index = 0, rate_count = 0;
-    HTTRANSMIT_SETTING ht_setting;
-/* Remove to global variable
-    __s32 ralinkrate[] =
-	{2,  4,   11,  22, // CCK
-	12, 18,   24,  36, 48, 72, 96, 108, // OFDM
-	13, 26,   39,  52,  78, 104, 117, 130, 26,  52,  78, 104, 156, 208, 234, 260, // 20MHz, 800ns GI, MCS: 0 ~ 15
-	39, 78,  117, 156, 234, 312, 351, 390,										  // 20MHz, 800ns GI, MCS: 16 ~ 23
-	27, 54,   81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, // 40MHz, 800ns GI, MCS: 0 ~ 15
-	81, 162, 243, 324, 486, 648, 729, 810,										  // 40MHz, 800ns GI, MCS: 16 ~ 23
-	14, 29,   43,  57,  87, 115, 130, 144, 29, 59,   87, 115, 173, 230, 260, 288, // 20MHz, 400ns GI, MCS: 0 ~ 15
-	43, 87,  130, 173, 260, 317, 390, 433,										  // 20MHz, 400ns GI, MCS: 16 ~ 23
-	30, 60,   90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, // 40MHz, 400ns GI, MCS: 0 ~ 15
-	90, 180, 270, 360, 540, 720, 810, 900};										  // 40MHz, 400ns GI, MCS: 16 ~ 23
-*/
-
-    rate_count = sizeof(ralinkrate)/sizeof(__s32);
-    //check if the interface is down
-	if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-	return -ENETDOWN;
-	}
-
-    if ((pAd->StaCfg.bAutoTxRateSwitch == FALSE) &&
-        (INFRA_ON(pAd)) &&
-        ((pAd->CommonCfg.PhyMode <= PHY_11G) || (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM)))
-        ht_setting.word = pAd->StaCfg.HTPhyMode.word;
-    else
-        ht_setting.word = pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word;
-
-#ifdef DOT11_N_SUPPORT
-    if (ht_setting.field.MODE >= MODE_HTMIX)
-    {
-//	rate_index = 12 + ((UCHAR)ht_setting.field.BW *16) + ((UCHAR)ht_setting.field.ShortGI *32) + ((UCHAR)ht_setting.field.MCS);
-	rate_index = 12 + ((UCHAR)ht_setting.field.BW *24) + ((UCHAR)ht_setting.field.ShortGI *48) + ((UCHAR)ht_setting.field.MCS);
-    }
-    else
-#endif // DOT11_N_SUPPORT //
-    if (ht_setting.field.MODE == MODE_OFDM)
-	rate_index = (UCHAR)(ht_setting.field.MCS) + 4;
-    else if (ht_setting.field.MODE == MODE_CCK)
-	rate_index = (UCHAR)(ht_setting.field.MCS);
-
-    if (rate_index < 0)
-        rate_index = 0;
-
-    if (rate_index > rate_count)
-        rate_index = rate_count;
-
-    wrqu->bitrate.value = ralinkrate[rate_index] * 500000;
-    wrqu->bitrate.disabled = 0;
-
-    return 0;
-}
-
-static const iw_handler rt_handler[] =
-{
-	(iw_handler) NULL,			            /* SIOCSIWCOMMIT */
-	(iw_handler) rt_ioctl_giwname,			/* SIOCGIWNAME   */
-	(iw_handler) NULL,			            /* SIOCSIWNWID   */
-	(iw_handler) NULL,			            /* SIOCGIWNWID   */
-	(iw_handler) rt_ioctl_siwfreq,		    /* SIOCSIWFREQ   */
-	(iw_handler) rt_ioctl_giwfreq,		    /* SIOCGIWFREQ   */
-	(iw_handler) rt_ioctl_siwmode,		    /* SIOCSIWMODE   */
-	(iw_handler) rt_ioctl_giwmode,		    /* SIOCGIWMODE   */
-	(iw_handler) NULL,		                /* SIOCSIWSENS   */
-	(iw_handler) NULL,		                /* SIOCGIWSENS   */
-	(iw_handler) NULL /* not used */,		/* SIOCSIWRANGE  */
-	(iw_handler) rt_ioctl_giwrange,		    /* SIOCGIWRANGE  */
-	(iw_handler) NULL /* not used */,		/* SIOCSIWPRIV   */
-	(iw_handler) NULL /* kernel code */,    /* SIOCGIWPRIV   */
-	(iw_handler) NULL /* not used */,		/* SIOCSIWSTATS  */
-	(iw_handler) rt28xx_get_wireless_stats /* kernel code */,    /* SIOCGIWSTATS  */
-	(iw_handler) NULL,		                /* SIOCSIWSPY    */
-	(iw_handler) NULL,		                /* SIOCGIWSPY    */
-	(iw_handler) NULL,				        /* SIOCSIWTHRSPY */
-	(iw_handler) NULL,				        /* SIOCGIWTHRSPY */
-	(iw_handler) rt_ioctl_siwap,            /* SIOCSIWAP     */
-	(iw_handler) rt_ioctl_giwap,		    /* SIOCGIWAP     */
-#ifdef SIOCSIWMLME
-	(iw_handler) rt_ioctl_siwmlme,	        /* SIOCSIWMLME   */
-#else
-	(iw_handler) NULL,				        /* SIOCSIWMLME */
-#endif // SIOCSIWMLME //
-	(iw_handler) rt_ioctl_iwaplist,		    /* SIOCGIWAPLIST */
-#ifdef SIOCGIWSCAN
-	(iw_handler) rt_ioctl_siwscan,		    /* SIOCSIWSCAN   */
-	(iw_handler) rt_ioctl_giwscan,		    /* SIOCGIWSCAN   */
-#else
-	(iw_handler) NULL,				        /* SIOCSIWSCAN   */
-	(iw_handler) NULL,				        /* SIOCGIWSCAN   */
-#endif /* SIOCGIWSCAN */
-	(iw_handler) rt_ioctl_siwessid,		    /* SIOCSIWESSID  */
-	(iw_handler) rt_ioctl_giwessid,		    /* SIOCGIWESSID  */
-	(iw_handler) rt_ioctl_siwnickn,		    /* SIOCSIWNICKN  */
-	(iw_handler) rt_ioctl_giwnickn,		    /* SIOCGIWNICKN  */
-	(iw_handler) NULL,				        /* -- hole --    */
-	(iw_handler) NULL,				        /* -- hole --    */
-	(iw_handler) rt_ioctl_siwrate,          /* SIOCSIWRATE   */
-	(iw_handler) rt_ioctl_giwrate,          /* SIOCGIWRATE   */
-	(iw_handler) rt_ioctl_siwrts,		    /* SIOCSIWRTS    */
-	(iw_handler) rt_ioctl_giwrts,		    /* SIOCGIWRTS    */
-	(iw_handler) rt_ioctl_siwfrag,		    /* SIOCSIWFRAG   */
-	(iw_handler) rt_ioctl_giwfrag,		    /* SIOCGIWFRAG   */
-	(iw_handler) NULL,		                /* SIOCSIWTXPOW  */
-	(iw_handler) NULL,		                /* SIOCGIWTXPOW  */
-	(iw_handler) NULL,		                /* SIOCSIWRETRY  */
-	(iw_handler) NULL,		                /* SIOCGIWRETRY  */
-	(iw_handler) rt_ioctl_siwencode,		/* SIOCSIWENCODE */
-	(iw_handler) rt_ioctl_giwencode,		/* SIOCGIWENCODE */
-	(iw_handler) NULL,		                /* SIOCSIWPOWER  */
-	(iw_handler) NULL,		                /* SIOCGIWPOWER  */
-	(iw_handler) NULL,						/* -- hole -- */
-	(iw_handler) NULL,						/* -- hole -- */
-#if WIRELESS_EXT > 17
-    (iw_handler) rt_ioctl_siwgenie,         /* SIOCSIWGENIE  */
-	(iw_handler) rt_ioctl_giwgenie,         /* SIOCGIWGENIE  */
-	(iw_handler) rt_ioctl_siwauth,		    /* SIOCSIWAUTH   */
-	(iw_handler) rt_ioctl_giwauth,		    /* SIOCGIWAUTH   */
-	(iw_handler) rt_ioctl_siwencodeext,	    /* SIOCSIWENCODEEXT */
-	(iw_handler) rt_ioctl_giwencodeext,		/* SIOCGIWENCODEEXT */
-	(iw_handler) rt_ioctl_siwpmksa,         /* SIOCSIWPMKSA  */
-#endif
-};
-
-static const iw_handler rt_priv_handlers[] = {
-	(iw_handler) NULL, /* + 0x00 */
-	(iw_handler) NULL, /* + 0x01 */
-	(iw_handler) rt_ioctl_setparam, /* + 0x02 */
-#ifdef DBG
-	(iw_handler) rt_private_ioctl_bbp, /* + 0x03 */
-#else
-	(iw_handler) NULL, /* + 0x03 */
-#endif
-	(iw_handler) NULL, /* + 0x04 */
-	(iw_handler) NULL, /* + 0x05 */
-	(iw_handler) NULL, /* + 0x06 */
-	(iw_handler) NULL, /* + 0x07 */
-	(iw_handler) NULL, /* + 0x08 */
-	(iw_handler) rt_private_get_statistics, /* + 0x09 */
-	(iw_handler) NULL, /* + 0x0A */
-	(iw_handler) NULL, /* + 0x0B */
-	(iw_handler) NULL, /* + 0x0C */
-	(iw_handler) NULL, /* + 0x0D */
-	(iw_handler) NULL, /* + 0x0E */
-	(iw_handler) NULL, /* + 0x0F */
-	(iw_handler) NULL, /* + 0x10 */
-	(iw_handler) rt_private_show, /* + 0x11 */
-    (iw_handler) NULL, /* + 0x12 */
-	(iw_handler) NULL, /* + 0x13 */
-    (iw_handler) NULL, /* + 0x14 */
-	(iw_handler) NULL, /* + 0x15 */
-    (iw_handler) NULL, /* + 0x16 */
-	(iw_handler) NULL, /* + 0x17 */
-	(iw_handler) NULL, /* + 0x18 */
-};
-
-const struct iw_handler_def rt28xx_iw_handler_def =
-{
-#define	N(a)	(sizeof (a) / sizeof (a[0]))
-	.standard	= (iw_handler *) rt_handler,
-	.num_standard	= sizeof(rt_handler) / sizeof(iw_handler),
-	.private	= (iw_handler *) rt_priv_handlers,
-	.num_private		= N(rt_priv_handlers),
-	.private_args	= (struct iw_priv_args *) privtab,
-	.num_private_args	= N(privtab),
-#if IW_HANDLER_VERSION >= 7
-    .get_wireless_stats = rt28xx_get_wireless_stats,
-#endif
-};
-
-INT RTMPSetInformation(
-    IN  PRTMP_ADAPTER pAd,
-    IN  OUT struct ifreq    *rq,
-    IN  INT                 cmd)
-{
-    struct iwreq                        *wrq = (struct iwreq *) rq;
-    NDIS_802_11_SSID                    Ssid;
-    NDIS_802_11_MAC_ADDRESS             Bssid;
-    RT_802_11_PHY_MODE                  PhyMode;
-    RT_802_11_STA_CONFIG                StaConfig;
-    NDIS_802_11_RATES                   aryRates;
-    RT_802_11_PREAMBLE                  Preamble;
-    NDIS_802_11_WEP_STATUS              WepStatus;
-    NDIS_802_11_AUTHENTICATION_MODE     AuthMode = Ndis802_11AuthModeMax;
-    NDIS_802_11_NETWORK_INFRASTRUCTURE  BssType;
-    NDIS_802_11_RTS_THRESHOLD           RtsThresh;
-    NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
-    NDIS_802_11_POWER_MODE              PowerMode;
-    PNDIS_802_11_KEY                    pKey = NULL;
-    PNDIS_802_11_WEP			        pWepKey =NULL;
-    PNDIS_802_11_REMOVE_KEY             pRemoveKey = NULL;
-    NDIS_802_11_CONFIGURATION           Config, *pConfig = NULL;
-    NDIS_802_11_NETWORK_TYPE            NetType;
-    ULONG                               Now;
-    UINT                                KeyIdx = 0;
-    INT                                 Status = NDIS_STATUS_SUCCESS, MaxPhyMode = PHY_11G;
-    ULONG                               PowerTemp;
-    BOOLEAN                             RadioState;
-    BOOLEAN                             StateMachineTouched = FALSE;
-     PNDIS_802_11_PASSPHRASE                    ppassphrase = NULL;
-#ifdef DOT11_N_SUPPORT
-	OID_SET_HT_PHYMODE					HT_PhyMode;	//11n ,kathy
-#endif // DOT11_N_SUPPORT //
-#ifdef WPA_SUPPLICANT_SUPPORT
-    PNDIS_802_11_PMKID                  pPmkId = NULL;
-    BOOLEAN				                IEEE8021xState = FALSE;
-    BOOLEAN				                IEEE8021x_required_keys = FALSE;
-    UCHAR                               wpa_supplicant_enable = 0;
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-#ifdef SNMP_SUPPORT
-	TX_RTY_CFG_STRUC			tx_rty_cfg;
-	ULONG						ShortRetryLimit, LongRetryLimit;
-	UCHAR						ctmp;
-#endif // SNMP_SUPPORT //
-
-
-
-
-#ifdef DOT11_N_SUPPORT
-	MaxPhyMode = PHY_11N_5G;
-#endif // DOT11_N_SUPPORT //
-
-	DBGPRINT(RT_DEBUG_TRACE, ("-->RTMPSetInformation(),	0x%08x\n", cmd&0x7FFF));
-	switch(cmd & 0x7FFF) {
-		case RT_OID_802_11_COUNTRY_REGION:
-			if (wrq->u.data.length < sizeof(UCHAR))
-				Status = -EINVAL;
-			// Only avaliable when EEPROM not programming
-            else if (!(pAd->CommonCfg.CountryRegion & 0x80) && !(pAd->CommonCfg.CountryRegionForABand & 0x80))
-			{
-				ULONG   Country;
-				UCHAR	TmpPhy;
-
-				Status = copy_from_user(&Country, wrq->u.data.pointer, wrq->u.data.length);
-				pAd->CommonCfg.CountryRegion = (UCHAR)(Country & 0x000000FF);
-				pAd->CommonCfg.CountryRegionForABand = (UCHAR)((Country >> 8) & 0x000000FF);
-                TmpPhy = pAd->CommonCfg.PhyMode;
-				pAd->CommonCfg.PhyMode = 0xff;
-				// Build all corresponding channel information
-				RTMPSetPhyMode(pAd, TmpPhy);
-#ifdef DOT11_N_SUPPORT
-				SetCommonHT(pAd);
-#endif // DOT11_N_SUPPORT //
-				DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_COUNTRY_REGION (A:%d  B/G:%d)\n", pAd->CommonCfg.CountryRegionForABand,
-				    pAd->CommonCfg.CountryRegion));
-            }
-            break;
-        case OID_802_11_BSSID_LIST_SCAN:
-            Now = jiffies;
-			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID_LIST_SCAN, TxCnt = %d \n", pAd->RalinkCounters.LastOneSecTotalTxCount));
-
-            if (MONITOR_ON(pAd))
-            {
-                DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
-                break;
-            }
-
-			//Benson add 20080527, when radio off, sta don't need to scan
-			if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
-				break;
-
-			if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-			{
-                DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is scanning now !!!\n"));
-				pAd->StaCfg.bScanReqIsFromWebUI = TRUE;
-				Status = NDIS_STATUS_SUCCESS;
-                break;
-            }
-
-			if (pAd->RalinkCounters.LastOneSecTotalTxCount > 100)
-            {
-                DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
-				Status = NDIS_STATUS_SUCCESS;
-				pAd->StaCfg.ScanCnt = 99;		// Prevent auto scan triggered by this OID
-				break;
-            }
-
-            if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
-				((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
-				(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
-				(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
-				(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) &&
-                (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
-            {
-                DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
-				Status = NDIS_STATUS_SUCCESS;
-				pAd->StaCfg.ScanCnt = 99;		// Prevent auto scan triggered by this OID
-				break;
-            }
-
-
-            if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)
-            {
-                RTMP_MLME_RESET_STATE_MACHINE(pAd);
-                DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
-            }
-
-            // tell CNTL state machine to call NdisMSetInformationComplete() after completing
-            // this request, because this request is initiated by NDIS.
-            pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
-            // Reset allowed scan retries
-            pAd->StaCfg.ScanCnt = 0;
-            pAd->StaCfg.LastScanTime = Now;
-
-			pAd->StaCfg.bScanReqIsFromWebUI = TRUE;
-            RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
-            MlmeEnqueue(pAd,
-                        MLME_CNTL_STATE_MACHINE,
-                        OID_802_11_BSSID_LIST_SCAN,
-                        0,
-                        NULL);
-
-            Status = NDIS_STATUS_SUCCESS;
-            StateMachineTouched = TRUE;
-            break;
-        case OID_802_11_SSID:
-            if (wrq->u.data.length != sizeof(NDIS_802_11_SSID))
-                Status = -EINVAL;
-            else
-            {
-		PSTRING pSsidString = NULL;
-                Status = copy_from_user(&Ssid, wrq->u.data.pointer, wrq->u.data.length);
-
-				DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SSID (Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
-                if (Ssid.SsidLength > MAX_LEN_OF_SSID)
-                    Status = -EINVAL;
-                else
-                {
-			if (Ssid.SsidLength == 0)
-				{
-				Set_SSID_Proc(pAd, "");
-				}
-					else
-                    {
-				pSsidString = (PSTRING)kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
-						if (pSsidString)
-						{
-							NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
-							NdisMoveMemory(pSsidString, Ssid.Ssid, Ssid.SsidLength);
-							Set_SSID_Proc(pAd, pSsidString);
-							kfree(pSsidString);
-						}
-						else
-							Status = -ENOMEM;
-                    }
-                }
-            }
-            break;
-		case OID_802_11_SET_PASSPHRASE:
-	    ppassphrase= kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
-
-	    if(ppassphrase== NULL)
-            {
-		Status = -ENOMEM;
-				DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_PASSPHRASE, Failed!!\n"));
-		break;
-            }
-			else
-		{
-		Status = copy_from_user(ppassphrase, wrq->u.data.pointer, wrq->u.data.length);
-
-				if (Status)
-		{
-			Status  = -EINVAL;
-			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_PASSPHRASE, Failed (length mismatch)!!\n"));
-			}
-			else
-			{
-					if(ppassphrase->KeyLength < 8 || ppassphrase->KeyLength > 64)
-					{
-						Status  = -EINVAL;
-			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_PASSPHRASE, Failed (len less than 8 or greater than 64)!!\n"));
-					}
-					else
-					{
-						// set key passphrase and length
-						NdisZeroMemory(pAd->StaCfg.WpaPassPhrase, 64);
-					NdisMoveMemory(pAd->StaCfg.WpaPassPhrase, &ppassphrase->KeyMaterial, ppassphrase->KeyLength);
-						pAd->StaCfg.WpaPassPhraseLen = ppassphrase->KeyLength;
-						hex_dump("pAd->StaCfg.WpaPassPhrase", pAd->StaCfg.WpaPassPhrase, 64);
-						printk("WpaPassPhrase=%s\n",pAd->StaCfg.WpaPassPhrase);
-					}
-                }
-            }
-		kfree(ppassphrase);
-			break;
-
-        case OID_802_11_BSSID:
-            if (wrq->u.data.length != sizeof(NDIS_802_11_MAC_ADDRESS))
-                Status  = -EINVAL;
-            else
-            {
-                Status = copy_from_user(&Bssid, wrq->u.data.pointer, wrq->u.data.length);
-
-                // tell CNTL state machine to call NdisMSetInformationComplete() after completing
-                // this request, because this request is initiated by NDIS.
-                pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
-
-				// Prevent to connect AP again in STAMlmePeriodicExec
-				pAd->MlmeAux.AutoReconnectSsidLen= 32;
-
-                // Reset allowed scan retries
-				pAd->StaCfg.ScanCnt = 0;
-
-                if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)
-                {
-                    RTMP_MLME_RESET_STATE_MACHINE(pAd);
-                    DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
-                }
-                MlmeEnqueue(pAd,
-                            MLME_CNTL_STATE_MACHINE,
-                            OID_802_11_BSSID,
-                            sizeof(NDIS_802_11_MAC_ADDRESS),
-                            (VOID *)&Bssid);
-                Status = NDIS_STATUS_SUCCESS;
-                StateMachineTouched = TRUE;
-
-                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID %02x:%02x:%02x:%02x:%02x:%02x\n",
-                                        Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
-            }
-            break;
-        case RT_OID_802_11_RADIO:
-            if (wrq->u.data.length != sizeof(BOOLEAN))
-                Status  = -EINVAL;
-            else
-            {
-                Status = copy_from_user(&RadioState, wrq->u.data.pointer, wrq->u.data.length);
-                DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RADIO (=%d)\n", RadioState));
-                if (pAd->StaCfg.bSwRadio != RadioState)
-                {
-                    pAd->StaCfg.bSwRadio = RadioState;
-                    if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
-                    {
-                        pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
-                        if (pAd->StaCfg.bRadio == TRUE)
-                        {
-                            MlmeRadioOn(pAd);
-                            // Update extra information
-							pAd->ExtraInfo = EXTRA_INFO_CLEAR;
-                        }
-                        else
-                        {
-				if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-				            {
-				                if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)
-						        {
-						            RTMP_MLME_RESET_STATE_MACHINE(pAd);
-						            DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
-						        }
-				            }
-
-                            MlmeRadioOff(pAd);
-                            // Update extra information
-							pAd->ExtraInfo = SW_RADIO_OFF;
-                        }
-                    }
-                }
-            }
-            break;
-        case RT_OID_802_11_PHY_MODE:
-            if (wrq->u.data.length != sizeof(RT_802_11_PHY_MODE))
-                Status  = -EINVAL;
-            else
-            {
-                Status = copy_from_user(&PhyMode, wrq->u.data.pointer, wrq->u.data.length);
-				if (PhyMode <= MaxPhyMode)
-				{
-                RTMPSetPhyMode(pAd, PhyMode);
-#ifdef DOT11_N_SUPPORT
-				SetCommonHT(pAd);
-#endif // DOT11_N_SUPPORT //
-				}
-                DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PHY_MODE (=%d)\n", PhyMode));
-            }
-            break;
-        case RT_OID_802_11_STA_CONFIG:
-            if (wrq->u.data.length != sizeof(RT_802_11_STA_CONFIG))
-                Status  = -EINVAL;
-            else
-            {
-		UINT32	Value;
-
-                Status = copy_from_user(&StaConfig, wrq->u.data.pointer, wrq->u.data.length);
-                pAd->CommonCfg.bEnableTxBurst = StaConfig.EnableTxBurst;
-                pAd->CommonCfg.UseBGProtection = StaConfig.UseBGProtection;
-                pAd->CommonCfg.bUseShortSlotTime = 1; // 2003-10-30 always SHORT SLOT capable
-                if ((pAd->CommonCfg.PhyMode != StaConfig.AdhocMode) &&
-					(StaConfig.AdhocMode <= MaxPhyMode))
-                {
-                    // allow dynamic change of "USE OFDM rate or not" in ADHOC mode
-                    // if setting changed, need to reset current TX rate as well as BEACON frame format
-                    if (pAd->StaCfg.BssType == BSS_ADHOC)
-                    {
-			pAd->CommonCfg.PhyMode = StaConfig.AdhocMode;
-			RTMPSetPhyMode(pAd, PhyMode);
-                        MlmeUpdateTxRates(pAd, FALSE, 0);
-                        MakeIbssBeacon(pAd);           // re-build BEACON frame
-                        AsicEnableIbssSync(pAd);   // copy to on-chip memory
-                    }
-                }
-                DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_STA_CONFIG (Burst=%d, Protection=%ld,ShortSlot=%d\n",
-                                        pAd->CommonCfg.bEnableTxBurst,
-                                        pAd->CommonCfg.UseBGProtection,
-                                        pAd->CommonCfg.bUseShortSlotTime));
-
-				if (pAd->CommonCfg.PSPXlink)
-					Value = PSPXLINK;
-				else
-					Value = STANORMAL;
-				RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, Value);
-				Value = 0;
-				RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
-				Value &= (~0x80);
-				RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-            }
-            break;
-        case OID_802_11_DESIRED_RATES:
-            if (wrq->u.data.length != sizeof(NDIS_802_11_RATES))
-                Status  = -EINVAL;
-            else
-            {
-                Status = copy_from_user(&aryRates, wrq->u.data.pointer, wrq->u.data.length);
-                NdisZeroMemory(pAd->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
-                NdisMoveMemory(pAd->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES));
-                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DESIRED_RATES (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
-                    pAd->CommonCfg.DesireRate[0],pAd->CommonCfg.DesireRate[1],
-                    pAd->CommonCfg.DesireRate[2],pAd->CommonCfg.DesireRate[3],
-                    pAd->CommonCfg.DesireRate[4],pAd->CommonCfg.DesireRate[5],
-                    pAd->CommonCfg.DesireRate[6],pAd->CommonCfg.DesireRate[7] ));
-                // Changing DesiredRate may affect the MAX TX rate we used to TX frames out
-                MlmeUpdateTxRates(pAd, FALSE, 0);
-            }
-            break;
-        case RT_OID_802_11_PREAMBLE:
-            if (wrq->u.data.length != sizeof(RT_802_11_PREAMBLE))
-                Status  = -EINVAL;
-            else
-            {
-                Status = copy_from_user(&Preamble, wrq->u.data.pointer, wrq->u.data.length);
-                if (Preamble == Rt802_11PreambleShort)
-                {
-                    pAd->CommonCfg.TxPreamble = Preamble;
-                    MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
-                }
-                else if ((Preamble == Rt802_11PreambleLong) || (Preamble == Rt802_11PreambleAuto))
-                {
-                    // if user wants AUTO, initialize to LONG here, then change according to AP's
-                    // capability upon association.
-                    pAd->CommonCfg.TxPreamble = Preamble;
-                    MlmeSetTxPreamble(pAd, Rt802_11PreambleLong);
-                }
-                else
-                {
-                    Status = -EINVAL;
-                    break;
-                }
-                DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PREAMBLE (=%d)\n", Preamble));
-            }
-            break;
-        case OID_802_11_WEP_STATUS:
-            if (wrq->u.data.length != sizeof(NDIS_802_11_WEP_STATUS))
-                Status  = -EINVAL;
-            else
-            {
-                Status = copy_from_user(&WepStatus, wrq->u.data.pointer, wrq->u.data.length);
-                // Since TKIP, AES, WEP are all supported. It should not have any invalid setting
-                if (WepStatus <= Ndis802_11Encryption3KeyAbsent)
-                {
-                    if (pAd->StaCfg.WepStatus != WepStatus)
-                    {
-                        // Config has changed
-                        pAd->bConfigChanged = TRUE;
-                    }
-                    pAd->StaCfg.WepStatus     = WepStatus;
-                    pAd->StaCfg.OrigWepStatus = WepStatus;
-                    pAd->StaCfg.PairCipher    = WepStatus;
-			pAd->StaCfg.GroupCipher   = WepStatus;
-                }
-                else
-                {
-                    Status  = -EINVAL;
-                    break;
-                }
-                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEP_STATUS (=%d)\n",WepStatus));
-            }
-            break;
-        case OID_802_11_AUTHENTICATION_MODE:
-            if (wrq->u.data.length != sizeof(NDIS_802_11_AUTHENTICATION_MODE))
-                Status  = -EINVAL;
-            else
-            {
-                Status = copy_from_user(&AuthMode, wrq->u.data.pointer, wrq->u.data.length);
-                if (AuthMode > Ndis802_11AuthModeMax)
-                {
-                    Status  = -EINVAL;
-                    break;
-                }
-                else
-                {
-                    if (pAd->StaCfg.AuthMode != AuthMode)
-                    {
-                        // Config has changed
-                        pAd->bConfigChanged = TRUE;
-                    }
-                    pAd->StaCfg.AuthMode = AuthMode;
-                }
-                pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_AUTHENTICATION_MODE (=%d) \n",pAd->StaCfg.AuthMode));
-            }
-            break;
-        case OID_802_11_INFRASTRUCTURE_MODE:
-            if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_INFRASTRUCTURE))
-                Status  = -EINVAL;
-            else
-            {
-                Status = copy_from_user(&BssType, wrq->u.data.pointer, wrq->u.data.length);
-
-				if (BssType == Ndis802_11IBSS)
-					Set_NetworkType_Proc(pAd, "Adhoc");
-				else if (BssType == Ndis802_11Infrastructure)
-					Set_NetworkType_Proc(pAd, "Infra");
-                else if (BssType == Ndis802_11Monitor)
-					Set_NetworkType_Proc(pAd, "Monitor");
-                else
-                {
-                    Status  = -EINVAL;
-                    DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_INFRASTRUCTURE_MODE (unknown)\n"));
-                }
-            }
-            break;
-	 case OID_802_11_REMOVE_WEP:
-            DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_WEP\n"));
-            if (wrq->u.data.length != sizeof(NDIS_802_11_KEY_INDEX))
-            {
-				Status = -EINVAL;
-            }
-            else
-            {
-		KeyIdx = *(NDIS_802_11_KEY_INDEX *) wrq->u.data.pointer;
-
-		if (KeyIdx & 0x80000000)
-		{
-			// Should never set default bit when remove key
-			Status = -EINVAL;
-		}
-		else
-		{
-			KeyIdx = KeyIdx & 0x0fffffff;
-			if (KeyIdx >= 4){
-				Status = -EINVAL;
-			}
-			else
-			{
-						pAd->SharedKey[BSS0][KeyIdx].KeyLen = 0;
-						pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
-						AsicRemoveSharedKeyEntry(pAd, 0, (UCHAR)KeyIdx);
-			}
-		}
-            }
-            break;
-        case RT_OID_802_11_RESET_COUNTERS:
-            NdisZeroMemory(&pAd->WlanCounters, sizeof(COUNTER_802_11));
-            NdisZeroMemory(&pAd->Counters8023, sizeof(COUNTER_802_3));
-            NdisZeroMemory(&pAd->RalinkCounters, sizeof(COUNTER_RALINK));
-            pAd->Counters8023.RxNoBuffer   = 0;
-			pAd->Counters8023.GoodReceives = 0;
-			pAd->Counters8023.RxNoBuffer   = 0;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RESET_COUNTERS \n"));
-            break;
-        case OID_802_11_RTS_THRESHOLD:
-            if (wrq->u.data.length != sizeof(NDIS_802_11_RTS_THRESHOLD))
-                Status  = -EINVAL;
-            else
-            {
-                Status = copy_from_user(&RtsThresh, wrq->u.data.pointer, wrq->u.data.length);
-                if (RtsThresh > MAX_RTS_THRESHOLD)
-                    Status  = -EINVAL;
-                else
-                    pAd->CommonCfg.RtsThreshold = (USHORT)RtsThresh;
-            }
-            DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_RTS_THRESHOLD (=%ld)\n",RtsThresh));
-            break;
-        case OID_802_11_FRAGMENTATION_THRESHOLD:
-            if (wrq->u.data.length != sizeof(NDIS_802_11_FRAGMENTATION_THRESHOLD))
-                Status  = -EINVAL;
-            else
-            {
-                Status = copy_from_user(&FragThresh, wrq->u.data.pointer, wrq->u.data.length);
-                pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
-                if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
-                {
-                    if (FragThresh == 0)
-                    {
-                        pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
-                        pAd->CommonCfg.bUseZeroToDisableFragment = TRUE;
-                    }
-                    else
-                        Status  = -EINVAL;
-                }
-                else
-                    pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
-            }
-            DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_FRAGMENTATION_THRESHOLD (=%ld) \n",FragThresh));
-            break;
-        case OID_802_11_POWER_MODE:
-            if (wrq->u.data.length != sizeof(NDIS_802_11_POWER_MODE))
-                Status = -EINVAL;
-            else
-            {
-                Status = copy_from_user(&PowerMode, wrq->u.data.pointer, wrq->u.data.length);
-                if (PowerMode == Ndis802_11PowerModeCAM)
-			Set_PSMode_Proc(pAd, "CAM");
-                else if (PowerMode == Ndis802_11PowerModeMAX_PSP)
-			Set_PSMode_Proc(pAd, "Max_PSP");
-                else if (PowerMode == Ndis802_11PowerModeFast_PSP)
-					Set_PSMode_Proc(pAd, "Fast_PSP");
-                else if (PowerMode == Ndis802_11PowerModeLegacy_PSP)
-					Set_PSMode_Proc(pAd, "Legacy_PSP");
-                else
-                    Status = -EINVAL;
-            }
-            DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_POWER_MODE (=%d)\n",PowerMode));
-            break;
-         case RT_OID_802_11_TX_POWER_LEVEL_1:
-			if (wrq->u.data.length  < sizeof(ULONG))
-				Status = -EINVAL;
-			else
-			{
-				Status = copy_from_user(&PowerTemp, wrq->u.data.pointer, wrq->u.data.length);
-				if (PowerTemp > 100)
-					PowerTemp = 0xffffffff;  // AUTO
-				pAd->CommonCfg.TxPowerDefault = PowerTemp; //keep current setting.
-				pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
-                DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAd->CommonCfg.TxPowerPercentage));
-			}
-	        break;
-		case OID_802_11_NETWORK_TYPE_IN_USE:
-			if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_TYPE))
-				Status = -EINVAL;
-			else
-			{
-				Status = copy_from_user(&NetType, wrq->u.data.pointer, wrq->u.data.length);
-
-				if (NetType == Ndis802_11DS)
-					RTMPSetPhyMode(pAd, PHY_11B);
-				else if (NetType == Ndis802_11OFDM24)
-					RTMPSetPhyMode(pAd, PHY_11BG_MIXED);
-				else if (NetType == Ndis802_11OFDM5)
-					RTMPSetPhyMode(pAd, PHY_11A);
-				else
-					Status = -EINVAL;
-#ifdef DOT11_N_SUPPORT
-				if (Status == NDIS_STATUS_SUCCESS)
-					SetCommonHT(pAd);
-#endif // DOT11_N_SUPPORT //
-                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_NETWORK_TYPE_IN_USE (=%d)\n",NetType));
-		    }
-			break;
-        // For WPA PSK PMK key
-        case RT_OID_802_11_ADD_WPA:
-            pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
-            if(pKey == NULL)
-            {
-                Status = -ENOMEM;
-                break;
-            }
-
-            Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
-            if (pKey->Length != wrq->u.data.length)
-            {
-                Status  = -EINVAL;
-                DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!!\n"));
-            }
-            else
-            {
-                if ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
-				    (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
-				    (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone) )
-                {
-                    Status = -EOPNOTSUPP;
-                    DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!! [AuthMode != WPAPSK/WPA2PSK/WPANONE]\n"));
-                }
-                else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
-						 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
-						 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) )     // Only for WPA PSK mode
-				{
-                    NdisMoveMemory(pAd->StaCfg.PMK, &pKey->KeyMaterial, pKey->KeyLength);
-                    // Use RaConfig as PSK agent.
-                    // Start STA supplicant state machine
-                    if (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
-                        pAd->StaCfg.WpaState = SS_START;
-
-                    DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
-                }
-                else
-                {
-                    pAd->StaCfg.WpaState = SS_NOTUSE;
-                    DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
-                }
-            }
-            kfree(pKey);
-            break;
-        case OID_802_11_REMOVE_KEY:
-            pRemoveKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
-            if(pRemoveKey == NULL)
-            {
-                Status = -ENOMEM;
-                break;
-            }
-
-            Status = copy_from_user(pRemoveKey, wrq->u.data.pointer, wrq->u.data.length);
-            if (pRemoveKey->Length != wrq->u.data.length)
-            {
-                Status  = -EINVAL;
-                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!\n"));
-            }
-            else
-            {
-                if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-                {
-                    RTMPWPARemoveKeyProc(pAd, pRemoveKey);
-                    DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Remove WPA Key!!\n"));
-                }
-                else
-                {
-                    KeyIdx = pRemoveKey->KeyIndex;
-
-                    if (KeyIdx & 0x80000000)
-                    {
-                        // Should never set default bit when remove key
-                        Status  = -EINVAL;
-                        DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(Should never set default bit when remove key)\n"));
-                    }
-                    else
-                    {
-                        KeyIdx = KeyIdx & 0x0fffffff;
-                        if (KeyIdx > 3)
-                        {
-                            Status  = -EINVAL;
-                            DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(KeyId[%d] out of range)\n", KeyIdx));
-                        }
-                        else
-                        {
-                            pAd->SharedKey[BSS0][KeyIdx].KeyLen = 0;
-                            pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
-                            AsicRemoveSharedKeyEntry(pAd, 0, (UCHAR)KeyIdx);
-                            DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY (id=0x%x, Len=%d-byte)\n", pRemoveKey->KeyIndex, pRemoveKey->Length));
-                        }
-                    }
-                }
-            }
-            kfree(pRemoveKey);
-            break;
-        // New for WPA
-        case OID_802_11_ADD_KEY:
-            pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
-            if(pKey == NULL)
-            {
-                Status = -ENOMEM;
-                break;
-            }
-            Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
-            if (pKey->Length != wrq->u.data.length)
-            {
-                Status  = -EINVAL;
-                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY, Failed!!\n"));
-            }
-            else
-            {
-                RTMPAddKey(pAd, pKey);
-                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
-            }
-            kfree(pKey);
-            break;
-        case OID_802_11_CONFIGURATION:
-            if (wrq->u.data.length != sizeof(NDIS_802_11_CONFIGURATION))
-                Status  = -EINVAL;
-            else
-            {
-                Status = copy_from_user(&Config, wrq->u.data.pointer, wrq->u.data.length);
-                pConfig = &Config;
-
-                if ((pConfig->BeaconPeriod >= 20) && (pConfig->BeaconPeriod <=400))
-                     pAd->CommonCfg.BeaconPeriod = (USHORT) pConfig->BeaconPeriod;
-
-                pAd->StaActive.AtimWin = (USHORT) pConfig->ATIMWindow;
-                MAP_KHZ_TO_CHANNEL_ID(pConfig->DSConfig, pAd->CommonCfg.Channel);
-                //
-				// Save the channel on MlmeAux for CntlOidRTBssidProc used.
-				//
-				pAd->MlmeAux.Channel = pAd->CommonCfg.Channel;
-
-                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CONFIGURATION (BeacnPeriod=%ld,AtimW=%ld,Ch=%d)\n",
-                    pConfig->BeaconPeriod, pConfig->ATIMWindow, pAd->CommonCfg.Channel));
-                // Config has changed
-                pAd->bConfigChanged = TRUE;
-            }
-            break;
-#ifdef DOT11_N_SUPPORT
-		case RT_OID_802_11_SET_HT_PHYMODE:
-			if (wrq->u.data.length	!= sizeof(OID_SET_HT_PHYMODE))
-				Status = -EINVAL;
-			else
-			{
-			    POID_SET_HT_PHYMODE	pHTPhyMode = &HT_PhyMode;
-
-				Status = copy_from_user(&HT_PhyMode, wrq->u.data.pointer, wrq->u.data.length);
-				DBGPRINT(RT_DEBUG_TRACE, ("Set::pHTPhyMode	(PhyMode = %d,TransmitNo = %d, HtMode =	%d,	ExtOffset =	%d , MCS = %d, BW =	%d,	STBC = %d, SHORTGI = %d) \n",
-				pHTPhyMode->PhyMode, pHTPhyMode->TransmitNo,pHTPhyMode->HtMode,pHTPhyMode->ExtOffset,
-				pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC,	pHTPhyMode->SHORTGI));
-				if (pAd->CommonCfg.PhyMode	>= PHY_11ABGN_MIXED)
-					RTMPSetHT(pAd,	pHTPhyMode);
-			}
-			DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_HT_PHYMODE(MCS=%d,BW=%d,SGI=%d,STBC=%d)\n",
-				pAd->StaCfg.HTPhyMode.field.MCS, pAd->StaCfg.HTPhyMode.field.BW, pAd->StaCfg.HTPhyMode.field.ShortGI,
-				pAd->StaCfg.HTPhyMode.field.STBC));
-			break;
-#endif // DOT11_N_SUPPORT //
-		case RT_OID_802_11_SET_APSD_SETTING:
-			if (wrq->u.data.length != sizeof(ULONG))
-				Status = -EINVAL;
-			else
-			{
-				ULONG apsd ;
-				Status = copy_from_user(&apsd, wrq->u.data.pointer,	wrq->u.data.length);
-
-				/*-------------------------------------------------------------------
-				|B31~B7	|	B6~B5	 |	 B4	 |	 B3	 |	B2	 |	B1	 |	   B0		|
-				---------------------------------------------------------------------
-				| Rsvd	| Max SP Len | AC_VO | AC_VI | AC_BK | AC_BE | APSD	Capable	|
-				---------------------------------------------------------------------*/
-				pAd->CommonCfg.bAPSDCapable = (apsd & 0x00000001) ? TRUE :	FALSE;
-				pAd->CommonCfg.bAPSDAC_BE = ((apsd	& 0x00000002) >> 1)	? TRUE : FALSE;
-				pAd->CommonCfg.bAPSDAC_BK = ((apsd	& 0x00000004) >> 2)	? TRUE : FALSE;
-				pAd->CommonCfg.bAPSDAC_VI = ((apsd	& 0x00000008) >> 3)	? TRUE : FALSE;
-				pAd->CommonCfg.bAPSDAC_VO = ((apsd	& 0x00000010) >> 4)	? TRUE : FALSE;
-				pAd->CommonCfg.MaxSPLength	= (UCHAR)((apsd	& 0x00000060) >> 5);
-
-				DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_APSD_SETTING (apsd=0x%lx, APSDCap=%d, [BE,BK,VI,VO]=[%d/%d/%d/%d],	MaxSPLen=%d)\n", apsd, pAd->CommonCfg.bAPSDCapable,
-					pAd->CommonCfg.bAPSDAC_BE,	pAd->CommonCfg.bAPSDAC_BK,	pAd->CommonCfg.bAPSDAC_VI,	pAd->CommonCfg.bAPSDAC_VO,	pAd->CommonCfg.MaxSPLength));
-			}
-			break;
-
-		case RT_OID_802_11_SET_APSD_PSM:
-			if (wrq->u.data.length	!= sizeof(ULONG))
-				Status = -EINVAL;
-			else
-			{
-				// Driver needs	to notify AP when PSM changes
-				Status = copy_from_user(&pAd->CommonCfg.bAPSDForcePowerSave, wrq->u.data.pointer, wrq->u.data.length);
-				if (pAd->CommonCfg.bAPSDForcePowerSave	!= pAd->StaCfg.Psm)
-				{
-					RTMP_SET_PSM_BIT(pAd,	pAd->CommonCfg.bAPSDForcePowerSave);
-					RTMPSendNullFrame(pAd,	pAd->CommonCfg.TxRate,	TRUE);
-				}
-				DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_APSD_PSM (bAPSDForcePowerSave:%d)\n",	pAd->CommonCfg.bAPSDForcePowerSave));
-			}
-			break;
-#ifdef QOS_DLS_SUPPORT
-		case RT_OID_802_11_SET_DLS:
-			if (wrq->u.data.length != sizeof(ULONG))
-				Status = -EINVAL;
-			else
-			{
-				BOOLEAN	oldvalue = pAd->CommonCfg.bDLSCapable;
-				Status = copy_from_user(&pAd->CommonCfg.bDLSCapable, wrq->u.data.pointer, wrq->u.data.length);
-				if (oldvalue &&	!pAd->CommonCfg.bDLSCapable)
-				{
-					int	i;
-					// tear	down local dls table entry
-					for	(i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
-					{
-						if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
-						{
-							pAd->StaCfg.DLSEntry[i].Status	= DLS_NONE;
-							pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
-							RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
-						}
-					}
-
-					// tear	down peer dls table	entry
-					for	(i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
-					{
-						if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
-						{
-							pAd->StaCfg.DLSEntry[i].Status	= DLS_NONE;
-							pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
-							RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
-						}
-					}
-				}
-
-				DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS (=%d)\n", pAd->CommonCfg.bDLSCapable));
-			}
-			break;
-
-		case RT_OID_802_11_SET_DLS_PARAM:
-			if (wrq->u.data.length	!= sizeof(RT_802_11_DLS_UI))
-				Status = -EINVAL;
-			else
-			{
-				RT_802_11_DLS	Dls;
-
-				NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
-				RTMPMoveMemory(&Dls, wrq->u.data.pointer, sizeof(RT_802_11_DLS_UI));
-				MlmeEnqueue(pAd,
-							MLME_CNTL_STATE_MACHINE,
-							RT_OID_802_11_SET_DLS_PARAM,
-							sizeof(RT_802_11_DLS),
-							&Dls);
-				DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS_PARAM \n"));
-			}
-			break;
-#endif // QOS_DLS_SUPPORT //
-		case RT_OID_802_11_SET_WMM:
-			if (wrq->u.data.length	!= sizeof(BOOLEAN))
-				Status = -EINVAL;
-			else
-			{
-				Status = copy_from_user(&pAd->CommonCfg.bWmmCapable, wrq->u.data.pointer, wrq->u.data.length);
-				DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_WMM (=%d)	\n", pAd->CommonCfg.bWmmCapable));
-			}
-			break;
-
-		case OID_802_11_DISASSOCIATE:
-			//
-			// Set NdisRadioStateOff to	TRUE, instead of called	MlmeRadioOff.
-			// Later on, NDIS_802_11_BSSID_LIST_EX->NumberOfItems should be	0
-			// when	query OID_802_11_BSSID_LIST.
-			//
-			// TRUE:  NumberOfItems	will set to	0.
-			// FALSE: NumberOfItems	no change.
-			//
-			pAd->CommonCfg.NdisRadioStateOff =	TRUE;
-			// Set to immediately send the media disconnect	event
-			pAd->MlmeAux.CurrReqIsFromNdis	= TRUE;
-			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DISASSOCIATE	\n"));
-
-
-			if (INFRA_ON(pAd))
-			{
-				if (pAd->Mlme.CntlMachine.CurrState !=	CNTL_IDLE)
-				{
-					RTMP_MLME_RESET_STATE_MACHINE(pAd);
-					DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME	busy, reset	MLME state machine !!!\n"));
-				}
-
-				MlmeEnqueue(pAd,
-					MLME_CNTL_STATE_MACHINE,
-					OID_802_11_DISASSOCIATE,
-					0,
-					NULL);
-
-				StateMachineTouched	= TRUE;
-			}
-			break;
-
-#ifdef DOT11_N_SUPPORT
-		case RT_OID_802_11_SET_IMME_BA_CAP:
-				if (wrq->u.data.length != sizeof(OID_BACAP_STRUC))
-					Status = -EINVAL;
-				else
-				{
-					OID_BACAP_STRUC Orde ;
-					Status = copy_from_user(&Orde, wrq->u.data.pointer, wrq->u.data.length);
-					if (Orde.Policy > BA_NOTUSE)
-					{
-						Status = NDIS_STATUS_INVALID_DATA;
-					}
-					else if (Orde.Policy == BA_NOTUSE)
-					{
-						pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
-						pAd->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
-						pAd->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
-						pAd->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
-						pAd->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
-						pAd->CommonCfg.DesiredHtPhy.MimoPs= Orde.MMPSmode;
-						pAd->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
-						// UPdata to HT IE
-						pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
-						pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
-						pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
-					}
-					else
-					{
-                        pAd->CommonCfg.BACapability.field.AutoBA = Orde.AutoBA;
-						pAd->CommonCfg.BACapability.field.Policy = IMMED_BA; // we only support immediate BA.
-						pAd->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
-						pAd->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
-						pAd->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
-						pAd->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
-						pAd->CommonCfg.DesiredHtPhy.MimoPs = Orde.MMPSmode;
-						pAd->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
-
-						// UPdata to HT IE
-						pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
-						pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
-						pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
-
-						if (pAd->CommonCfg.BACapability.field.RxBAWinLimit > MAX_RX_REORDERBUF)
-							pAd->CommonCfg.BACapability.field.RxBAWinLimit = MAX_RX_REORDERBUF;
-
-					}
-
-					pAd->CommonCfg.REGBACapability.word = pAd->CommonCfg.BACapability.word;
-					DBGPRINT(RT_DEBUG_TRACE, ("Set::(Orde.AutoBA = %d) (Policy=%d)(ReBAWinLimit=%d)(TxBAWinLimit=%d)(AutoMode=%d)\n",Orde.AutoBA, pAd->CommonCfg.BACapability.field.Policy,
-						pAd->CommonCfg.BACapability.field.RxBAWinLimit,pAd->CommonCfg.BACapability.field.TxBAWinLimit, pAd->CommonCfg.BACapability.field.AutoBA));
-					DBGPRINT(RT_DEBUG_TRACE, ("Set::(MimoPs = %d)(AmsduEnable = %d) (AmsduSize=%d)(MpduDensity=%d)\n",pAd->CommonCfg.DesiredHtPhy.MimoPs, pAd->CommonCfg.DesiredHtPhy.AmsduEnable,
-						pAd->CommonCfg.DesiredHtPhy.AmsduSize, pAd->CommonCfg.DesiredHtPhy.MpduDensity));
-				}
-
-				break;
-		case RT_OID_802_11_ADD_IMME_BA:
-			DBGPRINT(RT_DEBUG_TRACE, (" Set :: RT_OID_802_11_ADD_IMME_BA \n"));
-			if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
-					Status = -EINVAL;
-			else
-			{
-				UCHAR		        index;
-				OID_ADD_BA_ENTRY    BA;
-				MAC_TABLE_ENTRY     *pEntry;
-
-				Status = copy_from_user(&BA, wrq->u.data.pointer, wrq->u.data.length);
-				if (BA.TID > 15)
-				{
-					Status = NDIS_STATUS_INVALID_DATA;
-					break;
-				}
-				else
-				{
-					//BATableInsertEntry
-					//As ad-hoc mode, BA pair is not limited to only BSSID. so add via OID.
-					index = BA.TID;
-					// in ad hoc mode, when adding BA pair, we should insert this entry into MACEntry too
-					pEntry = MacTableLookup(pAd, BA.MACAddr);
-					if (!pEntry)
-					{
-						DBGPRINT(RT_DEBUG_TRACE, ("RT_OID_802_11_ADD_IMME_BA. break on no connection.----:%x:%x\n", BA.MACAddr[4], BA.MACAddr[5]));
-						break;
-					}
-					if (BA.IsRecipient == FALSE)
-					{
-					    if (pEntry->bIAmBadAtheros == TRUE)
-							pAd->CommonCfg.BACapability.field.RxBAWinLimit = 0x10;
-
-						BAOriSessionSetUp(pAd, pEntry, index, 0, 100, TRUE);
-					}
-					else
-					{
-						//BATableInsertEntry(pAd, pEntry->Aid, BA.MACAddr, 0, 0xffff, BA.TID, BA.nMSDU, BA.IsRecipient);
-					}
-
-					DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_IMME_BA. Rec = %d. Mac = %x:%x:%x:%x:%x:%x . \n",
-						BA.IsRecipient, BA.MACAddr[0], BA.MACAddr[1], BA.MACAddr[2], BA.MACAddr[2]
-						, BA.MACAddr[4], BA.MACAddr[5]));
-				}
-			}
-			break;
-
-		case RT_OID_802_11_TEAR_IMME_BA:
-			DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA \n"));
-			if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
-					Status = -EINVAL;
-			else
-			{
-				POID_ADD_BA_ENTRY	pBA;
-				MAC_TABLE_ENTRY *pEntry;
-
-				pBA = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
-
-				if (pBA == NULL)
-				{
-					DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA kmalloc() can't allocate enough memory\n"));
-					Status = NDIS_STATUS_FAILURE;
-				}
-				else
-				{
-					Status = copy_from_user(pBA, wrq->u.data.pointer, wrq->u.data.length);
-					DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA(TID=%d, bAllTid=%d)\n", pBA->TID, pBA->bAllTid));
-
-					if (!pBA->bAllTid && (pBA->TID > NUM_OF_TID))
-					{
-						Status = NDIS_STATUS_INVALID_DATA;
-						break;
-					}
-
-					if (pBA->IsRecipient == FALSE)
-					{
-						pEntry = MacTableLookup(pAd, pBA->MACAddr);
-						DBGPRINT(RT_DEBUG_TRACE, (" pBA->IsRecipient == FALSE\n"));
-						if (pEntry)
-						{
-							DBGPRINT(RT_DEBUG_TRACE, (" pBA->pEntry\n"));
-							BAOriSessionTearDown(pAd, pEntry->Aid, pBA->TID, FALSE, TRUE);
-						}
-						else
-							DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
-					}
-					else
-					{
-						pEntry = MacTableLookup(pAd, pBA->MACAddr);
-						if (pEntry)
-						{
-							BARecSessionTearDown( pAd, (UCHAR)pEntry->Aid, pBA->TID, TRUE);
-						}
-						else
-							DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
-					}
-					kfree(pBA);
-				}
-            }
-            break;
-#endif // DOT11_N_SUPPORT //
-
-        // For WPA_SUPPLICANT to set static wep key
-	case OID_802_11_ADD_WEP:
-	    pWepKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
-
-	    if(pWepKey == NULL)
-            {
-                Status = -ENOMEM;
-				DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed!!\n"));
-                break;
-            }
-            Status = copy_from_user(pWepKey, wrq->u.data.pointer, wrq->u.data.length);
-            if (Status)
-            {
-                Status  = -EINVAL;
-                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (length mismatch)!!\n"));
-            }
-            else
-            {
-		        KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
-                // KeyIdx must be 0 ~ 3
-                if (KeyIdx > 4)
-			{
-                    Status  = -EINVAL;
-                    DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (KeyIdx must be smaller than 4)!!\n"));
-                }
-                else
-                {
-                    UCHAR CipherAlg = 0;
-                    PUCHAR Key;
-
-                    // set key material and key length
-                    NdisZeroMemory(pAd->SharedKey[BSS0][KeyIdx].Key, 16);
-                    pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
-                    NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
-
-                    switch(pWepKey->KeyLength)
-                    {
-                        case 5:
-                            CipherAlg = CIPHER_WEP64;
-                            break;
-                        case 13:
-                            CipherAlg = CIPHER_WEP128;
-                            break;
-                        default:
-                            DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, only support CIPHER_WEP64(len:5) & CIPHER_WEP128(len:13)!!\n"));
-                            Status = -EINVAL;
-                            break;
-                    }
-                    pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
-
-                    // Default key for tx (shared key)
-                    if (pWepKey->KeyIndex & 0x80000000)
-                    {
-#ifdef WPA_SUPPLICANT_SUPPORT
-                        // set key material and key length
-                        NdisZeroMemory(pAd->StaCfg.DesireSharedKey[KeyIdx].Key, 16);
-                        pAd->StaCfg.DesireSharedKey[KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
-                        NdisMoveMemory(pAd->StaCfg.DesireSharedKey[KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
-                        pAd->StaCfg.DesireSharedKeyId = KeyIdx;
-                        pAd->StaCfg.DesireSharedKey[KeyIdx].CipherAlg = CipherAlg;
-#endif // WPA_SUPPLICANT_SUPPORT //
-                        pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
-                    }
-
-#ifdef WPA_SUPPLICANT_SUPPORT
-					if ((pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) &&
-						(pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
-					{
-						Key = pWepKey->KeyMaterial;
-
-						// Set Group key material to Asic
-					AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
-
-						// Update WCID attribute table and IVEIV table for this group key table
-						RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx, CipherAlg, NULL);
-
-						STA_PORT_SECURED(pAd);
-
-					// Indicate Connected for GUI
-					pAd->IndicateMediaState = NdisMediaStateConnected;
-					}
-                    else if (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)
-#endif // WPA_SUPPLICANT_SUPPORT
-                    {
-                        Key = pAd->SharedKey[BSS0][KeyIdx].Key;
-
-                        // Set key material and cipherAlg to Asic
-					AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
-
-                        if (pWepKey->KeyIndex & 0x80000000)
-                        {
-                            PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[BSSID_WCID];
-                            // Assign group key info
-						RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx, CipherAlg, NULL);
-						// Assign pairwise key info
-						RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx, CipherAlg, pEntry);
-                        }
-                    }
-					DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP (id=0x%x, Len=%d-byte), %s\n", pWepKey->KeyIndex, pWepKey->KeyLength, (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED) ? "Port Secured":"Port NOT Secured"));
-				}
-            }
-            kfree(pWepKey);
-            break;
-#ifdef WPA_SUPPLICANT_SUPPORT
-	    case OID_SET_COUNTERMEASURES:
-            if (wrq->u.data.length != sizeof(int))
-                Status  = -EINVAL;
-            else
-            {
-                int enabled = 0;
-                Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
-                if (enabled == 1)
-                    pAd->StaCfg.bBlockAssoc = TRUE;
-                else
-                    // WPA MIC error should block association attempt for 60 seconds
-                    pAd->StaCfg.bBlockAssoc = FALSE;
-                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_SET_COUNTERMEASURES bBlockAssoc=%s\n", pAd->StaCfg.bBlockAssoc ? "TRUE":"FALSE"));
-            }
-	        break;
-        case RT_OID_WPA_SUPPLICANT_SUPPORT:
-			if (wrq->u.data.length != sizeof(UCHAR))
-                Status  = -EINVAL;
-            else
-            {
-                Status = copy_from_user(&wpa_supplicant_enable, wrq->u.data.pointer, wrq->u.data.length);
-			pAd->StaCfg.WpaSupplicantUP = wpa_supplicant_enable;
-			DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAd->StaCfg.WpaSupplicantUP));
-			}
-            break;
-        case OID_802_11_DEAUTHENTICATION:
-            if (wrq->u.data.length != sizeof(MLME_DEAUTH_REQ_STRUCT))
-                Status  = -EINVAL;
-            else
-            {
-                MLME_DEAUTH_REQ_STRUCT      *pInfo;
-		MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
-                if (MsgElem == NULL)
-                {
-			DBGPRINT(RT_DEBUG_ERROR, ("%s():alloc memory failed!\n", __FUNCTION__));
-                        return -EINVAL;
-                }
-
-                pInfo = (MLME_DEAUTH_REQ_STRUCT *) MsgElem->Msg;
-                Status = copy_from_user(pInfo, wrq->u.data.pointer, wrq->u.data.length);
-                MlmeDeauthReqAction(pAd, MsgElem);
-				kfree(MsgElem);
-
-                if (INFRA_ON(pAd))
-                {
-                    LinkDown(pAd, FALSE);
-                    pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-                }
-                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DEAUTHENTICATION (Reason=%d)\n", pInfo->Reason));
-            }
-            break;
-        case OID_802_11_DROP_UNENCRYPTED:
-            if (wrq->u.data.length != sizeof(int))
-                Status  = -EINVAL;
-            else
-            {
-                int enabled = 0;
-                Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
-                if (enabled == 1)
-                    pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-                else
-                    pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
-				NdisAcquireSpinLock(&pAd->MacTabLock);
-				pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
-				NdisReleaseSpinLock(&pAd->MacTabLock);
-                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DROP_UNENCRYPTED (=%d)\n", enabled));
-            }
-            break;
-        case OID_802_11_SET_IEEE8021X:
-            if (wrq->u.data.length != sizeof(BOOLEAN))
-                Status  = -EINVAL;
-            else
-            {
-                Status = copy_from_user(&IEEE8021xState, wrq->u.data.pointer, wrq->u.data.length);
-		        pAd->StaCfg.IEEE8021X = IEEE8021xState;
-                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X (=%d)\n", IEEE8021xState));
-            }
-            break;
-        case OID_802_11_SET_IEEE8021X_REQUIRE_KEY:
-			if (wrq->u.data.length != sizeof(BOOLEAN))
-				 Status  = -EINVAL;
-            else
-            {
-                Status = copy_from_user(&IEEE8021x_required_keys, wrq->u.data.pointer, wrq->u.data.length);
-				pAd->StaCfg.IEEE8021x_required_keys = IEEE8021x_required_keys;
-				DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X_REQUIRE_KEY (%d)\n", IEEE8021x_required_keys));
-			}
-			break;
-        case OID_802_11_PMKID:
-	        pPmkId = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
-
-	        if(pPmkId == NULL) {
-                Status = -ENOMEM;
-                break;
-            }
-            Status = copy_from_user(pPmkId, wrq->u.data.pointer, wrq->u.data.length);
-
-	        // check the PMKID information
-	        if (pPmkId->BSSIDInfoCount == 0)
-                NdisZeroMemory(pAd->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
-	        else
-	        {
-		        PBSSID_INFO	pBssIdInfo;
-		        UINT		BssIdx;
-		        UINT		CachedIdx;
-
-		        for (BssIdx = 0; BssIdx < pPmkId->BSSIDInfoCount; BssIdx++)
-		        {
-			        // point to the indexed BSSID_INFO structure
-			        pBssIdInfo = (PBSSID_INFO) ((PUCHAR) pPmkId + 2 * sizeof(UINT) + BssIdx * sizeof(BSSID_INFO));
-			        // Find the entry in the saved data base.
-			        for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
-			        {
-				        // compare the BSSID
-				        if (NdisEqualMemory(pBssIdInfo->BSSID, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, sizeof(NDIS_802_11_MAC_ADDRESS)))
-					        break;
-			        }
-
-			        // Found, replace it
-			        if (CachedIdx < PMKID_NO)
-			        {
-				        DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
-				        NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
-				        pAd->StaCfg.SavedPMKNum++;
-			        }
-			        // Not found, replace the last one
-			        else
-			        {
-				        // Randomly replace one
-				        CachedIdx = (pBssIdInfo->BSSID[5] % PMKID_NO);
-				        DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
-				        NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
-			        }
-		        }
-			}
-			if(pPmkId)
-				kfree(pPmkId);
-	        break;
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-
-
-#ifdef SNMP_SUPPORT
-		case OID_802_11_SHORTRETRYLIMIT:
-			if (wrq->u.data.length != sizeof(ULONG))
-				Status = -EINVAL;
-			else
-			{
-				Status = copy_from_user(&ShortRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
-				RTMP_IO_READ32(pAd, TX_RTY_CFG, &tx_rty_cfg.word);
-				tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
-				RTMP_IO_WRITE32(pAd, TX_RTY_CFG, tx_rty_cfg.word);
-				DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SHORTRETRYLIMIT (tx_rty_cfg.field.ShortRetryLimit=%d, ShortRetryLimit=%ld)\n", tx_rty_cfg.field.ShortRtyLimit, ShortRetryLimit));
-			}
-			break;
-
-		case OID_802_11_LONGRETRYLIMIT:
-			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT \n"));
-			if (wrq->u.data.length != sizeof(ULONG))
-				Status = -EINVAL;
-			else
-			{
-				Status = copy_from_user(&LongRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
-				RTMP_IO_READ32(pAd, TX_RTY_CFG, &tx_rty_cfg.word);
-				tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
-				RTMP_IO_WRITE32(pAd, TX_RTY_CFG, tx_rty_cfg.word);
-				DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT (tx_rty_cfg.field.LongRetryLimit= %d,LongRetryLimit=%ld)\n", tx_rty_cfg.field.LongRtyLimit, LongRetryLimit));
-			}
-			break;
-
-		case OID_802_11_WEPDEFAULTKEYVALUE:
-			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE\n"));
-			pKey = kmalloc(wrq->u.data.length, GFP_KERNEL);
-			Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
-			//pKey = &WepKey;
-
-			if ( pKey->Length != wrq->u.data.length)
-			{
-				Status = -EINVAL;
-				DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE, Failed!!\n"));
-			}
-			KeyIdx = pKey->KeyIndex & 0x0fffffff;
-			DBGPRINT(RT_DEBUG_TRACE,("pKey->KeyIndex =%d, pKey->KeyLength=%d\n", pKey->KeyIndex, pKey->KeyLength));
-
-			// it is a shared key
-			if (KeyIdx > 4)
-				Status = -EINVAL;
-			else
-			{
-				pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = (UCHAR) pKey->KeyLength;
-				NdisMoveMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, &pKey->KeyMaterial, pKey->KeyLength);
-				if (pKey->KeyIndex & 0x80000000)
-				{
-					// Default key for tx (shared key)
-					pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
-				}
-				//RestartAPIsRequired = TRUE;
-			}
-			break;
-
-
-		case OID_802_11_WEPDEFAULTKEYID:
-			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYID \n"));
-
-			if (wrq->u.data.length != sizeof(UCHAR))
-				Status = -EINVAL;
-			else
-				Status = copy_from_user(&pAd->StaCfg.DefaultKeyId, wrq->u.data.pointer, wrq->u.data.length);
-
-			break;
-
-
-		case OID_802_11_CURRENTCHANNEL:
-			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CURRENTCHANNEL \n"));
-			if (wrq->u.data.length != sizeof(UCHAR))
-				Status = -EINVAL;
-			else
-			{
-				Status = copy_from_user(&ctmp, wrq->u.data.pointer, wrq->u.data.length);
-				sprintf((PSTRING)&ctmp,"%d", ctmp);
-				Set_Channel_Proc(pAd, (PSTRING)&ctmp);
-			}
-			break;
-#endif
-
-
-
-		case RT_OID_802_11_SET_PSPXLINK_MODE:
-			if (wrq->u.data.length != sizeof(BOOLEAN))
-                Status  = -EINVAL;
-            else
-            {
-                Status = copy_from_user(&pAd->CommonCfg.PSPXlink, wrq->u.data.pointer, wrq->u.data.length);
-				/*if (pAd->CommonCfg.PSPXlink)
-					RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_PROMISCUOUS)*/
-				DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_PSPXLINK_MODE(=%d) \n", pAd->CommonCfg.PSPXlink));
-            }
-			break;
-
-
-        default:
-            DBGPRINT(RT_DEBUG_TRACE, ("Set::unknown IOCTL's subcmd = 0x%08x\n", cmd));
-            Status = -EOPNOTSUPP;
-            break;
-    }
-
-
-    return Status;
-}
-
-INT RTMPQueryInformation(
-    IN  PRTMP_ADAPTER pAd,
-    IN  OUT struct ifreq    *rq,
-    IN  INT                 cmd)
-{
-    struct iwreq                        *wrq = (struct iwreq *) rq;
-    NDIS_802_11_BSSID_LIST_EX           *pBssidList = NULL;
-    PNDIS_WLAN_BSSID_EX                 pBss;
-    NDIS_802_11_SSID                    Ssid;
-    NDIS_802_11_CONFIGURATION           *pConfiguration = NULL;
-    RT_802_11_LINK_STATUS               *pLinkStatus = NULL;
-    RT_802_11_STA_CONFIG                *pStaConfig = NULL;
-    NDIS_802_11_STATISTICS              *pStatistics = NULL;
-    NDIS_802_11_RTS_THRESHOLD           RtsThresh;
-    NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
-    NDIS_802_11_POWER_MODE              PowerMode;
-    NDIS_802_11_NETWORK_INFRASTRUCTURE  BssType;
-    RT_802_11_PREAMBLE                  PreamType;
-    NDIS_802_11_AUTHENTICATION_MODE     AuthMode;
-    NDIS_802_11_WEP_STATUS              WepStatus;
-    NDIS_MEDIA_STATE                    MediaState;
-    ULONG                               BssBufSize, ulInfo=0, NetworkTypeList[4], apsd = 0;
-    USHORT                              BssLen = 0;
-    PUCHAR                              pBuf = NULL, pPtr;
-    INT                                 Status = NDIS_STATUS_SUCCESS;
-    UINT                                we_version_compiled;
-    UCHAR                               i, Padding = 0;
-    BOOLEAN                             RadioState;
-	STRING								driverVersion[8];
-    OID_SET_HT_PHYMODE			        *pHTPhyMode = NULL;
-
-
-#ifdef SNMP_SUPPORT
-	//for snmp, kathy
-	DefaultKeyIdxValue			*pKeyIdxValue;
-	INT							valueLen;
-	TX_RTY_CFG_STRUC			tx_rty_cfg;
-	ULONG						ShortRetryLimit, LongRetryLimit;
-	UCHAR						tmp[64];
-#endif //SNMP
-
-    switch(cmd)
-    {
-        case RT_OID_DEVICE_NAME:
-            wrq->u.data.length = sizeof(pAd->nickname);
-            Status = copy_to_user(wrq->u.data.pointer, pAd->nickname, wrq->u.data.length);
-            break;
-        case RT_OID_VERSION_INFO:
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_VERSION_INFO \n"));
-			wrq->u.data.length = 8*sizeof(CHAR);
-			sprintf(&driverVersion[0], "%s", STA_DRIVER_VERSION);
-			driverVersion[7] = '\0';
-			if (copy_to_user(wrq->u.data.pointer, &driverVersion[0], wrq->u.data.length))
-            {
-				Status = -EFAULT;
-            }
-            break;
-
-        case OID_802_11_BSSID_LIST:
-            if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-            {
-		/*
-		 * Still scanning, indicate the caller should try again.
-		 */
-		DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (Still scanning)\n"));
-				return -EAGAIN;
-            }
-            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (%d BSS returned)\n",pAd->ScanTab.BssNr));
-			pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
-            // Claculate total buffer size required
-            BssBufSize = sizeof(ULONG);
-
-            for (i = 0; i < pAd->ScanTab.BssNr; i++)
-            {
-                // Align pointer to 4 bytes boundary.
-                //Padding = 4 - (pAdapter->ScanTab.BssEntry[i].VarIELen & 0x0003);
-                //if (Padding == 4)
-                //    Padding = 0;
-                BssBufSize += (sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAd->ScanTab.BssEntry[i].VarIELen + Padding);
-            }
-
-            // For safety issue, we add 256 bytes just in case
-            BssBufSize += 256;
-            // Allocate the same size as passed from higher layer
-            pBuf = kmalloc(BssBufSize, MEM_ALLOC_FLAG);
-            if(pBuf == NULL)
-            {
-                Status = -ENOMEM;
-                break;
-            }
-            // Init 802_11_BSSID_LIST_EX structure
-            NdisZeroMemory(pBuf, BssBufSize);
-            pBssidList = (PNDIS_802_11_BSSID_LIST_EX) pBuf;
-            pBssidList->NumberOfItems = pAd->ScanTab.BssNr;
-
-            // Calculate total buffer length
-            BssLen = 4; // Consist of NumberOfItems
-            // Point to start of NDIS_WLAN_BSSID_EX
-            // pPtr = pBuf + sizeof(ULONG);
-            pPtr = (PUCHAR) &pBssidList->Bssid[0];
-            for (i = 0; i < pAd->ScanTab.BssNr; i++)
-            {
-                pBss = (PNDIS_WLAN_BSSID_EX) pPtr;
-                NdisMoveMemory(&pBss->MacAddress, &pAd->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
-                if ((pAd->ScanTab.BssEntry[i].Hidden == 1) && (pAd->StaCfg.bShowHiddenSSID == FALSE))
-                {
-                    //
-					// We must return this SSID during 4way handshaking, otherwise Aegis will failed to parse WPA infomation
-					// and then failed to send EAPOl farame.
-					//
-					if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAd->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED))
-					{
-						pBss->Ssid.SsidLength = pAd->ScanTab.BssEntry[i].SsidLen;
-						NdisMoveMemory(pBss->Ssid.Ssid, pAd->ScanTab.BssEntry[i].Ssid, pAd->ScanTab.BssEntry[i].SsidLen);
-					}
-					else
-			pBss->Ssid.SsidLength = 0;
-                }
-                else
-                {
-                    pBss->Ssid.SsidLength = pAd->ScanTab.BssEntry[i].SsidLen;
-                    NdisMoveMemory(pBss->Ssid.Ssid, pAd->ScanTab.BssEntry[i].Ssid, pAd->ScanTab.BssEntry[i].SsidLen);
-                }
-                pBss->Privacy = pAd->ScanTab.BssEntry[i].Privacy;
-                pBss->Rssi = pAd->ScanTab.BssEntry[i].Rssi - pAd->BbpRssiToDbmDelta;
-                pBss->NetworkTypeInUse = NetworkTypeInUseSanity(&pAd->ScanTab.BssEntry[i]);
-                pBss->Configuration.Length = sizeof(NDIS_802_11_CONFIGURATION);
-                pBss->Configuration.BeaconPeriod = pAd->ScanTab.BssEntry[i].BeaconPeriod;
-                pBss->Configuration.ATIMWindow = pAd->ScanTab.BssEntry[i].AtimWin;
-
-                MAP_CHANNEL_ID_TO_KHZ(pAd->ScanTab.BssEntry[i].Channel, pBss->Configuration.DSConfig);
-
-                if (pAd->ScanTab.BssEntry[i].BssType == BSS_INFRA)
-                    pBss->InfrastructureMode = Ndis802_11Infrastructure;
-                else
-                    pBss->InfrastructureMode = Ndis802_11IBSS;
-
-                NdisMoveMemory(pBss->SupportedRates, pAd->ScanTab.BssEntry[i].SupRate, pAd->ScanTab.BssEntry[i].SupRateLen);
-                NdisMoveMemory(pBss->SupportedRates + pAd->ScanTab.BssEntry[i].SupRateLen,
-                               pAd->ScanTab.BssEntry[i].ExtRate,
-                               pAd->ScanTab.BssEntry[i].ExtRateLen);
-
-                if (pAd->ScanTab.BssEntry[i].VarIELen == 0)
-                {
-                    pBss->IELength = sizeof(NDIS_802_11_FIXED_IEs);
-                    NdisMoveMemory(pBss->IEs, &pAd->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
-                    pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
-                }
-                else
-                {
-                    pBss->IELength = (ULONG)(sizeof(NDIS_802_11_FIXED_IEs) + pAd->ScanTab.BssEntry[i].VarIELen);
-                    pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
-                    NdisMoveMemory(pBss->IEs, &pAd->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
-                    NdisMoveMemory(pBss->IEs + sizeof(NDIS_802_11_FIXED_IEs), pAd->ScanTab.BssEntry[i].VarIEs, pAd->ScanTab.BssEntry[i].VarIELen);
-                    pPtr += pAd->ScanTab.BssEntry[i].VarIELen;
-                }
-                pBss->Length = (ULONG)(sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAd->ScanTab.BssEntry[i].VarIELen + Padding);
-
-#if WIRELESS_EXT < 17
-                if ((BssLen + pBss->Length) < wrq->u.data.length)
-                BssLen += pBss->Length;
-                else
-                {
-                    pBssidList->NumberOfItems = i;
-                    break;
-                }
-#else
-                BssLen += pBss->Length;
-#endif
-            }
-
-#if WIRELESS_EXT < 17
-            wrq->u.data.length = BssLen;
-#else
-            if (BssLen > wrq->u.data.length)
-            {
-                kfree(pBssidList);
-                return -E2BIG;
-            }
-            else
-                wrq->u.data.length = BssLen;
-#endif
-            Status = copy_to_user(wrq->u.data.pointer, pBssidList, BssLen);
-            kfree(pBssidList);
-            break;
-        case OID_802_3_CURRENT_ADDRESS:
-            wrq->u.data.length = MAC_ADDR_LEN;
-            Status = copy_to_user(wrq->u.data.pointer, &pAd->CurrentAddress, wrq->u.data.length);
-            break;
-        case OID_GEN_MEDIA_CONNECT_STATUS:
-            if (pAd->IndicateMediaState == NdisMediaStateConnected)
-                MediaState = NdisMediaStateConnected;
-            else
-                MediaState = NdisMediaStateDisconnected;
-
-            wrq->u.data.length = sizeof(NDIS_MEDIA_STATE);
-            Status = copy_to_user(wrq->u.data.pointer, &MediaState, wrq->u.data.length);
-            break;
-        case OID_802_11_BSSID:
-            if (INFRA_ON(pAd) || ADHOC_ON(pAd))
-            {
-                Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.Bssid, sizeof(NDIS_802_11_MAC_ADDRESS));
-
-            }
-            else
-            {
-                DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID(=EMPTY)\n"));
-                Status = -ENOTCONN;
-            }
-            break;
-        case OID_802_11_SSID:
-			NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
-			NdisZeroMemory(Ssid.Ssid, MAX_LEN_OF_SSID);
-            Ssid.SsidLength = pAd->CommonCfg.SsidLen;
-			memcpy(Ssid.Ssid, pAd->CommonCfg.Ssid,	Ssid.SsidLength);
-            wrq->u.data.length = sizeof(NDIS_802_11_SSID);
-            Status = copy_to_user(wrq->u.data.pointer, &Ssid, wrq->u.data.length);
-            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SSID (Len=%d, ssid=%s)\n", Ssid.SsidLength,Ssid.Ssid));
-            break;
-        case RT_OID_802_11_QUERY_LINK_STATUS:
-            pLinkStatus = (RT_802_11_LINK_STATUS *) kmalloc(sizeof(RT_802_11_LINK_STATUS), MEM_ALLOC_FLAG);
-            if (pLinkStatus)
-            {
-                pLinkStatus->CurrTxRate = RateIdTo500Kbps[pAd->CommonCfg.TxRate];   // unit : 500 kbps
-                pLinkStatus->ChannelQuality = pAd->Mlme.ChannelQuality;
-                pLinkStatus->RxByteCount = pAd->RalinkCounters.ReceivedByteCount;
-                pLinkStatus->TxByteCount = pAd->RalinkCounters.TransmittedByteCount;
-			pLinkStatus->CentralChannel = pAd->CommonCfg.CentralChannel;
-                wrq->u.data.length = sizeof(RT_802_11_LINK_STATUS);
-                Status = copy_to_user(wrq->u.data.pointer, pLinkStatus, wrq->u.data.length);
-                kfree(pLinkStatus);
-                DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS\n"));
-            }
-            else
-            {
-                DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS(kmalloc failed)\n"));
-                Status = -EFAULT;
-            }
-            break;
-        case OID_802_11_CONFIGURATION:
-            pConfiguration = (NDIS_802_11_CONFIGURATION *) kmalloc(sizeof(NDIS_802_11_CONFIGURATION), MEM_ALLOC_FLAG);
-            if (pConfiguration)
-            {
-                pConfiguration->Length = sizeof(NDIS_802_11_CONFIGURATION);
-                pConfiguration->BeaconPeriod = pAd->CommonCfg.BeaconPeriod;
-                pConfiguration->ATIMWindow = pAd->StaActive.AtimWin;
-                MAP_CHANNEL_ID_TO_KHZ(pAd->CommonCfg.Channel, pConfiguration->DSConfig);
-                wrq->u.data.length = sizeof(NDIS_802_11_CONFIGURATION);
-                Status = copy_to_user(wrq->u.data.pointer, pConfiguration, wrq->u.data.length);
-                DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(BeaconPeriod=%ld,AtimW=%ld,Channel=%d) \n",
-                                        pConfiguration->BeaconPeriod, pConfiguration->ATIMWindow, pAd->CommonCfg.Channel));
-				kfree(pConfiguration);
-            }
-            else
-            {
-                DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(kmalloc failed)\n"));
-                Status = -EFAULT;
-            }
-            break;
-		case RT_OID_802_11_SNR_0:
-			if ((pAd->StaCfg.LastSNR0 > 0))
-			{
-				ulInfo = ((0xeb	- pAd->StaCfg.LastSNR0) * 3) /	16 ;
-				wrq->u.data.length = sizeof(ulInfo);
-				Status = copy_to_user(wrq->u.data.pointer, &ulInfo,	wrq->u.data.length);
-				DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_SNR_0(0x=%lx)\n", ulInfo));
-			}
-            else
-			    Status = -EFAULT;
-			break;
-		case RT_OID_802_11_SNR_1:
-			if ((pAd->Antenna.field.RxPath	> 1) &&
-                (pAd->StaCfg.LastSNR1 > 0))
-			{
-				ulInfo = ((0xeb	- pAd->StaCfg.LastSNR1) * 3) /	16 ;
-				wrq->u.data.length = sizeof(ulInfo);
-				Status = copy_to_user(wrq->u.data.pointer, &ulInfo,	wrq->u.data.length);
-				DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(0x=%lx)\n",ulInfo));
-			}
-			else
-				Status = -EFAULT;
-            DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(pAd->StaCfg.LastSNR1=%d)\n",pAd->StaCfg.LastSNR1));
-			break;
-        case OID_802_11_RSSI_TRIGGER:
-            ulInfo = pAd->StaCfg.RssiSample.LastRssi0 - pAd->BbpRssiToDbmDelta;
-            wrq->u.data.length = sizeof(ulInfo);
-            Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
-            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RSSI_TRIGGER(=%ld)\n", ulInfo));
-            break;
-		case OID_802_11_RSSI:
-        case RT_OID_802_11_RSSI:
-			ulInfo = pAd->StaCfg.RssiSample.LastRssi0;
-			wrq->u.data.length = sizeof(ulInfo);
-			Status = copy_to_user(wrq->u.data.pointer, &ulInfo,	wrq->u.data.length);
-			break;
-		case RT_OID_802_11_RSSI_1:
-            ulInfo = pAd->StaCfg.RssiSample.LastRssi1;
-			wrq->u.data.length = sizeof(ulInfo);
-			Status = copy_to_user(wrq->u.data.pointer, &ulInfo,	wrq->u.data.length);
-			break;
-        case RT_OID_802_11_RSSI_2:
-            ulInfo = pAd->StaCfg.RssiSample.LastRssi2;
-			wrq->u.data.length = sizeof(ulInfo);
-			Status = copy_to_user(wrq->u.data.pointer, &ulInfo,	wrq->u.data.length);
-			break;
-        case OID_802_11_STATISTICS:
-            pStatistics = (NDIS_802_11_STATISTICS *) kmalloc(sizeof(NDIS_802_11_STATISTICS), MEM_ALLOC_FLAG);
-            if (pStatistics)
-            {
-                DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS \n"));
-                // add the most up-to-date h/w raw counters into software counters
-			    NICUpdateRawCounters(pAd);
-
-                // Sanity check for calculation of sucessful count
-                if (pAd->WlanCounters.TransmittedFragmentCount.QuadPart < pAd->WlanCounters.RetryCount.QuadPart)
-                    pAd->WlanCounters.TransmittedFragmentCount.QuadPart = pAd->WlanCounters.RetryCount.QuadPart;
-
-                pStatistics->TransmittedFragmentCount.QuadPart = pAd->WlanCounters.TransmittedFragmentCount.QuadPart;
-                pStatistics->MulticastTransmittedFrameCount.QuadPart = pAd->WlanCounters.MulticastTransmittedFrameCount.QuadPart;
-                pStatistics->FailedCount.QuadPart = pAd->WlanCounters.FailedCount.QuadPart;
-                pStatistics->RetryCount.QuadPart = pAd->WlanCounters.RetryCount.QuadPart;
-                pStatistics->MultipleRetryCount.QuadPart = pAd->WlanCounters.MultipleRetryCount.QuadPart;
-                pStatistics->RTSSuccessCount.QuadPart = pAd->WlanCounters.RTSSuccessCount.QuadPart;
-                pStatistics->RTSFailureCount.QuadPart = pAd->WlanCounters.RTSFailureCount.QuadPart;
-                pStatistics->ACKFailureCount.QuadPart = pAd->WlanCounters.ACKFailureCount.QuadPart;
-                pStatistics->FrameDuplicateCount.QuadPart = pAd->WlanCounters.FrameDuplicateCount.QuadPart;
-                pStatistics->ReceivedFragmentCount.QuadPart = pAd->WlanCounters.ReceivedFragmentCount.QuadPart;
-                pStatistics->MulticastReceivedFrameCount.QuadPart = pAd->WlanCounters.MulticastReceivedFrameCount.QuadPart;
-#ifdef DBG
-                pStatistics->FCSErrorCount = pAd->RalinkCounters.RealFcsErrCount;
-#else
-                pStatistics->FCSErrorCount.QuadPart = pAd->WlanCounters.FCSErrorCount.QuadPart;
-                pStatistics->FrameDuplicateCount.u.LowPart = pAd->WlanCounters.FrameDuplicateCount.u.LowPart / 100;
-#endif
-                wrq->u.data.length = sizeof(NDIS_802_11_STATISTICS);
-                Status = copy_to_user(wrq->u.data.pointer, pStatistics, wrq->u.data.length);
-                kfree(pStatistics);
-            }
-            else
-            {
-                DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS(kmalloc failed)\n"));
-                Status = -EFAULT;
-            }
-            break;
-        case OID_GEN_RCV_OK:
-            ulInfo = pAd->Counters8023.GoodReceives;
-            wrq->u.data.length = sizeof(ulInfo);
-            Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
-            break;
-        case OID_GEN_RCV_NO_BUFFER:
-            ulInfo = pAd->Counters8023.RxNoBuffer;
-            wrq->u.data.length = sizeof(ulInfo);
-            Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
-            break;
-        case RT_OID_802_11_PHY_MODE:
-            ulInfo = (ULONG)pAd->CommonCfg.PhyMode;
-            wrq->u.data.length = sizeof(ulInfo);
-            Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
-            DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PHY_MODE (=%ld)\n", ulInfo));
-            break;
-        case RT_OID_802_11_STA_CONFIG:
-            pStaConfig = (RT_802_11_STA_CONFIG *) kmalloc(sizeof(RT_802_11_STA_CONFIG), MEM_ALLOC_FLAG);
-            if (pStaConfig)
-            {
-                DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG\n"));
-                pStaConfig->EnableTxBurst = pAd->CommonCfg.bEnableTxBurst;
-                pStaConfig->EnableTurboRate = 0;
-                pStaConfig->UseBGProtection = pAd->CommonCfg.UseBGProtection;
-                pStaConfig->UseShortSlotTime = pAd->CommonCfg.bUseShortSlotTime;
-                //pStaConfig->AdhocMode = pAd->StaCfg.AdhocMode;
-                pStaConfig->HwRadioStatus = (pAd->StaCfg.bHwRadio == TRUE) ? 1 : 0;
-                pStaConfig->Rsv1 = 0;
-                pStaConfig->SystemErrorBitmap = pAd->SystemErrorBitmap;
-                wrq->u.data.length = sizeof(RT_802_11_STA_CONFIG);
-                Status = copy_to_user(wrq->u.data.pointer, pStaConfig, wrq->u.data.length);
-                kfree(pStaConfig);
-            }
-            else
-            {
-                DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
-                Status = -EFAULT;
-            }
-            break;
-        case OID_802_11_RTS_THRESHOLD:
-            RtsThresh = pAd->CommonCfg.RtsThreshold;
-            wrq->u.data.length = sizeof(RtsThresh);
-            Status = copy_to_user(wrq->u.data.pointer, &RtsThresh, wrq->u.data.length);
-            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RTS_THRESHOLD(=%ld)\n", RtsThresh));
-            break;
-        case OID_802_11_FRAGMENTATION_THRESHOLD:
-            FragThresh = pAd->CommonCfg.FragmentThreshold;
-            if (pAd->CommonCfg.bUseZeroToDisableFragment == TRUE)
-                FragThresh = 0;
-            wrq->u.data.length = sizeof(FragThresh);
-            Status = copy_to_user(wrq->u.data.pointer, &FragThresh, wrq->u.data.length);
-            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_FRAGMENTATION_THRESHOLD(=%ld)\n", FragThresh));
-            break;
-        case OID_802_11_POWER_MODE:
-            PowerMode = pAd->StaCfg.WindowsPowerMode;
-            wrq->u.data.length = sizeof(PowerMode);
-            Status = copy_to_user(wrq->u.data.pointer, &PowerMode, wrq->u.data.length);
-            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_POWER_MODE(=%d)\n", PowerMode));
-            break;
-        case RT_OID_802_11_RADIO:
-            RadioState = (BOOLEAN) pAd->StaCfg.bSwRadio;
-            wrq->u.data.length = sizeof(RadioState);
-            Status = copy_to_user(wrq->u.data.pointer, &RadioState, wrq->u.data.length);
-            DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_RADIO (=%d)\n", RadioState));
-            break;
-        case OID_802_11_INFRASTRUCTURE_MODE:
-            if (pAd->StaCfg.BssType == BSS_ADHOC)
-                BssType = Ndis802_11IBSS;
-            else if (pAd->StaCfg.BssType == BSS_INFRA)
-                BssType = Ndis802_11Infrastructure;
-            else if (pAd->StaCfg.BssType == BSS_MONITOR)
-                BssType = Ndis802_11Monitor;
-            else
-                BssType = Ndis802_11AutoUnknown;
-
-            wrq->u.data.length = sizeof(BssType);
-            Status = copy_to_user(wrq->u.data.pointer, &BssType, wrq->u.data.length);
-            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_INFRASTRUCTURE_MODE(=%d)\n", BssType));
-            break;
-        case RT_OID_802_11_PREAMBLE:
-            PreamType = pAd->CommonCfg.TxPreamble;
-            wrq->u.data.length = sizeof(PreamType);
-            Status = copy_to_user(wrq->u.data.pointer, &PreamType, wrq->u.data.length);
-            DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PREAMBLE(=%d)\n", PreamType));
-            break;
-        case OID_802_11_AUTHENTICATION_MODE:
-            AuthMode = pAd->StaCfg.AuthMode;
-            wrq->u.data.length = sizeof(AuthMode);
-            Status = copy_to_user(wrq->u.data.pointer, &AuthMode, wrq->u.data.length);
-            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_AUTHENTICATION_MODE(=%d)\n", AuthMode));
-            break;
-        case OID_802_11_WEP_STATUS:
-            WepStatus = pAd->StaCfg.WepStatus;
-            wrq->u.data.length = sizeof(WepStatus);
-            Status = copy_to_user(wrq->u.data.pointer, &WepStatus, wrq->u.data.length);
-            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEP_STATUS(=%d)\n", WepStatus));
-            break;
-        case OID_802_11_TX_POWER_LEVEL:
-			wrq->u.data.length = sizeof(ULONG);
-			Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.TxPower, wrq->u.data.length);
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_TX_POWER_LEVEL %x\n",pAd->CommonCfg.TxPower));
-			break;
-        case RT_OID_802_11_TX_POWER_LEVEL_1:
-            wrq->u.data.length = sizeof(ULONG);
-            Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.TxPowerPercentage, wrq->u.data.length);
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAd->CommonCfg.TxPowerPercentage));
-			break;
-        case OID_802_11_NETWORK_TYPES_SUPPORTED:
-			if ((pAd->RfIcType	== RFIC_2850) || (pAd->RfIcType ==	RFIC_2750) || (pAd->RfIcType == RFIC_3052))
-			{
-				NetworkTypeList[0] = 3;                 // NumberOfItems = 3
-				NetworkTypeList[1] = Ndis802_11DS;      // NetworkType[1] = 11b
-				NetworkTypeList[2] = Ndis802_11OFDM24;  // NetworkType[2] = 11g
-				NetworkTypeList[3] = Ndis802_11OFDM5;   // NetworkType[3] = 11a
-                wrq->u.data.length = 16;
-				Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
-			}
-			else
-			{
-				NetworkTypeList[0] = 2;                 // NumberOfItems = 2
-				NetworkTypeList[1] = Ndis802_11DS;      // NetworkType[1] = 11b
-				NetworkTypeList[2] = Ndis802_11OFDM24;  // NetworkType[2] = 11g
-			    wrq->u.data.length = 12;
-				Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
-			}
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_NETWORK_TYPES_SUPPORTED\n"));
-				break;
-	    case OID_802_11_NETWORK_TYPE_IN_USE:
-            wrq->u.data.length = sizeof(ULONG);
-			if (pAd->CommonCfg.PhyMode == PHY_11A)
-				ulInfo = Ndis802_11OFDM5;
-			else if ((pAd->CommonCfg.PhyMode == PHY_11BG_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11G))
-				ulInfo = Ndis802_11OFDM24;
-			else
-				ulInfo = Ndis802_11DS;
-            Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
-			break;
-        case RT_OID_802_11_QUERY_LAST_RX_RATE:
-            ulInfo = (ULONG)pAd->LastRxRate;
-            wrq->u.data.length = sizeof(ulInfo);
-			Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_RX_RATE (=%ld)\n", ulInfo));
-			break;
-		case RT_OID_802_11_QUERY_LAST_TX_RATE:
-			//ulInfo = (ULONG)pAd->LastTxRate;
-			ulInfo = (ULONG)pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word;
-			wrq->u.data.length = sizeof(ulInfo);
-			Status = copy_to_user(wrq->u.data.pointer, &ulInfo,	wrq->u.data.length);
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_TX_RATE (=%lx)\n", ulInfo));
-			break;
-        case RT_OID_802_11_QUERY_EEPROM_VERSION:
-            wrq->u.data.length = sizeof(ULONG);
-            Status = copy_to_user(wrq->u.data.pointer, &pAd->EepromVersion, wrq->u.data.length);
-            break;
-        case RT_OID_802_11_QUERY_FIRMWARE_VERSION:
-            wrq->u.data.length = sizeof(ULONG);
-            Status = copy_to_user(wrq->u.data.pointer, &pAd->FirmwareVersion, wrq->u.data.length);
-			break;
-	    case RT_OID_802_11_QUERY_NOISE_LEVEL:
-			wrq->u.data.length = sizeof(UCHAR);
-			Status = copy_to_user(wrq->u.data.pointer, &pAd->BbpWriteLatch[66], wrq->u.data.length);
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_NOISE_LEVEL (=%d)\n", pAd->BbpWriteLatch[66]));
-			break;
-	    case RT_OID_802_11_EXTRA_INFO:
-			wrq->u.data.length = sizeof(ULONG);
-			Status = copy_to_user(wrq->u.data.pointer, &pAd->ExtraInfo, wrq->u.data.length);
-	        DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_EXTRA_INFO (=%ld)\n", pAd->ExtraInfo));
-	        break;
-	    case RT_OID_WE_VERSION_COMPILED:
-	        wrq->u.data.length = sizeof(UINT);
-	        we_version_compiled = WIRELESS_EXT;
-	        Status = copy_to_user(wrq->u.data.pointer, &we_version_compiled, wrq->u.data.length);
-	        break;
-		case RT_OID_802_11_QUERY_APSD_SETTING:
-			apsd = (pAd->CommonCfg.bAPSDCapable | (pAd->CommonCfg.bAPSDAC_BE << 1) | (pAd->CommonCfg.bAPSDAC_BK << 2)
-				| (pAd->CommonCfg.bAPSDAC_VI << 3)	| (pAd->CommonCfg.bAPSDAC_VO << 4)	| (pAd->CommonCfg.MaxSPLength << 5));
-
-			wrq->u.data.length = sizeof(ULONG);
-			Status = copy_to_user(wrq->u.data.pointer, &apsd, wrq->u.data.length);
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_APSD_SETTING (=0x%lx,APSDCap=%d,AC_BE=%d,AC_BK=%d,AC_VI=%d,AC_VO=%d,MAXSPLen=%d)\n",
-				apsd,pAd->CommonCfg.bAPSDCapable,pAd->CommonCfg.bAPSDAC_BE,pAd->CommonCfg.bAPSDAC_BK,pAd->CommonCfg.bAPSDAC_VI,pAd->CommonCfg.bAPSDAC_VO,pAd->CommonCfg.MaxSPLength));
-			break;
-		case RT_OID_802_11_QUERY_APSD_PSM:
-			wrq->u.data.length = sizeof(ULONG);
-			Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.bAPSDForcePowerSave, wrq->u.data.length);
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_APSD_PSM (=%d)\n", pAd->CommonCfg.bAPSDForcePowerSave));
-			break;
-		case RT_OID_802_11_QUERY_WMM:
-			wrq->u.data.length = sizeof(BOOLEAN);
-			Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.bWmmCapable, wrq->u.data.length);
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_WMM (=%d)\n",	pAd->CommonCfg.bWmmCapable));
-			break;
-#ifdef WPA_SUPPLICANT_SUPPORT
-        case RT_OID_NEW_DRIVER:
-            {
-                UCHAR enabled = 1;
-	        wrq->u.data.length = sizeof(UCHAR);
-	        Status = copy_to_user(wrq->u.data.pointer, &enabled, wrq->u.data.length);
-                DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_NEW_DRIVER (=%d)\n", enabled));
-            }
-	        break;
-        case RT_OID_WPA_SUPPLICANT_SUPPORT:
-	        wrq->u.data.length = sizeof(UCHAR);
-	        Status = copy_to_user(wrq->u.data.pointer, &pAd->StaCfg.WpaSupplicantUP, wrq->u.data.length);
-            DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAd->StaCfg.WpaSupplicantUP));
-	        break;
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-        case RT_OID_DRIVER_DEVICE_NAME:
-            DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_DRIVER_DEVICE_NAME \n"));
-			wrq->u.data.length = 16;
-			if (copy_to_user(wrq->u.data.pointer, pAd->StaCfg.dev_name, wrq->u.data.length))
-			{
-				Status = -EFAULT;
-			}
-            break;
-        case RT_OID_802_11_QUERY_HT_PHYMODE:
-            pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
-            if (pHTPhyMode)
-            {
-                pHTPhyMode->PhyMode = pAd->CommonCfg.PhyMode;
-			pHTPhyMode->HtMode = (UCHAR)pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE;
-			pHTPhyMode->BW = (UCHAR)pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.BW;
-			pHTPhyMode->MCS= (UCHAR)pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS;
-			pHTPhyMode->SHORTGI= (UCHAR)pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI;
-			pHTPhyMode->STBC= (UCHAR)pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC;
-
-			pHTPhyMode->ExtOffset = ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) ? (EXTCHA_BELOW) : (EXTCHA_ABOVE));
-                wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
-                if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
-			{
-				Status = -EFAULT;
-			}
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
-				pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
-			DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word));
-            }
-            else
-            {
-                DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
-                Status = -EFAULT;
-            }
-            break;
-        case RT_OID_802_11_COUNTRY_REGION:
-            DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_COUNTRY_REGION \n"));
-			wrq->u.data.length = sizeof(ulInfo);
-            ulInfo = pAd->CommonCfg.CountryRegionForABand;
-            ulInfo = (ulInfo << 8)|(pAd->CommonCfg.CountryRegion);
-			if (copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length))
-            {
-				Status = -EFAULT;
-            }
-            break;
-        case RT_OID_802_11_QUERY_DAT_HT_PHYMODE:
-            pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
-            if (pHTPhyMode)
-            {
-                pHTPhyMode->PhyMode = pAd->CommonCfg.PhyMode;
-			pHTPhyMode->HtMode = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.HTMODE;
-			pHTPhyMode->BW = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.BW;
-			pHTPhyMode->MCS= (UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.MCS;
-			pHTPhyMode->SHORTGI= (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.ShortGI;
-			pHTPhyMode->STBC= (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.STBC;
-
-                wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
-                if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
-			{
-				Status = -EFAULT;
-			}
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
-				pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
-			DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word));
-            }
-            else
-            {
-                DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
-                Status = -EFAULT;
-            }
-            break;
-        case RT_OID_QUERY_MULTIPLE_CARD_SUPPORT:
-			wrq->u.data.length = sizeof(UCHAR);
-            i = 0;
-#ifdef MULTIPLE_CARD_SUPPORT
-            i = 1;
-#endif // MULTIPLE_CARD_SUPPORT //
-			if (copy_to_user(wrq->u.data.pointer, &i, wrq->u.data.length))
-            {
-				Status = -EFAULT;
-            }
-            DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_QUERY_MULTIPLE_CARD_SUPPORT(=%d) \n", i));
-            break;
-#ifdef SNMP_SUPPORT
-		case RT_OID_802_11_MAC_ADDRESS:
-            wrq->u.data.length = MAC_ADDR_LEN;
-            Status = copy_to_user(wrq->u.data.pointer, &pAd->CurrentAddress, wrq->u.data.length);
-			break;
-
-		case RT_OID_802_11_MANUFACTUREROUI:
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREROUI \n"));
-			wrq->u.data.length = ManufacturerOUI_LEN;
-			Status = copy_to_user(wrq->u.data.pointer, &pAd->CurrentAddress, wrq->u.data.length);
-			break;
-
-		case RT_OID_802_11_MANUFACTURERNAME:
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTURERNAME \n"));
-			wrq->u.data.length = strlen(ManufacturerNAME);
-			Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
-			break;
-
-		case RT_OID_802_11_RESOURCETYPEIDNAME:
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_RESOURCETYPEIDNAME \n"));
-			wrq->u.data.length = strlen(ResourceTypeIdName);
-			Status = copy_to_user(wrq->u.data.pointer, ResourceTypeIdName, wrq->u.data.length);
-			break;
-
-		case RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED:
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED \n"));
-			ulInfo = 1; // 1 is support wep else 2 is not support.
-			wrq->u.data.length = sizeof(ulInfo);
-			Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
-			break;
-
-		case RT_OID_802_11_POWERMANAGEMENTMODE:
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_POWERMANAGEMENTMODE \n"));
-			if (pAd->StaCfg.Psm == PSMP_ACTION)
-				ulInfo = 1; // 1 is power active else 2 is power save.
-			else
-				ulInfo = 2;
-
-			wrq->u.data.length = sizeof(ulInfo);
-			Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
-			break;
-
-		case OID_802_11_WEPDEFAULTKEYVALUE:
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEPDEFAULTKEYVALUE \n"));
-			//KeyIdxValue.KeyIdx = pAd->PortCfg.MBSSID[pAd->IoctlIF].DefaultKeyId;
-			pKeyIdxValue = wrq->u.data.pointer;
-			DBGPRINT(RT_DEBUG_TRACE,("KeyIdxValue.KeyIdx = %d, \n",pKeyIdxValue->KeyIdx));
-			valueLen = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen;
-			NdisMoveMemory(pKeyIdxValue->Value,
-						   &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
-						   valueLen);
-			pKeyIdxValue->Value[valueLen]='\0';
-
-			wrq->u.data.length = sizeof(DefaultKeyIdxValue);
-
-			Status = copy_to_user(wrq->u.data.pointer, pKeyIdxValue, wrq->u.data.length);
-			DBGPRINT(RT_DEBUG_TRACE,("DefaultKeyId = %d, total len = %d, str len=%d, KeyValue= %02x %02x %02x %02x \n",
-										pAd->StaCfg.DefaultKeyId,
-										wrq->u.data.length,
-										pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen,
-										pAd->SharedKey[BSS0][0].Key[0],
-										pAd->SharedKey[BSS0][1].Key[0],
-										pAd->SharedKey[BSS0][2].Key[0],
-										pAd->SharedKey[BSS0][3].Key[0]));
-			break;
-
-		case OID_802_11_WEPDEFAULTKEYID:
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPDEFAULTKEYID \n"));
-			wrq->u.data.length = sizeof(UCHAR);
-			Status = copy_to_user(wrq->u.data.pointer, &pAd->StaCfg.DefaultKeyId, wrq->u.data.length);
-			DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyId =%d \n", pAd->StaCfg.DefaultKeyId));
-			break;
-
-		case RT_OID_802_11_WEPKEYMAPPINGLENGTH:
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPKEYMAPPINGLENGTH \n"));
-			wrq->u.data.length = sizeof(UCHAR);
-			Status = copy_to_user(wrq->u.data.pointer,
-									&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen,
-									wrq->u.data.length);
-			break;
-
-		case OID_802_11_SHORTRETRYLIMIT:
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SHORTRETRYLIMIT \n"));
-			wrq->u.data.length = sizeof(ULONG);
-			RTMP_IO_READ32(pAd, TX_RTY_CFG, &tx_rty_cfg.word);
-			ShortRetryLimit = tx_rty_cfg.field.ShortRtyLimit;
-			DBGPRINT(RT_DEBUG_TRACE, ("ShortRetryLimit =%ld,  tx_rty_cfg.field.ShortRetryLimit=%d\n", ShortRetryLimit, tx_rty_cfg.field.ShortRtyLimit));
-			Status = copy_to_user(wrq->u.data.pointer, &ShortRetryLimit, wrq->u.data.length);
-			break;
-
-		case OID_802_11_LONGRETRYLIMIT:
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_LONGRETRYLIMIT \n"));
-			wrq->u.data.length = sizeof(ULONG);
-			RTMP_IO_READ32(pAd, TX_RTY_CFG, &tx_rty_cfg.word);
-			LongRetryLimit = tx_rty_cfg.field.LongRtyLimit;
-			DBGPRINT(RT_DEBUG_TRACE, ("LongRetryLimit =%ld,  tx_rty_cfg.field.LongRtyLimit=%d\n", LongRetryLimit, tx_rty_cfg.field.LongRtyLimit));
-			Status = copy_to_user(wrq->u.data.pointer, &LongRetryLimit, wrq->u.data.length);
-			break;
-
-		case RT_OID_802_11_PRODUCTID:
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRODUCTID \n"));
-
-#ifdef RTMP_MAC_PCI
-			{
-
-				USHORT  device_id;
-				if (((POS_COOKIE)pAd->OS_Cookie)->pci_dev != NULL)
-				pci_read_config_word(((POS_COOKIE)pAd->OS_Cookie)->pci_dev, PCI_DEVICE_ID, &device_id);
-				else
-					DBGPRINT(RT_DEBUG_TRACE, (" pci_dev = NULL\n"));
-				sprintf((PSTRING)tmp, "%04x %04x\n", NIC_PCI_VENDOR_ID, device_id);
-			}
-#endif // RTMP_MAC_PCI //
-			wrq->u.data.length = strlen((PSTRING)tmp);
-			Status = copy_to_user(wrq->u.data.pointer, tmp, wrq->u.data.length);
-			break;
-
-		case RT_OID_802_11_MANUFACTUREID:
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREID \n"));
-			wrq->u.data.length = strlen(ManufacturerNAME);
-			Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
-			break;
-
-		case OID_802_11_CURRENTCHANNEL:
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CURRENTCHANNEL \n"));
-			wrq->u.data.length = sizeof(UCHAR);
-			DBGPRINT(RT_DEBUG_TRACE, ("sizeof UCHAR=%d, channel=%d \n", sizeof(UCHAR), pAd->CommonCfg.Channel));
-			Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.Channel, wrq->u.data.length);
-			DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
-			break;
-#endif //SNMP_SUPPORT
-
-		case OID_802_11_BUILD_CHANNEL_EX:
-			{
-				UCHAR value;
-				DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BUILD_CHANNEL_EX \n"));
-				wrq->u.data.length = sizeof(UCHAR);
-#ifdef EXT_BUILD_CHANNEL_LIST
-				DBGPRINT(RT_DEBUG_TRACE, ("Support EXT_BUILD_CHANNEL_LIST.\n"));
-				value = 1;
-#else
-				DBGPRINT(RT_DEBUG_TRACE, ("Doesn't support EXT_BUILD_CHANNEL_LIST.\n"));
-				value = 0;
-#endif // EXT_BUILD_CHANNEL_LIST //
-				Status = copy_to_user(wrq->u.data.pointer, &value, 1);
-				DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
-			}
-			break;
-
-		case OID_802_11_GET_CH_LIST:
-			{
-				PRT_CHANNEL_LIST_INFO pChListBuf;
-
-				DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CH_LIST \n"));
-				if (pAd->ChannelListNum == 0)
-				{
-					wrq->u.data.length = 0;
-					break;
-				}
-
-				pChListBuf = (RT_CHANNEL_LIST_INFO *) kmalloc(sizeof(RT_CHANNEL_LIST_INFO), MEM_ALLOC_FLAG);
-				if (pChListBuf == NULL)
-				{
-					wrq->u.data.length = 0;
-					break;
-				}
-
-				pChListBuf->ChannelListNum = pAd->ChannelListNum;
-				for (i = 0; i < pChListBuf->ChannelListNum; i++)
-					pChListBuf->ChannelList[i] = pAd->ChannelList[i].Channel;
-
-				wrq->u.data.length = sizeof(RT_CHANNEL_LIST_INFO);
-				Status = copy_to_user(wrq->u.data.pointer, pChListBuf, sizeof(RT_CHANNEL_LIST_INFO));
-				DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
-
-				if (pChListBuf)
-					kfree(pChListBuf);
-			}
-			break;
-
-		case OID_802_11_GET_COUNTRY_CODE:
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_COUNTRY_CODE \n"));
-			wrq->u.data.length = 2;
-			Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.CountryCode, 2);
-			DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
-			break;
-
-		case OID_802_11_GET_CHANNEL_GEOGRAPHY:
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CHANNEL_GEOGRAPHY \n"));
-			wrq->u.data.length = 1;
-			Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.Geography, 1);
-			DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
-			break;
-
-
-#ifdef QOS_DLS_SUPPORT
-		case RT_OID_802_11_QUERY_DLS:
-			wrq->u.data.length = sizeof(BOOLEAN);
-			Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.bDLSCapable, wrq->u.data.length);
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS(=%d)\n", pAd->CommonCfg.bDLSCapable));
-			break;
-
-		case RT_OID_802_11_QUERY_DLS_PARAM:
-			{
-				PRT_802_11_DLS_INFO	pDlsInfo = kmalloc(sizeof(RT_802_11_DLS_INFO), GFP_ATOMIC);
-				if (pDlsInfo == NULL)
-					break;
-
-				for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
-				{
-					RTMPMoveMemory(&pDlsInfo->Entry[i], &pAd->StaCfg.DLSEntry[i], sizeof(RT_802_11_DLS_UI));
-				}
-
-				pDlsInfo->num = MAX_NUM_OF_DLS_ENTRY;
-				wrq->u.data.length = sizeof(RT_802_11_DLS_INFO);
-				Status = copy_to_user(wrq->u.data.pointer, pDlsInfo, wrq->u.data.length);
-				DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS_PARAM\n"));
-
-				if (pDlsInfo)
-					kfree(pDlsInfo);
-			}
-			break;
-#endif // QOS_DLS_SUPPORT //
-
-		case OID_802_11_SET_PSPXLINK_MODE:
-			wrq->u.data.length = sizeof(BOOLEAN);
-            Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.PSPXlink, wrq->u.data.length);
-			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SET_PSPXLINK_MODE(=%d)\n", pAd->CommonCfg.PSPXlink));
-			break;
-
-
-        default:
-            DBGPRINT(RT_DEBUG_TRACE, ("Query::unknown IOCTL's subcmd = 0x%08x\n", cmd));
-            Status = -EOPNOTSUPP;
-            break;
-    }
-    return Status;
-}
-
-INT rt28xx_sta_ioctl(
-	IN	struct net_device	*net_dev,
-	IN	OUT	struct ifreq	*rq,
-	IN	INT					cmd)
-{
-	POS_COOKIE			pObj;
-	RTMP_ADAPTER        *pAd = NULL;
-	struct iwreq        *wrq = (struct iwreq *) rq;
-	BOOLEAN				StateMachineTouched = FALSE;
-	INT					Status = NDIS_STATUS_SUCCESS;
-	USHORT				subcmd;
-
-
-	pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
-	if (pAd == NULL)
-	{
-		/* if 1st open fail, pAd will be free;
-		   So the net_dev->priv will be NULL in 2rd open */
-		return -ENETDOWN;
-	}
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-    //check if the interface is down
-    if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-    {
-#ifdef CONFIG_APSTA_MIXED_SUPPORT
-	    if (wrq->u.data.pointer == NULL)
-	    {
-		    return Status;
-	    }
-
-	    if (strstr(wrq->u.data.pointer, "OpMode") == NULL)
-#endif // CONFIG_APSTA_MIXED_SUPPORT //
-		{
-            DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		    return -ENETDOWN;
-        }
-    }
-
-	{	// determine this ioctl command is comming from which interface.
-		pObj->ioctl_if_type = INT_MAIN;
-		pObj->ioctl_if = MAIN_MBSSID;
-	}
-
-	switch(cmd)
-	{
-#ifdef RALINK_ATE
-#ifdef RALINK_28xx_QA
-		case RTPRIV_IOCTL_ATE:
-			{
-				RtmpDoAte(pAd, wrq);
-			}
-			break;
-#endif // RALINK_28xx_QA //
-#endif // RALINK_ATE //
-        case SIOCGIFHWADDR:
-			DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIFHWADDR\n"));
-			memcpy(wrq->u.name, pAd->CurrentAddress, ETH_ALEN);
-			break;
-		case SIOCGIWNAME:
-        {
-		char *name=&wrq->u.name[0];
-		rt_ioctl_giwname(net_dev, NULL, name, NULL);
-            break;
-		}
-		case SIOCGIWESSID:  //Get ESSID
-        {
-		struct iw_point *essid=&wrq->u.essid;
-		rt_ioctl_giwessid(net_dev, NULL, essid, essid->pointer);
-            break;
-		}
-		case SIOCSIWESSID:  //Set ESSID
-		{
-		struct iw_point	*essid=&wrq->u.essid;
-		rt_ioctl_siwessid(net_dev, NULL, essid, essid->pointer);
-            break;
-		}
-		case SIOCSIWNWID:   // set network id (the cell)
-		case SIOCGIWNWID:   // get network id
-			Status = -EOPNOTSUPP;
-			break;
-		case SIOCSIWFREQ:   //set channel/frequency (Hz)
-		{
-		struct iw_freq *freq=&wrq->u.freq;
-		rt_ioctl_siwfreq(net_dev, NULL, freq, NULL);
-			break;
-		}
-		case SIOCGIWFREQ:   // get channel/frequency (Hz)
-		{
-		struct iw_freq *freq=&wrq->u.freq;
-		rt_ioctl_giwfreq(net_dev, NULL, freq, NULL);
-			break;
-		}
-		case SIOCSIWNICKN: //set node name/nickname
-		{
-		//struct iw_point *data=&wrq->u.data;
-		//rt_ioctl_siwnickn(net_dev, NULL, data, NULL);
-			break;
-			}
-		case SIOCGIWNICKN: //get node name/nickname
-        {
-			struct iw_point	*erq = NULL;
-		erq = &wrq->u.data;
-            erq->length = strlen((PSTRING) pAd->nickname);
-            Status = copy_to_user(erq->pointer, pAd->nickname, erq->length);
-			break;
-		}
-		case SIOCGIWRATE:   //get default bit rate (bps)
-		    rt_ioctl_giwrate(net_dev, NULL, &wrq->u, NULL);
-            break;
-	    case SIOCSIWRATE:  //set default bit rate (bps)
-	        rt_ioctl_siwrate(net_dev, NULL, &wrq->u, NULL);
-            break;
-        case SIOCGIWRTS:  // get RTS/CTS threshold (bytes)
-		{
-		struct iw_param *rts=&wrq->u.rts;
-		rt_ioctl_giwrts(net_dev, NULL, rts, NULL);
-            break;
-		}
-        case SIOCSIWRTS:  //set RTS/CTS threshold (bytes)
-		{
-		struct iw_param *rts=&wrq->u.rts;
-		rt_ioctl_siwrts(net_dev, NULL, rts, NULL);
-            break;
-		}
-        case SIOCGIWFRAG:  //get fragmentation thr (bytes)
-		{
-		struct iw_param *frag=&wrq->u.frag;
-		rt_ioctl_giwfrag(net_dev, NULL, frag, NULL);
-            break;
-		}
-        case SIOCSIWFRAG:  //set fragmentation thr (bytes)
-		{
-		struct iw_param *frag=&wrq->u.frag;
-		rt_ioctl_siwfrag(net_dev, NULL, frag, NULL);
-            break;
-		}
-        case SIOCGIWENCODE:  //get encoding token & mode
-		{
-		struct iw_point *erq=&wrq->u.encoding;
-		if(erq)
-			rt_ioctl_giwencode(net_dev, NULL, erq, erq->pointer);
-            break;
-		}
-        case SIOCSIWENCODE:  //set encoding token & mode
-		{
-		struct iw_point *erq=&wrq->u.encoding;
-		if(erq)
-			rt_ioctl_siwencode(net_dev, NULL, erq, erq->pointer);
-            break;
-		}
-		case SIOCGIWAP:     //get access point MAC addresses
-		{
-		struct sockaddr *ap_addr=&wrq->u.ap_addr;
-		rt_ioctl_giwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
-			break;
-		}
-	    case SIOCSIWAP:  //set access point MAC addresses
-		{
-		struct sockaddr *ap_addr=&wrq->u.ap_addr;
-		rt_ioctl_siwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
-            break;
-		}
-		case SIOCGIWMODE:   //get operation mode
-		{
-		__u32 *mode=&wrq->u.mode;
-		rt_ioctl_giwmode(net_dev, NULL, mode, NULL);
-            break;
-		}
-		case SIOCSIWMODE:   //set operation mode
-		{
-		__u32 *mode=&wrq->u.mode;
-		rt_ioctl_siwmode(net_dev, NULL, mode, NULL);
-            break;
-		}
-		case SIOCGIWSENS:   //get sensitivity (dBm)
-		case SIOCSIWSENS:	//set sensitivity (dBm)
-		case SIOCGIWPOWER:  //get Power Management settings
-		case SIOCSIWPOWER:  //set Power Management settings
-		case SIOCGIWTXPOW:  //get transmit power (dBm)
-		case SIOCSIWTXPOW:  //set transmit power (dBm)
-		case SIOCGIWRANGE:	//Get range of parameters
-		case SIOCGIWRETRY:	//get retry limits and lifetime
-		case SIOCSIWRETRY:	//set retry limits and lifetime
-			Status = -EOPNOTSUPP;
-			break;
-		case RT_PRIV_IOCTL:
-        case RT_PRIV_IOCTL_EXT:
-			subcmd = wrq->u.data.flags;
-			if( subcmd & OID_GET_SET_TOGGLE)
-				Status = RTMPSetInformation(pAd, rq, subcmd);
-			else
-				Status = RTMPQueryInformation(pAd, rq, subcmd);
-			break;
-		case SIOCGIWPRIV:
-			if (wrq->u.data.pointer)
-			{
-				if ( access_ok(VERIFY_WRITE, wrq->u.data.pointer, sizeof(privtab)) != TRUE)
-					break;
-				wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
-				if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
-					Status = -EFAULT;
-			}
-			break;
-		case RTPRIV_IOCTL_SET:
-			if(access_ok(VERIFY_READ, wrq->u.data.pointer, wrq->u.data.length) != TRUE)
-					break;
-			rt_ioctl_setparam(net_dev, NULL, NULL, wrq->u.data.pointer);
-			break;
-		case RTPRIV_IOCTL_GSITESURVEY:
-			RTMPIoctlGetSiteSurvey(pAd, wrq);
-		    break;
-#ifdef DBG
-		case RTPRIV_IOCTL_MAC:
-			RTMPIoctlMAC(pAd, wrq);
-			break;
-		case RTPRIV_IOCTL_E2P:
-			RTMPIoctlE2PROM(pAd, wrq);
-			break;
-#ifdef RTMP_RF_RW_SUPPORT
-		case RTPRIV_IOCTL_RF:
-			RTMPIoctlRF(pAd, wrq);
-			break;
-#endif // RTMP_RF_RW_SUPPORT //
-#endif // DBG //
-
-        case SIOCETHTOOL:
-                break;
-		default:
-			DBGPRINT(RT_DEBUG_ERROR, ("IOCTL::unknown IOCTL's cmd = 0x%08x\n", cmd));
-			Status = -EOPNOTSUPP;
-			break;
-	}
-
-    if(StateMachineTouched) // Upper layer sent a MLME-related operations
-	RTMP_MLME_HANDLER(pAd);
-
-	return Status;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set SSID
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_SSID_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg)
-{
-    NDIS_802_11_SSID                    Ssid, *pSsid=NULL;
-    BOOLEAN                             StateMachineTouched = FALSE;
-    int                                 success = TRUE;
-
-    if( strlen(arg) <= MAX_LEN_OF_SSID)
-    {
-        NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
-        if (strlen(arg) != 0)
-        {
-            NdisMoveMemory(Ssid.Ssid, arg, strlen(arg));
-            Ssid.SsidLength = strlen(arg);
-        }
-        else   //ANY ssid
-        {
-            Ssid.SsidLength = 0;
-	    memcpy(Ssid.Ssid, "", 0);
-		pAdapter->StaCfg.BssType = BSS_INFRA;
-		pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
-        pAdapter->StaCfg.WepStatus  = Ndis802_11EncryptionDisabled;
-	}
-        pSsid = &Ssid;
-
-        if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
-        {
-            RTMP_MLME_RESET_STATE_MACHINE(pAdapter);
-            DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
-        }
-
-		if ((pAdapter->StaCfg.WpaPassPhraseLen >= 8) &&
-			(pAdapter->StaCfg.WpaPassPhraseLen <= 64))
-		{
-			STRING passphrase_str[65] = {0};
-			UCHAR keyMaterial[40];
-
-			RTMPMoveMemory(passphrase_str, pAdapter->StaCfg.WpaPassPhrase, pAdapter->StaCfg.WpaPassPhraseLen);
-			RTMPZeroMemory(pAdapter->StaCfg.PMK, 32);
-			if (pAdapter->StaCfg.WpaPassPhraseLen == 64)
-			{
-			    AtoH((PSTRING) pAdapter->StaCfg.WpaPassPhrase, pAdapter->StaCfg.PMK, 32);
-			}
-			else
-			{
-			    PasswordHash((PSTRING) pAdapter->StaCfg.WpaPassPhrase, Ssid.Ssid, Ssid.SsidLength, keyMaterial);
-			    NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
-			}
-		}
-
-        pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
-        pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
-		pAdapter->bConfigChanged = TRUE;
-
-        MlmeEnqueue(pAdapter,
-                    MLME_CNTL_STATE_MACHINE,
-                    OID_802_11_SSID,
-                    sizeof(NDIS_802_11_SSID),
-                    (VOID *)pSsid);
-
-        StateMachineTouched = TRUE;
-        DBGPRINT(RT_DEBUG_TRACE, ("Set_SSID_Proc::(Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
-    }
-    else
-        success = FALSE;
-
-    if (StateMachineTouched) // Upper layer sent a MLME-related operations
-	RTMP_MLME_HANDLER(pAdapter);
-
-    return success;
-}
-
-#ifdef WMM_SUPPORT
-/*
-    ==========================================================================
-    Description:
-        Set WmmCapable Enable or Disable
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT	Set_WmmCapable_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	BOOLEAN	bWmmCapable;
-
-	bWmmCapable = simple_strtol(arg, 0, 10);
-
-	if ((bWmmCapable == 1)
-		)
-		pAd->CommonCfg.bWmmCapable = TRUE;
-	else if (bWmmCapable == 0)
-		pAd->CommonCfg.bWmmCapable = FALSE;
-	else
-		return FALSE;  //Invalid argument
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Set_WmmCapable_Proc::(bWmmCapable=%d)\n",
-		pAd->CommonCfg.bWmmCapable));
-
-	return TRUE;
-}
-#endif // WMM_SUPPORT //
-
-/*
-    ==========================================================================
-    Description:
-        Set Network Type(Infrastructure/Adhoc mode)
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_NetworkType_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg)
-{
-    UINT32	Value = 0;
-
-    if (strcmp(arg, "Adhoc") == 0)
-	{
-		if (pAdapter->StaCfg.BssType != BSS_ADHOC)
-		{
-			// Config has changed
-			pAdapter->bConfigChanged = TRUE;
-            if (MONITOR_ON(pAdapter))
-            {
-                RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
-                RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
-				Value &= (~0x80);
-				RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
-                OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
-                pAdapter->StaCfg.bAutoReconnect = TRUE;
-                LinkDown(pAdapter, FALSE);
-            }
-			if (INFRA_ON(pAdapter))
-			{
-				//BOOLEAN Cancelled;
-				// Set the AutoReconnectSsid to prevent it reconnect to old SSID
-				// Since calling this indicate user don't want to connect to that SSID anymore.
-				pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
-				NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
-
-				LinkDown(pAdapter, FALSE);
-
-				DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event BB!\n"));
-			}
-		}
-		pAdapter->StaCfg.BssType = BSS_ADHOC;
-        pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
-		DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(AD-HOC)\n"));
-	}
-    else if (strcmp(arg, "Infra") == 0)
-	{
-		if (pAdapter->StaCfg.BssType != BSS_INFRA)
-		{
-			// Config has changed
-			pAdapter->bConfigChanged = TRUE;
-            if (MONITOR_ON(pAdapter))
-            {
-                RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
-                RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
-				Value &= (~0x80);
-				RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
-                OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
-                pAdapter->StaCfg.bAutoReconnect = TRUE;
-                LinkDown(pAdapter, FALSE);
-            }
-			if (ADHOC_ON(pAdapter))
-			{
-				// Set the AutoReconnectSsid to prevent it reconnect to old SSID
-				// Since calling this indicate user don't want to connect to that SSID anymore.
-				pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
-				NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
-
-				LinkDown(pAdapter, FALSE);
-			}
-		}
-		pAdapter->StaCfg.BssType = BSS_INFRA;
-        pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
-		DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(INFRA)\n"));
-	}
-    else if (strcmp(arg, "Monitor") == 0)
-    {
-			UCHAR	bbpValue = 0;
-			BCN_TIME_CFG_STRUC csr;
-			OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_INFRA_ON);
-            OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_ADHOC_ON);
-			OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
-			// disable all periodic state machine
-			pAdapter->StaCfg.bAutoReconnect = FALSE;
-			// reset all mlme state machine
-			RTMP_MLME_RESET_STATE_MACHINE(pAdapter);
-			DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_MEDIA_STATE_CONNECTED \n"));
-            if (pAdapter->CommonCfg.CentralChannel == 0)
-            {
-#ifdef DOT11_N_SUPPORT
-                if (pAdapter->CommonCfg.PhyMode == PHY_11AN_MIXED)
-                    pAdapter->CommonCfg.CentralChannel = 36;
-                else
-#endif // DOT11_N_SUPPORT //
-                    pAdapter->CommonCfg.CentralChannel = 6;
-            }
-#ifdef DOT11_N_SUPPORT
-            else
-                N_ChannelCheck(pAdapter);
-#endif // DOT11_N_SUPPORT //
-
-#ifdef DOT11_N_SUPPORT
-			if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
-                pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
-                pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
-			{
-				// 40MHz ,control channel at lower
-				RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
-				bbpValue &= (~0x18);
-				bbpValue |= 0x10;
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
-				pAdapter->CommonCfg.BBPCurrentBW = BW_40;
-				//  RX : control channel at lower
-				RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
-				bbpValue &= (~0x20);
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
-
-				RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
-				Value &= 0xfffffffe;
-				RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
-				pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel + 2;
-                AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
-			    AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
-                DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
-                                           pAdapter->CommonCfg.Channel,
-                                           pAdapter->CommonCfg.CentralChannel));
-			}
-			else if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
-                     pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
-                     pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW)
-			{
-				// 40MHz ,control channel at upper
-				RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
-				bbpValue &= (~0x18);
-				bbpValue |= 0x10;
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
-				pAdapter->CommonCfg.BBPCurrentBW = BW_40;
-				RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
-				Value |= 0x1;
-				RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
-
-				RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
-				bbpValue |= (0x20);
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
-				pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel - 2;
-                AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
-			    AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
-                DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
-                                           pAdapter->CommonCfg.Channel,
-                                           pAdapter->CommonCfg.CentralChannel));
-			}
-			else
-#endif // DOT11_N_SUPPORT //
-			{
-				// 20MHz
-				RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
-				bbpValue &= (~0x18);
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
-				pAdapter->CommonCfg.BBPCurrentBW = BW_20;
-                AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.Channel, FALSE);
-			    AsicLockChannel(pAdapter, pAdapter->CommonCfg.Channel);
-				DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAdapter->CommonCfg.Channel));
-			}
-			// Enable Rx with promiscuous reception
-			RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, 0x3);
-			// ASIC supporsts sniffer function with replacing RSSI with timestamp.
-			//RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
-			//Value |= (0x80);
-			//RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
-			// disable sync
-			RTMP_IO_READ32(pAdapter, BCN_TIME_CFG, &csr.word);
-			csr.field.bBeaconGen = 0;
-			csr.field.bTBTTEnable = 0;
-			csr.field.TsfSyncMode = 0;
-			RTMP_IO_WRITE32(pAdapter, BCN_TIME_CFG, csr.word);
-
-			pAdapter->StaCfg.BssType = BSS_MONITOR;
-            pAdapter->net_dev->type = ARPHRD_IEEE80211_PRISM; //ARPHRD_IEEE80211; // IEEE80211
-			DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(MONITOR)\n"));
-    }
-
-    // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
-    pAdapter->StaCfg.WpaState = SS_NOTUSE;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("Set_NetworkType_Proc::(NetworkType=%d)\n", pAdapter->StaCfg.BssType));
-
-    return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set Authentication mode
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_AuthMode_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg)
-{
-    if ((strcmp(arg, "WEPAUTO") == 0) || (strcmp(arg, "wepauto") == 0))
-        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
-    else if ((strcmp(arg, "OPEN") == 0) || (strcmp(arg, "open") == 0))
-        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
-    else if ((strcmp(arg, "SHARED") == 0) || (strcmp(arg, "shared") == 0))
-        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
-    else if ((strcmp(arg, "WPAPSK") == 0) || (strcmp(arg, "wpapsk") == 0))
-        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
-    else if ((strcmp(arg, "WPANONE") == 0) || (strcmp(arg, "wpanone") == 0))
-        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
-    else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "wpa2psk") == 0))
-        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
-#ifdef WPA_SUPPLICANT_SUPPORT
-    else if ((strcmp(arg, "WPA") == 0) || (strcmp(arg, "wpa") == 0))
-        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
-    else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "wpa2") == 0))
-        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
-#endif // WPA_SUPPLICANT_SUPPORT //
-    else
-        return FALSE;
-
-    pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("Set_AuthMode_Proc::(AuthMode=%d)\n", pAdapter->StaCfg.AuthMode));
-
-    return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set Encryption Type
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_EncrypType_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg)
-{
-    if ((strcmp(arg, "NONE") == 0) || (strcmp(arg, "none") == 0))
-    {
-        if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-            return TRUE;    // do nothing
-
-        pAdapter->StaCfg.WepStatus     = Ndis802_11WEPDisabled;
-        pAdapter->StaCfg.PairCipher    = Ndis802_11WEPDisabled;
-	    pAdapter->StaCfg.GroupCipher   = Ndis802_11WEPDisabled;
-    }
-    else if ((strcmp(arg, "WEP") == 0) || (strcmp(arg, "wep") == 0))
-    {
-        if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-            return TRUE;    // do nothing
-
-        pAdapter->StaCfg.WepStatus     = Ndis802_11WEPEnabled;
-        pAdapter->StaCfg.PairCipher    = Ndis802_11WEPEnabled;
-	    pAdapter->StaCfg.GroupCipher   = Ndis802_11WEPEnabled;
-    }
-    else if ((strcmp(arg, "TKIP") == 0) || (strcmp(arg, "tkip") == 0))
-    {
-        if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
-            return TRUE;    // do nothing
-
-        pAdapter->StaCfg.WepStatus     = Ndis802_11Encryption2Enabled;
-        pAdapter->StaCfg.PairCipher    = Ndis802_11Encryption2Enabled;
-	    pAdapter->StaCfg.GroupCipher   = Ndis802_11Encryption2Enabled;
-    }
-    else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "aes") == 0))
-    {
-        if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
-            return TRUE;    // do nothing
-
-        pAdapter->StaCfg.WepStatus     = Ndis802_11Encryption3Enabled;
-        pAdapter->StaCfg.PairCipher    = Ndis802_11Encryption3Enabled;
-	    pAdapter->StaCfg.GroupCipher   = Ndis802_11Encryption3Enabled;
-    }
-    else
-        return FALSE;
-
-    pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("Set_EncrypType_Proc::(EncrypType=%d)\n", pAdapter->StaCfg.WepStatus));
-
-    return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set Default Key ID
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_DefaultKeyID_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg)
-{
-    ULONG                               KeyIdx;
-
-    KeyIdx = simple_strtol(arg, 0, 10);
-    if((KeyIdx >= 1 ) && (KeyIdx <= 4))
-        pAdapter->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1 );
-    else
-        return FALSE;  //Invalid argument
-
-    DBGPRINT(RT_DEBUG_TRACE, ("Set_DefaultKeyID_Proc::(DefaultKeyID=%d)\n", pAdapter->StaCfg.DefaultKeyId));
-
-    return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set WEP KEY1
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_Key1_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg)
-{
-    int                                 KeyLen;
-    int                                 i;
-    UCHAR                               CipherAlg=CIPHER_WEP64;
-
-    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-        return TRUE;    // do nothing
-
-    KeyLen = strlen(arg);
-
-    switch (KeyLen)
-    {
-        case 5: //wep 40 Ascii type
-            pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
-            memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
-            CipherAlg = CIPHER_WEP64;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
-            break;
-        case 10: //wep 40 Hex type
-            for(i=0; i < KeyLen; i++)
-            {
-                if( !isxdigit(*(arg+i)) )
-                    return FALSE;  //Not Hex value;
-            }
-            pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
-            AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
-            CipherAlg = CIPHER_WEP64;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
-            break;
-        case 13: //wep 104 Ascii type
-            pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
-            memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
-            CipherAlg = CIPHER_WEP128;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
-            break;
-        case 26: //wep 104 Hex type
-            for(i=0; i < KeyLen; i++)
-            {
-                if( !isxdigit(*(arg+i)) )
-                    return FALSE;  //Not Hex value;
-            }
-            pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
-            AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
-            CipherAlg = CIPHER_WEP128;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
-            break;
-        default: //Invalid argument
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::Invalid argument (=%s)\n", arg));
-            return FALSE;
-    }
-
-    pAdapter->SharedKey[BSS0][0].CipherAlg = CipherAlg;
-
-    // Set keys (into ASIC)
-    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-        ;   // not support
-    else    // Old WEP stuff
-    {
-        AsicAddSharedKeyEntry(pAdapter,
-                              0,
-                              0,
-                              pAdapter->SharedKey[BSS0][0].CipherAlg,
-                              pAdapter->SharedKey[BSS0][0].Key,
-                              NULL,
-                              NULL);
-    }
-
-    return TRUE;
-}
-/*
-    ==========================================================================
-
-    Description:
-        Set WEP KEY2
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_Key2_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg)
-{
-    int                                 KeyLen;
-    int                                 i;
-    UCHAR                               CipherAlg=CIPHER_WEP64;
-
-    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-        return TRUE;    // do nothing
-
-    KeyLen = strlen(arg);
-
-    switch (KeyLen)
-    {
-        case 5: //wep 40 Ascii type
-            pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
-            memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
-            CipherAlg = CIPHER_WEP64;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
-            break;
-        case 10: //wep 40 Hex type
-            for(i=0; i < KeyLen; i++)
-            {
-                if( !isxdigit(*(arg+i)) )
-                    return FALSE;  //Not Hex value;
-            }
-            pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
-            AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
-            CipherAlg = CIPHER_WEP64;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
-            break;
-        case 13: //wep 104 Ascii type
-            pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
-            memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
-            CipherAlg = CIPHER_WEP128;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
-            break;
-        case 26: //wep 104 Hex type
-            for(i=0; i < KeyLen; i++)
-            {
-                if( !isxdigit(*(arg+i)) )
-                    return FALSE;  //Not Hex value;
-            }
-            pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
-            AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
-            CipherAlg = CIPHER_WEP128;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
-            break;
-        default: //Invalid argument
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::Invalid argument (=%s)\n", arg));
-            return FALSE;
-    }
-    pAdapter->SharedKey[BSS0][1].CipherAlg = CipherAlg;
-
-    // Set keys (into ASIC)
-    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-        ;   // not support
-    else    // Old WEP stuff
-    {
-        AsicAddSharedKeyEntry(pAdapter,
-                              0,
-                              1,
-                              pAdapter->SharedKey[BSS0][1].CipherAlg,
-                              pAdapter->SharedKey[BSS0][1].Key,
-                              NULL,
-                              NULL);
-    }
-
-    return TRUE;
-}
-/*
-    ==========================================================================
-    Description:
-        Set WEP KEY3
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_Key3_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg)
-{
-    int                                 KeyLen;
-    int                                 i;
-    UCHAR                               CipherAlg=CIPHER_WEP64;
-
-    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-        return TRUE;    // do nothing
-
-    KeyLen = strlen(arg);
-
-    switch (KeyLen)
-    {
-        case 5: //wep 40 Ascii type
-            pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
-            memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
-            CipherAlg = CIPHER_WEP64;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
-            break;
-        case 10: //wep 40 Hex type
-            for(i=0; i < KeyLen; i++)
-            {
-                if( !isxdigit(*(arg+i)) )
-                    return FALSE;  //Not Hex value;
-            }
-            pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
-            AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
-            CipherAlg = CIPHER_WEP64;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
-            break;
-        case 13: //wep 104 Ascii type
-            pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
-            memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
-            CipherAlg = CIPHER_WEP128;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
-            break;
-        case 26: //wep 104 Hex type
-            for(i=0; i < KeyLen; i++)
-            {
-                if( !isxdigit(*(arg+i)) )
-                    return FALSE;  //Not Hex value;
-            }
-            pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
-            AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
-            CipherAlg = CIPHER_WEP128;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
-            break;
-        default: //Invalid argument
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::Invalid argument (=%s)\n", arg));
-            return FALSE;
-    }
-    pAdapter->SharedKey[BSS0][2].CipherAlg = CipherAlg;
-
-    // Set keys (into ASIC)
-    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-        ;   // not support
-    else    // Old WEP stuff
-    {
-        AsicAddSharedKeyEntry(pAdapter,
-                              0,
-                              2,
-                              pAdapter->SharedKey[BSS0][2].CipherAlg,
-                              pAdapter->SharedKey[BSS0][2].Key,
-                              NULL,
-                              NULL);
-    }
-
-    return TRUE;
-}
-/*
-    ==========================================================================
-    Description:
-        Set WEP KEY4
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_Key4_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg)
-{
-    int                                 KeyLen;
-    int                                 i;
-    UCHAR                               CipherAlg=CIPHER_WEP64;
-
-    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-        return TRUE;    // do nothing
-
-    KeyLen = strlen(arg);
-
-    switch (KeyLen)
-    {
-        case 5: //wep 40 Ascii type
-            pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
-            memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
-            CipherAlg = CIPHER_WEP64;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
-            break;
-        case 10: //wep 40 Hex type
-            for(i=0; i < KeyLen; i++)
-            {
-                if( !isxdigit(*(arg+i)) )
-                    return FALSE;  //Not Hex value;
-            }
-            pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
-            AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
-            CipherAlg = CIPHER_WEP64;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
-            break;
-        case 13: //wep 104 Ascii type
-            pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
-            memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
-            CipherAlg = CIPHER_WEP128;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
-            break;
-        case 26: //wep 104 Hex type
-            for(i=0; i < KeyLen; i++)
-            {
-                if( !isxdigit(*(arg+i)) )
-                    return FALSE;  //Not Hex value;
-            }
-            pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
-            AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
-            CipherAlg = CIPHER_WEP128;
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
-            break;
-        default: //Invalid argument
-            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::Invalid argument (=%s)\n", arg));
-            return FALSE;
-    }
-    pAdapter->SharedKey[BSS0][3].CipherAlg = CipherAlg;
-
-    // Set keys (into ASIC)
-    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-        ;   // not support
-    else    // Old WEP stuff
-    {
-        AsicAddSharedKeyEntry(pAdapter,
-                              0,
-                              3,
-                              pAdapter->SharedKey[BSS0][3].CipherAlg,
-                              pAdapter->SharedKey[BSS0][3].Key,
-                              NULL,
-                              NULL);
-    }
-
-    return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set WPA PSK key
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_WPAPSK_Proc(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PSTRING          arg)
-{
-    int status;
-
-    if ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
-        (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
-	    (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
-		)
-        return TRUE;    // do nothing
-
-    DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc::(WPAPSK=%s)\n", arg));
-
-	status = RT_CfgSetWPAPSKKey(pAd, arg, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, pAd->StaCfg.PMK);
-	if (status == FALSE)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc(): Set key failed!\n"));
-		return FALSE;
-	}
-	NdisZeroMemory(pAd->StaCfg.WpaPassPhrase, 64);
-    NdisMoveMemory(pAd->StaCfg.WpaPassPhrase, arg, strlen(arg));
-    pAd->StaCfg.WpaPassPhraseLen = (UINT)strlen(arg);
-
-
-
-    if(pAd->StaCfg.BssType == BSS_ADHOC &&
-       pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
-    {
-        pAd->StaCfg.WpaState = SS_NOTUSE;
-    }
-    else
-    {
-        // Start STA supplicant state machine
-        pAd->StaCfg.WpaState = SS_START;
-    }
-
-    return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set Power Saving mode
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_PSMode_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg)
-{
-    if (pAdapter->StaCfg.BssType == BSS_INFRA)
-    {
-        if ((strcmp(arg, "Max_PSP") == 0) ||
-			(strcmp(arg, "max_psp") == 0) ||
-			(strcmp(arg, "MAX_PSP") == 0))
-        {
-            // do NOT turn on PSM bit here, wait until MlmeCheckPsmChange()
-            // to exclude certain situations.
-            if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
-                pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
-            pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
-            OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
-            pAdapter->StaCfg.DefaultListenCount = 5;
-
-        }
-        else if ((strcmp(arg, "Fast_PSP") == 0) ||
-				 (strcmp(arg, "fast_psp") == 0) ||
-                 (strcmp(arg, "FAST_PSP") == 0))
-        {
-            // do NOT turn on PSM bit here, wait until MlmeCheckPsmChange()
-            // to exclude certain situations.
-            OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
-            if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
-                pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
-            pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
-            pAdapter->StaCfg.DefaultListenCount = 3;
-        }
-        else if ((strcmp(arg, "Legacy_PSP") == 0) ||
-                 (strcmp(arg, "legacy_psp") == 0) ||
-                 (strcmp(arg, "LEGACY_PSP") == 0))
-        {
-            // do NOT turn on PSM bit here, wait until MlmeCheckPsmChange()
-            // to exclude certain situations.
-            OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
-            if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
-                pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
-            pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
-            pAdapter->StaCfg.DefaultListenCount = 3;
-        }
-        else
-        {
-            //Default Ndis802_11PowerModeCAM
-            // clear PSM bit immediately
-            RTMP_SET_PSM_BIT(pAdapter, PWR_ACTIVE);
-            OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
-            if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
-                pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
-            pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
-        }
-
-        DBGPRINT(RT_DEBUG_TRACE, ("Set_PSMode_Proc::(PSMode=%ld)\n", pAdapter->StaCfg.WindowsPowerMode));
-    }
-    else
-        return FALSE;
-
-
-    return TRUE;
-}
-//Add to suport the function which clould dynamicallly enable/disable PCIe Power Saving
-
-#ifdef WPA_SUPPLICANT_SUPPORT
-/*
-    ==========================================================================
-    Description:
-        Set WpaSupport flag.
-    Value:
-        0: Driver ignore wpa_supplicant.
-        1: wpa_supplicant initiates scanning and AP selection.
-        2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters.
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-INT Set_Wpa_Support(
-    IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-
-    if ( simple_strtol(arg, 0, 10) == 0)
-        pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
-    else if ( simple_strtol(arg, 0, 10) == 1)
-        pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
-    else if ( simple_strtol(arg, 0, 10) == 2)
-        pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE_WITH_WEB_UI;
-    else
-        pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("Set_Wpa_Support::(WpaSupplicantUP=%d)\n", pAd->StaCfg.WpaSupplicantUP));
-
-    return TRUE;
-}
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-#ifdef DBG
-/*
-    ==========================================================================
-    Description:
-        Read / Write MAC
-    Arguments:
-        pAdapter                    Pointer to our adapter
-        wrq                         Pointer to the ioctl argument
-
-    Return Value:
-        None
-
-    Note:
-        Usage:
-               1.) iwpriv ra0 mac 0        ==> read MAC where Addr=0x0
-               2.) iwpriv ra0 mac 0=12     ==> write MAC where Addr=0x0, value=12
-    ==========================================================================
-*/
-VOID RTMPIoctlMAC(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq)
-{
-	PSTRING				this_char;
-	PSTRING				value;
-	INT					j = 0, k = 0;
-	STRING				msg[1024];
-	STRING				arg[255];
-	ULONG				macAddr = 0;
-	UCHAR				temp[16];
-	STRING				temp2[16];
-	UINT32				macValue = 0;
-	INT					Status;
-	BOOLEAN				bIsPrintAllMAC = FALSE;
-
-
-	memset(msg, 0x00, 1024);
-	if (wrq->u.data.length > 1) //No parameters.
-	{
-	    Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
-		sprintf(msg, "\n");
-
-		//Parsing Read or Write
-	    this_char = arg;
-		if (!*this_char)
-			goto next;
-
-		if ((value = rtstrchr(this_char, '=')) != NULL)
-			*value++ = 0;
-
-		if (!value || !*value)
-		{ //Read
-			// Sanity check
-			if(strlen(this_char) > 4)
-				goto next;
-
-			j = strlen(this_char);
-			while(j-- > 0)
-			{
-				if(this_char[j] > 'f' || this_char[j] < '0')
-					return;
-			}
-
-			// Mac Addr
-			k = j = strlen(this_char);
-			while(j-- > 0)
-			{
-				this_char[4-k+j] = this_char[j];
-			}
-
-			while(k < 4)
-				this_char[3-k++]='0';
-			this_char[4]='\0';
-
-			if(strlen(this_char) == 4)
-			{
-				AtoH(this_char, temp, 2);
-				macAddr = *temp*256 + temp[1];
-				if (macAddr < 0xFFFF)
-				{
-					RTMP_IO_READ32(pAdapter, macAddr, &macValue);
-					DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%lx, MacValue=%x\n", macAddr, macValue));
-					sprintf(msg+strlen(msg), "[0x%08lX]:%08X  ", macAddr , macValue);
-				}
-				else
-				{//Invalid parametes, so default printk all mac
-					bIsPrintAllMAC = TRUE;
-					goto next;
-				}
-			}
-		}
-		else
-		{ //Write
-			memcpy(&temp2, value, strlen(value));
-			temp2[strlen(value)] = '\0';
-
-			// Sanity check
-			if((strlen(this_char) > 4) || strlen(temp2) > 8)
-				goto next;
-
-			j = strlen(this_char);
-			while(j-- > 0)
-			{
-				if(this_char[j] > 'f' || this_char[j] < '0')
-					return;
-			}
-
-			j = strlen(temp2);
-			while(j-- > 0)
-			{
-				if(temp2[j] > 'f' || temp2[j] < '0')
-					return;
-			}
-
-			//MAC Addr
-			k = j = strlen(this_char);
-			while(j-- > 0)
-			{
-				this_char[4-k+j] = this_char[j];
-			}
-
-			while(k < 4)
-				this_char[3-k++]='0';
-			this_char[4]='\0';
-
-			//MAC value
-			k = j = strlen(temp2);
-			while(j-- > 0)
-			{
-				temp2[8-k+j] = temp2[j];
-			}
-
-			while(k < 8)
-				temp2[7-k++]='0';
-			temp2[8]='\0';
-
-			{
-				AtoH(this_char, temp, 2);
-				macAddr = *temp*256 + temp[1];
-
-				AtoH(temp2, temp, 4);
-				macValue = *temp*256*256*256 + temp[1]*256*256 + temp[2]*256 + temp[3];
-
-				// debug mode
-				if (macAddr == (HW_DEBUG_SETTING_BASE + 4))
-				{
-					// 0x2bf4: byte0 non-zero: enable R17 tuning, 0: disable R17 tuning
-                    if (macValue & 0x000000ff)
-                    {
-                        pAdapter->BbpTuning.bEnable = TRUE;
-                        DBGPRINT(RT_DEBUG_TRACE,("turn on R17 tuning\n"));
-                    }
-                    else
-                    {
-                        UCHAR R66;
-                        pAdapter->BbpTuning.bEnable = FALSE;
-                        R66 = 0x26 + GET_LNA_GAIN(pAdapter);
-#ifdef RALINK_ATE
-						if (ATE_ON(pAdapter))
-						{
-							ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
-						}
-						else
-#endif // RALINK_ATE //
-
-							RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
-                        DBGPRINT(RT_DEBUG_TRACE,("turn off R17 tuning, restore to 0x%02x\n", R66));
-                    }
-					return;
-				}
-
-				DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%02lx, MacValue=0x%x\n", macAddr, macValue));
-
-				RTMP_IO_WRITE32(pAdapter, macAddr, macValue);
-				sprintf(msg+strlen(msg), "[0x%08lX]:%08X  ", macAddr, macValue);
-			}
-		}
-	}
-	else
-		bIsPrintAllMAC = TRUE;
-next:
-	if (bIsPrintAllMAC)
-	{
-		struct file		*file_w;
-		PSTRING			fileName = "MacDump.txt";
-		mm_segment_t	orig_fs;
-
-		orig_fs = get_fs();
-		set_fs(KERNEL_DS);
-
-		// open file
-		file_w = filp_open(fileName, O_WRONLY|O_CREAT, 0);
-		if (IS_ERR(file_w))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("-->2) %s: Error %ld opening %s\n", __FUNCTION__, -PTR_ERR(file_w), fileName));
-		}
-		else
-		{
-			if (file_w->f_op && file_w->f_op->write)
-			{
-				file_w->f_pos = 0;
-				macAddr = 0x1000;
-
-				while (macAddr <= 0x1800)
-				{
-					RTMP_IO_READ32(pAdapter, macAddr, &macValue);
-					sprintf(msg, "%08lx = %08X\n", macAddr, macValue);
-
-					// write data to file
-					file_w->f_op->write(file_w, msg, strlen(msg), &file_w->f_pos);
-
-					printk("%s", msg);
-					macAddr += 4;
-				}
-				sprintf(msg, "\nDump all MAC values to %s\n", fileName);
-			}
-			filp_close(file_w, NULL);
-		}
-		set_fs(orig_fs);
-	}
-	if(strlen(msg) == 1)
-		sprintf(msg+strlen(msg), "===>Error command format!");
-
-	// Copy the information into the user buffer
-	wrq->u.data.length = strlen(msg);
-	Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlMAC\n\n"));
-}
-
-/*
-    ==========================================================================
-    Description:
-        Read / Write E2PROM
-    Arguments:
-        pAdapter                    Pointer to our adapter
-        wrq                         Pointer to the ioctl argument
-
-    Return Value:
-        None
-
-    Note:
-        Usage:
-               1.) iwpriv ra0 e2p 0		==> read E2PROM where Addr=0x0
-               2.) iwpriv ra0 e2p 0=1234    ==> write E2PROM where Addr=0x0, value=1234
-    ==========================================================================
-*/
-VOID RTMPIoctlE2PROM(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq)
-{
-	PSTRING				this_char;
-	PSTRING				value;
-	INT					j = 0, k = 0;
-	STRING				msg[1024];
-	STRING				arg[255];
-	USHORT				eepAddr = 0;
-	UCHAR				temp[16];
-	STRING				temp2[16];
-	USHORT				eepValue;
-	int					Status;
-	BOOLEAN				bIsPrintAllE2P = FALSE;
-
-
-	memset(msg, 0x00, 1024);
-	if (wrq->u.data.length > 1) //No parameters.
-	{
-	    Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
-		sprintf(msg, "\n");
-
-	    //Parsing Read or Write
-		this_char = arg;
-
-
-		if (!*this_char)
-			goto next;
-
-		if ((value = rtstrchr(this_char, '=')) != NULL)
-			*value++ = 0;
-
-		if (!value || !*value)
-		{ //Read
-
-			// Sanity check
-			if(strlen(this_char) > 4)
-				goto next;
-
-			j = strlen(this_char);
-			while(j-- > 0)
-			{
-				if(this_char[j] > 'f' || this_char[j] < '0')
-					return;
-			}
-
-			// E2PROM addr
-			k = j = strlen(this_char);
-			while(j-- > 0)
-			{
-				this_char[4-k+j] = this_char[j];
-			}
-
-			while(k < 4)
-				this_char[3-k++]='0';
-			this_char[4]='\0';
-
-			if(strlen(this_char) == 4)
-			{
-				AtoH(this_char, temp, 2);
-				eepAddr = *temp*256 + temp[1];
-				if (eepAddr < 0xFFFF)
-				{
-					RT28xx_EEPROM_READ16(pAdapter, eepAddr, eepValue);
-					sprintf(msg+strlen(msg), "[0x%04X]:0x%04X  ", eepAddr , eepValue);
-				}
-				else
-				{//Invalid parametes, so default printk all bbp
-					bIsPrintAllE2P = TRUE;
-					goto next;
-				}
-			}
-		}
-		else
-		{ //Write
-			memcpy(&temp2, value, strlen(value));
-			temp2[strlen(value)] = '\0';
-
-			// Sanity check
-			if((strlen(this_char) > 4) || strlen(temp2) > 8)
-				goto next;
-
-			j = strlen(this_char);
-			while(j-- > 0)
-			{
-				if(this_char[j] > 'f' || this_char[j] < '0')
-					return;
-			}
-			j = strlen(temp2);
-			while(j-- > 0)
-			{
-				if(temp2[j] > 'f' || temp2[j] < '0')
-					return;
-			}
-
-			//MAC Addr
-			k = j = strlen(this_char);
-			while(j-- > 0)
-			{
-				this_char[4-k+j] = this_char[j];
-			}
-
-			while(k < 4)
-				this_char[3-k++]='0';
-			this_char[4]='\0';
-
-			//MAC value
-			k = j = strlen(temp2);
-			while(j-- > 0)
-			{
-				temp2[4-k+j] = temp2[j];
-			}
-
-			while(k < 4)
-				temp2[3-k++]='0';
-			temp2[4]='\0';
-
-			AtoH(this_char, temp, 2);
-			eepAddr = *temp*256 + temp[1];
-
-			AtoH(temp2, temp, 2);
-			eepValue = *temp*256 + temp[1];
-
-			RT28xx_EEPROM_WRITE16(pAdapter, eepAddr, eepValue);
-			sprintf(msg+strlen(msg), "[0x%02X]:%02X  ", eepAddr, eepValue);
-		}
-	}
-	else
-		bIsPrintAllE2P = TRUE;
-next:
-	if (bIsPrintAllE2P)
-	{
-		struct file		*file_w;
-		PSTRING			fileName = "EEPROMDump.txt";
-		mm_segment_t	orig_fs;
-
-		orig_fs = get_fs();
-		set_fs(KERNEL_DS);
-
-		// open file
-		file_w = filp_open(fileName, O_WRONLY|O_CREAT, 0);
-		if (IS_ERR(file_w))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("-->2) %s: Error %ld opening %s\n", __FUNCTION__, -PTR_ERR(file_w), fileName));
-		}
-		else
-		{
-			if (file_w->f_op && file_w->f_op->write)
-			{
-				file_w->f_pos = 0;
-				eepAddr = 0x00;
-
-				while (eepAddr <= 0xFE)
-				{
-					RT28xx_EEPROM_READ16(pAdapter, eepAddr, eepValue);
-					sprintf(msg, "%08x = %04x\n", eepAddr , eepValue);
-
-					// write data to file
-					file_w->f_op->write(file_w, msg, strlen(msg), &file_w->f_pos);
-
-					printk("%s", msg);
-					eepAddr += 2;
-				}
-				sprintf(msg, "\nDump all EEPROM values to %s\n", fileName);
-			}
-			filp_close(file_w, NULL);
-		}
-		set_fs(orig_fs);
-	}
-	if(strlen(msg) == 1)
-		sprintf(msg+strlen(msg), "===>Error command format!");
-
-
-	// Copy the information into the user buffer
-	wrq->u.data.length = strlen(msg);
-	Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlE2PROM\n"));
-}
-
-
-#ifdef RT30xx
-/*
-    ==========================================================================
-    Description:
-        Read / Write RF register
-Arguments:
-    pAdapter                    Pointer to our adapter
-    wrq                         Pointer to the ioctl argument
-
-    Return Value:
-        None
-
-    Note:
-        Usage:
-               1.) iwpriv ra0 rf                ==> read all RF registers
-               2.) iwpriv ra0 rf 1              ==> read RF where RegID=1
-               3.) iwpriv ra0 rf 1=10		    ==> write RF R1=0x10
-    ==========================================================================
-*/
-VOID RTMPIoctlRF(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq)
-{
-	CHAR				*this_char;
-	CHAR				*value;
-	UCHAR				regRF = 0;
-	STRING				msg[2048];
-	CHAR				arg[255];
-	INT					rfId;
-	LONG				rfValue;
-	int					Status;
-	BOOLEAN				bIsPrintAllRF = FALSE;
-
-
-	memset(msg, 0x00, 2048);
-	if (wrq->u.data.length > 1) //No parameters.
-	{
-	    Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
-		sprintf(msg, "\n");
-
-	    //Parsing Read or Write
-		this_char = arg;
-		if (!*this_char)
-			goto next;
-
-		if ((value = strchr(this_char, '=')) != NULL)
-			*value++ = 0;
-
-		if (!value || !*value)
-		{ //Read
-			if (sscanf((PSTRING) this_char, "%d", &(rfId)) == 1)
-			{
-				if (rfId <= 31)
-				{
-#ifdef RALINK_ATE
-					/*
-						In RT2860 ATE mode, we do not load 8051 firmware.
-	                    We must access RF directly.
-						For RT2870 ATE mode, ATE_RF_IO_WRITE8(/READ8)_BY_REG_ID are redefined.
-					*/
-					if (ATE_ON(pAdapter))
-					{
-						ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
-					}
-					else
-#endif // RALINK_ATE //
-					// according to Andy, Gary, David require.
-					// the command rf shall read rf register directly for dubug.
-					// BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
-					RT30xxReadRFRegister(pAdapter, rfId, &regRF);
-
-					sprintf(msg+strlen(msg), "R%02d[0x%02x]:%02X  ", rfId, rfId, regRF);
-				}
-				else
-				{//Invalid parametes, so default printk all RF
-					bIsPrintAllRF = TRUE;
-					goto next;
-				}
-			}
-			else
-			{ //Invalid parametes, so default printk all RF
-				bIsPrintAllRF = TRUE;
-				goto next;
-			}
-		}
-		else
-		{ //Write
-			if ((sscanf((PSTRING) this_char, "%d", &(rfId)) == 1) && (sscanf((PSTRING) value, "%lx", &(rfValue)) == 1))
-			{
-				if (rfId <= 31)
-				{
-#ifdef RALINK_ATE
-						/*
-							In RT2860 ATE mode, we do not load 8051 firmware.
-		                    We must access RF directly.
-							For RT2870 ATE mode, ATE_RF_IO_WRITE8(/READ8)_BY_REG_ID are redefined.
-						*/
-						if (ATE_ON(pAdapter))
-						{
-							ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
-							ATE_RF_IO_WRITE8_BY_REG_ID(pAdapter, (UCHAR)rfId,(UCHAR) rfValue);
-							//Read it back for showing
-							ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
-							sprintf(msg+strlen(msg), "R%02d[0x%02X]:%02X\n", rfId, rfId, regRF);
-						}
-						else
-#endif // RALINK_ATE //
-						{
-							// according to Andy, Gary, David require.
-							// the command RF shall read/write RF register directly for dubug.
-							//BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
-							//BBP_IO_WRITE8_BY_REG_ID(pAdapter, (UCHAR)bbpId,(UCHAR) bbpValue);
-							RT30xxReadRFRegister(pAdapter, rfId, &regRF);
-							RT30xxWriteRFRegister(pAdapter, (UCHAR)rfId,(UCHAR) rfValue);
-							//Read it back for showing
-							//BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
-							RT30xxReadRFRegister(pAdapter, rfId, &regRF);
-			                sprintf(msg+strlen(msg), "R%02d[0x%02X]:%02X\n", rfId, rfId, regRF);
-				                }
-				}
-				else
-				{//Invalid parametes, so default printk all RF
-					bIsPrintAllRF = TRUE;
-				}
-			}
-			else
-			{ //Invalid parametes, so default printk all RF
-				bIsPrintAllRF = TRUE;
-			}
-		}
-	}
-	else
-		bIsPrintAllRF = TRUE;
-next:
-	if (bIsPrintAllRF)
-	{
-		memset(msg, 0x00, 2048);
-		sprintf(msg, "\n");
-		for (rfId = 0; rfId <= 31; rfId++)
-		{
-#ifdef RALINK_ATE
-			/*
-				In RT2860 ATE mode, we do not load 8051 firmware.
-                We must access RF directly.
-				For RT2870 ATE mode, ATE_RF_IO_WRITE8(/READ8)_BY_REG_ID are redefined.
-			*/
-			if (ATE_ON(pAdapter))
-			{
-				ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
-			}
-			else
-#endif // RALINK_ATE //
-
-			// according to Andy, Gary, David require.
-			// the command RF shall read/write RF register directly for dubug.
-			RT30xxReadRFRegister(pAdapter, rfId, &regRF);
-			sprintf(msg+strlen(msg), "%03d = %02X\n", rfId, regRF);
-		}
-		// Copy the information into the user buffer
-		DBGPRINT(RT_DEBUG_TRACE, ("strlen(msg)=%d\n", (UINT32)strlen(msg)));
-		wrq->u.data.length = strlen(msg);
-		if (copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __FUNCTION__));
-		}
-	}
-	else
-	{
-		if(strlen(msg) == 1)
-			sprintf(msg+strlen(msg), "===>Error command format!");
-
-		DBGPRINT(RT_DEBUG_TRACE, ("copy to user [msg=%s]\n", msg));
-		// Copy the information into the user buffer
-		DBGPRINT(RT_DEBUG_TRACE, ("strlen(msg) =%d\n", (UINT32)strlen(msg)));
-
-		// Copy the information into the user buffer
-		wrq->u.data.length = strlen(msg);
-		Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlRF\n\n"));
-}
-#endif // RT30xx //
-#endif // DBG //
-
-
-
-
-INT Set_TGnWifiTest_Proc(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PSTRING          arg)
-{
-    if (simple_strtol(arg, 0, 10) == 0)
-        pAd->StaCfg.bTGnWifiTest = FALSE;
-    else
-        pAd->StaCfg.bTGnWifiTest = TRUE;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("IF Set_TGnWifiTest_Proc::(bTGnWifiTest=%d)\n", pAd->StaCfg.bTGnWifiTest));
-	return TRUE;
-}
-
-#ifdef EXT_BUILD_CHANNEL_LIST
-INT Set_Ieee80211dClientMode_Proc(
-    IN  PRTMP_ADAPTER   pAdapter,
-    IN  PSTRING          arg)
-{
-    if (simple_strtol(arg, 0, 10) == 0)
-        pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_None;
-    else if (simple_strtol(arg, 0, 10) == 1)
-        pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Flexible;
-    else if (simple_strtol(arg, 0, 10) == 2)
-        pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Strict;
-    else
-        return FALSE;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("Set_Ieee802dMode_Proc::(IEEEE0211dMode=%d)\n", pAdapter->StaCfg.IEEE80211dClientMode));
-    return TRUE;
-}
-#endif // EXT_BUILD_CHANNEL_LIST //
-
-#ifdef CARRIER_DETECTION_SUPPORT
-INT Set_CarrierDetect_Proc(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PSTRING         arg)
-{
-    if (simple_strtol(arg, 0, 10) == 0)
-        pAd->CommonCfg.CarrierDetect.Enable = FALSE;
-    else
-        pAd->CommonCfg.CarrierDetect.Enable = TRUE;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("IF Set_CarrierDetect_Proc::(CarrierDetect.Enable=%d)\n", pAd->CommonCfg.CarrierDetect.Enable));
-	return TRUE;
-}
-#endif // CARRIER_DETECTION_SUPPORT //
-
-
-INT	Show_Adhoc_MacTable_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			extra)
-{
-	INT i;
-
-	sprintf(extra, "\n");
-
-#ifdef DOT11_N_SUPPORT
-	sprintf(extra, "%sHT Operating Mode : %d\n", extra, pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode);
-#endif // DOT11_N_SUPPORT //
-
-	sprintf(extra, "%s\n%-19s%-4s%-4s%-7s%-7s%-7s%-10s%-6s%-6s%-6s%-6s\n", extra,
-			"MAC", "AID", "BSS", "RSSI0", "RSSI1", "RSSI2", "PhMd", "BW", "MCS", "SGI", "STBC");
-
-	for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
-	{
-		PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
-
-		if (strlen(extra) > (IW_PRIV_SIZE_MASK - 30))
-		    break;
-		if ((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
-		{
-			sprintf(extra, "%s%02X:%02X:%02X:%02X:%02X:%02X  ", extra,
-				pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
-				pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
-			sprintf(extra, "%s%-4d", extra, (int)pEntry->Aid);
-			sprintf(extra, "%s%-4d", extra, (int)pEntry->apidx);
-			sprintf(extra, "%s%-7d", extra, pEntry->RssiSample.AvgRssi0);
-			sprintf(extra, "%s%-7d", extra, pEntry->RssiSample.AvgRssi1);
-			sprintf(extra, "%s%-7d", extra, pEntry->RssiSample.AvgRssi2);
-			sprintf(extra, "%s%-10s", extra, GetPhyMode(pEntry->HTPhyMode.field.MODE));
-			sprintf(extra, "%s%-6s", extra, GetBW(pEntry->HTPhyMode.field.BW));
-			sprintf(extra, "%s%-6d", extra, pEntry->HTPhyMode.field.MCS);
-			sprintf(extra, "%s%-6d", extra, pEntry->HTPhyMode.field.ShortGI);
-			sprintf(extra, "%s%-6d", extra, pEntry->HTPhyMode.field.STBC);
-			sprintf(extra, "%s%-10d, %d, %d%%\n", extra, pEntry->DebugFIFOCount, pEntry->DebugTxCount,
-						(pEntry->DebugTxCount) ? ((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount) : 0);
-			sprintf(extra, "%s\n", extra);
-		}
-	}
-
-	return TRUE;
-}
-
-
-INT Set_BeaconLostTime_Proc(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PSTRING         arg)
-{
-	ULONG ltmp = (ULONG)simple_strtol(arg, 0, 10);
-
-	if ((ltmp != 0) && (ltmp <= 60))
-		pAd->StaCfg.BeaconLostTime = (ltmp * OS_HZ);
-
-    DBGPRINT(RT_DEBUG_TRACE, ("IF Set_BeaconLostTime_Proc::(BeaconLostTime=%ld)\n", pAd->StaCfg.BeaconLostTime));
-	return TRUE;
-}
-
-INT Set_AutoRoaming_Proc(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PSTRING         arg)
-{
-    if (simple_strtol(arg, 0, 10) == 0)
-        pAd->StaCfg.bAutoRoaming = FALSE;
-    else
-        pAd->StaCfg.bAutoRoaming = TRUE;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("IF Set_AutoRoaming_Proc::(bAutoRoaming=%d)\n", pAd->StaCfg.bAutoRoaming));
-	return TRUE;
-}
-
-
-/*
-    ==========================================================================
-    Description:
-        Issue a site survey command to driver
-	Arguments:
-	    pAdapter                    Pointer to our adapter
-	    wrq                         Pointer to the ioctl argument
-
-    Return Value:
-        None
-
-    Note:
-        Usage:
-               1.) iwpriv ra0 set site_survey
-    ==========================================================================
-*/
-INT Set_SiteSurvey_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PSTRING			arg)
-{
-	NDIS_802_11_SSID Ssid;
-
-	//check if the interface is down
-	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	if (MONITOR_ON(pAd))
-    {
-        DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
-        return -EINVAL;
-    }
-
-	RTMPZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
-	Ssid.SsidLength = 0;
-	if ((arg != NULL) &&
-		(strlen(arg) <= MAX_LEN_OF_SSID))
-    {
-        RTMPMoveMemory(Ssid.Ssid, arg, strlen(arg));
-        Ssid.SsidLength = strlen(arg);
-	}
-
-	pAd->StaCfg.bScanReqIsFromWebUI = TRUE;
-
-	if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)
-	{
-		RTMP_MLME_RESET_STATE_MACHINE(pAd);
-		DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
-	}
-
-	// tell CNTL state machine to call NdisMSetInformationComplete() after completing
-	// this request, because this request is initiated by NDIS.
-	pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
-	// Reset allowed scan retries
-	pAd->StaCfg.ScanCnt = 0;
-	NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime);
-
-	MlmeEnqueue(pAd,
-		MLME_CNTL_STATE_MACHINE,
-		OID_802_11_BSSID_LIST_SCAN,
-		Ssid.SsidLength,
-		Ssid.Ssid);
-
-	RTMP_MLME_HANDLER(pAd);
-
-    DBGPRINT(RT_DEBUG_TRACE, ("Set_SiteSurvey_Proc\n"));
-
-    return TRUE;
-}
-
-INT Set_ForceTxBurst_Proc(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  PSTRING         arg)
-{
-    if (simple_strtol(arg, 0, 10) == 0)
-        pAd->StaCfg.bForceTxBurst = FALSE;
-    else
-        pAd->StaCfg.bForceTxBurst = TRUE;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ForceTxBurst_Proc::(bForceTxBurst=%d)\n", pAd->StaCfg.bForceTxBurst));
-	return TRUE;
-}
-
-#ifdef ANT_DIVERSITY_SUPPORT
-INT	Set_Antenna_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-    UCHAR UsedAnt;
-	DBGPRINT(RT_DEBUG_TRACE, ("==> Set_Antenna_Proc *******************\n"));
-
-    if(simple_strtol(arg, 0, 10) <= 3)
-        UsedAnt = simple_strtol(arg, 0, 10);
-
-    pAd->CommonCfg.bRxAntDiversity = UsedAnt; // Auto switch
-    if (UsedAnt == ANT_DIVERSITY_ENABLE)
-    {
-            pAd->RxAnt.EvaluateStableCnt = 0;
-            DBGPRINT(RT_DEBUG_TRACE, ("<== Set_Antenna_Proc(Auto Switch Mode), (%d,%d)\n", pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt));
-    }
-    /* 2: Fix in the PHY Antenna CON1*/
-    if (UsedAnt == ANT_FIX_ANT1)
-    {
-            AsicSetRxAnt(pAd, 0);
-            DBGPRINT(RT_DEBUG_TRACE, ("<== Set_Antenna_Proc(Fix in Ant CON1), (%d,%d)\n", pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt));
-    }
-    /* 3: Fix in the PHY Antenna CON2*/
-    if (UsedAnt == ANT_FIX_ANT2)
-    {
-            AsicSetRxAnt(pAd, 1);
-            DBGPRINT(RT_DEBUG_TRACE, ("<== Set_Antenna_Proc(Fix in Ant CON2), (%d,%d)\n", pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt));
-    }
-
-	return TRUE;
-}
-#endif // ANT_DIVERSITY_SUPPORT //
\ No newline at end of file
diff --git a/drivers/staging/rt3090/vr_ikans.h b/drivers/staging/rt3090/vr_ikans.h
deleted file mode 100644
index 16bff3b..0000000
--- a/drivers/staging/rt3090/vr_ikans.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	vr_ikans.h
-
-    Abstract:
-    Handle association related requests either from WSTA or from local MLME
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
-    Sample Lin	01-28-2008    Created
- */
-
-#ifndef __VR_IKANS_H__
-#define __VR_IKANS_H__
-
-#ifndef MODULE_IKANOS
-#define IKANOS_EXTERN	extern
-#else
-#define IKANOS_EXTERN
-#endif // MODULE_IKANOS //
-
-#ifdef IKANOS_VX_1X0
-	typedef void (*IkanosWlanTxCbFuncP)(void *, void *);
-
-	struct IKANOS_TX_INFO
-	{
-		struct net_device *netdev;
-		IkanosWlanTxCbFuncP *fp;
-	};
-#endif // IKANOS_VX_1X0 //
-
-
-IKANOS_EXTERN void VR_IKANOS_FP_Init(UINT8 BssNum, UINT8 *pApMac);
-
-IKANOS_EXTERN INT32 IKANOS_DataFramesTx(struct sk_buff *pSkb,
-										struct net_device *pNetDev);
-
-IKANOS_EXTERN void IKANOS_DataFrameRx(PRTMP_ADAPTER pAd,
-										void *pRxParam,
-										struct sk_buff *pSkb,
-										UINT32 Length);
-
-#endif // __VR_IKANS_H__ //
-
-/* End of vr_ikans.h */
diff --git a/drivers/staging/rt3090/wpa.h b/drivers/staging/rt3090/wpa.h
deleted file mode 100644
index 8baa287..0000000
--- a/drivers/staging/rt3090/wpa.h
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	wpa.h
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Name		Date			Modification logs
-*/
-
-#ifndef	__WPA_H__
-#define	__WPA_H__
-
-// EAPOL Key descripter frame format related length
-#define LEN_KEY_DESC_NONCE			32
-#define LEN_KEY_DESC_IV				16
-#define LEN_KEY_DESC_RSC			8
-#define LEN_KEY_DESC_ID				8
-#define LEN_KEY_DESC_REPLAY			8
-#define LEN_KEY_DESC_MIC			16
-
-// The length is the EAPoL-Key frame except key data field.
-// Please refer to 802.11i-2004 ,Figure 43u in p.78
-#define LEN_EAPOL_KEY_MSG			(sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE)
-
-// EAP Code Type.
-#define EAP_CODE_REQUEST	1
-#define EAP_CODE_RESPONSE	2
-#define EAP_CODE_SUCCESS    3
-#define EAP_CODE_FAILURE    4
-
-// EAPOL frame Protocol Version
-#define	EAPOL_VER					1
-#define	EAPOL_VER2					2
-
-// EAPOL-KEY Descriptor Type
-#define	WPA1_KEY_DESC				0xfe
-#define WPA2_KEY_DESC               0x02
-
-// Key Descriptor Version of Key Information
-#define	DESC_TYPE_TKIP				1
-#define	DESC_TYPE_AES				2
-
-#define LEN_MSG1_2WAY               0x7f
-#define MAX_LEN_OF_EAP_HS           256
-
-#define LEN_MASTER_KEY				32
-
-// EAPOL EK, MK
-#define LEN_EAP_EK					16
-#define LEN_EAP_MICK				16
-#define LEN_EAP_KEY					((LEN_EAP_EK)+(LEN_EAP_MICK))
-// TKIP key related
-#define LEN_PMKID					16
-#define LEN_TKIP_EK					16
-#define LEN_TKIP_RXMICK				8
-#define LEN_TKIP_TXMICK				8
-#define LEN_AES_EK					16
-#define LEN_AES_KEY					LEN_AES_EK
-#define LEN_TKIP_KEY				((LEN_TKIP_EK)+(LEN_TKIP_RXMICK)+(LEN_TKIP_TXMICK))
-#define TKIP_AP_TXMICK_OFFSET		((LEN_EAP_KEY)+(LEN_TKIP_EK))
-#define TKIP_AP_RXMICK_OFFSET		(TKIP_AP_TXMICK_OFFSET+LEN_TKIP_TXMICK)
-#define TKIP_GTK_LENGTH				((LEN_TKIP_EK)+(LEN_TKIP_RXMICK)+(LEN_TKIP_TXMICK))
-#define LEN_PTK						((LEN_EAP_KEY)+(LEN_TKIP_KEY))
-#define MIN_LEN_OF_GTK				5
-#define LEN_PMK						32
-#define LEN_PMK_NAME				16
-#define LEN_NONCE					32
-
-// RSN IE Length definition
-#define MAX_LEN_OF_RSNIE		255
-#define MIN_LEN_OF_RSNIE		8
-
-#define KEY_LIFETIME				3600
-
-//EAP Packet Type
-#define	EAPPacket		0
-#define	EAPOLStart		1
-#define	EAPOLLogoff		2
-#define	EAPOLKey		3
-#define	EAPOLASFAlert	4
-#define	EAPTtypeMax		5
-
-#define	EAPOL_MSG_INVALID	0
-#define	EAPOL_PAIR_MSG_1	1
-#define	EAPOL_PAIR_MSG_2	2
-#define	EAPOL_PAIR_MSG_3	3
-#define	EAPOL_PAIR_MSG_4	4
-#define	EAPOL_GROUP_MSG_1	5
-#define	EAPOL_GROUP_MSG_2	6
-
-#define PAIRWISEKEY					1
-#define GROUPKEY					0
-
-// Retry timer counter initial value
-#define PEER_MSG1_RETRY_TIMER_CTR           0
-#define PEER_MSG3_RETRY_TIMER_CTR           10
-#define GROUP_MSG1_RETRY_TIMER_CTR          20
-
-// WPA mechanism retry timer interval
-#define PEER_MSG1_RETRY_EXEC_INTV           1000			// 1 sec
-#define PEER_MSG3_RETRY_EXEC_INTV           3000			// 3 sec
-#define GROUP_KEY_UPDATE_EXEC_INTV          1000				// 1 sec
-#define PEER_GROUP_KEY_UPDATE_INIV			2000				// 2 sec
-
-#define ENQUEUE_EAPOL_START_TIMER			200					// 200 ms
-
-// group rekey interval
-#define TIME_REKEY                          0
-#define PKT_REKEY                           1
-#define DISABLE_REKEY                       2
-#define MAX_REKEY                           2
-
-#define MAX_REKEY_INTER                     0x3ffffff
-
-#define GROUP_SUITE					0
-#define PAIRWISE_SUITE				1
-#define AKM_SUITE					2
-#define PMKID_LIST					3
-
-
-#define EAPOL_START_DISABLE					0
-#define EAPOL_START_PSK						1
-#define EAPOL_START_1X						2
-
-#define MIX_CIPHER_WPA_TKIP_ON(x)       (((x) & 0x08) != 0)
-#define MIX_CIPHER_WPA_AES_ON(x)        (((x) & 0x04) != 0)
-#define MIX_CIPHER_WPA2_TKIP_ON(x)      (((x) & 0x02) != 0)
-#define MIX_CIPHER_WPA2_AES_ON(x)       (((x) & 0x01) != 0)
-
-#ifndef ROUND_UP
-#define ROUND_UP(__x, __y) \
-	(((ULONG)((__x)+((__y)-1))) & ((ULONG)~((__y)-1)))
-#endif
-
-#define	SET_UINT16_TO_ARRARY(_V, _LEN)		\
-{											\
-	_V[0] = (_LEN & 0xFF00) >> 8;			\
-	_V[1] = (_LEN & 0xFF);					\
-}
-
-#define	INC_UINT16_TO_ARRARY(_V, _LEN)			\
-{												\
-	UINT16	var_len;							\
-												\
-	var_len = (_V[0]<<8) | (_V[1]);				\
-	var_len += _LEN;							\
-												\
-	_V[0] = (var_len & 0xFF00) >> 8;			\
-	_V[1] = (var_len & 0xFF);					\
-}
-
-#define	CONV_ARRARY_TO_UINT16(_V)	((_V[0]<<8) | (_V[1]))
-
-
-#define	ADD_ONE_To_64BIT_VAR(_V)		\
-{										\
-	UCHAR	cnt = LEN_KEY_DESC_REPLAY;	\
-	do									\
-	{									\
-		cnt--;							\
-		_V[cnt]++;						\
-		if (cnt == 0)					\
-			break;						\
-	}while (_V[cnt] == 0);				\
-}
-
-#define IS_WPA_CAPABILITY(a)       (((a) >= Ndis802_11AuthModeWPA) && ((a) <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
-
-// EAPOL Key Information definition within Key descriptor format
-typedef	struct PACKED _KEY_INFO
-{
-#ifdef RT_BIG_ENDIAN
-	UCHAR	KeyAck:1;
-    UCHAR	Install:1;
-    UCHAR	KeyIndex:2;
-    UCHAR	KeyType:1;
-    UCHAR	KeyDescVer:3;
-    UCHAR	Rsvd:3;
-    UCHAR	EKD_DL:1;		// EKD for AP; DL for STA
-    UCHAR	Request:1;
-    UCHAR	Error:1;
-    UCHAR	Secure:1;
-    UCHAR	KeyMic:1;
-#else
-	UCHAR	KeyMic:1;
-	UCHAR	Secure:1;
-	UCHAR	Error:1;
-	UCHAR	Request:1;
-	UCHAR	EKD_DL:1;       // EKD for AP; DL for STA
-	UCHAR	Rsvd:3;
-	UCHAR	KeyDescVer:3;
-	UCHAR	KeyType:1;
-	UCHAR	KeyIndex:2;
-	UCHAR	Install:1;
-	UCHAR	KeyAck:1;
-#endif
-}	KEY_INFO, *PKEY_INFO;
-
-// EAPOL Key descriptor format
-typedef	struct PACKED _KEY_DESCRIPTER
-{
-	UCHAR		Type;
-	KEY_INFO	KeyInfo;
-	UCHAR		KeyLength[2];
-	UCHAR		ReplayCounter[LEN_KEY_DESC_REPLAY];
-	UCHAR		KeyNonce[LEN_KEY_DESC_NONCE];
-	UCHAR		KeyIv[LEN_KEY_DESC_IV];
-	UCHAR		KeyRsc[LEN_KEY_DESC_RSC];
-	UCHAR		KeyId[LEN_KEY_DESC_ID];
-	UCHAR		KeyMic[LEN_KEY_DESC_MIC];
-	UCHAR		KeyDataLen[2];
-	UCHAR		KeyData[MAX_LEN_OF_RSNIE];
-}	KEY_DESCRIPTER, *PKEY_DESCRIPTER;
-
-typedef	struct PACKED _EAPOL_PACKET
-{
-	UCHAR				ProVer;
-	UCHAR				ProType;
-	UCHAR				Body_Len[2];
-	KEY_DESCRIPTER		KeyDesc;
-}	EAPOL_PACKET, *PEAPOL_PACKET;
-
-//802.11i D10 page 83
-typedef struct PACKED _GTK_ENCAP
-{
-#ifndef RT_BIG_ENDIAN
-    UCHAR               Kid:2;
-    UCHAR               tx:1;
-    UCHAR               rsv:5;
-    UCHAR               rsv1;
-#else
-    UCHAR               rsv:5;
-    UCHAR               tx:1;
-    UCHAR               Kid:2;
-    UCHAR               rsv1;
-#endif
-    UCHAR               GTK[TKIP_GTK_LENGTH];
-}   GTK_ENCAP, *PGTK_ENCAP;
-
-typedef struct PACKED _KDE_ENCAP
-{
-    UCHAR               Type;
-    UCHAR               Len;
-    UCHAR               OUI[3];
-    UCHAR               DataType;
-    GTK_ENCAP      GTKEncap;
-}   KDE_ENCAP, *PKDE_ENCAP;
-
-// For WPA1
-typedef struct PACKED _RSNIE {
-    UCHAR   oui[4];
-    USHORT  version;
-    UCHAR   mcast[4];
-    USHORT  ucount;
-    struct PACKED {
-        UCHAR oui[4];
-    }ucast[1];
-} RSNIE, *PRSNIE;
-
-// For WPA2
-typedef struct PACKED _RSNIE2 {
-    USHORT  version;
-    UCHAR   mcast[4];
-    USHORT  ucount;
-    struct PACKED {
-        UCHAR oui[4];
-    }ucast[1];
-} RSNIE2, *PRSNIE2;
-
-// AKM Suite
-typedef struct PACKED _RSNIE_AUTH {
-    USHORT acount;
-    struct PACKED {
-        UCHAR oui[4];
-    }auth[1];
-} RSNIE_AUTH,*PRSNIE_AUTH;
-
-typedef	union PACKED _RSN_CAPABILITIES	{
-	struct	PACKED {
-#ifdef RT_BIG_ENDIAN
-        USHORT		Rsvd:10;
-        USHORT		GTKSA_R_Counter:2;
-        USHORT		PTKSA_R_Counter:2;
-        USHORT		No_Pairwise:1;
-		USHORT		PreAuth:1;
-#else
-        USHORT		PreAuth:1;
-		USHORT		No_Pairwise:1;
-		USHORT		PTKSA_R_Counter:2;
-		USHORT		GTKSA_R_Counter:2;
-		USHORT		Rsvd:10;
-#endif
-	}	field;
-	USHORT			word;
-}	RSN_CAPABILITIES, *PRSN_CAPABILITIES;
-
-typedef struct PACKED _EAP_HDR {
-    UCHAR   ProVer;
-    UCHAR   ProType;
-    UCHAR   Body_Len[2];
-    UCHAR   code;
-    UCHAR   identifier;
-    UCHAR   length[2]; // including code and identifier, followed by length-2 octets of data
-} EAP_HDR, *PEAP_HDR;
-
-// For supplicant state machine states. 802.11i Draft 4.1, p. 97
-// We simplified it
-typedef	enum	_WpaState
-{
-	SS_NOTUSE,				// 0
-	SS_START,				// 1
-	SS_WAIT_MSG_3,			// 2
-	SS_WAIT_GROUP,			// 3
-	SS_FINISH,			// 4
-	SS_KEYUPDATE,			// 5
-}	WPA_STATE;
-
-//
-//	The definition of the cipher combination
-//
-//	 bit3	bit2  bit1   bit0
-//	+------------+------------+
-//	|	  WPA	 |	   WPA2   |
-//	+------+-----+------+-----+
-//	| TKIP | AES | TKIP | AES |
-//	|	0  |  1  |   1  |  0  | -> 0x06
-//	|	0  |  1  |   1  |  1  | -> 0x07
-//	|	1  |  0  |   0  |  1  | -> 0x09
-//	|	1  |  0  |   1  |  1  | -> 0x0B
-//	|	1  |  1  |   0  |  1  | -> 0x0D
-//	|	1  |  1  |   1  |  0  | -> 0x0E
-//	|	1  |  1  |   1  |  1  |	-> 0x0F
-//	+------+-----+------+-----+
-//
-typedef	enum	_WpaMixPairCipher
-{
-	MIX_CIPHER_NOTUSE			= 0x00,
-	WPA_NONE_WPA2_TKIPAES		= 0x03,		// WPA2-TKIPAES
-	WPA_AES_WPA2_TKIP			= 0x06,
-	WPA_AES_WPA2_TKIPAES		= 0x07,
-	WPA_TKIP_WPA2_AES			= 0x09,
-	WPA_TKIP_WPA2_TKIPAES		= 0x0B,
-	WPA_TKIPAES_WPA2_NONE		= 0x0C,		// WPA-TKIPAES
-	WPA_TKIPAES_WPA2_AES		= 0x0D,
-	WPA_TKIPAES_WPA2_TKIP		= 0x0E,
-	WPA_TKIPAES_WPA2_TKIPAES	= 0x0F,
-}	WPA_MIX_PAIR_CIPHER;
-
-typedef struct PACKED _RSN_IE_HEADER_STRUCT	{
-	UCHAR		Eid;
-	UCHAR		Length;
-	USHORT		Version;	// Little endian format
-}	RSN_IE_HEADER_STRUCT, *PRSN_IE_HEADER_STRUCT;
-
-// Cipher suite selector types
-typedef struct PACKED _CIPHER_SUITE_STRUCT	{
-	UCHAR		Oui[3];
-	UCHAR		Type;
-}	CIPHER_SUITE_STRUCT, *PCIPHER_SUITE_STRUCT;
-
-// Authentication and Key Management suite selector
-typedef struct PACKED _AKM_SUITE_STRUCT	{
-	UCHAR		Oui[3];
-	UCHAR		Type;
-}	AKM_SUITE_STRUCT, *PAKM_SUITE_STRUCT;
-
-// RSN capability
-typedef struct	PACKED _RSN_CAPABILITY	{
-	USHORT		Rsv:10;
-	USHORT		GTKSAReplayCnt:2;
-	USHORT		PTKSAReplayCnt:2;
-	USHORT		NoPairwise:1;
-	USHORT		PreAuth:1;
-}	RSN_CAPABILITY, *PRSN_CAPABILITY;
-
-
-/*========================================
-	The prototype is defined in cmm_wpa.c
-  ========================================*/
-BOOLEAN WpaMsgTypeSubst(
-	IN  UCHAR   EAPType,
-	OUT INT		*MsgType);
-
-VOID    PRF(
-	IN  UCHAR   *key,
-	IN  INT     key_len,
-	IN  UCHAR   *prefix,
-	IN  INT     prefix_len,
-	IN  UCHAR   *data,
-	IN  INT     data_len,
-	OUT UCHAR   *output,
-	IN  INT     len);
-
-int PasswordHash(
-	char *password,
-	unsigned char *ssid,
-	int ssidlength,
-	unsigned char *output);
-
-PUINT8	GetSuiteFromRSNIE(
-		IN	PUINT8	rsnie,
-		IN	UINT	rsnie_len,
-		IN	UINT8	type,
-		OUT	UINT8	*count);
-
-VOID WpaShowAllsuite(
-	IN	PUINT8	rsnie,
-	IN	UINT	rsnie_len);
-
-VOID RTMPInsertRSNIE(
-	IN PUCHAR pFrameBuf,
-	OUT PULONG pFrameLen,
-	IN PUINT8 rsnie_ptr,
-	IN UINT8  rsnie_len,
-	IN PUINT8 pmkid_ptr,
-	IN UINT8  pmkid_len);
-
-
-#endif
diff --git a/drivers/staging/rtl8187se/Kconfig b/drivers/staging/rtl8187se/Kconfig
index 3211dd3..e24a6f7 100644
--- a/drivers/staging/rtl8187se/Kconfig
+++ b/drivers/staging/rtl8187se/Kconfig
@@ -1,7 +1,8 @@
-config RTL8187SE
+config R8187SE
 	tristate "RealTek RTL8187SE Wireless LAN NIC driver"
 	depends on PCI && WLAN
 	select WIRELESS_EXT
 	select WEXT_PRIV
 	default N
 	---help---
+	  If built as a module, it will be called r8187se.ko.
diff --git a/drivers/staging/rtl8187se/Makefile b/drivers/staging/rtl8187se/Makefile
index ac35cff..b395acf 100644
--- a/drivers/staging/rtl8187se/Makefile
+++ b/drivers/staging/rtl8187se/Makefile
@@ -16,7 +16,7 @@
 
 #EXTRA_CFLAGS += -mhard-float -DCONFIG_FORCE_HARD_FLOAT=y
 
-rtl8187se-objs :=			\
+r8187se-objs :=			\
 		r8180_core.o		\
 		r8180_93cx6.o		\
 		r8180_wx.o		\
@@ -35,5 +35,5 @@
 		ieee80211/ieee80211_crypt_ccmp.o	\
 		ieee80211/ieee80211_crypt_wep.o
 
-obj-$(CONFIG_RTL8187SE)	+= rtl8187se.o
+obj-$(CONFIG_R8187SE)	+= r8187se.o
 
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
index 5e2e79b1..f882dd8 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
@@ -37,7 +37,6 @@
 #include <linux/slab.h>
 #include <linux/tcp.h>
 #include <linux/types.h>
-#include <linux/version.h>
 #include <linux/wireless.h>
 #include <linux/etherdevice.h>
 #include <asm/uaccess.h>
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
index 334e4c7..1fe19c3 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
@@ -1837,7 +1837,7 @@
 
 					 	            if (((ieee->current_network.wmm_info^info_element->data[6])& \
 										    0x0f)||(!ieee->init_wmmparam_flag)) {
-						   	      //refresh paramete element for current network
+						   	      // 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);
@@ -1958,10 +1958,10 @@
  * 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 enought room to TX an entire packet.
+ * 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 treshold is not enought.. If the
+ * 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
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
index e2945db..dde1f2e 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
@@ -47,7 +47,6 @@
 #include <linux/slab.h>
 #include <linux/tcp.h>
 #include <linux/types.h>
-#include <linux/version.h>
 #include <linux/wireless.h>
 #include <linux/etherdevice.h>
 #include <asm/uaccess.h>
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
index a08b97a..6aad48f 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
@@ -30,7 +30,6 @@
 
 ******************************************************************************/
 #include <linux/wireless.h>
-#include <linux/version.h>
 #include <linux/kmod.h>
 #include <linux/module.h>
 
diff --git a/drivers/staging/rtl8187se/r8180.h b/drivers/staging/rtl8187se/r8180.h
index 8216d7e..ce82888 100644
--- a/drivers/staging/rtl8187se/r8180.h
+++ b/drivers/staging/rtl8187se/r8180.h
@@ -77,21 +77,6 @@
 	WIRELESS_MODE_AUTO = 0x08,
 } WIRELESS_MODE;
 
-typedef enum _VERSION_8185{
-	// RTL8185
-	VERSION_8185_UNKNOWN,
-	VERSION_8185_C, // C-cut
-	VERSION_8185_D, // D-cut
-	// RTL8185B
-	VERSION_8185B_B, // B-cut
-	VERSION_8185B_D, // D-cut
-	VERSION_8185B_E, // E-cut
-	//RTL8187S-PCIE
-	VERSION_8187S_B, // B-cut
-	VERSION_8187S_C, // C-cut
-	VERSION_8187S_D, // D-cut
-
-}VERSION_8185,*PVERSION_8185;
 typedef struct 	ChnlAccessSetting {
 	u16 SIFS_Timer;
 	u16 DIFS_Timer;
@@ -341,11 +326,8 @@
 	int irq;
 	struct ieee80211_device *ieee80211;
 
-        short card_8185; /* O: rtl8180, 1:rtl8185 V B/C, 2:rtl8185 V D, 3:rtl8185B */
-	short card_8185_Bversion; /* if TCR reports card V B/C this discriminates */
 	short phy_ver; /* meaningful for rtl8225 1:A 2:B 3:C */
 	short enable_gpio0;
-	enum card_type {PCI,MINIPCI,CARDBUS,USB/*rtl8187*/}card_type;
 	short hw_plcp_len;
 	short plcp_preamble_mode; // 0:auto 1:short 2:long
 
@@ -521,7 +503,7 @@
 	//u32 NumTxOkInPeriod;   //YJ,del,080828
 	u8   TxPollingTimes;
 
-	bool	bApBufOurFrame;// TRUE if AP buffer our unicast data , we will keep eAwake untill receive data or timeout.
+	bool	bApBufOurFrame;// TRUE if AP buffer our unicast data , we will keep eAwake until receive data or timeout.
 	u8	WaitBufDataBcnCount;
 	u8	WaitBufDataTimeOut;
 
@@ -599,7 +581,7 @@
 	u8						RSSI;
 	char					RxPower;
 	 u8 InitialGain;
-	 //For adjust Dig Threshhold during Legacy/Leisure Power Save Mode
+	 //For adjust Dig Threshold during Legacy/Leisure Power Save Mode
 	u32				DozePeriodInPast2Sec;
 	 // Don't access BB/RF under disable PLL situation.
 	u8					InitialGainBackUp;
diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c
index 53e654d..57c62b0 100644
--- a/drivers/staging/rtl8187se/r8180_core.c
+++ b/drivers/staging/rtl8187se/r8180_core.c
@@ -886,8 +886,6 @@
 		rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
 	}else{
 		rxconf = rxconf | (1<<ACCEPT_NICMAC_FRAME_SHIFT);
-		if(priv->card_8185 == 0)
-			rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
 	}
 
 	if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
@@ -910,9 +908,6 @@
 
 	rxconf = rxconf &~ RCR_CS_MASK;
 
-	if (!priv->card_8185)
-		rxconf |= (priv->rcr_csense<<RCR_CS_SHIFT);
-
 	write_nic_dword(dev, RX_CONF, rxconf);
 
 	fix_rx_fifo(dev);
@@ -964,28 +959,19 @@
 
 	txconf = read_nic_dword(dev, TX_CONF);
 
-	if (priv->card_8185) {
-		byte = read_nic_byte(dev,CW_CONF);
-		byte &= ~(1<<CW_CONF_PERPACKET_CW_SHIFT);
-		byte &= ~(1<<CW_CONF_PERPACKET_RETRY_SHIFT);
-		write_nic_byte(dev, CW_CONF, byte);
+	byte = read_nic_byte(dev, CW_CONF);
+	byte &= ~(1<<CW_CONF_PERPACKET_CW_SHIFT);
+	byte &= ~(1<<CW_CONF_PERPACKET_RETRY_SHIFT);
+	write_nic_byte(dev, CW_CONF, byte);
 
-		tx_agc_ctl = read_nic_byte(dev, TX_AGC_CTL);
-		tx_agc_ctl &= ~(1<<TX_AGC_CTL_PERPACKET_GAIN_SHIFT);
-		tx_agc_ctl &= ~(1<<TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT);
-		tx_agc_ctl |=(1<<TX_AGC_CTL_FEEDBACK_ANT);
-		write_nic_byte(dev, TX_AGC_CTL, tx_agc_ctl);
-		write_nic_byte(dev, 0xec, 0x3f); /* Disable early TX */
-	}
+	tx_agc_ctl = read_nic_byte(dev, TX_AGC_CTL);
+	tx_agc_ctl &= ~(1<<TX_AGC_CTL_PERPACKET_GAIN_SHIFT);
+	tx_agc_ctl &= ~(1<<TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT);
+	tx_agc_ctl |= (1<<TX_AGC_CTL_FEEDBACK_ANT);
+	write_nic_byte(dev, TX_AGC_CTL, tx_agc_ctl);
+	write_nic_byte(dev, 0xec, 0x3f); /* Disable early TX */
 
-	if (priv->card_8185)
-		txconf = txconf &~ (1<<TCR_PROBE_NOTIMESTAMP_SHIFT);
-	else {
-		if(hwseqnum)
-			txconf= txconf &~ (1<<TX_CONF_HEADER_AUTOICREMENT_SHIFT);
-		else
-			txconf= txconf | (1<<TX_CONF_HEADER_AUTOICREMENT_SHIFT);
-	}
+	txconf = txconf & ~(1<<TCR_PROBE_NOTIMESTAMP_SHIFT);
 
 	txconf = txconf &~ TX_LOOPBACK_MASK;
 	txconf = txconf | (TX_LOOPBACK_NONE <<TX_LOOPBACK_SHIFT);
@@ -995,13 +981,10 @@
 	txconf = txconf | (priv->retry_rts<<TX_RTSRETRY_SHIFT);
 	txconf = txconf &~ (1<<TX_NOCRC_SHIFT);
 
-	if (priv->card_8185) {
-		if (priv->hw_plcp_len)
-			txconf = txconf &~ TCR_PLCP_LEN;
-		else
-			txconf = txconf | TCR_PLCP_LEN;
-	} else
-		txconf = txconf &~ TCR_SAT;
+	if (priv->hw_plcp_len)
+		txconf = txconf & ~TCR_PLCP_LEN;
+	else
+		txconf = txconf | TCR_PLCP_LEN;
 
 	txconf = txconf &~ TCR_MXDMA_MASK;
 	txconf = txconf | (TCR_MXDMA_2048<<TCR_MXDMA_SHIFT);
@@ -1720,8 +1703,6 @@
 		else
 			quality = 127 - quality;
 		priv->SignalQuality = quality;
-		if(!priv->card_8185)
-			printk("check your card type\n");
 
 		stats.signal = (u8)quality;//priv->wstats.qual.level = priv->SignalStrength;
 		stats.signalstrength = RXAGC;
@@ -1848,7 +1829,7 @@
 				    sizeof(u8),
 				    PCI_DMA_FROMDEVICE);
 
-drop: // this is used when we have not enought mem
+drop: // this is used when we have not enough mem
 		/* restore the descriptor */
 		*(priv->rxringtail+2)=priv->rxbuffer->dma;
 		*(priv->rxringtail)=*(priv->rxringtail) &~ 0xfff;
@@ -1919,8 +1900,8 @@
 	/*
 	* 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 (trought
-	* the ieee stack, or from the try_wake_queue (again trought
+	* 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);
@@ -2221,10 +2202,8 @@
 		*(tail+6) = 0;
 		*(tail+7) = 0;
 
-		if(priv->card_8185){
-			//FIXME: this should be triggered by HW encryption parameters.
-			*tail |= (1<<15); //no encrypt
-		}
+		/*FIXME: this should be triggered by HW encryption parameters.*/
+		*tail |= (1<<15); /* no encrypt */
 
 		if(remain==len && !descfrag) {
 			ownbit_flag = false;	//added by david woo,2007.12.14
@@ -2266,7 +2245,7 @@
 
 		/* hw_plcp_len is not used for rtl8180 chip */
 		/* FIXME */
-		if(priv->card_8185 == 0 || !priv->hw_plcp_len){
+		if (!priv->hw_plcp_len) {
 			duration = rtl8180_len2duration(len, rate, &ext);
 			*(tail+1) = *(tail+1) | ((duration & 0x7fff)<<16);
 			if(ext) *(tail+1) = *(tail+1) |(1<<31); //plcp length extension
@@ -2355,8 +2334,7 @@
 
 	rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
 
-	if(priv->card_8185)
-		rtl8180_set_chan(dev, priv->chan);
+	rtl8180_set_chan(dev, priv->chan);
 }
 
 void rtl8180_rq_tx_ack(struct net_device *dev){
@@ -2702,8 +2680,6 @@
 	struct r8180_priv *priv = ieee80211_priv(dev);
 	u16 word;
 	u16 version;
-	u8 hw_version;
-	//u8 config3;
 	u32 usValue;
 	u16 tmpu16;
 	int i, j;
@@ -2928,50 +2904,13 @@
 
 	priv->InitialGain = 6;
 
-	hw_version =( read_nic_dword(dev, TCR) & TCR_HWVERID_MASK)>>TCR_HWVERID_SHIFT;
+	DMESG("MAC controller is a RTL8187SE b/g");
+	priv->phy_ver = 2;
 
-	switch (hw_version){
-		case HW_VERID_R8185B_B:
-                        priv->card_8185 = VERSION_8187S_C;
-		        DMESG("MAC controller is a RTL8187SE b/g");
-			priv->phy_ver = 2;
-			break;
-		case HW_VERID_R8185_ABC:
-			DMESG("MAC controller is a RTL8185 b/g");
-			priv->card_8185 = 1;
-			/* you should not find a card with 8225 PHY ver < C*/
-			priv->phy_ver = 2;
-			break;
-		case HW_VERID_R8185_D:
-			DMESG("MAC controller is a RTL8185 b/g (V. D)");
-			priv->card_8185 = 2;
-			/* you should not find a card with 8225 PHY ver < C*/
-			priv->phy_ver = 2;
-			break;
-		case HW_VERID_R8180_ABCD:
-			DMESG("MAC controller is a RTL8180");
-			priv->card_8185 = 0;
-			break;
-		case HW_VERID_R8180_F:
-			DMESG("MAC controller is a RTL8180 (v. F)");
-			priv->card_8185 = 0;
-			break;
-		default:
-			DMESGW("MAC chip not recognized: version %x. Assuming RTL8180",hw_version);
-			priv->card_8185 = 0;
-			break;
-	}
-
-	if(priv->card_8185){
-		priv->ieee80211->modulation |= IEEE80211_OFDM_MODULATION;
-		priv->ieee80211->short_slot = 1;
-	}
-	/* you should not found any 8185 Ver B Card */
-	priv->card_8185_Bversion = 0;
+	priv->ieee80211->modulation |= IEEE80211_OFDM_MODULATION;
+	priv->ieee80211->short_slot = 1;
 
 	// just for sync 85
-	priv->card_type = PCI;
-        DMESG("This is a PCI NIC");
 	priv->enable_gpio0 = 0;
 
 	usValue = eprom_read(dev, EEPROM_SW_REVD_OFFSET);
@@ -3026,12 +2965,10 @@
 		priv->chtxpwr[i]=word & 0xff;
 		priv->chtxpwr[i+1]=(word & 0xff00)>>8;
 	}
-	if(priv->card_8185){
-		for(i=1,j=0; i<14; i+=2,j++){
-			word = eprom_read(dev,EPROM_TXPW_OFDM_CH1_2 + j);
-			priv->chtxpwr_ofdm[i]=word & 0xff;
-			priv->chtxpwr_ofdm[i+1]=(word & 0xff00)>>8;
-		}
+	for (i = 1, j = 0; i < 14; i += 2, j++) {
+		word = eprom_read(dev, EPROM_TXPW_OFDM_CH1_2 + j);
+		priv->chtxpwr_ofdm[i] = word & 0xff;
+		priv->chtxpwr_ofdm[i+1] = (word & 0xff00)>>8;
 	}
 
 	//3Read crystal calibtration and thermal meter indication on 87SE.
@@ -3057,37 +2994,11 @@
 
 	version = eprom_read(dev,EPROM_VERSION);
 	DMESG("EEPROM version %x",version);
-	if( (!priv->card_8185) && version < 0x0101){
-		DMESG ("EEPROM version too old, assuming defaults");
-		DMESG ("If you see this message *plase* send your \
-DMESG output to andreamrl@tiscali.it THANKS");
-		priv->digphy=1;
-		priv->antb=0;
-		priv->diversity=1;
-		priv->cs_treshold=0xc;
-		priv->rcr_csense=1;
-		priv->rf_chip=RFCHIPID_PHILIPS;
-	}else{
-		if(!priv->card_8185){
-			u8 rfparam = eprom_read(dev,RF_PARAM);
-			DMESG("RfParam: %x",rfparam);
+	priv->rcr_csense = 3;
 
-			priv->digphy = rfparam & (1<<RF_PARAM_DIGPHY_SHIFT) ? 0:1;
-			priv->antb =  rfparam & (1<<RF_PARAM_ANTBDEFAULT_SHIFT) ? 1:0;
+	priv->cs_treshold = (eprom_read(dev, ENERGY_TRESHOLD) & 0xff00) >> 8;
 
-			priv->rcr_csense = (rfparam & RF_PARAM_CARRIERSENSE_MASK) >>
-					RF_PARAM_CARRIERSENSE_SHIFT;
-
-			priv->diversity =
-				(read_nic_byte(dev,CONFIG2)&(1<<CONFIG2_ANTENNA_SHIFT)) ? 1:0;
-		}else{
-			priv->rcr_csense = 3;
-		}
-
-		priv->cs_treshold = (eprom_read(dev,ENERGY_TRESHOLD)&0xff00) >>8;
-
-		priv->rf_chip = 0xff & eprom_read(dev,RFCHIPID);
-	}
+	priv->rf_chip = 0xff & eprom_read(dev, RFCHIPID);
 
 	priv->rf_chip = RF_ZEBRA4;
 	priv->rf_sleep = rtl8225z4_rf_sleep;
@@ -3099,19 +3010,6 @@
 	priv->rf_set_chan = rtl8225z2_rf_set_chan;
 	priv->rf_set_sens = NULL;
 
-	if(!priv->card_8185){
-		if(priv->antb)
-			DMESG ("Antenna B is default antenna");
-		else
-			DMESG ("Antenna A is default antenna");
-
-		if(priv->diversity)
-			DMESG ("Antenna diversity is enabled");
-		else
-			DMESG("Antenna diversity is disabled");
-
-		DMESG("Carrier sense %d",priv->rcr_csense);
-	}
 
 	if (0!=alloc_rx_desc_ring(dev, priv->rxbuffersize, priv->rxringcount))
 		return -ENOMEM;
@@ -3144,17 +3042,6 @@
 				  TX_BEACON_RING_ADDR))
 		return -ENOMEM;
 
-	if(!priv->card_8185){
-		if(read_nic_byte(dev, CONFIG0) & (1<<CONFIG0_WEP40_SHIFT))
-			DMESG ("40-bit WEP is supported in hardware");
-		else
-			DMESG ("40-bit WEP is NOT supported in hardware");
-
-		if(read_nic_byte(dev,CONFIG0) & (1<<CONFIG0_WEP104_SHIFT))
-			DMESG ("104-bit WEP is supported in hardware");
-		else
-			DMESG ("104-bit WEP is NOT supported in hardware");
-	}
 #if !defined(SA_SHIRQ)
         if(request_irq(dev->irq, (void *)rtl8180_interrupt, IRQF_SHARED, dev->name, dev)){
 #else
@@ -3172,17 +3059,6 @@
 
 void rtl8180_no_hw_wep(struct net_device *dev)
 {
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	if (!priv->card_8185) {
-		u8 security;
-
-		security  = read_nic_byte(dev, SECURITY);
-		security &=~(1<<SECURITY_WEP_TX_ENABLE_SHIFT);
-		security &=~(1<<SECURITY_WEP_RX_ENABLE_SHIFT);
-
-		write_nic_byte(dev, SECURITY, security);
-	}
 }
 
 void rtl8180_set_hw_wep(struct net_device *dev)
@@ -3355,9 +3231,6 @@
 void rtl8180_adapter_start(struct net_device *dev)
 {
         struct r8180_priv *priv = ieee80211_priv(dev);
-	u32 anaparam;
-	u16 word;
-	u8 config3;
 
 	rtl8180_rtx_disable(dev);
 	rtl8180_reset(dev);
@@ -3371,12 +3244,6 @@
 
 	rtl8180_beacon_tx_disable(dev);
 
-	if(priv->card_type == CARDBUS ){
-		config3=read_nic_byte(dev, CONFIG3);
-		write_nic_byte(dev,CONFIG3,config3 | CONFIG3_FuncRegEn);
-		write_nic_word(dev,FEMR, FEMR_INTR | FEMR_WKUP | FEMR_GWAKE |
-			read_nic_word(dev, FEMR));
-	}
 	rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
 	write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
 	write_nic_word(dev, MAC4, ((u32*)dev->dev_addr)[1] & 0xffff );
@@ -3384,12 +3251,6 @@
 
 	rtl8180_update_msr(dev);
 
-	if(!priv->card_8185){
-		anaparam  = eprom_read(dev,EPROM_ANAPARAM_ADDRLWORD);
-		anaparam |= eprom_read(dev,EPROM_ANAPARAM_ADDRHWORD)<<16;
-
-		rtl8180_set_anaparam(dev,anaparam);
-	}
 	/* These might be unnecessary since we do in rx_enable / tx_enable */
 	fix_rx_fifo(dev);
 	fix_tx_fifo(dev);
@@ -3399,61 +3260,34 @@
 	/*
 	   The following is very strange. seems to be that 1 means test mode,
 	   but we need to acknolwledges the nic when a packet is ready
-	   altought we set it to 0
+	   although we set it to 0
 	*/
 
 	write_nic_byte(dev,
 		       CONFIG2, read_nic_byte(dev,CONFIG2) &~\
 		       (1<<CONFIG2_DMA_POLLING_MODE_SHIFT));
 	//^the nic isn't in test mode
-	if(priv->card_8185)
-			write_nic_byte(dev,
+	write_nic_byte(dev,
 		       CONFIG2, read_nic_byte(dev,CONFIG2)|(1<<4));
 
 	rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
 
 	write_nic_dword(dev,INT_TIMEOUT,0);
 
-	if(!priv->card_8185)
-	{
-		/*
-		experimental - this might be needed to calibrate AGC,
-		anyway it shouldn't hurt
-		*/
-		write_nic_byte(dev, CONFIG5,
-			read_nic_byte(dev, CONFIG5) | (1<<AGCRESET_SHIFT));
-		read_nic_byte(dev, CONFIG5);
-		udelay(15);
-		write_nic_byte(dev, CONFIG5,
-			read_nic_byte(dev, CONFIG5) &~ (1<<AGCRESET_SHIFT));
-	}else{
-		write_nic_byte(dev, WPA_CONFIG, 0);
-		//write_nic_byte(dev, TESTR, 0xd);
-	}
+	write_nic_byte(dev, WPA_CONFIG, 0);
 
 	rtl8180_no_hw_wep(dev);
 
-	if(priv->card_8185){
-		rtl8185_set_rate(dev);
-		write_nic_byte(dev, RATE_FALLBACK, 0x81);
-	}else{
-		word  = read_nic_word(dev, BRSR);
-		word &= ~BRSR_MBR;
-		word &= ~BRSR_BPLCP;
-		word |= ieeerate2rtlrate(priv->ieee80211->basic_rate);
-		word |= 0x0f;
-		write_nic_word(dev, BRSR, word);
-	}
+	rtl8185_set_rate(dev);
+	write_nic_byte(dev, RATE_FALLBACK, 0x81);
 
-	if(priv->card_8185){
-		write_nic_byte(dev, GP_ENABLE,read_nic_byte(dev, GP_ENABLE) & ~(1<<6));
+	write_nic_byte(dev, GP_ENABLE, read_nic_byte(dev, GP_ENABLE) & ~(1<<6));
 
-		//FIXME cfg 3 ClkRun enable - isn't it ReadOnly ?
-		rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
-		write_nic_byte(dev,CONFIG3, read_nic_byte(dev, CONFIG3)
-			       | (1 << CONFIG3_CLKRUN_SHIFT));
-		rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-	}
+	/*FIXME cfg 3 ClkRun enable - isn't it ReadOnly ? */
+	rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
+	write_nic_byte(dev, CONFIG3, read_nic_byte(dev, CONFIG3)
+		       | (1 << CONFIG3_CLKRUN_SHIFT));
+	rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
 
 	priv->rf_init(dev);
 
@@ -4144,7 +3978,7 @@
 		}
 
 	/* we check all the descriptors between the head and the nic,
-	 * but not the currenly pointed by the nic (the next to be txed)
+	 * 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);
diff --git a/drivers/staging/rtl8187se/r8180_dm.c b/drivers/staging/rtl8187se/r8180_dm.c
index b6eeeec..cbca58d 100644
--- a/drivers/staging/rtl8187se/r8180_dm.c
+++ b/drivers/staging/rtl8187se/r8180_dm.c
@@ -36,7 +36,7 @@
 //
 //	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 chane TR switch
+//		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.
 //
@@ -197,7 +197,6 @@
 	{ // Advised from SD3 DZ
 		priv->InitialGain = 4; // In 87B, m74dBm means State 4 (m82dBm)
 	}
-	//if(pHalData->VersionID != VERSION_8187B_B)
 	{ // Advised from SD3 DZ
 		OfdmFA1 =  0x20;
 	}
@@ -1326,7 +1325,7 @@
 			break;
 
 		default:
-			printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
+			printk("SetAntenna8185: unknown RFChipID(%d)\n", priv->rf_chip);
 			break;
 		}
 		break;
@@ -1346,13 +1345,13 @@
 			break;
 
 		default:
-			printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
+			printk("SetAntenna8185: unknown RFChipID(%d)\n", priv->rf_chip);
 			break;
 		}
 		break;
 
 	default:
-		printk("SetAntenna8185: unkown u1bAntennaIndex(%d)\n", u1bAntennaIndex);
+		printk("SetAntenna8185: unknown u1bAntennaIndex(%d)\n", u1bAntennaIndex);
 		break;
 	}
 
@@ -1448,7 +1447,7 @@
 
 		priv->bAdSwitchedChecking = false;
 
-		// Adjust Rx signal strength threashold.
+		// Adjust Rx signal strength threshold.
 		priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2;
 
 		priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
@@ -1562,7 +1561,7 @@
 //				priv->AdRxSignalStrength, priv->AdRxSsThreshold);
 
 			priv->bAdSwitchedChecking = false;
-			// Increase Rx signal strength threashold if necessary.
+			// 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.
 			{
diff --git a/drivers/staging/rtl8187se/r8180_rtl8225z2.c b/drivers/staging/rtl8187se/r8180_rtl8225z2.c
index b648751..afe10f0 100644
--- a/drivers/staging/rtl8187se/r8180_rtl8225z2.c
+++ b/drivers/staging/rtl8187se/r8180_rtl8225z2.c
@@ -23,7 +23,6 @@
 	u16 out, select;
 	u8 bit;
 	u32 bangdata = (data << 4) | (adr & 0xf);
-	struct r8180_priv *priv = ieee80211_priv(dev);
 
 	out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
 
@@ -33,7 +32,7 @@
 	select = read_nic_word(dev, RFPinsSelect);
 
 	write_nic_word(dev, RFPinsSelect, select | 0x7 |
-		((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
+		       SW_CONTROL_GPIO);
 
 	force_pci_posting(dev);
 	udelay(10);
@@ -71,16 +70,11 @@
 	force_pci_posting(dev);
 	udelay(10);
 
-	write_nic_word(dev, RFPinsOutput, out |
-		((priv->card_type == USB) ? 4 : BB_HOST_BANG_EN));
+	write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
 
-	write_nic_word(dev, RFPinsSelect, select |
-		((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
+	write_nic_word(dev, RFPinsSelect, select | SW_CONTROL_GPIO);
 
-	if (priv->card_type == USB)
-		mdelay(2);
-	else
-		rtl8185_rf_pins_enable(dev);
+	rtl8185_rf_pins_enable(dev);
 }
 
 static const u16 rtl8225bcd_rxgain[] = {
@@ -174,15 +168,9 @@
 	u8 cck_power_level = 0xff & priv->chtxpwr[ch];
 	u8 ofdm_power_level = 0xff & priv->chtxpwr_ofdm[ch];
 
-	if (priv->card_type == USB) {
-		max_cck_power_level = 11;
-		max_ofdm_power_level = 25;
-		min_ofdm_power_level = 10;
-	} else {
-		max_cck_power_level = 35;
-		max_ofdm_power_level = 35;
-		min_ofdm_power_level = 0;
-	}
+	max_cck_power_level = 35;
+	max_ofdm_power_level = 35;
+	min_ofdm_power_level = 0;
 
 	if (cck_power_level > max_cck_power_level)
 		cck_power_level = max_cck_power_level;
@@ -445,30 +433,28 @@
 	 * OFDM Power in dBm = Index * 0.5 + 0
 	 * CCK Power in dBm = Index * 0.25 + 13
 	 */
-	if (priv->card_8185 >= VERSION_8187S_B) {
-		s32 tmp = 0;
+	s32 tmp = 0;
 
-		if (WirelessMode == WIRELESS_MODE_G) {
-			bUseDefault = false;
-			tmp = (2 * PowerInDbm);
+	if (WirelessMode == 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 (WirelessMode == WIRELESS_MODE_B) {
-			bUseDefault = false;
-			tmp = (4 * PowerInDbm) - 52;
+		if (tmp < 0)
+			TxPwrIdx = 0;
+		else if (tmp > 40) /* 40 means 20 dBm. */
+			TxPwrIdx = 40;
+		else
+			TxPwrIdx = (s8)tmp;
+	} else if (WirelessMode == 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;
-		}
+		if (tmp < 0)
+			TxPwrIdx = 0;
+		else if (tmp > 28) /* 28 means 20 dBm. */
+			TxPwrIdx = 28;
+		else
+			TxPwrIdx = (s8)tmp;
 	}
 
 	/*
@@ -631,8 +617,7 @@
 
 	priv->chan = channel;
 
-	if (priv->card_type != USB)
-		rtl8225_host_pci_init(dev);
+	rtl8225_host_pci_init(dev);
 
 	write_nic_dword(dev, RF_TIMING, 0x000a8008);
 
@@ -655,7 +640,7 @@
 	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, ((priv->card_type == USB)? 0x82a : rtl8225_chan[channel]));  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);
@@ -681,13 +666,6 @@
 
 	write_rtl8225(dev, 0x2, 0xc4d);
 
-	if (priv->card_type == USB) {
-		mdelay(200);
-
-		write_rtl8225(dev, 0x2, 0x44d);
-		mdelay(100);
-	}
-
 	/* FIXME!! rtl8187 we have to check if calibrarion
 	 * is successful and eventually cal. again (repeat
 	 * the two write on reg 2)
@@ -707,9 +685,6 @@
 
 	write_rtl8225(dev, 0x0, 0x2bf);
 
-	if (priv->card_type != USB)
-		rtl8185_rf_pins_enable(dev);
-
 	for (i = 0; i < 128; i++) {
 		data = rtl8225_agc[i];
 
@@ -726,7 +701,7 @@
 
 	write_phy_ofdm(dev, 0x00, 0x01); mdelay(1);
 	write_phy_ofdm(dev, 0x01, 0x02); mdelay(1);
-	write_phy_ofdm(dev, 0x02, ((priv->card_type == USB) ? 0x42 : 0x62)); 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);
@@ -774,7 +749,7 @@
 	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, ((priv->card_type == USB) ? 0x9b: 0x93)); 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);
@@ -808,12 +783,8 @@
 	/* switch to high-speed 3-wire
 	 * last digit. 2 for both cck and ofdm
 	 */
-	if (priv->card_type == USB)
-		write_nic_dword(dev, 0x94, 0x3dc00002);
-	else {
-		write_nic_dword(dev, 0x94, 0x15c00002);
-		rtl8185_rf_pins_enable(dev);
-	}
+	write_nic_dword(dev, 0x94, 0x15c00002);
+	rtl8185_rf_pins_enable(dev);
 
 	rtl8225_rf_set_chan(dev, priv->chan);
 }
@@ -1058,7 +1029,7 @@
 			break;
 		default:
 			bResult = false;
-			printk("SetZebraRFPowerState8185(): unknow state to set: 0x%X!!!\n", eRFPowerState);
+			printk("SetZebraRFPowerState8185(): unknown state to set: 0x%X!!!\n", eRFPowerState);
 			break;
 		}
 		break;
diff --git a/drivers/staging/rtl8187se/r8180_wx.c b/drivers/staging/rtl8187se/r8180_wx.c
index 766892e..536cb6e 100644
--- a/drivers/staging/rtl8187se/r8180_wx.c
+++ b/drivers/staging/rtl8187se/r8180_wx.c
@@ -276,7 +276,7 @@
 	range->max_qual.updated = 7; /* Updated all three */
 
 	range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
-	/* TODO: Find real 'good' to 'bad' threshol value for RSSI */
+	/* 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 */
diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c
index cd07059..50309f2 100644
--- a/drivers/staging/rtl8187se/r8185b_init.c
+++ b/drivers/staging/rtl8187se/r8185b_init.c
@@ -1023,6 +1023,7 @@
 	u32	addr,data;
 	u32	u4bRegOffset, u4bRegValue, u4bRF23, u4bRF24;
        u8			u1b24E;
+	int d_cut = 0;
 
 
 	//=============================================================================
@@ -1035,8 +1036,10 @@
 	u4bRF23= RF_ReadReg(dev, 0x08);			mdelay(1);
 	u4bRF24= RF_ReadReg(dev, 0x09);			mdelay(1);
 
-	if (u4bRF23==0x818 && u4bRF24==0x70C && priv->card_8185 == VERSION_8187S_C)
-		priv->card_8185 = VERSION_8187S_D;
+	if (u4bRF23 == 0x818 && u4bRF24 == 0x70C) {
+		d_cut = 1;
+		printk(KERN_INFO "rtl8187se: card type changed from C- to D-cut\n");
+	}
 
 	// Page0 : reg0-reg15
 
@@ -1070,18 +1073,9 @@
 
 	RF_WriteReg(dev, 0x03, 0x0806);			mdelay(1);
 
-	if(priv->card_8185 < VERSION_8187S_C)
-	{
-		RF_WriteReg(dev, 0x04, 0x03f7);			mdelay(1);
-		RF_WriteReg(dev, 0x05, 0x05ab);			mdelay(1);
-		RF_WriteReg(dev, 0x06, 0x00c1);			mdelay(1);
-	}
-	else
-	{
-		RF_WriteReg(dev, 0x04, 0x03a7);			mdelay(1);
-		RF_WriteReg(dev, 0x05, 0x059b);			mdelay(1);
-		RF_WriteReg(dev, 0x06, 0x0081);			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);
@@ -1091,14 +1085,11 @@
 	RF_WriteReg(dev, 0x0a, 0x0001);			mdelay(1);
 	RF_WriteReg(dev, 0x0b, 0x0418);			mdelay(1);
 
-	if(priv->card_8185 == VERSION_8187S_D)
-	{
+	if (d_cut) {
 		RF_WriteReg(dev, 0x0c, 0x0fbe);			mdelay(1);
 		RF_WriteReg(dev, 0x0d, 0x0008);			mdelay(1);
 		RF_WriteReg(dev, 0x0e, 0x0807);			mdelay(1); // RX LO buffer
-	}
-	else
-	{
+	} else {
 		RF_WriteReg(dev, 0x0c, 0x0fbe);			mdelay(1);
 		RF_WriteReg(dev, 0x0d, 0x0008);			mdelay(1);
 		RF_WriteReg(dev, 0x0e, 0x0806);			mdelay(1); // RX LO buffer
@@ -2493,8 +2484,8 @@
 	PhyConfig8185(dev);
 
 	// We assume RegWirelessMode has already been initialized before,
-	// however, we has to validate the wireless mode here and provide a reasonble
-	// initialized value if necessary. 2005.01.13, by rcnjko.
+	// 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) &&
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c
index 12c2a18..2644155 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c
@@ -164,7 +164,7 @@
  	ieee->privacy_invoked = 0;
  	ieee->ieee802_1x = 1;
 	ieee->raw_tx = 0;
-	//ieee->hwsec_support = 1; //defalt support hw security. //use module_param instead.
+	//ieee->hwsec_support = 1; //default support hw security. //use module_param instead.
 	ieee->hwsec_active = 0; //disable hwsec, switch it on when necessary.
 
 	ieee80211_softmac_init(ieee);
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
index eae7c45..593d228 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
@@ -2330,10 +2330,10 @@
  * 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 enought room to TX an entire packet.
+ * 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 treshold is not enought.. If the
+ * 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
diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c
index 0eaee3a..3d67fbb 100644
--- a/drivers/staging/rtl8192e/r8190_rtl8256.c
+++ b/drivers/staging/rtl8192e/r8190_rtl8256.c
@@ -629,7 +629,7 @@
 
 			default:
 					bResult = false;
-					RT_TRACE(COMP_ERR, "SetRFPowerState8190(): unknow state to set: 0x%X!!!\n", eRFPowerState);
+					RT_TRACE(COMP_ERR, "SetRFPowerState8190(): unknown state to set: 0x%X!!!\n", eRFPowerState);
 					break;
 		}
 
diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c
index b0802a7..ff8fe7e 100644
--- a/drivers/staging/rtl8192e/r8192E_core.c
+++ b/drivers/staging/rtl8192e/r8192E_core.c
@@ -1041,7 +1041,7 @@
         tx_desc_819x_pci *entry = &ring->desc[ring->idx];
         struct sk_buff *skb;
 
-        /* beacon packet will only use the first descriptor defautly,
+        /* beacon packet will only use the first descriptor defaultly,
          * and the OWN may not be cleared by the hardware
          * */
         if(prio != BEACON_QUEUE) {
@@ -2562,7 +2562,7 @@
 		priv->bTXPowerDataReadFromEEPORM = false;
 	}
 
-	// 2007/11/15 MH 8190PCI Default=2T4R, 8192PCIE dafault=1T2R
+	// 2007/11/15 MH 8190PCI Default=2T4R, 8192PCIE default=1T2R
 	priv->rf_type = RTL819X_DEFAULT_RF_TYPE;
 
 	if(priv->card_8192_version > VERSION_8190_BD)
@@ -3554,7 +3554,7 @@
 	//spin_lock_irqsave(&priv->tx_lock,flags);
 	/* prepare misc info for the beacon xmit */
 	tcb_desc->queue_index = BEACON_QUEUE;
-	/* IBSS does not support HT yet, use 1M defautly */
+	/* IBSS does not support HT yet, use 1M defaultly */
 	tcb_desc->data_rate = 2;
 	tcb_desc->RATRIndex = 7;
 	tcb_desc->bTxDisableRateFallBack = 1;
diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c
index bf87632..5ffb4f7 100644
--- a/drivers/staging/rtl8192e/r8192E_dm.c
+++ b/drivers/staging/rtl8192e/r8192E_dm.c
@@ -455,7 +455,7 @@
 					(pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
 		}
 
-		//DbgPrint("[DM] THresh H/L=%d/%d\n\r", RATR.HighRSSIThreshForRA, RATR.LowRSSIThreshForRA);
+		//DbgPrint("[DM] Thresh H/L=%d/%d\n\r", RATR.HighRSSIThreshForRA, RATR.LowRSSIThreshForRA);
 		if(priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA)
 		{
 			//DbgPrint("[DM] RSSI=%d STA=HIGH\n\r", pHalData->UndecoratedSmoothedPWDB);
@@ -571,7 +571,7 @@
 	0x5a400169,	// 3, +3db
 	0x50800142,	// 4, +2db
 	0x47c0011f,	// 5, +1db
-	0x40000100,	// 6, +0db ===> default, upper for higher temprature, lower for low temprature
+	0x40000100,	// 6, +0db ===> default, upper for higher temperature, lower for low temperature
 	0x390000e4,	// 7, -1db
 	0x32c000cb,	// 8, -2db
 	0x2d4000b5,	// 9, -3db
@@ -932,14 +932,14 @@
 	RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d \n", tmpRegA);
 	if(tmpRegA < 3 || tmpRegA > 13)
 		return;
-	if(tmpRegA >= 12)	// if over 12, TP will be bad when high temprature
+	if(tmpRegA >= 12)	// if over 12, TP will be bad when high temperature
 		tmpRegA = 12;
 	RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d \n", tmpRegA);
 	priv->ThermalMeter[0] = ThermalMeterVal;	//We use fixed value by Bryant's suggestion
 	priv->ThermalMeter[1] = ThermalMeterVal;	//We use fixed value by Bryant's suggestion
 
-	//Get current RF-A temprature index
-	if(priv->ThermalMeter[0] >= (u8)tmpRegA)	//lower temprature
+	//Get current RF-A temperature index
+	if(priv->ThermalMeter[0] >= (u8)tmpRegA)	//lower temperature
 	{
 		tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0]-(u8)tmpRegA);
 		tmpCCK40Mindex = tmpCCK20Mindex - 6;
@@ -953,7 +953,7 @@
 	else
 	{
 		tmpval = ((u8)tmpRegA - priv->ThermalMeter[0]);
-		if(tmpval >= 6)								// higher temprature
+		if(tmpval >= 6)								// higher temperature
 			tmpOFDMindex = tmpCCK20Mindex = 0;		// max to +6dB
 		else
 			tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval;
@@ -2017,7 +2017,7 @@
 	dm_digtable.dbg_mode = DM_DBG_OFF;	//off=by real rssi value, on=by DM_DigTable.Rssi_val for new dig
 	dm_digtable.dig_algorithm_switch = 0;
 
-	/* 2007/10/04 MH Define init gain threshol. */
+	/* 2007/10/04 MH Define init gain threshold. */
 	dm_digtable.dig_state		= DM_STA_DIG_MAX;
 	dm_digtable.dig_highpwr_state	= DM_STA_DIG_MAX;
 	dm_digtable.initialgain_lowerbound_state = false;
@@ -2145,7 +2145,7 @@
 	/*DbgPrint("DIG Check\n\r RSSI=%d LOW=%d HIGH=%d STATE=%d",
 	pHalData->UndecoratedSmoothedPWDB, DM_DigTable.RssiLowThresh,
 	DM_DigTable.RssiHighThresh, DM_DigTable.Dig_State);*/
-	/* 1. When RSSI decrease, We have to judge if it is smaller than a treshold
+	/* 1. When RSSI decrease, We have to judge if it is smaller than a threshold
 		  and then execute below step. */
 	if ((priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh))
 	{
@@ -2205,7 +2205,7 @@
 
 	}
 
-	/* 2. When RSSI increase, We have to judge if it is larger than a treshold
+	/* 2. When RSSI increase, We have to judge if it is larger than a threshold
 		  and then execute below step.  */
 	if ((priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) )
 	{
@@ -2314,7 +2314,7 @@
 	}
 
 	/* 3. When RSSI >75% or <70%, it is a high power issue. We have to judge if
-		  it is larger than a treshold and then execute below step.  */
+		  it is larger than a threshold and then execute below step.  */
 	// 2008/02/05 MH SD3-Jerry Modify PD_TH for high power issue.
 	if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh)
 	{
diff --git a/drivers/staging/rtl8192e/r8192E_wx.c b/drivers/staging/rtl8192e/r8192E_wx.c
index e9e799c..d1eb892 100644
--- a/drivers/staging/rtl8192e/r8192E_wx.c
+++ b/drivers/staging/rtl8192e/r8192E_wx.c
@@ -446,7 +446,7 @@
 	range->max_qual.updated = 7; /* Updated all three */
 
 	range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
-	/* TODO: Find real 'good' to 'bad' threshol value for RSSI */
+	/* 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 */
diff --git a/drivers/staging/rtl8192e/r819xE_cmdpkt.c b/drivers/staging/rtl8192e/r819xE_cmdpkt.c
index d6b7d2f..2aaa4e1 100644
--- a/drivers/staging/rtl8192e/r819xE_cmdpkt.c
+++ b/drivers/staging/rtl8192e/r819xE_cmdpkt.c
@@ -783,7 +783,7 @@
 
 			default:
 
-			        RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():unknow CMD Element\n");
+			        RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():unknown CMD Element\n");
 				return 1;	/* This is a command packet. */
 		}
 		// 2007/01/22 MH Display received rx command packet info.
diff --git a/drivers/staging/rtl8192e/r819xE_phyreg.h b/drivers/staging/rtl8192e/r819xE_phyreg.h
index d4a4392..37f0fee 100644
--- a/drivers/staging/rtl8192e/r819xE_phyreg.h
+++ b/drivers/staging/rtl8192e/r819xE_phyreg.h
@@ -294,7 +294,7 @@
 #define bR2RCCAMask               		0x00000f00
 #define bHSSI_R2TDelay            		0xf8000000
 #define bHSSI_T2RDelay            		0xf80000
-#define bContTxHSSI               		0x400     //chane gain at continue Tx
+#define bContTxHSSI               		0x400     //channel gain at continue Tx
 #define bIGFromCCK                		0x200
 #define bAGCAddress               		0x3f
 #define bRxHPTx                   			0x7000
diff --git a/drivers/staging/rtl8192su/Kconfig b/drivers/staging/rtl8192su/Kconfig
index b8c95f9..123fa6d 100644
--- a/drivers/staging/rtl8192su/Kconfig
+++ b/drivers/staging/rtl8192su/Kconfig
@@ -1,6 +1,6 @@
 config RTL8192SU
 	tristate "RealTek RTL8192SU Wireless LAN NIC driver"
-	depends on PCI && WLAN
+	depends on PCI && WLAN && USB
 	depends on WIRELESS_EXT
 	default N
 	---help---
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c
index c3383bb..e8c67d5 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c
@@ -156,7 +156,7 @@
  	ieee->privacy_invoked = 0;
  	ieee->ieee802_1x = 1;
 	ieee->raw_tx = 0;
-	//ieee->hwsec_support = 1; //defalt support hw security. //use module_param instead.
+	//ieee->hwsec_support = 1; //default support hw security. //use module_param instead.
 	ieee->hwsec_active = 0; //disable hwsec, switch it on when necessary.
 
 	ieee80211_softmac_init(ieee);
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c
index 8e56f97..ac223ce 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c
@@ -37,7 +37,6 @@
 #include <linux/slab.h>
 #include <linux/tcp.h>
 #include <linux/types.h>
-#include <linux/version.h>
 #include <linux/wireless.h>
 #include <linux/etherdevice.h>
 #include <asm/uaccess.h>
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
index fd8e112..203c0a5 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
@@ -2120,10 +2120,10 @@
  * 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 enought room to TX an entire packet.
+ * 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 treshold is not enought.. If the
+ * 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
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c
index 47ff0ef..60621d6 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c
@@ -47,7 +47,6 @@
 #include <linux/slab.h>
 #include <linux/tcp.h>
 #include <linux/types.h>
-#include <linux/version.h>
 #include <linux/wireless.h>
 #include <linux/etherdevice.h>
 #include <asm/uaccess.h>
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c
index 6146c64..85c7e96 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c
@@ -30,7 +30,6 @@
 
 ******************************************************************************/
 #include <linux/wireless.h>
-#include <linux/version.h>
 #include <linux/kmod.h>
 #include <linux/module.h>
 
diff --git a/drivers/staging/rtl8192su/ieee80211/readme b/drivers/staging/rtl8192su/ieee80211/readme
index 5764f28..7ba177b 100644
--- a/drivers/staging/rtl8192su/ieee80211/readme
+++ b/drivers/staging/rtl8192su/ieee80211/readme
@@ -37,7 +37,7 @@
   disassociate clients, and it is really prone to always allow access.
   In bss client mode it is a bit rough with AP deauth and disassoc requests.
 - It has not any entry point to view the collected stats.
-- Altought it takes care of the card supported rates in the management frame
+- Although it takes care of the card supported rates in the management frame
   it sends, support for rate changing on TXed packet is not complete.
 - Give up once associated in bss client mode (it never detect a
   signal loss condition to disassociate and restart scanning)
diff --git a/drivers/staging/rtl8192su/r8192S_phy.c b/drivers/staging/rtl8192su/r8192S_phy.c
index 2c111d7..77ab026 100644
--- a/drivers/staging/rtl8192su/r8192S_phy.c
+++ b/drivers/staging/rtl8192su/r8192S_phy.c
@@ -1728,7 +1728,7 @@
 
 			default:
 				bResult = FALSE;
-				//RT_ASSERT(FALSE, ("phy_SetRFPowerState8192SU(): unknow state to set: 0x%X!!!\n", eRFPowerState));
+				//RT_ASSERT(FALSE, ("phy_SetRFPowerState8192SU(): unknown state to set: 0x%X!!!\n", eRFPowerState));
 				break;
 		}
 		break;
@@ -2711,7 +2711,7 @@
 // However, this procedure is performed synchronously  which should be running under
 // passive level.
 //
-//not understant it
+//not understand it
 void PHY_SwChnlPhy8192S(	// Only called during initialize
 	struct net_device* dev,
 	u8		channel
diff --git a/drivers/staging/rtl8192su/r8192S_phyreg.h b/drivers/staging/rtl8192su/r8192S_phyreg.h
index 96c7cfa..2e4d76d 100644
--- a/drivers/staging/rtl8192su/r8192S_phyreg.h
+++ b/drivers/staging/rtl8192su/r8192S_phyreg.h
@@ -38,7 +38,7 @@
 // 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00
 // 3. RF register 0x00-2E
 // 4. Bit Mask for BB/RF register
-// 5. Other defintion for BB/RF R/W
+// 5. Other definition for BB/RF R/W
 //
 
 
@@ -453,7 +453,7 @@
 #define		bR2RCCAMask               			0x00000f00
 #define		bHSSI_R2TDelay            		0xf8000000
 #define		bHSSI_T2RDelay            		0xf80000
-#define		bContTxHSSI               			0x400     //chane gain at continue Tx
+#define		bContTxHSSI               			0x400     //channel gain at continue Tx
 #define		bIGFromCCK                			0x200
 #define		bAGCAddress               			0x3f
 #define		bRxHPTx                   			0x7000
diff --git a/drivers/staging/rtl8192su/r8192S_rtl6052.c b/drivers/staging/rtl8192su/r8192S_rtl6052.c
index 69ef6df..2239809 100644
--- a/drivers/staging/rtl8192su/r8192S_rtl6052.c
+++ b/drivers/staging/rtl8192su/r8192S_rtl6052.c
@@ -326,7 +326,7 @@
 
 		//
 		// If path A and Path B coexist, we must limit Path A tx power.
-		// Protect Path B pwr over or under flow. We need to calculate upper and
+		// Protect Path B pwr over or underflow. We need to calculate upper and
 		// lower bound of path A tx power.
 		//
 		if (priv->rf_type == RF_2T2R)
@@ -354,7 +354,7 @@
 
 			//
 			// If path A and Path B coexist, we must limit Path A tx power.
-			// Protect Path B pwr over or under flow. We need to calculate upper and
+			// Protect Path B pwr under/over flow. We need to calculate upper and
 			// lower bound of path A tx power.
 			//
 			if (priv->rf_type == RF_2T2R)
diff --git a/drivers/staging/rtl8192su/r8192U_dm.c b/drivers/staging/rtl8192su/r8192U_dm.c
index 5358ae8..7891e96 100644
--- a/drivers/staging/rtl8192su/r8192U_dm.c
+++ b/drivers/staging/rtl8192su/r8192U_dm.c
@@ -593,7 +593,7 @@
 	0x5a400169,	// 3, +3db
 	0x50800142,	// 4, +2db
 	0x47c0011f,	// 5, +1db
-	0x40000100,	// 6, +0db ===> default, upper for higher temprature, lower for low temprature
+	0x40000100,	// 6, +0db ===> default, upper for higher temperature, lower for low temperature
 	0x390000e4,	// 7, -1db
 	0x32c000cb,	// 8, -2db
 	0x2d4000b5,	// 9, -3db
@@ -912,14 +912,14 @@
 	RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d \n", tmpRegA);
 	if(tmpRegA < 3 || tmpRegA > 13)
 		return;
-	if(tmpRegA >= 12)	// if over 12, TP will be bad when high temprature
+	if(tmpRegA >= 12)	// if over 12, TP will be bad when high temperature
 		tmpRegA = 12;
 	RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d \n", tmpRegA);
 	priv->ThermalMeter[0] = ThermalMeterVal;	//We use fixed value by Bryant's suggestion
 	priv->ThermalMeter[1] = ThermalMeterVal;	//We use fixed value by Bryant's suggestion
 
-	//Get current RF-A temprature index
-	if(priv->ThermalMeter[0] >= (u8)tmpRegA)	//lower temprature
+	//Get current RF-A temperature index
+	if(priv->ThermalMeter[0] >= (u8)tmpRegA)	//lower temperature
 	{
 		tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0]-(u8)tmpRegA);
 		tmpCCK40Mindex = tmpCCK20Mindex - 6;
@@ -933,7 +933,7 @@
 	else
 	{
 		tmpval = ((u8)tmpRegA - priv->ThermalMeter[0]);
-		if(tmpval >= 6)								// higher temprature
+		if(tmpval >= 6)								// higher temperature
 			tmpOFDMindex = tmpCCK20Mindex = 0;		// max to +6dB
 		else
 			tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval;
diff --git a/drivers/staging/rtl8192su/r8192U_wx.c b/drivers/staging/rtl8192su/r8192U_wx.c
index 2208c9b..a7cc6f9 100644
--- a/drivers/staging/rtl8192su/r8192U_wx.c
+++ b/drivers/staging/rtl8192su/r8192U_wx.c
@@ -435,7 +435,7 @@
 	range->max_qual.updated = 7; /* Updated all three */
 
 	range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
-	/* TODO: Find real 'good' to 'bad' threshol value for RSSI */
+	/* 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 */
diff --git a/drivers/staging/rtl8192su/r819xU_cmdpkt.c b/drivers/staging/rtl8192su/r819xU_cmdpkt.c
index e2ba93e..3ebfe79 100644
--- a/drivers/staging/rtl8192su/r819xU_cmdpkt.c
+++ b/drivers/staging/rtl8192su/r819xU_cmdpkt.c
@@ -697,7 +697,7 @@
 
 			default:
 
-			        RT_TRACE(COMP_ERR, "---->cmpk_message_handle_rx():unknow CMD Element\n");
+			        RT_TRACE(COMP_ERR, "---->cmpk_message_handle_rx():unknown CMD Element\n");
 				return 1;	/* This is a command packet. */
 		}
 		// 2007/01/22 MH Display received rx command packet info.
diff --git a/drivers/staging/rtl8192u/Kconfig b/drivers/staging/rtl8192u/Kconfig
new file mode 100644
index 0000000..9913ab8
--- /dev/null
+++ b/drivers/staging/rtl8192u/Kconfig
@@ -0,0 +1,6 @@
+config RTL8192U
+	tristate "RealTek RTL8192U Wireless LAN NIC driver"
+	depends on PCI && WLAN && USB
+	depends on WIRELESS_EXT
+	default N
+	---help---
diff --git a/drivers/staging/rtl8192u/Makefile b/drivers/staging/rtl8192u/Makefile
new file mode 100644
index 0000000..2d59c4e
--- /dev/null
+++ b/drivers/staging/rtl8192u/Makefile
@@ -0,0 +1,33 @@
+NIC_SELECT = RTL8192U
+
+EXTRA_CFLAGS += -std=gnu89
+EXTRA_CFLAGS += -O2
+
+EXTRA_CFLAGS += -mhard-float -DCONFIG_FORCE_HARD_FLOAT=y
+EXTRA_CFLAGS += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX
+EXTRA_CFLAGS += -DTHOMAS_BEACON -DTHOMAS_TASKLET -DTHOMAS_SKB -DTHOMAS_TURBO
+#EXTRA_CFLAGS += -DUSB_TX_DRIVER_AGGREGATION_ENABLE
+#EXTRA_CFLAGS += -DUSB_RX_AGGREGATION_SUPPORT
+EXTRA_CFLAGS += -DUSE_ONE_PIPE
+EXTRA_CFLAGS += -DENABLE_DOT11D
+EXTRA_CFLAGS += -Idrivers/staging/rtl8192u/ieee80211
+
+r8192u_usb-objs := r8192U_core.o r8180_93cx6.o r8192U_wx.o		\
+		  r8190_rtl8256.o r819xU_phy.o r819xU_firmware.o	\
+		  r819xU_cmdpkt.o r8192U_dm.o r819xU_firmware_img.o	\
+		  ieee80211/ieee80211_crypt.o				\
+		  ieee80211/ieee80211_crypt_tkip.o			\
+		  ieee80211/ieee80211_crypt_ccmp.o			\
+		  ieee80211/ieee80211_crypt_wep.o			\
+		  ieee80211/ieee80211_rx.o				\
+		  ieee80211/ieee80211_softmac.o				\
+		  ieee80211/ieee80211_tx.o				\
+		  ieee80211/ieee80211_wx.o				\
+		  ieee80211/ieee80211_module.o				\
+		  ieee80211/ieee80211_softmac_wx.o			\
+		  ieee80211/rtl819x_HTProc.o				\
+		  ieee80211/rtl819x_TSProc.o				\
+		  ieee80211/rtl819x_BAProc.o				\
+		  ieee80211/dot11d.o
+
+obj-$(CONFIG_RTL8192U) += r8192u_usb.o
diff --git a/drivers/staging/rtl8192u/authors b/drivers/staging/rtl8192u/authors
new file mode 100644
index 0000000..b08bbae
--- /dev/null
+++ b/drivers/staging/rtl8192u/authors
@@ -0,0 +1 @@
+Andrea Merello <andreamrl@tiscali.it>
diff --git a/drivers/staging/rtl8192u/changes b/drivers/staging/rtl8192u/changes
new file mode 100644
index 0000000..87c33fd
--- /dev/null
+++ b/drivers/staging/rtl8192u/changes
@@ -0,0 +1,5 @@
+v 0.1
+
+First version.
+This is based on the rtl8180-sa2400 pre-0.22-CVS code..
+
diff --git a/drivers/staging/rtl8192u/copying b/drivers/staging/rtl8192u/copying
new file mode 100644
index 0000000..d60c31a
--- /dev/null
+++ b/drivers/staging/rtl8192u/copying
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/drivers/staging/rtl8192u/dot11d.h b/drivers/staging/rtl8192u/dot11d.h
new file mode 100644
index 0000000..15b7a4b
--- /dev/null
+++ b/drivers/staging/rtl8192u/dot11d.h
@@ -0,0 +1,102 @@
+#ifndef __INC_DOT11D_H
+#define __INC_DOT11D_H
+
+#ifdef ENABLE_DOT11D
+#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_DOT11D_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 //ENABLE_DOT11D
+#endif // #ifndef __INC_DOT11D_H
diff --git a/drivers/staging/rtl8192u/ieee80211.h b/drivers/staging/rtl8192u/ieee80211.h
new file mode 100644
index 0000000..3a47f12
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211.h
@@ -0,0 +1,2638 @@
+/*
+ * 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
+ * <andreamrl@tiscali.it>
+ *
+ * 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/version.h>
+#include <linux/module.h>
+#include <linux/jiffies.h>
+#include <linux/timer.h>
+#include <linux/sched.h>
+
+#include <linux/delay.h>
+#include <linux/wireless.h>
+
+#include "ieee80211/rtl819x_HT.h"
+#include "ieee80211/rtl819x_BA.h"
+#include "ieee80211/rtl819x_TS.h"
+
+
+#ifndef IW_MODE_MONITOR
+#define IW_MODE_MONITOR 6
+#endif
+
+#ifndef IWEVCUSTOM
+#define IWEVCUSTOM 0x8c02
+#endif
+
+
+#ifndef container_of
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ *
+ * @ptr:        the pointer to the member.
+ * @type:       the type of the container struct this is embedded in.
+ * @member:     the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({                      \
+	const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
+	(type *)( (char *)__mptr - offsetof(type,member) );})
+#endif
+
+#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
+
+/* added for rtl819x tx procedure */
+#define MAX_QUEUE_SIZE		0x10
+
+//
+// 8190 queue mapping
+//
+#define BK_QUEUE                               0
+#define BE_QUEUE                               1
+#define VI_QUEUE                               2
+#define VO_QUEUE                               3
+#define HCCA_QUEUE                             4
+#define TXCMD_QUEUE                            5
+#define MGNT_QUEUE                             6
+#define HIGH_QUEUE                             7
+#define BEACON_QUEUE                           8
+
+#define LOW_QUEUE                              BE_QUEUE
+#define NORMAL_QUEUE                           MGNT_QUEUE
+
+//added by amy for ps
+#define SWRF_TIMEOUT				50
+
+//added by amy for LEAP related
+#define IE_CISCO_FLAG_POSITION		0x08	// Flag byte: byte 8, numbered from 0.
+#define SUPPORT_CKIP_MIC			0x08	// bit3
+#define SUPPORT_CKIP_PK			0x10	// bit4
+/* defined for skb cb field */
+/* At most 28 byte */
+typedef struct cb_desc {
+	/* Tx Desc Related flags (8-9) */
+	u8 bLastIniPkt:1;
+	u8 bCmdOrInit:1;
+	u8 bFirstSeg:1;
+	u8 bLastSeg:1;
+	u8 bEncrypt:1;
+	u8 bTxDisableRateFallBack:1;
+	u8 bTxUseDriverAssingedRate:1;
+	u8 bHwSec:1; //indicate whether use Hw security. WB
+
+	u8 reserved1;
+
+	/* Tx Firmware Relaged flags (10-11)*/
+	u8 bCTSEnable:1;
+	u8 bRTSEnable:1;
+	u8 bUseShortGI:1;
+	u8 bUseShortPreamble:1;
+	u8 bTxEnableFwCalcDur:1;
+	u8 bAMPDUEnable:1;
+	u8 bRTSSTBC:1;
+	u8 RTSSC:1;
+
+	u8 bRTSBW:1;
+	u8 bPacketBW:1;
+	u8 bRTSUseShortPreamble:1;
+	u8 bRTSUseShortGI:1;
+	u8 bMulticast:1;
+	u8 bBroadcast:1;
+	//u8 reserved2:2;
+	u8 drv_agg_enable:1;
+	u8 reserved2:1;
+
+	/* Tx Desc related element(12-19) */
+	u8 rata_index;
+	u8 queue_index;
+	//u8 reserved3;
+	//u8 reserved4;
+	u16 txbuf_size;
+	//u8 reserved5;
+	u8 RATRIndex;
+	u8 reserved6;
+	u8 reserved7;
+	u8 reserved8;
+
+	/* Tx firmware related element(20-27) */
+	u8 data_rate;
+	u8 rts_rate;
+	u8 ampdu_factor;
+	u8 ampdu_density;
+	//u8 reserved9;
+	//u8 reserved10;
+	//u8 reserved11;
+	u8 DrvAggrNum;
+	u16 pkt_size;
+	u8 reserved12;
+}cb_desc, *pcb_desc;
+
+/*--------------------------Define -------------------------------------------*/
+#define MGN_1M                  0x02
+#define MGN_2M                  0x04
+#define MGN_5_5M                0x0b
+#define MGN_11M                 0x16
+
+#define MGN_6M                  0x0c
+#define MGN_9M                  0x12
+#define MGN_12M                 0x18
+#define MGN_18M                 0x24
+#define MGN_24M                 0x30
+#define MGN_36M                 0x48
+#define MGN_48M                 0x60
+#define MGN_54M                 0x6c
+
+#define MGN_MCS0                0x80
+#define MGN_MCS1                0x81
+#define MGN_MCS2                0x82
+#define MGN_MCS3                0x83
+#define MGN_MCS4                0x84
+#define MGN_MCS5                0x85
+#define MGN_MCS6                0x86
+#define MGN_MCS7                0x87
+#define MGN_MCS8                0x88
+#define MGN_MCS9                0x89
+#define MGN_MCS10               0x8a
+#define MGN_MCS11               0x8b
+#define MGN_MCS12               0x8c
+#define MGN_MCS13               0x8d
+#define MGN_MCS14               0x8e
+#define MGN_MCS15               0x8f
+
+//----------------------------------------------------------------------------
+//		802.11 Management frame Reason Code field
+//----------------------------------------------------------------------------
+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
+};
+
+
+
+#define aSifsTime	 ((priv->ieee80211->current_network.mode == IEEE_A)||(priv->ieee80211->current_network.mode == IEEE_N_24G)||(priv->ieee80211->current_network.mode == IEEE_N_5G))? 16 : 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
+
+#define MAX_IE_LEN  0xff
+
+// added for kernel conflict
+#define ieee80211_crypt_deinit_entries 	ieee80211_crypt_deinit_entries_rsl
+#define ieee80211_crypt_deinit_handler 	ieee80211_crypt_deinit_handler_rsl
+#define ieee80211_crypt_delayed_deinit 	ieee80211_crypt_delayed_deinit_rsl
+#define ieee80211_register_crypto_ops  	ieee80211_register_crypto_ops_rsl
+#define ieee80211_unregister_crypto_ops ieee80211_unregister_crypto_ops_rsl
+#define ieee80211_get_crypto_ops 	ieee80211_get_crypto_ops_rsl
+
+#define ieee80211_ccmp_null		ieee80211_ccmp_null_rsl
+
+#define ieee80211_tkip_null		ieee80211_tkip_null_rsl
+
+#define ieee80211_wep_null		ieee80211_wep_null_rsl
+
+#define free_ieee80211          	free_ieee80211_rsl
+#define alloc_ieee80211        		alloc_ieee80211_rsl
+
+#define ieee80211_rx 			ieee80211_rx_rsl
+#define ieee80211_rx_mgt		ieee80211_rx_mgt_rsl
+
+#define ieee80211_get_beacon		ieee80211_get_beacon_rsl
+#define ieee80211_wake_queue		ieee80211_wake_queue_rsl
+#define ieee80211_stop_queue		ieee80211_stop_queue_rsl
+#define ieee80211_reset_queue		ieee80211_reset_queue_rsl
+#define ieee80211_softmac_stop_protocol	ieee80211_softmac_stop_protocol_rsl
+#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl
+#define ieee80211_is_shortslot		ieee80211_is_shortslot_rsl
+#define ieee80211_is_54g		ieee80211_is_54g_rsl
+#define ieee80211_wpa_supplicant_ioctl	ieee80211_wpa_supplicant_ioctl_rsl
+#define ieee80211_ps_tx_ack		ieee80211_ps_tx_ack_rsl
+#define ieee80211_softmac_xmit		ieee80211_softmac_xmit_rsl
+#define ieee80211_stop_send_beacons	ieee80211_stop_send_beacons_rsl
+#define notify_wx_assoc_event		notify_wx_assoc_event_rsl
+#define SendDisassociation		SendDisassociation_rsl
+#define ieee80211_disassociate		ieee80211_disassociate_rsl
+#define ieee80211_start_send_beacons	ieee80211_start_send_beacons_rsl
+#define ieee80211_stop_scan		ieee80211_stop_scan_rsl
+#define ieee80211_send_probe_requests	ieee80211_send_probe_requests_rsl
+#define ieee80211_softmac_scan_syncro	ieee80211_softmac_scan_syncro_rsl
+#define ieee80211_start_scan_syncro	ieee80211_start_scan_syncro_rsl
+
+#define ieee80211_wx_get_essid		ieee80211_wx_get_essid_rsl
+#define ieee80211_wx_set_essid		ieee80211_wx_set_essid_rsl
+#define ieee80211_wx_set_rate		ieee80211_wx_set_rate_rsl
+#define ieee80211_wx_get_rate		ieee80211_wx_get_rate_rsl
+#define ieee80211_wx_set_wap		ieee80211_wx_set_wap_rsl
+#define ieee80211_wx_get_wap		ieee80211_wx_get_wap_rsl
+#define ieee80211_wx_set_mode		ieee80211_wx_set_mode_rsl
+#define ieee80211_wx_get_mode		ieee80211_wx_get_mode_rsl
+#define ieee80211_wx_set_scan		ieee80211_wx_set_scan_rsl
+#define ieee80211_wx_get_freq		ieee80211_wx_get_freq_rsl
+#define ieee80211_wx_set_freq		ieee80211_wx_set_freq_rsl
+#define ieee80211_wx_set_rawtx		ieee80211_wx_set_rawtx_rsl
+#define ieee80211_wx_get_name		ieee80211_wx_get_name_rsl
+#define ieee80211_wx_set_power		ieee80211_wx_set_power_rsl
+#define ieee80211_wx_get_power		ieee80211_wx_get_power_rsl
+#define ieee80211_wlan_frequencies	ieee80211_wlan_frequencies_rsl
+#define ieee80211_wx_set_rts		ieee80211_wx_set_rts_rsl
+#define ieee80211_wx_get_rts		ieee80211_wx_get_rts_rsl
+
+#define ieee80211_txb_free		ieee80211_txb_free_rsl
+
+#define ieee80211_wx_set_gen_ie		ieee80211_wx_set_gen_ie_rsl
+#define ieee80211_wx_get_scan		ieee80211_wx_get_scan_rsl
+#define ieee80211_wx_set_encode		ieee80211_wx_set_encode_rsl
+#define ieee80211_wx_get_encode		ieee80211_wx_get_encode_rsl
+#if WIRELESS_EXT >= 18
+#define ieee80211_wx_set_mlme		ieee80211_wx_set_mlme_rsl
+#define ieee80211_wx_set_auth		ieee80211_wx_set_auth_rsl
+#define ieee80211_wx_set_encode_ext	ieee80211_wx_set_encode_ext_rsl
+#define ieee80211_wx_get_encode_ext	ieee80211_wx_get_encode_ext_rsl
+#endif
+
+
+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;
+
+
+#if WIRELESS_EXT < 17
+#define IW_QUAL_QUAL_INVALID   0x10
+#define IW_QUAL_LEVEL_INVALID  0x20
+#define IW_QUAL_NOISE_INVALID  0x40
+#define IW_QUAL_QUAL_UPDATED   0x1
+#define IW_QUAL_LEVEL_UPDATED  0x2
+#define IW_QUAL_NOISE_UPDATED  0x4
+#endif
+
+
+// linux under 2.6.9 release may not support it, so modify it for common use
+#define MSECS(t) msecs_to_jiffies(t)
+#define msleep_interruptible_rsl  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_1ADDR_LEN 10
+#define IEEE80211_2ADDR_LEN 16
+#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_VERS		0x0003
+#define IEEE80211_FCTL_FTYPE		0x000c
+#define IEEE80211_FCTL_STYPE		0x00f0
+#define IEEE80211_FCTL_FRAMETYPE	0x00fc
+#define IEEE80211_FCTL_TODS		0x0100
+#define IEEE80211_FCTL_FROMDS		0x0200
+#define IEEE80211_FCTL_DSTODS		0x0300 //added by david
+#define IEEE80211_FCTL_MOREFRAGS	0x0400
+#define IEEE80211_FCTL_RETRY		0x0800
+#define IEEE80211_FCTL_PM		0x1000
+#define IEEE80211_FCTL_MOREDATA		0x2000
+#define IEEE80211_FCTL_WEP		0x4000
+#define IEEE80211_FCTL_ORDER		0x8000
+
+#define IEEE80211_FTYPE_MGMT		0x0000
+#define IEEE80211_FTYPE_CTL		0x0004
+#define IEEE80211_FTYPE_DATA		0x0008
+
+/* management */
+#define IEEE80211_STYPE_ASSOC_REQ	0x0000
+#define IEEE80211_STYPE_ASSOC_RESP 	0x0010
+#define IEEE80211_STYPE_REASSOC_REQ	0x0020
+#define IEEE80211_STYPE_REASSOC_RESP	0x0030
+#define IEEE80211_STYPE_PROBE_REQ	0x0040
+#define IEEE80211_STYPE_PROBE_RESP	0x0050
+#define IEEE80211_STYPE_BEACON		0x0080
+#define IEEE80211_STYPE_ATIM		0x0090
+#define IEEE80211_STYPE_DISASSOC	0x00A0
+#define IEEE80211_STYPE_AUTH		0x00B0
+#define IEEE80211_STYPE_DEAUTH		0x00C0
+#define IEEE80211_STYPE_MANAGE_ACT	0x00D0
+
+/* control */
+#define IEEE80211_STYPE_PSPOLL		0x00A0
+#define IEEE80211_STYPE_RTS		0x00B0
+#define IEEE80211_STYPE_CTS		0x00C0
+#define IEEE80211_STYPE_ACK		0x00D0
+#define IEEE80211_STYPE_CFEND		0x00E0
+#define IEEE80211_STYPE_CFENDACK	0x00F0
+#define IEEE80211_STYPE_BLOCKACK   0x0094
+
+/* data */
+#define IEEE80211_STYPE_DATA		0x0000
+#define IEEE80211_STYPE_DATA_CFACK	0x0010
+#define IEEE80211_STYPE_DATA_CFPOLL	0x0020
+#define IEEE80211_STYPE_DATA_CFACKPOLL	0x0030
+#define IEEE80211_STYPE_NULLFUNC	0x0040
+#define IEEE80211_STYPE_CFACK		0x0050
+#define IEEE80211_STYPE_CFPOLL		0x0060
+#define IEEE80211_STYPE_CFACKPOLL	0x0070
+#define IEEE80211_STYPE_QOS_DATA	0x0080 //added for WMM 2006/8/2
+#define IEEE80211_STYPE_QOS_NULL	0x00C0
+
+#define IEEE80211_SCTL_FRAG		0x000F
+#define IEEE80211_SCTL_SEQ		0xFFF0
+
+/* QOS control */
+#define IEEE80211_QCTL_TID              0x000F
+
+#define	FC_QOS_BIT					BIT7
+#define IsDataFrame(pdu)			( ((pdu[0] & 0x0C)==0x08) ? true : false )
+#define	IsLegacyDataFrame(pdu)	(IsDataFrame(pdu) && (!(pdu[0]&FC_QOS_BIT)) )
+//added by wb. Is this right?
+#define IsQoSDataFrame(pframe)  ((*(u16*)pframe&(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) == (IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA))
+#define Frame_Order(pframe)     (*(u16*)pframe&IEEE80211_FCTL_ORDER)
+#define SN_LESS(a, b)		(((a-b)&0x800)!=0)
+#define SN_EQUAL(a, b)	(a == b)
+#define MAX_DEV_ADDR_SIZE 8
+typedef enum _ACT_CATEGORY{
+	ACT_CAT_QOS = 1,
+	ACT_CAT_DLS = 2,
+	ACT_CAT_BA  = 3,
+	ACT_CAT_HT  = 7,
+	ACT_CAT_WMM = 17,
+} ACT_CATEGORY, *PACT_CATEGORY;
+
+typedef enum _TS_ACTION{
+	ACT_ADDTSREQ = 0,
+	ACT_ADDTSRSP = 1,
+	ACT_DELTS    = 2,
+	ACT_SCHEDULE = 3,
+} TS_ACTION, *PTS_ACTION;
+
+typedef enum _BA_ACTION{
+	ACT_ADDBAREQ = 0,
+	ACT_ADDBARSP = 1,
+	ACT_DELBA    = 2,
+} BA_ACTION, *PBA_ACTION;
+
+typedef enum _InitialGainOpType{
+	IG_Backup=0,
+	IG_Restore,
+	IG_Max
+}InitialGainOpType;
+
+/* debug macros */
+#define CONFIG_IEEE80211_DEBUG
+#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: " fmt, ## args); } while (0)
+//wb added to debug out data buf
+//if you want print DATA buffer related BA, please set ieee80211_debug_level to DATA|BA
+#define IEEE80211_DEBUG_DATA(level, data, datalen)	\
+	do{ if ((ieee80211_debug_level & (level)) == (level))	\
+		{ 	\
+			int i;					\
+			u8* pdata = (u8*) data;			\
+			printk(KERN_DEBUG "ieee80211: %s()\n", __FUNCTION__);	\
+			for(i=0; i<(int)(datalen); i++)			\
+			{						\
+				printk("%2x ", pdata[i]);		\
+				if ((i+1)%16 == 0) printk("\n");	\
+			}				\
+			printk("\n");			\
+		}					\
+	} while (0)
+#else
+#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
+#define IEEE80211_DEBUG_DATA(level, data, datalen) do {} while(0)
+#endif	/* CONFIG_IEEE80211_DEBUG */
+
+/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
+
+#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
+#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
+
+/*
+ * 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_DL_HT		   (1<<10)  //HT
+#define IEEE80211_DL_BA		   (1<<11)  //ba
+#define IEEE80211_DL_TS		   (1<<12)  //TS
+#define IEEE80211_DL_QOS           (1<<13)
+#define IEEE80211_DL_REORDER	   (1<<14)
+#define IEEE80211_DL_IOT	   (1<<15)
+#define IEEE80211_DL_IPS	   (1<<16)
+#define IEEE80211_DL_TRACE	   (1<<29)  //trace function, need to user net_ratelimit() together in order not to print too much to the screen
+#define IEEE80211_DL_DATA	   (1<<30)   //use this flag to control whether print data buf out.
+#define IEEE80211_DL_ERR	   (1<<31)   //always open
+#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 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)
+#define IEEE80211_DEBUG_QOS(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a)
+
+#ifdef CONFIG_IEEE80211_DEBUG
+/* Added by Annie, 2005-11-22. */
+#define MAX_STR_LEN     64
+/* I want to see ASCII 33 to 126 only. Otherwise, I print '?'. Annie, 2005-11-22.*/
+#define PRINTABLE(_ch)  (_ch>'!' && _ch<'~')
+#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len)                            	\
+			if((_Comp) & level)   							\
+			{                                                                       \
+				int             __i;                                            \
+				u8  buffer[MAX_STR_LEN];                                    	\
+				int length = (_Len<MAX_STR_LEN)? _Len : (MAX_STR_LEN-1) ;  	\
+				memset(buffer, 0, MAX_STR_LEN);                      		\
+				memcpy(buffer, (u8 *)_Ptr, length );            		\
+				for( __i=0; __i<MAX_STR_LEN; __i++ )                            \
+				{                                                               \
+				     if( !PRINTABLE(buffer[__i]) )   buffer[__i] = '?';     	\
+				}                                                               \
+				buffer[length] = '\0';                                          \
+				printk("Rtl819x: ");                                         	\
+				printk(_TitleString);                                         \
+				printk(": %d, <%s>\n", _Len, buffer);                         \
+			}
+#else
+#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len)  do {} while (0)
+#endif
+
+#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_VERS(fc) ((fc) & IEEE80211_FCTL_VERS)
+#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
+#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
+
+#define WLAN_FC_GET_FRAMETYPE(fc) ((fc) & IEEE80211_FCTL_FRAMETYPE)
+#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
+#define WLAN_GET_SEQ_SEQ(seq)  (((seq) & IEEE80211_SCTL_SEQ) >> 4)
+
+/* Authentication algorithms */
+#define WLAN_AUTH_OPEN 0
+#define WLAN_AUTH_SHARED_KEY 1
+#define WLAN_AUTH_LEAP 2
+
+#define WLAN_AUTH_CHALLENGE_LEN 128
+
+#define WLAN_CAPABILITY_BSS (1<<0)
+#define WLAN_CAPABILITY_IBSS (1<<1)
+#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
+#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
+#define WLAN_CAPABILITY_PRIVACY (1<<4)
+#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
+#define WLAN_CAPABILITY_PBCC (1<<6)
+#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
+#define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8)
+#define WLAN_CAPABILITY_QOS (1<<9)
+#define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
+#define WLAN_CAPABILITY_DSSS_OFDM (1<<13)
+
+/* 802.11g ERP information element */
+#define WLAN_ERP_NON_ERP_PRESENT (1<<0)
+#define WLAN_ERP_USE_PROTECTION (1<<1)
+#define WLAN_ERP_BARKER_PREAMBLE (1<<2)
+
+/* Status codes */
+enum ieee80211_statuscode {
+	WLAN_STATUS_SUCCESS = 0,
+	WLAN_STATUS_UNSPECIFIED_FAILURE = 1,
+	WLAN_STATUS_CAPS_UNSUPPORTED = 10,
+	WLAN_STATUS_REASSOC_NO_ASSOC = 11,
+	WLAN_STATUS_ASSOC_DENIED_UNSPEC = 12,
+	WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG = 13,
+	WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION = 14,
+	WLAN_STATUS_CHALLENGE_FAIL = 15,
+	WLAN_STATUS_AUTH_TIMEOUT = 16,
+	WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17,
+	WLAN_STATUS_ASSOC_DENIED_RATES = 18,
+	/* 802.11b */
+	WLAN_STATUS_ASSOC_DENIED_NOSHORTPREAMBLE = 19,
+	WLAN_STATUS_ASSOC_DENIED_NOPBCC = 20,
+	WLAN_STATUS_ASSOC_DENIED_NOAGILITY = 21,
+	/* 802.11h */
+	WLAN_STATUS_ASSOC_DENIED_NOSPECTRUM = 22,
+	WLAN_STATUS_ASSOC_REJECTED_BAD_POWER = 23,
+	WLAN_STATUS_ASSOC_REJECTED_BAD_SUPP_CHAN = 24,
+	/* 802.11g */
+	WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25,
+	WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26,
+	/* 802.11i */
+	WLAN_STATUS_INVALID_IE = 40,
+	WLAN_STATUS_INVALID_GROUP_CIPHER = 41,
+	WLAN_STATUS_INVALID_PAIRWISE_CIPHER = 42,
+	WLAN_STATUS_INVALID_AKMP = 43,
+	WLAN_STATUS_UNSUPP_RSN_VERSION = 44,
+	WLAN_STATUS_INVALID_RSN_IE_CAP = 45,
+	WLAN_STATUS_CIPHER_SUITE_REJECTED = 46,
+};
+
+/* Reason codes */
+enum ieee80211_reasoncode {
+	WLAN_REASON_UNSPECIFIED = 1,
+	WLAN_REASON_PREV_AUTH_NOT_VALID = 2,
+	WLAN_REASON_DEAUTH_LEAVING = 3,
+	WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY = 4,
+	WLAN_REASON_DISASSOC_AP_BUSY = 5,
+	WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6,
+	WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7,
+	WLAN_REASON_DISASSOC_STA_HAS_LEFT = 8,
+	WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH = 9,
+	/* 802.11h */
+	WLAN_REASON_DISASSOC_BAD_POWER = 10,
+	WLAN_REASON_DISASSOC_BAD_SUPP_CHAN = 11,
+	/* 802.11i */
+	WLAN_REASON_INVALID_IE = 13,
+	WLAN_REASON_MIC_FAILURE = 14,
+	WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT = 15,
+	WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT = 16,
+	WLAN_REASON_IE_DIFFERENT = 17,
+	WLAN_REASON_INVALID_GROUP_CIPHER = 18,
+	WLAN_REASON_INVALID_PAIRWISE_CIPHER = 19,
+	WLAN_REASON_INVALID_AKMP = 20,
+	WLAN_REASON_UNSUPP_RSN_VERSION = 21,
+	WLAN_REASON_INVALID_RSN_IE_CAP = 22,
+	WLAN_REASON_IEEE8021X_FAILED = 23,
+	WLAN_REASON_CIPHER_SUITE_REJECTED = 24,
+};
+
+#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];
+	s8 rssi;
+	u8 signal;
+	u8 noise;
+	u16 rate; /* in 100 kbps */
+	u8 received_channel;
+	u8 control;
+	u8 mask;
+	u8 freq;
+	u16 len;
+	u64 tsf;
+	u32 beacon_time;
+	u8 nic_type;
+	u16       Length;
+	//      u8        DataRate;      // In 0.5 Mbps
+	u8        SignalQuality; // in 0-100 index.
+	s32       RecvSignalPower; // Real power in dBm for this packet, no beautification and aggregation.
+	s8        RxPower; // in dBm Translate from PWdB
+	u8        SignalStrength; // in 0-100 index.
+	u16       bHwError:1;
+	u16       bCRC:1;
+	u16       bICV:1;
+	u16       bShortPreamble:1;
+	u16       Antenna:1;      //for rtl8185
+	u16       Decrypted:1;    //for rtl8185, rtl8187
+	u16       Wakeup:1;       //for rtl8185
+	u16       Reserved0:1;    //for rtl8185
+	u8        AGC;
+	u32       TimeStampLow;
+	u32       TimeStampHigh;
+	bool      bShift;
+	bool      bIsQosData;             // Added by Annie, 2005-12-22.
+	u8        UserPriority;
+
+	//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
+	//1Attention Please!!!<11n or 8190 specific code should be put below this line>
+	//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+	u8        RxDrvInfoSize;
+	u8        RxBufShift;
+	bool      bIsAMPDU;
+	bool      bFirstMPDU;
+	bool      bContainHTC;
+	bool      RxIs40MHzPacket;
+	u32       RxPWDBAll;
+	u8        RxMIMOSignalStrength[4];        // in 0~100 index
+	s8        RxMIMOSignalQuality[2];
+	bool      bPacketMatchBSSID;
+	bool      bIsCCK;
+	bool      bPacketToSelf;
+	//added by amy
+	u8*       virtual_address;
+	u16          packetlength;              // Total packet length: Must equal to sum of all FragLength
+	u16          fraglength;                        // FragLength should equal to PacketLength in non-fragment case
+	u16          fragoffset;                        // Data offset for this fragment
+	u16          ntotalfrag;
+	bool      	  bisrxaggrsubframe;
+	bool		  bPacketBeacon;	//cosa add for rssi
+	bool		  bToSelfBA;		//cosa add for rssi
+	char 	  cck_adc_pwdb[4];	//cosa add for rx path selection
+	u16		  Seq_Num;
+
+};
+
+/* 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_ENCRYPT       (1<<9)
+
+#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 SEC_ALG_NONE            0
+#define SEC_ALG_WEP             1
+#define SEC_ALG_TKIP            2
+#define SEC_ALG_CCMP            3
+
+#define WEP_KEYS 		4
+#define WEP_KEY_LEN		13
+#define SCM_KEY_LEN             32
+#define SCM_TEMPORAL_KEY_LENGTH 16
+
+struct ieee80211_security {
+	u16 active_key:2,
+	    enabled:1,
+	    auth_mode:2,
+	    auth_algo:4,
+	    unicast_uses_group:1,
+	    encrypt:1;
+	u8 key_sizes[WEP_KEYS];
+	u8 keys[WEP_KEYS][SCM_KEY_LEN];
+	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 ieee80211_mfie {
+	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_HOP_PARAMS = 8,
+	MFIE_TYPE_HOP_TABLE = 9,
+	MFIE_TYPE_REQUEST = 10,
+	MFIE_TYPE_CHALLENGE = 16,
+	MFIE_TYPE_POWER_CONSTRAINT = 32,
+	MFIE_TYPE_POWER_CAPABILITY = 33,
+	MFIE_TYPE_TPC_REQUEST = 34,
+	MFIE_TYPE_TPC_REPORT = 35,
+	MFIE_TYPE_SUPP_CHANNELS = 36,
+	MFIE_TYPE_CSA = 37,
+	MFIE_TYPE_MEASURE_REQUEST = 38,
+	MFIE_TYPE_MEASURE_REPORT = 39,
+	MFIE_TYPE_QUIET = 40,
+	MFIE_TYPE_IBSS_DFS = 41,
+	MFIE_TYPE_ERP = 42,
+	MFIE_TYPE_RSN = 48,
+	MFIE_TYPE_RATES_EX = 50,
+	MFIE_TYPE_HT_CAP= 45,
+	 MFIE_TYPE_HT_INFO= 61,
+	 MFIE_TYPE_AIRONET=133,
+	MFIE_TYPE_GENERIC = 221,
+	MFIE_TYPE_QOS_PARAMETER = 222,
+};
+
+/* Minimal header; can be used for passing 802.11 frames with sufficient
+ * information to determine what type of underlying data type is actually
+ * stored in the data. */
+struct ieee80211_hdr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_1addr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_2addr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_4addr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 addr4[ETH_ALEN];
+	u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addrqos {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 payload[0];
+	__le16 qos_ctl;
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_4addrqos {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 addr4[ETH_ALEN];
+	u8 payload[0];
+	__le16 qos_ctl;
+} __attribute__ ((packed));
+
+struct ieee80211_info_element {
+	u8 id;
+	u8 len;
+	u8 data[0];
+} __attribute__ ((packed));
+
+struct ieee80211_authentication {
+	struct ieee80211_hdr_3addr header;
+	__le16 algorithm;
+	__le16 transaction;
+	__le16 status;
+	/*challenge*/
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_disassoc {
+	struct ieee80211_hdr_3addr header;
+	__le16 reason;
+} __attribute__ ((packed));
+
+struct ieee80211_probe_request {
+	struct ieee80211_hdr_3addr header;
+	/* SSID, supported rates */
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_probe_response {
+	struct ieee80211_hdr_3addr header;
+	u32 time_stamp[2];
+	__le16 beacon_interval;
+	__le16 capability;
+	/* SSID, supported rates, FH params, DS params,
+	 * CF params, IBSS params, TIM (if beacon), RSN */
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+/* Alias beacon for probe_response */
+#define ieee80211_beacon ieee80211_probe_response
+
+struct ieee80211_assoc_request_frame {
+	struct ieee80211_hdr_3addr header;
+	__le16 capability;
+	__le16 listen_interval;
+	/* SSID, supported rates, RSN */
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_reassoc_request_frame {
+	struct ieee80211_hdr_3addr header;
+	__le16 capability;
+	__le16 listen_interval;
+	u8 current_ap[ETH_ALEN];
+	/* SSID, supported rates, RSN */
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_assoc_response_frame {
+	struct ieee80211_hdr_3addr header;
+	__le16 capability;
+	__le16 status;
+	__le16 aid;
+	struct ieee80211_info_element info_element[0]; /* supported rates */
+} __attribute__ ((packed));
+
+struct ieee80211_txb {
+	u8 nr_frags;
+	u8 encrypted;
+	u8 queue_index;
+	u8 rts_included;
+	u16 reserved;
+	__le16 frag_size;
+	__le16 payload_size;
+	struct sk_buff *fragments[0];
+};
+
+#define MAX_TX_AGG_COUNT		  16
+struct ieee80211_drv_agg_txb {
+	u8 nr_drv_agg_frames;
+	struct sk_buff *tx_agg_frames[MAX_TX_AGG_COUNT];
+}__attribute__((packed));
+
+#define MAX_SUBFRAME_COUNT 		  64
+struct ieee80211_rxb {
+	u8 nr_subframes;
+	struct sk_buff *subframes[MAX_SUBFRAME_COUNT];
+	u8 dst[ETH_ALEN];
+	u8 src[ETH_ALEN];
+}__attribute__((packed));
+
+typedef union _frameqos {
+	u16 shortdata;
+	u8  chardata[2];
+	struct {
+		u16 tid:4;
+		u16 eosp:1;
+		u16 ack_policy:2;
+		u16 reserved:1;
+		u16 txop:8;
+	}field;
+}frameqos,*pframeqos;
+
+/* 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                 161
+#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)
+
+/* QoS structure */
+#define NETWORK_HAS_QOS_PARAMETERS      (1<<3)
+#define NETWORK_HAS_QOS_INFORMATION     (1<<4)
+#define NETWORK_HAS_QOS_MASK            (NETWORK_HAS_QOS_PARAMETERS | \
+					 NETWORK_HAS_QOS_INFORMATION)
+/* 802.11h */
+#define NETWORK_HAS_POWER_CONSTRAINT    (1<<5)
+#define NETWORK_HAS_CSA                 (1<<6)
+#define NETWORK_HAS_QUIET               (1<<7)
+#define NETWORK_HAS_IBSS_DFS            (1<<8)
+#define NETWORK_HAS_TPC_REPORT          (1<<9)
+
+#define NETWORK_HAS_ERP_VALUE           (1<<10)
+
+#define QOS_QUEUE_NUM                   4
+#define QOS_OUI_LEN                     3
+#define QOS_OUI_TYPE                    2
+#define QOS_ELEMENT_ID                  221
+#define QOS_OUI_INFO_SUB_TYPE           0
+#define QOS_OUI_PARAM_SUB_TYPE          1
+#define QOS_VERSION_1                   1
+#define QOS_AIFSN_MIN_VALUE             2
+struct ieee80211_qos_information_element {
+	u8 elementID;
+	u8 length;
+	u8 qui[QOS_OUI_LEN];
+	u8 qui_type;
+	u8 qui_subtype;
+	u8 version;
+	u8 ac_info;
+} __attribute__ ((packed));
+
+struct ieee80211_qos_ac_parameter {
+	u8 aci_aifsn;
+	u8 ecw_min_max;
+	__le16 tx_op_limit;
+} __attribute__ ((packed));
+
+struct ieee80211_qos_parameter_info {
+	struct ieee80211_qos_information_element info_element;
+	u8 reserved;
+	struct ieee80211_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct ieee80211_qos_parameters {
+	__le16 cw_min[QOS_QUEUE_NUM];
+	__le16 cw_max[QOS_QUEUE_NUM];
+	u8 aifs[QOS_QUEUE_NUM];
+	u8 flag[QOS_QUEUE_NUM];
+	__le16 tx_op_limit[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct ieee80211_qos_data {
+	struct ieee80211_qos_parameters parameters;
+	int active;
+	int supported;
+	u8 param_count;
+	u8 old_param_count;
+};
+
+struct ieee80211_tim_parameters {
+	u8 tim_count;
+	u8 tim_period;
+} __attribute__ ((packed));
+
+//#else
+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 ((u32)type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
+}
+//added by amy for reorder
+static inline u8 Frame_QoSTID(u8* buf)
+{
+	struct ieee80211_hdr_3addr *hdr;
+	u16 fc;
+	hdr = (struct ieee80211_hdr_3addr *)buf;
+	fc = le16_to_cpu(hdr->frame_ctl);
+	return (u8)((frameqos*)(buf + (((fc & IEEE80211_FCTL_TODS)&&(fc & IEEE80211_FCTL_FROMDS))? 30 : 24)))->field.tid;
+}
+
+//added by amy for reorder
+
+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;
+	unsigned char CurrentShowTxate;
+	unsigned char last_packet_rate;
+	unsigned int txretrycount;
+};
+
+#define BEACON_PROBE_SSID_ID_POSITION 12
+
+struct ieee80211_info_element_hdr {
+	u8 id;
+	u8 len;
+} __attribute__ ((packed));
+
+/*
+ * 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 2 //1Mbps
+
+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 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
+
+//added by David for QoS 2006/6/30
+//#define WMM_Hang_8187
+#ifdef WMM_Hang_8187
+#undef WMM_Hang_8187
+#endif
+
+#define WME_AC_BK   0x00
+#define WME_AC_BE   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
+
+#define MAX_RECEIVE_BUFFER_SIZE 9100
+
+//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 */
+#define ETHERNET_HEADER_SIZE    14      /* length of two Ethernet address plus ether type*/
+
+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
+
+typedef struct _bss_ht{
+
+	bool				support_ht;
+
+	// HT related elements
+	u8					ht_cap_buf[32];
+	u16					ht_cap_len;
+	u8					ht_info_buf[32];
+	u16					ht_info_len;
+
+	HT_SPEC_VER			ht_spec_ver;
+	//HT_CAPABILITY_ELE			bdHTCapEle;
+	//HT_INFORMATION_ELE		bdHTInfoEle;
+
+	bool				aggregation;
+	bool				long_slot_time;
+}bss_ht, *pbss_ht;
+
+typedef enum _erp_t{
+	ERP_NonERPpresent	= 0x01,
+	ERP_UseProtection	= 0x02,
+	ERP_BarkerPreambleMode = 0x04,
+} erp_t;
+
+
+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;
+	struct ieee80211_qos_data qos_data;
+	//added by amy for LEAP
+	bool	bWithAironetIE;
+	bool	bCkipSupported;
+	bool	bCcxRmEnable;
+	u16 	CcxRmState[2];
+	// CCXv4 S59, MBSSID.
+	bool	bMBssidValid;
+	u8	MBssidMask;
+	u8	MBssid[6];
+	// CCX 2 S38, WLAN Device Version Number element. Annie, 2006-08-20.
+	bool	bWithCcxVerNum;
+	u8	BssCcxVerNumber;
+	/* 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;
+	u32 flags;
+	u32 last_associate;
+	u32 time_stamp[2];
+	u16 beacon_interval;
+	u16 listen_interval;
+	u16 atim_window;
+	u8  erp_value;
+	u8  wpa_ie[MAX_WPA_IE_LEN];
+	size_t wpa_ie_len;
+	u8  rsn_ie[MAX_WPA_IE_LEN];
+	size_t rsn_ie_len;
+
+	struct ieee80211_tim_parameters tim;
+	u8  dtim_period;
+	u8  dtim_data;
+	u32 last_dtim_sta_time[2];
+
+	//appeded for QoS
+	u8 wmm_info;
+	struct ieee80211_wmm_ac_param wmm_param[4];
+	u8 QoS_Enable;
+#ifdef THOMAS_TURBO
+	u8 Turbo_Enable;//enable turbo mode, added by thomas
+#endif
+#ifdef ENABLE_DOT11D
+	u16 CountryIeLen;
+	u8 CountryIeBuf[MAX_IE_LEN];
+#endif
+	// HT Related, by amy, 2008.04.29
+	BSS_HT	bssht;
+	// Add to handle broadcom AP management frame CCK rate.
+	bool broadcom_cap_exist;
+	bool ralink_cap_exist;
+	bool atheros_cap_exist;
+	bool cisco_cap_exist;
+	bool unknown_cap_exist;
+//	u8	berp_info;
+	bool	berp_info_valid;
+	bool buseprotection;
+	//put at the end of the structure.
+	struct list_head list;
+};
+
+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 authentcated
+	 * 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)
+#define CFG_IEEE80211_RTS (1<<2)
+
+#define IEEE80211_24GHZ_MIN_CHANNEL 1
+#define IEEE80211_24GHZ_MAX_CHANNEL 14
+#define IEEE80211_24GHZ_CHANNELS (IEEE80211_24GHZ_MAX_CHANNEL - \
+				  IEEE80211_24GHZ_MIN_CHANNEL + 1)
+
+#define IEEE80211_52GHZ_MIN_CHANNEL 34
+#define IEEE80211_52GHZ_MAX_CHANNEL 165
+#define IEEE80211_52GHZ_CHANNELS (IEEE80211_52GHZ_MAX_CHANNEL - \
+				  IEEE80211_52GHZ_MIN_CHANNEL + 1)
+
+
+
+typedef struct tx_pending_t{
+	int frag;
+	struct ieee80211_txb *txb;
+}tx_pending_t;
+
+typedef struct _bandwidth_autoswitch
+{
+	long threshold_20Mhzto40Mhz;
+	long	threshold_40Mhzto20Mhz;
+	bool bforced_tx20Mhz;
+	bool bautoswitch_enable;
+}bandwidth_autoswitch,*pbandwidth_autoswitch;
+
+
+//added by amy for order
+
+#define REORDER_WIN_SIZE	128
+#define REORDER_ENTRY_NUM	128
+typedef struct _RX_REORDER_ENTRY
+{
+	struct list_head	List;
+	u16			SeqNum;
+	struct ieee80211_rxb* prxb;
+} RX_REORDER_ENTRY, *PRX_REORDER_ENTRY;
+//added by amy for order
+typedef enum _Fsync_State{
+	Default_Fsync,
+	HW_Fsync,
+	SW_Fsync
+}Fsync_State;
+
+// Power save mode configured.
+typedef	enum _RT_PS_MODE
+{
+	eActive,	// Active/Continuous access.
+	eMaxPs,		// Max power save mode.
+	eFastPs		// Fast power save mode.
+}RT_PS_MODE;
+
+typedef enum _IPS_CALLBACK_FUNCION
+{
+	IPS_CALLBACK_NONE = 0,
+	IPS_CALLBACK_MGNT_LINK_REQUEST = 1,
+	IPS_CALLBACK_JOIN_REQUEST = 2,
+}IPS_CALLBACK_FUNCION;
+
+typedef enum _RT_JOIN_ACTION{
+	RT_JOIN_INFRA   = 1,
+	RT_JOIN_IBSS  = 2,
+	RT_START_IBSS = 3,
+	RT_NO_ACTION  = 4,
+}RT_JOIN_ACTION;
+
+typedef struct _IbssParms{
+	u16   atimWin;
+}IbssParms, *PIbssParms;
+#define MAX_NUM_RATES	264 // Max num of support rates element: 8,  Max num of ext. support rate: 255. 061122, by rcnjko.
+
+// RF state.
+typedef	enum _RT_RF_POWER_STATE
+{
+	eRfOn,
+	eRfSleep,
+	eRfOff
+}RT_RF_POWER_STATE;
+
+typedef struct _RT_POWER_SAVE_CONTROL
+{
+
+	//
+	// Inactive Power Save(IPS) : Disable RF when disconnected
+	//
+	bool				bInactivePs;
+	bool				bIPSModeBackup;
+	bool				bSwRfProcessing;
+	RT_RF_POWER_STATE	eInactivePowerState;
+	struct work_struct 	InactivePsWorkItem;
+	struct timer_list	InactivePsTimer;
+
+	// Return point for join action
+	IPS_CALLBACK_FUNCION	ReturnPoint;
+
+	// Recored Parameters for rescheduled JoinRequest
+	bool				bTmpBssDesc;
+	RT_JOIN_ACTION		tmpJoinAction;
+	struct ieee80211_network tmpBssDesc;
+
+	// Recored Parameters for rescheduled MgntLinkRequest
+	bool				bTmpScanOnly;
+	bool				bTmpActiveScan;
+	bool				bTmpFilterHiddenAP;
+	bool				bTmpUpdateParms;
+	u8					tmpSsidBuf[33];
+	OCTET_STRING			tmpSsid2Scan;
+	bool				bTmpSsid2Scan;
+	u8					tmpNetworkType;
+	u8					tmpChannelNumber;
+	u16					tmpBcnPeriod;
+	u8					tmpDtimPeriod;
+	u16					tmpmCap;
+	OCTET_STRING			tmpSuppRateSet;
+	u8					tmpSuppRateBuf[MAX_NUM_RATES];
+	bool				bTmpSuppRate;
+	IbssParms				tmpIbpm;
+	bool				bTmpIbpm;
+
+	//
+	// Leisre Poswer Save : Disable RF if connected but traffic is not busy
+	//
+	bool				bLeisurePs;
+
+}RT_POWER_SAVE_CONTROL,*PRT_POWER_SAVE_CONTROL;
+
+typedef u32 RT_RF_CHANGE_SOURCE;
+#define RF_CHANGE_BY_SW BIT31
+#define RF_CHANGE_BY_HW BIT30
+#define RF_CHANGE_BY_PS BIT29
+#define RF_CHANGE_BY_IPS BIT28
+#define RF_CHANGE_BY_INIT	0	// Do not change the RFOff reason. Defined by Bruce, 2008-01-17.
+
+#ifdef ENABLE_DOT11D
+typedef 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,
+	COUNTRY_CODE_MIC,
+	COUNTRY_CODE_GLOBAL_DOMAIN
+}country_code_type_t;
+#endif
+
+#define RT_MAX_LD_SLOT_NUM	10
+typedef struct _RT_LINK_DETECT_T{
+
+	u32				NumRecvBcnInPeriod;
+	u32				NumRecvDataInPeriod;
+
+	u32				RxBcnNum[RT_MAX_LD_SLOT_NUM];	// number of Rx beacon / CheckForHang_period  to determine link status
+	u32				RxDataNum[RT_MAX_LD_SLOT_NUM];	// number of Rx data / CheckForHang_period  to determine link status
+	u16				SlotNum;	// number of CheckForHang period to determine link status
+	u16				SlotIndex;
+
+	u32				NumTxOkInPeriod;
+	u32				NumRxOkInPeriod;
+	bool				bBusyTraffic;
+}RT_LINK_DETECT_T, *PRT_LINK_DETECT_T;
+
+
+struct ieee80211_device {
+	struct net_device *dev;
+	struct ieee80211_security sec;
+
+	//hw security related
+//	u8 hwsec_support; //support?
+	u8 hwsec_active;  //hw security active.
+	bool is_silent_reset;
+	bool ieee_up;
+	//added by amy
+	bool bSupportRemoteWakeUp;
+	RT_PS_MODE	dot11PowerSaveMode; // Power save mode configured.
+	bool actscanning;
+	bool beinretry;
+	RT_RF_POWER_STATE		eRFPowerState;
+	RT_RF_CHANGE_SOURCE	RfOffReason;
+	bool is_set_key;
+	//11n spec related I wonder if These info structure need to be moved out of ieee80211_device
+
+	//11n HT below
+	PRT_HIGH_THROUGHPUT	pHTInfo;
+	//struct timer_list		SwBwTimer;
+//	spinlock_t chnlop_spinlock;
+	spinlock_t bw_spinlock;
+
+	spinlock_t reorder_spinlock;
+	// for HT operation rate set.  we use this one for HT data rate to seperate different descriptors
+	//the way fill this is the same as in the IE
+	u8	Regdot11HTOperationalRateSet[16];		//use RATR format
+	u8	dot11HTOperationalRateSet[16];		//use RATR format
+	u8	RegHTSuppRateSet[16];
+	u8				HTCurrentOperaRate;
+	u8				HTHighestOperaRate;
+	//wb added for rate operation mode to firmware
+	u8	bTxDisableRateFallBack;
+	u8 	bTxUseDriverAssingedRate;
+	atomic_t	atm_chnlop;
+	atomic_t	atm_swbw;
+//	u8	HTHighestOperaRate;
+//	u8 	HTCurrentOperaRate;
+
+	// 802.11e and WMM Traffic Stream Info (TX)
+	struct list_head		Tx_TS_Admit_List;
+	struct list_head		Tx_TS_Pending_List;
+	struct list_head		Tx_TS_Unused_List;
+	TX_TS_RECORD		TxTsRecord[TOTAL_TS_NUM];
+	// 802.11e and WMM Traffic Stream Info (RX)
+	struct list_head		Rx_TS_Admit_List;
+	struct list_head		Rx_TS_Pending_List;
+	struct list_head		Rx_TS_Unused_List;
+	RX_TS_RECORD		RxTsRecord[TOTAL_TS_NUM];
+//#ifdef TO_DO_LIST
+	RX_REORDER_ENTRY	RxReorderEntry[128];
+	struct list_head		RxReorder_Unused_List;
+//#endif
+	// Qos related. Added by Annie, 2005-11-01.
+//	PSTA_QOS			pStaQos;
+	u8				ForcedPriority;		// Force per-packet priority 1~7. (default: 0, not to force it.)
+
+
+	/* 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_*) */
+	struct iw_spy_data spy_data;
+
+	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 auth_mode;
+	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_encrypt_msdu;
+	int host_decrypt;
+	/* host performs multicast decryption */
+	int host_mc_decrypt;
+
+	/* host should strip IV and ICV from protected frames */
+	/* meaningful only when hardware decryption is being used */
+	int host_strip_iv_icv;
+
+	int host_open_frag;
+	int host_build_iv;
+	int ieee802_1x; /* is IEEE 802.1X used */
+
+	/* WPA data */
+	bool bHalfWirelessN24GMode;
+	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 group_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 crypt_quiesced;
+
+	int bcrx_sta_key; /* use individual keys to override default keys even
+			   * with RX of broad/multicast frames */
+
+	/* Fragmentation structures */
+	// each streaming contain a entry
+	struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN];
+	unsigned int frag_next_idx[17];
+	u16 fts; /* Fragmentation Threshold */
+#define DEFAULT_RTS_THRESHOLD 2346U
+#define MIN_RTS_THRESHOLD 1
+#define MAX_RTS_THRESHOLD 2346U
+	u16 rts; /* RTS threshold */
+
+	/* Association info */
+	u8 bssid[ETH_ALEN];
+
+	/* 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 reg_mode;
+	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;
+
+	int perfect_rssi;
+	int worst_rssi;
+
+	u16 prev_seq_ctl;       /* used to drop duplicate frames */
+
+	/* map of allowed channels. 0 is dummy */
+	// FIXME: remeber to default to a basic channel plan depending of the PHY type
+#ifdef ENABLE_DOT11D
+	void* pDot11dInfo;
+	bool bGlobalDomain;
+#else
+	int channel_map[MAX_CHANNEL_NUMBER+1];
+#endif
+	int rate;       /* current rate */
+	int basic_rate;
+	//FIXME: pleace 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;
+	int ps_period;
+	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;
+	/* set on initialization */
+	u8  qos_support;
+
+	/* 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;
+//{ added for rtl819x
+#define IEEE80211_QUEUE_LIMIT 128
+	u8 AsocRetryCount;
+	unsigned int hw_header;
+	struct sk_buff_head skb_waitQ[MAX_QUEUE_SIZE];
+	struct sk_buff_head  skb_aggQ[MAX_QUEUE_SIZE];
+	struct sk_buff_head  skb_drv_aggQ[MAX_QUEUE_SIZE];
+	u32	sta_edca_param[4];
+	bool aggregation;
+	// Enable/Disable Rx immediate BA capability.
+	bool enable_rx_imm_BA;
+	bool bibsscoordinator;
+
+	//+by amy for DM ,080515
+	//Dynamic Tx power for near/far range enable/Disable  , by amy , 2008-05-15
+	bool	bdynamic_txpower_enable;
+
+	bool bCTSToSelfEnable;
+	u8 	CTSToSelfTH;
+
+	u32 	fsync_time_interval;
+	u32	fsync_rate_bitmap;
+	u8	fsync_rssi_threshold;
+	bool	bfsync_enable;
+
+	u8	fsync_multiple_timeinterval;		// FsyncMultipleTimeInterval * FsyncTimeInterval
+	u32	fsync_firstdiff_ratethreshold;		// low threshold
+	u32	fsync_seconddiff_ratethreshold;	 // decrease threshold
+	Fsync_State			fsync_state;
+	bool		bis_any_nonbepkts;
+	//20Mhz 40Mhz AutoSwitch Threshold
+	bandwidth_autoswitch bandwidth_auto_switch;
+	//for txpower tracking
+	bool FwRWRF;
+
+	//added by amy for AP roaming
+	RT_LINK_DETECT_T	LinkDetectInfo;
+	//added by amy for ps
+	RT_POWER_SAVE_CONTROL	PowerSaveControl;
+//}
+	/* 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_procedure_wq;
+	struct delayed_work softmac_scan_wq;
+	struct delayed_work associate_retry_wq;
+	 struct delayed_work start_ibss_wq;
+	struct work_struct wx_sync_scan_wq;
+	struct workqueue_struct *wq;
+	// Qos related. Added by Annie, 2005-11-01.
+	//STA_QOS  StaQos;
+
+	//u32 STA_EDCA_PARAM[4];
+	//CHANNEL_ACCESS_SETTING ChannelAccessSetting;
+
+
+	/* 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);
+	int (*is_queue_full) (struct net_device * dev, int pri);
+
+	int (*handle_management) (struct net_device * dev,
+				  struct ieee80211_network * network, u16 type);
+	int (*is_qos_active) (struct net_device *dev, struct sk_buff *skb);
+
+	/* Softmac-generated frames (mamagement) 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 fucntion 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. I 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 swithced 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 swithcing to ad-hoc mode
+	 * or in behalf of iwlist scan when the card is associated
+	 * and root user ask for a scan.
+	 * the fucntion stop_scan should stop both the syncro and
+	 * background scanning and can sleep.
+	 * The fucntion 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,u16 tx_rate);
+	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);
+	int (*handle_beacon) (struct net_device * dev, struct ieee80211_beacon * beacon, struct ieee80211_network * network);
+	int (*handle_assoc_response) (struct net_device * dev, struct ieee80211_assoc_response_frame * resp, struct ieee80211_network * network);
+
+
+	/* check whether Tx hw resouce available */
+	short (*check_nic_enough_desc)(struct net_device *dev, int queue_index);
+	//added by wb for HT related
+//	void (*SwChnlByTimerHandler)(struct net_device *dev, int channel);
+	void (*SetBWModeHandler)(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset);
+//	void (*UpdateHalRATRTableHandler)(struct net_device* dev, u8* pMcsRate);
+	bool (*GetNmodeSupportBySecCfg)(struct net_device* dev);
+	void (*SetWirelessMode)(struct net_device* dev, u8 wireless_mode);
+	bool (*GetHalfNmodeSupportByAPsHandler)(struct net_device* dev);
+	void (*InitialGainHandler)(struct net_device *dev, u8 Operation);
+
+	/* 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_N_24G 		  (1<<4)
+#define	IEEE_N_5G		  (1<<5)
+#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 respones 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;
+}
+
+extern 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;
+}
+
+extern 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;
+}
+
+extern inline int ieee80211_get_hdrlen(u16 fc)
+{
+	int hdrlen = IEEE80211_3ADDR_LEN;
+
+	switch (WLAN_FC_GET_TYPE(fc)) {
+	case IEEE80211_FTYPE_DATA:
+		if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
+			hdrlen = IEEE80211_4ADDR_LEN; /* 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 = IEEE80211_1ADDR_LEN;
+			break;
+		default:
+			hdrlen = IEEE80211_2ADDR_LEN;
+			break;
+		}
+		break;
+	}
+
+	return hdrlen;
+}
+
+static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr)
+{
+	switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) {
+	case IEEE80211_1ADDR_LEN:
+		return ((struct ieee80211_hdr_1addr *)hdr)->payload;
+	case IEEE80211_2ADDR_LEN:
+		return ((struct ieee80211_hdr_2addr *)hdr)->payload;
+	case IEEE80211_3ADDR_LEN:
+		return ((struct ieee80211_hdr_3addr *)hdr)->payload;
+	case IEEE80211_4ADDR_LEN:
+		return ((struct ieee80211_hdr_4addr *)hdr)->payload;
+	}
+	return NULL;
+}
+
+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_is_cck_rate(u8 rate)
+{
+	switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
+	case IEEE80211_CCK_RATE_1MB:
+	case IEEE80211_CCK_RATE_2MB:
+	case IEEE80211_CCK_RATE_5MB:
+	case IEEE80211_CCK_RATE_11MB:
+		return 1;
+	}
+	return 0;
+}
+
+
+/* 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_xmit(struct sk_buff *skb,
+			  struct net_device *dev);
+extern void ieee80211_txb_free(struct ieee80211_txb *);
+
+
+/* ieee80211_rx.c */
+extern int ieee80211_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);
+#if WIRELESS_EXT >= 18
+extern int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee,
+			    struct iw_request_info *info,
+			    union iwreq_data* wrqu, char *extra);
+extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
+			    struct iw_request_info *info,
+			    union iwreq_data* wrqu, char *extra);
+extern int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
+			       struct iw_request_info *info,
+			       struct iw_param *data, char *extra);
+extern int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra);
+#endif
+extern int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len);
+
+/* ieee80211_softmac.c */
+extern short ieee80211_is_54g(struct ieee80211_network net);
+extern short ieee80211_is_shortslot(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);
+
+void SendDisassociation(struct ieee80211_device *ieee, u8* asSta, u8 asRsn);
+extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee);
+
+extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
+extern void notify_wx_assoc_event(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_wake_queue(struct ieee80211_device *ieee);
+extern void ieee80211_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 softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee);
+
+/* 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 ieee80211_device *ieee);
+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 int ieee80211_wx_set_rts(struct ieee80211_device *ieee,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra);
+
+extern int ieee80211_wx_get_rts(struct ieee80211_device *ieee,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra);
+//HT
+#define MAX_RECEIVE_BUFFER_SIZE 9100  //
+extern void HTDebugHTCapability(u8* CapIE, u8* TitleString );
+extern void HTDebugHTInfo(u8*  InfoIE, u8* TitleString);
+
+void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET    Offset);
+extern void HTUpdateDefaultSetting(struct ieee80211_device* ieee);
+extern void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u8* len, u8 isEncrypt);
+extern void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* len, u8 isEncrypt);
+extern void HTConstructRT2RTAggElement(struct ieee80211_device* ieee, u8* posRT2RTAgg, u8* len);
+extern void HTOnAssocRsp(struct ieee80211_device *ieee);
+extern void HTInitializeHTInfo(struct ieee80211_device* ieee);
+extern void HTInitializeBssDesc(PBSS_HT pBssHT);
+extern void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork);
+extern void HTUpdateSelfAndPeerSetting(struct ieee80211_device* ieee,   struct ieee80211_network * pNetwork);
+extern u8 HTGetHighestMCSRate(struct ieee80211_device* ieee, u8* pMCSRateSet, u8* pMCSFilter);
+extern u8 MCS_FILTER_ALL[];
+extern u16 MCS_DATA_RATE[2][2][77] ;
+extern u8 HTCCheck(struct ieee80211_device* ieee, u8*   pFrame);
+//extern void HTSetConnectBwModeCallback(unsigned long data);
+extern void HTResetIOTSetting(PRT_HIGH_THROUGHPUT  pHTInfo);
+extern bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee);
+extern u16 HTHalfMcsToDataRate(struct ieee80211_device* ieee,  u8      nMcsRate);
+extern u16 HTMcsToDataRate( struct ieee80211_device* ieee, u8 nMcsRate);
+extern u16  TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate);
+//function in BAPROC.c
+extern int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb);
+extern int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb);
+extern int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb);
+extern void TsInitAddBA( struct ieee80211_device* ieee, PTX_TS_RECORD   pTS, u8 Policy, u8 bOverwritePending);
+extern void TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect);
+extern void BaSetupTimeOut(unsigned long data);
+extern void TxBaInactTimeout(unsigned long data);
+extern void RxBaInactTimeout(unsigned long data);
+extern void ResetBaEntry( PBA_RECORD pBA);
+//function in TS.c
+extern bool GetTs(
+	struct ieee80211_device*        ieee,
+	PTS_COMMON_INFO                 *ppTS,
+	u8*                             Addr,
+	u8                              TID,
+	TR_SELECT                       TxRxSelect,  //Rx:1, Tx:0
+	bool                            bAddNewTs
+	);
+extern void TSInitialize(struct ieee80211_device *ieee);
+extern  void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD   pTxTS);
+extern void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr);
+extern void RemoveAllTS(struct ieee80211_device* ieee);
+void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee);
+
+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;
+}
+
+/* For the function is more related to hardware setting, it's better to use the
+ * ieee handler to refer to it.
+ */
+extern short check_nic_enough_desc(struct net_device *dev, int queue_index);
+extern int ieee80211_data_xmit(struct sk_buff *skb, struct net_device *dev);
+extern int ieee80211_parse_info_param(struct ieee80211_device *ieee,
+		struct ieee80211_info_element *info_element,
+		u16 length,
+		struct ieee80211_network *network,
+		struct ieee80211_rx_stats *stats);
+
+void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8  index);
+#define RT_ASOC_RETRY_LIMIT	5
+#endif /* IEEE80211_H */
diff --git a/drivers/staging/rtl8192u/ieee80211/EndianFree.h b/drivers/staging/rtl8192u/ieee80211/EndianFree.h
new file mode 100644
index 0000000..dc85fb9
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/EndianFree.h
@@ -0,0 +1,194 @@
+#ifndef __INC_ENDIANFREE_H
+#define __INC_ENDIANFREE_H
+
+/*
+ *	Call endian free function when
+ *		1. Read/write packet content.
+ *		2. Before write integer to IO.
+ *		3. After read integer from IO.
+ */
+
+#define __MACHINE_LITTLE_ENDIAN 1234    /* LSB first: i386, vax */
+#define __MACHINE_BIG_ENDIAN    4321    /* MSB first: 68000, ibm, net, ppc */
+
+#define BYTE_ORDER __MACHINE_LITTLE_ENDIAN
+
+#if BYTE_ORDER == __MACHINE_LITTLE_ENDIAN
+// Convert data
+#define EF1Byte(_val)				((u8)(_val))
+#define EF2Byte(_val)				((u16)(_val))
+#define EF4Byte(_val)				((u32)(_val))
+
+#else
+// Convert data
+#define EF1Byte(_val)				((u8)(_val))
+#define EF2Byte(_val)				(((((u16)(_val))&0x00ff)<<8)|((((u16)(_val))&0xff00)>>8))
+#define EF4Byte(_val)				(((((u32)(_val))&0x000000ff)<<24)|\
+						((((u32)(_val))&0x0000ff00)<<8)|\
+						((((u32)(_val))&0x00ff0000)>>8)|\
+						((((u32)(_val))&0xff000000)>>24))
+#endif
+
+// Read data from memory
+#define ReadEF1Byte(_ptr)		EF1Byte(*((u8 *)(_ptr)))
+#define ReadEF2Byte(_ptr)		EF2Byte(*((u16 *)(_ptr)))
+#define ReadEF4Byte(_ptr)		EF4Byte(*((u32 *)(_ptr)))
+
+// Write data to memory
+#define WriteEF1Byte(_ptr, _val)	(*((u8 *)(_ptr)))=EF1Byte(_val)
+#define WriteEF2Byte(_ptr, _val)	(*((u16 *)(_ptr)))=EF2Byte(_val)
+#define WriteEF4Byte(_ptr, _val)	(*((u32 *)(_ptr)))=EF4Byte(_val)
+// Convert Host system specific byte ording (litten or big endia) to Network byte ording (big endian).
+// 2006.05.07, by rcnjko.
+#if BYTE_ORDER == __MACHINE_LITTLE_ENDIAN
+#define H2N1BYTE(_val)	((u8)(_val))
+#define H2N2BYTE(_val)	(((((u16)(_val))&0x00ff)<<8)|\
+			((((u16)(_val))&0xff00)>>8))
+#define H2N4BYTE(_val)	(((((u32)(_val))&0x000000ff)<<24)|\
+			((((u32)(_val))&0x0000ff00)<<8)	|\
+			((((u32)(_val))&0x00ff0000)>>8)	|\
+			((((u32)(_val))&0xff000000)>>24))
+#else
+#define H2N1BYTE(_val)			((u8)(_val))
+#define H2N2BYTE(_val)			((u16)(_val))
+#define H2N4BYTE(_val)			((u32)(_val))
+#endif
+
+// Convert from Network byte ording (big endian) to Host system specific byte ording (litten or big endia).
+// 2006.05.07, by rcnjko.
+#if BYTE_ORDER == __MACHINE_LITTLE_ENDIAN
+#define N2H1BYTE(_val)	((u8)(_val))
+#define N2H2BYTE(_val)	(((((u16)(_val))&0x00ff)<<8)|\
+			((((u16)(_val))&0xff00)>>8))
+#define N2H4BYTE(_val)	(((((u32)(_val))&0x000000ff)<<24)|\
+			((((u32)(_val))&0x0000ff00)<<8)	|\
+			((((u32)(_val))&0x00ff0000)>>8)	|\
+			((((u32)(_val))&0xff000000)>>24))
+#else
+#define N2H1BYTE(_val)			((u8)(_val))
+#define N2H2BYTE(_val)			((u16)(_val))
+#define N2H4BYTE(_val)			((u32)(_val))
+#endif
+
+//
+//	Example:
+//		BIT_LEN_MASK_32(0) => 0x00000000
+//		BIT_LEN_MASK_32(1) => 0x00000001
+//		BIT_LEN_MASK_32(2) => 0x00000003
+//		BIT_LEN_MASK_32(32) => 0xFFFFFFFF
+//
+#define BIT_LEN_MASK_32(__BitLen) (0xFFFFFFFF >> (32 - (__BitLen)))
+//
+//	Example:
+//		BIT_OFFSET_LEN_MASK_32(0, 2) => 0x00000003
+//		BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000
+//
+#define BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen) (BIT_LEN_MASK_32(__BitLen) << (__BitOffset))
+
+//
+//	Description:
+//		Return 4-byte value in host byte ordering from
+//		4-byte pointer in litten-endian system.
+//
+#define LE_P4BYTE_TO_HOST_4BYTE(__pStart) (EF4Byte(*((u32 *)(__pStart))))
+
+//
+//	Description:
+//		Translate subfield (continuous bits in little-endian) of 4-byte value in litten byte to
+//		4-byte value in host byte ordering.
+//
+#define LE_BITS_TO_4BYTE(__pStart, __BitOffset, __BitLen) \
+	( \
+	  ( LE_P4BYTE_TO_HOST_4BYTE(__pStart) >> (__BitOffset) ) \
+	  & \
+	  BIT_LEN_MASK_32(__BitLen) \
+	)
+
+//
+//	Description:
+//		Mask subfield (continuous bits in little-endian) of 4-byte value in litten byte oredering
+//		and return the result in 4-byte value in host byte ordering.
+//
+#define LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \
+	( \
+	  LE_P4BYTE_TO_HOST_4BYTE(__pStart) \
+	  & \
+	  ( ~BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen) ) \
+	)
+
+//
+//	Description:
+//		Set subfield of little-endian 4-byte value to specified value.
+//
+#define SET_BITS_TO_LE_4BYTE(__pStart, __BitOffset, __BitLen, __Value) \
+	*((u32 *)(__pStart)) = \
+	EF4Byte( \
+	LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \
+	| \
+	( (((u32)__Value) & BIT_LEN_MASK_32(__BitLen)) << (__BitOffset) ) \
+       );
+
+
+#define BIT_LEN_MASK_16(__BitLen) \
+	(0xFFFF >> (16 - (__BitLen)))
+
+#define BIT_OFFSET_LEN_MASK_16(__BitOffset, __BitLen) \
+	(BIT_LEN_MASK_16(__BitLen) << (__BitOffset))
+
+#define LE_P2BYTE_TO_HOST_2BYTE(__pStart) \
+	(EF2Byte(*((u16 *)(__pStart))))
+
+#define LE_BITS_TO_2BYTE(__pStart, __BitOffset, __BitLen) \
+	( \
+	  ( LE_P2BYTE_TO_HOST_2BYTE(__pStart) >> (__BitOffset) ) \
+	  & \
+	  BIT_LEN_MASK_16(__BitLen) \
+	)
+
+#define LE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \
+	( \
+	  LE_P2BYTE_TO_HOST_2BYTE(__pStart) \
+	  & \
+	  ( ~BIT_OFFSET_LEN_MASK_16(__BitOffset, __BitLen) ) \
+	)
+
+#define SET_BITS_TO_LE_2BYTE(__pStart, __BitOffset, __BitLen, __Value) \
+	*((u16 *)(__pStart)) = \
+	EF2Byte( \
+		LE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \
+		| \
+		( (((u16)__Value) & BIT_LEN_MASK_16(__BitLen)) << (__BitOffset) ) \
+       );
+
+#define BIT_LEN_MASK_8(__BitLen) \
+	(0xFF >> (8 - (__BitLen)))
+
+#define BIT_OFFSET_LEN_MASK_8(__BitOffset, __BitLen) \
+	(BIT_LEN_MASK_8(__BitLen) << (__BitOffset))
+
+#define LE_P1BYTE_TO_HOST_1BYTE(__pStart) \
+	(EF1Byte(*((u8 *)(__pStart))))
+
+#define LE_BITS_TO_1BYTE(__pStart, __BitOffset, __BitLen) \
+	( \
+	  ( LE_P1BYTE_TO_HOST_1BYTE(__pStart) >> (__BitOffset) ) \
+	  & \
+	  BIT_LEN_MASK_8(__BitLen) \
+	)
+
+#define LE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \
+	( \
+	  LE_P1BYTE_TO_HOST_1BYTE(__pStart) \
+	  & \
+	  ( ~BIT_OFFSET_LEN_MASK_8(__BitOffset, __BitLen) ) \
+	)
+
+#define SET_BITS_TO_LE_1BYTE(__pStart, __BitOffset, __BitLen, __Value) \
+	*((u8 *)(__pStart)) = \
+	EF1Byte( \
+		LE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \
+		| \
+		( (((u8)__Value) & BIT_LEN_MASK_8(__BitLen)) << (__BitOffset) ) \
+       );
+
+#endif // #ifndef __INC_ENDIANFREE_H
diff --git a/drivers/staging/rtl8192u/ieee80211/Makefile b/drivers/staging/rtl8192u/ieee80211/Makefile
new file mode 100644
index 0000000..71ca5d9
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/Makefile
@@ -0,0 +1,139 @@
+NIC_SELECT = RTL8192U
+
+KVER  := $(shell uname -r)
+MODDESTDIR := /lib/modules/$(KVER)/kernel/drivers/net/wireless/$(NIC_SELECT)
+
+CC = gcc
+ifneq ($(shell uname -r|cut -d. -f1,2), 2.4)
+EXTRA_CFLAGS += -I$(TOPDIR)/drivers/net/wireless
+EXTRA_CFLAGS += -O2
+EXTRA_CFLAGS += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX
+
+#it will fail to compile in suse linux enterprise 10 sp2. This flag is to solve this problem.
+ifeq ($(shell uname -r | cut -d. -f1,2,3,4), 2.6.16.60-0)
+EXTRA_CFLAGS += -DOPENSUSE_SLED
+endif
+
+ifeq ($(NIC_SELECT),RTL8192U)
+#EXTRA_CFLAGS += -DUSB_TX_DRIVER_AGGREGATION_ENABLE
+#EXTRA_CFLAGS += -DUSB_RX_AGGREGATION_SUPPORT
+endif
+#EXTRA_CFLAGS += -DJOHN_NOCPY
+#flags to enable or disble 80211D feature
+EXTRA_CFLAGS += -DENABLE_DOT11D
+ieee80211-rsl-objs := ieee80211_rx.o \
+		      ieee80211_softmac.o \
+		      ieee80211_tx.o \
+		      ieee80211_wx.o \
+		      ieee80211_module.o \
+		      ieee80211_softmac_wx.o\
+		      rtl819x_HTProc.o\
+		      rtl819x_TSProc.o\
+		      rtl819x_BAProc.o\
+		      dot11d.o
+
+ieee80211_crypt-rsl-objs := ieee80211_crypt.o
+ieee80211_crypt_tkip-rsl-objs := ieee80211_crypt_tkip.o
+ieee80211_crypt_ccmp-rsl-objs := ieee80211_crypt_ccmp.o
+ieee80211_crypt_wep-rsl-objs := ieee80211_crypt_wep.o
+
+obj-m +=ieee80211-rsl.o
+obj-m +=ieee80211_crypt-rsl.o
+obj-m +=ieee80211_crypt_wep-rsl.o
+obj-m +=ieee80211_crypt_tkip-rsl.o
+obj-m +=ieee80211_crypt_ccmp-rsl.o
+
+KSRC := /lib/modules/$(KVER)/build
+INSTALL_PREFIX :=
+
+all: modules
+
+modules:
+	$(MAKE) -C $(KSRC) M=$(PWD) CC=$(CC) modules
+
+install: modules
+	rm -fr $(MODDESTDIR)
+	mkdir -p $(MODDESTDIR)
+	@install -p -m 644 ieee80211_crypt-rsl.ko $(MODDESTDIR)
+	@install -p -m 644 ieee80211_crypt_wep-rsl.ko $(MODDESTDIR)
+	@install -p -m 644 ieee80211_crypt_tkip-rsl.ko $(MODDESTDIR)
+	@install -p -m 644 ieee80211_crypt_ccmp-rsl.ko $(MODDESTDIR)
+	@install -p -m 644 ieee80211-rsl.ko $(MODDESTDIR)
+	depmod -a
+uninstall:
+	rm -fr $(MODDESTDIR)
+	depmod -a
+
+else
+LD := ld
+KSRC := /lib/modules/$(KVER)/build
+CONFIG_FILE := $(KSRC)/include/linux/autoconf.h
+
+CFLAGS += -DLINUX -D__KERNEL__ -DMODULE -O2 -pipe -Wall
+CFLAGS += -I$(KSRC)/include -I.
+#Kernel 2.4.31
+CFLAGS += -DMODVERSIONS -DEXPORT_SYMTAB -include $(KSRC)/include/linux/modversions.h
+#Kernel 2.4.20
+#CFLAGS += -D__NO_VERSION__ -DEXPORT_SYMTAB
+#CFLAGS += -DENABLE_DOT11D
+SMP := $(shell $(CC) $(MODCFLAGS) -E -dM $(CONFIG_FILE) | \
+   grep CONFIG_SMP | awk '{print $$3}')
+ifneq ($(SMP),1)
+   SMP := 0
+endif
+ifeq ($(SMP),1)
+   CFLAGS    += -D__SMP__
+endif
+
+#CFLAGS += -DJOHN_NOCPY
+
+OBJS := ${patsubst %.c, %.o, ${wildcard *.c}}
+all:${OBJS} ieee80211_crypt-rsl.o michael_mic-rsl.o aes-rsl.o ieee80211_crypt_wep-rsl.o ieee80211_crypt_tkip-rsl.o ieee80211_crypt_ccmp-rsl.o crypto-rsl.o ieee80211-rsl.o
+
+ieee80211_crypt-rsl.o: ieee80211_crypt.o
+	mv $^ $@
+
+michael_mic-rsl.o: michael_mic.o
+	mv $^ $@
+
+aes-rsl.o: aes.o
+	mv $^ $@
+
+ieee80211_crypt_wep-rsl.o: ieee80211_crypt_wep.o
+	mv $^ $@
+
+ieee80211_crypt_tkip-rsl.o: ieee80211_crypt_tkip.o
+	mv $^ $@
+
+ieee80211_crypt_ccmp-rsl.o: ieee80211_crypt_ccmp.o
+	mv $^ $@
+
+crypto-rsl.o: arc4.o api.o autoload.o cipher.o compress.o digest.o scatterwalk.o proc.o
+	$(LD) -r $^ -o $@
+
+ieee80211-rsl.o: ieee80211_rx.o ieee80211_tx.o ieee80211_wx.o ieee80211_module.o ieee80211_softmac_wx.o ieee80211_softmac.o rtl819x_HTProc.o rtl819x_TSProc.o rtl819x_BAProc.o dot11d.o
+	$(LD) -r $^ -o $@
+install:
+	rm -fr $(MODDESTDIR)
+	mkdir -p $(MODDESTDIR)
+	@install -p -m 644 ieee80211_crypt-rsl.o $(MODDESTDIR)
+	@install -p -m 644 crypto-rsl.o $(MODDESTDIR)
+	@install -p -m 644 michael_mic-rsl.o $(MODDESTDIR)
+	@install -p -m 644 aes-rsl.o $(MODDESTDIR)
+	@install -p -m 644 ieee80211_crypt_wep-rsl.o $(MODDESTDIR)
+	@install -p -m 644 ieee80211_crypt_tkip-rsl.o $(MODDESTDIR)
+	@install -p -m 644 ieee80211_crypt_ccmp-rsl.o $(MODDESTDIR)
+	@install -p -m 644 ieee80211-rsl.o $(MODDESTDIR)
+	/sbin/depmod -a ${shell uname -r}
+
+uninstall:
+	rm -fr $(MODDESTDIR)
+	/sbin/depmod -a ${shell uname -r}
+
+endif
+
+.PHONY: clean
+clean:
+	rm -fr *.mod.c *.mod *.o .*.cmd *.mod.* *.ko *.o *~
+	rm -rf .tmp_versions
+	rm -rf Module.symvers
diff --git a/drivers/staging/rtl8192u/ieee80211/aes.c b/drivers/staging/rtl8192u/ieee80211/aes.c
new file mode 100644
index 0000000..a6bb6c9
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/aes.c
@@ -0,0 +1,469 @@
+/*
+ * Cryptographic API.
+ *
+ * AES Cipher Algorithm.
+ *
+ * Based on Brian Gladman's code.
+ *
+ * Linux developers:
+ *  Alexander Kjeldaas <astor@fast.no>
+ *  Herbert Valerio Riedel <hvr@hvrlab.org>
+ *  Kyle McMartin <kyle@debian.org>
+ *  Adam J. Richter <adam@yggdrasil.com> (conversion to 2.5 API).
+ *
+ * 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.
+ *
+ * ---------------------------------------------------------------------------
+ * Copyright (c) 2002, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
+ * All rights reserved.
+ *
+ * LICENSE TERMS
+ *
+ * The free distribution and use of this software in both source and binary
+ * form is allowed (with or without changes) provided that:
+ *
+ *   1. distributions of this source code include the above copyright
+ *      notice, this list of conditions and the following disclaimer;
+ *
+ *   2. distributions in binary form include the above copyright
+ *      notice, this list of conditions and the following disclaimer
+ *      in the documentation and/or other associated materials;
+ *
+ *   3. the copyright holder's name is not used to endorse products
+ *      built using this software without specific written permission.
+ *
+ * ALTERNATIVELY, provided that this notice is retained in full, this product
+ * may be distributed under the terms of the GNU General Public License (GPL),
+ * in which case the provisions of the GPL apply INSTEAD OF those given above.
+ *
+ * DISCLAIMER
+ *
+ * This software is provided 'as is' with no explicit or implied warranties
+ * in respect of its properties, including, but not limited to, correctness
+ * and/or fitness for purpose.
+ * ---------------------------------------------------------------------------
+ */
+
+/* Some changes from the Gladman version:
+    s/RIJNDAEL(e_key)/E_KEY/g
+    s/RIJNDAEL(d_key)/D_KEY/g
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+//#include <linux/crypto.h>
+#include "rtl_crypto.h"
+#include <asm/byteorder.h>
+
+#define AES_MIN_KEY_SIZE	16
+#define AES_MAX_KEY_SIZE	32
+
+#define AES_BLOCK_SIZE		16
+
+static inline
+u32 generic_rotr32 (const u32 x, const unsigned bits)
+{
+	const unsigned n = bits % 32;
+	return (x >> n) | (x << (32 - n));
+}
+
+static inline
+u32 generic_rotl32 (const u32 x, const unsigned bits)
+{
+	const unsigned n = bits % 32;
+	return (x << n) | (x >> (32 - n));
+}
+
+#define rotl generic_rotl32
+#define rotr generic_rotr32
+
+/*
+ * #define byte(x, nr) ((unsigned char)((x) >> (nr*8)))
+ */
+inline static u8
+byte(const u32 x, const unsigned n)
+{
+	return x >> (n << 3);
+}
+
+#define u32_in(x) le32_to_cpu(*(const u32 *)(x))
+#define u32_out(to, from) (*(u32 *)(to) = cpu_to_le32(from))
+
+struct aes_ctx {
+	int key_length;
+	u32 E[60];
+	u32 D[60];
+};
+
+#define E_KEY ctx->E
+#define D_KEY ctx->D
+
+static u8 pow_tab[256] __initdata;
+static u8 log_tab[256] __initdata;
+static u8 sbx_tab[256] __initdata;
+static u8 isb_tab[256] __initdata;
+static u32 rco_tab[10];
+static u32 ft_tab[4][256];
+static u32 it_tab[4][256];
+
+static u32 fl_tab[4][256];
+static u32 il_tab[4][256];
+
+static inline u8 __init
+f_mult (u8 a, u8 b)
+{
+	u8 aa = log_tab[a], cc = aa + log_tab[b];
+
+	return pow_tab[cc + (cc < aa ? 1 : 0)];
+}
+
+#define ff_mult(a,b)    (a && b ? f_mult(a, b) : 0)
+
+#define f_rn(bo, bi, n, k)					\
+    bo[n] =  ft_tab[0][byte(bi[n],0)] ^				\
+	     ft_tab[1][byte(bi[(n + 1) & 3],1)] ^		\
+	     ft_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
+	     ft_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
+
+#define i_rn(bo, bi, n, k)					\
+    bo[n] =  it_tab[0][byte(bi[n],0)] ^				\
+	     it_tab[1][byte(bi[(n + 3) & 3],1)] ^		\
+	     it_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
+	     it_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
+
+#define ls_box(x)				\
+    ( fl_tab[0][byte(x, 0)] ^			\
+      fl_tab[1][byte(x, 1)] ^			\
+      fl_tab[2][byte(x, 2)] ^			\
+      fl_tab[3][byte(x, 3)] )
+
+#define f_rl(bo, bi, n, k)					\
+    bo[n] =  fl_tab[0][byte(bi[n],0)] ^				\
+	     fl_tab[1][byte(bi[(n + 1) & 3],1)] ^		\
+	     fl_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
+	     fl_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
+
+#define i_rl(bo, bi, n, k)					\
+    bo[n] =  il_tab[0][byte(bi[n],0)] ^				\
+	     il_tab[1][byte(bi[(n + 3) & 3],1)] ^		\
+	     il_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
+	     il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
+
+static void __init
+gen_tabs (void)
+{
+	u32 i, t;
+	u8 p, q;
+
+	/* log and power tables for GF(2**8) finite field with
+	   0x011b as modular polynomial - the simplest primitive
+	   root is 0x03, used here to generate the tables */
+
+	for (i = 0, p = 1; i < 256; ++i) {
+		pow_tab[i] = (u8) p;
+		log_tab[p] = (u8) i;
+
+		p ^= (p << 1) ^ (p & 0x80 ? 0x01b : 0);
+	}
+
+	log_tab[1] = 0;
+
+	for (i = 0, p = 1; i < 10; ++i) {
+		rco_tab[i] = p;
+
+		p = (p << 1) ^ (p & 0x80 ? 0x01b : 0);
+	}
+
+	for (i = 0; i < 256; ++i) {
+		p = (i ? pow_tab[255 - log_tab[i]] : 0);
+		q = ((p >> 7) | (p << 1)) ^ ((p >> 6) | (p << 2));
+		p ^= 0x63 ^ q ^ ((q >> 6) | (q << 2));
+		sbx_tab[i] = p;
+		isb_tab[p] = (u8) i;
+	}
+
+	for (i = 0; i < 256; ++i) {
+		p = sbx_tab[i];
+
+		t = p;
+		fl_tab[0][i] = t;
+		fl_tab[1][i] = rotl (t, 8);
+		fl_tab[2][i] = rotl (t, 16);
+		fl_tab[3][i] = rotl (t, 24);
+
+		t = ((u32) ff_mult (2, p)) |
+		    ((u32) p << 8) |
+		    ((u32) p << 16) | ((u32) ff_mult (3, p) << 24);
+
+		ft_tab[0][i] = t;
+		ft_tab[1][i] = rotl (t, 8);
+		ft_tab[2][i] = rotl (t, 16);
+		ft_tab[3][i] = rotl (t, 24);
+
+		p = isb_tab[i];
+
+		t = p;
+		il_tab[0][i] = t;
+		il_tab[1][i] = rotl (t, 8);
+		il_tab[2][i] = rotl (t, 16);
+		il_tab[3][i] = rotl (t, 24);
+
+		t = ((u32) ff_mult (14, p)) |
+		    ((u32) ff_mult (9, p) << 8) |
+		    ((u32) ff_mult (13, p) << 16) |
+		    ((u32) ff_mult (11, p) << 24);
+
+		it_tab[0][i] = t;
+		it_tab[1][i] = rotl (t, 8);
+		it_tab[2][i] = rotl (t, 16);
+		it_tab[3][i] = rotl (t, 24);
+	}
+}
+
+#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
+
+#define imix_col(y,x)       \
+    u   = star_x(x);        \
+    v   = star_x(u);        \
+    w   = star_x(v);        \
+    t   = w ^ (x);          \
+   (y)  = u ^ v ^ w;        \
+   (y) ^= rotr(u ^ t,  8) ^ \
+	  rotr(v ^ t, 16) ^ \
+	  rotr(t,24)
+
+/* initialise the key schedule from the user supplied key */
+
+#define loop4(i)                                    \
+{   t = rotr(t,  8); t = ls_box(t) ^ rco_tab[i];    \
+    t ^= E_KEY[4 * i];     E_KEY[4 * i + 4] = t;    \
+    t ^= E_KEY[4 * i + 1]; E_KEY[4 * i + 5] = t;    \
+    t ^= E_KEY[4 * i + 2]; E_KEY[4 * i + 6] = t;    \
+    t ^= E_KEY[4 * i + 3]; E_KEY[4 * i + 7] = t;    \
+}
+
+#define loop6(i)                                    \
+{   t = rotr(t,  8); t = ls_box(t) ^ rco_tab[i];    \
+    t ^= E_KEY[6 * i];     E_KEY[6 * i + 6] = t;    \
+    t ^= E_KEY[6 * i + 1]; E_KEY[6 * i + 7] = t;    \
+    t ^= E_KEY[6 * i + 2]; E_KEY[6 * i + 8] = t;    \
+    t ^= E_KEY[6 * i + 3]; E_KEY[6 * i + 9] = t;    \
+    t ^= E_KEY[6 * i + 4]; E_KEY[6 * i + 10] = t;   \
+    t ^= E_KEY[6 * i + 5]; E_KEY[6 * i + 11] = t;   \
+}
+
+#define loop8(i)                                    \
+{   t = rotr(t,  8); ; t = ls_box(t) ^ rco_tab[i];  \
+    t ^= E_KEY[8 * i];     E_KEY[8 * i + 8] = t;    \
+    t ^= E_KEY[8 * i + 1]; E_KEY[8 * i + 9] = t;    \
+    t ^= E_KEY[8 * i + 2]; E_KEY[8 * i + 10] = t;   \
+    t ^= E_KEY[8 * i + 3]; E_KEY[8 * i + 11] = t;   \
+    t  = E_KEY[8 * i + 4] ^ ls_box(t);    \
+    E_KEY[8 * i + 12] = t;                \
+    t ^= E_KEY[8 * i + 5]; E_KEY[8 * i + 13] = t;   \
+    t ^= E_KEY[8 * i + 6]; E_KEY[8 * i + 14] = t;   \
+    t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t;   \
+}
+
+static int
+aes_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags)
+{
+	struct aes_ctx *ctx = ctx_arg;
+	u32 i, t, u, v, w;
+
+	if (key_len != 16 && key_len != 24 && key_len != 32) {
+		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+		return -EINVAL;
+	}
+
+	ctx->key_length = key_len;
+
+	E_KEY[0] = u32_in (in_key);
+	E_KEY[1] = u32_in (in_key + 4);
+	E_KEY[2] = u32_in (in_key + 8);
+	E_KEY[3] = u32_in (in_key + 12);
+
+	switch (key_len) {
+	case 16:
+		t = E_KEY[3];
+		for (i = 0; i < 10; ++i)
+			loop4 (i);
+		break;
+
+	case 24:
+		E_KEY[4] = u32_in (in_key + 16);
+		t = E_KEY[5] = u32_in (in_key + 20);
+		for (i = 0; i < 8; ++i)
+			loop6 (i);
+		break;
+
+	case 32:
+		E_KEY[4] = u32_in (in_key + 16);
+		E_KEY[5] = u32_in (in_key + 20);
+		E_KEY[6] = u32_in (in_key + 24);
+		t = E_KEY[7] = u32_in (in_key + 28);
+		for (i = 0; i < 7; ++i)
+			loop8 (i);
+		break;
+	}
+
+	D_KEY[0] = E_KEY[0];
+	D_KEY[1] = E_KEY[1];
+	D_KEY[2] = E_KEY[2];
+	D_KEY[3] = E_KEY[3];
+
+	for (i = 4; i < key_len + 24; ++i) {
+		imix_col (D_KEY[i], E_KEY[i]);
+	}
+
+	return 0;
+}
+
+/* encrypt a block of text */
+
+#define f_nround(bo, bi, k) \
+    f_rn(bo, bi, 0, k);     \
+    f_rn(bo, bi, 1, k);     \
+    f_rn(bo, bi, 2, k);     \
+    f_rn(bo, bi, 3, k);     \
+    k += 4
+
+#define f_lround(bo, bi, k) \
+    f_rl(bo, bi, 0, k);     \
+    f_rl(bo, bi, 1, k);     \
+    f_rl(bo, bi, 2, k);     \
+    f_rl(bo, bi, 3, k)
+
+static void aes_encrypt(void *ctx_arg, u8 *out, const u8 *in)
+{
+	const struct aes_ctx *ctx = ctx_arg;
+	u32 b0[4], b1[4];
+	const u32 *kp = E_KEY + 4;
+
+	b0[0] = u32_in (in) ^ E_KEY[0];
+	b0[1] = u32_in (in + 4) ^ E_KEY[1];
+	b0[2] = u32_in (in + 8) ^ E_KEY[2];
+	b0[3] = u32_in (in + 12) ^ E_KEY[3];
+
+	if (ctx->key_length > 24) {
+		f_nround (b1, b0, kp);
+		f_nround (b0, b1, kp);
+	}
+
+	if (ctx->key_length > 16) {
+		f_nround (b1, b0, kp);
+		f_nround (b0, b1, kp);
+	}
+
+	f_nround (b1, b0, kp);
+	f_nround (b0, b1, kp);
+	f_nround (b1, b0, kp);
+	f_nround (b0, b1, kp);
+	f_nround (b1, b0, kp);
+	f_nround (b0, b1, kp);
+	f_nround (b1, b0, kp);
+	f_nround (b0, b1, kp);
+	f_nround (b1, b0, kp);
+	f_lround (b0, b1, kp);
+
+	u32_out (out, b0[0]);
+	u32_out (out + 4, b0[1]);
+	u32_out (out + 8, b0[2]);
+	u32_out (out + 12, b0[3]);
+}
+
+/* decrypt a block of text */
+
+#define i_nround(bo, bi, k) \
+    i_rn(bo, bi, 0, k);     \
+    i_rn(bo, bi, 1, k);     \
+    i_rn(bo, bi, 2, k);     \
+    i_rn(bo, bi, 3, k);     \
+    k -= 4
+
+#define i_lround(bo, bi, k) \
+    i_rl(bo, bi, 0, k);     \
+    i_rl(bo, bi, 1, k);     \
+    i_rl(bo, bi, 2, k);     \
+    i_rl(bo, bi, 3, k)
+
+static void aes_decrypt(void *ctx_arg, u8 *out, const u8 *in)
+{
+	const struct aes_ctx *ctx = ctx_arg;
+	u32 b0[4], b1[4];
+	const int key_len = ctx->key_length;
+	const u32 *kp = D_KEY + key_len + 20;
+
+	b0[0] = u32_in (in) ^ E_KEY[key_len + 24];
+	b0[1] = u32_in (in + 4) ^ E_KEY[key_len + 25];
+	b0[2] = u32_in (in + 8) ^ E_KEY[key_len + 26];
+	b0[3] = u32_in (in + 12) ^ E_KEY[key_len + 27];
+
+	if (key_len > 24) {
+		i_nround (b1, b0, kp);
+		i_nround (b0, b1, kp);
+	}
+
+	if (key_len > 16) {
+		i_nround (b1, b0, kp);
+		i_nround (b0, b1, kp);
+	}
+
+	i_nround (b1, b0, kp);
+	i_nround (b0, b1, kp);
+	i_nround (b1, b0, kp);
+	i_nround (b0, b1, kp);
+	i_nround (b1, b0, kp);
+	i_nround (b0, b1, kp);
+	i_nround (b1, b0, kp);
+	i_nround (b0, b1, kp);
+	i_nround (b1, b0, kp);
+	i_lround (b0, b1, kp);
+
+	u32_out (out, b0[0]);
+	u32_out (out + 4, b0[1]);
+	u32_out (out + 8, b0[2]);
+	u32_out (out + 12, b0[3]);
+}
+
+
+static struct crypto_alg aes_alg = {
+	.cra_name		=	"aes",
+	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
+	.cra_blocksize		=	AES_BLOCK_SIZE,
+	.cra_ctxsize		=	sizeof(struct aes_ctx),
+	.cra_module		=	THIS_MODULE,
+	.cra_list		=	LIST_HEAD_INIT(aes_alg.cra_list),
+	.cra_u			=	{
+		.cipher = {
+			.cia_min_keysize	=	AES_MIN_KEY_SIZE,
+			.cia_max_keysize	=	AES_MAX_KEY_SIZE,
+			.cia_setkey		= 	aes_set_key,
+			.cia_encrypt		=	aes_encrypt,
+			.cia_decrypt		=	aes_decrypt
+		}
+	}
+};
+
+static int __init aes_init(void)
+{
+	gen_tabs();
+	return crypto_register_alg(&aes_alg);
+}
+
+static void __exit aes_fini(void)
+{
+	crypto_unregister_alg(&aes_alg);
+}
+
+module_init(aes_init);
+module_exit(aes_fini);
+
+MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
+MODULE_LICENSE("Dual BSD/GPL");
+
diff --git a/drivers/staging/rtl8192u/ieee80211/api.c b/drivers/staging/rtl8192u/ieee80211/api.c
new file mode 100644
index 0000000..c627d02
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/api.c
@@ -0,0 +1,246 @@
+/*
+ * Scatterlist Cryptographic API.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2002 David S. Miller (davem@redhat.com)
+ *
+ * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
+ * and Nettle, by Niels Mé°ˆler.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#include "kmap_types.h"
+
+#include <linux/init.h>
+#include <linux/module.h>
+//#include <linux/crypto.h>
+#include "rtl_crypto.h"
+#include <linux/errno.h>
+#include <linux/rwsem.h>
+#include <linux/slab.h>
+#include "internal.h"
+
+LIST_HEAD(crypto_alg_list);
+DECLARE_RWSEM(crypto_alg_sem);
+
+static inline int crypto_alg_get(struct crypto_alg *alg)
+{
+	return try_inc_mod_count(alg->cra_module);
+}
+
+static inline void crypto_alg_put(struct crypto_alg *alg)
+{
+	if (alg->cra_module)
+		__MOD_DEC_USE_COUNT(alg->cra_module);
+}
+
+struct crypto_alg *crypto_alg_lookup(const char *name)
+{
+	struct crypto_alg *q, *alg = NULL;
+
+	if (!name)
+		return NULL;
+
+	down_read(&crypto_alg_sem);
+
+	list_for_each_entry(q, &crypto_alg_list, cra_list) {
+		if (!(strcmp(q->cra_name, name))) {
+			if (crypto_alg_get(q))
+				alg = q;
+			break;
+		}
+	}
+
+	up_read(&crypto_alg_sem);
+	return alg;
+}
+
+static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
+{
+	tfm->crt_flags = 0;
+
+	switch (crypto_tfm_alg_type(tfm)) {
+	case CRYPTO_ALG_TYPE_CIPHER:
+		return crypto_init_cipher_flags(tfm, flags);
+
+	case CRYPTO_ALG_TYPE_DIGEST:
+		return crypto_init_digest_flags(tfm, flags);
+
+	case CRYPTO_ALG_TYPE_COMPRESS:
+		return crypto_init_compress_flags(tfm, flags);
+
+	default:
+		break;
+	}
+
+	BUG();
+	return -EINVAL;
+}
+
+static int crypto_init_ops(struct crypto_tfm *tfm)
+{
+	switch (crypto_tfm_alg_type(tfm)) {
+	case CRYPTO_ALG_TYPE_CIPHER:
+		return crypto_init_cipher_ops(tfm);
+
+	case CRYPTO_ALG_TYPE_DIGEST:
+		return crypto_init_digest_ops(tfm);
+
+	case CRYPTO_ALG_TYPE_COMPRESS:
+		return crypto_init_compress_ops(tfm);
+
+	default:
+		break;
+	}
+
+	BUG();
+	return -EINVAL;
+}
+
+static void crypto_exit_ops(struct crypto_tfm *tfm)
+{
+	switch (crypto_tfm_alg_type(tfm)) {
+	case CRYPTO_ALG_TYPE_CIPHER:
+		crypto_exit_cipher_ops(tfm);
+		break;
+
+	case CRYPTO_ALG_TYPE_DIGEST:
+		crypto_exit_digest_ops(tfm);
+		break;
+
+	case CRYPTO_ALG_TYPE_COMPRESS:
+		crypto_exit_compress_ops(tfm);
+		break;
+
+	default:
+		BUG();
+
+	}
+}
+
+struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
+{
+	struct crypto_tfm *tfm = NULL;
+	struct crypto_alg *alg;
+
+	alg = crypto_alg_mod_lookup(name);
+	if (alg == NULL)
+		goto out;
+
+	tfm = kmalloc(sizeof(*tfm) + alg->cra_ctxsize, GFP_KERNEL);
+	if (tfm == NULL)
+		goto out_put;
+
+	memset(tfm, 0, sizeof(*tfm) + alg->cra_ctxsize);
+
+	tfm->__crt_alg = alg;
+
+	if (crypto_init_flags(tfm, flags))
+		goto out_free_tfm;
+
+	if (crypto_init_ops(tfm)) {
+		crypto_exit_ops(tfm);
+		goto out_free_tfm;
+	}
+
+	goto out;
+
+out_free_tfm:
+	kfree(tfm);
+	tfm = NULL;
+out_put:
+	crypto_alg_put(alg);
+out:
+	return tfm;
+}
+
+void crypto_free_tfm(struct crypto_tfm *tfm)
+{
+	struct crypto_alg *alg = tfm->__crt_alg;
+	int size = sizeof(*tfm) + alg->cra_ctxsize;
+
+	crypto_exit_ops(tfm);
+	crypto_alg_put(alg);
+	memset(tfm, 0, size);
+	kfree(tfm);
+}
+
+int crypto_register_alg(struct crypto_alg *alg)
+{
+	int ret = 0;
+	struct crypto_alg *q;
+
+	down_write(&crypto_alg_sem);
+
+	list_for_each_entry(q, &crypto_alg_list, cra_list) {
+		if (!(strcmp(q->cra_name, alg->cra_name))) {
+			ret = -EEXIST;
+			goto out;
+		}
+	}
+
+	list_add_tail(&alg->cra_list, &crypto_alg_list);
+out:
+	up_write(&crypto_alg_sem);
+	return ret;
+}
+
+int crypto_unregister_alg(struct crypto_alg *alg)
+{
+	int ret = -ENOENT;
+	struct crypto_alg *q;
+
+	BUG_ON(!alg->cra_module);
+
+	down_write(&crypto_alg_sem);
+	list_for_each_entry(q, &crypto_alg_list, cra_list) {
+		if (alg == q) {
+			list_del(&alg->cra_list);
+			ret = 0;
+			goto out;
+		}
+	}
+out:
+	up_write(&crypto_alg_sem);
+	return ret;
+}
+
+int crypto_alg_available(const char *name, u32 flags)
+{
+	int ret = 0;
+	struct crypto_alg *alg = crypto_alg_mod_lookup(name);
+
+	if (alg) {
+		crypto_alg_put(alg);
+		ret = 1;
+	}
+
+	return ret;
+}
+
+static int __init init_crypto(void)
+{
+	printk(KERN_INFO "Initializing Cryptographic API\n");
+	crypto_init_proc();
+	return 0;
+}
+
+__initcall(init_crypto);
+
+/*
+EXPORT_SYMBOL_GPL(crypto_register_alg);
+EXPORT_SYMBOL_GPL(crypto_unregister_alg);
+EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
+EXPORT_SYMBOL_GPL(crypto_free_tfm);
+EXPORT_SYMBOL_GPL(crypto_alg_available);
+*/
+
+EXPORT_SYMBOL_NOVERS(crypto_register_alg);
+EXPORT_SYMBOL_NOVERS(crypto_unregister_alg);
+EXPORT_SYMBOL_NOVERS(crypto_alloc_tfm);
+EXPORT_SYMBOL_NOVERS(crypto_free_tfm);
+EXPORT_SYMBOL_NOVERS(crypto_alg_available);
diff --git a/drivers/staging/rtl8192u/ieee80211/arc4.c b/drivers/staging/rtl8192u/ieee80211/arc4.c
new file mode 100644
index 0000000..e3ad8d2
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/arc4.c
@@ -0,0 +1,103 @@
+/*
+ * Cryptographic API
+ *
+ * ARC4 Cipher Algorithm
+ *
+ * Jon Oberheide <jon@oberheide.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include "rtl_crypto.h"
+
+#define ARC4_MIN_KEY_SIZE	1
+#define ARC4_MAX_KEY_SIZE	256
+#define ARC4_BLOCK_SIZE		1
+
+struct arc4_ctx {
+	u8 S[256];
+	u8 x, y;
+};
+
+static int arc4_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags)
+{
+	struct arc4_ctx *ctx = ctx_arg;
+	int i, j = 0, k = 0;
+
+	ctx->x = 1;
+	ctx->y = 0;
+
+	for(i = 0; i < 256; i++)
+		ctx->S[i] = i;
+
+	for(i = 0; i < 256; i++)
+	{
+		u8 a = ctx->S[i];
+		j = (j + in_key[k] + a) & 0xff;
+		ctx->S[i] = ctx->S[j];
+		ctx->S[j] = a;
+		if((unsigned int)++k >= key_len)
+			k = 0;
+	}
+
+	return 0;
+}
+
+static void arc4_crypt(void *ctx_arg, u8 *out, const u8 *in)
+{
+	struct arc4_ctx *ctx = ctx_arg;
+
+	u8 *const S = ctx->S;
+	u8 x = ctx->x;
+	u8 y = ctx->y;
+	u8 a, b;
+
+	a = S[x];
+	y = (y + a) & 0xff;
+	b = S[y];
+	S[x] = b;
+	S[y] = a;
+	x = (x + 1) & 0xff;
+	*out++ = *in ^ S[(a + b) & 0xff];
+
+	ctx->x = x;
+	ctx->y = y;
+}
+
+static struct crypto_alg arc4_alg = {
+	.cra_name		=	"arc4",
+	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
+	.cra_blocksize		=	ARC4_BLOCK_SIZE,
+	.cra_ctxsize		=	sizeof(struct arc4_ctx),
+	.cra_module		=	THIS_MODULE,
+	.cra_list		=	LIST_HEAD_INIT(arc4_alg.cra_list),
+	.cra_u			=	{ .cipher = {
+	.cia_min_keysize	=	ARC4_MIN_KEY_SIZE,
+	.cia_max_keysize	=	ARC4_MAX_KEY_SIZE,
+	.cia_setkey		= 	arc4_set_key,
+	.cia_encrypt		=	arc4_crypt,
+	.cia_decrypt		=	arc4_crypt } }
+};
+
+static int __init arc4_init(void)
+{
+	return crypto_register_alg(&arc4_alg);
+}
+
+
+static void __exit arc4_exit(void)
+{
+	crypto_unregister_alg(&arc4_alg);
+}
+
+module_init(arc4_init);
+module_exit(arc4_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ARC4 Cipher Algorithm");
+MODULE_AUTHOR("Jon Oberheide <jon@oberheide.org>");
diff --git a/drivers/staging/rtl8192u/ieee80211/autoload.c b/drivers/staging/rtl8192u/ieee80211/autoload.c
new file mode 100644
index 0000000..c97756f
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/autoload.c
@@ -0,0 +1,40 @@
+/*
+ * Cryptographic API.
+ *
+ * Algorithm autoloader.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#include "kmap_types.h"
+
+#include <linux/kernel.h>
+//#include <linux/crypto.h>
+#include "rtl_crypto.h"
+#include <linux/string.h>
+#include <linux/kmod.h>
+#include "internal.h"
+
+/*
+ * A far more intelligent version of this is planned.  For now, just
+ * try an exact match on the name of the algorithm.
+ */
+void crypto_alg_autoload(const char *name)
+{
+	request_module(name);
+}
+
+struct crypto_alg *crypto_alg_mod_lookup(const char *name)
+{
+	struct crypto_alg *alg = crypto_alg_lookup(name);
+	if (alg == NULL) {
+		crypto_alg_autoload(name);
+		alg = crypto_alg_lookup(name);
+	}
+	return alg;
+}
diff --git a/drivers/staging/rtl8192u/ieee80211/cipher.c b/drivers/staging/rtl8192u/ieee80211/cipher.c
new file mode 100644
index 0000000..0b9e8a4
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/cipher.c
@@ -0,0 +1,299 @@
+/*
+ * Cryptographic API.
+ *
+ * Cipher operations.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#include <linux/kernel.h>
+//#include <linux/crypto.h>
+#include "rtl_crypto.h"
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <asm/scatterlist.h>
+#include "internal.h"
+#include "scatterwalk.h"
+
+typedef void (cryptfn_t)(void *, u8 *, const u8 *);
+typedef void (procfn_t)(struct crypto_tfm *, u8 *,
+			u8*, cryptfn_t, int enc, void *, int);
+
+static inline void xor_64(u8 *a, const u8 *b)
+{
+	((u32 *)a)[0] ^= ((u32 *)b)[0];
+	((u32 *)a)[1] ^= ((u32 *)b)[1];
+}
+
+static inline void xor_128(u8 *a, const u8 *b)
+{
+	((u32 *)a)[0] ^= ((u32 *)b)[0];
+	((u32 *)a)[1] ^= ((u32 *)b)[1];
+	((u32 *)a)[2] ^= ((u32 *)b)[2];
+	((u32 *)a)[3] ^= ((u32 *)b)[3];
+}
+
+
+/*
+ * Generic encrypt/decrypt wrapper for ciphers, handles operations across
+ * multiple page boundaries by using temporary blocks.  In user context,
+ * the kernel is given a chance to schedule us once per block.
+ */
+static int crypt(struct crypto_tfm *tfm,
+		 struct scatterlist *dst,
+		 struct scatterlist *src,
+		 unsigned int nbytes, cryptfn_t crfn,
+		 procfn_t prfn, int enc, void *info)
+{
+	struct scatter_walk walk_in, walk_out;
+	const unsigned int bsize = crypto_tfm_alg_blocksize(tfm);
+	u8 tmp_src[bsize];
+	u8 tmp_dst[bsize];
+
+	if (!nbytes)
+		return 0;
+
+	if (nbytes % bsize) {
+		tfm->crt_flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
+		return -EINVAL;
+	}
+
+	scatterwalk_start(&walk_in, src);
+	scatterwalk_start(&walk_out, dst);
+
+	for(;;) {
+		u8 *src_p, *dst_p;
+		int in_place;
+
+		scatterwalk_map(&walk_in, 0);
+		scatterwalk_map(&walk_out, 1);
+		src_p = scatterwalk_whichbuf(&walk_in, bsize, tmp_src);
+		dst_p = scatterwalk_whichbuf(&walk_out, bsize, tmp_dst);
+		in_place = scatterwalk_samebuf(&walk_in, &walk_out,
+					       src_p, dst_p);
+
+		nbytes -= bsize;
+
+		scatterwalk_copychunks(src_p, &walk_in, bsize, 0);
+
+		prfn(tfm, dst_p, src_p, crfn, enc, info, in_place);
+
+		scatterwalk_done(&walk_in, 0, nbytes);
+
+		scatterwalk_copychunks(dst_p, &walk_out, bsize, 1);
+		scatterwalk_done(&walk_out, 1, nbytes);
+
+		if (!nbytes)
+			return 0;
+
+		crypto_yield(tfm);
+	}
+}
+
+static void cbc_process(struct crypto_tfm *tfm, u8 *dst, u8 *src,
+			cryptfn_t fn, int enc, void *info, int in_place)
+{
+	u8 *iv = info;
+
+	/* Null encryption */
+	if (!iv)
+		return;
+
+	if (enc) {
+		tfm->crt_u.cipher.cit_xor_block(iv, src);
+		fn(crypto_tfm_ctx(tfm), dst, iv);
+		memcpy(iv, dst, crypto_tfm_alg_blocksize(tfm));
+	} else {
+		u8 stack[in_place ? crypto_tfm_alg_blocksize(tfm) : 0];
+		u8 *buf = in_place ? stack : dst;
+
+		fn(crypto_tfm_ctx(tfm), buf, src);
+		tfm->crt_u.cipher.cit_xor_block(buf, iv);
+		memcpy(iv, src, crypto_tfm_alg_blocksize(tfm));
+		if (buf != dst)
+			memcpy(dst, buf, crypto_tfm_alg_blocksize(tfm));
+	}
+}
+
+static void ecb_process(struct crypto_tfm *tfm, u8 *dst, u8 *src,
+			cryptfn_t fn, int enc, void *info, int in_place)
+{
+	fn(crypto_tfm_ctx(tfm), dst, src);
+}
+
+static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
+{
+	struct cipher_alg *cia = &tfm->__crt_alg->cra_cipher;
+
+	if (keylen < cia->cia_min_keysize || keylen > cia->cia_max_keysize) {
+		tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+		return -EINVAL;
+	} else
+		return cia->cia_setkey(crypto_tfm_ctx(tfm), key, keylen,
+				       &tfm->crt_flags);
+}
+
+static int ecb_encrypt(struct crypto_tfm *tfm,
+		       struct scatterlist *dst,
+		       struct scatterlist *src, unsigned int nbytes)
+{
+	return crypt(tfm, dst, src, nbytes,
+		     tfm->__crt_alg->cra_cipher.cia_encrypt,
+		     ecb_process, 1, NULL);
+}
+
+static int ecb_decrypt(struct crypto_tfm *tfm,
+		       struct scatterlist *dst,
+		       struct scatterlist *src,
+		       unsigned int nbytes)
+{
+	return crypt(tfm, dst, src, nbytes,
+		     tfm->__crt_alg->cra_cipher.cia_decrypt,
+		     ecb_process, 1, NULL);
+}
+
+static int cbc_encrypt(struct crypto_tfm *tfm,
+		       struct scatterlist *dst,
+		       struct scatterlist *src,
+		       unsigned int nbytes)
+{
+	return crypt(tfm, dst, src, nbytes,
+		     tfm->__crt_alg->cra_cipher.cia_encrypt,
+		     cbc_process, 1, tfm->crt_cipher.cit_iv);
+}
+
+static int cbc_encrypt_iv(struct crypto_tfm *tfm,
+			  struct scatterlist *dst,
+			  struct scatterlist *src,
+			  unsigned int nbytes, u8 *iv)
+{
+	return crypt(tfm, dst, src, nbytes,
+		     tfm->__crt_alg->cra_cipher.cia_encrypt,
+		     cbc_process, 1, iv);
+}
+
+static int cbc_decrypt(struct crypto_tfm *tfm,
+		       struct scatterlist *dst,
+		       struct scatterlist *src,
+		       unsigned int nbytes)
+{
+	return crypt(tfm, dst, src, nbytes,
+		     tfm->__crt_alg->cra_cipher.cia_decrypt,
+		     cbc_process, 0, tfm->crt_cipher.cit_iv);
+}
+
+static int cbc_decrypt_iv(struct crypto_tfm *tfm,
+			  struct scatterlist *dst,
+			  struct scatterlist *src,
+			  unsigned int nbytes, u8 *iv)
+{
+	return crypt(tfm, dst, src, nbytes,
+		     tfm->__crt_alg->cra_cipher.cia_decrypt,
+		     cbc_process, 0, iv);
+}
+
+static int nocrypt(struct crypto_tfm *tfm,
+		   struct scatterlist *dst,
+		   struct scatterlist *src,
+		   unsigned int nbytes)
+{
+	return -ENOSYS;
+}
+
+static int nocrypt_iv(struct crypto_tfm *tfm,
+		      struct scatterlist *dst,
+		      struct scatterlist *src,
+		      unsigned int nbytes, u8 *iv)
+{
+	return -ENOSYS;
+}
+
+int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags)
+{
+	u32 mode = flags & CRYPTO_TFM_MODE_MASK;
+
+	tfm->crt_cipher.cit_mode = mode ? mode : CRYPTO_TFM_MODE_ECB;
+	if (flags & CRYPTO_TFM_REQ_WEAK_KEY)
+		tfm->crt_flags = CRYPTO_TFM_REQ_WEAK_KEY;
+
+	return 0;
+}
+
+int crypto_init_cipher_ops(struct crypto_tfm *tfm)
+{
+	int ret = 0;
+	struct cipher_tfm *ops = &tfm->crt_cipher;
+
+	ops->cit_setkey = setkey;
+
+	switch (tfm->crt_cipher.cit_mode) {
+	case CRYPTO_TFM_MODE_ECB:
+		ops->cit_encrypt = ecb_encrypt;
+		ops->cit_decrypt = ecb_decrypt;
+		break;
+
+	case CRYPTO_TFM_MODE_CBC:
+		ops->cit_encrypt = cbc_encrypt;
+		ops->cit_decrypt = cbc_decrypt;
+		ops->cit_encrypt_iv = cbc_encrypt_iv;
+		ops->cit_decrypt_iv = cbc_decrypt_iv;
+		break;
+
+	case CRYPTO_TFM_MODE_CFB:
+		ops->cit_encrypt = nocrypt;
+		ops->cit_decrypt = nocrypt;
+		ops->cit_encrypt_iv = nocrypt_iv;
+		ops->cit_decrypt_iv = nocrypt_iv;
+		break;
+
+	case CRYPTO_TFM_MODE_CTR:
+		ops->cit_encrypt = nocrypt;
+		ops->cit_decrypt = nocrypt;
+		ops->cit_encrypt_iv = nocrypt_iv;
+		ops->cit_decrypt_iv = nocrypt_iv;
+		break;
+
+	default:
+		BUG();
+	}
+
+	if (ops->cit_mode == CRYPTO_TFM_MODE_CBC) {
+
+		switch (crypto_tfm_alg_blocksize(tfm)) {
+		case 8:
+			ops->cit_xor_block = xor_64;
+			break;
+
+		case 16:
+			ops->cit_xor_block = xor_128;
+			break;
+
+		default:
+			printk(KERN_WARNING "%s: block size %u not supported\n",
+			       crypto_tfm_alg_name(tfm),
+			       crypto_tfm_alg_blocksize(tfm));
+			ret = -EINVAL;
+			goto out;
+		}
+
+		ops->cit_ivsize = crypto_tfm_alg_blocksize(tfm);
+		ops->cit_iv = kmalloc(ops->cit_ivsize, GFP_KERNEL);
+		if (ops->cit_iv == NULL)
+			ret = -ENOMEM;
+	}
+
+out:
+	return ret;
+}
+
+void crypto_exit_cipher_ops(struct crypto_tfm *tfm)
+{
+	if (tfm->crt_cipher.cit_iv)
+		kfree(tfm->crt_cipher.cit_iv);
+}
diff --git a/drivers/staging/rtl8192u/ieee80211/compress.c b/drivers/staging/rtl8192u/ieee80211/compress.c
new file mode 100644
index 0000000..86c23c9
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/compress.c
@@ -0,0 +1,64 @@
+/*
+ * Cryptographic API.
+ *
+ * Compression operations.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#include <linux/types.h>
+//#include <linux/crypto.h>
+#include "rtl_crypto.h"
+#include <linux/errno.h>
+#include <asm/scatterlist.h>
+#include <linux/string.h>
+#include "internal.h"
+
+static int crypto_compress(struct crypto_tfm *tfm,
+			    const u8 *src, unsigned int slen,
+			    u8 *dst, unsigned int *dlen)
+{
+	return tfm->__crt_alg->cra_compress.coa_compress(crypto_tfm_ctx(tfm),
+							 src, slen, dst,
+							 dlen);
+}
+
+static int crypto_decompress(struct crypto_tfm *tfm,
+			     const u8 *src, unsigned int slen,
+			     u8 *dst, unsigned int *dlen)
+{
+	return tfm->__crt_alg->cra_compress.coa_decompress(crypto_tfm_ctx(tfm),
+							   src, slen, dst,
+							   dlen);
+}
+
+int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags)
+{
+	return flags ? -EINVAL : 0;
+}
+
+int crypto_init_compress_ops(struct crypto_tfm *tfm)
+{
+	int ret = 0;
+	struct compress_tfm *ops = &tfm->crt_compress;
+
+	ret = tfm->__crt_alg->cra_compress.coa_init(crypto_tfm_ctx(tfm));
+	if (ret)
+		goto out;
+
+	ops->cot_compress = crypto_compress;
+	ops->cot_decompress = crypto_decompress;
+
+out:
+	return ret;
+}
+
+void crypto_exit_compress_ops(struct crypto_tfm *tfm)
+{
+	tfm->__crt_alg->cra_compress.coa_exit(crypto_tfm_ctx(tfm));
+}
diff --git a/drivers/staging/rtl8192u/ieee80211/crypto_compat.h b/drivers/staging/rtl8192u/ieee80211/crypto_compat.h
new file mode 100644
index 0000000..da48658
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/crypto_compat.h
@@ -0,0 +1,60 @@
+/*
+ * Header file to maintain compatibility among different kernel versions.
+ *
+ * Copyright (c) 2004-2006  <lawrence_wang@realsil.com.cn>
+ *
+ * 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/crypto.h>
+
+static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm,
+					struct scatterlist *dst,
+					struct scatterlist *src,
+					unsigned int nbytes)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes);
+}
+
+
+static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm,
+					struct scatterlist *dst,
+					struct scatterlist *src,
+					unsigned int nbytes)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes);
+}
+
+ struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
+{
+	struct crypto_tfm *tfm = NULL;
+	int err;
+	printk("call crypto_alloc_tfm!!!\n");
+	do {
+		struct crypto_alg *alg;
+
+		alg = crypto_alg_mod_lookup(name, 0, CRYPTO_ALG_ASYNC);
+		err = PTR_ERR(alg);
+		if (IS_ERR(alg))
+			continue;
+
+		tfm = __crypto_alloc_tfm(alg, flags);
+		err = 0;
+		if (IS_ERR(tfm)) {
+			crypto_mod_put(alg);
+			err = PTR_ERR(tfm);
+			tfm = NULL;
+		}
+	} while (err == -EAGAIN && !signal_pending(current));
+
+	return tfm;
+}
+//EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
+//EXPORT_SYMBOL_GPL(crypto_free_tfm);
+
+
diff --git a/drivers/staging/rtl8192u/ieee80211/digest.c b/drivers/staging/rtl8192u/ieee80211/digest.c
new file mode 100644
index 0000000..301ed51
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/digest.c
@@ -0,0 +1,108 @@
+/*
+ * Cryptographic API.
+ *
+ * Digest operations.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+//#include <linux/crypto.h>
+#include "rtl_crypto.h"
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/highmem.h>
+#include <asm/scatterlist.h>
+#include "internal.h"
+
+static void init(struct crypto_tfm *tfm)
+{
+	tfm->__crt_alg->cra_digest.dia_init(crypto_tfm_ctx(tfm));
+}
+
+static void update(struct crypto_tfm *tfm,
+		   struct scatterlist *sg, unsigned int nsg)
+{
+	unsigned int i;
+
+	for (i = 0; i < nsg; i++) {
+
+		struct page *pg = sg[i].page;
+		unsigned int offset = sg[i].offset;
+		unsigned int l = sg[i].length;
+
+		do {
+			unsigned int bytes_from_page = min(l, ((unsigned int)
+							   (PAGE_SIZE)) -
+							   offset);
+			char *p = crypto_kmap(pg, 0) + offset;
+
+			tfm->__crt_alg->cra_digest.dia_update
+					(crypto_tfm_ctx(tfm), p,
+					 bytes_from_page);
+			crypto_kunmap(p, 0);
+			crypto_yield(tfm);
+			offset = 0;
+			pg++;
+			l -= bytes_from_page;
+		} while (l > 0);
+	}
+}
+
+static void final(struct crypto_tfm *tfm, u8 *out)
+{
+	tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), out);
+}
+
+static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
+{
+	u32 flags;
+	if (tfm->__crt_alg->cra_digest.dia_setkey == NULL)
+		return -ENOSYS;
+	return tfm->__crt_alg->cra_digest.dia_setkey(crypto_tfm_ctx(tfm),
+						     key, keylen, &flags);
+}
+
+static void digest(struct crypto_tfm *tfm,
+		   struct scatterlist *sg, unsigned int nsg, u8 *out)
+{
+	unsigned int i;
+
+	tfm->crt_digest.dit_init(tfm);
+
+	for (i = 0; i < nsg; i++) {
+		char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset;
+		tfm->__crt_alg->cra_digest.dia_update(crypto_tfm_ctx(tfm),
+						      p, sg[i].length);
+		crypto_kunmap(p, 0);
+		crypto_yield(tfm);
+	}
+	crypto_digest_final(tfm, out);
+}
+
+int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags)
+{
+	return flags ? -EINVAL : 0;
+}
+
+int crypto_init_digest_ops(struct crypto_tfm *tfm)
+{
+	struct digest_tfm *ops = &tfm->crt_digest;
+
+	ops->dit_init	= init;
+	ops->dit_update	= update;
+	ops->dit_final	= final;
+	ops->dit_digest	= digest;
+	ops->dit_setkey	= setkey;
+
+	return crypto_alloc_hmac_block(tfm);
+}
+
+void crypto_exit_digest_ops(struct crypto_tfm *tfm)
+{
+	crypto_free_hmac_block(tfm);
+}
diff --git a/drivers/staging/rtl8192u/ieee80211/dot11d.c b/drivers/staging/rtl8192u/ieee80211/dot11d.c
new file mode 100644
index 0000000..b91cbfc
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/dot11d.c
@@ -0,0 +1,223 @@
+#ifdef ENABLE_DOT11D
+//-----------------------------------------------------------------------------
+//	File:
+//		Dot11d.c
+//
+//	Description:
+//		Implement 802.11d.
+//
+//-----------------------------------------------------------------------------
+
+#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);
+
+	printk("Dot11d_Init()\n");
+}
+
+//
+//	Description:
+//		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);
+
+	//printk("Dot11d_Reset()\n");
+}
+
+//
+//	Description:
+//		Update country IE from Beacon or Probe Resopnse
+//		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;
+	PCHNL_TXPOWER_TRIPLE pTriple;
+
+	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.
+			printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
+			return;
+		}
+		if(MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + pTriple->NumChnls))
+		{ // It is not a valid set of channel id, so stop processing.
+			printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
+			return;
+		}
+
+		for(j = 0 ; j < pTriple->NumChnls; j++)
+		{
+			pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1;
+			pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = pTriple->MaxTxPowerInDbm;
+			MaxChnlNum = pTriple->FirstChnl + j;
+		}
+
+		pTriple = (PCHNL_TXPOWER_TRIPLE)((u8*)pTriple + 3);
+	}
+	//printk("Dot11d_UpdateCountryIe(): Channel List:\n");
+	printk("Channel List:");
+	for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
+		if(pDot11dInfo->channel_map[i] > 0)
+			printk(" %d", i);
+	printk("\n");
+
+	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)
+	{
+		printk("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)
+	{
+		printk("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)
+	{
+		printk("IsLegalChannel(): Invalid Channel\n");
+		return default_chn;
+	}
+
+	if(pDot11dInfo->channel_map[channel] > 0)
+		return channel;
+
+	return default_chn;
+}
+EXPORT_SYMBOL(Dot11d_Init);
+EXPORT_SYMBOL(Dot11d_Reset);
+EXPORT_SYMBOL(Dot11d_UpdateCountryIe);
+EXPORT_SYMBOL(DOT11D_GetMaxTxPwrInDbm);
+EXPORT_SYMBOL(DOT11D_ScanComplete);
+EXPORT_SYMBOL(IsLegalChannel);
+EXPORT_SYMBOL(ToLegalChannel);
+
+#endif
diff --git a/drivers/staging/rtl8192u/ieee80211/dot11d.h b/drivers/staging/rtl8192u/ieee80211/dot11d.h
new file mode 100644
index 0000000..15b7a4b
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/dot11d.h
@@ -0,0 +1,102 @@
+#ifndef __INC_DOT11D_H
+#define __INC_DOT11D_H
+
+#ifdef ENABLE_DOT11D
+#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_DOT11D_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 //ENABLE_DOT11D
+#endif // #ifndef __INC_DOT11D_H
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h
new file mode 100644
index 0000000..10908e123
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h
@@ -0,0 +1,2639 @@
+/*
+ * 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
+ * <andreamrl@tiscali.it>
+ *
+ * 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/version.h>
+#include <linux/module.h>
+#include <linux/jiffies.h>
+#include <linux/timer.h>
+#include <linux/sched.h>
+
+#include <linux/delay.h>
+#include <linux/wireless.h>
+
+#include "rtl819x_HT.h"
+#include "rtl819x_BA.h"
+#include "rtl819x_TS.h"
+
+
+#ifndef IW_MODE_MONITOR
+#define IW_MODE_MONITOR 6
+#endif
+
+#ifndef IWEVCUSTOM
+#define IWEVCUSTOM 0x8c02
+#endif
+
+
+#ifndef container_of
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ *
+ * @ptr:        the pointer to the member.
+ * @type:       the type of the container struct this is embedded in.
+ * @member:     the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({                      \
+	const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
+	(type *)( (char *)__mptr - offsetof(type,member) );})
+#endif
+
+#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
+
+/* added for rtl819x tx procedure */
+#define MAX_QUEUE_SIZE		0x10
+
+//
+// 8190 queue mapping
+//
+#define BK_QUEUE                               0
+#define BE_QUEUE                               1
+#define VI_QUEUE                               2
+#define VO_QUEUE                               3
+#define HCCA_QUEUE                             4
+#define TXCMD_QUEUE                            5
+#define MGNT_QUEUE                             6
+#define HIGH_QUEUE                             7
+#define BEACON_QUEUE                           8
+
+#define LOW_QUEUE                              BE_QUEUE
+#define NORMAL_QUEUE                           MGNT_QUEUE
+
+//added by amy for ps
+#define SWRF_TIMEOUT				50
+
+//added by amy for LEAP related
+#define IE_CISCO_FLAG_POSITION		0x08	// Flag byte: byte 8, numbered from 0.
+#define SUPPORT_CKIP_MIC			0x08	// bit3
+#define SUPPORT_CKIP_PK			0x10	// bit4
+/* defined for skb cb field */
+/* At most 28 byte */
+typedef struct cb_desc {
+	/* Tx Desc Related flags (8-9) */
+	u8 bLastIniPkt:1;
+	u8 bCmdOrInit:1;
+	u8 bFirstSeg:1;
+	u8 bLastSeg:1;
+	u8 bEncrypt:1;
+	u8 bTxDisableRateFallBack:1;
+	u8 bTxUseDriverAssingedRate:1;
+	u8 bHwSec:1; //indicate whether use Hw security. WB
+
+	u8 reserved1;
+
+	/* Tx Firmware Relaged flags (10-11)*/
+	u8 bCTSEnable:1;
+	u8 bRTSEnable:1;
+	u8 bUseShortGI:1;
+	u8 bUseShortPreamble:1;
+	u8 bTxEnableFwCalcDur:1;
+	u8 bAMPDUEnable:1;
+	u8 bRTSSTBC:1;
+	u8 RTSSC:1;
+
+	u8 bRTSBW:1;
+	u8 bPacketBW:1;
+	u8 bRTSUseShortPreamble:1;
+	u8 bRTSUseShortGI:1;
+	u8 bMulticast:1;
+	u8 bBroadcast:1;
+	//u8 reserved2:2;
+	u8 drv_agg_enable:1;
+	u8 reserved2:1;
+
+	/* Tx Desc related element(12-19) */
+	u8 rata_index;
+	u8 queue_index;
+	//u8 reserved3;
+	//u8 reserved4;
+	u16 txbuf_size;
+	//u8 reserved5;
+	u8 RATRIndex;
+	u8 reserved6;
+	u8 reserved7;
+	u8 reserved8;
+
+	/* Tx firmware related element(20-27) */
+	u8 data_rate;
+	u8 rts_rate;
+	u8 ampdu_factor;
+	u8 ampdu_density;
+	//u8 reserved9;
+	//u8 reserved10;
+	//u8 reserved11;
+	u8 DrvAggrNum;
+	u16 pkt_size;
+	u8 reserved12;
+}cb_desc, *pcb_desc;
+
+/*--------------------------Define -------------------------------------------*/
+#define MGN_1M                  0x02
+#define MGN_2M                  0x04
+#define MGN_5_5M                0x0b
+#define MGN_11M                 0x16
+
+#define MGN_6M                  0x0c
+#define MGN_9M                  0x12
+#define MGN_12M                 0x18
+#define MGN_18M                 0x24
+#define MGN_24M                 0x30
+#define MGN_36M                 0x48
+#define MGN_48M                 0x60
+#define MGN_54M                 0x6c
+
+#define MGN_MCS0                0x80
+#define MGN_MCS1                0x81
+#define MGN_MCS2                0x82
+#define MGN_MCS3                0x83
+#define MGN_MCS4                0x84
+#define MGN_MCS5                0x85
+#define MGN_MCS6                0x86
+#define MGN_MCS7                0x87
+#define MGN_MCS8                0x88
+#define MGN_MCS9                0x89
+#define MGN_MCS10               0x8a
+#define MGN_MCS11               0x8b
+#define MGN_MCS12               0x8c
+#define MGN_MCS13               0x8d
+#define MGN_MCS14               0x8e
+#define MGN_MCS15               0x8f
+
+//----------------------------------------------------------------------------
+//		802.11 Management frame Reason Code field
+//----------------------------------------------------------------------------
+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
+};
+
+
+
+#define aSifsTime	 ((priv->ieee80211->current_network.mode == IEEE_A)||(priv->ieee80211->current_network.mode == IEEE_N_24G)||(priv->ieee80211->current_network.mode == IEEE_N_5G))? 16 : 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
+
+#define MAX_IE_LEN  0xff
+
+// added for kernel conflict
+#define ieee80211_crypt_deinit_entries 	ieee80211_crypt_deinit_entries_rsl
+#define ieee80211_crypt_deinit_handler 	ieee80211_crypt_deinit_handler_rsl
+#define ieee80211_crypt_delayed_deinit 	ieee80211_crypt_delayed_deinit_rsl
+#define ieee80211_register_crypto_ops  	ieee80211_register_crypto_ops_rsl
+#define ieee80211_unregister_crypto_ops ieee80211_unregister_crypto_ops_rsl
+#define ieee80211_get_crypto_ops 	ieee80211_get_crypto_ops_rsl
+
+#define ieee80211_ccmp_null		ieee80211_ccmp_null_rsl
+
+#define ieee80211_tkip_null		ieee80211_tkip_null_rsl
+
+#define ieee80211_wep_null		ieee80211_wep_null_rsl
+
+#define free_ieee80211          	free_ieee80211_rsl
+#define alloc_ieee80211        		alloc_ieee80211_rsl
+
+#define ieee80211_rx 			ieee80211_rx_rsl
+#define ieee80211_rx_mgt		ieee80211_rx_mgt_rsl
+
+#define ieee80211_get_beacon		ieee80211_get_beacon_rsl
+#define ieee80211_wake_queue		ieee80211_wake_queue_rsl
+#define ieee80211_stop_queue		ieee80211_stop_queue_rsl
+#define ieee80211_reset_queue		ieee80211_reset_queue_rsl
+#define ieee80211_softmac_stop_protocol	ieee80211_softmac_stop_protocol_rsl
+#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl
+#define ieee80211_is_shortslot		ieee80211_is_shortslot_rsl
+#define ieee80211_is_54g		ieee80211_is_54g_rsl
+#define ieee80211_wpa_supplicant_ioctl	ieee80211_wpa_supplicant_ioctl_rsl
+#define ieee80211_ps_tx_ack		ieee80211_ps_tx_ack_rsl
+#define ieee80211_softmac_xmit		ieee80211_softmac_xmit_rsl
+#define ieee80211_stop_send_beacons	ieee80211_stop_send_beacons_rsl
+#define notify_wx_assoc_event		notify_wx_assoc_event_rsl
+#define SendDisassociation		SendDisassociation_rsl
+#define ieee80211_disassociate		ieee80211_disassociate_rsl
+#define ieee80211_start_send_beacons	ieee80211_start_send_beacons_rsl
+#define ieee80211_stop_scan		ieee80211_stop_scan_rsl
+#define ieee80211_send_probe_requests	ieee80211_send_probe_requests_rsl
+#define ieee80211_softmac_scan_syncro	ieee80211_softmac_scan_syncro_rsl
+#define ieee80211_start_scan_syncro	ieee80211_start_scan_syncro_rsl
+
+#define ieee80211_wx_get_essid		ieee80211_wx_get_essid_rsl
+#define ieee80211_wx_set_essid		ieee80211_wx_set_essid_rsl
+#define ieee80211_wx_set_rate		ieee80211_wx_set_rate_rsl
+#define ieee80211_wx_get_rate		ieee80211_wx_get_rate_rsl
+#define ieee80211_wx_set_wap		ieee80211_wx_set_wap_rsl
+#define ieee80211_wx_get_wap		ieee80211_wx_get_wap_rsl
+#define ieee80211_wx_set_mode		ieee80211_wx_set_mode_rsl
+#define ieee80211_wx_get_mode		ieee80211_wx_get_mode_rsl
+#define ieee80211_wx_set_scan		ieee80211_wx_set_scan_rsl
+#define ieee80211_wx_get_freq		ieee80211_wx_get_freq_rsl
+#define ieee80211_wx_set_freq		ieee80211_wx_set_freq_rsl
+#define ieee80211_wx_set_rawtx		ieee80211_wx_set_rawtx_rsl
+#define ieee80211_wx_get_name		ieee80211_wx_get_name_rsl
+#define ieee80211_wx_set_power		ieee80211_wx_set_power_rsl
+#define ieee80211_wx_get_power		ieee80211_wx_get_power_rsl
+#define ieee80211_wlan_frequencies	ieee80211_wlan_frequencies_rsl
+#define ieee80211_wx_set_rts		ieee80211_wx_set_rts_rsl
+#define ieee80211_wx_get_rts		ieee80211_wx_get_rts_rsl
+
+#define ieee80211_txb_free		ieee80211_txb_free_rsl
+
+#define ieee80211_wx_set_gen_ie		ieee80211_wx_set_gen_ie_rsl
+#define ieee80211_wx_get_scan		ieee80211_wx_get_scan_rsl
+#define ieee80211_wx_set_encode		ieee80211_wx_set_encode_rsl
+#define ieee80211_wx_get_encode		ieee80211_wx_get_encode_rsl
+#if WIRELESS_EXT >= 18
+#define ieee80211_wx_set_mlme		ieee80211_wx_set_mlme_rsl
+#define ieee80211_wx_set_auth		ieee80211_wx_set_auth_rsl
+#define ieee80211_wx_set_encode_ext	ieee80211_wx_set_encode_ext_rsl
+#define ieee80211_wx_get_encode_ext	ieee80211_wx_get_encode_ext_rsl
+#endif
+
+
+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;
+
+
+#if WIRELESS_EXT < 17
+#define IW_QUAL_QUAL_INVALID   0x10
+#define IW_QUAL_LEVEL_INVALID  0x20
+#define IW_QUAL_NOISE_INVALID  0x40
+#define IW_QUAL_QUAL_UPDATED   0x1
+#define IW_QUAL_LEVEL_UPDATED  0x2
+#define IW_QUAL_NOISE_UPDATED  0x4
+#endif
+
+
+// linux under 2.6.9 release may not support it, so modify it for common use
+#define MSECS(t) msecs_to_jiffies(t)
+#define msleep_interruptible_rsl  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_1ADDR_LEN 10
+#define IEEE80211_2ADDR_LEN 16
+#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_VERS		0x0003
+#define IEEE80211_FCTL_FTYPE		0x000c
+#define IEEE80211_FCTL_STYPE		0x00f0
+#define IEEE80211_FCTL_FRAMETYPE	0x00fc
+#define IEEE80211_FCTL_TODS		0x0100
+#define IEEE80211_FCTL_FROMDS		0x0200
+#define IEEE80211_FCTL_DSTODS		0x0300 //added by david
+#define IEEE80211_FCTL_MOREFRAGS	0x0400
+#define IEEE80211_FCTL_RETRY		0x0800
+#define IEEE80211_FCTL_PM		0x1000
+#define IEEE80211_FCTL_MOREDATA		0x2000
+#define IEEE80211_FCTL_WEP		0x4000
+#define IEEE80211_FCTL_ORDER		0x8000
+
+#define IEEE80211_FTYPE_MGMT		0x0000
+#define IEEE80211_FTYPE_CTL		0x0004
+#define IEEE80211_FTYPE_DATA		0x0008
+
+/* management */
+#define IEEE80211_STYPE_ASSOC_REQ	0x0000
+#define IEEE80211_STYPE_ASSOC_RESP 	0x0010
+#define IEEE80211_STYPE_REASSOC_REQ	0x0020
+#define IEEE80211_STYPE_REASSOC_RESP	0x0030
+#define IEEE80211_STYPE_PROBE_REQ	0x0040
+#define IEEE80211_STYPE_PROBE_RESP	0x0050
+#define IEEE80211_STYPE_BEACON		0x0080
+#define IEEE80211_STYPE_ATIM		0x0090
+#define IEEE80211_STYPE_DISASSOC	0x00A0
+#define IEEE80211_STYPE_AUTH		0x00B0
+#define IEEE80211_STYPE_DEAUTH		0x00C0
+#define IEEE80211_STYPE_MANAGE_ACT	0x00D0
+
+/* control */
+#define IEEE80211_STYPE_PSPOLL		0x00A0
+#define IEEE80211_STYPE_RTS		0x00B0
+#define IEEE80211_STYPE_CTS		0x00C0
+#define IEEE80211_STYPE_ACK		0x00D0
+#define IEEE80211_STYPE_CFEND		0x00E0
+#define IEEE80211_STYPE_CFENDACK	0x00F0
+#define IEEE80211_STYPE_BLOCKACK   0x0094
+
+/* data */
+#define IEEE80211_STYPE_DATA		0x0000
+#define IEEE80211_STYPE_DATA_CFACK	0x0010
+#define IEEE80211_STYPE_DATA_CFPOLL	0x0020
+#define IEEE80211_STYPE_DATA_CFACKPOLL	0x0030
+#define IEEE80211_STYPE_NULLFUNC	0x0040
+#define IEEE80211_STYPE_CFACK		0x0050
+#define IEEE80211_STYPE_CFPOLL		0x0060
+#define IEEE80211_STYPE_CFACKPOLL	0x0070
+#define IEEE80211_STYPE_QOS_DATA	0x0080 //added for WMM 2006/8/2
+#define IEEE80211_STYPE_QOS_NULL	0x00C0
+
+#define IEEE80211_SCTL_FRAG		0x000F
+#define IEEE80211_SCTL_SEQ		0xFFF0
+
+/* QOS control */
+#define IEEE80211_QCTL_TID              0x000F
+
+#define	FC_QOS_BIT					BIT7
+#define IsDataFrame(pdu)			( ((pdu[0] & 0x0C)==0x08) ? true : false )
+#define	IsLegacyDataFrame(pdu)	(IsDataFrame(pdu) && (!(pdu[0]&FC_QOS_BIT)) )
+//added by wb. Is this right?
+#define IsQoSDataFrame(pframe)  ((*(u16*)pframe&(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) == (IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA))
+#define Frame_Order(pframe)     (*(u16*)pframe&IEEE80211_FCTL_ORDER)
+#define SN_LESS(a, b)		(((a-b)&0x800)!=0)
+#define SN_EQUAL(a, b)	(a == b)
+#define MAX_DEV_ADDR_SIZE 8
+typedef enum _ACT_CATEGORY{
+	ACT_CAT_QOS = 1,
+	ACT_CAT_DLS = 2,
+	ACT_CAT_BA  = 3,
+	ACT_CAT_HT  = 7,
+	ACT_CAT_WMM = 17,
+} ACT_CATEGORY, *PACT_CATEGORY;
+
+typedef enum _TS_ACTION{
+	ACT_ADDTSREQ = 0,
+	ACT_ADDTSRSP = 1,
+	ACT_DELTS    = 2,
+	ACT_SCHEDULE = 3,
+} TS_ACTION, *PTS_ACTION;
+
+typedef enum _BA_ACTION{
+	ACT_ADDBAREQ = 0,
+	ACT_ADDBARSP = 1,
+	ACT_DELBA    = 2,
+} BA_ACTION, *PBA_ACTION;
+
+typedef enum _InitialGainOpType{
+	IG_Backup=0,
+	IG_Restore,
+	IG_Max
+}InitialGainOpType;
+
+/* debug macros */
+#define CONFIG_IEEE80211_DEBUG
+#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: " fmt, ## args); } while (0)
+//wb added to debug out data buf
+//if you want print DATA buffer related BA, please set ieee80211_debug_level to DATA|BA
+#define IEEE80211_DEBUG_DATA(level, data, datalen)	\
+	do{ if ((ieee80211_debug_level & (level)) == (level))	\
+		{ 	\
+			int i;					\
+			u8* pdata = (u8*) data;			\
+			printk(KERN_DEBUG "ieee80211: %s()\n", __FUNCTION__);	\
+			for(i=0; i<(int)(datalen); i++)			\
+			{						\
+				printk("%2x ", pdata[i]);		\
+				if ((i+1)%16 == 0) printk("\n");	\
+			}				\
+			printk("\n");			\
+		}					\
+	} while (0)
+#else
+#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
+#define IEEE80211_DEBUG_DATA(level, data, datalen) do {} while(0)
+#endif	/* CONFIG_IEEE80211_DEBUG */
+
+/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
+
+#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
+#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
+
+/*
+ * 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_DL_HT		   (1<<10)  //HT
+#define IEEE80211_DL_BA		   (1<<11)  //ba
+#define IEEE80211_DL_TS		   (1<<12)  //TS
+#define IEEE80211_DL_QOS           (1<<13)
+#define IEEE80211_DL_REORDER	   (1<<14)
+#define IEEE80211_DL_IOT	   (1<<15)
+#define IEEE80211_DL_IPS	   (1<<16)
+#define IEEE80211_DL_TRACE	   (1<<29)  //trace function, need to user net_ratelimit() together in order not to print too much to the screen
+#define IEEE80211_DL_DATA	   (1<<30)   //use this flag to control whether print data buf out.
+#define IEEE80211_DL_ERR	   (1<<31)   //always open
+#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 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)
+#define IEEE80211_DEBUG_QOS(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a)
+
+#ifdef CONFIG_IEEE80211_DEBUG
+/* Added by Annie, 2005-11-22. */
+#define MAX_STR_LEN     64
+/* I want to see ASCII 33 to 126 only. Otherwise, I print '?'. Annie, 2005-11-22.*/
+#define PRINTABLE(_ch)  (_ch>'!' && _ch<'~')
+#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len)                            	\
+			if((_Comp) & level)   							\
+			{                                                                       \
+				int             __i;                                            \
+				u8  buffer[MAX_STR_LEN];                                    	\
+				int length = (_Len<MAX_STR_LEN)? _Len : (MAX_STR_LEN-1) ;  	\
+				memset(buffer, 0, MAX_STR_LEN);                      		\
+				memcpy(buffer, (u8 *)_Ptr, length );            		\
+				for( __i=0; __i<MAX_STR_LEN; __i++ )                            \
+				{                                                               \
+				     if( !PRINTABLE(buffer[__i]) )   buffer[__i] = '?';     	\
+				}                                                               \
+				buffer[length] = '\0';                                          \
+				printk("Rtl819x: ");                                         	\
+				printk(_TitleString);                                         \
+				printk(": %d, <%s>\n", _Len, buffer);                         \
+			}
+#else
+#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len)  do {} while (0)
+#endif
+
+#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_VERS(fc) ((fc) & IEEE80211_FCTL_VERS)
+#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
+#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
+
+#define WLAN_FC_GET_FRAMETYPE(fc) ((fc) & IEEE80211_FCTL_FRAMETYPE)
+#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
+#define WLAN_GET_SEQ_SEQ(seq)  (((seq) & IEEE80211_SCTL_SEQ) >> 4)
+
+/* Authentication algorithms */
+#define WLAN_AUTH_OPEN 0
+#define WLAN_AUTH_SHARED_KEY 1
+#define WLAN_AUTH_LEAP 2
+
+#define WLAN_AUTH_CHALLENGE_LEN 128
+
+#define WLAN_CAPABILITY_BSS (1<<0)
+#define WLAN_CAPABILITY_IBSS (1<<1)
+#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
+#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
+#define WLAN_CAPABILITY_PRIVACY (1<<4)
+#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
+#define WLAN_CAPABILITY_PBCC (1<<6)
+#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
+#define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8)
+#define WLAN_CAPABILITY_QOS (1<<9)
+#define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
+#define WLAN_CAPABILITY_DSSS_OFDM (1<<13)
+
+/* 802.11g ERP information element */
+#define WLAN_ERP_NON_ERP_PRESENT (1<<0)
+#define WLAN_ERP_USE_PROTECTION (1<<1)
+#define WLAN_ERP_BARKER_PREAMBLE (1<<2)
+
+/* Status codes */
+enum ieee80211_statuscode {
+	WLAN_STATUS_SUCCESS = 0,
+	WLAN_STATUS_UNSPECIFIED_FAILURE = 1,
+	WLAN_STATUS_CAPS_UNSUPPORTED = 10,
+	WLAN_STATUS_REASSOC_NO_ASSOC = 11,
+	WLAN_STATUS_ASSOC_DENIED_UNSPEC = 12,
+	WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG = 13,
+	WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION = 14,
+	WLAN_STATUS_CHALLENGE_FAIL = 15,
+	WLAN_STATUS_AUTH_TIMEOUT = 16,
+	WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17,
+	WLAN_STATUS_ASSOC_DENIED_RATES = 18,
+	/* 802.11b */
+	WLAN_STATUS_ASSOC_DENIED_NOSHORTPREAMBLE = 19,
+	WLAN_STATUS_ASSOC_DENIED_NOPBCC = 20,
+	WLAN_STATUS_ASSOC_DENIED_NOAGILITY = 21,
+	/* 802.11h */
+	WLAN_STATUS_ASSOC_DENIED_NOSPECTRUM = 22,
+	WLAN_STATUS_ASSOC_REJECTED_BAD_POWER = 23,
+	WLAN_STATUS_ASSOC_REJECTED_BAD_SUPP_CHAN = 24,
+	/* 802.11g */
+	WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25,
+	WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26,
+	/* 802.11i */
+	WLAN_STATUS_INVALID_IE = 40,
+	WLAN_STATUS_INVALID_GROUP_CIPHER = 41,
+	WLAN_STATUS_INVALID_PAIRWISE_CIPHER = 42,
+	WLAN_STATUS_INVALID_AKMP = 43,
+	WLAN_STATUS_UNSUPP_RSN_VERSION = 44,
+	WLAN_STATUS_INVALID_RSN_IE_CAP = 45,
+	WLAN_STATUS_CIPHER_SUITE_REJECTED = 46,
+};
+
+/* Reason codes */
+enum ieee80211_reasoncode {
+	WLAN_REASON_UNSPECIFIED = 1,
+	WLAN_REASON_PREV_AUTH_NOT_VALID = 2,
+	WLAN_REASON_DEAUTH_LEAVING = 3,
+	WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY = 4,
+	WLAN_REASON_DISASSOC_AP_BUSY = 5,
+	WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6,
+	WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7,
+	WLAN_REASON_DISASSOC_STA_HAS_LEFT = 8,
+	WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH = 9,
+	/* 802.11h */
+	WLAN_REASON_DISASSOC_BAD_POWER = 10,
+	WLAN_REASON_DISASSOC_BAD_SUPP_CHAN = 11,
+	/* 802.11i */
+	WLAN_REASON_INVALID_IE = 13,
+	WLAN_REASON_MIC_FAILURE = 14,
+	WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT = 15,
+	WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT = 16,
+	WLAN_REASON_IE_DIFFERENT = 17,
+	WLAN_REASON_INVALID_GROUP_CIPHER = 18,
+	WLAN_REASON_INVALID_PAIRWISE_CIPHER = 19,
+	WLAN_REASON_INVALID_AKMP = 20,
+	WLAN_REASON_UNSUPP_RSN_VERSION = 21,
+	WLAN_REASON_INVALID_RSN_IE_CAP = 22,
+	WLAN_REASON_IEEE8021X_FAILED = 23,
+	WLAN_REASON_CIPHER_SUITE_REJECTED = 24,
+};
+
+#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];
+	s8 rssi;
+	u8 signal;
+	u8 noise;
+	u16 rate; /* in 100 kbps */
+	u8 received_channel;
+	u8 control;
+	u8 mask;
+	u8 freq;
+	u16 len;
+	u64 tsf;
+	u32 beacon_time;
+	u8 nic_type;
+	u16       Length;
+	//      u8        DataRate;      // In 0.5 Mbps
+	u8        SignalQuality; // in 0-100 index.
+	s32       RecvSignalPower; // Real power in dBm for this packet, no beautification and aggregation.
+	s8        RxPower; // in dBm Translate from PWdB
+	u8        SignalStrength; // in 0-100 index.
+	u16       bHwError:1;
+	u16       bCRC:1;
+	u16       bICV:1;
+	u16       bShortPreamble:1;
+	u16       Antenna:1;      //for rtl8185
+	u16       Decrypted:1;    //for rtl8185, rtl8187
+	u16       Wakeup:1;       //for rtl8185
+	u16       Reserved0:1;    //for rtl8185
+	u8        AGC;
+	u32       TimeStampLow;
+	u32       TimeStampHigh;
+	bool      bShift;
+	bool      bIsQosData;             // Added by Annie, 2005-12-22.
+	u8        UserPriority;
+
+	//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
+	//1Attention Please!!!<11n or 8190 specific code should be put below this line>
+	//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+	u8        RxDrvInfoSize;
+	u8        RxBufShift;
+	bool      bIsAMPDU;
+	bool      bFirstMPDU;
+	bool      bContainHTC;
+	bool      RxIs40MHzPacket;
+	u32       RxPWDBAll;
+	u8        RxMIMOSignalStrength[4];        // in 0~100 index
+	s8        RxMIMOSignalQuality[2];
+	bool      bPacketMatchBSSID;
+	bool      bIsCCK;
+	bool      bPacketToSelf;
+	//added by amy
+	u8*       virtual_address;
+	u16          packetlength;              // Total packet length: Must equal to sum of all FragLength
+	u16          fraglength;                        // FragLength should equal to PacketLength in non-fragment case
+	u16          fragoffset;                        // Data offset for this fragment
+	u16          ntotalfrag;
+	bool      	  bisrxaggrsubframe;
+	bool		  bPacketBeacon;	//cosa add for rssi
+	bool		  bToSelfBA;		//cosa add for rssi
+	char 	  cck_adc_pwdb[4];	//cosa add for rx path selection
+	u16		  Seq_Num;
+
+};
+
+/* 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_ENCRYPT       (1<<9)
+
+#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 SEC_ALG_NONE            0
+#define SEC_ALG_WEP             1
+#define SEC_ALG_TKIP            2
+#define SEC_ALG_CCMP            3
+
+#define WEP_KEYS 		4
+#define WEP_KEY_LEN		13
+#define SCM_KEY_LEN             32
+#define SCM_TEMPORAL_KEY_LENGTH 16
+
+struct ieee80211_security {
+	u16 active_key:2,
+	    enabled:1,
+	    auth_mode:2,
+	    auth_algo:4,
+	    unicast_uses_group:1,
+	    encrypt:1;
+	u8 key_sizes[WEP_KEYS];
+	u8 keys[WEP_KEYS][SCM_KEY_LEN];
+	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 ieee80211_mfie {
+	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_HOP_PARAMS = 8,
+	MFIE_TYPE_HOP_TABLE = 9,
+	MFIE_TYPE_REQUEST = 10,
+	MFIE_TYPE_CHALLENGE = 16,
+	MFIE_TYPE_POWER_CONSTRAINT = 32,
+	MFIE_TYPE_POWER_CAPABILITY = 33,
+	MFIE_TYPE_TPC_REQUEST = 34,
+	MFIE_TYPE_TPC_REPORT = 35,
+	MFIE_TYPE_SUPP_CHANNELS = 36,
+	MFIE_TYPE_CSA = 37,
+	MFIE_TYPE_MEASURE_REQUEST = 38,
+	MFIE_TYPE_MEASURE_REPORT = 39,
+	MFIE_TYPE_QUIET = 40,
+	MFIE_TYPE_IBSS_DFS = 41,
+	MFIE_TYPE_ERP = 42,
+	MFIE_TYPE_RSN = 48,
+	MFIE_TYPE_RATES_EX = 50,
+	MFIE_TYPE_HT_CAP= 45,
+	 MFIE_TYPE_HT_INFO= 61,
+	 MFIE_TYPE_AIRONET=133,
+	MFIE_TYPE_GENERIC = 221,
+	MFIE_TYPE_QOS_PARAMETER = 222,
+};
+
+/* Minimal header; can be used for passing 802.11 frames with sufficient
+ * information to determine what type of underlying data type is actually
+ * stored in the data. */
+struct ieee80211_hdr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_1addr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_2addr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_4addr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 addr4[ETH_ALEN];
+	u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addrqos {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 payload[0];
+	__le16 qos_ctl;
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_4addrqos {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 addr4[ETH_ALEN];
+	u8 payload[0];
+	__le16 qos_ctl;
+} __attribute__ ((packed));
+
+struct ieee80211_info_element {
+	u8 id;
+	u8 len;
+	u8 data[0];
+} __attribute__ ((packed));
+
+struct ieee80211_authentication {
+	struct ieee80211_hdr_3addr header;
+	__le16 algorithm;
+	__le16 transaction;
+	__le16 status;
+	/*challenge*/
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_disassoc {
+	struct ieee80211_hdr_3addr header;
+	__le16 reason;
+} __attribute__ ((packed));
+
+struct ieee80211_probe_request {
+	struct ieee80211_hdr_3addr header;
+	/* SSID, supported rates */
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_probe_response {
+	struct ieee80211_hdr_3addr header;
+	u32 time_stamp[2];
+	__le16 beacon_interval;
+	__le16 capability;
+	/* SSID, supported rates, FH params, DS params,
+	 * CF params, IBSS params, TIM (if beacon), RSN */
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+/* Alias beacon for probe_response */
+#define ieee80211_beacon ieee80211_probe_response
+
+struct ieee80211_assoc_request_frame {
+	struct ieee80211_hdr_3addr header;
+	__le16 capability;
+	__le16 listen_interval;
+	/* SSID, supported rates, RSN */
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_reassoc_request_frame {
+	struct ieee80211_hdr_3addr header;
+	__le16 capability;
+	__le16 listen_interval;
+	u8 current_ap[ETH_ALEN];
+	/* SSID, supported rates, RSN */
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_assoc_response_frame {
+	struct ieee80211_hdr_3addr header;
+	__le16 capability;
+	__le16 status;
+	__le16 aid;
+	struct ieee80211_info_element info_element[0]; /* supported rates */
+} __attribute__ ((packed));
+
+struct ieee80211_txb {
+	u8 nr_frags;
+	u8 encrypted;
+	u8 queue_index;
+	u8 rts_included;
+	u16 reserved;
+	__le16 frag_size;
+	__le16 payload_size;
+	struct sk_buff *fragments[0];
+};
+
+#define MAX_TX_AGG_COUNT		  16
+struct ieee80211_drv_agg_txb {
+	u8 nr_drv_agg_frames;
+	struct sk_buff *tx_agg_frames[MAX_TX_AGG_COUNT];
+}__attribute__((packed));
+
+#define MAX_SUBFRAME_COUNT 		  64
+struct ieee80211_rxb {
+	u8 nr_subframes;
+	struct sk_buff *subframes[MAX_SUBFRAME_COUNT];
+	u8 dst[ETH_ALEN];
+	u8 src[ETH_ALEN];
+}__attribute__((packed));
+
+typedef union _frameqos {
+	u16 shortdata;
+	u8  chardata[2];
+	struct {
+		u16 tid:4;
+		u16 eosp:1;
+		u16 ack_policy:2;
+		u16 reserved:1;
+		u16 txop:8;
+	}field;
+}frameqos,*pframeqos;
+
+/* 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                 161
+#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)
+
+/* QoS structure */
+#define NETWORK_HAS_QOS_PARAMETERS      (1<<3)
+#define NETWORK_HAS_QOS_INFORMATION     (1<<4)
+#define NETWORK_HAS_QOS_MASK            (NETWORK_HAS_QOS_PARAMETERS | \
+					 NETWORK_HAS_QOS_INFORMATION)
+/* 802.11h */
+#define NETWORK_HAS_POWER_CONSTRAINT    (1<<5)
+#define NETWORK_HAS_CSA                 (1<<6)
+#define NETWORK_HAS_QUIET               (1<<7)
+#define NETWORK_HAS_IBSS_DFS            (1<<8)
+#define NETWORK_HAS_TPC_REPORT          (1<<9)
+
+#define NETWORK_HAS_ERP_VALUE           (1<<10)
+
+#define QOS_QUEUE_NUM                   4
+#define QOS_OUI_LEN                     3
+#define QOS_OUI_TYPE                    2
+#define QOS_ELEMENT_ID                  221
+#define QOS_OUI_INFO_SUB_TYPE           0
+#define QOS_OUI_PARAM_SUB_TYPE          1
+#define QOS_VERSION_1                   1
+#define QOS_AIFSN_MIN_VALUE             2
+struct ieee80211_qos_information_element {
+	u8 elementID;
+	u8 length;
+	u8 qui[QOS_OUI_LEN];
+	u8 qui_type;
+	u8 qui_subtype;
+	u8 version;
+	u8 ac_info;
+} __attribute__ ((packed));
+
+struct ieee80211_qos_ac_parameter {
+	u8 aci_aifsn;
+	u8 ecw_min_max;
+	__le16 tx_op_limit;
+} __attribute__ ((packed));
+
+struct ieee80211_qos_parameter_info {
+	struct ieee80211_qos_information_element info_element;
+	u8 reserved;
+	struct ieee80211_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct ieee80211_qos_parameters {
+	__le16 cw_min[QOS_QUEUE_NUM];
+	__le16 cw_max[QOS_QUEUE_NUM];
+	u8 aifs[QOS_QUEUE_NUM];
+	u8 flag[QOS_QUEUE_NUM];
+	__le16 tx_op_limit[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct ieee80211_qos_data {
+	struct ieee80211_qos_parameters parameters;
+	int active;
+	int supported;
+	u8 param_count;
+	u8 old_param_count;
+};
+
+struct ieee80211_tim_parameters {
+	u8 tim_count;
+	u8 tim_period;
+} __attribute__ ((packed));
+
+//#else
+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 ((u32)type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
+}
+//added by amy for reorder
+static inline u8 Frame_QoSTID(u8* buf)
+{
+	struct ieee80211_hdr_3addr *hdr;
+	u16 fc;
+	hdr = (struct ieee80211_hdr_3addr *)buf;
+	fc = le16_to_cpu(hdr->frame_ctl);
+	return (u8)((frameqos*)(buf + (((fc & IEEE80211_FCTL_TODS)&&(fc & IEEE80211_FCTL_FROMDS))? 30 : 24)))->field.tid;
+}
+
+//added by amy for reorder
+
+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;
+	unsigned char CurrentShowTxate;
+	unsigned char last_packet_rate;
+	unsigned int txretrycount;
+};
+
+#define BEACON_PROBE_SSID_ID_POSITION 12
+
+struct ieee80211_info_element_hdr {
+	u8 id;
+	u8 len;
+} __attribute__ ((packed));
+
+/*
+ * 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 2 //1Mbps
+
+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 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
+
+//added by David for QoS 2006/6/30
+//#define WMM_Hang_8187
+#ifdef WMM_Hang_8187
+#undef WMM_Hang_8187
+#endif
+
+#define WME_AC_BK   0x00
+#define WME_AC_BE   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
+
+#define MAX_RECEIVE_BUFFER_SIZE 9100
+
+//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 */
+#define ETHERNET_HEADER_SIZE    14      /* length of two Ethernet address plus ether type*/
+
+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
+
+typedef struct _bss_ht{
+
+	bool				support_ht;
+
+	// HT related elements
+	u8					ht_cap_buf[32];
+	u16					ht_cap_len;
+	u8					ht_info_buf[32];
+	u16					ht_info_len;
+
+	HT_SPEC_VER			ht_spec_ver;
+	//HT_CAPABILITY_ELE			bdHTCapEle;
+	//HT_INFORMATION_ELE		bdHTInfoEle;
+
+	bool				aggregation;
+	bool				long_slot_time;
+}bss_ht, *pbss_ht;
+
+typedef enum _erp_t{
+	ERP_NonERPpresent	= 0x01,
+	ERP_UseProtection	= 0x02,
+	ERP_BarkerPreambleMode = 0x04,
+} erp_t;
+
+
+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;
+	struct ieee80211_qos_data qos_data;
+
+	//added by amy for LEAP
+	bool	bWithAironetIE;
+	bool	bCkipSupported;
+	bool	bCcxRmEnable;
+	u16 	CcxRmState[2];
+	// CCXv4 S59, MBSSID.
+	bool	bMBssidValid;
+	u8	MBssidMask;
+	u8	MBssid[6];
+	// CCX 2 S38, WLAN Device Version Number element. Annie, 2006-08-20.
+	bool	bWithCcxVerNum;
+	u8	BssCcxVerNumber;
+	/* 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;
+	u32 flags;
+	u32 last_associate;
+	u32 time_stamp[2];
+	u16 beacon_interval;
+	u16 listen_interval;
+	u16 atim_window;
+	u8  erp_value;
+	u8  wpa_ie[MAX_WPA_IE_LEN];
+	size_t wpa_ie_len;
+	u8  rsn_ie[MAX_WPA_IE_LEN];
+	size_t rsn_ie_len;
+
+	struct ieee80211_tim_parameters tim;
+	u8  dtim_period;
+	u8  dtim_data;
+	u32 last_dtim_sta_time[2];
+
+	//appeded for QoS
+	u8 wmm_info;
+	struct ieee80211_wmm_ac_param wmm_param[4];
+	u8 QoS_Enable;
+#ifdef THOMAS_TURBO
+	u8 Turbo_Enable;//enable turbo mode, added by thomas
+#endif
+#ifdef ENABLE_DOT11D
+	u16 CountryIeLen;
+	u8 CountryIeBuf[MAX_IE_LEN];
+#endif
+	// HT Related, by amy, 2008.04.29
+	BSS_HT	bssht;
+	// Add to handle broadcom AP management frame CCK rate.
+	bool broadcom_cap_exist;
+	bool ralink_cap_exist;
+	bool atheros_cap_exist;
+	bool cisco_cap_exist;
+	bool unknown_cap_exist;
+//	u8	berp_info;
+	bool	berp_info_valid;
+	bool buseprotection;
+	//put at the end of the structure.
+	struct list_head list;
+};
+
+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 authentcated
+	 * 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)
+#define CFG_IEEE80211_RTS (1<<2)
+
+#define IEEE80211_24GHZ_MIN_CHANNEL 1
+#define IEEE80211_24GHZ_MAX_CHANNEL 14
+#define IEEE80211_24GHZ_CHANNELS (IEEE80211_24GHZ_MAX_CHANNEL - \
+				  IEEE80211_24GHZ_MIN_CHANNEL + 1)
+
+#define IEEE80211_52GHZ_MIN_CHANNEL 34
+#define IEEE80211_52GHZ_MAX_CHANNEL 165
+#define IEEE80211_52GHZ_CHANNELS (IEEE80211_52GHZ_MAX_CHANNEL - \
+				  IEEE80211_52GHZ_MIN_CHANNEL + 1)
+
+
+
+typedef struct tx_pending_t{
+	int frag;
+	struct ieee80211_txb *txb;
+}tx_pending_t;
+
+typedef struct _bandwidth_autoswitch
+{
+	long threshold_20Mhzto40Mhz;
+	long	threshold_40Mhzto20Mhz;
+	bool bforced_tx20Mhz;
+	bool bautoswitch_enable;
+}bandwidth_autoswitch,*pbandwidth_autoswitch;
+
+
+//added by amy for order
+
+#define REORDER_WIN_SIZE	128
+#define REORDER_ENTRY_NUM	128
+typedef struct _RX_REORDER_ENTRY
+{
+	struct list_head	List;
+	u16			SeqNum;
+	struct ieee80211_rxb* prxb;
+} RX_REORDER_ENTRY, *PRX_REORDER_ENTRY;
+//added by amy for order
+typedef enum _Fsync_State{
+	Default_Fsync,
+	HW_Fsync,
+	SW_Fsync
+}Fsync_State;
+
+// Power save mode configured.
+typedef	enum _RT_PS_MODE
+{
+	eActive,	// Active/Continuous access.
+	eMaxPs,		// Max power save mode.
+	eFastPs		// Fast power save mode.
+}RT_PS_MODE;
+
+typedef enum _IPS_CALLBACK_FUNCION
+{
+	IPS_CALLBACK_NONE = 0,
+	IPS_CALLBACK_MGNT_LINK_REQUEST = 1,
+	IPS_CALLBACK_JOIN_REQUEST = 2,
+}IPS_CALLBACK_FUNCION;
+
+typedef enum _RT_JOIN_ACTION{
+	RT_JOIN_INFRA   = 1,
+	RT_JOIN_IBSS  = 2,
+	RT_START_IBSS = 3,
+	RT_NO_ACTION  = 4,
+}RT_JOIN_ACTION;
+
+typedef struct _IbssParms{
+	u16   atimWin;
+}IbssParms, *PIbssParms;
+#define MAX_NUM_RATES	264 // Max num of support rates element: 8,  Max num of ext. support rate: 255. 061122, by rcnjko.
+
+// RF state.
+typedef	enum _RT_RF_POWER_STATE
+{
+	eRfOn,
+	eRfSleep,
+	eRfOff
+}RT_RF_POWER_STATE;
+
+typedef struct _RT_POWER_SAVE_CONTROL
+{
+
+	//
+	// Inactive Power Save(IPS) : Disable RF when disconnected
+	//
+	bool				bInactivePs;
+	bool				bIPSModeBackup;
+	bool				bSwRfProcessing;
+	RT_RF_POWER_STATE	eInactivePowerState;
+	struct work_struct 	InactivePsWorkItem;
+	struct timer_list	InactivePsTimer;
+
+	// Return point for join action
+	IPS_CALLBACK_FUNCION	ReturnPoint;
+
+	// Recored Parameters for rescheduled JoinRequest
+	bool				bTmpBssDesc;
+	RT_JOIN_ACTION		tmpJoinAction;
+	struct ieee80211_network tmpBssDesc;
+
+	// Recored Parameters for rescheduled MgntLinkRequest
+	bool				bTmpScanOnly;
+	bool				bTmpActiveScan;
+	bool				bTmpFilterHiddenAP;
+	bool				bTmpUpdateParms;
+	u8					tmpSsidBuf[33];
+	OCTET_STRING			tmpSsid2Scan;
+	bool				bTmpSsid2Scan;
+	u8					tmpNetworkType;
+	u8					tmpChannelNumber;
+	u16					tmpBcnPeriod;
+	u8					tmpDtimPeriod;
+	u16					tmpmCap;
+	OCTET_STRING			tmpSuppRateSet;
+	u8					tmpSuppRateBuf[MAX_NUM_RATES];
+	bool				bTmpSuppRate;
+	IbssParms				tmpIbpm;
+	bool				bTmpIbpm;
+
+	//
+	// Leisre Poswer Save : Disable RF if connected but traffic is not busy
+	//
+	bool				bLeisurePs;
+
+}RT_POWER_SAVE_CONTROL,*PRT_POWER_SAVE_CONTROL;
+
+typedef u32 RT_RF_CHANGE_SOURCE;
+#define RF_CHANGE_BY_SW BIT31
+#define RF_CHANGE_BY_HW BIT30
+#define RF_CHANGE_BY_PS BIT29
+#define RF_CHANGE_BY_IPS BIT28
+#define RF_CHANGE_BY_INIT	0	// Do not change the RFOff reason. Defined by Bruce, 2008-01-17.
+
+#ifdef ENABLE_DOT11D
+typedef 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,
+	COUNTRY_CODE_MIC,
+	COUNTRY_CODE_GLOBAL_DOMAIN
+}country_code_type_t;
+#endif
+
+#define RT_MAX_LD_SLOT_NUM	10
+typedef struct _RT_LINK_DETECT_T{
+
+	u32				NumRecvBcnInPeriod;
+	u32				NumRecvDataInPeriod;
+
+	u32				RxBcnNum[RT_MAX_LD_SLOT_NUM];	// number of Rx beacon / CheckForHang_period  to determine link status
+	u32				RxDataNum[RT_MAX_LD_SLOT_NUM];	// number of Rx data / CheckForHang_period  to determine link status
+	u16				SlotNum;	// number of CheckForHang period to determine link status
+	u16				SlotIndex;
+
+	u32				NumTxOkInPeriod;
+	u32				NumRxOkInPeriod;
+	bool				bBusyTraffic;
+}RT_LINK_DETECT_T, *PRT_LINK_DETECT_T;
+
+
+struct ieee80211_device {
+	struct net_device *dev;
+	struct ieee80211_security sec;
+
+	//hw security related
+//	u8 hwsec_support; //support?
+	u8 hwsec_active;  //hw security active.
+	bool is_silent_reset;
+	bool ieee_up;
+	//added by amy
+	bool bSupportRemoteWakeUp;
+	RT_PS_MODE	dot11PowerSaveMode; // Power save mode configured.
+	bool actscanning;
+	bool beinretry;
+	RT_RF_POWER_STATE		eRFPowerState;
+	RT_RF_CHANGE_SOURCE	RfOffReason;
+	bool is_set_key;
+	//11n spec related I wonder if These info structure need to be moved out of ieee80211_device
+
+	//11n HT below
+	PRT_HIGH_THROUGHPUT	pHTInfo;
+	//struct timer_list		SwBwTimer;
+//	spinlock_t chnlop_spinlock;
+	spinlock_t bw_spinlock;
+
+	spinlock_t reorder_spinlock;
+	// for HT operation rate set.  we use this one for HT data rate to seperate different descriptors
+	//the way fill this is the same as in the IE
+	u8	Regdot11HTOperationalRateSet[16];		//use RATR format
+	u8	dot11HTOperationalRateSet[16];		//use RATR format
+	u8	RegHTSuppRateSet[16];
+	u8				HTCurrentOperaRate;
+	u8				HTHighestOperaRate;
+	//wb added for rate operation mode to firmware
+	u8	bTxDisableRateFallBack;
+	u8 	bTxUseDriverAssingedRate;
+	atomic_t	atm_chnlop;
+	atomic_t	atm_swbw;
+//	u8	HTHighestOperaRate;
+//	u8 	HTCurrentOperaRate;
+
+	// 802.11e and WMM Traffic Stream Info (TX)
+	struct list_head		Tx_TS_Admit_List;
+	struct list_head		Tx_TS_Pending_List;
+	struct list_head		Tx_TS_Unused_List;
+	TX_TS_RECORD		TxTsRecord[TOTAL_TS_NUM];
+	// 802.11e and WMM Traffic Stream Info (RX)
+	struct list_head		Rx_TS_Admit_List;
+	struct list_head		Rx_TS_Pending_List;
+	struct list_head		Rx_TS_Unused_List;
+	RX_TS_RECORD		RxTsRecord[TOTAL_TS_NUM];
+//#ifdef TO_DO_LIST
+	RX_REORDER_ENTRY	RxReorderEntry[128];
+	struct list_head		RxReorder_Unused_List;
+//#endif
+	// Qos related. Added by Annie, 2005-11-01.
+//	PSTA_QOS			pStaQos;
+	u8				ForcedPriority;		// Force per-packet priority 1~7. (default: 0, not to force it.)
+
+
+	/* 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_*) */
+	struct iw_spy_data spy_data;
+
+	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 auth_mode;
+	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_encrypt_msdu;
+	int host_decrypt;
+	/* host performs multicast decryption */
+	int host_mc_decrypt;
+
+	/* host should strip IV and ICV from protected frames */
+	/* meaningful only when hardware decryption is being used */
+	int host_strip_iv_icv;
+
+	int host_open_frag;
+	int host_build_iv;
+	int ieee802_1x; /* is IEEE 802.1X used */
+
+	/* WPA data */
+	bool bHalfWirelessN24GMode;
+	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 group_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 crypt_quiesced;
+
+	int bcrx_sta_key; /* use individual keys to override default keys even
+			   * with RX of broad/multicast frames */
+
+	/* Fragmentation structures */
+	// each streaming contain a entry
+	struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN];
+	unsigned int frag_next_idx[17];
+	u16 fts; /* Fragmentation Threshold */
+#define DEFAULT_RTS_THRESHOLD 2346U
+#define MIN_RTS_THRESHOLD 1
+#define MAX_RTS_THRESHOLD 2346U
+	u16 rts; /* RTS threshold */
+
+	/* Association info */
+	u8 bssid[ETH_ALEN];
+
+	/* 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 reg_mode;
+	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;
+
+	int perfect_rssi;
+	int worst_rssi;
+
+	u16 prev_seq_ctl;       /* used to drop duplicate frames */
+
+	/* map of allowed channels. 0 is dummy */
+	// FIXME: remeber to default to a basic channel plan depending of the PHY type
+#ifdef ENABLE_DOT11D
+	void* pDot11dInfo;
+	bool bGlobalDomain;
+#else
+	int channel_map[MAX_CHANNEL_NUMBER+1];
+#endif
+	int rate;       /* current rate */
+	int basic_rate;
+	//FIXME: pleace 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;
+	int ps_period;
+	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;
+	/* set on initialization */
+	u8  qos_support;
+
+	/* 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;
+//{ added for rtl819x
+#define IEEE80211_QUEUE_LIMIT 128
+	u8 AsocRetryCount;
+	unsigned int hw_header;
+	struct sk_buff_head skb_waitQ[MAX_QUEUE_SIZE];
+	struct sk_buff_head  skb_aggQ[MAX_QUEUE_SIZE];
+	struct sk_buff_head  skb_drv_aggQ[MAX_QUEUE_SIZE];
+	u32	sta_edca_param[4];
+	bool aggregation;
+	// Enable/Disable Rx immediate BA capability.
+	bool enable_rx_imm_BA;
+	bool bibsscoordinator;
+
+	//+by amy for DM ,080515
+	//Dynamic Tx power for near/far range enable/Disable  , by amy , 2008-05-15
+	bool	bdynamic_txpower_enable;
+
+	bool bCTSToSelfEnable;
+	u8 	CTSToSelfTH;
+
+	u32 	fsync_time_interval;
+	u32	fsync_rate_bitmap;
+	u8	fsync_rssi_threshold;
+	bool	bfsync_enable;
+
+	u8	fsync_multiple_timeinterval;		// FsyncMultipleTimeInterval * FsyncTimeInterval
+	u32	fsync_firstdiff_ratethreshold;		// low threshold
+	u32	fsync_seconddiff_ratethreshold;	 // decrease threshold
+	Fsync_State			fsync_state;
+	bool		bis_any_nonbepkts;
+	//20Mhz 40Mhz AutoSwitch Threshold
+	bandwidth_autoswitch bandwidth_auto_switch;
+	//for txpower tracking
+	bool FwRWRF;
+
+	//added by amy for AP roaming
+	RT_LINK_DETECT_T	LinkDetectInfo;
+	//added by amy for ps
+	RT_POWER_SAVE_CONTROL	PowerSaveControl;
+//}
+	/* 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_procedure_wq;
+	struct delayed_work softmac_scan_wq;
+	struct delayed_work associate_retry_wq;
+	 struct delayed_work start_ibss_wq;
+	struct work_struct wx_sync_scan_wq;
+	struct workqueue_struct *wq;
+        // Qos related. Added by Annie, 2005-11-01.
+        //STA_QOS  StaQos;
+
+        //u32 STA_EDCA_PARAM[4];
+	//CHANNEL_ACCESS_SETTING ChannelAccessSetting;
+
+
+	/* 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);
+        int (*is_queue_full) (struct net_device * dev, int pri);
+
+        int (*handle_management) (struct net_device * dev,
+                                  struct ieee80211_network * network, u16 type);
+        int (*is_qos_active) (struct net_device *dev, struct sk_buff *skb);
+
+	/* Softmac-generated frames (mamagement) 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 fucntion 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. I 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 swithced 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 swithcing to ad-hoc mode
+	 * or in behalf of iwlist scan when the card is associated
+	 * and root user ask for a scan.
+	 * the fucntion stop_scan should stop both the syncro and
+	 * background scanning and can sleep.
+	 * The fucntion 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,u16 tx_rate);
+	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);
+	int (*handle_beacon) (struct net_device * dev, struct ieee80211_beacon * beacon, struct ieee80211_network * network);
+	int (*handle_assoc_response) (struct net_device * dev, struct ieee80211_assoc_response_frame * resp, struct ieee80211_network * network);
+
+
+	/* check whether Tx hw resouce available */
+	short (*check_nic_enough_desc)(struct net_device *dev, int queue_index);
+	//added by wb for HT related
+//	void (*SwChnlByTimerHandler)(struct net_device *dev, int channel);
+	void (*SetBWModeHandler)(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset);
+//	void (*UpdateHalRATRTableHandler)(struct net_device* dev, u8* pMcsRate);
+	bool (*GetNmodeSupportBySecCfg)(struct net_device* dev);
+	void (*SetWirelessMode)(struct net_device* dev, u8 wireless_mode);
+	bool (*GetHalfNmodeSupportByAPsHandler)(struct net_device* dev);
+	void (*InitialGainHandler)(struct net_device *dev, u8 Operation);
+
+	/* 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_N_24G 		  (1<<4)
+#define	IEEE_N_5G		  (1<<5)
+#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 respones 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;
+}
+
+extern 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;
+}
+
+extern 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;
+}
+
+extern inline int ieee80211_get_hdrlen(u16 fc)
+{
+	int hdrlen = IEEE80211_3ADDR_LEN;
+
+	switch (WLAN_FC_GET_TYPE(fc)) {
+	case IEEE80211_FTYPE_DATA:
+		if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
+			hdrlen = IEEE80211_4ADDR_LEN; /* 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 = IEEE80211_1ADDR_LEN;
+			break;
+		default:
+			hdrlen = IEEE80211_2ADDR_LEN;
+			break;
+		}
+		break;
+	}
+
+	return hdrlen;
+}
+
+static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr)
+{
+	switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) {
+	case IEEE80211_1ADDR_LEN:
+		return ((struct ieee80211_hdr_1addr *)hdr)->payload;
+	case IEEE80211_2ADDR_LEN:
+		return ((struct ieee80211_hdr_2addr *)hdr)->payload;
+	case IEEE80211_3ADDR_LEN:
+		return ((struct ieee80211_hdr_3addr *)hdr)->payload;
+	case IEEE80211_4ADDR_LEN:
+		return ((struct ieee80211_hdr_4addr *)hdr)->payload;
+	}
+	return NULL;
+}
+
+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_is_cck_rate(u8 rate)
+{
+	switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
+	case IEEE80211_CCK_RATE_1MB:
+	case IEEE80211_CCK_RATE_2MB:
+	case IEEE80211_CCK_RATE_5MB:
+	case IEEE80211_CCK_RATE_11MB:
+		return 1;
+	}
+	return 0;
+}
+
+
+/* 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_xmit(struct sk_buff *skb,
+			  struct net_device *dev);
+extern void ieee80211_txb_free(struct ieee80211_txb *);
+
+
+/* ieee80211_rx.c */
+extern int ieee80211_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);
+#if WIRELESS_EXT >= 18
+extern int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee,
+			    struct iw_request_info *info,
+			    union iwreq_data* wrqu, char *extra);
+extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
+			    struct iw_request_info *info,
+			    union iwreq_data* wrqu, char *extra);
+extern int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
+			       struct iw_request_info *info,
+			       struct iw_param *data, char *extra);
+extern int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra);
+#endif
+extern int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len);
+
+/* ieee80211_softmac.c */
+extern short ieee80211_is_54g(struct ieee80211_network net);
+extern short ieee80211_is_shortslot(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);
+
+void SendDisassociation(struct ieee80211_device *ieee, u8* asSta, u8 asRsn);
+extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee);
+
+extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
+extern void notify_wx_assoc_event(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_wake_queue(struct ieee80211_device *ieee);
+extern void ieee80211_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 softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee);
+
+/* 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 ieee80211_device *ieee);
+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 int ieee80211_wx_set_rts(struct ieee80211_device *ieee,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra);
+
+extern int ieee80211_wx_get_rts(struct ieee80211_device *ieee,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra);
+//HT
+#define MAX_RECEIVE_BUFFER_SIZE 9100  //
+extern void HTDebugHTCapability(u8* CapIE, u8* TitleString );
+extern void HTDebugHTInfo(u8*  InfoIE, u8* TitleString);
+
+void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET    Offset);
+extern void HTUpdateDefaultSetting(struct ieee80211_device* ieee);
+extern void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u8* len, u8 isEncrypt);
+extern void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* len, u8 isEncrypt);
+extern void HTConstructRT2RTAggElement(struct ieee80211_device* ieee, u8* posRT2RTAgg, u8* len);
+extern void HTOnAssocRsp(struct ieee80211_device *ieee);
+extern void HTInitializeHTInfo(struct ieee80211_device* ieee);
+extern void HTInitializeBssDesc(PBSS_HT pBssHT);
+extern void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork);
+extern void HTUpdateSelfAndPeerSetting(struct ieee80211_device* ieee,   struct ieee80211_network * pNetwork);
+extern u8 HTGetHighestMCSRate(struct ieee80211_device* ieee, u8* pMCSRateSet, u8* pMCSFilter);
+extern u8 MCS_FILTER_ALL[];
+extern u16 MCS_DATA_RATE[2][2][77] ;
+extern u8 HTCCheck(struct ieee80211_device* ieee, u8*   pFrame);
+//extern void HTSetConnectBwModeCallback(unsigned long data);
+extern void HTResetIOTSetting(PRT_HIGH_THROUGHPUT  pHTInfo);
+extern bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee);
+extern u16 HTHalfMcsToDataRate(struct ieee80211_device* ieee,  u8      nMcsRate);
+extern u16 HTMcsToDataRate( struct ieee80211_device* ieee, u8 nMcsRate);
+extern u16  TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate);
+//function in BAPROC.c
+extern int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb);
+extern int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb);
+extern int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb);
+extern void TsInitAddBA( struct ieee80211_device* ieee, PTX_TS_RECORD   pTS, u8 Policy, u8 bOverwritePending);
+extern void TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect);
+extern void BaSetupTimeOut(unsigned long data);
+extern void TxBaInactTimeout(unsigned long data);
+extern void RxBaInactTimeout(unsigned long data);
+extern void ResetBaEntry( PBA_RECORD pBA);
+//function in TS.c
+extern bool GetTs(
+	struct ieee80211_device*        ieee,
+	PTS_COMMON_INFO                 *ppTS,
+	u8*                             Addr,
+	u8                              TID,
+	TR_SELECT                       TxRxSelect,  //Rx:1, Tx:0
+	bool                            bAddNewTs
+	);
+extern void TSInitialize(struct ieee80211_device *ieee);
+extern  void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD   pTxTS);
+extern void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr);
+extern void RemoveAllTS(struct ieee80211_device* ieee);
+void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee);
+
+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;
+}
+
+/* For the function is more related to hardware setting, it's better to use the
+ * ieee handler to refer to it.
+ */
+extern short check_nic_enough_desc(struct net_device *dev, int queue_index);
+extern int ieee80211_data_xmit(struct sk_buff *skb, struct net_device *dev);
+extern int ieee80211_parse_info_param(struct ieee80211_device *ieee,
+		struct ieee80211_info_element *info_element,
+		u16 length,
+		struct ieee80211_network *network,
+		struct ieee80211_rx_stats *stats);
+
+void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8  index);
+#define RT_ASOC_RETRY_LIMIT	5
+#endif /* IEEE80211_H */
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c
new file mode 100644
index 0000000..521e7b9
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c
@@ -0,0 +1,244 @@
+/*
+ * 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.
+ *
+ */
+
+//#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <asm/string.h>
+#include <asm/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)) {
+		printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
+		       "deletion list\n", ieee->dev->name);
+		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 = kmalloc(sizeof(*alg), GFP_KERNEL);
+	if (alg == NULL)
+		return -ENOMEM;
+
+	memset(alg, 0, sizeof(*alg));
+	alg->ops = ops;
+
+	spin_lock_irqsave(&hcrypt->lock, flags);
+	list_add(&alg->list, &hcrypt->algs);
+	spin_unlock_irqrestore(&hcrypt->lock, flags);
+
+	printk(KERN_DEBUG "ieee80211_crypt: 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) {
+		printk(KERN_DEBUG "ieee80211_crypt: 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 __init ieee80211_crypto_init(void)
+{
+	int ret = -ENOMEM;
+
+	hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL);
+	if (!hcrypt)
+		goto out;
+
+	memset(hcrypt, 0, sizeof(*hcrypt));
+	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 __exit ieee80211_crypto_deinit(void)
+{
+	struct list_head *ptr, *n;
+
+	if (hcrypt == NULL)
+		return;
+
+	for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
+	     ptr = n, n = ptr->next) {
+		struct ieee80211_crypto_alg *alg =
+			(struct ieee80211_crypto_alg *) ptr;
+		list_del(ptr);
+		printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
+		       "'%s' (deinit)\n", alg->ops->name);
+		kfree(alg);
+	}
+
+	kfree(hcrypt);
+}
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.h b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.h
new file mode 100644
index 0000000..b58a3bc
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.h
@@ -0,0 +1,86 @@
+/*
+ * 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/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c
new file mode 100644
index 0000000..0b33bf4
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c
@@ -0,0 +1,480 @@
+/*
+ * 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.
+ */
+
+//#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.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 <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];
+};
+
+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 = kmalloc(sizeof(*priv), GFP_ATOMIC);
+	if (priv == NULL)
+		goto fail;
+	memset(priv, 0, sizeof(*priv));
+	priv->key_idx = key_idx;
+
+       priv->tfm = (void*)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
+	if (IS_ERR(priv->tfm)) {
+		printk(KERN_DEBUG "ieee80211_crypt_ccmp: 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));
+	*/
+	// fixed by David :2006.9.6
+	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;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+
+	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;
+//	mic = skb_put(skb, CCMP_MIC_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;
+	if (!tcb_desc->bHwSec)
+	{
+		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;
+
+		//mic is moved to here by john
+		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;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	u8 pn[6];
+
+	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()) {
+			printk(KERN_DEBUG "CCMP: received packet without ExtIV"
+			       " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
+		}
+		key->dot11RSNAStatsCCMPFormatErrors++;
+		return -2;
+	}
+	keyidx >>= 6;
+	if (key->key_idx != keyidx) {
+		printk(KERN_DEBUG "CCMP: 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()) {
+			printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT
+			       " with keyid=%d that does not have a configured"
+			       " key\n", MAC_ARG(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()) {
+			printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT
+			       " previous PN %02x%02x%02x%02x%02x%02x "
+			       "received PN %02x%02x%02x%02x%02x%02x\n",
+			       MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn),
+			       MAC_ARG(pn));
+		}
+		key->dot11RSNAStatsCCMPReplays++;
+		return -4;
+	}
+	if (!tcb_desc->bHwSec)
+	{
+		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;
+
+
+		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()) {
+				printk(KERN_DEBUG "CCMP: decrypt failed: STA="
+				MAC_FMT "\n", MAC_ARG(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=%02x%02x%02x%02x%02x%02x "
+		     "rx_pn=%02x%02x%02x%02x%02x%02x "
+		     "format_errors=%d replays=%d decrypt_errors=%d\n",
+		     ccmp->key_idx, ccmp->key_set,
+		     MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn),
+		     ccmp->dot11RSNAStatsCCMPFormatErrors,
+		     ccmp->dot11RSNAStatsCCMPReplays,
+		     ccmp->dot11RSNAStatsCCMPDecryptErrors);
+
+	return p;
+}
+
+void ieee80211_ccmp_null(void)
+{
+//    printk("============>%s()\n", __FUNCTION__);
+	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 __init ieee80211_crypto_ccmp_init(void)
+{
+	return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
+}
+
+void __exit ieee80211_crypto_ccmp_exit(void)
+{
+	ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
+}
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c
new file mode 100644
index 0000000..841b999
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c
@@ -0,0 +1,780 @@
+/*
+ * 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/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.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;
+
+	/* 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 = kmalloc(sizeof(*priv), GFP_ATOMIC);
+	if (priv == NULL)
+		goto fail;
+	memset(priv, 0, sizeof(*priv));
+	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;
+		int len;
+	u8 *pos;
+	struct ieee80211_hdr_4addr *hdr;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4};
+	int ret = 0;
+	u8 rc4key[16],  *icv;
+	u32 crc;
+	struct scatterlist sg;
+
+	if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
+	    skb->len < hdr_len)
+		return -1;
+
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+
+	if (!tcb_desc->bHwSec)
+	{
+		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);
+	}
+	else
+	tkey->tx_phase1_done = 1;
+
+
+	len = skb->len - hdr_len;
+	pos = skb_push(skb, 8);
+	memmove(pos, pos + 8, hdr_len);
+	pos += hdr_len;
+
+	if (tcb_desc->bHwSec)
+	{
+		*pos++ = Hi8(tkey->tx_iv16);
+		*pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F;
+		*pos++ = Lo8(tkey->tx_iv16);
+	}
+	else
+	{
+		*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;
+
+	if (!tcb_desc->bHwSec)
+	{
+		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++;
+	}
+
+	if (!tcb_desc->bHwSec)
+		return ret;
+	else
+		return 0;
+
+
+}
+
+static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
+{
+	struct ieee80211_tkip_data *tkey = priv;
+	u8 keyidx, *pos;
+	u32 iv32;
+	u16 iv16;
+	struct ieee80211_hdr_4addr *hdr;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	struct blkcipher_desc desc = {.tfm = tkey->rx_tfm_arc4};
+	u8 rc4key[16];
+	u8 icv[4];
+	u32 crc;
+	struct scatterlist sg;
+	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 " MAC_FMT "\n", MAC_ARG(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 " MAC_FMT
+			       " with keyid=%d that does not have a configured"
+			       " key\n", MAC_ARG(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 (!tcb_desc->bHwSec)
+	{
+		if (iv32 < tkey->rx_iv32 ||
+		(iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
+			if (net_ratelimit()) {
+				printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
+				" previous TSC %08x%04x received TSC "
+				"%08x%04x\n", MAC_ARG(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 " MAC_FMT "\n",
+						MAC_ARG(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="
+				MAC_FMT "\n", MAC_ARG(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);
+
+	// { david, 2006.9.1
+	// fix the wpa process with wmm enabled.
+	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);
+	// { david, 2006.9.1
+	// fix the wpa process with wmm enabled.
+	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 " MAC_FMT " keyidx=%d\n",
+		       skb->dev ? skb->dev->name : "N/A", MAC_ARG(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 __init ieee80211_crypto_tkip_init(void)
+{
+	return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
+}
+
+void __exit ieee80211_crypto_tkip_exit(void)
+{
+	ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
+}
+
+void ieee80211_tkip_null(void)
+{
+//    printk("============>%s()\n", __FUNCTION__);
+	return;
+}
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c
new file mode 100644
index 0000000..61ad11c
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c
@@ -0,0 +1,297 @@
+/*
+ * 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.
+ */
+
+//#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/skbuff.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: 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 = kmalloc(sizeof(*priv), GFP_ATOMIC);
+	if (priv == NULL)
+		goto fail;
+	memset(priv, 0, sizeof(*priv));
+	priv->key_idx = keyidx;
+
+	priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
+	if (IS_ERR(priv->tx_tfm)) {
+		printk(KERN_DEBUG "ieee80211_crypt_wep: 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)) {
+		printk(KERN_DEBUG "ieee80211_crypt_wep: 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;
+	u32 klen, len;
+	u8 key[WEP_KEY_LEN + 3];
+	u8 *pos;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	struct blkcipher_desc desc = {.tfm = wep->tx_tfm};
+	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);
+
+	if (!tcb_desc->bHwSec)
+	{
+
+		/* 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);
+	}
+
+	return 0;
+}
+
+
+/* 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;
+	u32  klen, plen;
+	u8 key[WEP_KEY_LEN + 3];
+	u8 keyidx, *pos;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	struct blkcipher_desc desc = {.tfm = wep->rx_tfm};
+	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;
+
+	if (!tcb_desc->bHwSec)
+	{
+		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 __init ieee80211_crypto_wep_init(void)
+{
+	return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
+}
+
+void __exit ieee80211_crypto_wep_exit(void)
+{
+	ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
+}
+
+void ieee80211_wep_null(void)
+{
+//	printk("============>%s()\n", __FUNCTION__);
+	return;
+}
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c
new file mode 100644
index 0000000..7a8690f
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c
@@ -0,0 +1,324 @@
+/*******************************************************************************
+
+  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/version.h>
+#include <linux/wireless.h>
+#include <linux/etherdevice.h>
+#include <asm/uaccess.h>
+#include <net/arp.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 = kmalloc(
+		MAX_NETWORK_COUNT * sizeof(struct ieee80211_network),
+		GFP_KERNEL);
+	if (!ieee->networks) {
+		printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
+		       ieee->dev->name);
+		return -ENOMEM;
+	}
+
+	memset(ieee->networks, 0,
+	       MAX_NETWORK_COUNT * sizeof(struct ieee80211_network));
+
+	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);
+	memset(ieee, 0, sizeof(struct ieee80211_device)+sizeof_priv);
+	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);
+	spin_lock_init(&ieee->bw_spinlock);
+	spin_lock_init(&ieee->reorder_spinlock);
+	//added by WB
+	atomic_set(&(ieee->atm_chnlop), 0);
+	atomic_set(&(ieee->atm_swbw), 0);
+
+	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;
+	//ieee->hwsec_support = 1; //defalt support hw security. //use module_param instead.
+	ieee->hwsec_active = 0; //disable hwsec, switch it on when necessary.
+
+	ieee80211_softmac_init(ieee);
+
+	ieee->pHTInfo = (RT_HIGH_THROUGHPUT*)kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL);
+	if (ieee->pHTInfo == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for HTInfo\n");
+		return NULL;
+	}
+	HTUpdateDefaultSetting(ieee);
+	HTInitializeHTInfo(ieee); //may move to other place.
+	TSInitialize(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;
+//	del_timer_sync(&ieee->SwBwTimer);
+	if (ieee->pHTInfo != NULL)
+	{
+		kfree(ieee->pHTInfo);
+		ieee->pHTInfo = NULL;
+	}
+	RemoveAllTS(ieee);
+	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);
+	free_netdev(dev);
+}
+
+#ifdef CONFIG_IEEE80211_DEBUG
+
+u32 ieee80211_debug_level = 0;
+static int debug = \
+	//		    IEEE80211_DL_INFO	|
+	//		    IEEE80211_DL_WX	|
+	//		    IEEE80211_DL_SCAN	|
+	//		    IEEE80211_DL_STATE	|
+	//		    IEEE80211_DL_MGMT	|
+	//		    IEEE80211_DL_FRAG	|
+	//		    IEEE80211_DL_EAP	|
+	//		    IEEE80211_DL_DROP	|
+	//		    IEEE80211_DL_TX	|
+	//		    IEEE80211_DL_RX	|
+			    //IEEE80211_DL_QOS    |
+	//		    IEEE80211_DL_HT 	|
+	//		    IEEE80211_DL_TS	|
+//			    IEEE80211_DL_BA 	|
+	//		    IEEE80211_DL_REORDER|
+//			    IEEE80211_DL_TRACE  |
+			    //IEEE80211_DL_DATA	|
+			    IEEE80211_DL_ERR	  //awayls open this flags to show error out
+			    ;
+struct proc_dir_entry *ieee80211_proc = NULL;
+
+static int show_debug_level(char *page, char **start, off_t offset,
+			    int count, int *eof, void *data)
+{
+	return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
+}
+
+static int store_debug_level(struct file *file, const char *buffer,
+			     unsigned long count, void *data)
+{
+	char buf[] = "0x00000000";
+	unsigned long len = min(sizeof(buf) - 1, count);
+	char *p = (char *)buf;
+	unsigned long val;
+
+	if (copy_from_user(buf, buffer, len))
+		return count;
+	buf[len] = 0;
+	if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
+		p++;
+		if (p[0] == 'x' || p[0] == 'X')
+			p++;
+		val = simple_strtoul(p, &p, 16);
+	} else
+		val = simple_strtoul(p, &p, 10);
+	if (p == buf)
+		printk(KERN_INFO DRV_NAME
+		       ": %s is not in hex or decimal form.\n", buf);
+	else
+		ieee80211_debug_level = val;
+
+	return strnlen(buf, count);
+}
+
+int __init ieee80211_debug_init(void)
+{
+	struct proc_dir_entry *e;
+
+	ieee80211_debug_level = debug;
+
+	ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net);
+	if (ieee80211_proc == NULL) {
+		IEEE80211_ERROR("Unable to create " DRV_NAME
+				" proc directory\n");
+		return -EIO;
+	}
+	e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
+			      ieee80211_proc);
+	if (!e) {
+		remove_proc_entry(DRV_NAME, init_net.proc_net);
+		ieee80211_proc = NULL;
+		return -EIO;
+	}
+	e->read_proc = show_debug_level;
+	e->write_proc = store_debug_level;
+	e->data = NULL;
+
+	return 0;
+}
+
+void __exit ieee80211_debug_exit(void)
+{
+	if (ieee80211_proc) {
+		remove_proc_entry("debug_level", ieee80211_proc);
+		remove_proc_entry(DRV_NAME, init_net.proc_net);
+		ieee80211_proc = NULL;
+	}
+}
+
+#include <linux/moduleparam.h>
+module_param(debug, int, 0444);
+MODULE_PARM_DESC(debug, "debug output mask");
+#endif
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
new file mode 100644
index 0000000..0e003c5
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
@@ -0,0 +1,2668 @@
+/*
+ * 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 <andreamrl@tiscali.it>
+
+  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/version.h>
+#include <linux/wireless.h>
+#include <linux/etherdevice.h>
+#include <asm/uaccess.h>
+#include <linux/ctype.h>
+
+#include "ieee80211.h"
+#ifdef ENABLE_DOT11D
+#include "dot11d.h"
+#endif
+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_QCTL_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_QCTL_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_QCTL_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_QCTL_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)
+{
+	/* On the struct stats definition there is written that
+	 * this is not mandatory.... but seems that the probe
+	 * response parser uses it
+	 */
+        struct ieee80211_hdr_3addr * hdr = (struct ieee80211_hdr_3addr *)skb->data;
+
+	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)))
+        if ((memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN)))//use ADDR1 to perform address matching for Management frames
+        {
+                dev_kfree_skb_any(skb);
+                return 0;
+        }
+
+	ieee80211_rx_frame_softmac(ieee, skb, rx_stats, type, stype);
+
+	dev_kfree_skb_any(skb);
+
+	return 0;
+
+	#ifdef NOT_YET
+	if (ieee->iw_mode == IW_MODE_MASTER) {
+		printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",
+		       ieee->dev->name);
+		return 0;
+/*
+  hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr_4addr *)
+  skb->data);*/
+	}
+
+	if (ieee->hostapd && type == IEEE80211_TYPE_MGMT) {
+		if (stype == WLAN_FC_STYPE_BEACON &&
+		    ieee->iw_mode == IW_MODE_MASTER) {
+			struct sk_buff *skb2;
+			/* Process beacon frames also in kernel driver to
+			 * update STA(AP) table statistics */
+			skb2 = skb_clone(skb, GFP_ATOMIC);
+			if (skb2)
+				hostap_rx(skb2->dev, skb2, rx_stats);
+		}
+
+		/* send management frames to the user space daemon for
+		 * processing */
+		ieee->apdevstats.rx_packets++;
+		ieee->apdevstats.rx_bytes += skb->len;
+		prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT);
+		return 0;
+	}
+
+	    if (ieee->iw_mode == IW_MODE_MASTER) {
+		if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {
+			printk(KERN_DEBUG "%s: unknown management frame "
+			       "(type=0x%02x, stype=0x%02x) dropped\n",
+			       skb->dev->name, type, stype);
+			return -1;
+		}
+
+		hostap_rx(skb->dev, skb, rx_stats);
+		return 0;
+	}
+
+	printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame "
+	       "received in non-Host AP mode\n", skb->dev->name);
+	return -1;
+	#endif
+}
+
+
+
+/* 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;
+	if (ieee->hwsec_active)
+	{
+		cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE);
+		tcb_desc->bHwSec = 1;
+	}
+	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()) {
+			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
+			       "received packet from " MAC_FMT "\n",
+			       ieee->dev->name, MAC_ARG(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=" MAC_FMT
+			") res=%d\n", MAC_ARG(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;
+	if (ieee->hwsec_active)
+	{
+		cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE);
+		tcb_desc->bHwSec = 1;
+	}
+
+	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) {
+		printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
+		       " (SA=" MAC_FMT " keyidx=%d)\n",
+		       ieee->dev->name, MAC_ARG(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_QCTL_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_QCTL_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;
+		//for (pos = (head)->next; pos != (head); pos = pos->next)
+		//__list_for_each(p, &ieee->ibss_mac_hash[index]) {
+		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) {
+				printk(KERN_WARNING "Cannot malloc new mac entry\n");
+				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;
+}
+bool
+AddReorderEntry(
+	PRX_TS_RECORD			pTS,
+	PRX_REORDER_ENTRY		pReorderEntry
+	)
+{
+	struct list_head *pList = &pTS->RxPendingPktList;
+	while(pList->next != &pTS->RxPendingPktList)
+	{
+		if( SN_LESS(pReorderEntry->SeqNum, ((PRX_REORDER_ENTRY)list_entry(pList->next,RX_REORDER_ENTRY,List))->SeqNum) )
+		{
+			pList = pList->next;
+		}
+		else if( SN_EQUAL(pReorderEntry->SeqNum, ((PRX_REORDER_ENTRY)list_entry(pList->next,RX_REORDER_ENTRY,List))->SeqNum) )
+		{
+			return false;
+		}
+		else
+		{
+			break;
+		}
+	}
+	pReorderEntry->List.next = pList->next;
+	pReorderEntry->List.next->prev = &pReorderEntry->List;
+	pReorderEntry->List.prev = pList;
+	pList->next = &pReorderEntry->List;
+
+	return true;
+}
+
+void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8  index)
+{
+	u8 i = 0 , j=0;
+	u16 ethertype;
+//	if(index > 1)
+//		IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): hahahahhhh, We indicate packet from reorder list, index is %u\n",__FUNCTION__,index);
+	for(j = 0; j<index; j++)
+	{
+//added by amy for reorder
+		struct ieee80211_rxb* prxb = prxbIndicateArray[j];
+		for(i = 0; i<prxb->nr_subframes; i++) {
+			struct sk_buff *sub_skb = prxb->subframes[i];
+
+		/* convert hdr + possible LLC headers into Ethernet header */
+			ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7];
+			if (sub_skb->len >= 8 &&
+				((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 &&
+				  ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
+				 memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) {
+			/* remove RFC1042 or Bridge-Tunnel encapsulation and
+			 * replace EtherType */
+				skb_pull(sub_skb, SNAP_SIZE);
+				memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN);
+				memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN);
+			} else {
+				u16 len;
+			/* Leave Ethernet header part of hdr and full payload */
+				len = htons(sub_skb->len);
+				memcpy(skb_push(sub_skb, 2), &len, 2);
+				memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN);
+				memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN);
+			}
+			//stats->rx_packets++;
+			//stats->rx_bytes += sub_skb->len;
+
+		/* Indicat the packets to upper layer */
+			if (sub_skb) {
+				//printk("0skb_len(%d)\n", skb->len);
+				sub_skb->protocol = eth_type_trans(sub_skb, ieee->dev);
+				memset(sub_skb->cb, 0, sizeof(sub_skb->cb));
+				sub_skb->dev = ieee->dev;
+				sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
+				//skb->ip_summed = CHECKSUM_UNNECESSARY; /* 802.11 crc not sufficient */
+				ieee->last_rx_ps_time = jiffies;
+				//printk("1skb_len(%d)\n", skb->len);
+				netif_rx(sub_skb);
+			}
+		}
+		kfree(prxb);
+		prxb = NULL;
+	}
+}
+
+
+void RxReorderIndicatePacket( struct ieee80211_device *ieee,
+		struct ieee80211_rxb* prxb,
+		PRX_TS_RECORD		pTS,
+		u16			SeqNum)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	PRX_REORDER_ENTRY 	pReorderEntry = NULL;
+	struct ieee80211_rxb* prxbIndicateArray[REORDER_WIN_SIZE];
+	u8			WinSize = pHTInfo->RxReorderWinSize;
+	u16			WinEnd = (pTS->RxIndicateSeq + WinSize -1)%4096;
+	u8			index = 0;
+	bool			bMatchWinStart = false, bPktInBuf = false;
+	IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): Seq is %d,pTS->RxIndicateSeq is %d, WinSize is %d\n",__FUNCTION__,SeqNum,pTS->RxIndicateSeq,WinSize);
+	/* Rx Reorder initialize condition.*/
+	if(pTS->RxIndicateSeq == 0xffff) {
+		pTS->RxIndicateSeq = SeqNum;
+	}
+
+	/* Drop out the packet which SeqNum is smaller than WinStart */
+	if(SN_LESS(SeqNum, pTS->RxIndicateSeq)) {
+		IEEE80211_DEBUG(IEEE80211_DL_REORDER,"Packet Drop! IndicateSeq: %d, NewSeq: %d\n",
+				 pTS->RxIndicateSeq, SeqNum);
+		pHTInfo->RxReorderDropCounter++;
+		{
+			int i;
+			for(i =0; i < prxb->nr_subframes; i++) {
+				dev_kfree_skb(prxb->subframes[i]);
+			}
+			kfree(prxb);
+			prxb = NULL;
+		}
+		return;
+	}
+
+	/*
+	 * Sliding window manipulation. Conditions includes:
+	 * 1. Incoming SeqNum is equal to WinStart =>Window shift 1
+	 * 2. Incoming SeqNum is larger than the WinEnd => Window shift N
+	 */
+	if(SN_EQUAL(SeqNum, pTS->RxIndicateSeq)) {
+		pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096;
+		bMatchWinStart = true;
+	} else if(SN_LESS(WinEnd, SeqNum)) {
+		if(SeqNum >= (WinSize - 1)) {
+			pTS->RxIndicateSeq = SeqNum + 1 -WinSize;
+		} else {
+			pTS->RxIndicateSeq = 4095 - (WinSize - (SeqNum +1)) + 1;
+		}
+		IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Window Shift! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum);
+	}
+
+	/*
+	 * Indication process.
+	 * After Packet dropping and Sliding Window shifting as above, we can now just indicate the packets
+	 * with the SeqNum smaller than latest WinStart and buffer other packets.
+	 */
+	/* For Rx Reorder condition:
+	 * 1. All packets with SeqNum smaller than WinStart => Indicate
+	 * 2. All packets with SeqNum larger than or equal to WinStart => Buffer it.
+	 */
+	if(bMatchWinStart) {
+		/* Current packet is going to be indicated.*/
+		IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Packets indication!! IndicateSeq: %d, NewSeq: %d\n",\
+				pTS->RxIndicateSeq, SeqNum);
+		prxbIndicateArray[0] = prxb;
+//		printk("========================>%s(): SeqNum is %d\n",__FUNCTION__,SeqNum);
+		index = 1;
+	} else {
+		/* Current packet is going to be inserted into pending list.*/
+		//IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): We RX no ordered packed, insert to orderd list\n",__FUNCTION__);
+		if(!list_empty(&ieee->RxReorder_Unused_List)) {
+			pReorderEntry = (PRX_REORDER_ENTRY)list_entry(ieee->RxReorder_Unused_List.next,RX_REORDER_ENTRY,List);
+			list_del_init(&pReorderEntry->List);
+
+			/* Make a reorder entry and insert into a the packet list.*/
+			pReorderEntry->SeqNum = SeqNum;
+			pReorderEntry->prxb = prxb;
+	//		IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): pREorderEntry->SeqNum is %d\n",__FUNCTION__,pReorderEntry->SeqNum);
+
+			if(!AddReorderEntry(pTS, pReorderEntry)) {
+				IEEE80211_DEBUG(IEEE80211_DL_REORDER, "%s(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n",
+					__FUNCTION__, pTS->RxIndicateSeq, SeqNum);
+				list_add_tail(&pReorderEntry->List,&ieee->RxReorder_Unused_List);
+				{
+					int i;
+					for(i =0; i < prxb->nr_subframes; i++) {
+						dev_kfree_skb(prxb->subframes[i]);
+					}
+					kfree(prxb);
+					prxb = NULL;
+				}
+			} else {
+				IEEE80211_DEBUG(IEEE80211_DL_REORDER,
+					 "Pkt insert into buffer!! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum);
+			}
+		}
+		else {
+			/*
+			 * Packets are dropped if there is not enough reorder entries.
+			 * This part shall be modified!! We can just indicate all the
+			 * packets in buffer and get reorder entries.
+			 */
+			IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): There is no reorder entry!! Packet is dropped!!\n");
+			{
+				int i;
+				for(i =0; i < prxb->nr_subframes; i++) {
+					dev_kfree_skb(prxb->subframes[i]);
+				}
+				kfree(prxb);
+				prxb = NULL;
+			}
+		}
+	}
+
+	/* Check if there is any packet need indicate.*/
+	while(!list_empty(&pTS->RxPendingPktList)) {
+		IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): start RREORDER indicate\n",__FUNCTION__);
+		pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
+		if( SN_LESS(pReorderEntry->SeqNum, pTS->RxIndicateSeq) ||
+				SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq))
+		{
+			/* This protect buffer from overflow. */
+			if(index >= REORDER_WIN_SIZE) {
+				IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Buffer overflow!! \n");
+				bPktInBuf = true;
+				break;
+			}
+
+			list_del_init(&pReorderEntry->List);
+
+			if(SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq))
+				pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096;
+
+			IEEE80211_DEBUG(IEEE80211_DL_REORDER,"Packets indication!! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum);
+			prxbIndicateArray[index] = pReorderEntry->prxb;
+		//	printk("========================>%s(): pReorderEntry->SeqNum is %d\n",__FUNCTION__,pReorderEntry->SeqNum);
+			index++;
+
+			list_add_tail(&pReorderEntry->List,&ieee->RxReorder_Unused_List);
+		} else {
+			bPktInBuf = true;
+			break;
+		}
+	}
+
+	/* Handling pending timer. Set this timer to prevent from long time Rx buffering.*/
+	if(index>0) {
+		// Cancel previous pending timer.
+	//	del_timer_sync(&pTS->RxPktPendingTimer);
+		pTS->RxTimeoutIndicateSeq = 0xffff;
+
+		// Indicate packets
+		if(index>REORDER_WIN_SIZE){
+			IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Rx Reorer buffer full!! \n");
+			return;
+		}
+		ieee80211_indicate_packets(ieee, prxbIndicateArray, index);
+	}
+
+	if(bPktInBuf && pTS->RxTimeoutIndicateSeq==0xffff) {
+		// Set new pending timer.
+		IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): SET rx timeout timer\n", __FUNCTION__);
+		pTS->RxTimeoutIndicateSeq = pTS->RxIndicateSeq;
+		if(timer_pending(&pTS->RxPktPendingTimer))
+			del_timer_sync(&pTS->RxPktPendingTimer);
+		pTS->RxPktPendingTimer.expires = jiffies + MSECS(pHTInfo->RxReorderPendingTime);
+		add_timer(&pTS->RxPktPendingTimer);
+	}
+}
+
+u8 parse_subframe(struct sk_buff *skb,
+                  struct ieee80211_rx_stats *rx_stats,
+		  struct ieee80211_rxb *rxb,u8* src,u8* dst)
+{
+	struct ieee80211_hdr_3addr  *hdr = (struct ieee80211_hdr_3addr* )skb->data;
+	u16		fc = le16_to_cpu(hdr->frame_ctl);
+
+	u16		LLCOffset= sizeof(struct ieee80211_hdr_3addr);
+	u16		ChkLength;
+	bool		bIsAggregateFrame = false;
+	u16		nSubframe_Length;
+	u8		nPadding_Length = 0;
+	u16		SeqNum=0;
+
+	struct sk_buff *sub_skb;
+	u8             *data_ptr;
+	/* just for debug purpose */
+	SeqNum = WLAN_GET_SEQ_SEQ(le16_to_cpu(hdr->seq_ctl));
+
+	if((IEEE80211_QOS_HAS_SEQ(fc))&&\
+			(((frameqos *)(skb->data + IEEE80211_3ADDR_LEN))->field.reserved)) {
+		bIsAggregateFrame = true;
+	}
+
+	if(IEEE80211_QOS_HAS_SEQ(fc)) {
+		LLCOffset += 2;
+	}
+
+	if(rx_stats->bContainHTC) {
+		LLCOffset += sHTCLng;
+	}
+	//printk("ChkLength = %d\n", LLCOffset);
+	// Null packet, don't indicate it to upper layer
+	ChkLength = LLCOffset;/* + (Frame_WEP(frame)!=0 ?Adapter->MgntInfo.SecurityInfo.EncryptionHeadOverhead:0);*/
+
+	if( skb->len <= ChkLength ) {
+		return 0;
+	}
+
+	skb_pull(skb, LLCOffset);
+
+	if(!bIsAggregateFrame) {
+		rxb->nr_subframes = 1;
+#ifdef JOHN_NOCPY
+		rxb->subframes[0] = skb;
+#else
+		rxb->subframes[0] = skb_copy(skb, GFP_ATOMIC);
+#endif
+
+		memcpy(rxb->src,src,ETH_ALEN);
+		memcpy(rxb->dst,dst,ETH_ALEN);
+		//IEEE80211_DEBUG_DATA(IEEE80211_DL_RX,skb->data,skb->len);
+		return 1;
+	} else {
+		rxb->nr_subframes = 0;
+		memcpy(rxb->src,src,ETH_ALEN);
+		memcpy(rxb->dst,dst,ETH_ALEN);
+		while(skb->len > ETHERNET_HEADER_SIZE) {
+			/* Offset 12 denote 2 mac address */
+			nSubframe_Length = *((u16*)(skb->data + 12));
+			//==m==>change the length order
+			nSubframe_Length = (nSubframe_Length>>8) + (nSubframe_Length<<8);
+
+			if(skb->len<(ETHERNET_HEADER_SIZE + nSubframe_Length)) {
+				printk("%s: A-MSDU parse error!! pRfd->nTotalSubframe : %d\n",\
+						__FUNCTION__,rxb->nr_subframes);
+				printk("%s: A-MSDU parse error!! Subframe Length: %d\n",__FUNCTION__, nSubframe_Length);
+				printk("nRemain_Length is %d and nSubframe_Length is : %d\n",skb->len,nSubframe_Length);
+				printk("The Packet SeqNum is %d\n",SeqNum);
+				return 0;
+			}
+
+			/* move the data point to data content */
+			skb_pull(skb, ETHERNET_HEADER_SIZE);
+
+#ifdef JOHN_NOCPY
+			sub_skb = skb_clone(skb, GFP_ATOMIC);
+			sub_skb->len = nSubframe_Length;
+			sub_skb->tail = sub_skb->data + nSubframe_Length;
+#else
+			/* Allocate new skb for releasing to upper layer */
+			sub_skb = dev_alloc_skb(nSubframe_Length + 12);
+			skb_reserve(sub_skb, 12);
+			data_ptr = (u8 *)skb_put(sub_skb, nSubframe_Length);
+			memcpy(data_ptr,skb->data,nSubframe_Length);
+#endif
+			rxb->subframes[rxb->nr_subframes++] = sub_skb;
+			if(rxb->nr_subframes >= MAX_SUBFRAME_COUNT) {
+				IEEE80211_DEBUG_RX("ParseSubframe(): Too many Subframes! Packets dropped!\n");
+				break;
+			}
+			skb_pull(skb,nSubframe_Length);
+
+			if(skb->len != 0) {
+				nPadding_Length = 4 - ((nSubframe_Length + ETHERNET_HEADER_SIZE) % 4);
+				if(nPadding_Length == 4) {
+					nPadding_Length = 0;
+				}
+
+				if(skb->len < nPadding_Length) {
+					return 0;
+				}
+
+				skb_pull(skb,nPadding_Length);
+			}
+		}
+#ifdef JOHN_NOCPY
+		dev_kfree_skb(skb);
+#endif
+		//{just for debug added by david
+		//printk("AMSDU::rxb->nr_subframes = %d\n",rxb->nr_subframes);
+		//}
+		return rxb->nr_subframes;
+	}
+}
+
+/* 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_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
+		 struct ieee80211_rx_stats *rx_stats)
+{
+	struct net_device *dev = ieee->dev;
+	struct ieee80211_hdr_4addr *hdr;
+	//struct ieee80211_hdr_3addrqos *hdr;
+
+	size_t hdrlen;
+	u16 fc, type, stype, sc;
+	struct net_device_stats *stats;
+	unsigned int frag;
+	u8 *payload;
+	u16 ethertype;
+	//added by amy for reorder
+	u8	TID = 0;
+	u16	SeqNum = 0;
+	PRX_TS_RECORD pTS = NULL;
+	//bool bIsAggregateFrame = false;
+	//added by amy for reorder
+#ifdef NOT_YET
+	struct net_device *wds = NULL;
+	struct sk_buff *skb2 = NULL;
+	struct net_device *wds = NULL;
+	int frame_authorized = 0;
+	int from_assoc_ap = 0;
+	void *sta = NULL;
+#endif
+//	u16 qos_ctl = 0;
+	u8 dst[ETH_ALEN];
+	u8 src[ETH_ALEN];
+	u8 bssid[ETH_ALEN];
+	struct ieee80211_crypt_data *crypt = NULL;
+	int keyidx = 0;
+
+	int i;
+	struct ieee80211_rxb* rxb = NULL;
+	// cheat the the hdr type
+	hdr = (struct ieee80211_hdr_4addr *)skb->data;
+	stats = &ieee->stats;
+
+	if (skb->len < 10) {
+		printk(KERN_INFO "%s: SKB length < 10\n",
+		       dev->name);
+		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);
+	hdrlen = ieee80211_get_hdrlen(fc);
+
+	if(HTCCheck(ieee, skb->data))
+	{
+		if(net_ratelimit())
+		printk("find HTCControl\n");
+		hdrlen += 4;
+		rx_stats->bContainHTC = 1;
+	}
+
+	//IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
+#ifdef NOT_YET
+#if WIRELESS_EXT > 15
+	/* Put this code here so that we avoid duplicating it in all
+	 * Rx paths. - Jean II */
+#ifdef IW_WIRELESS_SPY		/* defined in iw_handler.h */
+	/* If spy monitoring on */
+	if (iface->spy_data.spy_number > 0) {
+		struct iw_quality wstats;
+		wstats.level = rx_stats->rssi;
+		wstats.noise = rx_stats->noise;
+		wstats.updated = 6;	/* No qual value */
+		/* Update spy records */
+		wireless_spy_update(dev, hdr->addr2, &wstats);
+	}
+#endif /* IW_WIRELESS_SPY */
+#endif /* WIRELESS_EXT > 15 */
+	hostap_update_rx_stats(local->ap, hdr, rx_stats);
+#endif
+
+#if WIRELESS_EXT > 15
+	if (ieee->iw_mode == IW_MODE_MONITOR) {
+		ieee80211_monitor_rx(ieee, skb, rx_stats);
+		stats->rx_packets++;
+		stats->rx_bytes += skb->len;
+		return 1;
+	}
+#endif
+	if (ieee->host_decrypt) {
+		int idx = 0;
+		if (skb->len >= hdrlen + 3)
+			idx = skb->data[hdrlen + 3] >> 6;
+		crypt = ieee->crypt[idx];
+#ifdef NOT_YET
+		sta = NULL;
+
+		/* Use station specific key to override default keys if the
+		 * receiver address is a unicast address ("individual RA"). If
+		 * bcrx_sta_key parameter is set, station specific key is used
+		 * even with broad/multicast targets (this is against IEEE
+		 * 802.11, but makes it easier to use different keys with
+		 * stations that do not support WEP key mapping). */
+
+		if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key)
+			(void) hostap_handle_sta_crypto(local, hdr, &crypt,
+							&sta);
+#endif
+
+		/* 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=" MAC_FMT ")\n",
+					     MAC_ARG(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( (ieee->pHTInfo->bCurRxReorderEnable == false) || !ieee->current_network.qos_data.active|| !IsDataFrame(skb->data) || IsLegacyDataFrame(skb->data)){
+		if (is_duplicate_packet(ieee, hdr))
+		goto rx_dropped;
+
+	}
+	else
+	{
+		PRX_TS_RECORD pRxTS = NULL;
+			//IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): QOS ENABLE AND RECEIVE QOS DATA , we will get Ts, tid:%d\n",__FUNCTION__, tid);
+		if(GetTs(
+				ieee,
+				(PTS_COMMON_INFO*) &pRxTS,
+				hdr->addr2,
+				(u8)Frame_QoSTID((u8*)(skb->data)),
+				RX_DIR,
+				true))
+		{
+
+		//	IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): pRxTS->RxLastFragNum is %d,frag is %d,pRxTS->RxLastSeqNum is %d,seq is %d\n",__FUNCTION__,pRxTS->RxLastFragNum,frag,pRxTS->RxLastSeqNum,WLAN_GET_SEQ_SEQ(sc));
+			if( 	(fc & (1<<11))  &&
+					(frag == pRxTS->RxLastFragNum) &&
+					(WLAN_GET_SEQ_SEQ(sc) == pRxTS->RxLastSeqNum)	)
+			{
+				goto rx_dropped;
+			}
+			else
+			{
+				pRxTS->RxLastFragNum = frag;
+				pRxTS->RxLastSeqNum = WLAN_GET_SEQ_SEQ(sc);
+			}
+		}
+		else
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s(): No TS!! Skip the check!!\n",__FUNCTION__);
+			goto rx_dropped;
+		}
+	}
+	if (type == IEEE80211_FTYPE_MGMT) {
+
+
+	//IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
+		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;
+	}
+
+#ifdef NOT_YET
+	if (hostap_rx_frame_wds(ieee, hdr, fc, &wds))
+		goto rx_dropped;
+	if (wds) {
+		skb->dev = dev = wds;
+		stats = hostap_get_stats(dev);
+	}
+
+	if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
+	    (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS &&
+	    ieee->stadev &&
+	    memcmp(hdr->addr2, ieee->assoc_ap_addr, ETH_ALEN) == 0) {
+		/* Frame from BSSID of the AP for which we are a client */
+		skb->dev = dev = ieee->stadev;
+		stats = hostap_get_stats(dev);
+		from_assoc_ap = 1;
+	}
+#endif
+
+	dev->last_rx = jiffies;
+
+#ifdef NOT_YET
+	if ((ieee->iw_mode == IW_MODE_MASTER ||
+	     ieee->iw_mode == IW_MODE_REPEAT) &&
+	    !from_assoc_ap) {
+		switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats,
+					     wds != NULL)) {
+		case AP_RX_CONTINUE_NOT_AUTHORIZED:
+			frame_authorized = 0;
+			break;
+		case AP_RX_CONTINUE:
+			frame_authorized = 1;
+			break;
+		case AP_RX_DROP:
+			goto rx_dropped;
+		case AP_RX_EXIT:
+			goto rx_exit;
+		}
+	}
+#endif
+	//IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
+	/* 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;
+
+	/* skb: hdr + (possibly fragmented, possibly encrypted) payload */
+
+	if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
+	    (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
+	{
+		printk("decrypt frame error\n");
+		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) {
+			printk(KERN_WARNING "%s: host decrypted and "
+			       "reassembled frame did not fit skb\n",
+			       dev->name);
+			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))
+	{
+		printk("==>decrypt msdu error\n");
+		goto rx_dropped;
+	}
+
+	//added by amy for AP roaming
+	ieee->LinkDetectInfo.NumRecvDataInPeriod++;
+	ieee->LinkDetectInfo.NumRxOkInPeriod++;
+
+	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=" MAC_FMT ")\n",
+				MAC_ARG(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 " MAC_FMT
+			" (drop_unencrypted=1)\n",
+			MAC_ARG(hdr->addr2));
+		goto rx_dropped;
+	}
+/*
+	if(ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
+		printk(KERN_WARNING "RX: IEEE802.1X EPAOL frame!\n");
+	}
+*/
+//added by amy for reorder
+	if(ieee->current_network.qos_data.active && IsQoSDataFrame(skb->data)
+		&& !is_multicast_ether_addr(hdr->addr1) && !is_broadcast_ether_addr(hdr->addr1))
+	{
+		TID = Frame_QoSTID(skb->data);
+		SeqNum = WLAN_GET_SEQ_SEQ(sc);
+		GetTs(ieee,(PTS_COMMON_INFO*) &pTS,hdr->addr2,TID,RX_DIR,true);
+		if(TID !=0 && TID !=3)
+		{
+			ieee->bis_any_nonbepkts = true;
+		}
+	}
+//added by amy for reorder
+	/* skb: hdr + (possible reassembled) full plaintext payload */
+	payload = skb->data + hdrlen;
+	//ethertype = (payload[6] << 8) | payload[7];
+	rxb = (struct ieee80211_rxb*)kmalloc(sizeof(struct ieee80211_rxb),GFP_ATOMIC);
+	if(rxb == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR,"%s(): kmalloc rxb error\n",__FUNCTION__);
+		goto rx_dropped;
+	}
+	/* to parse amsdu packets */
+	/* qos data packets & reserved bit is 1 */
+	if(parse_subframe(skb,rx_stats,rxb,src,dst) == 0) {
+		/* only to free rxb, and not submit the packets to upper layer */
+		for(i =0; i < rxb->nr_subframes; i++) {
+			dev_kfree_skb(rxb->subframes[i]);
+		}
+		kfree(rxb);
+		rxb = NULL;
+		goto rx_dropped;
+	}
+
+//added by amy for reorder
+	if(ieee->pHTInfo->bCurRxReorderEnable == false ||pTS == NULL){
+//added by amy for reorder
+		for(i = 0; i<rxb->nr_subframes; i++) {
+			struct sk_buff *sub_skb = rxb->subframes[i];
+
+			if (sub_skb) {
+				/* convert hdr + possible LLC headers into Ethernet header */
+				ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7];
+				if (sub_skb->len >= 8 &&
+						((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 &&
+						  ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
+						 memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) {
+					/* remove RFC1042 or Bridge-Tunnel encapsulation and
+					 * replace EtherType */
+					skb_pull(sub_skb, SNAP_SIZE);
+					memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN);
+					memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN);
+				} else {
+					u16 len;
+					/* Leave Ethernet header part of hdr and full payload */
+					len = htons(sub_skb->len);
+					memcpy(skb_push(sub_skb, 2), &len, 2);
+					memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN);
+					memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN);
+				}
+
+				stats->rx_packets++;
+				stats->rx_bytes += sub_skb->len;
+				if(is_multicast_ether_addr(dst)) {
+					stats->multicast++;
+				}
+
+				/* Indicat the packets to upper layer */
+				//printk("0skb_len(%d)\n", skb->len);
+				sub_skb->protocol = eth_type_trans(sub_skb, dev);
+				memset(sub_skb->cb, 0, sizeof(sub_skb->cb));
+				sub_skb->dev = dev;
+				sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
+				//skb->ip_summed = CHECKSUM_UNNECESSARY; /* 802.11 crc not sufficient */
+				ieee->last_rx_ps_time = jiffies;
+				//printk("1skb_len(%d)\n", skb->len);
+				netif_rx(sub_skb);
+			}
+		}
+		kfree(rxb);
+		rxb = NULL;
+
+	}
+	else
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): REORDER ENABLE AND PTS not NULL, and we will enter RxReorderIndicatePacket()\n",__FUNCTION__);
+		RxReorderIndicatePacket(ieee, rxb, pTS, SeqNum);
+	}
+#ifndef JOHN_NOCPY
+	dev_kfree_skb(skb);
+#endif
+
+ rx_exit:
+#ifdef NOT_YET
+	if (sta)
+		hostap_handle_sta_release(sta);
+#endif
+	return 1;
+
+ rx_dropped:
+	if (rxb != NULL)
+	{
+		kfree(rxb);
+		rxb = NULL;
+	}
+	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 u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
+
+/*
+* Make ther structure we read from the beacon packet has
+* the right values
+*/
+static int ieee80211_verify_qos_info(struct ieee80211_qos_information_element
+                                     *info_element, int sub_type)
+{
+
+        if (info_element->qui_subtype != sub_type)
+                return -1;
+        if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN))
+                return -1;
+        if (info_element->qui_type != QOS_OUI_TYPE)
+                return -1;
+        if (info_element->version != QOS_VERSION_1)
+                return -1;
+
+        return 0;
+}
+
+
+/*
+ * Parse a QoS parameter element
+ */
+static int ieee80211_read_qos_param_element(struct ieee80211_qos_parameter_info
+                                            *element_param, struct ieee80211_info_element
+                                            *info_element)
+{
+        int ret = 0;
+        u16 size = sizeof(struct ieee80211_qos_parameter_info) - 2;
+
+        if ((info_element == NULL) || (element_param == NULL))
+                return -1;
+
+        if (info_element->id == QOS_ELEMENT_ID && info_element->len == size) {
+                memcpy(element_param->info_element.qui, info_element->data,
+                       info_element->len);
+                element_param->info_element.elementID = info_element->id;
+                element_param->info_element.length = info_element->len;
+        } else
+                ret = -1;
+        if (ret == 0)
+                ret = ieee80211_verify_qos_info(&element_param->info_element,
+                                                QOS_OUI_PARAM_SUB_TYPE);
+        return ret;
+}
+
+/*
+ * Parse a QoS information element
+ */
+static int ieee80211_read_qos_info_element(struct
+                                           ieee80211_qos_information_element
+                                           *element_info, struct ieee80211_info_element
+                                           *info_element)
+{
+        int ret = 0;
+        u16 size = sizeof(struct ieee80211_qos_information_element) - 2;
+
+        if (element_info == NULL)
+                return -1;
+        if (info_element == NULL)
+                return -1;
+
+        if ((info_element->id == QOS_ELEMENT_ID) && (info_element->len == size)) {
+                memcpy(element_info->qui, info_element->data,
+                       info_element->len);
+                element_info->elementID = info_element->id;
+                element_info->length = info_element->len;
+        } else
+                ret = -1;
+
+        if (ret == 0)
+                ret = ieee80211_verify_qos_info(element_info,
+                                                QOS_OUI_INFO_SUB_TYPE);
+        return ret;
+}
+
+
+/*
+ * Write QoS parameters from the ac parameters.
+ */
+static int ieee80211_qos_convert_ac_to_parameters(struct
+                                                  ieee80211_qos_parameter_info
+                                                  *param_elm, struct
+                                                  ieee80211_qos_parameters
+                                                  *qos_param)
+{
+        int rc = 0;
+        int i;
+        struct ieee80211_qos_ac_parameter *ac_params;
+	u8 aci;
+        //u8 cw_min;
+        //u8 cw_max;
+
+        for (i = 0; i < QOS_QUEUE_NUM; i++) {
+                ac_params = &(param_elm->ac_params_record[i]);
+
+		aci = (ac_params->aci_aifsn & 0x60) >> 5;
+
+		if(aci >= QOS_QUEUE_NUM)
+			continue;
+                qos_param->aifs[aci] = (ac_params->aci_aifsn) & 0x0f;
+
+		/* WMM spec P.11: The minimum value for AIFSN shall be 2 */
+                qos_param->aifs[aci] = (qos_param->aifs[aci] < 2) ? 2:qos_param->aifs[aci];
+
+                qos_param->cw_min[aci] = ac_params->ecw_min_max & 0x0F;
+
+                qos_param->cw_max[aci] = (ac_params->ecw_min_max & 0xF0) >> 4;
+
+                qos_param->flag[aci] =
+                    (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00;
+                qos_param->tx_op_limit[aci] = le16_to_cpu(ac_params->tx_op_limit);
+        }
+        return rc;
+}
+
+/*
+ * we have a generic data element which it may contain QoS information or
+ * parameters element. check the information element length to decide
+ * which type to read
+ */
+static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element
+                                             *info_element,
+                                             struct ieee80211_network *network)
+{
+        int rc = 0;
+        struct ieee80211_qos_parameters *qos_param = NULL;
+        struct ieee80211_qos_information_element qos_info_element;
+
+        rc = ieee80211_read_qos_info_element(&qos_info_element, info_element);
+
+        if (rc == 0) {
+                network->qos_data.param_count = qos_info_element.ac_info & 0x0F;
+                network->flags |= NETWORK_HAS_QOS_INFORMATION;
+        } else {
+                struct ieee80211_qos_parameter_info param_element;
+
+                rc = ieee80211_read_qos_param_element(&param_element,
+                                                      info_element);
+                if (rc == 0) {
+                        qos_param = &(network->qos_data.parameters);
+                        ieee80211_qos_convert_ac_to_parameters(&param_element,
+                                                               qos_param);
+                        network->flags |= NETWORK_HAS_QOS_PARAMETERS;
+                        network->qos_data.param_count =
+                            param_element.info_element.ac_info & 0x0F;
+                }
+        }
+
+        if (rc == 0) {
+                IEEE80211_DEBUG_QOS("QoS is supported\n");
+                network->qos_data.supported = 1;
+        }
+        return rc;
+}
+
+#ifdef CONFIG_IEEE80211_DEBUG
+#define MFIE_STRING(x) case MFIE_TYPE_ ##x: return #x
+
+static const char *get_info_element_string(u16 id)
+{
+        switch (id) {
+                MFIE_STRING(SSID);
+                MFIE_STRING(RATES);
+                MFIE_STRING(FH_SET);
+                MFIE_STRING(DS_SET);
+                MFIE_STRING(CF_SET);
+                MFIE_STRING(TIM);
+                MFIE_STRING(IBSS_SET);
+                MFIE_STRING(COUNTRY);
+                MFIE_STRING(HOP_PARAMS);
+                MFIE_STRING(HOP_TABLE);
+                MFIE_STRING(REQUEST);
+                MFIE_STRING(CHALLENGE);
+                MFIE_STRING(POWER_CONSTRAINT);
+                MFIE_STRING(POWER_CAPABILITY);
+                MFIE_STRING(TPC_REQUEST);
+                MFIE_STRING(TPC_REPORT);
+                MFIE_STRING(SUPP_CHANNELS);
+                MFIE_STRING(CSA);
+                MFIE_STRING(MEASURE_REQUEST);
+                MFIE_STRING(MEASURE_REPORT);
+                MFIE_STRING(QUIET);
+                MFIE_STRING(IBSS_DFS);
+               // MFIE_STRING(ERP_INFO);
+                MFIE_STRING(RSN);
+                MFIE_STRING(RATES_EX);
+                MFIE_STRING(GENERIC);
+                MFIE_STRING(QOS_PARAMETER);
+        default:
+                return "UNKNOWN";
+        }
+}
+#endif
+
+#ifdef ENABLE_DOT11D
+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);
+		}
+	}
+
+}
+#endif
+
+int ieee80211_parse_info_param(struct ieee80211_device *ieee,
+		struct ieee80211_info_element *info_element,
+		u16 length,
+		struct ieee80211_network *network,
+		struct ieee80211_rx_stats *stats)
+{
+	u8 i;
+	short offset;
+        u16	tmp_htcap_len=0;
+	u16	tmp_htinfo_len=0;
+	u16 ht_realtek_agg_len=0;
+	u8  ht_realtek_agg_buf[MAX_IE_LEN];
+//	u16 broadcom_len = 0;
+#ifdef CONFIG_IEEE80211_DEBUG
+	char rates_str[64];
+	char *p;
+#endif
+
+	while (length >= sizeof(*info_element)) {
+		if (sizeof(*info_element) + info_element->len > length) {
+			IEEE80211_DEBUG_MGMT("Info elem: parse failed: "
+					     "info_element->len + 2 > left : "
+					     "info_element->len+2=%zd left=%d, id=%d.\n",
+					     info_element->len +
+					     sizeof(*info_element),
+					     length, info_element->id);
+			/* We stop processing but don't return an error here
+			 * because some misbehaviour APs break this rule. ie.
+			 * Orinoco AP1000. */
+			break;
+		}
+
+		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_MGMT("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];
+#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_MGMT("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];
+#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_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
+					     rates_str, network->rates_ex_len);
+			break;
+
+		case MFIE_TYPE_DS_SET:
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n",
+					     info_element->data[0]);
+			network->channel = info_element->data[0];
+			break;
+
+		case MFIE_TYPE_FH_SET:
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n");
+			break;
+
+		case MFIE_TYPE_CF_SET:
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n");
+			break;
+
+		case MFIE_TYPE_TIM:
+			if(info_element->len < 4)
+				break;
+
+			network->tim.tim_count = info_element->data[0];
+			network->tim.tim_period = info_element->data[1];
+
+                        network->dtim_period = info_element->data[1];
+                        if(ieee->state != IEEE80211_LINKED)
+                                break;
+
+                        network->last_dtim_sta_time[0] = stats->mac_time[0];
+                        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);
+
+                        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) ;
+
+                        if(info_element->data[3+offset] & (1<<(ieee->assoc_id%8)))
+                                network->dtim_data |= IEEE80211_DTIM_UCAST;
+
+			//IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: partially ignored\n");
+			break;
+
+		case MFIE_TYPE_ERP:
+			network->erp_value = info_element->data[0];
+			network->flags |= NETWORK_HAS_ERP_VALUE;
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
+					     network->erp_value);
+			break;
+		case MFIE_TYPE_IBSS_SET:
+			network->atim_window = info_element->data[0];
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n",
+					     network->atim_window);
+			break;
+
+		case MFIE_TYPE_CHALLENGE:
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n");
+			break;
+
+		case MFIE_TYPE_GENERIC:
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n",
+					     info_element->len);
+			if (!ieee80211_parse_qos_info_param_IE(info_element,
+							       network))
+				break;
+
+			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);
+				break;
+			}
+
+#ifdef THOMAS_TURBO
+                        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;
+                        }
+#endif
+
+                        //for HTcap and HTinfo parameters
+			if(tmp_htcap_len == 0){
+				if(info_element->len >= 4 &&
+				   info_element->data[0] == 0x00 &&
+				   info_element->data[1] == 0x90 &&
+				   info_element->data[2] == 0x4c &&
+				   info_element->data[3] == 0x033){
+
+						tmp_htcap_len = min(info_element->len,(u8)MAX_IE_LEN);
+				   		if(tmp_htcap_len != 0){
+				   			network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
+							network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf)?\
+								sizeof(network->bssht.bdHTCapBuf):tmp_htcap_len;
+							memcpy(network->bssht.bdHTCapBuf,info_element->data,network->bssht.bdHTCapLen);
+				   		}
+				}
+				if(tmp_htcap_len != 0)
+					network->bssht.bdSupportHT = true;
+				else
+					network->bssht.bdSupportHT = false;
+			}
+
+
+			if(tmp_htinfo_len == 0){
+				if(info_element->len >= 4 &&
+					info_element->data[0] == 0x00 &&
+				   	info_element->data[1] == 0x90 &&
+				   	info_element->data[2] == 0x4c &&
+				   	info_element->data[3] == 0x034){
+
+						tmp_htinfo_len = min(info_element->len,(u8)MAX_IE_LEN);
+						if(tmp_htinfo_len != 0){
+							network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
+							if(tmp_htinfo_len){
+								network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf)?\
+									sizeof(network->bssht.bdHTInfoBuf):tmp_htinfo_len;
+								memcpy(network->bssht.bdHTInfoBuf,info_element->data,network->bssht.bdHTInfoLen);
+							}
+
+						}
+
+				}
+			}
+
+			if(ieee->aggregation){
+				if(network->bssht.bdSupportHT){
+					if(info_element->len >= 4 &&
+						info_element->data[0] == 0x00 &&
+						info_element->data[1] == 0xe0 &&
+						info_element->data[2] == 0x4c &&
+						info_element->data[3] == 0x02){
+
+						ht_realtek_agg_len = min(info_element->len,(u8)MAX_IE_LEN);
+						memcpy(ht_realtek_agg_buf,info_element->data,info_element->len);
+
+					}
+					if(ht_realtek_agg_len >= 5){
+						network->bssht.bdRT2RTAggregation = true;
+
+						if((ht_realtek_agg_buf[4] == 1) && (ht_realtek_agg_buf[5] & 0x02))
+						network->bssht.bdRT2RTLongSlotTime = true;
+					}
+				}
+
+			}
+
+			//if(tmp_htcap_len !=0  ||  tmp_htinfo_len != 0)
+			{
+				if((info_element->len >= 3 &&
+					 info_element->data[0] == 0x00 &&
+					 info_element->data[1] == 0x05 &&
+					 info_element->data[2] == 0xb5) ||
+					 (info_element->len >= 3 &&
+					 info_element->data[0] == 0x00 &&
+					 info_element->data[1] == 0x0a &&
+					 info_element->data[2] == 0xf7) ||
+					 (info_element->len >= 3 &&
+					 info_element->data[0] == 0x00 &&
+					 info_element->data[1] == 0x10 &&
+					 info_element->data[2] == 0x18)){
+
+						network->broadcom_cap_exist = true;
+
+				}
+			}
+			if(info_element->len >= 3 &&
+				info_element->data[0] == 0x00 &&
+				info_element->data[1] == 0x0c &&
+				info_element->data[2] == 0x43)
+			{
+				network->ralink_cap_exist = true;
+			}
+			else
+				network->ralink_cap_exist = false;
+			//added by amy for atheros AP
+			if((info_element->len >= 3 &&
+				info_element->data[0] == 0x00 &&
+				info_element->data[1] == 0x03 &&
+				info_element->data[2] == 0x7f) ||
+				(info_element->len >= 3 &&
+				info_element->data[0] == 0x00 &&
+				info_element->data[1] == 0x13 &&
+				info_element->data[2] == 0x74))
+			{
+				printk("========>%s(): athros AP is exist\n",__FUNCTION__);
+				network->atheros_cap_exist = true;
+			}
+			else
+				network->atheros_cap_exist = false;
+
+			if(info_element->len >= 3 &&
+				info_element->data[0] == 0x00 &&
+				info_element->data[1] == 0x40 &&
+				info_element->data[2] == 0x96)
+			{
+				network->cisco_cap_exist = true;
+			}
+			else
+				network->cisco_cap_exist = false;
+			//added by amy for LEAP of cisco
+			if(info_element->len > 4 &&
+				info_element->data[0] == 0x00 &&
+				info_element->data[1] == 0x40 &&
+				info_element->data[2] == 0x96 &&
+				info_element->data[3] == 0x01)
+			{
+				if(info_element->len == 6)
+				{
+					memcpy(network->CcxRmState, &info_element[4], 2);
+					if(network->CcxRmState[0] != 0)
+					{
+						network->bCcxRmEnable = true;
+					}
+					else
+						network->bCcxRmEnable = false;
+					//
+					// CCXv4 Table 59-1 MBSSID Masks.
+					//
+					network->MBssidMask = network->CcxRmState[1] & 0x07;
+					if(network->MBssidMask != 0)
+					{
+						network->bMBssidValid = true;
+						network->MBssidMask = 0xff << (network->MBssidMask);
+						cpMacAddr(network->MBssid, network->bssid);
+						network->MBssid[5] &= network->MBssidMask;
+					}
+					else
+					{
+						network->bMBssidValid = false;
+					}
+				}
+				else
+				{
+					network->bCcxRmEnable = false;
+				}
+			}
+			if(info_element->len > 4  &&
+				info_element->data[0] == 0x00 &&
+				info_element->data[1] == 0x40 &&
+				info_element->data[2] == 0x96 &&
+				info_element->data[3] == 0x03)
+			{
+				if(info_element->len == 5)
+				{
+					network->bWithCcxVerNum = true;
+					network->BssCcxVerNumber = info_element->data[4];
+				}
+				else
+				{
+					network->bWithCcxVerNum = false;
+					network->BssCcxVerNumber = 0;
+				}
+			}
+			break;
+
+		case MFIE_TYPE_RSN:
+			IEEE80211_DEBUG_MGMT("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;
+
+                        //HT related element.
+		case MFIE_TYPE_HT_CAP:
+			IEEE80211_DEBUG_SCAN("MFIE_TYPE_HT_CAP: %d bytes\n",
+					     info_element->len);
+			tmp_htcap_len = min(info_element->len,(u8)MAX_IE_LEN);
+			if(tmp_htcap_len != 0){
+				network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
+				network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf)?\
+					sizeof(network->bssht.bdHTCapBuf):tmp_htcap_len;
+				memcpy(network->bssht.bdHTCapBuf,info_element->data,network->bssht.bdHTCapLen);
+
+				//If peer is HT, but not WMM, call QosSetLegacyWMMParamWithHT()
+				// windows driver will update WMM parameters each beacon received once connected
+                                // Linux driver is a bit different.
+				network->bssht.bdSupportHT = true;
+			}
+			else
+				network->bssht.bdSupportHT = false;
+			break;
+
+
+		case MFIE_TYPE_HT_INFO:
+			IEEE80211_DEBUG_SCAN("MFIE_TYPE_HT_INFO: %d bytes\n",
+					     info_element->len);
+			tmp_htinfo_len = min(info_element->len,(u8)MAX_IE_LEN);
+			if(tmp_htinfo_len){
+				network->bssht.bdHTSpecVer = HT_SPEC_VER_IEEE;
+				network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf)?\
+					sizeof(network->bssht.bdHTInfoBuf):tmp_htinfo_len;
+				memcpy(network->bssht.bdHTInfoBuf,info_element->data,network->bssht.bdHTInfoLen);
+			}
+			break;
+
+		case MFIE_TYPE_AIRONET:
+			IEEE80211_DEBUG_SCAN("MFIE_TYPE_AIRONET: %d bytes\n",
+					     info_element->len);
+			if(info_element->len >IE_CISCO_FLAG_POSITION)
+			{
+				network->bWithAironetIE = true;
+
+				// CCX 1 spec v1.13, A01.1 CKIP Negotiation (page23):
+				// "A Cisco access point advertises support for CKIP in beacon and probe response packets,
+				//  by adding an Aironet element and setting one or both of the CKIP negotiation bits."
+				if(	(info_element->data[IE_CISCO_FLAG_POSITION]&SUPPORT_CKIP_MIC)	||
+					(info_element->data[IE_CISCO_FLAG_POSITION]&SUPPORT_CKIP_PK)	)
+				{
+		 			network->bCkipSupported = true;
+				}
+				else
+				{
+					network->bCkipSupported = false;
+				}
+			}
+			else
+			{
+				network->bWithAironetIE = false;
+		 		network->bCkipSupported = false;
+			}
+			break;
+		case MFIE_TYPE_QOS_PARAMETER:
+			printk(KERN_ERR
+			       "QoS Error need to parse QOS_PARAMETER IE\n");
+			break;
+
+#ifdef ENABLE_DOT11D
+		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, network->bssid);//addr2 is same as addr3 when from an AP
+			break;
+#endif
+/* TODO */
+		default:
+			IEEE80211_DEBUG_MGMT
+			    ("Unsupported info element: %s (%d)\n",
+			     get_info_element_string(info_element->id),
+			     info_element->id);
+			break;
+		}
+
+		length -= sizeof(*info_element) + info_element->len;
+		info_element =
+		    (struct ieee80211_info_element *)&info_element->
+		    data[info_element->len];
+	}
+
+	if(!network->atheros_cap_exist && !network->broadcom_cap_exist &&
+		!network->cisco_cap_exist && !network->ralink_cap_exist && !network->bssht.bdRT2RTAggregation)
+	{
+		network->unknown_cap_exist = true;
+	}
+	else
+	{
+		network->unknown_cap_exist = false;
+	}
+	return 0;
+}
+
+static inline u8 ieee80211_SignalStrengthTranslate(
+	u8  CurrSS
+	)
+{
+	u8 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;
+}
+
+long ieee80211_translate_todbm(u8 signal_strength_index	)// 0-100 index.
+{
+	long	signal_power; // in dBm.
+
+	// Translate to dBm (x=0.5y-95).
+	signal_power = (long)((signal_strength_index + 1) >> 1);
+	signal_power -= 95;
+
+	return signal_power;
+}
+
+static 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
+
+        network->qos_data.active = 0;
+        network->qos_data.supported = 0;
+        network->qos_data.param_count = 0;
+        network->qos_data.old_param_count = 0;
+
+	/* Pull out fixed field data */
+	memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
+	network->capability = le16_to_cpu(beacon->capability);
+	network->last_scanned = jiffies;
+	network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]);
+	network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]);
+	network->beacon_interval = le32_to_cpu(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->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?
+            0x3 : 0x0;
+	network->berp_info_valid = false;
+        network->broadcom_cap_exist = false;
+	network->ralink_cap_exist = false;
+	network->atheros_cap_exist = false;
+	network->cisco_cap_exist = false;
+	network->unknown_cap_exist = false;
+#ifdef THOMAS_TURBO
+	network->Turbo_Enable = 0;
+#endif
+#ifdef ENABLE_DOT11D
+	network->CountryIeLen = 0;
+	memset(network->CountryIeBuf, 0, MAX_IE_LEN);
+#endif
+//Initialize HT parameters
+	//ieee80211_ht_initialize(&network->bssht);
+	HTInitializeBssDesc(&network->bssht);
+	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;
+
+        if (ieee80211_parse_info_param
+            (ieee,beacon->info_element, stats->len - sizeof(*beacon), network, stats))
+                return 1;
+
+	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 (" MAC_FMT ")' "
+				     "network.\n",
+				     escape_essid(network->ssid,
+						  network->ssid_len),
+				     MAC_ARG(network->bssid));
+		return 1;
+	}
+
+	if(network->bssht.bdSupportHT){
+		if(network->mode == IEEE_A)
+			network->mode = IEEE_N_5G;
+		else if(network->mode & (IEEE_G | IEEE_B))
+			network->mode = IEEE_N_24G;
+	}
+	if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
+		network->flags |= NETWORK_EMPTY_ESSID;
+
+	stats->signal = 30 + (stats->SignalStrength * 70) / 100;
+	//stats->signal = ieee80211_SignalStrengthTranslate(stats->signal);
+	stats->noise = ieee80211_translate_todbm((u8)(100-stats->signal)) -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) &&
+		(((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) &&
+		(src->channel == dst->channel) &&
+		!memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
+		//!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
+		(!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) &&
+		((src->capability & WLAN_CAPABILITY_IBSS) ==
+		(dst->capability & WLAN_CAPABILITY_IBSS)) &&
+		((src->capability & WLAN_CAPABILITY_BSS) ==
+		(dst->capability & WLAN_CAPABILITY_BSS)));
+}
+
+static inline void update_network(struct ieee80211_network *dst,
+				  struct ieee80211_network *src)
+{
+	int qos_active;
+	u8 old_param;
+
+	memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
+	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;
+	if(src->ssid_len > 0)
+	{
+		memset(dst->ssid, 0, dst->ssid_len);
+		dst->ssid_len = src->ssid_len;
+		memcpy(dst->ssid, src->ssid, src->ssid_len);
+	}
+	dst->mode = src->mode;
+	dst->flags = src->flags;
+	dst->time_stamp[0] = src->time_stamp[0];
+	dst->time_stamp[1] = src->time_stamp[1];
+	if (src->flags & NETWORK_HAS_ERP_VALUE)
+	{
+		dst->erp_value = src->erp_value;
+		dst->berp_info_valid = src->berp_info_valid = true;
+	}
+	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];
+	memcpy(&dst->tim, &src->tim, sizeof(struct ieee80211_tim_parameters));
+
+        dst->bssht.bdSupportHT = src->bssht.bdSupportHT;
+	dst->bssht.bdRT2RTAggregation = src->bssht.bdRT2RTAggregation;
+	dst->bssht.bdHTCapLen= src->bssht.bdHTCapLen;
+	memcpy(dst->bssht.bdHTCapBuf,src->bssht.bdHTCapBuf,src->bssht.bdHTCapLen);
+	dst->bssht.bdHTInfoLen= src->bssht.bdHTInfoLen;
+	memcpy(dst->bssht.bdHTInfoBuf,src->bssht.bdHTInfoBuf,src->bssht.bdHTInfoLen);
+	dst->bssht.bdHTSpecVer = src->bssht.bdHTSpecVer;
+	dst->bssht.bdRT2RTLongSlotTime = src->bssht.bdRT2RTLongSlotTime;
+	dst->broadcom_cap_exist = src->broadcom_cap_exist;
+	dst->ralink_cap_exist = src->ralink_cap_exist;
+	dst->atheros_cap_exist = src->atheros_cap_exist;
+	dst->cisco_cap_exist = src->cisco_cap_exist;
+	dst->unknown_cap_exist = src->unknown_cap_exist;
+	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;
+	/* qos related parameters */
+	//qos_active = src->qos_data.active;
+	qos_active = dst->qos_data.active;
+	//old_param = dst->qos_data.old_param_count;
+	old_param = dst->qos_data.param_count;
+	if(dst->flags & NETWORK_HAS_QOS_MASK)
+		memcpy(&dst->qos_data, &src->qos_data,
+			sizeof(struct ieee80211_qos_data));
+	else {
+		dst->qos_data.supported = src->qos_data.supported;
+		dst->qos_data.param_count = src->qos_data.param_count;
+	}
+
+	if(dst->qos_data.supported == 1) {
+		dst->QoS_Enable = 1;
+		if(dst->ssid_len)
+			IEEE80211_DEBUG_QOS
+				("QoS the network %s is QoS supported\n",
+				dst->ssid);
+		else
+			IEEE80211_DEBUG_QOS
+				("QoS the network is QoS supported\n");
+	}
+	dst->qos_data.active = qos_active;
+	dst->qos_data.old_param_count = old_param;
+
+	/* dst->last_associate is not overwritten */
+	dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame.
+	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[1].ac_aci_acm_aifsn) {
+	  memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
+	}
+	//dst->QoS_Enable = src->QoS_Enable;
+#ifdef THOMAS_TURBO
+	dst->Turbo_Enable = src->Turbo_Enable;
+#endif
+
+#ifdef ENABLE_DOT11D
+	dst->CountryIeLen = src->CountryIeLen;
+	memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen);
+#endif
+
+	//added by amy for LEAP
+	dst->bWithAironetIE = src->bWithAironetIE;
+	dst->bCkipSupported = src->bCkipSupported;
+	memcpy(dst->CcxRmState,src->CcxRmState,2);
+	dst->bCcxRmEnable = src->bCcxRmEnable;
+	dst->MBssidMask = src->MBssidMask;
+	dst->bMBssidValid = src->bMBssidValid;
+	memcpy(dst->MBssid,src->MBssid,6);
+	dst->bWithCcxVerNum = src->bWithCcxVerNum;
+	dst->BssCcxVerNumber = src->BssCcxVerNumber;
+
+}
+
+static inline int is_beacon(__le16 fc)
+{
+	return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == IEEE80211_STYPE_BEACON);
+}
+
+static 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[0];
+#endif
+	unsigned long flags;
+	short renew;
+	//u8 wmm_info;
+
+	memset(&network, 0, sizeof(struct ieee80211_network));
+	IEEE80211_DEBUG_SCAN(
+		"'%s' (" MAC_FMT "): %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),
+		MAC_ARG(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' (" MAC_FMT ") via %s.\n",
+				     escape_essid(info_element->data,
+						  info_element->len),
+				     MAC_ARG(beacon->header.addr3),
+				     WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
+				     IEEE80211_STYPE_PROBE_RESP ?
+				     "PROBE RESPONSE" : "BEACON");
+		return;
+	}
+
+#ifdef ENABLE_DOT11D
+	// 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( !IsLegalChannel(ieee, network.channel) )
+		return;
+	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;
+				}
+			}
+		}
+	}
+#endif
+
+	/* 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)) {
+		update_network(&ieee->current_network, &network);
+		if((ieee->current_network.mode == IEEE_N_24G || ieee->current_network.mode == IEEE_G)
+		&& ieee->current_network.berp_info_valid){
+		if(ieee->current_network.erp_value& ERP_UseProtection)
+			ieee->current_network.buseprotection = true;
+		else
+			ieee->current_network.buseprotection = false;
+		}
+		if(is_beacon(beacon->header.frame_ctl))
+		{
+			if(ieee->state == IEEE80211_LINKED)
+				ieee->LinkDetectInfo.NumRecvBcnInPeriod++;
+		}
+		else //hidden AP
+			network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags);
+	}
+
+	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' (" MAC_FMT ") from "
+					     "network list.\n",
+					     escape_essid(target->ssid,
+							  target->ssid_len),
+					     MAC_ARG(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' (" MAC_FMT ") via %s.\n",
+				     escape_essid(network.ssid,
+						  network.ssid_len),
+				     MAC_ARG(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);
+		if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
+			ieee80211_softmac_new_net(ieee,&network);
+	} else {
+		IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
+				     escape_essid(target->ssid,
+						  target->ssid_len),
+				     MAC_ARG(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(beacon->header.frame_ctl) == 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);
+		if(renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE))
+			ieee80211_softmac_new_net(ieee,&network);
+	}
+
+	spin_unlock_irqrestore(&ieee->lock, flags);
+	if (is_beacon(beacon->header.frame_ctl)&&is_same_network(&ieee->current_network, &network, ieee)&&\
+		(ieee->state == IEEE80211_LINKED)) {
+		if(ieee->handle_beacon != NULL) {
+			ieee->handle_beacon(ieee->dev,beacon,&ieee->current_network);
+		}
+	}
+}
+
+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;
+
+	}
+}
+
+EXPORT_SYMBOL(ieee80211_rx_mgt);
+EXPORT_SYMBOL(ieee80211_rx);
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
new file mode 100644
index 0000000..8a86e93
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
@@ -0,0 +1,3287 @@
+/* IEEE 802.11 SoftMAC layer
+ * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
+ *
+ * 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/version.h>
+#include <asm/uaccess.h>
+#ifdef ENABLE_DOT11D
+#include "dot11d.h"
+#endif
+
+u8 rsn_authen_cipher_suite[16][4] = {
+	{0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved
+	{0x00,0x0F,0xAC,0x01}, //WEP-40         //RSNA default
+	{0x00,0x0F,0xAC,0x02}, //TKIP           //NONE		//{used just as default}
+	{0x00,0x0F,0xAC,0x03}, //WRAP-historical
+	{0x00,0x0F,0xAC,0x04}, //CCMP
+	{0x00,0x0F,0xAC,0x05}, //WEP-104
+};
+
+short ieee80211_is_54g(struct ieee80211_network net)
+{
+	return ((net.rates_ex_len > 0) || (net.rates_len > 4));
+}
+
+short ieee80211_is_shortslot(struct ieee80211_network net)
+{
+	return (net.capability & WLAN_CAPABILITY_SHORT_SLOT);
+}
+
+/* returns the total length needed for pleacing 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
+ */
+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;
+}
+
+/* pleace the MFIE rate, tag to the memory (double) poined.
+ * Then it updates the pointer so that
+ * it points after the new MFIE tag added.
+ */
+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;
+}
+
+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;
+}
+
+
+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;
+}
+
+#ifdef THOMAS_TURBO
+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");
+}
+#endif
+
+void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
+{
+	int nh;
+	nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
+
+/*
+ * if the queue is full but we have newer frames then
+ * just overwrites the oldest.
+ *
+ * if (nh == ieee->mgmt_queue_tail)
+ *		return -1;
+ */
+	ieee->mgmt_queue_head = nh;
+	ieee->mgmt_queue_ring[nh] = skb;
+
+	//return 0;
+}
+
+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;
+}
+
+void init_mgmt_queue(struct ieee80211_device *ieee)
+{
+	ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
+}
+
+u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee)
+{
+	PRT_HIGH_THROUGHPUT      pHTInfo = ieee->pHTInfo;
+	u8 rate;
+
+	// 2008/01/25 MH For broadcom, MGNT frame set as OFDM 6M.
+	if(pHTInfo->IOTAction & HT_IOT_ACT_MGNT_USE_CCK_6M)
+		rate = 0x0c;
+	else
+		rate = ieee->basic_rate & 0x7f;
+
+	if(rate == 0){
+		// 2005.01.26, by rcnjko.
+		if(ieee->mode == IEEE_A||
+		   ieee->mode== IEEE_N_5G||
+		   (ieee->mode== IEEE_N_24G&&!pHTInfo->bCurSuppCCK))
+			rate = 0x0c;
+		else
+			rate = 0x02;
+	}
+
+	/*
+	// Data rate of ProbeReq is already decided. Annie, 2005-03-31
+	if( pMgntInfo->bScanInProgress || (pMgntInfo->bDualModeScanStep!=0) )
+	{
+	if(pMgntInfo->dot11CurrentWirelessMode==WIRELESS_MODE_A)
+	rate = 0x0c;
+	else
+	rate = 0x02;
+	}
+	 */
+	return rate;
+}
+
+
+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;
+
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8);
+	spin_lock_irqsave(&ieee->lock, flags);
+
+	/* called with 2nd param 0, no mgmt lock required */
+	ieee80211_sta_wakeup(ieee,0);
+
+	tcb_desc->queue_index = MGNT_QUEUE;
+	tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
+	tcb_desc->RATRIndex = 7;
+	tcb_desc->bTxDisableRateFallBack = 1;
+	tcb_desc->bTxUseDriverAssingedRate = 1;
+
+	if(single){
+		if(ieee->queue_stop){
+			enqueue_mgmt(ieee,skb);
+		}else{
+			header->seq_ctl = 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);
+			//dev_kfree_skb_any(skb);//edit by thomas
+		}
+
+		spin_unlock_irqrestore(&ieee->lock, flags);
+	}else{
+		spin_unlock_irqrestore(&ieee->lock, flags);
+		spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
+
+		header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
+
+		if (ieee->seq_ctrl[0] == 0xFFF)
+			ieee->seq_ctrl[0] = 0;
+		else
+			ieee->seq_ctrl[0]++;
+
+		/* check wether the managed packet queued greater than 5 */
+		if(!ieee->check_nic_enough_desc(ieee->dev,tcb_desc->queue_index)||\
+				(skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0)||\
+				(ieee->queue_stop) ) {
+			/* insert the skb packet to the management queue */
+			/* as for the completion function, it does not need
+			 * to check it any more.
+			 * */
+			printk("%s():insert to waitqueue!\n",__FUNCTION__);
+			skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb);
+		} else {
+			//printk("TX packet!\n");
+			ieee->softmac_hard_start_xmit(skb,ieee->dev);
+			//dev_kfree_skb_any(skb);//edit by thomas
+		}
+		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_ctl = 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_ctl = 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_hard_start_xmit(skb,ieee->dev);
+
+	}
+	//dev_kfree_skb_any(skb);//edit by thomas
+}
+
+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 + ieee->tx_headroom);
+	if (!skb)
+		return NULL;
+
+	skb_reserve(skb, ieee->tx_headroom);
+
+	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);
+void ieee80211_send_beacon(struct ieee80211_device *ieee)
+{
+	struct sk_buff *skb;
+	if(!ieee->ieee_up)
+		return;
+	//unsigned long flags;
+	skb = ieee80211_get_beacon_(ieee);
+
+	if (skb){
+		softmac_mgmt_xmit(skb, ieee);
+		ieee->softmac_stats.tx_beacons++;
+		//dev_kfree_skb_any(skb);//edit by thomas
+	}
+//	ieee->beacon_timer.expires = jiffies +
+//		(MSECS( ieee->current_network.beacon_interval -5));
+
+	//spin_lock_irqsave(&ieee->beacon_lock,flags);
+	if(ieee->beacon_txing && ieee->ieee_up){
+//		if(!timer_pending(&ieee->beacon_timer))
+//			add_timer(&ieee->beacon_timer);
+		mod_timer(&ieee->beacon_timer,jiffies+(MSECS(ieee->current_network.beacon_interval-5)));
+	}
+	//spin_unlock_irqrestore(&ieee->beacon_lock,flags);
+}
+
+
+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);
+}
+
+
+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++;
+		//dev_kfree_skb_any(skb);//edit by thomas
+	}
+}
+
+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.
+ */
+void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
+{
+	short ch = 0;
+#ifdef ENABLE_DOT11D
+	u8 channel_map[MAX_CHANNEL_NUMBER+1];
+	memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
+#endif
+	down(&ieee->scan_sem);
+
+	while(1)
+	{
+
+		do{
+			ch++;
+			if (ch > MAX_CHANNEL_NUMBER)
+				goto out; /* scan completed */
+#ifdef ENABLE_DOT11D
+		}while(!channel_map[ch]);
+#else
+		}while(!ieee->channel_map[ch]);
+#endif
+
+		/* this fuction 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 temporarly '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);
+#ifdef ENABLE_DOT11D
+		if(channel_map[ch] == 1)
+#endif
+		ieee80211_send_probe_requests(ieee);
+
+		/* this prevent excessive time wait when we
+		 * need to wait for a syncro scan to end..
+		 */
+		if(ieee->state < IEEE80211_LINKED)
+			;
+		else
+		if (ieee->sync_scan_hurryup)
+			goto out;
+
+
+		msleep_interruptible_rsl(IEEE80211_SOFTMAC_SCAN_TIME);
+
+	}
+out:
+	if(ieee->state < IEEE80211_LINKED){
+		ieee->actscanning = false;
+		up(&ieee->scan_sem);
+	}
+	else{
+	ieee->sync_scan_hurryup = 0;
+#ifdef ENABLE_DOT11D
+	if(IS_DOT11D_ENABLE(ieee))
+		DOT11D_ScanComplete(ieee);
+#endif
+	up(&ieee->scan_sem);
+}
+}
+
+
+void ieee80211_softmac_scan_wq(struct work_struct *work)
+{
+	struct delayed_work *dwork = container_of(work, struct delayed_work, work);
+	struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
+	static short watchdog = 0;
+#ifdef ENABLE_DOT11D
+	u8 channel_map[MAX_CHANNEL_NUMBER+1];
+	memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
+#endif
+	if(!ieee->ieee_up)
+		return;
+	down(&ieee->scan_sem);
+	do{
+		ieee->current_network.channel =
+			(ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
+		if (watchdog++ > MAX_CHANNEL_NUMBER)
+		{
+		//if current channel is not in channel map, set to default channel.
+		#ifdef ENABLE_DOT11D
+			if (!channel_map[ieee->current_network.channel]);
+		#else
+			if (!ieee->channel_map[ieee->current_network.channel]);
+		#endif
+				ieee->current_network.channel = 6;
+				goto out; /* no good chans */
+		}
+#ifdef ENABLE_DOT11D
+	}while(!channel_map[ieee->current_network.channel]);
+#else
+	}while(!ieee->channel_map[ieee->current_network.channel]);
+#endif
+	if (ieee->scanning == 0 )
+		goto out;
+	ieee->set_chan(ieee->dev, ieee->current_network.channel);
+#ifdef ENABLE_DOT11D
+	if(channel_map[ieee->current_network.channel] == 1)
+#endif
+	ieee80211_send_probe_requests(ieee);
+
+
+	queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
+
+	up(&ieee->scan_sem);
+	return;
+out:
+#ifdef ENABLE_DOT11D
+	if(IS_DOT11D_ENABLE(ieee))
+		DOT11D_ScanComplete(ieee);
+#endif
+	ieee->actscanning = false;
+	watchdog = 0;
+	ieee->scanning = 0;
+	up(&ieee->scan_sem);
+}
+
+
+
+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);
+}
+
+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,ieee->basic_rate);
+	if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
+		ieee80211_beacons_start(ieee);
+}
+
+
+void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
+{
+//	unsigned long flags;
+
+	//ieee->sync_scan_hurryup = 1;
+
+	down(&ieee->scan_sem);
+//	spin_lock_irqsave(&ieee->lock, flags);
+
+	if (ieee->scanning == 1){
+		ieee->scanning = 0;
+
+		cancel_delayed_work(&ieee->softmac_scan_wq);
+	}
+
+//	spin_unlock_irqrestore(&ieee->lock, flags);
+	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_start_scan(struct ieee80211_device *ieee)
+{
+#ifdef ENABLE_DOT11D
+	if(IS_DOT11D_ENABLE(ieee) )
+	{
+		if(IS_COUNTRY_IE_VALID(ieee))
+		{
+			RESET_CIE_WATCHDOG(ieee);
+		}
+	}
+#endif
+	if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
+		if (ieee->scanning == 0){
+			ieee->scanning = 1;
+			queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0);
+		}
+	}else
+		ieee->start_scan(ieee->dev);
+
+}
+
+/* called with wx_sem held */
+void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
+{
+#ifdef ENABLE_DOT11D
+	if(IS_DOT11D_ENABLE(ieee) )
+	{
+		if(IS_COUNTRY_IE_VALID(ieee))
+		{
+			RESET_CIE_WATCHDOG(ieee);
+		}
+	}
+#endif
+	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;
+	int len = sizeof(struct ieee80211_authentication) + challengelen + ieee->tx_headroom;
+
+
+	skb = dev_alloc_skb(len);
+	if (!skb) return NULL;
+
+	skb_reserve(skb, ieee->tx_headroom);
+	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;
+	if(ieee->auth_mode == 0)
+		auth->algorithm = WLAN_AUTH_OPEN;
+	else if(ieee->auth_mode == 1)
+		auth->algorithm = WLAN_AUTH_SHARED_KEY;
+	else if(ieee->auth_mode == 2)
+		auth->algorithm = WLAN_AUTH_OPEN;//0x80;
+	printk("=================>%s():auth->algorithm is %d\n",__FUNCTION__,auth->algorithm);
+	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 = NULL;
+	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;
+	u8 erpinfo_content = 0;
+
+	u8* tmp_ht_cap_buf;
+	u8 tmp_ht_cap_len=0;
+	u8* tmp_ht_info_buf;
+	u8 tmp_ht_info_len=0;
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	u8* tmp_generic_ie_buf=NULL;
+	u8 tmp_generic_ie_len=0;
+
+	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;
+
+
+	crypt = ieee->crypt[ieee->tx_keyidx];
+
+
+	encrypt = ieee->host_encrypt && crypt && crypt->ops &&
+		((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len));
+	//HT ralated element
+	tmp_ht_cap_buf =(u8*) &(ieee->pHTInfo->SelfHTCap);
+	tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
+	tmp_ht_info_buf =(u8*) &(ieee->pHTInfo->SelfHTInfo);
+	tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo);
+	HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, &tmp_ht_cap_len,encrypt);
+	HTConstructInfoElement(ieee,tmp_ht_info_buf,&tmp_ht_info_len, encrypt);
+
+
+	if(pHTInfo->bRegRT2RTAggregation)
+	{
+		tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
+		tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer);
+		HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len);
+	}
+//	printk("===============>tmp_ht_cap_len is %d,tmp_ht_info_len is %d, tmp_generic_ie_len is %d\n",tmp_ht_cap_len,tmp_ht_info_len,tmp_generic_ie_len);
+	beacon_size = sizeof(struct ieee80211_probe_response)+2+
+		ssid_len
+		+3 //channel
+		+rate_len
+		+rate_ex_len
+		+atim_len
+		+erp_len
+		+wpa_ie_len
+	//	+tmp_ht_cap_len
+	//	+tmp_ht_info_len
+	//	+tmp_generic_ie_len
+//		+wmm_len+2
+		+ieee->tx_headroom;
+	skb = dev_alloc_skb(beacon_size);
+	if (!skb)
+		return NULL;
+	skb_reserve(skb, ieee->tx_headroom);
+	beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, (beacon_size - ieee->tx_headroom));
+	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);
+	beacon_buf->capability |=
+		cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE); //add short preamble here
+
+	if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
+		cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
+
+	crypt = ieee->crypt[ieee->tx_keyidx];
+	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[0].id = MFIE_TYPE_SSID;
+	beacon_buf->info_element[0].len = ssid_len;
+
+	tag = (u8*) beacon_buf->info_element[0].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){
+	u16 val16;
+		*(tag++) = MFIE_TYPE_IBSS_SET;
+		*(tag++) = 2;
+		//*((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window);
+		 val16 = cpu_to_le16(ieee->current_network.atim_window);
+		memcpy((u8 *)tag, (u8 *)&val16, 2);
+		tag+=2;
+	}
+
+	if(erp_len){
+		*(tag++) = MFIE_TYPE_ERP;
+		*(tag++) = 1;
+		*(tag++) = erpinfo_content;
+	}
+	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. WB 2008.07.07
+			memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
+		}
+		memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
+		tag += wpa_ie_len;
+	}
+
+	//skb->dev = ieee->dev;
+	return skb;
+}
+
+
+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 + ieee->tx_headroom;
+
+	skb = dev_alloc_skb(len);
+
+	if (!skb)
+		return NULL;
+
+	skb_reserve(skb, ieee->tx_headroom);
+
+	assoc = (struct ieee80211_assoc_response_frame *)
+		skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
+
+	assoc->header.frame_ctl = 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;
+}
+
+struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8 *dest)
+{
+	struct sk_buff *skb;
+	struct ieee80211_authentication *auth;
+	int len = ieee->tx_headroom + sizeof(struct ieee80211_authentication)+1;
+
+	skb = dev_alloc_skb(len);
+
+	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;
+
+
+}
+
+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_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
+		IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
+		(pwr ? IEEE80211_FCTL_PM:0));
+
+	return skb;
+
+
+}
+
+
+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);
+}
+
+
+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);
+}
+
+
+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);
+}
+
+
+inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
+{
+	struct sk_buff *skb;
+	//unsigned long flags;
+
+	struct ieee80211_assoc_request_frame *hdr;
+	u8 *tag;//,*rsn_ie;
+	//short info_addr = 0;
+	//int i;
+	//u16 suite_count = 0;
+	//u8 suit_select = 0;
+	//unsigned int wpa_len = beacon->wpa_ie_len;
+	//for HT
+	u8* ht_cap_buf = NULL;
+	u8 ht_cap_len=0;
+	u8* realtek_ie_buf=NULL;
+	u8 realtek_ie_len=0;
+	int wpa_ie_len= ieee->wpa_ie_len;
+	unsigned int ckip_ie_len=0;
+	unsigned int ccxrm_ie_len=0;
+	unsigned int cxvernum_ie_len=0;
+	struct ieee80211_crypt_data* crypt;
+	int encrypt;
+
+	unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
+	unsigned int wmm_info_len = beacon->qos_data.supported?9:0;
+#ifdef THOMAS_TURBO
+	unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
+#endif
+
+	int len = 0;
+
+	crypt = ieee->crypt[ieee->tx_keyidx];
+	encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name,"WEP") || wpa_ie_len));
+
+	//Include High Throuput capability && Realtek proprietary
+	if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
+	{
+		ht_cap_buf = (u8*)&(ieee->pHTInfo->SelfHTCap);
+		ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
+		HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt);
+		if(ieee->pHTInfo->bCurrentRT2RTAggregation)
+		{
+			realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
+			realtek_ie_len = sizeof( ieee->pHTInfo->szRT2RTAggBuffer);
+			HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len);
+
+		}
+	}
+	if(ieee->qos_support){
+		wmm_info_len = beacon->qos_data.supported?9:0;
+	}
+
+
+	if(beacon->bCkipSupported)
+	{
+		ckip_ie_len = 30+2;
+	}
+	if(beacon->bCcxRmEnable)
+	{
+		ccxrm_ie_len = 6+2;
+	}
+	if( beacon->BssCcxVerNumber >= 2 )
+	{
+		cxvernum_ie_len = 5+2;
+	}
+#ifdef THOMAS_TURBO
+	len = sizeof(struct ieee80211_assoc_request_frame)+ 2
+		+ beacon->ssid_len//essid tagged val
+		+ rate_len//rates tagged val
+		+ wpa_ie_len
+		+ wmm_info_len
+		+ turbo_info_len
+		+ ht_cap_len
+		+ realtek_ie_len
+		+ ckip_ie_len
+		+ ccxrm_ie_len
+		+ cxvernum_ie_len
+		+ ieee->tx_headroom;
+#else
+	len = sizeof(struct ieee80211_assoc_request_frame)+ 2
+		+ beacon->ssid_len//essid tagged val
+		+ rate_len//rates tagged val
+		+ wpa_ie_len
+		+ wmm_info_len
+		+ ht_cap_len
+		+ realtek_ie_len
+		+ ckip_ie_len
+		+ ccxrm_ie_len
+		+ cxvernum_ie_len
+		+ ieee->tx_headroom;
+#endif
+
+	skb = dev_alloc_skb(len);
+
+	if (!skb)
+		return NULL;
+
+	skb_reserve(skb, ieee->tx_headroom);
+
+	hdr = (struct ieee80211_assoc_request_frame *)
+		skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)+2);
+
+
+	hdr->header.frame_ctl = 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, John
+
+	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); //add short_preamble here
+
+	if(ieee->short_slot)
+		hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
+	if (wmm_info_len) //QOS
+	hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS);
+
+	hdr->listen_interval = 0xa; //FIXME
+
+	hdr->info_element[0].id = MFIE_TYPE_SSID;
+
+	hdr->info_element[0].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);
+	// For CCX 1 S13, CKIP. Added by Annie, 2006-08-14.
+	if( beacon->bCkipSupported )
+	{
+		static u8	AironetIeOui[] = {0x00, 0x01, 0x66}; // "4500-client"
+		u8	CcxAironetBuf[30];
+		OCTET_STRING	osCcxAironetIE;
+
+		memset(CcxAironetBuf, 0,30);
+		osCcxAironetIE.Octet = CcxAironetBuf;
+		osCcxAironetIE.Length = sizeof(CcxAironetBuf);
+		//
+		// Ref. CCX test plan v3.61, 3.2.3.1 step 13.
+		// We want to make the device type as "4500-client". 060926, by CCW.
+		//
+		memcpy(osCcxAironetIE.Octet, AironetIeOui, sizeof(AironetIeOui));
+
+		// CCX1 spec V1.13, A01.1 CKIP Negotiation (page23):
+		// "The CKIP negotiation is started with the associate request from the client to the access point,
+		//  containing an Aironet element with both the MIC and KP bits set."
+		osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |=  (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC) ;
+		tag = skb_put(skb, ckip_ie_len);
+		*tag++ = MFIE_TYPE_AIRONET;
+		*tag++ = osCcxAironetIE.Length;
+		memcpy(tag,osCcxAironetIE.Octet,osCcxAironetIE.Length);
+		tag += osCcxAironetIE.Length;
+	}
+
+	if(beacon->bCcxRmEnable)
+	{
+		static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00};
+		OCTET_STRING osCcxRmCap;
+
+		osCcxRmCap.Octet = CcxRmCapBuf;
+		osCcxRmCap.Length = sizeof(CcxRmCapBuf);
+		tag = skb_put(skb,ccxrm_ie_len);
+		*tag++ = MFIE_TYPE_GENERIC;
+		*tag++ = osCcxRmCap.Length;
+		memcpy(tag,osCcxRmCap.Octet,osCcxRmCap.Length);
+		tag += osCcxRmCap.Length;
+	}
+
+	if( beacon->BssCcxVerNumber >= 2 )
+	{
+		u8			CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
+		OCTET_STRING	osCcxVerNum;
+		CcxVerNumBuf[4] = beacon->BssCcxVerNumber;
+		osCcxVerNum.Octet = CcxVerNumBuf;
+		osCcxVerNum.Length = sizeof(CcxVerNumBuf);
+		tag = skb_put(skb,cxvernum_ie_len);
+		*tag++ = MFIE_TYPE_GENERIC;
+		*tag++ = osCcxVerNum.Length;
+		memcpy(tag,osCcxVerNum.Octet,osCcxVerNum.Length);
+		tag += osCcxVerNum.Length;
+	}
+	//HT cap element
+	if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
+		if(ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC)
+		{
+			tag = skb_put(skb, ht_cap_len);
+			*tag++ = MFIE_TYPE_HT_CAP;
+			*tag++ = ht_cap_len - 2;
+			memcpy(tag, ht_cap_buf,ht_cap_len -2);
+			tag += ht_cap_len -2;
+		}
+	}
+
+
+	//choose what wpa_supplicant gives to associate.
+	tag = skb_put(skb, wpa_ie_len);
+	if (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);
+	}
+#ifdef THOMAS_TURBO
+	tag = skb_put(skb,turbo_info_len);
+	if(turbo_info_len) {
+		ieee80211_TURBO_Info(ieee, &tag);
+	}
+#endif
+
+	if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
+		if(ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC)
+		{
+			tag = skb_put(skb, ht_cap_len);
+			*tag++ = MFIE_TYPE_GENERIC;
+			*tag++ = ht_cap_len - 2;
+			memcpy(tag, ht_cap_buf,ht_cap_len - 2);
+			tag += ht_cap_len -2;
+		}
+
+		if(ieee->pHTInfo->bCurrentRT2RTAggregation){
+			tag = skb_put(skb, realtek_ie_len);
+			*tag++ = MFIE_TYPE_GENERIC;
+			*tag++ = realtek_ie_len - 2;
+			memcpy(tag, realtek_ie_buf,realtek_ie_len -2 );
+		}
+	}
+//	printk("<=====%s(), %p, %p\n", __FUNCTION__, ieee->dev, ieee->dev->dev_addr);
+//	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
+	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 possibily
+	 * 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);
+}
+
+void ieee80211_associate_abort_cb(unsigned long dev)
+{
+	ieee80211_associate_abort((struct ieee80211_device *) dev);
+}
+
+
+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");
+		//printk(KERN_WARNING "Sending authentication request\n");
+		softmac_mgmt_xmit(skb, ieee);
+		//BUGON when you try to add_timer twice, using mod_timer may be better, john0709
+		if(!timer_pending(&ieee->associate_timer)){
+			ieee->associate_timer.expires = jiffies + (HZ / 2);
+			add_timer(&ieee->associate_timer);
+		}
+		//dev_kfree_skb_any(skb);//edit by thomas
+	}
+}
+
+void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
+{
+	u8 *c;
+	struct sk_buff *skb;
+	struct ieee80211_network *beacon = &ieee->current_network;
+//	int hlen = sizeof(struct ieee80211_authentication);
+
+	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);
+		mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
+		//dev_kfree_skb_any(skb);//edit by thomas
+	}
+	kfree(challenge);
+}
+
+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);
+		mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
+		//dev_kfree_skb_any(skb);//edit by thomas
+	}
+}
+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 = 108;
+		printk(KERN_INFO"Using G rates:%d\n", ieee->rate);
+	}else{
+		ieee->rate = 22;
+		printk(KERN_INFO"Using B rates:%d\n", ieee->rate);
+	}
+	if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
+	{
+		printk("Successfully associated, ht enabled\n");
+		HTOnAssocRsp(ieee);
+	}
+	else
+	{
+		printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT);
+		memset(ieee->dot11HTOperationalRateSet, 0, 16);
+		//HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+	}
+	ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500);
+	// To prevent the immediately calling watch_dog after association.
+	if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
+	{
+		ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
+		ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;
+	}
+	ieee->link_change(ieee->dev);
+	if(ieee->is_silent_reset == 0){
+		printk("============>normal associate\n");
+	notify_wx_assoc_event(ieee);
+	}
+	else if(ieee->is_silent_reset == 1)
+	{
+		printk("==================>silent reset associate\n");
+		ieee->is_silent_reset = 0;
+	}
+
+	if (ieee->data_hard_resume)
+		ieee->data_hard_resume(ieee->dev);
+	netif_carrier_on(ieee->dev);
+}
+
+void ieee80211_associate_complete(struct ieee80211_device *ieee)
+{
+//	int i;
+//	struct net_device* dev = ieee->dev;
+	del_timer_sync(&ieee->associate_timer);
+
+	ieee->state = IEEE80211_LINKED;
+	//ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet);
+	queue_work(ieee->wq, &ieee->associate_complete_wq);
+}
+
+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);
+	printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel);
+	//ieee->set_chan(ieee->dev, ieee->current_network.channel);
+	HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+
+	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;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
+		ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0';
+		ssidbroad =  !(net->ssid_len == 0 || net->ssid[0]== '\0');
+		apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
+		ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\
+				(!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
+
+
+		if (	/* if the user set the AP check if match.
+			 * if the network does not broadcast essid we check the user supplyed 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 bradcast and that those two bssid matches
+			 */
+			(!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:%d, qos:%d, myHT:%d, networkHT:%d\n",ieee->current_network.ssid,ieee->current_network.channel, ieee->current_network.qos_data.supported, ieee->pHTInfo->bEnableHT, ieee->current_network.bssht.bdSupportHT);
+
+				//ieee->pHTInfo->IOTAction = 0;
+				HTResetIOTSetting(ieee->pHTInfo);
+				if (ieee->iw_mode == IW_MODE_INFRA){
+					/* Join the network for the first time */
+					ieee->AsocRetryCount = 0;
+					//for HT by amy 080514
+					if((ieee->current_network.qos_data.supported == 1) &&
+					  // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT))
+					   ieee->current_network.bssht.bdSupportHT)
+/*WB, 2008.09.09:bCurrentHTSupport and bEnableHT two flags are going to put together to check whether we are in HT now, so needn't to check bEnableHT flags here. That's is to say we will set to HT support whenever joined AP has the ability to support HT. And whether we are in HT or not, please check bCurrentHTSupport&&bEnableHT now please.*/
+					{
+					//	ieee->pHTInfo->bCurrentHTSupport = true;
+						HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network));
+					}
+					else
+					{
+						ieee->pHTInfo->bCurrentHTSupport = false;
+					}
+
+					ieee->state = IEEE80211_ASSOCIATING;
+					queue_work(ieee->wq, &ieee->associate_procedure_wq);
+				}else{
+					if(ieee80211_is_54g(ieee->current_network) &&
+						(ieee->modulation & IEEE80211_OFDM_MODULATION)){
+						ieee->rate = 108;
+						ieee->SetWirelessMode(ieee->dev, IEEE_G);
+						printk(KERN_INFO"Using G rates\n");
+					}else{
+						ieee->rate = 22;
+						ieee->SetWirelessMode(ieee->dev, IEEE_B);
+						printk(KERN_INFO"Using B rates\n");
+					}
+					memset(ieee->dot11HTOperationalRateSet, 0, 16);
+					//HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+					ieee->state = IEEE80211_LINKED;
+				}
+
+		}
+	}
+
+}
+
+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 = (u8*)kmalloc(*chlen, GFP_ATOMIC);
+			memcpy(*challenge, t, *chlen);
+		}
+	}
+
+	return cpu_to_le16(a->status);
+
+}
+
+
+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 */
+	}
+
+	//IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
+	if (ssidlen == 0) return 1;
+
+	if (!ssid) return 1; /* ssid not found in tagged param */
+	return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
+
+}
+
+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 ieee80211_device *ieee, struct sk_buff *skb, int *aid)
+{
+	struct ieee80211_assoc_response_frame *response_head;
+	u16 status_code;
+
+	if (skb->len <  sizeof(struct ieee80211_assoc_response_frame)){
+		IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
+		return 0xcafe;
+	}
+
+	response_head = (struct ieee80211_assoc_response_frame*) skb->data;
+	*aid = le16_to_cpu(response_head->aid) & 0x3fff;
+
+	status_code = le16_to_cpu(response_head->status);
+	if((status_code==WLAN_STATUS_ASSOC_DENIED_RATES || \
+	   status_code==WLAN_STATUS_CAPS_UNSUPPORTED)&&
+	   ((ieee->mode == IEEE_G) &&
+	    (ieee->current_network.mode == IEEE_N_24G) &&
+	    (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) {
+		 ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE;
+	}else {
+		 ieee->AsocRetryCount = 0;
+	}
+
+	return le16_to_cpu(response_head->status);
+}
+
+static inline void
+ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
+{
+	u8 dest[ETH_ALEN];
+
+	//IEEE80211DMESG("Rx probe");
+	ieee->softmac_stats.rx_probe_rq++;
+	//DMESG("Dest is "MACSTR, MAC2STR(dest));
+	if (probe_rq_parse(ieee, skb, dest)){
+		//IEEE80211DMESG("Was for me!");
+		ieee->softmac_stats.tx_probe_rs++;
+		ieee80211_resp_to_probe(ieee, dest);
+	}
+}
+
+static inline void
+ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
+{
+	u8 dest[ETH_ALEN];
+	int status;
+	//IEEE80211DMESG("Rx probe");
+	ieee->softmac_stats.rx_auth_rq++;
+
+	if ((status = auth_rq_parse(skb, dest))!= -1){
+		ieee80211_resp_to_auth(ieee, status, dest);
+	}
+	//DMESG("Dest is "MACSTR, MAC2STR(dest));
+
+}
+
+static inline void
+ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
+{
+
+	u8 dest[ETH_ALEN];
+	//unsigned long flags;
+
+	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: "MAC_FMT"\n", MAC_ARG(dest));
+	//FIXME
+}
+
+
+
+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);
+
+}
+
+
+short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
+{
+	int timeout = ieee->ps_timeout;
+	u8 dtim;
+	/*if(ieee->ps == IEEE80211_PS_DISABLED ||
+		ieee->iw_mode != IW_MODE_INFRA ||
+		ieee->state != IEEE80211_LINKED)
+
+		return 0;
+	*/
+	dtim = ieee->current_network.dtim_data;
+	//printk("DTIM\n");
+	if(!(dtim & IEEE80211_DTIM_VALID))
+		return 0;
+	timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
+	//printk("VALID\n");
+	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]
+			+ (ieee->current_network.beacon_interval
+			* ieee->current_network.dtim_period) * 1000;
+	}
+
+	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;
+
+
+}
+
+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){
+		//	printk("send null 1\n");
+			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){
+			printk("Warning: driver is probably failing to report TX ps error\n");
+			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
+		 */
+	}
+	/* 21112005 - tx again null without PS bit if lost */
+	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);
+}
+void ieee80211_process_action(struct ieee80211_device* ieee, struct sk_buff* skb)
+{
+	struct ieee80211_hdr* header = (struct ieee80211_hdr*)skb->data;
+	u8* act = ieee80211_get_payload(header);
+	u8 tmp = 0;
+//	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
+	if (act == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n");
+		return;
+	}
+	tmp = *act;
+	act ++;
+	switch (tmp)
+	{
+		case ACT_CAT_BA:
+			if (*act == ACT_ADDBAREQ)
+			ieee80211_rx_ADDBAReq(ieee, skb);
+			else if (*act == ACT_ADDBARSP)
+			ieee80211_rx_ADDBARsp(ieee, skb);
+			else if (*act == ACT_DELBA)
+			ieee80211_rx_DELBA(ieee, skb);
+			break;
+		default:
+//			if (net_ratelimit())
+//			IEEE80211_DEBUG(IEEE80211_DL_BA, "unknown action frame(%d)\n", tmp);
+			break;
+	}
+	return;
+
+}
+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;
+	int chlen=0;
+	int aid;
+	struct ieee80211_assoc_response_frame *assoc_resp;
+//	struct ieee80211_info_element *info_element;
+	bool bSupportNmode = true, bHalfSupportNmode = false; //default support N mode, disable halfNmode
+
+	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_ctl) != IEEE80211_STYPE_PROBE_RESP &&
+		WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
+		ieee->last_rx_ps_time = jiffies;
+
+	switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
+
+		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){
+				struct ieee80211_network network_resp;
+				struct ieee80211_network *network = &network_resp;
+
+				if (0 == (errcode=assoc_parse(ieee,skb, &aid))){
+					ieee->state=IEEE80211_LINKED;
+					ieee->assoc_id = aid;
+					ieee->softmac_stats.rx_ass_ok++;
+					/* station support qos */
+					/* Let the register setting defaultly with Legacy station */
+					if(ieee->qos_support) {
+						assoc_resp = (struct ieee80211_assoc_response_frame*)skb->data;
+						memset(network, 0, sizeof(*network));
+						if (ieee80211_parse_info_param(ieee,assoc_resp->info_element,\
+									rx_stats->len - sizeof(*assoc_resp),\
+									network,rx_stats)){
+							return 1;
+						}
+						else
+						{	//filling the PeerHTCap. //maybe not neccesary as we can get its info from current_network.
+							memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen);
+							memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen);
+						}
+						if (ieee->handle_assoc_response != NULL)
+							ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame*)header, network);
+					}
+					ieee80211_associate_complete(ieee);
+				} else {
+					/* aid could not been allocated */
+					ieee->softmac_stats.rx_ass_err++;
+					printk(
+						"Association response status code 0x%x\n",
+						errcode);
+					IEEE80211_DEBUG_MGMT(
+						"Association response status code 0x%x\n",
+						errcode);
+					if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) {
+						queue_work(ieee->wq, &ieee->associate_procedure_wq);
+					} else {
+						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");
+
+						if (0 == (errcode=auth_parse(skb, &challenge, &chlen))){
+							if(ieee->open_wep || !challenge){
+								ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
+								ieee->softmac_stats.rx_auth_rs_ok++;
+								if(!(ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE))
+								{
+									if (!ieee->GetNmodeSupportBySecCfg(ieee->dev))
+									{
+												// WEP or TKIP encryption
+										if(IsHTHalfNmodeAPs(ieee))
+										{
+											bSupportNmode = true;
+											bHalfSupportNmode = true;
+										}
+										else
+										{
+											bSupportNmode = false;
+											bHalfSupportNmode = false;
+										}
+									printk("==========>to link with AP using SEC(%d, %d)", bSupportNmode, bHalfSupportNmode);
+									}
+								}
+								/* Dummy wirless mode setting to avoid encryption issue */
+								if(bSupportNmode) {
+									//N mode setting
+									ieee->SetWirelessMode(ieee->dev, \
+											ieee->current_network.mode);
+								}else{
+									//b/g mode setting
+									/*TODO*/
+									ieee->SetWirelessMode(ieee->dev, IEEE_G);
+								}
+
+								if (ieee->current_network.mode == IEEE_N_24G && bHalfSupportNmode == true)
+								{
+									printk("===============>entern half N mode\n");
+									ieee->bHalfWirelessN24GMode = true;
+								}
+								else
+									ieee->bHalfWirelessN24GMode = false;
+
+								ieee80211_associate_step2(ieee);
+							}else{
+								ieee80211_auth_challenge(ieee, challenge, chlen);
+							}
+						}else{
+							ieee->softmac_stats.rx_auth_rs_err++;
+							IEEE80211_DEBUG_MGMT("Authentication respose 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){
+
+				ieee->state = IEEE80211_ASSOCIATING;
+				ieee->softmac_stats.reassoc++;
+
+				notify_wx_assoc_event(ieee);
+				//HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+				RemovePeerTS(ieee, header->addr2);
+				queue_work(ieee->wq, &ieee->associate_procedure_wq);
+			}
+			break;
+		case IEEE80211_STYPE_MANAGE_ACT:
+			ieee80211_process_action(ieee,skb);
+			break;
+		default:
+			return -1;
+			break;
+	}
+
+	//dev_kfree_skb_any(skb);
+	return 0;
+}
+
+/* following are for a simplier 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 enought 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 treshold is not enought.. 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 int queue_index = txb->queue_index;
+	unsigned long flags;
+	int  i;
+	cb_desc *tcb_desc = NULL;
+
+	spin_lock_irqsave(&ieee->lock,flags);
+
+	/* called with 2nd parm 0, no tx mgmt lock required */
+	ieee80211_sta_wakeup(ieee,0);
+
+	/* update the tx status */
+	ieee->stats.tx_bytes += txb->payload_size;
+	ieee->stats.tx_packets++;
+	tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
+	if(tcb_desc->bMulticast) {
+		ieee->stats.multicast++;
+	}
+	/* if xmit available, just xmit it immediately, else just insert it to the wait queue */
+	for(i = 0; i < txb->nr_frags; i++) {
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+		if ((skb_queue_len(&ieee->skb_drv_aggQ[queue_index]) != 0) ||
+#else
+		if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) ||
+#endif
+		(!ieee->check_nic_enough_desc(ieee->dev,queue_index))||\
+		     (ieee->queue_stop)) {
+			/* insert the skb packet to the wait queue */
+			/* as for the completion function, it does not need
+			 * to check it any more.
+			 * */
+			//printk("error:no descriptor left@queue_index %d\n", queue_index);
+			//ieee80211_stop_queue(ieee);
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+			skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]);
+#else
+			skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
+#endif
+		}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 */
+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);
+				//(i+1)<ieee->tx_pending.txb->nr_frags);
+			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_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_ctl = 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);//edit by thomas
+		}
+	}
+	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_stop_queue(struct ieee80211_device *ieee)
+{
+	//unsigned long flags;
+	//spin_lock_irqsave(&ieee->lock,flags);
+
+	if (! netif_queue_stopped(ieee->dev)){
+		netif_stop_queue(ieee->dev);
+		ieee->softmac_stats.swtxstop++;
+	}
+	ieee->queue_stop = 1;
+	//spin_unlock_irqrestore(&ieee->lock,flags);
+
+}
+
+
+inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
+{
+
+	get_random_bytes(ieee->current_network.bssid, ETH_ALEN);
+
+	/* an IBSS cell address must have the two less significant
+	 * bits of the first byte = 2
+	 */
+	ieee->current_network.bssid[0] &= ~0x01;
+	ieee->current_network.bssid[0] |= 0x02;
+}
+
+/* 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);
+}
+
+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);
+	}
+}
+void ieee80211_start_ibss_wq(struct work_struct *work)
+{
+
+	struct delayed_work *dwork = container_of(work, struct 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
+	 */
+	if(!ieee->proto_started){
+		printk("==========oh driver down return\n");
+		return;
+	}
+	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);
+
+
+#ifdef ENABLE_DOT11D //if creating an ad-hoc, set its channel to 10 temporarily--this is the requirement for ASUS, not 11D, so disable 11d.
+//	if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK))
+	if (ieee->state == IEEE80211_NOLINK)
+		ieee->current_network.channel = 6;
+#endif
+	/* if not then the state is not linked. Maybe the user swithced 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 tryed to associate when
+	 * we had just checked the ieee->state and we was going to start the
+	 * scan) beacause 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 = 108;
+		}else{
+			ieee->current_network.rates_ex_len = 0;
+			ieee->rate = 22;
+		}
+
+		// By default, WMM function will be disabled in IBSS mode
+		ieee->current_network.QoS_Enable = 0;
+		ieee->SetWirelessMode(ieee->dev, IEEE_G);
+		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);
+
+	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, 150);
+}
+
+/* this is called only in user context, with wx_sem held */
+void ieee80211_start_bss(struct ieee80211_device *ieee)
+{
+	unsigned long flags;
+#ifdef ENABLE_DOT11D
+	//
+	// 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;
+		}
+	}
+#endif
+	/* 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_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);
+#ifdef ENABLE_DOT11D
+	if(IS_DOT11D_ENABLE(ieee))
+		Dot11d_Reset(ieee);
+#endif
+	ieee->state = IEEE80211_NOLINK;
+	ieee->is_set_key = false;
+	ieee->link_change(ieee->dev);
+	//HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+	notify_wx_assoc_event(ieee);
+
+}
+void ieee80211_associate_retry_wq(struct work_struct *work)
+{
+        struct delayed_work *dwork = container_of(work, struct 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 procdure (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;
+
+	ieee80211_softmac_check_all_nets(ieee);
+
+	spin_lock_irqsave(&ieee->lock, flags);
+
+	if(ieee->state == IEEE80211_NOLINK)
+		ieee80211_start_scan(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;
+	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_ctl = 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);
+	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);
+	RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS
+}
+
+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 */
+#ifdef ENABLE_DOT11D
+		}while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
+#else
+		}while(!ieee->channel_map[ch]);
+#endif
+		ieee->current_network.channel = ch;
+	}
+
+	if (ieee->current_network.beacon_interval == 0)
+		ieee->current_network.beacon_interval = 100;
+//	printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel);
+//	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 ??
+	 */
+	if (ieee->iw_mode == IW_MODE_INFRA)
+		ieee80211_start_bss(ieee);
+
+	else if (ieee->iw_mode == IW_MODE_ADHOC)
+		ieee80211_start_ibss(ieee);
+
+	else if (ieee->iw_mode == IW_MODE_MASTER)
+		ieee80211_start_master_bss(ieee);
+
+	else if(ieee->iw_mode == IW_MODE_MONITOR)
+		ieee80211_start_monitor_mode(ieee);
+}
+
+
+#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;
+	}
+#ifdef ENABLE_DOT11D
+	ieee->pDot11dInfo = kmalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
+	if (!ieee->pDot11dInfo)
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n");
+	memset(ieee->pDot11dInfo, 0, sizeof(RT_DOT11D_INFO));
+#endif
+	//added for  AP roaming
+	ieee->LinkDetectInfo.SlotNum = 2;
+	ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
+	ieee->LinkDetectInfo.NumRecvDataInPeriod=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 = 22;
+	ieee->ps = IEEE80211_PS_DISABLED;
+	ieee->sta_sleep = 0;
+	ieee->Regdot11HTOperationalRateSet[0]= 0xff;//support MCS 0~7
+	ieee->Regdot11HTOperationalRateSet[1]= 0xff;//support MCS 8~15
+	ieee->Regdot11HTOperationalRateSet[4]= 0x01;
+	//added by amy
+	ieee->actscanning = false;
+	ieee->beinretry = false;
+	ieee->is_set_key = false;
+	init_mgmt_queue(ieee);
+
+	ieee->sta_edca_param[0] = 0x0000A403;
+	ieee->sta_edca_param[1] = 0x0000A427;
+	ieee->sta_edca_param[2] = 0x005E4342;
+	ieee->sta_edca_param[3] = 0x002F3262;
+	ieee->aggregation = true;
+	ieee->enable_rx_imm_BA = 1;
+	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;
+
+#ifdef PF_SYNCTHREAD
+	ieee->wq = create_workqueue(DRV_NAME,0);
+#else
+	ieee->wq = create_workqueue(DRV_NAME);
+#endif
+
+	INIT_DELAYED_WORK(&ieee->start_ibss_wq,ieee80211_start_ibss_wq);
+	INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
+	INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
+	INIT_DELAYED_WORK(&ieee->softmac_scan_wq,ieee80211_softmac_scan_wq);
+	INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
+	INIT_WORK(&ieee->wx_sync_scan_wq,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);
+
+}
+
+void ieee80211_softmac_free(struct ieee80211_device *ieee)
+{
+	down(&ieee->wx_sem);
+#ifdef ENABLE_DOT11D
+	if(NULL != ieee->pDot11dInfo)
+	{
+		kfree(ieee->pDot11dInfo);
+		ieee->pDot11dInfo = NULL;
+	}
+#endif
+	del_timer_sync(&ieee->associate_timer);
+
+	cancel_delayed_work(&ieee->associate_retry_wq);
+	destroy_workqueue(ieee->wq);
+
+	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;
+}
+
+
+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 = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
+		if (buf == NULL)
+			return -ENOMEM;
+
+		memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
+		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;
+		ieee->auth_mode = 1;
+	} else if (value & AUTH_ALG_OPEN_SYSTEM){
+		sec.auth_mode = WLAN_AUTH_OPEN;
+		ieee->open_wep = 1;
+		ieee->auth_mode = 0;
+	}
+	else if (value & IW_AUTH_ALG_LEAP){
+		sec.auth_mode = WLAN_AUTH_LEAP;
+		ieee->open_wep = 1;
+		ieee->auth_mode = 2;
+	}
+
+
+	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:
+		// added for WPA2 mixed mode
+		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 (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+		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.encrypt = 0;
+			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.encrypt = 1;
+	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) {
+		request_module("ieee80211_crypt_wep");
+		ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
+		//set WEP40 first, it will be modified according to WEP104 or WEP40 at other place
+	} else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
+		request_module("ieee80211_crypt_tkip");
+		ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
+	} else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
+		request_module("ieee80211_crypt_ccmp");
+		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 = (struct ieee80211_crypt_data *)
+			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 && try_module_get(new_crypt->ops->owner))
+			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;
+}
+
+inline struct sk_buff *ieee80211_disassociate_skb(
+							struct ieee80211_network *beacon,
+							struct ieee80211_device *ieee,
+							u8	asRsn)
+{
+	struct sk_buff *skb;
+	struct ieee80211_disassoc *disass;
+
+	skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc));
+	if (!skb)
+		return NULL;
+
+	disass = (struct ieee80211_disassoc *) skb_put(skb,sizeof(struct ieee80211_disassoc));
+	disass->header.frame_ctl = 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->reason = 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);
+				//dev_kfree_skb_any(skb);//edit by thomas
+		}
+}
+
+int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
+{
+	struct ieee_param *param;
+	int ret=0;
+
+	down(&ieee->wx_sem);
+	//IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
+
+	if (p->length < sizeof(struct ieee_param) || !p->pointer){
+		ret = -EINVAL;
+		goto out;
+	}
+
+	param = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
+	if (param == NULL){
+		ret = -ENOMEM;
+		goto out;
+	}
+	if (copy_from_user(param, p->pointer, p->length)) {
+		kfree(param);
+		ret = -EFAULT;
+		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);
+}
+
+EXPORT_SYMBOL(ieee80211_get_beacon);
+EXPORT_SYMBOL(ieee80211_wake_queue);
+EXPORT_SYMBOL(ieee80211_stop_queue);
+EXPORT_SYMBOL(ieee80211_reset_queue);
+EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
+EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
+EXPORT_SYMBOL(ieee80211_is_shortslot);
+EXPORT_SYMBOL(ieee80211_is_54g);
+EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
+EXPORT_SYMBOL(ieee80211_ps_tx_ack);
+EXPORT_SYMBOL(ieee80211_softmac_xmit);
+EXPORT_SYMBOL(ieee80211_stop_send_beacons);
+EXPORT_SYMBOL(notify_wx_assoc_event);
+EXPORT_SYMBOL(SendDisassociation);
+EXPORT_SYMBOL(ieee80211_disassociate);
+EXPORT_SYMBOL(ieee80211_start_send_beacons);
+EXPORT_SYMBOL(ieee80211_stop_scan);
+EXPORT_SYMBOL(ieee80211_send_probe_requests);
+EXPORT_SYMBOL(ieee80211_softmac_scan_syncro);
+EXPORT_SYMBOL(ieee80211_start_scan_syncro);
+//EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame);
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c
new file mode 100644
index 0000000..f335c25
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c
@@ -0,0 +1,615 @@
+/* IEEE 802.11 SoftMAC layer
+ * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
+ *
+ * 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 "ieee80211.h"
+#ifdef ENABLE_DOT11D
+#include "dot11d.h"
+#endif
+/* 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;
+
+	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 */
+
+#ifdef ENABLE_DOT11D
+		if (!(GET_DOT11D_INFO(ieee)->channel_map)[fwrq->m]) {
+			ret = -EINVAL;
+			goto out;
+		}
+#endif
+		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;
+	//NM 0.7.0 will not accept channel any more.
+	fwrq->m = ieee80211_wlan_frequencies[ieee->current_network.channel-1] * 100000;
+	fwrq->e = 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;
+	u8 zero[] = {0,0,0,0,0,0};
+	unsigned long flags;
+
+	short ifup = ieee->proto_started;//dev->flags & IFF_UP;
+	struct sockaddr *temp = (struct sockaddr *)awrq;
+
+	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 = memcmp(temp->sa_data, zero,ETH_ALEN)!=0;
+
+	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;
+
+	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)
+{
+	u32 tmp_rate;
+	tmp_rate = TxCountToDataRate(ieee, ieee->softmac_stats.CurrentShowTxate);
+
+	wrqu->bitrate.value = tmp_rate * 500000;
+
+	return 0;
+}
+
+
+int ieee80211_wx_set_rts(struct ieee80211_device *ieee,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	if (wrqu->rts.disabled || !wrqu->rts.fixed)
+		ieee->rts = DEFAULT_RTS_THRESHOLD;
+	else
+	{
+		if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
+				wrqu->rts.value > MAX_RTS_THRESHOLD)
+			return -EINVAL;
+		ieee->rts = wrqu->rts.value;
+	}
+	return 0;
+}
+
+int ieee80211_wx_get_rts(struct ieee80211_device *ieee,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	wrqu->rts.value = ieee->rts;
+	wrqu->rts.fixed = 0;	/* no auto select */
+	wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
+	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;
+	HT_EXTCHNL_OFFSET chan_offset=0;
+	HT_CHANNEL_WIDTH bandwidth=0;
+	int b40M = 0;
+	static int count = 0;
+	chan = ieee->current_network.channel;
+	netif_carrier_off(ieee->dev);
+
+	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);
+	ieee->InitialGainHandler(ieee->dev,IG_Backup);
+	if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT && ieee->pHTInfo->bCurBW40MHz) {
+		b40M = 1;
+		chan_offset = ieee->pHTInfo->CurSTAExtChnlOffset;
+		bandwidth = (HT_CHANNEL_WIDTH)ieee->pHTInfo->bCurBW40MHz;
+		printk("Scan in 40M, force to 20M first:%d, %d\n", chan_offset, bandwidth);
+		ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+		}
+	ieee80211_start_scan_syncro(ieee);
+	if (b40M) {
+		printk("Scan in 20M, back to 40M\n");
+		if (chan_offset == HT_EXTCHNL_OFFSET_UPPER)
+			ieee->set_chan(ieee->dev, chan + 2);
+		else if (chan_offset == HT_EXTCHNL_OFFSET_LOWER)
+			ieee->set_chan(ieee->dev, chan - 2);
+		else
+			ieee->set_chan(ieee->dev, chan);
+		ieee->SetBWModeHandler(ieee->dev, bandwidth, chan_offset);
+	} else {
+		ieee->set_chan(ieee->dev, chan);
+	}
+
+	ieee->InitialGainHandler(ieee->dev,IG_Restore);
+	ieee->state = IEEE80211_LINKED;
+	ieee->link_change(ieee->dev);
+	// To prevent the immediately calling watch_dog after scan.
+	if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
+	{
+		ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
+		ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;
+	}
+	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);
+
+	netif_carrier_on(ieee->dev);
+	count = 0;
+	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;
+	}
+
+	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 consisten infos. not needed otherwise
+	 */
+	spin_lock_irqsave(&ieee->lock, flags);
+
+	if (wrqu->essid.flags && wrqu->essid.length) {
+		//first flush current network.ssid
+		len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE;
+		strncpy(ieee->current_network.ssid, extra, len+1);
+		ieee->current_network.ssid_len = len+1;
+		ieee->ssid_set = 1;
+	}
+	else{
+		ieee->ssid_set = 0;
+		ieee->current_network.ssid[0] = '\0';
+		ieee->current_network.ssid_len = 0;
+	}
+	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;
+
+	printk(KERN_INFO"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)
+{
+	strcpy(wrqu->name, "802.11");
+	if(ieee->modulation & IEEE80211_CCK_MODULATION){
+		strcat(wrqu->name, "b");
+		if(ieee->modulation & IEEE80211_OFDM_MODULATION)
+			strcat(wrqu->name, "/g");
+	}else if(ieee->modulation & IEEE80211_OFDM_MODULATION)
+		strcat(wrqu->name, "g");
+	if (ieee->mode & (IEEE_N_24G | IEEE_N_5G))
+		strcat(wrqu->name, "/n");
+
+	if((ieee->state == IEEE80211_LINKED) ||
+		(ieee->state == IEEE80211_LINKED_SCANNING))
+		strcat(wrqu->name," linked");
+	else if(ieee->state != IEEE80211_NOLINK)
+		strcat(wrqu->name," link..");
+
+
+	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;
+	down(&ieee->wx_sem);
+
+	if (wrqu->power.disabled){
+		ieee->ps = IEEE80211_PS_DISABLED;
+		goto exit;
+	}
+	if (wrqu->power.flags & IW_POWER_TIMEOUT) {
+		//ieee->ps_period = wrqu->power.value / 1000;
+		ieee->ps_timeout = wrqu->power.value / 1000;
+	}
+
+	if (wrqu->power.flags & IW_POWER_PERIOD) {
+
+		//ieee->ps_timeout = wrqu->power.value / 1000;
+		ieee->ps_period = wrqu->power.value / 1000;
+		//wrq->value / 1024;
+
+	}
+	switch (wrqu->power.flags & IW_POWER_MODE) {
+	case IW_POWER_UNICAST_R:
+		ieee->ps = IEEE80211_PS_UNICAST;
+		break;
+	case IW_POWER_MULTICAST_R:
+		ieee->ps = IEEE80211_PS_MBCAST;
+		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;
+
+	}
+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->ps_period * 1000;
+//ieee->current_network.dtim_period * ieee->current_network.beacon_interval * 1024;
+	}
+
+       if ((ieee->ps & (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST)) == (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST))
+		wrqu->power.flags |= IW_POWER_ALL_R;
+	else if (ieee->ps & IEEE80211_PS_MBCAST)
+		wrqu->power.flags |= IW_POWER_MULTICAST_R;
+	else
+		wrqu->power.flags |= IW_POWER_UNICAST_R;
+
+exit:
+	up(&ieee->wx_sem);
+	return ret;
+
+}
+EXPORT_SYMBOL(ieee80211_wx_get_essid);
+EXPORT_SYMBOL(ieee80211_wx_set_essid);
+EXPORT_SYMBOL(ieee80211_wx_set_rate);
+EXPORT_SYMBOL(ieee80211_wx_get_rate);
+EXPORT_SYMBOL(ieee80211_wx_set_wap);
+EXPORT_SYMBOL(ieee80211_wx_get_wap);
+EXPORT_SYMBOL(ieee80211_wx_set_mode);
+EXPORT_SYMBOL(ieee80211_wx_get_mode);
+EXPORT_SYMBOL(ieee80211_wx_set_scan);
+EXPORT_SYMBOL(ieee80211_wx_get_freq);
+EXPORT_SYMBOL(ieee80211_wx_set_freq);
+EXPORT_SYMBOL(ieee80211_wx_set_rawtx);
+EXPORT_SYMBOL(ieee80211_wx_get_name);
+EXPORT_SYMBOL(ieee80211_wx_set_power);
+EXPORT_SYMBOL(ieee80211_wx_get_power);
+EXPORT_SYMBOL(ieee80211_wlan_frequencies);
+EXPORT_SYMBOL(ieee80211_wx_set_rts);
+EXPORT_SYMBOL(ieee80211_wx_get_rts);
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
new file mode 100644
index 0000000..b29c36b
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
@@ -0,0 +1,912 @@
+/******************************************************************************
+
+  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 <andreamrl@tiscali.it>
+
+  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/version.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;
+
+	if (!(crypt && crypt->ops))
+	{
+		printk("=========>%s(), crypt is null\n", __FUNCTION__);
+		return -1;
+	}
+#ifdef CONFIG_IEEE80211_CRYPT_TKIP
+	struct ieee80211_hdr *header;
+
+	if (ieee->tkip_countermeasures &&
+	    crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
+		header = (struct ieee80211_hdr *) frag->data;
+		if (net_ratelimit()) {
+			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
+			       "TX packet to " MAC_FMT "\n",
+			       ieee->dev->name, MAC_ARG(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) {
+		printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
+		       ieee->dev->name, 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;
+	kfree(txb);
+}
+
+struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
+					  int 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;
+		}
+		memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb));
+	}
+	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 ethhdr *eth;
+	struct iphdr *ip;
+	eth = (struct ethhdr *)skb->data;
+	if (eth->h_proto != htons(ETH_P_IP))
+		return 0;
+
+//	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
+	ip = ip_hdr(skb);
+	switch (ip->tos & 0xfc) {
+		case 0x20:
+			return 2;
+		case 0x40:
+			return 1;
+		case 0x60:
+			return 3;
+		case 0x80:
+			return 4;
+		case 0xa0:
+			return 5;
+		case 0xc0:
+			return 6;
+		case 0xe0:
+			return 7;
+		default:
+			return 0;
+	}
+}
+
+#define SN_LESS(a, b)		(((a-b)&0x800)!=0)
+void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, struct sk_buff* skb, cb_desc* tcb_desc)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	PTX_TS_RECORD			pTxTs = NULL;
+	struct ieee80211_hdr_1addr* hdr = (struct ieee80211_hdr_1addr*)skb->data;
+
+	if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
+		return;
+	if (!IsQoSDataFrame(skb->data))
+		return;
+
+	if (is_multicast_ether_addr(hdr->addr1) || is_broadcast_ether_addr(hdr->addr1))
+		return;
+	//check packet and mode later
+#ifdef TO_DO_LIST
+	if(pTcb->PacketLength >= 4096)
+		return;
+	// For RTL819X, if pairwisekey = wep/tkip, we don't aggrregation.
+	if(!Adapter->HalFunc.GetNmodeSupportBySecCfgHandler(Adapter))
+		return;
+#endif
+	if(!ieee->GetNmodeSupportBySecCfg(ieee->dev))
+	{
+		return;
+	}
+	if(pHTInfo->bCurrentAMPDUEnable)
+	{
+		if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTxTs), hdr->addr1, skb->priority, TX_DIR, true))
+		{
+			printk("===>can't get TS\n");
+			return;
+		}
+		if (pTxTs->TxAdmittedBARecord.bValid == false)
+		{
+			TsStartAddBaProcess(ieee, pTxTs);
+			goto FORCED_AGG_SETTING;
+		}
+		else if (pTxTs->bUsingBa == false)
+		{
+			if (SN_LESS(pTxTs->TxAdmittedBARecord.BaStartSeqCtrl.field.SeqNum, (pTxTs->TxCurSeq+1)%4096))
+				pTxTs->bUsingBa = true;
+			else
+				goto FORCED_AGG_SETTING;
+		}
+
+		if (ieee->iw_mode == IW_MODE_INFRA)
+		{
+			tcb_desc->bAMPDUEnable = true;
+			tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor;
+			tcb_desc->ampdu_density = pHTInfo->CurrentMPDUDensity;
+		}
+	}
+FORCED_AGG_SETTING:
+	switch(pHTInfo->ForcedAMPDUMode )
+	{
+		case HT_AGG_AUTO:
+			break;
+
+		case HT_AGG_FORCE_ENABLE:
+			tcb_desc->bAMPDUEnable = true;
+			tcb_desc->ampdu_density = pHTInfo->ForcedMPDUDensity;
+			tcb_desc->ampdu_factor = pHTInfo->ForcedAMPDUFactor;
+			break;
+
+		case HT_AGG_FORCE_DISABLE:
+			tcb_desc->bAMPDUEnable = false;
+			tcb_desc->ampdu_density = 0;
+			tcb_desc->ampdu_factor = 0;
+			break;
+
+	}
+		return;
+}
+
+extern void ieee80211_qurey_ShortPreambleMode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
+{
+	tcb_desc->bUseShortPreamble = false;
+	if (tcb_desc->data_rate == 2)
+	{//// 1M can only use Long Preamble. 11B spec
+		return;
+	}
+	else if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
+	{
+		tcb_desc->bUseShortPreamble = true;
+	}
+	return;
+}
+extern	void
+ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, cb_desc *tcb_desc)
+{
+	PRT_HIGH_THROUGHPUT		pHTInfo = ieee->pHTInfo;
+
+	tcb_desc->bUseShortGI 		= false;
+
+	if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
+		return;
+
+	if(pHTInfo->bForcedShortGI)
+	{
+		tcb_desc->bUseShortGI = true;
+		return;
+	}
+
+	if((pHTInfo->bCurBW40MHz==true) && pHTInfo->bCurShortGI40MHz)
+		tcb_desc->bUseShortGI = true;
+	else if((pHTInfo->bCurBW40MHz==false) && pHTInfo->bCurShortGI20MHz)
+		tcb_desc->bUseShortGI = true;
+}
+
+void ieee80211_query_BandwidthMode(struct ieee80211_device* ieee, cb_desc *tcb_desc)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+
+	tcb_desc->bPacketBW = false;
+
+	if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
+		return;
+
+	if(tcb_desc->bMulticast || tcb_desc->bBroadcast)
+		return;
+
+	if((tcb_desc->data_rate & 0x80)==0) // If using legacy rate, it shall use 20MHz channel.
+		return;
+	//BandWidthAutoSwitch is for auto switch to 20 or 40 in long distance
+	if(pHTInfo->bCurBW40MHz && pHTInfo->bCurTxBW40MHz && !ieee->bandwidth_auto_switch.bforced_tx20Mhz)
+		tcb_desc->bPacketBW = true;
+	return;
+}
+
+void ieee80211_query_protectionmode(struct ieee80211_device* ieee, cb_desc* tcb_desc, struct sk_buff* skb)
+{
+	// Common Settings
+	tcb_desc->bRTSSTBC			= false;
+	tcb_desc->bRTSUseShortGI		= false; // Since protection frames are always sent by legacy rate, ShortGI will never be used.
+	tcb_desc->bCTSEnable			= false; // Most of protection using RTS/CTS
+	tcb_desc->RTSSC				= 0;		// 20MHz: Don't care;  40MHz: Duplicate.
+	tcb_desc->bRTSBW			= false; // RTS frame bandwidth is always 20MHz
+
+	if(tcb_desc->bBroadcast || tcb_desc->bMulticast)//only unicast frame will use rts/cts
+		return;
+
+	if (is_broadcast_ether_addr(skb->data+16))  //check addr3 as infrastructure add3 is DA.
+		return;
+
+	if (ieee->mode < IEEE_N_24G) //b, g mode
+	{
+			// (1) RTS_Threshold is compared to the MPDU, not MSDU.
+			// (2) If there are more than one frag in  this MSDU, only the first frag uses protection frame.
+			//		Other fragments are protected by previous fragment.
+			//		So we only need to check the length of first fragment.
+		if (skb->len > ieee->rts)
+		{
+			tcb_desc->bRTSEnable = true;
+			tcb_desc->rts_rate = MGN_24M;
+		}
+		else if (ieee->current_network.buseprotection)
+		{
+			// Use CTS-to-SELF in protection mode.
+			tcb_desc->bRTSEnable = true;
+			tcb_desc->bCTSEnable = true;
+			tcb_desc->rts_rate = MGN_24M;
+		}
+		//otherwise return;
+		return;
+	}
+	else
+	{// 11n High throughput case.
+		PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
+		while (true)
+		{
+			//check ERP protection
+			if (ieee->current_network.buseprotection)
+			{// CTS-to-SELF
+				tcb_desc->bRTSEnable = true;
+				tcb_desc->bCTSEnable = true;
+				tcb_desc->rts_rate = MGN_24M;
+				break;
+			}
+			//check HT op mode
+			if(pHTInfo->bCurrentHTSupport  && pHTInfo->bEnableHT)
+			{
+				u8 HTOpMode = pHTInfo->CurrentOpMode;
+				if((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) ||
+							(!pHTInfo->bCurBW40MHz && HTOpMode == 3) )
+				{
+					tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
+					tcb_desc->bRTSEnable = true;
+					break;
+				}
+			}
+			//check rts
+			if (skb->len > ieee->rts)
+			{
+				tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
+				tcb_desc->bRTSEnable = true;
+				break;
+			}
+			//to do list: check MIMO power save condition.
+			//check AMPDU aggregation for TXOP
+			if(tcb_desc->bAMPDUEnable)
+			{
+				tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
+				// According to 8190 design, firmware sends CF-End only if RTS/CTS is enabled. However, it degrads
+				// throughput around 10M, so we disable of this mechanism. 2007.08.03 by Emily
+				tcb_desc->bRTSEnable = false;
+				break;
+			}
+			//check IOT action
+			if(pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF)
+			{
+				tcb_desc->bCTSEnable	= true;
+				tcb_desc->rts_rate  = 	MGN_24M;
+				tcb_desc->bRTSEnable = true;
+				break;
+			}
+			// Totally no protection case!!
+			goto NO_PROTECTION;
+		}
+		}
+	// For test , CTS replace with RTS
+	if( 0 )
+	{
+		tcb_desc->bCTSEnable	= true;
+		tcb_desc->rts_rate = MGN_24M;
+		tcb_desc->bRTSEnable 	= true;
+	}
+	if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
+		tcb_desc->bUseShortPreamble = true;
+	if (ieee->mode == IW_MODE_MASTER)
+			goto NO_PROTECTION;
+	return;
+NO_PROTECTION:
+	tcb_desc->bRTSEnable	= false;
+	tcb_desc->bCTSEnable	= false;
+	tcb_desc->rts_rate		= 0;
+	tcb_desc->RTSSC		= 0;
+	tcb_desc->bRTSBW		= false;
+}
+
+
+void ieee80211_txrate_selectmode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
+{
+#ifdef TO_DO_LIST
+	if(!IsDataFrame(pFrame))
+	{
+		pTcb->bTxDisableRateFallBack = TRUE;
+		pTcb->bTxUseDriverAssingedRate = TRUE;
+		pTcb->RATRIndex = 7;
+		return;
+	}
+
+	if(pMgntInfo->ForcedDataRate!= 0)
+	{
+		pTcb->bTxDisableRateFallBack = TRUE;
+		pTcb->bTxUseDriverAssingedRate = TRUE;
+		return;
+	}
+#endif
+	if(ieee->bTxDisableRateFallBack)
+		tcb_desc->bTxDisableRateFallBack = true;
+
+	if(ieee->bTxUseDriverAssingedRate)
+		tcb_desc->bTxUseDriverAssingedRate = true;
+	if(!tcb_desc->bTxDisableRateFallBack || !tcb_desc->bTxUseDriverAssingedRate)
+	{
+		if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
+			tcb_desc->RATRIndex = 0;
+	}
+}
+
+void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u8* dst)
+{
+	if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst))
+		return;
+	if (IsQoSDataFrame(skb->data)) //we deal qos data only
+	{
+		PTX_TS_RECORD pTS = NULL;
+		if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTS), dst, skb->priority, TX_DIR, true))
+		{
+			return;
+		}
+		pTS->TxCurSeq = (pTS->TxCurSeq+1)%4096;
+	}
+}
+
+int ieee80211_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 = 0, encrypt;
+	int bytes, fc, qos_ctl = 0, 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];
+	int qos_actived = ieee->current_network.qos_data.active;
+
+	struct ieee80211_crypt_data* crypt;
+
+	cb_desc *tcb_desc;
+
+	spin_lock_irqsave(&ieee->lock, flags);
+
+	/* If there is no driver handler to take the TXB, dont' 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)))) {
+		printk(KERN_WARNING "%s: No xmit handler.\n",
+		       ieee->dev->name);
+		goto success;
+	}
+
+
+	if(likely(ieee->raw_tx == 0)){
+		if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
+			printk(KERN_WARNING "%s: skb too small (%d).\n",
+			ieee->dev->name, skb->len);
+			goto success;
+		}
+
+		memset(skb->cb, 0, sizeof(skb->cb));
+		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 (encrypt)
+			fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_WEP;
+		else
+
+                        fc = IEEE80211_FTYPE_DATA;
+
+		//if(ieee->current_network.QoS_Enable)
+		if(qos_actived)
+			fc |= IEEE80211_STYPE_QOS_DATA;
+		else
+			fc |= 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) ||
+		is_broadcast_ether_addr(header.addr1)) {
+			frag_size = MAX_FRAG_THRESHOLD;
+			qos_ctl |= QOS_CTL_NOTCONTAIN_ACK;
+		}
+		else {
+			frag_size = ieee->fts;//default:392
+			qos_ctl = 0;
+		}
+
+		//if (ieee->current_network.QoS_Enable)
+		if(qos_actived)
+		{
+			hdr_len = IEEE80211_3ADDR_LEN + 2;
+
+			skb->priority = ieee80211_classify(skb, &ieee->current_network);
+			qos_ctl |= skb->priority; //set in the ieee80211_classify
+			header.qos_ctl = cpu_to_le16(qos_ctl & IEEE80211_QOS_TID);
+		} 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 encryptiong 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 + ieee->tx_headroom, GFP_ATOMIC);
+		if (unlikely(!txb)) {
+			printk(KERN_WARNING "%s: Could not allocate TXB\n",
+			ieee->dev->name);
+			goto failed;
+		}
+		txb->encrypted = encrypt;
+		txb->payload_size = bytes;
+
+		//if (ieee->current_network.QoS_Enable)
+		if(qos_actived)
+		{
+			txb->queue_index = UP2AC(skb->priority);
+		} else {
+			txb->queue_index = WME_AC_BK;;
+		}
+
+
+
+		for (i = 0; i < nr_frags; i++) {
+			skb_frag = txb->fragments[i];
+			tcb_desc = (cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE);
+			if(qos_actived){
+				skb_frag->priority = skb->priority;//UP2AC(skb->priority);
+				tcb_desc->queue_index =  UP2AC(skb->priority);
+			} else {
+				skb_frag->priority = WME_AC_BK;
+				tcb_desc->queue_index = WME_AC_BK;
+			}
+			skb_reserve(skb_frag, ieee->tx_headroom);
+
+			if (encrypt){
+				if (ieee->hwsec_active)
+					tcb_desc->bHwSec = 1;
+				else
+					tcb_desc->bHwSec = 0;
+				skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
+			}
+			else
+			{
+				tcb_desc->bHwSec = 0;
+			}
+			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)
+			if(qos_actived)
+			{
+				// 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);
+		}
+
+		if(qos_actived)
+		{
+		  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))) {
+			printk(KERN_WARNING "%s: skb too small (%d).\n",
+			ieee->dev->name, skb->len);
+			goto success;
+		}
+
+		txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
+		if(!txb){
+			printk(KERN_WARNING "%s: Could not allocate TXB\n",
+			ieee->dev->name);
+			goto failed;
+		}
+
+		txb->encrypted = 0;
+		txb->payload_size = skb->len;
+		memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
+	}
+
+ success:
+//WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place.
+	if (txb)
+	{
+		cb_desc *tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
+		tcb_desc->bTxEnableFwCalcDur = 1;
+		if (is_multicast_ether_addr(header.addr1))
+			tcb_desc->bMulticast = 1;
+		if (is_broadcast_ether_addr(header.addr1))
+			tcb_desc->bBroadcast = 1;
+		ieee80211_txrate_selectmode(ieee, tcb_desc);
+		if ( tcb_desc->bMulticast ||  tcb_desc->bBroadcast)
+			tcb_desc->data_rate = ieee->basic_rate;
+		else
+			//tcb_desc->data_rate = CURRENT_RATE(ieee->current_network.mode, ieee->rate, ieee->HTCurrentOperaRate);
+			tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate);
+		ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc);
+		ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc);
+		ieee80211_query_HTCapShortGI(ieee, tcb_desc);
+		ieee80211_query_BandwidthMode(ieee, tcb_desc);
+		ieee80211_query_protectionmode(ieee, tcb_desc, txb->fragments[0]);
+		ieee80211_query_seqnum(ieee, txb->fragments[0], header.addr1);
+//		IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, txb->fragments[0]->data, txb->fragments[0]->len);
+		//IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, tcb_desc, sizeof(cb_desc));
+	}
+	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 0;
+			}
+			ieee80211_txb_free(txb);
+		}
+	}
+
+	return 0;
+
+ failed:
+	spin_unlock_irqrestore(&ieee->lock, flags);
+	netif_stop_queue(dev);
+	stats->tx_errors++;
+	return 1;
+
+}
+
+EXPORT_SYMBOL(ieee80211_txb_free);
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c
new file mode 100644
index 0000000..d397f1d
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c
@@ -0,0 +1,878 @@
+/******************************************************************************
+
+  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/version.h>
+#include <linux/kmod.h>
+#include <linux/module.h>
+
+#include "ieee80211.h"
+struct modes_unit {
+	char *mode_string;
+	int mode_size;
+};
+struct modes_unit ieee80211_modes[] = {
+	{"a",1},
+	{"b",1},
+	{"g",1},
+	{"?",1},
+	{"N-24G",5},
+	{"N-5G",4},
+};
+
+#define iwe_stream_add_event_rsl iwe_stream_add_event
+
+#define MAX_CUSTOM_LEN 64
+static inline char *rtl819x_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 proto_name[IFNAMSIZ];
+	char *pname = proto_name;
+	char *p;
+	struct iw_event iwe;
+	int i, j;
+	u16 max_rate, rate;
+	static u8	EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};
+
+	/* First entry *MUST* be the AP MAC address */
+	iwe.cmd = SIOCGIWAP;
+	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+	memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
+	start = iwe_stream_add_event_rsl(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->flags & NETWORK_EMPTY_ESSID) {
+	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(network->ssid_len, (u8)32);
+		start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
+	}
+	/* Add the protocol name */
+	iwe.cmd = SIOCGIWNAME;
+	for(i=0; i<(sizeof(ieee80211_modes)/sizeof(ieee80211_modes[0])); i++) {
+		if(network->mode&(1<<i)) {
+			sprintf(pname,ieee80211_modes[i].mode_string,ieee80211_modes[i].mode_size);
+			pname +=ieee80211_modes[i].mode_size;
+		}
+	}
+	*pname = '\0';
+	snprintf(iwe.u.name, IFNAMSIZ, "IEEE802.11%s", proto_name);
+	start = iwe_stream_add_event_rsl(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_rsl(info, start, stop, &iwe, IW_EV_UINT_LEN);
+	}
+
+	/* Add frequency/channel */
+	iwe.cmd = SIOCGIWFREQ;
+/*	iwe.u.freq.m = ieee80211_frequency(network->channel, network->mode);
+	iwe.u.freq.e = 3; */
+	iwe.u.freq.m = network->channel;
+	iwe.u.freq.e = 0;
+	iwe.u.freq.i = 0;
+	start = iwe_stream_add_event_rsl(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;
+	}
+
+	if (network->mode >= IEEE_N_24G)//add N rate here;
+	{
+		PHT_CAPABILITY_ELE ht_cap = NULL;
+		bool is40M = false, isShortGI = false;
+		u8 max_mcs = 0;
+		if (!memcmp(network->bssht.bdHTCapBuf, EWC11NHTCap, 4))
+			ht_cap = (PHT_CAPABILITY_ELE)&network->bssht.bdHTCapBuf[4];
+		else
+			ht_cap = (PHT_CAPABILITY_ELE)&network->bssht.bdHTCapBuf[0];
+		is40M = (ht_cap->ChlWidth)?1:0;
+		isShortGI = (ht_cap->ChlWidth)?
+						((ht_cap->ShortGI40Mhz)?1:0):
+						((ht_cap->ShortGI20Mhz)?1:0);
+
+		max_mcs = HTGetHighestMCSRate(ieee, ht_cap->MCS, MCS_FILTER_ALL);
+		rate = MCS_DATA_RATE[is40M][isShortGI][max_mcs&0x7f];
+		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_rsl(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... */
+	iwe.cmd = IWEVQUAL;
+	iwe.u.qual.qual = network->stats.signal;
+	iwe.u.qual.level = network->stats.rssi;
+	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_rsl(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);
+#if (WIRELESS_EXT < 18)
+	if (ieee->wpa_enabled && network->wpa_ie_len){
+		char buf[MAX_WPA_IE_LEN * 2 + 30];
+	//	printk("WPA IE\n");
+		u8 *p = buf;
+		p += sprintf(p, "wpa_ie=");
+		for (i = 0; i < network->wpa_ie_len; i++) {
+			p += sprintf(p, "%02x", network->wpa_ie[i]);
+		}
+
+		memset(&iwe, 0, sizeof(iwe));
+		iwe.cmd = IWEVCUSTOM;
+		iwe.u.data.length = strlen(buf);
+		start = iwe_stream_add_point(info, start, stop, &iwe, buf);
+	}
+
+	if (ieee->wpa_enabled && network->rsn_ie_len){
+		char buf[MAX_WPA_IE_LEN * 2 + 30];
+
+		u8 *p = buf;
+		p += sprintf(p, "rsn_ie=");
+		for (i = 0; i < network->rsn_ie_len; i++) {
+			p += sprintf(p, "%02x", network->rsn_ie[i]);
+		}
+
+		memset(&iwe, 0, sizeof(iwe));
+		iwe.cmd = IWEVCUSTOM;
+		iwe.u.data.length = strlen(buf);
+		start = iwe_stream_add_point(info, start, stop, &iwe, buf);
+	}
+#else
+	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);
+	}
+#endif
+
+
+	/* 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;
+
+	char *ev = extra;
+//	char *stop = ev + IW_SCAN_MAX_DATA;
+	char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA;
+	//char *stop = ev + IW_SCAN_MAX_DATA;
+	int i = 0;
+	int err = 0;
+	IEEE80211_DEBUG_WX("Getting scan\n");
+	down(&ieee->wx_sem);
+	spin_lock_irqsave(&ieee->lock, flags);
+
+	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 = rtl819x_translate_scan(ieee, ev, stop, network, info);
+		else
+			IEEE80211_DEBUG_SCAN(
+				"Not showing network '%s ("
+				MAC_FMT ")' due to age (%lums).\n",
+				escape_essid(network->ssid,
+					     network->ssid_len),
+				MAC_ARG(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 = kmalloc(sizeof(struct ieee80211_crypt_data),
+				    GFP_KERNEL);
+		if (new_crypt == NULL)
+			return -ENOMEM;
+		memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
+		new_crypt->ops = ieee80211_get_crypto_ops("WEP");
+		if (!new_crypt->ops) {
+			request_module("ieee80211_crypt_wep");
+			new_crypt->ops = ieee80211_get_crypto_ops("WEP");
+		}
+		if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+			new_crypt->priv = new_crypt->ops->init(key);
+
+		if (!new_crypt->ops || !new_crypt->priv) {
+			kfree(new_crypt);
+			new_crypt = NULL;
+
+			printk(KERN_WARNING "%s: could not initialize WEP: "
+			       "load module ieee80211_crypt_wep\n",
+			       dev->name);
+			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
+		 * explicitely 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 */
+			printk("Setting key %d to all zero.\n",
+					   key);
+
+			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);
+	ieee->auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
+	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)) {
+		printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
+		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;
+	}
+	len = crypt->ops->get_key(keybuf, SCM_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;
+}
+#if (WIRELESS_EXT >= 18)
+int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	int ret = 0;
+	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;
+	int group_key = 0;
+	const char *alg, *module;
+	struct ieee80211_crypto_ops *ops;
+	struct ieee80211_crypt_data **crypt;
+
+	struct ieee80211_security sec = {
+		.flags = 0,
+	};
+	//printk("======>encoding flag:%x,ext flag:%x, ext alg:%d\n", encoding->flags,ext->ext_flags, ext->alg);
+	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 */
+		//printk("not group key, flags:%x, ext->alg:%d\n", ext->ext_flags, ext->alg);
+		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;// | SEC_ENCRYPT;
+	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.encrypt = 0;
+			sec.level = SEC_LEVEL_0;
+			sec.flags |= SEC_LEVEL;
+		}
+		//printk("disabled: flag:%x\n", encoding->flags);
+		goto done;
+	}
+
+	sec.enabled = 1;
+    //    sec.encrypt = 1;
+	switch (ext->alg) {
+	case IW_ENCODE_ALG_WEP:
+		alg = "WEP";
+		module = "ieee80211_crypt_wep";
+		break;
+	case IW_ENCODE_ALG_TKIP:
+		alg = "TKIP";
+		module = "ieee80211_crypt_tkip";
+		break;
+	case IW_ENCODE_ALG_CCMP:
+		alg = "CCMP";
+		module = "ieee80211_crypt_ccmp";
+		break;
+	default:
+		IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
+				   dev->name, ext->alg);
+		ret = -EINVAL;
+		goto done;
+	}
+	printk("alg name:%s\n",alg);
+
+	 ops = ieee80211_get_crypto_ops(alg);
+	if (ops == NULL) {
+		request_module(module);
+		ops = ieee80211_get_crypto_ops(alg);
+	}
+	if (ops == NULL) {
+		IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
+				   dev->name, ext->alg);
+		printk("========>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 && try_module_get(new_crypt->ops->owner))
+			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);
+		printk("key setting failed\n");
+		ret = -EINVAL;
+		goto done;
+	}
+ //skip_host_crypt:
+	//printk("skip_host_crypt:ext_flags:%x\n", ext->ext_flags);
+	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.encode_alg[idx] = SEC_ALG_WEP;
+			sec.flags |= SEC_LEVEL;
+			sec.level = SEC_LEVEL_1;
+		} else if (ext->alg == IW_ENCODE_ALG_TKIP) {
+		      //  sec.encode_alg[idx] = SEC_ALG_TKIP;
+			sec.flags |= SEC_LEVEL;
+			sec.level = SEC_LEVEL_2;
+		} else if (ext->alg == IW_ENCODE_ALG_CCMP) {
+		       // sec.encode_alg[idx] = SEC_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;
+	}
+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_get_encode_ext(struct ieee80211_device *ieee,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	struct iw_point *encoding = &wrqu->encoding;
+	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+	struct ieee80211_crypt_data *crypt;
+	int idx, max_key_len;
+
+	max_key_len = encoding->length - sizeof(*ext);
+	if (max_key_len < 0)
+		return -EINVAL;
+
+	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 &&
+	    ext->alg != IW_ENCODE_ALG_WEP)
+		if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
+			return -EINVAL;
+
+	crypt = ieee->crypt[idx];
+	encoding->flags = idx + 1;
+	memset(ext, 0, sizeof(*ext));
+
+	if (crypt == NULL || crypt->ops == NULL ) {
+		ext->alg = IW_ENCODE_ALG_NONE;
+		ext->key_len = 0;
+		encoding->flags |= IW_ENCODE_DISABLED;
+	} else {
+		if (strcmp(crypt->ops->name, "WEP") == 0 )
+			ext->alg = IW_ENCODE_ALG_WEP;
+		else if (strcmp(crypt->ops->name, "TKIP"))
+			ext->alg = IW_ENCODE_ALG_TKIP;
+		else if (strcmp(crypt->ops->name, "CCMP"))
+			ext->alg = IW_ENCODE_ALG_CCMP;
+		else
+			return -EINVAL;
+		ext->key_len = crypt->ops->get_key(ext->key, SCM_KEY_LEN, NULL, crypt->priv);
+		encoding->flags |= IW_ENCODE_ENABLED;
+		if (ext->key_len &&
+		    (ext->alg == IW_ENCODE_ALG_TKIP ||
+		     ext->alg == IW_ENCODE_ALG_CCMP))
+			ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
+
+	}
+
+	return 0;
+}
+
+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;
+	switch (mlme->cmd) {
+	case IW_MLME_DEAUTH:
+	case IW_MLME_DISASSOC:
+		ieee80211_disassociate(ieee);
+		break;
+	 default:
+		return -EOPNOTSUPP;
+	}
+	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*/
+		//printk("wpa version:%x\n", data->value);
+		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:
+		//printk("======>%s():data->value is %d\n",__FUNCTION__,data->value);
+	//	ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM)?1:0;
+		if(data->value & IW_AUTH_ALG_SHARED_KEY){
+			ieee->open_wep = 0;
+			ieee->auth_mode = 1;
+		}
+		else if(data->value & IW_AUTH_ALG_OPEN_SYSTEM){
+			ieee->open_wep = 1;
+			ieee->auth_mode = 0;
+		}
+		else if(data->value & IW_AUTH_ALG_LEAP){
+			ieee->open_wep = 1;
+			ieee->auth_mode = 2;
+			//printk("hahahaa:LEAP\n");
+		}
+		else
+			return -EINVAL;
+		//printk("open_wep:%d\n", ieee->open_wep);
+		break;
+
+	case IW_AUTH_WPA_ENABLED:
+		ieee->wpa_enabled = (data->value)?1:0;
+		//printk("enalbe wpa:%d\n", ieee->wpa_enabled);
+		break;
+
+	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;
+}
+#endif
+int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
+{
+	u8 *buf;
+
+	if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
+	{
+	//	printk("return error out, len:%d\n", len);
+	return -EINVAL;
+	}
+
+
+	if (len)
+	{
+		if (len != ie[1]+2)
+		{
+			printk("len:%d, ie:%d\n", len, ie[1]);
+			return -EINVAL;
+		}
+		buf = kmalloc(len, GFP_KERNEL);
+		if (buf == NULL)
+			return -ENOMEM;
+		memcpy(buf, ie, len);
+		kfree(ieee->wpa_ie);
+		ieee->wpa_ie = buf;
+		ieee->wpa_ie_len = len;
+	}
+	else{
+		if (ieee->wpa_ie)
+		kfree(ieee->wpa_ie);
+		ieee->wpa_ie = NULL;
+		ieee->wpa_ie_len = 0;
+	}
+	return 0;
+
+}
+
+EXPORT_SYMBOL(ieee80211_wx_set_gen_ie);
+#if (WIRELESS_EXT >= 18)
+EXPORT_SYMBOL(ieee80211_wx_set_mlme);
+EXPORT_SYMBOL(ieee80211_wx_set_auth);
+EXPORT_SYMBOL(ieee80211_wx_set_encode_ext);
+EXPORT_SYMBOL(ieee80211_wx_get_encode_ext);
+#endif
+EXPORT_SYMBOL(ieee80211_wx_get_scan);
+EXPORT_SYMBOL(ieee80211_wx_set_encode);
+EXPORT_SYMBOL(ieee80211_wx_get_encode);
diff --git a/drivers/staging/rtl8192u/ieee80211/internal.h b/drivers/staging/rtl8192u/ieee80211/internal.h
new file mode 100644
index 0000000..a7c096e
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/internal.h
@@ -0,0 +1,99 @@
+/*
+ * Cryptographic API.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * 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.
+ *
+ */
+#ifndef _CRYPTO_INTERNAL_H
+#define _CRYPTO_INTERNAL_H
+
+
+//#include <linux/crypto.h>
+#include "rtl_crypto.h"
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <linux/init.h>
+#include <asm/hardirq.h>
+#include <asm/softirq.h>
+#include <asm/kmap_types.h>
+
+
+extern enum km_type crypto_km_types[];
+
+static inline enum km_type crypto_kmap_type(int out)
+{
+	return crypto_km_types[(in_softirq() ? 2 : 0) + out];
+}
+
+static inline void *crypto_kmap(struct page *page, int out)
+{
+	return kmap_atomic(page, crypto_kmap_type(out));
+}
+
+static inline void crypto_kunmap(void *vaddr, int out)
+{
+	kunmap_atomic(vaddr, crypto_kmap_type(out));
+}
+
+static inline void crypto_yield(struct crypto_tfm *tfm)
+{
+	if (!in_softirq())
+		cond_resched();
+}
+
+static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
+{
+	return (void *)&tfm[1];
+}
+
+struct crypto_alg *crypto_alg_lookup(const char *name);
+
+#ifdef CONFIG_KMOD
+void crypto_alg_autoload(const char *name);
+struct crypto_alg *crypto_alg_mod_lookup(const char *name);
+#else
+static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
+{
+	return crypto_alg_lookup(name);
+}
+#endif
+
+#ifdef CONFIG_CRYPTO_HMAC
+int crypto_alloc_hmac_block(struct crypto_tfm *tfm);
+void crypto_free_hmac_block(struct crypto_tfm *tfm);
+#else
+static inline int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
+{
+	return 0;
+}
+
+static inline void crypto_free_hmac_block(struct crypto_tfm *tfm)
+{ }
+#endif
+
+#ifdef CONFIG_PROC_FS
+void __init crypto_init_proc(void);
+#else
+static inline void crypto_init_proc(void)
+{ }
+#endif
+
+int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
+int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
+int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags);
+
+int crypto_init_digest_ops(struct crypto_tfm *tfm);
+int crypto_init_cipher_ops(struct crypto_tfm *tfm);
+int crypto_init_compress_ops(struct crypto_tfm *tfm);
+
+void crypto_exit_digest_ops(struct crypto_tfm *tfm);
+void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
+void crypto_exit_compress_ops(struct crypto_tfm *tfm);
+
+#endif	/* _CRYPTO_INTERNAL_H */
+
diff --git a/drivers/staging/rtl8192u/ieee80211/kmap_types.h b/drivers/staging/rtl8192u/ieee80211/kmap_types.h
new file mode 100644
index 0000000..de67bb0
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/kmap_types.h
@@ -0,0 +1,20 @@
+#ifndef __KMAP_TYPES_H
+
+#define __KMAP_TYPES_H
+
+
+enum km_type {
+	KM_BOUNCE_READ,
+	KM_SKB_SUNRPC_DATA,
+	KM_SKB_DATA_SOFTIRQ,
+	KM_USER0,
+	KM_USER1,
+	KM_BH_IRQ,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
+	KM_TYPE_NR
+};
+
+#define _ASM_KMAP_TYPES_H
+
+#endif
diff --git a/drivers/staging/rtl8192u/ieee80211/michael_mic.c b/drivers/staging/rtl8192u/ieee80211/michael_mic.c
new file mode 100644
index 0000000..df256e4
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/michael_mic.c
@@ -0,0 +1,194 @@
+/*
+ * Cryptographic API
+ *
+ * Michael MIC (IEEE 802.11i/TKIP) keyed digest
+ *
+ * Copyright (c) 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.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+//#include <linux/crypto.h>
+#include "rtl_crypto.h"
+
+
+struct michael_mic_ctx {
+	u8 pending[4];
+	size_t pending_len;
+
+	u32 l, r;
+};
+
+
+static inline u32 rotl(u32 val, int bits)
+{
+	return (val << bits) | (val >> (32 - bits));
+}
+
+
+static inline u32 rotr(u32 val, int bits)
+{
+	return (val >> bits) | (val << (32 - bits));
+}
+
+
+static inline u32 xswap(u32 val)
+{
+	return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8);
+}
+
+
+#define michael_block(l, r)	\
+do {				\
+	r ^= rotl(l, 17);	\
+	l += r;			\
+	r ^= xswap(l);		\
+	l += r;			\
+	r ^= rotl(l, 3);	\
+	l += r;			\
+	r ^= rotr(l, 2);	\
+	l += r;			\
+} while (0)
+
+
+static inline u32 get_le32(const u8 *p)
+{
+	return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+}
+
+
+static inline void put_le32(u8 *p, u32 v)
+{
+	p[0] = v;
+	p[1] = v >> 8;
+	p[2] = v >> 16;
+	p[3] = v >> 24;
+}
+
+
+static void michael_init(void *ctx)
+{
+	struct michael_mic_ctx *mctx = ctx;
+	mctx->pending_len = 0;
+}
+
+
+static void michael_update(void *ctx, const u8 *data, unsigned int len)
+{
+	struct michael_mic_ctx *mctx = ctx;
+
+	if (mctx->pending_len) {
+		int flen = 4 - mctx->pending_len;
+		if (flen > len)
+			flen = len;
+		memcpy(&mctx->pending[mctx->pending_len], data, flen);
+		mctx->pending_len += flen;
+		data += flen;
+		len -= flen;
+
+		if (mctx->pending_len < 4)
+			return;
+
+		mctx->l ^= get_le32(mctx->pending);
+		michael_block(mctx->l, mctx->r);
+		mctx->pending_len = 0;
+	}
+
+	while (len >= 4) {
+		mctx->l ^= get_le32(data);
+		michael_block(mctx->l, mctx->r);
+		data += 4;
+		len -= 4;
+	}
+
+	if (len > 0) {
+		mctx->pending_len = len;
+		memcpy(mctx->pending, data, len);
+	}
+}
+
+
+static void michael_final(void *ctx, u8 *out)
+{
+	struct michael_mic_ctx *mctx = ctx;
+	u8 *data = mctx->pending;
+
+	/* Last block and padding (0x5a, 4..7 x 0) */
+	switch (mctx->pending_len) {
+	case 0:
+		mctx->l ^= 0x5a;
+		break;
+	case 1:
+		mctx->l ^= data[0] | 0x5a00;
+		break;
+	case 2:
+		mctx->l ^= data[0] | (data[1] << 8) | 0x5a0000;
+		break;
+	case 3:
+		mctx->l ^= data[0] | (data[1] << 8) | (data[2] << 16) |
+			0x5a000000;
+		break;
+	}
+	michael_block(mctx->l, mctx->r);
+	/* l ^= 0; */
+	michael_block(mctx->l, mctx->r);
+
+	put_le32(out, mctx->l);
+	put_le32(out + 4, mctx->r);
+}
+
+
+static int michael_setkey(void *ctx, const u8 *key, unsigned int keylen,
+			  u32 *flags)
+{
+	struct michael_mic_ctx *mctx = ctx;
+	if (keylen != 8) {
+		if (flags)
+			*flags = CRYPTO_TFM_RES_BAD_KEY_LEN;
+		return -EINVAL;
+	}
+	mctx->l = get_le32(key);
+	mctx->r = get_le32(key + 4);
+	return 0;
+}
+
+
+static struct crypto_alg michael_mic_alg = {
+	.cra_name	= "michael_mic",
+	.cra_flags	= CRYPTO_ALG_TYPE_DIGEST,
+	.cra_blocksize	= 8,
+	.cra_ctxsize	= sizeof(struct michael_mic_ctx),
+	.cra_module	= THIS_MODULE,
+	.cra_list	= LIST_HEAD_INIT(michael_mic_alg.cra_list),
+	.cra_u		= { .digest = {
+	.dia_digestsize	= 8,
+	.dia_init	= michael_init,
+	.dia_update	= michael_update,
+	.dia_final	= michael_final,
+	.dia_setkey	= michael_setkey } }
+};
+
+
+static int __init michael_mic_init(void)
+{
+	return crypto_register_alg(&michael_mic_alg);
+}
+
+
+static void __exit michael_mic_exit(void)
+{
+	crypto_unregister_alg(&michael_mic_alg);
+}
+
+
+module_init(michael_mic_init);
+module_exit(michael_mic_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Michael MIC");
+MODULE_AUTHOR("Jouni Malinen <jkmaline@cc.hut.fi>");
diff --git a/drivers/staging/rtl8192u/ieee80211/proc.c b/drivers/staging/rtl8192u/ieee80211/proc.c
new file mode 100644
index 0000000..6eda928
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/proc.c
@@ -0,0 +1,116 @@
+/*
+ * Scatterlist Cryptographic API.
+ *
+ * Procfs information.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#include <linux/init.h>
+//#include <linux/crypto.h>
+#include "rtl_crypto.h"
+#include <linux/rwsem.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include "internal.h"
+
+extern struct list_head crypto_alg_list;
+extern struct rw_semaphore crypto_alg_sem;
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+	struct list_head *v;
+	loff_t n = *pos;
+
+	down_read(&crypto_alg_sem);
+	list_for_each(v, &crypto_alg_list)
+		if (!n--)
+			return list_entry(v, struct crypto_alg, cra_list);
+	return NULL;
+}
+
+static void *c_next(struct seq_file *m, void *p, loff_t *pos)
+{
+	struct list_head *v = p;
+
+	(*pos)++;
+	v = v->next;
+	return (v == &crypto_alg_list) ?
+		NULL : list_entry(v, struct crypto_alg, cra_list);
+}
+
+static void c_stop(struct seq_file *m, void *p)
+{
+	up_read(&crypto_alg_sem);
+}
+
+static int c_show(struct seq_file *m, void *p)
+{
+	struct crypto_alg *alg = (struct crypto_alg *)p;
+
+	seq_printf(m, "name         : %s\n", alg->cra_name);
+	seq_printf(m, "module       : %s\n",
+		   (alg->cra_module ?
+		    alg->cra_module->name :
+		    "kernel"));
+
+	switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
+	case CRYPTO_ALG_TYPE_CIPHER:
+		seq_printf(m, "type         : cipher\n");
+		seq_printf(m, "blocksize    : %u\n", alg->cra_blocksize);
+		seq_printf(m, "min keysize  : %u\n",
+					alg->cra_cipher.cia_min_keysize);
+		seq_printf(m, "max keysize  : %u\n",
+					alg->cra_cipher.cia_max_keysize);
+		break;
+
+	case CRYPTO_ALG_TYPE_DIGEST:
+		seq_printf(m, "type         : digest\n");
+		seq_printf(m, "blocksize    : %u\n", alg->cra_blocksize);
+		seq_printf(m, "digestsize   : %u\n",
+			   alg->cra_digest.dia_digestsize);
+		break;
+	case CRYPTO_ALG_TYPE_COMPRESS:
+		seq_printf(m, "type         : compression\n");
+		break;
+	default:
+		seq_printf(m, "type         : unknown\n");
+		break;
+	}
+
+	seq_putc(m, '\n');
+	return 0;
+}
+
+static struct seq_operations crypto_seq_ops = {
+	.start		= c_start,
+	.next		= c_next,
+	.stop		= c_stop,
+	.show		= c_show
+};
+
+static int crypto_info_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &crypto_seq_ops);
+}
+
+static struct file_operations proc_crypto_ops = {
+	.open		= crypto_info_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release
+};
+
+void __init crypto_init_proc(void)
+{
+	struct proc_dir_entry *proc;
+
+	proc = create_proc_entry("crypto", 0, NULL);
+	if (proc)
+		proc->proc_fops = &proc_crypto_ops;
+}
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_BA.h b/drivers/staging/rtl8192u/ieee80211/rtl819x_BA.h
new file mode 100644
index 0000000..8ddc8bf9
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_BA.h
@@ -0,0 +1,69 @@
+#ifndef _BATYPE_H_
+#define _BATYPE_H_
+
+#define 	TOTAL_TXBA_NUM	16
+#define	TOTAL_RXBA_NUM	16
+
+#define	BA_SETUP_TIMEOUT	200
+#define	BA_INACT_TIMEOUT	60000
+
+#define	BA_POLICY_DELAYED		0
+#define	BA_POLICY_IMMEDIATE	1
+
+#define	ADDBA_STATUS_SUCCESS			0
+#define	ADDBA_STATUS_REFUSED		37
+#define	ADDBA_STATUS_INVALID_PARAM	38
+
+#define	DELBA_REASON_QSTA_LEAVING	36
+#define	DELBA_REASON_END_BA			37
+#define	DELBA_REASON_UNKNOWN_BA	38
+#define	DELBA_REASON_TIMEOUT			39
+/*  whether need define BA Action frames here?
+struct ieee80211_ADDBA_Req{
+	struct ieee80211_header_data header;
+	u8	category;
+	u8
+} __attribute__ ((packed));
+*/
+//Is this need?I put here just to make it easier to define structure BA_RECORD //WB
+typedef union _SEQUENCE_CONTROL{
+	u16 ShortData;
+	struct
+	{
+		u16	FragNum:4;
+		u16	SeqNum:12;
+	}field;
+}SEQUENCE_CONTROL, *PSEQUENCE_CONTROL;
+
+typedef union _BA_PARAM_SET {
+	u8 charData[2];
+	u16 shortData;
+	struct {
+		u16 AMSDU_Support:1;
+		u16 BAPolicy:1;
+		u16 TID:4;
+		u16 BufferSize:10;
+	} field;
+} BA_PARAM_SET, *PBA_PARAM_SET;
+
+typedef union _DELBA_PARAM_SET {
+	u8 charData[2];
+	u16 shortData;
+	struct {
+		u16 Reserved:11;
+		u16 Initiator:1;
+		u16 TID:4;
+	} field;
+} DELBA_PARAM_SET, *PDELBA_PARAM_SET;
+
+typedef struct _BA_RECORD {
+	struct timer_list		Timer;
+	u8				bValid;
+	u8				DialogToken;
+	BA_PARAM_SET		BaParamSet;
+	u16				BaTimeoutValue;
+	SEQUENCE_CONTROL	BaStartSeqCtrl;
+} BA_RECORD, *PBA_RECORD;
+
+#endif //end _BATYPE_H_
+
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
new file mode 100644
index 0000000..26af43b
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
@@ -0,0 +1,737 @@
+/********************************************************************************************************************************
+ * This file is created to process BA Action Frame. According to 802.11 spec, there are 3 BA action types at all. And as BA is
+ * related to TS, this part need some struture defined in QOS side code. Also TX RX is going to be resturctured, so how to send
+ * ADDBAREQ ADDBARSP and DELBA packet is still on consideration. Temporarily use MANAGE QUEUE instead of Normal Queue.
+ * WB 2008-05-27
+ * *****************************************************************************************************************************/
+#include "ieee80211.h"
+#include "rtl819x_BA.h"
+
+/********************************************************************************************************************
+ *function:  Activate BA entry. And if Time is nozero, start timer.
+ *   input:  PBA_RECORD 		pBA  //BA entry to be enabled
+ *   	     u16 			Time //indicate time delay.
+ *  output:  none
+********************************************************************************************************************/
+void ActivateBAEntry(struct ieee80211_device* ieee, PBA_RECORD pBA, u16 Time)
+{
+	pBA->bValid = true;
+	if(Time != 0)
+		mod_timer(&pBA->Timer, jiffies + MSECS(Time));
+}
+
+/********************************************************************************************************************
+ *function:  deactivate BA entry, including its timer.
+ *   input:  PBA_RECORD 		pBA  //BA entry to be disabled
+ *  output:  none
+********************************************************************************************************************/
+void DeActivateBAEntry( struct ieee80211_device* ieee, PBA_RECORD pBA)
+{
+	pBA->bValid = false;
+	del_timer_sync(&pBA->Timer);
+}
+/********************************************************************************************************************
+ *function: deactivete BA entry in Tx Ts, and send DELBA.
+ *   input:
+ *   	     PTX_TS_RECORD		pTxTs //Tx Ts which is to deactivate BA entry.
+ *  output:  none
+ *  notice:  As PTX_TS_RECORD structure will be defined in QOS, so wait to be merged. //FIXME
+********************************************************************************************************************/
+u8 TxTsDeleteBA( struct ieee80211_device* ieee, PTX_TS_RECORD	pTxTs)
+{
+	PBA_RECORD		pAdmittedBa = &pTxTs->TxAdmittedBARecord;  //These two BA entries must exist in TS structure
+	PBA_RECORD		pPendingBa = &pTxTs->TxPendingBARecord;
+	u8			bSendDELBA = false;
+
+	// Delete pending BA
+	if(pPendingBa->bValid)
+	{
+		DeActivateBAEntry(ieee, pPendingBa);
+		bSendDELBA = true;
+	}
+
+	// Delete admitted BA
+	if(pAdmittedBa->bValid)
+	{
+		DeActivateBAEntry(ieee, pAdmittedBa);
+		bSendDELBA = true;
+	}
+
+	return bSendDELBA;
+}
+
+/********************************************************************************************************************
+ *function: deactivete BA entry in Tx Ts, and send DELBA.
+ *   input:
+ *   	     PRX_TS_RECORD		pRxTs //Rx Ts which is to deactivate BA entry.
+ *  output:  none
+ *  notice:  As PRX_TS_RECORD structure will be defined in QOS, so wait to be merged. //FIXME, same with above
+********************************************************************************************************************/
+u8 RxTsDeleteBA( struct ieee80211_device* ieee, PRX_TS_RECORD	pRxTs)
+{
+	PBA_RECORD		pBa = &pRxTs->RxAdmittedBARecord;
+	u8			bSendDELBA = false;
+
+	if(pBa->bValid)
+	{
+		DeActivateBAEntry(ieee, pBa);
+		bSendDELBA = true;
+	}
+
+	return bSendDELBA;
+}
+
+/********************************************************************************************************************
+ *function: reset BA entry
+ *   input:
+ *   	     PBA_RECORD		pBA //entry to be reset
+ *  output:  none
+********************************************************************************************************************/
+void ResetBaEntry( PBA_RECORD pBA)
+{
+	pBA->bValid			= false;
+	pBA->BaParamSet.shortData	= 0;
+	pBA->BaTimeoutValue		= 0;
+	pBA->DialogToken		= 0;
+	pBA->BaStartSeqCtrl.ShortData	= 0;
+}
+//These functions need porting here or not?
+/*******************************************************************************************************************************
+ *function:  construct ADDBAREQ and ADDBARSP frame here together.
+ *   input:  u8* 		Dst 	//ADDBA frame's destination
+ *   	     PBA_RECORD 	pBA	//BA_RECORD entry which stores the necessary information for BA.
+ *   	     u16 		StatusCode  //status code in RSP and I will use it to indicate whether it's RSP or REQ(will I?)
+ *   	     u8			type	//indicate whether it's RSP(ACT_ADDBARSP) ow REQ(ACT_ADDBAREQ)
+ *  output:  none
+ *  return:  sk_buff* 		skb     //return constructed skb to xmit
+*******************************************************************************************************************************/
+static struct sk_buff* ieee80211_ADDBA(struct ieee80211_device* ieee, u8* Dst, PBA_RECORD pBA, u16 StatusCode, u8 type)
+{
+	struct sk_buff *skb = NULL;
+	 struct ieee80211_hdr_3addr* BAReq = NULL;
+	u8* tag = NULL;
+	u16 tmp = 0;
+	u16 len = ieee->tx_headroom + 9;
+	//category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) +  BA Timeout Value(2) +  BA Start SeqCtrl(2)(or StatusCode(2))
+	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:"MAC_FMT", ieee->dev:%p\n", __FUNCTION__, type, MAC_ARG(Dst), ieee->dev);
+	if (pBA == NULL||ieee == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee);
+		return NULL;
+	}
+	skb = dev_alloc_skb(len + sizeof( struct ieee80211_hdr_3addr)); //need to add something others? FIXME
+	if (skb == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc skb for ADDBA_REQ\n");
+		return NULL;
+	}
+
+	memset(skb->data, 0, sizeof( struct ieee80211_hdr_3addr));  	//I wonder whether it's necessary. Apparently kernel will not do it when alloc a skb.
+	skb_reserve(skb, ieee->tx_headroom);
+
+	BAReq = ( struct ieee80211_hdr_3addr *) skb_put(skb,sizeof( struct ieee80211_hdr_3addr));
+
+	memcpy(BAReq->addr1, Dst, ETH_ALEN);
+	memcpy(BAReq->addr2, ieee->dev->dev_addr, ETH_ALEN);
+
+	memcpy(BAReq->addr3, ieee->current_network.bssid, ETH_ALEN);
+
+	BAReq->frame_ctl = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame
+
+	//tag += sizeof( struct ieee80211_hdr_3addr); //move to action field
+	tag = (u8*)skb_put(skb, 9);
+	*tag ++= ACT_CAT_BA;
+	*tag ++= type;
+	// Dialog Token
+	*tag ++= pBA->DialogToken;
+
+	if (ACT_ADDBARSP == type)
+	{
+		// Status Code
+		printk("=====>to send ADDBARSP\n");
+		tmp = cpu_to_le16(StatusCode);
+		memcpy(tag, (u8*)&tmp, 2);
+		tag += 2;
+	}
+	// BA Parameter Set
+	tmp = cpu_to_le16(pBA->BaParamSet.shortData);
+	memcpy(tag, (u8*)&tmp, 2);
+	tag += 2;
+	// BA Timeout Value
+	tmp = cpu_to_le16(pBA->BaTimeoutValue);
+	memcpy(tag, (u8*)&tmp, 2);
+	tag += 2;
+
+	if (ACT_ADDBAREQ == type)
+	{
+	// BA Start SeqCtrl
+		memcpy(tag,(u8*)&(pBA->BaStartSeqCtrl), 2);
+		tag += 2;
+	}
+
+	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
+	return skb;
+	//return NULL;
+}
+
+
+/********************************************************************************************************************
+ *function:  construct DELBA frame
+ *   input:  u8* 		dst 	//DELBA frame's destination
+ *   	     PBA_RECORD 	pBA	//BA_RECORD entry which stores the necessary information for BA
+ *   	     TR_SELECT	        TxRxSelect  //TX RX direction
+ *   	     u16 		ReasonCode  //status code.
+ *  output:  none
+ *  return:  sk_buff* 		skb     //return constructed skb to xmit
+********************************************************************************************************************/
+static struct sk_buff* ieee80211_DELBA(
+	struct ieee80211_device* ieee,
+	u8*		         dst,
+	PBA_RECORD		 pBA,
+	TR_SELECT		 TxRxSelect,
+	u16			 ReasonCode
+	)
+{
+	DELBA_PARAM_SET	DelbaParamSet;
+	struct sk_buff *skb = NULL;
+	 struct ieee80211_hdr_3addr* Delba = NULL;
+	u8* tag = NULL;
+	u16 tmp = 0;
+	//len = head len + DELBA Parameter Set(2) + Reason Code(2)
+	u16 len = 6 + ieee->tx_headroom;
+
+	if (net_ratelimit())
+	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:"MAC_FMT"\n", __FUNCTION__, ReasonCode, MAC_ARG(dst));
+
+	memset(&DelbaParamSet, 0, 2);
+
+	DelbaParamSet.field.Initiator	= (TxRxSelect==TX_DIR)?1:0;
+	DelbaParamSet.field.TID	= pBA->BaParamSet.field.TID;
+
+	skb = dev_alloc_skb(len + sizeof( struct ieee80211_hdr_3addr)); //need to add something others? FIXME
+	if (skb == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc skb for ADDBA_REQ\n");
+		return NULL;
+	}
+//	memset(skb->data, 0, len+sizeof( struct ieee80211_hdr_3addr));
+	skb_reserve(skb, ieee->tx_headroom);
+
+	Delba = ( struct ieee80211_hdr_3addr *) skb_put(skb,sizeof( struct ieee80211_hdr_3addr));
+
+	memcpy(Delba->addr1, dst, ETH_ALEN);
+	memcpy(Delba->addr2, ieee->dev->dev_addr, ETH_ALEN);
+	memcpy(Delba->addr3, ieee->current_network.bssid, ETH_ALEN);
+	Delba->frame_ctl = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame
+
+	tag = (u8*)skb_put(skb, 6);
+
+	*tag ++= ACT_CAT_BA;
+	*tag ++= ACT_DELBA;
+
+	// DELBA Parameter Set
+	tmp = cpu_to_le16(DelbaParamSet.shortData);
+	memcpy(tag, (u8*)&tmp, 2);
+	tag += 2;
+	// Reason Code
+	tmp = cpu_to_le16(ReasonCode);
+	memcpy(tag, (u8*)&tmp, 2);
+	tag += 2;
+
+	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
+	if (net_ratelimit())
+	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "<=====%s()\n", __FUNCTION__);
+	return skb;
+}
+
+/********************************************************************************************************************
+ *function: send ADDBAReq frame out
+ *   input:  u8* 		dst 	//ADDBAReq frame's destination
+ *   	     PBA_RECORD 	pBA	//BA_RECORD entry which stores the necessary information for BA
+ *  output:  none
+ *  notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
+********************************************************************************************************************/
+void ieee80211_send_ADDBAReq(struct ieee80211_device* ieee, u8*	dst, PBA_RECORD	pBA)
+{
+	struct sk_buff *skb = NULL;
+	skb = ieee80211_ADDBA(ieee, dst, pBA, 0, ACT_ADDBAREQ); //construct ACT_ADDBAREQ frames so set statuscode zero.
+
+	if (skb)
+	{
+		softmac_mgmt_xmit(skb, ieee);
+		//add statistic needed here.
+		//and skb will be freed in softmac_mgmt_xmit(), so omit all dev_kfree_skb_any() outside softmac_mgmt_xmit()
+		//WB
+	}
+	else
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
+	}
+	return;
+}
+
+/********************************************************************************************************************
+ *function: send ADDBARSP frame out
+ *   input:  u8* 		dst 	//DELBA frame's destination
+ *   	     PBA_RECORD 	pBA	//BA_RECORD entry which stores the necessary information for BA
+ *   	     u16		StatusCode //RSP StatusCode
+ *  output:  none
+ *  notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
+********************************************************************************************************************/
+void ieee80211_send_ADDBARsp(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, u16 StatusCode)
+{
+	struct sk_buff *skb = NULL;
+	skb = ieee80211_ADDBA(ieee, dst, pBA, StatusCode, ACT_ADDBARSP); //construct ACT_ADDBARSP frames
+	if (skb)
+	{
+		softmac_mgmt_xmit(skb, ieee);
+		//same above
+	}
+	else
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
+	}
+
+	return;
+
+}
+/********************************************************************************************************************
+ *function: send ADDBARSP frame out
+ *   input:  u8* 		dst 	//DELBA frame's destination
+ *   	     PBA_RECORD 	pBA	//BA_RECORD entry which stores the necessary information for BA
+ *   	     TR_SELECT          TxRxSelect //TX or RX
+ *   	     u16		ReasonCode //DEL ReasonCode
+ *  output:  none
+ *  notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
+********************************************************************************************************************/
+
+void ieee80211_send_DELBA(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, TR_SELECT TxRxSelect, u16 ReasonCode)
+{
+	struct sk_buff *skb = NULL;
+	skb = ieee80211_DELBA(ieee, dst, pBA, TxRxSelect, ReasonCode); //construct ACT_ADDBARSP frames
+	if (skb)
+	{
+		softmac_mgmt_xmit(skb, ieee);
+		//same above
+	}
+	else
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
+	}
+	return ;
+}
+
+/********************************************************************************************************************
+ *function: RX ADDBAReq
+ *   input:  struct sk_buff *   skb	//incoming ADDBAReq skb.
+ *  return:  0(pass), other(fail)
+ *  notice:  As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
+********************************************************************************************************************/
+int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb)
+{
+	 struct ieee80211_hdr_3addr* req = NULL;
+	u16 rc = 0;
+	u8 * dst = NULL, *pDialogToken = NULL, *tag = NULL;
+	PBA_RECORD pBA = NULL;
+	PBA_PARAM_SET	pBaParamSet = NULL;
+	u16* pBaTimeoutVal = NULL;
+	PSEQUENCE_CONTROL pBaStartSeqCtrl = NULL;
+	PRX_TS_RECORD	pTS = NULL;
+
+	if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %d)\n", skb->len, 	(sizeof( struct ieee80211_hdr_3addr) + 9));
+		return -1;
+	}
+
+	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
+
+	req = ( struct ieee80211_hdr_3addr*) skb->data;
+	tag = (u8*)req;
+	dst = (u8*)(&req->addr2[0]);
+	tag += sizeof( struct ieee80211_hdr_3addr);
+	pDialogToken = tag + 2;  //category+action
+	pBaParamSet = (PBA_PARAM_SET)(tag + 3);   //+DialogToken
+	pBaTimeoutVal = (u16*)(tag + 5);
+	pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7);
+
+	printk("====================>rx ADDBAREQ from :"MAC_FMT"\n", MAC_ARG(dst));
+//some other capability is not ready now.
+	if(	(ieee->current_network.qos_data.active == 0) ||
+		(ieee->pHTInfo->bCurrentHTSupport == false)) //||
+	//	(ieee->pStaQos->bEnableRxImmBA == false)	)
+	{
+		rc = ADDBA_STATUS_REFUSED;
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n", ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport);
+		goto OnADDBAReq_Fail;
+	}
+	// Search for related traffic stream.
+	// If there is no matched TS, reject the ADDBA request.
+	if(	!GetTs(
+			ieee,
+			(PTS_COMMON_INFO*)(&pTS),
+			dst,
+			(u8)(pBaParamSet->field.TID),
+			RX_DIR,
+			true)	)
+	{
+		rc = ADDBA_STATUS_REFUSED;
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS in %s()\n", __FUNCTION__);
+		goto OnADDBAReq_Fail;
+	}
+	pBA = &pTS->RxAdmittedBARecord;
+	// To Determine the ADDBA Req content
+	// We can do much more check here, including BufferSize, AMSDU_Support, Policy, StartSeqCtrl...
+	// I want to check StartSeqCtrl to make sure when we start aggregation!!!
+	//
+	if(pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED)
+	{
+		rc = ADDBA_STATUS_INVALID_PARAM;
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "BA Policy is not correct in %s()\n", __FUNCTION__);
+		goto OnADDBAReq_Fail;
+	}
+		// Admit the ADDBA Request
+	//
+	DeActivateBAEntry(ieee, pBA);
+	pBA->DialogToken = *pDialogToken;
+	pBA->BaParamSet = *pBaParamSet;
+	pBA->BaTimeoutValue = *pBaTimeoutVal;
+	pBA->BaStartSeqCtrl = *pBaStartSeqCtrl;
+	//for half N mode we only aggregate 1 frame
+	if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
+	pBA->BaParamSet.field.BufferSize = 1;
+	else
+	pBA->BaParamSet.field.BufferSize = 32;
+	ActivateBAEntry(ieee, pBA, pBA->BaTimeoutValue);
+	ieee80211_send_ADDBARsp(ieee, dst, pBA, ADDBA_STATUS_SUCCESS);
+
+	// End of procedure.
+	return 0;
+
+OnADDBAReq_Fail:
+	{
+		BA_RECORD	BA;
+		BA.BaParamSet = *pBaParamSet;
+		BA.BaTimeoutValue = *pBaTimeoutVal;
+		BA.DialogToken = *pDialogToken;
+		BA.BaParamSet.field.BAPolicy = BA_POLICY_IMMEDIATE;
+		ieee80211_send_ADDBARsp(ieee, dst, &BA, rc);
+		return 0; //we send RSP out.
+	}
+
+}
+
+/********************************************************************************************************************
+ *function: RX ADDBARSP
+ *   input:  struct sk_buff *   skb	//incoming ADDBAReq skb.
+ *  return:  0(pass), other(fail)
+ *  notice:  As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
+********************************************************************************************************************/
+int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb)
+{
+	 struct ieee80211_hdr_3addr* rsp = NULL;
+	PBA_RECORD		pPendingBA, pAdmittedBA;
+	PTX_TS_RECORD		pTS = NULL;
+	u8* dst = NULL, *pDialogToken = NULL, *tag = NULL;
+	u16* pStatusCode = NULL, *pBaTimeoutVal = NULL;
+	PBA_PARAM_SET		pBaParamSet = NULL;
+	u16			ReasonCode;
+
+	if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %d)\n", skb->len, 	(sizeof( struct ieee80211_hdr_3addr) + 9));
+		return -1;
+	}
+	rsp = ( struct ieee80211_hdr_3addr*)skb->data;
+	tag = (u8*)rsp;
+	dst = (u8*)(&rsp->addr2[0]);
+	tag += sizeof( struct ieee80211_hdr_3addr);
+	pDialogToken = tag + 2;
+	pStatusCode = (u16*)(tag + 3);
+	pBaParamSet = (PBA_PARAM_SET)(tag + 5);
+	pBaTimeoutVal = (u16*)(tag + 7);
+
+	// Check the capability
+	// Since we can always receive A-MPDU, we just check if it is under HT mode.
+	if(     ieee->current_network.qos_data.active == 0  ||
+		ieee->pHTInfo->bCurrentHTSupport == false ||
+		ieee->pHTInfo->bCurrentAMPDUEnable == false )
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n",ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bCurrentAMPDUEnable);
+		ReasonCode = DELBA_REASON_UNKNOWN_BA;
+		goto OnADDBARsp_Reject;
+	}
+
+
+	//
+	// Search for related TS.
+	// If there is no TS found, we wil reject ADDBA Rsp by sending DELBA frame.
+	//
+	if (!GetTs(
+			ieee,
+			(PTS_COMMON_INFO*)(&pTS),
+			dst,
+			(u8)(pBaParamSet->field.TID),
+			TX_DIR,
+			false)	)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS in %s()\n", __FUNCTION__);
+		ReasonCode = DELBA_REASON_UNKNOWN_BA;
+		goto OnADDBARsp_Reject;
+	}
+
+	pTS->bAddBaReqInProgress = false;
+	pPendingBA = &pTS->TxPendingBARecord;
+	pAdmittedBA = &pTS->TxAdmittedBARecord;
+
+
+	//
+	// Check if related BA is waiting for setup.
+	// If not, reject by sending DELBA frame.
+	//
+	if((pAdmittedBA->bValid==true))
+	{
+		// Since BA is already setup, we ignore all other ADDBA Response.
+		IEEE80211_DEBUG(IEEE80211_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. Drop because already admit it! \n");
+		return -1;
+	}
+	else if((pPendingBA->bValid == false) ||(*pDialogToken != pPendingBA->DialogToken))
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR,  "OnADDBARsp(): Recv ADDBA Rsp. BA invalid, DELBA! \n");
+		ReasonCode = DELBA_REASON_UNKNOWN_BA;
+		goto OnADDBARsp_Reject;
+	}
+	else
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n", *pStatusCode);
+		DeActivateBAEntry(ieee, pPendingBA);
+	}
+
+
+	if(*pStatusCode == ADDBA_STATUS_SUCCESS)
+	{
+		//
+		// Determine ADDBA Rsp content here.
+		// We can compare the value of BA parameter set that Peer returned and Self sent.
+		// If it is OK, then admitted. Or we can send DELBA to cancel BA mechanism.
+		//
+		if(pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED)
+		{
+			// Since this is a kind of ADDBA failed, we delay next ADDBA process.
+			pTS->bAddBaReqDelayed = true;
+			DeActivateBAEntry(ieee, pAdmittedBA);
+			ReasonCode = DELBA_REASON_END_BA;
+			goto OnADDBARsp_Reject;
+		}
+
+
+		//
+		// Admitted condition
+		//
+		pAdmittedBA->DialogToken = *pDialogToken;
+		pAdmittedBA->BaTimeoutValue = *pBaTimeoutVal;
+		pAdmittedBA->BaStartSeqCtrl = pPendingBA->BaStartSeqCtrl;
+		pAdmittedBA->BaParamSet = *pBaParamSet;
+		DeActivateBAEntry(ieee, pAdmittedBA);
+		ActivateBAEntry(ieee, pAdmittedBA, *pBaTimeoutVal);
+	}
+	else
+	{
+		// Delay next ADDBA process.
+		pTS->bAddBaReqDelayed = true;
+	}
+
+	// End of procedure
+	return 0;
+
+OnADDBARsp_Reject:
+	{
+		BA_RECORD	BA;
+		BA.BaParamSet = *pBaParamSet;
+		ieee80211_send_DELBA(ieee, dst, &BA, TX_DIR, ReasonCode);
+		return 0;
+	}
+
+}
+
+/********************************************************************************************************************
+ *function: RX DELBA
+ *   input:  struct sk_buff *   skb	//incoming ADDBAReq skb.
+ *  return:  0(pass), other(fail)
+ *  notice:  As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
+********************************************************************************************************************/
+int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb)
+{
+	 struct ieee80211_hdr_3addr* delba = NULL;
+	PDELBA_PARAM_SET	pDelBaParamSet = NULL;
+	u16*			pReasonCode = NULL;
+	u8*			dst = NULL;
+
+	if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %d)\n", skb->len, 	(sizeof( struct ieee80211_hdr_3addr) + 6));
+		return -1;
+	}
+
+	if(ieee->current_network.qos_data.active == 0 ||
+		ieee->pHTInfo->bCurrentHTSupport == false )
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "received DELBA while QOS or HT is not supported(%d, %d)\n",ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport);
+		return -1;
+	}
+
+	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
+	delba = ( struct ieee80211_hdr_3addr*)skb->data;
+	dst = (u8*)(&delba->addr2[0]);
+	delba += sizeof( struct ieee80211_hdr_3addr);
+	pDelBaParamSet = (PDELBA_PARAM_SET)(delba+2);
+	pReasonCode = (u16*)(delba+4);
+
+	if(pDelBaParamSet->field.Initiator == 1)
+	{
+		PRX_TS_RECORD 	pRxTs;
+
+		if( !GetTs(
+				ieee,
+				(PTS_COMMON_INFO*)&pRxTs,
+				dst,
+				(u8)pDelBaParamSet->field.TID,
+				RX_DIR,
+				false)	)
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_ERR,  "can't get TS for RXTS in %s()\n", __FUNCTION__);
+			return -1;
+		}
+
+		RxTsDeleteBA(ieee, pRxTs);
+	}
+	else
+	{
+		PTX_TS_RECORD	pTxTs;
+
+		if(!GetTs(
+			ieee,
+			(PTS_COMMON_INFO*)&pTxTs,
+			dst,
+			(u8)pDelBaParamSet->field.TID,
+			TX_DIR,
+			false)	)
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_ERR,  "can't get TS for TXTS in %s()\n", __FUNCTION__);
+			return -1;
+		}
+
+		pTxTs->bUsingBa = false;
+		pTxTs->bAddBaReqInProgress = false;
+		pTxTs->bAddBaReqDelayed = false;
+		del_timer_sync(&pTxTs->TsAddBaTimer);
+		//PlatformCancelTimer(Adapter, &pTxTs->TsAddBaTimer);
+		TxTsDeleteBA(ieee, pTxTs);
+	}
+	return 0;
+}
+
+//
+// ADDBA initiate. This can only be called by TX side.
+//
+void
+TsInitAddBA(
+	struct ieee80211_device* ieee,
+	PTX_TS_RECORD	pTS,
+	u8		Policy,
+	u8		bOverwritePending
+	)
+{
+	PBA_RECORD			pBA = &pTS->TxPendingBARecord;
+
+	if(pBA->bValid==true && bOverwritePending==false)
+		return;
+
+	// Set parameters to "Pending" variable set
+	DeActivateBAEntry(ieee, pBA);
+
+	pBA->DialogToken++;						// DialogToken: Only keep the latest dialog token
+	pBA->BaParamSet.field.AMSDU_Support = 0;	// Do not support A-MSDU with A-MPDU now!!
+	pBA->BaParamSet.field.BAPolicy = Policy;	// Policy: Delayed or Immediate
+	pBA->BaParamSet.field.TID = pTS->TsCommonInfo.TSpec.f.TSInfo.field.ucTSID;	// TID
+	// BufferSize: This need to be set according to A-MPDU vector
+	pBA->BaParamSet.field.BufferSize = 32;		// BufferSize: This need to be set according to A-MPDU vector
+	pBA->BaTimeoutValue = 0;					// Timeout value: Set 0 to disable Timer
+	pBA->BaStartSeqCtrl.field.SeqNum = (pTS->TxCurSeq + 3) % 4096; 	// Block Ack will start after 3 packets later.
+
+	ActivateBAEntry(ieee, pBA, BA_SETUP_TIMEOUT);
+
+	ieee80211_send_ADDBAReq(ieee, pTS->TsCommonInfo.Addr, pBA);
+}
+
+void
+TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect)
+{
+
+	if(TxRxSelect == TX_DIR)
+	{
+		PTX_TS_RECORD	pTxTs = (PTX_TS_RECORD)pTsCommonInfo;
+
+		if(TxTsDeleteBA(ieee, pTxTs))
+			ieee80211_send_DELBA(
+				ieee,
+				pTsCommonInfo->Addr,
+				(pTxTs->TxAdmittedBARecord.bValid)?(&pTxTs->TxAdmittedBARecord):(&pTxTs->TxPendingBARecord),
+				TxRxSelect,
+				DELBA_REASON_END_BA);
+	}
+	else if(TxRxSelect == RX_DIR)
+	{
+		PRX_TS_RECORD	pRxTs = (PRX_TS_RECORD)pTsCommonInfo;
+		if(RxTsDeleteBA(ieee, pRxTs))
+			ieee80211_send_DELBA(
+				ieee,
+				pTsCommonInfo->Addr,
+				&pRxTs->RxAdmittedBARecord,
+				TxRxSelect,
+				DELBA_REASON_END_BA	);
+	}
+}
+/********************************************************************************************************************
+ *function:  BA setup timer
+ *   input:  unsigned long	 data		//acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer
+ *  return:  NULL
+ *  notice:
+********************************************************************************************************************/
+void BaSetupTimeOut(unsigned long data)
+{
+	PTX_TS_RECORD	pTxTs = (PTX_TS_RECORD)data;
+
+	pTxTs->bAddBaReqInProgress = false;
+	pTxTs->bAddBaReqDelayed = true;
+	pTxTs->TxPendingBARecord.bValid = false;
+}
+
+void TxBaInactTimeout(unsigned long data)
+{
+	PTX_TS_RECORD	pTxTs = (PTX_TS_RECORD)data;
+	struct ieee80211_device *ieee = container_of(pTxTs, struct ieee80211_device, TxTsRecord[pTxTs->num]);
+	TxTsDeleteBA(ieee, pTxTs);
+	ieee80211_send_DELBA(
+		ieee,
+		pTxTs->TsCommonInfo.Addr,
+		&pTxTs->TxAdmittedBARecord,
+		TX_DIR,
+		DELBA_REASON_TIMEOUT);
+}
+
+void RxBaInactTimeout(unsigned long data)
+{
+	PRX_TS_RECORD	pRxTs = (PRX_TS_RECORD)data;
+	struct ieee80211_device *ieee = container_of(pRxTs, struct ieee80211_device, RxTsRecord[pRxTs->num]);
+
+	RxTsDeleteBA(ieee, pRxTs);
+	ieee80211_send_DELBA(
+		ieee,
+		pRxTs->TsCommonInfo.Addr,
+		&pRxTs->RxAdmittedBARecord,
+		RX_DIR,
+		DELBA_REASON_TIMEOUT);
+	return ;
+}
+
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h b/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h
new file mode 100644
index 0000000..cde603f
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h
@@ -0,0 +1,481 @@
+#ifndef _RTL819XU_HTTYPE_H_
+#define _RTL819XU_HTTYPE_H_
+
+//------------------------------------------------------------
+// The HT Capability element is present in beacons, association request,
+//	reassociation request and probe response frames
+//------------------------------------------------------------
+
+//
+// Operation mode value
+//
+#define HT_OPMODE_NO_PROTECT		0
+#define HT_OPMODE_OPTIONAL		1
+#define HT_OPMODE_40MHZ_PROTECT	2
+#define HT_OPMODE_MIXED			3
+
+//
+// MIMO Power Save Setings
+//
+#define MIMO_PS_STATIC				0
+#define MIMO_PS_DYNAMIC			1
+#define MIMO_PS_NOLIMIT			3
+
+
+//
+//	There should be 128 bits to cover all of the MCS rates. However, since
+//	8190 does not support too much rates, one integer is quite enough.
+//
+
+#define sHTCLng	4
+
+
+#define HT_SUPPORTED_MCS_1SS_BITMAP					0x000000ff
+#define HT_SUPPORTED_MCS_2SS_BITMAP					0x0000ff00
+#define HT_SUPPORTED_MCS_1SS_2SS_BITMAP			HT_MCS_1SS_BITMAP|HT_MCS_1SS_2SS_BITMAP
+
+
+typedef enum _HT_MCS_RATE{
+	HT_MCS0   = 0x00000001,
+	HT_MCS1   = 0x00000002,
+	HT_MCS2   = 0x00000004,
+	HT_MCS3   = 0x00000008,
+	HT_MCS4   = 0x00000010,
+	HT_MCS5   = 0x00000020,
+	HT_MCS6   = 0x00000040,
+	HT_MCS7   = 0x00000080,
+	HT_MCS8   = 0x00000100,
+	HT_MCS9   = 0x00000200,
+	HT_MCS10 = 0x00000400,
+	HT_MCS11 = 0x00000800,
+	HT_MCS12 = 0x00001000,
+	HT_MCS13 = 0x00002000,
+	HT_MCS14 = 0x00004000,
+	HT_MCS15 = 0x00008000,
+	// Do not define MCS32 here although 8190 support MCS32
+}HT_MCS_RATE,*PHT_MCS_RATE;
+
+//
+// Represent Channel Width in HT Capabilities
+//
+typedef enum _HT_CHANNEL_WIDTH{
+	HT_CHANNEL_WIDTH_20 = 0,
+	HT_CHANNEL_WIDTH_20_40 = 1,
+}HT_CHANNEL_WIDTH, *PHT_CHANNEL_WIDTH;
+
+//
+// Represent Extention Channel Offset in HT Capabilities
+// This is available only in 40Mhz mode.
+//
+typedef enum _HT_EXTCHNL_OFFSET{
+	HT_EXTCHNL_OFFSET_NO_EXT = 0,
+	HT_EXTCHNL_OFFSET_UPPER = 1,
+	HT_EXTCHNL_OFFSET_NO_DEF = 2,
+	HT_EXTCHNL_OFFSET_LOWER = 3,
+}HT_EXTCHNL_OFFSET, *PHT_EXTCHNL_OFFSET;
+
+typedef enum _CHNLOP{
+	CHNLOP_NONE = 0, // No Action now
+	CHNLOP_SCAN = 1, // Scan in progress
+	CHNLOP_SWBW = 2, // Bandwidth switching in progress
+	CHNLOP_SWCHNL = 3, // Software Channel switching in progress
+} CHNLOP, *PCHNLOP;
+
+// Determine if the Channel Operation is in progress
+#define CHHLOP_IN_PROGRESS(_pHTInfo)	\
+		((_pHTInfo)->ChnlOp > CHNLOP_NONE) ? TRUE : FALSE
+
+/*
+typedef	union _HT_CAPABILITY{
+	u16	ShortData;
+	u8	CharData[2];
+	struct
+	{
+		u16	AdvCoding:1;
+		u16	ChlWidth:1;
+		u16	MimoPwrSave:2;
+		u16	GreenField:1;
+		u16	ShortGI20Mhz:1;
+		u16	ShortGI40Mhz:1;
+		u16	STBC:1;
+		u16	BeamForm:1;
+		u16	DelayBA:1;
+		u16	MaxAMSDUSize:1;
+		u16	DssCCk:1;
+		u16	PSMP:1;
+		u16	Rsvd:3;
+	}Field;
+}HT_CAPABILITY, *PHT_CAPABILITY;
+
+typedef	union _HT_CAPABILITY_MACPARA{
+	u8	ShortData;
+	u8	CharData[1];
+	struct
+	{
+		u8	MaxRxAMPDU:2;
+		u8	MPDUDensity:2;
+		u8	Rsvd:4;
+	}Field;
+}HT_CAPABILITY_MACPARA, *PHT_CAPABILITY_MACPARA;
+*/
+
+typedef enum _HT_ACTION{
+	ACT_RECOMMAND_WIDTH		= 0,
+	ACT_MIMO_PWR_SAVE 		= 1,
+	ACT_PSMP					= 2,
+	ACT_SET_PCO_PHASE		= 3,
+	ACT_MIMO_CHL_MEASURE	= 4,
+	ACT_RECIPROCITY_CORRECT	= 5,
+	ACT_MIMO_CSI_MATRICS		= 6,
+	ACT_MIMO_NOCOMPR_STEER	= 7,
+	ACT_MIMO_COMPR_STEER		= 8,
+	ACT_ANTENNA_SELECT		= 9,
+} HT_ACTION, *PHT_ACTION;
+
+
+/* 2007/06/07 MH Define sub-carrier mode for 40MHZ. */
+typedef enum _HT_Bandwidth_40MHZ_Sub_Carrier{
+	SC_MODE_DUPLICATE = 0,
+	SC_MODE_LOWER = 1,
+	SC_MODE_UPPER = 2,
+	SC_MODE_FULL40MHZ = 3,
+}HT_BW40_SC_E;
+
+typedef	struct _HT_CAPABILITY_ELE{
+
+	//HT capability info
+	u8	AdvCoding:1;
+	u8	ChlWidth:1;
+	u8	MimoPwrSave:2;
+	u8	GreenField:1;
+	u8	ShortGI20Mhz:1;
+	u8	ShortGI40Mhz:1;
+	u8	TxSTBC:1;
+	u8	RxSTBC:2;
+	u8	DelayBA:1;
+	u8	MaxAMSDUSize:1;
+	u8	DssCCk:1;
+	u8	PSMP:1;
+	u8	Rsvd1:1;
+	u8	LSigTxopProtect:1;
+
+	//MAC HT parameters info
+	u8	MaxRxAMPDUFactor:2;
+	u8	MPDUDensity:3;
+	u8	Rsvd2:3;
+
+	//Supported MCS set
+	u8	MCS[16];
+
+
+	//Extended HT Capability Info
+	u16	ExtHTCapInfo;
+
+	//TXBF Capabilities
+	u8	TxBFCap[4];
+
+	//Antenna Selection Capabilities
+	u8	ASCap;
+
+} __attribute__ ((packed)) HT_CAPABILITY_ELE, *PHT_CAPABILITY_ELE;
+
+//------------------------------------------------------------
+// The HT Information element is present in beacons
+// Only AP is required to include this element
+//------------------------------------------------------------
+
+typedef struct _HT_INFORMATION_ELE{
+	u8	ControlChl;
+
+	u8	ExtChlOffset:2;
+	u8	RecommemdedTxWidth:1;
+	u8	RIFS:1;
+	u8	PSMPAccessOnly:1;
+	u8	SrvIntGranularity:3;
+
+	u8	OptMode:2;
+	u8	NonGFDevPresent:1;
+	u8	Revd1:5;
+	u8	Revd2:8;
+
+	u8	Rsvd3:6;
+	u8	DualBeacon:1;
+	u8	DualCTSProtect:1;
+
+	u8	SecondaryBeacon:1;
+	u8	LSigTxopProtectFull:1;
+	u8	PcoActive:1;
+	u8	PcoPhase:1;
+	u8	Rsvd4:4;
+
+	u8	BasicMSC[16];
+} __attribute__ ((packed)) HT_INFORMATION_ELE, *PHT_INFORMATION_ELE;
+
+//
+// MIMO Power Save control field.
+// This is appear in MIMO Power Save Action Frame
+//
+typedef struct _MIMOPS_CTRL{
+	u8	MimoPsEnable:1;
+	u8	MimoPsMode:1;
+	u8	Reserved:6;
+} MIMOPS_CTRL, *PMIMOPS_CTRL;
+
+typedef enum _HT_SPEC_VER{
+	HT_SPEC_VER_IEEE = 0,
+	HT_SPEC_VER_EWC = 1,
+}HT_SPEC_VER, *PHT_SPEC_VER;
+
+typedef enum _HT_AGGRE_MODE_E{
+	HT_AGG_AUTO = 0,
+	HT_AGG_FORCE_ENABLE = 1,
+	HT_AGG_FORCE_DISABLE = 2,
+}HT_AGGRE_MODE_E, *PHT_AGGRE_MODE_E;
+
+//------------------------------------------------------------
+//  The Data structure is used to keep HT related variables when card is
+//  configured as non-AP STA mode.  **Note**  Current_xxx should be set
+//	to default value in HTInitializeHTInfo()
+//------------------------------------------------------------
+
+typedef struct _RT_HIGH_THROUGHPUT{
+	u8				bEnableHT;
+	u8				bCurrentHTSupport;
+
+	u8				bRegBW40MHz;				// Tx 40MHz channel capablity
+	u8				bCurBW40MHz;				// Tx 40MHz channel capability
+
+	u8				bRegShortGI40MHz;			// Tx Short GI for 40Mhz
+	u8				bCurShortGI40MHz;			// Tx Short GI for 40MHz
+
+	u8				bRegShortGI20MHz;			// Tx Short GI for 20MHz
+	u8				bCurShortGI20MHz;			// Tx Short GI for 20MHz
+
+	u8				bRegSuppCCK;				// Tx CCK rate capability
+	u8				bCurSuppCCK;				// Tx CCK rate capability
+
+	// 802.11n spec version for "peer"
+	HT_SPEC_VER			ePeerHTSpecVer;
+
+
+	// HT related information for "Self"
+	HT_CAPABILITY_ELE	SelfHTCap;		// This is HT cap element sent to peer STA, which also indicate HT Rx capabilities.
+	HT_INFORMATION_ELE	SelfHTInfo;		// This is HT info element sent to peer STA, which also indicate HT Rx capabilities.
+
+	// HT related information for "Peer"
+	u8				PeerHTCapBuf[32];
+	u8				PeerHTInfoBuf[32];
+
+
+	// A-MSDU related
+	u8				bAMSDU_Support;			// This indicates Tx A-MSDU capability
+	u16				nAMSDU_MaxSize;			// This indicates Tx A-MSDU capability
+	u8				bCurrent_AMSDU_Support;	// This indicates Tx A-MSDU capability
+	u16				nCurrent_AMSDU_MaxSize;	// This indicates Tx A-MSDU capability
+
+
+	// AMPDU  related <2006.08.10 Emily>
+	u8				bAMPDUEnable;				// This indicate Tx A-MPDU capability
+	u8				bCurrentAMPDUEnable;		// This indicate Tx A-MPDU capability
+	u8				AMPDU_Factor;				// This indicate Tx A-MPDU capability
+	u8				CurrentAMPDUFactor;		// This indicate Tx A-MPDU capability
+	u8				MPDU_Density;				// This indicate Tx A-MPDU capability
+	u8				CurrentMPDUDensity;			// This indicate Tx A-MPDU capability
+
+	// Forced A-MPDU enable
+	HT_AGGRE_MODE_E	ForcedAMPDUMode;
+	u8				ForcedAMPDUFactor;
+	u8				ForcedMPDUDensity;
+
+	// Forced A-MSDU enable
+	HT_AGGRE_MODE_E	ForcedAMSDUMode;
+	u16				ForcedAMSDUMaxSize;
+
+	u8				bForcedShortGI;
+
+	u8				CurrentOpMode;
+
+	// MIMO PS related
+	u8				SelfMimoPs;
+	u8				PeerMimoPs;
+
+	// 40MHz Channel Offset settings.
+	HT_EXTCHNL_OFFSET	CurSTAExtChnlOffset;
+	u8				bCurTxBW40MHz;	// If we use 40 MHz to Tx
+	u8				PeerBandwidth;
+
+	// For Bandwidth Switching
+	u8				bSwBwInProgress;
+	CHNLOP				ChnlOp; // software switching channel in progress. By Bruce, 2008-02-15.
+	u8				SwBwStep;
+	//struct timer_list		SwBwTimer;  //moved to ieee80211_device. as timer_list need include some header file here.
+
+	// For Realtek proprietary A-MPDU factor for aggregation
+	u8				bRegRT2RTAggregation;
+	u8				bCurrentRT2RTAggregation;
+	u8				bCurrentRT2RTLongSlotTime;
+	u8				szRT2RTAggBuffer[10];
+
+	// Rx Reorder control
+	u8				bRegRxReorderEnable;
+	u8				bCurRxReorderEnable;
+	u8				RxReorderWinSize;
+	u8				RxReorderPendingTime;
+	u16				RxReorderDropCounter;
+
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+	u8				UsbTxAggrNum;
+#endif
+#ifdef USB_RX_AGGREGATION_SUPPORT
+	u8				UsbRxFwAggrEn;
+	u8				UsbRxFwAggrPageNum;
+	u8				UsbRxFwAggrPacketNum;
+	u8				UsbRxFwAggrTimeout;
+#endif
+
+	// Add for Broadcom(Linksys) IOT. Joseph
+	u8				bIsPeerBcm;
+
+	// For IOT issue.
+	u8				IOTPeer;
+	u32				IOTAction;
+} __attribute__ ((packed)) RT_HIGH_THROUGHPUT, *PRT_HIGH_THROUGHPUT;
+
+
+//------------------------------------------------------------
+// The Data structure is used to keep HT related variable for "each Sta"
+// when card is configured as "AP mode"
+//------------------------------------------------------------
+
+typedef struct _RT_HTINFO_STA_ENTRY{
+	u8			bEnableHT;
+
+	u8			bSupportCck;
+
+	u16			AMSDU_MaxSize;
+
+	u8			AMPDU_Factor;
+	u8			MPDU_Density;
+
+	u8			HTHighestOperaRate;
+
+	u8			bBw40MHz;
+
+	u8			MimoPs;
+
+	u8			McsRateSet[16];
+
+
+}RT_HTINFO_STA_ENTRY, *PRT_HTINFO_STA_ENTRY;
+
+
+
+
+
+//------------------------------------------------------------
+// The Data structure is used to keep HT related variable for "each AP"
+// when card is configured as "STA mode"
+//------------------------------------------------------------
+
+typedef struct _BSS_HT{
+
+	u8				bdSupportHT;
+
+	// HT related elements
+	u8					bdHTCapBuf[32];
+	u16					bdHTCapLen;
+	u8					bdHTInfoBuf[32];
+	u16					bdHTInfoLen;
+
+	HT_SPEC_VER				bdHTSpecVer;
+	//HT_CAPABILITY_ELE			bdHTCapEle;
+	//HT_INFORMATION_ELE		bdHTInfoEle;
+
+	u8					bdRT2RTAggregation;
+	u8					bdRT2RTLongSlotTime;
+} __attribute__ ((packed)) BSS_HT, *PBSS_HT;
+
+typedef struct _MIMO_RSSI{
+	u32	EnableAntenna;
+	u32	AntennaA;
+	u32 	AntennaB;
+	u32 	AntennaC;
+	u32 	AntennaD;
+	u32	Average;
+}MIMO_RSSI, *PMIMO_RSSI;
+
+typedef struct _MIMO_EVM{
+	u32	EVM1;
+	u32    EVM2;
+}MIMO_EVM, *PMIMO_EVM;
+
+typedef struct _FALSE_ALARM_STATISTICS{
+	u32	Cnt_Parity_Fail;
+	u32    Cnt_Rate_Illegal;
+	u32	Cnt_Crc8_fail;
+	u32	Cnt_all;
+}FALSE_ALARM_STATISTICS, *PFALSE_ALARM_STATISTICS;
+
+
+extern u8 MCS_FILTER_ALL[16];
+extern u8 MCS_FILTER_1SS[16];
+
+/* 2007/07/11 MH Modify the macro. Becaus STA may link with a N-AP. If we set
+   STA in A/B/G mode and AP is still in N mode. The macro will be wrong. We have
+   to add a macro to judge wireless mode. */
+#define PICK_RATE(_nLegacyRate, _nMcsRate)	\
+		(_nMcsRate==0)?(_nLegacyRate&0x7f):(_nMcsRate)
+/* 2007/07/12 MH We only define legacy and HT wireless mode now. */
+#define	LEGACY_WIRELESS_MODE	IEEE_MODE_MASK
+
+#define CURRENT_RATE(WirelessMode, LegacyRate, HTRate)	\
+					((WirelessMode & (LEGACY_WIRELESS_MODE))!=0)?\
+						(LegacyRate):\
+						(PICK_RATE(LegacyRate, HTRate))
+
+
+
+// MCS Bw 40 {1~7, 12~15,32}
+#define	RATE_ADPT_1SS_MASK 		0xFF
+#define	RATE_ADPT_2SS_MASK		0xF0 //Skip MCS8~11 because mcs7 > mcs6, 9, 10, 11. 2007.01.16 by Emily
+#define	RATE_ADPT_MCS32_MASK		0x01
+
+#define 	IS_11N_MCS_RATE(rate)		(rate&0x80)
+
+typedef enum _HT_AGGRE_SIZE{
+	HT_AGG_SIZE_8K = 0,
+	HT_AGG_SIZE_16K = 1,
+	HT_AGG_SIZE_32K = 2,
+	HT_AGG_SIZE_64K = 3,
+}HT_AGGRE_SIZE_E, *PHT_AGGRE_SIZE_E;
+
+/* Indicate different AP vendor for IOT issue */
+typedef enum _HT_IOT_PEER
+{
+	HT_IOT_PEER_UNKNOWN = 0,
+	HT_IOT_PEER_REALTEK = 1,
+	HT_IOT_PEER_BROADCOM = 2,
+	HT_IOT_PEER_RALINK = 3,
+	HT_IOT_PEER_ATHEROS = 4,
+	HT_IOT_PEER_CISCO= 5,
+	HT_IOT_PEER_MAX = 6
+}HT_IOT_PEER_E, *PHTIOT_PEER_E;
+
+//
+// IOT Action for different AP
+//
+typedef enum _HT_IOT_ACTION{
+	HT_IOT_ACT_TX_USE_AMSDU_4K = 0x00000001,
+	HT_IOT_ACT_TX_USE_AMSDU_8K = 0x00000002,
+	HT_IOT_ACT_DISABLE_MCS14 = 0x00000004,
+	HT_IOT_ACT_DISABLE_MCS15 = 0x00000008,
+	HT_IOT_ACT_DISABLE_ALL_2SS = 0x00000010,
+	HT_IOT_ACT_DISABLE_EDCA_TURBO = 0x00000020,
+	HT_IOT_ACT_MGNT_USE_CCK_6M = 0x00000040,
+	HT_IOT_ACT_CDD_FSYNC = 0x00000080,
+	HT_IOT_ACT_PURE_N_MODE = 0x00000100,
+	HT_IOT_ACT_FORCED_CTS2SELF = 0x00000200,
+}HT_IOT_ACTION_E, *PHT_IOT_ACTION_E;
+
+#endif //_RTL819XU_HTTYPE_H_
+
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c
new file mode 100644
index 0000000..2c4eb38
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c
@@ -0,0 +1,1462 @@
+
+//As this function is mainly ported from Windows driver, so leave the name little changed. If any confusion caused, tell me. Created by WB. 2008.05.08
+#include "ieee80211.h"
+#include "rtl819x_HT.h"
+u8 MCS_FILTER_ALL[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+u8 MCS_FILTER_1SS[16] = {0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+u16 MCS_DATA_RATE[2][2][77] =
+	{	{	{13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78 ,104, 156, 208, 234, 260,
+			39, 78, 117, 234, 312, 351, 390, 52, 104, 156, 208, 312, 416, 468, 520,
+			0, 78, 104, 130, 117, 156, 195, 104, 130, 130, 156, 182, 182, 208, 156, 195,
+			195, 234, 273, 273, 312, 130, 156, 181, 156, 181, 208, 234, 208, 234, 260, 260,
+			286, 195, 234, 273, 234, 273, 312, 351, 312, 351, 390, 390, 429},			// Long GI, 20MHz
+			{14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289,
+			43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520, 578,
+			0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231, 173, 217,
+			217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260, 231, 260, 289, 289,
+			318, 217, 260, 303, 260, 303, 347, 390, 347, 390, 433, 433, 477}	},		// Short GI, 20MHz
+		{	{27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540,
+			81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648, 864, 972, 1080,
+			12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324, 378, 378, 432, 324, 405,
+			405, 486, 567, 567, 648, 270, 324, 378, 324, 378, 432, 486, 432, 486, 540, 540,
+			594, 405, 486, 567, 486, 567, 648, 729, 648, 729, 810, 810, 891}, 	// Long GI, 40MHz
+			{30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600,
+			90, 180, 270, 360, 540, 720, 810, 900, 120, 240, 360, 480, 720, 960, 1080, 1200,
+			13, 180, 240, 300, 270, 360, 450, 240, 300, 300, 360, 420, 420, 480, 360, 450,
+			450, 540, 630, 630, 720, 300, 360, 420, 360, 420, 480, 540, 480, 540, 600, 600,
+			660, 450, 540, 630, 540, 630, 720, 810, 720, 810, 900, 900, 990}	}	// Short GI, 40MHz
+	};
+
+static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf};
+static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70};
+static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e};
+static u8 NETGEAR834Bv2_BROADCOM[3] = {0x00, 0x1b, 0x2f};
+static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f};	//cosa 03202008
+static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf};
+static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc};
+static u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e};
+static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02};
+//static u8 DLINK_ATHEROS[3] = {0x00, 0x1c, 0xf0};
+static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94};
+
+// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Shoud we put the
+// code in other place??
+//static u8 WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96};
+/********************************************************************************************************************
+ *function:  This function update default settings in pHTInfo structure
+ *   input:  PRT_HIGH_THROUGHPUT	pHTInfo
+ *  output:  none
+ *  return:  none
+ *  notice:  These value need be modified if any changes.
+ * *****************************************************************************************************************/
+void HTUpdateDefaultSetting(struct ieee80211_device* ieee)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	//const typeof( ((struct ieee80211_device *)0)->pHTInfo ) *__mptr = &pHTInfo;
+
+	//printk("pHTinfo:%p, &pHTinfo:%p, mptr:%p,  offsetof:%x\n", pHTInfo, &pHTInfo, __mptr, offsetof(struct ieee80211_device, pHTInfo));
+	//printk("===>ieee:%p,\n", ieee);
+	// ShortGI support
+	pHTInfo->bRegShortGI20MHz= 1;
+	pHTInfo->bRegShortGI40MHz= 1;
+
+	// 40MHz channel support
+	pHTInfo->bRegBW40MHz = 1;
+
+	// CCK rate support in 40MHz channel
+	if(pHTInfo->bRegBW40MHz)
+		pHTInfo->bRegSuppCCK = 1;
+	else
+		pHTInfo->bRegSuppCCK = true;
+
+	// AMSDU related
+	pHTInfo->nAMSDU_MaxSize = 7935UL;
+	pHTInfo->bAMSDU_Support = 0;
+
+	// AMPDU related
+	pHTInfo->bAMPDUEnable = 1;
+	pHTInfo->AMPDU_Factor = 2; //// 0: 2n13(8K), 1:2n14(16K), 2:2n15(32K), 3:2n16(64k)
+	pHTInfo->MPDU_Density = 0;// 0: No restriction, 1: 1/8usec, 2: 1/4usec, 3: 1/2usec, 4: 1usec, 5: 2usec, 6: 4usec, 7:8usec
+
+	// MIMO Power Save
+	pHTInfo->SelfMimoPs = 3;// 0: Static Mimo Ps, 1: Dynamic Mimo Ps, 3: No Limitation, 2: Reserved(Set to 3 automatically.)
+	if(pHTInfo->SelfMimoPs == 2)
+		pHTInfo->SelfMimoPs = 3;
+	// 8190 only. Assign rate operation mode to firmware
+	ieee->bTxDisableRateFallBack = 0;
+	ieee->bTxUseDriverAssingedRate = 0;
+
+#ifdef 	TO_DO_LIST
+	// 8190 only. Assign duration operation mode to firmware
+	pMgntInfo->bTxEnableFwCalcDur = (BOOLEAN)pNdisCommon->bRegTxEnableFwCalcDur;
+#endif
+	// 8190 only, Realtek proprietary aggregation mode
+	// Set MPDUDensity=2,   1: Set MPDUDensity=2(32k)  for Realtek AP and set MPDUDensity=0(8k) for others
+	pHTInfo->bRegRT2RTAggregation = 1;//0: Set MPDUDensity=2,   1: Set MPDUDensity=2(32k)  for Realtek AP and set MPDUDensity=0(8k) for others
+
+	// For Rx Reorder Control
+	pHTInfo->bRegRxReorderEnable = 1;
+	pHTInfo->RxReorderWinSize = 64;
+	pHTInfo->RxReorderPendingTime = 30;
+
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+	pHTInfo->UsbTxAggrNum = 4;
+#endif
+#ifdef USB_RX_AGGREGATION_SUPPORT
+	pHTInfo->UsbRxFwAggrEn = 1;
+	pHTInfo->UsbRxFwAggrPageNum = 24;
+	pHTInfo->UsbRxFwAggrPacketNum = 8;
+	pHTInfo->UsbRxFwAggrTimeout = 16; ////usb rx FW aggregation timeout threshold.It's in units of 64us
+#endif
+
+
+}
+/********************************************************************************************************************
+ *function:  This function print out each field on HT capability IE mainly from (Beacon/ProbeRsp/AssocReq)
+ *   input:  u8*	CapIE       //Capability IE to be printed out
+ *   	     u8* 	TitleString //mainly print out caller function
+ *  output:  none
+ *  return:  none
+ *  notice:  Driver should not print out this message by default.
+ * *****************************************************************************************************************/
+void HTDebugHTCapability(u8* CapIE, u8* TitleString )
+{
+
+	static u8	EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};	// For 11n EWC definition, 2007.07.17, by Emily
+	PHT_CAPABILITY_ELE 		pCapELE;
+
+	if(!memcmp(CapIE, EWC11NHTCap, sizeof(EWC11NHTCap)))
+	{
+		//EWC IE
+		IEEE80211_DEBUG(IEEE80211_DL_HT, "EWC IE in %s()\n", __FUNCTION__);
+		pCapELE = (PHT_CAPABILITY_ELE)(&CapIE[4]);
+	}else
+		pCapELE = (PHT_CAPABILITY_ELE)(&CapIE[0]);
+
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "<Log HT Capability>. Called by %s\n", TitleString );
+
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tSupported Channel Width = %s\n", (pCapELE->ChlWidth)?"20MHz": "20/40MHz");
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tSupport Short GI for 20M = %s\n", (pCapELE->ShortGI20Mhz)?"YES": "NO");
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tSupport Short GI for 40M = %s\n", (pCapELE->ShortGI40Mhz)?"YES": "NO");
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tSupport TX STBC = %s\n", (pCapELE->TxSTBC)?"YES": "NO");
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tMax AMSDU Size = %s\n", (pCapELE->MaxAMSDUSize)?"3839": "7935");
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tSupport CCK in 20/40 mode = %s\n", (pCapELE->DssCCk)?"YES": "NO");
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tMax AMPDU Factor = %d\n", pCapELE->MaxRxAMPDUFactor);
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tMPDU Density = %d\n", pCapELE->MPDUDensity);
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tMCS Rate Set = [%x][%x][%x][%x][%x]\n", pCapELE->MCS[0],\
+				pCapELE->MCS[1], pCapELE->MCS[2], pCapELE->MCS[3], pCapELE->MCS[4]);
+	return;
+
+}
+/********************************************************************************************************************
+ *function:  This function print out each field on HT Information IE mainly from (Beacon/ProbeRsp)
+ *   input:  u8*	InfoIE       //Capability IE to be printed out
+ *   	     u8* 	TitleString //mainly print out caller function
+ *  output:  none
+ *  return:  none
+ *  notice:  Driver should not print out this message by default.
+ * *****************************************************************************************************************/
+void HTDebugHTInfo(u8*	InfoIE, u8* TitleString)
+{
+
+	static u8	EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34};	// For 11n EWC definition, 2007.07.17, by Emily
+	PHT_INFORMATION_ELE		pHTInfoEle;
+
+	if(!memcmp(InfoIE, EWC11NHTInfo, sizeof(EWC11NHTInfo)))
+	{
+		// Not EWC IE
+		IEEE80211_DEBUG(IEEE80211_DL_HT, "EWC IE in %s()\n", __FUNCTION__);
+		pHTInfoEle = (PHT_INFORMATION_ELE)(&InfoIE[4]);
+	}else
+		pHTInfoEle = (PHT_INFORMATION_ELE)(&InfoIE[0]);
+
+
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "<Log HT Information Element>. Called by %s\n", TitleString);
+
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "\tPrimary channel = %d\n", pHTInfoEle->ControlChl);
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSenondary channel =");
+	switch(pHTInfoEle->ExtChlOffset)
+	{
+		case 0:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "Not Present\n");
+			break;
+		case 1:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "Upper channel\n");
+			break;
+		case 2:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "Reserved. Eooro!!!\n");
+			break;
+		case 3:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "Lower Channel\n");
+			break;
+	}
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "\tRecommended channel width = %s\n", (pHTInfoEle->RecommemdedTxWidth)?"20Mhz": "40Mhz");
+
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "\tOperation mode for protection = ");
+	switch(pHTInfoEle->OptMode)
+	{
+		case 0:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "No Protection\n");
+			break;
+		case 1:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "HT non-member protection mode\n");
+			break;
+		case 2:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "Suggest to open protection\n");
+			break;
+		case 3:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "HT mixed mode\n");
+			break;
+	}
+
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "\tBasic MCS Rate Set = [%x][%x][%x][%x][%x]\n", pHTInfoEle->BasicMSC[0],\
+				pHTInfoEle->BasicMSC[1], pHTInfoEle->BasicMSC[2], pHTInfoEle->BasicMSC[3], pHTInfoEle->BasicMSC[4]);
+	return;
+}
+
+/*
+*	Return:     	true if station in half n mode and AP supports 40 bw
+*/
+bool IsHTHalfNmode40Bandwidth(struct ieee80211_device* ieee)
+{
+	bool			retValue = false;
+	PRT_HIGH_THROUGHPUT	 pHTInfo = ieee->pHTInfo;
+
+	if(pHTInfo->bCurrentHTSupport == false )	// wireless is n mode
+		retValue = false;
+	else if(pHTInfo->bRegBW40MHz == false)	// station supports 40 bw
+		retValue = false;
+	else if(!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) 	// station in half n mode
+		retValue = false;
+	else if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ChlWidth) // ap support 40 bw
+		retValue = true;
+	else
+		retValue = false;
+
+	return retValue;
+}
+
+bool IsHTHalfNmodeSGI(struct ieee80211_device* ieee, bool is40MHz)
+{
+	bool			retValue = false;
+	PRT_HIGH_THROUGHPUT	 pHTInfo = ieee->pHTInfo;
+
+	if(pHTInfo->bCurrentHTSupport == false )	// wireless is n mode
+		retValue = false;
+	else if(!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) 	// station in half n mode
+		retValue = false;
+	else if(is40MHz) // ap support 40 bw
+	{
+		if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ShortGI40Mhz) // ap support 40 bw short GI
+			retValue = true;
+		else
+			retValue = false;
+	}
+	else
+	{
+		if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ShortGI20Mhz) // ap support 40 bw short GI
+			retValue = true;
+		else
+			retValue = false;
+	}
+
+	return retValue;
+}
+
+u16 HTHalfMcsToDataRate(struct ieee80211_device* ieee, 	u8	nMcsRate)
+{
+
+	u8	is40MHz;
+	u8	isShortGI;
+
+	is40MHz  =  (IsHTHalfNmode40Bandwidth(ieee))?1:0;
+	isShortGI = (IsHTHalfNmodeSGI(ieee, is40MHz))? 1:0;
+
+	return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate&0x7f)];
+}
+
+
+u16 HTMcsToDataRate( struct ieee80211_device* ieee, u8 nMcsRate)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+
+	u8	is40MHz = (pHTInfo->bCurBW40MHz)?1:0;
+	u8	isShortGI = (pHTInfo->bCurBW40MHz)?
+						((pHTInfo->bCurShortGI40MHz)?1:0):
+						((pHTInfo->bCurShortGI20MHz)?1:0);
+	return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate&0x7f)];
+}
+
+/********************************************************************************************************************
+ *function:  This function returns current datarate.
+ *   input:  struct ieee80211_device* 	ieee
+ *   	     u8 			nDataRate
+ *  output:  none
+ *  return:  tx rate
+ *  notice:  quite unsure about how to use this function //wb
+ * *****************************************************************************************************************/
+u16  TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate)
+{
+	//PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	u16		CCKOFDMRate[12] = {0x02 , 0x04 , 0x0b , 0x16 , 0x0c , 0x12 , 0x18 , 0x24 , 0x30 , 0x48 , 0x60 , 0x6c};
+	u8	is40MHz = 0;
+	u8	isShortGI = 0;
+
+	if(nDataRate < 12)
+	{
+		return CCKOFDMRate[nDataRate];
+	}
+	else
+	{
+		if (nDataRate >= 0x10 && nDataRate <= 0x1f)//if(nDataRate > 11 && nDataRate < 28 )
+		{
+			is40MHz = 0;
+			isShortGI = 0;
+
+		      // nDataRate = nDataRate - 12;
+		}
+		else if(nDataRate >=0x20  && nDataRate <= 0x2f ) //(27, 44)
+		{
+			is40MHz = 1;
+			isShortGI = 0;
+
+			//nDataRate = nDataRate - 28;
+		}
+		else if(nDataRate >= 0x30  && nDataRate <= 0x3f )  //(43, 60)
+		{
+			is40MHz = 0;
+			isShortGI = 1;
+
+			//nDataRate = nDataRate - 44;
+		}
+		else if(nDataRate >= 0x40  && nDataRate <= 0x4f ) //(59, 76)
+		{
+			is40MHz = 1;
+			isShortGI = 1;
+
+			//nDataRate = nDataRate - 60;
+		}
+		return MCS_DATA_RATE[is40MHz][isShortGI][nDataRate&0xf];
+	}
+}
+
+
+
+bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee)
+{
+	bool			retValue = false;
+	struct ieee80211_network* net = &ieee->current_network;
+	if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) ||
+		     (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) ||
+		     (memcmp(net->bssid, PCI_RALINK, 3)==0) ||
+		     (memcmp(net->bssid, EDIMAX_RALINK, 3)==0) ||
+		     (memcmp(net->bssid, AIRLINK_RALINK, 3)==0) ||
+		     (net->ralink_cap_exist))
+		retValue = true;
+	else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) ||
+		    (memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)||
+		    (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)||
+		    (memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) ||
+		    (net->broadcom_cap_exist))
+		  retValue = true;
+	else if(net->bssht.bdRT2RTAggregation)
+		retValue = true;
+	else
+		retValue = false;
+
+	return retValue;
+}
+
+/********************************************************************************************************************
+ *function:  This function returns peer IOT.
+ *   input:  struct ieee80211_device* 	ieee
+ *  output:  none
+ *  return:
+ *  notice:
+ * *****************************************************************************************************************/
+void HTIOTPeerDetermine(struct ieee80211_device* ieee)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	struct ieee80211_network* net = &ieee->current_network;
+	if(net->bssht.bdRT2RTAggregation)
+		pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK;
+	else if(net->broadcom_cap_exist)
+		pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
+	else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) ||
+			(memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)||
+			(memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)||
+			(memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) )
+		pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
+	else if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) ||
+			(memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) ||
+			(memcmp(net->bssid, PCI_RALINK, 3)==0) ||
+			(memcmp(net->bssid, EDIMAX_RALINK, 3)==0) ||
+			(memcmp(net->bssid, AIRLINK_RALINK, 3)==0) ||
+			 net->ralink_cap_exist)
+		pHTInfo->IOTPeer = HT_IOT_PEER_RALINK;
+	else if(net->atheros_cap_exist)
+		pHTInfo->IOTPeer = HT_IOT_PEER_ATHEROS;
+	else if(memcmp(net->bssid, CISCO_BROADCOM, 3)==0)
+		pHTInfo->IOTPeer = HT_IOT_PEER_CISCO;
+	else
+		pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN;
+
+	IEEE80211_DEBUG(IEEE80211_DL_IOT, "Joseph debug!! IOTPEER: %x\n", pHTInfo->IOTPeer);
+}
+/********************************************************************************************************************
+ *function:  Check whether driver should declare received rate up to MCS13 only since some chipset is not good
+ *	     at receiving MCS14~15 frame from some AP.
+ *   input:  struct ieee80211_device* 	ieee
+ *   	     u8 *			PeerMacAddr
+ *  output:  none
+ *  return:  return 1 if driver should declare MCS13 only(otherwise return 0)
+  * *****************************************************************************************************************/
+u8 HTIOTActIsDisableMCS14(struct ieee80211_device* ieee, u8* PeerMacAddr)
+{
+	u8 ret = 0;
+	return ret;
+ }
+
+
+/**
+* Function:	HTIOTActIsDisableMCS15
+*
+* Overview:	Check whether driver should declare capability of receving MCS15
+*
+* Input:
+*			PADAPTER		Adapter,
+*
+* Output:		None
+* Return:     	true if driver should disable MCS15
+* 2008.04.15	Emily
+*/
+bool HTIOTActIsDisableMCS15(struct ieee80211_device* ieee)
+{
+	bool retValue = false;
+
+#ifdef TODO
+	// Apply for 819u only
+#if (HAL_CODE_BASE==RTL8192)
+
+#if (DEV_BUS_TYPE == USB_INTERFACE)
+	// Alway disable MCS15 by Jerry Chang's request.by Emily, 2008.04.15
+	retValue = true;
+#elif (DEV_BUS_TYPE == PCI_INTERFACE)
+	// Enable MCS15 if the peer is Cisco AP. by Emily, 2008.05.12
+//	if(pBssDesc->bCiscoCapExist)
+//		retValue = false;
+//	else
+		retValue = false;
+#endif
+#endif
+#endif
+	// Jerry Chang suggest that 8190 1x2 does not need to disable MCS15
+
+	return retValue;
+}
+
+/**
+* Function:	HTIOTActIsDisableMCSTwoSpatialStream
+*
+* Overview:	Check whether driver should declare capability of receving All 2 ss packets
+*
+* Input:
+*			PADAPTER		Adapter,
+*
+* Output:		None
+* Return:     	true if driver should disable all two spatial stream packet
+* 2008.04.21	Emily
+*/
+bool HTIOTActIsDisableMCSTwoSpatialStream(struct ieee80211_device* ieee, u8 *PeerMacAddr)
+{
+	bool retValue = false;
+
+#ifdef TODO
+	// Apply for 819u only
+#endif
+	return retValue;
+}
+
+/********************************************************************************************************************
+ *function:  Check whether driver should disable EDCA turbo mode
+ *   input:  struct ieee80211_device* 	ieee
+ *   	     u8* 			PeerMacAddr
+ *  output:  none
+ *  return:  return 1 if driver should disable EDCA turbo mode(otherwise return 0)
+  * *****************************************************************************************************************/
+u8 HTIOTActIsDisableEDCATurbo(struct ieee80211_device* 	ieee, u8* PeerMacAddr)
+{
+	u8	retValue = false;	// default enable EDCA Turbo mode.
+	// Set specific EDCA parameter for different AP in DM handler.
+
+	return retValue;
+}
+
+/********************************************************************************************************************
+ *function:  Check whether we need to use OFDM to sned MGNT frame for broadcom AP
+ *   input:  struct ieee80211_network *network   //current network we live
+ *  output:  none
+ *  return:  return 1 if true
+  * *****************************************************************************************************************/
+u8 HTIOTActIsMgntUseCCK6M(struct ieee80211_network *network)
+{
+	u8	retValue = 0;
+
+	// 2008/01/25 MH Judeg if we need to use OFDM to sned MGNT frame for broadcom AP.
+	// 2008/01/28 MH We must prevent that we select null bssid to link.
+
+	if(network->broadcom_cap_exist)
+	{
+		retValue = 1;
+	}
+
+	return retValue;
+}
+
+u8 HTIOTActIsCCDFsync(u8* PeerMacAddr)
+{
+	u8	retValue = 0;
+	if(	(memcmp(PeerMacAddr, UNKNOWN_BORADCOM, 3)==0) ||
+		(memcmp(PeerMacAddr, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0) ||
+		(memcmp(PeerMacAddr, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3) ==0))
+	{
+		retValue = 1;
+	}
+
+	return retValue;
+}
+
+void HTResetIOTSetting(
+	PRT_HIGH_THROUGHPUT		pHTInfo
+)
+{
+	pHTInfo->IOTAction = 0;
+	pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN;
+}
+
+
+/********************************************************************************************************************
+ *function:  Construct Capablility Element in Beacon... if HTEnable is turned on
+ *   input:  struct ieee80211_device* 	ieee
+ *   	     u8* 			posHTCap //pointer to store Capability Ele
+ *   	     u8*			len //store length of CE
+ *   	     u8				IsEncrypt //whether encrypt, needed further
+ *  output:  none
+ *  return:  none
+ *  notice:  posHTCap can't be null and should be initialized before.
+  * *****************************************************************************************************************/
+void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u8* len, u8 IsEncrypt)
+{
+	PRT_HIGH_THROUGHPUT	pHT = ieee->pHTInfo;
+	PHT_CAPABILITY_ELE 	pCapELE = NULL;
+	//u8 bIsDeclareMCS13;
+
+	if ((posHTCap == NULL) || (pHT == NULL))
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "posHTCap or pHTInfo can't be null in HTConstructCapabilityElement()\n");
+		return;
+	}
+	memset(posHTCap, 0, *len);
+	if(pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC)
+	{
+		u8	EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};	// For 11n EWC definition, 2007.07.17, by Emily
+		memcpy(posHTCap, EWC11NHTCap, sizeof(EWC11NHTCap));
+		pCapELE = (PHT_CAPABILITY_ELE)&(posHTCap[4]);
+	}else
+	{
+		pCapELE = (PHT_CAPABILITY_ELE)posHTCap;
+	}
+
+
+	//HT capability info
+	pCapELE->AdvCoding 		= 0; // This feature is not supported now!!
+	if(ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
+	{
+		pCapELE->ChlWidth = 0;
+	}
+	else
+	{
+		pCapELE->ChlWidth = (pHT->bRegBW40MHz?1:0);
+	}
+
+//	pCapELE->ChlWidth 		= (pHT->bRegBW40MHz?1:0);
+	pCapELE->MimoPwrSave 		= pHT->SelfMimoPs;
+	pCapELE->GreenField		= 0; // This feature is not supported now!!
+	pCapELE->ShortGI20Mhz		= 1; // We can receive Short GI!!
+	pCapELE->ShortGI40Mhz		= 1; // We can receive Short GI!!
+	//DbgPrint("TX HT cap/info ele BW=%d SG20=%d SG40=%d\n\r",
+		//pCapELE->ChlWidth, pCapELE->ShortGI20Mhz, pCapELE->ShortGI40Mhz);
+	pCapELE->TxSTBC 		= 1;
+	pCapELE->RxSTBC 		= 0;
+	pCapELE->DelayBA		= 0;	// Do not support now!!
+	pCapELE->MaxAMSDUSize	= (MAX_RECEIVE_BUFFER_SIZE>=7935)?1:0;
+	pCapELE->DssCCk 		= ((pHT->bRegBW40MHz)?(pHT->bRegSuppCCK?1:0):0);
+	pCapELE->PSMP			= 0; // Do not support now!!
+	pCapELE->LSigTxopProtect	= 0; // Do not support now!!
+
+
+	//MAC HT parameters info
+	// TODO: Nedd to take care of this part
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "TX HT cap/info ele BW=%d MaxAMSDUSize:%d DssCCk:%d\n", pCapELE->ChlWidth, pCapELE->MaxAMSDUSize, pCapELE->DssCCk);
+
+	if( IsEncrypt)
+	{
+		pCapELE->MPDUDensity 	= 7; // 8us
+		pCapELE->MaxRxAMPDUFactor 	= 2; // 2 is for 32 K and 3 is 64K
+	}
+	else
+	{
+		pCapELE->MaxRxAMPDUFactor 	= 3; // 2 is for 32 K and 3 is 64K
+		pCapELE->MPDUDensity 	= 0; // no density
+	}
+
+	//Supported MCS set
+	memcpy(pCapELE->MCS, ieee->Regdot11HTOperationalRateSet, 16);
+	if(pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS15)
+		pCapELE->MCS[1] &= 0x7f;
+
+	if(pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS14)
+		pCapELE->MCS[1] &= 0xbf;
+
+	if(pHT->IOTAction & HT_IOT_ACT_DISABLE_ALL_2SS)
+		pCapELE->MCS[1] &= 0x00;
+
+	// 2008.06.12
+	// For RTL819X, if pairwisekey = wep/tkip, ap is ralink, we support only MCS0~7.
+	if(ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
+	{
+		int i;
+		for(i = 1; i< 16; i++)
+			pCapELE->MCS[i] = 0;
+	}
+
+	//Extended HT Capability Info
+	memset(&pCapELE->ExtHTCapInfo, 0, 2);
+
+
+	//TXBF Capabilities
+	memset(pCapELE->TxBFCap, 0, 4);
+
+	//Antenna Selection Capabilities
+	pCapELE->ASCap = 0;
+//add 2 to give space for element ID and len when construct frames
+	if(pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC)
+		*len = 30 + 2;
+	else
+		*len = 26 + 2;
+
+
+
+//	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_HT, posHTCap, *len -2);
+
+	//Print each field in detail. Driver should not print out this message by default
+//	HTDebugHTCapability(posHTCap, (u8*)"HTConstructCapability()");
+	return;
+
+}
+/********************************************************************************************************************
+ *function:  Construct  Information Element in Beacon... if HTEnable is turned on
+ *   input:  struct ieee80211_device* 	ieee
+ *   	     u8* 			posHTCap //pointer to store Information Ele
+ *   	     u8*			len   //store len of
+ *   	     u8				IsEncrypt //whether encrypt, needed further
+ *  output:  none
+ *  return:  none
+ *  notice:  posHTCap can't be null and be initialized before. only AP and IBSS sta should do this
+  * *****************************************************************************************************************/
+void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* len, u8 IsEncrypt)
+{
+	PRT_HIGH_THROUGHPUT	pHT = ieee->pHTInfo;
+	PHT_INFORMATION_ELE		pHTInfoEle = (PHT_INFORMATION_ELE)posHTInfo;
+	if ((posHTInfo == NULL) || (pHTInfoEle == NULL))
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "posHTInfo or pHTInfoEle can't be null in HTConstructInfoElement()\n");
+		return;
+	}
+
+	memset(posHTInfo, 0, *len);
+	if ( (ieee->iw_mode == IW_MODE_ADHOC) || (ieee->iw_mode == IW_MODE_MASTER)) //ap mode is not currently supported
+	{
+		pHTInfoEle->ControlChl 			= ieee->current_network.channel;
+		pHTInfoEle->ExtChlOffset 			= ((pHT->bRegBW40MHz == false)?HT_EXTCHNL_OFFSET_NO_EXT:
+											(ieee->current_network.channel<=6)?
+												HT_EXTCHNL_OFFSET_UPPER:HT_EXTCHNL_OFFSET_LOWER);
+		pHTInfoEle->RecommemdedTxWidth	= pHT->bRegBW40MHz;
+		pHTInfoEle->RIFS 					= 0;
+		pHTInfoEle->PSMPAccessOnly		= 0;
+		pHTInfoEle->SrvIntGranularity		= 0;
+		pHTInfoEle->OptMode				= pHT->CurrentOpMode;
+		pHTInfoEle->NonGFDevPresent		= 0;
+		pHTInfoEle->DualBeacon			= 0;
+		pHTInfoEle->SecondaryBeacon		= 0;
+		pHTInfoEle->LSigTxopProtectFull		= 0;
+		pHTInfoEle->PcoActive				= 0;
+		pHTInfoEle->PcoPhase				= 0;
+
+		memset(pHTInfoEle->BasicMSC, 0, 16);
+
+
+		*len = 22 + 2; //same above
+
+	}
+	else
+	{
+		//STA should not generate High Throughput Information Element
+		*len = 0;
+	}
+	//IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_HT, posHTInfo, *len - 2);
+	//HTDebugHTInfo(posHTInfo, "HTConstructInforElement");
+	return;
+}
+
+/*
+  *  According to experiment, Realtek AP to STA (based on rtl8190) may achieve best performance
+  *  if both STA and AP set limitation of aggregation size to 32K, that is, set AMPDU density to 2
+  *  (Ref: IEEE 11n specification). However, if Realtek STA associates to other AP, STA should set
+  *  limitation of aggregation size to 8K, otherwise, performance of traffic stream from STA to AP
+  *  will be much less than the traffic stream from AP to STA if both of the stream runs concurrently
+  *  at the same time.
+  *
+  *  Frame Format
+  *  Element ID		Length		OUI			Type1		Reserved
+  *  1 byte			1 byte		3 bytes		1 byte		1 byte
+  *
+  *  OUI 		= 0x00, 0xe0, 0x4c,
+  *  Type 	= 0x02
+  *  Reserved 	= 0x00
+  *
+  *  2007.8.21 by Emily
+*/
+/********************************************************************************************************************
+ *function:  Construct  Information Element in Beacon... in RT2RT condition
+ *   input:  struct ieee80211_device* 	ieee
+ *   	     u8* 			posRT2RTAgg //pointer to store Information Ele
+ *   	     u8*			len   //store len
+ *  output:  none
+ *  return:  none
+ *  notice:
+  * *****************************************************************************************************************/
+void HTConstructRT2RTAggElement(struct ieee80211_device* ieee, u8* posRT2RTAgg, u8* len)
+{
+	if (posRT2RTAgg == NULL) {
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "posRT2RTAgg can't be null in HTConstructRT2RTAggElement()\n");
+		return;
+	}
+	memset(posRT2RTAgg, 0, *len);
+	*posRT2RTAgg++ = 0x00;
+	*posRT2RTAgg++ = 0xe0;
+	*posRT2RTAgg++ = 0x4c;
+	*posRT2RTAgg++ = 0x02;
+	*posRT2RTAgg++ = 0x01;
+	*posRT2RTAgg = 0x10;//*posRT2RTAgg = 0x02;
+
+	if(ieee->bSupportRemoteWakeUp) {
+		*posRT2RTAgg |= 0x08;//RT_HT_CAP_USE_WOW;
+	}
+
+	*len = 6 + 2;
+	return;
+#ifdef TODO
+#if (HAL_CODE_BASE == RTL8192 && DEV_BUS_TYPE == USB_INTERFACE)
+	/*
+	//Emily. If it is required to Ask Realtek AP to send AMPDU during AES mode, enable this
+	   section of code.
+	if(IS_UNDER_11N_AES_MODE(Adapter))
+	{
+		posRT2RTAgg->Octet[5] |=RT_HT_CAP_USE_AMPDU;
+	}else
+	{
+		posRT2RTAgg->Octet[5] &= 0xfb;
+	}
+	*/
+
+#else
+	// Do Nothing
+#endif
+
+	posRT2RTAgg->Length = 6;
+#endif
+
+
+
+
+}
+
+
+/********************************************************************************************************************
+ *function:  Pick the right Rate Adaptive table to use
+ *   input:  struct ieee80211_device* 	ieee
+ *   	     u8* 			pOperateMCS //A pointer to MCS rate bitmap
+ *  return:  always we return true
+ *  notice:
+  * *****************************************************************************************************************/
+u8 HT_PickMCSRate(struct ieee80211_device* ieee, u8* pOperateMCS)
+{
+	u8					i;
+	if (pOperateMCS == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "pOperateMCS can't be null in HT_PickMCSRate()\n");
+		return false;
+	}
+
+	switch(ieee->mode)
+	{
+	case IEEE_A:
+	case IEEE_B:
+	case IEEE_G:
+			//legacy rate routine handled at selectedrate
+
+			//no MCS rate
+			for(i=0;i<=15;i++){
+				pOperateMCS[i] = 0;
+			}
+			break;
+
+	case IEEE_N_24G:	//assume CCK rate ok
+	case IEEE_N_5G:
+			// Legacy part we only use 6, 5.5,2,1 for N_24G and 6 for N_5G.
+			// Legacy part shall be handled at SelectRateSet().
+
+			//HT part
+			// TODO: may be different if we have different number of antenna
+			pOperateMCS[0] &=RATE_ADPT_1SS_MASK;	//support MCS 0~7
+			pOperateMCS[1] &=RATE_ADPT_2SS_MASK;
+			pOperateMCS[3] &=RATE_ADPT_MCS32_MASK;
+			break;
+
+	//should never reach here
+	default:
+
+			break;
+
+	}
+
+	return true;
+}
+
+/*
+*	Description:
+*		This function will get the highest speed rate in input MCS set.
+*
+*	/param 	Adapter			Pionter to Adapter entity
+*			pMCSRateSet		Pointer to MCS rate bitmap
+*			pMCSFilter		Pointer to MCS rate filter
+*
+*	/return	Highest MCS rate included in pMCSRateSet and filtered by pMCSFilter.
+*
+*/
+/********************************************************************************************************************
+ *function:  This function will get the highest speed rate in input MCS set.
+ *   input:  struct ieee80211_device* 	ieee
+ *   	     u8* 			pMCSRateSet //Pointer to MCS rate bitmap
+ *   	     u8*			pMCSFilter //Pointer to MCS rate filter
+ *  return:  Highest MCS rate included in pMCSRateSet and filtered by pMCSFilter
+ *  notice:
+  * *****************************************************************************************************************/
+u8 HTGetHighestMCSRate(struct ieee80211_device* ieee, u8* pMCSRateSet, u8* pMCSFilter)
+{
+	u8		i, j;
+	u8		bitMap;
+	u8		mcsRate = 0;
+	u8		availableMcsRate[16];
+	if (pMCSRateSet == NULL || pMCSFilter == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "pMCSRateSet or pMCSFilter can't be null in HTGetHighestMCSRate()\n");
+		return false;
+	}
+	for(i=0; i<16; i++)
+		availableMcsRate[i] = pMCSRateSet[i] & pMCSFilter[i];
+
+	for(i = 0; i < 16; i++)
+	{
+		if(availableMcsRate[i] != 0)
+			break;
+	}
+	if(i == 16)
+		return false;
+
+	for(i = 0; i < 16; i++)
+	{
+		if(availableMcsRate[i] != 0)
+		{
+			bitMap = availableMcsRate[i];
+			for(j = 0; j < 8; j++)
+			{
+				if((bitMap%2) != 0)
+				{
+					if(HTMcsToDataRate(ieee, (8*i+j)) > HTMcsToDataRate(ieee, mcsRate))
+						mcsRate = (8*i+j);
+				}
+				bitMap = bitMap>>1;
+			}
+		}
+	}
+	return (mcsRate|0x80);
+}
+
+
+
+/*
+**
+**1.Filter our operation rate set with AP's rate set
+**2.shall reference channel bandwidth, STBC, Antenna number
+**3.generate rate adative table for firmware
+**David 20060906
+**
+** \pHTSupportedCap: the connected STA's supported rate Capability element
+*/
+u8 HTFilterMCSRate( struct ieee80211_device* ieee, u8* pSupportMCS, u8* pOperateMCS)
+{
+
+	u8 i=0;
+
+	// filter out operational rate set not supported by AP, the lenth of it is 16
+	for(i=0;i<=15;i++){
+		pOperateMCS[i] = ieee->Regdot11HTOperationalRateSet[i]&pSupportMCS[i];
+	}
+
+
+	// TODO: adjust our operational rate set  according to our channel bandwidth, STBC and Antenna number
+
+	// TODO: fill suggested rate adaptive rate index and give firmware info using Tx command packet
+	// we also shall suggested the first start rate set according to our singal strength
+	HT_PickMCSRate(ieee, pOperateMCS);
+
+	// For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7.
+	if(ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
+		pOperateMCS[1] = 0;
+
+	//
+	// For RTL819X, we support only MCS0~15.
+	// And also, we do not know how to use MCS32 now.
+	//
+	for(i=2; i<=15; i++)
+		pOperateMCS[i] = 0;
+
+	return true;
+}
+void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH	Bandwidth, HT_EXTCHNL_OFFSET	Offset);
+void HTOnAssocRsp(struct ieee80211_device *ieee)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	PHT_CAPABILITY_ELE		pPeerHTCap = NULL;
+	PHT_INFORMATION_ELE		pPeerHTInfo = NULL;
+	u16	nMaxAMSDUSize = 0;
+	u8*	pMcsFilter = NULL;
+
+	static u8				EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};		// For 11n EWC definition, 2007.07.17, by Emily
+	static u8				EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34};	// For 11n EWC definition, 2007.07.17, by Emily
+
+	if( pHTInfo->bCurrentHTSupport == false )
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "<=== HTOnAssocRsp(): HT_DISABLE\n");
+		return;
+	}
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "===> HTOnAssocRsp_wq(): HT_ENABLE\n");
+//	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, pHTInfo->PeerHTCapBuf, sizeof(HT_CAPABILITY_ELE));
+//	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, pHTInfo->PeerHTInfoBuf, sizeof(HT_INFORMATION_ELE));
+
+//	HTDebugHTCapability(pHTInfo->PeerHTCapBuf,"HTOnAssocRsp_wq");
+//	HTDebugHTInfo(pHTInfo->PeerHTInfoBuf,"HTOnAssocRsp_wq");
+	//
+	if(!memcmp(pHTInfo->PeerHTCapBuf,EWC11NHTCap, sizeof(EWC11NHTCap)))
+		pPeerHTCap = (PHT_CAPABILITY_ELE)(&pHTInfo->PeerHTCapBuf[4]);
+	else
+		pPeerHTCap = (PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf);
+
+	if(!memcmp(pHTInfo->PeerHTInfoBuf, EWC11NHTInfo, sizeof(EWC11NHTInfo)))
+		pPeerHTInfo = (PHT_INFORMATION_ELE)(&pHTInfo->PeerHTInfoBuf[4]);
+	else
+		pPeerHTInfo = (PHT_INFORMATION_ELE)(pHTInfo->PeerHTInfoBuf);
+
+
+	////////////////////////////////////////////////////////
+	// Configurations:
+	////////////////////////////////////////////////////////
+	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_HT, pPeerHTCap, sizeof(HT_CAPABILITY_ELE));
+//	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_HT, pPeerHTInfo, sizeof(HT_INFORMATION_ELE));
+	// Config Supported Channel Width setting
+	//
+	HTSetConnectBwMode(ieee, (HT_CHANNEL_WIDTH)(pPeerHTCap->ChlWidth), (HT_EXTCHNL_OFFSET)(pPeerHTInfo->ExtChlOffset));
+
+//	if(pHTInfo->bCurBW40MHz == true)
+		pHTInfo->bCurTxBW40MHz = ((pPeerHTInfo->RecommemdedTxWidth == 1)?true:false);
+
+	//
+	// Update short GI/ long GI setting
+	//
+	// TODO:
+	pHTInfo->bCurShortGI20MHz=
+		((pHTInfo->bRegShortGI20MHz)?((pPeerHTCap->ShortGI20Mhz==1)?true:false):false);
+	pHTInfo->bCurShortGI40MHz=
+		((pHTInfo->bRegShortGI40MHz)?((pPeerHTCap->ShortGI40Mhz==1)?true:false):false);
+
+	//
+	// Config TX STBC setting
+	//
+	// TODO:
+
+	//
+	// Config DSSS/CCK  mode in 40MHz mode
+	//
+	// TODO:
+	pHTInfo->bCurSuppCCK =
+		((pHTInfo->bRegSuppCCK)?((pPeerHTCap->DssCCk==1)?true:false):false);
+
+
+	//
+	// Config and configure A-MSDU setting
+	//
+	pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support;
+
+	nMaxAMSDUSize = (pPeerHTCap->MaxAMSDUSize==0)?3839:7935;
+
+	if(pHTInfo->nAMSDU_MaxSize > nMaxAMSDUSize )
+		pHTInfo->nCurrent_AMSDU_MaxSize = nMaxAMSDUSize;
+	else
+		pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
+
+
+	//
+	// Config A-MPDU setting
+	//
+	pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable;
+
+	// <1> Decide AMPDU Factor
+
+	// By Emily
+	if(!pHTInfo->bRegRT2RTAggregation)
+	{
+		// Decide AMPDU Factor according to protocol handshake
+		if(pHTInfo->AMPDU_Factor > pPeerHTCap->MaxRxAMPDUFactor)
+			pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor;
+		else
+			pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
+
+	}else
+	{
+		// Set MPDU density to 2 to Realtek AP, and set it to 0 for others
+		// Replace MPDU factor declared in original association response frame format. 2007.08.20 by Emily
+		if (ieee->current_network.bssht.bdRT2RTAggregation)
+		{
+			if( ieee->pairwise_key_type != KEY_TYPE_NA)
+				// Realtek may set 32k in security mode and 64k for others
+				pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor;
+			else
+				pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_64K;
+		}else
+		{
+			if(pPeerHTCap->MaxRxAMPDUFactor < HT_AGG_SIZE_32K)
+				pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor;
+			else
+				pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_32K;
+		}
+	}
+
+	// <2> Set AMPDU Minimum MPDU Start Spacing
+	// 802.11n 3.0 section 9.7d.3
+	if(pHTInfo->MPDU_Density > pPeerHTCap->MPDUDensity)
+		pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
+	else
+		pHTInfo->CurrentMPDUDensity = pPeerHTCap->MPDUDensity;
+	if(ieee->pairwise_key_type != KEY_TYPE_NA )
+		pHTInfo->CurrentMPDUDensity 	= 7; // 8us
+	// Force TX AMSDU
+
+	// Lanhsin: mark for tmp to avoid deauth by ap from  s3
+	//if(memcmp(pMgntInfo->Bssid, NETGEAR834Bv2_BROADCOM, 3)==0)
+	if(0)
+		{
+
+			pHTInfo->bCurrentAMPDUEnable = false;
+			pHTInfo->ForcedAMSDUMode = HT_AGG_FORCE_ENABLE;
+			pHTInfo->ForcedAMSDUMaxSize = 7935;
+
+		pHTInfo->IOTAction |=  HT_IOT_ACT_TX_USE_AMSDU_8K;
+	}
+
+	// Rx Reorder Setting
+	pHTInfo->bCurRxReorderEnable = pHTInfo->bRegRxReorderEnable;
+
+	//
+	// Filter out unsupported HT rate for this AP
+	// Update RATR table
+	// This is only for 8190 ,8192 or later product which using firmware to handle rate adaptive mechanism.
+	//
+
+	// Handle Ralink AP bad MCS rate set condition. Joseph.
+	// This fix the bug of Ralink AP. This may be removed in the future.
+	if(pPeerHTCap->MCS[0] == 0)
+		pPeerHTCap->MCS[0] = 0xff;
+
+	HTFilterMCSRate(ieee, pPeerHTCap->MCS, ieee->dot11HTOperationalRateSet);
+
+	//
+	// Config MIMO Power Save setting
+	//
+	pHTInfo->PeerMimoPs = pPeerHTCap->MimoPwrSave;
+	if(pHTInfo->PeerMimoPs == MIMO_PS_STATIC)
+		pMcsFilter = MCS_FILTER_1SS;
+	else
+		pMcsFilter = MCS_FILTER_ALL;
+	//WB add for MCS8 bug
+//	pMcsFilter = MCS_FILTER_1SS;
+	ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, ieee->dot11HTOperationalRateSet, pMcsFilter);
+	ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate;
+
+	//
+	// Config current operation mode.
+	//
+	pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode;
+
+
+
+}
+
+void HTSetConnectBwModeCallback(struct ieee80211_device* ieee);
+/********************************************************************************************************************
+ *function:  initialize HT info(struct PRT_HIGH_THROUGHPUT)
+ *   input:  struct ieee80211_device* 	ieee
+ *  output:  none
+ *  return:  none
+ *  notice: This function is called when *  (1) MPInitialization Phase *  (2) Receiving of Deauthentication from AP
+********************************************************************************************************************/
+// TODO: Should this funciton be called when receiving of Disassociation?
+void HTInitializeHTInfo(struct ieee80211_device* ieee)
+{
+	PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
+
+	//
+	// These parameters will be reset when receiving deauthentication packet
+	//
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "===========>%s()\n", __FUNCTION__);
+	pHTInfo->bCurrentHTSupport = false;
+
+	// 40MHz channel support
+	pHTInfo->bCurBW40MHz = false;
+	pHTInfo->bCurTxBW40MHz = false;
+
+	// Short GI support
+	pHTInfo->bCurShortGI20MHz = false;
+	pHTInfo->bCurShortGI40MHz = false;
+	pHTInfo->bForcedShortGI = false;
+
+	// CCK rate support
+	// This flag is set to true to support CCK rate by default.
+	// It will be affected by "pHTInfo->bRegSuppCCK" and AP capabilities only when associate to
+	// 11N BSS.
+	pHTInfo->bCurSuppCCK = true;
+
+	// AMSDU related
+	pHTInfo->bCurrent_AMSDU_Support = false;
+	pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
+
+	// AMPUD related
+	pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
+	pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
+
+
+
+	// Initialize all of the parameters related to 11n
+	memset((void*)(&(pHTInfo->SelfHTCap)), 0, sizeof(pHTInfo->SelfHTCap));
+	memset((void*)(&(pHTInfo->SelfHTInfo)), 0, sizeof(pHTInfo->SelfHTInfo));
+	memset((void*)(&(pHTInfo->PeerHTCapBuf)), 0, sizeof(pHTInfo->PeerHTCapBuf));
+	memset((void*)(&(pHTInfo->PeerHTInfoBuf)), 0, sizeof(pHTInfo->PeerHTInfoBuf));
+
+	pHTInfo->bSwBwInProgress = false;
+	pHTInfo->ChnlOp = CHNLOP_NONE;
+
+	// Set default IEEE spec for Draft N
+	pHTInfo->ePeerHTSpecVer = HT_SPEC_VER_IEEE;
+
+	// Realtek proprietary aggregation mode
+	pHTInfo->bCurrentRT2RTAggregation = false;
+	pHTInfo->bCurrentRT2RTLongSlotTime = false;
+	pHTInfo->IOTPeer = 0;
+	pHTInfo->IOTAction = 0;
+
+	//MCS rate initialized here
+	{
+		u8* RegHTSuppRateSets = &(ieee->RegHTSuppRateSet[0]);
+		RegHTSuppRateSets[0] = 0xFF;	//support MCS 0~7
+		RegHTSuppRateSets[1] = 0xFF;	//support MCS 8~15
+		RegHTSuppRateSets[4] = 0x01;	//support MCS 32
+	}
+}
+/********************************************************************************************************************
+ *function:  initialize Bss HT structure(struct PBSS_HT)
+ *   input:  PBSS_HT pBssHT //to be initialized
+ *  output:  none
+ *  return:  none
+ *  notice: This function is called when initialize network structure
+********************************************************************************************************************/
+void HTInitializeBssDesc(PBSS_HT pBssHT)
+{
+
+	pBssHT->bdSupportHT = false;
+	memset(pBssHT->bdHTCapBuf, 0, sizeof(pBssHT->bdHTCapBuf));
+	pBssHT->bdHTCapLen = 0;
+	memset(pBssHT->bdHTInfoBuf, 0, sizeof(pBssHT->bdHTInfoBuf));
+	pBssHT->bdHTInfoLen = 0;
+
+	pBssHT->bdHTSpecVer= HT_SPEC_VER_IEEE;
+
+	pBssHT->bdRT2RTAggregation = false;
+	pBssHT->bdRT2RTLongSlotTime = false;
+}
+/********************************************************************************************************************
+ *function:  initialize Bss HT structure(struct PBSS_HT)
+ *   input:  struct ieee80211_device 	*ieee
+ *   	     struct ieee80211_network 	*pNetwork //usually current network we are live in
+ *  output:  none
+ *  return:  none
+ *  notice: This function should ONLY be called before association
+********************************************************************************************************************/
+void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, 	struct ieee80211_network * pNetwork)
+{
+	PRT_HIGH_THROUGHPUT		pHTInfo = ieee->pHTInfo;
+//	u16						nMaxAMSDUSize;
+//	PHT_CAPABILITY_ELE		pPeerHTCap = (PHT_CAPABILITY_ELE)pNetwork->bssht.bdHTCapBuf;
+//	PHT_INFORMATION_ELE		pPeerHTInfo = (PHT_INFORMATION_ELE)pNetwork->bssht.bdHTInfoBuf;
+//	u8*	pMcsFilter;
+	u8	bIOTAction = 0;
+
+	//
+	//  Save Peer Setting before Association
+	//
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "==============>%s()\n", __FUNCTION__);
+	/*unmark bEnableHT flag here is the same reason why unmarked in function ieee80211_softmac_new_net. WB 2008.09.10*/
+//	if( pHTInfo->bEnableHT &&  pNetwork->bssht.bdSupportHT)
+	if (pNetwork->bssht.bdSupportHT)
+	{
+		pHTInfo->bCurrentHTSupport = true;
+		pHTInfo->ePeerHTSpecVer = pNetwork->bssht.bdHTSpecVer;
+
+		// Save HTCap and HTInfo information Element
+		if(pNetwork->bssht.bdHTCapLen > 0 && 	pNetwork->bssht.bdHTCapLen <= sizeof(pHTInfo->PeerHTCapBuf))
+			memcpy(pHTInfo->PeerHTCapBuf, pNetwork->bssht.bdHTCapBuf, pNetwork->bssht.bdHTCapLen);
+
+		if(pNetwork->bssht.bdHTInfoLen > 0 && pNetwork->bssht.bdHTInfoLen <= sizeof(pHTInfo->PeerHTInfoBuf))
+			memcpy(pHTInfo->PeerHTInfoBuf, pNetwork->bssht.bdHTInfoBuf, pNetwork->bssht.bdHTInfoLen);
+
+		// Check whether RT to RT aggregation mode is enabled
+		if(pHTInfo->bRegRT2RTAggregation)
+		{
+			pHTInfo->bCurrentRT2RTAggregation = pNetwork->bssht.bdRT2RTAggregation;
+			pHTInfo->bCurrentRT2RTLongSlotTime = pNetwork->bssht.bdRT2RTLongSlotTime;
+		}
+		else
+		{
+			pHTInfo->bCurrentRT2RTAggregation = false;
+			pHTInfo->bCurrentRT2RTLongSlotTime = false;
+		}
+
+		// Determine the IOT Peer Vendor.
+		HTIOTPeerDetermine(ieee);
+
+		// Decide IOT Action
+		// Must be called after the parameter of pHTInfo->bCurrentRT2RTAggregation is decided
+		pHTInfo->IOTAction = 0;
+		bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid);
+		if(bIOTAction)
+			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS14;
+
+		bIOTAction = HTIOTActIsDisableMCS15(ieee);
+		if(bIOTAction)
+			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS15;
+
+		bIOTAction = HTIOTActIsDisableMCSTwoSpatialStream(ieee, pNetwork->bssid);
+		if(bIOTAction)
+			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_ALL_2SS;
+
+
+		bIOTAction = HTIOTActIsDisableEDCATurbo(ieee, pNetwork->bssid);
+		if(bIOTAction)
+			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_EDCA_TURBO;
+
+		bIOTAction = HTIOTActIsMgntUseCCK6M(pNetwork);
+		if(bIOTAction)
+			pHTInfo->IOTAction |= HT_IOT_ACT_MGNT_USE_CCK_6M;
+
+		bIOTAction = HTIOTActIsCCDFsync(pNetwork->bssid);
+		if(bIOTAction)
+			pHTInfo->IOTAction |= HT_IOT_ACT_CDD_FSYNC;
+
+
+	}
+	else
+	{
+		pHTInfo->bCurrentHTSupport = false;
+		pHTInfo->bCurrentRT2RTAggregation = false;
+		pHTInfo->bCurrentRT2RTLongSlotTime = false;
+
+		pHTInfo->IOTAction = 0;
+	}
+
+}
+
+void HTUpdateSelfAndPeerSetting(struct ieee80211_device* ieee, 	struct ieee80211_network * pNetwork)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+//	PHT_CAPABILITY_ELE		pPeerHTCap = (PHT_CAPABILITY_ELE)pNetwork->bssht.bdHTCapBuf;
+	PHT_INFORMATION_ELE		pPeerHTInfo = (PHT_INFORMATION_ELE)pNetwork->bssht.bdHTInfoBuf;
+
+	if(pHTInfo->bCurrentHTSupport)
+	{
+		//
+		// Config current operation mode.
+		//
+		if(pNetwork->bssht.bdHTInfoLen != 0)
+			pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode;
+
+		//
+		// <TODO: Config according to OBSS non-HT STA present!!>
+		//
+	}
+}
+
+void HTUseDefaultSetting(struct ieee80211_device* ieee)
+{
+	PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
+//	u8	regBwOpMode;
+
+	if(pHTInfo->bEnableHT)
+	{
+		pHTInfo->bCurrentHTSupport = true;
+
+		pHTInfo->bCurSuppCCK = pHTInfo->bRegSuppCCK;
+
+		pHTInfo->bCurBW40MHz = pHTInfo->bRegBW40MHz;
+
+		pHTInfo->bCurShortGI20MHz= pHTInfo->bRegShortGI20MHz;
+
+		pHTInfo->bCurShortGI40MHz= pHTInfo->bRegShortGI40MHz;
+
+		pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support;
+
+		pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
+
+		pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable;
+
+		pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
+
+		pHTInfo->CurrentMPDUDensity = pHTInfo->CurrentMPDUDensity;
+
+		// Set BWOpMode register
+
+		//update RATR index0
+		HTFilterMCSRate(ieee, ieee->Regdot11HTOperationalRateSet, ieee->dot11HTOperationalRateSet);
+	//function below is not implemented at all. WB
+#ifdef TODO
+		Adapter->HalFunc.InitHalRATRTableHandler( Adapter, &pMgntInfo->dot11OperationalRateSet, pMgntInfo->dot11HTOperationalRateSet);
+#endif
+		ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, ieee->dot11HTOperationalRateSet, MCS_FILTER_ALL);
+		ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate;
+
+	}
+	else
+	{
+		pHTInfo->bCurrentHTSupport = false;
+	}
+	return;
+}
+/********************************************************************************************************************
+ *function:  check whether HT control field exists
+ *   input:  struct ieee80211_device 	*ieee
+ *   	     u8*			pFrame //coming skb->data
+ *  output:  none
+ *  return:  return true if HT control field exists(false otherwise)
+ *  notice:
+********************************************************************************************************************/
+u8 HTCCheck(struct ieee80211_device* ieee, u8*	pFrame)
+{
+	if(ieee->pHTInfo->bCurrentHTSupport)
+	{
+		if( (IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1)
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "HT CONTROL FILED EXIST!!\n");
+			return true;
+		}
+	}
+	return false;
+}
+
+//
+// This function set bandwidth mode in protocol layer.
+//
+void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH	Bandwidth, HT_EXTCHNL_OFFSET	Offset)
+{
+	PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
+//	u32 flags = 0;
+
+	if(pHTInfo->bRegBW40MHz == false)
+		return;
+
+
+
+	// To reduce dummy operation
+//	if((pHTInfo->bCurBW40MHz==false && Bandwidth==HT_CHANNEL_WIDTH_20) ||
+//	   (pHTInfo->bCurBW40MHz==true && Bandwidth==HT_CHANNEL_WIDTH_20_40 && Offset==pHTInfo->CurSTAExtChnlOffset))
+//		return;
+
+//	spin_lock_irqsave(&(ieee->bw_spinlock), flags);
+	if(pHTInfo->bSwBwInProgress) {
+//		spin_unlock_irqrestore(&(ieee->bw_spinlock), flags);
+		return;
+	}
+	//if in half N mode, set to 20M bandwidth please 09.08.2008 WB.
+	if(Bandwidth==HT_CHANNEL_WIDTH_20_40 && (!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)))
+	 {
+			// Handle Illegal extention channel offset!!
+		if(ieee->current_network.channel<2 && Offset==HT_EXTCHNL_OFFSET_LOWER)
+			Offset = HT_EXTCHNL_OFFSET_NO_EXT;
+		if(Offset==HT_EXTCHNL_OFFSET_UPPER || Offset==HT_EXTCHNL_OFFSET_LOWER) {
+			pHTInfo->bCurBW40MHz = true;
+			pHTInfo->CurSTAExtChnlOffset = Offset;
+		} else {
+			pHTInfo->bCurBW40MHz = false;
+			pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT;
+		}
+	} else {
+		pHTInfo->bCurBW40MHz = false;
+		pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT;
+	}
+
+	pHTInfo->bSwBwInProgress = true;
+
+	// TODO: 2007.7.13 by Emily Wait 2000ms  in order to garantee that switching
+	//   bandwidth is executed after scan is finished. It is a temporal solution
+	//   because software should ganrantee the last operation of switching bandwidth
+	//   is executed properlly.
+	HTSetConnectBwModeCallback(ieee);
+
+//	spin_unlock_irqrestore(&(ieee->bw_spinlock), flags);
+}
+
+void HTSetConnectBwModeCallback(struct ieee80211_device* ieee)
+{
+	PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
+
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "======>%s()\n", __FUNCTION__);
+
+	if(pHTInfo->bCurBW40MHz)
+	{
+		if(pHTInfo->CurSTAExtChnlOffset==HT_EXTCHNL_OFFSET_UPPER)
+			ieee->set_chan(ieee->dev, ieee->current_network.channel+2);
+		else if(pHTInfo->CurSTAExtChnlOffset==HT_EXTCHNL_OFFSET_LOWER)
+			ieee->set_chan(ieee->dev, ieee->current_network.channel-2);
+		else
+			ieee->set_chan(ieee->dev, ieee->current_network.channel);
+
+		ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20_40, pHTInfo->CurSTAExtChnlOffset);
+	} else {
+		ieee->set_chan(ieee->dev, ieee->current_network.channel);
+		ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+	}
+
+	pHTInfo->bSwBwInProgress = false;
+}
+
+EXPORT_SYMBOL(HTUpdateSelfAndPeerSetting);
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_Qos.h b/drivers/staging/rtl8192u/ieee80211/rtl819x_Qos.h
new file mode 100644
index 0000000..13b1e5c
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_Qos.h
@@ -0,0 +1,583 @@
+#ifndef __INC_QOS_TYPE_H
+#define __INC_QOS_TYPE_H
+
+//#include "EndianFree.h"
+#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 BIT8                    0x00000100
+#define BIT9                    0x00000200
+#define BIT10                   0x00000400
+#define BIT11                   0x00000800
+#define BIT12                   0x00001000
+#define BIT13                   0x00002000
+#define BIT14                   0x00004000
+#define BIT15                   0x00008000
+#define BIT16                   0x00010000
+#define BIT17                   0x00020000
+#define BIT18                   0x00040000
+#define BIT19                   0x00080000
+#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_WMMELE_LENGTH	64
+
+//
+// QoS mode.
+// enum 0, 1, 2, 4: since we can use the OR(|) operation.
+//
+// QOS_MODE is redefined for enum can't be ++, | under C++ compiler, 2006.05.17, by rcnjko.
+//typedef	enum _QOS_MODE{
+//	QOS_DISABLE		= 0,
+//	QOS_WMM			= 1,
+//	QOS_EDCA			= 2,
+//	QOS_HCCA			= 4,
+//}QOS_MODE,*PQOS_MODE;
+//
+typedef u32 QOS_MODE, *PQOS_MODE;
+#define QOS_DISABLE		0
+#define QOS_WMM			1
+#define QOS_WMMSA		2
+#define QOS_EDCA		4
+#define QOS_HCCA		8
+#define QOS_WMM_UAPSD		16   //WMM Power Save, 2006-06-14 Isaiah
+
+#define AC_PARAM_SIZE	4
+#define WMM_PARAM_ELE_BODY_LEN	18
+
+//
+// QoS ACK Policy Field Values
+// Ref: WMM spec 2.1.6: QoS Control Field, p.10.
+//
+typedef	enum _ACK_POLICY{
+	eAckPlc0_ACK		= 0x00,
+	eAckPlc1_NoACK		= 0x01,
+}ACK_POLICY,*PACK_POLICY;
+
+#define WMM_PARAM_ELEMENT_SIZE	(8+(4*AC_PARAM_SIZE))
+
+//
+// QoS Control Field
+// Ref:
+//	1. WMM spec 2.1.6: QoS Control Field, p.9.
+//	2. 802.11e/D13.0 7.1.3.5, p.26.
+//
+typedef	union _QOS_CTRL_FIELD{
+	u8	charData[2];
+	u16	shortData;
+
+	// WMM spec
+	struct
+	{
+		u8		UP:3;
+		u8		usRsvd1:1;
+		u8		EOSP:1;
+		u8		AckPolicy:2;
+		u8		usRsvd2:1;
+		u8		ucRsvdByte;
+	}WMM;
+
+	// 802.11e: QoS data type frame sent by non-AP QSTAs.
+	struct
+	{
+		u8		TID:4;
+		u8		bIsQsize:1;// 0: BIT[8:15] is TXOP Duration Requested, 1: BIT[8:15] is Queue Size.
+		u8		AckPolicy:2;
+		u8		usRsvd:1;
+		u8		TxopOrQsize;	// (BIT4=0)TXOP Duration Requested or (BIT4=1)Queue Size.
+	}BySta;
+
+	// 802.11e: QoS data, QoS Null, and QoS Data+CF-Ack frames sent by HC.
+	struct
+	{
+		u8		TID:4;
+		u8		EOSP:1;
+		u8		AckPolicy:2;
+		u8		usRsvd:1;
+		u8		PSBufState;		// QAP PS Buffer State.
+	}ByHc_Data;
+
+	// 802.11e: QoS (+) CF-Poll frames sent by HC.
+	struct
+	{
+		u8		TID:4;
+		u8		EOSP:1;
+		u8		AckPolicy:2;
+		u8		usRsvd:1;
+		u8		TxopLimit;		// TXOP Limit.
+	}ByHc_CFP;
+
+}QOS_CTRL_FIELD, *PQOS_CTRL_FIELD;
+
+
+//
+// QoS Info Field
+// Ref:
+//	1. WMM spec 2.2.1: WME Information Element, p.11.
+//	2. 8185 QoS code: QOS_INFO [def. in QoS_mp.h]
+//
+typedef	union _QOS_INFO_FIELD{
+	u8	charData;
+
+	struct
+	{
+		u8		ucParameterSetCount:4;
+		u8		ucReserved:4;
+	}WMM;
+
+	struct
+	{
+		//Ref WMM_Specification_1-1.pdf, 2006-06-13 Isaiah
+		u8		ucAC_VO_UAPSD:1;
+		u8		ucAC_VI_UAPSD:1;
+		u8		ucAC_BE_UAPSD:1;
+		u8		ucAC_BK_UAPSD:1;
+		u8		ucReserved1:1;
+		u8		ucMaxSPLen:2;
+		u8		ucReserved2:1;
+
+	}ByWmmPsSta;
+
+	struct
+	{
+		//Ref WMM_Specification_1-1.pdf, 2006-06-13 Isaiah
+		u8		ucParameterSetCount:4;
+		u8		ucReserved:3;
+		u8		ucApUapsd:1;
+	}ByWmmPsAp;
+
+	struct
+	{
+		u8		ucAC3_UAPSD:1;
+		u8		ucAC2_UAPSD:1;
+		u8		ucAC1_UAPSD:1;
+		u8		ucAC0_UAPSD:1;
+		u8		ucQAck:1;
+		u8		ucMaxSPLen:2;
+		u8		ucMoreDataAck:1;
+	} By11eSta;
+
+	struct
+	{
+		u8		ucParameterSetCount:4;
+		u8		ucQAck:1;
+		u8		ucQueueReq:1;
+		u8		ucTXOPReq:1;
+		u8		ucReserved:1;
+	} By11eAp;
+
+	struct
+	{
+		u8		ucReserved1:4;
+		u8		ucQAck:1;
+		u8		ucReserved2:2;
+		u8		ucMoreDataAck:1;
+	} ByWmmsaSta;
+
+	struct
+	{
+		u8		ucReserved1:4;
+		u8		ucQAck:1;
+		u8		ucQueueReq:1;
+		u8		ucTXOPReq:1;
+		u8		ucReserved2:1;
+	} ByWmmsaAp;
+
+	struct
+	{
+		u8		ucAC3_UAPSD:1;
+		u8		ucAC2_UAPSD:1;
+		u8		ucAC1_UAPSD:1;
+		u8		ucAC0_UAPSD:1;
+		u8		ucQAck:1;
+		u8		ucMaxSPLen:2;
+		u8		ucMoreDataAck:1;
+	} ByAllSta;
+
+	struct
+	{
+		u8		ucParameterSetCount:4;
+		u8		ucQAck:1;
+		u8		ucQueueReq:1;
+		u8		ucTXOPReq:1;
+		u8		ucApUapsd:1;
+	} ByAllAp;
+
+}QOS_INFO_FIELD, *PQOS_INFO_FIELD;
+
+
+//
+// ACI to AC coding.
+// Ref: WMM spec 2.2.2: WME Parameter Element, p.13.
+//
+// AC_CODING is redefined for enum can't be ++, | under C++ compiler, 2006.05.17, by rcnjko.
+//typedef	enum _AC_CODING{
+//	AC0_BE	= 0,		// ACI: 0x00	// Best Effort
+//	AC1_BK	= 1,		// ACI: 0x01	// Background
+//	AC2_VI	= 2,		// ACI: 0x10	// Video
+//	AC3_VO	= 3,		// ACI: 0x11	// Voice
+//	AC_MAX = 4,		// Max: define total number; Should not to be used as a real enum.
+//}AC_CODING,*PAC_CODING;
+//
+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.
+
+//
+// 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;
+
+//
+// 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;
+
+//
+// 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;
+
+
+
+//
+// QoS element subtype
+//
+typedef	enum _QOS_ELE_SUBTYPE{
+	QOSELE_TYPE_INFO	= 0x00,		// 0x00: Information element
+	QOSELE_TYPE_PARAM	= 0x01,		// 0x01: parameter element
+}QOS_ELE_SUBTYPE,*PQOS_ELE_SUBTYPE;
+
+
+//
+// Direction Field Values.
+// Ref: WMM spec 2.2.11: WME TSPEC Element, p.18.
+//
+typedef	enum _DIRECTION_VALUE{
+	DIR_UP			= 0,		// 0x00	// UpLink
+	DIR_DOWN		= 1,		// 0x01	// DownLink
+	DIR_DIRECT		= 2,		// 0x10	// DirectLink
+	DIR_BI_DIR		= 3,		// 0x11	// Bi-Direction
+}DIRECTION_VALUE,*PDIRECTION_VALUE;
+
+
+//
+// TS Info field in WMM TSPEC Element.
+// Ref:
+//	1. WMM spec 2.2.11: WME TSPEC Element, p.18.
+//	2. 8185 QoS code: QOS_TSINFO [def. in QoS_mp.h]
+//
+typedef union _QOS_TSINFO{
+	u8		charData[3];
+	struct {
+		u8		ucTrafficType:1;			//WMM is reserved
+		u8		ucTSID:4;
+		u8		ucDirection:2;
+		u8		ucAccessPolicy:2;	//WMM: bit8=0, bit7=1
+		u8		ucAggregation:1;		//WMM is reserved
+		u8		ucPSB:1;				//WMMSA is APSD
+		u8		ucUP:3;
+		u8		ucTSInfoAckPolicy:2;		//WMM is reserved
+		u8		ucSchedule:1;			//WMM is reserved
+		u8		ucReserved:7;
+	}field;
+}QOS_TSINFO, *PQOS_TSINFO;
+
+//
+// WMM TSPEC Body.
+// Ref: WMM spec 2.2.11: WME TSPEC Element, p.16.
+//
+typedef union _TSPEC_BODY{
+	u8		charData[55];
+
+	struct
+	{
+		QOS_TSINFO	TSInfo;	//u8	TSInfo[3];
+		u16	NominalMSDUsize;
+		u16	MaxMSDUsize;
+		u32	MinServiceItv;
+		u32	MaxServiceItv;
+		u32	InactivityItv;
+		u32	SuspenItv;
+		u32	ServiceStartTime;
+		u32	MinDataRate;
+		u32	MeanDataRate;
+		u32	PeakDataRate;
+		u32	MaxBurstSize;
+		u32	DelayBound;
+		u32	MinPhyRate;
+		u16	SurplusBandwidthAllowance;
+		u16	MediumTime;
+	} f;	// Field
+}TSPEC_BODY, *PTSPEC_BODY;
+
+
+//
+// WMM TSPEC Element.
+// Ref: WMM spec 2.2.11: WME TSPEC Element, p.16.
+//
+typedef struct _WMM_TSPEC{
+	u8		ID;
+	u8		Length;
+	u8		OUI[3];
+	u8		OUI_Type;
+	u8		OUI_SubType;
+	u8		Version;
+	TSPEC_BODY	Body;
+} WMM_TSPEC, *PWMM_TSPEC;
+
+//
+// ACM implementation method.
+// Annie, 2005-12-13.
+//
+typedef	enum _ACM_METHOD{
+	eAcmWay0_SwAndHw		= 0,		// By SW and HW.
+	eAcmWay1_HW			= 1,		// By HW.
+	eAcmWay2_SW			= 2,		// By SW.
+}ACM_METHOD,*PACM_METHOD;
+
+
+typedef struct _ACM{
+//	u8		RegEnableACM;
+	u64		UsedTime;
+	u64		MediumTime;
+	u8		HwAcmCtl;	// TRUE: UsedTime exceed => Do NOT USE this AC. It wll be written to ACM_CONTROL(0xBF BIT 0/1/2 in 8185B).
+}ACM, *PACM;
+
+typedef	u8		AC_UAPSD, *PAC_UAPSD;
+
+#define	GET_VO_UAPSD(_apsd) ((_apsd) & BIT0)
+#define	SET_VO_UAPSD(_apsd) ((_apsd) |= BIT0)
+
+#define	GET_VI_UAPSD(_apsd) ((_apsd) & BIT1)
+#define	SET_VI_UAPSD(_apsd) ((_apsd) |= BIT1)
+
+#define	GET_BK_UAPSD(_apsd) ((_apsd) & BIT2)
+#define	SET_BK_UAPSD(_apsd) ((_apsd) |= BIT2)
+
+#define	GET_BE_UAPSD(_apsd) ((_apsd) & BIT3)
+#define	SET_BE_UAPSD(_apsd) ((_apsd) |= BIT3)
+
+
+//typedef struct _TCLASS{
+// TODO
+//} TCLASS, *PTCLASS;
+typedef union _QOS_TCLAS{
+
+	struct _TYPE_GENERAL{
+		u8		Priority;
+		u8 		ClassifierType;
+		u8 		Mask;
+	} TYPE_GENERAL;
+
+	struct _TYPE0_ETH{
+		u8		Priority;
+		u8 		ClassifierType;
+		u8 		Mask;
+		u8		SrcAddr[6];
+		u8		DstAddr[6];
+		u16		Type;
+	} TYPE0_ETH;
+
+	struct _TYPE1_IPV4{
+		u8		Priority;
+		u8 		ClassifierType;
+		u8 		Mask;
+		u8 		Version;
+		u8		SrcIP[4];
+		u8		DstIP[4];
+		u16		SrcPort;
+		u16		DstPort;
+		u8		DSCP;
+		u8		Protocol;
+		u8		Reserved;
+	} TYPE1_IPV4;
+
+	struct _TYPE1_IPV6{
+		u8		Priority;
+		u8 		ClassifierType;
+		u8 		Mask;
+		u8 		Version;
+		u8		SrcIP[16];
+		u8		DstIP[16];
+		u16		SrcPort;
+		u16		DstPort;
+		u8		FlowLabel[3];
+	} TYPE1_IPV6;
+
+	struct _TYPE2_8021Q{
+		u8		Priority;
+		u8 		ClassifierType;
+		u8 		Mask;
+		u16		TagType;
+	} TYPE2_8021Q;
+} QOS_TCLAS, *PQOS_TCLAS;
+
+//typedef struct _WMM_TSTREAM{
+//
+//- TSPEC
+//- AC (which to mapping)
+//} WMM_TSTREAM, *PWMM_TSTREAM;
+typedef struct _QOS_TSTREAM{
+	u8			AC;
+	WMM_TSPEC		TSpec;
+	QOS_TCLAS		TClass;
+} QOS_TSTREAM, *PQOS_TSTREAM;
+
+//typedef struct _U_APSD{
+//- TriggerEnable [4]
+//- MaxSPLength
+//- HighestAcBuffered
+//} U_APSD, *PU_APSD;
+
+//joseph TODO:
+//	UAPSD function should be implemented by 2 data structure
+//	"Qos control field" and "Qos info field"
+//typedef struct _QOS_UAPSD{
+//	u8			bTriggerEnable[4];
+//	u8 			MaxSPLength;
+//	u8			HighestBufAC;
+//} QOS_UAPSD, *PQOS_APSD;
+
+//----------------------------------------------------------------------------
+//      802.11 Management frame Status Code field
+//----------------------------------------------------------------------------
+typedef struct _OCTET_STRING{
+	u8        	*Octet;
+	u16             Length;
+}OCTET_STRING, *POCTET_STRING;
+//
+// STA QoS data.
+// Ref: DOT11_QOS in 8185 code. [def. in QoS_mp.h]
+//
+typedef struct _STA_QOS{
+	//DECLARE_RT_OBJECT(STA_QOS);
+	u8				WMMIEBuf[MAX_WMMELE_LENGTH];
+	u8*				WMMIE;
+
+	// Part 1. Self QoS Mode.
+	QOS_MODE			QosCapability; //QoS Capability, 2006-06-14 Isaiah
+	QOS_MODE			CurrentQosMode;
+
+	// For WMM Power Save Mode :
+	// ACs are trigger/delivery enabled or legacy power save enabled. 2006-06-13 Isaiah
+	AC_UAPSD			b4ac_Uapsd;  //VoUapsd(bit0), ViUapsd(bit1),  BkUapsd(bit2), BeUapsd(bit3),
+	AC_UAPSD			Curr4acUapsd;
+	u8				bInServicePeriod;
+	u8				MaxSPLength;
+	int 				NumBcnBeforeTrigger;
+
+	// Part 2. EDCA Parameter (perAC)
+	u8 *				pWMMInfoEle;
+	u8				WMMParamEle[WMM_PARAM_ELEMENT_SIZE];
+	u8				WMMPELength;
+
+	// <Bruce_Note>
+	//2 ToDo: remove the Qos Info Field and replace it by the above WMM Info element.
+	// By Bruce, 2008-01-30.
+	// Part 2. EDCA Parameter (perAC)
+	QOS_INFO_FIELD			QosInfoField_STA; 	// Maintained by STA
+	QOS_INFO_FIELD			QosInfoField_AP;	// Retrieved from AP
+
+	AC_PARAM			CurAcParameters[4];
+
+	// Part 3. ACM
+	ACM				acm[4];
+	ACM_METHOD			AcmMethod;
+
+	// Part 4. Per TID (Part 5: TCLASS will be described by TStream)
+	QOS_TSTREAM			TStream[16];
+	WMM_TSPEC			TSpec;
+
+	u32				QBssWirelessMode;
+
+	// No Ack Setting
+	u8				bNoAck;
+
+	// Enable/Disable Rx immediate BA capability.
+	u8				bEnableRxImmBA;
+
+}STA_QOS, *PSTA_QOS;
+
+//
+// BSS QOS data.
+// Ref: BssDscr in 8185 code. [def. in BssDscr.h]
+//
+typedef struct _BSS_QOS{
+	QOS_MODE		bdQoSMode;
+
+	u8			bdWMMIEBuf[MAX_WMMELE_LENGTH];
+	u8*		bdWMMIE;
+
+	QOS_ELE_SUBTYPE		EleSubType;
+
+	u8 *			pWMMInfoEle;
+	u8 *			pWMMParamEle;
+
+	QOS_INFO_FIELD		QosInfoField;
+	AC_PARAM		AcParameter[4];
+}BSS_QOS, *PBSS_QOS;
+
+
+//
+// Ref: sQoSCtlLng and QoSCtl definition in 8185 QoS code.
+//#define QoSCtl   ((	(Adapter->bRegQoS) && (Adapter->dot11QoS.QoSMode &(QOS_EDCA|QOS_HCCA))	  )  ?sQoSCtlLng:0)
+//
+#define sQoSCtlLng			2
+#define	QOS_CTRL_LEN(_QosMode)		((_QosMode > QOS_DISABLE)? sQoSCtlLng : 0)
+
+
+//Added by joseph
+//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
+//#define UP2AC(up)			((up<3)?((up==0)?1:0):(up>>1))
+#define IsACValid(ac)			((ac<=7 )?true:false )
+
+#endif // #ifndef __INC_QOS_TYPE_H
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_TS.h b/drivers/staging/rtl8192u/ieee80211/rtl819x_TS.h
new file mode 100644
index 0000000..baaac21
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_TS.h
@@ -0,0 +1,56 @@
+#ifndef _TSTYPE_H_
+#define _TSTYPE_H_
+#include "rtl819x_Qos.h"
+#define TS_SETUP_TIMEOUT	60  // In millisecond
+#define TS_INACT_TIMEOUT	60
+#define TS_ADDBA_DELAY		60
+
+#define TOTAL_TS_NUM		16
+#define TCLAS_NUM		4
+
+// This define the Tx/Rx directions
+typedef enum _TR_SELECT {
+	TX_DIR = 0,
+	RX_DIR = 1,
+} TR_SELECT, *PTR_SELECT;
+
+typedef struct _TS_COMMON_INFO{
+	struct list_head		List;
+	struct timer_list		SetupTimer;
+	struct timer_list		InactTimer;
+	u8				Addr[6];
+	TSPEC_BODY			TSpec;
+	QOS_TCLAS			TClass[TCLAS_NUM];
+	u8				TClasProc;
+	u8				TClasNum;
+} TS_COMMON_INFO, *PTS_COMMON_INFO;
+
+typedef struct _TX_TS_RECORD{
+	TS_COMMON_INFO		TsCommonInfo;
+	u16				TxCurSeq;
+	BA_RECORD			TxPendingBARecord;  	// For BA Originator
+	BA_RECORD			TxAdmittedBARecord;	// For BA Originator
+//	QOS_DL_RECORD		DLRecord;
+	u8				bAddBaReqInProgress;
+	u8				bAddBaReqDelayed;
+	u8				bUsingBa;
+	struct timer_list		TsAddBaTimer;
+	u8				num;
+} TX_TS_RECORD, *PTX_TS_RECORD;
+
+typedef struct _RX_TS_RECORD {
+	TS_COMMON_INFO		TsCommonInfo;
+	u16				RxIndicateSeq;
+	u16				RxTimeoutIndicateSeq;
+	struct list_head		RxPendingPktList;
+	struct timer_list		RxPktPendingTimer;
+	BA_RECORD			RxAdmittedBARecord;	 // For BA Recepient
+	u16				RxLastSeqNum;
+	u8				RxLastFragNum;
+	u8				num;
+//	QOS_DL_RECORD		DLRecord;
+} RX_TS_RECORD, *PRX_TS_RECORD;
+
+
+#endif
+
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c
new file mode 100644
index 0000000..5373d56
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c
@@ -0,0 +1,628 @@
+#include "ieee80211.h"
+#include <linux/etherdevice.h>
+#include "rtl819x_TS.h"
+
+void TsSetupTimeOut(unsigned long data)
+{
+	// Not implement yet
+	// This is used for WMMSA and ACM , that would send ADDTSReq frame.
+}
+
+void TsInactTimeout(unsigned long data)
+{
+	// Not implement yet
+	// This is used for WMMSA and ACM.
+	// This function would be call when TS is no Tx/Rx for some period of time.
+}
+
+/********************************************************************************************************************
+ *function:  I still not understand this function, so wait for further implementation
+ *   input:  unsigned long	 data		//acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer
+ *  return:  NULL
+ *  notice:
+********************************************************************************************************************/
+void RxPktPendingTimeout(unsigned long data)
+{
+	PRX_TS_RECORD	pRxTs = (PRX_TS_RECORD)data;
+	struct ieee80211_device *ieee = container_of(pRxTs, struct ieee80211_device, RxTsRecord[pRxTs->num]);
+
+	PRX_REORDER_ENTRY 	pReorderEntry = NULL;
+
+	//u32 flags = 0;
+	unsigned long flags = 0;
+	struct ieee80211_rxb *stats_IndicateArray[REORDER_WIN_SIZE];
+	u8 index = 0;
+	bool bPktInBuf = false;
+
+
+	spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
+	//PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
+	IEEE80211_DEBUG(IEEE80211_DL_REORDER,"==================>%s()\n",__FUNCTION__);
+	if(pRxTs->RxTimeoutIndicateSeq != 0xffff)
+	{
+		// Indicate the pending packets sequentially according to SeqNum until meet the gap.
+		while(!list_empty(&pRxTs->RxPendingPktList))
+		{
+			pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTs->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
+			if(index == 0)
+				pRxTs->RxIndicateSeq = pReorderEntry->SeqNum;
+
+			if( SN_LESS(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq) ||
+				SN_EQUAL(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq)	)
+			{
+				list_del_init(&pReorderEntry->List);
+
+				if(SN_EQUAL(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq))
+					pRxTs->RxIndicateSeq = (pRxTs->RxIndicateSeq + 1) % 4096;
+
+				IEEE80211_DEBUG(IEEE80211_DL_REORDER,"RxPktPendingTimeout(): IndicateSeq: %d\n", pReorderEntry->SeqNum);
+				stats_IndicateArray[index] = pReorderEntry->prxb;
+				index++;
+
+				list_add_tail(&pReorderEntry->List, &ieee->RxReorder_Unused_List);
+			}
+			else
+			{
+				bPktInBuf = true;
+				break;
+			}
+		}
+	}
+
+	if(index>0)
+	{
+		// Set RxTimeoutIndicateSeq to 0xffff to indicate no pending packets in buffer now.
+		pRxTs->RxTimeoutIndicateSeq = 0xffff;
+
+		// Indicate packets
+		if(index > REORDER_WIN_SIZE){
+			IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Rx Reorer buffer full!! \n");
+			spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
+			return;
+		}
+		ieee80211_indicate_packets(ieee, stats_IndicateArray, index);
+	}
+
+	if(bPktInBuf && (pRxTs->RxTimeoutIndicateSeq==0xffff))
+	{
+		pRxTs->RxTimeoutIndicateSeq = pRxTs->RxIndicateSeq;
+		if(timer_pending(&pRxTs->RxPktPendingTimer))
+			del_timer_sync(&pRxTs->RxPktPendingTimer);
+		pRxTs->RxPktPendingTimer.expires = jiffies + ieee->pHTInfo->RxReorderPendingTime;
+		add_timer(&pRxTs->RxPktPendingTimer);
+	}
+	spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
+	//PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
+}
+
+/********************************************************************************************************************
+ *function:  Add BA timer function
+ *   input:  unsigned long	 data		//acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer
+ *  return:  NULL
+ *  notice:
+********************************************************************************************************************/
+void TsAddBaProcess(unsigned long data)
+{
+	PTX_TS_RECORD	pTxTs = (PTX_TS_RECORD)data;
+	u8 num = pTxTs->num;
+	struct ieee80211_device *ieee = container_of(pTxTs, struct ieee80211_device, TxTsRecord[num]);
+
+	TsInitAddBA(ieee, pTxTs, BA_POLICY_IMMEDIATE, false);
+	IEEE80211_DEBUG(IEEE80211_DL_BA, "TsAddBaProcess(): ADDBA Req is started!! \n");
+}
+
+
+void ResetTsCommonInfo(PTS_COMMON_INFO	pTsCommonInfo)
+{
+	memset(pTsCommonInfo->Addr, 0, 6);
+	memset(&pTsCommonInfo->TSpec, 0, sizeof(TSPEC_BODY));
+	memset(&pTsCommonInfo->TClass, 0, sizeof(QOS_TCLAS)*TCLAS_NUM);
+	pTsCommonInfo->TClasProc = 0;
+	pTsCommonInfo->TClasNum = 0;
+}
+
+void ResetTxTsEntry(PTX_TS_RECORD pTS)
+{
+	ResetTsCommonInfo(&pTS->TsCommonInfo);
+	pTS->TxCurSeq = 0;
+	pTS->bAddBaReqInProgress = false;
+	pTS->bAddBaReqDelayed = false;
+	pTS->bUsingBa = false;
+	ResetBaEntry(&pTS->TxAdmittedBARecord); //For BA Originator
+	ResetBaEntry(&pTS->TxPendingBARecord);
+}
+
+void ResetRxTsEntry(PRX_TS_RECORD pTS)
+{
+	ResetTsCommonInfo(&pTS->TsCommonInfo);
+	pTS->RxIndicateSeq = 0xffff; // This indicate the RxIndicateSeq is not used now!!
+	pTS->RxTimeoutIndicateSeq = 0xffff; // This indicate the RxTimeoutIndicateSeq is not used now!!
+	ResetBaEntry(&pTS->RxAdmittedBARecord);	  // For BA Recepient
+}
+
+void TSInitialize(struct ieee80211_device *ieee)
+{
+	PTX_TS_RECORD		pTxTS  = ieee->TxTsRecord;
+	PRX_TS_RECORD		pRxTS  = ieee->RxTsRecord;
+	PRX_REORDER_ENTRY	pRxReorderEntry = ieee->RxReorderEntry;
+	u8				count = 0;
+	IEEE80211_DEBUG(IEEE80211_DL_TS, "==========>%s()\n", __FUNCTION__);
+	// Initialize Tx TS related info.
+	INIT_LIST_HEAD(&ieee->Tx_TS_Admit_List);
+	INIT_LIST_HEAD(&ieee->Tx_TS_Pending_List);
+	INIT_LIST_HEAD(&ieee->Tx_TS_Unused_List);
+
+	for(count = 0; count < TOTAL_TS_NUM; count++)
+	{
+		//
+		pTxTS->num = count;
+		// The timers for the operation of Traffic Stream and Block Ack.
+		// DLS related timer will be add here in the future!!
+		init_timer(&pTxTS->TsCommonInfo.SetupTimer);
+		pTxTS->TsCommonInfo.SetupTimer.data = (unsigned long)pTxTS;
+		pTxTS->TsCommonInfo.SetupTimer.function = TsSetupTimeOut;
+
+		init_timer(&pTxTS->TsCommonInfo.InactTimer);
+		pTxTS->TsCommonInfo.InactTimer.data = (unsigned long)pTxTS;
+		pTxTS->TsCommonInfo.InactTimer.function = TsInactTimeout;
+
+		init_timer(&pTxTS->TsAddBaTimer);
+		pTxTS->TsAddBaTimer.data = (unsigned long)pTxTS;
+		pTxTS->TsAddBaTimer.function = TsAddBaProcess;
+
+		init_timer(&pTxTS->TxPendingBARecord.Timer);
+		pTxTS->TxPendingBARecord.Timer.data = (unsigned long)pTxTS;
+		pTxTS->TxPendingBARecord.Timer.function = BaSetupTimeOut;
+
+		init_timer(&pTxTS->TxAdmittedBARecord.Timer);
+		pTxTS->TxAdmittedBARecord.Timer.data = (unsigned long)pTxTS;
+		pTxTS->TxAdmittedBARecord.Timer.function = TxBaInactTimeout;
+
+		ResetTxTsEntry(pTxTS);
+		list_add_tail(&pTxTS->TsCommonInfo.List, &ieee->Tx_TS_Unused_List);
+		pTxTS++;
+	}
+
+	// Initialize Rx TS related info.
+	INIT_LIST_HEAD(&ieee->Rx_TS_Admit_List);
+	INIT_LIST_HEAD(&ieee->Rx_TS_Pending_List);
+	INIT_LIST_HEAD(&ieee->Rx_TS_Unused_List);
+	for(count = 0; count < TOTAL_TS_NUM; count++)
+	{
+		pRxTS->num = count;
+		INIT_LIST_HEAD(&pRxTS->RxPendingPktList);
+
+		init_timer(&pRxTS->TsCommonInfo.SetupTimer);
+		pRxTS->TsCommonInfo.SetupTimer.data = (unsigned long)pRxTS;
+		pRxTS->TsCommonInfo.SetupTimer.function = TsSetupTimeOut;
+
+		init_timer(&pRxTS->TsCommonInfo.InactTimer);
+		pRxTS->TsCommonInfo.InactTimer.data = (unsigned long)pRxTS;
+		pRxTS->TsCommonInfo.InactTimer.function = TsInactTimeout;
+
+		init_timer(&pRxTS->RxAdmittedBARecord.Timer);
+		pRxTS->RxAdmittedBARecord.Timer.data = (unsigned long)pRxTS;
+		pRxTS->RxAdmittedBARecord.Timer.function = RxBaInactTimeout;
+
+		init_timer(&pRxTS->RxPktPendingTimer);
+		pRxTS->RxPktPendingTimer.data = (unsigned long)pRxTS;
+		pRxTS->RxPktPendingTimer.function = RxPktPendingTimeout;
+
+		ResetRxTsEntry(pRxTS);
+		list_add_tail(&pRxTS->TsCommonInfo.List, &ieee->Rx_TS_Unused_List);
+		pRxTS++;
+	}
+	// Initialize unused Rx Reorder List.
+	INIT_LIST_HEAD(&ieee->RxReorder_Unused_List);
+//#ifdef TO_DO_LIST
+	for(count = 0; count < REORDER_ENTRY_NUM; count++)
+	{
+		list_add_tail( &pRxReorderEntry->List,&ieee->RxReorder_Unused_List);
+		if(count == (REORDER_ENTRY_NUM-1))
+			break;
+		pRxReorderEntry = &ieee->RxReorderEntry[count+1];
+	}
+//#endif
+
+}
+
+void AdmitTS(struct ieee80211_device *ieee, PTS_COMMON_INFO pTsCommonInfo, u32 InactTime)
+{
+	del_timer_sync(&pTsCommonInfo->SetupTimer);
+	del_timer_sync(&pTsCommonInfo->InactTimer);
+
+	if(InactTime!=0)
+		mod_timer(&pTsCommonInfo->InactTimer, jiffies + MSECS(InactTime));
+}
+
+
+PTS_COMMON_INFO SearchAdmitTRStream(struct ieee80211_device *ieee, u8*	Addr, u8 TID, TR_SELECT	TxRxSelect)
+{
+	//DIRECTION_VALUE 	dir;
+	u8 	dir;
+	bool				search_dir[4] = {0, 0, 0, 0};
+	struct list_head*		psearch_list; //FIXME
+	PTS_COMMON_INFO	pRet = NULL;
+	if(ieee->iw_mode == IW_MODE_MASTER) //ap mode
+	{
+		if(TxRxSelect == TX_DIR)
+		{
+			search_dir[DIR_DOWN] = true;
+			search_dir[DIR_BI_DIR]= true;
+		}
+		else
+		{
+			search_dir[DIR_UP] 	= true;
+			search_dir[DIR_BI_DIR]= true;
+		}
+	}
+	else if(ieee->iw_mode == IW_MODE_ADHOC)
+	{
+		if(TxRxSelect == TX_DIR)
+			search_dir[DIR_UP] 	= true;
+		else
+			search_dir[DIR_DOWN] = true;
+	}
+	else
+	{
+		if(TxRxSelect == TX_DIR)
+		{
+			search_dir[DIR_UP] 	= true;
+			search_dir[DIR_BI_DIR]= true;
+			search_dir[DIR_DIRECT]= true;
+		}
+		else
+		{
+			search_dir[DIR_DOWN] = true;
+			search_dir[DIR_BI_DIR]= true;
+			search_dir[DIR_DIRECT]= true;
+		}
+	}
+
+	if(TxRxSelect == TX_DIR)
+		psearch_list = &ieee->Tx_TS_Admit_List;
+	else
+		psearch_list = &ieee->Rx_TS_Admit_List;
+
+	//for(dir = DIR_UP; dir <= DIR_BI_DIR; dir++)
+	for(dir = 0; dir <= DIR_BI_DIR; dir++)
+	{
+		if(search_dir[dir] ==false )
+			continue;
+		list_for_each_entry(pRet, psearch_list, List){
+	//		IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:"MAC_FMT", TID:%d, dir:%d\n", MAC_ARG(pRet->Addr), pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection);
+			if (memcmp(pRet->Addr, Addr, 6) == 0)
+				if (pRet->TSpec.f.TSInfo.field.ucTSID == TID)
+					if(pRet->TSpec.f.TSInfo.field.ucDirection == dir)
+					{
+	//					printk("Bingo! got it\n");
+						break;
+					}
+
+		}
+		if(&pRet->List  != psearch_list)
+			break;
+	}
+
+	if(&pRet->List  != psearch_list){
+		return pRet ;
+	}
+	else
+		return NULL;
+}
+
+void MakeTSEntry(
+		PTS_COMMON_INFO	pTsCommonInfo,
+		u8*		Addr,
+		PTSPEC_BODY	pTSPEC,
+		PQOS_TCLAS	pTCLAS,
+		u8		TCLAS_Num,
+		u8		TCLAS_Proc
+	)
+{
+	u8	count;
+
+	if(pTsCommonInfo == NULL)
+		return;
+
+	memcpy(pTsCommonInfo->Addr, Addr, 6);
+
+	if(pTSPEC != NULL)
+		memcpy((u8*)(&(pTsCommonInfo->TSpec)), (u8*)pTSPEC, sizeof(TSPEC_BODY));
+
+	for(count = 0; count < TCLAS_Num; count++)
+		memcpy((u8*)(&(pTsCommonInfo->TClass[count])), (u8*)pTCLAS, sizeof(QOS_TCLAS));
+
+	pTsCommonInfo->TClasProc = TCLAS_Proc;
+	pTsCommonInfo->TClasNum = TCLAS_Num;
+}
+
+
+bool GetTs(
+	struct ieee80211_device*	ieee,
+	PTS_COMMON_INFO			*ppTS,
+	u8*				Addr,
+	u8				TID,
+	TR_SELECT			TxRxSelect,  //Rx:1, Tx:0
+	bool				bAddNewTs
+	)
+{
+	u8	UP = 0;
+	//
+	// We do not build any TS for Broadcast or Multicast stream.
+	// So reject these kinds of search here.
+	//
+	if(is_broadcast_ether_addr(Addr) || is_multicast_ether_addr(Addr))
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "get TS for Broadcast or Multicast\n");
+		return false;
+	}
+	if (ieee->current_network.qos_data.supported == 0)
+		UP = 0;
+	else
+	{
+		// In WMM case: we use 4 TID only
+		if (!IsACValid(TID))
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_ERR, " in %s(), TID(%d) is not valid\n", __FUNCTION__, TID);
+			return false;
+		}
+
+		switch(TID)
+		{
+		case 0:
+		case 3:
+			UP = 0;
+			break;
+
+		case 1:
+		case 2:
+			UP = 2;
+			break;
+
+		case 4:
+		case 5:
+			UP = 5;
+			break;
+
+		case 6:
+		case 7:
+			UP = 7;
+			break;
+		}
+	}
+
+	*ppTS = SearchAdmitTRStream(
+			ieee,
+			Addr,
+			UP,
+			TxRxSelect);
+	if(*ppTS != NULL)
+	{
+		return true;
+	}
+	else
+	{
+		if(bAddNewTs == false)
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_TS, "add new TS failed(tid:%d)\n", UP);
+			return false;
+		}
+		else
+		{
+			//
+			// Create a new Traffic stream for current Tx/Rx
+			// This is for EDCA and WMM to add a new TS.
+			// For HCCA or WMMSA, TS cannot be addmit without negotiation.
+			//
+			TSPEC_BODY	TSpec;
+			PQOS_TSINFO		pTSInfo = &TSpec.f.TSInfo;
+			struct list_head*	pUnusedList =
+								(TxRxSelect == TX_DIR)?
+								(&ieee->Tx_TS_Unused_List):
+								(&ieee->Rx_TS_Unused_List);
+
+			struct list_head*	pAddmitList =
+								(TxRxSelect == TX_DIR)?
+								(&ieee->Tx_TS_Admit_List):
+								(&ieee->Rx_TS_Admit_List);
+
+			DIRECTION_VALUE		Dir =		(ieee->iw_mode == IW_MODE_MASTER)?
+								((TxRxSelect==TX_DIR)?DIR_DOWN:DIR_UP):
+								((TxRxSelect==TX_DIR)?DIR_UP:DIR_DOWN);
+			IEEE80211_DEBUG(IEEE80211_DL_TS, "to add Ts\n");
+			if(!list_empty(pUnusedList))
+			{
+				(*ppTS) = list_entry(pUnusedList->next, TS_COMMON_INFO, List);
+				list_del_init(&(*ppTS)->List);
+				if(TxRxSelect==TX_DIR)
+				{
+					PTX_TS_RECORD tmp = container_of(*ppTS, TX_TS_RECORD, TsCommonInfo);
+					ResetTxTsEntry(tmp);
+				}
+				else{
+					PRX_TS_RECORD tmp = container_of(*ppTS, RX_TS_RECORD, TsCommonInfo);
+					ResetRxTsEntry(tmp);
+				}
+
+				IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:"MAC_FMT"\n", UP, Dir, MAC_ARG(Addr));
+				// Prepare TS Info releated field
+				pTSInfo->field.ucTrafficType = 0;			// Traffic type: WMM is reserved in this field
+				pTSInfo->field.ucTSID = UP;			// TSID
+				pTSInfo->field.ucDirection = Dir;			// Direction: if there is DirectLink, this need additional consideration.
+				pTSInfo->field.ucAccessPolicy = 1;		// Access policy
+				pTSInfo->field.ucAggregation = 0; 		// Aggregation
+				pTSInfo->field.ucPSB = 0; 				// Aggregation
+				pTSInfo->field.ucUP = UP;				// User priority
+				pTSInfo->field.ucTSInfoAckPolicy = 0;		// Ack policy
+				pTSInfo->field.ucSchedule = 0;			// Schedule
+
+				MakeTSEntry(*ppTS, Addr, &TSpec, NULL, 0, 0);
+				AdmitTS(ieee, *ppTS, 0);
+				list_add_tail(&((*ppTS)->List), pAddmitList);
+				// if there is DirectLink, we need to do additional operation here!!
+
+				return true;
+			}
+			else
+			{
+				IEEE80211_DEBUG(IEEE80211_DL_ERR, "in function %s() There is not enough TS record to be used!!", __FUNCTION__);
+				return false;
+			}
+		}
+	}
+}
+
+void RemoveTsEntry(
+	struct ieee80211_device*	ieee,
+	PTS_COMMON_INFO			pTs,
+	TR_SELECT			TxRxSelect
+	)
+{
+	//u32 flags = 0;
+	unsigned long flags = 0;
+	del_timer_sync(&pTs->SetupTimer);
+	del_timer_sync(&pTs->InactTimer);
+	TsInitDelBA(ieee, pTs, TxRxSelect);
+
+	if(TxRxSelect == RX_DIR)
+	{
+//#ifdef TO_DO_LIST
+		PRX_REORDER_ENTRY	pRxReorderEntry;
+		PRX_TS_RECORD 		pRxTS = (PRX_TS_RECORD)pTs;
+		if(timer_pending(&pRxTS->RxPktPendingTimer))
+			del_timer_sync(&pRxTS->RxPktPendingTimer);
+
+		while(!list_empty(&pRxTS->RxPendingPktList))
+		{
+		//      PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
+			spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
+			//pRxReorderEntry = list_entry(&pRxTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
+			pRxReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
+			list_del_init(&pRxReorderEntry->List);
+			{
+				int i = 0;
+				struct ieee80211_rxb * prxb = pRxReorderEntry->prxb;
+				if (unlikely(!prxb))
+				{
+					spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
+					return;
+				}
+				for(i =0; i < prxb->nr_subframes; i++) {
+					dev_kfree_skb(prxb->subframes[i]);
+				}
+				kfree(prxb);
+				prxb = NULL;
+			}
+			list_add_tail(&pRxReorderEntry->List,&ieee->RxReorder_Unused_List);
+			//PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
+			spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
+		}
+
+//#endif
+	}
+	else
+	{
+		PTX_TS_RECORD pTxTS = (PTX_TS_RECORD)pTs;
+		del_timer_sync(&pTxTS->TsAddBaTimer);
+	}
+}
+
+void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr)
+{
+	PTS_COMMON_INFO	pTS, pTmpTS;
+	printk("===========>RemovePeerTS,"MAC_FMT"\n", MAC_ARG(Addr));
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List)
+	{
+		if (memcmp(pTS->Addr, Addr, 6) == 0)
+		{
+			RemoveTsEntry(ieee, pTS, TX_DIR);
+			list_del_init(&pTS->List);
+			list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
+		}
+	}
+
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List)
+	{
+		if (memcmp(pTS->Addr, Addr, 6) == 0)
+		{
+			printk("====>remove Tx_TS_admin_list\n");
+			RemoveTsEntry(ieee, pTS, TX_DIR);
+			list_del_init(&pTS->List);
+			list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
+		}
+	}
+
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List)
+	{
+		if (memcmp(pTS->Addr, Addr, 6) == 0)
+		{
+			RemoveTsEntry(ieee, pTS, RX_DIR);
+			list_del_init(&pTS->List);
+			list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
+		}
+	}
+
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List)
+	{
+		if (memcmp(pTS->Addr, Addr, 6) == 0)
+		{
+			RemoveTsEntry(ieee, pTS, RX_DIR);
+			list_del_init(&pTS->List);
+			list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
+		}
+	}
+}
+
+void RemoveAllTS(struct ieee80211_device* ieee)
+{
+	PTS_COMMON_INFO pTS, pTmpTS;
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List)
+	{
+		RemoveTsEntry(ieee, pTS, TX_DIR);
+		list_del_init(&pTS->List);
+		list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
+	}
+
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List)
+	{
+		RemoveTsEntry(ieee, pTS, TX_DIR);
+		list_del_init(&pTS->List);
+		list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
+	}
+
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List)
+	{
+		RemoveTsEntry(ieee, pTS, RX_DIR);
+		list_del_init(&pTS->List);
+		list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
+	}
+
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List)
+	{
+		RemoveTsEntry(ieee, pTS, RX_DIR);
+		list_del_init(&pTS->List);
+		list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
+	}
+}
+
+void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD	pTxTS)
+{
+	if(pTxTS->bAddBaReqInProgress == false)
+	{
+		pTxTS->bAddBaReqInProgress = true;
+		if(pTxTS->bAddBaReqDelayed)
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_BA, "TsStartAddBaProcess(): Delayed Start ADDBA after 60 sec!!\n");
+			mod_timer(&pTxTS->TsAddBaTimer, jiffies + MSECS(TS_ADDBA_DELAY));
+		}
+		else
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_BA,"TsStartAddBaProcess(): Immediately Start ADDBA now!!\n");
+			mod_timer(&pTxTS->TsAddBaTimer, jiffies+10); //set 10 ticks
+		}
+	}
+	else
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s()==>BA timer is already added\n", __FUNCTION__);
+}
+EXPORT_SYMBOL(RemovePeerTS);
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl_crypto.h b/drivers/staging/rtl8192u/ieee80211/rtl_crypto.h
new file mode 100644
index 0000000..ccf6ae7
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/rtl_crypto.h
@@ -0,0 +1,399 @@
+/*
+ * Scatterlist Cryptographic API.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2002 David S. Miller (davem@redhat.com)
+ *
+ * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
+ * and Nettle, by Niels Mé°ˆler.
+ *
+ * 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.
+ *
+ */
+#ifndef _LINUX_CRYPTO_H
+#define _LINUX_CRYPTO_H
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/string.h>
+#include <asm/page.h>
+#include <asm/errno.h>
+
+#define crypto_register_alg crypto_register_alg_rsl
+#define crypto_unregister_alg crypto_unregister_alg_rsl
+#define crypto_alloc_tfm crypto_alloc_tfm_rsl
+#define crypto_free_tfm crypto_free_tfm_rsl
+#define crypto_alg_available crypto_alg_available_rsl
+
+/*
+ * Algorithm masks and types.
+ */
+#define CRYPTO_ALG_TYPE_MASK		0x000000ff
+#define CRYPTO_ALG_TYPE_CIPHER		0x00000001
+#define CRYPTO_ALG_TYPE_DIGEST		0x00000002
+#define CRYPTO_ALG_TYPE_COMPRESS	0x00000004
+
+/*
+ * Transform masks and values (for crt_flags).
+ */
+#define CRYPTO_TFM_MODE_MASK		0x000000ff
+#define CRYPTO_TFM_REQ_MASK		0x000fff00
+#define CRYPTO_TFM_RES_MASK		0xfff00000
+
+#define CRYPTO_TFM_MODE_ECB		0x00000001
+#define CRYPTO_TFM_MODE_CBC		0x00000002
+#define CRYPTO_TFM_MODE_CFB		0x00000004
+#define CRYPTO_TFM_MODE_CTR		0x00000008
+
+#define CRYPTO_TFM_REQ_WEAK_KEY		0x00000100
+#define CRYPTO_TFM_RES_WEAK_KEY		0x00100000
+#define CRYPTO_TFM_RES_BAD_KEY_LEN   	0x00200000
+#define CRYPTO_TFM_RES_BAD_KEY_SCHED 	0x00400000
+#define CRYPTO_TFM_RES_BAD_BLOCK_LEN 	0x00800000
+#define CRYPTO_TFM_RES_BAD_FLAGS 	0x01000000
+
+/*
+ * Miscellaneous stuff.
+ */
+#define CRYPTO_UNSPEC			0
+#define CRYPTO_MAX_ALG_NAME		64
+
+struct scatterlist;
+
+/*
+ * Algorithms: modular crypto algorithm implementations, managed
+ * via crypto_register_alg() and crypto_unregister_alg().
+ */
+struct cipher_alg {
+	unsigned int cia_min_keysize;
+	unsigned int cia_max_keysize;
+	int (*cia_setkey)(void *ctx, const u8 *key,
+	                  unsigned int keylen, u32 *flags);
+	void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src);
+	void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src);
+};
+
+struct digest_alg {
+	unsigned int dia_digestsize;
+	void (*dia_init)(void *ctx);
+	void (*dia_update)(void *ctx, const u8 *data, unsigned int len);
+	void (*dia_final)(void *ctx, u8 *out);
+	int (*dia_setkey)(void *ctx, const u8 *key,
+	                  unsigned int keylen, u32 *flags);
+};
+
+struct compress_alg {
+	int (*coa_init)(void *ctx);
+	void (*coa_exit)(void *ctx);
+	int (*coa_compress)(void *ctx, const u8 *src, unsigned int slen,
+	                    u8 *dst, unsigned int *dlen);
+	int (*coa_decompress)(void *ctx, const u8 *src, unsigned int slen,
+	                      u8 *dst, unsigned int *dlen);
+};
+
+#define cra_cipher	cra_u.cipher
+#define cra_digest	cra_u.digest
+#define cra_compress	cra_u.compress
+
+struct crypto_alg {
+	struct list_head cra_list;
+	u32 cra_flags;
+	unsigned int cra_blocksize;
+	unsigned int cra_ctxsize;
+	const char cra_name[CRYPTO_MAX_ALG_NAME];
+
+	union {
+		struct cipher_alg cipher;
+		struct digest_alg digest;
+		struct compress_alg compress;
+	} cra_u;
+
+	struct module *cra_module;
+};
+
+/*
+ * Algorithm registration interface.
+ */
+int crypto_register_alg(struct crypto_alg *alg);
+int crypto_unregister_alg(struct crypto_alg *alg);
+
+/*
+ * Algorithm query interface.
+ */
+int crypto_alg_available(const char *name, u32 flags);
+
+/*
+ * Transforms: user-instantiated objects which encapsulate algorithms
+ * and core processing logic.  Managed via crypto_alloc_tfm() and
+ * crypto_free_tfm(), as well as the various helpers below.
+ */
+struct crypto_tfm;
+
+struct cipher_tfm {
+	void *cit_iv;
+	unsigned int cit_ivsize;
+	u32 cit_mode;
+	int (*cit_setkey)(struct crypto_tfm *tfm,
+	                  const u8 *key, unsigned int keylen);
+	int (*cit_encrypt)(struct crypto_tfm *tfm,
+			   struct scatterlist *dst,
+			   struct scatterlist *src,
+			   unsigned int nbytes);
+	int (*cit_encrypt_iv)(struct crypto_tfm *tfm,
+	                      struct scatterlist *dst,
+	                      struct scatterlist *src,
+	                      unsigned int nbytes, u8 *iv);
+	int (*cit_decrypt)(struct crypto_tfm *tfm,
+			   struct scatterlist *dst,
+			   struct scatterlist *src,
+			   unsigned int nbytes);
+	int (*cit_decrypt_iv)(struct crypto_tfm *tfm,
+			   struct scatterlist *dst,
+			   struct scatterlist *src,
+			   unsigned int nbytes, u8 *iv);
+	void (*cit_xor_block)(u8 *dst, const u8 *src);
+};
+
+struct digest_tfm {
+	void (*dit_init)(struct crypto_tfm *tfm);
+	void (*dit_update)(struct crypto_tfm *tfm,
+	                   struct scatterlist *sg, unsigned int nsg);
+	void (*dit_final)(struct crypto_tfm *tfm, u8 *out);
+	void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg,
+	                   unsigned int nsg, u8 *out);
+	int (*dit_setkey)(struct crypto_tfm *tfm,
+	                  const u8 *key, unsigned int keylen);
+#ifdef CONFIG_CRYPTO_HMAC
+	void *dit_hmac_block;
+#endif
+};
+
+struct compress_tfm {
+	int (*cot_compress)(struct crypto_tfm *tfm,
+	                    const u8 *src, unsigned int slen,
+	                    u8 *dst, unsigned int *dlen);
+	int (*cot_decompress)(struct crypto_tfm *tfm,
+	                      const u8 *src, unsigned int slen,
+	                      u8 *dst, unsigned int *dlen);
+};
+
+#define crt_cipher	crt_u.cipher
+#define crt_digest	crt_u.digest
+#define crt_compress	crt_u.compress
+
+struct crypto_tfm {
+
+	u32 crt_flags;
+
+	union {
+		struct cipher_tfm cipher;
+		struct digest_tfm digest;
+		struct compress_tfm compress;
+	} crt_u;
+
+	struct crypto_alg *__crt_alg;
+};
+
+/*
+ * Transform user interface.
+ */
+
+/*
+ * crypto_alloc_tfm() will first attempt to locate an already loaded algorithm.
+ * If that fails and the kernel supports dynamically loadable modules, it
+ * will then attempt to load a module of the same name or alias.  A refcount
+ * is grabbed on the algorithm which is then associated with the new transform.
+ *
+ * crypto_free_tfm() frees up the transform and any associated resources,
+ * then drops the refcount on the associated algorithm.
+ */
+struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags);
+void crypto_free_tfm(struct crypto_tfm *tfm);
+
+/*
+ * Transform helpers which query the underlying algorithm.
+ */
+static inline const char *crypto_tfm_alg_name(struct crypto_tfm *tfm)
+{
+	return tfm->__crt_alg->cra_name;
+}
+
+static inline const char *crypto_tfm_alg_modname(struct crypto_tfm *tfm)
+{
+	struct crypto_alg *alg = tfm->__crt_alg;
+
+	if (alg->cra_module)
+		return alg->cra_module->name;
+	else
+		return NULL;
+}
+
+static inline u32 crypto_tfm_alg_type(struct crypto_tfm *tfm)
+{
+	return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK;
+}
+
+static inline unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	return tfm->__crt_alg->cra_cipher.cia_min_keysize;
+}
+
+static inline unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	return tfm->__crt_alg->cra_cipher.cia_max_keysize;
+}
+
+static inline unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	return tfm->crt_cipher.cit_ivsize;
+}
+
+static inline unsigned int crypto_tfm_alg_blocksize(struct crypto_tfm *tfm)
+{
+	return tfm->__crt_alg->cra_blocksize;
+}
+
+static inline unsigned int crypto_tfm_alg_digestsize(struct crypto_tfm *tfm)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
+	return tfm->__crt_alg->cra_digest.dia_digestsize;
+}
+
+/*
+ * API wrappers.
+ */
+static inline void crypto_digest_init(struct crypto_tfm *tfm)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
+	tfm->crt_digest.dit_init(tfm);
+}
+
+static inline void crypto_digest_update(struct crypto_tfm *tfm,
+                                        struct scatterlist *sg,
+                                        unsigned int nsg)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
+	tfm->crt_digest.dit_update(tfm, sg, nsg);
+}
+
+static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
+	tfm->crt_digest.dit_final(tfm, out);
+}
+
+static inline void crypto_digest_digest(struct crypto_tfm *tfm,
+                                        struct scatterlist *sg,
+                                        unsigned int nsg, u8 *out)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
+	tfm->crt_digest.dit_digest(tfm, sg, nsg, out);
+}
+
+static inline int crypto_digest_setkey(struct crypto_tfm *tfm,
+                                       const u8 *key, unsigned int keylen)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
+	if (tfm->crt_digest.dit_setkey == NULL)
+		return -ENOSYS;
+	return tfm->crt_digest.dit_setkey(tfm, key, keylen);
+}
+
+static inline int crypto_cipher_setkey(struct crypto_tfm *tfm,
+                                       const u8 *key, unsigned int keylen)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	return tfm->crt_cipher.cit_setkey(tfm, key, keylen);
+}
+
+static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm,
+                                        struct scatterlist *dst,
+                                        struct scatterlist *src,
+                                        unsigned int nbytes)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes);
+}
+
+static inline int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm,
+                                           struct scatterlist *dst,
+                                           struct scatterlist *src,
+                                           unsigned int nbytes, u8 *iv)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
+	return tfm->crt_cipher.cit_encrypt_iv(tfm, dst, src, nbytes, iv);
+}
+
+static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm,
+                                        struct scatterlist *dst,
+                                        struct scatterlist *src,
+                                        unsigned int nbytes)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes);
+}
+
+static inline int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm,
+                                           struct scatterlist *dst,
+                                           struct scatterlist *src,
+                                           unsigned int nbytes, u8 *iv)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
+	return tfm->crt_cipher.cit_decrypt_iv(tfm, dst, src, nbytes, iv);
+}
+
+static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm,
+                                        const u8 *src, unsigned int len)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	memcpy(tfm->crt_cipher.cit_iv, src, len);
+}
+
+static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm,
+                                        u8 *dst, unsigned int len)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	memcpy(dst, tfm->crt_cipher.cit_iv, len);
+}
+
+static inline int crypto_comp_compress(struct crypto_tfm *tfm,
+                                       const u8 *src, unsigned int slen,
+                                       u8 *dst, unsigned int *dlen)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
+	return tfm->crt_compress.cot_compress(tfm, src, slen, dst, dlen);
+}
+
+static inline int crypto_comp_decompress(struct crypto_tfm *tfm,
+                                         const u8 *src, unsigned int slen,
+                                         u8 *dst, unsigned int *dlen)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
+	return tfm->crt_compress.cot_decompress(tfm, src, slen, dst, dlen);
+}
+
+/*
+ * HMAC support.
+ */
+#ifdef CONFIG_CRYPTO_HMAC
+void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen);
+void crypto_hmac_update(struct crypto_tfm *tfm,
+                        struct scatterlist *sg, unsigned int nsg);
+void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
+                       unsigned int *keylen, u8 *out);
+void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
+                 struct scatterlist *sg, unsigned int nsg, u8 *out);
+#endif	/* CONFIG_CRYPTO_HMAC */
+
+#endif	/* _LINUX_CRYPTO_H */
+
diff --git a/drivers/staging/rtl8192u/ieee80211/scatterwalk.c b/drivers/staging/rtl8192u/ieee80211/scatterwalk.c
new file mode 100644
index 0000000..49f401f
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/scatterwalk.c
@@ -0,0 +1,126 @@
+/*
+ * Cryptographic API.
+ *
+ * Cipher operations.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *               2002 Adam J. Richter <adam@yggdrasil.com>
+ *               2004 Jean-Luc Cooke <jlcooke@certainkey.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#include "kmap_types.h"
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/highmem.h>
+#include <asm/scatterlist.h>
+#include "internal.h"
+#include "scatterwalk.h"
+
+enum km_type crypto_km_types[] = {
+	KM_USER0,
+	KM_USER1,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
+};
+
+void *scatterwalk_whichbuf(struct scatter_walk *walk, unsigned int nbytes, void *scratch)
+{
+	if (nbytes <= walk->len_this_page &&
+	    (((unsigned long)walk->data) & (PAGE_CACHE_SIZE - 1)) + nbytes <=
+	    PAGE_CACHE_SIZE)
+		return walk->data;
+	else
+		return scratch;
+}
+
+static void memcpy_dir(void *buf, void *sgdata, size_t nbytes, int out)
+{
+	if (out)
+		memcpy(sgdata, buf, nbytes);
+	else
+		memcpy(buf, sgdata, nbytes);
+}
+
+void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg)
+{
+	unsigned int rest_of_page;
+
+	walk->sg = sg;
+
+	walk->page = sg->page;
+	walk->len_this_segment = sg->length;
+
+	rest_of_page = PAGE_CACHE_SIZE - (sg->offset & (PAGE_CACHE_SIZE - 1));
+	walk->len_this_page = min(sg->length, rest_of_page);
+	walk->offset = sg->offset;
+}
+
+void scatterwalk_map(struct scatter_walk *walk, int out)
+{
+	walk->data = crypto_kmap(walk->page, out) + walk->offset;
+}
+
+static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
+				 unsigned int more)
+{
+	/* walk->data may be pointing the first byte of the next page;
+	   however, we know we transfered at least one byte.  So,
+	   walk->data - 1 will be a virtual address in the mapped page. */
+
+	if (out)
+		flush_dcache_page(walk->page);
+
+	if (more) {
+		walk->len_this_segment -= walk->len_this_page;
+
+		if (walk->len_this_segment) {
+			walk->page++;
+			walk->len_this_page = min(walk->len_this_segment,
+						  (unsigned)PAGE_CACHE_SIZE);
+			walk->offset = 0;
+		}
+		else
+			scatterwalk_start(walk, sg_next(walk->sg));
+	}
+}
+
+void scatterwalk_done(struct scatter_walk *walk, int out, int more)
+{
+	crypto_kunmap(walk->data, out);
+	if (walk->len_this_page == 0 || !more)
+		scatterwalk_pagedone(walk, out, more);
+}
+
+/*
+ * Do not call this unless the total length of all of the fragments
+ * has been verified as multiple of the block size.
+ */
+int scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
+			   size_t nbytes, int out)
+{
+	if (buf != walk->data) {
+		while (nbytes > walk->len_this_page) {
+			memcpy_dir(buf, walk->data, walk->len_this_page, out);
+			buf += walk->len_this_page;
+			nbytes -= walk->len_this_page;
+
+			crypto_kunmap(walk->data, out);
+			scatterwalk_pagedone(walk, out, 1);
+			scatterwalk_map(walk, out);
+		}
+
+		memcpy_dir(buf, walk->data, nbytes, out);
+	}
+
+	walk->offset += nbytes;
+	walk->len_this_page -= nbytes;
+	walk->len_this_segment -= nbytes;
+	return 0;
+}
diff --git a/drivers/staging/rtl8192u/ieee80211/scatterwalk.h b/drivers/staging/rtl8192u/ieee80211/scatterwalk.h
new file mode 100644
index 0000000..b164465
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211/scatterwalk.h
@@ -0,0 +1,51 @@
+/*
+ * Cryptographic API.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2002 Adam J. Richter <adam@yggdrasil.com>
+ * Copyright (c) 2004 Jean-Luc Cooke <jlcooke@certainkey.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef _CRYPTO_SCATTERWALK_H
+#define _CRYPTO_SCATTERWALK_H
+#include <linux/mm.h>
+#include <asm/scatterlist.h>
+
+struct scatter_walk {
+	struct scatterlist	*sg;
+	struct page		*page;
+	void			*data;
+	unsigned int		len_this_page;
+	unsigned int		len_this_segment;
+	unsigned int		offset;
+};
+
+/* Define sg_next is an inline routine now in case we want to change
+   scatterlist to a linked list later. */
+static inline struct scatterlist *sg_next(struct scatterlist *sg)
+{
+	return sg + 1;
+}
+
+static inline int scatterwalk_samebuf(struct scatter_walk *walk_in,
+				      struct scatter_walk *walk_out,
+				      void *src_p, void *dst_p)
+{
+	return walk_in->page == walk_out->page &&
+	       walk_in->offset == walk_out->offset &&
+	       walk_in->data == src_p && walk_out->data == dst_p;
+}
+
+void *scatterwalk_whichbuf(struct scatter_walk *walk, unsigned int nbytes, void *scratch);
+void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg);
+int scatterwalk_copychunks(void *buf, struct scatter_walk *walk, size_t nbytes, int out);
+void scatterwalk_map(struct scatter_walk *walk, int out);
+void scatterwalk_done(struct scatter_walk *walk, int out, int more);
+
+#endif  /* _CRYPTO_SCATTERWALK_H */
diff --git a/drivers/staging/rtl8192u/ieee80211_crypt.h b/drivers/staging/rtl8192u/ieee80211_crypt.h
new file mode 100644
index 0000000..b58a3bc
--- /dev/null
+++ b/drivers/staging/rtl8192u/ieee80211_crypt.h
@@ -0,0 +1,86 @@
+/*
+ * 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/rtl8192u/r8180_93cx6.c b/drivers/staging/rtl8192u/r8180_93cx6.c
new file mode 100644
index 0000000..8878cfe
--- /dev/null
+++ b/drivers/staging/rtl8192u/r8180_93cx6.c
@@ -0,0 +1,146 @@
+/*
+   This files contains card eeprom (93c46 or 93c56) programming routines,
+   memory is addressed by 16 bits words.
+
+   This is part of rtl8180 OpenSource driver.
+   Copyright (C) Andrea Merello 2004  <andreamrl@tiscali.it>
+   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.
+*/
+
+#include "r8180_93cx6.h"
+
+void eprom_cs(struct net_device *dev, short bit)
+{
+	if(bit)
+		write_nic_byte_E(dev, EPROM_CMD,
+			       (1<<EPROM_CS_SHIFT) | \
+			       read_nic_byte_E(dev, EPROM_CMD)); //enable EPROM
+	else
+		write_nic_byte_E(dev, EPROM_CMD, read_nic_byte_E(dev, EPROM_CMD)\
+			       &~(1<<EPROM_CS_SHIFT)); //disable EPROM
+
+	force_pci_posting(dev);
+	udelay(EPROM_DELAY);
+}
+
+
+void eprom_ck_cycle(struct net_device *dev)
+{
+	write_nic_byte_E(dev, EPROM_CMD,
+		       (1<<EPROM_CK_SHIFT) | read_nic_byte_E(dev,EPROM_CMD));
+	force_pci_posting(dev);
+	udelay(EPROM_DELAY);
+	write_nic_byte_E(dev, EPROM_CMD,
+		       read_nic_byte_E(dev, EPROM_CMD) &~ (1<<EPROM_CK_SHIFT));
+	force_pci_posting(dev);
+	udelay(EPROM_DELAY);
+}
+
+
+void eprom_w(struct net_device *dev,short bit)
+{
+	if(bit)
+		write_nic_byte_E(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | \
+			       read_nic_byte_E(dev,EPROM_CMD));
+	else
+		write_nic_byte_E(dev, EPROM_CMD, read_nic_byte_E(dev,EPROM_CMD)\
+			       &~(1<<EPROM_W_SHIFT));
+
+	force_pci_posting(dev);
+	udelay(EPROM_DELAY);
+}
+
+
+short eprom_r(struct net_device *dev)
+{
+	short bit;
+
+	bit=(read_nic_byte_E(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT) );
+	udelay(EPROM_DELAY);
+
+	if(bit) return 1;
+	return 0;
+}
+
+
+void eprom_send_bits_string(struct net_device *dev, short b[], int len)
+{
+	int i;
+
+	for(i=0; i<len; i++){
+		eprom_w(dev, b[i]);
+		eprom_ck_cycle(dev);
+	}
+}
+
+
+u32 eprom_read(struct net_device *dev, u32 addr)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	short read_cmd[]={1,1,0};
+	short addr_str[8];
+	int i;
+	int addr_len;
+	u32 ret;
+
+	ret=0;
+        //enable EPROM programming
+	write_nic_byte_E(dev, EPROM_CMD,
+		       (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT));
+	force_pci_posting(dev);
+	udelay(EPROM_DELAY);
+
+	if (priv->epromtype==EPROM_93c56){
+		addr_str[7]=addr & 1;
+		addr_str[6]=addr & (1<<1);
+		addr_str[5]=addr & (1<<2);
+		addr_str[4]=addr & (1<<3);
+		addr_str[3]=addr & (1<<4);
+		addr_str[2]=addr & (1<<5);
+		addr_str[1]=addr & (1<<6);
+		addr_str[0]=addr & (1<<7);
+		addr_len=8;
+	}else{
+		addr_str[5]=addr & 1;
+		addr_str[4]=addr & (1<<1);
+		addr_str[3]=addr & (1<<2);
+		addr_str[2]=addr & (1<<3);
+		addr_str[1]=addr & (1<<4);
+		addr_str[0]=addr & (1<<5);
+		addr_len=6;
+	}
+	eprom_cs(dev, 1);
+	eprom_ck_cycle(dev);
+	eprom_send_bits_string(dev, read_cmd, 3);
+	eprom_send_bits_string(dev, addr_str, addr_len);
+
+	//keep chip pin D to low state while reading.
+	//I'm unsure if it is necessary, but anyway shouldn't hurt
+	eprom_w(dev, 0);
+
+	for(i=0;i<16;i++){
+		//eeprom needs a clk cycle between writing opcode&adr
+		//and reading data. (eeprom outs a dummy 0)
+		eprom_ck_cycle(dev);
+		ret |= (eprom_r(dev)<<(15-i));
+	}
+
+	eprom_cs(dev, 0);
+	eprom_ck_cycle(dev);
+
+	//disable EPROM programming
+	write_nic_byte_E(dev, EPROM_CMD,
+		       (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT));
+	return ret;
+}
diff --git a/drivers/staging/rtl8192u/r8180_93cx6.h b/drivers/staging/rtl8192u/r8180_93cx6.h
new file mode 100644
index 0000000..fb3ac97
--- /dev/null
+++ b/drivers/staging/rtl8192u/r8180_93cx6.h
@@ -0,0 +1,40 @@
+/*
+	This is part of rtl8187 OpenSource driver
+	Copyright (C) Andrea Merello 2004-2005  <andreamrl@tiscali.it>
+	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 "r8192U.h"
+#include "r8192U_hw.h"
+
+#define EPROM_DELAY 10
+
+#define EPROM_ANAPARAM_ADDRLWORD 0xd
+#define EPROM_ANAPARAM_ADDRHWORD 0xe
+
+#define EPROM_RFCHIPID 0x6
+#define EPROM_TXPW_BASE 0x05
+#define EPROM_RFCHIPID_RTL8225U 5
+#define EPROM_RF_PARAM 0x4
+#define EPROM_CONFIG2 0xc
+
+#define EPROM_VERSION 0x1E
+#define MAC_ADR 0x7
+
+#define CIS 0x18
+
+#define EPROM_TXPW0 0x16
+#define EPROM_TXPW2 0x1b
+#define EPROM_TXPW1 0x3d
+
+
+u32 eprom_read(struct net_device *dev,u32 addr); //reads a 16 bits word
diff --git a/drivers/staging/rtl8192u/r8180_pm.c b/drivers/staging/rtl8192u/r8180_pm.c
new file mode 100644
index 0000000..0c58d0e
--- /dev/null
+++ b/drivers/staging/rtl8192u/r8180_pm.c
@@ -0,0 +1,48 @@
+/*
+   Power management interface routines.
+   Written by Mariusz Matuszek.
+   This code is currently just a placeholder for later work and
+   does not do anything useful.
+
+   This is part of rtl8180 OpenSource driver.
+   Copyright (C) Andrea Merello 2004  <andreamrl@tiscali.it>
+   Released under the terms of GPL (General Public Licence)
+*/
+
+#ifdef CONFIG_RTL8180_PM
+
+
+#include "r8180_hw.h"
+#include "r8180_pm.h"
+
+int rtl8180_save_state (struct pci_dev *dev, u32 state)
+{
+	printk(KERN_NOTICE "r8180 save state call (state %u).\n", state);
+	return(-EAGAIN);
+}
+
+
+int rtl8180_suspend (struct pci_dev *dev, u32 state)
+{
+	printk(KERN_NOTICE "r8180 suspend call (state %u).\n", state);
+	return(-EAGAIN);
+}
+
+
+int rtl8180_resume (struct pci_dev *dev)
+{
+	printk(KERN_NOTICE "r8180 resume call.\n");
+	return(-EAGAIN);
+}
+
+
+int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable)
+{
+	printk(KERN_NOTICE "r8180 enable wake call (state %u, enable %d).\n",
+	       state, enable);
+	return(-EAGAIN);
+}
+
+
+
+#endif //CONFIG_RTL8180_PM
diff --git a/drivers/staging/rtl8192u/r8180_pm.h b/drivers/staging/rtl8192u/r8180_pm.h
new file mode 100644
index 0000000..c7d18a8
--- /dev/null
+++ b/drivers/staging/rtl8192u/r8180_pm.h
@@ -0,0 +1,28 @@
+/*
+        Power management interface routines.
+	Written by Mariusz Matuszek.
+	This code is currently just a placeholder for later work and
+	does not do anything useful.
+
+	This is part of rtl8180 OpenSource driver.
+	Copyright (C) Andrea Merello 2004  <andreamrl@tiscali.it>
+	Released under the terms of GPL (General Public Licence)
+
+*/
+
+#ifdef CONFIG_RTL8180_PM
+
+#ifndef R8180_PM_H
+#define R8180_PM_H
+
+#include <linux/types.h>
+#include <linux/pci.h>
+
+int rtl8180_save_state (struct pci_dev *dev, u32 state);
+int rtl8180_suspend (struct pci_dev *dev, u32 state);
+int rtl8180_resume (struct pci_dev *dev);
+int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable);
+
+#endif //R8180_PM_H
+
+#endif // CONFIG_RTL8180_PM
diff --git a/drivers/staging/rtl8192u/r8190_rtl8256.c b/drivers/staging/rtl8192u/r8190_rtl8256.c
new file mode 100644
index 0000000..74ff337
--- /dev/null
+++ b/drivers/staging/rtl8192u/r8190_rtl8256.c
@@ -0,0 +1,312 @@
+/*
+  This is part of the rtl8192 driver
+  released under the GPL (See file COPYING for details).
+
+  This files contains programming code for the rtl8256
+  radio frontend.
+
+  *Many* thanks to Realtek Corp. for their great support!
+
+*/
+
+#include "r8192U.h"
+#include "r8192U_hw.h"
+#include "r819xU_phyreg.h"
+#include "r819xU_phy.h"
+#include "r8190_rtl8256.h"
+
+/*--------------------------------------------------------------------------
+ * Overview:   	set RF band width (20M or 40M)
+ * Input:       struct net_device*	dev
+ * 		WIRELESS_BANDWIDTH_E	Bandwidth	//20M or 40M
+ * Output:      NONE
+ * Return:      NONE
+ * Note:	8226 support both 20M  and 40 MHz
+ *---------------------------------------------------------------------------*/
+void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth)	//20M or 40M
+{
+	u8	eRFPath;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	//for(eRFPath = RF90_PATH_A; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
+	for(eRFPath = 0; eRFPath <RF90_PATH_MAX; eRFPath++)
+	{
+		if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
+				continue;
+
+		switch(Bandwidth)
+		{
+			case HT_CHANNEL_WIDTH_20:
+				if(priv->card_8192_version == VERSION_819xU_A || priv->card_8192_version == VERSION_819xU_B)// 8256 D-cut, E-cut, xiong: consider it later!
+				{
+					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x100); //phy para:1ba
+					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3d7);
+					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x021);
+
+					//cosa add for sd3's request 01/23/2008
+					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x5ab);
+				}
+				else
+				{
+					RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n");
+				}
+
+				break;
+			case HT_CHANNEL_WIDTH_20_40:
+				if(priv->card_8192_version == VERSION_819xU_A ||priv->card_8192_version == VERSION_819xU_B)// 8256 D-cut, E-cut, xiong: consider it later!
+				{
+					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x300); //phy para:3ba
+					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3df);
+					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x0a1);
+
+					//cosa add for sd3's request 01/23/2008
+					if(priv->chan == 3 || priv->chan == 9) //I need to set priv->chan whenever current channel changes
+						rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x59b);
+					else
+						rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x5ab);
+				}
+				else
+				{
+					RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n");
+				}
+
+
+				break;
+			default:
+				RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth );
+				break;
+
+		}
+	}
+	return;
+}
+/*--------------------------------------------------------------------------
+ * Overview:    Interface to config 8256
+ * Input:       struct net_device*	dev
+ * Output:      NONE
+ * Return:      NONE
+ *---------------------------------------------------------------------------*/
+void PHY_RF8256_Config(struct net_device* dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	// Initialize general global value
+	//
+	// TODO: Extend RF_PATH_C and RF_PATH_D in the future
+	priv->NumTotalRFPath = RTL819X_TOTAL_RF_PATH;
+	// Config BB and RF
+	phy_RF8256_Config_ParaFile(dev);
+
+	return;
+}
+/*--------------------------------------------------------------------------
+ * Overview:    Interface to config 8256
+ * Input:       struct net_device*	dev
+ * Output:      NONE
+ * Return:      NONE
+ *---------------------------------------------------------------------------*/
+void phy_RF8256_Config_ParaFile(struct net_device* dev)
+{
+	u32 	u4RegValue = 0;
+	//static s1Byte				szRadioAFile[] = RTL819X_PHY_RADIO_A;
+	//static s1Byte				szRadioBFile[] = RTL819X_PHY_RADIO_B;
+	//static s1Byte				szRadioCFile[] = RTL819X_PHY_RADIO_C;
+	//static s1Byte				szRadioDFile[] = RTL819X_PHY_RADIO_D;
+	u8 	eRFPath;
+	BB_REGISTER_DEFINITION_T	*pPhyReg;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32	RegOffSetToBeCheck = 0x3;
+	u32 	RegValueToBeCheck = 0x7f1;
+	u32	RF3_Final_Value = 0;
+	u8	ConstRetryTimes = 5, RetryTimes = 5;
+	u8 ret = 0;
+	//3//-----------------------------------------------------------------
+	//3// <2> Initialize RF
+	//3//-----------------------------------------------------------------
+	for(eRFPath = (RF90_RADIO_PATH_E)RF90_PATH_A; eRFPath <priv->NumTotalRFPath; eRFPath++)
+	{
+		if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
+				continue;
+
+		pPhyReg = &priv->PHYRegDef[eRFPath];
+
+		// Joseph test for shorten RF config
+	//	pHalData->RfReg0Value[eRFPath] =  rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, rGlobalCtrl, bMaskDWord);
+
+		/*----Store original RFENV control type----*/
+		switch(eRFPath)
+		{
+		case RF90_PATH_A:
+		case RF90_PATH_C:
+			u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV);
+			break;
+		case RF90_PATH_B :
+		case RF90_PATH_D:
+			u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16);
+			break;
+		}
+
+		/*----Set RF_ENV enable----*/
+		rtl8192_setBBreg(dev, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1);
+
+		/*----Set RF_ENV output high----*/
+		rtl8192_setBBreg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0x1);
+
+		/* Set bit number of Address and Data for RF register */
+		rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); 	// Set 0 to 4 bits for Z-serial and set 1 to 6 bits for 8258
+		rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0);	// Set 0 to 12 bits for Z-serial and 8258, and set 1 to 14 bits for ???
+
+		rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E) eRFPath, 0x0, bMask12Bits, 0xbf);
+
+		/*----Check RF block (for FPGA platform only)----*/
+		// TODO: this function should be removed on ASIC , Emily 2007.2.2
+		if (rtl8192_phy_checkBBAndRF(dev, HW90_BLOCK_RF, (RF90_RADIO_PATH_E)eRFPath))
+		{
+			RT_TRACE(COMP_ERR, "PHY_RF8256_Config():Check Radio[%d] Fail!!\n", eRFPath);
+			goto phy_RF8256_Config_ParaFile_Fail;
+		}
+
+		RetryTimes = ConstRetryTimes;
+		RF3_Final_Value = 0;
+		/*----Initialize RF fom connfiguration file----*/
+		switch(eRFPath)
+		{
+		case RF90_PATH_A:
+			while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
+			{
+				ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
+				RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
+				RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
+				RetryTimes--;
+			}
+			break;
+		case RF90_PATH_B:
+			while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
+			{
+				ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
+				RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
+				RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
+				RetryTimes--;
+			}
+			break;
+		case RF90_PATH_C:
+			while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
+			{
+				ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
+				RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
+				RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
+				RetryTimes--;
+			}
+			break;
+		case RF90_PATH_D:
+			while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
+			{
+				ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
+				RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
+				RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
+				RetryTimes--;
+			}
+			break;
+		}
+
+		/*----Restore RFENV control type----*/;
+		switch(eRFPath)
+		{
+		case RF90_PATH_A:
+		case RF90_PATH_C:
+			rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue);
+			break;
+		case RF90_PATH_B :
+		case RF90_PATH_D:
+			rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue);
+			break;
+		}
+
+		if(ret){
+			RT_TRACE(COMP_ERR, "phy_RF8256_Config_ParaFile():Radio[%d] Fail!!", eRFPath);
+			goto phy_RF8256_Config_ParaFile_Fail;
+		}
+
+	}
+
+	RT_TRACE(COMP_PHY, "PHY Initialization Success\n") ;
+	return ;
+
+phy_RF8256_Config_ParaFile_Fail:
+	RT_TRACE(COMP_ERR, "PHY Initialization failed\n") ;
+	return ;
+}
+
+
+void PHY_SetRF8256CCKTxPower(struct net_device*	dev, u8	powerlevel)
+{
+	u32	TxAGC=0;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	//modified by vivi, 20080109
+	TxAGC = powerlevel;
+
+	if(priv->bDynamicTxLowPower == TRUE ) //cosa 05/22/2008 for scan
+	{
+		if(priv->CustomerID == RT_CID_819x_Netcore)
+			TxAGC = 0x22;
+		else
+		TxAGC += priv->CckPwEnl;
+	}
+
+	if(TxAGC > 0x24)
+		TxAGC = 0x24;
+	rtl8192_setBBreg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC);
+}
+
+
+void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	//Joseph TxPower for 8192 testing
+	u32 writeVal, powerBase0, powerBase1, writeVal_tmp;
+	u8 index = 0;
+	u16 RegOffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c};
+	u8 byte0, byte1, byte2, byte3;
+
+	powerBase0 = powerlevel + priv->TxPowerDiff;	//OFDM rates
+	powerBase0 = (powerBase0<<24) | (powerBase0<<16) |(powerBase0<<8) |powerBase0;
+	powerBase1 = powerlevel;							//MCS rates
+	powerBase1 = (powerBase1<<24) | (powerBase1<<16) |(powerBase1<<8) |powerBase1;
+
+	for(index=0; index<6; index++)
+	{
+		writeVal = priv->MCSTxPowerLevelOriginalOffset[index] + ((index<2)?powerBase0:powerBase1);
+		byte0 = (u8)(writeVal & 0x7f);
+		byte1 = (u8)((writeVal & 0x7f00)>>8);
+		byte2 = (u8)((writeVal & 0x7f0000)>>16);
+		byte3 = (u8)((writeVal & 0x7f000000)>>24);
+		if(byte0 > 0x24)	// Max power index = 0x24
+			byte0 = 0x24;
+		if(byte1 > 0x24)
+			byte1 = 0x24;
+		if(byte2 > 0x24)
+			byte2 = 0x24;
+		if(byte3 > 0x24)
+			byte3 = 0x24;
+
+		//for tx power track
+		if(index == 3)
+		{
+			writeVal_tmp = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0;
+			priv->Pwr_Track = writeVal_tmp;
+		}
+
+		if(priv->bDynamicTxHighPower == TRUE)     //Add by Jacken 2008/03/06
+		{
+			// Emily, 20080613. Set low tx power for both MCS and legacy OFDM
+			writeVal = 0x03030303;
+		}
+		else
+		{
+			writeVal = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0;
+		}
+		rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal);
+	}
+	return;
+
+}
+
diff --git a/drivers/staging/rtl8192u/r8190_rtl8256.h b/drivers/staging/rtl8192u/r8190_rtl8256.h
new file mode 100644
index 0000000..5c1f650
--- /dev/null
+++ b/drivers/staging/rtl8192u/r8190_rtl8256.h
@@ -0,0 +1,27 @@
+/*
+  This is part of the rtl8180-sa2400 driver
+  released under the GPL (See file COPYING for details).
+  Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
+
+  This files contains programming code for the rtl8256
+  radio frontend.
+
+  *Many* thanks to Realtek Corp. for their great support!
+
+*/
+
+#ifndef RTL8225H
+#define RTL8225H
+
+#ifdef RTL8190P
+#define RTL819X_TOTAL_RF_PATH 4 //for 90P
+#else
+#define RTL819X_TOTAL_RF_PATH 2 //for 8192U
+#endif
+extern void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth);
+extern void PHY_RF8256_Config(struct net_device* dev);
+extern void phy_RF8256_Config_ParaFile(struct net_device* dev);
+extern void PHY_SetRF8256CCKTxPower(struct net_device*	dev, u8	powerlevel);
+extern void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel);
+
+#endif
diff --git a/drivers/staging/rtl8192u/r8192U.h b/drivers/staging/rtl8192u/r8192U.h
new file mode 100644
index 0000000..69a2721
--- /dev/null
+++ b/drivers/staging/rtl8192u/r8192U.h
@@ -0,0 +1,1263 @@
+/*
+   This is part of rtl8187 OpenSource driver.
+   Copyright (C) Andrea Merello 2004-2005  <andreamrl@tiscali.it>
+   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 rtl8192 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.
+*/
+
+#ifndef R819xU_H
+#define R819xU_H
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+//#include <linux/config.h>
+#include <linux/init.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/usb.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 <linux/random.h>
+#include <linux/version.h>
+#include <asm/io.h>
+#include "ieee80211.h"
+
+#define RTL8192U
+#define RTL819xU_MODULE_NAME "rtl819xU"
+//added for HW security, john.0629
+#define FALSE 0
+#define TRUE 1
+#define MAX_KEY_LEN     61
+#define KEY_BUF_SIZE    5
+
+#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 BIT8            0x00000100
+#define BIT9            0x00000200
+#define BIT10           0x00000400
+#define BIT11           0x00000800
+#define BIT12           0x00001000
+#define BIT13           0x00002000
+#define BIT14           0x00004000
+#define BIT15           0x00008000
+#define BIT16           0x00010000
+#define BIT17           0x00020000
+#define BIT18           0x00040000
+#define BIT19           0x00080000
+#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
+
+// Rx smooth factor
+#define	Rx_Smooth_Factor		20
+#define DMESG(x,a...)
+#define DMESGW(x,a...)
+#define DMESGE(x,a...)
+extern u32 rt_global_debug_component;
+#define RT_TRACE(component, x, args...) \
+do { if(rt_global_debug_component & component) \
+	printk(KERN_DEBUG RTL819xU_MODULE_NAME ":" x "\n" , \
+	       ##args);\
+}while(0);
+
+#define COMP_TRACE				BIT0		// For function call tracing.
+#define COMP_DBG				BIT1		// Only for temporary debug message.
+#define COMP_INIT				BIT2		// during driver initialization / halt / reset.
+
+
+#define COMP_RECV				BIT3		// Reveive part data path.
+#define COMP_SEND				BIT4		// Send part path.
+#define COMP_IO					BIT5		// I/O Related. Added by Annie, 2006-03-02.
+#define COMP_POWER				BIT6		// 802.11 Power Save mode or System/Device Power state related.
+#define COMP_EPROM				BIT7		// 802.11 link related: join/start BSS, leave BSS.
+#define COMP_SWBW				BIT8	// For bandwidth switch.
+#define COMP_POWER_TRACKING			BIT9	//FOR 8190 TX POWER TRACKING
+#define COMP_TURBO				BIT10	// For Turbo Mode related. By Annie, 2005-10-21.
+#define COMP_QOS				BIT11	// For QoS.
+#define COMP_RATE				BIT12	// For Rate Adaptive mechanism, 2006.07.02, by rcnjko.
+#define COMP_RM					BIT13	// For Radio Measurement.
+#define COMP_DIG				BIT14	// For DIG, 2006.09.25, by rcnjko.
+#define COMP_PHY	 			BIT15
+#define COMP_CH					BIT16	//channel setting debug
+#define COMP_TXAGC				BIT17	// For Tx power, 060928, by rcnjko.
+#define COMP_HIPWR				BIT18	// For High Power Mechanism, 060928, by rcnjko.
+#define COMP_HALDM				BIT19	// For HW Dynamic Mechanism, 061010, by rcnjko.
+#define COMP_SEC			        BIT20	// Event handling
+#define COMP_LED				BIT21	// For LED.
+#define COMP_RF					BIT22	// For RF.
+//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
+#define COMP_RXDESC				BIT23	// Show Rx desc information for SD3 debug. Added by Annie, 2006-07-15.
+//1//1Attention Please!!!<11n or 8190 specific code should be put below this line>
+//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+#define COMP_FIRMWARE				BIT24	//for firmware downloading
+#define COMP_HT					BIT25	// For 802.11n HT related information. by Emily 2006-8-11
+#define COMP_AMSDU				BIT26	// For A-MSDU Debugging
+
+#define COMP_SCAN				BIT27
+//#define COMP_RESET				BIT28
+#define COMP_DOWN				BIT29  //for rm driver module
+#define COMP_RESET				BIT30  //for silent reset
+#define COMP_ERR				BIT31 //for error out, always on
+
+#define RTL819x_DEBUG
+#ifdef RTL819x_DEBUG
+#define assert(expr) \
+        if (!(expr)) {                                  \
+                printk( "Assertion failed! %s,%s,%s,line=%d\n", \
+                #expr,__FILE__,__FUNCTION__,__LINE__);          \
+        }
+//wb added to debug out data buf
+//if you want print DATA buffer related BA, please set ieee80211_debug_level to DATA|BA
+#define RT_DEBUG_DATA(level, data, datalen)      \
+        do{ if ((rt_global_debug_component & (level)) == (level))   \
+                {       \
+                        int i;                                  \
+                        u8* pdata = (u8*) data;                 \
+                        printk(KERN_DEBUG RTL819xU_MODULE_NAME ": %s()\n", __FUNCTION__);   \
+                        for(i=0; i<(int)(datalen); i++)                 \
+                        {                                               \
+                                printk("%2x ", pdata[i]);               \
+                                if ((i+1)%16 == 0) printk("\n");        \
+                        }                               \
+                        printk("\n");                   \
+                }                                       \
+        } while (0)
+#else
+#define assert(expr) do {} while (0)
+#define RT_DEBUG_DATA(level, data, datalen) do {} while(0)
+#endif /* RTL8169_DEBUG */
+
+
+//
+// Queue Select Value in TxDesc
+//
+#define QSLT_BK                                 0x1
+#define QSLT_BE                                 0x0
+#define QSLT_VI                                 0x4
+#define QSLT_VO                                 0x6
+#define QSLT_BEACON                             0x10
+#define QSLT_HIGH                               0x11
+#define QSLT_MGNT                               0x12
+#define QSLT_CMD                                0x13
+
+#define DESC90_RATE1M                           0x00
+#define DESC90_RATE2M                           0x01
+#define DESC90_RATE5_5M                         0x02
+#define DESC90_RATE11M                          0x03
+#define DESC90_RATE6M                           0x04
+#define DESC90_RATE9M                           0x05
+#define DESC90_RATE12M                          0x06
+#define DESC90_RATE18M                          0x07
+#define DESC90_RATE24M                          0x08
+#define DESC90_RATE36M                          0x09
+#define DESC90_RATE48M                          0x0a
+#define DESC90_RATE54M                          0x0b
+#define DESC90_RATEMCS0                         0x00
+#define DESC90_RATEMCS1                         0x01
+#define DESC90_RATEMCS2                         0x02
+#define DESC90_RATEMCS3                         0x03
+#define DESC90_RATEMCS4                         0x04
+#define DESC90_RATEMCS5                         0x05
+#define DESC90_RATEMCS6                         0x06
+#define DESC90_RATEMCS7                         0x07
+#define DESC90_RATEMCS8                         0x08
+#define DESC90_RATEMCS9                         0x09
+#define DESC90_RATEMCS10                        0x0a
+#define DESC90_RATEMCS11                        0x0b
+#define DESC90_RATEMCS12                        0x0c
+#define DESC90_RATEMCS13                        0x0d
+#define DESC90_RATEMCS14                        0x0e
+#define DESC90_RATEMCS15                        0x0f
+#define DESC90_RATEMCS32                        0x20
+
+#define RTL819X_DEFAULT_RF_TYPE RF_1T2R
+
+#define IEEE80211_WATCH_DOG_TIME    2000
+#define		PHY_Beacon_RSSI_SLID_WIN_MAX		10
+//for txpowertracking by amy
+#define 	OFDM_Table_Length	19
+#define	CCK_Table_length	12
+
+/* for rtl819x */
+typedef struct _tx_desc_819x_usb {
+        //DWORD 0
+        u16	PktSize;
+        u8	Offset;
+        u8	Reserved0:3;
+        u8	CmdInit:1;
+        u8	LastSeg:1;
+        u8	FirstSeg:1;
+        u8	LINIP:1;
+        u8	OWN:1;
+
+        //DWORD 1
+        u8	TxFWInfoSize;
+        u8	RATid:3;
+        u8	DISFB:1;
+        u8	USERATE:1;
+        u8	MOREFRAG:1;
+        u8	NoEnc:1;
+        u8	PIFS:1;
+        u8	QueueSelect:5;
+        u8	NoACM:1;
+        u8	Reserved1:2;
+        u8	SecCAMID:5;
+        u8	SecDescAssign:1;
+        u8	SecType:2;
+
+        //DWORD 2
+        u16	TxBufferSize;
+        //u16 Reserved2;
+        u8	ResvForPaddingLen:7;
+        u8	Reserved3:1;
+        u8	Reserved4;
+
+        //DWORD 3, 4, 5
+        u32	Reserved5;
+        u32	Reserved6;
+        u32	Reserved7;
+}tx_desc_819x_usb, *ptx_desc_819x_usb;
+
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+typedef struct _tx_desc_819x_usb_aggr_subframe {
+	//DWORD 0
+	u16	PktSize;
+	u8	Offset;
+	u8	TxFWInfoSize;
+
+	//DWORD 1
+	u8	RATid:3;
+	u8	DISFB:1;
+	u8	USERATE:1;
+	u8	MOREFRAG:1;
+	u8	NoEnc:1;
+	u8	PIFS:1;
+	u8	QueueSelect:5;
+	u8	NoACM:1;
+	u8	Reserved1:2;
+	u8	SecCAMID:5;
+	u8	SecDescAssign:1;
+	u8	SecType:2;
+	u8	PacketID:7;
+	u8	OWN:1;
+}tx_desc_819x_usb_aggr_subframe, *ptx_desc_819x_usb_aggr_subframe;
+#endif
+
+
+
+typedef struct _tx_desc_cmd_819x_usb {
+        //DWORD 0
+	u16	Reserved0;
+	u8	Reserved1;
+	u8	Reserved2:3;
+	u8	CmdInit:1;
+	u8	LastSeg:1;
+	u8	FirstSeg:1;
+	u8	LINIP:1;
+	u8	OWN:1;
+
+        //DOWRD 1
+	//u32	Reserved3;
+	u8	TxFWInfoSize;
+	u8	Reserved3;
+	u8	QueueSelect;
+	u8	Reserved4;
+
+        //DOWRD 2
+	u16 	TxBufferSize;
+	u16	Reserved5;
+
+       //DWORD 3,4,5
+	//u32	TxBufferAddr;
+	//u32	NextDescAddress;
+	u32	Reserved6;
+	u32	Reserved7;
+	u32	Reserved8;
+}tx_desc_cmd_819x_usb, *ptx_desc_cmd_819x_usb;
+
+
+typedef struct _tx_fwinfo_819x_usb {
+        //DOWRD 0
+        u8		TxRate:7;
+        u8		CtsEnable:1;
+        u8		RtsRate:7;
+        u8		RtsEnable:1;
+        u8		TxHT:1;
+        u8		Short:1;                //Short PLCP for CCK, or short GI for 11n MCS
+        u8		TxBandwidth:1;          // This is used for HT MCS rate only.
+        u8		TxSubCarrier:2;         // This is used for legacy OFDM rate only.
+        u8		STBC:2;
+        u8		AllowAggregation:1;
+        u8		RtsHT:1;                //Interpre RtsRate field as high throughput data rate
+        u8		RtsShort:1;             //Short PLCP for CCK, or short GI for 11n MCS
+        u8		RtsBandwidth:1;         // This is used for HT MCS rate only.
+        u8		RtsSubcarrier:2;        // This is used for legacy OFDM rate only.
+        u8		RtsSTBC:2;
+        u8		EnableCPUDur:1;         //Enable firmware to recalculate and assign packet duration
+
+        //DWORD 1
+        u32		RxMF:2;
+        u32		RxAMD:3;
+        u32		TxPerPktInfoFeedback:1;//1 indicate Tx info gathtered by firmware and returned by Rx Cmd
+        u32		Reserved1:2;
+        u32		TxAGCOffSet:4;
+        u32		TxAGCSign:1;
+        u32		Tx_INFO_RSVD:6;
+	u32		PacketID:13;
+        //u32                Reserved;
+}tx_fwinfo_819x_usb, *ptx_fwinfo_819x_usb;
+
+typedef struct rtl8192_rx_info {
+	struct urb *urb;
+	struct net_device *dev;
+	u8 out_pipe;
+}rtl8192_rx_info ;
+
+typedef struct rx_desc_819x_usb{
+	//DOWRD 0
+	u16                 Length:14;
+	u16                 CRC32:1;
+	u16                 ICV:1;
+	u8                  RxDrvInfoSize;
+	u8                  Shift:2;
+	u8                  PHYStatus:1;
+	u8                  SWDec:1;
+	//u8                LastSeg:1;
+	//u8                FirstSeg:1;
+	//u8                EOR:1;
+	//u8                OWN:1;
+	u8                  Reserved1:4;
+
+	//DWORD 1
+	u32                 Reserved2;
+
+	//DWORD 2
+	//u32               Reserved3;
+
+	//DWORD 3
+	//u32                BufferAddress;
+
+}rx_desc_819x_usb, *prx_desc_819x_usb;
+
+#ifdef USB_RX_AGGREGATION_SUPPORT
+typedef struct _rx_desc_819x_usb_aggr_subframe{
+	//DOWRD 0
+	u16			Length:14;
+	u16			CRC32:1;
+	u16			ICV:1;
+	u8			Offset;
+	u8			RxDrvInfoSize;
+	//DOWRD 1
+	u8			Shift:2;
+	u8			PHYStatus:1;
+	u8			SWDec:1;
+	u8			Reserved1:4;
+	u8			Reserved2;
+	u16			Reserved3;
+	//DWORD 2
+	//u4Byte		Reserved3;
+	//DWORD 3
+	//u4Byte           	BufferAddress;
+}rx_desc_819x_usb_aggr_subframe, *prx_desc_819x_usb_aggr_subframe;
+#endif
+
+typedef struct rx_drvinfo_819x_usb{
+	//DWORD 0
+	u16                 Reserved1:12;
+	u16                 PartAggr:1;
+	u16                 FirstAGGR:1;
+	u16                 Reserved2:2;
+
+	u8                  RxRate:7;
+	u8                  RxHT:1;
+
+	u8                  BW:1;
+	u8                  SPLCP:1;
+	u8                  Reserved3:2;
+	u8                  PAM:1;
+	u8                  Mcast:1;
+	u8                  Bcast:1;
+	u8                  Reserved4:1;
+
+	//DWORD 1
+	u32                  TSFL;
+
+}rx_drvinfo_819x_usb, *prx_drvinfo_819x_usb;
+
+
+#define MAX_DEV_ADDR_SIZE		8  /* support till 64 bit bus width OS */
+#define MAX_FIRMWARE_INFORMATION_SIZE   32 /*2006/04/30 by Emily forRTL8190*/
+#define MAX_802_11_HEADER_LENGTH        (40 + MAX_FIRMWARE_INFORMATION_SIZE)
+#define ENCRYPTION_MAX_OVERHEAD		128
+#define	USB_HWDESC_HEADER_LEN		sizeof(tx_desc_819x_usb)
+#define TX_PACKET_SHIFT_BYTES 	  	(USB_HWDESC_HEADER_LEN + sizeof(tx_fwinfo_819x_usb))
+#define MAX_FRAGMENT_COUNT		8
+#ifdef RTL8192U
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+#define MAX_TRANSMIT_BUFFER_SIZE			32000
+#else
+#define MAX_TRANSMIT_BUFFER_SIZE			8000
+#endif
+#else
+#define MAX_TRANSMIT_BUFFER_SIZE  	(1600+(MAX_802_11_HEADER_LENGTH+ENCRYPTION_MAX_OVERHEAD)*MAX_FRAGMENT_COUNT)
+#endif
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+#define TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES (sizeof(tx_desc_819x_usb_aggr_subframe) + sizeof(tx_fwinfo_819x_usb))
+#endif
+#define scrclng					4		// octets for crc32 (FCS, ICV)
+
+typedef enum rf_optype
+{
+	RF_OP_By_SW_3wire = 0,
+	RF_OP_By_FW,
+	RF_OP_MAX
+}rf_op_type;
+/* 8190 Loopback Mode definition */
+typedef enum _rtl819xUsb_loopback{
+	RTL819xU_NO_LOOPBACK = 0,
+	RTL819xU_MAC_LOOPBACK = 1,
+	RTL819xU_DMA_LOOPBACK = 2,
+	RTL819xU_CCK_LOOPBACK = 3,
+}rtl819xUsb_loopback_e;
+
+/* due to rtl8192 firmware */
+typedef enum _desc_packet_type_e{
+	DESC_PACKET_TYPE_INIT = 0,
+	DESC_PACKET_TYPE_NORMAL = 1,
+}desc_packet_type_e;
+
+typedef enum _firmware_source{
+	FW_SOURCE_IMG_FILE = 0,
+	FW_SOURCE_HEADER_FILE = 1,		//from header file
+}firmware_source_e, *pfirmware_source_e;
+
+typedef enum _firmware_status{
+	FW_STATUS_0_INIT = 0,
+	FW_STATUS_1_MOVE_BOOT_CODE = 1,
+	FW_STATUS_2_MOVE_MAIN_CODE = 2,
+	FW_STATUS_3_TURNON_CPU = 3,
+	FW_STATUS_4_MOVE_DATA_CODE = 4,
+	FW_STATUS_5_READY = 5,
+}firmware_status_e;
+
+typedef struct _rt_firmare_seg_container {
+	u16	seg_size;
+	u8	*seg_ptr;
+}fw_seg_container, *pfw_seg_container;
+typedef struct _rt_firmware{
+	firmware_status_e firmware_status;
+	u16               cmdpacket_frag_thresold;
+#define RTL8190_MAX_FIRMWARE_CODE_SIZE  64000   //64k
+	u8                firmware_buf[RTL8190_MAX_FIRMWARE_CODE_SIZE];
+	u16               firmware_buf_size;
+}rt_firmware, *prt_firmware;
+
+//+by amy 080507
+#define MAX_RECEIVE_BUFFER_SIZE	9100	// Add this to 9100 bytes to receive A-MSDU from RT-AP
+
+typedef struct _rt_firmware_info_819xUsb{
+	u8		sz_info[16];
+}rt_firmware_info_819xUsb, *prt_firmware_info_819xUsb;
+
+/* Firmware Queue Layout */
+#define NUM_OF_FIRMWARE_QUEUE		10
+#define NUM_OF_PAGES_IN_FW		0x100
+
+#ifdef USE_ONE_PIPE
+#define NUM_OF_PAGE_IN_FW_QUEUE_BE	0x000
+#define NUM_OF_PAGE_IN_FW_QUEUE_BK	0x000
+#define NUM_OF_PAGE_IN_FW_QUEUE_VI	0x0ff
+#define NUM_OF_PAGE_IN_FW_QUEUE_VO	0x000
+#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA	0
+#define NUM_OF_PAGE_IN_FW_QUEUE_CMD	0x0
+#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT	0x00
+#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH	0
+#define NUM_OF_PAGE_IN_FW_QUEUE_BCN	0x0
+#define NUM_OF_PAGE_IN_FW_QUEUE_PUB	0x00
+#else
+
+#define NUM_OF_PAGE_IN_FW_QUEUE_BE	0x020
+#define NUM_OF_PAGE_IN_FW_QUEUE_BK	0x020
+#define NUM_OF_PAGE_IN_FW_QUEUE_VI	0x040
+#define NUM_OF_PAGE_IN_FW_QUEUE_VO	0x040
+#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA	0
+#define NUM_OF_PAGE_IN_FW_QUEUE_CMD	0x4
+#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT	0x20
+#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH	0
+#define NUM_OF_PAGE_IN_FW_QUEUE_BCN	0x4
+#define NUM_OF_PAGE_IN_FW_QUEUE_PUB	0x18
+
+#endif
+
+#define APPLIED_RESERVED_QUEUE_IN_FW	0x80000000
+#define RSVD_FW_QUEUE_PAGE_BK_SHIFT	0x00
+#define RSVD_FW_QUEUE_PAGE_BE_SHIFT	0x08
+#define RSVD_FW_QUEUE_PAGE_VI_SHIFT	0x10
+#define RSVD_FW_QUEUE_PAGE_VO_SHIFT	0x18
+#define RSVD_FW_QUEUE_PAGE_MGNT_SHIFT	0x10
+#define RSVD_FW_QUEUE_PAGE_CMD_SHIFT	0x08
+#define RSVD_FW_QUEUE_PAGE_BCN_SHIFT	0x00
+#define RSVD_FW_QUEUE_PAGE_PUB_SHIFT	0x08
+//=================================================================
+//=================================================================
+
+#define EPROM_93c46 0
+#define EPROM_93c56 1
+
+#define DEFAULT_FRAG_THRESHOLD 2342U
+#define MIN_FRAG_THRESHOLD     256U
+#define DEFAULT_BEACONINTERVAL 0x64U
+#define DEFAULT_BEACON_ESSID "Rtl819xU"
+
+#define DEFAULT_SSID ""
+#define DEFAULT_RETRY_RTS 7
+#define DEFAULT_RETRY_DATA 7
+#define PRISM_HDR_SIZE 64
+
+#define		PHY_RSSI_SLID_WIN_MAX				100
+
+
+typedef enum _WIRELESS_MODE {
+	WIRELESS_MODE_UNKNOWN = 0x00,
+	WIRELESS_MODE_A = 0x01,
+	WIRELESS_MODE_B = 0x02,
+	WIRELESS_MODE_G = 0x04,
+	WIRELESS_MODE_AUTO = 0x08,
+	WIRELESS_MODE_N_24G = 0x10,
+	WIRELESS_MODE_N_5G = 0x20
+} WIRELESS_MODE;
+
+
+#define RTL_IOCTL_WPA_SUPPLICANT		SIOCIWFIRSTPRIV+30
+
+typedef struct buffer
+{
+	struct buffer *next;
+	u32 *buf;
+
+} buffer;
+
+typedef struct rtl_reg_debug{
+        unsigned int  cmd;
+        struct {
+                unsigned char type;
+                unsigned char addr;
+                unsigned char page;
+                unsigned char length;
+        } head;
+        unsigned char buf[0xff];
+}rtl_reg_debug;
+
+
+
+
+
+
+typedef struct _rt_9x_tx_rate_history {
+	u32             cck[4];
+	u32             ofdm[8];
+	// HT_MCS[0][]: BW=0 SG=0
+	// HT_MCS[1][]: BW=1 SG=0
+	// HT_MCS[2][]: BW=0 SG=1
+	// HT_MCS[3][]: BW=1 SG=1
+	u32             ht_mcs[4][16];
+}rt_tx_rahis_t, *prt_tx_rahis_t;
+typedef struct _RT_SMOOTH_DATA_4RF {
+	char    elements[4][100];//array to store values
+	u32     index;                  //index to current array to store
+	u32     TotalNum;               //num of valid elements
+	u32     TotalVal[4];            //sum of valid elements
+}RT_SMOOTH_DATA_4RF, *PRT_SMOOTH_DATA_4RF;
+
+#define MAX_8192U_RX_SIZE			8192    // This maybe changed for D-cut larger aggregation size
+//stats seems messed up, clean it ASAP
+typedef struct Stats
+{
+	unsigned long txrdu;
+//	unsigned long rxrdu;
+	//unsigned long rxnolast;
+	//unsigned long rxnodata;
+//	unsigned long rxreset;
+//	unsigned long rxnopointer;
+	unsigned long rxok;
+	unsigned long rxframgment;
+	unsigned long rxcmdpkt[4];		//08/05/08 amy rx cmd element txfeedback/bcn report/cfg set/query
+	unsigned long rxurberr;
+	unsigned long rxstaterr;
+	unsigned long received_rate_histogram[4][32];	//0: Total, 1:OK, 2:CRC, 3:ICV, 2007 07 03 cosa
+	unsigned long received_preamble_GI[2][32];		//0: Long preamble/GI, 1:Short preamble/GI
+	unsigned long rx_AMPDUsize_histogram[5]; // level: (<4K), (4K~8K), (8K~16K), (16K~32K), (32K~64K)
+	unsigned long rx_AMPDUnum_histogram[5]; // level: (<5), (5~10), (10~20), (20~40), (>40)
+	unsigned long numpacket_matchbssid;	// debug use only.
+	unsigned long numpacket_toself;		// debug use only.
+	unsigned long num_process_phyinfo;		// debug use only.
+	unsigned long numqry_phystatus;
+	unsigned long numqry_phystatusCCK;
+	unsigned long numqry_phystatusHT;
+	unsigned long received_bwtype[5];              //0: 20M, 1: funn40M, 2: upper20M, 3: lower20M, 4: duplicate
+	unsigned long txnperr;
+	unsigned long txnpdrop;
+	unsigned long txresumed;
+//	unsigned long rxerr;
+//	unsigned long rxoverflow;
+//	unsigned long rxint;
+	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 txlpdrop;
+	unsigned long txlperr;
+	unsigned long txbeokint;
+	unsigned long txbedrop;
+	unsigned long txbeerr;
+	unsigned long txbkokint;
+	unsigned long txbkdrop;
+	unsigned long txbkerr;
+	unsigned long txviokint;
+	unsigned long txvidrop;
+	unsigned long txvierr;
+	unsigned long txvookint;
+	unsigned long txvodrop;
+	unsigned long txvoerr;
+	unsigned long txbeaconokint;
+	unsigned long txbeacondrop;
+	unsigned long txbeaconerr;
+	unsigned long txmanageokint;
+	unsigned long txmanagedrop;
+	unsigned long txmanageerr;
+	unsigned long txdatapkt;
+	unsigned long txfeedback;
+	unsigned long txfeedbackok;
+
+	unsigned long txoktotal;
+	unsigned long txokbytestotal;
+	unsigned long txokinperiod;
+	unsigned long txmulticast;
+	unsigned long txbytesmulticast;
+	unsigned long txbroadcast;
+	unsigned long txbytesbroadcast;
+	unsigned long txunicast;
+	unsigned long txbytesunicast;
+
+	unsigned long rxoktotal;
+	unsigned long rxbytesunicast;
+	unsigned long txfeedbackfail;
+	unsigned long txerrtotal;
+	unsigned long txerrbytestotal;
+	unsigned long txerrmulticast;
+	unsigned long txerrbroadcast;
+	unsigned long txerrunicast;
+	unsigned long txretrycount;
+	unsigned long txfeedbackretry;
+	u8	      last_packet_rate;
+	unsigned long slide_signal_strength[100];
+	unsigned long slide_evm[100];
+	unsigned long slide_rssi_total;	// For recording sliding window's RSSI value
+	unsigned long slide_evm_total;	// For recording sliding window's EVM value
+	long signal_strength; // Transformed, in dbm. Beautified signal strength for UI, not correct.
+	long signal_quality;
+	long last_signal_strength_inpercent;
+	long recv_signal_power;	// Correct smoothed ss in Dbm, only used in driver to report real power now.
+	u8 rx_rssi_percentage[4];
+	u8 rx_evm_percentage[2];
+	long rxSNRdB[4];
+	rt_tx_rahis_t txrate;
+	u32 Slide_Beacon_pwdb[100];     //cosa add for beacon rssi
+	u32 Slide_Beacon_Total;         //cosa add for beacon rssi
+	RT_SMOOTH_DATA_4RF              cck_adc_pwdb;
+
+	u32	CurrentShowTxate;
+} Stats;
+
+
+// Bandwidth Offset
+#define HAL_PRIME_CHNL_OFFSET_DONT_CARE		0
+#define HAL_PRIME_CHNL_OFFSET_LOWER			1
+#define HAL_PRIME_CHNL_OFFSET_UPPER			2
+
+//+by amy 080507
+
+typedef struct 	ChnlAccessSetting {
+	u16 SIFS_Timer;
+	u16 DIFS_Timer;
+	u16 SlotTimeTimer;
+	u16 EIFS_Timer;
+	u16 CWminIndex;
+	u16 CWmaxIndex;
+}*PCHANNEL_ACCESS_SETTING,CHANNEL_ACCESS_SETTING;
+
+typedef struct _BB_REGISTER_DEFINITION{
+	u32 rfintfs; 			// set software control: //		0x870~0x877[8 bytes]
+	u32 rfintfi; 			// readback data: //		0x8e0~0x8e7[8 bytes]
+	u32 rfintfo; 			// output data: //		0x860~0x86f [16 bytes]
+	u32 rfintfe; 			// output enable: //		0x860~0x86f [16 bytes]
+	u32 rf3wireOffset; 		// LSSI data: //		0x840~0x84f [16 bytes]
+	u32 rfLSSI_Select; 		// BB Band Select: //		0x878~0x87f [8 bytes]
+	u32 rfTxGainStage;		// Tx gain stage: //		0x80c~0x80f [4 bytes]
+	u32 rfHSSIPara1; 		// wire parameter control1 : //		0x820~0x823,0x828~0x82b, 0x830~0x833, 0x838~0x83b [16 bytes]
+	u32 rfHSSIPara2; 		// wire parameter control2 : //		0x824~0x827,0x82c~0x82f, 0x834~0x837, 0x83c~0x83f [16 bytes]
+	u32 rfSwitchControl; 	//Tx Rx antenna control : //		0x858~0x85f [16 bytes]
+	u32 rfAGCControl1; 	//AGC parameter control1 : //		0xc50~0xc53,0xc58~0xc5b, 0xc60~0xc63, 0xc68~0xc6b [16 bytes]
+	u32 rfAGCControl2; 	//AGC parameter control2 : //		0xc54~0xc57,0xc5c~0xc5f, 0xc64~0xc67, 0xc6c~0xc6f [16 bytes]
+	u32 rfRxIQImbalance; 	//OFDM Rx IQ imbalance matrix : //		0xc14~0xc17,0xc1c~0xc1f, 0xc24~0xc27, 0xc2c~0xc2f [16 bytes]
+	u32 rfRxAFE;  			//Rx IQ DC ofset and Rx digital filter, Rx DC notch filter : //		0xc10~0xc13,0xc18~0xc1b, 0xc20~0xc23, 0xc28~0xc2b [16 bytes]
+	u32 rfTxIQImbalance; 	//OFDM Tx IQ imbalance matrix //		0xc80~0xc83,0xc88~0xc8b, 0xc90~0xc93, 0xc98~0xc9b [16 bytes]
+	u32 rfTxAFE; 			//Tx IQ DC Offset and Tx DFIR type //		0xc84~0xc87,0xc8c~0xc8f, 0xc94~0xc97, 0xc9c~0xc9f [16 bytes]
+	u32 rfLSSIReadBack; 	//LSSI RF readback data //		0x8a0~0x8af [16 bytes]
+}BB_REGISTER_DEFINITION_T, *PBB_REGISTER_DEFINITION_T;
+
+typedef enum _RT_RF_TYPE_819xU{
+        RF_TYPE_MIN = 0,
+        RF_8225,
+        RF_8256,
+        RF_8258,
+        RF_PSEUDO_11N = 4,
+}RT_RF_TYPE_819xU, *PRT_RF_TYPE_819xU;
+
+typedef struct _rate_adaptive
+{
+	u8				rate_adaptive_disabled;
+	u8				ratr_state;
+	u16				reserve;
+
+	u32				high_rssi_thresh_for_ra;
+	u32				high2low_rssi_thresh_for_ra;
+	u8				low2high_rssi_thresh_for_ra40M;
+	u32				low_rssi_thresh_for_ra40M;
+	u8				low2high_rssi_thresh_for_ra20M;
+	u32				low_rssi_thresh_for_ra20M;
+	u32				upper_rssi_threshold_ratr;
+	u32				middle_rssi_threshold_ratr;
+	u32				low_rssi_threshold_ratr;
+	u32				low_rssi_threshold_ratr_40M;
+	u32				low_rssi_threshold_ratr_20M;
+	u8				ping_rssi_enable;	//cosa add for test
+	u32				ping_rssi_ratr;	//cosa add for test
+	u32				ping_rssi_thresh_for_ra;//cosa add for test
+	u32				last_ratr;
+
+} rate_adaptive, *prate_adaptive;
+
+#define TxBBGainTableLength 37
+#define	CCKTxBBGainTableLength 23
+
+typedef struct _txbbgain_struct
+{
+	long	txbb_iq_amplifygain;
+	u32	txbbgain_value;
+} txbbgain_struct, *ptxbbgain_struct;
+
+typedef struct _ccktxbbgain_struct
+{
+	//The Value is from a22 to a29 one Byte one time is much Safer
+	u8	ccktxbb_valuearray[8];
+} ccktxbbgain_struct,*pccktxbbgain_struct;
+
+
+typedef struct _init_gain
+{
+	u8				xaagccore1;
+	u8				xbagccore1;
+	u8				xcagccore1;
+	u8				xdagccore1;
+	u8				cca;
+
+} init_gain, *pinit_gain;
+//by amy 0606
+
+typedef struct _phy_ofdm_rx_status_report_819xusb
+{
+	u8	trsw_gain_X[4];
+	u8	pwdb_all;
+	u8	cfosho_X[4];
+	u8	cfotail_X[4];
+	u8	rxevm_X[2];
+	u8	rxsnr_X[4];
+	u8	pdsnr_X[2];
+	u8	csi_current_X[2];
+	u8	csi_target_X[2];
+	u8	sigevm;
+	u8	max_ex_pwr;
+	u8	sgi_en;
+	u8  rxsc_sgien_exflg;
+}phy_sts_ofdm_819xusb_t;
+
+typedef struct _phy_cck_rx_status_report_819xusb
+{
+	/* For CCK rate descriptor. This is a unsigned 8:1 variable. LSB bit presend
+	   0.5. And MSB 7 bts presend a signed value. Range from -64~+63.5. */
+	u8	adc_pwdb_X[4];
+	u8	sq_rpt;
+	u8	cck_agc_rpt;
+}phy_sts_cck_819xusb_t;
+
+
+typedef struct _phy_ofdm_rx_status_rxsc_sgien_exintfflag{
+	u8			reserved:4;
+	u8			rxsc:2;
+	u8			sgi_en:1;
+	u8			ex_intf_flag:1;
+}phy_ofdm_rx_status_rxsc_sgien_exintfflag;
+
+typedef enum _RT_CUSTOMER_ID
+{
+	RT_CID_DEFAULT = 0,
+	RT_CID_8187_ALPHA0 = 1,
+	RT_CID_8187_SERCOMM_PS = 2,
+	RT_CID_8187_HW_LED = 3,
+	RT_CID_8187_NETGEAR = 4,
+	RT_CID_WHQL = 5,
+	RT_CID_819x_CAMEO  = 6,
+	RT_CID_819x_RUNTOP = 7,
+	RT_CID_819x_Senao = 8,
+	RT_CID_TOSHIBA = 9,	// Merge by Jacken, 2008/01/31.
+	RT_CID_819x_Netcore = 10,
+	RT_CID_Nettronix = 11,
+	RT_CID_DLINK = 12,
+	RT_CID_PRONET = 13,
+}RT_CUSTOMER_ID, *PRT_CUSTOMER_ID;
+
+//================================================================================
+// LED customization.
+//================================================================================
+
+typedef	enum _LED_STRATEGY_8190{
+	SW_LED_MODE0, // SW control 1 LED via GPIO0. It is default option.
+	SW_LED_MODE1, // SW control for PCI Express
+	SW_LED_MODE2, // SW control for Cameo.
+	SW_LED_MODE3, // SW contorl for RunTop.
+	SW_LED_MODE4, // SW control for Netcore
+	HW_LED, // HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes)
+}LED_STRATEGY_8190, *PLED_STRATEGY_8190;
+
+typedef enum _RESET_TYPE {
+	RESET_TYPE_NORESET = 0x00,
+	RESET_TYPE_NORMAL = 0x01,
+	RESET_TYPE_SILENT = 0x02
+} RESET_TYPE;
+
+/* The simple tx command OP code. */
+typedef enum _tag_TxCmd_Config_Index{
+	TXCMD_TXRA_HISTORY_CTRL				= 0xFF900000,
+	TXCMD_RESET_TX_PKT_BUFF				= 0xFF900001,
+	TXCMD_RESET_RX_PKT_BUFF				= 0xFF900002,
+	TXCMD_SET_TX_DURATION				= 0xFF900003,
+	TXCMD_SET_RX_RSSI						= 0xFF900004,
+	TXCMD_SET_TX_PWR_TRACKING			= 0xFF900005,
+	TXCMD_XXXX_CTRL,
+}DCMD_TXCMD_OP;
+
+typedef struct r8192_priv
+{
+	struct usb_device *udev;
+	//added for maintain info from eeprom
+	short epromtype;
+	u16 eeprom_vid;
+	u16 eeprom_pid;
+	u8  eeprom_CustomerID;
+	u8  eeprom_ChannelPlan;
+	RT_CUSTOMER_ID CustomerID;
+	LED_STRATEGY_8190	LedStrategy;
+	u8  txqueue_to_outpipemap[9];
+	int irq;
+	struct ieee80211_device *ieee80211;
+
+	short card_8192; /* O: rtl8192, 1:rtl8185 V B/C, 2:rtl8185 V D */
+	u8 card_8192_version; /* if TCR reports card V B/C this discriminates */
+//	short phy_ver; /* meaningful for rtl8225 1:A 2:B 3:C */
+	short enable_gpio0;
+	enum card_type {PCI,MINIPCI,CARDBUS,USB}card_type;
+	short hw_plcp_len;
+	short plcp_preamble_mode;
+
+	spinlock_t irq_lock;
+//	spinlock_t irq_th_lock;
+	spinlock_t tx_lock;
+        struct mutex mutex;
+	//spinlock_t rf_lock; //used to lock rf write operation added by wb
+
+	u16 irq_mask;
+//	short irq_enabled;
+//	struct net_device *dev; //comment this out.
+	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 cck_txpwr_base;
+//	u8 ofdm_txpwr_base;
+//	u8 challow[15]; //channels from 1 to 14, 0 not used
+	short up;
+	short crcmon; //if 1 allow bad crc frame reception in monitor mode
+//	short prism_hdr;
+
+//	struct timer_list scan_timer;
+	/*short scanpending;
+	short stopscan;*/
+//	spinlock_t scan_lock;
+//	u8 active_probe;
+	//u8 active_scan_num;
+	struct semaphore wx_sem;
+	struct semaphore rf_sem; //used to lock rf write operation added by wb, modified by david
+//	short hw_wep;
+
+//	short digphy;
+//	short antb;
+//	short diversity;
+//	u8 cs_treshold;
+//	short rcr_csense;
+	u8 rf_type; //0 means 1T2R, 1 means 2T4R
+	RT_RF_TYPE_819xU rf_chip;
+
+//	u32 key0[4];
+	short (*rf_set_sens)(struct net_device *dev,short sens);
+	u8 (*rf_set_chan)(struct net_device *dev,u8 ch);
+	void (*rf_close)(struct net_device *dev);
+	void (*rf_init)(struct net_device *dev);
+	//short rate;
+	short promisc;
+	/*stats*/
+	struct Stats stats;
+	struct iw_statistics wstats;
+	struct proc_dir_entry *dir_dev;
+
+	/*RX stuff*/
+//	u32 *rxring;
+//	u32 *rxringtail;
+//	dma_addr_t rxringdma;
+	struct urb **rx_urb;
+	struct urb **rx_cmd_urb;
+#ifdef THOMAS_BEACON
+	u32 *oldaddr;
+#endif
+#ifdef THOMAS_TASKLET
+	atomic_t irt_counter;//count for irq_rx_tasklet
+#endif
+#ifdef JACKSON_NEW_RX
+        struct sk_buff **pp_rxskb;
+        int     rx_inx;
+#endif
+
+/* modified by davad for Rx process */
+       struct sk_buff_head rx_queue;
+       struct sk_buff_head skb_queue;
+       struct work_struct qos_activate;
+	short  tx_urb_index;
+	atomic_t tx_pending[0x10];//UART_PRIORITY+1
+
+
+	struct tasklet_struct irq_rx_tasklet;
+	struct urb *rxurb_task;
+
+	//2 Tx Related variables
+	u16	ShortRetryLimit;
+	u16	LongRetryLimit;
+	u32	TransmitConfig;
+	u8	RegCWinMin;		// For turbo mode CW adaptive. Added by Annie, 2005-10-27.
+
+	u32     LastRxDescTSFHigh;
+	u32     LastRxDescTSFLow;
+
+
+	//2 Rx Related variables
+	u16	EarlyRxThreshold;
+	u32	ReceiveConfig;
+	u8	AcmControl;
+
+	u8	RFProgType;
+
+	u8 retry_data;
+	u8 retry_rts;
+	u16 rts;
+
+	struct 	ChnlAccessSetting  ChannelAccessSetting;
+	struct work_struct reset_wq;
+
+/**********************************************************/
+	//for rtl819xUsb
+	u16     basic_rate;
+	u8      short_preamble;
+	u8      slot_time;
+	bool 	bDcut;
+	bool bCurrentRxAggrEnable;
+	u8 Rf_Mode; //add for Firmware RF -R/W switch
+	prt_firmware		pFirmware;
+	rtl819xUsb_loopback_e	LoopbackMode;
+	firmware_source_e	firmware_source;
+	u16 EEPROMTxPowerDiff;
+	u8 EEPROMThermalMeter;
+	u8 EEPROMPwDiff;
+	u8 EEPROMCrystalCap;
+	u8 EEPROM_Def_Ver;
+	u8 EEPROMTxPowerLevelCCK;// CCK channel 1~14
+	u8 EEPROMTxPowerLevelCCK_V1[3];
+	u8 EEPROMTxPowerLevelOFDM24G[3]; // OFDM 2.4G channel 1~14
+	u8 EEPROMTxPowerLevelOFDM5G[24];	// OFDM 5G
+
+/*PHY related*/
+	BB_REGISTER_DEFINITION_T	PHYRegDef[4];	//Radio A/B/C/D
+	// Read/write are allow for following hardware information variables
+	u32	MCSTxPowerLevelOriginalOffset[6];
+	u32	CCKTxPowerLevelOriginalOffset;
+	u8	TxPowerLevelCCK[14];			// CCK channel 1~14
+	u8	TxPowerLevelOFDM24G[14];		// OFDM 2.4G channel 1~14
+	u8	TxPowerLevelOFDM5G[14];			// OFDM 5G
+	u32	Pwr_Track;
+	u8	TxPowerDiff;
+	u8	AntennaTxPwDiff[2];				// Antenna gain offset, index 0 for B, 1 for C, and 2 for D
+	u8	CrystalCap;						// CrystalCap.
+	u8	ThermalMeter[2];				// ThermalMeter, index 0 for RFIC0, and 1 for RFIC1
+
+	u8	CckPwEnl;
+	// Use to calculate PWBD.
+	u8	bCckHighPower;
+	long	undecorated_smoothed_pwdb;
+
+	//for set channel
+	u8	SwChnlInProgress;
+	u8 	SwChnlStage;
+	u8	SwChnlStep;
+	u8	SetBWModeInProgress;
+	HT_CHANNEL_WIDTH		CurrentChannelBW;
+	u8      ChannelPlan;
+	// 8190 40MHz mode
+	//
+	u8	nCur40MhzPrimeSC;	// Control channel sub-carrier
+	// Joseph test for shorten RF configuration time.
+	// We save RF reg0 in this variable to reduce RF reading.
+	//
+	u32					RfReg0Value[4];
+	u8 					NumTotalRFPath;
+	bool 				brfpath_rxenable[4];
+	//RF set related
+	bool				SetRFPowerStateInProgress;
+//+by amy 080507
+	struct timer_list watch_dog_timer;
+
+//+by amy 080515 for dynamic mechenism
+	//Add by amy Tx Power Control for Near/Far Range 2008/05/15
+	bool	bdynamic_txpower;  //bDynamicTxPower
+	bool	bDynamicTxHighPower;  // Tx high power state
+	bool	bDynamicTxLowPower;  // Tx low power state
+	bool	bLastDTPFlag_High;
+	bool	bLastDTPFlag_Low;
+
+	bool	bstore_last_dtpflag;
+	bool	bstart_txctrl_bydtp;   //Define to discriminate on High power State or on sitesuvey to change Tx gain index
+	//Add by amy for Rate Adaptive
+	rate_adaptive rate_adaptive;
+	//Add by amy for TX power tracking
+	//2008/05/15  Mars OPEN/CLOSE TX POWER TRACKING
+       txbbgain_struct txbbgain_table[TxBBGainTableLength];
+	u8			   txpower_count;//For 6 sec do tracking again
+	bool			   btxpower_trackingInit;
+	u8			   OFDM_index;
+	u8			   CCK_index;
+	//2007/09/10 Mars Add CCK TX Power Tracking
+	ccktxbbgain_struct	cck_txbbgain_table[CCKTxBBGainTableLength];
+	ccktxbbgain_struct	cck_txbbgain_ch14_table[CCKTxBBGainTableLength];
+	u8 rfa_txpowertrackingindex;
+	u8 rfa_txpowertrackingindex_real;
+	u8 rfa_txpowertracking_default;
+	u8 rfc_txpowertrackingindex;
+	u8 rfc_txpowertrackingindex_real;
+
+	s8 cck_present_attentuation;
+	u8 cck_present_attentuation_20Mdefault;
+	u8 cck_present_attentuation_40Mdefault;
+	char cck_present_attentuation_difference;
+	bool btxpower_tracking;
+	bool bcck_in_ch14;
+	bool btxpowerdata_readfromEEPORM;
+	u16 	TSSI_13dBm;
+	//For Backup Initial Gain
+	init_gain initgain_backup;
+	u8 DefaultInitialGain[4];
+	// For EDCA Turbo mode, Added by amy 080515.
+	bool		bis_any_nonbepkts;
+	bool		bcurrent_turbo_EDCA;
+	bool		bis_cur_rdlstate;
+	struct timer_list fsync_timer;
+	bool bfsync_processing;	// 500ms Fsync timer is active or not
+	u32 	rate_record;
+	u32 	rateCountDiffRecord;
+	u32	ContiuneDiffCount;
+	bool bswitch_fsync;
+
+	u8	framesync;
+	u32 	framesyncC34;
+	u8   	framesyncMonitor;
+        	//Added by amy 080516  for RX related
+	u16 	nrxAMPDU_size;
+	u8 	nrxAMPDU_aggr_num;
+
+	//by amy for gpio
+	 bool bHwRadioOff;
+
+	//by amy for reset_count
+	u32 reset_count;
+	bool bpbc_pressed;
+	//by amy for debug
+	u32 txpower_checkcnt;
+	u32 txpower_tracking_callback_cnt;
+	u8 thermal_read_val[40];
+	u8 thermal_readback_index;
+	u32 ccktxpower_adjustcnt_not_ch14;
+	u32 ccktxpower_adjustcnt_ch14;
+	u8 tx_fwinfo_force_subcarriermode;
+	u8 tx_fwinfo_force_subcarrierval;
+	//by amy for silent reset
+	RESET_TYPE	ResetProgress;
+	bool		bForcedSilentReset;
+	bool		bDisableNormalResetCheck;
+	u16		TxCounter;
+	u16		RxCounter;
+	int		IrpPendingCount;
+	bool		bResetInProgress;
+	bool		force_reset;
+	u8		InitialGainOperateType;
+
+	u16		SifsTime;
+
+	//define work item by amy 080526
+
+	struct delayed_work update_beacon_wq;
+	struct delayed_work watch_dog_wq;
+	struct delayed_work txpower_tracking_wq;
+	struct delayed_work rfpath_check_wq;
+	struct delayed_work gpio_change_rf_wq;
+	struct delayed_work initialgain_operate_wq;
+	struct workqueue_struct *priv_wq;
+}r8192_priv;
+
+// for rtl8187
+// now mirging to rtl8187B
+/*
+typedef enum{
+	LOW_PRIORITY = 0x02,
+	NORM_PRIORITY
+	} priority_t;
+*/
+//for rtl8187B
+typedef enum{
+	BULK_PRIORITY = 0x01,
+	//RSVD0,
+	//RSVD1,
+	LOW_PRIORITY,
+	NORM_PRIORITY,
+	VO_PRIORITY,
+	VI_PRIORITY, //0x05
+	BE_PRIORITY,
+	BK_PRIORITY,
+	RSVD2,
+	RSVD3,
+	BEACON_PRIORITY, //0x0A
+	HIGH_PRIORITY,
+	MANAGE_PRIORITY,
+	RSVD4,
+	RSVD5,
+	UART_PRIORITY //0x0F
+} priority_t;
+
+typedef enum{
+	NIC_8192U = 1,
+	NIC_8190P = 2,
+	NIC_8192E = 3,
+	} nic_t;
+
+
+#ifdef JOHN_HWSEC
+struct ssid_thread {
+	struct net_device *dev;
+       	u8 name[IW_ESSID_MAX_SIZE + 1];
+};
+#endif
+
+bool init_firmware(struct net_device *dev);
+short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb);
+short rtl8192_tx(struct net_device *dev, struct sk_buff* skb);
+
+u32 read_cam(struct net_device *dev, u8 addr);
+void write_cam(struct net_device *dev, u8 addr, u32 data);
+
+u8 read_nic_byte(struct net_device *dev, int x);
+u8 read_nic_byte_E(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_byte_E(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 rtl8192_rtx_disable(struct net_device *);
+void rtl8192_rx_enable(struct net_device *);
+void rtl8192_tx_enable(struct net_device *);
+
+void rtl8192_disassociate(struct net_device *dev);
+//void fix_rx_fifo(struct net_device *dev);
+void rtl8185_set_rf_pins_enable(struct net_device *dev,u32 a);
+
+void rtl8192_set_anaparam(struct net_device *dev,u32 a);
+void rtl8185_set_anaparam2(struct net_device *dev,u32 a);
+void rtl8192_update_msr(struct net_device *dev);
+int rtl8192_down(struct net_device *dev);
+int rtl8192_up(struct net_device *dev);
+void rtl8192_commit(struct net_device *dev);
+void rtl8192_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 rtl8192_set_rxconf(struct net_device *dev);
+//short check_nic_enough_desc(struct net_device *dev, priority_t priority);
+extern void rtl819xusb_beacon_tx(struct net_device *dev,u16  tx_rate);
+
+void EnableHWSecurityConfig8192(struct net_device *dev);
+void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, u8 *MacAddr, u8 DefaultKey, u32 *KeyContent );
+
+
+#endif
diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c
new file mode 100644
index 0000000..adade13
--- /dev/null
+++ b/drivers/staging/rtl8192u/r8192U_core.c
@@ -0,0 +1,6085 @@
+/******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192U
+ *
+ * Based on the r8187 driver, which is:
+ * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * Jerry chuang <wlanfae@realtek.com>
+ */
+
+#ifndef CONFIG_FORCE_HARD_FLOAT
+double __floatsidf (int i) { return i; }
+unsigned int __fixunsdfsi (double d) { return d; }
+double __adddf3(double a, double b) { return a+b; }
+double __addsf3(float a, float b) { return a+b; }
+double __subdf3(double a, double b) { return a-b; }
+double __extendsfdf2(float a) {return a;}
+#endif
+
+#undef LOOP_TEST
+#undef DUMP_RX
+#undef DUMP_TX
+#undef DEBUG_TX_DESC2
+#undef RX_DONT_PASS_UL
+#undef DEBUG_EPROM
+#undef DEBUG_RX_VERBOSE
+#undef DUMMY_RX
+#undef DEBUG_ZERO_RX
+#undef DEBUG_RX_SKB
+#undef DEBUG_TX_FRAG
+#undef DEBUG_RX_FRAG
+#undef DEBUG_TX_FILLDESC
+#undef DEBUG_TX
+#undef DEBUG_IRQ
+#undef DEBUG_RX
+#undef DEBUG_RXALLOC
+#undef DEBUG_REGISTERS
+#undef DEBUG_RING
+#undef DEBUG_IRQ_TASKLET
+#undef DEBUG_TX_ALLOC
+#undef DEBUG_TX_DESC
+
+#define CONFIG_RTL8192_IO_MAP
+
+#include <asm/uaccess.h>
+#include "r8192U_hw.h"
+#include "r8192U.h"
+#include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
+#include "r8180_93cx6.h"   /* Card EEPROM */
+#include "r8192U_wx.h"
+#include "r819xU_phy.h" //added by WB 4.30.2008
+#include "r819xU_phyreg.h"
+#include "r819xU_cmdpkt.h"
+#include "r8192U_dm.h"
+//#include "r8192xU_phyreg.h"
+#include <linux/usb.h>
+// FIXME: check if 2.6.7 is ok
+
+#ifdef CONFIG_RTL8192_PM
+#include "r8192_pm.h"
+#endif
+
+#ifdef ENABLE_DOT11D
+#include "dot11d.h"
+#endif
+//set here to open your trace code. //WB
+u32 rt_global_debug_component = \
+			//	COMP_INIT    	|
+//				COMP_DBG	|
+			//	COMP_EPROM   	|
+//				COMP_PHY	|
+			//	COMP_RF		|
+//				COMP_FIRMWARE	|
+//				COMP_CH		|
+			//	COMP_POWER_TRACKING |
+//				COMP_RATE	|
+			//	COMP_TXAGC	|
+		//		COMP_TRACE	|
+				COMP_DOWN	|
+		//		COMP_RECV	|
+		//              COMP_SWBW	|
+				COMP_SEC	|
+	//			COMP_RESET	|
+		//		COMP_SEND	|
+			//	COMP_EVENTS	|
+				COMP_ERR ; //always open err flags on
+
+#define TOTAL_CAM_ENTRY 32
+#define CAM_CONTENT_COUNT 8
+
+static struct usb_device_id rtl8192_usb_id_tbl[] = {
+	/* Realtek */
+	{USB_DEVICE(0x0bda, 0x8192)},
+	{USB_DEVICE(0x0bda, 0x8709)},
+	/* Corega */
+	{USB_DEVICE(0x07aa, 0x0043)},
+	/* Belkin */
+	{USB_DEVICE(0x050d, 0x805E)},
+	/* Sitecom */
+	{USB_DEVICE(0x0df6, 0x0031)},
+	/* EnGenius */
+	{USB_DEVICE(0x1740, 0x9201)},
+	/* Dlink */
+	{USB_DEVICE(0x2001, 0x3301)},
+	/* Zinwell */
+	{USB_DEVICE(0x5a57, 0x0290)},
+	{}
+};
+
+MODULE_LICENSE("GPL");
+MODULE_VERSION("V 1.1");
+MODULE_DEVICE_TABLE(usb, rtl8192_usb_id_tbl);
+MODULE_DESCRIPTION("Linux driver for Realtek RTL8192 USB WiFi cards");
+
+static char* ifname = "wlan%d";
+static int hwwep = 1;  //default use hw. set 0 to use software security
+static int channels = 0x3fff;
+
+
+
+module_param(ifname, charp, S_IRUGO|S_IWUSR );
+//module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
+module_param(hwwep,int, S_IRUGO|S_IWUSR);
+module_param(channels,int, S_IRUGO|S_IWUSR);
+
+MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default");
+//MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
+MODULE_PARM_DESC(hwwep," Try to use hardware security support. ");
+MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
+
+static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
+			 const struct usb_device_id *id);
+static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf);
+
+
+static struct usb_driver rtl8192_usb_driver = {
+	.name		= RTL819xU_MODULE_NAME,		  /* Driver name   */
+	.id_table	= rtl8192_usb_id_tbl,		  /* PCI_ID table  */
+	.probe		= rtl8192_usb_probe,		  /* probe fn      */
+	.disconnect	= rtl8192_usb_disconnect,	  /* remove fn     */
+#ifdef CONFIG_RTL8192_PM
+	.suspend	= rtl8192_suspend,		  /* PM suspend fn */
+	.resume		= rtl8192_resume,                 /* PM resume fn  */
+#else
+	.suspend	= NULL,				  /* PM suspend fn */
+	.resume      	= NULL,				  /* PM resume fn  */
+#endif
+};
+
+#ifdef ENABLE_DOT11D
+
+typedef struct _CHANNEL_LIST
+{
+	u8	Channel[32];
+	u8	Len;
+}CHANNEL_LIST, *PCHANNEL_LIST;
+
+static CHANNEL_LIST ChannelPlan[] = {
+	{{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,149,153,157,161,165},24},  		//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},13},    //Spain. Change to ETSI.
+	{{1,2,3,4,5,6,7,8,9,10,11,12,13},13},  	//France. Change to ETSI.
+	{{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},	//MKK					//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},13},	//Israel.
+	{{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},			// For 11a , TELEC
+	{{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22},    //MIC
+	{{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 void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
+{
+	int i, max_chan=-1, min_chan=-1;
+	struct ieee80211_device* ieee = priv->ieee80211;
+	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:
+		case COUNTRY_CODE_MIC:
+		{
+			Dot11d_Init(ieee);
+			ieee->bGlobalDomain = false;
+			//acturally 8225 & 8256 rf chip only support B,G,24N mode
+			if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256))
+			{
+				min_chan = 1;
+				max_chan = 14;
+			}
+			else
+			{
+				RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__);
+			}
+			if (ChannelPlan[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<ChannelPlan[channel_plan].Len;i++)
+				{
+					if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
+					break;
+					GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
+				}
+			}
+			break;
+		}
+		case COUNTRY_CODE_GLOBAL_DOMAIN:
+		{
+			GET_DOT11D_INFO(ieee)->bEnabled = 0;//this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain settings.
+			Dot11d_Reset(ieee);
+			ieee->bGlobalDomain = true;
+			break;
+		}
+		default:
+			break;
+	}
+	return;
+}
+#endif
+
+#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 	rx_hal_is_cck_rate(_pdrvinfo)\
+			(_pdrvinfo->RxRate == DESC90_RATE1M ||\
+			_pdrvinfo->RxRate == DESC90_RATE2M ||\
+			_pdrvinfo->RxRate == DESC90_RATE5_5M ||\
+			_pdrvinfo->RxRate == DESC90_RATE11M) &&\
+			!_pdrvinfo->RxHT\
+
+
+void CamResetAllEntry(struct net_device *dev)
+{
+	u32 ulcommand = 0;
+	//2004/02/11  In static WEP, OID_ADD_KEY or OID_ADD_WEP are set before STA associate to AP.
+	// However, ResetKey is called on OID_802_11_INFRASTRUCTURE_MODE and MlmeAssociateRequest
+	// In this condition, Cam can not be reset because upper layer will not set this static key again.
+	//if(Adapter->EncAlgorithm == WEP_Encryption)
+	//      return;
+//debug
+	//DbgPrint("========================================\n");
+	//DbgPrint("                            Call ResetAllEntry                                              \n");
+	//DbgPrint("========================================\n\n");
+	ulcommand |= BIT31|BIT30;
+	write_nic_dword(dev, RWCAM, ulcommand);
+
+}
+
+
+void write_cam(struct net_device *dev, u8 addr, u32 data)
+{
+	write_nic_dword(dev, WCAMI, data);
+	write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
+}
+
+u32 read_cam(struct net_device *dev, u8 addr)
+{
+	write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
+	return read_nic_dword(dev, 0xa8);
+}
+
+void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
+{
+	int status;
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	struct usb_device *udev = priv->udev;
+
+	status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+			       RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
+			       indx|0xfe00, 0, &data, 1, HZ / 2);
+
+	if (status < 0)
+	{
+		printk("write_nic_byte_E TimeOut! status:%d\n", status);
+	}
+}
+
+u8 read_nic_byte_E(struct net_device *dev, int indx)
+{
+	int status;
+	u8 data;
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	struct usb_device *udev = priv->udev;
+
+	status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+			       RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
+			       indx|0xfe00, 0, &data, 1, HZ / 2);
+
+	if (status < 0)
+	{
+		printk("read_nic_byte_E TimeOut! status:%d\n", status);
+	}
+
+	return data;
+}
+//as 92U has extend page from 4 to 16, so modify functions below.
+void write_nic_byte(struct net_device *dev, int indx, u8 data)
+{
+	int status;
+
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	struct usb_device *udev = priv->udev;
+
+	status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+			       RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
+			       (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 1, HZ / 2);
+
+	if (status < 0)
+	{
+		printk("write_nic_byte TimeOut! status:%d\n", status);
+	}
+
+
+}
+
+
+void write_nic_word(struct net_device *dev, int indx, u16 data)
+{
+
+	int status;
+
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	struct usb_device *udev = priv->udev;
+
+	status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+			       RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
+			       (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 2, HZ / 2);
+
+	if (status < 0)
+	{
+		printk("write_nic_word TimeOut! status:%d\n", status);
+	}
+
+}
+
+
+void write_nic_dword(struct net_device *dev, int indx, u32 data)
+{
+
+	int status;
+
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	struct usb_device *udev = priv->udev;
+
+	status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+			       RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
+			       (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 4, HZ / 2);
+
+
+	if (status < 0)
+	{
+		printk("write_nic_dword TimeOut! status:%d\n", status);
+	}
+
+}
+
+
+
+u8 read_nic_byte(struct net_device *dev, int indx)
+{
+	u8 data;
+	int status;
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	struct usb_device *udev = priv->udev;
+
+	status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+			       RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
+			       (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 1, HZ / 2);
+
+	if (status < 0)
+	{
+		printk("read_nic_byte TimeOut! status:%d\n", status);
+	}
+
+	return data;
+}
+
+
+
+u16 read_nic_word(struct net_device *dev, int indx)
+{
+	u16 data;
+	int status;
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	struct usb_device *udev = priv->udev;
+
+	status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+			       RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
+			       (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 2, HZ / 2);
+
+	if (status < 0)
+	{
+		printk("read_nic_word TimeOut! status:%d\n", status);
+	}
+
+
+	return data;
+}
+
+u16 read_nic_word_E(struct net_device *dev, int indx)
+{
+	u16 data;
+	int status;
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	struct usb_device *udev = priv->udev;
+
+	status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+			       RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
+			       indx|0xfe00, 0, &data, 2, HZ / 2);
+
+	if (status < 0)
+	{
+		printk("read_nic_word TimeOut! status:%d\n", status);
+	}
+
+
+	return data;
+}
+
+u32 read_nic_dword(struct net_device *dev, int indx)
+{
+	u32 data;
+	int status;
+//	int result;
+
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	struct usb_device *udev = priv->udev;
+
+	status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+			       RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
+			       (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 4, HZ / 2);
+//	if(0 != result) {
+//	  printk(KERN_WARNING "read size of data = %d\, date = %d\n", result, data);
+//	}
+
+	if (status < 0)
+	{
+		printk("read_nic_dword TimeOut! status:%d\n", status);
+	}
+
+
+
+	return data;
+}
+
+
+//u8 read_phy_cck(struct net_device *dev, u8 adr);
+//u8 read_phy_ofdm(struct net_device *dev, u8 adr);
+/* this might still called in what was the PHY rtl8185/rtl8192 common code
+ * plans are to possibilty turn it again in one common code...
+ */
+inline void force_pci_posting(struct net_device *dev)
+{
+}
+
+
+static struct net_device_stats *rtl8192_stats(struct net_device *dev);
+void rtl8192_commit(struct net_device *dev);
+//void rtl8192_restart(struct net_device *dev);
+void rtl8192_restart(struct work_struct *work);
+//void rtl8192_rq_tx_ack(struct work_struct *work);
+
+void watch_dog_timer_callback(unsigned long data);
+
+/****************************************************************************
+   -----------------------------PROCFS STUFF-------------------------
+*****************************************************************************/
+
+static struct proc_dir_entry *rtl8192_proc = NULL;
+
+
+
+static int proc_get_stats_ap(char *page, char **start,
+			  off_t offset, int count,
+			  int *eof, void *data)
+{
+	struct net_device *dev = data;
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	struct ieee80211_device *ieee = priv->ieee80211;
+	struct ieee80211_network *target;
+
+	int len = 0;
+
+	list_for_each_entry(target, &ieee->network_list, list) {
+
+		len += snprintf(page + len, count - len,
+		"%s ", target->ssid);
+
+		if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
+			len += snprintf(page + len, count - len,
+			"WPA\n");
+		}
+		else{
+			len += snprintf(page + len, count - len,
+			"non_WPA\n");
+		}
+
+	}
+
+	*eof = 1;
+	return len;
+}
+
+static int proc_get_registers(char *page, char **start,
+			  off_t offset, int count,
+			  int *eof, void *data)
+{
+	struct net_device *dev = data;
+//	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+
+	int len = 0;
+	int i,n;
+
+	int max=0xff;
+
+	/* This dump the current register page */
+len += snprintf(page + len, count - len,
+			"\n####################page 0##################\n ");
+
+	for(n=0;n<=max;)
+	{
+		//printk( "\nD: %2x> ", n);
+		len += snprintf(page + len, count - len,
+			"\nD:  %2x > ",n);
+
+		for(i=0;i<16 && n<=max;i++,n++)
+		len += snprintf(page + len, count - len,
+			"%2x ",read_nic_byte(dev,0x000|n));
+
+		//	printk("%2x ",read_nic_byte(dev,n));
+	}
+len += snprintf(page + len, count - len,
+			"\n####################page 1##################\n ");
+	for(n=0;n<=max;)
+	{
+		//printk( "\nD: %2x> ", n);
+		len += snprintf(page + len, count - len,
+			"\nD:  %2x > ",n);
+
+		for(i=0;i<16 && n<=max;i++,n++)
+		len += snprintf(page + len, count - len,
+			"%2x ",read_nic_byte(dev,0x100|n));
+
+		//      printk("%2x ",read_nic_byte(dev,n));
+	}
+len += snprintf(page + len, count - len,
+			"\n####################page 3##################\n ");
+	for(n=0;n<=max;)
+	{
+		//printk( "\nD: %2x> ", n);
+		len += snprintf(page + len, count - len,
+			"\nD:  %2x > ",n);
+
+		for(i=0;i<16 && n<=max;i++,n++)
+		len += snprintf(page + len, count - len,
+			"%2x ",read_nic_byte(dev,0x300|n));
+
+		//      printk("%2x ",read_nic_byte(dev,n));
+	}
+
+
+	len += snprintf(page + len, count - len,"\n");
+	*eof = 1;
+	return len;
+
+}
+
+
+
+
+
+static int proc_get_stats_tx(char *page, char **start,
+			  off_t offset, int count,
+			  int *eof, void *data)
+{
+	struct net_device *dev = data;
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+
+	int len = 0;
+
+	len += snprintf(page + len, count - len,
+		"TX VI priority ok int: %lu\n"
+		"TX VI priority error int: %lu\n"
+		"TX VO priority ok int: %lu\n"
+		"TX VO priority error int: %lu\n"
+		"TX BE priority ok int: %lu\n"
+		"TX BE priority error int: %lu\n"
+		"TX BK priority ok int: %lu\n"
+		"TX BK priority error int: %lu\n"
+		"TX MANAGE priority ok int: %lu\n"
+		"TX MANAGE priority error int: %lu\n"
+		"TX BEACON priority ok int: %lu\n"
+		"TX BEACON priority error int: %lu\n"
+//		"TX high priority ok int: %lu\n"
+//		"TX high priority failed error int: %lu\n"
+		"TX queue resume: %lu\n"
+		"TX queue stopped?: %d\n"
+		"TX fifo overflow: %lu\n"
+//		"TX beacon: %lu\n"
+		"TX VI queue: %d\n"
+		"TX VO queue: %d\n"
+		"TX BE queue: %d\n"
+		"TX BK queue: %d\n"
+//		"TX HW queue: %d\n"
+		"TX VI dropped: %lu\n"
+		"TX VO dropped: %lu\n"
+		"TX BE dropped: %lu\n"
+		"TX BK dropped: %lu\n"
+		"TX total data packets %lu\n",
+//		"TX beacon aborted: %lu\n",
+		priv->stats.txviokint,
+		priv->stats.txvierr,
+		priv->stats.txvookint,
+		priv->stats.txvoerr,
+		priv->stats.txbeokint,
+		priv->stats.txbeerr,
+		priv->stats.txbkokint,
+		priv->stats.txbkerr,
+		priv->stats.txmanageokint,
+		priv->stats.txmanageerr,
+		priv->stats.txbeaconokint,
+		priv->stats.txbeaconerr,
+//		priv->stats.txhpokint,
+//		priv->stats.txhperr,
+		priv->stats.txresumed,
+		netif_queue_stopped(dev),
+		priv->stats.txoverflow,
+//		priv->stats.txbeacon,
+		atomic_read(&(priv->tx_pending[VI_PRIORITY])),
+		atomic_read(&(priv->tx_pending[VO_PRIORITY])),
+		atomic_read(&(priv->tx_pending[BE_PRIORITY])),
+		atomic_read(&(priv->tx_pending[BK_PRIORITY])),
+//		read_nic_byte(dev, TXFIFOCOUNT),
+		priv->stats.txvidrop,
+		priv->stats.txvodrop,
+		priv->stats.txbedrop,
+		priv->stats.txbkdrop,
+		priv->stats.txdatapkt
+//		priv->stats.txbeaconerr
+		);
+
+	*eof = 1;
+	return len;
+}
+
+
+
+static int proc_get_stats_rx(char *page, char **start,
+			  off_t offset, int count,
+			  int *eof, void *data)
+{
+	struct net_device *dev = data;
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+
+	int len = 0;
+
+	len += snprintf(page + len, count - len,
+		"RX packets: %lu\n"
+		"RX urb status error: %lu\n"
+		"RX invalid urb error: %lu\n",
+		priv->stats.rxoktotal,
+		priv->stats.rxstaterr,
+		priv->stats.rxurberr);
+
+	*eof = 1;
+	return len;
+}
+void rtl8192_proc_module_init(void)
+{
+	RT_TRACE(COMP_INIT, "Initializing proc filesystem");
+	rtl8192_proc=create_proc_entry(RTL819xU_MODULE_NAME, S_IFDIR, init_net.proc_net);
+}
+
+
+void rtl8192_proc_module_remove(void)
+{
+	remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net);
+}
+
+
+void rtl8192_proc_remove_one(struct net_device *dev)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+
+
+	if (priv->dir_dev) {
+	//	remove_proc_entry("stats-hw", priv->dir_dev);
+		remove_proc_entry("stats-tx", priv->dir_dev);
+		remove_proc_entry("stats-rx", priv->dir_dev);
+	//	remove_proc_entry("stats-ieee", priv->dir_dev);
+		remove_proc_entry("stats-ap", priv->dir_dev);
+		remove_proc_entry("registers", priv->dir_dev);
+	//	remove_proc_entry("cck-registers",priv->dir_dev);
+	//	remove_proc_entry("ofdm-registers",priv->dir_dev);
+		//remove_proc_entry(dev->name, rtl8192_proc);
+		remove_proc_entry("wlan0", rtl8192_proc);
+		priv->dir_dev = NULL;
+	}
+}
+
+
+void rtl8192_proc_init_one(struct net_device *dev)
+{
+	struct proc_dir_entry *e;
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	priv->dir_dev = create_proc_entry(dev->name,
+					  S_IFDIR | S_IRUGO | S_IXUGO,
+					  rtl8192_proc);
+	if (!priv->dir_dev) {
+		RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
+		      dev->name);
+		return;
+	}
+	e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
+				   priv->dir_dev, proc_get_stats_rx, dev);
+
+	if (!e) {
+		RT_TRACE(COMP_ERR,"Unable to initialize "
+		      "/proc/net/rtl8192/%s/stats-rx\n",
+		      dev->name);
+	}
+
+
+	e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
+				   priv->dir_dev, proc_get_stats_tx, dev);
+
+	if (!e) {
+		RT_TRACE(COMP_ERR, "Unable to initialize "
+		      "/proc/net/rtl8192/%s/stats-tx\n",
+		      dev->name);
+	}
+
+	e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
+				   priv->dir_dev, proc_get_stats_ap, dev);
+
+	if (!e) {
+		RT_TRACE(COMP_ERR, "Unable to initialize "
+		      "/proc/net/rtl8192/%s/stats-ap\n",
+		      dev->name);
+	}
+
+	e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
+				   priv->dir_dev, proc_get_registers, dev);
+	if (!e) {
+		RT_TRACE(COMP_ERR, "Unable to initialize "
+		      "/proc/net/rtl8192/%s/registers\n",
+		      dev->name);
+	}
+}
+/****************************************************************************
+   -----------------------------MISC STUFF-------------------------
+*****************************************************************************/
+
+/* this is only for debugging */
+void print_buffer(u32 *buffer, int len)
+{
+	int i;
+	u8 *buf =(u8*)buffer;
+
+	printk("ASCII BUFFER DUMP (len: %x):\n",len);
+
+	for(i=0;i<len;i++)
+		printk("%c",buf[i]);
+
+	printk("\nBINARY BUFFER DUMP (len: %x):\n",len);
+
+	for(i=0;i<len;i++)
+		printk("%x",buf[i]);
+
+	printk("\n");
+}
+
+//short check_nic_enough_desc(struct net_device *dev, priority_t priority)
+short check_nic_enough_desc(struct net_device *dev,int queue_index)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	int used = atomic_read(&priv->tx_pending[queue_index]);
+
+	return (used < MAX_TX_URB);
+}
+
+void tx_timeout(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	//rtl8192_commit(dev);
+
+	schedule_work(&priv->reset_wq);
+	//DMESG("TXTIMEOUT");
+}
+
+
+/* this is only for debug */
+void dump_eprom(struct net_device *dev)
+{
+	int i;
+	for(i=0; i<63; i++)
+		RT_TRACE(COMP_EPROM, "EEPROM addr %x : %x", i, eprom_read(dev,i));
+}
+
+/* this is only for debug */
+void rtl8192_dump_reg(struct net_device *dev)
+{
+	int i;
+	int n;
+	int max=0x1ff;
+
+	RT_TRACE(COMP_PHY, "Dumping NIC register map");
+
+	for(n=0;n<=max;)
+	{
+		printk( "\nD: %2x> ", n);
+		for(i=0;i<16 && n<=max;i++,n++)
+			printk("%2x ",read_nic_byte(dev,n));
+	}
+	printk("\n");
+}
+
+/****************************************************************************
+      ------------------------------HW STUFF---------------------------
+*****************************************************************************/
+
+
+void rtl8192_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 rtl8192_update_msr(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 msr;
+
+	msr  = read_nic_byte(dev, MSR);
+	msr &= ~ MSR_LINK_MASK;
+
+	/* do not change in link_state != WLAN_LINK_ASSOCIATED.
+	 * msr must be updated if the state is ASSOCIATING.
+	 * this is intentional and make sense for ad-hoc and
+	 * master (see the create BSS/IBSS func)
+	 */
+	if (priv->ieee80211->state == IEEE80211_LINKED){
+
+		if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
+			msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
+		else 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
+		msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
+
+	write_nic_byte(dev, MSR, msr);
+}
+
+void rtl8192_set_chan(struct net_device *dev,short ch)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+//	u32 tx;
+	RT_TRACE(COMP_CH, "=====>%s()====ch:%d\n", __FUNCTION__, ch);
+	priv->chan=ch;
+
+	/* this hack should avoid frame TX during channel setting*/
+
+
+//	tx = read_nic_dword(dev,TX_CONF);
+//	tx &= ~TX_LOOPBACK_MASK;
+
+#ifndef LOOP_TEST
+//	write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
+
+	//need to implement rf set channel here WB
+
+	if (priv->rf_set_chan)
+	priv->rf_set_chan(dev,priv->chan);
+	mdelay(10);
+//	write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
+#endif
+}
+
+static void rtl8192_rx_isr(struct urb *urb);
+//static void rtl8192_rx_isr(struct urb *rx_urb);
+
+u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats)
+{
+
+#ifdef USB_RX_AGGREGATION_SUPPORT
+	if (pstats->bisrxaggrsubframe)
+		return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
+			+ pstats->RxBufShift + 8);
+	else
+#endif
+		return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
+				+ pstats->RxBufShift);
+
+}
+static int rtl8192_rx_initiate(struct net_device*dev)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	struct urb *entry;
+	struct sk_buff *skb;
+	struct rtl8192_rx_info *info;
+
+	/* nomal packet rx procedure */
+	while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB) {
+		skb = __dev_alloc_skb(RX_URB_SIZE, GFP_KERNEL);
+		if (!skb)
+			break;
+		entry = usb_alloc_urb(0, GFP_KERNEL);
+		if (!entry) {
+			kfree_skb(skb);
+			break;
+		}
+//		printk("nomal packet IN request!\n");
+		usb_fill_bulk_urb(entry, priv->udev,
+				  usb_rcvbulkpipe(priv->udev, 3), skb_tail_pointer(skb),
+				  RX_URB_SIZE, rtl8192_rx_isr, skb);
+		info = (struct rtl8192_rx_info *) skb->cb;
+		info->urb = entry;
+		info->dev = dev;
+		info->out_pipe = 3; //denote rx normal packet queue
+		skb_queue_tail(&priv->rx_queue, skb);
+		usb_submit_urb(entry, GFP_KERNEL);
+	}
+
+	/* command packet rx procedure */
+	while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB + 3) {
+//		printk("command packet IN request!\n");
+		skb = __dev_alloc_skb(RX_URB_SIZE ,GFP_KERNEL);
+		if (!skb)
+			break;
+		entry = usb_alloc_urb(0, GFP_KERNEL);
+		if (!entry) {
+			kfree_skb(skb);
+			break;
+		}
+		usb_fill_bulk_urb(entry, priv->udev,
+				  usb_rcvbulkpipe(priv->udev, 9), skb_tail_pointer(skb),
+				  RX_URB_SIZE, rtl8192_rx_isr, skb);
+		info = (struct rtl8192_rx_info *) skb->cb;
+		info->urb = entry;
+		info->dev = dev;
+		   info->out_pipe = 9; //denote rx cmd packet queue
+		skb_queue_tail(&priv->rx_queue, skb);
+		usb_submit_urb(entry, GFP_KERNEL);
+	}
+
+	return 0;
+}
+
+void rtl8192_set_rxconf(struct net_device *dev)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	u32 rxconf;
+
+	rxconf=read_nic_dword(dev,RCR);
+	rxconf = rxconf &~ MAC_FILTER_MASK;
+	rxconf = rxconf | RCR_AMF;
+	rxconf = rxconf | RCR_ADF;
+	rxconf = rxconf | RCR_AB;
+	rxconf = rxconf | RCR_AM;
+	//rxconf = rxconf | RCR_ACF;
+
+	if (dev->flags & IFF_PROMISC) {DMESG ("NIC in promisc mode");}
+
+	if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
+	   dev->flags & IFF_PROMISC){
+		rxconf = rxconf | RCR_AAP;
+	} /*else if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
+		rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
+		rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
+	}*/else{
+		rxconf = rxconf | RCR_APM;
+		rxconf = rxconf | RCR_CBSSID;
+	}
+
+
+	if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
+		rxconf = rxconf | RCR_AICV;
+		rxconf = rxconf | RCR_APWRMGT;
+	}
+
+	if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
+		rxconf = rxconf | RCR_ACRC32;
+
+
+	rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
+	rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
+	rxconf = rxconf &~ MAX_RX_DMA_MASK;
+	rxconf = rxconf | ((u32)7<<RCR_MXDMA_OFFSET);
+
+//	rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
+	rxconf = rxconf | RCR_ONLYERLPKT;
+
+//	rxconf = rxconf &~ RCR_CS_MASK;
+//	rxconf = rxconf | (1<<RCR_CS_SHIFT);
+
+	write_nic_dword(dev, RCR, rxconf);
+
+	#ifdef DEBUG_RX
+	DMESG("rxconf: %x %x",rxconf ,read_nic_dword(dev,RCR));
+	#endif
+}
+//wait to be removed
+void rtl8192_rx_enable(struct net_device *dev)
+{
+	//u8 cmd;
+
+	//struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+
+	rtl8192_rx_initiate(dev);
+
+//	rtl8192_set_rxconf(dev);
+}
+
+
+void rtl8192_tx_enable(struct net_device *dev)
+{
+}
+
+
+
+void rtl8192_rtx_disable(struct net_device *dev)
+{
+	u8 cmd;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	struct sk_buff *skb;
+	struct rtl8192_rx_info *info;
+
+	cmd=read_nic_byte(dev,CMDR);
+	write_nic_byte(dev, CMDR, cmd &~ \
+		(CR_TE|CR_RE));
+	force_pci_posting(dev);
+	mdelay(10);
+
+	while ((skb = __skb_dequeue(&priv->rx_queue))) {
+		info = (struct rtl8192_rx_info *) skb->cb;
+		if (!info->urb)
+			continue;
+
+		usb_kill_urb(info->urb);
+		kfree_skb(skb);
+	}
+
+	if (skb_queue_len(&priv->skb_queue)) {
+		printk(KERN_WARNING "skb_queue not empty\n");
+	}
+
+	skb_queue_purge(&priv->skb_queue);
+	return;
+}
+
+
+int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
+{
+	return 0;
+}
+
+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};
+inline u16 rtl8192_rate2rate(short rate)
+{
+	if (rate >11) return 0;
+	return rtl_rate[rate];
+}
+
+
+/* The protype of rx_isr has changed since one verion of Linux Kernel */
+static void rtl8192_rx_isr(struct urb *urb)
+{
+	struct sk_buff *skb = (struct sk_buff *) urb->context;
+	struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
+	struct net_device *dev = info->dev;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	int out_pipe = info->out_pipe;
+	int err;
+	if(!priv->up)
+		return;
+	if (unlikely(urb->status)) {
+		info->urb = NULL;
+		priv->stats.rxstaterr++;
+		priv->ieee80211->stats.rx_errors++;
+		usb_free_urb(urb);
+	//	printk("%s():rx status err\n",__FUNCTION__);
+		return;
+	}
+	skb_unlink(skb, &priv->rx_queue);
+	skb_put(skb, urb->actual_length);
+
+	skb_queue_tail(&priv->skb_queue, skb);
+	tasklet_schedule(&priv->irq_rx_tasklet);
+
+	skb = dev_alloc_skb(RX_URB_SIZE);
+	if (unlikely(!skb)) {
+		usb_free_urb(urb);
+		printk("%s():can,t alloc skb\n",__FUNCTION__);
+		/* TODO check rx queue length and refill *somewhere* */
+		return;
+	}
+
+	usb_fill_bulk_urb(urb, priv->udev,
+			usb_rcvbulkpipe(priv->udev, out_pipe), skb_tail_pointer(skb),
+			RX_URB_SIZE, rtl8192_rx_isr, skb);
+
+	info = (struct rtl8192_rx_info *) skb->cb;
+	info->urb = urb;
+	info->dev = dev;
+	info->out_pipe = out_pipe;
+
+	urb->transfer_buffer = skb_tail_pointer(skb);
+	urb->context = skb;
+	skb_queue_tail(&priv->rx_queue, skb);
+	err = usb_submit_urb(urb, GFP_ATOMIC);
+	if(err && err != EPERM)
+		printk("can not submit rxurb, err is %x,URB status is %x\n",err,urb->status);
+}
+
+u32
+rtl819xusb_rx_command_packet(
+	struct net_device *dev,
+	struct ieee80211_rx_stats *pstats
+	)
+{
+	u32	status;
+
+	//RT_TRACE(COMP_RECV, DBG_TRACE, ("---> RxCommandPacketHandle819xUsb()\n"));
+
+	status = cmpk_message_handle_rx(dev, pstats);
+	if (status)
+	{
+		DMESG("rxcommandpackethandle819xusb: It is a command packet\n");
+	}
+	else
+	{
+		//RT_TRACE(COMP_RECV, DBG_TRACE, ("RxCommandPacketHandle819xUsb: It is not a command packet\n"));
+	}
+
+	//RT_TRACE(COMP_RECV, DBG_TRACE, ("<--- RxCommandPacketHandle819xUsb()\n"));
+	return status;
+}
+
+
+void rtl8192_data_hard_stop(struct net_device *dev)
+{
+	//FIXME !!
+}
+
+
+void rtl8192_data_hard_resume(struct net_device *dev)
+{
+	// FIXME !!
+}
+
+/* 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
+ */
+void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	int ret;
+	unsigned long flags;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	u8 queue_index = tcb_desc->queue_index;
+
+	/* shall not be referred by command packet */
+	assert(queue_index != TXCMD_QUEUE);
+
+	spin_lock_irqsave(&priv->tx_lock,flags);
+
+	memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
+//	tcb_desc->RATRIndex = 7;
+//	tcb_desc->bTxDisableRateFallBack = 1;
+//	tcb_desc->bTxUseDriverAssingedRate = 1;
+	tcb_desc->bTxEnableFwCalcDur = 1;
+	skb_push(skb, priv->ieee80211->tx_headroom);
+	ret = rtl8192_tx(dev, skb);
+
+	//priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
+	//priv->ieee80211->stats.tx_packets++;
+
+	spin_unlock_irqrestore(&priv->tx_lock,flags);
+
+//	return ret;
+	return;
+}
+
+/* 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 packet are dropped (for data frame the queue
+ * is stopped before this can happen).
+ */
+int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	int ret;
+	unsigned long flags;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	u8 queue_index = tcb_desc->queue_index;
+
+
+	spin_lock_irqsave(&priv->tx_lock,flags);
+
+	memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
+	if(queue_index == TXCMD_QUEUE) {
+		skb_push(skb, USB_HWDESC_HEADER_LEN);
+		rtl819xU_tx_cmd(dev, skb);
+		ret = 1;
+		spin_unlock_irqrestore(&priv->tx_lock,flags);
+		return ret;
+	} else {
+		skb_push(skb, priv->ieee80211->tx_headroom);
+		ret = rtl8192_tx(dev, skb);
+	}
+
+	spin_unlock_irqrestore(&priv->tx_lock,flags);
+
+	return ret;
+}
+
+
+void rtl8192_try_wake_queue(struct net_device *dev, int pri);
+
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+u16 DrvAggr_PaddingAdd(struct net_device *dev, struct sk_buff *skb)
+{
+	u16     PaddingNum =  256 - ((skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES) % 256);
+	return  (PaddingNum&0xff);
+}
+
+u8 MRateToHwRate8190Pci(u8 rate);
+u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc);
+u8 MapHwQueueToFirmwareQueue(u8 QueueID);
+struct sk_buff *DrvAggr_Aggregation(struct net_device *dev, struct ieee80211_drv_agg_txb *pSendList)
+{
+	struct ieee80211_device *ieee = netdev_priv(dev);
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	cb_desc 	*tcb_desc = NULL;
+	u8 		i;
+	u32		TotalLength;
+	struct sk_buff	*skb;
+	struct sk_buff  *agg_skb;
+	tx_desc_819x_usb_aggr_subframe *tx_agg_desc = NULL;
+	tx_fwinfo_819x_usb	       *tx_fwinfo = NULL;
+
+	//
+	// Local variable initialization.
+	//
+	/* first skb initialization */
+	skb = pSendList->tx_agg_frames[0];
+	TotalLength = skb->len;
+
+	/* Get the total aggregation length including the padding space and
+	 * sub frame header.
+	 */
+	for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
+		TotalLength += DrvAggr_PaddingAdd(dev, skb);
+		skb = pSendList->tx_agg_frames[i];
+		TotalLength += (skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
+	}
+
+	/* allocate skb to contain the aggregated packets */
+	agg_skb = dev_alloc_skb(TotalLength + ieee->tx_headroom);
+	memset(agg_skb->data, 0, agg_skb->len);
+	skb_reserve(agg_skb, ieee->tx_headroom);
+
+//	RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
+	/* reserve info for first subframe Tx descriptor to be set in the tx function */
+	skb = pSendList->tx_agg_frames[0];
+	tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	tcb_desc->drv_agg_enable = 1;
+	tcb_desc->pkt_size = skb->len;
+	tcb_desc->DrvAggrNum = pSendList->nr_drv_agg_frames;
+	printk("DrvAggNum = %d\n", tcb_desc->DrvAggrNum);
+//	RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
+//	printk("========>skb->data ======> \n");
+//	RT_DEBUG_DATA(COMP_SEND, skb->data, skb->len);
+	memcpy(agg_skb->cb, skb->cb, sizeof(skb->cb));
+	memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
+
+	for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
+		/* push the next sub frame to be 256 byte aline */
+		skb_put(agg_skb,DrvAggr_PaddingAdd(dev,skb));
+
+		/* Subframe drv Tx descriptor and firmware info setting */
+		skb = pSendList->tx_agg_frames[i];
+		tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+		tx_agg_desc = (tx_desc_819x_usb_aggr_subframe *)agg_skb->tail;
+		tx_fwinfo = (tx_fwinfo_819x_usb *)(agg_skb->tail + sizeof(tx_desc_819x_usb_aggr_subframe));
+
+		memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
+		/* DWORD 0 */
+		tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
+		tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
+		tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
+		tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
+		if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
+			tx_fwinfo->AllowAggregation = 1;
+			/* DWORD 1 */
+			tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
+			tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
+		} else {
+			tx_fwinfo->AllowAggregation = 0;
+			/* DWORD 1 */
+			tx_fwinfo->RxMF = 0;
+			tx_fwinfo->RxAMD = 0;
+		}
+
+		/* Protection mode related */
+		tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
+		tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
+		tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
+		tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
+		tx_fwinfo->RtsRate =  MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
+		tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
+		tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
+		tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
+				      (tcb_desc->bRTSUseShortGI?1:0);
+
+		/* Set Bandwidth and sub-channel settings. */
+		if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
+		{
+			if(tcb_desc->bPacketBW) {
+				tx_fwinfo->TxBandwidth = 1;
+				tx_fwinfo->TxSubCarrier = 0;    //By SD3's Jerry suggestion, use duplicated mode
+			} else {
+				tx_fwinfo->TxBandwidth = 0;
+				tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
+			}
+		} else {
+			tx_fwinfo->TxBandwidth = 0;
+			tx_fwinfo->TxSubCarrier = 0;
+		}
+
+		/* Fill Tx descriptor */
+		memset(tx_agg_desc, 0, sizeof(tx_desc_819x_usb_aggr_subframe));
+		/* DWORD 0 */
+		//tx_agg_desc->LINIP = 0;
+		//tx_agg_desc->CmdInit = 1;
+		tx_agg_desc->Offset =  sizeof(tx_fwinfo_819x_usb) + 8;
+		/* already raw data, need not to substract header length */
+		tx_agg_desc->PktSize = skb->len & 0xffff;
+
+		/*DWORD 1*/
+		tx_agg_desc->SecCAMID= 0;
+		tx_agg_desc->RATid = tcb_desc->RATRIndex;
+		{
+			//MPDUOverhead = 0;
+			tx_agg_desc->NoEnc = 1;
+		}
+		tx_agg_desc->SecType = 0x0;
+
+		if (tcb_desc->bHwSec) {
+			switch (priv->ieee80211->pairwise_key_type)
+			{
+				case KEY_TYPE_WEP40:
+				case KEY_TYPE_WEP104:
+					tx_agg_desc->SecType = 0x1;
+					tx_agg_desc->NoEnc = 0;
+					break;
+				case KEY_TYPE_TKIP:
+					tx_agg_desc->SecType = 0x2;
+					tx_agg_desc->NoEnc = 0;
+					break;
+				case KEY_TYPE_CCMP:
+					tx_agg_desc->SecType = 0x3;
+					tx_agg_desc->NoEnc = 0;
+					break;
+				case KEY_TYPE_NA:
+					tx_agg_desc->SecType = 0x0;
+					tx_agg_desc->NoEnc = 1;
+					break;
+			}
+		}
+
+		tx_agg_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
+		tx_agg_desc->TxFWInfoSize =  sizeof(tx_fwinfo_819x_usb);
+
+		tx_agg_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
+		tx_agg_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
+
+		tx_agg_desc->OWN = 1;
+
+		//DWORD 2
+		/* According windows driver, it seems that there no need to fill this field */
+		//tx_agg_desc->TxBufferSize= (u32)(skb->len - USB_HWDESC_HEADER_LEN);
+
+		/* to fill next packet */
+		skb_put(agg_skb,TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
+		memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
+	}
+
+	for(i = 0; i < pSendList->nr_drv_agg_frames; i++) {
+		dev_kfree_skb_any(pSendList->tx_agg_frames[i]);
+	}
+
+	return agg_skb;
+}
+
+/* NOTE:
+	This function return a list of PTCB which is proper to be aggregate with the input TCB.
+	If no proper TCB is found to do aggregation, SendList will only contain the input TCB.
+*/
+u8 DrvAggr_GetAggregatibleList(struct net_device *dev, struct sk_buff *skb,
+		struct ieee80211_drv_agg_txb *pSendList)
+{
+	struct ieee80211_device *ieee = netdev_priv(dev);
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	u16		nMaxAggrNum = pHTInfo->UsbTxAggrNum;
+	cb_desc 	*tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	u8		QueueID = tcb_desc->queue_index;
+
+	do {
+		pSendList->tx_agg_frames[pSendList->nr_drv_agg_frames++] = skb;
+		if(pSendList->nr_drv_agg_frames >= nMaxAggrNum) {
+			break;
+		}
+
+	} while((skb = skb_dequeue(&ieee->skb_drv_aggQ[QueueID])));
+
+	RT_TRACE(COMP_AMSDU, "DrvAggr_GetAggregatibleList, nAggrTcbNum = %d \n", pSendList->nr_drv_agg_frames);
+	return pSendList->nr_drv_agg_frames;
+}
+#endif
+
+static void rtl8192_tx_isr(struct urb *tx_urb)
+{
+	struct sk_buff *skb = (struct sk_buff*)tx_urb->context;
+	struct net_device *dev = NULL;
+	struct r8192_priv *priv = NULL;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	u8  queue_index = tcb_desc->queue_index;
+//	bool bToSend0Byte;
+//	u16 BufLen = skb->len;
+
+	memcpy(&dev,(struct net_device*)(skb->cb),sizeof(struct net_device*));
+	priv = ieee80211_priv(dev);
+
+	if(tcb_desc->queue_index != TXCMD_QUEUE) {
+		if(tx_urb->status == 0) {
+			dev->trans_start = jiffies;
+			// As act as station mode, destion shall be  unicast address.
+			//priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
+			//priv->ieee80211->stats.tx_packets++;
+			priv->stats.txoktotal++;
+			priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
+			priv->stats.txbytesunicast += (skb->len - priv->ieee80211->tx_headroom);
+		} else {
+			priv->ieee80211->stats.tx_errors++;
+			//priv->stats.txmanageerr++;
+			/* TODO */
+		}
+	}
+
+	/* free skb and tx_urb */
+	if(skb != NULL) {
+		dev_kfree_skb_any(skb);
+		usb_free_urb(tx_urb);
+		atomic_dec(&priv->tx_pending[queue_index]);
+	}
+
+	{
+		//
+		// Handle HW Beacon:
+		// We had transfer our beacon frame to host controler at this moment.
+		//
+		//
+		// Caution:
+		// Handling the wait queue of command packets.
+		// For Tx command packets, we must not do TCB fragment because it is not handled right now.
+		// We must cut the packets to match the size of TX_CMD_PKT before we send it.
+		//
+
+		/* Handle MPDU in wait queue. */
+		if(queue_index != BEACON_QUEUE) {
+			/* Don't send data frame during scanning.*/
+			if((skb_queue_len(&priv->ieee80211->skb_waitQ[queue_index]) != 0)&&\
+					(!(priv->ieee80211->queue_stop))) {
+				if(NULL != (skb = skb_dequeue(&(priv->ieee80211->skb_waitQ[queue_index]))))
+					priv->ieee80211->softmac_hard_start_xmit(skb, dev);
+
+				return; //modified by david to avoid further processing AMSDU
+			}
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+			else if ((skb_queue_len(&priv->ieee80211->skb_drv_aggQ[queue_index])!= 0)&&\
+				(!(priv->ieee80211->queue_stop))) {
+				// Tx Driver Aggregation process
+				/* The driver will aggregation the packets according to the following stets
+				 * 1. check whether there's tx irq available, for it's a completion return
+				 *    function, it should contain enough tx irq;
+				 * 2. check pakcet type;
+				 * 3. intialize sendlist, check whether the to-be send packet no greater than 1
+				 * 4. aggregation the packets, and fill firmware info and tx desc to it, etc.
+				 * 5. check whehter the packet could be sent, otherwise just insert to wait head
+				 * */
+				skb = skb_dequeue(&priv->ieee80211->skb_drv_aggQ[queue_index]);
+				if(!check_nic_enough_desc(dev, queue_index)) {
+					skb_queue_head(&(priv->ieee80211->skb_drv_aggQ[queue_index]), skb);
+					return;
+				}
+
+				{
+					/*TODO*/
+					/*
+					u8* pHeader = skb->data;
+
+					if(IsMgntQosData(pHeader) ||
+					    IsMgntQData_Ack(pHeader) ||
+					    IsMgntQData_Poll(pHeader) ||
+					    IsMgntQData_Poll_Ack(pHeader)
+					  )
+					*/
+					{
+						struct ieee80211_drv_agg_txb SendList;
+
+						memset(&SendList, 0, sizeof(struct ieee80211_drv_agg_txb));
+						if(DrvAggr_GetAggregatibleList(dev, skb, &SendList) > 1) {
+							skb = DrvAggr_Aggregation(dev, &SendList);
+
+						}
+					}
+					priv->ieee80211->softmac_hard_start_xmit(skb, dev);
+				}
+			}
+#endif
+		}
+	}
+
+}
+
+void rtl8192_beacon_stop(struct net_device *dev)
+{
+	u8 msr, msrm, msr2;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	msr  = read_nic_byte(dev, MSR);
+	msrm = msr & MSR_LINK_MASK;
+	msr2 = msr & ~MSR_LINK_MASK;
+
+	if(NIC_8192U == priv->card_8192) {
+		usb_kill_urb(priv->rx_urb[MAX_RX_URB]);
+	}
+	if ((msrm == (MSR_LINK_ADHOC<<MSR_LINK_SHIFT) ||
+		(msrm == (MSR_LINK_MASTER<<MSR_LINK_SHIFT)))){
+		write_nic_byte(dev, MSR, msr2 | MSR_LINK_NONE);
+		write_nic_byte(dev, MSR, msr);
+	}
+}
+
+void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
+{
+	 struct r8192_priv *priv = ieee80211_priv(dev);
+	 struct ieee80211_network *net;
+	 u8 i=0, basic_rate = 0;
+	 net = & priv->ieee80211->current_network;
+
+	 for (i=0; i<net->rates_len; i++)
+	 {
+		 basic_rate = net->rates[i]&0x7f;
+		 switch(basic_rate)
+		 {
+			 case MGN_1M:	*rate_config |= RRSR_1M;	break;
+			 case MGN_2M:	*rate_config |= RRSR_2M;	break;
+			 case MGN_5_5M:	*rate_config |= RRSR_5_5M;	break;
+			 case MGN_11M:	*rate_config |= RRSR_11M;	break;
+			 case MGN_6M:	*rate_config |= RRSR_6M;	break;
+			 case MGN_9M:	*rate_config |= RRSR_9M;	break;
+			 case MGN_12M:	*rate_config |= RRSR_12M;	break;
+			 case MGN_18M:	*rate_config |= RRSR_18M;	break;
+			 case MGN_24M:	*rate_config |= RRSR_24M;	break;
+			 case MGN_36M:	*rate_config |= RRSR_36M;	break;
+			 case MGN_48M:	*rate_config |= RRSR_48M;	break;
+			 case MGN_54M:	*rate_config |= RRSR_54M;	break;
+		 }
+	 }
+	 for (i=0; i<net->rates_ex_len; i++)
+	 {
+		 basic_rate = net->rates_ex[i]&0x7f;
+		 switch(basic_rate)
+		 {
+			 case MGN_1M:	*rate_config |= RRSR_1M;	break;
+			 case MGN_2M:	*rate_config |= RRSR_2M;	break;
+			 case MGN_5_5M:	*rate_config |= RRSR_5_5M;	break;
+			 case MGN_11M:	*rate_config |= RRSR_11M;	break;
+			 case MGN_6M:	*rate_config |= RRSR_6M;	break;
+			 case MGN_9M:	*rate_config |= RRSR_9M;	break;
+			 case MGN_12M:	*rate_config |= RRSR_12M;	break;
+			 case MGN_18M:	*rate_config |= RRSR_18M;	break;
+			 case MGN_24M:	*rate_config |= RRSR_24M;	break;
+			 case MGN_36M:	*rate_config |= RRSR_36M;	break;
+			 case MGN_48M:	*rate_config |= RRSR_48M;	break;
+			 case MGN_54M:	*rate_config |= RRSR_54M;	break;
+		 }
+	 }
+}
+
+
+#define SHORT_SLOT_TIME 9
+#define NON_SHORT_SLOT_TIME 20
+
+void rtl8192_update_cap(struct net_device* dev, u16 cap)
+{
+	u32 tmp = 0;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_network *net = &priv->ieee80211->current_network;
+	priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
+	tmp = priv->basic_rate;
+	if (priv->short_preamble)
+		tmp |= BRSR_AckShortPmb;
+	write_nic_dword(dev, RRSR, tmp);
+
+	if (net->mode & (IEEE_G|IEEE_N_24G))
+	{
+		u8 slot_time = 0;
+		if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
+		{//short slot time
+			slot_time = SHORT_SLOT_TIME;
+		}
+		else //long slot time
+			slot_time = NON_SHORT_SLOT_TIME;
+		priv->slot_time = slot_time;
+		write_nic_byte(dev, SLOT_TIME, slot_time);
+	}
+
+}
+void rtl8192_net_update(struct net_device *dev)
+{
+
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_network *net;
+	u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
+	u16 rate_config = 0;
+	net = & priv->ieee80211->current_network;
+
+	rtl8192_config_rate(dev, &rate_config);
+	priv->basic_rate = rate_config &= 0x15f;
+
+	write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
+	write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
+	//for(i=0;i<ETH_ALEN;i++)
+	//	write_nic_byte(dev,BSSID+i,net->bssid[i]);
+
+	rtl8192_update_msr(dev);
+//	rtl8192_update_cap(dev, net->capability);
+	if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
+	{
+	write_nic_word(dev, ATIMWND, 2);
+	write_nic_word(dev, BCN_DMATIME, 1023);
+	write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
+//	write_nic_word(dev, BcnIntTime, 100);
+	write_nic_word(dev, BCN_DRV_EARLY_INT, 1);
+	write_nic_byte(dev, BCN_ERR_THRESH, 100);
+		BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
+	// TODO: BcnIFS may required to be changed on ASIC
+		BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
+
+	write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
+	}
+
+
+
+}
+
+//temporary hw beacon is not used any more.
+//open it when necessary
+void rtl819xusb_beacon_tx(struct net_device *dev,u16  tx_rate)
+{
+
+}
+inline u8 rtl8192_IsWirelessBMode(u16 rate)
+{
+	if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
+		return 1;
+	else return 0;
+}
+
+u16 N_DBPSOfRate(u16 DataRate);
+
+u16 ComputeTxTime(
+	u16		FrameLength,
+	u16		DataRate,
+	u8		bManagementFrame,
+	u8		bShortPreamble
+)
+{
+	u16	FrameTime;
+	u16	N_DBPS;
+	u16	Ceiling;
+
+	if( rtl8192_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;
+}
+
+void rtl819xU_cmd_isr(struct urb *tx_cmd_urb, struct pt_regs *regs)
+{
+	usb_free_urb(tx_cmd_urb);
+}
+
+unsigned int txqueue2outpipe(struct r8192_priv* priv,unsigned int tx_queue) {
+
+	if(tx_queue >= 9)
+	{
+		RT_TRACE(COMP_ERR,"%s():Unknown queue ID!!!\n",__FUNCTION__);
+		return 0x04;
+	}
+	return priv->txqueue_to_outpipemap[tx_queue];
+}
+
+short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	//u8			*tx;
+	int			status;
+	struct urb		*tx_urb;
+	//int			urb_buf_len;
+	unsigned int 		idx_pipe;
+	tx_desc_cmd_819x_usb *pdesc = (tx_desc_cmd_819x_usb *)skb->data;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	u8 queue_index = tcb_desc->queue_index;
+
+	//printk("\n %s::queue_index = %d\n",__FUNCTION__, queue_index);
+	atomic_inc(&priv->tx_pending[queue_index]);
+	tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
+	if(!tx_urb){
+		dev_kfree_skb(skb);
+		return -ENOMEM;
+	}
+
+	memset(pdesc, 0, USB_HWDESC_HEADER_LEN);
+	/* Tx descriptor ought to be set according to the skb->cb */
+	pdesc->FirstSeg = 1;//bFirstSeg;
+	pdesc->LastSeg = 1;//bLastSeg;
+	pdesc->CmdInit = tcb_desc->bCmdOrInit;
+	pdesc->TxBufferSize = tcb_desc->txbuf_size;
+	pdesc->OWN = 1;
+	pdesc->LINIP = tcb_desc->bLastIniPkt;
+
+	//----------------------------------------------------------------------------
+	// Fill up USB_OUT_CONTEXT.
+	//----------------------------------------------------------------------------
+	// Get index to out pipe from specified QueueID.
+#ifndef USE_ONE_PIPE
+	idx_pipe = txqueue2outpipe(priv,queue_index);
+#else
+	idx_pipe = 0x04;
+#endif
+#ifdef JOHN_DUMP_TXDESC
+	int i;
+	printk("<Tx descriptor>--rate %x---",rate);
+	for (i = 0; i < 8; i++)
+		printk("%8x ", tx[i]);
+	printk("\n");
+#endif
+	usb_fill_bulk_urb(tx_urb,priv->udev, usb_sndbulkpipe(priv->udev,idx_pipe), \
+			skb->data, skb->len, rtl8192_tx_isr, skb);
+
+	status = usb_submit_urb(tx_urb, GFP_ATOMIC);
+
+	if (!status){
+		return 0;
+	}else{
+		DMESGE("Error TX CMD URB, error %d",
+				status);
+		return -1;
+	}
+}
+
+/*
+ * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
+ * in TxFwInfo data structure
+ * 2006.10.30 by Emily
+ *
+ * \param QUEUEID       Software Queue
+*/
+u8 MapHwQueueToFirmwareQueue(u8 QueueID)
+{
+	u8 QueueSelect = 0x0;       //defualt set to
+
+	switch(QueueID) {
+		case BE_QUEUE:
+			QueueSelect = QSLT_BE;  //or QSelect = pTcb->priority;
+			break;
+
+		case BK_QUEUE:
+			QueueSelect = QSLT_BK;  //or QSelect = pTcb->priority;
+			break;
+
+		case VO_QUEUE:
+			QueueSelect = QSLT_VO;  //or QSelect = pTcb->priority;
+			break;
+
+		case VI_QUEUE:
+			QueueSelect = QSLT_VI;  //or QSelect = pTcb->priority;
+			break;
+		case MGNT_QUEUE:
+			QueueSelect = QSLT_MGNT;
+			break;
+
+		case BEACON_QUEUE:
+			QueueSelect = QSLT_BEACON;
+			break;
+
+			// TODO: 2006.10.30 mark other queue selection until we verify it is OK
+			// TODO: Remove Assertions
+//#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
+		case TXCMD_QUEUE:
+			QueueSelect = QSLT_CMD;
+			break;
+//#endif
+		case HIGH_QUEUE:
+			QueueSelect = QSLT_HIGH;
+			break;
+
+		default:
+			RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
+			break;
+	}
+	return QueueSelect;
+}
+
+u8 MRateToHwRate8190Pci(u8 rate)
+{
+	u8  ret = DESC90_RATE1M;
+
+	switch(rate) {
+		case MGN_1M:    ret = DESC90_RATE1M;    break;
+		case MGN_2M:    ret = DESC90_RATE2M;    break;
+		case MGN_5_5M:  ret = DESC90_RATE5_5M;  break;
+		case MGN_11M:   ret = DESC90_RATE11M;   break;
+		case MGN_6M:    ret = DESC90_RATE6M;    break;
+		case MGN_9M:    ret = DESC90_RATE9M;    break;
+		case MGN_12M:   ret = DESC90_RATE12M;   break;
+		case MGN_18M:   ret = DESC90_RATE18M;   break;
+		case MGN_24M:   ret = DESC90_RATE24M;   break;
+		case MGN_36M:   ret = DESC90_RATE36M;   break;
+		case MGN_48M:   ret = DESC90_RATE48M;   break;
+		case MGN_54M:   ret = DESC90_RATE54M;   break;
+
+		// HT rate since here
+		case MGN_MCS0:  ret = DESC90_RATEMCS0;  break;
+		case MGN_MCS1:  ret = DESC90_RATEMCS1;  break;
+		case MGN_MCS2:  ret = DESC90_RATEMCS2;  break;
+		case MGN_MCS3:  ret = DESC90_RATEMCS3;  break;
+		case MGN_MCS4:  ret = DESC90_RATEMCS4;  break;
+		case MGN_MCS5:  ret = DESC90_RATEMCS5;  break;
+		case MGN_MCS6:  ret = DESC90_RATEMCS6;  break;
+		case MGN_MCS7:  ret = DESC90_RATEMCS7;  break;
+		case MGN_MCS8:  ret = DESC90_RATEMCS8;  break;
+		case MGN_MCS9:  ret = DESC90_RATEMCS9;  break;
+		case MGN_MCS10: ret = DESC90_RATEMCS10; break;
+		case MGN_MCS11: ret = DESC90_RATEMCS11; break;
+		case MGN_MCS12: ret = DESC90_RATEMCS12; break;
+		case MGN_MCS13: ret = DESC90_RATEMCS13; break;
+		case MGN_MCS14: ret = DESC90_RATEMCS14; break;
+		case MGN_MCS15: ret = DESC90_RATEMCS15; break;
+		case (0x80|0x20): ret = DESC90_RATEMCS32; break;
+
+		default:       break;
+	}
+	return ret;
+}
+
+
+u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
+{
+	u8   tmp_Short;
+
+	tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
+
+	if(TxHT==1 && TxRate != DESC90_RATEMCS15)
+		tmp_Short = 0;
+
+	return tmp_Short;
+}
+
+static void tx_zero_isr(struct urb *tx_urb)
+{
+	return;
+}
+
+/*
+ * The tx procedure is just as following,
+ * skb->cb will contain all the following information,
+ * priority, morefrag, rate, &dev.
+ * */
+short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	tx_desc_819x_usb *tx_desc = (tx_desc_819x_usb *)skb->data;
+	tx_fwinfo_819x_usb *tx_fwinfo = (tx_fwinfo_819x_usb *)(skb->data + USB_HWDESC_HEADER_LEN);
+	struct usb_device *udev = priv->udev;
+	int pend;
+	int status;
+	struct urb *tx_urb = NULL, *tx_urb_zero = NULL;
+	//int urb_len;
+	unsigned int idx_pipe;
+//	RT_DEBUG_DATA(COMP_SEND, tcb_desc, sizeof(cb_desc));
+//	printk("=============> %s\n", __FUNCTION__);
+	pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]);
+	/* we are locked here so the two atomic_read and inc are executed
+	 * without interleaves
+	 * !!! For debug purpose
+	 */
+	if( pend > MAX_TX_URB){
+		printk("To discard skb packet!\n");
+		dev_kfree_skb_any(skb);
+		return -1;
+	}
+
+	tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
+	if(!tx_urb){
+		dev_kfree_skb_any(skb);
+		return -ENOMEM;
+	}
+
+	/* Fill Tx firmware info */
+	memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
+	/* DWORD 0 */
+	tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
+	tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
+	tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
+	tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
+	if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
+		tx_fwinfo->AllowAggregation = 1;
+		/* DWORD 1 */
+		tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
+		tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
+	} else {
+		tx_fwinfo->AllowAggregation = 0;
+		/* DWORD 1 */
+		tx_fwinfo->RxMF = 0;
+		tx_fwinfo->RxAMD = 0;
+	}
+
+	/* Protection mode related */
+	tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
+	tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
+	tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
+	tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
+	tx_fwinfo->RtsRate =  MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
+	tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
+	tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
+	tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
+				(tcb_desc->bRTSUseShortGI?1:0);
+
+	/* Set Bandwidth and sub-channel settings. */
+	if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
+	{
+		if(tcb_desc->bPacketBW) {
+			tx_fwinfo->TxBandwidth = 1;
+			tx_fwinfo->TxSubCarrier = 0;    //By SD3's Jerry suggestion, use duplicated mode
+		} else {
+			tx_fwinfo->TxBandwidth = 0;
+			tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
+		}
+	} else {
+		tx_fwinfo->TxBandwidth = 0;
+		tx_fwinfo->TxSubCarrier = 0;
+	}
+
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+	if (tcb_desc->drv_agg_enable)
+	{
+		tx_fwinfo->Tx_INFO_RSVD = (tcb_desc->DrvAggrNum & 0x1f) << 1;
+	}
+#endif
+	/* Fill Tx descriptor */
+	memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
+	/* DWORD 0 */
+	tx_desc->LINIP = 0;
+	tx_desc->CmdInit = 1;
+	tx_desc->Offset =  sizeof(tx_fwinfo_819x_usb) + 8;
+
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+	if (tcb_desc->drv_agg_enable) {
+		tx_desc->PktSize = tcb_desc->pkt_size;
+	} else
+#endif
+	{
+		tx_desc->PktSize = (skb->len - TX_PACKET_SHIFT_BYTES) & 0xffff;
+	}
+
+	/*DWORD 1*/
+	tx_desc->SecCAMID= 0;
+	tx_desc->RATid = tcb_desc->RATRIndex;
+	{
+		//MPDUOverhead = 0;
+		tx_desc->NoEnc = 1;
+	}
+	tx_desc->SecType = 0x0;
+		if (tcb_desc->bHwSec)
+			{
+				switch (priv->ieee80211->pairwise_key_type)
+				{
+					case KEY_TYPE_WEP40:
+					case KEY_TYPE_WEP104:
+						 tx_desc->SecType = 0x1;
+						 tx_desc->NoEnc = 0;
+						 break;
+					case KEY_TYPE_TKIP:
+						 tx_desc->SecType = 0x2;
+						 tx_desc->NoEnc = 0;
+						 break;
+					case KEY_TYPE_CCMP:
+						 tx_desc->SecType = 0x3;
+						 tx_desc->NoEnc = 0;
+						 break;
+					case KEY_TYPE_NA:
+						 tx_desc->SecType = 0x0;
+						 tx_desc->NoEnc = 1;
+						 break;
+				}
+			}
+
+	tx_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
+	tx_desc->TxFWInfoSize =  sizeof(tx_fwinfo_819x_usb);
+
+	tx_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
+	tx_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
+
+	/* Fill fields that are required to be initialized in all of the descriptors */
+	//DWORD 0
+	tx_desc->FirstSeg = 1;
+	tx_desc->LastSeg = 1;
+	tx_desc->OWN = 1;
+
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+	if (tcb_desc->drv_agg_enable) {
+		tx_desc->TxBufferSize = tcb_desc->pkt_size + sizeof(tx_fwinfo_819x_usb);
+	} else
+#endif
+	{
+		//DWORD 2
+		tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN);
+	}
+	/* Get index to out pipe from specified QueueID */
+#ifndef USE_ONE_PIPE
+	idx_pipe = txqueue2outpipe(priv,tcb_desc->queue_index);
+#else
+	idx_pipe = 0x5;
+#endif
+
+	//RT_DEBUG_DATA(COMP_SEND,tx_fwinfo,sizeof(tx_fwinfo_819x_usb));
+	//RT_DEBUG_DATA(COMP_SEND,tx_desc,sizeof(tx_desc_819x_usb));
+
+	/* To submit bulk urb */
+	usb_fill_bulk_urb(tx_urb,udev,
+			usb_sndbulkpipe(udev,idx_pipe), skb->data,
+			skb->len, rtl8192_tx_isr, skb);
+
+	status = usb_submit_urb(tx_urb, GFP_ATOMIC);
+	if (!status){
+//we need to send 0 byte packet whenever 512N bytes/64N(HIGN SPEED/NORMAL SPEED) bytes packet has been transmitted. Otherwise, it will be halt to wait for another packet. WB. 2008.08.27
+		bool bSend0Byte = false;
+		u8 zero = 0;
+		if(udev->speed == USB_SPEED_HIGH)
+		{
+			if (skb->len > 0 && skb->len % 512 == 0)
+				bSend0Byte = true;
+		}
+		else
+		{
+			if (skb->len > 0 && skb->len % 64 == 0)
+				bSend0Byte = true;
+		}
+		if (bSend0Byte)
+		{
+			tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC);
+			if(!tx_urb_zero){
+				RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
+				return -ENOMEM;
+			}
+			usb_fill_bulk_urb(tx_urb_zero,udev,
+					usb_sndbulkpipe(udev,idx_pipe), &zero,
+					0, tx_zero_isr, dev);
+			status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
+			if (status){
+			RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
+			return -1;
+			}
+		}
+		dev->trans_start = jiffies;
+		atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
+		return 0;
+	}else{
+		RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
+				status);
+		return -1;
+	}
+}
+
+short rtl8192_usb_initendpoints(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	priv->rx_urb = (struct urb**) kmalloc (sizeof(struct urb*) * (MAX_RX_URB+1), GFP_KERNEL);
+
+#ifndef JACKSON_NEW_RX
+	for(i=0;i<(MAX_RX_URB+1);i++){
+
+		priv->rx_urb[i] = usb_alloc_urb(0,GFP_KERNEL);
+
+		priv->rx_urb[i]->transfer_buffer = kmalloc(RX_URB_SIZE, GFP_KERNEL);
+
+		priv->rx_urb[i]->transfer_buffer_length = RX_URB_SIZE;
+	}
+#endif
+
+#ifdef THOMAS_BEACON
+{
+	long align = 0;
+	void *oldaddr, *newaddr;
+
+	priv->rx_urb[16] = usb_alloc_urb(0, GFP_KERNEL);
+	priv->oldaddr = kmalloc(16, GFP_KERNEL);
+	oldaddr = priv->oldaddr;
+	align = ((long)oldaddr) & 3;
+	if (align) {
+		newaddr = oldaddr + 4 - align;
+		priv->rx_urb[16]->transfer_buffer_length = 16 - 4 + align;
+	} else {
+		newaddr = oldaddr;
+		priv->rx_urb[16]->transfer_buffer_length = 16;
+	}
+	priv->rx_urb[16]->transfer_buffer = newaddr;
+}
+#endif
+
+	memset(priv->rx_urb, 0, sizeof(struct urb*) * MAX_RX_URB);
+	priv->pp_rxskb = (struct sk_buff **)kmalloc(sizeof(struct sk_buff *) * MAX_RX_URB, GFP_KERNEL);
+	if (priv->pp_rxskb == NULL)
+		goto destroy;
+
+	memset(priv->pp_rxskb, 0, sizeof(struct sk_buff*) * MAX_RX_URB);
+
+	goto _middle;
+
+
+destroy:
+	if (priv->pp_rxskb) {
+		kfree(priv->pp_rxskb);
+	}
+	if (priv->rx_urb) {
+		kfree(priv->rx_urb);
+	}
+
+	priv->pp_rxskb = NULL;
+	priv->rx_urb = NULL;
+
+	DMESGE("Endpoint Alloc Failure");
+	return -ENOMEM;
+
+
+_middle:
+
+	printk("End of initendpoints\n");
+	return 0;
+
+}
+#ifdef THOMAS_BEACON
+void rtl8192_usb_deleteendpoints(struct net_device *dev)
+{
+	int i;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	if(priv->rx_urb){
+		for(i=0;i<(MAX_RX_URB+1);i++){
+			usb_kill_urb(priv->rx_urb[i]);
+			usb_free_urb(priv->rx_urb[i]);
+		}
+		kfree(priv->rx_urb);
+		priv->rx_urb = NULL;
+	}
+	if(priv->oldaddr){
+		kfree(priv->oldaddr);
+		priv->oldaddr = NULL;
+	}
+	if (priv->pp_rxskb) {
+		kfree(priv->pp_rxskb);
+		priv->pp_rxskb = 0;
+	}
+}
+#else
+void rtl8192_usb_deleteendpoints(struct net_device *dev)
+{
+	int i;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+#ifndef JACKSON_NEW_RX
+
+	if(priv->rx_urb){
+		for(i=0;i<(MAX_RX_URB+1);i++){
+			usb_kill_urb(priv->rx_urb[i]);
+			kfree(priv->rx_urb[i]->transfer_buffer);
+			usb_free_urb(priv->rx_urb[i]);
+		}
+		kfree(priv->rx_urb);
+		priv->rx_urb = NULL;
+
+	}
+#else
+	if(priv->rx_urb){
+		kfree(priv->rx_urb);
+		priv->rx_urb = NULL;
+	}
+	if(priv->oldaddr){
+		kfree(priv->oldaddr);
+		priv->oldaddr = NULL;
+	}
+	if (priv->pp_rxskb) {
+		kfree(priv->pp_rxskb);
+		priv->pp_rxskb = 0;
+
+	}
+
+#endif
+}
+#endif
+
+extern void rtl8192_update_ratr_table(struct net_device* dev);
+void rtl8192_link_change(struct net_device *dev)
+{
+//	int i;
+
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_device* ieee = priv->ieee80211;
+	//write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
+	if (ieee->state == IEEE80211_LINKED)
+	{
+		rtl8192_net_update(dev);
+		rtl8192_update_ratr_table(dev);
+		//add this as in pure N mode, wep encryption will use software way, but there is no chance to set this as wep will not set group key in wext. WB.2008.07.08
+		if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
+		EnableHWSecurityConfig8192(dev);
+	}
+	/*update timing params*/
+//	RT_TRACE(COMP_CH, "========>%s(), chan:%d\n", __FUNCTION__, priv->chan);
+//	rtl8192_set_chan(dev, priv->chan);
+	 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
+        {
+                u32 reg = 0;
+                reg = read_nic_dword(dev, RCR);
+                if (priv->ieee80211->state == IEEE80211_LINKED)
+                        priv->ReceiveConfig = reg |= RCR_CBSSID;
+                else
+                        priv->ReceiveConfig = reg &= ~RCR_CBSSID;
+                write_nic_dword(dev, RCR, reg);
+        }
+
+//	rtl8192_set_rxconf(dev);
+}
+
+static struct ieee80211_qos_parameters def_qos_parameters = {
+        {3,3,3,3},/* cw_min */
+        {7,7,7,7},/* cw_max */
+        {2,2,2,2},/* aifs */
+        {0,0,0,0},/* flags */
+        {0,0,0,0} /* tx_op_limit */
+};
+
+
+void rtl8192_update_beacon(struct work_struct * work)
+{
+        struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
+        struct net_device *dev = priv->ieee80211->dev;
+ 	struct ieee80211_device* ieee = priv->ieee80211;
+	struct ieee80211_network* net = &ieee->current_network;
+
+	if (ieee->pHTInfo->bCurrentHTSupport)
+		HTUpdateSelfAndPeerSetting(ieee, net);
+	ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
+	rtl8192_update_cap(dev, net->capability);
+}
+/*
+* background support to run QoS activate functionality
+*/
+int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
+void rtl8192_qos_activate(struct work_struct * work)
+{
+	struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
+	struct net_device *dev = priv->ieee80211->dev;
+	struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
+	u8 mode = priv->ieee80211->current_network.mode;
+	//u32 size = sizeof(struct ieee80211_qos_parameters);
+	u8  u1bAIFS;
+	u32 u4bAcParam;
+	int i;
+
+	if (priv == NULL)
+		return;
+
+       mutex_lock(&priv->mutex);
+	if(priv->ieee80211->state != IEEE80211_LINKED)
+		goto success;
+	RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
+	/* It better set slot time at first */
+	/* For we just support b/g mode at present, let the slot time at 9/20 selection */
+	/* update the ac parameter to related registers */
+	for(i = 0; i <  QOS_QUEUE_NUM; i++) {
+		//Mode G/A: slotTimeTimer = 9; Mode B: 20
+		u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
+		u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
+				(((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
+				(((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
+				((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
+
+		write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
+		//write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
+	}
+
+success:
+       mutex_unlock(&priv->mutex);
+}
+
+static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
+		int active_network,
+		struct ieee80211_network *network)
+{
+	int ret = 0;
+	u32 size = sizeof(struct ieee80211_qos_parameters);
+
+	if(priv->ieee80211->state !=IEEE80211_LINKED)
+		return ret;
+
+	if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
+		return ret;
+
+	if (network->flags & NETWORK_HAS_QOS_MASK) {
+		if (active_network &&
+				(network->flags & NETWORK_HAS_QOS_PARAMETERS))
+			network->qos_data.active = network->qos_data.supported;
+
+		if ((network->qos_data.active == 1) && (active_network == 1) &&
+				(network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
+				(network->qos_data.old_param_count !=
+				 network->qos_data.param_count)) {
+			network->qos_data.old_param_count =
+				network->qos_data.param_count;
+			queue_work(priv->priv_wq, &priv->qos_activate);
+			RT_TRACE (COMP_QOS, "QoS parameters change call "
+					"qos_activate\n");
+		}
+	} else {
+		memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
+		       &def_qos_parameters, size);
+
+		if ((network->qos_data.active == 1) && (active_network == 1)) {
+			queue_work(priv->priv_wq, &priv->qos_activate);
+			RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
+		}
+		network->qos_data.active = 0;
+		network->qos_data.supported = 0;
+	}
+
+	return 0;
+}
+
+/* handle manage frame frame beacon and probe response */
+static int rtl8192_handle_beacon(struct net_device * dev,
+			      struct ieee80211_beacon * beacon,
+			      struct ieee80211_network * network)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	rtl8192_qos_handle_probe_response(priv,1,network);
+	queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
+	return 0;
+
+}
+
+/*
+* handling the beaconing responses. if we get different QoS setting
+* off the network from the associated setting, adjust the QoS
+* setting
+*/
+static int rtl8192_qos_association_resp(struct r8192_priv *priv,
+				    struct ieee80211_network *network)
+{
+	int ret = 0;
+	unsigned long flags;
+	u32 size = sizeof(struct ieee80211_qos_parameters);
+	int set_qos_param = 0;
+
+	if ((priv == NULL) || (network == NULL))
+		return ret;
+
+	if(priv->ieee80211->state !=IEEE80211_LINKED)
+		return ret;
+
+	if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
+		return ret;
+
+	spin_lock_irqsave(&priv->ieee80211->lock, flags);
+	if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
+		memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
+			 &network->qos_data.parameters,\
+			sizeof(struct ieee80211_qos_parameters));
+		priv->ieee80211->current_network.qos_data.active = 1;
+		 {
+			set_qos_param = 1;
+			/* update qos parameter for current network */
+			priv->ieee80211->current_network.qos_data.old_param_count = \
+				 priv->ieee80211->current_network.qos_data.param_count;
+			priv->ieee80211->current_network.qos_data.param_count = \
+				 network->qos_data.param_count;
+		}
+	} else {
+		memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
+		       &def_qos_parameters, size);
+		priv->ieee80211->current_network.qos_data.active = 0;
+		priv->ieee80211->current_network.qos_data.supported = 0;
+		set_qos_param = 1;
+	}
+
+	spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
+
+	RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
+	if (set_qos_param == 1)
+		queue_work(priv->priv_wq, &priv->qos_activate);
+
+
+	return ret;
+}
+
+
+static int rtl8192_handle_assoc_response(struct net_device *dev,
+				     struct ieee80211_assoc_response_frame *resp,
+				     struct ieee80211_network *network)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	rtl8192_qos_association_resp(priv, network);
+	return 0;
+}
+
+
+void rtl8192_update_ratr_table(struct net_device* dev)
+	//	POCTET_STRING	posLegacyRate,
+	//	u8*			pMcsRate)
+	//	PRT_WLAN_STA	pEntry)
+{
+	struct r8192_priv* priv = ieee80211_priv(dev);
+	struct ieee80211_device* ieee = priv->ieee80211;
+	u8* pMcsRate = ieee->dot11HTOperationalRateSet;
+	//struct ieee80211_network *net = &ieee->current_network;
+	u32 ratr_value = 0;
+	u8 rate_index = 0;
+	rtl8192_config_rate(dev, (u16*)(&ratr_value));
+	ratr_value |= (*(u16*)(pMcsRate)) << 12;
+//	switch (net->mode)
+	switch (ieee->mode)
+	{
+		case IEEE_A:
+			ratr_value &= 0x00000FF0;
+			break;
+		case IEEE_B:
+			ratr_value &= 0x0000000F;
+			break;
+		case IEEE_G:
+			ratr_value &= 0x00000FF7;
+			break;
+		case IEEE_N_24G:
+		case IEEE_N_5G:
+			if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
+				ratr_value &= 0x0007F007;
+			else{
+				if (priv->rf_type == RF_1T2R)
+					ratr_value &= 0x000FF007;
+				else
+					ratr_value &= 0x0F81F007;
+			}
+			break;
+		default:
+			break;
+	}
+	ratr_value &= 0x0FFFFFFF;
+	if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
+		ratr_value |= 0x80000000;
+	}else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
+		ratr_value |= 0x80000000;
+	}
+	write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
+	write_nic_byte(dev, UFWP, 1);
+}
+
+static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
+static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
+bool GetNmodeSupportBySecCfg8192(struct net_device*dev)
+{
+	struct r8192_priv* priv = ieee80211_priv(dev);
+	struct ieee80211_device* ieee = priv->ieee80211;
+	struct ieee80211_network * network = &ieee->current_network;
+	int wpa_ie_len= ieee->wpa_ie_len;
+	struct ieee80211_crypt_data* crypt;
+	int encrypt;
+
+	crypt = ieee->crypt[ieee->tx_keyidx];
+	//we use connecting AP's capability instead of only security config on our driver to distinguish whether it should use N mode or G mode
+	encrypt = (network->capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
+
+	/* simply judge  */
+	if(encrypt && (wpa_ie_len == 0)) {
+		/* wep encryption, no N mode setting */
+		return false;
+//	} else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
+	} else if((wpa_ie_len != 0)) {
+		/* parse pairwise key type */
+		//if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
+		if (((ieee->wpa_ie[0] == 0xdd) && (!memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) || ((ieee->wpa_ie[0] == 0x30) && (!memcmp(&ieee->wpa_ie[10],ccmp_rsn_ie, 4))))
+			return true;
+		else
+			return false;
+	} else {
+		return true;
+	}
+
+	return true;
+}
+
+bool GetHalfNmodeSupportByAPs819xUsb(struct net_device* dev)
+{
+	bool			Reval;
+	struct r8192_priv* priv = ieee80211_priv(dev);
+	struct ieee80211_device* ieee = priv->ieee80211;
+
+	if(ieee->bHalfWirelessN24GMode == true)
+		Reval = true;
+	else
+		Reval =  false;
+
+	return Reval;
+}
+
+void rtl8192_refresh_supportrate(struct r8192_priv* priv)
+{
+	struct ieee80211_device* ieee = priv->ieee80211;
+	//we donot consider set support rate for ABG mode, only HT MCS rate is set here.
+	if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
+	{
+		memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
+		//RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
+		//RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
+	}
+	else
+		memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
+	return;
+}
+
+u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 ret = 0;
+	switch(priv->rf_chip)
+	{
+		case RF_8225:
+		case RF_8256:
+		case RF_PSEUDO_11N:
+			ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
+			break;
+		case RF_8258:
+			ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
+			break;
+		default:
+			ret = WIRELESS_MODE_B;
+			break;
+	}
+	return ret;
+}
+void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
+
+	if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
+	{
+		if(bSupportMode & WIRELESS_MODE_N_24G)
+		{
+			wireless_mode = WIRELESS_MODE_N_24G;
+		}
+		else if(bSupportMode & WIRELESS_MODE_N_5G)
+		{
+			wireless_mode = WIRELESS_MODE_N_5G;
+		}
+		else if((bSupportMode & WIRELESS_MODE_A))
+		{
+			wireless_mode = WIRELESS_MODE_A;
+		}
+		else if((bSupportMode & WIRELESS_MODE_G))
+		{
+			wireless_mode = WIRELESS_MODE_G;
+		}
+		else if((bSupportMode & WIRELESS_MODE_B))
+		{
+			wireless_mode = WIRELESS_MODE_B;
+		}
+		else{
+			RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
+			wireless_mode = WIRELESS_MODE_B;
+		}
+	}
+#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA
+	ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
+#endif
+	priv->ieee80211->mode = wireless_mode;
+
+	if ((wireless_mode == WIRELESS_MODE_N_24G) ||  (wireless_mode == WIRELESS_MODE_N_5G))
+		priv->ieee80211->pHTInfo->bEnableHT = 1;
+	else
+		priv->ieee80211->pHTInfo->bEnableHT = 0;
+	RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
+	rtl8192_refresh_supportrate(priv);
+
+}
+//init priv variables here. only non_zero value should be initialized here.
+static void rtl8192_init_priv_variable(struct net_device* dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 i;
+	priv->card_8192 = NIC_8192U;
+	priv->chan = 1; //set to channel 1
+	priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
+	priv->ieee80211->iw_mode = IW_MODE_INFRA;
+	priv->ieee80211->ieee_up=0;
+	priv->retry_rts = DEFAULT_RETRY_RTS;
+	priv->retry_data = DEFAULT_RETRY_DATA;
+	priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
+	priv->ieee80211->rate = 110; //11 mbps
+	priv->ieee80211->short_slot = 1;
+	priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
+	priv->CckPwEnl = 6;
+	//for silent reset
+	priv->IrpPendingCount = 1;
+	priv->ResetProgress = RESET_TYPE_NORESET;
+	priv->bForcedSilentReset = 0;
+	priv->bDisableNormalResetCheck = false;
+	priv->force_reset = false;
+
+	priv->ieee80211->FwRWRF = 0; 	//we don't use FW read/write RF until stable firmware is available.
+	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 |
+		IEEE_SOFTMAC_BEACONS;//added by amy 080604 //|  //IEEE_SOFTMAC_SINGLE_QUEUE;
+
+	priv->ieee80211->active_scan = 1;
+	priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
+	priv->ieee80211->host_encrypt = 1;
+	priv->ieee80211->host_decrypt = 1;
+	priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
+	priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
+	priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
+	priv->ieee80211->set_chan = rtl8192_set_chan;
+	priv->ieee80211->link_change = rtl8192_link_change;
+	priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
+	priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
+	priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
+	priv->ieee80211->init_wmmparam_flag = 0;
+	priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
+	priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
+	priv->ieee80211->tx_headroom = TX_PACKET_SHIFT_BYTES;
+	priv->ieee80211->qos_support = 1;
+
+	//added by WB
+//	priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
+	priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
+	priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
+	priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
+	//added by david
+	priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8192;
+	priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xUsb;
+	priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
+	//added by amy
+	priv->ieee80211->InitialGainHandler = InitialGain819xUsb;
+	priv->card_type = USB;
+#ifdef TO_DO_LIST
+	if(Adapter->bInHctTest)
+	{
+		pHalData->ShortRetryLimit = 7;
+		pHalData->LongRetryLimit = 7;
+	}
+#endif
+	{
+		priv->ShortRetryLimit = 0x30;
+		priv->LongRetryLimit = 0x30;
+	}
+	priv->EarlyRxThreshold = 7;
+	priv->enable_gpio0 = 0;
+	priv->TransmitConfig =
+	//	TCR_DurProcMode |	//for RTL8185B, duration setting by HW
+	//?	TCR_DISReqQsize |
+		(TCR_MXDMA_2048<<TCR_MXDMA_OFFSET)|  // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
+		(priv->ShortRetryLimit<<TCR_SRL_OFFSET)|	// Short retry limit
+		(priv->LongRetryLimit<<TCR_LRL_OFFSET) |	// Long retry limit
+		(false ? TCR_SAT: 0);	// FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
+#ifdef TO_DO_LIST
+	if(Adapter->bInHctTest)
+		pHalData->ReceiveConfig	=	pHalData->CSMethod |
+						RCR_AMF | RCR_ADF |	//RCR_AAP | 	//accept management/data
+						//guangan200710
+						RCR_ACF |	//accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
+						RCR_AB | RCR_AM | RCR_APM |		//accept BC/MC/UC
+						RCR_AICV | RCR_ACRC32 | 		//accept ICV/CRC error packet
+						((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
+						(pHalData->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
+						(pHalData->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt:0);
+	else
+
+#endif
+	priv->ReceiveConfig	=
+		RCR_AMF | RCR_ADF |		//accept management/data
+		RCR_ACF |			//accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
+		RCR_AB | RCR_AM | RCR_APM |	//accept BC/MC/UC
+		//RCR_AICV | RCR_ACRC32 | 	//accept ICV/CRC error packet
+		((u32)7<<RCR_MXDMA_OFFSET)| // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
+		(priv->EarlyRxThreshold<<RX_FIFO_THRESHOLD_SHIFT) | // Rx FIFO Threshold, 7: No Rx threshold.
+		(priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0);
+
+	priv->AcmControl = 0;
+	priv->pFirmware = (rt_firmware*)kmalloc(sizeof(rt_firmware), GFP_KERNEL);
+	if (priv->pFirmware)
+	memset(priv->pFirmware, 0, sizeof(rt_firmware));
+
+	/* rx related queue */
+	skb_queue_head_init(&priv->rx_queue);
+	skb_queue_head_init(&priv->skb_queue);
+
+	/* Tx related queue */
+	for(i = 0; i < MAX_QUEUE_SIZE; i++) {
+		skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
+	}
+	for(i = 0; i < MAX_QUEUE_SIZE; i++) {
+		skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
+	}
+	for(i = 0; i < MAX_QUEUE_SIZE; i++) {
+		skb_queue_head_init(&priv->ieee80211->skb_drv_aggQ [i]);
+	}
+	priv->rf_set_chan = rtl8192_phy_SwChnl;
+}
+
+//init lock here
+static void rtl8192_init_priv_lock(struct r8192_priv* priv)
+{
+	spin_lock_init(&priv->tx_lock);
+	spin_lock_init(&priv->irq_lock);//added by thomas
+	//spin_lock_init(&priv->rf_lock);
+	sema_init(&priv->wx_sem,1);
+	sema_init(&priv->rf_sem,1);
+	mutex_init(&priv->mutex);
+}
+
+extern  void    rtl819x_watchdog_wqcallback(struct work_struct *work);
+
+void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
+//init tasklet and wait_queue here. only 2.6 above kernel is considered
+#define DRV_NAME "wlan0"
+static void rtl8192_init_priv_task(struct net_device* dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+#ifdef PF_SYNCTHREAD
+	priv->priv_wq = create_workqueue(DRV_NAME,0);
+#else
+	priv->priv_wq = create_workqueue(DRV_NAME);
+#endif
+
+	INIT_WORK(&priv->reset_wq, rtl8192_restart);
+
+	//INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
+	INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
+	INIT_DELAYED_WORK(&priv->txpower_tracking_wq,  dm_txpower_trackingcallback);
+//	INIT_DELAYED_WORK(&priv->gpio_change_rf_wq,  dm_gpio_change_rf_callback);
+	INIT_DELAYED_WORK(&priv->rfpath_check_wq,  dm_rf_pathcheck_workitemcallback);
+	INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
+	INIT_DELAYED_WORK(&priv->initialgain_operate_wq, InitialGainOperateWorkItemCallBack);
+	//INIT_WORK(&priv->SwChnlWorkItem,  rtl8192_SwChnl_WorkItem);
+	//INIT_WORK(&priv->SetBWModeWorkItem,  rtl8192_SetBWModeWorkItem);
+	INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
+
+	tasklet_init(&priv->irq_rx_tasklet,
+	     (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
+	     (unsigned long)priv);
+}
+
+static void rtl8192_get_eeprom_size(struct net_device* dev)
+{
+	u16 curCR = 0;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
+	curCR = read_nic_word_E(dev,EPROM_CMD);
+	RT_TRACE(COMP_EPROM, "read from Reg EPROM_CMD(%x):%x\n", EPROM_CMD, curCR);
+	//whether need I consider BIT5?
+	priv->epromtype = (curCR & Cmd9346CR_9356SEL) ? EPROM_93c56 : EPROM_93c46;
+	RT_TRACE(COMP_EPROM, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
+}
+
+//used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead.
+static inline u16 endian_swap(u16* data)
+{
+	u16 tmp = *data;
+	*data = (tmp >> 8) | (tmp << 8);
+	return *data;
+}
+static void rtl8192_read_eeprom_info(struct net_device* dev)
+{
+	u16 wEPROM_ID = 0;
+	u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x02};
+	u8 bLoad_From_EEPOM = false;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u16 tmpValue = 0;
+	RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
+	wEPROM_ID = eprom_read(dev, 0); //first read EEPROM ID out;
+	RT_TRACE(COMP_EPROM, "EEPROM ID is 0x%x\n", wEPROM_ID);
+
+	if (wEPROM_ID != RTL8190_EEPROM_ID)
+	{
+		RT_TRACE(COMP_ERR, "EEPROM ID is invalid(is 0x%x(should be 0x%x)\n", wEPROM_ID, RTL8190_EEPROM_ID);
+	}
+	else
+		bLoad_From_EEPOM = true;
+
+	if (bLoad_From_EEPOM)
+	{
+		tmpValue = eprom_read(dev, (EEPROM_VID>>1));
+		priv->eeprom_vid = endian_swap(&tmpValue);
+		priv->eeprom_pid = eprom_read(dev, (EEPROM_PID>>1));
+		tmpValue = eprom_read(dev, (EEPROM_ChannelPlan>>1));
+		priv->eeprom_ChannelPlan =((tmpValue&0xff00)>>8);
+		priv->btxpowerdata_readfromEEPORM = true;
+		priv->eeprom_CustomerID = eprom_read(dev, (EEPROM_Customer_ID>>1)) >>8;
+	}
+	else
+	{
+		priv->eeprom_vid = 0;
+		priv->eeprom_pid = 0;
+		priv->card_8192_version = VERSION_819xU_B;
+		priv->eeprom_ChannelPlan = 0;
+		priv->eeprom_CustomerID = 0;
+	}
+	RT_TRACE(COMP_EPROM, "vid:0x%4x, pid:0x%4x, CustomID:0x%2x, ChanPlan:0x%x\n", priv->eeprom_vid, priv->eeprom_pid, priv->eeprom_CustomerID, priv->eeprom_ChannelPlan);
+	//set channelplan from eeprom
+	priv->ChannelPlan = priv->eeprom_ChannelPlan;
+	if (bLoad_From_EEPOM)
+	{
+		int i;
+		for (i=0; i<6; i+=2)
+		{
+			u16 tmp = 0;
+			tmp = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i)>>1));
+			*(u16*)(&dev->dev_addr[i]) = tmp;
+		}
+	}
+	else
+	{
+		memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
+		//should I set IDR0 here?
+	}
+	RT_TRACE(COMP_EPROM, "MAC addr:"MAC_FMT"\n", MAC_ARG(dev->dev_addr));
+	priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
+	priv->rf_chip = RF_8256;
+
+	if (priv->card_8192_version == (u8)VERSION_819xU_A)
+	{
+		//read Tx power gain offset of legacy OFDM to HT rate
+		if (bLoad_From_EEPOM)
+			priv->EEPROMTxPowerDiff = (eprom_read(dev, (EEPROM_TxPowerDiff>>1))&0xff00) >> 8;
+		else
+			priv->EEPROMTxPowerDiff = EEPROM_Default_TxPower;
+		RT_TRACE(COMP_EPROM, "TxPowerDiff:%d\n", priv->EEPROMTxPowerDiff);
+		//read ThermalMeter from EEPROM
+		if (bLoad_From_EEPOM)
+			priv->EEPROMThermalMeter = (u8)(eprom_read(dev, (EEPROM_ThermalMeter>>1))&0x00ff);
+		else
+			priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
+		RT_TRACE(COMP_EPROM, "ThermalMeter:%d\n", priv->EEPROMThermalMeter);
+		//vivi, for tx power track
+		priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
+		//read antenna tx power offset of B/C/D to A from EEPROM
+		if (bLoad_From_EEPOM)
+			priv->EEPROMPwDiff = (eprom_read(dev, (EEPROM_PwDiff>>1))&0x0f00)>>8;
+		else
+			priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
+		RT_TRACE(COMP_EPROM, "TxPwDiff:%d\n", priv->EEPROMPwDiff);
+		// Read CrystalCap from EEPROM
+		if (bLoad_From_EEPOM)
+			priv->EEPROMCrystalCap = (eprom_read(dev, (EEPROM_CrystalCap>>1))&0x0f);
+		else
+			priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
+		RT_TRACE(COMP_EPROM, "CrystalCap = %d\n", priv->EEPROMCrystalCap);
+		//get per-channel Tx power level
+		if (bLoad_From_EEPOM)
+			priv->EEPROM_Def_Ver = (eprom_read(dev, (EEPROM_TxPwIndex_Ver>>1))&0xff00)>>8;
+		else
+			priv->EEPROM_Def_Ver = 1;
+		RT_TRACE(COMP_EPROM, "EEPROM_DEF_VER:%d\n", priv->EEPROM_Def_Ver);
+		if (priv->EEPROM_Def_Ver == 0) //old eeprom definition
+		{
+			int i;
+			if (bLoad_From_EEPOM)
+				priv->EEPROMTxPowerLevelCCK = (eprom_read(dev, (EEPROM_TxPwIndex_CCK>>1))&0xff) >> 8;
+			else
+				priv->EEPROMTxPowerLevelCCK = 0x10;
+			RT_TRACE(COMP_EPROM, "CCK Tx Power Levl: 0x%02x\n", priv->EEPROMTxPowerLevelCCK);
+			for (i=0; i<3; i++)
+			{
+				if (bLoad_From_EEPOM)
+				{
+					tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G+i)>>1);
+					if (((EEPROM_TxPwIndex_OFDM_24G+i) % 2) == 0)
+						tmpValue = tmpValue & 0x00ff;
+					else
+						tmpValue = (tmpValue & 0xff00) >> 8;
+				}
+				else
+					tmpValue = 0x10;
+				priv->EEPROMTxPowerLevelOFDM24G[i] = (u8) tmpValue;
+				RT_TRACE(COMP_EPROM, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK);
+			}
+		}//end if EEPROM_DEF_VER == 0
+		else if (priv->EEPROM_Def_Ver == 1)
+		{
+			if (bLoad_From_EEPOM)
+			{
+				tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1>>1));
+				tmpValue = (tmpValue & 0xff00) >> 8;
+			}
+			else
+				tmpValue = 0x10;
+			priv->EEPROMTxPowerLevelCCK_V1[0] = (u8)tmpValue;
+
+			if (bLoad_From_EEPOM)
+				tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1 + 2)>>1);
+			else
+				tmpValue = 0x1010;
+			*((u16*)(&priv->EEPROMTxPowerLevelCCK_V1[1])) = tmpValue;
+			if (bLoad_From_EEPOM)
+				tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1>>1));
+			else
+				tmpValue = 0x1010;
+			*((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[0])) = tmpValue;
+			if (bLoad_From_EEPOM)
+				tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1+2)>>1);
+			else
+				tmpValue = 0x10;
+			priv->EEPROMTxPowerLevelOFDM24G[2] = (u8)tmpValue;
+		}//endif EEPROM_Def_Ver == 1
+
+		//update HAL variables
+		//
+		{
+			int i;
+			for (i=0; i<14; i++)
+			{
+				if (i<=3)
+					priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[0];
+				else if (i>=4 && i<=9)
+					priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[1];
+				else
+					priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[2];
+			}
+
+			for (i=0; i<14; i++)
+			{
+				if (priv->EEPROM_Def_Ver == 0)
+				{
+					if (i<=3)
+						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[0] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
+					else if (i>=4 && i<=9)
+						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK;
+					else
+						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[2] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
+				}
+				else if (priv->EEPROM_Def_Ver == 1)
+				{
+					if (i<=3)
+						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[0];
+					else if (i>=4 && i<=9)
+						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[1];
+					else
+						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[2];
+				}
+			}
+		}//end update HAL variables
+		priv->TxPowerDiff = priv->EEPROMPwDiff;
+// Antenna B gain offset to antenna A, bit0~3
+		priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
+		// Antenna C gain offset to antenna A, bit4~7
+		priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);
+		// CrystalCap, bit12~15
+		priv->CrystalCap = priv->EEPROMCrystalCap;
+		// ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
+		// 92U does not enable TX power tracking.
+		priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
+	}//end if VersionID == VERSION_819xU_A
+
+//added by vivi, for dlink led, 20080416
+	switch(priv->eeprom_CustomerID)
+	{
+		case EEPROM_CID_RUNTOP:
+			priv->CustomerID = RT_CID_819x_RUNTOP;
+			break;
+
+		case EEPROM_CID_DLINK:
+			priv->CustomerID = RT_CID_DLINK;
+			break;
+
+		default:
+			priv->CustomerID = RT_CID_DEFAULT;
+			break;
+
+	}
+
+	switch(priv->CustomerID)
+	{
+		case RT_CID_819x_RUNTOP:
+			priv->LedStrategy = SW_LED_MODE2;
+			break;
+
+		case RT_CID_DLINK:
+			priv->LedStrategy = SW_LED_MODE4;
+			break;
+
+		default:
+			priv->LedStrategy = SW_LED_MODE0;
+			break;
+
+	}
+
+
+	if(priv->rf_type == RF_1T2R)
+	{
+		RT_TRACE(COMP_EPROM, "\n1T2R config\n");
+	}
+	else
+	{
+		RT_TRACE(COMP_EPROM, "\n2T4R config\n");
+	}
+
+	// 2008/01/16 MH We can only know RF type in the function. So we have to init
+	// DIG RATR table again.
+	init_rate_adaptive(dev);
+	//we need init DIG RATR table here again.
+
+	RT_TRACE(COMP_EPROM, "<===========%s()\n", __FUNCTION__);
+	return;
+}
+
+short rtl8192_get_channel_map(struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+#ifdef ENABLE_DOT11D
+	if(priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN){
+		printk("rtl8180_init:Error channel plan! Set to default.\n");
+		priv->ChannelPlan= 0;
+	}
+	RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
+
+	rtl819x_set_channel_map(priv->ChannelPlan, priv);
+#else
+	int ch,i;
+	//Set Default Channel Plan
+	if(!channels){
+		DMESG("No channels, aborting");
+		return -1;
+	}
+	ch=channels;
+	priv->ChannelPlan= 0;//hikaru
+	 // set channels 1..14 allowed in given locale
+	for (i=1; i<=14; i++) {
+		(priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
+		ch >>= 1;
+	}
+#endif
+	return 0;
+}
+
+short rtl8192_init(struct net_device *dev)
+{
+
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	memset(&(priv->stats),0,sizeof(struct Stats));
+	memset(priv->txqueue_to_outpipemap,0,9);
+#ifdef PIPE12
+	{
+		int i=0;
+		u8 queuetopipe[]={3,2,1,0,4,8,7,6,5};
+		memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
+/*		for(i=0;i<9;i++)
+			printk("%d ",priv->txqueue_to_outpipemap[i]);
+		printk("\n");*/
+	}
+#else
+	{
+		u8 queuetopipe[]={3,2,1,0,4,4,0,4,4};
+		memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
+/*		for(i=0;i<9;i++)
+			printk("%d ",priv->txqueue_to_outpipemap[i]);
+		printk("\n");*/
+	}
+#endif
+	rtl8192_init_priv_variable(dev);
+	rtl8192_init_priv_lock(priv);
+	rtl8192_init_priv_task(dev);
+	rtl8192_get_eeprom_size(dev);
+	rtl8192_read_eeprom_info(dev);
+	rtl8192_get_channel_map(dev);
+	init_hal_dm(dev);
+	init_timer(&priv->watch_dog_timer);
+	priv->watch_dog_timer.data = (unsigned long)dev;
+	priv->watch_dog_timer.function = watch_dog_timer_callback;
+	if(rtl8192_usb_initendpoints(dev)!=0){
+		DMESG("Endopoints initialization failed");
+		return -ENOMEM;
+	}
+
+	//rtl8192_adapter_start(dev);
+#ifdef DEBUG_EPROM
+	dump_eprom(dev);
+#endif
+	return 0;
+}
+
+/******************************************************************************
+ *function:  This function actually only set RRSR, RATR and BW_OPMODE registers
+ *	     not to do all the hw config as its name says
+ *   input:  net_device dev
+ *  output:  none
+ *  return:  none
+ *  notice:  This part need to modified according to the rate set we filtered
+ * ****************************************************************************/
+void rtl8192_hwconfig(struct net_device* dev)
+{
+	u32 regRATR = 0, regRRSR = 0;
+	u8 regBwOpMode = 0, regTmp = 0;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+// Set RRSR, RATR, and BW_OPMODE registers
+	//
+	switch(priv->ieee80211->mode)
+	{
+	case WIRELESS_MODE_B:
+		regBwOpMode = BW_OPMODE_20MHZ;
+		regRATR = RATE_ALL_CCK;
+		regRRSR = RATE_ALL_CCK;
+		break;
+	case WIRELESS_MODE_A:
+		regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
+		regRATR = RATE_ALL_OFDM_AG;
+		regRRSR = RATE_ALL_OFDM_AG;
+		break;
+	case WIRELESS_MODE_G:
+		regBwOpMode = BW_OPMODE_20MHZ;
+		regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+		regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+		break;
+	case WIRELESS_MODE_AUTO:
+#ifdef TO_DO_LIST
+		if (Adapter->bInHctTest)
+		{
+		    regBwOpMode = BW_OPMODE_20MHZ;
+		    regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+		    regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+		}
+		else
+#endif
+		{
+		    regBwOpMode = BW_OPMODE_20MHZ;
+		    regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
+		    regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+		}
+		break;
+	case WIRELESS_MODE_N_24G:
+		// It support CCK rate by default.
+		// CCK rate will be filtered out only when associated AP does not support it.
+		regBwOpMode = BW_OPMODE_20MHZ;
+			regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
+			regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+		break;
+	case WIRELESS_MODE_N_5G:
+		regBwOpMode = BW_OPMODE_5G;
+		regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
+		regRRSR = RATE_ALL_OFDM_AG;
+		break;
+	}
+
+	write_nic_byte(dev, BW_OPMODE, regBwOpMode);
+	{
+		u32 ratr_value = 0;
+		ratr_value = regRATR;
+		if (priv->rf_type == RF_1T2R)
+		{
+			ratr_value &= ~(RATE_ALL_OFDM_2SS);
+		}
+		write_nic_dword(dev, RATR0, ratr_value);
+		write_nic_byte(dev, UFWP, 1);
+	}
+	regTmp = read_nic_byte(dev, 0x313);
+	regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
+	write_nic_dword(dev, RRSR, regRRSR);
+
+	//
+	// Set Retry Limit here
+	//
+	write_nic_word(dev, RETRY_LIMIT,
+			priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \
+			priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
+	// Set Contention Window here
+
+	// Set Tx AGC
+
+	// Set Tx Antenna including Feedback control
+
+	// Set Auto Rate fallback control
+
+
+}
+
+
+//InitializeAdapter and PhyCfg
+bool rtl8192_adapter_start(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32 dwRegRead = 0;
+	bool init_status = true;
+	RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__);
+	priv->Rf_Mode = RF_OP_By_SW_3wire;
+	//for ASIC power on sequence
+	write_nic_byte_E(dev, 0x5f, 0x80);
+	mdelay(50);
+	write_nic_byte_E(dev, 0x5f, 0xf0);
+	write_nic_byte_E(dev, 0x5d, 0x00);
+	write_nic_byte_E(dev, 0x5e, 0x80);
+	write_nic_byte(dev, 0x17, 0x37);
+	mdelay(10);
+//#ifdef TO_DO_LIST
+	priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
+	//config CPUReset Register
+	//Firmware Reset or not?
+	dwRegRead = read_nic_dword(dev, CPU_GEN);
+	if (priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
+		dwRegRead |= CPU_GEN_SYSTEM_RESET; //do nothing here?
+	else if (priv->pFirmware->firmware_status == FW_STATUS_5_READY)
+		dwRegRead |= CPU_GEN_FIRMWARE_RESET;
+	else
+		RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__,   priv->pFirmware->firmware_status);
+
+	write_nic_dword(dev, CPU_GEN, dwRegRead);
+	//mdelay(30);
+	//config BB.
+	rtl8192_BBConfig(dev);
+
+	//Loopback mode or not
+	priv->LoopbackMode = RTL819xU_NO_LOOPBACK;
+//	priv->LoopbackMode = RTL819xU_MAC_LOOPBACK;
+
+	dwRegRead = read_nic_dword(dev, CPU_GEN);
+	if (priv->LoopbackMode == RTL819xU_NO_LOOPBACK)
+		dwRegRead = ((dwRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
+	else if (priv->LoopbackMode == RTL819xU_MAC_LOOPBACK)
+		dwRegRead |= CPU_CCK_LOOPBACK;
+	else
+		RT_TRACE(COMP_ERR, "Serious error in %s(): wrong loopback mode setting(%d)\n", __FUNCTION__,  priv->LoopbackMode);
+
+	write_nic_dword(dev, CPU_GEN, dwRegRead);
+
+	//after reset cpu, we need wait for a seconds to write in register.
+	udelay(500);
+
+	//xiong add for new bitfile:usb suspend reset pin set to 1. //do we need?
+	write_nic_byte_E(dev, 0x5f, (read_nic_byte_E(dev, 0x5f)|0x20));
+
+	//Set Hardware
+	rtl8192_hwconfig(dev);
+
+	//turn on Tx/Rx
+	write_nic_byte(dev, CMDR, CR_RE|CR_TE);
+
+	//set IDR0 here
+	write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
+	write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]);
+
+	//set RCR
+	write_nic_dword(dev, RCR, priv->ReceiveConfig);
+
+	//Initialize Number of Reserved Pages in Firmware Queue
+	write_nic_dword(dev, RQPN1,  NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
+						NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
+						NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
+						NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
+	write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT |\
+						NUM_OF_PAGE_IN_FW_QUEUE_CMD << RSVD_FW_QUEUE_PAGE_CMD_SHIFT);
+	write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
+						NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT
+//						| NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT
+						);
+	write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
+
+	//Set AckTimeout
+	// TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
+	write_nic_byte(dev, ACK_TIMEOUT, 0x30);
+
+//	RT_TRACE(COMP_INIT, "%s():priv->ResetProgress is %d\n", __FUNCTION__,priv->ResetProgress);
+	if(priv->ResetProgress == RESET_TYPE_NORESET)
+	rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
+	if(priv->ResetProgress == RESET_TYPE_NORESET){
+	CamResetAllEntry(dev);
+	{
+		u8 SECR_value = 0x0;
+		SECR_value |= SCR_TxEncEnable;
+		SECR_value |= SCR_RxDecEnable;
+		SECR_value |= SCR_NoSKMC;
+		write_nic_byte(dev, SECR, SECR_value);
+	}
+	}
+
+	//Beacon related
+	write_nic_word(dev, ATIMWND, 2);
+	write_nic_word(dev, BCN_INTERVAL, 100);
+
+	{
+#define DEFAULT_EDCA 0x005e4332
+		int i;
+		for (i=0; i<QOS_QUEUE_NUM; i++)
+		write_nic_dword(dev, WDCAPARA_ADD[i], DEFAULT_EDCA);
+	}
+#ifdef USB_RX_AGGREGATION_SUPPORT
+	//3 For usb rx firmware aggregation control
+	if(priv->ResetProgress == RESET_TYPE_NORESET)
+	{
+		u32 ulValue;
+		PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
+		ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
+					(pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
+		/*
+		 * If usb rx firmware aggregation is enabled,
+		 * when anyone of three threshold conditions above is reached,
+		 * firmware will send aggregated packet to driver.
+		 */
+		write_nic_dword(dev, 0x1a8, ulValue);
+		priv->bCurrentRxAggrEnable = true;
+	}
+#endif
+
+	rtl8192_phy_configmac(dev);
+
+	if (priv->card_8192_version == (u8) VERSION_819xU_A)
+	{
+		rtl8192_phy_getTxPower(dev);
+		rtl8192_phy_setTxPower(dev, priv->chan);
+	}
+
+	//Firmware download
+	init_status = init_firmware(dev);
+	if(!init_status)
+	{
+		RT_TRACE(COMP_ERR,"ERR!!! %s(): Firmware download is failed\n", __FUNCTION__);
+		return init_status;
+	}
+	RT_TRACE(COMP_INIT, "%s():after firmware download\n", __FUNCTION__);
+	//
+#ifdef TO_DO_LIST
+if(Adapter->ResetProgress == RESET_TYPE_NORESET)
+	{
+		if(pMgntInfo->RegRfOff == TRUE)
+		{ // User disable RF via registry.
+			RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RegRfOff ----------\n"));
+			MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_SW);
+			// Those action will be discard in MgntActSet_RF_State because off the same state
+			for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
+				PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
+		}
+		else if(pMgntInfo->RfOffReason > RF_CHANGE_BY_PS)
+		{ // H/W or S/W RF OFF before sleep.
+			RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RfOffReason(%d) ----------\n", pMgntInfo->RfOffReason));
+			MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
+		}
+		else
+		{
+			pHalData->eRFPowerState = eRfOn;
+			pMgntInfo->RfOffReason = 0;
+			RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): RF is on ----------\n"));
+		}
+	}
+	else
+	{
+		if(pHalData->eRFPowerState == eRfOff)
+		{
+			MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
+			// Those action will be discard in MgntActSet_RF_State because off the same state
+			for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
+				PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
+		}
+	}
+#endif
+	//config RF.
+	if(priv->ResetProgress == RESET_TYPE_NORESET){
+	rtl8192_phy_RFConfig(dev);
+	RT_TRACE(COMP_INIT, "%s():after phy RF config\n", __FUNCTION__);
+	}
+
+
+	if(priv->ieee80211->FwRWRF)
+		// We can force firmware to do RF-R/W
+		priv->Rf_Mode = RF_OP_By_FW;
+	else
+		priv->Rf_Mode = RF_OP_By_SW_3wire;
+
+
+	rtl8192_phy_updateInitGain(dev);
+	/*--set CCK and OFDM Block "ON"--*/
+	rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
+	rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
+
+	if(priv->ResetProgress == RESET_TYPE_NORESET)
+	{
+		//if D or C cut
+		u8 tmpvalue = read_nic_byte(dev, 0x301);
+		if(tmpvalue ==0x03)
+		{
+			priv->bDcut = TRUE;
+			RT_TRACE(COMP_POWER_TRACKING, "D-cut\n");
+		}
+		else
+		{
+			priv->bDcut = FALSE;
+			RT_TRACE(COMP_POWER_TRACKING, "C-cut\n");
+		}
+		dm_initialize_txpower_tracking(dev);
+
+		if(priv->bDcut == TRUE)
+		{
+			u32 i, TempCCk;
+			u32 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
+		//	u32 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
+			for(i = 0; i<TxBBGainTableLength; i++)
+			{
+				if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
+				{
+					priv->rfa_txpowertrackingindex= (u8)i;
+					priv->rfa_txpowertrackingindex_real= (u8)i;
+					priv->rfa_txpowertracking_default= priv->rfa_txpowertrackingindex;
+					break;
+				}
+			}
+
+			TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
+
+			for(i=0 ; i<CCKTxBBGainTableLength ; i++)
+			{
+
+				if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
+				{
+					priv->cck_present_attentuation_20Mdefault=(u8) i;
+					break;
+				}
+			}
+			priv->cck_present_attentuation_40Mdefault= 0;
+			priv->cck_present_attentuation_difference= 0;
+			priv->cck_present_attentuation = priv->cck_present_attentuation_20Mdefault;
+
+	//		pMgntInfo->bTXPowerTracking = FALSE;//TEMPLY DISABLE
+		}
+	}
+	write_nic_byte(dev, 0x87, 0x0);
+
+
+	return init_status;
+}
+
+/* this configures registers for beacon tx and enables it via
+ * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
+ * be used to stop beacon transmission
+ */
+/***************************************************************************
+    -------------------------------NET STUFF---------------------------
+***************************************************************************/
+
+static struct net_device_stats *rtl8192_stats(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	return &priv->ieee80211->stats;
+}
+
+bool
+HalTxCheckStuck819xUsb(
+	struct net_device *dev
+	)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u16 		RegTxCounter = read_nic_word(dev, 0x128);
+	bool		bStuck = FALSE;
+	RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
+	if(priv->TxCounter==RegTxCounter)
+		bStuck = TRUE;
+
+	priv->TxCounter = RegTxCounter;
+
+	return bStuck;
+}
+
+/*
+*	<Assumption: RT_TX_SPINLOCK is acquired.>
+*	First added: 2006.11.19 by emily
+*/
+RESET_TYPE
+TxCheckStuck(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8			QueueID;
+//	PRT_TCB			pTcb;
+//	u8			ResetThreshold;
+	bool			bCheckFwTxCnt = false;
+	//unsigned long flags;
+
+	//
+	// Decide Stuch threshold according to current power save mode
+	//
+
+//     RT_TRACE(COMP_RESET, " ==> TxCheckStuck()\n");
+//	     PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
+//	     spin_lock_irqsave(&priv->ieee80211->lock,flags);
+	     for (QueueID = 0; QueueID<=BEACON_QUEUE;QueueID ++)
+	     {
+	     		if(QueueID == TXCMD_QUEUE)
+		         continue;
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+			if((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_drv_aggQ[QueueID]) == 0))
+#else
+		     	if((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0)  && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0))
+#endif
+			 	continue;
+
+	             bCheckFwTxCnt = true;
+	     }
+//	     PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
+//	spin_unlock_irqrestore(&priv->ieee80211->lock,flags);
+//	RT_TRACE(COMP_RESET,"bCheckFwTxCnt is %d\n",bCheckFwTxCnt);
+	if(bCheckFwTxCnt)
+	{
+		if(HalTxCheckStuck819xUsb(dev))
+		{
+			RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
+			return RESET_TYPE_SILENT;
+		}
+	}
+	return RESET_TYPE_NORESET;
+}
+
+bool
+HalRxCheckStuck819xUsb(struct net_device *dev)
+{
+	u16 	RegRxCounter = read_nic_word(dev, 0x130);
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	bool bStuck = FALSE;
+	static u8	rx_chk_cnt = 0;
+	RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
+	// If rssi is small, we should check rx for long time because of bad rx.
+	// or maybe it will continuous silent reset every 2 seconds.
+	rx_chk_cnt++;
+	if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
+	{
+		rx_chk_cnt = 0;	//high rssi, check rx stuck right now.
+	}
+	else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
+		((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
+		(priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
+	{
+		if(rx_chk_cnt < 2)
+		{
+			return bStuck;
+		}
+		else
+		{
+			rx_chk_cnt = 0;
+		}
+	}
+	else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
+		(priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
+		priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
+	{
+		if(rx_chk_cnt < 4)
+		{
+			//DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
+			return bStuck;
+		}
+		else
+		{
+			rx_chk_cnt = 0;
+			//DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
+		}
+	}
+	else
+	{
+		if(rx_chk_cnt < 8)
+		{
+			//DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
+			return bStuck;
+		}
+		else
+		{
+			rx_chk_cnt = 0;
+			//DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
+		}
+	}
+
+	if(priv->RxCounter==RegRxCounter)
+		bStuck = TRUE;
+
+	priv->RxCounter = RegRxCounter;
+
+	return bStuck;
+}
+
+RESET_TYPE
+RxCheckStuck(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	//int                     i;
+	bool        bRxCheck = FALSE;
+
+//       RT_TRACE(COMP_RESET," ==> RxCheckStuck()\n");
+	//PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
+
+	 if(priv->IrpPendingCount > 1)
+		bRxCheck = TRUE;
+       //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
+
+//       RT_TRACE(COMP_RESET,"bRxCheck is %d \n",bRxCheck);
+	if(bRxCheck)
+	{
+		if(HalRxCheckStuck819xUsb(dev))
+		{
+			RT_TRACE(COMP_RESET, "RxStuck Condition\n");
+			return RESET_TYPE_SILENT;
+		}
+	}
+	return RESET_TYPE_NORESET;
+}
+
+
+/**
+*	This function is called by Checkforhang to check whether we should ask OS to reset driver
+*
+*	\param pAdapter	The adapter context for this miniport
+*
+*	Note:NIC with USB interface sholud not call this function because we cannot scan descriptor
+*	to judge whether there is tx stuck.
+*	Note: This function may be required to be rewrite for Vista OS.
+*	<<<Assumption: Tx spinlock has been acquired >>>
+*
+*	8185 and 8185b does not implement this function. This is added by Emily at 2006.11.24
+*/
+RESET_TYPE
+rtl819x_ifcheck_resetornot(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	RESET_TYPE	TxResetType = RESET_TYPE_NORESET;
+	RESET_TYPE	RxResetType = RESET_TYPE_NORESET;
+	RT_RF_POWER_STATE 	rfState;
+
+	rfState = priv->ieee80211->eRFPowerState;
+
+	TxResetType = TxCheckStuck(dev);
+	if( rfState != eRfOff ||
+		/*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
+		(priv->ieee80211->iw_mode != IW_MODE_ADHOC))
+	{
+		// If driver is in the status of firmware download failure , driver skips RF initialization and RF is
+		// in turned off state. Driver should check whether Rx stuck and do silent reset. And
+		// if driver is in firmware download failure status, driver should initialize RF in the following
+		// silent reset procedure Emily, 2008.01.21
+
+		// Driver should not check RX stuck in IBSS mode because it is required to
+		// set Check BSSID in order to send beacon, however, if check BSSID is
+		// set, STA cannot hear any packet a all. Emily, 2008.04.12
+		RxResetType = RxCheckStuck(dev);
+	}
+	if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
+		return RESET_TYPE_NORMAL;
+	else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT){
+		RT_TRACE(COMP_RESET,"%s():silent reset\n",__FUNCTION__);
+		return RESET_TYPE_SILENT;
+	}
+	else
+		return RESET_TYPE_NORESET;
+
+}
+
+void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
+int _rtl8192_up(struct net_device *dev);
+int rtl8192_close(struct net_device *dev);
+
+
+
+void
+CamRestoreAllEntry(	struct net_device *dev)
+{
+	u8 EntryId = 0;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8*	MacAddr = priv->ieee80211->current_network.bssid;
+
+	static u8	CAM_CONST_ADDR[4][6] = {
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
+	static u8	CAM_CONST_BROAD[] =
+		{0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+	RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
+
+
+	if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
+	    (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
+	{
+
+		for(EntryId=0; EntryId<4; EntryId++)
+		{
+			{
+				MacAddr = CAM_CONST_ADDR[EntryId];
+				setKey(dev,
+						EntryId ,
+						EntryId,
+						priv->ieee80211->pairwise_key_type,
+						MacAddr,
+						0,
+						NULL);
+			}
+		}
+
+	}
+	else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
+	{
+
+		{
+			if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
+				setKey(dev,
+						4,
+						0,
+						priv->ieee80211->pairwise_key_type,
+						(u8*)dev->dev_addr,
+						0,
+						NULL);
+			else
+				setKey(dev,
+						4,
+						0,
+						priv->ieee80211->pairwise_key_type,
+						MacAddr,
+						0,
+						NULL);
+		}
+	}
+	else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
+	{
+
+		{
+			if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
+				setKey(dev,
+						4,
+						0,
+						priv->ieee80211->pairwise_key_type,
+						(u8*)dev->dev_addr,
+						0,
+						NULL);
+			else
+				setKey(dev,
+						4,
+						0,
+						priv->ieee80211->pairwise_key_type,
+						MacAddr,
+						0,
+						NULL);
+		}
+	}
+
+
+
+	if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
+	{
+		MacAddr = CAM_CONST_BROAD;
+		for(EntryId=1 ; EntryId<4 ; EntryId++)
+		{
+			{
+				setKey(dev,
+						EntryId,
+						EntryId,
+						priv->ieee80211->group_key_type,
+						MacAddr,
+						0,
+						NULL);
+			}
+		}
+		if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
+				setKey(dev,
+						0,
+						0,
+						priv->ieee80211->group_key_type,
+						CAM_CONST_ADDR[0],
+						0,
+						NULL);
+	}
+	else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
+	{
+		MacAddr = CAM_CONST_BROAD;
+		for(EntryId=1; EntryId<4 ; EntryId++)
+		{
+			{
+				setKey(dev,
+						EntryId ,
+						EntryId,
+						priv->ieee80211->group_key_type,
+						MacAddr,
+						0,
+						NULL);
+			}
+		}
+
+		if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
+				setKey(dev,
+						0 ,
+						0,
+						priv->ieee80211->group_key_type,
+						CAM_CONST_ADDR[0],
+						0,
+						NULL);
+	}
+}
+//////////////////////////////////////////////////////////////
+// This function is used to fix Tx/Rx stop bug temporarily.
+// This function will do "system reset" to NIC when Tx or Rx is stuck.
+// The method checking Tx/Rx stuck of this function is supported by FW,
+// which reports Tx and Rx counter to register 0x128 and 0x130.
+//////////////////////////////////////////////////////////////
+void
+rtl819x_ifsilentreset(struct net_device *dev)
+{
+	//OCTET_STRING asocpdu;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8	reset_times = 0;
+	int reset_status = 0;
+	struct ieee80211_device *ieee = priv->ieee80211;
+
+
+	// 2007.07.20. If we need to check CCK stop, please uncomment this line.
+	//bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
+
+	if(priv->ResetProgress==RESET_TYPE_NORESET)
+	{
+RESET_START:
+
+		RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
+
+		// Set the variable for reset.
+		priv->ResetProgress = RESET_TYPE_SILENT;
+//		rtl8192_close(dev);
+		down(&priv->wx_sem);
+		if(priv->up == 0)
+		{
+			RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
+			up(&priv->wx_sem);
+			return ;
+		}
+		priv->up = 0;
+		RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
+//		if(!netif_queue_stopped(dev))
+//			netif_stop_queue(dev);
+
+		rtl8192_rtx_disable(dev);
+		rtl8192_cancel_deferred_work(priv);
+		deinit_hal_dm(dev);
+		del_timer_sync(&priv->watch_dog_timer);
+
+		ieee->sync_scan_hurryup = 1;
+		if(ieee->state == IEEE80211_LINKED)
+		{
+			down(&ieee->wx_sem);
+			printk("ieee->state is IEEE80211_LINKED\n");
+			ieee80211_stop_send_beacons(priv->ieee80211);
+			del_timer_sync(&ieee->associate_timer);
+			cancel_delayed_work(&ieee->associate_retry_wq);
+			ieee80211_stop_scan(ieee);
+			netif_carrier_off(dev);
+			up(&ieee->wx_sem);
+		}
+		else{
+			printk("ieee->state is NOT LINKED\n");
+			ieee80211_softmac_stop_protocol(priv->ieee80211);			}
+		up(&priv->wx_sem);
+		RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
+	//rtl8192_irq_disable(dev);
+		RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
+		reset_status = _rtl8192_up(dev);
+
+		RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
+		if(reset_status == -EAGAIN)
+		{
+			if(reset_times < 3)
+			{
+				reset_times++;
+				goto RESET_START;
+			}
+			else
+			{
+				RT_TRACE(COMP_ERR," ERR!!! %s():  Reset Failed!!\n", __FUNCTION__);
+			}
+		}
+		ieee->is_silent_reset = 1;
+		EnableHWSecurityConfig8192(dev);
+		if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
+		{
+			ieee->set_chan(ieee->dev, ieee->current_network.channel);
+
+			queue_work(ieee->wq, &ieee->associate_complete_wq);
+
+		}
+		else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
+		{
+			ieee->set_chan(ieee->dev, ieee->current_network.channel);
+			ieee->link_change(ieee->dev);
+
+		//	notify_wx_assoc_event(ieee);
+
+			ieee80211_start_send_beacons(ieee);
+
+			if (ieee->data_hard_resume)
+				ieee->data_hard_resume(ieee->dev);
+			netif_carrier_on(ieee->dev);
+		}
+
+		CamRestoreAllEntry(dev);
+
+		priv->ResetProgress = RESET_TYPE_NORESET;
+		priv->reset_count++;
+
+		priv->bForcedSilentReset =false;
+		priv->bResetInProgress = false;
+
+		// For test --> force write UFWP.
+		write_nic_byte(dev, UFWP, 1);
+		RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
+	}
+}
+
+void CAM_read_entry(
+	struct net_device *dev,
+	u32	 		iIndex
+)
+{
+ 	u32 target_command=0;
+	 u32 target_content=0;
+	 u8 entry_i=0;
+	 u32 ulStatus;
+	s32 i=100;
+//	printk("=======>start read CAM\n");
+ 	for(entry_i=0;entry_i<CAM_CONTENT_COUNT;entry_i++)
+ 	{
+   	// polling bit, and No Write enable, and address
+		target_command= entry_i+CAM_CONTENT_COUNT*iIndex;
+		target_command= target_command | BIT31;
+
+	//Check polling bit is clear
+//	mdelay(1);
+		while((i--)>=0)
+		{
+			ulStatus = read_nic_dword(dev, RWCAM);
+			if(ulStatus & BIT31){
+				continue;
+			}
+			else{
+				break;
+			}
+		}
+		write_nic_dword(dev, RWCAM, target_command);
+		RT_TRACE(COMP_SEC,"CAM_read_entry(): WRITE A0: %x \n",target_command);
+	 //	printk("CAM_read_entry(): WRITE A0: %lx \n",target_command);
+		target_content = read_nic_dword(dev, RCAMO);
+		RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n",target_content);
+	 //	printk("CAM_read_entry(): WRITE A8: %lx \n",target_content);
+	}
+	printk("\n");
+}
+
+void rtl819x_update_rxcounts(
+	struct r8192_priv *priv,
+	u32* TotalRxBcnNum,
+	u32* TotalRxDataNum
+)
+{
+	u16 			SlotIndex;
+	u8			i;
+
+	*TotalRxBcnNum = 0;
+	*TotalRxDataNum = 0;
+
+	SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
+	priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
+	priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
+	for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
+		*TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
+		*TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
+	}
+}
+
+
+extern	void	rtl819x_watchdog_wqcallback(struct work_struct *work)
+{
+	struct delayed_work *dwork = container_of(work,struct delayed_work,work);
+       struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
+       struct net_device *dev = priv->ieee80211->dev;
+	struct ieee80211_device* ieee = priv->ieee80211;
+	RESET_TYPE	ResetType = RESET_TYPE_NORESET;
+	static u8	check_reset_cnt=0;
+	bool bBusyTraffic = false;
+
+	if(!priv->up)
+		return;
+	hal_dm_watchdog(dev);
+
+	{//to get busy traffic condition
+		if(ieee->state == IEEE80211_LINKED)
+		{
+			if(	ieee->LinkDetectInfo.NumRxOkInPeriod> 666 ||
+				ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) {
+				bBusyTraffic = true;
+			}
+			ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
+			ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
+			ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
+		}
+	}
+	//added by amy for AP roaming
+	{
+		if(priv->ieee80211->state == IEEE80211_LINKED && priv->ieee80211->iw_mode == IW_MODE_INFRA)
+		{
+			u32	TotalRxBcnNum = 0;
+			u32	TotalRxDataNum = 0;
+
+			rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
+			if((TotalRxBcnNum+TotalRxDataNum) == 0)
+			{
+				#ifdef TODO
+				if(rfState == eRfOff)
+					RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
+				#endif
+				printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
+			//	Dot11d_Reset(dev);
+				priv->ieee80211->state = IEEE80211_ASSOCIATING;
+				notify_wx_assoc_event(priv->ieee80211);
+				RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
+				priv->ieee80211->link_change(dev);
+                                queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
+
+			}
+		}
+		priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod=0;
+		priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod=0;
+	}
+//	CAM_read_entry(dev,4);
+	//check if reset the driver
+	if(check_reset_cnt++ >= 3)
+	{
+    		ResetType = rtl819x_ifcheck_resetornot(dev);
+		check_reset_cnt = 3;
+		//DbgPrint("Start to check silent reset\n");
+	}
+	//	RT_TRACE(COMP_RESET,"%s():priv->force_reset is %d,priv->ResetProgress is %d, priv->bForcedSilentReset is %d,priv->bDisableNormalResetCheck is %d,ResetType is %d\n",__FUNCTION__,priv->force_reset,priv->ResetProgress,priv->bForcedSilentReset,priv->bDisableNormalResetCheck,ResetType);
+	if( (priv->force_reset) || (priv->ResetProgress==RESET_TYPE_NORESET &&
+		(priv->bForcedSilentReset ||
+		(!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT)))) // This is control by OID set in Pomelo
+	{
+		RT_TRACE(COMP_RESET,"%s():priv->force_reset is %d,priv->ResetProgress is %d, priv->bForcedSilentReset is %d,priv->bDisableNormalResetCheck is %d,ResetType is %d\n",__FUNCTION__,priv->force_reset,priv->ResetProgress,priv->bForcedSilentReset,priv->bDisableNormalResetCheck,ResetType);
+		rtl819x_ifsilentreset(dev);
+	}
+	priv->force_reset = false;
+	priv->bForcedSilentReset = false;
+	priv->bResetInProgress = false;
+	RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
+
+}
+
+void watch_dog_timer_callback(unsigned long data)
+{
+	struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
+	//printk("===============>watch_dog  timer\n");
+	queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq, 0);
+	mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
+}
+int _rtl8192_up(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	//int i;
+	int init_status = 0;
+	priv->up=1;
+	priv->ieee80211->ieee_up=1;
+	RT_TRACE(COMP_INIT, "Bringing up iface");
+	init_status = rtl8192_adapter_start(dev);
+	if(!init_status)
+	{
+		RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n", __FUNCTION__);
+		priv->up=priv->ieee80211->ieee_up = 0;
+		return -EAGAIN;
+	}
+	RT_TRACE(COMP_INIT, "start adapter finished\n");
+	rtl8192_rx_enable(dev);
+//	rtl8192_tx_enable(dev);
+	if(priv->ieee80211->state != IEEE80211_LINKED)
+	ieee80211_softmac_start_protocol(priv->ieee80211);
+	ieee80211_reset_queue(priv->ieee80211);
+	watch_dog_timer_callback((unsigned long) dev);
+	if(!netif_queue_stopped(dev))
+		netif_start_queue(dev);
+	else
+		netif_wake_queue(dev);
+
+	return 0;
+}
+
+
+int rtl8192_open(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	int ret;
+	down(&priv->wx_sem);
+	ret = rtl8192_up(dev);
+	up(&priv->wx_sem);
+	return ret;
+
+}
+
+
+int rtl8192_up(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	if (priv->up == 1) return -1;
+
+	return _rtl8192_up(dev);
+}
+
+
+int rtl8192_close(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	int ret;
+
+	down(&priv->wx_sem);
+
+	ret = rtl8192_down(dev);
+
+	up(&priv->wx_sem);
+
+	return ret;
+
+}
+
+int rtl8192_down(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	int i;
+
+	if (priv->up == 0) return -1;
+
+	priv->up=0;
+	priv->ieee80211->ieee_up = 0;
+	RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
+/* FIXME */
+	if (!netif_queue_stopped(dev))
+		netif_stop_queue(dev);
+
+	rtl8192_rtx_disable(dev);
+	//rtl8192_irq_disable(dev);
+
+ /* Tx related queue release */
+	for(i = 0; i < MAX_QUEUE_SIZE; i++) {
+		skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
+	}
+	for(i = 0; i < MAX_QUEUE_SIZE; i++) {
+		skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
+	}
+
+	for(i = 0; i < MAX_QUEUE_SIZE; i++) {
+		skb_queue_purge(&priv->ieee80211->skb_drv_aggQ [i]);
+	}
+
+	//as cancel_delayed_work will del work->timer, so if work is not definedas struct delayed_work, it will corrupt
+//	flush_scheduled_work();
+	rtl8192_cancel_deferred_work(priv);
+	deinit_hal_dm(dev);
+	del_timer_sync(&priv->watch_dog_timer);
+
+
+	ieee80211_softmac_stop_protocol(priv->ieee80211);
+	memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
+	RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
+
+		return 0;
+}
+
+
+void rtl8192_commit(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	int reset_status = 0;
+	//u8 reset_times = 0;
+	if (priv->up == 0) return ;
+	priv->up = 0;
+
+	rtl8192_cancel_deferred_work(priv);
+	del_timer_sync(&priv->watch_dog_timer);
+	//cancel_delayed_work(&priv->SwChnlWorkItem);
+
+	ieee80211_softmac_stop_protocol(priv->ieee80211);
+
+	//rtl8192_irq_disable(dev);
+	rtl8192_rtx_disable(dev);
+	reset_status = _rtl8192_up(dev);
+
+}
+
+/*
+void rtl8192_restart(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+*/
+void rtl8192_restart(struct work_struct *work)
+{
+	struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
+	struct net_device *dev = priv->ieee80211->dev;
+
+	down(&priv->wx_sem);
+
+	rtl8192_commit(dev);
+
+	up(&priv->wx_sem);
+}
+
+static void r8192_set_multicast(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	short promisc;
+
+	//down(&priv->wx_sem);
+
+	/* FIXME FIXME */
+
+	promisc = (dev->flags & IFF_PROMISC) ? 1:0;
+
+	if (promisc != priv->promisc)
+	//	rtl8192_commit(dev);
+
+	priv->promisc = promisc;
+
+	//schedule_work(&priv->reset_wq);
+	//up(&priv->wx_sem);
+}
+
+
+int r8192_set_mac_adr(struct net_device *dev, void *mac)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	struct sockaddr *addr = mac;
+
+	down(&priv->wx_sem);
+
+	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+
+	schedule_work(&priv->reset_wq);
+	up(&priv->wx_sem);
+
+	return 0;
+}
+
+/* based on ipw2200 driver */
+int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	struct iwreq *wrq = (struct iwreq *)rq;
+	int ret=-1;
+	struct ieee80211_device *ieee = priv->ieee80211;
+	u32 key[4];
+	u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
+	struct iw_point *p = &wrq->u.data;
+	struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
+
+	down(&priv->wx_sem);
+
+
+     if (p->length < sizeof(struct ieee_param) || !p->pointer){
+	     ret = -EINVAL;
+	     goto out;
+	}
+
+     ipw = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
+     if (ipw == NULL){
+	     ret = -ENOMEM;
+	     goto out;
+     }
+     if (copy_from_user(ipw, p->pointer, p->length)) {
+		kfree(ipw);
+	    ret = -EFAULT;
+	    goto out;
+	}
+
+	switch (cmd) {
+	    case RTL_IOCTL_WPA_SUPPLICANT:
+	//parse here for HW security
+			if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
+			{
+				if (ipw->u.crypt.set_tx)
+				{
+					if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
+						ieee->pairwise_key_type = KEY_TYPE_CCMP;
+					else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
+						ieee->pairwise_key_type = KEY_TYPE_TKIP;
+					else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
+					{
+						if (ipw->u.crypt.key_len == 13)
+							ieee->pairwise_key_type = KEY_TYPE_WEP104;
+						else if (ipw->u.crypt.key_len == 5)
+							ieee->pairwise_key_type = KEY_TYPE_WEP40;
+					}
+					else
+						ieee->pairwise_key_type = KEY_TYPE_NA;
+
+					if (ieee->pairwise_key_type)
+					{
+						memcpy((u8*)key, ipw->u.crypt.key, 16);
+						EnableHWSecurityConfig8192(dev);
+					//we fill both index entry and 4th entry for pairwise key as in IPW interface, adhoc will only get here, so we need index entry for its default key serching!
+					//added by WB.
+						setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
+						if (ieee->auth_mode != 2)
+						setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
+					}
+				}
+				else //if (ipw->u.crypt.idx) //group key use idx > 0
+				{
+					memcpy((u8*)key, ipw->u.crypt.key, 16);
+					if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
+						ieee->group_key_type= KEY_TYPE_CCMP;
+					else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
+						ieee->group_key_type = KEY_TYPE_TKIP;
+					else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
+					{
+						if (ipw->u.crypt.key_len == 13)
+							ieee->group_key_type = KEY_TYPE_WEP104;
+						else if (ipw->u.crypt.key_len == 5)
+							ieee->group_key_type = KEY_TYPE_WEP40;
+					}
+					else
+						ieee->group_key_type = KEY_TYPE_NA;
+
+					if (ieee->group_key_type)
+					{
+							setKey(	dev,
+								ipw->u.crypt.idx,
+								ipw->u.crypt.idx,		//KeyIndex
+						     		ieee->group_key_type,	//KeyType
+						            	broadcast_addr,	//MacAddr
+								0,		//DefaultKey
+							      	key);		//KeyContent
+					}
+				}
+			}
+#ifdef JOHN_HWSEC_DEBUG
+		//john's test 0711
+		printk("@@ wrq->u pointer = ");
+		for(i=0;i<wrq->u.data.length;i++){
+			if(i%10==0) printk("\n");
+			printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
+		}
+		printk("\n");
+#endif /*JOHN_HWSEC_DEBUG*/
+		ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
+		break;
+
+	    default:
+		ret = -EOPNOTSUPP;
+		break;
+	}
+	kfree(ipw);
+	ipw = NULL;
+out:
+	up(&priv->wx_sem);
+	return ret;
+}
+
+u8 HwRateToMRate90(bool bIsHT, u8 rate)
+{
+	u8  ret_rate = 0xff;
+
+	if(!bIsHT) {
+		switch(rate) {
+			case DESC90_RATE1M:   ret_rate = MGN_1M;         break;
+			case DESC90_RATE2M:   ret_rate = MGN_2M;         break;
+			case DESC90_RATE5_5M: ret_rate = MGN_5_5M;       break;
+			case DESC90_RATE11M:  ret_rate = MGN_11M;        break;
+			case DESC90_RATE6M:   ret_rate = MGN_6M;         break;
+			case DESC90_RATE9M:   ret_rate = MGN_9M;         break;
+			case DESC90_RATE12M:  ret_rate = MGN_12M;        break;
+			case DESC90_RATE18M:  ret_rate = MGN_18M;        break;
+			case DESC90_RATE24M:  ret_rate = MGN_24M;        break;
+			case DESC90_RATE36M:  ret_rate = MGN_36M;        break;
+			case DESC90_RATE48M:  ret_rate = MGN_48M;        break;
+			case DESC90_RATE54M:  ret_rate = MGN_54M;        break;
+
+			default:
+				ret_rate = 0xff;
+				RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
+				break;
+		}
+
+	} else {
+		switch(rate) {
+			case DESC90_RATEMCS0:   ret_rate = MGN_MCS0;    break;
+			case DESC90_RATEMCS1:   ret_rate = MGN_MCS1;    break;
+			case DESC90_RATEMCS2:   ret_rate = MGN_MCS2;    break;
+			case DESC90_RATEMCS3:   ret_rate = MGN_MCS3;    break;
+			case DESC90_RATEMCS4:   ret_rate = MGN_MCS4;    break;
+			case DESC90_RATEMCS5:   ret_rate = MGN_MCS5;    break;
+			case DESC90_RATEMCS6:   ret_rate = MGN_MCS6;    break;
+			case DESC90_RATEMCS7:   ret_rate = MGN_MCS7;    break;
+			case DESC90_RATEMCS8:   ret_rate = MGN_MCS8;    break;
+			case DESC90_RATEMCS9:   ret_rate = MGN_MCS9;    break;
+			case DESC90_RATEMCS10:  ret_rate = MGN_MCS10;   break;
+			case DESC90_RATEMCS11:  ret_rate = MGN_MCS11;   break;
+			case DESC90_RATEMCS12:  ret_rate = MGN_MCS12;   break;
+			case DESC90_RATEMCS13:  ret_rate = MGN_MCS13;   break;
+			case DESC90_RATEMCS14:  ret_rate = MGN_MCS14;   break;
+			case DESC90_RATEMCS15:  ret_rate = MGN_MCS15;   break;
+			case DESC90_RATEMCS32:  ret_rate = (0x80|0x20); break;
+
+			default:
+				ret_rate = 0xff;
+				RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
+				break;
+		}
+	}
+
+	return ret_rate;
+}
+
+/**
+ * Function:     UpdateRxPktTimeStamp
+ * Overview:     Recored down the TSF time stamp when receiving a packet
+ *
+ * Input:
+ *       PADAPTER        Adapter
+ *       PRT_RFD         pRfd,
+ *
+ * Output:
+ *       PRT_RFD         pRfd
+ *                               (pRfd->Status.TimeStampHigh is updated)
+ *                               (pRfd->Status.TimeStampLow is updated)
+ * Return:
+ *               None
+ */
+void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+
+	if(stats->bIsAMPDU && !stats->bFirstMPDU) {
+		stats->mac_time[0] = priv->LastRxDescTSFLow;
+		stats->mac_time[1] = priv->LastRxDescTSFHigh;
+	} else {
+		priv->LastRxDescTSFLow = stats->mac_time[0];
+		priv->LastRxDescTSFHigh = stats->mac_time[1];
+	}
+}
+
+//by amy 080606
+
+long rtl819x_translate_todbm(u8 signal_strength_index	)// 0-100 index.
+{
+	long	signal_power; // in dBm.
+
+	// Translate to dBm (x=0.5y-95).
+	signal_power = (long)((signal_strength_index + 1) >> 1);
+	signal_power -= 95;
+
+	return signal_power;
+}
+
+
+/* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
+    be a local static. Otherwise, it may increase when we return from S3/S4. The
+    value will be kept in memory or disk. We must delcare the value in adapter
+    and it will be reinitialized when return from S3/S4. */
+void rtl8192_process_phyinfo(struct r8192_priv * priv,u8* buffer, struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
+{
+	bool bcheck = false;
+	u8	rfpath;
+	u32	nspatial_stream, tmp_val;
+	//u8	i;
+	static u32 slide_rssi_index=0, slide_rssi_statistics=0;
+	static u32 slide_evm_index=0, slide_evm_statistics=0;
+	static u32 last_rssi=0, last_evm=0;
+
+	static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
+	static u32 last_beacon_adc_pwdb=0;
+
+	struct ieee80211_hdr_3addr *hdr;
+	u16 sc ;
+	unsigned int frag,seq;
+	hdr = (struct ieee80211_hdr_3addr *)buffer;
+	sc = le16_to_cpu(hdr->seq_ctl);
+	frag = WLAN_GET_SEQ_FRAG(sc);
+	seq = WLAN_GET_SEQ_SEQ(sc);
+	//cosa add 04292008 to record the sequence number
+	pcurrent_stats->Seq_Num = seq;
+	//
+	// Check whether we should take the previous packet into accounting
+	//
+	if(!pprevious_stats->bIsAMPDU)
+	{
+		// if previous packet is not aggregated packet
+		bcheck = true;
+	}else
+	{
+	}
+
+
+	if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
+	{
+		slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
+		last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
+		priv->stats.slide_rssi_total -= last_rssi;
+	}
+	priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
+
+	priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
+	if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
+		slide_rssi_index = 0;
+
+	// <1> Showed on UI for user, in dbm
+	tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
+	priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
+	pcurrent_stats->rssi = priv->stats.signal_strength;
+	//
+	// If the previous packet does not match the criteria, neglect it
+	//
+	if(!pprevious_stats->bPacketMatchBSSID)
+	{
+		if(!pprevious_stats->bToSelfBA)
+			return;
+	}
+
+	if(!bcheck)
+		return;
+
+
+	//rtl8190_process_cck_rxpathsel(priv,pprevious_stats);//only rtl8190 supported
+
+	//
+	// Check RSSI
+	//
+	priv->stats.num_process_phyinfo++;
+
+	/* record the general signal strength to the sliding window. */
+
+
+	// <2> Showed on UI for engineering
+	// hardware does not provide rssi information for each rf path in CCK
+	if(!pprevious_stats->bIsCCK && (pprevious_stats->bPacketToSelf || pprevious_stats->bToSelfBA))
+	{
+		for (rfpath = RF90_PATH_A; rfpath < priv->NumTotalRFPath; rfpath++)
+		{
+		     if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
+				 continue;
+
+			//Fixed by Jacken 2008-03-20
+			if(priv->stats.rx_rssi_percentage[rfpath] == 0)
+			{
+				priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
+				//DbgPrint("MIMO RSSI initialize \n");
+			}
+			if(pprevious_stats->RxMIMOSignalStrength[rfpath]  > priv->stats.rx_rssi_percentage[rfpath])
+			{
+				priv->stats.rx_rssi_percentage[rfpath] =
+					( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
+					(pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
+				priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath]  + 1;
+			}
+			else
+			{
+				priv->stats.rx_rssi_percentage[rfpath] =
+					( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
+					(pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
+			}
+			RT_TRACE(COMP_DBG,"priv->stats.rx_rssi_percentage[rfPath]  = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
+		}
+	}
+
+
+	//
+	// Check PWDB.
+	//
+	RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
+				pprevious_stats->bIsCCK? "CCK": "OFDM",
+				pprevious_stats->RxPWDBAll);
+
+	if(pprevious_stats->bPacketBeacon)
+	{
+/* record the beacon pwdb to the sliding window. */
+		if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
+		{
+			slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
+			last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
+			priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
+			//DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
+			//	slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
+		}
+		priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
+		priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
+		//DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
+		slide_beacon_adc_pwdb_index++;
+		if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
+			slide_beacon_adc_pwdb_index = 0;
+		pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
+		if(pprevious_stats->RxPWDBAll >= 3)
+			pprevious_stats->RxPWDBAll -= 3;
+	}
+
+	RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
+				pprevious_stats->bIsCCK? "CCK": "OFDM",
+				pprevious_stats->RxPWDBAll);
+
+
+	if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
+	{
+		if(priv->undecorated_smoothed_pwdb < 0)	// initialize
+		{
+			priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
+			//DbgPrint("First pwdb initialize \n");
+		}
+		if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
+		{
+			priv->undecorated_smoothed_pwdb =
+					( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
+					(pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
+			priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
+		}
+		else
+		{
+			priv->undecorated_smoothed_pwdb =
+					( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
+					(pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
+		}
+
+	}
+
+	//
+	// Check EVM
+	//
+	/* record the general EVM to the sliding window. */
+	if(pprevious_stats->SignalQuality == 0)
+	{
+	}
+	else
+	{
+		if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
+			if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
+				slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
+				last_evm = priv->stats.slide_evm[slide_evm_index];
+				priv->stats.slide_evm_total -= last_evm;
+			}
+
+			priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
+
+			priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
+			if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
+				slide_evm_index = 0;
+
+			// <1> Showed on UI for user, in percentage.
+			tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
+			priv->stats.signal_quality = tmp_val;
+			//cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
+			priv->stats.last_signal_strength_inpercent = tmp_val;
+		}
+
+		// <2> Showed on UI for engineering
+		if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
+		{
+			for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
+			{
+				if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
+				{
+					if(priv->stats.rx_evm_percentage[nspatial_stream] == 0)	// initialize
+					{
+						priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
+					}
+					priv->stats.rx_evm_percentage[nspatial_stream] =
+						( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
+						(pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
+				}
+			}
+		}
+	}
+
+
+}
+
+/*-----------------------------------------------------------------------------
+ * Function:	rtl819x_query_rxpwrpercentage()
+ *
+ * Overview:
+ *
+ * Input:		char		antpower
+ *
+ * Output:		NONE
+ *
+ * Return:		0-100 percentage
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/26/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static u8 rtl819x_query_rxpwrpercentage(
+	char		antpower
+	)
+{
+	if ((antpower <= -100) || (antpower >= 20))
+	{
+		return	0;
+	}
+	else if (antpower >= 0)
+	{
+		return	100;
+	}
+	else
+	{
+		return	(100+antpower);
+	}
+
+}	/* QueryRxPwrPercentage */
+
+static u8
+rtl819x_evm_dbtopercentage(
+    char value
+    )
+{
+    char ret_val;
+
+    ret_val = value;
+
+    if(ret_val >= 0)
+        ret_val = 0;
+    if(ret_val <= -33)
+        ret_val = -33;
+    ret_val = 0 - ret_val;
+    ret_val*=3;
+	if(ret_val == 99)
+		ret_val = 100;
+    return(ret_val);
+}
+//
+//	Description:
+// 	We want good-looking for signal strength/quality
+//	2007/7/19 01:09, by cosa.
+//
+long
+rtl819x_signal_scale_mapping(
+	long currsig
+	)
+{
+	long retsig;
+
+	// Step 1. Scale mapping.
+	if(currsig >= 61 && currsig <= 100)
+	{
+		retsig = 90 + ((currsig - 60) / 4);
+	}
+	else if(currsig >= 41 && currsig <= 60)
+	{
+		retsig = 78 + ((currsig - 40) / 2);
+	}
+	else if(currsig >= 31 && currsig <= 40)
+	{
+		retsig = 66 + (currsig - 30);
+	}
+	else if(currsig >= 21 && currsig <= 30)
+	{
+		retsig = 54 + (currsig - 20);
+	}
+	else if(currsig >= 5 && currsig <= 20)
+	{
+		retsig = 42 + (((currsig - 5) * 2) / 3);
+	}
+	else if(currsig == 4)
+	{
+		retsig = 36;
+	}
+	else if(currsig == 3)
+	{
+		retsig = 27;
+	}
+	else if(currsig == 2)
+	{
+		retsig = 18;
+	}
+	else if(currsig == 1)
+	{
+		retsig = 9;
+	}
+	else
+	{
+		retsig = currsig;
+	}
+
+	return retsig;
+}
+
+static void rtl8192_query_rxphystatus(
+	struct r8192_priv * priv,
+	struct ieee80211_rx_stats * pstats,
+	rx_drvinfo_819x_usb  * pdrvinfo,
+	struct ieee80211_rx_stats * precord_stats,
+	bool bpacket_match_bssid,
+	bool bpacket_toself,
+	bool bPacketBeacon,
+	bool bToSelfBA
+	)
+{
+	//PRT_RFD_STATUS		pRtRfdStatus = &(pRfd->Status);
+	phy_sts_ofdm_819xusb_t*	pofdm_buf;
+	phy_sts_cck_819xusb_t	*	pcck_buf;
+	phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
+	u8				*prxpkt;
+	u8				i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
+	char				rx_pwr[4], rx_pwr_all=0;
+	//long				rx_avg_pwr = 0;
+	char				rx_snrX, rx_evmX;
+	u8				evm, pwdb_all;
+	u32				RSSI, total_rssi=0;//, total_evm=0;
+//	long				signal_strength_index = 0;
+	u8				is_cck_rate=0;
+	u8				rf_rx_num = 0;
+
+
+	priv->stats.numqry_phystatus++;
+
+	is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
+
+	// Record it for next packet processing
+	memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
+	pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
+	pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
+	pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
+	pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
+	pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
+
+	prxpkt = (u8*)pdrvinfo;
+
+	/* Move pointer to the 16th bytes. Phy status start address. */
+	prxpkt += sizeof(rx_drvinfo_819x_usb);
+
+	/* Initial the cck and ofdm buffer pointer */
+	pcck_buf = (phy_sts_cck_819xusb_t *)prxpkt;
+	pofdm_buf = (phy_sts_ofdm_819xusb_t *)prxpkt;
+
+	pstats->RxMIMOSignalQuality[0] = -1;
+	pstats->RxMIMOSignalQuality[1] = -1;
+	precord_stats->RxMIMOSignalQuality[0] = -1;
+	precord_stats->RxMIMOSignalQuality[1] = -1;
+
+	if(is_cck_rate)
+	{
+		//
+		// (1)Hardware does not provide RSSI for CCK
+		//
+
+		//
+		// (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
+		//
+		u8 report;//, cck_agc_rpt;
+
+		priv->stats.numqry_phystatusCCK++;
+
+		if(!priv->bCckHighPower)
+		{
+			report = pcck_buf->cck_agc_rpt & 0xc0;
+			report = report>>6;
+			switch(report)
+			{
+				//Fixed by Jacken from Bryant 2008-03-20
+				//Original value is -38 , -26 , -14 , -2
+				//Fixed value is -35 , -23 , -11 , 6
+				case 0x3:
+					rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
+					break;
+				case 0x2:
+					rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
+					break;
+				case 0x1:
+					rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
+					break;
+				case 0x0:
+					rx_pwr_all = 6 - (pcck_buf->cck_agc_rpt & 0x3e);
+					break;
+			}
+		}
+		else
+		{
+			report = pcck_buf->cck_agc_rpt & 0x60;
+			report = report>>5;
+			switch(report)
+			{
+				case 0x3:
+					rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
+					break;
+				case 0x2:
+					rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
+					break;
+				case 0x1:
+					rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
+					break;
+				case 0x0:
+					rx_pwr_all = 6 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
+					break;
+			}
+		}
+
+		pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
+		pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
+		pstats->RecvSignalPower = pwdb_all;
+
+		//
+		// (3) Get Signal Quality (EVM)
+		//
+		//if(bpacket_match_bssid)
+		{
+			u8	sq;
+
+			if(pstats->RxPWDBAll > 40)
+			{
+				sq = 100;
+			}else
+			{
+				sq = pcck_buf->sq_rpt;
+
+				if(pcck_buf->sq_rpt > 64)
+					sq = 0;
+				else if (pcck_buf->sq_rpt < 20)
+					sq = 100;
+				else
+					sq = ((64-sq) * 100) / 44;
+			}
+			pstats->SignalQuality = precord_stats->SignalQuality = sq;
+			pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
+			pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
+		}
+	}
+	else
+	{
+		priv->stats.numqry_phystatusHT++;
+		//
+		// (1)Get RSSI for HT rate
+		//
+		for(i=RF90_PATH_A; i<priv->NumTotalRFPath; i++)
+		{
+			// 2008/01/30 MH we will judge RF RX path now.
+			if (priv->brfpath_rxenable[i])
+				rf_rx_num++;
+			else
+				continue;
+
+		if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i))
+				continue;
+
+			//Fixed by Jacken from Bryant 2008-03-20
+			//Original value is 106
+			rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
+
+			//Get Rx snr value in DB
+			tmp_rxsnr =	pofdm_buf->rxsnr_X[i];
+			rx_snrX = (char)(tmp_rxsnr);
+			//rx_snrX >>= 1;;
+			rx_snrX /= 2;
+			priv->stats.rxSNRdB[i] = (long)rx_snrX;
+
+			/* Translate DBM to percentage. */
+			RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
+			total_rssi += RSSI;
+
+			/* Record Signal Strength for next packet */
+			//if(bpacket_match_bssid)
+			{
+				pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
+				precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
+			}
+		}
+
+
+		//
+		// (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
+		//
+		//Fixed by Jacken from Bryant 2008-03-20
+		//Original value is 106
+		rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
+		pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
+
+		pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
+		pstats->RxPower = precord_stats->RxPower =  rx_pwr_all;
+
+		//
+		// (3)EVM of HT rate
+		//
+		if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
+			pdrvinfo->RxRate<=DESC90_RATEMCS15)
+			max_spatial_stream = 2; //both spatial stream make sense
+		else
+			max_spatial_stream = 1; //only spatial stream 1 makes sense
+
+		for(i=0; i<max_spatial_stream; i++)
+		{
+			tmp_rxevm =	pofdm_buf->rxevm_X[i];
+			rx_evmX = (char)(tmp_rxevm);
+
+			// Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
+			// fill most significant bit to "zero" when doing shifting operation which may change a negative
+			// value to positive one, then the dbm value (which is supposed to be negative)  is not correct anymore.
+			rx_evmX /= 2;	//dbm
+
+			evm = rtl819x_evm_dbtopercentage(rx_evmX);
+			//if(bpacket_match_bssid)
+			{
+				if(i==0) // Fill value in RFD, Get the first spatial stream only
+					pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
+				pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
+			}
+		}
+
+
+		/* record rx statistics for debug */
+		rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
+		prxsc =	(phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
+		if(pdrvinfo->BW)	//40M channel
+			priv->stats.received_bwtype[1+prxsc->rxsc]++;
+		else				//20M channel
+			priv->stats.received_bwtype[0]++;
+	}
+
+	//UI BSS List signal strength(in percentage), make it good looking, from 0~100.
+	//It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
+	if(is_cck_rate)
+	{
+		pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;
+
+	}
+	else
+	{
+		//pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u8)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u8)(total_rssi/=RF90_PATH_MAX);
+		// We can judge RX path number now.
+		if (rf_rx_num != 0)
+			pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
+	}
+}	/* QueryRxPhyStatus8190Pci */
+
+void
+rtl8192_record_rxdesc_forlateruse(
+	struct ieee80211_rx_stats *	psrc_stats,
+	struct ieee80211_rx_stats *	ptarget_stats
+)
+{
+	ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
+	ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
+	ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
+}
+
+
+void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
+				   struct ieee80211_rx_stats * pstats,
+				   rx_drvinfo_819x_usb  *pdrvinfo)
+{
+	// TODO: We must only check packet for current MAC address. Not finish
+	rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
+	struct net_device *dev=info->dev;
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	bool bpacket_match_bssid, bpacket_toself;
+	bool bPacketBeacon=FALSE, bToSelfBA=FALSE;
+	static struct ieee80211_rx_stats  previous_stats;
+	struct ieee80211_hdr_3addr *hdr;//by amy
+       u16 fc,type;
+
+	// Get Signal Quality for only RX data queue (but not command queue)
+
+	u8* tmp_buf;
+	//u16 tmp_buf_len = 0;
+	u8  *praddr;
+
+	/* Get MAC frame start address. */
+	tmp_buf = (u8*)skb->data;// + get_rxpacket_shiftbytes_819xusb(pstats);
+
+	hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
+	fc = le16_to_cpu(hdr->frame_ctl);
+	type = WLAN_FC_GET_TYPE(fc);
+	praddr = hdr->addr1;
+
+	/* Check if the received packet is acceptabe. */
+	bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
+							(eqMacAddr(priv->ieee80211->current_network.bssid,  (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
+								 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
+	bpacket_toself =  bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
+
+		if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
+		{
+			bPacketBeacon = true;
+			//DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
+		}
+		if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
+		{
+			if((eqMacAddr(praddr,dev->dev_addr)))
+				bToSelfBA = true;
+				//DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
+		}
+
+
+
+	if(bpacket_match_bssid)
+	{
+		priv->stats.numpacket_matchbssid++;
+	}
+	if(bpacket_toself){
+		priv->stats.numpacket_toself++;
+	}
+	//
+	// Process PHY information for previous packet (RSSI/PWDB/EVM)
+	//
+	// Because phy information is contained in the last packet of AMPDU only, so driver
+	// should process phy information of previous packet
+	rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
+	rtl8192_query_rxphystatus(priv, pstats, pdrvinfo, &previous_stats, bpacket_match_bssid,bpacket_toself,bPacketBeacon,bToSelfBA);
+	rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
+
+}
+
+/**
+* Function:	UpdateReceivedRateHistogramStatistics
+* Overview:	Recored down the received data rate
+*
+* Input:
+* 	struct net_device *dev
+*	struct ieee80211_rx_stats *stats
+*
+* Output:
+*
+*			(priv->stats.ReceivedRateHistogram[] is updated)
+* Return:
+*		None
+*/
+void
+UpdateReceivedRateHistogramStatistics8190(
+	struct net_device *dev,
+	struct ieee80211_rx_stats *stats
+	)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	u32 rcvType=1;   //0: Total, 1:OK, 2:CRC, 3:ICV
+	u32 rateIndex;
+	u32 preamble_guardinterval;  //1: short preamble/GI, 0: long preamble/GI
+
+
+	if(stats->bCRC)
+	rcvType = 2;
+	else if(stats->bICV)
+	rcvType = 3;
+
+	if(stats->bShortPreamble)
+	preamble_guardinterval = 1;// short
+	else
+	preamble_guardinterval = 0;// long
+
+	switch(stats->rate)
+	{
+		//
+		// CCK rate
+		//
+		case MGN_1M:    rateIndex = 0;  break;
+		case MGN_2M:    rateIndex = 1;  break;
+		case MGN_5_5M:  rateIndex = 2;  break;
+		case MGN_11M:   rateIndex = 3;  break;
+		//
+		// Legacy OFDM rate
+		//
+		case MGN_6M:    rateIndex = 4;  break;
+		case MGN_9M:    rateIndex = 5;  break;
+		case MGN_12M:   rateIndex = 6;  break;
+		case MGN_18M:   rateIndex = 7;  break;
+		case MGN_24M:   rateIndex = 8;  break;
+		case MGN_36M:   rateIndex = 9;  break;
+		case MGN_48M:   rateIndex = 10; break;
+		case MGN_54M:   rateIndex = 11; break;
+		//
+		// 11n High throughput rate
+		//
+		case MGN_MCS0:  rateIndex = 12; break;
+		case MGN_MCS1:  rateIndex = 13; break;
+		case MGN_MCS2:  rateIndex = 14; break;
+		case MGN_MCS3:  rateIndex = 15; break;
+		case MGN_MCS4:  rateIndex = 16; break;
+		case MGN_MCS5:  rateIndex = 17; break;
+		case MGN_MCS6:  rateIndex = 18; break;
+		case MGN_MCS7:  rateIndex = 19; break;
+		case MGN_MCS8:  rateIndex = 20; break;
+		case MGN_MCS9:  rateIndex = 21; break;
+		case MGN_MCS10: rateIndex = 22; break;
+		case MGN_MCS11: rateIndex = 23; break;
+		case MGN_MCS12: rateIndex = 24; break;
+		case MGN_MCS13: rateIndex = 25; break;
+		case MGN_MCS14: rateIndex = 26; break;
+		case MGN_MCS15: rateIndex = 27; break;
+		default:        rateIndex = 28; break;
+	}
+    priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
+    priv->stats.received_rate_histogram[0][rateIndex]++; //total
+    priv->stats.received_rate_histogram[rcvType][rateIndex]++;
+}
+
+
+void query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe)
+{
+	rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
+	struct net_device *dev=info->dev;
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	//rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
+	rx_drvinfo_819x_usb  *driver_info = NULL;
+
+	//
+	//Get Rx Descriptor Information
+	//
+#ifdef USB_RX_AGGREGATION_SUPPORT
+	if (bIsRxAggrSubframe)
+	{
+		rx_desc_819x_usb_aggr_subframe *desc = (rx_desc_819x_usb_aggr_subframe *)skb->data;
+		stats->Length = desc->Length ;
+		stats->RxDrvInfoSize = desc->RxDrvInfoSize;
+		stats->RxBufShift = 0; //RxBufShift = 2 in RxDesc, but usb didn't shift bytes in fact.
+		stats->bICV = desc->ICV;
+		stats->bCRC = desc->CRC32;
+		stats->bHwError = stats->bCRC|stats->bICV;
+		stats->Decrypted = !desc->SWDec;//RTL8190 set this bit to indicate that Hw does not decrypt packet
+	} else
+#endif
+	{
+		rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
+
+		stats->Length = desc->Length;
+		stats->RxDrvInfoSize = desc->RxDrvInfoSize;
+		stats->RxBufShift = 0;//desc->Shift&0x03;
+		stats->bICV = desc->ICV;
+		stats->bCRC = desc->CRC32;
+		stats->bHwError = stats->bCRC|stats->bICV;
+		//RTL8190 set this bit to indicate that Hw does not decrypt packet
+		stats->Decrypted = !desc->SWDec;
+	}
+
+	if((priv->ieee80211->pHTInfo->bCurrentHTSupport == true) && (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP))
+	{
+		stats->bHwError = false;
+	}
+	else
+	{
+		stats->bHwError = stats->bCRC|stats->bICV;
+	}
+
+	if(stats->Length < 24 || stats->Length > MAX_8192U_RX_SIZE)
+		stats->bHwError |= 1;
+	//
+	//Get Driver Info
+	//
+	// TODO: Need to verify it on FGPA platform
+	//Driver info are written to the RxBuffer following rx desc
+	if (stats->RxDrvInfoSize != 0) {
+		driver_info = (rx_drvinfo_819x_usb *)(skb->data + sizeof(rx_desc_819x_usb) + \
+				stats->RxBufShift);
+		/* unit: 0.5M */
+		/* TODO */
+		if(!stats->bHwError){
+			u8	ret_rate;
+			ret_rate = HwRateToMRate90(driver_info->RxHT, driver_info->RxRate);
+			if(ret_rate == 0xff)
+			{
+				// Abnormal Case: Receive CRC OK packet with Rx descriptor indicating non supported rate.
+				// Special Error Handling here, 2008.05.16, by Emily
+
+				stats->bHwError = 1;
+				stats->rate = MGN_1M;	//Set 1M rate by default
+			}else
+			{
+				stats->rate = ret_rate;
+			}
+		}
+		else
+			stats->rate = 0x02;
+
+		stats->bShortPreamble = driver_info->SPLCP;
+
+
+		UpdateReceivedRateHistogramStatistics8190(dev, stats);
+
+		stats->bIsAMPDU = (driver_info->PartAggr==1);
+		stats->bFirstMPDU = (driver_info->PartAggr==1) && (driver_info->FirstAGGR==1);
+		stats->TimeStampLow = driver_info->TSFL;
+		// xiong mask it, 070514
+		//pRfd->Status.TimeStampHigh = PlatformEFIORead4Byte(Adapter, TSFR+4);
+		// stats->TimeStampHigh = read_nic_dword(dev,  TSFR+4);
+
+		UpdateRxPktTimeStamp8190(dev, stats);
+
+		//
+		// Rx A-MPDU
+		//
+		if(driver_info->FirstAGGR==1 || driver_info->PartAggr == 1)
+			RT_TRACE(COMP_RXDESC, "driver_info->FirstAGGR = %d, driver_info->PartAggr = %d\n",
+					driver_info->FirstAGGR, driver_info->PartAggr);
+
+	}
+
+	skb_pull(skb,sizeof(rx_desc_819x_usb));
+	//
+	// Get Total offset of MPDU Frame Body
+	//
+	if((stats->RxBufShift + stats->RxDrvInfoSize) > 0) {
+		stats->bShift = 1;
+		skb_pull(skb,stats->RxBufShift + stats->RxDrvInfoSize);
+	}
+
+#ifdef USB_RX_AGGREGATION_SUPPORT
+	/* for the rx aggregated sub frame, the redundant space truelly contained in the packet */
+	if(bIsRxAggrSubframe) {
+		skb_pull(skb, 8);
+	}
+#endif
+	/* for debug 2008.5.29 */
+
+	//added by vivi, for MP, 20080108
+	stats->RxIs40MHzPacket = driver_info->BW;
+	if(stats->RxDrvInfoSize != 0)
+		TranslateRxSignalStuff819xUsb(skb, stats, driver_info);
+
+}
+
+u32 GetRxPacketShiftBytes819xUsb(struct ieee80211_rx_stats  *Status, bool bIsRxAggrSubframe)
+{
+#ifdef USB_RX_AGGREGATION_SUPPORT
+	if (bIsRxAggrSubframe)
+		return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
+			+ Status->RxBufShift + 8);
+	else
+#endif
+		return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
+				+ Status->RxBufShift);
+}
+
+void rtl8192_rx_nomal(struct sk_buff* skb)
+{
+	rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
+	struct net_device *dev=info->dev;
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	struct ieee80211_rx_stats stats = {
+		.signal = 0,
+		.noise = -98,
+		.rate = 0,
+		//      .mac_time = jiffies,
+		.freq = IEEE80211_24GHZ_BAND,
+	};
+	u32 rx_pkt_len = 0;
+	struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
+	bool unicast_packet = false;
+#ifdef USB_RX_AGGREGATION_SUPPORT
+	struct sk_buff *agg_skb = NULL;
+	u32  TotalLength = 0;
+	u32  TempDWord = 0;
+	u32  PacketLength = 0;
+	u32  PacketOccupiedLendth = 0;
+	u8   TempByte = 0;
+	u32  PacketShiftBytes = 0;
+	rx_desc_819x_usb_aggr_subframe *RxDescr = NULL;
+	u8  PaddingBytes = 0;
+	//add just for testing
+	u8   testing;
+
+#endif
+
+	/* 20 is for ps-poll */
+	if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
+#ifdef USB_RX_AGGREGATION_SUPPORT
+		TempByte = *(skb->data + sizeof(rx_desc_819x_usb));
+#endif
+		/* first packet should not contain Rx aggregation header */
+		query_rxdesc_status(skb, &stats, false);
+		/* TODO */
+		/* hardware related info */
+#ifdef USB_RX_AGGREGATION_SUPPORT
+		if (TempByte & BIT0) {
+			agg_skb = skb;
+			//TotalLength = agg_skb->len - 4; /*sCrcLng*/
+			TotalLength = stats.Length - 4; /*sCrcLng*/
+			//RT_TRACE(COMP_RECV, "%s:first aggregated packet!Length=%d\n",__FUNCTION__,TotalLength);
+			/* though the head pointer has passed this position  */
+			TempDWord = *(u32 *)(agg_skb->data - 4);
+			PacketLength = (u16)(TempDWord & 0x3FFF); /*sCrcLng*/
+			skb = dev_alloc_skb(PacketLength);
+			memcpy(skb_put(skb,PacketLength),agg_skb->data,PacketLength);
+			PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, false);
+		}
+#endif
+		/* Process the MPDU recevied */
+		skb_trim(skb, skb->len - 4/*sCrcLng*/);
+
+		rx_pkt_len = skb->len;
+		ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
+		unicast_packet = false;
+		if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
+			//TODO
+		}else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
+			//TODO
+		}else {
+			/* unicast packet */
+			unicast_packet = true;
+		}
+
+		if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
+			dev_kfree_skb_any(skb);
+		} else {
+			priv->stats.rxoktotal++;
+			if(unicast_packet) {
+				priv->stats.rxbytesunicast += rx_pkt_len;
+			}
+		}
+#ifdef USB_RX_AGGREGATION_SUPPORT
+		testing = 1;
+		// (PipeIndex == 0) && (TempByte & BIT0) => TotalLength > 0.
+		if (TotalLength > 0) {
+			PacketOccupiedLendth = PacketLength + (PacketShiftBytes + 8);
+			if ((PacketOccupiedLendth & 0xFF) != 0)
+				PacketOccupiedLendth = (PacketOccupiedLendth & 0xFFFFFF00) + 256;
+			PacketOccupiedLendth -= 8;
+			TempDWord = PacketOccupiedLendth - PacketShiftBytes; /*- PacketLength */
+			if (agg_skb->len > TempDWord)
+				skb_pull(agg_skb, TempDWord);
+			else
+				agg_skb->len = 0;
+
+			while (agg_skb->len>=GetRxPacketShiftBytes819xUsb(&stats, true)) {
+				u8 tmpCRC = 0, tmpICV = 0;
+				//RT_TRACE(COMP_RECV,"%s:aggred pkt,total_len = %d\n",__FUNCTION__,agg_skb->len);
+				RxDescr = (rx_desc_819x_usb_aggr_subframe *)(agg_skb->data);
+				tmpCRC = RxDescr->CRC32;
+				tmpICV = RxDescr->ICV;
+				memcpy(agg_skb->data, &agg_skb->data[44], 2);
+				RxDescr->CRC32 = tmpCRC;
+				RxDescr->ICV = tmpICV;
+
+				memset(&stats, 0, sizeof(struct ieee80211_rx_stats));
+				stats.signal = 0;
+				stats.noise = -98;
+				stats.rate = 0;
+				stats.freq = IEEE80211_24GHZ_BAND;
+				query_rxdesc_status(agg_skb, &stats, true);
+				PacketLength = stats.Length;
+
+				if(PacketLength > agg_skb->len) {
+					break;
+				}
+				/* Process the MPDU recevied */
+				skb = dev_alloc_skb(PacketLength);
+				memcpy(skb_put(skb,PacketLength),agg_skb->data, PacketLength);
+				skb_trim(skb, skb->len - 4/*sCrcLng*/);
+
+				rx_pkt_len = skb->len;
+				ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
+				unicast_packet = false;
+				if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
+					//TODO
+				}else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
+					//TODO
+				}else {
+					/* unicast packet */
+					unicast_packet = true;
+				}
+				if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
+					dev_kfree_skb_any(skb);
+				} else {
+					priv->stats.rxoktotal++;
+					if(unicast_packet) {
+						priv->stats.rxbytesunicast += rx_pkt_len;
+					}
+				}
+				/* should trim the packet which has been copied to target skb */
+				skb_pull(agg_skb, PacketLength);
+				PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, true);
+				PacketOccupiedLendth = PacketLength + PacketShiftBytes;
+				if ((PacketOccupiedLendth & 0xFF) != 0) {
+					PaddingBytes = 256 - (PacketOccupiedLendth & 0xFF);
+					if (agg_skb->len > PaddingBytes)
+						skb_pull(agg_skb, PaddingBytes);
+					else
+						agg_skb->len = 0;
+				}
+			}
+			dev_kfree_skb(agg_skb);
+		}
+#endif
+	} else {
+		priv->stats.rxurberr++;
+		printk("actual_length:%d\n", skb->len);
+		dev_kfree_skb_any(skb);
+	}
+
+}
+
+void
+rtl819xusb_process_received_packet(
+	struct net_device *dev,
+	struct ieee80211_rx_stats *pstats
+	)
+{
+//	bool bfreerfd=false, bqueued=false;
+	u8* 	frame;
+	u16     frame_len=0;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+//	u8			index = 0;
+//	u8			TID = 0;
+	//u16			seqnum = 0;
+	//PRX_TS_RECORD	pts = NULL;
+
+	// Get shifted bytes of Starting address of 802.11 header. 2006.09.28, by Emily
+	//porting by amy 080508
+	pstats->virtual_address += get_rxpacket_shiftbytes_819xusb(pstats);
+	frame = pstats->virtual_address;
+	frame_len = pstats->packetlength;
+#ifdef TODO	// by amy about HCT
+	if(!Adapter->bInHctTest)
+		CountRxErrStatistics(Adapter, pRfd);
+#endif
+	{
+	#ifdef ENABLE_PS  //by amy for adding ps function in future
+		RT_RF_POWER_STATE rtState;
+		// When RF is off, we should not count the packet for hw/sw synchronize
+		// reason, ie. there may be a duration while sw switch is changed and hw
+		// switch is being changed. 2006.12.04, by shien chang.
+		Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (u8* )(&rtState));
+		if (rtState == eRfOff)
+		{
+			return;
+		}
+	#endif
+	priv->stats.rxframgment++;
+
+	}
+#ifdef TODO
+	RmMonitorSignalStrength(Adapter, pRfd);
+#endif
+	/* 2007/01/16 MH Add RX command packet handle here. */
+	/* 2007/03/01 MH We have to release RFD and return if rx pkt is cmd pkt. */
+	if (rtl819xusb_rx_command_packet(dev, pstats))
+	{
+		return;
+	}
+
+#ifdef SW_CRC_CHECK
+	SwCrcCheck();
+#endif
+
+
+}
+
+void query_rx_cmdpkt_desc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats)
+{
+//	rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
+//	struct net_device *dev=info->dev;
+//	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
+//	rx_drvinfo_819x_usb  *driver_info;
+
+	//
+	//Get Rx Descriptor Information
+	//
+	stats->virtual_address = (u8*)skb->data;
+	stats->Length = desc->Length;
+	stats->RxDrvInfoSize = 0;
+	stats->RxBufShift = 0;
+	stats->packetlength = stats->Length-scrclng;
+	stats->fraglength = stats->packetlength;
+	stats->fragoffset = 0;
+	stats->ntotalfrag = 1;
+}
+
+
+void rtl8192_rx_cmd(struct sk_buff *skb)
+{
+	struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
+	struct net_device *dev = info->dev;
+	//int ret;
+//	struct urb *rx_urb = info->urb;
+	/* TODO */
+	struct ieee80211_rx_stats stats = {
+		.signal = 0,
+		.noise = -98,
+		.rate = 0,
+		//      .mac_time = jiffies,
+		.freq = IEEE80211_24GHZ_BAND,
+	};
+
+	if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE))
+	{
+
+		query_rx_cmdpkt_desc_status(skb,&stats);
+		// this is to be done by amy 080508     prfd->queue_id = 1;
+
+
+		//
+		//  Process the command packet received.
+		//
+
+		rtl819xusb_process_received_packet(dev,&stats);
+
+		dev_kfree_skb_any(skb);
+	}
+	else
+		;
+
+
+}
+
+void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
+{
+	struct sk_buff *skb;
+	struct rtl8192_rx_info *info;
+
+	while (NULL != (skb = skb_dequeue(&priv->skb_queue))) {
+		info = (struct rtl8192_rx_info *)skb->cb;
+		switch (info->out_pipe) {
+		/* Nomal packet pipe */
+			case 3:
+				//RT_TRACE(COMP_RECV, "normal in-pipe index(%d)\n",info->out_pipe);
+				priv->IrpPendingCount--;
+				rtl8192_rx_nomal(skb);
+				break;
+
+				/* Command packet pipe */
+			case 9:
+				RT_TRACE(COMP_RECV, "command in-pipe index(%d)\n",\
+						info->out_pipe);
+
+				rtl8192_rx_cmd(skb);
+				break;
+
+			default: /* should never get here! */
+				RT_TRACE(COMP_ERR, "Unknown in-pipe index(%d)\n",\
+						info->out_pipe);
+				dev_kfree_skb(skb);
+				break;
+
+		}
+	}
+}
+
+static const struct net_device_ops rtl8192_netdev_ops = {
+	.ndo_open               = rtl8192_open,
+	.ndo_stop               = rtl8192_close,
+	.ndo_get_stats          = rtl8192_stats,
+	.ndo_tx_timeout         = tx_timeout,
+	.ndo_do_ioctl           = rtl8192_ioctl,
+	.ndo_set_multicast_list = r8192_set_multicast,
+	.ndo_set_mac_address    = r8192_set_mac_adr,
+	.ndo_validate_addr      = eth_validate_addr,
+	.ndo_change_mtu         = eth_change_mtu,
+	.ndo_start_xmit         = ieee80211_xmit,
+};
+
+
+/****************************************************************************
+     ---------------------------- USB_STUFF---------------------------
+*****************************************************************************/
+
+static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
+			 const struct usb_device_id *id)
+{
+//	unsigned long ioaddr = 0;
+	struct net_device *dev = NULL;
+	struct r8192_priv *priv= NULL;
+	struct usb_device *udev = interface_to_usbdev(intf);
+	RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
+
+	dev = alloc_ieee80211(sizeof(struct r8192_priv));
+
+
+	usb_set_intfdata(intf, dev);
+	SET_NETDEV_DEV(dev, &intf->dev);
+	priv = ieee80211_priv(dev);
+	priv->ieee80211 = netdev_priv(dev);
+	priv->udev=udev;
+
+	dev->netdev_ops = &rtl8192_netdev_ops;
+
+	 //DMESG("Oops: i'm coming\n");
+#if WIRELESS_EXT >= 12
+#if WIRELESS_EXT < 17
+	dev->get_wireless_stats = r8192_get_wireless_stats;
+#endif
+	dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
+#endif
+	dev->type=ARPHRD_ETHER;
+
+	dev->watchdog_timeo = HZ*3;	//modified by john, 0805
+
+	if (dev_alloc_name(dev, ifname) < 0){
+		RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
+		ifname = "wlan%d";
+		dev_alloc_name(dev, ifname);
+	}
+
+	RT_TRACE(COMP_INIT, "Driver probe completed1\n");
+	if(rtl8192_init(dev)!=0){
+		RT_TRACE(COMP_ERR, "Initialization failed");
+		goto fail;
+	}
+	netif_carrier_off(dev);
+	netif_stop_queue(dev);
+
+	register_netdev(dev);
+	RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
+	rtl8192_proc_init_one(dev);
+
+
+	RT_TRACE(COMP_INIT, "Driver probe completed\n");
+	return 0;
+
+
+fail:
+	free_ieee80211(dev);
+
+	RT_TRACE(COMP_ERR, "wlan driver load failed\n");
+	return -ENODEV;
+
+}
+
+//detach all the work and timer structure declared or inititialize in r8192U_init function.
+void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
+{
+
+	cancel_work_sync(&priv->reset_wq);
+	cancel_delayed_work(&priv->watch_dog_wq);
+	cancel_delayed_work(&priv->update_beacon_wq);
+	cancel_work_sync(&priv->qos_activate);
+	//cancel_work_sync(&priv->SetBWModeWorkItem);
+	//cancel_work_sync(&priv->SwChnlWorkItem);
+
+}
+
+
+static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf)
+{
+	struct net_device *dev = usb_get_intfdata(intf);
+
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	if(dev){
+
+		unregister_netdev(dev);
+
+		RT_TRACE(COMP_DOWN, "=============>wlan driver to be removed\n");
+		rtl8192_proc_remove_one(dev);
+
+			rtl8192_down(dev);
+		if (priv->pFirmware)
+		{
+			kfree(priv->pFirmware);
+			priv->pFirmware = NULL;
+		}
+	//	priv->rf_close(dev);
+//		rtl8192_SetRFPowerState(dev, eRfOff);
+		rtl8192_usb_deleteendpoints(dev);
+		destroy_workqueue(priv->priv_wq);
+		//rtl8192_irq_disable(dev);
+		//rtl8192_reset(dev);
+		mdelay(10);
+
+	}
+	free_ieee80211(dev);
+	RT_TRACE(COMP_DOWN, "wlan driver removed\n");
+}
+
+/* fun with the built-in ieee80211 stack... */
+extern int ieee80211_debug_init(void);
+extern void ieee80211_debug_exit(void);
+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);
+
+static int __init rtl8192_usb_module_init(void)
+{
+	int ret;
+
+#ifdef CONFIG_IEEE80211_DEBUG
+	ret = ieee80211_debug_init();
+	if (ret) {
+		printk(KERN_ERR "ieee80211_debug_init() failed %d\n", ret);
+		return ret;
+	}
+#endif
+	ret = ieee80211_crypto_init();
+	if (ret) {
+		printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret);
+		return ret;
+	}
+
+	ret = ieee80211_crypto_tkip_init();
+	if (ret) {
+		printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n",
+			ret);
+		return ret;
+	}
+
+	ret = ieee80211_crypto_ccmp_init();
+	if (ret) {
+		printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n",
+			ret);
+		return ret;
+	}
+
+	ret = ieee80211_crypto_wep_init();
+	if (ret) {
+		printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret);
+		return ret;
+	}
+
+	printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
+	printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
+	RT_TRACE(COMP_INIT, "Initializing module");
+	RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
+	rtl8192_proc_module_init();
+	return usb_register(&rtl8192_usb_driver);
+}
+
+
+static void __exit rtl8192_usb_module_exit(void)
+{
+	usb_deregister(&rtl8192_usb_driver);
+
+	RT_TRACE(COMP_DOWN, "Exiting");
+//	rtl8192_proc_module_remove();
+}
+
+
+void rtl8192_try_wake_queue(struct net_device *dev, int pri)
+{
+	unsigned long flags;
+	short enough_desc;
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+
+	spin_lock_irqsave(&priv->tx_lock,flags);
+	enough_desc = check_nic_enough_desc(dev,pri);
+	spin_unlock_irqrestore(&priv->tx_lock,flags);
+
+	if(enough_desc)
+		ieee80211_wake_queue(priv->ieee80211);
+}
+
+void EnableHWSecurityConfig8192(struct net_device *dev)
+{
+	u8 SECR_value = 0x0;
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	 struct ieee80211_device* ieee = priv->ieee80211;
+	SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
+	if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
+	{
+		SECR_value |= SCR_RxUseDK;
+		SECR_value |= SCR_TxUseDK;
+	}
+	else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
+	{
+		SECR_value |= SCR_RxUseDK;
+		SECR_value |= SCR_TxUseDK;
+	}
+	//add HWSec active enable here.
+//default using hwsec. when peer AP is in N mode only and pairwise_key_type is none_aes(which HT_IOT_ACT_PURE_N_MODE indicates it), use software security. when peer AP is in b,g,n mode mixed and pairwise_key_type is none_aes, use g mode hw security. WB on 2008.7.4
+
+	ieee->hwsec_active = 1;
+
+	if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep)//!ieee->hwsec_support) //add hwsec_support flag to totol control hw_sec on/off
+	{
+		ieee->hwsec_active = 0;
+		SECR_value &= ~SCR_RxDecEnable;
+	}
+	RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \
+			ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
+	{
+		write_nic_byte(dev, SECR,  SECR_value);//SECR_value |  SCR_UseDK );
+	}
+}
+
+
+void setKey(	struct net_device *dev,
+		u8 EntryNo,
+		u8 KeyIndex,
+		u16 KeyType,
+		u8 *MacAddr,
+		u8 DefaultKey,
+		u32 *KeyContent )
+{
+	u32 TargetCommand = 0;
+	u32 TargetContent = 0;
+	u16 usConfig = 0;
+	u8 i;
+	if (EntryNo >= TOTAL_CAM_ENTRY)
+		RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
+
+	RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr"MAC_FMT"\n", dev,EntryNo, KeyIndex, KeyType, MAC_ARG(MacAddr));
+
+	if (DefaultKey)
+		usConfig |= BIT15 | (KeyType<<2);
+	else
+		usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
+//	usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
+
+
+	for(i=0 ; i<CAM_CONTENT_COUNT; i++){
+		TargetCommand  = i+CAM_CONTENT_COUNT*EntryNo;
+		TargetCommand |= BIT31|BIT16;
+
+		if(i==0){//MAC|Config
+			TargetContent = (u32)(*(MacAddr+0)) << 16|
+					(u32)(*(MacAddr+1)) << 24|
+					(u32)usConfig;
+
+			write_nic_dword(dev, WCAMI, TargetContent);
+			write_nic_dword(dev, RWCAM, TargetCommand);
+	//		printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
+		}
+		else if(i==1){//MAC
+			TargetContent = (u32)(*(MacAddr+2)) 	 |
+					(u32)(*(MacAddr+3)) <<  8|
+					(u32)(*(MacAddr+4)) << 16|
+					(u32)(*(MacAddr+5)) << 24;
+			write_nic_dword(dev, WCAMI, TargetContent);
+			write_nic_dword(dev, RWCAM, TargetCommand);
+		}
+		else {
+			//Key Material
+			if(KeyContent !=NULL){
+			write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
+			write_nic_dword(dev, RWCAM, TargetCommand);
+		}
+	}
+	}
+
+}
+
+/***************************************************************************
+     ------------------- module init / exit stubs ----------------
+****************************************************************************/
+module_init(rtl8192_usb_module_init);
+module_exit(rtl8192_usb_module_exit);
diff --git a/drivers/staging/rtl8192u/r8192U_dm.c b/drivers/staging/rtl8192u/r8192U_dm.c
new file mode 100644
index 0000000..2dde9fa
--- /dev/null
+++ b/drivers/staging/rtl8192u/r8192U_dm.c
@@ -0,0 +1,3890 @@
+/*++
+Copyright-c Realtek Semiconductor Corp. All rights reserved.
+
+Module Name:
+	r8192U_dm.c
+
+Abstract:
+	HW dynamic mechanism.
+
+Major Change History:
+	When      	Who				What
+	----------	--------------- -------------------------------
+	2008-05-14	amy                     create version 0 porting from windows code.
+
+--*/
+#include "r8192U.h"
+#include "r8192U_dm.h"
+#include "r8192U_hw.h"
+#include "r819xU_phy.h"
+#include "r819xU_phyreg.h"
+#include "r8190_rtl8256.h"
+#include "r819xU_cmdpkt.h"
+/*---------------------------Define Local Constant---------------------------*/
+//
+// Indicate different AP vendor for IOT issue.
+//
+static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
+		{ 0x5e4322, 	0x5e4322, 	0x5e4322, 	0x604322, 	0xa44f, 	0x5ea44f};
+static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
+		{ 0x5e4322, 	0xa44f, 	0x5e4322, 	0x604322, 	0x5ea44f, 	0x5ea44f};
+
+
+#define RTK_UL_EDCA 0xa44f
+#define RTK_DL_EDCA 0x5e4322
+/*---------------------------Define Local Constant---------------------------*/
+
+
+/*------------------------Define global variable-----------------------------*/
+// Debug variable ?
+dig_t	dm_digtable;
+// Store current shoftware write register content for MAC PHY.
+u8		dm_shadow[16][256] = {{0}};
+// For Dynamic Rx Path Selection by Signal Strength
+DRxPathSel	DM_RxPathSelTable;
+/*------------------------Define global variable-----------------------------*/
+
+
+/*------------------------Define local variable------------------------------*/
+/*------------------------Define local variable------------------------------*/
+
+
+/*--------------------Define export function prototype-----------------------*/
+extern	void	init_hal_dm(struct net_device *dev);
+extern	void deinit_hal_dm(struct net_device *dev);
+
+extern void hal_dm_watchdog(struct net_device *dev);
+
+
+extern	void	init_rate_adaptive(struct net_device *dev);
+extern	void	dm_txpower_trackingcallback(struct work_struct *work);
+
+extern	void	dm_cck_txpower_adjust(struct net_device *dev,bool  binch14);
+extern	void	dm_restore_dynamic_mechanism_state(struct net_device *dev);
+extern	void	dm_backup_dynamic_mechanism_state(struct net_device *dev);
+extern	void	dm_change_dynamic_initgain_thresh(struct net_device *dev,
+								u32		dm_type,
+								u32		dm_value);
+extern	void	DM_ChangeFsyncSetting(struct net_device *dev,
+												s32		DM_Type,
+												s32		DM_Value);
+extern	void dm_force_tx_fw_info(struct net_device *dev,
+										u32		force_type,
+										u32		force_value);
+extern	void	dm_init_edca_turbo(struct net_device *dev);
+extern	void	dm_rf_operation_test_callback(unsigned long data);
+extern	void	dm_rf_pathcheck_workitemcallback(struct work_struct *work);
+extern	void dm_fsync_timer_callback(unsigned long data);
+extern	void dm_check_fsync(struct net_device *dev);
+extern	void	dm_shadow_init(struct net_device *dev);
+
+
+/*--------------------Define export function prototype-----------------------*/
+
+
+/*---------------------Define local function prototype-----------------------*/
+// DM --> Rate Adaptive
+static	void	dm_check_rate_adaptive(struct net_device *dev);
+
+// DM --> Bandwidth switch
+static	void	dm_init_bandwidth_autoswitch(struct net_device *dev);
+static	void	dm_bandwidth_autoswitch(	struct net_device *dev);
+
+// DM --> TX power control
+//static	void	dm_initialize_txpower_tracking(struct net_device *dev);
+
+static	void	dm_check_txpower_tracking(struct net_device *dev);
+
+
+
+//static	void	dm_txpower_reset_recovery(struct net_device *dev);
+
+
+// DM --> BB init gain restore
+#ifndef RTL8192U
+static	void	dm_bb_initialgain_restore(struct net_device *dev);
+
+
+// DM --> BB init gain backup
+static	void	dm_bb_initialgain_backup(struct net_device *dev);
+#endif
+// DM --> Dynamic Init Gain by RSSI
+static	void	dm_dig_init(struct net_device *dev);
+static	void	dm_ctrl_initgain_byrssi(struct net_device *dev);
+static	void	dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev);
+static	void	dm_ctrl_initgain_byrssi_by_driverrssi(	struct net_device *dev);
+static	void	dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct net_device *dev);
+static	void	dm_initial_gain(struct net_device *dev);
+static	void	dm_pd_th(struct net_device *dev);
+static	void	dm_cs_ratio(struct net_device *dev);
+
+static	void dm_init_ctstoself(struct net_device *dev);
+// DM --> EDCA turboe mode control
+static	void	dm_check_edca_turbo(struct net_device *dev);
+
+// DM --> HW RF control
+static	void	dm_check_rfctrl_gpio(struct net_device *dev);
+
+#ifndef RTL8190P
+//static	void	dm_gpio_change_rf(struct net_device *dev);
+#endif
+// DM --> Check PBC
+static	void dm_check_pbc_gpio(struct net_device *dev);
+
+
+// DM --> Check current RX RF path state
+static	void	dm_check_rx_path_selection(struct net_device *dev);
+static 	void dm_init_rxpath_selection(struct net_device *dev);
+static	void dm_rxpath_sel_byrssi(struct net_device *dev);
+
+
+// DM --> Fsync for broadcom ap
+static void dm_init_fsync(struct net_device *dev);
+static void dm_deInit_fsync(struct net_device *dev);
+
+//Added by vivi, 20080522
+static	void	dm_check_txrateandretrycount(struct net_device *dev);
+
+/*---------------------Define local function prototype-----------------------*/
+
+/*---------------------Define of Tx Power Control For Near/Far Range --------*/   //Add by Jacken 2008/02/18
+static	void	dm_init_dynamic_txpower(struct net_device *dev);
+static	void	dm_dynamic_txpower(struct net_device *dev);
+
+
+// DM --> For rate adaptive and DIG, we must send RSSI to firmware
+static	void dm_send_rssi_tofw(struct net_device *dev);
+static	void	dm_ctstoself(struct net_device *dev);
+/*---------------------------Define function prototype------------------------*/
+//================================================================================
+//	HW Dynamic mechanism interface.
+//================================================================================
+
+//
+//	Description:
+//		Prepare SW resource for HW dynamic mechanism.
+//
+//	Assumption:
+//		This function is only invoked at driver intialization once.
+//
+//
+extern	void
+init_hal_dm(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	// Undecorated Smoothed Signal Strength, it can utilized to dynamic mechanism.
+	priv->undecorated_smoothed_pwdb = -1;
+
+	//Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code.
+	dm_init_dynamic_txpower(dev);
+	init_rate_adaptive(dev);
+	//dm_initialize_txpower_tracking(dev);
+	dm_dig_init(dev);
+	dm_init_edca_turbo(dev);
+	dm_init_bandwidth_autoswitch(dev);
+	dm_init_fsync(dev);
+	dm_init_rxpath_selection(dev);
+	dm_init_ctstoself(dev);
+
+}	// InitHalDm
+
+extern void deinit_hal_dm(struct net_device *dev)
+{
+
+	dm_deInit_fsync(dev);
+
+}
+
+
+#ifdef USB_RX_AGGREGATION_SUPPORT
+void dm_CheckRxAggregation(struct net_device *dev) {
+	struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
+	PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
+	static unsigned long	lastTxOkCnt = 0;
+	static unsigned long	lastRxOkCnt = 0;
+	unsigned long		curTxOkCnt = 0;
+	unsigned long		curRxOkCnt = 0;
+
+/*
+	if (pHalData->bForcedUsbRxAggr) {
+		if (pHalData->ForcedUsbRxAggrInfo == 0) {
+			if (pHalData->bCurrentRxAggrEnable) {
+				Adapter->HalFunc.HalUsbRxAggrHandler(Adapter, FALSE);
+			}
+		} else {
+			if (!pHalData->bCurrentRxAggrEnable || (pHalData->ForcedUsbRxAggrInfo != pHalData->LastUsbRxAggrInfoSetting)) {
+				Adapter->HalFunc.HalUsbRxAggrHandler(Adapter, TRUE);
+			}
+		}
+		return;
+	}
+
+*/
+	curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
+	curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
+
+	if((curTxOkCnt + curRxOkCnt) < 15000000) {
+		return;
+	}
+
+	if(curTxOkCnt > 4*curRxOkCnt) {
+		if (priv->bCurrentRxAggrEnable) {
+			write_nic_dword(dev, 0x1a8, 0);
+			priv->bCurrentRxAggrEnable = false;
+		}
+	}else{
+		if (!priv->bCurrentRxAggrEnable && !pHTInfo->bCurrentRT2RTAggregation) {
+			u32 ulValue;
+			ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
+				(pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
+			/*
+			 * If usb rx firmware aggregation is enabled,
+			 * when anyone of three threshold conditions above is reached,
+			 * firmware will send aggregated packet to driver.
+			 */
+			write_nic_dword(dev, 0x1a8, ulValue);
+			priv->bCurrentRxAggrEnable = true;
+		}
+	}
+
+	lastTxOkCnt = priv->stats.txbytesunicast;
+	lastRxOkCnt = priv->stats.rxbytesunicast;
+}	// dm_CheckEdcaTurbo
+#endif
+
+
+
+extern  void    hal_dm_watchdog(struct net_device *dev)
+{
+	//struct r8192_priv *priv = ieee80211_priv(dev);
+
+	//static u8 	previous_bssid[6] ={0};
+
+	/*Add by amy 2008/05/15 ,porting from windows code.*/
+	dm_check_rate_adaptive(dev);
+	dm_dynamic_txpower(dev);
+	dm_check_txrateandretrycount(dev);
+	dm_check_txpower_tracking(dev);
+	dm_ctrl_initgain_byrssi(dev);
+	dm_check_edca_turbo(dev);
+	dm_bandwidth_autoswitch(dev);
+	dm_check_rfctrl_gpio(dev);
+	dm_check_rx_path_selection(dev);
+	dm_check_fsync(dev);
+
+	// Add by amy 2008-05-15 porting from windows code.
+	dm_check_pbc_gpio(dev);
+	dm_send_rssi_tofw(dev);
+	dm_ctstoself(dev);
+#ifdef USB_RX_AGGREGATION_SUPPORT
+	dm_CheckRxAggregation(dev);
+#endif
+}	//HalDmWatchDog
+
+
+/*
+  * Decide Rate Adaptive Set according to distance (signal strength)
+  *	01/11/2008	MHC		Modify input arguments and RATR table level.
+  *	01/16/2008	MHC		RF_Type is assigned in ReadAdapterInfo(). We must call
+  *						the function after making sure RF_Type.
+  */
+extern void init_rate_adaptive(struct net_device * dev)
+{
+
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	prate_adaptive	pra = (prate_adaptive)&priv->rate_adaptive;
+
+	pra->ratr_state = DM_RATR_STA_MAX;
+	pra->high2low_rssi_thresh_for_ra = RateAdaptiveTH_High;
+	pra->low2high_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M+5;
+	pra->low2high_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M+5;
+
+	pra->high_rssi_thresh_for_ra = RateAdaptiveTH_High+5;
+	pra->low_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M;
+	pra->low_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M;
+
+	if(priv->CustomerID == RT_CID_819x_Netcore)
+		pra->ping_rssi_enable = 1;
+	else
+		pra->ping_rssi_enable = 0;
+	pra->ping_rssi_thresh_for_ra = 15;
+
+
+	if (priv->rf_type == RF_2T4R)
+	{
+		// 07/10/08 MH Modify for RA smooth scheme.
+		/* 2008/01/11 MH Modify 2T RATR table for different RSSI. 080515 porting by amy from windows code.*/
+		pra->upper_rssi_threshold_ratr		= 	0x8f0f0000;
+		pra->middle_rssi_threshold_ratr		= 	0x8f0ff000;
+		pra->low_rssi_threshold_ratr		= 	0x8f0ff001;
+		pra->low_rssi_threshold_ratr_40M	= 	0x8f0ff005;
+		pra->low_rssi_threshold_ratr_20M	= 	0x8f0ff001;
+		pra->ping_rssi_ratr	= 	0x0000000d;//cosa add for test
+	}
+	else if (priv->rf_type == RF_1T2R)
+	{
+		pra->upper_rssi_threshold_ratr		= 	0x000f0000;
+		pra->middle_rssi_threshold_ratr		= 	0x000ff000;
+		pra->low_rssi_threshold_ratr		= 	0x000ff001;
+		pra->low_rssi_threshold_ratr_40M	= 	0x000ff005;
+		pra->low_rssi_threshold_ratr_20M	= 	0x000ff001;
+		pra->ping_rssi_ratr	= 	0x0000000d;//cosa add for test
+	}
+
+}	// InitRateAdaptive
+
+
+/*-----------------------------------------------------------------------------
+ * Function:	dm_check_rate_adaptive()
+ *
+ * Overview:
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/26/08	amy 	Create version 0 proting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static void dm_check_rate_adaptive(struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
+	prate_adaptive			pra = (prate_adaptive)&priv->rate_adaptive;
+	u32						currentRATR, targetRATR = 0;
+	u32						LowRSSIThreshForRA = 0, HighRSSIThreshForRA = 0;
+	bool						bshort_gi_enabled = false;
+	static u8					ping_rssi_state=0;
+
+
+	if(!priv->up)
+	{
+		RT_TRACE(COMP_RATE, "<---- dm_check_rate_adaptive(): driver is going to unload\n");
+		return;
+	}
+
+	if(pra->rate_adaptive_disabled)//this variable is set by ioctl.
+		return;
+
+	// TODO: Only 11n mode is implemented currently,
+	if( !(priv->ieee80211->mode == WIRELESS_MODE_N_24G ||
+		 priv->ieee80211->mode == WIRELESS_MODE_N_5G))
+		 return;
+
+	if( priv->ieee80211->state == IEEE80211_LINKED )
+	{
+	//	RT_TRACE(COMP_RATE, "dm_CheckRateAdaptive(): \t");
+
+		//
+		// Check whether Short GI is enabled
+		//
+		bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI40MHz) ||
+			(!pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI20MHz);
+
+
+		pra->upper_rssi_threshold_ratr =
+				(pra->upper_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
+
+		pra->middle_rssi_threshold_ratr =
+				(pra->middle_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
+
+		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
+		{
+			pra->low_rssi_threshold_ratr =
+				(pra->low_rssi_threshold_ratr_40M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
+		}
+		else
+		{
+			pra->low_rssi_threshold_ratr =
+			(pra->low_rssi_threshold_ratr_20M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
+		}
+		//cosa add for test
+		pra->ping_rssi_ratr =
+				(pra->ping_rssi_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
+
+		/* 2007/10/08 MH We support RA smooth scheme now. When it is the first
+		   time to link with AP. We will not change upper/lower threshold. If
+		   STA stay in high or low level, we must change two different threshold
+		   to prevent jumping frequently. */
+		if (pra->ratr_state == DM_RATR_STA_HIGH)
+		{
+			HighRSSIThreshForRA 	= pra->high2low_rssi_thresh_for_ra;
+			LowRSSIThreshForRA	= (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
+					(pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
+		}
+		else if (pra->ratr_state == DM_RATR_STA_LOW)
+		{
+			HighRSSIThreshForRA	= pra->high_rssi_thresh_for_ra;
+			LowRSSIThreshForRA 	= (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
+					(pra->low2high_rssi_thresh_for_ra40M):(pra->low2high_rssi_thresh_for_ra20M);
+		}
+		else
+		{
+			HighRSSIThreshForRA	= pra->high_rssi_thresh_for_ra;
+			LowRSSIThreshForRA	= (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
+					(pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
+		}
+
+		//DbgPrint("[DM] THresh H/L=%d/%d\n\r", RATR.HighRSSIThreshForRA, RATR.LowRSSIThreshForRA);
+		if(priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA)
+		{
+			//DbgPrint("[DM] RSSI=%d STA=HIGH\n\r", pHalData->UndecoratedSmoothedPWDB);
+			pra->ratr_state = DM_RATR_STA_HIGH;
+			targetRATR = pra->upper_rssi_threshold_ratr;
+		}else if(priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA)
+		{
+			//DbgPrint("[DM] RSSI=%d STA=Middle\n\r", pHalData->UndecoratedSmoothedPWDB);
+			pra->ratr_state = DM_RATR_STA_MIDDLE;
+			targetRATR = pra->middle_rssi_threshold_ratr;
+		}else
+		{
+			//DbgPrint("[DM] RSSI=%d STA=LOW\n\r", pHalData->UndecoratedSmoothedPWDB);
+			pra->ratr_state = DM_RATR_STA_LOW;
+			targetRATR = pra->low_rssi_threshold_ratr;
+		}
+
+			//cosa add for test
+		if(pra->ping_rssi_enable)
+		{
+			//pHalData->UndecoratedSmoothedPWDB = 19;
+			if(priv->undecorated_smoothed_pwdb < (long)(pra->ping_rssi_thresh_for_ra+5))
+			{
+				if( (priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) ||
+					ping_rssi_state )
+				{
+					//DbgPrint("TestRSSI = %d, set RATR to 0x%x \n", pHalData->UndecoratedSmoothedPWDB, pRA->TestRSSIRATR);
+					pra->ratr_state = DM_RATR_STA_LOW;
+					targetRATR = pra->ping_rssi_ratr;
+					ping_rssi_state = 1;
+				}
+				//else
+				//	DbgPrint("TestRSSI is between the range. \n");
+			}
+			else
+			{
+				//DbgPrint("TestRSSI Recover to 0x%x \n", targetRATR);
+				ping_rssi_state = 0;
+			}
+		}
+
+		// 2008.04.01
+		// For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7.
+		if(priv->ieee80211->GetHalfNmodeSupportByAPsHandler(dev))
+			targetRATR &=  0xf00fffff;
+
+		//
+		// Check whether updating of RATR0 is required
+		//
+		currentRATR = read_nic_dword(dev, RATR0);
+		if( targetRATR !=  currentRATR )
+		{
+			u32 ratr_value;
+			ratr_value = targetRATR;
+			RT_TRACE(COMP_RATE,"currentRATR = %x, targetRATR = %x\n", currentRATR, targetRATR);
+			if(priv->rf_type == RF_1T2R)
+			{
+				ratr_value &= ~(RATE_ALL_OFDM_2SS);
+			}
+			write_nic_dword(dev, RATR0, ratr_value);
+			write_nic_byte(dev, UFWP, 1);
+
+			pra->last_ratr = targetRATR;
+		}
+
+	}
+	else
+	{
+		pra->ratr_state = DM_RATR_STA_MAX;
+	}
+
+}	// dm_CheckRateAdaptive
+
+
+static void dm_init_bandwidth_autoswitch(struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH;
+	priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW;
+	priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
+	priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable = false;
+
+}	// dm_init_bandwidth_autoswitch
+
+
+static void dm_bandwidth_autoswitch(struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 ||!priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable){
+		return;
+	}else{
+		if(priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz == false){//If send packets in 40 Mhz in 20/40
+			if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz)
+				priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = true;
+		}else{//in force send packets in 20 Mhz in 20/40
+			if(priv->undecorated_smoothed_pwdb >= priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz)
+				priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
+
+		}
+	}
+}	// dm_BandwidthAutoSwitch
+
+//OFDM default at 0db, index=6.
+static u32 OFDMSwingTable[OFDM_Table_Length] = {
+	0x7f8001fe,	// 0, +6db
+	0x71c001c7,	// 1, +5db
+	0x65400195,	// 2, +4db
+	0x5a400169,	// 3, +3db
+	0x50800142,	// 4, +2db
+	0x47c0011f,	// 5, +1db
+	0x40000100,	// 6, +0db ===> default, upper for higher temprature, lower for low temprature
+	0x390000e4,	// 7, -1db
+	0x32c000cb,	// 8, -2db
+	0x2d4000b5,	// 9, -3db
+	0x288000a2,	// 10, -4db
+	0x24000090,	// 11, -5db
+	0x20000080,	// 12, -6db
+	0x1c800072,	// 13, -7db
+	0x19800066,	// 14, -8db
+	0x26c0005b,	// 15, -9db
+	0x24400051,	// 16, -10db
+	0x12000048,	// 17, -11db
+	0x10000040	// 18, -12db
+};
+
+static u8	CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = {
+	{0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},	// 0, +0db ===> CCK40M default
+	{0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},	// 1, -1db
+	{0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},	// 2, -2db
+	{0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},	// 3, -3db
+	{0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},	// 4, -4db
+	{0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},	// 5, -5db
+	{0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},	// 6, -6db ===> CCK20M default
+	{0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},	// 7, -7db
+	{0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},	// 8, -8db
+	{0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},	// 9, -9db
+	{0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},	// 10, -10db
+	{0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}	// 11, -11db
+};
+
+static u8	CCKSwingTable_Ch14[CCK_Table_length][8] = {
+	{0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},	// 0, +0db  ===> CCK40M default
+	{0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},	// 1, -1db
+	{0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},	// 2, -2db
+	{0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},	// 3, -3db
+	{0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},	// 4, -4db
+	{0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},	// 5, -5db
+	{0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},	// 6, -6db  ===> CCK20M default
+	{0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},	// 7, -7db
+	{0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},	// 8, -8db
+	{0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},	// 9, -9db
+	{0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},	// 10, -10db
+	{0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}	// 11, -11db
+};
+
+static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	bool						bHighpowerstate, viviflag = FALSE;
+	DCMD_TXCMD_T			tx_cmd;
+	u8						powerlevelOFDM24G;
+	int						i =0, j = 0, k = 0;
+	u8						RF_Type, tmp_report[5]={0, 0, 0, 0, 0};
+	u32						Value;
+	u8						Pwr_Flag;
+	u16						Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver=0;
+	//RT_STATUS 				rtStatus = RT_STATUS_SUCCESS;
+	bool rtStatus = true;
+	u32						delta=0;
+
+	write_nic_byte(dev, 0x1ba, 0);
+
+	priv->ieee80211->bdynamic_txpower_enable = false;
+	bHighpowerstate = priv->bDynamicTxHighPower;
+
+	powerlevelOFDM24G = (u8)(priv->Pwr_Track>>24);
+	RF_Type = priv->rf_type;
+	Value = (RF_Type<<8) | powerlevelOFDM24G;
+
+	RT_TRACE(COMP_POWER_TRACKING, "powerlevelOFDM24G = %x\n", powerlevelOFDM24G);
+
+	for(j = 0; j<=30; j++)
+{	//fill tx_cmd
+
+	tx_cmd.Op		= TXCMD_SET_TX_PWR_TRACKING;
+	tx_cmd.Length	= 4;
+	tx_cmd.Value		= Value;
+#ifdef RTL8192U
+	rtStatus = SendTxCommandPacket(dev, &tx_cmd, 12);
+	if (rtStatus == RT_STATUS_FAILURE)
+	{
+		RT_TRACE(COMP_POWER_TRACKING, "Set configuration with tx cmd queue fail!\n");
+	}
+#else
+	cmpk_message_handle_tx(dev, (u8*)&tx_cmd,
+								DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T));
+#endif
+	mdelay(1);
+	//DbgPrint("hi, vivi, strange\n");
+	for(i = 0;i <= 30; i++)
+	{
+		Pwr_Flag = read_nic_byte(dev, 0x1ba);
+
+		if (Pwr_Flag == 0)
+		{
+			mdelay(1);
+			continue;
+		}
+#ifdef RTL8190P
+		Avg_TSSI_Meas = read_nic_word(dev, 0x1bc);
+#else
+		Avg_TSSI_Meas = read_nic_word(dev, 0x13c);
+#endif
+		if(Avg_TSSI_Meas == 0)
+		{
+			write_nic_byte(dev, 0x1ba, 0);
+			break;
+		}
+
+		for(k = 0;k < 5; k++)
+		{
+#ifdef RTL8190P
+			tmp_report[k] = read_nic_byte(dev, 0x1d8+k);
+#else
+			if(k !=4)
+				tmp_report[k] = read_nic_byte(dev, 0x134+k);
+			else
+				tmp_report[k] = read_nic_byte(dev, 0x13e);
+#endif
+			RT_TRACE(COMP_POWER_TRACKING, "TSSI_report_value = %d\n", tmp_report[k]);
+		}
+
+		//check if the report value is right
+		for(k = 0;k < 5; k++)
+		{
+			if(tmp_report[k] <= 20)
+			{
+				viviflag =TRUE;
+				break;
+			}
+		}
+		if(viviflag ==TRUE)
+		{
+			write_nic_byte(dev, 0x1ba, 0);
+			viviflag = FALSE;
+			RT_TRACE(COMP_POWER_TRACKING, "we filted this data\n");
+			for(k = 0;k < 5; k++)
+				tmp_report[k] = 0;
+			break;
+		}
+
+		for(k = 0;k < 5; k++)
+		{
+			Avg_TSSI_Meas_from_driver += tmp_report[k];
+		}
+
+		Avg_TSSI_Meas_from_driver = Avg_TSSI_Meas_from_driver*100/5;
+		RT_TRACE(COMP_POWER_TRACKING, "Avg_TSSI_Meas_from_driver = %d\n", Avg_TSSI_Meas_from_driver);
+		TSSI_13dBm = priv->TSSI_13dBm;
+		RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", TSSI_13dBm);
+
+		//if(abs(Avg_TSSI_Meas_from_driver - TSSI_13dBm) <= E_FOR_TX_POWER_TRACK)
+		// For MacOS-compatible
+		if(Avg_TSSI_Meas_from_driver > TSSI_13dBm)
+			delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm;
+		else
+			delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver;
+
+		if(delta <= E_FOR_TX_POWER_TRACK)
+		{
+			priv->ieee80211->bdynamic_txpower_enable = TRUE;
+			write_nic_byte(dev, 0x1ba, 0);
+			RT_TRACE(COMP_POWER_TRACKING, "tx power track is done\n");
+			RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
+			RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
+#ifdef RTL8190P
+			RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex = %d\n", priv->rfc_txpowertrackingindex);
+			RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real = %d\n", priv->rfc_txpowertrackingindex_real);
+#endif
+			RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation_difference = %d\n", priv->cck_present_attentuation_difference);
+			RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation = %d\n", priv->cck_present_attentuation);
+			return;
+		}
+		else
+		{
+			if(Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK)
+			{
+				if((priv->rfa_txpowertrackingindex > 0)
+#ifdef RTL8190P
+					&&(priv->rfc_txpowertrackingindex > 0)
+#endif
+				)
+				{
+					priv->rfa_txpowertrackingindex--;
+					if(priv->rfa_txpowertrackingindex_real > 4)
+					{
+						priv->rfa_txpowertrackingindex_real--;
+						rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
+					}
+#ifdef RTL8190P
+					priv->rfc_txpowertrackingindex--;
+					if(priv->rfc_txpowertrackingindex_real > 4)
+					{
+						priv->rfc_txpowertrackingindex_real--;
+						rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
+					}
+#endif
+				}
+			}
+			else
+			{
+				if((priv->rfa_txpowertrackingindex < 36)
+#ifdef RTL8190P
+					&&(priv->rfc_txpowertrackingindex < 36)
+#endif
+					)
+				{
+					priv->rfa_txpowertrackingindex++;
+					priv->rfa_txpowertrackingindex_real++;
+					rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
+
+#ifdef RTL8190P
+					priv->rfc_txpowertrackingindex++;
+					priv->rfc_txpowertrackingindex_real++;
+					rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
+#endif
+				}
+			}
+			priv->cck_present_attentuation_difference
+				= priv->rfa_txpowertrackingindex - priv->rfa_txpowertracking_default;
+
+			if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
+				priv->cck_present_attentuation
+				= priv->cck_present_attentuation_20Mdefault + priv->cck_present_attentuation_difference;
+			else
+				priv->cck_present_attentuation
+				= priv->cck_present_attentuation_40Mdefault + priv->cck_present_attentuation_difference;
+
+			if(priv->cck_present_attentuation > -1&&priv->cck_present_attentuation <23)
+			{
+				if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14)
+				{
+					priv->bcck_in_ch14 = TRUE;
+					dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
+				}
+				else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14)
+				{
+					priv->bcck_in_ch14 = FALSE;
+					dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
+				}
+				else
+					dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
+			}
+		RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
+		RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
+#ifdef RTL8190P
+		RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex = %d\n", priv->rfc_txpowertrackingindex);
+		RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real = %d\n", priv->rfc_txpowertrackingindex_real);
+#endif
+		RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation_difference = %d\n", priv->cck_present_attentuation_difference);
+		RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation = %d\n", priv->cck_present_attentuation);
+
+		if (priv->cck_present_attentuation_difference <= -12||priv->cck_present_attentuation_difference >= 24)
+		{
+			priv->ieee80211->bdynamic_txpower_enable = TRUE;
+			write_nic_byte(dev, 0x1ba, 0);
+			RT_TRACE(COMP_POWER_TRACKING, "tx power track--->limited\n");
+			return;
+		}
+
+
+	}
+		write_nic_byte(dev, 0x1ba, 0);
+		Avg_TSSI_Meas_from_driver = 0;
+		for(k = 0;k < 5; k++)
+			tmp_report[k] = 0;
+		break;
+	}
+}
+		priv->ieee80211->bdynamic_txpower_enable = TRUE;
+		write_nic_byte(dev, 0x1ba, 0);
+}
+
+static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev)
+{
+#define ThermalMeterVal	9
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32 tmpRegA, TempCCk;
+	u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval;
+	int i =0, CCKSwingNeedUpdate=0;
+
+	if(!priv->btxpower_trackingInit)
+	{
+		//Query OFDM default setting
+		tmpRegA= rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord);
+		for(i=0; i<OFDM_Table_Length; i++)	//find the index
+		{
+			if(tmpRegA == OFDMSwingTable[i])
+			{
+				priv->OFDM_index= (u8)i;
+				RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, OFDM_index=0x%x\n",
+					rOFDM0_XATxIQImbalance, tmpRegA, priv->OFDM_index);
+			}
+		}
+
+		//Query CCK default setting From 0xa22
+		TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
+		for(i=0 ; i<CCK_Table_length ; i++)
+		{
+			if(TempCCk == (u32)CCKSwingTable_Ch1_Ch13[i][0])
+			{
+				priv->CCK_index =(u8) i;
+				RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, CCK_index=0x%x\n",
+					rCCK0_TxFilter1, TempCCk, priv->CCK_index);
+				break;
+			}
+		}
+		priv->btxpower_trackingInit = TRUE;
+		//pHalData->TXPowercount = 0;
+		return;
+	}
+
+	//==========================
+	// this is only for test, should be masked
+	//==========================
+
+	// read and filter out unreasonable value
+	tmpRegA = rtl8192_phy_QueryRFReg(dev, RF90_PATH_A, 0x12, 0x078);	// 0x12: RF Reg[10:7]
+	RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d \n", tmpRegA);
+	if(tmpRegA < 3 || tmpRegA > 13)
+		return;
+	if(tmpRegA >= 12)	// if over 12, TP will be bad when high temprature
+		tmpRegA = 12;
+	RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d \n", tmpRegA);
+	priv->ThermalMeter[0] = ThermalMeterVal;	//We use fixed value by Bryant's suggestion
+	priv->ThermalMeter[1] = ThermalMeterVal;	//We use fixed value by Bryant's suggestion
+
+	//Get current RF-A temprature index
+	if(priv->ThermalMeter[0] >= (u8)tmpRegA)	//lower temprature
+	{
+		tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0]-(u8)tmpRegA);
+		tmpCCK40Mindex = tmpCCK20Mindex - 6;
+		if(tmpOFDMindex >= OFDM_Table_Length)
+			tmpOFDMindex = OFDM_Table_Length-1;
+		if(tmpCCK20Mindex >= CCK_Table_length)
+			tmpCCK20Mindex = CCK_Table_length-1;
+		if(tmpCCK40Mindex >= CCK_Table_length)
+			tmpCCK40Mindex = CCK_Table_length-1;
+	}
+	else
+	{
+		tmpval = ((u8)tmpRegA - priv->ThermalMeter[0]);
+		if(tmpval >= 6)								// higher temprature
+			tmpOFDMindex = tmpCCK20Mindex = 0;		// max to +6dB
+		else
+			tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval;
+		tmpCCK40Mindex = 0;
+	}
+	//DbgPrint("%ddb, tmpOFDMindex = %d, tmpCCK20Mindex = %d, tmpCCK40Mindex = %d",
+		//((u1Byte)tmpRegA - pHalData->ThermalMeter[0]),
+		//tmpOFDMindex, tmpCCK20Mindex, tmpCCK40Mindex);
+	if(priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)	//40M
+		tmpCCKindex = tmpCCK40Mindex;
+	else
+		tmpCCKindex = tmpCCK20Mindex;
+
+	if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14)
+	{
+		priv->bcck_in_ch14 = TRUE;
+		CCKSwingNeedUpdate = 1;
+	}
+	else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14)
+	{
+		priv->bcck_in_ch14 = FALSE;
+		CCKSwingNeedUpdate = 1;
+	}
+
+	if(priv->CCK_index != tmpCCKindex)
+	{
+		priv->CCK_index = tmpCCKindex;
+		CCKSwingNeedUpdate = 1;
+	}
+
+	if(CCKSwingNeedUpdate)
+	{
+		//DbgPrint("Update CCK Swing, CCK_index = %d\n", pHalData->CCK_index);
+		dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
+	}
+	if(priv->OFDM_index != tmpOFDMindex)
+	{
+		priv->OFDM_index = tmpOFDMindex;
+		rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable[priv->OFDM_index]);
+		RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n",
+			priv->OFDM_index, OFDMSwingTable[priv->OFDM_index]);
+	}
+	priv->txpower_count = 0;
+}
+
+extern	void	dm_txpower_trackingcallback(struct work_struct *work)
+{
+	struct delayed_work *dwork = container_of(work,struct delayed_work,work);
+       struct r8192_priv *priv = container_of(dwork,struct r8192_priv,txpower_tracking_wq);
+       struct net_device *dev = priv->ieee80211->dev;
+
+#ifdef RTL8190P
+	dm_TXPowerTrackingCallback_TSSI(dev);
+#else
+	if(priv->bDcut == TRUE)
+		dm_TXPowerTrackingCallback_TSSI(dev);
+	else
+		dm_TXPowerTrackingCallback_ThermalMeter(dev);
+#endif
+}
+
+
+static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev)
+{
+
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	//Initial the Tx BB index and mapping value
+	priv->txbbgain_table[0].txbb_iq_amplifygain = 			12;
+	priv->txbbgain_table[0].txbbgain_value=0x7f8001fe;
+	priv->txbbgain_table[1].txbb_iq_amplifygain = 			11;
+	priv->txbbgain_table[1].txbbgain_value=0x788001e2;
+	priv->txbbgain_table[2].txbb_iq_amplifygain = 			10;
+	priv->txbbgain_table[2].txbbgain_value=0x71c001c7;
+	priv->txbbgain_table[3].txbb_iq_amplifygain = 			9;
+	priv->txbbgain_table[3].txbbgain_value=0x6b8001ae;
+	priv->txbbgain_table[4].txbb_iq_amplifygain = 		       8;
+	priv->txbbgain_table[4].txbbgain_value=0x65400195;
+	priv->txbbgain_table[5].txbb_iq_amplifygain = 		       7;
+	priv->txbbgain_table[5].txbbgain_value=0x5fc0017f;
+	priv->txbbgain_table[6].txbb_iq_amplifygain = 		       6;
+	priv->txbbgain_table[6].txbbgain_value=0x5a400169;
+	priv->txbbgain_table[7].txbb_iq_amplifygain = 		       5;
+	priv->txbbgain_table[7].txbbgain_value=0x55400155;
+	priv->txbbgain_table[8].txbb_iq_amplifygain = 		       4;
+	priv->txbbgain_table[8].txbbgain_value=0x50800142;
+	priv->txbbgain_table[9].txbb_iq_amplifygain = 		       3;
+	priv->txbbgain_table[9].txbbgain_value=0x4c000130;
+	priv->txbbgain_table[10].txbb_iq_amplifygain = 		       2;
+	priv->txbbgain_table[10].txbbgain_value=0x47c0011f;
+	priv->txbbgain_table[11].txbb_iq_amplifygain = 		       1;
+	priv->txbbgain_table[11].txbbgain_value=0x43c0010f;
+	priv->txbbgain_table[12].txbb_iq_amplifygain = 		       0;
+	priv->txbbgain_table[12].txbbgain_value=0x40000100;
+	priv->txbbgain_table[13].txbb_iq_amplifygain = 		       -1;
+	priv->txbbgain_table[13].txbbgain_value=0x3c8000f2;
+	priv->txbbgain_table[14].txbb_iq_amplifygain = 		     -2;
+	priv->txbbgain_table[14].txbbgain_value=0x390000e4;
+	priv->txbbgain_table[15].txbb_iq_amplifygain = 		     -3;
+	priv->txbbgain_table[15].txbbgain_value=0x35c000d7;
+	priv->txbbgain_table[16].txbb_iq_amplifygain = 		     -4;
+	priv->txbbgain_table[16].txbbgain_value=0x32c000cb;
+	priv->txbbgain_table[17].txbb_iq_amplifygain = 		     -5;
+	priv->txbbgain_table[17].txbbgain_value=0x300000c0;
+	priv->txbbgain_table[18].txbb_iq_amplifygain = 			    -6;
+	priv->txbbgain_table[18].txbbgain_value=0x2d4000b5;
+	priv->txbbgain_table[19].txbb_iq_amplifygain = 		     -7;
+	priv->txbbgain_table[19].txbbgain_value=0x2ac000ab;
+	priv->txbbgain_table[20].txbb_iq_amplifygain = 		     -8;
+	priv->txbbgain_table[20].txbbgain_value=0x288000a2;
+	priv->txbbgain_table[21].txbb_iq_amplifygain = 		     -9;
+	priv->txbbgain_table[21].txbbgain_value=0x26000098;
+	priv->txbbgain_table[22].txbb_iq_amplifygain = 		     -10;
+	priv->txbbgain_table[22].txbbgain_value=0x24000090;
+	priv->txbbgain_table[23].txbb_iq_amplifygain = 		     -11;
+	priv->txbbgain_table[23].txbbgain_value=0x22000088;
+	priv->txbbgain_table[24].txbb_iq_amplifygain = 		     -12;
+	priv->txbbgain_table[24].txbbgain_value=0x20000080;
+	priv->txbbgain_table[25].txbb_iq_amplifygain = 		     -13;
+	priv->txbbgain_table[25].txbbgain_value=0x1a00006c;
+	priv->txbbgain_table[26].txbb_iq_amplifygain = 		     -14;
+	priv->txbbgain_table[26].txbbgain_value=0x1c800072;
+	priv->txbbgain_table[27].txbb_iq_amplifygain = 		     -15;
+	priv->txbbgain_table[27].txbbgain_value=0x18000060;
+	priv->txbbgain_table[28].txbb_iq_amplifygain = 		     -16;
+	priv->txbbgain_table[28].txbbgain_value=0x19800066;
+	priv->txbbgain_table[29].txbb_iq_amplifygain = 		     -17;
+	priv->txbbgain_table[29].txbbgain_value=0x15800056;
+	priv->txbbgain_table[30].txbb_iq_amplifygain = 		     -18;
+	priv->txbbgain_table[30].txbbgain_value=0x26c0005b;
+	priv->txbbgain_table[31].txbb_iq_amplifygain = 		     -19;
+	priv->txbbgain_table[31].txbbgain_value=0x14400051;
+	priv->txbbgain_table[32].txbb_iq_amplifygain = 		     -20;
+	priv->txbbgain_table[32].txbbgain_value=0x24400051;
+	priv->txbbgain_table[33].txbb_iq_amplifygain = 		     -21;
+	priv->txbbgain_table[33].txbbgain_value=0x1300004c;
+	priv->txbbgain_table[34].txbb_iq_amplifygain = 		     -22;
+	priv->txbbgain_table[34].txbbgain_value=0x12000048;
+	priv->txbbgain_table[35].txbb_iq_amplifygain = 		     -23;
+	priv->txbbgain_table[35].txbbgain_value=0x11000044;
+	priv->txbbgain_table[36].txbb_iq_amplifygain = 		     -24;
+	priv->txbbgain_table[36].txbbgain_value=0x10000040;
+
+	//ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
+	//This Table is for CH1~CH13
+	priv->cck_txbbgain_table[0].ccktxbb_valuearray[0] = 0x36;
+	priv->cck_txbbgain_table[0].ccktxbb_valuearray[1] = 0x35;
+	priv->cck_txbbgain_table[0].ccktxbb_valuearray[2] = 0x2e;
+	priv->cck_txbbgain_table[0].ccktxbb_valuearray[3] = 0x25;
+	priv->cck_txbbgain_table[0].ccktxbb_valuearray[4] = 0x1c;
+	priv->cck_txbbgain_table[0].ccktxbb_valuearray[5] = 0x12;
+	priv->cck_txbbgain_table[0].ccktxbb_valuearray[6] = 0x09;
+	priv->cck_txbbgain_table[0].ccktxbb_valuearray[7] = 0x04;
+
+	priv->cck_txbbgain_table[1].ccktxbb_valuearray[0] = 0x33;
+	priv->cck_txbbgain_table[1].ccktxbb_valuearray[1] = 0x32;
+	priv->cck_txbbgain_table[1].ccktxbb_valuearray[2] = 0x2b;
+	priv->cck_txbbgain_table[1].ccktxbb_valuearray[3] = 0x23;
+	priv->cck_txbbgain_table[1].ccktxbb_valuearray[4] = 0x1a;
+	priv->cck_txbbgain_table[1].ccktxbb_valuearray[5] = 0x11;
+	priv->cck_txbbgain_table[1].ccktxbb_valuearray[6] = 0x08;
+	priv->cck_txbbgain_table[1].ccktxbb_valuearray[7] = 0x04;
+
+	priv->cck_txbbgain_table[2].ccktxbb_valuearray[0] = 0x30;
+	priv->cck_txbbgain_table[2].ccktxbb_valuearray[1] = 0x2f;
+	priv->cck_txbbgain_table[2].ccktxbb_valuearray[2] = 0x29;
+	priv->cck_txbbgain_table[2].ccktxbb_valuearray[3] = 0x21;
+	priv->cck_txbbgain_table[2].ccktxbb_valuearray[4] = 0x19;
+	priv->cck_txbbgain_table[2].ccktxbb_valuearray[5] = 0x10;
+	priv->cck_txbbgain_table[2].ccktxbb_valuearray[6] = 0x08;
+	priv->cck_txbbgain_table[2].ccktxbb_valuearray[7] = 0x03;
+
+	priv->cck_txbbgain_table[3].ccktxbb_valuearray[0] = 0x2d;
+	priv->cck_txbbgain_table[3].ccktxbb_valuearray[1] = 0x2d;
+	priv->cck_txbbgain_table[3].ccktxbb_valuearray[2] = 0x27;
+	priv->cck_txbbgain_table[3].ccktxbb_valuearray[3] = 0x1f;
+	priv->cck_txbbgain_table[3].ccktxbb_valuearray[4] = 0x18;
+	priv->cck_txbbgain_table[3].ccktxbb_valuearray[5] = 0x0f;
+	priv->cck_txbbgain_table[3].ccktxbb_valuearray[6] = 0x08;
+	priv->cck_txbbgain_table[3].ccktxbb_valuearray[7] = 0x03;
+
+	priv->cck_txbbgain_table[4].ccktxbb_valuearray[0] = 0x2b;
+	priv->cck_txbbgain_table[4].ccktxbb_valuearray[1] = 0x2a;
+	priv->cck_txbbgain_table[4].ccktxbb_valuearray[2] = 0x25;
+	priv->cck_txbbgain_table[4].ccktxbb_valuearray[3] = 0x1e;
+	priv->cck_txbbgain_table[4].ccktxbb_valuearray[4] = 0x16;
+	priv->cck_txbbgain_table[4].ccktxbb_valuearray[5] = 0x0e;
+	priv->cck_txbbgain_table[4].ccktxbb_valuearray[6] = 0x07;
+	priv->cck_txbbgain_table[4].ccktxbb_valuearray[7] = 0x03;
+
+	priv->cck_txbbgain_table[5].ccktxbb_valuearray[0] = 0x28;
+	priv->cck_txbbgain_table[5].ccktxbb_valuearray[1] = 0x28;
+	priv->cck_txbbgain_table[5].ccktxbb_valuearray[2] = 0x22;
+	priv->cck_txbbgain_table[5].ccktxbb_valuearray[3] = 0x1c;
+	priv->cck_txbbgain_table[5].ccktxbb_valuearray[4] = 0x15;
+	priv->cck_txbbgain_table[5].ccktxbb_valuearray[5] = 0x0d;
+	priv->cck_txbbgain_table[5].ccktxbb_valuearray[6] = 0x07;
+	priv->cck_txbbgain_table[5].ccktxbb_valuearray[7] = 0x03;
+
+	priv->cck_txbbgain_table[6].ccktxbb_valuearray[0] = 0x26;
+	priv->cck_txbbgain_table[6].ccktxbb_valuearray[1] = 0x25;
+	priv->cck_txbbgain_table[6].ccktxbb_valuearray[2] = 0x21;
+	priv->cck_txbbgain_table[6].ccktxbb_valuearray[3] = 0x1b;
+	priv->cck_txbbgain_table[6].ccktxbb_valuearray[4] = 0x14;
+	priv->cck_txbbgain_table[6].ccktxbb_valuearray[5] = 0x0d;
+	priv->cck_txbbgain_table[6].ccktxbb_valuearray[6] = 0x06;
+	priv->cck_txbbgain_table[6].ccktxbb_valuearray[7] = 0x03;
+
+	priv->cck_txbbgain_table[7].ccktxbb_valuearray[0] = 0x24;
+	priv->cck_txbbgain_table[7].ccktxbb_valuearray[1] = 0x23;
+	priv->cck_txbbgain_table[7].ccktxbb_valuearray[2] = 0x1f;
+	priv->cck_txbbgain_table[7].ccktxbb_valuearray[3] = 0x19;
+	priv->cck_txbbgain_table[7].ccktxbb_valuearray[4] = 0x13;
+	priv->cck_txbbgain_table[7].ccktxbb_valuearray[5] = 0x0c;
+	priv->cck_txbbgain_table[7].ccktxbb_valuearray[6] = 0x06;
+	priv->cck_txbbgain_table[7].ccktxbb_valuearray[7] = 0x03;
+
+	priv->cck_txbbgain_table[8].ccktxbb_valuearray[0] = 0x22;
+	priv->cck_txbbgain_table[8].ccktxbb_valuearray[1] = 0x21;
+	priv->cck_txbbgain_table[8].ccktxbb_valuearray[2] = 0x1d;
+	priv->cck_txbbgain_table[8].ccktxbb_valuearray[3] = 0x18;
+	priv->cck_txbbgain_table[8].ccktxbb_valuearray[4] = 0x11;
+	priv->cck_txbbgain_table[8].ccktxbb_valuearray[5] = 0x0b;
+	priv->cck_txbbgain_table[8].ccktxbb_valuearray[6] = 0x06;
+	priv->cck_txbbgain_table[8].ccktxbb_valuearray[7] = 0x02;
+
+	priv->cck_txbbgain_table[9].ccktxbb_valuearray[0] = 0x20;
+	priv->cck_txbbgain_table[9].ccktxbb_valuearray[1] = 0x20;
+	priv->cck_txbbgain_table[9].ccktxbb_valuearray[2] = 0x1b;
+	priv->cck_txbbgain_table[9].ccktxbb_valuearray[3] = 0x16;
+	priv->cck_txbbgain_table[9].ccktxbb_valuearray[4] = 0x11;
+	priv->cck_txbbgain_table[9].ccktxbb_valuearray[5] = 0x08;
+	priv->cck_txbbgain_table[9].ccktxbb_valuearray[6] = 0x05;
+	priv->cck_txbbgain_table[9].ccktxbb_valuearray[7] = 0x02;
+
+	priv->cck_txbbgain_table[10].ccktxbb_valuearray[0] = 0x1f;
+	priv->cck_txbbgain_table[10].ccktxbb_valuearray[1] = 0x1e;
+	priv->cck_txbbgain_table[10].ccktxbb_valuearray[2] = 0x1a;
+	priv->cck_txbbgain_table[10].ccktxbb_valuearray[3] = 0x15;
+	priv->cck_txbbgain_table[10].ccktxbb_valuearray[4] = 0x10;
+	priv->cck_txbbgain_table[10].ccktxbb_valuearray[5] = 0x0a;
+	priv->cck_txbbgain_table[10].ccktxbb_valuearray[6] = 0x05;
+	priv->cck_txbbgain_table[10].ccktxbb_valuearray[7] = 0x02;
+
+	priv->cck_txbbgain_table[11].ccktxbb_valuearray[0] = 0x1d;
+	priv->cck_txbbgain_table[11].ccktxbb_valuearray[1] = 0x1c;
+	priv->cck_txbbgain_table[11].ccktxbb_valuearray[2] = 0x18;
+	priv->cck_txbbgain_table[11].ccktxbb_valuearray[3] = 0x14;
+	priv->cck_txbbgain_table[11].ccktxbb_valuearray[4] = 0x0f;
+	priv->cck_txbbgain_table[11].ccktxbb_valuearray[5] = 0x0a;
+	priv->cck_txbbgain_table[11].ccktxbb_valuearray[6] = 0x05;
+	priv->cck_txbbgain_table[11].ccktxbb_valuearray[7] = 0x02;
+
+	priv->cck_txbbgain_table[12].ccktxbb_valuearray[0] = 0x1b;
+	priv->cck_txbbgain_table[12].ccktxbb_valuearray[1] = 0x1a;
+	priv->cck_txbbgain_table[12].ccktxbb_valuearray[2] = 0x17;
+	priv->cck_txbbgain_table[12].ccktxbb_valuearray[3] = 0x13;
+	priv->cck_txbbgain_table[12].ccktxbb_valuearray[4] = 0x0e;
+	priv->cck_txbbgain_table[12].ccktxbb_valuearray[5] = 0x09;
+	priv->cck_txbbgain_table[12].ccktxbb_valuearray[6] = 0x04;
+	priv->cck_txbbgain_table[12].ccktxbb_valuearray[7] = 0x02;
+
+	priv->cck_txbbgain_table[13].ccktxbb_valuearray[0] = 0x1a;
+	priv->cck_txbbgain_table[13].ccktxbb_valuearray[1] = 0x19;
+	priv->cck_txbbgain_table[13].ccktxbb_valuearray[2] = 0x16;
+	priv->cck_txbbgain_table[13].ccktxbb_valuearray[3] = 0x12;
+	priv->cck_txbbgain_table[13].ccktxbb_valuearray[4] = 0x0d;
+	priv->cck_txbbgain_table[13].ccktxbb_valuearray[5] = 0x09;
+	priv->cck_txbbgain_table[13].ccktxbb_valuearray[6] = 0x04;
+	priv->cck_txbbgain_table[13].ccktxbb_valuearray[7] = 0x02;
+
+	priv->cck_txbbgain_table[14].ccktxbb_valuearray[0] = 0x18;
+	priv->cck_txbbgain_table[14].ccktxbb_valuearray[1] = 0x17;
+	priv->cck_txbbgain_table[14].ccktxbb_valuearray[2] = 0x15;
+	priv->cck_txbbgain_table[14].ccktxbb_valuearray[3] = 0x11;
+	priv->cck_txbbgain_table[14].ccktxbb_valuearray[4] = 0x0c;
+	priv->cck_txbbgain_table[14].ccktxbb_valuearray[5] = 0x08;
+	priv->cck_txbbgain_table[14].ccktxbb_valuearray[6] = 0x04;
+	priv->cck_txbbgain_table[14].ccktxbb_valuearray[7] = 0x02;
+
+	priv->cck_txbbgain_table[15].ccktxbb_valuearray[0] = 0x17;
+	priv->cck_txbbgain_table[15].ccktxbb_valuearray[1] = 0x16;
+	priv->cck_txbbgain_table[15].ccktxbb_valuearray[2] = 0x13;
+	priv->cck_txbbgain_table[15].ccktxbb_valuearray[3] = 0x10;
+	priv->cck_txbbgain_table[15].ccktxbb_valuearray[4] = 0x0c;
+	priv->cck_txbbgain_table[15].ccktxbb_valuearray[5] = 0x08;
+	priv->cck_txbbgain_table[15].ccktxbb_valuearray[6] = 0x04;
+	priv->cck_txbbgain_table[15].ccktxbb_valuearray[7] = 0x02;
+
+	priv->cck_txbbgain_table[16].ccktxbb_valuearray[0] = 0x16;
+	priv->cck_txbbgain_table[16].ccktxbb_valuearray[1] = 0x15;
+	priv->cck_txbbgain_table[16].ccktxbb_valuearray[2] = 0x12;
+	priv->cck_txbbgain_table[16].ccktxbb_valuearray[3] = 0x0f;
+	priv->cck_txbbgain_table[16].ccktxbb_valuearray[4] = 0x0b;
+	priv->cck_txbbgain_table[16].ccktxbb_valuearray[5] = 0x07;
+	priv->cck_txbbgain_table[16].ccktxbb_valuearray[6] = 0x04;
+	priv->cck_txbbgain_table[16].ccktxbb_valuearray[7] = 0x01;
+
+	priv->cck_txbbgain_table[17].ccktxbb_valuearray[0] = 0x14;
+	priv->cck_txbbgain_table[17].ccktxbb_valuearray[1] = 0x14;
+	priv->cck_txbbgain_table[17].ccktxbb_valuearray[2] = 0x11;
+	priv->cck_txbbgain_table[17].ccktxbb_valuearray[3] = 0x0e;
+	priv->cck_txbbgain_table[17].ccktxbb_valuearray[4] = 0x0b;
+	priv->cck_txbbgain_table[17].ccktxbb_valuearray[5] = 0x07;
+	priv->cck_txbbgain_table[17].ccktxbb_valuearray[6] = 0x03;
+	priv->cck_txbbgain_table[17].ccktxbb_valuearray[7] = 0x02;
+
+	priv->cck_txbbgain_table[18].ccktxbb_valuearray[0] = 0x13;
+	priv->cck_txbbgain_table[18].ccktxbb_valuearray[1] = 0x13;
+	priv->cck_txbbgain_table[18].ccktxbb_valuearray[2] = 0x10;
+	priv->cck_txbbgain_table[18].ccktxbb_valuearray[3] = 0x0d;
+	priv->cck_txbbgain_table[18].ccktxbb_valuearray[4] = 0x0a;
+	priv->cck_txbbgain_table[18].ccktxbb_valuearray[5] = 0x06;
+	priv->cck_txbbgain_table[18].ccktxbb_valuearray[6] = 0x03;
+	priv->cck_txbbgain_table[18].ccktxbb_valuearray[7] = 0x01;
+
+	priv->cck_txbbgain_table[19].ccktxbb_valuearray[0] = 0x12;
+	priv->cck_txbbgain_table[19].ccktxbb_valuearray[1] = 0x12;
+	priv->cck_txbbgain_table[19].ccktxbb_valuearray[2] = 0x0f;
+	priv->cck_txbbgain_table[19].ccktxbb_valuearray[3] = 0x0c;
+	priv->cck_txbbgain_table[19].ccktxbb_valuearray[4] = 0x09;
+	priv->cck_txbbgain_table[19].ccktxbb_valuearray[5] = 0x06;
+	priv->cck_txbbgain_table[19].ccktxbb_valuearray[6] = 0x03;
+	priv->cck_txbbgain_table[19].ccktxbb_valuearray[7] = 0x01;
+
+	priv->cck_txbbgain_table[20].ccktxbb_valuearray[0] = 0x11;
+	priv->cck_txbbgain_table[20].ccktxbb_valuearray[1] = 0x11;
+	priv->cck_txbbgain_table[20].ccktxbb_valuearray[2] = 0x0f;
+	priv->cck_txbbgain_table[20].ccktxbb_valuearray[3] = 0x0c;
+	priv->cck_txbbgain_table[20].ccktxbb_valuearray[4] = 0x09;
+	priv->cck_txbbgain_table[20].ccktxbb_valuearray[5] = 0x06;
+	priv->cck_txbbgain_table[20].ccktxbb_valuearray[6] = 0x03;
+	priv->cck_txbbgain_table[20].ccktxbb_valuearray[7] = 0x01;
+
+	priv->cck_txbbgain_table[21].ccktxbb_valuearray[0] = 0x10;
+	priv->cck_txbbgain_table[21].ccktxbb_valuearray[1] = 0x10;
+	priv->cck_txbbgain_table[21].ccktxbb_valuearray[2] = 0x0e;
+	priv->cck_txbbgain_table[21].ccktxbb_valuearray[3] = 0x0b;
+	priv->cck_txbbgain_table[21].ccktxbb_valuearray[4] = 0x08;
+	priv->cck_txbbgain_table[21].ccktxbb_valuearray[5] = 0x05;
+	priv->cck_txbbgain_table[21].ccktxbb_valuearray[6] = 0x03;
+	priv->cck_txbbgain_table[21].ccktxbb_valuearray[7] = 0x01;
+
+	priv->cck_txbbgain_table[22].ccktxbb_valuearray[0] = 0x0f;
+	priv->cck_txbbgain_table[22].ccktxbb_valuearray[1] = 0x0f;
+	priv->cck_txbbgain_table[22].ccktxbb_valuearray[2] = 0x0d;
+	priv->cck_txbbgain_table[22].ccktxbb_valuearray[3] = 0x0b;
+	priv->cck_txbbgain_table[22].ccktxbb_valuearray[4] = 0x08;
+	priv->cck_txbbgain_table[22].ccktxbb_valuearray[5] = 0x05;
+	priv->cck_txbbgain_table[22].ccktxbb_valuearray[6] = 0x03;
+	priv->cck_txbbgain_table[22].ccktxbb_valuearray[7] = 0x01;
+
+	//ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
+	//This Table is for CH14
+	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[0] = 0x36;
+	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[1] = 0x35;
+	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[2] = 0x2e;
+	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[3] = 0x1b;
+	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[0] = 0x33;
+	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[1] = 0x32;
+	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[2] = 0x2b;
+	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[3] = 0x19;
+	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[0] = 0x30;
+	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[1] = 0x2f;
+	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[2] = 0x29;
+	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[3] = 0x18;
+	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[0] = 0x2d;
+	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[1] = 0x2d;
+	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[2] = 0x27;
+	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[3] = 0x17;
+	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[0] = 0x2b;
+	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[1] = 0x2a;
+	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[2] = 0x25;
+	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[3] = 0x15;
+	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[0] = 0x28;
+	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[1] = 0x28;
+	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[2] = 0x22;
+	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[3] = 0x14;
+	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[0] = 0x26;
+	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[1] = 0x25;
+	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[2] = 0x21;
+	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[3] = 0x13;
+	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[0] = 0x24;
+	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[1] = 0x23;
+	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[2] = 0x1f;
+	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[3] = 0x12;
+	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[0] = 0x22;
+	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[1] = 0x21;
+	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[2] = 0x1d;
+	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[3] = 0x11;
+	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[0] = 0x20;
+	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[1] = 0x20;
+	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[2] = 0x1b;
+	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[3] = 0x10;
+	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[0] = 0x1f;
+	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[1] = 0x1e;
+	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[2] = 0x1a;
+	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[3] = 0x0f;
+	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[0] = 0x1d;
+	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[1] = 0x1c;
+	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[2] = 0x18;
+	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[3] = 0x0e;
+	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[0] = 0x1b;
+	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[1] = 0x1a;
+	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[2] = 0x17;
+	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[3] = 0x0e;
+	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[0] = 0x1a;
+	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[1] = 0x19;
+	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[2] = 0x16;
+	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[3] = 0x0d;
+	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[0] = 0x18;
+	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[1] = 0x17;
+	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[2] = 0x15;
+	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[3] = 0x0c;
+	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[0] = 0x17;
+	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[1] = 0x16;
+	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[2] = 0x13;
+	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[3] = 0x0b;
+	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[0] = 0x16;
+	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[1] = 0x15;
+	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[2] = 0x12;
+	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[3] = 0x0b;
+	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[0] = 0x14;
+	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[1] = 0x14;
+	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[2] = 0x11;
+	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[3] = 0x0a;
+	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[0] = 0x13;
+	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[1] = 0x13;
+	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[2] = 0x10;
+	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[3] = 0x0a;
+	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[0] = 0x12;
+	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[1] = 0x12;
+	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[2] = 0x0f;
+	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[3] = 0x09;
+	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[0] = 0x11;
+	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[1] = 0x11;
+	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[2] = 0x0f;
+	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[3] = 0x09;
+	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[0] = 0x10;
+	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[1] = 0x10;
+	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[2] = 0x0e;
+	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[3] = 0x08;
+	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[0] = 0x0f;
+	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[1] = 0x0f;
+	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[2] = 0x0d;
+	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[3] = 0x08;
+	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[7] = 0x00;
+
+	priv->btxpower_tracking = TRUE;
+	priv->txpower_count       = 0;
+	priv->btxpower_trackingInit = FALSE;
+
+}
+
+static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	// Tx Power tracking by Theremal Meter require Firmware R/W 3-wire. This mechanism
+	// can be enabled only when Firmware R/W 3-wire is enabled. Otherwise, frequent r/w
+	// 3-wire by driver cause RF goes into wrong state.
+	if(priv->ieee80211->FwRWRF)
+		priv->btxpower_tracking = TRUE;
+	else
+		priv->btxpower_tracking = FALSE;
+	priv->txpower_count       = 0;
+	priv->btxpower_trackingInit = FALSE;
+}
+
+
+void dm_initialize_txpower_tracking(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+#ifdef RTL8190P
+	dm_InitializeTXPowerTracking_TSSI(dev);
+#else
+	if(priv->bDcut == TRUE)
+		dm_InitializeTXPowerTracking_TSSI(dev);
+	else
+		dm_InitializeTXPowerTracking_ThermalMeter(dev);
+#endif
+}// dm_InitializeTXPowerTracking
+
+
+static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	static u32 tx_power_track_counter = 0;
+
+	if(!priv->btxpower_tracking)
+		return;
+	else
+	{
+		if((tx_power_track_counter % 30 == 0)&&(tx_power_track_counter != 0))
+		{
+				queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
+		}
+		tx_power_track_counter++;
+	}
+
+}
+
+
+static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	static u8 	TM_Trigger=0;
+	//DbgPrint("dm_CheckTXPowerTracking() \n");
+	if(!priv->btxpower_tracking)
+		return;
+	else
+	{
+		if(priv->txpower_count  <= 2)
+		{
+			priv->txpower_count++;
+			return;
+		}
+	}
+
+	if(!TM_Trigger)
+	{
+		//Attention!! You have to wirte all 12bits data to RF, or it may cause RF to crash
+		//actually write reg0x02 bit1=0, then bit1=1.
+		//DbgPrint("Trigger ThermalMeter, write RF reg0x2 = 0x4d to 0x4f\n");
+		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
+		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
+		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
+		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
+		TM_Trigger = 1;
+		return;
+	}
+	else
+	{
+		//DbgPrint("Schedule TxPowerTrackingWorkItem\n");
+			queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
+		TM_Trigger = 0;
+	}
+}
+
+
+static void dm_check_txpower_tracking(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	//static u32 tx_power_track_counter = 0;
+
+#ifdef  RTL8190P
+	dm_CheckTXPowerTracking_TSSI(dev);
+#else
+	if(priv->bDcut == TRUE)
+		dm_CheckTXPowerTracking_TSSI(dev);
+	else
+		dm_CheckTXPowerTracking_ThermalMeter(dev);
+#endif
+
+}	// dm_CheckTXPowerTracking
+
+
+static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool  bInCH14)
+{
+	u32 TempVal;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	//Write 0xa22 0xa23
+	TempVal = 0;
+	if(!bInCH14){
+		//Write 0xa22 0xa23
+		TempVal = 	priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[0] +
+					(priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[1]<<8) ;
+
+		rtl8192_setBBreg(dev, rCCK0_TxFilter1,bMaskHWord, TempVal);
+		//Write 0xa24 ~ 0xa27
+		TempVal = 0;
+		TempVal = 	priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[2] +
+					(priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[3]<<8) +
+					(priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[4]<<16 )+
+					(priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[5]<<24);
+		rtl8192_setBBreg(dev, rCCK0_TxFilter2,bMaskDWord, TempVal);
+		//Write 0xa28  0xa29
+		TempVal = 0;
+		TempVal = 	priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[6] +
+					(priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[7]<<8) ;
+
+		rtl8192_setBBreg(dev, rCCK0_DebugPort,bMaskLWord, TempVal);
+	}
+	else
+	{
+		TempVal = 	priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[0] +
+					(priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[1]<<8) ;
+
+		rtl8192_setBBreg(dev, rCCK0_TxFilter1,bMaskHWord, TempVal);
+		//Write 0xa24 ~ 0xa27
+		TempVal = 0;
+		TempVal = 	priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[2] +
+					(priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[3]<<8) +
+					(priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[4]<<16 )+
+					(priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[5]<<24);
+		rtl8192_setBBreg(dev, rCCK0_TxFilter2,bMaskDWord, TempVal);
+		//Write 0xa28  0xa29
+		TempVal = 0;
+		TempVal = 	priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[6] +
+					(priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[7]<<8) ;
+
+		rtl8192_setBBreg(dev, rCCK0_DebugPort,bMaskLWord, TempVal);
+	}
+
+
+}
+
+static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev,	bool  bInCH14)
+{
+	u32 TempVal;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	TempVal = 0;
+	if(!bInCH14)
+	{
+		//Write 0xa22 0xa23
+		TempVal = 	CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] +
+					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8) ;
+		rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
+		RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
+			rCCK0_TxFilter1, TempVal);
+		//Write 0xa24 ~ 0xa27
+		TempVal = 0;
+		TempVal = 	CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] +
+					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) +
+					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16 )+
+					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][5]<<24);
+		rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
+		RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
+			rCCK0_TxFilter2, TempVal);
+		//Write 0xa28  0xa29
+		TempVal = 0;
+		TempVal = 	CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] +
+					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8) ;
+
+		rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
+		RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
+			rCCK0_DebugPort, TempVal);
+	}
+	else
+	{
+//		priv->CCKTxPowerAdjustCntNotCh14++;	//cosa add for debug.
+		//Write 0xa22 0xa23
+		TempVal = 	CCKSwingTable_Ch14[priv->CCK_index][0] +
+					(CCKSwingTable_Ch14[priv->CCK_index][1]<<8) ;
+
+		rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
+		RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
+			rCCK0_TxFilter1, TempVal);
+		//Write 0xa24 ~ 0xa27
+		TempVal = 0;
+		TempVal = 	CCKSwingTable_Ch14[priv->CCK_index][2] +
+					(CCKSwingTable_Ch14[priv->CCK_index][3]<<8) +
+					(CCKSwingTable_Ch14[priv->CCK_index][4]<<16 )+
+					(CCKSwingTable_Ch14[priv->CCK_index][5]<<24);
+		rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
+		RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
+			rCCK0_TxFilter2, TempVal);
+		//Write 0xa28  0xa29
+		TempVal = 0;
+		TempVal = 	CCKSwingTable_Ch14[priv->CCK_index][6] +
+					(CCKSwingTable_Ch14[priv->CCK_index][7]<<8) ;
+
+		rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
+		RT_TRACE(COMP_POWER_TRACKING,"CCK chnl 14, reg 0x%x = 0x%x\n",
+			rCCK0_DebugPort, TempVal);
+	}
+}
+
+
+
+extern void dm_cck_txpower_adjust(
+	struct net_device *dev,
+	bool  binch14
+)
+{	// dm_CCKTxPowerAdjust
+
+	struct r8192_priv *priv = ieee80211_priv(dev);
+#ifdef RTL8190P
+	dm_CCKTxPowerAdjust_TSSI(dev, binch14);
+#else
+	if(priv->bDcut == TRUE)
+		dm_CCKTxPowerAdjust_TSSI(dev, binch14);
+	else
+		dm_CCKTxPowerAdjust_ThermalMeter(dev, binch14);
+#endif
+}
+
+
+#ifndef  RTL8192U
+static void dm_txpower_reset_recovery(
+	struct net_device *dev
+)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	RT_TRACE(COMP_POWER_TRACKING, "Start Reset Recovery ==>\n");
+	rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
+	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc80 is %08x\n",priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
+	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFA_txPowerTrackingIndex is %x\n",priv->rfa_txpowertrackingindex);
+	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF A I/Q Amplify Gain is %ld\n",priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbb_iq_amplifygain);
+	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: CCK Attenuation is %d dB\n",priv->cck_present_attentuation);
+	dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
+
+	rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
+	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc90 is %08x\n",priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
+	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n",priv->rfc_txpowertrackingindex);
+	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF C I/Q Amplify Gain is %ld\n",priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbb_iq_amplifygain);
+
+}	// dm_TXPowerResetRecovery
+
+extern void dm_restore_dynamic_mechanism_state(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32 	reg_ratr = priv->rate_adaptive.last_ratr;
+
+	if(!priv->up)
+	{
+		RT_TRACE(COMP_RATE, "<---- dm_restore_dynamic_mechanism_state(): driver is going to unload\n");
+		return;
+	}
+
+	//
+	// Restore previous state for rate adaptive
+	//
+	if(priv->rate_adaptive.rate_adaptive_disabled)
+		return;
+	// TODO: Only 11n mode is implemented currently,
+	if( !(priv->ieee80211->mode==WIRELESS_MODE_N_24G ||
+		 priv->ieee80211->mode==WIRELESS_MODE_N_5G))
+		 return;
+	{
+			/* 2007/11/15 MH Copy from 8190PCI. */
+			u32 ratr_value;
+			ratr_value = reg_ratr;
+			if(priv->rf_type == RF_1T2R)	// 1T2R, Spatial Stream 2 should be disabled
+			{
+				ratr_value &=~ (RATE_ALL_OFDM_2SS);
+				//DbgPrint("HW_VAR_TATR_0 from 0x%x ==> 0x%x\n", ((pu4Byte)(val))[0], ratr_value);
+			}
+			//DbgPrint("set HW_VAR_TATR_0 = 0x%x\n", ratr_value);
+			//cosa PlatformEFIOWrite4Byte(Adapter, RATR0, ((pu4Byte)(val))[0]);
+			write_nic_dword(dev, RATR0, ratr_value);
+			write_nic_byte(dev, UFWP, 1);
+	}
+	//Resore TX Power Tracking Index
+	if(priv->btxpower_trackingInit && priv->btxpower_tracking){
+		dm_txpower_reset_recovery(dev);
+	}
+
+	//
+	//Restore BB Initial Gain
+	//
+	dm_bb_initialgain_restore(dev);
+
+}	// DM_RestoreDynamicMechanismState
+
+static void dm_bb_initialgain_restore(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32 bit_mask = 0x7f; //Bit0~ Bit6
+
+	if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
+		return;
+
+	//Disable Initial Gain
+	//PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800);
+	rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	// Only clear byte 1 and rewrite.
+	rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bit_mask, (u32)priv->initgain_backup.xaagccore1);
+	rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bit_mask, (u32)priv->initgain_backup.xbagccore1);
+	rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bit_mask, (u32)priv->initgain_backup.xcagccore1);
+	rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, bit_mask, (u32)priv->initgain_backup.xdagccore1);
+	bit_mask  = bMaskByte2;
+	rtl8192_setBBreg(dev, rCCK0_CCA, bit_mask, (u32)priv->initgain_backup.cca);
+
+	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
+	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
+	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
+	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
+	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n",priv->initgain_backup.cca);
+	//Enable Initial Gain
+	//PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x100);
+	rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);	// Only clear byte 1 and rewrite.
+
+}	// dm_BBInitialGainRestore
+
+
+extern void dm_backup_dynamic_mechanism_state(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	// Fsync to avoid reset
+	priv->bswitch_fsync  = false;
+	priv->bfsync_processing = false;
+	//Backup BB InitialGain
+	dm_bb_initialgain_backup(dev);
+
+}	// DM_BackupDynamicMechanismState
+
+
+static void dm_bb_initialgain_backup(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32 bit_mask = bMaskByte0; //Bit0~ Bit6
+
+	if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
+		return;
+
+	//PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800);
+	rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	// Only clear byte 1 and rewrite.
+	priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bit_mask);
+	priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bit_mask);
+	priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bit_mask);
+	priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, bit_mask);
+	bit_mask  = bMaskByte2;
+	priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, bit_mask);
+
+	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
+	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
+	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
+	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
+	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n",priv->initgain_backup.cca);
+
+}   // dm_BBInitialGainBakcup
+
+#endif
+/*-----------------------------------------------------------------------------
+ * Function:	dm_change_dynamic_initgain_thresh()
+ *
+ * Overview:
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/29/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+extern void dm_change_dynamic_initgain_thresh(struct net_device *dev,
+								u32		dm_type,
+								u32		dm_value)
+{
+	if (dm_type == DIG_TYPE_THRESH_HIGH)
+	{
+		dm_digtable.rssi_high_thresh = dm_value;
+	}
+	else if (dm_type == DIG_TYPE_THRESH_LOW)
+	{
+		dm_digtable.rssi_low_thresh = dm_value;
+	}
+	else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH)
+	{
+		dm_digtable.rssi_high_power_highthresh = dm_value;
+	}
+	else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH)
+	{
+		dm_digtable.rssi_high_power_highthresh = dm_value;
+	}
+	else if (dm_type == DIG_TYPE_ENABLE)
+	{
+		dm_digtable.dig_state		= DM_STA_DIG_MAX;
+		dm_digtable.dig_enable_flag	= true;
+	}
+	else if (dm_type == DIG_TYPE_DISABLE)
+	{
+		dm_digtable.dig_state		= DM_STA_DIG_MAX;
+		dm_digtable.dig_enable_flag	= false;
+	}
+	else if (dm_type == DIG_TYPE_DBG_MODE)
+	{
+		if(dm_value >= DM_DBG_MAX)
+			dm_value = DM_DBG_OFF;
+		dm_digtable.dbg_mode		= (u8)dm_value;
+	}
+	else if (dm_type == DIG_TYPE_RSSI)
+	{
+		if(dm_value > 100)
+			dm_value = 30;
+		dm_digtable.rssi_val			= (long)dm_value;
+	}
+	else if (dm_type == DIG_TYPE_ALGORITHM)
+	{
+		if (dm_value >= DIG_ALGO_MAX)
+			dm_value = DIG_ALGO_BY_FALSE_ALARM;
+		if(dm_digtable.dig_algorithm != (u8)dm_value)
+			dm_digtable.dig_algorithm_switch = 1;
+		dm_digtable.dig_algorithm	= (u8)dm_value;
+	}
+	else if (dm_type == DIG_TYPE_BACKOFF)
+	{
+		if(dm_value > 30)
+			dm_value = 30;
+		dm_digtable.backoff_val		= (u8)dm_value;
+	}
+	else if(dm_type == DIG_TYPE_RX_GAIN_MIN)
+	{
+		if(dm_value == 0)
+			dm_value = 0x1;
+		dm_digtable.rx_gain_range_min = (u8)dm_value;
+	}
+	else if(dm_type == DIG_TYPE_RX_GAIN_MAX)
+	{
+		if(dm_value > 0x50)
+			dm_value = 0x50;
+		dm_digtable.rx_gain_range_max = (u8)dm_value;
+	}
+}	/* DM_ChangeDynamicInitGainThresh */
+extern	void
+dm_change_fsync_setting(
+	struct net_device *dev,
+	s32		DM_Type,
+	s32		DM_Value)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	if (DM_Type == 0)	// monitor 0xc38 register
+	{
+		if(DM_Value > 1)
+			DM_Value = 1;
+		priv->framesyncMonitor = (u8)DM_Value;
+		//DbgPrint("pHalData->framesyncMonitor = %d", pHalData->framesyncMonitor);
+	}
+}
+
+extern void
+dm_change_rxpath_selection_setting(
+	struct net_device *dev,
+	s32		DM_Type,
+	s32		DM_Value)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	prate_adaptive 	pRA = (prate_adaptive)&(priv->rate_adaptive);
+
+
+	if(DM_Type == 0)
+	{
+		if(DM_Value > 1)
+			DM_Value = 1;
+		DM_RxPathSelTable.Enable = (u8)DM_Value;
+	}
+	else if(DM_Type == 1)
+	{
+		if(DM_Value > 1)
+			DM_Value = 1;
+		DM_RxPathSelTable.DbgMode = (u8)DM_Value;
+	}
+	else if(DM_Type == 2)
+	{
+		if(DM_Value > 40)
+			DM_Value = 40;
+		DM_RxPathSelTable.SS_TH_low = (u8)DM_Value;
+	}
+	else if(DM_Type == 3)
+	{
+		if(DM_Value > 25)
+			DM_Value = 25;
+		DM_RxPathSelTable.diff_TH = (u8)DM_Value;
+	}
+	else if(DM_Type == 4)
+	{
+		if(DM_Value >= CCK_Rx_Version_MAX)
+			DM_Value = CCK_Rx_Version_1;
+		DM_RxPathSelTable.cck_method= (u8)DM_Value;
+	}
+	else if(DM_Type == 10)
+	{
+		if(DM_Value > 100)
+			DM_Value = 50;
+		DM_RxPathSelTable.rf_rssi[0] = (u8)DM_Value;
+	}
+	else if(DM_Type == 11)
+	{
+		if(DM_Value > 100)
+			DM_Value = 50;
+		DM_RxPathSelTable.rf_rssi[1] = (u8)DM_Value;
+	}
+	else if(DM_Type == 12)
+	{
+		if(DM_Value > 100)
+			DM_Value = 50;
+		DM_RxPathSelTable.rf_rssi[2] = (u8)DM_Value;
+	}
+	else if(DM_Type == 13)
+	{
+		if(DM_Value > 100)
+			DM_Value = 50;
+		DM_RxPathSelTable.rf_rssi[3] = (u8)DM_Value;
+	}
+	else if(DM_Type == 20)
+	{
+		if(DM_Value > 1)
+			DM_Value = 1;
+		pRA->ping_rssi_enable = (u8)DM_Value;
+	}
+	else if(DM_Type == 21)
+	{
+		if(DM_Value > 30)
+			DM_Value = 30;
+		pRA->ping_rssi_thresh_for_ra = DM_Value;
+	}
+}
+
+
+/*-----------------------------------------------------------------------------
+ * Function:	dm_dig_init()
+ *
+ * Overview:	Set DIG scheme init value.
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/15/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static void dm_dig_init(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	/* 2007/10/05 MH Disable DIG scheme now. Not tested. */
+	dm_digtable.dig_enable_flag	= true;
+	dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI;
+	dm_digtable.dbg_mode = DM_DBG_OFF;	//off=by real rssi value, on=by DM_DigTable.Rssi_val for new dig
+	dm_digtable.dig_algorithm_switch = 0;
+
+	/* 2007/10/04 MH Define init gain threshol. */
+	dm_digtable.dig_state		= DM_STA_DIG_MAX;
+	dm_digtable.dig_highpwr_state	= DM_STA_DIG_MAX;
+	dm_digtable.initialgain_lowerbound_state = false;
+
+	dm_digtable.rssi_low_thresh 	= DM_DIG_THRESH_LOW;
+	dm_digtable.rssi_high_thresh 	= DM_DIG_THRESH_HIGH;
+
+	dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
+	dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
+
+	dm_digtable.rssi_val = 50;	//for new dig debug rssi value
+	dm_digtable.backoff_val = DM_DIG_BACKOFF;
+	dm_digtable.rx_gain_range_max = DM_DIG_MAX;
+	if(priv->CustomerID == RT_CID_819x_Netcore)
+		dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore;
+	else
+		dm_digtable.rx_gain_range_min = DM_DIG_MIN;
+
+}	/* dm_dig_init */
+
+
+/*-----------------------------------------------------------------------------
+ * Function:	dm_ctrl_initgain_byrssi()
+ *
+ * Overview:	Driver must monitor RSSI and notify firmware to change initial
+ *				gain according to different threshold. BB team provide the
+ *				suggested solution.
+ *
+ * Input:			struct net_device *dev
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/27/2008	amy		Create Version 0 porting from windows code.
+ *---------------------------------------------------------------------------*/
+static void dm_ctrl_initgain_byrssi(struct net_device *dev)
+{
+
+	if (dm_digtable.dig_enable_flag == false)
+		return;
+
+	if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
+		dm_ctrl_initgain_byrssi_by_fwfalse_alarm(dev);
+	else if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
+		dm_ctrl_initgain_byrssi_by_driverrssi(dev);
+//		;
+	else
+		return;
+}
+
+
+static void dm_ctrl_initgain_byrssi_by_driverrssi(
+	struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 i;
+	static u8 	fw_dig=0;
+
+	if (dm_digtable.dig_enable_flag == false)
+		return;
+
+	//DbgPrint("Dig by Sw Rssi \n");
+	if(dm_digtable.dig_algorithm_switch)	// if swithed algorithm, we have to disable FW Dig.
+		fw_dig = 0;
+	if(fw_dig <= 3)	// execute several times to make sure the FW Dig is disabled
+	{// FW DIG Off
+		for(i=0; i<3; i++)
+			rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	// Only clear byte 1 and rewrite.
+		fw_dig++;
+		dm_digtable.dig_state = DM_STA_DIG_OFF;	//fw dig off.
+	}
+
+	if(priv->ieee80211->state == IEEE80211_LINKED)
+		dm_digtable.cur_connect_state = DIG_CONNECT;
+	else
+		dm_digtable.cur_connect_state = DIG_DISCONNECT;
+
+	//DbgPrint("DM_DigTable.PreConnectState = %d, DM_DigTable.CurConnectState = %d \n",
+		//DM_DigTable.PreConnectState, DM_DigTable.CurConnectState);
+
+	if(dm_digtable.dbg_mode == DM_DBG_OFF)
+		dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb;
+	//DbgPrint("DM_DigTable.Rssi_val = %d \n", DM_DigTable.Rssi_val);
+	dm_initial_gain(dev);
+	dm_pd_th(dev);
+	dm_cs_ratio(dev);
+	if(dm_digtable.dig_algorithm_switch)
+		dm_digtable.dig_algorithm_switch = 0;
+	dm_digtable.pre_connect_state = dm_digtable.cur_connect_state;
+
+}	/* dm_CtrlInitGainByRssi */
+
+static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
+	struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	static u32 reset_cnt = 0;
+	u8 i;
+
+	if (dm_digtable.dig_enable_flag == false)
+		return;
+
+	if(dm_digtable.dig_algorithm_switch)
+	{
+		dm_digtable.dig_state = DM_STA_DIG_MAX;
+		// Fw DIG On.
+		for(i=0; i<3; i++)
+			rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);	// Only clear byte 1 and rewrite.
+		dm_digtable.dig_algorithm_switch = 0;
+	}
+
+	if (priv->ieee80211->state != IEEE80211_LINKED)
+		return;
+
+	// For smooth, we can not change DIG state.
+	if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) &&
+		(priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh))
+	{
+		return;
+	}
+	//DbgPrint("Dig by Fw False Alarm\n");
+	//if (DM_DigTable.Dig_State == DM_STA_DIG_OFF)
+	/*DbgPrint("DIG Check\n\r RSSI=%d LOW=%d HIGH=%d STATE=%d",
+	pHalData->UndecoratedSmoothedPWDB, DM_DigTable.RssiLowThresh,
+	DM_DigTable.RssiHighThresh, DM_DigTable.Dig_State);*/
+	/* 1. When RSSI decrease, We have to judge if it is smaller than a treshold
+		  and then execute below step. */
+	if ((priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh))
+	{
+		/* 2008/02/05 MH When we execute silent reset, the DIG PHY parameters
+		   will be reset to init value. We must prevent the condition. */
+		if (dm_digtable.dig_state == DM_STA_DIG_OFF &&
+			(priv->reset_count == reset_cnt))
+		{
+			return;
+		}
+		else
+		{
+			reset_cnt = priv->reset_count;
+		}
+
+		// If DIG is off, DIG high power state must reset.
+		dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
+		dm_digtable.dig_state = DM_STA_DIG_OFF;
+
+		// 1.1 DIG Off.
+		rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	// Only clear byte 1 and rewrite.
+
+		// 1.2 Set initial gain.
+		write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x17);
+		write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x17);
+		write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x17);
+		write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x17);
+
+		// 1.3 Lower PD_TH for OFDM.
+		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
+		{
+			/* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
+			// 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
+			#ifdef RTL8190P
+				write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
+			#else
+				write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
+			#endif
+			/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
+				write_nic_byte(pAdapter, rOFDM0_RxDetector1, 0x40);
+			*/
+			//else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
+
+
+			//else
+				//PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x40);
+		}
+		else
+			write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
+
+		// 1.4 Lower CS ratio for CCK.
+		write_nic_byte(dev, 0xa0a, 0x08);
+
+		// 1.5 Higher EDCCA.
+		//PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x325);
+		return;
+
+	}
+
+	/* 2. When RSSI increase, We have to judge if it is larger than a treshold
+		  and then execute below step.  */
+	if ((priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) )
+	{
+		u8 reset_flag = 0;
+
+		if (dm_digtable.dig_state == DM_STA_DIG_ON &&
+			(priv->reset_count == reset_cnt))
+		{
+			dm_ctrl_initgain_byrssi_highpwr(dev);
+			return;
+		}
+		else
+		{
+			if (priv->reset_count != reset_cnt)
+				reset_flag = 1;
+
+			reset_cnt = priv->reset_count;
+		}
+
+		dm_digtable.dig_state = DM_STA_DIG_ON;
+		//DbgPrint("DIG ON\n\r");
+
+		// 2.1 Set initial gain.
+		// 2008/02/26 MH SD3-Jerry suggest to prevent dirty environment.
+		if (reset_flag == 1)
+		{
+			write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x2c);
+			write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x2c);
+			write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x2c);
+			write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x2c);
+		}
+		else
+		{
+			write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x20);
+			write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x20);
+			write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x20);
+			write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x20);
+		}
+
+		// 2.2 Higher PD_TH for OFDM.
+		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
+		{
+			/* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
+			// 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
+			#ifdef RTL8190P
+				write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
+			#else
+				write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
+			#endif
+			/*
+			else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
+				write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
+			*/
+			//else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
+
+			//else
+				//PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x42);
+		}
+		else
+			write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
+
+		// 2.3 Higher CS ratio for CCK.
+		write_nic_byte(dev, 0xa0a, 0xcd);
+
+		// 2.4 Lower EDCCA.
+		/* 2008/01/11 MH 90/92 series are the same. */
+		//PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x346);
+
+		// 2.5 DIG On.
+		rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);	// Only clear byte 1 and rewrite.
+
+	}
+
+	dm_ctrl_initgain_byrssi_highpwr(dev);
+
+}	/* dm_CtrlInitGainByRssi */
+
+
+/*-----------------------------------------------------------------------------
+ * Function:	dm_ctrl_initgain_byrssi_highpwr()
+ *
+ * Overview:
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/28/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static void dm_ctrl_initgain_byrssi_highpwr(
+	struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	static u32 reset_cnt_highpwr = 0;
+
+	// For smooth, we can not change high power DIG state in the range.
+	if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_high_power_lowthresh) &&
+		(priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_highthresh))
+	{
+		return;
+	}
+
+	/* 3. When RSSI >75% or <70%, it is a high power issue. We have to judge if
+		  it is larger than a treshold and then execute below step.  */
+	// 2008/02/05 MH SD3-Jerry Modify PD_TH for high power issue.
+	if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh)
+	{
+		if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON &&
+			(priv->reset_count == reset_cnt_highpwr))
+			return;
+		else
+			dm_digtable.dig_highpwr_state = DM_STA_DIG_ON;
+
+		// 3.1 Higher PD_TH for OFDM for high power state.
+		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
+		{
+			#ifdef RTL8190P
+				write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
+			#else
+				write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
+			#endif
+
+			/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
+				write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
+			*/
+
+		}
+		else
+			write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
+	}
+	else
+	{
+		if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF&&
+			(priv->reset_count == reset_cnt_highpwr))
+			return;
+		else
+			dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF;
+
+		if (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_lowthresh &&
+			 priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh)
+		{
+			// 3.2 Recover PD_TH for OFDM for normal power region.
+			if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
+			{
+				#ifdef RTL8190P
+					write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
+				#else
+					write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
+				#endif
+				/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
+					write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
+				*/
+
+			}
+			else
+				write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
+		}
+	}
+
+	reset_cnt_highpwr = priv->reset_count;
+
+}	/* dm_CtrlInitGainByRssiHighPwr */
+
+
+static void dm_initial_gain(
+	struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8					initial_gain=0;
+	static u8				initialized=0, force_write=0;
+	static u32			reset_cnt=0;
+
+	if(dm_digtable.dig_algorithm_switch)
+	{
+		initialized = 0;
+		reset_cnt = 0;
+	}
+
+	if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
+	{
+		if(dm_digtable.cur_connect_state == DIG_CONNECT)
+		{
+			if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) > dm_digtable.rx_gain_range_max)
+				dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_max;
+			else if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min)
+				dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_min;
+			else
+				dm_digtable.cur_ig_value = dm_digtable.rssi_val+10-dm_digtable.backoff_val;
+		}
+		else		//current state is disconnected
+		{
+			if(dm_digtable.cur_ig_value == 0)
+				dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
+			else
+				dm_digtable.cur_ig_value = dm_digtable.pre_ig_value;
+		}
+	}
+	else	// disconnected -> connected or connected -> disconnected
+	{
+		dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
+		dm_digtable.pre_ig_value = 0;
+	}
+	//DbgPrint("DM_DigTable.CurIGValue = 0x%x, DM_DigTable.PreIGValue = 0x%x\n", DM_DigTable.CurIGValue, DM_DigTable.PreIGValue);
+
+	// if silent reset happened, we should rewrite the values back
+	if(priv->reset_count != reset_cnt)
+	{
+		force_write = 1;
+		reset_cnt = priv->reset_count;
+	}
+
+	if(dm_digtable.pre_ig_value != read_nic_byte(dev, rOFDM0_XAAGCCore1))
+		force_write = 1;
+
+	{
+		if((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
+			|| !initialized || force_write)
+		{
+			initial_gain = (u8)dm_digtable.cur_ig_value;
+			//DbgPrint("Write initial gain = 0x%x\n", initial_gain);
+			// Set initial gain.
+			write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
+			write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
+			write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
+			write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain);
+			dm_digtable.pre_ig_value = dm_digtable.cur_ig_value;
+			initialized = 1;
+			force_write = 0;
+		}
+	}
+}
+
+static void dm_pd_th(
+	struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	static u8				initialized=0, force_write=0;
+	static u32			reset_cnt = 0;
+
+	if(dm_digtable.dig_algorithm_switch)
+	{
+		initialized = 0;
+		reset_cnt = 0;
+	}
+
+	if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
+	{
+		if(dm_digtable.cur_connect_state == DIG_CONNECT)
+		{
+			if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh)
+				dm_digtable.curpd_thstate = DIG_PD_AT_HIGH_POWER;
+			else if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
+				dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
+			else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) &&
+					(dm_digtable.rssi_val < dm_digtable.rssi_high_power_lowthresh))
+				dm_digtable.curpd_thstate = DIG_PD_AT_NORMAL_POWER;
+			else
+				dm_digtable.curpd_thstate = dm_digtable.prepd_thstate;
+		}
+		else
+		{
+			dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
+		}
+	}
+	else	// disconnected -> connected or connected -> disconnected
+	{
+		dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
+	}
+
+	// if silent reset happened, we should rewrite the values back
+	if(priv->reset_count != reset_cnt)
+	{
+		force_write = 1;
+		reset_cnt = priv->reset_count;
+	}
+
+	{
+		if((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
+			(initialized<=3) || force_write)
+		{
+			//DbgPrint("Write PD_TH state = %d\n", DM_DigTable.CurPD_THState);
+			if(dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER)
+			{
+				// Lower PD_TH for OFDM.
+				if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
+				{
+					/* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
+					// 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
+					#ifdef RTL8190P
+						write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
+					#else
+						write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
+					#endif
+					/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
+						write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
+					*/
+				}
+				else
+					write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
+			}
+			else if(dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER)
+			{
+				// Higher PD_TH for OFDM.
+				if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
+				{
+					/* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
+					// 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
+					#ifdef RTL8190P
+						write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
+					#else
+						write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
+					#endif
+					/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
+						write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
+					*/
+				}
+				else
+					write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
+			}
+			else if(dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER)
+			{
+				// Higher PD_TH for OFDM for high power state.
+				if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
+				{
+					#ifdef RTL8190P
+						write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
+					#else
+						write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
+					#endif
+					/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
+						write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
+					*/
+				}
+				else
+					write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
+			}
+			dm_digtable.prepd_thstate = dm_digtable.curpd_thstate;
+			if(initialized <= 3)
+				initialized++;
+			force_write = 0;
+		}
+	}
+}
+
+static	void dm_cs_ratio(
+	struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	static u8				initialized=0,force_write=0;
+	static u32			reset_cnt = 0;
+
+	if(dm_digtable.dig_algorithm_switch)
+	{
+		initialized = 0;
+		reset_cnt = 0;
+	}
+
+	if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
+	{
+		if(dm_digtable.cur_connect_state == DIG_CONNECT)
+		{
+			if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
+				dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
+			else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) )
+				dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER;
+			else
+				dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state;
+		}
+		else
+		{
+			dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
+		}
+	}
+	else	// disconnected -> connected or connected -> disconnected
+	{
+		dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
+	}
+
+	// if silent reset happened, we should rewrite the values back
+	if(priv->reset_count != reset_cnt)
+	{
+		force_write = 1;
+		reset_cnt = priv->reset_count;
+	}
+
+
+	{
+		if((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
+			!initialized || force_write)
+		{
+			//DbgPrint("Write CS_ratio state = %d\n", DM_DigTable.CurCS_ratioState);
+			if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER)
+			{
+				// Lower CS ratio for CCK.
+				write_nic_byte(dev, 0xa0a, 0x08);
+			}
+			else if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER)
+			{
+				// Higher CS ratio for CCK.
+				write_nic_byte(dev, 0xa0a, 0xcd);
+			}
+			dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
+			initialized = 1;
+			force_write = 0;
+		}
+	}
+}
+
+extern void dm_init_edca_turbo(struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	priv->bcurrent_turbo_EDCA = false;
+	priv->ieee80211->bis_any_nonbepkts = false;
+	priv->bis_cur_rdlstate = false;
+}	// dm_init_edca_turbo
+
+static void dm_check_edca_turbo(
+	struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
+	//PSTA_QOS			pStaQos = pMgntInfo->pStaQos;
+
+	// Keep past Tx/Rx packet count for RT-to-RT EDCA turbo.
+	static unsigned long			lastTxOkCnt = 0;
+	static unsigned long			lastRxOkCnt = 0;
+	unsigned long				curTxOkCnt = 0;
+	unsigned long				curRxOkCnt = 0;
+
+	//
+	// Do not be Turbo if it's under WiFi config and Qos Enabled, because the EDCA parameters
+	// should follow the settings from QAP. By Bruce, 2007-12-07.
+	//
+	if(priv->ieee80211->state != IEEE80211_LINKED)
+		goto dm_CheckEdcaTurbo_EXIT;
+	// We do not turn on EDCA turbo mode for some AP that has IOT issue
+	if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO)
+		goto dm_CheckEdcaTurbo_EXIT;
+
+//	printk("========>%s():bis_any_nonbepkts is %d\n",__FUNCTION__,priv->bis_any_nonbepkts);
+	// Check the status for current condition.
+	if(!priv->ieee80211->bis_any_nonbepkts)
+	{
+		curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
+		curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
+		// For RT-AP, we needs to turn it on when Rx>Tx
+		if(curRxOkCnt > 4*curTxOkCnt)
+		{
+			//printk("%s():curRxOkCnt > 4*curTxOkCnt\n");
+			if(!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
+			{
+				write_nic_dword(dev, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]);
+				priv->bis_cur_rdlstate = true;
+			}
+		}
+		else
+		{
+
+			//printk("%s():curRxOkCnt < 4*curTxOkCnt\n");
+			if(priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
+			{
+				write_nic_dword(dev, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]);
+				priv->bis_cur_rdlstate = false;
+			}
+
+		}
+
+		priv->bcurrent_turbo_EDCA = true;
+	}
+	else
+	{
+		//
+		// Turn Off EDCA turbo here.
+		// Restore original EDCA according to the declaration of AP.
+		//
+		 if(priv->bcurrent_turbo_EDCA)
+		{
+
+			{
+				u8		u1bAIFS;
+				u32		u4bAcParam;
+				struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
+				u8 mode = priv->ieee80211->mode;
+
+			// For Each time updating EDCA parameter, reset EDCA turbo mode status.
+				dm_init_edca_turbo(dev);
+				u1bAIFS = qos_parameters->aifs[0] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
+				u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[0]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
+					(((u32)(qos_parameters->cw_max[0]))<< AC_PARAM_ECW_MAX_OFFSET)|
+					(((u32)(qos_parameters->cw_min[0]))<< AC_PARAM_ECW_MIN_OFFSET)|
+					((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
+			//write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
+				write_nic_dword(dev, EDCAPARA_BE,  u4bAcParam);
+
+			// Check ACM bit.
+			// If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
+				{
+			// TODO:  Modified this part and try to set acm control in only 1 IO processing!!
+
+					PACI_AIFSN	pAciAifsn = (PACI_AIFSN)&(qos_parameters->aifs[0]);
+					u8		AcmCtrl = read_nic_byte( dev, AcmHwCtrl );
+					if( pAciAifsn->f.ACM )
+					{ // ACM bit is 1.
+						AcmCtrl |= AcmHw_BeqEn;
+					}
+					else
+					{ // ACM bit is 0.
+						AcmCtrl &= (~AcmHw_BeqEn);
+					}
+
+					RT_TRACE( COMP_QOS,"SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl ) ;
+					write_nic_byte(dev, AcmHwCtrl, AcmCtrl );
+				}
+			}
+			priv->bcurrent_turbo_EDCA = false;
+		}
+	}
+
+
+dm_CheckEdcaTurbo_EXIT:
+	// Set variables for next time.
+	priv->ieee80211->bis_any_nonbepkts = false;
+	lastTxOkCnt = priv->stats.txbytesunicast;
+	lastRxOkCnt = priv->stats.rxbytesunicast;
+}	// dm_CheckEdcaTurbo
+
+extern void DM_CTSToSelfSetting(struct net_device * dev,u32 DM_Type, u32 DM_Value)
+{
+	struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
+
+	if (DM_Type == 0)	// CTS to self disable/enable
+	{
+		if(DM_Value > 1)
+			DM_Value = 1;
+		priv->ieee80211->bCTSToSelfEnable = (bool)DM_Value;
+		//DbgPrint("pMgntInfo->bCTSToSelfEnable = %d\n", pMgntInfo->bCTSToSelfEnable);
+	}
+	else if(DM_Type == 1) //CTS to self Th
+	{
+		if(DM_Value >= 50)
+			DM_Value = 50;
+		priv->ieee80211->CTSToSelfTH = (u8)DM_Value;
+		//DbgPrint("pMgntInfo->CTSToSelfTH = %d\n", pMgntInfo->CTSToSelfTH);
+	}
+}
+
+static void dm_init_ctstoself(struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
+
+	priv->ieee80211->bCTSToSelfEnable = TRUE;
+	priv->ieee80211->CTSToSelfTH = CTSToSelfTHVal;
+}
+
+static void dm_ctstoself(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
+	PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
+	static unsigned long				lastTxOkCnt = 0;
+	static unsigned long				lastRxOkCnt = 0;
+	unsigned long						curTxOkCnt = 0;
+	unsigned long						curRxOkCnt = 0;
+
+	if(priv->ieee80211->bCTSToSelfEnable != TRUE)
+	{
+		pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
+		return;
+	}
+	/*
+	1. Uplink
+	2. Linksys350/Linksys300N
+	3. <50 disable, >55 enable
+	*/
+
+	if(pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM)
+	{
+		curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
+		curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
+		if(curRxOkCnt > 4*curTxOkCnt)	//downlink, disable CTS to self
+		{
+			pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
+			//DbgPrint("dm_CTSToSelf() ==> CTS to self disabled -- downlink\n");
+		}
+		else	//uplink
+		{
+			pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
+		}
+
+		lastTxOkCnt = priv->stats.txbytesunicast;
+		lastRxOkCnt = priv->stats.rxbytesunicast;
+	}
+}
+
+
+/*-----------------------------------------------------------------------------
+ * Function:	dm_check_rfctrl_gpio()
+ *
+ * Overview:	Copy 8187B template for 9xseries.
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/28/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static void dm_check_rfctrl_gpio(struct net_device * dev)
+{
+	//struct r8192_priv *priv = ieee80211_priv(dev);
+
+	// Walk around for DTM test, we will not enable HW - radio on/off because r/w
+	// page 1 register before Lextra bus is enabled cause system fails when resuming
+	// from S4. 20080218, Emily
+
+	// Stop to execute workitem to prevent S3/S4 bug.
+#ifdef RTL8190P
+	return;
+#endif
+#ifdef RTL8192U
+	return;
+#endif
+#ifdef RTL8192E
+		queue_delayed_work(priv->priv_wq,&priv->gpio_change_rf_wq,0);
+#endif
+
+}	/* dm_CheckRfCtrlGPIO */
+
+/*-----------------------------------------------------------------------------
+ * Function:	dm_check_pbc_gpio()
+ *
+ * Overview:	Check if PBC button is pressed.
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/28/2008	amy 	Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static	void	dm_check_pbc_gpio(struct net_device *dev)
+{
+#ifdef RTL8192U
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 tmp1byte;
+
+
+	tmp1byte = read_nic_byte(dev,GPI);
+	if(tmp1byte == 0xff)
+		return;
+
+	if (tmp1byte&BIT6 || tmp1byte&BIT0)
+	{
+		// Here we only set bPbcPressed to TRUE
+		// After trigger PBC, the variable will be set to FALSE
+		RT_TRACE(COMP_IO, "CheckPbcGPIO - PBC is pressed\n");
+		priv->bpbc_pressed = true;
+	}
+#endif
+
+}
+
+#ifdef RTL8192E
+
+/*-----------------------------------------------------------------------------
+ * Function:	dm_GPIOChangeRF
+ * Overview:	PCI will not support workitem call back HW radio on-off control.
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	02/21/2008	MHC		Create Version 0.
+ *
+ *---------------------------------------------------------------------------*/
+extern	void	dm_gpio_change_rf_callback(struct work_struct *work)
+{
+	struct delayed_work *dwork = container_of(work,struct delayed_work,work);
+       struct r8192_priv *priv = container_of(dwork,struct r8192_priv,gpio_change_rf_wq);
+       struct net_device *dev = priv->ieee80211->dev;
+	u8 tmp1byte;
+	RT_RF_POWER_STATE	eRfPowerStateToSet;
+	bool bActuallySet = false;
+
+	do{
+		bActuallySet=false;
+
+		if(!priv->up)
+		{
+			RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF),"dm_gpio_change_rf_callback(): Callback function breaks out!!\n");
+		}
+		else
+		{
+			// 0x108 GPIO input register is read only
+			//set 0x108 B1= 1: RF-ON; 0: RF-OFF.
+			tmp1byte = read_nic_byte(dev,GPI);
+
+			eRfPowerStateToSet = (tmp1byte&BIT1) ?  eRfOn : eRfOff;
+
+			if( (priv->bHwRadioOff == true) && (eRfPowerStateToSet == eRfOn))
+			{
+				RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio ON\n");
+
+				priv->bHwRadioOff = false;
+				bActuallySet = true;
+			}
+			else if ( (priv->bHwRadioOff == false) && (eRfPowerStateToSet == eRfOff))
+			{
+				RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio OFF\n");
+				priv->bHwRadioOff = true;
+				bActuallySet = true;
+			}
+
+			if(bActuallySet)
+			{
+				#ifdef TO_DO
+				MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
+				//DrvIFIndicateCurrentPhyStatus(pAdapter);
+				#endif
+			}
+			else
+			{
+				msleep(2000);
+			}
+
+		}
+	}while(TRUE)
+
+}	/* dm_GPIOChangeRF */
+
+#endif
+/*-----------------------------------------------------------------------------
+ * Function:	DM_RFPathCheckWorkItemCallBack()
+ *
+ * Overview:	Check if Current RF RX path is enabled
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	01/30/2008	MHC		Create Version 0.
+ *
+ *---------------------------------------------------------------------------*/
+extern	void	dm_rf_pathcheck_workitemcallback(struct work_struct *work)
+{
+	struct delayed_work *dwork = container_of(work,struct delayed_work,work);
+       struct r8192_priv *priv = container_of(dwork,struct r8192_priv,rfpath_check_wq);
+       struct net_device *dev =priv->ieee80211->dev;
+	//bool bactually_set = false;
+	u8 rfpath = 0, i;
+
+
+	/* 2008/01/30 MH After discussing with SD3 Jerry, 0xc04/0xd04 register will
+	   always be the same. We only read 0xc04 now. */
+	rfpath = read_nic_byte(dev, 0xc04);
+
+	// Check Bit 0-3, it means if RF A-D is enabled.
+	for (i = 0; i < RF90_PATH_MAX; i++)
+	{
+		if (rfpath & (0x01<<i))
+			priv->brfpath_rxenable[i] = 1;
+		else
+			priv->brfpath_rxenable[i] = 0;
+	}
+	if(!DM_RxPathSelTable.Enable)
+		return;
+
+	dm_rxpath_sel_byrssi(dev);
+}	/* DM_RFPathCheckWorkItemCallBack */
+
+static void dm_init_rxpath_selection(struct net_device * dev)
+{
+	u8 i;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	DM_RxPathSelTable.Enable = 1;	//default enabled
+	DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low;
+	DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH;
+	if(priv->CustomerID == RT_CID_819x_Netcore)
+		DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
+	else
+		DM_RxPathSelTable.cck_method = CCK_Rx_Version_1;
+	DM_RxPathSelTable.DbgMode = DM_DBG_OFF;
+	DM_RxPathSelTable.disabledRF = 0;
+	for(i=0; i<4; i++)
+	{
+		DM_RxPathSelTable.rf_rssi[i] = 50;
+		DM_RxPathSelTable.cck_pwdb_sta[i] = -64;
+		DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
+	}
+}
+
+static void dm_rxpath_sel_byrssi(struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8				i, max_rssi_index=0, min_rssi_index=0, sec_rssi_index=0, rf_num=0;
+	u8				tmp_max_rssi=0, tmp_min_rssi=0, tmp_sec_rssi=0;
+	u8				cck_default_Rx=0x2;	//RF-C
+	u8				cck_optional_Rx=0x3;//RF-D
+	long				tmp_cck_max_pwdb=0, tmp_cck_min_pwdb=0, tmp_cck_sec_pwdb=0;
+	u8				cck_rx_ver2_max_index=0, cck_rx_ver2_min_index=0, cck_rx_ver2_sec_index=0;
+	u8				cur_rf_rssi;
+	long				cur_cck_pwdb;
+	static u8			disabled_rf_cnt=0, cck_Rx_Path_initialized=0;
+	u8				update_cck_rx_path;
+
+	if(priv->rf_type != RF_2T4R)
+		return;
+
+	if(!cck_Rx_Path_initialized)
+	{
+		DM_RxPathSelTable.cck_Rx_path = (read_nic_byte(dev, 0xa07)&0xf);
+		cck_Rx_Path_initialized = 1;
+	}
+
+	DM_RxPathSelTable.disabledRF = 0xf;
+	DM_RxPathSelTable.disabledRF &=~ (read_nic_byte(dev, 0xc04));
+
+	if(priv->ieee80211->mode == WIRELESS_MODE_B)
+	{
+		DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;	//pure B mode, fixed cck version2
+		//DbgPrint("Pure B mode, use cck rx version2 \n");
+	}
+
+	//decide max/sec/min rssi index
+	for (i=0; i<RF90_PATH_MAX; i++)
+	{
+		if(!DM_RxPathSelTable.DbgMode)
+			DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i];
+
+		if(priv->brfpath_rxenable[i])
+		{
+			rf_num++;
+			cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i];
+
+			if(rf_num == 1)	// find first enabled rf path and the rssi values
+			{	//initialize, set all rssi index to the same one
+				max_rssi_index = min_rssi_index = sec_rssi_index = i;
+				tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi;
+			}
+			else if(rf_num == 2)
+			{	// we pick up the max index first, and let sec and min to be the same one
+				if(cur_rf_rssi >= tmp_max_rssi)
+				{
+					tmp_max_rssi = cur_rf_rssi;
+					max_rssi_index = i;
+				}
+				else
+				{
+					tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi;
+					sec_rssi_index = min_rssi_index = i;
+				}
+			}
+			else
+			{
+				if(cur_rf_rssi > tmp_max_rssi)
+				{
+					tmp_sec_rssi = tmp_max_rssi;
+					sec_rssi_index = max_rssi_index;
+					tmp_max_rssi = cur_rf_rssi;
+					max_rssi_index = i;
+				}
+				else if(cur_rf_rssi == tmp_max_rssi)
+				{	// let sec and min point to the different index
+					tmp_sec_rssi = cur_rf_rssi;
+					sec_rssi_index = i;
+				}
+				else if((cur_rf_rssi < tmp_max_rssi) &&(cur_rf_rssi > tmp_sec_rssi))
+				{
+					tmp_sec_rssi = cur_rf_rssi;
+					sec_rssi_index = i;
+				}
+				else if(cur_rf_rssi == tmp_sec_rssi)
+				{
+					if(tmp_sec_rssi == tmp_min_rssi)
+					{	// let sec and min point to the different index
+						tmp_sec_rssi = cur_rf_rssi;
+						sec_rssi_index = i;
+					}
+					else
+					{
+						// This case we don't need to set any index
+					}
+				}
+				else if((cur_rf_rssi < tmp_sec_rssi) && (cur_rf_rssi > tmp_min_rssi))
+				{
+					// This case we don't need to set any index
+				}
+				else if(cur_rf_rssi == tmp_min_rssi)
+				{
+					if(tmp_sec_rssi == tmp_min_rssi)
+					{	// let sec and min point to the different index
+						tmp_min_rssi = cur_rf_rssi;
+						min_rssi_index = i;
+					}
+					else
+					{
+						// This case we don't need to set any index
+					}
+				}
+				else if(cur_rf_rssi < tmp_min_rssi)
+				{
+					tmp_min_rssi = cur_rf_rssi;
+					min_rssi_index = i;
+				}
+			}
+		}
+	}
+
+	rf_num = 0;
+	// decide max/sec/min cck pwdb index
+	if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2)
+	{
+		for (i=0; i<RF90_PATH_MAX; i++)
+		{
+			if(priv->brfpath_rxenable[i])
+			{
+				rf_num++;
+				cur_cck_pwdb =  DM_RxPathSelTable.cck_pwdb_sta[i];
+
+				if(rf_num == 1)	// find first enabled rf path and the rssi values
+				{	//initialize, set all rssi index to the same one
+					cck_rx_ver2_max_index = cck_rx_ver2_min_index = cck_rx_ver2_sec_index = i;
+					tmp_cck_max_pwdb = tmp_cck_min_pwdb = tmp_cck_sec_pwdb = cur_cck_pwdb;
+				}
+				else if(rf_num == 2)
+				{	// we pick up the max index first, and let sec and min to be the same one
+					if(cur_cck_pwdb >= tmp_cck_max_pwdb)
+					{
+						tmp_cck_max_pwdb = cur_cck_pwdb;
+						cck_rx_ver2_max_index = i;
+					}
+					else
+					{
+						tmp_cck_sec_pwdb = tmp_cck_min_pwdb = cur_cck_pwdb;
+						cck_rx_ver2_sec_index = cck_rx_ver2_min_index = i;
+					}
+				}
+				else
+				{
+					if(cur_cck_pwdb > tmp_cck_max_pwdb)
+					{
+						tmp_cck_sec_pwdb = tmp_cck_max_pwdb;
+						cck_rx_ver2_sec_index = cck_rx_ver2_max_index;
+						tmp_cck_max_pwdb = cur_cck_pwdb;
+						cck_rx_ver2_max_index = i;
+					}
+					else if(cur_cck_pwdb == tmp_cck_max_pwdb)
+					{	// let sec and min point to the different index
+						tmp_cck_sec_pwdb = cur_cck_pwdb;
+						cck_rx_ver2_sec_index = i;
+					}
+					else if((cur_cck_pwdb < tmp_cck_max_pwdb) &&(cur_cck_pwdb > tmp_cck_sec_pwdb))
+					{
+						tmp_cck_sec_pwdb = cur_cck_pwdb;
+						cck_rx_ver2_sec_index = i;
+					}
+					else if(cur_cck_pwdb == tmp_cck_sec_pwdb)
+					{
+						if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
+						{	// let sec and min point to the different index
+							tmp_cck_sec_pwdb = cur_cck_pwdb;
+							cck_rx_ver2_sec_index = i;
+						}
+						else
+						{
+							// This case we don't need to set any index
+						}
+					}
+					else if((cur_cck_pwdb < tmp_cck_sec_pwdb) && (cur_cck_pwdb > tmp_cck_min_pwdb))
+					{
+						// This case we don't need to set any index
+					}
+					else if(cur_cck_pwdb == tmp_cck_min_pwdb)
+					{
+						if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
+						{	// let sec and min point to the different index
+							tmp_cck_min_pwdb = cur_cck_pwdb;
+							cck_rx_ver2_min_index = i;
+						}
+						else
+						{
+							// This case we don't need to set any index
+						}
+					}
+					else if(cur_cck_pwdb < tmp_cck_min_pwdb)
+					{
+						tmp_cck_min_pwdb = cur_cck_pwdb;
+						cck_rx_ver2_min_index = i;
+					}
+				}
+
+			}
+		}
+	}
+
+
+	// Set CCK Rx path
+	// reg0xA07[3:2]=cck default rx path, reg0xa07[1:0]=cck optional rx path.
+	update_cck_rx_path = 0;
+	if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2)
+	{
+		cck_default_Rx = cck_rx_ver2_max_index;
+		cck_optional_Rx = cck_rx_ver2_sec_index;
+		if(tmp_cck_max_pwdb != -64)
+			update_cck_rx_path = 1;
+	}
+
+	if(tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2)
+	{
+		if((tmp_max_rssi - tmp_min_rssi) >= DM_RxPathSelTable.diff_TH)
+		{
+			//record the enabled rssi threshold
+			DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] = tmp_max_rssi+5;
+			//disable the BB Rx path, OFDM
+			rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<min_rssi_index, 0x0);	// 0xc04[3:0]
+			rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<min_rssi_index, 0x0);	// 0xd04[3:0]
+			disabled_rf_cnt++;
+		}
+		if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_1)
+		{
+			cck_default_Rx = max_rssi_index;
+			cck_optional_Rx = sec_rssi_index;
+			if(tmp_max_rssi)
+				update_cck_rx_path = 1;
+		}
+	}
+
+	if(update_cck_rx_path)
+	{
+		DM_RxPathSelTable.cck_Rx_path = (cck_default_Rx<<2)|(cck_optional_Rx);
+		rtl8192_setBBreg(dev, rCCK0_AFESetting, 0x0f000000, DM_RxPathSelTable.cck_Rx_path);
+	}
+
+	if(DM_RxPathSelTable.disabledRF)
+	{
+		for(i=0; i<4; i++)
+		{
+			if((DM_RxPathSelTable.disabledRF>>i) & 0x1)	//disabled rf
+			{
+				if(tmp_max_rssi >= DM_RxPathSelTable.rf_enable_rssi_th[i])
+				{
+					//enable the BB Rx path
+					//DbgPrint("RF-%d is enabled. \n", 0x1<<i);
+					rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<i, 0x1);	// 0xc04[3:0]
+					rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<i, 0x1);	// 0xd04[3:0]
+					DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
+					disabled_rf_cnt--;
+				}
+			}
+		}
+	}
+}
+
+/*-----------------------------------------------------------------------------
+ * Function:	dm_check_rx_path_selection()
+ *
+ * Overview:	Call a workitem to check current RXRF path and Rx Path selection by RSSI.
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/28/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static	void	dm_check_rx_path_selection(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	queue_delayed_work(priv->priv_wq,&priv->rfpath_check_wq,0);
+}	/* dm_CheckRxRFPath */
+
+
+static void dm_init_fsync (struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	priv->ieee80211->fsync_time_interval = 500;
+	priv->ieee80211->fsync_rate_bitmap = 0x0f000800;
+	priv->ieee80211->fsync_rssi_threshold = 30;
+#ifdef RTL8190P
+	priv->ieee80211->bfsync_enable = true;
+#else
+	priv->ieee80211->bfsync_enable = false;
+#endif
+	priv->ieee80211->fsync_multiple_timeinterval = 3;
+	priv->ieee80211->fsync_firstdiff_ratethreshold= 100;
+	priv->ieee80211->fsync_seconddiff_ratethreshold= 200;
+	priv->ieee80211->fsync_state = Default_Fsync;
+	priv->framesyncMonitor = 1;	// current default 0xc38 monitor on
+
+	init_timer(&priv->fsync_timer);
+	priv->fsync_timer.data = (unsigned long)dev;
+	priv->fsync_timer.function = dm_fsync_timer_callback;
+}
+
+
+static void dm_deInit_fsync(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	del_timer_sync(&priv->fsync_timer);
+}
+
+extern void dm_fsync_timer_callback(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct r8192_priv *priv = ieee80211_priv((struct net_device *)data);
+	u32 rate_index, rate_count = 0, rate_count_diff=0;
+	bool		bSwitchFromCountDiff = false;
+	bool		bDoubleTimeInterval = false;
+
+	if(	priv->ieee80211->state == IEEE80211_LINKED &&
+		priv->ieee80211->bfsync_enable &&
+		(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC))
+	{
+		 // Count rate 54, MCS [7], [12, 13, 14, 15]
+		u32 rate_bitmap;
+		for(rate_index = 0; rate_index <= 27; rate_index++)
+		{
+			rate_bitmap  = 1 << rate_index;
+			if(priv->ieee80211->fsync_rate_bitmap &  rate_bitmap)
+				rate_count+= priv->stats.received_rate_histogram[1][rate_index];
+		}
+
+		if(rate_count < priv->rate_record)
+			rate_count_diff = 0xffffffff - rate_count + priv->rate_record;
+		else
+			rate_count_diff = rate_count - priv->rate_record;
+		if(rate_count_diff < priv->rateCountDiffRecord)
+		{
+
+			u32 DiffNum = priv->rateCountDiffRecord - rate_count_diff;
+			// Contiune count
+			if(DiffNum >= priv->ieee80211->fsync_seconddiff_ratethreshold)
+				priv->ContiuneDiffCount++;
+			else
+				priv->ContiuneDiffCount = 0;
+
+			// Contiune count over
+			if(priv->ContiuneDiffCount >=2)
+			{
+				bSwitchFromCountDiff = true;
+				priv->ContiuneDiffCount = 0;
+			}
+		}
+		else
+		{
+			// Stop contiune count
+			priv->ContiuneDiffCount = 0;
+		}
+
+		//If Count diff <= FsyncRateCountThreshold
+		if(rate_count_diff <= priv->ieee80211->fsync_firstdiff_ratethreshold)
+		{
+			bSwitchFromCountDiff = true;
+			priv->ContiuneDiffCount = 0;
+		}
+		priv->rate_record = rate_count;
+		priv->rateCountDiffRecord = rate_count_diff;
+		RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync);
+		// if we never receive those mcs rate and rssi > 30 % then switch fsyn
+		if(priv->undecorated_smoothed_pwdb > priv->ieee80211->fsync_rssi_threshold && bSwitchFromCountDiff)
+		{
+			bDoubleTimeInterval = true;
+			priv->bswitch_fsync = !priv->bswitch_fsync;
+			if(priv->bswitch_fsync)
+			{
+			#ifdef RTL8190P
+				write_nic_byte(dev, 0xC36, 0x00);
+			#else
+				write_nic_byte(dev,0xC36, 0x1c);
+			#endif
+				write_nic_byte(dev, 0xC3e, 0x90);
+			}
+			else
+			{
+			#ifdef RTL8190P
+				write_nic_byte(dev, 0xC36, 0x40);
+			#else
+				write_nic_byte(dev, 0xC36, 0x5c);
+			#endif
+				write_nic_byte(dev, 0xC3e, 0x96);
+			}
+		}
+		else if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->fsync_rssi_threshold)
+		{
+			if(priv->bswitch_fsync)
+			{
+				priv->bswitch_fsync  = false;
+			#ifdef RTL8190P
+				write_nic_byte(dev, 0xC36, 0x40);
+			#else
+				write_nic_byte(dev, 0xC36, 0x5c);
+			#endif
+				write_nic_byte(dev, 0xC3e, 0x96);
+			}
+		}
+		if(bDoubleTimeInterval){
+			if(timer_pending(&priv->fsync_timer))
+				del_timer_sync(&priv->fsync_timer);
+			priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval*priv->ieee80211->fsync_multiple_timeinterval);
+			add_timer(&priv->fsync_timer);
+		}
+		else{
+			if(timer_pending(&priv->fsync_timer))
+				del_timer_sync(&priv->fsync_timer);
+			priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
+			add_timer(&priv->fsync_timer);
+		}
+	}
+	else
+	{
+		// Let Register return to default value;
+		if(priv->bswitch_fsync)
+		{
+			priv->bswitch_fsync  = false;
+		#ifdef RTL8190P
+			write_nic_byte(dev, 0xC36, 0x40);
+		#else
+			write_nic_byte(dev, 0xC36, 0x5c);
+		#endif
+			write_nic_byte(dev, 0xC3e, 0x96);
+		}
+		priv->ContiuneDiffCount = 0;
+	#ifdef RTL8190P
+		write_nic_dword(dev, rOFDM0_RxDetector2, 0x164052cd);
+	#else
+		write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
+	#endif
+	}
+	RT_TRACE(COMP_HALDM, "ContiuneDiffCount %d\n", priv->ContiuneDiffCount);
+	RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync);
+}
+
+static void dm_StartHWFsync(struct net_device *dev)
+{
+	RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__);
+	write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cf);
+	write_nic_byte(dev, 0xc3b, 0x41);
+}
+
+static void dm_EndSWFsync(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__);
+	del_timer_sync(&(priv->fsync_timer));
+
+	// Let Register return to default value;
+	if(priv->bswitch_fsync)
+	{
+		priv->bswitch_fsync  = false;
+
+		#ifdef RTL8190P
+			write_nic_byte(dev, 0xC36, 0x40);
+		#else
+			write_nic_byte(dev, 0xC36, 0x5c);
+		#endif
+
+		write_nic_byte(dev, 0xC3e, 0x96);
+	}
+
+	priv->ContiuneDiffCount = 0;
+#ifndef RTL8190P
+	write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
+#endif
+
+}
+
+static void dm_StartSWFsync(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32 			rateIndex;
+	u32 			rateBitmap;
+
+	RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__);
+	// Initial rate record to zero, start to record.
+	priv->rate_record = 0;
+	// Initial contiune diff count to zero, start to record.
+	priv->ContiuneDiffCount = 0;
+	priv->rateCountDiffRecord = 0;
+	priv->bswitch_fsync  = false;
+
+	if(priv->ieee80211->mode == WIRELESS_MODE_N_24G)
+	{
+		priv->ieee80211->fsync_firstdiff_ratethreshold= 600;
+		priv->ieee80211->fsync_seconddiff_ratethreshold = 0xffff;
+	}
+	else
+	{
+		priv->ieee80211->fsync_firstdiff_ratethreshold= 200;
+		priv->ieee80211->fsync_seconddiff_ratethreshold = 200;
+	}
+	for(rateIndex = 0; rateIndex <= 27; rateIndex++)
+	{
+		rateBitmap  = 1 << rateIndex;
+		if(priv->ieee80211->fsync_rate_bitmap &  rateBitmap)
+			priv->rate_record += priv->stats.received_rate_histogram[1][rateIndex];
+	}
+	if(timer_pending(&priv->fsync_timer))
+		del_timer_sync(&priv->fsync_timer);
+	priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
+	add_timer(&priv->fsync_timer);
+
+#ifndef RTL8190P
+	write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cd);
+#endif
+
+}
+
+static void dm_EndHWFsync(struct net_device *dev)
+{
+	RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__);
+	write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
+	write_nic_byte(dev, 0xc3b, 0x49);
+
+}
+
+void dm_check_fsync(struct net_device *dev)
+{
+#define	RegC38_Default				0
+#define	RegC38_NonFsync_Other_AP	1
+#define	RegC38_Fsync_AP_BCM		2
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	//u32 			framesyncC34;
+	static u8		reg_c38_State=RegC38_Default;
+	static u32	reset_cnt=0;
+
+	RT_TRACE(COMP_HALDM, "RSSI %d TimeInterval %d MultipleTimeInterval %d\n", priv->ieee80211->fsync_rssi_threshold, priv->ieee80211->fsync_time_interval, priv->ieee80211->fsync_multiple_timeinterval);
+	RT_TRACE(COMP_HALDM, "RateBitmap 0x%x FirstDiffRateThreshold %d SecondDiffRateThreshold %d\n", priv->ieee80211->fsync_rate_bitmap, priv->ieee80211->fsync_firstdiff_ratethreshold, priv->ieee80211->fsync_seconddiff_ratethreshold);
+
+	if(	priv->ieee80211->state == IEEE80211_LINKED &&
+		(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC))
+	{
+		if(priv->ieee80211->bfsync_enable == 0)
+		{
+			switch(priv->ieee80211->fsync_state)
+			{
+				case Default_Fsync:
+					dm_StartHWFsync(dev);
+					priv->ieee80211->fsync_state = HW_Fsync;
+					break;
+				case SW_Fsync:
+					dm_EndSWFsync(dev);
+					dm_StartHWFsync(dev);
+					priv->ieee80211->fsync_state = HW_Fsync;
+					break;
+				case HW_Fsync:
+				default:
+					break;
+			}
+		}
+		else
+		{
+			switch(priv->ieee80211->fsync_state)
+			{
+				case Default_Fsync:
+					dm_StartSWFsync(dev);
+					priv->ieee80211->fsync_state = SW_Fsync;
+					break;
+				case HW_Fsync:
+					dm_EndHWFsync(dev);
+					dm_StartSWFsync(dev);
+					priv->ieee80211->fsync_state = SW_Fsync;
+					break;
+				case SW_Fsync:
+				default:
+					break;
+
+			}
+		}
+		if(priv->framesyncMonitor)
+		{
+			if(reg_c38_State != RegC38_Fsync_AP_BCM)
+			{	//For broadcom AP we write different default value
+				#ifdef RTL8190P
+					write_nic_byte(dev, rOFDM0_RxDetector3, 0x15);
+				#else
+					write_nic_byte(dev, rOFDM0_RxDetector3, 0x95);
+				#endif
+
+				reg_c38_State = RegC38_Fsync_AP_BCM;
+			}
+		}
+	}
+	else
+	{
+		switch(priv->ieee80211->fsync_state)
+		{
+			case HW_Fsync:
+				dm_EndHWFsync(dev);
+				priv->ieee80211->fsync_state = Default_Fsync;
+				break;
+			case SW_Fsync:
+				dm_EndSWFsync(dev);
+				priv->ieee80211->fsync_state = Default_Fsync;
+				break;
+			case Default_Fsync:
+			default:
+				break;
+		}
+
+		if(priv->framesyncMonitor)
+		{
+			if(priv->ieee80211->state == IEEE80211_LINKED)
+			{
+				if(priv->undecorated_smoothed_pwdb <= RegC38_TH)
+				{
+					if(reg_c38_State != RegC38_NonFsync_Other_AP)
+					{
+						#ifdef RTL8190P
+							write_nic_byte(dev, rOFDM0_RxDetector3, 0x10);
+						#else
+							write_nic_byte(dev, rOFDM0_RxDetector3, 0x90);
+						#endif
+
+						reg_c38_State = RegC38_NonFsync_Other_AP;
+					}
+				}
+				else if(priv->undecorated_smoothed_pwdb >= (RegC38_TH+5))
+				{
+					if(reg_c38_State)
+					{
+						write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
+						reg_c38_State = RegC38_Default;
+						//DbgPrint("Fsync is idle, rssi>=40, write 0xc38 = 0x%x \n", pHalData->framesync);
+					}
+				}
+			}
+			else
+			{
+				if(reg_c38_State)
+				{
+					write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
+					reg_c38_State = RegC38_Default;
+					//DbgPrint("Fsync is idle, not connected, write 0xc38 = 0x%x \n", pHalData->framesync);
+				}
+			}
+		}
+	}
+	if(priv->framesyncMonitor)
+	{
+		if(priv->reset_count != reset_cnt)
+		{	//After silent reset, the reg_c38_State will be returned to default value
+			write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
+			reg_c38_State = RegC38_Default;
+			reset_cnt = priv->reset_count;
+			//DbgPrint("reg_c38_State = 0 for silent reset. \n");
+		}
+	}
+	else
+	{
+		if(reg_c38_State)
+		{
+			write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
+			reg_c38_State = RegC38_Default;
+			//DbgPrint("framesync no monitor, write 0xc38 = 0x%x \n", pHalData->framesync);
+		}
+	}
+}
+
+
+/*-----------------------------------------------------------------------------
+ * Function:	dm_shadow_init()
+ *
+ * Overview:	Store all NIC MAC/BB register content.
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/29/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+extern void dm_shadow_init(struct net_device *dev)
+{
+	u8	page;
+	u16	offset;
+
+	for (page = 0; page < 5; page++)
+		for (offset = 0; offset < 256; offset++)
+		{
+			dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256);
+			//DbgPrint("P-%d/O-%02x=%02x\r\n", page, offset, DM_Shadow[page][offset]);
+		}
+
+	for (page = 8; page < 11; page++)
+		for (offset = 0; offset < 256; offset++)
+			dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256);
+
+	for (page = 12; page < 15; page++)
+		for (offset = 0; offset < 256; offset++)
+			dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256);
+
+}   /* dm_shadow_init */
+
+/*---------------------------Define function prototype------------------------*/
+/*-----------------------------------------------------------------------------
+ * Function:	DM_DynamicTxPower()
+ *
+ * Overview:	Detect Signal strength to control TX Registry
+			Tx Power Control For Near/Far Range
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	03/06/2008	Jacken	Create Version 0.
+ *
+ *---------------------------------------------------------------------------*/
+static void dm_init_dynamic_txpower(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	//Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code.
+	priv->ieee80211->bdynamic_txpower_enable = true;    //Default to enable Tx Power Control
+	priv->bLastDTPFlag_High = false;
+	priv->bLastDTPFlag_Low = false;
+	priv->bDynamicTxHighPower = false;
+	priv->bDynamicTxLowPower = false;
+}
+
+static void dm_dynamic_txpower(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	unsigned int txhipower_threshhold=0;
+	unsigned int txlowpower_threshold=0;
+	if(priv->ieee80211->bdynamic_txpower_enable != true)
+	{
+		priv->bDynamicTxHighPower = false;
+		priv->bDynamicTxLowPower = false;
+		return;
+	}
+	//printk("priv->ieee80211->current_network.unknown_cap_exist is %d ,priv->ieee80211->current_network.broadcom_cap_exist is %d\n",priv->ieee80211->current_network.unknown_cap_exist,priv->ieee80211->current_network.broadcom_cap_exist);
+	if((priv->ieee80211->current_network.atheros_cap_exist ) && (priv->ieee80211->mode == IEEE_G)){
+		txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH;
+		txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
+	}
+	else
+	{
+		txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
+		txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
+	}
+
+//	printk("=======>%s(): txhipower_threshhold is %d,txlowpower_threshold is %d\n",__FUNCTION__,txhipower_threshhold,txlowpower_threshold);
+	RT_TRACE(COMP_TXAGC,"priv->undecorated_smoothed_pwdb = %ld \n" , priv->undecorated_smoothed_pwdb);
+
+	if(priv->ieee80211->state == IEEE80211_LINKED)
+	{
+		if(priv->undecorated_smoothed_pwdb >= txhipower_threshhold)
+		{
+			priv->bDynamicTxHighPower = true;
+			priv->bDynamicTxLowPower = false;
+		}
+		else
+		{
+			// high power state check
+			if(priv->undecorated_smoothed_pwdb < txlowpower_threshold && priv->bDynamicTxHighPower == true)
+			{
+				priv->bDynamicTxHighPower = false;
+			}
+			// low power state check
+			if(priv->undecorated_smoothed_pwdb < 35)
+			{
+				priv->bDynamicTxLowPower = true;
+			}
+			else if(priv->undecorated_smoothed_pwdb >= 40)
+			{
+				priv->bDynamicTxLowPower = false;
+			}
+		}
+	}
+	else
+	{
+		//pHalData->bTXPowerCtrlforNearFarRange = !pHalData->bTXPowerCtrlforNearFarRange;
+		priv->bDynamicTxHighPower = false;
+		priv->bDynamicTxLowPower = false;
+	}
+
+	if( (priv->bDynamicTxHighPower != priv->bLastDTPFlag_High ) ||
+		(priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low ) )
+	{
+		RT_TRACE(COMP_TXAGC,"SetTxPowerLevel8190()  channel = %d \n" , priv->ieee80211->current_network.channel);
+
+#if  defined(RTL8190P) || defined(RTL8192E)
+		SetTxPowerLevel8190(Adapter,pHalData->CurrentChannel);
+#endif
+
+#ifdef RTL8192U
+		rtl8192_phy_setTxPower(dev,priv->ieee80211->current_network.channel);
+		//pHalData->bStartTxCtrlByTPCNFR = FALSE;    //Clear th flag of Set TX Power from Sitesurvey
+#endif
+	}
+	priv->bLastDTPFlag_High = priv->bDynamicTxHighPower;
+	priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower;
+
+}	/* dm_dynamic_txpower */
+
+//added by vivi, for read tx rate and retrycount
+static void dm_check_txrateandretrycount(struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_device* ieee = priv->ieee80211;
+	//for 11n tx rate
+//	priv->stats.CurrentShowTxate = read_nic_byte(dev, Current_Tx_Rate_Reg);
+	ieee->softmac_stats.CurrentShowTxate = read_nic_byte(dev, Current_Tx_Rate_Reg);
+	//printk("=============>tx_rate_reg:%x\n", ieee->softmac_stats.CurrentShowTxate);
+	//for initial tx rate
+//	priv->stats.last_packet_rate = read_nic_byte(dev, Initial_Tx_Rate_Reg);
+	ieee->softmac_stats.last_packet_rate = read_nic_byte(dev ,Initial_Tx_Rate_Reg);
+	//for tx tx retry count
+//	priv->stats.txretrycount = read_nic_dword(dev, Tx_Retry_Count_Reg);
+	ieee->softmac_stats.txretrycount = read_nic_dword(dev, Tx_Retry_Count_Reg);
+}
+
+static void dm_send_rssi_tofw(struct net_device *dev)
+{
+	DCMD_TXCMD_T			tx_cmd;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	// If we test chariot, we should stop the TX command ?
+	// Because 92E will always silent reset when we send tx command. We use register
+	// 0x1e0(byte) to botify driver.
+	write_nic_byte(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb);
+	return;
+	tx_cmd.Op		= TXCMD_SET_RX_RSSI;
+	tx_cmd.Length	= 4;
+	tx_cmd.Value		= priv->undecorated_smoothed_pwdb;
+
+	cmpk_message_handle_tx(dev, (u8*)&tx_cmd,
+								DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T));
+}
+
+/*---------------------------Define function prototype------------------------*/
+
diff --git a/drivers/staging/rtl8192u/r8192U_dm.h b/drivers/staging/rtl8192u/r8192U_dm.h
new file mode 100644
index 0000000..3ceb59b
--- /dev/null
+++ b/drivers/staging/rtl8192u/r8192U_dm.h
@@ -0,0 +1,254 @@
+/*****************************************************************************
+ *	Copyright(c) 2007,  RealTEK Technology Inc. All Right Reserved.
+ *
+ * Module:		Hal819xUsbDM.h	(RTL8192  Header H File)
+ *
+ *
+ * Note:		For dynamic control definition constant structure.
+ *
+ *
+ * Export:
+ *
+ * Abbrev:
+ *
+ * History:
+ *	Data		Who		Remark
+ *	10/04/2007  MHC    	Create initial version.
+ *
+ *****************************************************************************/
+ /* Check to see if the file has been included already.  */
+#ifndef	__R8192UDM_H__
+#define __R8192UDM_H__
+
+
+/*--------------------------Define Parameters-------------------------------*/
+#define		DM_DIG_THRESH_HIGH					40
+#define		DM_DIG_THRESH_LOW					35
+
+#define		DM_DIG_HIGH_PWR_THRESH_HIGH		75
+#define		DM_DIG_HIGH_PWR_THRESH_LOW		70
+
+#define		BW_AUTO_SWITCH_HIGH_LOW			25
+#define		BW_AUTO_SWITCH_LOW_HIGH			30
+
+#define		DM_check_fsync_time_interval				500
+
+
+#define		DM_DIG_BACKOFF				12
+#define		DM_DIG_MAX					0x36
+#define		DM_DIG_MIN					0x1c
+#define		DM_DIG_MIN_Netcore			0x12
+
+#define		RxPathSelection_SS_TH_low		30
+#define		RxPathSelection_diff_TH			18
+
+#define		RateAdaptiveTH_High			50
+#define		RateAdaptiveTH_Low_20M		30
+#define		RateAdaptiveTH_Low_40M		10
+#define		VeryLowRSSI					15
+#define		CTSToSelfTHVal					30
+
+//defined by vivi, for tx power track
+#define		E_FOR_TX_POWER_TRACK               300
+//Dynamic Tx Power Control Threshold
+#define		TX_POWER_NEAR_FIELD_THRESH_HIGH		68
+#define		TX_POWER_NEAR_FIELD_THRESH_LOW		62
+//added by amy for atheros AP
+#define         TX_POWER_ATHEROAP_THRESH_HIGH           78
+#define 	TX_POWER_ATHEROAP_THRESH_LOW		72
+
+//defined by vivi, for showing on UI
+#define 		Current_Tx_Rate_Reg         0x1b8
+#define 		Initial_Tx_Rate_Reg         	  0x1b9
+#define 		Tx_Retry_Count_Reg         0x1ac
+#define		RegC38_TH				 20
+/*--------------------------Define Parameters-------------------------------*/
+
+
+/*------------------------------Define structure----------------------------*/
+/* 2007/10/04 MH Define upper and lower threshold of DIG enable or disable. */
+typedef struct _dynamic_initial_gain_threshold_
+{
+	u8		dig_enable_flag;
+	u8		dig_algorithm;
+	u8		dbg_mode;
+	u8		dig_algorithm_switch;
+
+	long		rssi_low_thresh;
+	long		rssi_high_thresh;
+
+	long		rssi_high_power_lowthresh;
+	long		rssi_high_power_highthresh;
+
+	u8		dig_state;
+	u8		dig_highpwr_state;
+	u8		cur_connect_state;
+	u8		pre_connect_state;
+
+	u8		curpd_thstate;
+	u8		prepd_thstate;
+	u8		curcs_ratio_state;
+	u8		precs_ratio_state;
+
+	u32		pre_ig_value;
+	u32		cur_ig_value;
+
+	u8		backoff_val;
+	u8		rx_gain_range_max;
+	u8		rx_gain_range_min;
+	bool		initialgain_lowerbound_state;
+
+	long		rssi_val;
+}dig_t;
+
+typedef enum tag_dynamic_init_gain_state_definition
+{
+	DM_STA_DIG_OFF = 0,
+	DM_STA_DIG_ON,
+	DM_STA_DIG_MAX
+}dm_dig_sta_e;
+
+
+/* 2007/10/08 MH Define RATR state. */
+typedef enum tag_dynamic_ratr_state_definition
+{
+	DM_RATR_STA_HIGH = 0,
+	DM_RATR_STA_MIDDLE = 1,
+	DM_RATR_STA_LOW = 2,
+	DM_RATR_STA_MAX
+}dm_ratr_sta_e;
+
+/* 2007/10/11 MH Define DIG operation type. */
+typedef enum tag_dynamic_init_gain_operation_type_definition
+{
+	DIG_TYPE_THRESH_HIGH	= 0,
+	DIG_TYPE_THRESH_LOW	= 1,
+	DIG_TYPE_THRESH_HIGHPWR_HIGH	= 2,
+	DIG_TYPE_THRESH_HIGHPWR_LOW	= 3,
+	DIG_TYPE_DBG_MODE				= 4,
+	DIG_TYPE_RSSI						= 5,
+	DIG_TYPE_ALGORITHM				= 6,
+	DIG_TYPE_BACKOFF					= 7,
+	DIG_TYPE_PWDB_FACTOR			= 8,
+	DIG_TYPE_RX_GAIN_MIN				= 9,
+	DIG_TYPE_RX_GAIN_MAX				= 10,
+	DIG_TYPE_ENABLE 		= 20,
+	DIG_TYPE_DISABLE 		= 30,
+	DIG_OP_TYPE_MAX
+}dm_dig_op_e;
+
+typedef enum tag_dig_algorithm_definition
+{
+	DIG_ALGO_BY_FALSE_ALARM = 0,
+	DIG_ALGO_BY_RSSI	= 1,
+	DIG_ALGO_MAX
+}dm_dig_alg_e;
+
+typedef enum tag_dig_dbgmode_definition
+{
+	DIG_DBG_OFF = 0,
+	DIG_DBG_ON = 1,
+	DIG_DBG_MAX
+}dm_dig_dbg_e;
+
+typedef enum tag_dig_connect_definition
+{
+	DIG_DISCONNECT = 0,
+	DIG_CONNECT = 1,
+	DIG_CONNECT_MAX
+}dm_dig_connect_e;
+
+typedef enum tag_dig_packetdetection_threshold_definition
+{
+	DIG_PD_AT_LOW_POWER = 0,
+	DIG_PD_AT_NORMAL_POWER = 1,
+	DIG_PD_AT_HIGH_POWER = 2,
+	DIG_PD_MAX
+}dm_dig_pd_th_e;
+
+typedef enum tag_dig_cck_cs_ratio_state_definition
+{
+	DIG_CS_RATIO_LOWER = 0,
+	DIG_CS_RATIO_HIGHER = 1,
+	DIG_CS_MAX
+}dm_dig_cs_ratio_e;
+typedef struct _Dynamic_Rx_Path_Selection_
+{
+	u8		Enable;
+	u8		DbgMode;
+	u8		cck_method;
+	u8		cck_Rx_path;
+
+	u8		SS_TH_low;
+	u8		diff_TH;
+	u8		disabledRF;
+	u8		reserved;
+
+	u8		rf_rssi[4];
+	u8		rf_enable_rssi_th[4];
+	long		cck_pwdb_sta[4];
+}DRxPathSel;
+
+typedef enum tag_CCK_Rx_Path_Method_Definition
+{
+	CCK_Rx_Version_1 = 0,
+	CCK_Rx_Version_2= 1,
+	CCK_Rx_Version_MAX
+}DM_CCK_Rx_Path_Method;
+
+typedef enum tag_DM_DbgMode_Definition
+{
+	DM_DBG_OFF = 0,
+	DM_DBG_ON = 1,
+	DM_DBG_MAX
+}DM_DBG_E;
+
+typedef struct tag_Tx_Config_Cmd_Format
+{
+	u32	Op;										/* Command packet type. */
+	u32	Length;									/* Command packet length. */
+	u32	Value;
+}DCMD_TXCMD_T, *PDCMD_TXCMD_T;
+/*------------------------------Define structure----------------------------*/
+
+
+/*------------------------Export global variable----------------------------*/
+extern	dig_t	dm_digtable;
+extern	u8		dm_shadow[16][256];
+extern DRxPathSel      DM_RxPathSelTable;
+/*------------------------Export global variable----------------------------*/
+
+
+/*------------------------Export Marco Definition---------------------------*/
+
+/*------------------------Export Marco Definition---------------------------*/
+
+
+/*--------------------------Exported Function prototype---------------------*/
+extern  void    init_hal_dm(struct net_device *dev);
+extern  void deinit_hal_dm(struct net_device *dev);
+
+extern void hal_dm_watchdog(struct net_device *dev);
+
+extern  void    init_rate_adaptive(struct net_device *dev);
+extern  void    dm_txpower_trackingcallback(struct work_struct *work);
+extern  void    dm_restore_dynamic_mechanism_state(struct net_device *dev);
+extern  void    dm_backup_dynamic_mechanism_state(struct net_device *dev);
+extern  void    dm_change_dynamic_initgain_thresh(struct net_device *dev,
+								u32 dm_type, u32 dm_value);
+extern  void    dm_force_tx_fw_info(struct net_device *dev,u32 force_type, u32 force_value);
+extern  void    dm_init_edca_turbo(struct net_device *dev);
+extern  void    dm_rf_operation_test_callback(unsigned long data);
+extern  void    dm_rf_pathcheck_workitemcallback(struct work_struct *work);
+extern  void dm_fsync_timer_callback(unsigned long data);
+extern	void	dm_cck_txpower_adjust(struct net_device *dev,bool  binch14);
+extern  void    dm_shadow_init(struct net_device *dev);
+extern void dm_initialize_txpower_tracking(struct net_device *dev);
+/*--------------------------Exported Function prototype---------------------*/
+
+
+#endif	/*__R8192UDM_H__ */
+
+
+/* End of r8192U_dm.h */
+
diff --git a/drivers/staging/rtl8192u/r8192U_hw.h b/drivers/staging/rtl8192u/r8192U_hw.h
new file mode 100644
index 0000000..e89aaf7
--- /dev/null
+++ b/drivers/staging/rtl8192u/r8192U_hw.h
@@ -0,0 +1,411 @@
+/*
+	This is part of rtl8187 OpenSource driver.
+	Copyright (C) Andrea Merello 2004-2005  <andreamrl@tiscali.it>
+	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 rtl8187 MAC controller */
+#ifndef R8192_HW
+#define R8192_HW
+
+typedef enum _VERSION_819xU{
+	VERSION_819xU_A, // A-cut
+	VERSION_819xU_B, // B-cut
+	VERSION_819xU_C,// C-cut
+}VERSION_819xU,*PVERSION_819xU;
+//added for different RF type
+typedef enum _RT_RF_TYPE_DEF
+{
+	RF_1T2R = 0,
+	RF_2T4R,
+
+	RF_819X_MAX_TYPE
+}RT_RF_TYPE_DEF;
+
+
+typedef enum _BaseBand_Config_Type{
+	BaseBand_Config_PHY_REG = 0,			//Radio Path A
+	BaseBand_Config_AGC_TAB = 1,			//Radio Path B
+}BaseBand_Config_Type, *PBaseBand_Config_Type;
+#define	RTL8187_REQT_READ	0xc0
+#define	RTL8187_REQT_WRITE	0x40
+#define	RTL8187_REQ_GET_REGS	0x05
+#define	RTL8187_REQ_SET_REGS	0x05
+
+#define MAX_TX_URB 5
+#define MAX_RX_URB 16
+
+#define R8180_MAX_RETRY 255
+//#define MAX_RX_NORMAL_URB 3
+//#define MAX_RX_COMMAND_URB 2
+#define RX_URB_SIZE 9100
+
+#define BB_ANTATTEN_CHAN14	0x0c
+#define BB_ANTENNA_B 0x40
+
+#define BB_HOST_BANG (1<<30)
+#define BB_HOST_BANG_EN (1<<2)
+#define BB_HOST_BANG_CLK (1<<1)
+#define BB_HOST_BANG_RW (1<<3)
+#define BB_HOST_BANG_DATA	 1
+
+//#if (RTL819X_FPGA_VER & RTL819X_FPGA_VIVI_070920)
+#define AFR			0x010
+#define AFR_CardBEn		(1<<0)
+#define AFR_CLKRUN_SEL		(1<<1)
+#define AFR_FuncRegEn		(1<<2)
+#define RTL8190_EEPROM_ID	0x8129
+#define EEPROM_VID		0x02
+#define EEPROM_PID		0x04
+#define EEPROM_NODE_ADDRESS_BYTE_0	0x0C
+
+#define EEPROM_TxPowerDiff	0x1F
+#define EEPROM_ThermalMeter	0x20
+#define EEPROM_PwDiff		0x21	//0x21
+#define EEPROM_CrystalCap	0x22	//0x22
+
+#define EEPROM_TxPwIndex_CCK	0x23	//0x23
+#define EEPROM_TxPwIndex_OFDM_24G	0x24	//0x24~0x26
+#define EEPROM_TxPwIndex_CCK_V1		0x29	//0x29~0x2B
+#define EEPROM_TxPwIndex_OFDM_24G_V1	0x2C	//0x2C~0x2E
+#define EEPROM_TxPwIndex_Ver		0x27	//0x27
+
+#define EEPROM_Default_TxPowerDiff		0x0
+#define EEPROM_Default_ThermalMeter		0x7
+#define EEPROM_Default_PwDiff			0x4
+#define EEPROM_Default_CrystalCap		0x5
+#define EEPROM_Default_TxPower			0x1010
+#define EEPROM_Customer_ID			0x7B	//0x7B:CustomerID
+#define EEPROM_ChannelPlan			0x16	//0x7C
+#define EEPROM_IC_VER				0x7d	//0x7D
+#define EEPROM_CRC				0x7e	//0x7E~0x7F
+
+#define EEPROM_CID_DEFAULT			0x0
+#define EEPROM_CID_CAMEO				0x1
+#define EEPROM_CID_RUNTOP				0x2
+#define EEPROM_CID_Senao				0x3
+#define EEPROM_CID_TOSHIBA				0x4	// Toshiba setting, Merge by Jacken, 2008/01/31
+#define EEPROM_CID_NetCore				0x5
+#define EEPROM_CID_Nettronix			0x6
+#define EEPROM_CID_Pronet				0x7
+#define EEPROM_CID_DLINK				0x8
+
+#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
+
+//#endif
+enum _RTL8192Usb_HW {
+
+	PCIF			= 0x009, // PCI Function Register 0x0009h~0x000bh
+#define	BB_GLOBAL_RESET_BIT	0x1
+	BB_GLOBAL_RESET		= 0x020, // BasebandGlobal Reset Register
+	BSSIDR			= 0x02E, // BSSID Register
+	CMDR			= 0x037, // Command register
+#define CR_RST			0x10
+#define CR_RE			0x08
+#define CR_TE			0x04
+#define CR_MulRW		0x01
+	SIFS			= 0x03E, // SIFS register
+	TCR			= 0x040, // Transmit Configuration Register
+
+#define TCR_MXDMA_2048 		7
+#define TCR_LRL_OFFSET		0
+#define TCR_SRL_OFFSET		8
+#define TCR_MXDMA_OFFSET	21
+#define TCR_SAT			BIT24		// Enable Rate depedent ack timeout timer
+	RCR			= 0x044, // Receive Configuration Register
+#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_FIFO_THRESHOLD_MASK ((1<<13) | (1<<14) | (1<<15))
+#define RX_FIFO_THRESHOLD_SHIFT 13
+#define RX_FIFO_THRESHOLD_128 3
+#define RX_FIFO_THRESHOLD_256 4
+#define RX_FIFO_THRESHOLD_512 5
+#define RX_FIFO_THRESHOLD_1024 6
+#define RX_FIFO_THRESHOLD_NONE 7
+#define MAX_RX_DMA_MASK ((1<<8) | (1<<9) | (1<<10))
+#define RCR_MXDMA_OFFSET	8
+#define RCR_FIFO_OFFSET		13
+#define RCR_ONLYERLPKT		BIT31			// Early Receiving based on Packet Size.
+#define RCR_ENCS2		BIT30			// Enable Carrier Sense Detection Method 2
+#define RCR_ENCS1		BIT29			// Enable Carrier Sense Detection Method 1
+#define RCR_ENMBID		BIT27			// Enable Multiple BssId.
+#define RCR_ACKTXBW		(BIT24|BIT25)		// TXBW Setting of ACK frames
+#define RCR_CBSSID		BIT23			// Accept BSSID match packet
+#define RCR_APWRMGT		BIT22			// Accept power management packet
+#define	RCR_ADD3		BIT21			// Accept address 3 match packet
+#define RCR_AMF			BIT20			// Accept management type frame
+#define RCR_ACF			BIT19			// Accept control type frame
+#define RCR_ADF			BIT18			// Accept data type frame
+#define RCR_RXFTH		BIT13			// Rx FIFO Threshold
+#define RCR_AICV		BIT12			// Accept ICV error packet
+#define	RCR_ACRC32		BIT5			// Accept CRC32 error packet
+#define	RCR_AB			BIT3			// Accept broadcast packet
+#define	RCR_AM			BIT2			// Accept multicast packet
+#define	RCR_APM			BIT1			// Accept physical match packet
+#define	RCR_AAP			BIT0			// Accept all unicast packet
+	SLOT_TIME		= 0x049, // Slot Time Register
+	ACK_TIMEOUT		= 0x04c, // Ack Timeout Register
+	PIFS_TIME		= 0x04d, // PIFS time
+	USTIME			= 0x04e, // Microsecond Tuning Register, Sets the microsecond time unit used by MAC clock.
+	EDCAPARA_BE		= 0x050, // EDCA Parameter of AC BE
+	EDCAPARA_BK		= 0x054, // EDCA Parameter of AC BK
+	EDCAPARA_VO		= 0x058, // EDCA Parameter of AC VO
+	EDCAPARA_VI		= 0x05C, // EDCA Parameter of AC VI
+	RFPC			= 0x05F, // Rx FIFO Packet Count
+	CWRR			= 0x060, // Contention Window Report Register
+	BCN_TCFG		= 0x062, // Beacon Time Configuration
+#define BCN_TCFG_CW_SHIFT		8
+#define BCN_TCFG_IFS			0
+	BCN_INTERVAL		= 0x070, // Beacon Interval (TU)
+	ATIMWND			= 0x072, // ATIM Window Size (TU)
+	BCN_DRV_EARLY_INT	= 0x074, // Driver Early Interrupt Time (TU). Time to send interrupt to notify to change beacon content before TBTT
+	BCN_DMATIME		= 0x076, // Beacon DMA and ATIM interrupt time (US). Indicates the time before TBTT to perform beacon queue DMA
+	BCN_ERR_THRESH		= 0x078, // Beacon Error Threshold
+	RWCAM			= 0x0A0, //IN 8190 Data Sheet is called CAMcmd
+	WCAMI			= 0x0A4, // Software write CAM input content
+	RCAMO			= 0x0A8, // Software read/write CAM config
+	SECR			= 0x0B0, //Security Configuration Register
+#define	SCR_TxUseDK		BIT0			//Force Tx Use Default Key
+#define SCR_RxUseDK		BIT1			//Force Rx Use Default Key
+#define SCR_TxEncEnable		BIT2			//Enable Tx Encryption
+#define SCR_RxDecEnable		BIT3			//Enable Rx Decryption
+#define SCR_SKByA2		BIT4			//Search kEY BY A2
+#define SCR_NoSKMC		BIT5			//No Key Search for Multicast
+#define SCR_UseDK		0x01
+#define SCR_TxSecEnable		0x02
+#define SCR_RxSecEnable		0x04
+	TPPoll			= 0x0fd, // Transmit priority polling register
+	PSR			= 0x0ff, // Page Select Register
+#define CPU_CCK_LOOPBACK	0x00030000
+#define CPU_GEN_SYSTEM_RESET	0x00000001
+#define CPU_GEN_FIRMWARE_RESET	0x00000008
+#define CPU_GEN_BOOT_RDY	0x00000010
+#define CPU_GEN_FIRM_RDY	0x00000020
+#define CPU_GEN_PUT_CODE_OK	0x00000080
+#define CPU_GEN_BB_RST		0x00000100
+#define CPU_GEN_PWR_STB_CPU	0x00000004
+#define CPU_GEN_NO_LOOPBACK_MSK	0xFFF8FFFF		// Set bit18,17,16 to 0. Set bit19
+#define CPU_GEN_NO_LOOPBACK_SET	0x00080000		// Set BIT19 to 1
+
+//----------------------------------------------------------------------------
+//       8190 CPU General Register		(offset 0x100, 4 byte)
+//----------------------------------------------------------------------------
+#define	CPU_CCK_LOOPBACK	0x00030000
+#define	CPU_GEN_SYSTEM_RESET	0x00000001
+#define	CPU_GEN_FIRMWARE_RESET	0x00000008
+#define	CPU_GEN_BOOT_RDY	0x00000010
+#define	CPU_GEN_FIRM_RDY	0x00000020
+#define	CPU_GEN_PUT_CODE_OK	0x00000080
+#define	CPU_GEN_BB_RST		0x00000100
+#define	CPU_GEN_PWR_STB_CPU	0x00000004
+#define CPU_GEN_NO_LOOPBACK_MSK	0xFFF8FFFF // Set bit18,17,16 to 0. Set bit19
+#define CPU_GEN_NO_LOOPBACK_SET	0x00080000 // Set BIT19 to 1
+	CPU_GEN			= 0x100, // CPU Reset Register
+	LED1Cfg			=		0x154,// LED1 Configuration Register
+	LED0Cfg			=		0x155,// LED0 Configuration Register
+
+	AcmAvg			= 0x170, // ACM Average Period Register
+	AcmHwCtrl		= 0x171, // ACM Hardware Control Register
+//----------------------------------------------------------------------------
+////
+////       8190 AcmHwCtrl bits                                    (offset 0x171, 1 byte)
+////----------------------------------------------------------------------------
+//
+#define AcmHw_HwEn              BIT0
+#define AcmHw_BeqEn             BIT1
+#define AcmHw_ViqEn             BIT2
+#define AcmHw_VoqEn             BIT3
+#define AcmHw_BeqStatus         BIT4
+#define AcmHw_ViqStatus         BIT5
+#define AcmHw_VoqStatus         BIT6
+
+	AcmFwCtrl		= 0x172, // ACM Firmware Control Register
+	AES_11N_FIX		= 0x173,
+	VOAdmTime		= 0x174, // VO Queue Admitted Time Register
+	VIAdmTime		= 0x178, // VI Queue Admitted Time Register
+	BEAdmTime		= 0x17C, // BE Queue Admitted Time Register
+	RQPN1			= 0x180, // Reserved Queue Page Number , Vo Vi, Be, Bk
+	RQPN2			= 0x184, // Reserved Queue Page Number, HCCA, Cmd, Mgnt, High
+	RQPN3			= 0x188, // Reserved Queue Page Number, Bcn, Public,
+//	QPRR			= 0x1E0, // Queue Page Report per TID
+	QPNR			= 0x1D0, //0x1F0, // Queue Packet Number report per TID
+	BQDA			= 0x200, // Beacon Queue Descriptor Address
+	HQDA			= 0x204, // High Priority Queue Descriptor Address
+	CQDA			= 0x208, // Command Queue Descriptor Address
+	MQDA			= 0x20C, // Management Queue Descriptor Address
+	HCCAQDA			= 0x210, // HCCA Queue Descriptor Address
+	VOQDA			= 0x214, // VO Queue Descriptor Address
+	VIQDA			= 0x218, // VI Queue Descriptor Address
+	BEQDA			= 0x21C, // BE Queue Descriptor Address
+	BKQDA			= 0x220, // BK Queue Descriptor Address
+	RCQDA			= 0x224, // Receive command Queue Descriptor Address
+	RDQDA			= 0x228, // Receive Queue Descriptor Start Address
+
+	MAR0			= 0x240, // Multicast filter.
+	MAR4			= 0x244,
+
+	CCX_PERIOD		= 0x250, // CCX Measurement Period Register, in unit of TU.
+	CLM_RESULT		= 0x251, // CCA Busy fraction register.
+	NHM_PERIOD		= 0x252, // NHM Measurement Period register, in unit of TU.
+
+	NHM_THRESHOLD0		= 0x253, // Noise Histogram Meashorement0.
+	NHM_THRESHOLD1		= 0x254, // Noise Histogram Meashorement1.
+	NHM_THRESHOLD2		= 0x255, // Noise Histogram Meashorement2.
+	NHM_THRESHOLD3		= 0x256, // Noise Histogram Meashorement3.
+	NHM_THRESHOLD4		= 0x257, // Noise Histogram Meashorement4.
+	NHM_THRESHOLD5		= 0x258, // Noise Histogram Meashorement5.
+	NHM_THRESHOLD6		= 0x259, // Noise Histogram Meashorement6
+
+	MCTRL			= 0x25A, // Measurement Control
+
+	NHM_RPI_COUNTER0	= 0x264, // Noise Histogram RPI counter0, the fraction of signal strength < NHM_THRESHOLD0.
+	NHM_RPI_COUNTER1	= 0x265, // Noise Histogram RPI counter1, the fraction of signal strength in (NHM_THRESHOLD0, NHM_THRESHOLD1].
+	NHM_RPI_COUNTER2	= 0x266, // Noise Histogram RPI counter2, the fraction of signal strength in (NHM_THRESHOLD1, NHM_THRESHOLD2].
+	NHM_RPI_COUNTER3	= 0x267, // Noise Histogram RPI counter3, the fraction of signal strength in (NHM_THRESHOLD2, NHM_THRESHOLD3].
+	NHM_RPI_COUNTER4	= 0x268, // Noise Histogram RPI counter4, the fraction of signal strength in (NHM_THRESHOLD3, NHM_THRESHOLD4].
+	NHM_RPI_COUNTER5	= 0x269, // Noise Histogram RPI counter5, the fraction of signal strength in (NHM_THRESHOLD4, NHM_THRESHOLD5].
+	NHM_RPI_COUNTER6	= 0x26A, // Noise Histogram RPI counter6, the fraction of signal strength in (NHM_THRESHOLD5, NHM_THRESHOLD6].
+	NHM_RPI_COUNTER7	= 0x26B, // Noise Histogram RPI counter7, the fraction of signal strength in (NHM_THRESHOLD6, NHM_THRESHOLD7].
+#define	BW_OPMODE_11J			BIT0
+#define	BW_OPMODE_5G			BIT1
+#define	BW_OPMODE_20MHZ			BIT2
+	BW_OPMODE		= 0x300, // Bandwidth operation mode
+	MSR			= 0x303, // Media Status register
+#define MSR_LINK_MASK      ((1<<0)|(1<<1))
+#define MSR_LINK_MANAGED   2
+#define MSR_LINK_NONE      0
+#define MSR_LINK_SHIFT     0
+#define MSR_LINK_ADHOC     1
+#define MSR_LINK_MASTER    3
+#define MSR_LINK_ENEDCA	   (1<<4)
+	RETRY_LIMIT		= 0x304, // Retry Limit [15:8]-short, [7:0]-long
+#define RETRY_LIMIT_SHORT_SHIFT 8
+#define RETRY_LIMIT_LONG_SHIFT 0
+	TSFR			= 0x308,
+	RRSR			= 0x310, // Response Rate Set
+#define RRSR_RSC_OFFSET			21
+#define RRSR_SHORT_OFFSET			23
+#define RRSR_RSC_DUPLICATE			0x600000
+#define RRSR_RSC_LOWSUBCHNL		0x400000
+#define RRSR_RSC_UPSUBCHANL		0x200000
+#define RRSR_SHORT					0x800000
+#define RRSR_1M						BIT0
+#define RRSR_2M						BIT1
+#define RRSR_5_5M					BIT2
+#define RRSR_11M					BIT3
+#define RRSR_6M						BIT4
+#define RRSR_9M						BIT5
+#define RRSR_12M					BIT6
+#define RRSR_18M					BIT7
+#define RRSR_24M					BIT8
+#define RRSR_36M					BIT9
+#define RRSR_48M					BIT10
+#define RRSR_54M					BIT11
+#define RRSR_MCS0					BIT12
+#define RRSR_MCS1					BIT13
+#define RRSR_MCS2					BIT14
+#define RRSR_MCS3					BIT15
+#define RRSR_MCS4					BIT16
+#define RRSR_MCS5					BIT17
+#define RRSR_MCS6					BIT18
+#define RRSR_MCS7					BIT19
+#define BRSR_AckShortPmb			BIT23		// CCK ACK: use Short Preamble or not.
+	RATR0			= 0x320, // Rate Adaptive Table register1
+	UFWP			= 0x318,
+	DRIVER_RSSI		= 0x32c,					// Driver tell Firmware current RSSI
+//----------------------------------------------------------------------------
+//       8190 Rate Adaptive Table Register	(offset 0x320, 4 byte)
+//----------------------------------------------------------------------------
+//CCK
+#define	RATR_1M			0x00000001
+#define	RATR_2M			0x00000002
+#define	RATR_55M		0x00000004
+#define	RATR_11M		0x00000008
+//OFDM
+#define	RATR_6M			0x00000010
+#define	RATR_9M			0x00000020
+#define	RATR_12M		0x00000040
+#define	RATR_18M		0x00000080
+#define	RATR_24M		0x00000100
+#define	RATR_36M		0x00000200
+#define	RATR_48M		0x00000400
+#define	RATR_54M		0x00000800
+//MCS 1 Spatial Stream
+#define	RATR_MCS0		0x00001000
+#define	RATR_MCS1		0x00002000
+#define	RATR_MCS2		0x00004000
+#define	RATR_MCS3		0x00008000
+#define	RATR_MCS4		0x00010000
+#define	RATR_MCS5		0x00020000
+#define	RATR_MCS6		0x00040000
+#define	RATR_MCS7		0x00080000
+//MCS 2 Spatial Stream
+#define	RATR_MCS8		0x00100000
+#define	RATR_MCS9		0x00200000
+#define	RATR_MCS10		0x00400000
+#define	RATR_MCS11		0x00800000
+#define	RATR_MCS12		0x01000000
+#define	RATR_MCS13		0x02000000
+#define	RATR_MCS14		0x04000000
+#define	RATR_MCS15		0x08000000
+// ALL CCK Rate
+#define RATE_ALL_CCK		RATR_1M|RATR_2M|RATR_55M|RATR_11M
+#define RATE_ALL_OFDM_AG	RATR_6M|RATR_9M|RATR_12M|RATR_18M|RATR_24M\
+							|RATR_36M|RATR_48M|RATR_54M
+#define RATE_ALL_OFDM_1SS	RATR_MCS0|RATR_MCS1|RATR_MCS2|RATR_MCS3 | \
+							RATR_MCS4|RATR_MCS5|RATR_MCS6|RATR_MCS7
+#define RATE_ALL_OFDM_2SS	RATR_MCS8|RATR_MCS9	|RATR_MCS10|RATR_MCS11| \
+							RATR_MCS12|RATR_MCS13|RATR_MCS14|RATR_MCS15
+
+	MCS_TXAGC		= 0x340, // MCS AGC
+	CCK_TXAGC		= 0x348, // CCK AGC
+//	ISR			= 0x350, // Interrupt Status Register
+//	IMR			= 0x354, // Interrupt Mask Register
+//	IMR_POLL		= 0x360,
+	MacBlkCtrl		= 0x403, // Mac block on/off control register
+
+	EPROM_CMD 		= 0xfe58,
+#define Cmd9346CR_9356SEL	(1<<4)
+#define EPROM_CMD_RESERVED_MASK (1<<5)
+#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
+	MAC0 			= 0x000,
+	MAC1 			= 0x001,
+	MAC2 			= 0x002,
+	MAC3 			= 0x003,
+	MAC4 			= 0x004,
+	MAC5 			= 0x005,
+
+};
+//----------------------------------------------------------------------------
+//       818xB AnaParm & AnaParm2 Register
+//----------------------------------------------------------------------------
+//#define ANAPARM_ASIC_ON    0x45090658
+//#define ANAPARM2_ASIC_ON   0x727f3f52
+#define GPI 0x108
+#define GPO 0x109
+#define GPE 0x10a
+#endif
diff --git a/drivers/staging/rtl8192u/r8192U_wx.c b/drivers/staging/rtl8192u/r8192U_wx.c
new file mode 100644
index 0000000..25d5c87
--- /dev/null
+++ b/drivers/staging/rtl8192u/r8192U_wx.c
@@ -0,0 +1,1228 @@
+/*
+   This file contains wireless extension handlers.
+
+   This is part of rtl8180 OpenSource driver.
+   Copyright (C) Andrea Merello 2004-2005  <andreamrl@tiscali.it>
+   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.
+*/
+
+#include <linux/string.h>
+#include "r8192U.h"
+#include "r8192U_hw.h"
+
+#ifdef ENABLE_DOT11D
+#include "dot11d.h"
+#endif
+
+#define RATE_COUNT 12
+u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
+	6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
+
+
+#ifndef ENETDOWN
+#define ENETDOWN 1
+#endif
+
+static int r8192_wx_get_freq(struct net_device *dev,
+			     struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	return ieee80211_wx_get_freq(priv->ieee80211,a,wrqu,b);
+}
+
+
+static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b)
+{
+	struct r8192_priv *priv=ieee80211_priv(dev);
+
+	return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
+}
+
+
+
+static int r8192_wx_get_rate(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
+}
+
+
+
+static int r8192_wx_set_rate(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	down(&priv->wx_sem);
+
+	ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
+
+	up(&priv->wx_sem);
+
+	return ret;
+}
+
+
+static int r8192_wx_set_rts(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	down(&priv->wx_sem);
+
+	ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra);
+
+	up(&priv->wx_sem);
+
+	return ret;
+}
+
+static int r8192_wx_get_rts(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	return ieee80211_wx_get_rts(priv->ieee80211,info,wrqu,extra);
+}
+
+static int r8192_wx_set_power(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	down(&priv->wx_sem);
+
+	ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra);
+
+	up(&priv->wx_sem);
+
+	return ret;
+}
+
+static int r8192_wx_get_power(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	return ieee80211_wx_get_power(priv->ieee80211,info,wrqu,extra);
+}
+
+#ifdef JOHN_IOCTL
+u16 read_rtl8225(struct net_device *dev, u8 addr);
+void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
+u32 john_read_rtl8225(struct net_device *dev, u8 adr);
+void _write_rtl8225(struct net_device *dev, u8 adr, u16 data);
+
+static int r8192_wx_read_regs(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 addr;
+	u16 data1;
+
+	down(&priv->wx_sem);
+
+
+	get_user(addr,(u8*)wrqu->data.pointer);
+	data1 = read_rtl8225(dev, addr);
+	wrqu->data.length = data1;
+
+	up(&priv->wx_sem);
+	return 0;
+
+}
+
+static int r8192_wx_write_regs(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 addr;
+
+	down(&priv->wx_sem);
+
+	get_user(addr, (u8*)wrqu->data.pointer);
+	write_rtl8225(dev, addr, wrqu->data.length);
+
+	up(&priv->wx_sem);
+	return 0;
+
+}
+
+void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
+u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data);
+
+static int r8192_wx_read_bb(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 databb;
+
+	down(&priv->wx_sem);
+
+	databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000);
+	wrqu->data.length = databb;
+
+	up(&priv->wx_sem);
+	return 0;
+}
+
+void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
+static int r8192_wx_write_bb(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 databb;
+
+	down(&priv->wx_sem);
+
+	get_user(databb, (u8*)wrqu->data.pointer);
+	rtl8187_write_phy(dev, wrqu->data.length, databb);
+
+	up(&priv->wx_sem);
+	return 0;
+
+}
+
+
+static int r8192_wx_write_nicb(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32 addr;
+
+	down(&priv->wx_sem);
+
+	get_user(addr, (u32*)wrqu->data.pointer);
+	write_nic_byte(dev, addr, wrqu->data.length);
+
+	up(&priv->wx_sem);
+	return 0;
+
+}
+static int r8192_wx_read_nicb(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32 addr;
+	u16 data1;
+
+	down(&priv->wx_sem);
+
+	get_user(addr,(u32*)wrqu->data.pointer);
+	data1 = read_nic_byte(dev, addr);
+	wrqu->data.length = data1;
+
+	up(&priv->wx_sem);
+	return 0;
+}
+
+static int r8192_wx_get_ap_status(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_device *ieee = priv->ieee80211;
+	struct ieee80211_network *target;
+	int name_len;
+
+	down(&priv->wx_sem);
+
+	//count the length of input ssid
+	for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++);
+
+	//search for the correspoding info which is received
+	list_for_each_entry(target, &ieee->network_list, list) {
+		if ( (target->ssid_len == name_len) &&
+		     (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){
+			if(target->wpa_ie_len>0 || target->rsn_ie_len>0 )
+				//set flags=1 to indicate this ap is WPA
+				wrqu->data.flags = 1;
+			else wrqu->data.flags = 0;
+
+
+		break;
+		}
+	}
+
+	up(&priv->wx_sem);
+	return 0;
+}
+
+
+
+#endif
+static int r8192_wx_force_reset(struct net_device *dev,
+		struct iw_request_info *info,
+		union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	down(&priv->wx_sem);
+
+	printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra);
+	priv->force_reset = *extra;
+	up(&priv->wx_sem);
+	return 0;
+
+}
+
+
+static int r8192_wx_set_rawtx(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	int ret;
+
+	down(&priv->wx_sem);
+
+	ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
+
+	up(&priv->wx_sem);
+
+	return ret;
+
+}
+
+static int r8192_wx_set_crcmon(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	int *parms = (int *)extra;
+	int enable = (parms[0] > 0);
+	short prev = priv->crcmon;
+
+	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 r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	int ret;
+	down(&priv->wx_sem);
+
+	ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
+
+	rtl8192_set_rxconf(dev);
+
+	up(&priv->wx_sem);
+	return ret;
+}
+
+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;
+};
+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 iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range;
+	struct r8192_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' threshol 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->min_pmp=0;
+	range->max_pmp = 5000000;
+	range->min_pmt = 0;
+	range->max_pmt = 65535*1000;
+	range->pmp_flags = IW_POWER_PERIOD;
+	range->pmt_flags = IW_POWER_TIMEOUT;
+	range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
+
+	range->we_version_compiled = WIRELESS_EXT;
+	range->we_version_source = 16;
+
+//	range->retry_capa;	/* What retry options are supported */
+//	range->retry_flags;	/* How to decode max/min retry limit */
+//	range->r_time_flags;	/* How to decode max/min retry life */
+//	range->min_retry;	/* Minimal number of retries */
+//	range->max_retry;	/* Maximal number of retries */
+//	range->min_r_time;	/* Minimal retry lifetime */
+//	range->max_r_time;	/* Maximal retry lifetime */
+
+
+	for (i = 0, val = 0; i < 14; i++) {
+
+		// Include only legal frequencies for some countries
+#ifdef ENABLE_DOT11D
+		if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
+#else
+		if ((priv->ieee80211->channel_map)[i+1]) {
+#endif
+			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->num_channels = val;
+#if WIRELESS_EXT > 17
+	range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
+			  IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
+#endif
+	tmp->scan_capa = 0x01;
+	return 0;
+}
+
+
+static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_device* ieee = priv->ieee80211;
+	int ret = 0;
+
+	if(!priv->up) return -ENETDOWN;
+
+	if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
+		return -EAGAIN;
+	if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
+	{
+		struct iw_scan_req* req = (struct iw_scan_req*)b;
+		if (req->essid_len)
+		{
+			//printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
+			ieee->current_network.ssid_len = req->essid_len;
+			memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
+			//printk("=====>network ssid:%s\n", ieee->current_network.ssid);
+		}
+	}
+
+	down(&priv->wx_sem);
+	if(priv->ieee80211->state != IEEE80211_LINKED){
+		priv->ieee80211->scanning = 0;
+		ieee80211_softmac_scan_syncro(priv->ieee80211);
+		ret = 0;
+	}
+	else
+	ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
+	up(&priv->wx_sem);
+	return ret;
+}
+
+
+static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b)
+{
+
+	int ret;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	if(!priv->up) return -ENETDOWN;
+
+	down(&priv->wx_sem);
+
+	ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
+
+	up(&priv->wx_sem);
+
+	return ret;
+}
+
+static int r8192_wx_set_essid(struct net_device *dev,
+			      struct iw_request_info *a,
+			      union iwreq_data *wrqu, char *b)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	int ret;
+	down(&priv->wx_sem);
+
+	ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
+
+	up(&priv->wx_sem);
+
+	return ret;
+}
+
+
+
+
+static int r8192_wx_get_essid(struct net_device *dev,
+			      struct iw_request_info *a,
+			      union iwreq_data *wrqu, char *b)
+{
+	int ret;
+	struct r8192_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 r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b)
+{
+	int ret;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	down(&priv->wx_sem);
+
+	ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
+
+	up(&priv->wx_sem);
+	return ret;
+}
+
+static int r8192_wx_get_name(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
+}
+
+
+static int r8192_wx_set_frag(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	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 r8192_wx_get_frag(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_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 r8192_wx_set_wap(struct net_device *dev,
+			 struct iw_request_info *info,
+			 union iwreq_data *awrq,
+			 char *extra)
+{
+
+	int ret;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+//        struct sockaddr *temp = (struct sockaddr *)awrq;
+	down(&priv->wx_sem);
+
+	ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
+
+	up(&priv->wx_sem);
+
+	return ret;
+
+}
+
+
+static int r8192_wx_get_wap(struct net_device *dev,
+			    struct iw_request_info *info,
+			    union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
+}
+
+
+static int r8192_wx_get_enc(struct net_device *dev,
+			    struct iw_request_info *info,
+			    union iwreq_data *wrqu, char *key)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
+}
+
+static int r8192_wx_set_enc(struct net_device *dev,
+			    struct iw_request_info *info,
+			    union iwreq_data *wrqu, char *key)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_device *ieee = priv->ieee80211;
+	int ret;
+
+	//u32 TargetContent;
+	u32 hwkey[4]={0,0,0,0};
+	u8 mask=0xff;
+	u32 key_idx=0;
+	//u8 broadcast_addr[6] ={	0xff,0xff,0xff,0xff,0xff,0xff};
+	u8 zero_addr[4][6] ={	{0x00,0x00,0x00,0x00,0x00,0x00},
+				{0x00,0x00,0x00,0x00,0x00,0x01},
+				{0x00,0x00,0x00,0x00,0x00,0x02},
+				{0x00,0x00,0x00,0x00,0x00,0x03} };
+	int i;
+
+       if(!priv->up) return -ENETDOWN;
+
+	down(&priv->wx_sem);
+
+	RT_TRACE(COMP_SEC, "Setting SW wep key");
+	ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
+
+	up(&priv->wx_sem);
+
+
+
+	//sometimes, the length is zero while we do not type key value
+	if(wrqu->encoding.length!=0){
+
+		for(i=0 ; i<4 ; i++){
+			hwkey[i] |=  key[4*i+0]&mask;
+			if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
+			if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
+			hwkey[i] |= (key[4*i+1]&mask)<<8;
+			hwkey[i] |= (key[4*i+2]&mask)<<16;
+			hwkey[i] |= (key[4*i+3]&mask)<<24;
+		}
+
+		#define CONF_WEP40  0x4
+		#define CONF_WEP104 0x14
+
+		switch(wrqu->encoding.flags & IW_ENCODE_INDEX){
+			case 0: key_idx = ieee->tx_keyidx; break;
+			case 1:	key_idx = 0; break;
+			case 2:	key_idx = 1; break;
+			case 3:	key_idx = 2; break;
+			case 4:	key_idx	= 3; break;
+			default: break;
+		}
+
+		if(wrqu->encoding.length==0x5){
+				ieee->pairwise_key_type = KEY_TYPE_WEP40;
+			EnableHWSecurityConfig8192(dev);
+
+			setKey( dev,
+				key_idx,                //EntryNo
+				key_idx,                //KeyIndex
+				KEY_TYPE_WEP40,         //KeyType
+				zero_addr[key_idx],
+				0,                      //DefaultKey
+				hwkey);                 //KeyContent
+
+		}
+
+		else if(wrqu->encoding.length==0xd){
+				ieee->pairwise_key_type = KEY_TYPE_WEP104;
+				EnableHWSecurityConfig8192(dev);
+
+			setKey( dev,
+				key_idx,                //EntryNo
+				key_idx,                //KeyIndex
+				KEY_TYPE_WEP104,        //KeyType
+				zero_addr[key_idx],
+				0,                      //DefaultKey
+				hwkey);                 //KeyContent
+
+		}
+		else printk("wrong type in WEP, not WEP40 and WEP104\n");
+
+	}
+
+	return ret;
+}
+
+
+static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
+ iwreq_data *wrqu, char *p){
+
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	int *parms=(int*)p;
+	int mode=parms[0];
+
+	priv->ieee80211->active_scan = mode;
+
+	return 1;
+}
+
+
+
+static int r8192_wx_set_retry(struct net_device *dev,
+				struct iw_request_info *info,
+				union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	int err = 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
+	 */
+
+	rtl8192_commit(dev);
+	/*
+	if(priv->up){
+		rtl8180_rtx_disable(dev);
+		rtl8180_rx_enable(dev);
+		rtl8180_tx_enable(dev);
+
+	}
+	*/
+exit:
+	up(&priv->wx_sem);
+
+	return err;
+}
+
+static int r8192_wx_get_retry(struct net_device *dev,
+				struct iw_request_info *info,
+				union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_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;
+	}
+	//printk("returning %d",wrqu->retry.value);
+
+
+	return 0;
+}
+
+static int r8192_wx_get_sens(struct net_device *dev,
+				struct iw_request_info *info,
+				union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_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 r8192_wx_set_sens(struct net_device *dev,
+				struct iw_request_info *info,
+				union iwreq_data *wrqu, char *extra)
+{
+
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	short err = 0;
+	down(&priv->wx_sem);
+	//DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
+	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;
+}
+
+#if (WIRELESS_EXT >= 18)
+//hw security need to reorganized.
+static int r8192_wx_set_enc_ext(struct net_device *dev,
+					struct iw_request_info *info,
+					union iwreq_data *wrqu, char *extra)
+{
+	int ret=0;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_device* ieee = priv->ieee80211;
+	//printk("===>%s()\n", __FUNCTION__);
+
+
+	down(&priv->wx_sem);
+	ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
+
+	{
+		u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
+		u8 zero[6] = {0};
+		u32 key[4] = {0};
+		struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+		struct iw_point *encoding = &wrqu->encoding;
+		u8 idx = 0, alg = 0, group = 0;
+		if ((encoding->flags & IW_ENCODE_DISABLED) ||
+		ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01
+			goto end_hw_sec;
+
+		alg =  (ext->alg == IW_ENCODE_ALG_CCMP)?KEY_TYPE_CCMP:ext->alg; // as IW_ENCODE_ALG_CCMP is defined to be 3 and KEY_TYPE_CCMP is defined to 4;
+		idx = encoding->flags & IW_ENCODE_INDEX;
+		if (idx)
+			idx --;
+		group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
+
+		if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg ==  KEY_TYPE_WEP40))
+		{
+			if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) )
+				alg = KEY_TYPE_WEP104;
+			ieee->pairwise_key_type = alg;
+			EnableHWSecurityConfig8192(dev);
+		}
+		memcpy((u8*)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
+
+		if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) )
+		{
+
+			setKey( dev,
+					idx,//EntryNo
+					idx, //KeyIndex
+					alg,  //KeyType
+					zero, //MacAddr
+					0,              //DefaultKey
+					key);           //KeyContent
+		}
+		else if (group)
+		{
+			ieee->group_key_type = alg;
+			setKey( dev,
+					idx,//EntryNo
+					idx, //KeyIndex
+					alg,  //KeyType
+					broadcast_addr, //MacAddr
+					0,              //DefaultKey
+					key);           //KeyContent
+		}
+		else //pairwise key
+		{
+			setKey( dev,
+					4,//EntryNo
+					idx, //KeyIndex
+					alg,  //KeyType
+					(u8*)ieee->ap_mac_addr, //MacAddr
+					0,              //DefaultKey
+					key);           //KeyContent
+		}
+
+
+	}
+
+end_hw_sec:
+
+	up(&priv->wx_sem);
+	return ret;
+
+}
+static int r8192_wx_set_auth(struct net_device *dev,
+					struct iw_request_info *info,
+					union iwreq_data *data, char *extra)
+{
+	int ret=0;
+	//printk("====>%s()\n", __FUNCTION__);
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	down(&priv->wx_sem);
+	ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
+	up(&priv->wx_sem);
+	return ret;
+}
+
+static int r8192_wx_set_mlme(struct net_device *dev,
+					struct iw_request_info *info,
+					union iwreq_data *wrqu, char *extra)
+{
+	//printk("====>%s()\n", __FUNCTION__);
+
+	int ret=0;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	down(&priv->wx_sem);
+	ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
+
+	up(&priv->wx_sem);
+	return ret;
+}
+#endif
+static int r8192_wx_set_gen_ie(struct net_device *dev,
+					struct iw_request_info *info,
+					union iwreq_data *data, char *extra)
+{
+	   //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
+	int ret=0;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	down(&priv->wx_sem);
+	ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
+	up(&priv->wx_sem);
+	//printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
+	return ret;
+
+
+}
+
+static int dummy(struct net_device *dev, struct iw_request_info *a,
+		 union iwreq_data *wrqu,char *b)
+{
+	return -1;
+}
+
+
+static iw_handler r8192_wx_handlers[] =
+{
+	NULL,                     /* SIOCSIWCOMMIT */
+	r8192_wx_get_name,   	  /* SIOCGIWNAME */
+	dummy,                    /* SIOCSIWNWID */
+	dummy,                    /* SIOCGIWNWID */
+	r8192_wx_set_freq,        /* SIOCSIWFREQ */
+	r8192_wx_get_freq,        /* SIOCGIWFREQ */
+	r8192_wx_set_mode,        /* SIOCSIWMODE */
+	r8192_wx_get_mode,        /* SIOCGIWMODE */
+	r8192_wx_set_sens,        /* SIOCSIWSENS */
+	r8192_wx_get_sens,        /* SIOCGIWSENS */
+	NULL,                     /* SIOCSIWRANGE */
+	rtl8180_wx_get_range,	  /* SIOCGIWRANGE */
+	NULL,                     /* SIOCSIWPRIV */
+	NULL,                     /* SIOCGIWPRIV */
+	NULL,                     /* SIOCSIWSTATS */
+	NULL,                     /* SIOCGIWSTATS */
+	dummy,                    /* SIOCSIWSPY */
+	dummy,                    /* SIOCGIWSPY */
+	NULL,                     /* SIOCGIWTHRSPY */
+	NULL,                     /* SIOCWIWTHRSPY */
+	r8192_wx_set_wap,      	  /* SIOCSIWAP */
+	r8192_wx_get_wap,         /* SIOCGIWAP */
+#if (WIRELESS_EXT >= 18)
+	r8192_wx_set_mlme,                     /* MLME-- */
+#else
+	 NULL,
+#endif
+	dummy,                     /* SIOCGIWAPLIST -- depricated */
+	r8192_wx_set_scan,        /* SIOCSIWSCAN */
+	r8192_wx_get_scan,        /* SIOCGIWSCAN */
+	r8192_wx_set_essid,       /* SIOCSIWESSID */
+	r8192_wx_get_essid,       /* SIOCGIWESSID */
+	dummy,                    /* SIOCSIWNICKN */
+	dummy,                    /* SIOCGIWNICKN */
+	NULL,                     /* -- hole -- */
+	NULL,                     /* -- hole -- */
+	r8192_wx_set_rate,        /* SIOCSIWRATE */
+	r8192_wx_get_rate,        /* SIOCGIWRATE */
+	r8192_wx_set_rts,                    /* SIOCSIWRTS */
+	r8192_wx_get_rts,                    /* SIOCGIWRTS */
+	r8192_wx_set_frag,        /* SIOCSIWFRAG */
+	r8192_wx_get_frag,        /* SIOCGIWFRAG */
+	dummy,                    /* SIOCSIWTXPOW */
+	dummy,                    /* SIOCGIWTXPOW */
+	r8192_wx_set_retry,       /* SIOCSIWRETRY */
+	r8192_wx_get_retry,       /* SIOCGIWRETRY */
+	r8192_wx_set_enc,         /* SIOCSIWENCODE */
+	r8192_wx_get_enc,         /* SIOCGIWENCODE */
+	r8192_wx_set_power,                    /* SIOCSIWPOWER */
+	r8192_wx_get_power,                    /* SIOCGIWPOWER */
+	NULL,			/*---hole---*/
+	NULL, 			/*---hole---*/
+	r8192_wx_set_gen_ie,//NULL, 			/* SIOCSIWGENIE */
+	NULL, 			/* SIOCSIWGENIE */
+
+#if (WIRELESS_EXT >= 18)
+	r8192_wx_set_auth,//NULL, 			/* SIOCSIWAUTH */
+	NULL,//r8192_wx_get_auth,//NULL, 			/* SIOCSIWAUTH */
+	r8192_wx_set_enc_ext, 			/* SIOCSIWENCODEEXT */
+	NULL,//r8192_wx_get_enc_ext,//NULL, 			/* SIOCSIWENCODEEXT */
+#else
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+#endif
+	NULL, 			/* SIOCSIWPMKSA */
+	NULL, 			 /*---hole---*/
+
+};
+
+
+static const struct iw_priv_args r8192_private_args[] = {
+
+	{
+		SIOCIWFIRSTPRIV + 0x0,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
+	},
+
+	{
+		SIOCIWFIRSTPRIV + 0x1,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
+
+	},
+	{
+		SIOCIWFIRSTPRIV + 0x2,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
+	}
+#ifdef JOHN_IOCTL
+	,
+	{
+		SIOCIWFIRSTPRIV + 0x3,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF"
+	}
+	,
+	{
+		SIOCIWFIRSTPRIV + 0x4,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF"
+	}
+	,
+	{
+		SIOCIWFIRSTPRIV + 0x5,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
+	}
+	,
+	{
+		SIOCIWFIRSTPRIV + 0x6,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
+	}
+	,
+	{
+		SIOCIWFIRSTPRIV + 0x7,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
+	}
+	,
+	{
+		SIOCIWFIRSTPRIV + 0x8,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
+	}
+	,
+	{
+		SIOCIWFIRSTPRIV + 0x9,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
+	}
+
+#endif
+	,
+	{
+		SIOCIWFIRSTPRIV + 0x3,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
+
+	}
+
+};
+
+
+static iw_handler r8192_private_handler[] = {
+//	r8192_wx_set_monitor,  /* SIOCIWFIRSTPRIV */
+	r8192_wx_set_crcmon,   /*SIOCIWSECONDPRIV*/
+//	r8192_wx_set_forceassociate,
+//	r8192_wx_set_beaconinterval,
+//	r8192_wx_set_monitor_type,
+	r8192_wx_set_scan_type,
+	r8192_wx_set_rawtx,
+#ifdef JOHN_IOCTL
+	r8192_wx_read_regs,
+	r8192_wx_write_regs,
+	r8192_wx_read_bb,
+	r8192_wx_write_bb,
+	r8192_wx_read_nicb,
+	r8192_wx_write_nicb,
+	r8192_wx_get_ap_status,
+#endif
+	//r8192_wx_null,
+	r8192_wx_force_reset,
+};
+
+//#if WIRELESS_EXT >= 17
+struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
+{
+       struct r8192_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.rssi;
+	tmp_qual = (&ieee->current_network)->stats.signal;
+	tmp_noise = (&ieee->current_network)->stats.noise;
+	//printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_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;
+}
+//#endif
+
+
+struct iw_handler_def  r8192_wx_handlers_def={
+	.standard = r8192_wx_handlers,
+	.num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler),
+	.private = r8192_private_handler,
+	.num_private = sizeof(r8192_private_handler) / sizeof(iw_handler),
+	.num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
+#if WIRELESS_EXT >= 17
+	.get_wireless_stats = r8192_get_wireless_stats,
+#endif
+	.private_args = (struct iw_priv_args *)r8192_private_args,
+};
diff --git a/drivers/staging/rtl8192u/r8192U_wx.h b/drivers/staging/rtl8192u/r8192U_wx.h
new file mode 100644
index 0000000..b2f7a57
--- /dev/null
+++ b/drivers/staging/rtl8192u/r8192U_wx.h
@@ -0,0 +1,23 @@
+/*
+	This is part of rtl8180 OpenSource driver - v 0.3
+	Copyright (C) Andrea Merello 2004  <andreamrl@tiscali.it>
+	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 file (will) contains wireless extension handlers*/
+
+#ifndef R8180_WX_H
+#define R8180_WX_H
+//#include <linux/wireless.h>
+//#include "ieee80211.h"
+extern struct iw_handler_def r8192_wx_handlers_def;
+/* Enable  the rtl819x_core.c to share this function, david 2008.9.22 */
+extern struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev);
+
+#endif
diff --git a/drivers/staging/rtl8192u/r819xU_HTGen.h b/drivers/staging/rtl8192u/r819xU_HTGen.h
new file mode 100644
index 0000000..f37b6d6
--- /dev/null
+++ b/drivers/staging/rtl8192u/r819xU_HTGen.h
@@ -0,0 +1,13 @@
+//
+// IOT Action for different AP
+//
+typedef enum _HT_IOT_ACTION{
+	HT_IOT_ACT_TX_USE_AMSDU_4K = 0x00000001,
+	HT_IOT_ACT_TX_USE_AMSDU_8K = 0x00000002,
+	HT_IOT_ACT_DECLARE_MCS13 = 0x00000004,
+	HT_IOT_ACT_DISABLE_EDCA_TURBO = 0x00000008,
+	HT_IOT_ACT_MGNT_USE_CCK_6M = 0x00000010,
+	HT_IOT_ACT_CDD_FSYNC = 0x00000020,
+	HT_IOT_ACT_PURE_N_MODE = 0x00000040,
+}HT_IOT_ACTION_E, *PHT_IOT_ACTION_E;
+
diff --git a/drivers/staging/rtl8192u/r819xU_HTType.h b/drivers/staging/rtl8192u/r819xU_HTType.h
new file mode 100644
index 0000000..01f58b9
--- /dev/null
+++ b/drivers/staging/rtl8192u/r819xU_HTType.h
@@ -0,0 +1,391 @@
+#ifndef _R819XU_HTTYPE_H_
+#define _R819XU_HTTYPE_H_
+
+
+//------------------------------------------------------------
+// The HT Capability element is present in beacons, association request,
+//	reassociation request and probe response frames
+//------------------------------------------------------------
+
+//
+// Operation mode value
+//
+#define HT_OPMODE_NO_PROTECT		0
+#define HT_OPMODE_OPTIONAL		1
+#define HT_OPMODE_40MHZ_PROTECT	2
+#define HT_OPMODE_MIXED			3
+
+//
+// MIMO Power Save Setings
+//
+#define MIMO_PS_STATIC				0
+#define MIMO_PS_DYNAMIC			1
+#define MIMO_PS_NOLIMIT			3
+
+
+//
+//	There should be 128 bits to cover all of the MCS rates. However, since
+//	8190 does not support too much rates, one integer is quite enough.
+//
+
+#define sHTCLng	4
+
+
+#define HT_SUPPORTED_MCS_1SS_BITMAP					0x000000ff
+#define HT_SUPPORTED_MCS_2SS_BITMAP					0x0000ff00
+#define HT_SUPPORTED_MCS_1SS_2SS_BITMAP			HT_MCS_1SS_BITMAP|HT_MCS_1SS_2SS_BITMAP
+
+
+typedef enum _HT_MCS_RATE{
+	HT_MCS0   = 0x00000001,
+	HT_MCS1   = 0x00000002,
+	HT_MCS2   = 0x00000004,
+	HT_MCS3   = 0x00000008,
+	HT_MCS4   = 0x00000010,
+	HT_MCS5   = 0x00000020,
+	HT_MCS6   = 0x00000040,
+	HT_MCS7   = 0x00000080,
+	HT_MCS8   = 0x00000100,
+	HT_MCS9   = 0x00000200,
+	HT_MCS10 = 0x00000400,
+	HT_MCS11 = 0x00000800,
+	HT_MCS12 = 0x00001000,
+	HT_MCS13 = 0x00002000,
+	HT_MCS14 = 0x00004000,
+	HT_MCS15 = 0x00008000,
+	// Do not define MCS32 here although 8190 support MCS32
+}HT_MCS_RATE,*PHT_MCS_RATE;
+
+//
+// Represent Channel Width in HT Capabilities
+//
+typedef enum _HT_CHANNEL_WIDTH{
+	HT_CHANNEL_WIDTH_20 = 0,
+	HT_CHANNEL_WIDTH_20_40 = 1,
+}HT_CHANNEL_WIDTH, *PHT_CHANNEL_WIDTH;
+
+//
+// Represent Extention Channel Offset in HT Capabilities
+// This is available only in 40Mhz mode.
+//
+typedef enum _HT_EXTCHNL_OFFSET{
+	HT_EXTCHNL_OFFSET_NO_EXT = 0,
+	HT_EXTCHNL_OFFSET_UPPER = 1,
+	HT_EXTCHNL_OFFSET_NO_DEF = 2,
+	HT_EXTCHNL_OFFSET_LOWER = 3,
+}HT_EXTCHNL_OFFSET, *PHT_EXTCHNL_OFFSET;
+
+typedef enum _CHNLOP{
+	CHNLOP_NONE = 0, // No Action now
+	CHNLOP_SCAN = 1, // Scan in progress
+	CHNLOP_SWBW = 2, // Bandwidth switching in progress
+	CHNLOP_SWCHNL = 3, // Software Channel switching in progress
+} CHNLOP, *PCHNLOP;
+
+// Determine if the Channel Operation is in progress
+#define CHHLOP_IN_PROGRESS(_pHTInfo)	\
+		((_pHTInfo)->ChnlOp > CHNLOP_NONE) ? TRUE : FALSE
+
+
+typedef enum _HT_ACTION{
+	ACT_RECOMMAND_WIDTH		= 0,
+	ACT_MIMO_PWR_SAVE 		= 1,
+	ACT_PSMP					= 2,
+	ACT_SET_PCO_PHASE		= 3,
+	ACT_MIMO_CHL_MEASURE	= 4,
+	ACT_RECIPROCITY_CORRECT	= 5,
+	ACT_MIMO_CSI_MATRICS		= 6,
+	ACT_MIMO_NOCOMPR_STEER	= 7,
+	ACT_MIMO_COMPR_STEER		= 8,
+	ACT_ANTENNA_SELECT		= 9,
+} HT_ACTION, *PHT_ACTION;
+
+
+/* 2007/06/07 MH Define sub-carrier mode for 40MHZ. */
+typedef enum _HT_Bandwidth_40MHZ_Sub_Carrier{
+	SC_MODE_DUPLICATE = 0,
+	SC_MODE_LOWER = 1,
+	SC_MODE_UPPER = 2,
+	SC_MODE_FULL40MHZ = 3,
+}HT_BW40_SC_E;
+
+typedef	struct _HT_CAPABILITY_ELE{
+
+	//HT capability info
+	u8	AdvCoding:1;
+	u8	ChlWidth:1;
+	u8	MimoPwrSave:2;
+	u8	GreenField:1;
+	u8	ShortGI20Mhz:1;
+	u8	ShortGI40Mhz:1;
+	u8	TxSTBC:1;
+	u8	RxSTBC:2;
+	u8	DelayBA:1;
+	u8	MaxAMSDUSize:1;
+	u8	DssCCk:1;
+	u8	PSMP:1;
+	u8	Rsvd1:1;
+	u8	LSigTxopProtect:1;
+
+	//MAC HT parameters info
+	u8	MaxRxAMPDUFactor:2;
+	u8	MPDUDensity:3;
+	u8	Rsvd2:3;
+
+	//Supported MCS set
+	u8	MCS[16];
+
+
+	//Extended HT Capability Info
+	u16	ExtHTCapInfo;
+
+	//TXBF Capabilities
+	u8	TxBFCap[4];
+
+	//Antenna Selection Capabilities
+	u8	ASCap;
+
+}__attribute__((packed)) HT_CAPABILITY_ELE, *PHT_CAPABILITY_ELE;
+
+//------------------------------------------------------------
+// The HT Information element is present in beacons
+// Only AP is required to include this element
+//------------------------------------------------------------
+
+typedef struct _HT_INFORMATION_ELE{
+	u8	ControlChl;
+
+	u8	ExtChlOffset:2;
+	u8	RecommemdedTxWidth:1;
+	u8	RIFS:1;
+	u8	PSMPAccessOnly:1;
+	u8	SrvIntGranularity:3;
+
+	u8	OptMode:2;
+	u8	NonGFDevPresent:1;
+	u8	Revd1:5;
+	u8	Revd2:8;
+
+	u8	Rsvd3:6;
+	u8	DualBeacon:1;
+	u8	DualCTSProtect:1;
+
+	u8	SecondaryBeacon:1;
+	u8	LSigTxopProtectFull:1;
+	u8	PcoActive:1;
+	u8	PcoPhase:1;
+	u8	Rsvd4:4;
+
+	u8	BasicMSC[16];
+}__attribute__((packed)) HT_INFORMATION_ELE, *PHT_INFORMATION_ELE;
+
+//
+// MIMO Power Save control field.
+// This is appear in MIMO Power Save Action Frame
+//
+typedef struct _MIMOPS_CTRL{
+	u8	MimoPsEnable:1;
+	u8	MimoPsMode:1;
+	u8	Reserved:6;
+} MIMOPS_CTRL, *PMIMOPS_CTRL;
+
+typedef enum _HT_SPEC_VER{
+	HT_SPEC_VER_IEEE = 0,
+	HT_SPEC_VER_EWC = 1,
+}HT_SPEC_VER, *PHT_SPEC_VER;
+
+typedef enum _HT_AGGRE_MODE_E{
+	HT_AGG_AUTO = 0,
+	HT_AGG_FORCE_ENABLE = 1,
+	HT_AGG_FORCE_DISABLE = 2,
+}HT_AGGRE_MODE_E, *PHT_AGGRE_MODE_E;
+
+//------------------------------------------------------------
+//  The Data structure is used to keep HT related variables when card is
+//  configured as non-AP STA mode.  **Note**  Current_xxx should be set
+//	to default value in HTInitializeHTInfo()
+//------------------------------------------------------------
+
+typedef struct _RT_HIGH_THROUGHPUT{
+//	DECLARE_RT_OBJECT(_RT_HIGH_THROUGHPUT);
+	u8				bEnableHT;
+	u8				bCurrentHTSupport;
+
+	u8				bRegBW40MHz;				// Tx 40MHz channel capablity
+	u8				bCurBW40MHz;				// Tx 40MHz channel capability
+
+	u8				bRegShortGI40MHz;			// Tx Short GI for 40Mhz
+	u8				bCurShortGI40MHz;			// Tx Short GI for 40MHz
+
+	u8				bRegShortGI20MHz;			// Tx Short GI for 20MHz
+	u8				bCurShortGI20MHz;			// Tx Short GI for 20MHz
+
+	u8				bRegSuppCCK;				// Tx CCK rate capability
+	u8				bCurSuppCCK;				// Tx CCK rate capability
+
+	// 802.11n spec version for "peer"
+	HT_SPEC_VER			ePeerHTSpecVer;
+
+
+	// HT related information for "Self"
+	HT_CAPABILITY_ELE	SelfHTCap;					// This is HT cap element sent to peer STA, which also indicate HT Rx capabilities.
+	HT_INFORMATION_ELE	SelfHTInfo;					// This is HT info element sent to peer STA, which also indicate HT Rx capabilities.
+
+	// HT related information for "Peer"
+	u8				PeerHTCapBuf[32];
+	u8				PeerHTInfoBuf[32];
+
+
+	// A-MSDU related
+	u8				bAMSDU_Support;			// This indicates Tx A-MSDU capability
+	u16				nAMSDU_MaxSize;			// This indicates Tx A-MSDU capability
+	u8				bCurrent_AMSDU_Support;	// This indicates Tx A-MSDU capability
+	u16				nCurrent_AMSDU_MaxSize;	// This indicates Tx A-MSDU capability
+
+
+	// AMPDU  related <2006.08.10 Emily>
+	u8				bAMPDUEnable;				// This indicate Tx A-MPDU capability
+	u8				bCurrentAMPDUEnable;		// This indicate Tx A-MPDU capability
+	u8				AMPDU_Factor;				// This indicate Tx A-MPDU capability
+	u8				CurrentAMPDUFactor;		// This indicate Tx A-MPDU capability
+	u8				MPDU_Density;				// This indicate Tx A-MPDU capability
+	u8				CurrentMPDUDensity;			// This indicate Tx A-MPDU capability
+
+	// Forced A-MPDU enable
+	HT_AGGRE_MODE_E	ForcedAMPDUMode;
+	u8				ForcedAMPDUFactor;
+	u8				ForcedMPDUDensity;
+
+	// Forced A-MSDU enable
+	HT_AGGRE_MODE_E	ForcedAMSDUMode;
+	u16				ForcedAMSDUMaxSize;
+
+	u8				bForcedShortGI;
+
+	u8				CurrentOpMode;
+
+	// MIMO PS related
+	u8				SelfMimoPs;
+	u8				PeerMimoPs;
+
+	// 40MHz Channel Offset settings.
+	HT_EXTCHNL_OFFSET	CurSTAExtChnlOffset;
+	u8				bCurTxBW40MHz;	// If we use 40 MHz to Tx
+	u8				PeerBandwidth;
+
+	// For Bandwidth Switching
+	u8				bSwBwInProgress;
+	CHNLOP				ChnlOp; // software switching channel in progress. By Bruce, 2008-02-15.
+	u8				SwBwStep;
+	//RT_TIMER			SwBwTimer;
+	struct timer_list		SwBwTimer;
+
+	// For Realtek proprietary A-MPDU factor for aggregation
+	u8				bRegRT2RTAggregation;
+	u8				bCurrentRT2RTAggregation;
+	u8				bCurrentRT2RTLongSlotTime;
+	u8				szRT2RTAggBuffer[10];
+
+	// Rx Reorder control
+	u8				bRegRxReorderEnable;
+	u8				bCurRxReorderEnable;
+	u8				RxReorderWinSize;
+	u8				RxReorderPendingTime;
+	u16				RxReorderDropCounter;
+
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+	u8				UsbTxAggrNum;
+#endif
+#ifdef USB_RX_AGGREGATION_SUPPORT
+	u8				UsbRxFwAggrEn;
+	u8				UsbRxFwAggrPageNum;
+	u8				UsbRxFwAggrPacketNum;
+	u8				UsbRxFwAggrTimeout;
+#endif
+
+	// Add for Broadcom(Linksys) IOT. Joseph
+	u8				bIsPeerBcm;
+
+	// For IOT issue.
+	u32					IOTAction;
+}RT_HIGH_THROUGHPUT, *PRT_HIGH_THROUGHPUT;
+
+
+//------------------------------------------------------------
+// The Data structure is used to keep HT related variable for "each Sta"
+// when card is configured as "AP mode"
+//------------------------------------------------------------
+
+typedef struct _RT_HTINFO_STA_ENTRY{
+	u8			bEnableHT;
+
+	u8			bSupportCck;
+
+	u16			AMSDU_MaxSize;
+
+	u8			AMPDU_Factor;
+	u8			MPDU_Density;
+
+	u8			HTHighestOperaRate;
+
+	u8			bBw40MHz;
+
+	u8			MimoPs;
+
+	u8			McsRateSet[16];
+
+
+}RT_HTINFO_STA_ENTRY, *PRT_HTINFO_STA_ENTRY;
+
+
+
+
+
+//------------------------------------------------------------
+// The Data structure is used to keep HT related variable for "each AP"
+// when card is configured as "STA mode"
+//------------------------------------------------------------
+
+typedef struct _BSS_HT{
+
+	u8				bdSupportHT;
+
+	// HT related elements
+	u8					bdHTCapBuf[32];
+	u16					bdHTCapLen;
+	u8					bdHTInfoBuf[32];
+	u16					bdHTInfoLen;
+
+	HT_SPEC_VER				bdHTSpecVer;
+	//HT_CAPABILITY_ELE			bdHTCapEle;
+	//HT_INFORMATION_ELE		bdHTInfoEle;
+
+	u8					bdRT2RTAggregation;
+	u8					bdRT2RTLongSlotTime;
+}BSS_HT, *PBSS_HT;
+
+typedef struct _MIMO_RSSI{
+	u32	EnableAntenna;
+	u32	AntennaA;
+	u32 	AntennaB;
+	u32 	AntennaC;
+	u32 	AntennaD;
+	u32	Average;
+}MIMO_RSSI, *PMIMO_RSSI;
+
+typedef struct _MIMO_EVM{
+	u32	EVM1;
+	u32    EVM2;
+}MIMO_EVM, *PMIMO_EVM;
+
+typedef struct _FALSE_ALARM_STATISTICS{
+	u32	Cnt_Parity_Fail;
+	u32    Cnt_Rate_Illegal;
+	u32	Cnt_Crc8_fail;
+	u32	Cnt_all;
+}FALSE_ALARM_STATISTICS, *PFALSE_ALARM_STATISTICS;
+
+
+
+#endif //__INC_HTTYPE_H
+
diff --git a/drivers/staging/rtl8192u/r819xU_cmdpkt.c b/drivers/staging/rtl8192u/r819xU_cmdpkt.c
new file mode 100644
index 0000000..fd19a85
--- /dev/null
+++ b/drivers/staging/rtl8192u/r819xU_cmdpkt.c
@@ -0,0 +1,791 @@
+/******************************************************************************
+
+     (c) Copyright 2008, RealTEK Technologies Inc. All Rights Reserved.
+
+ Module:	r819xusb_cmdpkt.c	(RTL8190 TX/RX command packet handler Source C File)
+
+ Note:      The module is responsible for handling TX and RX command packet.
+			1. TX : Send set and query configuration command packet.
+			2. RX : Receive tx feedback, beacon state, query configuration
+				command packet.
+
+ Function:
+
+ Export:
+
+ Abbrev:
+
+ History:
+	Data		Who		Remark
+
+	05/06/2008  amy    	Create initial version porting from windows driver.
+
+******************************************************************************/
+#include "r8192U.h"
+#include "r819xU_cmdpkt.h"
+/*---------------------------Define Local Constant---------------------------*/
+/* Debug constant*/
+#define		CMPK_DEBOUNCE_CNT			1
+/* 2007/10/24 MH Add for printing a range of data. */
+#define		CMPK_PRINT(Address)\
+{\
+	unsigned char	i;\
+	u32	temp[10];\
+	\
+	memcpy(temp, Address, 40);\
+	for (i = 0; i <40; i+=4)\
+		printk("\r\n %08x", temp[i]);\
+}\
+/*---------------------------Define functions---------------------------------*/
+
+rt_status
+SendTxCommandPacket(
+	struct net_device *dev,
+	void* 			pData,
+	u32				DataLen
+	)
+{
+	rt_status	rtStatus = RT_STATUS_SUCCESS;
+	struct r8192_priv   *priv = ieee80211_priv(dev);
+	struct sk_buff	    *skb;
+	cb_desc		    *tcb_desc;
+	unsigned char	    *ptr_buf;
+	//bool	bLastInitPacket = false;
+
+	//PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
+
+	//Get TCB and local buffer from common pool. (It is shared by CmdQ, MgntQ, and USB coalesce DataQ)
+	skb  = dev_alloc_skb(USB_HWDESC_HEADER_LEN + DataLen + 4);
+	memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
+	tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE);
+	tcb_desc->queue_index = TXCMD_QUEUE;
+	tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_NORMAL;
+	tcb_desc->bLastIniPkt = 0;
+	skb_reserve(skb, USB_HWDESC_HEADER_LEN);
+	ptr_buf = skb_put(skb, DataLen);
+	memset(ptr_buf,0,DataLen);
+	memcpy(ptr_buf,pData,DataLen);
+	tcb_desc->txbuf_size= (u16)DataLen;
+
+	if(!priv->ieee80211->check_nic_enough_desc(dev,tcb_desc->queue_index)||
+			(!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index]))||\
+			(priv->ieee80211->queue_stop) ) {
+			RT_TRACE(COMP_FIRMWARE,"===================NULL packet==================================> tx full!\n");
+			skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb);
+		} else {
+			priv->ieee80211->softmac_hard_start_xmit(skb,dev);
+		}
+
+	//PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
+	return rtStatus;
+}
+
+/*-----------------------------------------------------------------------------
+ * Function:	cmpk_message_handle_tx()
+ *
+ * Overview:	Driver internal module can call the API to send message to
+ *				firmware side. For example, you can send a debug command packet.
+ *				Or you can send a request for FW to modify RLX4181 LBUS HW bank.
+ *				Otherwise, you can change MAC/PHT/RF register by firmware at
+ *				run time. We do not support message more than one segment now.
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/06/2008	amy		porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+ extern	rt_status	cmpk_message_handle_tx(
+	struct net_device *dev,
+	u8*	codevirtualaddress,
+	u32	packettype,
+	u32	buffer_len)
+{
+
+	bool 	    rt_status = true;
+#ifdef RTL8192U
+	return rt_status;
+#else
+	struct r8192_priv   *priv = ieee80211_priv(dev);
+	u16		    frag_threshold;
+	u16		    frag_length, frag_offset = 0;
+	//u16		    total_size;
+	//int		    i;
+
+	rt_firmware	    *pfirmware = priv->pFirmware;
+	struct sk_buff	    *skb;
+	unsigned char	    *seg_ptr;
+	cb_desc		    *tcb_desc;
+	u8                  bLastIniPkt;
+
+	firmware_init_param(dev);
+	//Fragmentation might be required
+	frag_threshold = pfirmware->cmdpacket_frag_thresold;
+	do {
+		if((buffer_len - frag_offset) > frag_threshold) {
+			frag_length = frag_threshold ;
+			bLastIniPkt = 0;
+
+		} else {
+			frag_length = buffer_len - frag_offset;
+			bLastIniPkt = 1;
+
+		}
+
+		/* Allocate skb buffer to contain firmware info and tx descriptor info
+		 * add 4 to avoid packet appending overflow.
+		 * */
+		#ifdef RTL8192U
+		skb  = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4);
+		#else
+		skb  = dev_alloc_skb(frag_length + 4);
+		#endif
+		memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
+		tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE);
+		tcb_desc->queue_index = TXCMD_QUEUE;
+		tcb_desc->bCmdOrInit = packettype;
+		tcb_desc->bLastIniPkt = bLastIniPkt;
+
+		#ifdef RTL8192U
+		skb_reserve(skb, USB_HWDESC_HEADER_LEN);
+		#endif
+
+		seg_ptr = skb_put(skb, buffer_len);
+		/*
+		 * Transform from little endian to big endian
+		 * and pending  zero
+		 */
+		memcpy(seg_ptr,codevirtualaddress,buffer_len);
+		tcb_desc->txbuf_size= (u16)buffer_len;
+
+
+		if(!priv->ieee80211->check_nic_enough_desc(dev,tcb_desc->queue_index)||
+			(!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index]))||\
+			(priv->ieee80211->queue_stop) ) {
+			RT_TRACE(COMP_FIRMWARE,"=====================================================> tx full!\n");
+			skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb);
+		} else {
+			priv->ieee80211->softmac_hard_start_xmit(skb,dev);
+		}
+
+		codevirtualaddress += frag_length;
+		frag_offset += frag_length;
+
+	}while(frag_offset < buffer_len);
+
+	return rt_status;
+
+
+#endif
+}	/* CMPK_Message_Handle_Tx */
+
+/*-----------------------------------------------------------------------------
+ * Function:    cmpk_counttxstatistic()
+ *
+ * Overview:
+ *
+ * Input:       PADAPTER 	pAdapter		-	.
+ *				CMPK_TXFB_T *psTx_FB	-	.
+ *
+ * Output:      NONE
+ *
+ * Return:      NONE
+ *
+ * Revised History:
+ *  When		Who		Remark
+ *  05/12/2008	amy 	Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static	void
+cmpk_count_txstatistic(
+	struct net_device *dev,
+	cmpk_txfb_t	*pstx_fb)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+#ifdef ENABLE_PS
+	RT_RF_POWER_STATE	rtState;
+
+	pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
+
+	// When RF is off, we should not count the packet for hw/sw synchronize
+	// reason, ie. there may be a duration while sw switch is changed and hw
+	// switch is being changed. 2006.12.04, by shien chang.
+	if (rtState == eRfOff)
+	{
+		return;
+	}
+#endif
+
+#ifdef TODO
+	if(pAdapter->bInHctTest)
+		return;
+#endif
+	/* We can not know the packet length and transmit type: broadcast or uni
+	   or multicast. So the relative statistics must be collected in tx
+	   feedback info. */
+	if (pstx_fb->tok)
+	{
+		priv->stats.txfeedbackok++;
+		priv->stats.txoktotal++;
+		priv->stats.txokbytestotal += pstx_fb->pkt_length;
+		priv->stats.txokinperiod++;
+
+		/* We can not make sure broadcast/multicast or unicast mode. */
+		if (pstx_fb->pkt_type == PACKET_MULTICAST)
+		{
+			priv->stats.txmulticast++;
+			priv->stats.txbytesmulticast += pstx_fb->pkt_length;
+		}
+		else if (pstx_fb->pkt_type == PACKET_BROADCAST)
+		{
+			priv->stats.txbroadcast++;
+			priv->stats.txbytesbroadcast += pstx_fb->pkt_length;
+		}
+		else
+		{
+			priv->stats.txunicast++;
+			priv->stats.txbytesunicast += pstx_fb->pkt_length;
+		}
+	}
+	else
+	{
+		priv->stats.txfeedbackfail++;
+		priv->stats.txerrtotal++;
+		priv->stats.txerrbytestotal += pstx_fb->pkt_length;
+
+		/* We can not make sure broadcast/multicast or unicast mode. */
+		if (pstx_fb->pkt_type == PACKET_MULTICAST)
+		{
+			priv->stats.txerrmulticast++;
+		}
+		else if (pstx_fb->pkt_type == PACKET_BROADCAST)
+		{
+			priv->stats.txerrbroadcast++;
+		}
+		else
+		{
+			priv->stats.txerrunicast++;
+		}
+	}
+
+	priv->stats.txretrycount += pstx_fb->retry_cnt;
+	priv->stats.txfeedbackretry += pstx_fb->retry_cnt;
+
+}	/* cmpk_CountTxStatistic */
+
+
+
+/*-----------------------------------------------------------------------------
+ * Function:    cmpk_handle_tx_feedback()
+ *
+ * Overview:	The function is responsible for extract the message inside TX
+ *				feedbck message from firmware. It will contain dedicated info in
+ *				ws-06-0063-rtl8190-command-packet-specification. Please
+ *				refer to chapter "TX Feedback Element". We have to read 20 bytes
+ *				in the command packet.
+ *
+ * Input:       struct net_device *    dev
+ *				u8 	*	pmsg		-	Msg Ptr of the command packet.
+ *
+ * Output:      NONE
+ *
+ * Return:      NONE
+ *
+ * Revised History:
+ *  When		Who		Remark
+ *  05/08/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static	void
+cmpk_handle_tx_feedback(
+	struct net_device *dev,
+	u8	*	pmsg)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	cmpk_txfb_t		rx_tx_fb;	/* */
+
+	priv->stats.txfeedback++;
+
+	/* 0. Display received message. */
+	//cmpk_Display_Message(CMPK_RX_TX_FB_SIZE, pMsg);
+
+	/* 1. Extract TX feedback info from RFD to temp structure buffer. */
+	/* It seems that FW use big endian(MIPS) and DRV use little endian in
+	   windows OS. So we have to read the content byte by byte or transfer
+	   endian type before copy the message copy. */
+	/* 2007/07/05 MH Use pointer to transfer structure memory. */
+	//memcpy((UINT8 *)&rx_tx_fb, pMsg, sizeof(CMPK_TXFB_T));
+	memcpy((u8*)&rx_tx_fb, pmsg, sizeof(cmpk_txfb_t));
+	/* 2. Use tx feedback info to count TX statistics. */
+	cmpk_count_txstatistic(dev, &rx_tx_fb);
+	/* 2007/01/17 MH Comment previous method for TX statistic function. */
+	/* Collect info TX feedback packet to fill TCB. */
+	/* We can not know the packet length and transmit type: broadcast or uni
+	   or multicast. */
+	//CountTxStatistics( pAdapter, &tcb );
+
+}	/* cmpk_Handle_Tx_Feedback */
+
+void
+cmdpkt_beacontimerinterrupt_819xusb(
+	struct net_device *dev
+)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u16 tx_rate;
+	{
+		//
+		// 070117, rcnjko: 87B have to S/W beacon for DTM encryption_cmn.
+		//
+		if(priv->ieee80211->current_network.mode == IEEE_A  ||
+			priv->ieee80211->current_network.mode == IEEE_N_5G ||
+			(priv->ieee80211->current_network.mode == IEEE_N_24G  && (!priv->ieee80211->pHTInfo->bCurSuppCCK)))
+		{
+			tx_rate = 60;
+			DMESG("send beacon frame  tx rate is 6Mbpm\n");
+		}
+		else
+		{
+			tx_rate =10;
+			DMESG("send beacon frame  tx rate is 1Mbpm\n");
+		}
+
+		rtl819xusb_beacon_tx(dev,tx_rate); // HW Beacon
+
+	}
+
+}
+
+
+
+
+/*-----------------------------------------------------------------------------
+ * Function:    cmpk_handle_interrupt_status()
+ *
+ * Overview:    The function is responsible for extract the message from
+ *				firmware. It will contain dedicated info in
+ *				ws-07-0063-v06-rtl819x-command-packet-specification-070315.doc.
+ * 				Please refer to chapter "Interrupt Status Element".
+ *
+ * Input:       struct net_device *dev,
+ *			u8*	pmsg		-	Message Pointer of the command packet.
+ *
+ * Output:      NONE
+ *
+ * Return:      NONE
+ *
+ * Revised History:
+ *  When			Who			Remark
+ *  05/12/2008	amy		Add this for rtl8192 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static	void
+cmpk_handle_interrupt_status(
+	struct net_device *dev,
+	u8*	pmsg)
+{
+	cmpk_intr_sta_t		rx_intr_status;	/* */
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	DMESG("---> cmpk_Handle_Interrupt_Status()\n");
+
+	/* 0. Display received message. */
+	//cmpk_Display_Message(CMPK_RX_BEACON_STATE_SIZE, pMsg);
+
+	/* 1. Extract TX feedback info from RFD to temp structure buffer. */
+	/* It seems that FW use big endian(MIPS) and DRV use little endian in
+	   windows OS. So we have to read the content byte by byte or transfer
+	   endian type before copy the message copy. */
+	//rx_bcn_state.Element_ID 	= pMsg[0];
+	//rx_bcn_state.Length 		= pMsg[1];
+	rx_intr_status.length = pmsg[1];
+	if (rx_intr_status.length != (sizeof(cmpk_intr_sta_t) - 2))
+	{
+		DMESG("cmpk_Handle_Interrupt_Status: wrong length!\n");
+		return;
+	}
+
+
+	// Statistics of beacon for ad-hoc mode.
+	if(	priv->ieee80211->iw_mode == IW_MODE_ADHOC)
+	{
+		//2 maybe need endian transform?
+		rx_intr_status.interrupt_status = *((u32 *)(pmsg + 4));
+		//rx_intr_status.InterruptStatus = N2H4BYTE(*((UINT32 *)(pMsg + 4)));
+
+		DMESG("interrupt status = 0x%x\n", rx_intr_status.interrupt_status);
+
+		if (rx_intr_status.interrupt_status & ISR_TxBcnOk)
+		{
+			priv->ieee80211->bibsscoordinator = true;
+			priv->stats.txbeaconokint++;
+		}
+		else if (rx_intr_status.interrupt_status & ISR_TxBcnErr)
+		{
+			priv->ieee80211->bibsscoordinator = false;
+			priv->stats.txbeaconerr++;
+		}
+
+		if (rx_intr_status.interrupt_status & ISR_BcnTimerIntr)
+		{
+			cmdpkt_beacontimerinterrupt_819xusb(dev);
+		}
+
+	}
+
+	 // Other informations in interrupt status we need?
+
+
+	DMESG("<---- cmpk_handle_interrupt_status()\n");
+
+}	/* cmpk_handle_interrupt_status */
+
+
+/*-----------------------------------------------------------------------------
+ * Function:    cmpk_handle_query_config_rx()
+ *
+ * Overview:    The function is responsible for extract the message from
+ *				firmware. It will contain dedicated info in
+ *				ws-06-0063-rtl8190-command-packet-specification. Please
+ *				refer to chapter "Beacon State Element".
+ *
+ * Input:       u8 *  pmsg	-	Message Pointer of the command packet.
+ *
+ * Output:      NONE
+ *
+ * Return:      NONE
+ *
+ * Revised History:
+ *  When		Who		Remark
+ *  05/12/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static	void
+cmpk_handle_query_config_rx(
+	struct net_device *dev,
+	u8*	   pmsg)
+{
+	cmpk_query_cfg_t	rx_query_cfg;	/* */
+
+	/* 0. Display received message. */
+	//cmpk_Display_Message(CMPK_RX_BEACON_STATE_SIZE, pMsg);
+
+	/* 1. Extract TX feedback info from RFD to temp structure buffer. */
+	/* It seems that FW use big endian(MIPS) and DRV use little endian in
+	   windows OS. So we have to read the content byte by byte or transfer
+	   endian type before copy the message copy. */
+	//rx_query_cfg.Element_ID 	= pMsg[0];
+	//rx_query_cfg.Length 		= pMsg[1];
+	rx_query_cfg.cfg_action 	= (pmsg[4] & 0x80000000)>>31;
+	rx_query_cfg.cfg_type 		= (pmsg[4] & 0x60) >> 5;
+	rx_query_cfg.cfg_size 		= (pmsg[4] & 0x18) >> 3;
+	rx_query_cfg.cfg_page 		= (pmsg[6] & 0x0F) >> 0;
+	rx_query_cfg.cfg_offset 		= pmsg[7];
+	rx_query_cfg.value 			= (pmsg[8] << 24) | (pmsg[9] << 16) |
+								  (pmsg[10] << 8) | (pmsg[11] << 0);
+	rx_query_cfg.mask 			= (pmsg[12] << 24) | (pmsg[13] << 16) |
+								  (pmsg[14] << 8) | (pmsg[15] << 0);
+
+}	/* cmpk_Handle_Query_Config_Rx */
+
+
+/*-----------------------------------------------------------------------------
+ * Function:	cmpk_count_tx_status()
+ *
+ * Overview:	Count aggregated tx status from firmwar of one type rx command
+ *				packet element id = RX_TX_STATUS.
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/12/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static	void	cmpk_count_tx_status(	struct net_device *dev,
+									cmpk_tx_status_t 	*pstx_status)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+#ifdef ENABLE_PS
+
+	RT_RF_POWER_STATE	rtstate;
+
+	pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
+
+	// When RF is off, we should not count the packet for hw/sw synchronize
+	// reason, ie. there may be a duration while sw switch is changed and hw
+	// switch is being changed. 2006.12.04, by shien chang.
+	if (rtState == eRfOff)
+	{
+		return;
+	}
+#endif
+
+	priv->stats.txfeedbackok	+= pstx_status->txok;
+	priv->stats.txoktotal		+= pstx_status->txok;
+
+	priv->stats.txfeedbackfail	+= pstx_status->txfail;
+	priv->stats.txerrtotal		+= pstx_status->txfail;
+
+	priv->stats.txretrycount		+= pstx_status->txretry;
+	priv->stats.txfeedbackretry	+= pstx_status->txretry;
+
+	//pAdapter->TxStats.NumTxOkBytesTotal += psTx_FB->pkt_length;
+	//pAdapter->TxStats.NumTxErrBytesTotal += psTx_FB->pkt_length;
+	//pAdapter->MgntInfo.LinkDetectInfo.NumTxOkInPeriod++;
+
+	priv->stats.txmulticast	+= pstx_status->txmcok;
+	priv->stats.txbroadcast	+= pstx_status->txbcok;
+	priv->stats.txunicast		+= pstx_status->txucok;
+
+	priv->stats.txerrmulticast	+= pstx_status->txmcfail;
+	priv->stats.txerrbroadcast	+= pstx_status->txbcfail;
+	priv->stats.txerrunicast	+= pstx_status->txucfail;
+
+	priv->stats.txbytesmulticast	+= pstx_status->txmclength;
+	priv->stats.txbytesbroadcast	+= pstx_status->txbclength;
+	priv->stats.txbytesunicast		+= pstx_status->txuclength;
+
+	priv->stats.last_packet_rate		= pstx_status->rate;
+}	/* cmpk_CountTxStatus */
+
+
+
+/*-----------------------------------------------------------------------------
+ * Function:	cmpk_handle_tx_status()
+ *
+ * Overview:	Firmware add a new tx feedback status to reduce rx command
+ *				packet buffer operation load.
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/12/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static	void
+cmpk_handle_tx_status(
+	struct net_device *dev,
+	u8*	   pmsg)
+{
+	cmpk_tx_status_t	rx_tx_sts;	/* */
+
+	memcpy((void*)&rx_tx_sts, (void*)pmsg, sizeof(cmpk_tx_status_t));
+	/* 2. Use tx feedback info to count TX statistics. */
+	cmpk_count_tx_status(dev, &rx_tx_sts);
+
+}	/* cmpk_Handle_Tx_Status */
+
+
+/*-----------------------------------------------------------------------------
+ * Function:	cmpk_handle_tx_rate_history()
+ *
+ * Overview:	Firmware add a new tx rate history
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/12/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static	void
+cmpk_handle_tx_rate_history(
+	struct net_device *dev,
+	u8*	   pmsg)
+{
+	cmpk_tx_rahis_t	*ptxrate;
+//	RT_RF_POWER_STATE	rtState;
+	u8				i, j;
+	u16				length = sizeof(cmpk_tx_rahis_t);
+	u32				*ptemp;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+
+#ifdef ENABLE_PS
+	pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
+
+	// When RF is off, we should not count the packet for hw/sw synchronize
+	// reason, ie. there may be a duration while sw switch is changed and hw
+	// switch is being changed. 2006.12.04, by shien chang.
+	if (rtState == eRfOff)
+	{
+		return;
+	}
+#endif
+
+	ptemp = (u32 *)pmsg;
+
+	//
+	// Do endian transfer to word alignment(16 bits) for windows system.
+	// You must do different endian transfer for linux and MAC OS
+	//
+	for (i = 0; i < (length/4); i++)
+	{
+		u16	 temp1, temp2;
+
+		temp1 = ptemp[i]&0x0000FFFF;
+		temp2 = ptemp[i]>>16;
+		ptemp[i] = (temp1<<16)|temp2;
+	}
+
+	ptxrate = (cmpk_tx_rahis_t *)pmsg;
+
+	if (ptxrate == NULL )
+	{
+		return;
+	}
+
+	for (i = 0; i < 16; i++)
+	{
+		// Collect CCK rate packet num
+		if (i < 4)
+			priv->stats.txrate.cck[i] += ptxrate->cck[i];
+
+		// Collect OFDM rate packet num
+		if (i< 8)
+			priv->stats.txrate.ofdm[i] += ptxrate->ofdm[i];
+
+		for (j = 0; j < 4; j++)
+			priv->stats.txrate.ht_mcs[j][i] += ptxrate->ht_mcs[j][i];
+	}
+
+}	/* cmpk_Handle_Tx_Rate_History */
+
+
+/*-----------------------------------------------------------------------------
+ * Function:    cmpk_message_handle_rx()
+ *
+ * Overview:    In the function, we will capture different RX command packet
+ *				info. Every RX command packet element has different message
+ *				length and meaning in content. We only support three type of RX
+ *				command packet now. Please refer to document
+ *				ws-06-0063-rtl8190-command-packet-specification.
+ *
+ * Input:       NONE
+ *
+ * Output:      NONE
+ *
+ * Return:      NONE
+ *
+ * Revised History:
+ *  When		Who		Remark
+ *  05/06/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+extern	u32
+cmpk_message_handle_rx(
+	struct net_device *dev,
+	struct ieee80211_rx_stats *pstats)
+{
+//	u32			debug_level = DBG_LOUD;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	int			total_length;
+	u8			cmd_length, exe_cnt = 0;
+	u8			element_id;
+	u8			*pcmd_buff;
+
+	/* 0. Check inpt arguments. If is is a command queue message or pointer is
+	      null. */
+	if (/*(prfd->queue_id != CMPK_RX_QUEUE_ID) || */(pstats== NULL))
+	{
+		/* Print error message. */
+		/*RT_TRACE(COMP_SEND, DebugLevel,
+				("\n\r[CMPK]-->Err queue id or pointer"));*/
+		return 0;	/* This is not a command packet. */
+	}
+
+	/* 1. Read received command packet message length from RFD. */
+	total_length = pstats->Length;
+
+	/* 2. Read virtual address from RFD. */
+	pcmd_buff = pstats->virtual_address;
+
+	/* 3. Read command pakcet element id and length. */
+	element_id = pcmd_buff[0];
+	/*RT_TRACE(COMP_SEND, DebugLevel,
+			("\n\r[CMPK]-->element ID=%d Len=%d", element_id, total_length));*/
+
+	/* 4. Check every received command packet conent according to different
+	      element type. Because FW may aggregate RX command packet to minimize
+	      transmit time between DRV and FW.*/
+	// Add a counter to prevent to locked in the loop too long
+	while (total_length > 0 || exe_cnt++ >100)
+	{
+		/* 2007/01/17 MH We support aggregation of different cmd in the same packet. */
+		element_id = pcmd_buff[0];
+
+		switch(element_id)
+		{
+			case RX_TX_FEEDBACK:
+				cmpk_handle_tx_feedback (dev, pcmd_buff);
+				cmd_length = CMPK_RX_TX_FB_SIZE;
+				break;
+
+			case RX_INTERRUPT_STATUS:
+				cmpk_handle_interrupt_status(dev, pcmd_buff);
+				cmd_length = sizeof(cmpk_intr_sta_t);
+				break;
+
+			case BOTH_QUERY_CONFIG:
+				cmpk_handle_query_config_rx(dev, pcmd_buff);
+				cmd_length = CMPK_BOTH_QUERY_CONFIG_SIZE;
+				break;
+
+			case RX_TX_STATUS:
+				cmpk_handle_tx_status(dev, pcmd_buff);
+				cmd_length = CMPK_RX_TX_STS_SIZE;
+				break;
+
+			case RX_TX_PER_PKT_FEEDBACK:
+				// You must at lease add a switch case element here,
+				// Otherwise, we will jump to default case.
+				//DbgPrint("CCX Test\r\n");
+				cmd_length = CMPK_RX_TX_FB_SIZE;
+				break;
+
+			case RX_TX_RATE_HISTORY:
+				//DbgPrint(" rx tx rate history\r\n");
+				cmpk_handle_tx_rate_history(dev, pcmd_buff);
+				cmd_length = CMPK_TX_RAHIS_SIZE;
+				break;
+
+			default:
+
+				RT_TRACE(COMP_ERR, "---->cmpk_message_handle_rx():unknow CMD Element\n");
+				return 1;	/* This is a command packet. */
+		}
+		// 2007/01/22 MH Display received rx command packet info.
+		//cmpk_Display_Message(cmd_length, pcmd_buff);
+
+		// 2007/01/22 MH Add to display tx statistic.
+		//cmpk_DisplayTxStatistic(pAdapter);
+
+		/* 2007/03/09 MH Collect sidderent cmd element pkt num. */
+		priv->stats.rxcmdpkt[element_id]++;
+
+		total_length -= cmd_length;
+		pcmd_buff    += cmd_length;
+	}	/* while (total_length > 0) */
+	return	1;	/* This is a command packet. */
+
+}	/* CMPK_Message_Handle_Rx */
diff --git a/drivers/staging/rtl8192u/r819xU_cmdpkt.h b/drivers/staging/rtl8192u/r819xU_cmdpkt.h
new file mode 100644
index 0000000..a8855e6
--- /dev/null
+++ b/drivers/staging/rtl8192u/r819xU_cmdpkt.h
@@ -0,0 +1,207 @@
+#ifndef R819XUSB_CMDPKT_H
+#define R819XUSB_CMDPKT_H
+/* Different command packet have dedicated message length and definition. */
+#define		CMPK_RX_TX_FB_SIZE					sizeof(cmpk_txfb_t)		//20
+#define		CMPK_TX_SET_CONFIG_SIZE				sizeof(cmpk_set_cfg_t)	//16
+#define		CMPK_BOTH_QUERY_CONFIG_SIZE			sizeof(cmpk_set_cfg_t)	//16
+#define		CMPK_RX_TX_STS_SIZE					sizeof(cmpk_tx_status_t)//
+#define		CMPK_RX_DBG_MSG_SIZE			sizeof(cmpk_rx_dbginfo_t)//
+#define		CMPK_TX_RAHIS_SIZE			sizeof(cmpk_tx_rahis_t)
+
+/* 2008/05/08 amy For USB constant. */
+#define ISR_TxBcnOk					BIT27			// Transmit Beacon OK
+#define ISR_TxBcnErr				BIT26			// Transmit Beacon Error
+#define ISR_BcnTimerIntr			BIT13			// Beacon Timer Interrupt
+
+
+/* Define element ID of command packet. */
+
+/*------------------------------Define structure----------------------------*/
+/* Define different command packet structure. */
+/* 1. RX side: TX feedback packet. */
+typedef struct tag_cmd_pkt_tx_feedback
+{
+	// DWORD 0
+	u8	element_id;			/* Command packet type. */
+	u8	length;				/* Command packet length. */
+	/* 2007/07/05 MH Change tx feedback info field. */
+	/*------TX Feedback Info Field */
+	u8	TID:4;				/* */
+	u8	fail_reason:3;		/* */
+	u8	tok:1;				/* Transmit ok. */
+	u8	reserve1:4;			/* */
+	u8	pkt_type:2;		/* */
+	u8	bandwidth:1;		/* */
+	u8	qos_pkt:1;			/* */
+
+	// DWORD 1
+	u8	reserve2;			/* */
+	/*------TX Feedback Info Field */
+	u8	retry_cnt;			/* */
+	u16	pkt_id;				/* */
+
+	// DWORD 3
+	u16	seq_num;			/* */
+	u8	s_rate;				/* Start rate. */
+	u8	f_rate;				/* Final rate. */
+
+	// DWORD 4
+	u8	s_rts_rate;			/* */
+	u8	f_rts_rate;			/* */
+	u16	pkt_length;			/* */
+
+	// DWORD 5
+	u16	reserve3;			/* */
+	u16	duration;			/* */
+}cmpk_txfb_t;
+
+/* 2. RX side: Interrupt status packet. It includes Beacon State,
+	  Beacon Timer Interrupt and other useful informations in MAC ISR Reg. */
+typedef struct tag_cmd_pkt_interrupt_status
+{
+	u8	element_id;			/* Command packet type. */
+	u8	length;				/* Command packet length. */
+	u16	reserve;
+	u32	interrupt_status;				/* Interrupt Status. */
+}cmpk_intr_sta_t;
+
+
+/* 3. TX side: Set configuration packet. */
+typedef struct tag_cmd_pkt_set_configuration
+{
+	u8	element_id;			/* Command packet type. */
+	u8	length;				/* Command packet length. */
+	u16	reserve1;			/* */
+	u8 	cfg_reserve1:3;
+	u8	cfg_size:2;			/* Configuration info. */
+	u8	cfg_type:2;			/* Configuration info. */
+	u8	cfg_action:1;		/* Configuration info. */
+	u8	cfg_reserve2;		/* Configuration info. */
+	u8	cfg_page:4;			/* Configuration info. */
+	u8	cfg_reserve3:4;		/* Configuration info. */
+	u8	cfg_offset;			/* Configuration info. */
+	u32	value;				/* */
+	u32	mask;				/* */
+}cmpk_set_cfg_t;
+
+/* 4. Both side : TX/RX query configuraton packet. The query structure is the
+      same as set configuration. */
+#define		cmpk_query_cfg_t	cmpk_set_cfg_t
+
+/* 5. Multi packet feedback status. */
+typedef struct tag_tx_stats_feedback // PJ quick rxcmd 09042007
+{
+	// For endian transfer --> Driver will not the same as firmware structure.
+	// DW 0
+	u16	reserve1;
+	u8 	length;				// Command packet length
+	u8 	element_id;			// Command packet type
+
+	// DW 1
+	u16	txfail;				// Tx Fail count
+	u16 	txok;				// Tx ok count
+
+	// DW 2
+	u16	txmcok;  			// tx multicast
+	u16 	txretry;			// Tx Retry count
+
+	// DW 3
+	u16  txucok;				// tx unicast
+	u16	txbcok;  			// tx broadcast
+
+	// DW 4
+	u16	txbcfail;			//
+	u16	txmcfail;			//
+
+	// DW 5
+	u16	reserve2;			//
+	u16	txucfail;			//
+
+	// DW 6-8
+	u32	txmclength;
+	u32	txbclength;
+	u32	txuclength;
+
+	// DW 9
+	u16	reserve3_23;
+	u8	reserve3_1;
+	u8	rate;
+}__attribute__((packed)) cmpk_tx_status_t;
+
+/* 6. Debug feedback message. */
+/* 2007/10/23 MH Define RX debug message  */
+typedef struct tag_rx_debug_message_feedback
+{
+	// For endian transfer --> for driver
+	// DW 0
+	u16	reserve1;
+	u8 	length;				// Command packet length
+	u8 	element_id;			// Command packet type
+
+	// DW 1-??
+	// Variable debug message.
+
+}cmpk_rx_dbginfo_t;
+
+/* 2008/03/20 MH Define transmit rate history. For big endian format. */
+typedef struct tag_tx_rate_history
+{
+	// For endian transfer --> for driver
+	// DW 0
+	u8 	element_id;			// Command packet type
+	u8 	length;				// Command packet length
+	u16	reserved1;
+
+	// DW 1-2	CCK rate counter
+	u16 	cck[4];
+
+	// DW 3-6
+	u16 	ofdm[8];
+
+	// DW 7-14
+	//UINT16	MCS_BW0_SG0[16];
+
+	// DW 15-22
+	//UINT16	MCS_BW1_SG0[16];
+
+	// DW 23-30
+	//UINT16	MCS_BW0_SG1[16];
+
+	// DW 31-38
+	//UINT16	MCS_BW1_SG1[16];
+
+	// DW 7-14	BW=0 SG=0
+	// DW 15-22	BW=1 SG=0
+	// DW 23-30	BW=0 SG=1
+	// DW 31-38	BW=1 SG=1
+	u16	ht_mcs[4][16];
+
+}__attribute__((packed)) cmpk_tx_rahis_t;
+
+typedef enum tag_command_packet_directories
+{
+    RX_TX_FEEDBACK = 0,
+    RX_INTERRUPT_STATUS		= 1,
+    TX_SET_CONFIG				= 2,
+    BOTH_QUERY_CONFIG			= 3,
+    RX_TX_STATUS				= 4,
+    RX_DBGINFO_FEEDBACK		= 5,
+    RX_TX_PER_PKT_FEEDBACK		= 6,
+    RX_TX_RATE_HISTORY		= 7,
+    RX_CMD_ELE_MAX
+}cmpk_element_e;
+
+typedef enum _rt_status{
+	RT_STATUS_SUCCESS,
+	RT_STATUS_FAILURE,
+	RT_STATUS_PENDING,
+	RT_STATUS_RESOURCE
+}rt_status,*prt_status;
+
+extern rt_status cmpk_message_handle_tx(struct net_device *dev, u8* codevirtualaddress, u32 packettype, u32 buffer_len);
+
+extern  u32 cmpk_message_handle_rx(struct net_device *dev, struct ieee80211_rx_stats * pstats);
+extern rt_status SendTxCommandPacket( struct net_device *dev, void* pData, u32 DataLen);
+
+
+#endif
diff --git a/drivers/staging/rtl8192u/r819xU_firmware.c b/drivers/staging/rtl8192u/r819xU_firmware.c
new file mode 100644
index 0000000..3cc2d57
--- /dev/null
+++ b/drivers/staging/rtl8192u/r819xU_firmware.c
@@ -0,0 +1,434 @@
+/**************************************************************************************************
+ * Procedure:    Init boot code/firmware code/data session
+ *
+ * Description: This routine will intialize firmware. If any error occurs during the initialization
+ * 		process, the routine shall terminate immediately and return fail.
+ *		NIC driver should call NdisOpenFile only from MiniportInitialize.
+ *
+ * Arguments:   The pointer of the adapter
+
+ * Returns:
+ *        NDIS_STATUS_FAILURE - the following initialization process should be terminated
+ *        NDIS_STATUS_SUCCESS - if firmware initialization process success
+**************************************************************************************************/
+//#include "ieee80211.h"
+#include "r8192U.h"
+#include "r8192U_hw.h"
+#include "r819xU_firmware_img.h"
+#include "r819xU_firmware.h"
+#include <linux/firmware.h>
+void firmware_init_param(struct net_device *dev)
+{
+	struct r8192_priv 	*priv = ieee80211_priv(dev);
+	rt_firmware		*pfirmware = priv->pFirmware;
+
+	pfirmware->cmdpacket_frag_thresold = GET_COMMAND_PACKET_FRAG_THRESHOLD(MAX_TRANSMIT_BUFFER_SIZE);
+}
+
+/*
+ * segment the img and use the ptr and length to remember info on each segment
+ *
+ */
+bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, u32 buffer_len)
+{
+	struct r8192_priv   *priv = ieee80211_priv(dev);
+	bool 		    rt_status = true;
+	u16		    frag_threshold;
+	u16		    frag_length, frag_offset = 0;
+	//u16		    total_size;
+	int		    i;
+
+	rt_firmware	    *pfirmware = priv->pFirmware;
+	struct sk_buff	    *skb;
+	unsigned char	    *seg_ptr;
+	cb_desc		    *tcb_desc;
+	u8                  bLastIniPkt;
+
+	firmware_init_param(dev);
+	//Fragmentation might be required
+	frag_threshold = pfirmware->cmdpacket_frag_thresold;
+	do {
+		if((buffer_len - frag_offset) > frag_threshold) {
+			frag_length = frag_threshold ;
+			bLastIniPkt = 0;
+
+		} else {
+			frag_length = buffer_len - frag_offset;
+			bLastIniPkt = 1;
+
+		}
+
+		/* Allocate skb buffer to contain firmware info and tx descriptor info
+		 * add 4 to avoid packet appending overflow.
+		 * */
+		#ifdef RTL8192U
+		skb  = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4);
+		#else
+		skb  = dev_alloc_skb(frag_length + 4);
+		#endif
+		memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
+		tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE);
+		tcb_desc->queue_index = TXCMD_QUEUE;
+		tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT;
+		tcb_desc->bLastIniPkt = bLastIniPkt;
+
+		#ifdef RTL8192U
+		skb_reserve(skb, USB_HWDESC_HEADER_LEN);
+		#endif
+		seg_ptr = skb->data;
+		/*
+		 * Transform from little endian to big endian
+		 * and pending  zero
+		 */
+		for(i=0 ; i < frag_length; i+=4) {
+			*seg_ptr++ = ((i+0)<frag_length)?code_virtual_address[i+3]:0;
+			*seg_ptr++ = ((i+1)<frag_length)?code_virtual_address[i+2]:0;
+			*seg_ptr++ = ((i+2)<frag_length)?code_virtual_address[i+1]:0;
+			*seg_ptr++ = ((i+3)<frag_length)?code_virtual_address[i+0]:0;
+		}
+		tcb_desc->txbuf_size= (u16)i;
+		skb_put(skb, i);
+
+		if(!priv->ieee80211->check_nic_enough_desc(dev,tcb_desc->queue_index)||
+			(!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index]))||\
+			(priv->ieee80211->queue_stop) ) {
+			RT_TRACE(COMP_FIRMWARE,"=====================================================> tx full!\n");
+			skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb);
+		} else {
+			priv->ieee80211->softmac_hard_start_xmit(skb,dev);
+		}
+
+		code_virtual_address += frag_length;
+		frag_offset += frag_length;
+
+	}while(frag_offset < buffer_len);
+
+	return rt_status;
+
+}
+
+bool
+fwSendNullPacket(
+	struct net_device *dev,
+	u32			Length
+)
+{
+	bool	rtStatus = true;
+	struct r8192_priv   *priv = ieee80211_priv(dev);
+	struct sk_buff	    *skb;
+	cb_desc		    *tcb_desc;
+	unsigned char	    *ptr_buf;
+	bool	bLastInitPacket = false;
+
+	//PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
+
+	//Get TCB and local buffer from common pool. (It is shared by CmdQ, MgntQ, and USB coalesce DataQ)
+	skb  = dev_alloc_skb(Length+ 4);
+	memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
+	tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE);
+	tcb_desc->queue_index = TXCMD_QUEUE;
+	tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT;
+	tcb_desc->bLastIniPkt = bLastInitPacket;
+	ptr_buf = skb_put(skb, Length);
+	memset(ptr_buf,0,Length);
+	tcb_desc->txbuf_size= (u16)Length;
+
+	if(!priv->ieee80211->check_nic_enough_desc(dev,tcb_desc->queue_index)||
+			(!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index]))||\
+			(priv->ieee80211->queue_stop) ) {
+			RT_TRACE(COMP_FIRMWARE,"===================NULL packet==================================> tx full!\n");
+			skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb);
+		} else {
+			priv->ieee80211->softmac_hard_start_xmit(skb,dev);
+		}
+
+	//PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
+	return rtStatus;
+}
+
+
+//-----------------------------------------------------------------------------
+// Procedure:    Check whether main code is download OK. If OK, turn on CPU
+//
+// Description:   CPU register locates in different page against general register.
+//			    Switch to CPU register in the begin and switch back before return
+//
+//
+// Arguments:   The pointer of the adapter
+//
+// Returns:
+//        NDIS_STATUS_FAILURE - the following initialization process should be terminated
+//        NDIS_STATUS_SUCCESS - if firmware initialization process success
+//-----------------------------------------------------------------------------
+bool CPUcheck_maincodeok_turnonCPU(struct net_device *dev)
+{
+	bool		rt_status = true;
+	int		check_putcodeOK_time = 200000, check_bootOk_time = 200000;
+	u32		CPU_status = 0;
+
+	/* Check whether put code OK */
+	do {
+		CPU_status = read_nic_dword(dev, CPU_GEN);
+
+		if(CPU_status&CPU_GEN_PUT_CODE_OK)
+			break;
+
+	}while(check_putcodeOK_time--);
+
+	if(!(CPU_status&CPU_GEN_PUT_CODE_OK)) {
+		RT_TRACE(COMP_ERR, "Download Firmware: Put code fail!\n");
+		goto CPUCheckMainCodeOKAndTurnOnCPU_Fail;
+	} else {
+		RT_TRACE(COMP_FIRMWARE, "Download Firmware: Put code ok!\n");
+	}
+
+	/* Turn On CPU */
+	CPU_status = read_nic_dword(dev, CPU_GEN);
+	write_nic_byte(dev, CPU_GEN, (u8)((CPU_status|CPU_GEN_PWR_STB_CPU)&0xff));
+	mdelay(1000);
+
+	/* Check whether CPU boot OK */
+	do {
+		CPU_status = read_nic_dword(dev, CPU_GEN);
+
+		if(CPU_status&CPU_GEN_BOOT_RDY)
+			break;
+	}while(check_bootOk_time--);
+
+	if(!(CPU_status&CPU_GEN_BOOT_RDY)) {
+		goto CPUCheckMainCodeOKAndTurnOnCPU_Fail;
+	} else {
+		RT_TRACE(COMP_FIRMWARE, "Download Firmware: Boot ready!\n");
+	}
+
+	return rt_status;
+
+CPUCheckMainCodeOKAndTurnOnCPU_Fail:
+	RT_TRACE(COMP_ERR, "ERR in %s()\n", __FUNCTION__);
+	rt_status = FALSE;
+	return rt_status;
+}
+
+bool CPUcheck_firmware_ready(struct net_device *dev)
+{
+
+	bool		rt_status = true;
+	int		check_time = 200000;
+	u32		CPU_status = 0;
+
+	/* Check Firmware Ready */
+	do {
+		CPU_status = read_nic_dword(dev, CPU_GEN);
+
+		if(CPU_status&CPU_GEN_FIRM_RDY)
+			break;
+
+	}while(check_time--);
+
+	if(!(CPU_status&CPU_GEN_FIRM_RDY))
+		goto CPUCheckFirmwareReady_Fail;
+	else
+		RT_TRACE(COMP_FIRMWARE, "Download Firmware: Firmware ready!\n");
+
+	return rt_status;
+
+CPUCheckFirmwareReady_Fail:
+	RT_TRACE(COMP_ERR, "ERR in %s()\n", __FUNCTION__);
+	rt_status = false;
+	return rt_status;
+
+}
+
+bool init_firmware(struct net_device *dev)
+{
+	struct r8192_priv 	*priv = ieee80211_priv(dev);
+	bool			rt_status = TRUE;
+
+	u8			*firmware_img_buf[3] = { &rtl8190_fwboot_array[0],
+							 &rtl8190_fwmain_array[0],
+							 &rtl8190_fwdata_array[0]};
+
+	u32			firmware_img_len[3] = { sizeof(rtl8190_fwboot_array),
+							sizeof(rtl8190_fwmain_array),
+							sizeof(rtl8190_fwdata_array)};
+	u32			file_length = 0;
+	u8			*mapped_file = NULL;
+	u32			init_step = 0;
+	opt_rst_type_e	rst_opt = OPT_SYSTEM_RESET;
+	firmware_init_step_e 	starting_state = FW_INIT_STEP0_BOOT;
+
+	rt_firmware		*pfirmware = priv->pFirmware;
+	const struct firmware 	*fw_entry;
+	const char *fw_name[3] = { "RTL8192U/boot.img",
+			   "RTL8192U/main.img",
+			   "RTL8192U/data.img"};
+	int rc;
+
+	RT_TRACE(COMP_FIRMWARE, " PlatformInitFirmware()==>\n");
+
+	if (pfirmware->firmware_status == FW_STATUS_0_INIT ) {
+		/* it is called by reset */
+		rst_opt = OPT_SYSTEM_RESET;
+		starting_state = FW_INIT_STEP0_BOOT;
+		// TODO: system reset
+
+	}else if(pfirmware->firmware_status == FW_STATUS_5_READY) {
+		/* it is called by Initialize */
+		rst_opt = OPT_FIRMWARE_RESET;
+		starting_state = FW_INIT_STEP2_DATA;
+	}else {
+		 RT_TRACE(COMP_FIRMWARE, "PlatformInitFirmware: undefined firmware state\n");
+	}
+
+	/*
+	 * Download boot, main, and data image for System reset.
+	 * Download data image for firmware reseta
+	 */
+	priv->firmware_source = FW_SOURCE_IMG_FILE;
+	for(init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; init_step++) {
+		/*
+		 * Open Image file, and map file to contineous memory if open file success.
+		 * or read image file from array. Default load from IMG file
+		 */
+		if(rst_opt == OPT_SYSTEM_RESET) {
+			switch(priv->firmware_source) {
+				case FW_SOURCE_IMG_FILE:
+					rc = request_firmware(&fw_entry, fw_name[init_step],&priv->udev->dev);
+					if(rc < 0 ) {
+						RT_TRACE(COMP_ERR, "request firmware fail!\n");
+						goto download_firmware_fail;
+					}
+
+					if(fw_entry->size > sizeof(pfirmware->firmware_buf)) {
+						RT_TRACE(COMP_ERR, "img file size exceed the container buffer fail!\n");
+						goto download_firmware_fail;
+					}
+
+					if(init_step != FW_INIT_STEP1_MAIN) {
+						memcpy(pfirmware->firmware_buf,fw_entry->data,fw_entry->size);
+						mapped_file = pfirmware->firmware_buf;
+						file_length = fw_entry->size;
+					} else {
+					#ifdef RTL8190P
+						memcpy(pfirmware->firmware_buf,fw_entry->data,fw_entry->size);
+						mapped_file = pfirmware->firmware_buf;
+						file_length = fw_entry->size;
+					#else
+						memset(pfirmware->firmware_buf,0,128);
+						memcpy(&pfirmware->firmware_buf[128],fw_entry->data,fw_entry->size);
+						mapped_file = pfirmware->firmware_buf;
+						file_length = fw_entry->size + 128;
+					#endif
+					}
+					pfirmware->firmware_buf_size = file_length;
+					break;
+
+				case FW_SOURCE_HEADER_FILE:
+					mapped_file =  firmware_img_buf[init_step];
+					file_length  = firmware_img_len[init_step];
+					if(init_step == FW_INIT_STEP2_DATA) {
+						memcpy(pfirmware->firmware_buf, mapped_file, file_length);
+						pfirmware->firmware_buf_size = file_length;
+					}
+					break;
+
+				default:
+					break;
+			}
+
+
+		}else if(rst_opt == OPT_FIRMWARE_RESET ) {
+			/* we only need to download data.img here */
+			mapped_file = pfirmware->firmware_buf;
+			file_length = pfirmware->firmware_buf_size;
+		}
+
+		/* Download image file */
+		/* The firmware download process is just as following,
+		 * 1. that is each packet will be segmented and inserted to the wait queue.
+		 * 2. each packet segment will be put in the skb_buff packet.
+		 * 3. each skb_buff packet data content will already include the firmware info
+		 *   and Tx descriptor info
+		 * */
+		rt_status = fw_download_code(dev,mapped_file,file_length);
+		if(rst_opt == OPT_SYSTEM_RESET) {
+			release_firmware(fw_entry);
+		}
+
+		if(rt_status != TRUE) {
+			goto download_firmware_fail;
+		}
+
+		switch(init_step) {
+			case FW_INIT_STEP0_BOOT:
+				/* Download boot
+				 * initialize command descriptor.
+				 * will set polling bit when firmware code is also configured
+				 */
+				pfirmware->firmware_status = FW_STATUS_1_MOVE_BOOT_CODE;
+#ifdef RTL8190P
+				// To initialize IMEM, CPU move code  from 0x80000080, hence, we send 0x80 byte packet
+				rt_status = fwSendNullPacket(dev, RTL8190_CPU_START_OFFSET);
+				if(rt_status != true)
+				{
+					RT_TRACE(COMP_INIT, "fwSendNullPacket() fail ! \n");
+					goto  download_firmware_fail;
+				}
+#endif
+				//mdelay(1000);
+				/*
+				 * To initialize IMEM, CPU move code  from 0x80000080,
+				 * hence, we send 0x80 byte packet
+				 */
+				break;
+
+			case FW_INIT_STEP1_MAIN:
+				/* Download firmware code. Wait until Boot Ready and Turn on CPU */
+				pfirmware->firmware_status = FW_STATUS_2_MOVE_MAIN_CODE;
+
+				/* Check Put Code OK and Turn On CPU */
+				rt_status = CPUcheck_maincodeok_turnonCPU(dev);
+				if(rt_status != TRUE) {
+					RT_TRACE(COMP_ERR, "CPUcheck_maincodeok_turnonCPU fail!\n");
+					goto download_firmware_fail;
+				}
+
+				pfirmware->firmware_status = FW_STATUS_3_TURNON_CPU;
+				break;
+
+			case FW_INIT_STEP2_DATA:
+				/* download initial data code */
+				pfirmware->firmware_status = FW_STATUS_4_MOVE_DATA_CODE;
+				mdelay(1);
+
+				rt_status = CPUcheck_firmware_ready(dev);
+				if(rt_status != TRUE) {
+					RT_TRACE(COMP_ERR, "CPUcheck_firmware_ready fail(%d)!\n",rt_status);
+					goto download_firmware_fail;
+				}
+
+				/* wait until data code is initialized ready.*/
+				pfirmware->firmware_status = FW_STATUS_5_READY;
+				break;
+		}
+	}
+
+	RT_TRACE(COMP_FIRMWARE, "Firmware Download Success\n");
+	//assert(pfirmware->firmware_status == FW_STATUS_5_READY, ("Firmware Download Fail\n"));
+
+	return rt_status;
+
+download_firmware_fail:
+	RT_TRACE(COMP_ERR, "ERR in %s()\n", __FUNCTION__);
+	rt_status = FALSE;
+	return rt_status;
+
+}
+
+
+
+
+
+
+
+
diff --git a/drivers/staging/rtl8192u/r819xU_firmware.h b/drivers/staging/rtl8192u/r819xU_firmware.h
new file mode 100644
index 0000000..a4bceeef
--- /dev/null
+++ b/drivers/staging/rtl8192u/r819xU_firmware.h
@@ -0,0 +1,27 @@
+#ifndef __INC_FIRMWARE_H
+#define __INC_FIRMWARE_H
+
+#define RTL8190_CPU_START_OFFSET	0x80
+/* TODO: this definition is TBD */
+//#define USB_HWDESC_HEADER_LEN	0
+
+/* It should be double word alignment */
+//#if DEV_BUS_TYPE==PCI_INTERFACE
+//#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v)	4*(v/4) - 8
+//#else
+#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v)	(4*(v/4) - 8 - USB_HWDESC_HEADER_LEN)
+//#endif
+
+typedef enum _firmware_init_step{
+	FW_INIT_STEP0_BOOT = 0,
+	FW_INIT_STEP1_MAIN = 1,
+	FW_INIT_STEP2_DATA = 2,
+}firmware_init_step_e;
+
+typedef enum _opt_rst_type{
+	OPT_SYSTEM_RESET = 0,
+	OPT_FIRMWARE_RESET = 1,
+}opt_rst_type_e;
+
+#endif
+
diff --git a/drivers/staging/rtl8192u/r819xU_firmware_img.c b/drivers/staging/rtl8192u/r819xU_firmware_img.c
new file mode 100644
index 0000000..29b656d
--- /dev/null
+++ b/drivers/staging/rtl8192u/r819xU_firmware_img.c
@@ -0,0 +1,3447 @@
+/*Created on  2008/ 7/16,  5:31*/
+#include <linux/types.h>
+
+u8 rtl8190_fwboot_array[] = {
+0x10,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x3c,0x08,0xbf,0xc0,0x25,0x08,0x00,0x08,
+0x3c,0x09,0xb0,0x03,0xad,0x28,0x00,0x20,0x40,0x80,0x68,0x00,0x00,0x00,0x00,0x00,
+0x3c,0x0a,0xd0,0x00,0x40,0x8a,0x60,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x01,
+0x25,0x08,0xb0,0x50,0x24,0x09,0x00,0x01,0x3c,0x01,0x7f,0xff,0x34,0x21,0xff,0xff,
+0x01,0x01,0x50,0x24,0x00,0x09,0x48,0x40,0x35,0x29,0x00,0x01,0x01,0x2a,0x10,0x2b,
+0x14,0x40,0xff,0xfc,0x00,0x00,0x00,0x00,0x3c,0x0a,0x00,0x00,0x25,0x4a,0x00,0x00,
+0x4c,0x8a,0x00,0x00,0x4c,0x89,0x08,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x01,
+0x25,0x08,0xb0,0x50,0x3c,0x01,0x80,0x00,0x01,0x21,0x48,0x25,0x3c,0x0a,0xbf,0xc0,
+0x25,0x4a,0x00,0x7c,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0xad,0x00,0x00,0x00,
+0x21,0x08,0x00,0x04,0x01,0x09,0x10,0x2b,0x14,0x40,0xff,0xf8,0x00,0x00,0x00,0x00,
+0x3c,0x08,0x80,0x01,0x25,0x08,0x7f,0xff,0x24,0x09,0x00,0x01,0x3c,0x01,0x7f,0xff,
+0x34,0x21,0xff,0xff,0x01,0x01,0x50,0x24,0x00,0x09,0x48,0x40,0x35,0x29,0x00,0x01,
+0x01,0x2a,0x10,0x2b,0x14,0x40,0xff,0xfc,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x01,
+0x25,0x4a,0x00,0x00,0x3c,0x01,0x7f,0xff,0x34,0x21,0xff,0xff,0x01,0x41,0x50,0x24,
+0x3c,0x09,0x00,0x01,0x35,0x29,0x7f,0xff,0x4c,0x8a,0x20,0x00,0x4c,0x89,0x28,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x08,0x04,0x10,
+0x00,0x00,0x00,0x00,0x40,0x88,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x3c,0x08,0xbf,0xc0,0x00,0x00,0x00,0x00,0x8d,0x09,0x00,0x00,0x00,0x00,0x00,0x00,
+0x3c,0x0a,0xbf,0xc0,0x25,0x4a,0x01,0x20,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,
+0x3c,0x08,0xb0,0x03,0x8d,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x35,0x29,0x00,0x10,
+0xad,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x00,0x25,0x08,0x4b,0x84,
+0x01,0x00,0x00,0x08,0x00,0x00,0x00,0x00,};
+
+u8 rtl8190_fwmain_array[] = {
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x40,0x04,0x68,0x00,0x40,0x05,0x70,0x00,0x40,0x06,0x40,0x00,0x0c,0x00,0x12,0x94,
+0x00,0x00,0x00,0x00,0x40,0x1a,0x68,0x00,0x33,0x5b,0x00,0x3c,0x17,0x60,0x00,0x09,
+0x00,0x00,0x00,0x00,0x40,0x1b,0x60,0x00,0x00,0x00,0x00,0x00,0x03,0x5b,0xd0,0x24,
+0x40,0x1a,0x70,0x00,0x03,0x40,0x00,0x08,0x42,0x00,0x00,0x10,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0xff,0x34,0x42,0xff,0xff,0x8c,0x43,0x00,0x00,
+0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x00,0xd0,
+0xac,0x62,0x00,0x00,0x00,0x00,0x20,0x21,0x27,0x85,0x8b,0x60,0x00,0x85,0x18,0x21,
+0x24,0x84,0x00,0x01,0x28,0x82,0x00,0x0a,0x14,0x40,0xff,0xfc,0xa0,0x60,0x00,0x00,
+0x27,0x82,0x8b,0x6a,0x24,0x04,0x00,0x06,0x24,0x84,0xff,0xff,0xa4,0x40,0x00,0x00,
+0x04,0x81,0xff,0xfd,0x24,0x42,0x00,0x02,0x24,0x02,0x00,0x03,0xa3,0x82,0x8b,0x60,
+0x24,0x02,0x09,0xc4,0x24,0x03,0x01,0x00,0xa7,0x82,0x8b,0x76,0x24,0x02,0x04,0x00,
+0xaf,0x83,0x8b,0x78,0xaf,0x82,0x8b,0x7c,0x24,0x03,0x00,0x0a,0x24,0x02,0x00,0x04,
+0x24,0x05,0x00,0x02,0x24,0x04,0x00,0x01,0xa3,0x83,0x8b,0x62,0xa3,0x82,0x8b,0x68,
+0x24,0x03,0x00,0x01,0x24,0x02,0x02,0x00,0xa3,0x84,0x8b,0x66,0xa3,0x85,0x8b,0x69,
+0xa7,0x82,0x8b,0x6a,0xa7,0x83,0x8b,0x6c,0xa3,0x84,0x8b,0x61,0xa3,0x80,0x8b,0x63,
+0xa3,0x80,0x8b,0x64,0xa3,0x80,0x8b,0x65,0xa3,0x85,0x8b,0x67,0x03,0xe0,0x00,0x08,
+0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x01,0x84,
+0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00,0x27,0x84,0x8b,0x88,0x00,0x00,0x10,0x21,
+0x24,0x42,0x00,0x01,0x00,0x02,0x16,0x00,0x00,0x02,0x16,0x03,0x28,0x43,0x00,0x03,
+0xac,0x80,0xff,0xfc,0xa0,0x80,0x00,0x00,0x14,0x60,0xff,0xf9,0x24,0x84,0x00,0x0c,
+0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,
+0x34,0x63,0x00,0x20,0x24,0x42,0x01,0xc8,0x3c,0x08,0xb0,0x03,0xac,0x62,0x00,0x00,
+0x35,0x08,0x00,0x70,0x8d,0x02,0x00,0x00,0x00,0xa0,0x48,0x21,0x00,0x04,0x26,0x00,
+0x00,0x02,0x2a,0x43,0x00,0x06,0x36,0x00,0x00,0x07,0x3e,0x00,0x00,0x02,0x12,0x03,
+0x29,0x23,0x00,0x03,0x00,0x04,0x56,0x03,0x00,0x06,0x36,0x03,0x00,0x07,0x3e,0x03,
+0x30,0x48,0x00,0x01,0x10,0x60,0x00,0x11,0x30,0xa5,0x00,0x07,0x24,0x02,0x00,0x02,
+0x00,0x49,0x10,0x23,0x00,0x45,0x10,0x07,0x30,0x42,0x00,0x01,0x10,0x40,0x00,0x66,
+0x00,0x00,0x00,0x00,0x8f,0xa2,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x02,0x21,0x43,
+0x11,0x00,0x00,0x10,0x00,0x07,0x20,0x0b,0x15,0x20,0x00,0x06,0x24,0x02,0x00,0x01,
+0x3c,0x02,0xb0,0x05,0x34,0x42,0x01,0x20,0xa4,0x44,0x00,0x00,0x03,0xe0,0x00,0x08,
+0x00,0x00,0x00,0x00,0x11,0x22,0x00,0x04,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05,
+0x08,0x00,0x00,0x96,0x34,0x42,0x01,0x24,0x3c,0x02,0xb0,0x05,0x08,0x00,0x00,0x96,
+0x34,0x42,0x01,0x22,0x15,0x20,0x00,0x54,0x24,0x02,0x00,0x01,0x3c,0x02,0xb0,0x03,
+0x34,0x42,0x00,0x74,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x83,0x8b,0x84,
+0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x70,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,
+0x30,0x6b,0x00,0x08,0x11,0x60,0x00,0x18,0x00,0x09,0x28,0x40,0x00,0x00,0x40,0x21,
+0x27,0x85,0x8b,0x80,0x8c,0xa3,0x00,0x00,0x8c,0xa2,0x00,0x04,0x00,0x00,0x00,0x00,
+0x00,0x62,0x38,0x23,0x00,0x43,0x10,0x2a,0x10,0x40,0x00,0x3d,0x00,0x00,0x00,0x00,
+0xac,0xa7,0x00,0x00,0x25,0x02,0x00,0x01,0x00,0x02,0x16,0x00,0x00,0x02,0x46,0x03,
+0x29,0x03,0x00,0x03,0x14,0x60,0xff,0xf3,0x24,0xa5,0x00,0x0c,0x3c,0x03,0xb0,0x03,
+0x34,0x63,0x00,0x70,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4b,0x10,0x23,
+0xa0,0x62,0x00,0x00,0x00,0x09,0x28,0x40,0x00,0xa9,0x10,0x21,0x00,0x02,0x10,0x80,
+0x27,0x83,0x8b,0x88,0x00,0x0a,0x20,0x0b,0x00,0x43,0x18,0x21,0x10,0xc0,0x00,0x05,
+0x00,0x00,0x38,0x21,0x80,0x62,0x00,0x01,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x05,
+0x00,0x00,0x00,0x00,0x80,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x03,
+0x00,0xa9,0x10,0x21,0x24,0x07,0x00,0x01,0x00,0xa9,0x10,0x21,0x00,0x02,0x30,0x80,
+0x27,0x82,0x8b,0x88,0xa0,0x67,0x00,0x01,0x00,0xc2,0x38,0x21,0x80,0xe3,0x00,0x01,
+0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x07,0x00,0x00,0x00,0x00,0x27,0x83,0x8b,0x80,
+0x00,0xc3,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x21,
+0xac,0x62,0x00,0x00,0x27,0x85,0x8b,0x84,0x27,0x82,0x8b,0x80,0x00,0xc5,0x28,0x21,
+0x00,0xc2,0x10,0x21,0x8c,0x43,0x00,0x00,0x8c,0xa4,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x64,0x18,0x2a,0x14,0x60,0x00,0x03,0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,
+0xa0,0xe2,0x00,0x00,0xa0,0xe0,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
+0x08,0x00,0x00,0xb9,0xac,0xa0,0x00,0x00,0x11,0x22,0x00,0x08,0x00,0x00,0x00,0x00,
+0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x7c,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,
+0xaf,0x83,0x8b,0x9c,0x08,0x00,0x00,0xa9,0x3c,0x02,0xb0,0x03,0x3c,0x02,0xb0,0x03,
+0x34,0x42,0x00,0x78,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x83,0x8b,0x90,
+0x08,0x00,0x00,0xa9,0x3c,0x02,0xb0,0x03,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,
+0x34,0x63,0x00,0x20,0x24,0x42,0x04,0x18,0x3c,0x05,0xb0,0x03,0xac,0x62,0x00,0x00,
+0x34,0xa5,0x00,0x70,0x8c,0xa2,0x00,0x00,0x90,0x84,0x00,0x08,0x3c,0x06,0xb0,0x03,
+0x00,0x02,0x16,0x00,0x2c,0x83,0x00,0x03,0x34,0xc6,0x00,0x72,0x24,0x07,0x00,0x01,
+0x10,0x60,0x00,0x11,0x00,0x02,0x2f,0xc2,0x90,0xc2,0x00,0x00,0x00,0x00,0x18,0x21,
+0x00,0x02,0x16,0x00,0x10,0xa7,0x00,0x09,0x00,0x02,0x16,0x03,0x14,0x80,0x00,0x0c,
+0x30,0x43,0x00,0x03,0x83,0x82,0x8b,0x88,0x00,0x00,0x00,0x00,0x00,0x02,0x10,0x80,
+0x00,0x43,0x10,0x21,0x00,0x02,0x16,0x00,0x00,0x02,0x1e,0x03,0x3c,0x02,0xb0,0x03,
+0x34,0x42,0x00,0x72,0xa0,0x43,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
+0x30,0x45,0x00,0x05,0x10,0x87,0x00,0x04,0x30,0x43,0x00,0x06,0x93,0x82,0x8b,0xa0,
+0x08,0x00,0x01,0x21,0x00,0x43,0x10,0x21,0x83,0x82,0x8b,0x94,0x00,0x00,0x00,0x00,
+0x00,0x02,0x10,0x40,0x08,0x00,0x01,0x21,0x00,0x45,0x10,0x21,0x10,0x80,0x00,0x05,
+0x00,0x00,0x18,0x21,0x24,0x63,0x00,0x01,0x00,0x64,0x10,0x2b,0x14,0x40,0xff,0xfd,
+0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,
+0x3c,0x02,0x80,0x00,0x24,0x42,0x04,0xec,0x3c,0x04,0xb0,0x02,0x34,0x63,0x00,0x20,
+0xac,0x62,0x00,0x00,0x34,0x84,0x00,0x08,0x24,0x02,0x00,0x01,0xaf,0x84,0x8b,0xb0,
+0xa3,0x82,0x8b,0xc0,0xa7,0x80,0x8b,0xb4,0xa7,0x80,0x8b,0xb6,0xaf,0x80,0x8b,0xb8,
+0xaf,0x80,0x8b,0xbc,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,
+0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x05,0x2c,0x3c,0x04,0xb0,0x03,
+0xac,0x62,0x00,0x00,0x34,0x84,0x00,0xac,0x80,0xa2,0x00,0x15,0x8c,0x83,0x00,0x00,
+0x27,0xbd,0xff,0xf0,0x00,0x43,0x10,0x21,0xac,0x82,0x00,0x00,0x03,0xe0,0x00,0x08,
+0x27,0xbd,0x00,0x10,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,0x34,0x42,0x00,0x20,
+0x24,0x63,0x05,0x64,0x27,0xbd,0xff,0xe0,0xac,0x43,0x00,0x00,0xaf,0xb1,0x00,0x14,
+0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x18,0x8f,0x90,0x8b,0xb0,0x0c,0x00,0x02,0x9a,
+0x00,0x80,0x88,0x21,0x14,0x40,0x00,0x2a,0x3c,0x02,0x00,0x80,0x16,0x20,0x00,0x02,
+0x34,0x42,0x02,0x01,0x24,0x02,0x02,0x01,0xae,0x02,0x00,0x00,0x97,0x84,0x8b,0xb4,
+0x97,0x82,0x8b,0xb6,0x3c,0x03,0xb0,0x02,0x00,0x83,0x20,0x21,0x24,0x42,0x00,0x04,
+0xa7,0x82,0x8b,0xb6,0xa4,0x82,0x00,0x00,0x8f,0x84,0x8b,0xb8,0x8f,0x82,0x8b,0xb0,
+0x93,0x85,0x8b,0x62,0x24,0x84,0x00,0x01,0x24,0x42,0x00,0x04,0x24,0x03,0x8f,0xff,
+0x3c,0x07,0xb0,0x06,0x3c,0x06,0xb0,0x03,0x00,0x43,0x10,0x24,0x00,0x85,0x28,0x2a,
+0x34,0xe7,0x80,0x18,0xaf,0x82,0x8b,0xb0,0xaf,0x84,0x8b,0xb8,0x10,0xa0,0x00,0x08,
+0x34,0xc6,0x01,0x08,0x8f,0x83,0x8b,0xbc,0x8f,0x84,0x8b,0x7c,0x8c,0xc2,0x00,0x00,
+0x00,0x64,0x18,0x21,0x00,0x43,0x10,0x2b,0x14,0x40,0x00,0x09,0x00,0x00,0x00,0x00,
+0x8c,0xe2,0x00,0x00,0x3c,0x03,0x0f,0x00,0x3c,0x04,0x04,0x00,0x00,0x43,0x10,0x24,
+0x10,0x44,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x98,0x00,0x00,0x00,0x00,
+0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,
+0x27,0xbd,0xff,0xd8,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,0x24,0x63,0x06,0x50,
+0xaf,0xb0,0x00,0x10,0x34,0x42,0x00,0x20,0x8f,0x90,0x8b,0xb0,0xac,0x43,0x00,0x00,
+0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x20,
+0x00,0x80,0x88,0x21,0x00,0xa0,0x90,0x21,0x0c,0x00,0x02,0x9a,0x00,0xc0,0x98,0x21,
+0x24,0x07,0x8f,0xff,0x14,0x40,0x00,0x19,0x26,0x03,0x00,0x04,0x24,0x02,0x0e,0x03,
+0xae,0x02,0x00,0x00,0x00,0x67,0x80,0x24,0x26,0x02,0x00,0x04,0xae,0x11,0x00,0x00,
+0x00,0x47,0x80,0x24,0x97,0x86,0x8b,0xb4,0x26,0x03,0x00,0x04,0xae,0x12,0x00,0x00,
+0x00,0x67,0x80,0x24,0xae,0x13,0x00,0x00,0x8f,0x84,0x8b,0xb0,0x3c,0x02,0xb0,0x02,
+0x97,0x85,0x8b,0xb6,0x00,0xc2,0x30,0x21,0x8f,0x82,0x8b,0xb8,0x24,0x84,0x00,0x10,
+0x24,0xa5,0x00,0x10,0x00,0x87,0x20,0x24,0x24,0x42,0x00,0x01,0xa7,0x85,0x8b,0xb6,
+0xaf,0x84,0x8b,0xb0,0xaf,0x82,0x8b,0xb8,0xa4,0xc5,0x00,0x00,0x8f,0xbf,0x00,0x20,
+0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,
+0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,0x94,0x82,0x00,0x04,0x00,0x00,0x00,0x00,
+0x30,0x42,0xe0,0x00,0x14,0x40,0x00,0x14,0x00,0x00,0x00,0x00,0x90,0x82,0x00,0x02,
+0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfc,0x00,0x82,0x28,0x21,0x8c,0xa4,0x00,0x00,
+0x3c,0x02,0x00,0x70,0x8c,0xa6,0x00,0x08,0x00,0x82,0x10,0x21,0x2c,0x43,0x00,0x06,
+0x10,0x60,0x00,0x09,0x3c,0x03,0x80,0x01,0x00,0x02,0x10,0x80,0x24,0x63,0x01,0xe8,
+0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08,
+0x00,0x00,0x00,0x00,0xaf,0x86,0x80,0x14,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,
+0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x8c,0xa4,0x00,0x00,0x0c,0x00,0x17,0xb3,
+0x00,0x00,0x00,0x00,0x08,0x00,0x01,0xde,0x00,0x00,0x00,0x00,0x0c,0x00,0x24,0xaa,
+0x00,0xc0,0x20,0x21,0x08,0x00,0x01,0xde,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,
+0x34,0x42,0x01,0x08,0x8c,0x44,0x00,0x00,0x8f,0x82,0x80,0x18,0x3c,0x03,0x00,0x0f,
+0x34,0x63,0x42,0x40,0x00,0x43,0x10,0x21,0x00,0x82,0x20,0x2b,0x10,0x80,0x00,0x09,
+0x24,0x03,0x00,0x05,0x8f,0x82,0x83,0x30,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,
+0xaf,0x82,0x83,0x30,0x10,0x43,0x00,0x03,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,
+0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x8c,0x63,0x01,0x08,0x24,0x02,0x00,0x01,
+0xa3,0x82,0x80,0x11,0xaf,0x80,0x83,0x30,0xaf,0x83,0x80,0x18,0x08,0x00,0x01,0xfb,
+0x00,0x00,0x00,0x00,0x30,0x84,0x00,0xff,0x14,0x80,0x00,0x2f,0x00,0x00,0x00,0x00,
+0x8f,0x82,0x80,0x14,0xa3,0x85,0x83,0x63,0x10,0x40,0x00,0x2b,0x2c,0xa2,0x00,0x04,
+0x14,0x40,0x00,0x06,0x00,0x05,0x10,0x40,0x24,0xa2,0xff,0xfc,0x2c,0x42,0x00,0x08,
+0x10,0x40,0x00,0x09,0x24,0xa2,0xff,0xf0,0x00,0x05,0x10,0x40,0x27,0x84,0x83,0x6c,
+0x00,0x44,0x10,0x21,0x94,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x63,0x00,0x01,
+0x03,0xe0,0x00,0x08,0xa4,0x43,0x00,0x00,0x2c,0x42,0x00,0x10,0x14,0x40,0x00,0x0a,
+0x00,0x05,0x10,0x40,0x24,0xa2,0xff,0xe0,0x2c,0x42,0x00,0x10,0x14,0x40,0x00,0x06,
+0x00,0x05,0x10,0x40,0x24,0xa2,0xff,0xd0,0x2c,0x42,0x00,0x10,0x10,0x40,0x00,0x09,
+0x24,0xa2,0xff,0xc0,0x00,0x05,0x10,0x40,0x27,0x84,0x83,0x6c,0x00,0x44,0x10,0x21,
+0x94,0x43,0xff,0xf8,0x00,0x00,0x00,0x00,0x24,0x63,0x00,0x01,0x03,0xe0,0x00,0x08,
+0xa4,0x43,0xff,0xf8,0x2c,0x42,0x00,0x10,0x10,0x40,0x00,0x07,0x00,0x05,0x10,0x40,
+0x27,0x84,0x83,0x6c,0x00,0x44,0x10,0x21,0x94,0x43,0xff,0xf8,0x00,0x00,0x00,0x00,
+0x24,0x63,0x00,0x01,0xa4,0x43,0xff,0xf8,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
+0x8f,0x86,0x8b,0xb0,0x8f,0x82,0x80,0x14,0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,
+0x10,0x40,0x00,0x2a,0x00,0xc0,0x38,0x21,0x24,0x02,0x00,0x07,0x24,0x03,0xff,0x9c,
+0xa3,0x82,0x83,0x6b,0xa3,0x83,0x83,0x6a,0x27,0x8a,0x83,0x68,0x00,0x00,0x20,0x21,
+0x24,0x09,0x8f,0xff,0x00,0x04,0x10,0x80,0x00,0x4a,0x28,0x21,0x8c,0xa2,0x00,0x00,
+0x24,0xe3,0x00,0x04,0x24,0x88,0x00,0x01,0xac,0xe2,0x00,0x00,0x10,0x80,0x00,0x02,
+0x00,0x69,0x38,0x24,0xac,0xa0,0x00,0x00,0x31,0x04,0x00,0xff,0x2c,0x82,0x00,0x27,
+0x14,0x40,0xff,0xf5,0x00,0x04,0x10,0x80,0x97,0x83,0x8b,0xb6,0x97,0x85,0x8b,0xb4,
+0x3c,0x02,0xb0,0x02,0x24,0x63,0x00,0x9c,0x00,0xa2,0x28,0x21,0x3c,0x04,0xb0,0x06,
+0xa7,0x83,0x8b,0xb6,0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00,0x8c,0x85,0x00,0x00,
+0x24,0x02,0x8f,0xff,0x24,0xc6,0x00,0x9c,0x3c,0x03,0x0f,0x00,0x00,0xc2,0x30,0x24,
+0x00,0xa3,0x28,0x24,0x3c,0x02,0x04,0x00,0xaf,0x86,0x8b,0xb0,0x10,0xa2,0x00,0x03,
+0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x98,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x10,
+0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x8f,0x86,0x8b,0xb0,
+0x27,0xbd,0xff,0xc8,0x24,0x02,0x00,0x08,0x24,0x03,0x00,0x20,0xaf,0xbf,0x00,0x30,
+0xa3,0xa2,0x00,0x13,0xa3,0xa3,0x00,0x12,0xa7,0xa4,0x00,0x10,0x00,0xc0,0x28,0x21,
+0x27,0xa9,0x00,0x10,0x00,0x00,0x38,0x21,0x24,0x08,0x8f,0xff,0x00,0x07,0x10,0x80,
+0x00,0x49,0x10,0x21,0x8c,0x44,0x00,0x00,0x24,0xe3,0x00,0x01,0x30,0x67,0x00,0xff,
+0x24,0xa2,0x00,0x04,0x2c,0xe3,0x00,0x08,0xac,0xa4,0x00,0x00,0x14,0x60,0xff,0xf7,
+0x00,0x48,0x28,0x24,0x97,0x83,0x8b,0xb6,0x97,0x85,0x8b,0xb4,0x3c,0x02,0xb0,0x02,
+0x24,0x63,0x00,0x20,0x00,0xa2,0x28,0x21,0x3c,0x04,0xb0,0x06,0xa7,0x83,0x8b,0xb6,
+0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00,0x8c,0x85,0x00,0x00,0x24,0x02,0x8f,0xff,
+0x24,0xc6,0x00,0x20,0x3c,0x03,0x0f,0x00,0x00,0xc2,0x30,0x24,0x00,0xa3,0x28,0x24,
+0x3c,0x02,0x04,0x00,0xaf,0x86,0x8b,0xb0,0x10,0xa2,0x00,0x03,0x00,0x00,0x00,0x00,
+0x0c,0x00,0x04,0x98,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x30,0x00,0x00,0x00,0x00,
+0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0x93,0x82,0x8b,0xc0,0x00,0x00,0x00,0x00,
+0x10,0x40,0x00,0x11,0x24,0x06,0x00,0x01,0x8f,0x82,0x8b,0xb8,0x3c,0x05,0xb0,0x06,
+0x3c,0x04,0xb0,0x03,0x34,0xa5,0x80,0x18,0x34,0x84,0x01,0x08,0x14,0x40,0x00,0x09,
+0x00,0x00,0x30,0x21,0x97,0x82,0x8b,0xb4,0x8c,0x84,0x00,0x00,0x3c,0x03,0xb0,0x02,
+0x00,0x43,0x10,0x21,0xaf,0x84,0x8b,0xbc,0xa7,0x80,0x8b,0xb6,0xac,0x40,0x00,0x00,
+0xac,0x40,0x00,0x04,0x8c,0xa2,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0xc0,0x10,0x21,
+0x8f,0x86,0x8b,0xb0,0x8f,0x82,0x8b,0xb8,0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,
+0x00,0xc0,0x40,0x21,0x14,0x40,0x00,0x0a,0x00,0x40,0x50,0x21,0x00,0x00,0x38,0x21,
+0x27,0x89,0x83,0x38,0x24,0xe2,0x00,0x01,0x00,0x07,0x18,0x80,0x30,0x47,0x00,0xff,
+0x00,0x69,0x18,0x21,0x2c,0xe2,0x00,0x0a,0x14,0x40,0xff,0xfa,0xac,0x60,0x00,0x00,
+0x3c,0x02,0x00,0x80,0x10,0x82,0x00,0x6f,0x00,0x00,0x00,0x00,0x97,0x82,0x83,0x3e,
+0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xa7,0x82,0x83,0x3e,0x90,0xa3,0x00,0x15,
+0x97,0x82,0x83,0x40,0x00,0x03,0x1e,0x00,0x00,0x03,0x1e,0x03,0x00,0x43,0x10,0x21,
+0xa7,0x82,0x83,0x40,0x8c,0xa4,0x00,0x20,0x3c,0x02,0x00,0x60,0x3c,0x03,0x00,0x20,
+0x00,0x82,0x20,0x24,0x10,0x83,0x00,0x54,0x00,0x00,0x00,0x00,0x14,0x80,0x00,0x47,
+0x00,0x00,0x00,0x00,0x97,0x82,0x83,0x44,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,
+0xa7,0x82,0x83,0x44,0x84,0xa3,0x00,0x06,0x8f,0x82,0x83,0x54,0x00,0x00,0x00,0x00,
+0x00,0x43,0x10,0x21,0xaf,0x82,0x83,0x54,0x25,0x42,0x00,0x01,0x28,0x43,0x27,0x10,
+0xaf,0x82,0x8b,0xb8,0x10,0x60,0x00,0x09,0x24,0x02,0x00,0x04,0x93,0x83,0x80,0x11,
+0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x05,0x24,0x02,0x00,0x04,0x8f,0xbf,0x00,0x10,
+0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x24,0x03,0x00,0x28,
+0xa3,0x83,0x83,0x3a,0xa3,0x82,0x83,0x3b,0x90,0xa2,0x00,0x18,0x93,0x83,0x83,0x63,
+0x00,0x00,0x38,0x21,0x00,0x02,0x16,0x00,0x00,0x02,0x16,0x03,0xa7,0x82,0x83,0x4e,
+0xa3,0x83,0x83,0x5c,0x27,0x89,0x83,0x38,0x24,0x05,0x8f,0xff,0x00,0x07,0x10,0x80,
+0x00,0x49,0x10,0x21,0x8c,0x44,0x00,0x00,0x24,0xe3,0x00,0x01,0x30,0x67,0x00,0xff,
+0x25,0x02,0x00,0x04,0x2c,0xe3,0x00,0x0a,0xad,0x04,0x00,0x00,0x14,0x60,0xff,0xf7,
+0x00,0x45,0x40,0x24,0x97,0x83,0x8b,0xb6,0x97,0x85,0x8b,0xb4,0x3c,0x02,0xb0,0x02,
+0x24,0x63,0x00,0x28,0x00,0xa2,0x28,0x21,0x3c,0x04,0xb0,0x06,0xa7,0x83,0x8b,0xb6,
+0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00,0x8c,0x85,0x00,0x00,0x24,0x02,0x8f,0xff,
+0x24,0xc6,0x00,0x28,0x3c,0x03,0x0f,0x00,0x00,0xc2,0x30,0x24,0x00,0xa3,0x28,0x24,
+0x3c,0x02,0x04,0x00,0xaf,0x86,0x8b,0xb0,0x10,0xa2,0x00,0x03,0x00,0x00,0x00,0x00,
+0x0c,0x00,0x04,0x98,0x00,0x00,0x00,0x00,0x0c,0x00,0x02,0x38,0x00,0x00,0x00,0x00,
+0xa3,0x80,0x80,0x11,0x08,0x00,0x02,0xe7,0x00,0x00,0x00,0x00,0x97,0x82,0x83,0x46,
+0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xa7,0x82,0x83,0x46,0x84,0xa3,0x00,0x06,
+0x8f,0x82,0x83,0x58,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x21,0xaf,0x82,0x83,0x58,
+0x08,0x00,0x02,0xdf,0x25,0x42,0x00,0x01,0x97,0x82,0x83,0x42,0x00,0x00,0x00,0x00,
+0x24,0x42,0x00,0x01,0xa7,0x82,0x83,0x42,0x84,0xa3,0x00,0x06,0x8f,0x82,0x83,0x50,
+0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x21,0xaf,0x82,0x83,0x50,0x08,0x00,0x02,0xdf,
+0x25,0x42,0x00,0x01,0x97,0x82,0x83,0x3c,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,
+0xa7,0x82,0x83,0x3c,0x08,0x00,0x02,0xc7,0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xd0,
+0xaf,0xbf,0x00,0x28,0x8c,0xa3,0x00,0x20,0x8f,0x8a,0x8b,0xb0,0x3c,0x02,0x00,0x10,
+0x00,0x62,0x10,0x24,0x00,0xa0,0x38,0x21,0x01,0x40,0x48,0x21,0x10,0x40,0x00,0x3d,
+0x00,0x80,0x28,0x21,0x8c,0xe4,0x00,0x1c,0x34,0xa5,0x12,0x06,0xaf,0xa5,0x00,0x10,
+0x8c,0x82,0x00,0x08,0x00,0x03,0x1c,0x42,0x30,0x63,0x00,0x30,0x00,0x02,0x13,0x02,
+0x30,0x42,0x00,0x40,0x00,0x43,0x10,0x25,0x90,0xe6,0x00,0x10,0x90,0xe4,0x00,0x13,
+0x94,0xe8,0x00,0x0c,0x94,0xe3,0x00,0x1a,0x00,0x02,0x16,0x00,0x90,0xe7,0x00,0x12,
+0x00,0xa2,0x28,0x25,0x24,0x02,0x12,0x34,0xa7,0xa2,0x00,0x1c,0x24,0x02,0x56,0x78,
+0xaf,0xa5,0x00,0x10,0xa3,0xa6,0x00,0x18,0xa3,0xa7,0x00,0x1f,0xa7,0xa3,0x00,0x1a,
+0xa3,0xa4,0x00,0x19,0xa7,0xa8,0x00,0x20,0xa7,0xa2,0x00,0x22,0x00,0x00,0x28,0x21,
+0x27,0xa7,0x00,0x10,0x24,0x06,0x8f,0xff,0x00,0x05,0x10,0x80,0x00,0x47,0x10,0x21,
+0x8c,0x44,0x00,0x00,0x24,0xa3,0x00,0x01,0x30,0x65,0x00,0xff,0x25,0x22,0x00,0x04,
+0x2c,0xa3,0x00,0x05,0xad,0x24,0x00,0x00,0x14,0x60,0xff,0xf7,0x00,0x46,0x48,0x24,
+0x97,0x83,0x8b,0xb6,0x97,0x85,0x8b,0xb4,0x3c,0x02,0xb0,0x02,0x24,0x63,0x00,0x14,
+0x00,0xa2,0x28,0x21,0x3c,0x04,0xb0,0x06,0xa7,0x83,0x8b,0xb6,0x34,0x84,0x80,0x18,
+0xa4,0xa3,0x00,0x00,0x8c,0x85,0x00,0x00,0x24,0x02,0x8f,0xff,0x25,0x46,0x00,0x14,
+0x3c,0x03,0x0f,0x00,0x00,0xc2,0x50,0x24,0x00,0xa3,0x28,0x24,0x3c,0x02,0x04,0x00,
+0xaf,0x8a,0x8b,0xb0,0x10,0xa2,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x98,
+0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x28,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,
+0x27,0xbd,0x00,0x30,0x3c,0x05,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xc8,
+0x00,0x04,0x22,0x00,0x34,0xa5,0x00,0x20,0x24,0x42,0x0e,0x04,0x3c,0x03,0xb0,0x00,
+0xaf,0xb5,0x00,0x24,0xaf,0xb4,0x00,0x20,0xaf,0xb2,0x00,0x18,0xaf,0xb0,0x00,0x10,
+0xaf,0xbf,0x00,0x30,0x00,0x83,0x80,0x21,0xaf,0xb7,0x00,0x2c,0xaf,0xb6,0x00,0x28,
+0xaf,0xb3,0x00,0x1c,0xaf,0xb1,0x00,0x14,0xac,0xa2,0x00,0x00,0x8e,0x09,0x00,0x00,
+0x00,0x00,0x90,0x21,0x26,0x10,0x00,0x08,0x00,0x09,0xa6,0x02,0x12,0x80,0x00,0x13,
+0x00,0x00,0xa8,0x21,0x24,0x13,0x00,0x02,0x3c,0x16,0x00,0xff,0x3c,0x17,0xff,0x00,
+0x8e,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x12,0x02,0x24,0x42,0x00,0x02,
+0x31,0x25,0x00,0xff,0x10,0xb3,0x00,0x76,0x30,0x51,0x00,0xff,0x24,0x02,0x00,0x03,
+0x10,0xa2,0x00,0x18,0x00,0x00,0x00,0x00,0x02,0x51,0x10,0x21,0x30,0x52,0xff,0xff,
+0x02,0x54,0x18,0x2b,0x14,0x60,0xff,0xf2,0x02,0x11,0x80,0x21,0x12,0xa0,0x00,0x0a,
+0x3c,0x02,0xb0,0x06,0x34,0x42,0x80,0x18,0x8c,0x43,0x00,0x00,0x3c,0x04,0x0f,0x00,
+0x3c,0x02,0x04,0x00,0x00,0x64,0x18,0x24,0x10,0x62,0x00,0x03,0x00,0x00,0x00,0x00,
+0x0c,0x00,0x04,0x98,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x30,0x7b,0xb6,0x01,0x7c,
+0x7b,0xb4,0x01,0x3c,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,
+0x27,0xbd,0x00,0x38,0x8e,0x09,0x00,0x04,0x24,0x15,0x00,0x01,0x8e,0x06,0x00,0x0c,
+0x00,0x09,0x11,0x42,0x00,0x09,0x18,0xc2,0x30,0x48,0x00,0x03,0x00,0x09,0x14,0x02,
+0x30,0x6c,0x00,0x03,0x00,0x09,0x26,0x02,0x11,0x15,0x00,0x45,0x30,0x43,0x00,0x0f,
+0x29,0x02,0x00,0x02,0x14,0x40,0x00,0x26,0x00,0x00,0x00,0x00,0x11,0x13,0x00,0x0f,
+0x00,0x00,0x38,0x21,0x00,0x07,0x22,0x02,0x30,0x84,0xff,0x00,0x3c,0x03,0x00,0xff,
+0x00,0x07,0x2e,0x02,0x00,0x07,0x12,0x00,0x00,0x43,0x10,0x24,0x00,0xa4,0x28,0x25,
+0x00,0xa2,0x28,0x25,0x00,0x07,0x1e,0x00,0x00,0xa3,0x28,0x25,0x0c,0x00,0x01,0x94,
+0x01,0x20,0x20,0x21,0x08,0x00,0x03,0xa7,0x02,0x51,0x10,0x21,0x11,0x95,0x00,0x0f,
+0x00,0x00,0x00,0x00,0x11,0x88,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x04,0x10,0x80,
+0x27,0x83,0x8b,0x60,0x00,0x43,0x10,0x21,0x8c,0x47,0x00,0x18,0x08,0x00,0x03,0xce,
+0x00,0x07,0x22,0x02,0x00,0x04,0x10,0x40,0x27,0x83,0x8b,0x68,0x00,0x43,0x10,0x21,
+0x94,0x47,0x00,0x02,0x08,0x00,0x03,0xce,0x00,0x07,0x22,0x02,0x27,0x82,0x8b,0x60,
+0x00,0x82,0x10,0x21,0x90,0x47,0x00,0x00,0x08,0x00,0x03,0xce,0x00,0x07,0x22,0x02,
+0x15,0x00,0xff,0xdc,0x00,0x00,0x38,0x21,0x10,0x75,0x00,0x05,0x00,0x80,0x38,0x21,
+0x00,0x65,0x18,0x26,0x24,0x82,0x01,0x00,0x00,0x00,0x38,0x21,0x00,0x43,0x38,0x0a,
+0x24,0x02,0x00,0x01,0x11,0x82,0x00,0x0e,0x3c,0x02,0xb0,0x03,0x24,0x02,0x00,0x02,
+0x11,0x82,0x00,0x06,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x00,0xe2,0x10,0x21,
+0x8c,0x47,0x00,0x00,0x08,0x00,0x03,0xce,0x00,0x07,0x22,0x02,0x3c,0x02,0xb0,0x03,
+0x00,0xe2,0x10,0x21,0x94,0x43,0x00,0x00,0x08,0x00,0x03,0xcd,0x30,0x67,0xff,0xff,
+0x00,0xe2,0x10,0x21,0x90,0x43,0x00,0x00,0x08,0x00,0x03,0xcd,0x30,0x67,0x00,0xff,
+0x30,0x62,0x00,0x03,0x00,0x02,0x12,0x00,0x11,0x95,0x00,0x07,0x00,0x44,0x38,0x21,
+0x11,0x93,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x03,0xff,0x3c,0x02,0xb0,0x0a,
+0x08,0x00,0x04,0x04,0x3c,0x02,0xb0,0x0a,0x08,0x00,0x04,0x08,0x3c,0x02,0xb0,0x0a,
+0x8e,0x09,0x00,0x04,0x8e,0x02,0x00,0x08,0x8e,0x03,0x00,0x0c,0x00,0x09,0x41,0x42,
+0x00,0x02,0x22,0x02,0x00,0x03,0x3a,0x02,0x30,0x84,0xff,0x00,0x30,0xe7,0xff,0x00,
+0x00,0x02,0x5e,0x02,0x00,0x02,0x32,0x00,0x00,0x03,0x56,0x02,0x00,0x03,0x2a,0x00,
+0x01,0x64,0x58,0x25,0x00,0xd6,0x30,0x24,0x01,0x47,0x50,0x25,0x00,0x02,0x16,0x00,
+0x00,0xb6,0x28,0x24,0x00,0x03,0x1e,0x00,0x01,0x66,0x58,0x25,0x01,0x45,0x50,0x25,
+0x00,0x57,0x10,0x24,0x00,0x77,0x18,0x24,0x01,0x62,0x38,0x25,0x01,0x43,0x30,0x25,
+0x00,0x09,0x10,0xc2,0x00,0x09,0x1c,0x02,0x31,0x08,0x00,0x03,0x30,0x4c,0x00,0x03,
+0x30,0x63,0x00,0x0f,0x00,0x09,0x26,0x02,0x00,0xe0,0x58,0x21,0x15,0x00,0x00,0x28,
+0x00,0xc0,0x50,0x21,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x06,0x00,0x80,0x28,0x21,
+0x24,0x02,0x00,0x03,0x14,0x62,0xff,0x69,0x02,0x51,0x10,0x21,0x24,0x85,0x01,0x00,
+0x24,0x02,0x00,0x01,0x11,0x82,0x00,0x15,0x24,0x02,0x00,0x02,0x11,0x82,0x00,0x0a,
+0x3c,0x03,0xb0,0x03,0x00,0xa3,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x0a,0x20,0x27,
+0x01,0x6a,0x28,0x24,0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25,0xac,0x62,0x00,0x00,
+0x08,0x00,0x03,0xa7,0x02,0x51,0x10,0x21,0x00,0xa3,0x18,0x21,0x94,0x62,0x00,0x00,
+0x00,0x0a,0x20,0x27,0x01,0x6a,0x28,0x24,0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25,
+0xa4,0x62,0x00,0x00,0x08,0x00,0x03,0xa7,0x02,0x51,0x10,0x21,0x3c,0x03,0xb0,0x03,
+0x00,0xa3,0x18,0x21,0x90,0x62,0x00,0x00,0x00,0x0a,0x20,0x27,0x01,0x6a,0x28,0x24,
+0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25,0x08,0x00,0x03,0xa6,0xa0,0x62,0x00,0x00,
+0x24,0x02,0x00,0x01,0x11,0x02,0x00,0x21,0x00,0x00,0x00,0x00,0x15,0x13,0xff,0x42,
+0x00,0x00,0x00,0x00,0x11,0x82,0x00,0x17,0x00,0x00,0x00,0x00,0x11,0x88,0x00,0x0b,
+0x00,0x00,0x00,0x00,0x27,0x83,0x8b,0x60,0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,
+0x8c,0x82,0x00,0x18,0x00,0x06,0x18,0x27,0x00,0xe6,0x28,0x24,0x00,0x43,0x10,0x24,
+0x00,0x45,0x10,0x25,0x08,0x00,0x03,0xa6,0xac,0x82,0x00,0x18,0x27,0x83,0x8b,0x68,
+0x00,0x04,0x20,0x40,0x00,0x83,0x20,0x21,0x94,0x82,0x00,0x02,0x00,0x06,0x18,0x27,
+0x00,0xe6,0x28,0x24,0x00,0x43,0x10,0x24,0x00,0x45,0x10,0x25,0x08,0x00,0x03,0xa6,
+0xa4,0x82,0x00,0x02,0x27,0x83,0x8b,0x60,0x00,0x83,0x18,0x21,0x90,0x62,0x00,0x00,
+0x00,0x06,0x20,0x27,0x08,0x00,0x04,0x5c,0x00,0xe6,0x28,0x24,0x30,0x62,0x00,0x07,
+0x00,0x02,0x12,0x00,0x11,0x88,0x00,0x0f,0x00,0x44,0x10,0x21,0x11,0x93,0x00,0x07,
+0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x0a,0x00,0x43,0x18,0x21,0x8c,0x62,0x00,0x00,
+0x00,0x06,0x20,0x27,0x08,0x00,0x04,0x49,0x00,0xe6,0x28,0x24,0x3c,0x03,0xb0,0x0a,
+0x00,0x43,0x18,0x21,0x94,0x62,0x00,0x00,0x00,0x06,0x20,0x27,0x08,0x00,0x04,0x52,
+0x00,0xe6,0x28,0x24,0x3c,0x03,0xb0,0x0a,0x08,0x00,0x04,0x7f,0x00,0x43,0x18,0x21,
+0x97,0x85,0x8b,0xb4,0x3c,0x07,0xb0,0x02,0x3c,0x04,0xb0,0x03,0x3c,0x02,0x80,0x00,
+0x00,0xa7,0x28,0x21,0x34,0x84,0x00,0x20,0x24,0x42,0x12,0x60,0x24,0x03,0xff,0x80,
+0xac,0x82,0x00,0x00,0xa0,0xa3,0x00,0x07,0x97,0x82,0x8b,0xb6,0x97,0x85,0x8b,0xb4,
+0x3c,0x06,0xb0,0x06,0x30,0x42,0xff,0xf8,0x24,0x42,0x00,0x10,0x00,0xa2,0x10,0x21,
+0x30,0x42,0x0f,0xff,0x24,0x44,0x00,0x08,0x30,0x84,0x0f,0xff,0x00,0x05,0x28,0xc2,
+0x3c,0x03,0x00,0x40,0x00,0xa3,0x28,0x25,0x00,0x87,0x20,0x21,0x34,0xc6,0x80,0x18,
+0xac,0xc5,0x00,0x00,0xaf,0x84,0x8b,0xb0,0xa7,0x82,0x8b,0xb4,0xa7,0x80,0x8b,0xb6,
+0xaf,0x80,0x8b,0xb8,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa5,0x00,0xff,
+0x30,0x84,0x00,0xff,0x24,0x02,0x00,0x01,0x00,0xe0,0x48,0x21,0x30,0xc6,0x00,0xff,
+0x8f,0xa7,0x00,0x10,0x10,0x82,0x00,0x07,0x00,0xa0,0x40,0x21,0x24,0x02,0x00,0x03,
+0x10,0x82,0x00,0x03,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
+0x24,0xa8,0x01,0x00,0x3c,0x03,0xb0,0x03,0x24,0x02,0x00,0x01,0x00,0x07,0x20,0x27,
+0x01,0x27,0x28,0x24,0x10,0xc2,0x00,0x14,0x01,0x03,0x18,0x21,0x24,0x02,0x00,0x02,
+0x10,0xc2,0x00,0x09,0x00,0x07,0x50,0x27,0x3c,0x03,0xb0,0x03,0x01,0x03,0x18,0x21,
+0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,0x00,0x45,0x10,0x25,
+0x08,0x00,0x04,0xe3,0xac,0x62,0x00,0x00,0x3c,0x03,0xb0,0x03,0x01,0x03,0x18,0x21,
+0x94,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,0x00,0x45,0x10,0x25,
+0x03,0xe0,0x00,0x08,0xa4,0x62,0x00,0x00,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25,0xa0,0x62,0x00,0x00,0x03,0xe0,0x00,0x08,
+0x00,0x00,0x00,0x00,0x30,0x84,0x00,0x07,0x00,0x04,0x22,0x00,0x30,0xa5,0x00,0xff,
+0x00,0x85,0x28,0x21,0x3c,0x02,0xb0,0x0a,0x00,0xa2,0x40,0x21,0x30,0xc6,0x00,0xff,
+0x24,0x02,0x00,0x01,0x8f,0xa4,0x00,0x10,0x10,0xc2,0x00,0x14,0x24,0x02,0x00,0x02,
+0x00,0x04,0x50,0x27,0x10,0xc2,0x00,0x09,0x00,0xe4,0x48,0x24,0x3c,0x03,0xb0,0x0a,
+0x00,0xa3,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,
+0x00,0x49,0x10,0x25,0x03,0xe0,0x00,0x08,0xac,0x62,0x00,0x00,0x3c,0x03,0xb0,0x0a,
+0x00,0xa3,0x18,0x21,0x94,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,
+0x00,0x49,0x10,0x25,0x03,0xe0,0x00,0x08,0xa4,0x62,0x00,0x00,0x91,0x02,0x00,0x00,
+0x00,0x04,0x18,0x27,0x00,0xe4,0x20,0x24,0x00,0x43,0x10,0x24,0x00,0x44,0x10,0x25,
+0x03,0xe0,0x00,0x08,0xa1,0x02,0x00,0x00,0x30,0xa9,0x00,0xff,0x27,0x83,0x8b,0x60,
+0x30,0x85,0x00,0xff,0x24,0x02,0x00,0x01,0x00,0x07,0x50,0x27,0x00,0xc7,0x40,0x24,
+0x11,0x22,0x00,0x17,0x00,0xa3,0x18,0x21,0x00,0x05,0x20,0x40,0x27,0x82,0x8b,0x60,
+0x00,0x05,0x28,0x80,0x27,0x83,0x8b,0x68,0x00,0x83,0x50,0x21,0x00,0xa2,0x20,0x21,
+0x24,0x02,0x00,0x02,0x00,0x07,0x40,0x27,0x11,0x22,0x00,0x07,0x00,0xc7,0x28,0x24,
+0x8c,0x82,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x48,0x10,0x24,0x00,0x45,0x10,0x25,
+0x03,0xe0,0x00,0x08,0xac,0x82,0x00,0x18,0x95,0x42,0x00,0x02,0x00,0x00,0x00,0x00,
+0x00,0x48,0x10,0x24,0x00,0x45,0x10,0x25,0x03,0xe0,0x00,0x08,0xa5,0x42,0x00,0x02,
+0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,0x00,0x48,0x10,0x25,
+0x03,0xe0,0x00,0x08,0xa0,0x62,0x00,0x00,0x00,0x04,0x32,0x02,0x30,0xc6,0xff,0x00,
+0x00,0x04,0x16,0x02,0x00,0x04,0x1a,0x00,0x3c,0x05,0x00,0xff,0x00,0x65,0x18,0x24,
+0x00,0x46,0x10,0x25,0x00,0x43,0x10,0x25,0x00,0x04,0x26,0x00,0x03,0xe0,0x00,0x08,
+0x00,0x44,0x10,0x25,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xe8,
+0x34,0x63,0x00,0x20,0x24,0x42,0x14,0xe4,0x3c,0x04,0xb0,0x03,0xaf,0xbf,0x00,0x14,
+0xac,0x62,0x00,0x00,0xaf,0xb0,0x00,0x10,0x34,0x84,0x00,0x2c,0x8c,0x83,0x00,0x00,
+0xa7,0x80,0xbb,0xf0,0x00,0x03,0x12,0x02,0x00,0x03,0x2d,0x02,0x30,0x42,0x0f,0xff,
+0xa3,0x83,0xbb,0xf8,0xa7,0x85,0xbb,0xfc,0xa7,0x82,0xbb,0xfa,0xa7,0x80,0xbb,0xf2,
+0xa7,0x80,0xbb,0xf4,0xa7,0x80,0xbb,0xf6,0x0c,0x00,0x06,0xce,0x24,0x04,0x05,0x00,
+0x3c,0x05,0x08,0x00,0x00,0x45,0x28,0x25,0x24,0x04,0x05,0x00,0x0c,0x00,0x06,0xc1,
+0x00,0x40,0x80,0x21,0x3c,0x02,0xf7,0xff,0x34,0x42,0xff,0xff,0x02,0x02,0x80,0x24,
+0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xc1,0x24,0x04,0x05,0x00,0x3c,0x02,0xb0,0x03,
+0x3c,0x03,0xb0,0x03,0x34,0x42,0x01,0x08,0x34,0x63,0x01,0x18,0x8c,0x45,0x00,0x00,
+0x8c,0x64,0x00,0x00,0x3c,0x02,0x00,0x0f,0x3c,0x03,0x00,0x4c,0x30,0x84,0x02,0x00,
+0x34,0x63,0x4b,0x40,0xaf,0x85,0xbc,0x00,0x10,0x80,0x00,0x06,0x34,0x42,0x42,0x40,
+0xaf,0x83,0xbc,0x04,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,
+0x27,0xbd,0x00,0x18,0xaf,0x82,0xbc,0x04,0x08,0x00,0x05,0x69,0x00,0x00,0x00,0x00,
+0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xc8,0x34,0x63,0x00,0x20,
+0x24,0x42,0x15,0xc0,0x30,0x84,0x00,0xff,0xaf,0xbf,0x00,0x30,0xaf,0xb7,0x00,0x2c,
+0xaf,0xb6,0x00,0x28,0xaf,0xb5,0x00,0x24,0xaf,0xb4,0x00,0x20,0xaf,0xb3,0x00,0x1c,
+0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xac,0x62,0x00,0x00,
+0x10,0x80,0x00,0x1c,0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x08,0x00,0x00,0x00,0x00,
+0x8f,0xbf,0x00,0x30,0x7b,0xb6,0x01,0x7c,0x7b,0xb4,0x01,0x3c,0x7b,0xb2,0x00,0xfc,
+0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0xa7,0x80,0xbb,0xf0,
+0xa7,0x80,0xbb,0xf2,0xa7,0x80,0xbb,0xf4,0xa7,0x80,0xbb,0xf6,0x0c,0x00,0x06,0xce,
+0x24,0x04,0x05,0x00,0x3c,0x05,0x08,0x00,0x00,0x45,0x28,0x25,0x24,0x04,0x05,0x00,
+0x0c,0x00,0x06,0xc1,0x00,0x40,0x80,0x21,0x3c,0x05,0xf7,0xff,0x34,0xa5,0xff,0xff,
+0x02,0x05,0x28,0x24,0x0c,0x00,0x06,0xc1,0x24,0x04,0x05,0x00,0x08,0x00,0x05,0x84,
+0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xce,0x24,0x04,0x05,0xa0,0x24,0x04,0x05,0xa4,
+0x0c,0x00,0x06,0xce,0x00,0x02,0xbc,0x02,0x24,0x04,0x05,0xa8,0x00,0x02,0xb4,0x02,
+0x0c,0x00,0x06,0xce,0x30,0x55,0xff,0xff,0x00,0x40,0x80,0x21,0x97,0x84,0xbb,0xf0,
+0x97,0x82,0xbb,0xf2,0x97,0x83,0xbb,0xf6,0x02,0xe4,0x20,0x23,0x02,0xa2,0x10,0x23,
+0x00,0x82,0x20,0x21,0x97,0x82,0xbb,0xf4,0x32,0x14,0xff,0xff,0x02,0x83,0x18,0x23,
+0x02,0xc2,0x10,0x23,0x00,0x82,0x20,0x21,0x93,0x82,0xbb,0xf8,0x00,0x83,0x20,0x21,
+0x30,0x84,0xff,0xff,0x00,0x82,0x10,0x2b,0x14,0x40,0x00,0xaa,0x00,0x00,0x00,0x00,
+0x97,0x82,0xbb,0xfc,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x2b,0x14,0x40,0x00,0x7f,
+0x00,0x00,0x00,0x00,0x97,0x82,0xbb,0xfa,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x2b,
+0x10,0x40,0x00,0x3a,0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xce,0x24,0x04,0x04,0x50,
+0x30,0x51,0x00,0x7f,0x00,0x40,0x80,0x21,0x2e,0x22,0x00,0x32,0x10,0x40,0x00,0x13,
+0x24,0x02,0x00,0x20,0x12,0x22,0x00,0x17,0x24,0x02,0xff,0x80,0x02,0x02,0x10,0x24,
+0x26,0x31,0x00,0x01,0x00,0x51,0x80,0x25,0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xc1,
+0x24,0x04,0x04,0x50,0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xc1,0x24,0x04,0x04,0x58,
+0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xc1,0x24,0x04,0x04,0x60,0x02,0x00,0x28,0x21,
+0x24,0x04,0x04,0x68,0x0c,0x00,0x06,0xc1,0x00,0x00,0x00,0x00,0xa7,0x97,0xbb,0xf0,
+0xa7,0x95,0xbb,0xf2,0xa7,0x96,0xbb,0xf4,0xa7,0x94,0xbb,0xf6,0x08,0x00,0x05,0x84,
+0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0,
+0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24,0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x03,
+0x10,0x43,0x00,0x07,0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,
+0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25,0x0c,0x00,0x06,0xc1,0x24,0x04,0x02,0x08,
+0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x2c,0x00,0x40,0x90,0x21,0x3c,0x02,0xff,0xff,
+0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24,0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xc1,
+0x24,0x04,0x02,0x2c,0x08,0x00,0x05,0xcb,0x24,0x02,0xff,0x80,0x0c,0x00,0x06,0xce,
+0x24,0x04,0x04,0x50,0x30,0x51,0x00,0x7f,0x24,0x02,0x00,0x20,0x16,0x22,0xff,0xdb,
+0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x2c,0x34,0x52,0x40,0x00,
+0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xc1,0x24,0x04,0x02,0x2c,0x0c,0x00,0x06,0xce,
+0x24,0x04,0x02,0x58,0x24,0x04,0x02,0x5c,0x0c,0x00,0x06,0xce,0x00,0x02,0x9e,0x02,
+0x30,0x43,0x00,0xff,0x00,0x13,0x12,0x00,0x00,0x43,0x10,0x25,0x2c,0x43,0x00,0x04,
+0x14,0x60,0x00,0x1d,0x2c,0x42,0x00,0x11,0x10,0x40,0x00,0x0b,0x00,0x00,0x00,0x00,
+0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24,0x02,0x40,0x28,0x21,
+0x24,0x04,0x02,0x2c,0x0c,0x00,0x06,0xc1,0x36,0x52,0x80,0x00,0x02,0x40,0x28,0x21,
+0x08,0x00,0x05,0xd9,0x24,0x04,0x02,0x2c,0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x08,
+0x3c,0x04,0x00,0xc0,0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24,0x00,0x02,0x15,0x82,
+0x24,0x03,0x00,0x02,0x14,0x43,0xff,0xee,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,
+0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25,0x0c,0x00,0x06,0xc1,0x24,0x04,0x02,0x08,
+0x08,0x00,0x06,0x15,0x3c,0x02,0xff,0xff,0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x08,
+0x00,0x40,0x28,0x21,0x00,0x02,0x15,0x82,0x30,0x42,0x00,0x03,0x24,0x03,0x00,0x03,
+0x14,0x43,0xff,0xdf,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,
+0x3c,0x03,0x00,0x80,0x08,0x00,0x06,0x2a,0x00,0x43,0x28,0x25,0x0c,0x00,0x06,0xce,
+0x24,0x04,0x04,0x50,0x30,0x51,0x00,0x7f,0x00,0x40,0x80,0x21,0x2e,0x22,0x00,0x32,
+0x10,0x40,0xff,0x9a,0x24,0x02,0x00,0x20,0x12,0x22,0x00,0x04,0x24,0x02,0xff,0x80,
+0x02,0x02,0x10,0x24,0x08,0x00,0x05,0xcd,0x26,0x31,0x00,0x02,0x0c,0x00,0x06,0xce,
+0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0,0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24,
+0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x03,0x10,0x43,0x00,0x07,0x00,0x00,0x00,0x00,
+0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25,
+0x0c,0x00,0x06,0xc1,0x24,0x04,0x02,0x08,0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x2c,
+0x00,0x40,0x90,0x21,0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24,
+0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xc1,0x24,0x04,0x02,0x2c,0x08,0x00,0x06,0x44,
+0x24,0x02,0xff,0x80,0x0c,0x00,0x06,0xce,0x24,0x04,0x04,0x50,0x00,0x40,0x80,0x21,
+0x30,0x51,0x00,0x7f,0x24,0x02,0x00,0x20,0x12,0x22,0x00,0x1d,0x2e,0x22,0x00,0x21,
+0x14,0x40,0xff,0x72,0x24,0x02,0xff,0x80,0x02,0x02,0x10,0x24,0x26,0x31,0xff,0xff,
+0x00,0x51,0x80,0x25,0x24,0x04,0x04,0x50,0x0c,0x00,0x06,0xc1,0x02,0x00,0x28,0x21,
+0x24,0x04,0x04,0x58,0x0c,0x00,0x06,0xc1,0x02,0x00,0x28,0x21,0x24,0x04,0x04,0x60,
+0x0c,0x00,0x06,0xc1,0x02,0x00,0x28,0x21,0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xc1,
+0x24,0x04,0x04,0x68,0x24,0x02,0x00,0x20,0x16,0x22,0xff,0x60,0x00,0x00,0x00,0x00,
+0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x2c,0x00,0x40,0x90,0x21,0x3c,0x02,0xff,0xff,
+0x34,0x42,0x3f,0xff,0x02,0x42,0x10,0x24,0x08,0x00,0x06,0x1b,0x34,0x52,0x80,0x00,
+0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x2c,0x34,0x52,0x40,0x00,0x02,0x40,0x28,0x21,
+0x0c,0x00,0x06,0xc1,0x24,0x04,0x02,0x2c,0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x58,
+0x24,0x04,0x02,0x5c,0x0c,0x00,0x06,0xce,0x00,0x02,0x9e,0x02,0x30,0x43,0x00,0xff,
+0x00,0x13,0x12,0x00,0x00,0x43,0x10,0x25,0x2c,0x43,0x00,0x04,0x14,0x60,0x00,0x20,
+0x2c,0x42,0x00,0x11,0x10,0x40,0x00,0x0d,0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0xff,
+0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24,0x02,0x40,0x28,0x21,0x24,0x04,0x02,0x2c,
+0x0c,0x00,0x06,0xc1,0x36,0x52,0x80,0x00,0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xc1,
+0x24,0x04,0x02,0x2c,0x08,0x00,0x06,0x68,0x2e,0x22,0x00,0x21,0x0c,0x00,0x06,0xce,
+0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0,0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24,
+0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x02,0x14,0x43,0xff,0xec,0x00,0x00,0x00,0x00,
+0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25,
+0x0c,0x00,0x06,0xc1,0x24,0x04,0x02,0x08,0x08,0x00,0x06,0x98,0x3c,0x02,0xff,0xff,
+0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x08,0x00,0x40,0x28,0x21,0x00,0x02,0x15,0x82,
+0x30,0x42,0x00,0x03,0x24,0x03,0x00,0x03,0x14,0x43,0xff,0xdc,0x3c,0x03,0x00,0x80,
+0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,0x08,0x00,0x06,0xb0,
+0x00,0x43,0x28,0x25,0x30,0x83,0x00,0x03,0x00,0x04,0x20,0x40,0x00,0x83,0x20,0x23,
+0x3c,0x02,0xb0,0x0a,0x00,0x82,0x20,0x21,0xac,0x85,0x00,0x00,0x00,0x00,0x18,0x21,
+0x24,0x63,0x00,0x01,0x2c,0x62,0x00,0x0a,0x14,0x40,0xff,0xfe,0x24,0x63,0x00,0x01,
+0x03,0xe0,0x00,0x08,0x24,0x63,0xff,0xff,0x30,0x86,0x00,0x03,0x00,0x04,0x28,0x40,
+0x3c,0x03,0xb0,0x0a,0x00,0xa6,0x10,0x23,0x00,0x43,0x10,0x21,0x24,0x04,0xff,0xff,
+0xac,0x44,0x10,0x00,0x00,0x00,0x18,0x21,0x24,0x63,0x00,0x01,0x2c,0x62,0x00,0x0a,
+0x14,0x40,0xff,0xfe,0x24,0x63,0x00,0x01,0x24,0x63,0xff,0xff,0x00,0xa6,0x18,0x23,
+0x3c,0x02,0xb0,0x0a,0x00,0x62,0x18,0x21,0x8c,0x62,0x00,0x00,0x03,0xe0,0x00,0x08,
+0x00,0x00,0x00,0x00,0x3c,0x05,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x1b,0x84,
+0x24,0x03,0x00,0x01,0x34,0xa5,0x00,0x20,0x3c,0x06,0xb0,0x03,0xac,0xa2,0x00,0x00,
+0x34,0xc6,0x01,0x04,0xa0,0x83,0x00,0x48,0xa0,0x80,0x00,0x04,0xa0,0x80,0x00,0x05,
+0xa0,0x80,0x00,0x06,0xa0,0x80,0x00,0x07,0xa0,0x80,0x00,0x08,0xa0,0x80,0x00,0x09,
+0xa0,0x80,0x00,0x0a,0xa0,0x80,0x00,0x11,0xa0,0x80,0x00,0x13,0xa0,0x80,0x00,0x49,
+0x94,0xc2,0x00,0x00,0xac,0x80,0x00,0x00,0xa0,0x80,0x00,0x4e,0x00,0x02,0x14,0x00,
+0x00,0x02,0x14,0x03,0x30,0x43,0x00,0xff,0x30,0x42,0xff,0x00,0xa4,0x82,0x00,0x44,
+0xa4,0x83,0x00,0x46,0xac,0x80,0x00,0x24,0xac,0x80,0x00,0x28,0xac,0x80,0x00,0x2c,
+0xac,0x80,0x00,0x30,0xac,0x80,0x00,0x34,0xac,0x80,0x00,0x38,0xac,0x80,0x00,0x3c,
+0x03,0xe0,0x00,0x08,0xac,0x80,0x00,0x40,0x84,0x83,0x00,0x0c,0x3c,0x07,0xb0,0x03,
+0x34,0xe7,0x00,0x20,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,
+0x27,0x83,0x8f,0xf4,0x00,0x43,0x10,0x21,0x8c,0x48,0x00,0x18,0x3c,0x02,0x80,0x00,
+0x24,0x42,0x1c,0x18,0xac,0xe2,0x00,0x00,0x8d,0x03,0x00,0x08,0x80,0x82,0x00,0x13,
+0x00,0x05,0x2c,0x00,0x00,0x03,0x1e,0x02,0x00,0x02,0x12,0x00,0x30,0x63,0x00,0x7e,
+0x00,0x62,0x18,0x21,0x00,0x65,0x18,0x21,0x3c,0x02,0xc0,0x00,0x3c,0x05,0xb0,0x05,
+0x34,0x42,0x04,0x00,0x24,0x63,0x00,0x01,0x3c,0x07,0xb0,0x05,0x3c,0x08,0xb0,0x05,
+0x34,0xa5,0x04,0x20,0xac,0xa3,0x00,0x00,0x00,0xc2,0x30,0x21,0x34,0xe7,0x04,0x24,
+0x35,0x08,0x02,0x28,0x24,0x02,0x00,0x01,0x24,0x03,0x00,0x20,0xac,0xe6,0x00,0x00,
+0xac,0x82,0x00,0x3c,0x03,0xe0,0x00,0x08,0xa1,0x03,0x00,0x00,0x27,0xbd,0xff,0xa8,
+0x00,0x07,0x60,0x80,0x27,0x82,0xb3,0xf0,0xaf,0xbe,0x00,0x50,0xaf,0xb7,0x00,0x4c,
+0xaf,0xb5,0x00,0x44,0xaf,0xb4,0x00,0x40,0xaf,0xbf,0x00,0x54,0xaf,0xb6,0x00,0x48,
+0xaf,0xb3,0x00,0x3c,0xaf,0xb2,0x00,0x38,0xaf,0xb1,0x00,0x34,0xaf,0xb0,0x00,0x30,
+0x01,0x82,0x10,0x21,0x8c,0x43,0x00,0x00,0x00,0xe0,0x70,0x21,0x3c,0x02,0x80,0x00,
+0x94,0x73,0x00,0x14,0x3c,0x07,0xb0,0x03,0x34,0xe7,0x00,0x20,0x24,0x42,0x1c,0xac,
+0x3c,0x03,0xb0,0x05,0xac,0xe2,0x00,0x00,0x34,0x63,0x01,0x28,0x90,0x67,0x00,0x00,
+0x00,0x13,0xa8,0xc0,0x02,0xb3,0x18,0x21,0x27,0x82,0x8f,0xf4,0x00,0x03,0x18,0x80,
+0x00,0x62,0x18,0x21,0x00,0x05,0x2c,0x00,0x00,0x07,0x3e,0x00,0x28,0xc2,0x00,0x03,
+0x00,0xc0,0xa0,0x21,0x00,0x80,0x78,0x21,0x00,0x05,0xbc,0x03,0x8c,0x68,0x00,0x18,
+0x02,0xa0,0x58,0x21,0x10,0x40,0x01,0x81,0x00,0x07,0xf6,0x03,0x00,0xde,0x10,0x07,
+0x30,0x5e,0x00,0x01,0x01,0x73,0x10,0x21,0x27,0x83,0x8f,0xf8,0x00,0x02,0x10,0x80,
+0x00,0x43,0x10,0x21,0x80,0x4d,0x00,0x06,0x8d,0x03,0x00,0x00,0x8d,0x02,0x00,0x04,
+0x8d,0x0a,0x00,0x08,0x8d,0x03,0x00,0x0c,0xaf,0xa2,0x00,0x20,0x11,0xa0,0x01,0x71,
+0xaf,0xa3,0x00,0x18,0x27,0x82,0xb3,0xf0,0x01,0x82,0x10,0x21,0x8c,0x44,0x00,0x00,
+0x00,0x00,0x00,0x00,0x90,0x83,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x04,
+0x14,0x60,0x00,0x12,0x00,0x00,0xb0,0x21,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x46,
+0x90,0x43,0x00,0x00,0x2a,0x84,0x00,0x04,0x10,0x80,0x01,0x56,0x30,0x65,0x00,0x01,
+0x91,0xe2,0x00,0x09,0x00,0x00,0x00,0x00,0x12,0x82,0x00,0x02,0x00,0x00,0x00,0x00,
+0x00,0x00,0x28,0x21,0x14,0xa0,0x00,0x03,0x00,0x00,0x38,0x21,0x13,0xc0,0x00,0x03,
+0x38,0xf6,0x00,0x01,0x24,0x07,0x00,0x01,0x38,0xf6,0x00,0x01,0x01,0x73,0x10,0x21,
+0x00,0x02,0x30,0x80,0x27,0x83,0x90,0x00,0x00,0xc3,0x48,0x21,0x91,0x25,0x00,0x00,
+0x8f,0xa4,0x00,0x20,0x2c,0xa3,0x00,0x04,0x00,0x04,0x11,0xc3,0x30,0x42,0x00,0x01,
+0x00,0x03,0xb0,0x0b,0x12,0xc0,0x00,0xd8,0xaf,0xa2,0x00,0x24,0x93,0x90,0xbb,0xda,
+0x00,0x0a,0x16,0x42,0x30,0x52,0x00,0x3f,0x2e,0x06,0x00,0x0c,0x10,0xc0,0x00,0xc0,
+0x00,0xa0,0x20,0x21,0x2c,0xa2,0x00,0x10,0x14,0x40,0x00,0x04,0x00,0x90,0x10,0x2b,
+0x30,0xa2,0x00,0x07,0x24,0x44,0x00,0x04,0x00,0x90,0x10,0x2b,0x10,0x40,0x00,0x0b,
+0x01,0x73,0x10,0x21,0x27,0x85,0xbb,0x0c,0x00,0x10,0x10,0x40,0x00,0x50,0x10,0x21,
+0x00,0x45,0x10,0x21,0x90,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x18,0x2b,
+0x14,0x60,0xff,0xfa,0x00,0x10,0x10,0x40,0x01,0x73,0x10,0x21,0x00,0x02,0x10,0x80,
+0x27,0x83,0x8f,0xf8,0x00,0x43,0x10,0x21,0x31,0xa4,0x00,0x01,0x10,0x80,0x00,0xa5,
+0xa0,0x50,0x00,0x07,0x3c,0x04,0xb0,0x05,0x34,0x84,0x00,0x08,0x24,0x02,0x00,0x01,
+0x3c,0x03,0x80,0x00,0xa1,0xe2,0x00,0x4e,0xac,0x83,0x00,0x00,0x8c,0x85,0x00,0x00,
+0x3c,0x02,0x00,0xf0,0x3c,0x03,0x40,0xf0,0x34,0x42,0xf0,0x00,0x34,0x63,0xf0,0x00,
+0x24,0x17,0x00,0x0e,0x24,0x13,0x01,0x06,0xac,0x82,0x00,0x00,0xac,0x83,0x00,0x00,
+0x27,0x82,0xb3,0xf0,0x01,0x82,0x10,0x21,0x8c,0x43,0x00,0x00,0x24,0x05,0x00,0x01,
+0xaf,0xa5,0x00,0x1c,0x90,0x62,0x00,0x16,0x00,0x13,0xa8,0xc0,0x32,0x51,0x00,0x02,
+0x34,0x42,0x00,0x04,0xa0,0x62,0x00,0x16,0x8f,0xa3,0x00,0x20,0x8f,0xa4,0x00,0x18,
+0x00,0x03,0x13,0x43,0x00,0x04,0x1a,0x02,0x30,0x47,0x00,0x01,0x12,0x20,0x00,0x04,
+0x30,0x64,0x07,0xff,0x2e,0x03,0x00,0x04,0x32,0x42,0x00,0x33,0x00,0x43,0x90,0x0b,
+0x8f,0xa5,0x00,0x24,0x8f,0xa6,0x00,0x1c,0x00,0x12,0x10,0x40,0x00,0x05,0x19,0xc0,
+0x00,0x47,0x10,0x21,0x00,0x06,0x2a,0x80,0x00,0x43,0x10,0x21,0x00,0x10,0x32,0x00,
+0x00,0x04,0x24,0x80,0x02,0x65,0x28,0x21,0x00,0xa4,0x28,0x21,0x00,0x46,0x10,0x21,
+0x00,0x17,0x1c,0x00,0x3c,0x04,0xc0,0x00,0x00,0x43,0x30,0x21,0x16,0x80,0x00,0x29,
+0x00,0xa4,0x28,0x21,0x3c,0x02,0xb0,0x05,0x34,0x42,0x04,0x00,0x3c,0x03,0xb0,0x05,
+0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x04,0x34,0x84,0x02,0x28,
+0x24,0x02,0x00,0x01,0xac,0x65,0x00,0x00,0xa0,0x82,0x00,0x00,0x3c,0x02,0xb0,0x09,
+0x34,0x42,0x01,0x46,0x90,0x44,0x00,0x00,0x91,0xe3,0x00,0x09,0x30,0x86,0x00,0x01,
+0x02,0x83,0x18,0x26,0x00,0x03,0x30,0x0b,0x14,0xc0,0x00,0x03,0x00,0x00,0x28,0x21,
+0x13,0xc0,0x00,0x03,0x02,0xb3,0x10,0x21,0x24,0x05,0x00,0x01,0x02,0xb3,0x10,0x21,
+0x27,0x83,0x8f,0xf8,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x84,0x48,0x00,0x04,
+0x00,0xa0,0x30,0x21,0x00,0xe0,0x20,0x21,0x02,0x80,0x28,0x21,0x02,0xc0,0x38,0x21,
+0x0c,0x00,0x00,0x72,0xaf,0xa8,0x00,0x10,0x7b,0xbe,0x02,0xbc,0x7b,0xb6,0x02,0x7c,
+0x7b,0xb4,0x02,0x3c,0x7b,0xb2,0x01,0xfc,0x7b,0xb0,0x01,0xbc,0x03,0xe0,0x00,0x08,
+0x27,0xbd,0x00,0x58,0x24,0x02,0x00,0x01,0x12,0x82,0x00,0x3d,0x3c,0x02,0xb0,0x05,
+0x24,0x02,0x00,0x02,0x12,0x82,0x00,0x31,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x03,
+0x12,0x82,0x00,0x25,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x10,0x12,0x82,0x00,0x19,
+0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x11,0x12,0x82,0x00,0x0d,0x3c,0x02,0xb0,0x05,
+0x24,0x02,0x00,0x12,0x16,0x82,0xff,0xd1,0x3c,0x02,0xb0,0x05,0x3c,0x03,0xb0,0x05,
+0x34,0x42,0x04,0x20,0x3c,0x04,0xb0,0x05,0x34,0x63,0x04,0x24,0xac,0x46,0x00,0x00,
+0x34,0x84,0x02,0x28,0xac,0x65,0x00,0x00,0x08,0x00,0x07,0xe2,0x24,0x02,0x00,0x20,
+0x34,0x42,0x04,0x40,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,
+0x34,0x63,0x04,0x44,0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x40,0x08,0x00,0x07,0xe2,
+0xac,0x65,0x00,0x00,0x34,0x42,0x04,0x28,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,
+0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x2c,0x34,0x84,0x02,0x28,0x24,0x02,0xff,0x80,
+0x08,0x00,0x07,0xe2,0xac,0x65,0x00,0x00,0x34,0x42,0x04,0x18,0x3c,0x03,0xb0,0x05,
+0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x1c,0x34,0x84,0x02,0x28,
+0x24,0x02,0x00,0x08,0x08,0x00,0x07,0xe2,0xac,0x65,0x00,0x00,0x34,0x42,0x04,0x10,
+0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x14,
+0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x04,0x08,0x00,0x07,0xe2,0xac,0x65,0x00,0x00,
+0x34,0x42,0x04,0x08,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,
+0x34,0x63,0x04,0x0c,0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x02,0x08,0x00,0x07,0xe2,
+0xac,0x65,0x00,0x00,0x24,0x17,0x00,0x14,0x08,0x00,0x07,0xb4,0x24,0x13,0x01,0x02,
+0x30,0xa2,0x00,0x07,0x24,0x44,0x00,0x0c,0x00,0x90,0x18,0x2b,0x10,0x60,0x00,0x0c,
+0x26,0x02,0x00,0x04,0x27,0x85,0xbb,0x0c,0x00,0x10,0x10,0x40,0x00,0x50,0x10,0x21,
+0x00,0x45,0x10,0x21,0x90,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x18,0x2b,
+0x14,0x60,0xff,0xfa,0x00,0x10,0x10,0x40,0x2e,0x06,0x00,0x0c,0x26,0x02,0x00,0x04,
+0x08,0x00,0x07,0x9e,0x00,0x46,0x80,0x0a,0x27,0x82,0xb3,0xf0,0x01,0x82,0x20,0x21,
+0x8c,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0xe2,0x00,0x19,0x00,0x00,0x00,0x00,
+0x14,0x40,0x00,0x07,0x00,0x00,0x00,0x00,0x27,0x82,0x90,0x10,0x00,0xc2,0x10,0x21,
+0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x14,0x00,0x00,0x00,0x00,
+0x90,0xe3,0x00,0x16,0x27,0x82,0x8f,0xf8,0x00,0xc2,0x10,0x21,0x34,0x63,0x00,0x20,
+0x90,0x50,0x00,0x07,0xa0,0xe3,0x00,0x16,0x8c,0x84,0x00,0x00,0x00,0x0a,0x1e,0x42,
+0x24,0x06,0x00,0x01,0x90,0x82,0x00,0x16,0x30,0x71,0x00,0x02,0x30,0x72,0x00,0x3f,
+0x30,0x42,0x00,0xfb,0x24,0x17,0x00,0x18,0x24,0x13,0x01,0x03,0x24,0x15,0x08,0x18,
+0xaf,0xa6,0x00,0x1c,0x08,0x00,0x07,0xbe,0xa0,0x82,0x00,0x16,0x8d,0x02,0x00,0x04,
+0x00,0x0a,0x1c,0x42,0x30,0x42,0x00,0x10,0x14,0x40,0x00,0x15,0x30,0x72,0x00,0x3f,
+0x81,0x22,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x11,0x30,0x72,0x00,0x3e,
+0x27,0x83,0x90,0x08,0x00,0xc3,0x18,0x21,0x80,0x64,0x00,0x00,0x27,0x83,0xb5,0x68,
+0x00,0x04,0x11,0x00,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x23,
+0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x05,0x90,0x43,0x00,0x04,
+0x00,0x00,0x00,0x00,0x00,0x64,0x18,0x24,0x30,0x63,0x00,0x01,0x02,0x43,0x90,0x25,
+0x27,0x85,0xb3,0xf0,0x01,0x85,0x28,0x21,0x8c,0xa6,0x00,0x00,0x01,0x73,0x10,0x21,
+0x27,0x83,0x90,0x00,0x90,0xc4,0x00,0x16,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,
+0x30,0x84,0x00,0xdf,0x90,0x50,0x00,0x00,0xa0,0xc4,0x00,0x16,0x80,0xc6,0x00,0x12,
+0x8c,0xa3,0x00,0x00,0x2d,0xc4,0x00,0x02,0xaf,0xa6,0x00,0x1c,0x90,0x62,0x00,0x16,
+0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfb,0x14,0x80,0x00,0x06,0xa0,0x62,0x00,0x16,
+0x24,0x02,0x00,0x06,0x11,0xc2,0x00,0x03,0x24,0x02,0x00,0x04,0x15,0xc2,0xff,0x0e,
+0x32,0x51,0x00,0x02,0x32,0x51,0x00,0x02,0x2e,0x02,0x00,0x0c,0x14,0x40,0x00,0x0f,
+0x00,0x11,0x18,0x2b,0x32,0x02,0x00,0x0f,0x34,0x42,0x00,0x10,0x00,0x03,0x19,0x00,
+0x00,0x43,0x18,0x21,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xb8,0xa0,0x43,0x00,0x00,
+0x00,0x00,0x20,0x21,0x02,0x00,0x28,0x21,0x0c,0x00,0x02,0x05,0xaf,0xaf,0x00,0x28,
+0x8f,0xaf,0x00,0x28,0x08,0x00,0x07,0xbe,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0xb9,
+0x32,0x03,0x00,0xff,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x42,0x90,0x62,0x00,0x00,
+0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x0f,0x14,0x40,0xfe,0xaa,0x00,0x00,0x00,0x00,
+0x91,0xe2,0x00,0x09,0x00,0x00,0x00,0x00,0x02,0x82,0x10,0x26,0x08,0x00,0x07,0x75,
+0x00,0x02,0x28,0x0b,0x08,0x00,0x07,0x7b,0x00,0x00,0xb0,0x21,0x24,0x02,0x00,0x10,
+0x10,0xc2,0x00,0x08,0x24,0x02,0x00,0x11,0x10,0xc2,0xfe,0x7d,0x00,0x07,0x17,0x83,
+0x24,0x02,0x00,0x12,0x14,0xc2,0xfe,0x7b,0x00,0x07,0x17,0x43,0x08,0x00,0x07,0x55,
+0x30,0x5e,0x00,0x01,0x08,0x00,0x07,0x55,0x00,0x07,0xf7,0xc2,0x00,0x04,0x10,0x40,
+0x27,0x83,0x80,0x1c,0x00,0x43,0x10,0x21,0x00,0x80,0x40,0x21,0x94,0x44,0x00,0x00,
+0x2d,0x07,0x00,0x04,0x24,0xc2,0x00,0x03,0x00,0x47,0x30,0x0a,0x00,0x86,0x00,0x18,
+0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x23,0x7c,
+0xac,0x62,0x00,0x00,0x2d,0x06,0x00,0x10,0x00,0x00,0x20,0x12,0x00,0x04,0x22,0x42,
+0x24,0x84,0x00,0x01,0x24,0x83,0x00,0xc0,0x10,0xe0,0x00,0x0b,0x24,0x82,0x00,0x60,
+0x00,0x40,0x20,0x21,0x00,0x65,0x20,0x0a,0x3c,0x03,0xb0,0x03,0x34,0x63,0x01,0x00,
+0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x00,0x44,0x20,0x04,
+0x03,0xe0,0x00,0x08,0x00,0x80,0x10,0x21,0x24,0x85,0x00,0x28,0x24,0x83,0x00,0x24,
+0x31,0x02,0x00,0x08,0x14,0xc0,0xff,0xf4,0x24,0x84,0x00,0x14,0x00,0x60,0x20,0x21,
+0x08,0x00,0x08,0xf6,0x00,0xa2,0x20,0x0b,0x27,0xbd,0xff,0xe0,0x3c,0x03,0xb0,0x03,
+0x3c,0x02,0x80,0x00,0xaf,0xb0,0x00,0x10,0x24,0x42,0x24,0x18,0x00,0x80,0x80,0x21,
+0x34,0x63,0x00,0x20,0x3c,0x04,0xb0,0x03,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,
+0xaf,0xbf,0x00,0x1c,0x83,0xb1,0x00,0x33,0x83,0xa8,0x00,0x37,0x34,0x84,0x01,0x10,
+0xac,0x62,0x00,0x00,0x2e,0x02,0x00,0x10,0x00,0xe0,0x90,0x21,0x8c,0x87,0x00,0x00,
+0x14,0x40,0x00,0x0c,0x2e,0x02,0x00,0x0c,0x3c,0x02,0x00,0x0f,0x34,0x42,0xf0,0x00,
+0x00,0xe2,0x10,0x24,0x14,0x40,0x00,0x37,0x32,0x02,0x00,0x08,0x32,0x02,0x00,0x07,
+0x27,0x83,0x80,0xcc,0x00,0x43,0x10,0x21,0x90,0x50,0x00,0x00,0x00,0x00,0x00,0x00,
+0x2e,0x02,0x00,0x0c,0x14,0x40,0x00,0x03,0x02,0x00,0x20,0x21,0x32,0x02,0x00,0x0f,
+0x24,0x44,0x00,0x0c,0x00,0x87,0x10,0x06,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x07,
+0x2c,0x82,0x00,0x0c,0x00,0x04,0x10,0x80,0x27,0x83,0xb4,0x40,0x00,0x43,0x10,0x21,
+0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0x82,0x00,0x0c,0x14,0x40,0x00,0x05,
+0x00,0x05,0x10,0x40,0x00,0x46,0x10,0x21,0x00,0x02,0x11,0x00,0x00,0x82,0x10,0x21,
+0x24,0x44,0x00,0x04,0x15,0x00,0x00,0x02,0x24,0x06,0x00,0x20,0x24,0x06,0x00,0x0e,
+0x0c,0x00,0x08,0xdf,0x00,0x00,0x00,0x00,0x00,0x40,0x30,0x21,0x3c,0x02,0xb0,0x03,
+0x34,0x42,0x01,0x00,0x90,0x43,0x00,0x00,0x2e,0x04,0x00,0x04,0x24,0x02,0x00,0x10,
+0x24,0x05,0x00,0x0a,0x00,0x44,0x28,0x0a,0x30,0x63,0x00,0x01,0x14,0x60,0x00,0x02,
+0x00,0x05,0x10,0x40,0x00,0xa0,0x10,0x21,0x30,0x45,0x00,0xff,0x00,0xc5,0x10,0x21,
+0x24,0x46,0x00,0x46,0x02,0x26,0x18,0x04,0xa6,0x43,0x00,0x00,0x8f,0xbf,0x00,0x1c,
+0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x00,0xc0,0x10,0x21,0x03,0xe0,0x00,0x08,
+0x27,0xbd,0x00,0x20,0x10,0x40,0xff,0xcf,0x2e,0x02,0x00,0x0c,0x32,0x02,0x00,0x07,
+0x27,0x83,0x80,0xc4,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x00,0x08,0x00,0x09,0x24,
+0x02,0x04,0x80,0x23,0x27,0xbd,0xff,0xb8,0x00,0x05,0x38,0x80,0x27,0x82,0xb3,0xf0,
+0xaf,0xbe,0x00,0x40,0xaf,0xb6,0x00,0x38,0xaf,0xb3,0x00,0x2c,0xaf,0xbf,0x00,0x44,
+0xaf,0xb7,0x00,0x3c,0xaf,0xb5,0x00,0x34,0xaf,0xb4,0x00,0x30,0xaf,0xb2,0x00,0x28,
+0xaf,0xb1,0x00,0x24,0xaf,0xb0,0x00,0x20,0x00,0xe2,0x38,0x21,0x8c,0xe6,0x00,0x00,
+0xaf,0xa5,0x00,0x4c,0x3c,0x02,0x80,0x00,0x3c,0x05,0xb0,0x03,0x34,0xa5,0x00,0x20,
+0x24,0x42,0x25,0x74,0x24,0x03,0x00,0x01,0xac,0xa2,0x00,0x00,0xa0,0xc3,0x00,0x12,
+0x8c,0xe5,0x00,0x00,0x94,0xc3,0x00,0x06,0x90,0xa2,0x00,0x16,0xa4,0xc3,0x00,0x14,
+0x27,0x83,0x8f,0xf0,0x34,0x42,0x00,0x08,0xa0,0xa2,0x00,0x16,0x8c,0xe8,0x00,0x00,
+0xaf,0xa4,0x00,0x48,0x27,0x82,0x8f,0xf4,0x95,0x11,0x00,0x14,0x00,0x00,0x00,0x00,
+0x00,0x11,0x98,0xc0,0x02,0x71,0x20,0x21,0x00,0x04,0x20,0x80,0x00,0x82,0x10,0x21,
+0x8c,0x52,0x00,0x18,0x00,0x83,0x18,0x21,0x84,0x75,0x00,0x06,0x8e,0x45,0x00,0x08,
+0x8e,0x46,0x00,0x04,0x8e,0x47,0x00,0x04,0x00,0x05,0x1c,0x82,0x00,0x06,0x31,0x42,
+0x27,0x82,0x90,0x00,0x30,0x63,0x00,0x01,0x30,0xc6,0x00,0x01,0x00,0x82,0x20,0x21,
+0xa5,0x15,0x00,0x1a,0x00,0x05,0x14,0x42,0xaf,0xa3,0x00,0x18,0xaf,0xa6,0x00,0x1c,
+0x30,0xe7,0x00,0x10,0x30,0x56,0x00,0x01,0x80,0x97,0x00,0x06,0x14,0xe0,0x00,0x47,
+0x00,0x05,0xf7,0xc2,0x80,0x82,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x44,
+0x02,0x71,0x10,0x21,0x93,0x90,0xbb,0xd9,0x00,0x00,0x00,0x00,0x2e,0x02,0x00,0x0c,
+0x14,0x40,0x00,0x06,0x02,0x00,0x20,0x21,0x00,0x16,0x10,0x40,0x00,0x43,0x10,0x21,
+0x00,0x02,0x11,0x00,0x02,0x02,0x10,0x21,0x24,0x44,0x00,0x04,0x02,0x71,0x10,0x21,
+0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0x00,0x80,0x80,0x21,
+0xa0,0x44,0x00,0x03,0xa0,0x44,0x00,0x00,0x02,0x00,0x20,0x21,0x02,0xc0,0x28,0x21,
+0x0c,0x00,0x08,0xdf,0x02,0xa0,0x30,0x21,0x02,0x71,0x18,0x21,0x00,0x03,0x88,0x80,
+0x00,0x40,0xa0,0x21,0x27,0x82,0x90,0x10,0x02,0x22,0x10,0x21,0x8c,0x44,0x00,0x00,
+0x26,0xe3,0x00,0x02,0x00,0x03,0x17,0xc2,0x00,0x62,0x18,0x21,0x00,0x04,0x25,0xc2,
+0x00,0x03,0x18,0x43,0x30,0x84,0x00,0x01,0x00,0x03,0x18,0x40,0x03,0xc4,0x20,0x24,
+0x14,0x80,0x00,0x15,0x02,0x43,0x38,0x21,0x3c,0x08,0xb0,0x03,0x35,0x08,0x00,0x28,
+0x8d,0x03,0x00,0x00,0x8f,0xa6,0x00,0x4c,0x8f,0xa4,0x00,0x48,0x27,0x82,0x8f,0xf8,
+0x02,0x22,0x10,0x21,0x24,0x63,0x00,0x01,0x02,0xa0,0x28,0x21,0xa4,0x54,0x00,0x04,
+0x00,0xc0,0x38,0x21,0x0c,0x00,0x07,0x2b,0xad,0x03,0x00,0x00,0x7b,0xbe,0x02,0x3c,
+0x7b,0xb6,0x01,0xfc,0x7b,0xb4,0x01,0xbc,0x7b,0xb2,0x01,0x7c,0x7b,0xb0,0x01,0x3c,
+0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x48,0x8f,0xa2,0x00,0x1c,0x8f,0xa6,0x00,0x18,
+0x02,0x00,0x20,0x21,0x02,0xc0,0x28,0x21,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0x06,
+0xaf,0xa0,0x00,0x14,0x08,0x00,0x09,0xc2,0x02,0x82,0xa0,0x21,0x02,0x71,0x10,0x21,
+0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0x90,0x50,0x00,0x00,
+0x08,0x00,0x09,0xae,0xa0,0x50,0x00,0x03,0x27,0xbd,0xff,0xb8,0xaf,0xb1,0x00,0x24,
+0x8f,0xb1,0x00,0x5c,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,
+0x24,0x42,0x27,0x98,0xaf,0xbe,0x00,0x40,0xaf,0xb7,0x00,0x3c,0xaf,0xb6,0x00,0x38,
+0xaf,0xb5,0x00,0x34,0xaf,0xb4,0x00,0x30,0xaf,0xa5,0x00,0x4c,0x8f,0xb5,0x00,0x58,
+0xaf,0xbf,0x00,0x44,0xaf,0xb3,0x00,0x2c,0xaf,0xb2,0x00,0x28,0xaf,0xb0,0x00,0x20,
+0x00,0xe0,0xb0,0x21,0xac,0x62,0x00,0x00,0x00,0x80,0xf0,0x21,0x00,0x00,0xb8,0x21,
+0x16,0x20,0x00,0x2b,0x00,0x00,0xa0,0x21,0x27,0x85,0xb3,0xf0,0x00,0x07,0x10,0x80,
+0x00,0x45,0x10,0x21,0x8c,0x53,0x00,0x00,0x00,0x15,0x18,0x80,0x00,0x65,0x18,0x21,
+0x92,0x62,0x00,0x16,0x8c,0x72,0x00,0x00,0x30,0x42,0x00,0x03,0x14,0x40,0x00,0x2d,
+0x00,0x00,0x00,0x00,0x92,0x42,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x03,
+0x14,0x40,0x00,0x28,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x34,0x00,0x00,0x00,0x00,
+0x14,0x40,0x00,0x18,0x02,0x20,0x10,0x21,0x8c,0x82,0x00,0x38,0x00,0x00,0x00,0x00,
+0x14,0x40,0x00,0x14,0x02,0x20,0x10,0x21,0x8c,0x82,0x00,0x3c,0x00,0x00,0x00,0x00,
+0x14,0x40,0x00,0x0f,0x3c,0x03,0xb0,0x09,0x3c,0x05,0xb0,0x05,0x34,0x63,0x01,0x44,
+0x34,0xa5,0x02,0x52,0x94,0x66,0x00,0x00,0x90,0xa2,0x00,0x00,0x8f,0xa3,0x00,0x4c,
+0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x06,0x30,0x42,0x00,0x01,0x10,0x40,0x00,0x04,
+0x30,0xc6,0xff,0xff,0x2c,0xc2,0x00,0x41,0x10,0x40,0x00,0x09,0x24,0x05,0x00,0x14,
+0x02,0x20,0x10,0x21,0x7b,0xbe,0x02,0x3c,0x7b,0xb6,0x01,0xfc,0x7b,0xb4,0x01,0xbc,
+0x7b,0xb2,0x01,0x7c,0x7b,0xb0,0x01,0x3c,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x48,
+0x0c,0x00,0x07,0x06,0x24,0x06,0x01,0x07,0x24,0x02,0x00,0x01,0x08,0x00,0x0a,0x28,
+0xa3,0xc2,0x00,0x11,0x10,0xc0,0x00,0x1c,0x24,0x02,0x00,0x01,0x10,0xc2,0x00,0x17,
+0x00,0xc0,0x88,0x21,0x96,0x54,0x00,0x1a,0x02,0xa0,0xb8,0x21,0x12,0x20,0xff,0xed,
+0x02,0x20,0x10,0x21,0x27,0x83,0xb3,0xf0,0x00,0x17,0x10,0x80,0x00,0x43,0x10,0x21,
+0x8c,0x44,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x28,0x80,0x86,0x00,0x12,
+0x8c,0x62,0x00,0x00,0x00,0x14,0x2c,0x00,0x00,0x05,0x2c,0x03,0x00,0x46,0x10,0x21,
+0x8f,0xa6,0x00,0x4c,0x02,0xe0,0x38,0x21,0x03,0xc0,0x20,0x21,0x0c,0x00,0x07,0x2b,
+0xac,0x62,0x00,0x00,0x08,0x00,0x0a,0x28,0xaf,0xd1,0x00,0x40,0x96,0x74,0x00,0x1a,
+0x08,0x00,0x0a,0x3b,0x02,0xc0,0xb8,0x21,0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,
+0x8c,0x50,0x00,0x00,0x02,0x60,0x20,0x21,0x0c,0x00,0x1f,0x11,0x02,0x00,0x28,0x21,
+0x30,0x42,0x00,0xff,0x02,0x00,0x28,0x21,0x02,0x40,0x20,0x21,0x0c,0x00,0x1f,0x11,
+0xaf,0xa2,0x00,0x18,0x8f,0xa4,0x00,0x18,0x00,0x00,0x00,0x00,0x10,0x80,0x00,0xed,
+0x30,0x50,0x00,0xff,0x12,0x00,0x00,0x18,0x24,0x11,0x00,0x01,0x96,0x63,0x00,0x14,
+0x96,0x44,0x00,0x14,0x27,0x85,0x8f,0xf0,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
+0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21,0x00,0x04,0x18,0xc0,0x8c,0x46,0x00,0x08,
+0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x65,0x18,0x21,0x00,0x06,0x17,0x02,
+0x24,0x04,0x00,0xff,0x8c,0x63,0x00,0x08,0x10,0x44,0x00,0xd6,0x00,0x03,0x17,0x02,
+0x10,0x44,0x00,0xd5,0x3c,0x02,0x80,0x00,0x00,0x66,0x18,0x2b,0x24,0x11,0x00,0x02,
+0x24,0x02,0x00,0x01,0x00,0x43,0x88,0x0a,0x24,0x02,0x00,0x01,0x12,0x22,0x00,0x5a,
+0x24,0x02,0x00,0x02,0x16,0x22,0xff,0xbd,0x00,0x00,0x00,0x00,0x96,0x49,0x00,0x14,
+0x27,0x82,0x8f,0xf4,0x02,0xa0,0xb8,0x21,0x00,0x09,0x50,0xc0,0x01,0x49,0x18,0x21,
+0x00,0x03,0x40,0x80,0x01,0x02,0x10,0x21,0x8c,0x43,0x00,0x18,0x00,0x00,0x00,0x00,
+0x8c,0x65,0x00,0x08,0x8c,0x62,0x00,0x0c,0x8c,0x62,0x00,0x04,0x00,0x05,0x24,0x42,
+0x00,0x05,0x1c,0x82,0x30,0x42,0x00,0x10,0x30,0x66,0x00,0x01,0x14,0x40,0x00,0x41,
+0x30,0x87,0x00,0x01,0x27,0x82,0x90,0x08,0x01,0x02,0x10,0x21,0x80,0x44,0x00,0x00,
+0x27,0x82,0xb5,0x68,0x00,0x04,0x19,0x00,0x00,0x64,0x18,0x23,0x00,0x03,0x18,0x80,
+0x00,0x64,0x18,0x23,0x00,0x03,0x18,0x80,0x00,0x62,0x10,0x21,0x90,0x45,0x00,0x05,
+0x27,0x84,0xb4,0x90,0x00,0x64,0x18,0x21,0x90,0x63,0x00,0x00,0x10,0xa0,0x00,0x2b,
+0x2c,0x64,0x00,0x0c,0x14,0x80,0x00,0x04,0x00,0x60,0x10,0x21,0x00,0x06,0x11,0x00,
+0x00,0x62,0x10,0x21,0x24,0x42,0x00,0x24,0x3c,0x01,0xb0,0x03,0xa0,0x22,0x00,0xb9,
+0x14,0x80,0x00,0x06,0x00,0x60,0x28,0x21,0x00,0x07,0x10,0x40,0x00,0x46,0x10,0x21,
+0x00,0x02,0x11,0x00,0x00,0x62,0x10,0x21,0x24,0x45,0x00,0x04,0x01,0x49,0x10,0x21,
+0x27,0x83,0x90,0x00,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0xa0,0x18,0x21,
+0xa0,0x45,0x00,0x03,0xa0,0x45,0x00,0x00,0x24,0x02,0x00,0x08,0x12,0x02,0x00,0x0b,
+0x24,0x02,0x00,0x01,0x00,0x60,0x28,0x21,0x02,0x40,0x20,0x21,0x0c,0x00,0x1f,0x8d,
+0xaf,0xa2,0x00,0x10,0x30,0x54,0xff,0xff,0x92,0x42,0x00,0x16,0x00,0x00,0x00,0x00,
+0x02,0x02,0x10,0x25,0x08,0x00,0x0a,0x3b,0xa2,0x42,0x00,0x16,0x00,0x60,0x28,0x21,
+0x02,0x40,0x20,0x21,0x0c,0x00,0x1f,0x3e,0xaf,0xa0,0x00,0x10,0x08,0x00,0x0a,0xbe,
+0x30,0x54,0xff,0xff,0x08,0x00,0x0a,0xa6,0x00,0x60,0x10,0x21,0x14,0x80,0xff,0xfd,
+0x00,0x00,0x00,0x00,0x00,0x06,0x11,0x00,0x00,0x62,0x10,0x21,0x08,0x00,0x0a,0xa6,
+0x24,0x42,0x00,0x04,0x27,0x82,0x90,0x00,0x01,0x02,0x10,0x21,0x90,0x43,0x00,0x00,
+0x08,0x00,0x0a,0xb6,0xa0,0x43,0x00,0x03,0x96,0x69,0x00,0x14,0x02,0xc0,0xb8,0x21,
+0x24,0x0b,0x00,0x01,0x00,0x09,0x10,0xc0,0x00,0x49,0x18,0x21,0x00,0x03,0x40,0x80,
+0x00,0x40,0x50,0x21,0x27,0x82,0x8f,0xf4,0x01,0x02,0x10,0x21,0x8c,0x43,0x00,0x18,
+0x00,0x00,0x00,0x00,0x8c,0x65,0x00,0x08,0x8c,0x62,0x00,0x0c,0x8c,0x62,0x00,0x04,
+0x00,0x05,0x24,0x42,0x00,0x05,0x1c,0x82,0x30,0x42,0x00,0x10,0x30,0x66,0x00,0x01,
+0x10,0x40,0x00,0x0d,0x30,0x87,0x00,0x01,0x27,0x82,0x90,0x08,0x01,0x02,0x10,0x21,
+0x80,0x43,0x00,0x00,0x00,0x00,0x58,0x21,0x00,0x03,0x11,0x00,0x00,0x43,0x10,0x23,
+0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x23,0x00,0x02,0x10,0x80,0x27,0x83,0xb5,0x60,
+0x00,0x43,0x10,0x21,0xa0,0x40,0x00,0x04,0x11,0x60,0x00,0x4f,0x00,0x00,0x00,0x00,
+0x01,0x49,0x10,0x21,0x00,0x02,0x20,0x80,0x27,0x85,0x90,0x00,0x00,0x85,0x10,0x21,
+0x80,0x43,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x42,0x01,0x49,0x10,0x21,
+0x27,0x82,0x90,0x08,0x00,0x82,0x10,0x21,0x80,0x44,0x00,0x00,0x27,0x82,0xb5,0x68,
+0x00,0x04,0x19,0x00,0x00,0x64,0x18,0x23,0x00,0x03,0x18,0x80,0x00,0x64,0x18,0x23,
+0x00,0x03,0x18,0x80,0x00,0x62,0x10,0x21,0x90,0x45,0x00,0x05,0x27,0x84,0xb4,0x90,
+0x00,0x64,0x18,0x21,0x90,0x63,0x00,0x00,0x10,0xa0,0x00,0x2c,0x2c,0x64,0x00,0x0c,
+0x14,0x80,0x00,0x04,0x00,0x60,0x10,0x21,0x00,0x06,0x11,0x00,0x00,0x62,0x10,0x21,
+0x24,0x42,0x00,0x24,0x3c,0x01,0xb0,0x03,0xa0,0x22,0x00,0xb9,0x14,0x80,0x00,0x06,
+0x00,0x60,0x28,0x21,0x00,0x07,0x10,0x40,0x00,0x46,0x10,0x21,0x00,0x02,0x11,0x00,
+0x00,0x62,0x10,0x21,0x24,0x45,0x00,0x04,0x01,0x49,0x10,0x21,0x27,0x83,0x90,0x00,
+0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0xa0,0x18,0x21,0xa0,0x45,0x00,0x03,
+0xa0,0x45,0x00,0x00,0x8f,0xa4,0x00,0x18,0x24,0x02,0x00,0x08,0x10,0x82,0x00,0x0c,
+0x00,0x60,0x28,0x21,0x24,0x02,0x00,0x01,0x02,0x60,0x20,0x21,0x0c,0x00,0x1f,0x8d,
+0xaf,0xa2,0x00,0x10,0x8f,0xa3,0x00,0x18,0x30,0x54,0xff,0xff,0x92,0x62,0x00,0x16,
+0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x25,0x08,0x00,0x0a,0x3b,0xa2,0x62,0x00,0x16,
+0x02,0x60,0x20,0x21,0x0c,0x00,0x1f,0x3e,0xaf,0xa0,0x00,0x10,0x08,0x00,0x0b,0x2d,
+0x00,0x00,0x00,0x00,0x08,0x00,0x0b,0x15,0x00,0x60,0x10,0x21,0x14,0x80,0xff,0xfd,
+0x00,0x00,0x00,0x00,0x00,0x06,0x11,0x00,0x00,0x62,0x10,0x21,0x08,0x00,0x0b,0x15,
+0x24,0x42,0x00,0x04,0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21,0x90,0x43,0x00,0x00,
+0x08,0x00,0x0b,0x25,0xa0,0x43,0x00,0x03,0x27,0x85,0x90,0x00,0x08,0x00,0x0b,0x41,
+0x01,0x49,0x10,0x21,0x3c,0x02,0x80,0x00,0x00,0x62,0x18,0x26,0x08,0x00,0x0a,0x76,
+0x00,0xc2,0x30,0x26,0x12,0x00,0xff,0x2d,0x24,0x02,0x00,0x01,0x08,0x00,0x0a,0x7b,
+0x24,0x11,0x00,0x02,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xd0,
+0x24,0x42,0x2d,0x44,0x34,0x63,0x00,0x20,0x3c,0x05,0xb0,0x05,0xaf,0xb3,0x00,0x24,
+0xaf,0xb2,0x00,0x20,0xaf,0xb1,0x00,0x1c,0xaf,0xbf,0x00,0x28,0xaf,0xb0,0x00,0x18,
+0xac,0x62,0x00,0x00,0x34,0xa5,0x02,0x42,0x90,0xa2,0x00,0x00,0x00,0x80,0x90,0x21,
+0x24,0x11,0x00,0x10,0x30,0x53,0x00,0xff,0x24,0x02,0x00,0x10,0x12,0x22,0x00,0xcf,
+0x00,0x00,0x18,0x21,0x24,0x02,0x00,0x11,0x12,0x22,0x00,0xc1,0x24,0x02,0x00,0x12,
+0x12,0x22,0x00,0xb4,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0xad,0xae,0x43,0x00,0x40,
+0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c,0x8c,0x44,0x00,0x00,0x3c,0x03,0x00,0x02,
+0x34,0x63,0x00,0xff,0x00,0x83,0x80,0x24,0x00,0x10,0x14,0x43,0x10,0x40,0x00,0x05,
+0x00,0x00,0x00,0x00,0x8e,0x42,0x00,0x34,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x92,
+0x00,0x00,0x00,0x00,0x93,0x83,0x8b,0x61,0x00,0x00,0x00,0x00,0x30,0x62,0x00,0x02,
+0x10,0x40,0x00,0x04,0x32,0x10,0x00,0xff,0x00,0x10,0x11,0xc3,0x14,0x40,0x00,0x86,
+0x00,0x00,0x00,0x00,0x16,0x00,0x00,0x15,0x02,0x00,0x10,0x21,0x26,0x22,0x00,0x01,
+0x30,0x51,0x00,0xff,0x2e,0x23,0x00,0x13,0x14,0x60,0xff,0xdb,0x24,0x03,0x00,0x02,
+0x12,0x63,0x00,0x73,0x24,0x02,0x00,0x05,0x2a,0x62,0x00,0x03,0x10,0x40,0x00,0x58,
+0x24,0x02,0x00,0x04,0x24,0x02,0x00,0x01,0x12,0x62,0x00,0x4b,0x02,0x40,0x20,0x21,
+0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,
+0x30,0x70,0x00,0xff,0x12,0x00,0x00,0x06,0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x28,
+0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30,
+0x92,0x46,0x00,0x04,0x8e,0x43,0x00,0x24,0x24,0x02,0x00,0x07,0x02,0x40,0x20,0x21,
+0x00,0x00,0x28,0x21,0x24,0x07,0x00,0x06,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xe6,
+0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x24,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c,
+0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,0x16,0x00,0xff,0xec,0x02,0x00,0x10,0x21,
+0x92,0x46,0x00,0x05,0x8e,0x43,0x00,0x28,0x24,0x02,0x00,0x05,0x02,0x40,0x20,0x21,
+0x24,0x05,0x00,0x01,0x24,0x07,0x00,0x04,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xe6,
+0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x28,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c,
+0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,0x16,0x00,0xff,0xdc,0x02,0x00,0x10,0x21,
+0x92,0x46,0x00,0x06,0x8e,0x43,0x00,0x2c,0x24,0x02,0x00,0x03,0x02,0x40,0x20,0x21,
+0x24,0x05,0x00,0x02,0x00,0x00,0x38,0x21,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xe6,
+0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x2c,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c,
+0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,0x16,0x00,0xff,0xcc,0x02,0x00,0x10,0x21,
+0x92,0x46,0x00,0x07,0x8e,0x43,0x00,0x30,0x24,0x02,0x00,0x02,0x02,0x40,0x20,0x21,
+0x24,0x05,0x00,0x03,0x24,0x07,0x00,0x01,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xe6,
+0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x30,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c,
+0x08,0x00,0x0b,0x97,0x30,0x42,0x00,0xff,0x92,0x46,0x00,0x04,0x8e,0x43,0x00,0x24,
+0x24,0x02,0x00,0x07,0x00,0x00,0x28,0x21,0x24,0x07,0x00,0x06,0xaf,0xa2,0x00,0x10,
+0x0c,0x00,0x09,0xe6,0xaf,0xa3,0x00,0x14,0x08,0x00,0x0b,0x90,0xae,0x42,0x00,0x24,
+0x12,0x62,0x00,0x0d,0x24,0x02,0x00,0x03,0x24,0x02,0x00,0x08,0x16,0x62,0xff,0xa8,
+0x02,0x40,0x20,0x21,0x92,0x46,0x00,0x07,0x8e,0x42,0x00,0x30,0x24,0x05,0x00,0x03,
+0x24,0x07,0x00,0x01,0xaf,0xa3,0x00,0x10,0x0c,0x00,0x09,0xe6,0xaf,0xa2,0x00,0x14,
+0x08,0x00,0x0b,0x90,0xae,0x42,0x00,0x30,0x92,0x46,0x00,0x06,0x8e,0x43,0x00,0x2c,
+0x02,0x40,0x20,0x21,0x24,0x05,0x00,0x02,0x00,0x00,0x38,0x21,0xaf,0xa2,0x00,0x10,
+0x0c,0x00,0x09,0xe6,0xaf,0xa3,0x00,0x14,0x08,0x00,0x0b,0x90,0xae,0x42,0x00,0x2c,
+0x92,0x46,0x00,0x05,0x8e,0x43,0x00,0x28,0x02,0x40,0x20,0x21,0x24,0x05,0x00,0x01,
+0x24,0x07,0x00,0x04,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xe6,0xaf,0xa3,0x00,0x14,
+0x08,0x00,0x0b,0x90,0xae,0x42,0x00,0x28,0x0c,0x00,0x01,0x59,0x24,0x04,0x00,0x01,
+0x08,0x00,0x0b,0x81,0x00,0x00,0x00,0x00,0x8f,0x84,0xb4,0x30,0xae,0x40,0x00,0x34,
+0x94,0x85,0x00,0x14,0x0c,0x00,0x1b,0x84,0x00,0x00,0x00,0x00,0x93,0x83,0x8b,0x61,
+0x00,0x00,0x00,0x00,0x30,0x62,0x00,0x02,0x10,0x40,0xff,0x69,0x00,0x00,0x00,0x00,
+0x0c,0x00,0x01,0x59,0x00,0x00,0x20,0x21,0x08,0x00,0x0b,0x79,0x00,0x00,0x00,0x00,
+0x02,0x40,0x20,0x21,0x0c,0x00,0x09,0x5d,0x02,0x20,0x28,0x21,0x08,0x00,0x0b,0x6d,
+0x3c,0x02,0xb0,0x05,0x8e,0x42,0x00,0x3c,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x4a,
+0x00,0x00,0x00,0x00,0x8f,0x82,0xb4,0x38,0x00,0x00,0x00,0x00,0x90,0x42,0x00,0x0a,
+0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x2b,0x08,0x00,0x0b,0x6a,0xae,0x43,0x00,0x3c,
+0x8e,0x42,0x00,0x38,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x3d,0x24,0x02,0x00,0x12,
+0x8f,0x82,0xb4,0x34,0x00,0x00,0x00,0x00,0x90,0x42,0x00,0x0a,0x00,0x00,0x00,0x00,
+0x00,0x02,0x18,0x2b,0x08,0x00,0x0b,0x6a,0xae,0x43,0x00,0x38,0x8e,0x42,0x00,0x34,
+0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x30,0x24,0x02,0x00,0x11,0x8f,0x82,0xb4,0x30,
+0x00,0x00,0x00,0x00,0x90,0x42,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x2b,
+0x08,0x00,0x0b,0x6a,0xae,0x43,0x00,0x34,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,
+0x27,0xbd,0xff,0xe0,0x34,0x63,0x00,0x20,0x24,0x42,0x30,0xf8,0x3c,0x08,0xb0,0x03,
+0xaf,0xb1,0x00,0x14,0xac,0x62,0x00,0x00,0x35,0x08,0x01,0x00,0xaf,0xbf,0x00,0x18,
+0xaf,0xb0,0x00,0x10,0x91,0x03,0x00,0x00,0x00,0xa0,0x48,0x21,0x24,0x11,0x00,0x0a,
+0x2c,0xa5,0x00,0x04,0x24,0x02,0x00,0x10,0x00,0x45,0x88,0x0a,0x30,0x63,0x00,0x01,
+0x00,0xc0,0x28,0x21,0x14,0x60,0x00,0x02,0x00,0x11,0x40,0x40,0x02,0x20,0x40,0x21,
+0x84,0x83,0x00,0x0c,0x31,0x11,0x00,0xff,0x01,0x20,0x20,0x21,0x00,0x03,0x10,0xc0,
+0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x8f,0xf8,0x00,0x43,0x10,0x21,
+0x84,0x43,0x00,0x04,0x24,0x06,0x00,0x0e,0x10,0xe0,0x00,0x06,0x02,0x23,0x80,0x21,
+0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,
+0x27,0xbd,0x00,0x20,0x0c,0x00,0x08,0xdf,0x00,0x00,0x00,0x00,0x02,0x11,0x18,0x21,
+0x08,0x00,0x0c,0x60,0x00,0x62,0x80,0x21,0x27,0xbd,0xff,0xd0,0xaf,0xbf,0x00,0x28,
+0xaf,0xb4,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18,0xaf,0xb5,0x00,0x24,
+0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x84,0x82,0x00,0x0c,0x3c,0x06,0xb0,0x03,
+0x34,0xc6,0x00,0x20,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x80,
+0x27,0x82,0x8f,0xf4,0x00,0x62,0x10,0x21,0x8c,0x55,0x00,0x18,0x3c,0x02,0x80,0x00,
+0x24,0x42,0x31,0xa8,0xac,0xc2,0x00,0x00,0x8e,0xb0,0x00,0x08,0x27,0x82,0x8f,0xf8,
+0x00,0x62,0x18,0x21,0x90,0x71,0x00,0x07,0x00,0x10,0x86,0x43,0x32,0x10,0x00,0x01,
+0x00,0xa0,0x38,0x21,0x02,0x00,0x30,0x21,0x00,0xa0,0x98,0x21,0x02,0x20,0x28,0x21,
+0x0c,0x00,0x0c,0x3e,0x00,0x80,0x90,0x21,0x02,0x20,0x20,0x21,0x02,0x00,0x28,0x21,
+0x24,0x06,0x00,0x14,0x0c,0x00,0x08,0xdf,0x00,0x40,0xa0,0x21,0x86,0x43,0x00,0x0c,
+0x3c,0x09,0xb0,0x09,0x3c,0x08,0xb0,0x09,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
+0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0x80,0x43,0x00,0x06,
+0x3c,0x07,0xb0,0x09,0x3c,0x05,0xb0,0x09,0x28,0x62,0x00,0x00,0x24,0x64,0x00,0x03,
+0x00,0x82,0x18,0x0b,0x00,0x03,0x18,0x83,0x3c,0x02,0xb0,0x09,0x00,0x03,0x18,0x80,
+0x34,0x42,0x01,0x02,0x35,0x29,0x01,0x10,0x35,0x08,0x01,0x14,0x34,0xe7,0x01,0x20,
+0x34,0xa5,0x01,0x24,0xa4,0x54,0x00,0x00,0x12,0x60,0x00,0x11,0x02,0xa3,0xa8,0x21,
+0x8e,0xa2,0x00,0x0c,0x8e,0xa3,0x00,0x08,0x00,0x02,0x14,0x00,0x00,0x03,0x1c,0x02,
+0x00,0x43,0x10,0x21,0xad,0x22,0x00,0x00,0x8e,0xa3,0x00,0x0c,0x00,0x00,0x00,0x00,
+0x00,0x03,0x1c,0x02,0xa5,0x03,0x00,0x00,0x8f,0xbf,0x00,0x28,0x7b,0xb4,0x01,0x3c,
+0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30,
+0x8e,0xa2,0x00,0x04,0x00,0x00,0x00,0x00,0xad,0x22,0x00,0x00,0x8e,0xa4,0x00,0x08,
+0x00,0x00,0x00,0x00,0xa5,0x04,0x00,0x00,0x7a,0xa2,0x00,0x7c,0x00,0x00,0x00,0x00,
+0x00,0x03,0x1c,0x00,0x00,0x02,0x14,0x02,0x00,0x62,0x18,0x21,0xac,0xe3,0x00,0x00,
+0x8e,0xa2,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x02,0x14,0x02,0x08,0x00,0x0c,0xb2,
+0xa4,0xa2,0x00,0x00,0x27,0xbd,0xff,0xe0,0xaf,0xb2,0x00,0x18,0xaf,0xb0,0x00,0x10,
+0xaf,0xbf,0x00,0x1c,0xaf,0xb1,0x00,0x14,0x84,0x82,0x00,0x0c,0x00,0x80,0x90,0x21,
+0x3c,0x05,0xb0,0x03,0x00,0x02,0x20,0xc0,0x00,0x82,0x20,0x21,0x00,0x04,0x20,0x80,
+0x27,0x82,0x8f,0xf4,0x00,0x82,0x10,0x21,0x8c,0x51,0x00,0x18,0x3c,0x02,0x80,0x00,
+0x34,0xa5,0x00,0x20,0x24,0x42,0x33,0x24,0x27,0x83,0x8f,0xf8,0xac,0xa2,0x00,0x00,
+0x00,0x83,0x20,0x21,0x3c,0x02,0xb0,0x03,0x90,0x86,0x00,0x07,0x34,0x42,0x01,0x00,
+0x8e,0x23,0x00,0x08,0x90,0x44,0x00,0x00,0x2c,0xc5,0x00,0x04,0x24,0x02,0x00,0x10,
+0x24,0x10,0x00,0x0a,0x00,0x45,0x80,0x0a,0x00,0x03,0x1e,0x43,0x30,0x84,0x00,0x01,
+0x30,0x65,0x00,0x01,0x14,0x80,0x00,0x02,0x00,0x10,0x10,0x40,0x02,0x00,0x10,0x21,
+0x00,0xc0,0x20,0x21,0x24,0x06,0x00,0x20,0x0c,0x00,0x08,0xdf,0x30,0x50,0x00,0xff,
+0x86,0x44,0x00,0x0c,0x27,0x85,0x90,0x00,0x3c,0x06,0xb0,0x09,0x00,0x04,0x18,0xc0,
+0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x65,0x18,0x21,0x80,0x64,0x00,0x06,
+0x00,0x50,0x10,0x21,0x34,0xc6,0x01,0x02,0x24,0x85,0x00,0x03,0x28,0x83,0x00,0x00,
+0x00,0xa3,0x20,0x0b,0x00,0x04,0x20,0x83,0x00,0x04,0x20,0x80,0xa4,0xc2,0x00,0x00,
+0x02,0x24,0x20,0x21,0x8c,0x83,0x00,0x04,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x10,
+0xac,0x43,0x00,0x00,0x8c,0x86,0x00,0x08,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x14,
+0xa4,0x46,0x00,0x00,0x8c,0x85,0x00,0x0c,0x8c,0x82,0x00,0x08,0x3c,0x06,0xb0,0x09,
+0x00,0x05,0x2c,0x00,0x00,0x02,0x14,0x02,0x00,0xa2,0x28,0x21,0x34,0xc6,0x01,0x20,
+0xac,0xc5,0x00,0x00,0x8c,0x83,0x00,0x0c,0x3c,0x05,0xb0,0x09,0x34,0xa5,0x01,0x24,
+0x00,0x03,0x1c,0x02,0xa4,0xa3,0x00,0x00,0x92,0x42,0x00,0x0a,0x3c,0x03,0xb0,0x09,
+0x34,0x63,0x01,0x30,0x00,0x02,0x13,0x00,0x24,0x42,0x00,0x04,0x30,0x42,0xff,0xff,
+0xa4,0x62,0x00,0x00,0x86,0x44,0x00,0x0c,0x27,0x83,0x90,0x08,0x8f,0xbf,0x00,0x1c,
+0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,
+0x94,0x44,0x00,0x02,0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x3c,0x05,0xb0,0x09,
+0x34,0xa5,0x01,0x32,0xa4,0xa4,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,
+0x27,0xbd,0xff,0xe0,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,0xaf,0xb0,0x00,0x10,
+0x34,0x42,0x00,0x20,0x00,0xa0,0x80,0x21,0x24,0x63,0x34,0xb0,0x00,0x05,0x2c,0x43,
+0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x18,0xac,0x43,0x00,0x00,0x10,0xa0,0x00,0x05,
+0x00,0x80,0x88,0x21,0x8c,0x82,0x00,0x34,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0xb6,
+0x00,0x00,0x00,0x00,0x32,0x10,0x00,0xff,0x12,0x00,0x00,0x4c,0x00,0x00,0x10,0x21,
+0x24,0x02,0x00,0x08,0x12,0x02,0x00,0xa3,0x2a,0x02,0x00,0x09,0x10,0x40,0x00,0x89,
+0x24,0x02,0x00,0x40,0x24,0x04,0x00,0x02,0x12,0x04,0x00,0x79,0x2a,0x02,0x00,0x03,
+0x10,0x40,0x00,0x69,0x24,0x02,0x00,0x04,0x24,0x02,0x00,0x01,0x12,0x02,0x00,0x5a,
+0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05,0x34,0x42,0x00,0x08,0x3c,0x03,0x80,0x00,
+0xa2,0x20,0x00,0x4e,0xac,0x43,0x00,0x00,0x82,0x24,0x00,0x11,0x92,0x27,0x00,0x11,
+0x10,0x80,0x00,0x4e,0x00,0x00,0x00,0x00,0x92,0x26,0x00,0x0a,0x24,0x02,0x00,0x12,
+0x10,0x46,0x00,0x09,0x30,0xc2,0x00,0xff,0x27,0x83,0xb3,0xf0,0x00,0x02,0x10,0x80,
+0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x83,0x00,0x14,
+0x00,0x00,0x00,0x00,0xa6,0x23,0x00,0x0c,0x3c,0x02,0xb0,0x09,0x34,0x42,0x00,0x40,
+0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x03,0xa2,0x23,0x00,0x10,
+0x14,0x60,0x00,0x2b,0x30,0x65,0x00,0x01,0x30,0xc2,0x00,0xff,0x27,0x83,0xb3,0xf0,
+0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x82,0x23,0x00,0x12,
+0x90,0x82,0x00,0x16,0x00,0x00,0x00,0x00,0x00,0x02,0x11,0x42,0x30,0x42,0x00,0x01,
+0x00,0x62,0x18,0x21,0x00,0x03,0x26,0x00,0x14,0x80,0x00,0x18,0xa2,0x23,0x00,0x12,
+0x00,0x07,0x16,0x00,0x14,0x40,0x00,0x11,0x24,0x02,0x00,0x01,0x96,0x23,0x00,0x0c,
+0x27,0x84,0x90,0x00,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,
+0x00,0x44,0x10,0x21,0x80,0x45,0x00,0x06,0x00,0x03,0x1a,0x00,0x3c,0x02,0xb0,0x00,
+0x00,0x65,0x18,0x21,0x00,0x62,0x18,0x21,0x90,0x64,0x00,0x00,0x90,0x62,0x00,0x04,
+0xa2,0x20,0x00,0x15,0xa3,0x80,0x8b,0xc4,0x24,0x02,0x00,0x01,0x8f,0xbf,0x00,0x18,
+0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x0c,0x00,0x0c,0xc9,
+0x02,0x20,0x20,0x21,0x92,0x27,0x00,0x11,0x08,0x00,0x0d,0x79,0x00,0x07,0x16,0x00,
+0x0c,0x00,0x0c,0x6a,0x02,0x20,0x20,0x21,0x86,0x23,0x00,0x0c,0x27,0x84,0x8f,0xf8,
+0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x44,0x20,0x21,
+0x90,0x85,0x00,0x07,0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0xa2,0x25,0x00,0x13,
+0x90,0x83,0x00,0x07,0x08,0x00,0x0d,0x91,0xa0,0x43,0x00,0x02,0x92,0x26,0x00,0x0a,
+0x08,0x00,0x0d,0x5a,0x30,0xc2,0x00,0xff,0x8e,0x22,0x00,0x24,0x00,0x00,0x00,0x00,
+0x10,0x50,0x00,0x07,0xa2,0x20,0x00,0x08,0x24,0x02,0x00,0x07,0xa2,0x22,0x00,0x0a,
+0x92,0x22,0x00,0x27,0xae,0x20,0x00,0x24,0x08,0x00,0x0d,0x4d,0xa2,0x22,0x00,0x04,
+0x08,0x00,0x0d,0xab,0x24,0x02,0x00,0x06,0x16,0x02,0xff,0x9b,0x3c,0x02,0xb0,0x05,
+0x8e,0x23,0x00,0x2c,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x07,0xa2,0x24,0x00,0x08,
+0x24,0x02,0x00,0x03,0xa2,0x22,0x00,0x0a,0x92,0x22,0x00,0x2f,0xae,0x20,0x00,0x2c,
+0x08,0x00,0x0d,0x4d,0xa2,0x22,0x00,0x06,0x08,0x00,0x0d,0xba,0xa2,0x20,0x00,0x0a,
+0x8e,0x22,0x00,0x28,0x24,0x03,0x00,0x01,0x24,0x04,0x00,0x01,0x10,0x44,0x00,0x07,
+0xa2,0x23,0x00,0x08,0x24,0x02,0x00,0x05,0xa2,0x22,0x00,0x0a,0x92,0x22,0x00,0x2b,
+0xae,0x20,0x00,0x28,0x08,0x00,0x0d,0x4d,0xa2,0x22,0x00,0x05,0x08,0x00,0x0d,0xc6,
+0x24,0x02,0x00,0x04,0x12,0x02,0x00,0x12,0x2a,0x02,0x00,0x41,0x10,0x40,0x00,0x09,
+0x24,0x02,0x00,0x80,0x24,0x02,0x00,0x20,0x16,0x02,0xff,0x7b,0x3c,0x02,0xb0,0x05,
+0x24,0x02,0x00,0x12,0xa2,0x22,0x00,0x0a,0xa2,0x22,0x00,0x08,0x08,0x00,0x0d,0x4d,
+0xae,0x20,0x00,0x3c,0x16,0x02,0xff,0x74,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x10,
+0xa2,0x22,0x00,0x0a,0xa2,0x22,0x00,0x08,0x08,0x00,0x0d,0x4d,0xae,0x20,0x00,0x34,
+0x24,0x02,0x00,0x11,0xa2,0x22,0x00,0x0a,0xa2,0x22,0x00,0x08,0x08,0x00,0x0d,0x4d,
+0xae,0x20,0x00,0x38,0x8e,0x24,0x00,0x30,0x24,0x02,0x00,0x03,0x24,0x03,0x00,0x01,
+0x10,0x83,0x00,0x07,0xa2,0x22,0x00,0x08,0x24,0x02,0x00,0x02,0xa2,0x22,0x00,0x0a,
+0x92,0x22,0x00,0x33,0xae,0x20,0x00,0x30,0x08,0x00,0x0d,0x4d,0xa2,0x22,0x00,0x07,
+0x08,0x00,0x0d,0xec,0xa2,0x24,0x00,0x0a,0x8f,0x84,0xb4,0x30,0xae,0x20,0x00,0x34,
+0x94,0x85,0x00,0x14,0x0c,0x00,0x1b,0x84,0x32,0x10,0x00,0xff,0x08,0x00,0x0d,0x3e,
+0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x37,0xe4,
+0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00,0x80,0xa2,0x00,0x15,0x3c,0x06,0xb0,0x05,
+0x10,0x40,0x00,0x0a,0x34,0xc6,0x02,0x54,0x83,0x83,0x8b,0xc4,0x00,0x00,0x00,0x00,
+0xac,0x83,0x00,0x24,0x8c,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x42,
+0x30,0x42,0x00,0x01,0x03,0xe0,0x00,0x08,0xac,0x82,0x00,0x28,0x8c,0x82,0x00,0x2c,
+0x3c,0x06,0xb0,0x05,0x34,0xc6,0x04,0x50,0x00,0x02,0x18,0x43,0x30,0x63,0x00,0x01,
+0x10,0x40,0x00,0x04,0x30,0x45,0x00,0x01,0xac,0x83,0x00,0x28,0x03,0xe0,0x00,0x08,
+0xac,0x85,0x00,0x24,0x90,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,
+0x30,0x43,0x00,0x02,0x30,0x42,0x00,0x01,0xac,0x83,0x00,0x28,0x03,0xe0,0x00,0x08,
+0xac,0x82,0x00,0x24,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xd8,
+0x34,0x63,0x00,0x20,0x24,0x42,0x38,0x74,0xac,0x62,0x00,0x00,0xaf,0xb1,0x00,0x1c,
+0xaf,0xbf,0x00,0x20,0xaf,0xb0,0x00,0x18,0x90,0xa6,0x00,0x0a,0x27,0x83,0xb3,0xf0,
+0x00,0xa0,0x88,0x21,0x00,0x06,0x10,0x80,0x00,0x43,0x10,0x21,0x8c,0x50,0x00,0x00,
+0x80,0xa5,0x00,0x11,0x92,0x03,0x00,0x12,0x10,0xa0,0x00,0x04,0xa2,0x20,0x00,0x15,
+0x24,0x02,0x00,0x12,0x10,0xc2,0x00,0xda,0x00,0x00,0x00,0x00,0x82,0x22,0x00,0x12,
+0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x67,0x00,0x00,0x00,0x00,0xa2,0x20,0x00,0x12,
+0xa2,0x00,0x00,0x19,0x86,0x23,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0,
+0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21,
+0xa0,0x40,0x00,0x00,0x92,0x03,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0xdf,
+0xa2,0x03,0x00,0x16,0x82,0x02,0x00,0x12,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x20,
+0x00,0x00,0x00,0x00,0x92,0x23,0x00,0x08,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x45,
+0x24,0x02,0x00,0x01,0xa2,0x20,0x00,0x04,0x92,0x08,0x00,0x04,0x00,0x00,0x00,0x00,
+0x15,0x00,0x00,0x1e,0x24,0x02,0x00,0x01,0x92,0x07,0x00,0x0a,0xa2,0x02,0x00,0x17,
+0x92,0x02,0x00,0x16,0x30,0xe3,0x00,0xff,0x30,0x42,0x00,0xe4,0x10,0x60,0x00,0x03,
+0xa2,0x02,0x00,0x16,0x34,0x42,0x00,0x01,0xa2,0x02,0x00,0x16,0x11,0x00,0x00,0x05,
+0x00,0x00,0x00,0x00,0x92,0x02,0x00,0x16,0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x02,
+0xa2,0x02,0x00,0x16,0x92,0x02,0x00,0x17,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x08,
+0x00,0x00,0x00,0x00,0x96,0x02,0x00,0x06,0x00,0x00,0x00,0x00,0xa6,0x02,0x00,0x14,
+0x8f,0xbf,0x00,0x20,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,
+0x96,0x02,0x00,0x00,0x08,0x00,0x0e,0x68,0xa6,0x02,0x00,0x14,0x92,0x07,0x00,0x0a,
+0x00,0x00,0x00,0x00,0x14,0xe0,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x0e,0x54,
+0xa2,0x00,0x00,0x17,0x96,0x04,0x00,0x00,0x96,0x05,0x00,0x06,0x27,0x86,0x8f,0xf0,
+0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x05,0x10,0xc0,0x00,0x45,0x10,0x21,
+0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21,0x00,0x02,0x10,0x80,0x00,0x46,0x10,0x21,
+0x8c,0x66,0x00,0x08,0x8c,0x45,0x00,0x08,0x3c,0x03,0x80,0x00,0x00,0xc3,0x20,0x24,
+0x10,0x80,0x00,0x08,0x00,0xa3,0x10,0x24,0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21,
+0x10,0x80,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0xa6,0x18,0x2b,0x08,0x00,0x0e,0x54,
+0xa2,0x03,0x00,0x17,0x10,0x40,0xff,0xfd,0x00,0xa6,0x18,0x2b,0x08,0x00,0x0e,0x88,
+0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x09,0x24,0x02,0x00,0x02,0x10,0x62,0x00,0x05,
+0x24,0x02,0x00,0x03,0x14,0x62,0xff,0xb8,0x00,0x00,0x00,0x00,0x08,0x00,0x0e,0x4e,
+0xa2,0x20,0x00,0x07,0x08,0x00,0x0e,0x4e,0xa2,0x20,0x00,0x06,0x08,0x00,0x0e,0x4e,
+0xa2,0x20,0x00,0x05,0x82,0x22,0x00,0x10,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x69,
+0x2c,0x62,0x00,0x02,0x10,0x40,0x00,0x49,0x3c,0x02,0xb0,0x09,0x92,0x25,0x00,0x08,
+0x00,0x00,0x00,0x00,0x30,0xa6,0x00,0xff,0x2c,0xc2,0x00,0x04,0x10,0x40,0x00,0x3b,
+0x2c,0xc2,0x00,0x10,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,
+0x24,0x02,0x00,0x01,0x00,0xc2,0x10,0x04,0x00,0x02,0x10,0x27,0x00,0x62,0x18,0x24,
+0xa0,0x83,0x00,0x00,0x86,0x23,0x00,0x0c,0x96,0x26,0x00,0x0c,0x00,0x03,0x10,0xc0,
+0x00,0x43,0x10,0x21,0x00,0x02,0x28,0x80,0x27,0x83,0x8f,0xf4,0x00,0xa3,0x18,0x21,
+0x8c,0x64,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x04,0x00,0x00,0x00,0x00,
+0x30,0x42,0x00,0x10,0x10,0x40,0x00,0x18,0x24,0x07,0x00,0x01,0x93,0x82,0x8b,0x61,
+0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x0a,0x24,0x05,0x00,0x24,
+0x00,0x06,0x2c,0x00,0x00,0x05,0x2c,0x03,0x0c,0x00,0x1b,0x84,0x02,0x00,0x20,0x21,
+0x92,0x02,0x00,0x16,0xa2,0x00,0x00,0x12,0x30,0x42,0x00,0xe7,0x08,0x00,0x0e,0x45,
+0xa2,0x02,0x00,0x16,0xf0,0xc5,0x00,0x06,0x00,0x00,0x28,0x12,0x27,0x82,0x8f,0xf0,
+0x00,0xa2,0x28,0x21,0x0c,0x00,0x01,0x4b,0x3c,0x04,0x00,0x80,0x96,0x26,0x00,0x0c,
+0x08,0x00,0x0e,0xc5,0x00,0x06,0x2c,0x00,0x27,0x83,0x90,0x00,0x27,0x82,0x90,0x08,
+0x00,0xa2,0x10,0x21,0x00,0xa3,0x18,0x21,0x90,0x44,0x00,0x00,0x90,0x65,0x00,0x05,
+0x93,0x82,0x80,0x10,0x00,0x00,0x30,0x21,0x0c,0x00,0x21,0xf5,0xaf,0xa2,0x00,0x10,
+0x96,0x26,0x00,0x0c,0x08,0x00,0x0e,0xbf,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xcd,
+0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x30,0xa5,0x00,0x0f,
+0x24,0x02,0x00,0x80,0x08,0x00,0x0e,0xae,0x00,0xa2,0x10,0x07,0x86,0x26,0x00,0x0c,
+0x3c,0x03,0xb0,0x09,0x34,0x42,0x01,0x72,0x34,0x63,0x01,0x78,0x94,0x47,0x00,0x00,
+0x8c,0x65,0x00,0x00,0x00,0x06,0x10,0xc0,0x00,0x46,0x10,0x21,0x3c,0x04,0xb0,0x09,
+0xae,0x25,0x00,0x1c,0x34,0x84,0x01,0x7c,0x27,0x83,0x8f,0xf4,0x00,0x02,0x10,0x80,
+0x8c,0x85,0x00,0x00,0x00,0x43,0x10,0x21,0x8c,0x43,0x00,0x18,0xae,0x25,0x00,0x20,
+0xa6,0x27,0x00,0x18,0x8c,0x66,0x00,0x08,0x02,0x20,0x20,0x21,0x0c,0x00,0x0f,0x15,
+0x00,0x00,0x28,0x21,0x86,0x25,0x00,0x18,0x8e,0x26,0x00,0x1c,0x8e,0x27,0x00,0x20,
+0x02,0x20,0x20,0x21,0x0c,0x00,0x1c,0x86,0xaf,0xa2,0x00,0x10,0x08,0x00,0x0e,0x45,
+0xa2,0x02,0x00,0x12,0x92,0x22,0x00,0x08,0x08,0x00,0x0e,0x45,0xa2,0x22,0x00,0x09,
+0xa2,0x20,0x00,0x11,0x80,0x82,0x00,0x50,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x03,
+0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xd0,0xac,0x40,0x00,0x00,0x08,0x00,0x0e,0x45,
+0xa0,0x80,0x00,0x50,0x94,0x8a,0x00,0x0c,0x24,0x03,0x00,0x24,0x00,0x80,0x70,0x21,
+0x3c,0x02,0x80,0x00,0x3c,0x04,0xb0,0x03,0x24,0x42,0x3c,0x54,0xf1,0x43,0x00,0x06,
+0x34,0x84,0x00,0x20,0x00,0x00,0x18,0x12,0x00,0xa0,0x68,0x21,0xac,0x82,0x00,0x00,
+0x27,0x85,0x90,0x00,0x27,0x82,0x8f,0xff,0x27,0xbd,0xff,0xf8,0x00,0x62,0x60,0x21,
+0x00,0x65,0x58,0x21,0x00,0x00,0xc0,0x21,0x11,0xa0,0x00,0xcc,0x00,0x00,0x78,0x21,
+0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
+0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21,0x91,0x87,0x00,0x00,0x80,0x48,0x00,0x04,
+0x03,0xa0,0x60,0x21,0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,
+0x00,0x43,0x10,0x21,0x00,0x02,0x48,0x80,0x27,0x83,0x8f,0xf4,0xa3,0xa7,0x00,0x00,
+0x01,0x23,0x18,0x21,0x8c,0x64,0x00,0x18,0x25,0x02,0xff,0xff,0x00,0x48,0x40,0x0b,
+0x8c,0x83,0x00,0x04,0x2d,0x05,0x00,0x07,0x24,0x02,0x00,0x06,0x30,0x63,0x00,0x08,
+0x14,0x60,0x00,0x35,0x00,0x45,0x40,0x0a,0x93,0xa7,0x00,0x00,0x27,0x82,0x90,0x08,
+0x01,0x22,0x10,0x21,0x30,0xe3,0x00,0xf0,0x38,0x63,0x00,0x50,0x30,0xe5,0x00,0xff,
+0x00,0x05,0x20,0x2b,0x00,0x03,0x18,0x2b,0x00,0x64,0x18,0x24,0x90,0x49,0x00,0x00,
+0x10,0x60,0x00,0x16,0x30,0xe4,0x00,0x0f,0x24,0x02,0x00,0x04,0x10,0xa2,0x00,0x9d,
+0x00,0x00,0x00,0x00,0x11,0xa0,0x00,0x3a,0x2c,0xa2,0x00,0x0c,0x10,0x40,0x00,0x02,
+0x24,0x84,0x00,0x0c,0x00,0xe0,0x20,0x21,0x30,0x84,0x00,0xff,0x00,0x04,0x10,0x40,
+0x27,0x83,0xbb,0x0c,0x00,0x44,0x10,0x21,0x00,0x43,0x10,0x21,0x90,0x47,0x00,0x00,
+0x00,0x00,0x00,0x00,0x2c,0xe3,0x00,0x0c,0xa3,0xa7,0x00,0x00,0x10,0x60,0x00,0x02,
+0x24,0xe2,0x00,0x04,0x00,0xe0,0x10,0x21,0xa3,0xa2,0x00,0x00,0x91,0x65,0x00,0x00,
+0x91,0x82,0x00,0x00,0x30,0xa3,0x00,0xff,0x00,0x62,0x10,0x2b,0x10,0x40,0x00,0x0e,
+0x2c,0x62,0x00,0x0c,0x14,0x40,0x00,0x03,0x00,0x60,0x20,0x21,0x30,0xa2,0x00,0x0f,
+0x24,0x44,0x00,0x0c,0x00,0x04,0x10,0x40,0x00,0x44,0x20,0x21,0x27,0x83,0xbb,0x0c,
+0x00,0x83,0x18,0x21,0x90,0x62,0x00,0x02,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x05,
+0x00,0x09,0x11,0x00,0xa1,0x85,0x00,0x00,0x93,0xa2,0x00,0x00,0x03,0xe0,0x00,0x08,
+0x27,0xbd,0x00,0x08,0x00,0x49,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x49,0x10,0x23,
+0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,0x27,0x83,0xb4,0x98,0x00,0x43,0x10,0x21,
+0x90,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0x83,0x00,0x0c,0x14,0x60,0x00,0x06,
+0x00,0x80,0x10,0x21,0x00,0x18,0x10,0x40,0x00,0x4f,0x10,0x21,0x00,0x02,0x11,0x00,
+0x00,0x82,0x10,0x21,0x24,0x42,0x00,0x04,0x08,0x00,0x0f,0x76,0xa1,0x82,0x00,0x00,
+0x8f,0x8d,0x81,0x5c,0x00,0x00,0x00,0x00,0x01,0xa8,0x10,0x21,0x90,0x43,0x00,0x00,
+0x00,0x00,0x00,0x00,0x10,0x60,0xff,0xd1,0x00,0x00,0x28,0x21,0x00,0x06,0x74,0x82,
+0x30,0xe2,0x00,0xff,0x2c,0x42,0x00,0x0c,0x14,0x40,0x00,0x03,0x00,0xe0,0x10,0x21,
+0x30,0xe2,0x00,0x0f,0x24,0x42,0x00,0x0c,0x30,0x44,0x00,0xff,0xa3,0xa2,0x00,0x00,
+0x24,0x02,0x00,0x0c,0x10,0x82,0x00,0x0d,0x00,0x09,0x11,0x00,0x00,0x49,0x10,0x23,
+0x00,0x02,0x10,0x80,0x00,0x04,0x18,0x40,0x00,0x49,0x10,0x23,0x00,0x64,0x18,0x21,
+0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x27,0x84,0xb4,0x98,0x00,0x44,0x10,0x21,
+0x90,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0xa3,0xa7,0x00,0x00,0x00,0x0a,0x1c,0x00,
+0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,
+0x27,0x83,0x8f,0xf4,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x18,0x00,0x00,0x00,0x00,
+0x8c,0x83,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x10,0x14,0x60,0x00,0x33,
+0x00,0x06,0x14,0x42,0x00,0x09,0x11,0x00,0x00,0x49,0x10,0x23,0x00,0x02,0x10,0x80,
+0x00,0x49,0x10,0x23,0x27,0x83,0xb5,0x68,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,
+0x90,0x44,0x00,0x04,0x90,0x43,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x64,0xc0,0x24,
+0x93,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0xe2,0x00,0x0f,0x10,0x40,0x00,0x0f,
+0x31,0xcf,0x00,0x01,0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,
+0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x84,0x8f,0xf0,0x00,0x44,0x10,0x21,
+0x84,0x43,0x00,0x06,0x00,0x00,0x00,0x00,0x28,0x63,0x06,0x41,0x14,0x60,0x00,0x04,
+0x30,0xe2,0x00,0xff,0x24,0x07,0x00,0x0f,0xa3,0xa7,0x00,0x00,0x30,0xe2,0x00,0xff,
+0x2c,0x42,0x00,0x0c,0x14,0x40,0x00,0x06,0x00,0xe0,0x10,0x21,0x00,0x18,0x10,0x40,
+0x00,0x4f,0x10,0x21,0x00,0x02,0x11,0x00,0x00,0x47,0x10,0x21,0x24,0x42,0x00,0x04,
+0xa3,0xa2,0x00,0x00,0x00,0x40,0x38,0x21,0x01,0xa8,0x10,0x21,0x90,0x43,0x00,0x00,
+0x24,0xa4,0x00,0x01,0x30,0x85,0xff,0xff,0x00,0xa3,0x18,0x2b,0x14,0x60,0xff,0xad,
+0x30,0xe2,0x00,0xff,0x08,0x00,0x0f,0x63,0x00,0x00,0x00,0x00,0x08,0x00,0x0f,0xc4,
+0x30,0x58,0x00,0x01,0x81,0xc2,0x00,0x48,0x00,0x00,0x00,0x00,0x10,0x40,0xff,0x73,
+0x00,0x00,0x00,0x00,0x08,0x00,0x0f,0x51,0x00,0x00,0x00,0x00,0x00,0x0a,0x1c,0x00,
+0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,
+0x00,0x45,0x10,0x21,0x80,0x48,0x00,0x05,0x91,0x67,0x00,0x00,0x08,0x00,0x0f,0x31,
+0x03,0xa0,0x58,0x21,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,
+0x24,0x42,0x3f,0xf4,0x03,0xe0,0x00,0x08,0xac,0x62,0x00,0x00,0x27,0xbd,0xff,0xc0,
+0xaf,0xb7,0x00,0x34,0xaf,0xb6,0x00,0x30,0xaf,0xb5,0x00,0x2c,0xaf,0xb4,0x00,0x28,
+0xaf,0xb3,0x00,0x24,0xaf,0xb2,0x00,0x20,0xaf,0xbf,0x00,0x3c,0xaf,0xbe,0x00,0x38,
+0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18,0x84,0x82,0x00,0x0c,0x27,0x93,0x8f,0xf4,
+0x3c,0x05,0xb0,0x03,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x80,
+0x00,0x73,0x10,0x21,0x8c,0x5e,0x00,0x18,0x3c,0x02,0x80,0x00,0x34,0xa5,0x00,0x20,
+0x24,0x42,0x40,0x0c,0xac,0xa2,0x00,0x00,0x8f,0xd0,0x00,0x08,0x27,0x95,0x90,0x00,
+0x00,0x75,0x18,0x21,0x00,0x00,0x28,0x21,0x02,0x00,0x30,0x21,0x90,0x71,0x00,0x00,
+0x0c,0x00,0x0f,0x15,0x00,0x80,0xb0,0x21,0x00,0x40,0x90,0x21,0x00,0x10,0x14,0x42,
+0x30,0x54,0x00,0x01,0x02,0x40,0x20,0x21,0x00,0x10,0x14,0x82,0x02,0x80,0x28,0x21,
+0x12,0x51,0x00,0x23,0x00,0x10,0xbf,0xc2,0x86,0xc3,0x00,0x0c,0x30,0x50,0x00,0x01,
+0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x55,0x10,0x21,
+0xa0,0x52,0x00,0x00,0x86,0xc3,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0,
+0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x53,0x30,0x21,0x8c,0xc7,0x00,0x18,
+0x27,0x83,0x8f,0xf0,0x00,0x43,0x10,0x21,0x8c,0xe3,0x00,0x04,0x84,0x46,0x00,0x06,
+0x00,0x03,0x19,0x42,0x0c,0x00,0x08,0xdf,0x30,0x73,0x00,0x01,0x00,0x40,0x88,0x21,
+0x02,0x40,0x20,0x21,0x02,0x80,0x28,0x21,0x16,0xe0,0x00,0x10,0x02,0x00,0x30,0x21,
+0x86,0xc2,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,
+0x00,0x03,0x18,0x80,0x27,0x82,0x8f,0xf8,0x00,0x62,0x18,0x21,0xa4,0x71,0x00,0x04,
+0x7b,0xbe,0x01,0xfc,0x7b,0xb6,0x01,0xbc,0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c,
+0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,0x86,0xc3,0x00,0x0c,
+0xaf,0xb3,0x00,0x10,0xaf,0xa0,0x00,0x14,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
+0x00,0x02,0x10,0x80,0x00,0x55,0x10,0x21,0x80,0x47,0x00,0x06,0x00,0x00,0x00,0x00,
+0x24,0xe7,0x00,0x02,0x00,0x07,0x17,0xc2,0x00,0xe2,0x38,0x21,0x00,0x07,0x38,0x43,
+0x00,0x07,0x38,0x40,0x0c,0x00,0x09,0x06,0x03,0xc7,0x38,0x21,0x08,0x00,0x10,0x44,
+0x02,0x22,0x88,0x21,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xd0,
+0x34,0x63,0x00,0x20,0x24,0x42,0x41,0x94,0xaf,0xb2,0x00,0x20,0xac,0x62,0x00,0x00,
+0xaf,0xbf,0x00,0x28,0xaf,0xb3,0x00,0x24,0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18,
+0x3c,0x02,0xb0,0x03,0x90,0x83,0x00,0x0a,0x34,0x42,0x01,0x04,0x94,0x45,0x00,0x00,
+0x00,0x03,0x18,0x80,0x27,0x82,0xb3,0xf0,0x00,0x62,0x18,0x21,0x30,0xa6,0xff,0xff,
+0x8c,0x71,0x00,0x00,0x80,0x85,0x00,0x12,0x30,0xc9,0x00,0xff,0x00,0x06,0x32,0x02,
+0xa4,0x86,0x00,0x44,0xa4,0x89,0x00,0x46,0x82,0x22,0x00,0x12,0x00,0x80,0x90,0x21,
+0x10,0xa0,0x00,0x1b,0xa0,0x80,0x00,0x15,0x00,0xc5,0x10,0x2a,0x10,0x40,0x00,0x14,
+0x00,0x00,0x00,0x00,0xa2,0x20,0x00,0x19,0x84,0x83,0x00,0x0c,0x00,0x00,0x00,0x00,
+0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x10,
+0x00,0x43,0x10,0x21,0xa0,0x40,0x00,0x00,0xa0,0x80,0x00,0x12,0x92,0x22,0x00,0x16,
+0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xdf,0xa2,0x22,0x00,0x16,0x8f,0xbf,0x00,0x28,
+0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30,
+0x0c,0x00,0x0f,0xfd,0x00,0x00,0x00,0x00,0x08,0x00,0x10,0x93,0x00,0x00,0x00,0x00,
+0x28,0x42,0x00,0x02,0x10,0x40,0x01,0x76,0x00,0x00,0x28,0x21,0x94,0x87,0x00,0x0c,
+0x00,0x00,0x00,0x00,0x00,0xe0,0x10,0x21,0x00,0x02,0x14,0x00,0x00,0x02,0x14,0x03,
+0x00,0x07,0x24,0x00,0x00,0x04,0x24,0x03,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,
+0x00,0x04,0x28,0xc0,0x00,0xa4,0x28,0x21,0x27,0x82,0x90,0x10,0x00,0x03,0x18,0x80,
+0x00,0x62,0x18,0x21,0x00,0x05,0x28,0x80,0x27,0x82,0x8f,0xf8,0x00,0xa2,0x10,0x21,
+0x8c,0x68,0x00,0x00,0x80,0x44,0x00,0x06,0x27,0x82,0x90,0x00,0x00,0x08,0x1d,0x02,
+0x00,0xa2,0x28,0x21,0x38,0x84,0x00,0x00,0x30,0x63,0x00,0x01,0x01,0x24,0x30,0x0b,
+0x80,0xaa,0x00,0x04,0x80,0xa9,0x00,0x05,0x10,0x60,0x00,0x02,0x00,0x08,0x14,0x02,
+0x30,0x46,0x00,0x0f,0x15,0x20,0x00,0x28,0x01,0x49,0x10,0x21,0x15,0x40,0x00,0x11,
+0x30,0xe3,0xff,0xff,0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa8,0x00,0xff,
+0x2d,0x02,0x00,0x04,0x10,0x40,0x01,0x46,0x2d,0x02,0x00,0x10,0x3c,0x04,0xb0,0x05,
+0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01,0x01,0x02,0x10,0x04,
+0x00,0x62,0x18,0x25,0xa0,0x83,0x00,0x00,0x96,0x47,0x00,0x0c,0x00,0x00,0x00,0x00,
+0x30,0xe3,0xff,0xff,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x27,0x84,0x90,0x00,
+0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,0x80,0x45,0x00,0x06,0x00,0x03,0x1a,0x00,
+0x3c,0x04,0xb0,0x00,0x00,0x65,0x18,0x21,0x00,0x64,0x20,0x21,0x94,0x82,0x00,0x00,
+0x82,0x43,0x00,0x10,0x00,0x02,0x14,0x00,0x14,0x60,0x00,0x06,0x00,0x02,0x3c,0x03,
+0x30,0xe2,0x00,0x04,0x14,0x40,0x00,0x04,0x01,0x49,0x10,0x21,0x34,0xe2,0x08,0x00,
+0xa4,0x82,0x00,0x00,0x01,0x49,0x10,0x21,0x00,0x02,0x16,0x00,0x00,0x02,0x16,0x03,
+0x00,0x46,0x10,0x2a,0x10,0x40,0x00,0x7c,0x00,0x00,0x00,0x00,0x82,0x42,0x00,0x10,
+0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0e,0x00,0x00,0x00,0x00,0x86,0x43,0x00,0x0c,
+0x25,0x44,0x00,0x01,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,
+0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0xa0,0x44,0x00,0x04,0x92,0x23,0x00,0x16,
+0x02,0x40,0x20,0x21,0x30,0x63,0x00,0xfb,0x08,0x00,0x10,0x98,0xa2,0x23,0x00,0x16,
+0x86,0x43,0x00,0x0c,0x25,0x24,0x00,0x01,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
+0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0xa0,0x44,0x00,0x05,
+0x86,0x45,0x00,0x0c,0x0c,0x00,0x1f,0x08,0x02,0x20,0x20,0x21,0x10,0x40,0x00,0x5a,
+0x00,0x00,0x00,0x00,0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa6,0x00,0xff,
+0x2c,0xc2,0x00,0x04,0x10,0x40,0x00,0x4c,0x2c,0xc2,0x00,0x10,0x3c,0x04,0xb0,0x05,
+0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01,0x00,0xc2,0x10,0x04,
+0x00,0x02,0x10,0x27,0x00,0x62,0x18,0x24,0xa0,0x83,0x00,0x00,0x92,0x45,0x00,0x08,
+0x00,0x00,0x00,0x00,0x30,0xa5,0x00,0xff,0x14,0xa0,0x00,0x33,0x24,0x02,0x00,0x01,
+0xa2,0x40,0x00,0x04,0x92,0x22,0x00,0x04,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x0c,
+0x24,0x02,0x00,0x01,0xa2,0x22,0x00,0x17,0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00,
+0x10,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0x96,0x22,0x00,0x06,0x08,0x00,0x10,0x93,
+0xa6,0x22,0x00,0x14,0x96,0x22,0x00,0x00,0x08,0x00,0x10,0x93,0xa6,0x22,0x00,0x14,
+0x92,0x22,0x00,0x0a,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x03,0x00,0x00,0x00,0x00,
+0x08,0x00,0x11,0x22,0xa2,0x20,0x00,0x17,0x96,0x24,0x00,0x00,0x96,0x25,0x00,0x06,
+0x27,0x86,0x8f,0xf0,0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x05,0x10,0xc0,
+0x00,0x45,0x10,0x21,0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21,0x00,0x02,0x10,0x80,
+0x00,0x46,0x10,0x21,0x8c,0x65,0x00,0x08,0x8c,0x44,0x00,0x08,0x3c,0x03,0x80,0x00,
+0x00,0xa3,0x30,0x24,0x10,0xc0,0x00,0x08,0x00,0x83,0x10,0x24,0x10,0x40,0x00,0x04,
+0x00,0x00,0x18,0x21,0x10,0xc0,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0x85,0x18,0x2b,
+0x08,0x00,0x11,0x22,0xa2,0x23,0x00,0x17,0x10,0x40,0xff,0xfd,0x00,0x85,0x18,0x2b,
+0x08,0x00,0x11,0x45,0x00,0x00,0x00,0x00,0x10,0xa2,0x00,0x09,0x24,0x02,0x00,0x02,
+0x10,0xa2,0x00,0x05,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xca,0x00,0x00,0x00,0x00,
+0x08,0x00,0x11,0x1d,0xa2,0x40,0x00,0x07,0x08,0x00,0x11,0x1d,0xa2,0x40,0x00,0x06,
+0x08,0x00,0x11,0x1d,0xa2,0x40,0x00,0x05,0x14,0x40,0xff,0xbe,0x3c,0x04,0xb0,0x05,
+0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80,
+0x08,0x00,0x11,0x14,0x00,0xa2,0x10,0x07,0x0c,0x00,0x10,0x03,0x02,0x40,0x20,0x21,
+0x08,0x00,0x10,0x93,0x00,0x00,0x00,0x00,0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,
+0x30,0xa6,0x00,0xff,0x2c,0xc2,0x00,0x04,0x10,0x40,0x00,0x99,0x2c,0xc2,0x00,0x10,
+0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01,
+0x00,0xc2,0x10,0x04,0x00,0x02,0x10,0x27,0x00,0x62,0x18,0x24,0xa0,0x83,0x00,0x00,
+0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa5,0x00,0xff,0x14,0xa0,0x00,0x80,
+0x24,0x02,0x00,0x01,0xa2,0x40,0x00,0x04,0x86,0x43,0x00,0x0c,0x27,0x93,0x8f,0xf4,
+0x96,0x47,0x00,0x0c,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x28,0x80,
+0x00,0xb3,0x18,0x21,0x8c,0x64,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x04,
+0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x10,0x10,0x40,0x00,0x64,0x00,0x00,0x30,0x21,
+0x00,0x07,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
+0x00,0x02,0x10,0x80,0x00,0x53,0x10,0x21,0x8c,0x43,0x00,0x18,0x93,0x82,0x8b,0x61,
+0x8c,0x64,0x00,0x04,0x30,0x42,0x00,0x01,0x00,0x04,0x21,0x42,0x14,0x40,0x00,0x4d,
+0x30,0x90,0x00,0x01,0x00,0x07,0x2c,0x00,0x00,0x05,0x2c,0x03,0x0c,0x00,0x1b,0x84,
+0x02,0x20,0x20,0x21,0x96,0x26,0x00,0x06,0x12,0x00,0x00,0x14,0x30,0xc5,0xff,0xff,
+0x02,0x60,0x90,0x21,0x00,0x05,0x10,0xc0,0x00,0x45,0x10,0x21,0x00,0x02,0x10,0x80,
+0x00,0x52,0x18,0x21,0x92,0x22,0x00,0x0a,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0b,
+0x02,0x20,0x20,0x21,0x8c,0x63,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x62,0x00,0x04,
+0x00,0x00,0x00,0x00,0x00,0x02,0x11,0x42,0x0c,0x00,0x1b,0x84,0x30,0x50,0x00,0x01,
+0x96,0x26,0x00,0x06,0x16,0x00,0xff,0xef,0x30,0xc5,0xff,0xff,0x92,0x22,0x00,0x04,
+0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x0d,0x24,0x02,0x00,0x01,0xa2,0x22,0x00,0x17,
+0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x05,0x00,0x00,0x00,0x00,
+0xa6,0x26,0x00,0x14,0x92,0x22,0x00,0x16,0x08,0x00,0x10,0x92,0x30,0x42,0x00,0xc3,
+0x96,0x22,0x00,0x00,0x08,0x00,0x11,0xb9,0xa6,0x22,0x00,0x14,0x92,0x22,0x00,0x0a,
+0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x11,0xb4,
+0xa2,0x20,0x00,0x17,0x96,0x24,0x00,0x00,0x30,0xc5,0xff,0xff,0x00,0x05,0x18,0xc0,
+0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,0x00,0x65,0x18,0x21,0x27,0x84,0x8f,0xf0,
+0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,0x00,0x03,0x18,0x80,0x8c,0x45,0x00,0x08,
+0x00,0x64,0x18,0x21,0x8c,0x64,0x00,0x08,0x3c,0x02,0x80,0x00,0x00,0xa2,0x38,0x24,
+0x10,0xe0,0x00,0x08,0x00,0x82,0x10,0x24,0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21,
+0x10,0xe0,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0x85,0x18,0x2b,0x08,0x00,0x11,0xb4,
+0xa2,0x23,0x00,0x17,0x10,0x40,0xff,0xfd,0x00,0x85,0x18,0x2b,0x08,0x00,0x11,0xd8,
+0x00,0x00,0x00,0x00,0x24,0x05,0x00,0x24,0xf0,0xe5,0x00,0x06,0x00,0x00,0x28,0x12,
+0x27,0x82,0x8f,0xf0,0x00,0xa2,0x28,0x21,0x0c,0x00,0x01,0x4b,0x00,0x00,0x20,0x21,
+0x96,0x47,0x00,0x0c,0x08,0x00,0x11,0x96,0x00,0x07,0x2c,0x00,0x27,0x83,0x90,0x00,
+0x27,0x82,0x90,0x08,0x00,0xa2,0x10,0x21,0x00,0xa3,0x18,0x21,0x90,0x44,0x00,0x00,
+0x90,0x65,0x00,0x05,0x93,0x82,0x80,0x10,0x24,0x07,0x00,0x01,0x0c,0x00,0x21,0xf5,
+0xaf,0xa2,0x00,0x10,0x96,0x47,0x00,0x0c,0x08,0x00,0x11,0x89,0x00,0x07,0x1c,0x00,
+0x10,0xa2,0x00,0x09,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x05,0x24,0x02,0x00,0x03,
+0x14,0xa2,0xff,0x7d,0x00,0x00,0x00,0x00,0x08,0x00,0x11,0x7a,0xa2,0x40,0x00,0x07,
+0x08,0x00,0x11,0x7a,0xa2,0x40,0x00,0x06,0x08,0x00,0x11,0x7a,0xa2,0x40,0x00,0x05,
+0x14,0x40,0xff,0x71,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,
+0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80,0x08,0x00,0x11,0x71,0x00,0xa2,0x10,0x07,
+0x14,0x40,0xfe,0xc3,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,
+0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80,0x08,0x00,0x10,0xcc,0x00,0xa2,0x10,0x07,
+0x84,0x83,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
+0x00,0x02,0x10,0x80,0x27,0x83,0x8f,0xf4,0x00,0x43,0x10,0x21,0x8c,0x47,0x00,0x18,
+0x00,0x00,0x00,0x00,0x8c,0xe6,0x00,0x08,0x0c,0x00,0x0f,0x15,0x00,0x00,0x00,0x00,
+0x02,0x40,0x20,0x21,0x00,0x00,0x28,0x21,0x00,0x00,0x30,0x21,0x00,0x00,0x38,0x21,
+0x0c,0x00,0x1c,0x86,0xaf,0xa2,0x00,0x10,0x00,0x02,0x1e,0x00,0x14,0x60,0xfe,0x6b,
+0xa2,0x22,0x00,0x12,0x92,0x43,0x00,0x08,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x40,
+0x24,0x02,0x00,0x01,0xa2,0x40,0x00,0x04,0x92,0x28,0x00,0x04,0x00,0x00,0x00,0x00,
+0x15,0x00,0x00,0x19,0x24,0x02,0x00,0x01,0x92,0x27,0x00,0x0a,0xa2,0x22,0x00,0x17,
+0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x10,0x00,0x00,0x00,0x00,
+0x96,0x22,0x00,0x06,0x00,0x00,0x00,0x00,0xa6,0x22,0x00,0x14,0x92,0x22,0x00,0x16,
+0x30,0xe3,0x00,0xff,0x30,0x42,0x00,0xc0,0x10,0x60,0x00,0x03,0xa2,0x22,0x00,0x16,
+0x34,0x42,0x00,0x01,0xa2,0x22,0x00,0x16,0x11,0x00,0xfe,0x50,0x00,0x00,0x00,0x00,
+0x92,0x22,0x00,0x16,0x08,0x00,0x10,0x92,0x34,0x42,0x00,0x02,0x96,0x22,0x00,0x00,
+0x08,0x00,0x12,0x3b,0xa6,0x22,0x00,0x14,0x92,0x27,0x00,0x0a,0x00,0x00,0x00,0x00,
+0x14,0xe0,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x12,0x34,0xa2,0x20,0x00,0x17,
+0x96,0x24,0x00,0x00,0x96,0x25,0x00,0x06,0x27,0x86,0x8f,0xf0,0x00,0x04,0x18,0xc0,
+0x00,0x64,0x18,0x21,0x00,0x05,0x10,0xc0,0x00,0x45,0x10,0x21,0x00,0x03,0x18,0x80,
+0x00,0x66,0x18,0x21,0x00,0x02,0x10,0x80,0x00,0x46,0x10,0x21,0x8c,0x65,0x00,0x08,
+0x8c,0x44,0x00,0x08,0x3c,0x03,0x80,0x00,0x00,0xa3,0x30,0x24,0x10,0xc0,0x00,0x08,
+0x00,0x83,0x10,0x24,0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21,0x10,0xc0,0x00,0x02,
+0x24,0x03,0x00,0x01,0x00,0x85,0x18,0x2b,0x08,0x00,0x12,0x34,0xa2,0x23,0x00,0x17,
+0x10,0x40,0xff,0xfd,0x00,0x85,0x18,0x2b,0x08,0x00,0x12,0x63,0x00,0x00,0x00,0x00,
+0x10,0x62,0x00,0x09,0x24,0x02,0x00,0x02,0x10,0x62,0x00,0x05,0x24,0x02,0x00,0x03,
+0x14,0x62,0xff,0xbd,0x00,0x00,0x00,0x00,0x08,0x00,0x12,0x2e,0xa2,0x40,0x00,0x07,
+0x08,0x00,0x12,0x2e,0xa2,0x40,0x00,0x06,0x08,0x00,0x12,0x2e,0xa2,0x40,0x00,0x05,
+0x3c,0x02,0x80,0x00,0x00,0x82,0x30,0x24,0x10,0xc0,0x00,0x08,0x00,0xa2,0x18,0x24,
+0x10,0x60,0x00,0x04,0x00,0x00,0x10,0x21,0x10,0xc0,0x00,0x02,0x24,0x02,0x00,0x01,
+0x00,0xa4,0x10,0x2b,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x10,0x60,0xff,0xfd,
+0x00,0xa4,0x10,0x2b,0x08,0x00,0x12,0x7e,0x00,0x00,0x00,0x00,0x30,0x82,0xff,0xff,
+0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,0x27,0x84,0x90,0x00,0x00,0x03,0x18,0x80,
+0x00,0x64,0x18,0x21,0x80,0x66,0x00,0x06,0x00,0x02,0x12,0x00,0x3c,0x03,0xb0,0x00,
+0x00,0x46,0x10,0x21,0x00,0x45,0x10,0x21,0x03,0xe0,0x00,0x08,0x00,0x43,0x10,0x21,
+0x27,0xbd,0xff,0xe0,0x30,0x82,0x00,0x7c,0x30,0x84,0xff,0x00,0xaf,0xbf,0x00,0x1c,
+0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x14,0x40,0x00,0x41,
+0x00,0x04,0x22,0x03,0x24,0x02,0x00,0x04,0x3c,0x10,0xb0,0x03,0x8e,0x10,0x00,0x00,
+0x10,0x82,0x00,0x32,0x24,0x02,0x00,0x08,0x10,0x82,0x00,0x03,0x32,0x02,0x00,0x20,
+0x08,0x00,0x12,0xa4,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x17,0x3c,0x02,0xb0,0x06,
+0x34,0x42,0x80,0x24,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x67,0x00,0xff,
+0x10,0xe0,0x00,0x23,0x00,0x00,0x88,0x21,0x8f,0x85,0x8f,0xd0,0x00,0x40,0x30,0x21,
+0x94,0xa2,0x00,0x08,0x8c,0xc3,0x00,0x00,0x26,0x31,0x00,0x01,0x24,0x42,0x00,0x02,
+0x30,0x42,0x01,0xff,0x34,0x63,0x01,0x00,0x02,0x27,0x20,0x2a,0xa4,0xa2,0x00,0x08,
+0x14,0x80,0xff,0xf7,0xac,0xc3,0x00,0x00,0x84,0xa3,0x00,0x08,0x3c,0x02,0xb0,0x03,
+0x34,0x42,0x00,0x30,0xac,0x43,0x00,0x00,0x27,0x92,0xb3,0xf0,0x24,0x11,0x00,0x12,
+0x8e,0x44,0x00,0x00,0x26,0x31,0xff,0xff,0x90,0x82,0x00,0x10,0x00,0x00,0x00,0x00,
+0x10,0x40,0x00,0x03,0x26,0x52,0x00,0x04,0x0c,0x00,0x20,0xd0,0x00,0x00,0x00,0x00,
+0x06,0x21,0xff,0xf7,0x24,0x02,0xff,0xdf,0x02,0x02,0x80,0x24,0x3c,0x01,0xb0,0x03,
+0x0c,0x00,0x13,0x18,0xac,0x30,0x00,0x00,0x08,0x00,0x12,0xa4,0x00,0x00,0x00,0x00,
+0x8f,0x85,0x8f,0xd0,0x08,0x00,0x12,0xba,0x00,0x00,0x00,0x00,0x24,0x02,0xff,0x95,
+0x3c,0x03,0xb0,0x03,0x02,0x02,0x80,0x24,0x34,0x63,0x00,0x30,0x3c,0x01,0xb0,0x03,
+0xac,0x30,0x00,0x00,0x0c,0x00,0x12,0xe1,0xac,0x60,0x00,0x00,0x08,0x00,0x12,0xa4,
+0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x50,0x08,0x00,0x12,0xa4,
+0xac,0x46,0x00,0x00,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4b,0x84,0x3c,0x0b,0xb0,0x03,
+0xad,0x6a,0x00,0x20,0x3c,0x08,0x80,0x01,0x25,0x08,0x00,0x00,0x3c,0x09,0x80,0x01,
+0x25,0x29,0x03,0x1c,0x11,0x09,0x00,0x10,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00,
+0x25,0x4a,0x4b,0xac,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0x3c,0x08,0xb0,0x06,
+0x35,0x08,0x80,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8d,0x09,0x00,0x00,
+0x00,0x00,0x00,0x00,0x31,0x29,0x00,0x01,0x00,0x00,0x00,0x00,0x24,0x01,0x00,0x01,
+0x15,0x21,0xff,0xf2,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4b,0xe8,
+0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0x3c,0x02,0xb0,0x03,0x8c,0x43,0x00,0x00,
+0x00,0x00,0x00,0x00,0x34,0x63,0x00,0x40,0x00,0x00,0x00,0x00,0xac,0x43,0x00,0x00,
+0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0x14,0x3c,0x0b,0xb0,0x03,
+0xad,0x6a,0x00,0x20,0x3c,0x02,0x80,0x01,0x24,0x42,0x00,0x00,0x3c,0x03,0x80,0x01,
+0x24,0x63,0x03,0x1c,0x3c,0x04,0xb0,0x00,0x8c,0x85,0x00,0x00,0x00,0x00,0x00,0x00,
+0xac,0x45,0x00,0x00,0x24,0x42,0x00,0x04,0x24,0x84,0x00,0x04,0x00,0x43,0x08,0x2a,
+0x14,0x20,0xff,0xf9,0x00,0x00,0x00,0x00,0x0c,0x00,0x13,0x18,0x00,0x00,0x00,0x00,
+0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0x60,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,
+0x3c,0x02,0x80,0x01,0x24,0x42,0x03,0x20,0x3c,0x03,0x80,0x01,0x24,0x63,0x3f,0x14,
+0xac,0x40,0x00,0x00,0xac,0x40,0x00,0x04,0xac,0x40,0x00,0x08,0xac,0x40,0x00,0x0c,
+0x24,0x42,0x00,0x10,0x00,0x43,0x08,0x2a,0x14,0x20,0xff,0xf9,0x00,0x00,0x00,0x00,
+0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0xa0,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,
+0x3c,0x1c,0x80,0x01,0x27,0x9c,0x7f,0xf0,0x27,0x9d,0x8b,0xd0,0x00,0x00,0x00,0x00,
+0x27,0x9d,0x8f,0xb8,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0xc4,0x3c,0x0b,0xb0,0x03,
+0xad,0x6a,0x00,0x20,0x40,0x80,0x68,0x00,0x40,0x08,0x60,0x00,0x00,0x00,0x00,0x00,
+0x35,0x08,0xff,0x01,0x40,0x88,0x60,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x15,0x65,
+0x00,0x00,0x00,0x00,0x24,0x84,0xf8,0x00,0x30,0x87,0x00,0x03,0x00,0x04,0x30,0x40,
+0x00,0xc7,0x20,0x23,0x3c,0x02,0xb0,0x0a,0x27,0xbd,0xff,0xe0,0x24,0x03,0xff,0xff,
+0x00,0x82,0x20,0x21,0xaf,0xb1,0x00,0x14,0xac,0x83,0x10,0x00,0xaf,0xbf,0x00,0x18,
+0xaf,0xb0,0x00,0x10,0x00,0xa0,0x88,0x21,0x24,0x03,0x00,0x01,0x8c,0x82,0x10,0x00,
+0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x00,0xc7,0x10,0x23,0x3c,0x03,0xb0,0x0a,
+0x00,0x43,0x10,0x21,0x8c,0x50,0x00,0x00,0x0c,0x00,0x13,0x95,0x02,0x20,0x20,0x21,
+0x02,0x11,0x80,0x24,0x00,0x50,0x80,0x06,0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x18,
+0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x27,0xbd,0xff,0xd8,
+0xaf,0xb2,0x00,0x18,0x00,0xa0,0x90,0x21,0x24,0x05,0xff,0xff,0xaf,0xb3,0x00,0x1c,
+0xaf,0xbf,0x00,0x20,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x00,0xc0,0x98,0x21,
+0x12,0x45,0x00,0x23,0x24,0x84,0xf8,0x00,0x30,0x83,0x00,0x03,0x00,0x04,0x10,0x40,
+0x00,0x40,0x88,0x21,0x00,0x60,0x20,0x21,0x00,0x43,0x10,0x23,0x3c,0x03,0xb0,0x0a,
+0x00,0x43,0x10,0x21,0xac,0x45,0x10,0x00,0x00,0x40,0x18,0x21,0x24,0x05,0x00,0x01,
+0x8c,0x62,0x10,0x00,0x00,0x00,0x00,0x00,0x14,0x45,0xff,0xfd,0x3c,0x02,0xb0,0x0a,
+0x02,0x24,0x88,0x23,0x02,0x22,0x88,0x21,0x8e,0x30,0x00,0x00,0x0c,0x00,0x13,0x95,
+0x02,0x40,0x20,0x21,0x00,0x12,0x18,0x27,0x02,0x03,0x80,0x24,0x00,0x53,0x10,0x04,
+0x02,0x02,0x80,0x25,0xae,0x30,0x00,0x00,0x24,0x03,0x00,0x01,0x8e,0x22,0x10,0x00,
+0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x20,
+0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,
+0x30,0x82,0x00,0x03,0x00,0x04,0x18,0x40,0x00,0x62,0x18,0x23,0x3c,0x04,0xb0,0x0a,
+0x00,0x64,0x18,0x21,0xac,0x66,0x00,0x00,0x24,0x04,0x00,0x01,0x8c,0x62,0x10,0x00,
+0x00,0x00,0x00,0x00,0x14,0x44,0xff,0xfd,0x00,0x00,0x00,0x00,0x08,0x00,0x13,0x83,
+0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x21,0x00,0x64,0x10,0x06,0x30,0x42,0x00,0x01,
+0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x24,0x63,0x00,0x01,0x2c,0x62,0x00,0x20,
+0x14,0x40,0xff,0xf9,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21,
+0x27,0xbd,0xff,0xe0,0x3c,0x03,0xb0,0x05,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,
+0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x1c,0x00,0x80,0x90,0x21,0x00,0xa0,0x80,0x21,
+0x00,0xc0,0x88,0x21,0x34,0x63,0x02,0x2e,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
+0x30,0x42,0x00,0x01,0x14,0x40,0xff,0xfc,0x24,0x04,0x08,0x24,0x3c,0x05,0x00,0xc0,
+0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x03,0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0xc0,
+0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x03,0x3c,0x02,0xc0,0x00,0x00,0x10,0x1c,0x00,
+0x34,0x42,0x04,0x00,0x3c,0x04,0xb0,0x05,0x3c,0x05,0xb0,0x05,0x24,0x63,0x16,0x09,
+0x02,0x22,0x10,0x21,0x34,0x84,0x04,0x20,0x34,0xa5,0x04,0x24,0x3c,0x06,0xb0,0x05,
+0xac,0x83,0x00,0x00,0x24,0x07,0x00,0x01,0xac,0xa2,0x00,0x00,0x34,0xc6,0x02,0x28,
+0x24,0x02,0x00,0x20,0xae,0x47,0x00,0x3c,0x24,0x04,0x08,0x24,0xa0,0xc2,0x00,0x00,
+0x3c,0x05,0x00,0xc0,0xa2,0x47,0x00,0x11,0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x01,
+0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0xc0,0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x01,
+0x8f,0xbf,0x00,0x1c,0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,
+0x27,0xbd,0x00,0x20,0x24,0x02,0x00,0x06,0xac,0x82,0x00,0x0c,0xa0,0x80,0x00,0x50,
+0xac,0x80,0x00,0x00,0xac,0x80,0x00,0x04,0xac,0x80,0x00,0x08,0xac,0x80,0x00,0x14,
+0xac,0x80,0x00,0x18,0xac,0x80,0x00,0x1c,0xa4,0x80,0x00,0x20,0xac,0x80,0x00,0x24,
+0xac,0x80,0x00,0x28,0xac,0x80,0x00,0x2c,0xa0,0x80,0x00,0x30,0xa0,0x80,0x00,0x31,
+0xac,0x80,0x00,0x34,0xac,0x80,0x00,0x38,0xa0,0x80,0x00,0x3c,0xac,0x82,0x00,0x10,
+0xa0,0x80,0x00,0x44,0xac,0x80,0x00,0x48,0x03,0xe0,0x00,0x08,0xac,0x80,0x00,0x4c,
+0x3c,0x04,0xb0,0x06,0x34,0x84,0x80,0x00,0x8c,0x83,0x00,0x00,0x3c,0x02,0x12,0x00,
+0x3c,0x05,0xb0,0x03,0x00,0x62,0x18,0x25,0x34,0xa5,0x00,0x8b,0x24,0x02,0xff,0x80,
+0xac,0x83,0x00,0x00,0x03,0xe0,0x00,0x08,0xa0,0xa2,0x00,0x00,0x3c,0x04,0xb0,0x03,
+0x34,0x84,0x00,0x0b,0x24,0x02,0x00,0x22,0x3c,0x05,0xb0,0x01,0x3c,0x06,0x45,0x67,
+0x3c,0x0a,0xb0,0x09,0xa0,0x82,0x00,0x00,0x34,0xa5,0x00,0x04,0x34,0xc6,0x89,0xaa,
+0x35,0x4a,0x00,0x04,0x24,0x02,0x01,0x23,0x3c,0x0b,0xb0,0x09,0x3c,0x07,0x01,0x23,
+0x3c,0x0c,0xb0,0x09,0x3c,0x01,0xb0,0x01,0xac,0x20,0x00,0x00,0x27,0xbd,0xff,0xe0,
+0xac,0xa0,0x00,0x00,0x35,0x6b,0x00,0x08,0x3c,0x01,0xb0,0x09,0xac,0x26,0x00,0x00,
+0x34,0xe7,0x45,0x66,0xa5,0x42,0x00,0x00,0x35,0x8c,0x00,0x0c,0x24,0x02,0xcd,0xef,
+0x3c,0x0d,0xb0,0x09,0x3c,0x08,0xcd,0xef,0x3c,0x0e,0xb0,0x09,0xad,0x67,0x00,0x00,
+0xaf,0xb7,0x00,0x1c,0xa5,0x82,0x00,0x00,0xaf,0xb6,0x00,0x18,0xaf,0xb5,0x00,0x14,
+0xaf,0xb4,0x00,0x10,0xaf,0xb3,0x00,0x0c,0xaf,0xb2,0x00,0x08,0xaf,0xb1,0x00,0x04,
+0xaf,0xb0,0x00,0x00,0x35,0xad,0x00,0x10,0x35,0x08,0x01,0x22,0x35,0xce,0x00,0x14,
+0x24,0x02,0x89,0xab,0x3c,0x0f,0xb0,0x09,0x3c,0x09,0x89,0xab,0x3c,0x10,0xb0,0x09,
+0x3c,0x11,0xb0,0x09,0x3c,0x12,0xb0,0x09,0x3c,0x13,0xb0,0x09,0x3c,0x14,0xb0,0x09,
+0x3c,0x15,0xb0,0x09,0x3c,0x16,0xb0,0x09,0x3c,0x17,0xb0,0x09,0xad,0xa8,0x00,0x00,
+0x24,0x03,0xff,0xff,0xa5,0xc2,0x00,0x00,0x35,0xef,0x00,0x18,0x35,0x29,0xcd,0xee,
+0x36,0x10,0x00,0x1c,0x36,0x31,0x00,0x20,0x36,0x52,0x00,0x24,0x36,0x73,0x00,0x28,
+0x36,0x94,0x00,0x2c,0x36,0xb5,0x00,0x30,0x36,0xd6,0x00,0x34,0x36,0xf7,0x00,0x38,
+0x24,0x02,0x45,0x67,0xad,0xe9,0x00,0x00,0xa6,0x02,0x00,0x00,0xae,0x23,0x00,0x00,
+0x8f,0xb0,0x00,0x00,0xa6,0x43,0x00,0x00,0x8f,0xb1,0x00,0x04,0xae,0x63,0x00,0x00,
+0x8f,0xb2,0x00,0x08,0xa6,0x83,0x00,0x00,0x8f,0xb3,0x00,0x0c,0xae,0xa3,0x00,0x00,
+0x8f,0xb4,0x00,0x10,0xa6,0xc3,0x00,0x00,0x8f,0xb5,0x00,0x14,0xae,0xe3,0x00,0x00,
+0x7b,0xb6,0x00,0xfc,0x3c,0x18,0xb0,0x09,0x37,0x18,0x00,0x3c,0xa7,0x03,0x00,0x00,
+0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,
+0x34,0x63,0x00,0x20,0x24,0x42,0x51,0x38,0xac,0x62,0x00,0x00,0x8c,0x83,0x00,0x34,
+0x34,0x02,0xff,0xff,0x00,0x43,0x10,0x2a,0x14,0x40,0x01,0x0b,0x00,0x80,0x30,0x21,
+0x8c,0x84,0x00,0x08,0x24,0x02,0x00,0x03,0x10,0x82,0x00,0xfe,0x00,0x00,0x00,0x00,
+0x8c,0xc2,0x00,0x2c,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x47,0x24,0x02,0x00,0x06,
+0x3c,0x03,0xb0,0x05,0x34,0x63,0x04,0x50,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
+0x30,0x42,0x00,0xff,0x14,0x40,0x00,0xe4,0xac,0xc2,0x00,0x2c,0x24,0x02,0x00,0x01,
+0x10,0x82,0x00,0xe3,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0x82,0x00,0xd1,
+0x00,0x00,0x00,0x00,0x8c,0xc7,0x00,0x04,0x24,0x02,0x00,0x02,0x10,0xe2,0x00,0xc7,
+0x00,0x00,0x00,0x00,0x8c,0xc2,0x00,0x14,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x09,
+0x24,0x02,0x00,0x01,0x3c,0x03,0xb0,0x09,0x34,0x63,0x01,0x60,0x90,0x62,0x00,0x00,
+0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0x10,0x40,0x00,0x05,0xac,0xc2,0x00,0x14,
+0x24,0x02,0x00,0x01,0xac,0xc2,0x00,0x00,0x03,0xe0,0x00,0x08,0xac,0xc0,0x00,0x14,
+0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xd0,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,
+0x04,0x61,0x00,0x16,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2e,0x90,0x62,0x00,0x00,
+0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x10,0x3c,0x02,0xb0,0x05,
+0x34,0x42,0x02,0x42,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x0b,
+0x00,0x00,0x00,0x00,0x80,0xc2,0x00,0x50,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x07,
+0x00,0x00,0x00,0x00,0x14,0x80,0x00,0x05,0x24,0x02,0x00,0x0e,0x24,0x03,0x00,0x01,
+0xac,0xc2,0x00,0x00,0x03,0xe0,0x00,0x08,0xa0,0xc3,0x00,0x50,0x80,0xc2,0x00,0x31,
+0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0a,0x3c,0x02,0xb0,0x06,0x34,0x42,0x80,0x18,
+0x8c,0x43,0x00,0x00,0x3c,0x04,0xf0,0x00,0x3c,0x02,0x80,0x00,0x00,0x64,0x18,0x24,
+0x10,0x62,0x00,0x03,0x24,0x02,0x00,0x09,0x03,0xe0,0x00,0x08,0xac,0xc2,0x00,0x00,
+0x8c,0xc2,0x00,0x40,0x00,0x00,0x00,0x00,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,
+0x10,0x60,0x00,0x09,0x3c,0x03,0xb0,0x03,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c,
+0x8c,0x43,0x00,0x00,0x3c,0x04,0x00,0x02,0x00,0x64,0x18,0x24,0x14,0x60,0xff,0xf2,
+0x24,0x02,0x00,0x10,0x3c,0x03,0xb0,0x03,0x34,0x63,0x02,0x01,0x90,0x62,0x00,0x00,
+0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x80,0x10,0x40,0x00,0x0e,0x00,0x00,0x00,0x00,
+0x8c,0xc3,0x00,0x0c,0x00,0x00,0x00,0x00,0xac,0xc3,0x00,0x10,0x3c,0x02,0xb0,0x03,
+0x90,0x42,0x02,0x01,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x0f,0xac,0xc2,0x00,0x0c,
+0x90,0xc3,0x00,0x0f,0x24,0x02,0x00,0x0d,0x3c,0x01,0xb0,0x03,0x08,0x00,0x14,0xa6,
+0xa0,0x23,0x02,0x01,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x80,0x90,0x44,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x04,0x1e,0x00,0x00,0x03,0x1e,0x03,0x10,0x60,0x00,0x15,
+0xa0,0xc4,0x00,0x44,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x0b,0x24,0x02,0x00,0x02,
+0x10,0x62,0x00,0x03,0x24,0x03,0x00,0x0d,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
+0x8c,0xc2,0x00,0x0c,0xac,0xc3,0x00,0x00,0x24,0x03,0x00,0x04,0xac,0xc2,0x00,0x10,
+0x03,0xe0,0x00,0x08,0xac,0xc3,0x00,0x0c,0x24,0x02,0x00,0x0d,0xac,0xc2,0x00,0x00,
+0x24,0x03,0x00,0x04,0x24,0x02,0x00,0x06,0xac,0xc3,0x00,0x10,0x03,0xe0,0x00,0x08,
+0xac,0xc2,0x00,0x0c,0x8c,0xc3,0x00,0x38,0x00,0x00,0x00,0x00,0x2c,0x62,0x00,0x06,
+0x10,0x40,0x00,0x2e,0x00,0x03,0x10,0x80,0x3c,0x03,0x80,0x01,0x24,0x63,0x02,0x00,
+0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08,
+0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xe2,0x00,0x06,0x24,0x02,0x00,0x03,
+0x8c,0xa2,0x02,0xbc,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x06,0x3c,0x03,0xb0,0x06,
+0x24,0x02,0x00,0x02,0xac,0xc2,0x00,0x00,0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,
+0xac,0xc2,0x00,0x38,0x34,0x63,0x80,0x24,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
+0x30,0x42,0x00,0xff,0x10,0x40,0x00,0x05,0xac,0xc2,0x00,0x18,0x24,0x02,0x00,0x02,
+0xac,0xc2,0x00,0x00,0x08,0x00,0x14,0xfa,0xac,0xc0,0x00,0x18,0x08,0x00,0x14,0xfa,
+0xac,0xc0,0x00,0x00,0x24,0x02,0x00,0x02,0x24,0x03,0x00,0x0b,0xac,0xc2,0x00,0x38,
+0x03,0xe0,0x00,0x08,0xac,0xc3,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xe2,0x00,0x05,
+0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x0c,0xac,0xc2,0x00,0x00,0x08,0x00,0x14,0xfb,
+0x24,0x02,0x00,0x04,0x08,0x00,0x15,0x12,0x24,0x02,0x00,0x03,0xac,0xc0,0x00,0x38,
+0x03,0xe0,0x00,0x08,0xac,0xc0,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xe2,0x00,0x05,
+0x24,0x02,0x00,0x03,0x80,0xc2,0x00,0x30,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x08,
+0x24,0x02,0x00,0x04,0xac,0xc2,0x00,0x00,0x93,0x82,0x86,0x3c,0x00,0x00,0x00,0x00,
+0x14,0x40,0xff,0xd6,0x24,0x02,0x00,0x05,0x03,0xe0,0x00,0x08,0xac,0xc0,0x00,0x38,
+0x08,0x00,0x15,0x22,0xac,0xc0,0x00,0x00,0x3c,0x02,0xb0,0x06,0x34,0x42,0x80,0x18,
+0x8c,0x43,0x00,0x00,0x3c,0x04,0xf0,0x00,0x3c,0x02,0x80,0x00,0x00,0x64,0x18,0x24,
+0x10,0x62,0x00,0x03,0x24,0x02,0x00,0x09,0x08,0x00,0x15,0x26,0xac,0xc2,0x00,0x00,
+0x24,0x02,0x00,0x05,0x08,0x00,0x15,0x18,0xac,0xc2,0x00,0x38,0x80,0xc2,0x00,0x30,
+0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x37,0x24,0x02,0x00,0x04,0x08,0x00,0x14,0xa6,
+0x00,0x00,0x00,0x00,0x84,0xc2,0x00,0x20,0x00,0x00,0x00,0x00,0x10,0x40,0xff,0x66,
+0x24,0x02,0x00,0x06,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e,0x90,0x43,0x00,0x00,
+0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff,0x00,0x60,0x10,0x21,
+0x14,0x40,0xff,0x24,0xa4,0xc3,0x00,0x20,0x08,0x00,0x14,0xa6,0x24,0x02,0x00,0x06,
+0x8c,0xc2,0x00,0x1c,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x57,0x24,0x02,0x00,0x05,
+0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2c,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
+0x30,0x42,0x00,0xff,0x10,0x40,0xff,0x14,0xac,0xc2,0x00,0x1c,0x08,0x00,0x14,0xa6,
+0x24,0x02,0x00,0x05,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x02,0x17,0x42,0x30,0x42,0x00,0x01,0x14,0x40,0xff,0x47,0x24,0x02,0x00,0x06,
+0x08,0x00,0x14,0x5c,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x0a,0x03,0xe0,0x00,0x08,
+0xac,0x82,0x00,0x00,0x27,0xbd,0xff,0xd8,0xaf,0xb0,0x00,0x10,0x27,0x90,0x86,0x48,
+0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18,0x0c,0x00,0x2b,0xe8,
+0xaf,0xb1,0x00,0x14,0xaf,0x90,0x8f,0xd0,0x48,0x02,0x00,0x00,0x0c,0x00,0x13,0xec,
+0x00,0x00,0x00,0x00,0x0c,0x00,0x18,0x4e,0x02,0x00,0x20,0x21,0x0c,0x00,0x00,0x34,
+0x00,0x00,0x00,0x00,0x0c,0x00,0x13,0xf7,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x68,
+0x0c,0x00,0x27,0xc1,0x00,0x00,0x00,0x00,0x93,0x84,0x80,0x10,0x0c,0x00,0x21,0x9a,
+0x00,0x00,0x00,0x00,0x27,0x84,0x89,0x08,0x0c,0x00,0x06,0xe1,0x00,0x00,0x00,0x00,
+0x0c,0x00,0x01,0x3b,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x10,0x0c,0x00,0x13,0xd5,
+0x00,0x00,0x00,0x00,0x27,0x82,0x89,0x3c,0xaf,0x82,0x84,0x50,0x0c,0x00,0x00,0x61,
+0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x01,0x08,0x3c,0x04,0xb0,0x09,
+0x3c,0x05,0xb0,0x09,0x8c,0x66,0x00,0x00,0x34,0x84,0x01,0x68,0x24,0x02,0xc8,0x80,
+0x34,0xa5,0x01,0x40,0x24,0x03,0x00,0x0a,0xa4,0x82,0x00,0x00,0xa4,0xa3,0x00,0x00,
+0x3c,0x04,0xb0,0x03,0x8c,0x82,0x00,0x00,0x8f,0x87,0x84,0x10,0xaf,0x86,0x84,0x08,
+0x34,0x42,0x00,0x20,0xac,0x82,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x58,
+0x8c,0x43,0x00,0x00,0x2c,0xe4,0x00,0x11,0x34,0x63,0x01,0x00,0xac,0x43,0x00,0x00,
+0x10,0x80,0xff,0xfa,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x00,0x07,0x10,0x80,
+0x24,0x63,0x02,0x18,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x68,0x0c,0x00,0x26,0xe5,
+0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x10,0x27,0x85,0x86,0x48,0x0c,0x00,0x14,0x4e,
+0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x09,0x34,0x42,0x00,0x07,0x3c,0x03,0xb0,0x06,
+0x90,0x44,0x00,0x00,0x34,0x63,0x80,0x18,0x8c,0x65,0x00,0x00,0x3c,0x02,0xb0,0x03,
+0x34,0x42,0x00,0xec,0x3c,0x03,0xb0,0x03,0x30,0x86,0x00,0xff,0xa0,0x46,0x00,0x00,
+0x00,0x05,0x2f,0x02,0x34,0x63,0x00,0xed,0x24,0x02,0x00,0x01,0x10,0xc2,0x00,0x2c,
+0xa0,0x65,0x00,0x00,0xa3,0x80,0x81,0x58,0x93,0x83,0x81,0xf1,0x24,0x02,0x00,0x01,
+0x10,0x62,0x00,0x08,0x00,0x00,0x00,0x00,0x8f,0x87,0x84,0x10,0x8f,0x82,0x84,0x44,
+0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xaf,0x82,0x84,0x44,0x08,0x00,0x15,0x9b,
+0x3c,0x02,0xb0,0x03,0x8f,0x87,0x84,0x10,0x00,0x00,0x00,0x00,0x24,0xe2,0xff,0xfc,
+0x2c,0x42,0x00,0x03,0x14,0x40,0x00,0x0a,0x3c,0x03,0xb0,0x06,0x93,0x82,0x86,0x3c,
+0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x07,0x34,0x63,0x80,0x18,0x27,0x84,0x84,0x68,
+0x0c,0x00,0x27,0x75,0x00,0x00,0x00,0x00,0x8f,0x87,0x84,0x10,0x3c,0x03,0xb0,0x06,
+0x34,0x63,0x80,0x18,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x02,
+0x10,0x40,0xff,0xe6,0x00,0x00,0x00,0x00,0x8f,0x82,0xbc,0x10,0x8f,0x84,0xbc,0x18,
+0x3c,0x05,0xb0,0x01,0x00,0x45,0x10,0x21,0xac,0x44,0x00,0x00,0x8f,0x83,0xbc,0x10,
+0x8f,0x82,0xbc,0x14,0x00,0x65,0x18,0x21,0x08,0x00,0x15,0xc7,0xac,0x62,0x00,0x04,
+0x14,0xa0,0xff,0xd4,0x3c,0x02,0xb0,0x03,0x93,0x83,0x81,0x58,0x34,0x42,0x00,0xee,
+0x24,0x63,0x00,0x01,0x30,0x64,0x00,0xff,0x2c,0x84,0x00,0xf1,0xa0,0x43,0x00,0x00,
+0xa3,0x83,0x81,0x58,0x14,0x80,0xff,0xcc,0x00,0x00,0x00,0x00,0xaf,0x86,0x84,0x24,
+0xa3,0x86,0x86,0x23,0x08,0x00,0x15,0xc1,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x68,
+0x0c,0x00,0x29,0x6e,0x00,0x00,0x00,0x00,0xa3,0x82,0x84,0x41,0x8f,0x82,0x84,0x44,
+0xaf,0x80,0x84,0x10,0x24,0x42,0x00,0x01,0xaf,0x82,0x84,0x44,0x08,0x00,0x15,0x9a,
+0x00,0x00,0x38,0x21,0x27,0x84,0x86,0x48,0x0c,0x00,0x19,0x19,0x00,0x00,0x00,0x00,
+0x30,0x42,0x00,0xff,0x14,0x40,0x00,0x05,0x3c,0x03,0xb0,0x05,0xaf,0x80,0x84,0x10,
+0xaf,0x80,0x84,0x14,0x08,0x00,0x15,0xc6,0x00,0x00,0x00,0x00,0x34,0x63,0x04,0x50,
+0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x3c,
+0x14,0x40,0x00,0x20,0x24,0x02,0x00,0x01,0x8f,0x84,0x84,0x18,0x00,0x00,0x00,0x00,
+0x10,0x82,0x00,0x20,0x3c,0x03,0xb0,0x09,0x34,0x63,0x01,0x60,0x90,0x62,0x00,0x00,
+0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x24,0x14,0x40,0x00,0x15,
+0x24,0x02,0x00,0x01,0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x07,0x00,0x00,0x00,0x00,
+0x24,0x07,0x00,0x03,0x24,0x02,0x00,0x01,0xaf,0x82,0x84,0x14,0xaf,0x87,0x84,0x10,
+0x08,0x00,0x15,0xc6,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e,
+0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff,
+0x00,0x60,0x10,0x21,0xa7,0x83,0x84,0x30,0x14,0x40,0xff,0xf1,0x00,0x00,0x00,0x00,
+0x24,0x02,0x00,0x01,0xaf,0x82,0x84,0x14,0xaf,0x80,0x84,0x10,0x08,0x00,0x15,0xc6,
+0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2c,0x8c,0x62,0x00,0x00,
+0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x2c,0x14,0x40,0xff,0xf5,
+0x24,0x02,0x00,0x01,0x08,0x00,0x16,0x1a,0x3c,0x03,0xb0,0x09,0x27,0x84,0x86,0x48,
+0x0c,0x00,0x1a,0xde,0x00,0x00,0x00,0x00,0x83,0x82,0x84,0x40,0x00,0x00,0x00,0x00,
+0x14,0x40,0xff,0xec,0x24,0x02,0x00,0x02,0x3c,0x03,0xb0,0x05,0x34,0x63,0x04,0x50,
+0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x3c,
+0x14,0x40,0xff,0xe4,0x24,0x02,0x00,0x02,0x8f,0x84,0x84,0x18,0x24,0x02,0x00,0x01,
+0x10,0x82,0x00,0x12,0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x04,0x00,0x00,0x00,0x00,
+0x24,0x07,0x00,0x04,0x08,0x00,0x16,0x26,0x24,0x02,0x00,0x02,0x3c,0x02,0xb0,0x05,
+0x34,0x42,0x02,0x2e,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,
+0x30,0x63,0x00,0xff,0x00,0x60,0x10,0x21,0xa7,0x83,0x84,0x30,0x14,0x40,0xff,0xf4,
+0x00,0x00,0x00,0x00,0x08,0x00,0x16,0x35,0x24,0x02,0x00,0x02,0x3c,0x03,0xb0,0x05,
+0x34,0x63,0x02,0x2c,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,
+0xaf,0x82,0x84,0x2c,0x14,0x40,0xff,0xf7,0x00,0x00,0x00,0x00,0x08,0x00,0x16,0x56,
+0x24,0x02,0x00,0x02,0x27,0x84,0x89,0x08,0x0c,0x00,0x0b,0x51,0x00,0x00,0x00,0x00,
+0x8f,0x83,0x84,0x14,0xaf,0x82,0x84,0x2c,0x38,0x64,0x00,0x02,0x00,0x04,0x18,0x0a,
+0xaf,0x83,0x84,0x14,0x14,0x40,0xff,0xad,0x24,0x07,0x00,0x05,0x8f,0x82,0x89,0x48,
+0xaf,0x80,0x84,0x10,0x10,0x40,0x00,0x02,0x24,0x04,0x00,0x01,0xaf,0x84,0x84,0x18,
+0x93,0x82,0x89,0x56,0x00,0x00,0x00,0x00,0x10,0x40,0xff,0x43,0x00,0x00,0x00,0x00,
+0x3c,0x02,0xb0,0x05,0x34,0x42,0x00,0x08,0x8c,0x43,0x00,0x00,0x3c,0x04,0x20,0x00,
+0x00,0x64,0x18,0x24,0x10,0x60,0xff,0x3c,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,
+0x34,0x42,0x00,0xa0,0x8c,0x43,0x00,0x00,0x3c,0x04,0x80,0x00,0xaf,0x80,0x89,0x30,
+0x24,0x63,0x00,0x01,0xac,0x43,0x00,0x00,0x3c,0x01,0xb0,0x05,0xac,0x24,0x00,0x08,
+0xaf,0x80,0x89,0x2c,0xaf,0x80,0x89,0x34,0xaf,0x80,0x89,0x38,0xaf,0x80,0x89,0x44,
+0xaf,0x80,0x89,0x3c,0x08,0x00,0x15,0xc6,0x00,0x00,0x00,0x00,0x83,0x82,0x84,0x60,
+0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x02,0x24,0x02,0x00,0x20,0xaf,0x82,0x84,0x2c,
+0x8f,0x85,0x84,0x2c,0x27,0x84,0x89,0x08,0x0c,0x00,0x0d,0x2c,0x00,0x00,0x00,0x00,
+0x00,0x02,0x1e,0x00,0xa3,0x82,0x84,0x40,0xaf,0x80,0x84,0x2c,0x10,0x60,0xff,0x8e,
+0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e,0x90,0x43,0x00,0x00,
+0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff,0x00,0x60,0x10,0x21,
+0xa7,0x83,0x84,0x30,0x10,0x40,0x00,0x04,0x24,0x04,0x00,0x02,0xaf,0x84,0x84,0x18,
+0x08,0x00,0x16,0x36,0x00,0x00,0x00,0x00,0x08,0x00,0x16,0x27,0x24,0x07,0x00,0x06,
+0x27,0x84,0x84,0x10,0x27,0x85,0x89,0x08,0x0c,0x00,0x0d,0xf9,0x00,0x00,0x00,0x00,
+0x8f,0x82,0x84,0x34,0xaf,0x80,0x84,0x3c,0x14,0x40,0x00,0x19,0x00,0x40,0x18,0x21,
+0x8f,0x82,0x84,0x38,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x15,0x24,0x02,0x00,0x02,
+0x8f,0x83,0x84,0x18,0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x0b,0x3c,0x02,0x40,0x00,
+0x8f,0x83,0x84,0x14,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x02,0x24,0x07,0x00,0x03,
+0x24,0x07,0x00,0x06,0xaf,0x87,0x84,0x10,0x24,0x04,0x00,0x03,0xaf,0x84,0x84,0x18,
+0x08,0x00,0x15,0xc6,0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x14,0x3c,0x01,0xb0,0x05,
+0xac,0x22,0x00,0x00,0xaf,0x80,0x84,0x10,0x08,0x00,0x16,0xcf,0x24,0x04,0x00,0x03,
+0x10,0x60,0x00,0x10,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x10,0x27,0x85,0x89,0x08,
+0x0c,0x00,0x0e,0x1d,0x00,0x00,0x00,0x00,0x8f,0x83,0x84,0x14,0x24,0x02,0x00,0x01,
+0xa3,0x80,0x84,0x40,0xaf,0x80,0x84,0x18,0x10,0x62,0x00,0x02,0x24,0x07,0x00,0x03,
+0x24,0x07,0x00,0x04,0xaf,0x87,0x84,0x10,0xaf,0x80,0x84,0x34,0x08,0x00,0x15,0xc6,
+0x00,0x00,0x00,0x00,0x83,0x82,0x84,0x60,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x04,
+0x00,0x00,0x00,0x00,0x27,0x84,0x89,0x08,0x0c,0x00,0x10,0x65,0x00,0x00,0x00,0x00,
+0x8f,0x82,0x84,0x14,0xa3,0x80,0x84,0x40,0xaf,0x80,0x84,0x10,0xaf,0x80,0x84,0x18,
+0x14,0x40,0x00,0x03,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0xaf,0x82,0x84,0x14,
+0xaf,0x80,0x84,0x38,0x08,0x00,0x15,0xc6,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x10,
+0x27,0x85,0x89,0x08,0x0c,0x00,0x0e,0x1d,0x00,0x00,0x00,0x00,0x8f,0x82,0x84,0x14,
+0xa3,0x80,0x84,0x40,0xaf,0x80,0x84,0x10,0xaf,0x80,0x84,0x18,0x14,0x40,0xfe,0xc2,
+0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0xaf,0x82,0x84,0x14,0x08,0x00,0x15,0xc6,
+0x00,0x00,0x00,0x00,0x27,0x84,0x89,0x08,0x0c,0x00,0x10,0x65,0x00,0x00,0x00,0x00,
+0x08,0x00,0x16,0xff,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x68,0x0c,0x00,0x2a,0x96,
+0x00,0x00,0x00,0x00,0x08,0x00,0x15,0xfe,0x00,0x00,0x00,0x00,0x0c,0x00,0x24,0x66,
+0x00,0x00,0x00,0x00,0x0c,0x00,0x27,0x56,0x00,0x00,0x00,0x00,0x0c,0x00,0x18,0x40,
+0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x68,0x0c,0x00,0x27,0x64,0x00,0x00,0x00,0x00,
+0x93,0x83,0xbc,0x08,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x2b,0x3c,0x02,0xb0,0x03,
+0x34,0x42,0x01,0x08,0x8c,0x44,0x00,0x00,0x8f,0x83,0xbc,0x00,0x8f,0x82,0xbc,0x04,
+0x00,0x83,0x18,0x23,0x00,0x43,0x10,0x2b,0x10,0x40,0x00,0x23,0x3c,0x02,0xb0,0x03,
+0x24,0x04,0x05,0xa0,0x34,0x42,0x01,0x18,0x8c,0x42,0x00,0x00,0x0c,0x00,0x06,0xce,
+0x00,0x00,0x00,0x00,0x24,0x04,0x05,0xa4,0x0c,0x00,0x06,0xce,0x00,0x02,0x84,0x02,
+0x30,0x51,0xff,0xff,0x24,0x04,0x05,0xa8,0x00,0x02,0x94,0x02,0x0c,0x00,0x06,0xce,
+0x3a,0x10,0xff,0xff,0x3a,0x31,0xff,0xff,0x30,0x42,0xff,0xff,0x2e,0x10,0x00,0x01,
+0x2e,0x31,0x00,0x01,0x3a,0x52,0xff,0xff,0x02,0x11,0x80,0x25,0x2e,0x52,0x00,0x01,
+0x38,0x42,0xff,0xff,0x02,0x12,0x80,0x25,0x2c,0x42,0x00,0x01,0x02,0x02,0x80,0x25,
+0x16,0x00,0x00,0x02,0x24,0x04,0x00,0x02,0x00,0x00,0x20,0x21,0x0c,0x00,0x05,0x70,
+0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,0x8c,0x43,0x00,0x00,
+0x00,0x00,0x00,0x00,0xaf,0x83,0xbc,0x00,0x0c,0x00,0x01,0xeb,0x00,0x00,0x00,0x00,
+0xaf,0x80,0x84,0x10,0xaf,0x80,0x84,0x44,0x08,0x00,0x15,0x9a,0x00,0x00,0x38,0x21,
+0x27,0x90,0xb3,0xf0,0x24,0x11,0x00,0x12,0x8e,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
+0x90,0x82,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x03,0x00,0x00,0x00,0x00,
+0x0c,0x00,0x20,0xd0,0x00,0x00,0x00,0x00,0x26,0x31,0xff,0xff,0x06,0x21,0xff,0xf6,
+0x26,0x10,0x00,0x04,0xaf,0x80,0x84,0x10,0x08,0x00,0x15,0xc7,0x00,0x00,0x38,0x21,
+0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,0x8c,0x44,0x00,0x00,0x8f,0x82,0x84,0x08,
+0x00,0x04,0x19,0xc2,0x00,0x02,0x11,0xc2,0x10,0x62,0xff,0xf6,0x00,0x00,0x00,0x00,
+0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x02,0x90,0x43,0x00,0x00,0x3c,0x12,0xb0,0x05,
+0xaf,0x84,0x84,0x08,0x30,0x63,0x00,0xff,0x00,0x03,0x11,0x40,0x00,0x43,0x10,0x23,
+0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0x02,0x99,0x00,0x00,0x00,0x88,0x21,
+0x36,0x52,0x02,0x2c,0x27,0x90,0xb3,0xf0,0x8e,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
+0x90,0x83,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x62,0x00,0x03,0x10,0x40,0x00,0x06,
+0x30,0x62,0x00,0x1c,0x14,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0x8f,0x85,0x84,0x08,
+0x0c,0x00,0x1e,0xb2,0x02,0x60,0x30,0x21,0x8e,0x42,0x00,0x00,0x00,0x00,0x00,0x00,
+0x30,0x42,0x00,0xff,0x14,0x40,0xff,0xd7,0x00,0x00,0x00,0x00,0x26,0x31,0x00,0x01,
+0x2a,0x22,0x00,0x13,0x14,0x40,0xff,0xec,0x26,0x10,0x00,0x04,0x08,0x00,0x17,0x5d,
+0x00,0x00,0x00,0x00,0x8f,0x84,0x84,0x1c,0x27,0x85,0x89,0x08,0x0c,0x00,0x17,0xd3,
+0x00,0x00,0x00,0x00,0x8f,0x83,0x84,0x1c,0x24,0x02,0x00,0x04,0x14,0x62,0xfe,0xa2,
+0x00,0x00,0x00,0x00,0x08,0x00,0x16,0x27,0x24,0x07,0x00,0x05,0x27,0x84,0x89,0x08,
+0x0c,0x00,0x24,0x8d,0x00,0x00,0x00,0x00,0x24,0x07,0x00,0x05,0xaf,0x87,0x84,0x10,
+0x08,0x00,0x15,0xc7,0x00,0x00,0x00,0x00,0x8f,0x82,0x89,0x3c,0x00,0x00,0x00,0x00,
+0x10,0x40,0x00,0x0d,0x00,0x00,0x00,0x00,0x8f,0x84,0xb4,0x30,0xaf,0x80,0x89,0x3c,
+0x94,0x85,0x00,0x14,0x0c,0x00,0x1b,0x84,0x00,0x00,0x00,0x00,0x93,0x82,0x8b,0x61,
+0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x02,0x10,0x40,0x00,0x03,0x00,0x00,0x00,0x00,
+0x0c,0x00,0x01,0x59,0x00,0x00,0x20,0x21,0x8f,0x84,0xb4,0x30,0x0c,0x00,0x20,0xd0,
+0x00,0x00,0x00,0x00,0x08,0x00,0x17,0x5d,0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0x90,
+0x27,0xbd,0xff,0xe8,0x00,0x80,0x18,0x21,0x34,0x42,0x00,0x01,0x27,0x84,0x89,0x08,
+0x10,0x62,0x00,0x05,0xaf,0xbf,0x00,0x10,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,
+0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x06,0xe1,0x00,0x00,0x00,0x00,
+0x27,0x84,0x86,0x48,0x0c,0x00,0x18,0x4e,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x10,
+0x0c,0x00,0x13,0xd5,0x00,0x00,0x00,0x00,0x08,0x00,0x17,0xba,0x00,0x00,0x00,0x00,
+0x8f,0x82,0x89,0x48,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x05,0x00,0x00,0x18,0x21,
+0x8f,0x82,0x84,0x18,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x02,0x00,0x00,0x00,0x00,
+0x24,0x03,0x00,0x01,0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21,0x27,0xbd,0xff,0xe0,
+0x3c,0x06,0xb0,0x03,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x34,0xc6,0x00,0x5f,
+0xaf,0xbf,0x00,0x18,0x90,0xc3,0x00,0x00,0x3c,0x07,0xb0,0x03,0x34,0xe7,0x00,0x5d,
+0x34,0x63,0x00,0x01,0x3c,0x09,0xb0,0x03,0x24,0x02,0x00,0x01,0xa0,0xc3,0x00,0x00,
+0x00,0x80,0x80,0x21,0xa0,0xe2,0x00,0x00,0x00,0xa0,0x88,0x21,0x35,0x29,0x00,0x5e,
+0x00,0xe0,0x40,0x21,0x24,0x04,0x00,0x01,0x91,0x22,0x00,0x00,0x91,0x03,0x00,0x00,
+0x30,0x42,0x00,0x01,0x14,0x83,0x00,0x03,0x30,0x42,0x00,0x01,0x14,0x40,0xff,0xfa,
+0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x04,0x12,0x02,0x00,0x2c,0x24,0x05,0x0f,0x00,
+0x24,0x02,0x00,0x06,0x12,0x02,0x00,0x08,0x24,0x05,0x00,0x0f,0x3c,0x02,0xb0,0x03,
+0x34,0x42,0x02,0x00,0xa0,0x50,0x00,0x00,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,
+0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x24,0x04,0x0c,0x04,0x0c,0x00,0x13,0x5b,
+0x24,0x06,0x00,0x0f,0x24,0x04,0x0d,0x04,0x24,0x05,0x00,0x0f,0x0c,0x00,0x13,0x5b,
+0x24,0x06,0x00,0x0f,0x24,0x04,0x08,0x80,0x24,0x05,0x1e,0x00,0x0c,0x00,0x13,0x5b,
+0x24,0x06,0x00,0x0f,0x24,0x04,0x08,0x8c,0x24,0x05,0x0f,0x00,0x0c,0x00,0x13,0x5b,
+0x24,0x06,0x00,0x0f,0x24,0x04,0x08,0x24,0x3c,0x05,0x00,0x30,0x0c,0x00,0x13,0x5b,
+0x24,0x06,0x00,0x02,0x24,0x04,0x08,0x2c,0x3c,0x05,0x00,0x30,0x0c,0x00,0x13,0x5b,
+0x24,0x06,0x00,0x02,0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0x30,0x0c,0x00,0x13,0x5b,
+0x24,0x06,0x00,0x02,0x24,0x04,0x08,0x3c,0x3c,0x05,0x00,0x30,0x0c,0x00,0x13,0x5b,
+0x24,0x06,0x00,0x02,0x08,0x00,0x17,0xf4,0x3c,0x02,0xb0,0x03,0x24,0x04,0x08,0x8c,
+0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x04,0x24,0x04,0x08,0x80,0x24,0x05,0x1e,0x00,
+0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x04,0x24,0x04,0x0c,0x04,0x24,0x05,0x00,0x0f,
+0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x04,0x24,0x04,0x0d,0x04,0x24,0x05,0x00,0x0f,
+0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x04,0x24,0x04,0x08,0x24,0x3c,0x05,0x00,0x30,
+0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x03,0x24,0x04,0x08,0x2c,0x3c,0x05,0x00,0x30,
+0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x03,0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0x30,
+0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x02,0x3c,0x05,0x00,0x30,0x24,0x06,0x00,0x03,
+0x0c,0x00,0x13,0x5b,0x24,0x04,0x08,0x3c,0x02,0x20,0x20,0x21,0x24,0x05,0x00,0x14,
+0x0c,0x00,0x13,0xa0,0x24,0x06,0x01,0x07,0x08,0x00,0x17,0xf4,0x3c,0x02,0xb0,0x03,
+0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x73,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
+0x30,0x42,0x00,0x02,0x14,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0xa3,0x80,0x81,0x59,
+0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0xa3,0x82,0x81,0x59,
+0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,
+0x00,0x80,0x70,0x21,0x34,0x63,0x00,0x20,0x24,0x42,0x61,0x38,0x3c,0x04,0xb0,0x03,
+0xac,0x62,0x00,0x00,0x34,0x84,0x00,0x30,0xad,0xc0,0x02,0xbc,0xad,0xc0,0x02,0xb8,
+0x8c,0x83,0x00,0x00,0x24,0x02,0x00,0xff,0xa5,0xc0,0x00,0x0a,0x00,0x00,0x30,0x21,
+0xa7,0x82,0x8f,0xe0,0x27,0x88,0x8f,0xf0,0xa5,0xc3,0x00,0x08,0x3c,0x07,0xb0,0x08,
+0x30,0xc2,0xff,0xff,0x00,0x02,0x20,0xc0,0x24,0xc3,0x00,0x01,0x00,0x82,0x10,0x21,
+0x00,0x60,0x30,0x21,0x00,0x02,0x10,0x80,0x30,0x63,0xff,0xff,0x00,0x48,0x10,0x21,
+0x00,0x87,0x20,0x21,0x28,0xc5,0x00,0xff,0xac,0x83,0x00,0x00,0x14,0xa0,0xff,0xf4,
+0xa4,0x43,0x00,0x00,0x3c,0x02,0xb0,0x08,0x34,0x03,0xff,0xff,0x25,0xc4,0x00,0x0c,
+0x24,0x0a,0x00,0x02,0x34,0x42,0x07,0xf8,0x3c,0x06,0xb0,0x03,0xa7,0x83,0xb3,0xcc,
+0xac,0x43,0x00,0x00,0xaf,0x84,0xb3,0xf0,0x34,0xc6,0x00,0x64,0xa0,0x8a,0x00,0x18,
+0x94,0xc5,0x00,0x00,0x8f,0x82,0xb3,0xf0,0x25,0xc4,0x00,0x30,0x24,0x08,0x00,0x03,
+0x3c,0x03,0xb0,0x03,0xa0,0x45,0x00,0x21,0x34,0x63,0x00,0x66,0xaf,0x84,0xb3,0xf4,
+0xa0,0x88,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xb3,0xf4,0x25,0xc4,0x00,0x54,
+0x25,0xc7,0x00,0x78,0xa0,0x45,0x00,0x21,0xaf,0x84,0xb3,0xf8,0xa0,0x88,0x00,0x18,
+0x94,0x65,0x00,0x00,0x8f,0x82,0xb3,0xf8,0x25,0xc8,0x00,0x9c,0x24,0x09,0x00,0x01,
+0xa0,0x45,0x00,0x21,0xaf,0x87,0xb3,0xfc,0xa0,0xea,0x00,0x18,0x94,0xc4,0x00,0x00,
+0x8f,0x82,0xb3,0xfc,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x62,0xa0,0x44,0x00,0x21,
+0xaf,0x88,0xb4,0x00,0xa1,0x09,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xb4,0x00,
+0x25,0xc4,0x00,0xc0,0x3c,0x06,0xb0,0x03,0xa0,0x45,0x00,0x21,0xaf,0x84,0xb4,0x04,
+0xa0,0x89,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xb4,0x04,0x25,0xc4,0x00,0xe4,
+0x34,0xc6,0x00,0x60,0xa0,0x45,0x00,0x21,0xaf,0x84,0xb4,0x08,0xa0,0x80,0x00,0x18,
+0x94,0xc5,0x00,0x00,0x8f,0x82,0xb4,0x08,0x25,0xc3,0x01,0x08,0x25,0xc7,0x01,0x2c,
+0xa0,0x45,0x00,0x21,0xaf,0x83,0xb4,0x0c,0xa0,0x60,0x00,0x18,0x94,0xc8,0x00,0x00,
+0x8f,0x82,0xb4,0x0c,0x25,0xc4,0x01,0x50,0x25,0xc5,0x01,0x74,0xa0,0x48,0x00,0x21,
+0x25,0xc6,0x01,0x98,0x25,0xc9,0x01,0xbc,0x25,0xca,0x01,0xe0,0x25,0xcb,0x02,0x04,
+0x25,0xcc,0x02,0x28,0x25,0xcd,0x02,0x4c,0x24,0x02,0x00,0x10,0x3c,0x03,0xb0,0x03,
+0xaf,0x87,0xb4,0x10,0x34,0x63,0x00,0x38,0xa0,0xe0,0x00,0x18,0xaf,0x84,0xb4,0x14,
+0xa0,0x80,0x00,0x18,0xaf,0x85,0xb4,0x18,0xa0,0xa0,0x00,0x18,0xaf,0x86,0xb4,0x1c,
+0xa0,0xc0,0x00,0x18,0xaf,0x89,0xb4,0x20,0xa1,0x20,0x00,0x18,0xaf,0x8a,0xb4,0x24,
+0xa1,0x40,0x00,0x18,0xaf,0x8b,0xb4,0x28,0xa1,0x60,0x00,0x18,0xaf,0x8c,0xb4,0x2c,
+0xa1,0x80,0x00,0x18,0xaf,0x8d,0xb4,0x30,0xa1,0xa2,0x00,0x18,0x94,0x64,0x00,0x00,
+0x8f,0x82,0xb4,0x30,0x25,0xc5,0x02,0x70,0x3c,0x03,0xb0,0x03,0xa0,0x44,0x00,0x21,
+0x24,0x02,0x00,0x11,0xaf,0x85,0xb4,0x34,0x34,0x63,0x00,0x6e,0xa0,0xa2,0x00,0x18,
+0x94,0x64,0x00,0x00,0x8f,0x82,0xb4,0x34,0x25,0xc5,0x02,0x94,0x3c,0x03,0xb0,0x03,
+0xa0,0x44,0x00,0x21,0x24,0x02,0x00,0x12,0xaf,0x85,0xb4,0x38,0x34,0x63,0x00,0x6c,
+0xa0,0xa2,0x00,0x18,0x94,0x64,0x00,0x00,0x8f,0x82,0xb4,0x38,0x24,0x05,0xff,0xff,
+0x24,0x07,0x00,0x01,0xa0,0x44,0x00,0x21,0x24,0x06,0x00,0x12,0x27,0x84,0xb3,0xf0,
+0x8c,0x82,0x00,0x00,0x24,0xc6,0xff,0xff,0xa0,0x40,0x00,0x04,0x8c,0x83,0x00,0x00,
+0xa4,0x45,0x00,0x00,0xa4,0x45,0x00,0x02,0xa0,0x60,0x00,0x0a,0x8c,0x82,0x00,0x00,
+0xa4,0x65,0x00,0x06,0xa4,0x65,0x00,0x08,0xa0,0x40,0x00,0x10,0x8c,0x83,0x00,0x00,
+0xa4,0x45,0x00,0x0c,0xa4,0x45,0x00,0x0e,0xa0,0x60,0x00,0x12,0x8c,0x82,0x00,0x00,
+0x00,0x00,0x00,0x00,0xa0,0x40,0x00,0x16,0x8c,0x83,0x00,0x00,0xa4,0x45,0x00,0x14,
+0xa0,0x67,0x00,0x17,0x8c,0x82,0x00,0x00,0x24,0x84,0x00,0x04,0xa0,0x40,0x00,0x20,
+0x04,0xc1,0xff,0xe7,0xac,0x40,0x00,0x1c,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
+0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x64,0x00,
+0x00,0x05,0x28,0x40,0xac,0x62,0x00,0x00,0x00,0xa6,0x28,0x21,0x2c,0xe2,0x00,0x10,
+0x14,0x80,0x00,0x06,0x00,0x00,0x18,0x21,0x10,0x40,0x00,0x02,0x00,0x00,0x00,0x00,
+0x00,0xe0,0x18,0x21,0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21,0x24,0x02,0x00,0x20,
+0x10,0xe2,0x00,0x06,0x2c,0xe4,0x00,0x10,0x24,0xa2,0x00,0x01,0x10,0x80,0xff,0xf9,
+0x00,0x02,0x11,0x00,0x08,0x00,0x19,0x0d,0x00,0x47,0x18,0x21,0x08,0x00,0x19,0x0d,
+0x24,0xa3,0x00,0x50,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xc8,
+0x34,0x63,0x00,0x20,0x24,0x42,0x64,0x64,0xaf,0xb2,0x00,0x18,0xaf,0xbf,0x00,0x34,
+0xaf,0xbe,0x00,0x30,0xaf,0xb7,0x00,0x2c,0xaf,0xb6,0x00,0x28,0xaf,0xb5,0x00,0x24,
+0xaf,0xb4,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,
+0xac,0x62,0x00,0x00,0x8c,0x86,0x02,0xbc,0x00,0x80,0x90,0x21,0x14,0xc0,0x01,0x66,
+0x00,0xc0,0x38,0x21,0x84,0x82,0x00,0x08,0x3c,0x03,0xb0,0x06,0x94,0x84,0x00,0x08,
+0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x8c,0x45,0x00,0x00,0x8c,0x43,0x00,0x00,
+0x24,0x84,0x00,0x02,0x30,0x84,0x01,0xff,0x30,0xb1,0xff,0xff,0x00,0x03,0x44,0x02,
+0xa6,0x44,0x00,0x08,0x14,0xe0,0x00,0x08,0x3c,0x03,0xb0,0x06,0x34,0x63,0x80,0x24,
+0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x42,0x01,0x00,0xac,0x62,0x00,0x00,
+0x8e,0x46,0x02,0xbc,0x00,0x00,0x00,0x00,0x14,0xc0,0x01,0x4c,0x00,0x11,0x98,0xc0,
+0x00,0x11,0x3a,0x00,0x3c,0x04,0xb0,0x00,0x00,0xe4,0x20,0x21,0x8c,0x83,0x00,0x0c,
+0x00,0x11,0x98,0xc0,0x02,0x71,0x10,0x21,0x00,0x03,0x1b,0x82,0x30,0x63,0x00,0x1f,
+0x00,0x02,0x10,0x80,0x27,0x9e,0x8f,0xf4,0x00,0x5e,0x10,0x21,0x00,0x60,0x30,0x21,
+0xac,0x44,0x00,0x18,0xae,0x43,0x02,0xbc,0x14,0xc0,0x00,0x10,0x3c,0x02,0xb0,0x00,
+0x00,0x08,0x10,0xc0,0x00,0x48,0x10,0x21,0x27,0x84,0x8f,0xf0,0x00,0x02,0x10,0x80,
+0x00,0x44,0x10,0x21,0x94,0x45,0x00,0x00,0x02,0x71,0x18,0x21,0x00,0x03,0x18,0x80,
+0x00,0x64,0x18,0x21,0x24,0x02,0xff,0xff,0xa4,0x62,0x00,0x02,0xa4,0x68,0x00,0x04,
+0xae,0x51,0x02,0xb8,0xa6,0x45,0x00,0x0a,0x3c,0x02,0xb0,0x00,0x00,0xe2,0x40,0x21,
+0x8d,0x16,0x00,0x00,0x8d,0x14,0x00,0x04,0x02,0x71,0x10,0x21,0x00,0x02,0x38,0x80,
+0x00,0x14,0x1a,0x02,0x27,0x84,0x90,0x00,0x30,0x63,0x00,0x1f,0x24,0x02,0x00,0x10,
+0x00,0xe4,0x20,0x21,0xa6,0x43,0x00,0x06,0x8d,0x10,0x00,0x08,0xa0,0x82,0x00,0x06,
+0x86,0x45,0x00,0x06,0x00,0xfe,0x10,0x21,0x24,0x03,0x00,0x13,0x10,0xa3,0x01,0x15,
+0xac,0x48,0x00,0x18,0x3c,0x03,0xb0,0x03,0x34,0x63,0x01,0x00,0xa6,0x40,0x00,0x02,
+0x3c,0x02,0xb0,0x03,0x90,0x64,0x00,0x00,0x34,0x42,0x01,0x08,0x8c,0x45,0x00,0x00,
+0x00,0x10,0x1b,0xc2,0x27,0x82,0x8f,0xf0,0x00,0x04,0x20,0x82,0x00,0xe2,0x10,0x21,
+0x30,0x63,0x00,0x01,0xac,0x45,0x00,0x08,0x10,0x60,0x00,0xec,0x30,0x97,0x00,0x01,
+0x00,0x10,0x16,0x82,0x30,0x46,0x00,0x01,0x00,0x10,0x12,0x02,0x00,0x10,0x19,0xc2,
+0x00,0x10,0x26,0x02,0x00,0x10,0x2e,0x42,0x30,0x47,0x00,0x7f,0x24,0x02,0x00,0x01,
+0x30,0x75,0x00,0x01,0x30,0x84,0x00,0x01,0x10,0xc2,0x00,0xd9,0x30,0xa3,0x00,0x01,
+0x0c,0x00,0x19,0x00,0x00,0x60,0x28,0x21,0x02,0x71,0x18,0x21,0x00,0x03,0x18,0x80,
+0x2c,0x46,0x00,0x54,0x27,0x85,0x90,0x00,0x27,0x84,0x8f,0xf8,0x00,0x06,0x10,0x0a,
+0x00,0x65,0x28,0x21,0x26,0xa6,0x00,0x02,0x00,0x64,0x18,0x21,0xa0,0xa2,0x00,0x02,
+0xa0,0x66,0x00,0x06,0xa0,0x62,0x00,0x07,0xa0,0xa2,0x00,0x01,0x02,0x71,0x20,0x21,
+0x00,0x04,0x20,0x80,0x00,0x9e,0x60,0x21,0x8d,0x85,0x00,0x18,0x00,0x10,0x15,0xc2,
+0x30,0x42,0x00,0x01,0x8c,0xa3,0x00,0x0c,0xa6,0x42,0x00,0x00,0x27,0x82,0x90,0x10,
+0x00,0x82,0x50,0x21,0xa6,0x56,0x00,0x04,0x8d,0x45,0x00,0x00,0x00,0x03,0x19,0x42,
+0x3c,0x02,0xff,0xef,0x34,0x42,0xff,0xff,0x30,0x63,0x00,0x01,0x00,0xa2,0x48,0x24,
+0x00,0x03,0x1d,0x00,0x01,0x23,0x48,0x25,0x00,0x09,0x15,0x02,0x26,0xc5,0x00,0x10,
+0x00,0x14,0x19,0x82,0x00,0x14,0x25,0x82,0x00,0x10,0x34,0x02,0x00,0x10,0x3c,0x42,
+0x00,0x10,0x44,0x82,0x30,0x42,0x00,0x01,0x30,0xb5,0xff,0xff,0x30,0xce,0x00,0x01,
+0x30,0xe5,0x00,0x01,0x30,0x6d,0x00,0x01,0x30,0x8b,0x00,0x03,0x32,0x94,0x00,0x07,
+0x31,0x06,0x00,0x01,0xad,0x49,0x00,0x00,0x10,0x40,0x00,0x0b,0x32,0x07,0x00,0x7f,
+0x8d,0x84,0x00,0x18,0x3c,0x03,0xff,0xf0,0x34,0x63,0xff,0xff,0x8c,0x82,0x00,0x0c,
+0x01,0x23,0x18,0x24,0x00,0x02,0x13,0x82,0x30,0x42,0x00,0x0f,0x00,0x02,0x14,0x00,
+0x00,0x62,0x18,0x25,0xad,0x43,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xc2,0x00,0x90,
+0x00,0x00,0x00,0x00,0x15,0xa0,0x00,0x03,0x00,0x00,0x00,0x00,0x15,0x60,0x00,0x81,
+0x24,0x02,0x00,0x01,0x96,0x42,0x00,0x04,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x04,
+0xa6,0x42,0x00,0x04,0x0c,0x00,0x19,0x00,0x01,0xc0,0x20,0x21,0x02,0x71,0x18,0x21,
+0x00,0x03,0x38,0x80,0x2c,0x45,0x00,0x54,0x27,0x84,0x90,0x00,0x00,0xe4,0x20,0x21,
+0x00,0x05,0x10,0x0a,0xa0,0x82,0x00,0x00,0xa0,0x80,0x00,0x04,0xa0,0x80,0x00,0x05,
+0x96,0x45,0x00,0x04,0x27,0x82,0x8f,0xf0,0x00,0xe2,0x10,0x21,0xa4,0x45,0x00,0x06,
+0x00,0xfe,0x18,0x21,0x92,0x45,0x00,0x01,0x8c,0x66,0x00,0x18,0x27,0x82,0x90,0x10,
+0x00,0xe2,0x10,0x21,0xa0,0x40,0x00,0x00,0xa0,0x85,0x00,0x07,0x94,0xc3,0x00,0x10,
+0x24,0x02,0x00,0x04,0x30,0x63,0x00,0x0f,0x10,0x62,0x00,0x5e,0x24,0xc6,0x00,0x10,
+0x94,0xc3,0x00,0x16,0x27,0x85,0x90,0x08,0x00,0xe5,0x10,0x21,0xa4,0x43,0x00,0x02,
+0x94,0xc2,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x4c,
+0x02,0x71,0x20,0x21,0x94,0xc2,0x00,0x00,0x24,0x03,0x00,0xa4,0x30,0x42,0x00,0xff,
+0x10,0x43,0x00,0x47,0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x00,0x24,0x03,0x00,0x88,
+0x30,0x42,0x00,0x88,0x10,0x43,0x00,0x3c,0x02,0x71,0x18,0x21,0x27,0x84,0x90,0x10,
+0x00,0x03,0x18,0x80,0x00,0x64,0x18,0x21,0x8c,0x62,0x00,0x00,0x3c,0x04,0x00,0x80,
+0x00,0x44,0x10,0x25,0xac,0x62,0x00,0x00,0x02,0x71,0x10,0x21,0x00,0x02,0x10,0x80,
+0x00,0x45,0x10,0x21,0xa0,0x54,0x00,0x00,0x92,0x43,0x02,0xbf,0x3c,0x02,0xb0,0x03,
+0x34,0x42,0x00,0xc3,0xa0,0x43,0x00,0x00,0x8e,0x4b,0x02,0xbc,0x00,0x00,0x00,0x00,
+0x11,0x60,0x00,0x1c,0x32,0xa2,0x00,0xff,0x00,0x15,0x1a,0x02,0x30,0x64,0xff,0xff,
+0x38,0x42,0x00,0x00,0x24,0x65,0x00,0x01,0x00,0x82,0x28,0x0a,0x02,0x20,0x30,0x21,
+0x10,0xa0,0x00,0x12,0x00,0x00,0x38,0x21,0x02,0x71,0x10,0x21,0x00,0x02,0x10,0x80,
+0x27,0x83,0x8f,0xf0,0x00,0x43,0x20,0x21,0x24,0xa9,0xff,0xff,0x3c,0x0a,0xb0,0x08,
+0x24,0x0c,0xff,0xff,0x00,0x06,0x10,0xc0,0x00,0x4a,0x10,0x21,0x8c,0x43,0x00,0x00,
+0x24,0xe8,0x00,0x01,0x10,0xe9,0x00,0x0f,0x30,0x63,0x00,0xff,0x31,0x07,0xff,0xff,
+0x00,0xe5,0x10,0x2b,0x14,0x40,0xff,0xf7,0x00,0x60,0x30,0x21,0x25,0x62,0xff,0xff,
+0xae,0x42,0x02,0xbc,0x7b,0xbe,0x01,0xbc,0x7b,0xb6,0x01,0x7c,0x7b,0xb4,0x01,0x3c,
+0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,
+0x27,0xbd,0x00,0x38,0xa4,0x86,0x00,0x04,0xa4,0x8c,0x00,0x02,0xae,0x51,0x02,0xb8,
+0x08,0x00,0x1a,0x2f,0xa6,0x43,0x00,0x0a,0x94,0xc2,0x00,0x18,0x00,0x00,0x00,0x00,
+0x30,0x42,0x00,0x60,0x10,0x40,0xff,0xc1,0x02,0x71,0x18,0x21,0x02,0x71,0x20,0x21,
+0x27,0x82,0x90,0x10,0x00,0x04,0x20,0x80,0x00,0x82,0x20,0x21,0x8c,0x83,0x00,0x00,
+0x3c,0x02,0xff,0x7f,0x34,0x42,0xff,0xff,0x00,0x62,0x18,0x24,0x08,0x00,0x1a,0x0e,
+0xac,0x83,0x00,0x00,0x27,0x85,0x90,0x08,0x00,0xe5,0x10,0x21,0x08,0x00,0x19,0xf8,
+0xa4,0x40,0x00,0x02,0x11,0x62,0x00,0x07,0x00,0x00,0x00,0x00,0x2d,0x62,0x00,0x02,
+0x14,0x40,0xff,0x80,0x00,0x00,0x00,0x00,0x96,0x42,0x00,0x04,0x08,0x00,0x19,0xd8,
+0x24,0x42,0x00,0x0c,0x96,0x42,0x00,0x04,0x08,0x00,0x19,0xd8,0x24,0x42,0x00,0x08,
+0x16,0xe6,0xff,0x70,0x3c,0x02,0xff,0xfb,0x8d,0x83,0x00,0x18,0x34,0x42,0xff,0xff,
+0x02,0x02,0x10,0x24,0xac,0x62,0x00,0x08,0x08,0x00,0x19,0xd1,0x00,0x00,0x30,0x21,
+0x16,0xe6,0xff,0x27,0x3c,0x02,0xfb,0xff,0x34,0x42,0xff,0xff,0x02,0x02,0x10,0x24,
+0xad,0x02,0x00,0x08,0x08,0x00,0x19,0x90,0x00,0x00,0x30,0x21,0x93,0x88,0xbb,0x04,
+0x00,0x10,0x1e,0x42,0x00,0x10,0x26,0x82,0x27,0x82,0x8f,0xf8,0x2d,0x05,0x00,0x0c,
+0x00,0xe2,0x48,0x21,0x30,0x63,0x00,0x01,0x30,0x86,0x00,0x01,0x14,0xa0,0x00,0x06,
+0x01,0x00,0x38,0x21,0x00,0x03,0x10,0x40,0x00,0x46,0x10,0x21,0x00,0x02,0x11,0x00,
+0x01,0x02,0x10,0x21,0x24,0x47,0x00,0x04,0x02,0x71,0x10,0x21,0x00,0x02,0x10,0x80,
+0x27,0x84,0x90,0x00,0x27,0x83,0x8f,0xf8,0x00,0x44,0x20,0x21,0x00,0x43,0x10,0x21,
+0xa1,0x27,0x00,0x07,0xa0,0x40,0x00,0x06,0xa0,0x80,0x00,0x02,0x08,0x00,0x19,0x9f,
+0xa0,0x80,0x00,0x01,0x24,0x02,0x00,0x01,0xa6,0x42,0x00,0x02,0x0c,0x00,0x01,0xc4,
+0x01,0x00,0x20,0x21,0x08,0x00,0x1a,0x35,0x00,0x00,0x00,0x00,0x27,0x9e,0x8f,0xf4,
+0x08,0x00,0x19,0x52,0x00,0x11,0x3a,0x00,0x94,0x91,0x00,0x0a,0x08,0x00,0x19,0x39,
+0x00,0x00,0x00,0x00,0x30,0xa9,0xff,0xff,0x00,0x09,0x18,0xc0,0x00,0x69,0x18,0x21,
+0x3c,0x06,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x6a,0x54,0x00,0x03,0x18,0x80,
+0x34,0xc6,0x00,0x20,0x27,0x85,0x90,0x00,0xac,0xc2,0x00,0x00,0x00,0x65,0x18,0x21,
+0x80,0x62,0x00,0x07,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x32,0x24,0x88,0x00,0x06,
+0x90,0x82,0x00,0x16,0x00,0x80,0x40,0x21,0x34,0x42,0x00,0x02,0x30,0x43,0x00,0x01,
+0x14,0x60,0x00,0x02,0xa0,0x82,0x00,0x16,0xa0,0x80,0x00,0x17,0x95,0x03,0x00,0x02,
+0x00,0x00,0x00,0x00,0x10,0x69,0x00,0x22,0x3c,0x02,0x34,0x34,0x91,0x02,0x00,0x04,
+0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x06,0x00,0x03,0x20,0xc0,0x24,0x02,0x00,0x01,
+0xa1,0x02,0x00,0x04,0xa5,0x09,0x00,0x02,0x03,0xe0,0x00,0x08,0xa5,0x09,0x00,0x00,
+0x00,0x83,0x20,0x21,0x27,0x87,0x8f,0xf0,0x00,0x04,0x20,0x80,0x00,0x87,0x20,0x21,
+0x94,0x83,0x00,0x04,0x3c,0x02,0xb0,0x08,0x3c,0x06,0xb0,0x03,0x00,0x03,0x28,0xc0,
+0x00,0xa3,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0xa2,0x28,0x21,0x3c,0x02,0x80,0x01,
+0x24,0x42,0x82,0xe4,0x00,0x67,0x18,0x21,0x34,0xc6,0x00,0x20,0xac,0xc2,0x00,0x00,
+0xa4,0x69,0x00,0x00,0xa4,0x89,0x00,0x02,0xac,0xa9,0x00,0x00,0x91,0x02,0x00,0x04,
+0xa5,0x09,0x00,0x02,0x24,0x42,0x00,0x01,0x03,0xe0,0x00,0x08,0xa1,0x02,0x00,0x04,
+0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0xb0,0x34,0x42,0x34,0x34,0x03,0xe0,0x00,0x08,
+0xac,0x62,0x00,0x00,0x90,0x82,0x00,0x16,0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x01,
+0x30,0x43,0x00,0x02,0x14,0x60,0xff,0xd1,0xa0,0x82,0x00,0x16,0x24,0x02,0x00,0x01,
+0x08,0x00,0x1a,0xab,0xa0,0x82,0x00,0x17,0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,
+0x00,0x80,0x38,0x21,0x84,0x84,0x00,0x02,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,
+0x3c,0x0a,0xb0,0x06,0x34,0x63,0x00,0x20,0x24,0x42,0x6b,0x78,0x3c,0x0b,0xb0,0x08,
+0x27,0x89,0x8f,0xf0,0x34,0x0c,0xff,0xff,0x35,0x4a,0x80,0x20,0x10,0x80,0x00,0x30,
+0xac,0x62,0x00,0x00,0x97,0x82,0x8f,0xe0,0x94,0xe6,0x02,0xba,0x00,0x02,0x18,0xc0,
+0x00,0x6b,0x28,0x21,0xac,0xa6,0x00,0x00,0x8c,0xe4,0x02,0xb8,0x00,0x62,0x18,0x21,
+0x00,0x03,0x18,0x80,0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,0x00,0x02,0x10,0x80,
+0x00,0x49,0x10,0x21,0x94,0x48,0x00,0x04,0x00,0x69,0x18,0x21,0xa4,0x66,0x00,0x00,
+0x00,0x08,0x28,0xc0,0x00,0xab,0x10,0x21,0xac,0x4c,0x00,0x00,0x8c,0xe4,0x02,0xb8,
+0x27,0x82,0x8f,0xf4,0x00,0xa8,0x28,0x21,0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,
+0x00,0x03,0x18,0x80,0x00,0x62,0x10,0x21,0x8c,0x46,0x00,0x18,0x27,0x84,0x90,0x00,
+0x00,0x64,0x18,0x21,0x8c,0xc2,0x00,0x00,0x80,0x67,0x00,0x06,0x00,0x05,0x28,0x80,
+0x30,0x42,0xff,0xff,0x00,0x47,0x10,0x21,0x30,0x43,0x00,0xff,0x00,0x03,0x18,0x2b,
+0x00,0x02,0x12,0x02,0x00,0x43,0x10,0x21,0x3c,0x04,0x00,0x04,0x00,0xa9,0x28,0x21,
+0x00,0x44,0x10,0x25,0xa4,0xac,0x00,0x00,0xad,0x42,0x00,0x00,0xa7,0x88,0x8f,0xe0,
+0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,
+0x84,0xe3,0x00,0x06,0x27,0x82,0xb3,0xf0,0x94,0xe5,0x02,0xba,0x00,0x03,0x18,0x80,
+0x00,0x62,0x18,0x21,0x8c,0x64,0x00,0x00,0x0c,0x00,0x1a,0x95,0x00,0x00,0x00,0x00,
+0x08,0x00,0x1b,0x18,0x00,0x00,0x00,0x00,0x94,0x88,0x00,0x00,0x00,0x80,0x58,0x21,
+0x27,0x8a,0x8f,0xf0,0x00,0x08,0x18,0xc0,0x00,0x68,0x18,0x21,0x3c,0x04,0xb0,0x03,
+0x00,0x03,0x18,0x80,0x3c,0x02,0x80,0x00,0x00,0x6a,0x18,0x21,0x34,0x84,0x00,0x20,
+0x24,0x42,0x6c,0x98,0x30,0xa5,0xff,0xff,0xac,0x82,0x00,0x00,0x94,0x67,0x00,0x02,
+0x11,0x05,0x00,0x35,0x24,0x04,0x00,0x01,0x91,0x66,0x00,0x04,0x00,0x00,0x00,0x00,
+0x00,0x86,0x10,0x2a,0x10,0x40,0x00,0x10,0x00,0xc0,0x48,0x21,0x3c,0x0d,0xb0,0x03,
+0x01,0x40,0x60,0x21,0x35,0xad,0x00,0x20,0x10,0xe5,0x00,0x0d,0x24,0x84,0x00,0x01,
+0x00,0x07,0x10,0xc0,0x00,0x47,0x10,0x21,0x00,0x02,0x10,0x80,0x01,0x20,0x30,0x21,
+0x00,0x4a,0x10,0x21,0x00,0x86,0x18,0x2a,0x00,0xe0,0x40,0x21,0x94,0x47,0x00,0x02,
+0x14,0x60,0xff,0xf5,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x10,0x21,
+0x00,0x08,0x20,0xc0,0x00,0x88,0x20,0x21,0x24,0xc2,0xff,0xff,0x00,0x04,0x20,0x80,
+0xa1,0x62,0x00,0x04,0x00,0x8c,0x20,0x21,0x94,0x83,0x00,0x04,0x00,0x07,0x10,0xc0,
+0x00,0x47,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x4c,0x10,0x21,0x00,0x03,0x28,0xc0,
+0x94,0x46,0x00,0x02,0x00,0xa3,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x6c,0x18,0x21,
+0xa4,0x66,0x00,0x00,0xa4,0x86,0x00,0x02,0x95,0x64,0x00,0x02,0x3c,0x03,0xb0,0x08,
+0x3c,0x02,0x80,0x01,0x00,0xa3,0x28,0x21,0x24,0x42,0x82,0xe4,0xad,0xa2,0x00,0x00,
+0x10,0x87,0x00,0x03,0xac,0xa6,0x00,0x00,0x03,0xe0,0x00,0x08,0x24,0x02,0x00,0x01,
+0x08,0x00,0x1b,0x66,0xa5,0x68,0x00,0x02,0x91,0x62,0x00,0x04,0xa5,0x67,0x00,0x00,
+0x24,0x42,0xff,0xff,0x30,0x43,0x00,0xff,0x14,0x60,0x00,0x03,0xa1,0x62,0x00,0x04,
+0x24,0x02,0xff,0xff,0xa5,0x62,0x00,0x02,0x91,0x65,0x00,0x04,0x00,0x00,0x00,0x00,
+0x10,0xa0,0xff,0xf1,0x00,0x00,0x00,0x00,0x95,0x66,0x00,0x00,0x34,0x02,0xff,0xff,
+0x14,0xc2,0xff,0xed,0x3c,0x03,0xb0,0x03,0x95,0x64,0x00,0x02,0x3c,0x02,0xee,0xee,
+0x00,0xa2,0x10,0x25,0x34,0x63,0x00,0xbc,0xac,0x62,0x00,0x00,0x10,0x86,0xff,0xe6,
+0xa1,0x60,0x00,0x04,0x24,0x02,0xff,0xff,0x08,0x00,0x1b,0x66,0xa5,0x62,0x00,0x02,
+0x00,0x05,0x40,0xc0,0x01,0x05,0x30,0x21,0x27,0xbd,0xff,0xd8,0x00,0x06,0x30,0x80,
+0x27,0x82,0x8f,0xf4,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x20,
+0xaf,0xb3,0x00,0x1c,0xaf,0xb0,0x00,0x10,0x00,0xc2,0x10,0x21,0x8c,0x47,0x00,0x18,
+0x00,0xa0,0x90,0x21,0x3c,0x02,0x80,0x00,0x3c,0x05,0xb0,0x03,0x34,0xa5,0x00,0x20,
+0x24,0x42,0x6e,0x10,0xac,0xa2,0x00,0x00,0x27,0x83,0x90,0x00,0x00,0xc3,0x30,0x21,
+0x8c,0xe2,0x00,0x00,0x80,0xc5,0x00,0x06,0x00,0x80,0x88,0x21,0x30,0x42,0xff,0xff,
+0x00,0x45,0x10,0x21,0x30,0x43,0x00,0xff,0x10,0x60,0x00,0x02,0x00,0x02,0x12,0x02,
+0x24,0x42,0x00,0x01,0x30,0x53,0x00,0xff,0x01,0x12,0x10,0x21,0x00,0x02,0x10,0x80,
+0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0x80,0x44,0x00,0x07,0x00,0x00,0x00,0x00,
+0x10,0x80,0x00,0x4b,0x26,0x24,0x00,0x06,0x32,0x50,0xff,0xff,0x02,0x20,0x20,0x21,
+0x0c,0x00,0x1b,0x26,0x02,0x00,0x28,0x21,0x92,0x22,0x00,0x10,0x00,0x00,0x00,0x00,
+0x14,0x40,0x00,0x2e,0x3c,0x03,0xb0,0x08,0x3c,0x09,0x80,0x01,0x27,0x88,0x8f,0xf0,
+0xa6,0x32,0x00,0x0c,0x00,0x10,0x20,0xc0,0x00,0x90,0x20,0x21,0x00,0x04,0x20,0x80,
+0x00,0x88,0x20,0x21,0x94,0x82,0x00,0x04,0x3c,0x03,0xb0,0x08,0x3c,0x07,0xb0,0x03,
+0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x48,0x10,0x21,
+0x00,0xa3,0x28,0x21,0x25,0x26,0x82,0xe4,0x34,0x03,0xff,0xff,0x34,0xe7,0x00,0x20,
+0xac,0xe6,0x00,0x00,0xa4,0x83,0x00,0x02,0xa4,0x43,0x00,0x00,0xac,0xa3,0x00,0x00,
+0x92,0x22,0x00,0x10,0x92,0x23,0x00,0x0a,0xa6,0x32,0x00,0x0e,0x02,0x62,0x10,0x21,
+0x14,0x60,0x00,0x05,0xa2,0x22,0x00,0x10,0x92,0x22,0x00,0x16,0x00,0x00,0x00,0x00,
+0x30,0x42,0x00,0xfe,0xa2,0x22,0x00,0x16,0x92,0x22,0x00,0x04,0x00,0x00,0x00,0x00,
+0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x92,0x22,0x00,0x16,0x00,0x00,0x00,0x00,
+0x30,0x42,0x00,0xfd,0xa2,0x22,0x00,0x16,0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc,
+0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x96,0x22,0x00,0x0e,
+0x27,0x88,0x8f,0xf0,0x00,0x02,0x20,0xc0,0x00,0x82,0x20,0x21,0x00,0x04,0x20,0x80,
+0x00,0x88,0x20,0x21,0x94,0x82,0x00,0x04,0x3c,0x06,0xb0,0x03,0x3c,0x09,0x80,0x01,
+0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0xa3,0x28,0x21,
+0x00,0x48,0x10,0x21,0x34,0xc6,0x00,0x20,0x25,0x23,0x82,0xe4,0xac,0xc3,0x00,0x00,
+0xa4,0x50,0x00,0x00,0xac,0xb0,0x00,0x00,0x08,0x00,0x1b,0xb5,0xa4,0x90,0x00,0x02,
+0x08,0x00,0x1b,0xac,0x32,0x50,0xff,0xff,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,
+0x24,0x42,0x6f,0xd8,0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00,0x90,0x82,0x00,0x04,
+0x97,0xaa,0x00,0x12,0x00,0x80,0x60,0x21,0x30,0xa8,0xff,0xff,0x00,0x4a,0x20,0x23,
+0x34,0x09,0xff,0xff,0x30,0xcf,0xff,0xff,0x30,0xee,0xff,0xff,0x11,0x09,0x00,0x73,
+0xa1,0x84,0x00,0x04,0x00,0x0e,0xc0,0xc0,0x00,0x08,0x10,0xc0,0x00,0x48,0x10,0x21,
+0x03,0x0e,0x20,0x21,0x27,0x8d,0x8f,0xf0,0x00,0x04,0x20,0x80,0x00,0x02,0x10,0x80,
+0x00,0x4d,0x10,0x21,0x00,0x8d,0x20,0x21,0x94,0x86,0x00,0x02,0x94,0x43,0x00,0x04,
+0x3c,0x19,0x80,0x01,0xa4,0x46,0x00,0x02,0x00,0x03,0x28,0xc0,0x00,0xa3,0x18,0x21,
+0x94,0x87,0x00,0x02,0x3c,0x02,0xb0,0x08,0x00,0x03,0x18,0x80,0x00,0xa2,0x28,0x21,
+0x00,0x6d,0x18,0x21,0x27,0x22,0x82,0xe4,0x3c,0x01,0xb0,0x03,0xac,0x22,0x00,0x20,
+0xa4,0x66,0x00,0x00,0x10,0xe9,0x00,0x57,0xac,0xa6,0x00,0x00,0x01,0xe0,0x30,0x21,
+0x11,0x40,0x00,0x1d,0x00,0x00,0x48,0x21,0x01,0x40,0x38,0x21,0x27,0x8b,0x8f,0xf4,
+0x27,0x8a,0x90,0x00,0x00,0x06,0x40,0xc0,0x01,0x06,0x18,0x21,0x00,0x03,0x18,0x80,
+0x00,0x6b,0x10,0x21,0x8c,0x44,0x00,0x18,0x00,0x6a,0x18,0x21,0x80,0x65,0x00,0x06,
+0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0xff,0xff,0x00,0x45,0x10,0x21,
+0x30,0x44,0x00,0xff,0x00,0x02,0x12,0x02,0x01,0x22,0x18,0x21,0x24,0x62,0x00,0x01,
+0x14,0x80,0x00,0x02,0x30,0x49,0x00,0xff,0x30,0x69,0x00,0xff,0x01,0x06,0x10,0x21,
+0x00,0x02,0x10,0x80,0x00,0x4d,0x10,0x21,0x24,0xe7,0xff,0xff,0x94,0x46,0x00,0x02,
+0x14,0xe0,0xff,0xe9,0x00,0x06,0x40,0xc0,0x91,0x82,0x00,0x10,0x00,0x00,0x00,0x00,
+0x14,0x40,0x00,0x20,0x3c,0x06,0xb0,0x03,0xa5,0x8f,0x00,0x0c,0x03,0x0e,0x20,0x21,
+0x00,0x04,0x20,0x80,0x00,0x8d,0x20,0x21,0x94,0x82,0x00,0x04,0x3c,0x03,0xb0,0x08,
+0x3c,0x07,0xb0,0x03,0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21,0x00,0x02,0x10,0x80,
+0x00,0x4d,0x10,0x21,0x00,0xa3,0x28,0x21,0x27,0x26,0x82,0xe4,0x34,0x03,0xff,0xff,
+0x34,0xe7,0x00,0x20,0xac,0xe6,0x00,0x00,0xa4,0x83,0x00,0x02,0xa4,0x43,0x00,0x00,
+0xac,0xa3,0x00,0x00,0x91,0x82,0x00,0x10,0x91,0x83,0x00,0x04,0xa5,0x8e,0x00,0x0e,
+0x01,0x22,0x10,0x21,0x14,0x60,0x00,0x05,0xa1,0x82,0x00,0x10,0x91,0x82,0x00,0x16,
+0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfd,0xa1,0x82,0x00,0x16,0x03,0xe0,0x00,0x08,
+0x00,0x00,0x00,0x00,0x95,0x82,0x00,0x0e,0x3c,0x03,0xb0,0x08,0x00,0x02,0x20,0xc0,
+0x00,0x82,0x20,0x21,0x00,0x04,0x20,0x80,0x00,0x8d,0x20,0x21,0x94,0x82,0x00,0x04,
+0x34,0xc6,0x00,0x20,0x27,0x27,0x82,0xe4,0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21,
+0x00,0x02,0x10,0x80,0x00,0xa3,0x28,0x21,0x00,0x4d,0x10,0x21,0xac,0xc7,0x00,0x00,
+0xa4,0x8f,0x00,0x02,0xa4,0x4f,0x00,0x00,0xac,0xaf,0x00,0x00,0x08,0x00,0x1c,0x44,
+0x03,0x0e,0x20,0x21,0x08,0x00,0x1c,0x1f,0xa5,0x88,0x00,0x02,0x00,0x0e,0xc0,0xc0,
+0x03,0x0e,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x8d,0x8f,0xf0,0x00,0x4d,0x10,0x21,
+0x94,0x43,0x00,0x02,0x30,0x84,0x00,0xff,0x14,0x80,0x00,0x05,0xa5,0x83,0x00,0x00,
+0x24,0x02,0xff,0xff,0x3c,0x19,0x80,0x01,0x08,0x00,0x1c,0x1f,0xa5,0x82,0x00,0x02,
+0x08,0x00,0x1c,0x1f,0x3c,0x19,0x80,0x01,0x3c,0x08,0xb0,0x03,0x3c,0x02,0x80,0x00,
+0x27,0xbd,0xff,0x78,0x35,0x08,0x00,0x20,0x24,0x42,0x72,0x18,0xaf,0xb2,0x00,0x68,
+0xaf,0xb1,0x00,0x64,0xaf,0xb0,0x00,0x60,0xad,0x02,0x00,0x00,0xaf,0xbf,0x00,0x84,
+0xaf,0xbe,0x00,0x80,0xaf,0xb7,0x00,0x7c,0xaf,0xb6,0x00,0x78,0xaf,0xb5,0x00,0x74,
+0xaf,0xb4,0x00,0x70,0xaf,0xb3,0x00,0x6c,0xaf,0xa4,0x00,0x88,0x90,0x83,0x00,0x0a,
+0x27,0x82,0xb3,0xf0,0xaf,0xa6,0x00,0x90,0x00,0x03,0x18,0x80,0x00,0x62,0x18,0x21,
+0x8c,0x63,0x00,0x00,0xaf,0xa7,0x00,0x94,0x27,0x86,0x8f,0xf4,0xaf,0xa3,0x00,0x1c,
+0x94,0x63,0x00,0x14,0x30,0xb1,0xff,0xff,0x24,0x08,0x00,0x01,0x00,0x03,0x20,0xc0,
+0xaf,0xa3,0x00,0x18,0x00,0x83,0x18,0x21,0xaf,0xa4,0x00,0x54,0x00,0x03,0x18,0x80,
+0x27,0x84,0x90,0x00,0x00,0x64,0x20,0x21,0x80,0x82,0x00,0x06,0x00,0x66,0x18,0x21,
+0x8c,0x66,0x00,0x18,0x24,0x42,0x00,0x02,0x00,0x02,0x1f,0xc2,0x8c,0xc4,0x00,0x08,
+0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40,0x00,0x04,0x2f,0xc2,
+0x00,0x04,0x1c,0x82,0x00,0xc2,0x38,0x21,0x00,0x04,0x24,0x42,0x8f,0xa2,0x00,0x1c,
+0x30,0x63,0x00,0x01,0x30,0x84,0x00,0x01,0xaf,0xa5,0x00,0x3c,0xaf,0xa3,0x00,0x34,
+0xaf,0xa4,0x00,0x38,0xaf,0xa0,0x00,0x40,0xaf,0xa0,0x00,0x44,0xaf,0xa0,0x00,0x50,
+0xaf,0xa8,0x00,0x20,0x80,0x42,0x00,0x12,0x8f,0xb2,0x00,0x18,0xaf,0xa2,0x00,0x28,
+0x8c,0xd0,0x00,0x0c,0x14,0xa0,0x01,0xe4,0x00,0x60,0x30,0x21,0x00,0x10,0x10,0x82,
+0x30,0x45,0x00,0x07,0x10,0xa0,0x00,0x11,0xaf,0xa0,0x00,0x30,0x8f,0xa4,0x00,0x98,
+0x27,0x82,0x80,0x1c,0x00,0x04,0x18,0x40,0x00,0x62,0x18,0x21,0x24,0xa2,0x00,0x06,
+0x8f,0xa5,0x00,0x20,0x94,0x64,0x00,0x00,0x00,0x45,0x10,0x04,0x00,0x44,0x00,0x1a,
+0x14,0x80,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0d,0x00,0x00,0x10,0x12,
+0x24,0x42,0x00,0x20,0x30,0x42,0xff,0xfc,0xaf,0xa2,0x00,0x30,0x8f,0xa3,0x00,0x18,
+0x8f,0xa4,0x00,0x28,0x34,0x02,0xff,0xff,0xaf,0xa0,0x00,0x2c,0xaf,0xa2,0x00,0x48,
+0xaf,0xa3,0x00,0x4c,0x00,0x60,0xf0,0x21,0x00,0x00,0xb8,0x21,0x18,0x80,0x00,0x48,
+0xaf,0xa0,0x00,0x24,0x00,0x11,0x89,0x02,0xaf,0xb1,0x00,0x58,0x00,0x80,0xa8,0x21,
+0x00,0x12,0x10,0xc0,0x00,0x52,0x18,0x21,0x00,0x03,0x80,0x80,0x27,0x85,0x8f,0xf0,
+0x02,0x40,0x20,0x21,0x00,0x40,0xa0,0x21,0x02,0x05,0x10,0x21,0x94,0x56,0x00,0x02,
+0x0c,0x00,0x12,0x87,0x00,0x00,0x28,0x21,0x90,0x42,0x00,0x00,0x24,0x03,0x00,0x08,
+0x30,0x42,0x00,0x0c,0x10,0x43,0x01,0x9e,0x24,0x04,0x00,0x01,0x24,0x02,0x00,0x01,
+0x10,0x82,0x01,0x7c,0x3c,0x02,0xb0,0x03,0x8f,0xa6,0x00,0x88,0x34,0x42,0x01,0x04,
+0x84,0xc5,0x00,0x0c,0x02,0x92,0x18,0x21,0x94,0x46,0x00,0x00,0x00,0x05,0x20,0xc0,
+0x00,0x85,0x20,0x21,0x00,0x03,0x18,0x80,0x27,0x82,0x90,0x00,0x27,0x85,0x8f,0xf8,
+0x00,0x65,0x28,0x21,0x00,0x62,0x18,0x21,0x80,0x71,0x00,0x05,0x80,0x73,0x00,0x04,
+0x8f,0xa3,0x00,0x88,0x30,0xd0,0xff,0xff,0x00,0x10,0x3a,0x03,0x32,0x08,0x00,0xff,
+0x27,0x82,0x90,0x10,0x00,0x04,0x20,0x80,0x80,0xa6,0x00,0x06,0x00,0x82,0x20,0x21,
+0xa4,0x67,0x00,0x44,0xa4,0x68,0x00,0x46,0x8c,0x84,0x00,0x00,0x38,0xc6,0x00,0x00,
+0x01,0x00,0x80,0x21,0x00,0x04,0x15,0x02,0x30,0x42,0x00,0x01,0x10,0x40,0x00,0x03,
+0x00,0xe6,0x80,0x0a,0x00,0x04,0x14,0x02,0x30,0x50,0x00,0x0f,0x12,0x20,0x01,0x50,
+0x02,0x40,0x20,0x21,0x02,0x71,0x10,0x21,0x00,0x50,0x10,0x2a,0x14,0x40,0x00,0xed,
+0x02,0x92,0x10,0x21,0x93,0x82,0x8b,0x61,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,
+0x14,0x40,0x00,0xe0,0x02,0x92,0x28,0x21,0x26,0xe2,0x00,0x01,0x30,0x57,0xff,0xff,
+0x02,0x40,0xf0,0x21,0x26,0xb5,0xff,0xff,0x16,0xa0,0xff,0xbd,0x02,0xc0,0x90,0x21,
+0x16,0xe0,0x00,0xd0,0x00,0x00,0x00,0x00,0x8f,0xa3,0x00,0x98,0x00,0x00,0x00,0x00,
+0x2c,0x62,0x00,0x10,0x10,0x40,0x00,0x2e,0x00,0x00,0x00,0x00,0x8f,0xa4,0x00,0x24,
+0x00,0x00,0x00,0x00,0x18,0x80,0x00,0x2a,0x24,0x03,0x00,0x01,0x8f,0xa5,0x00,0x1c,
+0x27,0x84,0x8f,0xf4,0x94,0xb2,0x00,0x14,0xa0,0xa3,0x00,0x12,0x8f,0xa6,0x00,0x3c,
+0x00,0x12,0x10,0xc0,0x00,0x52,0x10,0x21,0x00,0x02,0x80,0x80,0x27,0x82,0x90,0x00,
+0x02,0x02,0x10,0x21,0x80,0x43,0x00,0x06,0x02,0x04,0x20,0x21,0x8c,0x85,0x00,0x18,
+0x24,0x63,0x00,0x02,0x00,0x03,0x17,0xc2,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x43,
+0x00,0x03,0x18,0x40,0x14,0xc0,0x00,0x0e,0x00,0xa3,0x38,0x21,0x27,0x82,0x8f,0xf0,
+0x02,0x02,0x10,0x21,0x94,0x43,0x00,0x06,0x8f,0xa8,0x00,0x1c,0x24,0x02,0x00,0x01,
+0xa5,0x03,0x00,0x1a,0x7b,0xbe,0x04,0x3c,0x7b,0xb6,0x03,0xfc,0x7b,0xb4,0x03,0xbc,
+0x7b,0xb2,0x03,0x7c,0x7b,0xb0,0x03,0x3c,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x88,
+0x8f,0xa4,0x00,0x98,0x8f,0xa5,0x00,0x38,0x8f,0xa6,0x00,0x34,0xaf,0xa0,0x00,0x10,
+0x0c,0x00,0x09,0x06,0xaf,0xa0,0x00,0x14,0x08,0x00,0x1d,0x4b,0x00,0x00,0x00,0x00,
+0x8f,0xa3,0x00,0x44,0x93,0x82,0x81,0x59,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x61,
+0x30,0x69,0x00,0x03,0x8f,0xa4,0x00,0x24,0x8f,0xa5,0x00,0x28,0x00,0x00,0x00,0x00,
+0x00,0x85,0x10,0x2a,0x10,0x40,0x00,0x8f,0x00,0x00,0x00,0x00,0x8f,0xa6,0x00,0x1c,
+0x00,0x00,0x00,0x00,0x90,0xc4,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x83,0x00,0xff,
+0x00,0xa3,0x10,0x2a,0x10,0x40,0x00,0x87,0x00,0x00,0x00,0x00,0x8f,0xa8,0x00,0x24,
+0x00,0x00,0x00,0x00,0x11,0x00,0x00,0x83,0x00,0x65,0x10,0x23,0x00,0xa8,0x18,0x23,
+0x00,0x62,0x10,0x2a,0x14,0x40,0x00,0x7d,0x30,0x63,0x00,0xff,0x00,0x85,0x10,0x23,
+0x30,0x42,0x00,0xff,0xaf,0xa2,0x00,0x50,0x8f,0xa2,0x00,0x50,0x00,0x00,0x00,0x00,
+0x10,0x40,0x00,0x73,0x00,0x00,0xa8,0x21,0x27,0x8c,0x8f,0xf0,0x3c,0x0b,0x80,0xff,
+0x24,0x10,0x00,0x04,0x27,0x91,0x8f,0xf4,0x35,0x6b,0xff,0xff,0x3c,0x0d,0x7f,0x00,
+0x27,0x8e,0x90,0x00,0x01,0x80,0x78,0x21,0x00,0x12,0x30,0xc0,0x00,0xd2,0x10,0x21,
+0x00,0x02,0x10,0x80,0x00,0x4c,0x10,0x21,0x94,0x42,0x00,0x06,0x8f,0xa3,0x00,0x2c,
+0x8f,0xa4,0x00,0x30,0xaf,0xa2,0x00,0x44,0x8f,0xa5,0x00,0x44,0x30,0x49,0x00,0x03,
+0x02,0x09,0x10,0x23,0x30,0x42,0x00,0x03,0x00,0xa2,0x10,0x21,0x8f,0xa8,0x00,0x30,
+0x24,0x42,0x00,0x04,0x30,0x42,0xff,0xff,0x00,0x64,0x38,0x21,0x01,0x02,0x28,0x23,
+0x00,0x62,0x18,0x21,0x00,0x48,0x10,0x2b,0x10,0x40,0x00,0x52,0x00,0x00,0x20,0x21,
+0x30,0xe7,0xff,0xff,0x30,0xa4,0xff,0xff,0xaf,0xa7,0x00,0x2c,0x00,0xd2,0x10,0x21,
+0x00,0x02,0x10,0x80,0x00,0x51,0x18,0x21,0x8c,0x65,0x00,0x18,0x00,0x04,0x25,0x40,
+0x00,0x8d,0x20,0x24,0x8c,0xa8,0x00,0x04,0x00,0x4e,0x18,0x21,0x00,0x4f,0x50,0x21,
+0x01,0x0b,0x40,0x24,0x01,0x04,0x40,0x25,0xac,0xa8,0x00,0x04,0x8f,0xa4,0x00,0x98,
+0x8f,0xa2,0x00,0x50,0x26,0xb5,0x00,0x01,0xa0,0x64,0x00,0x00,0x8c,0xa4,0x00,0x08,
+0x00,0x00,0x00,0x00,0x04,0x81,0x00,0x0c,0x02,0xa2,0x30,0x2a,0x80,0x62,0x00,0x06,
+0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x02,0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,
+0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40,0x00,0xa2,0x38,0x21,0x8f,0xa5,0x00,0x40,
+0x00,0x00,0x00,0x00,0xa4,0xe5,0x00,0x00,0x95,0x52,0x00,0x02,0x14,0xc0,0xff,0xc7,
+0x00,0x12,0x30,0xc0,0x8f,0xa4,0x00,0x24,0x8f,0xa5,0x00,0x50,0x8f,0xa6,0x00,0x1c,
+0x8f,0xa3,0x00,0x2c,0x00,0x85,0x80,0x21,0xa0,0xd0,0x00,0x12,0x00,0x09,0x10,0x23,
+0x30,0x42,0x00,0x03,0x8f,0xa8,0x00,0x88,0x00,0x62,0x10,0x23,0xa4,0xc2,0x00,0x1a,
+0x85,0x03,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
+0x00,0x02,0x10,0x80,0x27,0x83,0x8f,0xf4,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x18,
+0x00,0x00,0x00,0x00,0x8c,0x83,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x10,
+0x14,0x60,0xff,0x74,0x02,0x00,0x10,0x21,0x8f,0xa3,0x00,0x54,0x8f,0xa4,0x00,0x18,
+0x8f,0xa5,0x00,0x24,0x00,0x64,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x08,
+0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x00,0x10,0xa0,0x00,0x03,0x00,0x00,0x30,0x21,
+0x08,0x00,0x1d,0x51,0x02,0x00,0x10,0x21,0x93,0x82,0x80,0x10,0x00,0x00,0x28,0x21,
+0x00,0x00,0x38,0x21,0x0c,0x00,0x21,0xf5,0xaf,0xa2,0x00,0x10,0x08,0x00,0x1d,0x51,
+0x02,0x00,0x10,0x21,0x30,0x63,0xff,0xff,0x08,0x00,0x1d,0xa3,0xaf,0xa3,0x00,0x2c,
+0x8f,0xa8,0x00,0x44,0x08,0x00,0x1d,0xc5,0x31,0x09,0x00,0x03,0x08,0x00,0x1d,0x7e,
+0xaf,0xa3,0x00,0x50,0x8f,0xa6,0x00,0x44,0xaf,0xa0,0x00,0x50,0x08,0x00,0x1d,0xc5,
+0x30,0xc9,0x00,0x03,0x8f,0xa5,0x00,0x48,0x8f,0xa6,0x00,0x4c,0x8f,0xa4,0x00,0x1c,
+0x03,0xc0,0x38,0x21,0x0c,0x00,0x1b,0xf6,0xaf,0xb7,0x00,0x10,0x08,0x00,0x1d,0x2e,
+0x00,0x00,0x00,0x00,0x00,0x05,0x28,0x80,0x27,0x82,0x8f,0xf0,0x00,0xa2,0x28,0x21,
+0x00,0x00,0x20,0x21,0x0c,0x00,0x01,0x4b,0x00,0x00,0x00,0x00,0x08,0x00,0x1d,0x27,
+0x26,0xe2,0x00,0x01,0x00,0x02,0x80,0x80,0x27,0x83,0x90,0x00,0x8f,0xa4,0x00,0x1c,
+0x02,0x03,0x18,0x21,0x26,0x31,0x00,0x01,0x02,0x40,0x28,0x21,0x0c,0x00,0x1f,0x08,
+0xa0,0x71,0x00,0x05,0x14,0x40,0xff,0x13,0x00,0x00,0x00,0x00,0x16,0xe0,0x00,0x4d,
+0x03,0xc0,0x38,0x21,0x8f,0xa4,0x00,0x24,0x8f,0xa5,0x00,0x20,0x24,0x02,0x00,0x01,
+0x24,0x84,0x00,0x01,0xaf,0xb2,0x00,0x48,0xaf,0xb6,0x00,0x4c,0x02,0xc0,0xf0,0x21,
+0x10,0xa2,0x00,0x41,0xaf,0xa4,0x00,0x24,0x27,0x82,0x8f,0xf0,0x02,0x02,0x10,0x21,
+0x94,0x42,0x00,0x06,0x8f,0xa4,0x00,0x30,0xaf,0xa0,0x00,0x20,0xaf,0xa2,0x00,0x44,
+0x30,0x49,0x00,0x03,0x8f,0xa8,0x00,0x44,0x00,0x09,0x10,0x23,0x30,0x42,0x00,0x03,
+0x01,0x02,0x10,0x21,0x24,0x42,0x00,0x04,0x30,0x42,0xff,0xff,0x00,0x44,0x18,0x2b,
+0x10,0x60,0x00,0x2b,0x00,0x00,0x00,0x00,0x8f,0xa5,0x00,0x2c,0x00,0x82,0x10,0x23,
+0x00,0xa4,0x18,0x21,0x30,0x63,0xff,0xff,0x30,0x44,0xff,0xff,0xaf,0xa3,0x00,0x2c,
+0x02,0x92,0x28,0x21,0x00,0x05,0x28,0x80,0x27,0x82,0x8f,0xf4,0x00,0xa2,0x10,0x21,
+0x8c,0x46,0x00,0x18,0x3c,0x03,0x80,0xff,0x3c,0x02,0x7f,0x00,0x8c,0xc8,0x00,0x04,
+0x00,0x04,0x25,0x40,0x34,0x63,0xff,0xff,0x00,0x82,0x20,0x24,0x01,0x03,0x40,0x24,
+0x01,0x04,0x40,0x25,0xac,0xc8,0x00,0x04,0x8f,0xa8,0x00,0x98,0x27,0x82,0x90,0x00,
+0x00,0xa2,0x10,0x21,0xa0,0x48,0x00,0x00,0x8c,0xc4,0x00,0x08,0x00,0x00,0x00,0x00,
+0x00,0x04,0x27,0xc2,0x10,0x80,0xfe,0xdb,0xaf,0xa4,0x00,0x3c,0x80,0x42,0x00,0x06,
+0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x02,0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,
+0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40,0x00,0xc2,0x38,0x21,0x8f,0xa2,0x00,0x40,
+0x00,0x00,0x00,0x00,0xa4,0xe2,0x00,0x00,0x08,0x00,0x1d,0x2a,0x26,0xb5,0xff,0xff,
+0x8f,0xa6,0x00,0x2c,0x00,0x00,0x20,0x21,0x00,0xc2,0x10,0x21,0x30,0x42,0xff,0xff,
+0x08,0x00,0x1e,0x38,0xaf,0xa2,0x00,0x2c,0x8f,0xa6,0x00,0x1c,0x08,0x00,0x1e,0x22,
+0xa4,0xd2,0x00,0x14,0x8f,0xa5,0x00,0x48,0x8f,0xa6,0x00,0x4c,0x8f,0xa4,0x00,0x1c,
+0x0c,0x00,0x1b,0xf6,0xaf,0xb7,0x00,0x10,0x08,0x00,0x1e,0x19,0x00,0x00,0xb8,0x21,
+0x0c,0x00,0x12,0x87,0x00,0x00,0x28,0x21,0x00,0x40,0x18,0x21,0x94,0x42,0x00,0x00,
+0x00,0x00,0x00,0x00,0x34,0x42,0x08,0x00,0xa4,0x62,0x00,0x00,0x08,0x00,0x1d,0x1e,
+0x02,0x71,0x10,0x21,0x02,0x92,0x18,0x21,0x00,0x03,0x80,0x80,0x27,0x82,0x8f,0xf4,
+0x02,0x02,0x10,0x21,0x8c,0x44,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x83,0x00,0x04,
+0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x10,0x10,0x60,0x00,0x09,0x24,0x06,0x00,0x01,
+0x93,0x82,0x8b,0x61,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x10,0x40,0xfe,0xa2,
+0x3c,0x04,0x00,0x80,0x27,0x85,0x8f,0xf0,0x08,0x00,0x1e,0x09,0x02,0x05,0x28,0x21,
+0x27,0x83,0x90,0x08,0x27,0x82,0x90,0x00,0x02,0x03,0x18,0x21,0x02,0x02,0x10,0x21,
+0x90,0x64,0x00,0x00,0x90,0x45,0x00,0x05,0x93,0x83,0x80,0x10,0x00,0x00,0x38,0x21,
+0x0c,0x00,0x21,0xf5,0xaf,0xa3,0x00,0x10,0x08,0x00,0x1e,0x80,0x00,0x00,0x00,0x00,
+0x27,0x82,0x90,0x08,0x02,0x02,0x10,0x21,0x94,0x43,0x00,0x02,0x8f,0xa6,0x00,0x58,
+0x00,0x03,0x19,0x02,0x00,0x66,0x18,0x23,0x30,0x63,0x0f,0xff,0x28,0x62,0x00,0x20,
+0x10,0x40,0x00,0x06,0x28,0x62,0x00,0x40,0x8f,0xa8,0x00,0x90,0x00,0x00,0x00,0x00,
+0x00,0x68,0x10,0x06,0x08,0x00,0x1c,0xf7,0x30,0x44,0x00,0x01,0x10,0x40,0x00,0x04,
+0x00,0x00,0x00,0x00,0x8f,0xa4,0x00,0x94,0x08,0x00,0x1e,0xa1,0x00,0x64,0x10,0x06,
+0x08,0x00,0x1c,0xf7,0x00,0x00,0x20,0x21,0x8f,0xa4,0x00,0x98,0x8f,0xa5,0x00,0x38,
+0xaf,0xa0,0x00,0x10,0x0c,0x00,0x09,0x06,0xaf,0xa8,0x00,0x14,0x30,0x42,0xff,0xff,
+0x08,0x00,0x1c,0xc7,0xaf,0xa2,0x00,0x40,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,
+0x27,0xbd,0xff,0xe0,0x34,0x42,0x00,0x20,0x24,0x63,0x7a,0xc8,0xaf,0xb1,0x00,0x14,
+0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x18,0xac,0x43,0x00,0x00,0x90,0x82,0x00,0x0a,
+0x00,0x80,0x80,0x21,0x14,0x40,0x00,0x45,0x00,0x00,0x88,0x21,0x92,0x02,0x00,0x04,
+0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x3c,0x00,0x00,0x00,0x00,0x12,0x20,0x00,0x18,
+0x00,0x00,0x00,0x00,0x92,0x02,0x00,0x16,0x92,0x05,0x00,0x0a,0x30,0x42,0x00,0xfc,
+0x10,0xa0,0x00,0x03,0xa2,0x02,0x00,0x16,0x34,0x42,0x00,0x01,0xa2,0x02,0x00,0x16,
+0x92,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x83,0x00,0xff,0x10,0x60,0x00,0x05,
+0x00,0x00,0x00,0x00,0x92,0x02,0x00,0x16,0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x02,
+0xa2,0x02,0x00,0x16,0x10,0x60,0x00,0x0a,0x00,0x00,0x00,0x00,0x14,0xa0,0x00,0x08,
+0x00,0x00,0x00,0x00,0x96,0x02,0x00,0x00,0xa2,0x00,0x00,0x17,0xa6,0x02,0x00,0x14,
+0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,
+0x14,0x80,0x00,0x05,0x24,0x02,0x00,0x01,0x96,0x03,0x00,0x06,0xa2,0x02,0x00,0x17,
+0x08,0x00,0x1e,0xdc,0xa6,0x03,0x00,0x14,0x96,0x04,0x00,0x00,0x96,0x05,0x00,0x06,
+0x27,0x86,0x8f,0xf0,0x00,0x04,0x10,0xc0,0x00,0x05,0x18,0xc0,0x00,0x44,0x10,0x21,
+0x00,0x65,0x18,0x21,0x00,0x02,0x10,0x80,0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21,
+0x00,0x46,0x10,0x21,0x8c,0x65,0x00,0x08,0x8c,0x44,0x00,0x08,0x0c,0x00,0x12,0x78,
+0x00,0x00,0x00,0x00,0x30,0x43,0x00,0xff,0x10,0x60,0x00,0x04,0xa2,0x02,0x00,0x17,
+0x96,0x02,0x00,0x06,0x08,0x00,0x1e,0xdc,0xa6,0x02,0x00,0x14,0x96,0x02,0x00,0x00,
+0x08,0x00,0x1e,0xdc,0xa6,0x02,0x00,0x14,0x96,0x05,0x00,0x00,0x0c,0x00,0x1f,0x08,
+0x02,0x00,0x20,0x21,0x08,0x00,0x1e,0xc3,0x02,0x22,0x88,0x21,0x94,0x85,0x00,0x06,
+0x0c,0x00,0x1f,0x08,0x00,0x00,0x00,0x00,0x08,0x00,0x1e,0xbf,0x00,0x40,0x88,0x21,
+0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x7c,0x20,
+0x27,0xbd,0xff,0xf0,0xac,0x62,0x00,0x00,0x00,0x00,0x10,0x21,0x03,0xe0,0x00,0x08,
+0x27,0xbd,0x00,0x10,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,
+0x24,0x42,0x7c,0x44,0xac,0x62,0x00,0x00,0x90,0x89,0x00,0x0a,0x00,0x80,0x30,0x21,
+0x11,0x20,0x00,0x05,0x00,0xa0,0x50,0x21,0x90,0x82,0x00,0x17,0x00,0x00,0x00,0x00,
+0x14,0x40,0x00,0x1b,0x00,0x00,0x00,0x00,0x90,0xc7,0x00,0x04,0x00,0x00,0x00,0x00,
+0x10,0xe0,0x00,0x1b,0x00,0x00,0x00,0x00,0x94,0xc8,0x00,0x00,0x27,0x83,0x8f,0xf0,
+0x93,0x85,0x8b,0x60,0x00,0x08,0x10,0xc0,0x00,0x48,0x10,0x21,0x00,0x02,0x10,0x80,
+0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x08,0x00,0xe5,0x28,0x2b,0x10,0xa0,0x00,0x06,
+0x01,0x44,0x18,0x23,0x8f,0x82,0x8b,0x78,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x2b,
+0x10,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x24,0x03,0x00,0x10,0xa4,0xc8,0x00,0x14,
+0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21,0x11,0x20,0x00,0x05,0x00,0x00,0x00,0x00,
+0x94,0xc2,0x00,0x06,0x24,0x03,0x00,0x08,0x08,0x00,0x1f,0x34,0xa4,0xc2,0x00,0x14,
+0x08,0x00,0x1f,0x34,0x00,0x00,0x18,0x21,0x27,0xbd,0xff,0xc8,0xaf,0xb5,0x00,0x2c,
+0xaf,0xb4,0x00,0x28,0xaf,0xb3,0x00,0x24,0xaf,0xb0,0x00,0x18,0xaf,0xbf,0x00,0x30,
+0xaf,0xb2,0x00,0x20,0xaf,0xb1,0x00,0x1c,0x94,0x91,0x00,0x06,0x00,0x80,0xa0,0x21,
+0x3c,0x02,0x80,0x00,0x3c,0x04,0xb0,0x03,0x00,0x11,0xa8,0xc0,0x34,0x84,0x00,0x20,
+0x24,0x42,0x7c,0xf8,0x02,0xb1,0x48,0x21,0xac,0x82,0x00,0x00,0x00,0x09,0x48,0x80,
+0x24,0x03,0x00,0x01,0x27,0x82,0x90,0x00,0xa2,0x83,0x00,0x12,0x01,0x22,0x10,0x21,
+0x27,0x84,0x8f,0xf4,0x01,0x24,0x20,0x21,0x80,0x48,0x00,0x06,0x8c,0x8a,0x00,0x18,
+0x27,0x83,0x90,0x10,0x01,0x23,0x48,0x21,0x8d,0x24,0x00,0x00,0x25,0x08,0x00,0x02,
+0x8d,0x42,0x00,0x00,0x8d,0x49,0x00,0x04,0x00,0x08,0x17,0xc2,0x8d,0x43,0x00,0x08,
+0x01,0x02,0x40,0x21,0x00,0x04,0x25,0xc2,0x00,0x08,0x40,0x43,0x30,0x84,0x00,0x01,
+0x00,0x03,0x1f,0xc2,0x00,0x08,0x40,0x40,0x00,0xe0,0x80,0x21,0x00,0x64,0x18,0x24,
+0x00,0x09,0x49,0x42,0x01,0x48,0x10,0x21,0x00,0xa0,0x98,0x21,0x00,0xa0,0x20,0x21,
+0x00,0x40,0x38,0x21,0x02,0x00,0x28,0x21,0x14,0x60,0x00,0x19,0x31,0x29,0x00,0x01,
+0x94,0x42,0x00,0x00,0x02,0xb1,0x88,0x21,0x02,0x00,0x28,0x21,0x00,0x11,0x88,0x80,
+0x27,0x90,0x8f,0xf0,0x02,0x30,0x80,0x21,0x96,0x03,0x00,0x06,0x30,0x52,0xff,0xff,
+0x02,0x60,0x20,0x21,0x00,0x60,0x30,0x21,0xa6,0x83,0x00,0x1a,0x27,0x82,0x8f,0xf8,
+0x0c,0x00,0x08,0xdf,0x02,0x22,0x88,0x21,0x00,0x52,0x10,0x21,0x96,0x03,0x00,0x06,
+0xa6,0x22,0x00,0x04,0x8f,0xbf,0x00,0x30,0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c,
+0x7b,0xb0,0x00,0xfc,0x00,0x60,0x10,0x21,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,
+0xaf,0xa9,0x00,0x10,0x0c,0x00,0x09,0x06,0xaf,0xa0,0x00,0x14,0x08,0x00,0x1f,0x72,
+0x02,0xb1,0x88,0x21,0x27,0xbd,0xff,0xc0,0xaf,0xbe,0x00,0x38,0xaf,0xb7,0x00,0x34,
+0xaf,0xb6,0x00,0x30,0xaf,0xb5,0x00,0x2c,0xaf,0xb3,0x00,0x24,0xaf,0xb1,0x00,0x1c,
+0xaf,0xbf,0x00,0x3c,0xaf,0xb4,0x00,0x28,0xaf,0xb2,0x00,0x20,0xaf,0xb0,0x00,0x18,
+0x94,0x90,0x00,0x00,0x3c,0x08,0xb0,0x03,0x35,0x08,0x00,0x20,0x00,0x10,0x10,0xc0,
+0x00,0x50,0x18,0x21,0x00,0x40,0x88,0x21,0x3c,0x02,0x80,0x00,0x00,0x03,0x48,0x80,
+0x24,0x42,0x7e,0x34,0x00,0x80,0x98,0x21,0x27,0x84,0x90,0x00,0x01,0x24,0x20,0x21,
+0x93,0xb7,0x00,0x53,0xad,0x02,0x00,0x00,0x80,0x83,0x00,0x06,0x27,0x82,0x8f,0xf4,
+0x01,0x22,0x10,0x21,0x8c,0x44,0x00,0x18,0x24,0x63,0x00,0x02,0x00,0x03,0x17,0xc2,
+0x8c,0x88,0x00,0x08,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x43,0x00,0x03,0x18,0x40,
+0xaf,0xa7,0x00,0x4c,0x2c,0xa2,0x00,0x10,0x00,0xa0,0xa8,0x21,0x00,0x83,0x50,0x21,
+0x00,0x08,0x47,0xc2,0x00,0xc0,0x58,0x21,0x00,0x00,0xb0,0x21,0x8c,0x92,0x00,0x0c,
+0x14,0x40,0x00,0x13,0x00,0x00,0xf0,0x21,0x92,0x67,0x00,0x04,0x24,0x14,0x00,0x01,
+0x12,0x87,0x00,0x10,0x02,0x30,0x10,0x21,0x27,0x83,0x90,0x08,0x01,0x23,0x18,0x21,
+0x80,0x64,0x00,0x00,0x27,0x83,0xb5,0x60,0x00,0x04,0x11,0x00,0x00,0x44,0x10,0x23,
+0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,
+0x90,0x44,0x00,0x04,0x00,0x00,0x00,0x00,0x10,0x80,0x00,0x23,0x00,0x00,0x00,0x00,
+0x02,0x30,0x10,0x21,0x00,0x02,0x80,0x80,0x24,0x04,0x00,0x01,0x27,0x83,0x90,0x10,
+0xa2,0x64,0x00,0x12,0x02,0x03,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x02,0x15,0xc2,0x30,0x42,0x00,0x01,0x01,0x02,0x10,0x24,0x14,0x40,0x00,0x0e,
+0x02,0xa0,0x20,0x21,0x27,0x82,0x8f,0xf0,0x02,0x02,0x10,0x21,0x94,0x43,0x00,0x06,
+0x00,0x00,0x00,0x00,0xa6,0x63,0x00,0x1a,0x94,0x42,0x00,0x06,0x7b,0xbe,0x01,0xfc,
+0x7b,0xb6,0x01,0xbc,0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,
+0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,0x8f,0xa5,0x00,0x4c,0x01,0x60,0x30,0x21,
+0x01,0x40,0x38,0x21,0xaf,0xa0,0x00,0x10,0x0c,0x00,0x09,0x06,0xaf,0xa0,0x00,0x14,
+0x08,0x00,0x1f,0xd9,0x00,0x00,0x00,0x00,0x27,0x83,0x90,0x10,0x01,0x23,0x18,0x21,
+0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x15,0xc2,0x30,0x42,0x00,0x01,
+0x01,0x02,0x10,0x24,0x14,0x40,0x00,0xaf,0x00,0xa0,0x20,0x21,0x32,0x4f,0x00,0x03,
+0x00,0x12,0x10,0x82,0x25,0xe3,0x00,0x0d,0x30,0x45,0x00,0x07,0x00,0x74,0x78,0x04,
+0x10,0xa0,0x00,0x0e,0x00,0x00,0x90,0x21,0x27,0x82,0x80,0x1c,0x00,0x15,0x18,0x40,
+0x00,0x62,0x18,0x21,0x94,0x64,0x00,0x00,0x24,0xa2,0x00,0x06,0x00,0x54,0x10,0x04,
+0x00,0x44,0x00,0x1a,0x14,0x80,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0d,
+0x00,0x00,0x10,0x12,0x24,0x42,0x00,0x20,0x30,0x52,0xff,0xfc,0x02,0x30,0x10,0x21,
+0x27,0x83,0x90,0x00,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x03,
+0x00,0x00,0x00,0x00,0x30,0x83,0x00,0xff,0x2c,0x62,0x00,0x0c,0x14,0x40,0x00,0x04,
+0x2c,0x62,0x00,0x19,0x30,0x82,0x00,0x0f,0x24,0x43,0x00,0x0c,0x2c,0x62,0x00,0x19,
+0x10,0x40,0x00,0x19,0x24,0x0e,0x00,0x20,0x24,0x62,0xff,0xe9,0x2c,0x42,0x00,0x02,
+0x14,0x40,0x00,0x15,0x24,0x0e,0x00,0x10,0x24,0x62,0xff,0xeb,0x2c,0x42,0x00,0x02,
+0x14,0x40,0x00,0x11,0x24,0x0e,0x00,0x08,0x24,0x02,0x00,0x14,0x10,0x62,0x00,0x0e,
+0x24,0x0e,0x00,0x02,0x24,0x62,0xff,0xef,0x2c,0x42,0x00,0x03,0x14,0x40,0x00,0x0a,
+0x24,0x0e,0x00,0x10,0x24,0x62,0xff,0xf1,0x2c,0x42,0x00,0x02,0x14,0x40,0x00,0x06,
+0x24,0x0e,0x00,0x08,0x24,0x62,0xff,0xf3,0x2c,0x42,0x00,0x02,0x24,0x0e,0x00,0x04,
+0x24,0x03,0x00,0x02,0x00,0x62,0x70,0x0a,0x30,0xe2,0x00,0xff,0x00,0x00,0x48,0x21,
+0x00,0x00,0x68,0x21,0x10,0x40,0x00,0x6d,0x00,0x00,0x58,0x21,0x3c,0x14,0x80,0xff,
+0x27,0x99,0x8f,0xf0,0x01,0xf2,0xc0,0x23,0x36,0x94,0xff,0xff,0x01,0xc9,0x10,0x2a,
+0x14,0x40,0x00,0x64,0x24,0x03,0x00,0x04,0x00,0x10,0x28,0xc0,0x00,0xb0,0x10,0x21,
+0x00,0x02,0x10,0x80,0x00,0x59,0x10,0x21,0x94,0x56,0x00,0x06,0x00,0x00,0x00,0x00,
+0x32,0xcc,0x00,0x03,0x00,0x6c,0x10,0x23,0x30,0x42,0x00,0x03,0x02,0xc2,0x10,0x21,
+0x24,0x42,0x00,0x04,0x30,0x51,0xff,0xff,0x02,0x32,0x18,0x2b,0x10,0x60,0x00,0x4d,
+0x01,0xf1,0x10,0x23,0x02,0x51,0x10,0x23,0x01,0x78,0x18,0x2b,0x10,0x60,0x00,0x34,
+0x30,0x44,0xff,0xff,0x29,0x22,0x00,0x40,0x10,0x40,0x00,0x31,0x01,0x72,0x18,0x21,
+0x25,0x22,0x00,0x01,0x00,0x02,0x16,0x00,0x00,0x02,0x4e,0x03,0x00,0xb0,0x10,0x21,
+0x00,0x02,0x30,0x80,0x27,0x82,0x8f,0xf4,0x30,0x6b,0xff,0xff,0x00,0xc2,0x18,0x21,
+0x8c,0x67,0x00,0x18,0x00,0x04,0x25,0x40,0x3c,0x03,0x7f,0x00,0x8c,0xe2,0x00,0x04,
+0x00,0x83,0x20,0x24,0x27,0x83,0x90,0x00,0x00,0x54,0x10,0x24,0x00,0xc3,0x28,0x21,
+0x00,0x44,0x10,0x25,0xac,0xe2,0x00,0x04,0x16,0xe0,0x00,0x02,0xa0,0xb5,0x00,0x00,
+0xa0,0xb5,0x00,0x03,0x27,0x84,0x90,0x10,0x00,0xc4,0x18,0x21,0x8c,0x62,0x00,0x00,
+0x8c,0xe8,0x00,0x08,0x00,0x02,0x15,0xc2,0x00,0x08,0x47,0xc2,0x30,0x42,0x00,0x01,
+0x01,0x02,0x10,0x24,0x10,0x40,0x00,0x0a,0x00,0x00,0x00,0x00,0x80,0xa2,0x00,0x06,
+0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x02,0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,
+0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40,0x00,0xe2,0x50,0x21,0xa5,0x5e,0x00,0x00,
+0x92,0x62,0x00,0x04,0x25,0xad,0x00,0x01,0x27,0x84,0x8f,0xf0,0x00,0xc4,0x18,0x21,
+0x01,0xa2,0x10,0x2a,0x94,0x70,0x00,0x02,0x14,0x40,0xff,0xb8,0x00,0x00,0x00,0x00,
+0x96,0x63,0x00,0x14,0x00,0x0c,0x10,0x23,0xa2,0x69,0x00,0x12,0x30,0x42,0x00,0x03,
+0x01,0x62,0x10,0x23,0x00,0x03,0x80,0xc0,0x8f,0xa5,0x00,0x4c,0x30,0x4b,0xff,0xff,
+0x02,0x03,0x80,0x21,0x27,0x82,0x8f,0xf8,0x00,0x10,0x80,0x80,0xa6,0x6b,0x00,0x1a,
+0x02,0xa0,0x20,0x21,0x01,0x60,0x30,0x21,0x01,0x60,0x88,0x21,0x0c,0x00,0x08,0xdf,
+0x02,0x02,0x80,0x21,0x00,0x5e,0x10,0x21,0xa6,0x02,0x00,0x04,0x08,0x00,0x1f,0xdf,
+0x02,0x20,0x10,0x21,0x01,0x62,0x10,0x2b,0x10,0x40,0xff,0xe9,0x00,0x00,0x20,0x21,
+0x29,0x22,0x00,0x40,0x10,0x40,0xff,0xe6,0x01,0x71,0x18,0x21,0x08,0x00,0x20,0x55,
+0x25,0x22,0x00,0x01,0x08,0x00,0x20,0x84,0x32,0xcc,0x00,0x03,0x08,0x00,0x20,0x84,
+0x00,0x00,0x60,0x21,0x8f,0xa5,0x00,0x4c,0x01,0x40,0x38,0x21,0xaf,0xa0,0x00,0x10,
+0x0c,0x00,0x09,0x06,0xaf,0xb4,0x00,0x14,0x92,0x67,0x00,0x04,0x08,0x00,0x1f,0xf7,
+0x30,0x5e,0xff,0xff,0x30,0x84,0xff,0xff,0x00,0x04,0x30,0xc0,0x00,0xc4,0x20,0x21,
+0x00,0x04,0x20,0x80,0x27,0x82,0x8f,0xf0,0x3c,0x03,0xb0,0x08,0x30,0xa5,0xff,0xff,
+0x00,0x82,0x20,0x21,0x00,0xc3,0x30,0x21,0xac,0xc5,0x00,0x00,0x03,0xe0,0x00,0x08,
+0xa4,0x85,0x00,0x00,0x30,0x84,0xff,0xff,0x00,0x04,0x30,0xc0,0x00,0xc4,0x30,0x21,
+0x27,0x88,0x8f,0xf0,0x00,0x06,0x30,0x80,0x00,0xc8,0x30,0x21,0x94,0xc3,0x00,0x04,
+0x3c,0x02,0xb0,0x08,0x3c,0x07,0xb0,0x03,0x00,0x03,0x20,0xc0,0x00,0x83,0x18,0x21,
+0x00,0x03,0x18,0x80,0x00,0x82,0x20,0x21,0x3c,0x02,0x80,0x01,0x30,0xa5,0xff,0xff,
+0x00,0x68,0x18,0x21,0x34,0xe7,0x00,0x20,0x24,0x42,0x82,0xe4,0xac,0xe2,0x00,0x00,
+0xa4,0xc5,0x00,0x02,0xa4,0x65,0x00,0x00,0x03,0xe0,0x00,0x08,0xac,0x85,0x00,0x00,
+0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x34,0x42,0x00,0x20,0x24,0x63,0x83,0x40,
+0xac,0x43,0x00,0x00,0x90,0x82,0x00,0x10,0x3c,0x08,0xb0,0x03,0x3c,0x09,0xb0,0x06,
+0x27,0x87,0x8f,0xf0,0x3c,0x0d,0xb0,0x08,0x34,0x0e,0xff,0xff,0x35,0x08,0x00,0x62,
+0x00,0x80,0x30,0x21,0x24,0x0c,0xff,0xff,0x10,0x40,0x00,0x2c,0x35,0x29,0x80,0x20,
+0x97,0x82,0x8f,0xe0,0x94,0x85,0x00,0x0c,0x3c,0x0b,0xb0,0x03,0x00,0x02,0x18,0xc0,
+0x00,0x62,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x47,0x10,0x21,0xa4,0x45,0x00,0x00,
+0x94,0x84,0x00,0x0e,0x00,0x6d,0x18,0x21,0xac,0x65,0x00,0x00,0x00,0x04,0x10,0xc0,
+0x00,0x44,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x47,0x10,0x21,0x94,0x45,0x00,0x04,
+0x3c,0x0a,0x77,0x77,0x35,0x6b,0x00,0xb4,0x00,0x05,0x10,0xc0,0x00,0x45,0x18,0x21,
+0x00,0x03,0x18,0x80,0x00,0x67,0x18,0x21,0x00,0x4d,0x10,0x21,0xac,0x4e,0x00,0x00,
+0xa4,0x6e,0x00,0x00,0x95,0x04,0x00,0x00,0x90,0xc3,0x00,0x10,0x24,0x02,0x00,0xff,
+0x00,0x44,0x10,0x23,0x00,0x43,0x10,0x2a,0xa7,0x85,0x8f,0xe0,0x10,0x40,0x00,0x04,
+0x35,0x4a,0x88,0x88,0xad,0x6a,0x00,0x00,0x90,0xc3,0x00,0x10,0x00,0x00,0x00,0x00,
+0x30,0x63,0x00,0xff,0x3c,0x02,0x00,0x40,0x00,0x62,0x18,0x25,0xad,0x23,0x00,0x00,
+0xa4,0xcc,0x00,0x0e,0xa4,0xcc,0x00,0x0c,0xa0,0xc0,0x00,0x10,0x03,0xe0,0x00,0x08,
+0x00,0x00,0x00,0x00,0x30,0x84,0xff,0xff,0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,
+0x27,0x89,0x8f,0xf0,0x00,0x02,0x10,0x80,0x00,0x49,0x10,0x21,0x97,0x83,0x8f,0xe0,
+0x94,0x4a,0x00,0x04,0x3c,0x02,0xb0,0x08,0x00,0x03,0x38,0xc0,0x00,0x0a,0x40,0xc0,
+0x00,0xe3,0x18,0x21,0x01,0x0a,0x28,0x21,0x00,0xe2,0x38,0x21,0x01,0x02,0x40,0x21,
+0x00,0x03,0x18,0x80,0x00,0x05,0x28,0x80,0x3c,0x06,0xb0,0x03,0x3c,0x02,0x80,0x01,
+0x00,0xa9,0x28,0x21,0x00,0x69,0x18,0x21,0x34,0xc6,0x00,0x20,0x34,0x09,0xff,0xff,
+0x24,0x42,0x84,0x34,0xac,0xc2,0x00,0x00,0xa4,0x64,0x00,0x00,0xac,0xe4,0x00,0x00,
+0xa4,0xa9,0x00,0x00,0xad,0x09,0x00,0x00,0xa7,0x8a,0x8f,0xe0,0x03,0xe0,0x00,0x08,
+0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,0x34,0x63,0x00,0x20,
+0x24,0x42,0x84,0xb4,0x3c,0x04,0xb0,0x03,0xac,0x62,0x00,0x00,0x34,0x84,0x01,0x10,
+0x8c,0x82,0x00,0x00,0x97,0x83,0x81,0x60,0x30,0x42,0xff,0xff,0x10,0x62,0x00,0x16,
+0x24,0x0a,0x00,0x01,0xa7,0x82,0x81,0x60,0xaf,0x80,0xb4,0x40,0x00,0x40,0x28,0x21,
+0x24,0x06,0x00,0x01,0x27,0x84,0xb4,0x44,0x25,0x43,0xff,0xff,0x00,0x66,0x10,0x04,
+0x00,0xa2,0x10,0x24,0x14,0x40,0x00,0x07,0x00,0x00,0x00,0x00,0x8c,0x83,0xff,0xfc,
+0x00,0x00,0x00,0x00,0x00,0x66,0x10,0x04,0x00,0xa2,0x10,0x24,0x38,0x42,0x00,0x00,
+0x01,0x42,0x18,0x0a,0x25,0x4a,0x00,0x01,0x2d,0x42,0x00,0x14,0xac,0x83,0x00,0x00,
+0x14,0x40,0xff,0xf1,0x24,0x84,0x00,0x04,0x3c,0x0b,0xb0,0x03,0x00,0x00,0x50,0x21,
+0x3c,0x0c,0x80,0x00,0x27,0x89,0xb4,0x90,0x35,0x6b,0x01,0x20,0x8d,0x68,0x00,0x00,
+0x8d,0x23,0x00,0x04,0x01,0x0c,0x10,0x24,0x00,0x02,0x17,0xc2,0x11,0x03,0x00,0x37,
+0xa1,0x22,0x00,0xdc,0xa1,0x20,0x00,0xd5,0xa1,0x20,0x00,0xd6,0x01,0x20,0x30,0x21,
+0x00,0x00,0x38,0x21,0x00,0x00,0x28,0x21,0x01,0x20,0x20,0x21,0x00,0xa8,0x10,0x06,
+0x30,0x42,0x00,0x01,0x10,0xe0,0x00,0x10,0xa0,0x82,0x00,0x0a,0x90,0x82,0x00,0x07,
+0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x31,0x24,0xa2,0xff,0xff,0xa0,0x82,0x00,0x08,
+0x90,0x82,0x00,0x0a,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x09,0x00,0x00,0x00,0x00,
+0x90,0x83,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0x40,0x00,0x43,0x10,0x21,
+0x00,0x46,0x10,0x21,0xa0,0x45,0x00,0x09,0x90,0x82,0x00,0x0a,0x00,0x00,0x00,0x00,
+0x10,0x40,0x00,0x07,0x00,0x00,0x00,0x00,0x14,0xe0,0x00,0x04,0x00,0x00,0x00,0x00,
+0xa0,0xc5,0x00,0xd5,0x24,0x07,0x00,0x01,0xa0,0x85,0x00,0x08,0xa0,0xc5,0x00,0xd6,
+0x24,0xa5,0x00,0x01,0x2c,0xa2,0x00,0x1c,0x14,0x40,0xff,0xe0,0x24,0x84,0x00,0x03,
+0x90,0xc4,0x00,0xd5,0x00,0x00,0x28,0x21,0x00,0xa4,0x10,0x2b,0x10,0x40,0x00,0x0b,
+0x00,0x00,0x00,0x00,0x00,0xc0,0x18,0x21,0xa0,0x64,0x00,0x08,0x90,0xc2,0x00,0xd5,
+0x24,0xa5,0x00,0x01,0xa0,0x62,0x00,0x09,0x90,0xc4,0x00,0xd5,0x00,0x00,0x00,0x00,
+0x00,0xa4,0x10,0x2b,0x14,0x40,0xff,0xf8,0x24,0x63,0x00,0x03,0x25,0x4a,0x00,0x01,
+0x2d,0x42,0x00,0x08,0xad,0x28,0x00,0x04,0x25,0x6b,0x00,0x04,0x14,0x40,0xff,0xbf,
+0x25,0x29,0x00,0xec,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x90,0x82,0x00,0x05,
+0x08,0x00,0x21,0x68,0xa0,0x82,0x00,0x08,0x97,0x85,0x8b,0x6a,0x3c,0x03,0xb0,0x03,
+0x3c,0x02,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x63,0x00,0x20,0x24,0x42,0x86,0x68,
+0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x62,0x00,0x00,0x30,0x90,0x00,0xff,
+0x00,0x05,0x28,0x42,0x00,0x00,0x48,0x21,0x27,0x8f,0xb4,0x94,0x00,0x00,0x50,0x21,
+0x00,0x00,0x58,0x21,0x27,0x98,0xb5,0x74,0x27,0x99,0xb5,0x70,0x27,0x8e,0xb5,0x6e,
+0x27,0x8c,0xb4,0x98,0x27,0x8d,0xb4,0xf0,0x27,0x88,0xb5,0x68,0x00,0x0a,0x18,0x80,
+0x01,0x6f,0x10,0x21,0xac,0x40,0x00,0x00,0xac,0x45,0x00,0x58,0x00,0x6e,0x20,0x21,
+0x00,0x78,0x10,0x21,0xa1,0x00,0xff,0xfc,0xad,0x00,0x00,0x00,0xa1,0x00,0x00,0x04,
+0xa1,0x00,0x00,0x05,0xad,0x00,0xff,0xf8,0x00,0x79,0x18,0x21,0x24,0x06,0x00,0x01,
+0x24,0xc6,0xff,0xff,0xa0,0x80,0x00,0x00,0xa4,0x60,0x00,0x00,0xac,0x40,0x00,0x00,
+0x24,0x63,0x00,0x02,0x24,0x42,0x00,0x04,0x04,0xc1,0xff,0xf9,0x24,0x84,0x00,0x01,
+0x00,0x0a,0x10,0x80,0x00,0x4d,0x20,0x21,0x00,0x00,0x30,0x21,0x00,0x4c,0x18,0x21,
+0x27,0x87,0x81,0x64,0x8c,0xe2,0x00,0x00,0x24,0xe7,0x00,0x04,0xac,0x82,0x00,0x00,
+0xa0,0x66,0x00,0x00,0xa0,0x66,0x00,0x01,0x24,0xc6,0x00,0x01,0x28,0xc2,0x00,0x1c,
+0xa0,0x60,0x00,0x02,0x24,0x84,0x00,0x04,0x14,0x40,0xff,0xf6,0x24,0x63,0x00,0x03,
+0x25,0x29,0x00,0x01,0x29,0x22,0x00,0x08,0x25,0x4a,0x00,0x3b,0x25,0x08,0x00,0xec,
+0x14,0x40,0xff,0xd6,0x25,0x6b,0x00,0xec,0xa7,0x80,0x81,0x60,0x00,0x00,0x48,0x21,
+0x27,0x83,0xb4,0x40,0xac,0x69,0x00,0x00,0x25,0x29,0x00,0x01,0x29,0x22,0x00,0x0c,
+0x14,0x40,0xff,0xfc,0x24,0x63,0x00,0x04,0x0c,0x00,0x21,0x2d,0x00,0x00,0x00,0x00,
+0x2e,0x04,0x00,0x14,0x27,0x83,0xb4,0x90,0x24,0x09,0x00,0x07,0x10,0x80,0x00,0x0a,
+0x00,0x00,0x00,0x00,0x90,0x62,0x00,0xd5,0x25,0x29,0xff,0xff,0xa0,0x62,0x00,0x00,
+0x05,0x21,0xff,0xfa,0x24,0x63,0x00,0xec,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,
+0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x90,0x62,0x00,0xd6,0x08,0x00,0x21,0xeb,
+0x25,0x29,0xff,0xff,0x30,0x84,0x00,0xff,0x00,0x04,0x11,0x00,0x00,0x44,0x10,0x23,
+0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x27,0x83,0xb4,0x90,
+0x00,0x43,0x60,0x21,0x3c,0x04,0xb0,0x03,0x3c,0x02,0x80,0x01,0x34,0x84,0x00,0x20,
+0x24,0x42,0x87,0xd4,0x30,0xc6,0x00,0xff,0x93,0xa9,0x00,0x13,0x30,0xa5,0x00,0xff,
+0x30,0xe7,0x00,0xff,0xac,0x82,0x00,0x00,0x10,0xc0,0x00,0xeb,0x25,0x8f,0x00,0xd0,
+0x91,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x42,0xff,0xfc,0x2c,0x43,0x00,0x18,
+0x10,0x60,0x00,0xcf,0x3c,0x03,0x80,0x01,0x00,0x02,0x10,0x80,0x24,0x63,0x02,0x5c,
+0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08,
+0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x2d,0x10,0x40,0x00,0x14,0x00,0x00,0x00,0x00,
+0x10,0xa0,0x00,0x0f,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x09,
+0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x06,0x00,0x00,0x00,0x00,
+0x8d,0x82,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x42,0xff,0xd0,0x03,0xe0,0x00,0x08,
+0xad,0x82,0x00,0xd0,0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23,0x24,0x42,0xff,0xe0,
+0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23,0x24,0x42,0x00,0x01,0x10,0xa0,0x00,0x0f,
+0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xf9,0x00,0x00,0x00,0x00,
+0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x07,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x03,
+0x14,0xa2,0xff,0xf0,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23,
+0x24,0x42,0xff,0xe8,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,
+0x08,0x00,0x22,0x23,0x24,0x42,0x00,0x02,0x10,0xa0,0xff,0xfc,0x00,0x00,0x00,0x00,
+0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xe6,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,
+0x10,0xa2,0xff,0xf4,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xef,0x00,0x00,0x00,0x00,
+0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23,0x24,0x42,0xff,0xf8,0x2d,0x22,0x00,0x19,
+0x14,0x40,0xff,0xde,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xec,0x00,0x00,0x00,0x00,
+0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xd6,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,
+0x10,0xa2,0xff,0xe4,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0xf1,0x00,0x00,0x00,0x00,
+0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23,0x24,0x42,0xff,0xf0,0x2d,0x22,0x00,0x1b,
+0x10,0x40,0xff,0xf1,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xdc,0x00,0x00,0x00,0x00,
+0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xc6,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,
+0x14,0xa2,0xff,0xce,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23,
+0x24,0x42,0xff,0xf4,0x2d,0x22,0x00,0x1e,0x10,0x40,0xff,0xe3,0x00,0x00,0x00,0x00,
+0x10,0xa0,0xff,0xce,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xc9,
+0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xd6,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x34,
+0x24,0x02,0x00,0x03,0x2d,0x22,0x00,0x23,0x10,0x40,0xff,0xd7,0x00,0x00,0x00,0x00,
+0x10,0xa0,0xff,0xaf,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xbd,
+0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xda,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x03,
+0x14,0xa2,0xff,0x9f,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x25,0x00,0x00,0x00,0x00,
+0x2d,0x22,0x00,0x25,0x10,0x40,0xff,0xc8,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xa0,
+0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x06,0x00,0x00,0x00,0x00,
+0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x97,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x80,
+0x24,0x02,0x00,0x03,0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23,0x24,0x42,0xff,0xfc,
+0x2d,0x22,0x00,0x16,0x14,0x40,0x00,0x0e,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xa3,
+0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x8d,0x00,0x00,0x00,0x00,
+0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x9b,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xa8,
+0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23,0x24,0x42,0xff,0xfa,
+0x10,0xa0,0xff,0x96,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x80,
+0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x8e,0x00,0x00,0x00,0x00,
+0x08,0x00,0x22,0x48,0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x17,0x14,0x40,0xff,0x9e,
+0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x97,0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x19,
+0x10,0x40,0xff,0xe2,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0x84,0x00,0x00,0x00,0x00,
+0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x6e,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,
+0x10,0xa2,0xff,0x7c,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0x89,0x00,0x00,0x00,0x00,
+0x08,0x00,0x22,0x25,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0xb4,0x2d,0x22,0x00,0x1b,
+0x2d,0x22,0x00,0x1e,0x10,0x40,0xff,0xde,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0x73,
+0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x5d,0x00,0x00,0x00,0x00,
+0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x6b,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0x88,
+0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x25,0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x23,
+0x14,0x40,0xff,0xf2,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x4e,0x00,0x00,0x00,0x00,
+0x08,0x00,0x22,0x4c,0x2d,0x22,0x00,0x25,0x08,0x00,0x22,0x85,0x2d,0x22,0x00,0x27,
+0x10,0xa0,0xff,0x5e,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x48,
+0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x56,0x24,0x02,0x00,0x03,
+0x14,0xa2,0xff,0x63,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x91,0x00,0x00,0x00,0x00,
+0x2d,0x22,0x00,0x27,0x14,0x40,0xff,0x8e,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x3e,
+0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x29,0x14,0x40,0xff,0x89,0x00,0x00,0x00,0x00,
+0x08,0x00,0x22,0x2b,0x00,0x00,0x00,0x00,0x91,0x86,0x00,0x00,0x91,0x83,0x00,0xd4,
+0x25,0x8d,0x00,0x5c,0x30,0xc4,0x00,0xff,0x00,0x04,0x10,0x40,0x00,0x44,0x10,0x21,
+0x00,0x04,0x50,0x80,0x01,0x82,0x58,0x21,0x01,0x8a,0x40,0x21,0x25,0x78,0x00,0x08,
+0x10,0x60,0x00,0x37,0x25,0x0e,0x00,0x60,0x2c,0xa2,0x00,0x03,0x14,0x40,0x00,0x25,
+0x00,0x00,0x00,0x00,0x91,0x82,0x00,0xdd,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x1e,
+0x00,0x00,0x00,0x00,0x27,0x87,0x81,0x64,0x01,0x47,0x10,0x21,0x8c,0x43,0x00,0x00,
+0x00,0x00,0x00,0x00,0xad,0x03,0x00,0x60,0x91,0x62,0x00,0x08,0x00,0x00,0x00,0x00,
+0x00,0x40,0x30,0x21,0xa1,0x82,0x00,0x00,0x30,0xc2,0x00,0xff,0x00,0x02,0x10,0x80,
+0x00,0x47,0x10,0x21,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x18,0x42,
+0xad,0xa3,0x00,0x00,0x91,0x84,0x00,0x00,0x8d,0xc5,0x00,0x00,0x00,0x04,0x20,0x80,
+0x00,0x87,0x10,0x21,0x8c,0x43,0x00,0x00,0x00,0x05,0x28,0x40,0x00,0x8c,0x20,0x21,
+0x00,0x03,0x18,0x80,0x00,0xa3,0x10,0x2b,0x00,0x62,0x28,0x0a,0xac,0x85,0x00,0x60,
+0x03,0xe0,0x00,0x08,0xa1,0x80,0x00,0xd4,0x27,0x87,0x81,0x64,0x08,0x00,0x23,0x0e,
+0xa1,0x80,0x00,0xdd,0x27,0x82,0x81,0xd4,0x8d,0x83,0x00,0xd8,0x00,0x82,0x10,0x21,
+0x90,0x44,0x00,0x00,0x24,0x63,0x00,0x01,0x00,0x64,0x20,0x2b,0x14,0x80,0xff,0x0d,
+0xad,0x83,0x00,0xd8,0x8d,0x02,0x00,0x60,0xa1,0x80,0x00,0xd4,0x00,0x02,0x1f,0xc2,
+0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,0x03,0xe0,0x00,0x08,0xad,0x82,0x00,0x5c,
+0x10,0xe0,0x00,0x1a,0x24,0x83,0xff,0xfc,0x2c,0x62,0x00,0x18,0x10,0x40,0x01,0x18,
+0x00,0x03,0x10,0x80,0x3c,0x03,0x80,0x01,0x24,0x63,0x02,0xbc,0x00,0x43,0x10,0x21,
+0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,
+0x2d,0x22,0x00,0x2d,0x10,0x40,0x00,0x5f,0x00,0x00,0x00,0x00,0x10,0xa0,0x00,0x5a,
+0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x54,0x00,0x00,0x00,0x00,
+0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x51,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,
+0x00,0x00,0x00,0x00,0x24,0x42,0xff,0xd0,0xad,0x82,0x00,0xd0,0x8d,0xe3,0x00,0x00,
+0x8d,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x21,0xad,0xa2,0x00,0x00,
+0xad,0xe0,0x00,0x00,0x8d,0xa3,0x00,0x00,0x8d,0xc4,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x83,0x10,0x2a,0x10,0x40,0x00,0x22,0x00,0x00,0x00,0x00,0x93,0x05,0x00,0x01,
+0x91,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x45,0x00,0x05,0x24,0x02,0x00,0x01,
+0xa1,0x85,0x00,0x00,0xa1,0x82,0x00,0xd4,0x03,0xe0,0x00,0x08,0xad,0x80,0x00,0xd8,
+0x91,0x82,0x00,0xdd,0x24,0x03,0x00,0x01,0x10,0x43,0x00,0x05,0x00,0x00,0x00,0x00,
+0xa1,0x83,0x00,0xd4,0xad,0x80,0x00,0xd8,0x03,0xe0,0x00,0x08,0xa1,0x83,0x00,0xdd,
+0x00,0x04,0x17,0xc2,0x00,0x82,0x10,0x21,0x00,0x02,0x10,0x43,0xad,0xa2,0x00,0x00,
+0x91,0x83,0x00,0x00,0x27,0x82,0x81,0x64,0x8d,0xc5,0x00,0x00,0x00,0x03,0x18,0x80,
+0x00,0x62,0x18,0x21,0x8c,0x64,0x00,0x00,0x00,0x05,0x28,0x40,0x00,0x04,0x18,0x80,
+0x00,0xa3,0x10,0x2b,0x00,0x62,0x28,0x0a,0x08,0x00,0x23,0x20,0xad,0xc5,0x00,0x00,
+0x97,0x82,0x8b,0x6c,0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x2a,0x10,0x40,0xfe,0xb9,
+0x00,0x00,0x00,0x00,0x91,0x82,0x00,0xdd,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x15,
+0x00,0x00,0x00,0x00,0x91,0x83,0x00,0x00,0x27,0x82,0x81,0x64,0x00,0x03,0x18,0x80,
+0x00,0x62,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x6c,0x18,0x21,0xac,0x64,0x00,0x60,
+0x93,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x10,0x80,0x01,0x82,0x10,0x21,
+0x24,0x4e,0x00,0x60,0xa1,0x85,0x00,0x00,0x8d,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,0x03,0xe0,0x00,0x08,
+0xad,0xa2,0x00,0x00,0x08,0x00,0x23,0x92,0xa1,0x80,0x00,0xdd,0x8d,0x82,0x00,0xd0,
+0x08,0x00,0x23,0x4e,0x24,0x42,0xff,0xe0,0x8d,0x82,0x00,0xd0,0x08,0x00,0x23,0x4e,
+0x24,0x42,0x00,0x01,0x10,0xa0,0x00,0x0d,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,
+0x10,0xa2,0xff,0xf9,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xa7,
+0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xf0,0x00,0x00,0x00,0x00,
+0x8d,0x82,0x00,0xd0,0x08,0x00,0x23,0x4e,0x24,0x42,0xff,0xe8,0x8d,0x82,0x00,0xd0,
+0x08,0x00,0x23,0x4e,0x24,0x42,0x00,0x02,0x10,0xa0,0xff,0xfc,0x00,0x00,0x00,0x00,
+0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xe8,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,
+0x10,0xa2,0xff,0x96,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xf1,0x00,0x00,0x00,0x00,
+0x8d,0x82,0x00,0xd0,0x08,0x00,0x23,0x4e,0x24,0x42,0xff,0xf8,0x2d,0x22,0x00,0x19,
+0x14,0x40,0xff,0xe0,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xec,0x00,0x00,0x00,0x00,
+0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xd8,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,
+0x10,0xa2,0xff,0x86,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0xf1,0x00,0x00,0x00,0x00,
+0x8d,0x82,0x00,0xd0,0x08,0x00,0x23,0x4e,0x24,0x42,0xff,0xf0,0x2d,0x22,0x00,0x1b,
+0x10,0x40,0xff,0xf1,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xdc,0x00,0x00,0x00,0x00,
+0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xc8,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,
+0x14,0xa2,0xff,0xd0,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x23,0x4e,
+0x24,0x42,0xff,0xf4,0x2d,0x22,0x00,0x1e,0x10,0x40,0xff,0xe3,0x00,0x00,0x00,0x00,
+0x10,0xa0,0xff,0xce,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x6b,
+0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xd6,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0xaa,
+0x24,0x02,0x00,0x03,0x2d,0x22,0x00,0x23,0x10,0x40,0xff,0xd7,0x00,0x00,0x00,0x00,
+0x10,0xa0,0xff,0xb1,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x5f,
+0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xda,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x03,
+0x14,0xa2,0xff,0x56,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0x9b,0x00,0x00,0x00,0x00,
+0x2d,0x22,0x00,0x25,0x10,0x40,0xff,0xc8,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xa2,
+0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x06,0x00,0x00,0x00,0x00,
+0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x99,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0xf4,
+0x24,0x02,0x00,0x03,0x8d,0x82,0x00,0xd0,0x08,0x00,0x23,0x4e,0x24,0x42,0xff,0xfc,
+0x2d,0x22,0x00,0x16,0x14,0x40,0x00,0x0e,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xa3,
+0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x8f,0x00,0x00,0x00,0x00,
+0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x3d,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xa8,
+0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x23,0x4e,0x24,0x42,0xff,0xfa,
+0x10,0xa0,0xff,0x96,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x82,
+0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x30,0x00,0x00,0x00,0x00,
+0x08,0x00,0x23,0xbc,0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x17,0x14,0x40,0xff,0x9e,
+0x00,0x00,0x00,0x00,0x08,0x00,0x24,0x0b,0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x19,
+0x10,0x40,0xff,0xe2,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0x84,0x00,0x00,0x00,0x00,
+0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x70,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,
+0x10,0xa2,0xff,0x1e,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0x89,0x00,0x00,0x00,0x00,
+0x08,0x00,0x23,0x9b,0x00,0x00,0x00,0x00,0x08,0x00,0x24,0x28,0x2d,0x22,0x00,0x1b,
+0x2d,0x22,0x00,0x1e,0x10,0x40,0xff,0xde,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0x73,
+0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x5f,0x00,0x00,0x00,0x00,
+0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x0d,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0x88,
+0x00,0x00,0x00,0x00,0x08,0x00,0x23,0x9b,0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x23,
+0x14,0x40,0xff,0xf2,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0xc2,0x00,0x00,0x00,0x00,
+0x08,0x00,0x23,0xc0,0x2d,0x22,0x00,0x25,0x08,0x00,0x23,0xf9,0x2d,0x22,0x00,0x27,
+0x10,0xa0,0xff,0x5e,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x4a,
+0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xfe,0xf8,0x24,0x02,0x00,0x03,
+0x14,0xa2,0xff,0x63,0x00,0x00,0x00,0x00,0x08,0x00,0x24,0x05,0x00,0x00,0x00,0x00,
+0x2d,0x22,0x00,0x27,0x14,0x40,0xff,0x8e,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0xb2,
+0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x29,0x14,0x40,0xff,0x89,0x00,0x00,0x00,0x00,
+0x08,0x00,0x23,0xa1,0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xe8,0x3c,0x02,0xb0,0x03,
+0xaf,0xbf,0x00,0x14,0xaf,0xb0,0x00,0x10,0x34,0x42,0x01,0x18,0x3c,0x03,0xb0,0x03,
+0x8c,0x50,0x00,0x00,0x34,0x63,0x01,0x2c,0x90,0x62,0x00,0x00,0x32,0x05,0x00,0x01,
+0xa3,0x82,0x80,0x10,0x14,0xa0,0x00,0x14,0x30,0x44,0x00,0xff,0x32,0x02,0x01,0x00,
+0x14,0x40,0x00,0x09,0x00,0x00,0x00,0x00,0x32,0x02,0x08,0x00,0x10,0x40,0x00,0x02,
+0x24,0x02,0x00,0x01,0xa3,0x82,0xbc,0x08,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,
+0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x05,0x39,0x00,0x00,0x00,0x00,
+0x26,0x02,0xff,0x00,0xa3,0x80,0xbc,0x08,0x3c,0x01,0xb0,0x03,0xac,0x22,0x01,0x18,
+0x08,0x00,0x24,0x77,0x32,0x02,0x08,0x00,0x0c,0x00,0x21,0x9a,0x00,0x00,0x00,0x00,
+0x26,0x02,0xff,0xff,0x3c,0x01,0xb0,0x03,0xac,0x22,0x01,0x18,0x08,0x00,0x24,0x74,
+0x32,0x02,0x01,0x00,0x27,0xbd,0xff,0xe0,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xd0,
+0xaf,0xbf,0x00,0x18,0x8c,0x43,0x00,0x00,0x3c,0x02,0x00,0x40,0x24,0x07,0x0f,0xff,
+0x00,0x03,0x33,0x02,0x00,0x03,0x2d,0x02,0x00,0x03,0x43,0x02,0x30,0x69,0x0f,0xff,
+0x00,0x62,0x18,0x24,0x30,0xa5,0x00,0x03,0x30,0xc6,0x00,0xff,0x10,0x60,0x00,0x08,
+0x31,0x08,0x00,0xff,0x01,0x00,0x30,0x21,0x0c,0x00,0x25,0x38,0xaf,0xa9,0x00,0x10,
+0x8f,0xbf,0x00,0x18,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,
+0x0c,0x00,0x25,0x8a,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0xd4,
+0x08,0x00,0x24,0xa0,0xac,0x62,0x00,0x00,0x27,0xbd,0xff,0xc0,0xaf,0xb6,0x00,0x30,
+0xaf,0xb3,0x00,0x24,0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18,0xaf,0xbf,0x00,0x3c,
+0xaf,0xbe,0x00,0x38,0xaf,0xb7,0x00,0x34,0xaf,0xb5,0x00,0x2c,0xaf,0xb4,0x00,0x28,
+0xaf,0xb2,0x00,0x20,0x0c,0x00,0x17,0xc8,0x00,0x80,0x80,0x21,0x00,0x00,0xb0,0x21,
+0x00,0x00,0x88,0x21,0x10,0x40,0x00,0x12,0x00,0x00,0x98,0x21,0x3c,0x02,0xb0,0x03,
+0x3c,0x03,0xb0,0x03,0x3c,0x04,0xb0,0x03,0x24,0x05,0x00,0x01,0x34,0x42,0x00,0xbc,
+0x34,0x63,0x00,0xbb,0x34,0x84,0x00,0xba,0xa4,0x40,0x00,0x00,0xa0,0x65,0x00,0x00,
+0xa0,0x85,0x00,0x00,0x7b,0xbe,0x01,0xfc,0x7b,0xb6,0x01,0xbc,0x7b,0xb4,0x01,0x7c,
+0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,
+0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x47,0x90,0x44,0x00,0x00,0x00,0x10,0x1a,0x02,
+0x3c,0x15,0xfd,0xff,0x30,0x84,0x00,0xff,0xa0,0x50,0x00,0x00,0x30,0x74,0x00,0x0f,
+0xaf,0xa4,0x00,0x10,0x00,0x00,0x90,0x21,0x3c,0x17,0x02,0x00,0x36,0xb5,0xff,0xff,
+0x3c,0x1e,0xb0,0x03,0x0c,0x00,0x06,0xce,0x24,0x04,0x04,0x00,0x00,0x57,0x10,0x25,
+0x00,0x40,0x28,0x21,0x0c,0x00,0x06,0xc1,0x24,0x04,0x04,0x00,0x00,0x00,0x80,0x21,
+0x0c,0x00,0x26,0x52,0x00,0x00,0x00,0x00,0x26,0x03,0x00,0x01,0x30,0x70,0x00,0xff,
+0x10,0x40,0x00,0x47,0x2e,0x03,0x00,0x02,0x14,0x60,0xff,0xf9,0x00,0x00,0x00,0x00,
+0x0c,0x00,0x06,0xce,0x24,0x04,0x04,0x00,0x00,0x55,0x10,0x24,0x00,0x40,0x28,0x21,
+0x0c,0x00,0x06,0xc1,0x24,0x04,0x04,0x00,0x24,0x02,0x00,0x01,0x12,0x82,0x00,0x38,
+0x00,0x00,0x00,0x00,0x12,0x80,0x00,0x36,0x00,0x00,0x00,0x00,0x32,0x22,0x00,0x60,
+0x32,0x23,0x0c,0x00,0x00,0x03,0x1a,0x02,0x3c,0x05,0x00,0x60,0x00,0x02,0x11,0x42,
+0x02,0x25,0x20,0x24,0x00,0x43,0x10,0x25,0x3c,0x03,0x04,0x00,0x02,0x23,0x28,0x24,
+0x00,0x04,0x24,0x42,0x00,0x44,0x10,0x25,0x00,0x05,0x2d,0x02,0x00,0x45,0x88,0x25,
+0x12,0x20,0x00,0x05,0x26,0x42,0x00,0x01,0x26,0xc2,0x00,0x01,0x30,0x56,0x00,0xff,
+0x02,0x71,0x98,0x21,0x26,0x42,0x00,0x01,0x02,0x5e,0x20,0x21,0x30,0x52,0x00,0xff,
+0x2e,0x43,0x00,0x05,0xa0,0x91,0x00,0xd8,0x14,0x60,0xff,0xce,0x3c,0x02,0xb0,0x03,
+0x8f,0xa5,0x00,0x10,0x34,0x42,0x01,0x47,0xa0,0x45,0x00,0x00,0x12,0x60,0x00,0x0e,
+0x3c,0x02,0xb0,0x03,0x12,0xc0,0x00,0x0d,0x34,0x42,0x00,0xbc,0x00,0x13,0x10,0x40,
+0x00,0x53,0x10,0x21,0x00,0x02,0x10,0xc0,0x00,0x53,0x10,0x21,0x00,0x02,0x98,0x80,
+0x02,0x76,0x00,0x1b,0x16,0xc0,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0d,
+0x00,0x00,0x98,0x12,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xbc,0x3c,0x03,0xb0,0x03,
+0x3c,0x04,0xb0,0x03,0xa4,0x53,0x00,0x00,0x34,0x63,0x00,0xbb,0x34,0x84,0x00,0xba,
+0x24,0x02,0x00,0x01,0xa0,0x60,0x00,0x00,0x08,0x00,0x24,0xc5,0xa0,0x82,0x00,0x00,
+0x0c,0x00,0x06,0xce,0x24,0x04,0x04,0xfc,0x08,0x00,0x24,0xf3,0x00,0x40,0x88,0x21,
+0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0xbc,0x3c,0x04,0xb0,0x03,0x3c,0x05,0xb0,0x03,
+0xa4,0x60,0x00,0x00,0x34,0x84,0x00,0xbb,0x34,0xa5,0x00,0xba,0x24,0x02,0x00,0x02,
+0x24,0x03,0x00,0x01,0xa0,0x82,0x00,0x00,0x08,0x00,0x24,0xc5,0xa0,0xa3,0x00,0x00,
+0x27,0xbd,0xff,0xd8,0xaf,0xb0,0x00,0x10,0x30,0xd0,0x00,0xff,0x2e,0x02,0x00,0x2e,
+0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c,
+0x30,0xb1,0x00,0xff,0x14,0x40,0x00,0x06,0x00,0x80,0x90,0x21,0x8f,0xbf,0x00,0x20,
+0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,
+0x2e,0x13,0x00,0x10,0x24,0x05,0x00,0x14,0x0c,0x00,0x13,0xa0,0x24,0x06,0x01,0x07,
+0x12,0x60,0x00,0x38,0x02,0x00,0x30,0x21,0x8f,0xa2,0x00,0x38,0x30,0xc3,0x00,0x3f,
+0x3c,0x04,0xb0,0x09,0x00,0x02,0x14,0x00,0x00,0x43,0x30,0x25,0x34,0x84,0x01,0x60,
+0x90,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xfd,0x24,0x02,0x00,0x01,
+0x12,0x22,0x00,0x2a,0x2a,0x22,0x00,0x02,0x14,0x40,0x00,0x24,0x24,0x02,0x00,0x02,
+0x12,0x22,0x00,0x20,0x24,0x02,0x00,0x03,0x12,0x22,0x00,0x19,0x00,0x00,0x00,0x00,
+0x16,0x60,0xff,0xe2,0x24,0x02,0x00,0x01,0x12,0x22,0x00,0x13,0x2a,0x22,0x00,0x02,
+0x14,0x40,0x00,0x0d,0x24,0x02,0x00,0x02,0x12,0x22,0x00,0x09,0x24,0x02,0x00,0x03,
+0x16,0x22,0xff,0xda,0x00,0x00,0x00,0x00,0x24,0x04,0x08,0x4c,0x24,0x05,0xff,0xff,
+0x0c,0x00,0x13,0x5b,0x3c,0x06,0x0c,0xb8,0x08,0x00,0x25,0x43,0x00,0x00,0x00,0x00,
+0x08,0x00,0x25,0x6b,0x24,0x04,0x08,0x48,0x16,0x20,0xff,0xd0,0x00,0x00,0x00,0x00,
+0x08,0x00,0x25,0x6b,0x24,0x04,0x08,0x40,0x08,0x00,0x25,0x6b,0x24,0x04,0x08,0x44,
+0x24,0x04,0x08,0x4c,0x0c,0x00,0x13,0x5b,0x24,0x05,0xff,0xff,0x08,0x00,0x25,0x60,
+0x00,0x00,0x00,0x00,0x08,0x00,0x25,0x79,0x24,0x04,0x08,0x48,0x16,0x20,0xff,0xe0,
+0x00,0x00,0x00,0x00,0x08,0x00,0x25,0x79,0x24,0x04,0x08,0x40,0x08,0x00,0x25,0x79,
+0x24,0x04,0x08,0x44,0x02,0x40,0x20,0x21,0x0c,0x00,0x25,0xca,0x02,0x20,0x28,0x21,
+0x08,0x00,0x25,0x4e,0x00,0x40,0x30,0x21,0x27,0xbd,0xff,0xd8,0x2c,0xc2,0x00,0x2e,
+0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x20,
+0xaf,0xb3,0x00,0x1c,0x00,0xc0,0x80,0x21,0x30,0xb1,0x00,0xff,0x00,0x80,0x90,0x21,
+0x14,0x40,0x00,0x07,0x00,0x00,0x18,0x21,0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc,
+0x7b,0xb0,0x00,0xbc,0x00,0x60,0x10,0x21,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,
+0x2e,0x13,0x00,0x10,0x24,0x05,0x00,0x14,0x0c,0x00,0x13,0xa0,0x24,0x06,0x01,0x07,
+0x12,0x60,0x00,0x24,0x02,0x00,0x30,0x21,0x3c,0x03,0xb0,0x09,0x34,0x63,0x01,0x60,
+0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xfd,0x30,0xc5,0x00,0x3f,
+0x0c,0x00,0x26,0x07,0x02,0x20,0x20,0x21,0x16,0x60,0x00,0x0a,0x00,0x40,0x80,0x21,
+0x24,0x02,0x00,0x01,0x12,0x22,0x00,0x15,0x2a,0x22,0x00,0x02,0x14,0x40,0x00,0x0f,
+0x24,0x02,0x00,0x02,0x12,0x22,0x00,0x0b,0x24,0x02,0x00,0x03,0x12,0x22,0x00,0x03,
+0x00,0x00,0x00,0x00,0x08,0x00,0x25,0x96,0x02,0x00,0x18,0x21,0x24,0x04,0x08,0x4c,
+0x24,0x05,0xff,0xff,0x0c,0x00,0x13,0x5b,0x3c,0x06,0x0c,0xb8,0x08,0x00,0x25,0x96,
+0x02,0x00,0x18,0x21,0x08,0x00,0x25,0xb8,0x24,0x04,0x08,0x48,0x16,0x20,0xff,0xf5,
+0x00,0x00,0x00,0x00,0x08,0x00,0x25,0xb8,0x24,0x04,0x08,0x40,0x08,0x00,0x25,0xb8,
+0x24,0x04,0x08,0x44,0x02,0x40,0x20,0x21,0x0c,0x00,0x25,0xca,0x02,0x20,0x28,0x21,
+0x08,0x00,0x25,0xa2,0x00,0x40,0x30,0x21,0x27,0xbd,0xff,0xe8,0x2c,0xc2,0x00,0x1f,
+0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0x00,0xc0,0x80,0x21,0x14,0x40,0x00,0x1d,
+0x30,0xa5,0x00,0xff,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x18,0x28,0xa2,0x00,0x02,
+0x14,0x40,0x00,0x12,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x0e,0x24,0x02,0x00,0x03,
+0x10,0xa2,0x00,0x07,0x24,0x04,0x08,0x4c,0x26,0x10,0xff,0xe2,0x02,0x00,0x10,0x21,
+0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,
+0x24,0x05,0xff,0xff,0x0c,0x00,0x13,0x5b,0x3c,0x06,0x0d,0xf8,0x08,0x00,0x25,0xdb,
+0x26,0x10,0xff,0xe2,0x08,0x00,0x25,0xe0,0x24,0x04,0x08,0x48,0x14,0xa0,0xff,0xf2,
+0x24,0x04,0x08,0x40,0x08,0x00,0x25,0xe1,0x24,0x05,0xff,0xff,0x08,0x00,0x25,0xe0,
+0x24,0x04,0x08,0x44,0x2c,0xc2,0x00,0x10,0x14,0x40,0xff,0xec,0x24,0x02,0x00,0x01,
+0x10,0xa2,0x00,0x14,0x28,0xa2,0x00,0x02,0x14,0x40,0x00,0x0e,0x24,0x02,0x00,0x02,
+0x10,0xa2,0x00,0x0a,0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x03,0x24,0x04,0x08,0x4c,
+0x08,0x00,0x25,0xdb,0x26,0x10,0xff,0xf1,0x24,0x05,0xff,0xff,0x0c,0x00,0x13,0x5b,
+0x3c,0x06,0x0d,0xb8,0x08,0x00,0x25,0xdb,0x26,0x10,0xff,0xf1,0x08,0x00,0x25,0xfa,
+0x24,0x04,0x08,0x48,0x14,0xa0,0xff,0xf6,0x24,0x04,0x08,0x40,0x08,0x00,0x25,0xfb,
+0x24,0x05,0xff,0xff,0x08,0x00,0x25,0xfa,0x24,0x04,0x08,0x44,0x27,0xbd,0xff,0xe8,
+0x30,0x84,0x00,0xff,0x24,0x02,0x00,0x01,0x10,0x82,0x00,0x39,0xaf,0xbf,0x00,0x10,
+0x28,0x82,0x00,0x02,0x14,0x40,0x00,0x27,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,
+0x10,0x82,0x00,0x17,0x00,0xa0,0x30,0x21,0x24,0x02,0x00,0x03,0x10,0x82,0x00,0x05,
+0x24,0x04,0x08,0x3c,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,
+0x27,0xbd,0x00,0x18,0x0c,0x00,0x13,0x5b,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x3c,
+0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5b,0x00,0x00,0x30,0x21,0x24,0x04,0x08,0x3c,
+0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x01,0x24,0x04,0x08,0xac,
+0x0c,0x00,0x13,0x3d,0x24,0x05,0x0f,0xff,0x08,0x00,0x26,0x15,0x00,0x00,0x00,0x00,
+0x24,0x04,0x08,0x34,0x0c,0x00,0x13,0x5b,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x34,
+0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5b,0x00,0x00,0x30,0x21,0x24,0x04,0x08,0x34,
+0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x01,0x08,0x00,0x26,0x24,
+0x24,0x04,0x08,0xa8,0x14,0x80,0xff,0xdf,0x00,0xa0,0x30,0x21,0x24,0x04,0x08,0x24,
+0x0c,0x00,0x13,0x5b,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x24,0x3c,0x05,0x80,0x00,
+0x0c,0x00,0x13,0x5b,0x00,0x00,0x30,0x21,0x24,0x04,0x08,0x24,0x3c,0x05,0x80,0x00,
+0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x01,0x08,0x00,0x26,0x24,0x24,0x04,0x08,0xa0,
+0x00,0xa0,0x30,0x21,0x24,0x04,0x08,0x2c,0x0c,0x00,0x13,0x5b,0x3c,0x05,0x3f,0x00,
+0x24,0x04,0x08,0x2c,0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5b,0x00,0x00,0x30,0x21,
+0x24,0x04,0x08,0x2c,0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x01,
+0x08,0x00,0x26,0x24,0x24,0x04,0x08,0xa4,0x3c,0x05,0x00,0x14,0x3c,0x02,0xb0,0x05,
+0x34,0x42,0x04,0x20,0x3c,0x06,0xc0,0x00,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,
+0x34,0xa5,0x17,0x09,0xac,0x45,0x00,0x00,0x34,0xc6,0x05,0x07,0x34,0x63,0x04,0x24,
+0x34,0x84,0x02,0x28,0x3c,0x07,0xb0,0x05,0x24,0x02,0x00,0x20,0xac,0x66,0x00,0x00,
+0x34,0xe7,0x04,0x50,0xa0,0x82,0x00,0x00,0x90,0xe2,0x00,0x00,0x00,0x00,0x00,0x00,
+0x30,0x42,0x00,0x03,0x10,0x40,0xff,0xfc,0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,
+0x00,0x00,0x00,0x00,0x93,0x85,0x81,0xf1,0x24,0x02,0x00,0x01,0x14,0xa2,0x00,0x51,
+0x00,0x80,0x40,0x21,0x8c,0x89,0x00,0x04,0x3c,0x03,0xb0,0x01,0x01,0x23,0x30,0x21,
+0x8c,0xc2,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x08,0x10,0x45,0x00,0x59,
+0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x38,0x24,0x03,0x00,0xb4,0x30,0x44,0x00,0xff,
+0x10,0x83,0x00,0x61,0x24,0x02,0x00,0xc4,0x10,0x82,0x00,0x54,0x24,0x02,0x00,0x94,
+0x10,0x82,0x00,0x45,0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x38,0x00,0x00,0x00,0x00,
+0x30,0x47,0xff,0xff,0x30,0xe3,0x40,0xff,0x24,0x02,0x40,0x88,0x14,0x62,0x00,0x39,
+0x30,0xe3,0x03,0x00,0x24,0x02,0x03,0x00,0x10,0x62,0x00,0x38,0x00,0x00,0x00,0x00,
+0x94,0xc2,0x00,0x56,0x00,0x00,0x00,0x00,0x30,0x47,0xff,0xff,0x30,0xe2,0x00,0x80,
+0x14,0x40,0x00,0x30,0x3c,0x02,0xb0,0x01,0x01,0x22,0x30,0x21,0x94,0xc3,0x00,0x60,
+0x24,0x02,0x00,0x08,0x14,0x43,0x00,0x3b,0x00,0x00,0x00,0x00,0x90,0xc2,0x00,0x62,
+0x24,0x03,0x00,0x04,0x00,0x02,0x39,0x02,0x10,0xe3,0x00,0x15,0x24,0x02,0x00,0x06,
+0x14,0xe2,0x00,0x34,0x00,0x00,0x00,0x00,0x8d,0x05,0x01,0xac,0x94,0xc4,0x00,0x66,
+0x27,0x82,0x89,0x58,0x00,0x05,0x28,0x80,0x30,0x87,0xff,0xff,0x00,0xa2,0x28,0x21,
+0x00,0x07,0x1a,0x00,0x8c,0xa4,0x00,0x00,0x00,0x07,0x12,0x02,0x00,0x43,0x10,0x25,
+0x24,0x42,0x00,0x5e,0x24,0x03,0xc0,0x00,0x30,0x47,0xff,0xff,0x00,0x83,0x20,0x24,
+0x00,0x87,0x20,0x25,0xac,0xa4,0x00,0x00,0x08,0x00,0x26,0xcd,0xad,0x07,0x00,0x10,
+0x8d,0x05,0x01,0xac,0x94,0xc4,0x00,0x64,0x27,0x82,0x89,0x58,0x00,0x05,0x28,0x80,
+0x30,0x87,0xff,0xff,0x00,0xa2,0x28,0x21,0x00,0x07,0x1a,0x00,0x8c,0xa4,0x00,0x00,
+0x00,0x07,0x12,0x02,0x00,0x43,0x10,0x25,0x24,0x42,0x00,0x36,0x3c,0x03,0xff,0xff,
+0x30,0x47,0xff,0xff,0x00,0x83,0x20,0x24,0x00,0x87,0x20,0x25,0xac,0xa4,0x00,0x00,
+0xad,0x07,0x00,0x10,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x50,
+0x08,0x00,0x26,0x8b,0x30,0x47,0xff,0xff,0x8d,0x04,0x01,0xac,0x27,0x83,0x89,0x58,
+0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x00,0x3c,0x03,0xff,0xff,
+0x00,0x43,0x10,0x24,0x34,0x42,0x00,0x2e,0xac,0x82,0x00,0x00,0x24,0x03,0x00,0x2e,
+0xad,0x03,0x00,0x10,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8d,0x04,0x01,0xac,
+0x27,0x83,0x89,0x58,0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x00,
+0x3c,0x03,0xff,0xff,0x00,0x43,0x10,0x24,0x34,0x42,0x00,0x0e,0x24,0x03,0x00,0x0e,
+0x08,0x00,0x26,0xcc,0xac,0x82,0x00,0x00,0x8d,0x04,0x01,0xac,0x27,0x83,0x89,0x58,
+0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x00,0x3c,0x03,0xff,0xff,
+0x00,0x43,0x10,0x24,0x34,0x42,0x00,0x14,0x24,0x03,0x00,0x14,0x08,0x00,0x26,0xcc,
+0xac,0x82,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xc6,0x00,0xff,
+0x00,0x06,0x48,0x40,0x01,0x26,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x8b,0xbc,0x20,
+0x27,0x83,0xbc,0x26,0x00,0x4b,0x40,0x21,0x00,0x43,0x10,0x21,0x94,0x47,0x00,0x00,
+0x30,0xa2,0x3f,0xff,0x10,0xe2,0x00,0x29,0x30,0x8a,0xff,0xff,0x95,0x02,0x00,0x02,
+0x24,0x03,0x00,0x01,0x00,0x02,0x11,0x82,0x30,0x42,0x00,0x01,0x10,0x43,0x00,0x18,
+0x00,0x00,0x00,0x00,0x01,0x26,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x4b,0x30,0x21,
+0x94,0xc4,0x00,0x02,0x27,0x83,0xbc,0x26,0x27,0x85,0xbc,0x24,0x00,0x45,0x28,0x21,
+0x30,0x84,0xff,0xdf,0x00,0x43,0x10,0x21,0xa4,0xc4,0x00,0x02,0xa4,0x40,0x00,0x00,
+0xa4,0xa0,0x00,0x00,0x94,0xc3,0x00,0x02,0x3c,0x04,0xb0,0x01,0x01,0x44,0x20,0x21,
+0x30,0x63,0xff,0xbf,0xa4,0xc3,0x00,0x02,0xa0,0xc0,0x00,0x00,0x8c,0x82,0x00,0x04,
+0x24,0x03,0xf0,0xff,0x00,0x43,0x10,0x24,0x03,0xe0,0x00,0x08,0xac,0x82,0x00,0x04,
+0x24,0x02,0xc0,0x00,0x91,0x04,0x00,0x01,0x00,0xa2,0x10,0x24,0x00,0x47,0x28,0x25,
+0x3c,0x03,0xb0,0x01,0x24,0x02,0x00,0x02,0x14,0x82,0xff,0xe2,0x01,0x43,0x18,0x21,
+0xac,0x65,0x00,0x00,0x08,0x00,0x26,0xfa,0x01,0x26,0x10,0x21,0x08,0x00,0x26,0xfa,
+0x01,0x26,0x10,0x21,0x93,0x83,0x81,0xf1,0x24,0x02,0x00,0x01,0x14,0x62,0x00,0x0d,
+0x3c,0x02,0xb0,0x01,0x8c,0x84,0x00,0x04,0x3c,0x06,0xb0,0x09,0x00,0x82,0x20,0x21,
+0x8c,0x85,0x00,0x08,0x8c,0x83,0x00,0x04,0x3c,0x02,0x01,0x00,0x34,0xc6,0x01,0x00,
+0x00,0x62,0x18,0x24,0x14,0x60,0x00,0x05,0x30,0xa5,0x20,0x00,0x24,0x02,0x00,0x06,
+0xa0,0xc2,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x09,
+0x10,0xa0,0xff,0xfc,0x34,0x63,0x01,0x00,0x24,0x02,0x00,0x0e,0x08,0x00,0x27,0x2d,
+0xa0,0x62,0x00,0x00,0x3c,0x02,0xb0,0x01,0x30,0xa5,0xff,0xff,0x00,0xa2,0x28,0x21,
+0x8c,0xa3,0x00,0x00,0x3c,0x02,0x10,0x00,0x00,0x80,0x30,0x21,0x00,0x62,0x18,0x24,
+0x8c,0xa2,0x00,0x04,0x10,0x60,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x42,0x80,0x00,
+0x10,0x40,0x00,0x13,0x00,0x00,0x00,0x00,0x8c,0xc2,0x01,0xa8,0x00,0x00,0x00,0x00,
+0x24,0x44,0x00,0x01,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40,0x00,0x83,0x10,0x0a,
+0x93,0x83,0x81,0xf0,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x82,0x20,0x23,
+0x24,0x63,0xff,0xff,0xac,0xc4,0x01,0xa8,0xa3,0x83,0x81,0xf0,0x8c,0xc4,0x01,0xac,
+0x8c,0xc2,0x01,0xa8,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x26,0x00,0x02,0x10,0x2b,
+0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x73,
+0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x04,
+0x00,0x00,0x00,0x00,0xa3,0x80,0x81,0xf1,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
+0x24,0x02,0x00,0x01,0xa3,0x82,0x81,0xf1,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
+0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xa8,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,
+0x30,0x62,0x00,0xff,0x00,0x03,0x2e,0x02,0x00,0x02,0x39,0x80,0x2c,0xa2,0x00,0x02,
+0x00,0x03,0x34,0x02,0x10,0x40,0x00,0x05,0x00,0x03,0x1a,0x02,0xa4,0x87,0x01,0xd8,
+0xa0,0x85,0x01,0xd4,0xa0,0x86,0x01,0xd5,0xa0,0x83,0x01,0xd6,0x03,0xe0,0x00,0x08,
+0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x04,0x3c,0x05,0xb0,0x01,0x00,0x80,0x50,0x21,
+0x00,0x45,0x10,0x21,0x8c,0x43,0x00,0x04,0x24,0x02,0x00,0x05,0x00,0x03,0x1a,0x02,
+0x30,0x69,0x00,0x0f,0x11,0x22,0x00,0x0b,0x24,0x02,0x00,0x07,0x11,0x22,0x00,0x09,
+0x24,0x02,0x00,0x0a,0x11,0x22,0x00,0x07,0x24,0x02,0x00,0x0b,0x11,0x22,0x00,0x05,
+0x24,0x02,0x00,0x01,0x93,0x83,0x81,0xf0,0x3c,0x04,0xb0,0x06,0x10,0x62,0x00,0x03,
+0x34,0x84,0x80,0x18,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x02,0x14,0x40,0xff,0xfa,0x00,0x00,0x00,0x00,
+0x8d,0x43,0x01,0xa8,0x27,0x82,0x89,0x58,0x00,0x03,0x18,0x80,0x00,0x6a,0x20,0x21,
+0x8c,0x87,0x00,0xa8,0x00,0x62,0x18,0x21,0x8c,0x68,0x00,0x00,0x00,0xe5,0x28,0x21,
+0x8c,0xa9,0x00,0x00,0x3c,0x02,0xff,0xff,0x27,0x83,0x8a,0x58,0x01,0x22,0x10,0x24,
+0x00,0x48,0x10,0x25,0xac,0xa2,0x00,0x00,0x8d,0x44,0x01,0xa8,0x00,0x07,0x30,0xc2,
+0x3c,0x02,0x00,0x80,0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x00,0x06,0x32,0x00,
+0x8c,0xa9,0x00,0x04,0x00,0xc2,0x30,0x25,0x8c,0x82,0x00,0x00,0x3c,0x03,0x80,0x00,
+0x01,0x22,0x10,0x25,0x00,0x43,0x10,0x25,0xac,0xa2,0x00,0x04,0xaf,0x87,0xbc,0x10,
+0x8c,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x82,0xbc,0x18,0x8c,0xa3,0x00,0x04,
+0x3c,0x01,0xb0,0x07,0xac,0x26,0x80,0x18,0x8d,0x42,0x01,0xa8,0xaf,0x83,0xbc,0x14,
+0x93,0x85,0x81,0xf0,0x24,0x44,0x00,0x01,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40,
+0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x24,0xa5,0xff,0xff,
+0x00,0x82,0x20,0x23,0xad,0x44,0x01,0xa8,0xa3,0x85,0x81,0xf0,0x08,0x00,0x27,0x89,
+0x00,0x00,0x00,0x00,0x3c,0x05,0xb0,0x03,0x3c,0x02,0x80,0x01,0x24,0x42,0x9f,0x04,
+0x34,0xa5,0x00,0x20,0xac,0xa2,0x00,0x00,0x24,0x02,0x00,0x02,0x24,0x03,0x00,0x20,
+0xac,0x82,0x00,0x64,0x3c,0x02,0x80,0x01,0xac,0x83,0x00,0x60,0x00,0x80,0x38,0x21,
+0xac,0x80,0x00,0x00,0xac,0x80,0x00,0x04,0xac,0x80,0x00,0x08,0xac,0x80,0x00,0x4c,
+0xac,0x80,0x00,0x50,0xac,0x80,0x00,0x54,0xac,0x80,0x00,0x0c,0xac,0x80,0x00,0x58,
+0xa0,0x80,0x00,0x5c,0x24,0x83,0x00,0x68,0x24,0x42,0xa0,0x14,0x24,0x04,0x00,0x0f,
+0x24,0x84,0xff,0xff,0xac,0x62,0x00,0x00,0x04,0x81,0xff,0xfd,0x24,0x63,0x00,0x04,
+0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xa8,0xac,0xe0,0x01,0xa8,0xac,0xe0,0x01,0xac,
+0xac,0xe0,0x01,0xb0,0xac,0xe0,0x01,0xb4,0xa0,0xe0,0x01,0xb8,0xa0,0xe0,0x01,0xb9,
+0xa0,0xe0,0x01,0xba,0xa0,0xe0,0x01,0xc0,0xa0,0xe0,0x01,0xc1,0xac,0xe0,0x01,0xc4,
+0xac,0xe0,0x01,0xc8,0xac,0xe0,0x01,0xcc,0xac,0xe0,0x01,0xd0,0x8c,0x44,0x00,0x00,
+0x3c,0x02,0x80,0x01,0x24,0x42,0xa0,0xfc,0x30,0x83,0x00,0xff,0x00,0x03,0x19,0x80,
+0xa4,0xe3,0x01,0xd8,0xac,0xe2,0x00,0x78,0x3c,0x03,0x80,0x01,0x3c,0x02,0x80,0x01,
+0x24,0x63,0xa2,0x88,0x24,0x42,0xa1,0xf4,0xac,0xe3,0x00,0x88,0xac,0xe2,0x00,0x98,
+0x3c,0x03,0x80,0x01,0x3c,0x02,0x80,0x01,0x00,0x04,0x2e,0x03,0x00,0x04,0x34,0x03,
+0x24,0x63,0xa3,0x30,0x00,0x04,0x22,0x03,0x24,0x42,0xa4,0x74,0xac,0xe3,0x00,0xa0,
+0xac,0xe2,0x00,0xa4,0xa0,0xe5,0x01,0xd4,0xa0,0xe6,0x01,0xd5,0x03,0xe0,0x00,0x08,
+0xa0,0xe4,0x01,0xd6,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,0x34,0x63,0x00,0x20,
+0x24,0x42,0xa0,0x14,0x03,0xe0,0x00,0x08,0xac,0x62,0x00,0x00,0x3c,0x02,0xb0,0x03,
+0x3c,0x03,0x80,0x01,0x34,0x42,0x00,0x20,0x24,0x63,0xa0,0x2c,0xac,0x43,0x00,0x00,
+0x8c,0x82,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x11,0x00,0x80,0x28,0x21,
+0x8c,0x82,0x00,0x14,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0d,0x00,0x00,0x00,0x00,
+0x8c,0x84,0x00,0x10,0x8c,0xa3,0x00,0x14,0x8c,0xa2,0x00,0x04,0x00,0x83,0x20,0x21,
+0x00,0x44,0x10,0x21,0x30,0x43,0x00,0xff,0x00,0x03,0x18,0x2b,0x00,0x02,0x12,0x02,
+0x00,0x43,0x10,0x21,0x00,0x02,0x12,0x00,0x30,0x42,0x3f,0xff,0xac,0xa2,0x00,0x04,
+0xac,0xa0,0x00,0x00,0xac,0xa0,0x00,0x4c,0xac,0xa0,0x00,0x50,0xac,0xa0,0x00,0x54,
+0x03,0xe0,0x00,0x08,0xac,0xa0,0x00,0x0c,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,
+0x34,0x63,0x00,0x20,0x24,0x42,0xa0,0xa8,0xac,0x62,0x00,0x00,0x8c,0x86,0x00,0x04,
+0x3c,0x02,0xb0,0x01,0x24,0x03,0x00,0x01,0x00,0xc2,0x10,0x21,0x8c,0x45,0x00,0x00,
+0xac,0x83,0x00,0x4c,0x00,0x05,0x14,0x02,0x30,0xa3,0x3f,0xff,0x30,0x42,0x00,0xff,
+0xac,0x83,0x00,0x10,0xac,0x82,0x00,0x14,0x8c,0x83,0x00,0x14,0xac,0x85,0x00,0x40,
+0x00,0xc3,0x30,0x21,0x03,0xe0,0x00,0x08,0xac,0x86,0x00,0x08,0x3c,0x02,0xb0,0x03,
+0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,0x24,0x63,0xa0,0xfc,
+0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x4c,
+0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0a,0x00,0x80,0x80,0x21,0xae,0x00,0x00,0x00,
+0xae,0x00,0x00,0x4c,0xae,0x00,0x00,0x50,0xae,0x00,0x00,0x54,0xae,0x00,0x00,0x0c,
+0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,
+0x0c,0x00,0x28,0x2a,0x00,0x00,0x00,0x00,0x08,0x00,0x28,0x4c,0xae,0x00,0x00,0x00,
+0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,
+0x24,0x63,0xa1,0x60,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,
+0x8c,0x82,0x00,0x4c,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x16,0x00,0x80,0x80,0x21,
+0x8e,0x03,0x00,0x08,0x3c,0x02,0xb0,0x01,0x8e,0x04,0x00,0x44,0x00,0x62,0x18,0x21,
+0x90,0x65,0x00,0x00,0x24,0x02,0x00,0x01,0xae,0x02,0x00,0x50,0x30,0xa3,0x00,0xff,
+0x00,0x03,0x10,0x82,0x00,0x04,0x23,0x02,0x30,0x84,0x00,0x0f,0x30,0x42,0x00,0x03,
+0x00,0x03,0x19,0x02,0xae,0x04,0x00,0x34,0xae,0x02,0x00,0x2c,0xae,0x03,0x00,0x30,
+0xa2,0x05,0x00,0x48,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,
+0x27,0xbd,0x00,0x18,0x0c,0x00,0x28,0x2a,0x00,0x00,0x00,0x00,0x08,0x00,0x28,0x64,
+0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,
+0x34,0x42,0x00,0x20,0x24,0x63,0xa1,0xf4,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,
+0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x50,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x16,
+0x00,0x80,0x80,0x21,0x92,0x03,0x00,0x44,0x8e,0x02,0x00,0x40,0x83,0x85,0x8b,0xc4,
+0x92,0x04,0x00,0x41,0x30,0x63,0x00,0x01,0x00,0x02,0x16,0x02,0xae,0x04,0x00,0x14,
+0x00,0x00,0x30,0x21,0xae,0x02,0x00,0x18,0x10,0xa0,0x00,0x04,0xae,0x03,0x00,0x3c,
+0x10,0x60,0x00,0x03,0x24,0x02,0x00,0x01,0x24,0x06,0x00,0x01,0x24,0x02,0x00,0x01,
+0xa3,0x86,0x8b,0xc4,0x8f,0xbf,0x00,0x14,0xae,0x02,0x00,0x54,0x8f,0xb0,0x00,0x10,
+0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x28,0x58,0x00,0x00,0x00,0x00,
+0x08,0x00,0x28,0x89,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,
+0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,0x24,0x63,0xa2,0x88,0xaf,0xb0,0x00,0x10,
+0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x50,0x00,0x00,0x00,0x00,
+0x10,0x40,0x00,0x1b,0x00,0x80,0x80,0x21,0x3c,0x02,0xb0,0x03,0x8c,0x42,0x00,0x00,
+0x92,0x04,0x00,0x44,0x8e,0x03,0x00,0x40,0x83,0x86,0x8b,0xc4,0x92,0x05,0x00,0x41,
+0x30,0x42,0x08,0x00,0x30,0x84,0x00,0x01,0x00,0x02,0x12,0xc2,0x00,0x03,0x1e,0x02,
+0x00,0x82,0x20,0x25,0xae,0x05,0x00,0x14,0x00,0x00,0x38,0x21,0xae,0x03,0x00,0x18,
+0x10,0xc0,0x00,0x04,0xae,0x04,0x00,0x3c,0x10,0x80,0x00,0x03,0x24,0x02,0x00,0x01,
+0x24,0x07,0x00,0x01,0x24,0x02,0x00,0x01,0xa3,0x87,0x8b,0xc4,0x8f,0xbf,0x00,0x14,
+0xae,0x02,0x00,0x54,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,
+0x0c,0x00,0x28,0x58,0x00,0x00,0x00,0x00,0x08,0x00,0x28,0xae,0x00,0x00,0x00,0x00,
+0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,
+0x24,0x63,0xa3,0x30,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,
+0x8c,0x82,0x00,0x54,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x42,0x00,0x80,0x80,0x21,
+0x8e,0x04,0x00,0x04,0x8e,0x03,0x00,0x44,0x3c,0x02,0x80,0x00,0x3c,0x08,0xb0,0x01,
+0x34,0x42,0x00,0x10,0x00,0x88,0x20,0x21,0x00,0x62,0x18,0x25,0xac,0x83,0x00,0x04,
+0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac,0x27,0x89,0x89,0x58,0x00,0x48,0x10,0x21,
+0x8c,0x45,0x00,0x00,0x00,0x03,0x18,0x80,0x00,0x69,0x18,0x21,0xac,0x65,0x00,0x00,
+0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac,0x27,0x87,0x8a,0x58,0x00,0x48,0x10,0x21,
+0x8c,0x45,0x00,0x04,0x00,0x03,0x18,0x80,0x00,0x67,0x18,0x21,0xac,0x65,0x00,0x00,
+0x8e,0x02,0x01,0xac,0x8e,0x06,0x00,0x04,0x02,0x00,0x20,0x21,0x00,0x02,0x10,0x80,
+0x00,0x47,0x38,0x21,0x94,0xe3,0x00,0x02,0x00,0x49,0x10,0x21,0x90,0x45,0x00,0x00,
+0x00,0x03,0x1a,0x00,0x00,0xc8,0x30,0x21,0x00,0xa3,0x28,0x25,0x0c,0x00,0x26,0x69,
+0xa4,0xc5,0x00,0x2e,0x8e,0x03,0x01,0xac,0x8e,0x07,0x00,0x04,0x3c,0x06,0xb0,0x03,
+0x24,0x65,0x00,0x01,0x28,0xa4,0x00,0x00,0x24,0x62,0x00,0x40,0x00,0xa4,0x10,0x0a,
+0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x03,0x18,0x80,0x00,0xa2,0x28,0x23,
+0x00,0x70,0x18,0x21,0xae,0x05,0x01,0xac,0xac,0x67,0x00,0xa8,0x34,0xc6,0x00,0x30,
+0x8c,0xc3,0x00,0x00,0x93,0x82,0x81,0xf0,0x02,0x00,0x20,0x21,0x24,0x63,0x00,0x01,
+0x24,0x42,0x00,0x01,0xac,0xc3,0x00,0x00,0xa3,0x82,0x81,0xf0,0x0c,0x00,0x28,0x0b,
+0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,
+0x27,0xbd,0x00,0x18,0x0c,0x00,0x28,0xa2,0x00,0x00,0x00,0x00,0x08,0x00,0x28,0xd8,
+0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,
+0x34,0x42,0x00,0x20,0x24,0x63,0xa4,0x74,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,
+0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x54,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x42,
+0x00,0x80,0x80,0x21,0x8e,0x04,0x00,0x04,0x8e,0x03,0x00,0x44,0x3c,0x02,0x80,0x00,
+0x3c,0x08,0xb0,0x01,0x34,0x42,0x00,0x10,0x00,0x88,0x20,0x21,0x00,0x62,0x18,0x25,
+0xac,0x83,0x00,0x04,0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac,0x27,0x89,0x89,0x58,
+0x00,0x48,0x10,0x21,0x8c,0x45,0x00,0x00,0x00,0x03,0x18,0x80,0x00,0x69,0x18,0x21,
+0xac,0x65,0x00,0x00,0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac,0x27,0x87,0x8a,0x58,
+0x00,0x48,0x10,0x21,0x8c,0x45,0x00,0x04,0x00,0x03,0x18,0x80,0x00,0x67,0x18,0x21,
+0xac,0x65,0x00,0x00,0x8e,0x02,0x01,0xac,0x8e,0x06,0x00,0x04,0x02,0x00,0x20,0x21,
+0x00,0x02,0x10,0x80,0x00,0x47,0x38,0x21,0x94,0xe3,0x00,0x02,0x00,0x49,0x10,0x21,
+0x90,0x45,0x00,0x00,0x00,0x03,0x1a,0x00,0x00,0xc8,0x30,0x21,0x00,0xa3,0x28,0x25,
+0x0c,0x00,0x26,0x69,0xa4,0xc5,0x00,0x2e,0x8e,0x03,0x01,0xac,0x8e,0x07,0x00,0x04,
+0x3c,0x06,0xb0,0x03,0x24,0x65,0x00,0x01,0x28,0xa4,0x00,0x00,0x24,0x62,0x00,0x40,
+0x00,0xa4,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x03,0x18,0x80,
+0x00,0xa2,0x28,0x23,0x00,0x70,0x18,0x21,0xae,0x05,0x01,0xac,0xac,0x67,0x00,0xa8,
+0x34,0xc6,0x00,0x30,0x8c,0xc3,0x00,0x00,0x93,0x82,0x81,0xf0,0x02,0x00,0x20,0x21,
+0x24,0x63,0x00,0x01,0x24,0x42,0x00,0x01,0xac,0xc3,0x00,0x00,0xa3,0x82,0x81,0xf0,
+0x0c,0x00,0x28,0x0b,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,
+0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x28,0xa2,0x00,0x00,0x00,0x00,
+0x08,0x00,0x29,0x29,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,
+0x27,0xbd,0xff,0xd8,0x34,0x42,0x00,0x20,0x24,0x63,0xa5,0xb8,0xaf,0xb2,0x00,0x18,
+0xac,0x43,0x00,0x00,0x3c,0x12,0xb0,0x03,0x3c,0x02,0x80,0x01,0xaf,0xb4,0x00,0x20,
+0xaf,0xb3,0x00,0x1c,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x24,
+0x00,0x80,0x80,0x21,0x24,0x54,0xa0,0x14,0x00,0x00,0x88,0x21,0x3c,0x13,0xb0,0x01,
+0x36,0x52,0x00,0xef,0x3c,0x02,0xb0,0x09,0x34,0x42,0x00,0x06,0x90,0x43,0x00,0x00,
+0x8e,0x04,0x00,0x04,0x92,0x02,0x01,0xbb,0x30,0x69,0x00,0xff,0x00,0x04,0x42,0x02,
+0x10,0x40,0x00,0x1e,0x00,0x00,0x38,0x21,0x8e,0x03,0x01,0xa8,0x3c,0x06,0x28,0x38,
+0x34,0xc6,0x00,0x20,0x24,0x64,0x00,0x3d,0x28,0x82,0x00,0x00,0x24,0x63,0x00,0x7c,
+0x00,0x82,0x18,0x0a,0x00,0x03,0x19,0x83,0x00,0x03,0x19,0x80,0x00,0x83,0x20,0x23,
+0x00,0x04,0x10,0x80,0x00,0x50,0x10,0x21,0x8c,0x45,0x00,0xa8,0xae,0x04,0x01,0xac,
+0xae,0x04,0x01,0xa8,0x00,0xb3,0x18,0x21,0xae,0x05,0x00,0x04,0xac,0x66,0x00,0x00,
+0x8e,0x02,0x00,0x04,0x3c,0x03,0x80,0x00,0x34,0x63,0x4e,0x00,0x00,0x53,0x10,0x21,
+0xac,0x43,0x00,0x04,0xa2,0x00,0x01,0xbb,0x93,0x83,0x81,0xf7,0x00,0x00,0x00,0x00,
+0x24,0x62,0x00,0x01,0xa3,0x82,0x81,0xf7,0xa2,0x43,0x00,0x00,0x01,0x28,0x10,0x23,
+0x24,0x44,0x00,0x40,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x7f,0x00,0x83,0x10,0x0a,
+0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x24,0x84,0xff,0xff,0x10,0x44,0x00,0x6b,
+0x3c,0x02,0xb0,0x01,0x8e,0x03,0x00,0x04,0x3c,0x04,0x7c,0x00,0x00,0x62,0x18,0x21,
+0x8c,0x65,0x00,0x04,0x34,0x84,0x00,0xf0,0x00,0x00,0x30,0x21,0xae,0x05,0x00,0x44,
+0x00,0xa4,0x20,0x24,0x8c,0x63,0x00,0x00,0x10,0x80,0x00,0x6b,0x3c,0x02,0xff,0xff,
+0x3c,0x09,0xb0,0x03,0x3c,0x05,0x7c,0x00,0x35,0x29,0x00,0x99,0x3c,0x0a,0xb0,0x01,
+0x24,0x08,0x00,0x40,0x34,0xa5,0x00,0xf0,0x3c,0x0b,0xff,0xff,0x3c,0x0c,0x28,0x38,
+0x16,0x20,0x00,0x06,0x24,0xe7,0x00,0x01,0x93,0x82,0x81,0xf6,0x24,0x11,0x00,0x01,
+0x24,0x42,0x00,0x01,0xa1,0x22,0x00,0x00,0xa3,0x82,0x81,0xf6,0x8e,0x02,0x00,0x04,
+0x24,0x06,0x00,0x01,0x24,0x42,0x01,0x00,0x30,0x42,0x3f,0xff,0xae,0x02,0x00,0x04,
+0x00,0x4a,0x10,0x21,0x8c,0x43,0x00,0x04,0x00,0x00,0x00,0x00,0xae,0x03,0x00,0x44,
+0x00,0x65,0x20,0x24,0x8c,0x43,0x00,0x00,0x10,0xe8,0x00,0x2d,0x00,0x00,0x00,0x00,
+0x14,0x80,0xff,0xeb,0x00,0x6b,0x10,0x24,0x14,0x4c,0xff,0xe9,0x24,0x02,0x00,0x01,
+0x10,0xc2,0x00,0x30,0x3c,0x03,0xb0,0x09,0x8e,0x02,0x00,0x44,0x8e,0x04,0x00,0x60,
+0x00,0x02,0x1e,0x42,0x00,0x02,0x12,0x02,0x30,0x42,0x00,0x0f,0x30,0x63,0x00,0x01,
+0xae,0x02,0x00,0x00,0x10,0x44,0x00,0x1a,0xae,0x03,0x00,0x58,0x8e,0x02,0x00,0x64,
+0x8e,0x04,0x00,0x58,0x00,0x00,0x00,0x00,0x10,0x82,0x00,0x05,0x00,0x00,0x00,0x00,
+0xae,0x00,0x00,0x4c,0xae,0x00,0x00,0x50,0xae,0x00,0x00,0x54,0xae,0x00,0x00,0x0c,
+0x8e,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0x80,0x00,0x50,0x10,0x21,
+0x8c,0x42,0x00,0x68,0x00,0x00,0x00,0x00,0x10,0x54,0x00,0x06,0x00,0x00,0x00,0x00,
+0x00,0x40,0xf8,0x09,0x02,0x00,0x20,0x21,0x8e,0x04,0x00,0x58,0x8e,0x03,0x00,0x00,
+0x00,0x00,0x00,0x00,0xae,0x03,0x00,0x60,0x08,0x00,0x29,0x81,0xae,0x04,0x00,0x64,
+0x8e,0x02,0x00,0x64,0x00,0x00,0x00,0x00,0x14,0x62,0xff,0xe5,0x00,0x00,0x00,0x00,
+0x7a,0x02,0x0d,0x7c,0x8f,0xbf,0x00,0x24,0x8f,0xb4,0x00,0x20,0x7b,0xb2,0x00,0xfc,
+0x7b,0xb0,0x00,0xbc,0x00,0x43,0x10,0x26,0x00,0x02,0x10,0x2b,0x03,0xe0,0x00,0x08,
+0x27,0xbd,0x00,0x28,0x8e,0x04,0x00,0x04,0x34,0x63,0x00,0x06,0x90,0x62,0x00,0x00,
+0x00,0x04,0x42,0x02,0x00,0x48,0x10,0x23,0x24,0x44,0x00,0x40,0x28,0x83,0x00,0x00,
+0x24,0x42,0x00,0x7f,0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,
+0x00,0x82,0x20,0x23,0x14,0x86,0xff,0xc4,0x00,0x00,0x00,0x00,0x8e,0x03,0x00,0x00,
+0x00,0x00,0x00,0x00,0x2c,0x62,0x00,0x03,0x14,0x40,0x00,0x05,0x24,0x02,0x00,0x0d,
+0x10,0x62,0x00,0x03,0x24,0x02,0x00,0x01,0x08,0x00,0x2a,0x04,0xa2,0x02,0x00,0x5c,
+0x08,0x00,0x2a,0x04,0xa2,0x00,0x00,0x5c,0x00,0x62,0x10,0x24,0x3c,0x03,0x28,0x38,
+0x14,0x43,0xff,0x93,0x24,0x02,0x00,0x01,0x08,0x00,0x29,0xdc,0x00,0x00,0x00,0x00,
+0x3c,0x02,0xb0,0x01,0x00,0xa2,0x40,0x21,0x00,0xa0,0x48,0x21,0x8d,0x05,0x00,0x00,
+0x24,0x02,0xc0,0x00,0x00,0x09,0x38,0xc2,0x00,0xa2,0x28,0x24,0x24,0xc2,0xff,0xff,
+0x00,0x07,0x3a,0x00,0x3c,0x0a,0xb0,0x06,0x3c,0x03,0x00,0x80,0x00,0xa6,0x28,0x25,
+0x2c,0x42,0x1f,0xff,0x00,0xe3,0x38,0x25,0x35,0x4a,0x80,0x18,0x10,0x40,0x00,0x0e,
+0xad,0x05,0x00,0x00,0xaf,0x89,0xbc,0x10,0x8d,0x02,0x00,0x00,0x00,0x00,0x00,0x00,
+0xaf,0x82,0xbc,0x18,0x8d,0x03,0x00,0x04,0xad,0x47,0x00,0x00,0xaf,0x83,0xbc,0x14,
+0xac,0x80,0x01,0xd0,0xac,0x80,0x01,0xc4,0xa0,0x80,0x01,0xc0,0xa0,0x80,0x01,0xc1,
+0xac,0x80,0x01,0xc8,0xac,0x80,0x01,0xcc,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
+0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,0x8c,0x83,0x01,0xc4,0x00,0x80,0x38,0x21,
+0x90,0x84,0x01,0xc0,0x00,0x03,0x18,0x80,0x00,0x67,0x18,0x21,0x8c,0x65,0x00,0xa8,
+0x3c,0x02,0xb0,0x01,0x24,0x03,0x00,0x01,0x00,0xa2,0x10,0x21,0x8c,0x42,0x00,0x00,
+0x10,0x83,0x00,0x18,0x00,0x02,0x14,0x02,0x8c,0xe9,0x01,0xcc,0x8c,0xea,0x01,0xc8,
+0x30,0x46,0x00,0xff,0x01,0x2a,0x18,0x21,0x30,0x64,0x00,0xff,0x00,0x03,0x1a,0x02,
+0x24,0x62,0x00,0x01,0x14,0x80,0x00,0x02,0x30,0x48,0x00,0xff,0x30,0x68,0x00,0xff,
+0x90,0xe2,0x01,0xc1,0x00,0x00,0x00,0x00,0x00,0x48,0x10,0x23,0x00,0x02,0x12,0x00,
+0x00,0x49,0x10,0x21,0x00,0x4a,0x10,0x21,0x00,0x46,0x30,0x23,0x0c,0x00,0x2a,0x2c,
+0x00,0xe0,0x20,0x21,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,
+0x27,0xbd,0x00,0x18,0x8c,0xe6,0x01,0xc8,0x08,0x00,0x2a,0x6b,0x00,0x00,0x00,0x00,
+0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x14,0xaf,0xb0,0x00,0x10,0x8c,0x82,0x01,0xc4,
+0x90,0x87,0x01,0xc1,0x00,0x80,0x80,0x21,0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,
+0x8c,0x48,0x00,0xa8,0x3c,0x02,0xb0,0x01,0x00,0x07,0x3a,0x00,0x01,0x02,0x10,0x21,
+0x8c,0x43,0x00,0x00,0x00,0xe5,0x38,0x21,0x00,0xe6,0x38,0x21,0x00,0x03,0x1c,0x02,
+0x30,0x63,0x00,0xff,0x00,0xe3,0x38,0x23,0x01,0x00,0x28,0x21,0x0c,0x00,0x2a,0x2c,
+0x00,0xe0,0x30,0x21,0x8e,0x02,0x01,0xa8,0x8f,0xbf,0x00,0x14,0x24,0x44,0x00,0x01,
+0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40,0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,
+0x00,0x02,0x11,0x80,0x00,0x82,0x20,0x23,0xae,0x04,0x01,0xa8,0x8f,0xb0,0x00,0x10,
+0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,
+0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,0x24,0x63,0xaa,0x58,0xaf,0xb0,0x00,0x10,
+0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,0x90,0x82,0x01,0xd4,0x00,0x00,0x00,0x00,
+0x14,0x40,0x00,0x6a,0x00,0x80,0x80,0x21,0x90,0x82,0x01,0xc0,0x00,0x00,0x00,0x00,
+0x14,0x40,0x00,0x61,0x00,0x00,0x00,0x00,0x8c,0x83,0x01,0xa8,0x8c,0x82,0x01,0xac,
+0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x22,0x00,0x00,0x28,0x21,0x93,0x82,0x81,0xf1,
+0x00,0x03,0x30,0x80,0x00,0xc4,0x18,0x21,0x24,0x04,0x00,0x01,0x8c,0x67,0x00,0xa8,
+0x10,0x44,0x00,0x20,0x3c,0x04,0xb0,0x01,0xaf,0x87,0xbc,0x10,0x00,0xe4,0x20,0x21,
+0x8c,0x86,0x00,0x00,0x00,0x07,0x18,0xc2,0x3c,0x02,0x00,0x80,0xaf,0x86,0xbc,0x18,
+0x8c,0x86,0x00,0x04,0x00,0x03,0x1a,0x00,0x3c,0x05,0xb0,0x06,0x00,0x62,0x18,0x25,
+0x34,0xa5,0x80,0x18,0xac,0xa3,0x00,0x00,0x8e,0x02,0x01,0xa8,0x8e,0x09,0x01,0xac,
+0xaf,0x86,0xbc,0x14,0x24,0x44,0x00,0x01,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40,
+0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x82,0x20,0x23,
+0x00,0x80,0x30,0x21,0xae,0x04,0x01,0xa8,0x00,0xc9,0x10,0x26,0x00,0x02,0x28,0x2b,
+0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x00,0xa0,0x10,0x21,0x03,0xe0,0x00,0x08,
+0x27,0xbd,0x00,0x18,0x93,0x82,0x81,0xf0,0x00,0x00,0x00,0x00,0x2c,0x42,0x00,0x02,
+0x14,0x40,0xff,0xf7,0x00,0x00,0x28,0x21,0x3c,0x05,0xb0,0x01,0x00,0xe5,0x28,0x21,
+0x27,0x83,0x89,0x58,0x00,0xc3,0x18,0x21,0x8c,0xa6,0x00,0x00,0x8c,0x64,0x00,0x00,
+0x24,0x02,0xc0,0x00,0x00,0xc2,0x10,0x24,0x00,0x44,0x10,0x25,0xac,0xa2,0x00,0x00,
+0x8e,0x03,0x01,0xa8,0x27,0x84,0x8a,0x58,0x8c,0xa6,0x00,0x04,0x00,0x03,0x18,0x80,
+0x00,0x64,0x18,0x21,0x8c,0x62,0x00,0x00,0x3c,0x03,0x80,0x00,0x00,0x07,0x20,0xc2,
+0x00,0xc2,0x10,0x25,0x00,0x43,0x10,0x25,0xac,0xa2,0x00,0x04,0xaf,0x87,0xbc,0x10,
+0x8c,0xa6,0x00,0x00,0x3c,0x02,0x00,0x80,0x00,0x04,0x22,0x00,0x3c,0x03,0xb0,0x06,
+0xaf,0x86,0xbc,0x18,0x00,0x82,0x20,0x25,0x34,0x63,0x80,0x18,0x8c,0xa6,0x00,0x04,
+0xac,0x64,0x00,0x00,0x8e,0x02,0x01,0xa8,0xaf,0x86,0xbc,0x14,0x24,0x44,0x00,0x01,
+0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40,0x00,0x83,0x10,0x0a,0x93,0x83,0x81,0xf0,
+0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x82,0x20,0x23,0x24,0x63,0xff,0xff,
+0xae,0x04,0x01,0xa8,0xa3,0x83,0x81,0xf0,0x8e,0x04,0x01,0xac,0x8e,0x02,0x01,0xa8,
+0x08,0x00,0x2a,0xcb,0x00,0x44,0x10,0x26,0x0c,0x00,0x2a,0x4c,0x00,0x00,0x00,0x00,
+0x7a,0x02,0x0d,0x7c,0x08,0x00,0x2a,0xcb,0x00,0x43,0x10,0x26,0x8c,0x86,0x01,0xa8,
+0x8c,0x89,0x01,0xac,0x00,0x00,0x00,0x00,0x10,0xc9,0x00,0xb4,0x00,0xc0,0x68,0x21,
+0x00,0x06,0x10,0x80,0x27,0x83,0x89,0x58,0x00,0x43,0x18,0x21,0x00,0x44,0x10,0x21,
+0x8c,0x47,0x00,0xa8,0x94,0x65,0x00,0x02,0x3c,0x02,0xb0,0x01,0x00,0xe2,0x10,0x21,
+0x30,0xa5,0x3f,0xff,0xa4,0x45,0x00,0x2c,0x90,0x8a,0x01,0xc0,0x00,0x00,0x00,0x00,
+0x11,0x40,0x00,0x0c,0x00,0x07,0x32,0x02,0x8c,0x83,0x01,0xc4,0x90,0x85,0x01,0xc1,
+0x00,0x03,0x18,0x80,0x00,0x64,0x18,0x21,0x8c,0x62,0x00,0xa8,0x00,0x00,0x00,0x00,
+0x00,0x02,0x12,0x02,0x00,0x45,0x10,0x21,0x30,0x42,0x00,0x3f,0x14,0xc2,0xff,0xde,
+0x00,0x00,0x00,0x00,0x3c,0x04,0xb0,0x01,0x00,0xe4,0x40,0x21,0x8d,0x06,0x00,0x00,
+0x00,0x0d,0x28,0x80,0x00,0x06,0x14,0x02,0x30,0x4b,0x00,0xff,0x00,0xeb,0x70,0x21,
+0x01,0xc4,0x20,0x21,0x90,0x83,0x00,0x00,0x27,0x82,0x89,0x58,0x00,0xa2,0x28,0x21,
+0x8c,0xa4,0x00,0x00,0x00,0x03,0x18,0x82,0x30,0x63,0x00,0x03,0x2c,0x62,0x00,0x02,
+0x14,0x40,0x00,0x66,0x30,0x8c,0x3f,0xff,0x24,0x02,0x00,0x02,0x10,0x62,0x00,0x61,
+0x2d,0x82,0x08,0x00,0x15,0x40,0x00,0x36,0x01,0x6c,0x10,0x21,0x01,0x6c,0x18,0x21,
+0x30,0x62,0x00,0xff,0x00,0x02,0x10,0x2b,0x00,0x03,0x1a,0x02,0x3c,0x04,0xb0,0x01,
+0x00,0x62,0x18,0x21,0x00,0xe4,0x20,0x21,0x24,0x02,0x00,0x01,0xa2,0x03,0x01,0xc1,
+0xa0,0x82,0x00,0x08,0x8e,0x06,0x01,0xa8,0x3c,0x03,0xb0,0x00,0x34,0x63,0xff,0xf4,
+0x24,0xc5,0x00,0x01,0x28,0xa4,0x00,0x00,0x24,0xc2,0x00,0x40,0x00,0xa4,0x10,0x0a,
+0x01,0xc3,0x18,0x21,0xa4,0x6c,0x00,0x00,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,
+0x92,0x04,0x01,0xc0,0x00,0xa2,0x38,0x23,0x3c,0x03,0xb0,0x03,0xae,0x0b,0x01,0xcc,
+0xae,0x0c,0x01,0xc8,0xae,0x06,0x01,0xc4,0xae,0x07,0x01,0xa8,0x34,0x63,0x01,0x08,
+0x92,0x05,0x01,0xd6,0x8c,0x66,0x00,0x00,0x24,0x84,0x00,0x01,0x30,0x82,0x00,0xff,
+0x00,0x45,0x10,0x2b,0xae,0x06,0x01,0xd0,0x10,0x40,0x00,0x07,0xa2,0x04,0x01,0xc0,
+0x92,0x02,0x01,0xd5,0x92,0x03,0x01,0xc1,0x24,0x42,0xff,0xfc,0x00,0x62,0x18,0x2a,
+0x14,0x60,0x00,0x08,0x00,0x00,0x00,0x00,0x02,0x00,0x20,0x21,0x0c,0x00,0x2a,0x4c,
+0x00,0x00,0x00,0x00,0x8e,0x09,0x01,0xac,0x8e,0x06,0x01,0xa8,0x08,0x00,0x2a,0xcb,
+0x00,0xc9,0x10,0x26,0x8e,0x09,0x01,0xac,0x08,0x00,0x2a,0xca,0x00,0xe0,0x30,0x21,
+0x30,0x43,0x00,0xff,0x92,0x07,0x01,0xc1,0x00,0x02,0x12,0x02,0x30,0x44,0x00,0xff,
+0x38,0x63,0x00,0x00,0x24,0x46,0x00,0x01,0x92,0x05,0x01,0xd5,0x00,0x83,0x30,0x0a,
+0x00,0xc7,0x18,0x21,0x00,0xa3,0x10,0x2a,0x14,0x40,0xff,0xeb,0x00,0x00,0x00,0x00,
+0x24,0xa2,0xff,0xfc,0x00,0x62,0x10,0x2a,0x10,0x40,0x00,0x07,0x01,0x80,0x28,0x21,
+0x92,0x03,0x01,0xd6,0x25,0x42,0x00,0x01,0x00,0x43,0x10,0x2a,0x14,0x40,0x00,0x07,
+0x25,0xa4,0x00,0x01,0x01,0x80,0x28,0x21,0x01,0x60,0x30,0x21,0x0c,0x00,0x2a,0x74,
+0x02,0x00,0x20,0x21,0x08,0x00,0x2b,0x6d,0x00,0x00,0x00,0x00,0x28,0x83,0x00,0x00,
+0x25,0xa2,0x00,0x40,0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,
+0x00,0x82,0x20,0x23,0x00,0xc7,0x18,0x21,0x25,0x42,0x00,0x01,0x00,0x80,0x30,0x21,
+0xa2,0x03,0x01,0xc1,0xae,0x0b,0x01,0xcc,0xae,0x0c,0x01,0xc8,0x08,0x00,0x2a,0xc9,
+0xa2,0x02,0x01,0xc0,0x14,0x40,0xff,0x9f,0x00,0x00,0x00,0x00,0x15,0x40,0x00,0x14,
+0x24,0x02,0xc0,0x00,0x00,0xc2,0x10,0x24,0x00,0x4c,0x10,0x25,0xad,0x02,0x00,0x00,
+0xaf,0x87,0xbc,0x10,0x8d,0x05,0x00,0x00,0x00,0x07,0x18,0xc2,0x3c,0x02,0x00,0x80,
+0x00,0x03,0x1a,0x00,0x3c,0x04,0xb0,0x06,0xaf,0x85,0xbc,0x18,0x00,0x62,0x18,0x25,
+0x34,0x84,0x80,0x18,0x8d,0x05,0x00,0x04,0xac,0x83,0x00,0x00,0x8e,0x02,0x01,0xa8,
+0x8e,0x09,0x01,0xac,0xaf,0x85,0xbc,0x14,0x08,0x00,0x2a,0xc2,0x24,0x44,0x00,0x01,
+0x01,0x6c,0x10,0x21,0x30,0x45,0x00,0xff,0x92,0x04,0x01,0xc1,0x00,0x02,0x12,0x02,
+0x30,0x46,0x00,0xff,0x38,0xa5,0x00,0x00,0x24,0x42,0x00,0x01,0x92,0x03,0x01,0xd5,
+0x00,0xc5,0x10,0x0a,0x00,0x82,0x20,0x21,0x00,0x64,0x18,0x2a,0x10,0x60,0xff,0xca,
+0x01,0x80,0x28,0x21,0x08,0x00,0x2b,0x6b,0x02,0x00,0x20,0x21,0x90,0x87,0x01,0xc0,
+0x00,0x00,0x00,0x00,0x10,0xe0,0xff,0x06,0x00,0x00,0x28,0x21,0x3c,0x02,0xb0,0x03,
+0x34,0x42,0x01,0x08,0x94,0x83,0x01,0xd8,0x8c,0x88,0x01,0xd0,0x8c,0x45,0x00,0x00,
+0x01,0x03,0x18,0x21,0x00,0xa3,0x10,0x2b,0x10,0x40,0x00,0x0b,0x2c,0xe2,0x00,0x02,
+0x00,0xa8,0x10,0x2b,0x10,0x40,0xfe,0xf9,0x00,0xc9,0x10,0x26,0x3c,0x02,0x80,0x00,
+0x00,0x62,0x18,0x21,0x00,0xa2,0x10,0x21,0x00,0x43,0x10,0x2b,0x14,0x40,0xfe,0xf3,
+0x00,0xc9,0x10,0x26,0x2c,0xe2,0x00,0x02,0x10,0x40,0xff,0x90,0x00,0x00,0x00,0x00,
+0x24,0x02,0x00,0x01,0x14,0xe2,0xfe,0xed,0x00,0xc9,0x10,0x26,0x3c,0x03,0xb0,0x06,
+0x34,0x63,0x80,0x18,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x02,
+0x14,0x40,0xfe,0xe5,0x00,0x00,0x00,0x00,0x08,0x00,0x2b,0x6b,0x00,0x00,0x00,0x00,
+0x3c,0x04,0xb0,0x03,0x3c,0x06,0xb0,0x07,0x3c,0x02,0x80,0x01,0x34,0xc6,0x00,0x18,
+0x34,0x84,0x00,0x20,0x24,0x42,0xaf,0xa0,0x24,0x03,0xff,0x83,0xac,0x82,0x00,0x00,
+0xa0,0xc3,0x00,0x00,0x90,0xc4,0x00,0x00,0x27,0xbd,0xff,0xf8,0x3c,0x03,0xb0,0x07,
+0x24,0x02,0xff,0x82,0xa3,0xa4,0x00,0x00,0xa0,0x62,0x00,0x00,0x90,0x64,0x00,0x00,
+0x3c,0x02,0xb0,0x07,0x34,0x42,0x00,0x08,0xa3,0xa4,0x00,0x01,0xa0,0x40,0x00,0x00,
+0x90,0x43,0x00,0x00,0x24,0x02,0x00,0x03,0x3c,0x05,0xb0,0x07,0xa3,0xa3,0x00,0x00,
+0xa0,0xc2,0x00,0x00,0x90,0xc4,0x00,0x00,0x34,0xa5,0x00,0x10,0x24,0x02,0x00,0x06,
+0x3c,0x03,0xb0,0x07,0xa3,0xa4,0x00,0x00,0x34,0x63,0x00,0x38,0xa0,0xa2,0x00,0x00,
+0x90,0x64,0x00,0x00,0x3c,0x02,0xb0,0x07,0x34,0x42,0x00,0x20,0xa3,0xa4,0x00,0x00,
+0xa0,0xa0,0x00,0x00,0x90,0xa3,0x00,0x00,0xaf,0x82,0xbf,0x20,0xa3,0xa3,0x00,0x00,
+0xa0,0x40,0x00,0x00,0x90,0x43,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x08,
+};
+
+u8 rtl8190_fwdata_array[] ={
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x10,0x00,0x08,0x00,
+0x02,0xe9,0x01,0x74,0x02,0xab,0x01,0xc7,0x01,0x55,0x00,0xe4,0x00,0xab,0x00,0x72,
+0x00,0x55,0x00,0x4c,0x00,0x4c,0x00,0x4c,0x00,0x4c,0x00,0x4c,0x02,0x76,0x01,0x3b,
+0x00,0xd2,0x00,0x9e,0x00,0x69,0x00,0x4f,0x00,0x46,0x00,0x3f,0x01,0x3b,0x00,0x9e,
+0x00,0x69,0x00,0x4f,0x00,0x35,0x00,0x27,0x00,0x23,0x00,0x20,0x01,0x2f,0x00,0x98,
+0x00,0x65,0x00,0x4c,0x00,0x33,0x00,0x26,0x00,0x22,0x00,0x1e,0x00,0x98,0x00,0x4c,
+0x00,0x33,0x00,0x26,0x00,0x19,0x00,0x13,0x00,0x11,0x00,0x0f,0x02,0x39,0x01,0x1c,
+0x00,0xbd,0x00,0x8e,0x00,0x5f,0x00,0x47,0x00,0x3f,0x00,0x39,0x01,0x1c,0x00,0x8e,
+0x00,0x5f,0x00,0x47,0x00,0x2f,0x00,0x23,0x00,0x20,0x00,0x1c,0x01,0x11,0x00,0x89,
+0x00,0x5b,0x00,0x44,0x00,0x2e,0x00,0x22,0x00,0x1e,0x00,0x1b,0x00,0x89,0x00,0x44,
+0x00,0x2e,0x00,0x22,0x00,0x17,0x00,0x11,0x00,0x0f,0x00,0x0e,0x02,0xab,0x02,0xab,
+0x02,0x66,0x02,0x66,0x07,0x06,0x06,0x06,0x05,0x06,0x07,0x08,0x04,0x06,0x07,0x08,
+0x09,0x0a,0x0b,0x0b,0x49,0x6e,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0x4c,
+0x42,0x4d,0x4f,0x44,0x00,0x00,0x00,0x00,0x54,0x4c,0x42,0x4c,0x5f,0x64,0x61,0x74,
+0x61,0x00,0x54,0x4c,0x42,0x53,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x64,0x45,0x4c,
+0x5f,0x64,0x61,0x74,0x61,0x00,0x41,0x64,0x45,0x53,0x00,0x00,0x00,0x00,0x00,0x00,
+0x45,0x78,0x63,0x43,0x6f,0x64,0x65,0x36,0x00,0x00,0x45,0x78,0x63,0x43,0x6f,0x64,
+0x65,0x37,0x00,0x00,0x53,0x79,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x70,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x52,0x49,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x43,0x70,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4f,0x76,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x0b,0x53,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x2c,
+0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x60,
+0x00,0x00,0x00,0x90,0x00,0x00,0x00,0xc0,0x00,0x00,0x01,0x20,0x00,0x00,0x01,0x80,
+0x00,0x00,0x01,0xb0,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0x9c,
+0x00,0x00,0x00,0xd0,0x00,0x00,0x01,0x38,0x00,0x00,0x01,0xa0,0x00,0x00,0x01,0xd4,
+0x00,0x00,0x02,0x08,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0xd0,0x00,0x00,0x01,0x38,
+0x00,0x00,0x01,0xa0,0x00,0x00,0x02,0x6f,0x00,0x00,0x03,0x40,0x00,0x00,0x03,0xa8,
+0x00,0x00,0x04,0x10,0x01,0x01,0x01,0x02,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,
+0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x07,0x74,0x80,0x00,0x07,0x88,
+0x80,0x00,0x07,0x88,0x80,0x00,0x07,0x78,0x80,0x00,0x07,0x78,0x80,0x00,0x07,0x9c,
+0x80,0x00,0x53,0xc4,0x80,0x00,0x54,0x24,0x80,0x00,0x54,0x38,0x80,0x00,0x54,0x5c,
+0x80,0x00,0x54,0x68,0x80,0x00,0x54,0xa8,0x80,0x00,0x56,0xa8,0x80,0x00,0x57,0xec,
+0x80,0x00,0x58,0x14,0x80,0x00,0x59,0x0c,0x80,0x00,0x59,0xc4,0x80,0x00,0x5a,0x6c,
+0x80,0x00,0x5a,0xe0,0x80,0x00,0x5b,0xec,0x80,0x00,0x5c,0x24,0x80,0x00,0x5c,0x38,
+0x80,0x00,0x5c,0x4c,0x80,0x00,0x5d,0x40,0x80,0x00,0x5d,0x80,0x80,0x00,0x5e,0x34,
+0x80,0x00,0x5e,0x5c,0x80,0x00,0x56,0x68,0x80,0x00,0x5e,0x78,0x80,0x00,0x88,0xf8,
+0x80,0x00,0x88,0xf8,0x80,0x00,0x88,0xf8,0x80,0x00,0x89,0x2c,0x80,0x00,0x89,0x6c,
+0x80,0x00,0x89,0xa4,0x80,0x00,0x89,0xd4,0x80,0x00,0x8a,0x10,0x80,0x00,0x8a,0x50,
+0x80,0x00,0x8a,0xb8,0x80,0x00,0x8a,0xcc,0x80,0x00,0x8b,0x08,0x80,0x00,0x8b,0x10,
+0x80,0x00,0x8b,0x4c,0x80,0x00,0x8b,0x60,0x80,0x00,0x8b,0x68,0x80,0x00,0x8b,0x70,
+0x80,0x00,0x8b,0x70,0x80,0x00,0x8b,0x70,0x80,0x00,0x8b,0x70,0x80,0x00,0x8a,0x90,
+0x80,0x00,0x8b,0xa0,0x80,0x00,0x8b,0xb4,0x80,0x00,0x88,0x54,0x80,0x00,0x8e,0xc8,
+0x80,0x00,0x8e,0xc8,0x80,0x00,0x8e,0xc8,0x80,0x00,0x8e,0xfc,0x80,0x00,0x8f,0x3c,
+0x80,0x00,0x8f,0x74,0x80,0x00,0x8f,0xa4,0x80,0x00,0x8f,0xe0,0x80,0x00,0x90,0x20,
+0x80,0x00,0x90,0x88,0x80,0x00,0x90,0x9c,0x80,0x00,0x90,0xd8,0x80,0x00,0x90,0xe0,
+0x80,0x00,0x91,0x1c,0x80,0x00,0x91,0x30,0x80,0x00,0x91,0x38,0x80,0x00,0x91,0x40,
+0x80,0x00,0x91,0x40,0x80,0x00,0x91,0x40,0x80,0x00,0x91,0x40,0x80,0x00,0x90,0x60,
+0x80,0x00,0x91,0x70,0x80,0x00,0x91,0x84,0x80,0x00,0x8d,0x00,};
+
+u32 Rtl8192UsbPHY_REGArray[] = {
+0x0, };
+
+u32 Rtl8192UsbPHY_REG_1T2RArray[] = {
+0x800,0x00000000,
+0x804,0x00000001,
+0x808,0x0000fc00,
+0x80c,0x0000001c,
+0x810,0x801010aa,
+0x814,0x008514d0,
+0x818,0x00000040,
+0x81c,0x00000000,
+0x820,0x00000004,
+0x824,0x00690000,
+0x828,0x00000004,
+0x82c,0x00e90000,
+0x830,0x00000004,
+0x834,0x00690000,
+0x838,0x00000004,
+0x83c,0x00e90000,
+0x840,0x00000000,
+0x844,0x00000000,
+0x848,0x00000000,
+0x84c,0x00000000,
+0x850,0x00000000,
+0x854,0x00000000,
+0x858,0x65a965a9,
+0x85c,0x65a965a9,
+0x860,0x001f0010,
+0x864,0x007f0010,
+0x868,0x001f0010,
+0x86c,0x007f0010,
+0x870,0x0f100f70,
+0x874,0x0f100f70,
+0x878,0x00000000,
+0x87c,0x00000000,
+0x880,0x6870e36c,
+0x884,0xe3573600,
+0x888,0x4260c340,
+0x88c,0x0000ff00,
+0x890,0x00000000,
+0x894,0xfffffffe,
+0x898,0x4c42382f,
+0x89c,0x00656056,
+0x8b0,0x00000000,
+0x8e0,0x00000000,
+0x8e4,0x00000000,
+0x900,0x00000000,
+0x904,0x00000023,
+0x908,0x00000000,
+0x90c,0x31121311,
+0xa00,0x00d0c7d8,
+0xa04,0x811f0008,
+0xa08,0x80cd8300,
+0xa0c,0x2e62740f,
+0xa10,0x95009b78,
+0xa14,0x11145008,
+0xa18,0x00881117,
+0xa1c,0x89140fa0,
+0xa20,0x1a1b0000,
+0xa24,0x090e1317,
+0xa28,0x00000204,
+0xa2c,0x00000000,
+0xc00,0x00000040,
+0xc04,0x00005433,
+0xc08,0x000000e4,
+0xc0c,0x6c6c6c6c,
+0xc10,0x08800000,
+0xc14,0x40000100,
+0xc18,0x08000000,
+0xc1c,0x40000100,
+0xc20,0x08000000,
+0xc24,0x40000100,
+0xc28,0x08000000,
+0xc2c,0x40000100,
+0xc30,0x6de9ac44,
+0xc34,0x465c52cd,
+0xc38,0x497f5994,
+0xc3c,0x0a969764,
+0xc40,0x1f7c403f,
+0xc44,0x000100b7,
+0xc48,0xec020000,
+0xc4c,0x00000300,
+0xc50,0x69543420,
+0xc54,0x433c0094,
+0xc58,0x69543420,
+0xc5c,0x433c0094,
+0xc60,0x69543420,
+0xc64,0x433c0094,
+0xc68,0x69543420,
+0xc6c,0x433c0094,
+0xc70,0x2c7f000d,
+0xc74,0x0186175b,
+0xc78,0x0000001f,
+0xc7c,0x00b91612,
+0xc80,0x40000100,
+0xc84,0x20000000,
+0xc88,0x40000100,
+0xc8c,0x20200000,
+0xc90,0x40000100,
+0xc94,0x00000000,
+0xc98,0x40000100,
+0xc9c,0x00000000,
+0xca0,0x00492492,
+0xca4,0x00000000,
+0xca8,0x00000000,
+0xcac,0x00000000,
+0xcb0,0x00000000,
+0xcb4,0x00000000,
+0xcb8,0x00000000,
+0xcbc,0x00492492,
+0xcc0,0x00000000,
+0xcc4,0x00000000,
+0xcc8,0x00000000,
+0xccc,0x00000000,
+0xcd0,0x00000000,
+0xcd4,0x00000000,
+0xcd8,0x64b22427,
+0xcdc,0x00766932,
+0xce0,0x00222222,
+0xd00,0x00000750,
+0xd04,0x00000403,
+0xd08,0x0000907f,
+0xd0c,0x00000001,
+0xd10,0xa0633333,
+0xd14,0x33333c63,
+0xd18,0x6a8f5b6b,
+0xd1c,0x00000000,
+0xd20,0x00000000,
+0xd24,0x00000000,
+0xd28,0x00000000,
+0xd2c,0xcc979975,
+0xd30,0x00000000,
+0xd34,0x00000000,
+0xd38,0x00000000,
+0xd3c,0x00027293,
+0xd40,0x00000000,
+0xd44,0x00000000,
+0xd48,0x00000000,
+0xd4c,0x00000000,
+0xd50,0x6437140a,
+0xd54,0x024dbd02,
+0xd58,0x00000000,
+0xd5c,0x04032064,
+0xe00,0x161a1a1a,
+0xe04,0x12121416,
+0xe08,0x00001800,
+0xe0c,0x00000000,
+0xe10,0x161a1a1a,
+0xe14,0x12121416,
+0xe18,0x161a1a1a,
+0xe1c,0x12121416,
+};
+
+u32 Rtl8192UsbRadioA_Array[] = {
+0x019,0x00000003,
+0x000,0x000000bf,
+0x001,0x00000ee0,
+0x002,0x0000004c,
+0x003,0x000007f1,
+0x004,0x00000975,
+0x005,0x00000c58,
+0x006,0x00000ae6,
+0x007,0x000000ca,
+0x008,0x00000e1c,
+0x009,0x000007f0,
+0x00a,0x000009d0,
+0x00b,0x000001ba,
+0x00c,0x00000240,
+0x00e,0x00000020,
+0x00f,0x00000990,
+0x012,0x00000806,
+0x014,0x000005ab,
+0x015,0x00000f80,
+0x016,0x00000020,
+0x017,0x00000597,
+0x018,0x0000050a,
+0x01a,0x00000f80,
+0x01b,0x00000f5e,
+0x01c,0x00000008,
+0x01d,0x00000607,
+0x01e,0x000006cc,
+0x01f,0x00000000,
+0x020,0x000001a5,
+0x01f,0x00000001,
+0x020,0x00000165,
+0x01f,0x00000002,
+0x020,0x000000c6,
+0x01f,0x00000003,
+0x020,0x00000086,
+0x01f,0x00000004,
+0x020,0x00000046,
+0x01f,0x00000005,
+0x020,0x000001e6,
+0x01f,0x00000006,
+0x020,0x000001a6,
+0x01f,0x00000007,
+0x020,0x00000166,
+0x01f,0x00000008,
+0x020,0x000000c7,
+0x01f,0x00000009,
+0x020,0x00000087,
+0x01f,0x0000000a,
+0x020,0x000000f7,
+0x01f,0x0000000b,
+0x020,0x000000d7,
+0x01f,0x0000000c,
+0x020,0x000000b7,
+0x01f,0x0000000d,
+0x020,0x00000097,
+0x01f,0x0000000e,
+0x020,0x00000077,
+0x01f,0x0000000f,
+0x020,0x00000057,
+0x01f,0x00000010,
+0x020,0x00000037,
+0x01f,0x00000011,
+0x020,0x000000fb,
+0x01f,0x00000012,
+0x020,0x000000db,
+0x01f,0x00000013,
+0x020,0x000000bb,
+0x01f,0x00000014,
+0x020,0x000000ff,
+0x01f,0x00000015,
+0x020,0x000000e3,
+0x01f,0x00000016,
+0x020,0x000000c3,
+0x01f,0x00000017,
+0x020,0x000000a3,
+0x01f,0x00000018,
+0x020,0x00000083,
+0x01f,0x00000019,
+0x020,0x00000063,
+0x01f,0x0000001a,
+0x020,0x00000043,
+0x01f,0x0000001b,
+0x020,0x00000023,
+0x01f,0x0000001c,
+0x020,0x00000003,
+0x01f,0x0000001d,
+0x020,0x000001e3,
+0x01f,0x0000001e,
+0x020,0x000001c3,
+0x01f,0x0000001f,
+0x020,0x000001a3,
+0x01f,0x00000020,
+0x020,0x00000183,
+0x01f,0x00000021,
+0x020,0x00000163,
+0x01f,0x00000022,
+0x020,0x00000143,
+0x01f,0x00000023,
+0x020,0x00000123,
+0x01f,0x00000024,
+0x020,0x00000103,
+0x023,0x00000203,
+0x024,0x00000200,
+0x00b,0x000001ba,
+0x02c,0x000003d7,
+0x02d,0x00000ff0,
+0x000,0x00000037,
+0x004,0x00000160,
+0x007,0x00000080,
+0x002,0x0000088d,
+0x0fe,0x00000000,
+0x0fe,0x00000000,
+0x016,0x00000200,
+0x016,0x00000380,
+0x016,0x00000020,
+0x016,0x000001a0,
+0x000,0x000000bf,
+0x00d,0x0000001f,
+0x00d,0x00000c9f,
+0x002,0x0000004d,
+0x000,0x00000cbf,
+0x004,0x00000975,
+0x007,0x00000700,
+};
+
+u32 Rtl8192UsbRadioB_Array[] = {
+0x019,0x00000003,
+0x000,0x000000bf,
+0x001,0x000006e0,
+0x002,0x0000004c,
+0x003,0x000007f1,
+0x004,0x00000975,
+0x005,0x00000c58,
+0x006,0x00000ae6,
+0x007,0x000000ca,
+0x008,0x00000e1c,
+0x000,0x000000b7,
+0x00a,0x00000850,
+0x000,0x000000bf,
+0x00b,0x000001ba,
+0x00c,0x00000240,
+0x00e,0x00000020,
+0x015,0x00000f80,
+0x016,0x00000020,
+0x017,0x00000597,
+0x018,0x0000050a,
+0x01a,0x00000e00,
+0x01b,0x00000f5e,
+0x01d,0x00000607,
+0x01e,0x000006cc,
+0x00b,0x000001ba,
+0x023,0x00000203,
+0x024,0x00000200,
+0x000,0x00000037,
+0x004,0x00000160,
+0x016,0x00000200,
+0x016,0x00000380,
+0x016,0x00000020,
+0x016,0x000001a0,
+0x00d,0x00000ccc,
+0x000,0x000000bf,
+0x002,0x0000004d,
+0x000,0x00000cbf,
+0x004,0x00000975,
+0x007,0x00000700,
+};
+
+u32 Rtl8192UsbRadioC_Array[] = {
+0x0, };
+
+u32 Rtl8192UsbRadioD_Array[] = {
+0x0, };
+
+u32 Rtl8192UsbMACPHY_Array[] = {
+0x03c,0xffff0000,0x00000f0f,
+0x340,0xffffffff,0x161a1a1a,
+0x344,0xffffffff,0x12121416,
+0x348,0x0000ffff,0x00001818,
+0x12c,0xffffffff,0x04000802,
+0x318,0x00000fff,0x00000100,
+};
+
+u32 Rtl8192UsbMACPHY_Array_PG[] = {
+0x03c,0xffff0000,0x00000f0f,
+0xe00,0xffffffff,0x06090909,
+0xe04,0xffffffff,0x00030306,
+0xe08,0x0000ff00,0x00000000,
+0xe10,0xffffffff,0x0a0c0d0f,
+0xe14,0xffffffff,0x06070809,
+0xe18,0xffffffff,0x0a0c0d0f,
+0xe1c,0xffffffff,0x06070809,
+0x12c,0xffffffff,0x04000802,
+0x318,0x00000fff,0x00000800,
+};
+
+u32 Rtl8192UsbAGCTAB_Array[] = {
+0xc78,0x7d000001,
+0xc78,0x7d010001,
+0xc78,0x7d020001,
+0xc78,0x7d030001,
+0xc78,0x7d040001,
+0xc78,0x7d050001,
+0xc78,0x7c060001,
+0xc78,0x7b070001,
+0xc78,0x7a080001,
+0xc78,0x79090001,
+0xc78,0x780a0001,
+0xc78,0x770b0001,
+0xc78,0x760c0001,
+0xc78,0x750d0001,
+0xc78,0x740e0001,
+0xc78,0x730f0001,
+0xc78,0x72100001,
+0xc78,0x71110001,
+0xc78,0x70120001,
+0xc78,0x6f130001,
+0xc78,0x6e140001,
+0xc78,0x6d150001,
+0xc78,0x6c160001,
+0xc78,0x6b170001,
+0xc78,0x6a180001,
+0xc78,0x69190001,
+0xc78,0x681a0001,
+0xc78,0x671b0001,
+0xc78,0x661c0001,
+0xc78,0x651d0001,
+0xc78,0x641e0001,
+0xc78,0x491f0001,
+0xc78,0x48200001,
+0xc78,0x47210001,
+0xc78,0x46220001,
+0xc78,0x45230001,
+0xc78,0x44240001,
+0xc78,0x43250001,
+0xc78,0x28260001,
+0xc78,0x27270001,
+0xc78,0x26280001,
+0xc78,0x25290001,
+0xc78,0x242a0001,
+0xc78,0x232b0001,
+0xc78,0x222c0001,
+0xc78,0x212d0001,
+0xc78,0x202e0001,
+0xc78,0x0a2f0001,
+0xc78,0x08300001,
+0xc78,0x06310001,
+0xc78,0x05320001,
+0xc78,0x04330001,
+0xc78,0x03340001,
+0xc78,0x02350001,
+0xc78,0x01360001,
+0xc78,0x00370001,
+0xc78,0x00380001,
+0xc78,0x00390001,
+0xc78,0x003a0001,
+0xc78,0x003b0001,
+0xc78,0x003c0001,
+0xc78,0x003d0001,
+0xc78,0x003e0001,
+0xc78,0x003f0001,
+0xc78,0x7d400001,
+0xc78,0x7d410001,
+0xc78,0x7d420001,
+0xc78,0x7d430001,
+0xc78,0x7d440001,
+0xc78,0x7d450001,
+0xc78,0x7c460001,
+0xc78,0x7b470001,
+0xc78,0x7a480001,
+0xc78,0x79490001,
+0xc78,0x784a0001,
+0xc78,0x774b0001,
+0xc78,0x764c0001,
+0xc78,0x754d0001,
+0xc78,0x744e0001,
+0xc78,0x734f0001,
+0xc78,0x72500001,
+0xc78,0x71510001,
+0xc78,0x70520001,
+0xc78,0x6f530001,
+0xc78,0x6e540001,
+0xc78,0x6d550001,
+0xc78,0x6c560001,
+0xc78,0x6b570001,
+0xc78,0x6a580001,
+0xc78,0x69590001,
+0xc78,0x685a0001,
+0xc78,0x675b0001,
+0xc78,0x665c0001,
+0xc78,0x655d0001,
+0xc78,0x645e0001,
+0xc78,0x495f0001,
+0xc78,0x48600001,
+0xc78,0x47610001,
+0xc78,0x46620001,
+0xc78,0x45630001,
+0xc78,0x44640001,
+0xc78,0x43650001,
+0xc78,0x28660001,
+0xc78,0x27670001,
+0xc78,0x26680001,
+0xc78,0x25690001,
+0xc78,0x246a0001,
+0xc78,0x236b0001,
+0xc78,0x226c0001,
+0xc78,0x216d0001,
+0xc78,0x206e0001,
+0xc78,0x0a6f0001,
+0xc78,0x08700001,
+0xc78,0x06710001,
+0xc78,0x05720001,
+0xc78,0x04730001,
+0xc78,0x03740001,
+0xc78,0x02750001,
+0xc78,0x01760001,
+0xc78,0x00770001,
+0xc78,0x00780001,
+0xc78,0x00790001,
+0xc78,0x007a0001,
+0xc78,0x007b0001,
+0xc78,0x007c0001,
+0xc78,0x007d0001,
+0xc78,0x007e0001,
+0xc78,0x007f0001,
+0xc78,0x2e00001e,
+0xc78,0x2e01001e,
+0xc78,0x2e02001e,
+0xc78,0x2e03001e,
+0xc78,0x2e04001e,
+0xc78,0x2e05001e,
+0xc78,0x3006001e,
+0xc78,0x3407001e,
+0xc78,0x3908001e,
+0xc78,0x3c09001e,
+0xc78,0x3f0a001e,
+0xc78,0x420b001e,
+0xc78,0x440c001e,
+0xc78,0x450d001e,
+0xc78,0x460e001e,
+0xc78,0x460f001e,
+0xc78,0x4710001e,
+0xc78,0x4811001e,
+0xc78,0x4912001e,
+0xc78,0x4a13001e,
+0xc78,0x4b14001e,
+0xc78,0x4b15001e,
+0xc78,0x4c16001e,
+0xc78,0x4d17001e,
+0xc78,0x4e18001e,
+0xc78,0x4f19001e,
+0xc78,0x4f1a001e,
+0xc78,0x501b001e,
+0xc78,0x511c001e,
+0xc78,0x521d001e,
+0xc78,0x521e001e,
+0xc78,0x531f001e,
+0xc78,0x5320001e,
+0xc78,0x5421001e,
+0xc78,0x5522001e,
+0xc78,0x5523001e,
+0xc78,0x5624001e,
+0xc78,0x5725001e,
+0xc78,0x5726001e,
+0xc78,0x5827001e,
+0xc78,0x5828001e,
+0xc78,0x5929001e,
+0xc78,0x592a001e,
+0xc78,0x5a2b001e,
+0xc78,0x5b2c001e,
+0xc78,0x5c2d001e,
+0xc78,0x5c2e001e,
+0xc78,0x5d2f001e,
+0xc78,0x5e30001e,
+0xc78,0x5f31001e,
+0xc78,0x6032001e,
+0xc78,0x6033001e,
+0xc78,0x6134001e,
+0xc78,0x6235001e,
+0xc78,0x6336001e,
+0xc78,0x6437001e,
+0xc78,0x6438001e,
+0xc78,0x6539001e,
+0xc78,0x663a001e,
+0xc78,0x673b001e,
+0xc78,0x673c001e,
+0xc78,0x683d001e,
+0xc78,0x693e001e,
+0xc78,0x6a3f001e,
+};
diff --git a/drivers/staging/rtl8192u/r819xU_firmware_img.h b/drivers/staging/rtl8192u/r819xU_firmware_img.h
new file mode 100644
index 0000000..d9d9515
--- /dev/null
+++ b/drivers/staging/rtl8192u/r819xU_firmware_img.h
@@ -0,0 +1,35 @@
+#ifndef IMG_H
+#define IMG_H
+
+#define BOOT_ARR_LEN 344
+#define MAIN_ARR_LEN 45136
+#define DATA_ARR_LEN 796
+#define MACPHY_Array_PGLength 30
+#define PHY_REG_1T2RArrayLength 296
+#define AGCTAB_ArrayLength 384
+#define MACPHY_ArrayLength 18
+
+#define RadioA_ArrayLength 246
+#define RadioB_ArrayLength 78
+#define RadioC_ArrayLength 1
+#define RadioD_ArrayLength 1
+#define PHY_REGArrayLength 1
+
+
+extern u8 rtl8190_fwboot_array[BOOT_ARR_LEN];
+extern u8 rtl8190_fwmain_array[MAIN_ARR_LEN];
+extern u8 rtl8190_fwdata_array[DATA_ARR_LEN];
+
+extern u32 Rtl8192UsbPHY_REGArray[];
+extern u32 Rtl8192UsbPHY_REG_1T2RArray[];
+extern u32 Rtl8192UsbRadioA_Array[];
+extern u32 Rtl8192UsbRadioB_Array[];
+extern u32 Rtl8192UsbRadioC_Array[];
+extern u32 Rtl8192UsbRadioD_Array[];
+extern u32 Rtl8192UsbMACPHY_Array[];
+extern u32 Rtl8192UsbMACPHY_Array_PG[];
+extern u32 Rtl8192UsbAGCTAB_Array[];
+
+
+
+#endif
diff --git a/drivers/staging/rtl8192u/r819xU_phy.c b/drivers/staging/rtl8192u/r819xU_phy.c
new file mode 100644
index 0000000..a3adaed
--- /dev/null
+++ b/drivers/staging/rtl8192u/r819xU_phy.c
@@ -0,0 +1,1777 @@
+#include "r8192U.h"
+#include "r8192U_hw.h"
+#include "r819xU_phy.h"
+#include "r819xU_phyreg.h"
+#include "r8190_rtl8256.h"
+#include "r8192U_dm.h"
+#include "r819xU_firmware_img.h"
+
+#ifdef ENABLE_DOT11D
+#include "dot11d.h"
+#endif
+static u32 RF_CHANNEL_TABLE_ZEBRA[] = {
+	0,
+	0x085c, //2412 1
+	0x08dc, //2417 2
+	0x095c, //2422 3
+	0x09dc, //2427 4
+	0x0a5c, //2432 5
+	0x0adc, //2437 6
+	0x0b5c, //2442 7
+	0x0bdc, //2447 8
+	0x0c5c, //2452 9
+	0x0cdc, //2457 10
+	0x0d5c, //2462 11
+	0x0ddc, //2467 12
+	0x0e5c, //2472 13
+	0x0f72, //2484
+};
+
+
+#define rtl819XPHY_REG_1T2RArray Rtl8192UsbPHY_REG_1T2RArray
+#define rtl819XMACPHY_Array_PG Rtl8192UsbMACPHY_Array_PG
+#define rtl819XMACPHY_Array Rtl8192UsbMACPHY_Array
+#define rtl819XRadioA_Array  Rtl8192UsbRadioA_Array
+#define rtl819XRadioB_Array Rtl8192UsbRadioB_Array
+#define rtl819XRadioC_Array Rtl8192UsbRadioC_Array
+#define rtl819XRadioD_Array Rtl8192UsbRadioD_Array
+#define rtl819XAGCTAB_Array Rtl8192UsbAGCTAB_Array
+
+/******************************************************************************
+ *function:  This function read BB parameters from Header file we gen,
+ *	     and do register read/write
+ *   input:  u32	dwBitMask  //taget bit pos in the addr to be modified
+ *  output:  none
+ *  return:  u32	return the shift bit bit position of the mask
+ * ****************************************************************************/
+u32 rtl8192_CalculateBitShift(u32 dwBitMask)
+{
+	u32 i;
+	for (i=0; i<=31; i++)
+	{
+		if (((dwBitMask>>i)&0x1) == 1)
+			break;
+	}
+	return i;
+}
+/******************************************************************************
+ *function:  This function check different RF type to execute legal judgement. If RF Path is illegal, we will return false.
+ *   input:  none
+ *  output:  none
+ *  return:  0(illegal, false), 1(legal,true)
+ * ***************************************************************************/
+u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath)
+{
+	u8 ret = 1;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	if (priv->rf_type == RF_2T4R)
+		ret = 0;
+	else if (priv->rf_type == RF_1T2R)
+	{
+		if (eRFPath == RF90_PATH_A || eRFPath == RF90_PATH_B)
+			ret = 1;
+		else if (eRFPath == RF90_PATH_C || eRFPath == RF90_PATH_D)
+			ret = 0;
+	}
+	return ret;
+}
+/******************************************************************************
+ *function:  This function set specific bits to BB register
+ *   input:  net_device dev
+ *           u32	dwRegAddr  //target addr to be modified
+ *           u32	dwBitMask  //taget bit pos in the addr to be modified
+ *           u32	dwData     //value to be write
+ *  output:  none
+ *  return:  none
+ *  notice:
+ * ****************************************************************************/
+void rtl8192_setBBreg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask, u32 dwData)
+{
+
+	u32 OriginalValue, BitShift, NewValue;
+
+	if(dwBitMask!= bMaskDWord)
+	{//if not "double word" write
+		OriginalValue = read_nic_dword(dev, dwRegAddr);
+		BitShift = rtl8192_CalculateBitShift(dwBitMask);
+		NewValue = (((OriginalValue) & (~dwBitMask)) | (dwData << BitShift));
+		write_nic_dword(dev, dwRegAddr, NewValue);
+	}else
+		write_nic_dword(dev, dwRegAddr, dwData);
+	return;
+}
+/******************************************************************************
+ *function:  This function reads specific bits from BB register
+ *   input:  net_device dev
+ *           u32	dwRegAddr  //target addr to be readback
+ *           u32	dwBitMask  //taget bit pos in the addr to be readback
+ *  output:  none
+ *  return:  u32	Data	//the readback register value
+ *  notice:
+ * ****************************************************************************/
+u32 rtl8192_QueryBBReg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask)
+{
+	u32 Ret = 0, OriginalValue, BitShift;
+
+	OriginalValue = read_nic_dword(dev, dwRegAddr);
+	BitShift = rtl8192_CalculateBitShift(dwBitMask);
+	Ret =(OriginalValue & dwBitMask) >> BitShift;
+
+	return (Ret);
+}
+static  u32 phy_FwRFSerialRead( struct net_device* dev, RF90_RADIO_PATH_E       eRFPath, u32 Offset  );
+
+static void phy_FwRFSerialWrite( struct net_device* dev, RF90_RADIO_PATH_E       eRFPath, u32  Offset, u32  Data);
+
+/******************************************************************************
+ *function:  This function read register from RF chip
+ *   input:  net_device dev
+ *   	     RF90_RADIO_PATH_E eRFPath //radio path of A/B/C/D
+ *           u32	Offset     //target address to be read
+ *  output:  none
+ *  return:  u32 	readback value
+ *  notice:  There are three types of serial operations:(1) Software serial write.(2)Hardware LSSI-Low Speed Serial Interface.(3)Hardware HSSI-High speed serial write. Driver here need to implement (1) and (2)---need more spec for this information.
+ * ****************************************************************************/
+u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32 ret = 0;
+	u32 NewOffset = 0;
+	BB_REGISTER_DEFINITION_T* pPhyReg = &priv->PHYRegDef[eRFPath];
+	rtl8192_setBBreg(dev, pPhyReg->rfLSSIReadBack, bLSSIReadBackData, 0);
+	//make sure RF register offset is correct
+	Offset &= 0x3f;
+
+	//switch page for 8256 RF IC
+	if (priv->rf_chip == RF_8256)
+	{
+		if (Offset >= 31)
+		{
+			priv->RfReg0Value[eRFPath] |= 0x140;
+			//Switch to Reg_Mode2 for Reg 31-45
+			rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16) );
+			//modify offset
+			NewOffset = Offset -30;
+		}
+		else if (Offset >= 16)
+		{
+			priv->RfReg0Value[eRFPath] |= 0x100;
+			priv->RfReg0Value[eRFPath] &= (~0x40);
+			//Switch to Reg_Mode 1 for Reg16-30
+			rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16) );
+
+			NewOffset = Offset - 15;
+		}
+		else
+			NewOffset = Offset;
+	}
+	else
+	{
+		RT_TRACE((COMP_PHY|COMP_ERR), "check RF type here, need to be 8256\n");
+		NewOffset = Offset;
+	}
+	//put desired read addr to LSSI control Register
+	rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadAddress, NewOffset);
+	//Issue a posedge trigger
+	//
+	rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2,  bLSSIReadEdge, 0x0);
+	rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2,  bLSSIReadEdge, 0x1);
+
+
+	// TODO: we should not delay such a  long time. Ask help from SD3
+	msleep(1);
+
+	ret = rtl8192_QueryBBReg(dev, pPhyReg->rfLSSIReadBack, bLSSIReadBackData);
+
+
+	// Switch back to Reg_Mode0;
+	if(priv->rf_chip == RF_8256)
+	{
+		priv->RfReg0Value[eRFPath] &= 0xebf;
+
+		rtl8192_setBBreg(
+			dev,
+			pPhyReg->rf3wireOffset,
+			bMaskDWord,
+			(priv->RfReg0Value[eRFPath] << 16));
+	}
+
+	return ret;
+
+}
+
+/******************************************************************************
+ *function:  This function write data to RF register
+ *   input:  net_device dev
+ *   	     RF90_RADIO_PATH_E eRFPath //radio path of A/B/C/D
+ *           u32	Offset     //target address to be written
+ *           u32	Data	//The new register data to be written
+ *  output:  none
+ *  return:  none
+ *  notice:  For RF8256 only.
+  ===========================================================
+ *Reg Mode	RegCTL[1]	RegCTL[0]		Note
+ *		(Reg00[12])	(Reg00[10])
+ *===========================================================
+ *Reg_Mode0	0		x			Reg 0 ~15(0x0 ~ 0xf)
+ *------------------------------------------------------------------
+ *Reg_Mode1	1		0			Reg 16 ~30(0x1 ~ 0xf)
+ *------------------------------------------------------------------
+ * Reg_Mode2	1		1			Reg 31 ~ 45(0x1 ~ 0xf)
+ *------------------------------------------------------------------
+ * ****************************************************************************/
+void rtl8192_phy_RFSerialWrite(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32 DataAndAddr = 0, NewOffset = 0;
+	BB_REGISTER_DEFINITION_T	*pPhyReg = &priv->PHYRegDef[eRFPath];
+
+	Offset &= 0x3f;
+	//spin_lock_irqsave(&priv->rf_lock, flags);
+//	down(&priv->rf_sem);
+	if (priv->rf_chip == RF_8256)
+	{
+
+		if (Offset >= 31)
+		{
+			priv->RfReg0Value[eRFPath] |= 0x140;
+			rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath] << 16));
+			NewOffset = Offset - 30;
+		}
+		else if (Offset >= 16)
+		{
+			priv->RfReg0Value[eRFPath] |= 0x100;
+			priv->RfReg0Value[eRFPath] &= (~0x40);
+			rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16));
+			NewOffset = Offset - 15;
+		}
+		else
+			NewOffset = Offset;
+	}
+	else
+	{
+		RT_TRACE((COMP_PHY|COMP_ERR), "check RF type here, need to be 8256\n");
+		NewOffset = Offset;
+	}
+
+	// Put write addr in [5:0]  and write data in [31:16]
+	DataAndAddr = (Data<<16) | (NewOffset&0x3f);
+
+	// Write Operation
+	rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr);
+
+
+	if(Offset==0x0)
+		priv->RfReg0Value[eRFPath] = Data;
+
+	// Switch back to Reg_Mode0;
+	if(priv->rf_chip == RF_8256)
+	{
+		if(Offset != 0)
+		{
+			priv->RfReg0Value[eRFPath] &= 0xebf;
+			rtl8192_setBBreg(
+				dev,
+				pPhyReg->rf3wireOffset,
+				bMaskDWord,
+				(priv->RfReg0Value[eRFPath] << 16));
+		}
+	}
+	//spin_unlock_irqrestore(&priv->rf_lock, flags);
+//	up(&priv->rf_sem);
+	return;
+}
+
+/******************************************************************************
+ *function:  This function set specific bits to RF register
+ *   input:  net_device dev
+ *   	     RF90_RADIO_PATH_E eRFPath //radio path of A/B/C/D
+ *           u32	RegAddr  //target addr to be modified
+ *           u32	BitMask  //taget bit pos in the addr to be modified
+ *           u32	Data     //value to be write
+ *  output:  none
+ *  return:  none
+ *  notice:
+ * ****************************************************************************/
+void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask, u32 Data)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32 Original_Value, BitShift, New_Value;
+//	u8	time = 0;
+
+	if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
+		return;
+
+	if (priv->Rf_Mode == RF_OP_By_FW)
+	{
+		if (BitMask != bMask12Bits) // RF data is 12 bits only
+		{
+			Original_Value = phy_FwRFSerialRead(dev, eRFPath, RegAddr);
+			BitShift =  rtl8192_CalculateBitShift(BitMask);
+			New_Value = ((Original_Value) & (~BitMask)) | (Data<< BitShift);
+
+			phy_FwRFSerialWrite(dev, eRFPath, RegAddr, New_Value);
+		}else
+			phy_FwRFSerialWrite(dev, eRFPath, RegAddr, Data);
+
+		udelay(200);
+
+	}
+	else
+	{
+		if (BitMask != bMask12Bits) // RF data is 12 bits only
+		{
+			Original_Value = rtl8192_phy_RFSerialRead(dev, eRFPath, RegAddr);
+			BitShift =  rtl8192_CalculateBitShift(BitMask);
+			New_Value = (((Original_Value) & (~BitMask)) | (Data<< BitShift));
+
+			rtl8192_phy_RFSerialWrite(dev, eRFPath, RegAddr, New_Value);
+		}else
+			rtl8192_phy_RFSerialWrite(dev, eRFPath, RegAddr, Data);
+	}
+	return;
+}
+
+/******************************************************************************
+ *function:  This function reads specific bits from RF register
+ *   input:  net_device dev
+ *           u32	RegAddr  //target addr to be readback
+ *           u32	BitMask  //taget bit pos in the addr to be readback
+ *  output:  none
+ *  return:  u32	Data	//the readback register value
+ *  notice:
+ * ****************************************************************************/
+u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask)
+{
+	u32 Original_Value, Readback_Value, BitShift;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+
+	if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
+		return 0;
+	if (priv->Rf_Mode == RF_OP_By_FW)
+	{
+		Original_Value = phy_FwRFSerialRead(dev, eRFPath, RegAddr);
+		BitShift =  rtl8192_CalculateBitShift(BitMask);
+		Readback_Value = (Original_Value & BitMask) >> BitShift;
+		udelay(200);
+		return (Readback_Value);
+	}
+	else
+	{
+		Original_Value = rtl8192_phy_RFSerialRead(dev, eRFPath, RegAddr);
+		BitShift =  rtl8192_CalculateBitShift(BitMask);
+		Readback_Value = (Original_Value & BitMask) >> BitShift;
+		return (Readback_Value);
+	}
+}
+/******************************************************************************
+ *function:  We support firmware to execute RF-R/W.
+ *   input:  dev
+ *  output:  none
+ *  return:  none
+ *  notice:
+ * ***************************************************************************/
+static	u32
+phy_FwRFSerialRead(
+	struct net_device* dev,
+	RF90_RADIO_PATH_E	eRFPath,
+	u32				Offset	)
+{
+	u32		retValue = 0;
+	u32		Data = 0;
+	u8		time = 0;
+	//DbgPrint("FW RF CTRL\n\r");
+	/* 2007/11/02 MH Firmware RF Write control. By Francis' suggestion, we can
+	   not execute the scheme in the initial step. Otherwise, RF-R/W will waste
+	   much time. This is only for site survey. */
+	// 1. Read operation need not insert data. bit 0-11
+	//Data &= bMask12Bits;
+	// 2. Write RF register address. Bit 12-19
+	Data |= ((Offset&0xFF)<<12);
+	// 3. Write RF path.  bit 20-21
+	Data |= ((eRFPath&0x3)<<20);
+	// 4. Set RF read indicator. bit 22=0
+	//Data |= 0x00000;
+	// 5. Trigger Fw to operate the command. bit 31
+	Data |= 0x80000000;
+	// 6. We can not execute read operation if bit 31 is 1.
+	while (read_nic_dword(dev, QPNR)&0x80000000)
+	{
+		// If FW can not finish RF-R/W for more than ?? times. We must reset FW.
+		if (time++ < 100)
+		{
+			//DbgPrint("FW not finish RF-R Time=%d\n\r", time);
+			udelay(10);
+		}
+		else
+			break;
+	}
+	// 7. Execute read operation.
+	write_nic_dword(dev, QPNR, Data);
+	// 8. Check if firmawre send back RF content.
+	while (read_nic_dword(dev, QPNR)&0x80000000)
+	{
+		// If FW can not finish RF-R/W for more than ?? times. We must reset FW.
+		if (time++ < 100)
+		{
+			//DbgPrint("FW not finish RF-W Time=%d\n\r", time);
+			udelay(10);
+		}
+		else
+			return	(0);
+	}
+	retValue = read_nic_dword(dev, RF_DATA);
+
+	return	(retValue);
+
+}	/* phy_FwRFSerialRead */
+
+/******************************************************************************
+ *function:  We support firmware to execute RF-R/W.
+ *   input:  dev
+ *  output:  none
+ *  return:  none
+ *  notice:
+ * ***************************************************************************/
+static void
+phy_FwRFSerialWrite(
+		struct net_device* dev,
+		RF90_RADIO_PATH_E	eRFPath,
+		u32				Offset,
+		u32				Data	)
+{
+	u8	time = 0;
+
+	//DbgPrint("N FW RF CTRL RF-%d OF%02x DATA=%03x\n\r", eRFPath, Offset, Data);
+	/* 2007/11/02 MH Firmware RF Write control. By Francis' suggestion, we can
+	   not execute the scheme in the initial step. Otherwise, RF-R/W will waste
+	   much time. This is only for site survey. */
+
+	// 1. Set driver write bit and 12 bit data. bit 0-11
+	//Data &= bMask12Bits;	// Done by uper layer.
+	// 2. Write RF register address. bit 12-19
+	Data |= ((Offset&0xFF)<<12);
+	// 3. Write RF path.  bit 20-21
+	Data |= ((eRFPath&0x3)<<20);
+	// 4. Set RF write indicator. bit 22=1
+	Data |= 0x400000;
+	// 5. Trigger Fw to operate the command. bit 31=1
+	Data |= 0x80000000;
+
+	// 6. Write operation. We can not write if bit 31 is 1.
+	while (read_nic_dword(dev, QPNR)&0x80000000)
+	{
+		// If FW can not finish RF-R/W for more than ?? times. We must reset FW.
+		if (time++ < 100)
+		{
+			//DbgPrint("FW not finish RF-W Time=%d\n\r", time);
+			udelay(10);
+		}
+		else
+			break;
+	}
+	// 7. No matter check bit. We always force the write. Because FW will
+	//    not accept the command.
+	write_nic_dword(dev, QPNR, Data);
+	/* 2007/11/02 MH Acoording to test, we must delay 20us to wait firmware
+	   to finish RF write operation. */
+	/* 2008/01/17 MH We support delay in firmware side now. */
+	//delay_us(20);
+
+}	/* phy_FwRFSerialWrite */
+
+
+/******************************************************************************
+ *function:  This function read BB parameters from Header file we gen,
+ *	     and do register read/write
+ *   input:  dev
+ *  output:  none
+ *  return:  none
+ *  notice:  BB parameters may change all the time, so please make
+ *           sure it has been synced with the newest.
+ * ***************************************************************************/
+void rtl8192_phy_configmac(struct net_device* dev)
+{
+	u32 dwArrayLen = 0, i;
+	u32* pdwArray = NULL;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	if(priv->btxpowerdata_readfromEEPORM)
+	{
+		RT_TRACE(COMP_PHY, "Rtl819XMACPHY_Array_PG\n");
+		dwArrayLen = MACPHY_Array_PGLength;
+		pdwArray = rtl819XMACPHY_Array_PG;
+
+	}
+	else
+	{
+		RT_TRACE(COMP_PHY, "Rtl819XMACPHY_Array\n");
+		dwArrayLen = MACPHY_ArrayLength;
+		pdwArray = rtl819XMACPHY_Array;
+	}
+	for(i = 0; i<dwArrayLen; i=i+3){
+		if(pdwArray[i] == 0x318)
+		{
+			pdwArray[i+2] = 0x00000800;
+			//DbgPrint("ptrArray[i], ptrArray[i+1], ptrArray[i+2] = %x, %x, %x\n",
+			//	ptrArray[i], ptrArray[i+1], ptrArray[i+2]);
+		}
+
+		RT_TRACE(COMP_DBG, "The Rtl8190MACPHY_Array[0] is %x Rtl8190MACPHY_Array[1] is %x Rtl8190MACPHY_Array[2] is %x\n",
+				pdwArray[i], pdwArray[i+1], pdwArray[i+2]);
+		rtl8192_setBBreg(dev, pdwArray[i], pdwArray[i+1], pdwArray[i+2]);
+	}
+	return;
+
+}
+
+/******************************************************************************
+ *function:  This function do dirty work
+ *   input:  dev
+ *  output:  none
+ *  return:  none
+ *  notice:  BB parameters may change all the time, so please make
+ *           sure it has been synced with the newest.
+ * ***************************************************************************/
+
+void rtl8192_phyConfigBB(struct net_device* dev, u8 ConfigType)
+{
+	u32 i;
+
+#ifdef TO_DO_LIST
+	u32 *rtl8192PhyRegArrayTable = NULL, *rtl8192AgcTabArrayTable = NULL;
+	if(Adapter->bInHctTest)
+	{
+		PHY_REGArrayLen = PHY_REGArrayLengthDTM;
+		AGCTAB_ArrayLen = AGCTAB_ArrayLengthDTM;
+		Rtl8190PHY_REGArray_Table = Rtl819XPHY_REGArrayDTM;
+		Rtl8190AGCTAB_Array_Table = Rtl819XAGCTAB_ArrayDTM;
+	}
+#endif
+	if (ConfigType == BaseBand_Config_PHY_REG)
+	{
+		for (i=0; i<PHY_REG_1T2RArrayLength; i+=2)
+		{
+			rtl8192_setBBreg(dev, rtl819XPHY_REG_1T2RArray[i], bMaskDWord, rtl819XPHY_REG_1T2RArray[i+1]);
+			RT_TRACE(COMP_DBG, "i: %x, The Rtl819xUsbPHY_REGArray[0] is %x Rtl819xUsbPHY_REGArray[1] is %x \n",i, rtl819XPHY_REG_1T2RArray[i], rtl819XPHY_REG_1T2RArray[i+1]);
+		}
+	}
+	else if (ConfigType == BaseBand_Config_AGC_TAB)
+	{
+		for (i=0; i<AGCTAB_ArrayLength; i+=2)
+		{
+			rtl8192_setBBreg(dev, rtl819XAGCTAB_Array[i], bMaskDWord, rtl819XAGCTAB_Array[i+1]);
+			RT_TRACE(COMP_DBG, "i:%x, The rtl819XAGCTAB_Array[0] is %x rtl819XAGCTAB_Array[1] is %x \n",i, rtl819XAGCTAB_Array[i], rtl819XAGCTAB_Array[i+1]);
+		}
+	}
+	return;
+
+
+}
+/******************************************************************************
+ *function:  This function initialize Register definition offset for Radio Path
+ *	     A/B/C/D
+ *   input:  net_device dev
+ *  output:  none
+ *  return:  none
+ *  notice:  Initialization value here is constant and it should never be changed
+ * ***************************************************************************/
+void rtl8192_InitBBRFRegDef(struct net_device* dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+// RF Interface Sowrtware Control
+	priv->PHYRegDef[RF90_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 LSBs if read 32-bit from 0x870
+	priv->PHYRegDef[RF90_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872)
+	priv->PHYRegDef[RF90_PATH_C].rfintfs = rFPGA0_XCD_RFInterfaceSW;// 16 LSBs if read 32-bit from 0x874
+	priv->PHYRegDef[RF90_PATH_D].rfintfs = rFPGA0_XCD_RFInterfaceSW;// 16 MSBs if read 32-bit from 0x874 (16-bit for 0x876)
+
+	// RF Interface Readback Value
+	priv->PHYRegDef[RF90_PATH_A].rfintfi = rFPGA0_XAB_RFInterfaceRB; // 16 LSBs if read 32-bit from 0x8E0
+	priv->PHYRegDef[RF90_PATH_B].rfintfi = rFPGA0_XAB_RFInterfaceRB;// 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2)
+	priv->PHYRegDef[RF90_PATH_C].rfintfi = rFPGA0_XCD_RFInterfaceRB;// 16 LSBs if read 32-bit from 0x8E4
+	priv->PHYRegDef[RF90_PATH_D].rfintfi = rFPGA0_XCD_RFInterfaceRB;// 16 MSBs if read 32-bit from 0x8E4 (16-bit for 0x8E6)
+
+	// RF Interface Output (and Enable)
+	priv->PHYRegDef[RF90_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; // 16 LSBs if read 32-bit from 0x860
+	priv->PHYRegDef[RF90_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; // 16 LSBs if read 32-bit from 0x864
+	priv->PHYRegDef[RF90_PATH_C].rfintfo = rFPGA0_XC_RFInterfaceOE;// 16 LSBs if read 32-bit from 0x868
+	priv->PHYRegDef[RF90_PATH_D].rfintfo = rFPGA0_XD_RFInterfaceOE;// 16 LSBs if read 32-bit from 0x86C
+
+	// RF Interface (Output and)  Enable
+	priv->PHYRegDef[RF90_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; // 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862)
+	priv->PHYRegDef[RF90_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; // 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866)
+	priv->PHYRegDef[RF90_PATH_C].rfintfe = rFPGA0_XC_RFInterfaceOE;// 16 MSBs if read 32-bit from 0x86A (16-bit for 0x86A)
+	priv->PHYRegDef[RF90_PATH_D].rfintfe = rFPGA0_XD_RFInterfaceOE;// 16 MSBs if read 32-bit from 0x86C (16-bit for 0x86E)
+
+	//Addr of LSSI. Wirte RF register by driver
+	priv->PHYRegDef[RF90_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; //LSSI Parameter
+	priv->PHYRegDef[RF90_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter;
+	priv->PHYRegDef[RF90_PATH_C].rf3wireOffset = rFPGA0_XC_LSSIParameter;
+	priv->PHYRegDef[RF90_PATH_D].rf3wireOffset = rFPGA0_XD_LSSIParameter;
+
+	// RF parameter
+	priv->PHYRegDef[RF90_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter;  //BB Band Select
+	priv->PHYRegDef[RF90_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter;
+	priv->PHYRegDef[RF90_PATH_C].rfLSSI_Select = rFPGA0_XCD_RFParameter;
+	priv->PHYRegDef[RF90_PATH_D].rfLSSI_Select = rFPGA0_XCD_RFParameter;
+
+	// Tx AGC Gain Stage (same for all path. Should we remove this?)
+	priv->PHYRegDef[RF90_PATH_A].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
+	priv->PHYRegDef[RF90_PATH_B].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
+	priv->PHYRegDef[RF90_PATH_C].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
+	priv->PHYRegDef[RF90_PATH_D].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
+
+	// Tranceiver A~D HSSI Parameter-1
+	priv->PHYRegDef[RF90_PATH_A].rfHSSIPara1 = rFPGA0_XA_HSSIParameter1;  //wire control parameter1
+	priv->PHYRegDef[RF90_PATH_B].rfHSSIPara1 = rFPGA0_XB_HSSIParameter1;  //wire control parameter1
+	priv->PHYRegDef[RF90_PATH_C].rfHSSIPara1 = rFPGA0_XC_HSSIParameter1;  //wire control parameter1
+	priv->PHYRegDef[RF90_PATH_D].rfHSSIPara1 = rFPGA0_XD_HSSIParameter1;  //wire control parameter1
+
+	// Tranceiver A~D HSSI Parameter-2
+	priv->PHYRegDef[RF90_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2;  //wire control parameter2
+	priv->PHYRegDef[RF90_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2;  //wire control parameter2
+	priv->PHYRegDef[RF90_PATH_C].rfHSSIPara2 = rFPGA0_XC_HSSIParameter2;  //wire control parameter2
+	priv->PHYRegDef[RF90_PATH_D].rfHSSIPara2 = rFPGA0_XD_HSSIParameter2;  //wire control parameter1
+
+	// RF switch Control
+	priv->PHYRegDef[RF90_PATH_A].rfSwitchControl = rFPGA0_XAB_SwitchControl; //TR/Ant switch control
+	priv->PHYRegDef[RF90_PATH_B].rfSwitchControl = rFPGA0_XAB_SwitchControl;
+	priv->PHYRegDef[RF90_PATH_C].rfSwitchControl = rFPGA0_XCD_SwitchControl;
+	priv->PHYRegDef[RF90_PATH_D].rfSwitchControl = rFPGA0_XCD_SwitchControl;
+
+	// AGC control 1
+	priv->PHYRegDef[RF90_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1;
+	priv->PHYRegDef[RF90_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1;
+	priv->PHYRegDef[RF90_PATH_C].rfAGCControl1 = rOFDM0_XCAGCCore1;
+	priv->PHYRegDef[RF90_PATH_D].rfAGCControl1 = rOFDM0_XDAGCCore1;
+
+	// AGC control 2
+	priv->PHYRegDef[RF90_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2;
+	priv->PHYRegDef[RF90_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2;
+	priv->PHYRegDef[RF90_PATH_C].rfAGCControl2 = rOFDM0_XCAGCCore2;
+	priv->PHYRegDef[RF90_PATH_D].rfAGCControl2 = rOFDM0_XDAGCCore2;
+
+	// RX AFE control 1
+	priv->PHYRegDef[RF90_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance;
+	priv->PHYRegDef[RF90_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance;
+	priv->PHYRegDef[RF90_PATH_C].rfRxIQImbalance = rOFDM0_XCRxIQImbalance;
+	priv->PHYRegDef[RF90_PATH_D].rfRxIQImbalance = rOFDM0_XDRxIQImbalance;
+
+	// RX AFE control 1
+	priv->PHYRegDef[RF90_PATH_A].rfRxAFE = rOFDM0_XARxAFE;
+	priv->PHYRegDef[RF90_PATH_B].rfRxAFE = rOFDM0_XBRxAFE;
+	priv->PHYRegDef[RF90_PATH_C].rfRxAFE = rOFDM0_XCRxAFE;
+	priv->PHYRegDef[RF90_PATH_D].rfRxAFE = rOFDM0_XDRxAFE;
+
+	// Tx AFE control 1
+	priv->PHYRegDef[RF90_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance;
+	priv->PHYRegDef[RF90_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance;
+	priv->PHYRegDef[RF90_PATH_C].rfTxIQImbalance = rOFDM0_XCTxIQImbalance;
+	priv->PHYRegDef[RF90_PATH_D].rfTxIQImbalance = rOFDM0_XDTxIQImbalance;
+
+	// Tx AFE control 2
+	priv->PHYRegDef[RF90_PATH_A].rfTxAFE = rOFDM0_XATxAFE;
+	priv->PHYRegDef[RF90_PATH_B].rfTxAFE = rOFDM0_XBTxAFE;
+	priv->PHYRegDef[RF90_PATH_C].rfTxAFE = rOFDM0_XCTxAFE;
+	priv->PHYRegDef[RF90_PATH_D].rfTxAFE = rOFDM0_XDTxAFE;
+
+	// Tranceiver LSSI Readback
+	priv->PHYRegDef[RF90_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack;
+	priv->PHYRegDef[RF90_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack;
+	priv->PHYRegDef[RF90_PATH_C].rfLSSIReadBack = rFPGA0_XC_LSSIReadBack;
+	priv->PHYRegDef[RF90_PATH_D].rfLSSIReadBack = rFPGA0_XD_LSSIReadBack;
+
+}
+/******************************************************************************
+ *function:  This function is to write register and then readback to make sure whether BB and RF is OK
+ *   input:  net_device dev
+ *   	     HW90_BLOCK_E CheckBlock
+ *   	     RF90_RADIO_PATH_E eRFPath  //only used when checkblock is HW90_BLOCK_RF
+ *  output:  none
+ *  return:  return whether BB and RF is ok(0:OK; 1:Fail)
+ *  notice:  This function may be removed in the ASIC
+ * ***************************************************************************/
+u8 rtl8192_phy_checkBBAndRF(struct net_device* dev, HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath)
+{
+//	struct r8192_priv *priv = ieee80211_priv(dev);
+//	BB_REGISTER_DEFINITION_T *pPhyReg = &priv->PHYRegDef[eRFPath];
+	u8 ret = 0;
+	u32 i, CheckTimes = 4, dwRegRead = 0;
+	u32 WriteAddr[4];
+	u32 WriteData[] = {0xfffff027, 0xaa55a02f, 0x00000027, 0x55aa502f};
+	// Initialize register address offset to be checked
+	WriteAddr[HW90_BLOCK_MAC] = 0x100;
+	WriteAddr[HW90_BLOCK_PHY0] = 0x900;
+	WriteAddr[HW90_BLOCK_PHY1] = 0x800;
+	WriteAddr[HW90_BLOCK_RF] = 0x3;
+	RT_TRACE(COMP_PHY, "=======>%s(), CheckBlock:%d\n", __FUNCTION__, CheckBlock);
+	for(i=0 ; i < CheckTimes ; i++)
+	{
+
+		//
+		// Write Data to register and readback
+		//
+		switch(CheckBlock)
+		{
+		case HW90_BLOCK_MAC:
+			RT_TRACE(COMP_ERR, "PHY_CheckBBRFOK(): Never Write 0x100 here!");
+			break;
+
+		case HW90_BLOCK_PHY0:
+		case HW90_BLOCK_PHY1:
+			write_nic_dword(dev, WriteAddr[CheckBlock], WriteData[i]);
+			dwRegRead = read_nic_dword(dev, WriteAddr[CheckBlock]);
+			break;
+
+		case HW90_BLOCK_RF:
+			WriteData[i] &= 0xfff;
+			rtl8192_phy_SetRFReg(dev, eRFPath, WriteAddr[HW90_BLOCK_RF], bMask12Bits, WriteData[i]);
+			// TODO: we should not delay for such a long time. Ask SD3
+			msleep(1);
+			dwRegRead = rtl8192_phy_QueryRFReg(dev, eRFPath, WriteAddr[HW90_BLOCK_RF], bMask12Bits);
+			msleep(1);
+			break;
+
+		default:
+			ret = 1;
+			break;
+		}
+
+
+		//
+		// Check whether readback data is correct
+		//
+		if(dwRegRead != WriteData[i])
+		{
+			RT_TRACE((COMP_PHY|COMP_ERR), "====>error=====dwRegRead: %x, WriteData: %x \n", dwRegRead, WriteData[i]);
+			ret = 1;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+
+/******************************************************************************
+ *function:  This function initialize BB&RF
+ *   input:  net_device dev
+ *  output:  none
+ *  return:  none
+ *  notice:  Initialization value may change all the time, so please make
+ *           sure it has been synced with the newest.
+ * ***************************************************************************/
+void rtl8192_BB_Config_ParaFile(struct net_device* dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 bRegValue = 0, eCheckItem = 0, rtStatus = 0;
+	u32 dwRegValue = 0;
+	/**************************************
+	//<1>Initialize BaseBand
+	**************************************/
+
+	/*--set BB Global Reset--*/
+	bRegValue = read_nic_byte(dev, BB_GLOBAL_RESET);
+	write_nic_byte(dev, BB_GLOBAL_RESET,(bRegValue|BB_GLOBAL_RESET_BIT));
+	mdelay(50);
+	/*---set BB reset Active---*/
+	dwRegValue = read_nic_dword(dev, CPU_GEN);
+	write_nic_dword(dev, CPU_GEN, (dwRegValue&(~CPU_GEN_BB_RST)));
+
+	/*----Ckeck FPGAPHY0 and PHY1 board is OK----*/
+	// TODO: this function should be removed on ASIC , Emily 2007.2.2
+	for(eCheckItem=(HW90_BLOCK_E)HW90_BLOCK_PHY0; eCheckItem<=HW90_BLOCK_PHY1; eCheckItem++)
+	{
+		rtStatus  = rtl8192_phy_checkBBAndRF(dev, (HW90_BLOCK_E)eCheckItem, (RF90_RADIO_PATH_E)0); //don't care RF path
+		if(rtStatus != 0)
+		{
+			RT_TRACE((COMP_ERR | COMP_PHY), "PHY_RF8256_Config():Check PHY%d Fail!!\n", eCheckItem-1);
+			return ;
+		}
+	}
+	/*---- Set CCK and OFDM Block "OFF"----*/
+	rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn|bOFDMEn, 0x0);
+	/*----BB Register Initilazation----*/
+	//==m==>Set PHY REG From Header<==m==
+	rtl8192_phyConfigBB(dev, BaseBand_Config_PHY_REG);
+
+	/*----Set BB reset de-Active----*/
+	dwRegValue = read_nic_dword(dev, CPU_GEN);
+	write_nic_dword(dev, CPU_GEN, (dwRegValue|CPU_GEN_BB_RST));
+
+	/*----BB AGC table Initialization----*/
+	//==m==>Set PHY REG From Header<==m==
+	rtl8192_phyConfigBB(dev, BaseBand_Config_AGC_TAB);
+
+	/*----Enable XSTAL ----*/
+	write_nic_byte_E(dev, 0x5e, 0x00);
+	if (priv->card_8192_version == (u8)VERSION_819xU_A)
+	{
+		//Antenna gain offset from B/C/D to A
+		dwRegValue = (priv->AntennaTxPwDiff[1]<<4 | priv->AntennaTxPwDiff[0]);
+		rtl8192_setBBreg(dev, rFPGA0_TxGainStage, (bXBTxAGC|bXCTxAGC), dwRegValue);
+
+		//XSTALLCap
+		dwRegValue = priv->CrystalCap & 0xf;
+		rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, bXtalCap, dwRegValue);
+	}
+
+	// Check if the CCK HighPower is turned ON.
+	// This is used to calculate PWDB.
+	priv->bCckHighPower = (u8)(rtl8192_QueryBBReg(dev, rFPGA0_XA_HSSIParameter2, 0x200));
+	return;
+}
+/******************************************************************************
+ *function:  This function initialize BB&RF
+ *   input:  net_device dev
+ *  output:  none
+ *  return:  none
+ *  notice:  Initialization value may change all the time, so please make
+ *           sure it has been synced with the newest.
+ * ***************************************************************************/
+void rtl8192_BBConfig(struct net_device* dev)
+{
+	rtl8192_InitBBRFRegDef(dev);
+	//config BB&RF. As hardCode based initialization has not been well
+	//implemented, so use file first.FIXME:should implement it for hardcode?
+	rtl8192_BB_Config_ParaFile(dev);
+	return;
+}
+
+/******************************************************************************
+ *function:  This function obtains the initialization value of Tx power Level offset
+ *   input:  net_device dev
+ *  output:  none
+ *  return:  none
+ * ***************************************************************************/
+void rtl8192_phy_getTxPower(struct net_device* dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	priv->MCSTxPowerLevelOriginalOffset[0] =
+		read_nic_dword(dev, rTxAGC_Rate18_06);
+	priv->MCSTxPowerLevelOriginalOffset[1] =
+		read_nic_dword(dev, rTxAGC_Rate54_24);
+	priv->MCSTxPowerLevelOriginalOffset[2] =
+		read_nic_dword(dev, rTxAGC_Mcs03_Mcs00);
+	priv->MCSTxPowerLevelOriginalOffset[3] =
+		read_nic_dword(dev, rTxAGC_Mcs07_Mcs04);
+	priv->MCSTxPowerLevelOriginalOffset[4] =
+		read_nic_dword(dev, rTxAGC_Mcs11_Mcs08);
+	priv->MCSTxPowerLevelOriginalOffset[5] =
+		read_nic_dword(dev, rTxAGC_Mcs15_Mcs12);
+
+	// read rx initial gain
+	priv->DefaultInitialGain[0] = read_nic_byte(dev, rOFDM0_XAAGCCore1);
+	priv->DefaultInitialGain[1] = read_nic_byte(dev, rOFDM0_XBAGCCore1);
+	priv->DefaultInitialGain[2] = read_nic_byte(dev, rOFDM0_XCAGCCore1);
+	priv->DefaultInitialGain[3] = read_nic_byte(dev, rOFDM0_XDAGCCore1);
+	RT_TRACE(COMP_INIT, "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x) \n",
+		priv->DefaultInitialGain[0], priv->DefaultInitialGain[1],
+		priv->DefaultInitialGain[2], priv->DefaultInitialGain[3]);
+
+	// read framesync
+	priv->framesync = read_nic_byte(dev, rOFDM0_RxDetector3);
+	priv->framesyncC34 = read_nic_byte(dev, rOFDM0_RxDetector2);
+	RT_TRACE(COMP_INIT, "Default framesync (0x%x) = 0x%x \n",
+		rOFDM0_RxDetector3, priv->framesync);
+
+	// read SIFS (save the value read fome MACPHY_REG.txt)
+	priv->SifsTime = read_nic_word(dev, SIFS);
+
+	return;
+}
+
+/******************************************************************************
+ *function:  This function obtains the initialization value of Tx power Level offset
+ *   input:  net_device dev
+ *  output:  none
+ *  return:  none
+ * ***************************************************************************/
+void rtl8192_phy_setTxPower(struct net_device* dev, u8 channel)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8	powerlevel = priv->TxPowerLevelCCK[channel-1];
+	u8	powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1];
+
+	switch(priv->rf_chip)
+	{
+	case RF_8256:
+		PHY_SetRF8256CCKTxPower(dev, powerlevel); //need further implement
+		PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G);
+		break;
+	default:
+//	case RF_8225:
+//	case RF_8258:
+		RT_TRACE((COMP_PHY|COMP_ERR), "error RF chipID(8225 or 8258) in function %s()\n", __FUNCTION__);
+		break;
+	}
+	return;
+}
+
+/******************************************************************************
+ *function:  This function check Rf chip to do RF config
+ *   input:  net_device dev
+ *  output:  none
+ *  return:  only 8256 is supported
+ * ***************************************************************************/
+void rtl8192_phy_RFConfig(struct net_device* dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	switch(priv->rf_chip)
+	{
+		case RF_8256:
+			PHY_RF8256_Config(dev);
+			break;
+	//	case RF_8225:
+	//	case RF_8258:
+		default:
+			RT_TRACE(COMP_ERR, "error chip id\n");
+			break;
+	}
+	return;
+}
+
+/******************************************************************************
+ *function:  This function update Initial gain
+ *   input:  net_device dev
+ *  output:  none
+ *  return:  As Windows has not implemented this, wait for complement
+ * ***************************************************************************/
+void rtl8192_phy_updateInitGain(struct net_device* dev)
+{
+	return;
+}
+
+/******************************************************************************
+ *function:  This function read RF parameters from general head file, and do RF 3-wire
+ *   input:  net_device dev
+ *  output:  none
+ *  return:  return code show if RF configuration is successful(0:pass, 1:fail)
+ *    Note:  Delay may be required for RF configuration
+ * ***************************************************************************/
+u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E	eRFPath)
+{
+
+	int i;
+	//u32* pRFArray;
+	u8 ret = 0;
+
+	switch(eRFPath){
+		case RF90_PATH_A:
+			for(i = 0;i<RadioA_ArrayLength; i=i+2){
+
+				if(rtl819XRadioA_Array[i] == 0xfe){
+						mdelay(100);
+						continue;
+				}
+				rtl8192_phy_SetRFReg(dev, eRFPath, rtl819XRadioA_Array[i], bMask12Bits, rtl819XRadioA_Array[i+1]);
+				mdelay(1);
+
+			}
+			break;
+		case RF90_PATH_B:
+			for(i = 0;i<RadioB_ArrayLength; i=i+2){
+
+				if(rtl819XRadioB_Array[i] == 0xfe){
+						mdelay(100);
+						continue;
+				}
+				rtl8192_phy_SetRFReg(dev, eRFPath, rtl819XRadioB_Array[i], bMask12Bits, rtl819XRadioB_Array[i+1]);
+				mdelay(1);
+
+			}
+			break;
+		case RF90_PATH_C:
+			for(i = 0;i<RadioC_ArrayLength; i=i+2){
+
+				if(rtl819XRadioC_Array[i] == 0xfe){
+						mdelay(100);
+						continue;
+				}
+				rtl8192_phy_SetRFReg(dev, eRFPath, rtl819XRadioC_Array[i], bMask12Bits, rtl819XRadioC_Array[i+1]);
+				mdelay(1);
+
+			}
+			break;
+		case RF90_PATH_D:
+			for(i = 0;i<RadioD_ArrayLength; i=i+2){
+
+				if(rtl819XRadioD_Array[i] == 0xfe){
+						mdelay(100);
+						continue;
+				}
+				rtl8192_phy_SetRFReg(dev, eRFPath, rtl819XRadioD_Array[i], bMask12Bits, rtl819XRadioD_Array[i+1]);
+				mdelay(1);
+
+			}
+			break;
+		default:
+			break;
+	}
+
+	return ret;;
+
+}
+/******************************************************************************
+ *function:  This function set Tx Power of the channel
+ *   input:  struct net_device *dev
+ *   	     u8 		channel
+ *  output:  none
+ *  return:  none
+ *    Note:
+ * ***************************************************************************/
+void rtl8192_SetTxPowerLevel(struct net_device *dev, u8 channel)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8	powerlevel = priv->TxPowerLevelCCK[channel-1];
+	u8	powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1];
+
+	switch(priv->rf_chip)
+	{
+	case RF_8225:
+#ifdef TO_DO_LIST
+		PHY_SetRF8225CckTxPower(Adapter, powerlevel);
+		PHY_SetRF8225OfdmTxPower(Adapter, powerlevelOFDM24G);
+#endif
+		break;
+
+	case RF_8256:
+		PHY_SetRF8256CCKTxPower(dev, powerlevel);
+		PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G);
+		break;
+
+	case RF_8258:
+		break;
+	default:
+		RT_TRACE(COMP_ERR, "unknown rf chip ID in rtl8192_SetTxPowerLevel()\n");
+		break;
+	}
+	return;
+}
+
+/******************************************************************************
+ *function:  This function set RF state on or off
+ *   input:  struct net_device *dev
+ *   	     RT_RF_POWER_STATE eRFPowerState  //Power State to set
+ *  output:  none
+ *  return:  none
+ *    Note:
+ * ***************************************************************************/
+bool rtl8192_SetRFPowerState(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState)
+{
+	bool				bResult = true;
+//	u8					eRFPath;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	if(eRFPowerState == priv->ieee80211->eRFPowerState)
+		return false;
+
+	if(priv->SetRFPowerStateInProgress == true)
+		return false;
+
+	priv->SetRFPowerStateInProgress = true;
+
+	switch(priv->rf_chip)
+	{
+		case RF_8256:
+		switch( eRFPowerState )
+		{
+			case eRfOn:
+	//RF-A, RF-B
+					//enable RF-Chip A/B
+					rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1);	// 0x860[4]
+					//analog to digital on
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8]
+					//digital to analog on
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x3); // 0x880[4:3]
+					//rx antenna on
+					rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0]
+					//rx antenna on
+					rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0]
+					//analog to digital part2 on
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5]
+
+				break;
+
+			case eRfSleep:
+
+				break;
+
+			case eRfOff:
+					//RF-A, RF-B
+					//disable RF-Chip A/B
+					rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0);	// 0x860[4]
+					//analog to digital off, for power save
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8]
+					//digital to analog off, for power save
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x0); // 0x880[4:3]
+					//rx antenna off
+					rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0);// 0xc04[3:0]
+					//rx antenna off
+					rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0);// 0xd04[3:0]
+					//analog to digital part2 off, for power save
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0); // 0x880[6:5]
+
+				break;
+
+			default:
+				bResult = false;
+				RT_TRACE(COMP_ERR, "SetRFPowerState819xUsb(): unknow state to set: 0x%X!!!\n", eRFPowerState);
+				break;
+		}
+			break;
+		default:
+			RT_TRACE(COMP_ERR, "Not support rf_chip(%x)\n", priv->rf_chip);
+			break;
+	}
+#ifdef TO_DO_LIST
+	if(bResult)
+	{
+		// Update current RF state variable.
+		pHalData->eRFPowerState = eRFPowerState;
+		switch(pHalData->RFChipID )
+		{
+			case RF_8256:
+		switch(pHalData->eRFPowerState)
+				{
+				case eRfOff:
+					//
+					//If Rf off reason is from IPS, Led should blink with no link, by Maddest 071015
+					//
+					if(pMgntInfo->RfOffReason==RF_CHANGE_BY_IPS )
+					{
+						Adapter->HalFunc.LedControlHandler(Adapter,LED_CTL_NO_LINK);
+					}
+					else
+					{
+						// Turn off LED if RF is not ON.
+						Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_OFF);
+					}
+					break;
+
+				case eRfOn:
+					// Turn on RF we are still linked, which might happen when
+					// we quickly turn off and on HW RF. 2006.05.12, by rcnjko.
+					if( pMgntInfo->bMediaConnect == TRUE )
+					{
+						Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_LINK);
+					}
+					else
+					{
+						// Turn off LED if RF is not ON.
+						Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_NO_LINK);
+					}
+					break;
+
+				default:
+					// do nothing.
+					break;
+				}// Switch RF state
+				break;
+
+				default:
+					RT_TRACE(COMP_RF, DBG_LOUD, ("SetRFPowerState8190(): Unknown RF type\n"));
+					break;
+			}
+
+	}
+#endif
+	priv->SetRFPowerStateInProgress = false;
+
+	return bResult;
+}
+
+/****************************************************************************************
+ *function:  This function set command table variable(struct SwChnlCmd).
+ *   input:  SwChnlCmd*		CmdTable 	//table to be set.
+ *   	     u32		CmdTableIdx 	//variable index in table to be set
+ *   	     u32		CmdTableSz	//table size.
+ *   	     SwChnlCmdID	CmdID		//command ID to set.
+ *	     u32		Para1
+ *	     u32		Para2
+ *	     u32		msDelay
+ *  output:
+ *  return:  true if finished, false otherwise
+ *    Note:
+ * ************************************************************************************/
+u8 rtl8192_phy_SetSwChnlCmdArray(
+	SwChnlCmd*		CmdTable,
+	u32			CmdTableIdx,
+	u32			CmdTableSz,
+	SwChnlCmdID		CmdID,
+	u32			Para1,
+	u32			Para2,
+	u32			msDelay
+	)
+{
+	SwChnlCmd* pCmd;
+
+	if(CmdTable == NULL)
+	{
+		RT_TRACE(COMP_ERR, "phy_SetSwChnlCmdArray(): CmdTable cannot be NULL.\n");
+		return false;
+	}
+	if(CmdTableIdx >= CmdTableSz)
+	{
+		RT_TRACE(COMP_ERR, "phy_SetSwChnlCmdArray(): Access invalid index, please check size of the table, CmdTableIdx:%d, CmdTableSz:%d\n",
+				CmdTableIdx, CmdTableSz);
+		return false;
+	}
+
+	pCmd = CmdTable + CmdTableIdx;
+	pCmd->CmdID = CmdID;
+	pCmd->Para1 = Para1;
+	pCmd->Para2 = Para2;
+	pCmd->msDelay = msDelay;
+
+	return true;
+}
+/******************************************************************************
+ *function:  This function set channel step by step
+ *   input:  struct net_device *dev
+ *   	     u8 		channel
+ *   	     u8* 		stage //3 stages
+ *   	     u8* 		step  //
+ *   	     u32* 		delay //whether need to delay
+ *  output:  store new stage, step and delay for next step(combine with function above)
+ *  return:  true if finished, false otherwise
+ *    Note:  Wait for simpler function to replace it //wb
+ * ***************************************************************************/
+u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel, u8* stage, u8* step, u32* delay)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+//	PCHANNEL_ACCESS_SETTING	pChnlAccessSetting;
+	SwChnlCmd				PreCommonCmd[MAX_PRECMD_CNT];
+	u32					PreCommonCmdCnt;
+	SwChnlCmd				PostCommonCmd[MAX_POSTCMD_CNT];
+	u32					PostCommonCmdCnt;
+	SwChnlCmd				RfDependCmd[MAX_RFDEPENDCMD_CNT];
+	u32					RfDependCmdCnt;
+	SwChnlCmd				*CurrentCmd = NULL;
+	//RF90_RADIO_PATH_E		eRFPath;
+	u8		eRFPath;
+//	u32		RfRetVal;
+//	u8		RetryCnt;
+
+	RT_TRACE(COMP_CH, "====>%s()====stage:%d, step:%d, channel:%d\n", __FUNCTION__, *stage, *step, channel);
+//	RT_ASSERT(IsLegalChannel(Adapter, channel), ("illegal channel: %d\n", channel));
+#ifdef ENABLE_DOT11D
+	if (!IsLegalChannel(priv->ieee80211, channel))
+	{
+		RT_TRACE(COMP_ERR, "=============>set to illegal channel:%d\n", channel);
+		return true; //return true to tell upper caller function this channel setting is finished! Or it will in while loop.
+	}
+#endif
+//FIXME:need to check whether channel is legal or not here.WB
+
+
+	//for(eRFPath = RF90_PATH_A; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
+//	for(eRFPath = 0; eRFPath <RF90_PATH_MAX; eRFPath++)
+//	{
+//		if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
+//			continue;
+		// <1> Fill up pre common command.
+		PreCommonCmdCnt = 0;
+		rtl8192_phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, MAX_PRECMD_CNT,
+					CmdID_SetTxPowerLevel, 0, 0, 0);
+		rtl8192_phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, MAX_PRECMD_CNT,
+					CmdID_End, 0, 0, 0);
+
+		// <2> Fill up post common command.
+		PostCommonCmdCnt = 0;
+
+		rtl8192_phy_SetSwChnlCmdArray(PostCommonCmd, PostCommonCmdCnt++, MAX_POSTCMD_CNT,
+					CmdID_End, 0, 0, 0);
+
+		// <3> Fill up RF dependent command.
+		RfDependCmdCnt = 0;
+		switch( priv->rf_chip )
+		{
+		case RF_8225:
+			if (!(channel >= 1 && channel <= 14))
+			{
+				RT_TRACE(COMP_ERR, "illegal channel for Zebra 8225: %d\n", channel);
+				return true;
+			}
+			rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
+				CmdID_RF_WriteReg, rZebra1_Channel, RF_CHANNEL_TABLE_ZEBRA[channel], 10);
+			rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
+				CmdID_End, 0, 0, 0);
+			break;
+
+		case RF_8256:
+			// TEST!! This is not the table for 8256!!
+			if (!(channel >= 1 && channel <= 14))
+			{
+				RT_TRACE(COMP_ERR, "illegal channel for Zebra 8256: %d\n", channel);
+				return true;
+			}
+			rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
+				CmdID_RF_WriteReg, rZebra1_Channel, channel, 10);
+			rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
+			CmdID_End, 0, 0, 0);
+			break;
+
+		case RF_8258:
+			break;
+
+		default:
+			RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", priv->rf_chip);
+			return true;
+			break;
+		}
+
+
+		do{
+			switch(*stage)
+			{
+			case 0:
+				CurrentCmd=&PreCommonCmd[*step];
+				break;
+			case 1:
+				CurrentCmd=&RfDependCmd[*step];
+				break;
+			case 2:
+				CurrentCmd=&PostCommonCmd[*step];
+				break;
+			}
+
+			if(CurrentCmd->CmdID==CmdID_End)
+			{
+				if((*stage)==2)
+				{
+					(*delay)=CurrentCmd->msDelay;
+					return true;
+				}
+				else
+				{
+					(*stage)++;
+					(*step)=0;
+					continue;
+				}
+			}
+
+			switch(CurrentCmd->CmdID)
+			{
+			case CmdID_SetTxPowerLevel:
+				if(priv->card_8192_version == (u8)VERSION_819xU_A) //xiong: consider it later!
+					rtl8192_SetTxPowerLevel(dev,channel);
+				break;
+			case CmdID_WritePortUlong:
+				write_nic_dword(dev, CurrentCmd->Para1, CurrentCmd->Para2);
+				break;
+			case CmdID_WritePortUshort:
+				write_nic_word(dev, CurrentCmd->Para1, (u16)CurrentCmd->Para2);
+				break;
+			case CmdID_WritePortUchar:
+				write_nic_byte(dev, CurrentCmd->Para1, (u8)CurrentCmd->Para2);
+				break;
+			case CmdID_RF_WriteReg:
+				for(eRFPath = 0; eRFPath < RF90_PATH_MAX; eRFPath++)
+				{
+				rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, CurrentCmd->Para1, bZebra1_ChannelNum, CurrentCmd->Para2);
+				}
+				break;
+			default:
+				break;
+			}
+
+			break;
+		}while(true);
+//	}/*for(Number of RF paths)*/
+
+	(*delay)=CurrentCmd->msDelay;
+	(*step)++;
+	return false;
+}
+
+/******************************************************************************
+ *function:  This function does acturally set channel work
+ *   input:  struct net_device *dev
+ *   	     u8 		channel
+ *  output:  none
+ *  return:  noin
+ *    Note:  We should not call this function directly
+ * ***************************************************************************/
+void rtl8192_phy_FinishSwChnlNow(struct net_device *dev, u8 channel)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32	delay = 0;
+
+	while(!rtl8192_phy_SwChnlStepByStep(dev,channel,&priv->SwChnlStage,&priv->SwChnlStep,&delay))
+	{
+	//	if(delay>0)
+	//		msleep(delay);//or mdelay? need further consideration
+		if(!priv->up)
+			break;
+	}
+}
+/******************************************************************************
+ *function:  Callback routine of the work item for switch channel.
+ *   input:
+ *
+ *  output:  none
+ *  return:  noin
+ * ***************************************************************************/
+void rtl8192_SwChnl_WorkItem(struct net_device *dev)
+{
+
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	RT_TRACE(COMP_CH, "==> SwChnlCallback819xUsbWorkItem(), chan:%d\n", priv->chan);
+
+
+	rtl8192_phy_FinishSwChnlNow(dev , priv->chan);
+
+	RT_TRACE(COMP_CH, "<== SwChnlCallback819xUsbWorkItem()\n");
+}
+
+/******************************************************************************
+ *function:  This function scheduled actural workitem to set channel
+ *   input:  net_device dev
+ *   	     u8		channel //channel to set
+ *  output:  none
+ *  return:  return code show if workitem is scheduled(1:pass, 0:fail)
+ *    Note:  Delay may be required for RF configuration
+ * ***************************************************************************/
+u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	RT_TRACE(COMP_CH, "=====>%s(), SwChnlInProgress:%d\n", __FUNCTION__, priv->SwChnlInProgress);
+	if(!priv->up)
+		return false;
+	if(priv->SwChnlInProgress)
+		return false;
+
+//	if(pHalData->SetBWModeInProgress)
+//		return;
+if (0) //to test current channel from RF reg 0x7.
+{
+	u8		eRFPath;
+	for(eRFPath = 0; eRFPath < 2; eRFPath++){
+	printk("====>set channel:%x\n",rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x7, bZebra1_ChannelNum));
+	udelay(10);
+	}
+}
+	//--------------------------------------------
+	switch(priv->ieee80211->mode)
+	{
+	case WIRELESS_MODE_A:
+	case WIRELESS_MODE_N_5G:
+		if (channel<=14){
+			RT_TRACE(COMP_ERR, "WIRELESS_MODE_A but channel<=14");
+			return false;
+		}
+		break;
+	case WIRELESS_MODE_B:
+		if (channel>14){
+			RT_TRACE(COMP_ERR, "WIRELESS_MODE_B but channel>14");
+			return false;
+		}
+		break;
+	case WIRELESS_MODE_G:
+	case WIRELESS_MODE_N_24G:
+		if (channel>14){
+			RT_TRACE(COMP_ERR, "WIRELESS_MODE_G but channel>14");
+			return false;
+		}
+		break;
+	}
+	//--------------------------------------------
+
+	priv->SwChnlInProgress = true;
+	if(channel == 0)
+		channel = 1;
+
+	priv->chan=channel;
+
+	priv->SwChnlStage=0;
+	priv->SwChnlStep=0;
+//	schedule_work(&(priv->SwChnlWorkItem));
+//	rtl8192_SwChnl_WorkItem(dev);
+	if(priv->up) {
+//		queue_work(priv->priv_wq,&(priv->SwChnlWorkItem));
+	rtl8192_SwChnl_WorkItem(dev);
+	}
+
+	priv->SwChnlInProgress = false;
+	return true;
+}
+
+
+//
+/******************************************************************************
+ *function:  Callback routine of the work item for set bandwidth mode.
+ *   input:  struct net_device *dev
+ *   	     HT_CHANNEL_WIDTH	Bandwidth  //20M or 40M
+ *   	     HT_EXTCHNL_OFFSET Offset 	   //Upper, Lower, or Don't care
+ *  output:  none
+ *  return:  none
+ *    Note:  I doubt whether SetBWModeInProgress flag is necessary as we can
+ *    	     test whether current work in the queue or not.//do I?
+ * ***************************************************************************/
+void rtl8192_SetBWModeWorkItem(struct net_device *dev)
+{
+
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 regBwOpMode;
+
+	RT_TRACE(COMP_SWBW, "==>rtl8192_SetBWModeWorkItem()  Switch to %s bandwidth\n", \
+					priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20?"20MHz":"40MHz")
+
+
+	if(priv->rf_chip == RF_PSEUDO_11N)
+	{
+		priv->SetBWModeInProgress= false;
+		return;
+	}
+
+	//<1>Set MAC register
+	regBwOpMode = read_nic_byte(dev, BW_OPMODE);
+
+	switch(priv->CurrentChannelBW)
+	{
+		case HT_CHANNEL_WIDTH_20:
+			regBwOpMode |= BW_OPMODE_20MHZ;
+		       // 2007/02/07 Mark by Emily becasue we have not verify whether this register works
+			write_nic_byte(dev, BW_OPMODE, regBwOpMode);
+			break;
+
+		case HT_CHANNEL_WIDTH_20_40:
+			regBwOpMode &= ~BW_OPMODE_20MHZ;
+			// 2007/02/07 Mark by Emily becasue we have not verify whether this register works
+			write_nic_byte(dev, BW_OPMODE, regBwOpMode);
+			break;
+
+		default:
+			RT_TRACE(COMP_ERR, "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n",priv->CurrentChannelBW);
+			break;
+	}
+
+	//<2>Set PHY related register
+	switch(priv->CurrentChannelBW)
+	{
+		case HT_CHANNEL_WIDTH_20:
+			// Add by Vivi 20071119
+			rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x0);
+			rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x0);
+			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 1);
+
+			// Correct the tx power for CCK rate in 20M. Suggest by YN, 20071207
+			priv->cck_present_attentuation =
+				priv->cck_present_attentuation_20Mdefault + priv->cck_present_attentuation_difference;
+
+			if(priv->cck_present_attentuation > 22)
+				priv->cck_present_attentuation= 22;
+			if(priv->cck_present_attentuation< 0)
+				priv->cck_present_attentuation = 0;
+			RT_TRACE(COMP_INIT, "20M, pHalData->CCKPresentAttentuation = %d\n", priv->cck_present_attentuation);
+
+			if(priv->chan == 14 && !priv->bcck_in_ch14)
+			{
+				priv->bcck_in_ch14 = TRUE;
+				dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
+			}
+			else if(priv->chan != 14 && priv->bcck_in_ch14)
+			{
+				priv->bcck_in_ch14 = FALSE;
+				dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
+			}
+			else
+				dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
+
+			break;
+		case HT_CHANNEL_WIDTH_20_40:
+			// Add by Vivi 20071119
+			rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x1);
+			rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x1);
+			rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, (priv->nCur40MhzPrimeSC>>1));
+			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 0);
+			rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00, priv->nCur40MhzPrimeSC);
+			priv->cck_present_attentuation =
+				priv->cck_present_attentuation_40Mdefault + priv->cck_present_attentuation_difference;
+
+			if(priv->cck_present_attentuation > 22)
+				priv->cck_present_attentuation = 22;
+			if(priv->cck_present_attentuation < 0)
+				priv->cck_present_attentuation = 0;
+
+			RT_TRACE(COMP_INIT, "40M, pHalData->CCKPresentAttentuation = %d\n", priv->cck_present_attentuation);
+			if(priv->chan == 14 && !priv->bcck_in_ch14)
+			{
+				priv->bcck_in_ch14 = true;
+				dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
+			}
+			else if(priv->chan!= 14 && priv->bcck_in_ch14)
+			{
+				priv->bcck_in_ch14 = false;
+				dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
+			}
+			else
+				dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
+
+			break;
+		default:
+			RT_TRACE(COMP_ERR, "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n" ,priv->CurrentChannelBW);
+			break;
+
+	}
+	//Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315
+
+	//<3>Set RF related register
+	switch( priv->rf_chip )
+	{
+		case RF_8225:
+#ifdef TO_DO_LIST
+			PHY_SetRF8225Bandwidth(Adapter, pHalData->CurrentChannelBW);
+#endif
+			break;
+
+		case RF_8256:
+			PHY_SetRF8256Bandwidth(dev, priv->CurrentChannelBW);
+			break;
+
+		case RF_8258:
+			// PHY_SetRF8258Bandwidth();
+			break;
+
+		case RF_PSEUDO_11N:
+			// Do Nothing
+			break;
+
+		default:
+			RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", priv->rf_chip);
+			break;
+	}
+	priv->SetBWModeInProgress= false;
+
+	RT_TRACE(COMP_SWBW, "<==SetBWMode819xUsb(), %d", atomic_read(&(priv->ieee80211->atm_swbw)) );
+}
+
+/******************************************************************************
+ *function:  This function schedules bandwith switch work.
+ *   input:  struct net_device *dev
+ *   	     HT_CHANNEL_WIDTH	Bandwidth  //20M or 40M
+ *   	     HT_EXTCHNL_OFFSET Offset 	   //Upper, Lower, or Don't care
+ *  output:  none
+ *  return:  none
+ *    Note:  I doubt whether SetBWModeInProgress flag is necessary as we can
+ *    	     test whether current work in the queue or not.//do I?
+ * ***************************************************************************/
+void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH	Bandwidth, HT_EXTCHNL_OFFSET Offset)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	if(priv->SetBWModeInProgress)
+		return;
+	priv->SetBWModeInProgress= true;
+
+	priv->CurrentChannelBW = Bandwidth;
+
+	if(Offset==HT_EXTCHNL_OFFSET_LOWER)
+		priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_UPPER;
+	else if(Offset==HT_EXTCHNL_OFFSET_UPPER)
+		priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_LOWER;
+	else
+		priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
+
+	//queue_work(priv->priv_wq, &(priv->SetBWModeWorkItem));
+	//	schedule_work(&(priv->SetBWModeWorkItem));
+	rtl8192_SetBWModeWorkItem(dev);
+
+}
+
+void InitialGain819xUsb(struct net_device *dev,	u8 Operation)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	priv->InitialGainOperateType = Operation;
+
+	if(priv->up)
+	{
+		queue_delayed_work(priv->priv_wq,&priv->initialgain_operate_wq,0);
+	}
+}
+
+extern void InitialGainOperateWorkItemCallBack(struct work_struct *work)
+{
+	struct delayed_work *dwork = container_of(work,struct delayed_work,work);
+       struct r8192_priv *priv = container_of(dwork,struct r8192_priv,initialgain_operate_wq);
+       struct net_device *dev = priv->ieee80211->dev;
+#define SCAN_RX_INITIAL_GAIN	0x17
+#define POWER_DETECTION_TH	0x08
+	u32	BitMask;
+	u8	initial_gain;
+	u8	Operation;
+
+	Operation = priv->InitialGainOperateType;
+
+	switch(Operation)
+	{
+		case IG_Backup:
+			RT_TRACE(COMP_SCAN, "IG_Backup, backup the initial gain.\n");
+			initial_gain = SCAN_RX_INITIAL_GAIN;//priv->DefaultInitialGain[0];//
+			BitMask = bMaskByte0;
+			if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
+				rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	// FW DIG OFF
+			priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, BitMask);
+			priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, BitMask);
+			priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, BitMask);
+			priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, BitMask);
+			BitMask  = bMaskByte2;
+			priv->initgain_backup.cca		= (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, BitMask);
+
+			RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
+			RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
+			RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
+			RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
+			RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xa0a is %x\n",priv->initgain_backup.cca);
+
+			RT_TRACE(COMP_SCAN, "Write scan initial gain = 0x%x \n", initial_gain);
+			write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
+			write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
+			write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
+			write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain);
+			RT_TRACE(COMP_SCAN, "Write scan 0xa0a = 0x%x \n", POWER_DETECTION_TH);
+			write_nic_byte(dev, 0xa0a, POWER_DETECTION_TH);
+			break;
+		case IG_Restore:
+			RT_TRACE(COMP_SCAN, "IG_Restore, restore the initial gain.\n");
+			BitMask = 0x7f; //Bit0~ Bit6
+			if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
+				rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	// FW DIG OFF
+
+			rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, BitMask, (u32)priv->initgain_backup.xaagccore1);
+			rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, BitMask, (u32)priv->initgain_backup.xbagccore1);
+			rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, BitMask, (u32)priv->initgain_backup.xcagccore1);
+			rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, BitMask, (u32)priv->initgain_backup.xdagccore1);
+			BitMask  = bMaskByte2;
+			rtl8192_setBBreg(dev, rCCK0_CCA, BitMask, (u32)priv->initgain_backup.cca);
+
+			RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
+			RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
+			RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
+			RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
+			RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xa0a is %x\n",priv->initgain_backup.cca);
+
+#ifdef RTL8190P
+			SetTxPowerLevel8190(Adapter,priv->CurrentChannel);
+#endif
+#ifdef RTL8192E
+			SetTxPowerLevel8190(Adapter,priv->CurrentChannel);
+#endif
+//#ifdef RTL8192U
+			rtl8192_phy_setTxPower(dev,priv->ieee80211->current_network.channel);
+//#endif
+
+			if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
+				rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);	// FW DIG ON
+			break;
+		default:
+			RT_TRACE(COMP_SCAN, "Unknown IG Operation. \n");
+			break;
+	}
+}
+
diff --git a/drivers/staging/rtl8192u/r819xU_phy.h b/drivers/staging/rtl8192u/r819xU_phy.h
new file mode 100644
index 0000000..3e3bc57
--- /dev/null
+++ b/drivers/staging/rtl8192u/r819xU_phy.h
@@ -0,0 +1,90 @@
+#ifndef _R819XU_PHY_H
+#define _R819XU_PHY_H
+
+/* Channel switch:The size of command tables for switch channel*/
+#define MAX_PRECMD_CNT 16
+#define MAX_RFDEPENDCMD_CNT 16
+#define MAX_POSTCMD_CNT 16
+
+typedef enum _SwChnlCmdID{
+	CmdID_End,
+	CmdID_SetTxPowerLevel,
+	CmdID_BBRegWrite10,
+	CmdID_WritePortUlong,
+	CmdID_WritePortUshort,
+	CmdID_WritePortUchar,
+	CmdID_RF_WriteReg,
+}SwChnlCmdID;
+
+/*--------------------------------Define structure--------------------------------*/
+/* 1. Switch channel related */
+typedef struct _SwChnlCmd{
+	SwChnlCmdID	CmdID;
+	u32			Para1;
+	u32			Para2;
+	u32			msDelay;
+}__attribute__ ((packed)) SwChnlCmd;
+
+extern u32 rtl819XMACPHY_Array_PG[];
+extern u32 rtl819XPHY_REG_1T2RArray[];
+extern u32 rtl819XAGCTAB_Array[];
+extern u32 rtl819XRadioA_Array[];
+extern u32 rtl819XRadioB_Array[];
+extern u32 rtl819XRadioC_Array[];
+extern u32 rtl819XRadioD_Array[];
+
+typedef enum _HW90_BLOCK{
+	HW90_BLOCK_MAC = 0,
+	HW90_BLOCK_PHY0 = 1,
+	HW90_BLOCK_PHY1 = 2,
+	HW90_BLOCK_RF = 3,
+	HW90_BLOCK_MAXIMUM = 4, // Never use this
+}HW90_BLOCK_E, *PHW90_BLOCK_E;
+
+typedef enum _RF90_RADIO_PATH{
+	RF90_PATH_A = 0,			//Radio Path A
+	RF90_PATH_B = 1,			//Radio Path B
+	RF90_PATH_C = 2,			//Radio Path C
+	RF90_PATH_D = 3,			//Radio Path D
+	RF90_PATH_MAX				//Max RF number 92 support
+}RF90_RADIO_PATH_E, *PRF90_RADIO_PATH_E;
+
+#define bMaskByte0                0xff
+#define bMaskByte1                0xff00
+#define bMaskByte2                0xff0000
+#define bMaskByte3                0xff000000
+#define bMaskHWord                0xffff0000
+#define bMaskLWord                0x0000ffff
+#define bMaskDWord                0xffffffff
+
+//extern u32 rtl8192_CalculateBitShift(u32 dwBitMask);
+extern u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath);
+extern void rtl8192_setBBreg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask, u32 dwData);
+extern u32 rtl8192_QueryBBReg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask);
+//extern u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset);
+//extern void rtl8192_phy_RFSerialWrite(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data);
+extern void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask, u32 Data);
+extern u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask);
+extern void rtl8192_phy_configmac(struct net_device* dev);
+extern void rtl8192_phyConfigBB(struct net_device* dev, u8 ConfigType);
+//extern void rtl8192_InitBBRFRegDef(struct net_device* dev);
+extern u8 rtl8192_phy_checkBBAndRF(struct net_device* dev, HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath);
+//extern void rtl8192_BB_Config_ParaFile(struct net_device* dev);
+extern void rtl8192_BBConfig(struct net_device* dev);
+extern void rtl8192_phy_getTxPower(struct net_device* dev);
+extern void rtl8192_phy_setTxPower(struct net_device* dev, u8 channel);
+extern void rtl8192_phy_RFConfig(struct net_device* dev);
+extern void rtl8192_phy_updateInitGain(struct net_device* dev);
+extern u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E	eRFPath);
+
+extern u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel);
+extern void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH	Bandwidth, HT_EXTCHNL_OFFSET Offset);
+extern void rtl8192_SwChnl_WorkItem(struct net_device *dev);
+void rtl8192_SetBWModeWorkItem(struct net_device *dev);
+extern bool rtl8192_SetRFPowerState(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState);
+//added by amy
+extern void InitialGain819xUsb(struct net_device *dev,	u8 Operation);
+
+extern void InitialGainOperateWorkItemCallBack(struct work_struct *work);
+
+#endif
diff --git a/drivers/staging/rtl8192u/r819xU_phyreg.h b/drivers/staging/rtl8192u/r819xU_phyreg.h
new file mode 100644
index 0000000..06b0b53
--- /dev/null
+++ b/drivers/staging/rtl8192u/r819xU_phyreg.h
@@ -0,0 +1,871 @@
+#ifndef _R819XU_PHYREG_H
+#define _R819XU_PHYREG_H
+
+
+#define   RF_DATA				0x1d4					// FW will write RF data in the register.
+
+//Register   //duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF
+//page 1
+#define rPMAC_Reset               		0x100
+#define rPMAC_TxStart             		0x104
+#define rPMAC_TxLegacySIG         		0x108
+#define rPMAC_TxHTSIG1            		0x10c
+#define rPMAC_TxHTSIG2            		0x110
+#define rPMAC_PHYDebug            		0x114
+#define rPMAC_TxPacketNum         		0x118
+#define rPMAC_TxIdle              		0x11c
+#define rPMAC_TxMACHeader0       	0x120
+#define rPMAC_TxMACHeader1       	0x124
+#define rPMAC_TxMACHeader2       	0x128
+#define rPMAC_TxMACHeader3       	0x12c
+#define rPMAC_TxMACHeader4       	0x130
+#define rPMAC_TxMACHeader5       	0x134
+#define rPMAC_TxDataType          		0x138
+#define rPMAC_TxRandomSeed      		0x13c
+#define rPMAC_CCKPLCPPreamble  		0x140
+#define rPMAC_CCKPLCPHeader     		0x144
+#define rPMAC_CCKCRC16            		0x148
+#define rPMAC_OFDMRxCRC32OK  		0x170
+#define rPMAC_OFDMRxCRC32Er   		0x174
+#define rPMAC_OFDMRxParityEr    		0x178
+#define rPMAC_OFDMRxCRC8Er     		0x17c
+#define rPMAC_CCKCRxRC16Er       		0x180
+#define rPMAC_CCKCRxRC32Er       		0x184
+#define rPMAC_CCKCRxRC32OK      		0x188
+#define rPMAC_TxStatus            		0x18c
+
+//page8
+#define rFPGA0_RFMOD              		0x800  //RF mode & CCK TxSC
+#define rFPGA0_TxInfo             		0x804
+#define rFPGA0_PSDFunction        		0x808
+#define rFPGA0_TxGainStage        		0x80c
+#define rFPGA0_RFTiming1          		0x810
+#define rFPGA0_RFTiming2          		0x814
+//#define rFPGA0_XC_RFTiming        		0x818
+//#define rFPGA0_XD_RFTiming        		0x81c
+#define rFPGA0_XA_HSSIParameter1  	0x820
+#define rFPGA0_XA_HSSIParameter2  	0x824
+#define rFPGA0_XB_HSSIParameter1  	0x828
+#define rFPGA0_XB_HSSIParameter2  	0x82c
+#define rFPGA0_XC_HSSIParameter1  	0x830
+#define rFPGA0_XC_HSSIParameter2  	0x834
+#define rFPGA0_XD_HSSIParameter1  	0x838
+#define rFPGA0_XD_HSSIParameter2  	0x83c
+#define rFPGA0_XA_LSSIParameter   	0x840
+#define rFPGA0_XB_LSSIParameter   	0x844
+#define rFPGA0_XC_LSSIParameter   	0x848
+#define rFPGA0_XD_LSSIParameter   	0x84c
+#define rFPGA0_RFWakeUpParameter  	0x850
+#define rFPGA0_RFSleepUpParameter 	0x854
+#define rFPGA0_XAB_SwitchControl  	0x858
+#define rFPGA0_XCD_SwitchControl  	0x85c
+#define rFPGA0_XA_RFInterfaceOE   	0x860
+#define rFPGA0_XB_RFInterfaceOE   	0x864
+#define rFPGA0_XC_RFInterfaceOE   	0x868
+#define rFPGA0_XD_RFInterfaceOE   	0x86c
+#define rFPGA0_XAB_RFInterfaceSW  	0x870
+#define rFPGA0_XCD_RFInterfaceSW  	0x874
+#define rFPGA0_XAB_RFParameter    	0x878
+#define rFPGA0_XCD_RFParameter    	0x87c
+#define rFPGA0_AnalogParameter1   	0x880
+#define rFPGA0_AnalogParameter2   	0x884
+#define rFPGA0_AnalogParameter3   	0x888
+#define rFPGA0_AnalogParameter4   	0x88c
+#define rFPGA0_XA_LSSIReadBack    	0x8a0
+#define rFPGA0_XB_LSSIReadBack    	0x8a4
+#define rFPGA0_XC_LSSIReadBack    	0x8a8
+#define rFPGA0_XD_LSSIReadBack    	0x8ac
+#define rFPGA0_PSDReport          		0x8b4
+#define rFPGA0_XAB_RFInterfaceRB  	0x8e0
+#define rFPGA0_XCD_RFInterfaceRB  	0x8e4
+
+//page 9
+#define rFPGA1_RFMOD              		0x900  //RF mode & OFDM TxSC
+#define rFPGA1_TxBlock            		0x904
+#define rFPGA1_DebugSelect        		0x908
+#define rFPGA1_TxInfo             		0x90c
+
+//page a
+#define rCCK0_System              		0xa00
+#define rCCK0_AFESetting          		0xa04
+#define rCCK0_CCA                 			0xa08
+#define rCCK0_RxAGC1              		0xa0c  //AGC default value, saturation level
+#define rCCK0_RxAGC2              		0xa10  //AGC & DAGC
+#define rCCK0_RxHP                		0xa14
+#define rCCK0_DSPParameter1       	0xa18  //Timing recovery & Channel estimation threshold
+#define rCCK0_DSPParameter2       	0xa1c  //SQ threshold
+#define rCCK0_TxFilter1           		0xa20
+#define rCCK0_TxFilter2           		0xa24
+#define rCCK0_DebugPort           		0xa28  //debug port and Tx filter3
+#define rCCK0_FalseAlarmReport    	0xa2c  //0xa2d
+#define rCCK0_TRSSIReport         		0xa50
+#define rCCK0_RxReport            		0xa54  //0xa57
+#define rCCK0_FACounterLower      	0xa5c  //0xa5b
+#define rCCK0_FACounterUpper      	0xa58  //0xa5c
+
+//page c
+#define rOFDM0_LSTF               		0xc00
+#define rOFDM0_TRxPathEnable      	0xc04
+#define rOFDM0_TRMuxPar           		0xc08
+#define rOFDM0_TRSWIsolation      		0xc0c
+#define rOFDM0_XARxAFE            		0xc10  //RxIQ DC offset, Rx digital filter, DC notch filter
+#define rOFDM0_XARxIQImbalance    	0xc14  //RxIQ imblance matrix
+#define rOFDM0_XBRxAFE            		0xc18
+#define rOFDM0_XBRxIQImbalance    	0xc1c
+#define rOFDM0_XCRxAFE            		0xc20
+#define rOFDM0_XCRxIQImbalance    	0xc24
+#define rOFDM0_XDRxAFE            		0xc28
+#define rOFDM0_XDRxIQImbalance    	0xc2c
+#define rOFDM0_RxDetector1        		0xc30  //PD,BW & SBD
+#define rOFDM0_RxDetector2        		0xc34  //SBD & Fame Sync.
+#define rOFDM0_RxDetector3        		0xc38  //Frame Sync.
+#define rOFDM0_RxDetector4        		0xc3c  //PD, SBD, Frame Sync & Short-GI
+#define rOFDM0_RxDSP              		0xc40  //Rx Sync Path
+#define rOFDM0_CFOandDAGC         	0xc44  //CFO & DAGC
+#define rOFDM0_CCADropThreshold   	0xc48 //CCA Drop threshold
+#define rOFDM0_ECCAThreshold      	0xc4c // energy CCA
+#define rOFDM0_XAAGCCore1         	0xc50
+#define rOFDM0_XAAGCCore2         	0xc54
+#define rOFDM0_XBAGCCore1         	0xc58
+#define rOFDM0_XBAGCCore2         	0xc5c
+#define rOFDM0_XCAGCCore1         	0xc60
+#define rOFDM0_XCAGCCore2         	0xc64
+#define rOFDM0_XDAGCCore1         	0xc68
+#define rOFDM0_XDAGCCore2         	0xc6c
+#define rOFDM0_AGCParameter1      	0xc70
+#define rOFDM0_AGCParameter2      	0xc74
+#define rOFDM0_AGCRSSITable       	0xc78
+#define rOFDM0_HTSTFAGC           		0xc7c
+#define rOFDM0_XATxIQImbalance   	0xc80
+#define rOFDM0_XATxAFE            		0xc84
+#define rOFDM0_XBTxIQImbalance    	0xc88
+#define rOFDM0_XBTxAFE            		0xc8c
+#define rOFDM0_XCTxIQImbalance    	0xc90
+#define rOFDM0_XCTxAFE            		0xc94
+#define rOFDM0_XDTxIQImbalance    	0xc98
+#define rOFDM0_XDTxAFE            		0xc9c
+#define rOFDM0_RxHPParameter      	0xce0
+#define rOFDM0_TxPseudoNoiseWgt   	0xce4
+#define rOFDM0_FrameSync          		0xcf0
+#define rOFDM0_DFSReport          		0xcf4
+#define rOFDM0_TxCoeff1           		0xca4
+#define rOFDM0_TxCoeff2           		0xca8
+#define rOFDM0_TxCoeff3           		0xcac
+#define rOFDM0_TxCoeff4           		0xcb0
+#define rOFDM0_TxCoeff5           		0xcb4
+#define rOFDM0_TxCoeff6           		0xcb8
+
+
+//page d
+#define rOFDM1_LSTF               		0xd00
+#define rOFDM1_TRxPathEnable      	0xd04
+#define rOFDM1_CFO                		0xd08
+#define rOFDM1_CSI1               		0xd10
+#define rOFDM1_SBD                		0xd14
+#define rOFDM1_CSI2               		0xd18
+#define rOFDM1_CFOTracking        		0xd2c
+#define rOFDM1_TRxMesaure1        	0xd34
+#define rOFDM1_IntfDet            		0xd3c
+#define rOFDM1_PseudoNoiseStateAB 0xd50
+#define rOFDM1_PseudoNoiseStateCD 0xd54
+#define rOFDM1_RxPseudoNoiseWgt   0xd58
+#define rOFDM_PHYCounter1         		0xda0  //cca, parity fail
+#define rOFDM_PHYCounter2         		0xda4  //rate illegal, crc8 fail
+#define rOFDM_PHYCounter3         		0xda8  //MCS not support
+#define rOFDM_ShortCFOAB          		0xdac
+#define rOFDM_ShortCFOCD          		0xdb0
+#define rOFDM_LongCFOAB           		0xdb4
+#define rOFDM_LongCFOCD           		0xdb8
+#define rOFDM_TailCFOAB           		0xdbc
+#define rOFDM_TailCFOCD           		0xdc0
+#define rOFDM_PWMeasure1          	0xdc4
+#define rOFDM_PWMeasure2          	0xdc8
+#define rOFDM_BWReport            		0xdcc
+#define rOFDM_AGCReport           		0xdd0
+#define rOFDM_RxSNR               		0xdd4
+#define rOFDM_RxEVMCSI            		0xdd8
+#define rOFDM_SIGReport           		0xddc
+
+//page e
+#define rTxAGC_Rate18_06			0xe00
+#define rTxAGC_Rate54_24			0xe04
+#define rTxAGC_CCK_Mcs32			0xe08
+#define rTxAGC_Mcs03_Mcs00			0xe10
+#define rTxAGC_Mcs07_Mcs04			0xe14
+#define rTxAGC_Mcs11_Mcs08			0xe18
+#define rTxAGC_Mcs15_Mcs12			0xe1c
+
+
+//RF
+//Zebra1
+#define rZebra1_HSSIEnable            	0x0
+#define rZebra1_TRxEnable1            	0x1
+#define rZebra1_TRxEnable2           	0x2
+#define rZebra1_AGC                   		0x4
+#define rZebra1_ChargePump            	0x5
+#define rZebra1_Channel               		0x7
+#define rZebra1_TxGain               		0x8
+#define rZebra1_TxLPF                 		0x9
+#define rZebra1_RxLPF                 		0xb
+#define rZebra1_RxHPFCorner           	0xc
+
+//Zebra4
+#define rGlobalCtrl                   		0
+#define rRTL8256_TxLPF                		19
+#define rRTL8256_RxLPF                		11
+
+//RTL8258
+#define rRTL8258_TxLPF                		0x11
+#define rRTL8258_RxLPF                		0x13
+#define rRTL8258_RSSILPF              	0xa
+
+//Bit Mask
+//page-1
+#define bBBResetB                 			0x100
+#define bGlobalResetB             		0x200
+#define bOFDMTxStart              		0x4
+#define bCCKTxStart               			0x8
+#define bCRC32Debug               		0x100
+#define bPMACLoopback             		0x10
+#define bTxLSIG                   			0xffffff
+#define bOFDMTxRate               		0xf
+#define bOFDMTxReserved           		0x10
+#define bOFDMTxLength             		0x1ffe0
+#define bOFDMTxParity             		0x20000
+#define bTxHTSIG1                 			0xffffff
+#define bTxHTMCSRate              		0x7f
+#define bTxHTBW                   			0x80
+#define bTxHTLength               		0xffff00
+#define bTxHTSIG2                 			0xffffff
+#define bTxHTSmoothing            		0x1
+#define bTxHTSounding             		0x2
+#define bTxHTReserved             		0x4
+#define bTxHTAggreation           		0x8
+#define bTxHTSTBC                 			0x30
+#define bTxHTAdvanceCoding        		0x40
+#define bTxHTShortGI              		0x80
+#define bTxHTNumberHT_LTF         		0x300
+#define bTxHTCRC8                 			0x3fc00
+#define bCounterReset             		0x10000
+#define bNumOfOFDMTx              		0xffff
+#define bNumOfCCKTx               		0xffff0000
+#define bTxIdleInterval           			0xffff
+#define bOFDMService              		0xffff0000
+#define bTxMACHeader              		0xffffffff
+#define bTxDataInit               			0xff
+#define bTxHTMode                 		0x100
+#define bTxDataType               		0x30000
+#define bTxRandomSeed             		0xffffffff
+#define bCCKTxPreamble           		0x1
+#define bCCKTxSFD                 			0xffff0000
+#define bCCKTxSIG                 			0xff
+#define bCCKTxService             		0xff00
+#define bCCKLengthExt             		0x8000
+#define bCCKTxLength              		0xffff0000
+#define bCCKTxCRC16               		0xffff
+#define bCCKTxStatus              		0x1
+#define bOFDMTxStatus             		0x2
+
+//page-8
+#define bRFMOD                    			0x1
+#define bJapanMode                		0x2
+#define bCCKTxSC                  			0x30
+#define bCCKEn                    			0x1000000
+#define bOFDMEn                   			0x2000000
+#define bOFDMRxADCPhase           		0x10000
+#define bOFDMTxDACPhase           		0x40000
+#define bXATxAGC                  			0x3f
+#define bXBTxAGC                  			0xf00
+#define bXCTxAGC                  			0xf000
+#define bXDTxAGC                  			0xf0000
+#define bPAStart                  			0xf0000000
+#define bTRStart                  			0x00f00000
+#define bRFStart                  			0x0000f000
+#define bBBStart                  			0x000000f0
+#define bBBCCKStart               		0x0000000f
+#define bPAEnd                    			0xf          //Reg0x814
+#define bTREnd                    			0x0f000000
+#define bRFEnd                    			0x000f0000
+#define bCCAMask                  			0x000000f0   //T2R
+#define bR2RCCAMask               		0x00000f00
+#define bHSSI_R2TDelay            		0xf8000000
+#define bHSSI_T2RDelay            		0xf80000
+#define bContTxHSSI               		0x400     //chane gain at continue Tx
+#define bIGFromCCK                		0x200
+#define bAGCAddress               		0x3f
+#define bRxHPTx                   			0x7000
+#define bRxHPT2R                  			0x38000
+#define bRxHPCCKIni               		0xc0000
+#define bAGCTxCode                		0xc00000
+#define bAGCRxCode                		0x300000
+#define b3WireDataLength          		0x800
+#define b3WireAddressLength       		0x400
+#define b3WireRFPowerDown         		0x1
+//#define bHWSISelect               		0x8
+#define b5GPAPEPolarity           		0x40000000
+#define b2GPAPEPolarity           		0x80000000
+#define bRFSW_TxDefaultAnt        		0x3
+#define bRFSW_TxOptionAnt         		0x30
+#define bRFSW_RxDefaultAnt        		0x300
+#define bRFSW_RxOptionAnt         		0x3000
+#define bRFSI_3WireData           		0x1
+#define bRFSI_3WireClock          		0x2
+#define bRFSI_3WireLoad           		0x4
+#define bRFSI_3WireRW             		0x8
+#define bRFSI_3Wire               			0xf  //3-wire total control
+#define bRFSI_RFENV               		0x10
+#define bRFSI_TRSW                		0x20
+#define bRFSI_TRSWB               		0x40
+#define bRFSI_ANTSW               		0x100
+#define bRFSI_ANTSWB              		0x200
+#define bRFSI_PAPE                			0x400
+#define bRFSI_PAPE5G              		0x800
+#define bBandSelect               			0x1
+#define bHTSIG2_GI                			0x80
+#define bHTSIG2_Smoothing         		0x01
+#define bHTSIG2_Sounding          		0x02
+#define bHTSIG2_Aggreaton         		0x08
+#define bHTSIG2_STBC              		0x30
+#define bHTSIG2_AdvCoding         		0x40
+#define bHTSIG2_NumOfHTLTF        	0x300
+#define bHTSIG2_CRC8              		0x3fc
+#define bHTSIG1_MCS               		0x7f
+#define bHTSIG1_BandWidth         		0x80
+#define bHTSIG1_HTLength          		0xffff
+#define bLSIG_Rate                			0xf
+#define bLSIG_Reserved            		0x10
+#define bLSIG_Length              		0x1fffe
+#define bLSIG_Parity              			0x20
+#define bCCKRxPhase               		0x4
+#define bLSSIReadAddress          		0x3f000000   //LSSI "Read" Address
+#define bLSSIReadEdge             		0x80000000   //LSSI "Read" edge signal
+#define bLSSIReadBackData         		0xfff
+#define bLSSIReadOKFlag           		0x1000
+#define bCCKSampleRate            		0x8       //0: 44MHz, 1:88MHz
+
+#define bRegulator0Standby        		0x1
+#define bRegulatorPLLStandby      		0x2
+#define bRegulator1Standby        		0x4
+#define bPLLPowerUp               		0x8
+#define bDPLLPowerUp              		0x10
+#define bDA10PowerUp              		0x20
+#define bAD7PowerUp               		0x200
+#define bDA6PowerUp               		0x2000
+#define bXtalPowerUp              		0x4000
+#define b40MDClkPowerUP           		0x8000
+#define bDA6DebugMode             		0x20000
+#define bDA6Swing                 			0x380000
+#define bADClkPhase               		0x4000000
+#define b80MClkDelay              		0x18000000
+#define bAFEWatchDogEnable        		0x20000000
+#define bXtalCap                			0x0f000000
+#define bIntDifClkEnable          		0x400
+#define bExtSigClkEnable         		0x800
+#define bBandgapMbiasPowerUp      	0x10000
+#define bAD11SHGain               		0xc0000
+#define bAD11InputRange           		0x700000
+#define bAD11OPCurrent            		0x3800000
+#define bIPathLoopback            		0x4000000
+#define bQPathLoopback            		0x8000000
+#define bAFELoopback              		0x10000000
+#define bDA10Swing                		0x7e0
+#define bDA10Reverse              		0x800
+#define bDAClkSource              		0x1000
+#define bAD7InputRange            		0x6000
+#define bAD7Gain                  			0x38000
+#define bAD7OutputCMMode          		0x40000
+#define bAD7InputCMMode           		0x380000
+#define bAD7Current               			0xc00000
+#define bRegulatorAdjust          		0x7000000
+#define bAD11PowerUpAtTx          		0x1
+#define bDA10PSAtTx               		0x10
+#define bAD11PowerUpAtRx          		0x100
+#define bDA10PSAtRx               		0x1000
+
+#define bCCKRxAGCFormat           		0x200
+
+#define bPSDFFTSamplepPoint       		0xc000
+#define bPSDAverageNum            		0x3000
+#define bIQPathControl            		0xc00
+#define bPSDFreq                  			0x3ff
+#define bPSDAntennaPath           		0x30
+#define bPSDIQSwitch              		0x40
+#define bPSDRxTrigger             		0x400000
+#define bPSDTxTrigger             		0x80000000
+#define bPSDSineToneScale        		0x7f000000
+#define bPSDReport                			0xffff
+
+//page-9
+#define bOFDMTxSC                 		0x30000000
+#define bCCKTxOn                  			0x1
+#define bOFDMTxOn                 		0x2
+#define bDebugPage                		0xfff  //reset debug page and also HWord, LWord
+#define bDebugItem                		0xff   //reset debug page and LWord
+#define bAntL              			0x10
+#define bAntNonHT           				0x100
+#define bAntHT1               			0x1000
+#define bAntHT2                   			0x10000
+#define bAntHT1S1                 			0x100000
+#define bAntNonHTS1               		0x1000000
+
+//page-a
+#define bCCKBBMode                		0x3
+#define bCCKTxPowerSaving         		0x80
+#define bCCKRxPowerSaving         		0x40
+#define bCCKSideBand              		0x10
+#define bCCKScramble              		0x8
+#define bCCKAntDiversity    			0x8000
+#define bCCKCarrierRecovery   		0x4000
+#define bCCKTxRate           			0x3000
+#define bCCKDCCancel             		0x0800
+#define bCCKISICancel             		0x0400
+#define bCCKMatchFilter           		0x0200
+#define bCCKEqualizer             		0x0100
+#define bCCKPreambleDetect       		0x800000
+#define bCCKFastFalseCCA          		0x400000
+#define bCCKChEstStart            		0x300000
+#define bCCKCCACount              		0x080000
+#define bCCKcs_lim                			0x070000
+#define bCCKBistMode              		0x80000000
+#define bCCKCCAMask             		0x40000000
+#define bCCKTxDACPhase         		0x4
+#define bCCKRxADCPhase         		0x20000000   //r_rx_clk
+#define bCCKr_cp_mode0         		0x0100
+#define bCCKTxDCOffset           		0xf0
+#define bCCKRxDCOffset           		0xf
+#define bCCKCCAMode              		0xc000
+#define bCCKFalseCS_lim           		0x3f00
+#define bCCKCS_ratio              		0xc00000
+#define bCCKCorgBit_sel           		0x300000
+#define bCCKPD_lim                			0x0f0000
+#define bCCKNewCCA                		0x80000000
+#define bCCKRxHPofIG              		0x8000
+#define bCCKRxIG                  			0x7f00
+#define bCCKLNAPolarity           		0x800000
+#define bCCKRx1stGain             		0x7f0000
+#define bCCKRFExtend              		0x20000000 //CCK Rx Iinital gain polarity
+#define bCCKRxAGCSatLevel        		0x1f000000
+#define bCCKRxAGCSatCount       		0xe0
+#define bCCKRxRFSettle            		0x1f       //AGCsamp_dly
+#define bCCKFixedRxAGC           		0x8000
+//#define bCCKRxAGCFormat         		0x4000   //remove to HSSI register 0x824
+#define bCCKAntennaPolarity      		0x2000
+#define bCCKTxFilterType          		0x0c00
+#define bCCKRxAGCReportType   		0x0300
+#define bCCKRxDAGCEn              		0x80000000
+#define bCCKRxDAGCPeriod        		0x20000000
+#define bCCKRxDAGCSatLevel     		0x1f000000
+#define bCCKTimingRecovery       		0x800000
+#define bCCKTxC0                  			0x3f0000
+#define bCCKTxC1                  			0x3f000000
+#define bCCKTxC2                  			0x3f
+#define bCCKTxC3                  			0x3f00
+#define bCCKTxC4                  			0x3f0000
+#define bCCKTxC5                  			0x3f000000
+#define bCCKTxC6                  			0x3f
+#define bCCKTxC7                  			0x3f00
+#define bCCKDebugPort             		0xff0000
+#define bCCKDACDebug              		0x0f000000
+#define bCCKFalseAlarmEnable      		0x8000
+#define bCCKFalseAlarmRead        		0x4000
+#define bCCKTRSSI                 			0x7f
+#define bCCKRxAGCReport           		0xfe
+#define bCCKRxReport_AntSel       		0x80000000
+#define bCCKRxReport_MFOff        		0x40000000
+#define bCCKRxRxReport_SQLoss     	0x20000000
+#define bCCKRxReport_Pktloss      		0x10000000
+#define bCCKRxReport_Lockedbit    	0x08000000
+#define bCCKRxReport_RateError    	0x04000000
+#define bCCKRxReport_RxRate       		0x03000000
+#define bCCKRxFACounterLower      	0xff
+#define bCCKRxFACounterUpper      	0xff000000
+#define bCCKRxHPAGCStart          		0xe000
+#define bCCKRxHPAGCFinal          		0x1c00
+
+#define bCCKRxFalseAlarmEnable    	0x8000
+#define bCCKFACounterFreeze       		0x4000
+
+#define bCCKTxPathSel             		0x10000000
+#define bCCKDefaultRxPath         		0xc000000
+#define bCCKOptionRxPath          		0x3000000
+
+//page c
+#define bNumOfSTF                			0x3
+#define bShift_L                 			0xc0
+#define bGI_TH                   			0xc
+#define bRxPathA                 			0x1
+#define bRxPathB                 			0x2
+#define bRxPathC                 			0x4
+#define bRxPathD                 			0x8
+#define bTxPathA                 			0x1
+#define bTxPathB                 			0x2
+#define bTxPathC                 			0x4
+#define bTxPathD                 			0x8
+#define bTRSSIFreq               			0x200
+#define bADCBackoff              			0x3000
+#define bDFIRBackoff             			0xc000
+#define bTRSSILatchPhase         		0x10000
+#define bRxIDCOffset             			0xff
+#define bRxQDCOffset             			0xff00
+#define bRxDFIRMode              		0x1800000
+#define bRxDCNFType              		0xe000000
+#define bRXIQImb_A               			0x3ff
+#define bRXIQImb_B               			0xfc00
+#define bRXIQImb_C               			0x3f0000
+#define bRXIQImb_D               			0xffc00000
+#define bDC_dc_Notch             		0x60000
+#define bRxNBINotch              			0x1f000000
+#define bPD_TH                   			0xf
+#define bPD_TH_Opt2              		0xc000
+#define bPWED_TH                 			0x700
+#define bIfMF_Win_L              			0x800
+#define bPD_Option               			0x1000
+#define bMF_Win_L                			0xe000
+#define bBW_Search_L             		0x30000
+#define bwin_enh_L               			0xc0000
+#define bBW_TH                   			0x700000
+#define bED_TH2                  			0x3800000
+#define bBW_option               			0x4000000
+#define bRatio_TH                			0x18000000
+#define bWindow_L                			0xe0000000
+#define bSBD_Option              			0x1
+#define bFrame_TH                			0x1c
+#define bFS_Option               			0x60
+#define bDC_Slope_check          		0x80
+#define bFGuard_Counter_DC_L     		0xe00
+#define bFrame_Weight_Short      		0x7000
+#define bSub_Tune                			0xe00000
+#define bFrame_DC_Length         		0xe000000
+#define bSBD_start_offset        		0x30000000
+#define bFrame_TH_2              		0x7
+#define bFrame_GI2_TH            		0x38
+#define bGI2_Sync_en             		0x40
+#define bSarch_Short_Early       		0x300
+#define bSarch_Short_Late        		0xc00
+#define bSarch_GI2_Late          		0x70000
+#define bCFOAntSum               		0x1
+#define bCFOAcc                  			0x2
+#define bCFOStartOffset          		0xc
+#define bCFOLookBack             		0x70
+#define bCFOSumWeight            		0x80
+#define bDAGCEnable              			0x10000
+#define bTXIQImb_A               			0x3ff
+#define bTXIQImb_B               			0xfc00
+#define bTXIQImb_C               			0x3f0000
+#define bTXIQImb_D               			0xffc00000
+#define bTxIDCOffset             			0xff
+#define bTxQDCOffset             			0xff00
+#define bTxDFIRMode              		0x10000
+#define bTxPesudoNoiseOn         		0x4000000
+#define bTxPesudoNoise_A         		0xff
+#define bTxPesudoNoise_B         		0xff00
+#define bTxPesudoNoise_C         		0xff0000
+#define bTxPesudoNoise_D         		0xff000000
+#define bCCADropOption           		0x20000
+#define bCCADropThres            		0xfff00000
+#define bEDCCA_H                 			0xf
+#define bEDCCA_L                 			0xf0
+#define bLambda_ED               0x300
+#define bRxInitialGain           0x7f
+#define bRxAntDivEn              0x80
+#define bRxAGCAddressForLNA      0x7f00
+#define bRxHighPowerFlow         0x8000
+#define bRxAGCFreezeThres        0xc0000
+#define bRxFreezeStep_AGC1       0x300000
+#define bRxFreezeStep_AGC2       0xc00000
+#define bRxFreezeStep_AGC3       0x3000000
+#define bRxFreezeStep_AGC0       0xc000000
+#define bRxRssi_Cmp_En           0x10000000
+#define bRxQuickAGCEn            0x20000000
+#define bRxAGCFreezeThresMode    0x40000000
+#define bRxOverFlowCheckType     0x80000000
+#define bRxAGCShift              0x7f
+#define bTRSW_Tri_Only           0x80
+#define bPowerThres              0x300
+#define bRxAGCEn                 0x1
+#define bRxAGCTogetherEn         0x2
+#define bRxAGCMin                0x4
+#define bRxHP_Ini                0x7
+#define bRxHP_TRLNA              0x70
+#define bRxHP_RSSI               0x700
+#define bRxHP_BBP1               0x7000
+#define bRxHP_BBP2               0x70000
+#define bRxHP_BBP3               0x700000
+#define bRSSI_H                  0x7f0000     //the threshold for high power
+#define bRSSI_Gen                0x7f000000   //the threshold for ant diversity
+#define bRxSettle_TRSW           0x7
+#define bRxSettle_LNA            0x38
+#define bRxSettle_RSSI           0x1c0
+#define bRxSettle_BBP            0xe00
+#define bRxSettle_RxHP           0x7000
+#define bRxSettle_AntSW_RSSI     0x38000
+#define bRxSettle_AntSW          0xc0000
+#define bRxProcessTime_DAGC      0x300000
+#define bRxSettle_HSSI           0x400000
+#define bRxProcessTime_BBPPW     0x800000
+#define bRxAntennaPowerShift     0x3000000
+#define bRSSITableSelect         0xc000000
+#define bRxHP_Final              0x7000000
+#define bRxHTSettle_BBP          0x7
+#define bRxHTSettle_HSSI         0x8
+#define bRxHTSettle_RxHP         0x70
+#define bRxHTSettle_BBPPW        0x80
+#define bRxHTSettle_Idle         0x300
+#define bRxHTSettle_Reserved     0x1c00
+#define bRxHTRxHPEn              0x8000
+#define bRxHTAGCFreezeThres      0x30000
+#define bRxHTAGCTogetherEn       0x40000
+#define bRxHTAGCMin              0x80000
+#define bRxHTAGCEn               0x100000
+#define bRxHTDAGCEn              0x200000
+#define bRxHTRxHP_BBP            0x1c00000
+#define bRxHTRxHP_Final          0xe0000000
+#define bRxPWRatioTH             0x3
+#define bRxPWRatioEn             0x4
+#define bRxMFHold                0x3800
+#define bRxPD_Delay_TH1          0x38
+#define bRxPD_Delay_TH2          0x1c0
+#define bRxPD_DC_COUNT_MAX       0x600
+//#define bRxMF_Hold               0x3800
+#define bRxPD_Delay_TH           0x8000
+#define bRxProcess_Delay         0xf0000
+#define bRxSearchrange_GI2_Early 0x700000
+#define bRxFrame_Guard_Counter_L 0x3800000
+#define bRxSGI_Guard_L           0xc000000
+#define bRxSGI_Search_L          0x30000000
+#define bRxSGI_TH                0xc0000000
+#define bDFSCnt0                 0xff
+#define bDFSCnt1                 0xff00
+#define bDFSFlag                 0xf0000
+
+#define bMFWeightSum             0x300000
+#define bMinIdxTH                0x7f000000
+
+#define bDAFormat                0x40000
+
+#define bTxChEmuEnable           0x01000000
+
+#define bTRSWIsolation_A         0x7f
+#define bTRSWIsolation_B         0x7f00
+#define bTRSWIsolation_C         0x7f0000
+#define bTRSWIsolation_D         0x7f000000
+
+#define bExtLNAGain              0x7c00
+
+//page d
+#define bSTBCEn                  0x4
+#define bAntennaMapping          0x10
+#define bNss                     0x20
+#define bCFOAntSumD              0x200
+#define bPHYCounterReset         0x8000000
+#define bCFOReportGet            0x4000000
+#define bOFDMContinueTx          0x10000000
+#define bOFDMSingleCarrier       0x20000000
+#define bOFDMSingleTone          0x40000000
+//#define bRxPath1                 0x01
+//#define bRxPath2                 0x02
+//#define bRxPath3                 0x04
+//#define bRxPath4                 0x08
+//#define bTxPath1                 0x10
+//#define bTxPath2                 0x20
+#define bHTDetect                0x100
+#define bCFOEn                   0x10000
+#define bCFOValue                0xfff00000
+#define bSigTone_Re              0x3f
+#define bSigTone_Im              0x7f00
+#define bCounter_CCA             0xffff
+#define bCounter_ParityFail      0xffff0000
+#define bCounter_RateIllegal     0xffff
+#define bCounter_CRC8Fail        0xffff0000
+#define bCounter_MCSNoSupport    0xffff
+#define bCounter_FastSync        0xffff
+#define bShortCFO                0xfff
+#define bShortCFOTLength         12   //total
+#define bShortCFOFLength         11   //fraction
+#define bLongCFO                 0x7ff
+#define bLongCFOTLength          11
+#define bLongCFOFLength          11
+#define bTailCFO                 0x1fff
+#define bTailCFOTLength          13
+#define bTailCFOFLength          12
+
+#define bmax_en_pwdB             0xffff
+#define bCC_power_dB             0xffff0000
+#define bnoise_pwdB              0xffff
+#define bPowerMeasTLength        10
+#define bPowerMeasFLength        3
+#define bRx_HT_BW                0x1
+#define bRxSC                    0x6
+#define bRx_HT                   0x8
+
+#define bNB_intf_det_on          0x1
+#define bIntf_win_len_cfg        0x30
+#define bNB_Intf_TH_cfg          0x1c0
+
+#define bRFGain                  0x3f
+#define bTableSel                0x40
+#define bTRSW                    0x80
+
+#define bRxSNR_A                 0xff
+#define bRxSNR_B                 0xff00
+#define bRxSNR_C                 0xff0000
+#define bRxSNR_D                 0xff000000
+#define bSNREVMTLength           8
+#define bSNREVMFLength           1
+
+#define bCSI1st                  0xff
+#define bCSI2nd                  0xff00
+#define bRxEVM1st                0xff0000
+#define bRxEVM2nd                0xff000000
+
+#define bSIGEVM                  0xff
+#define bPWDB                    0xff00
+#define bSGIEN                   0x10000
+
+#define bSFactorQAM1             0xf
+#define bSFactorQAM2             0xf0
+#define bSFactorQAM3             0xf00
+#define bSFactorQAM4             0xf000
+#define bSFactorQAM5             0xf0000
+#define bSFactorQAM6             0xf0000
+#define bSFactorQAM7             0xf00000
+#define bSFactorQAM8             0xf000000
+#define bSFactorQAM9             0xf0000000
+#define bCSIScheme               0x100000
+
+#define bNoiseLvlTopSet          0x3
+#define bChSmooth                0x4
+#define bChSmoothCfg1            0x38
+#define bChSmoothCfg2            0x1c0
+#define bChSmoothCfg3            0xe00
+#define bChSmoothCfg4            0x7000
+#define bMRCMode                 0x800000
+#define bTHEVMCfg                0x7000000
+
+#define bLoopFitType             0x1
+#define bUpdCFO                  0x40
+#define bUpdCFOOffData           0x80
+#define bAdvUpdCFO               0x100
+#define bAdvTimeCtrl             0x800
+#define bUpdClko                 0x1000
+#define bFC                      0x6000
+#define bTrackingMode            0x8000
+#define bPhCmpEnable             0x10000
+#define bUpdClkoLTF              0x20000
+#define bComChCFO                0x40000
+#define bCSIEstiMode             0x80000
+#define bAdvUpdEqz               0x100000
+#define bUChCfg                  0x7000000
+#define bUpdEqz                  0x8000000
+
+//page e
+#define bTxAGCRate18_06			0x7f7f7f7f
+#define bTxAGCRate54_24			0x7f7f7f7f
+#define bTxAGCRateMCS32		0x7f
+#define bTxAGCRateCCK			0x7f00
+#define bTxAGCRateMCS3_MCS0	0x7f7f7f7f
+#define bTxAGCRateMCS7_MCS4	0x7f7f7f7f
+#define bTxAGCRateMCS11_MCS8	0x7f7f7f7f
+#define bTxAGCRateMCS15_MCS12	0x7f7f7f7f
+
+
+//Rx Pseduo noise
+#define bRxPesudoNoiseOn         0x20000000
+#define bRxPesudoNoise_A         0xff
+#define bRxPesudoNoise_B         0xff00
+#define bRxPesudoNoise_C         0xff0000
+#define bRxPesudoNoise_D         0xff000000
+#define bPesudoNoiseState_A      0xffff
+#define bPesudoNoiseState_B      0xffff0000
+#define bPesudoNoiseState_C      0xffff
+#define bPesudoNoiseState_D      0xffff0000
+
+//RF
+//Zebra1
+#define bZebra1_HSSIEnable        0x8
+#define bZebra1_TRxControl        0xc00
+#define bZebra1_TRxGainSetting    0x07f
+#define bZebra1_RxCorner          0xc00
+#define bZebra1_TxChargePump      0x38
+#define bZebra1_RxChargePump      0x7
+#define bZebra1_ChannelNum        0xf80
+#define bZebra1_TxLPFBW           0x400
+#define bZebra1_RxLPFBW           0x600
+
+//Zebra4
+#define bRTL8256RegModeCtrl1      0x100
+#define bRTL8256RegModeCtrl0      0x40
+#define bRTL8256_TxLPFBW          0x18
+#define bRTL8256_RxLPFBW          0x600
+
+//RTL8258
+#define bRTL8258_TxLPFBW          0xc
+#define bRTL8258_RxLPFBW          0xc00
+#define bRTL8258_RSSILPFBW        0xc0
+
+//byte endable for sb_write
+#define bByte0                    0x1
+#define bByte1                    0x2
+#define bByte2                    0x4
+#define bByte3                    0x8
+#define bWord0                    0x3
+#define bWord1                    0xc
+#define bDWord                    0xf
+
+//for PutRegsetting & GetRegSetting BitMask
+#define bMaskByte0                0xff
+#define bMaskByte1                0xff00
+#define bMaskByte2                0xff0000
+#define bMaskByte3                0xff000000
+#define bMaskHWord                0xffff0000
+#define bMaskLWord                0x0000ffff
+#define bMaskDWord                0xffffffff
+
+//for PutRFRegsetting & GetRFRegSetting BitMask
+#define bMask12Bits               0xfff
+
+#define bEnable                   0x1
+#define bDisable                  0x0
+
+#define LeftAntenna               0x0
+#define RightAntenna              0x1
+
+#define tCheckTxStatus            500   //500ms
+#define tUpdateRxCounter          100   //100ms
+
+#define rateCCK     0
+#define rateOFDM    1
+#define rateHT      2
+
+//define Register-End
+#define bPMAC_End                 0x1ff
+#define bFPGAPHY0_End             0x8ff
+#define bFPGAPHY1_End             0x9ff
+#define bCCKPHY0_End              0xaff
+#define bOFDMPHY0_End             0xcff
+#define bOFDMPHY1_End             0xdff
+
+//define max debug item in each debug page
+//#define bMaxItem_FPGA_PHY0        0x9
+//#define bMaxItem_FPGA_PHY1        0x3
+//#define bMaxItem_PHY_11B          0x16
+//#define bMaxItem_OFDM_PHY0        0x29
+//#define bMaxItem_OFDM_PHY1        0x0
+
+#define bPMACControl              0x0
+#define bWMACControl              0x1
+#define bWNICControl              0x2
+
+#define PathA                     0x0
+#define PathB                     0x1
+#define PathC                     0x2
+#define PathD                     0x3
+
+#define	rRTL8256RxMixerPole		0xb
+#define 	bZebraRxMixerPole		0x6
+#define 	rRTL8256TxBBOPBias        0x9
+#define 	bRTL8256TxBBOPBias       0x400
+#define 	rRTL8256TxBBBW             19
+#define 	bRTL8256TxBBBW            	0x18
+
+#endif	//__INC_HAL8190PCIPHYREG_H
diff --git a/drivers/staging/samsung-laptop/Kconfig b/drivers/staging/samsung-laptop/Kconfig
new file mode 100644
index 0000000..f27c608
--- /dev/null
+++ b/drivers/staging/samsung-laptop/Kconfig
@@ -0,0 +1,10 @@
+config SAMSUNG_LAPTOP
+	tristate "Samsung Laptop driver"
+	default n
+	depends on RFKILL && BACKLIGHT_CLASS_DEVICE && X86
+	help
+	  This module implements a driver for the N128 Samsung Laptop
+	  providing control over the Wireless LED and the LCD backlight
+
+	  To compile this driver as a module, choose
+	  M here: the module will be called samsung-laptop.
diff --git a/drivers/staging/samsung-laptop/Makefile b/drivers/staging/samsung-laptop/Makefile
new file mode 100644
index 0000000..3c6f420
--- /dev/null
+++ b/drivers/staging/samsung-laptop/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SAMSUNG_LAPTOP)	+= samsung-laptop.o
diff --git a/drivers/staging/samsung-laptop/TODO b/drivers/staging/samsung-laptop/TODO
new file mode 100644
index 0000000..f7a6d58
--- /dev/null
+++ b/drivers/staging/samsung-laptop/TODO
@@ -0,0 +1,5 @@
+TODO:
+	- review from other developers
+	- figure out ACPI video issues
+
+Please send patches to Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c
new file mode 100644
index 0000000..4877138
--- /dev/null
+++ b/drivers/staging/samsung-laptop/samsung-laptop.c
@@ -0,0 +1,542 @@
+/*
+ * Samsung N130 Laptop driver
+ *
+ * Copyright (C) 2009 Greg Kroah-Hartman (gregkh@suse.de)
+ * Copyright (C) 2009 Novell Inc.
+ *
+ * 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.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/backlight.h>
+#include <linux/fb.h>
+#include <linux/dmi.h>
+#include <linux/platform_device.h>
+#include <linux/rfkill.h>
+
+/*
+ * This driver is needed because a number of Samsung laptops do not hook
+ * their control settings through ACPI.  So we have to poke around in the
+ * BIOS to do things like brightness values, and "special" key controls.
+ */
+
+/*
+ * We have 0 - 8 as valid brightness levels.  The specs say that level 0 should
+ * be reserved by the BIOS (which really doesn't make much sense), we tell
+ * userspace that the value is 0 - 7 and then just tell the hardware 1 - 8
+ */
+#define MAX_BRIGHT	0x07
+
+/* Brightness is 0 - 8, as described above.  Value 0 is for the BIOS to use */
+#define GET_BRIGHTNESS			0x00
+#define SET_BRIGHTNESS			0x01
+
+/* first byte:
+ * 0x00 - wireless is off
+ * 0x01 - wireless is on
+ * second byte:
+ * 0x02 - 3G is off
+ * 0x03 - 3G is on
+ * TODO, verify 3G is correct, that doesn't seem right...
+ */
+#define GET_WIRELESS_BUTTON		0x02
+#define SET_WIRELESS_BUTTON		0x03
+
+/* 0 is off, 1 is on */
+#define GET_BACKLIGHT			0x04
+#define SET_BACKLIGHT			0x05
+
+/*
+ * 0x80 or 0x00 - no action
+ * 0x81 - recovery key pressed
+ */
+#define GET_RECOVERY_METHOD		0x06
+#define SET_RECOVERY_METHOD		0x07
+
+/* 0 is low, 1 is high */
+#define GET_PERFORMANCE_LEVEL		0x08
+#define SET_PERFORMANCE_LEVEL		0x09
+
+/*
+ * Tell the BIOS that Linux is running on this machine.
+ * 81 is on, 80 is off
+ */
+#define SET_LINUX			0x0a
+
+
+#define MAIN_FUNCTION			0x4c49
+
+#define SABI_HEADER_PORT		0x00
+#define SABI_HEADER_RE_MEM		0x02
+#define SABI_HEADER_IFACEFUNC		0x03
+#define SABI_HEADER_EN_MEM		0x04
+#define SABI_HEADER_DATA_OFFSET		0x05
+#define SABI_HEADER_DATA_SEGMENT	0x07
+
+#define SABI_IFACE_MAIN			0x00
+#define SABI_IFACE_SUB			0x02
+#define SABI_IFACE_COMPLETE		0x04
+#define SABI_IFACE_DATA			0x05
+
+/* Structure to get data back to the calling function */
+struct sabi_retval {
+	u8 retval[20];
+};
+
+static void __iomem *sabi;
+static void __iomem *sabi_iface;
+static void __iomem *f0000_segment;
+static struct backlight_device *backlight_device;
+static struct mutex sabi_mutex;
+static struct platform_device *sdev;
+static struct rfkill *rfk;
+
+static int force;
+module_param(force, bool, 0);
+MODULE_PARM_DESC(force, "Disable the DMI check and forces the driver to be loaded");
+
+static int debug;
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+
+static int sabi_get_command(u8 command, struct sabi_retval *sretval)
+{
+	int retval = 0;
+	u16 port = readw(sabi + SABI_HEADER_PORT);
+
+	mutex_lock(&sabi_mutex);
+
+	/* enable memory to be able to write to it */
+	outb(readb(sabi + SABI_HEADER_EN_MEM), port);
+
+	/* write out the command */
+	writew(MAIN_FUNCTION, sabi_iface + SABI_IFACE_MAIN);
+	writew(command, sabi_iface + SABI_IFACE_SUB);
+	writeb(0, sabi_iface + SABI_IFACE_COMPLETE);
+	outb(readb(sabi + SABI_HEADER_IFACEFUNC), port);
+
+	/* write protect memory to make it safe */
+	outb(readb(sabi + SABI_HEADER_RE_MEM), port);
+
+	/* see if the command actually succeeded */
+	if (readb(sabi_iface + SABI_IFACE_COMPLETE) == 0xaa &&
+	    readb(sabi_iface + SABI_IFACE_DATA) != 0xff) {
+		/*
+		 * It did!
+		 * Save off the data into a structure so the caller use it.
+		 * Right now we only care about the first 4 bytes,
+		 * I suppose there are commands that need more, but I don't
+		 * know about them.
+		 */
+		sretval->retval[0] = readb(sabi_iface + SABI_IFACE_DATA);
+		sretval->retval[1] = readb(sabi_iface + SABI_IFACE_DATA + 1);
+		sretval->retval[2] = readb(sabi_iface + SABI_IFACE_DATA + 2);
+		sretval->retval[3] = readb(sabi_iface + SABI_IFACE_DATA + 3);
+		goto exit;
+	}
+
+	/* Something bad happened, so report it and error out */
+	printk(KERN_WARNING "SABI command 0x%02x failed with completion flag 0x%02x and output 0x%02x\n",
+		command, readb(sabi_iface + SABI_IFACE_COMPLETE),
+		readb(sabi_iface + SABI_IFACE_DATA));
+	retval = -EINVAL;
+exit:
+	mutex_unlock(&sabi_mutex);
+	return retval;
+
+}
+
+static int sabi_set_command(u8 command, u8 data)
+{
+	int retval = 0;
+	u16 port = readw(sabi + SABI_HEADER_PORT);
+
+	mutex_lock(&sabi_mutex);
+
+	/* enable memory to be able to write to it */
+	outb(readb(sabi + SABI_HEADER_EN_MEM), port);
+
+	/* write out the command */
+	writew(MAIN_FUNCTION, sabi_iface + SABI_IFACE_MAIN);
+	writew(command, sabi_iface + SABI_IFACE_SUB);
+	writeb(0, sabi_iface + SABI_IFACE_COMPLETE);
+	writeb(data, sabi_iface + SABI_IFACE_DATA);
+	outb(readb(sabi + SABI_HEADER_IFACEFUNC), port);
+
+	/* write protect memory to make it safe */
+	outb(readb(sabi + SABI_HEADER_RE_MEM), port);
+
+	/* see if the command actually succeeded */
+	if (readb(sabi_iface + SABI_IFACE_COMPLETE) == 0xaa &&
+	    readb(sabi_iface + SABI_IFACE_DATA) != 0xff) {
+		/* it did! */
+		goto exit;
+	}
+
+	/* Something bad happened, so report it and error out */
+	printk(KERN_WARNING "SABI command 0x%02x failed with completion flag 0x%02x and output 0x%02x\n",
+		command, readb(sabi_iface + SABI_IFACE_COMPLETE),
+		readb(sabi_iface + SABI_IFACE_DATA));
+	retval = -EINVAL;
+exit:
+	mutex_unlock(&sabi_mutex);
+	return retval;
+}
+
+static void test_backlight(void)
+{
+	struct sabi_retval sretval;
+
+	sabi_get_command(GET_BACKLIGHT, &sretval);
+	printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]);
+
+	sabi_set_command(SET_BACKLIGHT, 0);
+	printk(KERN_DEBUG "backlight should be off\n");
+
+	sabi_get_command(GET_BACKLIGHT, &sretval);
+	printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]);
+
+	msleep(1000);
+
+	sabi_set_command(SET_BACKLIGHT, 1);
+	printk(KERN_DEBUG "backlight should be on\n");
+
+	sabi_get_command(GET_BACKLIGHT, &sretval);
+	printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]);
+}
+
+static void test_wireless(void)
+{
+	struct sabi_retval sretval;
+
+	sabi_get_command(GET_WIRELESS_BUTTON, &sretval);
+	printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]);
+
+	sabi_set_command(SET_WIRELESS_BUTTON, 0);
+	printk(KERN_DEBUG "wireless led should be off\n");
+
+	sabi_get_command(GET_WIRELESS_BUTTON, &sretval);
+	printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]);
+
+	msleep(1000);
+
+	sabi_set_command(SET_WIRELESS_BUTTON, 1);
+	printk(KERN_DEBUG "wireless led should be on\n");
+
+	sabi_get_command(GET_WIRELESS_BUTTON, &sretval);
+	printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]);
+}
+
+static u8 read_brightness(void)
+{
+	struct sabi_retval sretval;
+	int user_brightness = 0;
+	int retval;
+
+	retval = sabi_get_command(GET_BRIGHTNESS, &sretval);
+	if (!retval)
+		user_brightness = sretval.retval[0];
+		if (user_brightness != 0)
+			--user_brightness;
+	return user_brightness;
+}
+
+static void set_brightness(u8 user_brightness)
+{
+	sabi_set_command(SET_BRIGHTNESS, user_brightness + 1);
+}
+
+static int get_brightness(struct backlight_device *bd)
+{
+	return (int)read_brightness();
+}
+
+static int update_status(struct backlight_device *bd)
+{
+	set_brightness(bd->props.brightness);
+
+	if (bd->props.power == FB_BLANK_UNBLANK)
+		sabi_set_command(SET_BACKLIGHT, 1);
+	else
+		sabi_set_command(SET_BACKLIGHT, 0);
+	return 0;
+}
+
+static struct backlight_ops backlight_ops = {
+	.get_brightness	= get_brightness,
+	.update_status	= update_status,
+};
+
+static int rfkill_set(void *data, bool blocked)
+{
+	/* Do something with blocked...*/
+	/*
+	 * blocked == false is on
+	 * blocked == true is off
+	 */
+	if (blocked)
+		sabi_set_command(SET_WIRELESS_BUTTON, 0);
+	else
+		sabi_set_command(SET_WIRELESS_BUTTON, 1);
+
+	return 0;
+}
+
+static struct rfkill_ops rfkill_ops = {
+	.set_block = rfkill_set,
+};
+
+static int init_wireless(struct platform_device *sdev)
+{
+	int retval;
+
+	rfk = rfkill_alloc("samsung-wifi", &sdev->dev, RFKILL_TYPE_WLAN,
+			   &rfkill_ops, NULL);
+	if (!rfk)
+		return -ENOMEM;
+
+	retval = rfkill_register(rfk);
+	if (retval) {
+		rfkill_destroy(rfk);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static void destroy_wireless(void)
+{
+	rfkill_unregister(rfk);
+	rfkill_destroy(rfk);
+}
+
+static ssize_t get_silent_state(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct sabi_retval sretval;
+	int retval;
+
+	/* Read the state */
+	retval = sabi_get_command(GET_PERFORMANCE_LEVEL, &sretval);
+	if (retval)
+		return retval;
+
+	/* The logic is backwards, yeah, lots of fun... */
+	if (sretval.retval[0] == 0)
+		retval = 1;
+	else
+		retval = 0;
+	return sprintf(buf, "%d\n", retval);
+}
+
+static ssize_t set_silent_state(struct device *dev,
+				struct device_attribute *attr, const char *buf,
+				size_t count)
+{
+	char value;
+
+	if (count >= 1) {
+		value = buf[0];
+		if ((value == '0') || (value == 'n') || (value == 'N')) {
+			/* Turn speed up */
+			sabi_set_command(SET_PERFORMANCE_LEVEL, 0x01);
+		} else if ((value == '1') || (value == 'y') || (value == 'Y')) {
+			/* Turn speed down */
+			sabi_set_command(SET_PERFORMANCE_LEVEL, 0x00);
+		} else {
+			return -EINVAL;
+		}
+	}
+	return count;
+}
+static DEVICE_ATTR(silent, S_IWUGO | S_IRUGO,
+		   get_silent_state, set_silent_state);
+
+
+static int __init dmi_check_cb(const struct dmi_system_id *id)
+{
+	printk(KERN_INFO KBUILD_MODNAME ": found laptop model '%s'\n",
+		id->ident);
+	return 0;
+}
+
+static struct dmi_system_id __initdata samsung_dmi_table[] = {
+	{
+		.ident = "N128",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "N128"),
+			DMI_MATCH(DMI_BOARD_NAME, "N128"),
+		},
+		.callback = dmi_check_cb,
+	},
+	{
+		.ident = "N130",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "N130"),
+			DMI_MATCH(DMI_BOARD_NAME, "N130"),
+		},
+		.callback = dmi_check_cb,
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(dmi, samsung_dmi_table);
+
+static int __init samsung_init(void)
+{
+	struct sabi_retval sretval;
+	const char *testStr = "SECLINUX";
+	void __iomem *memcheck;
+	unsigned int ifaceP;
+	int pStr;
+	int loca;
+	int retval;
+
+	mutex_init(&sabi_mutex);
+
+	if (!force && !dmi_check_system(samsung_dmi_table))
+		return -ENODEV;
+
+	f0000_segment = ioremap(0xf0000, 0xffff);
+	if (!f0000_segment) {
+		printk(KERN_ERR "Can't map the segment at 0xf0000\n");
+		return -EINVAL;
+	}
+
+	/* Try to find the signature "SECLINUX" in memory to find the header */
+	pStr = 0;
+	memcheck = f0000_segment;
+	for (loca = 0; loca < 0xffff; loca++) {
+		char temp = readb(memcheck + loca);
+
+		if (temp == testStr[pStr]) {
+			if (pStr == strlen(testStr)-1)
+				break;
+			++pStr;
+		} else {
+			pStr = 0;
+		}
+	}
+	if (loca == 0xffff) {
+		printk(KERN_ERR "This computer does not support SABI\n");
+		goto error_no_signature;
+		}
+
+	/* point to the SMI port Number */
+	loca += 1;
+	sabi = (memcheck + loca);
+
+	if (debug) {
+		printk(KERN_DEBUG "This computer supports SABI==%x\n",
+			loca + 0xf0000 - 6);
+		printk(KERN_DEBUG "SABI header:\n");
+		printk(KERN_DEBUG " SMI Port Number = 0x%04x\n",
+			readw(sabi + SABI_HEADER_PORT));
+		printk(KERN_DEBUG " SMI Interface Function = 0x%02x\n",
+			readb(sabi + SABI_HEADER_IFACEFUNC));
+		printk(KERN_DEBUG " SMI enable memory buffer = 0x%02x\n",
+			readb(sabi + SABI_HEADER_EN_MEM));
+		printk(KERN_DEBUG " SMI restore memory buffer = 0x%02x\n",
+			readb(sabi + SABI_HEADER_RE_MEM));
+		printk(KERN_DEBUG " SABI data offset = 0x%04x\n",
+			readw(sabi + SABI_HEADER_DATA_OFFSET));
+		printk(KERN_DEBUG " SABI data segment = 0x%04x\n",
+			readw(sabi + SABI_HEADER_DATA_SEGMENT));
+	}
+
+	/* Get a pointer to the SABI Interface */
+	ifaceP = (readw(sabi + SABI_HEADER_DATA_SEGMENT) & 0x0ffff) << 4;
+	ifaceP += readw(sabi + SABI_HEADER_DATA_OFFSET) & 0x0ffff;
+	sabi_iface = ioremap(ifaceP, 16);
+	if (!sabi_iface) {
+		printk(KERN_ERR "Can't remap %x\n", ifaceP);
+		goto exit;
+	}
+	if (debug) {
+		printk(KERN_DEBUG "ifaceP = 0x%08x\n", ifaceP);
+		printk(KERN_DEBUG "sabi_iface = %p\n", sabi_iface);
+
+		test_backlight();
+		test_wireless();
+
+		retval = sabi_get_command(GET_BRIGHTNESS, &sretval);
+		printk(KERN_DEBUG "brightness = 0x%02x\n", sretval.retval[0]);
+	}
+
+	/* Turn on "Linux" mode in the BIOS */
+	retval = sabi_set_command(SET_LINUX, 0x81);
+	if (retval) {
+		printk(KERN_ERR KBUILD_MODNAME ": Linux mode was not set!\n");
+		goto error_no_platform;
+	}
+
+	/* knock up a platform device to hang stuff off of */
+	sdev = platform_device_register_simple("samsung", -1, NULL, 0);
+	if (IS_ERR(sdev))
+		goto error_no_platform;
+
+	/* create a backlight device to talk to this one */
+	backlight_device = backlight_device_register("samsung", &sdev->dev,
+						     NULL, &backlight_ops);
+	if (IS_ERR(backlight_device))
+		goto error_no_backlight;
+
+	backlight_device->props.max_brightness = MAX_BRIGHT;
+	backlight_device->props.brightness = read_brightness();
+	backlight_device->props.power = FB_BLANK_UNBLANK;
+	backlight_update_status(backlight_device);
+
+	retval = init_wireless(sdev);
+	if (retval)
+		goto error_no_rfk;
+
+	retval = device_create_file(&sdev->dev, &dev_attr_silent);
+	if (retval)
+		goto error_file_create;
+
+exit:
+	return 0;
+
+error_file_create:
+	destroy_wireless();
+
+error_no_rfk:
+	backlight_device_unregister(backlight_device);
+
+error_no_backlight:
+	platform_device_unregister(sdev);
+
+error_no_platform:
+	iounmap(sabi_iface);
+
+error_no_signature:
+	iounmap(f0000_segment);
+	return -EINVAL;
+}
+
+static void __exit samsung_exit(void)
+{
+	/* Turn off "Linux" mode in the BIOS */
+	sabi_set_command(SET_LINUX, 0x80);
+
+	device_remove_file(&sdev->dev, &dev_attr_silent);
+	backlight_device_unregister(backlight_device);
+	destroy_wireless();
+	iounmap(sabi_iface);
+	iounmap(f0000_segment);
+	platform_device_unregister(sdev);
+}
+
+module_init(samsung_init);
+module_exit(samsung_exit);
+
+MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@suse.de>");
+MODULE_DESCRIPTION("Samsung Backlight driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c
index f890a16..e7bc9ec 100644
--- a/drivers/staging/sep/sep_driver.c
+++ b/drivers/staging/sep/sep_driver.c
@@ -273,7 +273,8 @@
 						void *virt_address)
 {
 	dma_addr_t pa = sep->shared_bus + (virt_address - sep->shared_addr);
-	edbg("sep: virt to bus b %08llx v %p\n", pa, virt_address);
+	edbg("sep: virt to bus b %08llx v %p\n",
+		(unsigned long long)pa, virt_address);
 	return pa;
 }
 
@@ -1788,6 +1789,7 @@
 	first_table_data.physical_address = 0xffffffff;
 
 	/* find the free structure for flow data */
+	error = -EINVAL;
 	flow_context_ptr = sep_find_flow_context(sep, SEP_FREE_FLOW_ID);
 	if (flow_context_ptr == NULL)
 		goto end_function;
@@ -2447,7 +2449,7 @@
 #endif
 
 /*
-  Function that is activaed on the succesful probe of the SEP device
+  Function that is activated on the successful probe of the SEP device
 */
 static int __devinit sep_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c
index 52af44c..060e9de 100644
--- a/drivers/staging/serqt_usb2/serqt_usb2.c
+++ b/drivers/staging/serqt_usb2/serqt_usb2.c
@@ -929,7 +929,7 @@
 	dbg(__FILE__ "qt_setuart completed.\n");
 
 	/*
-	 * Put this here to make it responsive to stty and defauls set by
+	 * Put this here to make it responsive to stty and defaults set by
 	 * the tty layer
 	 */
 	/* FIXME: is this needed? */
diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c
index e67a130..5b191af 100644
--- a/drivers/staging/slicoss/slicoss.c
+++ b/drivers/staging/slicoss/slicoss.c
@@ -354,7 +354,6 @@
 	.ndo_get_stats		= slic_get_stats,
 	.ndo_set_multicast_list	= slic_mcast_set_list,
 	.ndo_validate_addr	= eth_validate_addr,
-	.ndo_set_mac_address	= eth_mac_addr,
 	.ndo_change_mtu		= eth_change_mtu,
 };
 
diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c
index 6e91fc2..ef43713 100644
--- a/drivers/staging/usbip/vhci_hcd.c
+++ b/drivers/staging/usbip/vhci_hcd.c
@@ -56,7 +56,7 @@
 static int vhci_get_frame_number(struct usb_hcd *hcd);
 
 static const char driver_name[] = "vhci_hcd";
-static const char driver_desc[] = "USB/IP Virtual Host Contoroller";
+static const char driver_desc[] = "USB/IP Virtual Host Controller";
 
 struct vhci_hcd *the_controller;
 
diff --git a/drivers/staging/vme/TODO b/drivers/staging/vme/TODO
index adc5fca..2201ff6 100644
--- a/drivers/staging/vme/TODO
+++ b/drivers/staging/vme/TODO
@@ -11,7 +11,7 @@
 suitability of a DMA controller based on it's supported modes of operation, as
 opposed to the resource allocation mechanisms for master and slave windows:
 
-	struct vme_resource *vme_request_dma(struct device *dev);
+	struct vme_resource *vme_dma_request(struct device *dev);
 
 As opposed to:
 
diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c
index e139eae..1cf3e91 100644
--- a/drivers/staging/vme/bridges/vme_ca91cx42.c
+++ b/drivers/staging/vme/bridges/vme_ca91cx42.c
@@ -15,7 +15,6 @@
  * option) any later version.
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/types.h>
@@ -54,9 +53,6 @@
 			 * Only one VME interrupt can be
 			 * generated at a time, provide locking
 			 */
-struct mutex vme_irq;   /* Locking for VME irq callback configuration */
-
-
 
 static char driver_name[] = "vme_ca91cx42";
 
@@ -158,23 +154,13 @@
 static u32 ca91cx42_VIRQ_irqhandler(int stat)
 {
 	int vec, i, serviced = 0;
-	void (*call)(int, int, void *);
-	void *priv_data;
 
 	for (i = 7; i > 0; i--) {
 		if (stat & (1 << i)) {
 			vec = ioread32(ca91cx42_bridge->base +
 				CA91CX42_V_STATID[i]) & 0xff;
 
-			call = ca91cx42_bridge->irq[i - 1].callback[vec].func;
-			priv_data =
-			ca91cx42_bridge->irq[i - 1].callback[vec].priv_data;
-
-			if (call != NULL)
-				call(i, vec, priv_data);
-			else
-				printk("Spurilous VME interrupt, level:%x, "
-					"vector:%x\n", i, vec);
+			vme_irq_handler(ca91cx42_bridge, i, vec);
 
 			serviced |= (1 << i);
 		}
@@ -235,6 +221,8 @@
 	/* Initialise list for VME bus errors */
 	INIT_LIST_HEAD(&(bridge->vme_errors));
 
+	mutex_init(&(bridge->irq_mtx));
+
 	/* Disable interrupts from PCI to VME */
 	iowrite32(0, bridge->base + VINT_EN);
 
@@ -282,66 +270,31 @@
 /*
  * Set up an VME interrupt
  */
-int ca91cx42_request_irq(int level, int statid,
-	void (*callback)(int level, int vector, void *priv_data),
-	void *priv_data)
+void ca91cx42_irq_set(int level, int state, int sync)
+
 {
+	struct pci_dev *pdev;
 	u32 tmp;
 
-	mutex_lock(&(vme_irq));
-
-	if (ca91cx42_bridge->irq[level - 1].callback[statid].func) {
-		mutex_unlock(&(vme_irq));
-		printk("VME Interrupt already taken\n");
-		return -EBUSY;
-	}
-
-
-	ca91cx42_bridge->irq[level - 1].count++;
-	ca91cx42_bridge->irq[level - 1].callback[statid].priv_data = priv_data;
-	ca91cx42_bridge->irq[level - 1].callback[statid].func = callback;
-
 	/* Enable IRQ level */
 	tmp = ioread32(ca91cx42_bridge->base + LINT_EN);
-	tmp |= CA91CX42_LINT_VIRQ[level];
+
+	if (state == 0)
+		tmp &= ~CA91CX42_LINT_VIRQ[level];
+	else
+		tmp |= CA91CX42_LINT_VIRQ[level];
+
 	iowrite32(tmp, ca91cx42_bridge->base + LINT_EN);
 
-	mutex_unlock(&(vme_irq));
-
-	return 0;
-}
-
-/*
- * Free VME interrupt
- */
-void ca91cx42_free_irq(int level, int statid)
-{
-	u32 tmp;
-	struct pci_dev *pdev;
-
-	mutex_lock(&(vme_irq));
-
-	ca91cx42_bridge->irq[level - 1].count--;
-
-	/* Disable IRQ level if no more interrupts attached at this level*/
-	if (ca91cx42_bridge->irq[level - 1].count == 0) {
-		tmp = ioread32(ca91cx42_bridge->base + LINT_EN);
-		tmp &= ~CA91CX42_LINT_VIRQ[level];
-		iowrite32(tmp, ca91cx42_bridge->base + LINT_EN);
-
+	if ((state == 0) && (sync != 0)) {
 		pdev = container_of(ca91cx42_bridge->parent, struct pci_dev,
 			dev);
 
 		synchronize_irq(pdev->irq);
 	}
-
-	ca91cx42_bridge->irq[level - 1].callback[statid].func = NULL;
-	ca91cx42_bridge->irq[level - 1].callback[statid].priv_data = NULL;
-
-	mutex_unlock(&(vme_irq));
 }
 
-int ca91cx42_generate_irq(int level, int statid)
+int ca91cx42_irq_generate(int level, int statid)
 {
 	u32 tmp;
 
@@ -1065,7 +1018,6 @@
 	init_waitqueue_head(&dma_queue);
 	init_waitqueue_head(&iack_queue);
 	mutex_init(&(vme_int));
-	mutex_init(&(vme_irq));
 	mutex_init(&(vme_rmw));
 
 	ca91cx42_bridge->parent = &(pdev->dev);
@@ -1182,9 +1134,8 @@
 	ca91cx42_bridge->dma_list_exec = ca91cx42_dma_list_exec;
 	ca91cx42_bridge->dma_list_empty = ca91cx42_dma_list_empty;
 #endif
-	ca91cx42_bridge->request_irq = ca91cx42_request_irq;
-	ca91cx42_bridge->free_irq = ca91cx42_free_irq;
-	ca91cx42_bridge->generate_irq = ca91cx42_generate_irq;
+	ca91cx42_bridge->irq_set = ca91cx42_irq_set;
+	ca91cx42_bridge->irq_generate = ca91cx42_irq_generate;
 #if 0
 	ca91cx42_bridge->lm_set = ca91cx42_lm_set;
 	ca91cx42_bridge->lm_get = ca91cx42_lm_get;
@@ -1220,7 +1171,9 @@
 	vme_unregister_bridge(ca91cx42_bridge);
 err_reg:
 	ca91cx42_crcsr_exit(pdev);
+#if 0
 err_crcsr:
+#endif
 err_lm:
 	/* resources are stored in link list */
 	list_for_each(pos, &(ca91cx42_bridge->lm_resources)) {
@@ -1275,7 +1228,6 @@
 	struct vme_slave_resource *slave_image;
 	struct vme_dma_resource *dma_ctrlr;
 	struct vme_lm_resource *lm;
-	int i;
 
 	/* Turn off Ints */
 	iowrite32(0, ca91cx42_bridge->base + LINT_EN);
diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c
index 00fe080..89a7dcc 100644
--- a/drivers/staging/vme/bridges/vme_tsi148.c
+++ b/drivers/staging/vme/bridges/vme_tsi148.c
@@ -13,7 +13,6 @@
  * option) any later version.
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/mm.h>
@@ -78,8 +77,6 @@
 				 * Only one VME interrupt can be
 				 * generated at a time, provide locking
 				 */
-struct mutex vme_irq;	/* Locking for VME irq callback configuration */
-
 
 static char driver_name[] = "vme_tsi148";
 
@@ -240,7 +237,6 @@
  */
 static u32 tsi148_IACK_irqhandler(void)
 {
-	printk("tsi148_IACK_irqhandler\n");
 	wake_up(&iack_queue);
 
 	return TSI148_LCSR_INTC_IACKC;
@@ -252,8 +248,6 @@
 static u32 tsi148_VIRQ_irqhandler(u32 stat)
 {
 	int vec, i, serviced = 0;
-	void (*call)(int, int, void *);
-	void *priv_data;
 
 	for (i = 7; i > 0; i--) {
 		if (stat & (1 << i)) {
@@ -266,15 +260,7 @@
 			vec = ioread8(tsi148_bridge->base +
 				TSI148_LCSR_VIACK[i] + 3);
 
-			call = tsi148_bridge->irq[i - 1].callback[vec].func;
-			priv_data =
-				tsi148_bridge->irq[i-1].callback[vec].priv_data;
-
-			if (call != NULL)
-				call(i, vec, priv_data);
-			else
-				printk("Spurilous VME interrupt, level:%x, "
-					"vector:%x\n", i, vec);
+			vme_irq_handler(tsi148_bridge, i, vec);
 
 			serviced |= (1 << i);
 		}
@@ -354,6 +340,8 @@
 	/* Initialise list for VME bus errors */
 	INIT_LIST_HEAD(&(bridge->vme_errors));
 
+	mutex_init(&(bridge->irq_mtx));
+
 	result = request_irq(pdev->irq,
 			     tsi148_irqhandler,
 			     IRQF_SHARED,
@@ -433,55 +421,15 @@
 }
 
 /*
- * Set up an VME interrupt
+ * Configure VME interrupt
  */
-int tsi148_request_irq(int level, int statid,
-	void (*callback)(int level, int vector, void *priv_data),
-        void *priv_data)
+void tsi148_irq_set(int level, int state, int sync)
 {
-	u32 tmp;
-
-	mutex_lock(&(vme_irq));
-
-	if(tsi148_bridge->irq[level - 1].callback[statid].func) {
-		mutex_unlock(&(vme_irq));
-		printk("VME Interrupt already taken\n");
-		return -EBUSY;
-	}
-
-
-	tsi148_bridge->irq[level - 1].count++;
-	tsi148_bridge->irq[level - 1].callback[statid].priv_data = priv_data;
-	tsi148_bridge->irq[level - 1].callback[statid].func = callback;
-
-	/* Enable IRQ level */
-	tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO);
-	tmp |= TSI148_LCSR_INTEO_IRQEO[level - 1];
-	iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO);
-
-	tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN);
-	tmp |= TSI148_LCSR_INTEN_IRQEN[level - 1];
-	iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEN);
-
-	mutex_unlock(&(vme_irq));
-
-	return 0;
-}
-
-/*
- * Free VME interrupt
- */
-void tsi148_free_irq(int level, int statid)
-{
-	u32 tmp;
 	struct pci_dev *pdev;
+	u32 tmp;
 
-	mutex_lock(&(vme_irq));
-
-	tsi148_bridge->irq[level - 1].count--;
-
-	/* Disable IRQ level if no more interrupts attached at this level*/
-	if (tsi148_bridge->irq[level - 1].count == 0) {
+	/* We need to do the ordering differently for enabling and disabling */
+	if (state == 0) {
 		tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN);
 		tmp &= ~TSI148_LCSR_INTEN_IRQEN[level - 1];
 		iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEN);
@@ -490,22 +438,28 @@
 		tmp &= ~TSI148_LCSR_INTEO_IRQEO[level - 1];
 		iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO);
 
-		pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev);
+		if (sync != 0) {
+			pdev = container_of(tsi148_bridge->parent,
+				struct pci_dev, dev);
 
-		synchronize_irq(pdev->irq);
+			synchronize_irq(pdev->irq);
+		}
+	} else {
+		tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO);
+		tmp |= TSI148_LCSR_INTEO_IRQEO[level - 1];
+		iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO);
+
+		tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN);
+		tmp |= TSI148_LCSR_INTEN_IRQEN[level - 1];
+		iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEN);
 	}
-
-	tsi148_bridge->irq[level - 1].callback[statid].func = NULL;
-	tsi148_bridge->irq[level - 1].callback[statid].priv_data = NULL;
-
-	mutex_unlock(&(vme_irq));
 }
 
 /*
  * Generate a VME bus interrupt at the requested level & vector. Wait for
  * interrupt to be acked.
  */
-int tsi148_generate_irq(int level, int statid)
+int tsi148_irq_generate(int level, int statid)
 {
 	u32 tmp;
 
@@ -891,7 +845,7 @@
 		image->pci_resource.start);
 
 	/* If the existing size is OK, return */
-	if (existing_size == (size - 1))
+	if ((size != 0) && (existing_size == (size - 1)))
 		return 0;
 
 	if (existing_size != 0) {
@@ -903,6 +857,11 @@
 		memset(&(image->pci_resource), 0, sizeof(struct resource));
 	}
 
+	/* Exit here if size is zero */
+	if (size == 0) {
+		return 0;
+	}
+
 	if (image->pci_resource.name == NULL) {
 		image->pci_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL);
 		if (image->pci_resource.name == NULL) {
@@ -981,12 +940,13 @@
 
 	/* Verify input data */
 	if (vme_base & 0xFFFF) {
-		printk("Invalid VME Window alignment\n");
+		printk(KERN_ERR "Invalid VME Window alignment\n");
 		retval = -EINVAL;
 		goto err_window;
 	}
-	if (size < 0x10000) {
-		printk("Invalid VME Window size\n");
+
+	if ((size == 0) && (enabled != 0)) {
+		printk(KERN_ERR "Size must be non-zero for enabled windows\n");
 		retval = -EINVAL;
 		goto err_window;
 	}
@@ -994,26 +954,31 @@
 	spin_lock(&(image->lock));
 
 	/* Let's allocate the resource here rather than further up the stack as
-	 * it avoids pushing loads of bus dependant stuff up the stack
+	 * it avoids pushing loads of bus dependant stuff up the stack. If size
+	 * is zero, any existing resource will be freed.
 	 */
 	retval = tsi148_alloc_resource(image, size);
 	if (retval) {
 		spin_unlock(&(image->lock));
-		printk(KERN_ERR "Unable to allocate memory for resource "
-			"name\n");
-		retval = -ENOMEM;
+		printk(KERN_ERR "Unable to allocate memory for "
+			"resource\n");
 		goto err_res;
 	}
 
-	pci_base = (unsigned long long)image->pci_resource.start;
+	if (size == 0) {
+		pci_base = 0;
+		pci_bound = 0;
+		vme_offset = 0;
+	} else {
+		pci_base = (unsigned long long)image->pci_resource.start;
 
-
-	/*
-	 * Bound address is a valid address for the window, adjust
-	 * according to window granularity.
-	 */
-	pci_bound = pci_base + (size - 0x10000);
-	vme_offset = vme_base - pci_base;
+		/*
+		 * Bound address is a valid address for the window, adjust
+		 * according to window granularity.
+		 */
+		pci_bound = pci_base + (size - 0x10000);
+		vme_offset = vme_base - pci_base;
+	}
 
 	/* Convert 64-bit variables to 2x 32-bit variables */
 	reg_split(pci_base, &pci_base_high, &pci_base_low);
@@ -1022,19 +987,19 @@
 
 	if (pci_base_low & 0xFFFF) {
 		spin_unlock(&(image->lock));
-		printk("Invalid PCI base alignment\n");
+		printk(KERN_ERR "Invalid PCI base alignment\n");
 		retval = -EINVAL;
 		goto err_gran;
 	}
 	if (pci_bound_low & 0xFFFF) {
 		spin_unlock(&(image->lock));
-		printk("Invalid PCI bound alignment\n");
+		printk(KERN_ERR "Invalid PCI bound alignment\n");
 		retval = -EINVAL;
 		goto err_gran;
 	}
 	if (vme_offset_low & 0xFFFF) {
 		spin_unlock(&(image->lock));
-		printk("Invalid VME Offset alignment\n");
+		printk(KERN_ERR "Invalid VME Offset alignment\n");
 		retval = -EINVAL;
 		goto err_gran;
 	}
@@ -1094,7 +1059,8 @@
 		temp_ctl |= TSI148_LCSR_OTAT_TM_2eSST;
 	}
 	if (cycle & VME_2eSSTB) {
-		printk("Currently not setting Broadcast Select Registers\n");
+		printk(KERN_WARNING "Currently not setting Broadcast Select "
+			"Registers\n");
 		temp_ctl &= ~TSI148_LCSR_OTAT_TM_M;
 		temp_ctl |= TSI148_LCSR_OTAT_TM_2eSSTB;
 	}
@@ -1110,7 +1076,7 @@
 		break;
 	default:
 		spin_unlock(&(image->lock));
-		printk("Invalid data width\n");
+		printk(KERN_ERR "Invalid data width\n");
 		retval = -EINVAL;
 		goto err_dwidth;
 	}
@@ -1147,7 +1113,7 @@
 		break;
 	default:
 		spin_unlock(&(image->lock));
-		printk("Invalid address space\n");
+		printk(KERN_ERR "Invalid address space\n");
 		retval = -EINVAL;
 		goto err_aspace;
 		break;
@@ -2154,7 +2120,7 @@
 	iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO);
 
 	iowrite32be(TSI148_LCSR_INTC_LMC[monitor],
-		 tsi148_bridge->base + TSI148_LCSR_INTEO);
+		 tsi148_bridge->base + TSI148_LCSR_INTC);
 
 	/* Detach callback */
 	lm_callback[monitor] = NULL;
@@ -2334,7 +2300,6 @@
 	init_waitqueue_head(&dma_queue[1]);
 	init_waitqueue_head(&iack_queue);
 	mutex_init(&(vme_int));
-	mutex_init(&(vme_irq));
 	mutex_init(&(vme_rmw));
 
 	tsi148_bridge->parent = &(pdev->dev);
@@ -2482,9 +2447,8 @@
 	tsi148_bridge->dma_list_add = tsi148_dma_list_add;
 	tsi148_bridge->dma_list_exec = tsi148_dma_list_exec;
 	tsi148_bridge->dma_list_empty = tsi148_dma_list_empty;
-	tsi148_bridge->request_irq = tsi148_request_irq;
-	tsi148_bridge->free_irq = tsi148_free_irq;
-	tsi148_bridge->generate_irq = tsi148_generate_irq;
+	tsi148_bridge->irq_set = tsi148_irq_set;
+	tsi148_bridge->irq_generate = tsi148_irq_generate;
 	tsi148_bridge->lm_set = tsi148_lm_set;
 	tsi148_bridge->lm_get = tsi148_lm_get;
 	tsi148_bridge->lm_attach = tsi148_lm_attach;
@@ -2617,13 +2581,6 @@
 	}
 
 	/*
-	 *  Disable and clear all interrupts.
-	 */
-	iowrite32be(0x0, tsi148_bridge->base + TSI148_LCSR_INTEO);
-	iowrite32be(0xFFFFFFFF, tsi148_bridge->base + TSI148_LCSR_INTC);
-	iowrite32be(0xFFFFFFFF, tsi148_bridge->base + TSI148_LCSR_INTEN);
-
-	/*
 	 *  Map all Interrupts to PCI INTA
 	 */
 	iowrite32be(0x0, tsi148_bridge->base + TSI148_LCSR_INTM1);
diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c
index 7891288..e228942 100644
--- a/drivers/staging/vme/devices/vme_user.c
+++ b/drivers/staging/vme/devices/vme_user.c
@@ -31,7 +31,6 @@
 #include <linux/spinlock.h>
 #include <linux/syscalls.h>
 #include <linux/types.h>
-#include <linux/version.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -625,7 +624,7 @@
 static int __init vme_user_probe(struct device *dev, int cur_bus, int cur_slot)
 {
 	int i, err;
-	char name[8];
+	char name[12];
 
 	/* Save pointer to the bridge device */
 	if (vme_user_bridge != NULL) {
diff --git a/drivers/staging/vme/vme.c b/drivers/staging/vme/vme.c
index 477a1ad..994fdb9 100644
--- a/drivers/staging/vme/vme.c
+++ b/drivers/staging/vme/vme.c
@@ -13,7 +13,6 @@
  * option) any later version.
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/mm.h>
@@ -644,7 +643,7 @@
  * Request a DMA controller with specific attributes, return some unique
  * identifier.
  */
-struct vme_resource *vme_request_dma(struct device *dev)
+struct vme_resource *vme_dma_request(struct device *dev)
 {
 	struct vme_bridge *bridge;
 	struct list_head *dma_pos = NULL;
@@ -705,7 +704,7 @@
 err_bus:
 	return NULL;
 }
-EXPORT_SYMBOL(vme_request_dma);
+EXPORT_SYMBOL(vme_dma_request);
 
 /*
  * Start new list
@@ -880,7 +879,7 @@
 		return -EINVAL;
 	}
 
-	if (mutex_trylock(&(list->mtx))) {
+	if (!mutex_trylock(&(list->mtx))) {
 		printk("Link List already submitted\n");
 		return -EINVAL;
 	}
@@ -923,7 +922,7 @@
 		return -EINVAL;
 	}
 
-	if (mutex_trylock(&(list->mtx))) {
+	if (!mutex_trylock(&(list->mtx))) {
 		printk("Link List in use\n");
 		return -EINVAL;
 	}
@@ -956,7 +955,7 @@
 
 	ctrlr = list_entry(resource->entry, struct vme_dma_resource, list);
 
-	if (mutex_trylock(&(ctrlr->mtx))) {
+	if (!mutex_trylock(&(ctrlr->mtx))) {
 		printk("Resource busy, can't free\n");
 		return -EBUSY;
 	}
@@ -975,7 +974,23 @@
 }
 EXPORT_SYMBOL(vme_dma_free);
 
-int vme_request_irq(struct device *dev, int level, int statid,
+void vme_irq_handler(struct vme_bridge *bridge, int level, int statid)
+{
+	void (*call)(int, int, void *);
+	void *priv_data;
+
+	call = bridge->irq[level - 1].callback[statid].func;
+	priv_data = bridge->irq[level - 1].callback[statid].priv_data;
+
+	if (call != NULL)
+		call(level, statid, priv_data);
+	else
+		printk(KERN_WARNING "Spurilous VME interrupt, level:%x, "
+			"vector:%x\n", level, statid);
+}
+EXPORT_SYMBOL(vme_irq_handler);
+
+int vme_irq_request(struct device *dev, int level, int statid,
 	void (*callback)(int level, int vector, void *priv_data),
 	void *priv_data)
 {
@@ -988,20 +1003,37 @@
 	}
 
 	if((level < 1) || (level > 7)) {
-		printk(KERN_WARNING "Invalid interrupt level\n");
+		printk(KERN_ERR "Invalid interrupt level\n");
 		return -EINVAL;
 	}
 
-	if (bridge->request_irq == NULL) {
-		printk("Registering interrupts not supported\n");
+	if (bridge->irq_set == NULL) {
+		printk(KERN_ERR "Configuring interrupts not supported\n");
 		return -EINVAL;
 	}
 
-	return bridge->request_irq(level, statid, callback, priv_data);
+	mutex_lock(&(bridge->irq_mtx));
+
+	if (bridge->irq[level - 1].callback[statid].func) {
+		mutex_unlock(&(bridge->irq_mtx));
+		printk(KERN_WARNING "VME Interrupt already taken\n");
+		return -EBUSY;
+	}
+
+	bridge->irq[level - 1].count++;
+	bridge->irq[level - 1].callback[statid].priv_data = priv_data;
+	bridge->irq[level - 1].callback[statid].func = callback;
+
+	/* Enable IRQ level */
+	bridge->irq_set(level, 1, 1);
+
+	mutex_unlock(&(bridge->irq_mtx));
+
+	return 0;
 }
-EXPORT_SYMBOL(vme_request_irq);
+EXPORT_SYMBOL(vme_irq_request);
 
-void vme_free_irq(struct device *dev, int level, int statid)
+void vme_irq_free(struct device *dev, int level, int statid)
 {
 	struct vme_bridge *bridge;
 
@@ -1012,20 +1044,31 @@
 	}
 
 	if((level < 1) || (level > 7)) {
-		printk(KERN_WARNING "Invalid interrupt level\n");
+		printk(KERN_ERR "Invalid interrupt level\n");
 		return;
 	}
 
-	if (bridge->free_irq == NULL) {
-		printk("Freeing interrupts not supported\n");
+	if (bridge->irq_set == NULL) {
+		printk(KERN_ERR "Configuring interrupts not supported\n");
 		return;
 	}
 
-	bridge->free_irq(level, statid);
+	mutex_lock(&(bridge->irq_mtx));
+
+	bridge->irq[level - 1].count--;
+
+	/* Disable IRQ level if no more interrupts attached at this level*/
+	if (bridge->irq[level - 1].count == 0)
+		bridge->irq_set(level, 0, 1);
+
+	bridge->irq[level - 1].callback[statid].func = NULL;
+	bridge->irq[level - 1].callback[statid].priv_data = NULL;
+
+	mutex_unlock(&(bridge->irq_mtx));
 }
-EXPORT_SYMBOL(vme_free_irq);
+EXPORT_SYMBOL(vme_irq_free);
 
-int vme_generate_irq(struct device *dev, int level, int statid)
+int vme_irq_generate(struct device *dev, int level, int statid)
 {
 	struct vme_bridge *bridge;
 
@@ -1040,14 +1083,14 @@
 		return -EINVAL;
 	}
 
-	if (bridge->generate_irq == NULL) {
+	if (bridge->irq_generate == NULL) {
 		printk("Interrupt generation not supported\n");
 		return -EINVAL;
 	}
 
-	return bridge->generate_irq(level, statid);
+	return bridge->irq_generate(level, statid);
 }
-EXPORT_SYMBOL(vme_generate_irq);
+EXPORT_SYMBOL(vme_irq_generate);
 
 /*
  * Request the location monitor, return resource or NULL
@@ -1148,7 +1191,7 @@
 
 	/* XXX Check parameters */
 
-	return lm->parent->lm_set(lm, lm_base, aspace, cycle);
+	return bridge->lm_set(lm, lm_base, aspace, cycle);
 }
 EXPORT_SYMBOL(vme_lm_set);
 
@@ -1228,16 +1271,18 @@
 
 	lm = list_entry(resource->entry, struct vme_lm_resource, list);
 
-	if (mutex_trylock(&(lm->mtx))) {
-		printk(KERN_ERR "Resource busy, can't free\n");
-		return;
-	}
+	mutex_lock(&(lm->mtx));
 
-	/* XXX Check to see that there aren't any callbacks still attached */
+	/* XXX
+	 * Check to see that there aren't any callbacks still attached, if
+	 * there are we should probably be detaching them!
+	 */
 
 	lm->locked = 0;
 
 	mutex_unlock(&(lm->mtx));
+
+	kfree(resource);
 }
 EXPORT_SYMBOL(vme_lm_free);
 
diff --git a/drivers/staging/vme/vme.h b/drivers/staging/vme/vme.h
index 6206e91..97dc22e 100644
--- a/drivers/staging/vme/vme.h
+++ b/drivers/staging/vme/vme.h
@@ -123,7 +123,7 @@
 	unsigned int, loff_t);
 void vme_master_free(struct vme_resource *);
 
-struct vme_resource *vme_request_dma(struct device *);
+struct vme_resource *vme_dma_request(struct device *);
 struct vme_dma_list *vme_new_dma_list(struct vme_resource *);
 struct vme_dma_attr *vme_dma_pattern_attribute(u32, vme_pattern_t);
 struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t);
@@ -136,10 +136,10 @@
 int vme_dma_list_free(struct vme_dma_list *);
 int vme_dma_free(struct vme_resource *);
 
-int vme_request_irq(struct device *, int, int,
+int vme_irq_request(struct device *, int, int,
 	void (*callback)(int, int, void *), void *);
-void vme_free_irq(struct device *, int, int);
-int vme_generate_irq(struct device *, int, int);
+void vme_irq_free(struct device *, int, int);
+int vme_irq_generate(struct device *, int, int);
 
 struct vme_resource * vme_lm_request(struct device *);
 int vme_lm_count(struct vme_resource *);
diff --git a/drivers/staging/vme/vme_api.txt b/drivers/staging/vme/vme_api.txt
index 591eba5..a5c1b1c 100644
--- a/drivers/staging/vme/vme_api.txt
+++ b/drivers/staging/vme/vme_api.txt
@@ -77,7 +77,7 @@
 	struct vme_resource * vme_slave_request(struct device *dev,
 		vme_address_t aspace, vme_cycle_t cycle);
 
-	struct vme_resource *vme_request_dma(struct device *dev);
+	struct vme_resource *vme_dma_request(struct device *dev);
 
 For slave windows these attributes are split into those of type 'vme_address_t'
 and 'vme_cycle_t'. Master windows add a further set of attributes 'vme_cycle_t'.
@@ -290,10 +290,10 @@
 callback function. A void pointer parameter is provided, the value of which is
 passed to the callback function, the use of this pointer is user undefined:
 
-	int vme_request_irq(struct device *dev, int level, int statid,
+	int vme_irq_request(struct device *dev, int level, int statid,
 		void (*callback)(int, int, void *), void *priv);
 
-	void vme_free_irq(struct device *dev, int level, int statid);
+	void vme_irq_free(struct device *dev, int level, int statid);
 
 The callback parameters are as follows. Care must be taken in writing a callback
 function, callback functions run in interrupt context:
@@ -307,7 +307,7 @@
 The following function can be used to generate a VME interrupt at a given VME
 level and VME status ID:
 
-	int vme_generate_irq(struct device *dev, int level, int statid);
+	int vme_irq_generate(struct device *dev, int level, int statid);
 
 
 Location monitors
diff --git a/drivers/staging/vme/vme_bridge.h b/drivers/staging/vme/vme_bridge.h
index e43cc19..851fa92 100644
--- a/drivers/staging/vme/vme_bridge.h
+++ b/drivers/staging/vme/vme_bridge.h
@@ -120,6 +120,8 @@
 
 	/* Interrupt callbacks */
 	struct vme_irq irq[7];
+	/* Locking for VME irq callback configuration */
+	struct mutex irq_mtx;
 
 	/* Slave Functions */
 	int (*slave_get) (struct vme_slave_resource *, int *,
@@ -149,9 +151,8 @@
 	int (*dma_list_empty) (struct vme_dma_list *);
 
 	/* Interrupt Functions */
-	int (*request_irq) (int, int, void (*cback)(int, int, void*), void *);
-	void (*free_irq) (int, int);
-	int (*generate_irq) (int, int);
+	void (*irq_set) (int, int, int);
+	int (*irq_generate) (int, int);
 
 	/* Location monitor functions */
 	int (*lm_set) (struct vme_lm_resource *, unsigned long long,
@@ -175,6 +176,8 @@
 #endif
 };
 
+void vme_irq_handler(struct vme_bridge *, int, int);
+
 int vme_register_bridge (struct vme_bridge *);
 void vme_unregister_bridge (struct vme_bridge *);
 
diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h
index fa7f0fc..cde44d2 100644
--- a/drivers/staging/vt6655/device.h
+++ b/drivers/staging/vt6655/device.h
@@ -44,7 +44,6 @@
 #include <linux/timer.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
-#include <linux/version.h>
 #include <linux/string.h>
 #include <linux/wait.h>
 #include <linux/if_arp.h>
@@ -79,7 +78,6 @@
 // device specific
 //
 
-#include "kcompat.h"
 #include "device_cfg.h"
 #include "ttype.h"
 #include "80211hdr.h"
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c
index 53450b4..0db8d7b 100644
--- a/drivers/staging/vt6655/device_main.c
+++ b/drivers/staging/vt6655/device_main.c
@@ -661,7 +661,7 @@
    if(zonetype!=pDevice->abyEEPROM[EEP_OFS_ZONETYPE])
       printk("zonetype in file[%02x] mismatch with in EEPROM[%02x]\n",zonetype,pDevice->abyEEPROM[EEP_OFS_ZONETYPE]);
    else
-      printk("Read Zonetype file sucess,use default zonetype setting[%02x]\n",zonetype);
+      printk("Read Zonetype file success,use default zonetype setting[%02x]\n",zonetype);
  }
  	}
   else
diff --git a/drivers/staging/vt6655/ioctl.c b/drivers/staging/vt6655/ioctl.c
index fc9cbe0..d9a5fd2 100644
--- a/drivers/staging/vt6655/ioctl.c
+++ b/drivers/staging/vt6655/ioctl.c
@@ -159,7 +159,7 @@
 	 else if(zonetype == 0x02) { //Europe
              sZoneTypeCmd.ZoneType = ZoneType_Europe;
 	 }
-	 else { //Unknow ZoneType
+	 else { //Unknown ZoneType
 	        printk("Error:ZoneType[%x] Unknown ???\n",zonetype);
 	         result = -EFAULT;
 		break;
@@ -692,7 +692,7 @@
      wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, pItemSSID->abySSID);
    }
    #endif
-         pDevice->fWPA_Authened = TRUE;           //is sucessful peer to wpa_Result.authenticated?
+         pDevice->fWPA_Authened = TRUE;           //is successful peer to wpa_Result.authenticated?
 }
 
         //printk("get private wpa_supplicant announce WPA SM\n");
diff --git a/drivers/staging/vt6655/kcompat.h b/drivers/staging/vt6655/kcompat.h
deleted file mode 100644
index 2cf634c..0000000
--- a/drivers/staging/vt6655/kcompat.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking, Inc. All rights reserved.
- *
- * 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * File: kcompat.h
- *
- * Purpose: define kernel compatibility header
- *
- * Author: Lyndon Chen
- *
- * Date: Apr 8, 2002
- *
- */
-
-#ifndef _KCOMPAT_H
-#define _KCOMPAT_H
-
-#include <linux/version.h>
-
-#ifndef HAVE_NETDEV_PRIV
-#define netdev_priv(dev) (dev->priv)
-#endif
-
-#endif
-
diff --git a/drivers/staging/vt6655/mib.h b/drivers/staging/vt6655/mib.h
index 69e04f7..2aa2b91 100644
--- a/drivers/staging/vt6655/mib.h
+++ b/drivers/staging/vt6655/mib.h
@@ -325,10 +325,10 @@
    #ifdef Calcu_LinkQual
        //Tx count:
     ULONG TxNoRetryOkCount;         //success tx no retry !
-    ULONG TxRetryOkCount;              //sucess tx but retry !
+    ULONG TxRetryOkCount;              //success tx but retry !
     ULONG TxFailCount;                      //fail tx ?
       //Rx count:
-    ULONG RxOkCnt;                          //sucess rx !
+    ULONG RxOkCnt;                          //success rx !
     ULONG RxFcsErrCnt;                    //fail rx ?
       //statistic
     ULONG SignalStren;
diff --git a/drivers/staging/vt6655/rxtx.h b/drivers/staging/vt6655/rxtx.h
index 17bd1b1..5da815e 100644
--- a/drivers/staging/vt6655/rxtx.h
+++ b/drivers/staging/vt6655/rxtx.h
@@ -35,17 +35,10 @@
 
 /*---------------------  Export Definitions -------------------------*/
 
-/*---------------------  Export Classes  ----------------------------*/
-
 /*---------------------  Export Variables  --------------------------*/
 
 /*---------------------  Export Functions  --------------------------*/
 
-
-#ifdef __cplusplus
-extern "C" {                            /* Assume C declarations for C++ */
-#endif /* __cplusplus */
-
 /*
 VOID vGenerateMACHeader(
     IN PSDevice pDevice,
@@ -111,14 +104,4 @@
 CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket);
 CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket);
 
-#ifdef __cplusplus
-}                                       /* End of extern "C" { */
-#endif /* __cplusplus */
-
-
-
-
 #endif // __RXTX_H__
-
-
-
diff --git a/drivers/staging/vt6655/wcmd.c b/drivers/staging/vt6655/wcmd.c
index d81f5b7..c9eabf9 100644
--- a/drivers/staging/vt6655/wcmd.c
+++ b/drivers/staging/vt6655/wcmd.c
@@ -48,7 +48,6 @@
 #include "wmgr.h"
 #include "power.h"
 #include "wctl.h"
-#include "card.h"
 #include "baseband.h"
 #include "rxtx.h"
 #include "rf.h"
diff --git a/drivers/staging/vt6655/wpa.c b/drivers/staging/vt6655/wpa.c
index f92d33f..5da6714 100644
--- a/drivers/staging/vt6655/wpa.c
+++ b/drivers/staging/vt6655/wpa.c
@@ -147,7 +147,7 @@
         if (pRSN->len >= 12) //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)
         {
             j = 0;
-            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d, sizeof(pBSSList->abyPKType): %ld\n", pRSN->wPKCount, sizeof(pBSSList->abyPKType));
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d, sizeof(pBSSList->abyPKType): %zu\n", pRSN->wPKCount, sizeof(pBSSList->abyPKType));
             for(i = 0; (i < pRSN->wPKCount) && (j < sizeof(pBSSList->abyPKType)/sizeof(BYTE)); i++) {
                 if(pRSN->len >= 12+i*4+4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*i)
                     if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI00, 4))
@@ -178,7 +178,7 @@
             // overlay IE_RSN_Auth structure into correct place
             pIE_RSN_Auth = (PWLAN_IE_RSN_AUTH) pRSN->PKSList[m].abyOUI;
             j = 0;
-            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d, sizeof(pBSSList->abyAuthType): %ld\n",
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d, sizeof(pBSSList->abyAuthType): %zu\n",
                           pIE_RSN_Auth->wAuthCount, sizeof(pBSSList->abyAuthType));
             for(i = 0; (i < pIE_RSN_Auth->wAuthCount) && (j < sizeof(pBSSList->abyAuthType)/sizeof(BYTE)); i++) {
                 if(pRSN->len >= 14+4+(m+i)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*i)
diff --git a/drivers/staging/vt6655/wroute.c b/drivers/staging/vt6655/wroute.c
index ab99161..1d02040 100644
--- a/drivers/staging/vt6655/wroute.c
+++ b/drivers/staging/vt6655/wroute.c
@@ -113,7 +113,7 @@
     }
 
     if (pDevice->bEnableHostWEP) {
-        if (uNodeIndex >= 0) {
+	if (uNodeIndex < MAX_NODE_NUM + 1) {
             pTransmitKey = &STempKey;
             pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
             pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c
index 820a7b8..7dc01db 100644
--- a/drivers/staging/vt6656/baseband.c
+++ b/drivers/staging/vt6656/baseband.c
@@ -46,7 +46,6 @@
 #include "control.h"
 #include "datarate.h"
 #include "rndis.h"
-#include "control.h"
 
 /*---------------------  Static Definitions -------------------------*/
 static int          msglevel                =MSG_LEVEL_INFO;
@@ -1041,7 +1040,7 @@
    if(pDevice->config_file.ZoneType !=pDevice->abyEEPROM[EEP_OFS_ZONETYPE])
       printk("zonetype in file[%02x] mismatch with in EEPROM[%02x]\n",pDevice->config_file.ZoneType,pDevice->abyEEPROM[EEP_OFS_ZONETYPE]);
    else
-      printk("Read Zonetype file sucess,use default zonetype setting[%02x]\n",pDevice->config_file.ZoneType);
+      printk("Read Zonetype file success,use default zonetype setting[%02x]\n",pDevice->config_file.ZoneType);
  }
 }
 
diff --git a/drivers/staging/vt6656/channel.c b/drivers/staging/vt6656/channel.c
index e49796f..f7136b0 100644
--- a/drivers/staging/vt6656/channel.c
+++ b/drivers/staging/vt6656/channel.c
@@ -19,7 +19,7 @@
  *
  * File: channel.c
  *
- * Purpose: Channel number maping
+ * Purpose: Channel number mapping
  *
  * Author: Lucas Lin
  *
diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h
index b02ca2d..8b541d1 100644
--- a/drivers/staging/vt6656/device.h
+++ b/drivers/staging/vt6656/device.h
@@ -44,7 +44,6 @@
 #include <linux/timer.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
-#include <linux/version.h>
 #include <linux/string.h>
 #include <linux/wait.h>
 #include <linux/if_arp.h>
@@ -88,7 +87,6 @@
 // device specific
 //
 
-#include "kcompat.h"
 #include "device_cfg.h"
 #include "ttype.h"
 #include "80211hdr.h"
@@ -103,7 +101,7 @@
 #include "card.h"
 
 /*---------------------  Export Definitions -------------------------*/
-#define VNT_USB_VENDOR_ID                     0x160A
+#define VNT_USB_VENDOR_ID                     0x160a
 #define VNT_USB_PRODUCT_ID                    0x3184
 
 #define MAC_MAX_CONTEXT_REG     (256+128)
diff --git a/drivers/staging/vt6656/firmware.c b/drivers/staging/vt6656/firmware.c
index 52daa3b..585b6b1 100644
--- a/drivers/staging/vt6656/firmware.c
+++ b/drivers/staging/vt6656/firmware.c
@@ -801,7 +801,7 @@
                                             &(pBuffer[ii])
                                             );
 
-            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Download firmware...%d %ld\n", ii, sizeof(abyFirmware));
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Download firmware...%d %zu\n", ii, sizeof(abyFirmware));
             if (NdisStatus != STATUS_SUCCESS) {
                 if (pBuffer)
                     kfree(pBuffer);
diff --git a/drivers/staging/vt6656/hostap.c b/drivers/staging/vt6656/hostap.c
index 0c8267a..1078d61 100644
--- a/drivers/staging/vt6656/hostap.c
+++ b/drivers/staging/vt6656/hostap.c
@@ -37,7 +37,6 @@
 #include "baseband.h"
 #include "wpactl.h"
 #include "key.h"
-#include "mac.h"
 #include "datarate.h"
 
 #define VIAWGET_HOSTAPD_MAX_BUF_SIZE 1024
diff --git a/drivers/staging/vt6656/ioctl.c b/drivers/staging/vt6656/ioctl.c
index d94131f..6f33005 100644
--- a/drivers/staging/vt6656/ioctl.c
+++ b/drivers/staging/vt6656/ioctl.c
@@ -152,7 +152,7 @@
 	 else if(zonetype == 0x02) { //Europe
              sZoneTypeCmd.ZoneType = ZoneType_Europe;
 	 }
-	 else { //Unknow ZoneType
+	 else { //Unknown ZoneType
 	        printk("Error:ZoneType[%x] Unknown ???\n",zonetype);
 	         result = -EFAULT;
 		break;
@@ -679,7 +679,7 @@
      wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, pItemSSID->abySSID);
    }
    #endif
-         pDevice->fWPA_Authened = TRUE;           //is sucessful peer to wpa_Result.authenticated?
+         pDevice->fWPA_Authened = TRUE;           //is successful peer to wpa_Result.authenticated?
 }
 
         //printk("get private wpa_supplicant announce WPA SM\n");
diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c
index aa8d1a2..b7c6a22 100644
--- a/drivers/staging/vt6656/iwctl.c
+++ b/drivers/staging/vt6656/iwctl.c
@@ -1724,7 +1724,7 @@
 	case IW_AUTH_WPA_ENABLED:
 		//pDevice->bWPADEVUp = !! wrq->value;
 		//if(pDevice->bWPADEVUp==TRUE)
-		  // printk("iwctl_siwauth:set WPADEV to enable sucessful*******\n");
+		  // printk("iwctl_siwauth:set WPADEV to enable successful*******\n");
 		//else
 		 //  printk("iwctl_siwauth:set WPADEV to enable fail?????\n");
 		break;
diff --git a/drivers/staging/vt6656/kcompat.h b/drivers/staging/vt6656/kcompat.h
deleted file mode 100644
index 2cf634c..0000000
--- a/drivers/staging/vt6656/kcompat.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking, Inc. All rights reserved.
- *
- * 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * File: kcompat.h
- *
- * Purpose: define kernel compatibility header
- *
- * Author: Lyndon Chen
- *
- * Date: Apr 8, 2002
- *
- */
-
-#ifndef _KCOMPAT_H
-#define _KCOMPAT_H
-
-#include <linux/version.h>
-
-#ifndef HAVE_NETDEV_PRIV
-#define netdev_priv(dev) (dev->priv)
-#endif
-
-#endif
-
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index 0518611..ef17c49 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -64,11 +64,9 @@
 #include "ioctl.h"
 #include "iwctl.h"
 #include "dpc.h"
-#include "iocmd.h"
 #include "datarate.h"
 #include "rf.h"
 #include "firmware.h"
-#include "mac.h"
 #include "rndis.h"
 #include "control.h"
 #include "channel.h"
@@ -809,12 +807,6 @@
         kfree(pDevice);
         return -ENODEV;
     }
-	//2008-0623-02<Remark>by MikeLiu
-        //2007-0821-01<Add>by MikeLiu
-       //#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
-  	//usb_set_intfdata(intf, pDevice);
-	//SET_NETDEV_DEV(netdev, &intf->dev);
-       //#endif
 
 //2008-07-21-01<Add>by MikeLiu
 //register wpadev
@@ -1545,7 +1537,7 @@
   return buffer;
 }
 
-//return --->-1:fail;  >=0:sucessful
+//return --->-1:fail;  >=0:successful
 static int Read_config_file(PSDevice pDevice) {
   int result=0;
   UCHAR      tmpbuffer[100];
diff --git a/drivers/staging/vt6656/mib.h b/drivers/staging/vt6656/mib.h
index b806b4d..ac996d2 100644
--- a/drivers/staging/vt6656/mib.h
+++ b/drivers/staging/vt6656/mib.h
@@ -357,10 +357,10 @@
    #ifdef Calcu_LinkQual
        //Tx count:
     ULONG TxNoRetryOkCount;         //success tx no retry !
-    ULONG TxRetryOkCount;              //sucess tx but retry !
+    ULONG TxRetryOkCount;              //success tx but retry !
     ULONG TxFailCount;                      //fail tx ?
       //Rx count:
-    ULONG RxOkCnt;                          //sucess rx !
+    ULONG RxOkCnt;                          //success rx !
     ULONG RxFcsErrCnt;                    //fail rx ?
       //statistic
     ULONG SignalStren;
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index 94ddf8b..d9fa36c 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -3153,7 +3153,7 @@
     }
 
     if (pDevice->bEnableHostWEP) {
-        if (uNodeIndex >= 0) {
+        if (uNodeIndex < MAX_NODE_NUM + 1) {
             pTransmitKey = &STempKey;
             pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
             pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c
index 6912344..51b2dcf 100644
--- a/drivers/staging/vt6656/wcmd.c
+++ b/drivers/staging/vt6656/wcmd.c
@@ -48,7 +48,6 @@
 #include "wmgr.h"
 #include "power.h"
 #include "wctl.h"
-#include "card.h"
 #include "baseband.h"
 #include "control.h"
 #include "rxtx.h"
@@ -1332,7 +1331,7 @@
     }
 
   spin_lock_irq(&pDevice->lock);
-  //is wap_supplicant running sucessful OR only open && sharekey mode!
+  //is wap_supplicant running successful OR only open && sharekey mode!
   #if 1
   if(((pDevice->bLinkPass ==TRUE)&&(pMgmt->eAuthenMode < WMAC_AUTH_WPA)) ||  //open && sharekey linking
       (pDevice->fWPA_Authened == TRUE)) {   //wpa linking
diff --git a/drivers/staging/vt6656/wpa.c b/drivers/staging/vt6656/wpa.c
index f92d33f..5da6714 100644
--- a/drivers/staging/vt6656/wpa.c
+++ b/drivers/staging/vt6656/wpa.c
@@ -147,7 +147,7 @@
         if (pRSN->len >= 12) //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)
         {
             j = 0;
-            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d, sizeof(pBSSList->abyPKType): %ld\n", pRSN->wPKCount, sizeof(pBSSList->abyPKType));
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d, sizeof(pBSSList->abyPKType): %zu\n", pRSN->wPKCount, sizeof(pBSSList->abyPKType));
             for(i = 0; (i < pRSN->wPKCount) && (j < sizeof(pBSSList->abyPKType)/sizeof(BYTE)); i++) {
                 if(pRSN->len >= 12+i*4+4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*i)
                     if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI00, 4))
@@ -178,7 +178,7 @@
             // overlay IE_RSN_Auth structure into correct place
             pIE_RSN_Auth = (PWLAN_IE_RSN_AUTH) pRSN->PKSList[m].abyOUI;
             j = 0;
-            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d, sizeof(pBSSList->abyAuthType): %ld\n",
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d, sizeof(pBSSList->abyAuthType): %zu\n",
                           pIE_RSN_Auth->wAuthCount, sizeof(pBSSList->abyAuthType));
             for(i = 0; (i < pIE_RSN_Auth->wAuthCount) && (j < sizeof(pBSSList->abyAuthType)/sizeof(BYTE)); i++) {
                 if(pRSN->len >= 14+4+(m+i)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*i)
diff --git a/drivers/staging/wavelan/wavelan_cs.c b/drivers/staging/wavelan/wavelan_cs.c
index 33918fd..10c702b 100644
--- a/drivers/staging/wavelan/wavelan_cs.c
+++ b/drivers/staging/wavelan/wavelan_cs.c
@@ -3987,7 +3987,7 @@
 #endif
 
   /* Prevent reentrancy. We need to do that because we may have
-   * multiple interrupt handler running concurently.
+   * multiple interrupt handler running concurrently.
    * It is safe because interrupts are disabled before aquiring
    * the spinlock. */
   spin_lock(&lp->spinlock);
diff --git a/drivers/staging/wlags49_h2/Kconfig b/drivers/staging/wlags49_h2/Kconfig
new file mode 100644
index 0000000..92053fe
--- /dev/null
+++ b/drivers/staging/wlags49_h2/Kconfig
@@ -0,0 +1,9 @@
+config WLAGS49_H2
+	tristate "Agere Systems HERMES II Wireless PC Card Model 0110"
+	depends on WLAN_80211 && WIRELESS_EXT && PCMCIA
+	select WEXT_SPY
+	---help---
+	  Driver for wireless cards using Agere's HERMES II chipset
+	  which are identified with Manufacture ID: 0156,0003
+	  The software is a modified version of wl_lkm_722_abg.tar.gz
+	  from the Agere Systems website, addapted for Ubuntu 9.04.
diff --git a/drivers/staging/wlags49_h2/Makefile b/drivers/staging/wlags49_h2/Makefile
new file mode 100644
index 0000000..25d0a8a
--- /dev/null
+++ b/drivers/staging/wlags49_h2/Makefile
@@ -0,0 +1,81 @@
+#
+# Makefile for wlags49_h2_cs.ko and wlags49_h25_cs.ko
+#
+# Default build for Hermes-II base cards (possibly identified with
+# "manfid: 0x0156, 0x0003" in "pccardctl ident" output), comment
+# -DHERMES25 below
+#
+# If you want to build for Hermes-II.5 base cards (possibly identified with
+# "manfid: 0x0156, 0x0004" in "pccardctl ident" output), uncomment
+# -DHERMES25 below
+#
+#  If you want to build AP support (untested), comment out -DSTA_ONLY
+
+INSTALLDIR := /lib/modules/$(shell uname -r)/kernel/drivers/net/wireless
+EXTRA_CFLAGS += -I$(KERNELDIR)/include
+EXTRA_CFLAGS += -I$(src) \
+		-DBUS_PCMCIA \
+		-DUSE_WPA \
+		-DUSE_WEXT \
+		-DSTA_ONLY \
+		-DWVLAN_49 \
+#		-DHERMES25 \
+#		-DDBG \
+#		-DDBG_LVL=5 \
+#		-DUSE_UIL \
+#		-DUSE_PROFILE \
+
+ifeq ($(findstring HERMES25,$(EXTRA_CFLAGS)),)
+WLNAME := wlags49_h2_cs
+$(WLNAME)-y := sta_h2.o
+ifeq ($(findstring STA_ONLY,$(EXTRA_CFLAGS)),)
+$(WLNAME)-y += ap_h2.o
+endif
+else
+WLNAME=wlags49_h25_cs
+$(WLNAME)-y := sta_h25.o
+ifeq ($(findstring STA_ONLY,$(EXTRA_CFLAGS)),)
+$(WLNAME)-y += ap_h25.o
+endif
+endif
+
+# If KERNELRELEASE is defined, we've been invoked from the
+# kernel build system and can use its language.
+ifneq ($(KERNELRELEASE),)
+
+obj-m		+= $(WLNAME).o
+
+$(WLNAME)-y +=	wl_profile.o \
+		wl_wext.o \
+		wl_priv.o \
+		wl_main.o \
+		wl_enc.o \
+		wl_util.o \
+		wl_netdev.o \
+		wl_cs.o \
+		mmd.o \
+		hcf.o \
+		dhf.o
+
+$(WLNAME)-$(CONFIG_SYSFS)	+= wl_sysfs.o
+
+# Otherwise we were called directly from the command
+# line; invoke the kernel build system.
+else
+	KERNELDIR ?= /lib/modules/$(shell uname -r)/build
+	PWD := $(shell pwd)
+
+default:
+	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
+endif
+
+clean:
+	rm -fr *.o *.ko *.mod.c *.mod.o .*.*.cmd Module.symvers \
+		Module.markers modules.order .tmp_versions
+
+install: default
+	-rmmod $(WLNAME)
+	install -d $(INSTALLDIR)
+	install -m 0644 -o root -g root $(WLNAME).ko $(INSTALLDIR)
+	/sbin/depmod -aq
+
diff --git a/drivers/staging/wlags49_h2/README.ubuntu b/drivers/staging/wlags49_h2/README.ubuntu
new file mode 100644
index 0000000..47beaec
--- /dev/null
+++ b/drivers/staging/wlags49_h2/README.ubuntu
@@ -0,0 +1,180 @@
+=======================================================================
+WLAN driver for cards using the HERMES II and HERMES II.5 chipset
+
+HERMES II Card
+
+PCMCIA Info: "Agere Systems" "Wireless PC Card Model 0110"
+             Manufacture ID: 0156,0003
+
+HERMES II.5 Card
+
+PCMCIA Info: "Linksys" "WCF54G_Wireless-G_CompactFlash_Card"
+             Manufacture ID: 0156,0004
+
+Based on Agere Systems Linux LKM Wireless Driver Source Code,
+Version 7.22; complies with Open Source BSD License.
+=======================================================================
+
+DESCRIPTION
+
+The software is a modified version of wl_lkm_722_abg.tar.gz from the
+Agere Systems website, addapted for Ubuntu 9.04.
+
+Modified for kernel 2.6 by Henk de Groot <pe1dnn@amsat.org>
+Based on 7.18 version by Andrey Borzenkov <arvidjaar@mail.ru> $Revision: 39 $
+
+INSTALLATION
+
+Unpack in a new directory.
+
+Open a terminal screen.
+
+Change directory to the source directory
+
+Type command
+
+make
+
+and wait until it is finshed. Now you have build the module
+wlags49_h2_cs; this module is meant for a HERMES II card.
+
+The driver is tested with a Thomson SpeedTouch 110 Wireless PC Card.
+For the test Station mode was used with WEP. The driver is supposed
+to support WAP and as accesspoint that is NOT tested.
+
+If you have a card using the HERMES II.5 chip you have to make
+changes to the Makefile and uncomment -DHERMES25. This will build
+driver wlags49_h25_cs.
+
+Note: You can detemine the type with command "pccardctrl info"
+        MANIFID: 0156,0002 = HERMES - not supported by this driver
+        MANIFID: 0156,0003 = HERMES II   (Wireless B)
+        MANIFID: 0156,0004 = HERMES II.5 (Wireless B/G)
+
+After succesfull compile type command
+
+sudo make install
+
+to install the module.
+
+Now the card should be recognized. It should be able to configure
+and use the card with NetworkManager. Wpa_supplicant also works, as does
+manual configuration using the iwconfig/iwlist programs.
+
+Note: I only tested Station mode with WEP but if I didn't break anything
+WPA and AP mode should also work; note however that WPA was experimental
+in the original Agere driver!
+
+Note: to compile as AP change the makefile and remove the line
+-DSTA_ONLY \
+
+(or comment it, but in that case make sure to move it after all the
+ flags you want to use)
+
+CHANGES
+
+The HCF functions to control the card are virtually unchanged, the only
+changes are meant to fix compiler warnings. The only real change is in
+HCF_WAIT_WHILE which now has a udelay(2) added to give a small delay.
+
+The linux driver files (wl_xxxx.c) are changed in the following ways:
+- Addaptations of Andrey Borzenkov applied to 7.22 source
+- Alterations to avoid most HCF_ASSERTs
+-- Switching interrupts off and on in the HCF
+-- Bugfixes, things that were aparently wrong like reporting link status
+   change which checked a variable that was not changed in HCF anymore.
+-- Used on WEP but setting keys via SIOCSIWENCODEEXT was not supported
+-- Recovery actions added
+
+The major problem was the order in which calls can be made. The original
+looks like a traditonal UNIX driver. To call an "ioctl" function you
+have to "open" the device first to get a handle and after "close" no
+"ioctl" function can be called anymore. With the 2.6 driver this all
+changed; the former ioctl functions are now called before "open" and
+after "close", which was not expected. One of the problems was enable/
+disable of interrupts in the HCF. Interrupt handling starts at "open"
+so if a former "ioctl" routinge is called before "open" or after "close"
+then nothing should be done with interrupt switching in the HCF. Once
+this was solved most HCF_ASSERTS went away.
+
+The last point, recovery actions added, needs some clarification.
+Starting the card works most of the time, but unfortunately not always.
+At a few times recovery code was added; when the card starts to
+misbehave or the communication between the HCF and the card is
+out of sync and the HCF enters DEFUNCT mode everything is reset and
+reinitialized. Note, hcf.c contains a lot of documentation. It takes
+some time but slowly some things become clear. Also some unresolved
+issues are mentioned in hcf.c, so there are still unknown bugs.
+
+The card problems are almost in all cases when starting up and before
+the first association with an AP, once the card is in operation it
+seems to stay that way; when debugging no HCF_ASSERTS appear anymore.
+Note: some HCF_ASSERTS still appear, in a number of cases it is a real
+error, for example at card removal the missing card is detected.
+
+LICENSE
+
+The Agere Systems license applies. This is why I include the original
+README.wlags49. The instructions in that file are bogus now. I also
+include the man page. Eventhough setting parameters on the module
+does not work anymore but it provides some information about all the
+settings.
+
+I have not have personal contact with Agere, but others have. Agere
+agreed to make their software available under the BSD licence.
+This driver is based on the 7.22 version.
+
+The following was mailed by Agere to Andrey Borzenkov about this:
+
+    --- Begin Message ---
+
+        * From: TJ <tj@xxxxxxxxxxx>
+        * Date: Mon, 05 Feb 2007 19:28:59 +0000
+
+    Hi Andrey,
+
+    I've got some good news for you/us/the world of Hermes :)
+
+    I got a reply from the legal representative at Agere confirming that
+    their source-code is BSD licensed, and I've included the contents of the
+    email here.
+
+    I hope this re-assures you so that your excellent work on the drivers
+    can be made widely available for other hackers to work with.
+
+    Regards,
+
+    TJ.
+
+    ---------
+    On Mon, 2007-02-05 at 13:54 -0500, Pathare, Viren M (Viren) wrote:
+
+
+    "I would like to confirm that the two drivers; Linux LKM Wireless Driver
+    Source Code, Version 7.18 and Linux LKM Wireless Driver Source Code,
+    Version 7.22 comply with Open Source BSD License. Therefore the source
+    code can be distributed in unmodified or modified form consistent with
+    the terms of the license.
+
+    The Linux driver architecture was based on two modules, the MSF (Module
+    specific functions) and the HCF (Hardware Control Functions). Included
+    in the HCF is run-time firmware (binary format) which is downloaded into
+    the RAM of the Hermes 1/2/2.5 WMAC.
+
+    This hex coded firmware is not based on any open source software and
+    hence it is not subject to any Open Source License. The firmware was
+    developed by Agere and runs on the DISC processor embedded within the
+    Hermes 1/2/2.5 Wireless MAC devices.
+
+    Hope this helps.
+
+    Sincerely,
+
+    Viren Pathare
+    Intellectual Property Licensing Manager
+    Agere"
+
+
+
+    --- End Message ---
+
diff --git a/drivers/staging/wlags49_h2/README.wlags49 b/drivers/staging/wlags49_h2/README.wlags49
new file mode 100644
index 0000000..7586fd0
--- /dev/null
+++ b/drivers/staging/wlags49_h2/README.wlags49
@@ -0,0 +1,641 @@
+==============================================================================
+Agere Systems Inc.                                                   July 2004
+Readme for Linux Driver Source for Wavelan                   Version: 7.22-abg
+==============================================================================
+
+This text file includes update information, installation instructions,
+limitations to the current version of the product, and suggestions to solve
+known issues or problems.
+
+
+TABLE OF CONTENTS.
+
+1.  DESCRIPTION
+2.  SYSTEM REQUIREMENTS
+3.  NEW IN THIS RELEASE
+4.  INSTALLATION NOTES
+5.  TECHNICAL CONSTRAINTS
+6.  KNOWN ISSUES
+7.  TECHNICAL SUPPORT
+
+------------------------------------------------------------------------------
+1.  DESCRIPTION
+
+    With this package, you can build and install a Wireless driver for a
+    specific Linux kernel.
+
+    The driver in this package supports the network interface cards based on:
+     - WL60010, a.k.a. Hermes-II
+     - WL60040, a.k.a. Hermes-II.5
+
+    Although derived from the Hermes-I/II Linux driver, this release ONLY
+    Supports Hermes-II/II.5 chipsets.  Hermes-I is no longer supported.
+
+    The software is distributed in a compressed source file archive:
+     - wl_lkm_7_22_abg.tar.gz
+
+    Because this release supports more than one Hermes CPU and bus
+    architecture, a naming convention is used for the resulting binaries that
+    can be built from this source code. Driver binaries are named as follows:
+
+    wlags49_<hermes_type>_<bus_arch>.o
+
+    where 'wlags49' denotes an Agere WaveLan Linux build,
+
+    <hermes_type> is: 'h2' for Hermes-II, 'h25' for Hermes-II.5
+
+    <bus_arch> is: 'cs' for Card Services (PCMCIA, Compact Flash), PCI for
+    PCI or MiniPCI.
+
+    For example, a driver built for Hermes-II Card Services (PCMCIA/Compact
+    Flash) is named wlags49_h2_cs.o, whereas a driver built for Hermes-II
+    MiniPCI is named wlags49_h2_pci.o.
+    The following software is included with this distribution:
+
+    General information:
+    * README.wlags49              This file
+    * LICENSE.wlags49             License
+    * wlags49.mk                  Top level Makefile
+    * Build                       Script to build driver
+    * Install                     Script to install driver
+
+    Driver source:
+    * wireless/                   MSF source
+    * hcf/                        HCF and F/W source
+    * wireless/wlags49_cs.mk      Driver Makefile, PC Card
+    * wireless/wlags49_pci.mk     Driver Makefile, PCI
+    * include/hcf/debug.h         Driver debug support
+    * include/hcf/hcfcfg.h        Header to configure HCF
+    * include/wireless/*.h        Driver source headers
+
+    Driver online manual page:
+    * man/wlags49.4               Driver manual page
+
+    PCMCIA configuration update:
+    * etc/wlags49.conf            Add-on config file
+    * etc/wlags49.mk              config update Makefile
+    * etc/wlags49.patch           config update patch file
+
+    The driver is build up of 2 modules:
+     - a higher module called Module Specific Functions (MSF), which contains
+       the functions of the driver that are network driver interface and
+       Operating System specific.
+     - a lower module called Hardware Control Functions (HCF), which contains
+       the functions to interface to the Network Interface Card (NIC).  The HCF
+       provides for all WaveLAN NIC types one standard interface to the MSF.
+       This I/F is called the Wireless Connection Interface (WCI) and is the
+       subject of a seperate document (025726).
+
+    The HCF directory contains firmware images to allow the card to operate in
+    either station (STA) or Access Point (AP) mode. In the build process, the
+    files fw_h2.c and fw_h25.c are used for Hermes-II and Hermes-II.5
+    respectively. The firmware images in this release are identified as:
+	 - HII Station F/W:      fw_h2.c.sta
+	 - HII.5 Station F/W:    fw_h25.c.sta
+	 - HII AccesPoint F/W:   fw_h2.c.ap
+	 - HII.5 AccesPoint F/W: fw_h25.c.ap
+	To build a STA or AP mode driver, the suffix .sta or .ap must be removed.
+	The files as distributed by this release build STA drivers by default.
+
+------------------------------------------------------------------------------
+2.  SYSTEM REQUIREMENTS
+
+2.1 Operating System
+
+    This software can be compiled and installed with Linux kernel versions
+    2.4.x. Although this driver should compile for other CPUs as well, as of
+    the date of this release, no CPU architectures other than x86 have been
+    verified.
+
+    wl_lkm_7_22_abg is tested with the following Linux Distributions:
+    * Red Hat version 9.0
+    * Suse    version 9.0
+
+    If you're building for PC Card or Compact Flash, you need the Card Services
+    from David Hinds.
+
+    wl_lkm_7_22_abg is tested with:
+    * pcmcia-cs-3.2.7.tar.gz
+
+2.2 Free Disk Space
+
+    To compile the software you need to have the full set of Linux kernel
+    source files installed, as well as a sane build environment which includes
+    all tools necessary for compiling and linking code. Depending on the exact
+    version of the kernel, you need approximately 150 MB of free disk space.
+    Once compiled, the driver uses about 150-200 KB.  Please note, this size is
+    approximate and can vary depending on which version of the driver is built.
+    In addition, adding debug tracing support increases this size.
+
+------------------------------------------------------------------------------
+3.  NEW IN THIS RELEASE
+
+Version 7.22 abg - July 28, 2004
+
+------------------------------------------------------------------------------
+4.  INSTALLATION NOTES
+
+    The driver files for the Linux driver are not "ready" for direct
+    installation onto any Linux computer.  To build and install the driver you
+    need some expertise on the Linux operating system in general and the type
+    and version installed of the kernel installed on your computer.  With this
+    knowledge you can use the driver source files provided to build your own
+    Linux driver for your specific computer and kernel.
+
+4.1 Before you start
+
+    1) Determine the type and version of the Linux kernel of your computer and
+    check whether it meets the system requirements listed in section 2 of this
+    README.
+
+    2) If you're building for PC Card or Compact Flash, read the Linux
+    PCMCIA-HOWTO by David Hinds. This document is probably provided on the
+    CD-ROM of your Linux distribution. You can download the latest version
+    from:
+
+        http://pcmcia-cs.sourceforge.net
+
+   Please read the section titled "Prerequisites and kernel setup" of the
+   PCMCIA-HOWTO.
+
+4.2 Build the driver for PC Card / Compact Flash
+
+    1) Obtain a copy of the Linux PCMCIA package from a CD-ROM of your Linux
+    distribution or download the latest version.
+    For your convenience, the Agere Systems Wireless CD-ROM contains a copy of
+    the PCMCIA package in sub-directory: Xtras/Linux/PCMCIA
+
+    2) To unpack the Linux PCMCIA package, copy it to the current working
+    directory and type:
+       % tar xzvf pcmcia-cs-x.y.z.tar.gz
+       % mv pcmcia-cs-x.y.z pcmcia-cs
+
+    Note: If you use the archive supplied on the CDROM, use archive name
+    "pc3_2_1.tgz" instead of "pcmcia-cs-3.2.7.tar.gz".
+
+    Note: even though PCMCIA code exists in the kernel source tree, the PCMCIA
+    Card Services package needs to be unpacked locally to build drivers based
+    on it.
+
+    3) Extract the wlags49 distribution archive on top of the Linux PCMCIA
+    package.
+       % cd pcmcia-cs
+       % tar xzvf ../wl_lkm_7_22_abg.tar.gz
+
+    4) To build and install the driver, follow the procedure below:
+       % ./Configure
+
+    Answer the presented questions. Usually the default answers are OK and
+    pressing "Enter" is enough.
+    On newer RedHat systems, however, you should specify "/usr/src/linux-2.4"
+    as the Linux source directory instead of the default "/usr/src/linux".
+
+    For more detailed information on configuration, building and installing,
+    see the PCMCIA-HOWTO.
+
+    To build the default drivers, which support Hermes-II in station mode, run
+    the Build script:
+       % ./Build
+
+    This script determines whether your system uses in-kernel PCMCIA and either
+    builds the full PCMCIA package or just the driver.
+
+    Before installing the driver with the Install script, you must become
+    'root':
+       % su
+       ..
+       % ./Install
+
+    This script determines whether your system uses in-kernel PCMCIA and either
+    installs the full PCMCIA package or just the driver.
+
+    5) If it becomes necessary to clean the build, issue the following
+    commands:
+       % make clean
+       % make -C lib clean
+
+4.3 Build the driver for PCI
+
+    1) Extract the wlags49 to the current working directory.
+       % tar xzvf wl_lkm_7_22.tar.gz
+
+    Note: there is no need to unpack the driver source into a PCMCIA build
+    directory.
+
+    2) To build the PCI driver:
+       % make -f wlags49.mk wlags49_h2_pci
+       or
+       % make -f wlags49.mk wlags49_h25_pci
+
+    3) Install the driver.
+       % insmod ./wireless/wlags49_h25.o
+
+    4) If it becomes necessary to clean the build.
+       % make -f wlags49.mk pci_clean
+
+4.4 Configure your Wireless PC Card
+
+    There are 3 ways to configure the driver
+    - module parameters (/etc/pcmcia/config.opts)
+    - wireless extension (/etc/pcmcia/wireless.opts)
+    - Agere configuration file (/etc/agere/iwconfig-eth#)
+
+
+4.4.1 Configure through /etc/pcmcia/config.opts
+
+    To use this method, make sure that /etc/pcmcia/wireless.opts file is either
+    absent or contains blank parameter values as shown below.
+
+    *,*,*,00:60:1D:*|*,*,*,00:02:2D:*)
+        INFO=""
+        ESSID=""
+        MODE=""
+        KEY=""
+    ;;
+
+    1) To configure the Wireless PC Card, please refer to:
+       * The online manual page (wlags49.4)
+         % man wlags49
+       * The network adapter sections of the PCMCIA documentation.
+         % more PCMCIA-HOWTO
+
+    2) Use an editor to configure the module parameters:
+       # vi /etc/pcmcia/config.opts
+
+       a) To connect your computer to a wireless infrastructure that includes
+       access points such as the AP-1000 or AP-500, you need to identify the
+       network name of the wireless infrastructure.
+
+       For example if your infrastructure uses the network name "My Network",
+       edit the config.opts file to include the following:
+
+       module "<driver_name>" opts "network_name=My\ Network"
+
+       Notice that the space character needs to be escaped with a backslash.
+
+       b) To connect your computer to a Residential Gateway RG-1000, you need
+       to know the RG ID (=network_name) and the encryption key.  You can find
+       the RG ID on a small label on the rear of the unit.
+
+       For example if your RG-1000 has ID 225ccf and you did not change the
+       encryption key yet, edit the config.opts file to include the following:
+
+       module "<driver_name>" opts "network_name=\"225ccf\" key_1=\"25ccf\"
+       enable_encryption=Y"
+
+       If you changed your encryption key, you should specify this key as key_1
+       on the parameter line.
+
+       c) To connect your computer to a peer-to-peer network, in an environment
+       without access points, the IBSS mode is recommended.
+
+       For example to connect to a peer-to-peer network called "My Network",
+       enter the following in the config.opts file:
+
+       module "<driver_name>" opts "create_ibss=Y network_name=My\ Network"
+
+       d) Optionally you can also include a "Station Name" value that can be
+       used to indentify your computer on the wireless network.
+
+       For example if you wish to name your computer "Wave1" when connecting it
+       to a wireless infrastructure,  edit the config.opts file to include the
+       following:
+
+       module "<driver_name>" opts "network_name=Ocean station_name=Wave1"
+
+       e) To connect your computer to an Ad-Hoc workgroup of wireless
+       computers, enter the following in the config.opts file:
+
+       module "<driver_name>" opts "port_type=3"
+
+       Note that the "Ad-Hoc Demo Mode" is not the recommended mode for a
+       peer-to-peer network.  The configuration of this  non-interoperable mode
+       is only explained here for special applications (e.g. research, or
+       compatibility with other / previous WaveLAN/IEEE products).
+
+       The IBSS mode described in c) is the preferred and interoperable mode
+       for creating a peer-to-peer network.
+
+    3) Use an editor to modify the network options for your adapter.
+       # vi /etc/pcmcia/network.opts
+
+       The parameters need to be correct for the connected network. Check with
+       your system administrator for the correct network information.  Refer to
+       the PCMCIA-HOWTO for more configuration information.
+
+       For example:
+            *,*,*,*)
+                IF_PORT=""
+                BOOTP="n"
+                IPADDR="10.0.0.5"
+                NETMASK="255.255.255.0"
+                NETWORK="10.0.0.0"
+                BROADCAST="10.0.0.255"
+                GATEWAY="10.0.0.1"
+                DOMAIN="domain.org"
+                DNS_1="dns1.domain.org"
+                ;;
+
+       RedHat and Suse do not use the network.opts to configure the driver.
+       Instead RedHat uses a GUI-based tool called 'neat' ('net.cfg' in older
+       versions) and SuSE Linux uses 'YaST'. These tools creates scripts, like
+       ifcfg-eth0, in the directory /etc/sysconfig/network-scripts. Using the
+       default GNOME menu, you can start netcfg from: Programs->System->Network
+       Configuration.
+
+    4) Restart the PCMCIA services.
+       # /etc/rc.d/rc.pcmcia restart
+         or
+       # /etc/rc.d/init.d/pcmcia restart
+
+
+    For a more detailed description about the various configuration options and
+    definitions, please consult the Wireless documentation.
+
+4.4.2 Configure through /etc/pcmcia/wireless.opts
+
+    This driver has support for the "Wireless Extensions".  This interface
+    allows the "Wireless Tools" to get statistics from the driver and allows to
+    change the configuration of the driver on the fly.
+
+    The latest versions of the PCMCIA package contain scripts that use the
+    wireless extension to configure the driver as an alternative to the
+    configuration through module parameters as described in section 4.4.1.
+    Read the /etc/pcmcia/wireless.opts file for the theory of operation.  When
+    the driver is configured, go to section 4.4.1 step 3 to configure the
+    network parameters.
+
+    For more information, refer to the following WEB pages:
+    http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Linux.Wireless.Extensions.html
+    http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html
+
+4.4.3 Configure through /etc/agere/iwconfig-eth#
+
+    In addition to using either the module options or the wireless extensions
+    methods to configure a wireless device, this version of the software also
+    supports an Agere specific implementation. This was done because:
+    * Module options configures multiple devices the same.
+    * Wireless extensions parameters do not cover all of the available options
+      in the driver.
+
+    For each wireless ethernet device (identified by eth<n>, where n is a
+    positive integer), a file /etc/agere/iwconfig-eth<n> can be created which
+    contains configuration information for a wireless device. For example, the
+    file /etc/agere/iwconfig-eth1 is the config file for eth1. This file should
+    contain Key/Value pairs in the format:
+
+    <Key>=<Value>
+
+    where <Key> is the parameter to configure and <Value> is the value to
+    assign it. For example, if the config file /etc/agere/iwconfig-eth1
+    described above contains the following:
+
+    DesiredSSID=some_network
+    EnableEncryption=Y
+    Key1=net01
+    TxKey=1
+
+    this configures eth1 to associate to the ESSID 'some_network' with
+    encryption on, where the the first encryption key is 'net01' and the key to
+    use for encryption is Key 1.
+
+    Note that this only works on Agere hardware which uses this driver. For
+    other wireless drivers, or non-wireless devices, this file can be present,
+    but has no effect.
+
+    Please refer to the man page for more information on this configuration
+    file and the parameters that can be set.
+
+
+4.5 Configuring your Wireless PCI card
+
+    Note that the above method of configuring the card using
+    /etc/pcmcia/config.opts is only valid for PCMCIA/CF cards. For [mini]PCI
+    and CardBus cards, refer to your system's documentation on modules.conf to
+    load the driver with the proper options for a given wireless ethernet
+    interface. In addition, network configuration tools like 'netcfg', 'neat',
+    or 'YaST' (see Section 4.4.1, Step 3) can be used to configure the miniPCI
+    card. Lastly, the Agere configuration file described in Section 4.4.3 may
+    also be used for [mini]PCI and CardBus devices.
+
+4.6 Troubleshooting
+
+    When the Wireless PC Card is inserted, the card manager emit beeps in
+    different tones to indicate success or failure of particular configuration
+    steps.
+      a) Two high beeps
+         - The card was identified and configured successfully.
+      b) One high beep followed by a low beep
+         - The card was identified, but could not be configured.
+         - Examine the system log (dmesg) for PCMCIA error or warning messages.
+      c) One low beep
+         - The card could not be identified.
+         - Execute "cardctl ident" to display the adapter PnP information.
+           Verify the PnP information matches an entry in the PCMCIA
+           configuration file (/etc/pcmcia/config).
+         - Examine the system log (dmesg) for PCMCIA error or warning messages.
+
+    The Wireless PC Card has two LEDs that indicate the state of the adapter
+    and network.
+      * Power LED (toward the middle of the adapter)
+    	- This LED indicates power has been applied, and the card is
+    	  functional. In normal operation mode with Card Power Management
+    	  disabled, it is steady-on. With Card Power Management enabled, it
+    	  blinks rapidly (several times per second).
+      * Transmit/Receive LED (closer to the edge of the adapter)
+        - This LED flashes when it detects transmit or receive packets.
+
+      * Both LEDs blink at the same time every 10 seconds.
+    	- The adapter was unable to make contact with the named wireless
+    	  network. Verify the network_name, in the config.opts file matches the
+    	  network name of the access point.
+      * LEDs indicate normal operation with the Power LED
+    	steady-on or blinking rapidly and Transmit/Receive LED flashing, but no
+    	traffic.
+    	- If the network is operating in normal mode (ie.  port_type = 0 or not
+    	  specified), and a network_name has been specified, verify the
+    	  workstation network parameters (ifconfig, route, etc.) are correct
+    	  for the wireless network.
+    	- If the network is operating in Ad-Hoc (peer-to-peer) mode (ie.
+    	  port_type = 3), the adapter needs another workstation/adapter to
+    	  communicate with.  Verify the network parameters on both of the
+    	  workstations (ifconfig, route, etc.) are correct.
+
+    Refer to the online manual page for additional configuration, feature and
+    support information.
+       % man wlags49
+         or
+       % man 4 wlags49
+         or
+       % nroff -man wlags49.4 | more
+
+4.7 Identifying the software
+
+    This section explains how to identify the version of this software once it
+    is unpacked or installed.
+
+    The Linux Driver Source/Library distribution consist of two main
+    components, the driver source and the HCF module.
+
+    * To quickly identify the version of the source, type:
+      % grep DRV.*VERSION include/wireless/wl_version.h
+      #define DRV_MAJOR_VERSION   7
+      #define DRV_MINOR_VERSION   22
+
+    * To identify the revision of the HCF library contained in the driver,
+      type:
+      % grep HCF.Revision hcf/hcf.c
+      #define HCF_VERSION  TEXT( "HCF$Revision: 1.8 $" )
+
+    To identify a compiled wlags49 driver, go to the directory where the driver
+    is located. Card Services drivers (wlags49_h2_cs.o and wlags49_h25_cs.o)
+    are located in:
+    /lib/modules/<kernel-version>/pcmcia
+
+    PCI drivers (wlags49_h2.o) are located in:
+    /lib/modules/<kernel-version>/kernel/drivers/net
+
+    * To retrieve the version of the source used to compile the driver, type:
+      % strings <driver_name>.o | grep Agere
+      <driver_name> v7.22-abg-Beta for PCMCIA
+      <driver_name> v7.22-abg-Beta for PCI
+
+    * Likewise, to retrieve the revision of the HCF used to compile the driver,
+      type:
+      % strings <driver_name>.o | grep Revision
+      HCF$Revision: 5.15
+
+    At startup the wlags49 driver reports its version in the system log file
+    (/var/log/messages).
+
+------------------------------------------------------------------------------
+5.  TECHNICAL CONSTRAINTS
+
+    At the time of release of this software, the following constraints are
+    identified:
+
+5.1 Using the ISA adapter
+
+    Description: To allow operation in desktop computers Agere also provides an
+    optional ISA bus to PC Card adapter (also referred to as "swapbox").
+
+    This ISA Adapter can be configured for two different I/O Address values:
+      * 3E2 (factory-set default)
+      * 3E0
+
+    Impact: By default the i82365 module of the Linux pcmcia package only
+    probes at 3E0.
+
+    Actions:
+    1) Read the manual page on the probing of the i82365 module, by typing the
+    command:
+        man i82365
+
+    2) Apply one of the two following options:
+       a) Change the I/O address strapping of the ISA adapter by replacing the
+          jumper on the ISA adapter.  The correct jumper setting is pictured in
+          the electronic "Wireless ISA Adapter, Getting Started Guide" provided
+          on the Wireless Software CD-ROM. This guide is provided in Adobe's
+          Acrobat PDF format.
+
+       b) Alternatively, you can load the i82365 module with the
+          "extra_sockets" parameter set to 1.
+
+          On a RedHat 5.x thru 7.x, system, put this in the file
+          "/etc/sysconfig/pcmcia":
+             PCMCIA=yes
+             PCIC=i82365
+             PCIC_OPTS="extra_sockets=1"
+             CORE_OPTS=
+             CARDMGR_OPTS=
+
+          For other Linux distributions, you are advised to consult the
+          "PCMCIA-HOWTO" notes for information about changing the I/O Address
+          probing.
+
+5.2 Using the PCI Adapter
+
+    Description: To allow operation in desktop computers Agere also provides an
+    optional PCI bus to PC Card adapter (also referred to as "swapbox").
+
+    For correct interrupt assignment, the system should support PCIBIOS 2.2.
+    It is recommended to use PCMCIA package version 3.2.7 or higher.
+
+    The default configuration of the interrupt routing method of the PCI
+    Adapter's TI CardBus Controller is incorrect.
+
+    Actions:
+    1) Read the manual page on the "Options specific for TI CardBus
+    Controllers" of the i82365 module, by typing the command:
+        man i82365
+
+    2) Load the i82365 module with the "irq_mode" parameter set to 0.
+       On a RedHat 5.x thru 7.x system, put this in the file
+       "/etc/sysconfig/pcmcia":
+           PCMCIA=yes
+           PCIC=i82365
+           PCIC_OPTS="irq_mode=0"
+           CORE_OPTS=
+           CARDMGR_OPTS=
+
+   For the location of the PCMCIA scripts on other Linux distributions, you
+   are advised to consult the "PCMCIA-HOWTO", "Notes about specific Linux
+   distributions".
+
+------------------------------------------------------------------------------
+6.  KNOWN ISSUES
+
+    This is the current list of known issues for this release, and will be
+    addressed in the near future:
+
+    1. This driver release contains a version of Hermes-II.5 firmware which
+    REQUIRES calibrated cards. If there is no calibration data present in the
+    PDA of the hardware, the firmware does not operate.
+
+    2. WDS is not yet supported.
+
+    3. DMA is not yet supported.
+
+    4. WPA is not yet supported.
+
+    5. 32-bits I/O is not yet supported.
+
+    6. The current Build script also builds the PCI drivers.
+
+    7. The current Install script also copies the PCI drivers to the lib
+    directory.
+
+	8. If F/W files are required from outside this release, the entry points
+	inside these F/W files have to be renamed from "ap" and "station" to
+	"fw_image" and they have to be renamed to fw_h2.c and fw_h25.c for
+	Hermes-II and Hermes-II.5.
+
+------------------------------------------------------------------------------
+7.  TECHNICAL SUPPORT
+
+7.1 Finding Information
+
+    On the Agere Systems Web Site you can find the most recent device drivers,
+    software updates and user documentation.
+
+    World Wide Web:    http://www.agere.com
+
+7.2 Contact Technical Support
+
+    If you encounter problems when installing or using this product, or would
+    like information about our other "Wireless" products, please contact your
+    local Authorized "Wireless" Reseller or Agere Systems sales office.
+
+    Addresses and telephone numbers of the Agere Systems sales offices are
+    listed on our Agere Systems web site.
+
+    When contacting Technical Support, please use the Problem Report Form and
+    send it to us by Fax or E-Mail.  The Problem Report Form 'REPORT.TXT'
+    (Plain text format) is included on the disk. Alternatively, you can
+    download the Problem Report Form from the Agere Systems web site.
+
+    Include Product Name, Serial Number and software version number with each
+    request to help the Support Group helping you.
+
+==============================================================================
+                          END OF FILE
diff --git a/drivers/staging/wlags49_h2/TODO b/drivers/staging/wlags49_h2/TODO
new file mode 100644
index 0000000..14aa415
--- /dev/null
+++ b/drivers/staging/wlags49_h2/TODO
@@ -0,0 +1,33 @@
+First of all, the best thing would be that this driver becomes obsolte by
+adding support for Hermes II and Hermes II.5 cards to the existing orinoco
+driver. The orinoco driver currently only supports Hermes I based cards.
+Since this will not happen by magic and has not happend until now this
+driver provides a stop-gap solution for these type of cards.
+
+Having said that, the following wishlist comes to mind to make the driver
+suitable as fully supported kernel driver. Feel free to expand/enhance the
+list.
+
+TODO:
+	- verify against a Hermes II.5 card
+	- verify with WPA encription (both with H2 and H2.5 cards)
+	- sometimes the card does not initialize correctly, retry mechanisms
+	  are build in to catch most cases but not all
+	- once the driver runs it is very stable, but I have the impression
+	  some the crittical sections take to long
+	- the driver is split into a Hermes II and a Hermes II.5 part, it
+	  would be nice to handle both with one module instead of two
+	- review by the wireless developer community
+	- verify the code against the coding standards for a propper linux
+	  driver
+	- resolve license issues (?)
+
+DONE:
+	- verified against a Hermes II card (Thomson Speedtouch 110 PCMCIA
+	  card)
+	- verified with WEP encription
+
+Please send any patches or complaints about this driver to Greg
+Kroah-Hartman <greg@kroah.com> and Cc: Henk de Groot <pe1dnn@amsat.org>
+Don't bother the upstream wireless kernel developers about it, they
+want nothing to do with it.
diff --git a/drivers/staging/wlags49_h2/WARNING.txt b/drivers/staging/wlags49_h2/WARNING.txt
new file mode 100644
index 0000000..5d12973
--- /dev/null
+++ b/drivers/staging/wlags49_h2/WARNING.txt
@@ -0,0 +1,3 @@
+These sources are shared with the wlags49_h25 driver. Some files are even
+exclusively used by that driver. Do not delete them here without looking
+at that other driver.
diff --git a/drivers/staging/wlags49_h2/ap_h2.c b/drivers/staging/wlags49_h2/ap_h2.c
new file mode 100644
index 0000000..f5123d2
--- /dev/null
+++ b/drivers/staging/wlags49_h2/ap_h2.c
@@ -0,0 +1,3337 @@
+/*
+ * File:	ap_h24.236
+ *
+ * Abstract:	This file contains memory image 'fw_image'.
+ *
+ * Contents:	Total size of the memory image: 51010 bytes.
+ *		Total number of blocks: 4 blocks.
+ *		Block  1 : load address 00000060, 326 bytes.
+ *		Block  2 : load address 00000C16, 6424 bytes.
+ *		Block  3 : load address 001E252E, 444 bytes.
+ *		Block  4 : load address 001F4000, 43816 bytes.
+ *
+ * Identity:	component id: 32 (variant 2) version 2.36
+ *
+ * Compatibility:
+ *		supplying interface 8 (variant 2) : 2 - 4
+ *		acting on interface 1 (variant 4) : 6 - 7
+ *		acting on interface 1 (variant 5) : 6 - 7
+ *		acting on interface 1 (variant 6) : 6 - 7
+ *		acting on interface 2 (variant 2) : 1 - 2
+ *
+ * Generated:	by g:\fw\fupu3.exe version 4.26
+ *
+ * Commandline:	g:\fw\fupu3.exe /f=4 /n=fw_image /i=t2023600.hex
+ */
+
+
+#include "hcfcfg.h"				// to get hcf_16 etc defined as well as
+                                // possible settings which inluence mdd.h or dhf.h
+#include "mdd.h"   				//to get COMP_ID_STA etc defined
+#include "dhf.h"   				//used to be "fhfmem.h", to get memblock,plugrecord,
+
+static const hcf_8 fw_image_1_data[] = {
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x0D, 0x00, 0x00,
+	 0x3A, 0x0C, 0x00, 0x00, 0x3A, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00,
+	 0x0A, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0xEA, 0x00, 0x00, 0xFF, 0x07, 0x02, 0x00, 0x64, 0x00, 0x64, 0x00, 0x10, 0x27, 0x10, 0x27,
+	 0x14, 0x00, 0xD0, 0x07, 0xD0, 0x07, 0x10, 0x27, 0x2F, 0x00, 0x32, 0x00, 0x32, 0x00, 0x05, 0x00,
+	 0x02, 0x00, 0x02, 0x00, 0x10, 0x27, 0x05, 0x00, 0x00, 0x02, 0x00, 0x02, 0x13, 0x00, 0x0A, 0x00,
+	 0x07, 0x00, 0x03, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x09, 0x2B, 0x09, 0x2B, 0x09,
+	 0x03, 0x00, 0x00, 0x00, 0x00, 0x6E, 0x00, 0x14, 0x01, 0x00, 0x40, 0x00, 0x32, 0x00, 0x32, 0x00,
+	 0x0A, 0x00, 0x02, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+};  /* fw_image_1_data */
+
+static const hcf_8 fw_image_2_data[] = {
+	 0x9B, 0xA7, 0x00, 0x0A, 0x10, 0x01, 0x68, 0xA4, 0xB0, 0x01, 0x84, 0x01, 0x30, 0x33, 0x31, 0x33,
+	 0x44, 0x44, 0x30, 0x33, 0x31, 0x33, 0x30, 0x33, 0x31, 0x33, 0x32, 0x33, 0x32, 0x33, 0x90, 0x00,
+	 0x78, 0x04, 0xAE, 0xE4, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
+	 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA5, 0xC6, 0x84, 0xF8, 0x99, 0xEE,
+	 0x8D, 0xF6, 0x0D, 0xFF, 0xBD, 0xD6, 0xB1, 0xDE, 0x54, 0x91, 0x50, 0x60, 0x03, 0x02, 0xA9, 0xCE,
+	 0x7D, 0x56, 0x19, 0xE7, 0x62, 0xB5, 0xE6, 0x4D, 0x9A, 0xEC, 0x45, 0x8F, 0x9D, 0x1F, 0x40, 0x89,
+	 0x87, 0xFA, 0x15, 0xEF, 0xEB, 0xB2, 0xC9, 0x8E, 0x0B, 0xFB, 0xEC, 0x41, 0x67, 0xB3, 0xFD, 0x5F,
+	 0xEA, 0x45, 0xBF, 0x23, 0xF7, 0x53, 0x96, 0xE4, 0x5B, 0x9B, 0xC2, 0x75, 0x1C, 0xE1, 0xAE, 0x3D,
+	 0x6A, 0x4C, 0x5A, 0x6C, 0x41, 0x7E, 0x02, 0xF5, 0x4F, 0x83, 0x5C, 0x68, 0xF4, 0x51, 0x34, 0xD1,
+	 0x08, 0xF9, 0x93, 0xE2, 0x73, 0xAB, 0x53, 0x62, 0x3F, 0x2A, 0x0C, 0x08, 0x52, 0x95, 0x65, 0x46,
+	 0x5E, 0x9D, 0x28, 0x30, 0xA1, 0x37, 0x0F, 0x0A, 0xB5, 0x2F, 0x09, 0x0E, 0x36, 0x24, 0x9B, 0x1B,
+	 0x3D, 0xDF, 0x26, 0xCD, 0x69, 0x4E, 0xCD, 0x7F, 0x9F, 0xEA, 0x1B, 0x12, 0x9E, 0x1D, 0x74, 0x58,
+	 0x2E, 0x34, 0x2D, 0x36, 0xB2, 0xDC, 0xEE, 0xB4, 0xFB, 0x5B, 0xF6, 0xA4, 0x4D, 0x76, 0x61, 0xB7,
+	 0xCE, 0x7D, 0x7B, 0x52, 0x3E, 0xDD, 0x71, 0x5E, 0x97, 0x13, 0xF5, 0xA6, 0x68, 0xB9, 0x00, 0x00,
+	 0x2C, 0xC1, 0x60, 0x40, 0x1F, 0xE3, 0xC8, 0x79, 0xED, 0xB6, 0xBE, 0xD4, 0x46, 0x8D, 0xD9, 0x67,
+	 0x4B, 0x72, 0xDE, 0x94, 0xD4, 0x98, 0xE8, 0xB0, 0x4A, 0x85, 0x6B, 0xBB, 0x2A, 0xC5, 0xE5, 0x4F,
+	 0x16, 0xED, 0xC5, 0x86, 0xD7, 0x9A, 0x55, 0x66, 0x94, 0x11, 0xCF, 0x8A, 0x10, 0xE9, 0x06, 0x04,
+	 0x81, 0xFE, 0xF0, 0xA0, 0x44, 0x78, 0xBA, 0x25, 0xE3, 0x4B, 0xF3, 0xA2, 0xFE, 0x5D, 0xC0, 0x80,
+	 0x8A, 0x05, 0xAD, 0x3F, 0xBC, 0x21, 0x48, 0x70, 0x04, 0xF1, 0xDF, 0x63, 0xC1, 0x77, 0x75, 0xAF,
+	 0x63, 0x42, 0x30, 0x20, 0x1A, 0xE5, 0x0E, 0xFD, 0x6D, 0xBF, 0x4C, 0x81, 0x14, 0x18, 0x35, 0x26,
+	 0x2F, 0xC3, 0xE1, 0xBE, 0xA2, 0x35, 0xCC, 0x88, 0x39, 0x2E, 0x57, 0x93, 0xF2, 0x55, 0x82, 0xFC,
+	 0x47, 0x7A, 0xAC, 0xC8, 0xE7, 0xBA, 0x2B, 0x32, 0x95, 0xE6, 0xA0, 0xC0, 0x98, 0x19, 0xD1, 0x9E,
+	 0x7F, 0xA3, 0x66, 0x44, 0x7E, 0x54, 0xAB, 0x3B, 0x83, 0x0B, 0xCA, 0x8C, 0x29, 0xC7, 0xD3, 0x6B,
+	 0x3C, 0x28, 0x79, 0xA7, 0xE2, 0xBC, 0x1D, 0x16, 0x76, 0xAD, 0x3B, 0xDB, 0x56, 0x64, 0x4E, 0x74,
+	 0x1E, 0x14, 0xDB, 0x92, 0x0A, 0x0C, 0x6C, 0x48, 0xE4, 0xB8, 0x5D, 0x9F, 0x6E, 0xBD, 0xEF, 0x43,
+	 0xA6, 0xC4, 0xA8, 0x39, 0xA4, 0x31, 0x37, 0xD3, 0x8B, 0xF2, 0x32, 0xD5, 0x43, 0x8B, 0x59, 0x6E,
+	 0xB7, 0xDA, 0x8C, 0x01, 0x64, 0xB1, 0xD2, 0x9C, 0xE0, 0x49, 0xB4, 0xD8, 0xFA, 0xAC, 0x07, 0xF3,
+	 0x25, 0xCF, 0xAF, 0xCA, 0x8E, 0xF4, 0xE9, 0x47, 0x18, 0x10, 0xD5, 0x6F, 0x88, 0xF0, 0x6F, 0x4A,
+	 0x72, 0x5C, 0x24, 0x38, 0xF1, 0x57, 0xC7, 0x73, 0x51, 0x97, 0x23, 0xCB, 0x7C, 0xA1, 0x9C, 0xE8,
+	 0x21, 0x3E, 0xDD, 0x96, 0xDC, 0x61, 0x86, 0x0D, 0x85, 0x0F, 0x90, 0xE0, 0x42, 0x7C, 0xC4, 0x71,
+	 0xAA, 0xCC, 0xD8, 0x90, 0x05, 0x06, 0x01, 0xF7, 0x12, 0x1C, 0xA3, 0xC2, 0x5F, 0x6A, 0xF9, 0xAE,
+	 0xD0, 0x69, 0x91, 0x17, 0x58, 0x99, 0x27, 0x3A, 0xB9, 0x27, 0x38, 0xD9, 0x13, 0xEB, 0xB3, 0x2B,
+	 0x33, 0x22, 0xBB, 0xD2, 0x70, 0xA9, 0x89, 0x07, 0xA7, 0x33, 0xB6, 0x2D, 0x22, 0x3C, 0x92, 0x15,
+	 0x20, 0xC9, 0x49, 0x87, 0xFF, 0xAA, 0x78, 0x50, 0x7A, 0xA5, 0x8F, 0x03, 0xF8, 0x59, 0x80, 0x09,
+	 0x17, 0x1A, 0xDA, 0x65, 0x31, 0xD7, 0xC6, 0x84, 0xB8, 0xD0, 0xC3, 0x82, 0xB0, 0x29, 0x77, 0x5A,
+	 0x11, 0x1E, 0xCB, 0x7B, 0xFC, 0xA8, 0xD6, 0x6D, 0x3A, 0x2C, 0x00, 0x30, 0x00, 0x31, 0x00, 0x33,
+	 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x38, 0x00, 0x3A, 0x00, 0x3B,
+	 0x00, 0x3C, 0x00, 0x3D, 0x00, 0x3E, 0x00, 0x3F, 0x00, 0x3F, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0A, 0x02, 0x14,
+	 0x05, 0x32, 0x0B, 0x37, 0x08, 0x50, 0x0B, 0x6E, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x3F, 0x00,
+	 0x0C, 0x00, 0x30, 0x00, 0x03, 0x00, 0x0F, 0x00, 0x3E, 0x00, 0x3C, 0x00, 0x02, 0x00, 0x04, 0x00,
+	 0x0A, 0x00, 0x0B, 0x00, 0x10, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x63, 0x00, 0x20, 0x00, 0x63, 0x00, 0x63, 0x00, 0x20, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x10,
+	 0x9E, 0x10, 0x56, 0x10, 0x98, 0x10, 0x5C, 0x10, 0x92, 0x10, 0x62, 0x10, 0x8C, 0x10, 0x68, 0x10,
+	 0x86, 0x10, 0x6E, 0x10, 0x80, 0x10, 0x74, 0x10, 0x7A, 0x10, 0x07, 0x01, 0x00, 0x00, 0x0A, 0x22,
+	 0x00, 0x04, 0x08, 0x01, 0x00, 0x00, 0x0A, 0x26, 0x00, 0x04, 0x09, 0x01, 0x00, 0x00, 0x0A, 0x2A,
+	 0x00, 0x04, 0x0A, 0x01, 0x00, 0x00, 0x0A, 0x2E, 0x00, 0x04, 0x0B, 0x01, 0x00, 0x00, 0x10, 0x24,
+	 0x04, 0x04, 0x0C, 0x01, 0x00, 0x00, 0x10, 0x28, 0x04, 0x04, 0x0D, 0x01, 0x00, 0x00, 0x10, 0x2C,
+	 0x04, 0x04, 0x0E, 0x01, 0x00, 0x00, 0x10, 0x30, 0x04, 0x04, 0x0F, 0x01, 0x00, 0x00, 0x16, 0x34,
+	 0x08, 0x04, 0x10, 0x01, 0x00, 0x00, 0x16, 0x38, 0x08, 0x04, 0x11, 0x01, 0x00, 0x00, 0x16, 0x3C,
+	 0x08, 0x04, 0x12, 0x01, 0x00, 0x00, 0x16, 0x40, 0x08, 0x04, 0x13, 0x01, 0x00, 0x00, 0x17, 0x64,
+	 0x0C, 0x0B, 0x14, 0x01, 0x00, 0x00, 0x17, 0x68, 0x0C, 0x0B, 0x15, 0x01, 0x00, 0x00, 0x17, 0x6C,
+	 0x0C, 0x0B, 0x16, 0x01, 0x00, 0x00, 0x17, 0x70, 0x0C, 0x0B, 0x17, 0x01, 0x00, 0x00, 0x17, 0x74,
+	 0x0C, 0x0B, 0x18, 0x01, 0x00, 0x00, 0x17, 0x78, 0x0C, 0x0B, 0x19, 0x01, 0x00, 0x00, 0x17, 0x7C,
+	 0x0C, 0x0B, 0x1A, 0x01, 0x00, 0x00, 0x17, 0x80, 0x0C, 0x0B, 0x1B, 0x01, 0x00, 0x00, 0x17, 0x84,
+	 0x0C, 0x0B, 0x1C, 0x01, 0x00, 0x00, 0x17, 0x88, 0x0C, 0x0B, 0x1D, 0x01, 0x00, 0x00, 0x17, 0x8C,
+	 0x0C, 0x0B, 0x1E, 0x01, 0x00, 0x00, 0x1D, 0x95, 0x17, 0x04, 0x1F, 0x01, 0x00, 0x00, 0x1D, 0x99,
+	 0x17, 0x04, 0x20, 0x01, 0x00, 0x00, 0x1D, 0x9D, 0x17, 0x04, 0x21, 0x01, 0x00, 0x00, 0x1D, 0xA1,
+	 0x17, 0x04, 0x22, 0x01, 0x00, 0x00, 0x0E, 0xA5, 0x00, 0x00, 0xC0, 0x10, 0xE0, 0x10, 0x00, 0x11,
+	 0x20, 0x11, 0x78, 0x11, 0xC8, 0x10, 0xE8, 0x10, 0x08, 0x11, 0x28, 0x11, 0x80, 0x11, 0xD0, 0x10,
+	 0xF0, 0x10, 0x10, 0x11, 0x30, 0x11, 0x88, 0x11, 0xD8, 0x10, 0xF8, 0x10, 0x18, 0x11, 0x38, 0x11,
+	 0x90, 0x11, 0x40, 0x11, 0x48, 0x11, 0x50, 0x11, 0x58, 0x11, 0x60, 0x11, 0x68, 0x11, 0x70, 0x11,
+	 0x98, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD2, 0x14, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xEB, 0xBA, 0xEB,
+	 0xDF, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB,
+	 0x57, 0xEB, 0x90, 0xF1, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0xD6, 0xED,
+	 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB,
+	 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x2F, 0xEE,
+	 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB,
+	 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0xA4, 0xED, 0xBE, 0xED,
+	 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x57, 0xEB, 0x7F, 0xF4, 0x19, 0xEC,
+	 0x2C, 0xEC, 0xDC, 0xEC, 0xE0, 0xEC, 0x57, 0xEB, 0x57, 0xEB, 0x8F, 0xED, 0x84, 0xE3, 0x59, 0xE3,
+	 0xD7, 0xE3, 0x28, 0xE4, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xEB, 0xF6, 0xEB, 0x72, 0xF0, 0x72, 0xF0,
+	 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFC, 0x89, 0xEE, 0x45, 0xF0, 0x5A, 0x00, 0x02, 0x00, 0xF9, 0xFF,
+	 0x89, 0xEE, 0x9F, 0xEE, 0xCC, 0x00, 0x02, 0x00, 0xF7, 0xFF, 0x89, 0xEE, 0x9F, 0xEE, 0xB6, 0x1F,
+	 0x06, 0x00, 0xF0, 0xFF, 0x89, 0xEE, 0x73, 0xEE, 0x00, 0x00, 0x00, 0x02, 0xF6, 0xFF, 0x89, 0xEE,
+	 0x9F, 0xEE, 0x6C, 0x00, 0x02, 0x00, 0xF4, 0xFF, 0x89, 0xEE, 0x9F, 0xEE, 0x6A, 0x01, 0x02, 0x00,
+	 0xF5, 0xFF, 0x89, 0xEE, 0x4E, 0xF0, 0xA8, 0x1F, 0x02, 0x00, 0xE0, 0xFF, 0x89, 0xEE, 0x9F, 0xEE,
+	 0xEE, 0x21, 0x02, 0x00, 0xE1, 0xFF, 0x89, 0xEE, 0x9F, 0xEE, 0xF0, 0x21, 0x02, 0x00, 0xE2, 0xFF,
+	 0x89, 0xEE, 0x9F, 0xEE, 0xF2, 0x21, 0x02, 0x00, 0xE3, 0xFF, 0x89, 0xEE, 0x9F, 0xEE, 0xEA, 0x21,
+	 0x02, 0x00, 0x03, 0xFC, 0x89, 0xEE, 0xE5, 0xEF, 0x7C, 0x21, 0x02, 0x00, 0x04, 0xFC, 0x89, 0xEE,
+	 0x99, 0xEE, 0xBE, 0x1F, 0x22, 0x00, 0x06, 0xFC, 0x89, 0xEE, 0x9F, 0xEE, 0xA6, 0x1F, 0x02, 0x00,
+	 0x07, 0xFC, 0x89, 0xEE, 0x9F, 0xEE, 0x02, 0x20, 0x02, 0x00, 0x0E, 0xFC, 0x89, 0xEE, 0xF7, 0xEF,
+	 0x0C, 0x20, 0x22, 0x00, 0xB1, 0xFC, 0x89, 0xEE, 0x58, 0xF2, 0x2C, 0x21, 0x02, 0x00, 0x20, 0xFC,
+	 0x89, 0xEE, 0x9F, 0xEE, 0x32, 0x20, 0x02, 0x00, 0x25, 0xFC, 0x89, 0xEE, 0x9F, 0xEE, 0x3C, 0x20,
+	 0x02, 0x00, 0x26, 0xFC, 0x89, 0xEE, 0x9F, 0xEE, 0x3E, 0x20, 0x02, 0x00, 0x27, 0xFC, 0x89, 0xEE,
+	 0x9F, 0xEE, 0x40, 0x20, 0x02, 0x00, 0xB2, 0xFC, 0x89, 0xEE, 0x99, 0xEE, 0x50, 0x21, 0x22, 0x00,
+	 0xC1, 0xFC, 0x89, 0xEE, 0x9F, 0xEE, 0x98, 0x21, 0x20, 0x00, 0xB0, 0xFC, 0x69, 0xEE, 0x5D, 0xF2,
+	 0x00, 0x00, 0x00, 0x00, 0xC4, 0xFC, 0x69, 0xEE, 0x68, 0xF0, 0x00, 0x00, 0x08, 0x00, 0xC8, 0xFC,
+	 0x69, 0xEE, 0x63, 0xF0, 0x00, 0x00, 0x08, 0x00, 0xB4, 0xFC, 0x69, 0xEE, 0x9B, 0xF2, 0x00, 0x00,
+	 0x00, 0x00, 0xB6, 0xFC, 0x69, 0xEE, 0x4E, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xB7, 0xFC, 0x69, 0xEE,
+	 0x90, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xB8, 0xFC, 0x69, 0xEE, 0xED, 0xF3, 0x00, 0x00, 0x00, 0x00,
+	 0xB5, 0xFC, 0x89, 0xEE, 0x9F, 0xEE, 0xE6, 0x21, 0x02, 0x00, 0xB9, 0xFC, 0x89, 0xEE, 0x9F, 0xEE,
+	 0xE8, 0x21, 0x02, 0x00, 0x90, 0xFD, 0x89, 0xEE, 0x73, 0xEE, 0xEC, 0x21, 0x02, 0x00, 0x23, 0xFC,
+	 0x89, 0xEE, 0x9F, 0xEE, 0x38, 0x20, 0x02, 0x00, 0x29, 0xFC, 0x48, 0xEF, 0xF5, 0xEE, 0x00, 0x00,
+	 0x00, 0x00, 0xC2, 0xFC, 0x89, 0xEE, 0x9F, 0xEE, 0x74, 0x21, 0x02, 0x00, 0x32, 0xFC, 0x89, 0xEE,
+	 0x9F, 0xEE, 0x60, 0x01, 0x02, 0x00, 0x33, 0xFC, 0x89, 0xEE, 0x9F, 0xEE, 0x62, 0x01, 0x02, 0x00,
+	 0x10, 0xFC, 0x89, 0xEE, 0x9F, 0xEE, 0xAE, 0x1F, 0x02, 0x00, 0x11, 0xFC, 0x89, 0xEE, 0x9F, 0xEE,
+	 0x46, 0x20, 0x06, 0x00, 0x12, 0xFC, 0x89, 0xEE, 0x9F, 0xEE, 0x4C, 0x20, 0x06, 0x00, 0x13, 0xFC,
+	 0x89, 0xEE, 0x9F, 0xEE, 0x52, 0x20, 0x06, 0x00, 0x14, 0xFC, 0x89, 0xEE, 0x9F, 0xEE, 0x58, 0x20,
+	 0x06, 0x00, 0x15, 0xFC, 0x89, 0xEE, 0x9F, 0xEE, 0x5E, 0x20, 0x06, 0x00, 0x16, 0xFC, 0x89, 0xEE,
+	 0x9F, 0xEE, 0x64, 0x20, 0x06, 0x00, 0x17, 0xFC, 0x89, 0xEE, 0x9F, 0xEE, 0x2E, 0x20, 0x02, 0x00,
+	 0x83, 0xFC, 0x89, 0xEE, 0x9F, 0xEE, 0x6E, 0x01, 0x02, 0x00, 0x97, 0xFC, 0x89, 0xEE, 0x9F, 0xEE,
+	 0x6C, 0x01, 0x02, 0x00, 0x98, 0xFC, 0x31, 0xF0, 0x1F, 0xF0, 0xE4, 0x00, 0x02, 0x00, 0x99, 0xFC,
+	 0x31, 0xF0, 0x1F, 0xF0, 0xE4, 0x02, 0x02, 0x00, 0x9A, 0xFC, 0x31, 0xF0, 0x1F, 0xF0, 0xE4, 0x04,
+	 0x02, 0x00, 0x9B, 0xFC, 0x31, 0xF0, 0x1F, 0xF0, 0xE4, 0x06, 0x02, 0x00, 0x9C, 0xFC, 0x31, 0xF0,
+	 0x1F, 0xF0, 0xE4, 0x08, 0x02, 0x00, 0x9D, 0xFC, 0x31, 0xF0, 0x1F, 0xF0, 0xE4, 0x0A, 0x02, 0x00,
+	 0x18, 0xFC, 0x89, 0xEE, 0x9F, 0xEE, 0x30, 0x20, 0x02, 0x00, 0x22, 0xFC, 0x89, 0xEE, 0x9F, 0xEE,
+	 0x36, 0x20, 0x02, 0x00, 0x24, 0xFC, 0x89, 0xEE, 0x9F, 0xEE, 0x3A, 0x20, 0x02, 0x00, 0xC0, 0xFC,
+	 0x69, 0xEE, 0x61, 0xF0, 0x00, 0x00, 0x06, 0x00, 0x9E, 0xFC, 0x89, 0xEE, 0x17, 0xF0, 0x70, 0x01,
+	 0x02, 0x00, 0x9F, 0xFC, 0x31, 0xF0, 0x1F, 0xF0, 0xE6, 0x00, 0x02, 0x00, 0xA0, 0xFC, 0x31, 0xF0,
+	 0x1F, 0xF0, 0xE6, 0x02, 0x02, 0x00, 0xA1, 0xFC, 0x31, 0xF0, 0x1F, 0xF0, 0xE6, 0x04, 0x02, 0x00,
+	 0xA2, 0xFC, 0x31, 0xF0, 0x1F, 0xF0, 0xE6, 0x06, 0x02, 0x00, 0xA3, 0xFC, 0x31, 0xF0, 0x1F, 0xF0,
+	 0xE6, 0x08, 0x02, 0x00, 0xA4, 0xFC, 0x31, 0xF0, 0x1F, 0xF0, 0xE6, 0x0A, 0x02, 0x00, 0x20, 0xFD,
+	 0xBA, 0xEE, 0x73, 0xEE, 0x53, 0xF5, 0x08, 0x00, 0x21, 0xFD, 0xBA, 0xEE, 0x73, 0xEE, 0x57, 0xF5,
+	 0x0A, 0x00, 0x22, 0xFD, 0xBA, 0xEE, 0x73, 0xEE, 0x5C, 0xF5, 0x16, 0x00, 0x23, 0xFD, 0xBA, 0xEE,
+	 0x73, 0xEE, 0x67, 0xF5, 0x0A, 0x00, 0x10, 0xFD, 0x89, 0xEE, 0x73, 0xEE, 0x34, 0x01, 0x02, 0x00,
+	 0x45, 0xFD, 0x89, 0xEE, 0x73, 0xEE, 0xCC, 0x00, 0x02, 0x00, 0x47, 0xFD, 0x89, 0xEE, 0x73, 0xEE,
+	 0x38, 0x01, 0x02, 0x00, 0x48, 0xFD, 0x9E, 0xEF, 0x73, 0xEE, 0x60, 0x01, 0x02, 0x00, 0x49, 0xFD,
+	 0x9E, 0xEF, 0x73, 0xEE, 0x62, 0x01, 0x02, 0x00, 0x4A, 0xFD, 0x89, 0xEE, 0x73, 0xEE, 0x58, 0x01,
+	 0x02, 0x00, 0x4B, 0xFD, 0x89, 0xEE, 0x73, 0xEE, 0x5A, 0x01, 0x02, 0x00, 0x4D, 0xFD, 0xBA, 0xEE,
+	 0x73, 0xEE, 0x6C, 0xF5, 0x04, 0x00, 0x4F, 0xFD, 0xB2, 0xEF, 0x73, 0xEE, 0x80, 0x21, 0x02, 0x00,
+	 0xC0, 0xFD, 0xBA, 0xEE, 0x73, 0xEE, 0x6E, 0xF5, 0x02, 0x00, 0xC2, 0xFD, 0xA8, 0xEF, 0x73, 0xEE,
+	 0x00, 0x00, 0x02, 0x00, 0xC3, 0xFD, 0xBA, 0xEE, 0x73, 0xEE, 0x6F, 0xF5, 0x02, 0x00, 0x40, 0xFD,
+	 0xB2, 0xEE, 0x73, 0xEE, 0x78, 0x01, 0x02, 0x00, 0x24, 0xFD, 0xD8, 0xEF, 0x73, 0xEE, 0x00, 0x00,
+	 0x02, 0x00, 0x91, 0xFD, 0x89, 0xEE, 0x73, 0xEE, 0x86, 0x1B, 0x02, 0x00, 0x93, 0xFD, 0x89, 0xEE,
+	 0x73, 0xEE, 0x8C, 0x1B, 0x02, 0x00, 0xC1, 0xFD, 0x89, 0xEE, 0x73, 0xEE, 0xCA, 0x00, 0x02, 0x00,
+	 0xC6, 0xFD, 0xE7, 0xEE, 0x73, 0xEE, 0x8E, 0x21, 0x0A, 0x00, 0x89, 0xFD, 0x5F, 0xEF, 0x73, 0xEE,
+	 0x00, 0x00, 0x00, 0x00, 0x8A, 0xFD, 0xD7, 0xEE, 0x73, 0xEE, 0xC0, 0x21, 0x24, 0x00, 0x46, 0xFD,
+	 0x89, 0xEE, 0x73, 0xEE, 0x7A, 0x01, 0x06, 0x00, 0x86, 0xFD, 0x89, 0xEE, 0x73, 0xEE, 0xB6, 0x1F,
+	 0x06, 0x00, 0x87, 0xFD, 0x89, 0xEE, 0x73, 0xEE, 0xB8, 0x21, 0x06, 0x00, 0x8B, 0xFD, 0x7A, 0xF3,
+	 0x73, 0xEE, 0x00, 0x00, 0x12, 0x00, 0x8E, 0xFD, 0x89, 0xEE, 0x73, 0xEE, 0xB8, 0x12, 0x02, 0x00,
+	 0x80, 0xFD, 0xBC, 0xEF, 0x73, 0xEE, 0x1C, 0x00, 0x02, 0x00, 0x81, 0xFD, 0xBC, 0xEF, 0x73, 0xEE,
+	 0x1C, 0x02, 0x02, 0x00, 0x82, 0xFD, 0xBC, 0xEF, 0x73, 0xEE, 0x1C, 0x04, 0x02, 0x00, 0x83, 0xFD,
+	 0xBC, 0xEF, 0x73, 0xEE, 0x1C, 0x06, 0x02, 0x00, 0x84, 0xFD, 0xBC, 0xEF, 0x73, 0xEE, 0x1C, 0x08,
+	 0x02, 0x00, 0x85, 0xFD, 0xBC, 0xEF, 0x73, 0xEE, 0x1C, 0x0A, 0x02, 0x00, 0x00, 0xF1, 0x46, 0x00,
+	 0x2D, 0xEE, 0xF8, 0x00, 0x00, 0x03, 0x8A, 0xEA, 0x1F, 0x00, 0x36, 0x01, 0xCA, 0x00, 0x96, 0x01,
+	 0xCE, 0x00, 0xFC, 0x00, 0x78, 0x01, 0xDA, 0x1E, 0x1A, 0x01, 0x86, 0x1B, 0xC8, 0x00, 0x00, 0x00,
+	 0xCE, 0x12, 0x00, 0x00, 0xD2, 0x14, 0x14, 0x01, 0x03, 0x00, 0xAE, 0x00, 0xE4, 0x00, 0x3C, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x77, 0xB4, 0xEA, 0xB3, 0x26, 0xB5, 0x2F, 0xB5, 0xFB, 0xB3, 0xA4, 0xB4, 0x69, 0xB4, 0xE7, 0xC5,
+	 0x4A, 0xC5, 0xE7, 0xC5, 0xBE, 0xC5, 0x54, 0xC5, 0x48, 0xC5, 0x06, 0xC6, 0x17, 0xC6, 0x17, 0xC6,
+	 0x17, 0xC6, 0x20, 0xC6, 0x3B, 0xC6, 0x98, 0xC6, 0xB4, 0xC6, 0xBF, 0xC5, 0xD2, 0xC5, 0xA6, 0xC5,
+	 0x10, 0x00, 0x12, 0x00, 0x13, 0x00, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x30, 0x00, 0x31, 0x00,
+	 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x39, 0x00,
+	 0x3A, 0x00, 0x00, 0x00, 0x14, 0x01, 0x14, 0x01, 0x14, 0x01, 0x14, 0x01, 0x14, 0x01, 0x14, 0x01,
+	 0x14, 0x01, 0x14, 0x01, 0xF3, 0x02, 0xAD, 0x03, 0x60, 0x04, 0x04, 0x05, 0x07, 0x06, 0x08, 0x07,
+	 0x0A, 0x08, 0x16, 0x09, 0x44, 0x0A, 0x04, 0x0B, 0x40, 0x0C, 0x80, 0x0D, 0x00, 0x0E, 0x84, 0x0F,
+	 0x01, 0x10, 0x10, 0x11, 0x02, 0x14, 0x40, 0x20, 0x32, 0x21, 0x32, 0x22, 0x04, 0x23, 0x01, 0x24,
+	 0x0F, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2A, 0x01, 0x2B, 0x06, 0x2C,
+	 0x00, 0x38, 0x00, 0x39, 0xD6, 0x3A, 0x00, 0x3B, 0x00, 0x3C, 0x14, 0x3D, 0x7F, 0x3E, 0x00, 0x3F,
+	 0x68, 0x40, 0x75, 0x41, 0x07, 0x42, 0x07, 0x43, 0x00, 0x45, 0x3B, 0x4A, 0x00, 0x4B, 0x00, 0x4C,
+	 0x0F, 0x4D, 0x02, 0x75, 0x00, 0x76, 0x80, 0x00, 0x08, 0x01, 0x09, 0x01, 0x09, 0x01, 0x0A, 0x01,
+	 0x0A, 0x01, 0x0B, 0x01, 0x0B, 0x01, 0x0C, 0x01, 0x0C, 0x01, 0x0D, 0x01, 0x0D, 0x01, 0x0E, 0x01,
+	 0x0E, 0x01, 0x0F, 0x01, 0x0F, 0x01, 0x10, 0x01, 0x10, 0x01, 0x11, 0x01, 0x11, 0x01, 0x12, 0x01,
+	 0x12, 0x01, 0x13, 0x01, 0x13, 0x01, 0x14, 0x01, 0x14, 0x01, 0x15, 0x01, 0x15, 0x01, 0x16, 0x01,
+	 0x16, 0x01, 0x17, 0x01, 0x17, 0x01, 0x18, 0x01, 0x18, 0x01, 0x19, 0x01, 0x19, 0x01, 0x4D, 0x01,
+	 0x4D, 0x01, 0x4E, 0x01, 0x4E, 0x01, 0x4F, 0x01, 0x4F, 0x01, 0x50, 0x01, 0x50, 0x01, 0x51, 0x01,
+	 0x51, 0x01, 0x52, 0x01, 0x52, 0x01, 0x53, 0x01, 0x53, 0x01, 0x54, 0x01, 0x54, 0x01, 0x65, 0x01,
+	 0x65, 0x01, 0x66, 0x01, 0x66, 0x01, 0x67, 0x01, 0x67, 0x01, 0x68, 0x01, 0x68, 0x01, 0x69, 0x01,
+	 0x69, 0x01, 0x6A, 0x01, 0x6A, 0x01, 0x6B, 0x01, 0x6B, 0x01, 0x6C, 0x01, 0x6C, 0x01, 0x6D, 0x01,
+	 0x6D, 0x01, 0x6E, 0x01, 0x6E, 0x01, 0x6F, 0x01, 0x6F, 0x01, 0x70, 0x01, 0x70, 0x01, 0x71, 0x01,
+	 0x71, 0x01, 0x72, 0x01, 0x72, 0x01, 0x73, 0x01, 0x73, 0x01, 0x74, 0x01, 0x74, 0x01, 0x75, 0x01,
+	 0x75, 0x01, 0x76, 0x01, 0x76, 0x01, 0x77, 0x01, 0x77, 0x01, 0x78, 0x01, 0x78, 0x01, 0x79, 0x01,
+	 0x79, 0x01, 0x7A, 0x01, 0x7A, 0x01, 0x7B, 0x01, 0x7B, 0x01, 0x7C, 0x01, 0x7C, 0x01, 0x7D, 0x01,
+	 0x7D, 0x01, 0x7E, 0x01, 0x7E, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01,
+	 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01,
+	 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01,
+	 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x80, 0x12, 0x80, 0x12, 0x80, 0x12, 0x80, 0x12,
+	 0x80, 0x12, 0x80, 0x12, 0x80, 0x12, 0x80, 0x12, 0x80, 0x12, 0x80, 0x12, 0x80, 0x12, 0x80, 0x12,
+	 0x80, 0x12, 0x80, 0x12, 0x80, 0x13, 0x80, 0x13, 0x80, 0x13, 0x80, 0x13, 0x80, 0x13, 0x80, 0x13,
+	 0x80, 0x13, 0x80, 0x13, 0x80, 0x13, 0x80, 0x13, 0x80, 0x13, 0x80, 0x13, 0x80, 0x13, 0x80, 0x13,
+	 0x51, 0x44, 0x51, 0x44, 0x51, 0x44, 0x51, 0x44, 0x51, 0x44, 0x51, 0x44, 0x51, 0x44, 0x51, 0x44,
+	 0x51, 0x44, 0x51, 0x44, 0x51, 0x44, 0x51, 0x44, 0x51, 0x44, 0x51, 0x44, 0x22, 0x46, 0x22, 0x46,
+	 0x22, 0x46, 0x22, 0x46, 0x22, 0x46, 0x22, 0x46, 0x22, 0x46, 0x22, 0x46, 0x22, 0x46, 0x22, 0x46,
+	 0x22, 0x46, 0x23, 0x46, 0x23, 0x46, 0x23, 0x46, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47,
+	 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47,
+	 0x1C, 0x47, 0x1D, 0x47, 0x9A, 0x48, 0xDA, 0x48, 0x1A, 0x48, 0x5A, 0x48, 0x9A, 0x48, 0xDA, 0x48,
+	 0x1A, 0x48, 0x5A, 0x48, 0x9A, 0x48, 0xDA, 0x48, 0x1A, 0x48, 0x5A, 0x48, 0x9A, 0x48, 0x33, 0x48,
+	 0x78, 0x49, 0x78, 0x49, 0x79, 0x49, 0x79, 0x49, 0x79, 0x49, 0x79, 0x49, 0x7A, 0x49, 0x7A, 0x49,
+	 0x7A, 0x49, 0x7A, 0x49, 0x7B, 0x49, 0x7B, 0x49, 0x7B, 0x49, 0x7C, 0x49, 0x32, 0x00, 0x46, 0x00,
+	 0x5A, 0x00, 0x6E, 0x00, 0x82, 0x00, 0x96, 0x00, 0xAA, 0x00, 0xBE, 0x00, 0xD2, 0x00, 0xE6, 0x00,
+	 0xFA, 0x00, 0x0E, 0x01, 0x22, 0x01, 0x52, 0x01, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00,
+	 0x04, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00,
+	 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x15, 0x00, 0x6E, 0x6F, 0x6E, 0x2D, 0x73, 0x70,
+	 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x53, 0x53, 0x49, 0x44, 0x20, 0x21, 0x21, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0x00, 0x00, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x09, 0x00, 0x00,
+	 0x01, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x48, 0x45, 0x52, 0x4D, 0x45, 0x53, 0x20, 0x32,
+	 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+	 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
+	 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x15, 0x00, 0x6E, 0x6F, 0x6E, 0x2D, 0x73, 0x70,
+	 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x53, 0x53, 0x49, 0x44, 0x20, 0x21, 0x21, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0x00, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x09, 0x00, 0x00,
+	 0x01, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x48, 0x45, 0x52, 0x4D, 0x45, 0x53, 0x20, 0x32,
+	 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+	 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x69, 0x72, 0x73, 0x74, 0x20,
+	 0x57, 0x61, 0x76, 0x65, 0x4C, 0x41, 0x4E, 0x20, 0x49, 0x49, 0x20, 0x53, 0x53, 0x49, 0x44, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x02, 0x01, 0x82, 0x84, 0x8B, 0x96, 0x00, 0x00,
+	 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
+	 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xDD, 0x00, 0x50, 0xF2, 0x01,
+	 0x01, 0x00, 0x00, 0x50, 0xF2, 0x05, 0x02, 0x00, 0x00, 0x50, 0xF2, 0x02, 0x00, 0x50, 0xF2, 0x04,
+	 0x02, 0x00, 0x00, 0x50, 0xF2, 0x00, 0x00, 0x50, 0xF2, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x04, 0x00,
+	 0x15, 0x00, 0x02, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x04, 0x00, 0x10, 0x00, 0x02, 0x00,
+	 0x01, 0x00, 0x04, 0x00, 0x15, 0x00, 0x20, 0x00, 0x11, 0x00, 0x20, 0x00, 0x1E, 0x1F, 0x8E, 0x21,
+	 0x00, 0x23, 0xDA, 0x22, 0x04, 0x23, 0xC0, 0x21, 0xFF, 0xFF, 0xFF, 0xFF, 0x34, 0x23, 0x00, 0x00,
+	 0x50, 0x21, 0x8E, 0x21, 0xFF, 0xFF, 0x00, 0x00, 0x1E, 0x1F, 0x8E, 0x21, 0x00, 0x23, 0xFF, 0xFF,
+	 0x04, 0x23, 0xC0, 0x21, 0xFF, 0xFF, 0xFF, 0xFF, 0x34, 0x23, 0x00, 0x00, 0x8E, 0x21, 0x3C, 0x23,
+	 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x00, 0x06, 0x07,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80,
+	 0x00, 0x60, 0x1D, 0x00, 0x00, 0x00, 0x0D, 0x81, 0x00, 0x60, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+};  /* fw_image_2_data */
+
+static const hcf_8 fw_image_3_data[] = {
+	 0x3F, 0x41, 0xA5, 0x4C, 0x50, 0x37, 0x04, 0x00, 0x01, 0xB9, 0x41, 0x5F, 0xB5, 0x60, 0x55, 0xE0,
+	 0x0C, 0x60, 0x10, 0x62, 0xA2, 0xD3, 0x01, 0x60, 0x01, 0x65, 0xD4, 0x80, 0x5A, 0xD1, 0x0F, 0x02,
+	 0x5A, 0xD3, 0x3E, 0x60, 0x00, 0x66, 0xE0, 0x87, 0x40, 0x4A, 0xEA, 0x60, 0x88, 0x61, 0x64, 0x44,
+	 0xC8, 0x84, 0x0C, 0x63, 0xAA, 0x46, 0x58, 0xD0, 0xAA, 0x46, 0x59, 0xD8, 0xFB, 0x1F, 0x08, 0x60,
+	 0x00, 0x63, 0xFA, 0x60, 0x00, 0x65, 0xBD, 0xD3, 0xA3, 0xD3, 0x02, 0xA8, 0xD4, 0x80, 0x61, 0x02,
+	 0x60, 0x02, 0x26, 0x60, 0x6A, 0x61, 0x3C, 0x60, 0x00, 0x66, 0x41, 0x4B, 0x2B, 0x41, 0x26, 0x60,
+	 0xB2, 0x7C, 0xD1, 0x80, 0xA1, 0xD2, 0x25, 0x05, 0x59, 0xD0, 0x60, 0x45, 0x59, 0xD2, 0x44, 0x47,
+	 0xE0, 0x87, 0x40, 0x4A, 0x59, 0xD2, 0x59, 0x8B, 0x40, 0x4C, 0x08, 0x60, 0x00, 0x63, 0xBE, 0xD3,
+	 0xBD, 0xD1, 0xEC, 0x18, 0xD4, 0x80, 0xEA, 0x18, 0x03, 0x03, 0xC3, 0x83, 0xC3, 0x83, 0xF7, 0x01,
+	 0x67, 0x44, 0xC0, 0x84, 0xE0, 0x85, 0x2C, 0x44, 0xD4, 0x80, 0x63, 0x41, 0x01, 0x06, 0x65, 0x44,
+	 0xC8, 0x83, 0xAA, 0x46, 0x59, 0xD1, 0x27, 0xD8, 0x5A, 0x87, 0xFC, 0x1F, 0xAA, 0x46, 0x2B, 0x41,
+	 0xD5, 0x01, 0x26, 0x60, 0xB2, 0x61, 0x41, 0x4B, 0x2B, 0x41, 0x26, 0x60, 0xEA, 0x7C, 0xD1, 0x80,
+	 0xA1, 0xD2, 0x27, 0x05, 0x59, 0xD0, 0x60, 0x45, 0x59, 0xD2, 0x44, 0x47, 0xE0, 0x87, 0x40, 0x4A,
+	 0x59, 0xD2, 0x59, 0x8B, 0x40, 0x4C, 0x08, 0x60, 0x00, 0x63, 0xBE, 0xD3, 0xBD, 0xD1, 0xEC, 0x18,
+	 0xD4, 0x80, 0xEA, 0x18, 0x03, 0x03, 0xC3, 0x83, 0xC3, 0x83, 0xF7, 0x01, 0x04, 0xA3, 0xA3, 0xD1,
+	 0x5A, 0x88, 0x2C, 0x43, 0xD3, 0x80, 0xFF, 0xFF, 0x01, 0x06, 0x64, 0x43, 0xCF, 0x83, 0xAA, 0x46,
+	 0x60, 0xFE, 0x28, 0xD1, 0x5E, 0x88, 0x27, 0xD8, 0x5A, 0x87, 0xFB, 0x1F, 0x20, 0xFE, 0xAA, 0x46,
+	 0xD3, 0x01, 0xB8, 0xFE, 0xB9, 0xFE, 0xBA, 0xFE, 0xBB, 0xFE, 0xBD, 0xFE, 0xBF, 0xFE, 0x21, 0x60,
+	 0x80, 0x62, 0xA2, 0xD3, 0x12, 0x63, 0x60, 0x40, 0x01, 0x27, 0x05, 0x00, 0x0B, 0x60, 0xEA, 0x62,
+	 0x00, 0x64, 0x5A, 0xDB, 0xFE, 0x1F, 0xA2, 0x60, 0x49, 0x78, 0xFF, 0xFF, 0xF1, 0xFF, 0x94, 0x48,
+	 0x1F, 0x00, 0x04, 0x00, 0xF2, 0xFF, 0x98, 0x48, 0x1F, 0x00, 0x04, 0x00, 0xFB, 0xFF, 0xA0, 0x48,
+	 0x1F, 0x00, 0x04, 0x00, 0xF1, 0xFF, 0xF2, 0x4D, 0x1F, 0x00, 0x04, 0x00, 0xF2, 0xFF, 0xF6, 0x4D,
+	 0x1F, 0x00, 0x04, 0x00, 0xFB, 0xFF, 0xFE, 0x4D, 0x1F, 0x00, 0x04, 0x00, 0x86, 0xFD, 0xB6, 0x1F,
+	 0x00, 0x00, 0x06, 0x00, 0x10, 0xFD, 0x34, 0x01, 0x00, 0x00, 0x02, 0x00, 0x14, 0xFD, 0x7E, 0x21,
+	 0x00, 0x00, 0x0A, 0x00, 0x20, 0xFA, 0xFA, 0x1D, 0x00, 0x00, 0x0E, 0x00, 0x21, 0xFA, 0xDE, 0x1D,
+	 0x00, 0x00, 0x0E, 0x00, 0x22, 0xFA, 0x16, 0x1E, 0x00, 0x00, 0x0E, 0x00, 0x23, 0xFA, 0xCA, 0x1C,
+	 0x00, 0x00, 0x01, 0x00, 0x24, 0xFA, 0xBE, 0x1E, 0x00, 0x00, 0x0E, 0x00, 0x25, 0xFA, 0xDE, 0x1C,
+	 0x00, 0x00, 0x80, 0x00, 0x26, 0xFA, 0xC4, 0x1C, 0x00, 0x00, 0x01, 0x00,
+
+};  /* fw_image_3_data */
+
+static const hcf_8 fw_image_4_data[] = {
+	 0xA6, 0x60, 0x25, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA6, 0x60, 0x0B, 0x78, 0x41, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA6, 0x60, 0x11, 0x78, 0xC4, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA5, 0x60, 0x61, 0x78, 0x43, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x44, 0xFF, 0x20, 0x54, 0xCD, 0xE2, 0xA6, 0x60, 0x23, 0x78, 0x08, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA6, 0x60, 0x25, 0x78, 0x44, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA6, 0x60, 0x25, 0x78, 0x46, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA6, 0x60, 0x25, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xAC, 0x60, 0x81, 0x78, 0x4C, 0x4E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xAC, 0x60, 0x18, 0x78, 0x4C, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xC4, 0xE2, 0x84, 0xFF, 0x22, 0x58, 0x82, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA7, 0x60, 0xC4, 0x78, 0x43, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xE4, 0xE2, 0xAC, 0x60, 0x31, 0x78, 0x95, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xBF, 0x60, 0x76, 0x78, 0x64, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xAC, 0x60, 0x8C, 0x78, 0xA4, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xAC, 0x60, 0x72, 0x78, 0x47, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB2, 0x60, 0xD1, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB2, 0x60, 0xFE, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB1, 0x60, 0x90, 0x78, 0x42, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB1, 0x60, 0xC0, 0x78, 0x43, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB1, 0x60, 0xC0, 0x78, 0x44, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB4, 0x60, 0x73, 0x78, 0x45, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB1, 0x60, 0xC3, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x00, 0x60, 0x83, 0x64, 0x80, 0x29, 0x09, 0xFB, 0xB2, 0x60, 0x99, 0x78, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xC0, 0x60, 0x29, 0x78, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xBF, 0x60, 0xB4, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xBE, 0x60, 0x78, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xBD, 0x60, 0xE8, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB5, 0x60, 0x96, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA1, 0xFF, 0xFF, 0xFF, 0x83, 0x3E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xC0, 0x60, 0x9F, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0x41, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0x42, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0xB0, 0xFF, 0xB1, 0xFF, 0x40, 0xFF, 0x43, 0xFF, 0xC0, 0x60, 0x9A, 0x78, 0x44, 0xFF, 0xFF, 0x01,
+	 0xC0, 0x60, 0x9F, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0xC6, 0x60, 0x66, 0x78, 0x45, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0xC0, 0x60, 0x9A, 0x78, 0x84, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0xC0, 0x60, 0x99, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0xC7, 0x60, 0x26, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xE5, 0x60, 0x0E, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xC7, 0x60, 0x2E, 0x78, 0x42, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xC7, 0x60, 0x2E, 0x78, 0x24, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xE3, 0x60, 0x45, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xC7, 0x60, 0x2E, 0x78, 0x44, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xC7, 0x60, 0x2E, 0x78, 0x84, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xC7, 0x60, 0x2E, 0x78, 0x47, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xEB, 0x60, 0x5B, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xEB, 0x60, 0x87, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xEB, 0x60, 0xA0, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xEB, 0x60, 0x84, 0x78, 0x28, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xEB, 0x60, 0x84, 0x78, 0x44, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xEB, 0x60, 0x84, 0x78, 0x45, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xEB, 0x60, 0x84, 0x78, 0x46, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x00, 0x60, 0x87, 0x64, 0x80, 0x29, 0x09, 0xFB, 0x47, 0xFF, 0xEB, 0x60, 0x84, 0x78, 0xFF, 0xFF,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x87, 0xF3, 0x88, 0xF3, 0xDC, 0x81, 0x00, 0x7C, 0x01, 0x00, 0x00, 0xFA, 0x60, 0x46, 0xFE, 0x63,
+	 0xA3, 0xD8, 0xFE, 0x1F, 0xCD, 0x81, 0xD8, 0x84, 0xF8, 0x02, 0x87, 0xF3, 0x88, 0xF5, 0xDC, 0x81,
+	 0x80, 0x67, 0x40, 0x4A, 0x14, 0x60, 0x02, 0x65, 0x01, 0x7C, 0x07, 0x18, 0x2A, 0x43, 0x02, 0xFC,
+	 0x5F, 0x8A, 0x8E, 0xF8, 0x70, 0xF8, 0x00, 0xF4, 0xF8, 0x01, 0x2E, 0x58, 0xFF, 0xFF, 0x89, 0xF5,
+	 0x06, 0x64, 0x66, 0x43, 0x00, 0x7C, 0x63, 0x46, 0xFE, 0x63, 0xA3, 0xD8, 0xFE, 0x1F, 0xCC, 0x84,
+	 0x66, 0x43, 0xDB, 0x83, 0xF8, 0x02, 0x14, 0x60, 0x02, 0x65, 0x09, 0x60, 0x2B, 0x7C, 0x89, 0xF3,
+	 0x06, 0x61, 0x60, 0x46, 0x01, 0x63, 0x72, 0xF8, 0x00, 0xFC, 0x63, 0x47, 0x06, 0xFA, 0x72, 0xF8,
+	 0x8E, 0xF8, 0xDF, 0x83, 0x66, 0x44, 0xCD, 0x81, 0x02, 0xA6, 0xF5, 0x02, 0x89, 0xF3, 0x06, 0x61,
+	 0x60, 0x46, 0x03, 0x7C, 0x73, 0xF8, 0x66, 0x44, 0xCD, 0x81, 0x02, 0xA6, 0xFB, 0x02, 0x2E, 0x58,
+	 0xFF, 0xFF, 0x3F, 0x40, 0x40, 0x26, 0x0A, 0x00, 0x42, 0x60, 0x09, 0xE0, 0x3F, 0x40, 0x01, 0x2A,
+	 0x03, 0x00, 0x60, 0x60, 0x1C, 0xE0, 0x02, 0x00, 0x80, 0x60, 0x1C, 0xE0, 0x40, 0xEC, 0x00, 0xED,
+	 0x02, 0xEE, 0x80, 0x60, 0x58, 0xEC, 0x80, 0x60, 0x00, 0xED, 0x80, 0x60, 0x82, 0xEE, 0xC0, 0x60,
+	 0x59, 0xEC, 0xC0, 0x60, 0x07, 0xED, 0xAD, 0x4F, 0xFE, 0xB4, 0xA0, 0x5D, 0x00, 0xF3, 0x28, 0xFB,
+	 0x40, 0x44, 0xA4, 0x60, 0x5D, 0x7C, 0x20, 0xF9, 0xA5, 0x60, 0x48, 0x7C, 0x21, 0xF9, 0xA7, 0x60,
+	 0x30, 0x7C, 0x22, 0xF9, 0xB0, 0x60, 0xCD, 0x7C, 0x23, 0xF9, 0xB5, 0x60, 0x6C, 0x7C, 0x24, 0xF9,
+	 0xC0, 0x60, 0x88, 0x7C, 0x25, 0xF9, 0xC6, 0x60, 0xE0, 0x7C, 0x26, 0xF9, 0x91, 0x60, 0x00, 0xE8,
+	 0x28, 0xE8, 0x44, 0x60, 0x02, 0xE6, 0x00, 0x64, 0x40, 0x52, 0x10, 0x60, 0x04, 0xE6, 0x08, 0x60,
+	 0x00, 0x63, 0xFA, 0x60, 0x00, 0x65, 0xBD, 0xD3, 0xBD, 0xD3, 0x02, 0xA8, 0xD4, 0x80, 0x47, 0x02,
+	 0x46, 0x02, 0xDB, 0x83, 0xFA, 0x60, 0x27, 0x65, 0x5B, 0xD3, 0xBF, 0xD1, 0x1A, 0x18, 0xC3, 0x83,
+	 0xD4, 0x80, 0xC3, 0x83, 0xF9, 0x02, 0xDB, 0x83, 0xD3, 0x83, 0xD3, 0x86, 0x64, 0x41, 0xCD, 0x81,
+	 0xA6, 0xD1, 0xDA, 0x86, 0x1C, 0x60, 0x68, 0x65, 0x00, 0x60, 0x72, 0x63, 0xA5, 0xD3, 0xDA, 0x85,
+	 0x90, 0x84, 0xFF, 0x27, 0x02, 0x00, 0xA2, 0xD9, 0x01, 0x00, 0xF8, 0x1F, 0xCD, 0x81, 0xFF, 0xFF,
+	 0xEF, 0x02, 0x08, 0x60, 0x06, 0x63, 0xFA, 0x60, 0x28, 0x65, 0x5B, 0xD3, 0xBF, 0xD1, 0x0B, 0x18,
+	 0xC3, 0x83, 0xD4, 0x80, 0xC3, 0x83, 0xF9, 0x02, 0xBF, 0xD3, 0x21, 0x60, 0x72, 0x62, 0x0E, 0xB4,
+	 0xE0, 0x84, 0xE0, 0x84, 0xA2, 0xDB, 0x08, 0x60, 0x06, 0x63, 0xFD, 0x60, 0x0C, 0x65, 0x5B, 0xD3,
+	 0xBF, 0xD1, 0x0D, 0x18, 0xC3, 0x83, 0xD4, 0x80, 0xC3, 0x83, 0xF9, 0x02, 0xFA, 0xA3, 0xA3, 0xD3,
+	 0x02, 0x60, 0x00, 0x65, 0xF7, 0xA0, 0xFC, 0xA0, 0x0A, 0x05, 0x01, 0x05, 0x00, 0x00, 0x21, 0x60,
+	 0x00, 0x65, 0x3F, 0x43, 0x3F, 0x43, 0x21, 0x60, 0x00, 0x65, 0xC0, 0x60, 0x8F, 0xEE, 0xB7, 0x84,
+	 0x40, 0x5F, 0x00, 0x60, 0x30, 0xE2, 0x00, 0x60, 0x50, 0xE2, 0x00, 0x60, 0x79, 0xE2, 0x00, 0x60,
+	 0x90, 0xE2, 0x01, 0x60, 0xD0, 0xE2, 0x01, 0x60, 0xF0, 0xE2, 0x01, 0x60, 0xB0, 0xE2, 0x26, 0x64,
+	 0x35, 0xFB, 0x01, 0x60, 0x30, 0x64, 0x0A, 0xA4, 0x38, 0xFB, 0x60, 0x45, 0x00, 0x60, 0xF8, 0x64,
+	 0x0A, 0xA4, 0x39, 0xFB, 0x35, 0xF1, 0x0A, 0x64, 0xC4, 0x84, 0x36, 0xFB, 0xC0, 0x84, 0x0A, 0xA4,
+	 0x37, 0xFB, 0x09, 0x60, 0x2A, 0x64, 0x99, 0xFB, 0x82, 0xFF, 0x92, 0xFF, 0x5C, 0x41, 0x5C, 0x46,
+	 0x5C, 0x47, 0x00, 0xE1, 0xA7, 0x60, 0x9B, 0x63, 0x0C, 0x60, 0x16, 0x64, 0xA0, 0xDD, 0x87, 0xFF,
+	 0x97, 0xFF, 0x0C, 0x60, 0x02, 0x64, 0x40, 0x5A, 0x06, 0xA4, 0x40, 0x5B, 0x5C, 0x5E, 0x5C, 0x51,
+	 0x1F, 0x60, 0xAA, 0x62, 0xA2, 0xD3, 0x65, 0xFB, 0x21, 0x60, 0xEC, 0x61, 0x27, 0x7C, 0xA1, 0xD9,
+	 0x25, 0x60, 0x2E, 0x63, 0x7F, 0xA3, 0xE3, 0x87, 0x00, 0x7F, 0x8A, 0xFB, 0x02, 0x60, 0x80, 0x66,
+	 0x22, 0x60, 0x22, 0x64, 0x77, 0x60, 0x77, 0x63, 0x00, 0xFA, 0x01, 0xFC, 0x00, 0xF0, 0x01, 0xF0,
+	 0xD0, 0x80, 0xD3, 0x80, 0x1E, 0x02, 0x1D, 0x02, 0x06, 0x60, 0x80, 0x65, 0x45, 0x4A, 0xAA, 0x46,
+	 0x00, 0xFC, 0x01, 0xFA, 0xAA, 0x46, 0x00, 0xF0, 0x2A, 0x41, 0x50, 0x65, 0xD3, 0x80, 0xCD, 0x84,
+	 0x13, 0x03, 0x0A, 0x60, 0x80, 0x65, 0x45, 0x4A, 0xAA, 0x46, 0x00, 0xFC, 0x01, 0xFA, 0xAA, 0x46,
+	 0x00, 0xF0, 0x65, 0x41, 0xC8, 0x65, 0xD3, 0x80, 0xCD, 0x84, 0x06, 0x03, 0x12, 0x60, 0x7F, 0x64,
+	 0x03, 0x00, 0x10, 0x65, 0x02, 0x60, 0x7F, 0x64, 0x65, 0x43, 0x87, 0xFD, 0x1B, 0x60, 0x72, 0x62,
+	 0xA2, 0xDD, 0x07, 0x61, 0xC5, 0x81, 0xE1, 0x85, 0xD4, 0x84, 0x8B, 0xFB, 0xDC, 0x84, 0x89, 0xFB,
+	 0x0C, 0xA4, 0x88, 0xFB, 0x1B, 0x60, 0x74, 0x62, 0xA2, 0xDB, 0xA2, 0x60, 0x58, 0x4E, 0x1F, 0x78,
+	 0xFF, 0xFF, 0xA2, 0x60, 0x58, 0x4E, 0x00, 0x78, 0xFF, 0xFF, 0x8B, 0xF1, 0x8A, 0xF3, 0x7C, 0x63,
+	 0x8D, 0xFB, 0x60, 0x46, 0x01, 0xFC, 0xDC, 0x84, 0xD0, 0x80, 0x00, 0xFA, 0xFA, 0x04, 0x8E, 0xFB,
+	 0x60, 0x46, 0x00, 0x64, 0x00, 0xFA, 0x63, 0x44, 0x80, 0x7F, 0x01, 0xFA, 0x8B, 0xF3, 0x8A, 0xF1,
+	 0xDC, 0x84, 0xD0, 0x84, 0x8C, 0xFB, 0x03, 0x60, 0x26, 0x61, 0xB3, 0x60, 0x58, 0x4D, 0x64, 0x78,
+	 0xFF, 0xFF, 0x66, 0x44, 0x2E, 0xFB, 0x82, 0xFF, 0x40, 0x42, 0x87, 0xFF, 0x8C, 0xF3, 0x94, 0xFB,
+	 0x00, 0x64, 0x12, 0x60, 0xC8, 0x63, 0xA3, 0xDB, 0x00, 0x64, 0x40, 0x50, 0x63, 0xFF, 0x66, 0xFF,
+	 0x65, 0xFF, 0x64, 0xFF, 0x61, 0xFF, 0x62, 0xFF, 0x49, 0x60, 0x02, 0xE1, 0x52, 0x60, 0x02, 0xE1,
+	 0x5B, 0x60, 0x02, 0xE1, 0x65, 0x60, 0x02, 0xE1, 0x6C, 0x60, 0x02, 0xE1, 0x76, 0x60, 0x02, 0xE1,
+	 0x41, 0x60, 0x02, 0xE1, 0x04, 0x65, 0x21, 0x60, 0x7E, 0x64, 0x44, 0xD3, 0xEA, 0x60, 0x58, 0x4E,
+	 0x78, 0x78, 0xFF, 0xFF, 0x1C, 0x60, 0x04, 0x65, 0x0C, 0x64, 0xA5, 0xDB, 0xA3, 0x60, 0xED, 0x64,
+	 0x80, 0xFB, 0x2D, 0xFF, 0x0A, 0x61, 0x41, 0x4B, 0x09, 0x60, 0x08, 0x61, 0xB3, 0x60, 0x58, 0x4D,
+	 0x64, 0x78, 0xFF, 0xFF, 0xF0, 0x67, 0x0E, 0xFA, 0x1B, 0x60, 0xE0, 0x62, 0x1B, 0x60, 0xC4, 0x64,
+	 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x2B, 0x41,
+	 0x4D, 0x8B, 0xFF, 0xFF, 0xE9, 0x02, 0x0A, 0x61, 0x41, 0x4B, 0x09, 0x60, 0x08, 0x61, 0xB3, 0x60,
+	 0x58, 0x4D, 0x64, 0x78, 0xFF, 0xFF, 0x1B, 0x60, 0xE0, 0x62, 0x1B, 0x60, 0xB8, 0x64, 0xA2, 0xDB,
+	 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x2B, 0x41, 0x4D, 0x8B,
+	 0xFF, 0xFF, 0xEB, 0x02, 0xEB, 0x60, 0x4E, 0x78, 0xFF, 0xFF, 0x00, 0xEA, 0x00, 0xEB, 0x50, 0x60,
+	 0x03, 0xEA, 0x51, 0x60, 0x13, 0xEA, 0x52, 0x60, 0x30, 0xEA, 0x53, 0x60, 0x40, 0xEA, 0x54, 0x60,
+	 0x52, 0xEA, 0x55, 0x60, 0x6D, 0xEA, 0x56, 0x60, 0x71, 0xEA, 0x57, 0x60, 0x8B, 0xEA, 0x58, 0x60,
+	 0x47, 0xEA, 0x59, 0x60, 0xA0, 0xEA, 0x5A, 0x60, 0xB2, 0xEA, 0x5B, 0x60, 0xC1, 0xEA, 0x5C, 0x60,
+	 0xD7, 0xEA, 0x5D, 0x60, 0xEB, 0xEA, 0x5E, 0x60, 0xA0, 0xEA, 0x50, 0x60, 0x36, 0xEB, 0x51, 0x60,
+	 0x37, 0xEB, 0x52, 0x60, 0x20, 0xEB, 0x53, 0x60, 0xE4, 0xEB, 0x54, 0x60, 0x34, 0xEB, 0x55, 0x60,
+	 0x58, 0xEB, 0x56, 0x60, 0x48, 0xEB, 0x57, 0x60, 0xD0, 0xEB, 0x58, 0x60, 0xC3, 0xEB, 0x59, 0x60,
+	 0xFC, 0xEB, 0x5A, 0x60, 0x34, 0xEB, 0x5B, 0x60, 0x58, 0xEB, 0x5C, 0x60, 0xC0, 0xEB, 0x5D, 0x60,
+	 0xD0, 0xEB, 0x5E, 0x60, 0x91, 0xEB, 0x00, 0xEA, 0x00, 0xEB, 0xE0, 0x60, 0x02, 0xEA, 0xE0, 0x60,
+	 0x03, 0xEB, 0xA0, 0x60, 0x00, 0xEB, 0xB0, 0x60, 0x00, 0xEB, 0xAB, 0x48, 0x40, 0x3B, 0x01, 0x00,
+	 0xFC, 0x01, 0x00, 0xEB, 0x03, 0x60, 0x02, 0x62, 0x62, 0x44, 0xA2, 0xDB, 0x0F, 0x64, 0x60, 0x7F,
+	 0xA0, 0x5A, 0x80, 0x60, 0x00, 0xEA, 0xA0, 0x60, 0x00, 0xEA, 0xD1, 0x60, 0x00, 0xEA, 0x3F, 0x40,
+	 0x40, 0x26, 0x08, 0x00, 0x00, 0x60, 0x18, 0x64, 0x00, 0x60, 0x00, 0x65, 0x94, 0x84, 0xA0, 0x50,
+	 0x1D, 0x60, 0x19, 0xE2, 0x24, 0x44, 0xFF, 0xB4, 0x04, 0xFB, 0x50, 0x60, 0x00, 0x64, 0x05, 0xFB,
+	 0x10, 0x60, 0x10, 0x75, 0xEB, 0x60, 0x84, 0x78, 0xFF, 0xFF, 0x80, 0xFF, 0x90, 0xFF, 0x98, 0xFF,
+	 0x23, 0x60, 0x5C, 0x63, 0x20, 0x44, 0xBD, 0xDB, 0x21, 0x44, 0xBD, 0xDB, 0x22, 0x44, 0xBD, 0xDB,
+	 0x23, 0x44, 0xBD, 0xDB, 0x24, 0x44, 0xBD, 0xDB, 0x25, 0x44, 0xBD, 0xDB, 0x26, 0x44, 0xBD, 0xDB,
+	 0x27, 0x44, 0xBD, 0xDB, 0x28, 0x44, 0xBD, 0xDB, 0x29, 0x44, 0xBD, 0xDB, 0x2A, 0x44, 0xBD, 0xDB,
+	 0x2B, 0x44, 0xBD, 0xDB, 0x2C, 0x44, 0xBD, 0xDB, 0x2D, 0x44, 0xBD, 0xDB, 0x2E, 0x44, 0xBD, 0xDB,
+	 0x2F, 0x44, 0xBD, 0xDB, 0x23, 0x60, 0x50, 0x64, 0xA0, 0xDD, 0x24, 0x60, 0x7C, 0x63, 0x23, 0x60,
+	 0x52, 0x64, 0xA0, 0xDD, 0x23, 0x60, 0x54, 0x63, 0x30, 0x44, 0xA3, 0xDB, 0x23, 0x60, 0x56, 0x63,
+	 0x31, 0x44, 0xA3, 0xDB, 0x23, 0x60, 0x58, 0x63, 0x32, 0x44, 0xA3, 0xDB, 0x23, 0x60, 0x5A, 0x63,
+	 0x33, 0x44, 0xA3, 0xDB, 0x81, 0xFF, 0x91, 0xFF, 0x58, 0x51, 0x48, 0x00, 0x82, 0xFF, 0x92, 0xFF,
+	 0x58, 0x51, 0x44, 0x00, 0x83, 0xFF, 0x93, 0xFF, 0x58, 0x51, 0x40, 0x00, 0x84, 0xFF, 0x94, 0xFF,
+	 0x58, 0x51, 0x3C, 0x00, 0x85, 0xFF, 0x95, 0xFF, 0x58, 0x51, 0x38, 0x00, 0x86, 0xFF, 0x96, 0xFF,
+	 0x58, 0x51, 0x34, 0x00, 0x87, 0xFF, 0x97, 0xFF, 0x58, 0x51, 0x30, 0x00, 0x80, 0xFF, 0x90, 0xFF,
+	 0x99, 0xFF, 0x23, 0x60, 0x50, 0x64, 0xA0, 0xD1, 0x30, 0x44, 0x64, 0x43, 0xBD, 0xDB, 0x31, 0x44,
+	 0xBD, 0xDB, 0x32, 0x44, 0xBD, 0xDB, 0x33, 0x44, 0xBD, 0xDB, 0x34, 0x44, 0xBD, 0xDB, 0x35, 0x44,
+	 0xBD, 0xDB, 0x36, 0x44, 0xBD, 0xDB, 0x37, 0x44, 0xBD, 0xDB, 0x38, 0x44, 0xBD, 0xDB, 0x39, 0x44,
+	 0xBD, 0xDB, 0x3A, 0x44, 0xBD, 0xDB, 0x3B, 0x44, 0xBD, 0xDB, 0x3C, 0x44, 0xBD, 0xDB, 0x3D, 0x44,
+	 0xBD, 0xDB, 0x3E, 0x44, 0xBD, 0xDB, 0x3F, 0x44, 0xBD, 0xDB, 0xE3, 0x60, 0x50, 0x64, 0x0A, 0xFB,
+	 0x40, 0x21, 0xFE, 0x01, 0xA1, 0xFF, 0xFF, 0xFF, 0x78, 0x01, 0xFF, 0xFF, 0x42, 0x50, 0x40, 0x53,
+	 0x23, 0x60, 0x52, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x40, 0x52, 0x33, 0x44, 0x32, 0x42, 0xA2, 0xDB,
+	 0xDA, 0x82, 0xA2, 0xDD, 0xDA, 0x83, 0x65, 0x44, 0xBD, 0xDB, 0x61, 0x44, 0xBD, 0xDB, 0x66, 0x44,
+	 0xBD, 0xDB, 0xBD, 0xD9, 0x30, 0x44, 0xBD, 0xDB, 0x99, 0xFF, 0xA4, 0x4C, 0xBD, 0xDB, 0xA5, 0x4C,
+	 0xBD, 0xDB, 0xA0, 0x4C, 0xBD, 0xDB, 0xA1, 0x4C, 0xBD, 0xDB, 0x98, 0xFF, 0x23, 0x60, 0x52, 0x64,
+	 0xA0, 0xDD, 0x23, 0x60, 0x54, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x40, 0x50, 0x23, 0x60, 0x58, 0x62,
+	 0xA2, 0xD3, 0xFF, 0xFF, 0x40, 0x52, 0x23, 0x60, 0x5A, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x40, 0x53,
+	 0x31, 0x41, 0x23, 0x60, 0x56, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x40, 0x51, 0x23, 0x60, 0x50, 0x62,
+	 0xA2, 0xD3, 0xFF, 0xFF, 0x60, 0x43, 0x20, 0x44, 0xBD, 0xDB, 0x21, 0x44, 0xBD, 0xDB, 0x22, 0x44,
+	 0xBD, 0xDB, 0x23, 0x44, 0xBD, 0xDB, 0x24, 0x44, 0xBD, 0xDB, 0x25, 0x44, 0xBD, 0xDB, 0x26, 0x44,
+	 0xBD, 0xDB, 0x27, 0x44, 0xBD, 0xDB, 0x28, 0x44, 0xBD, 0xDB, 0x29, 0x44, 0xBD, 0xDB, 0x2A, 0x44,
+	 0xBD, 0xDB, 0x2B, 0x44, 0xBD, 0xDB, 0x2C, 0x44, 0xBD, 0xDB, 0x2D, 0x44, 0xBD, 0xDB, 0x2E, 0x44,
+	 0xBD, 0xDB, 0x2F, 0x44, 0xBD, 0xDB, 0x23, 0x60, 0x50, 0x64, 0xA0, 0xDD, 0x61, 0x58, 0xFF, 0xFF,
+	 0x30, 0x44, 0x02, 0xA8, 0x00, 0xE1, 0x07, 0x02, 0x62, 0xFF, 0x63, 0xFF, 0x64, 0xFF, 0x65, 0xFF,
+	 0x66, 0xFF, 0xBF, 0xFE, 0xA1, 0xFF, 0x82, 0xFF, 0x88, 0xFF, 0x6C, 0x40, 0x41, 0xFF, 0xC4, 0xE2,
+	 0x43, 0xFF, 0x5C, 0x49, 0x08, 0xE1, 0xA5, 0x60, 0x5E, 0x78, 0xFF, 0xFF, 0xA1, 0xFF, 0x98, 0xFF,
+	 0x80, 0x3E, 0x9F, 0xFE, 0x03, 0x04, 0xA6, 0x60, 0x28, 0x78, 0xFF, 0xFF, 0xE2, 0xFE, 0x40, 0x05,
+	 0xE0, 0xFE, 0x5B, 0x05, 0xE1, 0xFE, 0xF2, 0x04, 0x29, 0x40, 0x08, 0x26, 0xEF, 0x01, 0x72, 0x44,
+	 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0x95, 0xF3, 0xE8, 0x85, 0xFF, 0xB7,
+	 0xE0, 0x84, 0xE0, 0x84, 0xB4, 0x85, 0x73, 0x44, 0xD4, 0x84, 0x10, 0x65, 0xD4, 0x80, 0xFF, 0xFF,
+	 0x26, 0x04, 0x3F, 0x40, 0x40, 0x26, 0x13, 0x00, 0x0B, 0x60, 0xF8, 0x62, 0xA2, 0xD1, 0x00, 0x60,
+	 0x10, 0x64, 0x90, 0x84, 0xA0, 0x50, 0xF8, 0xA2, 0xA2, 0xD1, 0x0A, 0x60, 0x19, 0x64, 0x90, 0x84,
+	 0xA0, 0x52, 0x06, 0xA2, 0xA2, 0xD1, 0x46, 0x60, 0x09, 0x64, 0x90, 0x84, 0xA0, 0x50, 0xD2, 0xF4,
+	 0x25, 0x60, 0x16, 0x7C, 0x63, 0x40, 0x01, 0x26, 0x08, 0x00, 0xA4, 0xD3, 0xFF, 0xFF, 0x01, 0xB4,
+	 0xFF, 0xFF, 0x03, 0x02, 0xAD, 0x4F, 0xFE, 0xB4, 0xA0, 0x5D, 0x02, 0xEE, 0xBD, 0xFE, 0xBE, 0x01,
+	 0x21, 0x46, 0x5E, 0x62, 0x9A, 0xFF, 0x07, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x06, 0x25, 0x10, 0x00,
+	 0xA2, 0xDC, 0x7A, 0xDC, 0x7A, 0xDC, 0x62, 0x62, 0x01, 0x5D, 0x7A, 0xDC, 0x7A, 0xDC, 0x7A, 0xDC,
+	 0x7A, 0xDC, 0x44, 0xFF, 0x06, 0x25, 0x04, 0x00, 0x0E, 0xE1, 0x02, 0x60, 0x01, 0xE1, 0x9E, 0x01,
+	 0x62, 0xFF, 0xC4, 0xE2, 0x41, 0xFF, 0x0A, 0xE1, 0x99, 0x01, 0xC8, 0x74, 0xCD, 0xE2, 0x29, 0x44,
+	 0x08, 0xBC, 0x40, 0x49, 0x05, 0xE1, 0x25, 0x60, 0x18, 0x63, 0xA3, 0xD3, 0xD2, 0xF3, 0x06, 0x18,
+	 0x28, 0x40, 0x08, 0x2A, 0x05, 0x00, 0x28, 0x40, 0x48, 0x36, 0x02, 0x00, 0x02, 0xBC, 0xD2, 0xFB,
+	 0x3F, 0x40, 0x01, 0x2B, 0xFF, 0xFF, 0xA1, 0xFF, 0x67, 0x4C, 0x06, 0x61, 0xCD, 0x81, 0x04, 0x25,
+	 0x30, 0x00, 0x87, 0x4C, 0xFB, 0x02, 0x28, 0x40, 0x40, 0x2B, 0x02, 0x00, 0x15, 0x60, 0x6F, 0x6B,
+	 0xF3, 0x60, 0xA0, 0x64, 0x04, 0x25, 0x25, 0x00, 0x80, 0x4C, 0x30, 0x64, 0x3A, 0xDB, 0x44, 0xFF,
+	 0x04, 0x25, 0x1F, 0x00, 0x04, 0x60, 0x00, 0x65, 0x25, 0x44, 0x37, 0x36, 0xB4, 0x84, 0x6E, 0x36,
+	 0xB4, 0x84, 0x80, 0x4E, 0x24, 0x41, 0x04, 0x25, 0x14, 0x00, 0x61, 0x4C, 0x64, 0xA1, 0x61, 0x54,
+	 0xA1, 0xFF, 0xFF, 0xFF, 0x04, 0x25, 0x0D, 0x00, 0x67, 0x4E, 0x07, 0x64, 0x1C, 0xFB, 0x00, 0xE1,
+	 0x02, 0x60, 0x01, 0xE1, 0x53, 0x01, 0x33, 0xF3, 0xFD, 0x11, 0xFC, 0x18, 0x40, 0x64, 0x3A, 0xDB,
+	 0x0A, 0x00, 0xC4, 0xE2, 0x27, 0x44, 0x20, 0x2A, 0x04, 0x00, 0x42, 0x64, 0x3A, 0xDB, 0x67, 0x4C,
+	 0x02, 0x00, 0x41, 0x64, 0x3A, 0xDB, 0x62, 0xFF, 0x08, 0xE1, 0xE2, 0xFE, 0x72, 0x52, 0x5C, 0x49,
+	 0x32, 0x7B, 0x4D, 0xE2, 0x3B, 0x01, 0x08, 0xE1, 0x39, 0x01, 0xA1, 0xFF, 0x98, 0xFF, 0x80, 0x3E,
+	 0x00, 0x60, 0x46, 0x74, 0xCD, 0xE2, 0x04, 0xE1, 0x02, 0x60, 0x00, 0xE1, 0x3F, 0x44, 0x40, 0x26,
+	 0x0B, 0x00, 0x01, 0x2A, 0x05, 0x00, 0x42, 0x60, 0x09, 0xE0, 0x60, 0x60, 0x1C, 0xE0, 0x04, 0x00,
+	 0x42, 0x60, 0x09, 0xE0, 0x80, 0x60, 0x1C, 0xE0, 0x04, 0x29, 0xFE, 0x01, 0xC4, 0xE2, 0x43, 0x64,
+	 0x3A, 0xDB, 0x83, 0xF3, 0xFF, 0xFF, 0x60, 0x41, 0x3F, 0x44, 0x02, 0x27, 0x84, 0x00, 0x20, 0x2B,
+	 0xFF, 0x01, 0x80, 0xE1, 0x95, 0x60, 0x80, 0xE7, 0x61, 0x40, 0x40, 0x2B, 0x0D, 0x00, 0x05, 0x63,
+	 0xA7, 0x60, 0x58, 0x4F, 0x1D, 0x78, 0xFF, 0xFF, 0x28, 0x63, 0xFF, 0xFF, 0xFE, 0x1F, 0x01, 0x63,
+	 0xA7, 0x60, 0x58, 0x4F, 0x1D, 0x78, 0xFF, 0xFF, 0xFF, 0xB1, 0xCD, 0x81, 0xE1, 0x85, 0x1E, 0x60,
+	 0xA2, 0x64, 0x44, 0xD1, 0xFF, 0xFF, 0x64, 0x43, 0xA7, 0x60, 0x58, 0x4F, 0x1D, 0x78, 0xFF, 0xFF,
+	 0x00, 0x60, 0x00, 0x63, 0xA7, 0x60, 0x58, 0x4F, 0x1D, 0x78, 0xFF, 0xFF, 0x1E, 0x60, 0xBE, 0x61,
+	 0x21, 0x60, 0x72, 0x62, 0xA2, 0xD3, 0x45, 0xD1, 0x47, 0xBC, 0xE0, 0x84, 0x62, 0x45, 0x64, 0x5F,
+	 0xE8, 0x83, 0xA7, 0x60, 0x58, 0x4F, 0x1D, 0x78, 0xFF, 0xFF, 0x82, 0xF3, 0xCD, 0xE2, 0x60, 0x54,
+	 0x04, 0xE1, 0x04, 0x29, 0xFE, 0x01, 0xC4, 0xE2, 0x15, 0x60, 0xA2, 0xE7, 0x38, 0x69, 0xFF, 0xFF,
+	 0x68, 0x44, 0x01, 0x16, 0xFD, 0x01, 0x01, 0x2A, 0x36, 0x00, 0x03, 0x60, 0x80, 0x7C, 0xA3, 0x83,
+	 0x21, 0x60, 0x72, 0x62, 0xA2, 0xD1, 0x43, 0xBB, 0xB3, 0x83, 0x95, 0x60, 0x80, 0xE7, 0xA7, 0x60,
+	 0x58, 0x4F, 0x1D, 0x78, 0xFF, 0xFF, 0xE3, 0x83, 0x15, 0x60, 0xA2, 0xE7, 0x38, 0x69, 0xFF, 0xFF,
+	 0x68, 0x41, 0x01, 0x16, 0xFD, 0x01, 0x63, 0x47, 0x61, 0x40, 0x01, 0x2A, 0x03, 0x00, 0x00, 0x3A,
+	 0xCC, 0x84, 0x02, 0x00, 0x07, 0x3A, 0xDC, 0x84, 0xFF, 0xB4, 0xA5, 0xDB, 0x60, 0x47, 0xE8, 0x84,
+	 0x47, 0x65, 0x21, 0x60, 0x72, 0x62, 0xA2, 0xD3, 0xB4, 0x85, 0xB4, 0x83, 0x80, 0xE1, 0x95, 0x60,
+	 0x80, 0xE7, 0xA7, 0x60, 0x58, 0x4F, 0x1D, 0x78, 0xFF, 0xFF, 0x82, 0xF3, 0xCD, 0xE2, 0x60, 0x54,
+	 0x04, 0x29, 0xFE, 0x01, 0xC4, 0xE2, 0x83, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x2B, 0x04, 0x00,
+	 0xA6, 0x60, 0xF6, 0x78, 0xFF, 0xFF, 0xFF, 0x01, 0x83, 0xF3, 0x80, 0xE1, 0xCC, 0x84, 0xE0, 0x85,
+	 0x15, 0x60, 0xA2, 0xE7, 0x1D, 0x60, 0xDE, 0x64, 0x58, 0x4F, 0x4F, 0x00, 0x1D, 0x60, 0xFA, 0x64,
+	 0x58, 0x4F, 0x4B, 0x00, 0x1E, 0x60, 0x16, 0x64, 0x58, 0x4F, 0x47, 0x00, 0x1E, 0x60, 0x32, 0x64,
+	 0x58, 0x4F, 0x43, 0x00, 0x1E, 0x60, 0x4E, 0x64, 0x58, 0x4F, 0x3F, 0x00, 0x1E, 0x60, 0x6A, 0x64,
+	 0x58, 0x4F, 0x3B, 0x00, 0x1E, 0x60, 0x86, 0x64, 0x58, 0x4F, 0x37, 0x00, 0x01, 0x68, 0xFF, 0x6A,
+	 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x3F, 0x44, 0x20, 0x27, 0x00, 0x00, 0x3F, 0x40, 0x40, 0x26,
+	 0x08, 0x00, 0x00, 0x60, 0x18, 0x64, 0x00, 0x60, 0x00, 0x65, 0x94, 0x84, 0xA0, 0x50, 0x1D, 0x60,
+	 0x19, 0xE2, 0xC4, 0xE2, 0x00, 0x63, 0x82, 0xFD, 0x32, 0x7B, 0x4D, 0xE2, 0xBF, 0xFE, 0xC4, 0xE2,
+	 0x41, 0xFF, 0xE0, 0xFE, 0xE1, 0xFE, 0xE2, 0xFE, 0x43, 0xFF, 0x44, 0xFF, 0x46, 0xFF, 0x84, 0xF3,
+	 0x62, 0xFF, 0x60, 0x40, 0x05, 0x36, 0x2D, 0xFF, 0x07, 0x36, 0xD5, 0xFE, 0x08, 0xE1, 0x88, 0x60,
+	 0x85, 0x71, 0x8D, 0xE2, 0xA5, 0x60, 0x5E, 0x78, 0xFF, 0xFF, 0x50, 0xEC, 0x63, 0x4A, 0xFF, 0xFF,
+	 0x01, 0x16, 0xFE, 0x01, 0x40, 0xEC, 0x2F, 0x58, 0xFF, 0xFF, 0x44, 0xD3, 0x80, 0x7C, 0x60, 0x48,
+	 0x60, 0x47, 0x00, 0x7F, 0xB0, 0x8A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x30, 0x44, 0x02, 0xA8, 0x00, 0xE1, 0x02, 0x02, 0xA1, 0xFF, 0xFF, 0xFF, 0x82, 0xFF, 0x88, 0xFF,
+	 0x48, 0xE2, 0x01, 0x70, 0xAE, 0xF1, 0x00, 0x6B, 0x89, 0xFF, 0x64, 0x54, 0x88, 0xFF, 0x9F, 0xFE,
+	 0x02, 0x05, 0x64, 0x44, 0x60, 0x54, 0xCD, 0xE2, 0xC2, 0x64, 0x3A, 0xDB, 0xBC, 0xFF, 0xB5, 0xFF,
+	 0x1D, 0xFF, 0x26, 0x44, 0x02, 0xB4, 0x40, 0x46, 0x3C, 0x44, 0x00, 0xBC, 0xFF, 0xFF, 0x06, 0x03,
+	 0x27, 0x40, 0x26, 0x22, 0x03, 0x00, 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0x27, 0x44, 0x20, 0x2A,
+	 0x04, 0x00, 0xA0, 0x60, 0x00, 0xEA, 0xB0, 0x60, 0x00, 0xEA, 0x5C, 0x4D, 0x27, 0x44, 0x18, 0xB4,
+	 0x40, 0x47, 0x00, 0xE1, 0x6C, 0x40, 0x44, 0xE2, 0xC4, 0xE2, 0x47, 0xFF, 0xB7, 0xFF, 0xB4, 0xFF,
+	 0x32, 0xF1, 0x08, 0x29, 0x09, 0x00, 0x64, 0x40, 0x07, 0x22, 0x06, 0x00, 0x43, 0xFF, 0x27, 0x44,
+	 0x10, 0xBC, 0x40, 0x47, 0x00, 0x64, 0x32, 0xFB, 0x31, 0x41, 0x3C, 0x44, 0x01, 0xB1, 0x00, 0xBC,
+	 0x0A, 0x02, 0x09, 0x03, 0x32, 0xF3, 0x00, 0x7C, 0x01, 0xB4, 0xFF, 0xFF, 0x04, 0x03, 0x32, 0xF9,
+	 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0x48, 0x60, 0x2D, 0x7D, 0x08, 0x60, 0x00, 0x6B, 0x00, 0x64,
+	 0x33, 0xFB, 0x0C, 0x60, 0x16, 0x64, 0xA0, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0x32, 0xF3, 0x08, 0x29,
+	 0x0A, 0x00, 0x60, 0x40, 0x07, 0x22, 0x07, 0x00, 0xFE, 0xB4, 0x32, 0xFB, 0x27, 0x44, 0x10, 0xBC,
+	 0xF7, 0xB4, 0x40, 0x47, 0x43, 0xFF, 0x00, 0x64, 0x3A, 0xDB, 0x01, 0x60, 0x08, 0xE1, 0x31, 0x40,
+	 0x01, 0x2A, 0x04, 0x00, 0x00, 0x64, 0x33, 0xFB, 0x01, 0x60, 0x0A, 0xE1, 0xE5, 0xFE, 0x13, 0x05,
+	 0x27, 0x44, 0x10, 0x26, 0x13, 0x00, 0x9F, 0xFE, 0x02, 0x04, 0x02, 0xE1, 0x06, 0x00, 0x3E, 0xE1,
+	 0x31, 0x44, 0x01, 0x2A, 0x02, 0x00, 0x04, 0x0A, 0xBF, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x81, 0x3E,
+	 0xAF, 0x60, 0x19, 0x78, 0xFF, 0xFF, 0xA8, 0x60, 0x09, 0x78, 0xFF, 0xFF, 0x27, 0x44, 0x08, 0x26,
+	 0xFF, 0xFF, 0xBF, 0x60, 0x2A, 0x78, 0xFF, 0xFF, 0x48, 0xF3, 0x32, 0xF1, 0x00, 0x63, 0x64, 0x40,
+	 0x03, 0x22, 0x3D, 0x00, 0x31, 0x40, 0x08, 0x26, 0xF4, 0x01, 0xCD, 0xE2, 0x84, 0xE1, 0x70, 0x41,
+	 0xAD, 0x80, 0x71, 0x40, 0x80, 0x27, 0xED, 0x12, 0x03, 0x03, 0xBF, 0x60, 0x7C, 0x78, 0xFF, 0xFF,
+	 0xA1, 0xFF, 0xFF, 0xFF, 0xC4, 0xE2, 0x32, 0xFD, 0x60, 0x40, 0x01, 0x2A, 0xDF, 0x01, 0x00, 0x63,
+	 0x32, 0xFD, 0x6C, 0x40, 0x3C, 0x46, 0x3E, 0xF2, 0x2A, 0xF0, 0x27, 0x41, 0x44, 0x48, 0x20, 0xB9,
+	 0x01, 0xB4, 0xF7, 0xB1, 0x0A, 0x03, 0x64, 0x40, 0x08, 0x27, 0x07, 0x00, 0x0F, 0x60, 0x92, 0x63,
+	 0x00, 0x64, 0x45, 0xFB, 0x46, 0xFB, 0xBD, 0xDB, 0xA3, 0xDB, 0xCB, 0x0A, 0x41, 0x47, 0x3F, 0x40,
+	 0x01, 0x2B, 0x04, 0x00, 0xF6, 0xFE, 0x67, 0x4C, 0x05, 0x60, 0x69, 0x6B, 0x02, 0xE1, 0x01, 0x60,
+	 0x08, 0xE1, 0xF0, 0xFE, 0x84, 0xFF, 0xBF, 0x60, 0xAD, 0x64, 0x40, 0x42, 0x82, 0xFF, 0xE5, 0xFE,
+	 0x03, 0x04, 0xAC, 0x60, 0x41, 0x78, 0xFF, 0xFF, 0xE4, 0xFE, 0x0A, 0x04, 0x1D, 0xFF, 0x00, 0xEB,
+	 0x60, 0x7F, 0xA0, 0x5A, 0x80, 0x60, 0x00, 0xEA, 0xA0, 0x60, 0x00, 0xEA, 0xD1, 0x60, 0x00, 0xEA,
+	 0x43, 0xFF, 0xE6, 0xFE, 0x03, 0x05, 0xA7, 0x60, 0x9B, 0x78, 0xFF, 0xFF, 0x3C, 0x44, 0x60, 0x46,
+	 0x0F, 0xF0, 0x40, 0x42, 0x64, 0x40, 0x01, 0x2A, 0x03, 0x00, 0xAB, 0x60, 0x03, 0x78, 0xFF, 0xFF,
+	 0x0B, 0x64, 0x3A, 0xDB, 0x1C, 0x42, 0x22, 0x46, 0x13, 0xF2, 0xFF, 0x65, 0x60, 0x47, 0x2A, 0xF2,
+	 0x40, 0x45, 0x40, 0x48, 0x04, 0x2B, 0x17, 0x00, 0x16, 0xF2, 0x1D, 0xF2, 0x40, 0x43, 0x0F, 0xF2,
+	 0x40, 0x44, 0x25, 0x5E, 0x3F, 0x40, 0x01, 0x27, 0x40, 0x45, 0x0F, 0x64, 0x14, 0xF0, 0x35, 0xF2,
+	 0xA0, 0x82, 0x0F, 0xB4, 0xCA, 0x85, 0xD4, 0x80, 0x10, 0xF2, 0x01, 0x02, 0x2B, 0xFA, 0x27, 0x44,
+	 0x40, 0xBC, 0x40, 0x47, 0x13, 0x00, 0x17, 0xF2, 0x2C, 0xF0, 0x40, 0x43, 0x1B, 0xF2, 0x1D, 0xFA,
+	 0x40, 0x44, 0x64, 0x40, 0x01, 0x2A, 0x02, 0x00, 0xAB, 0xFC, 0x05, 0x00, 0x28, 0x40, 0xA4, 0x36,
+	 0x02, 0x00, 0x11, 0xF2, 0x2B, 0xFA, 0x27, 0x44, 0xBF, 0xB4, 0x40, 0x47, 0x28, 0x40, 0x40, 0x2B,
+	 0xFF, 0xFF, 0xAF, 0x60, 0x2E, 0x78, 0xFF, 0xFF, 0x22, 0x46, 0x2C, 0xF0, 0x27, 0x44, 0xDF, 0xB4,
+	 0x40, 0x47, 0xB5, 0xFF, 0xBC, 0xFF, 0x47, 0xFF, 0xB7, 0xFF, 0xB4, 0xFF, 0x48, 0x60, 0x2D, 0x7D,
+	 0x08, 0x60, 0x00, 0x6B, 0x64, 0x40, 0x01, 0x2A, 0x01, 0x00, 0x13, 0x00, 0x2A, 0xF0, 0x01, 0x65,
+	 0x64, 0x40, 0xA4, 0x3A, 0x04, 0x65, 0x27, 0x44, 0x34, 0x87, 0x36, 0xF3, 0xB4, 0xFF, 0x60, 0x5B,
+	 0x4D, 0xE2, 0x04, 0x64, 0x3A, 0xDB, 0x01, 0x60, 0x0A, 0xE1, 0x2B, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF,
+	 0x81, 0x3E, 0x06, 0x64, 0x3A, 0xDB, 0x22, 0x46, 0x01, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0xBF, 0x60,
+	 0x85, 0x78, 0xFF, 0xFF, 0xB5, 0xFF, 0xA1, 0xFF, 0x6C, 0x40, 0x3F, 0x40, 0x01, 0x2B, 0x03, 0x00,
+	 0x67, 0x4C, 0x05, 0x60, 0x69, 0x6B, 0x02, 0xE1, 0x01, 0x60, 0x08, 0xE1, 0xC4, 0xE2, 0x08, 0x64,
+	 0x3A, 0xDB, 0xF0, 0xFE, 0x25, 0x46, 0x01, 0xF2, 0x61, 0x45, 0xD4, 0x9E, 0x21, 0x46, 0x16, 0xFA,
+	 0x2A, 0x44, 0x72, 0x45, 0x24, 0xFA, 0x95, 0xF3, 0x06, 0x04, 0xE4, 0xE2, 0xDC, 0x9C, 0x29, 0x40,
+	 0x01, 0x26, 0x64, 0x44, 0x95, 0xF9, 0x25, 0xFA, 0x96, 0xF3, 0x02, 0x04, 0xDC, 0x84, 0x96, 0xFB,
+	 0x28, 0xFA, 0x97, 0xF3, 0x02, 0x04, 0xDC, 0x84, 0x97, 0xFB, 0x29, 0xFA, 0x2D, 0x44, 0x04, 0x2A,
+	 0x06, 0x00, 0x28, 0x40, 0xA4, 0x36, 0x03, 0x00, 0xA9, 0x60, 0xC9, 0x78, 0xFF, 0xFF, 0x94, 0xFC,
+	 0x1F, 0x60, 0x9A, 0x65, 0xA5, 0xD1, 0x28, 0x44, 0x08, 0x2A, 0x51, 0x00, 0x03, 0x2B, 0x01, 0x00,
+	 0x4E, 0x00, 0x64, 0x40, 0x00, 0x36, 0x4B, 0x00, 0x32, 0xF2, 0x2F, 0xF0, 0x50, 0xFE, 0x01, 0x2A,
+	 0x03, 0x00, 0x01, 0x61, 0x8F, 0xF3, 0x31, 0x00, 0xD0, 0x80, 0x33, 0xF2, 0x30, 0xF0, 0x34, 0xF2,
+	 0xD0, 0x80, 0x31, 0xF0, 0xFF, 0xFF, 0xD0, 0x80, 0x60, 0x47, 0x34, 0x0C, 0xFF, 0xB4, 0x12, 0x60,
+	 0xCE, 0x65, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0xFF, 0xFF, 0x31, 0x18, 0x60, 0x43, 0x50, 0xFE,
+	 0x66, 0x41, 0x32, 0xF0, 0x63, 0x46, 0x03, 0xF2, 0x61, 0x46, 0xD0, 0x80, 0x33, 0xF0, 0x63, 0x46,
+	 0x04, 0xF2, 0x61, 0x46, 0xD0, 0x80, 0x34, 0xF0, 0x63, 0x46, 0x05, 0xF2, 0xFF, 0xFF, 0xD0, 0x80,
+	 0xFF, 0xFF, 0x04, 0x0C, 0x00, 0xF2, 0x61, 0x46, 0x1A, 0x18, 0xE8, 0x01, 0x06, 0xF0, 0x8F, 0xF3,
+	 0x61, 0x46, 0x02, 0x61, 0x64, 0x40, 0x02, 0x2A, 0x12, 0x00, 0xFC, 0xA0, 0xFF, 0xFF, 0x04, 0x0E,
+	 0x61, 0x44, 0x14, 0xFA, 0x11, 0xFC, 0x0B, 0x00, 0x2C, 0xF2, 0x2F, 0xFA, 0x2D, 0xF2, 0x30, 0xFA,
+	 0x2E, 0xF2, 0x31, 0xFA, 0x1D, 0xFF, 0x26, 0x44, 0x02, 0xBC, 0x40, 0x46, 0x20, 0x00, 0x26, 0x43,
+	 0x84, 0xBB, 0xFC, 0xB3, 0x21, 0x46, 0x01, 0x5D, 0x0F, 0xFC, 0x5C, 0x46, 0x25, 0x44, 0x06, 0xFA,
+	 0x05, 0xFF, 0x27, 0x44, 0x01, 0x2A, 0x13, 0x00, 0x50, 0xFE, 0x28, 0x40, 0x08, 0x3A, 0x12, 0x00,
+	 0x2F, 0xF2, 0x30, 0xF0, 0x60, 0x43, 0x31, 0xF2, 0x22, 0x46, 0x64, 0x41, 0x2C, 0xF0, 0x2D, 0xF0,
+	 0xD3, 0x80, 0x2E, 0xF0, 0xD1, 0x80, 0xD0, 0x80, 0x27, 0x44, 0x09, 0x0C, 0x03, 0x00, 0x27, 0x44,
+	 0x06, 0x22, 0x05, 0x00, 0xB8, 0xB4, 0x40, 0x47, 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0xD4, 0x64,
+	 0x40, 0x48, 0x0D, 0x64, 0x3A, 0xDB, 0x21, 0x46, 0x1C, 0xF2, 0x62, 0xF1, 0xFF, 0xB4, 0xD0, 0x80,
+	 0xFF, 0xFF, 0x01, 0x06, 0x64, 0x44, 0x40, 0x45, 0x0A, 0x36, 0x70, 0x64, 0x14, 0x36, 0x38, 0x64,
+	 0x37, 0x3A, 0x03, 0x00, 0x04, 0x7F, 0x40, 0x45, 0x15, 0x64, 0x6E, 0x3A, 0x03, 0x00, 0x84, 0x7F,
+	 0x40, 0x45, 0x0B, 0x64, 0x40, 0x44, 0x00, 0x63, 0x28, 0x44, 0xA4, 0x36, 0x07, 0x00, 0x04, 0x2B,
+	 0x05, 0x00, 0x30, 0xF3, 0x24, 0x45, 0xD4, 0x84, 0xCA, 0x65, 0xD4, 0x83, 0xD4, 0x64, 0x1A, 0x00,
+	 0x0F, 0x64, 0x3A, 0xDB, 0x21, 0x46, 0x70, 0x63, 0x1C, 0xF2, 0xCA, 0x65, 0x40, 0x45, 0x0A, 0x36,
+	 0x70, 0x64, 0x14, 0x36, 0x38, 0x64, 0x37, 0x3A, 0x03, 0x00, 0x04, 0x7F, 0x40, 0x45, 0x15, 0x64,
+	 0x6E, 0x3A, 0x03, 0x00, 0x84, 0x7F, 0x40, 0x45, 0x0B, 0x64, 0x40, 0x44, 0x2B, 0xF2, 0xC4, 0x85,
+	 0xD4, 0x83, 0xC4, 0x64, 0x40, 0x48, 0x2F, 0xF0, 0xB0, 0xF0, 0xB1, 0xF2, 0x00, 0xE1, 0xA1, 0xFF,
+	 0xFF, 0xFF, 0x80, 0x4E, 0x83, 0x4C, 0x9A, 0xFF, 0x84, 0x4C, 0x85, 0x4C, 0x81, 0x4C, 0xA1, 0xFF,
+	 0x98, 0xFF, 0x87, 0x4F, 0x87, 0x4C, 0x87, 0x4F, 0x87, 0x4D, 0x87, 0x4C, 0x01, 0x08, 0x01, 0x00,
+	 0xFF, 0xFF, 0x87, 0x4C, 0x87, 0x4C, 0x87, 0x4C, 0x87, 0x4C, 0xFF, 0xFF, 0xFF, 0xFF, 0x6A, 0x44,
+	 0xBC, 0xFF, 0xC4, 0xE2, 0x0C, 0x74, 0x04, 0xE1, 0xA1, 0xFF, 0x35, 0xF3, 0xC4, 0xE2, 0x60, 0x54,
+	 0x89, 0xFF, 0x13, 0x74, 0x88, 0xFF, 0xB5, 0xFF, 0x47, 0xFF, 0x29, 0x44, 0xF7, 0xB4, 0x40, 0x49,
+	 0xB7, 0xFF, 0xB4, 0xFF, 0x48, 0x60, 0x2D, 0x7D, 0x08, 0x60, 0x00, 0x6B, 0x27, 0x44, 0x01, 0x2A,
+	 0x05, 0x00, 0xFE, 0xB4, 0x40, 0x47, 0xA8, 0x60, 0x89, 0x78, 0xFF, 0xFF, 0xA7, 0x60, 0x8E, 0x78,
+	 0xFF, 0xFF, 0x28, 0x40, 0xB4, 0x3A, 0x09, 0x00, 0x27, 0x44, 0x07, 0x22, 0x05, 0x00, 0xF8, 0xB4,
+	 0x40, 0x47, 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0x9B, 0x01, 0x28, 0x44, 0xD4, 0x36, 0x03, 0x00,
+	 0xAA, 0x60, 0xEA, 0x78, 0xFF, 0xFF, 0x48, 0xE2, 0x27, 0x44, 0xFB, 0xB4, 0x40, 0x47, 0x21, 0x60,
+	 0x98, 0x63, 0xA3, 0xD3, 0xB5, 0x60, 0x58, 0x4D, 0xE3, 0x78, 0xFF, 0xFF, 0x34, 0xFB, 0x1C, 0x42,
+	 0x22, 0x46, 0x2A, 0xF0, 0xF7, 0x60, 0xFF, 0x64, 0xA0, 0x84, 0xA2, 0xDA, 0x60, 0x40, 0x40, 0x2B,
+	 0xCC, 0x00, 0x22, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x22, 0x26, 0x42, 0x00, 0x01, 0x26, 0x03, 0x00,
+	 0x04, 0x26, 0x07, 0x00, 0xC2, 0x00, 0x04, 0x2B, 0xC0, 0x00, 0x88, 0xF3, 0xFF, 0xFF, 0x60, 0x46,
+	 0x01, 0x00, 0x07, 0xF4, 0x47, 0xF2, 0xFF, 0xFF, 0xDC, 0x84, 0x47, 0xFA, 0x0D, 0x60, 0x3E, 0x62,
+	 0x80, 0xFF, 0xC4, 0x60, 0x78, 0x44, 0x02, 0xA4, 0xA2, 0xDB, 0x7D, 0x78, 0xFF, 0xFF, 0x82, 0xFF,
+	 0x88, 0xF3, 0x66, 0x5C, 0xD0, 0x80, 0x00, 0x7C, 0x07, 0x03, 0x66, 0x43, 0x22, 0x46, 0x22, 0xF2,
+	 0x63, 0x46, 0x60, 0x40, 0x01, 0x2A, 0x01, 0x00, 0x3C, 0xF1, 0x47, 0xF0, 0x64, 0x41, 0x64, 0x47,
+	 0xFF, 0xB4, 0x60, 0x5F, 0x20, 0xBC, 0x80, 0x26, 0x80, 0xAC, 0x60, 0x47, 0x22, 0x46, 0x3A, 0xFA,
+	 0x64, 0x44, 0x20, 0x7F, 0x34, 0x94, 0x3B, 0xFA, 0x08, 0x60, 0x00, 0xEA, 0x0F, 0x64, 0x60, 0x7F,
+	 0xA0, 0x5A, 0x80, 0x60, 0x00, 0xEA, 0xA0, 0x60, 0x00, 0xEA, 0xD1, 0x60, 0x00, 0xEA, 0x85, 0x00,
+	 0x2A, 0xF2, 0x00, 0x60, 0x7C, 0x62, 0x60, 0x40, 0x40, 0x2B, 0x27, 0x00, 0xA2, 0xD3, 0x00, 0x61,
+	 0x60, 0xFE, 0xA0, 0xD3, 0xDE, 0x82, 0xA2, 0xD1, 0xFF, 0xFF, 0x20, 0xFE, 0x64, 0x5F, 0xDC, 0x84,
+	 0xF1, 0x81, 0xC0, 0x2B, 0x04, 0x00, 0x80, 0x2A, 0x02, 0x00, 0x7F, 0xA4, 0xDC, 0x84, 0xFF, 0x3B,
+	 0x03, 0x00, 0x60, 0x47, 0xDC, 0x87, 0x01, 0x61, 0xC0, 0x80, 0x00, 0x36, 0xDC, 0x84, 0x4E, 0xDB,
+	 0x60, 0xFE, 0xDA, 0x82, 0xA2, 0xD1, 0xFF, 0xFF, 0xC1, 0x84, 0xF0, 0x22, 0x10, 0xA4, 0xF0, 0x2A,
+	 0x01, 0x00, 0x00, 0x64, 0xA2, 0xDB, 0xFF, 0xFF, 0x20, 0xFE, 0x00, 0x60, 0x7C, 0x62, 0xA2, 0xD3,
+	 0xFF, 0xFF, 0xA0, 0xD3, 0x5A, 0xD1, 0x3A, 0xFA, 0x3B, 0xF8, 0x74, 0x62, 0xA2, 0xD0, 0xFF, 0xFF,
+	 0x64, 0x44, 0xE0, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xE1, 0x7F, 0x5A, 0xD0, 0xA0, 0x5A, 0x64, 0x44,
+	 0xE2, 0x7F, 0xA0, 0x5A, 0x00, 0x60, 0x80, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0xA0, 0xD1, 0x5A, 0xD1,
+	 0x64, 0x45, 0x64, 0x44, 0xE3, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xE4, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A,
+	 0x64, 0x44, 0xE5, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xE6, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44,
+	 0xE7, 0x7F, 0xA0, 0x5A, 0x65, 0x40, 0x0D, 0x3A, 0x1C, 0x00, 0x64, 0x47, 0xE8, 0x7F, 0x5A, 0xD1,
+	 0xA0, 0x5A, 0x64, 0x44, 0xE9, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xEA, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A,
+	 0x64, 0x44, 0xEB, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xEC, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44,
+	 0xED, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xEE, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xEF, 0x7F,
+	 0xA0, 0x5A, 0x08, 0x60, 0x00, 0xEA, 0x65, 0x44, 0x02, 0xA4, 0x60, 0x7F, 0xA0, 0x5A, 0x80, 0x60,
+	 0x00, 0xEA, 0xA0, 0x60, 0x00, 0xEA, 0xD1, 0x60, 0x00, 0xEA, 0x0B, 0xF2, 0xFF, 0xFF, 0x7F, 0xB4,
+	 0x0C, 0xF0, 0x04, 0x02, 0x64, 0x46, 0x00, 0xF0, 0x04, 0x64, 0x22, 0x46, 0x03, 0xFA, 0x60, 0x41,
+	 0x64, 0x46, 0x01, 0xF2, 0xFC, 0xA1, 0x61, 0x45, 0xD4, 0x84, 0xFF, 0xFF, 0x08, 0x02, 0x00, 0xF0,
+	 0x04, 0x63, 0x64, 0x46, 0x01, 0xF2, 0x22, 0x46, 0x1A, 0xFA, 0x03, 0xFC, 0x02, 0x00, 0x22, 0x46,
+	 0x1A, 0xFA, 0x35, 0xF2, 0x04, 0xF8, 0xDC, 0x84, 0x35, 0xFA, 0x14, 0xF2, 0x0F, 0xB5, 0x0F, 0xB4,
+	 0xCC, 0x84, 0x94, 0x80, 0x04, 0x60, 0x00, 0x65, 0x2A, 0xF2, 0x01, 0x02, 0x94, 0x84, 0x2A, 0xFA,
+	 0x95, 0xFC, 0x06, 0x00, 0xC4, 0x3A, 0x07, 0x00, 0x27, 0x44, 0xFD, 0xB4, 0x40, 0x47, 0x48, 0xE2,
+	 0xA8, 0x60, 0x28, 0x78, 0xFF, 0xFF, 0x28, 0x44, 0x04, 0x26, 0x05, 0x00, 0x68, 0x3A, 0x03, 0x00,
+	 0x32, 0x44, 0x00, 0x27, 0x03, 0x00, 0xA7, 0x60, 0x9B, 0x78, 0xFF, 0xFF, 0x0A, 0x64, 0x3A, 0xDB,
+	 0xA7, 0x60, 0x9B, 0x78, 0xFF, 0xFF, 0x0E, 0x64, 0x3A, 0xDB, 0x10, 0x60, 0x00, 0x65, 0x3C, 0x46,
+	 0x2A, 0xF2, 0x13, 0xF0, 0xA4, 0x84, 0xB4, 0xBC, 0x40, 0x48, 0x62, 0xF1, 0x64, 0x47, 0xFF, 0xB4,
+	 0x60, 0x45, 0xD0, 0x80, 0x70, 0x61, 0x01, 0x06, 0x64, 0x44, 0x0A, 0x36, 0x70, 0x64, 0x14, 0x36,
+	 0x38, 0x64, 0x37, 0x36, 0x15, 0x64, 0x6E, 0x36, 0x0B, 0x64, 0x40, 0x4E, 0xA0, 0x63, 0x0A, 0x64,
+	 0x65, 0x40, 0x0A, 0x36, 0x03, 0x00, 0x38, 0x61, 0x14, 0x64, 0xEB, 0x83, 0x40, 0x45, 0x43, 0x44,
+	 0x02, 0x60, 0x5E, 0x65, 0x2A, 0xF2, 0x2B, 0xF2, 0x60, 0x40, 0x04, 0x2B, 0x04, 0x00, 0x2E, 0x45,
+	 0xD4, 0x85, 0xC5, 0x84, 0x05, 0x00, 0x1B, 0xF0, 0xC5, 0x84, 0xC0, 0x84, 0x2E, 0x45, 0xC4, 0x84,
+	 0x60, 0x43, 0x28, 0x44, 0x00, 0xE1, 0xA1, 0xFF, 0x80, 0x4E, 0x83, 0x4C, 0x9A, 0xFF, 0x56, 0x62,
+	 0x7A, 0xD4, 0x7A, 0xD4, 0x7A, 0xD4, 0x5C, 0x62, 0x7A, 0xD4, 0x7A, 0xD4, 0x7A, 0xD4, 0xA1, 0xFF,
+	 0x98, 0xFF, 0x87, 0x4F, 0x87, 0x4C, 0x87, 0x4F, 0x87, 0x4D, 0x87, 0x4C, 0x01, 0x08, 0x01, 0x00,
+	 0xFF, 0xFF, 0x87, 0x4C, 0x87, 0x4C, 0x87, 0x4C, 0x87, 0x4C, 0xFF, 0xFF, 0xFF, 0xFF, 0x6A, 0x44,
+	 0xBC, 0xFF, 0xB5, 0xFF, 0x47, 0xFF, 0x27, 0x44, 0x02, 0xBC, 0x40, 0x47, 0x36, 0xF3, 0xB7, 0xFF,
+	 0xB4, 0xFF, 0x48, 0x60, 0x2D, 0x7D, 0x08, 0x60, 0x00, 0x6B, 0x60, 0x5B, 0x4D, 0xE2, 0xA8, 0x60,
+	 0x81, 0x78, 0xFF, 0xFF, 0x21, 0x46, 0xB5, 0xFF, 0xBC, 0xFF, 0x47, 0xFF, 0xB7, 0xFF, 0xB4, 0xFF,
+	 0x48, 0x60, 0x2D, 0x7D, 0x08, 0x60, 0x00, 0x6B, 0x26, 0x43, 0x25, 0x44, 0x06, 0xFA, 0x2A, 0x44,
+	 0x72, 0x45, 0x24, 0xFA, 0x95, 0xF3, 0x06, 0x04, 0xE4, 0xE2, 0xDC, 0x9C, 0x29, 0x40, 0x01, 0x26,
+	 0x64, 0x44, 0x95, 0xF9, 0x25, 0xFA, 0x96, 0xF3, 0x02, 0x04, 0xDC, 0x84, 0x96, 0xFB, 0x28, 0xFA,
+	 0x97, 0xF3, 0x02, 0x04, 0xDC, 0x84, 0x97, 0xFB, 0x29, 0xFA, 0x2D, 0x40, 0x01, 0x2A, 0x0E, 0x00,
+	 0x1D, 0xFF, 0x26, 0x44, 0x02, 0xBC, 0x40, 0x46, 0x27, 0x44, 0x07, 0x22, 0x05, 0x00, 0xF8, 0xB4,
+	 0x40, 0x47, 0x06, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0x30, 0xF1, 0x50, 0x00, 0xFC, 0xB3, 0x32, 0x40,
+	 0x01, 0x2A, 0x06, 0x00, 0x0A, 0xBB, 0x0F, 0xFC, 0xCB, 0xFE, 0xA7, 0x60, 0x9B, 0x78, 0xFF, 0xFF,
+	 0x2D, 0x44, 0x04, 0x26, 0x02, 0x00, 0x0F, 0xFC, 0x05, 0xFF, 0x30, 0xF1, 0x27, 0x44, 0x05, 0x22,
+	 0x2D, 0x00, 0xFA, 0xB4, 0x40, 0x47, 0x2D, 0x44, 0x10, 0x2A, 0x24, 0x00, 0x28, 0x40, 0xD4, 0x3A,
+	 0x21, 0x00, 0x31, 0x40, 0x08, 0x26, 0x00, 0x7C, 0x2B, 0x44, 0xD0, 0x80, 0x70, 0x45, 0x02, 0x28,
+	 0x64, 0x44, 0xC4, 0x84, 0xFF, 0xFF, 0x04, 0x24, 0x00, 0xB4, 0x60, 0x50, 0x08, 0x28, 0x01, 0x00,
+	 0x20, 0x29, 0x6D, 0xE2, 0x12, 0x60, 0xC0, 0x63, 0x1D, 0xF0, 0xC0, 0x64, 0xC0, 0x84, 0xA3, 0xD1,
+	 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xC0, 0x84, 0xA3, 0xDB, 0xA8, 0x60,
+	 0x89, 0x78, 0xFF, 0xFF, 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0x07, 0x00, 0x02, 0x2A, 0x05, 0x00,
+	 0xFD, 0xB4, 0x40, 0x47, 0x06, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0x05, 0x64, 0x3A, 0xDB, 0x28, 0x44,
+	 0xA4, 0x3A, 0x04, 0x00, 0x39, 0xF1, 0x25, 0x44, 0x0A, 0x36, 0x38, 0xF1, 0x31, 0x40, 0x08, 0x26,
+	 0x00, 0x7C, 0x2B, 0x44, 0xD0, 0x80, 0x70, 0x45, 0x02, 0x28, 0x64, 0x44, 0xC4, 0x84, 0xFF, 0xFF,
+	 0x04, 0x24, 0x00, 0xB4, 0x28, 0x40, 0xE4, 0x36, 0x00, 0xB4, 0x60, 0x50, 0x08, 0x28, 0x01, 0x00,
+	 0x20, 0x29, 0x6D, 0xE2, 0xA7, 0x60, 0x8E, 0x78, 0xFF, 0xFF, 0x21, 0x46, 0xB5, 0xFF, 0xBC, 0xFF,
+	 0x47, 0xFF, 0xB7, 0xFF, 0xB4, 0xFF, 0x48, 0x60, 0x2D, 0x7D, 0x08, 0x60, 0x00, 0x6B, 0x27, 0x44,
+	 0x07, 0x22, 0x05, 0x00, 0xF8, 0xB4, 0x40, 0x47, 0x06, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0xEA, 0x01,
+	 0x27, 0x44, 0x05, 0x22, 0x09, 0x00, 0xBA, 0xB4, 0x40, 0x47, 0x3C, 0x46, 0x02, 0x64, 0x31, 0xFB,
+	 0xC0, 0xFE, 0xA7, 0x60, 0x9B, 0x78, 0xFF, 0xFF, 0x27, 0x44, 0x02, 0x2A, 0x06, 0x00, 0xFD, 0xB4,
+	 0x40, 0x47, 0x06, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0xF4, 0x01, 0xF3, 0x0A, 0x7C, 0x50, 0x6D, 0xE2,
+	 0xF0, 0x01, 0x72, 0x45, 0xDC, 0x84, 0x95, 0xFB, 0x11, 0x64, 0x3A, 0xDB, 0x96, 0xF3, 0x06, 0x04,
+	 0xDC, 0x84, 0x96, 0xFB, 0x97, 0xF3, 0x02, 0x04, 0xDC, 0x84, 0x97, 0xFB, 0xA7, 0x60, 0xA6, 0x78,
+	 0xFF, 0xFF, 0x00, 0x61, 0x12, 0x64, 0x3A, 0xDB, 0x16, 0x60, 0xBA, 0x63, 0xBD, 0xD3, 0x72, 0x45,
+	 0x44, 0x8A, 0x02, 0x28, 0x02, 0x00, 0xE4, 0xE2, 0xDD, 0x81, 0x02, 0x28, 0x02, 0x00, 0xE4, 0xE2,
+	 0xDD, 0x81, 0xBD, 0xD3, 0x95, 0xF1, 0x61, 0x45, 0xC0, 0x84, 0x00, 0x61, 0x02, 0x24, 0x01, 0xB9,
+	 0xC4, 0x84, 0x60, 0x55, 0x2A, 0x52, 0x95, 0xFB, 0x02, 0x24, 0x01, 0xB9, 0xBD, 0xD3, 0x96, 0xF1,
+	 0x61, 0x45, 0xC0, 0x84, 0x00, 0x61, 0x02, 0x24, 0x01, 0xB9, 0xC4, 0x84, 0x96, 0xFB, 0x02, 0x24,
+	 0x01, 0xB9, 0xBD, 0xD3, 0x97, 0xF1, 0x61, 0x45, 0xC0, 0x84, 0xC4, 0x84, 0x97, 0xFB, 0xA8, 0x60,
+	 0x0C, 0x78, 0xFF, 0xFF, 0xAE, 0x01, 0xA1, 0xFF, 0xFF, 0xFF, 0x01, 0x25, 0x09, 0x00, 0x04, 0x25,
+	 0x03, 0x00, 0x47, 0xFF, 0x32, 0x74, 0xA5, 0x01, 0xC4, 0xE2, 0xAF, 0x60, 0x19, 0x78, 0xFF, 0xFF,
+	 0x4C, 0x4E, 0x47, 0xFF, 0x32, 0x74, 0xCD, 0xE2, 0xAC, 0x60, 0x8F, 0x78, 0x00, 0x61, 0x10, 0x64,
+	 0x3A, 0xDB, 0xA7, 0x60, 0x9B, 0x78, 0xFF, 0xFF, 0xA7, 0x60, 0x9B, 0x78, 0xFF, 0xFF, 0x5C, 0x4D,
+	 0x26, 0x44, 0x02, 0x26, 0x0C, 0x00, 0x3E, 0x46, 0x09, 0xF2, 0x1E, 0x41, 0x03, 0x1B, 0xAE, 0x60,
+	 0xCB, 0x78, 0xFF, 0xFF, 0x40, 0x5E, 0xFD, 0xFB, 0x21, 0x44, 0x02, 0x64, 0x40, 0x46, 0x41, 0x5D,
+	 0x21, 0x46, 0x00, 0xF2, 0x46, 0x45, 0x87, 0xFC, 0x4C, 0xE2, 0x01, 0x64, 0x33, 0xFB, 0x01, 0x60,
+	 0x0E, 0xE1, 0x03, 0xE1, 0x3F, 0x40, 0x01, 0x27, 0x00, 0x00, 0x21, 0x69, 0xB6, 0xFF, 0xA1, 0xFF,
+	 0x6C, 0x5E, 0xB6, 0xFF, 0xB7, 0xFF, 0x60, 0x5C, 0x20, 0x64, 0x3A, 0xDB, 0x68, 0x43, 0x26, 0xFC,
+	 0x22, 0x69, 0x64, 0x44, 0xA1, 0xFF, 0xFF, 0xFF, 0x6C, 0x5F, 0x60, 0x43, 0x26, 0xF2, 0xFF, 0xFF,
+	 0x68, 0x5F, 0x26, 0xFA, 0x3A, 0x69, 0x1D, 0xFC, 0x2E, 0x44, 0x36, 0xF1, 0x1C, 0xFA, 0xC3, 0x94,
+	 0xCD, 0xE2, 0x2E, 0x44, 0x14, 0x36, 0x12, 0x00, 0x0A, 0x36, 0x0F, 0x00, 0x63, 0x45, 0xE3, 0x83,
+	 0xE3, 0x83, 0xC7, 0x83, 0xE3, 0x83, 0xC7, 0x83, 0xFF, 0xFF, 0x37, 0x36, 0x05, 0x00, 0x6E, 0x36,
+	 0x04, 0x00, 0xAE, 0x60, 0xE3, 0x78, 0xFF, 0xFF, 0xEB, 0x83, 0xEB, 0x83, 0xEB, 0x83, 0xEB, 0x83,
+	 0xFF, 0xFF, 0x80, 0x27, 0xCF, 0x83, 0x1B, 0xFC, 0x01, 0x64, 0x4F, 0xFB, 0xA1, 0xFF, 0x1C, 0xF2,
+	 0x29, 0x41, 0xF9, 0x81, 0x52, 0x4A, 0x71, 0x89, 0x68, 0x5F, 0x27, 0xFA, 0x6C, 0x40, 0x03, 0x15,
+	 0xAE, 0x60, 0xF4, 0x78, 0xFF, 0xFF, 0x88, 0x60, 0x85, 0x71, 0x8D, 0xE2, 0x99, 0xF1, 0xFC, 0xA3,
+	 0xD3, 0x80, 0x43, 0x43, 0x03, 0x04, 0xAE, 0x60, 0xEB, 0x78, 0xFF, 0xFF, 0x32, 0x40, 0x01, 0x2A,
+	 0x4C, 0x00, 0x9A, 0xFF, 0x23, 0x43, 0x18, 0x61, 0xA1, 0xFF, 0x8C, 0x44, 0xCB, 0x83, 0x2A, 0xFA,
+	 0x40, 0x48, 0x40, 0x27, 0x04, 0xA1, 0x60, 0x40, 0x03, 0x2B, 0x01, 0x00, 0x06, 0xA1, 0x88, 0xB0,
+	 0x88, 0x36, 0xD9, 0x81, 0x62, 0x45, 0x23, 0x44, 0x54, 0x94, 0x28, 0x40, 0x04, 0x26, 0x00, 0x64,
+	 0x3F, 0xFA, 0xC9, 0x81, 0x65, 0x42, 0x7A, 0xDC, 0x00, 0xB9, 0xFD, 0x1C, 0x00, 0xF4, 0x6E, 0x61,
+	 0x10, 0x62, 0x14, 0x02, 0x05, 0x1D, 0x12, 0x1E, 0x0C, 0x00, 0x00, 0xF4, 0x7C, 0x61, 0x02, 0x62,
+	 0x7A, 0xDC, 0x63, 0x40, 0xFD, 0x1C, 0xF9, 0x1D, 0xFF, 0xB1, 0x08, 0x1E, 0x02, 0x02, 0x00, 0xF4,
+	 0x02, 0x62, 0xB6, 0xFF, 0xB7, 0xFF, 0xA1, 0xFF, 0x6C, 0x44, 0x5A, 0xDA, 0x98, 0xFF, 0x01, 0x60,
+	 0x08, 0xE1, 0x81, 0xE1, 0xA1, 0xFF, 0x6C, 0x40, 0xA1, 0xFF, 0x47, 0xFF, 0x26, 0x44, 0xFD, 0xB4,
+	 0x84, 0xBC, 0x01, 0x15, 0x7F, 0xB4, 0x40, 0x46, 0xA1, 0xFF, 0x6C, 0x40, 0x14, 0x63, 0x01, 0x11,
+	 0x01, 0x00, 0xFD, 0x1F, 0xAE, 0x60, 0x61, 0x78, 0xFF, 0xFF, 0x9A, 0xFF, 0x54, 0x63, 0x12, 0x64,
+	 0x40, 0x46, 0x00, 0x64, 0x0F, 0xFA, 0xA1, 0xFF, 0xCB, 0xF1, 0x12, 0x61, 0x50, 0xFE, 0x8C, 0x44,
+	 0xCC, 0xF0, 0xBD, 0xDA, 0x40, 0x48, 0x04, 0x26, 0x40, 0x00, 0xA1, 0xFF, 0x8C, 0x44, 0xBD, 0xDA,
+	 0x30, 0xFB, 0x6C, 0x44, 0xBD, 0xDA, 0xFF, 0xFF, 0x01, 0x26, 0x24, 0x00, 0xD0, 0x80, 0xA1, 0xFF,
+	 0x8C, 0x44, 0x6C, 0x5C, 0xF2, 0xFE, 0xBD, 0xDA, 0xCD, 0xF3, 0xD4, 0x80, 0xD0, 0x80, 0xBD, 0xD8,
+	 0x2D, 0x44, 0x15, 0x0C, 0x32, 0x40, 0x02, 0x2A, 0x07, 0x00, 0x28, 0x42, 0x0C, 0xB2, 0x08, 0x3A,
+	 0x03, 0x00, 0x10, 0xBC, 0x40, 0x4D, 0x4D, 0x00, 0x03, 0x0A, 0xAE, 0x60, 0xF9, 0x78, 0xFF, 0xFF,
+	 0x11, 0xBC, 0x40, 0x4D, 0x28, 0x45, 0xBF, 0x60, 0xFF, 0x64, 0x24, 0x88, 0x42, 0x00, 0x30, 0xBC,
+	 0x40, 0x4D, 0x3F, 0x00, 0x20, 0xB9, 0x5C, 0x8E, 0xA1, 0xFF, 0x8C, 0x44, 0xBD, 0xDA, 0xDC, 0x9C,
+	 0x6C, 0x44, 0xF2, 0xFE, 0xBD, 0xDA, 0x08, 0x28, 0x44, 0x4E, 0xDC, 0x84, 0x2E, 0x5C, 0xB0, 0x84,
+	 0xEF, 0xB1, 0x08, 0x24, 0x40, 0xB9, 0x41, 0x46, 0x2C, 0x00, 0x8C, 0x44, 0x04, 0x61, 0xBD, 0xDA,
+	 0x50, 0xFE, 0x80, 0x27, 0x00, 0x64, 0x30, 0xFB, 0x8C, 0x44, 0xBD, 0xDA, 0xD0, 0x80, 0x8C, 0x44,
+	 0xBD, 0xDA, 0xD4, 0x80, 0x00, 0x65, 0x8C, 0x44, 0xCD, 0xF1, 0xBD, 0xDA, 0xD0, 0x80, 0x28, 0x44,
+	 0x03, 0x0C, 0xA0, 0x2A, 0x0A, 0x00, 0x11, 0x00, 0x10, 0x65, 0x60, 0x40, 0xC4, 0x36, 0x04, 0x00,
+	 0xD4, 0x3A, 0x08, 0x00, 0x27, 0x40, 0x40, 0x26, 0x30, 0x65, 0x00, 0x64, 0x3F, 0xFA, 0x46, 0x4E,
+	 0x35, 0x8D, 0x5F, 0x00, 0x40, 0x26, 0xF9, 0x01, 0x30, 0x65, 0x9D, 0xDC, 0x9D, 0xDC, 0x9D, 0xDC,
+	 0xF4, 0x01, 0x00, 0xE1, 0x23, 0x43, 0xE8, 0xA3, 0x6A, 0x62, 0x9A, 0xFF, 0xA1, 0xFF, 0x28, 0x44,
+	 0x03, 0x2B, 0x04, 0x00, 0x7A, 0xDC, 0x7A, 0xDC, 0x7A, 0xDC, 0x28, 0x44, 0x88, 0xB0, 0x88, 0x2A,
+	 0x03, 0x00, 0x70, 0x62, 0x7A, 0xDC, 0x28, 0x44, 0x40, 0x2B, 0x13, 0x00, 0x72, 0x62, 0x7A, 0xDC,
+	 0x04, 0xE6, 0x7A, 0xDC, 0x3B, 0xF2, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x2B, 0x02, 0x00, 0x7A, 0xDC,
+	 0x7A, 0xDC, 0x08, 0x60, 0x00, 0xEB, 0xFC, 0xA3, 0x25, 0xFF, 0x3F, 0xFC, 0x04, 0xA3, 0xB0, 0xFF,
+	 0x01, 0x00, 0x3F, 0xFC, 0xCF, 0x83, 0xDF, 0x83, 0x04, 0x02, 0x00, 0xF4, 0x10, 0x62, 0x6C, 0x61,
+	 0x1F, 0x00, 0x27, 0x03, 0xCB, 0x83, 0xFF, 0x60, 0xFE, 0x65, 0x0E, 0xA3, 0xA7, 0x84, 0xF2, 0xA3,
+	 0x00, 0xF4, 0x10, 0x62, 0x6C, 0x61, 0x7A, 0xDC, 0xFE, 0x1C, 0x03, 0x1D, 0x7C, 0xA8, 0xD9, 0x81,
+	 0x0A, 0x02, 0x00, 0xF4, 0x02, 0x62, 0xA7, 0x84, 0x7A, 0x61, 0x7A, 0xDC, 0xFE, 0x1C, 0xF9, 0x1D,
+	 0x7C, 0xA8, 0xD9, 0x81, 0xF6, 0x03, 0xFF, 0xB1, 0x0C, 0x1E, 0x02, 0x02, 0x00, 0xF4, 0x02, 0x62,
+	 0xA1, 0xFF, 0x01, 0x60, 0x0C, 0xE1, 0xB6, 0xFF, 0xB7, 0xFF, 0xA1, 0xFF, 0xCD, 0x81, 0x6C, 0x44,
+	 0x5A, 0xDA, 0x98, 0xFF, 0x00, 0xE6, 0x7C, 0x44, 0x33, 0xFB, 0x01, 0x60, 0x0C, 0xE1, 0x83, 0xE1,
+	 0xA1, 0xFF, 0x8C, 0x44, 0x46, 0x45, 0xA1, 0xFF, 0x14, 0x63, 0x01, 0x10, 0xFE, 0x1F, 0x01, 0x60,
+	 0x08, 0xE1, 0x0A, 0x64, 0x60, 0x54, 0x47, 0xFF, 0x50, 0x4B, 0x67, 0x50, 0x69, 0xE2, 0x6A, 0x40,
+	 0x40, 0x2B, 0x01, 0x15, 0x29, 0x00, 0x6C, 0x40, 0x28, 0x40, 0x03, 0x26, 0x15, 0x00, 0x31, 0x40,
+	 0x20, 0x2A, 0x03, 0x00, 0x28, 0x40, 0x50, 0x3A, 0x0F, 0x00, 0x2D, 0x44, 0x20, 0x2A, 0x0C, 0x00,
+	 0x2B, 0x44, 0xAC, 0x80, 0x28, 0x40, 0xB4, 0x3A, 0x03, 0x00, 0x02, 0x03, 0x30, 0xFB, 0x04, 0x00,
+	 0x2B, 0x50, 0xA8, 0x60, 0x92, 0x78, 0x04, 0xE1, 0x04, 0xE1, 0xA1, 0xFF, 0x35, 0xF1, 0x26, 0x44,
+	 0x64, 0x54, 0xCD, 0xE2, 0x84, 0xBC, 0x2D, 0x40, 0x0C, 0x22, 0xFD, 0xB4, 0x40, 0x46, 0x23, 0x64,
+	 0x3A, 0xDB, 0xAB, 0x60, 0x6A, 0x78, 0xFF, 0xFF, 0x27, 0x40, 0x26, 0x22, 0x04, 0x00, 0x02, 0x64,
+	 0x31, 0xFB, 0xC0, 0xFE, 0xFF, 0xFF, 0x6C, 0x40, 0xB7, 0xFF, 0xB4, 0xFF, 0x48, 0x60, 0x2D, 0x7D,
+	 0x08, 0x60, 0x00, 0x6B, 0x37, 0xF3, 0x2B, 0x45, 0xD4, 0x80, 0xFF, 0xFF, 0x02, 0x28, 0x65, 0x44,
+	 0x60, 0x50, 0xA0, 0x4C, 0x20, 0xBC, 0xFF, 0xB4, 0xA0, 0x51, 0x35, 0xF1, 0x74, 0x44, 0xC0, 0x94,
+	 0x32, 0x40, 0x02, 0x2A, 0x18, 0x00, 0x28, 0x44, 0xA4, 0x36, 0x04, 0x00, 0x0C, 0xB4, 0xFF, 0xFF,
+	 0x04, 0x36, 0x11, 0x00, 0x26, 0x43, 0xFD, 0xB3, 0x04, 0xBB, 0x43, 0x46, 0x01, 0x2A, 0x03, 0x00,
+	 0x28, 0x47, 0x40, 0xBF, 0x40, 0x48, 0x0A, 0xBB, 0x0F, 0xFC, 0x50, 0x4B, 0x67, 0x50, 0x00, 0x64,
+	 0x30, 0xFB, 0x05, 0xFF, 0xC6, 0x01, 0x24, 0x64, 0x3A, 0xDB, 0x28, 0x44, 0x04, 0x2A, 0x03, 0x00,
+	 0xA7, 0x60, 0x8E, 0x78, 0xFF, 0xFF, 0x1D, 0xFF, 0x48, 0xE2, 0x27, 0x44, 0x06, 0x22, 0x05, 0x00,
+	 0xF9, 0xB4, 0x40, 0x47, 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0x26, 0x40, 0x10, 0x2A, 0x18, 0x00,
+	 0x26, 0xF2, 0xFF, 0xFF, 0x60, 0x47, 0xFF, 0xB4, 0xC0, 0xA0, 0xFF, 0xFF, 0x11, 0x0E, 0x98, 0xF1,
+	 0x1E, 0x60, 0xF8, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03,
+	 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF,
+	 0xAC, 0x60, 0x05, 0x78, 0xFF, 0xFF, 0x98, 0xF1, 0x1E, 0x60, 0xFA, 0x64, 0xA0, 0xD3, 0xFF, 0xFF,
+	 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00,
+	 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x2A, 0x64, 0x3A, 0xDB, 0x5C, 0x41, 0x87, 0xE1,
+	 0xA1, 0xFF, 0x6C, 0x40, 0x02, 0x00, 0x29, 0x64, 0x3A, 0xDB, 0x01, 0x60, 0x08, 0xE1, 0x87, 0xE1,
+	 0xA1, 0xFF, 0x6C, 0x40, 0x11, 0x00, 0x1F, 0x60, 0x0C, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84,
+	 0xFF, 0xFF, 0x08, 0x28, 0xA2, 0xDB, 0xF1, 0x01, 0x01, 0x60, 0x08, 0xE1, 0x21, 0x64, 0x3A, 0xDB,
+	 0x03, 0x00, 0x01, 0x60, 0x08, 0xE1, 0x6C, 0x40, 0x00, 0x64, 0x33, 0xFB, 0x32, 0x74, 0x40, 0x63,
+	 0x01, 0x16, 0xFE, 0x01, 0x01, 0x68, 0x01, 0x11, 0x09, 0x00, 0xA7, 0x6A, 0x22, 0x64, 0x3A, 0xDB,
+	 0x03, 0x60, 0xC9, 0x63, 0x01, 0x11, 0x02, 0x00, 0x6C, 0x40, 0xFC, 0x1F, 0x6C, 0x40, 0xB5, 0xFF,
+	 0x6C, 0x40, 0xBC, 0xFF, 0x6C, 0x40, 0xB7, 0xFF, 0xB4, 0xFF, 0x48, 0x60, 0x2D, 0x7D, 0x08, 0x60,
+	 0x00, 0x6B, 0x03, 0x0A, 0xA7, 0x60, 0x9B, 0x78, 0xFF, 0xFF, 0x01, 0x64, 0x4F, 0xFB, 0x27, 0x44,
+	 0x06, 0x22, 0x06, 0x00, 0xF9, 0xB4, 0x40, 0x47, 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0x48, 0xE2,
+	 0x27, 0x64, 0x3A, 0xDB, 0xB3, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x81, 0x3E, 0x54, 0x62, 0x22, 0x46,
+	 0xA2, 0xD0, 0x16, 0x63, 0x7C, 0x41, 0x44, 0x48, 0x80, 0x36, 0x04, 0x61, 0x28, 0x40, 0x50, 0x36,
+	 0x04, 0x61, 0x41, 0x4E, 0x28, 0x44, 0xA4, 0x36, 0x0E, 0x63, 0x12, 0x60, 0xC2, 0x62, 0xA2, 0xD1,
+	 0x24, 0x44, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xC0, 0x84, 0xA2, 0xDB,
+	 0x9A, 0xFF, 0xA1, 0xFF, 0x54, 0x62, 0xA2, 0xD2, 0xFF, 0xFF, 0x6A, 0x40, 0x80, 0x4E, 0x7A, 0xD4,
+	 0x7A, 0xD4, 0x7A, 0xD4, 0x7A, 0xD4, 0x7A, 0xD4, 0x7A, 0xD4, 0x7A, 0xD4, 0xFF, 0xFF, 0x01, 0x1D,
+	 0x78, 0x00, 0x7A, 0xD4, 0x7A, 0xD4, 0x7A, 0xD4, 0x7A, 0xD4, 0x28, 0x40, 0x03, 0x2B, 0x04, 0x00,
+	 0x7A, 0xD4, 0x7A, 0xD4, 0x7A, 0xD4, 0x6A, 0x40, 0x70, 0x62, 0x28, 0x44, 0x88, 0xB0, 0x88, 0x36,
+	 0x7A, 0xD4, 0x28, 0x40, 0x40, 0x2B, 0x0B, 0x00, 0x72, 0x62, 0x7A, 0xD4, 0x7A, 0xD4, 0xA2, 0xD2,
+	 0xFF, 0xFF, 0x60, 0x40, 0x20, 0x2B, 0x02, 0x00, 0x7A, 0xD4, 0x7A, 0xD4, 0x46, 0x00, 0x23, 0x43,
+	 0xCF, 0x83, 0xDF, 0x83, 0x02, 0x03, 0x55, 0x03, 0x04, 0x00, 0x03, 0xF0, 0x04, 0xF4, 0x64, 0x42,
+	 0x37, 0x00, 0x2E, 0x40, 0x04, 0x2A, 0x21, 0x00, 0xA1, 0xFF, 0x02, 0xFE, 0x10, 0x25, 0x42, 0xFE,
+	 0x72, 0x45, 0x65, 0x4C, 0x95, 0xF3, 0x03, 0x04, 0xE4, 0xE2, 0xDC, 0x84, 0x95, 0xFB, 0xA1, 0xFF,
+	 0x80, 0x4C, 0x96, 0xF3, 0x02, 0x04, 0xDC, 0x84, 0x96, 0xFB, 0x80, 0x4C, 0x97, 0xF3, 0x02, 0x04,
+	 0xDC, 0x84, 0x97, 0xFB, 0x80, 0x4C, 0x5C, 0x4E, 0xF8, 0xA3, 0x03, 0xF2, 0x9A, 0xF2, 0x04, 0xF4,
+	 0xFF, 0xB1, 0xF8, 0xA1, 0x06, 0xA4, 0x60, 0x42, 0x09, 0x00, 0x03, 0xF2, 0x9A, 0xF2, 0x04, 0xF4,
+	 0xC8, 0x82, 0xFF, 0xB1, 0x03, 0x00, 0x00, 0xF4, 0x81, 0xF2, 0xFF, 0xB1, 0x7A, 0xD4, 0xFF, 0xFF,
+	 0xFD, 0x1C, 0xF9, 0x1D, 0xFF, 0xB1, 0x17, 0x1E, 0x02, 0x02, 0x00, 0xF4, 0xDA, 0x82, 0xDA, 0x82,
+	 0xA2, 0xD2, 0xA1, 0xFF, 0x09, 0x74, 0x80, 0x4D, 0x0E, 0x00, 0x03, 0xF2, 0x9A, 0xF2, 0x04, 0xF4,
+	 0x23, 0x43, 0xA1, 0xFF, 0xA0, 0xD2, 0xFE, 0xA1, 0xCB, 0x83, 0x80, 0x4E, 0xAF, 0x83, 0x02, 0x1D,
+	 0x02, 0x03, 0xED, 0x01, 0xE3, 0x01, 0xA1, 0xFF, 0x28, 0x40, 0x40, 0x2B, 0x02, 0x00, 0x9C, 0x4E,
+	 0x9C, 0x4C, 0xA1, 0xFF, 0xDA, 0x83, 0x66, 0x44, 0x22, 0x46, 0x0C, 0xFA, 0x0B, 0xFC, 0x87, 0x4F,
+	 0x87, 0x4C, 0x87, 0x4F, 0x87, 0x4D, 0x87, 0x4C, 0x01, 0x08, 0x01, 0x00, 0xFF, 0xFF, 0x87, 0x4C,
+	 0x87, 0x4C, 0x87, 0x4C, 0x87, 0x4C, 0xFF, 0xFF, 0xFF, 0xFF, 0x6A, 0x44, 0xBC, 0xFF, 0x01, 0x60,
+	 0x08, 0xE1, 0x0C, 0x74, 0x04, 0xE1, 0xA1, 0xFF, 0x35, 0xF3, 0xC4, 0xE2, 0x60, 0x54, 0x89, 0xFF,
+	 0x13, 0x74, 0x88, 0xFF, 0x29, 0x44, 0xF7, 0xB4, 0x40, 0x49, 0x34, 0x64, 0x3A, 0xDB, 0x06, 0xE1,
+	 0x47, 0xFF, 0xA8, 0x60, 0x64, 0x78, 0xFF, 0xFF, 0xFF, 0x01, 0x08, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF,
+	 0x43, 0xFF, 0x01, 0x60, 0x00, 0xE1, 0x28, 0xF3, 0x47, 0xFF, 0x60, 0x40, 0x07, 0x37, 0x4B, 0x00,
+	 0x05, 0x3B, 0x04, 0x00, 0xFF, 0x0A, 0x80, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x29, 0xF5, 0x2A, 0xF3,
+	 0x47, 0xFF, 0x3F, 0xF0, 0x01, 0x1B, 0x01, 0x64, 0x60, 0x56, 0xAD, 0xE2, 0xB5, 0xFF, 0x6C, 0x40,
+	 0x40, 0xE1, 0xA1, 0xFF, 0x00, 0xF4, 0x6E, 0x61, 0x12, 0x62, 0x64, 0x43, 0x01, 0xE1, 0x03, 0x64,
+	 0xE2, 0xD0, 0xC9, 0x81, 0x64, 0x4C, 0xCC, 0x84, 0xDA, 0x82, 0xFA, 0x02, 0x01, 0x60, 0x00, 0x6B,
+	 0x9A, 0xFF, 0xCA, 0x82, 0x03, 0x00, 0x00, 0xF4, 0x81, 0xF2, 0xFF, 0xFF, 0x7A, 0xD0, 0xA1, 0xFF,
+	 0x64, 0x4C, 0xFC, 0x1C, 0xF8, 0x1D, 0x00, 0xB9, 0x06, 0x1E, 0x02, 0x02, 0x00, 0xF4, 0xDA, 0x82,
+	 0x5A, 0xD2, 0xA1, 0xFF, 0x60, 0x4D, 0x3F, 0x40, 0x02, 0x2B, 0x08, 0x00, 0x28, 0xF3, 0xA5, 0x60,
+	 0xC4, 0x65, 0x60, 0x40, 0x0E, 0x3B, 0x02, 0x00, 0x80, 0x4C, 0xFE, 0x01, 0xA1, 0xFF, 0x87, 0x4E,
+	 0x87, 0x4C, 0x87, 0x4C, 0x87, 0x4C, 0x87, 0x4C, 0x67, 0x4C, 0xFF, 0xFF, 0xBC, 0xFF, 0x00, 0xE1,
+	 0xD5, 0xFE, 0xA1, 0xFF, 0xFF, 0xFF, 0x00, 0x64, 0x40, 0x46, 0x60, 0x41, 0xB5, 0xFF, 0xB7, 0xFF,
+	 0xB4, 0xFF, 0x29, 0xF5, 0x3F, 0xF0, 0x24, 0xF2, 0x44, 0x43, 0x40, 0x44, 0x00, 0xF4, 0xF3, 0x60,
+	 0xA0, 0x65, 0x10, 0x62, 0x5A, 0xD2, 0xD9, 0x81, 0xD4, 0x80, 0xFF, 0xFF, 0xFB, 0x02, 0x61, 0x45,
+	 0x24, 0x44, 0xD4, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xFD, 0xA5, 0x48, 0x60, 0x00, 0x64,
+	 0xC4, 0x9D, 0x0D, 0x60, 0x00, 0x6B, 0x24, 0x44, 0xC0, 0x83, 0xBB, 0xFF, 0x29, 0xF5, 0x01, 0xE1,
+	 0x00, 0xF4, 0x6C, 0x61, 0x10, 0x62, 0x05, 0x00, 0x00, 0xF4, 0x01, 0xF2, 0xFF, 0xFF, 0x60, 0x41,
+	 0x04, 0x62, 0xA1, 0xFF, 0xFF, 0xFF, 0x01, 0x10, 0x1A, 0x00, 0x26, 0x44, 0x01, 0x26, 0x0C, 0x00,
+	 0x24, 0x44, 0xC8, 0x84, 0x40, 0x44, 0x02, 0x03, 0x6C, 0x45, 0xF3, 0x01, 0x03, 0x15, 0x01, 0x64,
+	 0x05, 0xFA, 0x15, 0x00, 0x6C, 0x45, 0xED, 0x01, 0x23, 0x44, 0xC8, 0x84, 0x40, 0x43, 0x02, 0x03,
+	 0x6C, 0x45, 0xE7, 0x01, 0x00, 0x64, 0x01, 0x15, 0x01, 0x64, 0x6C, 0x45, 0x05, 0xFB, 0xE2, 0xD2,
+	 0xDA, 0x82, 0xC9, 0x81, 0x60, 0x4C, 0xDD, 0x1C, 0xD7, 0x03, 0xBC, 0xFF, 0xDA, 0x01, 0x00, 0xE1,
+	 0xD5, 0xFE, 0xA1, 0xFF, 0xFF, 0xFF, 0x08, 0xE1, 0xA1, 0xFF, 0x67, 0x4C, 0x43, 0xFF, 0xAD, 0x4F,
+	 0x02, 0xBC, 0x00, 0x7F, 0xA0, 0x5D, 0x01, 0xE1, 0x01, 0x60, 0x69, 0x6B, 0xA5, 0x60, 0xC4, 0x64,
+	 0x60, 0x4C, 0xBB, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0x60, 0x4C, 0xA1, 0xFF, 0xFF, 0xFF, 0x60, 0x4C,
+	 0xFC, 0x01, 0x29, 0xF3, 0x2A, 0xF1, 0x07, 0xB5, 0x04, 0xE1, 0x65, 0x41, 0x64, 0x54, 0xCD, 0xE2,
+	 0x95, 0x81, 0xA1, 0x5D, 0xA1, 0xFF, 0xFF, 0xFF, 0xF9, 0x01, 0x00, 0xE1, 0x30, 0x40, 0x02, 0x36,
+	 0xA1, 0xFF, 0x83, 0xFF, 0x8D, 0xFF, 0x5C, 0x44, 0x5C, 0x43, 0x5C, 0x42, 0x5C, 0x41, 0x5C, 0x40,
+	 0xAC, 0xFF, 0xAD, 0xFF, 0xE7, 0xE1, 0xB1, 0x60, 0xC0, 0x78, 0xFF, 0xFF, 0x10, 0x61, 0x7F, 0x60,
+	 0xC0, 0x64, 0xA0, 0x80, 0x7F, 0x67, 0x02, 0x63, 0x26, 0x02, 0x98, 0xFE, 0x1A, 0x05, 0x1B, 0x60,
+	 0xB8, 0x62, 0xA2, 0xD5, 0x0E, 0xF2, 0x15, 0x18, 0x02, 0x18, 0x09, 0xF4, 0xFB, 0x01, 0x23, 0x44,
+	 0x00, 0xA8, 0x08, 0x7E, 0x0A, 0x02, 0x66, 0x44, 0x11, 0xFB, 0x46, 0x43, 0x23, 0x47, 0x80, 0xBF,
+	 0x3B, 0x42, 0x04, 0xA2, 0xA2, 0xDB, 0x08, 0xB9, 0x10, 0x7E, 0x00, 0x7F, 0x0E, 0xFA, 0x00, 0x67,
+	 0x0A, 0x00, 0x20, 0x44, 0xDC, 0x85, 0x0F, 0xB4, 0xF6, 0xA0, 0x7F, 0x67, 0x07, 0x63, 0x03, 0x05,
+	 0x45, 0x40, 0x00, 0x67, 0xD8, 0xFE, 0xFF, 0x27, 0x05, 0xFD, 0x0A, 0x7E, 0x04, 0xFB, 0x61, 0x55,
+	 0x4A, 0x00, 0x28, 0xFB, 0x01, 0xF3, 0x29, 0xFB, 0x44, 0x46, 0x40, 0x45, 0x10, 0x61, 0x7E, 0x60,
+	 0xC0, 0x64, 0xA0, 0x80, 0x7F, 0x67, 0x02, 0x63, 0x31, 0x02, 0xB3, 0x60, 0x58, 0x4F, 0x22, 0x78,
+	 0xFF, 0xFF, 0x7F, 0x67, 0x03, 0x63, 0x2A, 0x02, 0x26, 0x40, 0x01, 0x2B, 0x24, 0x00, 0x98, 0xFE,
+	 0x19, 0x05, 0x1B, 0x60, 0xB8, 0x62, 0xA2, 0xD5, 0x0E, 0xF2, 0x14, 0x18, 0x02, 0x18, 0x09, 0xF4,
+	 0xFB, 0x01, 0x23, 0x44, 0x00, 0xA8, 0x08, 0x7E, 0x0A, 0x02, 0x66, 0x44, 0x11, 0xFB, 0x46, 0x43,
+	 0x23, 0x47, 0x80, 0xBF, 0x3B, 0x42, 0x04, 0xA2, 0xA2, 0xDB, 0x08, 0xB9, 0x10, 0x7E, 0x00, 0x7F,
+	 0x0E, 0xFA, 0x09, 0x00, 0x20, 0x44, 0xDC, 0x85, 0x0F, 0xB4, 0xF6, 0xA0, 0x7F, 0x67, 0x07, 0x63,
+	 0x05, 0x05, 0x45, 0x40, 0xD8, 0xFE, 0x00, 0x67, 0xD0, 0xFE, 0xD9, 0xFE, 0xFF, 0x27, 0x05, 0xFD,
+	 0x0B, 0x7E, 0x04, 0xFB, 0x12, 0x60, 0xC8, 0x63, 0xA3, 0xD3, 0xFF, 0xFF, 0x20, 0xB0, 0x80, 0xBC,
+	 0x08, 0x28, 0xA3, 0xDB, 0x61, 0x55, 0x63, 0x00, 0x04, 0xB5, 0x82, 0xB5, 0x25, 0x02, 0x04, 0x03,
+	 0x20, 0x44, 0x7F, 0xB4, 0x40, 0x40, 0xA3, 0xD3, 0x99, 0xFE, 0x04, 0x04, 0x02, 0xBC, 0xFE, 0xB4,
+	 0xA3, 0xDB, 0x56, 0x00, 0xBC, 0xF3, 0x20, 0x40, 0x80, 0x26, 0x52, 0x00, 0xA3, 0xD3, 0xFF, 0xA0,
+	 0xF8, 0xB4, 0x02, 0x02, 0xA3, 0xDB, 0x1C, 0x00, 0x04, 0xBC, 0xBF, 0xB4, 0xA3, 0xDB, 0x08, 0xB0,
+	 0x01, 0x64, 0x08, 0x24, 0x02, 0x64, 0x28, 0xFB, 0x20, 0x44, 0x80, 0xBC, 0x40, 0x40, 0xD0, 0xFE,
+	 0x3F, 0x00, 0xBF, 0xB4, 0xA3, 0xDB, 0x3C, 0x00, 0x40, 0xB0, 0xFF, 0xFF, 0xFA, 0x02, 0xF8, 0xB4,
+	 0xA3, 0xDB, 0x08, 0xB5, 0x07, 0x7C, 0x01, 0x02, 0xBC, 0xF9, 0x20, 0x44, 0x7F, 0xB4, 0x40, 0x40,
+	 0x12, 0x60, 0xC8, 0x63, 0xA3, 0xD3, 0xFF, 0xFF, 0x20, 0xB5, 0x07, 0xB5, 0x08, 0x28, 0xC4, 0x02,
+	 0x99, 0xFE, 0x26, 0x05, 0x20, 0x44, 0x80, 0x26, 0x23, 0x00, 0x20, 0x2A, 0x00, 0x00, 0x40, 0x2A,
+	 0x1F, 0x00, 0xBF, 0xB4, 0x40, 0x40, 0x09, 0x00, 0xA8, 0xFF, 0x20, 0x44, 0x99, 0xFE, 0x02, 0x05,
+	 0x80, 0x2A, 0x03, 0x00, 0x40, 0xBC, 0x40, 0x40, 0x13, 0x00, 0x00, 0xF1, 0x80, 0xBC, 0x40, 0x40,
+	 0x64, 0x44, 0xE0, 0x84, 0xE8, 0x84, 0x0A, 0x36, 0x29, 0x01, 0x0B, 0x36, 0x5A, 0x01, 0x28, 0xFB,
+	 0x01, 0xF1, 0x29, 0xF9, 0x02, 0xF1, 0x2A, 0xF9, 0x03, 0xF1, 0x2B, 0xF9, 0xD0, 0xFE, 0xAE, 0xFF,
+	 0xA1, 0xFF, 0xFF, 0xFF, 0x82, 0x3E, 0x75, 0x44, 0x02, 0xB0, 0x01, 0xB0, 0x28, 0x02, 0xDC, 0x02,
+	 0x04, 0xB0, 0x08, 0xB0, 0x0B, 0x02, 0x20, 0x02, 0x40, 0x26, 0xA7, 0xFF, 0x8C, 0xFF, 0x75, 0x40,
+	 0x80, 0x2B, 0x01, 0x00, 0xAB, 0xFF, 0x75, 0x44, 0x8D, 0xFF, 0xEA, 0x01, 0x0A, 0xF3, 0xAA, 0xFF,
+	 0x60, 0x40, 0x20, 0x2B, 0x02, 0x00, 0x60, 0xFF, 0x0D, 0x00, 0x01, 0x26, 0x0C, 0x00, 0xC0, 0x60,
+	 0x00, 0x7C, 0xA0, 0x84, 0x80, 0x3B, 0x02, 0x00, 0xC0, 0x67, 0x03, 0x00, 0x40, 0x3B, 0x02, 0x00,
+	 0x00, 0x67, 0x0A, 0xFB, 0xD5, 0x01, 0xD4, 0x01, 0xAB, 0xFF, 0x00, 0x00, 0xD1, 0x01, 0x79, 0x63,
+	 0xFF, 0xFF, 0xFF, 0x1F, 0xA9, 0xFF, 0x77, 0x44, 0x60, 0x57, 0x10, 0x60, 0x00, 0x75, 0x40, 0x4A,
+	 0x01, 0x2A, 0x1C, 0x00, 0x24, 0x44, 0xAC, 0x86, 0x08, 0xF2, 0x18, 0x03, 0x1B, 0x60, 0xBE, 0x65,
+	 0xD4, 0x80, 0x0E, 0xF2, 0x02, 0x03, 0xA5, 0xD5, 0x04, 0x00, 0x01, 0xBC, 0x0E, 0xFA, 0x09, 0xF4,
+	 0xD1, 0xFE, 0x46, 0x44, 0x0B, 0x18, 0x66, 0x44, 0x10, 0xFB, 0x66, 0x47, 0x20, 0xBF, 0x3B, 0x42,
+	 0x04, 0xA2, 0xA2, 0xDB, 0x0E, 0xF2, 0x01, 0x75, 0x10, 0xBC, 0x0E, 0xFA, 0x2A, 0x44, 0x08, 0x2A,
+	 0x18, 0x00, 0x23, 0x44, 0x00, 0xA8, 0x5C, 0x43, 0x14, 0x03, 0x1B, 0x60, 0xB8, 0x62, 0xA2, 0xD5,
+	 0x01, 0x00, 0x09, 0xF4, 0x0E, 0xF2, 0x0D, 0x18, 0x08, 0xB0, 0x18, 0xAC, 0xFA, 0x03, 0x0E, 0xFA,
+	 0x66, 0x43, 0x11, 0xFD, 0x46, 0x43, 0x23, 0x47, 0x80, 0xBF, 0x3B, 0x42, 0x04, 0xA2, 0xA2, 0xDB,
+	 0x08, 0x75, 0x2A, 0x44, 0x06, 0x22, 0x2D, 0x00, 0x22, 0x44, 0x00, 0xA8, 0x60, 0x46, 0x0E, 0xF2,
+	 0x28, 0x03, 0x10, 0xB0, 0x01, 0xBC, 0x03, 0x02, 0x00, 0x64, 0x40, 0x42, 0x22, 0x00, 0x0E, 0xFA,
+	 0xD1, 0xFE, 0x1B, 0x60, 0xB2, 0x64, 0x40, 0x47, 0x58, 0x4F, 0x80, 0x00, 0x46, 0x42, 0x19, 0x02,
+	 0x22, 0x47, 0x40, 0xBF, 0x3B, 0x42, 0x04, 0xA2, 0xA2, 0xDB, 0x23, 0xF2, 0x66, 0x43, 0x00, 0xA8,
+	 0x0E, 0xF2, 0x08, 0x02, 0x60, 0x40, 0x02, 0x2A, 0xE4, 0x01, 0x12, 0xFD, 0x10, 0x64, 0x0E, 0xFA,
+	 0x02, 0x75, 0x07, 0x00, 0x60, 0x40, 0x04, 0x2A, 0xDC, 0x01, 0x12, 0xFD, 0x10, 0x64, 0x0E, 0xFA,
+	 0x04, 0x75, 0x2A, 0x44, 0x80, 0x2A, 0x19, 0x00, 0x21, 0x44, 0xAC, 0x86, 0x0E, 0xF2, 0x15, 0x03,
+	 0x01, 0xBC, 0x0E, 0xFA, 0xD1, 0xFE, 0x1B, 0x60, 0xCA, 0x64, 0x40, 0x47, 0x58, 0x4F, 0x56, 0x00,
+	 0x46, 0x41, 0x0B, 0x02, 0x21, 0x47, 0x10, 0xBF, 0x3B, 0x42, 0x04, 0xA2, 0xA2, 0xDB, 0x0E, 0xF2,
+	 0x66, 0x43, 0x08, 0xFD, 0x10, 0xBC, 0x0E, 0xFA, 0x80, 0x75, 0x2A, 0x44, 0x10, 0xB0, 0x20, 0x44,
+	 0x15, 0x03, 0x7F, 0xB4, 0x40, 0x40, 0x12, 0x60, 0xC8, 0x63, 0xA3, 0xD3, 0xFF, 0xFF, 0x20, 0xB0,
+	 0x80, 0xB0, 0x09, 0x03, 0x08, 0x03, 0x40, 0xBC, 0x7F, 0xB4, 0x04, 0xB0, 0xA3, 0xDB, 0x03, 0x03,
+	 0x20, 0x44, 0x80, 0xBC, 0x40, 0x40, 0xB1, 0x60, 0x90, 0x78, 0xFF, 0xFF, 0xB1, 0x60, 0xC0, 0x78,
+	 0xFF, 0xFF, 0xE8, 0xFE, 0x14, 0x05, 0xEA, 0xFE, 0x24, 0x05, 0xE9, 0xFE, 0x1C, 0x05, 0xE7, 0xFE,
+	 0x09, 0x05, 0x47, 0xFF, 0x20, 0x44, 0x0F, 0x22, 0x03, 0x00, 0xCC, 0x84, 0x40, 0x40, 0x0F, 0x22,
+	 0xB8, 0xFE, 0xEC, 0x01, 0x23, 0x41, 0x00, 0xB9, 0x5C, 0x4A, 0xE8, 0x02, 0x6E, 0x01, 0x24, 0x41,
+	 0x00, 0xB9, 0x1B, 0x60, 0xBE, 0x65, 0x45, 0x47, 0xE1, 0x02, 0x58, 0x4F, 0x0F, 0x00, 0xDE, 0x02,
+	 0x5C, 0x4A, 0x46, 0x44, 0x50, 0x01, 0x22, 0x41, 0x00, 0xB9, 0x5C, 0x4A, 0x08, 0x24, 0x81, 0x01,
+	 0xD5, 0x01, 0x21, 0x41, 0x00, 0xB9, 0x5C, 0x4A, 0xA6, 0x03, 0xD0, 0x01, 0x27, 0xD3, 0x03, 0x00,
+	 0x10, 0xB0, 0x09, 0xF2, 0x04, 0x03, 0xAC, 0x86, 0x0E, 0xF2, 0xFA, 0x02, 0x08, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x0E, 0xF3, 0x0F, 0x60, 0xFE, 0x65, 0x0C, 0xF3, 0x24, 0x86, 0x24, 0x46, 0x60, 0x40,
+	 0xFB, 0x3B, 0x07, 0x00, 0x80, 0x26, 0x02, 0x00, 0x23, 0x46, 0x03, 0x4C, 0x46, 0x61, 0x3A, 0x65,
+	 0x0C, 0x00, 0x2E, 0xF3, 0x40, 0x45, 0xF8, 0x2B, 0x02, 0x00, 0x40, 0x45, 0x03, 0x00, 0x58, 0x4F,
+	 0x39, 0x00, 0x07, 0x02, 0x58, 0x4F, 0x45, 0x00, 0x04, 0x05, 0x66, 0x50, 0x65, 0x52, 0x61, 0x51,
+	 0x09, 0x00, 0x26, 0x47, 0x00, 0xBF, 0x0E, 0xFB, 0x2E, 0xF5, 0x05, 0xF0, 0x80, 0x60, 0x64, 0x50,
+	 0x00, 0x72, 0x7E, 0x71, 0xAC, 0xFF, 0xB1, 0x60, 0xC0, 0x78, 0xFF, 0xFF, 0x8E, 0xFF, 0x0F, 0xF3,
+	 0x0F, 0x60, 0xFE, 0x65, 0x24, 0x86, 0x0D, 0xF3, 0x2E, 0xF3, 0x40, 0x45, 0xF8, 0x2B, 0x02, 0x00,
+	 0x40, 0x45, 0x03, 0x00, 0x58, 0x4F, 0x16, 0x00, 0x07, 0x02, 0x58, 0x4F, 0x22, 0x00, 0x04, 0x05,
+	 0x66, 0x50, 0x65, 0x52, 0x61, 0x51, 0x09, 0x00, 0x26, 0x47, 0x00, 0xBF, 0x0F, 0xFB, 0x2E, 0xF5,
+	 0x05, 0xF0, 0x80, 0x60, 0x64, 0x50, 0x00, 0x72, 0x7E, 0x71, 0x8D, 0xFF, 0xAD, 0xFF, 0xB1, 0x60,
+	 0xC0, 0x78, 0xFF, 0xFF, 0x25, 0x44, 0x8A, 0xF1, 0x8B, 0xF1, 0xD0, 0x80, 0xD0, 0x80, 0x07, 0x04,
+	 0x01, 0x06, 0x05, 0x00, 0x25, 0x46, 0x01, 0xF0, 0x03, 0x67, 0xA0, 0x85, 0x94, 0x80, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x25, 0x46, 0x26, 0x41, 0x46, 0x63, 0x01, 0xF2, 0xFF, 0xFF, 0xFF, 0xB5, 0xD5, 0x81,
+	 0x00, 0xF2, 0x05, 0x04, 0x04, 0x63, 0x60, 0x46, 0xF7, 0x1B, 0x42, 0xFE, 0x0D, 0x00, 0x61, 0x44,
+	 0xC5, 0x81, 0x63, 0x45, 0xC5, 0x81, 0x9C, 0x84, 0xDC, 0x84, 0x01, 0xF2, 0xF0, 0x85, 0xF0, 0x80,
+	 0x65, 0x44, 0xF8, 0x85, 0xFF, 0xFF, 0x02, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0xA2, 0xFF, 0x1B, 0x60,
+	 0xD0, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0xAC, 0x86, 0x0E, 0xF2, 0x07, 0x03, 0x00, 0xA8, 0x09, 0xF2,
+	 0xFA, 0x02, 0x01, 0x67, 0x0E, 0xFA, 0x08, 0xFE, 0x17, 0x00, 0x8C, 0xF3, 0xFF, 0xFF, 0xD8, 0xA0,
+	 0x00, 0xB4, 0x12, 0x06, 0x09, 0x60, 0x08, 0x61, 0x41, 0x4A, 0x7C, 0xA1, 0x0E, 0xA1, 0xA2, 0xFF,
+	 0xB3, 0x60, 0x58, 0x4E, 0x97, 0x78, 0xFF, 0xFF, 0xA3, 0xFF, 0x06, 0x03, 0x2A, 0x43, 0xB3, 0x60,
+	 0x58, 0x4E, 0xB8, 0x78, 0xFF, 0xFF, 0x08, 0xFE, 0xA3, 0xFF, 0x2D, 0x58, 0xFF, 0xFF, 0x41, 0x4A,
+	 0x7C, 0xA1, 0x0E, 0xA1, 0xA2, 0xFF, 0xB3, 0x60, 0x58, 0x4E, 0x97, 0x78, 0xFF, 0xFF, 0x07, 0x03,
+	 0x2A, 0x43, 0xB3, 0x60, 0x58, 0x4E, 0xB8, 0x78, 0xFF, 0xFF, 0x08, 0xFE, 0x0D, 0x00, 0x1B, 0x60,
+	 0xD0, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0xAC, 0x86, 0x0E, 0xF2, 0x06, 0x03, 0x00, 0xA8, 0x09, 0xF2,
+	 0xFA, 0x02, 0x01, 0x67, 0x0E, 0xFA, 0x08, 0xFE, 0xA3, 0xFF, 0x2D, 0x58, 0xFF, 0xFF, 0x8D, 0xF3,
+	 0x7C, 0x63, 0x00, 0xBE, 0x40, 0x45, 0x1A, 0x03, 0x00, 0x65, 0x65, 0x44, 0xDC, 0x85, 0x84, 0xA1,
+	 0x00, 0xF2, 0x06, 0x06, 0x01, 0xFC, 0x00, 0xA8, 0x60, 0x46, 0xF7, 0x02, 0x40, 0x45, 0x0E, 0x00,
+	 0x8C, 0xF3, 0x00, 0x63, 0xD4, 0x84, 0x8C, 0xFB, 0x80, 0x60, 0x7C, 0x64, 0x01, 0xFA, 0x00, 0xF0,
+	 0x00, 0xFC, 0xD3, 0x80, 0x8D, 0xF9, 0x02, 0x02, 0x8E, 0xF9, 0x08, 0xFE, 0x2E, 0x58, 0xFF, 0xFF,
+	 0x66, 0x44, 0x25, 0x46, 0x05, 0xFA, 0x06, 0xFA, 0x01, 0xF0, 0x03, 0x67, 0x02, 0xFC, 0xB0, 0x84,
+	 0x3A, 0x7E, 0x01, 0xFA, 0x12, 0x64, 0x03, 0xFA, 0x00, 0xF0, 0x04, 0xF8, 0x00, 0x64, 0x0C, 0x61,
+	 0x10, 0x63, 0x59, 0xDA, 0xFE, 0x1F, 0x2E, 0x58, 0xFF, 0xFF, 0x27, 0x43, 0xE3, 0x81, 0xE9, 0x81,
+	 0x03, 0x05, 0x16, 0x03, 0x00, 0x61, 0x01, 0x00, 0xE4, 0x63, 0x61, 0x46, 0xBF, 0xD2, 0x27, 0x45,
+	 0xDC, 0x84, 0xA2, 0xDA, 0xBE, 0xD2, 0x25, 0x46, 0x88, 0xF8, 0x04, 0x1B, 0x25, 0x44, 0x61, 0x46,
+	 0xA3, 0xDA, 0x04, 0x00, 0x0A, 0xFA, 0x60, 0x46, 0x25, 0x44, 0x09, 0xFA, 0x61, 0x46, 0xBE, 0xDA,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x25, 0x44, 0x00, 0xA8, 0x07, 0x4B, 0x0C, 0x03, 0x58, 0x4F, 0x33, 0x00,
+	 0x0B, 0x47, 0x1B, 0x60, 0xC4, 0x65, 0x27, 0x44, 0xD4, 0x80, 0x00, 0x64, 0x01, 0x02, 0x0F, 0xFA,
+	 0x58, 0x4F, 0xD3, 0x01, 0x70, 0x00, 0x25, 0x43, 0xE3, 0x84, 0x7C, 0x41, 0x02, 0x04, 0xE8, 0x81,
+	 0xE4, 0x63, 0x61, 0x46, 0xA3, 0xD2, 0x00, 0x7C, 0x40, 0x45, 0xBF, 0xD8, 0xA3, 0xD8, 0xBE, 0xD8,
+	 0x27, 0x42, 0x5A, 0xD3, 0x25, 0x5C, 0x60, 0x41, 0x02, 0x1B, 0x27, 0xD9, 0x05, 0x00, 0x25, 0x46,
+	 0x0A, 0xFA, 0x61, 0x46, 0x25, 0x44, 0x09, 0xFA, 0x25, 0x44, 0x27, 0x43, 0x00, 0x61, 0x60, 0x46,
+	 0x09, 0xF2, 0x08, 0xFC, 0x00, 0xA8, 0xDD, 0x81, 0xFA, 0x02, 0xBF, 0xD1, 0x66, 0x44, 0xBE, 0xDB,
+	 0xC1, 0x84, 0xBF, 0xDB, 0x48, 0x00, 0x25, 0x46, 0xE4, 0x63, 0x08, 0xF2, 0x89, 0xF2, 0x1E, 0x18,
+	 0x40, 0x47, 0xE0, 0x84, 0xE8, 0x85, 0x02, 0x05, 0xE8, 0x83, 0x00, 0x65, 0x65, 0x46, 0xBF, 0xD2,
+	 0x61, 0x5C, 0xCC, 0x84, 0xA2, 0xDA, 0x25, 0x46, 0x0A, 0xF2, 0x00, 0xB9, 0x65, 0x46, 0x08, 0x24,
+	 0xBE, 0xDA, 0x02, 0x1B, 0xA3, 0xD8, 0x02, 0x00, 0x60, 0x46, 0x89, 0xFA, 0x00, 0xB9, 0x61, 0x46,
+	 0x08, 0x28, 0x0A, 0xFA, 0x25, 0x46, 0x89, 0xFC, 0x8A, 0xFC, 0x88, 0xFC, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x00, 0x61, 0x28, 0x65, 0x25, 0x43, 0x8E, 0xF3, 0xAF, 0x83, 0x00, 0xBE, 0x18, 0x03, 0x02, 0x03,
+	 0x00, 0xFC, 0x01, 0x00, 0x8D, 0xFD, 0x63, 0x46, 0x65, 0x44, 0xCC, 0x85, 0x00, 0xF2, 0x07, 0x02,
+	 0x8E, 0xF5, 0x00, 0x64, 0x00, 0xFA, 0xDE, 0x60, 0xAF, 0x64, 0x09, 0xFB, 0x08, 0x00, 0x66, 0x43,
+	 0x00, 0xBE, 0xDD, 0x81, 0xF1, 0x02, 0x8C, 0xF1, 0x8E, 0xFD, 0xC1, 0x84, 0x8C, 0xFB, 0x2E, 0x58,
+	 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x45, 0x29, 0x43, 0xFC, 0xA3, 0x66, 0x44, 0xBD, 0xDB, 0x25, 0x44,
+	 0xBD, 0xDB, 0x00, 0x64, 0xBD, 0xDB, 0x03, 0x61, 0x0E, 0x65, 0x1B, 0x60, 0xD8, 0x63, 0x43, 0x49,
+	 0xA3, 0xD3, 0x06, 0xA3, 0x00, 0xA8, 0xCD, 0x81, 0x04, 0x02, 0xF9, 0x02, 0xB1, 0x60, 0xC0, 0x78,
+	 0xFF, 0xFF, 0x01, 0x26, 0xE6, 0x01, 0xD4, 0x80, 0x60, 0x45, 0xE3, 0x05, 0xF6, 0xA3, 0xBD, 0xD1,
+	 0xBD, 0xD1, 0x44, 0x47, 0x44, 0x48, 0x44, 0x45, 0x1C, 0x60, 0x16, 0x64, 0x44, 0xD7, 0xFF, 0xFF,
+	 0xFF, 0xFF, 0x48, 0xFE, 0x8D, 0xF5, 0x8C, 0xF3, 0x0D, 0x18, 0xCC, 0x84, 0x8C, 0xFB, 0x80, 0x60,
+	 0x7C, 0x64, 0x01, 0xFA, 0x00, 0x64, 0x00, 0xF0, 0x00, 0xFA, 0xD0, 0x80, 0x8D, 0xF9, 0x02, 0x02,
+	 0x8E, 0xF9, 0x08, 0xFE, 0x2E, 0x58, 0xFF, 0xFF, 0x1B, 0x60, 0x88, 0x63, 0x0D, 0x65, 0x00, 0x61,
+	 0x41, 0x48, 0xA3, 0xD3, 0x06, 0xA3, 0xAC, 0x86, 0x00, 0x61, 0x09, 0x03, 0x00, 0xF2, 0x09, 0xF0,
+	 0xAC, 0x86, 0x00, 0xF2, 0xDD, 0x81, 0xFC, 0x02, 0x64, 0x44, 0xAC, 0x86, 0xF6, 0x01, 0x61, 0x44,
+	 0x25, 0x46, 0x27, 0xDA, 0x65, 0x44, 0x28, 0x45, 0x45, 0x88, 0xCC, 0x85, 0x5A, 0x87, 0xE9, 0x02,
+	 0x00, 0x64, 0x27, 0xDA, 0x5A, 0xDA, 0x5A, 0x87, 0x88, 0xF3, 0x87, 0xF1, 0x02, 0xA4, 0x60, 0x46,
+	 0x60, 0x45, 0x00, 0x61, 0x1E, 0xF2, 0xFF, 0xFF, 0xAC, 0x86, 0x00, 0xF2, 0x04, 0x03, 0xAC, 0x86,
+	 0x00, 0xF2, 0xDD, 0x81, 0xFC, 0x02, 0x65, 0x44, 0x02, 0xA5, 0x65, 0x46, 0x64, 0x44, 0xCC, 0x9C,
+	 0xFF, 0xFF, 0xF0, 0x02, 0x61, 0x44, 0x25, 0x46, 0x27, 0xDA, 0x5A, 0x87, 0x28, 0x45, 0x45, 0x88,
+	 0x88, 0xF3, 0x87, 0xF1, 0x02, 0xA4, 0x60, 0x46, 0x60, 0x45, 0x00, 0x61, 0x72, 0xF2, 0xFF, 0xFF,
+	 0xAC, 0x86, 0x00, 0xF2, 0x09, 0x03, 0x00, 0xF2, 0x09, 0xF0, 0xAC, 0x86, 0x00, 0xF2, 0xDD, 0x81,
+	 0xFC, 0x02, 0x64, 0x44, 0xAC, 0x86, 0xF6, 0x01, 0x65, 0x44, 0x02, 0xA5, 0x65, 0x46, 0x64, 0x44,
+	 0xCC, 0x9C, 0x61, 0x44, 0xEB, 0x02, 0x25, 0x46, 0x27, 0xDA, 0x5A, 0x87, 0x28, 0x45, 0x45, 0x88,
+	 0x06, 0x60, 0x40, 0x65, 0x8D, 0xF3, 0x01, 0x61, 0xAC, 0x86, 0x00, 0xF2, 0x03, 0x03, 0xD5, 0x80,
+	 0xDD, 0x81, 0xFA, 0x04, 0xCD, 0x84, 0x25, 0x46, 0x27, 0xDA, 0x28, 0x45, 0xC4, 0x84, 0x5A, 0xDA,
+	 0xDA, 0x81, 0x8C, 0xF1, 0x59, 0xD8, 0x1B, 0x60, 0x86, 0x64, 0x18, 0x63, 0xA0, 0xD1, 0x06, 0xA4,
+	 0x59, 0xD8, 0xFC, 0x1F, 0x00, 0x64, 0x59, 0xDA, 0x59, 0xDA, 0x01, 0x60, 0x1C, 0x64, 0x0A, 0x63,
+	 0x58, 0xD1, 0x59, 0xD8, 0xFD, 0x1F, 0x7E, 0xF1, 0x59, 0xD8, 0x45, 0x01, 0x07, 0x4B, 0xB4, 0x60,
+	 0x58, 0x4F, 0x23, 0x78, 0xFF, 0xFF, 0x0B, 0x47, 0x58, 0x4F, 0x21, 0x00, 0x3C, 0x01, 0x07, 0x4B,
+	 0xB4, 0x60, 0x58, 0x4F, 0x23, 0x78, 0xFF, 0xFF, 0x0B, 0x47, 0x27, 0x44, 0x00, 0xBE, 0x08, 0xF0,
+	 0x15, 0x03, 0x64, 0x42, 0x4A, 0xD3, 0x09, 0xF2, 0xDC, 0x83, 0xA2, 0xDD, 0x25, 0x43, 0x09, 0xFC,
+	 0x63, 0x46, 0x27, 0x43, 0x0A, 0xFC, 0x09, 0xFA, 0x08, 0xF8, 0x00, 0xA8, 0x66, 0x43, 0x03, 0x02,
+	 0x64, 0x44, 0x58, 0xDD, 0x03, 0x00, 0x60, 0x46, 0x25, 0x44, 0x0A, 0xFA, 0x1C, 0x01, 0x27, 0x43,
+	 0xE3, 0x81, 0xE9, 0x81, 0x03, 0x05, 0x16, 0x03, 0x00, 0x61, 0x01, 0x00, 0xE4, 0x63, 0x61, 0x46,
+	 0xBF, 0xD2, 0x27, 0x45, 0xDC, 0x84, 0xA2, 0xDA, 0xA3, 0xD2, 0x25, 0x46, 0x88, 0xF8, 0x04, 0x1B,
+	 0x25, 0x44, 0x61, 0x46, 0xBE, 0xDA, 0x04, 0x00, 0x09, 0xFA, 0x60, 0x46, 0x25, 0x44, 0x0A, 0xFA,
+	 0x61, 0x46, 0xA3, 0xDA, 0x2F, 0x58, 0xFF, 0xFF, 0x30, 0x44, 0x02, 0xA8, 0x00, 0xE1, 0x03, 0x02,
+	 0x28, 0xE2, 0x40, 0xFF, 0xA1, 0xFF, 0x84, 0xFF, 0xBF, 0x60, 0xAD, 0x64, 0x40, 0x42, 0xB5, 0x60,
+	 0xA2, 0x64, 0x40, 0x40, 0x9D, 0xF3, 0x66, 0xFB, 0x0F, 0x60, 0x9A, 0x63, 0xAA, 0xF3, 0xBD, 0xDB,
+	 0x00, 0x60, 0x9A, 0x64, 0xBD, 0xDB, 0x02, 0x64, 0xBD, 0xDB, 0x04, 0x64, 0xA3, 0xDB, 0x5C, 0x49,
+	 0x0A, 0x64, 0x40, 0x4B, 0x5C, 0x5C, 0x01, 0x60, 0x39, 0xE2, 0x04, 0x60, 0x00, 0x7A, 0x89, 0xFF,
+	 0x03, 0x60, 0xFF, 0x73, 0x88, 0xFF, 0xB5, 0x60, 0xA2, 0x78, 0xFF, 0xFF, 0xA0, 0xFE, 0x07, 0x05,
+	 0xA3, 0xFE, 0x07, 0x05, 0xA1, 0xFE, 0x50, 0x05, 0x60, 0x64, 0x3B, 0xDB, 0x10, 0x00, 0x20, 0x58,
+	 0xFF, 0xFF, 0xFA, 0x01, 0x12, 0x60, 0xCC, 0x63, 0xA3, 0xD3, 0xFF, 0xFF, 0xFB, 0xB4, 0xA3, 0xDB,
+	 0xA0, 0x4C, 0x59, 0xBC, 0xFF, 0xB4, 0xA0, 0x51, 0xA0, 0x4C, 0x7D, 0xB4, 0xA0, 0x51, 0xA1, 0xFF,
+	 0xFF, 0xFF, 0x83, 0x3E, 0x40, 0x60, 0x0B, 0x65, 0x2B, 0x44, 0x00, 0x63, 0xE8, 0x80, 0xF8, 0x84,
+	 0x02, 0x24, 0x94, 0x84, 0xF3, 0x83, 0xCD, 0x81, 0xFF, 0xFF, 0xF8, 0x02, 0xDF, 0x83, 0x2F, 0x58,
+	 0x40, 0x4B, 0x00, 0x62, 0x01, 0x64, 0xD4, 0x80, 0xE0, 0x84, 0x1A, 0x03, 0xD4, 0x80, 0xE0, 0x84,
+	 0x15, 0x03, 0x61, 0x44, 0x11, 0x61, 0xE0, 0x84, 0xCD, 0x81, 0xFD, 0x04, 0x01, 0x00, 0xE0, 0x84,
+	 0xF2, 0x82, 0xFF, 0xFF, 0x02, 0x24, 0xC6, 0x82, 0x02, 0x28, 0xD6, 0x82, 0xE2, 0x80, 0xCD, 0x81,
+	 0x02, 0x28, 0x01, 0xBC, 0xF4, 0x02, 0x01, 0x2A, 0xC6, 0x82, 0x03, 0x00, 0xE9, 0x81, 0xF2, 0x82,
+	 0x61, 0x44, 0x2D, 0x58, 0xFF, 0xFF, 0x00, 0xA8, 0x10, 0x61, 0x04, 0x03, 0xF0, 0x84, 0xCD, 0x81,
+	 0xFD, 0x04, 0x61, 0x44, 0x2D, 0x58, 0xFF, 0xFF, 0x00, 0x64, 0x3B, 0xDB, 0x16, 0x60, 0xA8, 0x63,
+	 0xBD, 0xD3, 0xA3, 0xD1, 0x60, 0x40, 0x04, 0x3A, 0x2D, 0x00, 0x00, 0x64, 0x4A, 0xDB, 0x1B, 0x60,
+	 0x88, 0x63, 0xA3, 0xD3, 0x46, 0x43, 0xAC, 0x86, 0x3C, 0x45, 0x23, 0x03, 0xD4, 0x80, 0x07, 0xF2,
+	 0x02, 0x02, 0x09, 0xF2, 0xF8, 0x01, 0xD0, 0x80, 0x09, 0xF2, 0xF5, 0x02, 0x60, 0x43, 0x80, 0x67,
+	 0xB0, 0x81, 0x1B, 0x60, 0xDA, 0x62, 0x61, 0x44, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x09, 0x60, 0x08, 0x65, 0x0E, 0xF2, 0x02, 0xF2, 0x60, 0x40,
+	 0xF0, 0x37, 0x05, 0x00, 0x90, 0xF3, 0xD4, 0x80, 0xCC, 0x84, 0x01, 0x02, 0x90, 0xFB, 0x63, 0x44,
+	 0xDA, 0x01, 0x23, 0x46, 0x3C, 0x44, 0xAC, 0x80, 0xFF, 0xFF, 0x89, 0x02, 0x6A, 0xF3, 0x6B, 0xF3,
+	 0x02, 0xA8, 0x02, 0xA8, 0x08, 0x02, 0x00, 0x64, 0x6C, 0xFB, 0x6A, 0xFB, 0x6B, 0xFB, 0x00, 0x64,
+	 0x6D, 0xFB, 0xCA, 0xFE, 0x97, 0x00, 0x03, 0x02, 0x00, 0x64, 0x6B, 0xFB, 0xCA, 0xFE, 0x01, 0x64,
+	 0x3B, 0xDB, 0x1B, 0x60, 0x8E, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x35, 0x03,
+	 0x2C, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x26, 0x8A, 0x00, 0x2E, 0xF2, 0x12, 0x60, 0xCE, 0x65,
+	 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2,
+	 0x16, 0x18, 0x61, 0x46, 0x2E, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46,
+	 0x2D, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46, 0x2C, 0xF0, 0x63, 0x46,
+	 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46, 0xE8, 0x1B, 0x88, 0xF3,
+	 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0x63, 0x02, 0x66, 0x45, 0x63, 0x46, 0x06, 0xF2, 0x65, 0x46,
+	 0x80, 0xB0, 0x09, 0xF2, 0x5C, 0x03, 0xAC, 0x86, 0xCA, 0x01, 0x6B, 0xF3, 0xFF, 0xFF, 0x01, 0xA8,
+	 0xFF, 0xFF, 0x50, 0x02, 0x1B, 0x60, 0xA0, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46,
+	 0x0F, 0x03, 0x77, 0xF1, 0x07, 0xF2, 0xFF, 0xFF, 0xD0, 0x80, 0x09, 0xF2, 0x03, 0x02, 0xAC, 0x86,
+	 0x07, 0xF2, 0xFA, 0x02, 0x03, 0x02, 0x00, 0x64, 0x77, 0xFB, 0xEC, 0x01, 0x46, 0x5C, 0x3F, 0x00,
+	 0x1B, 0x60, 0xA6, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x01, 0x03, 0x37, 0x02,
+	 0x6C, 0xF3, 0xFF, 0xFF, 0x01, 0xA8, 0xFF, 0xFF, 0x14, 0x02, 0x1B, 0x60, 0x94, 0x62, 0xA2, 0xD3,
+	 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x0B, 0x03, 0x2A, 0xF0, 0x20, 0x67, 0x09, 0xF2, 0xB0, 0x83,
+	 0x00, 0xA8, 0x00, 0x64, 0x02, 0x03, 0x2A, 0xFC, 0x01, 0x00, 0x6C, 0xFB, 0x20, 0x00, 0x00, 0x64,
+	 0x6C, 0xFB, 0x1B, 0x60, 0x88, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x12, 0x03,
+	 0x2A, 0xF0, 0x08, 0x67, 0xA0, 0x80, 0xFF, 0xFF, 0x12, 0x03, 0x77, 0xF1, 0x07, 0xF2, 0xFF, 0xFF,
+	 0xD0, 0x80, 0x09, 0xF2, 0x03, 0x02, 0xAC, 0x86, 0x07, 0xF2, 0xFA, 0x02, 0x08, 0x02, 0x00, 0x64,
+	 0x77, 0xFB, 0xE7, 0x01, 0x00, 0x64, 0x77, 0xFB, 0xB5, 0x60, 0xA2, 0x78, 0xFF, 0xFF, 0x66, 0x44,
+	 0xFC, 0xFB, 0x46, 0x5C, 0x21, 0x60, 0x98, 0x63, 0xA3, 0xD3, 0xB5, 0x60, 0x58, 0x4D, 0xE3, 0x78,
+	 0xFF, 0xFF, 0x0D, 0xF2, 0x60, 0x5C, 0x64, 0x5F, 0x0D, 0xFA, 0x07, 0xF0, 0x2A, 0xF2, 0xFF, 0xFF,
+	 0x77, 0xF9, 0x60, 0x40, 0x08, 0x2B, 0x05, 0x00, 0x00, 0x64, 0x48, 0xFB, 0xB8, 0x60, 0x2D, 0x78,
+	 0xFF, 0xFF, 0x00, 0x64, 0xD0, 0x80, 0x88, 0xF3, 0x07, 0x02, 0x23, 0xF0, 0x04, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDA, 0xBD, 0x60, 0x28, 0x78, 0xFF, 0xFF, 0xD0, 0x80, 0xB8, 0xF3, 0x03, 0x03, 0x60, 0x40,
+	 0x03, 0x3A, 0x00, 0x00, 0x2A, 0xF2, 0x00, 0x63, 0x40, 0x47, 0x50, 0x36, 0x01, 0x00, 0x01, 0x63,
+	 0x48, 0xFD, 0x4A, 0xF3, 0x35, 0xFA, 0x10, 0xA4, 0x4A, 0xFB, 0x00, 0x64, 0x15, 0xFA, 0x16, 0xFA,
+	 0x0F, 0xFA, 0xFF, 0xFF, 0x07, 0xF0, 0x66, 0x43, 0x64, 0x46, 0x0E, 0xF0, 0x63, 0x46, 0x00, 0x7F,
+	 0x64, 0x5E, 0x4B, 0xFB, 0x64, 0x44, 0x00, 0x7E, 0xBB, 0xFB, 0x07, 0xF0, 0x88, 0xF3, 0xFF, 0xFF,
+	 0xD0, 0x80, 0xFF, 0xFF, 0x03, 0x03, 0xBB, 0xF3, 0xBA, 0xFB, 0x60, 0x41, 0x03, 0xF2, 0x00, 0xF4,
+	 0x01, 0xF2, 0xFC, 0xA5, 0x00, 0x7F, 0xD4, 0x84, 0x27, 0x45, 0x3C, 0x46, 0x1A, 0xFA, 0x22, 0x63,
+	 0x7B, 0x60, 0xFF, 0x64, 0xA4, 0x84, 0x03, 0x2B, 0x1C, 0x63, 0x2A, 0xFA, 0x60, 0x40, 0xA4, 0x36,
+	 0x14, 0x63, 0x43, 0x4C, 0x00, 0x7C, 0x22, 0xF8, 0x64, 0x41, 0x07, 0xF0, 0x66, 0x43, 0x64, 0x46,
+	 0x36, 0xF2, 0x63, 0x46, 0xFF, 0xB4, 0x22, 0xFA, 0x60, 0x40, 0x00, 0x36, 0x8E, 0x00, 0x2A, 0xF2,
+	 0xFF, 0xFF, 0x60, 0x40, 0x08, 0x3A, 0x89, 0x00, 0x03, 0xF2, 0x00, 0xF4, 0xA0, 0xD2, 0xAA, 0x60,
+	 0xAA, 0x65, 0x5A, 0xD0, 0xD4, 0x80, 0x03, 0x64, 0x0A, 0x02, 0xD0, 0x80, 0x00, 0x64, 0x5A, 0xD0,
+	 0x06, 0x02, 0xD0, 0x80, 0xF8, 0x7F, 0xD0, 0x80, 0x01, 0x03, 0x01, 0x02, 0x01, 0x61, 0x62, 0x43,
+	 0x46, 0x43, 0x3C, 0x46, 0x07, 0xF4, 0x36, 0xF2, 0xFF, 0xFF, 0xA3, 0x46, 0x60, 0x40, 0x22, 0x26,
+	 0x45, 0x00, 0x60, 0x45, 0x63, 0x42, 0x5A, 0xD0, 0xCD, 0x81, 0x3C, 0x46, 0x14, 0x02, 0x64, 0x44,
+	 0x88, 0x3A, 0x11, 0x00, 0x8E, 0x3B, 0x0F, 0x00, 0x65, 0x44, 0x01, 0x26, 0x5E, 0x00, 0x04, 0x26,
+	 0x03, 0x00, 0x10, 0x26, 0x01, 0x00, 0x2D, 0x00, 0xA3, 0x46, 0x37, 0xF2, 0xFF, 0xFF, 0x60, 0x40,
+	 0x80, 0x2B, 0x53, 0x00, 0x3A, 0x00, 0xA3, 0x46, 0x65, 0x44, 0x01, 0x26, 0x0B, 0x00, 0x04, 0x26,
+	 0x03, 0x00, 0x10, 0x26, 0x01, 0x00, 0x1D, 0x00, 0x37, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x80, 0x27,
+	 0x2C, 0x00, 0x17, 0x00, 0x88, 0xF3, 0xFF, 0xFF, 0x60, 0x46, 0x36, 0xF2, 0x66, 0x43, 0xFF, 0xB4,
+	 0x3C, 0x46, 0x22, 0xF0, 0x60, 0x47, 0xB0, 0x84, 0x22, 0xFA, 0x63, 0x46, 0x37, 0xF0, 0x60, 0x40,
+	 0x04, 0x27, 0x03, 0x00, 0x10, 0x27, 0x01, 0x00, 0x04, 0x00, 0x64, 0x40, 0x80, 0x27, 0x15, 0x00,
+	 0x00, 0x00, 0x3C, 0x46, 0x02, 0x65, 0xBC, 0x60, 0x58, 0x78, 0xFF, 0xFF, 0xCD, 0x81, 0x63, 0x42,
+	 0x5A, 0xD0, 0x3C, 0x46, 0x0A, 0x02, 0x64, 0x44, 0x88, 0x3A, 0x07, 0x00, 0x77, 0x37, 0x1D, 0x00,
+	 0x78, 0x37, 0x1B, 0x00, 0x8E, 0x37, 0x19, 0x00, 0xF1, 0x01, 0x3C, 0x46, 0x22, 0xF0, 0x80, 0x67,
+	 0xB0, 0x84, 0xA2, 0xDA, 0xFF, 0xFF, 0x3F, 0xF2, 0x3E, 0xF0, 0x08, 0xA4, 0x60, 0x41, 0x22, 0xF2,
+	 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x26, 0x03, 0x00, 0x04, 0x26, 0x03, 0x00, 0x06, 0x00, 0x04, 0x2B,
+	 0x04, 0x00, 0x61, 0x44, 0x64, 0x40, 0x10, 0x26, 0x3F, 0xFA, 0x3C, 0x46, 0x2C, 0xF2, 0x27, 0x40,
+	 0x01, 0x27, 0x32, 0xF2, 0xB5, 0xF1, 0x60, 0x40, 0x01, 0x26, 0x53, 0x00, 0x09, 0x60, 0x00, 0x64,
+	 0xD0, 0x80, 0x3F, 0xF2, 0x09, 0x06, 0x2C, 0x45, 0xC4, 0x84, 0xD0, 0x80, 0x40, 0x4A, 0x40, 0x06,
+	 0x60, 0x43, 0x64, 0x44, 0x54, 0x88, 0x18, 0x00, 0x60, 0x45, 0x1F, 0x60, 0x9C, 0x64, 0xA0, 0xD3,
+	 0xBB, 0xF3, 0x00, 0xBC, 0x60, 0x47, 0xEC, 0xA0, 0x33, 0x03, 0x32, 0x07, 0x2C, 0x44, 0xC4, 0x81,
+	 0x02, 0x60, 0x1C, 0x65, 0x45, 0x4A, 0xD5, 0x80, 0x2C, 0x45, 0x2A, 0x06, 0x27, 0x40, 0x04, 0x27,
+	 0x30, 0x00, 0x2A, 0x43, 0xD7, 0x85, 0x45, 0x48, 0xB6, 0xF1, 0x0F, 0xF2, 0xD3, 0x80, 0x01, 0x65,
+	 0x01, 0x07, 0x00, 0x65, 0xB4, 0x84, 0x0F, 0xFA, 0x00, 0x63, 0x3F, 0xF2, 0x28, 0x45, 0x60, 0x41,
+	 0xD4, 0x84, 0xDF, 0x83, 0xFC, 0x07, 0x14, 0xFC, 0x61, 0x44, 0x01, 0x36, 0x02, 0x00, 0x09, 0x3A,
+	 0x06, 0x00, 0x28, 0x44, 0x48, 0x88, 0x2A, 0x44, 0xC8, 0x83, 0x43, 0x4A, 0xE5, 0x01, 0x17, 0xFA,
+	 0x04, 0x60, 0x00, 0x64, 0x27, 0x45, 0xB4, 0x84, 0x2A, 0xFA, 0x28, 0x43, 0x16, 0xFC, 0x0D, 0x00,
+	 0x3F, 0xF2, 0x2C, 0x45, 0xB6, 0xF1, 0xC4, 0x81, 0xD1, 0x80, 0x0F, 0xF2, 0x01, 0x06, 0x01, 0xBC,
+	 0x0F, 0xFA, 0x3F, 0xF2, 0x17, 0xFA, 0x01, 0x64, 0x14, 0xFA, 0x07, 0xF0, 0x66, 0x43, 0x64, 0x46,
+	 0x0E, 0xF0, 0x63, 0x46, 0x00, 0x7F, 0x64, 0x5E, 0x4B, 0xFB, 0x64, 0x44, 0x00, 0x7E, 0xBB, 0xFB,
+	 0x62, 0xF1, 0x60, 0x43, 0x60, 0x47, 0xD0, 0x80, 0xC0, 0x65, 0x01, 0x06, 0x64, 0x44, 0x0A, 0x36,
+	 0x70, 0x64, 0x14, 0x36, 0x38, 0x64, 0x37, 0x36, 0x15, 0x64, 0x6E, 0x36, 0x0B, 0x64, 0x44, 0x86,
+	 0x2A, 0xF2, 0x07, 0xF0, 0x60, 0x40, 0xB0, 0x3A, 0x03, 0x00, 0x40, 0x3B, 0x01, 0x00, 0x12, 0x00,
+	 0x0C, 0xB4, 0x08, 0x3A, 0x55, 0x00, 0x22, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x80, 0x2B, 0x50, 0x00,
+	 0x17, 0xF2, 0x22, 0xF0, 0xFF, 0xFF, 0x64, 0x40, 0x22, 0x22, 0x04, 0x00, 0x00, 0xA8, 0x01, 0xA8,
+	 0x47, 0x03, 0x46, 0x03, 0x3C, 0x46, 0x2A, 0xF0, 0x40, 0x67, 0xB0, 0x84, 0xA2, 0xDA, 0x60, 0x45,
+	 0x22, 0xF2, 0xFF, 0xFF, 0x60, 0x43, 0x60, 0x40, 0x01, 0x26, 0x03, 0x00, 0x04, 0x26, 0x0A, 0x00,
+	 0x02, 0x00, 0x04, 0x27, 0x07, 0x00, 0x65, 0x44, 0x2A, 0x65, 0x60, 0x40, 0x03, 0x2B, 0x24, 0x65,
+	 0x45, 0x4C, 0x2E, 0x00, 0x65, 0x44, 0x2E, 0x65, 0x60, 0x40, 0x03, 0x2B, 0x28, 0x65, 0x45, 0x4C,
+	 0x07, 0xF0, 0x88, 0xF3, 0xFF, 0xFF, 0xD0, 0x80, 0x00, 0x7C, 0x03, 0x03, 0x63, 0x40, 0x01, 0x2A,
+	 0x01, 0x00, 0x3D, 0xF1, 0x2A, 0xF2, 0xFF, 0xFF, 0x08, 0xB0, 0x3E, 0xF2, 0x19, 0x03, 0x60, 0x47,
+	 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0x03, 0xB4, 0xD0, 0x80, 0xFF, 0xFF, 0x11, 0x03, 0x1B, 0x60,
+	 0xD4, 0x62, 0x1B, 0x60, 0xAC, 0x64, 0xA2, 0xDB, 0x3C, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB,
+	 0xFF, 0xFF, 0x2B, 0xFF, 0x5C, 0x5C, 0xFC, 0xFC, 0xCE, 0xFE, 0xB5, 0x60, 0xEC, 0x78, 0xFF, 0xFF,
+	 0xBB, 0xF1, 0x2C, 0x45, 0x64, 0x43, 0x17, 0xF2, 0x4B, 0xF1, 0xC4, 0x84, 0xE0, 0x84, 0xE0, 0x84,
+	 0xE0, 0x81, 0x63, 0x40, 0x37, 0x37, 0xE1, 0x81, 0x64, 0x45, 0xB5, 0x60, 0x58, 0x4D, 0xC1, 0x78,
+	 0xFF, 0xFF, 0xAE, 0x82, 0xFC, 0xA2, 0x0A, 0x03, 0x63, 0x40, 0x6E, 0x3B, 0x06, 0x00, 0x60, 0x41,
+	 0x04, 0x0D, 0x63, 0x44, 0x80, 0x7E, 0xBB, 0xFB, 0x61, 0x44, 0xDC, 0x84, 0x2B, 0xF0, 0x1B, 0xFA,
+	 0x64, 0x44, 0x80, 0x27, 0x34, 0x00, 0x16, 0xF2, 0x0F, 0xF0, 0xAC, 0x84, 0x2C, 0x45, 0x29, 0x03,
+	 0x4B, 0xF1, 0xC4, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x81, 0x63, 0x40, 0x37, 0x37, 0xE1, 0x81,
+	 0x64, 0x45, 0x0F, 0xF0, 0xB5, 0x60, 0x58, 0x4D, 0xC1, 0x78, 0xFF, 0xFF, 0xAE, 0x82, 0xFC, 0xA2,
+	 0x0A, 0x03, 0x63, 0x40, 0x6E, 0x3B, 0x06, 0x00, 0x60, 0x41, 0x04, 0x0D, 0x80, 0x67, 0xB0, 0x84,
+	 0x0F, 0xFA, 0x61, 0x44, 0xDC, 0x84, 0x1D, 0xFA, 0xDE, 0x65, 0xC4, 0x85, 0x26, 0x41, 0xE1, 0x81,
+	 0xC5, 0x84, 0x2B, 0xFA, 0x1B, 0xF0, 0xDE, 0x64, 0xC0, 0x85, 0x26, 0x44, 0xE0, 0x84, 0xC4, 0x84,
+	 0x10, 0xFA, 0x26, 0x44, 0x2C, 0xF0, 0x0A, 0xA4, 0x64, 0x40, 0x01, 0x26, 0x00, 0x64, 0x11, 0xFA,
+	 0xBB, 0xF3, 0x13, 0xFA, 0xFF, 0xFF, 0x0D, 0xF2, 0x3E, 0xF0, 0x60, 0x47, 0xFF, 0xB4, 0x64, 0x41,
+	 0x01, 0xB1, 0x01, 0x63, 0x1D, 0x02, 0x60, 0x41, 0xFF, 0x22, 0x04, 0x00, 0xB5, 0x60, 0x58, 0x4F,
+	 0xB2, 0x78, 0xFF, 0xFF, 0x0F, 0x60, 0x92, 0x64, 0xA0, 0xDD, 0x21, 0x60, 0x98, 0x62, 0xA2, 0xD3,
+	 0xB5, 0x60, 0x58, 0x4D, 0xE3, 0x78, 0xFF, 0xFF, 0x60, 0x41, 0x01, 0x63, 0x61, 0x40, 0xFF, 0x22,
+	 0x04, 0x00, 0xB5, 0x60, 0x58, 0x4F, 0xB2, 0x78, 0xFF, 0xFF, 0x0F, 0x60, 0x94, 0x64, 0xA0, 0xDD,
+	 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x40, 0x27, 0x03, 0x00, 0xBA, 0x60, 0x4A, 0x78, 0xFF, 0xFF,
+	 0x22, 0xF2, 0x46, 0x43, 0x60, 0x40, 0x22, 0x26, 0x8B, 0x00, 0x01, 0x26, 0x05, 0x00, 0x04, 0x26,
+	 0x0C, 0x00, 0xBA, 0x60, 0x4A, 0x78, 0xFF, 0xFF, 0x04, 0x27, 0x03, 0x00, 0xBA, 0x60, 0x4A, 0x78,
+	 0xFF, 0xFF, 0x88, 0xF3, 0xFF, 0xFF, 0x60, 0x46, 0x02, 0x00, 0x07, 0xF4, 0xFF, 0xFF, 0xA3, 0x46,
+	 0x2A, 0xF2, 0xA3, 0x46, 0x60, 0x40, 0x08, 0x27, 0x3B, 0x00, 0x88, 0xF3, 0x66, 0x5C, 0xD0, 0x80,
+	 0x37, 0xF0, 0x08, 0x03, 0x64, 0x40, 0x10, 0x2A, 0x12, 0x00, 0xFF, 0x60, 0xEF, 0x64, 0xA0, 0x84,
+	 0x37, 0xFA, 0x24, 0x00, 0x3D, 0xF3, 0x01, 0x61, 0x60, 0x43, 0xCF, 0x83, 0xE1, 0x81, 0xFD, 0x0D,
+	 0xE9, 0x81, 0xA1, 0x80, 0xFF, 0xFF, 0x03, 0x03, 0x91, 0x84, 0x37, 0xFA, 0x17, 0x00, 0x47, 0xF2,
+	 0xFF, 0xFF, 0x10, 0xA0, 0xFF, 0xFF, 0x02, 0x04, 0xFF, 0x60, 0xFF, 0x64, 0xDC, 0x84, 0x47, 0xFA,
+	 0x46, 0xF2, 0x16, 0x04, 0xDC, 0x84, 0x46, 0xFA, 0x45, 0xF2, 0x08, 0x04, 0xDC, 0x84, 0x45, 0xFA,
+	 0x05, 0x04, 0x37, 0xF2, 0xFF, 0xFF, 0xE0, 0x84, 0xE8, 0x84, 0x37, 0xFA, 0x0D, 0x60, 0x3E, 0x62,
+	 0x80, 0xFF, 0x78, 0x44, 0x03, 0xA4, 0xA2, 0xDB, 0xC4, 0x60, 0x05, 0x78, 0xFF, 0xFF, 0x84, 0xFF,
+	 0x0D, 0x60, 0x3E, 0x62, 0x80, 0xFF, 0x78, 0x44, 0x03, 0xA4, 0xA2, 0xDB, 0xC4, 0x60, 0x7D, 0x78,
+	 0xFF, 0xFF, 0x84, 0xFF, 0x88, 0xF3, 0x66, 0x5C, 0xD0, 0x80, 0x00, 0x7C, 0x07, 0x03, 0x66, 0x43,
+	 0x3C, 0x46, 0x22, 0xF2, 0x63, 0x46, 0x60, 0x40, 0x01, 0x2A, 0x01, 0x00, 0x3C, 0xF1, 0x47, 0xF0,
+	 0x64, 0x41, 0x64, 0x47, 0xFF, 0xB4, 0x60, 0x5F, 0x20, 0xBC, 0x80, 0x26, 0x80, 0xAC, 0x60, 0x47,
+	 0xA3, 0x46, 0x3A, 0xFA, 0x64, 0x44, 0x20, 0x7F, 0x34, 0x94, 0x3B, 0xFA, 0xA3, 0x46, 0x46, 0xF2,
+	 0x45, 0xF0, 0xA3, 0x46, 0x3C, 0xFA, 0x3D, 0xF8, 0x08, 0x60, 0x00, 0xEA, 0x0F, 0x64, 0x60, 0x7F,
+	 0xA0, 0x5A, 0x80, 0x60, 0x00, 0xEA, 0xA0, 0x60, 0x00, 0xEA, 0xD1, 0x60, 0x00, 0xEA, 0x8A, 0x00,
+	 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x08, 0x27, 0x35, 0x00, 0x2A, 0xF2, 0x00, 0x60, 0x7C, 0x62,
+	 0x60, 0x40, 0x40, 0x2B, 0x27, 0x00, 0xA2, 0xD3, 0x00, 0x61, 0x60, 0xFE, 0xA0, 0xD3, 0xDE, 0x82,
+	 0xA2, 0xD1, 0xFF, 0xFF, 0x20, 0xFE, 0x64, 0x5F, 0xDC, 0x84, 0xF1, 0x81, 0xC0, 0x2B, 0x04, 0x00,
+	 0x80, 0x2A, 0x02, 0x00, 0x7F, 0xA4, 0xDC, 0x84, 0xFF, 0x3B, 0x03, 0x00, 0x60, 0x47, 0xDC, 0x87,
+	 0x01, 0x61, 0xC0, 0x80, 0x00, 0x36, 0xDC, 0x84, 0x4E, 0xDB, 0x60, 0xFE, 0xDA, 0x82, 0xA2, 0xD1,
+	 0xFF, 0xFF, 0xC1, 0x84, 0xF0, 0x22, 0x10, 0xA4, 0xF0, 0x2A, 0x01, 0x00, 0x00, 0x64, 0xA2, 0xDB,
+	 0xFF, 0xFF, 0x20, 0xFE, 0x00, 0x60, 0x7C, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0xA0, 0xD3, 0x5A, 0xD1,
+	 0x3A, 0xFA, 0x3B, 0xF8, 0x74, 0x62, 0xA2, 0xD0, 0xFF, 0xFF, 0x64, 0x44, 0xE0, 0x7F, 0xA0, 0x5A,
+	 0x64, 0x47, 0xE1, 0x7F, 0x5A, 0xD0, 0xA0, 0x5A, 0x64, 0x44, 0xE2, 0x7F, 0xA0, 0x5A, 0x00, 0x60,
+	 0x80, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0xA0, 0xD1, 0x5A, 0xD1, 0x64, 0x45, 0x64, 0x44, 0xE3, 0x7F,
+	 0xA0, 0x5A, 0x64, 0x47, 0xE4, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xE5, 0x7F, 0xA0, 0x5A,
+	 0x64, 0x47, 0xE6, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xE7, 0x7F, 0xA0, 0x5A, 0x65, 0x40,
+	 0x0D, 0x3A, 0x1C, 0x00, 0x64, 0x47, 0xE8, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xE9, 0x7F,
+	 0xA0, 0x5A, 0x64, 0x47, 0xEA, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xEB, 0x7F, 0xA0, 0x5A,
+	 0x64, 0x47, 0xEC, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xED, 0x7F, 0xA0, 0x5A, 0x64, 0x47,
+	 0xEE, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xEF, 0x7F, 0xA0, 0x5A, 0x08, 0x60, 0x00, 0xEA,
+	 0x65, 0x44, 0x02, 0xA4, 0x60, 0x7F, 0xA0, 0x5A, 0x80, 0x60, 0x00, 0xEA, 0xA0, 0x60, 0x00, 0xEA,
+	 0xD1, 0x60, 0x00, 0xEA, 0x02, 0x64, 0x3B, 0xDB, 0xBD, 0x60, 0xEB, 0x78, 0xFF, 0xFF, 0x66, 0x44,
+	 0xFC, 0xFB, 0x07, 0xF0, 0x00, 0x64, 0xD0, 0x80, 0x88, 0xF3, 0x17, 0x03, 0xD0, 0x80, 0x66, 0x41,
+	 0x64, 0x46, 0x6F, 0xF2, 0x61, 0x46, 0x6D, 0x03, 0x60, 0x40, 0x00, 0x36, 0x6A, 0x00, 0x47, 0xF1,
+	 0x07, 0xF0, 0x64, 0x40, 0x02, 0x26, 0x01, 0x00, 0x0B, 0x00, 0x03, 0x12, 0xBB, 0x60, 0x4E, 0x78,
+	 0xFF, 0xFF, 0xFC, 0x0A, 0xBC, 0x60, 0x48, 0x78, 0xFF, 0xFF, 0xBC, 0x60, 0x48, 0x78, 0xFF, 0xFF,
+	 0x3E, 0xF2, 0x60, 0x45, 0x60, 0x47, 0x07, 0xB0, 0x00, 0x3A, 0x01, 0x00, 0xA6, 0x00, 0x65, 0x44,
+	 0x60, 0x40, 0x01, 0x36, 0x4E, 0x00, 0x02, 0x36, 0x4F, 0x00, 0x03, 0x36, 0x2D, 0x00, 0x04, 0x36,
+	 0x3E, 0x00, 0x52, 0x00, 0x00, 0x64, 0x4C, 0xFB, 0x66, 0x41, 0x64, 0x46, 0x6F, 0xF2, 0xFF, 0xFF,
+	 0x05, 0x7E, 0x6F, 0xFA, 0x61, 0x46, 0x00, 0x65, 0x65, 0x43, 0x66, 0x41, 0x64, 0x46, 0x70, 0xF2,
+	 0x8C, 0xFA, 0x00, 0xA8, 0x6F, 0xF2, 0x15, 0x03, 0x60, 0x47, 0xFF, 0xB5, 0x70, 0xF2, 0x00, 0xBB,
+	 0xFF, 0xA0, 0x07, 0x03, 0x0E, 0x06, 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0x02, 0x02, 0xFB, 0x04,
+	 0x08, 0x00, 0xB9, 0x81, 0xE8, 0x84, 0xD9, 0x81, 0xFD, 0x04, 0x0F, 0x60, 0xA2, 0x65, 0x45, 0xD3,
+	 0x0E, 0xFA, 0x0C, 0xF4, 0xFF, 0xFF, 0x1D, 0x00, 0x4C, 0xF3, 0xFF, 0xFF, 0xDC, 0x84, 0x4C, 0xFB,
+	 0xAB, 0xF3, 0x60, 0x45, 0xD4, 0x80, 0xFF, 0xFF, 0x14, 0x02, 0x1C, 0x60, 0x0C, 0x62, 0x0F, 0x60,
+	 0x96, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0xC3, 0x01, 0x4C, 0xF3,
+	 0x66, 0x41, 0xDC, 0x84, 0x4C, 0xFB, 0x64, 0x46, 0x6F, 0xF2, 0xFF, 0xFF, 0x03, 0x7E, 0x6F, 0xFA,
+	 0x61, 0x46, 0xBC, 0x60, 0x48, 0x78, 0xFF, 0xFF, 0x66, 0x41, 0x64, 0x46, 0x6F, 0xF2, 0xFF, 0xFF,
+	 0x01, 0x7E, 0x6F, 0xFA, 0x61, 0x46, 0xF5, 0x01, 0x66, 0x41, 0x64, 0x46, 0x6F, 0xF2, 0x8C, 0xFA,
+	 0x60, 0x47, 0x70, 0xF2, 0xFF, 0xB5, 0x08, 0x18, 0xE4, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0x03, 0x02,
+	 0xFB, 0x04, 0x01, 0x64, 0x01, 0x00, 0x00, 0x64, 0x0C, 0xF4, 0x00, 0xA8, 0xFF, 0xFF, 0xE4, 0x02,
+	 0x66, 0x41, 0x64, 0x46, 0x6F, 0xF2, 0xFF, 0xFF, 0x60, 0x47, 0x70, 0xF2, 0xFF, 0xB5, 0x61, 0x46,
+	 0x00, 0xA8, 0xFF, 0xFF, 0x29, 0x03, 0xE0, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0xFC, 0x03, 0x66, 0x41,
+	 0x64, 0x46, 0x70, 0xFA, 0x61, 0x46, 0x01, 0x65, 0x65, 0x43, 0x66, 0x41, 0x64, 0x46, 0x70, 0xF2,
+	 0x8C, 0xFA, 0x00, 0xA8, 0x6F, 0xF2, 0x15, 0x03, 0x60, 0x47, 0xFF, 0xB5, 0x70, 0xF2, 0x00, 0xBB,
+	 0xFF, 0xA0, 0x07, 0x03, 0x0E, 0x06, 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0x02, 0x02, 0xFB, 0x04,
+	 0x08, 0x00, 0xB9, 0x81, 0xE8, 0x84, 0xD9, 0x81, 0xFD, 0x04, 0x0F, 0x60, 0xA2, 0x65, 0x45, 0xD3,
+	 0x0E, 0xFA, 0x0C, 0xF4, 0xFF, 0xFF, 0xA3, 0x01, 0xA2, 0x01, 0x65, 0x44, 0x60, 0x40, 0x01, 0x36,
+	 0xA8, 0x01, 0x02, 0x36, 0x01, 0x00, 0xA5, 0x01, 0x66, 0x41, 0x64, 0x46, 0x6F, 0xF2, 0xFF, 0xFF,
+	 0x01, 0x7E, 0x6F, 0xFA, 0x61, 0x46, 0x00, 0x65, 0x65, 0x43, 0x66, 0x41, 0x64, 0x46, 0x70, 0xF2,
+	 0x8C, 0xFA, 0x00, 0xA8, 0x6F, 0xF2, 0x15, 0x03, 0x60, 0x47, 0xFF, 0xB5, 0x70, 0xF2, 0x00, 0xBB,
+	 0xFF, 0xA0, 0x07, 0x03, 0x0E, 0x06, 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0x02, 0x02, 0xFB, 0x04,
+	 0x08, 0x00, 0xB9, 0x81, 0xE8, 0x84, 0xD9, 0x81, 0xFD, 0x04, 0x0F, 0x60, 0xA2, 0x65, 0x45, 0xD3,
+	 0x0E, 0xFA, 0x0C, 0xF4, 0xFF, 0xFF, 0xBC, 0x60, 0x48, 0x78, 0xFF, 0xFF, 0x3E, 0xF2, 0x60, 0x45,
+	 0x60, 0x47, 0x07, 0xB0, 0x00, 0x3A, 0x01, 0x00, 0xA3, 0x00, 0x65, 0x44, 0x60, 0x40, 0x01, 0x36,
+	 0x0B, 0x00, 0x02, 0x36, 0x14, 0x00, 0x03, 0x36, 0x47, 0x00, 0x04, 0x36, 0x5E, 0x00, 0x05, 0x36,
+	 0x0E, 0x00, 0xBC, 0x60, 0x48, 0x78, 0xFF, 0xFF, 0x07, 0xF0, 0x66, 0x41, 0x64, 0x46, 0x6F, 0xF2,
+	 0xFF, 0xFF, 0x02, 0x7E, 0x6F, 0xFA, 0x61, 0x46, 0xBC, 0x60, 0x48, 0x78, 0xFF, 0xFF, 0x07, 0xF0,
+	 0x01, 0x65, 0x65, 0x43, 0x66, 0x41, 0x64, 0x46, 0x70, 0xF2, 0x8C, 0xFA, 0x00, 0xA8, 0x6F, 0xF2,
+	 0x15, 0x03, 0x60, 0x47, 0xFF, 0xB5, 0x70, 0xF2, 0x00, 0xBB, 0xFF, 0xA0, 0x07, 0x03, 0x0E, 0x06,
+	 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0x02, 0x02, 0xFB, 0x04, 0x08, 0x00, 0xB9, 0x81, 0xE8, 0x84,
+	 0xD9, 0x81, 0xFD, 0x04, 0x0F, 0x60, 0xA2, 0x65, 0x45, 0xD3, 0x0E, 0xFA, 0x0C, 0xF4, 0xFF, 0xFF,
+	 0x66, 0x41, 0x64, 0x46, 0x6F, 0xF2, 0x00, 0x63, 0x03, 0x7E, 0x6F, 0xFA, 0x61, 0x46, 0x4C, 0xFD,
+	 0x1C, 0x60, 0x0C, 0x62, 0x0F, 0x60, 0x96, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x04, 0xFF, 0xBC, 0x60, 0x48, 0x78, 0xFF, 0xFF, 0x66, 0x41, 0x64, 0x46, 0x70, 0xF2, 0x4C, 0xF3,
+	 0x02, 0xB0, 0x61, 0x46, 0xCC, 0x84, 0x05, 0x03, 0x04, 0x28, 0x4C, 0xFB, 0xBC, 0x60, 0x48, 0x78,
+	 0xFF, 0xFF, 0x04, 0x28, 0x4C, 0xFB, 0x66, 0x41, 0x64, 0x46, 0x6F, 0xF2, 0xFF, 0xFF, 0x04, 0x7E,
+	 0x6F, 0xFA, 0x61, 0x46, 0xBC, 0x60, 0x48, 0x78, 0xFF, 0xFF, 0x66, 0x41, 0x64, 0x46, 0x6F, 0xF2,
+	 0xFF, 0xFF, 0x60, 0x47, 0xFF, 0xB5, 0x70, 0xF2, 0x61, 0x46, 0xFF, 0xA0, 0xFF, 0xFF, 0x2F, 0x06,
+	 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0x02, 0x02, 0xFB, 0x04, 0x29, 0x00, 0x64, 0x46, 0x70, 0xFA,
+	 0x01, 0x65, 0x65, 0x43, 0x66, 0x41, 0x64, 0x46, 0x70, 0xF2, 0x8C, 0xFA, 0x00, 0xA8, 0x6F, 0xF2,
+	 0x15, 0x03, 0x60, 0x47, 0xFF, 0xB5, 0x70, 0xF2, 0x00, 0xBB, 0xFF, 0xA0, 0x07, 0x03, 0x0E, 0x06,
+	 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0x02, 0x02, 0xFB, 0x04, 0x08, 0x00, 0xB9, 0x81, 0xE8, 0x84,
+	 0xD9, 0x81, 0xFD, 0x04, 0x0F, 0x60, 0xA2, 0x65, 0x45, 0xD3, 0x0E, 0xFA, 0x0C, 0xF4, 0xFF, 0xFF,
+	 0x6F, 0xF2, 0x00, 0x63, 0x03, 0x7E, 0x6F, 0xFA, 0x3C, 0x46, 0x4C, 0xFD, 0x51, 0x00, 0x50, 0x00,
+	 0x65, 0x44, 0x60, 0x40, 0x01, 0x36, 0x03, 0x00, 0x02, 0x36, 0x12, 0x00, 0x49, 0x00, 0x66, 0x41,
+	 0x64, 0x46, 0x70, 0xF2, 0x61, 0x46, 0x01, 0xB0, 0xFF, 0xFF, 0x42, 0x02, 0x07, 0xF0, 0x66, 0x41,
+	 0x64, 0x46, 0x6F, 0xF2, 0xFF, 0xFF, 0x02, 0x7E, 0x6F, 0xFA, 0x61, 0x46, 0x39, 0x00, 0x38, 0x00,
+	 0x07, 0xF0, 0x66, 0x41, 0x64, 0x46, 0x6F, 0xF2, 0xFF, 0xFF, 0x01, 0x7E, 0x6F, 0xFA, 0x60, 0x47,
+	 0xFF, 0xB5, 0x70, 0xF2, 0x61, 0x46, 0xFF, 0xA0, 0xFF, 0xFF, 0xF1, 0x06, 0xE8, 0x84, 0xA4, 0x80,
+	 0xFF, 0xFF, 0x02, 0x02, 0xFB, 0x04, 0xEB, 0x01, 0x66, 0x41, 0x64, 0x46, 0x70, 0xFA, 0x61, 0x46,
+	 0x00, 0x65, 0x65, 0x43, 0x66, 0x41, 0x64, 0x46, 0x70, 0xF2, 0x8C, 0xFA, 0x00, 0xA8, 0x6F, 0xF2,
+	 0x15, 0x03, 0x60, 0x47, 0xFF, 0xB5, 0x70, 0xF2, 0x00, 0xBB, 0xFF, 0xA0, 0x07, 0x03, 0x0E, 0x06,
+	 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0x02, 0x02, 0xFB, 0x04, 0x08, 0x00, 0xB9, 0x81, 0xE8, 0x84,
+	 0xD9, 0x81, 0xFD, 0x04, 0x0F, 0x60, 0xA2, 0x65, 0x45, 0xD3, 0x0E, 0xFA, 0x0C, 0xF4, 0xFF, 0xFF,
+	 0x03, 0x64, 0x3B, 0xDB, 0xCA, 0xFE, 0x47, 0xF1, 0x01, 0x65, 0x32, 0x40, 0x04, 0x27, 0x08, 0x00,
+	 0x2C, 0xF2, 0x64, 0x45, 0x02, 0x22, 0x04, 0x00, 0x60, 0x40, 0x01, 0x26, 0x01, 0x00, 0xEC, 0x00,
+	 0x14, 0xF2, 0x65, 0x40, 0x01, 0x26, 0x1D, 0x00, 0x60, 0x45, 0x05, 0x64, 0x3B, 0xDB, 0x65, 0x44,
+	 0xCC, 0x85, 0x98, 0xF1, 0x1E, 0x60, 0xDE, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xD8, 0x80, 0xC4, 0x84,
+	 0x0B, 0x03, 0x07, 0x05, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x09, 0x04, 0xC6, 0xFE,
+	 0x07, 0x00, 0x00, 0x64, 0xB8, 0x84, 0xA2, 0xDB, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF,
+	 0xAF, 0x00, 0x60, 0x41, 0x2A, 0xF0, 0x00, 0x60, 0x0C, 0x64, 0xA0, 0x84, 0x04, 0x36, 0x02, 0x00,
+	 0x0C, 0x3A, 0x01, 0x00, 0xA5, 0x00, 0x61, 0x45, 0x60, 0x41, 0x98, 0xF1, 0x1E, 0x60, 0xDE, 0x64,
+	 0xA0, 0xD3, 0xFF, 0xFF, 0xD8, 0x80, 0xC4, 0x84, 0x0B, 0x03, 0x07, 0x05, 0xDC, 0x80, 0xD0, 0x80,
+	 0x04, 0x03, 0xA2, 0xDB, 0x09, 0x04, 0xC6, 0xFE, 0x07, 0x00, 0x00, 0x64, 0xB8, 0x84, 0xA2, 0xDB,
+	 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x61, 0x40, 0x08, 0x36, 0x01, 0x00, 0x88, 0x00,
+	 0x14, 0xF2, 0x1C, 0x65, 0x60, 0x41, 0x00, 0x63, 0xCD, 0x81, 0xC7, 0x83, 0xFD, 0x02, 0x3F, 0xF0,
+	 0x2C, 0xF2, 0xC3, 0x83, 0x60, 0x40, 0x01, 0x2A, 0x29, 0x00, 0x98, 0xF1, 0x1E, 0x60, 0xDC, 0x64,
+	 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24,
+	 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x98, 0xF1, 0x1E, 0x60,
+	 0xE2, 0x64, 0xA0, 0xD3, 0x63, 0x45, 0xD8, 0x80, 0xC4, 0x84, 0x0B, 0x03, 0x07, 0x05, 0xDC, 0x80,
+	 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x09, 0x04, 0xC6, 0xFE, 0x07, 0x00, 0x00, 0x64, 0xB8, 0x84,
+	 0xA2, 0xDB, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x52, 0x00, 0x98, 0xF1, 0x1E, 0x60,
+	 0xDA, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB,
+	 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x98, 0xF1,
+	 0x1E, 0x60, 0xE0, 0x64, 0xA0, 0xD3, 0x63, 0x45, 0xD8, 0x80, 0xC4, 0x84, 0x0B, 0x03, 0x07, 0x05,
+	 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x09, 0x04, 0xC6, 0xFE, 0x07, 0x00, 0x00, 0x64,
+	 0xB8, 0x84, 0xA2, 0xDB, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x15, 0xF2, 0xFF, 0xFF,
+	 0x0F, 0xB4, 0x00, 0xA8, 0x01, 0xA8, 0x24, 0x03, 0x12, 0x03, 0x98, 0xF1, 0x1E, 0x60, 0xE8, 0x64,
+	 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24,
+	 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x11, 0x00, 0x98, 0xF1,
+	 0x1E, 0x60, 0xE6, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03,
+	 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF,
+	 0x04, 0x64, 0x3B, 0xDB, 0x07, 0xF0, 0x66, 0x41, 0x64, 0x46, 0x06, 0xF0, 0xFF, 0x60, 0x5F, 0x64,
+	 0xA0, 0x84, 0x06, 0xFA, 0x61, 0x46, 0x1B, 0x60, 0xD4, 0x62, 0x1B, 0x60, 0xAC, 0x64, 0xA2, 0xDB,
+	 0x3C, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x5C, 0x5C, 0xFC, 0xFC,
+	 0xCE, 0xFE, 0xB5, 0x60, 0xEC, 0x78, 0xFF, 0xFF, 0x1F, 0x60, 0x64, 0x62, 0xA2, 0xD3, 0x07, 0xF4,
+	 0x06, 0xF2, 0x02, 0xA8, 0x3C, 0x46, 0x10, 0x03, 0x10, 0xB0, 0x2A, 0xF2, 0x0D, 0x03, 0x0E, 0xF2,
+	 0x0C, 0xB0, 0x60, 0x40, 0xF0, 0x37, 0x20, 0xBC, 0x02, 0x03, 0xFE, 0x7F, 0x0E, 0xFA, 0x23, 0xF0,
+	 0x10, 0x64, 0xB0, 0x84, 0xA2, 0xDA, 0xCC, 0x01, 0x0F, 0xF0, 0x15, 0xF2, 0x64, 0x41, 0x01, 0x2A,
+	 0x02, 0x00, 0xB1, 0xF1, 0x09, 0x00, 0x03, 0x65, 0x07, 0xF0, 0x66, 0x43, 0x64, 0x46, 0x06, 0xF0,
+	 0x63, 0x46, 0xB0, 0xF1, 0x64, 0x40, 0x10, 0x2A, 0x64, 0x45, 0xDC, 0x84, 0xD4, 0x80, 0x15, 0xFA,
+	 0x3B, 0x07, 0x61, 0x40, 0x01, 0x2A, 0x09, 0x00, 0x1F, 0x60, 0x0E, 0x64, 0xA0, 0xD3, 0xFF, 0xFF,
+	 0xDC, 0x84, 0xFF, 0xFF, 0x08, 0x28, 0xA2, 0xDB, 0x08, 0x00, 0x1F, 0x60, 0x10, 0x64, 0xA0, 0xD3,
+	 0xFF, 0xFF, 0xDC, 0x84, 0xFF, 0xFF, 0x08, 0x28, 0xA2, 0xDB, 0x2A, 0xF0, 0x08, 0x67, 0xB0, 0x84,
+	 0xA2, 0xDA, 0x08, 0xF0, 0x1B, 0x60, 0x8E, 0x64, 0xD0, 0x80, 0x07, 0xF2, 0x46, 0x43, 0x88, 0xF1,
+	 0x06, 0x03, 0x60, 0x46, 0x86, 0xF4, 0xD0, 0x80, 0x80, 0xBB, 0x01, 0x03, 0x06, 0xFC, 0x23, 0x46,
+	 0x3E, 0xF2, 0x00, 0x63, 0x01, 0xB0, 0x43, 0x5C, 0xFC, 0xFC, 0x0B, 0x03, 0x1B, 0x60, 0xDA, 0x62,
+	 0x1B, 0x60, 0xA6, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0xB5, 0x60, 0xEC, 0x78, 0xFF, 0xFF, 0x00, 0x64, 0x49, 0xFB, 0x98, 0xF1, 0x1E, 0x60,
+	 0xE8, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB,
+	 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x98, 0xF1,
+	 0x1E, 0x60, 0xEA, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03,
+	 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF,
+	 0x21, 0x60, 0x98, 0x63, 0xA3, 0xD3, 0xB5, 0x60, 0x58, 0x4D, 0xE3, 0x78, 0xFF, 0xFF, 0x0D, 0xF2,
+	 0x60, 0x5C, 0x64, 0x5F, 0x0D, 0xFA, 0x23, 0xF0, 0x01, 0x64, 0xB0, 0x84, 0xA2, 0xDA, 0x07, 0xF0,
+	 0x66, 0x41, 0x64, 0x46, 0x06, 0xF2, 0x7F, 0x65, 0xA4, 0x9E, 0x06, 0xFA, 0x61, 0x46, 0x40, 0x01,
+	 0xBE, 0x60, 0x70, 0x78, 0xFF, 0xFF, 0x21, 0x64, 0x3B, 0xDB, 0x31, 0xF3, 0x01, 0x63, 0xC4, 0xB4,
+	 0x31, 0xFB, 0x32, 0xFD, 0xBE, 0x60, 0x1C, 0x62, 0x42, 0x40, 0xA0, 0x4C, 0x40, 0xBC, 0x7D, 0xB4,
+	 0xA0, 0x51, 0xA0, 0xFE, 0x1A, 0xFF, 0x1B, 0x60, 0xA0, 0x64, 0x08, 0xF0, 0x07, 0xF0, 0xD0, 0x80,
+	 0x1B, 0x60, 0xA6, 0x62, 0x14, 0x02, 0xA2, 0xD3, 0x01, 0x63, 0xAC, 0x86, 0x07, 0xF2, 0x0F, 0x03,
+	 0xD0, 0x80, 0x09, 0xF2, 0xFA, 0x02, 0x23, 0xFC, 0x1B, 0x60, 0xD4, 0x62, 0x1B, 0x60, 0xAC, 0x64,
+	 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x3C, 0x46,
+	 0x06, 0x64, 0xA1, 0xFF, 0x49, 0xFB, 0x83, 0x3E, 0x31, 0xF3, 0x87, 0x60, 0x80, 0x61, 0x1D, 0xF0,
+	 0x60, 0x40, 0x01, 0x2A, 0x15, 0x00, 0xFE, 0xB4, 0x31, 0xFB, 0x00, 0x64, 0x49, 0xFB, 0x01, 0x64,
+	 0x47, 0xFB, 0x21, 0x60, 0x98, 0x63, 0xA3, 0xD3, 0xB5, 0x60, 0x58, 0x4D, 0xE3, 0x78, 0xFF, 0xFF,
+	 0x00, 0x71, 0x64, 0x5F, 0x0D, 0xFA, 0x40, 0x64, 0x3B, 0xDB, 0xBE, 0x60, 0x70, 0x78, 0xFF, 0xFF,
+	 0x02, 0x2A, 0x1B, 0x00, 0xD1, 0x91, 0x8D, 0xE2, 0x41, 0x64, 0x3B, 0xDB, 0x31, 0xF3, 0x21, 0x60,
+	 0xA0, 0x63, 0xFD, 0xB4, 0x31, 0xFB, 0xA3, 0xD3, 0xB5, 0x60, 0x58, 0x4D, 0xE3, 0x78, 0xFF, 0xFF,
+	 0x02, 0x63, 0x60, 0x5C, 0x0D, 0xF2, 0x47, 0xFD, 0xFF, 0xB5, 0x60, 0x47, 0xD0, 0x80, 0xDC, 0x84,
+	 0x1F, 0x03, 0x60, 0x47, 0xB4, 0x84, 0x0D, 0xFA, 0x1B, 0x00, 0x08, 0x2A, 0x07, 0x00, 0x42, 0x64,
+	 0x3B, 0xDB, 0x31, 0xF3, 0xFF, 0xFF, 0xF7, 0xB4, 0x31, 0xFB, 0x12, 0x00, 0x10, 0x2A, 0x09, 0x00,
+	 0x43, 0x64, 0x3B, 0xDB, 0x31, 0xF3, 0xFF, 0xFF, 0xEF, 0xB4, 0x31, 0xFB, 0xBD, 0x60, 0xEB, 0x78,
+	 0xFF, 0xFF, 0x44, 0x64, 0x3B, 0xDB, 0x31, 0xF3, 0xFF, 0xFF, 0xDF, 0xB4, 0x31, 0xFB, 0x00, 0x00,
+	 0x2A, 0x64, 0x3B, 0xDB, 0xB5, 0x60, 0xA2, 0x64, 0x40, 0x40, 0xBA, 0x60, 0x4F, 0x78, 0xFF, 0xFF,
+	 0x12, 0x60, 0xCC, 0x63, 0xA3, 0xD3, 0xFF, 0xFF, 0x02, 0xB5, 0x04, 0xB5, 0x04, 0x03, 0x03, 0x03,
+	 0xBE, 0x60, 0xF7, 0x78, 0xFF, 0xFF, 0xEB, 0x60, 0x58, 0x4E, 0x24, 0x78, 0xFF, 0xFF, 0x31, 0x40,
+	 0x01, 0x2A, 0x29, 0x00, 0x9D, 0xFE, 0x27, 0x04, 0x26, 0x0A, 0x9F, 0xFE, 0x24, 0x05, 0x85, 0xFF,
+	 0x20, 0x44, 0x84, 0xFF, 0x40, 0x26, 0x1F, 0x00, 0x3F, 0x40, 0x20, 0x2B, 0x1C, 0x00, 0x38, 0x69,
+	 0xFF, 0xFF, 0x68, 0x44, 0x01, 0x16, 0xFD, 0x01, 0x01, 0x2A, 0x15, 0x00, 0x1F, 0x60, 0x1A, 0x64,
+	 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xFF, 0xFF, 0x08, 0x28, 0xA2, 0xDB, 0x65, 0xF1, 0x02, 0x60,
+	 0xEE, 0x64, 0x82, 0xFB, 0xFF, 0xFF, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84, 0x83, 0xFB, 0x04, 0x64,
+	 0x84, 0xFB, 0xDF, 0xFE, 0x19, 0xFF, 0x10, 0x64, 0x3B, 0xDB, 0x66, 0xF3, 0x73, 0x45, 0xE0, 0x84,
+	 0xE0, 0x84, 0xE0, 0x84, 0xC4, 0x93, 0x75, 0xF1, 0xC9, 0xFE, 0x64, 0x40, 0x01, 0x26, 0x3D, 0x00,
+	 0x49, 0xF3, 0x3C, 0x46, 0x33, 0x18, 0xCC, 0x84, 0x49, 0xFB, 0x30, 0x02, 0xBF, 0x60, 0xAD, 0x64,
+	 0x40, 0x42, 0xFC, 0xFC, 0x00, 0x64, 0x5C, 0x5C, 0x32, 0xFB, 0x82, 0xFF, 0x5C, 0x47, 0x84, 0xFF,
+	 0x62, 0xFF, 0x1F, 0x60, 0x0A, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xFF, 0xFF, 0x08, 0x28,
+	 0xA2, 0xDB, 0x2A, 0xF2, 0x07, 0xF0, 0x0C, 0xB4, 0x08, 0x3A, 0x07, 0x00, 0x66, 0x41, 0x64, 0x46,
+	 0x06, 0xF0, 0xFF, 0x60, 0xDF, 0x64, 0xA0, 0x84, 0x06, 0xFA, 0x23, 0xF0, 0x01, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDA, 0x1B, 0x60, 0xD4, 0x62, 0x1B, 0x60, 0xAC, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0xCE, 0xFE, 0x06, 0x00, 0x66, 0xF3,
+	 0x73, 0x45, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xC4, 0x93, 0x12, 0x60, 0xC8, 0x63, 0xA3, 0xD3,
+	 0xAD, 0x49, 0x20, 0xB5, 0x08, 0xB1, 0x23, 0x03, 0xE1, 0x81, 0x10, 0xB5, 0x95, 0x81, 0x60, 0x41,
+	 0x18, 0x02, 0x12, 0x60, 0xCA, 0x7C, 0xA4, 0xD3, 0xFF, 0xFF, 0xCC, 0x84, 0xA4, 0xDB, 0x17, 0x02,
+	 0x0A, 0x64, 0xA4, 0xDB, 0x61, 0x44, 0x07, 0xB4, 0xFF, 0xFF, 0x11, 0x02, 0x08, 0xB1, 0xE1, 0x81,
+	 0x95, 0x81, 0xA3, 0xD3, 0x0C, 0x03, 0x08, 0xAC, 0x01, 0xBC, 0xA3, 0xDB, 0xFF, 0xFF, 0x13, 0xFF,
+	 0x06, 0x00, 0x10, 0xAC, 0xA3, 0xDB, 0x12, 0x60, 0xCA, 0x63, 0x0A, 0x7C, 0xA3, 0xD9, 0xB5, 0x60,
+	 0xAF, 0x78, 0xFF, 0xFF, 0x46, 0xF3, 0x45, 0xF1, 0x05, 0x1B, 0x64, 0x44, 0x03, 0x1B, 0x0F, 0x60,
+	 0x92, 0x62, 0xA2, 0xD3, 0x45, 0xFB, 0x00, 0x63, 0x46, 0xFD, 0x60, 0x41, 0x25, 0x64, 0x3B, 0xDB,
+	 0x27, 0x44, 0xEF, 0xB4, 0x40, 0x47, 0x00, 0xB9, 0x71, 0x40, 0x80, 0x27, 0x01, 0x12, 0x19, 0x03,
+	 0xBF, 0x60, 0x4D, 0x62, 0x84, 0xFF, 0x42, 0x42, 0x82, 0xFF, 0xA0, 0x4C, 0x14, 0xBC, 0xFF, 0xB4,
+	 0xA0, 0x51, 0x1F, 0x0A, 0xA1, 0xFF, 0xFF, 0xFF, 0x81, 0x3E, 0x70, 0x44, 0xAC, 0x80, 0x19, 0x0A,
+	 0x71, 0x40, 0x80, 0x27, 0xF7, 0x12, 0x45, 0xF3, 0x27, 0x02, 0x03, 0x18, 0xCC, 0x84, 0x45, 0xFB,
+	 0xF1, 0x02, 0x06, 0x0A, 0xA0, 0x4C, 0xFB, 0xB4, 0xA0, 0x51, 0xA7, 0x60, 0xDF, 0x78, 0xFF, 0xFF,
+	 0x84, 0xFF, 0xBF, 0x60, 0x2A, 0x64, 0x40, 0x42, 0x82, 0xFF, 0xA0, 0x4C, 0x14, 0xBC, 0xFF, 0xB4,
+	 0xA0, 0x51, 0xAF, 0x60, 0x19, 0x78, 0xFF, 0xFF, 0x3C, 0x44, 0xAC, 0x80, 0x32, 0xF1, 0x12, 0x03,
+	 0x64, 0x40, 0x07, 0x22, 0x0F, 0x00, 0xA7, 0x60, 0xC1, 0x78, 0xFF, 0xFF, 0xA0, 0x4C, 0x1C, 0xBC,
+	 0xDF, 0xB4, 0xA0, 0x51, 0xF1, 0x01, 0x06, 0x00, 0x28, 0x64, 0x3A, 0xDB, 0xA0, 0x4C, 0x30, 0xBC,
+	 0xF3, 0xB4, 0xA0, 0x51, 0xA1, 0xFF, 0xFF, 0xFF, 0x81, 0x3E, 0x28, 0x64, 0x3B, 0xDB, 0x0F, 0x60,
+	 0x94, 0x62, 0xA2, 0xD3, 0x32, 0x40, 0x02, 0x27, 0x16, 0x00, 0x46, 0xFB, 0x14, 0x18, 0xBF, 0x60,
+	 0x9B, 0x64, 0x84, 0xFF, 0x40, 0x42, 0x82, 0xFF, 0xA0, 0x4C, 0x14, 0xBC, 0xF7, 0xB4, 0xA0, 0x51,
+	 0xA1, 0xFF, 0xFF, 0xFF, 0x81, 0x3E, 0x70, 0x44, 0xAC, 0x80, 0x46, 0xF3, 0xCA, 0x0A, 0xDC, 0x02,
+	 0xCC, 0x84, 0x46, 0xFB, 0xF5, 0x02, 0x84, 0xFF, 0xBF, 0x60, 0xAD, 0x64, 0x40, 0x42, 0x82, 0xFF,
+	 0x27, 0x44, 0x08, 0xBC, 0x40, 0x47, 0xBB, 0xE1, 0x04, 0x00, 0x3A, 0xE1, 0x31, 0x40, 0x01, 0x26,
+	 0xBB, 0xE1, 0xA7, 0x60, 0xB5, 0x78, 0xFF, 0xFF, 0x24, 0xE2, 0x2D, 0xF3, 0x2C, 0xF3, 0x00, 0xBD,
+	 0xCC, 0x84, 0x08, 0x03, 0x2C, 0xFB, 0x06, 0x02, 0x65, 0x44, 0x2C, 0xFB, 0x8A, 0xFF, 0x80, 0x60,
+	 0x00, 0x75, 0x88, 0xFF, 0xD2, 0xF3, 0x31, 0x40, 0x01, 0x2A, 0x44, 0x00, 0x60, 0x43, 0x04, 0xB0,
+	 0x02, 0xB0, 0x08, 0x24, 0x16, 0x02, 0x29, 0x44, 0xFF, 0xFF, 0x00, 0xA8, 0xCC, 0x81, 0x0E, 0x03,
+	 0x41, 0x49, 0x37, 0x02, 0x63, 0x40, 0x08, 0x2A, 0x09, 0x00, 0xF7, 0xB3, 0x25, 0x60, 0x1C, 0x7C,
+	 0xA4, 0xD1, 0xAD, 0x4F, 0xFD, 0xB4, 0xA0, 0x5D, 0x44, 0x49, 0x2B, 0x00, 0x63, 0x40, 0x02, 0x2A,
+	 0x14, 0x00, 0x25, 0x60, 0x1E, 0x64, 0xA0, 0xD3, 0x25, 0x60, 0x1A, 0x7C, 0xA4, 0xDB, 0x40, 0x49,
+	 0x25, 0x60, 0x20, 0x64, 0xA0, 0xD3, 0x25, 0x60, 0x1C, 0x7C, 0xA4, 0xDB, 0x0C, 0xBB, 0xFD, 0xB3,
+	 0xAD, 0x4F, 0x02, 0xBC, 0x00, 0x7F, 0xA0, 0x5D, 0x14, 0x00, 0x25, 0x60, 0x22, 0x64, 0xA0, 0xD3,
+	 0x25, 0x60, 0x1A, 0x7C, 0x0E, 0x18, 0xA4, 0xDB, 0x40, 0x49, 0x25, 0x60, 0x24, 0x64, 0xA0, 0xD3,
+	 0x25, 0x60, 0x1C, 0x7C, 0xA4, 0xDB, 0x08, 0xBB, 0xFB, 0xB3, 0xAD, 0x4F, 0x02, 0xBC, 0x00, 0x7F,
+	 0xA0, 0x5D, 0xD2, 0xFD, 0x01, 0x60, 0x0C, 0x61, 0xA1, 0xD3, 0x61, 0x43, 0x17, 0x18, 0x58, 0xD3,
+	 0x62, 0x41, 0x03, 0x18, 0xCC, 0x84, 0xA1, 0xDB, 0x11, 0x00, 0x49, 0xD3, 0xA3, 0xDB, 0x06, 0xA1,
+	 0xA1, 0xD3, 0x59, 0xD1, 0x60, 0x45, 0xA5, 0xD3, 0x59, 0xD1, 0xB0, 0x84, 0xA5, 0xDB, 0x64, 0x44,
+	 0x06, 0x36, 0xCD, 0xFE, 0x07, 0x36, 0xD6, 0xFE, 0xE5, 0x01, 0x23, 0x46, 0xB5, 0x60, 0xAF, 0x78,
+	 0xFF, 0xFF, 0x46, 0x43, 0x1C, 0x60, 0x0A, 0x61, 0xA1, 0xD3, 0x59, 0xD1, 0x06, 0x1B, 0x59, 0xD3,
+	 0x59, 0xD1, 0x03, 0x1B, 0x59, 0xD3, 0x59, 0xD1, 0xF0, 0x18, 0x00, 0x63, 0x49, 0xDD, 0x60, 0x40,
+	 0x02, 0x36, 0x11, 0x00, 0x03, 0x36, 0x32, 0x00, 0x01, 0x36, 0x08, 0x00, 0x05, 0x3A, 0xEA, 0x01,
+	 0xA4, 0xD3, 0x5A, 0xD3, 0x9C, 0x85, 0xA4, 0x84, 0xA2, 0xDB, 0xE4, 0x01, 0x01, 0x60, 0x0C, 0x61,
+	 0x00, 0x64, 0xA1, 0xDB, 0xDF, 0x01, 0xC0, 0x60, 0x4F, 0x64, 0x40, 0x45, 0x22, 0x00, 0x01, 0x60,
+	 0x0C, 0x66, 0xA6, 0xD3, 0x04, 0xA1, 0x60, 0x43, 0xA1, 0xD3, 0xC9, 0x81, 0x60, 0x45, 0x00, 0xBB,
+	 0xA1, 0xDB, 0xBE, 0xD3, 0x09, 0x03, 0xD4, 0x84, 0x9C, 0x84, 0xDC, 0x84, 0xFF, 0xFF, 0x04, 0x0E,
+	 0xA3, 0xD1, 0x63, 0x46, 0x64, 0x43, 0xF2, 0x01, 0x9C, 0x84, 0xDC, 0x85, 0x49, 0xDD, 0x61, 0x44,
+	 0x00, 0xBB, 0xA6, 0xDB, 0x02, 0x03, 0x65, 0x44, 0xBE, 0xDB, 0xBC, 0x01, 0xC0, 0x60, 0x2A, 0x64,
+	 0x40, 0x45, 0x01, 0x60, 0x0C, 0x66, 0xA6, 0xD3, 0xFF, 0xFF, 0xD0, 0x80, 0x0F, 0x18, 0x02, 0x03,
+	 0x60, 0x46, 0xF9, 0x01, 0x58, 0xD3, 0xA4, 0xD3, 0x60, 0x45, 0x00, 0x63, 0xA4, 0xDD, 0x05, 0x18,
+	 0x58, 0xD3, 0xFF, 0xFF, 0xC4, 0x83, 0xA2, 0xDD, 0xCA, 0x84, 0xA6, 0xDB, 0x25, 0x58, 0x64, 0x41,
+	 0x30, 0x44, 0x02, 0xA8, 0x00, 0xE1, 0x06, 0x02, 0x40, 0xFF, 0x42, 0xFF, 0x43, 0xFF, 0x44, 0xFF,
+	 0x45, 0xFF, 0xA1, 0xFF, 0x88, 0xFF, 0x85, 0xFF, 0x21, 0xE1, 0x5C, 0x40, 0xC0, 0x60, 0x9A, 0x78,
+	 0xFF, 0xFF, 0x43, 0xFF, 0x39, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x84, 0x3E, 0xFB, 0x01, 0xA0, 0x4C,
+	 0x3D, 0x46, 0x2A, 0xF2, 0x46, 0x4D, 0x10, 0x25, 0x0E, 0x00, 0x09, 0xE1, 0xA1, 0xFF, 0x66, 0x40,
+	 0x0F, 0xF2, 0x01, 0x29, 0x02, 0x00, 0x40, 0xFF, 0x0A, 0xBC, 0xA2, 0xDA, 0x08, 0x25, 0xE9, 0x01,
+	 0xCB, 0xFE, 0x5C, 0x5D, 0xE7, 0x01, 0x44, 0xFF, 0x03, 0x2B, 0x21, 0x00, 0x89, 0xF3, 0x06, 0x61,
+	 0x60, 0x43, 0x66, 0x45, 0x31, 0xF0, 0x63, 0x46, 0x05, 0xF2, 0x65, 0x46, 0xD0, 0x80, 0x30, 0xF0,
+	 0x0F, 0x02, 0x63, 0x46, 0x04, 0xF2, 0x65, 0x46, 0xD0, 0x80, 0x2F, 0xF0, 0x09, 0x02, 0x63, 0x46,
+	 0x03, 0xF2, 0x65, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x03, 0x02, 0xFF, 0xFF, 0x48, 0xFE, 0x06, 0x00,
+	 0xCD, 0x81, 0x02, 0xA3, 0xE7, 0x02, 0x88, 0xF1, 0x08, 0xFE, 0x64, 0x43, 0x26, 0x03, 0x31, 0xF2,
+	 0x12, 0x60, 0xCE, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46,
+	 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46, 0x31, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2,
+	 0x0C, 0x02, 0x61, 0x46, 0x30, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46,
+	 0x2F, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46,
+	 0xE8, 0x1B, 0x88, 0xF3, 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0x07, 0xFC, 0x3F, 0xF2, 0x09, 0x60,
+	 0xB0, 0x65, 0xD4, 0x80, 0x2A, 0xF2, 0xA1, 0x05, 0x08, 0x25, 0x93, 0x01, 0x00, 0x64, 0x0D, 0x60,
+	 0x2C, 0x61, 0x40, 0x4B, 0xA1, 0xDB, 0x2D, 0x46, 0x3B, 0xF2, 0x88, 0xF1, 0x87, 0xF4, 0x60, 0x40,
+	 0x20, 0x2B, 0x12, 0x00, 0xD3, 0x80, 0x2C, 0xF0, 0x90, 0x03, 0x07, 0xF4, 0x64, 0x40, 0x01, 0x26,
+	 0x88, 0xF5, 0xB6, 0xF4, 0x2D, 0x46, 0x04, 0x64, 0x04, 0xB3, 0x22, 0xFA, 0x04, 0x03, 0xC2, 0x60,
+	 0x11, 0x78, 0xFF, 0xFF, 0x01, 0x00, 0xE0, 0x00, 0x74, 0x62, 0xA2, 0xD0, 0xFF, 0xFF, 0x64, 0x44,
+	 0xE0, 0x7F, 0xA0, 0x5B, 0x64, 0x47, 0xE1, 0x7F, 0x5A, 0xD0, 0xA0, 0x5B, 0x64, 0x44, 0xE2, 0x7F,
+	 0xA0, 0x5B, 0x64, 0x47, 0x7C, 0x5F, 0xE8, 0x84, 0xE8, 0x85, 0x0C, 0x60, 0x3A, 0x64, 0x44, 0xD3,
+	 0x5A, 0xD1, 0x03, 0x1B, 0xC2, 0x60, 0x04, 0x78, 0xFF, 0xFF, 0x60, 0x45, 0x64, 0x44, 0xE3, 0x7F,
+	 0xA0, 0x5B, 0x64, 0x47, 0xE4, 0x7F, 0x5A, 0xD1, 0xA0, 0x5B, 0x64, 0x44, 0xE5, 0x7F, 0xA0, 0x5B,
+	 0x64, 0x47, 0xE6, 0x7F, 0x5A, 0xD1, 0xA0, 0x5B, 0x64, 0x44, 0xE7, 0x7F, 0xA0, 0x5B, 0x65, 0x40,
+	 0x0D, 0x3A, 0x1C, 0x00, 0x64, 0x47, 0xE8, 0x7F, 0x5A, 0xD1, 0xA0, 0x5B, 0x64, 0x44, 0xE9, 0x7F,
+	 0xA0, 0x5B, 0x64, 0x47, 0xEA, 0x7F, 0x5A, 0xD1, 0xA0, 0x5B, 0x64, 0x44, 0xEB, 0x7F, 0xA0, 0x5B,
+	 0x64, 0x47, 0xEC, 0x7F, 0x5A, 0xD1, 0xA0, 0x5B, 0x64, 0x44, 0xED, 0x7F, 0xA0, 0x5B, 0x64, 0x47,
+	 0xEE, 0x7F, 0x5A, 0xD1, 0xA0, 0x5B, 0x64, 0x44, 0xEF, 0x7F, 0xA0, 0x5B, 0x65, 0x44, 0xD8, 0x84,
+	 0x08, 0x25, 0x78, 0x00, 0x60, 0x7F, 0xA0, 0x5B, 0x80, 0x60, 0x00, 0xEB, 0xA0, 0x60, 0x00, 0xEB,
+	 0xD1, 0x60, 0x00, 0xEB, 0x3F, 0xF2, 0x04, 0x65, 0xC4, 0x83, 0x0A, 0xE1, 0xB3, 0xFF, 0x9A, 0xFF,
+	 0xCB, 0x83, 0x00, 0xF4, 0x10, 0x62, 0x6C, 0x61, 0x0E, 0xA3, 0xAB, 0x84, 0xF2, 0xA3, 0xA1, 0xFF,
+	 0x08, 0x00, 0x00, 0xF4, 0x81, 0xF2, 0x02, 0x62, 0xC9, 0x81, 0xAB, 0x84, 0xA1, 0xFF, 0x01, 0x00,
+	 0xA2, 0xDC, 0x7A, 0xD4, 0xFD, 0x1C, 0xA2, 0xDC, 0x08, 0x25, 0x54, 0x00, 0xF2, 0x1D, 0x7C, 0xA8,
+	 0xD9, 0x81, 0xEF, 0x03, 0xFF, 0xB1, 0x09, 0x1E, 0x02, 0x02, 0x00, 0xF4, 0x02, 0x62, 0x5A, 0xD2,
+	 0x89, 0xFF, 0x80, 0x4F, 0x6F, 0x44, 0xA2, 0xDA, 0x88, 0xFF, 0x98, 0xFF, 0x09, 0xE1, 0xA1, 0xFF,
+	 0x3D, 0x46, 0x08, 0x25, 0x3F, 0x00, 0x40, 0xFF, 0x0F, 0xF0, 0x0A, 0x64, 0xB0, 0x84, 0x18, 0x14,
+	 0xF7, 0xB4, 0xA2, 0xDA, 0x0D, 0x60, 0x2C, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x2A,
+	 0x0C, 0x00, 0xD1, 0xF5, 0xD0, 0xF4, 0x0D, 0x60, 0x2C, 0x61, 0x59, 0xD1, 0x37, 0xF8, 0x05, 0x64,
+	 0x59, 0xD1, 0xCC, 0x84, 0xBD, 0xD8, 0xFC, 0x02, 0x2D, 0x46, 0xC0, 0x60, 0xB0, 0x78, 0xFF, 0xFF,
+	 0xA2, 0xDA, 0x2D, 0x46, 0x3B, 0xF0, 0xFF, 0xFF, 0x64, 0x40, 0x20, 0x2B, 0x18, 0x00, 0xD1, 0xF5,
+	 0xB7, 0xF0, 0x2A, 0x44, 0xA4, 0x84, 0xFF, 0xFF, 0x2F, 0x26, 0x10, 0x00, 0x2D, 0x46, 0x64, 0x44,
+	 0x3A, 0xF0, 0xBC, 0xF0, 0x64, 0x5F, 0x3D, 0xF0, 0x07, 0xF4, 0xD0, 0xF4, 0xFF, 0xFF, 0x08, 0xA3,
+	 0x5B, 0xD8, 0x65, 0x5C, 0x5B, 0xD8, 0x5B, 0xDA, 0x2D, 0x46, 0x01, 0x00, 0x2D, 0x46, 0xC0, 0x60,
+	 0xB0, 0x78, 0xFF, 0xFF, 0x98, 0xFF, 0x43, 0xFF, 0x40, 0xFF, 0xB0, 0xFF, 0xB1, 0xFF, 0x2D, 0x46,
+	 0x0D, 0x60, 0x2C, 0x61, 0xA1, 0xD3, 0x2D, 0x46, 0x60, 0x40, 0x01, 0x2A, 0x0A, 0x00, 0xD1, 0xF5,
+	 0xD0, 0xF4, 0x59, 0xD1, 0x37, 0xF8, 0x05, 0x64, 0x59, 0xD1, 0xCC, 0x84, 0xBD, 0xD8, 0xFC, 0x02,
+	 0x2D, 0x46, 0xC0, 0x60, 0x9A, 0x78, 0xFF, 0xFF, 0x98, 0xFF, 0x09, 0xE1, 0xA1, 0xFF, 0x3D, 0x46,
+	 0x08, 0x25, 0xE0, 0x01, 0x0F, 0xF2, 0x40, 0xFF, 0x02, 0xBC, 0xA2, 0xDA, 0xC0, 0x60, 0xB0, 0x78,
+	 0xFF, 0xFF, 0x00, 0x64, 0x0D, 0x60, 0x2C, 0x62, 0xA2, 0xDB, 0x04, 0x64, 0x22, 0xFA, 0x87, 0xF4,
+	 0x88, 0xF1, 0xFF, 0xFF, 0xD3, 0x80, 0x3B, 0xF2, 0xE7, 0x03, 0x60, 0x47, 0xC0, 0xB7, 0x02, 0xFE,
+	 0xF0, 0x84, 0xF0, 0x84, 0xF0, 0x84, 0x00, 0xA8, 0x40, 0x4A, 0x16, 0x03, 0xE0, 0x81, 0x61, 0x43,
+	 0x42, 0xFE, 0x00, 0x64, 0xF0, 0x84, 0xFE, 0x1F, 0x40, 0x4A, 0xE1, 0x84, 0xE0, 0x84, 0x2D, 0x46,
+	 0x07, 0xF4, 0xE0, 0x81, 0x37, 0xF0, 0x2A, 0x47, 0x0C, 0x60, 0x7A, 0x63, 0xA0, 0x84, 0x47, 0x9C,
+	 0x10, 0x03, 0x7C, 0x44, 0xA0, 0x63, 0x11, 0x00, 0x20, 0x64, 0x40, 0x4A, 0x63, 0x46, 0x37, 0xF0,
+	 0x66, 0x44, 0x64, 0x40, 0x80, 0x2B, 0x05, 0x00, 0x00, 0x60, 0x70, 0x7C, 0x00, 0x60, 0x90, 0x63,
+	 0x04, 0x00, 0x2D, 0x46, 0xC2, 0x60, 0x04, 0x78, 0xFF, 0xFF, 0x2D, 0x46, 0xCE, 0xFB, 0xCF, 0xF9,
+	 0xD0, 0xFD, 0x07, 0xF2, 0xD1, 0xFB, 0x60, 0x46, 0x37, 0xF0, 0x2A, 0x44, 0x0D, 0x60, 0x2C, 0x62,
+	 0x5A, 0xD9, 0x00, 0x65, 0x45, 0x4B, 0xA0, 0x84, 0xFF, 0xFF, 0x3F, 0x22, 0x05, 0x00, 0x90, 0x84,
+	 0x37, 0xFA, 0x01, 0x64, 0x40, 0x4B, 0x21, 0x00, 0xAD, 0x46, 0x0A, 0xA3, 0x3D, 0xF2, 0xAD, 0x46,
+	 0xA3, 0xD0, 0xAD, 0x46, 0xD0, 0x80, 0x3C, 0xF2, 0xAD, 0x46, 0x02, 0x03, 0x16, 0x07, 0x14, 0x04,
+	 0x5B, 0xD0, 0xAD, 0x46, 0xD0, 0x80, 0x3B, 0xF2, 0x03, 0x03, 0xAD, 0x46, 0x0E, 0x07, 0x0C, 0x04,
+	 0x3A, 0xF0, 0xAD, 0x46, 0x5B, 0xD0, 0x64, 0x5F, 0xD0, 0x80, 0x2B, 0x44, 0x18, 0x07, 0x04, 0x03,
+	 0xD0, 0x84, 0x10, 0xA4, 0xFF, 0xFF, 0x13, 0x07, 0x7F, 0x01, 0x01, 0x64, 0x0D, 0x60, 0x2C, 0x62,
+	 0xA2, 0xDB, 0x2D, 0x46, 0x0D, 0x60, 0x3C, 0x62, 0x80, 0xFF, 0x78, 0x44, 0x03, 0xA4, 0xA2, 0xDB,
+	 0xC2, 0x60, 0xAA, 0x78, 0xFF, 0xFF, 0x85, 0xFF, 0x2D, 0x46, 0x08, 0x25, 0x53, 0x01, 0x2D, 0x46,
+	 0x0D, 0x60, 0x3C, 0x62, 0x80, 0xFF, 0x78, 0x44, 0x03, 0xA4, 0xA2, 0xDB, 0xC3, 0x60, 0x33, 0x78,
+	 0xFF, 0xFF, 0x85, 0xFF, 0x2D, 0x46, 0x08, 0x25, 0x45, 0x01, 0x00, 0x60, 0x0F, 0x64, 0xC1, 0x60,
+	 0x70, 0x78, 0xFF, 0xFF, 0x07, 0xF4, 0x66, 0x41, 0x03, 0xF2, 0x04, 0xF2, 0x40, 0x42, 0x05, 0xF2,
+	 0x40, 0x43, 0x40, 0x44, 0x61, 0x46, 0x3C, 0xF2, 0x3D, 0xF2, 0x40, 0x40, 0x40, 0x41, 0x0D, 0x60,
+	 0x70, 0x65, 0x00, 0x61, 0xCF, 0xF1, 0xCE, 0xF5, 0x44, 0x4C, 0x2C, 0x5C, 0xE9, 0x80, 0x00, 0x64,
+	 0xF0, 0x84, 0xF0, 0x84, 0xC0, 0x83, 0xBD, 0xD2, 0x24, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C,
+	 0x20, 0x44, 0x40, 0x80, 0xDB, 0x83, 0xBD, 0xD2, 0x20, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C,
+	 0x21, 0x44, 0x40, 0x81, 0xDB, 0x83, 0xBD, 0xD2, 0x21, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C,
+	 0x22, 0x44, 0x40, 0x82, 0xDB, 0x83, 0xBD, 0xD2, 0x22, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C,
+	 0x23, 0x44, 0x40, 0x83, 0xF2, 0xA3, 0xBD, 0xD2, 0x23, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C,
+	 0x24, 0x44, 0xC0, 0x9C, 0x41, 0x84, 0xDD, 0x81, 0x08, 0x2A, 0xA7, 0x01, 0x0D, 0x60, 0x2E, 0x61,
+	 0x05, 0x64, 0xD0, 0xF4, 0xD1, 0xF5, 0xFE, 0xA3, 0x5B, 0xD0, 0xCC, 0x84, 0x59, 0xD9, 0xFC, 0x02,
+	 0xD0, 0xF3, 0xD1, 0xF5, 0x60, 0x42, 0x20, 0x44, 0xA2, 0xDA, 0x21, 0x44, 0x5A, 0xDA, 0x22, 0x44,
+	 0x5A, 0xDA, 0x23, 0x44, 0x5A, 0xDA, 0x24, 0x44, 0x5A, 0xDA, 0x61, 0x46, 0x0D, 0x60, 0x3C, 0x62,
+	 0xA2, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x41, 0xD0, 0xF3, 0xD1, 0xF5, 0xA0, 0xD2, 0x5A, 0xD0,
+	 0x40, 0x40, 0x44, 0x41, 0x5A, 0xD2, 0x5A, 0xD0, 0x40, 0x42, 0x5A, 0xD0, 0x44, 0x43, 0x61, 0x46,
+	 0xBA, 0xF0, 0x3B, 0xF2, 0x44, 0x44, 0x65, 0x5F, 0x40, 0x85, 0xCF, 0xF4, 0xCE, 0xF5, 0x43, 0x4C,
+	 0x0D, 0x60, 0x70, 0x65, 0xBD, 0xD2, 0x25, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84,
+	 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x20, 0x44,
+	 0x40, 0x80, 0xBD, 0xD2, 0x20, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1,
+	 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x21, 0x44, 0x40, 0x81,
+	 0xBD, 0xD2, 0x21, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x22, 0x44, 0x40, 0x82, 0xBD, 0xD2,
+	 0x22, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x23, 0x44, 0x40, 0x83, 0xBD, 0xD2, 0x23, 0x5C,
+	 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84,
+	 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x24, 0x44, 0x40, 0x84, 0xBD, 0xD2, 0x24, 0x5C, 0x90, 0x9C,
+	 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1,
+	 0x64, 0x47, 0x90, 0x9C, 0x25, 0x44, 0x40, 0x85, 0x61, 0x46, 0x3A, 0xF0, 0xFF, 0xFF, 0x64, 0x44,
+	 0xE0, 0x7F, 0xA0, 0x5B, 0x64, 0x47, 0xE1, 0x7F, 0x5A, 0xD0, 0xA0, 0x5B, 0x64, 0x44, 0xE2, 0x7F,
+	 0xA0, 0x5B, 0x64, 0x47, 0xCE, 0xF5, 0xBD, 0xD2, 0x25, 0x5C, 0x90, 0x84, 0xE8, 0x80, 0xF8, 0x84,
+	 0x20, 0x5C, 0x40, 0x80, 0x20, 0x44, 0xE4, 0x7F, 0xA0, 0x5B, 0x20, 0x47, 0xE5, 0x7F, 0xA0, 0x5B,
+	 0xBD, 0xD2, 0x20, 0x5C, 0x90, 0x84, 0xE8, 0x80, 0xF8, 0x84, 0x21, 0x5C, 0x40, 0x81, 0x21, 0x44,
+	 0xE6, 0x7F, 0xA0, 0x5B, 0x21, 0x47, 0xE7, 0x7F, 0xA0, 0x5B, 0x21, 0x44, 0xE8, 0x80, 0xF8, 0x84,
+	 0x22, 0x5C, 0x40, 0x82, 0x22, 0x44, 0xE8, 0x7F, 0xA0, 0x5B, 0x22, 0x47, 0xE9, 0x7F, 0xA0, 0x5B,
+	 0x22, 0x44, 0xE8, 0x80, 0xF8, 0x84, 0x23, 0x5C, 0x40, 0x83, 0x23, 0x44, 0xEA, 0x7F, 0xA0, 0x5B,
+	 0x23, 0x47, 0xEB, 0x7F, 0xA0, 0x5B, 0x23, 0x44, 0xE8, 0x80, 0xF8, 0x84, 0x24, 0x5C, 0x40, 0x84,
+	 0x24, 0x44, 0xEC, 0x7F, 0xA0, 0x5B, 0x24, 0x47, 0xED, 0x7F, 0xA0, 0x5B, 0x24, 0x44, 0xE8, 0x80,
+	 0xF8, 0x84, 0x25, 0x5C, 0x40, 0x85, 0x25, 0x44, 0xEE, 0x7F, 0xA0, 0x5B, 0x25, 0x47, 0xEF, 0x7F,
+	 0xA0, 0x5B, 0x2C, 0x43, 0xA3, 0xD2, 0x25, 0x5C, 0x90, 0x81, 0xE9, 0x84, 0xE3, 0x7F, 0xA0, 0x5B,
+	 0x0D, 0x60, 0x3C, 0x62, 0xA2, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0xCB, 0xF3, 0x5A, 0xD3, 0x40, 0x48,
+	 0x5A, 0xD3, 0x40, 0x49, 0x40, 0x4A, 0x00, 0x60, 0x70, 0x7C, 0x44, 0x4D, 0x45, 0xF2, 0x46, 0xF2,
+	 0x40, 0x47, 0x40, 0x46, 0x0D, 0x60, 0x70, 0x65, 0x00, 0x61, 0x2D, 0x5C, 0xE9, 0x80, 0x00, 0x64,
+	 0xF0, 0x84, 0xF0, 0x84, 0xC0, 0x83, 0xBD, 0xD2, 0x2A, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C,
+	 0x26, 0x44, 0x40, 0x86, 0xDB, 0x83, 0xBD, 0xD2, 0x26, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C,
+	 0x27, 0x44, 0x40, 0x87, 0xDB, 0x83, 0xBD, 0xD2, 0x27, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C,
+	 0x28, 0x44, 0x40, 0x88, 0xDB, 0x83, 0xBD, 0xD2, 0x28, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C,
+	 0x29, 0x44, 0x40, 0x89, 0xF2, 0xA3, 0xBD, 0xD2, 0x29, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C,
+	 0x2A, 0x44, 0xC0, 0x9C, 0x41, 0x8A, 0xDD, 0x81, 0x08, 0x2A, 0xA7, 0x01, 0x26, 0x44, 0x40, 0xFA,
+	 0x27, 0x44, 0x41, 0xFA, 0x28, 0x44, 0x42, 0xFA, 0x29, 0x44, 0x43, 0xFA, 0x2A, 0x44, 0x44, 0xFA,
+	 0x0D, 0x60, 0x3E, 0x62, 0xA2, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x60, 0x80, 0x7C, 0x44, 0x4D,
+	 0x2D, 0x42, 0xA2, 0xD2, 0x5A, 0xD0, 0x40, 0x46, 0x44, 0x47, 0x5A, 0xD2, 0x5A, 0xD0, 0x40, 0x48,
+	 0x5A, 0xD0, 0x44, 0x49, 0x47, 0xF2, 0x44, 0x4A, 0x40, 0x8B, 0x60, 0x5C, 0x64, 0x47, 0xE0, 0x7F,
+	 0xA0, 0x5A, 0xFF, 0xB4, 0x20, 0xBC, 0x7F, 0xB4, 0xE1, 0x7F, 0xA0, 0x5A, 0x64, 0x44, 0xE2, 0x7F,
+	 0xA0, 0x5A, 0x00, 0x60, 0x70, 0x63, 0x0D, 0x60, 0x70, 0x65, 0xBD, 0xD2, 0x2B, 0x5C, 0x90, 0x9C,
+	 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1,
+	 0x64, 0x47, 0x90, 0x9C, 0x26, 0x44, 0x40, 0x86, 0xBD, 0xD2, 0x26, 0x5C, 0x90, 0x9C, 0x64, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47,
+	 0x90, 0x9C, 0x27, 0x44, 0x40, 0x87, 0xBD, 0xD2, 0x27, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C,
+	 0x28, 0x44, 0x40, 0x88, 0xBD, 0xD2, 0x28, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84,
+	 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x29, 0x44,
+	 0x40, 0x89, 0xBD, 0xD2, 0x29, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1,
+	 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x2A, 0x44, 0x40, 0x8A,
+	 0xBD, 0xD2, 0x2A, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x2B, 0x44, 0x40, 0x8B, 0xBD, 0xD2,
+	 0x2B, 0x5C, 0x90, 0x84, 0xE8, 0x80, 0xF8, 0x84, 0x26, 0x5C, 0x40, 0x86, 0x26, 0x44, 0xE4, 0x7F,
+	 0xA0, 0x5A, 0x26, 0x47, 0xE5, 0x7F, 0xA0, 0x5A, 0xBD, 0xD2, 0x26, 0x5C, 0x90, 0x84, 0xE8, 0x80,
+	 0xF8, 0x84, 0x27, 0x5C, 0x40, 0x87, 0x27, 0x44, 0xE6, 0x7F, 0xA0, 0x5A, 0x27, 0x47, 0xE7, 0x7F,
+	 0xA0, 0x5A, 0x27, 0x44, 0xE8, 0x80, 0xF8, 0x84, 0x28, 0x5C, 0x40, 0x88, 0x28, 0x44, 0xE8, 0x7F,
+	 0xA0, 0x5A, 0x28, 0x47, 0xE9, 0x7F, 0xA0, 0x5A, 0x28, 0x44, 0xE8, 0x80, 0xF8, 0x84, 0x29, 0x5C,
+	 0x40, 0x89, 0x29, 0x44, 0xEA, 0x7F, 0xA0, 0x5A, 0x29, 0x47, 0xEB, 0x7F, 0xA0, 0x5A, 0x29, 0x44,
+	 0xE8, 0x80, 0xF8, 0x84, 0x2A, 0x5C, 0x40, 0x8A, 0x2A, 0x44, 0xEC, 0x7F, 0xA0, 0x5A, 0x2A, 0x47,
+	 0xED, 0x7F, 0xA0, 0x5A, 0x2A, 0x44, 0xE8, 0x80, 0xF8, 0x84, 0x2B, 0x5C, 0x40, 0x8B, 0x2B, 0x44,
+	 0xEE, 0x7F, 0xA0, 0x5A, 0x2B, 0x47, 0xEF, 0x7F, 0xA0, 0x5A, 0x38, 0xF0, 0x2B, 0x44, 0x90, 0x84,
+	 0xE8, 0x84, 0xE3, 0x7F, 0xA0, 0x5A, 0x0D, 0x60, 0x3E, 0x62, 0xA2, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x42, 0xFF, 0x40, 0xFF, 0xDD, 0xFE, 0xAD, 0x4F, 0x00, 0x7F, 0x01, 0xBC, 0xA0, 0x5D, 0x00, 0xEE,
+	 0x19, 0x61, 0xCD, 0x81, 0xFF, 0xFF, 0xFD, 0x02, 0x43, 0x45, 0x20, 0x44, 0x60, 0xBC, 0x40, 0x40,
+	 0x02, 0x60, 0xEE, 0x63, 0x65, 0xF3, 0x82, 0xFD, 0x40, 0x7F, 0x83, 0xFB, 0x05, 0x64, 0x84, 0xFB,
+	 0xDF, 0xFE, 0x19, 0xFF, 0xC5, 0x60, 0x6D, 0x64, 0x3F, 0x40, 0x01, 0x2B, 0x02, 0x00, 0xC5, 0x60,
+	 0x6D, 0x64, 0x85, 0xFB, 0xC0, 0x60, 0x9A, 0x78, 0xFF, 0xFF, 0x04, 0xEE, 0xAD, 0x4F, 0x00, 0x7F,
+	 0x01, 0xBC, 0xA0, 0x5D, 0x19, 0x61, 0xCD, 0x81, 0xFF, 0xFF, 0xFD, 0x02, 0xAD, 0x4F, 0x00, 0x7F,
+	 0x01, 0xBC, 0xA0, 0x5D, 0x00, 0xEE, 0x15, 0x60, 0xA2, 0xE7, 0x1C, 0x60, 0x68, 0x63, 0x1C, 0x60,
+	 0xDC, 0x65, 0xDF, 0xFE, 0x80, 0xE1, 0xBD, 0xD3, 0xFF, 0xFF, 0x60, 0x48, 0x60, 0x47, 0x80, 0xBC,
+	 0x00, 0x7F, 0x60, 0x4A, 0xD7, 0x80, 0xA1, 0xFF, 0xFF, 0xFF, 0xF5, 0x02, 0x1C, 0x60, 0xDC, 0x63,
+	 0x1D, 0x60, 0xDE, 0x65, 0xBD, 0xD3, 0xFF, 0xFF, 0x60, 0x48, 0x60, 0x47, 0x80, 0xBC, 0x00, 0x7F,
+	 0x60, 0x4A, 0xD7, 0x80, 0xA1, 0xFF, 0xFF, 0xFF, 0xF5, 0x02, 0x3F, 0x40, 0x20, 0x2B, 0x00, 0x00,
+	 0x01, 0x68, 0xFF, 0x6A, 0xBF, 0xFE, 0xC6, 0x60, 0x55, 0x78, 0xFF, 0xFF, 0x3F, 0x40, 0x20, 0x2B,
+	 0xAD, 0x00, 0x01, 0x16, 0xFE, 0x01, 0x38, 0x69, 0xA1, 0xFF, 0xFF, 0xFF, 0x68, 0x44, 0x01, 0x2A,
+	 0xA5, 0x00, 0x1F, 0x60, 0x1A, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xFF, 0xFF, 0x08, 0x28,
+	 0xA2, 0xDB, 0x65, 0xF1, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x9C, 0x01, 0x00, 0x65, 0xF1, 0xDD, 0xFE,
+	 0xAD, 0x4F, 0x00, 0x7F, 0x01, 0xBC, 0xA0, 0x5D, 0x00, 0xEE, 0x43, 0x45, 0x20, 0x44, 0x20, 0xBC,
+	 0x40, 0x40, 0x02, 0x60, 0xEE, 0x64, 0x82, 0xFB, 0x83, 0xF9, 0x05, 0x64, 0x84, 0xFB, 0xDF, 0xFE,
+	 0x19, 0xFF, 0x83, 0x00, 0x20, 0x44, 0x20, 0xBC, 0x40, 0x40, 0x43, 0x45, 0xA4, 0xD1, 0xDA, 0x83,
+	 0xC3, 0x85, 0x80, 0xE1, 0xDF, 0xFE, 0xBD, 0xD3, 0xFF, 0xFF, 0x60, 0x48, 0x60, 0x47, 0x80, 0xBC,
+	 0x00, 0x7F, 0x60, 0x4A, 0xD7, 0x80, 0xA1, 0xFF, 0xF6, 0x02, 0xBF, 0xFE, 0x6E, 0x00, 0x3F, 0x40,
+	 0x40, 0x26, 0x13, 0x00, 0x0B, 0x60, 0xF8, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x10, 0x64, 0x90, 0x84,
+	 0xA0, 0x50, 0xF8, 0xA2, 0xA2, 0xD1, 0x0A, 0x60, 0x19, 0x64, 0x90, 0x84, 0xA0, 0x52, 0x06, 0xA2,
+	 0xA2, 0xD1, 0x46, 0x60, 0x09, 0x64, 0x90, 0x84, 0xA0, 0x50, 0xAD, 0x4F, 0xFE, 0xB4, 0xA0, 0x5D,
+	 0xAD, 0x4F, 0xFD, 0xB4, 0xA0, 0x5D, 0x02, 0xEE, 0xBD, 0xFE, 0x50, 0x00, 0x80, 0xE1, 0x01, 0x16,
+	 0xFE, 0x01, 0x64, 0x48, 0x92, 0x6A, 0xA1, 0xFF, 0xFF, 0xFF, 0x68, 0x40, 0x1F, 0x60, 0x08, 0x64,
+	 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xFF, 0xFF, 0x08, 0x28, 0xA2, 0xDB, 0x3F, 0x00, 0x80, 0xE1,
+	 0x01, 0x16, 0xFE, 0x01, 0x01, 0x68, 0xA7, 0x6A, 0xA1, 0xFF, 0xFF, 0xFF, 0x68, 0x40, 0x36, 0x00,
+	 0x20, 0x44, 0x20, 0xBC, 0x40, 0x40, 0x80, 0xE1, 0x64, 0x46, 0x01, 0x16, 0xFE, 0x01, 0x21, 0x69,
+	 0xA1, 0xFF, 0xFF, 0xFF, 0x68, 0x5E, 0x01, 0x16, 0xFE, 0x01, 0x22, 0x69, 0xA1, 0xFF, 0xFF, 0xFF,
+	 0x68, 0x5F, 0x26, 0xFA, 0x1C, 0xF2, 0x01, 0x16, 0xFE, 0x01, 0x3A, 0x69, 0xA1, 0xFF, 0xFF, 0xFF,
+	 0x68, 0x5F, 0x27, 0xFA, 0x1B, 0x00, 0x20, 0x44, 0x20, 0xBC, 0x40, 0x40, 0x43, 0x45, 0xBE, 0xD5,
+	 0xA4, 0xD2, 0x5A, 0x86, 0xEF, 0xA0, 0x11, 0x61, 0x01, 0x06, 0x60, 0x41, 0x1C, 0x60, 0x46, 0x63,
+	 0x80, 0xE1, 0xBD, 0xD3, 0x26, 0x42, 0x01, 0x16, 0xFE, 0x01, 0x60, 0x49, 0xA1, 0xFF, 0xFF, 0xFF,
+	 0x68, 0x44, 0xCD, 0x81, 0xA2, 0xDA, 0x5A, 0x86, 0xF4, 0x02, 0x25, 0x43, 0x21, 0xE1, 0x00, 0x64,
+	 0xBF, 0xDB, 0x20, 0x44, 0x20, 0x2A, 0x07, 0x00, 0x07, 0xB4, 0x04, 0x36, 0xC3, 0xFE, 0x06, 0x36,
+	 0xCC, 0xFE, 0x07, 0x36, 0xD5, 0xFE, 0x20, 0x44, 0xD8, 0xB4, 0x40, 0x40, 0x20, 0x44, 0x40, 0x2A,
+	 0x07, 0x00, 0x9F, 0xFE, 0x1E, 0x05, 0xBF, 0xB4, 0x40, 0x40, 0x85, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x1B, 0x60, 0xE6, 0x63, 0xBD, 0xD3, 0x02, 0x61, 0x17, 0x1B, 0x04, 0xA3, 0xBD, 0xD3, 0x02, 0x61,
+	 0x13, 0x1B, 0x04, 0xA3, 0xBD, 0xD3, 0x02, 0x61, 0x0F, 0x1B, 0x04, 0xA3, 0xBD, 0xD3, 0x04, 0x61,
+	 0x0B, 0x1B, 0x04, 0xA3, 0xBD, 0xD3, 0x06, 0x61, 0x07, 0x1B, 0x04, 0xA3, 0xBD, 0xD3, 0x07, 0x61,
+	 0x03, 0x1B, 0xC0, 0x60, 0x9A, 0x78, 0xFF, 0xFF, 0xA3, 0xD1, 0x40, 0x44, 0x20, 0x44, 0x07, 0xB5,
+	 0xD4, 0x85, 0x35, 0x80, 0x24, 0x45, 0x1C, 0x60, 0x22, 0x64, 0x44, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x80, 0xE1, 0x43, 0x45, 0x20, 0x44, 0x20, 0xBC, 0x40, 0x40, 0x64, 0x43, 0xBD, 0xD3, 0xBD, 0xD1,
+	 0x40, 0x44, 0x10, 0x27, 0x10, 0x00, 0xFF, 0x60, 0x7F, 0x65, 0x15, 0x60, 0xA2, 0x64, 0x24, 0x40,
+	 0x08, 0x2B, 0xA4, 0x84, 0xA0, 0x57, 0xFF, 0xFF, 0x64, 0x49, 0xFF, 0xFF, 0x68, 0x44, 0x01, 0x16,
+	 0xFD, 0x01, 0x00, 0x7F, 0xA3, 0xDB, 0xA1, 0x01, 0x80, 0xE1, 0x43, 0x45, 0x20, 0x44, 0x20, 0xBC,
+	 0x40, 0x40, 0x64, 0x43, 0xBD, 0xD3, 0xBD, 0xD1, 0x40, 0x44, 0x10, 0x2B, 0x11, 0x00, 0xA3, 0xD3,
+	 0xFF, 0xFF, 0x15, 0x60, 0x80, 0xE7, 0x24, 0x40, 0x07, 0x27, 0x02, 0x00, 0x50, 0xEC, 0x00, 0x00,
+	 0x60, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x24, 0x40, 0x20, 0x2B, 0x40, 0xEC, 0x0F, 0x00,
+	 0x15, 0x60, 0x22, 0x64, 0x24, 0x40, 0x08, 0x27, 0x80, 0xBC, 0xA3, 0xD3, 0xA0, 0x57, 0x60, 0x48,
+	 0x64, 0x44, 0x80, 0xBC, 0xFF, 0xB4, 0x60, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x75, 0x01,
+	 0xA2, 0xFF, 0x30, 0x44, 0x02, 0xA8, 0x00, 0xE1, 0x01, 0x02, 0xA1, 0xFF, 0x86, 0xFF, 0x88, 0xFF,
+	 0x5C, 0x46, 0x5C, 0x49, 0x5C, 0x40, 0xDE, 0x60, 0x58, 0x4F, 0xE2, 0x78, 0xFF, 0xFF, 0xCE, 0x60,
+	 0x58, 0x4F, 0x00, 0x78, 0xFF, 0xFF, 0xE7, 0x60, 0x58, 0x4F, 0xBE, 0x78, 0xFF, 0xFF, 0xDB, 0x60,
+	 0x58, 0x4F, 0x3B, 0x78, 0xFF, 0xFF, 0x13, 0xE1, 0xA3, 0xFF, 0xC7, 0x60, 0x2E, 0x78, 0xFF, 0xFF,
+	 0xDC, 0x60, 0x87, 0x78, 0xFF, 0xFF, 0x0F, 0x60, 0xCE, 0x62, 0xA2, 0xD1, 0x80, 0x60, 0x00, 0x64,
+	 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x22, 0x00, 0x75, 0xF3, 0x31, 0x40, 0x01, 0x2A, 0x1E, 0x00,
+	 0xDC, 0x84, 0x01, 0xB4, 0x75, 0xFB, 0x09, 0x02, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1, 0x00, 0x60,
+	 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x11, 0x00, 0x0F, 0x60, 0xDC, 0x62, 0xA2, 0xD1,
+	 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x08, 0x00, 0xA9, 0xFE, 0xE4, 0x05,
+	 0xAB, 0xFE, 0x07, 0x05, 0xA8, 0xFE, 0xD4, 0x05, 0xAA, 0xFE, 0xD5, 0x05, 0xA1, 0xFF, 0xFF, 0xFF,
+	 0x85, 0x3E, 0x1B, 0x60, 0xC4, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x03, 0x02,
+	 0xC7, 0x60, 0x2E, 0x78, 0xFF, 0xFF, 0x26, 0x45, 0xD4, 0x80, 0x0F, 0xF0, 0xF9, 0x03, 0x64, 0x44,
+	 0x70, 0xB0, 0x70, 0x2A, 0x14, 0x00, 0x1F, 0x60, 0x18, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84,
+	 0xFF, 0xFF, 0x08, 0x28, 0xA2, 0xDB, 0xA2, 0xFF, 0x8F, 0xF3, 0xFF, 0xFF, 0xCC, 0x84, 0xFE, 0xA0,
+	 0x8F, 0xFB, 0x01, 0x07, 0xD4, 0xFE, 0xA3, 0xFF, 0xCB, 0x60, 0xBC, 0x78, 0xFF, 0xFF, 0x64, 0x40,
+	 0x02, 0x26, 0x09, 0x00, 0x66, 0x45, 0x09, 0xF4, 0x0F, 0xF2, 0x02, 0x18, 0x65, 0x46, 0xE3, 0x1B,
+	 0x00, 0x64, 0x40, 0x46, 0xCB, 0x01, 0xA2, 0xFF, 0x8F, 0xF3, 0x46, 0x46, 0xCC, 0x84, 0xFE, 0xA0,
+	 0x8F, 0xFB, 0x01, 0x07, 0xD4, 0xFE, 0xA3, 0xFF, 0x0F, 0xF0, 0xA3, 0xFC, 0x64, 0x44, 0x80, 0x26,
+	 0x22, 0x00, 0x98, 0xF1, 0x1E, 0x60, 0xF8, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80,
+	 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60,
+	 0x00, 0x75, 0x88, 0xFF, 0x32, 0x44, 0x01, 0x2A, 0x03, 0x00, 0x07, 0x60, 0x01, 0x64, 0x04, 0x00,
+	 0x02, 0x2A, 0x06, 0x00, 0x00, 0x60, 0x01, 0x64, 0x23, 0xFA, 0xCB, 0x60, 0xC8, 0x78, 0xFF, 0xFF,
+	 0xCB, 0x60, 0xBC, 0x78, 0xFF, 0xFF, 0x08, 0x26, 0x3F, 0x00, 0x2A, 0xF2, 0x60, 0x63, 0x60, 0x40,
+	 0x02, 0x2B, 0x66, 0x63, 0xBE, 0xD2, 0x69, 0xF1, 0xA3, 0xD2, 0xD0, 0x80, 0x68, 0xF1, 0x18, 0x02,
+	 0xBF, 0xD2, 0xD0, 0x80, 0x67, 0xF1, 0x14, 0x02, 0xD0, 0x80, 0xFF, 0xFF, 0x11, 0x02, 0x98, 0xF1,
+	 0x1F, 0x60, 0x04, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03,
+	 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF,
+	 0x32, 0x44, 0x01, 0x2A, 0x03, 0x00, 0x07, 0x60, 0x02, 0x64, 0x04, 0x00, 0x02, 0x2A, 0x06, 0x00,
+	 0x00, 0x60, 0x02, 0x64, 0x23, 0xFA, 0xCB, 0x60, 0xC8, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0xFF, 0xFF,
+	 0x60, 0x40, 0xB0, 0x3A, 0x06, 0x00, 0x00, 0x60, 0x02, 0x64, 0x23, 0xFA, 0xC8, 0x60, 0x6D, 0x78,
+	 0xFF, 0xFF, 0xCB, 0x60, 0xBC, 0x78, 0xFF, 0xFF, 0x32, 0x44, 0x01, 0x2A, 0x4A, 0x00, 0x20, 0x60,
+	 0x6C, 0x63, 0xBF, 0xD3, 0x00, 0x65, 0xB4, 0x81, 0xDB, 0x83, 0x3D, 0x03, 0xBF, 0xD3, 0xA3, 0xD3,
+	 0x40, 0x48, 0xBE, 0xD3, 0x40, 0x4A, 0x2E, 0xF0, 0x40, 0x4C, 0xD0, 0x80, 0x2D, 0xF0, 0x08, 0x02,
+	 0x2A, 0x44, 0xD0, 0x80, 0x2C, 0xF0, 0x04, 0x02, 0x28, 0x44, 0xD0, 0x80, 0xFF, 0xFF, 0x2B, 0x03,
+	 0x31, 0xF0, 0x2C, 0x44, 0xD0, 0x80, 0x30, 0xF0, 0x08, 0x02, 0x2A, 0x44, 0xD0, 0x80, 0x2F, 0xF0,
+	 0x04, 0x02, 0x28, 0x44, 0xD0, 0x80, 0xFF, 0xFF, 0x1E, 0x03, 0x34, 0xF0, 0x2C, 0x44, 0xD0, 0x80,
+	 0x33, 0xF0, 0x08, 0x02, 0x2A, 0x44, 0xD0, 0x80, 0x32, 0xF0, 0x04, 0x02, 0x28, 0x44, 0xD0, 0x80,
+	 0xFF, 0xFF, 0x11, 0x03, 0x38, 0xF0, 0x2C, 0x44, 0xD0, 0x80, 0x37, 0xF0, 0x08, 0x02, 0x2A, 0x44,
+	 0xD0, 0x80, 0x36, 0xF0, 0x04, 0x02, 0x28, 0x44, 0xD0, 0x80, 0xFF, 0xFF, 0x04, 0x03, 0xFA, 0xA1,
+	 0x06, 0xA3, 0xB7, 0x03, 0xC3, 0x01, 0x07, 0x60, 0x00, 0x64, 0x23, 0xFA, 0xCB, 0x60, 0xC8, 0x78,
+	 0xFF, 0xFF, 0x2A, 0xF2, 0x0F, 0xF0, 0x60, 0x45, 0xA4, 0x36, 0x08, 0x00, 0x0C, 0xB4, 0x04, 0x36,
+	 0x02, 0x00, 0x0C, 0x3A, 0x06, 0x00, 0xCB, 0x60, 0xBC, 0x78, 0xFF, 0xFF, 0xC9, 0x60, 0x42, 0x78,
+	 0xFF, 0xFF, 0x26, 0xF2, 0x50, 0xF1, 0x60, 0x47, 0x00, 0x7E, 0xD0, 0x84, 0x1F, 0xA4, 0x06, 0x0E,
+	 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0x07, 0x00, 0xC2, 0xA4, 0xE8, 0x84,
+	 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x87, 0xF8, 0xBF, 0xC0, 0x84, 0xA2, 0xDB, 0x0F, 0xF0,
+	 0x65, 0x40, 0x40, 0x2B, 0x22, 0x00, 0x32, 0x40, 0x08, 0x26, 0x1F, 0x00, 0x07, 0xF4, 0x36, 0xF2,
+	 0xFF, 0xFF, 0x37, 0xB4, 0x26, 0x46, 0x19, 0x02, 0x2C, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x26,
+	 0x11, 0x00, 0x98, 0xF1, 0x1E, 0x60, 0xFE, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80,
+	 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60,
+	 0x00, 0x75, 0x88, 0xFF, 0xCB, 0x60, 0xBC, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0x64, 0x40, 0x60, 0x26,
+	 0x03, 0x00, 0xC9, 0x60, 0x1A, 0x78, 0xFF, 0xFF, 0x60, 0x40, 0x40, 0x3A, 0xF3, 0x01, 0x98, 0xF1,
+	 0x1E, 0x60, 0xF2, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03,
+	 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF,
+	 0x27, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x3B, 0x12, 0x00, 0x98, 0xF1, 0x1F, 0x60, 0x00, 0x64,
+	 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24,
+	 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x13, 0x00, 0x02, 0x3B,
+	 0x11, 0x00, 0x98, 0xF1, 0x1F, 0x60, 0x02, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80,
+	 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60,
+	 0x00, 0x75, 0x88, 0xFF, 0x2A, 0xF2, 0x28, 0x41, 0x40, 0xA8, 0x01, 0xB1, 0x02, 0x02, 0x5F, 0x02,
+	 0x89, 0x00, 0x60, 0x40, 0x08, 0x2A, 0x2B, 0x00, 0x98, 0xF1, 0x1E, 0x60, 0xF0, 0x64, 0xA0, 0xD3,
+	 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE,
+	 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x1B, 0xF2, 0xFF, 0xFF, 0x60, 0x45,
+	 0x98, 0xF1, 0x1E, 0x60, 0xF6, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xD8, 0x80, 0xC4, 0x84, 0x0B, 0x03,
+	 0x07, 0x05, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x09, 0x04, 0xC6, 0xFE, 0x07, 0x00,
+	 0x00, 0x64, 0xB8, 0x84, 0xA2, 0xDB, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x0F, 0xF2,
+	 0xFF, 0xFF, 0x60, 0x40, 0x40, 0x26, 0x28, 0x00, 0x32, 0x44, 0x02, 0x26, 0x25, 0x00, 0x10, 0x2B,
+	 0x26, 0x00, 0x20, 0x60, 0x6C, 0x63, 0xBF, 0xD3, 0x2C, 0xF0, 0x00, 0xA8, 0x60, 0x41, 0x0D, 0x03,
+	 0x50, 0xFE, 0xBD, 0xD3, 0x2D, 0xF0, 0xD0, 0x80, 0xBD, 0xD3, 0x2E, 0xF0, 0xD0, 0x80, 0xBD, 0xD3,
+	 0x2C, 0xF0, 0xD0, 0x80, 0xFA, 0xA1, 0x10, 0x0C, 0xF3, 0x02, 0x50, 0xFE, 0x60, 0x60, 0x01, 0x64,
+	 0xD0, 0x80, 0x2D, 0xF0, 0x1D, 0x64, 0xD0, 0x80, 0x2E, 0xF0, 0x01, 0x64, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x03, 0x0C, 0xCB, 0x60, 0xBC, 0x78, 0xFF, 0xFF, 0x32, 0x40, 0x40, 0x2A, 0x00, 0x00, 0xCB, 0x60,
+	 0xB6, 0x78, 0xFF, 0xFF, 0x32, 0x40, 0x40, 0x26, 0xFA, 0x01, 0x2A, 0xF0, 0xFF, 0xFF, 0x64, 0x40,
+	 0x08, 0x2A, 0x20, 0x00, 0x32, 0x40, 0x02, 0x2A, 0x1D, 0x00, 0x03, 0x67, 0xA0, 0x84, 0x00, 0x37,
+	 0x64, 0x63, 0x60, 0x40, 0x02, 0x37, 0x5E, 0x63, 0x60, 0x40, 0x01, 0x37, 0x58, 0x63, 0x60, 0x40,
+	 0x03, 0x37, 0x0D, 0x00, 0xBD, 0xD2, 0x67, 0xF1, 0xBD, 0xD2, 0xD0, 0x80, 0x68, 0xF1, 0x07, 0x02,
+	 0xD0, 0x80, 0xBD, 0xD2, 0x69, 0xF1, 0x03, 0x02, 0xD0, 0x80, 0xFF, 0xFF, 0x03, 0x03, 0xCB, 0x60,
+	 0xBC, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0x87, 0xF4, 0x60, 0x40, 0x03, 0x2B, 0x31, 0x00, 0x89, 0xF3,
+	 0x06, 0x61, 0x60, 0x43, 0x66, 0x45, 0x31, 0xF0, 0x63, 0x46, 0x05, 0xF2, 0x65, 0x46, 0xD0, 0x80,
+	 0x30, 0xF0, 0x0F, 0x02, 0x63, 0x46, 0x04, 0xF2, 0x65, 0x46, 0xD0, 0x80, 0x2F, 0xF0, 0x09, 0x02,
+	 0x63, 0x46, 0x03, 0xF2, 0x65, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x03, 0x02, 0xFF, 0xFF, 0x48, 0xFE,
+	 0x06, 0x00, 0xCD, 0x81, 0x02, 0xA3, 0xE7, 0x02, 0x88, 0xF1, 0x08, 0xFE, 0x64, 0x43, 0x03, 0x03,
+	 0xCB, 0x60, 0xBC, 0x78, 0xFF, 0xFF, 0x43, 0x43, 0x23, 0x46, 0x06, 0xF0, 0x26, 0x46, 0x07, 0x67,
+	 0xA0, 0x84, 0x23, 0xFA, 0x64, 0x40, 0x02, 0x26, 0x2B, 0x00, 0xCB, 0x60, 0xBC, 0x78, 0xFF, 0xFF,
+	 0x26, 0x1B, 0x31, 0xF2, 0x12, 0x60, 0xCE, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3,
+	 0x66, 0x41, 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46, 0x31, 0xF0, 0x63, 0x46,
+	 0xD0, 0x80, 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46, 0x30, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2,
+	 0x06, 0x02, 0x61, 0x46, 0x2F, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4,
+	 0xFF, 0xFF, 0x63, 0x46, 0xE8, 0x1B, 0x88, 0xF3, 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0x43, 0x43,
+	 0x07, 0xFC, 0x43, 0x43, 0x02, 0xFE, 0x1D, 0xF0, 0x12, 0x60, 0xC0, 0x62, 0xC0, 0x64, 0xC0, 0x84,
+	 0xA2, 0xD1, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xC0, 0x84, 0xA2, 0xDB,
+	 0x63, 0x45, 0x2A, 0xF2, 0x35, 0xF0, 0x60, 0x40, 0xA4, 0x36, 0x0B, 0x00, 0x08, 0x2B, 0x0C, 0x00,
+	 0x23, 0x46, 0x22, 0xF2, 0x26, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x06, 0x02, 0xCB, 0x60, 0xBC, 0x78,
+	 0xFF, 0xFF, 0xCB, 0x60, 0xB6, 0x78, 0xFF, 0xFF, 0x23, 0x46, 0x1E, 0xF2, 0x26, 0x46, 0x44, 0x4C,
+	 0x0F, 0x26, 0x19, 0x00, 0x00, 0xBC, 0x40, 0x45, 0x0B, 0x03, 0x00, 0x64, 0x23, 0x46, 0x1E, 0xFA,
+	 0x26, 0x46, 0xA2, 0xFF, 0xB4, 0x60, 0x58, 0x4E, 0x48, 0x78, 0xFF, 0xFF, 0xA3, 0xFF, 0x26, 0x46,
+	 0x2A, 0xF0, 0x2C, 0x44, 0x64, 0x40, 0x04, 0x27, 0x06, 0x00, 0x23, 0x46, 0x22, 0xFA, 0x26, 0x46,
+	 0xCA, 0x60, 0xB6, 0x78, 0xFF, 0xFF, 0x3F, 0xF2, 0x02, 0xFA, 0xA2, 0xFF, 0x16, 0xF0, 0xFF, 0xFF,
+	 0x64, 0x44, 0x01, 0x26, 0xDC, 0x9C, 0x93, 0xF3, 0x2A, 0xF2, 0xDC, 0x83, 0x93, 0xFD, 0x06, 0xF4,
+	 0x01, 0xF8, 0x26, 0x46, 0x60, 0x40, 0x40, 0x2B, 0x18, 0x00, 0x64, 0x44, 0x00, 0x65, 0xFF, 0xB4,
+	 0xFC, 0xA4, 0x06, 0xF0, 0x03, 0x03, 0x64, 0x46, 0x0C, 0x0D, 0x02, 0x65, 0x26, 0x46, 0x00, 0xF2,
+	 0xFF, 0xFF, 0xD0, 0x80, 0xFF, 0xFF, 0x02, 0x03, 0x60, 0x46, 0xF9, 0x01, 0x01, 0xF2, 0xFF, 0xFF,
+	 0xD4, 0x84, 0x01, 0xFA, 0x66, 0x44, 0x26, 0x46, 0x06, 0xFA, 0x06, 0xF4, 0x00, 0xF2, 0x80, 0xFC,
+	 0x40, 0x45, 0xB4, 0x60, 0x58, 0x4E, 0x48, 0x78, 0xFF, 0xFF, 0xA3, 0xFF, 0x26, 0x46, 0x2C, 0x44,
+	 0x0F, 0x26, 0x10, 0x00, 0x23, 0x46, 0x22, 0xFA, 0x26, 0x44, 0x1E, 0xFA, 0x26, 0x46, 0x1B, 0x60,
+	 0xDA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0x6F, 0x00, 0xA3, 0x46, 0x22, 0xF2, 0x60, 0x45, 0xDC, 0x84, 0xD4, 0x80, 0x22, 0xFA,
+	 0xA3, 0x46, 0x6C, 0x02, 0x2A, 0xF0, 0xA3, 0x46, 0x1E, 0xF2, 0xA3, 0x46, 0x00, 0xBC, 0x00, 0xF2,
+	 0x01, 0x02, 0x64, 0x00, 0x44, 0x4C, 0x3F, 0xF0, 0x60, 0x43, 0x23, 0x46, 0x1E, 0xF4, 0x09, 0x60,
+	 0x00, 0x65, 0x3F, 0xF2, 0x26, 0x46, 0xC0, 0x84, 0xD4, 0x80, 0x60, 0x45, 0x57, 0x07, 0x80, 0xFC,
+	 0x1B, 0xF2, 0x06, 0xF2, 0x60, 0x41, 0x23, 0x46, 0x1E, 0xF4, 0x1B, 0xF0, 0x06, 0xF0, 0xC1, 0x81,
+	 0x06, 0xFA, 0x05, 0xFA, 0x9B, 0xFA, 0x65, 0x44, 0x3F, 0xFA, 0x64, 0x46, 0x00, 0xFC, 0x63, 0x46,
+	 0x01, 0xF2, 0x10, 0x61, 0xF2, 0xA4, 0x01, 0xFA, 0xC8, 0x83, 0x02, 0x64, 0x59, 0xD0, 0x58, 0xD8,
+	 0xFD, 0x1F, 0x06, 0x45, 0x1B, 0x60, 0xDA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x25, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xA2, 0xFF, 0x00, 0xF4, 0x01, 0xF0, 0x0A, 0x18,
+	 0x70, 0x67, 0xA0, 0x80, 0xF0, 0x67, 0x06, 0x03, 0xC0, 0x84, 0x01, 0xFA, 0x25, 0x46, 0x25, 0x44,
+	 0x80, 0xFC, 0x05, 0xFA, 0xB4, 0x60, 0x58, 0x4E, 0x48, 0x78, 0xFF, 0xFF, 0xD4, 0xFE, 0xA3, 0xFF,
+	 0x2C, 0x44, 0x04, 0x27, 0x16, 0x00, 0x23, 0x46, 0x1E, 0xF2, 0x9E, 0xFC, 0x60, 0x46, 0x46, 0x46,
+	 0x3F, 0xF2, 0x00, 0xF4, 0x60, 0x47, 0x08, 0xFA, 0x26, 0x46, 0x2C, 0x43, 0x2A, 0xFC, 0x06, 0xF4,
+	 0x00, 0x64, 0x00, 0xFA, 0x01, 0xF0, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84, 0x01, 0xFA, 0x26, 0x46,
+	 0x1D, 0x00, 0x00, 0x66, 0x46, 0x46, 0xC7, 0x60, 0x31, 0x78, 0xFF, 0xFF, 0xA3, 0x46, 0x1E, 0xF0,
+	 0x9E, 0xFC, 0x00, 0x63, 0x33, 0x85, 0xA3, 0x46, 0x0D, 0x03, 0xA3, 0x46, 0x22, 0xF2, 0x0F, 0x65,
+	 0xA4, 0x85, 0xD4, 0x84, 0x22, 0xFA, 0xA3, 0x46, 0xA2, 0xFF, 0xB4, 0x60, 0x58, 0x4E, 0x48, 0x78,
+	 0xFF, 0xFF, 0xA3, 0xFF, 0x26, 0x46, 0xCB, 0x60, 0xBC, 0x78, 0xFF, 0xFF, 0x07, 0xF0, 0x88, 0xF3,
+	 0xFF, 0xFF, 0xD0, 0x80, 0x64, 0x46, 0x6F, 0xF2, 0x26, 0x46, 0x50, 0x03, 0x60, 0x40, 0x00, 0x36,
+	 0x4D, 0x00, 0x64, 0x46, 0x0E, 0xF2, 0x26, 0x46, 0x60, 0x47, 0xFF, 0xB5, 0x27, 0xF2, 0xFF, 0xFF,
+	 0xFF, 0xB4, 0xD4, 0x80, 0xFF, 0xFF, 0x42, 0x06, 0x64, 0x46, 0x6F, 0xF2, 0x26, 0x46, 0x60, 0x47,
+	 0xFF, 0xB5, 0x65, 0x41, 0x0F, 0x60, 0xA2, 0x65, 0x00, 0x64, 0xE9, 0x81, 0xD8, 0x84, 0xFD, 0x02,
+	 0xC8, 0x84, 0x60, 0x43, 0x44, 0xD1, 0xFF, 0xFF, 0x64, 0x47, 0xFF, 0xB5, 0x27, 0xF2, 0xFF, 0xFF,
+	 0xFF, 0xB4, 0xD4, 0x80, 0x64, 0x44, 0x06, 0x06, 0x07, 0xF0, 0xFF, 0xFF, 0x64, 0x46, 0x0E, 0xFA,
+	 0x26, 0x46, 0x19, 0x00, 0x00, 0x61, 0x27, 0xF0, 0x0F, 0x60, 0xA2, 0x65, 0x61, 0x43, 0x45, 0xD3,
+	 0x64, 0x41, 0xFF, 0xB1, 0x61, 0x45, 0x60, 0x47, 0xFF, 0xB4, 0xDB, 0x83, 0xD4, 0x80, 0x63, 0x41,
+	 0xF3, 0x02, 0xCB, 0x83, 0x63, 0x41, 0x0F, 0x60, 0xA2, 0x65, 0x45, 0xD3, 0x07, 0xF0, 0xFF, 0xFF,
+	 0x64, 0x46, 0x0E, 0xFA, 0x26, 0x46, 0xAF, 0x84, 0xE8, 0x81, 0x05, 0x03, 0x00, 0x60, 0x01, 0x64,
+	 0xCD, 0x81, 0xE0, 0x84, 0xFD, 0x02, 0x64, 0x46, 0x70, 0xFA, 0x26, 0x46, 0x2A, 0xF2, 0x32, 0xF0,
+	 0x60, 0x40, 0x08, 0x2A, 0x5C, 0x00, 0x01, 0x2B, 0x2F, 0x00, 0x64, 0x40, 0x01, 0x2A, 0x2C, 0x00,
+	 0x98, 0xF1, 0x1E, 0x60, 0xF0, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80,
+	 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75,
+	 0x88, 0xFF, 0x1B, 0xF2, 0xFF, 0xFF, 0x60, 0x45, 0x98, 0xF1, 0x1E, 0x60, 0xF6, 0x64, 0xA0, 0xD3,
+	 0xFF, 0xFF, 0xD8, 0x80, 0xC4, 0x84, 0x0B, 0x03, 0x07, 0x05, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03,
+	 0xA2, 0xDB, 0x09, 0x04, 0xC6, 0xFE, 0x07, 0x00, 0x00, 0x64, 0xB8, 0x84, 0xA2, 0xDB, 0x8A, 0xFF,
+	 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x2B, 0x00, 0x98, 0xF1, 0x1E, 0x60, 0xEE, 0x64, 0xA0, 0xD3,
+	 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE,
+	 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x1B, 0xF2, 0xFF, 0xFF, 0x60, 0x45,
+	 0x98, 0xF1, 0x1E, 0x60, 0xF4, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xD8, 0x80, 0xC4, 0x84, 0x0B, 0x03,
+	 0x07, 0x05, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x09, 0x04, 0xC6, 0xFE, 0x07, 0x00,
+	 0x00, 0x64, 0xB8, 0x84, 0xA2, 0xDB, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x07, 0xF4,
+	 0xFF, 0xFF, 0x22, 0xF2, 0x26, 0x46, 0x0F, 0xB4, 0xDC, 0x85, 0x98, 0xF1, 0x1E, 0x60, 0xF2, 0x64,
+	 0xA0, 0xD3, 0xFF, 0xFF, 0xD8, 0x80, 0xC4, 0x84, 0x0B, 0x03, 0x07, 0x05, 0xDC, 0x80, 0xD0, 0x80,
+	 0x04, 0x03, 0xA2, 0xDB, 0x09, 0x04, 0xC6, 0xFE, 0x07, 0x00, 0x00, 0x64, 0xB8, 0x84, 0xA2, 0xDB,
+	 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x27, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x3B,
+	 0x12, 0x00, 0x98, 0xF1, 0x1F, 0x60, 0x00, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80,
+	 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60,
+	 0x00, 0x75, 0x88, 0xFF, 0x13, 0x00, 0x02, 0x3B, 0x11, 0x00, 0x98, 0xF1, 0x1F, 0x60, 0x02, 0x64,
+	 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24,
+	 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0xCC, 0x60, 0x06, 0x78,
+	 0xFF, 0xFF, 0xC7, 0x60, 0x31, 0x78, 0xFF, 0xFF, 0x1B, 0x60, 0xDA, 0x64, 0x40, 0x4B, 0xF0, 0x60,
+	 0x58, 0x4D, 0x75, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0xC7, 0x60, 0x31, 0x78, 0xFF, 0xFF,
+	 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0xBE, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xF8, 0xFE, 0x00, 0x66, 0x46, 0x46, 0xC7, 0x60, 0x31, 0x78,
+	 0xFF, 0xFF, 0x2A, 0xF2, 0x58, 0x63, 0x60, 0x47, 0x01, 0x27, 0x64, 0x63, 0x25, 0x60, 0x26, 0x62,
+	 0x61, 0x5C, 0xA2, 0xD9, 0xBD, 0xD0, 0xBD, 0xD0, 0x64, 0x45, 0x64, 0x41, 0xBD, 0xD0, 0x00, 0xF4,
+	 0x04, 0xF8, 0x83, 0xFA, 0x82, 0xF8, 0xA6, 0x46, 0x02, 0xB0, 0x5E, 0x63, 0x04, 0x03, 0x64, 0x63,
+	 0x03, 0xB0, 0x02, 0x3A, 0x6C, 0x63, 0x3F, 0xF2, 0xBD, 0xD0, 0xBD, 0xD0, 0x64, 0x45, 0x64, 0x41,
+	 0xBD, 0xD0, 0xA6, 0x46, 0x07, 0xF8, 0x86, 0xFA, 0x85, 0xF8, 0x60, 0x47, 0x08, 0xFA, 0x25, 0x60,
+	 0x26, 0x62, 0xA2, 0xD1, 0x26, 0x46, 0x64, 0x41, 0x2F, 0x58, 0xFF, 0xFF, 0x2A, 0xF2, 0x2C, 0xF0,
+	 0x31, 0x40, 0x20, 0x26, 0x09, 0x00, 0x60, 0x40, 0xA4, 0x36, 0x21, 0x00, 0x08, 0x26, 0x07, 0x00,
+	 0x7E, 0xF1, 0xCC, 0x60, 0xCF, 0x78, 0xFF, 0xFF, 0xCC, 0x60, 0xFF, 0x78, 0xFF, 0xFF, 0x64, 0x40,
+	 0x01, 0x26, 0x12, 0x00, 0x3F, 0xF0, 0x32, 0x40, 0x10, 0x2A, 0x0A, 0x00, 0x64, 0x41, 0x60, 0x40,
+	 0x40, 0x27, 0x06, 0x00, 0xCD, 0x81, 0xDD, 0x81, 0x03, 0x03, 0x02, 0x03, 0x01, 0x61, 0x01, 0x00,
+	 0x00, 0x61, 0x60, 0x40, 0x18, 0x3A, 0x03, 0x00, 0xCD, 0x60, 0x3B, 0x78, 0xFF, 0xFF, 0x07, 0xF2,
+	 0x88, 0xF1, 0x66, 0x45, 0xD0, 0x80, 0x60, 0x46, 0x06, 0xF2, 0x65, 0x46, 0x03, 0x03, 0xFF, 0xFF,
+	 0x02, 0x26, 0x07, 0x00, 0xDA, 0x60, 0x58, 0x4F, 0xDB, 0x78, 0xFF, 0xFF, 0xCD, 0x60, 0x37, 0x78,
+	 0xFF, 0xFF, 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0xA4, 0x3A, 0x07, 0x00, 0xDD, 0x60, 0x58, 0x4F,
+	 0x45, 0x78, 0xFF, 0xFF, 0xCD, 0x60, 0x37, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0xCB, 0x60, 0x58, 0x4F,
+	 0xD9, 0x78, 0xFF, 0xFF, 0x3F, 0xF2, 0x06, 0x65, 0xD4, 0x80, 0x60, 0x43, 0x52, 0x04, 0x00, 0xF4,
+	 0xAA, 0x60, 0xAA, 0x65, 0x09, 0xF2, 0x0A, 0xF0, 0xD4, 0x80, 0x03, 0x64, 0x4A, 0x02, 0xD0, 0x80,
+	 0x00, 0x64, 0x0B, 0xF0, 0x46, 0x02, 0x64, 0x45, 0xD4, 0x80, 0xF8, 0x7F, 0x08, 0x02, 0x0C, 0xF0,
+	 0x26, 0x46, 0x64, 0x45, 0x23, 0xF0, 0x20, 0x67, 0xB0, 0x84, 0xA2, 0xDA, 0x0B, 0x00, 0xD4, 0x80,
+	 0x1D, 0x60, 0x60, 0x64, 0x11, 0x02, 0x0C, 0xF0, 0x26, 0x46, 0x64, 0x45, 0x23, 0xF0, 0x40, 0x67,
+	 0xB0, 0x84, 0xA2, 0xDA, 0x65, 0x44, 0x88, 0x3A, 0x2C, 0x00, 0x77, 0x37, 0x03, 0x00, 0x78, 0x37,
+	 0x01, 0x00, 0x8E, 0x37, 0x00, 0x61, 0x25, 0x00, 0xD4, 0x80, 0x08, 0x65, 0x22, 0x02, 0xD7, 0x80,
+	 0x01, 0x60, 0x00, 0x64, 0x0C, 0xF0, 0x1D, 0x04, 0xD0, 0x80, 0x0D, 0xF0, 0x1A, 0x02, 0x26, 0x46,
+	 0x14, 0xF2, 0x01, 0x63, 0x02, 0xA8, 0x64, 0x47, 0x14, 0x03, 0x7F, 0xB4, 0xFD, 0xA0, 0x06, 0x03,
+	 0x10, 0x07, 0x23, 0xF0, 0x60, 0x67, 0xB0, 0x84, 0xA2, 0xDA, 0x6A, 0x00, 0xD2, 0xF3, 0xFF, 0xFF,
+	 0x02, 0xBC, 0xD2, 0xFB, 0xE5, 0x60, 0x58, 0x4F, 0x94, 0x78, 0xFF, 0xFF, 0xCD, 0x60, 0x37, 0x78,
+	 0xFF, 0xFF, 0x26, 0x46, 0x61, 0x40, 0x01, 0x2A, 0x12, 0x00, 0x98, 0xF1, 0x1F, 0x60, 0x06, 0x64,
+	 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24,
+	 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x7C, 0x00, 0xDD, 0x60,
+	 0x58, 0x4F, 0x45, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0xFF, 0xFF, 0xFF, 0xFF, 0x48, 0x36, 0x73, 0x00,
+	 0xCD, 0x60, 0x58, 0x4F, 0x48, 0x78, 0xFF, 0xFF, 0xCD, 0x60, 0x37, 0x78, 0xFF, 0xFF, 0x60, 0x40,
+	 0x0C, 0x26, 0x69, 0x00, 0x64, 0x40, 0x01, 0x2A, 0x66, 0x00, 0xB0, 0x3A, 0x05, 0x00, 0xD1, 0x60,
+	 0x58, 0x4F, 0x80, 0x78, 0xFF, 0xFF, 0x5B, 0x00, 0x00, 0x3A, 0x05, 0x00, 0xD4, 0x60, 0x58, 0x4F,
+	 0xF3, 0x78, 0xFF, 0xFF, 0x54, 0x00, 0x20, 0x3A, 0x05, 0x00, 0xD4, 0x60, 0x58, 0x4F, 0xF3, 0x78,
+	 0xFF, 0xFF, 0x4D, 0x00, 0xC0, 0x3A, 0x05, 0x00, 0xDA, 0x60, 0x58, 0x4F, 0x48, 0x78, 0xFF, 0xFF,
+	 0x46, 0x00, 0xA0, 0x3A, 0x05, 0x00, 0xDA, 0x60, 0x58, 0x4F, 0xA6, 0x78, 0xFF, 0xFF, 0x3F, 0x00,
+	 0x40, 0x3A, 0x0D, 0x00, 0xE1, 0x60, 0x58, 0x4F, 0x10, 0x78, 0xFF, 0xFF, 0x38, 0x00, 0x60, 0x40,
+	 0x50, 0x3A, 0x05, 0x00, 0xEA, 0x60, 0x58, 0x4F, 0xF5, 0x78, 0xFF, 0xFF, 0x30, 0x00, 0x33, 0x00,
+	 0xD2, 0xF3, 0xFF, 0xFF, 0x02, 0xBC, 0xD2, 0xFB, 0x2A, 0xF2, 0x3B, 0xF0, 0x60, 0x40, 0x40, 0x2B,
+	 0x19, 0x00, 0x22, 0xF2, 0xFF, 0xFF, 0x04, 0xB4, 0xFF, 0xFF, 0x14, 0x03, 0xC0, 0x60, 0x00, 0x64,
+	 0x64, 0x40, 0x20, 0x2B, 0x0F, 0x00, 0xA0, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0x23, 0xF2,
+	 0x10, 0xBD, 0xB4, 0x9C, 0x3F, 0xF2, 0x23, 0xF8, 0xF8, 0xA4, 0x3F, 0xFA, 0x00, 0xF4, 0x60, 0x47,
+	 0x08, 0xFA, 0x26, 0x46, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0xBE, 0x64, 0xA2, 0xDB, 0x26, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xF8, 0xFE, 0x0C, 0x00, 0x66, 0x44,
+	 0x00, 0xA8, 0xFF, 0xFF, 0x0A, 0x03, 0x26, 0x46, 0x1B, 0x60, 0xDA, 0x64, 0x40, 0x4B, 0xF0, 0x60,
+	 0x58, 0x4D, 0x75, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0xCB, 0x60, 0xB9, 0x78, 0xFF, 0xFF,
+	 0x14, 0xF2, 0x00, 0x7C, 0x3E, 0xF8, 0xCC, 0x84, 0xCC, 0x84, 0x19, 0x03, 0x60, 0x02, 0x11, 0xF2,
+	 0x07, 0xFA, 0xAC, 0xF3, 0x19, 0xFA, 0xCD, 0x60, 0x58, 0x4E, 0xE4, 0x78, 0xFF, 0xFF, 0x1B, 0x60,
+	 0xDA, 0x62, 0x1B, 0x60, 0x9A, 0x64, 0xA2, 0xDB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB,
+	 0xFF, 0xFF, 0x2B, 0xFF, 0xC8, 0xFE, 0xF2, 0x64, 0x3B, 0x42, 0x4A, 0xDB, 0x79, 0x00, 0xA2, 0xFF,
+	 0x46, 0x45, 0xB4, 0x60, 0x58, 0x4E, 0x91, 0x78, 0xFF, 0xFF, 0xA3, 0xFF, 0x11, 0x03, 0x7E, 0x63,
+	 0x46, 0x4B, 0x25, 0x46, 0xA3, 0xD0, 0x2B, 0x46, 0xA3, 0xD8, 0xFB, 0x1F, 0x89, 0xFC, 0x8A, 0xFC,
+	 0x88, 0xFC, 0x05, 0x18, 0x64, 0x46, 0x01, 0xF0, 0x10, 0x67, 0xC0, 0x84, 0x01, 0xFA, 0x08, 0xFE,
+	 0x2B, 0x46, 0x46, 0x46, 0x25, 0x46, 0xCD, 0x60, 0x58, 0x4E, 0xE4, 0x78, 0xFF, 0xFF, 0x1F, 0x60,
+	 0x8E, 0x62, 0xA2, 0xD3, 0x88, 0xF3, 0x00, 0xA8, 0x07, 0xFA, 0x0F, 0x03, 0x1B, 0x60, 0xDA, 0x62,
+	 0x1B, 0x60, 0x94, 0x64, 0xA2, 0xDB, 0x25, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0xF3, 0x64, 0x3B, 0x42, 0x4A, 0xDB, 0x0E, 0x00, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60,
+	 0x88, 0x64, 0xA2, 0xDB, 0x25, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0xF4, 0x64, 0x3B, 0x42, 0x4A, 0xDB, 0x26, 0x44, 0x00, 0xA8, 0xC1, 0xFE, 0x31, 0x03, 0xD2, 0xF3,
+	 0xFF, 0xFF, 0x02, 0xBC, 0xD2, 0xFB, 0x26, 0x46, 0x2A, 0xF2, 0x3B, 0xF0, 0x60, 0x40, 0x40, 0x2B,
+	 0x18, 0x00, 0x64, 0x40, 0x20, 0x2B, 0x15, 0x00, 0x22, 0xF2, 0xFF, 0xFF, 0x04, 0xB4, 0xFF, 0xFF,
+	 0x10, 0x03, 0xC0, 0x67, 0xA0, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0x23, 0xF2, 0x10, 0xBD,
+	 0xB4, 0x9C, 0x3F, 0xF2, 0x23, 0xF8, 0xF8, 0xA4, 0x3F, 0xFA, 0x00, 0xF4, 0x60, 0x47, 0x08, 0xFA,
+	 0x26, 0x46, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0xBE, 0x64, 0xA2, 0xDB, 0x26, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xF8, 0xFE, 0xF1, 0x64, 0x3B, 0x42, 0x4A, 0xDB,
+	 0x00, 0x66, 0x46, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x2A, 0xF2, 0x82, 0x60, 0xFF, 0x65, 0xA4, 0x87,
+	 0x02, 0xBF, 0x2A, 0xFA, 0x1C, 0xF2, 0x13, 0xFA, 0x32, 0xF2, 0x2C, 0xFA, 0x33, 0xF2, 0x2D, 0xFA,
+	 0x34, 0xF2, 0x2E, 0xFA, 0x2F, 0xF2, 0x32, 0xFA, 0x30, 0xF2, 0x33, 0xFA, 0x31, 0xF2, 0x34, 0xFA,
+	 0x67, 0xF3, 0x2F, 0xFA, 0x68, 0xF3, 0x30, 0xFA, 0x69, 0xF3, 0x31, 0xFA, 0x2E, 0x58, 0xFF, 0xFF,
+	 0x0F, 0x60, 0xF8, 0x62, 0xD0, 0x60, 0x7B, 0x64, 0xA2, 0xDB, 0x2F, 0x58, 0xFF, 0xFF, 0x1F, 0x60,
+	 0x62, 0x63, 0x20, 0x60, 0x02, 0x62, 0xA2, 0xD3, 0xA3, 0xDB, 0x1E, 0x63, 0x1F, 0x60, 0x6C, 0x61,
+	 0x20, 0x60, 0x0C, 0x64, 0x58, 0xD1, 0x59, 0xD9, 0xFD, 0x1F, 0x1F, 0x60, 0x8E, 0x63, 0x20, 0x60,
+	 0x2E, 0x62, 0xA2, 0xD3, 0xA3, 0xDB, 0x1F, 0x60, 0x90, 0x63, 0x20, 0x60, 0x30, 0x62, 0xA2, 0xD3,
+	 0xA3, 0xDB, 0x1F, 0x60, 0x9A, 0x63, 0x20, 0x60, 0x3A, 0x62, 0xA2, 0xD3, 0xA3, 0xDB, 0x1F, 0x60,
+	 0x9C, 0x63, 0x20, 0x60, 0x3C, 0x62, 0xA2, 0xD3, 0xA3, 0xDB, 0x1F, 0x60, 0x9E, 0x63, 0x20, 0x60,
+	 0x3E, 0x62, 0xA2, 0xD3, 0xA3, 0xDB, 0x1F, 0x60, 0xA0, 0x63, 0x20, 0x60, 0x40, 0x62, 0xA2, 0xD3,
+	 0xA3, 0xDB, 0x1F, 0x60, 0x92, 0x63, 0x20, 0x60, 0x32, 0x62, 0xA2, 0xD3, 0xA3, 0xDB, 0x1F, 0x60,
+	 0x94, 0x63, 0x20, 0x60, 0x34, 0x62, 0xA2, 0xD3, 0xA3, 0xDB, 0x1F, 0x60, 0x96, 0x63, 0x20, 0x60,
+	 0x36, 0x62, 0xA2, 0xD3, 0xA3, 0xDB, 0x1F, 0x60, 0xB6, 0x63, 0xBD, 0xD1, 0xCB, 0xF9, 0x67, 0xF9,
+	 0xBD, 0xD1, 0xCC, 0xF9, 0x68, 0xF9, 0xA3, 0xD1, 0xCD, 0xF9, 0x69, 0xF9, 0x01, 0x64, 0x6B, 0xFB,
+	 0x1F, 0x60, 0xA8, 0x62, 0xA2, 0xD3, 0xC4, 0xFB, 0x00, 0x63, 0x4A, 0xFD, 0x5A, 0xFD, 0x6C, 0xFD,
+	 0x6D, 0xFD, 0x21, 0x60, 0x82, 0x64, 0xA0, 0xD3, 0xEA, 0x60, 0x58, 0x4E, 0x78, 0x78, 0xFF, 0xFF,
+	 0x21, 0x60, 0x80, 0x64, 0xA0, 0xD1, 0x1F, 0x60, 0x92, 0x62, 0xA2, 0xD3, 0xFF, 0x60, 0xE7, 0x65,
+	 0x32, 0x41, 0xA5, 0x81, 0xFF, 0xA0, 0xFF, 0xFF, 0x01, 0x03, 0x0B, 0x00, 0x08, 0x65, 0xB5, 0x81,
+	 0x1F, 0x60, 0x96, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x2A, 0x02, 0x00, 0x10, 0x65,
+	 0xB5, 0x81, 0x41, 0x52, 0x88, 0xF5, 0x32, 0x44, 0x10, 0xB0, 0xFF, 0xFF, 0x0B, 0x03, 0x21, 0x60,
+	 0x2C, 0x62, 0xA2, 0xD3, 0x06, 0xF0, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0x80, 0xBF,
+	 0xB0, 0x84, 0x06, 0xFA, 0x1F, 0x60, 0x92, 0x62, 0xA2, 0xD3, 0x22, 0x7C, 0xFF, 0xA0, 0xFD, 0xA0,
+	 0x05, 0x06, 0x03, 0x03, 0xFE, 0xA0, 0x04, 0x7C, 0x01, 0x02, 0x36, 0xF8, 0x0E, 0xF0, 0x0F, 0x60,
+	 0xA2, 0x65, 0x20, 0x60, 0x38, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0xFE, 0xA0, 0x03, 0xA8, 0x11, 0x06,
+	 0x5F, 0xF1, 0x06, 0x02, 0x64, 0x44, 0x08, 0x2A, 0x09, 0x00, 0x06, 0x64, 0x44, 0xD3, 0x0D, 0x00,
+	 0x64, 0x44, 0x20, 0x2A, 0x03, 0x00, 0x0A, 0x64, 0x44, 0xD3, 0x07, 0x00, 0x01, 0x64, 0x44, 0xD3,
+	 0x04, 0x00, 0xE8, 0x84, 0xE0, 0x84, 0x44, 0xD3, 0x00, 0x00, 0x0E, 0xFA, 0x1F, 0x60, 0x9E, 0x62,
+	 0xA2, 0xD1, 0x20, 0x44, 0x20, 0xB5, 0x64, 0x41, 0x00, 0xB9, 0xD4, 0x84, 0x08, 0x28, 0x20, 0xBC,
+	 0x40, 0x40, 0x11, 0x60, 0xF0, 0x61, 0xA1, 0xD3, 0xFF, 0xFF, 0x00, 0xB8, 0x10, 0x60, 0x0C, 0x65,
+	 0x0D, 0x03, 0x11, 0x60, 0xF8, 0x63, 0xC5, 0xF3, 0xA3, 0xD1, 0xE0, 0x84, 0xC4, 0x84, 0xA0, 0xD3,
+	 0xFF, 0xFF, 0x01, 0xB0, 0xFF, 0xFF, 0x02, 0x02, 0xC5, 0xF9, 0x65, 0xF9, 0xC5, 0xF3, 0x01, 0x61,
+	 0xCC, 0x84, 0xFF, 0xFF, 0x02, 0x03, 0xE1, 0x81, 0xFB, 0x01, 0x9A, 0xF3, 0x61, 0x45, 0xA4, 0x80,
+	 0xFF, 0xFF, 0x0B, 0x02, 0x00, 0xB8, 0x01, 0x63, 0x08, 0x03, 0xE8, 0x84, 0xFF, 0xFF, 0x02, 0x24,
+	 0x02, 0x00, 0xDF, 0x83, 0xFA, 0x01, 0xC5, 0xFD, 0x65, 0xFD, 0x0A, 0x64, 0x25, 0x60, 0x1E, 0x63,
+	 0xA3, 0xDB, 0x01, 0x64, 0x25, 0x60, 0x20, 0x63, 0xA3, 0xDB, 0xB6, 0xF1, 0x09, 0x60, 0x2A, 0x64,
+	 0xD0, 0x80, 0x03, 0x64, 0x01, 0x06, 0x06, 0x64, 0xB0, 0xFB, 0x0F, 0x60, 0xD6, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0xDE, 0xFE, 0x0B, 0x04, 0x0F, 0x60, 0xD8, 0x62, 0x40, 0x60, 0x00, 0x64, 0xA2, 0xDB,
+	 0xCF, 0x60, 0x05, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xD6, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x65, 0xF1, 0x1C, 0x60, 0x00, 0x62, 0xA2, 0xD9, 0x08, 0x64, 0x4A, 0xDB,
+	 0xFF, 0xFF, 0x2D, 0xFF, 0x0F, 0x60, 0xD8, 0x62, 0x20, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xCF, 0x60,
+	 0x2D, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xD6, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0xBE, 0xFE, 0x0F, 0x60, 0xCE, 0x62, 0xA2, 0xD1, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x20, 0x44, 0x01, 0x65, 0x34, 0x80, 0x1F, 0x60, 0xA6, 0x64, 0xA0, 0xD3,
+	 0xC3, 0xFB, 0x60, 0x40, 0x05, 0x3A, 0x03, 0x00, 0xEB, 0x60, 0x1A, 0x61, 0x11, 0x00, 0x04, 0x3A,
+	 0x03, 0x00, 0xEB, 0x60, 0x0E, 0x61, 0x0C, 0x00, 0x03, 0x3A, 0x03, 0x00, 0xEB, 0x60, 0x02, 0x61,
+	 0x07, 0x00, 0x02, 0x3A, 0x03, 0x00, 0xEA, 0x60, 0xF6, 0x61, 0x02, 0x00, 0xEA, 0x60, 0xEA, 0x61,
+	 0x3E, 0x60, 0x00, 0x66, 0x01, 0x60, 0x78, 0x64, 0x0A, 0x63, 0x59, 0xD0, 0x58, 0xD9, 0xFD, 0x1F,
+	 0x00, 0x66, 0xC4, 0xF3, 0x60, 0x41, 0x00, 0xA8, 0xFA, 0xA1, 0x01, 0x03, 0xA1, 0xDB, 0x01, 0x60,
+	 0x7A, 0x63, 0x16, 0x60, 0xC4, 0x61, 0xBD, 0xD3, 0xFF, 0xFF, 0x20, 0x7F, 0xA1, 0xDB, 0xBD, 0xD3,
+	 0xFF, 0xFF, 0x21, 0x7F, 0x59, 0xDB, 0xA3, 0xD3, 0xFF, 0xFF, 0x22, 0x7F, 0x59, 0xDB, 0x0F, 0x60,
+	 0xD6, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE, 0x0B, 0x04, 0x0F, 0x60, 0xD8, 0x62, 0x40, 0x60,
+	 0x00, 0x64, 0xA2, 0xDB, 0xCF, 0x60, 0x77, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x1C, 0x60, 0x00, 0x62, 0x16, 0x60, 0xC2, 0x64, 0xA2, 0xDB, 0x20, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x2D, 0xFF, 0x0F, 0x60, 0xD8, 0x62, 0x20, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xCF, 0x60, 0x9C, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xD6, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0x65, 0xF1, 0x1C, 0x60, 0x00, 0x62, 0xA2, 0xD9, 0x08, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF,
+	 0x0F, 0x60, 0xD8, 0x62, 0x20, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xCF, 0x60, 0xB3, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xD6, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xBE, 0xFE,
+	 0x0F, 0x60, 0xCE, 0x62, 0xA2, 0xD1, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x20, 0x40, 0x20, 0x2A, 0x04, 0x00, 0xEB, 0x60, 0x58, 0x4E, 0x16, 0x78, 0xFF, 0xFF, 0x0F, 0x60,
+	 0xD6, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x4E, 0xF3, 0xFF, 0xFF, 0x13, 0x1B, 0x1F, 0x60, 0xAE, 0x64,
+	 0xA0, 0xD3, 0xC7, 0xFB, 0x1F, 0x60, 0x1E, 0x65, 0x1F, 0x60, 0xBC, 0x61, 0x1F, 0x60, 0x1C, 0x64,
+	 0x20, 0x63, 0x59, 0xD1, 0x58, 0xD9, 0xA5, 0xD9, 0xDA, 0x85, 0xFB, 0x1F, 0xD0, 0x60, 0x62, 0x78,
+	 0xFF, 0xFF, 0x20, 0x60, 0x40, 0x63, 0xE0, 0x84, 0xE0, 0x85, 0xC4, 0x85, 0xC7, 0x83, 0xFE, 0xA5,
+	 0x89, 0xF3, 0xFF, 0xFF, 0xC4, 0x84, 0x66, 0x45, 0x60, 0x46, 0x60, 0x41, 0xBD, 0xD1, 0x03, 0xF8,
+	 0xBD, 0xD1, 0x04, 0xF8, 0xA3, 0xD1, 0x05, 0xF8, 0x06, 0xF2, 0xFF, 0xFF, 0x02, 0x7E, 0x06, 0xFA,
+	 0x5F, 0xF3, 0x60, 0xFB, 0x73, 0xF0, 0x63, 0xF9, 0x66, 0x43, 0x21, 0x60, 0x2C, 0x62, 0x32, 0x40,
+	 0x08, 0x2A, 0x09, 0x00, 0xA2, 0xD3, 0x06, 0xF0, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84,
+	 0x80, 0xBF, 0xB0, 0x84, 0x06, 0xFA, 0x63, 0x44, 0x63, 0xF3, 0x60, 0x45, 0x66, 0x41, 0x65, 0x46,
+	 0x8C, 0xFA, 0x60, 0x40, 0x01, 0x36, 0x06, 0x00, 0x02, 0x36, 0x04, 0x00, 0x04, 0x36, 0x02, 0x00,
+	 0x05, 0x3A, 0x02, 0x00, 0x00, 0x64, 0x01, 0x00, 0x01, 0x64, 0x6F, 0xFA, 0x5F, 0xF3, 0x60, 0xF1,
+	 0xFF, 0xFF, 0xA0, 0x84, 0x65, 0x43, 0x02, 0x02, 0x5F, 0xF3, 0xFF, 0xFF, 0x60, 0x41, 0x0F, 0x60,
+	 0xAE, 0x65, 0x63, 0xF3, 0xFF, 0xFF, 0xE0, 0x84, 0x44, 0xD3, 0x61, 0x45, 0xA4, 0x80, 0xFF, 0xFF,
+	 0x04, 0x02, 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0xFC, 0x03, 0xA4, 0x84, 0x61, 0xFB, 0x6F, 0xF0,
+	 0x60, 0x47, 0x90, 0x84, 0x6F, 0xFA, 0x60, 0x47, 0x60, 0x45, 0x80, 0x64, 0xE8, 0x84, 0xA4, 0x80,
+	 0xFF, 0xFF, 0xFC, 0x03, 0xA4, 0x84, 0x70, 0xF0, 0x70, 0xFA, 0x00, 0x61, 0xE8, 0x84, 0xFF, 0xFF,
+	 0x02, 0x05, 0xDD, 0x81, 0xFB, 0x01, 0xE1, 0x81, 0x0F, 0x60, 0xA2, 0x65, 0x45, 0xD3, 0x0E, 0xFA,
+	 0x66, 0x43, 0x0C, 0xF4, 0xC5, 0xFE, 0x0F, 0x60, 0xD6, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x0F, 0x60,
+	 0xD8, 0x62, 0x00, 0x60, 0x30, 0x64, 0xA2, 0xDB, 0xCF, 0x60, 0xC7, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x4E, 0xDF, 0x60, 0x58, 0x4F, 0x13, 0x78, 0xFF, 0xFF, 0x0E, 0x4F,
+	 0x0F, 0x4E, 0xDC, 0x60, 0x58, 0x4F, 0x6B, 0x78, 0xFF, 0xFF, 0x0E, 0x4F, 0x0F, 0x4E, 0xDB, 0x60,
+	 0x58, 0x4F, 0xE8, 0x78, 0xFF, 0xFF, 0x0E, 0x4F, 0x0F, 0x4E, 0xDB, 0x60, 0x58, 0x4F, 0x42, 0x78,
+	 0xFF, 0xFF, 0x0E, 0x4F, 0xD7, 0x01, 0x4E, 0xF3, 0x7E, 0xF5, 0x60, 0x40, 0xFF, 0x22, 0x0A, 0x00,
+	 0x89, 0xF1, 0xCC, 0x84, 0xE0, 0x84, 0xC0, 0x86, 0x06, 0xF2, 0xFF, 0xFF, 0x00, 0x7E, 0x06, 0xFA,
+	 0x7E, 0xF5, 0x08, 0x00, 0x0F, 0x60, 0xF4, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x11, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x4E, 0xF3, 0x66, 0x40, 0xFF, 0x22, 0x05, 0x00, 0xFF, 0x22, 0x37, 0x00,
+	 0xD1, 0x60, 0x30, 0x78, 0xFF, 0xFF, 0x02, 0x64, 0x6A, 0xFB, 0xFF, 0xFF, 0xC1, 0xFE, 0x6A, 0xF3,
+	 0x00, 0x65, 0xD4, 0x80, 0x4E, 0xF3, 0x0F, 0x03, 0x0F, 0x60, 0xD6, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0x0F, 0x60, 0xD8, 0x62, 0x80, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xD0, 0x60, 0x9F, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xD6, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE,
+	 0x0B, 0x04, 0x0F, 0x60, 0xD8, 0x62, 0x20, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xD0, 0x60, 0xB3, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x1C, 0x60, 0x00, 0x62, 0x06, 0x64, 0x4A, 0xDB,
+	 0xFF, 0xFF, 0x2D, 0xFF, 0x20, 0x44, 0x01, 0xB5, 0x54, 0x80, 0xDA, 0xFE, 0xBE, 0xFE, 0x88, 0xF1,
+	 0x02, 0x64, 0x87, 0xF3, 0xC0, 0x83, 0x40, 0x48, 0x76, 0xFD, 0xE4, 0x60, 0x58, 0x4E, 0x9D, 0x78,
+	 0xFF, 0xFF, 0x28, 0x44, 0x4C, 0x88, 0x76, 0xF3, 0x02, 0x65, 0xC4, 0x83, 0xF5, 0x02, 0xA2, 0x60,
+	 0x58, 0x4E, 0x00, 0x78, 0xFF, 0xFF, 0x14, 0x60, 0xD0, 0x62, 0x14, 0x60, 0xD2, 0x64, 0xA2, 0xDB,
+	 0x00, 0x64, 0x4A, 0xDB, 0x01, 0x60, 0xFE, 0x63, 0x12, 0x60, 0xCC, 0x61, 0x00, 0x64, 0x59, 0xDB,
+	 0xFE, 0x1F, 0x7E, 0xF1, 0x1B, 0x60, 0x9A, 0x61, 0x64, 0x40, 0xFF, 0x26, 0x39, 0x00, 0xD1, 0x60,
+	 0x58, 0x4E, 0x33, 0x78, 0xFF, 0xFF, 0x1B, 0x60, 0x88, 0x61, 0xD1, 0x60, 0x58, 0x4E, 0x33, 0x78,
+	 0xFF, 0xFF, 0x1B, 0x60, 0x8E, 0x61, 0xD1, 0x60, 0x58, 0x4E, 0x33, 0x78, 0xFF, 0xFF, 0x1B, 0x60,
+	 0xA0, 0x61, 0xD1, 0x60, 0x58, 0x4E, 0x33, 0x78, 0xFF, 0xFF, 0x1B, 0x60, 0xA6, 0x61, 0xD1, 0x60,
+	 0x58, 0x4E, 0x33, 0x78, 0xFF, 0xFF, 0x1B, 0x60, 0xB2, 0x61, 0xD1, 0x60, 0x58, 0x4E, 0x33, 0x78,
+	 0xFF, 0xFF, 0x1B, 0x60, 0xBE, 0x61, 0xD1, 0x60, 0x58, 0x4E, 0x33, 0x78, 0xFF, 0xFF, 0x1B, 0x60,
+	 0xAC, 0x61, 0xD1, 0x60, 0x58, 0x4E, 0x33, 0x78, 0xFF, 0xFF, 0x1B, 0x60, 0x94, 0x61, 0xD1, 0x60,
+	 0x58, 0x4E, 0x5F, 0x78, 0xFF, 0xFF, 0x0F, 0x60, 0xD6, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x5A, 0xDB,
+	 0xC5, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0xA1, 0xD3, 0x0E, 0x57, 0x24, 0x00, 0x0E, 0xF2, 0x44, 0x4C,
+	 0x80, 0xB0, 0x10, 0xB0, 0x0B, 0x03, 0x1B, 0x60, 0xDA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x66, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x13, 0x00, 0x12, 0x02, 0xF0, 0x37,
+	 0x09, 0x00, 0x02, 0xF0, 0x09, 0x60, 0x08, 0x64, 0xD0, 0x80, 0xA2, 0xFF, 0x90, 0xF3, 0x02, 0x02,
+	 0xCC, 0x84, 0x90, 0xFB, 0x1B, 0x60, 0xDA, 0x64, 0x40, 0x4B, 0xF0, 0x60, 0x58, 0x4D, 0x75, 0x78,
+	 0xFF, 0xFF, 0x2C, 0x44, 0xAC, 0x86, 0x09, 0xF0, 0xD9, 0x02, 0x37, 0x58, 0xFF, 0xFF, 0xA1, 0xD3,
+	 0x0E, 0x57, 0x19, 0x00, 0x0E, 0xF2, 0x44, 0x4C, 0x80, 0xB0, 0x10, 0xB0, 0x0B, 0x03, 0x1B, 0x60,
+	 0xDA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0x08, 0x00, 0x07, 0x02, 0x1B, 0x60, 0xDA, 0x64, 0x40, 0x4B, 0xF0, 0x60, 0x58, 0x4D,
+	 0x75, 0x78, 0xFF, 0xFF, 0x2C, 0x44, 0xAC, 0x86, 0x09, 0xF0, 0xE4, 0x02, 0x37, 0x58, 0xFF, 0xFF,
+	 0x00, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0xB0, 0x64, 0x2A, 0xFA, 0x2F, 0xF2, 0x2C, 0xFA, 0x30, 0xF2,
+	 0x2D, 0xFA, 0x31, 0xF2, 0x2E, 0xFA, 0xCB, 0xF3, 0x2F, 0xFA, 0xCC, 0xF3, 0x30, 0xFA, 0xCD, 0xF3,
+	 0x31, 0xFA, 0x67, 0xF3, 0x32, 0xFA, 0x68, 0xF3, 0x33, 0xFA, 0x69, 0xF3, 0x34, 0xFA, 0xAC, 0xF1,
+	 0x19, 0xF8, 0x06, 0x63, 0x3F, 0xFC, 0x1C, 0xF2, 0x13, 0xFA, 0x00, 0x64, 0x3E, 0xFA, 0x07, 0xF2,
+	 0x88, 0xF1, 0xFF, 0xFF, 0xD0, 0x80, 0xFF, 0xFF, 0x0C, 0x03, 0x60, 0x46, 0x06, 0xF2, 0x26, 0x46,
+	 0x01, 0xB0, 0xFF, 0xFF, 0x03, 0x02, 0xD3, 0x60, 0x64, 0x78, 0xFF, 0xFF, 0xD4, 0x60, 0xBA, 0x78,
+	 0xFF, 0xFF, 0x00, 0xF4, 0x0A, 0xF2, 0x09, 0xF2, 0xFF, 0xA0, 0x00, 0xA0, 0x13, 0x02, 0xFF, 0xA0,
+	 0x04, 0x03, 0x08, 0x03, 0xD1, 0x60, 0xD5, 0x78, 0xFF, 0xFF, 0x02, 0x64, 0x55, 0xFB, 0xD1, 0x60,
+	 0xE0, 0x78, 0xFF, 0xFF, 0x01, 0x63, 0x32, 0x40, 0x08, 0x2A, 0x0F, 0x00, 0x55, 0xFD, 0xD1, 0x60,
+	 0xE0, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x00, 0xF4, 0x0A, 0xF2, 0x0E, 0x63, 0x01, 0xA4, 0x0A, 0xFA,
+	 0x0B, 0xFC, 0x43, 0x59, 0xD4, 0x60, 0x93, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x00, 0xF4, 0x0A, 0xF2,
+	 0x0D, 0x63, 0x01, 0xA4, 0x0A, 0xFA, 0x0B, 0xFC, 0x43, 0x59, 0xD4, 0x60, 0x93, 0x78, 0xFF, 0xFF,
+	 0x88, 0xF5, 0x00, 0xF2, 0x26, 0x46, 0x00, 0xA0, 0x2E, 0xF0, 0x37, 0x03, 0x66, 0x41, 0x12, 0x60,
+	 0xCE, 0x65, 0x64, 0x47, 0x00, 0x7F, 0x88, 0xF1, 0xE0, 0x84, 0x44, 0xD3, 0x64, 0x43, 0x11, 0x18,
+	 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xFC, 0x1B, 0x66, 0x44, 0x64, 0x46, 0x80, 0xF0, 0x60, 0x46,
+	 0x80, 0xF8, 0x65, 0x46, 0x65, 0x43, 0x80, 0xF0, 0x01, 0xFA, 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8,
+	 0x0B, 0x00, 0x64, 0x46, 0x62, 0x43, 0x00, 0xF2, 0xA3, 0xDB, 0x60, 0x46, 0x80, 0xF0, 0x81, 0xFC,
+	 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8, 0x60, 0x43, 0x61, 0x46, 0x87, 0xF1, 0x14, 0x60, 0xCE, 0x61,
+	 0xA1, 0xD3, 0xDA, 0x81, 0xD0, 0x80, 0xDC, 0x9C, 0x05, 0x05, 0xA1, 0xD3, 0x4A, 0xD9, 0xA0, 0xDD,
+	 0xDA, 0x9C, 0xA1, 0xD9, 0xD3, 0x60, 0x2D, 0x78, 0xFF, 0xFF, 0x14, 0x60, 0xCE, 0x64, 0xA0, 0xD3,
+	 0xFF, 0xFF, 0x62, 0x18, 0x14, 0x60, 0xCE, 0x64, 0x04, 0xA5, 0xA0, 0xD1, 0x72, 0x44, 0xFF, 0xB4,
+	 0x64, 0x40, 0xE0, 0x22, 0x1F, 0xB4, 0x64, 0x40, 0xF8, 0x22, 0x07, 0xB4, 0x02, 0x00, 0x03, 0x04,
+	 0xD0, 0x84, 0xD0, 0x80, 0xFC, 0x01, 0xE0, 0x84, 0x44, 0xD3, 0xFF, 0xFF, 0x60, 0x43, 0x66, 0x41,
+	 0x63, 0x46, 0x05, 0xF2, 0x00, 0xF0, 0x81, 0xF0, 0x02, 0x18, 0x64, 0x46, 0x81, 0xF8, 0x07, 0x1B,
+	 0x12, 0x60, 0xCE, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD9, 0x02, 0x00, 0x65, 0x46,
+	 0x00, 0xF8, 0x88, 0xF3, 0x63, 0x45, 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xD4, 0x80, 0x01, 0x18,
+	 0xFA, 0x04, 0x80, 0xF8, 0x65, 0x46, 0x00, 0xFA, 0x06, 0xF2, 0xFF, 0xFF, 0x00, 0x7E, 0x06, 0xFA,
+	 0x61, 0x46, 0x2E, 0xF0, 0x66, 0x41, 0x12, 0x60, 0xCE, 0x65, 0x64, 0x47, 0x00, 0x7F, 0x88, 0xF1,
+	 0xE0, 0x84, 0x44, 0xD3, 0x64, 0x43, 0x11, 0x18, 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xFC, 0x1B,
+	 0x66, 0x44, 0x64, 0x46, 0x80, 0xF0, 0x60, 0x46, 0x80, 0xF8, 0x65, 0x46, 0x65, 0x43, 0x80, 0xF0,
+	 0x01, 0xFA, 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8, 0x0B, 0x00, 0x64, 0x46, 0x62, 0x43, 0x00, 0xF2,
+	 0xA3, 0xDB, 0x60, 0x46, 0x80, 0xF0, 0x81, 0xFC, 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8, 0x60, 0x43,
+	 0x61, 0x46, 0xD3, 0x60, 0x2D, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x02, 0x61, 0xB3, 0x60, 0x58, 0x4D,
+	 0x77, 0x78, 0xFF, 0xFF, 0x87, 0xF1, 0x72, 0x44, 0xFF, 0xB4, 0xD0, 0x80, 0xFF, 0xFF, 0x02, 0x04,
+	 0xD0, 0x84, 0xFB, 0x01, 0xE0, 0x83, 0x88, 0xF3, 0x02, 0xA3, 0x43, 0x93, 0x66, 0x44, 0x00, 0xA8,
+	 0x56, 0xFD, 0x37, 0x03, 0x00, 0x64, 0x2B, 0xFA, 0x00, 0x60, 0xC0, 0x64, 0x2A, 0xFA, 0x66, 0x45,
+	 0x63, 0x46, 0x03, 0xF2, 0x04, 0xF0, 0x85, 0xF2, 0x65, 0x46, 0x2C, 0xFA, 0x2D, 0xF8, 0xAE, 0xFA,
+	 0xCB, 0xF3, 0x2F, 0xFA, 0x32, 0xFA, 0xCC, 0xF3, 0x30, 0xFA, 0x33, 0xFA, 0xCD, 0xF3, 0x31, 0xFA,
+	 0x34, 0xFA, 0xAC, 0xF1, 0x19, 0xF8, 0xFF, 0x67, 0x0E, 0xFA, 0x66, 0x45, 0x63, 0x46, 0x0E, 0xF2,
+	 0x65, 0x46, 0x02, 0x63, 0x00, 0x7E, 0x13, 0xFA, 0x3F, 0xFC, 0x00, 0x64, 0x3E, 0xFA, 0x88, 0xF3,
+	 0x07, 0xFA, 0x66, 0x41, 0x00, 0xF4, 0x05, 0x64, 0x09, 0xFA, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60,
+	 0x8E, 0x64, 0xA2, 0xDB, 0x61, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0xC1, 0xFE, 0x56, 0xF3, 0xA3, 0xFF, 0x60, 0x43, 0xE4, 0x60, 0x58, 0x4E, 0x9D, 0x78, 0xFF, 0xFF,
+	 0x56, 0xF3, 0xFF, 0xFF, 0x40, 0x58, 0x03, 0x65, 0xE2, 0x60, 0x58, 0x4E, 0x86, 0x78, 0xFF, 0xFF,
+	 0x56, 0xF3, 0x26, 0x46, 0x60, 0x43, 0x66, 0x41, 0x63, 0x46, 0x05, 0xF2, 0x00, 0xF0, 0x81, 0xF0,
+	 0x02, 0x18, 0x64, 0x46, 0x81, 0xF8, 0x07, 0x1B, 0x12, 0x60, 0xCE, 0x65, 0x60, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD9, 0x02, 0x00, 0x65, 0x46, 0x00, 0xF8, 0x88, 0xF3, 0x63, 0x45, 0x60, 0x46,
+	 0x00, 0xF2, 0xFF, 0xFF, 0xD4, 0x80, 0x01, 0x18, 0xFA, 0x04, 0x80, 0xF8, 0x65, 0x46, 0x00, 0xFA,
+	 0x06, 0xF2, 0xFF, 0xFF, 0x00, 0x7E, 0x06, 0xFA, 0x61, 0x46, 0x2E, 0xF0, 0x66, 0x41, 0x12, 0x60,
+	 0xCE, 0x65, 0x64, 0x47, 0x00, 0x7F, 0x88, 0xF1, 0xE0, 0x84, 0x44, 0xD3, 0x64, 0x43, 0x11, 0x18,
+	 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xFC, 0x1B, 0x66, 0x44, 0x64, 0x46, 0x80, 0xF0, 0x60, 0x46,
+	 0x80, 0xF8, 0x65, 0x46, 0x65, 0x43, 0x80, 0xF0, 0x01, 0xFA, 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8,
+	 0x0B, 0x00, 0x64, 0x46, 0x62, 0x43, 0x00, 0xF2, 0xA3, 0xDB, 0x60, 0x46, 0x80, 0xF0, 0x81, 0xFC,
+	 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8, 0x60, 0x43, 0x61, 0x46, 0x2C, 0xF2, 0x2D, 0xF0, 0xAE, 0xF2,
+	 0x66, 0x45, 0x63, 0x46, 0x03, 0xFA, 0x04, 0xF8, 0x55, 0xF3, 0x85, 0xFA, 0xFF, 0xA0, 0x65, 0x46,
+	 0x03, 0x03, 0xD4, 0x60, 0xD6, 0x78, 0xFF, 0xFF, 0x95, 0xF3, 0x66, 0x45, 0x63, 0x46, 0x1B, 0xFA,
+	 0x65, 0x46, 0xBA, 0x65, 0x60, 0x44, 0xC4, 0x85, 0x01, 0x60, 0xFE, 0x61, 0x00, 0x64, 0x80, 0x63,
+	 0xC7, 0x85, 0x94, 0x84, 0x59, 0xDB, 0xFC, 0x1F, 0x00, 0x60, 0x88, 0x64, 0x3F, 0xFA, 0x00, 0xF4,
+	 0x02, 0x64, 0x0A, 0xFA, 0x00, 0x64, 0x0B, 0xFA, 0x80, 0x7F, 0x10, 0x7E, 0x0C, 0xFA, 0x1A, 0x65,
+	 0x80, 0x61, 0x02, 0x60, 0x00, 0x63, 0x0F, 0x4E, 0xF2, 0x60, 0x58, 0x4F, 0x4A, 0x78, 0xFF, 0xFF,
+	 0x0E, 0x4F, 0xD4, 0x60, 0xA7, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x23, 0xF0, 0x00, 0x60, 0x02, 0x64,
+	 0xA0, 0x80, 0x00, 0xF4, 0x03, 0x03, 0xD4, 0x60, 0x50, 0x78, 0xFF, 0xFF, 0x09, 0xF2, 0xFF, 0xFF,
+	 0xFF, 0xA0, 0x00, 0xA0, 0x0C, 0x03, 0x03, 0x03, 0xD3, 0x60, 0xCC, 0x78, 0xFF, 0xFF, 0x0A, 0xF2,
+	 0x26, 0x46, 0xFF, 0xA0, 0x87, 0xF4, 0x10, 0x02, 0xD4, 0x60, 0xD6, 0x78, 0xFF, 0xFF, 0x0A, 0xF2,
+	 0xFF, 0xFF, 0xFF, 0xA0, 0xFD, 0xA0, 0x02, 0x03, 0x04, 0x03, 0x06, 0x00, 0xD4, 0x60, 0x0C, 0x78,
+	 0xFF, 0xFF, 0xD4, 0x60, 0x17, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x87, 0xF4, 0x66, 0x41, 0x63, 0x46,
+	 0x05, 0xF2, 0x00, 0xF0, 0x81, 0xF0, 0x02, 0x18, 0x64, 0x46, 0x81, 0xF8, 0x07, 0x1B, 0x12, 0x60,
+	 0xCE, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD9, 0x02, 0x00, 0x65, 0x46, 0x00, 0xF8,
+	 0x88, 0xF3, 0x63, 0x45, 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xD4, 0x80, 0x01, 0x18, 0xFA, 0x04,
+	 0x80, 0xF8, 0x65, 0x46, 0x00, 0xFA, 0x06, 0xF2, 0xFF, 0xFF, 0x00, 0x7E, 0x06, 0xFA, 0x61, 0x46,
+	 0x14, 0x60, 0xD0, 0x62, 0xA2, 0xD3, 0xDA, 0x81, 0x60, 0x45, 0xD5, 0x80, 0xA1, 0xD1, 0x11, 0x03,
+	 0xD3, 0x80, 0xD9, 0x81, 0xFA, 0x02, 0xC9, 0x81, 0xC8, 0x85, 0xD5, 0x80, 0xA5, 0xD3, 0x08, 0x28,
+	 0xA1, 0xDB, 0x14, 0x60, 0xD0, 0x62, 0x65, 0x44, 0xA2, 0xDB, 0x4A, 0xD3, 0xFF, 0xFF, 0xCC, 0x84,
+	 0xA2, 0xDB, 0xD1, 0x60, 0xCA, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x87, 0xF4, 0x66, 0x41, 0x63, 0x46,
+	 0x05, 0xF2, 0x00, 0xF0, 0x81, 0xF0, 0x02, 0x18, 0x64, 0x46, 0x81, 0xF8, 0x07, 0x1B, 0x12, 0x60,
+	 0xCE, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD9, 0x02, 0x00, 0x65, 0x46, 0x00, 0xF8,
+	 0x88, 0xF3, 0x63, 0x45, 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xD4, 0x80, 0x01, 0x18, 0xFA, 0x04,
+	 0x80, 0xF8, 0x65, 0x46, 0x00, 0xFA, 0x06, 0xF2, 0xFF, 0xFF, 0x00, 0x7E, 0x06, 0xFA, 0x61, 0x46,
+	 0x14, 0x60, 0xD0, 0x62, 0xA2, 0xD3, 0xDA, 0x81, 0x60, 0x45, 0xD5, 0x80, 0xA1, 0xD1, 0x11, 0x03,
+	 0xD3, 0x80, 0xD9, 0x81, 0xFA, 0x02, 0xC9, 0x81, 0xC8, 0x85, 0xD5, 0x80, 0xA5, 0xD3, 0x08, 0x28,
+	 0xA1, 0xDB, 0x14, 0x60, 0xD0, 0x62, 0x65, 0x44, 0xA2, 0xDB, 0x4A, 0xD3, 0xFF, 0xFF, 0xCC, 0x84,
+	 0xA2, 0xDB, 0xD1, 0x60, 0xD5, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x32, 0x44, 0x08, 0xB0, 0x87, 0xF4,
+	 0x03, 0x02, 0xD1, 0x60, 0xD5, 0x78, 0xFF, 0xFF, 0xD3, 0x60, 0x3C, 0x78, 0xFF, 0xFF, 0x32, 0x44,
+	 0x26, 0x46, 0x08, 0xB0, 0x07, 0xF2, 0x03, 0x02, 0xD1, 0x60, 0xD5, 0x78, 0xFF, 0xFF, 0x60, 0x46,
+	 0x1B, 0xF2, 0x26, 0x46, 0xBA, 0x65, 0x60, 0x44, 0xC4, 0x85, 0x01, 0x60, 0xFE, 0x61, 0x00, 0x64,
+	 0x80, 0x63, 0xC7, 0x85, 0x94, 0x84, 0x59, 0xDB, 0xFC, 0x1F, 0x00, 0xF4, 0x01, 0x60, 0xFE, 0x61,
+	 0x7E, 0x65, 0x18, 0x63, 0x5B, 0xD2, 0x59, 0xD1, 0xFF, 0xFF, 0xD0, 0x80, 0xD7, 0x80, 0x18, 0x02,
+	 0xF9, 0x02, 0x00, 0xF4, 0x02, 0x63, 0x0E, 0x65, 0x5B, 0xD2, 0x59, 0xD1, 0xFF, 0xFF, 0xD0, 0x80,
+	 0xD7, 0x80, 0x0E, 0x02, 0xF9, 0x02, 0x26, 0x46, 0x07, 0xF4, 0x06, 0xF2, 0xFF, 0xFF, 0x01, 0x7E,
+	 0x06, 0xFA, 0x26, 0x46, 0x00, 0xF4, 0x04, 0x64, 0x0A, 0xFA, 0x00, 0x64, 0x0B, 0xFA, 0x57, 0x00,
+	 0x26, 0x46, 0x87, 0xF4, 0x66, 0x41, 0x63, 0x46, 0x05, 0xF2, 0x00, 0xF0, 0x81, 0xF0, 0x02, 0x18,
+	 0x64, 0x46, 0x81, 0xF8, 0x07, 0x1B, 0x12, 0x60, 0xCE, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84,
+	 0x44, 0xD9, 0x02, 0x00, 0x65, 0x46, 0x00, 0xF8, 0x88, 0xF3, 0x63, 0x45, 0x60, 0x46, 0x00, 0xF2,
+	 0xFF, 0xFF, 0xD4, 0x80, 0x01, 0x18, 0xFA, 0x04, 0x80, 0xF8, 0x65, 0x46, 0x00, 0xFA, 0x06, 0xF2,
+	 0xFF, 0xFF, 0x00, 0x7E, 0x06, 0xFA, 0x61, 0x46, 0x14, 0x60, 0xD0, 0x62, 0xA2, 0xD3, 0xDA, 0x81,
+	 0x60, 0x45, 0xD5, 0x80, 0xA1, 0xD1, 0x11, 0x03, 0xD3, 0x80, 0xD9, 0x81, 0xFA, 0x02, 0xC9, 0x81,
+	 0xC8, 0x85, 0xD5, 0x80, 0xA5, 0xD3, 0x08, 0x28, 0xA1, 0xDB, 0x14, 0x60, 0xD0, 0x62, 0x65, 0x44,
+	 0xA2, 0xDB, 0x4A, 0xD3, 0xFF, 0xFF, 0xCC, 0x84, 0xA2, 0xDB, 0x00, 0xF4, 0x04, 0x64, 0x0A, 0xFA,
+	 0x0F, 0x64, 0x0B, 0xFA, 0x40, 0x59, 0x02, 0x60, 0x00, 0x61, 0x41, 0x58, 0x26, 0x46, 0x2C, 0xF2,
+	 0xA1, 0xDB, 0x2D, 0xF2, 0x59, 0xDB, 0x2E, 0xF2, 0x59, 0xDB, 0x03, 0x65, 0xE2, 0x60, 0x58, 0x4E,
+	 0x5B, 0x78, 0xFF, 0xFF, 0x03, 0x65, 0xE2, 0x60, 0x58, 0x4E, 0x86, 0x78, 0xFF, 0xFF, 0x26, 0x46,
+	 0x88, 0xF3, 0x07, 0xFA, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0x8E, 0x64, 0xA2, 0xDB, 0x26, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x00, 0x66, 0x46, 0x46,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0xF4, 0x0A, 0xF2, 0x09, 0xF2, 0xFF, 0xA0, 0x00, 0xA0, 0x06, 0x02,
+	 0xFF, 0xA0, 0x07, 0x03, 0x09, 0x03, 0xD3, 0x60, 0xCC, 0x78, 0xFF, 0xFF, 0xD3, 0x60, 0x8C, 0x78,
+	 0xFF, 0xFF, 0xD4, 0x60, 0xDB, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x07, 0xF4, 0x06, 0xF2, 0x66, 0x43,
+	 0x00, 0x7E, 0x06, 0xFA, 0x26, 0x46, 0xD3, 0x60, 0x3C, 0x78, 0xFF, 0xFF, 0x63, 0x46, 0x06, 0xF2,
+	 0xFF, 0xFF, 0x01, 0x7E, 0x06, 0xFA, 0x26, 0x46, 0x88, 0xF3, 0x07, 0xFA, 0x00, 0xF4, 0x02, 0x64,
+	 0x0A, 0xFA, 0x00, 0x64, 0x0B, 0xFA, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0x8E, 0x64, 0xA2, 0xDB,
+	 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x00, 0x66,
+	 0x46, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x16, 0x60, 0xAC, 0x7C, 0x2A, 0xF2, 0xA4, 0xDB, 0x22, 0x60,
+	 0x2A, 0x63, 0xFF, 0xB4, 0x01, 0x61, 0x00, 0x60, 0x10, 0x7C, 0xA3, 0xDB, 0x60, 0x40, 0x00, 0x36,
+	 0x03, 0x00, 0x02, 0x61, 0x00, 0x60, 0x30, 0x7C, 0x41, 0x47, 0x2A, 0xF8, 0x2F, 0xF2, 0x2C, 0xFA,
+	 0x30, 0xF2, 0x2D, 0xFA, 0x31, 0xF2, 0x2E, 0xFA, 0xCB, 0xF3, 0x2F, 0xFA, 0xCC, 0xF3, 0x30, 0xFA,
+	 0xCD, 0xF3, 0x31, 0xFA, 0x67, 0xF3, 0x32, 0xFA, 0x68, 0xF3, 0x33, 0xFA, 0x69, 0xF3, 0x34, 0xFA,
+	 0xAC, 0xF1, 0x19, 0xF8, 0x00, 0x7C, 0x3E, 0xF8, 0x1C, 0xF0, 0x13, 0xF8, 0x07, 0xF2, 0x88, 0xF1,
+	 0xFF, 0xFF, 0xD0, 0x80, 0xFF, 0xFF, 0x03, 0x02, 0xD9, 0x60, 0xA3, 0x78, 0xFF, 0xFF, 0x40, 0x4B,
+	 0xAB, 0x46, 0x06, 0xF2, 0xAB, 0x46, 0x00, 0xF4, 0x01, 0xB0, 0xFF, 0xFF, 0x03, 0x02, 0xD9, 0x60,
+	 0xA3, 0x78, 0xFF, 0xFF, 0x22, 0x60, 0x2C, 0x63, 0x09, 0xF2, 0xBD, 0xDB, 0x43, 0x44, 0x10, 0xB0,
+	 0x80, 0x60, 0x00, 0x63, 0x0D, 0x03, 0x1F, 0x60, 0x92, 0x62, 0xA2, 0xD1, 0xFF, 0xFF, 0x64, 0x44,
+	 0xFE, 0x26, 0x08, 0x00, 0x32, 0x40, 0x08, 0x26, 0x06, 0x00, 0xDA, 0x60, 0x02, 0x78, 0xFF, 0xFF,
+	 0x32, 0x40, 0x10, 0x2A, 0x00, 0x63, 0xAB, 0x46, 0x06, 0xF0, 0x7F, 0x60, 0xFF, 0x64, 0xA0, 0x84,
+	 0x63, 0x45, 0xB4, 0x84, 0x06, 0xFA, 0xAB, 0x46, 0x0A, 0xF0, 0x56, 0xF9, 0x24, 0x43, 0xBD, 0xD9,
+	 0x43, 0x44, 0x01, 0x63, 0x32, 0x40, 0x10, 0x26, 0x10, 0xBB, 0x1F, 0x60, 0x92, 0x62, 0xA2, 0xD3,
+	 0xFF, 0xFF, 0x60, 0x40, 0xFE, 0x26, 0x10, 0xBB, 0x09, 0xFC, 0x27, 0x44, 0xFE, 0xA0, 0xFF, 0xFF,
+	 0x03, 0x03, 0xD5, 0x60, 0xFE, 0x78, 0xFF, 0xFF, 0x16, 0x60, 0xA2, 0x64, 0x24, 0x43, 0x0B, 0xF0,
+	 0xA0, 0xD9, 0xBD, 0xD9, 0x0C, 0xF0, 0x58, 0xD9, 0xBD, 0xD9, 0x0D, 0xF0, 0x58, 0xD9, 0xBD, 0xD9,
+	 0x43, 0x44, 0x1C, 0x65, 0x2D, 0x61, 0x02, 0x60, 0x00, 0x63, 0xA5, 0xD0, 0xDA, 0x85, 0x64, 0x44,
+	 0x00, 0x7F, 0xCD, 0x81, 0xBD, 0xDB, 0x05, 0x03, 0x64, 0x47, 0x00, 0x7F, 0xCD, 0x81, 0xBD, 0xDB,
+	 0xF4, 0x02, 0x02, 0x60, 0x02, 0x61, 0xA1, 0xD3, 0xFF, 0xFF, 0xE0, 0x84, 0x04, 0xA5, 0xC5, 0x81,
+	 0xA1, 0xD3, 0x00, 0x65, 0x60, 0x43, 0x59, 0xD3, 0xFF, 0xFF, 0x7F, 0xB4, 0x02, 0x3A, 0x02, 0x00,
+	 0x01, 0x64, 0x15, 0x00, 0x04, 0x3A, 0x02, 0x00, 0x02, 0x64, 0x11, 0x00, 0x0A, 0x3A, 0x02, 0x00,
+	 0x04, 0x64, 0x0D, 0x00, 0x0B, 0x3A, 0x02, 0x00, 0x08, 0x64, 0x09, 0x00, 0x10, 0x3A, 0x02, 0x00,
+	 0x10, 0x64, 0x05, 0x00, 0x16, 0x3A, 0x02, 0x00, 0x20, 0x64, 0x01, 0x00, 0x00, 0x64, 0xCF, 0x83,
+	 0xB4, 0x85, 0xE1, 0x02, 0x65, 0x44, 0x60, 0xFB, 0xB8, 0xF3, 0x2B, 0x45, 0x66, 0x41, 0x65, 0x46,
+	 0x8C, 0xFA, 0x60, 0x40, 0x01, 0x36, 0x06, 0x00, 0x02, 0x36, 0x04, 0x00, 0x04, 0x36, 0x02, 0x00,
+	 0x05, 0x3A, 0x02, 0x00, 0x00, 0x64, 0x01, 0x00, 0x01, 0x64, 0x6F, 0xFA, 0x5F, 0xF3, 0x60, 0xF1,
+	 0xFF, 0xFF, 0xA0, 0x84, 0x65, 0x43, 0x02, 0x02, 0x5F, 0xF3, 0xFF, 0xFF, 0x60, 0x41, 0x0F, 0x60,
+	 0xAE, 0x65, 0xB8, 0xF3, 0xFF, 0xFF, 0xE0, 0x84, 0x44, 0xD3, 0x61, 0x45, 0xA4, 0x80, 0xFF, 0xFF,
+	 0x04, 0x02, 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0xFC, 0x03, 0xA4, 0x84, 0x61, 0xFB, 0x6F, 0xF0,
+	 0x60, 0x47, 0x90, 0x84, 0x6F, 0xFA, 0x60, 0x47, 0x60, 0x45, 0x80, 0x64, 0xE8, 0x84, 0xA4, 0x80,
+	 0xFF, 0xFF, 0xFC, 0x03, 0xA4, 0x84, 0x70, 0xF0, 0x70, 0xFA, 0x00, 0x61, 0xE8, 0x84, 0xFF, 0xFF,
+	 0x02, 0x05, 0xDD, 0x81, 0xFB, 0x01, 0xE1, 0x81, 0x0F, 0x60, 0xA2, 0x65, 0x45, 0xD3, 0x0E, 0xFA,
+	 0x66, 0x43, 0x0C, 0xF4, 0xFF, 0xFF, 0xD6, 0x60, 0x80, 0x78, 0xFF, 0xFF, 0x16, 0x65, 0x2D, 0x61,
+	 0x02, 0x60, 0x00, 0x63, 0xA5, 0xD0, 0xDA, 0x85, 0x64, 0x44, 0x00, 0x7F, 0xCD, 0x81, 0xBD, 0xDB,
+	 0x05, 0x03, 0x64, 0x47, 0x00, 0x7F, 0xCD, 0x81, 0xBD, 0xDB, 0xF4, 0x02, 0x02, 0x60, 0x02, 0x61,
+	 0xA1, 0xD3, 0xFF, 0xFF, 0xE0, 0x84, 0x04, 0xA5, 0xC5, 0x81, 0xA1, 0xD3, 0x00, 0x65, 0x60, 0x43,
+	 0x59, 0xD3, 0xFF, 0xFF, 0x7F, 0xB4, 0x02, 0x3A, 0x02, 0x00, 0x01, 0x64, 0x15, 0x00, 0x04, 0x3A,
+	 0x02, 0x00, 0x02, 0x64, 0x11, 0x00, 0x0A, 0x3A, 0x02, 0x00, 0x04, 0x64, 0x0D, 0x00, 0x0B, 0x3A,
+	 0x02, 0x00, 0x08, 0x64, 0x09, 0x00, 0x10, 0x3A, 0x02, 0x00, 0x10, 0x64, 0x05, 0x00, 0x16, 0x3A,
+	 0x02, 0x00, 0x20, 0x64, 0x01, 0x00, 0x00, 0x64, 0xCF, 0x83, 0xB4, 0x85, 0xE1, 0x02, 0x65, 0x44,
+	 0x60, 0xFB, 0xB8, 0xF3, 0x2B, 0x45, 0x66, 0x41, 0x65, 0x46, 0x8C, 0xFA, 0x60, 0x40, 0x01, 0x36,
+	 0x06, 0x00, 0x02, 0x36, 0x04, 0x00, 0x04, 0x36, 0x02, 0x00, 0x05, 0x3A, 0x02, 0x00, 0x00, 0x64,
+	 0x01, 0x00, 0x01, 0x64, 0x6F, 0xFA, 0x5F, 0xF3, 0x60, 0xF1, 0xFF, 0xFF, 0xA0, 0x84, 0x65, 0x43,
+	 0x02, 0x02, 0x5F, 0xF3, 0xFF, 0xFF, 0x60, 0x41, 0x0F, 0x60, 0xAE, 0x65, 0xB8, 0xF3, 0xFF, 0xFF,
+	 0xE0, 0x84, 0x44, 0xD3, 0x61, 0x45, 0xA4, 0x80, 0xFF, 0xFF, 0x04, 0x02, 0xE8, 0x84, 0xA4, 0x80,
+	 0xFF, 0xFF, 0xFC, 0x03, 0xA4, 0x84, 0x61, 0xFB, 0x6F, 0xF0, 0x60, 0x47, 0x90, 0x84, 0x6F, 0xFA,
+	 0x60, 0x47, 0x60, 0x45, 0x80, 0x64, 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0xFC, 0x03, 0xA4, 0x84,
+	 0x70, 0xF0, 0x70, 0xFA, 0x00, 0x61, 0xE8, 0x84, 0xFF, 0xFF, 0x02, 0x05, 0xDD, 0x81, 0xFB, 0x01,
+	 0xE1, 0x81, 0x0F, 0x60, 0xA2, 0x65, 0x45, 0xD3, 0x0E, 0xFA, 0x66, 0x43, 0x0C, 0xF4, 0xFF, 0xFF,
+	 0x26, 0x46, 0x3F, 0xF2, 0x00, 0xF4, 0x16, 0x65, 0x27, 0x40, 0x02, 0x3A, 0x03, 0x00, 0x1C, 0x65,
+	 0xF6, 0xA4, 0x01, 0x00, 0xFC, 0xA4, 0x24, 0x43, 0x22, 0x60, 0x82, 0x61, 0x5D, 0x91, 0x51, 0x90,
+	 0xFF, 0xFF, 0x04, 0x28, 0x60, 0x41, 0xCD, 0x84, 0x4C, 0x91, 0x60, 0x43, 0x60, 0xFE, 0xA5, 0xD2,
+	 0xDE, 0x85, 0x7F, 0x26, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0x5D, 0x93, 0xA3, 0xDB, 0x5D, 0x93,
+	 0xA5, 0xD2, 0xF6, 0x1F, 0x5D, 0x93, 0x20, 0xFE, 0xDF, 0x83, 0x22, 0x60, 0x28, 0x7C, 0x03, 0x1E,
+	 0x60, 0xFE, 0xBD, 0xDF, 0x20, 0xFE, 0x22, 0x60, 0x2C, 0x64, 0x53, 0x93, 0xA4, 0xDD, 0x26, 0x46,
+	 0x00, 0xF4, 0x1F, 0x60, 0x90, 0x64, 0xA0, 0xD3, 0x00, 0x63, 0x00, 0xB8, 0x0A, 0xFC, 0x03, 0x02,
+	 0xD7, 0x60, 0x14, 0x78, 0xFF, 0xFF, 0x0B, 0xF2, 0x27, 0x40, 0x02, 0x3A, 0x02, 0x00, 0x0E, 0xF2,
+	 0xFF, 0xFF, 0x60, 0x47, 0x00, 0x3A, 0x26, 0x00, 0x60, 0x41, 0x00, 0x36, 0x23, 0x00, 0xE0, 0xA0,
+	 0xDA, 0x85, 0x20, 0x07, 0x1F, 0x60, 0x1E, 0x63, 0xA3, 0xD1, 0x65, 0x42, 0xD1, 0x80, 0x1F, 0x60,
+	 0x20, 0x63, 0x18, 0x02, 0x50, 0xFE, 0x61, 0x40, 0xFE, 0x22, 0x08, 0x00, 0x62, 0x45, 0xBD, 0xD3,
+	 0xA5, 0xD0, 0xDA, 0x82, 0xD0, 0x80, 0xC9, 0x81, 0xF6, 0x0C, 0x0C, 0x00, 0x61, 0x40, 0x00, 0x36,
+	 0x33, 0x00, 0x62, 0x45, 0xA3, 0xD3, 0xA5, 0xD0, 0xFF, 0xFF, 0x90, 0x80, 0xFF, 0x26, 0x02, 0x00,
+	 0xDE, 0x82, 0x2A, 0x00, 0x0C, 0x63, 0x0A, 0xFC, 0x00, 0x64, 0x09, 0xFA, 0x0B, 0xFA, 0x01, 0x7E,
+	 0x0C, 0xFA, 0x26, 0x46, 0x08, 0x64, 0x3F, 0xFA, 0x07, 0xF2, 0x88, 0xF1, 0x40, 0x58, 0x07, 0xF8,
+	 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0x8E, 0x64, 0xA2, 0xDB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0xDA, 0x60, 0x1E, 0x78, 0xFF, 0xFF, 0x20, 0xFE,
+	 0x21, 0x60, 0xE2, 0x61, 0xA1, 0xD3, 0xFF, 0xFF, 0x22, 0xB0, 0xFF, 0xFF, 0x03, 0x03, 0xD8, 0x60,
+	 0x9F, 0x78, 0xFF, 0xFF, 0x01, 0x63, 0xD7, 0x01, 0x1F, 0x60, 0x92, 0x62, 0xA2, 0xD3, 0xFF, 0xFF,
+	 0xFF, 0xA4, 0xFF, 0xFF, 0x0C, 0x20, 0x0D, 0x00, 0xD8, 0x60, 0x9F, 0x78, 0xFF, 0xFF, 0x20, 0xFE,
+	 0x28, 0x46, 0x2A, 0x41, 0xFF, 0xB1, 0x60, 0xFE, 0x82, 0x64, 0xA1, 0xDA, 0xFF, 0xFF, 0x20, 0xFE,
+	 0x15, 0x00, 0x21, 0x60, 0xEE, 0x61, 0xA1, 0xDF, 0xD9, 0x81, 0xA1, 0xDF, 0xD9, 0x81, 0xA1, 0xDF,
+	 0x04, 0xA1, 0xA1, 0xDF, 0xD9, 0x81, 0xA1, 0xDF, 0xD9, 0x81, 0xA1, 0xDF, 0xD9, 0x81, 0xA1, 0xDF,
+	 0x2B, 0x46, 0x37, 0xF2, 0x7F, 0x60, 0xCF, 0x65, 0xA4, 0x84, 0xA2, 0xDA, 0x26, 0x46, 0x3F, 0xF2,
+	 0x00, 0xF4, 0x27, 0x40, 0x02, 0x3A, 0x40, 0x00, 0x60, 0x43, 0xF6, 0xA3, 0x00, 0x60, 0x1B, 0x61,
+	 0x00, 0x60, 0xDD, 0x65, 0x60, 0xFE, 0x81, 0xA1, 0x7F, 0xA1, 0x02, 0x06, 0x00, 0xF4, 0x03, 0x61,
+	 0xDD, 0x81, 0xA1, 0xD2, 0xCF, 0x83, 0xD4, 0x80, 0x2D, 0x03, 0x17, 0x03, 0xCF, 0x83, 0x61, 0x44,
+	 0x80, 0xA0, 0x28, 0x03, 0x02, 0x02, 0x00, 0xF4, 0x03, 0x61, 0xDD, 0x81, 0xA1, 0xD2, 0xCF, 0x83,
+	 0x81, 0xA1, 0x20, 0x03, 0x05, 0x07, 0x7F, 0xA1, 0xCC, 0x84, 0xDD, 0x81, 0xE4, 0x03, 0xF7, 0x01,
+	 0x00, 0xF4, 0x00, 0xB8, 0x04, 0x61, 0xE4, 0x03, 0xF2, 0x01, 0x01, 0x60, 0xFF, 0x63, 0x46, 0x48,
+	 0x41, 0x4A, 0xDD, 0x81, 0xA1, 0xD0, 0xDF, 0x83, 0xA3, 0xD9, 0x64, 0x44, 0xDD, 0x81, 0xA1, 0xD0,
+	 0xDF, 0x83, 0xA3, 0xD9, 0xCC, 0x84, 0x81, 0xA1, 0x05, 0x03, 0x7F, 0xA1, 0xF7, 0x04, 0x00, 0xF4,
+	 0x03, 0x61, 0xF4, 0x01, 0x20, 0xFE, 0x3F, 0x00, 0x60, 0x43, 0xFC, 0xA3, 0x00, 0x60, 0x15, 0x61,
+	 0x00, 0x60, 0xDD, 0x65, 0x60, 0xFE, 0x81, 0xA1, 0x7F, 0xA1, 0x02, 0x06, 0x00, 0xF4, 0x03, 0x61,
+	 0xDD, 0x81, 0xA1, 0xD2, 0xCF, 0x83, 0xD4, 0x80, 0x2D, 0x03, 0x17, 0x03, 0xCF, 0x83, 0x61, 0x44,
+	 0x80, 0xA0, 0x28, 0x03, 0x02, 0x02, 0x00, 0xF4, 0x03, 0x61, 0xDD, 0x81, 0xA1, 0xD2, 0xCF, 0x83,
+	 0x81, 0xA1, 0x20, 0x03, 0x05, 0x07, 0x7F, 0xA1, 0xCC, 0x84, 0xDD, 0x81, 0xE4, 0x03, 0xF7, 0x01,
+	 0x00, 0xF4, 0x00, 0xB8, 0x04, 0x61, 0xE4, 0x03, 0xF2, 0x01, 0x01, 0x60, 0xFF, 0x63, 0x46, 0x48,
+	 0x41, 0x4A, 0xDD, 0x81, 0xA1, 0xD0, 0xDF, 0x83, 0xA3, 0xD9, 0x64, 0x44, 0xDD, 0x81, 0xA1, 0xD0,
+	 0xDF, 0x83, 0xA3, 0xD9, 0xCC, 0x84, 0x81, 0xA1, 0x05, 0x03, 0x7F, 0xA1, 0xF7, 0x04, 0x00, 0xF4,
+	 0x03, 0x61, 0xF4, 0x01, 0x20, 0xFE, 0x00, 0xBB, 0x02, 0x60, 0x00, 0x61, 0x08, 0x24, 0xD7, 0x00,
+	 0x60, 0xFE, 0xA1, 0xD3, 0xFF, 0xFF, 0xFA, 0xA4, 0xFF, 0xFF, 0x01, 0x05, 0x50, 0x01, 0xDD, 0x81,
+	 0xA1, 0xD1, 0xFF, 0xFF, 0x64, 0x40, 0x00, 0x3A, 0x4A, 0x01, 0xDD, 0x81, 0xA1, 0xD1, 0xFF, 0xFF,
+	 0x64, 0x40, 0x50, 0x3A, 0x44, 0x01, 0xDD, 0x81, 0xA1, 0xD1, 0xFF, 0xFF, 0x64, 0x40, 0xF2, 0x3A,
+	 0x3E, 0x01, 0xDD, 0x81, 0xA1, 0xD1, 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x3A, 0x20, 0x01, 0xDD, 0x81,
+	 0xA1, 0xD1, 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x3A, 0x1A, 0x01, 0xDD, 0x81, 0xA1, 0xD1, 0xFF, 0xFF,
+	 0x64, 0x40, 0x00, 0x3A, 0x14, 0x01, 0x60, 0x5C, 0x00, 0x36, 0x30, 0x00, 0x00, 0x64, 0xD8, 0x60,
+	 0x58, 0x4E, 0xC4, 0x78, 0xFF, 0xFF, 0x21, 0x60, 0xF6, 0x62, 0xA2, 0xDB, 0x64, 0x40, 0x00, 0x36,
+	 0x2B, 0x00, 0xDD, 0x81, 0xA1, 0xD3, 0xDD, 0x81, 0xD8, 0x60, 0x58, 0x4E, 0xC4, 0x78, 0xFF, 0xFF,
+	 0x21, 0x60, 0xF8, 0x62, 0xA2, 0xDB, 0x64, 0x40, 0x00, 0x36, 0x24, 0x00, 0xDD, 0x81, 0xA1, 0xD3,
+	 0xDD, 0x81, 0xD8, 0x60, 0x58, 0x4E, 0xC4, 0x78, 0xFF, 0xFF, 0x21, 0x60, 0xFA, 0x62, 0xA2, 0xDB,
+	 0x64, 0x40, 0x00, 0x36, 0x1D, 0x00, 0xDD, 0x81, 0xA1, 0xD1, 0x21, 0x60, 0xFC, 0x62, 0xA2, 0xD9,
+	 0xDD, 0x81, 0xA1, 0xD1, 0x21, 0x60, 0xFD, 0x62, 0xA2, 0xD9, 0x19, 0x00, 0x20, 0xFE, 0x21, 0x60,
+	 0xF6, 0x62, 0x00, 0x60, 0x04, 0x64, 0xA2, 0xDB, 0x20, 0xFE, 0x21, 0x60, 0xF8, 0x62, 0x00, 0x60,
+	 0x04, 0x64, 0xA2, 0xDB, 0x20, 0xFE, 0x21, 0x60, 0xFA, 0x62, 0x00, 0x60, 0x02, 0x64, 0xA2, 0xDB,
+	 0x20, 0xFE, 0x21, 0x60, 0xFC, 0x62, 0x00, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0x00, 0x00, 0x20, 0xFE,
+	 0x21, 0x60, 0xE2, 0x62, 0xA2, 0xD1, 0x21, 0x60, 0xF6, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0xA0, 0x84,
+	 0xFF, 0xFF, 0x10, 0x26, 0x09, 0x00, 0x04, 0x26, 0x09, 0x00, 0x20, 0x26, 0x09, 0x00, 0x02, 0x26,
+	 0x09, 0x00, 0xD7, 0x60, 0x07, 0x78, 0xFF, 0xFF, 0x10, 0x7C, 0x05, 0x00, 0x04, 0x7C, 0x03, 0x00,
+	 0x20, 0x7C, 0x01, 0x00, 0x02, 0x7C, 0x21, 0x60, 0xEE, 0x61, 0xA1, 0xD9, 0x21, 0x60, 0xE4, 0x61,
+	 0xA1, 0xD1, 0x21, 0x60, 0xF8, 0x61, 0xA1, 0xD3, 0x21, 0x60, 0xEE, 0x61, 0xA0, 0x84, 0xA1, 0xD1,
+	 0xFF, 0xFF, 0x10, 0x26, 0x07, 0x00, 0x04, 0x26, 0x07, 0x00, 0x01, 0x26, 0x0D, 0x00, 0xD7, 0x60,
+	 0x07, 0x78, 0xFF, 0xFF, 0x10, 0x7C, 0x09, 0x00, 0x64, 0x40, 0x10, 0x22, 0x03, 0x00, 0xD7, 0x60,
+	 0x07, 0x78, 0xFF, 0xFF, 0x04, 0x7C, 0x01, 0x00, 0x01, 0x7C, 0x21, 0x60, 0xF0, 0x61, 0xA1, 0xD9,
+	 0x21, 0x60, 0xE6, 0x61, 0xA1, 0xD1, 0x21, 0x60, 0xFA, 0x61, 0xA1, 0xD3, 0xFF, 0xFF, 0xA0, 0x84,
+	 0x02, 0x26, 0x07, 0x00, 0x04, 0x26, 0x07, 0x00, 0x01, 0x26, 0x07, 0x00, 0xD7, 0x60, 0x07, 0x78,
+	 0xFF, 0xFF, 0x02, 0x7C, 0x03, 0x00, 0x04, 0x7C, 0x01, 0x00, 0x20, 0x7C, 0x21, 0x60, 0xF2, 0x61,
+	 0xA1, 0xD9, 0x21, 0x60, 0xFC, 0x61, 0xA1, 0xD1, 0x21, 0x60, 0xF4, 0x61, 0xA1, 0xD9, 0x21, 0x60,
+	 0xF2, 0x61, 0xA1, 0xD3, 0xFF, 0xFF, 0x60, 0x47, 0x21, 0x60, 0xF0, 0x61, 0xA1, 0xD1, 0xFF, 0xFF,
+	 0xB0, 0x84, 0x1F, 0x60, 0x92, 0x62, 0xA2, 0xD1, 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x36, 0x22, 0xBC,
+	 0xAB, 0x46, 0x36, 0xFA, 0xAB, 0x46, 0x21, 0x60, 0xEE, 0x61, 0xA1, 0xD3, 0x1F, 0x60, 0x92, 0x62,
+	 0xA2, 0xD1, 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x36, 0x22, 0xBC, 0x88, 0xF1, 0x66, 0x41, 0x64, 0x46,
+	 0x36, 0xFA, 0xFF, 0xFF, 0x61, 0x46, 0x50, 0x00, 0x21, 0x60, 0xFE, 0x62, 0xA2, 0xDB, 0xE0, 0x84,
+	 0xE0, 0x84, 0x03, 0x02, 0x01, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x02, 0xA5, 0x64, 0x44, 0xD4, 0x9C,
+	 0x22, 0x60, 0x00, 0x62, 0xA2, 0xD9, 0x22, 0x60, 0x02, 0x62, 0xA2, 0xDF, 0xDD, 0x81, 0xA1, 0xD1,
+	 0x00, 0x65, 0x64, 0x40, 0x00, 0x3A, 0x01, 0x65, 0xDD, 0x81, 0xA1, 0xD1, 0xFF, 0xFF, 0x64, 0x40,
+	 0x50, 0x3A, 0x01, 0x65, 0xDD, 0x81, 0xA1, 0xD1, 0xFF, 0xFF, 0x64, 0x40, 0xF2, 0x3A, 0x01, 0x65,
+	 0xDD, 0x81, 0xA1, 0xD1, 0x65, 0x40, 0x00, 0x3A, 0x18, 0x00, 0x00, 0x60, 0x00, 0x65, 0x64, 0x40,
+	 0x00, 0x36, 0x01, 0x65, 0x64, 0x40, 0x01, 0x36, 0x02, 0x65, 0x64, 0x40, 0x02, 0x36, 0x04, 0x65,
+	 0x64, 0x40, 0x04, 0x36, 0x10, 0x65, 0x64, 0x40, 0x05, 0x36, 0x20, 0x65, 0x65, 0x5C, 0x22, 0x60,
+	 0x02, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0xB0, 0x84, 0xA2, 0xDB, 0x21, 0x60, 0xFE, 0x62, 0xA2, 0xD3,
+	 0xFF, 0xFF, 0xFF, 0xA4, 0xA2, 0xDB, 0xCA, 0x02, 0x22, 0x60, 0x02, 0x62, 0xA2, 0xD3, 0x22, 0x60,
+	 0x00, 0x62, 0xA2, 0xD1, 0x2E, 0x58, 0xFF, 0xFF, 0xAB, 0x46, 0x82, 0xF0, 0xC0, 0x67, 0xB4, 0x84,
+	 0xAB, 0x46, 0x0B, 0xFA, 0x1F, 0x60, 0xA0, 0x64, 0xA0, 0xD1, 0x22, 0x60, 0xD4, 0x7C, 0x04, 0x1B,
+	 0xFF, 0x60, 0xFF, 0x63, 0xA4, 0xDD, 0x29, 0x00, 0x23, 0x60, 0x3C, 0x63, 0xA4, 0xDD, 0xDB, 0x83,
+	 0x60, 0xFE, 0x00, 0x64, 0xBD, 0xDB, 0x60, 0x64, 0xBD, 0xDB, 0x1D, 0x64, 0xBD, 0xDB, 0xC3, 0xF3,
+	 0xBD, 0xDB, 0xFF, 0xFF, 0x20, 0xFE, 0x01, 0x60, 0x78, 0x64, 0x06, 0x61, 0x58, 0xD1, 0xFF, 0xFF,
+	 0x60, 0xFE, 0xBD, 0xD9, 0x20, 0xFE, 0xCD, 0x81, 0x61, 0x40, 0x08, 0x28, 0xF7, 0x01, 0xB7, 0xF1,
+	 0xFF, 0xFF, 0x64, 0x47, 0x60, 0xFE, 0xBD, 0xD9, 0xBD, 0xDB, 0x20, 0xFE, 0x1F, 0x60, 0x9C, 0x64,
+	 0xA0, 0xD1, 0x60, 0xFE, 0xBD, 0xD9, 0xFF, 0xFF, 0x20, 0xFE, 0x22, 0x60, 0xD2, 0x64, 0x40, 0x48,
+	 0x18, 0x61, 0x26, 0x46, 0x00, 0xF4, 0xFF, 0x60, 0xF2, 0x64, 0xE1, 0x60, 0x58, 0x4D, 0xE5, 0x78,
+	 0xFF, 0xFF, 0x26, 0x46, 0x3F, 0xFC, 0x2B, 0x46, 0x56, 0xF1, 0x16, 0x60, 0xAC, 0x61, 0x1B, 0xF8,
+	 0xA1, 0xD1, 0x10, 0x60, 0x00, 0x64, 0xA0, 0x80, 0x06, 0xF2, 0x0C, 0x03, 0x10, 0xBC, 0x06, 0xFA,
+	 0x87, 0xF3, 0x00, 0x60, 0xE2, 0x62, 0xA2, 0xD3, 0x60, 0x45, 0xD4, 0x80, 0xDC, 0x84, 0x07, 0x07,
+	 0xA2, 0xDB, 0x05, 0x00, 0x10, 0xB5, 0xFF, 0xFF, 0x02, 0x03, 0xD4, 0x84, 0x06, 0xFA, 0x07, 0xF2,
+	 0x66, 0x45, 0x60, 0x46, 0x06, 0xF2, 0x65, 0x46, 0x02, 0xB0, 0xFF, 0xFF, 0x12, 0x03, 0x26, 0x46,
+	 0x88, 0xF3, 0x07, 0xFA, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0x8E, 0x64, 0xA2, 0xDB, 0x26, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x00, 0x66, 0x46, 0x46,
+	 0x4C, 0x00, 0x26, 0x46, 0x88, 0xF3, 0x07, 0xFA, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0x8E, 0x64,
+	 0xA2, 0xDB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE,
+	 0x00, 0x66, 0x46, 0x46, 0x1A, 0x00, 0x00, 0x60, 0xC0, 0x64, 0x2A, 0xFA, 0x02, 0x64, 0x3F, 0xFA,
+	 0x88, 0xF3, 0x07, 0xFA, 0x00, 0xF4, 0x09, 0x64, 0x09, 0xFA, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60,
+	 0x8E, 0x64, 0xA2, 0xDB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0xC1, 0xFE, 0x00, 0x66, 0x46, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x2B, 0x43, 0x14, 0x60, 0xD0, 0x62,
+	 0xA2, 0xD3, 0xDA, 0x81, 0x60, 0x45, 0xD5, 0x80, 0xA1, 0xD1, 0x11, 0x03, 0xD3, 0x80, 0xD9, 0x81,
+	 0xFA, 0x02, 0xC9, 0x81, 0xC8, 0x85, 0xD5, 0x80, 0xA5, 0xD3, 0x08, 0x28, 0xA1, 0xDB, 0x14, 0x60,
+	 0xD0, 0x62, 0x65, 0x44, 0xA2, 0xDB, 0x4A, 0xD3, 0xFF, 0xFF, 0xCC, 0x84, 0xA2, 0xDB, 0xAB, 0x46,
+	 0x06, 0xF2, 0xFF, 0xFF, 0x02, 0xBC, 0x06, 0xFA, 0xAB, 0x46, 0xAB, 0x46, 0x0F, 0x60, 0xFF, 0x64,
+	 0x02, 0xF0, 0x72, 0xF1, 0xA0, 0x84, 0xD0, 0x80, 0x02, 0xFA, 0xAB, 0x46, 0x01, 0x06, 0x72, 0xFB,
+	 0x27, 0x41, 0x01, 0xB1, 0xFF, 0xFF, 0x08, 0x03, 0x2B, 0x46, 0x0B, 0x58, 0x01, 0x65, 0xE2, 0x60,
+	 0x58, 0x4E, 0x86, 0x78, 0xFF, 0xFF, 0x0A, 0x00, 0x2B, 0x46, 0x0B, 0x58, 0x16, 0x60, 0xA2, 0x64,
+	 0x40, 0x59, 0x02, 0x65, 0xE2, 0x60, 0x58, 0x4E, 0x86, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x26, 0x46, 0x00, 0xF4, 0x00, 0x64, 0x09, 0xFA, 0x0B, 0xFA, 0x01, 0x7E,
+	 0x0C, 0xFA, 0x0A, 0x64, 0x0A, 0xFA, 0x26, 0x46, 0x08, 0x64, 0x3F, 0xFA, 0x07, 0xF2, 0x88, 0xF1,
+	 0x40, 0x58, 0x07, 0xF8, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0x8E, 0x64, 0xA2, 0xDB, 0x26, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0xFF, 0x60, 0xFD, 0x65,
+	 0x38, 0x46, 0x06, 0xF2, 0xFF, 0xFF, 0xA4, 0x83, 0x06, 0xFC, 0x02, 0xB0, 0x26, 0x46, 0x1C, 0x03,
+	 0x38, 0x43, 0x87, 0xF1, 0x14, 0x60, 0xCE, 0x61, 0xA1, 0xD3, 0xDA, 0x81, 0xD0, 0x80, 0xDC, 0x9C,
+	 0x05, 0x05, 0xA1, 0xD3, 0x4A, 0xD9, 0xA0, 0xDD, 0xDA, 0x9C, 0xA1, 0xD9, 0x02, 0x60, 0x00, 0x61,
+	 0x2C, 0xF2, 0xA1, 0xDB, 0x2D, 0xF2, 0x41, 0x58, 0x59, 0xDB, 0x2E, 0xF2, 0x59, 0xDB, 0x03, 0x65,
+	 0xE2, 0x60, 0x58, 0x4E, 0x86, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x07, 0xF2, 0x88, 0xF1, 0xFF, 0xFF, 0xD0, 0x80, 0xFF, 0xFF, 0x02, 0x02, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x40, 0x47, 0x07, 0xF2, 0x66, 0x45, 0x60, 0x46, 0x06, 0xF2, 0x65, 0x46, 0x02, 0xB0, 0xFF, 0xFF,
+	 0x1B, 0x02, 0x27, 0x43, 0x14, 0x60, 0xD0, 0x62, 0xA2, 0xD3, 0xDA, 0x81, 0x60, 0x45, 0xD5, 0x80,
+	 0xA1, 0xD1, 0x11, 0x03, 0xD3, 0x80, 0xD9, 0x81, 0xFA, 0x02, 0xC9, 0x81, 0xC8, 0x85, 0xD5, 0x80,
+	 0xA5, 0xD3, 0x08, 0x28, 0xA1, 0xDB, 0x14, 0x60, 0xD0, 0x62, 0x65, 0x44, 0xA2, 0xDB, 0x4A, 0xD3,
+	 0xFF, 0xFF, 0xCC, 0x84, 0xA2, 0xDB, 0x0C, 0x00, 0x27, 0x44, 0x40, 0x58, 0x03, 0x65, 0xE2, 0x60,
+	 0x58, 0x4E, 0x86, 0x78, 0xFF, 0xFF, 0x27, 0x43, 0xE4, 0x60, 0x58, 0x4E, 0x9D, 0x78, 0xFF, 0xFF,
+	 0x26, 0x46, 0x87, 0xF4, 0x66, 0x41, 0x63, 0x46, 0x05, 0xF2, 0x00, 0xF0, 0x81, 0xF0, 0x02, 0x18,
+	 0x64, 0x46, 0x81, 0xF8, 0x07, 0x1B, 0x12, 0x60, 0xCE, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84,
+	 0x44, 0xD9, 0x02, 0x00, 0x65, 0x46, 0x00, 0xF8, 0x88, 0xF3, 0x63, 0x45, 0x60, 0x46, 0x00, 0xF2,
+	 0xFF, 0xFF, 0xD4, 0x80, 0x01, 0x18, 0xFA, 0x04, 0x80, 0xF8, 0x65, 0x46, 0x00, 0xFA, 0x06, 0xF2,
+	 0xFF, 0xFF, 0x00, 0x7E, 0x06, 0xFA, 0x61, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x07, 0xF2, 0x88, 0xF1,
+	 0xFF, 0xFF, 0xD0, 0x80, 0xFF, 0xFF, 0x02, 0x02, 0x2F, 0x58, 0xFF, 0xFF, 0x40, 0x47, 0x07, 0xF2,
+	 0x66, 0x45, 0x60, 0x46, 0x06, 0xF2, 0x65, 0x46, 0x02, 0xB0, 0xFF, 0xFF, 0x02, 0x02, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x27, 0x46, 0x06, 0xF0, 0xFF, 0x60, 0xED, 0x64, 0xA0, 0x84, 0x06, 0xFA, 0x27, 0x43,
+	 0x87, 0xF1, 0x14, 0x60, 0xCE, 0x61, 0xA1, 0xD3, 0xDA, 0x81, 0xD0, 0x80, 0xDC, 0x9C, 0x05, 0x05,
+	 0xA1, 0xD3, 0x4A, 0xD9, 0xA0, 0xDD, 0xDA, 0x9C, 0xA1, 0xD9, 0x07, 0x58, 0x03, 0x65, 0xE2, 0x60,
+	 0x58, 0x4E, 0x86, 0x78, 0xFF, 0xFF, 0x27, 0x43, 0xE4, 0x60, 0x58, 0x4E, 0x9D, 0x78, 0xFF, 0xFF,
+	 0x26, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x26, 0x46, 0x2F, 0xF2, 0x2C, 0xFA, 0x30, 0xF2, 0x2D, 0xFA,
+	 0x31, 0xF2, 0x2E, 0xFA, 0xCB, 0xF3, 0x2F, 0xFA, 0xCC, 0xF3, 0x30, 0xFA, 0xCD, 0xF3, 0x31, 0xFA,
+	 0x67, 0xF3, 0x32, 0xFA, 0x68, 0xF3, 0x33, 0xFA, 0x69, 0xF3, 0x34, 0xFA, 0xAC, 0xF1, 0x19, 0xF8,
+	 0x1C, 0xF2, 0x13, 0xFA, 0x02, 0x63, 0x3F, 0xFC, 0x00, 0x64, 0x3E, 0xFA, 0x02, 0x60, 0x00, 0x61,
+	 0x2C, 0xF2, 0xA1, 0xDB, 0x2D, 0xF2, 0x41, 0x58, 0x59, 0xDB, 0x2E, 0xF2, 0x59, 0xDB, 0x06, 0x63,
+	 0x07, 0xF2, 0x88, 0xF1, 0xFF, 0xFF, 0xD0, 0x80, 0xFF, 0xFF, 0x0D, 0x02, 0x43, 0x59, 0x02, 0x65,
+	 0xE2, 0x60, 0x58, 0x4E, 0x5B, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0xC0, 0x64, 0x2A, 0xFA, 0x00, 0xF4,
+	 0x06, 0x64, 0x09, 0xFA, 0x15, 0x00, 0x07, 0xF2, 0x66, 0x45, 0x60, 0x46, 0x06, 0xF2, 0x65, 0x46,
+	 0x02, 0xB0, 0xFF, 0xFF, 0x1E, 0x02, 0x07, 0x63, 0x43, 0x59, 0x01, 0x65, 0xE2, 0x60, 0x58, 0x4E,
+	 0x5B, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0xA0, 0x64, 0x2A, 0xFA, 0x00, 0xF4, 0x07, 0x64, 0x09, 0xFA,
+	 0x26, 0x46, 0x88, 0xF3, 0x07, 0xFA, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0x8E, 0x64, 0xA2, 0xDB,
+	 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x00, 0x66,
+	 0x46, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xFE, 0x62, 0xDB, 0x60, 0xB0, 0x64, 0xA2, 0xDB,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x60, 0x03, 0x64, 0xA2, 0xDB, 0xDB, 0x60,
+	 0x4D, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xE8, 0x62, 0xA2, 0xD1,
+	 0x00, 0x60, 0x02, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x5A, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x72, 0xF3,
+	 0x88, 0xF5, 0xDC, 0x81, 0x66, 0x43, 0x02, 0xA3, 0x63, 0x46, 0xCD, 0x81, 0x06, 0xF2, 0xED, 0x03,
+	 0x60, 0x40, 0x08, 0x2A, 0xF7, 0x01, 0x0C, 0xAC, 0x06, 0xFA, 0x46, 0x49, 0x00, 0x60, 0x02, 0x61,
+	 0xB3, 0x60, 0x58, 0x4D, 0x77, 0x78, 0xFF, 0xFF, 0xE0, 0x03, 0x25, 0x60, 0x2C, 0x61, 0xA1, 0xD3,
+	 0xFF, 0xFF, 0x03, 0x1B, 0x00, 0x60, 0xA0, 0x64, 0x02, 0x00, 0x00, 0x60, 0xC0, 0x64, 0x2A, 0xFA,
+	 0xAB, 0xFC, 0x66, 0x45, 0x29, 0x44, 0x07, 0xFA, 0x29, 0x46, 0x03, 0xF2, 0x04, 0xF0, 0x85, 0xF2,
+	 0x65, 0x46, 0x2C, 0xFA, 0x2D, 0xF8, 0xAE, 0xFA, 0xCB, 0xF3, 0x2F, 0xFA, 0x32, 0xFA, 0xCC, 0xF3,
+	 0x30, 0xFA, 0x33, 0xFA, 0xCD, 0xF3, 0x31, 0xFA, 0x34, 0xFA, 0xAC, 0xF1, 0x19, 0xF8, 0x18, 0x67,
+	 0x0E, 0xFA, 0x66, 0x45, 0x63, 0x46, 0x0E, 0xF2, 0x65, 0x46, 0x00, 0x7E, 0x13, 0xFA, 0x02, 0x63,
+	 0x3F, 0xFC, 0x00, 0x64, 0x3E, 0xFA, 0x66, 0x41, 0x00, 0xF4, 0x25, 0x60, 0x28, 0x62, 0xA2, 0xD3,
+	 0xFF, 0xFF, 0x09, 0xFA, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0x9A, 0x64, 0xA2, 0xDB, 0x61, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC8, 0xFE, 0x9E, 0x01, 0x92, 0x01,
+	 0x0F, 0x60, 0xE8, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x5A, 0xDB, 0x2F, 0x58, 0xFF, 0xFF, 0x07, 0xF0,
+	 0xFF, 0xFF, 0x64, 0x43, 0x14, 0x60, 0xD0, 0x62, 0xA2, 0xD3, 0xDA, 0x81, 0x60, 0x45, 0xD5, 0x80,
+	 0xA1, 0xD1, 0x04, 0x03, 0xD3, 0x80, 0xD9, 0x81, 0xFA, 0x02, 0x09, 0x00, 0xA1, 0xDD, 0x14, 0x60,
+	 0xD0, 0x62, 0xD9, 0x84, 0xA2, 0xDB, 0x4A, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xA2, 0xDB, 0x66, 0x45,
+	 0x63, 0x46, 0x06, 0xF2, 0xFF, 0x60, 0x01, 0x7C, 0xA0, 0x9C, 0x06, 0xF8, 0x65, 0x46, 0x71, 0xF3,
+	 0x60, 0x40, 0x10, 0x2A, 0x03, 0x00, 0xCC, 0x84, 0x80, 0x2B, 0x71, 0xFB, 0x0F, 0x60, 0xE8, 0x62,
+	 0xA2, 0xD1, 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x0F, 0x60, 0xDC, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x0F, 0x60, 0xDE, 0x62, 0x00, 0x60, 0x02, 0x64,
+	 0xA2, 0xDB, 0xDB, 0x60, 0xF7, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x71, 0xF3,
+	 0x72, 0xF3, 0x00, 0xA8, 0x60, 0x88, 0x50, 0x03, 0xE0, 0x83, 0x6C, 0x03, 0xCB, 0x83, 0x88, 0xF3,
+	 0x73, 0xF1, 0x02, 0xA4, 0x40, 0x47, 0x64, 0x45, 0x27, 0x46, 0x72, 0xF4, 0x12, 0xF2, 0x40, 0x18,
+	 0xD4, 0x80, 0x02, 0x64, 0x3D, 0x07, 0x23, 0xFA, 0x2A, 0xF2, 0x0E, 0xF2, 0x0C, 0xB0, 0x02, 0xF0,
+	 0x0D, 0x02, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0x8E, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0xE6, 0x01, 0x60, 0x40, 0xF0, 0x37,
+	 0x08, 0x00, 0x09, 0x60, 0x08, 0x64, 0xD0, 0x80, 0xA2, 0xFF, 0x90, 0xF3, 0x02, 0x02, 0xDC, 0x84,
+	 0x90, 0xFB, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0xAC, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xA3, 0xFF, 0xCE, 0xFE, 0x98, 0xF1, 0x1E, 0x60,
+	 0xEC, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB,
+	 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0xBC, 0x01,
+	 0x27, 0x44, 0x02, 0xA4, 0x40, 0x47, 0xB8, 0x1F, 0x28, 0x43, 0xCB, 0x83, 0x88, 0xF3, 0x1A, 0x0E,
+	 0x02, 0xA4, 0x40, 0x4C, 0x43, 0x48, 0x2C, 0x46, 0x1E, 0xF2, 0x73, 0xF1, 0xAC, 0x86, 0x12, 0xF2,
+	 0x0C, 0x03, 0xD0, 0x80, 0xFF, 0xFF, 0x09, 0x07, 0x1B, 0x60, 0xDA, 0x64, 0x40, 0x4B, 0xF0, 0x60,
+	 0x58, 0x4D, 0x75, 0x78, 0xFF, 0xFF, 0x2C, 0x46, 0x9E, 0xFC, 0x2C, 0x44, 0x02, 0xA4, 0x28, 0x43,
+	 0x40, 0x4C, 0xE8, 0x1F, 0x7D, 0x01, 0x01, 0x63, 0x66, 0xF3, 0xAC, 0xF3, 0x00, 0xBD, 0xAC, 0x81,
+	 0x06, 0x03, 0x05, 0x03, 0xB5, 0x60, 0x58, 0x4D, 0xC1, 0x78, 0xFF, 0xFF, 0x60, 0x43, 0x5B, 0xFD,
+	 0x3E, 0x63, 0x16, 0x60, 0x60, 0x61, 0x00, 0x64, 0x59, 0xDB, 0xFE, 0x1F, 0x71, 0xFB, 0x72, 0xFB,
+	 0x16, 0x60, 0xA8, 0x65, 0x00, 0x64, 0xA5, 0xDB, 0x5A, 0xDB, 0x2F, 0x58, 0xFF, 0xFF, 0x1B, 0x60,
+	 0x9A, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x03, 0x02, 0xC7, 0x60, 0x2E, 0x78,
+	 0xFF, 0xFF, 0x07, 0xF0, 0x66, 0x45, 0x64, 0x46, 0x1B, 0xF2, 0x65, 0x46, 0x64, 0x45, 0x5B, 0xF1,
+	 0xE0, 0x84, 0x73, 0xF1, 0xC0, 0x84, 0xC0, 0x84, 0x12, 0xFA, 0x2C, 0xF2, 0x71, 0xF3, 0x60, 0x40,
+	 0x01, 0x2A, 0x36, 0x00, 0x00, 0xA8, 0x1F, 0x60, 0x8E, 0x62, 0xA2, 0xD3, 0x37, 0x03, 0x00, 0xA8,
+	 0xFF, 0xFF, 0x34, 0x03, 0xDE, 0x60, 0x58, 0x4D, 0x6B, 0x78, 0xFF, 0xFF, 0x25, 0x46, 0x09, 0x60,
+	 0x08, 0x61, 0xA2, 0xFF, 0x0E, 0xF2, 0x02, 0xF0, 0x60, 0x40, 0xF0, 0x37, 0x0D, 0x00, 0x92, 0xF3,
+	 0x90, 0xF3, 0xDC, 0x83, 0xD1, 0x80, 0x92, 0xFD, 0x0C, 0x03, 0x8C, 0xF3, 0xCC, 0x83, 0xD8, 0xA0,
+	 0x90, 0xFD, 0x07, 0x04, 0xD4, 0xFE, 0x05, 0x00, 0xD1, 0x80, 0x93, 0xF3, 0x02, 0x03, 0xDC, 0x84,
+	 0x93, 0xFB, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0x94, 0x64, 0xA2, 0xDB, 0x25, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xA3, 0xFF, 0xDC, 0x60, 0x87, 0x78, 0xFF, 0xFF,
+	 0x66, 0x41, 0x65, 0x46, 0x06, 0xF2, 0x61, 0x46, 0x60, 0x40, 0x10, 0x2A, 0x4C, 0x00, 0x80, 0x67,
+	 0xB4, 0x81, 0x1B, 0x60, 0xDA, 0x62, 0x61, 0x44, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xDE, 0x60, 0x58, 0x4D, 0x6B, 0x78, 0xFF, 0xFF, 0x25, 0x46,
+	 0x2A, 0xF2, 0x09, 0x60, 0x08, 0x61, 0x0C, 0xB0, 0xA2, 0xFF, 0x17, 0x03, 0x0E, 0xF2, 0x02, 0xF0,
+	 0x60, 0x40, 0xF0, 0x37, 0x0D, 0x00, 0x90, 0xF3, 0x92, 0xF3, 0xCC, 0x83, 0xD1, 0x80, 0x90, 0xFD,
+	 0x0C, 0x03, 0x8C, 0xF3, 0xDC, 0x83, 0xD8, 0xA0, 0x92, 0xFD, 0x07, 0x04, 0xD4, 0xFE, 0x05, 0x00,
+	 0xD1, 0x80, 0x93, 0xF3, 0x02, 0x03, 0xDC, 0x84, 0x93, 0xFB, 0x07, 0xF0, 0x0A, 0xF2, 0xA3, 0xFF,
+	 0x64, 0x45, 0x30, 0x1B, 0x66, 0x41, 0x65, 0x46, 0x02, 0xF0, 0x61, 0x46, 0x0F, 0x60, 0xFF, 0x61,
+	 0xA1, 0x84, 0x60, 0x41, 0xE9, 0x81, 0xE9, 0x81, 0xE9, 0x81, 0xE1, 0x82, 0x07, 0xB4, 0x01, 0x61,
+	 0x03, 0x03, 0xCC, 0x84, 0xE1, 0x81, 0xFD, 0x02, 0x16, 0x60, 0x62, 0x65, 0x46, 0xD1, 0x61, 0x44,
+	 0xB0, 0x84, 0xA2, 0xDB, 0x17, 0x00, 0x1B, 0x60, 0x8E, 0x61, 0x2A, 0xF2, 0x3E, 0xF2, 0x0C, 0xB0,
+	 0x01, 0xB0, 0x05, 0x03, 0x1B, 0x60, 0xA0, 0x61, 0x02, 0x02, 0x1B, 0x60, 0x88, 0x61, 0x1B, 0x60,
+	 0xDA, 0x62, 0x61, 0x44, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0xC1, 0xFE, 0xDC, 0x60, 0x87, 0x78, 0xFF, 0xFF, 0x07, 0xF0, 0x2B, 0xF2, 0x2A, 0xF2,
+	 0x60, 0x41, 0x44, 0x49, 0x60, 0x45, 0xA4, 0x3A, 0x0D, 0x00, 0x61, 0x40, 0xC0, 0x3B, 0x7B, 0x00,
+	 0xA9, 0x46, 0x06, 0xF2, 0xA9, 0x46, 0x60, 0x40, 0x20, 0x26, 0x75, 0x00, 0x20, 0xBC, 0xA9, 0x46,
+	 0x06, 0xFA, 0xA9, 0x46, 0xA9, 0x46, 0x06, 0xF0, 0xA9, 0x46, 0x65, 0x40, 0x10, 0x2B, 0x6E, 0x00,
+	 0x64, 0x40, 0x10, 0x2A, 0x36, 0x00, 0x65, 0x40, 0xA4, 0x3A, 0x65, 0x00, 0x29, 0x45, 0x65, 0x46,
+	 0x72, 0xF2, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x04, 0x02, 0x78, 0x00, 0xDE, 0x60, 0x51, 0x78,
+	 0xFF, 0xFF, 0x09, 0xF2, 0x2A, 0xF0, 0x00, 0xA8, 0x20, 0x67, 0x02, 0x03, 0xB0, 0x84, 0x2A, 0xFA,
+	 0x0E, 0xF2, 0x02, 0xF0, 0x60, 0x40, 0xF0, 0x37, 0x08, 0x00, 0x09, 0x60, 0x08, 0x64, 0xD0, 0x80,
+	 0xA2, 0xFF, 0x90, 0xF3, 0x02, 0x02, 0xDC, 0x84, 0x90, 0xFB, 0x3E, 0xF2, 0xA3, 0xFF, 0x01, 0xB0,
+	 0x1B, 0x60, 0xA0, 0x61, 0x02, 0x02, 0x1B, 0x60, 0x8E, 0x61, 0x1B, 0x60, 0xDA, 0x62, 0x61, 0x44,
+	 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE,
+	 0x17, 0x00, 0x10, 0x64, 0xB0, 0x84, 0xDF, 0x65, 0xA4, 0x9E, 0xA9, 0x46, 0x06, 0xFA, 0xA9, 0x46,
+	 0xA2, 0xFF, 0x16, 0x60, 0xA8, 0x62, 0x04, 0x64, 0xA2, 0xDB, 0x29, 0x44, 0x5A, 0xDB, 0x71, 0xF3,
+	 0xC1, 0xFE, 0xD4, 0xFE, 0x87, 0xF1, 0xA3, 0xFF, 0xD0, 0x80, 0xDC, 0x84, 0x01, 0x07, 0x71, 0xFB,
+	 0xA9, 0x46, 0x72, 0xF2, 0xA9, 0x46, 0x65, 0x18, 0xA9, 0x46, 0x02, 0xF0, 0xA9, 0x46, 0x0F, 0x60,
+	 0xFF, 0x61, 0xA1, 0x84, 0x60, 0x41, 0xE9, 0x81, 0xE9, 0x81, 0xE9, 0x81, 0xE1, 0x82, 0x07, 0xB4,
+	 0x01, 0x61, 0x03, 0x03, 0xCC, 0x84, 0xE1, 0x81, 0xFD, 0x02, 0x16, 0x60, 0x62, 0x65, 0x46, 0xD1,
+	 0xFF, 0xFF, 0xB1, 0x84, 0xA2, 0xDB, 0xDE, 0x60, 0x68, 0x78, 0xFF, 0xFF, 0x64, 0x40, 0x10, 0x2A,
+	 0xFA, 0x01, 0xFF, 0x60, 0xEF, 0x64, 0xA0, 0x84, 0xA9, 0x46, 0x06, 0xFA, 0xA9, 0x46, 0x65, 0x41,
+	 0x71, 0xF3, 0x29, 0x45, 0xCC, 0x84, 0x80, 0x2B, 0x71, 0xFB, 0x65, 0x46, 0x72, 0xF2, 0xFF, 0xFF,
+	 0x00, 0xA8, 0x60, 0x46, 0x37, 0x02, 0x61, 0x40, 0xA4, 0x3A, 0xE5, 0x01, 0x00, 0x60, 0x3A, 0x61,
+	 0xB3, 0x60, 0x58, 0x4D, 0x77, 0x78, 0xFF, 0xFF, 0x81, 0x03, 0x02, 0x60, 0x48, 0x64, 0x2A, 0xFA,
+	 0xCB, 0xF1, 0x2F, 0xF8, 0xCC, 0xF1, 0x30, 0xF8, 0xCD, 0xF1, 0x31, 0xF8, 0x67, 0xF1, 0x32, 0xF8,
+	 0x68, 0xF1, 0x33, 0xF8, 0x69, 0xF1, 0x34, 0xF8, 0xA9, 0x46, 0x03, 0xF2, 0x04, 0xF0, 0x85, 0xF0,
+	 0xA9, 0x46, 0x2C, 0xFA, 0x2D, 0xF8, 0xAE, 0xF8, 0xAC, 0xF1, 0x19, 0xF8, 0xFF, 0x67, 0x0E, 0xFA,
+	 0x00, 0x64, 0x3E, 0xFA, 0x3F, 0xFA, 0x29, 0x44, 0x07, 0xFA, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60,
+	 0x8E, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0xC1, 0xFE, 0x37, 0x00, 0x80, 0x67, 0xB4, 0x83, 0x2A, 0xF2, 0x09, 0x60, 0x08, 0x65, 0x0C, 0xB0,
+	 0x09, 0xF0, 0x0D, 0x02, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0x8E, 0x64, 0xA2, 0xDB, 0x66, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x9D, 0x18, 0x64, 0x46, 0x3E, 0xF2,
+	 0xA2, 0xFF, 0x01, 0xB0, 0x1B, 0x60, 0xA0, 0x61, 0x02, 0x02, 0x1B, 0x60, 0x88, 0x61, 0x02, 0xF2,
+	 0x0E, 0xF0, 0xD4, 0x80, 0x09, 0xF4, 0x06, 0x02, 0x90, 0xF3, 0x64, 0x40, 0xF0, 0x37, 0x02, 0x00,
+	 0xDC, 0x84, 0x90, 0xFB, 0x66, 0x44, 0x00, 0xA8, 0xFF, 0xFF, 0xF1, 0x02, 0x1B, 0x60, 0xDA, 0x62,
+	 0x61, 0x44, 0xA2, 0xDB, 0x5A, 0xDD, 0x08, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE,
+	 0xA3, 0xFF, 0xA9, 0x46, 0x02, 0xF0, 0xA9, 0x46, 0x0F, 0x60, 0xFF, 0x61, 0xA1, 0x84, 0x60, 0x41,
+	 0xE9, 0x81, 0xE9, 0x81, 0xE9, 0x81, 0xE1, 0x82, 0x07, 0xB4, 0x01, 0x61, 0x03, 0x03, 0xCC, 0x84,
+	 0xE1, 0x81, 0xFD, 0x02, 0x16, 0x60, 0x62, 0x65, 0x46, 0xD3, 0x9D, 0x85, 0xA4, 0x84, 0xA2, 0xDB,
+	 0x26, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x46, 0x45, 0x3F, 0xF2, 0x05, 0x48, 0x00, 0xA8, 0x60, 0x41,
+	 0x66, 0x44, 0x0B, 0x03, 0x0E, 0xA1, 0x00, 0xF2, 0x42, 0xFE, 0xAC, 0x86, 0x01, 0xF2, 0x1F, 0x03,
+	 0x7F, 0xB5, 0xD5, 0x81, 0x66, 0x44, 0xF7, 0x07, 0x25, 0x46, 0x05, 0xF0, 0x06, 0xFA, 0x05, 0xFA,
+	 0xD0, 0x80, 0x64, 0x43, 0x13, 0x03, 0x60, 0x46, 0x01, 0xF0, 0x80, 0x67, 0xB0, 0x84, 0x01, 0xFA,
+	 0x00, 0xF0, 0x00, 0x64, 0x00, 0xFA, 0x44, 0x45, 0xA2, 0xFF, 0xB4, 0x60, 0x58, 0x4E, 0x48, 0x78,
+	 0xFF, 0xFF, 0xA3, 0xFF, 0x08, 0x45, 0x25, 0x46, 0x01, 0x64, 0x02, 0xFA, 0x02, 0xFE, 0x2D, 0x58,
+	 0xFF, 0xFF, 0x23, 0xF2, 0x07, 0xF0, 0x10, 0xB0, 0x10, 0xAC, 0x3B, 0x03, 0x23, 0xFA, 0x80, 0x67,
+	 0xB0, 0x81, 0x1B, 0x60, 0xDA, 0x62, 0x61, 0x44, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x04, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x46, 0x45, 0x64, 0x46, 0x02, 0xF0, 0x0F, 0x60, 0xFF, 0x61,
+	 0xA1, 0x84, 0x60, 0x41, 0xE9, 0x81, 0xE9, 0x81, 0xE9, 0x81, 0xE1, 0x82, 0x07, 0xB4, 0x01, 0x61,
+	 0x03, 0x03, 0xCC, 0x84, 0xE1, 0x81, 0xFD, 0x02, 0x16, 0x60, 0x62, 0x65, 0x46, 0xD1, 0xFF, 0xFF,
+	 0xB1, 0x84, 0xA2, 0xDB, 0x9B, 0xF2, 0x25, 0x46, 0xE1, 0x81, 0x5B, 0xF1, 0x73, 0xF1, 0xC1, 0x81,
+	 0xC1, 0x81, 0x92, 0xFA, 0xA2, 0xFF, 0x02, 0xF0, 0x09, 0x60, 0x08, 0x61, 0xD1, 0x80, 0x0E, 0xF2,
+	 0x05, 0x02, 0x90, 0xF3, 0x20, 0xB0, 0xCC, 0x84, 0x01, 0x02, 0x90, 0xFB, 0xA3, 0xFF, 0x48, 0xFE,
+	 0x07, 0x00, 0x0E, 0xF2, 0x08, 0xFE, 0xF0, 0x7F, 0x60, 0x40, 0x20, 0x2A, 0x00, 0x7F, 0x0E, 0xFA,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x60, 0xA0, 0x61, 0xB3, 0x60, 0x58, 0x4D, 0x77, 0x78, 0xFF, 0xFF,
+	 0x66, 0x44, 0x57, 0xFB, 0x04, 0x64, 0x03, 0xFA, 0x80, 0x64, 0x2A, 0xFA, 0xAC, 0xF1, 0x19, 0xF8,
+	 0x00, 0x64, 0x3E, 0xFA, 0x00, 0x60, 0x80, 0x64, 0x0E, 0xFA, 0x88, 0xF1, 0x07, 0xF8, 0x67, 0x44,
+	 0x2C, 0xFA, 0x2D, 0xFA, 0x2E, 0xFA, 0x0F, 0x60, 0xF6, 0x62, 0xE1, 0x60, 0x9E, 0x64, 0xA2, 0xDB,
+	 0x10, 0x60, 0x02, 0x62, 0xE0, 0x60, 0x0D, 0x64, 0xA2, 0xDB, 0x16, 0x60, 0xB2, 0x63, 0x65, 0x44,
+	 0xBD, 0xDB, 0x10, 0x60, 0x04, 0x64, 0xBD, 0xDB, 0x02, 0x64, 0xBD, 0xDB, 0x06, 0x64, 0xA3, 0xDB,
+	 0xE6, 0x60, 0x5A, 0x78, 0xFF, 0xFF, 0xE6, 0x60, 0x58, 0x4D, 0x66, 0x78, 0xFF, 0xFF, 0x57, 0xF5,
+	 0xCB, 0xF1, 0x2F, 0xF8, 0xCC, 0xF1, 0x30, 0xF8, 0xCD, 0xF1, 0x31, 0xF8, 0x67, 0xF1, 0x32, 0xF8,
+	 0x68, 0xF1, 0x33, 0xF8, 0x69, 0xF1, 0x34, 0xF8, 0x1F, 0x60, 0x92, 0x62, 0xA2, 0xD1, 0x01, 0x64,
+	 0x64, 0x40, 0xFE, 0x26, 0x10, 0xBC, 0x32, 0x40, 0x10, 0x26, 0x10, 0xBC, 0x23, 0x60, 0x4C, 0x62,
+	 0xA2, 0xDB, 0x1F, 0x60, 0x90, 0x62, 0xA2, 0xD1, 0x1F, 0x60, 0x1E, 0x64, 0x02, 0x18, 0x1F, 0x60,
+	 0x40, 0x64, 0x22, 0x60, 0xA2, 0x62, 0xA2, 0xDB, 0x22, 0x60, 0xBE, 0x62, 0xA2, 0xDB, 0x21, 0x60,
+	 0xC6, 0x61, 0x20, 0x60, 0x32, 0x62, 0xA2, 0xD3, 0x22, 0x60, 0x82, 0x65, 0xFE, 0xA4, 0xE0, 0x84,
+	 0x02, 0x05, 0x67, 0x44, 0x99, 0x00, 0xE0, 0x84, 0xC4, 0x85, 0x21, 0x60, 0xEC, 0x62, 0xA2, 0xD3,
+	 0xA5, 0xD1, 0xDA, 0x85, 0x21, 0x60, 0xE4, 0x62, 0xA0, 0x83, 0xA2, 0xDD, 0xA5, 0xD1, 0x21, 0x60,
+	 0xE2, 0x62, 0xA0, 0x83, 0xA2, 0xDD, 0x21, 0x60, 0xC0, 0x61, 0xDD, 0x60, 0x06, 0x64, 0xA1, 0xDB,
+	 0x06, 0xA1, 0x21, 0x60, 0xEA, 0x62, 0xA2, 0xD3, 0x21, 0x60, 0xE2, 0x62, 0x60, 0x40, 0xFD, 0xA0,
+	 0xA2, 0xD3, 0x74, 0x03, 0x50, 0x60, 0x00, 0x7C, 0x60, 0x40, 0x02, 0x2A, 0x03, 0x00, 0x01, 0x60,
+	 0xF2, 0x63, 0x0E, 0x00, 0x04, 0x2A, 0x03, 0x00, 0x02, 0x60, 0xF2, 0x63, 0x09, 0x00, 0x10, 0x2A,
+	 0x03, 0x00, 0x04, 0x60, 0xF2, 0x63, 0x04, 0x00, 0x20, 0x2A, 0x04, 0x00, 0x05, 0x60, 0xF2, 0x63,
+	 0x59, 0xD9, 0x59, 0xDD, 0x21, 0x60, 0xEA, 0x62, 0xA2, 0xD3, 0x21, 0x60, 0xE4, 0x62, 0xFE, 0xA0,
+	 0xA2, 0xD3, 0x54, 0x03, 0x00, 0x60, 0x00, 0x63, 0x59, 0xDD, 0x61, 0x45, 0x60, 0x40, 0x01, 0x2A,
+	 0x04, 0x00, 0x00, 0x60, 0xF2, 0x63, 0x59, 0xD9, 0x59, 0xDD, 0x60, 0x40, 0x02, 0x2A, 0x04, 0x00,
+	 0x01, 0x60, 0xF2, 0x63, 0x59, 0xD9, 0x59, 0xDD, 0x60, 0x40, 0x04, 0x2A, 0x04, 0x00, 0x02, 0x60,
+	 0xF2, 0x63, 0x59, 0xD9, 0x59, 0xDD, 0x60, 0x40, 0x10, 0x2A, 0x04, 0x00, 0x04, 0x60, 0xF2, 0x63,
+	 0x59, 0xD9, 0x59, 0xDD, 0x60, 0x40, 0x20, 0x2A, 0x04, 0x00, 0x05, 0x60, 0xF2, 0x63, 0x59, 0xD9,
+	 0x59, 0xDD, 0xD5, 0x83, 0xEB, 0x83, 0xEB, 0x83, 0xA5, 0xDD, 0x21, 0x60, 0xEA, 0x62, 0xA2, 0xD3,
+	 0x21, 0x60, 0xE6, 0x62, 0xFF, 0xA0, 0xA2, 0xD3, 0x21, 0x03, 0x00, 0x60, 0x00, 0x63, 0x59, 0xDD,
+	 0x61, 0x45, 0x60, 0x40, 0x01, 0x2A, 0x04, 0x00, 0x00, 0x60, 0xF2, 0x63, 0x59, 0xD9, 0x59, 0xDD,
+	 0x60, 0x40, 0x02, 0x2A, 0x04, 0x00, 0x01, 0x60, 0xF2, 0x63, 0x59, 0xD9, 0x59, 0xDD, 0x60, 0x40,
+	 0x04, 0x2A, 0x04, 0x00, 0x02, 0x60, 0xF2, 0x63, 0x59, 0xD9, 0x59, 0xDD, 0xD5, 0x83, 0xEB, 0x83,
+	 0xEB, 0x83, 0xA5, 0xDD, 0x21, 0x60, 0xE8, 0x62, 0xA2, 0xD1, 0x59, 0xD9, 0x21, 0x60, 0xC0, 0x65,
+	 0xD5, 0x84, 0xDD, 0x7F, 0xA5, 0xDB, 0x65, 0x44, 0x22, 0x60, 0xAC, 0x62, 0xA2, 0xDB, 0x22, 0x60,
+	 0xC8, 0x62, 0xA2, 0xDB, 0x57, 0xF5, 0xCB, 0xF3, 0xCC, 0xF1, 0x00, 0x63, 0xC0, 0x87, 0xCD, 0xF1,
+	 0x5A, 0xFD, 0xC0, 0x85, 0x65, 0x47, 0xC4, 0x84, 0x07, 0xB5, 0x1C, 0x60, 0x10, 0x62, 0x16, 0x60,
+	 0xAE, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x0F, 0x60, 0xD0, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x0F, 0x60, 0xD2, 0x62, 0x00, 0x60, 0x02, 0x64, 0xA2, 0xDB, 0xE0, 0x60,
+	 0x17, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1,
+	 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60,
+	 0xD0, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x57, 0xF5, 0x00, 0x64, 0x95, 0xFB, 0x96, 0xFB, 0x97, 0xFB,
+	 0x75, 0xFB, 0x66, 0xF3, 0x00, 0x75, 0x00, 0x72, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x93, 0xC7, 0xF3,
+	 0xED, 0xE2, 0xCC, 0x84, 0x5A, 0xFB, 0x0F, 0x60, 0xD2, 0x62, 0x00, 0x60, 0x04, 0x64, 0xA2, 0xDB,
+	 0xE0, 0x60, 0x36, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xD0, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x65, 0xF1, 0x23, 0x60, 0x02, 0x62, 0xA2, 0xD9, 0x22, 0x60, 0xAA, 0x65,
+	 0xE2, 0x60, 0x58, 0x4D, 0x2F, 0x78, 0xFF, 0xFF, 0xE1, 0x60, 0x58, 0x4D, 0xA8, 0x78, 0xFF, 0xFF,
+	 0xE2, 0x60, 0x58, 0x4D, 0x49, 0x78, 0xFF, 0xFF, 0x57, 0xF5, 0x00, 0xF4, 0x66, 0xF1, 0x06, 0xF8,
+	 0x23, 0x60, 0x4C, 0x62, 0xA2, 0xD3, 0x07, 0xFA, 0x22, 0x60, 0xA2, 0x64, 0x40, 0x48, 0x10, 0x61,
+	 0x00, 0x60, 0x00, 0x64, 0xE1, 0x60, 0x58, 0x4D, 0xE5, 0x78, 0xFF, 0xFF, 0x57, 0xF5, 0x3F, 0xFC,
+	 0x5A, 0xF3, 0xC7, 0xF1, 0xAC, 0x83, 0x01, 0x64, 0x02, 0x02, 0x6C, 0xFB, 0x64, 0x43, 0x1B, 0x60,
+	 0xDA, 0x62, 0x1B, 0x60, 0x8E, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x04, 0x64, 0x5A, 0xDB,
+	 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0xCF, 0x83, 0x73, 0xF3, 0x5A, 0xFD, 0xDC, 0x84, 0x73, 0xFB,
+	 0x5C, 0xF3, 0xFF, 0xFF, 0xCC, 0x84, 0x5C, 0xFB, 0x03, 0x03, 0xE1, 0x60, 0x0A, 0x78, 0xFF, 0xFF,
+	 0x0A, 0x64, 0x5C, 0xFB, 0xA2, 0x4C, 0x20, 0x27, 0xF8, 0x01, 0x46, 0x60, 0x50, 0x65, 0x72, 0x44,
+	 0xD4, 0x80, 0xFF, 0xFF, 0xF2, 0x04, 0x5D, 0xFB, 0x40, 0x48, 0x95, 0xF3, 0x5E, 0xFB, 0x40, 0x4A,
+	 0x96, 0xF3, 0x97, 0xF3, 0x40, 0x4C, 0x60, 0x41, 0x66, 0xF1, 0x40, 0x63, 0xAD, 0x80, 0xF0, 0xA3,
+	 0x09, 0x02, 0x3C, 0x03, 0x2C, 0x41, 0x2A, 0x44, 0x40, 0x4C, 0x28, 0x44, 0x40, 0x4A, 0x00, 0x64,
+	 0x40, 0x48, 0xF4, 0x01, 0xD1, 0x80, 0x01, 0x02, 0x31, 0x04, 0x10, 0xA3, 0x80, 0x60, 0x00, 0x65,
+	 0xA5, 0x80, 0xCF, 0x83, 0x08, 0x02, 0x28, 0x44, 0x60, 0x88, 0x2A, 0x44, 0x70, 0x8A, 0x2C, 0x44,
+	 0x70, 0x8C, 0xF1, 0x81, 0xF5, 0x01, 0xE7, 0xA3, 0x64, 0x44, 0x00, 0xA0, 0x00, 0x62, 0x02, 0x02,
+	 0x00, 0x61, 0x1C, 0x00, 0xE0, 0x84, 0xDE, 0x82, 0xFD, 0x04, 0x42, 0xFE, 0xF8, 0x84, 0x62, 0x45,
+	 0xC7, 0x83, 0x60, 0x45, 0x02, 0xFE, 0xD5, 0x84, 0x02, 0x05, 0x01, 0x05, 0x61, 0x44, 0xCF, 0x83,
+	 0x60, 0x41, 0x08, 0x03, 0x28, 0x44, 0x60, 0x88, 0x2A, 0x44, 0x70, 0x8A, 0x2C, 0x44, 0x70, 0x8C,
+	 0xF1, 0x81, 0xF1, 0x01, 0xCE, 0x82, 0xE9, 0x81, 0xFD, 0x02, 0xF1, 0x81, 0x61, 0x44, 0x00, 0xA8,
+	 0xFF, 0xFF, 0x30, 0x03, 0x73, 0x40, 0x5D, 0xF3, 0xFF, 0xFF, 0x60, 0x47, 0xE8, 0x84, 0xE8, 0x84,
+	 0x5E, 0xF3, 0x3F, 0xB5, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84,
+	 0xB4, 0x84, 0x61, 0x45, 0xD4, 0x84, 0xC0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x81,
+	 0x64, 0x44, 0x73, 0x45, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xC4, 0x85, 0x61, 0x44, 0xD4, 0x80,
+	 0xFF, 0xFF, 0x10, 0x03, 0x60, 0x53, 0xD4, 0x84, 0xFF, 0xFF, 0x75, 0xF3, 0xFF, 0xFF, 0xDC, 0x84,
+	 0x01, 0xB4, 0x75, 0xFB, 0x1F, 0x60, 0x14, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xFF, 0xFF,
+	 0x08, 0x28, 0xA2, 0xDB, 0xE6, 0x60, 0xA3, 0x78, 0xFF, 0xFF, 0xC1, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x04, 0x64, 0x03, 0xFA, 0x00, 0xF4, 0x09, 0xF2, 0xFF, 0xFF, 0x60, 0x47, 0x00, 0x3A, 0x1C, 0x00,
+	 0x60, 0x43, 0x00, 0x36, 0x1C, 0x00, 0xE0, 0xA0, 0xDA, 0x85, 0x16, 0x07, 0x1F, 0x60, 0x1E, 0x61,
+	 0xA1, 0xD1, 0xFF, 0xFF, 0xD3, 0x80, 0xCB, 0x83, 0x0F, 0x02, 0x07, 0x0E, 0x59, 0xD3, 0xA5, 0xD0,
+	 0xDA, 0x85, 0xD0, 0x80, 0xFF, 0xFF, 0x08, 0x02, 0xF9, 0x1F, 0x13, 0x1E, 0xA5, 0xD0, 0x59, 0xD3,
+	 0xFF, 0xFF, 0x90, 0x80, 0xFF, 0x22, 0x0D, 0x00, 0xE1, 0x60, 0x9C, 0x78, 0xFF, 0xFF, 0x1F, 0x60,
+	 0x90, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x2A, 0x03, 0x00, 0x1F, 0x60, 0x40, 0x64,
+	 0x02, 0x00, 0x1F, 0x60, 0x1E, 0x64, 0x22, 0x60, 0xBE, 0x62, 0xA2, 0xDB, 0x26, 0x46, 0x2F, 0xF2,
+	 0x2C, 0xFA, 0x30, 0xF2, 0x2D, 0xFA, 0x31, 0xF2, 0x2E, 0xFA, 0xCB, 0xF1, 0x2F, 0xF8, 0xCC, 0xF1,
+	 0x30, 0xF8, 0xCD, 0xF1, 0x31, 0xF8, 0x67, 0xF1, 0x32, 0xF8, 0x68, 0xF1, 0x33, 0xF8, 0x69, 0xF1,
+	 0x34, 0xF8, 0x50, 0x63, 0x2A, 0xFC, 0xAC, 0xF3, 0x19, 0xFA, 0x00, 0x64, 0x3E, 0xFA, 0x88, 0xF3,
+	 0x07, 0xFA, 0x00, 0xF4, 0x66, 0xF1, 0x06, 0xF8, 0x23, 0x60, 0x4C, 0x62, 0xA2, 0xD3, 0x07, 0xFA,
+	 0x22, 0x60, 0xC6, 0x65, 0xE2, 0x60, 0x58, 0x4D, 0x2F, 0x78, 0xFF, 0xFF, 0x22, 0x60, 0xBE, 0x64,
+	 0x40, 0x48, 0x10, 0x61, 0x00, 0x60, 0x00, 0x64, 0xE1, 0x60, 0x58, 0x4D, 0xE5, 0x78, 0xFF, 0xFF,
+	 0x26, 0x46, 0x3F, 0xFC, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0x8E, 0x64, 0xA2, 0xDB, 0x26, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x20, 0x44, 0x80, 0x26,
+	 0x11, 0x00, 0x80, 0xBC, 0x40, 0x40, 0x00, 0x64, 0x95, 0xFB, 0x96, 0xFB, 0x97, 0xFB, 0x75, 0xFB,
+	 0x66, 0xF3, 0x00, 0x75, 0x00, 0x72, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x93, 0xC7, 0xF3, 0xED, 0xE2,
+	 0xCC, 0x84, 0x5A, 0xFB, 0x00, 0x66, 0x46, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xD0, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x5A, 0xDB, 0x00, 0x64, 0x73, 0xFB, 0x75, 0xFB, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x3E, 0x63, 0x16, 0x60, 0x60, 0x61, 0x59, 0xD1, 0x61, 0x46, 0x08, 0x1B, 0xFC, 0x1F, 0x22, 0x60,
+	 0xDE, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x01, 0x65, 0x00, 0x61, 0x17, 0x00, 0x16, 0x60, 0xA2, 0x61,
+	 0x49, 0xD1, 0xCB, 0x83, 0xFD, 0x18, 0x63, 0x41, 0x04, 0xA1, 0x61, 0x45, 0x66, 0x43, 0x22, 0x60,
+	 0xDE, 0x64, 0xDC, 0x84, 0x60, 0xFE, 0xA3, 0xD1, 0xDF, 0x83, 0xA0, 0xD9, 0xCD, 0x81, 0x20, 0xFE,
+	 0xF8, 0x02, 0x66, 0x44, 0x16, 0x60, 0x62, 0x7C, 0xD0, 0x81, 0x5A, 0xF3, 0xC7, 0xF1, 0x22, 0x60,
+	 0xDC, 0x63, 0x00, 0xA0, 0x64, 0x5F, 0xBD, 0xDB, 0x1B, 0x60, 0x94, 0x66, 0xA6, 0xD1, 0x02, 0x02,
+	 0x01, 0x18, 0x01, 0xB9, 0x61, 0x44, 0x60, 0xFE, 0xA3, 0xDB, 0xFC, 0xA3, 0x65, 0x44, 0x03, 0xA4,
+	 0xA3, 0xDB, 0xFF, 0xFF, 0x20, 0xFE, 0x2D, 0x58, 0xFF, 0xFF, 0x23, 0x60, 0x4E, 0x62, 0xA2, 0xDB,
+	 0xCD, 0x81, 0x28, 0xD3, 0x5A, 0x88, 0xDC, 0x83, 0x39, 0x18, 0xFB, 0x03, 0x61, 0x40, 0x7F, 0x3A,
+	 0x07, 0x00, 0x23, 0x60, 0x4E, 0x62, 0xA2, 0xD3, 0x03, 0x61, 0x7C, 0xA4, 0xA2, 0xDB, 0x00, 0xF4,
+	 0x60, 0xFE, 0xA3, 0xD1, 0xDD, 0x81, 0xA1, 0xD8, 0x61, 0x40, 0x7F, 0x3A, 0x09, 0x00, 0x20, 0xFE,
+	 0x23, 0x60, 0x4E, 0x62, 0xA2, 0xD3, 0x03, 0x61, 0x7C, 0xA4, 0xA2, 0xDB, 0x00, 0xF4, 0x60, 0xFE,
+	 0xCF, 0x83, 0xA3, 0xD3, 0xDD, 0x81, 0xA1, 0xDA, 0xFF, 0xB4, 0x00, 0x7F, 0x15, 0x03, 0xDB, 0x83,
+	 0x61, 0x40, 0x7F, 0x3A, 0x0B, 0x00, 0x20, 0xFE, 0x60, 0x45, 0x23, 0x60, 0x4E, 0x62, 0xA2, 0xD3,
+	 0x03, 0x61, 0x7C, 0xA4, 0xA2, 0xDB, 0x65, 0x44, 0x00, 0xF4, 0x60, 0xFE, 0xA3, 0xD1, 0xDF, 0x83,
+	 0xDD, 0x81, 0xCC, 0x84, 0xA1, 0xD8, 0xEC, 0x02, 0x20, 0xFE, 0xC3, 0x01, 0x23, 0x60, 0x4E, 0x62,
+	 0xA2, 0xD1, 0xFD, 0xA1, 0xFF, 0xB1, 0xC1, 0x83, 0xA2, 0xDD, 0x2D, 0x58, 0xFF, 0xFF, 0x67, 0x5C,
+	 0x11, 0x60, 0xF0, 0x61, 0xA1, 0xD3, 0xA5, 0xD9, 0x12, 0x18, 0x60, 0x43, 0x23, 0x60, 0x04, 0x64,
+	 0xA5, 0xDB, 0x60, 0xFE, 0xA0, 0xDD, 0xFF, 0xFF, 0x20, 0xFE, 0xDC, 0x84, 0xCF, 0x83, 0xE3, 0x83,
+	 0x59, 0xD1, 0xDC, 0x84, 0x60, 0xFE, 0xA0, 0xD9, 0xFF, 0xFF, 0x20, 0xFE, 0xF9, 0x1F, 0x2D, 0x58,
+	 0xFF, 0xFF, 0x20, 0x40, 0x20, 0x2A, 0x0D, 0x00, 0x12, 0x60, 0xB8, 0x62, 0xA2, 0xD1, 0x50, 0xF3,
+	 0x23, 0x60, 0x39, 0x63, 0x60, 0xFE, 0xA3, 0xD9, 0xDF, 0x83, 0x60, 0x47, 0xA3, 0xDB, 0xFF, 0xFF,
+	 0x20, 0xFE, 0x2D, 0x58, 0xFF, 0xFF, 0x0E, 0x57, 0x32, 0x40, 0x40, 0x26, 0x25, 0x00, 0x45, 0x48,
+	 0x00, 0x60, 0x10, 0x61, 0xB3, 0x60, 0x58, 0x4D, 0x77, 0x78, 0xFF, 0xFF, 0x1D, 0x03, 0xF2, 0x60,
+	 0x02, 0x64, 0x24, 0xFA, 0x00, 0x60, 0x48, 0x61, 0x28, 0x44, 0x59, 0xDA, 0x03, 0x64, 0x38, 0x43,
+	 0xBD, 0xD1, 0xCC, 0x84, 0x59, 0xD8, 0xFC, 0x02, 0x39, 0x44, 0x59, 0xDA, 0x06, 0x64, 0x23, 0xFA,
+	 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0xCA, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xFA, 0xFE, 0x37, 0x58, 0xFF, 0xFF, 0x0E, 0x57, 0x32, 0x40,
+	 0x40, 0x26, 0x51, 0x00, 0x45, 0x48, 0x00, 0x60, 0x68, 0x61, 0xB3, 0x60, 0x58, 0x4D, 0x77, 0x78,
+	 0xFF, 0xFF, 0x49, 0x03, 0xF2, 0x60, 0x01, 0x64, 0x24, 0xFA, 0x02, 0x60, 0x00, 0x61, 0x46, 0x4A,
+	 0x38, 0x44, 0x54, 0x94, 0x03, 0x64, 0x01, 0x02, 0x09, 0x00, 0x06, 0x63, 0x4A, 0x61, 0x38, 0x46,
+	 0xBD, 0xD0, 0xCC, 0x84, 0x2A, 0x46, 0x59, 0xD8, 0xFA, 0x02, 0x06, 0x00, 0xDA, 0x81, 0x38, 0x43,
+	 0xBD, 0xD1, 0xCC, 0x84, 0x59, 0xD8, 0xFC, 0x02, 0x05, 0x63, 0x28, 0x44, 0x02, 0xA8, 0x25, 0xFA,
+	 0x07, 0x02, 0x03, 0x64, 0x39, 0x43, 0xBD, 0xD1, 0xCC, 0x84, 0x59, 0xD8, 0xFC, 0x02, 0x08, 0x63,
+	 0x22, 0x60, 0x28, 0x7C, 0x28, 0x44, 0x03, 0xA8, 0xA4, 0xD3, 0x0F, 0x03, 0xE8, 0x85, 0xC7, 0x85,
+	 0x60, 0x43, 0xFE, 0xA3, 0x22, 0x60, 0x2A, 0x64, 0x58, 0xD1, 0xD9, 0x81, 0xA1, 0xD8, 0x7E, 0x2A,
+	 0x02, 0x00, 0x00, 0xF4, 0x02, 0x61, 0xF8, 0x1F, 0x65, 0x43, 0x2A, 0x46, 0x23, 0xFC, 0x1B, 0x60,
+	 0xDA, 0x62, 0x1B, 0x60, 0xCA, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB,
+	 0xFF, 0xFF, 0x2B, 0xFF, 0xFA, 0xFE, 0x37, 0x58, 0xFF, 0xFF, 0x0E, 0x57, 0x32, 0x40, 0x40, 0x26,
+	 0x1C, 0x00, 0x45, 0x48, 0x00, 0x60, 0x06, 0x61, 0xB3, 0x60, 0x58, 0x4D, 0x77, 0x78, 0xFF, 0xFF,
+	 0x14, 0x03, 0x02, 0x64, 0x23, 0xFA, 0xF2, 0x60, 0x00, 0x64, 0x5A, 0xDA, 0x28, 0x44, 0x5A, 0xDA,
+	 0xFF, 0xFF, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0xCA, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xFA, 0xFE, 0x37, 0x58, 0xFF, 0xFF, 0xA2, 0xFF,
+	 0x32, 0x40, 0x40, 0x26, 0x3E, 0x00, 0x7C, 0xF3, 0x67, 0x43, 0xDC, 0x84, 0xCC, 0x84, 0x39, 0x03,
+	 0x60, 0x46, 0x0A, 0x02, 0x7C, 0xFD, 0x00, 0x60, 0x46, 0x61, 0xB3, 0x60, 0x58, 0x4D, 0x77, 0x78,
+	 0xFF, 0xFF, 0x66, 0x44, 0x7C, 0xFB, 0x2E, 0x03, 0x46, 0x4B, 0x1E, 0x60, 0xD8, 0x61, 0x18, 0x64,
+	 0x23, 0xFA, 0xF1, 0x60, 0x00, 0x64, 0x24, 0xFA, 0x4A, 0x65, 0xA2, 0xFF, 0x2C, 0x63, 0x00, 0x64,
+	 0x59, 0xD1, 0xA2, 0xDB, 0xA5, 0xD8, 0xDA, 0x85, 0x80, 0x3A, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65,
+	 0xF7, 0x1F, 0x12, 0x63, 0x59, 0xD1, 0xA5, 0xD8, 0xDA, 0x85, 0x80, 0x3A, 0x02, 0x00, 0x00, 0xF4,
+	 0x04, 0x65, 0xF8, 0x1F, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0xCA, 0x64, 0xA2, 0xDB, 0x2B, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xFA, 0xFE, 0xA6, 0xFE, 0x00, 0x64,
+	 0x7C, 0xFB, 0xA3, 0xFF, 0xC7, 0x60, 0x2E, 0x78, 0xFF, 0xFF, 0xA6, 0xFE, 0xB8, 0x05, 0xA7, 0xFE,
+	 0x0A, 0x05, 0xA5, 0xFE, 0x03, 0x04, 0xE3, 0x60, 0xD3, 0x78, 0xFF, 0xFF, 0xA4, 0xFE, 0xF2, 0x04,
+	 0xE4, 0x60, 0x69, 0x78, 0xFF, 0xFF, 0x36, 0x45, 0x17, 0x60, 0x52, 0x64, 0x44, 0xD7, 0xFF, 0xFF,
+	 0xFF, 0xFF, 0x28, 0xF3, 0x7E, 0xF1, 0x60, 0x47, 0x07, 0xB4, 0x4E, 0xFB, 0x01, 0x61, 0x03, 0x03,
+	 0xCC, 0x84, 0xE1, 0x81, 0xFD, 0x02, 0x9D, 0x84, 0xA1, 0x80, 0xA0, 0x83, 0x1A, 0x03, 0x7E, 0xFD,
+	 0x0F, 0x60, 0xF4, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x7E, 0xF1, 0x31, 0x44, 0x64, 0x40, 0xFF, 0x26, 0x09, 0x00, 0xFE, 0xB4, 0x40, 0x51, 0x01, 0x7C,
+	 0xBC, 0xF9, 0x49, 0xF3, 0x01, 0x63, 0x60, 0x40, 0xFF, 0x26, 0x49, 0xFD, 0xC7, 0x60, 0x2E, 0x78,
+	 0xFF, 0xFF, 0xE3, 0x60, 0xD3, 0x78, 0xFF, 0xFF, 0x1F, 0x60, 0xB6, 0x63, 0xBD, 0xD3, 0xBD, 0xD1,
+	 0xBD, 0xD1, 0xB0, 0x84, 0xB0, 0x84, 0xFF, 0xFF, 0x07, 0x02, 0x6B, 0xFB, 0x31, 0x44, 0xFE, 0xB4,
+	 0x40, 0x51, 0x0D, 0x64, 0x05, 0xFB, 0x3F, 0x00, 0x28, 0xF3, 0x7E, 0xF1, 0x60, 0x47, 0x64, 0x41,
+	 0x07, 0xB1, 0x07, 0xB4, 0x08, 0x24, 0x67, 0x4C, 0x4E, 0xFB, 0x01, 0x61, 0x03, 0x03, 0xCC, 0x84,
+	 0xE1, 0x81, 0xFD, 0x02, 0xA1, 0x80, 0xB1, 0x83, 0x2E, 0x02, 0x7E, 0xFD, 0x1F, 0x60, 0xAA, 0x62,
+	 0xA2, 0xD3, 0xC5, 0xFB, 0x65, 0xFB, 0x7E, 0xF3, 0xFF, 0xFF, 0xCC, 0x85, 0xA4, 0x80, 0x7E, 0xFB,
+	 0x17, 0x02, 0x1B, 0x60, 0xC4, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x46, 0x5E,
+	 0x31, 0x44, 0x01, 0xBC, 0x40, 0x51, 0xED, 0xE2, 0x0F, 0x4E, 0xCE, 0x60, 0x58, 0x4F, 0x07, 0x78,
+	 0xFF, 0xFF, 0x0E, 0x4F, 0x01, 0x65, 0xE2, 0x60, 0x58, 0x4E, 0xDD, 0x78, 0xFF, 0xFF, 0x08, 0x00,
+	 0x0F, 0x60, 0xD6, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x10, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0xE5, 0x60, 0x16, 0x78, 0xFF, 0xFF, 0xD7, 0xFE, 0xC7, 0x60, 0x2E, 0x78, 0xFF, 0xFF, 0x2E, 0xF5,
+	 0x27, 0xF2, 0x12, 0x60, 0xCE, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41,
+	 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46, 0x27, 0xF0, 0x63, 0x46, 0xD0, 0x80,
+	 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46, 0x26, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02,
+	 0x61, 0x46, 0x25, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF,
+	 0x63, 0x46, 0xE8, 0x1B, 0x88, 0xF3, 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0x28, 0x02, 0x14, 0x60,
+	 0xD0, 0x62, 0xA2, 0xD3, 0xDA, 0x81, 0x60, 0x45, 0xD5, 0x80, 0xA1, 0xD1, 0x04, 0x03, 0xD3, 0x80,
+	 0xD9, 0x81, 0xFA, 0x02, 0x09, 0x00, 0xA1, 0xDD, 0x14, 0x60, 0xD0, 0x62, 0xD9, 0x84, 0xA2, 0xDB,
+	 0x4A, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xA2, 0xDB, 0x66, 0x45, 0x63, 0x46, 0x06, 0xF2, 0xFF, 0x60,
+	 0x01, 0x7C, 0xA0, 0x9C, 0x06, 0xF8, 0x65, 0x46, 0x71, 0xF3, 0x60, 0x40, 0x10, 0x2A, 0x03, 0x00,
+	 0xCC, 0x84, 0x80, 0x2B, 0x71, 0xFB, 0xE4, 0x60, 0x58, 0x4E, 0x9D, 0x78, 0xFF, 0xFF, 0xAB, 0x01,
+	 0x2E, 0xF5, 0x25, 0x60, 0x28, 0x61, 0x28, 0xF0, 0xFF, 0xFF, 0xA1, 0xD9, 0x27, 0xF2, 0x12, 0x60,
+	 0xCE, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46, 0x60, 0x43,
+	 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46, 0x27, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2, 0x0C, 0x02,
+	 0x61, 0x46, 0x26, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46, 0x25, 0xF0,
+	 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46, 0xE8, 0x1B,
+	 0x88, 0xF3, 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0x13, 0x02, 0x63, 0x46, 0x06, 0xF2, 0xFF, 0xFF,
+	 0x02, 0xB0, 0x08, 0xBC, 0x0D, 0x03, 0x06, 0xFA, 0xE4, 0x60, 0x58, 0x4E, 0x9D, 0x78, 0xFF, 0xFF,
+	 0x0F, 0x60, 0xE8, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x6A, 0x01, 0x7E, 0xF1, 0xFF, 0xFF, 0x64, 0x41, 0x07, 0xB1, 0xFF, 0xFF, 0x08, 0x24, 0x67, 0x4C,
+	 0x1B, 0x60, 0xC4, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x46, 0x5E, 0x1F, 0x60,
+	 0xAA, 0x62, 0xA2, 0xD3, 0xC5, 0xFB, 0x65, 0xFB, 0x1F, 0x60, 0xB6, 0x63, 0xBD, 0xD1, 0xCB, 0xF9,
+	 0x67, 0xF9, 0xBD, 0xD1, 0xCC, 0xF9, 0x68, 0xF9, 0xA3, 0xD1, 0xCD, 0xF9, 0x69, 0xF9, 0x01, 0x64,
+	 0x6B, 0xFB, 0x31, 0x44, 0x21, 0xBC, 0x40, 0x51, 0x20, 0x44, 0x01, 0x65, 0x34, 0x80, 0x01, 0x64,
+	 0x51, 0xFB, 0x21, 0x60, 0x50, 0x64, 0x52, 0xFB, 0x0F, 0x4E, 0xE8, 0x60, 0x58, 0x4F, 0x02, 0x78,
+	 0xFF, 0xFF, 0x0E, 0x4F, 0xC7, 0x60, 0x2E, 0x78, 0xFF, 0xFF, 0x0E, 0x57, 0x63, 0x46, 0x43, 0x47,
+	 0x1E, 0xF2, 0x72, 0xF2, 0x02, 0x1B, 0x01, 0x1B, 0x0C, 0x00, 0x60, 0x46, 0x1B, 0x60, 0xDA, 0x64,
+	 0x40, 0x4B, 0xF0, 0x60, 0x58, 0x4D, 0x75, 0x78, 0xFF, 0xFF, 0x27, 0x46, 0x72, 0xF2, 0xFF, 0xFF,
+	 0xF4, 0x1B, 0x37, 0x58, 0xFF, 0xFF, 0x1B, 0x60, 0xAC, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x00, 0xA8,
+	 0x60, 0x46, 0x0E, 0xF2, 0x5B, 0x03, 0x60, 0x40, 0xF0, 0x37, 0x48, 0x00, 0xFF, 0x37, 0x3D, 0x00,
+	 0xFD, 0x37, 0x35, 0x00, 0x18, 0x37, 0x29, 0x00, 0xFE, 0x37, 0x2C, 0x00, 0xF8, 0x37, 0x0A, 0x00,
+	 0x60, 0x47, 0xFF, 0xB5, 0x0F, 0x60, 0xD0, 0x62, 0x46, 0xD1, 0x00, 0x60, 0x01, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x1B, 0x60, 0xDA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xD6, 0x01, 0x06, 0xB4, 0xFD, 0x7F, 0x0E, 0xFA,
+	 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0xB2, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xF9, 0xFE, 0xC6, 0x01, 0xDB, 0x60, 0x58, 0x4F, 0xB7, 0x78,
+	 0xFF, 0xFF, 0x14, 0x00, 0xDE, 0x60, 0x58, 0x4F, 0x99, 0x78, 0xFF, 0xFF, 0xBC, 0x03, 0x23, 0xF0,
+	 0x60, 0x40, 0x04, 0x26, 0xE2, 0x1B, 0x02, 0x26, 0xE0, 0x18, 0xA2, 0xFF, 0x02, 0xF0, 0x09, 0x60,
+	 0x08, 0x64, 0xD0, 0x80, 0x90, 0xF3, 0x02, 0x02, 0xCC, 0x84, 0x90, 0xFB, 0x1B, 0x60, 0xDA, 0x64,
+	 0x40, 0x4B, 0xF0, 0x60, 0x58, 0x4D, 0x75, 0x78, 0xFF, 0xFF, 0xA5, 0x01, 0xAC, 0xFE, 0x09, 0x05,
+	 0xAD, 0xFE, 0x10, 0x05, 0xAE, 0xFE, 0x9F, 0x05, 0xAF, 0xFE, 0x3A, 0x05, 0xC7, 0x60, 0x2E, 0x78,
+	 0xFF, 0xFF, 0x0F, 0x60, 0xCE, 0x62, 0xA2, 0xD1, 0x20, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xCF, 0xFE, 0xF4, 0x01, 0x10, 0x60, 0x02, 0x65, 0x03, 0x61, 0x07, 0x00, 0xA2, 0xDD, 0x58, 0x4F,
+	 0x64, 0x58, 0xFF, 0xFF, 0x00, 0xB9, 0xFF, 0xFF, 0x08, 0x03, 0x00, 0x63, 0xA5, 0xD1, 0x5A, 0xD3,
+	 0xDA, 0x85, 0x00, 0xA8, 0xCD, 0x81, 0xF2, 0x02, 0xF8, 0x02, 0xE0, 0x01, 0x0F, 0x60, 0xCC, 0x62,
+	 0x0F, 0x60, 0xF2, 0x65, 0xE5, 0x60, 0x4E, 0x63, 0x00, 0x64, 0x5A, 0xDB, 0xD6, 0x80, 0xFF, 0xFF,
+	 0x04, 0x03, 0x5A, 0xDB, 0x5A, 0xDB, 0x5A, 0xDD, 0xF9, 0x01, 0x10, 0x60, 0x00, 0x65, 0x00, 0x64,
+	 0x5A, 0xDB, 0xD6, 0x80, 0xFF, 0xFF, 0x02, 0x03, 0x5A, 0xDD, 0xFB, 0x01, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x0F, 0x60, 0xD0, 0x64, 0x40, 0x41, 0x0F, 0x60, 0xCE, 0x63, 0xA3, 0xD1, 0x00, 0x64, 0xD0, 0x80,
+	 0x06, 0x61, 0x08, 0x03, 0xBD, 0xDB, 0xA3, 0xD3, 0xFF, 0xFF, 0xB0, 0x84, 0xCD, 0x81, 0xA3, 0xDB,
+	 0x06, 0xA3, 0xF9, 0x02, 0x0F, 0x60, 0xF4, 0x63, 0xA3, 0xD1, 0x00, 0x64, 0xD0, 0x80, 0x07, 0x61,
+	 0x19, 0x03, 0xBD, 0xDB, 0x64, 0x44, 0xFE, 0xA3, 0x02, 0xA3, 0xCD, 0x81, 0xE8, 0x84, 0xE3, 0x03,
+	 0x02, 0x05, 0xE1, 0x03, 0xF9, 0x01, 0x78, 0xFB, 0x7A, 0xFD, 0x61, 0x5C, 0xA3, 0xD3, 0x79, 0xF9,
+	 0x03, 0x18, 0x58, 0x4F, 0x60, 0x58, 0xFF, 0xFF, 0x7A, 0xF3, 0x79, 0xF1, 0x60, 0x43, 0x78, 0xF3,
+	 0x64, 0x41, 0xEA, 0x01, 0x21, 0x43, 0x0F, 0x60, 0xF4, 0x65, 0xD7, 0x80, 0xBD, 0xD1, 0xBD, 0xD3,
+	 0x03, 0x02, 0xC7, 0x60, 0x2E, 0x78, 0xFF, 0xFF, 0xA0, 0x84, 0xBD, 0xD1, 0x43, 0x41, 0xF5, 0x03,
+	 0xE5, 0x60, 0x53, 0x64, 0x64, 0x58, 0x40, 0x4F, 0x2A, 0xF0, 0x83, 0x60, 0xFF, 0x65, 0x64, 0x47,
+	 0x03, 0x2B, 0x01, 0x00, 0x17, 0x00, 0x03, 0x26, 0x03, 0xAC, 0x60, 0x47, 0xA4, 0x84, 0x2A, 0xFA,
+	 0x2F, 0xF2, 0x2C, 0xFA, 0x30, 0xF2, 0x2D, 0xFA, 0x31, 0xF2, 0x2E, 0xFA, 0x64, 0x41, 0xCB, 0xF3,
+	 0x2F, 0xFA, 0x60, 0x43, 0xCC, 0xF3, 0x30, 0xFA, 0xCD, 0xF1, 0x31, 0xF8, 0x32, 0xFC, 0x33, 0xFA,
+	 0x34, 0xF8, 0x19, 0x00, 0x60, 0x47, 0xA4, 0x84, 0x2A, 0xFA, 0x2F, 0xF2, 0x2C, 0xFA, 0x30, 0xF2,
+	 0x2D, 0xFA, 0x31, 0xF2, 0x2E, 0xFA, 0x36, 0xF2, 0x32, 0xFA, 0x37, 0xF2, 0x33, 0xFA, 0x38, 0xF2,
+	 0x34, 0xFA, 0xCB, 0xF3, 0x2F, 0xFA, 0x36, 0xFA, 0xCC, 0xF3, 0x30, 0xFA, 0x37, 0xFA, 0xCD, 0xF3,
+	 0x31, 0xFA, 0x38, 0xFA, 0x64, 0x41, 0x1C, 0xF2, 0x13, 0xFA, 0x00, 0xF4, 0x0D, 0xF2, 0xFF, 0xFF,
+	 0x60, 0x40, 0x80, 0x2B, 0x29, 0x00, 0x26, 0x46, 0x04, 0x63, 0x03, 0xFC, 0x00, 0xF4, 0x0D, 0xF2,
+	 0x06, 0xFA, 0xE6, 0x60, 0x58, 0x4E, 0xF4, 0x78, 0xFF, 0xFF, 0xFF, 0xA0, 0x59, 0xF5, 0x1A, 0x02,
+	 0x39, 0xF2, 0x26, 0x46, 0x3F, 0xFA, 0x00, 0xF4, 0x00, 0x60, 0x81, 0x67, 0x0D, 0xFA, 0x7C, 0x64,
+	 0x01, 0xFA, 0x26, 0x46, 0x00, 0x64, 0x3E, 0xFA, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0x9A, 0x64,
+	 0xA2, 0xDB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC8, 0xFE,
+	 0x00, 0x66, 0x46, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x26, 0x46, 0x3F, 0xF0, 0x42, 0x64, 0xD0, 0x80,
+	 0xFF, 0xFF, 0x01, 0x04, 0x3F, 0xFA, 0x1C, 0xF2, 0x13, 0xFA, 0x26, 0xF2, 0x27, 0xF0, 0x60, 0x47,
+	 0x00, 0xF4, 0x1F, 0xFA, 0x64, 0x47, 0x20, 0xFA, 0x61, 0x44, 0x21, 0xFA, 0x01, 0x67, 0x0D, 0xFA,
+	 0x10, 0x61, 0x1F, 0x60, 0x6C, 0x64, 0x1E, 0x63, 0x58, 0xD1, 0xCD, 0x81, 0xBD, 0xD8, 0xFC, 0x02,
+	 0x9B, 0xF1, 0xB8, 0xF1, 0x64, 0x5E, 0x64, 0x5F, 0x44, 0x63, 0xBD, 0xDA, 0x1F, 0x60, 0x66, 0x62,
+	 0xA2, 0xD3, 0xFF, 0xFF, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0x09, 0xBC, 0x4A, 0xD3, 0x60, 0x45,
+	 0x60, 0x40, 0x01, 0x36, 0x03, 0x64, 0x02, 0x36, 0x01, 0x64, 0xB4, 0x84, 0x06, 0xA2, 0xA2, 0xD1,
+	 0xBD, 0xDA, 0x64, 0x47, 0xBD, 0xDA, 0xB5, 0xF3, 0xB6, 0xF1, 0x60, 0x47, 0xBD, 0xDA, 0x64, 0x47,
+	 0xC3, 0xF1, 0xBD, 0xDA, 0x64, 0x44, 0xBD, 0xDA, 0x26, 0x46, 0x00, 0x64, 0x23, 0xF0, 0x3B, 0xF0,
+	 0x64, 0x40, 0x10, 0x2A, 0x06, 0x00, 0xC0, 0x67, 0xA0, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84,
+	 0x10, 0xBC, 0x3E, 0xFA, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0x9A, 0x64, 0xA2, 0xDB, 0x26, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC8, 0xFE, 0x00, 0x66, 0x46, 0x46,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x04, 0x60, 0x5C, 0x61, 0xB3, 0x60, 0x58, 0x4D, 0x77, 0x78, 0xFF, 0xFF,
+	 0x66, 0x44, 0x59, 0xFB, 0x04, 0x64, 0x03, 0xFA, 0x2F, 0x58, 0xFF, 0xFF, 0x59, 0xF5, 0xAC, 0xF1,
+	 0x19, 0xF8, 0x00, 0x64, 0x3E, 0xFA, 0x08, 0x64, 0x2A, 0xFA, 0x80, 0x7E, 0xF8, 0x7F, 0x0E, 0xFA,
+	 0x88, 0xF1, 0x07, 0xF8, 0x01, 0x60, 0x60, 0x67, 0x2C, 0xFA, 0x1D, 0x60, 0x00, 0x67, 0x2D, 0xFA,
+	 0x01, 0x60, 0x00, 0x67, 0x2E, 0xFA, 0xCB, 0xF1, 0x2F, 0xF8, 0x32, 0xF8, 0xCC, 0xF1, 0x30, 0xF8,
+	 0x33, 0xF8, 0xCD, 0xF1, 0x31, 0xF8, 0x34, 0xF8, 0x00, 0x63, 0x3B, 0xFC, 0x3D, 0xFC, 0x01, 0x64,
+	 0x3A, 0xFA, 0x66, 0x64, 0x39, 0xFA, 0x3C, 0xFC, 0xAA, 0x60, 0xAA, 0x64, 0x00, 0xF4, 0x02, 0xFA,
+	 0x00, 0x60, 0x03, 0x64, 0x5A, 0xDA, 0x1D, 0x60, 0x60, 0x64, 0x5A, 0xDA, 0x01, 0x60, 0x00, 0x64,
+	 0x5A, 0xDA, 0x82, 0x7F, 0x24, 0x7E, 0x08, 0xFA, 0x01, 0x60, 0x01, 0x64, 0x0A, 0xFA, 0x00, 0x64,
+	 0x0E, 0xFA, 0x2D, 0x58, 0xFF, 0xFF, 0x59, 0xF5, 0x3D, 0xF2, 0x3C, 0xF2, 0xCC, 0x83, 0x00, 0xA8,
+	 0x03, 0x03, 0x08, 0x28, 0x3D, 0xFC, 0x45, 0x00, 0x3D, 0xFA, 0x3A, 0xF2, 0x3B, 0xF0, 0x00, 0x63,
+	 0x00, 0xF4, 0x07, 0xFC, 0x01, 0xB0, 0x0B, 0xFA, 0x1A, 0x03, 0x1F, 0xF8, 0xFF, 0xFF, 0x1B, 0x60,
+	 0xDA, 0x62, 0x18, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x0A, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0x1F, 0xF2, 0x1E, 0xF0, 0x59, 0xF5, 0x00, 0xA8, 0x3B, 0xF8, 0xD0, 0x80, 0x06, 0x03,
+	 0x05, 0x03, 0x04, 0x60, 0x5C, 0x63, 0x0F, 0x64, 0x3A, 0xFA, 0x39, 0xFC, 0x00, 0xF4, 0x00, 0x64,
+	 0x06, 0xFA, 0xE6, 0x60, 0x58, 0x4E, 0xF4, 0x78, 0xFF, 0xFF, 0x59, 0xF5, 0x00, 0xF4, 0x81, 0x60,
+	 0x00, 0x64, 0x06, 0xFA, 0x32, 0x47, 0x04, 0xBC, 0x07, 0xFA, 0xB8, 0xF1, 0x00, 0x7F, 0x64, 0x5E,
+	 0x09, 0xFA, 0x59, 0xF5, 0x00, 0x64, 0x15, 0xFA, 0x39, 0xF2, 0x3F, 0xFA, 0x1B, 0x60, 0xDA, 0x62,
+	 0x1B, 0x60, 0x88, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0xE1, 0x60, 0x0D, 0x78, 0xFF, 0xFF, 0x66, 0x45, 0x0E, 0xF2, 0x0F, 0xF0, 0x10, 0xF0,
+	 0x64, 0x41, 0x01, 0xA8, 0x59, 0xF5, 0x09, 0x02, 0xAD, 0x83, 0x64, 0x44, 0xAC, 0x84, 0x08, 0x24,
+	 0x0A, 0x63, 0x3C, 0xFC, 0x3D, 0xFC, 0x1A, 0x02, 0x2D, 0x00, 0x03, 0x3A, 0x03, 0x00, 0x00, 0x64,
+	 0x3C, 0xFA, 0x29, 0x00, 0x04, 0x3A, 0x09, 0x00, 0x0A, 0x64, 0x3C, 0xFA, 0x01, 0x64, 0x3A, 0xFA,
+	 0x00, 0xF4, 0x00, 0x64, 0x1F, 0xFA, 0x1E, 0xFA, 0x1E, 0x00, 0x02, 0x3A, 0x1E, 0x00, 0x64, 0x44,
+	 0xAD, 0x83, 0xAC, 0x84, 0x02, 0x03, 0x3C, 0xFC, 0x3D, 0xFC, 0x15, 0x03, 0x3A, 0xFA, 0xF8, 0x65,
+	 0x52, 0x63, 0x64, 0x44, 0x01, 0x36, 0x0D, 0x00, 0x12, 0xA3, 0x64, 0x40, 0x02, 0x2A, 0x02, 0x00,
+	 0xC7, 0x83, 0xC7, 0x83, 0x64, 0x40, 0x08, 0x2A, 0x01, 0x00, 0xC7, 0x83, 0x64, 0x40, 0x04, 0x26,
+	 0xC7, 0x83, 0x39, 0xFC, 0x00, 0x64, 0x2E, 0x58, 0xFF, 0xFF, 0x3B, 0xF0, 0x3A, 0xF2, 0x65, 0x46,
+	 0x06, 0xF2, 0x40, 0x47, 0x1D, 0x18, 0x32, 0x47, 0x07, 0xFA, 0x24, 0x7E, 0x82, 0x7F, 0x08, 0xFA,
+	 0x01, 0x60, 0x01, 0x63, 0xB8, 0xF3, 0x0A, 0xFC, 0x00, 0x7F, 0x09, 0xFA, 0x27, 0x40, 0x01, 0x2A,
+	 0x0F, 0x00, 0x1F, 0xF8, 0x1B, 0x60, 0xDA, 0x62, 0x18, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB,
+	 0x0A, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x1E, 0xF0, 0x59, 0xF5, 0x3B, 0xF8, 0x65, 0x46,
+	 0x27, 0x40, 0x02, 0x26, 0x02, 0x00, 0x00, 0xF4, 0x13, 0x00, 0x6E, 0x61, 0xFF, 0x60, 0xFE, 0x64,
+	 0x00, 0x60, 0x0E, 0x63, 0x58, 0xD1, 0x59, 0xD8, 0xFD, 0x1F, 0x01, 0x60, 0xEE, 0x63, 0x00, 0xF4,
+	 0x02, 0x61, 0x58, 0xD1, 0x59, 0xD8, 0x7E, 0x3A, 0x02, 0x00, 0x00, 0xF4, 0x02, 0x61, 0xF9, 0x1F,
+	 0x27, 0x40, 0x04, 0x26, 0x1B, 0x00, 0x46, 0x4B, 0x1B, 0x60, 0x88, 0x62, 0xA2, 0xD3, 0xFF, 0xFF,
+	 0x00, 0xA8, 0x60, 0x46, 0x0E, 0x03, 0x89, 0xF0, 0xE7, 0x60, 0x58, 0x4D, 0xAE, 0x78, 0xFF, 0xFF,
+	 0x65, 0x44, 0xAC, 0x86, 0xFF, 0xFF, 0x08, 0x03, 0xE7, 0x60, 0x58, 0x4D, 0xAE, 0x78, 0xFF, 0xFF,
+	 0x04, 0x00, 0x2B, 0x46, 0x82, 0xFC, 0x00, 0xF4, 0x82, 0xFC, 0x00, 0xF4, 0x27, 0x40, 0x08, 0x26,
+	 0x1A, 0x00, 0x46, 0x4B, 0x1B, 0x60, 0xC4, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46,
+	 0x0E, 0x03, 0x89, 0xF0, 0xE7, 0x60, 0x58, 0x4D, 0xAE, 0x78, 0xFF, 0xFF, 0x65, 0x44, 0xAC, 0x86,
+	 0xFF, 0xFF, 0x08, 0x03, 0xE7, 0x60, 0x58, 0x4D, 0xAE, 0x78, 0xFF, 0xFF, 0x04, 0x00, 0x65, 0x46,
+	 0x02, 0xFA, 0x00, 0xF4, 0x82, 0xFC, 0x01, 0x64, 0x2E, 0x58, 0xFF, 0xFF, 0x01, 0x61, 0x02, 0x64,
+	 0x7A, 0x63, 0x58, 0xD0, 0xAB, 0x46, 0xA0, 0xD8, 0xAB, 0x46, 0xFB, 0x1F, 0xAB, 0x46, 0x00, 0xF4,
+	 0xCD, 0x81, 0xAB, 0x46, 0x00, 0xF4, 0xF3, 0x02, 0x2D, 0x58, 0xFF, 0xFF, 0x00, 0x60, 0x2A, 0x61,
+	 0xB3, 0x60, 0x58, 0x4D, 0x77, 0x78, 0xFF, 0xFF, 0x66, 0x44, 0x58, 0xFB, 0x04, 0x64, 0x03, 0xFA,
+	 0x67, 0x44, 0x2C, 0xFA, 0x2D, 0xFA, 0x2E, 0xFA, 0x32, 0xFA, 0x33, 0xFA, 0x34, 0xFA, 0x12, 0x60,
+	 0x80, 0x64, 0x88, 0xF1, 0x0E, 0xFA, 0x07, 0xF8, 0x00, 0x64, 0x3E, 0xFA, 0x11, 0x60, 0xD8, 0x63,
+	 0xA3, 0xDB, 0x06, 0xA3, 0x10, 0x60, 0x08, 0x64, 0xBD, 0xDB, 0x04, 0x64, 0xBD, 0xDB, 0x06, 0x64,
+	 0xA3, 0xDB, 0x10, 0x60, 0x06, 0x62, 0xEA, 0x60, 0x08, 0x64, 0xA2, 0xDB, 0x11, 0x60, 0xE4, 0x63,
+	 0x00, 0x64, 0xA3, 0xDB, 0x06, 0xA3, 0x10, 0x60, 0x0C, 0x64, 0xBD, 0xDB, 0x08, 0x64, 0xBD, 0xDB,
+	 0x06, 0x64, 0xA3, 0xDB, 0x10, 0x60, 0x0A, 0x62, 0xEA, 0x60, 0x12, 0x64, 0xA2, 0xDB, 0x0F, 0x60,
+	 0xFC, 0x62, 0xE9, 0x60, 0xF2, 0x64, 0xA2, 0xDB, 0x00, 0x64, 0x25, 0x60, 0x2A, 0x62, 0xA2, 0xDB,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x58, 0xF5, 0xCB, 0xF1, 0x2F, 0xF8, 0xCC, 0xF1, 0x30, 0xF8, 0xCD, 0xF1,
+	 0x31, 0xF8, 0xAC, 0xF1, 0x19, 0xF8, 0xEA, 0x60, 0x58, 0x4E, 0x1C, 0x78, 0xFF, 0xFF, 0x30, 0x64,
+	 0x3B, 0x42, 0x5A, 0xDB, 0x0F, 0x60, 0xE2, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x16, 0x60, 0xCC, 0x61,
+	 0xA1, 0xD3, 0xFF, 0xFF, 0x59, 0x18, 0x58, 0xF5, 0x40, 0x64, 0x2A, 0xFA, 0x52, 0xF3, 0x00, 0xF4,
+	 0x60, 0x43, 0xBD, 0xD1, 0x04, 0x65, 0x64, 0x47, 0xA5, 0xDA, 0x64, 0x41, 0xDD, 0x81, 0xE9, 0x81,
+	 0x62, 0x44, 0x04, 0x03, 0xBD, 0xD1, 0xCD, 0x81, 0x58, 0xD8, 0xFC, 0x02, 0x58, 0x8B, 0x21, 0x60,
+	 0x8E, 0x63, 0xA3, 0xD1, 0x2B, 0x44, 0xC8, 0x84, 0x64, 0x41, 0xFF, 0xB1, 0x61, 0x45, 0x03, 0xA1,
+	 0xE9, 0x81, 0x41, 0x4C, 0xBD, 0xD1, 0xCD, 0x81, 0x58, 0xD8, 0xFC, 0x02, 0x2B, 0xD2, 0x2B, 0x43,
+	 0x60, 0x47, 0x01, 0x7E, 0x52, 0xF1, 0xA3, 0xDA, 0xA4, 0xD3, 0xCB, 0x83, 0x44, 0x8B, 0xF8, 0x84,
+	 0x2C, 0x41, 0x0C, 0x04, 0xBE, 0xD2, 0xFF, 0xFF, 0x60, 0x47, 0xBE, 0xDA, 0x00, 0x7E, 0xA3, 0xD2,
+	 0x60, 0x45, 0x00, 0x7F, 0xB4, 0x84, 0xCD, 0x81, 0xBD, 0xDA, 0xF4, 0x02, 0x58, 0xF5, 0x2B, 0x44,
+	 0x04, 0xA4, 0x3F, 0xFA, 0x65, 0xF3, 0x64, 0xFB, 0x16, 0x60, 0xCE, 0x61, 0x01, 0x64, 0x52, 0xF1,
+	 0xA1, 0xDB, 0x65, 0xFB, 0xA4, 0xD3, 0x04, 0x65, 0x51, 0xF3, 0x01, 0x18, 0x0C, 0x65, 0xF3, 0xB4,
+	 0xB4, 0x84, 0x51, 0xFB, 0x02, 0xB0, 0xFF, 0xFF, 0x16, 0x03, 0x65, 0xF3, 0xFF, 0xFF, 0x60, 0x47,
+	 0x0F, 0xB4, 0x65, 0xFB, 0x01, 0x03, 0x0F, 0x00, 0xE9, 0x60, 0x74, 0x78, 0xFF, 0xFF, 0x51, 0xF1,
+	 0x65, 0xF3, 0x64, 0x40, 0x02, 0x26, 0xF8, 0x01, 0xF3, 0xA0, 0x04, 0xA4, 0x01, 0x04, 0xF1, 0xA4,
+	 0x10, 0x36, 0xF2, 0x01, 0x65, 0xFB, 0x65, 0xF3, 0x16, 0x60, 0xCC, 0x61, 0xA1, 0xD1, 0xCC, 0x84,
+	 0x01, 0x61, 0x08, 0x24, 0x03, 0x00, 0xE1, 0x81, 0xCC, 0x84, 0xFB, 0x01, 0xA1, 0x84, 0x51, 0xF1,
+	 0xE7, 0x03, 0x16, 0x60, 0xCE, 0x61, 0xA1, 0xDB, 0x00, 0x00, 0x65, 0xF3, 0x01, 0x61, 0xCC, 0x84,
+	 0xFF, 0xFF, 0x02, 0x03, 0xE1, 0x81, 0xFB, 0x01, 0x9A, 0xF3, 0x61, 0x45, 0xA4, 0x80, 0xFF, 0xFF,
+	 0xD7, 0x03, 0x31, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x0F, 0x60, 0xE2, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0xDE, 0xFE, 0x0B, 0x04, 0x0F, 0x60, 0xE4, 0x62, 0x40, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xE8, 0x60,
+	 0x95, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x65, 0xF1, 0x1C, 0x60, 0x00, 0x62,
+	 0xA2, 0xD9, 0x1E, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x0F, 0x60, 0xE4, 0x62, 0x20, 0x60,
+	 0x00, 0x64, 0xA2, 0xDB, 0xE8, 0x60, 0xC8, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0xBE, 0xFE, 0x0F, 0x60, 0xCE, 0x62, 0xA2, 0xD1, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xCF, 0xFE, 0x0F, 0x60, 0xE2, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x58, 0xF5, 0x1B, 0x60, 0xDA, 0x62,
+	 0x1B, 0x60, 0x8E, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0x00, 0x64, 0x4F, 0xFB, 0x0F, 0x60, 0xE4, 0x62, 0x00, 0x60, 0x01, 0x64, 0xA2, 0xDB,
+	 0xE8, 0x60, 0xF2, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0xC1, 0xFE, 0x33, 0x64, 0x3B, 0x42, 0x5A, 0xDB,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x34, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x0F, 0x60, 0xE2, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0xA6, 0xF1, 0x11, 0x60, 0xDC, 0x62, 0xA2, 0xD9, 0x1C, 0x60, 0x10, 0x62, 0x11, 0x60,
+	 0xD8, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0xA7, 0xF1, 0x11, 0x60,
+	 0xE8, 0x62, 0xA2, 0xD9, 0x1C, 0x60, 0x0E, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0xFD, 0x1B, 0x1C, 0x60,
+	 0x10, 0x62, 0x11, 0x60, 0xE4, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF,
+	 0x0F, 0x60, 0xE4, 0x62, 0x00, 0x60, 0x08, 0x64, 0xA2, 0xDB, 0xE9, 0x60, 0x23, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x4F, 0xF1, 0x0F, 0x60, 0xE2, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0x64, 0x40, 0xFF, 0x26, 0x03, 0x00, 0xE8, 0x60, 0x77, 0x78, 0xFF, 0xFF, 0x02, 0x0A, 0x00, 0x64,
+	 0x4F, 0xFB, 0xA8, 0xF1, 0x11, 0x60, 0xE8, 0x62, 0xA2, 0xD9, 0x0F, 0x60, 0xE4, 0x62, 0x00, 0x60,
+	 0x0C, 0x64, 0xA2, 0xDB, 0xE9, 0x60, 0x49, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x1C, 0x60, 0x10, 0x62,
+	 0x11, 0x60, 0xE4, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x0F, 0x60, 0xE2, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x04, 0x64, 0xA0, 0x80, 0x9C, 0x84,
+	 0x0C, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x1C, 0x60, 0x10, 0x62, 0x11, 0x60, 0xE4, 0x64, 0xA2, 0xDB,
+	 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x14, 0x00, 0xFF, 0x60, 0xF7, 0x64, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x4F, 0xF3, 0xDB, 0x0A, 0x00, 0xA0, 0x00, 0x64, 0x02, 0x03, 0x4F, 0xFB, 0xD6, 0x01,
+	 0x1C, 0x60, 0x10, 0x62, 0x11, 0x60, 0xD8, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x04, 0xFF, 0xE8, 0x60, 0x77, 0x78, 0xFF, 0xFF, 0x35, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x1C, 0x60,
+	 0x10, 0x62, 0x11, 0x60, 0xD8, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF,
+	 0x51, 0xF3, 0xFF, 0xFF, 0xE3, 0xB4, 0x51, 0xFB, 0x16, 0x60, 0xCA, 0x64, 0xA0, 0xD3, 0xFF, 0xFF,
+	 0xFE, 0xB4, 0xA2, 0xDB, 0x00, 0x64, 0x25, 0x60, 0x2A, 0x62, 0xA2, 0xDB, 0x0F, 0x60, 0xE2, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE, 0x0E, 0x04, 0x32, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x0F, 0x60,
+	 0xE4, 0x62, 0x40, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xE9, 0x60, 0x8E, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x64, 0xF1, 0x65, 0xF9, 0x1C, 0x60, 0x00, 0x62, 0xA2, 0xD9, 0x1E, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x0F, 0x60, 0xE4, 0x62, 0x20, 0x60, 0x00, 0x64, 0xA2, 0xDB,
+	 0xE9, 0x60, 0xB6, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0xBE, 0xFE, 0x0F, 0x60,
+	 0xCE, 0x62, 0xA2, 0xD1, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x0F, 0x60,
+	 0xCE, 0x62, 0xA2, 0xD1, 0x10, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x00, 0x60,
+	 0x04, 0x61, 0xB3, 0x60, 0x58, 0x4D, 0x77, 0x78, 0xFF, 0xFF, 0x01, 0x64, 0x23, 0xFA, 0xF1, 0x60,
+	 0x02, 0x64, 0x24, 0xFA, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0xCA, 0x64, 0xA2, 0xDB, 0x66, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xFA, 0xFE, 0xEA, 0x60, 0x58, 0x4E,
+	 0x2E, 0x78, 0xFF, 0xFF, 0x20, 0x44, 0x01, 0xB5, 0x54, 0x80, 0x31, 0x44, 0xDE, 0xB4, 0x40, 0x51,
+	 0x0F, 0x60, 0xE2, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x5A, 0xDB, 0x3E, 0x64, 0x3B, 0x42, 0x5A, 0xDB,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x3F, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x1C, 0x60, 0x10, 0x62, 0x11, 0x60,
+	 0xD8, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x00, 0x64, 0x51, 0xFB,
+	 0x0F, 0x60, 0xE2, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x5A, 0xDB, 0xBE, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x0F, 0x60, 0xE2, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xE2, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x08, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x66, 0x01, 0x60, 0x7A, 0x61, 0x16, 0x60,
+	 0xC4, 0x63, 0xA1, 0xD3, 0xFF, 0xFF, 0x20, 0x7F, 0xBD, 0xDB, 0x21, 0x60, 0x32, 0x64, 0xBD, 0xDB,
+	 0x04, 0xA1, 0xA1, 0xD3, 0xFF, 0xFF, 0x22, 0x7F, 0xA3, 0xDB, 0x10, 0x00, 0x01, 0x60, 0x7A, 0x61,
+	 0x16, 0x60, 0xC4, 0x63, 0xA1, 0xD3, 0x00, 0x66, 0x20, 0x7F, 0xBD, 0xDB, 0x59, 0xD3, 0xFF, 0xFF,
+	 0x21, 0x7F, 0xBD, 0xDB, 0x59, 0xD3, 0xFF, 0xFF, 0x22, 0x7F, 0xA3, 0xDB, 0x0F, 0x60, 0xE2, 0x62,
+	 0xA2, 0xD1, 0x9F, 0x60, 0xFF, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0xDE, 0xFE, 0x0B, 0x04, 0x0F, 0x60,
+	 0xE4, 0x62, 0x40, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xEA, 0x60, 0x3E, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x1C, 0x60, 0x00, 0x62, 0x16, 0x60, 0xC2, 0x64, 0xA2, 0xDB, 0x20, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x0F, 0x60, 0xE4, 0x62, 0x20, 0x60, 0x00, 0x64, 0xA2, 0xDB,
+	 0xEA, 0x60, 0x66, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xE2, 0x62,
+	 0xA2, 0xD1, 0x9F, 0x60, 0xFF, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0xBE, 0xFE, 0x0F, 0x60, 0xCE, 0x62,
+	 0xA2, 0xD1, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x2E, 0x58, 0xFF, 0xFF,
+	 0x5F, 0xFB, 0xAC, 0x85, 0x60, 0x41, 0x20, 0x03, 0x01, 0x60, 0x00, 0x63, 0x08, 0x64, 0xE9, 0x81,
+	 0xCC, 0x84, 0x02, 0x24, 0xDF, 0x83, 0xFB, 0x02, 0x21, 0x60, 0x8E, 0x64, 0xA0, 0xDD, 0x65, 0x41,
+	 0x21, 0x60, 0x90, 0x63, 0x0F, 0x60, 0xC0, 0x64, 0xE9, 0x81, 0x58, 0xD1, 0xFD, 0x04, 0xA3, 0xD9,
+	 0x0B, 0x03, 0x58, 0xD1, 0xE9, 0x81, 0x60, 0x45, 0xFC, 0x04, 0xA3, 0xD1, 0x64, 0x47, 0xB0, 0x84,
+	 0xBD, 0xDB, 0x00, 0xB9, 0x65, 0x44, 0xF0, 0x02, 0x20, 0x60, 0x38, 0x62, 0xA2, 0xD3, 0xFF, 0xFF,
+	 0x01, 0xA8, 0x01, 0x60, 0x70, 0x62, 0x06, 0x02, 0xA2, 0xD3, 0xFF, 0xFF, 0x01, 0xA8, 0xFF, 0xFF,
+	 0x01, 0x03, 0x02, 0x64, 0x60, 0x41, 0x21, 0x60, 0x8E, 0x63, 0xBD, 0xD3, 0xA3, 0xD3, 0xFF, 0xB5,
+	 0x80, 0xBF, 0xCD, 0x81, 0x65, 0x5C, 0x0F, 0x03, 0x80, 0xBF, 0xBD, 0xDB, 0x65, 0x44, 0xC8, 0x84,
+	 0xFF, 0xFF, 0x0C, 0x03, 0x60, 0x45, 0xCD, 0x81, 0xA3, 0xD3, 0x08, 0x03, 0x80, 0xBF, 0xCD, 0x81,
+	 0xFF, 0xFF, 0x01, 0x03, 0x80, 0xBC, 0x60, 0x47, 0xBD, 0xDB, 0x00, 0x65, 0x64, 0x41, 0x21, 0x60,
+	 0x90, 0x63, 0xBD, 0xD3, 0xFF, 0xFF, 0x80, 0xB0, 0xFF, 0xFF, 0x01, 0x03, 0x60, 0x45, 0x60, 0x47,
+	 0x80, 0xB0, 0xFF, 0xFF, 0x01, 0x03, 0x60, 0x45, 0xCD, 0x81, 0xFF, 0xFF, 0xF2, 0x02, 0x65, 0x44,
+	 0x7F, 0xB4, 0x02, 0x3A, 0x02, 0x00, 0x0A, 0x64, 0x15, 0x00, 0x04, 0x3A, 0x02, 0x00, 0x14, 0x64,
+	 0x11, 0x00, 0x0A, 0x3A, 0x02, 0x00, 0x32, 0x64, 0x0D, 0x00, 0x0B, 0x3A, 0x02, 0x00, 0x37, 0x64,
+	 0x09, 0x00, 0x10, 0x3A, 0x02, 0x00, 0x50, 0x64, 0x05, 0x00, 0x16, 0x3A, 0x02, 0x00, 0x6E, 0x64,
+	 0x01, 0x00, 0x14, 0x64, 0x62, 0xFB, 0x2E, 0x58, 0xFF, 0xFF, 0x3C, 0x64, 0x3B, 0x42, 0x5A, 0xDB,
+	 0x31, 0x40, 0x20, 0x2A, 0x18, 0x00, 0x3F, 0xF2, 0x47, 0x65, 0xC4, 0x84, 0xE8, 0x84, 0x23, 0xFA,
+	 0xF1, 0x60, 0x02, 0x64, 0x24, 0xFA, 0x1B, 0x60, 0xDA, 0x62, 0x1B, 0x60, 0xCA, 0x64, 0xA2, 0xDB,
+	 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xFA, 0xFE, 0x00, 0x66,
+	 0x46, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x26, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x0C, 0x63, 0x12, 0x60,
+	 0xB6, 0x62, 0x00, 0x64, 0x5A, 0xDB, 0xFE, 0x1F, 0x53, 0xFB, 0x54, 0xFB, 0x12, 0x60, 0xBA, 0x63,
+	 0x02, 0x64, 0xA3, 0xDB, 0x2E, 0x58, 0xFF, 0xFF, 0x12, 0x60, 0xBE, 0x62, 0xA2, 0xD3, 0x00, 0x63,
+	 0xF0, 0xA0, 0x01, 0xA4, 0x03, 0x03, 0xA2, 0xDB, 0x2E, 0x58, 0xFF, 0xFF, 0xA2, 0xDD, 0x12, 0x60,
+	 0xC0, 0x62, 0xA2, 0xD1, 0xA2, 0xDD, 0x5A, 0xD3, 0xA2, 0xDD, 0xC0, 0x81, 0x61, 0x44, 0x02, 0x24,
+	 0xFF, 0xFF, 0xE9, 0x81, 0xE9, 0x81, 0xE9, 0x81, 0xE9, 0x81, 0x5A, 0xD3, 0xE9, 0x81, 0xE8, 0x83,
+	 0xEB, 0x83, 0xEB, 0x83, 0xEB, 0x83, 0xEB, 0x85, 0xD4, 0x85, 0xC5, 0x83, 0xA2, 0xDD, 0x12, 0x60,
+	 0xB8, 0x62, 0x63, 0x47, 0x00, 0x7F, 0xA2, 0xDB, 0x2E, 0x58, 0xFF, 0xFF, 0x03, 0xE1, 0xA3, 0xFF,
+	 0x1B, 0x60, 0x5A, 0x63, 0x17, 0xFD, 0xAE, 0xFF, 0xEB, 0x60, 0x84, 0x78, 0xFF, 0xFF, 0x7F, 0x67,
+	 0x01, 0x61, 0x23, 0x58, 0xFF, 0xFF, 0xB1, 0xFE, 0x05, 0x05, 0xB0, 0xFE, 0x06, 0x05, 0xB2, 0xFE,
+	 0xB3, 0xFE, 0x22, 0x00, 0xF0, 0x60, 0xFA, 0x78, 0xFF, 0xFF, 0x28, 0xF3, 0x29, 0xF1, 0x40, 0x44,
+	 0x44, 0x45, 0x2A, 0xF1, 0x2B, 0xF1, 0x44, 0x46, 0x44, 0x47, 0x3F, 0xB4, 0xE0, 0x85, 0x16, 0x60,
+	 0xD2, 0x64, 0x44, 0xD7, 0x58, 0x43, 0xFF, 0xFF, 0x60, 0x45, 0x12, 0x60, 0xC8, 0x7C, 0xA4, 0xD3,
+	 0x61, 0x43, 0x04, 0xB4, 0x24, 0x44, 0x02, 0x03, 0x13, 0xFF, 0x06, 0x00, 0x3F, 0xB4, 0xB4, 0x84,
+	 0xFF, 0x27, 0x05, 0xFD, 0x04, 0xFB, 0x10, 0x75, 0xA1, 0xFF, 0xFF, 0xFF, 0x86, 0x3E, 0xB4, 0xFE,
+	 0x09, 0x05, 0xB5, 0xFE, 0x02, 0x24, 0x80, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xB7, 0xFE, 0x05, 0x05,
+	 0xB6, 0xFE, 0xF2, 0x01, 0xF1, 0x60, 0x35, 0x78, 0xFF, 0xFF, 0x36, 0x44, 0x00, 0x7F, 0xF4, 0xA0,
+	 0x60, 0x45, 0x05, 0x05, 0x17, 0x60, 0x5E, 0x64, 0x44, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0x01,
+	 0xE3, 0x01, 0x7F, 0x60, 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80, 0x7F, 0x67, 0x02, 0x61, 0x10, 0x02,
+	 0x10, 0x64, 0x40, 0x40, 0x02, 0x64, 0x40, 0x50, 0x61, 0xFF, 0x3F, 0x40, 0x40, 0x26, 0x04, 0x00,
+	 0x10, 0xE0, 0x46, 0x60, 0x09, 0xE0, 0x00, 0x00, 0x27, 0xF1, 0x00, 0x66, 0x20, 0x78, 0x42, 0xFE,
+	 0x23, 0x58, 0xFF, 0xFF, 0x78, 0x60, 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80, 0x7F, 0x67, 0x02, 0x61,
+	 0x1C, 0x02, 0x12, 0x60, 0xC8, 0x63, 0xA3, 0xD3, 0x07, 0x7C, 0x20, 0xB5, 0x0C, 0xB5, 0x04, 0x03,
+	 0x03, 0x02, 0xBC, 0xF9, 0x00, 0x67, 0x11, 0x00, 0x00, 0x61, 0x41, 0x56, 0xC7, 0xFE, 0xB4, 0x01,
+	 0x36, 0x47, 0xFF, 0x23, 0x04, 0x00, 0x00, 0x7F, 0x60, 0x41, 0x7F, 0x67, 0x06, 0x00, 0x04, 0x7C,
+	 0xBC, 0xF9, 0x20, 0x44, 0x80, 0xBC, 0x40, 0x40, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x78, 0x60,
+	 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80, 0x7F, 0x67, 0x02, 0x61, 0x31, 0x02, 0x12, 0x60, 0xC8, 0x63,
+	 0xA3, 0xD3, 0x01, 0x7C, 0x20, 0xB5, 0x0C, 0xB5, 0x03, 0x03, 0x02, 0x02, 0xBC, 0xF9, 0xFF, 0xFF,
+	 0x02, 0x61, 0x41, 0x56, 0xC7, 0xFE, 0xEB, 0x60, 0x84, 0x78, 0xFF, 0xFF, 0x7E, 0xF1, 0x20, 0x44,
+	 0x64, 0x40, 0xFF, 0x26, 0x1B, 0x00, 0x7F, 0xB4, 0x40, 0x40, 0x5C, 0x5E, 0x82, 0xFF, 0x26, 0x44,
+	 0xFD, 0xB4, 0x40, 0x46, 0x5C, 0x41, 0x87, 0xFF, 0x62, 0xFF, 0x00, 0x63, 0x1B, 0x60, 0xC4, 0x62,
+	 0xA2, 0xD3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x04, 0x03, 0x09, 0xF2, 0x0F, 0xFC, 0xAC, 0x86,
+	 0xFB, 0x01, 0x1C, 0x60, 0x04, 0x62, 0x06, 0x64, 0xA2, 0xDB, 0x2D, 0xFF, 0x00, 0x67, 0x23, 0x58,
+	 0xFF, 0xFF, 0x25, 0x46, 0x01, 0xF2, 0x08, 0xF0, 0x60, 0x47, 0x03, 0xB4, 0x03, 0xAC, 0x7F, 0x67,
+	 0x03, 0x61, 0x08, 0x02, 0x1B, 0x60, 0xE0, 0x64, 0x40, 0x4B, 0xF0, 0x60, 0x58, 0x4D, 0x75, 0x78,
+	 0xFF, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x24, 0x40, 0x01, 0x2B, 0x49, 0x00, 0x25, 0x44,
+	 0x1F, 0xB4, 0xE0, 0x85, 0xEC, 0x60, 0x36, 0x64, 0xC4, 0x98, 0xFF, 0xFF, 0xC0, 0xFE, 0x3D, 0x00,
+	 0xC1, 0xFE, 0x3B, 0x00, 0xC2, 0xFE, 0x39, 0x00, 0xC3, 0xFE, 0x37, 0x00, 0xC4, 0xFE, 0x35, 0x00,
+	 0xC5, 0xFE, 0x33, 0x00, 0xC6, 0xFE, 0x31, 0x00, 0xC7, 0xFE, 0x2F, 0x00, 0xC8, 0xFE, 0x2D, 0x00,
+	 0xC9, 0xFE, 0x2B, 0x00, 0xCA, 0xFE, 0x29, 0x00, 0xCB, 0xFE, 0x27, 0x00, 0xCC, 0xFE, 0x25, 0x00,
+	 0xCD, 0xFE, 0x23, 0x00, 0xCE, 0xFE, 0x21, 0x00, 0xCF, 0xFE, 0x1F, 0x00, 0xD0, 0xFE, 0x1D, 0x00,
+	 0xD1, 0xFE, 0x1B, 0x00, 0xD2, 0xFE, 0x19, 0x00, 0xD3, 0xFE, 0x17, 0x00, 0xD4, 0xFE, 0x15, 0x00,
+	 0xD5, 0xFE, 0x13, 0x00, 0xD6, 0xFE, 0x11, 0x00, 0xD7, 0xFE, 0x0F, 0x00, 0xD8, 0xFE, 0x0D, 0x00,
+	 0xD9, 0xFE, 0x0B, 0x00, 0xDA, 0xFE, 0x09, 0x00, 0xDB, 0xFE, 0x07, 0x00, 0xDC, 0xFE, 0x05, 0x00,
+	 0xDD, 0xFE, 0x03, 0x00, 0xDE, 0xFE, 0x01, 0x00, 0xDF, 0xFE, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x00, 0x64, 0x9F, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x9E, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x9D, 0xFE,
+	 0xF0, 0x84, 0xFF, 0xFF, 0x9C, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x9B, 0xFE, 0xF0, 0x84, 0xFF, 0xFF,
+	 0x9A, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x99, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x98, 0xFE, 0xF0, 0x84,
+	 0xFF, 0xFF, 0x97, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x96, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x95, 0xFE,
+	 0xF0, 0x84, 0xFF, 0xFF, 0x94, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x93, 0xFE, 0xF0, 0x84, 0xFF, 0xFF,
+	 0x92, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x91, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x90, 0xFE, 0xF0, 0x84,
+	 0x06, 0xFB, 0x8F, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x8E, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x8D, 0xFE,
+	 0xF0, 0x84, 0xFF, 0xFF, 0x8C, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x8B, 0xFE, 0xF0, 0x84, 0xFF, 0xFF,
+	 0x8A, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x89, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x88, 0xFE, 0xF0, 0x84,
+	 0xFF, 0xFF, 0x87, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x86, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x85, 0xFE,
+	 0xF0, 0x84, 0xFF, 0xFF, 0x84, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x83, 0xFE, 0xF0, 0x84, 0xFF, 0xFF,
+	 0x82, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x81, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x80, 0xFE, 0xF0, 0x84,
+	 0x05, 0xFB, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x5C, 0x5C, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x24, 0x40, 0x01, 0x27, 0x55, 0x00, 0x05, 0x60, 0x00, 0x63, 0x05, 0xFD, 0x30, 0x44, 0xBD, 0xDB,
+	 0x31, 0x44, 0xBD, 0xDB, 0x32, 0x44, 0xBD, 0xDB, 0x33, 0x44, 0xBD, 0xDB, 0x34, 0x44, 0xBD, 0xDB,
+	 0x35, 0x44, 0xBD, 0xDB, 0x36, 0x44, 0xBD, 0xDB, 0x37, 0x44, 0xBD, 0xDB, 0x38, 0x44, 0xBD, 0xDB,
+	 0x39, 0x44, 0xBD, 0xDB, 0x3A, 0x44, 0xBD, 0xDB, 0x3B, 0x44, 0xBD, 0xDB, 0x3C, 0x44, 0xBD, 0xDB,
+	 0x3D, 0x44, 0xBD, 0xDB, 0x3E, 0x44, 0xBD, 0xDB, 0x3F, 0x44, 0xBD, 0xDB, 0x02, 0x61, 0x61, 0x44,
+	 0x02, 0x36, 0x82, 0xFF, 0x03, 0x36, 0x83, 0xFF, 0x04, 0x36, 0x84, 0xFF, 0x05, 0x36, 0x85, 0xFF,
+	 0x06, 0x36, 0x86, 0xFF, 0x07, 0x36, 0x87, 0xFF, 0x20, 0x44, 0xBD, 0xDB, 0x21, 0x44, 0xBD, 0xDB,
+	 0x22, 0x44, 0xBD, 0xDB, 0x23, 0x44, 0xBD, 0xDB, 0x24, 0x44, 0xBD, 0xDB, 0x25, 0x44, 0xBD, 0xDB,
+	 0x26, 0x44, 0xBD, 0xDB, 0x27, 0x44, 0xBD, 0xDB, 0x28, 0x44, 0xBD, 0xDB, 0x29, 0x44, 0xBD, 0xDB,
+	 0x2A, 0x44, 0xBD, 0xDB, 0x2B, 0x44, 0xBD, 0xDB, 0x2C, 0x44, 0xBD, 0xDB, 0x2D, 0x44, 0xBD, 0xDB,
+	 0x2E, 0x44, 0xBD, 0xDB, 0x2F, 0x44, 0xBD, 0xDB, 0xDD, 0x81, 0x08, 0x3A, 0xD0, 0x01, 0x54, 0x00,
+	 0x27, 0x40, 0x10, 0x26, 0x30, 0x00, 0x26, 0x44, 0x01, 0x36, 0x2D, 0x00, 0x02, 0x36, 0x82, 0xFF,
+	 0x03, 0x36, 0x83, 0xFF, 0x04, 0x36, 0x84, 0xFF, 0x05, 0x36, 0x85, 0xFF, 0x06, 0x36, 0x86, 0xFF,
+	 0x25, 0x44, 0x00, 0x36, 0x44, 0x40, 0x01, 0x36, 0x44, 0x41, 0x02, 0x36, 0x44, 0x42, 0x03, 0x36,
+	 0x44, 0x43, 0x04, 0x36, 0x44, 0x44, 0x05, 0x36, 0x44, 0x45, 0x06, 0x36, 0x44, 0x46, 0x07, 0x36,
+	 0x44, 0x47, 0x08, 0x36, 0x44, 0x48, 0x09, 0x36, 0x44, 0x49, 0x0A, 0x36, 0x44, 0x4A, 0x0B, 0x36,
+	 0x44, 0x4B, 0x0C, 0x36, 0x44, 0x4C, 0x0D, 0x36, 0x44, 0x4D, 0x0E, 0x36, 0x44, 0x4E, 0x0F, 0x36,
+	 0x44, 0x4F, 0x87, 0xFF, 0x21, 0x00, 0x25, 0x44, 0x10, 0x36, 0x44, 0x50, 0x11, 0x36, 0x44, 0x51,
+	 0x12, 0x36, 0x44, 0x52, 0x13, 0x36, 0x44, 0x53, 0x14, 0x36, 0x44, 0x54, 0x15, 0x36, 0x44, 0x55,
+	 0x16, 0x36, 0x44, 0x56, 0x17, 0x36, 0x44, 0x57, 0x18, 0x36, 0x44, 0x58, 0x19, 0x36, 0x44, 0x59,
+	 0x1A, 0x36, 0x44, 0x5A, 0x1B, 0x36, 0x44, 0x5B, 0x1C, 0x36, 0x44, 0x5C, 0x1D, 0x36, 0x44, 0x5D,
+	 0x1E, 0x36, 0x44, 0x5E, 0x1F, 0x36, 0x44, 0x5F, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x25, 0x46,
+	 0xB3, 0x60, 0x58, 0x4F, 0x22, 0x78, 0xFF, 0xFF, 0x03, 0x61, 0x7F, 0x67, 0x0B, 0x02, 0x00, 0xF0,
+	 0x1B, 0x60, 0xE0, 0x62, 0x04, 0x64, 0xA2, 0xDB, 0x5A, 0xD9, 0x0A, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x40, 0x60, 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80,
+	 0x7F, 0x67, 0x02, 0x61, 0x11, 0x02, 0x1C, 0x60, 0x04, 0x62, 0x1A, 0x64, 0xA2, 0xDB, 0x00, 0x60,
+	 0x50, 0x63, 0x5A, 0xDD, 0xED, 0x60, 0xB9, 0x64, 0x80, 0xFB, 0x2D, 0xFF, 0xEB, 0x60, 0x84, 0x78,
+	 0xFF, 0xFF, 0x2A, 0xF3, 0x05, 0xFB, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x40, 0x60, 0xC0, 0x64,
+	 0x24, 0x45, 0xA4, 0x80, 0x7F, 0x67, 0x02, 0x61, 0x0F, 0x02, 0x1C, 0x60, 0x04, 0x62, 0x1C, 0x64,
+	 0xA2, 0xDB, 0x00, 0x60, 0x50, 0x63, 0x5A, 0xDD, 0xED, 0x60, 0xD3, 0x64, 0x80, 0xFB, 0x2D, 0xFF,
+	 0xEB, 0x60, 0x84, 0x78, 0xFF, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x7F, 0x60, 0xC0, 0x64,
+	 0x24, 0x45, 0xA4, 0x80, 0x02, 0x61, 0x34, 0x02, 0x25, 0x45, 0x20, 0x44, 0x80, 0x2A, 0x35, 0x00,
+	 0xF1, 0x60, 0x00, 0x64, 0xD4, 0x80, 0xFF, 0xFF, 0x01, 0x03, 0x29, 0x00, 0x21, 0x60, 0x74, 0x62,
+	 0xA2, 0xD1, 0x9A, 0xF3, 0x16, 0x60, 0xCC, 0x61, 0xA0, 0x84, 0xA1, 0xDB, 0x25, 0x45, 0x1B, 0x60,
+	 0x52, 0x63, 0x01, 0x61, 0xBD, 0xD3, 0xBD, 0xD1, 0xD4, 0x80, 0xBD, 0xD3, 0xBD, 0xD5, 0xCD, 0x81,
+	 0x02, 0x03, 0x15, 0x03, 0xF7, 0x01, 0xA2, 0xFF, 0xA6, 0xD3, 0x40, 0x4C, 0x00, 0xA8, 0x67, 0x43,
+	 0x0C, 0x02, 0xA2, 0xDD, 0x42, 0x48, 0x64, 0x41, 0xB3, 0x60, 0x58, 0x4D, 0x77, 0x78, 0xFF, 0xFF,
+	 0x66, 0x44, 0x28, 0xDB, 0x02, 0x03, 0x2C, 0x58, 0xA3, 0xFF, 0x0C, 0x61, 0x03, 0x00, 0x04, 0x61,
+	 0x7F, 0x67, 0x01, 0x00, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0xF1, 0x60, 0x02, 0x64, 0xD4, 0x80,
+	 0x7F, 0x67, 0x06, 0x63, 0xF8, 0x02, 0x31, 0x40, 0x20, 0x26, 0xF5, 0x01, 0x21, 0x60, 0x74, 0x62,
+	 0xA2, 0xD1, 0x9A, 0xF3, 0x16, 0x60, 0xCC, 0x61, 0xA0, 0x84, 0xA1, 0xDB, 0x16, 0x60, 0xD0, 0x61,
+	 0x01, 0x64, 0xA1, 0xDB, 0xFF, 0xFF, 0xC4, 0xFE, 0xE5, 0x01, 0xC6, 0xFE, 0xE3, 0x01, 0x7E, 0x60,
+	 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80, 0x02, 0x61, 0x3F, 0x02, 0x25, 0x45, 0xF8, 0x2B, 0x3B, 0x00,
+	 0x2E, 0xF5, 0x67, 0x44, 0xD4, 0x80, 0x17, 0x60, 0x6A, 0x63, 0x39, 0x03, 0x64, 0x61, 0x24, 0x44,
+	 0x01, 0x27, 0x29, 0x00, 0xA3, 0xFC, 0xA4, 0xF8, 0xBD, 0xD3, 0xA3, 0xD1, 0xD4, 0x80, 0xCD, 0x81,
+	 0x08, 0x24, 0x64, 0x58, 0x08, 0xA3, 0xF8, 0x02, 0x08, 0x60, 0x00, 0x63, 0xBD, 0xD3, 0xA3, 0xD1,
+	 0xFE, 0xA0, 0xFA, 0x60, 0x00, 0x64, 0xD0, 0x80, 0x14, 0x02, 0x13, 0x02, 0x04, 0xA3, 0xBE, 0xD3,
+	 0xBD, 0xD1, 0x0F, 0x18, 0xD4, 0x80, 0x0D, 0x18, 0x03, 0x03, 0xC3, 0x83, 0xC3, 0x83, 0xF7, 0x01,
+	 0x64, 0x41, 0xDD, 0x81, 0xE1, 0x81, 0xCB, 0x83, 0x46, 0x65, 0xF2, 0x60, 0x58, 0x4F, 0x4A, 0x78,
+	 0xFF, 0xFF, 0x00, 0x67, 0x0A, 0x00, 0xBD, 0xD3, 0xBE, 0xD1, 0xD4, 0x80, 0xCD, 0x81, 0x08, 0x24,
+	 0x64, 0x58, 0x08, 0xA3, 0xF8, 0x02, 0x04, 0x61, 0x7F, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x0F, 0x64,
+	 0x23, 0xFA, 0x67, 0x44, 0x24, 0xFA, 0x62, 0x41, 0x3E, 0x60, 0x00, 0x65, 0x1A, 0x63, 0xEA, 0x60,
+	 0x88, 0x64, 0x65, 0x46, 0x58, 0xD0, 0x2E, 0xF5, 0x59, 0xD8, 0xFB, 0x1F, 0x00, 0x67, 0x23, 0x58,
+	 0xFF, 0xFF, 0x4B, 0xD3, 0xFF, 0xFF, 0x60, 0x41, 0xE8, 0x84, 0xDC, 0x84, 0x23, 0xFA, 0xBF, 0xD1,
+	 0x4A, 0x65, 0x64, 0x43, 0xF2, 0x60, 0x58, 0x4F, 0x4A, 0x78, 0xFF, 0xFF, 0x00, 0x67, 0x23, 0x58,
+	 0xFF, 0xFF, 0x25, 0xF2, 0xFF, 0xFF, 0xE0, 0xA0, 0x20, 0x64, 0x01, 0x06, 0x25, 0xFA, 0x23, 0xF2,
+	 0xDF, 0xD1, 0xCC, 0x84, 0xE0, 0x85, 0x0B, 0x06, 0xBF, 0xD1, 0x64, 0x41, 0xD5, 0x80, 0x64, 0x43,
+	 0x01, 0x06, 0x65, 0x41, 0x4A, 0x65, 0xEF, 0x60, 0x58, 0x4F, 0x87, 0x78, 0xFF, 0xFF, 0x00, 0x67,
+	 0x23, 0x58, 0xFF, 0xFF, 0xBC, 0xF3, 0x02, 0x63, 0x23, 0xFC, 0x07, 0xB4, 0x25, 0xFA, 0x00, 0x67,
+	 0x23, 0x58, 0xFF, 0xFF, 0x4B, 0xD3, 0xBF, 0xD3, 0x60, 0x41, 0xC9, 0x83, 0xE9, 0x81, 0xDD, 0x81,
+	 0xA3, 0xFA, 0xE0, 0x81, 0x3C, 0x60, 0x00, 0x67, 0x02, 0x24, 0x02, 0xA4, 0x60, 0x47, 0x40, 0x4B,
+	 0xC9, 0x81, 0x4A, 0x65, 0xAB, 0x46, 0x59, 0xD0, 0xAB, 0x46, 0xA5, 0xD8, 0xDA, 0x85, 0x80, 0x3A,
+	 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0xF6, 0x1F, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0xFC, 0xA3,
+	 0xA3, 0xD1, 0x4C, 0x65, 0xA4, 0xD3, 0xDA, 0x83, 0x60, 0x47, 0x25, 0xFA, 0x00, 0x7E, 0x60, 0x47,
+	 0x01, 0x26, 0xDC, 0x84, 0x60, 0x41, 0xE8, 0x84, 0xD8, 0x84, 0x23, 0xFA, 0xAB, 0x01, 0xFC, 0xA3,
+	 0xA3, 0xD1, 0x4C, 0x65, 0xA4, 0xD3, 0xDA, 0x83, 0x00, 0x7F, 0x25, 0xFA, 0x60, 0x41, 0x01, 0x26,
+	 0xDD, 0x81, 0xE9, 0x84, 0xD8, 0x84, 0x23, 0xFA, 0x9D, 0x01, 0x23, 0xF2, 0x12, 0x60, 0xB8, 0x65,
+	 0x60, 0x41, 0x12, 0x60, 0x54, 0x63, 0xA3, 0xDB, 0xFF, 0xA1, 0x48, 0x64, 0x58, 0xD0, 0x7E, 0xA8,
+	 0x5B, 0xD9, 0x02, 0x02, 0x00, 0xF4, 0x02, 0x64, 0xFF, 0xA1, 0xD7, 0x80, 0x02, 0x03, 0x01, 0x03,
+	 0xF5, 0x01, 0x2E, 0xF5, 0x00, 0x60, 0x2F, 0x65, 0x25, 0xF2, 0x00, 0x63, 0xCC, 0x84, 0x03, 0xA3,
+	 0xFD, 0x05, 0x4A, 0x64, 0xD7, 0x80, 0x11, 0x60, 0xF0, 0x61, 0x2F, 0x05, 0xA1, 0xDD, 0xE3, 0x83,
+	 0xFE, 0xA3, 0x58, 0xD0, 0x7E, 0xA8, 0x59, 0xD9, 0x02, 0x02, 0x00, 0xF4, 0x02, 0x64, 0xF9, 0x1F,
+	 0x00, 0x63, 0x59, 0xDD, 0x2E, 0xF5, 0x11, 0x60, 0xF0, 0x64, 0x25, 0xF0, 0xA0, 0xD3, 0xD3, 0x80,
+	 0x01, 0xB0, 0x04, 0x03, 0x01, 0xA4, 0x03, 0x03, 0xA2, 0xDB, 0x01, 0x00, 0xA2, 0xDD, 0x11, 0x60,
+	 0xF8, 0x63, 0x10, 0x60, 0x0A, 0x65, 0xBD, 0xD3, 0xBD, 0xD1, 0xE0, 0x84, 0xC4, 0x82, 0x10, 0x60,
+	 0x2A, 0x65, 0x07, 0x64, 0x64, 0x41, 0x5A, 0xDB, 0xD6, 0x80, 0xCD, 0x81, 0x06, 0x03, 0xFB, 0x02,
+	 0x25, 0xF2, 0x02, 0xA3, 0xCC, 0x84, 0xA2, 0xDA, 0xEC, 0x02, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x12, 0x60, 0x54, 0x61, 0xA1, 0xD3, 0x23, 0xFA, 0xE0, 0x83, 0x4A, 0x65, 0x04, 0x02, 0x02, 0x63,
+	 0x23, 0xFC, 0xA5, 0xFC, 0x09, 0x00, 0xDB, 0x83, 0x59, 0xD1, 0xA5, 0xD8, 0xDA, 0x85, 0x80, 0x3A,
+	 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0xF8, 0x1F, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x11, 0x60,
+	 0xF0, 0x62, 0xA2, 0xD3, 0x00, 0x61, 0x02, 0xA4, 0xFE, 0xA0, 0x23, 0xFA, 0x1B, 0x03, 0xFA, 0xA4,
+	 0xFD, 0xA4, 0x01, 0xA1, 0xFD, 0x07, 0x61, 0x43, 0x23, 0xF2, 0x25, 0xFC, 0xE0, 0x83, 0x02, 0xA3,
+	 0x11, 0x60, 0xF0, 0x61, 0x00, 0x60, 0x4A, 0x64, 0x59, 0xD1, 0x58, 0xD8, 0x7E, 0x3A, 0x02, 0x00,
+	 0x00, 0xF4, 0x02, 0x64, 0xF9, 0x1F, 0x25, 0xF2, 0x23, 0xF2, 0x01, 0xB0, 0xCC, 0x84, 0x04, 0x02,
+	 0x23, 0xFA, 0x02, 0x00, 0x00, 0x64, 0x25, 0xFA, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x41, 0x4B,
+	 0x65, 0x42, 0x80, 0x64, 0xD4, 0x85, 0x2B, 0x41, 0x00, 0xA1, 0x55, 0x8B, 0x0D, 0x03, 0x02, 0x04,
+	 0x65, 0x41, 0x02, 0x00, 0x00, 0x64, 0x40, 0x4B, 0xCA, 0x84, 0x58, 0xD0, 0xC9, 0x81, 0xBD, 0xD9,
+	 0xFC, 0x02, 0x00, 0xF4, 0x04, 0x65, 0xEC, 0x01, 0x2F, 0x58, 0xFF, 0xFF, 0xFC, 0xA3, 0xA3, 0xD3,
+	 0x02, 0x7C, 0xA0, 0xD3, 0x23, 0xF8, 0xDC, 0x84, 0x25, 0xFA, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x02, 0x64, 0x23, 0xFA, 0x01, 0x64, 0x9D, 0xFE, 0x02, 0x28, 0x02, 0x64, 0x25, 0xFA, 0x00, 0x67,
+	 0x23, 0x58, 0xFF, 0xFF, 0x21, 0x60, 0x80, 0x62, 0xA2, 0xD3, 0x02, 0x7C, 0x23, 0xF8, 0x01, 0xB4,
+	 0x25, 0xFA, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0xFC, 0xA3, 0xA3, 0xD1, 0x02, 0x64, 0x23, 0xFA,
+	 0x64, 0x44, 0x7C, 0x5F, 0x60, 0x45, 0x64, 0x47, 0x7C, 0x5F, 0x89, 0xF1, 0x66, 0x41, 0xC0, 0x86,
+	 0xA5, 0xD2, 0x61, 0x46, 0x00, 0x63, 0x60, 0x40, 0x0A, 0x37, 0x01, 0x63, 0x14, 0x37, 0x02, 0x63,
+	 0x37, 0x37, 0x06, 0x63, 0x6E, 0x37, 0x0B, 0x63, 0x25, 0xFC, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x02, 0x64, 0x23, 0xFA, 0x88, 0xFF, 0x75, 0x44, 0x8D, 0xFF, 0xE8, 0x87, 0xE8, 0x84, 0xE8, 0x84,
+	 0x03, 0xB4, 0x25, 0xFA, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x25, 0xF0, 0x21, 0x60, 0x7C, 0x65,
+	 0x23, 0xF2, 0xA5, 0xD9, 0x02, 0xA8, 0x64, 0x44, 0x07, 0x02, 0x00, 0xBC, 0xF2, 0xA4, 0x04, 0x03,
+	 0x03, 0x07, 0x1F, 0x60, 0xAA, 0x62, 0xA2, 0xD9, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x20, 0x63,
+	 0x20, 0x60, 0x0A, 0x61, 0x48, 0x64, 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0x25, 0xF0, 0x20, 0x64,
+	 0xD0, 0x81, 0xFF, 0xFF, 0x02, 0x07, 0x25, 0xFA, 0x0F, 0x00, 0x20, 0x60, 0x0E, 0x63, 0xC3, 0x83,
+	 0x01, 0x2A, 0x06, 0x00, 0xCF, 0x83, 0xA3, 0xD3, 0xCD, 0x81, 0x00, 0x7F, 0xBD, 0xDB, 0x04, 0x03,
+	 0x00, 0x64, 0xC9, 0x81, 0xBD, 0xDB, 0xFD, 0x02, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x23, 0xF2,
+	 0x25, 0xF0, 0x01, 0x60, 0x70, 0x63, 0xA3, 0xD9, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0xFC, 0xA3,
+	 0xA5, 0xF0, 0xA3, 0xD1, 0xFF, 0xFF, 0x64, 0x5E, 0x00, 0x7F, 0x60, 0x41, 0x64, 0x47, 0x7C, 0x5F,
+	 0x89, 0xF1, 0x66, 0x43, 0xC0, 0x86, 0x65, 0x44, 0xA1, 0xDA, 0x63, 0x46, 0x00, 0x67, 0x23, 0x58,
+	 0xFF, 0xFF, 0xFC, 0xA3, 0xA3, 0xD1, 0xFF, 0xFF, 0x64, 0x5E, 0x00, 0x7F, 0x60, 0x45, 0x64, 0x47,
+	 0x7C, 0x5F, 0x89, 0xF1, 0x66, 0x41, 0xC0, 0x86, 0x65, 0x44, 0xA0, 0xD2, 0x61, 0x46, 0x25, 0xFA,
+	 0x02, 0x64, 0x23, 0xFA, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x23, 0xF2, 0x25, 0xF0, 0x02, 0xA8,
+	 0x00, 0x67, 0x02, 0x02, 0x2D, 0xF9, 0x2C, 0xF9, 0x23, 0x58, 0xFF, 0xFF, 0x1F, 0x60, 0xA8, 0x61,
+	 0x23, 0xF2, 0x25, 0xF2, 0x02, 0xA8, 0x00, 0xA8, 0x09, 0x02, 0x07, 0x03, 0xD0, 0xA0, 0x30, 0x65,
+	 0x03, 0x04, 0xA7, 0xA0, 0x59, 0x65, 0x01, 0x06, 0x65, 0x44, 0xA1, 0xDB, 0x00, 0x67, 0x23, 0x58,
+	 0xFF, 0xFF, 0x04, 0x61, 0x0A, 0x00, 0x25, 0x60, 0x2C, 0x61, 0x01, 0x64, 0xA1, 0xDB, 0x04, 0x00,
+	 0x25, 0x60, 0x2C, 0x61, 0x00, 0x64, 0xA1, 0xDB, 0x06, 0x61, 0x41, 0x56, 0xC7, 0xFE, 0xEB, 0x60,
+	 0x84, 0x78, 0xFF, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0xA2, 0xFF, 0x46, 0x45, 0x02, 0xF0,
+	 0x09, 0x60, 0x08, 0x64, 0xD0, 0x80, 0x00, 0xF4, 0x01, 0xF2, 0x66, 0x5C, 0x25, 0x46, 0x56, 0x02,
+	 0x70, 0x27, 0x54, 0x00, 0x12, 0x64, 0x03, 0xFA, 0x04, 0xF8, 0x0E, 0xF2, 0x87, 0xFC, 0x8D, 0xFC,
+	 0x8E, 0xFC, 0xDA, 0x82, 0x16, 0x61, 0x00, 0x63, 0xC9, 0x81, 0x5A, 0xDC, 0xFD, 0x02, 0x60, 0x40,
+	 0xF0, 0x3B, 0x16, 0x00, 0x32, 0x44, 0x8F, 0xF3, 0x01, 0xB0, 0xF6, 0xA0, 0x08, 0x24, 0x2C, 0x05,
+	 0xDC, 0x83, 0xF0, 0x67, 0x0E, 0xFA, 0x1B, 0x60, 0xC4, 0x64, 0x2B, 0xDB, 0x66, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0x8F, 0xFD, 0x2B, 0xFF, 0xFE, 0x64, 0x3B, 0x42, 0x4A, 0xDB, 0x4F, 0x00,
+	 0x90, 0xF3, 0x0A, 0x65, 0xD4, 0x80, 0xDC, 0x83, 0x17, 0x05, 0x90, 0xFD, 0x98, 0xFE, 0x04, 0x04,
+	 0x00, 0x7F, 0x08, 0x7E, 0x0E, 0xFA, 0x3B, 0xFF, 0x1B, 0x60, 0xB8, 0x64, 0x2B, 0xDB, 0x66, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0x0E, 0xF2, 0x2B, 0xFF, 0x60, 0x40, 0x08, 0x26, 0xF7, 0xFE,
+	 0xFD, 0x64, 0x3B, 0x42, 0x4A, 0xDB, 0x32, 0x00, 0x8C, 0xF3, 0xFF, 0xFF, 0xD8, 0xA0, 0xFF, 0xFF,
+	 0x0D, 0x04, 0x1B, 0x60, 0xD0, 0x64, 0x2B, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB,
+	 0xFF, 0xFF, 0x2B, 0xFF, 0xFC, 0x64, 0x3B, 0x42, 0x4A, 0xDB, 0x21, 0x00, 0x46, 0x45, 0x00, 0x64,
+	 0x2B, 0xDB, 0x25, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xA2, 0xFF,
+	 0x00, 0xF4, 0x01, 0xF0, 0x0A, 0x18, 0x70, 0x67, 0xA0, 0x80, 0xF0, 0x67, 0x06, 0x03, 0xC0, 0x84,
+	 0x01, 0xFA, 0x25, 0x46, 0x25, 0x44, 0x80, 0xFC, 0x05, 0xFA, 0xB4, 0x60, 0x58, 0x4E, 0x48, 0x78,
+	 0xFF, 0xFF, 0xD4, 0xFE, 0xA3, 0xFF, 0xFF, 0x64, 0x3B, 0x42, 0x4A, 0xDB, 0xD4, 0xFE, 0xA3, 0xFF,
+	 0x2D, 0x58, 0xFF, 0xFF, 0x1B, 0x60, 0xBE, 0x64, 0x40, 0x47, 0x58, 0x4F, 0x0D, 0x00, 0x1B, 0x60,
+	 0xB2, 0x64, 0x40, 0x47, 0x58, 0x4F, 0x18, 0x00, 0x1B, 0x60, 0xCA, 0x64, 0x40, 0x47, 0x58, 0x4F,
+	 0x03, 0x00, 0xEB, 0x60, 0x84, 0x78, 0xFF, 0xFF, 0x27, 0xD5, 0x0E, 0xF2, 0x0B, 0x18, 0x60, 0x40,
+	 0x01, 0x2A, 0x08, 0x00, 0x1B, 0x60, 0xE0, 0x64, 0x40, 0x4B, 0xF0, 0x60, 0x58, 0x4D, 0x75, 0x78,
+	 0xFF, 0xFF, 0xF2, 0x01, 0x2F, 0x58, 0xFF, 0xFF, 0x27, 0xD5, 0x0E, 0xF2, 0x14, 0x18, 0x60, 0x40,
+	 0x01, 0x2A, 0x11, 0x00, 0x02, 0xF0, 0x09, 0x60, 0x08, 0x64, 0xD0, 0x80, 0xA2, 0xFF, 0x90, 0xF3,
+	 0x02, 0x02, 0xCC, 0x84, 0x90, 0xFB, 0x1B, 0x60, 0xE0, 0x64, 0x40, 0x4B, 0xF0, 0x60, 0x58, 0x4D,
+	 0x75, 0x78, 0xFF, 0xFF, 0xE9, 0x01, 0x2F, 0x58, 0xFF, 0xFF, 0xFB, 0x64, 0x3A, 0x42, 0x4A, 0xDB,
+	 0xA2, 0xFF, 0x93, 0xF3, 0x8F, 0xF3, 0xCC, 0x80, 0xFA, 0xA0, 0x01, 0x14, 0x1E, 0x05, 0xB3, 0x60,
+	 0x58, 0x4D, 0x4E, 0x78, 0xFF, 0xFF, 0xA2, 0xFF, 0x18, 0x03, 0xF0, 0x67, 0x0E, 0xFA, 0x1B, 0x60,
+	 0xE0, 0x62, 0x1B, 0x60, 0xC4, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB,
+	 0xFF, 0xFF, 0x2B, 0xFF, 0xF6, 0x64, 0x3A, 0x42, 0x4A, 0xDB, 0x93, 0xF3, 0x8F, 0xF3, 0xCC, 0x83,
+	 0xDC, 0x84, 0x01, 0x15, 0x93, 0xFD, 0x8F, 0xFB, 0xD4, 0xFE, 0x92, 0xF3, 0x90, 0xF3, 0x00, 0xA8,
+	 0x91, 0xF1, 0x03, 0x02, 0xD0, 0x80, 0xFF, 0xFF, 0x27, 0x05, 0xB3, 0x60, 0x58, 0x4D, 0x4E, 0x78,
+	 0xFF, 0xFF, 0xA2, 0xFF, 0x21, 0x03, 0x00, 0x63, 0x92, 0xF3, 0x0E, 0xFC, 0xCC, 0x84, 0xFF, 0x3A,
+	 0x92, 0xFB, 0x98, 0xFE, 0x03, 0x04, 0x08, 0xBB, 0x0E, 0xFC, 0x3B, 0xFF, 0x1B, 0x60, 0xE0, 0x62,
+	 0x1B, 0x60, 0xB8, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0xF7, 0x64, 0x3A, 0x42, 0x4A, 0xDB, 0x90, 0xF3, 0x0E, 0xF2, 0xDC, 0x83, 0x08, 0xB0,
+	 0x90, 0xFD, 0x08, 0x28, 0xF7, 0xFE, 0xD4, 0xFE, 0xA3, 0xFF, 0xEB, 0x60, 0x84, 0x78, 0xFF, 0xFF,
+	 0xB9, 0xFE, 0x13, 0xFF, 0x24, 0x40, 0x80, 0x2B, 0x0B, 0x00, 0xA2, 0xFF, 0x25, 0x46, 0x09, 0xF4,
+	 0x0E, 0xF2, 0x05, 0x18, 0x08, 0xBC, 0x0E, 0xFA, 0xFF, 0xFF, 0xF7, 0xFE, 0x01, 0x00, 0xD8, 0xFE,
+	 0xA3, 0xFF, 0x25, 0x46, 0x3E, 0xF2, 0x00, 0xF4, 0x08, 0xF0, 0x25, 0x46, 0x06, 0xB4, 0xFF, 0x7F,
+	 0x10, 0xBC, 0x06, 0x26, 0xFD, 0x7F, 0x0E, 0xFA, 0x3E, 0xF2, 0x3F, 0xF2, 0x60, 0x41, 0x08, 0x2A,
+	 0x64, 0x47, 0x3F, 0xFA, 0x60, 0x45, 0x1F, 0x60, 0x62, 0x62, 0xA2, 0xD3, 0xA3, 0xFC, 0xAB, 0xFC,
+	 0x91, 0xFC, 0xD4, 0x80, 0xE0, 0x60, 0xC1, 0x65, 0xA5, 0x80, 0x01, 0x04, 0x07, 0x03, 0x23, 0xF0,
+	 0x08, 0x64, 0xB0, 0x84, 0xA2, 0xDA, 0xF2, 0x60, 0x25, 0x78, 0xFF, 0xFF, 0xF4, 0x60, 0x58, 0x4F,
+	 0x2D, 0x78, 0xFF, 0xFF, 0x14, 0x04, 0x23, 0xF0, 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDA, 0x98, 0xF1,
+	 0x1E, 0x60, 0xFC, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03,
+	 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x02, 0x00, 0x20, 0x60, 0x00, 0x75, 0x46, 0x00, 0x3E, 0xF0,
+	 0x89, 0xF1, 0x64, 0x47, 0x07, 0xB4, 0x07, 0x36, 0x3B, 0x00, 0x04, 0x03, 0xCC, 0x84, 0xE0, 0x84,
+	 0xC0, 0x83, 0x2D, 0x00, 0x2C, 0xF2, 0x88, 0xF1, 0x01, 0xB0, 0x64, 0x43, 0x35, 0x02, 0x2E, 0xF2,
+	 0x12, 0x60, 0xCE, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46,
+	 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46, 0x2E, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2,
+	 0x0C, 0x02, 0x61, 0x46, 0x2D, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46,
+	 0x2C, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46,
+	 0xE8, 0x1B, 0x88, 0xF3, 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0x01, 0x03, 0x09, 0x00, 0x66, 0x45,
+	 0x63, 0x46, 0x06, 0xF0, 0x65, 0x46, 0x64, 0x44, 0x0C, 0x26, 0x02, 0x00, 0x02, 0x26, 0x04, 0x00,
+	 0x23, 0xF0, 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDA, 0x07, 0xFC, 0x23, 0xF2, 0xFF, 0xFF, 0x10, 0x1B,
+	 0x1B, 0x60, 0xE0, 0x62, 0x1B, 0x60, 0x9A, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x0E, 0xF2, 0xC8, 0xFE, 0x10, 0xAC, 0x0E, 0xFA, 0x0F, 0x00,
+	 0x1B, 0x60, 0xE0, 0x62, 0x1B, 0x60, 0xAC, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x0E, 0xF2, 0xCE, 0xFE, 0x10, 0xAC, 0x0E, 0xFA, 0xEB, 0x60,
+	 0x84, 0x78, 0xFF, 0xFF, 0xCB, 0x84, 0xC9, 0x83, 0xFF, 0xFF, 0x08, 0x04, 0x58, 0xD1, 0xA5, 0xD8,
+	 0xDA, 0x85, 0x80, 0x3A, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0xF8, 0x1F, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x25, 0xF0, 0x21, 0x60, 0x2C, 0x62, 0xA2, 0xD9, 0x19, 0x00, 0x21, 0x60, 0x80, 0x64, 0xA0, 0xD1,
+	 0x7F, 0xF9, 0x0C, 0x60, 0x38, 0x62, 0x40, 0x63, 0x00, 0x64, 0x5A, 0xDB, 0xFE, 0x1F, 0x64, 0x40,
+	 0x01, 0x2A, 0x0C, 0x00, 0x04, 0x65, 0x0C, 0x60, 0x38, 0x61, 0x48, 0x64, 0x3E, 0x63, 0x7C, 0xA8,
+	 0x58, 0xD0, 0x59, 0xD9, 0x02, 0x02, 0x00, 0xF4, 0x02, 0x64, 0xF9, 0x1F, 0x21, 0x60, 0x2C, 0x62,
+	 0xA2, 0xD1, 0x0D, 0x60, 0x1C, 0x65, 0x02, 0xFE, 0x64, 0x44, 0xF8, 0x84, 0xF8, 0x84, 0xF8, 0x87,
+	 0x60, 0x41, 0x64, 0x44, 0xE0, 0x84, 0xE0, 0x84, 0xC4, 0x84, 0x3E, 0xFB, 0x60, 0x42, 0x61, 0x44,
+	 0x03, 0xA2, 0x60, 0xFE, 0xA2, 0xDB, 0xFF, 0xFF, 0x20, 0xFE, 0x64, 0x44, 0x0C, 0x60, 0x3A, 0x65,
+	 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xC4, 0x84, 0x40, 0xFB, 0xFF, 0xFF, 0x00, 0x67,
+	 0x00, 0x61, 0x23, 0x58, 0xFF, 0xFF, 0x21, 0x60, 0x80, 0x64, 0xA0, 0xD1, 0x7F, 0xF9, 0x00, 0x64,
+	 0x40, 0x41, 0x64, 0x40, 0x01, 0x2A, 0xA6, 0x00, 0x4A, 0x64, 0xA0, 0xD2, 0xFF, 0xFF, 0x40, 0x42,
+	 0x80, 0x2B, 0x04, 0x00, 0xFF, 0xB4, 0x40, 0x42, 0x01, 0x64, 0x40, 0x41, 0x88, 0xF3, 0x46, 0x4B,
+	 0x87, 0xF3, 0x60, 0x46, 0xE0, 0x83, 0xAB, 0x46, 0x26, 0xF0, 0xAB, 0x46, 0x55, 0xF8, 0xAB, 0x46,
+	 0x27, 0xF0, 0xAB, 0x46, 0x56, 0xF8, 0xAB, 0x46, 0x28, 0xF0, 0xAB, 0x46, 0x57, 0xF8, 0x66, 0x44,
+	 0x02, 0xA6, 0xF1, 0x1F, 0x88, 0xF3, 0xFF, 0xFF, 0x60, 0x46, 0xAB, 0x46, 0x0C, 0x60, 0x7A, 0x65,
+	 0x22, 0x44, 0xFF, 0xB4, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xC4, 0x81, 0xC9, 0x81,
+	 0x52, 0x64, 0x0E, 0x63, 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0x21, 0x44, 0x01, 0x2A, 0x08, 0x00,
+	 0xAB, 0x46, 0xF0, 0xA1, 0x6E, 0x64, 0x0E, 0x63, 0x59, 0xD1, 0x58, 0xD8, 0xFD, 0x1F, 0xAB, 0x46,
+	 0x22, 0x44, 0xFF, 0xB4, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0x0C, 0x60, 0xDC, 0x65, 0xC4, 0x81,
+	 0x60, 0x45, 0xC9, 0x81, 0x62, 0x64, 0x06, 0x63, 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0x21, 0x44,
+	 0x01, 0x2A, 0x08, 0x00, 0xAB, 0x46, 0xF8, 0xA1, 0xAE, 0x64, 0x06, 0x63, 0x59, 0xD1, 0x58, 0xD8,
+	 0xFD, 0x1F, 0xAB, 0x46, 0x65, 0x44, 0x0C, 0x60, 0xFC, 0x65, 0xC4, 0x81, 0xC9, 0x81, 0x6A, 0x64,
+	 0x06, 0x63, 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0x22, 0x44, 0xFF, 0xB4, 0xE0, 0x84, 0xE0, 0x85,
+	 0xC4, 0x84, 0x0C, 0x60, 0xC2, 0x65, 0xC4, 0x81, 0x72, 0x64, 0x04, 0x63, 0x58, 0xD0, 0x59, 0xD9,
+	 0xFD, 0x1F, 0xAB, 0x46, 0x21, 0x44, 0x01, 0x2A, 0x06, 0x00, 0xFA, 0xA1, 0x88, 0x64, 0x04, 0x63,
+	 0x59, 0xD1, 0x58, 0xD8, 0xFD, 0x1F, 0x37, 0xF0, 0x21, 0x44, 0x01, 0x2A, 0x13, 0x00, 0x22, 0x44,
+	 0x3D, 0xFB, 0x60, 0x41, 0x02, 0xFE, 0xF8, 0x84, 0xF8, 0x84, 0xF8, 0x84, 0x3C, 0xFB, 0x0C, 0x60,
+	 0xBE, 0x63, 0x88, 0xFF, 0xCD, 0x81, 0x06, 0xA3, 0xFD, 0x0D, 0x8D, 0xFF, 0x3B, 0xFD, 0x64, 0x47,
+	 0x80, 0xBF, 0x60, 0x5C, 0x22, 0x43, 0x80, 0x61, 0x88, 0xFF, 0xCF, 0x83, 0xE1, 0x81, 0xFD, 0x0D,
+	 0x8D, 0xFF, 0x61, 0x47, 0x31, 0x91, 0xB1, 0x84, 0x37, 0xFA, 0x87, 0xF3, 0xFF, 0xFF, 0xCC, 0x83,
+	 0xE3, 0x83, 0x66, 0x44, 0x02, 0xA6, 0x37, 0xF0, 0x66, 0x44, 0xB1, 0x9C, 0x37, 0xF8, 0x02, 0xA6,
+	 0xFA, 0x1F, 0xAB, 0x46, 0x00, 0x67, 0x00, 0x61, 0x23, 0x58, 0xFF, 0xFF, 0x23, 0xF2, 0x25, 0xF0,
+	 0x02, 0xA8, 0x00, 0x67, 0x24, 0x02, 0x3D, 0xF1, 0x64, 0x44, 0x03, 0xB4, 0x40, 0x42, 0xD0, 0x80,
+	 0x88, 0xF3, 0xFF, 0xFF, 0x60, 0x46, 0xB7, 0xF4, 0x80, 0x61, 0x02, 0x02, 0xE3, 0x83, 0xEB, 0x83,
+	 0x22, 0x44, 0x88, 0xFF, 0xCC, 0x84, 0xE1, 0x81, 0xFD, 0x0D, 0x8D, 0xFF, 0x61, 0x47, 0x31, 0x91,
+	 0x9D, 0x85, 0xA7, 0x83, 0x37, 0xFC, 0x87, 0xF3, 0xFF, 0xFF, 0xCC, 0x83, 0xE3, 0x83, 0x66, 0x44,
+	 0x02, 0xA6, 0xB7, 0xF2, 0x66, 0x44, 0xA5, 0x81, 0xB7, 0xFA, 0x02, 0xA6, 0xFA, 0x1F, 0x00, 0x67,
+	 0x23, 0x58, 0xFF, 0xFF, 0x11, 0x64, 0x23, 0xFA, 0x25, 0x44, 0x24, 0xFA, 0x04, 0x64, 0x40, 0x4B,
+	 0x62, 0x41, 0x0C, 0x60, 0xC2, 0x64, 0x04, 0x63, 0x58, 0xD1, 0x59, 0xD8, 0xFD, 0x1F, 0x2B, 0x43,
+	 0x00, 0x7C, 0x59, 0xD8, 0x4F, 0x8B, 0x06, 0xA4, 0xF6, 0x02, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x21, 0x60, 0x80, 0x64, 0xA0, 0xD1, 0x7F, 0xF9, 0x64, 0x40, 0x01, 0x2A, 0x4E, 0x00, 0x27, 0xF2,
+	 0x12, 0x60, 0xCE, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46,
+	 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46, 0x27, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2,
+	 0x0C, 0x02, 0x61, 0x46, 0x26, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46,
+	 0x25, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46,
+	 0xE8, 0x1B, 0x88, 0xF3, 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0x01, 0x03, 0x2A, 0x00, 0x43, 0x4B,
+	 0xAB, 0x46, 0x37, 0xF2, 0x80, 0x60, 0x30, 0x7C, 0xB0, 0x84, 0xA2, 0xDA, 0x4E, 0x61, 0x6E, 0x64,
+	 0x0E, 0x63, 0xAB, 0x46, 0x59, 0xD0, 0xAB, 0x46, 0x58, 0xD8, 0xFB, 0x1F, 0x88, 0x64, 0x04, 0x63,
+	 0xAB, 0x46, 0x59, 0xD0, 0xAB, 0x46, 0x58, 0xD8, 0xFB, 0x1F, 0xD9, 0x81, 0x98, 0x64, 0x04, 0x63,
+	 0xAB, 0x46, 0x59, 0xD0, 0xAB, 0x46, 0x58, 0xD8, 0xFB, 0x1F, 0xD9, 0x81, 0xAE, 0x64, 0x0E, 0x63,
+	 0xAB, 0x46, 0x59, 0xD0, 0xAB, 0x46, 0x58, 0xD8, 0xFB, 0x1F, 0x00, 0x67, 0x00, 0x61, 0x23, 0x58,
+	 0xFF, 0xFF, 0x01, 0x67, 0x20, 0x61, 0x23, 0x58, 0xFF, 0xFF, 0x21, 0x60, 0x80, 0x64, 0xA0, 0xD1,
+	 0x7F, 0xF9, 0x64, 0x40, 0x01, 0x2A, 0x31, 0x00, 0x27, 0xF2, 0x12, 0x60, 0xCE, 0x65, 0x60, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18,
+	 0x61, 0x46, 0x27, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46, 0x26, 0xF0,
+	 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46, 0x25, 0xF0, 0x63, 0x46, 0xD0, 0x80,
+	 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46, 0xE8, 0x1B, 0x88, 0xF3, 0x08, 0xFE,
+	 0x60, 0x43, 0x61, 0x46, 0x01, 0x03, 0x0D, 0x00, 0x43, 0x4B, 0xAB, 0x46, 0x37, 0xF2, 0x80, 0x60,
+	 0x30, 0x61, 0x9D, 0x85, 0xA4, 0x84, 0xA2, 0xDA, 0xAB, 0x46, 0x00, 0x67, 0x00, 0x61, 0x23, 0x58,
+	 0xFF, 0xFF, 0x01, 0x67, 0x20, 0x61, 0x23, 0x58, 0xFF, 0xFF, 0x3E, 0xF2, 0xAC, 0xF1, 0x08, 0xB0,
+	 0x19, 0xF8, 0x4A, 0x02, 0x07, 0x23, 0x2B, 0x00, 0x60, 0x47, 0x07, 0xB4, 0x89, 0xF1, 0xCC, 0x84,
+	 0xE0, 0x84, 0x40, 0x8A, 0xAA, 0x46, 0x03, 0xF2, 0x04, 0xF0, 0x05, 0xF2, 0x60, 0x43, 0xAA, 0x46,
+	 0x2C, 0xFC, 0x2D, 0xF8, 0x2E, 0xFA, 0xCB, 0xF1, 0x2F, 0xF8, 0xCC, 0xF1, 0x30, 0xF8, 0xCD, 0xF1,
+	 0x31, 0xF8, 0x46, 0x4A, 0x00, 0xF4, 0x02, 0xF2, 0x03, 0xF0, 0x04, 0xF2, 0x60, 0x43, 0xAA, 0x46,
+	 0x32, 0xFC, 0x33, 0xF8, 0x34, 0xFA, 0xAA, 0x46, 0x05, 0xF2, 0x06, 0xF0, 0x07, 0xF2, 0x60, 0x43,
+	 0xAA, 0x46, 0x36, 0xFC, 0x37, 0xF8, 0x38, 0xFA, 0x03, 0x60, 0x08, 0x64, 0x1C, 0x00, 0x67, 0xF1,
+	 0x2F, 0xF8, 0x68, 0xF1, 0x30, 0xF8, 0x69, 0xF1, 0x31, 0xF8, 0x46, 0x4A, 0x00, 0xF4, 0x02, 0xF2,
+	 0x03, 0xF0, 0x04, 0xF2, 0x60, 0x43, 0xAA, 0x46, 0x2C, 0xFC, 0x2D, 0xF8, 0x2E, 0xFA, 0xAA, 0x46,
+	 0x05, 0xF2, 0x06, 0xF0, 0x07, 0xF2, 0x60, 0x43, 0xAA, 0x46, 0x32, 0xFC, 0x33, 0xF8, 0x34, 0xFA,
+	 0x02, 0x60, 0x08, 0x64, 0x00, 0x00, 0x2A, 0xFA, 0x02, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x28, 0xF3,
+	 0xFF, 0xFF, 0x60, 0x47, 0x0F, 0xB4, 0x59, 0x00, 0xFF, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x1C, 0x60,
+	 0x04, 0x65, 0x04, 0x64, 0xA5, 0xDB, 0x12, 0x00, 0x1C, 0x60, 0x04, 0x65, 0x0C, 0x64, 0xA5, 0xDB,
+	 0x0D, 0x00, 0x1C, 0x60, 0x04, 0x65, 0x06, 0x64, 0xA5, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x00, 0x67,
+	 0x23, 0x58, 0xFF, 0xFF, 0x1C, 0x60, 0x04, 0x65, 0x08, 0x64, 0xA5, 0xDB, 0xF4, 0x60, 0xD9, 0x64,
+	 0x80, 0xFB, 0xFF, 0xFF, 0x2D, 0xFF, 0xEB, 0x60, 0x84, 0x78, 0xFF, 0xFF, 0x29, 0xF3, 0x65, 0xFB,
+	 0x83, 0xFB, 0x02, 0x60, 0xEE, 0x64, 0x82, 0xFB, 0x07, 0x64, 0x84, 0xFB, 0xF4, 0x60, 0xD9, 0x64,
+	 0x80, 0xFB, 0xFF, 0xFF, 0xDF, 0xFE, 0x00, 0x64, 0x19, 0xFF, 0xEB, 0x60, 0x84, 0x78, 0xFF, 0xFF,
+	 0xAF, 0x60, 0xFD, 0x63, 0x0C, 0x60, 0x16, 0x64, 0xA0, 0xDD, 0x62, 0xFF, 0xF4, 0x60, 0xC6, 0x63,
+	 0x80, 0xFD, 0xFF, 0xFF, 0x1A, 0xFF, 0xEB, 0x60, 0x84, 0x78, 0xFF, 0xFF, 0xA7, 0x60, 0x9B, 0x63,
+	 0x0C, 0x60, 0x16, 0x64, 0xA0, 0xDD, 0x62, 0xFF, 0x29, 0xF5, 0x1B, 0x60, 0xE0, 0x63, 0x1B, 0x60,
+	 0xB2, 0x64, 0xBD, 0xDB, 0x66, 0x44, 0xBD, 0xDB, 0x02, 0x64, 0xA3, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0xF9, 0xFE, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0xA7, 0x01, 0x00, 0x36, 0xA8, 0x01, 0x01, 0x36,
+	 0xAB, 0x01, 0x02, 0x36, 0xAE, 0x01, 0x03, 0x36, 0xB5, 0x01, 0x04, 0x36, 0xD1, 0x01, 0x05, 0x36,
+	 0xCF, 0x01, 0x06, 0x36, 0xF1, 0x01, 0x07, 0x36, 0xCB, 0x01, 0x08, 0x36, 0xB7, 0x01, 0x09, 0x36,
+	 0x0C, 0x00, 0x0A, 0x36, 0x0D, 0x00, 0x0B, 0x36, 0x0E, 0x00, 0x0C, 0x36, 0x17, 0x00, 0x0D, 0x36,
+	 0x0D, 0x00, 0x0E, 0x36, 0x1E, 0x00, 0x0F, 0x36, 0x32, 0x00, 0x02, 0x60, 0x00, 0x64, 0x08, 0x00,
+	 0x04, 0x60, 0x00, 0x64, 0x05, 0x00, 0x00, 0x60, 0x01, 0x64, 0x02, 0x00, 0x20, 0x60, 0x00, 0x64,
+	 0x32, 0x45, 0xB4, 0x85, 0x45, 0x52, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0xB0, 0x60, 0xC1, 0x63,
+	 0x0C, 0x60, 0x16, 0x64, 0xA0, 0xDD, 0x62, 0xFF, 0xFF, 0xFF, 0x1A, 0xFF, 0x00, 0x67, 0x23, 0x58,
+	 0xFF, 0xFF, 0x3F, 0x40, 0x02, 0x2B, 0x05, 0x00, 0x90, 0x60, 0x00, 0xE8, 0xAF, 0x60, 0xFD, 0x63,
+	 0x04, 0x00, 0x91, 0x60, 0x00, 0xE8, 0xB0, 0x60, 0xAB, 0x63, 0x28, 0xE8, 0x0C, 0x60, 0x16, 0x64,
+	 0xA0, 0xDD, 0x62, 0xFF, 0xFF, 0xFF, 0x1A, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x91, 0x60,
+	 0x00, 0xE8, 0x28, 0xE8, 0xD9, 0x60, 0xFE, 0x64, 0x32, 0x45, 0xA4, 0x85, 0x45, 0x52, 0x99, 0xFF,
+	 0xA5, 0x4F, 0xFF, 0xB4, 0x07, 0xFB, 0x98, 0xFF, 0xA7, 0x60, 0x9B, 0x63, 0x0C, 0x60, 0x16, 0x64,
+	 0xA0, 0xDD, 0x62, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x42, 0x6F, 0x6F, 0x74, 0x63, 0x6F,
+	 0x64, 0x65, 0x20, 0x21, 0x21, 0x20, 0x20, 0x00, 0x53, 0x54, 0x41, 0x2F, 0x41, 0x50, 0x20, 0x46,
+	 0x75, 0x6E, 0x63, 0x27, 0x73, 0x00, 0x20, 0x00, 0x02, 0x00, 0x02, 0x00, 0x24, 0x00, 0x00, 0x00,
+	 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x01, 0x00, 0x04, 0x00, 0x06, 0x00,
+	 0x07, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x06, 0x00, 0x06, 0x00, 0x07, 0x00, 0x01, 0x00,
+	 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00,
+	 0x40, 0x00, 0x32, 0x00, 0x32, 0x00, 0x0A, 0x00, 0x02, 0x00, 0x06, 0x00, 0x40, 0x00, 0x32, 0x00,
+	 0x36, 0x00, 0x0A, 0x00, 0x02, 0x00, 0x06, 0x00, 0x40, 0x00, 0x3B, 0x00, 0x40, 0x00, 0x17, 0x00,
+	 0x07, 0x00, 0x07, 0x00, 0x4A, 0x00, 0x40, 0x00, 0x4A, 0x00, 0x1E, 0x00, 0x0C, 0x00, 0x08, 0x00,
+	 0x57, 0x00, 0x4D, 0x00, 0x57, 0x00, 0x2B, 0x00, 0x19, 0x00, 0x08, 0x00, 0x5D, 0x00, 0x53, 0x00,
+	 0x5D, 0x00, 0x31, 0x00, 0x1F, 0x00, 0x08, 0x00,
+
+};  /* fw_image_4_data */
+
+static const CFG_IDENTITY_STRCT fw_image_infoidentity[] = {
+	{
+		sizeof( CFG_IDENTITY_STRCT ) / sizeof(hcf_16) - 1,
+		CFG_FW_IDENTITY,
+		COMP_ID_FW_AP,
+		2,							//Variant
+		2,							//Major
+		36							//Minor
+	},
+	{ 0000, 0000, 0000, 0000, 0000, 0000 }		//endsentinel
+};
+
+static const CFG_PROG_STRCT fw_image_code[] = {
+	{
+		8,
+		CFG_PROG,
+		CFG_PROG_VOLATILE,			// mode
+		0x0146,		// sizeof(fw_image_1_data),
+		0x00000060,					// Target address in NIC Memory
+		0x0000,						// CRC: yes/no	TYPE: primary/station/tertiary
+		(hcf_8 FAR   *) fw_image_1_data
+	},
+	{
+		8,
+		CFG_PROG,
+		CFG_PROG_VOLATILE,			// mode
+		0x1918,		// sizeof(fw_image_2_data),
+		0x00000C16,					// Target address in NIC Memory
+		0x0000,						// CRC: yes/no	TYPE: primary/station/tertiary
+		(hcf_8 FAR   *) fw_image_2_data
+	},
+	{
+		8,
+		CFG_PROG,
+		CFG_PROG_VOLATILE,			// mode
+		0x01bc,		// sizeof(fw_image_3_data),
+		0x001E252E,					// Target address in NIC Memory
+		0x0000,						// CRC: yes/no	TYPE: primary/station/tertiary
+		(hcf_8 FAR   *) fw_image_3_data
+	},
+	{
+		8,
+		CFG_PROG,
+		CFG_PROG_VOLATILE,			// mode
+		0xab28,		// sizeof(fw_image_4_data),
+		0x001F4000,					// Target address in NIC Memory
+		0x0000,						// CRC: yes/no	TYPE: primary/station/tertiary
+		(hcf_8 FAR   *) fw_image_4_data
+	},
+	{
+		5,
+		CFG_PROG,
+		CFG_PROG_STOP,				// mode
+		0000,
+ 	0x000F1297,					// Start execution address
+	},
+	{ 0000, 0000, 0000, 0000, 00000000, 0000, 00000000}
+};
+
+static const CFG_RANGE20_STRCT fw_image_infocompat[] = {
+	{	3 + ((20 * sizeof(CFG_RANGE_SPEC_STRCT)) / sizeof(hcf_16)),
+		CFG_FW_SUP_RANGE,
+		COMP_ROLE_SUPL,
+		COMP_ID_APF,
+		{
+			{ 2, 2, 4 }  				//variant, bottom, top
+		}
+	},
+	{	3 + ((20 * sizeof(CFG_RANGE_SPEC_STRCT)) / sizeof(hcf_16)),
+		CFG_MFI_ACT_RANGES_STA,
+		COMP_ROLE_ACT,
+		COMP_ID_MFI,
+		{
+			{ 4, 6, 7 }, 				//variant, bottom, top
+			{ 5, 6, 7 }, 				//variant, bottom, top
+			{ 6, 6, 7 }  				//variant, bottom, top
+		}
+	},
+	{	3 + ((20 * sizeof(CFG_RANGE_SPEC_STRCT)) / sizeof(hcf_16)),
+		CFG_CFI_ACT_RANGES_STA,
+		COMP_ROLE_ACT,
+		COMP_ID_CFI,
+		{
+			{ 2, 1, 2 }  				//variant, bottom, top
+		}
+	},
+	{ 0000, 0000, 0000, 0000, { { 0000, 0000, 0000 } } }			//endsentinel
+};
+
+memimage fw_image = {
+	"FUPU7D37dhfwci\001C",			//signature, <format number>, C/Bin type
+	(CFG_PROG_STRCT *) fw_image_code,
+	0x000F1297,
+	00000000,					//(dummy) pdaplug
+	00000000,					//(dummy) priplug
+	(CFG_RANGE20_STRCT *) fw_image_infocompat,
+	(CFG_IDENTITY_STRCT *) fw_image_infoidentity,
+};
+
diff --git a/drivers/staging/wlags49_h2/ap_h25.c b/drivers/staging/wlags49_h2/ap_h25.c
new file mode 100644
index 0000000..f4491cb
--- /dev/null
+++ b/drivers/staging/wlags49_h2/ap_h25.c
@@ -0,0 +1,4094 @@
+/*
+ * File:	ap_h54.124
+ *
+ * Abstract:	This file contains memory image 'fw_image'.
+ *
+ * Contents:	Total size of the memory image: 63146 bytes.
+ *		Total number of blocks: 4 blocks.
+ *		Block  1 : load address 00000060, 328 bytes.
+ *		Block  2 : load address 00000C16, 9266 bytes.
+ *		Block  3 : load address 001E3048, 6476 bytes.
+ *		Block  4 : load address 001F4000, 47076 bytes.
+ *
+ * Identity:	component id: 32 (variant 3) version 1.24
+ *
+ * Compatibility:
+ *		supplying interface 8 (variant 4) : 1 - 1
+ *		acting on interface 1 (variant 7) : 3 - 3
+ *		acting on interface 1 (variant 8) : 1 - 1
+ *		acting on interface 2 (variant 4) : 1 - 2
+ *
+ * Generated:	by g:\fw\fupu3.exe version 4.26
+ *
+ * Commandline:	g:\fw\fupu3.exe /f=4 /n=fw_image /i=t3012400.hex
+ */
+
+
+#include "hcfcfg.h"				// to get hcf_16 etc defined as well as
+                                // possible settings which inluence mdd.h or dhf.h
+#include "mdd.h"   				//to get COMP_ID_STA etc defined
+#include "dhf.h"   				//used to be "fhfmem.h", to get memblock,plugrecord,
+
+static const hcf_8 fw_image_1_data[] = {
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x0C, 0x00, 0x00,
+	 0x02, 0x0D, 0x00, 0x00, 0x02, 0x0D, 0xD6, 0xA2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+	 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x09, 0x00,
+	 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA,
+	 0x00, 0x00, 0xFF, 0x07, 0x02, 0x00, 0x64, 0x00, 0x64, 0x00, 0x10, 0x27, 0x10, 0x27, 0x14, 0x00,
+	 0xD0, 0x07, 0xD0, 0x07, 0x10, 0x27, 0x2F, 0x00, 0x32, 0x00, 0x32, 0x00, 0x05, 0x00, 0x02, 0x00,
+	 0x02, 0x00, 0x10, 0x27, 0x05, 0x00, 0x00, 0x02, 0x00, 0x02, 0x13, 0x00, 0x07, 0x00, 0x03, 0x00,
+	 0x32, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x09, 0x2B, 0x09, 0x2B, 0x09, 0xFF, 0x0F,
+	 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x01, 0x00, 0x40, 0x00, 0x32, 0x00, 0x32, 0x00,
+	 0x0A, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+};  /* fw_image_1_data */
+
+static const hcf_8 fw_image_2_data[] = {
+	 0x7C, 0xA4, 0x00, 0x16, 0x08, 0x40, 0x0F, 0xD2, 0xE1, 0x28, 0xA5, 0x7C, 0x50, 0x30, 0xF1, 0x84,
+	 0x44, 0x08, 0xAB, 0xAE, 0xA5, 0xB8, 0xFC, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
+	 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA5, 0xC6, 0x84, 0xF8,
+	 0x99, 0xEE, 0x8D, 0xF6, 0x0D, 0xFF, 0xBD, 0xD6, 0xB1, 0xDE, 0x54, 0x91, 0x50, 0x60, 0x03, 0x02,
+	 0xA9, 0xCE, 0x7D, 0x56, 0x19, 0xE7, 0x62, 0xB5, 0xE6, 0x4D, 0x9A, 0xEC, 0x45, 0x8F, 0x9D, 0x1F,
+	 0x40, 0x89, 0x87, 0xFA, 0x15, 0xEF, 0xEB, 0xB2, 0xC9, 0x8E, 0x0B, 0xFB, 0xEC, 0x41, 0x67, 0xB3,
+	 0xFD, 0x5F, 0xEA, 0x45, 0xBF, 0x23, 0xF7, 0x53, 0x96, 0xE4, 0x5B, 0x9B, 0xC2, 0x75, 0x1C, 0xE1,
+	 0xAE, 0x3D, 0x6A, 0x4C, 0x5A, 0x6C, 0x41, 0x7E, 0x02, 0xF5, 0x4F, 0x83, 0x5C, 0x68, 0xF4, 0x51,
+	 0x34, 0xD1, 0x08, 0xF9, 0x93, 0xE2, 0x73, 0xAB, 0x53, 0x62, 0x3F, 0x2A, 0x0C, 0x08, 0x52, 0x95,
+	 0x65, 0x46, 0x5E, 0x9D, 0x28, 0x30, 0xA1, 0x37, 0x0F, 0x0A, 0xB5, 0x2F, 0x09, 0x0E, 0x36, 0x24,
+	 0x9B, 0x1B, 0x3D, 0xDF, 0x26, 0xCD, 0x69, 0x4E, 0xCD, 0x7F, 0x9F, 0xEA, 0x1B, 0x12, 0x9E, 0x1D,
+	 0x74, 0x58, 0x2E, 0x34, 0x2D, 0x36, 0xB2, 0xDC, 0xEE, 0xB4, 0xFB, 0x5B, 0xF6, 0xA4, 0x4D, 0x76,
+	 0x61, 0xB7, 0xCE, 0x7D, 0x7B, 0x52, 0x3E, 0xDD, 0x71, 0x5E, 0x97, 0x13, 0xF5, 0xA6, 0x68, 0xB9,
+	 0x00, 0x00, 0x2C, 0xC1, 0x60, 0x40, 0x1F, 0xE3, 0xC8, 0x79, 0xED, 0xB6, 0xBE, 0xD4, 0x46, 0x8D,
+	 0xD9, 0x67, 0x4B, 0x72, 0xDE, 0x94, 0xD4, 0x98, 0xE8, 0xB0, 0x4A, 0x85, 0x6B, 0xBB, 0x2A, 0xC5,
+	 0xE5, 0x4F, 0x16, 0xED, 0xC5, 0x86, 0xD7, 0x9A, 0x55, 0x66, 0x94, 0x11, 0xCF, 0x8A, 0x10, 0xE9,
+	 0x06, 0x04, 0x81, 0xFE, 0xF0, 0xA0, 0x44, 0x78, 0xBA, 0x25, 0xE3, 0x4B, 0xF3, 0xA2, 0xFE, 0x5D,
+	 0xC0, 0x80, 0x8A, 0x05, 0xAD, 0x3F, 0xBC, 0x21, 0x48, 0x70, 0x04, 0xF1, 0xDF, 0x63, 0xC1, 0x77,
+	 0x75, 0xAF, 0x63, 0x42, 0x30, 0x20, 0x1A, 0xE5, 0x0E, 0xFD, 0x6D, 0xBF, 0x4C, 0x81, 0x14, 0x18,
+	 0x35, 0x26, 0x2F, 0xC3, 0xE1, 0xBE, 0xA2, 0x35, 0xCC, 0x88, 0x39, 0x2E, 0x57, 0x93, 0xF2, 0x55,
+	 0x82, 0xFC, 0x47, 0x7A, 0xAC, 0xC8, 0xE7, 0xBA, 0x2B, 0x32, 0x95, 0xE6, 0xA0, 0xC0, 0x98, 0x19,
+	 0xD1, 0x9E, 0x7F, 0xA3, 0x66, 0x44, 0x7E, 0x54, 0xAB, 0x3B, 0x83, 0x0B, 0xCA, 0x8C, 0x29, 0xC7,
+	 0xD3, 0x6B, 0x3C, 0x28, 0x79, 0xA7, 0xE2, 0xBC, 0x1D, 0x16, 0x76, 0xAD, 0x3B, 0xDB, 0x56, 0x64,
+	 0x4E, 0x74, 0x1E, 0x14, 0xDB, 0x92, 0x0A, 0x0C, 0x6C, 0x48, 0xE4, 0xB8, 0x5D, 0x9F, 0x6E, 0xBD,
+	 0xEF, 0x43, 0xA6, 0xC4, 0xA8, 0x39, 0xA4, 0x31, 0x37, 0xD3, 0x8B, 0xF2, 0x32, 0xD5, 0x43, 0x8B,
+	 0x59, 0x6E, 0xB7, 0xDA, 0x8C, 0x01, 0x64, 0xB1, 0xD2, 0x9C, 0xE0, 0x49, 0xB4, 0xD8, 0xFA, 0xAC,
+	 0x07, 0xF3, 0x25, 0xCF, 0xAF, 0xCA, 0x8E, 0xF4, 0xE9, 0x47, 0x18, 0x10, 0xD5, 0x6F, 0x88, 0xF0,
+	 0x6F, 0x4A, 0x72, 0x5C, 0x24, 0x38, 0xF1, 0x57, 0xC7, 0x73, 0x51, 0x97, 0x23, 0xCB, 0x7C, 0xA1,
+	 0x9C, 0xE8, 0x21, 0x3E, 0xDD, 0x96, 0xDC, 0x61, 0x86, 0x0D, 0x85, 0x0F, 0x90, 0xE0, 0x42, 0x7C,
+	 0xC4, 0x71, 0xAA, 0xCC, 0xD8, 0x90, 0x05, 0x06, 0x01, 0xF7, 0x12, 0x1C, 0xA3, 0xC2, 0x5F, 0x6A,
+	 0xF9, 0xAE, 0xD0, 0x69, 0x91, 0x17, 0x58, 0x99, 0x27, 0x3A, 0xB9, 0x27, 0x38, 0xD9, 0x13, 0xEB,
+	 0xB3, 0x2B, 0x33, 0x22, 0xBB, 0xD2, 0x70, 0xA9, 0x89, 0x07, 0xA7, 0x33, 0xB6, 0x2D, 0x22, 0x3C,
+	 0x92, 0x15, 0x20, 0xC9, 0x49, 0x87, 0xFF, 0xAA, 0x78, 0x50, 0x7A, 0xA5, 0x8F, 0x03, 0xF8, 0x59,
+	 0x80, 0x09, 0x17, 0x1A, 0xDA, 0x65, 0x31, 0xD7, 0xC6, 0x84, 0xB8, 0xD0, 0xC3, 0x82, 0xB0, 0x29,
+	 0x77, 0x5A, 0x11, 0x1E, 0xCB, 0x7B, 0xFC, 0xA8, 0xD6, 0x6D, 0x3A, 0x2C, 0x00, 0x30, 0x00, 0x31,
+	 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x38, 0x00, 0x3A,
+	 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3D, 0x00, 0x3E, 0x00, 0x3F, 0x00, 0x3F, 0x59, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x21, 0x10, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x20, 0x03, 0xE0, 0x01, 0x40, 0x01, 0x20, 0x03, 0xE0, 0x01,
+	 0x40, 0x01, 0x18, 0x08, 0xF0, 0x3F, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0A, 0x02, 0x14, 0x05, 0x32, 0x0B, 0x37,
+	 0x08, 0x50, 0x0B, 0x6E, 0x02, 0x00, 0x04, 0x00, 0x0B, 0x00, 0x16, 0x00, 0x0C, 0x00, 0x12, 0x00,
+	 0x18, 0x00, 0x24, 0x00, 0x30, 0x00, 0x48, 0x00, 0x60, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x39, 0x00, 0x20, 0x00, 0x39, 0x00,
+	 0x39, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0xA4, 0x10, 0xF2, 0x10, 0xAA, 0x10, 0xEC, 0x10, 0xB0, 0x10, 0xE6, 0x10, 0xB6, 0x10,
+	 0xE0, 0x10, 0xBC, 0x10, 0xDA, 0x10, 0xC2, 0x10, 0xD4, 0x10, 0xC8, 0x10, 0xCE, 0x10, 0x07, 0x01,
+	 0x00, 0x00, 0x16, 0x22, 0x00, 0x04, 0x08, 0x01, 0x00, 0x00, 0x16, 0x26, 0x00, 0x04, 0x09, 0x01,
+	 0x00, 0x00, 0x16, 0x2A, 0x00, 0x04, 0x0A, 0x01, 0x00, 0x00, 0x16, 0x2E, 0x00, 0x04, 0x0B, 0x01,
+	 0x00, 0x00, 0x10, 0x24, 0x04, 0x04, 0x0C, 0x01, 0x00, 0x00, 0x10, 0x28, 0x04, 0x04, 0x0D, 0x01,
+	 0x00, 0x00, 0x10, 0x2C, 0x04, 0x04, 0x0E, 0x01, 0x00, 0x00, 0x10, 0x30, 0x04, 0x04, 0x0F, 0x01,
+	 0x00, 0x00, 0x14, 0x34, 0x08, 0x84, 0x10, 0x01, 0x00, 0x00, 0x14, 0x38, 0x08, 0x84, 0x11, 0x01,
+	 0x00, 0x00, 0x14, 0x3C, 0x08, 0x84, 0x12, 0x01, 0x00, 0x00, 0x14, 0x40, 0x08, 0x84, 0x13, 0x01,
+	 0x00, 0x00, 0x17, 0x64, 0x0C, 0x8B, 0x14, 0x01, 0x00, 0x00, 0x17, 0x68, 0x0C, 0x8B, 0x15, 0x01,
+	 0x00, 0x00, 0x17, 0x6C, 0x0C, 0x8B, 0x16, 0x01, 0x00, 0x00, 0x17, 0x70, 0x0C, 0x8B, 0x17, 0x01,
+	 0x00, 0x00, 0x17, 0x74, 0x0C, 0x8B, 0x18, 0x01, 0x00, 0x00, 0x17, 0x78, 0x0C, 0x8B, 0x19, 0x01,
+	 0x00, 0x00, 0x17, 0x7C, 0x0C, 0x8B, 0x1A, 0x01, 0x00, 0x00, 0x17, 0x80, 0x0C, 0x8B, 0x1B, 0x01,
+	 0x00, 0x00, 0x17, 0x84, 0x0C, 0x8B, 0x1C, 0x01, 0x00, 0x00, 0x17, 0x88, 0x0C, 0x8B, 0x1D, 0x01,
+	 0x00, 0x00, 0x17, 0x8C, 0x0C, 0x8B, 0x1E, 0x01, 0x00, 0x00, 0x0E, 0x95, 0x17, 0x04, 0x1F, 0x01,
+	 0x00, 0x00, 0x0E, 0x99, 0x17, 0x04, 0x20, 0x01, 0x00, 0x00, 0x0E, 0x9D, 0x17, 0x04, 0x21, 0x01,
+	 0x00, 0x00, 0x0E, 0xA1, 0x17, 0x04, 0x22, 0x01, 0x00, 0x00, 0x0E, 0xA5, 0x00, 0x00, 0x14, 0x11,
+	 0x34, 0x11, 0x54, 0x11, 0x74, 0x11, 0xCC, 0x11, 0x1C, 0x11, 0x3C, 0x11, 0x5C, 0x11, 0x7C, 0x11,
+	 0xD4, 0x11, 0x24, 0x11, 0x44, 0x11, 0x64, 0x11, 0x84, 0x11, 0xDC, 0x11, 0x2C, 0x11, 0x4C, 0x11,
+	 0x6C, 0x11, 0x8C, 0x11, 0xE4, 0x11, 0x94, 0x11, 0x9C, 0x11, 0xA4, 0x11, 0xAC, 0x11, 0xB4, 0x11,
+	 0xBC, 0x11, 0xC4, 0x11, 0xEC, 0x11, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
+	 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
+	 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
+	 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x0A, 0x0A, 0x7F, 0x7F, 0x7F,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
+	 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x0A, 0x0A, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x10, 0x10, 0x10, 0x10,
+	 0x17, 0x17, 0x17, 0x17, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x14,
+	 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
+	 0x14, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x11, 0x11, 0x11, 0x11, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x14, 0x14,
+	 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x16, 0x16, 0x16, 0x16,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
+	 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x0A, 0x0A, 0x0A,
+	 0x0A, 0x7F, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x7F,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x10, 0x10, 0x10, 0x10, 0x7F, 0x14, 0x14, 0x14, 0x14,
+	 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x0A, 0x0A, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
+	 0x14, 0x14, 0x14, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+	 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x7F, 0x7F,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x9D, 0x9D, 0xA1, 0xAA, 0x10, 0x10,
+	 0x9D, 0x9D, 0x08, 0x02, 0x06, 0x00, 0xA5, 0xA5, 0xAA, 0xAA, 0x17, 0x17, 0xA2, 0xA2, 0x15, 0x05,
+	 0x07, 0x00, 0xAA, 0xAA, 0xB4, 0xB4, 0x1C, 0x1C, 0xA7, 0xA7, 0x1C, 0x0A, 0x08, 0x00, 0xB7, 0xB7,
+	 0xC1, 0xC1, 0x09, 0x09, 0xB4, 0xB4, 0x29, 0x17, 0x08, 0x00, 0xBD, 0xBD, 0xC7, 0xC7, 0x0F, 0x0F,
+	 0xBA, 0xBA, 0x2F, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x17,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0xE4, 0xF0, 0xFD, 0xF0, 0x1F, 0xF1, 0x60, 0xF6, 0x9B, 0xF0, 0x79, 0xF6, 0x9B, 0xF0, 0x9B, 0xF0,
+	 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0, 0xCC, 0xF7, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0,
+	 0x9B, 0xF0, 0x15, 0xF3, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0,
+	 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0,
+	 0x9B, 0xF0, 0x66, 0xF3, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0,
+	 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0,
+	 0xE3, 0xF2, 0xFE, 0xF2, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0, 0x9B, 0xF0,
+	 0xB4, 0x1C, 0x59, 0xF1, 0x6C, 0xF1, 0x1C, 0xF2, 0x20, 0xF2, 0x9B, 0xF0, 0x9B, 0xF0, 0xCF, 0xF2,
+	 0x64, 0xE6, 0x3E, 0xE6, 0x92, 0xE6, 0xE1, 0xE6, 0xA9, 0xE7, 0xCF, 0xE7, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x12, 0xF1, 0x35, 0xF1, 0x5D, 0xF6, 0x5D, 0xF6, 0x6D, 0xF6, 0x86, 0xF6, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFC, 0xC0, 0xF3, 0xF2, 0xF5, 0x5A, 0x00, 0x02, 0x00, 0xF9, 0xFF,
+	 0xC0, 0xF3, 0xD6, 0xF3, 0xCA, 0x00, 0x02, 0x00, 0xF7, 0xFF, 0xC0, 0xF3, 0xD6, 0xF3, 0xB0, 0x26,
+	 0x06, 0x00, 0xF0, 0xFF, 0xC0, 0xF3, 0xAA, 0xF3, 0x00, 0x00, 0x00, 0x02, 0xF6, 0xFF, 0xC0, 0xF3,
+	 0xD6, 0xF3, 0x6C, 0x00, 0x02, 0x00, 0xF4, 0xFF, 0xC0, 0xF3, 0xD6, 0xF3, 0x68, 0x01, 0x02, 0x00,
+	 0xF5, 0xFF, 0xC0, 0xF3, 0xFB, 0xF5, 0xA2, 0x26, 0x02, 0x00, 0xED, 0xFF, 0xC0, 0xF3, 0x0D, 0xF6,
+	 0x9E, 0x2B, 0x02, 0x00, 0xEC, 0xFF, 0xC0, 0xF3, 0x3B, 0xF6, 0xA0, 0x2B, 0x02, 0x00, 0xEB, 0xFF,
+	 0xC0, 0xF3, 0x41, 0xF6, 0xA2, 0x2B, 0x02, 0x00, 0xEE, 0xFF, 0xC0, 0xF3, 0x47, 0xF6, 0xD6, 0x2B,
+	 0x02, 0x00, 0xDA, 0xFF, 0xC0, 0xF3, 0xD6, 0xF3, 0xD0, 0x13, 0x0C, 0x00, 0xEA, 0xFF, 0xC0, 0xF3,
+	 0xAA, 0xF3, 0xEC, 0x2B, 0x06, 0x00, 0xE9, 0xFF, 0xC0, 0xF3, 0xD6, 0xF3, 0xF2, 0x2B, 0x02, 0x00,
+	 0xE8, 0xFF, 0xC0, 0xF3, 0xD6, 0xF3, 0xF4, 0x2B, 0x02, 0x00, 0xE7, 0xFF, 0xC0, 0xF3, 0xD6, 0xF3,
+	 0xF6, 0x2B, 0x02, 0x00, 0xE6, 0xFF, 0xC0, 0xF3, 0xD6, 0xF3, 0xF8, 0x2B, 0x02, 0x00, 0xE5, 0xFF,
+	 0xC0, 0xF3, 0xD6, 0xF3, 0xFA, 0x2B, 0x10, 0x00, 0xE4, 0xFF, 0xC0, 0xF3, 0xD6, 0xF3, 0x0A, 0x2C,
+	 0x18, 0x00, 0xDB, 0xFF, 0xC0, 0xF3, 0xD6, 0xF3, 0x22, 0x2C, 0x02, 0x00, 0xDC, 0xFF, 0xC0, 0xF3,
+	 0xD6, 0xF3, 0x24, 0x2C, 0x02, 0x00, 0xE1, 0xFF, 0xC0, 0xF3, 0xD6, 0xF3, 0xC6, 0x2C, 0x02, 0x00,
+	 0xE0, 0xFF, 0xC0, 0xF3, 0xD6, 0xF3, 0xC4, 0x2C, 0x02, 0x00, 0xE3, 0xFF, 0xC0, 0xF3, 0xD6, 0xF3,
+	 0xA8, 0x2C, 0x02, 0x00, 0xE2, 0xFF, 0x0E, 0xF4, 0xAA, 0xF3, 0x7E, 0x2C, 0x24, 0x00, 0x03, 0xFC,
+	 0xC0, 0xF3, 0x3A, 0xF5, 0x92, 0x2B, 0x02, 0x00, 0x04, 0xFC, 0xC0, 0xF3, 0xD0, 0xF3, 0xBA, 0x26,
+	 0x22, 0x00, 0x06, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3, 0xA0, 0x26, 0x02, 0x00, 0x07, 0xFC, 0xC0, 0xF3,
+	 0xD6, 0xF3, 0xFE, 0x26, 0x02, 0x00, 0x0E, 0xFC, 0xC0, 0xF3, 0x63, 0xF5, 0x08, 0x27, 0x22, 0x00,
+	 0xB1, 0xFC, 0xC0, 0xF3, 0x88, 0xF8, 0x2A, 0x28, 0x02, 0x00, 0x20, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3,
+	 0x2E, 0x27, 0x02, 0x00, 0x25, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3, 0x3A, 0x27, 0x02, 0x00, 0x26, 0xFC,
+	 0xC0, 0xF3, 0xD6, 0xF3, 0x3C, 0x27, 0x02, 0x00, 0x27, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3, 0x3E, 0x27,
+	 0x02, 0x00, 0xB2, 0xFC, 0xC0, 0xF3, 0xD0, 0xF3, 0x4E, 0x28, 0x22, 0x00, 0xC1, 0xFC, 0xC0, 0xF3,
+	 0xD6, 0xF3, 0x56, 0x2C, 0x20, 0x00, 0xB0, 0xFC, 0xA0, 0xF3, 0x8C, 0xF8, 0x00, 0x00, 0x00, 0x00,
+	 0xC4, 0xFC, 0xA0, 0xF3, 0x54, 0xF6, 0x00, 0x00, 0x08, 0x00, 0xC8, 0xFC, 0xA0, 0xF3, 0x52, 0xF6,
+	 0x00, 0x00, 0x08, 0x00, 0xB4, 0xFC, 0xA0, 0xF3, 0xC0, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xB6, 0xFC,
+	 0xA0, 0xF3, 0x6A, 0xF9, 0x00, 0x00, 0x00, 0x00, 0xB7, 0xFC, 0xA0, 0xF3, 0xAC, 0xF9, 0x00, 0x00,
+	 0x00, 0x00, 0xB8, 0xFC, 0xA0, 0xF3, 0x02, 0xFA, 0x00, 0x00, 0x00, 0x00, 0xBC, 0xFC, 0xA0, 0xF3,
+	 0x3B, 0xFA, 0x00, 0x00, 0x00, 0x00, 0xBD, 0xFC, 0xA0, 0xF3, 0xC3, 0xFA, 0x00, 0x00, 0x00, 0x00,
+	 0xBE, 0xFC, 0xA0, 0xF3, 0xEF, 0xFA, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFC, 0xA0, 0xF3, 0x3C, 0xFB,
+	 0x00, 0x00, 0x00, 0x00, 0xB3, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3, 0xA2, 0x0F, 0x10, 0x00, 0xB5, 0xFC,
+	 0xC0, 0xF3, 0xD6, 0xF3, 0xA4, 0x2C, 0x02, 0x00, 0xB9, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3, 0xA6, 0x2C,
+	 0x02, 0x00, 0x90, 0xFD, 0xC0, 0xF3, 0xAA, 0xF3, 0xAA, 0x2C, 0x02, 0x00, 0x88, 0xFC, 0xC0, 0xF3,
+	 0xD6, 0xF3, 0x78, 0x2B, 0x04, 0x00, 0x89, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3, 0x7C, 0x2B, 0x04, 0x00,
+	 0xC5, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3, 0x80, 0x2B, 0x04, 0x00, 0x23, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3,
+	 0x34, 0x27, 0x04, 0x00, 0x2A, 0xFC, 0xC0, 0xF3, 0x2C, 0xF4, 0xB6, 0x26, 0x02, 0x00, 0xC7, 0xFD,
+	 0xC0, 0xF3, 0xAA, 0xF3, 0xA6, 0x2B, 0x0A, 0x00, 0x29, 0xFC, 0x7F, 0xF4, 0x43, 0xF4, 0x00, 0x00,
+	 0x00, 0x00, 0xC2, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3, 0x86, 0x2B, 0x08, 0x00, 0x32, 0xFC, 0xC0, 0xF3,
+	 0xD6, 0xF3, 0x5C, 0x01, 0x02, 0x00, 0x33, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3, 0x5E, 0x01, 0x02, 0x00,
+	 0x35, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3, 0x8E, 0x2B, 0x02, 0x00, 0xC7, 0xFC, 0xC0, 0xF3, 0xEB, 0xF5,
+	 0x90, 0x2B, 0x02, 0x00, 0x10, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3, 0xA8, 0x26, 0x02, 0x00, 0x11, 0xFC,
+	 0xC0, 0xF3, 0xD6, 0xF3, 0x44, 0x27, 0x06, 0x00, 0x12, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3, 0x4A, 0x27,
+	 0x06, 0x00, 0x13, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3, 0x50, 0x27, 0x06, 0x00, 0x14, 0xFC, 0xC0, 0xF3,
+	 0xD6, 0xF3, 0x56, 0x27, 0x06, 0x00, 0x15, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3, 0x5C, 0x27, 0x06, 0x00,
+	 0x16, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3, 0x62, 0x27, 0x06, 0x00, 0x17, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3,
+	 0x2A, 0x27, 0x02, 0x00, 0x83, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3, 0x6C, 0x01, 0x02, 0x00, 0x97, 0xFC,
+	 0xC0, 0xF3, 0xD6, 0xF3, 0x6A, 0x01, 0x02, 0x00, 0x98, 0xFC, 0xD7, 0xF5, 0xC5, 0xF5, 0xEC, 0x00,
+	 0x02, 0x00, 0x99, 0xFC, 0xD7, 0xF5, 0xC5, 0xF5, 0xEC, 0x02, 0x02, 0x00, 0x9A, 0xFC, 0xD7, 0xF5,
+	 0xC5, 0xF5, 0xEC, 0x04, 0x02, 0x00, 0x9B, 0xFC, 0xD7, 0xF5, 0xC5, 0xF5, 0xEC, 0x06, 0x02, 0x00,
+	 0x9C, 0xFC, 0xD7, 0xF5, 0xC5, 0xF5, 0xEC, 0x08, 0x02, 0x00, 0x9D, 0xFC, 0xD7, 0xF5, 0xC5, 0xF5,
+	 0xEC, 0x0A, 0x02, 0x00, 0x18, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3, 0x2C, 0x27, 0x02, 0x00, 0x22, 0xFC,
+	 0xC0, 0xF3, 0xD6, 0xF3, 0x32, 0x27, 0x02, 0x00, 0x24, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3, 0x38, 0x27,
+	 0x02, 0x00, 0xC0, 0xFC, 0xA0, 0xF3, 0x50, 0xF6, 0x00, 0x00, 0x06, 0x00, 0x9E, 0xFC, 0xC0, 0xF3,
+	 0x83, 0xF5, 0x6E, 0x01, 0x04, 0x00, 0x9F, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3, 0x3E, 0x2C, 0x04, 0x00,
+	 0xA0, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3, 0x42, 0x2C, 0x04, 0x00, 0xA1, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3,
+	 0x46, 0x2C, 0x04, 0x00, 0xA2, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3, 0x4A, 0x2C, 0x04, 0x00, 0xA3, 0xFC,
+	 0xC0, 0xF3, 0xD6, 0xF3, 0x4E, 0x2C, 0x04, 0x00, 0xA4, 0xFC, 0xC0, 0xF3, 0xD6, 0xF3, 0x52, 0x2C,
+	 0x04, 0x00, 0x20, 0xFD, 0xF1, 0xF3, 0xAA, 0xF3, 0xD5, 0xFB, 0x08, 0x00, 0x21, 0xFD, 0xF1, 0xF3,
+	 0xAA, 0xF3, 0xD9, 0xFB, 0x0A, 0x00, 0x22, 0xFD, 0xF1, 0xF3, 0xAA, 0xF3, 0xDE, 0xFB, 0x16, 0x00,
+	 0x23, 0xFD, 0xF1, 0xF3, 0xAA, 0xF3, 0xE9, 0xFB, 0x0A, 0x00, 0x45, 0xFD, 0xC0, 0xF3, 0xAA, 0xF3,
+	 0xCA, 0x00, 0x02, 0x00, 0x47, 0xFD, 0xC0, 0xF3, 0xAA, 0xF3, 0x36, 0x01, 0x02, 0x00, 0x48, 0xFD,
+	 0xD4, 0xF4, 0xAA, 0xF3, 0x5C, 0x01, 0x02, 0x00, 0x49, 0xFD, 0xD4, 0xF4, 0xAA, 0xF3, 0x5E, 0x01,
+	 0x02, 0x00, 0x4A, 0xFD, 0xC0, 0xF3, 0xAA, 0xF3, 0x56, 0x01, 0x02, 0x00, 0x4B, 0xFD, 0xC0, 0xF3,
+	 0xAA, 0xF3, 0x58, 0x01, 0x02, 0x00, 0x4D, 0xFD, 0xF1, 0xF3, 0xAA, 0xF3, 0xEE, 0xFB, 0x08, 0x00,
+	 0x4F, 0xFD, 0xE8, 0xF4, 0xAA, 0xF3, 0x96, 0x2B, 0x02, 0x00, 0xC2, 0xFD, 0xDE, 0xF4, 0xAA, 0xF3,
+	 0x00, 0x00, 0x02, 0x00, 0x40, 0xFD, 0xE9, 0xF3, 0xAA, 0xF3, 0x78, 0x01, 0x02, 0x00, 0x24, 0xFD,
+	 0x01, 0xF5, 0xAA, 0xF3, 0x00, 0x00, 0x02, 0x00, 0x91, 0xFD, 0xC0, 0xF3, 0xAA, 0xF3, 0xCC, 0x1E,
+	 0x02, 0x00, 0x93, 0xFD, 0xC0, 0xF3, 0xAA, 0xF3, 0xD2, 0x1E, 0x02, 0x00, 0x8F, 0xFD, 0x0E, 0xF5,
+	 0xAA, 0xF3, 0x00, 0x00, 0x08, 0x00, 0xC1, 0xFD, 0x92, 0xF6, 0xAA, 0xF3, 0xC8, 0x00, 0x02, 0x00,
+	 0xC6, 0xFD, 0xC0, 0xF3, 0xAA, 0xF3, 0x20, 0x30, 0x04, 0x00, 0x25, 0xFD, 0xC0, 0xF3, 0xAA, 0xF3,
+	 0x62, 0x01, 0x02, 0x00, 0x89, 0xFD, 0x96, 0xF4, 0xAA, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x8A, 0xFD,
+	 0x0E, 0xF4, 0xAA, 0xF3, 0x7E, 0x2C, 0x24, 0x00, 0x46, 0xFD, 0xC0, 0xF3, 0xAA, 0xF3, 0x7A, 0x01,
+	 0x06, 0x00, 0x86, 0xFD, 0xC0, 0xF3, 0xAA, 0xF3, 0xB0, 0x26, 0x06, 0x00, 0x87, 0xFD, 0xC0, 0xF3,
+	 0xAA, 0xF3, 0x76, 0x2C, 0x06, 0x00, 0x8B, 0xFD, 0x96, 0xF9, 0xAA, 0xF3, 0x00, 0x00, 0x12, 0x00,
+	 0x8B, 0xFD, 0x96, 0xF9, 0xAA, 0xF3, 0x00, 0x00, 0x12, 0x00, 0x8E, 0xFD, 0xC0, 0xF3, 0xAA, 0xF3,
+	 0xEE, 0x14, 0x02, 0x00, 0x80, 0xFD, 0xEF, 0xF4, 0xAA, 0xF3, 0x22, 0x00, 0x02, 0x00, 0x81, 0xFD,
+	 0xEF, 0xF4, 0xAA, 0xF3, 0x22, 0x02, 0x02, 0x00, 0x82, 0xFD, 0xEF, 0xF4, 0xAA, 0xF3, 0x22, 0x04,
+	 0x02, 0x00, 0x83, 0xFD, 0xEF, 0xF4, 0xAA, 0xF3, 0x22, 0x06, 0x02, 0x00, 0x84, 0xFD, 0xEF, 0xF4,
+	 0xAA, 0xF3, 0x22, 0x08, 0x02, 0x00, 0x85, 0xFD, 0xEF, 0xF4, 0xAA, 0xF3, 0x22, 0x0A, 0x02, 0x00,
+	 0x00, 0xF1, 0x46, 0x00, 0x64, 0xF3, 0xF6, 0x00, 0x00, 0x03, 0x8E, 0xF7, 0x1F, 0x00, 0x34, 0x01,
+	 0xC8, 0x00, 0x96, 0x01, 0xCC, 0x00, 0xFA, 0x00, 0x78, 0x01, 0xD2, 0x25, 0x18, 0x01, 0xCC, 0x1E,
+	 0xC8, 0x00, 0x00, 0x00, 0x02, 0x15, 0x00, 0x00, 0x06, 0x17, 0x12, 0x01, 0x03, 0x00, 0xAE, 0x00,
+	 0xEC, 0x00, 0x44, 0x00, 0xDC, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x09, 0x08, 0x24, 0x28, 0x06,
+	 0x0C, 0x18, 0x08, 0x30, 0x14, 0x0C, 0x08, 0x36, 0x10, 0x12, 0xA1, 0xB6, 0x14, 0xB6, 0x50, 0xB7,
+	 0x59, 0xB7, 0x25, 0xB6, 0xCE, 0xB6, 0x93, 0xB6, 0x15, 0x1C, 0xD0, 0x1A, 0x15, 0x1C, 0x8B, 0x1B,
+	 0xEE, 0x1A, 0xCB, 0x1A, 0xD2, 0x1B, 0xF1, 0x1B, 0x06, 0x1C, 0x48, 0x1C, 0x74, 0x1C, 0x74, 0x1B,
+	 0x22, 0x46, 0x22, 0x46, 0x22, 0x46, 0x22, 0x46, 0x22, 0x46, 0x22, 0x46, 0x22, 0x46, 0x22, 0x46,
+	 0x22, 0x46, 0x22, 0x46, 0x22, 0x46, 0x23, 0x46, 0x23, 0x46, 0x23, 0x46, 0x1C, 0x47, 0x1C, 0x47,
+	 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47,
+	 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1D, 0x47, 0x9A, 0x48, 0xDA, 0x48, 0x1A, 0x48, 0x5A, 0x48,
+	 0x9A, 0x48, 0xDA, 0x48, 0x1A, 0x48, 0x5A, 0x48, 0x9A, 0x48, 0xDA, 0x48, 0x1A, 0x48, 0x5A, 0x48,
+	 0x9A, 0x48, 0x33, 0x48, 0x78, 0x49, 0x78, 0x49, 0x79, 0x49, 0x79, 0x49, 0x79, 0x49, 0x79, 0x49,
+	 0x7A, 0x49, 0x7A, 0x49, 0x7A, 0x49, 0x7A, 0x49, 0x7B, 0x49, 0x7B, 0x49, 0x7B, 0x49, 0x7C, 0x49,
+	 0xD8, 0x03, 0xDC, 0x03, 0xE0, 0x03, 0xE4, 0x03, 0xF0, 0x03, 0xF4, 0x03, 0xF8, 0x03, 0x0A, 0x04,
+	 0x0E, 0x04, 0x12, 0x04, 0x16, 0x04, 0x0C, 0x04, 0x10, 0x04, 0x14, 0x04, 0x18, 0x04, 0x1C, 0x04,
+	 0x20, 0x04, 0x24, 0x04, 0x28, 0x04, 0x4C, 0x04, 0x50, 0x04, 0x54, 0x04, 0x58, 0x04, 0x5C, 0x04,
+	 0x60, 0x04, 0x64, 0x04, 0x68, 0x04, 0x6C, 0x04, 0x70, 0x04, 0x74, 0x04, 0x7D, 0x04, 0x81, 0x04,
+	 0x85, 0x04, 0x89, 0x04, 0x8D, 0x04, 0x10, 0x00, 0x8E, 0x19, 0xAC, 0x00, 0x04, 0x00, 0x00, 0x00,
+	 0x00, 0x80, 0x3C, 0x0C, 0x00, 0x00, 0xFF, 0x3F, 0x44, 0x04, 0x00, 0x00, 0xD3, 0x22, 0x44, 0x04,
+	 0x9C, 0x02, 0xCB, 0x54, 0x44, 0x04, 0x00, 0x00, 0x01, 0x00, 0x44, 0x04, 0x00, 0x00, 0x00, 0x03,
+	 0x00, 0x0C, 0x71, 0x00, 0x30, 0x50, 0x20, 0x00, 0x80, 0xBF, 0x1F, 0xA6, 0x28, 0x00, 0x0B, 0x02,
+	 0x60, 0x84, 0x4C, 0x00, 0x02, 0x00, 0x4B, 0x1C, 0x98, 0x00, 0x00, 0x00, 0x20, 0x0B, 0x34, 0x04,
+	 0xFD, 0x34, 0x34, 0x00, 0x38, 0x04, 0xFD, 0x34, 0x34, 0x00, 0x3C, 0x04, 0x01, 0x00, 0x10, 0x00,
+	 0x00, 0x08, 0x00, 0x52, 0x14, 0x00, 0x04, 0x08, 0x0E, 0x32, 0x00, 0xA6, 0x10, 0x08, 0xC4, 0x03,
+	 0x50, 0x60, 0x18, 0x08, 0xF0, 0x3F, 0xFC, 0x01, 0x10, 0x0C, 0x00, 0x00, 0x80, 0x04, 0x14, 0x0C,
+	 0x00, 0x00, 0x00, 0x41, 0x20, 0x0C, 0xB0, 0x00, 0xB0, 0xB8, 0x24, 0x0C, 0x00, 0x00, 0xAB, 0x05,
+	 0x2C, 0x0C, 0x80, 0x05, 0x00, 0xFF, 0x30, 0x0C, 0x00, 0x00, 0xB0, 0x04, 0x34, 0x0C, 0x03, 0x00,
+	 0x00, 0xE8, 0x44, 0x0C, 0x04, 0x00, 0xFF, 0x0F, 0x00, 0x10, 0x2E, 0x00, 0x0C, 0xE3, 0x44, 0x04,
+	 0x00, 0x00, 0x01, 0x04, 0x44, 0x04, 0x00, 0x00, 0x01, 0x01, 0x44, 0x04, 0x00, 0x00, 0x01, 0x00,
+	 0x44, 0x04, 0x00, 0x00, 0x01, 0x04, 0x44, 0x04, 0x00, 0x00, 0x80, 0x03, 0x48, 0x0C, 0x00, 0x00,
+	 0x7F, 0x00, 0x04, 0x04, 0x08, 0x48, 0x00, 0x00, 0x04, 0x04, 0x08, 0x40, 0x00, 0x00, 0x00, 0x0C,
+	 0x71, 0x00, 0x30, 0x30, 0x00, 0x00, 0x5E, 0x40, 0x01, 0x00, 0x18, 0x00, 0x36, 0xC0, 0xE8, 0x0E,
+	 0x1C, 0x00, 0x78, 0xC8, 0xA5, 0x40, 0x24, 0x00, 0x9E, 0xB0, 0xB9, 0x95, 0x08, 0x08, 0x00, 0xEA,
+	 0x40, 0x01, 0x0C, 0x08, 0x00, 0xEA, 0x00, 0x00, 0x1C, 0x08, 0x00, 0x00, 0x42, 0x07, 0x20, 0x08,
+	 0x7B, 0x00, 0xD4, 0x09, 0x2C, 0x04, 0x14, 0x00, 0x50, 0x14, 0x30, 0x04, 0x28, 0x0F, 0x28, 0x7F,
+	 0x18, 0x08, 0x20, 0x00, 0xFC, 0x01, 0x04, 0x10, 0x69, 0x00, 0xFD, 0xC3, 0x08, 0x10, 0x69, 0x00,
+	 0xFD, 0xC3, 0x08, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x48, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x48, 0x0C,
+	 0x00, 0x00, 0x7F, 0x00, 0x04, 0x04, 0x08, 0x48, 0x02, 0x00, 0x00, 0x00, 0x5E, 0x48, 0x00, 0x00,
+	 0x04, 0x04, 0x08, 0x40, 0x02, 0x00, 0x00, 0x0C, 0x71, 0x00, 0x30, 0x50, 0x00, 0x00, 0x5E, 0x48,
+	 0x01, 0x00, 0x18, 0x00, 0x3A, 0xC0, 0xE8, 0x04, 0x1C, 0x00, 0x78, 0xD0, 0xA5, 0x40, 0x24, 0x00,
+	 0x9E, 0xB0, 0xB9, 0x85, 0x2C, 0x04, 0x14, 0x00, 0x50, 0x14, 0x30, 0x04, 0x28, 0x0F, 0x28, 0x7F,
+	 0x08, 0x08, 0x00, 0xEA, 0x40, 0x01, 0x0C, 0x08, 0x00, 0xEA, 0x00, 0x00, 0x1C, 0x08, 0x00, 0x00,
+	 0x42, 0x07, 0x20, 0x08, 0x7B, 0x00, 0xD4, 0x09, 0x18, 0x08, 0xF0, 0x3F, 0xFC, 0x01, 0x04, 0x10,
+	 0x69, 0x00, 0xDD, 0xCD, 0x08, 0x10, 0x69, 0x00, 0xDD, 0xCD, 0x08, 0x0C, 0x00, 0x00, 0x00, 0x00,
+	 0x48, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x40, 0x01, 0x41, 0x01, 0x0C, 0x04, 0x40, 0x04,
+	 0x41, 0x04, 0x10, 0x04, 0xD6, 0x08, 0x56, 0x0A, 0x14, 0x04, 0x42, 0x02, 0x56, 0x0A, 0x18, 0x04,
+	 0x56, 0x0A, 0x40, 0x02, 0x1C, 0x04, 0x42, 0x0A, 0x42, 0x2A, 0x20, 0x04, 0xC2, 0x00, 0xD6, 0x08,
+	 0x24, 0x04, 0xD6, 0x08, 0xC0, 0x00, 0x28, 0x04, 0xC2, 0x08, 0xC2, 0x28, 0x08, 0x04, 0x40, 0x01,
+	 0x41, 0x01, 0x0C, 0x04, 0x00, 0x01, 0x01, 0x01, 0x10, 0x04, 0x56, 0x0A, 0x56, 0x0A, 0x14, 0x04,
+	 0x42, 0x02, 0x56, 0x0A, 0x18, 0x04, 0x56, 0x0A, 0x40, 0x02, 0x1C, 0x04, 0x42, 0x0A, 0x42, 0x2A,
+	 0x20, 0x04, 0x42, 0x02, 0x56, 0x0A, 0x24, 0x04, 0x56, 0x0A, 0x40, 0x02, 0x28, 0x04, 0x42, 0x0A,
+	 0x42, 0x2A, 0x08, 0x04, 0x40, 0x01, 0x41, 0x01, 0x0C, 0x04, 0x40, 0x04, 0x41, 0x04, 0x10, 0x04,
+	 0xCE, 0x08, 0x4E, 0x0A, 0x14, 0x04, 0x42, 0x02, 0x4E, 0x0A, 0x18, 0x04, 0x4E, 0x0A, 0x40, 0x02,
+	 0x1C, 0x04, 0x42, 0x0A, 0x42, 0x2A, 0x20, 0x04, 0xC2, 0x00, 0xCE, 0x08, 0x24, 0x04, 0xCE, 0x08,
+	 0xC0, 0x00, 0x28, 0x04, 0xC2, 0x08, 0xC2, 0x28, 0x08, 0x04, 0x40, 0x01, 0x41, 0x01, 0x0C, 0x04,
+	 0x00, 0x01, 0x01, 0x01, 0x10, 0x04, 0x4E, 0x0A, 0x4E, 0x0A, 0x14, 0x04, 0x42, 0x02, 0x4E, 0x0A,
+	 0x18, 0x04, 0x4E, 0x0A, 0x40, 0x02, 0x1C, 0x04, 0x42, 0x0A, 0x42, 0x2A, 0x20, 0x04, 0x42, 0x02,
+	 0x4E, 0x0A, 0x24, 0x04, 0x4E, 0x0A, 0x40, 0x02, 0x28, 0x04, 0x42, 0x0A, 0x42, 0x2A, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00,
+	 0x05, 0x00, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16,
+	 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16,
+	 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16,
+	 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x17, 0xA0, 0x17, 0xA0, 0x17,
+	 0xA0, 0x18, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06,
+	 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06,
+	 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06,
+	 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06,
+	 0xFF, 0x06, 0x00, 0x00, 0x65, 0x00, 0x65, 0x00, 0x65, 0x00, 0x65, 0x00, 0x5D, 0x00, 0x52, 0x00,
+	 0x48, 0x00, 0x40, 0x00, 0x38, 0x00, 0x31, 0x00, 0x2C, 0x00, 0x27, 0x00, 0x23, 0x00, 0x1F, 0x00,
+	 0x00, 0x00, 0x65, 0x00, 0x65, 0x00, 0x65, 0x00, 0x65, 0x00, 0x5D, 0x00, 0x52, 0x00, 0x48, 0x00,
+	 0x40, 0x00, 0x38, 0x00, 0x31, 0x00, 0x2C, 0x00, 0x27, 0x00, 0x23, 0x00, 0x1F, 0x00, 0x00, 0x00,
+	 0x19, 0x00, 0x19, 0x00, 0x19, 0x00, 0x19, 0x00, 0x19, 0x00, 0x19, 0x00, 0x19, 0x00, 0x19, 0x00,
+	 0x19, 0x00, 0x19, 0x00, 0x19, 0x00, 0x19, 0x00, 0x19, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
+	 0x15, 0x00, 0x6E, 0x6F, 0x6E, 0x2D, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20,
+	 0x53, 0x53, 0x49, 0x44, 0x20, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x01, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x00, 0x09, 0x00, 0x00, 0x01, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00,
+	 0x48, 0x45, 0x52, 0x4D, 0x45, 0x53, 0x20, 0x32, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x01, 0x00,
+	 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00,
+	 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x14, 0x00, 0x03, 0x00, 0x15, 0x00, 0x6E, 0x6F, 0x6E, 0x2D, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66,
+	 0x69, 0x65, 0x64, 0x20, 0x53, 0x53, 0x49, 0x44, 0x20, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x09, 0x00, 0x00, 0x01, 0x00, 0x64, 0x00,
+	 0x64, 0x00, 0x00, 0x00, 0x48, 0x45, 0x52, 0x4D, 0x45, 0x53, 0x20, 0x32, 0x00, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x04, 0x00,
+	 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x69, 0x72, 0x73, 0x74, 0x20, 0x57, 0x61,
+	 0x76, 0x65, 0x4C, 0x41, 0x4E, 0x20, 0x49, 0x49, 0x20, 0x53, 0x53, 0x49, 0x44, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0xFF, 0x0F, 0xF0, 0x0F, 0x0F, 0x00, 0x50, 0x01, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x14, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x07, 0x00, 0x30, 0x00, 0xFF, 0x00, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00,
+	 0x0A, 0x00, 0x0A, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x0A, 0x00,
+	 0x00, 0x00, 0x02, 0x01, 0x02, 0x04, 0x0B, 0x16, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x82, 0x84,
+	 0x8B, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x01, 0x00,
+	 0x00, 0x00, 0x03, 0x00, 0x20, 0x00, 0x1B, 0x00, 0x17, 0x00, 0x11, 0x00, 0x10, 0x00, 0x0B, 0x00,
+	 0x0B, 0x00, 0x09, 0x00, 0x17, 0x00, 0x14, 0x00, 0x10, 0x00, 0x0D, 0x00, 0x0B, 0x00, 0x09, 0x00,
+	 0x08, 0x00, 0x07, 0x00, 0x0D, 0x00, 0x0A, 0x00, 0x09, 0x00, 0x08, 0x00, 0x05, 0x00, 0x05, 0x00,
+	 0xD8, 0x0C, 0xC0, 0x08, 0x90, 0x0D, 0x60, 0x09, 0x48, 0x0E, 0x30, 0x0A, 0x24, 0x0F, 0x18, 0x0B,
+	 0x0B, 0x6E, 0x0B, 0x37, 0x02, 0x14, 0x01, 0x0A, 0xFF, 0x0F, 0xF0, 0x0F, 0xFF, 0x0F, 0xF0, 0x0F,
+	 0xFF, 0x0F, 0xF0, 0x0F, 0xFF, 0x0F, 0xF0, 0x0F, 0xFF, 0x0F, 0xF0, 0x0F, 0xFF, 0x0F, 0xF0, 0x0F,
+	 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xDD, 0x00, 0x50, 0xF2, 0x01, 0x01, 0x00,
+	 0x00, 0x50, 0xF2, 0x05, 0x02, 0x00, 0x00, 0x50, 0xF2, 0x02, 0x00, 0x50, 0xF2, 0x04, 0x02, 0x00,
+	 0x00, 0x50, 0xF2, 0x00, 0x00, 0x50, 0xF2, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x04, 0x00, 0x15, 0x00, 0x02, 0x00,
+	 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x04, 0x00, 0x10, 0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x00,
+	 0x15, 0x00, 0x20, 0x00, 0x11, 0x00, 0x20, 0x00, 0x16, 0x26, 0xE2, 0x2B, 0xEA, 0x2D, 0xC4, 0x2D,
+	 0xEE, 0x2D, 0x7E, 0x2C, 0x1E, 0x2E, 0x22, 0x2E, 0xFF, 0xFF, 0x2C, 0x2E, 0x00, 0x00, 0x4E, 0x28,
+	 0xD8, 0x2B, 0x22, 0x2E, 0xFF, 0xFF, 0x00, 0x00, 0x16, 0x26, 0xE2, 0x2B, 0xEA, 0x2D, 0xFF, 0xFF,
+	 0xEE, 0x2D, 0x7E, 0x2C, 0x1E, 0x2E, 0x22, 0x2E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xFF, 0xFF, 0x2C, 0x2E, 0x00, 0x00, 0xE2, 0x2B, 0x34, 0x2E, 0x22, 0x2E, 0x00, 0x00, 0x00, 0x05,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x00, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2A, 0x00, 0x00, 0x08, 0x32, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x00, 0x60, 0x1D, 0x00, 0x00, 0x00, 0x0D, 0x81,
+	 0x00, 0x60, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+	 0x00, 0x00, 0xDD, 0x00, 0xFF, 0xFF, 0x97, 0xDA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x10, 0x00, 0x19, 0x0A, 0x09, 0x46, 0x1C, 0x60, 0x18, 0x00, 0x19, 0x1D, 0x09, 0x42,
+	 0x1C, 0x60,
+
+};  /* fw_image_2_data */
+
+static const hcf_8 fw_image_3_data[] = {
+	 0x00, 0x60, 0x46, 0x74, 0xCD, 0xE2, 0x04, 0xE1, 0x02, 0x60, 0x00, 0xE1, 0x82, 0xF3, 0x21, 0x60,
+	 0xCE, 0x61, 0x60, 0x40, 0x01, 0x2B, 0x02, 0x00, 0x21, 0x60, 0x56, 0x61, 0x0F, 0x60, 0xE8, 0x64,
+	 0x59, 0xD1, 0x58, 0xD9, 0x59, 0xD1, 0x58, 0xD9, 0x3F, 0x44, 0x40, 0x26, 0x05, 0x00, 0x18, 0x60,
+	 0x22, 0xF3, 0x5A, 0xD1, 0xA0, 0x50, 0xA4, 0x50, 0x3F, 0x40, 0x02, 0x2B, 0x03, 0x00, 0x18, 0x60,
+	 0x74, 0x78, 0xFF, 0xFF, 0x04, 0x29, 0xFE, 0x01, 0xC4, 0xE2, 0x43, 0x64, 0x3A, 0xDB, 0x82, 0xF3,
+	 0xFF, 0xFF, 0x60, 0x41, 0x3F, 0x44, 0xFF, 0x01, 0x3F, 0x40, 0x40, 0x26, 0x05, 0x00, 0x18, 0x60,
+	 0x20, 0xF3, 0x5A, 0xD1, 0xA0, 0x50, 0xA4, 0x52, 0xC4, 0xE2, 0x00, 0x63, 0x81, 0xFD, 0x32, 0x7B,
+	 0x4D, 0xE2, 0xBF, 0xFE, 0xC4, 0xE2, 0x41, 0xFF, 0xE0, 0xFE, 0xE1, 0xFE, 0xE2, 0xFE, 0x43, 0xFF,
+	 0x44, 0xFF, 0x46, 0xFF, 0x83, 0xF3, 0x62, 0xFF, 0x60, 0x40, 0x05, 0x36, 0x2D, 0xFF, 0x07, 0x36,
+	 0xD5, 0xFE, 0x08, 0xE1, 0x88, 0x60, 0x85, 0x71, 0x8D, 0xE2, 0xA3, 0x60, 0x30, 0x78, 0xFF, 0xFF,
+	 0x00, 0x60, 0x10, 0x62, 0x1A, 0x60, 0x58, 0x4D, 0xB4, 0x78, 0xFF, 0xFF, 0x64, 0x41, 0xA9, 0x9C,
+	 0x60, 0x45, 0x1A, 0x60, 0x58, 0x4D, 0x88, 0x78, 0xFF, 0xFF, 0x82, 0xF1, 0x09, 0x60, 0xB4, 0x61,
+	 0x64, 0x44, 0x01, 0x27, 0x24, 0x00, 0x60, 0x40, 0x0E, 0x3A, 0x0D, 0x00, 0x01, 0x7C, 0x10, 0x60,
+	 0xF2, 0xF9, 0x44, 0x60, 0x08, 0x7C, 0x10, 0x60, 0xC4, 0xF9, 0x12, 0x60, 0xE5, 0xF1, 0x02, 0x60,
+	 0xB0, 0x61, 0xB1, 0x9C, 0x26, 0x00, 0x00, 0x7C, 0x10, 0x60, 0xF2, 0xF9, 0x40, 0x60, 0x08, 0x7C,
+	 0x10, 0x60, 0xC4, 0xF9, 0x12, 0x60, 0xE5, 0xF1, 0x02, 0x60, 0x90, 0x61, 0xB1, 0x9C, 0x09, 0x60,
+	 0x67, 0x65, 0xFF, 0xB4, 0xC4, 0x85, 0xE0, 0x84, 0xE0, 0x84, 0xC4, 0x81, 0x12, 0x00, 0xFF, 0xB4,
+	 0xED, 0xA0, 0x25, 0x60, 0xCC, 0x61, 0x04, 0x04, 0xE2, 0xA0, 0xD9, 0x81, 0x01, 0x04, 0xD9, 0x81,
+	 0xA1, 0xD1, 0x02, 0x60, 0x50, 0x61, 0x1F, 0x60, 0xF6, 0x65, 0xE0, 0x84, 0x44, 0xD3, 0xB1, 0x9C,
+	 0xC8, 0x81, 0x61, 0x47, 0x00, 0x7E, 0xE9, 0x81, 0x07, 0x60, 0xF0, 0x65, 0xA5, 0x81, 0x0B, 0xB9,
+	 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x85, 0xB5, 0x85, 0x04, 0x60, 0x44, 0x62, 0x1A, 0x60, 0x58, 0x4D,
+	 0x88, 0x78, 0xFF, 0xFF, 0x82, 0xF3, 0xC8, 0x61, 0x61, 0x54, 0xCD, 0xE2, 0x60, 0x40, 0x01, 0x27,
+	 0x2E, 0x00, 0xCC, 0x84, 0xE0, 0x85, 0x15, 0x60, 0xA2, 0xE7, 0x1F, 0x60, 0x86, 0x64, 0x1A, 0x60,
+	 0x58, 0x4F, 0x7D, 0x78, 0xFF, 0xFF, 0x1F, 0x60, 0xA2, 0x64, 0x1A, 0x60, 0x58, 0x4F, 0x7D, 0x78,
+	 0xFF, 0xFF, 0x1F, 0x60, 0xBE, 0x64, 0x1A, 0x60, 0x58, 0x4F, 0x7D, 0x78, 0xFF, 0xFF, 0x1F, 0x60,
+	 0xDA, 0x64, 0x1A, 0x60, 0x58, 0x4F, 0x7D, 0x78, 0xFF, 0xFF, 0x75, 0x64, 0x06, 0x61, 0x61, 0x48,
+	 0x60, 0x44, 0x80, 0xBC, 0xFF, 0xB4, 0x60, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x21, 0x60,
+	 0xEC, 0x7C, 0x07, 0x60, 0xE9, 0xF9, 0x21, 0x60, 0x74, 0x63, 0x14, 0x61, 0x21, 0x00, 0x11, 0x60,
+	 0x62, 0xF1, 0xFF, 0xB4, 0xED, 0xA0, 0x64, 0x41, 0x04, 0x04, 0xE2, 0xA0, 0xD9, 0x81, 0x01, 0x04,
+	 0xD9, 0x81, 0xA1, 0xD1, 0x10, 0x60, 0x91, 0xF3, 0x64, 0x41, 0xFF, 0xB1, 0xFF, 0x60, 0x00, 0x65,
+	 0xA4, 0x84, 0x34, 0x94, 0xA2, 0xDB, 0x5A, 0xD3, 0x64, 0x41, 0xA5, 0x81, 0xFF, 0xB4, 0x34, 0x94,
+	 0xA2, 0xDB, 0x22, 0x60, 0x58, 0x7C, 0x07, 0x60, 0xE9, 0xF9, 0x21, 0x60, 0x02, 0x63, 0x13, 0x61,
+	 0x1A, 0x60, 0x58, 0x4D, 0x9C, 0x78, 0xFF, 0xFF, 0x07, 0x60, 0xE9, 0xF3, 0x31, 0x40, 0x80, 0x26,
+	 0x36, 0xA4, 0x07, 0x60, 0xE9, 0xFB, 0x60, 0x43, 0x09, 0x61, 0x1A, 0x60, 0x58, 0x4D, 0x9C, 0x78,
+	 0xFF, 0xFF, 0x82, 0xF3, 0x22, 0x60, 0xC4, 0x61, 0x00, 0x7C, 0x7E, 0x63, 0x59, 0xD9, 0xFE, 0x1F,
+	 0x60, 0x40, 0x01, 0x27, 0x03, 0x00, 0x23, 0x60, 0x46, 0x65, 0x15, 0x00, 0xFF, 0xB4, 0xF9, 0xA0,
+	 0x23, 0x60, 0x68, 0x65, 0x01, 0x7C, 0x0D, 0x04, 0xED, 0xA0, 0x23, 0x60, 0x8A, 0x65, 0x11, 0x7C,
+	 0x08, 0x04, 0xE2, 0xA0, 0x23, 0x60, 0xAC, 0x65, 0x21, 0x7C, 0x03, 0x04, 0x23, 0x60, 0xCE, 0x65,
+	 0x31, 0x7C, 0x64, 0x5F, 0x64, 0xFB, 0xA5, 0xD3, 0xDA, 0x85, 0xF0, 0xA0, 0x22, 0x60, 0xC4, 0x61,
+	 0x08, 0x06, 0x40, 0x54, 0x58, 0x53, 0x08, 0xFF, 0xA2, 0x60, 0xE7, 0x64, 0x43, 0xFB, 0x08, 0xFF,
+	 0xFF, 0x01, 0x60, 0x43, 0x60, 0x46, 0xA5, 0xD1, 0xDA, 0x85, 0xA5, 0xD3, 0xDA, 0x85, 0x59, 0xD9,
+	 0x59, 0xDB, 0x59, 0xD9, 0x59, 0xDB, 0xFB, 0x1F, 0x0C, 0x63, 0xA5, 0xD1, 0xDA, 0x85, 0xA5, 0xD3,
+	 0xDA, 0x85, 0x59, 0xD9, 0x59, 0xDB, 0x59, 0xD9, 0x59, 0xDB, 0xF7, 0x1F, 0x66, 0x44, 0x0E, 0x63,
+	 0x53, 0x93, 0x60, 0x40, 0x10, 0x36, 0x07, 0x00, 0x65, 0x44, 0x48, 0xD3, 0x59, 0xD9, 0x59, 0xDB,
+	 0x59, 0xD9, 0x59, 0xDB, 0xFB, 0x1F, 0x12, 0x60, 0xBC, 0xF1, 0x64, 0xF3, 0x64, 0x43, 0xDB, 0x81,
+	 0x25, 0x60, 0x5A, 0x65, 0x60, 0x40, 0x01, 0x37, 0x12, 0x00, 0x11, 0x37, 0x17, 0x00, 0x21, 0x37,
+	 0x1D, 0x00, 0x31, 0x37, 0x22, 0x00, 0xA3, 0xD1, 0x12, 0x60, 0xB7, 0xF5, 0x64, 0x44, 0xFF, 0xB4,
+	 0x12, 0x60, 0xB6, 0xFB, 0x64, 0x47, 0xFF, 0xB4, 0x12, 0x60, 0xAD, 0xF1, 0x1D, 0x00, 0xA1, 0xD3,
+	 0x12, 0x60, 0xB8, 0xF5, 0xFF, 0xB4, 0x12, 0x60, 0xAE, 0xF1, 0x16, 0x00, 0xA1, 0xD3, 0x12, 0x60,
+	 0xB9, 0xF5, 0x60, 0x47, 0xFF, 0xB4, 0x12, 0x60, 0xAF, 0xF1, 0x0E, 0x00, 0x59, 0xD3, 0x12, 0x60,
+	 0xBA, 0xF5, 0xFF, 0xB4, 0x12, 0x60, 0xB0, 0xF1, 0x07, 0x00, 0x59, 0xD3, 0x12, 0x60, 0xBB, 0xF5,
+	 0x60, 0x47, 0xFF, 0xB4, 0x12, 0x60, 0xB1, 0xF1, 0x12, 0x60, 0xB5, 0xFB, 0x12, 0x60, 0xB2, 0xF9,
+	 0x66, 0x42, 0xFC, 0xA2, 0xA2, 0xD3, 0x24, 0x60, 0x48, 0x63, 0xCC, 0x84, 0xE8, 0x84, 0xCC, 0x81,
+	 0x63, 0x45, 0xA6, 0xD3, 0xDA, 0x82, 0xFF, 0xB4, 0xFF, 0xFF, 0x03, 0x03, 0x60, 0x40, 0x80, 0x2B,
+	 0x03, 0x00, 0xDA, 0x86, 0xCD, 0x81, 0xF5, 0x01, 0x00, 0xB9, 0xA6, 0xD3, 0x0B, 0x03, 0x5A, 0xD1,
+	 0xDA, 0x86, 0xFF, 0xB4, 0xE0, 0x84, 0xC4, 0x84, 0x5C, 0x90, 0xBD, 0xD9, 0xFD, 0x02, 0xCD, 0x81,
+	 0x66, 0x42, 0xF2, 0x02, 0x5A, 0xD3, 0x24, 0x60, 0x86, 0x65, 0xD7, 0x80, 0xBD, 0xDB, 0xFD, 0x02,
+	 0x64, 0xF3, 0x15, 0x60, 0xDD, 0xF1, 0x60, 0x40, 0x01, 0x27, 0x09, 0x00, 0x64, 0x40, 0x10, 0x26,
+	 0x06, 0x00, 0x13, 0x64, 0xAD, 0xFB, 0x01, 0x60, 0x67, 0x64, 0x37, 0xFB, 0x09, 0x00, 0x08, 0x64,
+	 0xAD, 0xFB, 0x82, 0xF3, 0x01, 0x60, 0x67, 0x7C, 0x60, 0x40, 0x01, 0x27, 0x5B, 0x7C, 0x37, 0xF9,
+	 0x13, 0x60, 0x5B, 0xF1, 0x64, 0xF3, 0x15, 0x60, 0xD2, 0xF9, 0x15, 0x60, 0xD6, 0xF9, 0x60, 0x40,
+	 0x01, 0x27, 0x0A, 0x00, 0xFF, 0xB5, 0x10, 0x60, 0xA8, 0x63, 0x65, 0x41, 0xCD, 0x81, 0x06, 0xA3,
+	 0xFD, 0x02, 0xFA, 0xA3, 0xA3, 0xD3, 0x0F, 0x00, 0x01, 0x60, 0xFF, 0x65, 0xA4, 0x84, 0x11, 0x60,
+	 0x14, 0x61, 0xA1, 0xD1, 0xFF, 0xFF, 0xD0, 0x80, 0x08, 0xA1, 0xFB, 0x02, 0xFC, 0xA1, 0xA1, 0xD3,
+	 0x15, 0x60, 0xD2, 0xF1, 0xFF, 0xB4, 0xD0, 0x80, 0xFF, 0xFF, 0x04, 0x07, 0x15, 0x60, 0xD2, 0xFB,
+	 0x15, 0x60, 0xD6, 0xFB, 0x25, 0x60, 0x7A, 0x63, 0x24, 0x60, 0x08, 0x65, 0x12, 0x60, 0xB6, 0xF1,
+	 0x23, 0x60, 0xF0, 0x61, 0x25, 0x60, 0x68, 0x64, 0x40, 0x4F, 0x04, 0x64, 0xC3, 0x60, 0x58, 0x4D,
+	 0x25, 0x78, 0xFF, 0xFF, 0x25, 0x60, 0x82, 0x63, 0x12, 0x60, 0xB5, 0xF1, 0x24, 0x60, 0x48, 0x65,
+	 0x25, 0x60, 0x66, 0x64, 0x40, 0x4F, 0x08, 0x64, 0xC3, 0x60, 0x58, 0x4D, 0x25, 0x78, 0xFF, 0xFF,
+	 0x64, 0xF3, 0x08, 0x7C, 0x38, 0xF9, 0x24, 0x60, 0xE0, 0x61, 0x60, 0x40, 0x01, 0x2B, 0x0E, 0x00,
+	 0x01, 0x37, 0x06, 0x00, 0x11, 0x37, 0x03, 0x00, 0x21, 0x3B, 0x1E, 0xA1, 0x1E, 0xA1, 0x1E, 0xA1,
+	 0x1C, 0x63, 0x24, 0x60, 0xC2, 0x64, 0x59, 0xD1, 0x58, 0xD9, 0xFD, 0x1F, 0x12, 0x60, 0xB2, 0xF3,
+	 0x00, 0x7C, 0x60, 0x45, 0x70, 0x62, 0x1A, 0x60, 0x58, 0x4D, 0x88, 0x78, 0xFF, 0xFF, 0x04, 0x29,
+	 0xFE, 0x01, 0x00, 0x60, 0x10, 0x62, 0x1A, 0x60, 0x58, 0x4D, 0xB4, 0x78, 0xFF, 0xFF, 0x01, 0x61,
+	 0xB1, 0x9C, 0x60, 0x45, 0x1A, 0x60, 0x58, 0x4D, 0x88, 0x78, 0xFF, 0xFF, 0x18, 0x60, 0x50, 0x78,
+	 0xFF, 0xFF, 0x44, 0xD3, 0x80, 0x7C, 0x60, 0x48, 0x60, 0x47, 0x00, 0x7F, 0xB0, 0x8A, 0xFF, 0xFF,
+	 0x01, 0x16, 0xFE, 0x01, 0x2F, 0x58, 0xFF, 0xFF, 0xD5, 0x60, 0x84, 0xE7, 0x62, 0x47, 0x80, 0xBF,
+	 0x60, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x64, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01,
+	 0x65, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x95, 0x60, 0x84, 0xE7, 0x2D, 0x58, 0xFF, 0xFF,
+	 0x00, 0x7C, 0xBD, 0xD3, 0xD5, 0x60, 0x84, 0xE7, 0x60, 0x47, 0x80, 0xBF, 0x60, 0x4A, 0xBD, 0xD3,
+	 0x01, 0x16, 0xFE, 0x01, 0x90, 0x8A, 0xBD, 0xD3, 0x01, 0x16, 0xFE, 0x01, 0x90, 0x8A, 0xFF, 0xFF,
+	 0x01, 0x16, 0xFE, 0x01, 0xCD, 0x81, 0x95, 0x60, 0x84, 0xE7, 0xEB, 0x02, 0x2D, 0x58, 0xFF, 0xFF,
+	 0xD5, 0x60, 0x84, 0xE7, 0x62, 0x4A, 0x02, 0x64, 0x01, 0x16, 0xFE, 0x01, 0xCC, 0x84, 0xFF, 0xFF,
+	 0xFD, 0x02, 0x7C, 0x49, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x68, 0x5C, 0x7C, 0x49, 0xFF, 0xFF,
+	 0x01, 0x16, 0xFE, 0x01, 0x68, 0x44, 0x95, 0x60, 0x84, 0xE7, 0x2D, 0x58, 0xFF, 0xFF, 0x42, 0xFF,
+	 0x40, 0xFF, 0x3F, 0x40, 0x02, 0x27, 0x33, 0x00, 0x43, 0x45, 0x20, 0x44, 0x20, 0xBC, 0x40, 0x40,
+	 0x3F, 0x40, 0x02, 0x27, 0x1B, 0x00, 0x60, 0xBC, 0x40, 0x40, 0xDD, 0xFE, 0x18, 0x60, 0x07, 0xF1,
+	 0xAD, 0x4F, 0x00, 0x7F, 0xFA, 0xB4, 0x64, 0x41, 0x64, 0xF1, 0x02, 0xB1, 0x04, 0x65, 0x02, 0x02,
+	 0x64, 0x40, 0x01, 0x2B, 0x01, 0x65, 0xB4, 0x84, 0xA0, 0x5D, 0x00, 0xEE, 0x19, 0x61, 0xCD, 0x81,
+	 0xFF, 0xFF, 0xFD, 0x02, 0x43, 0x45, 0x3F, 0x40, 0x02, 0x27, 0x11, 0x00, 0xAE, 0x4F, 0xFD, 0xB4,
+	 0x04, 0xBC, 0xA0, 0x5E, 0x00, 0x60, 0x02, 0x71, 0x8D, 0xE2, 0x40, 0xE1, 0xA1, 0xFF, 0x04, 0xAC,
+	 0xA0, 0x5E, 0x0F, 0x60, 0xA0, 0x71, 0x8D, 0xE2, 0xA1, 0xFF, 0xDD, 0xFE, 0x1E, 0x00, 0x43, 0x45,
+	 0x20, 0x44, 0x60, 0xBC, 0x40, 0x40, 0xAE, 0x4F, 0xFD, 0xB4, 0x04, 0xBC, 0xA0, 0x5E, 0xDD, 0xFE,
+	 0x00, 0x60, 0x02, 0x71, 0x8D, 0xE2, 0x40, 0xE1, 0xA1, 0xFF, 0x04, 0xAC, 0xA0, 0x5E, 0x00, 0x60,
+	 0xC8, 0x71, 0x8D, 0xE2, 0xA1, 0xFF, 0x0C, 0x60, 0x00, 0x62, 0x00, 0x60, 0x71, 0x7C, 0x10, 0x60,
+	 0x00, 0x65, 0x1A, 0x60, 0x58, 0x4D, 0x88, 0x78, 0xFF, 0xFF, 0x20, 0x60, 0x3C, 0x63, 0x1E, 0x61,
+	 0x1A, 0x60, 0x58, 0x4D, 0x9C, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x14, 0x71, 0x8D, 0xE2, 0xA1, 0xFF,
+	 0x31, 0x44, 0x40, 0x26, 0x02, 0x00, 0x80, 0x26, 0x17, 0x00, 0x21, 0x60, 0xEC, 0x63, 0x07, 0x60,
+	 0xE9, 0xFD, 0x09, 0x61, 0x1A, 0x60, 0x58, 0x4D, 0x9C, 0x78, 0xFF, 0xFF, 0x31, 0x44, 0x40, 0x2A,
+	 0x14, 0x00, 0x31, 0x44, 0x7F, 0xB4, 0x40, 0x51, 0xAE, 0x4C, 0x10, 0x26, 0x0E, 0x00, 0x07, 0x60,
+	 0xEA, 0xFB, 0x31, 0x44, 0x80, 0xBC, 0x40, 0x51, 0x22, 0x60, 0x22, 0x63, 0x07, 0x60, 0xE9, 0xFD,
+	 0x09, 0x61, 0x1A, 0x60, 0x58, 0x4D, 0x9C, 0x78, 0xFF, 0xFF, 0x20, 0x60, 0xF0, 0x63, 0x03, 0x61,
+	 0x1A, 0x60, 0x58, 0x4D, 0x9C, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x10, 0x62, 0x19, 0x60, 0x8F, 0x7C,
+	 0x00, 0x60, 0xAC, 0x65, 0x1A, 0x60, 0x58, 0x4D, 0x88, 0x78, 0xFF, 0xFF, 0x80, 0xE1, 0xBF, 0xFE,
+	 0xA1, 0x4F, 0x70, 0xB4, 0x50, 0x36, 0xAF, 0x00, 0x20, 0x36, 0x03, 0x00, 0x18, 0x60, 0x24, 0x78,
+	 0xFF, 0xFF, 0x01, 0x60, 0x1A, 0xE1, 0xDF, 0xFE, 0x19, 0xFF, 0x00, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF,
+	 0x3F, 0x40, 0x20, 0x2B, 0xA1, 0x00, 0x01, 0x16, 0xFE, 0x01, 0x38, 0x69, 0xA1, 0xFF, 0xFF, 0xFF,
+	 0x68, 0x44, 0x01, 0x2A, 0x99, 0x00, 0x13, 0x60, 0x09, 0xF3, 0xFF, 0xFF, 0xDC, 0x84, 0x00, 0x36,
+	 0x00, 0x3B, 0xA2, 0xDB, 0x64, 0xF1, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x9C, 0x47, 0x00, 0x43, 0x45,
+	 0x20, 0x44, 0x20, 0xBC, 0x40, 0x40, 0x18, 0x60, 0x22, 0xF3, 0x3F, 0x40, 0x40, 0x26, 0x01, 0x00,
+	 0xA0, 0x50, 0x3F, 0x40, 0x02, 0x2B, 0x29, 0x00, 0xAE, 0x4F, 0xFD, 0xB4, 0xA0, 0x5E, 0xDD, 0xFE,
+	 0xAC, 0x4F, 0x10, 0xBC, 0xA0, 0x5C, 0xFF, 0xFF, 0x10, 0xAC, 0xA0, 0x5C, 0x00, 0x60, 0xC8, 0x71,
+	 0x8D, 0xE2, 0x40, 0xE1, 0x40, 0x29, 0xFE, 0x01, 0x0C, 0x60, 0x00, 0x62, 0x00, 0x60, 0x71, 0x7C,
+	 0x10, 0x60, 0x00, 0x65, 0x1A, 0x60, 0x58, 0x4D, 0x88, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0xC8, 0x71,
+	 0x8D, 0xE2, 0x40, 0xE1, 0x40, 0x29, 0xFE, 0x01, 0x01, 0x60, 0x08, 0xE1, 0x64, 0xF1, 0x82, 0xF9,
+	 0x05, 0x7C, 0x83, 0xF9, 0xDF, 0xFE, 0x19, 0xFF, 0xFF, 0xFF, 0x18, 0x60, 0x07, 0xF1, 0xAD, 0x4F,
+	 0x00, 0x7F, 0xFA, 0xB4, 0x64, 0x41, 0x64, 0xF1, 0x02, 0xB1, 0x04, 0x65, 0x02, 0x02, 0x64, 0x40,
+	 0x01, 0x2B, 0x01, 0x65, 0xB4, 0x84, 0xA0, 0x5D, 0xBF, 0xFE, 0x45, 0x00, 0x18, 0x60, 0x07, 0xF1,
+	 0xAD, 0x4F, 0x00, 0x7F, 0xFA, 0xB4, 0x64, 0x41, 0x64, 0xF1, 0x02, 0xB1, 0x04, 0x65, 0x02, 0x02,
+	 0x64, 0x40, 0x01, 0x2B, 0x01, 0x65, 0xB4, 0x84, 0xA0, 0x5D, 0x43, 0x45, 0x20, 0x44, 0x20, 0xBC,
+	 0x40, 0x40, 0x02, 0x60, 0xEE, 0x64, 0x3F, 0x40, 0x02, 0x27, 0xC8, 0x64, 0x81, 0xFB, 0x82, 0xF9,
+	 0x05, 0x64, 0x83, 0xFB, 0xDF, 0xFE, 0x19, 0xFF, 0x26, 0x00, 0x20, 0x44, 0x20, 0xBC, 0x40, 0x40,
+	 0x43, 0x45, 0xA4, 0xD1, 0xDA, 0x83, 0xC3, 0x85, 0x80, 0xE1, 0xDF, 0xFE, 0xBD, 0xD3, 0xFF, 0xFF,
+	 0x60, 0x48, 0x60, 0x47, 0x80, 0xBC, 0x00, 0x7F, 0x60, 0x4A, 0xD7, 0x80, 0xA1, 0xFF, 0xF6, 0x02,
+	 0xBF, 0xFE, 0x11, 0x00, 0x43, 0x45, 0xA4, 0xD1, 0xDA, 0x83, 0x0D, 0x18, 0x64, 0x44, 0x00, 0x61,
+	 0xFA, 0xA4, 0xDD, 0x81, 0xFD, 0x02, 0x1A, 0x60, 0x58, 0x4D, 0x9C, 0x78, 0xFF, 0xFF, 0xBF, 0xFE,
+	 0x02, 0x00, 0xF1, 0xFE, 0x01, 0x00, 0x25, 0x43, 0x21, 0xE1, 0x00, 0x64, 0xBF, 0xDB, 0x20, 0x44,
+	 0x20, 0x2A, 0x07, 0x00, 0x07, 0xB4, 0x04, 0x36, 0xC3, 0xFE, 0x06, 0x36, 0xCC, 0xFE, 0x07, 0x36,
+	 0xD5, 0xFE, 0x20, 0x44, 0xD8, 0xB4, 0x40, 0x40, 0x1F, 0x60, 0x2C, 0x63, 0xBD, 0xD3, 0x03, 0x61,
+	 0x0F, 0x1B, 0x04, 0xA3, 0xBD, 0xD3, 0x04, 0x61, 0x0B, 0x1B, 0x04, 0xA3, 0xBD, 0xD3, 0x06, 0x61,
+	 0x07, 0x1B, 0x04, 0xA3, 0xBD, 0xD3, 0x07, 0x61, 0x03, 0x1B, 0xC3, 0x60, 0x53, 0x78, 0xFF, 0xFF,
+	 0xA3, 0xD1, 0x40, 0x44, 0x20, 0x44, 0x07, 0xB5, 0xD4, 0x85, 0x35, 0x80, 0x24, 0x45, 0x1F, 0x60,
+	 0x6C, 0x64, 0x44, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0x43, 0x45, 0x20, 0x44, 0x20, 0xBC, 0x40, 0x40,
+	 0x64, 0x43, 0xBD, 0xD3, 0xBD, 0xD1, 0x40, 0x44, 0x10, 0x27, 0x19, 0x00, 0x3F, 0x40, 0x02, 0x2B,
+	 0x06, 0x00, 0x24, 0x47, 0x08, 0x2B, 0x13, 0x00, 0x07, 0xB4, 0x01, 0x36, 0x11, 0x00, 0xFF, 0x60,
+	 0x7F, 0x65, 0x15, 0x60, 0xA2, 0x64, 0x24, 0x40, 0x08, 0x2B, 0xA4, 0x84, 0xA0, 0x57, 0xFF, 0xFF,
+	 0x64, 0x49, 0xFF, 0xFF, 0x68, 0x44, 0x01, 0x16, 0xFD, 0x01, 0x00, 0x7F, 0xA3, 0xDB, 0xAB, 0x01,
+	 0x64, 0x42, 0x1A, 0x60, 0x58, 0x4D, 0xB4, 0x78, 0xFF, 0xFF, 0xBD, 0xD9, 0xA3, 0xDB, 0xA3, 0x01,
+	 0x43, 0x45, 0x20, 0x44, 0x20, 0xBC, 0x40, 0x40, 0x64, 0x43, 0xBD, 0xD3, 0xA3, 0xD1, 0x40, 0x44,
+	 0x10, 0x2B, 0x16, 0x00, 0xBE, 0xD1, 0xFF, 0xFF, 0x15, 0x60, 0x80, 0xE7, 0x24, 0x40, 0x07, 0x27,
+	 0x04, 0x00, 0xAC, 0x4F, 0x10, 0xBC, 0x00, 0x7F, 0xA0, 0x5C, 0x64, 0x4A, 0xFF, 0xFF, 0x01, 0x16,
+	 0xFE, 0x01, 0x24, 0x40, 0x20, 0x27, 0x1D, 0x00, 0xAC, 0x4F, 0xEF, 0xB4, 0xA0, 0x5C, 0x19, 0x00,
+	 0x3F, 0x40, 0x02, 0x2B, 0x06, 0x00, 0x24, 0x47, 0x08, 0x2B, 0x13, 0x00, 0x07, 0xB4, 0x01, 0x36,
+	 0x11, 0x00, 0x15, 0x60, 0x22, 0x64, 0x24, 0x40, 0x08, 0x27, 0x80, 0xBC, 0x7C, 0x48, 0xBE, 0xD3,
+	 0xA0, 0x57, 0x60, 0x48, 0x64, 0x44, 0x80, 0xBC, 0xFF, 0xB4, 0x60, 0x4A, 0xFF, 0xFF, 0x01, 0x16,
+	 0xFE, 0x01, 0x69, 0x01, 0x01, 0x61, 0x1A, 0x60, 0x58, 0x4D, 0x9C, 0x78, 0xFF, 0xFF, 0x63, 0x01,
+	 0x28, 0xF3, 0xFF, 0xFF, 0x60, 0x47, 0x0F, 0xB4, 0x9A, 0x00, 0xFF, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x04, 0x64, 0x0F, 0x60, 0x9F, 0xFB, 0x27, 0x00, 0x0C, 0x64, 0x3F, 0x40, 0x02, 0x2B, 0x23, 0x00,
+	 0x29, 0xF1, 0x0F, 0x60, 0x9F, 0xFB, 0x5A, 0xD9, 0x1C, 0x60, 0xD0, 0x64, 0x7F, 0xFB, 0xFF, 0xFF,
+	 0x2D, 0xFF, 0xF0, 0x60, 0xC7, 0x78, 0xFF, 0xFF, 0x22, 0x60, 0x22, 0x63, 0x09, 0x61, 0x1A, 0x60,
+	 0x58, 0x4D, 0x9C, 0x78, 0xFF, 0xFF, 0x77, 0x00, 0xD3, 0xF3, 0xFF, 0xFF, 0xFE, 0xB4, 0xD3, 0xFB,
+	 0x06, 0x64, 0x0F, 0x60, 0x9F, 0xFB, 0xFF, 0xFF, 0x2D, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x08, 0x64, 0x0F, 0x60, 0x9F, 0xFB, 0x1D, 0x60, 0x4F, 0x64, 0x7F, 0xFB, 0xFF, 0xFF, 0x2D, 0xFF,
+	 0xF0, 0x60, 0xC7, 0x78, 0xFF, 0xFF, 0x29, 0xF3, 0x11, 0x60, 0xF9, 0x65, 0x60, 0x5C, 0x3F, 0x40,
+	 0x02, 0x2B, 0x13, 0x00, 0x00, 0x37, 0x11, 0x00, 0x01, 0x3B, 0x55, 0x00, 0x11, 0x60, 0x19, 0x63,
+	 0xFF, 0xB7, 0x60, 0x5C, 0xA3, 0xD3, 0x08, 0xA3, 0x00, 0x7E, 0xD0, 0x80, 0xD7, 0x80, 0x02, 0x03,
+	 0xF9, 0x02, 0x49, 0x00, 0xF4, 0xA3, 0xA3, 0xD3, 0x05, 0x00, 0x00, 0xBC, 0xF2, 0xA4, 0x43, 0x03,
+	 0x42, 0x07, 0x64, 0x44, 0x64, 0xFB, 0x82, 0xFB, 0xC8, 0x64, 0x81, 0xFB, 0x07, 0x64, 0x83, 0xFB,
+	 0x1D, 0x60, 0x4F, 0x64, 0x7F, 0xFB, 0xFF, 0xFF, 0xDF, 0xFE, 0x00, 0x64, 0x19, 0xFF, 0xF0, 0x60,
+	 0xC7, 0x78, 0xFF, 0xFF, 0x88, 0xFF, 0xBA, 0x60, 0x98, 0x71, 0x8D, 0xE2, 0x01, 0x11, 0x09, 0x00,
+	 0x71, 0x40, 0x80, 0x27, 0xFB, 0x01, 0x88, 0xE2, 0xBA, 0x60, 0xD0, 0x64, 0x03, 0xFB, 0x8D, 0xFF,
+	 0x15, 0x00, 0x8D, 0xFF, 0xB1, 0x60, 0xED, 0x63, 0x06, 0x60, 0x0B, 0xFD, 0xFF, 0xFF, 0x62, 0xFF,
+	 0x1D, 0x60, 0x3C, 0x63, 0x7F, 0xFD, 0xFF, 0xFF, 0x1A, 0xFF, 0xF0, 0x60, 0xC7, 0x78, 0xFF, 0xFF,
+	 0xA4, 0x60, 0x7C, 0x63, 0x06, 0x60, 0x0B, 0xFD, 0xFF, 0xFF, 0x62, 0xFF, 0x29, 0xF5, 0x1F, 0x60,
+	 0x26, 0x63, 0x1E, 0x60, 0xF8, 0x64, 0xBD, 0xDB, 0x66, 0x44, 0xBD, 0xDB, 0x02, 0x64, 0xA3, 0xDB,
+	 0xFF, 0xFF, 0x2B, 0xFF, 0xF9, 0xFE, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x66, 0x01, 0x00, 0x36,
+	 0x67, 0x01, 0x01, 0x36, 0x69, 0x01, 0x02, 0x36, 0x7F, 0x01, 0x03, 0x36, 0x89, 0x01, 0x04, 0x36,
+	 0xC1, 0x01, 0x05, 0x36, 0xBF, 0x01, 0x06, 0x36, 0xF1, 0x01, 0x07, 0x36, 0xBB, 0x01, 0x08, 0x36,
+	 0x8A, 0x01, 0x09, 0x36, 0x0C, 0x00, 0x0A, 0x36, 0x0D, 0x00, 0x0B, 0x36, 0x0E, 0x00, 0x0C, 0x36,
+	 0x17, 0x00, 0x0D, 0x36, 0x0D, 0x00, 0x0E, 0x36, 0x1D, 0x00, 0x0F, 0x36, 0x41, 0x00, 0x02, 0x60,
+	 0x00, 0x64, 0x08, 0x00, 0x04, 0x60, 0x00, 0x64, 0x05, 0x00, 0x00, 0x60, 0x01, 0x64, 0x02, 0x00,
+	 0x20, 0x60, 0x00, 0x64, 0x32, 0x45, 0xB4, 0x85, 0x45, 0x52, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0xB2, 0x60, 0xD0, 0x63, 0x06, 0x60, 0x0B, 0xFD, 0x62, 0xFF, 0xFF, 0xFF, 0x1A, 0xFF, 0x00, 0x67,
+	 0x23, 0x58, 0xFF, 0xFF, 0x3F, 0x40, 0x02, 0x2B, 0x15, 0x00, 0x88, 0xFF, 0xBA, 0x60, 0x98, 0x71,
+	 0x8D, 0xE2, 0x01, 0x11, 0x09, 0x00, 0x71, 0x40, 0x80, 0x27, 0xFB, 0x01, 0x88, 0xE2, 0xBA, 0x60,
+	 0xD0, 0x64, 0x03, 0xFB, 0x8D, 0xFF, 0x11, 0x00, 0x8D, 0xFF, 0x90, 0x60, 0x00, 0xE8, 0xB1, 0x60,
+	 0xED, 0x63, 0x04, 0x00, 0x91, 0x60, 0x00, 0xE8, 0xB2, 0x60, 0xB6, 0x63, 0x2A, 0xE8, 0x06, 0x60,
+	 0x0B, 0xFD, 0xFF, 0xFF, 0x62, 0xFF, 0xFF, 0xFF, 0x1A, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0xD2, 0xF3, 0xFF, 0xFF, 0xEF, 0xB4, 0xD2, 0xFB, 0xAD, 0x4F, 0xFD, 0xB4, 0xA0, 0x5D, 0xD0, 0x60,
+	 0x00, 0xE8, 0x2A, 0xE8, 0xD9, 0x60, 0xFE, 0x64, 0x32, 0x45, 0xA4, 0x85, 0x45, 0x52, 0x99, 0xFF,
+	 0xA5, 0x4F, 0xFF, 0xB4, 0x07, 0xFB, 0x98, 0xFF, 0xA4, 0x60, 0x7C, 0x63, 0x06, 0x60, 0x0B, 0xFD,
+	 0x62, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x30, 0x44, 0x02, 0xA8, 0x00, 0xE1, 0x07, 0x02,
+	 0x62, 0xFF, 0x63, 0xFF, 0x64, 0xFF, 0x65, 0xFF, 0x66, 0xFF, 0xBF, 0xFE, 0xA1, 0xFF, 0x82, 0xFF,
+	 0x88, 0xFF, 0x6C, 0x40, 0x41, 0xFF, 0xC4, 0xE2, 0x43, 0xFF, 0x5C, 0x49, 0x08, 0xE1, 0xA3, 0x60,
+	 0x30, 0x78, 0xFF, 0xFF, 0x30, 0x44, 0x02, 0xA8, 0x00, 0xE1, 0x02, 0x02, 0xA1, 0xFF, 0xFF, 0xFF,
+	 0x82, 0xFF, 0x88, 0xFF, 0xA8, 0xE2, 0x01, 0x70, 0xAD, 0xF1, 0x00, 0x6B, 0x89, 0xFF, 0x64, 0x54,
+	 0x88, 0xFF, 0x9F, 0xFE, 0x02, 0x05, 0x64, 0x44, 0x60, 0x54, 0xCD, 0xE2, 0xC2, 0x64, 0x3A, 0xDB,
+	 0xBC, 0xFF, 0xB5, 0xFF, 0x1D, 0xFF, 0x26, 0x44, 0x02, 0xB4, 0x40, 0x46, 0x3C, 0x44, 0x00, 0xBC,
+	 0xFF, 0xFF, 0x06, 0x03, 0x27, 0x40, 0x26, 0x22, 0x03, 0x00, 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE,
+	 0x27, 0x44, 0x20, 0x2A, 0x04, 0x00, 0xA0, 0x60, 0x00, 0xEA, 0xB0, 0x60, 0x00, 0xEA, 0x5C, 0x44,
+	 0x27, 0x44, 0x18, 0xB4, 0x40, 0x47, 0x00, 0xE1, 0xA4, 0xE2, 0xC4, 0xE2, 0x47, 0xFF, 0xB6, 0xFF,
+	 0xB7, 0xFF, 0xB4, 0xFF, 0x32, 0xF1, 0x08, 0x29, 0x09, 0x00, 0x64, 0x40, 0x07, 0x22, 0x06, 0x00,
+	 0x43, 0xFF, 0x27, 0x44, 0x10, 0xBC, 0x40, 0x47, 0x00, 0x64, 0x32, 0xFB, 0x31, 0x41, 0x3C, 0x44,
+	 0x01, 0xB1, 0x00, 0xBC, 0x0A, 0x02, 0x09, 0x03, 0x32, 0xF3, 0x00, 0x7C, 0x01, 0xB4, 0xFF, 0xFF,
+	 0x04, 0x03, 0x32, 0xF9, 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0xC8, 0x60, 0x09, 0x7D, 0x00, 0x60,
+	 0x00, 0x6B, 0x00, 0x64, 0x33, 0xFB, 0x0C, 0x60, 0x16, 0x64, 0xA0, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x00, 0xE1, 0x30, 0x40, 0x02, 0x36, 0xA1, 0xFF, 0x83, 0xFF, 0x8D, 0xFF, 0x5C, 0x44, 0x5C, 0x43,
+	 0x5C, 0x42, 0x5C, 0x41, 0x5C, 0x40, 0xAC, 0xFF, 0xAD, 0xFF, 0xE7, 0xE1, 0xB3, 0x60, 0xBE, 0x78,
+	 0xFF, 0xFF, 0x30, 0x44, 0x02, 0xA8, 0x00, 0xE1, 0x03, 0x02, 0x28, 0xE2, 0x40, 0xFF, 0xA1, 0xFF,
+	 0x84, 0xFF, 0xC1, 0x60, 0x6B, 0x64, 0x40, 0x42, 0xB7, 0x60, 0xA2, 0x64, 0x40, 0x40, 0x9C, 0xF3,
+	 0x65, 0xFB, 0x0F, 0x60, 0xF6, 0x63, 0xA9, 0xF3, 0xBD, 0xDB, 0x00, 0x60, 0x9A, 0x64, 0xBD, 0xDB,
+	 0x02, 0x64, 0xBD, 0xDB, 0x04, 0x64, 0xA3, 0xDB, 0x5C, 0x49, 0x0A, 0x64, 0x40, 0x4B, 0x5C, 0x5C,
+	 0x01, 0x60, 0x39, 0xE2, 0x04, 0x60, 0x00, 0x7A, 0x89, 0xFF, 0x03, 0x60, 0xFF, 0x73, 0x88, 0xFF,
+	 0xB7, 0x60, 0xA2, 0x78, 0xFF, 0xFF, 0x30, 0x44, 0x02, 0xA8, 0x00, 0xE1, 0x06, 0x02, 0x40, 0xFF,
+	 0x42, 0xFF, 0x43, 0xFF, 0x44, 0xFF, 0x45, 0xFF, 0xA1, 0xFF, 0x88, 0xFF, 0x85, 0xFF, 0x21, 0xE1,
+	 0x5C, 0x40, 0xC3, 0x60, 0x53, 0x78, 0xFF, 0xFF, 0xA2, 0xFF, 0x30, 0x44, 0x02, 0xA8, 0x00, 0xE1,
+	 0x01, 0x02, 0xA1, 0xFF, 0x86, 0xFF, 0x88, 0xFF, 0x5C, 0x46, 0x5C, 0x49, 0x5C, 0x40, 0xE1, 0x60,
+	 0x58, 0x4F, 0x7A, 0x78, 0xFF, 0xFF, 0xD0, 0x60, 0x58, 0x4F, 0xA2, 0x78, 0xFF, 0xFF, 0xEB, 0x60,
+	 0x58, 0x4F, 0x10, 0x78, 0xFF, 0xFF, 0xDD, 0x60, 0x58, 0x4F, 0xF5, 0x78, 0xFF, 0xFF, 0x1F, 0xE1,
+	 0xA3, 0xFF, 0xCA, 0x60, 0x7E, 0x78, 0xFF, 0xFF, 0x03, 0xE1, 0xA3, 0xFF, 0x1E, 0x60, 0x9E, 0x63,
+	 0x17, 0xFD, 0xAE, 0xFF, 0xF0, 0x60, 0xC7, 0x78, 0xFF, 0xFF, 0x86, 0xF3, 0x87, 0xF3, 0xDC, 0x81,
+	 0x00, 0x7C, 0x01, 0x00, 0x00, 0xFA, 0x60, 0x46, 0xFE, 0x63, 0xA3, 0xD8, 0xFE, 0x1F, 0xCD, 0x81,
+	 0xD8, 0x84, 0xF8, 0x02, 0x86, 0xF3, 0x87, 0xF5, 0xDC, 0x81, 0x80, 0x67, 0x40, 0x4A, 0x05, 0x18,
+	 0x2A, 0x43, 0x02, 0xFC, 0x5F, 0x8A, 0x00, 0xF4, 0xFA, 0x01, 0x2E, 0x58, 0xFF, 0xFF, 0x88, 0xF3,
+	 0x06, 0x61, 0x00, 0x7C, 0x60, 0x46, 0xFE, 0x63, 0xA3, 0xD8, 0xFE, 0x1F, 0xCD, 0x81, 0x66, 0x44,
+	 0xD8, 0x84, 0xF8, 0x02, 0x09, 0x60, 0x2B, 0x7C, 0x88, 0xF3, 0x06, 0x61, 0x60, 0x46, 0x01, 0x63,
+	 0x76, 0xF8, 0x00, 0xFC, 0x63, 0x47, 0x06, 0xFA, 0x76, 0xF8, 0x03, 0x64, 0x77, 0xFA, 0xDF, 0x83,
+	 0x66, 0x44, 0xCD, 0x81, 0x02, 0xA6, 0xF4, 0x02, 0x2E, 0x58, 0xFF, 0xFF, 0x8A, 0xF1, 0x89, 0xF3,
+	 0x7C, 0x63, 0x8C, 0xFB, 0x60, 0x46, 0x01, 0xFC, 0xDC, 0x84, 0xD0, 0x80, 0x00, 0xFA, 0xFA, 0x04,
+	 0x8D, 0xFB, 0x60, 0x46, 0x00, 0x64, 0x00, 0xFA, 0x63, 0x44, 0x80, 0x7F, 0x01, 0xFA, 0x8A, 0xF3,
+	 0x89, 0xF1, 0xDC, 0x84, 0xD0, 0x84, 0x8B, 0xFB, 0x03, 0x60, 0x26, 0x61, 0xB5, 0x60, 0x58, 0x4D,
+	 0x8C, 0x78, 0xFF, 0xFF, 0x66, 0x44, 0x2E, 0xFB, 0x82, 0xFF, 0x40, 0x42, 0x87, 0xFF, 0x8B, 0xF3,
+	 0x93, 0xFB, 0x00, 0x64, 0x40, 0x50, 0x63, 0xFF, 0x60, 0xFF, 0x66, 0xFF, 0x65, 0xFF, 0x64, 0xFF,
+	 0x61, 0xFF, 0x62, 0xFF, 0x49, 0x60, 0x02, 0xE1, 0x52, 0x60, 0x02, 0xE1, 0x5C, 0x60, 0x02, 0xE1,
+	 0x65, 0x60, 0x02, 0xE1, 0x6B, 0x60, 0x02, 0xE1, 0x76, 0x60, 0x02, 0xE1, 0x41, 0x60, 0x02, 0xE1,
+	 0x04, 0x64, 0x0F, 0x60, 0x9F, 0xFB, 0x1F, 0x60, 0x64, 0x64, 0x7F, 0xFB, 0x2D, 0xFF, 0x0A, 0x61,
+	 0x41, 0x4B, 0x09, 0x60, 0x08, 0x61, 0xB5, 0x60, 0x58, 0x4D, 0x8C, 0x78, 0xFF, 0xFF, 0xF0, 0x67,
+	 0x0E, 0xFA, 0x1F, 0x60, 0x0A, 0x64, 0x0F, 0x60, 0x93, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x2B, 0x41, 0x4D, 0x8B, 0xFF, 0xFF, 0xEA, 0x02, 0x09, 0x61,
+	 0x41, 0x4B, 0x09, 0x60, 0x08, 0x61, 0xB5, 0x60, 0x58, 0x4D, 0x8C, 0x78, 0xFF, 0xFF, 0x1E, 0x60,
+	 0xFE, 0x64, 0x0F, 0x60, 0x93, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0x2B, 0x41, 0x4D, 0x8B, 0xFF, 0xFF, 0xEC, 0x02, 0x1E, 0x60, 0xB0, 0x78, 0xFF, 0xFF,
+	 0x00, 0xEA, 0x00, 0xEB, 0x50, 0x60, 0x03, 0xEA, 0x51, 0x60, 0x13, 0xEA, 0x52, 0x60, 0x30, 0xEA,
+	 0x53, 0x60, 0x40, 0xEA, 0x54, 0x60, 0x52, 0xEA, 0x55, 0x60, 0x6D, 0xEA, 0x56, 0x60, 0x71, 0xEA,
+	 0x57, 0x60, 0x8B, 0xEA, 0x58, 0x60, 0x47, 0xEA, 0x59, 0x60, 0xA0, 0xEA, 0x5A, 0x60, 0xB2, 0xEA,
+	 0x5B, 0x60, 0xC1, 0xEA, 0x5C, 0x60, 0xD7, 0xEA, 0x5D, 0x60, 0xEB, 0xEA, 0x5E, 0x60, 0xA0, 0xEA,
+	 0x50, 0x60, 0x36, 0xEB, 0x51, 0x60, 0x37, 0xEB, 0x52, 0x60, 0x20, 0xEB, 0x53, 0x60, 0xE4, 0xEB,
+	 0x54, 0x60, 0x34, 0xEB, 0x55, 0x60, 0x58, 0xEB, 0x56, 0x60, 0x48, 0xEB, 0x57, 0x60, 0xD0, 0xEB,
+	 0x58, 0x60, 0xC3, 0xEB, 0x59, 0x60, 0xFC, 0xEB, 0x5A, 0x60, 0x34, 0xEB, 0x5B, 0x60, 0x58, 0xEB,
+	 0x5C, 0x60, 0xC0, 0xEB, 0x5D, 0x60, 0xD0, 0xEB, 0x5E, 0x60, 0x91, 0xEB, 0x00, 0xEA, 0x00, 0xEB,
+	 0xE0, 0x60, 0x02, 0xEA, 0xE0, 0x60, 0x03, 0xEB, 0xA0, 0x60, 0x00, 0xEB, 0xB0, 0x60, 0x00, 0xEB,
+	 0xAB, 0x48, 0x40, 0x3B, 0x01, 0x00, 0xFC, 0x01, 0x00, 0xEB, 0x03, 0x60, 0x02, 0x64, 0xA0, 0xDB,
+	 0x0F, 0x64, 0x60, 0x7F, 0xA0, 0x5A, 0x80, 0x60, 0x00, 0xEA, 0xA0, 0x60, 0x00, 0xEA, 0xD1, 0x60,
+	 0x00, 0xEA, 0x24, 0x44, 0xFF, 0xB4, 0x04, 0xFB, 0x50, 0x60, 0x00, 0x64, 0x05, 0xFB, 0x10, 0x60,
+	 0x10, 0x75, 0xF0, 0x60, 0xC7, 0x78, 0xFF, 0xFF, 0x3F, 0x40, 0x40, 0x26, 0x40, 0x00, 0x05, 0x60,
+	 0xF9, 0xF1, 0x42, 0x60, 0x08, 0x64, 0x09, 0x60, 0x19, 0x63, 0x64, 0x40, 0x01, 0x2B, 0x04, 0x00,
+	 0x42, 0x60, 0x09, 0x64, 0x0A, 0x60, 0x19, 0x63, 0x18, 0x60, 0x22, 0xFB, 0x04, 0x60, 0x00, 0xBC,
+	 0x18, 0x60, 0x1E, 0xFB, 0x18, 0x60, 0x1D, 0xFD, 0x1D, 0x60, 0x19, 0x63, 0x18, 0x60, 0x21, 0xFD,
+	 0x80, 0x60, 0x1C, 0x64, 0x3F, 0x40, 0x01, 0x2A, 0x02, 0x00, 0x60, 0x60, 0x1C, 0x64, 0x18, 0x60,
+	 0x23, 0xFB, 0x18, 0x60, 0x1F, 0xFB, 0x18, 0x60, 0x22, 0xF3, 0xA0, 0x50, 0xA0, 0x50, 0x0B, 0x60,
+	 0xF8, 0x63, 0xA3, 0xD1, 0x30, 0x60, 0x38, 0x61, 0xA1, 0xD3, 0xF8, 0xA3, 0x90, 0x84, 0xA2, 0xDB,
+	 0xA3, 0xD1, 0x59, 0xD3, 0x06, 0xA3, 0x90, 0x84, 0xA2, 0xDB, 0xA3, 0xD1, 0x59, 0xD3, 0xFE, 0xA3,
+	 0x90, 0x84, 0xA2, 0xDB, 0xA3, 0xD1, 0x59, 0xD3, 0xFF, 0xFF, 0x90, 0x84, 0xA2, 0xDB, 0x80, 0x60,
+	 0x58, 0xEC, 0x80, 0x60, 0x00, 0xED, 0x80, 0x60, 0x80, 0xEE, 0x40, 0xEC, 0x00, 0xED, 0x00, 0xEE,
+	 0xC0, 0x60, 0x59, 0xEC, 0xC0, 0x60, 0x07, 0xED, 0xC0, 0x60, 0x8F, 0xEE, 0xAD, 0x4F, 0xFA, 0xB4,
+	 0xA0, 0x5D, 0x00, 0xF3, 0x28, 0xFB, 0x40, 0x44, 0xA2, 0x60, 0xE8, 0x7C, 0x20, 0xF9, 0x1D, 0x60,
+	 0xD0, 0x7C, 0x21, 0xF9, 0x1D, 0x60, 0xE6, 0x7C, 0x22, 0xF9, 0x1E, 0x60, 0x44, 0x7C, 0x23, 0xF9,
+	 0x1E, 0x60, 0x55, 0x7C, 0x24, 0xF9, 0x1E, 0x60, 0x7F, 0x7C, 0x25, 0xF9, 0x1E, 0x60, 0x90, 0x7C,
+	 0x26, 0xF9, 0xD0, 0x60, 0x00, 0xE8, 0x28, 0xE8, 0x44, 0x60, 0x01, 0xE6, 0x00, 0x64, 0x40, 0x52,
+	 0x10, 0x60, 0x04, 0xE6, 0x08, 0x60, 0x06, 0x63, 0xFD, 0x60, 0x0C, 0x65, 0x5B, 0xD3, 0xBF, 0xD1,
+	 0x0C, 0x18, 0xC3, 0x83, 0xD4, 0x80, 0xC3, 0x83, 0xF9, 0x02, 0xFA, 0xA3, 0xA3, 0xD3, 0x02, 0x60,
+	 0x00, 0x65, 0xF9, 0xA0, 0xFC, 0xA0, 0x09, 0x05, 0x00, 0x05, 0x21, 0x60, 0x00, 0x65, 0x3F, 0x43,
+	 0x21, 0x60, 0x00, 0x65, 0xC0, 0x60, 0x8F, 0xEE, 0x08, 0x00, 0x02, 0x60, 0x00, 0x65, 0x00, 0x60,
+	 0x00, 0x64, 0x18, 0xFB, 0x3F, 0x43, 0x11, 0x60, 0x10, 0xE6, 0xB7, 0x84, 0x40, 0x5F, 0x30, 0x60,
+	 0x20, 0x63, 0x3F, 0x40, 0x20, 0x27, 0x06, 0x00, 0x0F, 0x60, 0xFF, 0x64, 0xBD, 0xDB, 0x0F, 0x60,
+	 0xF0, 0x64, 0x03, 0x00, 0x0F, 0x64, 0xBD, 0xDB, 0x00, 0x64, 0xA3, 0xDB, 0x00, 0x60, 0x30, 0xE2,
+	 0x00, 0x60, 0x50, 0xE2, 0x00, 0x60, 0x79, 0xE2, 0x00, 0x60, 0x90, 0xE2, 0x01, 0x60, 0xD0, 0xE2,
+	 0x01, 0x60, 0xF0, 0xE2, 0x01, 0x60, 0xB0, 0xE2, 0x13, 0x64, 0xAD, 0xFB, 0x01, 0x60, 0x67, 0x64,
+	 0x37, 0xFB, 0x00, 0x60, 0x50, 0x64, 0x36, 0xFB, 0x09, 0x60, 0x2A, 0x64, 0x98, 0xFB, 0x82, 0xFF,
+	 0x92, 0xFF, 0x5C, 0x41, 0x5C, 0x46, 0x5C, 0x47, 0x00, 0xE1, 0xA4, 0x60, 0x7C, 0x63, 0x0C, 0x60,
+	 0x16, 0x64, 0xA0, 0xDD, 0x87, 0xFF, 0x97, 0xFF, 0x0C, 0x60, 0x02, 0x64, 0x40, 0x5A, 0x06, 0xA4,
+	 0x40, 0x5B, 0x5C, 0x5E, 0x13, 0x60, 0x52, 0xF3, 0x64, 0xFB, 0x3F, 0x40, 0x01, 0x22, 0x03, 0x00,
+	 0x80, 0x60, 0x37, 0x7C, 0x02, 0x00, 0x80, 0x60, 0x27, 0x7C, 0x16, 0x60, 0x55, 0xF9, 0x00, 0x60,
+	 0x80, 0x64, 0x89, 0xFB, 0x02, 0x60, 0x80, 0x66, 0x22, 0x60, 0x22, 0x64, 0x77, 0x60, 0x77, 0x63,
+	 0x00, 0xFA, 0x01, 0xFC, 0x00, 0xF0, 0x01, 0xF0, 0xD0, 0x80, 0xD3, 0x80, 0x1E, 0x02, 0x1D, 0x02,
+	 0x06, 0x60, 0x80, 0x65, 0x45, 0x4A, 0xAA, 0x46, 0x00, 0xFC, 0x01, 0xFA, 0xAA, 0x46, 0x00, 0xF0,
+	 0x2A, 0x41, 0x50, 0x65, 0xD3, 0x80, 0xCD, 0x84, 0x13, 0x03, 0x0A, 0x60, 0x80, 0x65, 0x45, 0x4A,
+	 0xAA, 0x46, 0x00, 0xFC, 0x01, 0xFA, 0xAA, 0x46, 0x00, 0xF0, 0x65, 0x41, 0xC8, 0x65, 0xD3, 0x80,
+	 0xCD, 0x84, 0x06, 0x03, 0x12, 0x60, 0x7F, 0x64, 0x03, 0x00, 0x10, 0x65, 0x02, 0x60, 0x7F, 0x64,
+	 0x65, 0x43, 0x86, 0xFD, 0x0F, 0x60, 0x5B, 0xFD, 0x07, 0x61, 0xC5, 0x81, 0xE1, 0x85, 0xD4, 0x84,
+	 0x8A, 0xFB, 0xDC, 0x84, 0x88, 0xFB, 0x0C, 0xA4, 0x87, 0xFB, 0x0F, 0x60, 0x5C, 0xFB, 0x1E, 0x60,
+	 0x58, 0x4E, 0xD3, 0x78, 0xFF, 0xFF, 0x1E, 0x60, 0x58, 0x4E, 0xB9, 0x78, 0xFF, 0xFF, 0x3F, 0x40,
+	 0x40, 0x26, 0x05, 0x00, 0x18, 0x60, 0x20, 0xF3, 0x5A, 0xD1, 0xA0, 0x50, 0xA4, 0x52, 0x00, 0x64,
+	 0x0A, 0x60, 0x7E, 0xFB, 0x1E, 0x60, 0xF2, 0x78, 0xFF, 0xFF, 0x5C, 0x51, 0x3F, 0x41, 0xA5, 0x4C,
+	 0x50, 0x37, 0x0B, 0x00, 0x01, 0xB9, 0x41, 0x5F, 0xB5, 0x60, 0x55, 0xE0, 0x05, 0x60, 0xF9, 0xF1,
+	 0xC0, 0x67, 0x90, 0x84, 0x3F, 0x40, 0x01, 0x26, 0xA0, 0x50, 0x06, 0x60, 0x08, 0xF3, 0x01, 0x60,
+	 0x01, 0x65, 0x01, 0x60, 0x02, 0x7C, 0xD4, 0x80, 0xD0, 0x80, 0x01, 0x03, 0x10, 0x02, 0x5A, 0xD1,
+	 0x5A, 0xD3, 0x3E, 0x60, 0x00, 0x66, 0xE0, 0x87, 0x40, 0x4A, 0xF7, 0x60, 0x8C, 0x61, 0x64, 0x44,
+	 0xC8, 0x84, 0x0C, 0x63, 0xAA, 0x46, 0x58, 0xD0, 0xAA, 0x46, 0x59, 0xD8, 0xFB, 0x1F, 0x08, 0x60,
+	 0x00, 0x63, 0xFA, 0x60, 0x00, 0x65, 0xBD, 0xD3, 0xA3, 0xD3, 0x02, 0xA8, 0xD4, 0x80, 0x07, 0x02,
+	 0x06, 0x02, 0x49, 0x60, 0x4C, 0x61, 0x3C, 0x60, 0x00, 0x66, 0x41, 0x4B, 0x03, 0x00, 0x24, 0x60,
+	 0x84, 0x78, 0xFF, 0xFF, 0x2B, 0x41, 0x49, 0x60, 0x94, 0x7C, 0xD1, 0x80, 0xA1, 0xD2, 0x25, 0x05,
+	 0x59, 0xD0, 0x60, 0x45, 0x59, 0xD2, 0x44, 0x47, 0xE0, 0x87, 0x40, 0x4A, 0x59, 0xD2, 0x59, 0x8B,
+	 0x40, 0x4C, 0x08, 0x60, 0x00, 0x63, 0xBE, 0xD3, 0xBD, 0xD1, 0xEC, 0x18, 0xD4, 0x80, 0xEA, 0x18,
+	 0x03, 0x03, 0xC3, 0x83, 0xC3, 0x83, 0xF7, 0x01, 0x67, 0x44, 0xC0, 0x84, 0xE0, 0x85, 0x2C, 0x44,
+	 0xD4, 0x80, 0x63, 0x41, 0x01, 0x06, 0x65, 0x44, 0xC8, 0x83, 0xAA, 0x46, 0x59, 0xD1, 0x27, 0xD8,
+	 0x5A, 0x87, 0xFC, 0x1F, 0xAA, 0x46, 0x2B, 0x41, 0xD5, 0x01, 0x49, 0x60, 0x94, 0x61, 0x41, 0x4B,
+	 0x2B, 0x41, 0x49, 0x60, 0x94, 0x7C, 0xD1, 0x80, 0xA1, 0xD2, 0x27, 0x05, 0x59, 0xD0, 0x60, 0x45,
+	 0x59, 0xD2, 0x44, 0x47, 0xE0, 0x87, 0x40, 0x4A, 0x59, 0xD2, 0x59, 0x8B, 0x40, 0x4C, 0x08, 0x60,
+	 0x00, 0x63, 0xBE, 0xD3, 0xBD, 0xD1, 0xEC, 0x18, 0xD4, 0x80, 0xEA, 0x18, 0x03, 0x03, 0xC3, 0x83,
+	 0xC3, 0x83, 0xF7, 0x01, 0x04, 0xA3, 0xA3, 0xD1, 0x5A, 0x88, 0x2C, 0x43, 0xD3, 0x80, 0xFF, 0xFF,
+	 0x01, 0x06, 0x64, 0x43, 0xCF, 0x83, 0xAA, 0x46, 0x60, 0xFE, 0x28, 0xD1, 0x5E, 0x88, 0x27, 0xD8,
+	 0x5A, 0x87, 0xFB, 0x1F, 0x20, 0xFE, 0xAA, 0x46, 0xD3, 0x01, 0xFA, 0x60, 0x39, 0x65, 0x24, 0x60,
+	 0x58, 0x4D, 0x97, 0x78, 0xFF, 0xFF, 0x03, 0x03, 0xBE, 0xD1, 0x07, 0x60, 0xED, 0xF9, 0x07, 0x60,
+	 0xED, 0xF3, 0x20, 0x60, 0x00, 0x7C, 0x60, 0x40, 0x10, 0x2A, 0x05, 0x00, 0x07, 0x60, 0xEC, 0xF9,
+	 0x07, 0x60, 0xEB, 0xF9, 0x12, 0x00, 0x04, 0xB0, 0x10, 0x60, 0x55, 0xF3, 0x0E, 0x03, 0x02, 0xBC,
+	 0xA2, 0xDB, 0x07, 0x60, 0xF5, 0xFB, 0x10, 0x60, 0xE8, 0xF3, 0x10, 0x60, 0xAC, 0xF3, 0x02, 0xBD,
+	 0x02, 0xBC, 0xA2, 0xDB, 0x65, 0x44, 0x10, 0x60, 0xE8, 0xFB, 0x07, 0x60, 0xED, 0xF3, 0x31, 0x41,
+	 0x60, 0x40, 0x20, 0x2A, 0x40, 0xB9, 0x40, 0x26, 0x03, 0x00, 0x60, 0x40, 0x01, 0x26, 0x80, 0xB9,
+	 0x41, 0x51, 0xFA, 0x60, 0x3A, 0x65, 0x24, 0x60, 0x58, 0x4D, 0x97, 0x78, 0xFF, 0xFF, 0x03, 0x02,
+	 0x23, 0x60, 0x1D, 0x78, 0xFF, 0xFF, 0x5B, 0xD3, 0xF8, 0x60, 0x3F, 0x65, 0x00, 0x7F, 0xE0, 0x84,
+	 0xE0, 0x84, 0x10, 0x60, 0xF7, 0xF3, 0xE0, 0x9C, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x5A, 0xD3,
+	 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0xBD, 0xD3, 0xFF, 0xFF, 0x60, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0xE0, 0x84, 0x10, 0x60, 0xFA, 0xF3, 0xE0, 0x9C, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB,
+	 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x21, 0x60, 0xFA, 0x61, 0xA3, 0xD3,
+	 0xFF, 0xFF, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0xE0, 0x84, 0xA1, 0xD3, 0xE0, 0x9C, 0xA4, 0x84,
+	 0xB0, 0x84, 0xA1, 0xDB, 0xA3, 0xD3, 0xFF, 0xFF, 0x00, 0x7F, 0xE0, 0x84, 0xE0, 0x84, 0x59, 0xD3,
+	 0xE0, 0x9C, 0xA4, 0x84, 0xB0, 0x84, 0xA1, 0xDB, 0x11, 0x60, 0x00, 0xF3, 0xFF, 0xFF, 0xA4, 0x84,
+	 0xB0, 0x84, 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x11, 0x60,
+	 0x03, 0xF3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84,
+	 0xB0, 0x84, 0xA2, 0xDB, 0x11, 0x60, 0x06, 0xF3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB,
+	 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0xA3, 0xD3, 0xFF, 0xFF, 0x60, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0xE0, 0x84, 0x11, 0x60, 0x09, 0xF3, 0xE0, 0x9C, 0xA4, 0x84, 0xB0, 0x84,
+	 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x11, 0x60, 0x0C, 0xF3,
+	 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84,
+	 0xA2, 0xDB, 0x11, 0x60, 0x0F, 0xF3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x5A, 0xD3,
+	 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x02, 0xA3, 0xA3, 0xD3, 0xF8, 0x60, 0x3F, 0x65,
+	 0x00, 0x7F, 0xE0, 0x84, 0xE0, 0x84, 0x11, 0x60, 0x12, 0xF3, 0xE0, 0x9C, 0xA4, 0x84, 0xB0, 0x84,
+	 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0xBD, 0xD3, 0xFF, 0xFF,
+	 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0xE0, 0x84, 0x11, 0x60, 0x15, 0xF3, 0xE0, 0x9C, 0xA4, 0x84,
+	 0xB0, 0x84, 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x22, 0x60,
+	 0x30, 0x61, 0xA3, 0xD3, 0xFF, 0xFF, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0xE0, 0x84, 0xA1, 0xD3,
+	 0xE0, 0x9C, 0xA4, 0x84, 0xB0, 0x84, 0xA1, 0xDB, 0xA3, 0xD3, 0xFF, 0xFF, 0x00, 0x7F, 0xE0, 0x84,
+	 0xE0, 0x84, 0x59, 0xD3, 0xE0, 0x9C, 0xA4, 0x84, 0xB0, 0x84, 0xA1, 0xDB, 0x11, 0x60, 0x1B, 0xF3,
+	 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84,
+	 0xA2, 0xDB, 0x11, 0x60, 0x1E, 0xF3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x5A, 0xD3,
+	 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x11, 0x60, 0x21, 0xF3, 0xFF, 0xFF, 0xA4, 0x84,
+	 0xB0, 0x84, 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0xA3, 0xD3,
+	 0xFF, 0xFF, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0xE0, 0x84, 0x11, 0x60, 0x24, 0xF3, 0xE0, 0x9C,
+	 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB,
+	 0x11, 0x60, 0x27, 0xF3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF,
+	 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x11, 0x60, 0x2A, 0xF3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84,
+	 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x00, 0x60, 0x6A, 0x63,
+	 0x22, 0x60, 0x56, 0x61, 0x21, 0x60, 0xEA, 0x64, 0x58, 0xD1, 0x59, 0xD9, 0xFD, 0x1F, 0x11, 0x60,
+	 0x33, 0xF3, 0xFF, 0xFF, 0x18, 0xAC, 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0x18, 0xAC, 0xA2, 0xDB,
+	 0x11, 0x60, 0x37, 0xF3, 0xFF, 0xFF, 0x18, 0xAC, 0xA2, 0xDB, 0x11, 0x60, 0x39, 0xF3, 0xFF, 0xFF,
+	 0x18, 0xAC, 0xA2, 0xDB, 0x11, 0x60, 0x40, 0xF3, 0xFF, 0xFF, 0x18, 0xAC, 0xA2, 0xDB, 0x11, 0x60,
+	 0x42, 0xF3, 0xFF, 0xFF, 0x18, 0xAC, 0xA2, 0xDB, 0x11, 0x60, 0x4E, 0xF3, 0xFF, 0xFF, 0x18, 0xAC,
+	 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0x18, 0xAC, 0xA2, 0xDB, 0x11, 0x60, 0x52, 0xF3, 0xFF, 0xFF,
+	 0x18, 0xAC, 0xA2, 0xDB, 0x11, 0x60, 0x54, 0xF3, 0xFF, 0xFF, 0x18, 0xAC, 0xA2, 0xDB, 0x11, 0x60,
+	 0x5B, 0xF3, 0xFF, 0xFF, 0x18, 0xAC, 0xA2, 0xDB, 0x11, 0x60, 0x5D, 0xF3, 0xFF, 0xFF, 0x18, 0xAC,
+	 0xA2, 0xDB, 0xFA, 0x60, 0x2C, 0x65, 0x24, 0x60, 0x58, 0x4D, 0x97, 0x78, 0xFF, 0xFF, 0x0E, 0x03,
+	 0x63, 0x45, 0x23, 0x60, 0xF0, 0x63, 0x06, 0x61, 0xA5, 0xD1, 0xDA, 0x85, 0x64, 0x44, 0x0F, 0xB4,
+	 0xBD, 0xDB, 0x64, 0x47, 0x0F, 0xB4, 0xCD, 0x81, 0xBD, 0xDB, 0xF6, 0x02, 0xFA, 0x60, 0x30, 0x65,
+	 0x24, 0x60, 0x58, 0x4D, 0x97, 0x78, 0xFF, 0xFF, 0x14, 0x03, 0xBD, 0xD3, 0x63, 0x46, 0x24, 0x60,
+	 0x88, 0x63, 0x12, 0x60, 0x53, 0xFB, 0xDA, 0x85, 0xBD, 0xDB, 0x0E, 0x61, 0xA6, 0xD1, 0xDA, 0x86,
+	 0x64, 0x44, 0xFF, 0xB4, 0xA5, 0xDB, 0xDA, 0x85, 0x64, 0x47, 0xFF, 0xB4, 0xCD, 0x81, 0xBD, 0xDB,
+	 0xF5, 0x02, 0xFA, 0x60, 0x31, 0x65, 0x24, 0x60, 0x58, 0x4D, 0x97, 0x78, 0xFF, 0xFF, 0x22, 0x03,
+	 0xBD, 0xD3, 0x12, 0x60, 0x71, 0xFB, 0x5A, 0x81, 0x12, 0x60, 0x80, 0xFB, 0x5A, 0x82, 0x12, 0x60,
+	 0x8F, 0xFB, 0x5A, 0x83, 0x12, 0x60, 0x9E, 0xFB, 0x5A, 0x84, 0x0E, 0x61, 0xBD, 0xD1, 0xBD, 0xD5,
+	 0x64, 0x44, 0xFF, 0xB4, 0x21, 0xDB, 0x5A, 0x81, 0x64, 0x47, 0xFF, 0xB4, 0x22, 0xDB, 0x5A, 0x82,
+	 0x66, 0x44, 0xFF, 0xB4, 0x23, 0xDB, 0x5A, 0x83, 0x66, 0x47, 0xFF, 0xB4, 0x24, 0xDB, 0xCD, 0x81,
+	 0x5A, 0x84, 0xEC, 0x02, 0xFA, 0x60, 0x47, 0x65, 0x24, 0x60, 0x58, 0x4D, 0x97, 0x78, 0xFF, 0xFF,
+	 0x11, 0x03, 0x63, 0x45, 0x25, 0x60, 0x5A, 0x63, 0xA5, 0xD1, 0xDA, 0x85, 0xBD, 0xD9, 0x02, 0x61,
+	 0xA5, 0xD1, 0xDA, 0x85, 0x64, 0x47, 0x00, 0x7E, 0xBD, 0xDB, 0x64, 0x44, 0x00, 0x7E, 0xCD, 0x81,
+	 0xBD, 0xDB, 0xF6, 0x02, 0xFA, 0x60, 0x2E, 0x65, 0x24, 0x60, 0x58, 0x4D, 0x97, 0x78, 0xFF, 0xFF,
+	 0x1F, 0x03, 0x63, 0x46, 0xFC, 0xA3, 0xA3, 0xD3, 0x24, 0x60, 0x08, 0x63, 0xCC, 0x84, 0xE8, 0x84,
+	 0xCC, 0x81, 0x00, 0x36, 0x0D, 0x00, 0x63, 0x45, 0xA6, 0xD3, 0x5A, 0xD1, 0xDA, 0x86, 0xFF, 0xB4,
+	 0xE0, 0x84, 0xC4, 0x84, 0x5C, 0x90, 0xBD, 0xD9, 0xFD, 0x02, 0xCD, 0x81, 0x66, 0x42, 0xF4, 0x02,
+	 0x66, 0x42, 0x5A, 0xD3, 0x24, 0x60, 0x48, 0x65, 0xBD, 0xDB, 0xD7, 0x80, 0xFF, 0xFF, 0xFC, 0x02,
+	 0x25, 0x60, 0x6E, 0x61, 0xFA, 0x60, 0x46, 0x65, 0x24, 0x60, 0x58, 0x4D, 0x97, 0x78, 0xFF, 0xFF,
+	 0x01, 0x03, 0xA1, 0xDD, 0xD9, 0x81, 0xFA, 0x60, 0x2F, 0x65, 0x24, 0x60, 0x58, 0x4D, 0x97, 0x78,
+	 0xFF, 0xFF, 0x01, 0x03, 0xA1, 0xDD, 0xD9, 0x81, 0xFA, 0x60, 0x3E, 0x65, 0x24, 0x60, 0x58, 0x4D,
+	 0x97, 0x78, 0xFF, 0xFF, 0x01, 0x03, 0xA1, 0xDD, 0xD9, 0x81, 0xFA, 0x60, 0x3F, 0x65, 0x24, 0x60,
+	 0x58, 0x4D, 0x97, 0x78, 0xFF, 0xFF, 0x01, 0x03, 0xA1, 0xDD, 0xD9, 0x81, 0xFA, 0x60, 0x40, 0x65,
+	 0x24, 0x60, 0x58, 0x4D, 0x97, 0x78, 0xFF, 0xFF, 0x01, 0x03, 0xA1, 0xDD, 0xD9, 0x81, 0xFA, 0x60,
+	 0x3B, 0x65, 0x24, 0x60, 0x58, 0x4D, 0x97, 0x78, 0xFF, 0xFF, 0x01, 0x03, 0xA1, 0xDD, 0xFA, 0x60,
+	 0x48, 0x65, 0x24, 0x60, 0x58, 0x4D, 0x97, 0x78, 0xFF, 0xFF, 0x10, 0x03, 0xBD, 0xD3, 0x25, 0x60,
+	 0xCA, 0x61, 0x0E, 0xB4, 0xBD, 0xD1, 0xA1, 0xDB, 0x64, 0x47, 0x0E, 0xB4, 0xA3, 0xD1, 0x59, 0xDB,
+	 0x64, 0x44, 0x0E, 0xB4, 0x59, 0xDB, 0x64, 0x47, 0x0E, 0xB4, 0x59, 0xDB, 0xFA, 0x60, 0x29, 0x65,
+	 0x24, 0x60, 0x58, 0x4D, 0x97, 0x78, 0xFF, 0xFF, 0x07, 0x03, 0x04, 0xA3, 0xA3, 0xD3, 0x20, 0x60,
+	 0x00, 0x65, 0xB4, 0x84, 0x10, 0x60, 0x29, 0xFB, 0xFA, 0x60, 0x2A, 0x65, 0x24, 0x60, 0x58, 0x4D,
+	 0x97, 0x78, 0xFF, 0xFF, 0x39, 0x03, 0x04, 0xA3, 0xBD, 0xD1, 0x10, 0x60, 0xCD, 0xF3, 0x64, 0x41,
+	 0x64, 0x5E, 0xA2, 0xDB, 0x64, 0x47, 0x5A, 0xD3, 0x60, 0x5C, 0x64, 0x5F, 0xA2, 0xDB, 0x10, 0x60,
+	 0xE3, 0xF3, 0xFF, 0x60, 0xC0, 0xB5, 0x61, 0x40, 0x80, 0x27, 0x05, 0x00, 0xE9, 0x87, 0x3F, 0xB4,
+	 0xB4, 0x84, 0xA2, 0xDB, 0x1E, 0x00, 0x65, 0x44, 0xA2, 0xDB, 0x10, 0x60, 0xDC, 0xF1, 0xE1, 0x80,
+	 0xF9, 0x81, 0xE1, 0x80, 0xF9, 0x84, 0xFF, 0x60, 0x80, 0xB4, 0xC0, 0x9C, 0xA2, 0xD9, 0x10, 0x60,
+	 0xDF, 0xF1, 0xFF, 0xFF, 0xC0, 0x9C, 0xA2, 0xD9, 0x10, 0x60, 0xE6, 0xF1, 0x01, 0x7E, 0x60, 0x47,
+	 0x60, 0x41, 0x64, 0x44, 0xFE, 0x60, 0x00, 0xB5, 0xC1, 0x84, 0x01, 0x60, 0xFF, 0xB4, 0xB4, 0x84,
+	 0xA2, 0xDB, 0xDB, 0x83, 0x11, 0x60, 0x62, 0xFD, 0xFA, 0x60, 0x2B, 0x65, 0x24, 0x60, 0x58, 0x4D,
+	 0x97, 0x78, 0xFF, 0xFF, 0x07, 0x03, 0x04, 0xA3, 0xBD, 0xD3, 0x10, 0x60, 0xD0, 0xFB, 0xA3, 0xD3,
+	 0x10, 0x60, 0x94, 0xFB, 0xFA, 0x60, 0x3C, 0x65, 0x24, 0x60, 0x58, 0x4D, 0x97, 0x78, 0xFF, 0xFF,
+	 0x1F, 0x03, 0xA3, 0xD3, 0xFC, 0x60, 0xFC, 0x65, 0xA4, 0x84, 0x60, 0x5C, 0x00, 0x7E, 0xC0, 0x60,
+	 0x00, 0xA0, 0x60, 0x43, 0x07, 0x04, 0x10, 0x60, 0xD4, 0xF3, 0xFF, 0xFF, 0x03, 0x60, 0xFF, 0xB4,
+	 0x3C, 0x94, 0xA2, 0xDB, 0x21, 0x60, 0x30, 0x61, 0x64, 0x44, 0x00, 0x7F, 0xC0, 0xA0, 0x60, 0x47,
+	 0x07, 0x04, 0x60, 0x43, 0xA1, 0xD3, 0xFF, 0xFF, 0x03, 0x60, 0xFF, 0xB4, 0x3C, 0x94, 0xA1, 0xDB,
+	 0xB8, 0xFE, 0xB9, 0xFE, 0xBA, 0xFE, 0xBB, 0xFE, 0xBD, 0xFE, 0xBF, 0xFE, 0x15, 0x60, 0xCB, 0xF3,
+	 0x12, 0x63, 0x60, 0x40, 0x01, 0x27, 0x04, 0x00, 0x0B, 0x60, 0xEA, 0x62, 0x5A, 0xDF, 0xFE, 0x1F,
+	 0x1F, 0x60, 0xC8, 0x78, 0xFF, 0xFF, 0x08, 0x60, 0x06, 0x63, 0xBE, 0xD3, 0xBD, 0xD1, 0x07, 0x18,
+	 0xD4, 0x80, 0x05, 0x18, 0x03, 0x03, 0xC3, 0x83, 0xC3, 0x83, 0xF7, 0x01, 0xDB, 0x83, 0x00, 0xBC,
+	 0x2D, 0x58, 0xFF, 0xFF, 0x86, 0xFD, 0xB0, 0x26, 0x00, 0x00, 0x06, 0x00, 0x10, 0xFD, 0x32, 0x01,
+	 0x00, 0x00, 0x02, 0x00, 0x14, 0xFD, 0x94, 0x2B, 0x00, 0x00, 0x0A, 0x00, 0x41, 0xFA, 0x46, 0x23,
+	 0x00, 0x00, 0x22, 0x00, 0x42, 0xFA, 0x68, 0x23, 0x00, 0x00, 0x22, 0x00, 0x43, 0xFA, 0x8A, 0x23,
+	 0x00, 0x00, 0x22, 0x00, 0x44, 0xFA, 0xAC, 0x23, 0x00, 0x00, 0x22, 0x00, 0x45, 0xFA, 0xCE, 0x23,
+	 0x00, 0x00, 0x22, 0x00, 0x25, 0xFD, 0x62, 0x01, 0x00, 0x00, 0x02, 0x00,
+
+};  /* fw_image_3_data */
+
+static const hcf_8 fw_image_4_data[] = {
+	 0x6C, 0x40, 0xA1, 0xFF, 0x98, 0xFF, 0x80, 0x3E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x41, 0xFF, 0x33, 0xF3, 0x32, 0x11, 0x31, 0x18, 0x40, 0x64, 0x3A, 0xDB, 0x1C, 0x00, 0xFF, 0xFF,
+	 0xC4, 0xE2, 0x27, 0x44, 0x20, 0x2A, 0x01, 0x00, 0xFF, 0xFF, 0x42, 0x64, 0x3A, 0xDB, 0x23, 0x00,
+	 0x41, 0xFF, 0xA3, 0x60, 0x34, 0x78, 0xE2, 0xFE, 0x40, 0x49, 0x02, 0x60, 0x01, 0xE1, 0x1D, 0x00,
+	 0x44, 0xFF, 0x1B, 0x09, 0x29, 0x44, 0x10, 0x2A, 0x04, 0x74, 0xCD, 0xE2, 0x10, 0x65, 0x0B, 0x00,
+	 0xA4, 0x60, 0x49, 0x78, 0xA4, 0xE2, 0x29, 0x44, 0x20, 0x2A, 0x0D, 0x00, 0x20, 0xAC, 0xEC, 0x01,
+	 0xA4, 0x60, 0x49, 0x78, 0x46, 0xFF, 0xB4, 0x84, 0x40, 0x49, 0xA1, 0xFF, 0xFF, 0xFF, 0x80, 0x3E,
+	 0xA4, 0x60, 0x49, 0x78, 0xFF, 0xFF, 0x62, 0xFF, 0x08, 0xE1, 0xA1, 0xFF, 0x98, 0xFF, 0x80, 0x3E,
+	 0xAA, 0x60, 0xF4, 0x78, 0x4C, 0x4E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xAA, 0x60, 0xFB, 0x78, 0x44, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xC4, 0xE2, 0x84, 0xFF, 0x22, 0x58, 0x82, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA4, 0x60, 0xB9, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0xE1, 0x01, 0xFF, 0xFF,
+	 0x10, 0x29, 0xFA, 0x01, 0xE4, 0xE2, 0xAA, 0x60, 0xB0, 0x78, 0x94, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xC1, 0x60, 0x35, 0x78, 0x64, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xAA, 0x60, 0x97, 0x78, 0xAC, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x80, 0x29, 0xE2, 0x01, 0xAA, 0x60, 0xF3, 0x78, 0x47, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB4, 0x60, 0xEF, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB5, 0x60, 0x1C, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB3, 0x60, 0x8B, 0x78, 0x42, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB3, 0x60, 0xBE, 0x78, 0x43, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB3, 0x60, 0xBE, 0x78, 0x44, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB6, 0x60, 0x9D, 0x78, 0x45, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB3, 0x60, 0xC1, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x00, 0x60, 0x83, 0x64, 0x80, 0x29, 0x09, 0xFB, 0xB4, 0x60, 0xB7, 0x78, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x98, 0xFF, 0xC2, 0x60, 0x69, 0x78, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xC1, 0x60, 0xE0, 0x78, 0x98, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xC0, 0x60, 0x3D, 0x78, 0x98, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xBF, 0x60, 0xB8, 0x78, 0x98, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB7, 0x60, 0x96, 0x78, 0x98, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA1, 0xFF, 0x98, 0xFF, 0x83, 0x3E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xC3, 0x60, 0x58, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0x41, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0x42, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0xB0, 0xFF, 0xB1, 0xFF, 0x40, 0xFF, 0x43, 0xFF, 0xC3, 0x60, 0x53, 0x78, 0x44, 0xFF, 0xFF, 0x01,
+	 0xC3, 0x60, 0x58, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0x1C, 0x60, 0x28, 0x78, 0x45, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0xC3, 0x60, 0x53, 0x78, 0x84, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0xC3, 0x60, 0x52, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0xCA, 0x60, 0x76, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xE8, 0x60, 0x6C, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x42, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0x85, 0x3E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xCA, 0x60, 0x7E, 0x78, 0x24, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xE6, 0x60, 0x2A, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xCA, 0x60, 0x7E, 0x78, 0x44, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xCA, 0x60, 0x7E, 0x78, 0x84, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xCA, 0x60, 0x7E, 0x78, 0x47, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xF0, 0x60, 0x9F, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xF0, 0x60, 0xCA, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xF0, 0x60, 0xE3, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xF0, 0x60, 0xC7, 0x78, 0x28, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xF0, 0x60, 0xC7, 0x78, 0x44, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xF0, 0x60, 0xC7, 0x78, 0x45, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xF0, 0x60, 0xC7, 0x78, 0x46, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x00, 0x60, 0x87, 0x64, 0x80, 0x29, 0x09, 0xFB, 0x47, 0xFF, 0xF0, 0x60, 0xC7, 0x78, 0xFF, 0xFF,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x43, 0xF7, 0xA7, 0xFF, 0x41, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0xA2, 0x60, 0x00, 0x78, 0x47, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x2E, 0x60, 0x54, 0x63, 0x20, 0x44, 0xBD, 0xDB, 0x21, 0x44, 0xBD, 0xDB, 0x22, 0x44, 0xBD, 0xDB,
+	 0x23, 0x44, 0xBD, 0xDB, 0x24, 0x44, 0xBD, 0xDB, 0x25, 0x44, 0xBD, 0xDB, 0x26, 0x44, 0xBD, 0xDB,
+	 0x27, 0x44, 0xBD, 0xDB, 0x28, 0x44, 0xBD, 0xDB, 0x29, 0x44, 0xBD, 0xDB, 0x2A, 0x44, 0xBD, 0xDB,
+	 0x2B, 0x44, 0xBD, 0xDB, 0x2C, 0x44, 0xBD, 0xDB, 0x2D, 0x44, 0xBD, 0xDB, 0x2E, 0x44, 0xBD, 0xDB,
+	 0x2F, 0x44, 0xBD, 0xDB, 0x17, 0x60, 0x24, 0xFD, 0x2F, 0x60, 0x74, 0x63, 0x17, 0x60, 0x25, 0xFD,
+	 0x30, 0x44, 0x17, 0x60, 0x26, 0xFB, 0x31, 0x44, 0x17, 0x60, 0x27, 0xFB, 0x32, 0x44, 0x17, 0x60,
+	 0x28, 0xFB, 0x33, 0x44, 0x17, 0x60, 0x29, 0xFB, 0x81, 0xFF, 0x91, 0xFF, 0x58, 0x51, 0x44, 0x00,
+	 0x82, 0xFF, 0x92, 0xFF, 0x58, 0x51, 0x40, 0x00, 0x83, 0xFF, 0x93, 0xFF, 0x58, 0x51, 0x3C, 0x00,
+	 0x84, 0xFF, 0x94, 0xFF, 0x58, 0x51, 0x38, 0x00, 0x85, 0xFF, 0x95, 0xFF, 0x58, 0x51, 0x34, 0x00,
+	 0x86, 0xFF, 0x96, 0xFF, 0x58, 0x51, 0x30, 0x00, 0x87, 0xFF, 0x97, 0xFF, 0x58, 0x51, 0x2C, 0x00,
+	 0x80, 0xFF, 0x90, 0xFF, 0x99, 0xFF, 0x17, 0x60, 0x24, 0xF1, 0x30, 0x44, 0x64, 0x43, 0xBD, 0xDB,
+	 0x31, 0x44, 0xBD, 0xDB, 0x32, 0x44, 0xBD, 0xDB, 0x33, 0x44, 0xBD, 0xDB, 0x34, 0x44, 0xBD, 0xDB,
+	 0x35, 0x44, 0xBD, 0xDB, 0x36, 0x44, 0xBD, 0xDB, 0x37, 0x44, 0xBD, 0xDB, 0x38, 0x44, 0xBD, 0xDB,
+	 0x39, 0x44, 0xBD, 0xDB, 0x3A, 0x44, 0xBD, 0xDB, 0x3B, 0x44, 0xBD, 0xDB, 0x3C, 0x44, 0xBD, 0xDB,
+	 0x3D, 0x44, 0xBD, 0xDB, 0x3E, 0x44, 0xBD, 0xDB, 0x3F, 0x44, 0xBD, 0xDB, 0xEE, 0x60, 0x48, 0x64,
+	 0x0A, 0xFB, 0x40, 0x21, 0xFE, 0x01, 0x70, 0x00, 0x42, 0x50, 0x40, 0x53, 0x17, 0x60, 0x25, 0xF3,
+	 0xFF, 0xFF, 0x40, 0x52, 0x33, 0x44, 0x32, 0x42, 0xA2, 0xDB, 0xDA, 0x82, 0xA2, 0xDD, 0xDA, 0x83,
+	 0x65, 0x44, 0xBD, 0xDB, 0x61, 0x44, 0xBD, 0xDB, 0x66, 0x44, 0xBD, 0xDB, 0xBD, 0xD9, 0x30, 0x44,
+	 0xBD, 0xDB, 0x99, 0xFF, 0xA4, 0x4C, 0xBD, 0xDB, 0xA5, 0x4C, 0xBD, 0xDB, 0xA0, 0x4C, 0xBD, 0xDB,
+	 0xA1, 0x4C, 0xBD, 0xDB, 0x98, 0xFF, 0x17, 0x60, 0x25, 0xFD, 0x17, 0x60, 0x26, 0xF3, 0xFF, 0xFF,
+	 0x40, 0x50, 0x17, 0x60, 0x28, 0xF3, 0xFF, 0xFF, 0x40, 0x52, 0x17, 0x60, 0x29, 0xF3, 0xFF, 0xFF,
+	 0x40, 0x53, 0x31, 0x41, 0x17, 0x60, 0x27, 0xF3, 0xFF, 0xFF, 0x40, 0x51, 0x17, 0x60, 0x24, 0xF3,
+	 0xFF, 0xFF, 0x60, 0x43, 0x20, 0x44, 0xBD, 0xDB, 0x21, 0x44, 0xBD, 0xDB, 0x22, 0x44, 0xBD, 0xDB,
+	 0x23, 0x44, 0xBD, 0xDB, 0x24, 0x44, 0xBD, 0xDB, 0x25, 0x44, 0xBD, 0xDB, 0x26, 0x44, 0xBD, 0xDB,
+	 0x27, 0x44, 0xBD, 0xDB, 0x28, 0x44, 0xBD, 0xDB, 0x29, 0x44, 0xBD, 0xDB, 0x2A, 0x44, 0xBD, 0xDB,
+	 0x2B, 0x44, 0xBD, 0xDB, 0x2C, 0x44, 0xBD, 0xDB, 0x2D, 0x44, 0xBD, 0xDB, 0x2E, 0x44, 0xBD, 0xDB,
+	 0x2F, 0x44, 0xBD, 0xDB, 0x17, 0x60, 0x24, 0xFD, 0x61, 0x58, 0xFF, 0xFF, 0x28, 0x60, 0x76, 0x63,
+	 0xA3, 0xD3, 0x33, 0x5C, 0x02, 0xA4, 0xBD, 0xDB, 0xFE, 0xB4, 0xE0, 0x85, 0xC4, 0x85, 0x47, 0xD9,
+	 0x34, 0x44, 0x5B, 0xDB, 0x44, 0xF3, 0x5B, 0xDB, 0xA1, 0xFF, 0xFF, 0xFF, 0x87, 0x3E, 0xFF, 0x01,
+	 0x82, 0xE1, 0x80, 0xFF, 0x90, 0xFF, 0x88, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0x87, 0x3E, 0x41, 0xFF,
+	 0x00, 0x60, 0x03, 0xE1, 0x21, 0x46, 0x66, 0x45, 0x00, 0xF4, 0x2E, 0x44, 0x09, 0xFA, 0x6A, 0x61,
+	 0x7F, 0x60, 0xFE, 0x63, 0xA1, 0xFF, 0x9A, 0xFF, 0x05, 0x11, 0x0A, 0x00, 0x00, 0xF4, 0x01, 0xF2,
+	 0x17, 0x18, 0x7A, 0x61, 0x02, 0x25, 0x04, 0x00, 0x6C, 0x44, 0x7A, 0xDA, 0xFB, 0x1C, 0xF6, 0x11,
+	 0xD9, 0x81, 0x41, 0xFF, 0x02, 0x1C, 0x00, 0xF4, 0xDA, 0x82, 0x41, 0xFF, 0xC9, 0x81, 0xCB, 0x83,
+	 0x6C, 0x44, 0x5A, 0xDA, 0x02, 0x1C, 0x00, 0xF4, 0x81, 0xF2, 0x6C, 0x44, 0x5A, 0xDA, 0xCB, 0x83,
+	 0x02, 0x74, 0x02, 0x60, 0x04, 0xE1, 0x80, 0x60, 0x00, 0x61, 0x5D, 0x93, 0xB5, 0xFF, 0x98, 0xFF,
+	 0x26, 0x44, 0xFD, 0xB4, 0x84, 0xBC, 0x40, 0x46, 0x65, 0x46, 0x00, 0x64, 0x23, 0xFA, 0x3F, 0xFC,
+	 0x63, 0x47, 0x0A, 0x63, 0x0F, 0xFC, 0x00, 0xF4, 0x08, 0xFA, 0xCB, 0xFE, 0x18, 0xE1, 0x44, 0xFF,
+	 0xA1, 0xFF, 0x98, 0xFF, 0x80, 0x3E, 0xE2, 0xFE, 0x03, 0x04, 0xA3, 0x60, 0x99, 0x78, 0xFF, 0xFF,
+	 0xE0, 0xFE, 0x03, 0x04, 0xA3, 0x60, 0xAF, 0x78, 0xFF, 0xFF, 0xE1, 0xFE, 0x07, 0x05, 0x9F, 0xFE,
+	 0x03, 0x04, 0x18, 0x60, 0x24, 0x78, 0xFF, 0xFF, 0x43, 0xFF, 0xA9, 0x01, 0xD3, 0xF3, 0xFF, 0xFF,
+	 0x01, 0xB4, 0xFF, 0xFF, 0x08, 0x24, 0x15, 0x00, 0x29, 0x44, 0x08, 0x26, 0xE1, 0x01, 0x72, 0x44,
+	 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0x94, 0xF3, 0xE8, 0x85, 0xFF, 0xB7,
+	 0xE0, 0x84, 0xE0, 0x84, 0xB4, 0x85, 0x73, 0x44, 0xD4, 0x84, 0x10, 0x65, 0xD4, 0x80, 0xFF, 0xFF,
+	 0x37, 0x04, 0x3F, 0x40, 0x40, 0x26, 0x09, 0x00, 0x18, 0x60, 0x1C, 0xF3, 0x5A, 0xD1, 0xA0, 0x50,
+	 0xA4, 0x52, 0x5A, 0xD3, 0x5A, 0xD1, 0xA0, 0x50, 0xA4, 0x50, 0xBC, 0xF3, 0xD2, 0xF1, 0x01, 0xA8,
+	 0x07, 0xA8, 0x0A, 0x03, 0x09, 0x03, 0x64, 0x40, 0x01, 0x26, 0x09, 0x00, 0x18, 0x60, 0x07, 0xF3,
+	 0xFF, 0xFF, 0x01, 0xB4, 0xFF, 0xFF, 0x03, 0x02, 0xAD, 0x4F, 0xFA, 0xB4, 0xA0, 0x5D, 0xAE, 0x4F,
+	 0x02, 0xBC, 0x00, 0x7F, 0xA0, 0x5E, 0x3F, 0x40, 0x02, 0x2B, 0x11, 0x00, 0x0C, 0x60, 0x00, 0x62,
+	 0x00, 0x60, 0x71, 0x7C, 0x00, 0x60, 0xB1, 0x65, 0x1A, 0x60, 0x58, 0x4D, 0x88, 0x78, 0xFF, 0xFF,
+	 0x08, 0xE1, 0x62, 0xFF, 0xA3, 0xFF, 0xFF, 0xFF, 0xA2, 0xFF, 0x02, 0x60, 0x08, 0xE1, 0xBD, 0xFE,
+	 0x97, 0x01, 0x21, 0x46, 0x01, 0x5D, 0x5C, 0x62, 0x03, 0xE1, 0x44, 0xFF, 0xA1, 0xFF, 0x9A, 0xFF,
+	 0x7A, 0xDC, 0x7A, 0xDC, 0x7A, 0xDC, 0x62, 0x62, 0x7A, 0xDC, 0x7A, 0xDC, 0x7A, 0xDC, 0xA1, 0xFF,
+	 0x5A, 0xDC, 0x12, 0xE1, 0x02, 0x60, 0x01, 0xE1, 0xA1, 0xFF, 0x98, 0xFF, 0x80, 0x3E, 0x28, 0x40,
+	 0x40, 0x2B, 0x03, 0x00, 0x29, 0x40, 0x20, 0x27, 0x97, 0x00, 0xC8, 0x74, 0xCD, 0xE2, 0x29, 0x44,
+	 0x08, 0xBC, 0x40, 0x49, 0x44, 0xFF, 0x05, 0xE1, 0x28, 0x40, 0x08, 0x2A, 0x07, 0x00, 0x28, 0x40,
+	 0x48, 0x36, 0x04, 0x00, 0xD2, 0xF3, 0xFF, 0xFF, 0x02, 0xBC, 0xD2, 0xFB, 0x29, 0x44, 0xFF, 0x60,
+	 0xEF, 0x65, 0x24, 0x89, 0x40, 0x27, 0x3F, 0x00, 0x00, 0x00, 0x29, 0x40, 0x80, 0x27, 0x0B, 0x00,
+	 0x07, 0x61, 0xA1, 0xFF, 0xCD, 0x81, 0x04, 0x25, 0x61, 0x00, 0x87, 0x4C, 0xFB, 0x02, 0xF3, 0x60,
+	 0xA0, 0x64, 0x80, 0x4C, 0x07, 0x00, 0xA1, 0xFF, 0x9C, 0x4C, 0x9C, 0x4C, 0x9C, 0x4D, 0x05, 0x60,
+	 0xCF, 0x64, 0x80, 0x4C, 0x28, 0x40, 0x40, 0x2B, 0x05, 0x00, 0x29, 0x40, 0x20, 0x27, 0x02, 0x00,
+	 0x15, 0x60, 0x6F, 0x6B, 0x04, 0x25, 0x4A, 0x00, 0x30, 0x64, 0x3A, 0xDB, 0x44, 0xFF, 0x04, 0x25,
+	 0x45, 0x00, 0x04, 0x60, 0x00, 0x65, 0x25, 0x44, 0xB4, 0x84, 0x80, 0x4E, 0x2D, 0x41, 0x04, 0x25,
+	 0x3D, 0x00, 0x61, 0x4C, 0x00, 0x60, 0x8A, 0x65, 0xC5, 0x81, 0x61, 0x54, 0xA1, 0xFF, 0xFF, 0xFF,
+	 0x04, 0x25, 0x34, 0x00, 0x67, 0x4E, 0x07, 0x64, 0x1C, 0xFB, 0x00, 0xE1, 0x02, 0x60, 0x05, 0xE1,
+	 0xA1, 0xFF, 0x98, 0xFF, 0x80, 0x3E, 0x28, 0x40, 0x40, 0x27, 0x0A, 0x00, 0x1C, 0x65, 0x28, 0x40,
+	 0xA4, 0x36, 0x14, 0x65, 0x23, 0x44, 0xC4, 0x84, 0x28, 0x40, 0x08, 0x2A, 0x0C, 0x00, 0x07, 0x00,
+	 0x23, 0x44, 0x1C, 0xA4, 0x29, 0x40, 0x20, 0x27, 0x02, 0x00, 0x11, 0x60, 0x0F, 0x6B, 0x3C, 0x46,
+	 0x98, 0xF0, 0x23, 0x44, 0xC4, 0x84, 0x06, 0x74, 0x25, 0x5C, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84,
+	 0xE0, 0x84, 0xB0, 0x84, 0x80, 0x4C, 0x9C, 0x4C, 0x44, 0xFF, 0x18, 0xE1, 0x0A, 0x64, 0x1E, 0x74,
+	 0x02, 0x60, 0x05, 0xE1, 0x40, 0x40, 0xA1, 0xFF, 0x98, 0xFF, 0x80, 0x3E, 0xC4, 0xE2, 0x27, 0x44,
+	 0x20, 0x2A, 0x06, 0x00, 0x42, 0x64, 0x3A, 0xDB, 0x67, 0x4C, 0xB0, 0x60, 0x80, 0x78, 0xFF, 0xFF,
+	 0x41, 0x64, 0x3A, 0xDB, 0x62, 0xFF, 0x08, 0xE1, 0xE2, 0xFE, 0x72, 0x52, 0xA1, 0xFF, 0x98, 0xFF,
+	 0x80, 0x3E, 0xA1, 0xFF, 0x98, 0xFF, 0x80, 0x3E, 0x28, 0x40, 0x08, 0x27, 0x66, 0x01, 0x3C, 0x46,
+	 0x8B, 0xFF, 0x84, 0x60, 0x00, 0xE4, 0x0F, 0x60, 0x92, 0x64, 0xC9, 0x60, 0x58, 0x4F, 0x10, 0x78,
+	 0xFF, 0xFF, 0x3F, 0xF2, 0x00, 0x60, 0x18, 0x70, 0x18, 0x71, 0x20, 0x72, 0x00, 0xF2, 0x60, 0x53,
+	 0x20, 0xE1, 0xA1, 0xFF, 0x88, 0x75, 0x00, 0xE1, 0xFF, 0xFF, 0x60, 0x50, 0x75, 0x44, 0x12, 0x71,
+	 0x6E, 0x72, 0x81, 0x75, 0xFF, 0xFF, 0x88, 0xFF, 0xA3, 0x60, 0xB5, 0x78, 0xFF, 0xFF, 0x32, 0xF3,
+	 0x08, 0x29, 0x0A, 0x00, 0x60, 0x40, 0x07, 0x22, 0x07, 0x00, 0xFE, 0xB4, 0x32, 0xFB, 0x27, 0x44,
+	 0x10, 0xBC, 0xF7, 0xB4, 0x40, 0x47, 0x43, 0xFF, 0x00, 0x64, 0x3A, 0xDB, 0x01, 0x60, 0x08, 0xE1,
+	 0x31, 0x40, 0x01, 0x2A, 0x04, 0x00, 0x00, 0x64, 0x33, 0xFB, 0x01, 0x60, 0x0A, 0xE1, 0xE5, 0xFE,
+	 0x27, 0x05, 0x9F, 0xFE, 0x12, 0x05, 0x31, 0x41, 0x40, 0x2A, 0x0F, 0x00, 0x07, 0x60, 0xEA, 0xF1,
+	 0xAE, 0x4C, 0x90, 0x80, 0x10, 0x2A, 0x09, 0x00, 0x7F, 0xB1, 0x07, 0x60, 0xEA, 0xFB, 0x60, 0x40,
+	 0x10, 0x2A, 0x80, 0xB9, 0x41, 0x51, 0xDF, 0xFE, 0x19, 0xFF, 0x27, 0x44, 0x10, 0x26, 0x13, 0x00,
+	 0x9F, 0xFE, 0x02, 0x04, 0x40, 0xE1, 0x06, 0x00, 0x7C, 0xE1, 0x31, 0x44, 0x01, 0x2A, 0x02, 0x00,
+	 0x04, 0x0A, 0xFD, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x81, 0x3E, 0xAF, 0x60, 0x7B, 0x78, 0xFF, 0xFF,
+	 0xAA, 0x60, 0xC0, 0x78, 0xFF, 0xFF, 0x27, 0x44, 0x08, 0x26, 0xFF, 0xFF, 0xC0, 0x60, 0xEA, 0x78,
+	 0xFF, 0xFF, 0x48, 0xF3, 0x32, 0xF1, 0x00, 0x63, 0x64, 0x40, 0x07, 0x26, 0x03, 0x00, 0xA5, 0x60,
+	 0x6C, 0x78, 0xFF, 0xFF, 0x31, 0x40, 0x08, 0x26, 0xF1, 0x01, 0xCD, 0xE2, 0x84, 0xE1, 0x70, 0x41,
+	 0xAD, 0x80, 0x71, 0x40, 0x80, 0x27, 0xEA, 0x12, 0x03, 0x03, 0xC1, 0x60, 0x3B, 0x78, 0xFF, 0xFF,
+	 0xA1, 0xFF, 0xFF, 0xFF, 0xC4, 0xE2, 0x32, 0xFD, 0x60, 0x40, 0x01, 0x2A, 0xDC, 0x01, 0x3C, 0x46,
+	 0x3E, 0xF2, 0x2A, 0xF0, 0x27, 0x41, 0x44, 0x48, 0x20, 0xB9, 0x01, 0xB4, 0xF7, 0xB1, 0x0A, 0x03,
+	 0x64, 0x40, 0x08, 0x27, 0x07, 0x00, 0x0F, 0x60, 0xEE, 0x63, 0x00, 0x64, 0x45, 0xFB, 0x46, 0xFB,
+	 0xBD, 0xDB, 0xA3, 0xDB, 0xCB, 0x0A, 0xCA, 0x11, 0x41, 0x47, 0x22, 0xF2, 0xFF, 0xFF, 0x60, 0x40,
+	 0x10, 0x26, 0x04, 0x00, 0x01, 0x2A, 0x05, 0x00, 0x10, 0x2B, 0x03, 0x00, 0x29, 0x47, 0x20, 0xBF,
+	 0x40, 0x49, 0x05, 0xE1, 0x01, 0x60, 0x08, 0xE1, 0x2A, 0xE8, 0x3C, 0x46, 0x00, 0x63, 0x32, 0xFD,
+	 0x43, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x2A, 0x03, 0x00, 0xA8, 0x60, 0x76, 0x78,
+	 0xFF, 0xFF, 0x64, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x27, 0x0E, 0x00, 0x1F, 0xF2, 0xFF, 0xFF,
+	 0x60, 0x40, 0x40, 0x2B, 0x09, 0x00, 0x15, 0x60, 0xDD, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x02, 0x2A,
+	 0x03, 0x00, 0xA9, 0x60, 0x81, 0x78, 0xFF, 0xFF, 0x1F, 0xF2, 0xC0, 0x60, 0x00, 0x65, 0xA4, 0x9C,
+	 0x3F, 0x60, 0xCF, 0x65, 0x29, 0x44, 0xA4, 0x84, 0x30, 0x89, 0x15, 0x60, 0xD9, 0xF3, 0xFF, 0xFF,
+	 0x15, 0x60, 0xD8, 0xFB, 0x1F, 0xF2, 0x39, 0xF1, 0xE0, 0x60, 0xFF, 0xB5, 0x0A, 0x18, 0x60, 0x47,
+	 0x1F, 0xB4, 0xD0, 0x84, 0xE0, 0xA0, 0x02, 0x0D, 0x00, 0x64, 0x02, 0x00, 0x01, 0x04, 0x1F, 0x64,
+	 0x60, 0x47, 0xB4, 0x81, 0x07, 0x60, 0xEB, 0xF1, 0xFF, 0xFF, 0xB1, 0x8C, 0x29, 0x40, 0x40, 0x2B,
+	 0x10, 0x00, 0x22, 0x60, 0xC6, 0x65, 0x60, 0x47, 0x1F, 0xB4, 0xE0, 0x84, 0xE0, 0x84, 0x44, 0xD3,
+	 0x5A, 0xD1, 0x01, 0x60, 0x00, 0xE1, 0x01, 0x60, 0x09, 0x6B, 0x60, 0x4C, 0xB5, 0xFF, 0x64, 0x4C,
+	 0x14, 0x00, 0x22, 0x60, 0xC6, 0x65, 0x60, 0x47, 0x1F, 0xB4, 0xE0, 0x84, 0xE0, 0x84, 0x44, 0xD3,
+	 0x5A, 0xD1, 0x01, 0x60, 0x00, 0xE1, 0x05, 0x60, 0x69, 0x6B, 0x60, 0x4C, 0xB5, 0xFF, 0x64, 0x4C,
+	 0x7C, 0x44, 0x29, 0x40, 0x80, 0x2B, 0x67, 0x44, 0x60, 0x4C, 0x00, 0xE1, 0x84, 0xFF, 0xC1, 0x60,
+	 0x6B, 0x64, 0x40, 0x42, 0x82, 0xFF, 0x0D, 0x00, 0xE5, 0xFE, 0x03, 0x04, 0xAA, 0x60, 0xC0, 0x78,
+	 0xFF, 0xFF, 0x32, 0xF1, 0xFF, 0xFF, 0x64, 0x40, 0x07, 0x22, 0x43, 0xFF, 0xA4, 0x60, 0x7C, 0x78,
+	 0xFF, 0xFF, 0x3C, 0x44, 0x0B, 0x64, 0x3A, 0xDB, 0x01, 0x60, 0x0A, 0xE1, 0x1C, 0x42, 0x22, 0x46,
+	 0x13, 0xF2, 0xFF, 0x65, 0x60, 0x47, 0x2A, 0xF2, 0x40, 0x45, 0x40, 0x48, 0x04, 0x2B, 0x13, 0x00,
+	 0x16, 0xF2, 0x1D, 0xF2, 0x40, 0x43, 0x0F, 0xF2, 0x40, 0x4D, 0x0F, 0x64, 0x14, 0xF0, 0x35, 0xF2,
+	 0xA0, 0x82, 0x0F, 0xB4, 0xCA, 0x85, 0xD4, 0x80, 0x10, 0xF2, 0x01, 0x02, 0x2B, 0xFA, 0x27, 0x44,
+	 0x40, 0xBC, 0x40, 0x47, 0x13, 0x00, 0x17, 0xF2, 0x2C, 0xF0, 0x40, 0x43, 0x1B, 0xF2, 0x1D, 0xFA,
+	 0x40, 0x4D, 0x64, 0x40, 0x01, 0x2A, 0x02, 0x00, 0xAB, 0xFC, 0x05, 0x00, 0x28, 0x40, 0xA4, 0x36,
+	 0x02, 0x00, 0x11, 0xF2, 0x2B, 0xFA, 0x27, 0x44, 0xBF, 0xB4, 0x40, 0x47, 0xF0, 0xFE, 0xAF, 0x60,
+	 0x85, 0x78, 0xFF, 0xFF, 0x22, 0x46, 0x2C, 0xF0, 0x27, 0x44, 0xDF, 0xB4, 0x40, 0x47, 0x64, 0x40,
+	 0x01, 0x26, 0x01, 0x00, 0x01, 0x00, 0x11, 0x00, 0x2A, 0xF0, 0x01, 0x65, 0x64, 0x40, 0xA4, 0x3A,
+	 0x04, 0x65, 0x27, 0x44, 0x34, 0x87, 0x36, 0xF3, 0xFF, 0xFF, 0x60, 0x56, 0xAD, 0xE2, 0x04, 0x64,
+	 0x3A, 0xDB, 0x69, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x81, 0x3E, 0x06, 0x64, 0x3A, 0xDB, 0x22, 0x46,
+	 0x01, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0xC1, 0x60, 0x44, 0x78, 0xFF, 0xFF, 0x28, 0x40, 0xC4, 0x3A,
+	 0x0C, 0x00, 0x27, 0x44, 0xFD, 0xB4, 0x40, 0x47, 0xA8, 0xE2, 0x05, 0xE1, 0x01, 0x60, 0x08, 0xE1,
+	 0x2A, 0xE8, 0x3C, 0x46, 0xA5, 0x60, 0x1C, 0x78, 0xFF, 0xFF, 0x3F, 0x40, 0x01, 0x2B, 0x05, 0x00,
+	 0x67, 0x4C, 0x01, 0x60, 0x00, 0xE1, 0x05, 0x60, 0x69, 0x6B, 0x07, 0x60, 0xEC, 0xF1, 0x1F, 0xF2,
+	 0x2A, 0xE8, 0xB0, 0x81, 0x29, 0x40, 0x40, 0x2B, 0x14, 0x00, 0x61, 0x4C, 0x22, 0x60, 0xC6, 0x65,
+	 0x61, 0x47, 0x1F, 0xB4, 0xE0, 0x84, 0xE0, 0x84, 0x44, 0xD3, 0x5A, 0xD1, 0x01, 0x60, 0x00, 0xE1,
+	 0x01, 0x60, 0x09, 0x6B, 0x60, 0x4C, 0xB5, 0xFF, 0xFF, 0x60, 0xF2, 0x64, 0x64, 0x4C, 0x40, 0x43,
+	 0x18, 0x00, 0x29, 0x47, 0x80, 0xB7, 0x34, 0x94, 0x60, 0x4C, 0x22, 0x60, 0xC6, 0x65, 0x61, 0x47,
+	 0x1F, 0xB4, 0xE0, 0x84, 0xE0, 0x84, 0x44, 0xD3, 0x5A, 0xD1, 0x01, 0x60, 0x00, 0xE1, 0x05, 0x60,
+	 0x69, 0x6B, 0x60, 0x4C, 0xB5, 0xFF, 0x64, 0x4C, 0x7C, 0x44, 0x29, 0x40, 0x80, 0x2B, 0x67, 0x44,
+	 0x60, 0x4C, 0x40, 0xE1, 0x01, 0x60, 0x08, 0xE1, 0x28, 0x45, 0xBF, 0x60, 0xFF, 0x64, 0x24, 0x88,
+	 0xC4, 0xE2, 0x08, 0x64, 0x3A, 0xDB, 0x21, 0x46, 0x2A, 0x44, 0x72, 0x45, 0x24, 0xFA, 0x94, 0xF3,
+	 0x06, 0x04, 0xE4, 0xE2, 0xDC, 0x9C, 0x29, 0x40, 0x01, 0x26, 0x64, 0x44, 0x94, 0xF9, 0x25, 0xFA,
+	 0x95, 0xF3, 0x02, 0x04, 0xDC, 0x84, 0x95, 0xFB, 0x28, 0xFA, 0x96, 0xF3, 0x02, 0x04, 0xDC, 0x84,
+	 0x96, 0xFB, 0x29, 0xFA, 0x24, 0x44, 0x04, 0x2A, 0x06, 0x00, 0x28, 0x40, 0xA4, 0x36, 0x03, 0x00,
+	 0xA7, 0x60, 0x46, 0x78, 0xFF, 0xFF, 0x94, 0xFC, 0x13, 0x60, 0x4A, 0xF1, 0x28, 0x44, 0x08, 0x2A,
+	 0x51, 0x00, 0x03, 0x2B, 0x01, 0x00, 0x4E, 0x00, 0x64, 0x40, 0x00, 0x36, 0x4B, 0x00, 0x32, 0xF2,
+	 0x2F, 0xF0, 0x50, 0xFE, 0x01, 0x2A, 0x03, 0x00, 0x01, 0x61, 0x8E, 0xF3, 0x31, 0x00, 0xD0, 0x80,
+	 0x33, 0xF2, 0x30, 0xF0, 0x34, 0xF2, 0xD0, 0x80, 0x31, 0xF0, 0xFF, 0xFF, 0xD0, 0x80, 0x60, 0x47,
+	 0x34, 0x0C, 0xFF, 0xB4, 0x15, 0x60, 0x02, 0x65, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0xFF, 0xFF,
+	 0x31, 0x18, 0x60, 0x43, 0x50, 0xFE, 0x66, 0x41, 0x32, 0xF0, 0x63, 0x46, 0x03, 0xF2, 0x61, 0x46,
+	 0xD0, 0x80, 0x33, 0xF0, 0x63, 0x46, 0x04, 0xF2, 0x61, 0x46, 0xD0, 0x80, 0x34, 0xF0, 0x63, 0x46,
+	 0x05, 0xF2, 0xFF, 0xFF, 0xD0, 0x80, 0xFF, 0xFF, 0x04, 0x0C, 0x00, 0xF2, 0x61, 0x46, 0x1A, 0x18,
+	 0xE8, 0x01, 0x06, 0xF0, 0x8E, 0xF3, 0x61, 0x46, 0x02, 0x61, 0x64, 0x40, 0x02, 0x2A, 0x12, 0x00,
+	 0xFC, 0xA0, 0xFF, 0xFF, 0x04, 0x0E, 0x61, 0x44, 0x14, 0xFA, 0x11, 0xFC, 0x0B, 0x00, 0x2C, 0xF2,
+	 0x2F, 0xFA, 0x2D, 0xF2, 0x30, 0xFA, 0x2E, 0xF2, 0x31, 0xFA, 0x1D, 0xFF, 0x26, 0x44, 0x02, 0xBC,
+	 0x40, 0x46, 0x1E, 0x00, 0x26, 0x43, 0x84, 0xBB, 0xFC, 0xB3, 0x21, 0x46, 0x01, 0x5D, 0x0F, 0xFC,
+	 0x5C, 0x46, 0x05, 0xFF, 0x27, 0x44, 0x01, 0x2A, 0x13, 0x00, 0x50, 0xFE, 0x28, 0x40, 0x08, 0x3A,
+	 0x12, 0x00, 0x2F, 0xF2, 0x30, 0xF0, 0x60, 0x43, 0x31, 0xF2, 0x22, 0x46, 0x64, 0x41, 0x2C, 0xF0,
+	 0x2D, 0xF0, 0xD3, 0x80, 0x2E, 0xF0, 0xD1, 0x80, 0xD0, 0x80, 0x27, 0x44, 0x09, 0x0C, 0x03, 0x00,
+	 0x27, 0x44, 0x06, 0x22, 0x05, 0x00, 0xB8, 0xB4, 0x40, 0x47, 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE,
+	 0xD4, 0x64, 0x40, 0x48, 0x0D, 0x64, 0x3A, 0xDB, 0x21, 0x46, 0x1C, 0xF2, 0x00, 0xE1, 0xF0, 0xFE,
+	 0x00, 0x63, 0x28, 0x44, 0xA4, 0x36, 0x07, 0x00, 0x04, 0x2B, 0x05, 0x00, 0x30, 0xF3, 0x2D, 0x45,
+	 0xD4, 0x84, 0xCA, 0x65, 0xD4, 0x83, 0xD4, 0x64, 0x35, 0x00, 0x0F, 0x64, 0x3A, 0xDB, 0x21, 0x46,
+	 0x29, 0x40, 0x40, 0x27, 0x15, 0x00, 0x80, 0x27, 0x02, 0x00, 0xCA, 0x65, 0x01, 0x00, 0x6A, 0x65,
+	 0x1C, 0xF2, 0xFF, 0xFF, 0x04, 0x7F, 0x40, 0x45, 0x0A, 0x36, 0x70, 0x64, 0x14, 0x36, 0x38, 0x64,
+	 0x37, 0x36, 0x15, 0x64, 0x6E, 0x3A, 0x17, 0x00, 0x84, 0x7F, 0x40, 0x45, 0x0B, 0x64, 0x13, 0x00,
+	 0x1C, 0xF2, 0x1E, 0x65, 0x40, 0x45, 0x0B, 0x36, 0x1E, 0x64, 0x0F, 0x36, 0x16, 0x64, 0x0A, 0x36,
+	 0x12, 0x64, 0x0E, 0x36, 0x0E, 0x64, 0x09, 0x36, 0x0E, 0x64, 0x0D, 0x36, 0x0A, 0x64, 0x08, 0x36,
+	 0x0A, 0x64, 0x0C, 0x36, 0x0A, 0x64, 0x40, 0x4D, 0x00, 0xE1, 0xF0, 0xFE, 0x2B, 0xF2, 0xC4, 0x85,
+	 0xD4, 0x83, 0xC4, 0x64, 0x40, 0x48, 0x2F, 0xF0, 0xB0, 0xF0, 0xB1, 0xF2, 0xA1, 0xFF, 0x12, 0x74,
+	 0xCD, 0xE2, 0x80, 0x4E, 0x12, 0x74, 0x83, 0x4C, 0x12, 0x74, 0x9A, 0xFF, 0x84, 0x4C, 0x12, 0x74,
+	 0x85, 0x4C, 0x12, 0x74, 0x81, 0x4C, 0x12, 0x74, 0xA1, 0xFF, 0x98, 0xFF, 0xB1, 0x60, 0x58, 0x4F,
+	 0x00, 0x78, 0xFF, 0xFF, 0x01, 0x60, 0x18, 0xE1, 0x78, 0x44, 0x03, 0xA4, 0x35, 0xFB, 0xB1, 0x60,
+	 0x43, 0x78, 0xFF, 0xFF, 0x29, 0x44, 0xF7, 0xB4, 0x40, 0x49, 0x27, 0x44, 0x01, 0x2A, 0x05, 0x00,
+	 0xFE, 0xB4, 0x40, 0x47, 0xA5, 0x60, 0xCD, 0x78, 0xFF, 0xFF, 0x13, 0x60, 0x2E, 0xF3, 0xFF, 0xFF,
+	 0x60, 0x40, 0x02, 0x36, 0xC1, 0xFE, 0xA4, 0x60, 0x6F, 0x78, 0xFF, 0xFF, 0x28, 0x40, 0xB4, 0x3A,
+	 0x0B, 0x00, 0x27, 0x44, 0x07, 0x22, 0x05, 0x00, 0xF8, 0xB4, 0x40, 0x47, 0x02, 0x64, 0x31, 0xFB,
+	 0xC0, 0xFE, 0xA6, 0x60, 0xDD, 0x78, 0xFF, 0xFF, 0x28, 0x44, 0xD4, 0x36, 0x03, 0x00, 0xA8, 0x60,
+	 0x5D, 0x78, 0xFF, 0xFF, 0xA8, 0xE2, 0x27, 0x44, 0xFB, 0xB4, 0x40, 0x47, 0x1C, 0x42, 0x22, 0x46,
+	 0x16, 0x60, 0x2B, 0xF3, 0xFF, 0xFF, 0x34, 0xFB, 0x2A, 0xF0, 0xF7, 0x60, 0xFF, 0x64, 0xA0, 0x84,
+	 0xA2, 0xDA, 0x60, 0x40, 0x40, 0x2B, 0xC4, 0x00, 0x22, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x22, 0x26,
+	 0x3F, 0x00, 0x01, 0x26, 0x03, 0x00, 0x04, 0x26, 0x05, 0x00, 0xBA, 0x00, 0x04, 0x2B, 0xB8, 0x00,
+	 0x87, 0xF5, 0x01, 0x00, 0x07, 0xF4, 0x4B, 0xF2, 0xFF, 0xFF, 0xDC, 0x84, 0x4B, 0xFA, 0x0C, 0x60,
+	 0xFE, 0x62, 0x80, 0xFF, 0xC8, 0x60, 0x78, 0x44, 0x02, 0xA4, 0xA2, 0xDB, 0x46, 0x78, 0xFF, 0xFF,
+	 0x82, 0xFF, 0x87, 0xF3, 0x66, 0x5C, 0xD0, 0x80, 0x00, 0x7C, 0x07, 0x03, 0x66, 0x43, 0x22, 0x46,
+	 0x22, 0xF2, 0x63, 0x46, 0x60, 0x40, 0x01, 0x2A, 0x01, 0x00, 0x3C, 0xF1, 0x4B, 0xF0, 0x64, 0x41,
+	 0x64, 0x47, 0x60, 0x5F, 0x20, 0xBC, 0x80, 0x26, 0x80, 0xAC, 0x60, 0x47, 0x22, 0x46, 0x3A, 0xFA,
+	 0x64, 0x44, 0x20, 0x7F, 0x34, 0x94, 0x3B, 0xFA, 0x08, 0x60, 0x00, 0xEA, 0x0F, 0x64, 0x60, 0x7F,
+	 0xA0, 0x5A, 0x80, 0x60, 0x00, 0xEA, 0xA0, 0x60, 0x00, 0xEA, 0xD1, 0x60, 0x00, 0xEA, 0x80, 0x00,
+	 0x2A, 0xF2, 0x00, 0x60, 0x7C, 0x62, 0x60, 0x40, 0x40, 0x2B, 0x24, 0x00, 0xA2, 0xD3, 0x00, 0x61,
+	 0x60, 0xFE, 0xA0, 0xD3, 0x5E, 0xD1, 0xFF, 0xFF, 0x20, 0xFE, 0x64, 0x5F, 0xDC, 0x84, 0xF1, 0x81,
+	 0xC0, 0x2B, 0x04, 0x00, 0x80, 0x2A, 0x02, 0x00, 0x7F, 0xA4, 0xDC, 0x84, 0xFF, 0x3B, 0x03, 0x00,
+	 0x60, 0x47, 0xDC, 0x87, 0x01, 0x61, 0xC0, 0x80, 0x00, 0x36, 0xDC, 0x84, 0x4E, 0xDB, 0x60, 0xFE,
+	 0x5A, 0xD1, 0xFF, 0xFF, 0xC1, 0x84, 0xF0, 0x22, 0x10, 0xA4, 0xF0, 0x2A, 0x01, 0x00, 0x00, 0x64,
+	 0xA2, 0xDB, 0x20, 0xFE, 0x00, 0x60, 0x3E, 0xF3, 0xFF, 0xFF, 0xA0, 0xD3, 0x5A, 0xD1, 0x3A, 0xFA,
+	 0x3B, 0xF8, 0x74, 0x62, 0xA2, 0xD0, 0xFF, 0xFF, 0x64, 0x44, 0xE0, 0x7F, 0xA0, 0x5A, 0x64, 0x47,
+	 0xE1, 0x7F, 0x5A, 0xD0, 0xA0, 0x5A, 0x64, 0x44, 0xE2, 0x7F, 0xA0, 0x5A, 0x00, 0x60, 0x40, 0xF3,
+	 0xFF, 0xFF, 0xA0, 0xD1, 0x5A, 0xD1, 0x64, 0x45, 0x64, 0x44, 0xE3, 0x7F, 0xA0, 0x5A, 0x64, 0x47,
+	 0xE4, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xE5, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xE6, 0x7F,
+	 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xE7, 0x7F, 0xA0, 0x5A, 0x65, 0x40, 0x0D, 0x3A, 0x1C, 0x00,
+	 0x64, 0x47, 0xE8, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xE9, 0x7F, 0xA0, 0x5A, 0x64, 0x47,
+	 0xEA, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xEB, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xEC, 0x7F,
+	 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xED, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xEE, 0x7F, 0x5A, 0xD1,
+	 0xA0, 0x5A, 0x64, 0x44, 0xEF, 0x7F, 0xA0, 0x5A, 0x08, 0x60, 0x00, 0xEA, 0x65, 0x44, 0x02, 0xA4,
+	 0x60, 0x7F, 0xA0, 0x5A, 0x80, 0x60, 0x00, 0xEA, 0xA0, 0x60, 0x00, 0xEA, 0xD1, 0x60, 0x00, 0xEA,
+	 0x0B, 0xF2, 0xFF, 0xFF, 0x7F, 0xB4, 0x0C, 0xF0, 0x04, 0x02, 0x64, 0x46, 0x00, 0xF0, 0x04, 0x64,
+	 0x22, 0x46, 0x03, 0xFA, 0x60, 0x41, 0x64, 0x46, 0x01, 0xF2, 0xFC, 0xA1, 0x61, 0x45, 0xD4, 0x84,
+	 0xFF, 0xFF, 0x08, 0x02, 0x00, 0xF0, 0x04, 0x63, 0x64, 0x46, 0x01, 0xF2, 0x22, 0x46, 0x1A, 0xFA,
+	 0x03, 0xFC, 0x02, 0x00, 0x22, 0x46, 0x1A, 0xFA, 0x35, 0xF2, 0x04, 0xF8, 0xDC, 0x84, 0x35, 0xFA,
+	 0x14, 0xF2, 0x0F, 0xB5, 0x0F, 0xB4, 0xCC, 0x84, 0x94, 0x80, 0x04, 0x60, 0x00, 0x65, 0x2A, 0xF2,
+	 0x01, 0x02, 0x94, 0x84, 0x2A, 0xFA, 0x95, 0xFC, 0x06, 0x00, 0xC4, 0x3A, 0x07, 0x00, 0x27, 0x44,
+	 0xFD, 0xB4, 0x40, 0x47, 0xA8, 0xE2, 0xA5, 0x60, 0x7A, 0x78, 0xFF, 0xFF, 0x28, 0x44, 0x04, 0x26,
+	 0x05, 0x00, 0x68, 0x3A, 0x03, 0x00, 0x32, 0x44, 0x00, 0x27, 0x03, 0x00, 0xA4, 0x60, 0x7C, 0x78,
+	 0xFF, 0xFF, 0x0A, 0x64, 0x3A, 0xDB, 0xA4, 0x60, 0x7C, 0x78, 0xFF, 0xFF, 0x0E, 0x64, 0x3A, 0xDB,
+	 0x3C, 0x44, 0x60, 0x46, 0x1E, 0xF0, 0x40, 0x42, 0x64, 0x40, 0x40, 0x27, 0x48, 0x00, 0x1F, 0xF2,
+	 0xFF, 0xFF, 0x60, 0x40, 0x40, 0x27, 0x3C, 0x00, 0x80, 0x2B, 0x0B, 0x00, 0xBF, 0x60, 0xFF, 0x65,
+	 0x29, 0x44, 0x24, 0x89, 0x80, 0x60, 0x00, 0x65, 0x29, 0x44, 0x34, 0x89, 0x80, 0x60, 0x00, 0x63,
+	 0x05, 0x00, 0x3F, 0x60, 0xFF, 0x65, 0x29, 0x44, 0x24, 0x89, 0x00, 0x63, 0x1E, 0xF2, 0x39, 0xF1,
+	 0xC0, 0x60, 0xFF, 0xB5, 0x0A, 0x18, 0x60, 0x47, 0x1F, 0xB4, 0xD0, 0x84, 0xE0, 0xA0, 0x02, 0x0D,
+	 0x00, 0x64, 0x02, 0x00, 0x01, 0x04, 0x1F, 0x64, 0x60, 0x47, 0xB4, 0x84, 0x07, 0x60, 0xEB, 0xF1,
+	 0x3C, 0x94, 0xB0, 0x84, 0x60, 0x4C, 0x22, 0x60, 0xC6, 0x65, 0x60, 0x47, 0x1F, 0xB4, 0xE0, 0x84,
+	 0xE0, 0x84, 0x44, 0xD3, 0x5A, 0xD1, 0x01, 0x60, 0x00, 0xE1, 0x05, 0x60, 0x69, 0x6B, 0x60, 0x4C,
+	 0xB5, 0xFF, 0x64, 0x4C, 0x7C, 0x44, 0x29, 0x40, 0x80, 0x2B, 0x67, 0x44, 0x60, 0x4C, 0x32, 0x00,
+	 0x15, 0x60, 0xDD, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x04, 0x26, 0xCB, 0x01, 0xBF, 0x01, 0x40, 0x60,
+	 0x00, 0x65, 0x29, 0x44, 0x34, 0x89, 0x40, 0x60, 0x00, 0x63, 0x9F, 0xF2, 0x1E, 0xF2, 0x39, 0xF1,
+	 0xC0, 0x60, 0xFF, 0xB5, 0x0A, 0x18, 0x60, 0x47, 0x1F, 0xB4, 0xD0, 0x84, 0xE0, 0xA0, 0x02, 0x0D,
+	 0x00, 0x64, 0x02, 0x00, 0x01, 0x04, 0x1F, 0x64, 0x60, 0x47, 0xB4, 0x84, 0x07, 0x60, 0xEB, 0xF1,
+	 0x3C, 0x94, 0xB0, 0x81, 0x61, 0x4C, 0x22, 0x60, 0xC6, 0x65, 0x61, 0x47, 0x1F, 0xB4, 0xE0, 0x84,
+	 0xE0, 0x84, 0x44, 0xD3, 0x5A, 0xD1, 0x01, 0x60, 0x00, 0xE1, 0x01, 0x60, 0x09, 0x6B, 0x60, 0x4C,
+	 0xB5, 0xFF, 0x64, 0x4C, 0x40, 0xE1, 0x01, 0x60, 0x08, 0xE1, 0x84, 0xFF, 0xC1, 0x60, 0x6B, 0x64,
+	 0x40, 0x42, 0x82, 0xFF, 0x2A, 0xF2, 0x10, 0x60, 0x00, 0x65, 0xA4, 0x84, 0xB4, 0xBC, 0x1E, 0xF0,
+	 0x40, 0x48, 0x64, 0x40, 0x40, 0x27, 0x17, 0x00, 0x1C, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x0A, 0x36,
+	 0x06, 0x00, 0x14, 0x36, 0x07, 0x00, 0x37, 0x36, 0x08, 0x00, 0x6E, 0x36, 0x09, 0x00, 0x70, 0x7C,
+	 0xA0, 0x63, 0x0F, 0x00, 0x38, 0x7C, 0x50, 0x63, 0x0C, 0x00, 0x15, 0x7C, 0x1E, 0x63, 0x09, 0x00,
+	 0x0B, 0x7C, 0x0F, 0x63, 0x06, 0x00, 0x9C, 0xF4, 0xFF, 0x65, 0x63, 0x47, 0xA4, 0x9C, 0xA7, 0x84,
+	 0x23, 0x00, 0x40, 0x45, 0x43, 0x4D, 0x00, 0xE1, 0xF0, 0xFE, 0x29, 0x40, 0x80, 0x2B, 0x03, 0x00,
+	 0x00, 0x60, 0x6A, 0x65, 0x02, 0x00, 0x00, 0x60, 0xCA, 0x65, 0x1F, 0xF2, 0xFF, 0xFF, 0x60, 0x40,
+	 0x40, 0x27, 0x0E, 0x00, 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x04, 0x27, 0x03, 0x00, 0x65, 0x44,
+	 0xE0, 0x85, 0x12, 0x00, 0x2B, 0xF2, 0x11, 0xF0, 0xC0, 0x84, 0xD0, 0x84, 0xC4, 0x83, 0x11, 0x00,
+	 0x1E, 0x64, 0xC4, 0x84, 0x60, 0x45, 0x08, 0x00, 0x40, 0x45, 0xFF, 0x60, 0xF8, 0x64, 0x40, 0x43,
+	 0x00, 0xE1, 0xF0, 0xFE, 0x00, 0x60, 0x3C, 0x65, 0x91, 0xF4, 0x1B, 0xF0, 0xC3, 0x84, 0xC4, 0x84,
+	 0xC0, 0x83, 0x28, 0x44, 0xA1, 0xFF, 0x12, 0x74, 0x80, 0x4E, 0x12, 0x74, 0x83, 0x4C, 0x9A, 0xFF,
+	 0x12, 0x74, 0x56, 0x62, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74,
+	 0x5C, 0x62, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0xA1, 0xFF,
+	 0x98, 0xFF, 0xB1, 0x60, 0x58, 0x4F, 0x00, 0x78, 0xFF, 0xFF, 0xBC, 0xFF, 0xB5, 0xFF, 0x01, 0x60,
+	 0x18, 0xE1, 0x47, 0xFF, 0x27, 0x44, 0x02, 0xBC, 0x40, 0x47, 0x36, 0xF3, 0xB6, 0xFF, 0xB7, 0xFF,
+	 0xB4, 0xFF, 0xC8, 0x60, 0x09, 0x7D, 0x7C, 0x4B, 0x60, 0x56, 0xAD, 0xE2, 0xA5, 0x60, 0xC7, 0x78,
+	 0xFF, 0xFF, 0x15, 0x60, 0xDD, 0xF3, 0x15, 0x60, 0xBE, 0xF3, 0x60, 0x40, 0x04, 0x26, 0x0B, 0x00,
+	 0x07, 0xB4, 0x60, 0x40, 0x01, 0x36, 0x07, 0x00, 0x29, 0x44, 0xBF, 0x60, 0xFF, 0xB7, 0x80, 0xBF,
+	 0x40, 0x49, 0x80, 0x67, 0x05, 0x00, 0x3F, 0x60, 0xFF, 0x65, 0x29, 0x44, 0x24, 0x89, 0x00, 0x64,
+	 0x12, 0x60, 0xD3, 0xF1, 0xFF, 0xFF, 0x15, 0x60, 0xD8, 0xF9, 0x39, 0xF1, 0x12, 0x60, 0xBF, 0xF1,
+	 0x64, 0x41, 0x64, 0x5E, 0x60, 0x45, 0x64, 0x47, 0x1F, 0xB4, 0x54, 0x94, 0xE0, 0xA0, 0x02, 0x0D,
+	 0x00, 0x64, 0x02, 0x00, 0x01, 0x04, 0x1F, 0x64, 0x60, 0x47, 0x07, 0x60, 0xEB, 0xF1, 0xB4, 0x84,
+	 0xB0, 0x8C, 0x22, 0x60, 0xC6, 0x7C, 0x60, 0x47, 0x1F, 0xB4, 0xE0, 0x84, 0xE0, 0x84, 0x40, 0xD3,
+	 0x5A, 0xD1, 0x01, 0x60, 0x00, 0xE1, 0x05, 0x60, 0x69, 0x6B, 0x60, 0x4C, 0xB5, 0xFF, 0x64, 0x4C,
+	 0x7C, 0x44, 0x29, 0x40, 0x80, 0x2B, 0x67, 0x44, 0x60, 0x4C, 0x40, 0xE1, 0x01, 0x60, 0x08, 0xE1,
+	 0x84, 0xFF, 0xC1, 0x60, 0x6B, 0x64, 0x40, 0x42, 0x82, 0xFF, 0x3C, 0x44, 0x60, 0x46, 0x40, 0x42,
+	 0x13, 0x64, 0x3A, 0xDB, 0x10, 0x60, 0x00, 0x65, 0x3C, 0x46, 0x2A, 0xF2, 0x15, 0x60, 0xBE, 0xF1,
+	 0xA4, 0x84, 0xC4, 0xBC, 0x40, 0x48, 0x64, 0x44, 0x04, 0x26, 0x09, 0x00, 0x02, 0x26, 0x0A, 0x00,
+	 0x01, 0x26, 0x0B, 0x00, 0x08, 0x2A, 0x03, 0x00, 0x0B, 0x63, 0x6E, 0x64, 0x08, 0x00, 0x15, 0x63,
+	 0x37, 0x64, 0x05, 0x00, 0x38, 0x63, 0x14, 0x64, 0x02, 0x00, 0x70, 0x63, 0x0A, 0x64, 0x43, 0x4D,
+	 0x40, 0x45, 0x00, 0xE1, 0xF0, 0xFE, 0x00, 0x60, 0x1E, 0x64, 0x1B, 0xF0, 0x11, 0xF0, 0xC0, 0x84,
+	 0xC0, 0x84, 0x60, 0x43, 0x28, 0x44, 0xA1, 0xFF, 0x12, 0x74, 0x80, 0x4E, 0x12, 0x74, 0x83, 0x4C,
+	 0x9A, 0xFF, 0x12, 0x74, 0x5C, 0x62, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4,
+	 0x12, 0x74, 0xA1, 0xFF, 0x98, 0xFF, 0xB1, 0x60, 0x58, 0x4F, 0x00, 0x78, 0xFF, 0xFF, 0x01, 0x60,
+	 0x18, 0xE1, 0x78, 0x44, 0x03, 0xA4, 0x35, 0xFB, 0xB1, 0x60, 0x43, 0x78, 0xFF, 0xFF, 0xC4, 0xE2,
+	 0x08, 0x64, 0x3A, 0xDB, 0xA5, 0x60, 0x1C, 0x78, 0xFF, 0xFF, 0x24, 0x40, 0x01, 0x2A, 0x0E, 0x00,
+	 0x1D, 0xFF, 0x26, 0x44, 0x02, 0xBC, 0x40, 0x46, 0x27, 0x44, 0x07, 0x22, 0x05, 0x00, 0xF8, 0xB4,
+	 0x40, 0x47, 0x06, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0x30, 0xF1, 0x52, 0x00, 0xFC, 0xB3, 0x32, 0x40,
+	 0x01, 0x2A, 0x06, 0x00, 0x0A, 0xBB, 0x0F, 0xFC, 0xCB, 0xFE, 0xA4, 0x60, 0x7C, 0x78, 0xFF, 0xFF,
+	 0x24, 0x44, 0x04, 0x26, 0x02, 0x00, 0x0F, 0xFC, 0x05, 0xFF, 0x30, 0xF1, 0x27, 0x44, 0x05, 0x22,
+	 0x2C, 0x00, 0xFA, 0xB4, 0x40, 0x47, 0x24, 0x44, 0x10, 0x2A, 0x23, 0x00, 0x28, 0x40, 0xD4, 0x3A,
+	 0x20, 0x00, 0x31, 0x40, 0x08, 0x26, 0x00, 0x7C, 0x2B, 0x44, 0xD0, 0x80, 0x70, 0x45, 0x02, 0x28,
+	 0x64, 0x44, 0xC4, 0x84, 0xFF, 0xFF, 0x04, 0x24, 0x00, 0xB4, 0x60, 0x50, 0x08, 0x28, 0x01, 0x00,
+	 0x20, 0x29, 0x6D, 0xE2, 0x1D, 0xF0, 0xC0, 0x64, 0xC0, 0x84, 0x0A, 0x60, 0x7B, 0xF1, 0xE8, 0x84,
+	 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xC0, 0x84, 0xA2, 0xDB, 0xA5, 0x60, 0xCD, 0x78,
+	 0xFF, 0xFF, 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0x07, 0x00, 0x02, 0x2A, 0x05, 0x00, 0xFD, 0xB4,
+	 0x40, 0x47, 0x06, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0x05, 0x64, 0x3A, 0xDB, 0x28, 0x44, 0xA4, 0x3A,
+	 0x07, 0x00, 0x01, 0x60, 0x02, 0x7C, 0x25, 0x44, 0x0A, 0x3A, 0x02, 0x00, 0x01, 0x60, 0x3A, 0x7C,
+	 0x31, 0x40, 0x08, 0x26, 0x00, 0x7C, 0x2B, 0x44, 0xD0, 0x80, 0x70, 0x45, 0x02, 0x28, 0x64, 0x44,
+	 0xC4, 0x84, 0xFF, 0xFF, 0x04, 0x24, 0x00, 0xB4, 0x28, 0x40, 0xE4, 0x36, 0x00, 0xB4, 0x60, 0x50,
+	 0x08, 0x28, 0x01, 0x00, 0x20, 0x29, 0x6D, 0xE2, 0xA4, 0x60, 0x6F, 0x78, 0xFF, 0xFF, 0x27, 0x44,
+	 0x05, 0x22, 0x09, 0x00, 0xBA, 0xB4, 0x40, 0x47, 0x3C, 0x46, 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE,
+	 0xA4, 0x60, 0x7C, 0x78, 0xFF, 0xFF, 0x27, 0x44, 0x02, 0x2A, 0x06, 0x00, 0xFD, 0xB4, 0x40, 0x47,
+	 0x06, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0xF4, 0x01, 0xF3, 0x0A, 0x7C, 0x50, 0x6D, 0xE2, 0xF0, 0x01,
+	 0x72, 0x45, 0xDC, 0x84, 0x94, 0xFB, 0x11, 0x64, 0x3A, 0xDB, 0x95, 0xF3, 0x06, 0x04, 0xDC, 0x84,
+	 0x95, 0xFB, 0x96, 0xF3, 0x02, 0x04, 0xDC, 0x84, 0x96, 0xFB, 0xA4, 0x60, 0x87, 0x78, 0xFF, 0xFF,
+	 0x00, 0x61, 0x12, 0x64, 0x3A, 0xDB, 0x18, 0x60, 0xEE, 0x63, 0xBD, 0xD3, 0x72, 0x45, 0x44, 0x8A,
+	 0x02, 0x28, 0x03, 0x00, 0xE4, 0xE2, 0xDD, 0x81, 0x04, 0x00, 0x02, 0x28, 0x02, 0x00, 0xE4, 0xE2,
+	 0xDD, 0x81, 0xBD, 0xD3, 0x94, 0xF1, 0x61, 0x45, 0xC0, 0x84, 0x00, 0x61, 0x02, 0x24, 0x01, 0xB9,
+	 0xC4, 0x84, 0x60, 0x55, 0x2A, 0x52, 0xE4, 0xE2, 0x94, 0xFB, 0x02, 0x24, 0x01, 0xB9, 0xBD, 0xD3,
+	 0x95, 0xF1, 0x61, 0x45, 0xC0, 0x84, 0x00, 0x61, 0x02, 0x24, 0x01, 0xB9, 0xC4, 0x84, 0x95, 0xFB,
+	 0x02, 0x24, 0x01, 0xB9, 0xBD, 0xD3, 0x96, 0xF1, 0x61, 0x45, 0xC0, 0x84, 0xC4, 0x84, 0x96, 0xFB,
+	 0xA5, 0x60, 0x71, 0x78, 0xFF, 0xFF, 0xAC, 0x01, 0x47, 0xFF, 0x44, 0xFF, 0xC8, 0x74, 0xCD, 0xE2,
+	 0xAA, 0x60, 0xFE, 0x78, 0x00, 0x61, 0xA4, 0x60, 0x7C, 0x78, 0xFF, 0xFF, 0x5C, 0x44, 0x26, 0x44,
+	 0x02, 0x26, 0x0C, 0x00, 0x3E, 0x46, 0x09, 0xF2, 0x1E, 0x41, 0x03, 0x1B, 0xAC, 0x60, 0x14, 0x78,
+	 0xFF, 0xFF, 0x40, 0x5E, 0xFD, 0xFB, 0x21, 0x44, 0x02, 0x64, 0x40, 0x46, 0x41, 0x5D, 0x21, 0x46,
+	 0x00, 0x64, 0x31, 0xFA, 0x00, 0xF2, 0x46, 0x45, 0x87, 0xFC, 0xAC, 0xE2, 0x01, 0x64, 0x33, 0xFB,
+	 0x32, 0x40, 0x01, 0x2A, 0x21, 0x00, 0x19, 0xF3, 0x01, 0x60, 0x1E, 0xE1, 0x1D, 0x18, 0x80, 0x64,
+	 0x40, 0x49, 0x00, 0xE1, 0x19, 0xFF, 0x08, 0x64, 0x2A, 0xFA, 0x5A, 0xDA, 0x2C, 0xFA, 0x5A, 0xDA,
+	 0x5A, 0xDA, 0xD2, 0xF3, 0xFF, 0xFF, 0x02, 0xBC, 0xD2, 0xFB, 0x72, 0x44, 0x24, 0xFA, 0x94, 0xF3,
+	 0x25, 0xFA, 0xA1, 0xFF, 0xFF, 0xFF, 0xB6, 0xFF, 0xB7, 0xFF, 0xB4, 0xFF, 0xC8, 0x60, 0x09, 0x7D,
+	 0x7C, 0x4B, 0xA4, 0x60, 0x7C, 0x78, 0xFF, 0xFF, 0x01, 0xE1, 0x01, 0x60, 0x1A, 0xE1, 0x3F, 0x60,
+	 0xCF, 0x65, 0x29, 0x44, 0x24, 0x89, 0x2E, 0x44, 0x00, 0x36, 0x41, 0x00, 0x01, 0x3A, 0xC9, 0x00,
+	 0x88, 0xFF, 0x40, 0x67, 0x29, 0x45, 0x34, 0x89, 0x04, 0x64, 0x89, 0xFF, 0x60, 0x54, 0x88, 0xFF,
+	 0xA1, 0xFF, 0x6C, 0x45, 0x65, 0x44, 0x0F, 0xB4, 0x40, 0x45, 0x1C, 0xFA, 0x65, 0x44, 0x29, 0x41,
+	 0xF9, 0x81, 0x52, 0x4A, 0x71, 0x89, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x83, 0x1D, 0xFC,
+	 0x1B, 0xFC, 0x98, 0xF1, 0xFC, 0xA3, 0xD3, 0x80, 0x43, 0x43, 0x03, 0x04, 0xAC, 0x60, 0x0A, 0x78,
+	 0xFF, 0xFF, 0x09, 0x7C, 0xD3, 0x80, 0x9A, 0xFF, 0x03, 0x07, 0xAC, 0x60, 0x0A, 0x78, 0xFF, 0xFF,
+	 0x25, 0x44, 0x01, 0x26, 0x0F, 0xAC, 0x1F, 0x60, 0x50, 0x65, 0x44, 0xD3, 0x12, 0x65, 0x45, 0x46,
+	 0x60, 0x47, 0x40, 0x7F, 0x27, 0xFA, 0x8F, 0xFC, 0x18, 0x61, 0xCB, 0xF1, 0xA1, 0xFF, 0x6C, 0x44,
+	 0xDC, 0x80, 0xFF, 0xFF, 0x21, 0x03, 0x50, 0xFE, 0xAC, 0x60, 0x20, 0x78, 0xFF, 0xFF, 0xC8, 0x60,
+	 0x0B, 0x7D, 0x08, 0x60, 0x00, 0x6B, 0xB5, 0xFF, 0xB7, 0xFF, 0xB4, 0xFF, 0xAA, 0x74, 0xCD, 0xE2,
+	 0x02, 0x64, 0x89, 0xFF, 0x60, 0x54, 0x88, 0xFF, 0x01, 0x60, 0x08, 0xE1, 0x05, 0xE1, 0xA1, 0xFF,
+	 0xFF, 0xFF, 0x04, 0x25, 0x76, 0x00, 0x6C, 0x44, 0x0A, 0x36, 0x07, 0x00, 0x14, 0x36, 0x05, 0x00,
+	 0x37, 0x36, 0x03, 0x00, 0x6E, 0x36, 0x01, 0x00, 0x6C, 0x00, 0x40, 0x45, 0x32, 0x74, 0xA1, 0xFF,
+	 0x1C, 0xFA, 0x40, 0x4E, 0x8C, 0x44, 0x60, 0x43, 0x1D, 0xFA, 0x01, 0xE1, 0x20, 0x64, 0x3A, 0xDB,
+	 0x2E, 0x44, 0x14, 0x36, 0x12, 0x00, 0x0A, 0x36, 0x0F, 0x00, 0x63, 0x45, 0xE3, 0x83, 0xE3, 0x83,
+	 0xC7, 0x83, 0xE3, 0x83, 0xC7, 0x83, 0xFF, 0xFF, 0x37, 0x36, 0x05, 0x00, 0x6E, 0x36, 0x04, 0x00,
+	 0xAC, 0x60, 0x1E, 0x78, 0xFF, 0xFF, 0xEB, 0x83, 0xEB, 0x83, 0xEB, 0x83, 0xEB, 0x83, 0xFF, 0xFF,
+	 0x80, 0x27, 0xCF, 0x83, 0x1B, 0xFC, 0x01, 0x64, 0x4F, 0xFB, 0xA1, 0xFF, 0x29, 0x41, 0xF9, 0x81,
+	 0x52, 0x4A, 0x71, 0x89, 0x2E, 0x44, 0x27, 0xFA, 0x98, 0xF1, 0xFC, 0xA3, 0xD3, 0x80, 0x43, 0x43,
+	 0x03, 0x04, 0xAC, 0x60, 0x0A, 0x78, 0xFF, 0xFF, 0x9A, 0xFF, 0x54, 0x63, 0x12, 0x64, 0x40, 0x46,
+	 0x8F, 0xFC, 0x18, 0x61, 0xCB, 0xF1, 0x50, 0xFE, 0x6C, 0x40, 0x9E, 0x15, 0x01, 0x60, 0x08, 0xE1,
+	 0x80, 0xE1, 0x00, 0x64, 0x33, 0xFB, 0x01, 0x60, 0x18, 0xE1, 0x01, 0x11, 0x0F, 0x00, 0x29, 0x44,
+	 0x20, 0xBC, 0x40, 0x49, 0x01, 0x64, 0x33, 0xFB, 0xB6, 0xFF, 0x00, 0xE1, 0x01, 0x60, 0x1A, 0xE1,
+	 0xA1, 0xFF, 0xFF, 0xFF, 0x6C, 0x40, 0xFC, 0x11, 0x01, 0x60, 0x18, 0xE1, 0xB5, 0xFF, 0xB6, 0xFF,
+	 0xB7, 0xFF, 0xB4, 0xFF, 0xC8, 0x60, 0x09, 0x7D, 0x7C, 0x4B, 0x35, 0xE1, 0xAC, 0xE2, 0xAA, 0x60,
+	 0x97, 0x78, 0xFF, 0xFF, 0x13, 0x60, 0x02, 0xF3, 0xFF, 0xFF, 0xDC, 0x84, 0x00, 0x36, 0x00, 0x3B,
+	 0xA2, 0xDB, 0x21, 0x64, 0x3A, 0xDB, 0xD2, 0x01, 0x25, 0x60, 0xF2, 0x64, 0xE5, 0x60, 0x78, 0x41,
+	 0xC7, 0x78, 0x97, 0xF1, 0x2A, 0x64, 0x3A, 0xDB, 0x5C, 0x41, 0xC8, 0x01, 0x29, 0x64, 0x3A, 0xDB,
+	 0x88, 0x60, 0x85, 0x71, 0x8D, 0xE2, 0xA2, 0xFC, 0x32, 0x40, 0x01, 0x2A, 0xA8, 0x00, 0x01, 0x60,
+	 0x1A, 0xE1, 0x23, 0x43, 0xA1, 0xFF, 0xEC, 0x44, 0x2A, 0xFA, 0x40, 0x48, 0xA1, 0xFF, 0x7A, 0xDC,
+	 0x7E, 0x36, 0x04, 0xA2, 0xFC, 0x1C, 0x03, 0x1D, 0x00, 0x64, 0x3F, 0xFA, 0x2E, 0x00, 0x03, 0x2B,
+	 0x04, 0x00, 0xA1, 0xFF, 0x7A, 0xDC, 0x7A, 0xDC, 0x7A, 0xDC, 0x8F, 0xB0, 0x88, 0x3A, 0x03, 0x00,
+	 0x70, 0x62, 0xA1, 0xFF, 0x7A, 0xDC, 0x28, 0x40, 0x40, 0x2B, 0x06, 0x00, 0x72, 0x62, 0xA1, 0xFF,
+	 0x7A, 0xDC, 0x7A, 0xDC, 0x7A, 0xDC, 0x7A, 0xDC, 0x3F, 0xFC, 0x00, 0xF4, 0x10, 0x62, 0x6E, 0x61,
+	 0xA1, 0xFF, 0x05, 0x1D, 0x12, 0x1E, 0x0C, 0x00, 0x00, 0xF4, 0x7C, 0x61, 0x02, 0x62, 0x7A, 0xDC,
+	 0x63, 0x40, 0xFD, 0x1C, 0xF9, 0x1D, 0xFF, 0xB1, 0x08, 0x1E, 0x02, 0x02, 0x00, 0xF4, 0x02, 0x62,
+	 0xB6, 0xFF, 0xB7, 0xFF, 0xA1, 0xFF, 0x6C, 0x44, 0x5A, 0xDA, 0x98, 0xFF, 0xA1, 0xFF, 0x6C, 0x40,
+	 0xA1, 0xFF, 0x47, 0xFF, 0x7C, 0x44, 0x33, 0xFB, 0x26, 0x44, 0xFD, 0xB4, 0x84, 0xBC, 0x01, 0x15,
+	 0x7F, 0xB4, 0x40, 0x46, 0x6C, 0x40, 0xB6, 0xFF, 0xB7, 0xFF, 0xA1, 0xFF, 0x6C, 0x45, 0xA1, 0xFF,
+	 0x7F, 0x60, 0x7F, 0x7C, 0x6C, 0x44, 0xA0, 0x84, 0x15, 0xA7, 0x15, 0xA4, 0x21, 0x46, 0x26, 0xFA,
+	 0x29, 0x40, 0x40, 0x2B, 0x07, 0x00, 0xB6, 0xFF, 0x40, 0x60, 0x00, 0x65, 0xA1, 0xFF, 0x6C, 0x44,
+	 0x1A, 0xFA, 0x09, 0x00, 0x65, 0x44, 0x0F, 0xB4, 0x06, 0xA8, 0x80, 0x60, 0x00, 0x65, 0x08, 0x28,
+	 0x7C, 0x45, 0x29, 0x44, 0x34, 0x89, 0x27, 0xF0, 0x65, 0x44, 0x64, 0x5E, 0x27, 0xFA, 0x81, 0xE1,
+	 0x01, 0x60, 0x18, 0xE1, 0x01, 0x11, 0x0F, 0x00, 0x29, 0x44, 0x20, 0xBC, 0x40, 0x49, 0x01, 0x64,
+	 0x33, 0xFB, 0xB6, 0xFF, 0x00, 0xE1, 0x01, 0x60, 0x1A, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x6C, 0x40,
+	 0xFC, 0x11, 0x01, 0x60, 0x18, 0xE1, 0x21, 0x46, 0xB5, 0xFF, 0xBC, 0xFF, 0x47, 0xFF, 0xB6, 0xFF,
+	 0xB7, 0xFF, 0xB4, 0xFF, 0xC8, 0x60, 0x09, 0x7D, 0x7C, 0x4B, 0x26, 0x43, 0x2A, 0x44, 0x72, 0x45,
+	 0x24, 0xFA, 0x94, 0xF3, 0x06, 0x04, 0xE4, 0xE2, 0xDC, 0x9C, 0x29, 0x40, 0x01, 0x26, 0x64, 0x44,
+	 0x94, 0xF9, 0x25, 0xFA, 0x95, 0xF3, 0x02, 0x04, 0xDC, 0x84, 0x95, 0xFB, 0x28, 0xFA, 0x96, 0xF3,
+	 0x02, 0x04, 0xDC, 0x84, 0x96, 0xFB, 0x29, 0xFA, 0xAA, 0x60, 0x1D, 0x78, 0xFF, 0xFF, 0xA1, 0xFF,
+	 0x12, 0x61, 0x8C, 0x44, 0xCC, 0xF0, 0x2A, 0xFA, 0x40, 0x48, 0x04, 0x26, 0x43, 0x00, 0xA1, 0xFF,
+	 0x8C, 0x44, 0x5A, 0xDA, 0x30, 0xFB, 0x6C, 0x44, 0x2C, 0xFA, 0xFF, 0xFF, 0x01, 0x26, 0x26, 0x00,
+	 0xD0, 0x80, 0xA1, 0xFF, 0x8C, 0x44, 0x6C, 0x5C, 0x00, 0xE1, 0xF2, 0xFE, 0x2D, 0xFA, 0xCD, 0xF3,
+	 0xD4, 0x80, 0xD0, 0x80, 0x2E, 0xF8, 0x24, 0x44, 0x16, 0x0C, 0x32, 0x40, 0x02, 0x2A, 0x07, 0x00,
+	 0x28, 0x42, 0x0C, 0xB2, 0x08, 0x3A, 0x03, 0x00, 0x10, 0xBC, 0x40, 0x44, 0x5C, 0x00, 0x04, 0x0A,
+	 0xA1, 0xFF, 0xAC, 0x60, 0x13, 0x78, 0xFF, 0xFF, 0x11, 0xBC, 0x40, 0x44, 0x28, 0x45, 0xBF, 0x60,
+	 0xFF, 0x64, 0x24, 0x88, 0x50, 0x00, 0x30, 0xBC, 0x40, 0x44, 0x4D, 0x00, 0x20, 0xB9, 0x5C, 0x8E,
+	 0xA1, 0xFF, 0x8C, 0x44, 0x2D, 0xFA, 0xDC, 0x9C, 0x6C, 0x44, 0x00, 0xE1, 0xF2, 0xFE, 0x2E, 0xFA,
+	 0x08, 0x28, 0x44, 0x4E, 0xDC, 0x84, 0x2E, 0x5C, 0xB0, 0x84, 0xEF, 0xB1, 0x08, 0x24, 0x40, 0xB9,
+	 0x41, 0x46, 0x39, 0x00, 0x23, 0x41, 0x13, 0x64, 0x51, 0x90, 0x56, 0x63, 0x03, 0x04, 0xAC, 0x60,
+	 0x0A, 0x78, 0xFF, 0xFF, 0x8C, 0x44, 0x04, 0x61, 0x2B, 0xFA, 0x50, 0xFE, 0x80, 0x27, 0x00, 0x64,
+	 0x30, 0xFB, 0x8C, 0x44, 0x2C, 0xFA, 0xD0, 0x80, 0x8C, 0x44, 0x2D, 0xFA, 0xD4, 0x80, 0x00, 0x65,
+	 0x8C, 0x44, 0xCD, 0xF1, 0x2E, 0xFA, 0xD0, 0x80, 0x28, 0x44, 0x03, 0x0C, 0xA0, 0x2A, 0x0A, 0x00,
+	 0x11, 0x00, 0x10, 0x65, 0x60, 0x40, 0xC4, 0x36, 0x04, 0x00, 0xD4, 0x3A, 0x08, 0x00, 0x27, 0x40,
+	 0x40, 0x26, 0x30, 0x65, 0x00, 0x64, 0x3F, 0xFA, 0x46, 0x4E, 0x35, 0x84, 0x66, 0x00, 0x40, 0x26,
+	 0xF9, 0x01, 0x30, 0x65, 0x7A, 0xDC, 0x7A, 0xDC, 0x7A, 0xDC, 0x04, 0x61, 0xF3, 0x01, 0xA1, 0xFF,
+	 0xAB, 0x60, 0xE6, 0x78, 0xFF, 0xFF, 0xFF, 0x60, 0xFE, 0x65, 0x23, 0x43, 0xE8, 0xA3, 0x80, 0x27,
+	 0xF6, 0x01, 0x20, 0xE6, 0x08, 0x60, 0x00, 0xEB, 0x28, 0x44, 0x03, 0x2B, 0x05, 0x00, 0x6A, 0x62,
+	 0x7A, 0xDC, 0x7A, 0xDC, 0x7A, 0xDC, 0x28, 0x44, 0x8F, 0xB0, 0x88, 0x3A, 0x03, 0x00, 0x70, 0x62,
+	 0x7A, 0xDC, 0x28, 0x44, 0x40, 0x2B, 0x0D, 0x00, 0x72, 0x62, 0x7A, 0xDC, 0xA1, 0xFF, 0x6C, 0x5C,
+	 0x5A, 0xD8, 0xE4, 0x40, 0x20, 0x2B, 0x03, 0x00, 0x7A, 0xDC, 0x7A, 0xDC, 0xF8, 0xA3, 0x25, 0xFF,
+	 0xB0, 0xFF, 0x3F, 0xFC, 0x00, 0xF4, 0x10, 0x62, 0x10, 0x61, 0x57, 0x90, 0x6C, 0x61, 0xA1, 0xFF,
+	 0x09, 0x07, 0x02, 0x1D, 0x2A, 0x1E, 0x21, 0x00, 0xCB, 0x83, 0x7A, 0xDC, 0xFE, 0x1C, 0xD9, 0x81,
+	 0x24, 0x1E, 0x1B, 0x00, 0xCB, 0x83, 0x0E, 0xA3, 0xA7, 0x84, 0xF2, 0xA3, 0x7A, 0xDC, 0xFE, 0x1C,
+	 0x05, 0x1D, 0x01, 0x60, 0x18, 0xE1, 0x7C, 0xA8, 0xD9, 0x81, 0x0A, 0x02, 0x00, 0xF4, 0x02, 0x62,
+	 0xA7, 0x84, 0x7A, 0x61, 0x7A, 0xDC, 0xFE, 0x1C, 0xF9, 0x1D, 0x7C, 0xA8, 0xD9, 0x81, 0xF6, 0x03,
+	 0xFF, 0xB1, 0x0B, 0x1E, 0x02, 0x02, 0x00, 0xF4, 0x02, 0x62, 0xA1, 0xFF, 0xFF, 0xFF, 0xB6, 0xFF,
+	 0xB7, 0xFF, 0x6C, 0x44, 0x5A, 0xDA, 0xCD, 0x81, 0x64, 0x40, 0x46, 0x45, 0x28, 0x44, 0x40, 0x2B,
+	 0x0E, 0x00, 0x64, 0x40, 0x20, 0x2B, 0x0B, 0x00, 0x01, 0xA2, 0x62, 0x44, 0x46, 0x45, 0x21, 0x46,
+	 0x00, 0xF4, 0x02, 0x62, 0x9A, 0xFF, 0x7A, 0xDC, 0x7A, 0xDC, 0x7A, 0xDC, 0x7A, 0xDC, 0x98, 0xFF,
+	 0x00, 0xE6, 0x01, 0xF2, 0x61, 0x45, 0xD4, 0x9E, 0x21, 0x46, 0x16, 0xFA, 0x25, 0x44, 0x06, 0xFA,
+	 0xA1, 0xFF, 0x8C, 0x44, 0xA1, 0xFF, 0x47, 0xFF, 0x50, 0x4B, 0x67, 0x50, 0x69, 0xE2, 0x25, 0x46,
+	 0x01, 0xF2, 0x61, 0x45, 0xD4, 0x9E, 0x21, 0x46, 0x16, 0xFA, 0x25, 0x45, 0x86, 0xF8, 0xFF, 0xFF,
+	 0x6A, 0x44, 0x40, 0x2B, 0x03, 0x15, 0xAF, 0x60, 0x10, 0x78, 0xFF, 0xFF, 0x29, 0x40, 0x10, 0x26,
+	 0x04, 0x00, 0x04, 0x74, 0xCD, 0xE2, 0xA1, 0xFF, 0xFF, 0xFF, 0x6C, 0x44, 0xB6, 0xFF, 0xB7, 0xFF,
+	 0xC4, 0xE2, 0x01, 0x60, 0x18, 0xE1, 0x05, 0x76, 0xAD, 0xE2, 0x41, 0xE1, 0xA1, 0xFF, 0x6C, 0x45,
+	 0xA1, 0xFF, 0x65, 0x41, 0x7F, 0x60, 0x7F, 0x7C, 0x6C, 0x44, 0xA0, 0x84, 0x15, 0xA7, 0x15, 0xA4,
+	 0x21, 0x46, 0x26, 0xFA, 0x22, 0x46, 0x10, 0xFA, 0x21, 0x46, 0x29, 0x40, 0x40, 0x2B, 0x07, 0x00,
+	 0xB6, 0xFF, 0xA1, 0xFF, 0x40, 0x60, 0x00, 0x65, 0x6C, 0x44, 0x1A, 0xFA, 0x09, 0x00, 0x65, 0x44,
+	 0x0F, 0xB4, 0x06, 0xA8, 0x80, 0x60, 0x00, 0x65, 0x08, 0x28, 0x7C, 0x45, 0x29, 0x44, 0x34, 0x89,
+	 0x27, 0xF0, 0x65, 0x47, 0x1F, 0xB1, 0x34, 0x97, 0x64, 0x5E, 0x07, 0x60, 0xF5, 0xF1, 0x29, 0x40,
+	 0x40, 0x2B, 0x04, 0x00, 0x64, 0x40, 0x02, 0x26, 0x10, 0x60, 0x00, 0xBC, 0x27, 0xFA, 0x01, 0x60,
+	 0x18, 0xE1, 0x00, 0x64, 0x33, 0xFB, 0xA8, 0xE2, 0x05, 0xE1, 0x28, 0x40, 0x03, 0x26, 0xCE, 0x00,
+	 0x31, 0x40, 0x20, 0x2A, 0x03, 0x00, 0x28, 0x40, 0x50, 0x3A, 0xC8, 0x00, 0x24, 0x44, 0x20, 0x2A,
+	 0xC5, 0x00, 0x2B, 0x44, 0xAC, 0x80, 0x28, 0x40, 0xB4, 0x3A, 0x03, 0x00, 0x02, 0x03, 0x30, 0xFB,
+	 0xBD, 0x00, 0x28, 0x44, 0xBF, 0x60, 0xFF, 0x65, 0xA4, 0x84, 0x40, 0x48, 0x2B, 0x50, 0xA1, 0xFF,
+	 0xFF, 0xFF, 0x01, 0x60, 0x08, 0xE1, 0x1C, 0xF2, 0xC4, 0xE2, 0x40, 0x45, 0x28, 0x40, 0xC4, 0x36,
+	 0x9D, 0x00, 0x29, 0x40, 0x40, 0x2B, 0x49, 0x00, 0x2B, 0x60, 0xBE, 0x63, 0x60, 0x40, 0x0B, 0x36,
+	 0x20, 0x00, 0x0F, 0x36, 0x1B, 0x00, 0x0A, 0x36, 0x16, 0x00, 0x0E, 0x36, 0x11, 0x00, 0x09, 0x36,
+	 0x0C, 0x00, 0x0D, 0x36, 0x07, 0x00, 0x08, 0x36, 0x02, 0x00, 0xA3, 0xD3, 0x15, 0x00, 0x02, 0xA3,
+	 0xA3, 0xD3, 0x12, 0x00, 0x04, 0xA3, 0xA3, 0xD3, 0x0F, 0x00, 0x06, 0xA3, 0xA3, 0xD3, 0x0C, 0x00,
+	 0x08, 0xA3, 0xA3, 0xD3, 0x09, 0x00, 0x0A, 0xA3, 0xA3, 0xD3, 0x06, 0x00, 0x0C, 0xA3, 0xA3, 0xD3,
+	 0x03, 0x00, 0x0E, 0xA3, 0xA3, 0xD3, 0xFF, 0xFF, 0x25, 0x60, 0x82, 0x63, 0x60, 0x40, 0x0C, 0x36,
+	 0x19, 0x00, 0x08, 0x36, 0x15, 0x00, 0x0D, 0x36, 0x11, 0x00, 0x09, 0x36, 0x0D, 0x00, 0x0E, 0x36,
+	 0x09, 0x00, 0x0A, 0x36, 0x05, 0x00, 0x0F, 0x36, 0x01, 0x00, 0x3A, 0x00, 0x02, 0xA3, 0x38, 0x00,
+	 0x04, 0xA3, 0x36, 0x00, 0x06, 0xA3, 0x34, 0x00, 0x08, 0xA3, 0x32, 0x00, 0x0A, 0xA3, 0x30, 0x00,
+	 0x0C, 0xA3, 0x2E, 0x00, 0x0E, 0xA3, 0x2C, 0x00, 0x2B, 0x00, 0x2B, 0x60, 0xCE, 0x63, 0x25, 0x44,
+	 0x0A, 0x36, 0x0C, 0x00, 0x14, 0x36, 0x07, 0x00, 0x37, 0x36, 0x02, 0x00, 0xA3, 0xD3, 0x09, 0x00,
+	 0x02, 0xA3, 0xA3, 0xD3, 0x06, 0x00, 0x04, 0xA3, 0xA3, 0xD3, 0x03, 0x00, 0x06, 0xA3, 0xA3, 0xD3,
+	 0xFF, 0xFF, 0x40, 0x45, 0x0A, 0x36, 0x0D, 0x00, 0x14, 0x36, 0x38, 0x64, 0x37, 0x3A, 0x03, 0x00,
+	 0x04, 0x7F, 0x40, 0x45, 0x15, 0x64, 0x6E, 0x3A, 0x09, 0x00, 0x84, 0x7F, 0x40, 0x45, 0x0B, 0x64,
+	 0x05, 0x00, 0x29, 0x44, 0x7F, 0x60, 0xFF, 0xB4, 0x40, 0x49, 0x70, 0x64, 0x40, 0x4D, 0x02, 0x00,
+	 0x40, 0x45, 0x0A, 0x00, 0x25, 0x60, 0x7A, 0x63, 0x0A, 0x36, 0x06, 0x00, 0x14, 0x36, 0x02, 0xA3,
+	 0x37, 0x36, 0x04, 0xA3, 0x6E, 0x36, 0x06, 0xA3, 0x28, 0xA3, 0xA3, 0xD1, 0xD8, 0xA3, 0x15, 0x60,
+	 0xD8, 0xF9, 0x39, 0xF1, 0xA3, 0xD1, 0x64, 0x41, 0x64, 0x5E, 0x60, 0x45, 0x64, 0x47, 0x1F, 0xB4,
+	 0x54, 0x94, 0xE0, 0xA0, 0x02, 0x0D, 0x00, 0x64, 0x02, 0x00, 0x01, 0x04, 0x1F, 0x64, 0x60, 0x47,
+	 0xB4, 0x85, 0x29, 0x44, 0xC0, 0x60, 0x00, 0xB4, 0xB4, 0x84, 0x1F, 0xFA, 0xB5, 0xFF, 0xA1, 0xFF,
+	 0xAD, 0xF3, 0xC4, 0xE2, 0x89, 0xFF, 0x60, 0x54, 0x88, 0xFF, 0xDC, 0x84, 0xE0, 0x94, 0xFF, 0x60,
+	 0xCF, 0x65, 0x29, 0x44, 0x24, 0x89, 0xA5, 0x60, 0xD6, 0x78, 0x04, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF,
+	 0xC4, 0xE2, 0xA1, 0xFF, 0xFF, 0x60, 0xCF, 0x65, 0x29, 0x44, 0x24, 0x89, 0xAD, 0xF3, 0xC4, 0xE2,
+	 0x89, 0xFF, 0x60, 0x54, 0x88, 0xFF, 0xDC, 0x84, 0xE0, 0x94, 0x26, 0x44, 0x84, 0xBC, 0x24, 0x40,
+	 0x0C, 0x22, 0xFD, 0xB4, 0x40, 0x46, 0x23, 0x64, 0x3A, 0xDB, 0xAC, 0x60, 0xAB, 0x78, 0xFF, 0xFF,
+	 0x27, 0x40, 0x26, 0x22, 0x05, 0x00, 0xF8, 0xB4, 0x40, 0x47, 0x06, 0x64, 0x31, 0xFB, 0xC0, 0xFE,
+	 0x29, 0x40, 0x10, 0x26, 0x02, 0x00, 0x04, 0x74, 0xCD, 0xE2, 0x01, 0x60, 0x18, 0xE1, 0x01, 0x60,
+	 0x18, 0xE1, 0x01, 0x11, 0x0F, 0x00, 0x29, 0x44, 0x20, 0xBC, 0x40, 0x49, 0x01, 0x64, 0x33, 0xFB,
+	 0xB6, 0xFF, 0x00, 0xE1, 0x01, 0x60, 0x1A, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x6C, 0x40, 0xFC, 0x11,
+	 0x01, 0x60, 0x18, 0xE1, 0xB5, 0xFF, 0x47, 0xFF, 0xB6, 0xFF, 0xB7, 0xFF, 0xB4, 0xFF, 0xC8, 0x60,
+	 0x09, 0x7D, 0x7C, 0x4B, 0x37, 0xF3, 0x2B, 0x45, 0xD4, 0x80, 0xFF, 0xFF, 0x02, 0x28, 0x65, 0x44,
+	 0x60, 0x50, 0xA0, 0x4C, 0x20, 0xBC, 0xFF, 0xB4, 0xA0, 0x51, 0x00, 0x60, 0x2E, 0x7C, 0x74, 0x44,
+	 0xC0, 0x94, 0x32, 0x40, 0x02, 0x2A, 0x19, 0x00, 0x28, 0x44, 0xA4, 0x36, 0x03, 0x00, 0x0C, 0xB4,
+	 0x04, 0x36, 0x13, 0x00, 0x26, 0x43, 0xFD, 0xB3, 0x04, 0xBB, 0x43, 0x46, 0x01, 0x2A, 0x03, 0x00,
+	 0x28, 0x47, 0x40, 0xBF, 0x40, 0x48, 0x0A, 0xBB, 0x0F, 0xFC, 0x50, 0x4B, 0x67, 0x50, 0x00, 0x64,
+	 0x30, 0xFB, 0x05, 0xFF, 0xAC, 0x60, 0xAB, 0x78, 0xFF, 0xFF, 0x24, 0x64, 0x3A, 0xDB, 0x28, 0x44,
+	 0x04, 0x2A, 0x03, 0x00, 0xA4, 0x60, 0x6F, 0x78, 0xFF, 0xFF, 0x1D, 0xFF, 0xA8, 0xE2, 0x26, 0x40,
+	 0x10, 0x2A, 0x06, 0x00, 0x25, 0x60, 0xF0, 0x64, 0xE5, 0x60, 0x78, 0x41, 0xC7, 0x78, 0x97, 0xF1,
+	 0xA4, 0x60, 0x6F, 0x78, 0xFF, 0xFF, 0x03, 0x0A, 0xA4, 0x60, 0x7C, 0x78, 0xFF, 0xFF, 0x01, 0x64,
+	 0x4F, 0xFB, 0xE1, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x81, 0x3E, 0x54, 0x62, 0x22, 0x46, 0xA2, 0xD0,
+	 0x16, 0x63, 0x7C, 0x41, 0x44, 0x48, 0x80, 0x36, 0x04, 0x61, 0x28, 0x40, 0x50, 0x36, 0x04, 0x61,
+	 0x41, 0x4E, 0x28, 0x44, 0xA4, 0x36, 0x0E, 0x63, 0x0A, 0x60, 0x7C, 0xF1, 0x2D, 0x44, 0xE8, 0x84,
+	 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xC0, 0x84, 0xA2, 0xDB, 0x9A, 0xFF, 0xA1, 0xFF,
+	 0x12, 0x74, 0xCD, 0xE2, 0x54, 0x62, 0xA2, 0xD2, 0xFF, 0xFF, 0x6A, 0x40, 0x80, 0x4E, 0x12, 0x74,
+	 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74,
+	 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0xFF, 0xFF, 0x01, 0x1D,
+	 0xB2, 0x00, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4,
+	 0x12, 0x74, 0x28, 0x40, 0x03, 0x2B, 0x06, 0x00, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74,
+	 0x7A, 0xD4, 0x12, 0x74, 0x70, 0x62, 0x28, 0x44, 0x8F, 0xB0, 0x88, 0x3A, 0x02, 0x00, 0x7A, 0xD4,
+	 0x12, 0x74, 0x28, 0x40, 0x40, 0x2B, 0x16, 0x00, 0x72, 0x62, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD2,
+	 0x12, 0x74, 0x80, 0x4C, 0x20, 0x2B, 0x05, 0x00, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4,
+	 0x12, 0x74, 0x22, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x10, 0x26, 0x04, 0x00, 0x26, 0x26, 0x4D, 0x00,
+	 0x26, 0x27, 0x4B, 0x00, 0x23, 0x43, 0xFF, 0xFF, 0x06, 0x1D, 0x2E, 0x1E, 0x00, 0x00, 0x03, 0xF0,
+	 0x04, 0xF4, 0x64, 0x42, 0x3D, 0x00, 0x2E, 0x40, 0x04, 0x2A, 0x27, 0x00, 0xA1, 0xFF, 0x02, 0xFE,
+	 0x10, 0x25, 0x42, 0xFE, 0x12, 0x74, 0x72, 0x45, 0x65, 0x4C, 0x94, 0xF3, 0x03, 0x04, 0xE4, 0xE2,
+	 0xDC, 0x84, 0x94, 0xFB, 0xA1, 0xFF, 0x12, 0x74, 0x80, 0x4C, 0x12, 0x74, 0x95, 0xF3, 0x02, 0x04,
+	 0xDC, 0x84, 0x95, 0xFB, 0x80, 0x4C, 0x12, 0x74, 0x96, 0xF3, 0x02, 0x04, 0xDC, 0x84, 0x96, 0xFB,
+	 0x80, 0x4C, 0x12, 0x74, 0x5C, 0x4E, 0xF8, 0xA3, 0x03, 0xF2, 0x9A, 0xF2, 0x04, 0xF4, 0xFF, 0xB1,
+	 0xF8, 0xA1, 0x06, 0xA4, 0x60, 0x42, 0x0A, 0x00, 0x4E, 0x00, 0x03, 0xF2, 0x9A, 0xF2, 0x04, 0xF4,
+	 0xC8, 0x82, 0xFF, 0xB1, 0x03, 0x00, 0x00, 0xF4, 0x81, 0xF2, 0xFF, 0xB1, 0x7A, 0xD4, 0x12, 0x74,
+	 0xFD, 0x1C, 0xF9, 0x1D, 0xFF, 0xB1, 0x1B, 0x1E, 0x02, 0x02, 0x00, 0xF4, 0xDA, 0x82, 0xDA, 0x82,
+	 0xA2, 0xD2, 0xA1, 0xFF, 0x09, 0x74, 0x60, 0x4D, 0x12, 0x00, 0x03, 0xF2, 0x9A, 0xF2, 0x04, 0xF4,
+	 0x23, 0x43, 0xA1, 0xFF, 0x12, 0x74, 0xA0, 0xD2, 0xFE, 0xA1, 0xCB, 0x83, 0x60, 0x4E, 0xAF, 0x83,
+	 0x03, 0x1D, 0x05, 0x03, 0x12, 0x74, 0xEB, 0x01, 0xA1, 0xFF, 0x12, 0x74, 0xDF, 0x01, 0x12, 0x74,
+	 0xDA, 0x83, 0x66, 0x44, 0x22, 0x46, 0x0C, 0xFA, 0x22, 0xF2, 0x0B, 0xFC, 0x28, 0x40, 0x40, 0x2B,
+	 0x1A, 0x00, 0x10, 0x26, 0x04, 0x00, 0x26, 0x26, 0x0F, 0x00, 0x26, 0x27, 0x0D, 0x00, 0x00, 0xF4,
+	 0x02, 0x62, 0xA1, 0xFF, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4,
+	 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x07, 0x00, 0xA1, 0xFF, 0x12, 0x74, 0x9C, 0x4E, 0x12, 0x74,
+	 0x9C, 0x4C, 0x12, 0x74, 0x00, 0x00, 0x88, 0xFF, 0xA1, 0xFF, 0xB1, 0x60, 0x58, 0x4F, 0x00, 0x78,
+	 0xFF, 0xFF, 0x01, 0x60, 0x18, 0xE1, 0x78, 0x44, 0x02, 0xA4, 0x35, 0xFB, 0xCC, 0x00, 0x29, 0x44,
+	 0xF7, 0xB4, 0x40, 0x49, 0x34, 0x64, 0x3A, 0xDB, 0x44, 0xE1, 0xA5, 0x60, 0xB2, 0x78, 0xFF, 0xFF,
+	 0x00, 0x6B, 0xBC, 0xFF, 0x15, 0xF3, 0xFF, 0xFF, 0xDC, 0x84, 0x15, 0xFB, 0x78, 0x5C, 0x07, 0x00,
+	 0x78, 0x5C, 0x2F, 0x00, 0x62, 0xFF, 0xFF, 0xFF, 0xA1, 0xFF, 0x98, 0xFF, 0x80, 0x3E, 0x80, 0x60,
+	 0x01, 0xE0, 0xD5, 0x60, 0x84, 0xE7, 0x82, 0xF3, 0x40, 0x60, 0x60, 0x40, 0x01, 0x23, 0x48, 0x60,
+	 0x5E, 0x65, 0x80, 0x60, 0x00, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x65, 0x4A, 0xFF, 0xFF,
+	 0x01, 0x16, 0xFE, 0x01, 0x00, 0x60, 0x00, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x80, 0x60,
+	 0x00, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x65, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01,
+	 0x00, 0x60, 0x01, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x95, 0x60, 0x84, 0xE7, 0x64, 0x58,
+	 0xFF, 0xFF, 0x80, 0x60, 0x01, 0xE0, 0xD5, 0x60, 0x84, 0xE7, 0x82, 0xF3, 0x7C, 0x45, 0x60, 0x40,
+	 0x01, 0x23, 0x02, 0x65, 0x8C, 0x60, 0x48, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x00, 0x60,
+	 0x00, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x00, 0x60, 0x7F, 0x6A, 0xFF, 0xFF, 0x01, 0x16,
+	 0xFE, 0x01, 0x84, 0x60, 0x04, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x48, 0x60, 0x08, 0x6A,
+	 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x65, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x84, 0x60,
+	 0x04, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x40, 0x60, 0x08, 0x6A, 0xFF, 0xFF, 0x01, 0x16,
+	 0xFE, 0x01, 0x65, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x8C, 0x60, 0x48, 0x6A, 0xFF, 0xFF,
+	 0x01, 0x16, 0xFE, 0x01, 0x00, 0x60, 0x00, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x00, 0x60,
+	 0x00, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x95, 0x60, 0x84, 0xE7, 0x64, 0x58, 0xFF, 0xFF,
+	 0x12, 0x74, 0x6A, 0x40, 0x87, 0x4F, 0x12, 0x74, 0x87, 0x4C, 0x12, 0x74, 0x29, 0x40, 0x40, 0x2B,
+	 0x08, 0x00, 0x0A, 0x64, 0x89, 0xFF, 0x60, 0x54, 0x88, 0xFF, 0x87, 0x4D, 0x12, 0x74, 0x87, 0x4D,
+	 0x09, 0x00, 0x03, 0x64, 0x89, 0xFF, 0x60, 0x54, 0x88, 0xFF, 0x87, 0x4F, 0x12, 0x74, 0x87, 0x4D,
+	 0x12, 0x74, 0x87, 0x4D, 0x7C, 0x44, 0x01, 0x08, 0x01, 0x00, 0x67, 0x44, 0x12, 0x74, 0x87, 0x4C,
+	 0x12, 0x74, 0x87, 0x4C, 0x12, 0x74, 0x87, 0x4C, 0x12, 0x74, 0x87, 0x4D, 0x12, 0x74, 0x87, 0x4D,
+	 0x12, 0x74, 0x87, 0x4D, 0x12, 0x74, 0x04, 0x21, 0x04, 0x00, 0xFF, 0x2A, 0x01, 0x00, 0x04, 0x00,
+	 0x03, 0x00, 0xFF, 0x2A, 0x0D, 0x00, 0x0C, 0x00, 0xBC, 0xFF, 0x61, 0xFF, 0x78, 0x5C, 0x57, 0x01,
+	 0x78, 0x5C, 0x7F, 0x01, 0xB6, 0xFF, 0xB7, 0xFF, 0xB4, 0xFF, 0xC8, 0x60, 0x09, 0x7D, 0x7C, 0x4B,
+	 0x6A, 0x44, 0x2F, 0x58, 0xFF, 0xFF, 0x04, 0x74, 0xC4, 0xE2, 0x04, 0xE1, 0x29, 0x40, 0x40, 0x2B,
+	 0x05, 0x00, 0xA1, 0xFF, 0xFF, 0xFF, 0xBC, 0xFF, 0x14, 0x74, 0x01, 0x00, 0x04, 0x74, 0xC4, 0xE2,
+	 0x04, 0xE1, 0xBC, 0xFF, 0xB5, 0xFF, 0x47, 0xFF, 0xB6, 0xFF, 0xB7, 0xFF, 0xB4, 0xFF, 0xC8, 0x60,
+	 0x09, 0x7D, 0x7C, 0x4B, 0x29, 0x40, 0x40, 0x27, 0x04, 0x00, 0xC2, 0x60, 0x58, 0x4F, 0xC8, 0x78,
+	 0xFF, 0xFF, 0xA1, 0xFF, 0x29, 0x40, 0x10, 0x26, 0x6D, 0x00, 0x80, 0x60, 0x01, 0xE0, 0xD5, 0x60,
+	 0x84, 0xE7, 0x82, 0xF3, 0x40, 0x60, 0x60, 0x40, 0x01, 0x23, 0x48, 0x60, 0x5E, 0x65, 0x80, 0x60,
+	 0x00, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x65, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01,
+	 0x00, 0x60, 0x00, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x80, 0x60, 0x00, 0x6A, 0xFF, 0xFF,
+	 0x01, 0x16, 0xFE, 0x01, 0x65, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x00, 0x60, 0x01, 0x6A,
+	 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x95, 0x60, 0x84, 0xE7, 0x80, 0x60, 0x01, 0xE0, 0xD5, 0x60,
+	 0x84, 0xE7, 0x82, 0xF3, 0x7C, 0x45, 0x60, 0x40, 0x01, 0x23, 0x02, 0x65, 0x8C, 0x60, 0x48, 0x6A,
+	 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x00, 0x60, 0x00, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01,
+	 0x00, 0x60, 0x7F, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x84, 0x60, 0x04, 0x6A, 0xFF, 0xFF,
+	 0x01, 0x16, 0xFE, 0x01, 0x48, 0x60, 0x08, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x65, 0x4A,
+	 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x84, 0x60, 0x04, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01,
+	 0x40, 0x60, 0x08, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x65, 0x4A, 0xFF, 0xFF, 0x01, 0x16,
+	 0xFE, 0x01, 0x8C, 0x60, 0x48, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x00, 0x60, 0x00, 0x6A,
+	 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x00, 0x60, 0x00, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01,
+	 0x95, 0x60, 0x84, 0xE7, 0x01, 0x60, 0x08, 0xE1, 0xFF, 0xFF, 0xC4, 0xE2, 0x29, 0x40, 0x40, 0x2B,
+	 0x04, 0x00, 0xC2, 0x60, 0x58, 0x4F, 0xC8, 0x78, 0xFF, 0xFF, 0xC2, 0x60, 0x58, 0x4F, 0xD0, 0x78,
+	 0xFF, 0xFF, 0xA1, 0xFF, 0xAD, 0xF3, 0xC4, 0xE2, 0x89, 0xFF, 0x60, 0x54, 0x88, 0xFF, 0xDC, 0x84,
+	 0xE0, 0x94, 0x35, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x08, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF,
+	 0x43, 0xFF, 0x01, 0x60, 0x00, 0xE1, 0x28, 0xF3, 0x47, 0xFF, 0x60, 0x40, 0x07, 0x37, 0x66, 0x00,
+	 0x05, 0x3B, 0x04, 0x00, 0xFF, 0x0A, 0x80, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x18, 0x60, 0x07, 0xF1,
+	 0xAD, 0x4F, 0x00, 0x7F, 0xFA, 0xB4, 0x64, 0x41, 0x64, 0xF1, 0x02, 0xB1, 0x04, 0x65, 0x02, 0x02,
+	 0x64, 0x40, 0x01, 0x2B, 0x01, 0x65, 0xB4, 0x84, 0xA0, 0x5D, 0x29, 0xF5, 0x2A, 0xF3, 0x47, 0xFF,
+	 0x3F, 0xF0, 0x01, 0x1B, 0x01, 0x64, 0x60, 0x56, 0xAD, 0xE2, 0xB5, 0xFF, 0x6C, 0x40, 0x40, 0xE1,
+	 0xA1, 0xFF, 0x00, 0xF4, 0x6E, 0x61, 0x12, 0x62, 0x64, 0x43, 0x01, 0xE1, 0x03, 0x64, 0xE2, 0xD0,
+	 0xC9, 0x81, 0x64, 0x4C, 0xCC, 0x84, 0xDA, 0x82, 0xFA, 0x02, 0x01, 0x60, 0x00, 0x6B, 0x9A, 0xFF,
+	 0xCA, 0x82, 0x03, 0x00, 0x00, 0xF4, 0x81, 0xF2, 0xFF, 0xFF, 0x7A, 0xD0, 0xA1, 0xFF, 0x64, 0x4C,
+	 0xFC, 0x1C, 0xF8, 0x1D, 0x00, 0xB9, 0x06, 0x1E, 0x02, 0x02, 0x00, 0xF4, 0xDA, 0x82, 0x5A, 0xD2,
+	 0xA1, 0xFF, 0x60, 0x4D, 0x3F, 0x40, 0x02, 0x2B, 0x10, 0x00, 0x28, 0xF3, 0xA5, 0x60, 0xC4, 0x65,
+	 0x60, 0x40, 0x0E, 0x3B, 0x0A, 0x00, 0xD2, 0xF3, 0xFF, 0xFF, 0x10, 0xBC, 0xD2, 0xFB, 0xAD, 0x4F,
+	 0x02, 0xBC, 0x00, 0x7F, 0xA0, 0x5D, 0x85, 0x4C, 0xFE, 0x01, 0xD2, 0xF3, 0xFF, 0xFF, 0x02, 0xBC,
+	 0xD2, 0xFB, 0xA1, 0xFF, 0x87, 0x4E, 0x87, 0x4C, 0x87, 0x4C, 0x87, 0x4C, 0x87, 0x4C, 0x67, 0x4C,
+	 0xFF, 0xFF, 0xBC, 0xFF, 0x00, 0xE1, 0xD5, 0xFE, 0xA1, 0xFF, 0xFF, 0xFF, 0x00, 0x64, 0x40, 0x46,
+	 0x60, 0x41, 0xB5, 0xFF, 0xB7, 0xFF, 0xB4, 0xFF, 0x29, 0xF5, 0x3F, 0xF0, 0x24, 0xF2, 0x44, 0x43,
+	 0x40, 0x4D, 0x00, 0xF4, 0xF3, 0x60, 0xA0, 0x65, 0x10, 0x62, 0x5A, 0xD2, 0xD9, 0x81, 0xD4, 0x80,
+	 0xFF, 0xFF, 0xFB, 0x02, 0x61, 0x45, 0x2D, 0x44, 0xD4, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84,
+	 0xFD, 0xA5, 0x48, 0x60, 0x00, 0x64, 0xC4, 0x9D, 0x0D, 0x60, 0x00, 0x6B, 0x2D, 0x44, 0xC0, 0x83,
+	 0xBB, 0xFF, 0x29, 0xF5, 0x01, 0xE1, 0x00, 0xF4, 0x6C, 0x61, 0x10, 0x62, 0x05, 0x00, 0x00, 0xF4,
+	 0x01, 0xF2, 0xFF, 0xFF, 0x60, 0x41, 0x04, 0x62, 0xA1, 0xFF, 0xFF, 0xFF, 0x01, 0x10, 0x1A, 0x00,
+	 0x26, 0x44, 0x01, 0x26, 0x0C, 0x00, 0x2D, 0x44, 0xC8, 0x84, 0x40, 0x4D, 0x02, 0x03, 0x6C, 0x45,
+	 0xF3, 0x01, 0x03, 0x15, 0x01, 0x64, 0x05, 0xFA, 0x15, 0x00, 0x6C, 0x45, 0xED, 0x01, 0x23, 0x44,
+	 0xC8, 0x84, 0x40, 0x43, 0x02, 0x03, 0x6C, 0x45, 0xE7, 0x01, 0x00, 0x64, 0x01, 0x15, 0x01, 0x64,
+	 0x6C, 0x45, 0x05, 0xFB, 0xE2, 0xD2, 0xDA, 0x82, 0xC9, 0x81, 0x60, 0x4C, 0xDD, 0x1C, 0xD7, 0x03,
+	 0xBC, 0xFF, 0xDA, 0x01, 0x00, 0xE1, 0xD5, 0xFE, 0xA1, 0xFF, 0xFF, 0xFF, 0x08, 0xE1, 0xA1, 0xFF,
+	 0x67, 0x4C, 0x43, 0xFF, 0xD2, 0xF3, 0xFF, 0xFF, 0x10, 0xBC, 0xD2, 0xFB, 0xAD, 0x4F, 0x02, 0xBC,
+	 0x00, 0x7F, 0xA0, 0x5D, 0x01, 0xE1, 0x01, 0x60, 0x69, 0x6B, 0xA5, 0x60, 0xC4, 0x64, 0x60, 0x4C,
+	 0xBB, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0x60, 0x4C, 0xA1, 0xFF, 0xFF, 0xFF, 0x60, 0x4C, 0xFC, 0x01,
+	 0x29, 0xF3, 0x2A, 0xF1, 0x07, 0xB5, 0x04, 0xE1, 0x65, 0x41, 0x64, 0x54, 0xCD, 0xE2, 0x95, 0x81,
+	 0xA1, 0x5D, 0xA1, 0xFF, 0xFF, 0xFF, 0xF9, 0x01, 0x10, 0x61, 0x7F, 0x60, 0xC0, 0x64, 0xA0, 0x80,
+	 0x7F, 0x67, 0x02, 0x63, 0x25, 0x02, 0x98, 0xFE, 0x19, 0x05, 0x0F, 0x60, 0x7F, 0xF5, 0x0E, 0xF2,
+	 0x15, 0x18, 0x02, 0x18, 0x09, 0xF4, 0xFB, 0x01, 0x23, 0x44, 0x00, 0xA8, 0x08, 0x7E, 0x0A, 0x02,
+	 0x66, 0x44, 0x11, 0xFB, 0x46, 0x43, 0x23, 0x47, 0x80, 0xBF, 0x3B, 0x42, 0x04, 0xA2, 0xA2, 0xDB,
+	 0x28, 0xB9, 0x10, 0x7E, 0x00, 0x7F, 0x0E, 0xFA, 0x00, 0x67, 0x0A, 0x00, 0x20, 0x44, 0xDC, 0x85,
+	 0x0F, 0xB4, 0xF7, 0xA0, 0x7F, 0x67, 0x07, 0x63, 0x03, 0x05, 0x45, 0x40, 0x00, 0x67, 0xD8, 0xFE,
+	 0xFF, 0x27, 0x05, 0xFD, 0x0A, 0x7E, 0x04, 0xFB, 0x61, 0x55, 0x48, 0x00, 0x28, 0xFB, 0x01, 0xF3,
+	 0x29, 0xFB, 0x44, 0x46, 0x40, 0x45, 0x10, 0x61, 0x7E, 0x60, 0xC0, 0x64, 0xA0, 0x80, 0x7F, 0x67,
+	 0x02, 0x63, 0x30, 0x02, 0xB5, 0x60, 0x58, 0x4F, 0x4B, 0x78, 0xFF, 0xFF, 0x7F, 0x67, 0x03, 0x63,
+	 0x29, 0x02, 0x26, 0x40, 0x01, 0x2B, 0x23, 0x00, 0x98, 0xFE, 0x18, 0x05, 0x0F, 0x60, 0x7F, 0xF5,
+	 0x0E, 0xF2, 0x14, 0x18, 0x02, 0x18, 0x09, 0xF4, 0xFB, 0x01, 0x23, 0x44, 0x00, 0xA8, 0x08, 0x7E,
+	 0x0A, 0x02, 0x66, 0x44, 0x11, 0xFB, 0x46, 0x43, 0x23, 0x47, 0x80, 0xBF, 0x3B, 0x42, 0x04, 0xA2,
+	 0xA2, 0xDB, 0x08, 0xB9, 0x10, 0x7E, 0x00, 0x7F, 0x0E, 0xFA, 0x09, 0x00, 0x20, 0x44, 0xDC, 0x85,
+	 0x0F, 0xB4, 0xF7, 0xA0, 0x7F, 0x67, 0x07, 0x63, 0x05, 0x05, 0x45, 0x40, 0xD8, 0xFE, 0x00, 0x67,
+	 0xD0, 0xFE, 0xD9, 0xFE, 0xFF, 0x27, 0x05, 0xFD, 0x0B, 0x7E, 0x04, 0xFB, 0x0A, 0x60, 0x7E, 0xF3,
+	 0xFF, 0xFF, 0x20, 0xB0, 0x80, 0xBC, 0x08, 0x28, 0xA2, 0xDB, 0x61, 0x55, 0x66, 0x00, 0x04, 0xB5,
+	 0x82, 0xB5, 0x25, 0x02, 0x04, 0x03, 0x20, 0x44, 0x7F, 0xB4, 0x40, 0x40, 0xA3, 0xD3, 0x99, 0xFE,
+	 0x04, 0x04, 0x02, 0xBC, 0xFE, 0xB4, 0xA3, 0xDB, 0x59, 0x00, 0xBC, 0xF3, 0x20, 0x40, 0x80, 0x26,
+	 0x55, 0x00, 0xA3, 0xD3, 0xFF, 0xA0, 0xF8, 0xB4, 0x02, 0x02, 0xA3, 0xDB, 0x1C, 0x00, 0x04, 0xBC,
+	 0xBF, 0xB4, 0xA3, 0xDB, 0x08, 0xB0, 0x01, 0x64, 0x08, 0x24, 0x02, 0x64, 0x28, 0xFB, 0x20, 0x44,
+	 0x80, 0xBC, 0x40, 0x40, 0xD0, 0xFE, 0x42, 0x00, 0xBF, 0xB4, 0xA3, 0xDB, 0x3F, 0x00, 0x40, 0xB0,
+	 0xFF, 0xFF, 0xFA, 0x02, 0xF8, 0xB4, 0xA3, 0xDB, 0x08, 0xB5, 0x07, 0x7C, 0x01, 0x02, 0xBC, 0xF9,
+	 0x20, 0x44, 0x7F, 0xB4, 0x40, 0x40, 0x14, 0x60, 0xFC, 0x63, 0xA3, 0xD3, 0xFF, 0xFF, 0x20, 0xB5,
+	 0x07, 0xB5, 0x08, 0x28, 0xC4, 0x02, 0x99, 0xFE, 0x29, 0x05, 0x20, 0x44, 0x80, 0x26, 0x26, 0x00,
+	 0x20, 0x2A, 0x03, 0x00, 0xDF, 0xB4, 0x40, 0x40, 0x6A, 0x00, 0x40, 0x2A, 0x1F, 0x00, 0xBF, 0xB4,
+	 0x40, 0x40, 0x09, 0x00, 0xA8, 0xFF, 0x20, 0x44, 0x99, 0xFE, 0x02, 0x05, 0x80, 0x2A, 0x03, 0x00,
+	 0x40, 0xBC, 0x40, 0x40, 0x13, 0x00, 0x00, 0xF1, 0x80, 0xBC, 0x40, 0x40, 0x64, 0x44, 0xE0, 0x84,
+	 0xE8, 0x84, 0x0A, 0x36, 0x29, 0x01, 0x0B, 0x36, 0x59, 0x01, 0x28, 0xFB, 0x01, 0xF1, 0x29, 0xF9,
+	 0x02, 0xF1, 0x2A, 0xF9, 0x03, 0xF1, 0x2B, 0xF9, 0xD0, 0xFE, 0xAE, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF,
+	 0x82, 0x3E, 0x75, 0x44, 0x02, 0xB0, 0x01, 0xB0, 0x4A, 0x02, 0xDC, 0x02, 0x04, 0xB0, 0x08, 0xB0,
+	 0x0B, 0x02, 0x20, 0x02, 0x40, 0x26, 0xA7, 0xFF, 0x8C, 0xFF, 0x75, 0x40, 0x80, 0x2B, 0x01, 0x00,
+	 0xAB, 0xFF, 0x75, 0x44, 0x8D, 0xFF, 0xEA, 0x01, 0x0A, 0xF3, 0xAA, 0xFF, 0x60, 0x40, 0x20, 0x2B,
+	 0x02, 0x00, 0x38, 0xFF, 0x0D, 0x00, 0x01, 0x26, 0x0C, 0x00, 0xC0, 0x60, 0x00, 0x7C, 0xA0, 0x84,
+	 0x80, 0x3B, 0x02, 0x00, 0xC0, 0x67, 0x03, 0x00, 0x40, 0x3B, 0x02, 0x00, 0x00, 0x67, 0x0A, 0xFB,
+	 0xD5, 0x01, 0xD4, 0x01, 0x0B, 0xF1, 0xAB, 0xFF, 0x64, 0x44, 0xFF, 0x27, 0x1F, 0x00, 0x20, 0x26,
+	 0x03, 0x00, 0x02, 0x60, 0x00, 0x75, 0x1A, 0x00, 0x19, 0xF3, 0xFF, 0xFF, 0x03, 0x1B, 0x04, 0x60,
+	 0x00, 0x75, 0x0A, 0x64, 0xCC, 0x84, 0x19, 0xFB, 0x01, 0x60, 0x00, 0x75, 0x64, 0x40, 0x03, 0x22,
+	 0x0D, 0x00, 0x20, 0x44, 0x80, 0x2A, 0x03, 0x00, 0x20, 0xBC, 0x40, 0x40, 0x07, 0x00, 0xD9, 0xFE,
+	 0x81, 0x60, 0x0B, 0x64, 0x28, 0xFB, 0x2C, 0x44, 0x29, 0xFB, 0xD0, 0xFE, 0xAF, 0x01, 0xA9, 0xFF,
+	 0x77, 0x44, 0x60, 0x57, 0x40, 0x4A, 0x01, 0x2A, 0x20, 0x00, 0x24, 0x44, 0xAC, 0x86, 0x08, 0xF2,
+	 0x1C, 0x03, 0x1F, 0x60, 0x04, 0x65, 0xD4, 0x80, 0x0E, 0xF2, 0x02, 0x03, 0xA5, 0xD5, 0x04, 0x00,
+	 0x01, 0xBC, 0x0E, 0xFA, 0x09, 0xF4, 0xD1, 0xFE, 0x46, 0x44, 0x0F, 0x18, 0x3F, 0xF2, 0x48, 0x65,
+	 0xC4, 0x84, 0x13, 0xFB, 0x66, 0x44, 0x10, 0xFB, 0x66, 0x47, 0x20, 0xBF, 0x3B, 0x42, 0x04, 0xA2,
+	 0xA2, 0xDB, 0x0E, 0xF2, 0x41, 0x75, 0x10, 0xBC, 0x0E, 0xFA, 0x2A, 0x44, 0x08, 0x2A, 0x17, 0x00,
+	 0x23, 0x44, 0x00, 0xA8, 0x5C, 0x43, 0x13, 0x03, 0x0F, 0x60, 0x7F, 0xF5, 0x01, 0x00, 0x09, 0xF4,
+	 0x0E, 0xF2, 0x0D, 0x18, 0x08, 0xB0, 0x18, 0xAC, 0xFA, 0x03, 0x0E, 0xFA, 0x66, 0x43, 0x11, 0xFD,
+	 0x46, 0x43, 0x23, 0x47, 0x80, 0xBF, 0x3B, 0x42, 0x04, 0xA2, 0xA2, 0xDB, 0x28, 0x75, 0x2A, 0x44,
+	 0x06, 0x22, 0x2D, 0x00, 0x22, 0x44, 0x00, 0xA8, 0x60, 0x46, 0x0E, 0xF2, 0x28, 0x03, 0x10, 0xB0,
+	 0x01, 0xBC, 0x03, 0x02, 0x00, 0x64, 0x40, 0x42, 0x22, 0x00, 0x0E, 0xFA, 0xD1, 0xFE, 0x1E, 0x60,
+	 0xF8, 0x64, 0x40, 0x47, 0x58, 0x4F, 0x80, 0x00, 0x46, 0x42, 0x19, 0x02, 0x22, 0x47, 0x40, 0xBF,
+	 0x3B, 0x42, 0x04, 0xA2, 0xA2, 0xDB, 0x23, 0xF2, 0x66, 0x43, 0x00, 0xA8, 0x0E, 0xF2, 0x08, 0x02,
+	 0x60, 0x40, 0x02, 0x2A, 0xE4, 0x01, 0x12, 0xFD, 0x10, 0x64, 0x0E, 0xFA, 0x02, 0x75, 0x07, 0x00,
+	 0x60, 0x40, 0x04, 0x2A, 0xDC, 0x01, 0x12, 0xFD, 0x10, 0x64, 0x0E, 0xFA, 0x04, 0x75, 0x2A, 0x44,
+	 0x80, 0x2A, 0x19, 0x00, 0x21, 0x44, 0xAC, 0x86, 0x0E, 0xF2, 0x15, 0x03, 0x01, 0xBC, 0x0E, 0xFA,
+	 0xD1, 0xFE, 0x1F, 0x60, 0x10, 0x64, 0x40, 0x47, 0x58, 0x4F, 0x56, 0x00, 0x46, 0x41, 0x0B, 0x02,
+	 0x21, 0x47, 0x10, 0xBF, 0x3B, 0x42, 0x04, 0xA2, 0xA2, 0xDB, 0x0E, 0xF2, 0x66, 0x43, 0x08, 0xFD,
+	 0x10, 0xBC, 0x0E, 0xFA, 0x80, 0x75, 0x2A, 0x44, 0x10, 0xB0, 0x20, 0x44, 0x15, 0x03, 0x7F, 0xB4,
+	 0x40, 0x40, 0x14, 0x60, 0xFC, 0x63, 0xA3, 0xD3, 0xFF, 0xFF, 0x20, 0xB0, 0x80, 0xB0, 0x09, 0x03,
+	 0x08, 0x03, 0x40, 0xBC, 0x7F, 0xB4, 0x04, 0xB0, 0xA3, 0xDB, 0x03, 0x03, 0x20, 0x44, 0x80, 0xBC,
+	 0x40, 0x40, 0xB3, 0x60, 0x8B, 0x78, 0xFF, 0xFF, 0xB3, 0x60, 0xBE, 0x78, 0xFF, 0xFF, 0xE8, 0xFE,
+	 0x14, 0x05, 0xEA, 0xFE, 0x24, 0x05, 0xE9, 0xFE, 0x1C, 0x05, 0xE7, 0xFE, 0x09, 0x05, 0x47, 0xFF,
+	 0x20, 0x44, 0x0F, 0x22, 0x03, 0x00, 0xCC, 0x84, 0x40, 0x40, 0x0F, 0x22, 0xB8, 0xFE, 0xEC, 0x01,
+	 0x23, 0x41, 0x00, 0xB9, 0x5C, 0x4A, 0xE8, 0x02, 0x6F, 0x01, 0x24, 0x41, 0x00, 0xB9, 0x1F, 0x60,
+	 0x04, 0x65, 0x45, 0x47, 0xE1, 0x02, 0x58, 0x4F, 0x0F, 0x00, 0xDE, 0x02, 0x5C, 0x4A, 0x46, 0x44,
+	 0x4D, 0x01, 0x22, 0x41, 0x00, 0xB9, 0x5C, 0x4A, 0x08, 0x24, 0x81, 0x01, 0xD5, 0x01, 0x21, 0x41,
+	 0x00, 0xB9, 0x5C, 0x4A, 0xA6, 0x03, 0xD0, 0x01, 0x27, 0xD3, 0x03, 0x00, 0x10, 0xB0, 0x09, 0xF2,
+	 0x04, 0x03, 0xAC, 0x86, 0x0E, 0xF2, 0xFA, 0x02, 0x08, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0E, 0xF3,
+	 0x0F, 0x60, 0xFE, 0x65, 0x0C, 0xF3, 0x24, 0x86, 0x24, 0x46, 0x60, 0x40, 0xFB, 0x3B, 0x07, 0x00,
+	 0x80, 0x26, 0x02, 0x00, 0x23, 0x46, 0x03, 0x4C, 0x46, 0x61, 0x3A, 0x65, 0x0C, 0x00, 0x2E, 0xF3,
+	 0x40, 0x45, 0xF8, 0x2B, 0x02, 0x00, 0x40, 0x45, 0x03, 0x00, 0x58, 0x4F, 0x44, 0x00, 0x07, 0x02,
+	 0x58, 0x4F, 0x50, 0x00, 0x04, 0x05, 0x66, 0x50, 0x65, 0x52, 0x61, 0x51, 0x09, 0x00, 0x26, 0x47,
+	 0x00, 0xBF, 0x0E, 0xFB, 0x2E, 0xF5, 0x05, 0xF0, 0x80, 0x60, 0x64, 0x50, 0x00, 0x72, 0x7E, 0x71,
+	 0xAC, 0xFF, 0xB3, 0x60, 0xBE, 0x78, 0xFF, 0xFF, 0x8E, 0xFF, 0x0F, 0xF3, 0x0F, 0x60, 0xFE, 0x65,
+	 0x24, 0x86, 0x0D, 0xF3, 0x24, 0x46, 0x60, 0x40, 0xFB, 0x3B, 0x07, 0x00, 0x80, 0x26, 0x02, 0x00,
+	 0x23, 0x46, 0x03, 0x4C, 0x46, 0x61, 0x3A, 0x65, 0x0C, 0x00, 0x2E, 0xF3, 0x40, 0x45, 0xF8, 0x2B,
+	 0x02, 0x00, 0x40, 0x45, 0x03, 0x00, 0x58, 0x4F, 0x16, 0x00, 0x07, 0x02, 0x58, 0x4F, 0x22, 0x00,
+	 0x04, 0x05, 0x66, 0x50, 0x65, 0x52, 0x61, 0x51, 0x09, 0x00, 0x26, 0x47, 0x00, 0xBF, 0x0F, 0xFB,
+	 0x2E, 0xF5, 0x05, 0xF0, 0x80, 0x60, 0x64, 0x50, 0x00, 0x72, 0x7E, 0x71, 0x8D, 0xFF, 0xAD, 0xFF,
+	 0xB3, 0x60, 0xBE, 0x78, 0xFF, 0xFF, 0x25, 0x44, 0x89, 0xF1, 0x8A, 0xF1, 0xD0, 0x80, 0xD0, 0x80,
+	 0x07, 0x04, 0x01, 0x06, 0x05, 0x00, 0x25, 0x46, 0x01, 0xF0, 0x03, 0x67, 0xA0, 0x85, 0x94, 0x80,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x25, 0x46, 0x26, 0x41, 0x46, 0x63, 0x01, 0xF2, 0xFF, 0xFF, 0xFF, 0xB5,
+	 0xD5, 0x81, 0x00, 0xF2, 0x05, 0x04, 0x04, 0x63, 0x60, 0x46, 0xF7, 0x1B, 0x42, 0xFE, 0x0D, 0x00,
+	 0x61, 0x44, 0xC5, 0x81, 0x63, 0x45, 0xC5, 0x81, 0x9C, 0x84, 0xDC, 0x84, 0x01, 0xF2, 0xF0, 0x85,
+	 0xF0, 0x80, 0x65, 0x44, 0xF8, 0x85, 0xFF, 0xFF, 0x02, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0xA2, 0xFF,
+	 0x0F, 0x60, 0x8B, 0xF3, 0xFF, 0xFF, 0xAC, 0x86, 0x0E, 0xF2, 0x07, 0x03, 0x00, 0xA8, 0x09, 0xF2,
+	 0xFA, 0x02, 0x01, 0x67, 0x0E, 0xFA, 0x08, 0xFE, 0x17, 0x00, 0x8B, 0xF3, 0xFF, 0xFF, 0xD8, 0xA0,
+	 0x00, 0xB4, 0x12, 0x06, 0x09, 0x60, 0x08, 0x61, 0x41, 0x4A, 0x7C, 0xA1, 0x0E, 0xA1, 0xA2, 0xFF,
+	 0xB5, 0x60, 0x58, 0x4E, 0xC1, 0x78, 0xFF, 0xFF, 0xA3, 0xFF, 0x06, 0x03, 0x2A, 0x43, 0xB5, 0x60,
+	 0x58, 0x4E, 0xE2, 0x78, 0xFF, 0xFF, 0x08, 0xFE, 0xA3, 0xFF, 0x2D, 0x58, 0xFF, 0xFF, 0x41, 0x4A,
+	 0x42, 0xA1, 0x03, 0x00, 0x41, 0x4A, 0x7C, 0xA1, 0x0E, 0xA1, 0xA2, 0xFF, 0xB5, 0x60, 0x58, 0x4E,
+	 0xC1, 0x78, 0xFF, 0xFF, 0x07, 0x03, 0x2A, 0x43, 0xB5, 0x60, 0x58, 0x4E, 0xE2, 0x78, 0xFF, 0xFF,
+	 0x08, 0xFE, 0x0C, 0x00, 0x0F, 0x60, 0x8B, 0xF3, 0xFF, 0xFF, 0xAC, 0x86, 0x0E, 0xF2, 0x06, 0x03,
+	 0x00, 0xA8, 0x09, 0xF2, 0xFA, 0x02, 0x01, 0x67, 0x0E, 0xFA, 0x08, 0xFE, 0xA3, 0xFF, 0x2D, 0x58,
+	 0xFF, 0xFF, 0x8C, 0xF3, 0x7C, 0x63, 0x00, 0xBE, 0x40, 0x45, 0x1A, 0x03, 0x00, 0x65, 0x65, 0x44,
+	 0xDC, 0x85, 0x84, 0xA1, 0x00, 0xF2, 0x06, 0x06, 0x01, 0xFC, 0x00, 0xA8, 0x60, 0x46, 0xF7, 0x02,
+	 0x40, 0x45, 0x0E, 0x00, 0x8B, 0xF3, 0x00, 0x63, 0xD4, 0x84, 0x8B, 0xFB, 0x80, 0x60, 0x7C, 0x64,
+	 0x01, 0xFA, 0x00, 0xF0, 0x00, 0xFC, 0xD3, 0x80, 0x8C, 0xF9, 0x02, 0x02, 0x8D, 0xF9, 0x08, 0xFE,
+	 0x2E, 0x58, 0xFF, 0xFF, 0x66, 0x44, 0x25, 0x46, 0x05, 0xFA, 0x06, 0xFA, 0x01, 0xF0, 0x03, 0x67,
+	 0x02, 0xFC, 0xB0, 0x84, 0x3A, 0x7E, 0x01, 0xFA, 0x12, 0x64, 0x03, 0xFA, 0x00, 0xF0, 0x04, 0xF8,
+	 0x00, 0x64, 0x0C, 0x61, 0x10, 0x63, 0x59, 0xDA, 0xFE, 0x1F, 0x2E, 0x58, 0xFF, 0xFF, 0x27, 0x43,
+	 0xE3, 0x81, 0xE9, 0x81, 0x03, 0x05, 0x16, 0x03, 0x00, 0x61, 0x01, 0x00, 0xEC, 0x63, 0x61, 0x46,
+	 0xBF, 0xD2, 0x27, 0x45, 0xDC, 0x84, 0xA2, 0xDA, 0xBE, 0xD2, 0x25, 0x46, 0x88, 0xF8, 0x04, 0x1B,
+	 0x25, 0x44, 0x61, 0x46, 0xA3, 0xDA, 0x04, 0x00, 0x0A, 0xFA, 0x60, 0x46, 0x25, 0x44, 0x09, 0xFA,
+	 0x61, 0x46, 0xBE, 0xDA, 0x2F, 0x58, 0xFF, 0xFF, 0x25, 0x44, 0x00, 0xA8, 0x07, 0x4B, 0x0C, 0x03,
+	 0x58, 0x4F, 0x33, 0x00, 0x0B, 0x47, 0x1F, 0x60, 0x0A, 0x65, 0x27, 0x44, 0xD4, 0x80, 0x00, 0x64,
+	 0x01, 0x02, 0x0F, 0xFA, 0x58, 0x4F, 0xD3, 0x01, 0x70, 0x00, 0x25, 0x43, 0xE3, 0x84, 0x7C, 0x41,
+	 0x02, 0x04, 0xE8, 0x81, 0xEC, 0x63, 0x61, 0x46, 0xA3, 0xD2, 0x00, 0x7C, 0x40, 0x45, 0xBF, 0xD8,
+	 0xA3, 0xD8, 0xBE, 0xD8, 0x27, 0x42, 0x5A, 0xD3, 0x25, 0x5C, 0x60, 0x41, 0x02, 0x1B, 0x27, 0xD9,
+	 0x05, 0x00, 0x25, 0x46, 0x0A, 0xFA, 0x61, 0x46, 0x25, 0x44, 0x09, 0xFA, 0x25, 0x44, 0x27, 0x43,
+	 0x00, 0x61, 0x60, 0x46, 0x09, 0xF2, 0x08, 0xFC, 0x00, 0xA8, 0xDD, 0x81, 0xFA, 0x02, 0xBF, 0xD1,
+	 0x66, 0x44, 0xBE, 0xDB, 0xC1, 0x84, 0xBF, 0xDB, 0x48, 0x00, 0x25, 0x46, 0xEC, 0x63, 0x08, 0xF2,
+	 0x89, 0xF2, 0x1E, 0x18, 0x40, 0x47, 0xE0, 0x84, 0xE8, 0x85, 0x02, 0x05, 0xE8, 0x83, 0x00, 0x65,
+	 0x65, 0x46, 0xBF, 0xD2, 0x61, 0x5C, 0xCC, 0x84, 0xA2, 0xDA, 0x25, 0x46, 0x0A, 0xF2, 0x00, 0xB9,
+	 0x65, 0x46, 0x08, 0x24, 0xBE, 0xDA, 0x02, 0x1B, 0xA3, 0xD8, 0x02, 0x00, 0x60, 0x46, 0x89, 0xFA,
+	 0x00, 0xB9, 0x61, 0x46, 0x08, 0x28, 0x0A, 0xFA, 0x25, 0x46, 0x89, 0xFC, 0x8A, 0xFC, 0x88, 0xFC,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x61, 0x28, 0x65, 0x25, 0x43, 0x8D, 0xF3, 0xAF, 0x83, 0x00, 0xBE,
+	 0x18, 0x03, 0x02, 0x03, 0x00, 0xFC, 0x01, 0x00, 0x8C, 0xFD, 0x63, 0x46, 0x65, 0x44, 0xCC, 0x85,
+	 0x00, 0xF2, 0x07, 0x02, 0x8D, 0xF5, 0x00, 0x64, 0x00, 0xFA, 0xDE, 0x60, 0xAF, 0x64, 0x09, 0xFB,
+	 0x08, 0x00, 0x66, 0x43, 0x00, 0xBE, 0xDD, 0x81, 0xF1, 0x02, 0x8B, 0xF1, 0x8D, 0xFD, 0xC1, 0x84,
+	 0x8B, 0xFB, 0x2E, 0x58, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x45, 0x29, 0x43, 0xFC, 0xA3, 0x66, 0x44,
+	 0xBD, 0xDB, 0x25, 0x44, 0xBD, 0xDB, 0x00, 0x64, 0xBD, 0xDB, 0x03, 0x61, 0x0E, 0x65, 0x1F, 0x60,
+	 0x1E, 0x63, 0x43, 0x49, 0xA3, 0xD3, 0x06, 0xA3, 0x00, 0xA8, 0xCD, 0x81, 0x04, 0x02, 0xF9, 0x02,
+	 0xB3, 0x60, 0xBE, 0x78, 0xFF, 0xFF, 0x01, 0x26, 0xE6, 0x01, 0xD4, 0x80, 0x60, 0x45, 0xE3, 0x05,
+	 0xF6, 0xA3, 0xBD, 0xD1, 0xBD, 0xD1, 0x44, 0x47, 0x44, 0x48, 0x44, 0x45, 0x1F, 0x60, 0x60, 0x64,
+	 0x44, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0x48, 0xFE, 0x8C, 0xF5, 0x8B, 0xF3, 0x0D, 0x18, 0xCC, 0x84,
+	 0x8B, 0xFB, 0x80, 0x60, 0x7C, 0x64, 0x01, 0xFA, 0x00, 0x64, 0x00, 0xF0, 0x00, 0xFA, 0xD0, 0x80,
+	 0x8C, 0xF9, 0x02, 0x02, 0x8D, 0xF9, 0x08, 0xFE, 0x2E, 0x58, 0xFF, 0xFF, 0x1E, 0x60, 0xCE, 0x63,
+	 0x0D, 0x65, 0x00, 0x61, 0x41, 0x48, 0xA3, 0xD3, 0x06, 0xA3, 0xAC, 0x86, 0x00, 0x61, 0x09, 0x03,
+	 0x00, 0xF2, 0x09, 0xF0, 0xAC, 0x86, 0x00, 0xF2, 0xDD, 0x81, 0xFC, 0x02, 0x64, 0x44, 0xAC, 0x86,
+	 0xF6, 0x01, 0x61, 0x44, 0x25, 0x46, 0x27, 0xDA, 0x65, 0x44, 0x28, 0x45, 0x45, 0x88, 0xCC, 0x85,
+	 0x5A, 0x87, 0xE9, 0x02, 0x00, 0x64, 0x27, 0xDA, 0x5A, 0xDA, 0x5A, 0x87, 0x87, 0xF3, 0x86, 0xF1,
+	 0x02, 0xA4, 0x60, 0x46, 0x60, 0x45, 0x00, 0x61, 0x22, 0xF2, 0xFF, 0xFF, 0xAC, 0x86, 0x00, 0xF2,
+	 0x04, 0x03, 0xAC, 0x86, 0x00, 0xF2, 0xDD, 0x81, 0xFC, 0x02, 0x65, 0x44, 0x02, 0xA5, 0x65, 0x46,
+	 0x64, 0x44, 0xCC, 0x9C, 0xFF, 0xFF, 0xF0, 0x02, 0x61, 0x44, 0x25, 0x46, 0x27, 0xDA, 0x5A, 0x87,
+	 0x28, 0x45, 0x45, 0x88, 0x87, 0xF3, 0x86, 0xF1, 0x02, 0xA4, 0x60, 0x46, 0x60, 0x45, 0x00, 0x61,
+	 0x76, 0xF2, 0xFF, 0xFF, 0xAC, 0x86, 0x00, 0xF2, 0x09, 0x03, 0x00, 0xF2, 0x09, 0xF0, 0xAC, 0x86,
+	 0x00, 0xF2, 0xDD, 0x81, 0xFC, 0x02, 0x64, 0x44, 0xAC, 0x86, 0xF6, 0x01, 0x65, 0x44, 0x02, 0xA5,
+	 0x65, 0x46, 0x64, 0x44, 0xCC, 0x9C, 0x61, 0x44, 0xEB, 0x02, 0x25, 0x46, 0x27, 0xDA, 0x5A, 0x87,
+	 0x28, 0x45, 0x45, 0x88, 0x06, 0x60, 0x40, 0x65, 0x8C, 0xF3, 0x01, 0x61, 0xAC, 0x86, 0x00, 0xF2,
+	 0x03, 0x03, 0xD5, 0x80, 0xDD, 0x81, 0xFA, 0x04, 0xCD, 0x84, 0x25, 0x46, 0x27, 0xDA, 0x28, 0x45,
+	 0xC4, 0x84, 0x5A, 0xDA, 0xDA, 0x81, 0x8B, 0xF1, 0x59, 0xD8, 0x1E, 0x60, 0xCC, 0x64, 0x18, 0x63,
+	 0xA0, 0xD1, 0x06, 0xA4, 0x59, 0xD8, 0xFC, 0x1F, 0x00, 0x64, 0x59, 0xDA, 0x59, 0xDA, 0x01, 0x60,
+	 0x1A, 0x64, 0x0A, 0x63, 0x58, 0xD1, 0x59, 0xD8, 0xFD, 0x1F, 0x7D, 0xF1, 0x59, 0xD8, 0x45, 0x01,
+	 0x07, 0x4B, 0xB6, 0x60, 0x58, 0x4F, 0x4D, 0x78, 0xFF, 0xFF, 0x0B, 0x47, 0x58, 0x4F, 0x21, 0x00,
+	 0x3C, 0x01, 0x07, 0x4B, 0xB6, 0x60, 0x58, 0x4F, 0x4D, 0x78, 0xFF, 0xFF, 0x0B, 0x47, 0x27, 0x44,
+	 0x00, 0xBE, 0x08, 0xF0, 0x15, 0x03, 0x64, 0x42, 0x4A, 0xD3, 0x09, 0xF2, 0xDC, 0x83, 0xA2, 0xDD,
+	 0x25, 0x43, 0x09, 0xFC, 0x63, 0x46, 0x27, 0x43, 0x0A, 0xFC, 0x09, 0xFA, 0x08, 0xF8, 0x00, 0xA8,
+	 0x66, 0x43, 0x03, 0x02, 0x64, 0x44, 0x58, 0xDD, 0x03, 0x00, 0x60, 0x46, 0x25, 0x44, 0x0A, 0xFA,
+	 0x1C, 0x01, 0x27, 0x43, 0xE3, 0x81, 0xE9, 0x81, 0x03, 0x05, 0x16, 0x03, 0x00, 0x61, 0x01, 0x00,
+	 0xEC, 0x63, 0x61, 0x46, 0xBF, 0xD2, 0x27, 0x45, 0xDC, 0x84, 0xA2, 0xDA, 0xA3, 0xD2, 0x25, 0x46,
+	 0x88, 0xF8, 0x04, 0x1B, 0x25, 0x44, 0x61, 0x46, 0xBE, 0xDA, 0x04, 0x00, 0x09, 0xFA, 0x60, 0x46,
+	 0x25, 0x44, 0x0A, 0xFA, 0x61, 0x46, 0xA3, 0xDA, 0x2F, 0x58, 0xFF, 0xFF, 0xA0, 0xFE, 0x07, 0x05,
+	 0xA3, 0xFE, 0x07, 0x05, 0xA1, 0xFE, 0x46, 0x05, 0x60, 0x64, 0x3B, 0xDB, 0x0F, 0x00, 0x20, 0x58,
+	 0xFF, 0xFF, 0xFA, 0x01, 0x0A, 0x60, 0x80, 0xF3, 0xFF, 0xFF, 0xFB, 0xB4, 0xA2, 0xDB, 0xA0, 0x4C,
+	 0x59, 0xBC, 0xFF, 0xB4, 0xA0, 0x51, 0xA0, 0x4C, 0x7D, 0xB4, 0xA0, 0x51, 0xA1, 0xFF, 0xFF, 0xFF,
+	 0x83, 0x3E, 0x40, 0x60, 0x0B, 0x65, 0x2B, 0x44, 0x00, 0x63, 0xE8, 0x80, 0xF8, 0x84, 0x02, 0x24,
+	 0x94, 0x84, 0xF3, 0x83, 0xCD, 0x81, 0xFF, 0xFF, 0xF8, 0x02, 0xDF, 0x83, 0x2F, 0x58, 0x40, 0x4B,
+	 0x00, 0x62, 0x01, 0x64, 0xD4, 0x80, 0xE0, 0x84, 0x1A, 0x03, 0xD4, 0x80, 0xE0, 0x84, 0x15, 0x03,
+	 0x61, 0x44, 0x11, 0x61, 0xE0, 0x84, 0xCD, 0x81, 0xFD, 0x04, 0x01, 0x00, 0xE0, 0x84, 0xF2, 0x82,
+	 0xFF, 0xFF, 0x02, 0x24, 0xC6, 0x82, 0x02, 0x28, 0xD6, 0x82, 0xE2, 0x80, 0xCD, 0x81, 0x02, 0x28,
+	 0x01, 0xBC, 0xF4, 0x02, 0x01, 0x2A, 0xC6, 0x82, 0x03, 0x00, 0xE9, 0x81, 0xF2, 0x82, 0x61, 0x44,
+	 0x2D, 0x58, 0xFF, 0xFF, 0x00, 0x64, 0x3B, 0xDB, 0x0C, 0x60, 0x6E, 0xF3, 0x5A, 0xD1, 0x60, 0x40,
+	 0x04, 0x3A, 0x2C, 0x00, 0x00, 0x64, 0x4A, 0xDB, 0x1E, 0x60, 0xCE, 0x63, 0xA3, 0xD3, 0x46, 0x43,
+	 0xAC, 0x86, 0x3C, 0x45, 0x22, 0x03, 0xD4, 0x80, 0x07, 0xF2, 0x02, 0x02, 0x09, 0xF2, 0xF8, 0x01,
+	 0xD0, 0x80, 0x09, 0xF2, 0xF5, 0x02, 0x60, 0x43, 0x80, 0x67, 0xB0, 0x81, 0x61, 0x44, 0x0F, 0x60,
+	 0x90, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x09, 0x60,
+	 0x08, 0x65, 0x0E, 0xF2, 0x02, 0xF2, 0x60, 0x40, 0xF0, 0x37, 0x05, 0x00, 0x8F, 0xF3, 0xD4, 0x80,
+	 0xCC, 0x84, 0x01, 0x02, 0x8F, 0xFB, 0x63, 0x44, 0xDB, 0x01, 0x23, 0x46, 0x3C, 0x44, 0xAC, 0x80,
+	 0xFF, 0xFF, 0x94, 0x02, 0x69, 0xF3, 0x6A, 0xF3, 0x02, 0xA8, 0x02, 0xA8, 0x08, 0x02, 0x00, 0x64,
+	 0x6B, 0xFB, 0x69, 0xFB, 0x6A, 0xFB, 0x00, 0x64, 0x6C, 0xFB, 0xCA, 0xFE, 0x92, 0x00, 0x03, 0x02,
+	 0x00, 0x64, 0x6A, 0xFB, 0xCA, 0xFE, 0x01, 0x64, 0x3B, 0xDB, 0x0F, 0x60, 0x6A, 0xF3, 0xFF, 0xFF,
+	 0x00, 0xA8, 0x60, 0x46, 0x35, 0x03, 0x2C, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x26, 0x86, 0x00,
+	 0x2E, 0xF2, 0x15, 0x60, 0x02, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41,
+	 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46, 0x2E, 0xF0, 0x63, 0x46, 0xD0, 0x80,
+	 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46, 0x2D, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02,
+	 0x61, 0x46, 0x2C, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF,
+	 0x63, 0x46, 0xE8, 0x1B, 0x87, 0xF3, 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0x5F, 0x02, 0x66, 0x45,
+	 0x63, 0x46, 0x06, 0xF2, 0x65, 0x46, 0x80, 0xB0, 0x09, 0xF2, 0x58, 0x03, 0xAC, 0x86, 0xCA, 0x01,
+	 0x6A, 0xF3, 0xFF, 0xFF, 0x01, 0xA8, 0xFF, 0xFF, 0x4C, 0x02, 0x0F, 0x60, 0x73, 0xF3, 0xFF, 0xFF,
+	 0x00, 0xA8, 0x60, 0x46, 0x0F, 0x03, 0x76, 0xF1, 0x07, 0xF2, 0xFF, 0xFF, 0xD0, 0x80, 0x09, 0xF2,
+	 0x03, 0x02, 0xAC, 0x86, 0x07, 0xF2, 0xFA, 0x02, 0x03, 0x02, 0x00, 0x64, 0x76, 0xFB, 0xED, 0x01,
+	 0x46, 0x5C, 0x3C, 0x00, 0x0F, 0x60, 0x76, 0xF3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x01, 0x03,
+	 0x35, 0x02, 0x6B, 0xF3, 0xFF, 0xFF, 0x01, 0xA8, 0xFF, 0xFF, 0x13, 0x02, 0x0F, 0x60, 0x6D, 0xF3,
+	 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x0B, 0x03, 0x2A, 0xF0, 0x20, 0x67, 0x09, 0xF2, 0xB0, 0x83,
+	 0x00, 0xA8, 0x00, 0x64, 0x02, 0x03, 0x2A, 0xFC, 0x01, 0x00, 0x6B, 0xFB, 0x1F, 0x00, 0x00, 0x64,
+	 0x6B, 0xFB, 0x0F, 0x60, 0x67, 0xF3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x12, 0x03, 0x2A, 0xF0,
+	 0x08, 0x67, 0xA0, 0x80, 0xFF, 0xFF, 0x12, 0x03, 0x76, 0xF1, 0x07, 0xF2, 0xFF, 0xFF, 0xD0, 0x80,
+	 0x09, 0xF2, 0x03, 0x02, 0xAC, 0x86, 0x07, 0xF2, 0xFA, 0x02, 0x08, 0x02, 0x00, 0x64, 0x76, 0xFB,
+	 0xE8, 0x01, 0x00, 0x64, 0x76, 0xFB, 0xB7, 0x60, 0xA2, 0x78, 0xFF, 0xFF, 0x66, 0x44, 0xFC, 0xFB,
+	 0x46, 0x5C, 0x16, 0x60, 0x2B, 0xF3, 0x0D, 0xF2, 0x60, 0x5C, 0x64, 0x5F, 0x0D, 0xFA, 0x07, 0xF0,
+	 0x2A, 0xF2, 0xFF, 0xFF, 0x76, 0xF9, 0x60, 0x40, 0x08, 0x2B, 0x05, 0x00, 0x00, 0x64, 0x48, 0xFB,
+	 0xBA, 0x60, 0x03, 0x78, 0xFF, 0xFF, 0x00, 0x64, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x02, 0x23, 0xF0,
+	 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDA, 0xBF, 0x60, 0x16, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0x00, 0x63,
+	 0x40, 0x47, 0x50, 0x36, 0x01, 0x00, 0x01, 0x63, 0x48, 0xFD, 0x4A, 0xF3, 0x35, 0xFA, 0x10, 0xA4,
+	 0x4A, 0xFB, 0x00, 0x64, 0x15, 0xFA, 0x16, 0xFA, 0x0F, 0xFA, 0x07, 0xF0, 0x87, 0xF3, 0xFF, 0xFF,
+	 0xD0, 0x80, 0xFF, 0xFF, 0x05, 0x03, 0x66, 0x43, 0x64, 0x46, 0x11, 0xF2, 0xBA, 0xFB, 0x63, 0x46,
+	 0x03, 0xF2, 0x00, 0xF4, 0x01, 0xF2, 0xFC, 0xA5, 0x00, 0x7F, 0xD4, 0x84, 0x27, 0x45, 0x3C, 0x46,
+	 0x1A, 0xFA, 0x22, 0x63, 0x7B, 0x60, 0xFF, 0x64, 0xA4, 0x84, 0x03, 0x2B, 0x1C, 0x63, 0x2A, 0xFA,
+	 0x8F, 0xB0, 0x88, 0x36, 0x02, 0xA3, 0x60, 0x40, 0xA4, 0x36, 0x14, 0x63, 0x43, 0x4C, 0x18, 0xFC,
+	 0x00, 0x7C, 0x22, 0xF8, 0x64, 0x41, 0x07, 0xF0, 0x66, 0x43, 0x64, 0x46, 0x3A, 0xF2, 0x63, 0x46,
+	 0xFF, 0xB4, 0x22, 0xFA, 0x60, 0x40, 0x00, 0x36, 0x92, 0x00, 0x2A, 0xF2, 0xFF, 0xFF, 0x0C, 0xB0,
+	 0x08, 0x3A, 0x8D, 0x00, 0x60, 0x40, 0x40, 0x26, 0x8A, 0x00, 0x03, 0xF2, 0x00, 0xF4, 0xA0, 0xD2,
+	 0xAA, 0x60, 0xAA, 0x65, 0x5A, 0xD0, 0xD4, 0x80, 0x03, 0x64, 0x0A, 0x02, 0xD0, 0x80, 0x00, 0x64,
+	 0x5A, 0xD0, 0x06, 0x02, 0xD0, 0x80, 0xF8, 0x7F, 0xD0, 0x80, 0x01, 0x03, 0x01, 0x02, 0x01, 0x61,
+	 0x62, 0x43, 0x46, 0x43, 0x3C, 0x46, 0x07, 0xF4, 0x3A, 0xF2, 0xFF, 0xFF, 0xA3, 0x46, 0x60, 0x40,
+	 0x22, 0x26, 0x49, 0x00, 0x60, 0x45, 0x63, 0x42, 0x5A, 0xD0, 0xCD, 0x81, 0x3C, 0x46, 0x18, 0x02,
+	 0x64, 0x44, 0x88, 0x3A, 0x15, 0x00, 0x8E, 0x37, 0x00, 0x00, 0x65, 0x44, 0x01, 0x26, 0x5F, 0x00,
+	 0x04, 0x26, 0x03, 0x00, 0x10, 0x26, 0x01, 0x00, 0x31, 0x00, 0xA3, 0x46, 0x3B, 0xF2, 0xFF, 0xFF,
+	 0x60, 0x40, 0x80, 0x27, 0x3E, 0x00, 0xA3, 0x46, 0x00, 0x7C, 0x22, 0xF8, 0xA3, 0x46, 0x4F, 0x00,
+	 0xA3, 0x46, 0x65, 0x44, 0x01, 0x26, 0x0B, 0x00, 0x04, 0x26, 0x03, 0x00, 0x10, 0x26, 0x01, 0x00,
+	 0x1D, 0x00, 0x3B, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x80, 0x27, 0x2B, 0x00, 0x17, 0x00, 0x87, 0xF3,
+	 0xFF, 0xFF, 0x60, 0x46, 0x3A, 0xF2, 0x66, 0x43, 0xFF, 0xB4, 0x3C, 0x46, 0x22, 0xF0, 0x60, 0x47,
+	 0xB0, 0x84, 0x22, 0xFA, 0x63, 0x46, 0x3B, 0xF0, 0x60, 0x40, 0x04, 0x27, 0x03, 0x00, 0x10, 0x27,
+	 0x01, 0x00, 0x04, 0x00, 0x64, 0x40, 0x80, 0x27, 0x14, 0x00, 0x00, 0x00, 0x3C, 0x46, 0x02, 0x65,
+	 0xBE, 0x60, 0xB6, 0x78, 0xFF, 0xFF, 0xCD, 0x81, 0x63, 0x42, 0x5A, 0xD0, 0x3C, 0x46, 0x09, 0x02,
+	 0x64, 0x44, 0x88, 0x3A, 0x06, 0x00, 0x77, 0x37, 0x1A, 0x00, 0x78, 0x37, 0x18, 0x00, 0x8E, 0x37,
+	 0x16, 0x00, 0x3C, 0x46, 0x22, 0xF0, 0x80, 0x67, 0xB0, 0x84, 0xA2, 0xDA, 0xFF, 0xFF, 0x3F, 0xF2,
+	 0x3E, 0xF0, 0x08, 0xA4, 0x60, 0x41, 0x22, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x26, 0x03, 0x00,
+	 0x04, 0x26, 0x03, 0x00, 0x04, 0x00, 0x04, 0x2B, 0x02, 0x00, 0x61, 0x44, 0x3F, 0xFA, 0x3C, 0x46,
+	 0x2C, 0xF2, 0x27, 0x40, 0x01, 0x27, 0x32, 0xF2, 0xB4, 0xF1, 0x60, 0x40, 0x01, 0x26, 0x47, 0x00,
+	 0x09, 0x60, 0x00, 0x64, 0xD0, 0x80, 0x3F, 0xF2, 0x09, 0x06, 0x2C, 0x45, 0xC4, 0x84, 0xD0, 0x80,
+	 0x40, 0x4A, 0x34, 0x06, 0x60, 0x43, 0x64, 0x44, 0x54, 0x88, 0x17, 0x00, 0x60, 0x45, 0x13, 0x60,
+	 0x4B, 0xF3, 0xBB, 0xF3, 0x00, 0xBC, 0x60, 0x47, 0xEC, 0xA0, 0x28, 0x03, 0x27, 0x07, 0x2C, 0x44,
+	 0xC4, 0x81, 0x02, 0x60, 0x1C, 0x65, 0x45, 0x4A, 0xD5, 0x80, 0x2C, 0x45, 0x1F, 0x06, 0x27, 0x40,
+	 0x04, 0x27, 0x25, 0x00, 0x2A, 0x43, 0xD7, 0x85, 0x45, 0x48, 0xB5, 0xF1, 0x0F, 0xF2, 0xD3, 0x80,
+	 0x01, 0x65, 0x01, 0x07, 0x00, 0x65, 0xB4, 0x84, 0x0F, 0xFA, 0x00, 0x63, 0x3F, 0xF2, 0x28, 0x45,
+	 0x60, 0x41, 0xD4, 0x84, 0xDF, 0x83, 0xFC, 0x07, 0x14, 0xFC, 0x17, 0xFA, 0x04, 0x60, 0x00, 0x64,
+	 0x27, 0x45, 0xB4, 0x84, 0x2A, 0xFA, 0x28, 0x43, 0x16, 0xFC, 0x0D, 0x00, 0x3F, 0xF2, 0x2C, 0x45,
+	 0xB5, 0xF1, 0xC4, 0x81, 0xD1, 0x80, 0x0F, 0xF2, 0x01, 0x06, 0x01, 0xBC, 0x0F, 0xFA, 0x3F, 0xF2,
+	 0x17, 0xFA, 0x01, 0x64, 0x14, 0xFA, 0x0F, 0xF0, 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x2A, 0x6F, 0x00,
+	 0x64, 0xF1, 0x15, 0x60, 0xDD, 0xF3, 0x64, 0x40, 0x01, 0x27, 0x03, 0x00, 0x60, 0x40, 0x02, 0x26,
+	 0x14, 0x00, 0x07, 0xF0, 0x66, 0x43, 0x64, 0x46, 0x12, 0xF0, 0x15, 0x60, 0xDE, 0xF3, 0x63, 0x46,
+	 0x64, 0x40, 0x10, 0x2A, 0x20, 0x00, 0x60, 0x40, 0x02, 0x26, 0x07, 0x00, 0x01, 0x26, 0x08, 0x00,
+	 0x04, 0x26, 0x09, 0x00, 0x06, 0x61, 0x6E, 0x63, 0x08, 0x00, 0x02, 0x61, 0x14, 0x63, 0x05, 0x00,
+	 0x00, 0x61, 0x0A, 0x63, 0x02, 0x00, 0x04, 0x61, 0x37, 0x63, 0x00, 0x64, 0x25, 0x60, 0xA2, 0x65,
+	 0x45, 0xD1, 0xD5, 0x81, 0x15, 0x60, 0xDA, 0xF9, 0x25, 0x60, 0x7A, 0x65, 0x45, 0xD1, 0x1C, 0xFC,
+	 0xB0, 0x84, 0x1E, 0xFA, 0x3C, 0x00, 0x60, 0x40, 0x10, 0x2A, 0x04, 0x00, 0x08, 0x61, 0x1E, 0x60,
+	 0x0B, 0x63, 0x27, 0x00, 0x20, 0x2A, 0x04, 0x00, 0x0A, 0x61, 0x16, 0x60, 0x0F, 0x63, 0x21, 0x00,
+	 0x40, 0x2A, 0x04, 0x00, 0x0C, 0x61, 0x12, 0x60, 0x0A, 0x63, 0x1B, 0x00, 0x80, 0x2A, 0x04, 0x00,
+	 0x0E, 0x61, 0x0E, 0x60, 0x0E, 0x63, 0x15, 0x00, 0x01, 0x2B, 0x04, 0x00, 0x10, 0x61, 0x0E, 0x60,
+	 0x09, 0x63, 0x0F, 0x00, 0x02, 0x2B, 0x04, 0x00, 0x12, 0x61, 0x0A, 0x60, 0x0D, 0x63, 0x09, 0x00,
+	 0x04, 0x2B, 0x04, 0x00, 0x14, 0x61, 0x0A, 0x60, 0x08, 0x63, 0x03, 0x00, 0x16, 0x61, 0x0A, 0x60,
+	 0x0C, 0x63, 0x1E, 0xF0, 0x40, 0x67, 0x25, 0x60, 0xA2, 0x65, 0x45, 0xD1, 0xD5, 0x81, 0x15, 0x60,
+	 0xDA, 0xF9, 0x25, 0x60, 0x7A, 0x65, 0x45, 0xD1, 0x1C, 0xFC, 0xB0, 0x84, 0x1E, 0xFA, 0xAA, 0xF2,
+	 0x15, 0x60, 0xC2, 0xF3, 0x07, 0xF0, 0x66, 0x43, 0x64, 0x46, 0x44, 0x44, 0x61, 0x40, 0x08, 0x26,
+	 0x02, 0x00, 0x61, 0x40, 0x80, 0x36, 0x12, 0xF2, 0x63, 0x46, 0x2C, 0x60, 0x26, 0x61, 0x00, 0x7F,
+	 0x60, 0x45, 0x45, 0xD3, 0xFF, 0xFF, 0x60, 0x45, 0x00, 0x7F, 0x4B, 0xFB, 0x65, 0x44, 0x00, 0x7E,
+	 0xBB, 0xFB, 0x62, 0xF1, 0x60, 0x43, 0x60, 0x47, 0xD0, 0x80, 0xC0, 0x65, 0x01, 0x06, 0x64, 0x44,
+	 0x0A, 0x36, 0x70, 0x64, 0x14, 0x36, 0x38, 0x64, 0x37, 0x36, 0x15, 0x64, 0x6E, 0x36, 0x0B, 0x64,
+	 0x44, 0x86, 0x2A, 0xF2, 0x07, 0xF0, 0x60, 0x40, 0xB0, 0x3A, 0x03, 0x00, 0x40, 0x3B, 0x01, 0x00,
+	 0x12, 0x00, 0x0C, 0xB4, 0x08, 0x3A, 0x44, 0x00, 0x22, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x80, 0x2B,
+	 0x3F, 0x00, 0x17, 0xF2, 0x22, 0xF0, 0xFF, 0xFF, 0x64, 0x40, 0x22, 0x22, 0x04, 0x00, 0x00, 0xA8,
+	 0x01, 0xA8, 0x36, 0x03, 0x35, 0x03, 0x3C, 0x46, 0x2A, 0xF0, 0x40, 0x67, 0xB0, 0x84, 0xA2, 0xDA,
+	 0x60, 0x45, 0x22, 0xF2, 0xFF, 0xFF, 0x60, 0x43, 0x60, 0x40, 0x01, 0x26, 0x05, 0x00, 0x04, 0x26,
+	 0x1D, 0x00, 0x10, 0x26, 0x10, 0x00, 0x04, 0x00, 0x04, 0x27, 0x18, 0x00, 0x10, 0x27, 0x0B, 0x00,
+	 0x65, 0x44, 0x2A, 0x61, 0x60, 0x40, 0x03, 0x2B, 0x24, 0x61, 0x8F, 0xB0, 0x88, 0x36, 0x02, 0xA1,
+	 0x41, 0x4C, 0x98, 0xFA, 0x15, 0x00, 0x65, 0x44, 0x32, 0x61, 0x60, 0x40, 0x03, 0x2B, 0x2C, 0x61,
+	 0x8F, 0xB0, 0x88, 0x36, 0x02, 0xA1, 0x41, 0x4C, 0x98, 0xFA, 0x0A, 0x00, 0x65, 0x44, 0x2E, 0x61,
+	 0x60, 0x40, 0x03, 0x2B, 0x28, 0x61, 0x8F, 0xB0, 0x88, 0x36, 0x02, 0xA1, 0x41, 0x4C, 0x98, 0xFA,
+	 0xBB, 0x60, 0xFB, 0x78, 0xFF, 0xFF, 0x66, 0x45, 0xAA, 0xF2, 0x15, 0x60, 0xC2, 0xF3, 0x24, 0x46,
+	 0x61, 0x40, 0x08, 0x26, 0x02, 0x00, 0x61, 0x40, 0x80, 0x36, 0x12, 0xF2, 0x65, 0x46, 0x60, 0x40,
+	 0x10, 0x26, 0x34, 0x00, 0x2C, 0x45, 0x17, 0xF2, 0x4B, 0xF1, 0xC4, 0x84, 0xE0, 0x84, 0xE0, 0x84,
+	 0xE0, 0x81, 0x64, 0x45, 0x16, 0xA1, 0xB7, 0x60, 0x58, 0x4D, 0xC0, 0x78, 0xFF, 0xFF, 0x64, 0xF1,
+	 0x01, 0xA4, 0xE0, 0x84, 0xE0, 0x84, 0x64, 0x40, 0x01, 0x2B, 0x06, 0xA4, 0x1B, 0xFA, 0xBB, 0xF3,
+	 0x25, 0x60, 0x82, 0x65, 0x60, 0x40, 0x0B, 0x37, 0x00, 0x63, 0x0F, 0x37, 0x02, 0x63, 0x0A, 0x37,
+	 0x04, 0x63, 0x0E, 0x37, 0x06, 0x63, 0x09, 0x37, 0x08, 0x63, 0x0D, 0x37, 0x0A, 0x63, 0x08, 0x37,
+	 0x0C, 0x63, 0x0C, 0x37, 0x0E, 0x63, 0x28, 0xA3, 0x47, 0xD1, 0xD8, 0xA3, 0xD7, 0x83, 0x15, 0x60,
+	 0xD9, 0xF9, 0x47, 0xD1, 0x40, 0x67, 0xB0, 0x84, 0x1F, 0xFA, 0x56, 0x00, 0x2A, 0xF2, 0xFF, 0xFF,
+	 0x60, 0x40, 0x80, 0x36, 0x17, 0x00, 0x50, 0x36, 0x15, 0x00, 0x10, 0x36, 0x13, 0x00, 0x30, 0x36,
+	 0x11, 0x00, 0xA0, 0x36, 0x0F, 0x00, 0xB0, 0x36, 0x0D, 0x00, 0xC0, 0x36, 0x0B, 0x00, 0xBB, 0xF3,
+	 0xFF, 0xFF, 0x60, 0x40, 0x0A, 0x37, 0x06, 0x00, 0x15, 0x60, 0xDD, 0xF3, 0x80, 0x60, 0x00, 0x61,
+	 0x60, 0x40, 0x04, 0x26, 0x00, 0x61, 0xBB, 0xF3, 0x25, 0x60, 0x7A, 0x65, 0x60, 0x40, 0x0A, 0x37,
+	 0x00, 0x63, 0x14, 0x37, 0x02, 0x63, 0x37, 0x37, 0x04, 0x63, 0x6E, 0x37, 0x06, 0x63, 0x28, 0xA3,
+	 0x47, 0xD1, 0xD8, 0xA3, 0xD7, 0x83, 0x15, 0x60, 0xD9, 0xF9, 0x47, 0xD1, 0xFF, 0xFF, 0xB1, 0x84,
+	 0x1F, 0xFA, 0xBB, 0xF1, 0x2C, 0x45, 0x64, 0x43, 0x17, 0xF2, 0x4B, 0xF1, 0xC4, 0x84, 0xE0, 0x84,
+	 0xE0, 0x84, 0xE0, 0x81, 0x63, 0x40, 0x37, 0x37, 0xE1, 0x81, 0x64, 0x45, 0xB7, 0x60, 0x58, 0x4D,
+	 0xC0, 0x78, 0xFF, 0xFF, 0xAE, 0x82, 0xFC, 0xA2, 0x0A, 0x03, 0x63, 0x40, 0x6E, 0x3B, 0x06, 0x00,
+	 0x60, 0x41, 0x04, 0x0D, 0x63, 0x44, 0x80, 0x7E, 0xBB, 0xFB, 0x61, 0x44, 0xDC, 0x84, 0x2B, 0xF0,
+	 0x1B, 0xFA, 0x64, 0x44, 0x80, 0x27, 0x47, 0x00, 0x07, 0xF0, 0x66, 0x45, 0x64, 0x46, 0x12, 0xF2,
+	 0x65, 0x46, 0x60, 0x40, 0x10, 0x2A, 0x2E, 0x00, 0x16, 0xF2, 0x0F, 0xF0, 0xAC, 0x84, 0x2C, 0x45,
+	 0x29, 0x03, 0x4B, 0xF1, 0xC4, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x81, 0x63, 0x40, 0x37, 0x37,
+	 0xE1, 0x81, 0x64, 0x45, 0x0F, 0xF0, 0xB7, 0x60, 0x58, 0x4D, 0xC0, 0x78, 0xFF, 0xFF, 0xAE, 0x82,
+	 0xFC, 0xA2, 0x0A, 0x03, 0x63, 0x40, 0x6E, 0x3B, 0x06, 0x00, 0x60, 0x41, 0x04, 0x0D, 0x80, 0x67,
+	 0xB0, 0x84, 0x0F, 0xFA, 0x61, 0x44, 0xDC, 0x84, 0x1D, 0xFA, 0xDE, 0x65, 0xC4, 0x85, 0x26, 0x41,
+	 0xE1, 0x81, 0xC5, 0x84, 0x2B, 0xFA, 0x1B, 0xF0, 0xDE, 0x64, 0xC0, 0x85, 0x26, 0x44, 0xE0, 0x84,
+	 0xC4, 0x84, 0x10, 0xFA, 0x26, 0x44, 0x2C, 0xF0, 0x0A, 0xA4, 0x66, 0x45, 0x24, 0x46, 0x92, 0xF2,
+	 0x65, 0x46, 0x9F, 0xF0, 0x61, 0x40, 0x10, 0x2A, 0x03, 0x00, 0x65, 0x40, 0x80, 0x27, 0xA0, 0xA4,
+	 0x64, 0x40, 0x01, 0x26, 0x00, 0x64, 0x11, 0xFA, 0xBB, 0xF3, 0x13, 0xFA, 0x7C, 0x44, 0x1D, 0xFA,
+	 0xFF, 0xFF, 0x0D, 0xF2, 0x3E, 0xF0, 0x60, 0x47, 0xFF, 0xB4, 0x64, 0x41, 0x01, 0xB1, 0x01, 0x63,
+	 0x17, 0x02, 0x60, 0x41, 0xFF, 0x22, 0x04, 0x00, 0xB7, 0x60, 0x58, 0x4F, 0xB1, 0x78, 0xFF, 0xFF,
+	 0x07, 0x60, 0xF7, 0xFD, 0x16, 0x60, 0x2B, 0xF3, 0xFF, 0xFF, 0x60, 0x41, 0x01, 0x63, 0x61, 0x40,
+	 0xFF, 0x22, 0x04, 0x00, 0xB7, 0x60, 0x58, 0x4F, 0xB1, 0x78, 0xFF, 0xFF, 0x07, 0x60, 0xF8, 0xFD,
+	 0xBD, 0x60, 0x7A, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x40, 0x27, 0x03, 0x00,
+	 0xBD, 0x60, 0x75, 0x78, 0xFF, 0xFF, 0x22, 0xF2, 0x46, 0x43, 0x60, 0x40, 0x22, 0x26, 0x09, 0x00,
+	 0x01, 0x26, 0x0A, 0x00, 0x04, 0x26, 0x4B, 0x00, 0x10, 0x26, 0x10, 0x00, 0xBD, 0x60, 0x75, 0x78,
+	 0xFF, 0xFF, 0xBC, 0x60, 0xF0, 0x78, 0xFF, 0xFF, 0x04, 0x27, 0x3D, 0x00, 0x10, 0x27, 0x03, 0x00,
+	 0xBD, 0x60, 0x75, 0x78, 0xFF, 0xFF, 0x87, 0xF3, 0x3C, 0xF1, 0x02, 0x00, 0x07, 0xF2, 0x00, 0x7C,
+	 0x40, 0x43, 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x08, 0x27, 0x21, 0x00, 0xA3, 0x46, 0x4B, 0xF2,
+	 0xFF, 0xFF, 0xDC, 0x84, 0x4B, 0xFA, 0x4A, 0xF2, 0x08, 0x04, 0xDC, 0x84, 0x4A, 0xFA, 0x49, 0xF2,
+	 0x04, 0x04, 0xDC, 0x84, 0x49, 0xFA, 0x01, 0x04, 0xFF, 0xFF, 0x87, 0xF3, 0x66, 0x5C, 0xD0, 0x80,
+	 0x00, 0x7C, 0x01, 0x02, 0x3C, 0xF1, 0x4B, 0xF0, 0x64, 0x47, 0x20, 0xBF, 0xA3, 0x46, 0x3A, 0xF8,
+	 0x3B, 0xFA, 0xA3, 0x46, 0x4A, 0xF2, 0x49, 0xF0, 0xA3, 0x46, 0x3C, 0xFA, 0x3D, 0xF8, 0x0F, 0x60,
+	 0xA0, 0x64, 0xA3, 0x46, 0x76, 0x61, 0x0E, 0x63, 0x59, 0xD0, 0x58, 0xD9, 0xFD, 0x1F, 0xA3, 0x46,
+	 0xBD, 0x60, 0x75, 0x78, 0xFF, 0xFF, 0x87, 0xF3, 0xFF, 0xFF, 0x60, 0x46, 0x02, 0x00, 0x07, 0xF4,
+	 0xFF, 0xFF, 0xA3, 0x46, 0x2A, 0xF2, 0xA3, 0x46, 0x60, 0x40, 0x08, 0x27, 0x48, 0x00, 0x87, 0xF3,
+	 0x66, 0x5C, 0xD0, 0x80, 0x3B, 0xF0, 0x08, 0x03, 0x64, 0x40, 0x10, 0x2A, 0x12, 0x00, 0xFF, 0x60,
+	 0xEF, 0x64, 0xA0, 0x84, 0x3B, 0xFA, 0x24, 0x00, 0x3D, 0xF3, 0x01, 0x61, 0x60, 0x43, 0xCF, 0x83,
+	 0xE1, 0x81, 0xFD, 0x0D, 0xE9, 0x81, 0xA1, 0x80, 0xFF, 0xFF, 0x03, 0x03, 0x91, 0x84, 0x3B, 0xFA,
+	 0x17, 0x00, 0x4B, 0xF2, 0xFF, 0xFF, 0x10, 0xA0, 0xFF, 0xFF, 0x02, 0x04, 0xFF, 0x60, 0xFF, 0x64,
+	 0xDC, 0x84, 0x4B, 0xFA, 0x4A, 0xF2, 0x16, 0x04, 0xDC, 0x84, 0x4A, 0xFA, 0x49, 0xF2, 0x08, 0x04,
+	 0xDC, 0x84, 0x49, 0xFA, 0x05, 0x04, 0x3B, 0xF2, 0xFF, 0xFF, 0xE0, 0x84, 0xE8, 0x84, 0x3B, 0xFA,
+	 0x0C, 0x60, 0xFE, 0x62, 0x80, 0xFF, 0x78, 0x44, 0x03, 0xA4, 0xA2, 0xDB, 0xC7, 0x60, 0xCF, 0x78,
+	 0xFF, 0xFF, 0x84, 0xFF, 0x06, 0x60, 0x17, 0xE1, 0x77, 0x40, 0x8B, 0xFF, 0x02, 0x60, 0x00, 0x75,
+	 0xC9, 0x60, 0x58, 0x4F, 0x67, 0x78, 0xFF, 0xFF, 0x01, 0x64, 0x06, 0x60, 0x80, 0xFB, 0x0C, 0x60,
+	 0xFE, 0x62, 0x80, 0xFF, 0x78, 0x44, 0x03, 0xA4, 0xA2, 0xDB, 0xC8, 0x60, 0x46, 0x78, 0xFF, 0xFF,
+	 0x84, 0xFF, 0x00, 0x7C, 0x06, 0x60, 0x80, 0xF3, 0xA2, 0xD9, 0x60, 0x40, 0x01, 0x2A, 0x04, 0x00,
+	 0xC9, 0x60, 0x58, 0x4F, 0xAF, 0x78, 0xFF, 0xFF, 0x3C, 0x46, 0x07, 0xF4, 0x87, 0xF3, 0x66, 0x5C,
+	 0xD0, 0x80, 0x00, 0x7C, 0x07, 0x03, 0x66, 0x43, 0x3C, 0x46, 0x22, 0xF2, 0x63, 0x46, 0x60, 0x40,
+	 0x01, 0x2A, 0x01, 0x00, 0x3C, 0xF1, 0x4B, 0xF0, 0x64, 0x41, 0x64, 0x47, 0xFF, 0xB4, 0x60, 0x5F,
+	 0x20, 0xBC, 0x80, 0x26, 0x80, 0xAC, 0x60, 0x47, 0xA3, 0x46, 0x3A, 0xFA, 0x64, 0x44, 0x20, 0x7F,
+	 0x34, 0x94, 0x3B, 0xFA, 0xA3, 0x46, 0x4A, 0xF2, 0x49, 0xF0, 0xA3, 0x46, 0x3C, 0xFA, 0x3D, 0xF8,
+	 0x80, 0x60, 0x10, 0xE0, 0x08, 0x60, 0x00, 0xEA, 0x0F, 0x64, 0x60, 0x7F, 0xA0, 0x5A, 0x80, 0x60,
+	 0x00, 0xEA, 0xA0, 0x60, 0x00, 0xEA, 0xD1, 0x60, 0x00, 0xEA, 0xBD, 0x60, 0x75, 0x78, 0xFF, 0xFF,
+	 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x08, 0x27, 0x31, 0x00, 0x2A, 0xF2, 0x00, 0x60, 0x7C, 0x62,
+	 0x60, 0x40, 0x40, 0x2B, 0x24, 0x00, 0xA2, 0xD3, 0x00, 0x61, 0x60, 0xFE, 0xA0, 0xD3, 0x5E, 0xD1,
+	 0xFF, 0xFF, 0x20, 0xFE, 0x64, 0x5F, 0xDC, 0x84, 0xF1, 0x81, 0xC0, 0x2B, 0x04, 0x00, 0x80, 0x2A,
+	 0x02, 0x00, 0x7F, 0xA4, 0xDC, 0x84, 0xFF, 0x3B, 0x03, 0x00, 0x60, 0x47, 0xDC, 0x87, 0x01, 0x61,
+	 0xC0, 0x80, 0x00, 0x36, 0xDC, 0x84, 0x4E, 0xDB, 0x60, 0xFE, 0x5A, 0xD1, 0xFF, 0xFF, 0xC1, 0x84,
+	 0xF0, 0x22, 0x10, 0xA4, 0xF0, 0x2A, 0x01, 0x00, 0x00, 0x64, 0xA2, 0xDB, 0x20, 0xFE, 0x00, 0x60,
+	 0x3E, 0xF3, 0xFF, 0xFF, 0xA0, 0xD3, 0x5A, 0xD1, 0x3A, 0xFA, 0x3B, 0xF8, 0x74, 0x62, 0xA2, 0xD0,
+	 0xFF, 0xFF, 0x64, 0x44, 0xE0, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xE1, 0x7F, 0x5A, 0xD0, 0xA0, 0x5A,
+	 0x64, 0x44, 0xE2, 0x7F, 0xA0, 0x5A, 0x00, 0x60, 0x40, 0xF3, 0xFF, 0xFF, 0xA0, 0xD1, 0x5A, 0xD1,
+	 0x64, 0x45, 0x64, 0x44, 0xE3, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xE4, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A,
+	 0x64, 0x44, 0xE5, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xE6, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44,
+	 0xE7, 0x7F, 0xA0, 0x5A, 0x65, 0x40, 0x0D, 0x3A, 0x1C, 0x00, 0x64, 0x47, 0xE8, 0x7F, 0x5A, 0xD1,
+	 0xA0, 0x5A, 0x64, 0x44, 0xE9, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xEA, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A,
+	 0x64, 0x44, 0xEB, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xEC, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44,
+	 0xED, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xEE, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xEF, 0x7F,
+	 0xA0, 0x5A, 0x08, 0x60, 0x00, 0xEA, 0x65, 0x44, 0x02, 0xA4, 0x60, 0x7F, 0xA0, 0x5A, 0x80, 0x60,
+	 0x00, 0xEA, 0xA0, 0x60, 0x00, 0xEA, 0xD1, 0x60, 0x00, 0xEA, 0x02, 0x64, 0x3B, 0xDB, 0xBA, 0x60,
+	 0xF3, 0x78, 0xFF, 0xFF, 0xBF, 0x60, 0xBB, 0x78, 0xFF, 0xFF, 0x66, 0x44, 0xFC, 0xFB, 0x07, 0xF0,
+	 0x00, 0x64, 0xD0, 0x80, 0x87, 0xF3, 0x0E, 0x03, 0xD0, 0x80, 0xFF, 0xFF, 0x0B, 0x03, 0x47, 0xF1,
+	 0x07, 0xF0, 0x64, 0x40, 0x02, 0x26, 0x01, 0x00, 0x08, 0x00, 0x03, 0x12, 0xBE, 0x60, 0x46, 0x78,
+	 0xFF, 0xFF, 0xFC, 0x0A, 0xBE, 0x60, 0xA6, 0x78, 0xFF, 0xFF, 0x87, 0xF0, 0x87, 0xF3, 0x10, 0xF0,
+	 0xD4, 0x80, 0xFF, 0xFF, 0x3D, 0x03, 0x66, 0x43, 0x65, 0x46, 0xFF, 0x67, 0x20, 0x85, 0x64, 0x5F,
+	 0x40, 0x44, 0x15, 0xF0, 0x25, 0x44, 0xD0, 0x84, 0x03, 0xA4, 0x03, 0x0E, 0xE8, 0x84, 0xE8, 0x84,
+	 0x04, 0x00, 0xFA, 0xA4, 0xE8, 0x84, 0xE8, 0x87, 0xC0, 0xBF, 0xC0, 0x84, 0x15, 0xFA, 0x40, 0x45,
+	 0x14, 0xF0, 0x24, 0x44, 0xD0, 0x84, 0x1F, 0xA4, 0x06, 0x0E, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84,
+	 0xE8, 0x84, 0xE8, 0x84, 0x07, 0x00, 0xC2, 0xA4, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84,
+	 0xE8, 0x87, 0xF8, 0xBF, 0xC0, 0x84, 0x14, 0xFA, 0x60, 0x5C, 0x2F, 0x67, 0xD0, 0x80, 0x60, 0x45,
+	 0x02, 0x28, 0x64, 0x45, 0x25, 0x5C, 0x8B, 0x67, 0xD0, 0x80, 0x60, 0x41, 0x02, 0x24, 0x64, 0x41,
+	 0xD5, 0x84, 0x80, 0x65, 0xC4, 0x87, 0x01, 0x05, 0x00, 0x64, 0xFF, 0xB4, 0x0E, 0xFA, 0x63, 0x46,
+	 0x07, 0xF0, 0x66, 0x43, 0x64, 0x46, 0x17, 0xF2, 0x63, 0x46, 0x60, 0x40, 0x00, 0x36, 0x2E, 0x00,
+	 0x01, 0x36, 0x1E, 0x00, 0x03, 0x3A, 0x25, 0x00, 0x64, 0x46, 0x10, 0xF2, 0x11, 0xFA, 0x12, 0xF2,
+	 0x00, 0x61, 0x60, 0x47, 0x00, 0x7F, 0x12, 0xFA, 0x97, 0xFA, 0x46, 0x44, 0x63, 0x46, 0xC1, 0x60,
+	 0x58, 0x4E, 0x72, 0x78, 0xFF, 0xFF, 0x65, 0x40, 0x00, 0x3A, 0x04, 0x00, 0xC1, 0x60, 0x58, 0x4E,
+	 0xBC, 0x78, 0xFF, 0xFF, 0x07, 0xF0, 0x66, 0x43, 0x64, 0x46, 0x96, 0xFC, 0x63, 0x46, 0x43, 0x00,
+	 0x64, 0x46, 0x16, 0xF2, 0x00, 0x61, 0x20, 0x28, 0xFF, 0xA4, 0x97, 0xFA, 0x16, 0xFA, 0x63, 0x46,
+	 0x3A, 0x00, 0x64, 0x46, 0x00, 0x61, 0x97, 0xFA, 0x63, 0x46, 0x35, 0x00, 0x07, 0xF0, 0x66, 0x41,
+	 0x64, 0x46, 0x16, 0xF2, 0xFF, 0xFF, 0x20, 0x28, 0xFF, 0xA4, 0x16, 0xFA, 0x93, 0xF4, 0x12, 0xF2,
+	 0x20, 0x28, 0xFF, 0xA3, 0x13, 0xFC, 0x61, 0x46, 0x63, 0x40, 0x00, 0x3A, 0x24, 0x00, 0xC1, 0x60,
+	 0x58, 0x4E, 0x93, 0x78, 0xFF, 0xFF, 0x61, 0x40, 0xFF, 0x36, 0x1D, 0x00, 0x66, 0x41, 0x64, 0x46,
+	 0x12, 0xF2, 0x93, 0xF4, 0x61, 0x46, 0x20, 0x28, 0x16, 0x00, 0x44, 0x44, 0xC1, 0x60, 0x58, 0x4E,
+	 0x72, 0x78, 0xFF, 0xFF, 0x24, 0x5C, 0x65, 0x40, 0x00, 0x36, 0x06, 0x00, 0x66, 0x41, 0x64, 0x46,
+	 0x01, 0x64, 0x17, 0xFA, 0x61, 0x46, 0x07, 0x00, 0x66, 0x43, 0x64, 0x46, 0xC1, 0x60, 0x58, 0x4E,
+	 0xBC, 0x78, 0xFF, 0xFF, 0x63, 0x46, 0xBE, 0x60, 0xA6, 0x78, 0xFF, 0xFF, 0x07, 0xF0, 0x66, 0x43,
+	 0x64, 0x46, 0x17, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0xFF, 0x27, 0xFF, 0xFF, 0x00, 0x36, 0x07, 0x00,
+	 0x01, 0x36, 0x1C, 0x00, 0x02, 0x36, 0x24, 0x00, 0x03, 0x36, 0x43, 0x00, 0xFF, 0xFF, 0x15, 0x60,
+	 0xF9, 0xF1, 0x16, 0xF2, 0x43, 0x44, 0xD0, 0x80, 0x2C, 0x60, 0x24, 0x61, 0x09, 0x03, 0xA1, 0xD1,
+	 0x2C, 0x60, 0x22, 0x63, 0xC0, 0x84, 0x16, 0xFA, 0xA3, 0xD3, 0xFF, 0xFF, 0x13, 0xFA, 0x39, 0x00,
+	 0x96, 0xFC, 0xC1, 0x60, 0x58, 0x4E, 0xBC, 0x78, 0xFF, 0xFF, 0x33, 0x00, 0x43, 0x44, 0xC1, 0x60,
+	 0x58, 0x4E, 0xBC, 0x78, 0xFF, 0xFF, 0x16, 0x60, 0x11, 0xF3, 0x96, 0xFC, 0x13, 0xFA, 0x29, 0x00,
+	 0x63, 0x46, 0x2B, 0x60, 0xF4, 0x63, 0xA3, 0xD3, 0x15, 0xF2, 0x60, 0x45, 0xD4, 0x80, 0x07, 0xF0,
+	 0x0C, 0x03, 0x66, 0x41, 0x44, 0x44, 0x64, 0x46, 0x12, 0xF2, 0x61, 0x46, 0xC1, 0x60, 0x58, 0x4E,
+	 0x72, 0x78, 0xFF, 0xFF, 0x65, 0x40, 0x00, 0x3A, 0x19, 0x00, 0x66, 0x43, 0x24, 0x46, 0xC1, 0x60,
+	 0x58, 0x4E, 0xBC, 0x78, 0xFF, 0xFF, 0x12, 0xF2, 0x91, 0xF2, 0x90, 0xFA, 0x60, 0x5F, 0x12, 0xFA,
+	 0x04, 0x00, 0xC1, 0x60, 0x58, 0x4E, 0xBC, 0x78, 0xFF, 0xFF, 0x03, 0x64, 0x17, 0xFA, 0x63, 0x46,
+	 0x05, 0x00, 0x24, 0x43, 0x02, 0x64, 0x17, 0xFA, 0x63, 0x46, 0x00, 0x00, 0x03, 0x64, 0x3B, 0xDB,
+	 0xCA, 0xFE, 0x47, 0xF1, 0x01, 0x65, 0x32, 0x40, 0x04, 0x27, 0x08, 0x00, 0x2C, 0xF2, 0x64, 0x45,
+	 0x02, 0x22, 0x04, 0x00, 0x60, 0x40, 0x01, 0x26, 0x01, 0x00, 0x7B, 0x00, 0x14, 0xF2, 0x65, 0x40,
+	 0x01, 0x26, 0x0C, 0x00, 0x60, 0x45, 0x05, 0x64, 0x3B, 0xDB, 0x65, 0x44, 0xCC, 0x85, 0x25, 0x60,
+	 0xD6, 0x64, 0xE5, 0x60, 0x78, 0x41, 0xD3, 0x78, 0x97, 0xF1, 0x50, 0x00, 0x60, 0x41, 0x2A, 0xF0,
+	 0x00, 0x60, 0x0C, 0x64, 0xA0, 0x84, 0x04, 0x36, 0x02, 0x00, 0x0C, 0x3A, 0x01, 0x00, 0x46, 0x00,
+	 0x61, 0x45, 0x60, 0x43, 0x25, 0x60, 0xD6, 0x64, 0xE5, 0x60, 0x78, 0x41, 0xD3, 0x78, 0x97, 0xF1,
+	 0x63, 0x40, 0x08, 0x36, 0x01, 0x00, 0x3A, 0x00, 0x14, 0xF2, 0x1C, 0x65, 0x60, 0x41, 0x00, 0x63,
+	 0xCD, 0x81, 0xC7, 0x83, 0xFD, 0x02, 0x3F, 0xF0, 0x2C, 0xF2, 0xC3, 0x83, 0x60, 0x40, 0x01, 0x2A,
+	 0x0D, 0x00, 0x25, 0x60, 0xD4, 0x64, 0xE5, 0x60, 0x78, 0x41, 0xC7, 0x78, 0x97, 0xF1, 0x25, 0x60,
+	 0xDA, 0x64, 0xE5, 0x60, 0x78, 0x41, 0xD2, 0x78, 0x63, 0x45, 0x20, 0x00, 0x25, 0x60, 0xD2, 0x64,
+	 0xE5, 0x60, 0x78, 0x41, 0xC7, 0x78, 0x97, 0xF1, 0x25, 0x60, 0xD8, 0x64, 0xE5, 0x60, 0x78, 0x41,
+	 0xD2, 0x78, 0x63, 0x45, 0x15, 0xF2, 0xFF, 0xFF, 0x0F, 0xB4, 0x00, 0xA8, 0x01, 0xA8, 0x0E, 0x03,
+	 0x07, 0x03, 0x25, 0x60, 0xE0, 0x64, 0xE5, 0x60, 0x78, 0x41, 0xC7, 0x78, 0x97, 0xF1, 0x06, 0x00,
+	 0x25, 0x60, 0xDE, 0x64, 0xE5, 0x60, 0x78, 0x41, 0xC7, 0x78, 0x97, 0xF1, 0x04, 0x64, 0x3B, 0xDB,
+	 0x07, 0xF0, 0x66, 0x41, 0x64, 0x46, 0x06, 0xF0, 0xFF, 0x60, 0x5F, 0x64, 0xA0, 0x84, 0x06, 0xFA,
+	 0x61, 0x46, 0x1E, 0x60, 0xF2, 0x64, 0x0F, 0x60, 0x8D, 0xFB, 0x3C, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x5C, 0x5C, 0xFC, 0xFC, 0xCE, 0xFE, 0xB7, 0x60, 0xE2, 0x78,
+	 0xFF, 0xFF, 0x13, 0x60, 0x2E, 0xF3, 0x07, 0xF4, 0x06, 0xF2, 0x02, 0xA8, 0x3C, 0x46, 0x10, 0x03,
+	 0x10, 0xB0, 0x2A, 0xF2, 0x0D, 0x03, 0x0E, 0xF2, 0x0C, 0xB0, 0x60, 0x40, 0xF0, 0x37, 0x20, 0xBC,
+	 0x02, 0x03, 0xFE, 0x7F, 0x0E, 0xFA, 0x23, 0xF0, 0x10, 0x64, 0xB0, 0x84, 0xA2, 0xDA, 0xCE, 0x01,
+	 0x2A, 0xF2, 0xFF, 0xFF, 0x50, 0xA8, 0x02, 0x7C, 0x10, 0x03, 0x0F, 0xF0, 0x15, 0xF2, 0x64, 0x41,
+	 0x01, 0x2A, 0x02, 0x00, 0xAF, 0xF1, 0x09, 0x00, 0x03, 0x65, 0x07, 0xF0, 0x66, 0x43, 0x64, 0x46,
+	 0x06, 0xF0, 0x63, 0x46, 0xAE, 0xF1, 0x64, 0x40, 0x10, 0x2A, 0x64, 0x45, 0xDC, 0x84, 0xD4, 0x80,
+	 0x15, 0xFA, 0x38, 0x07, 0x61, 0x40, 0x01, 0x2A, 0x08, 0x00, 0x13, 0x60, 0x03, 0xF3, 0xFF, 0xFF,
+	 0xDC, 0x84, 0x00, 0x36, 0x00, 0x3B, 0xA2, 0xDB, 0x07, 0x00, 0x13, 0x60, 0x04, 0xF3, 0xFF, 0xFF,
+	 0xDC, 0x84, 0x00, 0x36, 0x00, 0x3B, 0xA2, 0xDB, 0x2A, 0xF0, 0x08, 0x67, 0xB0, 0x84, 0xA2, 0xDA,
+	 0x08, 0xF0, 0x1E, 0x60, 0xD4, 0x64, 0xD0, 0x80, 0x07, 0xF2, 0x46, 0x43, 0x87, 0xF1, 0x06, 0x03,
+	 0x60, 0x46, 0x86, 0xF4, 0xD0, 0x80, 0x80, 0xBB, 0x01, 0x03, 0x06, 0xFC, 0x23, 0x46, 0x3E, 0xF2,
+	 0x00, 0x63, 0x01, 0xB0, 0x43, 0x5C, 0xFC, 0xFC, 0x0A, 0x03, 0x1E, 0x60, 0xEC, 0x64, 0x0F, 0x60,
+	 0x90, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xB7, 0x60,
+	 0xE2, 0x78, 0xFF, 0xFF, 0x00, 0x64, 0x49, 0xFB, 0x25, 0x60, 0xE0, 0x64, 0xE5, 0x60, 0x78, 0x41,
+	 0xC7, 0x78, 0x97, 0xF1, 0x25, 0x60, 0xE2, 0x64, 0xE5, 0x60, 0x78, 0x41, 0xC7, 0x78, 0x97, 0xF1,
+	 0x27, 0x44, 0xF7, 0xB4, 0x40, 0x47, 0x23, 0xF0, 0x01, 0x64, 0xB0, 0x84, 0xA2, 0xDA, 0x07, 0xF0,
+	 0x66, 0x41, 0x64, 0x46, 0x06, 0xF2, 0x7F, 0x65, 0xA4, 0x9E, 0x06, 0xFA, 0x61, 0x46, 0x5E, 0x01,
+	 0xC0, 0x60, 0x35, 0x78, 0xFF, 0xFF, 0x21, 0x64, 0x3B, 0xDB, 0x31, 0xF3, 0x01, 0x63, 0xC4, 0xB4,
+	 0x31, 0xFB, 0x32, 0xFD, 0xBF, 0x60, 0xEB, 0x62, 0x42, 0x40, 0xA0, 0x4C, 0x40, 0xBC, 0x7D, 0xB4,
+	 0xA0, 0x51, 0xA0, 0xFE, 0x1A, 0xFF, 0x1E, 0x60, 0xE6, 0x64, 0x08, 0xF0, 0x07, 0xF0, 0xD0, 0x80,
+	 0x1E, 0x60, 0xEC, 0x62, 0x13, 0x02, 0xA2, 0xD3, 0x01, 0x63, 0xAC, 0x86, 0x07, 0xF2, 0x0E, 0x03,
+	 0xD0, 0x80, 0x09, 0xF2, 0xFA, 0x02, 0x23, 0xFC, 0x1E, 0x60, 0xF2, 0x64, 0x0F, 0x60, 0x8D, 0xFB,
+	 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x3C, 0x46, 0x06, 0x64,
+	 0xA1, 0xFF, 0x49, 0xFB, 0x83, 0x3E, 0x31, 0xF3, 0x87, 0x60, 0x80, 0x61, 0x1D, 0xF0, 0x60, 0x40,
+	 0x01, 0x2A, 0x0F, 0x00, 0xFE, 0xB4, 0x31, 0xFB, 0x00, 0x64, 0x49, 0xFB, 0x01, 0x64, 0x47, 0xFB,
+	 0x00, 0x71, 0x05, 0x64, 0x64, 0x5F, 0x0D, 0xFA, 0x40, 0x64, 0x3B, 0xDB, 0xC0, 0x60, 0x35, 0x78,
+	 0xFF, 0xFF, 0x02, 0x2A, 0x17, 0x00, 0xD1, 0x91, 0x8D, 0xE2, 0x41, 0x64, 0x3B, 0xDB, 0x31, 0xF3,
+	 0x2C, 0x60, 0x5E, 0x63, 0xFD, 0xB4, 0x31, 0xFB, 0xA3, 0xD3, 0x02, 0x63, 0x60, 0x5C, 0x0D, 0xF2,
+	 0x47, 0xFD, 0xFF, 0xB5, 0x60, 0x47, 0xD0, 0x80, 0xDC, 0x84, 0x1F, 0x03, 0x60, 0x47, 0xB4, 0x84,
+	 0x0D, 0xFA, 0x1B, 0x00, 0x08, 0x2A, 0x07, 0x00, 0x42, 0x64, 0x3B, 0xDB, 0x31, 0xF3, 0xFF, 0xFF,
+	 0xF7, 0xB4, 0x31, 0xFB, 0x12, 0x00, 0x10, 0x2A, 0x09, 0x00, 0x43, 0x64, 0x3B, 0xDB, 0x31, 0xF3,
+	 0xFF, 0xFF, 0xEF, 0xB4, 0x31, 0xFB, 0xBF, 0x60, 0xBB, 0x78, 0xFF, 0xFF, 0x44, 0x64, 0x3B, 0xDB,
+	 0x31, 0xF3, 0xFF, 0xFF, 0xDF, 0xB4, 0x31, 0xFB, 0x00, 0x00, 0x2A, 0x64, 0x3B, 0xDB, 0xB7, 0x60,
+	 0xA2, 0x64, 0x40, 0x40, 0xBD, 0x60, 0x7D, 0x78, 0xFF, 0xFF, 0x0A, 0x60, 0x80, 0xF3, 0xFF, 0xFF,
+	 0x02, 0xB5, 0x04, 0xB5, 0x04, 0x03, 0x03, 0x03, 0xC0, 0x60, 0xB8, 0x78, 0xFF, 0xFF, 0xF0, 0x60,
+	 0x58, 0x4E, 0x74, 0x78, 0xFF, 0xFF, 0x31, 0x40, 0x01, 0x2A, 0x28, 0x00, 0x9D, 0xFE, 0x26, 0x04,
+	 0x25, 0x0A, 0x9F, 0xFE, 0x23, 0x05, 0x85, 0xFF, 0x20, 0x44, 0x84, 0xFF, 0x40, 0x26, 0x1E, 0x00,
+	 0x3F, 0x40, 0x20, 0x2B, 0x1B, 0x00, 0x38, 0x69, 0xFF, 0xFF, 0x68, 0x44, 0x01, 0x16, 0xFD, 0x01,
+	 0x01, 0x2A, 0x14, 0x00, 0x13, 0x60, 0x09, 0xF3, 0xFF, 0xFF, 0xDC, 0x84, 0x00, 0x36, 0x00, 0x3B,
+	 0xA2, 0xDB, 0x64, 0xF1, 0x02, 0x60, 0xEE, 0x64, 0x81, 0xFB, 0xFF, 0xFF, 0x80, 0x60, 0x00, 0x64,
+	 0xB0, 0x84, 0x82, 0xFB, 0x04, 0x64, 0x83, 0xFB, 0xDF, 0xFE, 0x19, 0xFF, 0x10, 0x64, 0x3B, 0xDB,
+	 0x65, 0xF3, 0x73, 0x45, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xC4, 0x93, 0x74, 0xF1, 0xC9, 0xFE,
+	 0x64, 0x40, 0x01, 0x26, 0x3B, 0x00, 0x49, 0xF3, 0x3C, 0x46, 0x31, 0x18, 0xCC, 0x84, 0x49, 0xFB,
+	 0x2E, 0x02, 0xC1, 0x60, 0x6B, 0x64, 0x40, 0x42, 0xFC, 0xFC, 0x00, 0x64, 0x5C, 0x5C, 0x32, 0xFB,
+	 0x82, 0xFF, 0x5C, 0x47, 0x84, 0xFF, 0x62, 0xFF, 0x13, 0x60, 0x01, 0xF3, 0xFF, 0xFF, 0xDC, 0x84,
+	 0x00, 0x36, 0x00, 0x3B, 0xA2, 0xDB, 0x2A, 0xF2, 0x07, 0xF0, 0x0C, 0xB4, 0x08, 0x3A, 0x07, 0x00,
+	 0x66, 0x41, 0x64, 0x46, 0x06, 0xF0, 0xFF, 0x60, 0xDF, 0x64, 0xA0, 0x84, 0x06, 0xFA, 0x23, 0xF0,
+	 0x01, 0x64, 0xB0, 0x84, 0xA2, 0xDA, 0x1E, 0x60, 0xF2, 0x64, 0x0F, 0x60, 0x8D, 0xFB, 0x66, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0xCE, 0xFE, 0x06, 0x00,
+	 0x65, 0xF3, 0x73, 0x45, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xC4, 0x93, 0x14, 0x60, 0xFC, 0x63,
+	 0xA3, 0xD3, 0xAD, 0x49, 0x20, 0xB5, 0x08, 0xB1, 0x22, 0x03, 0xE1, 0x81, 0x10, 0xB5, 0x95, 0x81,
+	 0x60, 0x41, 0x18, 0x02, 0x14, 0x60, 0xFE, 0x7C, 0xA4, 0xD3, 0xFF, 0xFF, 0xCC, 0x84, 0xA4, 0xDB,
+	 0x16, 0x02, 0x0A, 0x64, 0xA4, 0xDB, 0x61, 0x44, 0x07, 0xB4, 0xFF, 0xFF, 0x10, 0x02, 0x08, 0xB1,
+	 0xE1, 0x81, 0x95, 0x81, 0xA3, 0xD3, 0x0B, 0x03, 0x08, 0xAC, 0x01, 0xBC, 0xA3, 0xDB, 0xFF, 0xFF,
+	 0x13, 0xFF, 0x05, 0x00, 0x10, 0xAC, 0xA3, 0xDB, 0x0A, 0x7C, 0x0A, 0x60, 0x7F, 0xF9, 0xB7, 0x60,
+	 0xAE, 0x78, 0xFF, 0xFF, 0x46, 0xF3, 0x45, 0xF1, 0x04, 0x1B, 0x64, 0x44, 0x02, 0x1B, 0x07, 0x60,
+	 0xF7, 0xF3, 0x45, 0xFB, 0x00, 0x63, 0x46, 0xFD, 0x60, 0x41, 0x25, 0x64, 0x3B, 0xDB, 0x27, 0x44,
+	 0xEF, 0xB4, 0x40, 0x47, 0x00, 0xB9, 0x71, 0x40, 0x80, 0x27, 0x01, 0x12, 0x19, 0x03, 0xC1, 0x60,
+	 0x0C, 0x62, 0x84, 0xFF, 0x42, 0x42, 0x82, 0xFF, 0xA0, 0x4C, 0x14, 0xBC, 0xFF, 0xB4, 0xA0, 0x51,
+	 0x1F, 0x0A, 0xA1, 0xFF, 0xFF, 0xFF, 0x81, 0x3E, 0x70, 0x44, 0xAC, 0x80, 0x19, 0x0A, 0x71, 0x40,
+	 0x80, 0x27, 0xF7, 0x12, 0x45, 0xF3, 0x27, 0x02, 0x03, 0x18, 0xCC, 0x84, 0x45, 0xFB, 0xF1, 0x02,
+	 0x06, 0x0A, 0xA0, 0x4C, 0xFB, 0xB4, 0xA0, 0x51, 0xA4, 0x60, 0xD7, 0x78, 0xFF, 0xFF, 0x84, 0xFF,
+	 0xC0, 0x60, 0xEA, 0x64, 0x40, 0x42, 0x82, 0xFF, 0xA0, 0x4C, 0x14, 0xBC, 0xFF, 0xB4, 0xA0, 0x51,
+	 0xAF, 0x60, 0x7B, 0x78, 0xFF, 0xFF, 0x3C, 0x44, 0xAC, 0x80, 0x32, 0xF1, 0x12, 0x03, 0x64, 0x40,
+	 0x07, 0x22, 0x0F, 0x00, 0xA4, 0x60, 0xB6, 0x78, 0xFF, 0xFF, 0xA0, 0x4C, 0x1C, 0xBC, 0xDF, 0xB4,
+	 0xA0, 0x51, 0xF1, 0x01, 0x06, 0x00, 0x28, 0x64, 0x3A, 0xDB, 0xA0, 0x4C, 0x30, 0xBC, 0xF3, 0xB4,
+	 0xA0, 0x51, 0xA1, 0xFF, 0xFF, 0xFF, 0x81, 0x3E, 0x28, 0x64, 0x3B, 0xDB, 0x07, 0x60, 0xF8, 0xF3,
+	 0x32, 0x40, 0x02, 0x27, 0x16, 0x00, 0x46, 0xFB, 0x14, 0x18, 0xC1, 0x60, 0x59, 0x64, 0x84, 0xFF,
+	 0x40, 0x42, 0x82, 0xFF, 0xA0, 0x4C, 0x15, 0xBC, 0xF7, 0xB4, 0xA0, 0x51, 0xA1, 0xFF, 0xFF, 0xFF,
+	 0x81, 0x3E, 0x70, 0x44, 0xAC, 0x80, 0x46, 0xF3, 0xCB, 0x0A, 0xDD, 0x02, 0xCC, 0x84, 0x46, 0xFB,
+	 0xF5, 0x02, 0x84, 0xFF, 0xC1, 0x60, 0x6B, 0x64, 0x40, 0x42, 0x82, 0xFF, 0x27, 0x44, 0x08, 0xBC,
+	 0x40, 0x47, 0xF9, 0xE1, 0x04, 0x00, 0x78, 0xE1, 0x31, 0x40, 0x01, 0x26, 0xF9, 0xE1, 0xA4, 0x60,
+	 0xAA, 0x78, 0xFF, 0xFF, 0x15, 0x60, 0xFB, 0xF1, 0x60, 0x45, 0x2C, 0x60, 0x0A, 0x61, 0xC5, 0x83,
+	 0xA3, 0xD3, 0xFF, 0xFF, 0x60, 0x41, 0x66, 0x45, 0x24, 0x46, 0x0E, 0xF2, 0x65, 0x46, 0x64, 0x45,
+	 0xD5, 0x81, 0x61, 0x45, 0x00, 0x7F, 0xD4, 0x80, 0x64, 0x43, 0x08, 0x04, 0xE3, 0x83, 0x63, 0x45,
+	 0xC5, 0x81, 0x61, 0x45, 0xD4, 0x80, 0x02, 0x65, 0x03, 0x07, 0x03, 0x00, 0x00, 0x65, 0x01, 0x00,
+	 0x01, 0x65, 0x2E, 0x58, 0xFF, 0xFF, 0x66, 0x43, 0x64, 0x46, 0x8F, 0xF0, 0x12, 0xF2, 0x91, 0xF2,
+	 0x60, 0x40, 0x10, 0x36, 0x05, 0x00, 0x12, 0x36, 0x08, 0x00, 0x0C, 0x36, 0x0B, 0x00, 0x0F, 0x00,
+	 0x40, 0x61, 0xA5, 0x80, 0x0A, 0x64, 0x13, 0x02, 0xF3, 0x01, 0x10, 0x61, 0xA5, 0x80, 0x0E, 0x64,
+	 0x0E, 0x02, 0xEE, 0x01, 0x08, 0x61, 0xA5, 0x80, 0x10, 0x64, 0x09, 0x02, 0xE9, 0x01, 0xE1, 0x81,
+	 0xA5, 0x80, 0x03, 0x05, 0xC8, 0x84, 0x03, 0x02, 0xE3, 0x01, 0xFF, 0x61, 0x02, 0x00, 0x12, 0xFA,
+	 0x91, 0xFA, 0x63, 0x46, 0x2E, 0x58, 0xFF, 0xFF, 0x8F, 0xF0, 0x12, 0xF2, 0x91, 0xF2, 0x60, 0x40,
+	 0x0A, 0x36, 0x05, 0x00, 0x0E, 0x36, 0x08, 0x00, 0x10, 0x36, 0x0B, 0x00, 0x0F, 0x00, 0x08, 0x61,
+	 0xA5, 0x80, 0x10, 0x7E, 0x11, 0x02, 0xF3, 0x01, 0x04, 0x61, 0xA5, 0x80, 0x12, 0x7E, 0x0C, 0x02,
+	 0xEE, 0x01, 0x20, 0x61, 0xA5, 0x80, 0x0C, 0x7E, 0x07, 0x02, 0xE9, 0x01, 0xE9, 0x81, 0xA5, 0x80,
+	 0x05, 0x05, 0xD8, 0x84, 0x01, 0x02, 0xE3, 0x01, 0x12, 0xFA, 0x91, 0xFA, 0x2E, 0x58, 0xFF, 0xFF,
+	 0x24, 0xE2, 0x2D, 0xF3, 0x2C, 0xF3, 0x00, 0xBD, 0xCC, 0x84, 0x08, 0x03, 0x2C, 0xFB, 0x06, 0x02,
+	 0x65, 0x44, 0x2C, 0xFB, 0x8A, 0xFF, 0x80, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x44, 0xF3, 0xFF, 0xFF,
+	 0xDC, 0x84, 0x44, 0xFB, 0x28, 0x60, 0x72, 0x65, 0x28, 0x60, 0x70, 0x61, 0xA5, 0xD3, 0xA1, 0xD3,
+	 0x11, 0x18, 0xCC, 0x84, 0xA1, 0xDB, 0x0E, 0x02, 0xA5, 0xD3, 0xA1, 0xDB, 0x14, 0x60, 0x3B, 0xF3,
+	 0x14, 0x60, 0x3A, 0xF1, 0xA2, 0xDB, 0xD0, 0x80, 0xFF, 0xFF, 0x04, 0x03, 0x8A, 0xFF, 0x20, 0x60,
+	 0x00, 0x75, 0x88, 0xFF, 0xD2, 0xF3, 0x31, 0x40, 0x01, 0x2A, 0x3D, 0x00, 0x60, 0x43, 0x04, 0xB0,
+	 0x02, 0xB0, 0x08, 0x24, 0x16, 0x02, 0x10, 0xB0, 0x29, 0x44, 0x34, 0x02, 0x00, 0xA8, 0xCC, 0x81,
+	 0x0D, 0x03, 0x41, 0x49, 0x2F, 0x02, 0x63, 0x40, 0x08, 0x2A, 0x08, 0x00, 0xF7, 0xB3, 0x18, 0x60,
+	 0x0A, 0xF1, 0xAD, 0x4F, 0xFD, 0xB4, 0xA0, 0x5D, 0x44, 0x49, 0x24, 0x00, 0x63, 0x40, 0x02, 0x2A,
+	 0x10, 0x00, 0x18, 0x60, 0x0B, 0xF3, 0x18, 0x60, 0x09, 0xFB, 0x40, 0x49, 0x18, 0x60, 0x0C, 0xF3,
+	 0x18, 0x60, 0x0A, 0xFB, 0x0C, 0xBB, 0xFD, 0xB3, 0xAD, 0x4F, 0x02, 0xBC, 0x00, 0x7F, 0xA0, 0x5D,
+	 0x11, 0x00, 0x18, 0x60, 0x0D, 0xF3, 0x30, 0x60, 0x12, 0x7C, 0x0C, 0x18, 0xA4, 0xDB, 0x40, 0x49,
+	 0x18, 0x60, 0x0E, 0xF3, 0x18, 0x60, 0x0A, 0xFB, 0x08, 0xBB, 0xFB, 0xB3, 0xAD, 0x4F, 0x02, 0xBC,
+	 0x00, 0x7F, 0xA0, 0x5D, 0xD2, 0xFD, 0x00, 0x60, 0x85, 0xF3, 0x62, 0x43, 0x17, 0x18, 0x58, 0xD3,
+	 0x62, 0x41, 0x03, 0x18, 0xCC, 0x84, 0xA1, 0xDB, 0x11, 0x00, 0x49, 0xD3, 0xA3, 0xDB, 0x06, 0xA1,
+	 0xA1, 0xD3, 0x59, 0xD1, 0x60, 0x45, 0xA5, 0xD3, 0x59, 0xD1, 0xB0, 0x84, 0xA5, 0xDB, 0x64, 0x44,
+	 0x06, 0x36, 0xCD, 0xFE, 0x07, 0x36, 0xD6, 0xFE, 0xE6, 0x01, 0x23, 0x46, 0xB7, 0x60, 0xAE, 0x78,
+	 0xFF, 0xFF, 0x46, 0x43, 0x1F, 0x60, 0x44, 0x61, 0xA1, 0xD3, 0x59, 0xD1, 0x06, 0x1B, 0x59, 0xD3,
+	 0x59, 0xD1, 0x03, 0x1B, 0x59, 0xD3, 0x59, 0xD1, 0xF0, 0x18, 0x00, 0x63, 0x49, 0xDD, 0x60, 0x40,
+	 0x02, 0x36, 0x11, 0x00, 0x03, 0x36, 0x32, 0x00, 0x01, 0x36, 0x08, 0x00, 0x05, 0x3A, 0xEA, 0x01,
+	 0xA4, 0xD3, 0x5A, 0xD3, 0x9C, 0x85, 0xA4, 0x84, 0xA2, 0xDB, 0xE4, 0x01, 0x01, 0x60, 0x0A, 0x61,
+	 0x00, 0x64, 0xA1, 0xDB, 0xDF, 0x01, 0xC2, 0x60, 0x8F, 0x64, 0x40, 0x45, 0x22, 0x00, 0x01, 0x60,
+	 0x0A, 0x66, 0xA6, 0xD3, 0x04, 0xA1, 0x60, 0x43, 0xA1, 0xD3, 0xC9, 0x81, 0x60, 0x45, 0x00, 0xBB,
+	 0xA1, 0xDB, 0xBE, 0xD3, 0x09, 0x03, 0xD4, 0x84, 0x9C, 0x84, 0xDC, 0x84, 0xFF, 0xFF, 0x04, 0x0E,
+	 0xA3, 0xD1, 0x63, 0x46, 0x64, 0x43, 0xF2, 0x01, 0x9C, 0x84, 0xDC, 0x85, 0x49, 0xDD, 0x61, 0x44,
+	 0x00, 0xBB, 0xA6, 0xDB, 0x02, 0x03, 0x65, 0x44, 0xBE, 0xDB, 0xBC, 0x01, 0xC2, 0x60, 0x6A, 0x64,
+	 0x40, 0x45, 0x01, 0x60, 0x0A, 0x66, 0xA6, 0xD3, 0xFF, 0xFF, 0xD0, 0x80, 0x0F, 0x18, 0x02, 0x03,
+	 0x60, 0x46, 0xF9, 0x01, 0x58, 0xD3, 0xA4, 0xD3, 0x60, 0x45, 0x00, 0x63, 0xA4, 0xDD, 0x05, 0x18,
+	 0x58, 0xD3, 0xFF, 0xFF, 0xC4, 0x83, 0xA2, 0xDD, 0xCA, 0x84, 0xA6, 0xDB, 0x25, 0x58, 0x64, 0x41,
+	 0x04, 0x60, 0x40, 0x62, 0x1A, 0x60, 0x58, 0x4D, 0xB4, 0x78, 0xFF, 0xFF, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x64, 0x40, 0x01, 0x2B, 0x50, 0x00, 0x28, 0x40, 0x08, 0x3A, 0x4D, 0x00, 0xE8, 0x84, 0xE8, 0x84,
+	 0xE8, 0x84, 0xE8, 0x84, 0x15, 0x60, 0xD5, 0xFB, 0x64, 0xF1, 0x24, 0x60, 0x88, 0x63, 0x64, 0x40,
+	 0x01, 0x27, 0x3C, 0xA3, 0x29, 0x40, 0x40, 0x2B, 0x1E, 0xA3, 0xBD, 0xD1, 0x63, 0x45, 0x44, 0x4E,
+	 0x0E, 0x61, 0xBD, 0xD1, 0xCD, 0x81, 0xD0, 0x80, 0x01, 0x03, 0xFB, 0x04, 0xCB, 0x83, 0x15, 0x60,
+	 0xD8, 0xF3, 0x39, 0xF1, 0xD7, 0x83, 0xEB, 0x83, 0x2E, 0x41, 0x5D, 0x93, 0xDF, 0x83, 0x15, 0x60,
+	 0xD4, 0xFD, 0x15, 0x60, 0xD3, 0xFB, 0x53, 0x93, 0xDF, 0x80, 0x10, 0x03, 0x38, 0xF3, 0xCF, 0x83,
+	 0x08, 0x03, 0xDF, 0x83, 0x0B, 0x02, 0xDF, 0x83, 0xDC, 0x84, 0xF0, 0xA0, 0x38, 0xFB, 0x06, 0x03,
+	 0x03, 0x00, 0xCC, 0x84, 0x38, 0xFB, 0x02, 0x03, 0x00, 0x63, 0x02, 0x00, 0x08, 0x64, 0x38, 0xFB,
+	 0xE3, 0x80, 0xFB, 0x83, 0xC3, 0x83, 0x63, 0x44, 0xFC, 0xA0, 0x02, 0x0E, 0x08, 0x07, 0x08, 0x00,
+	 0x04, 0xA4, 0xFF, 0xFF, 0x05, 0x0D, 0xFC, 0x64, 0xFF, 0x7F, 0x60, 0x43, 0x01, 0x00, 0x04, 0x63,
+	 0x39, 0xFD, 0x15, 0x60, 0xD7, 0xFD, 0x2F, 0x58, 0xFF, 0xFF, 0x15, 0x60, 0xD2, 0xF3, 0x40, 0x4E,
+	 0x60, 0x46, 0x2F, 0xDB, 0x44, 0x44, 0xA1, 0xD3, 0xD9, 0x81, 0x48, 0x94, 0x24, 0x5C, 0xD0, 0x9C,
+	 0x66, 0x42, 0x04, 0x06, 0xD2, 0x9C, 0x2F, 0xD9, 0x64, 0x46, 0x24, 0x44, 0xE0, 0x84, 0x44, 0xD3,
+	 0xA3, 0xDB, 0xFF, 0xB4, 0x60, 0x5C, 0x66, 0x44, 0x22, 0xA4, 0xD0, 0x84, 0xE0, 0xA0, 0x02, 0x0D,
+	 0x00, 0x64, 0x02, 0x00, 0x01, 0x04, 0x1F, 0x64, 0xA2, 0xD3, 0x60, 0x5C, 0x64, 0x5E, 0x60, 0x47,
+	 0x2F, 0xD1, 0x28, 0xA3, 0xA3, 0xD9, 0xD8, 0xA3, 0x2E, 0x42, 0x4E, 0x8E, 0xBD, 0xDB, 0xDB, 0x02,
+	 0x2D, 0x58, 0xFF, 0xFF, 0x43, 0xFF, 0x39, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x84, 0x3E, 0xFB, 0x01,
+	 0x3D, 0x44, 0x00, 0xA8, 0xFF, 0xFF, 0x03, 0x02, 0x40, 0xFF, 0x44, 0xFF, 0xF4, 0x01, 0xA0, 0x4C,
+	 0x3D, 0x46, 0x2A, 0xF2, 0x46, 0x4D, 0x10, 0x25, 0x12, 0x00, 0x09, 0xE1, 0xA1, 0xFF, 0x2D, 0x46,
+	 0x0F, 0xF2, 0x01, 0x29, 0x06, 0x00, 0x2A, 0xF0, 0x40, 0xFF, 0x64, 0x40, 0x40, 0x2B, 0x08, 0xBC,
+	 0x02, 0xBC, 0x0F, 0xFA, 0x08, 0x25, 0xDE, 0x01, 0xCB, 0xFE, 0x5C, 0x5D, 0xDC, 0x01, 0x44, 0xFF,
+	 0x03, 0x2B, 0x21, 0x00, 0x88, 0xF3, 0x06, 0x61, 0x60, 0x43, 0x66, 0x45, 0x31, 0xF0, 0x63, 0x46,
+	 0x05, 0xF2, 0x65, 0x46, 0xD0, 0x80, 0x30, 0xF0, 0x0F, 0x02, 0x63, 0x46, 0x04, 0xF2, 0x65, 0x46,
+	 0xD0, 0x80, 0x2F, 0xF0, 0x09, 0x02, 0x63, 0x46, 0x03, 0xF2, 0x65, 0x46, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x03, 0x02, 0xFF, 0xFF, 0x48, 0xFE, 0x06, 0x00, 0xCD, 0x81, 0x02, 0xA3, 0xE7, 0x02, 0x87, 0xF1,
+	 0x08, 0xFE, 0x64, 0x43, 0x26, 0x03, 0x31, 0xF2, 0x15, 0x60, 0x02, 0x65, 0x60, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46,
+	 0x31, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46, 0x30, 0xF0, 0x63, 0x46,
+	 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46, 0x2F, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46, 0xE8, 0x1B, 0x87, 0xF3, 0x08, 0xFE, 0x60, 0x43,
+	 0x61, 0x46, 0x07, 0xFC, 0x3F, 0xF2, 0x09, 0x60, 0xB0, 0x65, 0xD4, 0x80, 0x2A, 0xF2, 0x9D, 0x05,
+	 0x08, 0x25, 0x88, 0x01, 0x5C, 0x4B, 0x0C, 0x60, 0xEC, 0x61, 0xA1, 0xDF, 0x2D, 0x46, 0x3B, 0xF2,
+	 0x87, 0xF1, 0x87, 0xF4, 0x60, 0x40, 0x20, 0x2B, 0xB7, 0x00, 0xD3, 0x80, 0x2C, 0xF0, 0x8D, 0x03,
+	 0x07, 0xF4, 0x64, 0x40, 0x01, 0x26, 0x87, 0xF5, 0xBA, 0xF4, 0x2D, 0x46, 0x04, 0x64, 0x04, 0xB3,
+	 0x22, 0xF0, 0x04, 0x03, 0xC5, 0x60, 0xBD, 0x78, 0xFF, 0xFF, 0xA6, 0x00, 0x10, 0x64, 0xB0, 0x9C,
+	 0x3B, 0xF2, 0x22, 0xF8, 0x60, 0x47, 0xC0, 0xB7, 0x02, 0xFE, 0xF0, 0x84, 0xF0, 0x84, 0xF0, 0x84,
+	 0x00, 0xA8, 0x40, 0x4A, 0x17, 0x03, 0xE0, 0x81, 0x61, 0x43, 0x42, 0xFE, 0x00, 0x64, 0xF0, 0x84,
+	 0xFE, 0x1F, 0x40, 0x4A, 0xE1, 0x84, 0xE0, 0x84, 0x2D, 0x46, 0x07, 0xF4, 0xE0, 0x81, 0x3B, 0xF0,
+	 0x2A, 0x47, 0x0C, 0x60, 0x3A, 0x63, 0xA0, 0x84, 0x47, 0x9C, 0x10, 0x03, 0x7C, 0x44, 0x00, 0x60,
+	 0xB2, 0x63, 0x14, 0x00, 0x07, 0xF4, 0x3B, 0xF0, 0x66, 0x44, 0x64, 0x40, 0x80, 0x2B, 0x06, 0x00,
+	 0x00, 0x60, 0x78, 0x7C, 0x00, 0x60, 0xA2, 0x63, 0x43, 0x4C, 0x08, 0x00, 0x2D, 0x46, 0xC5, 0x60,
+	 0xB0, 0x78, 0xFF, 0xFF, 0x2D, 0x46, 0xC5, 0x60, 0xB0, 0x78, 0xFF, 0xFF, 0xCE, 0xFB, 0xCF, 0xF9,
+	 0xD0, 0xFD, 0xAD, 0x46, 0x3D, 0xF2, 0xAD, 0x46, 0xA3, 0xD0, 0xAD, 0x46, 0xD0, 0x80, 0x3C, 0xF2,
+	 0xAD, 0x46, 0x02, 0x03, 0x15, 0x07, 0xEE, 0x04, 0x5B, 0xD0, 0xAD, 0x46, 0xD0, 0x80, 0x3A, 0xF2,
+	 0x03, 0x03, 0xAD, 0x46, 0x0D, 0x07, 0xE6, 0x04, 0x3A, 0xF0, 0xAD, 0x46, 0x5B, 0xD0, 0x64, 0x44,
+	 0xD0, 0x80, 0x2B, 0x44, 0x05, 0x07, 0xDE, 0x03, 0xD0, 0x84, 0x10, 0xA4, 0xFF, 0xFF, 0x00, 0x07,
+	 0xCF, 0xF3, 0xCE, 0xF5, 0xFE, 0xA4, 0x0F, 0x60, 0xC0, 0x61, 0x0E, 0x63, 0x58, 0xD0, 0x59, 0xD9,
+	 0xFD, 0x1F, 0x2D, 0x46, 0x8B, 0xFF, 0x2D, 0x46, 0x0F, 0x60, 0xB2, 0x64, 0xC9, 0x60, 0x58, 0x4F,
+	 0x10, 0x78, 0xFF, 0xFF, 0x3F, 0xF2, 0x00, 0x60, 0x18, 0x70, 0x18, 0x71, 0x20, 0x72, 0x60, 0x53,
+	 0x88, 0x75, 0x00, 0xF2, 0x09, 0xE1, 0x60, 0x50, 0x12, 0x71, 0x6E, 0x72, 0x83, 0x75, 0xA1, 0xFF,
+	 0xFF, 0xFF, 0x08, 0x25, 0x1F, 0x00, 0x40, 0xFF, 0x02, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x75, 0x40,
+	 0x03, 0x2A, 0x03, 0x00, 0x80, 0x75, 0x0A, 0x64, 0x0B, 0x00, 0x80, 0x75, 0x1B, 0xF3, 0x8B, 0xFF,
+	 0x02, 0x60, 0x00, 0x75, 0xFF, 0xFF, 0x02, 0x60, 0x00, 0x75, 0xDC, 0x84, 0xA2, 0xDB, 0x02, 0x64,
+	 0x98, 0xFF, 0x2D, 0x46, 0x0F, 0xF0, 0xFF, 0xFF, 0xB0, 0x84, 0xA2, 0xDA, 0x88, 0xFF, 0xC3, 0x60,
+	 0x74, 0x78, 0xFF, 0xFF, 0x8B, 0xFF, 0x02, 0x60, 0x00, 0x75, 0xFF, 0xFF, 0x02, 0x60, 0x00, 0x75,
+	 0x88, 0xFF, 0xC5, 0x60, 0x96, 0x78, 0xFF, 0xFF, 0x22, 0xF0, 0x22, 0x64, 0xB0, 0x84, 0x22, 0xFA,
+	 0x3A, 0xF0, 0xFF, 0xFF, 0x64, 0x44, 0xE0, 0x7F, 0xA0, 0x5B, 0x64, 0x47, 0xE1, 0x7F, 0x5A, 0xD0,
+	 0xA0, 0x5B, 0x64, 0x44, 0xE2, 0x7F, 0xA0, 0x5B, 0x64, 0x47, 0x7C, 0x5F, 0xE8, 0x84, 0xE8, 0x85,
+	 0x0D, 0x60, 0x02, 0x64, 0x44, 0xD3, 0x5A, 0xD1, 0x03, 0x1B, 0xC5, 0x60, 0xB0, 0x78, 0xFF, 0xFF,
+	 0x60, 0x45, 0x64, 0x44, 0xE3, 0x7F, 0xA0, 0x5B, 0x64, 0x47, 0xE4, 0x7F, 0x5A, 0xD1, 0xA0, 0x5B,
+	 0x64, 0x44, 0xE5, 0x7F, 0xA0, 0x5B, 0x64, 0x47, 0xE6, 0x7F, 0x5A, 0xD1, 0xA0, 0x5B, 0x64, 0x44,
+	 0xE7, 0x7F, 0xA0, 0x5B, 0x65, 0x40, 0x0D, 0x3A, 0x1C, 0x00, 0x64, 0x47, 0xE8, 0x7F, 0x5A, 0xD1,
+	 0xA0, 0x5B, 0x64, 0x44, 0xE9, 0x7F, 0xA0, 0x5B, 0x64, 0x47, 0xEA, 0x7F, 0x5A, 0xD1, 0xA0, 0x5B,
+	 0x64, 0x44, 0xEB, 0x7F, 0xA0, 0x5B, 0x64, 0x47, 0xEC, 0x7F, 0x5A, 0xD1, 0xA0, 0x5B, 0x64, 0x44,
+	 0xED, 0x7F, 0xA0, 0x5B, 0x64, 0x47, 0xEE, 0x7F, 0x5A, 0xD1, 0xA0, 0x5B, 0x64, 0x44, 0xEF, 0x7F,
+	 0xA0, 0x5B, 0x65, 0x44, 0xD8, 0x84, 0x08, 0x25, 0xB9, 0x00, 0x60, 0x7F, 0xA0, 0x5B, 0x80, 0x60,
+	 0x00, 0xEB, 0xA0, 0x60, 0x00, 0xEB, 0xD1, 0x60, 0x00, 0xEB, 0x3F, 0xF2, 0x3B, 0xF0, 0x60, 0x43,
+	 0xFC, 0xA4, 0x64, 0x40, 0x20, 0x2B, 0x03, 0x00, 0x08, 0xA4, 0x3F, 0xFA, 0x08, 0xA3, 0xF8, 0xA3,
+	 0x3F, 0xFA, 0x0A, 0xE1, 0xB3, 0xFF, 0x9A, 0xFF, 0xCB, 0x83, 0x00, 0xF4, 0x10, 0x62, 0x6C, 0x61,
+	 0x0E, 0xA3, 0xAB, 0x84, 0xF2, 0xA3, 0xA1, 0xFF, 0x08, 0x00, 0x00, 0xF4, 0x81, 0xF2, 0x6C, 0x18,
+	 0x02, 0x62, 0xC9, 0x81, 0xAB, 0x84, 0x01, 0x00, 0xA2, 0xDC, 0x7A, 0xD4, 0xFD, 0x1C, 0xA2, 0xDC,
+	 0x08, 0x25, 0x8C, 0x00, 0xF2, 0x1D, 0x41, 0x44, 0x7C, 0xA8, 0xD9, 0x81, 0xEE, 0x03, 0xFF, 0xB1,
+	 0x98, 0xFF, 0x09, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x08, 0x25, 0x80, 0x00, 0x40, 0xFF, 0x42, 0x42,
+	 0x46, 0x43, 0x06, 0x1E, 0x04, 0x02, 0x00, 0xF4, 0x02, 0x62, 0x42, 0x42, 0x46, 0x43, 0x01, 0xA2,
+	 0x63, 0x45, 0x01, 0xA2, 0x62, 0x43, 0x46, 0x4C, 0xC6, 0x60, 0x58, 0x4F, 0x4B, 0x78, 0xFF, 0xFF,
+	 0x0A, 0xE1, 0x9A, 0xFF, 0x24, 0x41, 0x02, 0xA1, 0x65, 0x43, 0x08, 0xA3, 0x23, 0x46, 0x22, 0x42,
+	 0x7E, 0x3A, 0x0A, 0x00, 0x00, 0xF4, 0x81, 0xF2, 0x37, 0x18, 0x02, 0x62, 0xC9, 0x81, 0xAB, 0x84,
+	 0x03, 0x00, 0xA2, 0xDC, 0x7E, 0x36, 0xF6, 0x01, 0x7A, 0xD4, 0xFF, 0xFF, 0xFA, 0x1C, 0xA2, 0xDC,
+	 0xF1, 0x1D, 0xD9, 0x81, 0xFF, 0xB1, 0x0B, 0x1E, 0x62, 0x40, 0x7E, 0x3A, 0x02, 0x00, 0x00, 0xF4,
+	 0x02, 0x62, 0x5A, 0xD2, 0x89, 0xFF, 0x80, 0x4F, 0x6F, 0x44, 0xA2, 0xDA, 0x88, 0xFF, 0x98, 0xFF,
+	 0x3D, 0x46, 0x0F, 0xF0, 0x0A, 0x64, 0xB0, 0x84, 0x18, 0x14, 0xF7, 0xB4, 0xA2, 0xDA, 0x06, 0x60,
+	 0x76, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x2A, 0x0C, 0x00, 0xD1, 0xF5, 0xD0, 0xF4, 0x0C, 0x60,
+	 0xEC, 0x61, 0x59, 0xD1, 0x3B, 0xF8, 0x05, 0x64, 0x59, 0xD1, 0xCC, 0x84, 0xBD, 0xD8, 0xFC, 0x02,
+	 0x2D, 0x46, 0xC3, 0x60, 0x74, 0x78, 0xFF, 0xFF, 0x28, 0x00, 0xA2, 0xDA, 0x2D, 0x46, 0x3B, 0xF0,
+	 0xFF, 0xFF, 0x64, 0x40, 0x20, 0x2B, 0x1E, 0x00, 0x07, 0xF4, 0xBB, 0xF0, 0x2A, 0x44, 0xA4, 0x84,
+	 0xFF, 0xFF, 0x2F, 0x26, 0x16, 0x00, 0x2D, 0x46, 0x64, 0x44, 0x3A, 0xF0, 0xBC, 0xF0, 0x64, 0x5F,
+	 0x3D, 0xF0, 0x07, 0xF4, 0xD0, 0xF4, 0xFF, 0xFF, 0x08, 0xA3, 0x5B, 0xD8, 0x65, 0x5C, 0x5B, 0xD8,
+	 0x5B, 0xDA, 0x2D, 0x46, 0xCE, 0xF3, 0x3C, 0xFA, 0xCF, 0xF3, 0x3D, 0xFA, 0x2A, 0x44, 0x23, 0xFA,
+	 0x01, 0x00, 0x2D, 0x46, 0xC3, 0x60, 0x74, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0x98, 0xFF, 0x43, 0xFF,
+	 0x40, 0xFF, 0xB0, 0xFF, 0xB1, 0xFF, 0x2D, 0x46, 0x0C, 0x60, 0xEC, 0x61, 0xA1, 0xD3, 0x2D, 0x46,
+	 0x60, 0x40, 0x01, 0x2A, 0x0A, 0x00, 0xD1, 0xF5, 0xD0, 0xF4, 0x59, 0xD1, 0x3B, 0xF8, 0x05, 0x64,
+	 0x59, 0xD1, 0xCC, 0x84, 0xBD, 0xD8, 0xFC, 0x02, 0x2D, 0x46, 0xC3, 0x60, 0x53, 0x78, 0xFF, 0xFF,
+	 0x98, 0xFF, 0x09, 0xE1, 0xA1, 0xFF, 0x3D, 0x46, 0x08, 0x25, 0xE0, 0x01, 0x0F, 0xF2, 0x40, 0xFF,
+	 0x02, 0xBC, 0xA2, 0xDA, 0xC3, 0x60, 0x74, 0x78, 0xFF, 0xFF, 0xB0, 0x84, 0x22, 0xFA, 0x00, 0x63,
+	 0x3B, 0xF2, 0x06, 0x60, 0x76, 0xFD, 0x60, 0x47, 0xC0, 0xB7, 0x02, 0xFE, 0xF0, 0x84, 0xF0, 0x84,
+	 0xF0, 0x84, 0x00, 0xA8, 0x40, 0x4A, 0x16, 0x03, 0xE0, 0x81, 0x61, 0x43, 0x42, 0xFE, 0x00, 0x64,
+	 0xF0, 0x84, 0xFE, 0x1F, 0x40, 0x4A, 0xE1, 0x84, 0xE0, 0x84, 0x2D, 0x46, 0x07, 0xF4, 0xE0, 0x81,
+	 0x3B, 0xF0, 0x2A, 0x47, 0x0C, 0x60, 0x3A, 0x63, 0xA0, 0x84, 0x47, 0x9C, 0x10, 0x03, 0x7C, 0x44,
+	 0xA8, 0x63, 0x0F, 0x00, 0x07, 0xF4, 0x20, 0x64, 0x40, 0x4A, 0x3B, 0xF0, 0x66, 0x44, 0x64, 0x40,
+	 0x80, 0x2B, 0x05, 0x00, 0x00, 0x60, 0x78, 0x7C, 0x00, 0x60, 0x98, 0x63, 0x02, 0x00, 0x2D, 0x46,
+	 0xBF, 0x01, 0x2D, 0x46, 0xCE, 0xFB, 0xCF, 0xF9, 0xD0, 0xFD, 0x07, 0xF2, 0xD1, 0xFB, 0x60, 0x46,
+	 0x3B, 0xF0, 0x2A, 0x44, 0x06, 0x60, 0x77, 0xF9, 0x5C, 0x4B, 0xA0, 0x84, 0xFF, 0xFF, 0x3F, 0x22,
+	 0x05, 0x00, 0x90, 0x84, 0x3B, 0xFA, 0x01, 0x64, 0x40, 0x4B, 0x21, 0x00, 0xAD, 0x46, 0x0A, 0xA3,
+	 0x3D, 0xF2, 0xAD, 0x46, 0xA3, 0xD0, 0xAD, 0x46, 0xD0, 0x80, 0x3C, 0xF2, 0xAD, 0x46, 0x02, 0x03,
+	 0x16, 0x07, 0x14, 0x04, 0x5B, 0xD0, 0xAD, 0x46, 0xD0, 0x80, 0x3B, 0xF2, 0x03, 0x03, 0xAD, 0x46,
+	 0x0E, 0x07, 0x0C, 0x04, 0x3A, 0xF0, 0xAD, 0x46, 0x5B, 0xD0, 0x64, 0x5F, 0xD0, 0x80, 0x2B, 0x44,
+	 0x17, 0x07, 0x04, 0x03, 0xD0, 0x84, 0x10, 0xA4, 0xFF, 0xFF, 0x12, 0x07, 0x89, 0x01, 0x01, 0x64,
+	 0x06, 0x60, 0x76, 0xFB, 0x2D, 0x46, 0x0C, 0x60, 0xFC, 0x62, 0x80, 0xFF, 0x78, 0x44, 0x03, 0xA4,
+	 0xA2, 0xDB, 0xC6, 0x60, 0x76, 0x78, 0xFF, 0xFF, 0x85, 0xFF, 0x2D, 0x46, 0x08, 0x25, 0x5E, 0x01,
+	 0x2D, 0x46, 0x0C, 0x60, 0xFC, 0x62, 0x80, 0xFF, 0x78, 0x44, 0x03, 0xA4, 0xA2, 0xDB, 0xC6, 0x60,
+	 0xFE, 0x78, 0xFF, 0xFF, 0x85, 0xFF, 0x2D, 0x46, 0x08, 0x25, 0x50, 0x01, 0x00, 0x60, 0x0F, 0x64,
+	 0xC4, 0x60, 0xDB, 0x78, 0xFF, 0xFF, 0x2D, 0x46, 0x3B, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x20, 0x2B,
+	 0x23, 0x00, 0x00, 0xF4, 0x08, 0x61, 0x2D, 0x46, 0x00, 0xF4, 0x0A, 0x62, 0x56, 0x92, 0x5A, 0xD0,
+	 0x2C, 0x46, 0x64, 0x47, 0x63, 0x40, 0x7F, 0x2A, 0x03, 0x00, 0x00, 0xF4, 0x03, 0x63, 0x46, 0x4C,
+	 0x60, 0xFE, 0xDE, 0xD8, 0x7F, 0x3A, 0x03, 0x00, 0x00, 0xF4, 0x03, 0x63, 0x46, 0x4C, 0xDE, 0xDA,
+	 0xFE, 0xA1, 0x20, 0xFE, 0xE8, 0x02, 0x63, 0x41, 0xFD, 0xA1, 0x46, 0x4C, 0x01, 0xF2, 0x2D, 0x46,
+	 0x61, 0x5E, 0x16, 0xFA, 0x2C, 0x44, 0x06, 0xFA, 0x2F, 0x58, 0xFF, 0xFF, 0x07, 0xF4, 0x66, 0x41,
+	 0x03, 0xF2, 0x04, 0xF2, 0x40, 0x42, 0x05, 0xF2, 0x40, 0x43, 0x40, 0x44, 0x61, 0x46, 0x3C, 0xF2,
+	 0x3D, 0xF2, 0x40, 0x40, 0x40, 0x41, 0x0D, 0x60, 0x72, 0x65, 0x00, 0x61, 0xCF, 0xF1, 0xCE, 0xF5,
+	 0x44, 0x4C, 0x2C, 0x5C, 0xE9, 0x80, 0x00, 0x64, 0xF0, 0x84, 0xF0, 0x84, 0xC0, 0x83, 0xBD, 0xD2,
+	 0x24, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x20, 0x44, 0x40, 0x80, 0xDB, 0x83, 0xBD, 0xD2,
+	 0x20, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x21, 0x44, 0x40, 0x81, 0xDB, 0x83, 0xBD, 0xD2,
+	 0x21, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x22, 0x44, 0x40, 0x82, 0xDB, 0x83, 0xBD, 0xD2,
+	 0x22, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x23, 0x44, 0x40, 0x83, 0xF2, 0xA3, 0xBD, 0xD2,
+	 0x23, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x24, 0x44, 0xC0, 0x9C, 0x41, 0x84, 0xDD, 0x81,
+	 0x08, 0x2A, 0xA7, 0x01, 0x0C, 0x60, 0xEE, 0x61, 0x05, 0x64, 0xD0, 0xF4, 0xD1, 0xF5, 0xFE, 0xA3,
+	 0x5B, 0xD0, 0xCC, 0x84, 0x59, 0xD9, 0xFC, 0x02, 0xD0, 0xF3, 0xD1, 0xF5, 0x60, 0x42, 0x20, 0x44,
+	 0xA2, 0xDA, 0x21, 0x44, 0x5A, 0xDA, 0x22, 0x44, 0x5A, 0xDA, 0x23, 0x44, 0x5A, 0xDA, 0x24, 0x44,
+	 0x5A, 0xDA, 0x61, 0x46, 0x06, 0x60, 0x7E, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x41, 0xD0, 0xF3,
+	 0xD1, 0xF5, 0xA0, 0xD2, 0x5A, 0xD0, 0x40, 0x40, 0x44, 0x41, 0x5A, 0xD2, 0x5A, 0xD0, 0x40, 0x42,
+	 0x5A, 0xD0, 0x44, 0x43, 0x61, 0x46, 0xBA, 0xF0, 0x3B, 0xF2, 0x44, 0x44, 0x65, 0x5F, 0x40, 0x85,
+	 0xCF, 0xF4, 0xCE, 0xF5, 0x43, 0x4C, 0x0D, 0x60, 0x72, 0x65, 0xBD, 0xD2, 0x25, 0x5C, 0x90, 0x9C,
+	 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1,
+	 0x64, 0x47, 0x90, 0x9C, 0x20, 0x44, 0x40, 0x80, 0xBD, 0xD2, 0x20, 0x5C, 0x90, 0x9C, 0x64, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47,
+	 0x90, 0x9C, 0x21, 0x44, 0x40, 0x81, 0xBD, 0xD2, 0x21, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C,
+	 0x22, 0x44, 0x40, 0x82, 0xBD, 0xD2, 0x22, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84,
+	 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x23, 0x44,
+	 0x40, 0x83, 0xBD, 0xD2, 0x23, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1,
+	 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x24, 0x44, 0x40, 0x84,
+	 0xBD, 0xD2, 0x24, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x25, 0x44, 0x40, 0x85, 0x61, 0x46,
+	 0x3A, 0xF0, 0xFF, 0xFF, 0x64, 0x44, 0xE0, 0x7F, 0xA0, 0x5B, 0x64, 0x47, 0xE1, 0x7F, 0x5A, 0xD0,
+	 0xA0, 0x5B, 0x64, 0x44, 0xE2, 0x7F, 0xA0, 0x5B, 0x64, 0x47, 0xCE, 0xF5, 0xBD, 0xD2, 0x25, 0x5C,
+	 0x90, 0x84, 0xE8, 0x80, 0xF8, 0x84, 0x20, 0x5C, 0x40, 0x80, 0x20, 0x44, 0xE4, 0x7F, 0xA0, 0x5B,
+	 0x20, 0x47, 0xE5, 0x7F, 0xA0, 0x5B, 0xBD, 0xD2, 0x20, 0x5C, 0x90, 0x84, 0xE8, 0x80, 0xF8, 0x84,
+	 0x21, 0x5C, 0x40, 0x81, 0x21, 0x44, 0xE6, 0x7F, 0xA0, 0x5B, 0x21, 0x47, 0xE7, 0x7F, 0xA0, 0x5B,
+	 0x21, 0x44, 0xE8, 0x80, 0xF8, 0x84, 0x22, 0x5C, 0x40, 0x82, 0x22, 0x44, 0xE8, 0x7F, 0xA0, 0x5B,
+	 0x22, 0x47, 0xE9, 0x7F, 0xA0, 0x5B, 0x22, 0x44, 0xE8, 0x80, 0xF8, 0x84, 0x23, 0x5C, 0x40, 0x83,
+	 0x23, 0x44, 0xEA, 0x7F, 0xA0, 0x5B, 0x23, 0x47, 0xEB, 0x7F, 0xA0, 0x5B, 0x23, 0x44, 0xE8, 0x80,
+	 0xF8, 0x84, 0x24, 0x5C, 0x40, 0x84, 0x24, 0x44, 0xEC, 0x7F, 0xA0, 0x5B, 0x24, 0x47, 0xED, 0x7F,
+	 0xA0, 0x5B, 0x24, 0x44, 0xE8, 0x80, 0xF8, 0x84, 0x25, 0x5C, 0x40, 0x85, 0x25, 0x44, 0xEE, 0x7F,
+	 0xA0, 0x5B, 0x25, 0x47, 0xEF, 0x7F, 0xA0, 0x5B, 0x2C, 0x43, 0xA3, 0xD2, 0x25, 0x5C, 0x90, 0x81,
+	 0xE9, 0x84, 0xE3, 0x7F, 0xA0, 0x5B, 0x06, 0x60, 0x7E, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xCB, 0xF3,
+	 0x5A, 0xD3, 0x40, 0x48, 0x5A, 0xD3, 0x40, 0x49, 0x40, 0x4A, 0x00, 0x60, 0x78, 0x7C, 0x44, 0x4D,
+	 0x49, 0xF2, 0x4A, 0xF2, 0x40, 0x47, 0x40, 0x46, 0x0D, 0x60, 0x72, 0x65, 0x00, 0x61, 0x2D, 0x5C,
+	 0xE9, 0x80, 0x00, 0x64, 0xF0, 0x84, 0xF0, 0x84, 0xC0, 0x83, 0xBD, 0xD2, 0x2A, 0x5C, 0x90, 0x9C,
+	 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1,
+	 0x64, 0x47, 0x90, 0x9C, 0x26, 0x44, 0x40, 0x86, 0xDB, 0x83, 0xBD, 0xD2, 0x26, 0x5C, 0x90, 0x9C,
+	 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1,
+	 0x64, 0x47, 0x90, 0x9C, 0x27, 0x44, 0x40, 0x87, 0xDB, 0x83, 0xBD, 0xD2, 0x27, 0x5C, 0x90, 0x9C,
+	 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1,
+	 0x64, 0x47, 0x90, 0x9C, 0x28, 0x44, 0x40, 0x88, 0xDB, 0x83, 0xBD, 0xD2, 0x28, 0x5C, 0x90, 0x9C,
+	 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1,
+	 0x64, 0x47, 0x90, 0x9C, 0x29, 0x44, 0x40, 0x89, 0xF2, 0xA3, 0xBD, 0xD2, 0x29, 0x5C, 0x90, 0x9C,
+	 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1,
+	 0x64, 0x47, 0x90, 0x9C, 0x2A, 0x44, 0xC0, 0x9C, 0x41, 0x8A, 0xDD, 0x81, 0x08, 0x2A, 0xA7, 0x01,
+	 0x26, 0x44, 0x44, 0xFA, 0x27, 0x44, 0x45, 0xFA, 0x28, 0x44, 0x46, 0xFA, 0x29, 0x44, 0x47, 0xFA,
+	 0x2A, 0x44, 0x48, 0xFA, 0x06, 0x60, 0x7F, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x60, 0x88, 0x7C,
+	 0x44, 0x4D, 0x2D, 0x42, 0xA2, 0xD2, 0x5A, 0xD0, 0x40, 0x46, 0x44, 0x47, 0x5A, 0xD2, 0x5A, 0xD0,
+	 0x40, 0x48, 0x5A, 0xD0, 0x44, 0x49, 0x4B, 0xF2, 0x44, 0x4A, 0x40, 0x8B, 0x60, 0x5C, 0x64, 0x47,
+	 0xE0, 0x7F, 0xA0, 0x5A, 0xFF, 0xB4, 0x20, 0xBC, 0x7F, 0xB4, 0xE1, 0x7F, 0xA0, 0x5A, 0x64, 0x44,
+	 0xE2, 0x7F, 0xA0, 0x5A, 0x00, 0x60, 0x78, 0x63, 0x0D, 0x60, 0x72, 0x65, 0xBD, 0xD2, 0x2B, 0x5C,
+	 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84,
+	 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x26, 0x44, 0x40, 0x86, 0xBD, 0xD2, 0x26, 0x5C, 0x90, 0x9C,
+	 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1,
+	 0x64, 0x47, 0x90, 0x9C, 0x27, 0x44, 0x40, 0x87, 0xBD, 0xD2, 0x27, 0x5C, 0x90, 0x9C, 0x64, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47,
+	 0x90, 0x9C, 0x28, 0x44, 0x40, 0x88, 0xBD, 0xD2, 0x28, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C,
+	 0x29, 0x44, 0x40, 0x89, 0xBD, 0xD2, 0x29, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84,
+	 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x2A, 0x44,
+	 0x40, 0x8A, 0xBD, 0xD2, 0x2A, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1,
+	 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x2B, 0x44, 0x40, 0x8B,
+	 0xBD, 0xD2, 0x2B, 0x5C, 0x90, 0x84, 0xE8, 0x80, 0xF8, 0x84, 0x26, 0x5C, 0x40, 0x86, 0x26, 0x44,
+	 0xE4, 0x7F, 0xA0, 0x5A, 0x26, 0x47, 0xE5, 0x7F, 0xA0, 0x5A, 0xBD, 0xD2, 0x26, 0x5C, 0x90, 0x84,
+	 0xE8, 0x80, 0xF8, 0x84, 0x27, 0x5C, 0x40, 0x87, 0x27, 0x44, 0xE6, 0x7F, 0xA0, 0x5A, 0x27, 0x47,
+	 0xE7, 0x7F, 0xA0, 0x5A, 0x27, 0x44, 0xE8, 0x80, 0xF8, 0x84, 0x28, 0x5C, 0x40, 0x88, 0x28, 0x44,
+	 0xE8, 0x7F, 0xA0, 0x5A, 0x28, 0x47, 0xE9, 0x7F, 0xA0, 0x5A, 0x28, 0x44, 0xE8, 0x80, 0xF8, 0x84,
+	 0x29, 0x5C, 0x40, 0x89, 0x29, 0x44, 0xEA, 0x7F, 0xA0, 0x5A, 0x29, 0x47, 0xEB, 0x7F, 0xA0, 0x5A,
+	 0x29, 0x44, 0xE8, 0x80, 0xF8, 0x84, 0x2A, 0x5C, 0x40, 0x8A, 0x2A, 0x44, 0xEC, 0x7F, 0xA0, 0x5A,
+	 0x2A, 0x47, 0xED, 0x7F, 0xA0, 0x5A, 0x2A, 0x44, 0xE8, 0x80, 0xF8, 0x84, 0x2B, 0x5C, 0x40, 0x8B,
+	 0x2B, 0x44, 0xEE, 0x7F, 0xA0, 0x5A, 0x2B, 0x47, 0xEF, 0x7F, 0xA0, 0x5A, 0x3C, 0xF0, 0x2B, 0x44,
+	 0x90, 0x84, 0xE8, 0x84, 0xE3, 0x7F, 0xA0, 0x5A, 0x06, 0x60, 0x7F, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x60, 0x45, 0x00, 0xF0, 0x84, 0x60, 0x00, 0xE3, 0x04, 0x71, 0x64, 0x50, 0x01, 0x2A, 0x04, 0x71,
+	 0x5C, 0x61, 0x04, 0x63, 0x59, 0xD0, 0x58, 0xD9, 0xFD, 0x1F, 0x3D, 0xF2, 0x60, 0x43, 0x60, 0x47,
+	 0x5B, 0xDB, 0x3C, 0xF2, 0xFF, 0xFF, 0x60, 0x47, 0x5B, 0xDB, 0x3A, 0xF2, 0xFF, 0xFF, 0x60, 0x47,
+	 0x5B, 0xDB, 0x3F, 0xF2, 0xFF, 0xFF, 0x60, 0x47, 0x5B, 0xDB, 0x81, 0x60, 0x18, 0xE3, 0x65, 0x43,
+	 0xE3, 0x84, 0x60, 0x47, 0x00, 0x7F, 0x60, 0x50, 0x7F, 0x64, 0x23, 0x94, 0x60, 0x51, 0x7C, 0x72,
+	 0x04, 0x75, 0x0C, 0x60, 0x16, 0x61, 0x16, 0x60, 0x00, 0x63, 0x59, 0xDD, 0x2A, 0xF2, 0x87, 0x60,
+	 0x8F, 0x65, 0xA4, 0x87, 0x40, 0xBF, 0x59, 0xDB, 0x56, 0x64, 0x0A, 0x63, 0x58, 0xD0, 0x59, 0xD9,
+	 0xFD, 0x1F, 0x62, 0x64, 0x04, 0x63, 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0x35, 0xF2, 0x0F, 0x65,
+	 0xA4, 0x9C, 0x59, 0xD9, 0x06, 0x63, 0x59, 0xDF, 0xFE, 0x1F, 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x45,
+	 0x03, 0x2B, 0x05, 0x00, 0x6A, 0x64, 0x04, 0x63, 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0x65, 0x40,
+	 0x8F, 0xB0, 0x88, 0x3A, 0x02, 0x00, 0x39, 0xF0, 0x59, 0xD9, 0x2F, 0x58, 0xFF, 0xFF, 0x0C, 0x60,
+	 0x16, 0x61, 0xA3, 0x46, 0x00, 0xF4, 0x02, 0x64, 0x0A, 0x63, 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F,
+	 0x59, 0xDF, 0x59, 0xDF, 0xA0, 0x4C, 0x04, 0xBC, 0xFF, 0xB4, 0xA0, 0x51, 0x23, 0x44, 0x01, 0xA7,
+	 0x80, 0xBF, 0x60, 0x50, 0x80, 0x60, 0x38, 0x71, 0x80, 0x60, 0x7C, 0x72, 0x01, 0x76, 0xFF, 0xFF,
+	 0x76, 0x44, 0x01, 0x3A, 0xFD, 0x01, 0x40, 0x76, 0x42, 0xFF, 0xFF, 0xFF, 0x40, 0x76, 0x80, 0x60,
+	 0x18, 0x70, 0x80, 0x60, 0x18, 0x71, 0x80, 0x60, 0x7C, 0x72, 0x80, 0x60, 0x10, 0x73, 0x02, 0x76,
+	 0x76, 0x44, 0xFF, 0xFF, 0x76, 0x44, 0x02, 0x3A, 0xFD, 0x01, 0x40, 0x76, 0x42, 0xFF, 0x3C, 0x46,
+	 0x00, 0xF2, 0x80, 0x60, 0x00, 0xBC, 0x60, 0x50, 0x80, 0x60, 0x12, 0x71, 0x80, 0x60, 0x6E, 0x72,
+	 0x3F, 0xF2, 0xFF, 0xFF, 0xF8, 0xA7, 0x80, 0xBF, 0x60, 0x53, 0x04, 0x76, 0xFF, 0xFF, 0x88, 0xFF,
+	 0x3C, 0x46, 0x07, 0xF2, 0xFF, 0xFF, 0x40, 0x43, 0xA3, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x77, 0x40,
+	 0x8B, 0xFF, 0xA0, 0x4C, 0x04, 0xE1, 0xFF, 0xFF, 0x76, 0x44, 0x04, 0x3A, 0xFD, 0x01, 0x40, 0x76,
+	 0x42, 0xFF, 0xFF, 0xFF, 0x10, 0x76, 0xFF, 0xFF, 0x76, 0x44, 0x20, 0x3A, 0xFD, 0x01, 0x40, 0x76,
+	 0x42, 0xFF, 0xA0, 0x48, 0x00, 0x7F, 0xA0, 0x51, 0x02, 0x60, 0x00, 0x75, 0x88, 0xFF, 0xA0, 0x4C,
+	 0xFB, 0xB4, 0xA0, 0x51, 0x06, 0x60, 0x1F, 0xE1, 0x16, 0xFF, 0x2F, 0x58, 0xFF, 0xFF, 0x26, 0x46,
+	 0x3F, 0xF2, 0xFF, 0xFF, 0xF8, 0xA4, 0x3F, 0xFA, 0x00, 0xF4, 0x60, 0x47, 0x08, 0xFA, 0xA0, 0x48,
+	 0x08, 0x26, 0x07, 0x00, 0xA0, 0x4C, 0x04, 0xE1, 0xFF, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0x00, 0x7F,
+	 0xA0, 0x51, 0x42, 0xFF, 0x26, 0x46, 0x8B, 0xFF, 0x02, 0x60, 0x00, 0x75, 0x3C, 0xF2, 0x40, 0x76,
+	 0x14, 0x1B, 0x26, 0x46, 0x3B, 0xF2, 0x0C, 0x60, 0xBC, 0x63, 0x60, 0x47, 0xC0, 0xB4, 0xE8, 0x84,
+	 0xE8, 0x84, 0xE8, 0x84, 0x43, 0x93, 0xE3, 0x9C, 0x64, 0x47, 0x80, 0x7C, 0x64, 0x5F, 0x60, 0x50,
+	 0x7F, 0x64, 0x23, 0x97, 0x80, 0xBF, 0x60, 0x51, 0x07, 0x00, 0x01, 0xA7, 0x80, 0xBF, 0x60, 0x50,
+	 0x80, 0x60, 0x40, 0x71, 0x80, 0x60, 0x7C, 0x72, 0x01, 0x76, 0xFF, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF,
+	 0x0C, 0x21, 0xFC, 0x01, 0x04, 0x25, 0xD5, 0x01, 0x40, 0x76, 0x43, 0xFF, 0x0C, 0x60, 0x22, 0x61,
+	 0x26, 0x46, 0x00, 0xF4, 0x02, 0x64, 0x0A, 0x63, 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0x59, 0xDF,
+	 0x59, 0xDF, 0x80, 0x60, 0x18, 0x70, 0x80, 0x60, 0x24, 0x71, 0x80, 0x60, 0x7C, 0x72, 0x80, 0x60,
+	 0x10, 0x73, 0x02, 0x76, 0xFF, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0x0C, 0x21, 0xFC, 0x01, 0x04, 0x25,
+	 0xB8, 0x01, 0x40, 0x76, 0x43, 0xFF, 0x26, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0x60, 0x47, 0x80, 0xBF,
+	 0x60, 0x50, 0x80, 0x60, 0x12, 0x71, 0x3F, 0xF2, 0x80, 0x60, 0x6E, 0x72, 0x60, 0x47, 0x80, 0xBF,
+	 0x60, 0x53, 0x04, 0x76, 0xFF, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0x0C, 0x21, 0xFC, 0x01, 0x04, 0x25,
+	 0xA0, 0x01, 0x40, 0x76, 0x43, 0xFF, 0x08, 0x76, 0xFF, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0x0C, 0x21,
+	 0xFC, 0x01, 0x04, 0x25, 0x96, 0x01, 0x76, 0x5C, 0xFF, 0xFF, 0x40, 0x76, 0x43, 0xFF, 0x88, 0xFF,
+	 0x26, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0xDF, 0x60, 0x2A, 0x78, 0xFF, 0xFF, 0x08, 0x60, 0x11, 0xF1,
+	 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x20, 0x00, 0x74, 0xF3, 0x31, 0x40,
+	 0x01, 0x2A, 0x1C, 0x00, 0xDC, 0x84, 0x01, 0xB4, 0x74, 0xFB, 0x08, 0x02, 0x08, 0x60, 0x12, 0xF1,
+	 0x00, 0x60, 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x10, 0x00, 0x08, 0x60, 0x18, 0xF1,
+	 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x08, 0x00, 0xA9, 0xFE, 0xE6, 0x05,
+	 0xAB, 0xFE, 0x07, 0x05, 0xA8, 0xFE, 0xD7, 0x05, 0xAA, 0xFE, 0xD8, 0x05, 0xA1, 0xFF, 0xFF, 0xFF,
+	 0x85, 0x3E, 0x0F, 0x60, 0x85, 0xF3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x03, 0x02, 0xCA, 0x60,
+	 0x7E, 0x78, 0xFF, 0xFF, 0x26, 0x45, 0xD4, 0x80, 0x0F, 0xF0, 0xF9, 0x03, 0x64, 0x44, 0x70, 0xB0,
+	 0x70, 0x2A, 0x13, 0x00, 0x13, 0x60, 0x08, 0xF3, 0xFF, 0xFF, 0xDC, 0x84, 0x00, 0x36, 0x00, 0x3B,
+	 0xA2, 0xDB, 0xA2, 0xFF, 0x8E, 0xF3, 0xFF, 0xFF, 0xCC, 0x84, 0xFE, 0xA0, 0x8E, 0xFB, 0x01, 0x07,
+	 0xD4, 0xFE, 0xA3, 0xFF, 0xCE, 0x60, 0x38, 0x78, 0xFF, 0xFF, 0x64, 0x40, 0x02, 0x26, 0x09, 0x00,
+	 0x66, 0x45, 0x09, 0xF4, 0x0F, 0xF2, 0x02, 0x18, 0x65, 0x46, 0xE4, 0x1B, 0x00, 0x64, 0x40, 0x46,
+	 0xCD, 0x01, 0xA2, 0xFF, 0x8E, 0xF3, 0x46, 0x46, 0xCC, 0x84, 0xFE, 0xA0, 0x8E, 0xFB, 0x01, 0x07,
+	 0xD4, 0xFE, 0xA3, 0xFF, 0x0F, 0xF0, 0xA3, 0xFC, 0x64, 0x44, 0x80, 0x26, 0x17, 0x00, 0x25, 0x60,
+	 0xF0, 0x64, 0xE5, 0x60, 0x78, 0x41, 0xC7, 0x78, 0x97, 0xF1, 0x32, 0x44, 0x01, 0x2A, 0x03, 0x00,
+	 0x07, 0x60, 0x01, 0x64, 0x04, 0x00, 0x02, 0x2A, 0x06, 0x00, 0x00, 0x60, 0x01, 0x64, 0x23, 0xFA,
+	 0xCE, 0x60, 0x44, 0x78, 0xFF, 0xFF, 0xCE, 0x60, 0x38, 0x78, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF,
+	 0x64, 0x44, 0x08, 0x26, 0x34, 0x00, 0x2A, 0xF2, 0x60, 0x63, 0x60, 0x40, 0x02, 0x2B, 0x66, 0x63,
+	 0xBE, 0xD2, 0x68, 0xF1, 0xA3, 0xD2, 0xD0, 0x80, 0x67, 0xF1, 0x0D, 0x02, 0xBF, 0xD2, 0xD0, 0x80,
+	 0x66, 0xF1, 0x09, 0x02, 0xD0, 0x80, 0xFF, 0xFF, 0x06, 0x02, 0x25, 0x60, 0xFC, 0x64, 0xE5, 0x60,
+	 0x78, 0x41, 0xC7, 0x78, 0x97, 0xF1, 0x32, 0x44, 0x01, 0x2A, 0x03, 0x00, 0x07, 0x60, 0x02, 0x64,
+	 0x04, 0x00, 0x02, 0x2A, 0x06, 0x00, 0x00, 0x60, 0x02, 0x64, 0x23, 0xFA, 0xCE, 0x60, 0x44, 0x78,
+	 0xFF, 0xFF, 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0xB0, 0x3A, 0x06, 0x00, 0x00, 0x60, 0x02, 0x64,
+	 0x23, 0xFA, 0xCB, 0x60, 0x9D, 0x78, 0xFF, 0xFF, 0xCE, 0x60, 0x38, 0x78, 0xFF, 0xFF, 0x32, 0x44,
+	 0x01, 0x2A, 0x4A, 0x00, 0x27, 0x60, 0x6A, 0x63, 0xBF, 0xD3, 0x00, 0x65, 0xB4, 0x81, 0xDB, 0x83,
+	 0x3D, 0x03, 0xBF, 0xD3, 0xA3, 0xD3, 0x40, 0x48, 0xBE, 0xD3, 0x40, 0x4A, 0x2E, 0xF0, 0x40, 0x4C,
+	 0xD0, 0x80, 0x2D, 0xF0, 0x08, 0x02, 0x2A, 0x44, 0xD0, 0x80, 0x2C, 0xF0, 0x04, 0x02, 0x28, 0x44,
+	 0xD0, 0x80, 0xFF, 0xFF, 0x2B, 0x03, 0x31, 0xF0, 0x2C, 0x44, 0xD0, 0x80, 0x30, 0xF0, 0x08, 0x02,
+	 0x2A, 0x44, 0xD0, 0x80, 0x2F, 0xF0, 0x04, 0x02, 0x28, 0x44, 0xD0, 0x80, 0xFF, 0xFF, 0x1E, 0x03,
+	 0x34, 0xF0, 0x2C, 0x44, 0xD0, 0x80, 0x33, 0xF0, 0x08, 0x02, 0x2A, 0x44, 0xD0, 0x80, 0x32, 0xF0,
+	 0x04, 0x02, 0x28, 0x44, 0xD0, 0x80, 0xFF, 0xFF, 0x11, 0x03, 0x38, 0xF0, 0x2C, 0x44, 0xD0, 0x80,
+	 0x37, 0xF0, 0x08, 0x02, 0x2A, 0x44, 0xD0, 0x80, 0x36, 0xF0, 0x04, 0x02, 0x28, 0x44, 0xD0, 0x80,
+	 0xFF, 0xFF, 0x04, 0x03, 0xFA, 0xA1, 0x06, 0xA3, 0xB7, 0x03, 0xC3, 0x01, 0x07, 0x60, 0x00, 0x64,
+	 0x23, 0xFA, 0xCE, 0x60, 0x44, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0x0F, 0xF0, 0x60, 0x45, 0xA4, 0x36,
+	 0x08, 0x00, 0x0C, 0xB4, 0x04, 0x36, 0x02, 0x00, 0x0C, 0x3A, 0x06, 0x00, 0xCE, 0x60, 0x38, 0x78,
+	 0xFF, 0xFF, 0xCC, 0x60, 0x35, 0x78, 0xFF, 0xFF, 0x26, 0xF2, 0x50, 0xF1, 0x60, 0x47, 0x00, 0x7E,
+	 0xD0, 0x84, 0x1F, 0xA4, 0x06, 0x0E, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84,
+	 0x07, 0x00, 0xC2, 0xA4, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x87, 0xF8, 0xBF,
+	 0xC0, 0x84, 0xA2, 0xDB, 0x0F, 0xF0, 0x65, 0x40, 0x40, 0x2B, 0x17, 0x00, 0x32, 0x40, 0x08, 0x26,
+	 0x14, 0x00, 0x07, 0xF4, 0x3A, 0xF2, 0xFF, 0xFF, 0x37, 0xB4, 0x26, 0x46, 0x0E, 0x02, 0x2C, 0xF2,
+	 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x26, 0x06, 0x00, 0x25, 0x60, 0xF6, 0x64, 0xE5, 0x60, 0x78, 0x41,
+	 0xC7, 0x78, 0x97, 0xF1, 0xCE, 0x60, 0x38, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0x64, 0x40, 0x60, 0x26,
+	 0x03, 0x00, 0xCC, 0x60, 0x0D, 0x78, 0xFF, 0xFF, 0x60, 0x40, 0x40, 0x3A, 0xF3, 0x01, 0x25, 0x60,
+	 0xEA, 0x64, 0xE5, 0x60, 0x78, 0x41, 0xC7, 0x78, 0x97, 0xF1, 0x27, 0xF2, 0xFF, 0xFF, 0x60, 0x40,
+	 0x01, 0x3B, 0x07, 0x00, 0x25, 0x60, 0xF8, 0x64, 0xE5, 0x60, 0x78, 0x41, 0xC7, 0x78, 0x97, 0xF1,
+	 0x08, 0x00, 0x02, 0x3B, 0x06, 0x00, 0x25, 0x60, 0xFA, 0x64, 0xE5, 0x60, 0x78, 0x41, 0xC7, 0x78,
+	 0x97, 0xF1, 0x2A, 0xF2, 0x28, 0x41, 0x40, 0xA8, 0x01, 0xB1, 0x02, 0x02, 0x43, 0x02, 0x6D, 0x00,
+	 0x60, 0x40, 0x08, 0x2A, 0x0F, 0x00, 0x25, 0x60, 0xE8, 0x64, 0xE5, 0x60, 0x78, 0x41, 0xC7, 0x78,
+	 0x97, 0xF1, 0x1B, 0xF2, 0xFF, 0xFF, 0x60, 0x45, 0x25, 0x60, 0xEE, 0x64, 0xE5, 0x60, 0x78, 0x41,
+	 0xD3, 0x78, 0x97, 0xF1, 0x0F, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x40, 0x26, 0x28, 0x00, 0x32, 0x44,
+	 0x02, 0x26, 0x25, 0x00, 0x10, 0x2B, 0x26, 0x00, 0x27, 0x60, 0x6A, 0x63, 0xBF, 0xD3, 0x2C, 0xF0,
+	 0x00, 0xA8, 0x60, 0x41, 0x0D, 0x03, 0x50, 0xFE, 0xBD, 0xD3, 0x2D, 0xF0, 0xD0, 0x80, 0xBD, 0xD3,
+	 0x2E, 0xF0, 0xD0, 0x80, 0xBD, 0xD3, 0x2C, 0xF0, 0xD0, 0x80, 0xFA, 0xA1, 0x10, 0x0C, 0xF3, 0x02,
+	 0x50, 0xFE, 0x60, 0x60, 0x01, 0x64, 0xD0, 0x80, 0x2D, 0xF0, 0x1D, 0x64, 0xD0, 0x80, 0x2E, 0xF0,
+	 0x01, 0x64, 0xD0, 0x80, 0xFF, 0xFF, 0x03, 0x0C, 0xCE, 0x60, 0x38, 0x78, 0xFF, 0xFF, 0x32, 0x40,
+	 0x40, 0x2A, 0x00, 0x00, 0xCD, 0x60, 0xEE, 0x78, 0xFF, 0xFF, 0x32, 0x40, 0x40, 0x26, 0xFA, 0x01,
+	 0x2A, 0xF0, 0xFF, 0xFF, 0x64, 0x40, 0x08, 0x2A, 0x20, 0x00, 0x32, 0x40, 0x02, 0x2A, 0x1D, 0x00,
+	 0x03, 0x67, 0xA0, 0x84, 0x00, 0x37, 0x64, 0x63, 0x60, 0x40, 0x02, 0x37, 0x5E, 0x63, 0x60, 0x40,
+	 0x01, 0x37, 0x58, 0x63, 0x60, 0x40, 0x03, 0x37, 0x0D, 0x00, 0xBD, 0xD2, 0x66, 0xF1, 0xBD, 0xD2,
+	 0xD0, 0x80, 0x67, 0xF1, 0x07, 0x02, 0xD0, 0x80, 0xBD, 0xD2, 0x68, 0xF1, 0x03, 0x02, 0xD0, 0x80,
+	 0xFF, 0xFF, 0x03, 0x03, 0xCE, 0x60, 0x38, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0x87, 0xF4, 0x60, 0x40,
+	 0x03, 0x2B, 0x31, 0x00, 0x88, 0xF3, 0x06, 0x61, 0x60, 0x43, 0x66, 0x45, 0x31, 0xF0, 0x63, 0x46,
+	 0x05, 0xF2, 0x65, 0x46, 0xD0, 0x80, 0x30, 0xF0, 0x0F, 0x02, 0x63, 0x46, 0x04, 0xF2, 0x65, 0x46,
+	 0xD0, 0x80, 0x2F, 0xF0, 0x09, 0x02, 0x63, 0x46, 0x03, 0xF2, 0x65, 0x46, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x03, 0x02, 0xFF, 0xFF, 0x48, 0xFE, 0x06, 0x00, 0xCD, 0x81, 0x02, 0xA3, 0xE7, 0x02, 0x87, 0xF1,
+	 0x08, 0xFE, 0x64, 0x43, 0x03, 0x03, 0xCE, 0x60, 0x38, 0x78, 0xFF, 0xFF, 0x43, 0x43, 0x23, 0x46,
+	 0x06, 0xF0, 0x26, 0x46, 0x07, 0x67, 0xA0, 0x84, 0x23, 0xFA, 0x64, 0x40, 0x02, 0x26, 0x2B, 0x00,
+	 0xCE, 0x60, 0x38, 0x78, 0xFF, 0xFF, 0x26, 0x1B, 0x31, 0xF2, 0x15, 0x60, 0x02, 0x65, 0x60, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18,
+	 0x61, 0x46, 0x31, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46, 0x30, 0xF0,
+	 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46, 0x2F, 0xF0, 0x63, 0x46, 0xD0, 0x80,
+	 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46, 0xE8, 0x1B, 0x87, 0xF3, 0x08, 0xFE,
+	 0x60, 0x43, 0x61, 0x46, 0x43, 0x43, 0x07, 0xFC, 0x43, 0x43, 0x1D, 0xF0, 0xC0, 0x64, 0xC0, 0x84,
+	 0x0A, 0x60, 0x7B, 0xF1, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xC0, 0x84,
+	 0xA2, 0xDB, 0x63, 0x45, 0x2A, 0xF2, 0x35, 0xF0, 0x60, 0x40, 0xA4, 0x36, 0x0B, 0x00, 0x08, 0x2B,
+	 0x0C, 0x00, 0x23, 0x46, 0x26, 0xF2, 0x26, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x06, 0x02, 0xCE, 0x60,
+	 0x38, 0x78, 0xFF, 0xFF, 0xCD, 0x60, 0xEE, 0x78, 0xFF, 0xFF, 0x23, 0x46, 0x22, 0xF2, 0x26, 0x46,
+	 0x44, 0x4C, 0x0F, 0x26, 0x19, 0x00, 0x00, 0xBC, 0x40, 0x45, 0x0B, 0x03, 0x00, 0x64, 0x23, 0x46,
+	 0x22, 0xFA, 0x26, 0x46, 0xA2, 0xFF, 0xB6, 0x60, 0x58, 0x4E, 0x72, 0x78, 0xFF, 0xFF, 0xA3, 0xFF,
+	 0x26, 0x46, 0x2A, 0xF0, 0x2C, 0x44, 0x64, 0x40, 0x04, 0x27, 0x06, 0x00, 0x23, 0x46, 0x26, 0xFA,
+	 0x26, 0x46, 0xCD, 0x60, 0xA5, 0x78, 0xFF, 0xFF, 0x3F, 0xF2, 0x02, 0xFA, 0xA2, 0xFF, 0x16, 0xF0,
+	 0xFF, 0xFF, 0x64, 0x44, 0x01, 0x26, 0xDC, 0x9C, 0x92, 0xF3, 0x2A, 0xF2, 0xDC, 0x83, 0x92, 0xFD,
+	 0x06, 0xF4, 0x01, 0xF8, 0x26, 0x46, 0x60, 0x40, 0x40, 0x2B, 0x18, 0x00, 0x64, 0x44, 0x00, 0x65,
+	 0xFF, 0xB4, 0xFC, 0xA4, 0x06, 0xF0, 0x03, 0x03, 0x64, 0x46, 0x0C, 0x0D, 0x02, 0x65, 0x26, 0x46,
+	 0x00, 0xF2, 0xFF, 0xFF, 0xD0, 0x80, 0xFF, 0xFF, 0x02, 0x03, 0x60, 0x46, 0xF9, 0x01, 0x01, 0xF2,
+	 0xFF, 0xFF, 0xD4, 0x84, 0x01, 0xFA, 0x66, 0x44, 0x26, 0x46, 0x06, 0xFA, 0x06, 0xF4, 0x00, 0xF2,
+	 0x80, 0xFC, 0x40, 0x45, 0xB6, 0x60, 0x58, 0x4E, 0x72, 0x78, 0xFF, 0xFF, 0xA3, 0xFF, 0x26, 0x46,
+	 0x2C, 0x44, 0x0F, 0x26, 0x0F, 0x00, 0x23, 0x46, 0x26, 0xFA, 0x26, 0x44, 0x22, 0xFA, 0x26, 0x46,
+	 0x00, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0x6E, 0x00, 0xA3, 0x46, 0x26, 0xF2, 0x60, 0x45, 0xDC, 0x84, 0xD4, 0x80, 0x26, 0xFA,
+	 0xA3, 0x46, 0x6B, 0x02, 0x2A, 0xF0, 0xA3, 0x46, 0x22, 0xF2, 0xA3, 0x46, 0x00, 0xBC, 0x00, 0xF2,
+	 0x01, 0x02, 0x63, 0x00, 0x44, 0x4C, 0x3F, 0xF0, 0x60, 0x43, 0x23, 0x46, 0x22, 0xF4, 0x09, 0x60,
+	 0x00, 0x65, 0x3F, 0xF2, 0x26, 0x46, 0xC0, 0x84, 0xD4, 0x80, 0x60, 0x45, 0x56, 0x07, 0x80, 0xFC,
+	 0x1B, 0xF2, 0x06, 0xF2, 0x60, 0x41, 0x23, 0x46, 0x22, 0xF4, 0x1B, 0xF0, 0x06, 0xF0, 0xC1, 0x81,
+	 0x06, 0xFA, 0x05, 0xFA, 0x9B, 0xFA, 0x65, 0x44, 0x3F, 0xFA, 0x64, 0x46, 0x00, 0xFC, 0x63, 0x46,
+	 0x01, 0xF2, 0x10, 0x61, 0xF2, 0xA4, 0x01, 0xFA, 0xC8, 0x83, 0x02, 0x64, 0x59, 0xD0, 0x58, 0xD8,
+	 0xFD, 0x1F, 0x06, 0x45, 0x00, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x25, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xA2, 0xFF, 0x00, 0xF4, 0x01, 0xF0, 0x0A, 0x18, 0x70, 0x67,
+	 0xA0, 0x80, 0xF0, 0x67, 0x06, 0x03, 0xC0, 0x84, 0x01, 0xFA, 0x25, 0x46, 0x25, 0x44, 0x80, 0xFC,
+	 0x05, 0xFA, 0xB6, 0x60, 0x58, 0x4E, 0x72, 0x78, 0xFF, 0xFF, 0xD4, 0xFE, 0xA3, 0xFF, 0x2C, 0x44,
+	 0x04, 0x27, 0x16, 0x00, 0x23, 0x46, 0x22, 0xF2, 0xA2, 0xFC, 0x60, 0x46, 0x46, 0x46, 0x3F, 0xF2,
+	 0x00, 0xF4, 0x60, 0x47, 0x08, 0xFA, 0x26, 0x46, 0x2C, 0x43, 0x2A, 0xFC, 0x06, 0xF4, 0x00, 0x64,
+	 0x00, 0xFA, 0x01, 0xF0, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84, 0x01, 0xFA, 0x26, 0x46, 0x1D, 0x00,
+	 0x00, 0x66, 0x46, 0x46, 0xCA, 0x60, 0x81, 0x78, 0xFF, 0xFF, 0xA3, 0x46, 0x22, 0xF0, 0xA2, 0xFC,
+	 0x00, 0x63, 0x33, 0x85, 0xA3, 0x46, 0x0D, 0x03, 0xA3, 0x46, 0x26, 0xF2, 0x0F, 0x65, 0xA4, 0x85,
+	 0xD4, 0x84, 0x26, 0xFA, 0xA3, 0x46, 0xA2, 0xFF, 0xB6, 0x60, 0x58, 0x4E, 0x72, 0x78, 0xFF, 0xFF,
+	 0xA3, 0xFF, 0x26, 0x46, 0xCE, 0x60, 0x38, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0x32, 0xF0, 0x60, 0x40,
+	 0x08, 0x2A, 0x24, 0x00, 0x01, 0x2B, 0x13, 0x00, 0x64, 0x40, 0x01, 0x2A, 0x10, 0x00, 0x25, 0x60,
+	 0xE8, 0x64, 0xE5, 0x60, 0x78, 0x41, 0xC7, 0x78, 0x97, 0xF1, 0x1B, 0xF2, 0xFF, 0xFF, 0x60, 0x45,
+	 0x25, 0x60, 0xEE, 0x64, 0xE5, 0x60, 0x78, 0x41, 0xD3, 0x78, 0x97, 0xF1, 0x0F, 0x00, 0x25, 0x60,
+	 0xE6, 0x64, 0xE5, 0x60, 0x78, 0x41, 0xC7, 0x78, 0x97, 0xF1, 0x1B, 0xF2, 0xFF, 0xFF, 0x60, 0x45,
+	 0x25, 0x60, 0xEC, 0x64, 0xE5, 0x60, 0x78, 0x41, 0xD3, 0x78, 0x97, 0xF1, 0x07, 0xF4, 0xFF, 0xFF,
+	 0x26, 0xF2, 0x26, 0x46, 0x0F, 0xB4, 0xDC, 0x85, 0x25, 0x60, 0xEA, 0x64, 0xE5, 0x60, 0x78, 0x41,
+	 0xD3, 0x78, 0x97, 0xF1, 0x27, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x3B, 0x07, 0x00, 0x25, 0x60,
+	 0xF8, 0x64, 0xE5, 0x60, 0x78, 0x41, 0xC7, 0x78, 0x97, 0xF1, 0x08, 0x00, 0x02, 0x3B, 0x06, 0x00,
+	 0x25, 0x60, 0xFA, 0x64, 0xE5, 0x60, 0x78, 0x41, 0xC7, 0x78, 0x97, 0xF1, 0x07, 0xF2, 0x26, 0xF0,
+	 0x41, 0x18, 0x60, 0x46, 0xFF, 0x67, 0x20, 0x88, 0x64, 0x5F, 0x40, 0x4A, 0x15, 0xF0, 0x28, 0x44,
+	 0xD0, 0x84, 0x03, 0xA4, 0x03, 0x0E, 0xE8, 0x84, 0xE8, 0x84, 0x04, 0x00, 0xFA, 0xA4, 0xE8, 0x84,
+	 0xE8, 0x87, 0xC0, 0xBF, 0xC0, 0x84, 0x15, 0xFA, 0x40, 0x48, 0x14, 0xF0, 0x2A, 0x44, 0xD0, 0x84,
+	 0x1F, 0xA4, 0x06, 0x0E, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0x07, 0x00,
+	 0xC2, 0xA4, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x87, 0xF8, 0xBF, 0xC0, 0x84,
+	 0x14, 0xFA, 0x2B, 0x60, 0xEC, 0x63, 0xBD, 0xDB, 0x60, 0x5C, 0x2F, 0x67, 0xD0, 0x80, 0x60, 0x45,
+	 0x02, 0x28, 0x64, 0x45, 0x28, 0x5C, 0xBD, 0xD9, 0x8B, 0x67, 0xD0, 0x80, 0x60, 0x41, 0x02, 0x24,
+	 0x64, 0x41, 0xD5, 0x84, 0x80, 0x65, 0xC4, 0x87, 0x01, 0x05, 0x00, 0x64, 0xFF, 0xB4, 0x0E, 0xFA,
+	 0xA3, 0xDB, 0x26, 0x46, 0xCE, 0x60, 0x7F, 0x78, 0xFF, 0xFF, 0xCA, 0x60, 0x81, 0x78, 0xFF, 0xFF,
+	 0x1F, 0x60, 0x20, 0x64, 0x40, 0x4B, 0xF6, 0x60, 0x58, 0x4D, 0xB3, 0x78, 0xFF, 0xFF, 0x00, 0x66,
+	 0x46, 0x46, 0xCA, 0x60, 0x81, 0x78, 0xFF, 0xFF, 0x1F, 0x60, 0x04, 0x64, 0x0F, 0x60, 0x90, 0xFB,
+	 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xF8, 0xFE, 0x00, 0x66,
+	 0x46, 0x46, 0xCA, 0x60, 0x81, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0x58, 0x63, 0x60, 0x47, 0x01, 0x27,
+	 0x64, 0x63, 0x61, 0x5C, 0x18, 0x60, 0x0F, 0xF9, 0xBD, 0xD0, 0xBD, 0xD0, 0x64, 0x45, 0x64, 0x41,
+	 0xBD, 0xD0, 0x00, 0xF4, 0x04, 0xF8, 0x83, 0xFA, 0x82, 0xF8, 0xA6, 0x46, 0x02, 0xB0, 0x5E, 0x63,
+	 0x04, 0x03, 0x64, 0x63, 0x03, 0xB0, 0x02, 0x3A, 0x6C, 0x63, 0x3F, 0xF2, 0xBD, 0xD0, 0xBD, 0xD0,
+	 0x64, 0x45, 0x64, 0x41, 0xBD, 0xD0, 0xA6, 0x46, 0x07, 0xF8, 0x86, 0xFA, 0x85, 0xF8, 0x60, 0x47,
+	 0x08, 0xFA, 0x18, 0x60, 0x0F, 0xF1, 0x26, 0x46, 0x64, 0x41, 0x2F, 0x58, 0xFF, 0xFF, 0x2A, 0xF2,
+	 0x2C, 0xF0, 0x31, 0x40, 0x20, 0x26, 0x09, 0x00, 0x60, 0x40, 0xA4, 0x36, 0x21, 0x00, 0x08, 0x26,
+	 0x07, 0x00, 0x7D, 0xF1, 0xCF, 0x60, 0x47, 0x78, 0xFF, 0xFF, 0xCF, 0x60, 0x77, 0x78, 0xFF, 0xFF,
+	 0x64, 0x40, 0x01, 0x26, 0x12, 0x00, 0x3F, 0xF0, 0x32, 0x40, 0x10, 0x2A, 0x0A, 0x00, 0x64, 0x41,
+	 0x60, 0x40, 0x40, 0x27, 0x06, 0x00, 0xCD, 0x81, 0xDD, 0x81, 0x03, 0x03, 0x02, 0x03, 0x01, 0x61,
+	 0x01, 0x00, 0x00, 0x61, 0x60, 0x40, 0x18, 0x3A, 0x03, 0x00, 0xCF, 0x60, 0xC9, 0x78, 0xFF, 0xFF,
+	 0x07, 0xF2, 0x87, 0xF1, 0x66, 0x45, 0xD0, 0x80, 0x60, 0x46, 0x06, 0xF2, 0x65, 0x46, 0x03, 0x03,
+	 0xFF, 0xFF, 0x02, 0x26, 0x07, 0x00, 0xDD, 0x60, 0x58, 0x4F, 0x90, 0x78, 0xFF, 0xFF, 0xCF, 0x60,
+	 0xC5, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0xA4, 0x3A, 0x07, 0x00, 0xDF, 0x60,
+	 0x58, 0x4F, 0xE3, 0x78, 0xFF, 0xFF, 0xCF, 0x60, 0xC5, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0xCE, 0x60,
+	 0x58, 0x4F, 0x54, 0x78, 0xFF, 0xFF, 0x3F, 0xF2, 0x06, 0x65, 0xD4, 0x80, 0x60, 0x43, 0x5B, 0x04,
+	 0x00, 0xF4, 0xAA, 0x60, 0xAA, 0x65, 0x09, 0xF2, 0x0A, 0xF0, 0xD4, 0x80, 0x03, 0x64, 0x53, 0x02,
+	 0xD0, 0x80, 0x00, 0x64, 0x0B, 0xF0, 0x4F, 0x02, 0x64, 0x45, 0xD4, 0x80, 0xF8, 0x7F, 0x08, 0x02,
+	 0x0C, 0xF0, 0x26, 0x46, 0x64, 0x45, 0x23, 0xF0, 0x20, 0x67, 0xB0, 0x84, 0xA2, 0xDA, 0x0B, 0x00,
+	 0xD4, 0x80, 0x1D, 0x60, 0x60, 0x64, 0x11, 0x02, 0x0C, 0xF0, 0x26, 0x46, 0x64, 0x45, 0x23, 0xF0,
+	 0x40, 0x67, 0xB0, 0x84, 0xA2, 0xDA, 0x65, 0x44, 0x88, 0x3A, 0x35, 0x00, 0x77, 0x37, 0x03, 0x00,
+	 0x78, 0x37, 0x01, 0x00, 0x8E, 0x37, 0x00, 0x61, 0x2E, 0x00, 0xD4, 0x80, 0x08, 0x65, 0x2B, 0x02,
+	 0xD7, 0x80, 0x01, 0x60, 0x00, 0x64, 0x0C, 0xF0, 0x26, 0x04, 0xD0, 0x80, 0x0D, 0xF0, 0x23, 0x02,
+	 0x26, 0x46, 0x14, 0xF2, 0x01, 0x63, 0x02, 0xA8, 0x64, 0x47, 0x1D, 0x03, 0x7F, 0xB4, 0xFD, 0xA0,
+	 0x06, 0x03, 0x19, 0x07, 0x23, 0xF0, 0x60, 0x67, 0xB0, 0x84, 0xA2, 0xDA, 0x6B, 0x00, 0x26, 0x46,
+	 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x08, 0x2A, 0x07, 0x00, 0x60, 0x40, 0x48, 0x36, 0x04, 0x00,
+	 0xD2, 0xF3, 0xFF, 0xFF, 0x02, 0xBC, 0xD2, 0xFB, 0xE8, 0x60, 0x58, 0x4F, 0xEF, 0x78, 0xFF, 0xFF,
+	 0xCF, 0x60, 0xC5, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x61, 0x40, 0x01, 0x2A, 0x09, 0x00, 0x25, 0x60,
+	 0xFE, 0x64, 0xE5, 0x60, 0x78, 0x41, 0xC7, 0x78, 0x97, 0xF1, 0xCF, 0x60, 0xC9, 0x78, 0xFF, 0xFF,
+	 0xDF, 0x60, 0x58, 0x4F, 0xE3, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0xFF, 0xFF, 0xFF, 0xFF, 0x48, 0x36,
+	 0x88, 0x00, 0xCF, 0x60, 0xD6, 0x78, 0xFF, 0xFF, 0xCF, 0x60, 0xC5, 0x78, 0xFF, 0xFF, 0x60, 0x40,
+	 0x0C, 0x26, 0x7F, 0x00, 0x64, 0x40, 0x01, 0x2A, 0x7C, 0x00, 0xB0, 0x3A, 0x05, 0x00, 0xD4, 0x60,
+	 0x58, 0x4F, 0x5A, 0x78, 0xFF, 0xFF, 0x71, 0x00, 0x00, 0x3A, 0x05, 0x00, 0xD7, 0x60, 0x58, 0x4F,
+	 0xCA, 0x78, 0xFF, 0xFF, 0x6A, 0x00, 0x20, 0x3A, 0x05, 0x00, 0xD7, 0x60, 0x58, 0x4F, 0xCA, 0x78,
+	 0xFF, 0xFF, 0x63, 0x00, 0xC0, 0x3A, 0x05, 0x00, 0xDC, 0x60, 0x58, 0x4F, 0xFE, 0x78, 0xFF, 0xFF,
+	 0x5C, 0x00, 0xA0, 0x3A, 0x05, 0x00, 0xDD, 0x60, 0x58, 0x4F, 0x5B, 0x78, 0xFF, 0xFF, 0x55, 0x00,
+	 0x40, 0x3A, 0x0D, 0x00, 0xE3, 0x60, 0x58, 0x4F, 0xC3, 0x78, 0xFF, 0xFF, 0x4E, 0x00, 0x60, 0x40,
+	 0x50, 0x3A, 0x05, 0x00, 0xED, 0x60, 0x58, 0x4F, 0xEB, 0x78, 0xFF, 0xFF, 0x46, 0x00, 0xCF, 0x60,
+	 0xC9, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x08, 0x2A, 0x07, 0x00,
+	 0x60, 0x40, 0x48, 0x36, 0x04, 0x00, 0xD2, 0xF3, 0xFF, 0xFF, 0x02, 0xBC, 0xD2, 0xFB, 0x2A, 0xF2,
+	 0x3B, 0xF0, 0x60, 0x40, 0x40, 0x2B, 0x04, 0x00, 0x64, 0x40, 0x20, 0x2B, 0x01, 0x00, 0x03, 0x00,
+	 0xCF, 0x60, 0xB9, 0x78, 0xFF, 0xFF, 0x22, 0xF2, 0xFF, 0xFF, 0x04, 0xB4, 0xFF, 0xFF, 0xF8, 0x03,
+	 0x23, 0xF2, 0x07, 0xF4, 0xBB, 0xF0, 0x26, 0x46, 0xA4, 0x84, 0xFF, 0xFF, 0x60, 0x40, 0x2F, 0x26,
+	 0x20, 0x00, 0xC9, 0x60, 0x58, 0x4F, 0xCF, 0x78, 0xFF, 0xFF, 0x64, 0x40, 0x18, 0x36, 0x09, 0x00,
+	 0x04, 0x65, 0xE5, 0x60, 0x58, 0x4E, 0x27, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0xCF, 0x60, 0xC9, 0x78,
+	 0xFF, 0xFF, 0x1F, 0x60, 0x04, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xF8, 0xFE, 0x0C, 0x00, 0x66, 0x44, 0x00, 0xA8, 0xFF, 0xFF,
+	 0x0A, 0x03, 0x26, 0x46, 0x1F, 0x60, 0x20, 0x64, 0x40, 0x4B, 0xF6, 0x60, 0x58, 0x4D, 0xB3, 0x78,
+	 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0xCE, 0x60, 0x35, 0x78, 0xFF, 0xFF, 0x14, 0xF2, 0x00, 0x7C,
+	 0x3E, 0xF8, 0xCC, 0x84, 0xCC, 0x84, 0x18, 0x03, 0x5C, 0x02, 0x11, 0xF2, 0x07, 0xFA, 0xAB, 0xF3,
+	 0x19, 0xFA, 0xD0, 0x60, 0x58, 0x4E, 0x86, 0x78, 0xFF, 0xFF, 0x1E, 0x60, 0xE0, 0x64, 0x0F, 0x60,
+	 0x90, 0xFB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC8, 0xFE,
+	 0xF2, 0x64, 0x3B, 0x42, 0x4A, 0xDB, 0x8D, 0x00, 0xA2, 0xFF, 0x46, 0x45, 0xB6, 0x60, 0x58, 0x4E,
+	 0xBB, 0x78, 0xFF, 0xFF, 0xA3, 0xFF, 0x11, 0x03, 0x7E, 0x63, 0x46, 0x4B, 0x25, 0x46, 0xA3, 0xD0,
+	 0x2B, 0x46, 0xA3, 0xD8, 0xFB, 0x1F, 0x89, 0xFC, 0x8A, 0xFC, 0x88, 0xFC, 0x05, 0x18, 0x64, 0x46,
+	 0x01, 0xF0, 0x10, 0x67, 0xC0, 0x84, 0x01, 0xFA, 0x08, 0xFE, 0x2B, 0x46, 0x46, 0x46, 0x25, 0x46,
+	 0xD0, 0x60, 0x58, 0x4E, 0x86, 0x78, 0xFF, 0xFF, 0x13, 0x60, 0x43, 0xF3, 0x87, 0xF3, 0x00, 0xA8,
+	 0x07, 0xFA, 0x0E, 0x03, 0x1E, 0x60, 0xDA, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x25, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xF3, 0x64, 0x3B, 0x42, 0x4A, 0xDB, 0x0D, 0x00,
+	 0x1E, 0x60, 0xCE, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x25, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB,
+	 0xFF, 0xFF, 0x2B, 0xFF, 0xF4, 0x64, 0x3B, 0x42, 0x4A, 0xDB, 0x26, 0x44, 0x00, 0xA8, 0xC1, 0xFE,
+	 0x48, 0x03, 0x26, 0x46, 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x08, 0x2A, 0x07, 0x00, 0x60, 0x40,
+	 0x48, 0x36, 0x04, 0x00, 0xD2, 0xF3, 0xFF, 0xFF, 0x02, 0xBC, 0xD2, 0xFB, 0x26, 0x46, 0x2A, 0xF2,
+	 0x3B, 0xF0, 0x60, 0x40, 0x40, 0x2B, 0x06, 0x00, 0xC0, 0x60, 0x00, 0x64, 0x64, 0x40, 0x20, 0x2B,
+	 0x01, 0x00, 0x03, 0x00, 0xD0, 0x60, 0x73, 0x78, 0xFF, 0xFF, 0x22, 0xF2, 0xFF, 0xFF, 0x04, 0xB4,
+	 0xFF, 0xFF, 0xF8, 0x03, 0x23, 0xF2, 0x07, 0xF4, 0xBB, 0xF0, 0x26, 0x46, 0xA4, 0x84, 0xFF, 0xFF,
+	 0x60, 0x40, 0x2F, 0x26, 0x07, 0x00, 0xC9, 0x60, 0x58, 0x4F, 0xCF, 0x78, 0xFF, 0xFF, 0x64, 0x40,
+	 0x18, 0x36, 0x09, 0x00, 0x04, 0x65, 0xE5, 0x60, 0x58, 0x4E, 0x27, 0x78, 0xFF, 0xFF, 0x26, 0x46,
+	 0xCF, 0x60, 0xC9, 0x78, 0xFF, 0xFF, 0x1F, 0x60, 0x04, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x26, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xF8, 0xFE, 0xF1, 0x64, 0x3B, 0x42,
+	 0x4A, 0xDB, 0x00, 0x66, 0x46, 0x46, 0xCF, 0x60, 0xC5, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0x82, 0x60,
+	 0xFF, 0x65, 0xA4, 0x87, 0x02, 0xBF, 0x2A, 0xFA, 0x1C, 0xF2, 0x13, 0xFA, 0x32, 0xF2, 0x2C, 0xFA,
+	 0x33, 0xF2, 0x2D, 0xFA, 0x34, 0xF2, 0x2E, 0xFA, 0x2F, 0xF2, 0x32, 0xFA, 0x30, 0xF2, 0x33, 0xFA,
+	 0x31, 0xF2, 0x34, 0xFA, 0x66, 0xF3, 0x2F, 0xFA, 0x67, 0xF3, 0x30, 0xFA, 0x68, 0xF3, 0x31, 0xFA,
+	 0x2E, 0x58, 0xFF, 0xFF, 0xD3, 0x60, 0x59, 0x64, 0x08, 0x60, 0x26, 0xFB, 0x2F, 0x58, 0xFF, 0xFF,
+	 0xB1, 0xF3, 0x12, 0x60, 0x2C, 0x63, 0xF7, 0xA0, 0xFF, 0xFF, 0x02, 0x06, 0x00, 0x64, 0xB1, 0xFB,
+	 0xB1, 0xF3, 0xB1, 0xFB, 0x01, 0xA4, 0xCC, 0x84, 0xFF, 0xFF, 0x02, 0x03, 0x2A, 0xA3, 0xFB, 0x01,
+	 0x63, 0x46, 0x10, 0x60, 0xA6, 0x63, 0x0E, 0x61, 0x60, 0xFE, 0xA6, 0xD1, 0xDE, 0x86, 0x01, 0x64,
+	 0x64, 0x40, 0x7F, 0x36, 0x00, 0x64, 0xA3, 0xDB, 0xDB, 0x83, 0xA3, 0xD9, 0xCD, 0x81, 0x04, 0xA3,
+	 0xF4, 0x02, 0x11, 0x60, 0x16, 0x63, 0x1C, 0x61, 0xA6, 0xD1, 0xDE, 0x86, 0x01, 0x64, 0x64, 0x40,
+	 0x7F, 0x36, 0x00, 0x64, 0xA3, 0xDB, 0xDB, 0x83, 0xA3, 0xD9, 0xCD, 0x81, 0x06, 0xA3, 0xF4, 0x02,
+	 0x20, 0xFE, 0x13, 0x60, 0x7F, 0xF3, 0x13, 0x60, 0x2D, 0xFB, 0x1E, 0x63, 0x26, 0x60, 0x64, 0x61,
+	 0x27, 0x60, 0x08, 0x64, 0x58, 0xD1, 0x59, 0xD9, 0xFD, 0x1F, 0x13, 0x60, 0x95, 0xF3, 0x13, 0x60,
+	 0x43, 0xFB, 0x13, 0x60, 0x96, 0xF3, 0x13, 0x60, 0x44, 0xFB, 0x13, 0x60, 0x9C, 0xF3, 0x13, 0x60,
+	 0x4A, 0xFB, 0x13, 0x60, 0x9D, 0xF3, 0x13, 0x60, 0x4B, 0xFB, 0x13, 0x60, 0x9E, 0xF3, 0x13, 0x60,
+	 0x4C, 0xFB, 0x13, 0x60, 0x9F, 0xF3, 0x13, 0x60, 0x4D, 0xFB, 0x13, 0x60, 0x97, 0xF3, 0x13, 0x60,
+	 0x45, 0xFB, 0x13, 0x60, 0x98, 0xF3, 0x13, 0x60, 0x46, 0xFB, 0x13, 0x60, 0x99, 0xF3, 0x13, 0x60,
+	 0x47, 0xFB, 0x26, 0x60, 0xB0, 0x63, 0xBD, 0xD1, 0xCB, 0xF9, 0x66, 0xF9, 0xBD, 0xD1, 0xCC, 0xF9,
+	 0x67, 0xF9, 0xA3, 0xD1, 0xCD, 0xF9, 0x68, 0xF9, 0x01, 0x64, 0x6A, 0xFB, 0x13, 0x60, 0x51, 0xF3,
+	 0xC4, 0xFB, 0x00, 0x63, 0x4A, 0xFD, 0x5A, 0xFD, 0x6B, 0xFD, 0x6C, 0xFD, 0x13, 0x60, 0x45, 0xF3,
+	 0x15, 0x60, 0xCB, 0xF1, 0xFF, 0x60, 0xE7, 0x65, 0x32, 0x41, 0xA5, 0x81, 0xFF, 0xA0, 0xFF, 0xFF,
+	 0x01, 0x03, 0x06, 0x00, 0x13, 0x60, 0x47, 0xF3, 0x08, 0xB9, 0x60, 0x40, 0x01, 0x26, 0x10, 0xB9,
+	 0x41, 0x52, 0x87, 0xF5, 0x32, 0x44, 0x10, 0xB0, 0xFF, 0xFF, 0x0A, 0x03, 0x14, 0x60, 0x15, 0xF3,
+	 0x06, 0xF0, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0x80, 0xBF, 0xB0, 0x84, 0x06, 0xFA,
+	 0x13, 0x60, 0x45, 0xF3, 0x22, 0x7C, 0xFF, 0xA0, 0xFD, 0xA0, 0x05, 0x06, 0x03, 0x03, 0xFE, 0xA0,
+	 0x04, 0x7C, 0x01, 0x02, 0x3A, 0xF8, 0x13, 0x60, 0x4C, 0xF1, 0x20, 0x44, 0x20, 0xB5, 0x64, 0x41,
+	 0x00, 0xB9, 0xD4, 0x84, 0x08, 0x28, 0x20, 0xBC, 0x40, 0x40, 0x15, 0x60, 0xCB, 0xF3, 0x30, 0x60,
+	 0x0E, 0x63, 0xF0, 0x84, 0xF0, 0x84, 0xF0, 0x84, 0x02, 0xB5, 0xF0, 0x84, 0xF0, 0x84, 0x03, 0xB4,
+	 0x65, 0x5C, 0xA3, 0xD9, 0x02, 0xA8, 0x18, 0x60, 0x08, 0xFB, 0x15, 0x02, 0x00, 0x60, 0xC8, 0x64,
+	 0x18, 0x60, 0x09, 0xFB, 0x18, 0x60, 0x0D, 0xFB, 0x07, 0x60, 0xD0, 0x64, 0x18, 0x60, 0x0A, 0xFB,
+	 0x18, 0x60, 0x0E, 0xFB, 0x01, 0x60, 0x90, 0x64, 0x18, 0x60, 0x0B, 0xFB, 0x00, 0x60, 0x64, 0x64,
+	 0x18, 0x60, 0x0C, 0xFB, 0x06, 0x00, 0x64, 0x64, 0x18, 0x60, 0x0B, 0xFB, 0x64, 0x64, 0x18, 0x60,
+	 0x0C, 0xFB, 0xB1, 0xF1, 0x10, 0x60, 0xA0, 0x63, 0x2F, 0x18, 0x60, 0x40, 0x01, 0x27, 0x12, 0x00,
+	 0xCC, 0x84, 0x06, 0xA3, 0xFD, 0x02, 0xA3, 0xD3, 0x10, 0x60, 0xA6, 0x63, 0x25, 0x1B, 0x10, 0x60,
+	 0xF8, 0x65, 0xA3, 0xD3, 0x06, 0xA3, 0xD7, 0x80, 0x02, 0x1B, 0xFB, 0x04, 0x1D, 0x00, 0xF8, 0xA3,
+	 0xA3, 0xD3, 0x18, 0x00, 0x11, 0x60, 0x14, 0x63, 0x11, 0x60, 0xF4, 0x65, 0xA3, 0xD1, 0x08, 0xA3,
+	 0xD0, 0x80, 0xD7, 0x80, 0x02, 0x03, 0xFA, 0x04, 0x0F, 0x00, 0xFA, 0xA3, 0xA3, 0xD3, 0x11, 0x60,
+	 0x16, 0x63, 0x0A, 0x1B, 0xA3, 0xD3, 0x08, 0xA3, 0xD7, 0x80, 0x02, 0x1B, 0xFB, 0x04, 0x04, 0x00,
+	 0xF6, 0xA3, 0xA3, 0xD3, 0xC5, 0xFB, 0x64, 0xFB, 0x27, 0x60, 0x34, 0x64, 0x26, 0x60, 0x90, 0x63,
+	 0xA0, 0xD1, 0xA3, 0xD9, 0x64, 0x41, 0x58, 0xD1, 0x5B, 0xD9, 0x64, 0xF3, 0xFF, 0xFF, 0x60, 0x40,
+	 0x01, 0x2B, 0x03, 0x00, 0xD1, 0x60, 0xE9, 0x78, 0xFF, 0xFF, 0x91, 0xFA, 0x61, 0x44, 0xEF, 0x60,
+	 0x58, 0x4E, 0xAB, 0x78, 0xFF, 0xFF, 0x12, 0xFA, 0x15, 0x60, 0xBC, 0xF3, 0x3F, 0x40, 0x01, 0x27,
+	 0x08, 0x00, 0x0F, 0x60, 0xFF, 0x65, 0xA4, 0x84, 0xEE, 0x60, 0x58, 0x4E, 0x26, 0x78, 0xFF, 0xFF,
+	 0x06, 0x00, 0x0F, 0x65, 0xA4, 0x84, 0xEE, 0x60, 0x58, 0x4E, 0x26, 0x78, 0xFF, 0xFF, 0x00, 0x65,
+	 0xEE, 0x60, 0x58, 0x4E, 0xC6, 0x78, 0xFF, 0xFF, 0xEF, 0x60, 0x58, 0x4E, 0x10, 0x78, 0xFF, 0xFF,
+	 0x15, 0x00, 0x11, 0xF8, 0x64, 0x44, 0xEF, 0x60, 0x58, 0x4E, 0xAB, 0x78, 0xFF, 0xFF, 0x12, 0xFA,
+	 0x15, 0x60, 0xBD, 0xF3, 0x0F, 0x60, 0xFF, 0x65, 0xA4, 0x84, 0xEE, 0x60, 0x58, 0x4E, 0x26, 0x78,
+	 0xFF, 0xFF, 0xFF, 0x65, 0xEE, 0x60, 0x58, 0x4E, 0xC6, 0x78, 0xFF, 0xFF, 0xB5, 0xF1, 0x09, 0x60,
+	 0x2A, 0x64, 0xD0, 0x80, 0x03, 0x64, 0x01, 0x06, 0x06, 0x64, 0xAE, 0xFB, 0x46, 0x48, 0xC3, 0xF3,
+	 0xFF, 0xFF, 0x60, 0x40, 0x05, 0x3A, 0x03, 0x00, 0x14, 0x60, 0x00, 0x66, 0x11, 0x00, 0x04, 0x3A,
+	 0x03, 0x00, 0x13, 0x60, 0xF4, 0x66, 0x0C, 0x00, 0x03, 0x3A, 0x03, 0x00, 0x13, 0x60, 0xE8, 0x66,
+	 0x07, 0x00, 0x02, 0x3A, 0x03, 0x00, 0x13, 0x60, 0xDC, 0x66, 0x02, 0x00, 0x13, 0x60, 0xD0, 0x66,
+	 0x60, 0xFE, 0xA6, 0xD3, 0xDE, 0x86, 0x10, 0x60, 0x5F, 0xFB, 0xA6, 0xD3, 0xDE, 0x86, 0x21, 0x60,
+	 0x2F, 0x63, 0xA3, 0xDB, 0x21, 0x60, 0xA7, 0x63, 0xA3, 0xDB, 0xA6, 0xD3, 0xDE, 0x86, 0x10, 0x60,
+	 0x5E, 0xFB, 0xA6, 0xD3, 0xDE, 0x86, 0x20, 0x60, 0xBF, 0x63, 0xA3, 0xDB, 0x20, 0xFE, 0xA6, 0xD3,
+	 0xDA, 0x86, 0x60, 0x43, 0x1F, 0xB3, 0x63, 0x5C, 0x1F, 0x60, 0x00, 0xB4, 0xE8, 0x84, 0xE8, 0x84,
+	 0xE8, 0x84, 0xB0, 0x85, 0x10, 0x60, 0x95, 0xF3, 0xFF, 0xFF, 0xFC, 0x60, 0x00, 0xB4, 0xB4, 0x84,
+	 0xA2, 0xDB, 0x10, 0x60, 0xD1, 0xFB, 0x21, 0x60, 0xCA, 0x63, 0xA3, 0xD3, 0xA6, 0xD1, 0xDE, 0x86,
+	 0x80, 0x60, 0x7F, 0xB5, 0x64, 0x44, 0xE8, 0x84, 0x7F, 0x60, 0x80, 0xB4, 0xB4, 0x84, 0xA3, 0xDB,
+	 0x60, 0xFE, 0xA6, 0xD3, 0xDE, 0x86, 0x10, 0x60, 0x62, 0xFB, 0x20, 0xFE, 0x10, 0x60, 0x2A, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE, 0x0A, 0x04, 0x40, 0x60, 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB,
+	 0xD2, 0x60, 0x5E, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x64, 0xF1, 0x0F, 0x60,
+	 0x9D, 0xF9, 0x0C, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x20, 0x44, 0x01, 0x65, 0x34, 0x80,
+	 0x20, 0x60, 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xD2, 0x60, 0x82, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x64, 0xF1, 0x0F, 0x60,
+	 0x9D, 0xF9, 0x0E, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x20, 0x60, 0x00, 0x64, 0x08, 0x60,
+	 0x16, 0xFB, 0xD2, 0x60, 0x97, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x60,
+	 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xBE, 0xFE, 0x08, 0x60, 0x11, 0xF1, 0x40, 0x60, 0x00, 0x64,
+	 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0xBE, 0xFE, 0x08, 0x60, 0x11, 0xF1, 0x40, 0x60, 0x00, 0x64,
+	 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x20, 0x40, 0x20, 0x2A, 0x04, 0x00, 0xF0, 0x60, 0x58, 0x4E,
+	 0x66, 0x78, 0xFF, 0xFF, 0x36, 0x40, 0x08, 0x3A, 0x6A, 0x00, 0x36, 0x40, 0x08, 0x3A, 0x05, 0x00,
+	 0x10, 0x60, 0x42, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x04, 0x00, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0x4E, 0xF3, 0xFF, 0xFF, 0x1D, 0x1B, 0x13, 0x60, 0x54, 0xF3, 0xC7, 0xFB, 0x26, 0x60,
+	 0x16, 0x65, 0x26, 0x60, 0xB8, 0x61, 0x26, 0x60, 0x14, 0x64, 0x20, 0x63, 0x59, 0xD1, 0x58, 0xD9,
+	 0xA5, 0xD9, 0xDA, 0x85, 0xFB, 0x1F, 0x00, 0x60, 0x01, 0x64, 0x08, 0x60, 0x22, 0xFB, 0xD3, 0x60,
+	 0x3C, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x36, 0x40, 0x08, 0x3A, 0x41, 0x00, 0xE7, 0x60, 0xC5, 0x78,
+	 0xFF, 0xFF, 0x27, 0x60, 0x3E, 0x63, 0x60, 0x41, 0x00, 0x62, 0xCD, 0x81, 0x04, 0xA2, 0xFD, 0x02,
+	 0x2C, 0x60, 0x3E, 0x61, 0xFC, 0xA2, 0x62, 0x45, 0xC5, 0x81, 0xE0, 0x84, 0xE0, 0x85, 0xC4, 0x85,
+	 0xC7, 0x83, 0xFE, 0xA5, 0x88, 0xF3, 0xFF, 0xFF, 0xC4, 0x84, 0x66, 0x45, 0x60, 0x46, 0xBD, 0xD1,
+	 0x03, 0xF8, 0xBD, 0xD1, 0x04, 0xF8, 0xA3, 0xD1, 0x05, 0xF8, 0x06, 0xF2, 0xFF, 0xFF, 0x02, 0x7E,
+	 0x06, 0xFA, 0x64, 0xF3, 0x61, 0x43, 0x60, 0x40, 0x01, 0x27, 0x02, 0xA3, 0xA3, 0xD1, 0x0F, 0xF8,
+	 0x16, 0x64, 0x12, 0xFA, 0x01, 0x64, 0x11, 0xFA, 0x66, 0x5C, 0xC1, 0x60, 0x58, 0x4E, 0x93, 0x78,
+	 0xFF, 0xFF, 0x66, 0x43, 0x32, 0x40, 0x08, 0x2A, 0x0A, 0x00, 0x14, 0x60, 0x15, 0xF3, 0x06, 0xF0,
+	 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0x80, 0xBF, 0xB0, 0x84, 0x06, 0xFA, 0xC5, 0xFE,
+	 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x00, 0x60, 0x30, 0x64, 0x08, 0x60, 0x16, 0xFB,
+	 0xD2, 0x60, 0xB5, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x60, 0x2A, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x00, 0x60, 0x03, 0x64, 0x08, 0x60, 0x22, 0xFB, 0xD2, 0x60, 0xB5, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x60, 0x42, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0x0F, 0x4E, 0xE1, 0x60, 0x58, 0x4F, 0xA9, 0x78, 0xFF, 0xFF, 0x0E, 0x4F, 0x0F, 0x4E, 0xDF, 0x60,
+	 0x58, 0x4F, 0x0F, 0x78, 0xFF, 0xFF, 0x0E, 0x4F, 0x0F, 0x4E, 0xDE, 0x60, 0x58, 0x4F, 0x9A, 0x78,
+	 0xFF, 0xFF, 0x0E, 0x4F, 0x0F, 0x4E, 0xDD, 0x60, 0x58, 0x4F, 0xFB, 0x78, 0xFF, 0xFF, 0x0E, 0x4F,
+	 0xD5, 0x01, 0x4E, 0xF3, 0x7D, 0xF5, 0x60, 0x40, 0xFF, 0x22, 0x0A, 0x00, 0x88, 0xF1, 0xCC, 0x84,
+	 0xE0, 0x84, 0xC0, 0x86, 0x06, 0xF2, 0xFF, 0xFF, 0x00, 0x7E, 0x06, 0xFA, 0x7D, 0xF5, 0x07, 0x00,
+	 0x08, 0x60, 0x24, 0xF1, 0x00, 0x60, 0x11, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x4E, 0xF3,
+	 0x66, 0x40, 0xFF, 0x22, 0x05, 0x00, 0xFF, 0x22, 0x39, 0x00, 0xD4, 0x60, 0x0C, 0x78, 0xFF, 0xFF,
+	 0x02, 0x64, 0x69, 0xFB, 0xFF, 0xFF, 0xC1, 0xFE, 0x69, 0xF3, 0x00, 0x65, 0xD4, 0x80, 0x4E, 0xF3,
+	 0x0E, 0x03, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x80, 0x60, 0x00, 0x64, 0x08, 0x60,
+	 0x16, 0xFB, 0xD3, 0x60, 0x7C, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x60,
+	 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE, 0x0A, 0x04, 0x20, 0x60, 0x00, 0x64, 0x08, 0x60,
+	 0x16, 0xFB, 0xD3, 0x60, 0x8F, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0xD3, 0xF3,
+	 0xFF, 0xFF, 0xFE, 0xB4, 0xD3, 0xFB, 0x1F, 0x60, 0x3A, 0x62, 0x06, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x2D, 0xFF, 0x20, 0x44, 0x01, 0xB5, 0x54, 0x80, 0xDA, 0xFE, 0xBE, 0xFE, 0x87, 0xF1, 0x02, 0x64,
+	 0x86, 0xF3, 0xC0, 0x83, 0x40, 0x48, 0x75, 0xFD, 0xE7, 0x60, 0x58, 0x4E, 0x81, 0x78, 0xFF, 0xFF,
+	 0x28, 0x44, 0x4C, 0x88, 0x75, 0xF3, 0x02, 0x65, 0xC4, 0x83, 0xF5, 0x02, 0x1E, 0x60, 0x58, 0x4E,
+	 0xB9, 0x78, 0xFF, 0xFF, 0x17, 0x60, 0x06, 0x64, 0x0B, 0x60, 0x82, 0xFB, 0x4A, 0xDF, 0x01, 0x60,
+	 0xFE, 0x63, 0x15, 0x60, 0x00, 0x61, 0x00, 0x64, 0x59, 0xDB, 0xFE, 0x1F, 0x7D, 0xF1, 0x1E, 0x60,
+	 0xE0, 0x61, 0x64, 0x40, 0xFF, 0x26, 0x38, 0x00, 0xD4, 0x60, 0x58, 0x4E, 0x0F, 0x78, 0xFF, 0xFF,
+	 0x1E, 0x60, 0xCE, 0x61, 0xD4, 0x60, 0x58, 0x4E, 0x0F, 0x78, 0xFF, 0xFF, 0x1E, 0x60, 0xD4, 0x61,
+	 0xD4, 0x60, 0x58, 0x4E, 0x0F, 0x78, 0xFF, 0xFF, 0x1E, 0x60, 0xE6, 0x61, 0xD4, 0x60, 0x58, 0x4E,
+	 0x0F, 0x78, 0xFF, 0xFF, 0x1E, 0x60, 0xEC, 0x61, 0xD4, 0x60, 0x58, 0x4E, 0x0F, 0x78, 0xFF, 0xFF,
+	 0x1E, 0x60, 0xF8, 0x61, 0xD4, 0x60, 0x58, 0x4E, 0x0F, 0x78, 0xFF, 0xFF, 0x1F, 0x60, 0x04, 0x61,
+	 0xD4, 0x60, 0x58, 0x4E, 0x0F, 0x78, 0xFF, 0xFF, 0x1E, 0x60, 0xF2, 0x61, 0xD4, 0x60, 0x58, 0x4E,
+	 0x0F, 0x78, 0xFF, 0xFF, 0x1E, 0x60, 0xDA, 0x61, 0xD4, 0x60, 0x58, 0x4E, 0x3A, 0x78, 0xFF, 0xFF,
+	 0x00, 0x64, 0x08, 0x60, 0x15, 0xFB, 0x5A, 0xDB, 0xC5, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0xA1, 0xD3,
+	 0x0E, 0x57, 0x23, 0x00, 0x0E, 0xF2, 0x44, 0x4C, 0x80, 0xB0, 0x10, 0xB0, 0x0A, 0x03, 0x00, 0x64,
+	 0x0F, 0x60, 0x90, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0x13, 0x00, 0x12, 0x02, 0xF0, 0x37, 0x09, 0x00, 0x02, 0xF0, 0x09, 0x60, 0x08, 0x64, 0xD0, 0x80,
+	 0xA2, 0xFF, 0x8F, 0xF3, 0x02, 0x02, 0xCC, 0x84, 0x8F, 0xFB, 0x1F, 0x60, 0x20, 0x64, 0x40, 0x4B,
+	 0xF6, 0x60, 0x58, 0x4D, 0xB3, 0x78, 0xFF, 0xFF, 0x2C, 0x44, 0xAC, 0x86, 0x09, 0xF0, 0xDA, 0x02,
+	 0x37, 0x58, 0xFF, 0xFF, 0xA1, 0xD3, 0x0E, 0x57, 0x18, 0x00, 0x0E, 0xF2, 0x44, 0x4C, 0x80, 0xB0,
+	 0x10, 0xB0, 0x0A, 0x03, 0x00, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x08, 0x00, 0x07, 0x02, 0x1F, 0x60, 0x20, 0x64, 0x40, 0x4B,
+	 0xF6, 0x60, 0x58, 0x4D, 0xB3, 0x78, 0xFF, 0xFF, 0x2C, 0x44, 0xAC, 0x86, 0x09, 0xF0, 0xE5, 0x02,
+	 0x37, 0x58, 0xFF, 0xFF, 0x00, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0xB0, 0x64, 0x2A, 0xFA, 0x2F, 0xF2,
+	 0x2C, 0xFA, 0x30, 0xF2, 0x2D, 0xFA, 0x31, 0xF2, 0x2E, 0xFA, 0xCB, 0xF3, 0x2F, 0xFA, 0xCC, 0xF3,
+	 0x30, 0xFA, 0xCD, 0xF3, 0x31, 0xFA, 0x66, 0xF3, 0x32, 0xFA, 0x67, 0xF3, 0x33, 0xFA, 0x68, 0xF3,
+	 0x34, 0xFA, 0xAB, 0xF1, 0x19, 0xF8, 0x06, 0x63, 0x3F, 0xFC, 0x1C, 0xF2, 0x13, 0xFA, 0x00, 0x64,
+	 0x3E, 0xFA, 0x07, 0xF2, 0x87, 0xF1, 0xFF, 0xFF, 0xD0, 0x80, 0xFF, 0xFF, 0x0C, 0x03, 0x60, 0x46,
+	 0x06, 0xF2, 0x26, 0x46, 0x01, 0xB0, 0xFF, 0xFF, 0x03, 0x02, 0xD6, 0x60, 0x40, 0x78, 0xFF, 0xFF,
+	 0xD7, 0x60, 0x92, 0x78, 0xFF, 0xFF, 0x00, 0xF4, 0x0A, 0xF2, 0x09, 0xF2, 0xFF, 0xA0, 0x00, 0xA0,
+	 0x13, 0x02, 0xFF, 0xA0, 0x04, 0x03, 0x08, 0x03, 0xD4, 0x60, 0xAF, 0x78, 0xFF, 0xFF, 0x02, 0x64,
+	 0x55, 0xFB, 0xD4, 0x60, 0xBA, 0x78, 0xFF, 0xFF, 0x01, 0x63, 0x32, 0x40, 0x08, 0x2A, 0x0F, 0x00,
+	 0x55, 0xFD, 0xD4, 0x60, 0xBA, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x00, 0xF4, 0x0A, 0xF2, 0x0E, 0x63,
+	 0x01, 0xA4, 0x0A, 0xFA, 0x0B, 0xFC, 0x43, 0x59, 0xD7, 0x60, 0x6C, 0x78, 0xFF, 0xFF, 0x26, 0x46,
+	 0x00, 0xF4, 0x0A, 0xF2, 0x0D, 0x63, 0x01, 0xA4, 0x0A, 0xFA, 0x0B, 0xFC, 0x43, 0x59, 0xD7, 0x60,
+	 0x6C, 0x78, 0xFF, 0xFF, 0x87, 0xF5, 0x00, 0xF2, 0x26, 0x46, 0x00, 0xA0, 0x2E, 0xF0, 0x37, 0x03,
+	 0x66, 0x41, 0x15, 0x60, 0x02, 0x65, 0x64, 0x47, 0x00, 0x7F, 0x87, 0xF1, 0xE0, 0x84, 0x44, 0xD3,
+	 0x64, 0x43, 0x11, 0x18, 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xFC, 0x1B, 0x66, 0x44, 0x64, 0x46,
+	 0x80, 0xF0, 0x60, 0x46, 0x80, 0xF8, 0x65, 0x46, 0x65, 0x43, 0x80, 0xF0, 0x01, 0xFA, 0x80, 0xFC,
+	 0x64, 0x46, 0x80, 0xF8, 0x0B, 0x00, 0x64, 0x46, 0x62, 0x43, 0x00, 0xF2, 0xA3, 0xDB, 0x60, 0x46,
+	 0x80, 0xF0, 0x81, 0xFC, 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8, 0x60, 0x43, 0x61, 0x46, 0x86, 0xF1,
+	 0x17, 0x60, 0x02, 0x61, 0xA1, 0xD3, 0xDA, 0x81, 0xD0, 0x80, 0xDC, 0x9C, 0x05, 0x05, 0xA1, 0xD3,
+	 0x4A, 0xD9, 0xA0, 0xDD, 0xDA, 0x9C, 0xA1, 0xD9, 0xD6, 0x60, 0x09, 0x78, 0xFF, 0xFF, 0x0B, 0x60,
+	 0x81, 0xF3, 0xFF, 0xFF, 0x62, 0x18, 0x17, 0x60, 0x02, 0x64, 0x04, 0xA5, 0xA0, 0xD1, 0x72, 0x44,
+	 0xFF, 0xB4, 0x64, 0x40, 0xE0, 0x22, 0x1F, 0xB4, 0x64, 0x40, 0xF8, 0x22, 0x07, 0xB4, 0x02, 0x00,
+	 0x03, 0x04, 0xD0, 0x84, 0xD0, 0x80, 0xFC, 0x01, 0xE0, 0x84, 0x44, 0xD3, 0xFF, 0xFF, 0x60, 0x43,
+	 0x66, 0x41, 0x63, 0x46, 0x05, 0xF2, 0x00, 0xF0, 0x81, 0xF0, 0x02, 0x18, 0x64, 0x46, 0x81, 0xF8,
+	 0x07, 0x1B, 0x15, 0x60, 0x02, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD9, 0x02, 0x00,
+	 0x65, 0x46, 0x00, 0xF8, 0x87, 0xF3, 0x63, 0x45, 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xD4, 0x80,
+	 0x01, 0x18, 0xFA, 0x04, 0x80, 0xF8, 0x65, 0x46, 0x00, 0xFA, 0x06, 0xF2, 0xFF, 0xFF, 0x00, 0x7E,
+	 0x06, 0xFA, 0x61, 0x46, 0x2E, 0xF0, 0x66, 0x41, 0x15, 0x60, 0x02, 0x65, 0x64, 0x47, 0x00, 0x7F,
+	 0x87, 0xF1, 0xE0, 0x84, 0x44, 0xD3, 0x64, 0x43, 0x11, 0x18, 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF,
+	 0xFC, 0x1B, 0x66, 0x44, 0x64, 0x46, 0x80, 0xF0, 0x60, 0x46, 0x80, 0xF8, 0x65, 0x46, 0x65, 0x43,
+	 0x80, 0xF0, 0x01, 0xFA, 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8, 0x0B, 0x00, 0x64, 0x46, 0x62, 0x43,
+	 0x00, 0xF2, 0xA3, 0xDB, 0x60, 0x46, 0x80, 0xF0, 0x81, 0xFC, 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8,
+	 0x60, 0x43, 0x61, 0x46, 0xD6, 0x60, 0x09, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x02, 0x61, 0xB5, 0x60,
+	 0x58, 0x4D, 0xA2, 0x78, 0xFF, 0xFF, 0x86, 0xF1, 0x72, 0x44, 0xFF, 0xB4, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x02, 0x04, 0xD0, 0x84, 0xFB, 0x01, 0xE0, 0x83, 0x87, 0xF3, 0x02, 0xA3, 0x43, 0x93, 0x66, 0x44,
+	 0x00, 0xA8, 0x56, 0xFD, 0x3A, 0x03, 0x00, 0x64, 0x2B, 0xFA, 0x00, 0x60, 0xC0, 0x64, 0x2A, 0xFA,
+	 0x66, 0x45, 0x63, 0x46, 0x03, 0xF2, 0x04, 0xF0, 0x85, 0xF2, 0x65, 0x46, 0x2C, 0xFA, 0x2D, 0xF8,
+	 0xAE, 0xFA, 0xCB, 0xF3, 0x2F, 0xFA, 0x32, 0xFA, 0xCC, 0xF3, 0x30, 0xFA, 0x33, 0xFA, 0xCD, 0xF3,
+	 0x31, 0xFA, 0x34, 0xFA, 0xAB, 0xF1, 0x19, 0xF8, 0xFF, 0x67, 0x0E, 0xFA, 0x66, 0x41, 0x43, 0x49,
+	 0x29, 0x46, 0x92, 0xF0, 0x2C, 0x60, 0x26, 0x63, 0x47, 0xD3, 0x61, 0x46, 0x02, 0x63, 0x00, 0x7E,
+	 0x13, 0xFA, 0x3F, 0xFC, 0x00, 0x64, 0x3E, 0xFA, 0x87, 0xF3, 0x07, 0xFA, 0x66, 0x41, 0x00, 0xF4,
+	 0x05, 0x64, 0x09, 0xFA, 0x1E, 0x60, 0xD4, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x61, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x56, 0xF3, 0xA3, 0xFF, 0x60, 0x43,
+	 0xE7, 0x60, 0x58, 0x4E, 0x81, 0x78, 0xFF, 0xFF, 0x56, 0xF3, 0xFF, 0xFF, 0x40, 0x58, 0x03, 0x65,
+	 0xE5, 0x60, 0x58, 0x4E, 0x51, 0x78, 0xFF, 0xFF, 0x56, 0xF3, 0x26, 0x46, 0x60, 0x43, 0x66, 0x41,
+	 0x63, 0x46, 0x05, 0xF2, 0x00, 0xF0, 0x81, 0xF0, 0x02, 0x18, 0x64, 0x46, 0x81, 0xF8, 0x07, 0x1B,
+	 0x15, 0x60, 0x02, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD9, 0x02, 0x00, 0x65, 0x46,
+	 0x00, 0xF8, 0x87, 0xF3, 0x63, 0x45, 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xD4, 0x80, 0x01, 0x18,
+	 0xFA, 0x04, 0x80, 0xF8, 0x65, 0x46, 0x00, 0xFA, 0x06, 0xF2, 0xFF, 0xFF, 0x00, 0x7E, 0x06, 0xFA,
+	 0x61, 0x46, 0x2E, 0xF0, 0x66, 0x41, 0x15, 0x60, 0x02, 0x65, 0x64, 0x47, 0x00, 0x7F, 0x87, 0xF1,
+	 0xE0, 0x84, 0x44, 0xD3, 0x64, 0x43, 0x11, 0x18, 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xFC, 0x1B,
+	 0x66, 0x44, 0x64, 0x46, 0x80, 0xF0, 0x60, 0x46, 0x80, 0xF8, 0x65, 0x46, 0x65, 0x43, 0x80, 0xF0,
+	 0x01, 0xFA, 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8, 0x0B, 0x00, 0x64, 0x46, 0x62, 0x43, 0x00, 0xF2,
+	 0xA3, 0xDB, 0x60, 0x46, 0x80, 0xF0, 0x81, 0xFC, 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8, 0x60, 0x43,
+	 0x61, 0x46, 0x2C, 0xF2, 0x2D, 0xF0, 0xAE, 0xF2, 0x66, 0x45, 0x63, 0x46, 0x03, 0xFA, 0x04, 0xF8,
+	 0x55, 0xF3, 0x85, 0xFA, 0xFF, 0xA0, 0x65, 0x46, 0x03, 0x03, 0xD7, 0x60, 0xAE, 0x78, 0xFF, 0xFF,
+	 0x94, 0xF3, 0x66, 0x45, 0x63, 0x46, 0x1F, 0xFA, 0x65, 0x46, 0xBA, 0x65, 0x60, 0x44, 0xC4, 0x85,
+	 0x01, 0x60, 0xFE, 0x61, 0x00, 0x64, 0x80, 0x63, 0xC7, 0x85, 0x94, 0x84, 0x59, 0xDB, 0xFC, 0x1F,
+	 0x00, 0x60, 0x88, 0x64, 0x3F, 0xFA, 0x00, 0xF4, 0x02, 0x64, 0x0A, 0xFA, 0x00, 0x64, 0x0B, 0xFA,
+	 0x80, 0x7F, 0x10, 0x7E, 0x0C, 0xFA, 0x1A, 0x65, 0x80, 0x61, 0x02, 0x60, 0x00, 0x63, 0x0F, 0x4E,
+	 0xF8, 0x60, 0x58, 0x4F, 0x7A, 0x78, 0xFF, 0xFF, 0x0E, 0x4F, 0xD7, 0x60, 0x80, 0x78, 0xFF, 0xFF,
+	 0x26, 0x46, 0x23, 0xF0, 0x00, 0x60, 0x02, 0x64, 0xA0, 0x80, 0x00, 0xF4, 0x03, 0x03, 0xD7, 0x60,
+	 0x2A, 0x78, 0xFF, 0xFF, 0x09, 0xF2, 0xFF, 0xFF, 0xFF, 0xA0, 0x00, 0xA0, 0x0C, 0x03, 0x03, 0x03,
+	 0xD6, 0x60, 0xA7, 0x78, 0xFF, 0xFF, 0x0A, 0xF2, 0x26, 0x46, 0xFF, 0xA0, 0x87, 0xF4, 0x10, 0x02,
+	 0xD7, 0x60, 0xAE, 0x78, 0xFF, 0xFF, 0x0A, 0xF2, 0xFF, 0xFF, 0xFF, 0xA0, 0xFD, 0xA0, 0x02, 0x03,
+	 0x04, 0x03, 0x06, 0x00, 0xD6, 0x60, 0xE6, 0x78, 0xFF, 0xFF, 0xD6, 0x60, 0xF1, 0x78, 0xFF, 0xFF,
+	 0x26, 0x46, 0x87, 0xF4, 0x66, 0x41, 0x63, 0x46, 0x05, 0xF2, 0x00, 0xF0, 0x81, 0xF0, 0x02, 0x18,
+	 0x64, 0x46, 0x81, 0xF8, 0x07, 0x1B, 0x15, 0x60, 0x02, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84,
+	 0x44, 0xD9, 0x02, 0x00, 0x65, 0x46, 0x00, 0xF8, 0x87, 0xF3, 0x63, 0x45, 0x60, 0x46, 0x00, 0xF2,
+	 0xFF, 0xFF, 0xD4, 0x80, 0x01, 0x18, 0xFA, 0x04, 0x80, 0xF8, 0x65, 0x46, 0x00, 0xFA, 0x06, 0xF2,
+	 0xFF, 0xFF, 0x00, 0x7E, 0x06, 0xFA, 0x61, 0x46, 0x0B, 0x60, 0x82, 0xF3, 0xDA, 0x81, 0x60, 0x45,
+	 0xD5, 0x80, 0xA1, 0xD1, 0x11, 0x03, 0xD3, 0x80, 0xD9, 0x81, 0xFA, 0x02, 0xC9, 0x81, 0xC8, 0x85,
+	 0xD5, 0x80, 0xA5, 0xD3, 0x08, 0x28, 0xA1, 0xDB, 0x17, 0x60, 0x04, 0x62, 0x65, 0x44, 0xA2, 0xDB,
+	 0x4A, 0xD3, 0xFF, 0xFF, 0xCC, 0x84, 0xA2, 0xDB, 0xD4, 0x60, 0xA4, 0x78, 0xFF, 0xFF, 0x26, 0x46,
+	 0x87, 0xF4, 0x66, 0x41, 0x63, 0x46, 0x05, 0xF2, 0x00, 0xF0, 0x81, 0xF0, 0x02, 0x18, 0x64, 0x46,
+	 0x81, 0xF8, 0x07, 0x1B, 0x15, 0x60, 0x02, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD9,
+	 0x02, 0x00, 0x65, 0x46, 0x00, 0xF8, 0x87, 0xF3, 0x63, 0x45, 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF,
+	 0xD4, 0x80, 0x01, 0x18, 0xFA, 0x04, 0x80, 0xF8, 0x65, 0x46, 0x00, 0xFA, 0x06, 0xF2, 0xFF, 0xFF,
+	 0x00, 0x7E, 0x06, 0xFA, 0x61, 0x46, 0x0B, 0x60, 0x82, 0xF3, 0xDA, 0x81, 0x60, 0x45, 0xD5, 0x80,
+	 0xA1, 0xD1, 0x11, 0x03, 0xD3, 0x80, 0xD9, 0x81, 0xFA, 0x02, 0xC9, 0x81, 0xC8, 0x85, 0xD5, 0x80,
+	 0xA5, 0xD3, 0x08, 0x28, 0xA1, 0xDB, 0x17, 0x60, 0x04, 0x62, 0x65, 0x44, 0xA2, 0xDB, 0x4A, 0xD3,
+	 0xFF, 0xFF, 0xCC, 0x84, 0xA2, 0xDB, 0xD4, 0x60, 0xAF, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x32, 0x44,
+	 0x08, 0xB0, 0x87, 0xF4, 0x03, 0x02, 0xD4, 0x60, 0xAF, 0x78, 0xFF, 0xFF, 0xD6, 0x60, 0x18, 0x78,
+	 0xFF, 0xFF, 0x32, 0x44, 0x26, 0x46, 0x08, 0xB0, 0x07, 0xF2, 0x03, 0x02, 0xD4, 0x60, 0xAF, 0x78,
+	 0xFF, 0xFF, 0x60, 0x46, 0x1F, 0xF2, 0x26, 0x46, 0xBA, 0x65, 0x60, 0x44, 0xC4, 0x85, 0x01, 0x60,
+	 0xFE, 0x61, 0x00, 0x64, 0x80, 0x63, 0xC7, 0x85, 0x94, 0x84, 0x59, 0xDB, 0xFC, 0x1F, 0x00, 0xF4,
+	 0x01, 0x60, 0xFE, 0x61, 0x7E, 0x65, 0x18, 0x63, 0x5B, 0xD2, 0x59, 0xD1, 0xFF, 0xFF, 0xD0, 0x80,
+	 0xD7, 0x80, 0x18, 0x02, 0xF9, 0x02, 0x00, 0xF4, 0x02, 0x63, 0x0E, 0x65, 0x5B, 0xD2, 0x59, 0xD1,
+	 0xFF, 0xFF, 0xD0, 0x80, 0xD7, 0x80, 0x0E, 0x02, 0xF9, 0x02, 0x26, 0x46, 0x07, 0xF4, 0x06, 0xF2,
+	 0xFF, 0xFF, 0x01, 0x7E, 0x06, 0xFA, 0x26, 0x46, 0x00, 0xF4, 0x04, 0x64, 0x0A, 0xFA, 0x00, 0x64,
+	 0x0B, 0xFA, 0x56, 0x00, 0x26, 0x46, 0x87, 0xF4, 0x66, 0x41, 0x63, 0x46, 0x05, 0xF2, 0x00, 0xF0,
+	 0x81, 0xF0, 0x02, 0x18, 0x64, 0x46, 0x81, 0xF8, 0x07, 0x1B, 0x15, 0x60, 0x02, 0x65, 0x60, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD9, 0x02, 0x00, 0x65, 0x46, 0x00, 0xF8, 0x87, 0xF3, 0x63, 0x45,
+	 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xD4, 0x80, 0x01, 0x18, 0xFA, 0x04, 0x80, 0xF8, 0x65, 0x46,
+	 0x00, 0xFA, 0x06, 0xF2, 0xFF, 0xFF, 0x00, 0x7E, 0x06, 0xFA, 0x61, 0x46, 0x0B, 0x60, 0x82, 0xF3,
+	 0xDA, 0x81, 0x60, 0x45, 0xD5, 0x80, 0xA1, 0xD1, 0x11, 0x03, 0xD3, 0x80, 0xD9, 0x81, 0xFA, 0x02,
+	 0xC9, 0x81, 0xC8, 0x85, 0xD5, 0x80, 0xA5, 0xD3, 0x08, 0x28, 0xA1, 0xDB, 0x17, 0x60, 0x04, 0x62,
+	 0x65, 0x44, 0xA2, 0xDB, 0x4A, 0xD3, 0xFF, 0xFF, 0xCC, 0x84, 0xA2, 0xDB, 0x00, 0xF4, 0x04, 0x64,
+	 0x0A, 0xFA, 0x0F, 0x64, 0x0B, 0xFA, 0x40, 0x59, 0x02, 0x60, 0x00, 0x61, 0x41, 0x58, 0x26, 0x46,
+	 0x2C, 0xF2, 0xA1, 0xDB, 0x2D, 0xF2, 0x59, 0xDB, 0x2E, 0xF2, 0x59, 0xDB, 0x03, 0x65, 0xE5, 0x60,
+	 0x58, 0x4E, 0x27, 0x78, 0xFF, 0xFF, 0x03, 0x65, 0xE5, 0x60, 0x58, 0x4E, 0x51, 0x78, 0xFF, 0xFF,
+	 0x26, 0x46, 0x87, 0xF3, 0x07, 0xFA, 0x1E, 0x60, 0xD4, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x26, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x00, 0x66, 0x46, 0x46,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0xF4, 0x0A, 0xF2, 0x09, 0xF2, 0xFF, 0xA0, 0x00, 0xA0, 0x06, 0x02,
+	 0xFF, 0xA0, 0x07, 0x03, 0x09, 0x03, 0xD6, 0x60, 0xA7, 0x78, 0xFF, 0xFF, 0xD6, 0x60, 0x68, 0x78,
+	 0xFF, 0xFF, 0xD7, 0x60, 0xB3, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x07, 0xF4, 0x06, 0xF2, 0x66, 0x43,
+	 0x00, 0x7E, 0x06, 0xFA, 0x26, 0x46, 0xD6, 0x60, 0x18, 0x78, 0xFF, 0xFF, 0x63, 0x46, 0x06, 0xF2,
+	 0xFF, 0xFF, 0x01, 0x7E, 0x06, 0xFA, 0x26, 0x46, 0x87, 0xF3, 0x07, 0xFA, 0x00, 0xF4, 0x02, 0x64,
+	 0x0A, 0xFA, 0x00, 0x64, 0x0B, 0xFA, 0x1E, 0x60, 0xD4, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x26, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x00, 0x66, 0x46, 0x46,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x01, 0x61, 0x00, 0x60, 0x10, 0x7C, 0x2A, 0xF2, 0x0C, 0x60, 0x70, 0xFB,
+	 0xFF, 0xB4, 0x16, 0x60, 0x83, 0xFB, 0x60, 0x40, 0x00, 0x36, 0x03, 0x00, 0x02, 0x61, 0x00, 0x60,
+	 0x30, 0x7C, 0x41, 0x47, 0x2A, 0xF8, 0x2F, 0xF2, 0x2C, 0xFA, 0x30, 0xF2, 0x2D, 0xFA, 0x31, 0xF2,
+	 0x2E, 0xFA, 0xCB, 0xF3, 0x2F, 0xFA, 0xCC, 0xF3, 0x30, 0xFA, 0xCD, 0xF3, 0x31, 0xFA, 0x66, 0xF3,
+	 0x32, 0xFA, 0x67, 0xF3, 0x33, 0xFA, 0x68, 0xF3, 0x34, 0xFA, 0xAB, 0xF1, 0x19, 0xF8, 0x00, 0x7C,
+	 0x3E, 0xF8, 0x1C, 0xF0, 0x13, 0xF8, 0x07, 0xF2, 0x87, 0xF1, 0xFF, 0xFF, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x03, 0x02, 0xDC, 0x60, 0x55, 0x78, 0xFF, 0xFF, 0x40, 0x4B, 0x01, 0x65, 0xEF, 0x60, 0x58, 0x4E,
+	 0xDC, 0x78, 0xFF, 0xFF, 0xAB, 0x46, 0x06, 0xF2, 0xAB, 0x46, 0x00, 0xF4, 0x01, 0xB0, 0xFF, 0xFF,
+	 0x03, 0x02, 0xDC, 0x60, 0x55, 0x78, 0xFF, 0xFF, 0x09, 0xF2, 0x16, 0x60, 0x84, 0xFB, 0x5A, 0x84,
+	 0x00, 0x63, 0x60, 0x40, 0x20, 0x26, 0x02, 0xBB, 0x60, 0x40, 0x04, 0x27, 0x04, 0xBB, 0xAB, 0x46,
+	 0x78, 0xFC, 0xAB, 0x46, 0xFF, 0xFF, 0x10, 0xB0, 0x80, 0x60, 0x00, 0x63, 0x0C, 0x03, 0x13, 0x60,
+	 0x45, 0xF1, 0xFF, 0xFF, 0x64, 0x44, 0xFE, 0x26, 0x08, 0x00, 0x32, 0x40, 0x08, 0x26, 0x06, 0x00,
+	 0xDC, 0x60, 0xB9, 0x78, 0xFF, 0xFF, 0x32, 0x40, 0x10, 0x2A, 0x00, 0x63, 0xAB, 0x46, 0x06, 0xF0,
+	 0x7F, 0x60, 0xFF, 0x64, 0xA0, 0x84, 0x63, 0x45, 0xB4, 0x84, 0x06, 0xFA, 0xAB, 0x46, 0x0A, 0xF0,
+	 0x56, 0xF9, 0x24, 0xD9, 0x5A, 0x84, 0x01, 0x63, 0x32, 0x40, 0x10, 0x26, 0x10, 0xBB, 0x13, 0x60,
+	 0x45, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0xFE, 0x26, 0x10, 0xBB, 0x15, 0x60, 0xDD, 0xF1, 0x63, 0x44,
+	 0x20, 0xBC, 0xFB, 0x60, 0xFF, 0xB7, 0x64, 0x40, 0x10, 0x26, 0x04, 0xBC, 0x60, 0x47, 0x60, 0x43,
+	 0x09, 0xFC, 0x27, 0x44, 0xFE, 0xA0, 0xFF, 0xFF, 0x03, 0x03, 0xD8, 0x60, 0xC8, 0x78, 0xFF, 0xFF,
+	 0x18, 0x60, 0xD6, 0x64, 0x24, 0x43, 0x0B, 0xF0, 0xA0, 0xD9, 0xBD, 0xD9, 0x0C, 0xF0, 0x58, 0xD9,
+	 0xBD, 0xD9, 0x0D, 0xF0, 0x58, 0xD9, 0xBD, 0xD9, 0x43, 0x44, 0x26, 0x46, 0x87, 0xF2, 0x3F, 0xF2,
+	 0x41, 0x4B, 0x00, 0xF4, 0x60, 0x43, 0xF6, 0xA3, 0x00, 0x60, 0x1B, 0x61, 0x00, 0x60, 0x01, 0x65,
+	 0x01, 0x60, 0xFF, 0x64, 0x40, 0x4C, 0xEF, 0x60, 0x58, 0x4E, 0x79, 0x78, 0xFF, 0xFF, 0x00, 0xBB,
+	 0xFF, 0xFF, 0x00, 0x02, 0x00, 0x64, 0x40, 0x4A, 0x60, 0xFE, 0x02, 0x60, 0x00, 0x63, 0xBD, 0xD3,
+	 0xBD, 0xD3, 0x60, 0x41, 0xF0, 0x60, 0x58, 0x4E, 0x27, 0x78, 0xFF, 0xFF, 0x20, 0xFE, 0x26, 0x46,
+	 0x3F, 0xF2, 0x00, 0xF4, 0x60, 0x43, 0xF6, 0xA3, 0x00, 0x60, 0x1B, 0x61, 0x00, 0x60, 0x32, 0x65,
+	 0x01, 0x60, 0xFF, 0x64, 0x40, 0x4C, 0xEF, 0x60, 0x58, 0x4E, 0x79, 0x78, 0xFF, 0xFF, 0x00, 0xBB,
+	 0xFF, 0xFF, 0x0B, 0x03, 0x60, 0xFE, 0x02, 0x60, 0x00, 0x63, 0xBD, 0xD3, 0xBD, 0xD3, 0x60, 0x41,
+	 0xF0, 0x60, 0x58, 0x4E, 0x27, 0x78, 0xFF, 0xFF, 0x00, 0x00, 0x20, 0xFE, 0x30, 0x60, 0x20, 0x61,
+	 0xA1, 0xD1, 0x82, 0xF3, 0x01, 0x60, 0x6E, 0x63, 0x60, 0x45, 0x2A, 0x44, 0x60, 0xFB, 0xA3, 0xD5,
+	 0x65, 0x40, 0x01, 0x27, 0x5B, 0xD5, 0x65, 0x40, 0x01, 0x27, 0x59, 0xD1, 0x66, 0x41, 0xA0, 0x84,
+	 0x24, 0x94, 0x2B, 0x46, 0x0F, 0xFA, 0x61, 0xFB, 0x16, 0x64, 0x12, 0xFA, 0x01, 0x64, 0x11, 0xFA,
+	 0x66, 0x5C, 0xC1, 0x60, 0x58, 0x4E, 0x93, 0x78, 0xFF, 0xFF, 0xD9, 0x60, 0x28, 0x78, 0xFF, 0xFF,
+	 0x26, 0x46, 0x87, 0xF2, 0x3F, 0xF2, 0x41, 0x4B, 0x00, 0xF4, 0x60, 0x43, 0xFC, 0xA3, 0x00, 0x60,
+	 0x15, 0x61, 0x00, 0x60, 0x01, 0x65, 0x01, 0x60, 0xFF, 0x64, 0x40, 0x4C, 0xEF, 0x60, 0x58, 0x4E,
+	 0x79, 0x78, 0xFF, 0xFF, 0x00, 0xBB, 0xFF, 0xFF, 0x00, 0x02, 0x00, 0x64, 0x40, 0x4A, 0x60, 0xFE,
+	 0x02, 0x60, 0x00, 0x63, 0xBD, 0xD3, 0xBD, 0xD3, 0x60, 0x41, 0xF0, 0x60, 0x58, 0x4E, 0x27, 0x78,
+	 0xFF, 0xFF, 0x20, 0xFE, 0x26, 0x46, 0x3F, 0xF2, 0x00, 0xF4, 0x60, 0x43, 0xFC, 0xA3, 0x00, 0x60,
+	 0x15, 0x61, 0x00, 0x60, 0x32, 0x65, 0x01, 0x60, 0xFF, 0x64, 0x40, 0x4C, 0xEF, 0x60, 0x58, 0x4E,
+	 0x79, 0x78, 0xFF, 0xFF, 0x00, 0xBB, 0xFF, 0xFF, 0x0B, 0x03, 0x60, 0xFE, 0x02, 0x60, 0x00, 0x63,
+	 0xBD, 0xD3, 0xBD, 0xD3, 0x60, 0x41, 0xF0, 0x60, 0x58, 0x4E, 0x27, 0x78, 0xFF, 0xFF, 0x00, 0x00,
+	 0x20, 0xFE, 0x30, 0x60, 0x20, 0x61, 0xA1, 0xD1, 0x82, 0xF3, 0x01, 0x60, 0x6E, 0x63, 0x60, 0x45,
+	 0x2A, 0x44, 0x60, 0xFB, 0xA3, 0xD5, 0x65, 0x40, 0x01, 0x27, 0x5B, 0xD5, 0x65, 0x40, 0x01, 0x27,
+	 0x59, 0xD1, 0x66, 0x41, 0xA0, 0x84, 0x24, 0x94, 0x2B, 0x46, 0x0F, 0xFA, 0x61, 0xFB, 0x16, 0x64,
+	 0x12, 0xFA, 0x01, 0x64, 0x11, 0xFA, 0x66, 0x5C, 0xC1, 0x60, 0x58, 0x4E, 0x93, 0x78, 0xFF, 0xFF,
+	 0x2B, 0x46, 0x0F, 0xF2, 0x12, 0x63, 0x7C, 0x18, 0x26, 0x46, 0x87, 0xF2, 0x01, 0x65, 0x41, 0x4B,
+	 0xAB, 0x46, 0x0F, 0xF2, 0xFF, 0xFF, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xFF, 0x22,
+	 0x00, 0x65, 0x78, 0xF2, 0xFF, 0xFF, 0xB4, 0x84, 0x78, 0xFA, 0xAB, 0x46, 0xFF, 0xFF, 0x26, 0x46,
+	 0x3F, 0xF2, 0x00, 0xF4, 0x16, 0x65, 0x27, 0x40, 0x02, 0x3A, 0x03, 0x00, 0x1C, 0x65, 0xF6, 0xA4,
+	 0x01, 0x00, 0xFC, 0xA4, 0x24, 0x43, 0x2D, 0x60, 0x5E, 0x61, 0x5D, 0x91, 0x51, 0x90, 0xFF, 0xFF,
+	 0x04, 0x28, 0x60, 0x41, 0xCD, 0x84, 0x4C, 0x91, 0x60, 0x43, 0x60, 0xFE, 0xA5, 0xD2, 0xDE, 0x85,
+	 0x7F, 0x26, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0x5D, 0x93, 0xA3, 0xDB, 0x5D, 0x93, 0xA5, 0xD2,
+	 0xF6, 0x1F, 0x5D, 0x93, 0x20, 0xFE, 0xDF, 0x83, 0x2D, 0x60, 0x04, 0x7C, 0x03, 0x1E, 0x60, 0xFE,
+	 0xBD, 0xDF, 0x20, 0xFE, 0x2D, 0x60, 0x08, 0x64, 0x53, 0x93, 0xA4, 0xDD, 0x26, 0x46, 0x00, 0xF4,
+	 0x13, 0x60, 0x44, 0xF3, 0x00, 0x63, 0x00, 0xB8, 0x0A, 0xFC, 0x03, 0x02, 0xD9, 0x60, 0xCF, 0x78,
+	 0xFF, 0xFF, 0x0B, 0xF2, 0x27, 0x40, 0x02, 0x3A, 0x02, 0x00, 0x0E, 0xF2, 0xFF, 0xFF, 0x60, 0x47,
+	 0x00, 0x3A, 0x25, 0x00, 0x60, 0x41, 0x00, 0x36, 0x22, 0x00, 0xE0, 0xA0, 0xDA, 0x85, 0x1F, 0x07,
+	 0x13, 0x60, 0x0B, 0xF1, 0x65, 0x42, 0xD1, 0x80, 0x26, 0x60, 0x18, 0x63, 0x18, 0x02, 0x50, 0xFE,
+	 0x61, 0x40, 0xFE, 0x22, 0x08, 0x00, 0x62, 0x45, 0xBD, 0xD3, 0xA5, 0xD0, 0xDA, 0x82, 0xD0, 0x80,
+	 0xC9, 0x81, 0xF6, 0x0C, 0x0C, 0x00, 0x61, 0x40, 0x00, 0x36, 0x31, 0x00, 0x62, 0x45, 0xA3, 0xD3,
+	 0xA5, 0xD0, 0xFF, 0xFF, 0x90, 0x80, 0xFF, 0x26, 0x02, 0x00, 0xDE, 0x82, 0x28, 0x00, 0x0C, 0x63,
+	 0x0A, 0xFC, 0x00, 0x64, 0x09, 0xFA, 0x0B, 0xFA, 0x01, 0x7E, 0x0C, 0xFA, 0x26, 0x46, 0x08, 0x64,
+	 0x3F, 0xFA, 0x07, 0xF2, 0x87, 0xF1, 0x40, 0x58, 0x07, 0xF8, 0x1E, 0x60, 0xD4, 0x64, 0x0F, 0x60,
+	 0x90, 0xFB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE,
+	 0xDC, 0x60, 0xD4, 0x78, 0xFF, 0xFF, 0x20, 0xFE, 0x16, 0x60, 0x50, 0xF3, 0xFF, 0xFF, 0x22, 0xB0,
+	 0xFF, 0xFF, 0x03, 0x03, 0xDB, 0x60, 0xB1, 0x78, 0xFF, 0xFF, 0x01, 0x63, 0xD9, 0x01, 0x13, 0x60,
+	 0x45, 0xF3, 0xFF, 0xFF, 0xFF, 0xA4, 0xFF, 0xFF, 0x0C, 0x20, 0x03, 0x00, 0xDB, 0x60, 0xB1, 0x78,
+	 0xFF, 0xFF, 0x00, 0x64, 0x16, 0x60, 0x56, 0xFB, 0x16, 0x60, 0x57, 0xFB, 0x16, 0x60, 0x58, 0xFB,
+	 0x16, 0x60, 0x5A, 0xFB, 0x16, 0x60, 0x5B, 0xFB, 0x16, 0x60, 0x5C, 0xFB, 0x16, 0x60, 0x5D, 0xFB,
+	 0x18, 0x60, 0x17, 0xFB, 0x2B, 0x46, 0x3B, 0xF2, 0x7F, 0x60, 0xCF, 0x65, 0xA4, 0x84, 0xA2, 0xDA,
+	 0x26, 0x46, 0x00, 0xF4, 0x0B, 0xF2, 0x27, 0x40, 0x02, 0x3A, 0x02, 0x00, 0x0E, 0xF2, 0xFF, 0xFF,
+	 0xCE, 0x81, 0x20, 0xFE, 0x30, 0x60, 0x28, 0x64, 0x40, 0x4A, 0xDA, 0x60, 0x58, 0x4D, 0x62, 0x78,
+	 0xFF, 0xFF, 0x20, 0xFE, 0x18, 0x60, 0x17, 0xF3, 0xFF, 0xFF, 0x08, 0x18, 0x18, 0x60, 0x19, 0xF3,
+	 0x18, 0x60, 0x1A, 0xF5, 0x60, 0x41, 0x30, 0x60, 0x2E, 0x62, 0xA2, 0xDF, 0x2A, 0xD1, 0xDA, 0x85,
+	 0x64, 0x44, 0x01, 0xA0, 0xFF, 0xFF, 0x01, 0x02, 0x75, 0x00, 0x45, 0x4A, 0x7C, 0x44, 0x60, 0xFE,
+	 0xA1, 0xD2, 0xFF, 0xFF, 0xD0, 0x80, 0x20, 0xFE, 0x01, 0x03, 0xE3, 0x01, 0x30, 0x60, 0x2E, 0x62,
+	 0xA2, 0xDF, 0x60, 0xFE, 0x5D, 0xD2, 0xFF, 0xFF, 0x60, 0x5C, 0x41, 0x94, 0x81, 0xA0, 0x20, 0xFE,
+	 0x2D, 0x04, 0x01, 0x64, 0x18, 0x60, 0x17, 0xFB, 0xC1, 0x84, 0x84, 0xA4, 0x18, 0x60, 0x19, 0xFB,
+	 0x00, 0xF2, 0x18, 0x60, 0x1A, 0xFB, 0x18, 0x60, 0x18, 0xFD, 0x02, 0x60, 0x00, 0x63, 0xCD, 0x85,
+	 0x64, 0x44, 0xD8, 0x81, 0xCD, 0x84, 0x4C, 0x91, 0x60, 0x43, 0x60, 0xFE, 0xA5, 0xD2, 0xDE, 0x85,
+	 0x7F, 0x26, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0x5D, 0x93, 0xA3, 0xDB, 0x5D, 0x93, 0xA5, 0xD2,
+	 0xF6, 0x1F, 0x5D, 0x93, 0x20, 0xFE, 0xDF, 0x83, 0x00, 0x60, 0x01, 0x61, 0x02, 0x60, 0x00, 0x64,
+	 0xE0, 0x87, 0x60, 0x46, 0x18, 0x60, 0x18, 0xF3, 0xFF, 0xFF, 0x60, 0x43, 0x60, 0xFE, 0xCD, 0x81,
+	 0x20, 0xFE, 0x2A, 0x44, 0x00, 0x60, 0x02, 0x65, 0x44, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0xDB, 0x60,
+	 0x5C, 0x78, 0xFF, 0xFF, 0x18, 0x60, 0x17, 0xF3, 0xFF, 0xFF, 0x08, 0x18, 0x18, 0x60, 0x19, 0xF3,
+	 0x18, 0x60, 0x1A, 0xF5, 0x60, 0x41, 0x30, 0x60, 0x2E, 0x62, 0xA2, 0xDF, 0x66, 0x5C, 0x26, 0x46,
+	 0x00, 0xF2, 0x64, 0x46, 0x58, 0x90, 0xFF, 0xFF, 0x03, 0x02, 0x61, 0x44, 0x0B, 0xA5, 0x04, 0x00,
+	 0x61, 0x44, 0xFC, 0xA4, 0x8B, 0x7C, 0xC0, 0x85, 0xDD, 0x81, 0x66, 0x44, 0x18, 0x60, 0x1A, 0xFB,
+	 0x26, 0x46, 0x1B, 0xF0, 0x18, 0x60, 0x1A, 0xF5, 0x64, 0x44, 0xD4, 0x80, 0xFF, 0xFF, 0xD7, 0x06,
+	 0x2D, 0x58, 0xFF, 0xFF, 0x60, 0xFE, 0x5D, 0xD2, 0xFF, 0xFF, 0x20, 0xFE, 0xFF, 0xB4, 0x41, 0x94,
+	 0x81, 0xA0, 0xFF, 0xFF, 0x02, 0x04, 0x00, 0xF4, 0x84, 0xA4, 0x60, 0x41, 0x62, 0x01, 0x60, 0xFE,
+	 0x5D, 0xD2, 0xFF, 0xFF, 0xFA, 0xA4, 0xFF, 0xFF, 0x04, 0x20, 0x02, 0x00, 0xFF, 0xA1, 0x61, 0x01,
+	 0x5D, 0xD0, 0xFF, 0xFF, 0x64, 0x40, 0x00, 0x36, 0x02, 0x00, 0xC9, 0x81, 0x5A, 0x01, 0x5D, 0xD0,
+	 0xFF, 0xFF, 0x64, 0x40, 0x50, 0x36, 0x02, 0x00, 0xFD, 0xA1, 0x53, 0x01, 0x5D, 0xD0, 0xFF, 0xFF,
+	 0x64, 0x40, 0xF2, 0x36, 0x04, 0x00, 0xFC, 0xA1, 0xDA, 0x60, 0x01, 0x78, 0xFF, 0xFF, 0x5D, 0xD0,
+	 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x36, 0x04, 0x00, 0xFB, 0xA1, 0xDA, 0x60, 0x01, 0x78, 0xFF, 0xFF,
+	 0x5D, 0xD0, 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x36, 0x04, 0x00, 0xFA, 0xA1, 0xDA, 0x60, 0x01, 0x78,
+	 0xFF, 0xFF, 0x5D, 0xD0, 0xFF, 0xFF, 0x64, 0x40, 0x00, 0x36, 0x04, 0x00, 0xF9, 0xA1, 0xDA, 0x60,
+	 0x01, 0x78, 0xFF, 0xFF, 0x60, 0x5C, 0x00, 0x36, 0x2A, 0x00, 0x00, 0x64, 0xDB, 0x60, 0x58, 0x4E,
+	 0x16, 0x78, 0xFF, 0xFF, 0x16, 0x60, 0x5A, 0xFB, 0x64, 0x40, 0x00, 0x36, 0x25, 0x00, 0x5D, 0xD2,
+	 0xDD, 0x81, 0xDB, 0x60, 0x58, 0x4E, 0x16, 0x78, 0xFF, 0xFF, 0x16, 0x60, 0x5B, 0xFB, 0x64, 0x40,
+	 0x00, 0x36, 0x1F, 0x00, 0x5D, 0xD2, 0xDD, 0x81, 0xDB, 0x60, 0x58, 0x4E, 0x16, 0x78, 0xFF, 0xFF,
+	 0x16, 0x60, 0x5C, 0xFB, 0x64, 0x40, 0x00, 0x36, 0x19, 0x00, 0x5D, 0xD0, 0x16, 0x60, 0x5D, 0xF9,
+	 0x5D, 0xD0, 0x2C, 0x60, 0xBB, 0x62, 0xA2, 0xD9, 0xD9, 0x60, 0xF9, 0x78, 0xFF, 0xFF, 0x20, 0xFE,
+	 0x00, 0x60, 0x04, 0x64, 0x16, 0x60, 0x5A, 0xFB, 0x20, 0xFE, 0x00, 0x60, 0x04, 0x64, 0x16, 0x60,
+	 0x5B, 0xFB, 0x20, 0xFE, 0x00, 0x60, 0x02, 0x64, 0x16, 0x60, 0x5C, 0xFB, 0x20, 0xFE, 0x00, 0x60,
+	 0x00, 0x64, 0x16, 0x60, 0x5D, 0xFB, 0xD9, 0x60, 0xF9, 0x78, 0xFF, 0xFF, 0x16, 0x60, 0x5E, 0xFB,
+	 0xE0, 0x84, 0xE0, 0x84, 0x03, 0x02, 0x01, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x02, 0xA5, 0x64, 0x44,
+	 0xD4, 0x9C, 0x16, 0x60, 0x5F, 0xF9, 0x2C, 0x60, 0xC0, 0x62, 0xA2, 0xDF, 0x5D, 0xD0, 0x00, 0x65,
+	 0x64, 0x40, 0x00, 0x3A, 0x01, 0x65, 0x5D, 0xD0, 0xFF, 0xFF, 0x64, 0x40, 0x50, 0x3A, 0x01, 0x65,
+	 0x5D, 0xD0, 0xFF, 0xFF, 0x64, 0x40, 0xF2, 0x3A, 0x01, 0x65, 0x5D, 0xD0, 0x65, 0x40, 0x00, 0x3A,
+	 0x17, 0x00, 0x00, 0x60, 0x00, 0x65, 0x64, 0x40, 0x00, 0x36, 0x01, 0x65, 0x64, 0x40, 0x01, 0x36,
+	 0x02, 0x65, 0x64, 0x40, 0x02, 0x36, 0x04, 0x65, 0x64, 0x40, 0x04, 0x36, 0x10, 0x65, 0x64, 0x40,
+	 0x05, 0x36, 0x20, 0x65, 0x65, 0x5C, 0x16, 0x60, 0x60, 0xF3, 0xFF, 0xFF, 0xB0, 0x84, 0xA2, 0xDB,
+	 0x16, 0x60, 0x5E, 0xF3, 0xFF, 0xFF, 0xFF, 0xA4, 0xA2, 0xDB, 0xD0, 0x02, 0x16, 0x60, 0x60, 0xF3,
+	 0x16, 0x60, 0x5F, 0xF1, 0x2E, 0x58, 0xFF, 0xFF, 0x20, 0xFE, 0x16, 0x60, 0x50, 0xF1, 0x16, 0x60,
+	 0x5A, 0xF3, 0xFF, 0xFF, 0xA0, 0x84, 0xFF, 0xFF, 0x10, 0x26, 0x09, 0x00, 0x04, 0x26, 0x09, 0x00,
+	 0x20, 0x26, 0x09, 0x00, 0x02, 0x26, 0x09, 0x00, 0xD9, 0x60, 0xC3, 0x78, 0xFF, 0xFF, 0x10, 0x7C,
+	 0x05, 0x00, 0x04, 0x7C, 0x03, 0x00, 0x20, 0x7C, 0x01, 0x00, 0x02, 0x7C, 0x16, 0x60, 0x56, 0xF9,
+	 0x16, 0x60, 0x51, 0xF1, 0x16, 0x60, 0x5B, 0xF3, 0x2C, 0x60, 0xAC, 0x62, 0xA0, 0x84, 0xA2, 0xD1,
+	 0xFF, 0xFF, 0x10, 0x26, 0x07, 0x00, 0x04, 0x26, 0x07, 0x00, 0x01, 0x26, 0x0D, 0x00, 0xD9, 0x60,
+	 0xC3, 0x78, 0xFF, 0xFF, 0x10, 0x7C, 0x09, 0x00, 0x64, 0x40, 0x10, 0x22, 0x03, 0x00, 0xD9, 0x60,
+	 0xC3, 0x78, 0xFF, 0xFF, 0x04, 0x7C, 0x01, 0x00, 0x01, 0x7C, 0x16, 0x60, 0x57, 0xF9, 0x16, 0x60,
+	 0x52, 0xF1, 0x16, 0x60, 0x5C, 0xF3, 0xFF, 0xFF, 0xA0, 0x84, 0x02, 0x26, 0x07, 0x00, 0x04, 0x26,
+	 0x07, 0x00, 0x01, 0x26, 0x07, 0x00, 0xD9, 0x60, 0xC3, 0x78, 0xFF, 0xFF, 0x02, 0x7C, 0x03, 0x00,
+	 0x04, 0x7C, 0x01, 0x00, 0x20, 0x7C, 0x16, 0x60, 0x58, 0xF9, 0x16, 0x60, 0x5D, 0xF1, 0x16, 0x60,
+	 0x59, 0xF9, 0x16, 0x60, 0x58, 0xF3, 0x16, 0x60, 0x57, 0xF1, 0x60, 0x47, 0xB0, 0x84, 0x13, 0x60,
+	 0x45, 0xF1, 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x36, 0x22, 0xBC, 0xAB, 0x46, 0x3A, 0xFA, 0xAB, 0x46,
+	 0x16, 0x60, 0x56, 0xF3, 0x13, 0x60, 0x45, 0xF1, 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x36, 0x22, 0xBC,
+	 0x87, 0xF1, 0x66, 0x41, 0x64, 0x46, 0x3A, 0xFA, 0xFF, 0xFF, 0x61, 0x46, 0xAB, 0x46, 0x82, 0xF0,
+	 0xC0, 0x67, 0xB4, 0x84, 0xAB, 0x46, 0x0B, 0xFA, 0x13, 0x60, 0x4D, 0xF1, 0x2D, 0x60, 0xBE, 0x7C,
+	 0x04, 0x1B, 0xFF, 0x60, 0xFF, 0x63, 0xA4, 0xDD, 0x26, 0x00, 0x2E, 0x60, 0x34, 0x63, 0xA4, 0xDD,
+	 0xDB, 0x83, 0x60, 0xFE, 0x00, 0x64, 0xBD, 0xDB, 0x60, 0x64, 0xBD, 0xDB, 0x1D, 0x64, 0xBD, 0xDB,
+	 0xC3, 0xF3, 0xBD, 0xDB, 0x20, 0xFE, 0x01, 0x60, 0x78, 0x64, 0x06, 0x61, 0x58, 0xD1, 0xFF, 0xFF,
+	 0x60, 0xFE, 0xBD, 0xD9, 0x20, 0xFE, 0xCD, 0x81, 0x61, 0x40, 0x08, 0x28, 0xF7, 0x01, 0xB6, 0xF1,
+	 0xFF, 0xFF, 0x64, 0x47, 0x60, 0xFE, 0xBD, 0xD9, 0xBD, 0xDB, 0x20, 0xFE, 0x13, 0x60, 0x4B, 0xF1,
+	 0x60, 0xFE, 0xBD, 0xD9, 0x20, 0xFE, 0x2D, 0x60, 0xBC, 0x64, 0x40, 0x48, 0x18, 0x61, 0x26, 0x46,
+	 0x00, 0xF4, 0xFF, 0x60, 0xF2, 0x64, 0xE4, 0x60, 0x58, 0x4D, 0xA7, 0x78, 0xFF, 0xFF, 0x26, 0x46,
+	 0x3F, 0xFC, 0x2B, 0x46, 0x56, 0xF1, 0x1F, 0xF8, 0x0C, 0x60, 0x70, 0xF1, 0x10, 0x60, 0x00, 0x64,
+	 0xA0, 0x80, 0x06, 0xF2, 0x0B, 0x03, 0x10, 0xBC, 0x06, 0xFA, 0x86, 0xF3, 0x00, 0x60, 0x70, 0xF3,
+	 0x60, 0x45, 0xD4, 0x80, 0xDC, 0x84, 0x07, 0x07, 0xA2, 0xDB, 0x05, 0x00, 0x10, 0xB5, 0xFF, 0xFF,
+	 0x02, 0x03, 0xD4, 0x84, 0x06, 0xFA, 0x07, 0xF2, 0x66, 0x45, 0x60, 0x46, 0x06, 0xF2, 0x65, 0x46,
+	 0x02, 0xB0, 0xFF, 0xFF, 0x11, 0x03, 0x26, 0x46, 0x87, 0xF3, 0x07, 0xFA, 0x1E, 0x60, 0xD4, 0x64,
+	 0x0F, 0x60, 0x90, 0xFB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0xC1, 0xFE, 0x00, 0x66, 0x46, 0x46, 0x50, 0x00, 0x26, 0x46, 0x87, 0xF3, 0x07, 0xFA, 0x1E, 0x60,
+	 0xD4, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0xC1, 0xFE, 0x00, 0x66, 0x46, 0x46, 0x19, 0x00, 0x00, 0x60, 0xC0, 0x64, 0x2A, 0xFA,
+	 0x02, 0x64, 0x3F, 0xFA, 0x87, 0xF3, 0x07, 0xFA, 0x00, 0xF4, 0x09, 0x64, 0x09, 0xFA, 0x1E, 0x60,
+	 0xD4, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0xC1, 0xFE, 0x00, 0x66, 0x46, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x2B, 0x43, 0x0B, 0x60,
+	 0x82, 0xF3, 0xDA, 0x81, 0x60, 0x45, 0xD5, 0x80, 0xA1, 0xD1, 0x11, 0x03, 0xD3, 0x80, 0xD9, 0x81,
+	 0xFA, 0x02, 0xC9, 0x81, 0xC8, 0x85, 0xD5, 0x80, 0xA5, 0xD3, 0x08, 0x28, 0xA1, 0xDB, 0x17, 0x60,
+	 0x04, 0x62, 0x65, 0x44, 0xA2, 0xDB, 0x4A, 0xD3, 0xFF, 0xFF, 0xCC, 0x84, 0xA2, 0xDB, 0xAB, 0x46,
+	 0x06, 0xF2, 0xFF, 0xFF, 0x02, 0xBC, 0x06, 0xFA, 0x78, 0xF2, 0x15, 0x60, 0xDC, 0xF3, 0x60, 0x45,
+	 0xA4, 0x84, 0x15, 0x60, 0xDC, 0xFB, 0xAB, 0x46, 0xAB, 0x46, 0x0F, 0x60, 0xFF, 0x64, 0x02, 0xF0,
+	 0x71, 0xF1, 0xA0, 0x84, 0xD0, 0x80, 0x02, 0xFA, 0xAB, 0x46, 0x01, 0x06, 0x71, 0xFB, 0x27, 0x41,
+	 0x01, 0xB1, 0xFF, 0xFF, 0x08, 0x03, 0x2B, 0x46, 0x0B, 0x58, 0x01, 0x65, 0xE5, 0x60, 0x58, 0x4E,
+	 0x51, 0x78, 0xFF, 0xFF, 0x0A, 0x00, 0x2B, 0x46, 0x0B, 0x58, 0x18, 0x60, 0xD6, 0x64, 0x40, 0x59,
+	 0x02, 0x65, 0xE5, 0x60, 0x58, 0x4E, 0x51, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x26, 0x46, 0x00, 0xF4, 0x00, 0x64, 0x09, 0xFA, 0x0B, 0xFA, 0x01, 0x7E, 0x0C, 0xFA,
+	 0x0A, 0x64, 0x0A, 0xFA, 0x26, 0x46, 0x08, 0x64, 0x3F, 0xFA, 0x07, 0xF2, 0x87, 0xF1, 0x40, 0x58,
+	 0x07, 0xF8, 0x1E, 0x60, 0xD4, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0xFF, 0x60, 0xFD, 0x65, 0x38, 0x46, 0x06, 0xF2,
+	 0xFF, 0xFF, 0xA4, 0x83, 0x06, 0xFC, 0x02, 0xB0, 0x26, 0x46, 0x1C, 0x03, 0x38, 0x43, 0x86, 0xF1,
+	 0x17, 0x60, 0x02, 0x61, 0xA1, 0xD3, 0xDA, 0x81, 0xD0, 0x80, 0xDC, 0x9C, 0x05, 0x05, 0xA1, 0xD3,
+	 0x4A, 0xD9, 0xA0, 0xDD, 0xDA, 0x9C, 0xA1, 0xD9, 0x02, 0x60, 0x00, 0x61, 0x2C, 0xF2, 0xA1, 0xDB,
+	 0x2D, 0xF2, 0x41, 0x58, 0x59, 0xDB, 0x2E, 0xF2, 0x59, 0xDB, 0x03, 0x65, 0xE5, 0x60, 0x58, 0x4E,
+	 0x51, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x07, 0xF2, 0x87, 0xF1,
+	 0xFF, 0xFF, 0xD0, 0x80, 0xFF, 0xFF, 0x02, 0x02, 0x2F, 0x58, 0xFF, 0xFF, 0x40, 0x47, 0x07, 0xF2,
+	 0x66, 0x45, 0x60, 0x46, 0x06, 0xF2, 0x65, 0x46, 0x02, 0xB0, 0xFF, 0xFF, 0x1A, 0x02, 0x27, 0x43,
+	 0x0B, 0x60, 0x82, 0xF3, 0xDA, 0x81, 0x60, 0x45, 0xD5, 0x80, 0xA1, 0xD1, 0x11, 0x03, 0xD3, 0x80,
+	 0xD9, 0x81, 0xFA, 0x02, 0xC9, 0x81, 0xC8, 0x85, 0xD5, 0x80, 0xA5, 0xD3, 0x08, 0x28, 0xA1, 0xDB,
+	 0x17, 0x60, 0x04, 0x62, 0x65, 0x44, 0xA2, 0xDB, 0x4A, 0xD3, 0xFF, 0xFF, 0xCC, 0x84, 0xA2, 0xDB,
+	 0x0C, 0x00, 0x27, 0x44, 0x40, 0x58, 0x03, 0x65, 0xE5, 0x60, 0x58, 0x4E, 0x51, 0x78, 0xFF, 0xFF,
+	 0x27, 0x43, 0xE7, 0x60, 0x58, 0x4E, 0x81, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x87, 0xF4, 0x66, 0x41,
+	 0x63, 0x46, 0x05, 0xF2, 0x00, 0xF0, 0x81, 0xF0, 0x02, 0x18, 0x64, 0x46, 0x81, 0xF8, 0x07, 0x1B,
+	 0x15, 0x60, 0x02, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD9, 0x02, 0x00, 0x65, 0x46,
+	 0x00, 0xF8, 0x87, 0xF3, 0x63, 0x45, 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xD4, 0x80, 0x01, 0x18,
+	 0xFA, 0x04, 0x80, 0xF8, 0x65, 0x46, 0x00, 0xFA, 0x06, 0xF2, 0xFF, 0xFF, 0x00, 0x7E, 0x06, 0xFA,
+	 0x61, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x07, 0xF2, 0x87, 0xF1, 0xFF, 0xFF, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x02, 0x02, 0x2F, 0x58, 0xFF, 0xFF, 0x40, 0x47, 0x07, 0xF2, 0x66, 0x45, 0x60, 0x46, 0x06, 0xF2,
+	 0x65, 0x46, 0x02, 0xB0, 0xFF, 0xFF, 0x02, 0x02, 0x2F, 0x58, 0xFF, 0xFF, 0x27, 0x46, 0x06, 0xF0,
+	 0xFF, 0x60, 0xED, 0x64, 0xA0, 0x84, 0x06, 0xFA, 0x27, 0x43, 0x86, 0xF1, 0x17, 0x60, 0x02, 0x61,
+	 0xA1, 0xD3, 0xDA, 0x81, 0xD0, 0x80, 0xDC, 0x9C, 0x05, 0x05, 0xA1, 0xD3, 0x4A, 0xD9, 0xA0, 0xDD,
+	 0xDA, 0x9C, 0xA1, 0xD9, 0x07, 0x58, 0x03, 0x65, 0xE5, 0x60, 0x58, 0x4E, 0x51, 0x78, 0xFF, 0xFF,
+	 0x27, 0x43, 0xE7, 0x60, 0x58, 0x4E, 0x81, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x26, 0x46, 0x2F, 0xF2, 0x2C, 0xFA, 0x30, 0xF2, 0x2D, 0xFA, 0x31, 0xF2, 0x2E, 0xFA, 0xCB, 0xF3,
+	 0x2F, 0xFA, 0xCC, 0xF3, 0x30, 0xFA, 0xCD, 0xF3, 0x31, 0xFA, 0x66, 0xF3, 0x32, 0xFA, 0x67, 0xF3,
+	 0x33, 0xFA, 0x68, 0xF3, 0x34, 0xFA, 0xAB, 0xF1, 0x19, 0xF8, 0x00, 0x65, 0xEF, 0x60, 0x58, 0x4E,
+	 0xDC, 0x78, 0xFF, 0xFF, 0x61, 0x44, 0x15, 0x60, 0xC2, 0xFB, 0x02, 0x63, 0x3F, 0xFC, 0x00, 0x64,
+	 0x3E, 0xFA, 0x02, 0x60, 0x00, 0x61, 0x2C, 0xF2, 0xA1, 0xDB, 0x2D, 0xF2, 0x41, 0x58, 0x59, 0xDB,
+	 0x2E, 0xF2, 0x59, 0xDB, 0x06, 0x63, 0x07, 0xF2, 0x87, 0xF1, 0xFF, 0xFF, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x0D, 0x02, 0x43, 0x59, 0x02, 0x65, 0xE5, 0x60, 0x58, 0x4E, 0x27, 0x78, 0xFF, 0xFF, 0x26, 0x46,
+	 0xC0, 0x64, 0x2A, 0xFA, 0x00, 0xF4, 0x06, 0x64, 0x09, 0xFA, 0x15, 0x00, 0x07, 0xF2, 0x66, 0x45,
+	 0x60, 0x46, 0x06, 0xF2, 0x65, 0x46, 0x02, 0xB0, 0xFF, 0xFF, 0x1D, 0x02, 0x07, 0x63, 0x43, 0x59,
+	 0x01, 0x65, 0xE5, 0x60, 0x58, 0x4E, 0x27, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0xA0, 0x64, 0x2A, 0xFA,
+	 0x00, 0xF4, 0x07, 0x64, 0x09, 0xFA, 0x26, 0x46, 0x87, 0xF3, 0x07, 0xFA, 0x1E, 0x60, 0xD4, 0x64,
+	 0x0F, 0x60, 0x90, 0xFB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0xC1, 0xFE, 0x00, 0x66, 0x46, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0xDE, 0x60, 0x66, 0x64, 0x08, 0x60,
+	 0x29, 0xFB, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x60, 0x03, 0x64, 0x08, 0x60, 0x1F, 0xFB, 0xDE, 0x60,
+	 0x05, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x1E, 0xF1, 0x00, 0x60,
+	 0x02, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x59, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x71, 0xF3, 0x87, 0xF5,
+	 0xDC, 0x81, 0x66, 0x43, 0x02, 0xA3, 0x63, 0x46, 0xCD, 0x81, 0x06, 0xF2, 0xEE, 0x03, 0x60, 0x40,
+	 0x08, 0x2A, 0xF7, 0x01, 0x0C, 0xAC, 0x06, 0xFA, 0x46, 0x49, 0x00, 0x60, 0x02, 0x61, 0xB5, 0x60,
+	 0x58, 0x4D, 0xA2, 0x78, 0xFF, 0xFF, 0xE1, 0x03, 0x18, 0x60, 0x13, 0xF3, 0xFF, 0xFF, 0x03, 0x1B,
+	 0x00, 0x60, 0xA0, 0x64, 0x02, 0x00, 0x00, 0x60, 0xC0, 0x64, 0x2A, 0xFA, 0xAB, 0xFC, 0x66, 0x45,
+	 0x29, 0x44, 0x07, 0xFA, 0x29, 0x46, 0x03, 0xF2, 0x04, 0xF0, 0x85, 0xF2, 0x65, 0x46, 0x2C, 0xFA,
+	 0x2D, 0xF8, 0xAE, 0xFA, 0xCB, 0xF3, 0x2F, 0xFA, 0x32, 0xFA, 0xCC, 0xF3, 0x30, 0xFA, 0x33, 0xFA,
+	 0xCD, 0xF3, 0x31, 0xFA, 0x34, 0xFA, 0xAB, 0xF1, 0x19, 0xF8, 0x18, 0x67, 0x0E, 0xFA, 0x66, 0x41,
+	 0x29, 0x46, 0x92, 0xF0, 0x2C, 0x60, 0x26, 0x63, 0x47, 0xD3, 0x61, 0x46, 0x00, 0x7E, 0x13, 0xFA,
+	 0x02, 0x63, 0x3F, 0xFC, 0x00, 0x64, 0x3E, 0xFA, 0x66, 0x41, 0x00, 0xF4, 0x18, 0x60, 0x12, 0xF3,
+	 0x09, 0xFA, 0x1E, 0x60, 0xE0, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x61, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC8, 0xFE, 0xA0, 0x01, 0x95, 0x01, 0x00, 0x64, 0x08, 0x60,
+	 0x1E, 0xFB, 0x5A, 0xDB, 0x2F, 0x58, 0xFF, 0xFF, 0x07, 0xF0, 0xFF, 0xFF, 0x64, 0x43, 0x0B, 0x60,
+	 0x82, 0xF3, 0xDA, 0x81, 0x60, 0x45, 0xD5, 0x80, 0xA1, 0xD1, 0x04, 0x03, 0xD3, 0x80, 0xD9, 0x81,
+	 0xFA, 0x02, 0x08, 0x00, 0xA1, 0xDD, 0xD9, 0x84, 0x0B, 0x60, 0x82, 0xFB, 0x4A, 0xD3, 0xFF, 0xFF,
+	 0xDC, 0x84, 0xA2, 0xDB, 0x66, 0x45, 0x63, 0x46, 0x06, 0xF2, 0xFF, 0x60, 0x01, 0x7C, 0xA0, 0x9C,
+	 0x06, 0xF8, 0x65, 0x46, 0x70, 0xF3, 0x60, 0x40, 0x10, 0x2A, 0x03, 0x00, 0xCC, 0x84, 0x80, 0x2B,
+	 0x70, 0xFB, 0x08, 0x60, 0x1E, 0xF1, 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x60, 0x30, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x00, 0x60, 0x02, 0x64,
+	 0x08, 0x60, 0x19, 0xFB, 0xDE, 0x60, 0xA8, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x70, 0xF3, 0x71, 0xF3, 0x00, 0xA8, 0x60, 0x88, 0x43, 0x03, 0xE0, 0x83, 0x5F, 0x03, 0xCB, 0x83,
+	 0x87, 0xF3, 0x72, 0xF1, 0x02, 0xA4, 0x40, 0x47, 0x64, 0x45, 0x27, 0x46, 0x76, 0xF4, 0x12, 0xF2,
+	 0x33, 0x18, 0xD4, 0x80, 0x02, 0x64, 0x30, 0x07, 0x23, 0xFA, 0x2A, 0xF2, 0x0E, 0xF2, 0x0C, 0xB0,
+	 0x02, 0xF0, 0x0C, 0x02, 0x1E, 0x60, 0xD4, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x66, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0xE7, 0x01, 0x60, 0x40, 0xF0, 0x37,
+	 0x08, 0x00, 0x09, 0x60, 0x08, 0x64, 0xD0, 0x80, 0xA2, 0xFF, 0x8F, 0xF3, 0x02, 0x02, 0xDC, 0x84,
+	 0x8F, 0xFB, 0x1E, 0x60, 0xF2, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xA3, 0xFF, 0xCE, 0xFE, 0x25, 0x60, 0xE4, 0x64, 0xE5, 0x60,
+	 0x78, 0x41, 0xC7, 0x78, 0x97, 0xF1, 0xC9, 0x01, 0x27, 0x44, 0x02, 0xA4, 0x40, 0x47, 0xC5, 0x1F,
+	 0x28, 0x43, 0xCB, 0x83, 0x87, 0xF3, 0x1A, 0x0E, 0x02, 0xA4, 0x40, 0x4C, 0x43, 0x48, 0x2C, 0x46,
+	 0x22, 0xF2, 0x72, 0xF1, 0xAC, 0x86, 0x12, 0xF2, 0x0C, 0x03, 0xD0, 0x80, 0xFF, 0xFF, 0x09, 0x07,
+	 0x1F, 0x60, 0x20, 0x64, 0x40, 0x4B, 0xF6, 0x60, 0x58, 0x4D, 0xB3, 0x78, 0xFF, 0xFF, 0x2C, 0x46,
+	 0xA2, 0xFC, 0x2C, 0x44, 0x02, 0xA4, 0x28, 0x43, 0x40, 0x4C, 0xE8, 0x1F, 0x8B, 0x01, 0x01, 0x63,
+	 0x65, 0xF3, 0xAB, 0xF3, 0x00, 0xBD, 0xAC, 0x81, 0x06, 0x03, 0x05, 0x03, 0xB7, 0x60, 0x58, 0x4D,
+	 0xC0, 0x78, 0xFF, 0xFF, 0x60, 0x43, 0x5B, 0xFD, 0x3E, 0x63, 0x18, 0x60, 0x94, 0x61, 0x00, 0x64,
+	 0x59, 0xDB, 0xFE, 0x1F, 0x70, 0xFB, 0x71, 0xFB, 0x18, 0x60, 0xDC, 0x65, 0xA5, 0xDF, 0x5A, 0xDF,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0x70, 0xF3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x03, 0x02,
+	 0xCA, 0x60, 0x7E, 0x78, 0xFF, 0xFF, 0x07, 0xF0, 0x66, 0x45, 0x64, 0x46, 0x1F, 0xF2, 0x65, 0x46,
+	 0x64, 0x45, 0x5B, 0xF1, 0xE0, 0x84, 0x72, 0xF1, 0xC0, 0x84, 0xC0, 0x84, 0x12, 0xFA, 0x2C, 0xF2,
+	 0x70, 0xF3, 0x60, 0x40, 0x01, 0x2A, 0x34, 0x00, 0x00, 0xA8, 0x13, 0x60, 0x43, 0xF3, 0x36, 0x03,
+	 0x00, 0xA8, 0xFF, 0xFF, 0x33, 0x03, 0xE1, 0x60, 0x58, 0x4D, 0x04, 0x78, 0xFF, 0xFF, 0x25, 0x46,
+	 0x09, 0x60, 0x08, 0x61, 0xA2, 0xFF, 0x0E, 0xF2, 0x02, 0xF0, 0x60, 0x40, 0xF0, 0x37, 0x0D, 0x00,
+	 0x91, 0xF3, 0x8F, 0xF3, 0xDC, 0x83, 0xD1, 0x80, 0x91, 0xFD, 0x0C, 0x03, 0x8B, 0xF3, 0xCC, 0x83,
+	 0xD8, 0xA0, 0x8F, 0xFD, 0x07, 0x04, 0xD4, 0xFE, 0x05, 0x00, 0xD1, 0x80, 0x92, 0xF3, 0x02, 0x03,
+	 0xDC, 0x84, 0x92, 0xFB, 0x1E, 0x60, 0xDA, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x25, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xA3, 0xFF, 0xDF, 0x60, 0x2A, 0x78, 0xFF, 0xFF,
+	 0x66, 0x41, 0x65, 0x46, 0x06, 0xF2, 0x61, 0x46, 0x60, 0x40, 0x10, 0x2A, 0x4B, 0x00, 0x80, 0x67,
+	 0xB4, 0x81, 0x61, 0x44, 0x0F, 0x60, 0x90, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB,
+	 0xFF, 0xFF, 0x2B, 0xFF, 0xE1, 0x60, 0x58, 0x4D, 0x04, 0x78, 0xFF, 0xFF, 0x25, 0x46, 0x2A, 0xF2,
+	 0x09, 0x60, 0x08, 0x61, 0x0C, 0xB0, 0xA2, 0xFF, 0x17, 0x03, 0x0E, 0xF2, 0x02, 0xF0, 0x60, 0x40,
+	 0xF0, 0x37, 0x0D, 0x00, 0x8F, 0xF3, 0x91, 0xF3, 0xCC, 0x83, 0xD1, 0x80, 0x8F, 0xFD, 0x0C, 0x03,
+	 0x8B, 0xF3, 0xDC, 0x83, 0xD8, 0xA0, 0x91, 0xFD, 0x07, 0x04, 0xD4, 0xFE, 0x05, 0x00, 0xD1, 0x80,
+	 0x92, 0xF3, 0x02, 0x03, 0xDC, 0x84, 0x92, 0xFB, 0x07, 0xF0, 0x0A, 0xF2, 0xA3, 0xFF, 0x64, 0x45,
+	 0x2F, 0x1B, 0x66, 0x41, 0x65, 0x46, 0x02, 0xF0, 0x61, 0x46, 0x0F, 0x60, 0xFF, 0x61, 0xA1, 0x84,
+	 0x60, 0x41, 0xE9, 0x81, 0xE9, 0x81, 0xE9, 0x81, 0xE1, 0x82, 0x07, 0xB4, 0x01, 0x61, 0x03, 0x03,
+	 0xCC, 0x84, 0xE1, 0x81, 0xFD, 0x02, 0x18, 0x60, 0x96, 0x65, 0x46, 0xD1, 0x61, 0x44, 0xB0, 0x84,
+	 0xA2, 0xDB, 0x16, 0x00, 0x1E, 0x60, 0xD4, 0x61, 0x2A, 0xF2, 0x3E, 0xF2, 0x0C, 0xB0, 0x01, 0xB0,
+	 0x05, 0x03, 0x1E, 0x60, 0xE6, 0x61, 0x02, 0x02, 0x1E, 0x60, 0xCE, 0x61, 0x61, 0x44, 0x0F, 0x60,
+	 0x90, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE,
+	 0xDF, 0x60, 0x2A, 0x78, 0xFF, 0xFF, 0x07, 0xF0, 0x2B, 0xF2, 0x2A, 0xF2, 0x60, 0x41, 0x44, 0x49,
+	 0x60, 0x45, 0xA4, 0x3A, 0x0D, 0x00, 0x61, 0x40, 0xC0, 0x3B, 0x79, 0x00, 0xA9, 0x46, 0x06, 0xF2,
+	 0xA9, 0x46, 0x60, 0x40, 0x20, 0x26, 0x73, 0x00, 0x20, 0xBC, 0xA9, 0x46, 0x06, 0xFA, 0xA9, 0x46,
+	 0xA9, 0x46, 0x06, 0xF0, 0xA9, 0x46, 0x65, 0x40, 0x10, 0x2B, 0x6C, 0x00, 0x64, 0x40, 0x10, 0x2A,
+	 0x35, 0x00, 0x65, 0x40, 0xA4, 0x3A, 0x63, 0x00, 0x29, 0x45, 0x65, 0x46, 0x76, 0xF2, 0xFF, 0xFF,
+	 0x00, 0xA8, 0x60, 0x46, 0x04, 0x02, 0x76, 0x00, 0xE0, 0x60, 0xEA, 0x78, 0xFF, 0xFF, 0x09, 0xF2,
+	 0x2A, 0xF0, 0x00, 0xA8, 0x20, 0x67, 0x02, 0x03, 0xB0, 0x84, 0x2A, 0xFA, 0x0E, 0xF2, 0x02, 0xF0,
+	 0x60, 0x40, 0xF0, 0x37, 0x08, 0x00, 0x09, 0x60, 0x08, 0x64, 0xD0, 0x80, 0xA2, 0xFF, 0x8F, 0xF3,
+	 0x02, 0x02, 0xDC, 0x84, 0x8F, 0xFB, 0x3E, 0xF2, 0xA3, 0xFF, 0x01, 0xB0, 0x1E, 0x60, 0xE6, 0x61,
+	 0x02, 0x02, 0x1E, 0x60, 0xD4, 0x61, 0x61, 0x44, 0x0F, 0x60, 0x90, 0xFB, 0x66, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x16, 0x00, 0x10, 0x64, 0xB0, 0x84,
+	 0xDF, 0x65, 0xA4, 0x9E, 0xA9, 0x46, 0x06, 0xFA, 0xA9, 0x46, 0xA2, 0xFF, 0x04, 0x64, 0x0C, 0x60,
+	 0x6E, 0xFB, 0x29, 0x44, 0x5A, 0xDB, 0x70, 0xF3, 0xC1, 0xFE, 0xD4, 0xFE, 0x86, 0xF1, 0xA3, 0xFF,
+	 0xD0, 0x80, 0xDC, 0x84, 0x01, 0x07, 0x70, 0xFB, 0xA9, 0x46, 0x76, 0xF2, 0xA9, 0x46, 0x64, 0x18,
+	 0xA9, 0x46, 0x02, 0xF0, 0xA9, 0x46, 0x0F, 0x60, 0xFF, 0x61, 0xA1, 0x84, 0x60, 0x41, 0xE9, 0x81,
+	 0xE9, 0x81, 0xE9, 0x81, 0xE1, 0x82, 0x07, 0xB4, 0x01, 0x61, 0x03, 0x03, 0xCC, 0x84, 0xE1, 0x81,
+	 0xFD, 0x02, 0x18, 0x60, 0x96, 0x65, 0x46, 0xD1, 0xFF, 0xFF, 0xB1, 0x84, 0xA2, 0xDB, 0xE1, 0x60,
+	 0x01, 0x78, 0xFF, 0xFF, 0x64, 0x40, 0x10, 0x2A, 0xFA, 0x01, 0xFF, 0x60, 0xEF, 0x64, 0xA0, 0x84,
+	 0xA9, 0x46, 0x06, 0xFA, 0xA9, 0x46, 0x65, 0x41, 0x70, 0xF3, 0x29, 0x45, 0xCC, 0x84, 0x80, 0x2B,
+	 0x70, 0xFB, 0x65, 0x46, 0x76, 0xF2, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x36, 0x02, 0x61, 0x40,
+	 0xA4, 0x3A, 0xE5, 0x01, 0x00, 0x60, 0x3A, 0x61, 0xB5, 0x60, 0x58, 0x4D, 0x9F, 0x78, 0xFF, 0xFF,
+	 0x83, 0x03, 0x02, 0x60, 0x48, 0x64, 0x2A, 0xFA, 0xCB, 0xF1, 0x2F, 0xF8, 0xCC, 0xF1, 0x30, 0xF8,
+	 0xCD, 0xF1, 0x31, 0xF8, 0x66, 0xF1, 0x32, 0xF8, 0x67, 0xF1, 0x33, 0xF8, 0x68, 0xF1, 0x34, 0xF8,
+	 0xA9, 0x46, 0x03, 0xF2, 0x04, 0xF0, 0x85, 0xF0, 0xA9, 0x46, 0x2C, 0xFA, 0x2D, 0xF8, 0xAE, 0xF8,
+	 0xAB, 0xF1, 0x19, 0xF8, 0xFF, 0x67, 0x0E, 0xFA, 0x00, 0x64, 0x3E, 0xFA, 0x3F, 0xFA, 0x29, 0x44,
+	 0x07, 0xFA, 0x1E, 0x60, 0xD4, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x35, 0x00, 0x80, 0x67, 0xB4, 0x83, 0x2A, 0xF2,
+	 0x09, 0x60, 0x08, 0x65, 0x0C, 0xB0, 0x09, 0xF0, 0x0C, 0x02, 0x1E, 0x60, 0xD4, 0x64, 0x0F, 0x60,
+	 0x90, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x9F, 0x18,
+	 0x64, 0x46, 0x3E, 0xF2, 0xA2, 0xFF, 0x01, 0xB0, 0x1E, 0x60, 0xE6, 0x61, 0x02, 0x02, 0x1E, 0x60,
+	 0xCE, 0x61, 0x02, 0xF2, 0x0E, 0xF0, 0xD4, 0x80, 0x09, 0xF4, 0x06, 0x02, 0x8F, 0xF3, 0x64, 0x40,
+	 0xF0, 0x37, 0x02, 0x00, 0xDC, 0x84, 0x8F, 0xFB, 0x66, 0x44, 0x00, 0xA8, 0xFF, 0xFF, 0xF1, 0x02,
+	 0x61, 0x44, 0x0F, 0x60, 0x90, 0xFB, 0x5A, 0xDD, 0x08, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0xC1, 0xFE, 0xA3, 0xFF, 0xA9, 0x46, 0x02, 0xF0, 0xA9, 0x46, 0x0F, 0x60, 0xFF, 0x61, 0xA1, 0x84,
+	 0x60, 0x41, 0xE9, 0x81, 0xE9, 0x81, 0xE9, 0x81, 0xE1, 0x82, 0x07, 0xB4, 0x01, 0x61, 0x03, 0x03,
+	 0xCC, 0x84, 0xE1, 0x81, 0xFD, 0x02, 0x18, 0x60, 0x96, 0x65, 0x46, 0xD3, 0x9D, 0x85, 0xA4, 0x84,
+	 0xA2, 0xDB, 0x26, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x46, 0x45, 0x3F, 0xF2, 0x05, 0x48, 0x00, 0xA8,
+	 0x60, 0x41, 0x66, 0x44, 0x0B, 0x03, 0x0E, 0xA1, 0x00, 0xF2, 0x42, 0xFE, 0xAC, 0x86, 0x01, 0xF2,
+	 0x1F, 0x03, 0x7F, 0xB5, 0xD5, 0x81, 0x66, 0x44, 0xF7, 0x07, 0x25, 0x46, 0x05, 0xF0, 0x06, 0xFA,
+	 0x05, 0xFA, 0xD0, 0x80, 0x64, 0x43, 0x13, 0x03, 0x60, 0x46, 0x01, 0xF0, 0x80, 0x67, 0xB0, 0x84,
+	 0x01, 0xFA, 0x00, 0xF0, 0x00, 0x64, 0x00, 0xFA, 0x44, 0x45, 0xA2, 0xFF, 0xB6, 0x60, 0x58, 0x4E,
+	 0x72, 0x78, 0xFF, 0xFF, 0xA3, 0xFF, 0x08, 0x45, 0x25, 0x46, 0x01, 0x64, 0x02, 0xFA, 0x02, 0xFE,
+	 0x2D, 0x58, 0xFF, 0xFF, 0x23, 0xF2, 0x07, 0xF0, 0x10, 0xB0, 0x10, 0xAC, 0x3A, 0x03, 0x23, 0xFA,
+	 0x80, 0x67, 0xB0, 0x81, 0x61, 0x44, 0x0F, 0x60, 0x90, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x04, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x46, 0x45, 0x64, 0x46, 0x02, 0xF0, 0x0F, 0x60, 0xFF, 0x61,
+	 0xA1, 0x84, 0x60, 0x41, 0xE9, 0x81, 0xE9, 0x81, 0xE9, 0x81, 0xE1, 0x82, 0x07, 0xB4, 0x01, 0x61,
+	 0x03, 0x03, 0xCC, 0x84, 0xE1, 0x81, 0xFD, 0x02, 0x18, 0x60, 0x96, 0x65, 0x46, 0xD1, 0xFF, 0xFF,
+	 0xB1, 0x84, 0xA2, 0xDB, 0x9F, 0xF2, 0x25, 0x46, 0xE1, 0x81, 0x5B, 0xF1, 0x72, 0xF1, 0xC1, 0x81,
+	 0xC1, 0x81, 0x92, 0xFA, 0xA2, 0xFF, 0x02, 0xF0, 0x09, 0x60, 0x08, 0x61, 0xD1, 0x80, 0x0E, 0xF2,
+	 0x05, 0x02, 0x8F, 0xF3, 0x20, 0xB0, 0xCC, 0x84, 0x01, 0x02, 0x8F, 0xFB, 0xA3, 0xFF, 0x48, 0xFE,
+	 0x07, 0x00, 0x0E, 0xF2, 0x08, 0xFE, 0xF0, 0x7F, 0x60, 0x40, 0x20, 0x2A, 0x00, 0x7F, 0x0E, 0xFA,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x60, 0xC5, 0x61, 0xB5, 0x60, 0x58, 0x4D, 0xA2, 0x78, 0xFF, 0xFF,
+	 0x66, 0x44, 0x57, 0xFB, 0x04, 0x64, 0x03, 0xFA, 0x80, 0x64, 0x2A, 0xFA, 0xAB, 0xF1, 0x19, 0xF8,
+	 0x00, 0x64, 0x3E, 0xFA, 0x00, 0x60, 0x80, 0x64, 0x0E, 0xFA, 0x87, 0xF1, 0x07, 0xF8, 0x67, 0x44,
+	 0x2C, 0xFA, 0x2D, 0xFA, 0x2E, 0xFA, 0xE4, 0x60, 0x65, 0x64, 0x08, 0x60, 0x25, 0xFB, 0xE2, 0x60,
+	 0xA0, 0x64, 0x08, 0x60, 0x2B, 0xFB, 0x18, 0x60, 0xE6, 0x63, 0x65, 0x44, 0xBD, 0xDB, 0x10, 0x60,
+	 0x58, 0x64, 0xBD, 0xDB, 0x02, 0x64, 0xBD, 0xDB, 0x06, 0x64, 0xA3, 0xDB, 0xE9, 0x60, 0xB2, 0x78,
+	 0xFF, 0xFF, 0xE9, 0x60, 0x58, 0x4D, 0xBE, 0x78, 0xFF, 0xFF, 0x57, 0xF5, 0xCB, 0xF1, 0x2F, 0xF8,
+	 0xCC, 0xF1, 0x30, 0xF8, 0xCD, 0xF1, 0x31, 0xF8, 0x66, 0xF1, 0x32, 0xF8, 0x67, 0xF1, 0x33, 0xF8,
+	 0x68, 0xF1, 0x34, 0xF8, 0x13, 0x60, 0x45, 0xF1, 0x01, 0x64, 0x64, 0x40, 0xFE, 0x26, 0x10, 0xBC,
+	 0x32, 0x40, 0x10, 0x26, 0x10, 0xBC, 0x20, 0xBC, 0x04, 0x60, 0x00, 0x65, 0x60, 0x44, 0xB4, 0x84,
+	 0x17, 0x60, 0x22, 0xFB, 0x13, 0x60, 0x44, 0xF1, 0x26, 0x60, 0x16, 0x64, 0x02, 0x18, 0x26, 0x60,
+	 0x38, 0x64, 0x16, 0x60, 0xBF, 0xFB, 0x16, 0x60, 0xCF, 0xFB, 0x2C, 0x60, 0x84, 0x61, 0x13, 0x60,
+	 0x97, 0xF3, 0x2D, 0x60, 0x5E, 0x65, 0xFE, 0xA4, 0xE0, 0x84, 0x02, 0x05, 0x67, 0x44, 0x21, 0x00,
+	 0xE0, 0x84, 0xC4, 0x85, 0x16, 0x60, 0x55, 0xF3, 0xA5, 0xD1, 0xDA, 0x85, 0xA0, 0x83, 0x16, 0x60,
+	 0x51, 0xFD, 0xA5, 0xD1, 0x2C, 0x60, 0xA0, 0x62, 0xA0, 0x83, 0xA2, 0xDD, 0x2C, 0x60, 0x84, 0x61,
+	 0x50, 0x60, 0x00, 0x7C, 0x00, 0x60, 0xF2, 0x65, 0xE2, 0x60, 0x58, 0x4D, 0x06, 0x78, 0xFF, 0xFF,
+	 0x16, 0x60, 0x53, 0xF1, 0x59, 0xD9, 0x2C, 0x60, 0x7E, 0x65, 0xD5, 0x84, 0xDD, 0x7F, 0xA5, 0xDB,
+	 0x65, 0x44, 0x16, 0x60, 0xC4, 0xFB, 0x16, 0x60, 0xD4, 0xFB, 0x79, 0x00, 0x16, 0x60, 0x54, 0xF3,
+	 0x2C, 0x60, 0xA0, 0x62, 0xFD, 0xA0, 0xA2, 0xD3, 0xEE, 0x03, 0x60, 0x40, 0x02, 0x2A, 0x02, 0x00,
+	 0x01, 0x63, 0x0B, 0x00, 0x04, 0x2A, 0x02, 0x00, 0x02, 0x63, 0x07, 0x00, 0x10, 0x2A, 0x02, 0x00,
+	 0x04, 0x63, 0x03, 0x00, 0x20, 0x2A, 0x01, 0x00, 0x05, 0x63, 0x63, 0x47, 0xB4, 0x83, 0x59, 0xD9,
+	 0x59, 0xDD, 0x16, 0x60, 0x54, 0xF3, 0x16, 0x60, 0x51, 0xF3, 0xFE, 0xA0, 0x40, 0x4C, 0xD3, 0x03,
+	 0x00, 0x60, 0x00, 0x63, 0x59, 0xDD, 0x41, 0x4A, 0x2C, 0x40, 0x01, 0x2A, 0x05, 0x00, 0x00, 0x63,
+	 0x63, 0x47, 0xB4, 0x83, 0x59, 0xD9, 0x59, 0xDD, 0x2C, 0x40, 0x02, 0x2A, 0x03, 0x00, 0x01, 0x63,
+	 0x59, 0xD9, 0x59, 0xDD, 0x2C, 0x40, 0x04, 0x2A, 0x05, 0x00, 0x02, 0x63, 0x63, 0x47, 0xB4, 0x83,
+	 0x59, 0xD9, 0x59, 0xDD, 0x2C, 0x40, 0x10, 0x2A, 0x05, 0x00, 0x04, 0x63, 0x63, 0x47, 0xB4, 0x83,
+	 0x59, 0xD9, 0x59, 0xDD, 0x2C, 0x40, 0x20, 0x2A, 0x05, 0x00, 0x05, 0x63, 0x63, 0x47, 0xB4, 0x83,
+	 0x59, 0xD9, 0x59, 0xDD, 0x2A, 0x44, 0x51, 0x93, 0xEB, 0x83, 0xEB, 0x83, 0xA0, 0xDD, 0x16, 0x60,
+	 0x54, 0xF3, 0x16, 0x60, 0x52, 0xF3, 0xFF, 0xA0, 0x40, 0x4C, 0x9D, 0x03, 0x59, 0xDF, 0x41, 0x4A,
+	 0x2C, 0x40, 0x01, 0x2A, 0x05, 0x00, 0x00, 0x63, 0x63, 0x47, 0xB4, 0x83, 0x59, 0xD9, 0x59, 0xDD,
+	 0x2C, 0x40, 0x02, 0x2A, 0x05, 0x00, 0x01, 0x63, 0x63, 0x47, 0xB4, 0x83, 0x59, 0xD9, 0x59, 0xDD,
+	 0x2C, 0x40, 0x04, 0x2A, 0x05, 0x00, 0x02, 0x63, 0x63, 0x47, 0xB4, 0x83, 0x59, 0xD9, 0x59, 0xDD,
+	 0x2A, 0x44, 0x51, 0x93, 0xEB, 0x83, 0xEB, 0x83, 0xA0, 0xDD, 0x2D, 0x58, 0xFF, 0xFF, 0x57, 0xF5,
+	 0xCB, 0xF3, 0xCC, 0xF1, 0x00, 0x63, 0xC0, 0x87, 0xCD, 0xF1, 0x5A, 0xFD, 0xC0, 0x85, 0x65, 0x47,
+	 0xC4, 0x84, 0x07, 0xB5, 0x18, 0x60, 0xE2, 0x64, 0x0F, 0x60, 0xA5, 0xFB, 0x02, 0x64, 0x4A, 0xDB,
+	 0xFF, 0xFF, 0x04, 0xFF, 0x10, 0x60, 0x24, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x00, 0x60, 0x02, 0x64,
+	 0x08, 0x60, 0x13, 0xFB, 0xE2, 0x60, 0xA9, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x08, 0x60, 0x12, 0xF1, 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x10, 0x60, 0x24, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x57, 0xF5, 0x00, 0x64, 0x94, 0xFB,
+	 0x95, 0xFB, 0x96, 0xFB, 0x74, 0xFB, 0x65, 0xF3, 0x00, 0x75, 0x00, 0x72, 0xE0, 0x84, 0xE0, 0x84,
+	 0xE0, 0x93, 0xC7, 0xF3, 0xED, 0xE2, 0xCC, 0x84, 0x5A, 0xFB, 0x00, 0x60, 0x04, 0x64, 0x08, 0x60,
+	 0x13, 0xFB, 0xE2, 0x60, 0xC7, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x60,
+	 0x24, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x64, 0xF1, 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x2B, 0x05, 0x00,
+	 0x67, 0x44, 0x16, 0x60, 0xC1, 0xFB, 0x16, 0x60, 0xD1, 0xFB, 0x16, 0x60, 0xF6, 0xF9, 0x2D, 0x60,
+	 0x86, 0x65, 0xE4, 0x60, 0x58, 0x4D, 0xE7, 0x78, 0xFF, 0xFF, 0x64, 0xF3, 0xFF, 0xFF, 0x60, 0x40,
+	 0x01, 0x2B, 0x05, 0x00, 0xFF, 0x60, 0xFF, 0x63, 0x16, 0x60, 0xC5, 0xFD, 0x08, 0x00, 0x2E, 0x60,
+	 0x1E, 0x63, 0x16, 0x60, 0xC5, 0xFD, 0xE4, 0x60, 0x58, 0x4D, 0xFF, 0x78, 0xFF, 0xFF, 0xE4, 0x60,
+	 0x58, 0x4D, 0x6E, 0x78, 0xFF, 0xFF, 0xE5, 0x60, 0x58, 0x4D, 0x18, 0x78, 0xFF, 0xFF, 0x57, 0xF5,
+	 0x00, 0xF4, 0x65, 0xF1, 0x06, 0xF8, 0x17, 0x60, 0x22, 0xF3, 0x15, 0x60, 0xDD, 0xF1, 0xFB, 0x60,
+	 0xFF, 0x65, 0x60, 0x44, 0xA4, 0x84, 0x60, 0x47, 0x64, 0x40, 0x10, 0x26, 0x04, 0xBC, 0x60, 0x47,
+	 0x07, 0xFA, 0x2D, 0x60, 0x7E, 0x64, 0x40, 0x48, 0x10, 0x61, 0x00, 0x60, 0x00, 0x64, 0xE4, 0x60,
+	 0x58, 0x4D, 0xA7, 0x78, 0xFF, 0xFF, 0x57, 0xF5, 0x3F, 0xFC, 0x5A, 0xF3, 0xC7, 0xF1, 0xAC, 0x83,
+	 0x01, 0x64, 0x02, 0x02, 0x6B, 0xFB, 0x64, 0x43, 0x1E, 0x60, 0xD4, 0x64, 0x0F, 0x60, 0x90, 0xFB,
+	 0x66, 0x44, 0x5A, 0xDB, 0x04, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0xCF, 0x83,
+	 0x72, 0xF3, 0x5A, 0xFD, 0xDC, 0x84, 0x72, 0xFB, 0x5C, 0xF3, 0xFF, 0xFF, 0xCC, 0x84, 0x5C, 0xFB,
+	 0x03, 0x03, 0xE3, 0x60, 0xBD, 0x78, 0xFF, 0xFF, 0x0A, 0x64, 0x5C, 0xFB, 0xA2, 0x4C, 0x20, 0x27,
+	 0xF8, 0x01, 0x46, 0x60, 0x50, 0x65, 0x72, 0x44, 0xD4, 0x80, 0xFF, 0xFF, 0xF2, 0x04, 0x5D, 0xFB,
+	 0x40, 0x48, 0x94, 0xF3, 0x5E, 0xFB, 0x40, 0x4A, 0x95, 0xF3, 0x96, 0xF3, 0x40, 0x4C, 0x60, 0x41,
+	 0x65, 0xF1, 0x40, 0x63, 0xAD, 0x80, 0xF0, 0xA3, 0x09, 0x02, 0x3C, 0x03, 0x2C, 0x41, 0x2A, 0x44,
+	 0x40, 0x4C, 0x28, 0x44, 0x40, 0x4A, 0x00, 0x64, 0x40, 0x48, 0xF4, 0x01, 0xD1, 0x80, 0x01, 0x02,
+	 0x31, 0x04, 0x10, 0xA3, 0x80, 0x60, 0x00, 0x65, 0xA5, 0x80, 0xCF, 0x83, 0x08, 0x02, 0x28, 0x44,
+	 0x60, 0x88, 0x2A, 0x44, 0x70, 0x8A, 0x2C, 0x44, 0x70, 0x8C, 0xF1, 0x81, 0xF5, 0x01, 0xE7, 0xA3,
+	 0x64, 0x44, 0x00, 0xA0, 0x00, 0x62, 0x02, 0x02, 0x00, 0x61, 0x1C, 0x00, 0xE0, 0x84, 0xDE, 0x82,
+	 0xFD, 0x04, 0x42, 0xFE, 0xF8, 0x84, 0x62, 0x45, 0xC7, 0x83, 0x60, 0x45, 0x02, 0xFE, 0xD5, 0x84,
+	 0x02, 0x05, 0x01, 0x05, 0x61, 0x44, 0xCF, 0x83, 0x60, 0x41, 0x08, 0x03, 0x28, 0x44, 0x60, 0x88,
+	 0x2A, 0x44, 0x70, 0x8A, 0x2C, 0x44, 0x70, 0x8C, 0xF1, 0x81, 0xF1, 0x01, 0xCE, 0x82, 0xE9, 0x81,
+	 0xFD, 0x02, 0xF1, 0x81, 0x61, 0x44, 0x00, 0xA8, 0xFF, 0xFF, 0x2F, 0x03, 0x73, 0x40, 0x5D, 0xF3,
+	 0xFF, 0xFF, 0x60, 0x47, 0xE8, 0x84, 0xE8, 0x84, 0x5E, 0xF3, 0x3F, 0xB5, 0xE0, 0x84, 0xE0, 0x84,
+	 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xB4, 0x84, 0x61, 0x45, 0xD4, 0x84, 0xC0, 0x84,
+	 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x81, 0x64, 0x44, 0x73, 0x45, 0xE0, 0x84, 0xE0, 0x84,
+	 0xE0, 0x84, 0xC4, 0x85, 0x61, 0x44, 0xD4, 0x80, 0xFF, 0xFF, 0x0F, 0x03, 0x60, 0x53, 0xD4, 0x84,
+	 0xFF, 0xFF, 0x74, 0xF3, 0xFF, 0xFF, 0xDC, 0x84, 0x01, 0xB4, 0x74, 0xFB, 0x13, 0x60, 0x06, 0xF3,
+	 0xFF, 0xFF, 0xDC, 0x84, 0x00, 0x36, 0x00, 0x3B, 0xA2, 0xDB, 0xE9, 0x60, 0xFB, 0x78, 0xFF, 0xFF,
+	 0xC1, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x04, 0x64, 0x03, 0xFA, 0x00, 0xF4, 0x09, 0xF2, 0xFF, 0xFF,
+	 0x60, 0x47, 0x00, 0x3A, 0x1C, 0x00, 0x60, 0x43, 0x00, 0x36, 0x1C, 0x00, 0xE0, 0xA0, 0xDA, 0x85,
+	 0x16, 0x07, 0x26, 0x60, 0x16, 0x61, 0xA1, 0xD1, 0xFF, 0xFF, 0xD3, 0x80, 0xCB, 0x83, 0x0F, 0x02,
+	 0x07, 0x0E, 0x59, 0xD3, 0xA5, 0xD0, 0xDA, 0x85, 0xD0, 0x80, 0xFF, 0xFF, 0x08, 0x02, 0xF9, 0x1F,
+	 0x12, 0x1E, 0xA5, 0xD0, 0x59, 0xD3, 0xFF, 0xFF, 0x90, 0x80, 0xFF, 0x22, 0x0C, 0x00, 0xE4, 0x60,
+	 0x63, 0x78, 0xFF, 0xFF, 0x13, 0x60, 0x44, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x2A, 0x03, 0x00,
+	 0x26, 0x60, 0x38, 0x64, 0x02, 0x00, 0x26, 0x60, 0x16, 0x64, 0x16, 0x60, 0xCF, 0xFB, 0x26, 0x46,
+	 0x2F, 0xF2, 0x2C, 0xFA, 0x30, 0xF2, 0x2D, 0xFA, 0x31, 0xF2, 0x2E, 0xFA, 0xCB, 0xF1, 0x2F, 0xF8,
+	 0xCC, 0xF1, 0x30, 0xF8, 0xCD, 0xF1, 0x31, 0xF8, 0x66, 0xF1, 0x32, 0xF8, 0x67, 0xF1, 0x33, 0xF8,
+	 0x68, 0xF1, 0x34, 0xF8, 0x00, 0x65, 0xEF, 0x60, 0x58, 0x4E, 0xDC, 0x78, 0xFF, 0xFF, 0x61, 0x44,
+	 0x15, 0x60, 0xC2, 0xFB, 0x50, 0x63, 0x2A, 0xFC, 0xAB, 0xF3, 0x19, 0xFA, 0x00, 0x64, 0x3E, 0xFA,
+	 0x87, 0xF3, 0x07, 0xFA, 0x00, 0xF4, 0x65, 0xF1, 0x06, 0xF8, 0x17, 0x60, 0x22, 0xF3, 0x15, 0x60,
+	 0xDD, 0xF1, 0xFB, 0x60, 0xFF, 0xB7, 0x64, 0x40, 0x10, 0x26, 0x04, 0xBC, 0x60, 0x47, 0x07, 0xFA,
+	 0x2D, 0x60, 0xA6, 0x65, 0xE4, 0x60, 0x58, 0x4D, 0xE7, 0x78, 0xFF, 0xFF, 0x64, 0xF3, 0x2E, 0x60,
+	 0x1E, 0x63, 0x60, 0x40, 0x01, 0x27, 0x67, 0x43, 0x16, 0x60, 0xD5, 0xFD, 0x2D, 0x60, 0x9E, 0x64,
+	 0x40, 0x48, 0x10, 0x61, 0x00, 0x60, 0x00, 0x64, 0xE4, 0x60, 0x58, 0x4D, 0xA7, 0x78, 0xFF, 0xFF,
+	 0x26, 0x46, 0x3F, 0xFC, 0x1E, 0x60, 0xD4, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x26, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x20, 0x44, 0x80, 0x26, 0x11, 0x00,
+	 0x80, 0xBC, 0x40, 0x40, 0x00, 0x64, 0x94, 0xFB, 0x95, 0xFB, 0x96, 0xFB, 0x74, 0xFB, 0x65, 0xF3,
+	 0x00, 0x75, 0x00, 0x72, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x93, 0xC7, 0xF3, 0xED, 0xE2, 0xCC, 0x84,
+	 0x5A, 0xFB, 0x00, 0x66, 0x46, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x64, 0x08, 0x60, 0x12, 0xFB,
+	 0x5A, 0xDB, 0x00, 0x64, 0x72, 0xFB, 0x74, 0xFB, 0x2F, 0x58, 0xFF, 0xFF, 0x3E, 0x63, 0x18, 0x60,
+	 0x94, 0x61, 0x59, 0xD1, 0x61, 0x46, 0x07, 0x1B, 0xFC, 0x1F, 0x2D, 0x60, 0xC8, 0x62, 0xA2, 0xDF,
+	 0x01, 0x65, 0x00, 0x61, 0x16, 0x00, 0x18, 0x60, 0xD6, 0x61, 0x49, 0xD1, 0xCB, 0x83, 0xFD, 0x18,
+	 0x63, 0x41, 0x04, 0xA1, 0x61, 0x45, 0x66, 0x43, 0x2D, 0x60, 0xC8, 0x64, 0xDC, 0x84, 0x60, 0xFE,
+	 0xBD, 0xD1, 0xA0, 0xD9, 0xCD, 0x81, 0x20, 0xFE, 0xF9, 0x02, 0x66, 0x44, 0x18, 0x60, 0x96, 0x7C,
+	 0xD0, 0x81, 0x5A, 0xF3, 0xC7, 0xF1, 0x2D, 0x60, 0xC6, 0x63, 0x00, 0xA0, 0x64, 0x5F, 0xBD, 0xDB,
+	 0x0F, 0x60, 0x6D, 0xF1, 0x02, 0x02, 0x01, 0x18, 0x01, 0xB9, 0x61, 0x44, 0x60, 0xFE, 0xA3, 0xDB,
+	 0xFC, 0xA3, 0x65, 0x44, 0x03, 0xA4, 0xA3, 0xDB, 0x20, 0xFE, 0x2D, 0x58, 0xFF, 0xFF, 0x17, 0x60,
+	 0x23, 0xFB, 0xCD, 0x81, 0x28, 0xD3, 0x5A, 0x88, 0xDC, 0x83, 0x31, 0x18, 0xFB, 0x03, 0x61, 0x40,
+	 0x7F, 0x3A, 0x06, 0x00, 0x17, 0x60, 0x23, 0xF3, 0x03, 0x61, 0x7C, 0xA4, 0xA2, 0xDB, 0x00, 0xF4,
+	 0x60, 0xFE, 0xA3, 0xD1, 0x5D, 0xD8, 0x61, 0x40, 0x7F, 0x3A, 0x08, 0x00, 0x20, 0xFE, 0x17, 0x60,
+	 0x23, 0xF3, 0x03, 0x61, 0x7C, 0xA4, 0xA2, 0xDB, 0x00, 0xF4, 0x60, 0xFE, 0xBF, 0xD3, 0x5D, 0xDA,
+	 0xFF, 0xB4, 0x00, 0x7F, 0x12, 0x03, 0xDF, 0x83, 0x61, 0x40, 0x7F, 0x3A, 0x0A, 0x00, 0x20, 0xFE,
+	 0x60, 0x45, 0x17, 0x60, 0x23, 0xF3, 0x03, 0x61, 0x7C, 0xA4, 0xA2, 0xDB, 0x65, 0x44, 0x00, 0xF4,
+	 0x60, 0xFE, 0xBD, 0xD1, 0xCC, 0x84, 0x5D, 0xD8, 0xEF, 0x02, 0x20, 0xFE, 0xCB, 0x01, 0x17, 0x60,
+	 0x23, 0xF1, 0xFD, 0xA1, 0xFF, 0xB1, 0xC1, 0x83, 0xA2, 0xDD, 0x2D, 0x58, 0xFF, 0xFF, 0x67, 0x5C,
+	 0x14, 0x60, 0x26, 0x61, 0xA1, 0xD3, 0xA5, 0xD9, 0x10, 0x18, 0x60, 0x43, 0x2D, 0x60, 0xEE, 0x64,
+	 0xA5, 0xDB, 0x60, 0xFE, 0xA0, 0xDD, 0x20, 0xFE, 0xDC, 0x84, 0xCF, 0x83, 0xE3, 0x83, 0x59, 0xD1,
+	 0xDC, 0x84, 0x60, 0xFE, 0xA0, 0xD9, 0x20, 0xFE, 0xFA, 0x1F, 0x2D, 0x58, 0xFF, 0xFF, 0x15, 0x60,
+	 0xDC, 0xF1, 0x15, 0x60, 0xDD, 0xF3, 0x64, 0x40, 0x01, 0x2A, 0x02, 0xBC, 0x64, 0x40, 0x02, 0x2A,
+	 0x04, 0xBC, 0x64, 0x40, 0x04, 0x2A, 0xEF, 0xB4, 0x15, 0x60, 0xDD, 0xFB, 0x07, 0xB4, 0x60, 0xFE,
+	 0x17, 0x60, 0x10, 0xFB, 0x20, 0xFE, 0x07, 0x7C, 0x15, 0x60, 0xDC, 0xF9, 0x2D, 0x58, 0xFF, 0xFF,
+	 0x20, 0x40, 0x20, 0x2A, 0x0A, 0x00, 0x0A, 0x60, 0x77, 0xF1, 0x50, 0xF3, 0x2E, 0x60, 0x31, 0x63,
+	 0x60, 0xFE, 0xBD, 0xD9, 0x60, 0x47, 0xA3, 0xDB, 0x20, 0xFE, 0x2D, 0x58, 0xFF, 0xFF, 0x0E, 0x57,
+	 0x32, 0x40, 0x40, 0x26, 0x24, 0x00, 0x45, 0x48, 0x00, 0x60, 0x10, 0x61, 0xB5, 0x60, 0x58, 0x4D,
+	 0x9F, 0x78, 0xFF, 0xFF, 0x1C, 0x03, 0xF2, 0x60, 0x02, 0x64, 0x24, 0xFA, 0x00, 0x60, 0x48, 0x61,
+	 0x28, 0x44, 0x59, 0xDA, 0x03, 0x64, 0x38, 0x43, 0xBD, 0xD1, 0xCC, 0x84, 0x59, 0xD8, 0xFC, 0x02,
+	 0x39, 0x44, 0x59, 0xDA, 0x06, 0x64, 0x23, 0xFA, 0x1F, 0x60, 0x10, 0x64, 0x0F, 0x60, 0x90, 0xFB,
+	 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xFA, 0xFE, 0x37, 0x58,
+	 0xFF, 0xFF, 0x0E, 0x57, 0x32, 0x40, 0x40, 0x26, 0x4F, 0x00, 0x45, 0x48, 0x00, 0x60, 0x68, 0x61,
+	 0xB5, 0x60, 0x58, 0x4D, 0x9F, 0x78, 0xFF, 0xFF, 0x47, 0x03, 0xF2, 0x60, 0x01, 0x64, 0x24, 0xFA,
+	 0x02, 0x60, 0x00, 0x61, 0x46, 0x4A, 0x38, 0x44, 0x54, 0x94, 0x03, 0x64, 0x01, 0x02, 0x09, 0x00,
+	 0x06, 0x63, 0x4A, 0x61, 0x38, 0x46, 0xBD, 0xD0, 0xCC, 0x84, 0x2A, 0x46, 0x59, 0xD8, 0xFA, 0x02,
+	 0x06, 0x00, 0xDA, 0x81, 0x38, 0x43, 0xBD, 0xD1, 0xCC, 0x84, 0x59, 0xD8, 0xFC, 0x02, 0x05, 0x63,
+	 0x28, 0x44, 0x02, 0xA8, 0x25, 0xFA, 0x07, 0x02, 0x03, 0x64, 0x39, 0x43, 0xBD, 0xD1, 0xCC, 0x84,
+	 0x59, 0xD8, 0xFC, 0x02, 0x08, 0x63, 0x28, 0x44, 0x03, 0xA8, 0x16, 0x60, 0x82, 0xF3, 0x0F, 0x03,
+	 0xE8, 0x85, 0xC7, 0x85, 0x60, 0x43, 0xFE, 0xA3, 0x2D, 0x60, 0x06, 0x64, 0x58, 0xD1, 0xD9, 0x81,
+	 0xA1, 0xD8, 0x7E, 0x2A, 0x02, 0x00, 0x00, 0xF4, 0x02, 0x61, 0xF8, 0x1F, 0x65, 0x43, 0x2A, 0x46,
+	 0x23, 0xFC, 0x1F, 0x60, 0x10, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xFA, 0xFE, 0x37, 0x58, 0xFF, 0xFF, 0x0E, 0x57, 0x32, 0x40,
+	 0x40, 0x26, 0x1B, 0x00, 0x45, 0x48, 0x00, 0x60, 0x06, 0x61, 0xB5, 0x60, 0x58, 0x4D, 0x9F, 0x78,
+	 0xFF, 0xFF, 0x13, 0x03, 0x02, 0x64, 0x23, 0xFA, 0xF2, 0x60, 0x00, 0x64, 0x5A, 0xDA, 0x28, 0x44,
+	 0x5A, 0xDA, 0xFF, 0xFF, 0x1F, 0x60, 0x10, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x66, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xFA, 0xFE, 0x37, 0x58, 0xFF, 0xFF, 0xA0, 0xD3,
+	 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x03, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE,
+	 0xDD, 0x98, 0xFF, 0xFF, 0x97, 0xF1, 0xA0, 0xD3, 0xFF, 0xFF, 0xD8, 0x80, 0xC4, 0x84, 0x0C, 0x03,
+	 0x08, 0x05, 0xDC, 0x80, 0xD0, 0x80, 0x05, 0x03, 0xA2, 0xDB, 0x02, 0x24, 0xC6, 0xFE, 0xDD, 0x98,
+	 0xFF, 0xFF, 0xFF, 0x60, 0xFE, 0x64, 0xA2, 0xDB, 0xDD, 0x98, 0xFF, 0xFF, 0xA2, 0xFF, 0x32, 0x40,
+	 0x40, 0x26, 0x3C, 0x00, 0x7B, 0xF3, 0x67, 0x43, 0xDC, 0x84, 0xCC, 0x84, 0x37, 0x03, 0x60, 0x46,
+	 0x0A, 0x02, 0x7B, 0xFD, 0x00, 0x60, 0x46, 0x61, 0xB5, 0x60, 0x58, 0x4D, 0x9F, 0x78, 0xFF, 0xFF,
+	 0x66, 0x44, 0x7B, 0xFB, 0x2C, 0x03, 0x46, 0x4B, 0x25, 0x60, 0xD0, 0x61, 0x18, 0x64, 0x23, 0xFA,
+	 0xF1, 0x60, 0x00, 0x64, 0x24, 0xFA, 0x4A, 0x65, 0xA2, 0xFF, 0x2C, 0x63, 0x59, 0xD1, 0xA2, 0xDF,
+	 0xA5, 0xD8, 0xDA, 0x85, 0x80, 0x3A, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0xF7, 0x1F, 0x12, 0x63,
+	 0x59, 0xD1, 0xA5, 0xD8, 0xDA, 0x85, 0x80, 0x3A, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0xF8, 0x1F,
+	 0x1F, 0x60, 0x10, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x2B, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB,
+	 0xFF, 0xFF, 0x2B, 0xFF, 0xFA, 0xFE, 0xA6, 0xFE, 0x00, 0x64, 0x7B, 0xFB, 0xA3, 0xFF, 0xCA, 0x60,
+	 0x7E, 0x78, 0xFF, 0xFF, 0xA6, 0xFE, 0xBA, 0x05, 0xA7, 0xFE, 0x0A, 0x05, 0xA5, 0xFE, 0x03, 0x04,
+	 0xE6, 0x60, 0x8E, 0x78, 0xFF, 0xFF, 0xA4, 0xFE, 0xF2, 0x04, 0xE7, 0x60, 0x1F, 0x78, 0xFF, 0xFF,
+	 0x36, 0x45, 0x19, 0x60, 0x86, 0x64, 0x44, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0x28, 0xF3, 0x7D, 0xF1,
+	 0x60, 0x47, 0x07, 0xB4, 0x4E, 0xFB, 0x01, 0x61, 0x03, 0x03, 0xCC, 0x84, 0xE1, 0x81, 0xFD, 0x02,
+	 0x9D, 0x84, 0xA1, 0x80, 0xA0, 0x83, 0x15, 0x03, 0x7D, 0xFD, 0x08, 0x60, 0x24, 0xF1, 0x00, 0x60,
+	 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x31, 0x44, 0xDE, 0xB4, 0x40, 0x51, 0x01, 0x7C,
+	 0xBC, 0xF9, 0x49, 0xF3, 0x01, 0x63, 0x60, 0x40, 0xFF, 0x26, 0x49, 0xFD, 0xCA, 0x60, 0x7E, 0x78,
+	 0xFF, 0xFF, 0xE6, 0x60, 0x8E, 0x78, 0xFF, 0xFF, 0x26, 0x60, 0xB0, 0x63, 0xBD, 0xD3, 0xBD, 0xD1,
+	 0xBD, 0xD1, 0xB0, 0x84, 0xB0, 0x84, 0xFF, 0xFF, 0x07, 0x02, 0x6A, 0xFB, 0x31, 0x44, 0xFE, 0xB4,
+	 0x40, 0x51, 0x0D, 0x64, 0x05, 0xFB, 0x1A, 0x00, 0x28, 0xF3, 0xFF, 0xFF, 0x13, 0x60, 0x52, 0xF3,
+	 0xC5, 0xFB, 0x64, 0xFB, 0x0F, 0x60, 0x85, 0xF3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x46, 0x5E,
+	 0x31, 0x44, 0x21, 0xBC, 0x40, 0x51, 0xED, 0xE2, 0x0F, 0x4E, 0xD0, 0x60, 0x58, 0x4F, 0xA8, 0x78,
+	 0xFF, 0xFF, 0x0E, 0x4F, 0x00, 0x00, 0xE8, 0x60, 0x74, 0x78, 0xFF, 0xFF, 0xD7, 0xFE, 0xCA, 0x60,
+	 0x7E, 0x78, 0xFF, 0xFF, 0x2E, 0xF5, 0x27, 0xF2, 0x15, 0x60, 0x02, 0x65, 0x60, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46,
+	 0x27, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46, 0x26, 0xF0, 0x63, 0x46,
+	 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46, 0x25, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46, 0xE8, 0x1B, 0x87, 0xF3, 0x08, 0xFE, 0x60, 0x43,
+	 0x61, 0x46, 0x26, 0x02, 0x0B, 0x60, 0x82, 0xF3, 0xDA, 0x81, 0x60, 0x45, 0xD5, 0x80, 0xA1, 0xD1,
+	 0x04, 0x03, 0xD3, 0x80, 0xD9, 0x81, 0xFA, 0x02, 0x08, 0x00, 0xA1, 0xDD, 0xD9, 0x84, 0x0B, 0x60,
+	 0x82, 0xFB, 0x4A, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xA2, 0xDB, 0x66, 0x45, 0x63, 0x46, 0x06, 0xF2,
+	 0xFF, 0x60, 0x01, 0x7C, 0xA0, 0x9C, 0x06, 0xF8, 0x65, 0x46, 0x70, 0xF3, 0x60, 0x40, 0x10, 0x2A,
+	 0x03, 0x00, 0xCC, 0x84, 0x80, 0x2B, 0x70, 0xFB, 0xE7, 0x60, 0x58, 0x4E, 0x81, 0x78, 0xFF, 0xFF,
+	 0xAD, 0x01, 0x2E, 0xF5, 0x28, 0xF0, 0x18, 0x60, 0x12, 0xF9, 0x27, 0xF2, 0x15, 0x60, 0x02, 0x65,
+	 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2,
+	 0x16, 0x18, 0x61, 0x46, 0x27, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46,
+	 0x26, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46, 0x25, 0xF0, 0x63, 0x46,
+	 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46, 0xE8, 0x1B, 0x87, 0xF3,
+	 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0x12, 0x02, 0x63, 0x46, 0x06, 0xF2, 0xFF, 0xFF, 0x02, 0xB0,
+	 0x08, 0xBC, 0x0C, 0x03, 0x06, 0xFA, 0xE7, 0x60, 0x58, 0x4E, 0x81, 0x78, 0xFF, 0xFF, 0x08, 0x60,
+	 0x1E, 0xF1, 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x6F, 0x01, 0x01, 0x64,
+	 0x51, 0xFB, 0x28, 0x60, 0x4E, 0x64, 0x52, 0xFB, 0x15, 0x60, 0xC3, 0xF3, 0xFF, 0xFF, 0x15, 0x18,
+	 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x08, 0x60, 0x1B, 0xF1, 0x00, 0x60, 0x10, 0x64,
+	 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x10, 0x60, 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xE7, 0x60,
+	 0x3D, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x2B, 0x60, 0x88, 0x61, 0xFF, 0x60,
+	 0x80, 0x65, 0xA1, 0xD3, 0xFF, 0xFF, 0xA4, 0x80, 0x59, 0xD3, 0x05, 0x02, 0x04, 0x1B, 0x59, 0xD3,
+	 0xFF, 0xFF, 0x01, 0x1B, 0x15, 0x00, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x08, 0x60,
+	 0x1B, 0xF1, 0x00, 0x60, 0x20, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x10, 0x60, 0x00, 0x64,
+	 0x08, 0x60, 0x16, 0xFB, 0xE7, 0x60, 0x60, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x00, 0x60, 0x04, 0x61, 0xB5, 0x60, 0x58, 0x4D, 0x9F, 0x78, 0xFF, 0xFF, 0x01, 0x64, 0x23, 0xFA,
+	 0xF1, 0x60, 0x02, 0x64, 0x24, 0xFA, 0x1F, 0x60, 0x10, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x66, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xFA, 0xFE, 0x00, 0x60, 0x30, 0x64,
+	 0x08, 0x60, 0x16, 0xFB, 0xD2, 0x60, 0xB5, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0xCA, 0x60, 0x7E, 0x78,
+	 0xFF, 0xFF, 0x0E, 0x57, 0x63, 0x46, 0x43, 0x47, 0x22, 0xF2, 0x76, 0xF2, 0x02, 0x1B, 0x01, 0x1B,
+	 0x0C, 0x00, 0x60, 0x46, 0x1F, 0x60, 0x20, 0x64, 0x40, 0x4B, 0xF6, 0x60, 0x58, 0x4D, 0xB3, 0x78,
+	 0xFF, 0xFF, 0x27, 0x46, 0x76, 0xF2, 0xFF, 0xFF, 0xF4, 0x1B, 0x37, 0x58, 0xFF, 0xFF, 0xE7, 0x60,
+	 0x9F, 0x64, 0x08, 0x60, 0x2A, 0xFB, 0x2F, 0x58, 0xFF, 0xFF, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x64,
+	 0x08, 0x60, 0x21, 0xFB, 0x5A, 0xDB, 0x10, 0x60, 0x42, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x28, 0xF3, 0x7D, 0xF1, 0x60, 0x47, 0x07, 0xB4, 0x4E, 0xFB, 0x01, 0x61, 0x03, 0x03,
+	 0xCC, 0x84, 0xE1, 0x81, 0xFD, 0x02, 0xA1, 0x80, 0xB1, 0x83, 0x16, 0x02, 0xCF, 0x85, 0xA7, 0x80,
+	 0x7D, 0xFD, 0x0B, 0x02, 0x01, 0x65, 0xE5, 0x60, 0x58, 0x4E, 0xA6, 0x78, 0xFF, 0xFF, 0x31, 0x44,
+	 0xDF, 0xB4, 0x40, 0x51, 0xD0, 0x60, 0xD9, 0x78, 0xFF, 0xFF, 0x08, 0x60, 0x21, 0xF1, 0x00, 0x60,
+	 0x01, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0xE6, 0x60, 0x8E, 0x78, 0xFF, 0xFF, 0x28, 0xF3,
+	 0x7D, 0xF1, 0x60, 0x47, 0x07, 0xB4, 0x4E, 0xFB, 0x01, 0x61, 0x03, 0x03, 0xCC, 0x84, 0xE1, 0x81,
+	 0xFD, 0x02, 0x9D, 0x84, 0xA1, 0x80, 0xA0, 0x83, 0x13, 0x03, 0x7D, 0xFD, 0x08, 0x60, 0x24, 0xF1,
+	 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x7D, 0xF1, 0x31, 0x44, 0x64, 0x40,
+	 0xFF, 0x26, 0x03, 0x00, 0x21, 0xBC, 0x40, 0x51, 0x03, 0x00, 0xCA, 0x60, 0x7E, 0x78, 0xFF, 0xFF,
+	 0xE6, 0x60, 0x8E, 0x78, 0xFF, 0xFF, 0x0E, 0x57, 0x32, 0x40, 0x40, 0x26, 0x1B, 0x00, 0x45, 0x48,
+	 0x00, 0x60, 0x06, 0x61, 0xB5, 0x60, 0x58, 0x4D, 0x9F, 0x78, 0xFF, 0xFF, 0x13, 0x03, 0x02, 0x64,
+	 0x23, 0xFA, 0xF2, 0x60, 0x04, 0x64, 0x5A, 0xDA, 0x28, 0x44, 0x5A, 0xDA, 0xFF, 0xFF, 0x1F, 0x60,
+	 0x10, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0xFA, 0xFE, 0x37, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0x79, 0xF3, 0xFF, 0xFF, 0x00, 0xA8,
+	 0x60, 0x46, 0x0E, 0xF2, 0x59, 0x03, 0x60, 0x40, 0xF0, 0x37, 0x46, 0x00, 0xFF, 0x37, 0x3B, 0x00,
+	 0xFD, 0x37, 0x33, 0x00, 0x18, 0x37, 0x27, 0x00, 0xFE, 0x37, 0x2A, 0x00, 0xF8, 0x37, 0x0A, 0x00,
+	 0x60, 0x47, 0xFF, 0xB5, 0x10, 0x60, 0x24, 0x62, 0x46, 0xD1, 0x00, 0x60, 0x01, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x00, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xD8, 0x01, 0x06, 0xB4, 0xFD, 0x7F, 0x0E, 0xFA, 0x1E, 0x60,
+	 0xF8, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0xF9, 0xFE, 0xC9, 0x01, 0xDE, 0x60, 0x58, 0x4F, 0x6C, 0x78, 0xFF, 0xFF, 0x14, 0x00,
+	 0xE1, 0x60, 0x58, 0x4F, 0x32, 0x78, 0xFF, 0xFF, 0xBF, 0x03, 0x23, 0xF0, 0x60, 0x40, 0x04, 0x26,
+	 0xE3, 0x1B, 0x02, 0x26, 0xE1, 0x18, 0xA2, 0xFF, 0x02, 0xF0, 0x09, 0x60, 0x08, 0x64, 0xD0, 0x80,
+	 0x8F, 0xF3, 0x02, 0x02, 0xCC, 0x84, 0x8F, 0xFB, 0x1F, 0x60, 0x20, 0x64, 0x40, 0x4B, 0xF6, 0x60,
+	 0x58, 0x4D, 0xB3, 0x78, 0xFF, 0xFF, 0xA8, 0x01, 0xAC, 0xFE, 0x09, 0x05, 0xAD, 0xFE, 0x0F, 0x05,
+	 0xAE, 0xFE, 0xA2, 0x05, 0xAF, 0xFE, 0x37, 0x05, 0xCA, 0x60, 0x7E, 0x78, 0xFF, 0xFF, 0x08, 0x60,
+	 0x11, 0xF1, 0x20, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0xF5, 0x01, 0x10, 0x60,
+	 0x56, 0x65, 0x03, 0x61, 0x07, 0x00, 0xA2, 0xDD, 0x58, 0x4F, 0x64, 0x58, 0xFF, 0xFF, 0x00, 0xB9,
+	 0xFF, 0xFF, 0x08, 0x03, 0x00, 0x63, 0xA5, 0xD1, 0x5A, 0xD3, 0xDA, 0x85, 0x00, 0xA8, 0xCD, 0x81,
+	 0xF2, 0x02, 0xF8, 0x02, 0xE1, 0x01, 0x10, 0x60, 0x20, 0x62, 0x10, 0x60, 0x46, 0x65, 0xE8, 0x60,
+	 0xA9, 0x63, 0x5A, 0xDF, 0xD6, 0x80, 0xFF, 0xFF, 0x04, 0x03, 0x5A, 0xDF, 0x5A, 0xDF, 0x5A, 0xDD,
+	 0xF9, 0x01, 0x10, 0x60, 0x54, 0x65, 0x5A, 0xDF, 0xD6, 0x80, 0xFF, 0xFF, 0x02, 0x03, 0x5A, 0xDD,
+	 0xFB, 0x01, 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x60, 0x24, 0x64, 0x40, 0x41, 0x10, 0x60, 0x22, 0x63,
+	 0xA3, 0xD1, 0x00, 0x64, 0xD0, 0x80, 0x06, 0x61, 0x08, 0x03, 0xBD, 0xDB, 0xA3, 0xD3, 0xFF, 0xFF,
+	 0xB0, 0x84, 0xCD, 0x81, 0xA3, 0xDB, 0x06, 0xA3, 0xF9, 0x02, 0x10, 0x60, 0x48, 0x63, 0xA3, 0xD1,
+	 0x00, 0x64, 0xD0, 0x80, 0x07, 0x61, 0x19, 0x03, 0xBD, 0xDB, 0x64, 0x44, 0xFE, 0xA3, 0x02, 0xA3,
+	 0xCD, 0x81, 0xE8, 0x84, 0xE3, 0x03, 0x02, 0x05, 0xE1, 0x03, 0xF9, 0x01, 0x77, 0xFB, 0x79, 0xFD,
+	 0x61, 0x5C, 0xA3, 0xD3, 0x78, 0xF9, 0x03, 0x18, 0x58, 0x4F, 0x60, 0x58, 0xFF, 0xFF, 0x79, 0xF3,
+	 0x78, 0xF1, 0x60, 0x43, 0x77, 0xF3, 0x64, 0x41, 0xEA, 0x01, 0x21, 0x43, 0x10, 0x60, 0x48, 0x65,
+	 0xD7, 0x80, 0xBD, 0xD1, 0xBD, 0xD3, 0x03, 0x02, 0xCA, 0x60, 0x7E, 0x78, 0xFF, 0xFF, 0xA0, 0x84,
+	 0xBD, 0xD1, 0x43, 0x41, 0xF5, 0x03, 0xE8, 0x60, 0xAE, 0x64, 0x64, 0x58, 0x40, 0x4F, 0x2A, 0xF0,
+	 0x83, 0x60, 0xFF, 0x65, 0x64, 0x47, 0x03, 0x2B, 0x01, 0x00, 0x17, 0x00, 0x03, 0x26, 0x03, 0xAC,
+	 0x60, 0x47, 0xA4, 0x84, 0x2A, 0xFA, 0x2F, 0xF2, 0x2C, 0xFA, 0x30, 0xF2, 0x2D, 0xFA, 0x31, 0xF2,
+	 0x2E, 0xFA, 0x64, 0x41, 0xCB, 0xF3, 0x2F, 0xFA, 0x60, 0x43, 0xCC, 0xF3, 0x30, 0xFA, 0xCD, 0xF1,
+	 0x31, 0xF8, 0x32, 0xFC, 0x33, 0xFA, 0x34, 0xF8, 0x19, 0x00, 0x60, 0x47, 0xA4, 0x84, 0x2A, 0xFA,
+	 0x2F, 0xF2, 0x2C, 0xFA, 0x30, 0xF2, 0x2D, 0xFA, 0x31, 0xF2, 0x2E, 0xFA, 0x36, 0xF2, 0x32, 0xFA,
+	 0x37, 0xF2, 0x33, 0xFA, 0x38, 0xF2, 0x34, 0xFA, 0xCB, 0xF3, 0x2F, 0xFA, 0x36, 0xFA, 0xCC, 0xF3,
+	 0x30, 0xFA, 0x37, 0xFA, 0xCD, 0xF3, 0x31, 0xFA, 0x38, 0xFA, 0x64, 0x41, 0x1C, 0xF2, 0x13, 0xFA,
+	 0x00, 0xF4, 0x0D, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x80, 0x2B, 0x28, 0x00, 0x26, 0x46, 0x04, 0x63,
+	 0x03, 0xFC, 0x00, 0xF4, 0x0D, 0xF2, 0x06, 0xFA, 0xEA, 0x60, 0x58, 0x4E, 0x49, 0x78, 0xFF, 0xFF,
+	 0xFF, 0xA0, 0x59, 0xF5, 0x19, 0x02, 0x39, 0xF2, 0x26, 0x46, 0x3F, 0xFA, 0x00, 0xF4, 0x00, 0x60,
+	 0x81, 0x67, 0x0D, 0xFA, 0x7C, 0x64, 0x01, 0xFA, 0x26, 0x46, 0x00, 0x64, 0x3E, 0xFA, 0x1E, 0x60,
+	 0xE0, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0xC8, 0xFE, 0x00, 0x66, 0x46, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x26, 0x46, 0x3F, 0xF0,
+	 0x42, 0x64, 0xD0, 0x80, 0xFF, 0xFF, 0x01, 0x04, 0x3F, 0xFA, 0x1C, 0xF2, 0x13, 0xFA, 0x26, 0xF2,
+	 0x27, 0xF0, 0x60, 0x47, 0x00, 0xF4, 0x1F, 0xFA, 0x64, 0x47, 0x20, 0xFA, 0x61, 0x44, 0x21, 0xFA,
+	 0x01, 0x67, 0x0D, 0xFA, 0x10, 0x61, 0x26, 0x60, 0x64, 0x64, 0x1E, 0x63, 0x58, 0xD1, 0xCD, 0x81,
+	 0xBD, 0xD8, 0xFC, 0x02, 0x9A, 0xF1, 0xB7, 0xF1, 0x64, 0x5E, 0x64, 0x5F, 0x44, 0x63, 0xBD, 0xDA,
+	 0x13, 0x60, 0x2F, 0xF3, 0xFF, 0xFF, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0x09, 0xBC, 0x4A, 0xD3,
+	 0x60, 0x45, 0x60, 0x40, 0x01, 0x36, 0x03, 0x64, 0x02, 0x36, 0x01, 0x64, 0xB4, 0x84, 0x06, 0xA2,
+	 0xA2, 0xD1, 0xBD, 0xDA, 0x64, 0x47, 0xBD, 0xDA, 0xB4, 0xF3, 0xB5, 0xF1, 0x60, 0x47, 0xBD, 0xDA,
+	 0x64, 0x47, 0xC3, 0xF1, 0xBD, 0xDA, 0x64, 0x44, 0xBD, 0xDA, 0x26, 0x46, 0x00, 0x64, 0x23, 0xF0,
+	 0x3B, 0xF0, 0x64, 0x40, 0x10, 0x2A, 0x06, 0x00, 0xC0, 0x67, 0xA0, 0x84, 0xE8, 0x84, 0xE8, 0x84,
+	 0xE8, 0x84, 0x10, 0xBC, 0x3E, 0xFA, 0x1E, 0x60, 0xE0, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x26, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC8, 0xFE, 0x00, 0x66, 0x46, 0x46,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x04, 0x60, 0x5C, 0x61, 0xB5, 0x60, 0x58, 0x4D, 0xA2, 0x78, 0xFF, 0xFF,
+	 0x66, 0x44, 0x59, 0xFB, 0x04, 0x64, 0x03, 0xFA, 0x2F, 0x58, 0xFF, 0xFF, 0x59, 0xF5, 0xAB, 0xF1,
+	 0x19, 0xF8, 0x00, 0x64, 0x3E, 0xFA, 0x08, 0x64, 0x2A, 0xFA, 0x80, 0x7E, 0xF8, 0x7F, 0x0E, 0xFA,
+	 0x87, 0xF1, 0x07, 0xF8, 0x01, 0x60, 0x60, 0x67, 0x2C, 0xFA, 0x1D, 0x60, 0x00, 0x67, 0x2D, 0xFA,
+	 0x01, 0x60, 0x00, 0x67, 0x2E, 0xFA, 0xCB, 0xF1, 0x2F, 0xF8, 0x32, 0xF8, 0xCC, 0xF1, 0x30, 0xF8,
+	 0x33, 0xF8, 0xCD, 0xF1, 0x31, 0xF8, 0x34, 0xF8, 0x00, 0x63, 0x3B, 0xFC, 0x3D, 0xFC, 0x01, 0x64,
+	 0x3A, 0xFA, 0x66, 0x64, 0x39, 0xFA, 0x3C, 0xFC, 0xAA, 0x60, 0xAA, 0x64, 0x00, 0xF4, 0x02, 0xFA,
+	 0x00, 0x60, 0x03, 0x64, 0x5A, 0xDA, 0x1D, 0x60, 0x60, 0x64, 0x5A, 0xDA, 0x01, 0x60, 0x00, 0x64,
+	 0x5A, 0xDA, 0x81, 0x7F, 0x18, 0x7E, 0x08, 0xFA, 0x01, 0x60, 0x01, 0x64, 0x0A, 0xFA, 0x00, 0x64,
+	 0x0E, 0xFA, 0x2D, 0x58, 0xFF, 0xFF, 0x59, 0xF5, 0x3D, 0xF2, 0x3C, 0xF2, 0xCC, 0x83, 0x00, 0xA8,
+	 0x03, 0x03, 0x08, 0x28, 0x3D, 0xFC, 0x42, 0x00, 0x3D, 0xFA, 0x3A, 0xF2, 0x3B, 0xF0, 0x00, 0x63,
+	 0x00, 0xF4, 0x07, 0xFC, 0x01, 0xB0, 0x0B, 0xFA, 0x19, 0x03, 0x1F, 0xF8, 0xFF, 0xFF, 0x18, 0x64,
+	 0x0F, 0x60, 0x90, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x0A, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0x1F, 0xF2, 0x1E, 0xF0, 0x59, 0xF5, 0x00, 0xA8, 0x3B, 0xF8, 0xD0, 0x80, 0x06, 0x03, 0x05, 0x03,
+	 0x04, 0x60, 0x5C, 0x63, 0x0F, 0x64, 0x3A, 0xFA, 0x39, 0xFC, 0x00, 0xF4, 0x00, 0x64, 0x06, 0xFA,
+	 0xEA, 0x60, 0x58, 0x4E, 0x49, 0x78, 0xFF, 0xFF, 0x59, 0xF5, 0x00, 0xF4, 0x81, 0x60, 0x00, 0x64,
+	 0x06, 0xFA, 0x32, 0x47, 0x07, 0xFA, 0xB7, 0xF1, 0x00, 0x7F, 0x64, 0x5E, 0x09, 0xFA, 0x59, 0xF5,
+	 0x00, 0x64, 0x15, 0xFA, 0x39, 0xF2, 0x3F, 0xFA, 0x1E, 0x60, 0xCE, 0x64, 0x0F, 0x60, 0x90, 0xFB,
+	 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xE3, 0x60, 0xC0, 0x78,
+	 0xFF, 0xFF, 0x66, 0x45, 0x0E, 0xF2, 0x0F, 0xF0, 0x10, 0xF0, 0x64, 0x41, 0x01, 0xA8, 0x59, 0xF5,
+	 0x09, 0x02, 0xAD, 0x83, 0x64, 0x44, 0xAC, 0x84, 0x08, 0x24, 0x0A, 0x63, 0x3C, 0xFC, 0x3D, 0xFC,
+	 0x1A, 0x02, 0x2D, 0x00, 0x03, 0x3A, 0x03, 0x00, 0x00, 0x64, 0x3C, 0xFA, 0x29, 0x00, 0x04, 0x3A,
+	 0x09, 0x00, 0x0A, 0x64, 0x3C, 0xFA, 0x01, 0x64, 0x3A, 0xFA, 0x00, 0xF4, 0x00, 0x64, 0x1F, 0xFA,
+	 0x1E, 0xFA, 0x1E, 0x00, 0x02, 0x3A, 0x1E, 0x00, 0x64, 0x44, 0xAD, 0x83, 0xAC, 0x84, 0x02, 0x03,
+	 0x3C, 0xFC, 0x3D, 0xFC, 0x15, 0x03, 0x3A, 0xFA, 0xF8, 0x65, 0x52, 0x63, 0x64, 0x44, 0x01, 0x36,
+	 0x0D, 0x00, 0x12, 0xA3, 0x64, 0x40, 0x02, 0x2A, 0x02, 0x00, 0xC7, 0x83, 0xC7, 0x83, 0x64, 0x40,
+	 0x08, 0x2A, 0x01, 0x00, 0xC7, 0x83, 0x64, 0x40, 0x04, 0x26, 0xC7, 0x83, 0x39, 0xFC, 0x00, 0x64,
+	 0x2E, 0x58, 0xFF, 0xFF, 0x3B, 0xF0, 0x3A, 0xF2, 0x65, 0x46, 0x06, 0xF2, 0x40, 0x47, 0x1C, 0x18,
+	 0x32, 0x47, 0x07, 0xFA, 0x18, 0x7E, 0x81, 0x7F, 0x08, 0xFA, 0x01, 0x60, 0x01, 0x63, 0xB7, 0xF3,
+	 0x0A, 0xFC, 0x00, 0x7F, 0x09, 0xFA, 0x27, 0x40, 0x01, 0x2A, 0x0E, 0x00, 0x1F, 0xF8, 0x18, 0x64,
+	 0x0F, 0x60, 0x90, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x0A, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0x1E, 0xF0, 0x59, 0xF5, 0x3B, 0xF8, 0x65, 0x46, 0x27, 0x40, 0x02, 0x26, 0x02, 0x00, 0x00, 0xF4,
+	 0x13, 0x00, 0x6E, 0x61, 0xFF, 0x60, 0xFE, 0x64, 0x00, 0x60, 0x0E, 0x63, 0x58, 0xD1, 0x59, 0xD8,
+	 0xFD, 0x1F, 0x01, 0x60, 0xEE, 0x63, 0x00, 0xF4, 0x02, 0x61, 0x58, 0xD1, 0x59, 0xD8, 0x7E, 0x3A,
+	 0x02, 0x00, 0x00, 0xF4, 0x02, 0x61, 0xF9, 0x1F, 0x27, 0x40, 0x04, 0x26, 0x1A, 0x00, 0x46, 0x4B,
+	 0x0F, 0x60, 0x67, 0xF3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x0E, 0x03, 0x89, 0xF0, 0xEB, 0x60,
+	 0x58, 0x4D, 0x00, 0x78, 0xFF, 0xFF, 0x65, 0x44, 0xAC, 0x86, 0xFF, 0xFF, 0x08, 0x03, 0xEB, 0x60,
+	 0x58, 0x4D, 0x00, 0x78, 0xFF, 0xFF, 0x04, 0x00, 0x2B, 0x46, 0x82, 0xFC, 0x00, 0xF4, 0x82, 0xFC,
+	 0x00, 0xF4, 0x27, 0x40, 0x08, 0x26, 0x19, 0x00, 0x46, 0x4B, 0x0F, 0x60, 0x85, 0xF3, 0xFF, 0xFF,
+	 0x00, 0xA8, 0x60, 0x46, 0x0E, 0x03, 0x89, 0xF0, 0xEB, 0x60, 0x58, 0x4D, 0x00, 0x78, 0xFF, 0xFF,
+	 0x65, 0x44, 0xAC, 0x86, 0xFF, 0xFF, 0x08, 0x03, 0xEB, 0x60, 0x58, 0x4D, 0x00, 0x78, 0xFF, 0xFF,
+	 0x04, 0x00, 0x65, 0x46, 0x02, 0xFA, 0x00, 0xF4, 0x82, 0xFC, 0x01, 0x64, 0x2E, 0x58, 0xFF, 0xFF,
+	 0x01, 0x61, 0x02, 0x64, 0x7A, 0x63, 0x58, 0xD0, 0xAB, 0x46, 0xA0, 0xD8, 0xAB, 0x46, 0xFB, 0x1F,
+	 0xAB, 0x46, 0x00, 0xF4, 0xCD, 0x81, 0xAB, 0x46, 0x00, 0xF4, 0xF3, 0x02, 0x2D, 0x58, 0xFF, 0xFF,
+	 0x00, 0x60, 0x2A, 0x61, 0xB5, 0x60, 0x58, 0x4D, 0xA2, 0x78, 0xFF, 0xFF, 0x66, 0x44, 0x58, 0xFB,
+	 0x04, 0x64, 0x03, 0xFA, 0x67, 0x44, 0x2C, 0xFA, 0x2D, 0xFA, 0x2E, 0xFA, 0x32, 0xFA, 0x33, 0xFA,
+	 0x34, 0xFA, 0x12, 0x60, 0x80, 0x64, 0x87, 0xF1, 0x0E, 0xFA, 0x07, 0xF8, 0x00, 0x64, 0x3E, 0xFA,
+	 0x0A, 0x60, 0x07, 0xFB, 0x06, 0xA2, 0x10, 0x60, 0x5C, 0x64, 0xA2, 0xDB, 0x04, 0x64, 0x5A, 0xDB,
+	 0x06, 0x64, 0x5A, 0xDB, 0xED, 0x60, 0xD9, 0x64, 0x08, 0x60, 0x2D, 0xFB, 0x00, 0x64, 0x0A, 0x60,
+	 0x0D, 0xFB, 0x06, 0xA2, 0x10, 0x60, 0x60, 0x64, 0xA2, 0xDB, 0x08, 0x64, 0x5A, 0xDB, 0x06, 0x64,
+	 0x5A, 0xDB, 0xED, 0x60, 0xE2, 0x64, 0x08, 0x60, 0x2F, 0xFB, 0xED, 0x60, 0xBE, 0x64, 0x08, 0x60,
+	 0x28, 0xFB, 0x00, 0x60, 0x30, 0x64, 0x08, 0x60, 0x1C, 0xFB, 0xEB, 0x60, 0x58, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x2F, 0x58, 0xFF, 0xFF, 0xED, 0x60, 0x70, 0x78, 0xFF, 0xFF,
+	 0x58, 0xF5, 0xCB, 0xF1, 0x2F, 0xF8, 0xCC, 0xF1, 0x30, 0xF8, 0xCD, 0xF1, 0x31, 0xF8, 0xAB, 0xF1,
+	 0x19, 0xF8, 0x58, 0xF5, 0x40, 0x64, 0x2A, 0xFA, 0x64, 0xF3, 0x63, 0xFB, 0x08, 0x60, 0x1B, 0xF1,
+	 0x00, 0x60, 0x10, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x03, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x03, 0x00,
+	 0xEC, 0x60, 0xCB, 0x78, 0xFF, 0xFF, 0x15, 0x60, 0xC0, 0xF3, 0xEF, 0x60, 0x58, 0x4E, 0xAB, 0x78,
+	 0xFF, 0xFF, 0x15, 0x60, 0xC2, 0xFB, 0x15, 0x60, 0xBC, 0xF3, 0x3F, 0x40, 0x01, 0x27, 0x08, 0x00,
+	 0x0F, 0x60, 0xFF, 0x65, 0xA4, 0x84, 0xEE, 0x60, 0x58, 0x4E, 0x26, 0x78, 0xFF, 0xFF, 0x05, 0x00,
+	 0x0F, 0xB4, 0xEE, 0x60, 0x58, 0x4E, 0x26, 0x78, 0xFF, 0xFF, 0x58, 0xF5, 0x2D, 0x60, 0x94, 0x64,
+	 0x00, 0xF4, 0x40, 0x48, 0x28, 0x60, 0x4E, 0x64, 0x20, 0x40, 0x10, 0x27, 0x02, 0x00, 0x28, 0x60,
+	 0x2C, 0x64, 0x28, 0xDB, 0x04, 0x61, 0x00, 0x60, 0x00, 0x64, 0xE4, 0x60, 0x58, 0x4D, 0xA7, 0x78,
+	 0xFF, 0xFF, 0x58, 0xF5, 0x3F, 0xFC, 0x01, 0x64, 0x52, 0xF1, 0x0C, 0x60, 0x81, 0xFB, 0x64, 0xFB,
+	 0xA4, 0xD3, 0x04, 0x65, 0x51, 0xF3, 0x01, 0x18, 0x0C, 0x65, 0xF3, 0xB4, 0xB4, 0x84, 0x51, 0xFB,
+	 0x0D, 0x00, 0xED, 0x60, 0x70, 0x78, 0xFF, 0xFF, 0x51, 0xF1, 0x64, 0xF3, 0xFF, 0xFF, 0xF3, 0xA0,
+	 0x04, 0xA4, 0x01, 0x04, 0xF1, 0xA4, 0x10, 0x36, 0xF4, 0x01, 0x64, 0xFB, 0x64, 0xF3, 0x15, 0x60,
+	 0xC3, 0xF1, 0xCC, 0x84, 0x01, 0x61, 0x08, 0x24, 0x03, 0x00, 0xE1, 0x81, 0xCC, 0x84, 0xFB, 0x01,
+	 0xA1, 0x84, 0x51, 0xF1, 0xEA, 0x03, 0x0C, 0x60, 0x81, 0xFB, 0x9D, 0xFE, 0x3D, 0x05, 0xBA, 0xFE,
+	 0x10, 0x60, 0x36, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE, 0x0A, 0x04, 0x40, 0x60, 0x00, 0x64,
+	 0x08, 0x60, 0x1C, 0xFB, 0xEB, 0x60, 0xD0, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x10, 0x60, 0x36, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x64, 0xF1, 0x0F, 0x60, 0x9D, 0xF9, 0x08, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x20, 0x60, 0x00, 0x64, 0x08, 0x60, 0x1C, 0xFB, 0xEB, 0x60,
+	 0xF5, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0xBE, 0xFE, 0x08, 0x60, 0x11, 0xF1,
+	 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x18, 0x60, 0x07, 0xF1, 0xAD, 0x4F,
+	 0x00, 0x7F, 0xFA, 0xB4, 0x64, 0x41, 0x64, 0xF1, 0x02, 0xB1, 0x04, 0x65, 0x02, 0x02, 0x64, 0x40,
+	 0x01, 0x2B, 0x01, 0x65, 0xB4, 0x84, 0xA0, 0x5D, 0x10, 0x60, 0x36, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0xDE, 0xFE, 0x0A, 0x04, 0x40, 0x60, 0x00, 0x64, 0x08, 0x60, 0x1C, 0xFB, 0xEB, 0x60, 0xCD, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x64, 0xF1, 0x0F, 0x60, 0x9D, 0xF9, 0x0E, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x20, 0x60, 0x00, 0x64, 0x08, 0x60, 0x1C, 0xFB, 0xEC, 0x60,
+	 0x2D, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0xBE, 0xFE, 0x08, 0x60, 0x11, 0xF1,
+	 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x10, 0x60, 0x36, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0x58, 0xF5, 0x1E, 0x60, 0xD4, 0x64, 0x0F, 0x60, 0x90, 0xFB, 0x66, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x00, 0x64, 0x4F, 0xFB, 0x00, 0x60, 0x01, 0x64,
+	 0x08, 0x60, 0x1C, 0xFB, 0xEC, 0x60, 0x51, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0xC1, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x10, 0x60, 0x36, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xA5, 0xF1, 0x0A, 0x60, 0x09, 0xF9,
+	 0x14, 0x60, 0x0E, 0x64, 0x0F, 0x60, 0xA5, 0xFB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF,
+	 0xA6, 0xF1, 0x0A, 0x60, 0x0F, 0xF9, 0x1F, 0x60, 0x48, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0xFD, 0x1B,
+	 0x14, 0x60, 0x1A, 0x64, 0x0F, 0x60, 0xA5, 0xFB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF,
+	 0x00, 0x60, 0x08, 0x64, 0x08, 0x60, 0x1C, 0xFB, 0xEC, 0x60, 0x7A, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x4F, 0xF1, 0x10, 0x60, 0x36, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x64, 0x40,
+	 0xFF, 0x26, 0x0B, 0x00, 0x51, 0xF3, 0xFF, 0xFF, 0x80, 0xB0, 0xFF, 0xFF, 0x03, 0x03, 0xED, 0x60,
+	 0x6A, 0x78, 0xFF, 0xFF, 0xEB, 0x60, 0xB4, 0x78, 0xFF, 0xFF, 0x02, 0x0A, 0x00, 0x64, 0x4F, 0xFB,
+	 0xA7, 0xF1, 0x0A, 0x60, 0x0F, 0xF9, 0x00, 0x60, 0x0C, 0x64, 0x08, 0x60, 0x1C, 0xFB, 0xEC, 0x60,
+	 0xA5, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x14, 0x60, 0x1A, 0x64, 0x0F, 0x60, 0xA5, 0xFB, 0x02, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x1B, 0xF1, 0x00, 0x60,
+	 0x04, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x0B, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x14, 0x60, 0x1A, 0x64,
+	 0x0F, 0x60, 0xA5, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x13, 0x00, 0xFF, 0x60,
+	 0xF7, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x4F, 0xF3, 0xDE, 0x0A, 0x00, 0xA0, 0x00, 0x64, 0x02, 0x03,
+	 0x4F, 0xFB, 0xD9, 0x01, 0x14, 0x60, 0x0E, 0x64, 0x0F, 0x60, 0xA5, 0xFB, 0x03, 0x64, 0x4A, 0xDB,
+	 0xFF, 0xFF, 0x04, 0xFF, 0xB7, 0x01, 0x15, 0x60, 0xC1, 0xF3, 0xEF, 0x60, 0x58, 0x4E, 0xAB, 0x78,
+	 0xFF, 0xFF, 0x15, 0x60, 0xC2, 0xFB, 0x15, 0x60, 0xBD, 0xF3, 0x0F, 0x60, 0xFF, 0x65, 0xA4, 0x84,
+	 0xEE, 0x60, 0x58, 0x4E, 0x26, 0x78, 0xFF, 0xFF, 0x58, 0xF5, 0x2D, 0x60, 0x94, 0x64, 0x00, 0xF4,
+	 0x40, 0x48, 0x28, 0x60, 0x4E, 0x64, 0x20, 0x40, 0x10, 0x27, 0x02, 0x00, 0x28, 0x60, 0x2C, 0x64,
+	 0x28, 0xDB, 0x04, 0x61, 0x00, 0x60, 0x00, 0x64, 0xE4, 0x60, 0x58, 0x4D, 0xA7, 0x78, 0xFF, 0xFF,
+	 0x58, 0xF5, 0x3F, 0xFC, 0x51, 0xF3, 0x20, 0x40, 0x10, 0x23, 0x02, 0x00, 0x20, 0xBC, 0x04, 0x00,
+	 0x60, 0x40, 0x01, 0x22, 0x40, 0xBC, 0x04, 0xBC, 0x80, 0xBC, 0x51, 0xFB, 0x11, 0x60, 0x16, 0x64,
+	 0x08, 0x60, 0x46, 0xFB, 0x06, 0x64, 0x08, 0x60, 0x4D, 0xFB, 0x15, 0x60, 0xC6, 0xF3, 0xFF, 0xFF,
+	 0x07, 0xB4, 0xA2, 0xDB, 0x51, 0xF3, 0x08, 0x60, 0x46, 0xF1, 0x60, 0x40, 0x20, 0x26, 0x03, 0x00,
+	 0x01, 0x26, 0x32, 0x00, 0x45, 0x00, 0x08, 0x60, 0x4D, 0xF3, 0xFF, 0xFF, 0xDD, 0xA0, 0x01, 0xA4,
+	 0x57, 0x03, 0xA2, 0xDB, 0x2B, 0x60, 0x88, 0x61, 0xE0, 0xA0, 0xF0, 0xA0, 0x05, 0x05, 0x01, 0x05,
+	 0x05, 0x00, 0x02, 0xA1, 0xF0, 0xA4, 0x02, 0x00, 0x04, 0xA1, 0xE0, 0xA4, 0xA1, 0xD1, 0x01, 0x61,
+	 0xDC, 0x84, 0xCC, 0x84, 0xFF, 0xFF, 0x02, 0x03, 0xE1, 0x81, 0xFB, 0x01, 0xA1, 0x80, 0x10, 0x60,
+	 0x9A, 0x64, 0x01, 0x02, 0xE0, 0x01, 0xA0, 0xD3, 0x11, 0x60, 0x0E, 0x63, 0xFA, 0xA4, 0xCC, 0x84,
+	 0x08, 0xA3, 0xFD, 0x02, 0xB1, 0xF1, 0xA3, 0xD3, 0x01, 0x18, 0xD5, 0x18, 0xFE, 0xA3, 0xA3, 0xD3,
+	 0x64, 0xFB, 0xEB, 0x60, 0xCD, 0x78, 0xFF, 0xFF, 0x11, 0x60, 0xF4, 0x65, 0x64, 0x41, 0xA1, 0xD3,
+	 0xD5, 0x80, 0x00, 0xB8, 0x25, 0x07, 0x02, 0x02, 0x08, 0xA1, 0xF9, 0x01, 0x61, 0x44, 0x08, 0x60,
+	 0x46, 0xFB, 0x01, 0x64, 0xA1, 0xDB, 0x49, 0xD3, 0x64, 0xFB, 0xEB, 0x60, 0xCD, 0x78, 0xFF, 0xFF,
+	 0x11, 0x60, 0xF4, 0x65, 0x64, 0x41, 0xA1, 0xD3, 0xD5, 0x80, 0x04, 0xB0, 0x11, 0x07, 0x02, 0x02,
+	 0x08, 0xA1, 0xF9, 0x01, 0x61, 0x44, 0x08, 0x60, 0x46, 0xFB, 0x49, 0xD3, 0x64, 0xFB, 0xEB, 0x60,
+	 0xCD, 0x78, 0xFF, 0xFF, 0x08, 0x60, 0x46, 0xF3, 0xFF, 0xFF, 0x08, 0xA4, 0xA2, 0xDB, 0x9A, 0x01,
+	 0x14, 0x60, 0x0E, 0x64, 0x0F, 0x60, 0xA5, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF,
+	 0x51, 0xF3, 0xFF, 0xFF, 0xE3, 0xB4, 0x51, 0xFB, 0x0C, 0x60, 0x7F, 0xF3, 0xFF, 0xFF, 0xFE, 0xB4,
+	 0xA2, 0xDB, 0x10, 0x60, 0x36, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE, 0x0A, 0x04, 0x40, 0x60,
+	 0x00, 0x64, 0x08, 0x60, 0x1C, 0xFB, 0xED, 0x60, 0x81, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x63, 0xF1, 0x64, 0xF9, 0x0F, 0x60, 0x9D, 0xF9, 0x0E, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x2D, 0xFF, 0x20, 0x60, 0x00, 0x64, 0x08, 0x60, 0x1C, 0xFB, 0xED, 0x60, 0xA3, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0xBE, 0xFE, 0x08, 0x60, 0x11, 0xF1, 0x40, 0x60, 0x00, 0x64,
+	 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x08, 0x60, 0x11, 0xF1, 0x10, 0x60, 0x00, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x00, 0x60, 0x30, 0x64, 0x08, 0x60, 0x1C, 0xFB, 0xEB, 0x60, 0x58, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x2F, 0x58, 0xFF, 0xFF, 0x14, 0x60, 0x0E, 0x64,
+	 0x0F, 0x60, 0xA5, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x00, 0x64, 0x51, 0xFB,
+	 0x00, 0x64, 0x08, 0x60, 0x1B, 0xFB, 0x5A, 0xDB, 0xBE, 0xFE, 0x00, 0x60, 0x30, 0x64, 0x08, 0x60,
+	 0x1C, 0xFB, 0xEB, 0x60, 0x58, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x08, 0x60, 0x1B, 0xF1, 0x00, 0x60, 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x1B, 0xF1, 0x00, 0x60, 0x08, 0x64, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x31, 0x40, 0x20, 0x2A, 0x35, 0x00, 0x3F, 0xF2, 0x47, 0x65,
+	 0xC4, 0x84, 0xE8, 0x84, 0x23, 0xFA, 0xF1, 0x60, 0x02, 0x64, 0x24, 0xFA, 0x64, 0xF3, 0x01, 0x60,
+	 0xFF, 0x65, 0xA4, 0x84, 0x01, 0x23, 0x14, 0x00, 0x11, 0x60, 0x14, 0x61, 0x11, 0x60, 0xF4, 0x65,
+	 0xA1, 0xD1, 0xD5, 0x80, 0xD0, 0x80, 0x0B, 0x03, 0x02, 0x03, 0x08, 0xA1, 0xF9, 0x01, 0x04, 0xA1,
+	 0xA1, 0xD3, 0x01, 0x60, 0x00, 0x65, 0x60, 0x47, 0xFF, 0xB4, 0xB4, 0x84, 0x01, 0x00, 0x01, 0x64,
+	 0x00, 0xF4, 0x08, 0xFA, 0xFF, 0xFF, 0x26, 0x46, 0x1F, 0x60, 0x10, 0x64, 0x0F, 0x60, 0x90, 0xFB,
+	 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xFA, 0xFE, 0x00, 0x66,
+	 0x46, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x26, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x5F, 0xFB, 0xAC, 0x85,
+	 0x60, 0x41, 0x2E, 0x60, 0x22, 0x63, 0x16, 0x60, 0xC6, 0xFD, 0x16, 0x60, 0xCC, 0xFD, 0x16, 0x60,
+	 0xD6, 0xFD, 0x16, 0x60, 0xE0, 0xFD, 0x5C, 0x03, 0x61, 0x5C, 0x00, 0x63, 0xE9, 0x81, 0xFF, 0xFF,
+	 0x02, 0x24, 0xDF, 0x83, 0xFB, 0x02, 0x08, 0x64, 0x53, 0x90, 0x64, 0x41, 0x03, 0x04, 0x01, 0x60,
+	 0x08, 0x63, 0x0C, 0x00, 0x01, 0x60, 0x00, 0x63, 0x10, 0x64, 0xE9, 0x81, 0xFF, 0xFF, 0x02, 0x24,
+	 0xDF, 0x83, 0x08, 0x36, 0x03, 0x00, 0xCC, 0x84, 0xFF, 0xFF, 0xF7, 0x02, 0x15, 0x60, 0xEC, 0xFD,
+	 0x43, 0x48, 0x65, 0x41, 0x2B, 0x60, 0xDA, 0x63, 0x28, 0x44, 0xFF, 0xB5, 0x10, 0x60, 0x08, 0x64,
+	 0xE9, 0x81, 0x58, 0xD1, 0xFD, 0x04, 0xA3, 0xD9, 0x0C, 0x03, 0x58, 0xD1, 0xE9, 0x81, 0x40, 0x4A,
+	 0xFC, 0x04, 0xA3, 0xD1, 0x64, 0x47, 0xB0, 0x84, 0xBD, 0xDB, 0x65, 0x44, 0xC8, 0x85, 0x2A, 0x44,
+	 0xEF, 0x02, 0x28, 0x43, 0x08, 0x3A, 0x24, 0x00, 0x60, 0x45, 0x04, 0x64, 0x32, 0x60, 0x00, 0x63,
+	 0x41, 0x48, 0xE9, 0x81, 0xCC, 0x84, 0x02, 0x24, 0xDF, 0x83, 0xFB, 0x02, 0x63, 0x40, 0x00, 0x36,
+	 0x17, 0x00, 0x17, 0x60, 0x11, 0xFD, 0x2E, 0x60, 0x24, 0x63, 0x65, 0x44, 0x28, 0x41, 0xE9, 0x81,
+	 0x58, 0xD1, 0xFD, 0x04, 0xA3, 0xD9, 0x15, 0x03, 0x58, 0xD1, 0xE9, 0x81, 0x60, 0x45, 0xFC, 0x04,
+	 0xA3, 0xD1, 0x64, 0x47, 0xB0, 0x84, 0xBD, 0xDB, 0x00, 0xB9, 0x65, 0x44, 0xF0, 0x02, 0x09, 0x00,
+	 0x67, 0x43, 0x16, 0x60, 0xC6, 0xFD, 0x16, 0x60, 0xCC, 0xFD, 0x16, 0x60, 0xD6, 0xFD, 0x16, 0x60,
+	 0xE0, 0xFD, 0x20, 0x40, 0x10, 0x27, 0x0D, 0x00, 0x2B, 0x60, 0xE2, 0x61, 0x15, 0x60, 0xEC, 0xF3,
+	 0xA1, 0xDB, 0xFF, 0xB4, 0xCC, 0x84, 0xA8, 0x83, 0x2B, 0x60, 0xD8, 0x64, 0x58, 0xD1, 0x59, 0xD9,
+	 0xFD, 0x1F, 0x2B, 0x60, 0xE4, 0x63, 0x15, 0x60, 0xBE, 0xF3, 0x08, 0x61, 0x60, 0xFE, 0xA3, 0xD1,
+	 0xFF, 0xFF, 0x20, 0xFE, 0x00, 0xA8, 0xE8, 0x84, 0x0F, 0x03, 0x60, 0xFE, 0x02, 0x28, 0xF6, 0x01,
+	 0x80, 0x62, 0xB2, 0x9C, 0xBD, 0xD9, 0x62, 0xF9, 0xCD, 0x81, 0x00, 0x36, 0x01, 0x00, 0xEE, 0x01,
+	 0x2E, 0x60, 0x24, 0x63, 0x08, 0x61, 0xEA, 0x01, 0x2E, 0x58, 0xFF, 0xFF, 0x2B, 0x60, 0x7C, 0x63,
+	 0x65, 0x40, 0xFF, 0x36, 0x02, 0xA3, 0xA3, 0xD3, 0xFF, 0xFF, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84,
+	 0xE8, 0x84, 0x40, 0x26, 0x7F, 0xB4, 0x20, 0x26, 0x3F, 0xB4, 0x60, 0x45, 0x80, 0x63, 0xEF, 0x60,
+	 0x58, 0x4D, 0x33, 0x78, 0xFF, 0xFF, 0x15, 0x60, 0xDF, 0xFB, 0x40, 0x63, 0xEF, 0x60, 0x58, 0x4D,
+	 0x33, 0x78, 0xFF, 0xFF, 0x15, 0x60, 0xE0, 0xFB, 0x20, 0x63, 0xEF, 0x60, 0x58, 0x4D, 0x33, 0x78,
+	 0xFF, 0xFF, 0x15, 0x60, 0xE1, 0xFB, 0x10, 0x63, 0xEF, 0x60, 0x58, 0x4D, 0x33, 0x78, 0xFF, 0xFF,
+	 0x15, 0x60, 0xE2, 0xFB, 0x08, 0x63, 0xEF, 0x60, 0x58, 0x4D, 0x33, 0x78, 0xFF, 0xFF, 0x15, 0x60,
+	 0xE3, 0xFB, 0x04, 0x63, 0xEF, 0x60, 0x58, 0x4D, 0x33, 0x78, 0xFF, 0xFF, 0x15, 0x60, 0xE4, 0xFB,
+	 0x02, 0x63, 0xEF, 0x60, 0x58, 0x4D, 0x33, 0x78, 0xFF, 0xFF, 0x15, 0x60, 0xE5, 0xFB, 0x01, 0x63,
+	 0xEF, 0x60, 0x58, 0x4D, 0x33, 0x78, 0xFF, 0xFF, 0x15, 0x60, 0xE6, 0xFB, 0x2E, 0x58, 0xFF, 0xFF,
+	 0x15, 0x60, 0xBE, 0xF3, 0xFF, 0xFF, 0x0F, 0xB4, 0x60, 0x45, 0x08, 0x63, 0xEF, 0x60, 0x58, 0x4D,
+	 0x5E, 0x78, 0xFF, 0xFF, 0x15, 0x60, 0xE7, 0xFB, 0x04, 0x63, 0xEF, 0x60, 0x58, 0x4D, 0x5E, 0x78,
+	 0xFF, 0xFF, 0x15, 0x60, 0xE8, 0xFB, 0x02, 0x63, 0xEF, 0x60, 0x58, 0x4D, 0x5E, 0x78, 0xFF, 0xFF,
+	 0x15, 0x60, 0xE9, 0xFB, 0x01, 0x63, 0xEF, 0x60, 0x58, 0x4D, 0x5E, 0x78, 0xFF, 0xFF, 0x15, 0x60,
+	 0xEA, 0xFB, 0x2E, 0x58, 0xFF, 0xFF, 0x63, 0x5C, 0xA7, 0x84, 0xEB, 0x83, 0x14, 0x02, 0x01, 0x03,
+	 0xFB, 0x01, 0x64, 0x44, 0x01, 0x36, 0x0B, 0x64, 0x02, 0x36, 0x0B, 0x64, 0x04, 0x36, 0x0A, 0x64,
+	 0x08, 0x36, 0x0A, 0x64, 0x10, 0x36, 0x09, 0x64, 0x20, 0x36, 0x09, 0x64, 0x40, 0x36, 0x09, 0x64,
+	 0x80, 0x36, 0x09, 0x64, 0x11, 0x00, 0x60, 0x40, 0x01, 0x36, 0x0B, 0x64, 0x02, 0x36, 0x0F, 0x64,
+	 0x04, 0x36, 0x0A, 0x64, 0x08, 0x36, 0x0E, 0x64, 0x10, 0x36, 0x09, 0x64, 0x20, 0x36, 0x0D, 0x64,
+	 0x40, 0x36, 0x08, 0x64, 0x80, 0x36, 0x0C, 0x64, 0x2D, 0x58, 0xFF, 0xFF, 0x63, 0x5C, 0xA7, 0x84,
+	 0xEB, 0x83, 0x0C, 0x02, 0x01, 0x03, 0xFB, 0x01, 0x64, 0x44, 0x01, 0x36, 0x0A, 0x64, 0x02, 0x36,
+	 0x14, 0x64, 0x04, 0x36, 0x37, 0x64, 0x08, 0x36, 0x6E, 0x64, 0x09, 0x00, 0x60, 0x40, 0x01, 0x36,
+	 0x0A, 0x64, 0x02, 0x36, 0x14, 0x64, 0x04, 0x36, 0x37, 0x64, 0x08, 0x36, 0x6E, 0x64, 0x2D, 0x58,
+	 0xFF, 0xFF, 0x60, 0xFE, 0x81, 0xA1, 0x7F, 0xA1, 0x02, 0x06, 0x00, 0xF4, 0x03, 0x61, 0x5D, 0xD2,
+	 0xCF, 0x83, 0xD4, 0x80, 0x25, 0x03, 0x16, 0x03, 0xCF, 0x83, 0x61, 0x44, 0x80, 0xA0, 0x20, 0x03,
+	 0x02, 0x02, 0x00, 0xF4, 0x03, 0x61, 0x5D, 0xD2, 0xCF, 0x83, 0x81, 0xA1, 0x19, 0x03, 0x05, 0x07,
+	 0x7F, 0xA1, 0xCC, 0x84, 0xDD, 0x81, 0xE6, 0x03, 0xF7, 0x01, 0x00, 0xF4, 0x00, 0xB8, 0x04, 0x61,
+	 0xE6, 0x03, 0xF2, 0x01, 0x2C, 0x43, 0x5D, 0xD0, 0xDE, 0xD9, 0x64, 0x44, 0x5D, 0xD0, 0xDE, 0xD9,
+	 0xCC, 0x84, 0x81, 0xA1, 0x05, 0x03, 0x7F, 0xA1, 0xF9, 0x04, 0x00, 0xF4, 0x03, 0x61, 0xF6, 0x01,
+	 0x20, 0xFE, 0x2E, 0x58, 0xFF, 0xFF, 0x01, 0x3A, 0x02, 0x00, 0x16, 0x64, 0x2B, 0x00, 0x02, 0x3A,
+	 0x02, 0x00, 0x14, 0x64, 0x27, 0x00, 0x04, 0x3A, 0x02, 0x00, 0x12, 0x64, 0x23, 0x00, 0x08, 0x3A,
+	 0x02, 0x00, 0x10, 0x64, 0x1F, 0x00, 0x10, 0x3A, 0x02, 0x00, 0x0E, 0x64, 0x1B, 0x00, 0x20, 0x3A,
+	 0x02, 0x00, 0x0C, 0x64, 0x17, 0x00, 0x40, 0x3A, 0x02, 0x00, 0x0A, 0x64, 0x13, 0x00, 0x80, 0x3A,
+	 0x02, 0x00, 0x08, 0x64, 0x0F, 0x00, 0x01, 0x3B, 0x02, 0x00, 0x06, 0x64, 0x0B, 0x00, 0x02, 0x3B,
+	 0x02, 0x00, 0x04, 0x64, 0x07, 0x00, 0x04, 0x3B, 0x02, 0x00, 0x02, 0x64, 0x03, 0x00, 0x08, 0x3B,
+	 0xFF, 0x01, 0x00, 0x64, 0x2E, 0x58, 0xFF, 0xFF, 0x27, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x36, 0x3A,
+	 0x02, 0x00, 0x00, 0x61, 0x2C, 0x00, 0x30, 0x3A, 0x02, 0x00, 0x02, 0x61, 0x28, 0x00, 0x24, 0x3A,
+	 0x02, 0x00, 0x04, 0x61, 0x24, 0x00, 0x18, 0x3A, 0x02, 0x00, 0x06, 0x61, 0x20, 0x00, 0x12, 0x3A,
+	 0x02, 0x00, 0x08, 0x61, 0x1C, 0x00, 0x0C, 0x3A, 0x02, 0x00, 0x0A, 0x61, 0x18, 0x00, 0x09, 0x3A,
+	 0x02, 0x00, 0x0C, 0x61, 0x14, 0x00, 0x06, 0x3A, 0x02, 0x00, 0x0E, 0x61, 0x10, 0x00, 0x6E, 0x3A,
+	 0x02, 0x00, 0x10, 0x61, 0x0C, 0x00, 0x37, 0x3A, 0x02, 0x00, 0x12, 0x61, 0x08, 0x00, 0x14, 0x3A,
+	 0x02, 0x00, 0x14, 0x61, 0x04, 0x00, 0x0A, 0x3A, 0xFF, 0xFF, 0x16, 0x61, 0x00, 0x00, 0x65, 0x40,
+	 0x01, 0x3A, 0x13, 0x00, 0x66, 0x45, 0x2B, 0x46, 0x92, 0xFA, 0x65, 0x46, 0x26, 0xF2, 0xFF, 0xFF,
+	 0x60, 0x41, 0x00, 0x7F, 0x60, 0x45, 0x61, 0x47, 0x00, 0x7F, 0xD4, 0x84, 0x66, 0x41, 0x2B, 0x46,
+	 0x0E, 0xF2, 0x60, 0x45, 0x65, 0x5E, 0x0E, 0xFA, 0x61, 0x46, 0x2E, 0x58, 0xFF, 0xFF, 0xCD, 0x81,
+	 0x7F, 0xB4, 0x02, 0x3A, 0x02, 0x00, 0x01, 0x64, 0x2E, 0x00, 0x04, 0x3A, 0x02, 0x00, 0x02, 0x64,
+	 0x2A, 0x00, 0x0B, 0x3A, 0x02, 0x00, 0x04, 0x64, 0x26, 0x00, 0x16, 0x3A, 0x02, 0x00, 0x08, 0x64,
+	 0x22, 0x00, 0x0C, 0x3A, 0x02, 0x00, 0x10, 0x64, 0x1E, 0x00, 0x12, 0x3A, 0x02, 0x00, 0x20, 0x64,
+	 0x1A, 0x00, 0x18, 0x3A, 0x02, 0x00, 0x40, 0x64, 0x16, 0x00, 0x24, 0x3A, 0x02, 0x00, 0x80, 0x64,
+	 0x12, 0x00, 0x30, 0x3A, 0x02, 0x00, 0x01, 0x7F, 0x0E, 0x00, 0x48, 0x3A, 0x02, 0x00, 0x02, 0x7F,
+	 0x0A, 0x00, 0x60, 0x3A, 0x02, 0x00, 0x04, 0x7F, 0x06, 0x00, 0x6C, 0x3A, 0x02, 0x00, 0x08, 0x7F,
+	 0x02, 0x00, 0x00, 0x64, 0x00, 0x00, 0x20, 0xFE, 0x2A, 0x45, 0x34, 0x8A, 0x60, 0xFE, 0x61, 0x40,
+	 0x00, 0x36, 0x02, 0x00, 0xBD, 0xD3, 0xC3, 0x01, 0x2E, 0x58, 0xFF, 0xFF, 0x53, 0xFB, 0x54, 0xFB,
+	 0x00, 0x60, 0x0C, 0x63, 0x14, 0x60, 0xEC, 0x62, 0x00, 0x64, 0x5A, 0xDB, 0xFE, 0x1F, 0x02, 0x64,
+	 0x0A, 0x60, 0x78, 0xFB, 0x2E, 0x58, 0xFF, 0xFF, 0x0A, 0x60, 0x7A, 0xF3, 0x00, 0x63, 0xF0, 0xA0,
+	 0x01, 0xA4, 0x03, 0x03, 0xA2, 0xDB, 0x2E, 0x58, 0xFF, 0xFF, 0xA2, 0xDD, 0x0A, 0x60, 0x7B, 0xF1,
+	 0xA2, 0xDD, 0x5A, 0xD3, 0xA2, 0xDD, 0xC0, 0x81, 0x61, 0x44, 0x02, 0x24, 0xFF, 0xFF, 0xE9, 0x81,
+	 0xE9, 0x81, 0xE9, 0x81, 0xE9, 0x81, 0x5A, 0xD3, 0xE9, 0x81, 0xE8, 0x83, 0xEB, 0x83, 0xEB, 0x83,
+	 0xEB, 0x83, 0xEB, 0x85, 0xD4, 0x85, 0xC5, 0x83, 0xA2, 0xDD, 0x63, 0x47, 0x00, 0x7F, 0x0A, 0x60,
+	 0x77, 0xFB, 0x2E, 0x58, 0xFF, 0xFF, 0x7F, 0x67, 0x01, 0x61, 0x23, 0x58, 0xFF, 0xFF, 0xB1, 0xFE,
+	 0x05, 0x05, 0xB0, 0xFE, 0x06, 0x05, 0xB2, 0xFE, 0xB3, 0xFE, 0x21, 0x00, 0xF7, 0x60, 0x38, 0x78,
+	 0xFF, 0xFF, 0x28, 0xF3, 0x29, 0xF1, 0x40, 0x44, 0x44, 0x45, 0x2A, 0xF1, 0x2B, 0xF1, 0x44, 0x46,
+	 0x44, 0x47, 0x3F, 0xB4, 0xE0, 0x85, 0x19, 0x60, 0x06, 0x64, 0x44, 0xD7, 0x58, 0x43, 0xFF, 0xFF,
+	 0x60, 0x45, 0x0A, 0x60, 0x7E, 0xF3, 0x61, 0x43, 0x04, 0xB4, 0x24, 0x44, 0x02, 0x03, 0x13, 0xFF,
+	 0x06, 0x00, 0x3F, 0xB4, 0xB4, 0x84, 0xFF, 0x27, 0x05, 0xFD, 0x04, 0xFB, 0x10, 0x75, 0xA1, 0xFF,
+	 0xFF, 0xFF, 0x86, 0x3E, 0xB4, 0xFE, 0x09, 0x05, 0xB5, 0xFE, 0x02, 0x24, 0x7F, 0xF7, 0xFF, 0xFF,
+	 0xFF, 0xFF, 0xB7, 0xFE, 0x05, 0x05, 0xB6, 0xFE, 0xF2, 0x01, 0xF7, 0x60, 0x73, 0x78, 0xFF, 0xFF,
+	 0x36, 0x44, 0x00, 0x7F, 0xEE, 0xA0, 0x60, 0x45, 0x05, 0x05, 0x19, 0x60, 0x98, 0x64, 0x44, 0xD7,
+	 0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0x01, 0xE3, 0x01, 0x7F, 0x60, 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80,
+	 0x7F, 0x67, 0x02, 0x61, 0x10, 0x02, 0x10, 0x64, 0x40, 0x40, 0x02, 0x64, 0x40, 0x50, 0x61, 0xFF,
+	 0x3F, 0x40, 0x40, 0x26, 0x04, 0x00, 0x10, 0xE0, 0x46, 0x60, 0x09, 0xE0, 0x00, 0x00, 0x27, 0xF1,
+	 0x00, 0x66, 0x20, 0x78, 0x42, 0xFE, 0x23, 0x58, 0xFF, 0xFF, 0x7F, 0x60, 0xC0, 0x64, 0x24, 0x45,
+	 0xA4, 0x80, 0x7F, 0x67, 0x02, 0x61, 0x19, 0x02, 0x0A, 0x60, 0x7E, 0xF3, 0x07, 0x7C, 0x20, 0xB5,
+	 0x0C, 0xB5, 0x04, 0x03, 0x03, 0x02, 0xBC, 0xF9, 0x00, 0x67, 0x0F, 0x00, 0x00, 0x61, 0x41, 0x56,
+	 0xC7, 0xFE, 0xB5, 0x01, 0x36, 0x47, 0xFF, 0x23, 0x04, 0x00, 0x00, 0x7F, 0x60, 0x41, 0x7F, 0x67,
+	 0x04, 0x00, 0x20, 0x44, 0x80, 0xBC, 0x40, 0x40, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x7F, 0x60,
+	 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80, 0x7F, 0x67, 0x02, 0x61, 0x31, 0x02, 0x0A, 0x60, 0x7E, 0xF3,
+	 0x01, 0x7C, 0x20, 0xB5, 0x0C, 0xB5, 0x03, 0x03, 0x02, 0x02, 0xBC, 0xF9, 0xFF, 0xFF, 0x02, 0x61,
+	 0x41, 0x56, 0xC7, 0xFE, 0xF0, 0x60, 0xC7, 0x78, 0xFF, 0xFF, 0x7D, 0xF1, 0x20, 0x44, 0x64, 0x40,
+	 0xFF, 0x26, 0x1C, 0x00, 0x7F, 0xB4, 0x40, 0x40, 0x5C, 0x5E, 0x82, 0xFF, 0x26, 0x44, 0xFD, 0xB4,
+	 0x40, 0x46, 0x5C, 0x41, 0x87, 0xFF, 0x62, 0xFF, 0x0F, 0x60, 0x85, 0xF3, 0xFF, 0xFF, 0x00, 0xA8,
+	 0x60, 0x46, 0x04, 0x03, 0x09, 0xF2, 0x8F, 0xFC, 0xAC, 0x86, 0xFB, 0x01, 0xD3, 0xF3, 0xFF, 0xFF,
+	 0xFE, 0xB4, 0xD3, 0xFB, 0x06, 0x64, 0x0F, 0x60, 0x9F, 0xFB, 0x2D, 0xFF, 0x00, 0x67, 0x23, 0x58,
+	 0xFF, 0xFF, 0x25, 0x46, 0x01, 0xF2, 0x08, 0xF0, 0x60, 0x47, 0x03, 0xB4, 0x03, 0xAC, 0x7F, 0x67,
+	 0x03, 0x61, 0x08, 0x02, 0x1F, 0x60, 0x26, 0x64, 0x40, 0x4B, 0xF6, 0x60, 0x58, 0x4D, 0xB3, 0x78,
+	 0xFF, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x24, 0x40, 0x01, 0x2B, 0x49, 0x00, 0x25, 0x44,
+	 0x1F, 0xB4, 0xE0, 0x85, 0xF1, 0x60, 0x76, 0x64, 0xC4, 0x98, 0xFF, 0xFF, 0xC0, 0xFE, 0x3D, 0x00,
+	 0xC1, 0xFE, 0x3B, 0x00, 0xC2, 0xFE, 0x39, 0x00, 0xC3, 0xFE, 0x37, 0x00, 0xC4, 0xFE, 0x35, 0x00,
+	 0xC5, 0xFE, 0x33, 0x00, 0xC6, 0xFE, 0x31, 0x00, 0xC7, 0xFE, 0x2F, 0x00, 0xC8, 0xFE, 0x2D, 0x00,
+	 0xC9, 0xFE, 0x2B, 0x00, 0xCA, 0xFE, 0x29, 0x00, 0xCB, 0xFE, 0x27, 0x00, 0xCC, 0xFE, 0x25, 0x00,
+	 0xCD, 0xFE, 0x23, 0x00, 0xCE, 0xFE, 0x21, 0x00, 0xCF, 0xFE, 0x1F, 0x00, 0xD0, 0xFE, 0x1D, 0x00,
+	 0xD1, 0xFE, 0x1B, 0x00, 0xD2, 0xFE, 0x19, 0x00, 0xD3, 0xFE, 0x17, 0x00, 0xD4, 0xFE, 0x15, 0x00,
+	 0xD5, 0xFE, 0x13, 0x00, 0xD6, 0xFE, 0x11, 0x00, 0xD7, 0xFE, 0x0F, 0x00, 0xD8, 0xFE, 0x0D, 0x00,
+	 0xD9, 0xFE, 0x0B, 0x00, 0xDA, 0xFE, 0x09, 0x00, 0xDB, 0xFE, 0x07, 0x00, 0xDC, 0xFE, 0x05, 0x00,
+	 0xDD, 0xFE, 0x03, 0x00, 0xDE, 0xFE, 0x01, 0x00, 0xDF, 0xFE, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x00, 0x64, 0x9F, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x9E, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x9D, 0xFE,
+	 0xF0, 0x84, 0xFF, 0xFF, 0x9C, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x9B, 0xFE, 0xF0, 0x84, 0xFF, 0xFF,
+	 0x9A, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x99, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x98, 0xFE, 0xF0, 0x84,
+	 0xFF, 0xFF, 0x97, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x96, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x95, 0xFE,
+	 0xF0, 0x84, 0xFF, 0xFF, 0x94, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x93, 0xFE, 0xF0, 0x84, 0xFF, 0xFF,
+	 0x92, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x91, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x90, 0xFE, 0xF0, 0x84,
+	 0x06, 0xFB, 0x8F, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x8E, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x8D, 0xFE,
+	 0xF0, 0x84, 0xFF, 0xFF, 0x8C, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x8B, 0xFE, 0xF0, 0x84, 0xFF, 0xFF,
+	 0x8A, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x89, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x88, 0xFE, 0xF0, 0x84,
+	 0xFF, 0xFF, 0x87, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x86, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x85, 0xFE,
+	 0xF0, 0x84, 0xFF, 0xFF, 0x84, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x83, 0xFE, 0xF0, 0x84, 0xFF, 0xFF,
+	 0x82, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x81, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x80, 0xFE, 0xF0, 0x84,
+	 0x05, 0xFB, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x5C, 0x5C, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x24, 0x40, 0x01, 0x27, 0x55, 0x00, 0x05, 0x60, 0x00, 0x63, 0x05, 0xFD, 0x30, 0x44, 0xBD, 0xDB,
+	 0x31, 0x44, 0xBD, 0xDB, 0x32, 0x44, 0xBD, 0xDB, 0x33, 0x44, 0xBD, 0xDB, 0x34, 0x44, 0xBD, 0xDB,
+	 0x35, 0x44, 0xBD, 0xDB, 0x36, 0x44, 0xBD, 0xDB, 0x37, 0x44, 0xBD, 0xDB, 0x38, 0x44, 0xBD, 0xDB,
+	 0x39, 0x44, 0xBD, 0xDB, 0x3A, 0x44, 0xBD, 0xDB, 0x3B, 0x44, 0xBD, 0xDB, 0x3C, 0x44, 0xBD, 0xDB,
+	 0x3D, 0x44, 0xBD, 0xDB, 0x3E, 0x44, 0xBD, 0xDB, 0x3F, 0x44, 0xBD, 0xDB, 0x02, 0x61, 0x61, 0x44,
+	 0x02, 0x36, 0x82, 0xFF, 0x03, 0x36, 0x83, 0xFF, 0x04, 0x36, 0x84, 0xFF, 0x05, 0x36, 0x85, 0xFF,
+	 0x06, 0x36, 0x86, 0xFF, 0x07, 0x36, 0x87, 0xFF, 0x20, 0x44, 0xBD, 0xDB, 0x21, 0x44, 0xBD, 0xDB,
+	 0x22, 0x44, 0xBD, 0xDB, 0x23, 0x44, 0xBD, 0xDB, 0x24, 0x44, 0xBD, 0xDB, 0x25, 0x44, 0xBD, 0xDB,
+	 0x26, 0x44, 0xBD, 0xDB, 0x27, 0x44, 0xBD, 0xDB, 0x28, 0x44, 0xBD, 0xDB, 0x29, 0x44, 0xBD, 0xDB,
+	 0x2A, 0x44, 0xBD, 0xDB, 0x2B, 0x44, 0xBD, 0xDB, 0x2C, 0x44, 0xBD, 0xDB, 0x2D, 0x44, 0xBD, 0xDB,
+	 0x2E, 0x44, 0xBD, 0xDB, 0x2F, 0x44, 0xBD, 0xDB, 0xDD, 0x81, 0x08, 0x3A, 0xD0, 0x01, 0x54, 0x00,
+	 0x27, 0x40, 0x10, 0x26, 0x30, 0x00, 0x26, 0x44, 0x01, 0x36, 0x2D, 0x00, 0x02, 0x36, 0x82, 0xFF,
+	 0x03, 0x36, 0x83, 0xFF, 0x04, 0x36, 0x84, 0xFF, 0x05, 0x36, 0x85, 0xFF, 0x06, 0x36, 0x86, 0xFF,
+	 0x25, 0x44, 0x00, 0x36, 0x44, 0x40, 0x01, 0x36, 0x44, 0x41, 0x02, 0x36, 0x44, 0x42, 0x03, 0x36,
+	 0x44, 0x43, 0x04, 0x36, 0x44, 0x44, 0x05, 0x36, 0x44, 0x45, 0x06, 0x36, 0x44, 0x46, 0x07, 0x36,
+	 0x44, 0x47, 0x08, 0x36, 0x44, 0x48, 0x09, 0x36, 0x44, 0x49, 0x0A, 0x36, 0x44, 0x4A, 0x0B, 0x36,
+	 0x44, 0x4B, 0x0C, 0x36, 0x44, 0x4C, 0x0D, 0x36, 0x44, 0x4D, 0x0E, 0x36, 0x44, 0x4E, 0x0F, 0x36,
+	 0x44, 0x4F, 0x87, 0xFF, 0x21, 0x00, 0x25, 0x44, 0x10, 0x36, 0x44, 0x50, 0x11, 0x36, 0x44, 0x51,
+	 0x12, 0x36, 0x44, 0x52, 0x13, 0x36, 0x44, 0x53, 0x14, 0x36, 0x44, 0x54, 0x15, 0x36, 0x44, 0x55,
+	 0x16, 0x36, 0x44, 0x56, 0x17, 0x36, 0x44, 0x57, 0x18, 0x36, 0x44, 0x58, 0x19, 0x36, 0x44, 0x59,
+	 0x1A, 0x36, 0x44, 0x5A, 0x1B, 0x36, 0x44, 0x5B, 0x1C, 0x36, 0x44, 0x5C, 0x1D, 0x36, 0x44, 0x5D,
+	 0x1E, 0x36, 0x44, 0x5E, 0x1F, 0x36, 0x44, 0x5F, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x25, 0x46,
+	 0xB5, 0x60, 0x58, 0x4F, 0x4B, 0x78, 0xFF, 0xFF, 0x03, 0x61, 0x7F, 0x67, 0x0A, 0x02, 0x00, 0xF0,
+	 0x04, 0x64, 0x0F, 0x60, 0x93, 0xFB, 0x5A, 0xD9, 0x0A, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x40, 0x60, 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80, 0x7F, 0x67,
+	 0x02, 0x61, 0x12, 0x02, 0x14, 0x64, 0x0F, 0x60, 0x9F, 0xFB, 0x00, 0x60, 0x50, 0x63, 0x5A, 0xDD,
+	 0xF2, 0x60, 0xF7, 0x64, 0x7F, 0xFB, 0x2D, 0xFF, 0xF0, 0x60, 0xC7, 0x78, 0xFF, 0xFF, 0x2A, 0xF3,
+	 0x05, 0xFB, 0x2B, 0xF3, 0x06, 0xFB, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x40, 0x60, 0xC0, 0x64,
+	 0x24, 0x45, 0xA4, 0x80, 0x7F, 0x67, 0x02, 0x61, 0x0E, 0x02, 0x16, 0x64, 0x0F, 0x60, 0x9F, 0xFB,
+	 0x00, 0x60, 0x50, 0x63, 0x5A, 0xDD, 0xF3, 0x60, 0x12, 0x64, 0x7F, 0xFB, 0x2D, 0xFF, 0xF0, 0x60,
+	 0xC7, 0x78, 0xFF, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x7F, 0x60, 0xC0, 0x64, 0x24, 0x45,
+	 0xA4, 0x80, 0x02, 0x61, 0x35, 0x02, 0x25, 0x45, 0xF1, 0x60, 0x02, 0x64, 0xD4, 0x80, 0xFF, 0xFF,
+	 0x34, 0x03, 0xF1, 0x60, 0x00, 0x64, 0xD4, 0x80, 0xFF, 0xFF, 0x01, 0x03, 0x28, 0x00, 0x15, 0x60,
+	 0xC3, 0xF1, 0x99, 0xF3, 0x19, 0x60, 0x00, 0x61, 0xA0, 0x84, 0xA1, 0xDB, 0x25, 0x45, 0x1E, 0x60,
+	 0x96, 0x63, 0x01, 0x61, 0xBD, 0xD3, 0xBD, 0xD1, 0xD4, 0x80, 0xBD, 0xD3, 0xBD, 0xD5, 0xCD, 0x81,
+	 0x02, 0x03, 0x15, 0x03, 0xF7, 0x01, 0xA2, 0xFF, 0xA6, 0xD3, 0x40, 0x4C, 0x00, 0xA8, 0x67, 0x43,
+	 0x0C, 0x02, 0xA2, 0xDD, 0x42, 0x48, 0x64, 0x41, 0xB5, 0x60, 0x58, 0x4D, 0xA2, 0x78, 0xFF, 0xFF,
+	 0x66, 0x44, 0x28, 0xDB, 0x02, 0x03, 0x2C, 0x58, 0xA3, 0xFF, 0x0C, 0x61, 0x03, 0x00, 0x04, 0x61,
+	 0x7F, 0x67, 0x01, 0x00, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0xF1, 0x60, 0x02, 0x64, 0xD4, 0x80,
+	 0x7F, 0x67, 0x06, 0x63, 0xF8, 0x02, 0x31, 0x40, 0x21, 0x2A, 0xF5, 0x01, 0x01, 0x64, 0x0C, 0x60,
+	 0x82, 0xFB, 0xFF, 0xFF, 0xC4, 0xFE, 0xEE, 0x01, 0xC6, 0xFE, 0xEC, 0x01, 0x7E, 0x60, 0xC0, 0x64,
+	 0x24, 0x45, 0xA4, 0x80, 0x02, 0x61, 0x3F, 0x02, 0x25, 0x45, 0xF8, 0x2B, 0x3B, 0x00, 0x2E, 0xF5,
+	 0x67, 0x44, 0xD4, 0x80, 0x19, 0x60, 0xAA, 0x63, 0x39, 0x03, 0x7E, 0x61, 0x24, 0x44, 0x01, 0x27,
+	 0x29, 0x00, 0xA3, 0xFC, 0xA4, 0xF8, 0xBD, 0xD3, 0xA3, 0xD1, 0xD4, 0x80, 0xCD, 0x81, 0x08, 0x24,
+	 0x64, 0x58, 0x08, 0xA3, 0xF8, 0x02, 0x08, 0x60, 0x00, 0x63, 0xBD, 0xD3, 0xA3, 0xD1, 0xFE, 0xA0,
+	 0xFA, 0x60, 0x00, 0x64, 0xD0, 0x80, 0x14, 0x02, 0x13, 0x02, 0x04, 0xA3, 0xBE, 0xD3, 0xBD, 0xD1,
+	 0x0F, 0x18, 0xD4, 0x80, 0x0D, 0x18, 0x03, 0x03, 0xC3, 0x83, 0xC3, 0x83, 0xF7, 0x01, 0x64, 0x41,
+	 0xDD, 0x81, 0xE1, 0x81, 0xCB, 0x83, 0x46, 0x65, 0xF8, 0x60, 0x58, 0x4F, 0x7A, 0x78, 0xFF, 0xFF,
+	 0x00, 0x67, 0x0A, 0x00, 0xBD, 0xD3, 0xBE, 0xD1, 0xD4, 0x80, 0xCD, 0x81, 0x08, 0x24, 0x64, 0x58,
+	 0x08, 0xA3, 0xF8, 0x02, 0x04, 0x61, 0x7F, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x0F, 0x64, 0x23, 0xFA,
+	 0x67, 0x44, 0x24, 0xFA, 0x62, 0x41, 0x3E, 0x60, 0x00, 0x65, 0x1A, 0x63, 0xF7, 0x60, 0x8C, 0x64,
+	 0x65, 0x46, 0x58, 0xD0, 0x2E, 0xF5, 0x59, 0xD8, 0xFB, 0x1F, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x4B, 0xD3, 0xFF, 0xFF, 0x60, 0x41, 0xE8, 0x84, 0xDC, 0x84, 0x23, 0xFA, 0xBF, 0xD1, 0x4A, 0x65,
+	 0x64, 0x43, 0xF8, 0x60, 0x58, 0x4F, 0x7A, 0x78, 0xFF, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x25, 0xF2, 0xFF, 0xFF, 0xE0, 0xA0, 0x20, 0x64, 0x01, 0x06, 0x25, 0xFA, 0x23, 0xF2, 0xDF, 0xD1,
+	 0xCC, 0x84, 0xE0, 0x85, 0x0B, 0x06, 0xBF, 0xD1, 0x64, 0x41, 0xD5, 0x80, 0x64, 0x43, 0x01, 0x06,
+	 0x65, 0x41, 0x4A, 0x65, 0xF4, 0x60, 0x58, 0x4F, 0xBD, 0x78, 0xFF, 0xFF, 0x00, 0x67, 0x23, 0x58,
+	 0xFF, 0xFF, 0xBC, 0xF3, 0x02, 0x63, 0x23, 0xFC, 0x07, 0xB4, 0x25, 0xFA, 0x00, 0x67, 0x23, 0x58,
+	 0xFF, 0xFF, 0x4B, 0xD3, 0xBF, 0xD3, 0x60, 0x41, 0xC9, 0x83, 0xE9, 0x81, 0xDD, 0x81, 0xA3, 0xFA,
+	 0xE0, 0x81, 0x3C, 0x60, 0x00, 0x67, 0x02, 0x24, 0x02, 0xA4, 0x60, 0x47, 0x40, 0x4B, 0xC9, 0x81,
+	 0x4A, 0x65, 0xAB, 0x46, 0x59, 0xD0, 0xAB, 0x46, 0xA5, 0xD8, 0xDA, 0x85, 0x80, 0x3A, 0x02, 0x00,
+	 0x00, 0xF4, 0x04, 0x65, 0xF6, 0x1F, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0xFC, 0xA3, 0xA3, 0xD1,
+	 0x4C, 0x65, 0xA4, 0xD3, 0xDA, 0x83, 0x60, 0x47, 0x25, 0xFA, 0x00, 0x7E, 0x60, 0x47, 0x01, 0x26,
+	 0xDC, 0x84, 0x60, 0x41, 0xE8, 0x84, 0xD8, 0x84, 0x23, 0xFA, 0xAB, 0x01, 0xFC, 0xA3, 0xA3, 0xD1,
+	 0x4C, 0x65, 0xA4, 0xD3, 0xDA, 0x83, 0x00, 0x7F, 0x25, 0xFA, 0x60, 0x41, 0x01, 0x26, 0xDD, 0x81,
+	 0xE9, 0x84, 0xD8, 0x84, 0x23, 0xFA, 0x9D, 0x01, 0x23, 0xF2, 0x25, 0xF2, 0x02, 0xA8, 0xF8, 0xA0,
+	 0x0F, 0x02, 0xEC, 0xA0, 0x0D, 0x04, 0x0C, 0x07, 0x15, 0x60, 0xD2, 0xF1, 0xFF, 0xFF, 0xD0, 0x80,
+	 0xFF, 0xFF, 0x04, 0x07, 0x15, 0x60, 0xD2, 0xFB, 0x15, 0x60, 0xD6, 0xFB, 0x13, 0x60, 0x5B, 0xFB,
+	 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x23, 0xF2, 0x14, 0x60, 0xEE, 0x65, 0x60, 0x41, 0x14, 0x60,
+	 0x8A, 0x63, 0xA3, 0xDB, 0xFF, 0xA1, 0x48, 0x64, 0x58, 0xD0, 0x7E, 0xA8, 0x5B, 0xD9, 0x02, 0x02,
+	 0x00, 0xF4, 0x02, 0x64, 0xFF, 0xA1, 0xD7, 0x80, 0x02, 0x03, 0x01, 0x03, 0xF5, 0x01, 0x2E, 0xF5,
+	 0x00, 0x60, 0x2F, 0x65, 0x25, 0xF2, 0x00, 0x63, 0xCC, 0x84, 0x03, 0xA3, 0xFD, 0x05, 0x4A, 0x64,
+	 0xD7, 0x80, 0x14, 0x60, 0x26, 0x61, 0x18, 0x05, 0xA1, 0xDD, 0xE3, 0x83, 0xFE, 0xA3, 0x58, 0xD0,
+	 0x7E, 0xA8, 0x59, 0xD9, 0x02, 0x02, 0x00, 0xF4, 0x02, 0x64, 0xF9, 0x1F, 0x00, 0x63, 0x59, 0xDD,
+	 0x2E, 0xF5, 0x25, 0xF0, 0x0A, 0x60, 0x13, 0xF3, 0xD3, 0x80, 0x01, 0xB0, 0x04, 0x03, 0x01, 0xA4,
+	 0x03, 0x03, 0xA2, 0xDB, 0x01, 0x00, 0xA2, 0xDD, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x14, 0x60,
+	 0x8A, 0x61, 0xA1, 0xD3, 0x23, 0xFA, 0xE0, 0x83, 0x4A, 0x65, 0x04, 0x02, 0x02, 0x63, 0x23, 0xFC,
+	 0xA5, 0xFC, 0x09, 0x00, 0xDB, 0x83, 0x59, 0xD1, 0xA5, 0xD8, 0xDA, 0x85, 0x80, 0x3A, 0x02, 0x00,
+	 0x00, 0xF4, 0x04, 0x65, 0xF8, 0x1F, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x0A, 0x60, 0x13, 0xF3,
+	 0x00, 0x61, 0x02, 0xA4, 0xFE, 0xA0, 0x23, 0xFA, 0x1B, 0x03, 0xFA, 0xA4, 0xFD, 0xA4, 0x01, 0xA1,
+	 0xFD, 0x07, 0x61, 0x43, 0x23, 0xF2, 0x25, 0xFC, 0xE0, 0x83, 0x02, 0xA3, 0x14, 0x60, 0x26, 0x61,
+	 0x00, 0x60, 0x4A, 0x64, 0x59, 0xD1, 0x58, 0xD8, 0x7E, 0x3A, 0x02, 0x00, 0x00, 0xF4, 0x02, 0x64,
+	 0xF9, 0x1F, 0x25, 0xF2, 0x23, 0xF2, 0x01, 0xB0, 0xCC, 0x84, 0x04, 0x02, 0x23, 0xFA, 0x02, 0x00,
+	 0x00, 0x64, 0x25, 0xFA, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x41, 0x4B, 0x65, 0x42, 0x80, 0x64,
+	 0xD4, 0x85, 0x2B, 0x41, 0x00, 0xA1, 0x55, 0x8B, 0x0D, 0x03, 0x02, 0x04, 0x65, 0x41, 0x02, 0x00,
+	 0x00, 0x64, 0x40, 0x4B, 0xCA, 0x84, 0x58, 0xD0, 0xC9, 0x81, 0xBD, 0xD9, 0xFC, 0x02, 0x00, 0xF4,
+	 0x04, 0x65, 0xEC, 0x01, 0x2F, 0x58, 0xFF, 0xFF, 0xFC, 0xA3, 0xA3, 0xD3, 0x02, 0x7C, 0xA0, 0xD3,
+	 0x23, 0xF8, 0xDC, 0x84, 0x25, 0xFA, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x02, 0x64, 0x23, 0xFA,
+	 0x01, 0x64, 0x9D, 0xFE, 0x02, 0x28, 0x02, 0x64, 0x25, 0xFA, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x02, 0x7C, 0x23, 0xF8, 0x01, 0x64, 0x25, 0xFA, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0xFC, 0xA3,
+	 0xA3, 0xD1, 0x02, 0x64, 0x23, 0xFA, 0x64, 0x44, 0x7C, 0x5F, 0x60, 0x45, 0x64, 0x47, 0x7C, 0x5F,
+	 0x88, 0xF1, 0x66, 0x41, 0xC0, 0x86, 0xA5, 0xD2, 0x61, 0x46, 0x25, 0xFA, 0x00, 0x67, 0x23, 0x58,
+	 0xFF, 0xFF, 0x02, 0x64, 0x23, 0xFA, 0x88, 0xFF, 0x75, 0x44, 0x8D, 0xFF, 0xE8, 0x87, 0xE8, 0x84,
+	 0xE8, 0x84, 0x03, 0xB4, 0x25, 0xFA, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x05, 0x64, 0x23, 0xFA,
+	 0x52, 0x63, 0x96, 0xF3, 0x4B, 0xDA, 0x95, 0xF3, 0x4B, 0xDA, 0x94, 0xF3, 0x4B, 0xDA, 0x60, 0x41,
+	 0x88, 0xFF, 0x72, 0x5C, 0x89, 0xFF, 0x4A, 0xD8, 0xA2, 0x48, 0x20, 0x23, 0x0E, 0x00, 0x64, 0x40,
+	 0x80, 0x27, 0x15, 0x00, 0xDC, 0x84, 0xBD, 0xDA, 0xBD, 0xD2, 0x11, 0x04, 0xDC, 0x84, 0xA2, 0xDA,
+	 0xA3, 0xD2, 0x0D, 0x04, 0xDC, 0x84, 0xA3, 0xDA, 0x0A, 0x00, 0x52, 0x63, 0x96, 0xF3, 0x4B, 0xDA,
+	 0x95, 0xF3, 0x4B, 0xDA, 0x94, 0xF3, 0x4B, 0xDA, 0x54, 0x90, 0x4C, 0x63, 0xE0, 0x02, 0x00, 0x67,
+	 0x23, 0x58, 0xFF, 0xFF, 0x25, 0xF0, 0x23, 0xF2, 0x15, 0x60, 0xC9, 0xF9, 0x02, 0xA8, 0x64, 0x44,
+	 0x1F, 0x02, 0x3F, 0x40, 0x02, 0x2B, 0x16, 0x00, 0x00, 0x37, 0x14, 0x00, 0x01, 0x3B, 0x18, 0x00,
+	 0x11, 0x60, 0xF9, 0x65, 0x11, 0x60, 0x19, 0x63, 0xFF, 0xB7, 0x60, 0x5C, 0xA3, 0xD3, 0x08, 0xA3,
+	 0x00, 0x7E, 0xD0, 0x80, 0xD7, 0x80, 0x03, 0x03, 0xF9, 0x02, 0x7F, 0x67, 0x0A, 0x00, 0xF4, 0xA3,
+	 0xA3, 0xD1, 0x04, 0x00, 0x00, 0xBC, 0xF2, 0xA4, 0x03, 0x03, 0x02, 0x07, 0x13, 0x60, 0x52, 0xF9,
+	 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x20, 0x63, 0x27, 0x60, 0x06, 0x61, 0x48, 0x64, 0x58, 0xD0,
+	 0x59, 0xD9, 0xFD, 0x1F, 0x25, 0xF0, 0x20, 0x64, 0xD0, 0x81, 0xFF, 0xFF, 0x02, 0x07, 0x25, 0xFA,
+	 0x0F, 0x00, 0x27, 0x60, 0x0A, 0x63, 0xC3, 0x83, 0x01, 0x2A, 0x06, 0x00, 0xCF, 0x83, 0xA3, 0xD3,
+	 0xCD, 0x81, 0x00, 0x7F, 0xBD, 0xDB, 0x04, 0x03, 0x00, 0x64, 0xC9, 0x81, 0xBD, 0xDB, 0xFD, 0x02,
+	 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x23, 0xF2, 0x25, 0xF0, 0x01, 0x60, 0x6E, 0x63, 0x7F, 0x67,
+	 0x3A, 0x18, 0xA3, 0xD9, 0x26, 0xF0, 0x7F, 0x67, 0x36, 0x18, 0x5B, 0xD9, 0x13, 0x60, 0x0A, 0xF3,
+	 0x25, 0xF0, 0x60, 0x40, 0x03, 0x3A, 0x2E, 0x00, 0x86, 0xF3, 0x87, 0xF3, 0x60, 0x43, 0xE3, 0x83,
+	 0x60, 0x46, 0x0F, 0xF8, 0x30, 0x61, 0x94, 0xFA, 0x01, 0x61, 0x91, 0xFA, 0x16, 0x64, 0x12, 0xFA,
+	 0x60, 0x40, 0x10, 0x36, 0x05, 0x00, 0x12, 0x36, 0x08, 0x00, 0x0C, 0x36, 0x0B, 0x00, 0x0F, 0x00,
+	 0x40, 0x61, 0xA1, 0x80, 0x0A, 0x64, 0x11, 0x02, 0xF3, 0x01, 0x10, 0x61, 0xA1, 0x80, 0x0E, 0x64,
+	 0x0C, 0x02, 0xEE, 0x01, 0x08, 0x61, 0xA1, 0x80, 0x10, 0x64, 0x07, 0x02, 0xE9, 0x01, 0xE1, 0x81,
+	 0xA1, 0x80, 0x05, 0x05, 0xC8, 0x84, 0x01, 0x02, 0xE3, 0x01, 0x12, 0xFA, 0x91, 0xFA, 0x66, 0x44,
+	 0x02, 0xA6, 0xD7, 0x1F, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0xFC, 0xA3, 0xA5, 0xF0, 0xA3, 0xD1,
+	 0xFF, 0xFF, 0x64, 0x5E, 0x00, 0x7F, 0x60, 0x41, 0x64, 0x47, 0x7C, 0x5F, 0x88, 0xF1, 0x66, 0x43,
+	 0xC0, 0x86, 0x65, 0x44, 0xA1, 0xDA, 0x63, 0x46, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0xFC, 0xA3,
+	 0xA3, 0xD1, 0xFF, 0xFF, 0x64, 0x5E, 0x00, 0x7F, 0x60, 0x45, 0x64, 0x47, 0x7C, 0x5F, 0x88, 0xF1,
+	 0x66, 0x41, 0xC0, 0x86, 0x65, 0x44, 0xA0, 0xD2, 0x61, 0x46, 0x25, 0xFA, 0x02, 0x64, 0x23, 0xFA,
+	 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x25, 0xF2, 0x15, 0x60, 0xC8, 0xFB, 0xFF, 0xFF, 0x00, 0x67,
+	 0x23, 0x58, 0xFF, 0xFF, 0x23, 0xF2, 0x25, 0xF0, 0x02, 0xA8, 0x00, 0x67, 0x02, 0x02, 0x2D, 0xF9,
+	 0x2C, 0xF9, 0x23, 0x58, 0xFF, 0xFF, 0x23, 0xF2, 0x25, 0xF2, 0x02, 0xA8, 0x00, 0xA8, 0x0A, 0x02,
+	 0x07, 0x03, 0xD0, 0xA0, 0x30, 0x65, 0x03, 0x04, 0xA7, 0xA0, 0x59, 0x65, 0x01, 0x06, 0x65, 0x44,
+	 0x13, 0x60, 0x51, 0xFB, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x25, 0xF2, 0x15, 0x60, 0xCF, 0xFB,
+	 0xFF, 0xFF, 0x08, 0x2A, 0x25, 0x00, 0x15, 0x60, 0xDD, 0xF3, 0xFF, 0xFF, 0xE9, 0xB4, 0x60, 0x44,
+	 0x15, 0x60, 0xCF, 0xF1, 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x26, 0x02, 0xBC, 0x64, 0x40, 0x02, 0x2A,
+	 0x04, 0xBC, 0x64, 0x40, 0x04, 0x26, 0x08, 0x00, 0x15, 0x60, 0xDD, 0xFB, 0x13, 0x64, 0xAD, 0xFB,
+	 0x01, 0x60, 0x67, 0x64, 0x37, 0xFB, 0x0C, 0x00, 0x10, 0xBC, 0x15, 0x60, 0xDD, 0xFB, 0x08, 0x64,
+	 0xAD, 0xFB, 0x82, 0xF3, 0x01, 0x60, 0x67, 0x7C, 0x60, 0x40, 0x01, 0x27, 0x5B, 0x7C, 0x37, 0xF9,
+	 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x25, 0xF2, 0x15, 0x60, 0xD0, 0xFB, 0x00, 0x67, 0x23, 0x58,
+	 0xFF, 0xFF, 0x25, 0xF2, 0x15, 0x60, 0xD1, 0xFB, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x25, 0xF2,
+	 0x15, 0x60, 0xEB, 0xFB, 0xFF, 0xFF, 0x0F, 0x22, 0x41, 0x75, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x04, 0x61, 0x06, 0x00, 0x01, 0x64, 0x01, 0x00, 0x00, 0x64, 0x18, 0x60, 0x13, 0xFB, 0x06, 0x61,
+	 0x41, 0x56, 0xC7, 0xFE, 0xF0, 0x60, 0xC7, 0x78, 0xFF, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x78, 0x60, 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80, 0x7F, 0x67, 0x02, 0x61, 0x10, 0x02, 0x08, 0x61,
+	 0x41, 0x56, 0xC7, 0xFE, 0xF0, 0x60, 0xC7, 0x78, 0xFF, 0xFF, 0x36, 0x47, 0xFF, 0x23, 0x04, 0x00,
+	 0x00, 0x7F, 0x60, 0x41, 0x7F, 0x67, 0x03, 0x00, 0x04, 0x7C, 0xBC, 0xF9, 0x00, 0x67, 0x23, 0x58,
+	 0xFF, 0xFF, 0x78, 0x60, 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80, 0x7F, 0x67, 0x02, 0x61, 0x10, 0x02,
+	 0x0A, 0x61, 0x41, 0x56, 0xC7, 0xFE, 0xF0, 0x60, 0xC7, 0x78, 0xFF, 0xFF, 0x36, 0x47, 0xFF, 0x23,
+	 0x04, 0x00, 0x00, 0x7F, 0x60, 0x41, 0x7F, 0x67, 0x03, 0x00, 0x01, 0x7C, 0xBC, 0xF9, 0x00, 0x67,
+	 0x23, 0x58, 0xFF, 0xFF, 0x02, 0x63, 0x64, 0xF3, 0x23, 0xFC, 0x60, 0x40, 0x01, 0x23, 0x17, 0x00,
+	 0x01, 0x60, 0xFF, 0x65, 0xA4, 0x84, 0x11, 0x60, 0x14, 0x61, 0x11, 0x60, 0xF4, 0x65, 0xA1, 0xD1,
+	 0xD5, 0x80, 0xD0, 0x80, 0x0B, 0x03, 0x02, 0x03, 0x08, 0xA1, 0xF9, 0x01, 0x04, 0xA1, 0xA1, 0xD3,
+	 0x01, 0x60, 0x00, 0x65, 0x60, 0x47, 0xFF, 0xB4, 0xB4, 0x84, 0x01, 0x00, 0xFF, 0x64, 0x25, 0xFA,
+	 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0xA2, 0xFF, 0x46, 0x45, 0x02, 0xF0, 0x09, 0x60, 0x08, 0x64,
+	 0xD0, 0x80, 0x00, 0xF4, 0x01, 0xF2, 0x66, 0x5C, 0x25, 0x46, 0x56, 0x02, 0x70, 0x27, 0x54, 0x00,
+	 0x12, 0x64, 0x03, 0xFA, 0x04, 0xF8, 0x0E, 0xF2, 0x87, 0xFC, 0x8D, 0xFC, 0x8E, 0xFC, 0xDA, 0x82,
+	 0x16, 0x61, 0x00, 0x63, 0xC9, 0x81, 0x5A, 0xDC, 0xFD, 0x02, 0x60, 0x40, 0xF0, 0x3B, 0x16, 0x00,
+	 0x32, 0x44, 0x8E, 0xF3, 0x01, 0xB0, 0xF6, 0xA0, 0x08, 0x24, 0x2C, 0x05, 0xDC, 0x83, 0xF0, 0x67,
+	 0x0E, 0xFA, 0x1F, 0x60, 0x0A, 0x64, 0x2B, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB,
+	 0x8E, 0xFD, 0x2B, 0xFF, 0xFE, 0x64, 0x3B, 0x42, 0x4A, 0xDB, 0x4F, 0x00, 0x8F, 0xF3, 0x09, 0x65,
+	 0xD4, 0x80, 0xDC, 0x83, 0x17, 0x05, 0x8F, 0xFD, 0x98, 0xFE, 0x04, 0x04, 0x00, 0x7F, 0x08, 0x7E,
+	 0x0E, 0xFA, 0x3B, 0xFF, 0x1E, 0x60, 0xFE, 0x64, 0x2B, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0x0E, 0xF2, 0x2B, 0xFF, 0x60, 0x40, 0x08, 0x26, 0xF7, 0xFE, 0xFD, 0x64, 0x3B, 0x42,
+	 0x4A, 0xDB, 0x32, 0x00, 0x8B, 0xF3, 0xFF, 0xFF, 0xD8, 0xA0, 0xFF, 0xFF, 0x0D, 0x04, 0x1F, 0x60,
+	 0x16, 0x64, 0x2B, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0xFC, 0x64, 0x3B, 0x42, 0x4A, 0xDB, 0x21, 0x00, 0x46, 0x45, 0x00, 0x64, 0x2B, 0xDB, 0x25, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xA2, 0xFF, 0x00, 0xF4, 0x01, 0xF0,
+	 0x0A, 0x18, 0x70, 0x67, 0xA0, 0x80, 0xF0, 0x67, 0x06, 0x03, 0xC0, 0x84, 0x01, 0xFA, 0x25, 0x46,
+	 0x25, 0x44, 0x80, 0xFC, 0x05, 0xFA, 0xB6, 0x60, 0x58, 0x4E, 0x72, 0x78, 0xFF, 0xFF, 0xD4, 0xFE,
+	 0xA3, 0xFF, 0xFF, 0x64, 0x3B, 0x42, 0x4A, 0xDB, 0xD4, 0xFE, 0xA3, 0xFF, 0x2D, 0x58, 0xFF, 0xFF,
+	 0x1F, 0x60, 0x04, 0x64, 0x40, 0x47, 0x58, 0x4F, 0x0D, 0x00, 0x1E, 0x60, 0xF8, 0x64, 0x40, 0x47,
+	 0x58, 0x4F, 0x18, 0x00, 0x1F, 0x60, 0x10, 0x64, 0x40, 0x47, 0x58, 0x4F, 0x03, 0x00, 0xF0, 0x60,
+	 0xC7, 0x78, 0xFF, 0xFF, 0x27, 0xD5, 0x0E, 0xF2, 0x0B, 0x18, 0x60, 0x40, 0x01, 0x2A, 0x08, 0x00,
+	 0x1F, 0x60, 0x26, 0x64, 0x40, 0x4B, 0xF6, 0x60, 0x58, 0x4D, 0xB3, 0x78, 0xFF, 0xFF, 0xF2, 0x01,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x27, 0xD5, 0x0E, 0xF2, 0x14, 0x18, 0x60, 0x40, 0x01, 0x2A, 0x11, 0x00,
+	 0x02, 0xF0, 0x09, 0x60, 0x08, 0x64, 0xD0, 0x80, 0xA2, 0xFF, 0x8F, 0xF3, 0x02, 0x02, 0xCC, 0x84,
+	 0x8F, 0xFB, 0x1F, 0x60, 0x26, 0x64, 0x40, 0x4B, 0xF6, 0x60, 0x58, 0x4D, 0xB3, 0x78, 0xFF, 0xFF,
+	 0xE9, 0x01, 0x2F, 0x58, 0xFF, 0xFF, 0xFB, 0x64, 0x3A, 0x42, 0x4A, 0xDB, 0xA2, 0xFF, 0x92, 0xF3,
+	 0x8E, 0xF3, 0xCC, 0x80, 0xFA, 0xA0, 0x01, 0x14, 0x1D, 0x05, 0xB5, 0x60, 0x58, 0x4D, 0x77, 0x78,
+	 0xFF, 0xFF, 0xA2, 0xFF, 0x17, 0x03, 0xF0, 0x67, 0x0E, 0xFA, 0x1F, 0x60, 0x0A, 0x64, 0x0F, 0x60,
+	 0x93, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xF6, 0x64,
+	 0x3A, 0x42, 0x4A, 0xDB, 0x92, 0xF3, 0x8E, 0xF3, 0xCC, 0x83, 0xDC, 0x84, 0x01, 0x15, 0x92, 0xFD,
+	 0x8E, 0xFB, 0xD4, 0xFE, 0x91, 0xF3, 0x8F, 0xF3, 0x00, 0xA8, 0x90, 0xF1, 0x03, 0x02, 0xD0, 0x80,
+	 0xFF, 0xFF, 0x26, 0x05, 0xB5, 0x60, 0x58, 0x4D, 0x77, 0x78, 0xFF, 0xFF, 0xA2, 0xFF, 0x20, 0x03,
+	 0x00, 0x63, 0x91, 0xF3, 0x0E, 0xFC, 0xCC, 0x84, 0xFF, 0x3A, 0x91, 0xFB, 0x98, 0xFE, 0x03, 0x04,
+	 0x08, 0xBB, 0x0E, 0xFC, 0x3B, 0xFF, 0x1E, 0x60, 0xFE, 0x64, 0x0F, 0x60, 0x93, 0xFB, 0x66, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xF7, 0x64, 0x3A, 0x42, 0x4A, 0xDB,
+	 0x8F, 0xF3, 0x0E, 0xF2, 0xDC, 0x83, 0x08, 0xB0, 0x8F, 0xFD, 0x08, 0x28, 0xF7, 0xFE, 0xD4, 0xFE,
+	 0xA3, 0xFF, 0xF0, 0x60, 0xC7, 0x78, 0xFF, 0xFF, 0xB9, 0xFE, 0x13, 0xFF, 0x24, 0x40, 0x80, 0x2B,
+	 0x0B, 0x00, 0xA2, 0xFF, 0x25, 0x46, 0x09, 0xF4, 0x0E, 0xF2, 0x05, 0x18, 0x08, 0xBC, 0x0E, 0xFA,
+	 0xFF, 0xFF, 0xF7, 0xFE, 0x01, 0x00, 0xD8, 0xFE, 0xA3, 0xFF, 0x25, 0x46, 0x3E, 0xF2, 0x00, 0xF4,
+	 0x08, 0xF0, 0x25, 0x46, 0x06, 0xB4, 0xFF, 0x7F, 0x10, 0xBC, 0x06, 0x26, 0xFD, 0x7F, 0x0E, 0xFA,
+	 0x3E, 0xF2, 0x3F, 0xF2, 0x60, 0x41, 0x08, 0x2A, 0x64, 0x47, 0x3F, 0xFA, 0x60, 0x45, 0x13, 0x60,
+	 0x2D, 0xF3, 0xA3, 0xFC, 0xAB, 0xFC, 0x91, 0xFC, 0xD4, 0x80, 0x38, 0x60, 0xC1, 0x65, 0xA5, 0x80,
+	 0x01, 0x04, 0x07, 0x03, 0x23, 0xF0, 0x08, 0x64, 0xB0, 0x84, 0xA2, 0xDA, 0xF8, 0x60, 0x57, 0x78,
+	 0xFF, 0xFF, 0xFB, 0x60, 0x58, 0x4F, 0x75, 0x78, 0xFF, 0xFF, 0x0B, 0x04, 0x23, 0xF0, 0x04, 0x64,
+	 0xB0, 0x84, 0xA2, 0xDA, 0x25, 0x60, 0xF4, 0x64, 0xE5, 0x60, 0x78, 0x41, 0xC7, 0x78, 0x97, 0xF1,
+	 0x46, 0x00, 0x3E, 0xF0, 0x88, 0xF1, 0x64, 0x47, 0x07, 0xB4, 0x07, 0x36, 0x3B, 0x00, 0x04, 0x03,
+	 0xCC, 0x84, 0xE0, 0x84, 0xC0, 0x83, 0x2D, 0x00, 0x2C, 0xF2, 0x87, 0xF1, 0x01, 0xB0, 0x64, 0x43,
+	 0x35, 0x02, 0x2E, 0xF2, 0x15, 0x60, 0x02, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3,
+	 0x66, 0x41, 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46, 0x2E, 0xF0, 0x63, 0x46,
+	 0xD0, 0x80, 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46, 0x2D, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2,
+	 0x06, 0x02, 0x61, 0x46, 0x2C, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4,
+	 0xFF, 0xFF, 0x63, 0x46, 0xE8, 0x1B, 0x87, 0xF3, 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0x01, 0x03,
+	 0x09, 0x00, 0x66, 0x45, 0x63, 0x46, 0x06, 0xF0, 0x65, 0x46, 0x64, 0x44, 0x0C, 0x26, 0x02, 0x00,
+	 0x02, 0x26, 0x04, 0x00, 0x23, 0xF0, 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDA, 0x07, 0xFC, 0x23, 0xF2,
+	 0xFF, 0xFF, 0x0F, 0x1B, 0x1E, 0x60, 0xE0, 0x64, 0x0F, 0x60, 0x93, 0xFB, 0x66, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x0E, 0xF2, 0xC8, 0xFE, 0x10, 0xAC, 0x0E, 0xFA,
+	 0x0E, 0x00, 0x1E, 0x60, 0xF2, 0x64, 0x0F, 0x60, 0x93, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x0E, 0xF2, 0xCE, 0xFE, 0x10, 0xAC, 0x0E, 0xFA, 0xF0, 0x60,
+	 0xC7, 0x78, 0xFF, 0xFF, 0xCB, 0x84, 0xC9, 0x83, 0xFF, 0xFF, 0x08, 0x04, 0x58, 0xD1, 0xA5, 0xD8,
+	 0xDA, 0x85, 0x80, 0x3A, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0xF8, 0x1F, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x25, 0xF0, 0x14, 0x60, 0x15, 0xF9, 0x11, 0x00, 0x0D, 0x60, 0x00, 0x62, 0x40, 0x63, 0x5A, 0xDF,
+	 0xFE, 0x1F, 0x04, 0x65, 0x0D, 0x60, 0x00, 0x61, 0x48, 0x64, 0x3E, 0x63, 0x7C, 0xA8, 0x58, 0xD0,
+	 0x59, 0xD9, 0x02, 0x02, 0x00, 0xF4, 0x02, 0x64, 0xF9, 0x1F, 0x14, 0x60, 0x15, 0xF1, 0x0C, 0x60,
+	 0xDC, 0x65, 0x02, 0xFE, 0x64, 0x44, 0xF8, 0x84, 0xF8, 0x84, 0xF8, 0x87, 0x60, 0x41, 0x64, 0x44,
+	 0xE0, 0x84, 0xE0, 0x84, 0xC4, 0x84, 0x3E, 0xFB, 0x60, 0x42, 0x61, 0x44, 0x03, 0xA2, 0x60, 0xFE,
+	 0xA2, 0xDB, 0x20, 0xFE, 0x64, 0x44, 0x0D, 0x60, 0x02, 0x65, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84,
+	 0xE0, 0x84, 0xC4, 0x84, 0x40, 0xFB, 0xFF, 0xFF, 0x00, 0x67, 0x00, 0x61, 0x23, 0x58, 0xFF, 0xFF,
+	 0x5C, 0x41, 0x25, 0xF2, 0xFF, 0xFF, 0x40, 0x42, 0x80, 0x2B, 0x04, 0x00, 0xFF, 0xB4, 0x40, 0x42,
+	 0x01, 0x64, 0x40, 0x41, 0x87, 0xF3, 0x46, 0x4B, 0x86, 0xF3, 0x60, 0x46, 0xE0, 0x83, 0xAB, 0x46,
+	 0x26, 0xF0, 0xAB, 0x46, 0x59, 0xF8, 0xAB, 0x46, 0x27, 0xF0, 0xAB, 0x46, 0x5A, 0xF8, 0xAB, 0x46,
+	 0x28, 0xF0, 0xAB, 0x46, 0x5B, 0xF8, 0x66, 0x44, 0x02, 0xA6, 0xF1, 0x1F, 0x87, 0xF3, 0xFF, 0xFF,
+	 0x60, 0x46, 0xAB, 0x46, 0x0C, 0x60, 0x3A, 0x65, 0x22, 0x44, 0xFF, 0xB4, 0xE0, 0x84, 0xE0, 0x84,
+	 0xE0, 0x84, 0xE0, 0x84, 0xC4, 0x81, 0xC9, 0x81, 0x52, 0x64, 0x0E, 0x63, 0x58, 0xD0, 0x59, 0xD9,
+	 0xFD, 0x1F, 0x21, 0x44, 0x01, 0x2A, 0x08, 0x00, 0xAB, 0x46, 0xF0, 0xA1, 0x76, 0x64, 0x0E, 0x63,
+	 0x59, 0xD1, 0x58, 0xD8, 0xFD, 0x1F, 0xAB, 0x46, 0x22, 0x44, 0xFF, 0xB4, 0xE0, 0x84, 0xE0, 0x84,
+	 0xE0, 0x84, 0x0C, 0x60, 0x9C, 0x65, 0xC4, 0x81, 0x60, 0x45, 0xC9, 0x81, 0x62, 0x64, 0x06, 0x63,
+	 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0x21, 0x44, 0x01, 0x2A, 0x08, 0x00, 0xAB, 0x46, 0xF8, 0xA1,
+	 0xB6, 0x64, 0x06, 0x63, 0x59, 0xD1, 0x58, 0xD8, 0xFD, 0x1F, 0xAB, 0x46, 0x65, 0x44, 0x0C, 0x60,
+	 0xBC, 0x65, 0xC4, 0x81, 0xC9, 0x81, 0x6A, 0x64, 0x06, 0x63, 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F,
+	 0x22, 0x44, 0xFF, 0xB4, 0xE0, 0x84, 0xE0, 0x85, 0xC4, 0x84, 0x0C, 0x60, 0x82, 0x65, 0xC4, 0x81,
+	 0x72, 0x64, 0x04, 0x63, 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0xAB, 0x46, 0x21, 0x44, 0x01, 0x2A,
+	 0x06, 0x00, 0xFA, 0xA1, 0x90, 0x64, 0x04, 0x63, 0x59, 0xD1, 0x58, 0xD8, 0xFD, 0x1F, 0x3B, 0xF0,
+	 0x21, 0x44, 0x01, 0x2A, 0x13, 0x00, 0x22, 0x44, 0x3D, 0xFB, 0x60, 0x41, 0x02, 0xFE, 0xF8, 0x84,
+	 0xF8, 0x84, 0xF8, 0x84, 0x3C, 0xFB, 0x0C, 0x60, 0x7E, 0x63, 0x88, 0xFF, 0xCD, 0x81, 0x06, 0xA3,
+	 0xFD, 0x0D, 0x8D, 0xFF, 0x3B, 0xFD, 0x64, 0x47, 0x80, 0xBF, 0x60, 0x5C, 0x22, 0x43, 0x80, 0x61,
+	 0x88, 0xFF, 0xCF, 0x83, 0xE1, 0x81, 0xFD, 0x0D, 0x8D, 0xFF, 0x61, 0x47, 0x31, 0x91, 0xB1, 0x84,
+	 0x3B, 0xFA, 0x86, 0xF3, 0xFF, 0xFF, 0xCC, 0x83, 0xE3, 0x83, 0x66, 0x44, 0x02, 0xA6, 0x3B, 0xF0,
+	 0x66, 0x44, 0xB1, 0x9C, 0x3B, 0xF8, 0x02, 0xA6, 0xFA, 0x1F, 0xAB, 0x46, 0x00, 0x67, 0x00, 0x61,
+	 0x23, 0x58, 0xFF, 0xFF, 0x23, 0xF2, 0x25, 0xF0, 0x02, 0xA8, 0x00, 0x67, 0x24, 0x02, 0x3D, 0xF1,
+	 0x64, 0x44, 0x03, 0xB4, 0x40, 0x42, 0xD0, 0x80, 0x87, 0xF3, 0xFF, 0xFF, 0x60, 0x46, 0xBB, 0xF4,
+	 0x80, 0x61, 0x02, 0x02, 0xE3, 0x83, 0xEB, 0x83, 0x22, 0x44, 0x88, 0xFF, 0xCC, 0x84, 0xE1, 0x81,
+	 0xFD, 0x0D, 0x8D, 0xFF, 0x61, 0x47, 0x31, 0x91, 0x9D, 0x85, 0xA7, 0x83, 0x3B, 0xFC, 0x86, 0xF3,
+	 0xFF, 0xFF, 0xCC, 0x83, 0xE3, 0x83, 0x66, 0x44, 0x02, 0xA6, 0xBB, 0xF2, 0x66, 0x44, 0xA5, 0x81,
+	 0xBB, 0xFA, 0x02, 0xA6, 0xFA, 0x1F, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x11, 0x64, 0x23, 0xFA,
+	 0x25, 0x44, 0x24, 0xFA, 0x04, 0x64, 0x40, 0x4B, 0x62, 0x41, 0x0C, 0x60, 0x82, 0x64, 0x04, 0x63,
+	 0x58, 0xD1, 0x59, 0xD8, 0xFD, 0x1F, 0x2B, 0x43, 0x00, 0x7C, 0x59, 0xD8, 0x4F, 0x8B, 0x06, 0xA4,
+	 0xF6, 0x02, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x27, 0xF2, 0x15, 0x60, 0x02, 0x65, 0x60, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18,
+	 0x61, 0x46, 0x27, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46, 0x26, 0xF0,
+	 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46, 0x25, 0xF0, 0x63, 0x46, 0xD0, 0x80,
+	 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46, 0xE8, 0x1B, 0x87, 0xF3, 0x08, 0xFE,
+	 0x60, 0x43, 0x61, 0x46, 0x01, 0x03, 0x2A, 0x00, 0x43, 0x4B, 0xAB, 0x46, 0x3B, 0xF2, 0x80, 0x60,
+	 0x30, 0x7C, 0xB0, 0x84, 0xA2, 0xDA, 0x4E, 0x61, 0x76, 0x64, 0x0E, 0x63, 0xAB, 0x46, 0x59, 0xD0,
+	 0xAB, 0x46, 0x58, 0xD8, 0xFB, 0x1F, 0x90, 0x64, 0x04, 0x63, 0xAB, 0x46, 0x59, 0xD0, 0xAB, 0x46,
+	 0x58, 0xD8, 0xFB, 0x1F, 0xD9, 0x81, 0xA0, 0x64, 0x04, 0x63, 0xAB, 0x46, 0x59, 0xD0, 0xAB, 0x46,
+	 0x58, 0xD8, 0xFB, 0x1F, 0xD9, 0x81, 0xB6, 0x64, 0x0E, 0x63, 0xAB, 0x46, 0x59, 0xD0, 0xAB, 0x46,
+	 0x58, 0xD8, 0xFB, 0x1F, 0x00, 0x67, 0x00, 0x61, 0x23, 0x58, 0xFF, 0xFF, 0x01, 0x67, 0x20, 0x61,
+	 0x23, 0x58, 0xFF, 0xFF, 0x27, 0xF2, 0x15, 0x60, 0x02, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84,
+	 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46, 0x27, 0xF0,
+	 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46, 0x26, 0xF0, 0x63, 0x46, 0xD0, 0x80,
+	 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46, 0x25, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03,
+	 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46, 0xE8, 0x1B, 0x87, 0xF3, 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46,
+	 0x01, 0x03, 0x0D, 0x00, 0x43, 0x4B, 0xAB, 0x46, 0x3B, 0xF2, 0x80, 0x60, 0x30, 0x61, 0x9D, 0x85,
+	 0xA4, 0x84, 0xA2, 0xDA, 0xAB, 0x46, 0x00, 0x67, 0x00, 0x61, 0x23, 0x58, 0xFF, 0xFF, 0x01, 0x67,
+	 0x20, 0x61, 0x23, 0x58, 0xFF, 0xFF, 0x00, 0x64, 0x40, 0x41, 0x4A, 0x64, 0xA0, 0xD2, 0xFF, 0xFF,
+	 0x40, 0x42, 0x80, 0x2B, 0x04, 0x00, 0xFF, 0xB4, 0x40, 0x42, 0x01, 0x64, 0x40, 0x41, 0x87, 0xF3,
+	 0x46, 0x4B, 0x86, 0xF3, 0x60, 0x46, 0xE0, 0x83, 0xAB, 0x46, 0x32, 0xF0, 0xAB, 0x46, 0x59, 0xF8,
+	 0xAB, 0x46, 0x33, 0xF0, 0xAB, 0x46, 0x5A, 0xF8, 0xAB, 0x46, 0x34, 0xF0, 0xAB, 0x46, 0x5B, 0xF8,
+	 0x66, 0x44, 0x02, 0xA6, 0xF1, 0x1F, 0x87, 0xF3, 0xFF, 0xFF, 0x60, 0x46, 0xAB, 0x46, 0x0C, 0x60,
+	 0x3A, 0x65, 0x22, 0x44, 0xFF, 0xB4, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xC4, 0x81,
+	 0xC9, 0x81, 0x4A, 0x64, 0x0E, 0x63, 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0x21, 0x44, 0x01, 0x2A,
+	 0x08, 0x00, 0xAB, 0x46, 0xF0, 0xA1, 0x76, 0x64, 0x0E, 0x63, 0x59, 0xD1, 0x58, 0xD8, 0xFD, 0x1F,
+	 0xAB, 0x46, 0x22, 0x44, 0xFF, 0xB4, 0xE0, 0x84, 0xE0, 0x85, 0xC4, 0x84, 0x0C, 0x60, 0x82, 0x65,
+	 0xC4, 0x81, 0x5A, 0x64, 0x04, 0x63, 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0xAB, 0x46, 0x21, 0x44,
+	 0x01, 0x2A, 0x06, 0x00, 0xFA, 0xA1, 0x90, 0x64, 0x04, 0x63, 0x59, 0xD1, 0x58, 0xD8, 0xFD, 0x1F,
+	 0x3B, 0xF0, 0x21, 0x44, 0x01, 0x2A, 0x13, 0x00, 0x22, 0x44, 0x3D, 0xFB, 0x60, 0x41, 0x02, 0xFE,
+	 0xF8, 0x84, 0xF8, 0x84, 0xF8, 0x84, 0x3C, 0xFB, 0x0C, 0x60, 0x7E, 0x63, 0x88, 0xFF, 0xCD, 0x81,
+	 0x06, 0xA3, 0xFD, 0x0D, 0x8D, 0xFF, 0x3B, 0xFD, 0x64, 0x47, 0x80, 0xBF, 0x60, 0x5C, 0x22, 0x43,
+	 0x80, 0x61, 0x88, 0xFF, 0xCF, 0x83, 0xE1, 0x81, 0xFD, 0x0D, 0x8D, 0xFF, 0x61, 0x47, 0x31, 0x91,
+	 0xB1, 0x84, 0x3B, 0xFA, 0x86, 0xF3, 0xFF, 0xFF, 0xCC, 0x83, 0xE3, 0x83, 0x66, 0x44, 0x02, 0xA6,
+	 0x3B, 0xF0, 0x66, 0x44, 0xB1, 0x9C, 0x3B, 0xF8, 0x02, 0xA6, 0xFA, 0x1F, 0xAB, 0x46, 0x00, 0x67,
+	 0x00, 0x61, 0x23, 0x58, 0xFF, 0xFF, 0x23, 0xF2, 0x25, 0xF0, 0x02, 0xA8, 0x00, 0x67, 0x24, 0x02,
+	 0x3D, 0xF1, 0x64, 0x44, 0x03, 0xB4, 0x40, 0x42, 0xD0, 0x80, 0x87, 0xF3, 0xFF, 0xFF, 0x60, 0x46,
+	 0xBB, 0xF4, 0x80, 0x61, 0x02, 0x02, 0xE3, 0x83, 0xEB, 0x83, 0x22, 0x44, 0x88, 0xFF, 0xCC, 0x84,
+	 0xE1, 0x81, 0xFD, 0x0D, 0x8D, 0xFF, 0x61, 0x47, 0x31, 0x91, 0x9D, 0x85, 0xA7, 0x83, 0x3B, 0xFC,
+	 0x86, 0xF3, 0xFF, 0xFF, 0xCC, 0x83, 0xE3, 0x83, 0x66, 0x44, 0x02, 0xA6, 0xBB, 0xF2, 0x66, 0x44,
+	 0xA5, 0x81, 0xBB, 0xFA, 0x02, 0xA6, 0xFA, 0x1F, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x27, 0xF2,
+	 0x15, 0x60, 0x02, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46,
+	 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46, 0x27, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2,
+	 0x0C, 0x02, 0x61, 0x46, 0x26, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46,
+	 0x25, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46,
+	 0xE8, 0x1B, 0x87, 0xF3, 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0x01, 0x03, 0x21, 0x00, 0x43, 0x4B,
+	 0xAB, 0x46, 0x3B, 0xF2, 0x80, 0x60, 0x30, 0x7C, 0xB0, 0x84, 0xA2, 0xDA, 0x4E, 0x61, 0x76, 0x64,
+	 0x0E, 0x63, 0xAB, 0x46, 0x59, 0xD0, 0xAB, 0x46, 0x58, 0xD8, 0xFB, 0x1F, 0x90, 0x64, 0x04, 0x63,
+	 0xAB, 0x46, 0x59, 0xD0, 0xAB, 0x46, 0x58, 0xD8, 0xFB, 0x1F, 0xA0, 0x64, 0x04, 0x63, 0xAB, 0x46,
+	 0x59, 0xD0, 0xAB, 0x46, 0x58, 0xD8, 0xFB, 0x1F, 0x00, 0x67, 0x00, 0x61, 0x23, 0x58, 0xFF, 0xFF,
+	 0x01, 0x67, 0x20, 0x61, 0x23, 0x58, 0xFF, 0xFF, 0x27, 0xF2, 0x15, 0x60, 0x02, 0x65, 0x60, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18,
+	 0x61, 0x46, 0x27, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46, 0x26, 0xF0,
+	 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46, 0x25, 0xF0, 0x63, 0x46, 0xD0, 0x80,
+	 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46, 0xE8, 0x1B, 0x87, 0xF3, 0x08, 0xFE,
+	 0x60, 0x43, 0x61, 0x46, 0x01, 0x03, 0x0D, 0x00, 0x43, 0x4B, 0xAB, 0x46, 0x3B, 0xF2, 0x80, 0x60,
+	 0x30, 0x61, 0x9D, 0x85, 0xA4, 0x84, 0xA2, 0xDA, 0xAB, 0x46, 0x00, 0x67, 0x00, 0x61, 0x23, 0x58,
+	 0xFF, 0xFF, 0x01, 0x67, 0x20, 0x61, 0x23, 0x58, 0xFF, 0xFF, 0x3E, 0xF2, 0xAB, 0xF1, 0x08, 0xB0,
+	 0x19, 0xF8, 0x4A, 0x02, 0x07, 0x23, 0x2B, 0x00, 0x60, 0x47, 0x07, 0xB4, 0x88, 0xF1, 0xCC, 0x84,
+	 0xE0, 0x84, 0x40, 0x8A, 0xAA, 0x46, 0x03, 0xF2, 0x04, 0xF0, 0x05, 0xF2, 0x60, 0x43, 0xAA, 0x46,
+	 0x2C, 0xFC, 0x2D, 0xF8, 0x2E, 0xFA, 0xCB, 0xF1, 0x2F, 0xF8, 0xCC, 0xF1, 0x30, 0xF8, 0xCD, 0xF1,
+	 0x31, 0xF8, 0x46, 0x4A, 0x00, 0xF4, 0x02, 0xF2, 0x03, 0xF0, 0x04, 0xF2, 0x60, 0x43, 0xAA, 0x46,
+	 0x32, 0xFC, 0x33, 0xF8, 0x34, 0xFA, 0xAA, 0x46, 0x05, 0xF2, 0x06, 0xF0, 0x07, 0xF2, 0x60, 0x43,
+	 0xAA, 0x46, 0x36, 0xFC, 0x37, 0xF8, 0x38, 0xFA, 0x03, 0x60, 0x08, 0x64, 0x1C, 0x00, 0x66, 0xF1,
+	 0x2F, 0xF8, 0x67, 0xF1, 0x30, 0xF8, 0x68, 0xF1, 0x31, 0xF8, 0x46, 0x4A, 0x00, 0xF4, 0x02, 0xF2,
+	 0x03, 0xF0, 0x04, 0xF2, 0x60, 0x43, 0xAA, 0x46, 0x2C, 0xFC, 0x2D, 0xF8, 0x2E, 0xFA, 0xAA, 0x46,
+	 0x05, 0xF2, 0x06, 0xF0, 0x07, 0xF2, 0x60, 0x43, 0xAA, 0x46, 0x32, 0xFC, 0x33, 0xF8, 0x34, 0xFA,
+	 0x02, 0x60, 0x08, 0x64, 0x00, 0x00, 0x2A, 0xFA, 0x02, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x42, 0x6F,
+	 0x6F, 0x74, 0x63, 0x6F, 0x64, 0x65, 0x20, 0x21, 0x21, 0x20, 0x20, 0x00, 0x53, 0x54, 0x41, 0x2F,
+	 0x41, 0x50, 0x20, 0x46, 0x75, 0x6E, 0x63, 0x27, 0x73, 0x00, 0x20, 0x00, 0x03, 0x00, 0x01, 0x00,
+	 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+	 0x04, 0x00, 0x06, 0x00, 0x07, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x06, 0x00, 0x06, 0x00,
+	 0x07, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00,
+	 0x02, 0x00, 0x00, 0x00,
+
+};  /* fw_image_4_data */
+
+static const CFG_IDENTITY_STRCT fw_image_infoidentity[] = {
+	{
+		sizeof( CFG_IDENTITY_STRCT ) / sizeof(hcf_16) - 1,
+		CFG_FW_IDENTITY,
+		COMP_ID_FW_AP,
+		3,							//Variant
+		1,							//Major
+		24							//Minor
+	},
+	{ 0000, 0000, 0000, 0000, 0000, 0000 }		//endsentinel
+};
+
+static const CFG_PROG_STRCT fw_image_code[] = {
+	{
+		8,
+		CFG_PROG,
+		CFG_PROG_VOLATILE,			// mode
+		0x0148,		// sizeof(fw_image_1_data),
+		0x00000060,					// Target address in NIC Memory
+		0x0000,						// CRC: yes/no	TYPE: primary/station/tertiary
+		(hcf_8 FAR   *) fw_image_1_data
+	},
+	{
+		8,
+		CFG_PROG,
+		CFG_PROG_VOLATILE,			// mode
+		0x2432,		// sizeof(fw_image_2_data),
+		0x00000C16,					// Target address in NIC Memory
+		0x0000,						// CRC: yes/no	TYPE: primary/station/tertiary
+		(hcf_8 FAR   *) fw_image_2_data
+	},
+	{
+		8,
+		CFG_PROG,
+		CFG_PROG_VOLATILE,			// mode
+		0x194c,		// sizeof(fw_image_3_data),
+		0x001E3048,					// Target address in NIC Memory
+		0x0000,						// CRC: yes/no	TYPE: primary/station/tertiary
+		(hcf_8 FAR   *) fw_image_3_data
+	},
+	{
+		8,
+		CFG_PROG,
+		CFG_PROG_VOLATILE,			// mode
+		0xb7e4,		// sizeof(fw_image_4_data),
+		0x001F4000,					// Target address in NIC Memory
+		0x0000,						// CRC: yes/no	TYPE: primary/station/tertiary
+		(hcf_8 FAR   *) fw_image_4_data
+	},
+	{
+		5,
+		CFG_PROG,
+		CFG_PROG_STOP,				// mode
+		0000,
+ 	0x000F2101,					// Start execution address
+	},
+	{ 0000, 0000, 0000, 0000, 00000000, 0000, 00000000}
+};
+
+static const CFG_RANGE20_STRCT fw_image_infocompat[] = {
+	{	3 + ((20 * sizeof(CFG_RANGE_SPEC_STRCT)) / sizeof(hcf_16)),
+		CFG_FW_SUP_RANGE,
+		COMP_ROLE_SUPL,
+		COMP_ID_APF,
+		{
+			{ 4, 1, 1 }  				//variant, bottom, top
+		}
+	},
+	{	3 + ((20 * sizeof(CFG_RANGE_SPEC_STRCT)) / sizeof(hcf_16)),
+		CFG_MFI_ACT_RANGES_STA,
+		COMP_ROLE_ACT,
+		COMP_ID_MFI,
+		{
+			{ 7, 3, 3 }, 				//variant, bottom, top
+			{ 8, 1, 1 }  				//variant, bottom, top
+		}
+	},
+	{	3 + ((20 * sizeof(CFG_RANGE_SPEC_STRCT)) / sizeof(hcf_16)),
+		CFG_CFI_ACT_RANGES_STA,
+		COMP_ROLE_ACT,
+		COMP_ID_CFI,
+		{
+			{ 4, 1, 2 }  				//variant, bottom, top
+		}
+	},
+	{ 0000, 0000, 0000, 0000, { { 0000, 0000, 0000 } } }			//endsentinel
+};
+
+memimage fw_image = {
+	"FUPU7D37dhfwci\001C",			//signature, <format number>, C/Bin type
+	(CFG_PROG_STRCT *) fw_image_code,
+	0x000F2101,
+	00000000,					//(dummy) pdaplug
+	00000000,					//(dummy) priplug
+	(CFG_RANGE20_STRCT *) fw_image_infocompat,
+	(CFG_IDENTITY_STRCT *) fw_image_infoidentity,
+};
+
diff --git a/drivers/staging/wlags49_h2/debug.h b/drivers/staging/wlags49_h2/debug.h
new file mode 100644
index 0000000..0b52e17
--- /dev/null
+++ b/drivers/staging/wlags49_h2/debug.h
@@ -0,0 +1,212 @@
+/*******************************************************************************
+ * Agere Systems Inc.
+ * Wireless device driver for Linux (wlags49).
+ *
+ * Copyright (c) 1998-2003 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * Initially developed by TriplePoint, Inc.
+ *   http://www.triplepoint.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ *   This file contains definitions and macros for debugging.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2003 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following Disclaimer as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ ******************************************************************************/
+
+#ifndef _DEBUG_H
+#define _DEBUG_H
+
+
+
+
+/* Turn on debugging here if not done with a preprocessor define */
+#ifndef DBG
+#define DBG 0
+#else
+#undef	DBG
+#define DBG 1
+#endif //DBG
+
+
+
+
+#if DBG
+/****************************************************************************/
+
+/* Set the level of debugging if not done with a preprocessor define. See
+   wl_main.c, init_module() for how the debug level translates into the
+   the types of messages displayed */
+#ifndef DBG_LVL
+#define DBG_LVL 5			/* yields nothing via init_module,
+							   original value of 5 yields DBG_TRACE_ON and DBG_VERBOSE_ON */
+#endif  // DBG_LVL
+
+
+#define DBG_ERROR_ON        0x00000001L
+#define DBG_WARNING_ON      0x00000002L
+#define DBG_NOTICE_ON       0x00000004L
+#define DBG_TRACE_ON        0x00000008L
+#define DBG_VERBOSE_ON      0x00000010L
+#define DBG_PARAM_ON        0x00000020L
+#define DBG_BREAK_ON        0x00000040L
+#define DBG_RX_ON           0x00000100L
+#define DBG_TX_ON           0x00000200L
+#define DBG_DS_ON           0x00000400L
+
+#define DBG_DEFAULTS        (DBG_ERROR_ON | DBG_WARNING_ON | DBG_BREAK_ON)
+
+#define DBG_FLAGS(A)        (A)->DebugFlag
+#define DBG_NAME(A)         (A)->dbgName
+#define DBG_LEVEL(A)        (A)->dbgLevel
+
+
+#ifndef PRINTK
+#   define PRINTK(S...)     printk(S)
+#endif // PRINTK
+
+
+#ifndef DBG_PRINT
+#   define DBG_PRINT(S...)  PRINTK(KERN_DEBUG S)
+#endif // DBG_PRINT
+
+
+#ifndef DBG_PRINTC
+#   define DBG_PRINTC(S...) PRINTK(S)
+#endif // DBG_PRINTC
+
+
+#ifndef DBG_TRAP
+#   define DBG_TRAP         {}
+#endif // DBG_TRAP
+
+
+#define _ENTER_STR          ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
+#define _LEAVE_STR          "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
+
+
+#define _DBG_ENTER(A)       DBG_PRINT("%s:%.*s:%s\n",DBG_NAME(A),++DBG_LEVEL(A),_ENTER_STR,__FUNC__)
+#define _DBG_LEAVE(A)       DBG_PRINT("%s:%.*s:%s\n",DBG_NAME(A),DBG_LEVEL(A)--,_LEAVE_STR,__FUNC__)
+
+
+#define DBG_FUNC(F)         static const char *__FUNC__ = F;
+
+#define DBG_ENTER(A)        {if (DBG_FLAGS(A) & DBG_TRACE_ON) _DBG_ENTER(A);}
+
+#define DBG_LEAVE(A)        {if (DBG_FLAGS(A) & DBG_TRACE_ON) _DBG_LEAVE(A);}
+
+#define DBG_PARAM(A,N,F,S...)   {if (DBG_FLAGS(A) & DBG_PARAM_ON) \
+                                    DBG_PRINT("  %s -- "F"\n",N,S);}
+
+
+#define DBG_ERROR(A,S...)   {if (DBG_FLAGS(A) & DBG_ERROR_ON) \
+                                {DBG_PRINT("%s:ERROR:%s ",DBG_NAME(A),__FUNC__);DBG_PRINTC(S);DBG_TRAP;}}
+
+
+#define DBG_WARNING(A,S...) {if (DBG_FLAGS(A) & DBG_WARNING_ON) \
+                                {DBG_PRINT("%s:WARNING:%s ",DBG_NAME(A),__FUNC__);DBG_PRINTC(S);}}
+
+
+#define DBG_NOTICE(A,S...)  {if (DBG_FLAGS(A) & DBG_NOTICE_ON) \
+                                {DBG_PRINT("%s:NOTICE:%s ",DBG_NAME(A),__FUNC__);DBG_PRINTC(S);}}
+
+
+#define DBG_TRACE(A,S...)   do {if (DBG_FLAGS(A) & DBG_TRACE_ON) \
+                                {DBG_PRINT("%s:%s ",DBG_NAME(A),__FUNC__);DBG_PRINTC(S);}} while (0)
+
+
+#define DBG_RX(A,S...)      {if (DBG_FLAGS(A) & DBG_RX_ON) \
+                                {DBG_PRINT(S);}}
+
+
+#define DBG_TX(A,S...)      {if (DBG_FLAGS(A) & DBG_TX_ON) \
+                                {DBG_PRINT(S);}}
+
+#define DBG_DS(A,S...)      {if (DBG_FLAGS(A) & DBG_DS_ON) \
+                                {DBG_PRINT(S);}}
+
+
+#define DBG_ASSERT(C)       {if (!(C)) \
+                                {DBG_PRINT("ASSERT(%s) -- %s#%d (%s)\n", \
+                                    #C,__FILE__,__LINE__,__FUNC__); \
+                                DBG_TRAP;}}
+
+typedef struct {
+    char           *dbgName;
+    int             dbgLevel;
+    unsigned long   DebugFlag;
+} dbg_info_t;
+
+
+/****************************************************************************/
+#else // DBG
+/****************************************************************************/
+
+#define DBG_DEFN
+#define DBG_TRAP
+#define DBG_FUNC(F)
+#define DBG_PRINT(S...)
+#define DBG_ENTER(A)
+#define DBG_LEAVE(A)
+#define DBG_PARAM(A,N,F,S...)
+#define DBG_ERROR(A,S...)
+#define DBG_WARNING(A,S...)
+#define DBG_NOTICE(A,S...)
+#define DBG_TRACE(A,S...)
+#define DBG_RX(A,S...)
+#define DBG_TX(A,S...)
+#define DBG_DS(A,S...)
+#define DBG_ASSERT(C)
+
+#endif // DBG
+/****************************************************************************/
+
+
+
+
+#endif // _DEBUG_H
+
diff --git a/drivers/staging/wlags49_h2/dhf.c b/drivers/staging/wlags49_h2/dhf.c
new file mode 100644
index 0000000..b6f5834
--- /dev/null
+++ b/drivers/staging/wlags49_h2/dhf.c
@@ -0,0 +1,390 @@
+
+//   vim:tw=110:ts=4:
+/**************************************************************************************************************
+*
+* FILE   :	DHF.C
+*
+* DATE	:	$Date: 2004/07/19 08:16:14 $   $Revision: 1.2 $
+* Original	:	2004/05/28 14:05:34    Revision: 1.36      Tag: hcf7_t20040602_01
+* Original	:	2004/05/11 06:22:57    Revision: 1.32      Tag: hcf7_t7_20040513_01
+* Original	:	2004/04/15 09:24:42    Revision: 1.28      Tag: hcf7_t7_20040415_01
+* Original	:	2004/04/08 15:18:16    Revision: 1.27      Tag: t7_20040413_01
+* Original	:	2004/04/01 15:32:55    Revision: 1.25      Tag: t7_20040401_01
+* Original	:	2004/03/10 15:39:28    Revision: 1.21      Tag: t20040310_01
+* Original	:	2004/03/04 11:03:37    Revision: 1.19      Tag: t20040304_01
+* Original	:	2004/03/02 09:27:11    Revision: 1.17      Tag: t20040302_03
+* Original	:	2004/02/24 13:00:28    Revision: 1.15      Tag: t20040224_01
+* Original	:	2004/02/19 10:57:28    Revision: 1.14      Tag: t20040219_01
+* Original	:	2003/11/27 09:00:09    Revision: 1.3      Tag: t20021216_01
+*
+* AUTHOR :	John Meertens
+*			Nico Valster
+*
+* SPECIFICATION: ........
+*
+* DESC   :	generic functions to handle the download of NIC firmware
+*			Local Support Routines for above procedures
+*
+*			Customizable via HCFCFG.H, which is included by HCF.H
+*
+*
+*	DHF is (intended to be) platform-independent.
+*	DHF is a module that provides a number of routines to download firmware
+*	images (the names primary, station, access point, secondary and tertiary
+*	are used or have been used) to volatile or nonvolatile memory
+*	in WaveLAN/IEEE NICs. To achieve this DHF makes use of the WaveLAN/IEEE
+*	WCI as implemented by the HCF-module.
+*
+*	Download to non-volatile memory is used to update a WaveLAN/IEEE NIC to new
+*	firmware. Normally this will be an upgrade to newer firmware, although
+*	downgrading to older firmware is possible too.
+*
+* Note: relative to Asserts, the following can be observed:
+*	Since the IFB is not known inside the routine, the macro HCFASSERT is replaced with MMDASSERT.
+*	Also the line number reported in the assert is raised by FILE_NAME_OFFSET (10000) to discriminate the
+*	DHF Asserts from HCF and MMD asserts.
+*
+***************************************************************************************************************
+*
+*
+* SOFTWARE LICENSE
+*
+* This software is provided subject to the following terms and conditions,
+* which you should read carefully before using the software.  Using this
+* software indicates your acceptance of these terms and conditions.  If you do
+* not agree with these terms and conditions, do not use the software.
+*
+* COPYRIGHT © 1999 - 2000 by Lucent Technologies.	All Rights Reserved
+* COPYRIGHT © 2001 - 2004	by Agere Systems Inc.	All Rights Reserved
+* All rights reserved.
+*
+* Redistribution and use in source or binary forms, with or without
+* modifications, are permitted provided that the following conditions are met:
+*
+* . Redistributions of source code must retain the above copyright notice, this
+*    list of conditions and the following Disclaimer as comments in the code as
+*    well as in the documentation and/or other materials provided with the
+*    distribution.
+*
+* . Redistributions in binary form must reproduce the above copyright notice,
+*    this list of conditions and the following Disclaimer in the documentation
+*    and/or other materials provided with the distribution.
+*
+* . Neither the name of Agere Systems Inc. nor the names of the contributors
+*    may be used to endorse or promote products derived from this software
+*    without specific prior written permission.
+*
+* Disclaimer
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+* INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+* USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+* RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+* DAMAGE.
+*
+*
+**************************************************************************************************************/
+
+#include "hcf.h"
+#include "hcfdef.h"
+#include "dhf.h"
+#include "mmd.h"
+
+//to distinguish MMD from HCF asserts by means of line number
+#undef	FILE_NAME_OFFSET
+#define FILE_NAME_OFFSET MMD_FILE_NAME_OFFSET
+/*-----------------------------------------------------------------------------
+ *
+ * Defines, data structures, and global variables
+ *
+ *---------------------------------------------------------------------------*/
+
+//                    12345678901234
+char signature[14] = "FUPU7D37dhfwci";
+
+//The binary download function "relocates" the image using constructions like:
+//	fw->identity = (CFG_IDENTITY_STRCT FAR *)((char FAR *)fw->identity + (hcf_32)fw );
+//under some of the memory models under MSVC 1.52 these constructions degrade to 16-bits pointer arithmetic.
+//fw->identity is limited, such that adding it to fw, does not need to carry over from offset to segment.
+//However the segment is not set at all.
+//As a workaround the PSEUDO_CHARP macro is introduced which is a char pointer except for MSVC 1.52, in
+//which case we know that a 32-bit quantity is adequate as a pointer.
+//Note that other platforms may experience comparable problems when using the binary download feature.
+#if defined(_MSC_VER) && _MSC_VER ==  800				// Visual C++ 1.5
+#define PSEUDO_CHARP hcf_32
+#else
+#define PSEUDO_CHARP hcf_8*
+#endif
+
+/*-----------------------------------------------------------------------------
+ *
+ * LTV-records retrieved from the NIC to:
+ *	- determine compatibility between NIC and image
+ *	- ((setup the buffer size dynamically for non-volatile download (see note below) ))
+ *	- supply plugging information contained in the PDA (H-I only)
+ *
+ *---------------------------------------------------------------------------*/
+
+// for USB/H1 we needed a smaller value than the CFG_DL_BUF_STRCT reported 8192
+// for the time being it seems simpler to always use 2000 for USB/H1 as well as all other cases rather than
+// using the "fixed anyway" CFG_DL_BUF_STRCT.
+#define DL_SIZE 2000
+
+//CFG_IDENTITY_STRCT   	pri_identity	= { LOF(CFG_IDENTITY_STRCT), CFG_PRI_IDENTITY };
+CFG_SUP_RANGE_STRCT 	mfi_sup        	= { LOF(CFG_SUP_RANGE_STRCT), CFG_NIC_MFI_SUP_RANGE };
+CFG_SUP_RANGE_STRCT 	cfi_sup        	= { LOF(CFG_SUP_RANGE_STRCT), CFG_NIC_CFI_SUP_RANGE };
+/* Note: could be used rather than the above explained and defined DL_SIZE if need arises
+ * CFG_DL_BUF_STRCT    	dl_buf         	= { LOF(CFG_DL_BUF_STRCT), CFG_DL_BUF };
+*/
+
+/*-----------------------------------------------------------------------------
+ * Array ltv_info stores NIC information (in the form of LTV-records)
+ * needed for download. A NULL record indicates the end of the array.
+ *---------------------------------------------------------------------------*/
+
+/* The LTV_INFO_STRUCT is needed to save the sizes of the structs, because after a GET_INFO()
+ * the len field is changed to the real len of the RID by the called routine.
+ * This is only relevant if the DHF used without reloading the driver/utility.
+ */
+
+LTV_INFO_STRUCT ltv_info[] = {
+	{ (LTVP)&mfi_sup,			LOF(CFG_SUP_RANGE_STRCT) } ,
+	{ (LTVP)&cfi_sup,			LOF(CFG_SUP_RANGE_STRCT) } ,
+	{ (LTVP) NULL, 				0 }
+};
+
+
+/***********************************************************************************************************/
+/***************************************  PROTOTYPES  ******************************************************/
+/***********************************************************************************************************/
+static int				check_comp_fw( memimage *fw );
+
+
+/************************************************************************************************************
+*.SUBMODULE		int check_comp_fw( memimage *fw )
+*.PURPOSE		Checks compatibility of CFI and MFI, NIC as supplier, station/AP firmware image as supplier.
+*
+*.ARGUMENTS
+*   fw         	F/W image to be downloaded
+*
+*.RETURNS
+*   HFC_SUCCESS      	- firmware OK
+*   DHF_ERR_INCOMP_FW
+*
+*.DESCRIPTION
+*   This function uses compatibility and identity information that has been
+*   retrieved from the card which is currently inserted to check whether the
+*   station firmware image to be downloaded is compatible.
+*.ENDDOC				END DOCUMENTATION
+*************************************************************************************************************/
+int
+check_comp_fw( memimage *fw )
+{
+CFG_RANGE20_STRCT  		*p;
+int   					rc = HCF_SUCCESS;
+CFG_RANGE_SPEC_STRCT*	i;
+
+	switch( fw->identity->typ ) {
+	  case CFG_FW_IDENTITY:				//Station F/W
+	  case COMP_ID_FW_AP_FAKE:			//;?is this useful (used to be:  CFG_AP_IDENTITY)
+		break;
+	  default:
+		MMDASSERT( DO_ASSERT, fw->identity->typ ) 	//unknown/unsupported firmware_type:
+		rc = DHF_ERR_INCOMP_FW;
+		return rc; /* ;? how useful is this anyway,
+					*  till that is sorted out might as well violate my own single exit principle
+					*/
+	}
+	p = fw->compat;
+	i = NULL;
+	while( p->len && i == NULL ) {					// check the MFI ranges
+		if ( p->typ  == CFG_MFI_ACT_RANGES_STA ) {
+			i = mmd_check_comp( (void*)p, &mfi_sup );
+		}
+		p++;
+	}
+	MMDASSERT( i, 0 )	//MFI: NIC Supplier not compatible with F/W image Actor
+	if ( i ) {
+		p = fw->compat;
+		i = NULL;
+		while ( p->len && i == NULL ) {			// check the CFI ranges
+			if ( p->typ  == CFG_CFI_ACT_RANGES_STA ) {
+				 i = mmd_check_comp( (void*)p, &cfi_sup );
+			}
+			p++;
+		}
+		MMDASSERT( i, 0 )	//CFI: NIC Supplier not compatible with F/W image Actor
+	}
+	if ( i == NULL ) {
+		rc = DHF_ERR_INCOMP_FW;
+	}
+	return rc;
+} // check_comp_fw
+
+
+
+
+
+/*-----------------------------------------------------------------------------
+ *
+ * Exported functions
+ *
+ *---------------------------------------------------------------------------*/
+
+
+
+/*************************************************************************************************************
+*
+*.MODULE 		int dhf_download_binary( void *ifbp, memimage *fw )
+*.PURPOSE		Downloads a complete (primary, station, or access point) firmware image to the NIC.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*   fw         	F/W image to be downloaded
+*
+*.RETURNS
+*   HCF_SUCCESS         	- download completed successfully.
+*   DHF_ERR_INCOMP_FW		- firmware not compatible
+*
+*.DESCRIPTION
+*   Initialize global variables
+*   Connect to the DHF
+*   Check the compatibility of the image (For primary firmware images it is checked first
+* 	whether download is necessary).
+*   If everything's download the firmware.
+*   Disconnect from the DHF.
+*
+*
+*.DIAGRAM
+*
+*.NOTICE:
+	MMDASSERT is unacceptable because some drivers call dhf_download_binary before hcf_connect
+
+* The old comment was:
+*.ENDDOC				END DOCUMENTATION
+*************************************************************************************************************/
+int
+dhf_download_binary( memimage *fw )
+{
+int 			rc = HCF_SUCCESS;
+CFG_PROG_STRCT 	*p;
+int				i;
+
+	//validate the image
+	for ( i = 0; i < sizeof(signature) && fw->signature[i] == signature[i]; i++ ) /*NOP*/;
+	if ( i != sizeof(signature) 		||
+		 fw->signature[i] != 0x01   	||
+		 //test for Little/Big Endian Binary flag
+		 fw->signature[i+1] != ( /*HCF_BIG_ENDIAN ? 'B' : */ 'L' ) ) rc = DHF_ERR_INCOMP_FW;
+	else {					//Little Endian Binary format
+		fw->codep    = (CFG_PROG_STRCT FAR *)((PSEUDO_CHARP)fw->codep + (hcf_32)fw );
+		fw->identity = (CFG_IDENTITY_STRCT FAR *)((PSEUDO_CHARP)fw->identity + (hcf_32)fw );
+		fw->compat   = (CFG_RANGE20_STRCT FAR *)((PSEUDO_CHARP)fw->compat + (hcf_32)fw );
+		for ( i = 0; fw->p[i]; i++ ) fw->p[i] = ((PSEUDO_CHARP)fw->p[i] + (hcf_32)fw );
+		p = fw->codep;
+		while ( p->len ) {
+			p->host_addr = (PSEUDO_CHARP)p->host_addr + (hcf_32)fw;
+			p++;
+		}
+	}
+	return rc;
+}   // dhf_download_binary
+
+
+/*************************************************************************************************************
+*
+*.MODULE 		int dhf_download_fw( void *ifbp, memimage *fw )
+*.PURPOSE		Downloads a complete (primary or tertiary) firmware image to the NIC.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*   fw     		F/W image to be downloaded
+*
+*.RETURNS
+*	HCF_SUCCESS        	- download completed successfully.
+*	HCF_ERR_NO_NIC     	- no NIC present
+*	DHF_ERR_INCOMP_FW 	- firmware not compatible
+*
+*.DESCRIPTION
+* - check the signature of the image
+* - get the compatibility information from the components on the NIC
+*	  - Primary Firmware Identity
+*	  -	Modem - Firmware I/F
+*	  -	Controller - Firmware I/F
+*!! - if necessary ( i.e. H-I) get the PDA contents from the NIC
+* - check the compatibility of the MFI and CFI of the NIC with the F/W image
+*	Note: the Primary F/W compatibility is only relevant for the "running" HCF and is already verified in
+*	hcf_connect
+*!! -	if necessary ( i.e. H-I)
+*!!	  -	verify the sumcheck of the PDA
+*!!	  -	plug the image (based on the PDA and the default plug records)
+* - loop over all the download LTVs in the image which consists of a sequence of
+*	  - CFG_PROG_VOLATILE/CFG_PROG_NON_VOLATILE
+*	  - 1 or more sequences of CFG_PROG_ADDR, CFG_PROG_DATA,....,CFG_PROG_DATA
+*	  -	CFG_PROG_STOP
+*
+*.DIAGRAM
+*
+*.NOTICE
+* The old comment was:
+*	// Download primary firmware if necessary and allowed. This is done silently (without telling
+*	// the user) and only if the firmware in the download image is newer than the firmware in the
+*	// card.  In Major version 4 of the primary firmware functions of Hermes and Shark were
+*	// combined. Prior to that two separate versions existed. We only have to download primary
+*	// firmware if major version of primary firmware in the NIC < 4.
+*	//		download = pri_identity.version_major < 4;
+*	//		if ( download ) {
+*	//			rc = check_comp_primary( fw );
+*	//		}
+* It is my understanding that Pri Variant 1 must be updated by Pri Variant 2. The test on
+* major version < 4 should amount to the same result but be "principally" less correct
+* In deliberation with the Architecture team, it was decided that this upgrade for old H-I
+* NICs, is an aspect which belongs on the WSU level not on the DHF level
+*
+*.ENDDOC				END DOCUMENTATION
+*************************************************************************************************************/
+int
+dhf_download_fw( void *ifbp, memimage *fw )
+{
+int 				rc = HCF_SUCCESS;
+LTV_INFO_STRUCT_PTR pp = ltv_info;
+CFG_PROG_STRCT 		*p = fw->codep;
+LTVP 				ltvp;
+int					i;
+
+	MMDASSERT( fw != NULL, 0 )
+	//validate the image
+	for ( i = 0; i < sizeof(signature) && fw->signature[i] == signature[i]; i++ ) /*NOP*/;
+	if ( i != sizeof(signature) 		||
+		 fw->signature[i] != 0x01		||
+		 //check for binary image
+		 ( fw->signature[i+1] != 'C' && fw->signature[i+1] != ( /*HCF_BIG_ENDIAN ? 'B' : */ 'L' ) ) )
+		 rc = DHF_ERR_INCOMP_FW;
+
+//	Retrieve all information needed for download from the NIC
+	while ( ( rc == HCF_SUCCESS ) && ( ( ltvp = pp->ltvp) != NULL ) ) {
+		ltvp->len = pp++->len;	// Set len to original len. This len is changed to real len by GET_INFO()
+		rc = GET_INFO( ltvp );
+		MMDASSERT( rc == HCF_SUCCESS, rc )
+		MMDASSERT( rc == HCF_SUCCESS, ltvp->typ )
+		MMDASSERT( rc == HCF_SUCCESS, ltvp->len )
+	}
+	if ( rc == HCF_SUCCESS ) rc = check_comp_fw( fw );
+	if ( rc == HCF_SUCCESS ) {
+		while ( rc == HCF_SUCCESS && p->len ) {
+			rc = PUT_INFO( p );
+			p++;
+		}
+	}
+	MMDASSERT( rc == HCF_SUCCESS, rc )
+	return rc;
+}   // dhf_download_fw
+
+
diff --git a/drivers/staging/wlags49_h2/dhf.h b/drivers/staging/wlags49_h2/dhf.h
new file mode 100644
index 0000000..c071f34
--- /dev/null
+++ b/drivers/staging/wlags49_h2/dhf.h
@@ -0,0 +1,226 @@
+
+//   vim:tw=110:ts=4:
+#ifndef DHF_H
+#define DHF_H
+
+/**************************************************************************************************************
+*
+* FILE   :	DHF.H
+*
+* DATE	:	$Date: 2004/07/19 08:16:14 $   $Revision: 1.2 $
+* Original	:	2004/05/17 07:33:13    Revision: 1.25      Tag: hcf7_t20040602_01
+* Original	:	2004/05/11 06:03:14    Revision: 1.24      Tag: hcf7_t7_20040513_01
+* Original	:	2004/04/15 09:24:42    Revision: 1.22      Tag: hcf7_t7_20040415_01
+* Original	:	2004/04/09 14:35:52    Revision: 1.21      Tag: t7_20040413_01
+* Original	:	2004/04/01 15:32:55    Revision: 1.18      Tag: t7_20040401_01
+* Original	:	2004/03/10 15:39:28    Revision: 1.15      Tag: t20040310_01
+* Original	:	2004/03/04 11:03:38    Revision: 1.13      Tag: t20040304_01
+* Original	:	2004/02/25 14:14:37    Revision: 1.11      Tag: t20040302_03
+* Original	:	2004/02/24 13:00:28    Revision: 1.10      Tag: t20040224_01
+* Original	:	2004/02/19 10:57:28    Revision: 1.8      Tag: t20040219_01
+*
+* AUTHOR :	John Meertens
+*			Nico Valster
+*
+* SPECIFICATION: .........
+*
+* DESC   :	structure definitions and function prototypes for unit DHF.
+*
+*			Customizable via HCFCFG.H, which is included indirectly via HCF.H
+*
+***************************************************************************************************************
+*
+*
+* SOFTWARE LICENSE
+*
+* This software is provided subject to the following terms and conditions,
+* which you should read carefully before using the software.  Using this
+* software indicates your acceptance of these terms and conditions.  If you do
+* not agree with these terms and conditions, do not use the software.
+*
+* COPYRIGHT © 1994 - 1995	by AT&T.				All Rights Reserved
+* COPYRIGHT © 1999 - 2000 by Lucent Technologies.	All Rights Reserved
+* COPYRIGHT © 2001 - 2004	by Agere Systems Inc.	All Rights Reserved
+* All rights reserved.
+*
+* Redistribution and use in source or binary forms, with or without
+* modifications, are permitted provided that the following conditions are met:
+*
+* . Redistributions of source code must retain the above copyright notice, this
+*    list of conditions and the following Disclaimer as comments in the code as
+*    well as in the documentation and/or other materials provided with the
+*    distribution.
+*
+* . Redistributions in binary form must reproduce the above copyright notice,
+*    this list of conditions and the following Disclaimer in the documentation
+*    and/or other materials provided with the distribution.
+*
+* . Neither the name of Agere Systems Inc. nor the names of the contributors
+*    may be used to endorse or promote products derived from this software
+*    without specific prior written permission.
+*
+* Disclaimer
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+* INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+* USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+* RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+* DAMAGE.
+*
+*
+**************************************************************************************************************/
+
+
+#ifdef _WIN32_WCE
+#include <windef.h>
+#endif
+
+#include "hcf.h"   		 	// includes HCFCFG.H too
+
+#ifdef DHF_UIL
+#define GET_INFO( pp )  uil_get_info( (LTVP)pp )
+#define PUT_INFO( pp )  uil_put_info( (LTVP)pp )
+#else
+#define GET_INFO( pp )  hcf_get_info( ifbp, (LTVP)pp )
+#define PUT_INFO( pp )  hcf_put_info( ifbp, (LTVP)pp )
+#endif
+
+
+/*---- Defines --------------------------------------------------------------*/
+#define CODEMASK				0x0000FFFFL    	// Codemask for plug records
+
+/*---- Error numbers --------------------------------------------------------*/
+
+#define DHF_ERR_INCOMP_FW		0x40	//Image not compatible with NIC
+
+/*---- Type definitions -----------------------------------------------------*/
+//* needed by dhf_wrap.c
+//
+typedef struct {
+	LTVP 	ltvp;
+	hcf_16	len;
+} LTV_INFO_STRUCT , *LTV_INFO_STRUCT_PTR;
+
+
+/*
+ * Type: 	plugrecord
+ *
+ * Abstract: This structure represents a Plug Data Record.
+ *
+ * Description:
+ * This structure is used to overlay the plug records in the firmware memory image.
+ */
+
+typedef struct {
+	hcf_32	code;      	// Code to plug
+	hcf_32	addr;      	// Address within the memory image to plug it in
+	hcf_32	len;       	// The # of bytes which are available to store it
+} plugrecord;
+
+/*
+ * Type: 	stringrecord
+ *
+ * Abstract: This structure represents a Firmware debug/assert string
+ *
+ * Description:
+ * This structure is used to get assert and debug outputs in the driver and/or utility to be
+ * able to get more visability of the FW.
+ */
+
+#define MAX_DEBUGSTRINGS 		1024
+#define MAX_DEBUGSTRING_LEN 	  82
+
+typedef struct {
+	hcf_32	id;
+	char 	str[MAX_DEBUGSTRING_LEN];
+} stringrecord;
+
+/*
+ * Type: 	exportrecord
+ *
+ * Abstract: This structure represents a Firmware export of a variable
+ *
+ * Description:
+ * This structure is used to get the address and name of a FW variable.
+ */
+
+#define MAX_DEBUGEXPORTS 		2048
+#define MAX_DEBUGEXPORT_LEN 	  12
+
+typedef struct {
+	hcf_32	id;
+	char 	str[MAX_DEBUGEXPORT_LEN];
+} exportrecord;
+
+// Offsets in memimage array p[]
+#define FWSTRINGS_FUNCTION		0
+#define FWEXPORTS_FUNCTION		1
+
+/*
+ * Type: memimage
+ *
+ * Abstract: The "root" description of a complete memory image
+ *
+ * Description:
+ * This type represents an entire memory image. The image is built up of several
+ * segments. These segments need not be contiguous areas in memory, in other words
+ * the image may contain 'holes'.
+ *
+ * The 'codep' field points to an array of segment_descriptor structures.
+ * The end of the array is indicated by a segment_descriptor of which all fields are zero.
+ * The 'execution' field is a 32-bit address representing the execution address
+ *	of the firmware within the memory image. This address is zero in case of non-volatile
+ *	memory download.
+ * The 'compat' field points to an array of TODO
+ * 	The end of the array is indicated by a plug record of which all fields are zero.
+ * The 'identity' field points to an array of TODO
+ * 	The end of the array is indicated by a plug record of which all fields are zero.
+ * The Hermes-I specific 'pdaplug' field points to an array of Production Data Plug record structures.
+ * 	The end of the array is indicated by a plug record of which all fields are zero.
+ * The Hermes-I specific 'priplug' field points to an array of Primary Information Plug record structures.
+ * 	The end of the array is indicated by a plug record of which all fields are zero.
+ */
+typedef struct {
+	char					signature[14+1+1];	// signature (see DHF.C) + C/LE-Bin/BE-Bin-flag + format version
+	CFG_PROG_STRCT FAR		*codep;				//
+	hcf_32           	 	execution;    		// Execution address of the firmware
+	void FAR 		      	*place_holder_1;
+	void FAR  		     	*place_holder_2;
+	CFG_RANGE20_STRCT FAR  	*compat;      		// Pointer to the compatibility info records
+	CFG_IDENTITY_STRCT FAR 	*identity;    		// Pointer to the identity info records
+	void FAR				*p[2];				/* (Up to 9) pointers for (future) expansion
+												 * currently in use:
+												 *  - F/W printf information
+												 */
+} memimage;
+
+
+
+/*-----------------------------------------------------------------------------
+ *
+ * DHF function prototypes
+ *
+ *---------------------------------------------------------------------------*/
+
+EXTERN_C int dhf_download_fw( void *ifbp, memimage *fw );	//	ifbp, ignored when using the UIL
+EXTERN_C int dhf_download_binary( memimage *fw );
+
+
+/*-----------------------------------------------------------------------------
+ *
+ * Functions to be provided by the user of the DHF module.
+ *
+ *---------------------------------------------------------------------------*/
+
+// defined in DHF.C; see there for comments
+EXTERN_C hcf_16 *find_record_in_pda( hcf_16 *pdap, hcf_16 code );
+
+#endif  // DHF_H
+
diff --git a/drivers/staging/wlags49_h2/dhfcfg.h b/drivers/staging/wlags49_h2/dhfcfg.h
new file mode 100644
index 0000000..a0c26c6
--- /dev/null
+++ b/drivers/staging/wlags49_h2/dhfcfg.h
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * Agere Systems Inc.
+ * Wireless device driver for Linux (wlags49).
+ *
+ * Copyright (c) 1998-2003 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * Initially developed by TriplePoint, Inc.
+ *   http://www.triplepoint.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ *   This file contains DHF configuration info.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2003 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following Disclaimer as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ ******************************************************************************/
+
+#ifndef DHFCFG_H
+#define DHFCFG_H
+/*-----------------------------------------------------------------------------
+ * File DHFCFG.H
+ *
+ * Contents: #defines for the DHF module
+ *
+ * Comments:
+ *   Some combinations of the #defines in this file are illegal (as noted below).
+ *   If an illegal combinations of #defines is specified a compile error is
+ *   generated. See document DHFUG.DOC for more information.
+ *
+ * Author: John Meertens
+ * Date:   11-01-2000
+ *
+ * Change history:
+ *---------------------------------------------------------------------------*/
+
+
+// Define DHF_WCI if you want to use the WCI to access the ORiNOCO card.
+// Define DHF_UIL if you want to use the UIL to access the ORiNOCO card.
+// You must define either DHF_WCI or DHF_UIL. If neither of the two is defined
+// or both a compile error is generated.
+#define DHF_WCI
+//!!!#define DHF_UIL
+
+// Define DHF_BIG_ENDIAN if you are working on a big endian platform.
+// Define DHF_LITTLE_ENDIAN if you are working on a little endian platform.
+// You must define either DHF_BIG_ENDIAN or DHF_LITTLE_ENDIAN. If neither of
+// the two is defined or both a compile error is generated.
+#ifdef USE_BIG_ENDIAN
+#define DHF_BIG_ENDIAN
+#else
+#define DHF_LITTLE_ENDIAN
+#endif  /* USE_BIG_ENDIAN */
+
+// Define DHF_WIN if you are working on Windows platform.
+// Define DHF_DOS if you are working on DOS.
+// You must define either DHF_WIN or DHF_DOS. If neither of
+// the two is defined or both a compile error is generated.
+//!!!#define DHF_WIN
+//!!!#define DHF_DOS
+
+// Define if you want the DHF to users. Not defining DHF_GET_RES_MSG
+// leads to a decrease in code size as message strings are not included.
+//!!!#define DHF_GET_RES_MSG
+
+// Linux driver specific
+// Prevent inclusion of stdlib.h and string.h
+#define _INC_STDLIB
+#define _INC_STRING
+
+//-----------------------------------------------------------------------------
+// Define one or more of the following DSF #defines if you want to implement
+// the related DSF-function. Function dsf_callback must allways be implemented.
+// See file DHF.H for prototypes of the functions.
+
+// Define DSF_ALLOC if you want to manage memory allocation and de-allocation
+// for the DHF. If DSF_ALLOC is defined you must implement dsf_alloc and dsf_free.
+//!!!#define DSF_ALLOC
+
+// Define DSF_CONFIRM if you want the DHF to ask the user for confirmation in a
+// number of situations. If DSF_CONFIRM is defined you must implement dsf_confirm.
+// Not defining DSF_CONFIRM leads to a decrease in code size as confirmation
+// strings are not included.
+//!!!#define DSF_CONFIRM
+
+// Define DSF_DEBUG_MESSAGE if you want debug messages added to your output.
+// If you define DSF_DEBUG_MESSAGE then you must implement function
+// dsf_debug_message.
+//#define DSF_DEBUG_MESSAGE
+
+// Define DSF_ASSERT if you want asserts to be activated.
+// If you define DSF_ASSERT then you must implement function dsf_assert.
+//#define DBG 1
+//#define DSF_ASSERT
+
+// Define DSF_DBWIN if you want asserts and debug messages to be send to a debug
+// window like SOFTICE or DebugView from SysInternals.
+//!!!#define DSF_DBWIN
+//!!! Not implemented yet!
+
+// Define DSF_VOLATILE_ONLY if you only wants to use valatile functions
+// This is a typical setting for a AP and a driver.
+#define DSF_VOLATILE_ONLY
+
+// Define DSF_HERMESII if you want to use the DHF for the Hermes-II
+#ifdef HERMES2
+#define DSF_HERMESII
+#else
+#undef DSF_HERMESII
+#endif // HERMES2
+
+// Define DSF_BINARY_FILE if you want to use the DHF in combination with
+// reading the Firmware from a separate binary file.
+//!!!#define DSF_BINARY_FILE
+
+#endif // DHFCFG_H
diff --git a/drivers/staging/wlags49_h2/hcf.c b/drivers/staging/wlags49_h2/hcf.c
new file mode 100644
index 0000000..6e39f50
--- /dev/null
+++ b/drivers/staging/wlags49_h2/hcf.c
@@ -0,0 +1,4881 @@
+//   vim:tw=110:ts=4:
+/************************************************************************************************************
+*
+* FILE   :	HCF.C
+*
+* DATE    :	$Date: 2004/08/05 11:47:10 $   $Revision: 1.10 $
+* Original:	2004/06/02 10:22:22    Revision: 1.85      Tag: hcf7_t20040602_01
+* Original:	2004/04/15 09:24:41    Revision: 1.63      Tag: hcf7_t7_20040415_01
+* Original:	2004/04/13 14:22:44    Revision: 1.62      Tag: t7_20040413_01
+* Original:	2004/04/01 15:32:55    Revision: 1.59      Tag: t7_20040401_01
+* Original:	2004/03/10 15:39:27    Revision: 1.55      Tag: t20040310_01
+* Original:	2004/03/04 11:03:37    Revision: 1.53      Tag: t20040304_01
+* Original:	2004/03/02 14:51:21    Revision: 1.50      Tag: t20040302_03
+* Original:	2004/02/24 13:00:27    Revision: 1.43      Tag: t20040224_01
+* Original:	2004/02/19 10:57:25    Revision: 1.39      Tag: t20040219_01
+*
+* AUTHOR :	Nico Valster
+*
+* SPECIFICATION: ........
+*
+* DESCRIPTION :	HCF Routines for Hermes-II (callable via the Wireless Connection I/F or WCI)
+*				Local Support Routines for above procedures
+*
+*			Customizable via HCFCFG.H, which is included by HCF.H
+*
+*************************************************************************************************************
+*
+*
+* SOFTWARE LICENSE
+*
+* This software is provided subject to the following terms and conditions,
+* which you should read carefully before using the software.  Using this
+* software indicates your acceptance of these terms and conditions.  If you do
+* not agree with these terms and conditions, do not use the software.
+*
+* COPYRIGHT © 1994 - 1995	by AT&T.				All Rights Reserved
+* COPYRIGHT © 1996 - 2000 by Lucent Technologies.	All Rights Reserved
+* COPYRIGHT © 2001 - 2004	by Agere Systems Inc.	All Rights Reserved
+* All rights reserved.
+*
+* Redistribution and use in source or binary forms, with or without
+* modifications, are permitted provided that the following conditions are met:
+*
+* . Redistributions of source code must retain the above copyright notice, this
+*    list of conditions and the following Disclaimer as comments in the code as
+*    well as in the documentation and/or other materials provided with the
+*    distribution.
+*
+* . Redistributions in binary form must reproduce the above copyright notice,
+*    this list of conditions and the following Disclaimer in the documentation
+*    and/or other materials provided with the distribution.
+*
+* . Neither the name of Agere Systems Inc. nor the names of the contributors
+*    may be used to endorse or promote products derived from this software
+*    without specific prior written permission.
+*
+* Disclaimer
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+* INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+* USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+* RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+* DAMAGE.
+*
+*
+************************************************************************************************************/
+
+
+/************************************************************************************************************
+**
+** Implementation Notes
+**
+* -	a leading marker of //! is used. The purpose of such a sequence is to help to understand the flow
+*	An example is:	//!rc = HCF_SUCCESS;
+*	if this is superfluous because rc is already guaranteed to be 0 but it shows to the (maintenance)
+*	programmer it is an intentional omission at the place where someone could consider it most appropriate at
+*	first glance
+* -	using near pointers in a model where ss!=ds is an invitation for disaster, so be aware of how you specify
+*	your model and how you define variables which are used at interrupt time
+* -	remember that sign extension on 32 bit platforms may cause problems unless code is carefully constructed,
+*	e.g. use "(hcf_16)~foo" rather than "~foo"
+*
+************************************************************************************************************/
+
+#include "hcf.h"				// HCF and MSF common include file
+#include "hcfdef.h"				// HCF specific include file
+#include "mmd.h"				// MoreModularDriver common include file
+
+#if ! defined offsetof
+#define offsetof(s,m)   ((unsigned int)&(((s *)0)->m))
+#endif // offsetof
+
+
+/***********************************************************************************************************/
+/***************************************  PROTOTYPES  ******************************************************/
+/***********************************************************************************************************/
+HCF_STATIC int			cmd_exe( IFBP ifbp, hcf_16 cmd_code, hcf_16 par_0 );
+HCF_STATIC int			init( IFBP ifbp );
+HCF_STATIC int			put_info( IFBP ifbp, LTVP ltvp );
+#if (HCF_EXT) & HCF_EXT_MB
+HCF_STATIC int			put_info_mb( IFBP ifbp, CFG_MB_INFO_STRCT FAR * ltvp );
+#endif // HCF_EXT_MB
+#if (HCF_TYPE) & HCF_TYPE_WPA
+HCF_STATIC void			calc_mic( hcf_32* p, hcf_32 M );
+void 					calc_mic_rx_frag( IFBP ifbp, wci_bufp p, int len );
+void 					calc_mic_tx_frag( IFBP ifbp, wci_bufp p, int len );
+HCF_STATIC int			check_mic( IFBP ifbp );
+#endif // HCF_TYPE_WPA
+
+HCF_STATIC void			calibrate( IFBP ifbp );
+HCF_STATIC int			cmd_cmpl( IFBP ifbp );
+HCF_STATIC hcf_16		get_fid( IFBP ifbp );
+HCF_STATIC void			isr_info( IFBP ifbp );
+#if HCF_DMA
+HCF_STATIC DESC_STRCT*	get_frame_lst(IFBP ifbp, int tx_rx_flag);
+#endif // HCF_DMA
+HCF_STATIC void			get_frag( IFBP ifbp, wci_bufp bufp, int len BE_PAR( int word_len ) );	//char*, byte count (usually even)
+#if HCF_DMA
+HCF_STATIC void			put_frame_lst( IFBP ifbp, DESC_STRCT *descp, int tx_rx_flag );
+#endif // HCF_DMA
+HCF_STATIC void			put_frag( IFBP ifbp, wci_bufp bufp, int len BE_PAR( int word_len ) );
+HCF_STATIC void			put_frag_finalize( IFBP ifbp );
+HCF_STATIC int			setup_bap( IFBP ifbp, hcf_16 fid, int offset, int type );
+#if (HCF_ASSERT) & HCF_ASSERT_PRINTF
+static int fw_printf(IFBP ifbp, CFG_FW_PRINTF_STRCT FAR *ltvp);
+#endif // HCF_ASSERT_PRINTF
+
+HCF_STATIC int			download( IFBP ifbp, CFG_PROG_STRCT FAR *ltvp );
+#if (HCF_ENCAP) & HCF_ENC
+HCF_STATIC hcf_8		hcf_encap( wci_bufp type );
+#endif // HCF_ENCAP
+HCF_STATIC hcf_8		null_addr[4] = { 0, 0, 0, 0 };
+#if ! defined IN_PORT_WORD			//replace I/O Macros with logging facility
+extern FILE *log_file;
+
+#define IN_PORT_WORD(port)			in_port_word( (hcf_io)(port) )
+
+static hcf_16 in_port_word( hcf_io port ) {
+hcf_16 i = (hcf_16)_inpw( port );
+	if ( log_file ) {
+		fprintf( log_file, "\nR %2.2x %4.4x", (port)&0xFF, i);
+	}
+	return i;
+} // in_port_word
+
+#define OUT_PORT_WORD(port, value)	out_port_word( (hcf_io)(port), (hcf_16)(value) )
+
+static void out_port_word( hcf_io port, hcf_16 value ) {
+	_outpw( port, value );
+	if ( log_file ) {
+		fprintf( log_file, "\nW %2.02x %4.04x", (port)&0xFF, value );
+	}
+}
+
+void IN_PORT_STRING_32( hcf_io prt, hcf_32 FAR * dst, int n)	{
+	int i = 0;
+	hcf_16 FAR * p;
+	if ( log_file ) {
+		fprintf( log_file, "\nread string_32 length %04x (%04d) at port %02.2x to addr %lp",
+				 (hcf_16)n, (hcf_16)n, (hcf_16)(prt)&0xFF, dst);
+	}
+	while ( n-- ) {
+		p = (hcf_16 FAR *)dst;
+		*p++ = (hcf_16)_inpw( prt );
+		*p   = (hcf_16)_inpw( prt );
+		if ( log_file ) {
+			fprintf( log_file, "%s%08lx ", i++ % 0x08 ? " " : "\n", *dst);
+		}
+		dst++;
+	}
+} // IN_PORT_STRING_32
+
+void IN_PORT_STRING_8_16( hcf_io prt, hcf_8 FAR * dst, int n) {	//also handles byte alignment problems
+	hcf_16 FAR * p = (hcf_16 FAR *)dst;							//this needs more elaborate code in non-x86 platforms
+	int i = 0;
+	if ( log_file ) {
+		fprintf( log_file, "\nread string_16 length %04x (%04d) at port %02.2x to addr %lp",
+				 (hcf_16)n, (hcf_16)n, (hcf_16)(prt)&0xFF, dst );
+	}
+	while ( n-- ) {
+		*p =(hcf_16)_inpw( prt);
+		if ( log_file ) {
+			if ( i++ % 0x10 ) {
+				fprintf( log_file, "%04x ", *p);
+			} else {
+				fprintf( log_file, "\n%04x ", *p);
+			}
+		}
+		p++;
+	}
+} // IN_PORT_STRING_8_16
+
+void OUT_PORT_STRING_32( hcf_io prt, hcf_32 FAR * src, int n)	{
+	int i = 0;
+	hcf_16 FAR * p;
+	if ( log_file ) {
+		fprintf( log_file, "\nwrite string_32 length %04x (%04d) at port %02.2x",
+				 (hcf_16)n, (hcf_16)n, (hcf_16)(prt)&0xFF);
+	}
+	while ( n-- ) {
+		p = (hcf_16 FAR *)src;
+		_outpw( prt, *p++ );
+		_outpw( prt, *p   );
+		if ( log_file ) {
+			fprintf( log_file, "%s%08lx ", i++ % 0x08 ? " " : "\n", *src);
+		}
+		src++;
+	}
+} // OUT_PORT_STRING_32
+
+void OUT_PORT_STRING_8_16( hcf_io prt, hcf_8 FAR * src, int n)	{	//also handles byte alignment problems
+	hcf_16 FAR * p = (hcf_16 FAR *)src;								//this needs more elaborate code in non-x86 platforms
+	int i = 0;
+	if ( log_file ) {
+		fprintf( log_file, "\nwrite string_16 length %04x (%04d) at port %04x", n, n, (hcf_16)prt);
+	}
+	while ( n-- ) {
+		(void)_outpw( prt, *p);
+		if ( log_file ) {
+			if ( i++ % 0x10 ) {
+				fprintf( log_file, "%04x ", *p);
+			} else {
+				fprintf( log_file, "\n%04x ", *p);
+			}
+		}
+		p++;
+	}
+} // OUT_PORT_STRING_8_16
+
+#endif // IN_PORT_WORD
+
+/************************************************************************************************************
+******************************* D A T A    D E F I N I T I O N S ********************************************
+************************************************************************************************************/
+
+#if HCF_ASSERT
+IFBP BASED assert_ifbp = NULL;			//to make asserts easily work under MMD and DHF
+#endif // HCF_ASSERT
+
+#if HCF_ENCAP
+/* SNAP header to be inserted in Ethernet-II frames */
+HCF_STATIC  hcf_8 BASED snap_header[] = { 0xAA, 0xAA, 0x03, 0x00, 0x00,	//5 bytes signature +
+										  0 };							//1 byte protocol identifier
+#endif // HCF_ENCAP
+
+#if (HCF_TYPE) & HCF_TYPE_WPA
+HCF_STATIC hcf_8 BASED mic_pad[8] = { 0x5A, 0, 0, 0, 0, 0, 0, 0 };		//MIC padding of message
+#endif // HCF_TYPE_WPA
+
+#if defined MSF_COMPONENT_ID
+CFG_IDENTITY_STRCT BASED cfg_drv_identity = {
+	sizeof(cfg_drv_identity)/sizeof(hcf_16) - 1,	//length of RID
+	CFG_DRV_IDENTITY,			// (0x0826)
+	MSF_COMPONENT_ID,
+	MSF_COMPONENT_VAR,
+	MSF_COMPONENT_MAJOR_VER,
+	MSF_COMPONENT_MINOR_VER
+} ;
+
+CFG_RANGES_STRCT BASED cfg_drv_sup_range = {
+	sizeof(cfg_drv_sup_range)/sizeof(hcf_16) - 1,	//length of RID
+	CFG_DRV_SUP_RANGE,			// (0x0827)
+
+	COMP_ROLE_SUPL,
+	COMP_ID_DUI,
+	{{	DUI_COMPAT_VAR,
+		DUI_COMPAT_BOT,
+		DUI_COMPAT_TOP
+	}}
+} ;
+
+struct CFG_RANGE3_STRCT BASED cfg_drv_act_ranges_pri = {
+	sizeof(cfg_drv_act_ranges_pri)/sizeof(hcf_16) - 1,	//length of RID
+	CFG_DRV_ACT_RANGES_PRI,		// (0x0828)
+
+	COMP_ROLE_ACT,
+	COMP_ID_PRI,
+	{
+	 { 0, 0, 0 }, 							// HCF_PRI_VAR_1 not supported by HCF 7
+	 { 0, 0, 0 }, 							// HCF_PRI_VAR_2 not supported by HCF 7
+	 {	3,									//var_rec[2] - Variant number
+		CFG_DRV_ACT_RANGES_PRI_3_BOTTOM,		//		 - Bottom Compatibility
+		CFG_DRV_ACT_RANGES_PRI_3_TOP			//		 - Top Compatibility
+	 }
+	}
+} ;
+
+
+struct CFG_RANGE4_STRCT BASED cfg_drv_act_ranges_sta = {
+	sizeof(cfg_drv_act_ranges_sta)/sizeof(hcf_16) - 1,	//length of RID
+	CFG_DRV_ACT_RANGES_STA,		// (0x0829)
+
+	COMP_ROLE_ACT,
+	COMP_ID_STA,
+	{
+#if defined HCF_STA_VAR_1
+	 {	1,									//var_rec[1] - Variant number
+		CFG_DRV_ACT_RANGES_STA_1_BOTTOM,		//		 - Bottom Compatibility
+		CFG_DRV_ACT_RANGES_STA_1_TOP			//		 - Top Compatibility
+	 },
+#else
+	 { 0, 0, 0 },
+#endif // HCF_STA_VAR_1
+#if defined HCF_STA_VAR_2
+	 {	2,									//var_rec[1] - Variant number
+		CFG_DRV_ACT_RANGES_STA_2_BOTTOM,		//		 - Bottom Compatibility
+		CFG_DRV_ACT_RANGES_STA_2_TOP			//		 - Top Compatibility
+	 },
+#else
+	 { 0, 0, 0 },
+#endif // HCF_STA_VAR_2
+// For Native_USB (Not used!)
+#if defined HCF_STA_VAR_3
+	 {	3,									//var_rec[1] - Variant number
+		CFG_DRV_ACT_RANGES_STA_3_BOTTOM,		//		 - Bottom Compatibility
+		CFG_DRV_ACT_RANGES_STA_3_TOP			//		 - Top Compatibility
+	 },
+#else
+	 { 0, 0, 0 },
+#endif // HCF_STA_VAR_3
+// Warp
+#if defined HCF_STA_VAR_4
+	 {	4,									//var_rec[1] - Variant number
+		CFG_DRV_ACT_RANGES_STA_4_BOTTOM,		//           - Bottom Compatibility
+		CFG_DRV_ACT_RANGES_STA_4_TOP			//           - Top Compatibility
+	 }
+#else
+	 { 0, 0, 0 }
+#endif // HCF_STA_VAR_4
+	}
+} ;
+
+
+struct CFG_RANGE6_STRCT BASED cfg_drv_act_ranges_hsi = {
+	sizeof(cfg_drv_act_ranges_hsi)/sizeof(hcf_16) - 1,	//length of RID
+	CFG_DRV_ACT_RANGES_HSI,		// (0x082A)
+	COMP_ROLE_ACT,
+	COMP_ID_HSI,
+	{
+#if defined HCF_HSI_VAR_0					// Controlled deployment
+	 {	0,									// var_rec[1] - Variant number
+		CFG_DRV_ACT_RANGES_HSI_0_BOTTOM,		//           - Bottom Compatibility
+		CFG_DRV_ACT_RANGES_HSI_0_TOP			//           - Top Compatibility
+	 },
+#else
+	 { 0, 0, 0 },
+#endif // HCF_HSI_VAR_0
+	 { 0, 0, 0 }, 							// HCF_HSI_VAR_1 not supported by HCF 7
+	 { 0, 0, 0 }, 							// HCF_HSI_VAR_2 not supported by HCF 7
+	 { 0, 0, 0 }, 							// HCF_HSI_VAR_3 not supported by HCF 7
+#if defined HCF_HSI_VAR_4					// Hermes-II all types
+	 {	4,									// var_rec[1] - Variant number
+		CFG_DRV_ACT_RANGES_HSI_4_BOTTOM,		//           - Bottom Compatibility
+		CFG_DRV_ACT_RANGES_HSI_4_TOP			//           - Top Compatibility
+	 },
+#else
+	 { 0, 0, 0 },
+#endif // HCF_HSI_VAR_4
+#if defined HCF_HSI_VAR_5					// WARP Hermes-2.5
+	 {	5,									// var_rec[1] - Variant number
+		CFG_DRV_ACT_RANGES_HSI_5_BOTTOM,		//           - Bottom Compatibility
+		CFG_DRV_ACT_RANGES_HSI_5_TOP			//           - Top Compatibility
+	 }
+#else
+	 { 0, 0, 0 }
+#endif // HCF_HSI_VAR_5
+	}
+} ;
+
+
+CFG_RANGE4_STRCT BASED cfg_drv_act_ranges_apf = {
+	sizeof(cfg_drv_act_ranges_apf)/sizeof(hcf_16) - 1,	//length of RID
+	CFG_DRV_ACT_RANGES_APF,		// (0x082B)
+
+	COMP_ROLE_ACT,
+	COMP_ID_APF,
+	{
+#if defined HCF_APF_VAR_1				//(Fake) Hermes-I
+	 {	1,									//var_rec[1] - Variant number
+		CFG_DRV_ACT_RANGES_APF_1_BOTTOM,		//           - Bottom Compatibility
+		CFG_DRV_ACT_RANGES_APF_1_TOP			//           - Top Compatibility
+	 },
+#else
+	 { 0, 0, 0 },
+#endif // HCF_APF_VAR_1
+#if defined HCF_APF_VAR_2				//Hermes-II
+	 {	2,									// var_rec[1] - Variant number
+		CFG_DRV_ACT_RANGES_APF_2_BOTTOM,		//           - Bottom Compatibility
+		CFG_DRV_ACT_RANGES_APF_2_TOP			//           - Top Compatibility
+	 },
+#else
+	 { 0, 0, 0 },
+#endif // HCF_APF_VAR_2
+#if defined HCF_APF_VAR_3						// Native_USB
+	 {	3,										// var_rec[1] - Variant number
+		CFG_DRV_ACT_RANGES_APF_3_BOTTOM,		//           - Bottom Compatibility	!!!!!see note below!!!!!!!
+		CFG_DRV_ACT_RANGES_APF_3_TOP			//           - Top Compatibility
+	 },
+#else
+	 { 0, 0, 0 },
+#endif // HCF_APF_VAR_3
+#if defined HCF_APF_VAR_4						// WARP Hermes 2.5
+	 {	4,										// var_rec[1] - Variant number
+		CFG_DRV_ACT_RANGES_APF_4_BOTTOM,		//           - Bottom Compatibility	!!!!!see note below!!!!!!!
+		CFG_DRV_ACT_RANGES_APF_4_TOP			//           - Top Compatibility
+	 }
+#else
+	 { 0, 0, 0 }
+#endif // HCF_APF_VAR_4
+	}
+} ;
+#define HCF_VERSION  TEXT( "HCF$Revision: 1.10 $" )
+
+static struct /*CFG_HCF_OPT_STRCT*/ {
+	hcf_16	len;					//length of cfg_hcf_opt struct
+	hcf_16	typ;					//type 0x082C
+	hcf_16	 v0;						//offset HCF_VERSION
+	hcf_16	 v1;						// MSF_COMPONENT_ID
+	hcf_16	 v2;						// HCF_ALIGN
+	hcf_16	 v3;						// HCF_ASSERT
+	hcf_16	 v4;						// HCF_BIG_ENDIAN
+	hcf_16	 v5;						// /* HCF_DLV | HCF_DLNV */
+	hcf_16	 v6;						// HCF_DMA
+	hcf_16	 v7;						// HCF_ENCAP
+	hcf_16	 v8;						// HCF_EXT
+	hcf_16	 v9;						// HCF_INT_ON
+	hcf_16	v10;						// HCF_IO
+	hcf_16	v11;						// HCF_LEGACY
+	hcf_16	v12;						// HCF_MAX_LTV
+	hcf_16	v13;						// HCF_PROT_TIME
+	hcf_16	v14;						// HCF_SLEEP
+	hcf_16	v15;						// HCF_TALLIES
+	hcf_16	v16;						// HCF_TYPE
+	hcf_16	v17;						// HCF_NIC_TAL_CNT
+	hcf_16	v18;						// HCF_HCF_TAL_CNT
+	hcf_16	v19;						// offset tallies
+	TCHAR	val[sizeof(HCF_VERSION)];
+} BASED cfg_hcf_opt = {
+	sizeof(cfg_hcf_opt)/sizeof(hcf_16) -1,
+	CFG_HCF_OPT,				// (0x082C)
+	( sizeof(cfg_hcf_opt) - sizeof(HCF_VERSION) - 4 )/sizeof(hcf_16),
+#if defined MSF_COMPONENT_ID
+	MSF_COMPONENT_ID,
+#else
+	0,
+#endif // MSF_COMPONENT_ID
+	HCF_ALIGN,
+	HCF_ASSERT,
+	HCF_BIG_ENDIAN,
+	0,									// /* HCF_DLV | HCF_DLNV*/,
+	HCF_DMA,
+	HCF_ENCAP,
+	HCF_EXT,
+	HCF_INT_ON,
+	HCF_IO,
+	HCF_LEGACY,
+	HCF_MAX_LTV,
+	HCF_PROT_TIME,
+	HCF_SLEEP,
+	HCF_TALLIES,
+	HCF_TYPE,
+#if (HCF_TALLIES) & ( HCF_TALLIES_NIC | HCF_TALLIES_HCF )
+	HCF_NIC_TAL_CNT,
+	HCF_HCF_TAL_CNT,
+	offsetof(IFB_STRCT, IFB_TallyLen ),
+#else
+	0, 0, 0,
+#endif // HCF_TALLIES_NIC / HCF_TALLIES_HCF
+	HCF_VERSION
+}; // cfg_hcf_opt
+#endif // MSF_COMPONENT_ID
+
+#if defined HCF_TALLIES_EXTRA
+	replaced by HCF_EXT_TALLIES_FW ;
+#endif // HCF_TALLIES_EXTRA
+
+#if defined MSF_COMPONENT_ID || (HCF_EXT) & HCF_EXT_MB
+#if (HCF_EXT) & HCF_EXT_MB
+HCF_STATIC LTV_STRCT BASED cfg_null = { 1, CFG_NULL, {0} };
+#endif // HCF_EXT_MB
+HCF_STATIC hcf_16* BASED xxxx[ ] = {
+#if (HCF_EXT) & HCF_EXT_MB
+	&cfg_null.len,							//CFG_NULL						0x0820
+#endif // HCF_EXT_MB
+#if defined MSF_COMPONENT_ID
+	&cfg_drv_identity.len,					//CFG_DRV_IDENTITY              0x0826
+	&cfg_drv_sup_range.len,					//CFG_DRV_SUP_RANGE             0x0827
+	&cfg_drv_act_ranges_pri.len,			//CFG_DRV_ACT_RANGES_PRI        0x0828
+	&cfg_drv_act_ranges_sta.len,			//CFG_DRV_ACT_RANGES_STA		0x0829
+	&cfg_drv_act_ranges_hsi.len,			//CFG_DRV_ACT_RANGES_HSI		0x082A
+	&cfg_drv_act_ranges_apf.len,			//CFG_DRV_ACT_RANGES_APF		0x082B
+	&cfg_hcf_opt.len,						//CFG_HCF_OPT					0x082C
+	NULL,									//IFB_PRIIdentity placeholder	0xFD02
+	NULL,									//IFB_PRISup placeholder		0xFD03
+#endif // MSF_COMPONENT_ID
+	NULL									//endsentinel
+  };
+#define xxxx_PRI_IDENTITY_OFFSET	(sizeof(xxxx)/sizeof(xxxx[0]) - 3)
+
+#endif // MSF_COMPONENT_ID / HCF_EXT_MB
+
+
+/************************************************************************************************************
+************************** T O P   L E V E L   H C F   R O U T I N E S **************************************
+************************************************************************************************************/
+
+#if (HCF_DL_ONLY) == 0
+/************************************************************************************************************
+*
+*.MODULE		int hcf_action( IFBP ifbp, hcf_16 action )
+*.PURPOSE		Changes the run-time Card behavior.
+*				Performs Miscellanuous actions.
+*
+*.ARGUMENTS
+*	ifbp					address of the Interface Block
+*	action					number identifying the type of change
+*	 - HCF_ACT_CCX_OFF		disable CKIP
+*	 - HCF_ACT_CCX_ON		enable CKIP
+*	 - HCF_ACT_INT_FORCE_ON	enable interrupt generation by WaveLAN NIC
+*	 - HCF_ACT_INT_OFF		disable interrupt generation by WaveLAN NIC
+*	 - HCF_ACT_INT_ON		compensate 1 HCF_ACT_INT_OFF, enable interrupt generation if balance reached
+*	 - HCF_ACT_PRS_SCAN		Hermes Probe Respons Scan (F102) command
+*	 - HCF_ACT_RX_ACK		acknowledge non-DMA receiver to Hermes
+*	 - HCF_ACT_SCAN			Hermes Inquire Scan (F101) command (non-WARP only)
+*	 - HCF_ACT_SLEEP		DDS Sleep request
+*	 - HCF_ACT_TALLIES		Hermes Inquire Tallies (F100) command
+*
+*.RETURNS
+*	HCF_SUCCESS				all (including invalid)
+*	HCF_INT_PENDING			HCF_ACT_INT_OFF, interrupt pending
+*	HCF_ERR_NO_NIC			HCF_ACT_INT_OFF, NIC presence check fails
+*
+*.CONDITIONS
+* Except for hcf_action with HCF_ACT_INT_FORCE_ON or HCF_ACT_INT_OFF as parameter or hcf_connect with an I/O
+* address (i.e. not HCF_DISCONNECT), all hcf-function calls MUST be preceeded by a call of hcf_action with
+* HCF_ACT_INT_OFF as parameter.
+* Note that hcf_connect defaults to NIC interrupt disabled mode, i.e. as if hcf_action( HCF_ACT_INT_OFF )
+* was called.
+*
+*.DESCRIPTION
+* hcf_action supports the following mode changing action-code pairs that are antonyms
+*	 - HCF_ACT_CCX_OFF / HCF_ACT_CCX_ON
+*	 - HCF_ACT_INT_[FORCE_]ON / HCF_ACT_INT_OFF
+*
+* Additionally hcf_action can start the following actions in the NIC:
+*	 - HCF_ACT_PRS_SCAN
+*	 - HCF_ACT_RX_ACK
+*	 - HCF_ACT_SCAN
+*	 - HCF_ACT_SLEEP
+*	 - HCF_ACT_TALLIES
+*
+* o HCF_ACT_INT_OFF: Sets NIC Interrupts mode Disabled.
+* This command, and the associated [Force] Enable NIC interrupts command, are only available if the HCF_INT_ON
+* compile time option is not set at 0x0000.
+*
+* o HCF_ACT_INT_ON: Sets NIC Interrupts mode Enabled.
+* Enable NIC Interrupts, depending on the number of preceding Disable NIC Interrupt calls.
+*
+* o HCF_ACT_INT_FORCE_ON: Force NIC Interrupts mode Enabled.
+* Sets NIC Interrupts mode Enabled, regardless off the number of preceding Disable NIC Interrupt calls.
+*
+* The disabling and enabling of interrupts are antonyms.
+* These actions must be balanced.
+* For each "disable interrupts" there must be a matching "enable interrupts".
+* The disable interrupts may be executed multiple times in a row without intervening enable interrupts, in
+* other words, the disable interrupts may be nested.
+* The interrupt generation mechanism is disabled at the first call with HCF_ACT_INT_OFF.
+* The interrupt generation mechanism is re-enabled when the number of calls with HCF_ACT_INT_ON matches the
+* number of calls with INT_OFF.
+*
+* It is not allowed to have more Enable NIC Interrupts calls than Disable NIC Interrupts calls.
+* The interrupt generation mechanism is initially (i.e. after hcf_connect) disabled.
+* An MSF based on a interrupt strategy must call hcf_action with INT_ON in its initialization logic.
+*
+*!	The INT_OFF/INT_ON housekeeping is initialized at 0x0000 by hcf_connect, causing the interrupt generation
+*	mechanism to be disabled at first. This suits MSF implementation based on a polling strategy.
+*
+* o HCF_ACT_CCX_OFF / HCF_ACT_CCX_ON
+*!! This can use some more explanation;?
+* Disables and Enables support in the HCF runtime code for the CCX feature. Each time one of these action
+* codes is used, the effects of the preceding use cease.
+*
+* o HCF_ACT_SLEEP: Initiates the Disconnected DeepSleep process
+* This command is only available if the HCF_DDS compile time option is set. It triggers the F/W to start the
+* sleep handshaking. Regardless whether the Host initiates a Disconnected DeepSleep (DDS) or the F/W initiates
+* a Connected DeepSleep (CDS), the Host-F/W sleep handshaking is completed when the NIC Interrupts mode is
+* enabled (by means of the balancing HCF_ACT_INT_ON), i.e. at that moment the F/W really goes into sleep mode.
+* The F/W is wokenup by the HCF when the NIC Interrupts mode are disabled, i.e. at the first HCF_ACT_INT_OFF
+* after going into sleep.
+*
+* The following Miscellanuous actions are defined:
+*
+* o HCF_ACT_RX_ACK: Receiver Acknowledgement (non-DMA, non-USB mode only)
+* Acking the receiver, frees the NIC memory used to hold the Rx frame and allows the F/W to
+* report the existence of the next Rx frame.
+* If the MSF does not need access (any longer) to the current frame, e.g. because it is rejected based on the
+* look ahead or copied to another buffer, the receiver may be acked. Acking earlier is assumed to have the
+* potential of improving the performance.
+* If the MSF does not explitly ack te receiver, the acking is done implicitly if:
+* - the received frame fits in the look ahead buffer, by the hcf_service_nic call that reported the Rx frame
+* - if not in the above step, by hcf_rcv_msg (assuming hcf_rcv_msg is called)
+* - if neither of the above implicit acks nor an explicit ack by the MSF, by the first hcf_service_nic after
+*	the hcf_service_nic that reported the Rx frame.
+* Note: If an Rx frame is already acked, an explicit ACK by the MSF acts as a NoOperation.
+*
+* o HCF_ACT_TALLIES: Inquire Tallies command
+* This command is only operational if the F/W is enabled.
+* The Inquire Tallies command requests the F/W to provide its current set of tallies.
+* See also hcf_get_info with CFG_TALLIES as parameter.
+*
+* o HCF_ACT_PRS_SCAN: Inquire Probe Respons Scan command
+* This command is only operational if the F/W is enabled.
+* The Probe Respons Scan command starts a scan sequence.
+* The HCF puts the result of this action in an MSF defined buffer (see CFG_RID_LOG_STRCT).
+*
+* o HCF_ACT_SCAN: Inquire Scan command
+* This command is only supported for HII F/W (i.e. pre-WARP) and it is operational if the F/W is enabled.
+* The Inquire Scan command starts a scan sequence.
+* The HCF puts the result of this action in an MSF defined buffer (see CFG_RID_LOG_STRCT).
+*
+* Assert fails if
+* - ifbp has a recognizable out-of-range value.
+* - NIC interrupts are not disabled while required by parameter action.
+* - an invalid code is specified in parameter action.
+* - HCF_ACT_INT_ON commands outnumber the HCF_ACT_INT_OFF commands.
+* - reentrancy, may be  caused by calling hcf_functions without adequate protection against NIC interrupts or
+*	multi-threading
+*
+* - Since the HCF does not maintain status information relative to the F/W enabled state, it is not asserted
+*	whether HCF_ACT_SCAN, HCF_ACT_PRS_SCAN or HCF_ACT_TALLIES are only used while F/W is enabled.
+*
+*.DIAGRAM
+* 0: The assert embedded in HCFLOGENTRY checks against re-entrancy. Re-entrancy could be caused by a MSF logic
+*	at task-level calling hcf_functions without shielding with HCF_ACT_ON/_OFF. However the HCF_ACT_INT_OFF
+*	action itself can per definition not be protected this way. Based on code inspection, it can be concluded,
+*	that there is no re-entrancy PROBLEM in this particular flow. It does not seem worth the trouble to
+*	explicitly check for this condition (although there was a report of an MSF which ran into this assert.
+* 2:IFB_IntOffCnt is used to balance the INT_OFF and INT_ON calls.  Disabling of the interrupts is achieved by
+*	writing a zero to the Hermes IntEn register.  In a shared interrupt environment (e.g. the mini-PCI NDIS
+*	driver) it is considered more correct to return the status HCF_INT_PENDING if and only if, the current
+*	invocation of hcf_service_nic is (apparently) called in the ISR when the ISR was activated as result of a
+*	change in HREG_EV_STAT matching a bit in HREG_INT_EN, i.e. not if invoked as result of another device
+*	generating an interrupt on the shared interrupt line.
+*	Note 1: it has been observed that under certain adverse conditions on certain platforms the writing of
+*	HREG_INT_EN can apparently fail, therefor it is paramount that HREG_INT_EN is written again with 0 for
+*	each and every call to HCF_ACT_INT_OFF.
+*	Note 2: it has been observed that under certain H/W & S/W architectures this logic is called when there is
+*	no NIC at all. To cater for this, the value of HREG_INT_EN is validated. If the unused bit 0x0100 is set,
+*	it is assumed there is no NIC.
+*	Note 3: During the download process, some versions of the F/W reset HREG_SW_0, hence checking this
+*	register for HCF_MAGIC (the classical NIC presence test) when HCF_ACT_INT_OFF is called due to another
+*	card interrupting via a shared IRQ during a download, fails.
+*4:	The construction "if ( ifbp->IFB_IntOffCnt-- == 0 )" is optimal (in the sense of shortest/quickest
+*	path in error free flows) but NOT fail safe in case of too many INT_ON invocations compared to INT_OFF).
+*	Enabling of the interrupts is achieved by writing the Hermes IntEn register.
+*	 - If the HCF is in Defunct mode, the interrupts stay disabled.
+*	 - Under "normal" conditions, the HCF is only interested in Info Events, Rx Events and Notify Events.
+*	 - When the HCF is out of Tx/Notify resources, the HCF is also interested in Alloc Events.
+*	 - via HCF_EXT, the MSF programmer can also request HREG_EV_TICK and/or HREG_EV_TX_EXC interrupts.
+*	For DMA operation, the DMA hardware handles the alloc events. The DMA engine will generate a 'TxDmaDone'
+*	event as soon as it has pumped a frame from host ram into NIC-RAM (note that the frame does not have to be
+*	transmitted then), and a 'RxDmaDone' event as soon as a received frame has been pumped from NIC-RAM into
+*	host ram.  Note that the 'alloc' event has been removed from the event-mask, because the DMA engine will
+*	react to and acknowledge this event.
+*6:	ack the "old" Rx-event. See "Rx Buffer free strategy" in hcf_service_nic above for more explanation.
+*	IFB_RxFID and IFB_RxLen must be cleared to bring both the internal HCF house keeping and the information
+*	supplied to the MSF in the state "no frame received".
+*8:	The HCF_ACT_SCAN, HCF_ACT_PRS_SCAN and HCF_ACT_TALLIES activity are merged by "clever" algebraic
+*	manipulations of the RID-values and action codes, so foregoing robustness against migration problems for
+*	ease of implementation. The assumptions about numerical relationships between CFG_TALLIES etc and
+*	HCF_ACT_TALLIES etc are checked by the "#if" statements just prior to the body of this routine, resulting
+*	in: err "maintenance" during compilation if the assumptions are no longer met. The writing of HREG_PARAM_1
+*	with 0x3FFF in case of an PRS scan, is a kludge to get around lack of specification, hence different
+*	implementation in F/W and Host.
+*	When there is no NIC RAM available, some versions of the Hermes F/W do report 0x7F00 as error in the
+*	Result field of the Status register and some F/W versions don't. To mask this difference to the MSF all
+*	return codes of the Hermes are ignored ("best" and "most simple" solution to these types of analomies with
+*	an acceptable loss due to ignoring all error situations as well).
+*	The "No inquire space" is reported via the Hermes tallies.
+*30: do not HCFASSERT( rc, rc ) since rc == HCF_INT_PENDING is no error
+*
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+#if ( (HCF_TYPE) & HCF_TYPE_HII5 ) == 0
+#if CFG_SCAN != CFG_TALLIES - HCF_ACT_TALLIES + HCF_ACT_SCAN
+err: "maintenance" apparently inviolated the underlying assumption about the numerical values of these macros
+#endif
+#endif // HCF_TYPE_HII5
+#if CFG_PRS_SCAN != CFG_TALLIES - HCF_ACT_TALLIES + HCF_ACT_PRS_SCAN
+err: "maintenance" apparently inviolated the underlying assumption about the numerical values of these macros
+#endif
+int
+hcf_action( IFBP ifbp, hcf_16 action )
+{
+int	rc = HCF_SUCCESS;
+
+	HCFASSERT( ifbp->IFB_Magic == HCF_MAGIC, ifbp->IFB_Magic )
+#if HCF_INT_ON
+	HCFLOGENTRY( action == HCF_ACT_INT_FORCE_ON ? HCF_TRACE_ACTION_KLUDGE : HCF_TRACE_ACTION, action )														/* 0 */
+#if (HCF_SLEEP)
+	HCFASSERT( ifbp->IFB_IntOffCnt != 0xFFFE || action == HCF_ACT_INT_OFF,
+			   MERGE_2( action, ifbp->IFB_IntOffCnt ) )
+#else
+	HCFASSERT( ifbp->IFB_IntOffCnt != 0xFFFE, action )
+#endif // HCF_SLEEP
+	HCFASSERT( ifbp->IFB_IntOffCnt != 0xFFFF ||
+			   action == HCF_ACT_INT_OFF || action == HCF_ACT_INT_FORCE_ON,  action )
+	HCFASSERT( ifbp->IFB_IntOffCnt <= 16 || ifbp->IFB_IntOffCnt >= 0xFFFE,
+			   MERGE_2( action, ifbp->IFB_IntOffCnt ) )	//nesting more than 16 deep seems unreasonable
+#endif // HCF_INT_ON
+
+	switch (action) {
+#if HCF_INT_ON
+hcf_16	i;
+	  case HCF_ACT_INT_OFF:						// Disable Interrupt generation
+#if HCF_SLEEP
+		if ( ifbp->IFB_IntOffCnt == 0xFFFE ) {	// WakeUp test	;?tie this to the "new" super-LinkStat
+			ifbp->IFB_IntOffCnt++;						// restore conventional I/F
+			OPW(HREG_IO, HREG_IO_WAKEUP_ASYNC );		// set wakeup bit
+			OPW(HREG_IO, HREG_IO_WAKEUP_ASYNC );		// set wakeup bit to counteract the clearing by F/W
+			// 800 us latency before FW switches to high power
+			MSF_WAIT(800);								// MSF-defined function to wait n microseconds.
+//OOR		if ( ifbp->IFB_DSLinkStat & CFG_LINK_STAT_DS_OOR ) { // OutOfRange
+//				printk( "<5>ACT_INT_OFF: Deepsleep phase terminated, enable and go to AwaitConnection\n" );		//;?remove me 1 day
+//				hcf_cntl( ifbp, HCF_CNTL_ENABLE );
+//			}
+//			ifbp->IFB_DSLinkStat &= ~( CFG_LINK_STAT_DS_IR | CFG_LINK_STAT_DS_OOR);	//clear IR/OOR state
+		}
+#endif // HCF_SLEEP
+/*2*/	ifbp->IFB_IntOffCnt++;
+//!     rc = 0;
+		i = IPW( HREG_INT_EN );
+		OPW( HREG_INT_EN, 0 );
+		if ( i & 0x1000 ) {
+			rc = HCF_ERR_NO_NIC;
+		} else {
+			if ( i & IPW( HREG_EV_STAT ) ) {
+				rc = HCF_INT_PENDING;
+			}
+		}
+		break;
+
+	  case HCF_ACT_INT_FORCE_ON:				// Enforce Enable Interrupt generation
+		ifbp->IFB_IntOffCnt = 0;
+		//Fall through in HCF_ACT_INT_ON
+
+	  case HCF_ACT_INT_ON:						// Enable Interrupt generation
+/*4*/	if ( ifbp->IFB_IntOffCnt-- == 0 && ifbp->IFB_CardStat == 0 ) {
+												//determine Interrupt Event mask
+#if HCF_DMA
+			if ( ifbp->IFB_CntlOpt & USE_DMA ) {
+				i = HREG_EV_INFO | HREG_EV_RDMAD | HREG_EV_TDMAD | HREG_EV_TX_EXT;	//mask when DMA active
+			} else
+#endif // HCF_DMA
+			{
+				i = HREG_EV_INFO | HREG_EV_RX | HREG_EV_TX_EXT;						//mask when DMA not active
+				if ( ifbp->IFB_RscInd == 0 ) {
+					i |= HREG_EV_ALLOC;												//mask when no TxFID available
+				}
+			}
+#if HCF_SLEEP
+			if ( ( IPW(HREG_EV_STAT) & ( i | HREG_EV_SLEEP_REQ ) ) == HREG_EV_SLEEP_REQ ) {
+				// firmware indicates it would like to go into sleep modus
+				// only acknowledge this request if no other events that can cause an interrupt are pending
+				ifbp->IFB_IntOffCnt--;			//becomes 0xFFFE
+            	OPW( HREG_INT_EN, i | HREG_EV_TICK );
+				OPW( HREG_EV_ACK, HREG_EV_SLEEP_REQ | HREG_EV_TICK | HREG_EV_ACK_REG_READY );
+			} else
+#endif // HCF_SLEEP
+			{
+            	OPW( HREG_INT_EN, i | HREG_EV_SLEEP_REQ );
+			}
+		}
+		break;
+#endif // HCF_INT_ON
+
+#if (HCF_SLEEP) & HCF_DDS
+	  case HCF_ACT_SLEEP:						// DDS Sleep request
+		hcf_cntl( ifbp, HCF_CNTL_DISABLE );
+		cmd_exe( ifbp, HCMD_SLEEP, 0 );
+		break;
+// 	  case HCF_ACT_WAKEUP:						// DDS Wakeup request
+// 		HCFASSERT( ifbp->IFB_IntOffCnt == 0xFFFE, ifbp->IFB_IntOffCnt )
+// 		ifbp->IFB_IntOffCnt++;					// restore conventional I/F
+// 		OPW( HREG_IO, HREG_IO_WAKEUP_ASYNC );
+// 		MSF_WAIT(800);							// MSF-defined function to wait n microseconds.
+// 		rc = hcf_action( ifbp, HCF_ACT_INT_OFF );	/*bogus, IFB_IntOffCnt == 0xFFFF, so if you carefully look
+// 													 *at the #if HCF_DDS statements, HCF_ACT_INT_OFF is empty
+// 													 *for DDS. "Much" better would be to merge the flows for
+// 													 *DDS and DEEP_SLEEP
+// 													 */
+// 		break;
+#endif // HCF_DDS
+
+#if (HCF_TYPE) & HCF_TYPE_CCX
+	  case HCF_ACT_CCX_ON:						// enable CKIP
+	  case HCF_ACT_CCX_OFF:						// disable CKIP
+		ifbp->IFB_CKIPStat = action;
+		break;
+#endif // HCF_TYPE_CCX
+
+	  case HCF_ACT_RX_ACK:						//Receiver ACK
+/*6*/	if ( ifbp->IFB_RxFID ) {
+			DAWA_ACK( HREG_EV_RX );
+		}
+		ifbp->IFB_RxFID = ifbp->IFB_RxLen = 0;
+		break;
+
+/*8*/ case	HCF_ACT_PRS_SCAN:					// Hermes PRS Scan (F102)
+		OPW( HREG_PARAM_1, 0x3FFF );
+			//Fall through in HCF_ACT_TALLIES
+	  case HCF_ACT_TALLIES:						// Hermes Inquire Tallies (F100)
+#if ( (HCF_TYPE) & HCF_TYPE_HII5 ) == 0
+	  case HCF_ACT_SCAN:						// Hermes Inquire Scan (F101)
+#endif // HCF_TYPE_HII5
+		/*!! the assumptions about numerical relationships between CFG_TALLIES etc and HCF_ACT_TALLIES etc
+		 *   are checked by #if statements just prior to this routine resulting in: err "maintenance"	*/
+		cmd_exe( ifbp, HCMD_INQUIRE, action - HCF_ACT_TALLIES + CFG_TALLIES );
+		break;
+
+	  default:
+		HCFASSERT( DO_ASSERT, action )
+		break;
+	}
+	//! do not HCFASSERT( rc == HCF_SUCCESS, rc )														/* 30*/
+	HCFLOGEXIT( HCF_TRACE_ACTION )
+	return rc;
+} // hcf_action
+#endif // HCF_DL_ONLY
+
+
+/************************************************************************************************************
+*
+*.MODULE		int hcf_cntl( IFBP ifbp, hcf_16 cmd )
+*.PURPOSE		Connect or disconnect a specific port to a specific network.
+*!!  ;???????????????? continue needs more explanation
+*				recovers by means of "continue" when the connect proces in CCX mode fails
+*				Enables or disables data transmission and reception for the NIC.
+*				Activates static NIC configuration for a specific port at connect.
+*				Activates static configuration for all ports at enable.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*	cmd			0x001F:	Hermes command (disable, enable, connect, disconnect, continue)
+*					HCF_CNTL_ENABLE		Enable
+*					HCF_CNTL_DISABLE    Disable
+*					HCF_CNTL_CONTINUE	Continue
+*					HCF_CNTL_CONNECT    Connect
+*					HCF_CNTL_DISCONNECT Disconnect
+*				0x0100: command qualifier (continue)
+*					HCMD_RETRY			retry flag
+*				0x0700:  port number (connect/disconnect)
+*					HCF_PORT_0          MAC Port 0
+*					HCF_PORT_1          MAC Port 1
+*					HCF_PORT_2          MAC Port 2
+*					HCF_PORT_3          MAC Port 3
+*					HCF_PORT_4          MAC Port 4
+*					HCF_PORT_5          MAC Port 5
+*					HCF_PORT_6          MAC Port 6
+*
+*.RETURNS
+*	HCF_SUCCESS
+*!!	via cmd_exe
+*	HCF_ERR_NO_NIC
+*	HCF_ERR_DEFUNCT_...
+*	HCF_ERR_TIME_OUT
+*
+*.DESCRIPTION
+* The parameter cmd contains a number of subfields.
+* The actual value for cmd is created by logical or-ing the appropriate mnemonics for the subfields.
+* The field 0x001F contains the command code
+*  - HCF_CNTL_ENABLE
+*  - HCF_CNTL_DISABLE
+*  - HCF_CNTL_CONNECT
+*  - HCF_CNTL_DISCONNECT
+*  - HCF_CNTL_CONTINUE
+*
+* For HCF_CNTL_CONTINUE, the field 0x0100 contains the retry flag HCMD_RETRY.
+* For HCF_CNTL_CONNECT and HCF_CNTL_DISCONNECT, the field 0x0700 contains the port number as HCF_PORT_#.
+* For Station as well as AccessPoint F/W, MAC Port 0 is the "normal" communication channel.
+* For AccessPoint F/W, MAC Port 1 through 6 control the WDS links.
+*
+* Note that despite the names HCF_CNTL_DISABLE and HCF_CNTL_ENABLE, hcf_cntl does not influence the NIC
+* Interrupts mode.
+*
+* The Connect is used by the MSF to bring a particular port in an inactive state as far as data transmission
+* and reception are concerned.
+* When a particular port is disconnected:
+* - the F/W disables the receiver for that port.
+* - the F/W ignores send commands for that port.
+* - all frames (Receive as well as pending Transmit) for that port on the NIC are discarded.
+*
+* When the NIC is disabled, above list applies to all ports, i.e. the result is like all ports are
+* disconnected.
+*
+* When a particular port is connected:
+* - the F/W effectuates the static configuration for that port.
+* - enables the receiver for that port.
+* - accepts send commands for that port.
+*
+* Enabling has the following effects:
+* - the F/W effectuates the static configuration for all ports.
+*	The F/W only updates its static configuration at a transition from disabled to enabled or from
+*	disconnected to connected.
+*	In order to enforce the static configuration, the MSF must assure that such a transition takes place.
+*	Due to such a disable/enable or disconnect/connect sequence, Rx/Tx frames may be lost, in other words,
+*	configuration may impact communication.
+* - The DMA Engine (if applicable) is enabled.
+* Note that the Enable Function by itself only enables data transmission and reception, it
+* does not enable the Interrupt Generation mechanism. This is done by hcf_action.
+*
+* Disabling has the following effects:
+*!!  ;?????is the following statement really true
+* - it acts as a disconnect on all ports.
+* - The DMA Engine (if applicable) is disabled.
+*
+* For impact of the disable command on the behavior of hcf_dma_tx/rx_get see the appropriate sections.
+*
+* Although the Enable/Disable and Connect/Disconnect are antonyms, there is no restriction on their sequencing,
+* in other words, they may be called multiple times in arbitrary sequence without being paired or balanced.
+* Each time one of these functions is called, the effects of the preceding calls cease.
+*
+* Assert fails if
+* - ifbp has a recognizable out-of-range value.
+* - NIC interrupts are not disabled.
+* - A command other than Continue, Enable, Disable, Connect or Disconnect is given.
+* - An invalid combination of the subfields is given or a bit outside the subfields is given.
+* - any return code besides HCF_SUCCESS.
+* - reentrancy, may be  caused by calling a hcf_function without adequate protection against NIC interrupts or
+*	multi-threading
+*
+*.DIAGRAM
+*	hcf_cntl takes successively the following actions:
+*2:	If the HCF is in Defunct mode or incompatible with the Primary or Station Supplier in the Hermes,
+*	hcf_cntl() returns immediately with HCF_ERR_NO_NIC;? as status.
+*8:	when the port is disabled, the DMA engine needs to be de-activated, so the host can safely reclaim tx
+*	packets from the tx descriptor chain.
+*
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+int
+hcf_cntl( IFBP ifbp, hcf_16 cmd )
+{
+int	rc = HCF_ERR_INCOMP_FW;
+#if HCF_ASSERT
+{	int x = cmd & HCMD_CMD_CODE;
+	if ( x == HCF_CNTL_CONTINUE ) x &= ~HCMD_RETRY;
+	else if ( (x == HCMD_DISABLE || x == HCMD_ENABLE) && ifbp->IFB_FWIdentity.comp_id == COMP_ID_FW_AP ) {
+		x &= ~HFS_TX_CNTL_PORT;
+	}
+	HCFASSERT( x==HCF_CNTL_ENABLE  || x==HCF_CNTL_DISABLE    || HCF_CNTL_CONTINUE ||
+			   x==HCF_CNTL_CONNECT || x==HCF_CNTL_DISCONNECT, cmd )
+}
+#endif // HCF_ASSERT
+// #if (HCF_SLEEP) & HCF_DDS
+// 	HCFASSERT( ifbp->IFB_IntOffCnt != 0xFFFE, cmd )
+// #endif // HCF_DDS
+	HCFLOGENTRY( HCF_TRACE_CNTL, cmd )
+	if ( ifbp->IFB_CardStat == 0 ) {																 /*2*/
+/*6*/	rc = cmd_exe( ifbp, cmd, 0 );
+#if (HCF_SLEEP) & HCF_DDS
+		ifbp->IFB_TickCnt = 0;				//start 2 second period (with 1 tick uncertanty)
+#endif // HCF_DDS
+	}
+#if HCF_DMA
+	//!rlav : note that this piece of code is always executed, regardless of the DEFUNCT bit in IFB_CardStat.
+	// The reason behind this is that the MSF should be able to get all its DMA resources back from the HCF,
+	// even if the hardware is disfunctional. Practical example under Windows : surprise removal.
+	if ( ifbp->IFB_CntlOpt & USE_DMA ) {
+		hcf_io io_port = ifbp->IFB_IOBase;
+		DESC_STRCT *p;
+		if ( cmd == HCF_CNTL_DISABLE || cmd == HCF_CNTL_ENABLE ) {
+			OUT_PORT_DWORD( (io_port + HREG_DMA_CTRL), DMA_CTRLSTAT_RESET);						/*8*/
+			ifbp->IFB_CntlOpt &= ~DMA_ENABLED;
+		}
+		if ( cmd == HCF_CNTL_ENABLE ) {
+			OUT_PORT_DWORD( (io_port + HREG_DMA_CTRL), DMA_CTRLSTAT_GO);
+			/* ;? by rewriting hcf_dma_rx_put you can probably just call hcf_dma_rx_put( ifbp->IFB_FirstDesc[DMA_RX] )
+			 * as additional beneficiary side effect, the SOP and EOP bits will also be cleared
+			 */
+			ifbp->IFB_CntlOpt |= DMA_ENABLED;
+			HCFASSERT( NT_ASSERT, NEVER_TESTED )
+			// make the entire rx descriptor chain DMA-owned, so the DMA engine can (re-)use it.
+			if ( ( p = ifbp->IFB_FirstDesc[DMA_RX] ) != NULL ) {   //;? Think this over again in the light of the new chaining strategy
+				if ( 1 ) 	{ //begin alternative
+					HCFASSERT( NT_ASSERT, NEVER_TESTED )
+					put_frame_lst( ifbp, ifbp->IFB_FirstDesc[DMA_RX], DMA_RX );
+					if ( ifbp->IFB_FirstDesc[DMA_RX] ) {
+						put_frame_lst( ifbp, ifbp->IFB_FirstDesc[DMA_RX]->next_desc_addr, DMA_RX );
+					}
+				} else {
+					while ( p ) {
+						//p->buf_cntl.cntl_stat |= DESC_DMA_OWNED;
+						p->BUF_CNT |= DESC_DMA_OWNED;
+						p = p->next_desc_addr;
+					}
+					// a rx chain is available so hand it over to the DMA engine
+					p = ifbp->IFB_FirstDesc[DMA_RX];
+					OUT_PORT_DWORD( (io_port + HREG_RXDMA_PTR32), p->desc_phys_addr);
+				}  //end alternative
+			}
+		}
+	}
+#endif // HCF_DMA
+	HCFASSERT( rc == HCF_SUCCESS, rc )
+	HCFLOGEXIT( HCF_TRACE_CNTL )
+	return rc;
+} // hcf_cntl
+
+
+/************************************************************************************************************
+*
+*.MODULE		int hcf_connect( IFBP ifbp, hcf_io io_base )
+*.PURPOSE		Grants access right for the HCF to the IFB.
+*				Initializes Card and HCF housekeeping.
+*
+*.ARGUMENTS
+*	ifbp		(near) address of the Interface Block
+*	io_base		non-USB: I/O Base address of the NIC (connect)
+*				non-USB: HCF_DISCONNECT
+*				USB:	 HCF_CONNECT, HCF_DISCONNECT
+*
+*.RETURNS
+*	HCF_SUCCESS
+*	HCF_ERR_INCOMP_PRI
+*	HCF_ERR_INCOMP_FW
+*	HCF_ERR_DEFUNCT_CMD_SEQ
+*!!	HCF_ERR_NO_NIC really returned ;?
+*	HCF_ERR_NO_NIC
+*	HCF_ERR_TIME_OUT
+*
+*	MSF-accessible fields of Result Block:
+*	IFB_IOBase				entry parameter io_base
+*	IFB_IORange				HREG_IO_RANGE (0x40/0x80)
+*	IFB_Version				version of the IFB layout
+*	IFB_FWIdentity			CFG_FW_IDENTITY_STRCT, specifies the identity of the
+*							"running" F/W, i.e. tertiary F/W under normal conditions
+*	IFB_FWSup				CFG_SUP_RANGE_STRCT, specifies the supplier range of
+*							the "running" F/W, i.e. tertiary F/W under normal conditions
+*	IFB_HSISup				CFG_SUP_RANGE_STRCT, specifies the HW/SW I/F range of the NIC
+*	IFB_PRIIdentity			CFG_PRI_IDENTITY_STRCT, specifies the Identity of the Primary F/W
+*	IFB_PRISup				CFG_SUP_RANGE_STRCT, specifies the supplier range of the Primary F/W
+*	all other				all MSF accessible fields, which are not specified above, are zero-filled
+*
+*.CONDITIONS
+* It is the responsibility of the MSF to assure the correctness of the I/O Base address.
+*
+* Note: hcf_connect defaults to NIC interrupt disabled mode, i.e. as if hcf_action( HCF_ACT_INT_OFF )
+* was called.
+*
+*.DESCRIPTION
+* hcf_connect passes the MSF-defined location of the IFB to the HCF and grants or revokes access right for the
+* HCF to the IFB. Revoking is done by specifying HCF_DISCONNECT rather than an I/O address for the parameter
+* io_base.  Every call of hcf_connect in "connect" mode, must eventually be followed by a call of hcf_connect
+* in "disconnect" mode. Clalling hcf_connect in "connect"/"disconnect" mode can not be nested.
+* The IFB address must be used as a handle with all subsequent HCF-function calls and the HCF uses the IFB
+* address as a handle when it performs a call(back) of an MSF-function (i.e. msf_assert).
+*
+* Note that not only the MSF accessible fields are cleared, but also all internal housekeeping
+* information is re-initialized.
+* This implies that all settings which are done via hcf_action and hcf_put_info (e.g. CFG_MB_ASSERT, CFG_REG_MB,
+* CFG_REG_INFO_LOG) must be done again. The only field which is not cleared, is IFB_MSFSup.
+*
+* If HCF_INT_ON is selected as compile option, NIC interrupts are disabled.
+*
+* Assert fails if
+* - ifbp is not properly aligned ( ref chapter HCF_ALIGN in 4.1.1)
+* - I/O Base Address is not a multiple of 0x40 (note: 0x0000 is explicitly allowed).
+*
+*.DIAGRAM
+*
+*0:	Throughout hcf_connect you need to distinguish the connect from the disconnect case, which requires
+*	some attention about what to use as "I/O" address when for which purpose.
+*2:
+*2a: Reset H-II by toggling reset bit in IO-register on and off.
+*	The HCF_TYPE_PRELOADED caters for the DOS environment where H-II is loaded by a separate program to
+*	overcome the 64k size limit posed on DOS drivers.
+*	The macro OPW is not yet useable because the IFB_IOBase field is not set.
+*	Note 1: hopefully the clearing and initializing of the IFB (see below) acts as a delay which meets the
+*	specification for S/W reset
+*	Note 2: it turns out that on some H/W constellations, the clock to access the EEProm is not lowered
+*	to an appropriate frequency by HREG_IO_SRESET. By giving an HCMD_INI first, this problem is worked around.
+*2b: Experimentally it is determined over a wide range of F/W versions that waiting for the for Cmd bit in
+*	Ev register gives a workable strategy. The available documentation does not give much clues.
+*4:	clear and initialize the IFB
+*	The HCF house keeping info is designed such that zero is the appropriate initial value for as much as
+*	feasible IFB-items.
+*	The readable fields mentioned in the description section and some HCF specific fields are given their
+*	actual value.
+*	IFB_TickIni is initialized at best guess before calibration
+*	Hcf_connect defaults to "no interrupt generation" (implicitly achieved by the zero-filling).
+*6:	Register compile-time linked MSF Routine and set default filter level
+*	cast needed to get around the "near" problem in DOS COM model
+*	er C2446: no conversion from void (__near __cdecl *)(unsigned char __far *,unsigned int,unsigned short,int)
+*							to   void (__far  __cdecl *)(unsigned char __far *,unsigned int,unsigned short,int)
+*8:	If a command is apparently still active (as indicated by the Busy bit in Cmd register) this may indicate a
+*	blocked cmd pipe line.  To unblock the following actions are done:
+*	 - Ack everything
+*	 - Wait for Busy bit drop  in Cmd register
+*	 - Wait for Cmd  bit raise in Ev  register
+*	The two waits are combined in a single HCF_WAIT_WHILE to optimize memory size. If either of these waits
+*	fail (prot_cnt becomes 0), then something is serious wrong. Rather than PANICK, the assumption is that the
+*	next cmd_exe will fail, causing the HCF to go into DEFUNCT mode
+*10:	Ack everything to unblock a (possibly blocked) cmd pipe line
+*	Note 1: it is very likely that an Alloc event is pending and very well possible that a (Send) Cmd event is
+*	pending on non-initial calls
+*	Note 2: it is assumed that this strategy takes away the need to ack every conceivable event after an
+*	Hermes Initialize
+*12:	Only H-II NEEDS the Hermes Initialize command. Due to the different semantics for H-I and H-II
+*	Initialize command, init() does not (and can not, since it is called e.g. after a download) execute the
+*	Hermes Initialize command. Executing the Hermes Initialize command for H-I would not harm but not do
+*	anything useful either, so it is skipped.
+*	The return status of cmd_exe is ignored. It is assumed that if cmd_exe fails, init fails too
+*14:	use io_base as a flag to merge hcf_connect and hcf_disconnect into 1 routine
+*	the call to init and its subsequent call of cmd_exe will return HCF_ERR_NO_NIC if appropriate. This status
+*	is (badly) needed by some legacy combination of NT4 and card services which do not yield an I/O address in
+*	time.
+*
+*.NOTICE
+*	On platforms where the NULL-pointer is not a bit-pattern of all zeros, the zero-filling of the IFB results
+*	in an incorrect initialization of pointers.
+*	The implementation of the MailBox manipulation in put_mb_info protects against the absence of a MailBox
+*	based on IFB_MBSize, IFB_MBWp and ifbp->IFB_MBRp. This has ramifications on the initialization of the
+*	MailBox via hcf_put_info with the CFG_REG_MB type, but it prevents dependency on the "NULL-"ness of
+*	IFB_MBp.
+*
+*.NOTICE
+*	There are a number of problems when asserting and logging hcf_connect, e.g.
+*	 - Asserting on re-entrancy of hcf_connect by means of
+*	 "HCFASSERT( (ifbp->IFB_AssertTrace & HCF_ASSERT_CONNECT) == 0, 0 )" is not useful because IFB contents
+*	 are undefined
+*	 - Asserting before the IFB is cleared will cause mdd_assert() to interpret the garbage in IFB_AssertRtn
+*	 as a routine address
+*	Therefore HCFTRACE nor HCFLOGENTRY is called by hcf_connect.
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+int
+hcf_connect( IFBP ifbp, hcf_io io_base )
+{
+int			rc = HCF_SUCCESS;
+hcf_io		io_addr;
+hcf_32		prot_cnt;
+hcf_8		*q;
+LTV_STRCT	x;
+#if HCF_ASSERT
+	hcf_16 xa = ifbp->IFB_FWIdentity.typ;
+	/* is assumed to cause an assert later on if hcf_connect is called without intervening hcf_disconnect.
+	 * xa == CFG_FW_IDENTITY in subsequent calls without preceding hcf_disconnect,
+	 * xa == 0 in subsequent calls with preceding hcf_disconnect,
+	 * xa == "garbage" (any value except CFG_FW_IDENTITY is acceptable) in the initial call
+	 */
+#endif // HCF_ASSERT
+
+	if ( io_base == HCF_DISCONNECT ) {					//disconnect
+		io_addr = ifbp->IFB_IOBase;
+		OPW( HREG_INT_EN, 0 );		//;?workaround against dying F/W on subsequent hcf_connect calls
+	} else {											//connect								/* 0 */
+		io_addr = io_base;
+	}
+
+#if 0 //;? if a subsequent hcf_connect is preceeded by an hcf_disconnect the wakeup is not needed !!
+#if HCF_SLEEP
+    OUT_PORT_WORD( .....+HREG_IO, HREG_IO_WAKEUP_ASYNC ); 	    //OPW not yet useable
+	MSF_WAIT(800);								// MSF-defined function to wait n microseconds.
+	note that MSF_WAIT uses not yet defined!!!! IFB_IOBase and IFB_TickIni (via PROT_CNT_INI)
+	so be carefull if this code is restored
+#endif // HCF_SLEEP
+#endif // 0
+
+#if ( (HCF_TYPE) & HCF_TYPE_PRELOADED ) == 0	//switch clock back for SEEPROM access  !!!
+	OUT_PORT_WORD( io_addr + HREG_CMD, HCMD_INI );  	    //OPW not yet useable
+	prot_cnt = INI_TICK_INI;
+	HCF_WAIT_WHILE( (IN_PORT_WORD( io_addr +  HREG_EV_STAT) & HREG_EV_CMD) == 0 );
+	OUT_PORT_WORD( (io_addr + HREG_IO), HREG_IO_SRESET );	//OPW not yet useable					/* 2a*/
+#endif // HCF_TYPE_PRELOADED
+	for ( q = (hcf_8*)(&ifbp->IFB_Magic); q > (hcf_8*)ifbp; *--q = 0 ) /*NOP*/;						/* 4 */
+	ifbp->IFB_Magic		= HCF_MAGIC;
+	ifbp->IFB_Version	= IFB_VERSION;
+#if defined MSF_COMPONENT_ID //a new IFB demonstrates how dirty the solution is
+	xxxx[xxxx_PRI_IDENTITY_OFFSET] = NULL;		//IFB_PRIIdentity placeholder	0xFD02
+	xxxx[xxxx_PRI_IDENTITY_OFFSET+1] = NULL;	//IFB_PRISup placeholder		0xFD03
+#endif // MSF_COMPONENT_ID
+#if (HCF_TALLIES) & ( HCF_TALLIES_NIC | HCF_TALLIES_HCF )
+	ifbp->IFB_TallyLen = 1 + 2 * (HCF_NIC_TAL_CNT + HCF_HCF_TAL_CNT);	//convert # of Tallies to L value for LTV
+	ifbp->IFB_TallyTyp = CFG_TALLIES;			//IFB_TallyTyp: set T value
+#endif // HCF_TALLIES_NIC / HCF_TALLIES_HCF
+	ifbp->IFB_IOBase	= io_addr;				//set IO_Base asap, so asserts via HREG_SW_2 don't harm
+	ifbp->IFB_IORange	= HREG_IO_RANGE;
+	ifbp->IFB_CntlOpt	= USE_16BIT;
+#if HCF_ASSERT
+	assert_ifbp = ifbp;
+	ifbp->IFB_AssertLvl = 1;
+#if (HCF_ASSERT) & HCF_ASSERT_LNK_MSF_RTN
+	if ( io_base != HCF_DISCONNECT ) {
+		ifbp->IFB_AssertRtn = (MSF_ASSERT_RTNP)msf_assert;											/* 6 */
+	}
+#endif // HCF_ASSERT_LNK_MSF_RTN
+#if (HCF_ASSERT) & HCF_ASSERT_MB				//build the structure to pass the assert info to hcf_put_info
+	ifbp->IFB_AssertStrct.len = sizeof(ifbp->IFB_AssertStrct)/sizeof(hcf_16) - 1;
+	ifbp->IFB_AssertStrct.typ = CFG_MB_INFO;
+	ifbp->IFB_AssertStrct.base_typ = CFG_MB_ASSERT;
+	ifbp->IFB_AssertStrct.frag_cnt = 1;
+	ifbp->IFB_AssertStrct.frag_buf[0].frag_len =
+		( offsetof(IFB_STRCT, IFB_AssertLvl) - offsetof(IFB_STRCT, IFB_AssertLine) ) / sizeof(hcf_16);
+	ifbp->IFB_AssertStrct.frag_buf[0].frag_addr = &ifbp->IFB_AssertLine;
+#endif // HCF_ASSERT_MB
+#endif // HCF_ASSERT
+	IF_PROT_TIME( prot_cnt = ifbp->IFB_TickIni = INI_TICK_INI; )
+#if ( (HCF_TYPE) & HCF_TYPE_PRELOADED ) == 0
+	//!! No asserts before Reset-bit in HREG_IO is cleared
+	OPW( HREG_IO, 0x0000 );						//OPW useable										/* 2b*/
+	HCF_WAIT_WHILE( (IPW( HREG_EV_STAT) & HREG_EV_CMD) == 0 );
+	IF_PROT_TIME( HCFASSERT( prot_cnt, IPW( HREG_EV_STAT) ) )
+	IF_PROT_TIME( if ( prot_cnt ) prot_cnt = ifbp->IFB_TickIni; )
+#endif // HCF_TYPE_PRELOADED
+	//!! No asserts before Reset-bit in HREG_IO is cleared
+	HCFASSERT( DO_ASSERT, MERGE_2( HCF_ASSERT, 0xCAF0 )	) //just to proof that the complete assert machinery is working
+	HCFASSERT( xa != CFG_FW_IDENTITY, 0 )		// assert if hcf_connect is called without intervening hcf_disconnect.
+	HCFASSERT( ((hcf_32)(void*)ifbp & (HCF_ALIGN-1) ) == 0, (hcf_32)(void*)ifbp )
+	HCFASSERT( (io_addr & 0x003F) == 0, io_addr )
+												//if Busy bit in Cmd register
+	if (IPW( HREG_CMD ) & HCMD_BUSY ) {																/* 8 */
+												//.  Ack all to unblock a (possibly) blocked cmd pipe line
+		OPW( HREG_EV_ACK, ~HREG_EV_SLEEP_REQ );
+												//.  Wait for Busy bit drop  in Cmd register
+												//.  Wait for Cmd  bit raise in Ev  register
+		HCF_WAIT_WHILE( ( IPW( HREG_CMD ) & HCMD_BUSY ) && (IPW( HREG_EV_STAT) & HREG_EV_CMD) == 0 );
+		IF_PROT_TIME( HCFASSERT( prot_cnt, IPW( HREG_EV_STAT) ) ) /* if prot_cnt == 0, cmd_exe will fail, causing DEFUNCT */
+	}
+	OPW( HREG_EV_ACK, ~HREG_EV_SLEEP_REQ );
+#if ( (HCF_TYPE) & HCF_TYPE_PRELOADED ) == 0														/*12*/
+	(void)cmd_exe( ifbp, HCMD_INI, 0 );
+#endif // HCF_TYPE_PRELOADED
+if ( io_base != HCF_DISCONNECT ) {
+		rc = init( ifbp );																			/*14*/
+		if ( rc == HCF_SUCCESS ) {
+			x.len = 2;
+			x.typ = CFG_NIC_BUS_TYPE;
+			(void)hcf_get_info( ifbp, &x );
+			ifbp->IFB_BusType = x.val[0];
+			//CFG_NIC_BUS_TYPE not supported -> default 32 bits/DMA, MSF has to overrule via CFG_CNTL_OPT
+			if ( x.len == 0 || x.val[0] == 0x0002 || x.val[0] == 0x0003 ) {
+#if (HCF_IO) & HCF_IO_32BITS
+				ifbp->IFB_CntlOpt &= ~USE_16BIT;			//reset USE_16BIT
+#endif // HCF_IO_32BITS
+#if HCF_DMA
+				ifbp->IFB_CntlOpt |= USE_DMA;				//SET DMA
+#else
+				ifbp->IFB_IORange = 0x40 /*i.s.o. HREG_IO_RANGE*/;
+#endif // HCF_DMA
+			}
+		}
+	} else HCFASSERT(  ( ifbp->IFB_Magic ^= HCF_MAGIC ) == 0, ifbp->IFB_Magic ) /*NOP*/;
+	/* of above HCFASSERT only the side effect is needed, NOP in case HCFASSERT is dummy */
+	ifbp->IFB_IOBase = io_base;																		/* 0*/
+	return rc;
+} // hcf_connect
+
+#if HCF_DMA
+/************************************************************************************************************
+* Function get_frame_lst
+*  - resolve the "last host-owned descriptor" problems when a descriptor list is reclaimed by the MSF.
+*
+* The FrameList to be reclaimed as well as the DescriptorList always start in IFB_FirstDesc[tx_rx_flag]
+* and this is always the "current" DELWA Descriptor.
+*
+* If a FrameList is available, the last descriptor of the FrameList to turned into a new DELWA Descriptor:
+*  - a copy is made from the information in the last descriptor of the FrameList into the current
+*	 DELWA Descriptor
+*  - the remainder of the DescriptorList is detached from the copy by setting the next_desc_addr at NULL
+*  - the DMA control bits of the copy are cleared to do not confuse the MSF
+*  - the copy of the last descriptor (i.e. the "old" DELWA Descriptor) is chained to the prev Descriptor
+*	 of the FrameList, thus replacing the original last Descriptor of the FrameList.
+*  - IFB_FirstDesc is changed to the address of that replaced (original) last descriptor of the FrameList,
+*	 i.e. the "new" DELWA Descriptor.
+*
+* This function makes a copy of that last host-owned descriptor, so the MSF will get a copy of the descriptor.
+* On top of that, it adjusts DMA related fields in the IFB structure.
+	// perform a copying-scheme to circumvent the 'last host owned descriptor cannot be reclaimed' limitation imposed by H2.5's DMA hardware design
+	// a 'reclaim descriptor' should be available in the HCF:
+*
+* Returns: address of the first descriptor of the FrameList
+*
+ 8: Be careful once you start re-ordering the steps in the copy process, that it still works for cases
+* 	of FrameLists of 1, 2 and more than 2 descriptors
+*
+* Input parameters:
+* tx_rx_flag      : specifies 'transmit' or 'receive' descriptor.
+*
+************************************************************************************************************/
+HCF_STATIC DESC_STRCT*
+get_frame_lst( IFBP ifbp, int tx_rx_flag )
+{
+
+DESC_STRCT *head = ifbp->IFB_FirstDesc[tx_rx_flag];
+DESC_STRCT *copy, *p, *prev;
+
+	HCFASSERT( tx_rx_flag == DMA_RX || tx_rx_flag == DMA_TX, tx_rx_flag )
+								//if FrameList
+	if ( head ) {
+								//.  search for last descriptor of first FrameList
+		p = prev = head;
+		while ( ( p->BUF_SIZE & DESC_EOP ) == 0 && p->next_desc_addr ) {
+			if ( ( ifbp->IFB_CntlOpt & DMA_ENABLED ) == 0 ) {	//clear control bits when disabled
+				p->BUF_CNT &= DESC_CNT_MASK;
+			}
+			prev = p;
+			p = p->next_desc_addr;
+		}
+								//.  if DMA enabled
+		if ( ifbp->IFB_CntlOpt & DMA_ENABLED ) {
+								//.  .  if last descriptor of FrameList is DMA owned
+								//.  .  or if FrameList is single (DELWA) Descriptor
+			if ( p->BUF_CNT & DESC_DMA_OWNED || head->next_desc_addr == NULL ) {
+								//.  .  .  refuse to return FrameList to caller
+				head = NULL;
+			}
+		}
+	}
+								//if returnable FrameList found
+	if ( head ) {
+								//.  if FrameList is single (DELWA) Descriptor (implies DMA disabled)
+ 		if ( head->next_desc_addr == NULL ) {
+								//.  .  clear DescriptorList
+			/*;?ifbp->IFB_LastDesc[tx_rx_flag] =*/ ifbp->IFB_FirstDesc[tx_rx_flag] = NULL;
+								//.  else
+		} else {
+								//.  .  strip hardware-related bits from last descriptor
+								//.  .  remove DELWA Descriptor from head of DescriptorList
+			copy = head;
+	 		head = head->next_desc_addr;
+								//.   .  exchange first (Confined) and last (possibly imprisoned) Descriptor
+			copy->buf_phys_addr = p->buf_phys_addr;
+			copy->buf_addr = p->buf_addr;
+			copy->BUF_SIZE = p->BUF_SIZE &= DESC_CNT_MASK;	//get rid of DESC_EOP and possibly DESC_SOP
+			copy->BUF_CNT = p->BUF_CNT &= DESC_CNT_MASK;	//get rid of DESC_DMA_OWNED
+#if (HCF_EXT) & HCF_DESC_STRCT_EXT
+			copy->DESC_MSFSup = p->DESC_MSFSup;
+#endif // HCF_DESC_STRCT_EXT
+								//.  .  turn into a DELWA Descriptor
+			p->buf_addr = NULL;
+								//.  .  chain copy to prev											/* 8*/
+			prev->next_desc_addr = copy;
+								//.  .  detach remainder of the DescriptorList from FrameList
+			copy->next_desc_addr = NULL;
+			copy->next_desc_phys_addr = 0xDEAD0000; //! just to be nice, not really needed
+								//.  .  save the new start (i.e. DELWA Descriptor) in IFB_FirstDesc
+			ifbp->IFB_FirstDesc[tx_rx_flag] = p;
+		}
+								//.  strip DESC_SOP from first descriptor
+		head->BUF_SIZE &= DESC_CNT_MASK;
+		//head->BUF_CNT &= DESC_CNT_MASK;  get rid of DESC_DMA_OWNED
+		head->next_desc_phys_addr = 0xDEAD0000; //! just to be nice, not really needed
+	}
+								//return the just detached FrameList (if any)
+	return head;
+} // get_frame_lst
+
+
+/************************************************************************************************************
+* Function put_frame_lst
+*
+* This function
+*
+* Returns: address of the first descriptor of the FrameList
+*
+* Input parameters:
+* tx_rx_flag      : specifies 'transmit' or 'receive' descriptor.
+*
+* The following list should be kept in sync with hcf_dma_tx/rx_put, in order to get them in the WCI-spec !!!!
+* Assert fails if
+* -	DMA is not enabled
+* -	descriptor list is NULL
+* -	a descriptor in the descriptor list is not double word aligned
+* -	a count of size field of a descriptor contains control bits, i.e. bits in the high order nibble.
+* -	the DELWA descriptor is not a "singleton" DescriptorList.
+* -	the DELWA descriptor is not the first Descriptor supplied
+* -	a non_DMA descriptor is supplied before the DELWA Descriptor is supplied
+* -	Possibly more checks could be added !!!!!!!!!!!!!
+
+*.NOTICE
+* The asserts marked with *sc* are really sanity checks for the HCF, they can (supposedly) not be influenced
+* by incorrect MSF behavior
+
+		// The MSF is required to supply the HCF with a single descriptor for MSF tx reclaim purposes.
+		// This 'reclaim descriptor' can be recognized by the fact that its buf_addr field is zero.
+	*********************************************************************************************
+	* Although not required from a hardware perspective:
+	* - make each descriptor in this rx-chain DMA-owned.
+	* - Also set the count to zero. EOP and SOP bits are also cleared.
+	*********************************************************************************************/
+HCF_STATIC void
+put_frame_lst( IFBP ifbp, DESC_STRCT *descp, int tx_rx_flag )
+{
+	DESC_STRCT	*p = descp;
+	hcf_16 port;
+
+	HCFASSERT( ifbp->IFB_CntlOpt & USE_DMA, ifbp->IFB_CntlOpt) //only hcf_dma_tx_put must also be DMA_ENABLED
+	HCFASSERT( tx_rx_flag == DMA_RX || tx_rx_flag == DMA_TX, tx_rx_flag )
+	HCFASSERT( p , 0 )
+
+	while ( p ) {
+		HCFASSERT( ((hcf_32)p & 3 ) == 0, (hcf_32)p )
+		HCFASSERT( (p->BUF_CNT & ~DESC_CNT_MASK) == 0, p->BUF_CNT )
+		HCFASSERT( (p->BUF_SIZE & ~DESC_CNT_MASK) == 0, p->BUF_SIZE )
+		p->BUF_SIZE &= DESC_CNT_MASK;					//!!this SHOULD be superfluous in case of correct MSF
+		p->BUF_CNT &= tx_rx_flag == DMA_RX ? 0 : DESC_CNT_MASK;	//!!this SHOULD be superfluous in case of correct MSF
+		p->BUF_CNT |= DESC_DMA_OWNED;
+		if ( p->next_desc_addr ) {
+//			HCFASSERT( p->buf_addr && p->buf_phys_addr  && p->BUF_SIZE && +/- p->BUF_SIZE, ... )
+			HCFASSERT( p->next_desc_addr->desc_phys_addr, (hcf_32)p->next_desc_addr )
+			p->next_desc_phys_addr = p->next_desc_addr->desc_phys_addr;
+		} else {									//
+			p->next_desc_phys_addr = 0;
+			if ( p->buf_addr == NULL ) {			// DELWA Descriptor
+				HCFASSERT( descp == p, (hcf_32)descp )	//singleton DescriptorList
+				HCFASSERT( ifbp->IFB_FirstDesc[tx_rx_flag] == NULL, (hcf_32)ifbp->IFB_FirstDesc[tx_rx_flag])
+				HCFASSERT( ifbp->IFB_LastDesc[tx_rx_flag] == NULL, (hcf_32)ifbp->IFB_LastDesc[tx_rx_flag])
+				descp->BUF_CNT = 0; //&= ~DESC_DMA_OWNED;
+				ifbp->IFB_FirstDesc[tx_rx_flag] = descp;
+// part of alternative ifbp->IFB_LastDesc[tx_rx_flag] = ifbp->IFB_FirstDesc[tx_rx_flag] = descp;
+													// if "recycling" a FrameList
+													// (e.g. called from hcf_cntl( HCF_CNTL_ENABLE )
+													// .  prepare for activation DMA controller
+// part of alternative descp = descp->next_desc_addr;
+			} else {								//a "real" FrameList, hand it over to the DMA engine
+				HCFASSERT( ifbp->IFB_FirstDesc[tx_rx_flag], (hcf_32)descp )
+				HCFASSERT( ifbp->IFB_LastDesc[tx_rx_flag], (hcf_32)descp )
+				HCFASSERT( ifbp->IFB_LastDesc[tx_rx_flag]->next_desc_addr == NULL,
+						   (hcf_32)ifbp->IFB_LastDesc[tx_rx_flag]->next_desc_addr)
+//				p->buf_cntl.cntl_stat |= DESC_DMA_OWNED;
+				ifbp->IFB_LastDesc[tx_rx_flag]->next_desc_addr = descp;
+				ifbp->IFB_LastDesc[tx_rx_flag]->next_desc_phys_addr = descp->desc_phys_addr;
+				port = HREG_RXDMA_PTR32;
+				if ( tx_rx_flag ) {
+					p->BUF_SIZE |= DESC_EOP;	// p points at the last descriptor in the caller-supplied descriptor chain
+					descp->BUF_SIZE |= DESC_SOP;
+					port = HREG_TXDMA_PTR32;
+				}
+				OUT_PORT_DWORD( (ifbp->IFB_IOBase + port), descp->desc_phys_addr );
+			}
+			ifbp->IFB_LastDesc[tx_rx_flag] = p;
+		}
+		p = p->next_desc_addr;
+	}
+} // put_frame_lst
+
+
+/************************************************************************************************************
+*
+*.MODULE		DESC_STRCT* hcf_dma_rx_get( IFBP ifbp )
+*.PURPOSE		decapsulate a message and provides that message to the MSF.
+*				reclaim all descriptors in the rx descriptor chain.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*
+*.RETURNS
+*	pointer to a FrameList
+*
+*.DESCRIPTION
+* hcf_dma_rx_get is intended to  return a received frame when such a frame is deposited in Host memory by the
+* DMA engine. In addition hcf_dma_rx_get can be used to reclaim all descriptors in the rx descriptor chain
+* when the DMA Engine is disabled, e.g. as part of a driver unloading strategy.
+* hcf_dma_rx_get must be called repeatedly by the MSF when hcf_service_nic signals availability of a rx frame
+* through the HREG_EV_RDMAD flag of IFB_DmaPackets. The calling must stop when a NULL pointer is returned, at
+* which time the HREG_EV_RDMAD flag is also cleared by the HCF to arm the mechanism for the next frame
+* reception.
+* Regardless whether the DMA Engine is currently enabled (as controlled via hcf_cntl), if the DMA controller
+* deposited an Rx-frame in the Rx-DescriptorList, this frame is detached from the Rx-DescriptorList,
+* transformed into a FrameList (i.e.  updating the housekeeping fields in the descriptors) and returned to the
+* caller.
+* If no such Rx-frame is available in the Rx-DescriptorList, the behavior of hcf_dma_rx_get depends on the
+* status of the DMA Engine.
+* If the DMA Engine is enabled, a NULL pointer is returned.
+* If the DMA Engine is disabled, the following strategy is used:
+* - the complete Rx-DescriptorList is returned. The DELWA Descriptor is not part of the Rx-DescriptorList.
+* - If there is no Rx-DescriptorList, the DELWA Descriptor is returned.
+* - If there is no DELWA Descriptor, a NULL pointer is returned.
+*
+* If the MSF performs an disable/enable sequence without exhausting the Rx-DescriptorList as described above,
+* the enable command will reset all house keeping information, i.e. already received but not yet by the MSF
+* retrieved frames are lost and the next frame will be received starting with the oldest descriptor.
+*
+* The HCF can be used in 2 fashions: with and without decapsulation for data transfer.
+* This is controlled at compile time by the HCF_ENC bit of the HCF_ENCAP system constant.
+* If appropriate, decapsulation is done by moving some data inside the buffers and updating the descriptors
+* accordingly.
+*!! ;?????where did I describe why a simple manipulation with the count values does not suffice?
+*
+*.DIAGRAM
+*
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+
+DESC_STRCT*
+hcf_dma_rx_get (IFBP ifbp)
+{
+DESC_STRCT *descp;	// pointer to start of FrameList
+
+	descp = get_frame_lst( ifbp, DMA_RX );
+	if ( descp && descp->buf_addr )  //!be aware of the missing curly bracket
+
+											//skip decapsulation at confined descriptor
+#if (HCF_ENCAP) == HCF_ENC
+#if (HCF_TYPE) & HCF_TYPE_CCX
+	if ( ifbp->IFB_CKIPStat == HCF_ACT_CCX_OFF )
+#endif // HCF_TYPE_CCX
+    {
+int i;
+DESC_STRCT *p = descp->next_desc_addr;	//pointer to 2nd descriptor of frame
+		HCFASSERT(p, 0)
+		// The 2nd descriptor contains (maybe) a SNAP header plus part or whole of the payload.
+		//determine decapsulation sub-flag in RxFS
+		i = *(wci_recordp)&descp->buf_addr[HFS_STAT] & ( HFS_STAT_MSG_TYPE | HFS_STAT_ERR );
+		if ( i == HFS_STAT_TUNNEL ||
+			 ( i == HFS_STAT_1042 && hcf_encap( (wci_bufp)&p->buf_addr[HCF_DASA_SIZE] ) != ENC_TUNNEL )) {
+			// The 2nd descriptor contains a SNAP header plus part or whole of the payload.
+			HCFASSERT( p->BUF_CNT == (p->buf_addr[5] + (p->buf_addr[4]<<8) + 2*6 + 2 - 8), p->BUF_CNT )
+			// perform decapsulation
+			HCFASSERT(p->BUF_SIZE >=8, p->BUF_SIZE)
+			// move SA[2:5] in the second buffer to replace part of the SNAP header
+			for ( i=3; i >= 0; i--) p->buf_addr[i+8] = p->buf_addr[i];
+			// copy DA[0:5], SA[0:1] from first buffer to second buffer
+			for ( i=0; i<8; i++) p->buf_addr[i] = descp->buf_addr[HFS_ADDR_DEST + i];
+			// make first buffer shorter in count
+			descp->BUF_CNT = HFS_ADDR_DEST;
+		}
+	}
+#endif // HCF_ENC
+	if ( descp == NULL ) ifbp->IFB_DmaPackets &= (hcf_16)~HREG_EV_RDMAD;  //;?could be integrated into get_frame_lst
+	HCFLOGEXIT( HCF_TRACE_DMA_RX_GET )
+	return descp;
+} // hcf_dma_rx_get
+
+
+/************************************************************************************************************
+*
+*.MODULE		void hcf_dma_rx_put( IFBP ifbp, DESC_STRCT *descp )
+*.PURPOSE		supply buffers for receive purposes.
+*				supply the Rx-DELWA descriptor.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*	descp		address of a DescriptorList
+*
+*.RETURNS		N.A.
+*
+*.DESCRIPTION
+* This function is called by the MSF to supply the HCF with new/more buffers for receive purposes.
+* The HCF can be used in 2 fashions: with and without encapsulation for data transfer.
+* This is controlled at compile time by the HCF_ENC bit of the HCF_ENCAP system constant.
+* As a consequence, some additional constaints apply to the number of descriptor and the buffers associated
+* with the first 2 descriptors. Independent of the encapsulation feature, the COUNT fields are ignored.
+* A special case is the supplying of the DELWA descriptor, which must be supplied as the first descriptor.
+*
+* Assert fails if
+* - ifbp has a recognizable out-of-range value.
+* - NIC interrupts are not disabled while required by parameter action.
+* - in case decapsulation by the HCF is selected:
+*	  -	The first databuffer does not have the exact size corresponding with the RxFS up to the 802.3 DestAddr
+*		field (== 29 words).
+*	  -	The FrameList does not consists of at least 2 Descriptors.
+*	  -	The second databuffer does not have the minimum size of 8 bytes.
+*!! The 2nd part of the list of asserts should be kept in sync with put_frame_lst, in order to get
+*!! them in the WCI-spec !!!!
+* - DMA is not enabled
+* - descriptor list is NULL
+* - a descriptor in the descriptor list is not double word aligned
+* - a count of size field of a descriptor contains control bits, i.e. bits in the high order nibble.
+* - the DELWA descriptor is not a "singleton" DescriptorList.
+* - the DELWA descriptor is not the first Descriptor supplied
+* - a non_DMA descriptor is supplied before the DELWA Descriptor is supplied
+*!! - Possibly more checks could be added !!!!!!!!!!!!!
+*
+*.DIAGRAM
+*
+*
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+void
+hcf_dma_rx_put( IFBP ifbp, DESC_STRCT *descp )
+{
+
+	HCFLOGENTRY( HCF_TRACE_DMA_RX_PUT, 0xDA01 )
+	HCFASSERT( ifbp->IFB_Magic == HCF_MAGIC, ifbp->IFB_Magic )
+	HCFASSERT_INT
+
+	put_frame_lst( ifbp, descp, DMA_RX );
+#if HCF_ASSERT && (HCF_ENCAP) == HCF_ENC
+	if ( descp->buf_addr ) {
+		HCFASSERT( descp->BUF_SIZE == HCF_DMA_RX_BUF1_SIZE, descp->BUF_SIZE )
+		HCFASSERT( descp->next_desc_addr, 0 ) // first descriptor should be followed by another descriptor
+		// The second DB is for SNAP and payload purposes. It should be a minimum of 12 bytes in size.
+		HCFASSERT( descp->next_desc_addr->BUF_SIZE >= 12, descp->next_desc_addr->BUF_SIZE )
+	}
+#endif // HCFASSERT / HCF_ENC
+	HCFLOGEXIT( HCF_TRACE_DMA_RX_PUT )
+} // hcf_dma_rx_put
+
+
+/************************************************************************************************************
+*
+*.MODULE		DESC_STRCT* hcf_dma_tx_get( IFBP ifbp )
+*.PURPOSE		DMA mode: reclaims and decapsulates packets in the tx descriptor chain if:
+*				 - A Tx packet has been copied from host-RAM into NIC-RAM by the DMA engine
+*				 - The Hermes/DMAengine have been disabled
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*
+*.RETURNS
+*	pointer to a reclaimed Tx packet.
+*
+*.DESCRIPTION
+* impact of the disable command:
+* When a non-empty pool of Tx descriptors exists (created by means of hcf_dma_put_tx), the MSF
+* is supposed to empty that pool by means of hcf_dma_tx_get calls after the disable in an
+* disable/enable sequence.
+*
+*.DIAGRAM
+*
+*.NOTICE
+*
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+DESC_STRCT*
+hcf_dma_tx_get( IFBP ifbp )
+{
+DESC_STRCT *descp;	// pointer to start of FrameList
+
+	descp = get_frame_lst( ifbp, DMA_TX );
+	if ( descp && descp->buf_addr )  //!be aware of the missing curly bracket
+											//skip decapsulation at confined descriptor
+#if (HCF_ENCAP) == HCF_ENC
+		if ( ( descp->BUF_CNT == HFS_TYPE )
+#if (HCF_TYPE) & HCF_TYPE_CCX
+			 || ( descp->BUF_CNT == HFS_DAT )
+#endif // HCF_TYPE_CCX
+		) { // perform decapsulation if needed
+			descp->next_desc_addr->buf_phys_addr -= HCF_DASA_SIZE;
+			descp->next_desc_addr->BUF_CNT 		 += HCF_DASA_SIZE;
+		}
+#endif // HCF_ENC
+	if ( descp == NULL ) {  //;?could be integrated into get_frame_lst
+		ifbp->IFB_DmaPackets &= (hcf_16)~HREG_EV_TDMAD;
+	}
+	HCFLOGEXIT( HCF_TRACE_DMA_TX_GET )
+	return descp;
+} // hcf_dma_tx_get
+
+
+/************************************************************************************************************
+*
+*.MODULE		void hcf_dma_tx_put( IFBP ifbp, DESC_STRCT *descp, hcf_16 tx_cntl )
+*.PURPOSE		puts a packet in the Tx DMA queue in host ram and kicks off the TxDma engine.
+*				supply the Tx-DELWA descriptor.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*	descp		address of Tx Descriptor Chain (i.e. a single Tx frame)
+*	tx_cntl		indicates MAC-port and (Hermes) options
+*
+*.RETURNS		N.A.
+*
+*.DESCRIPTION
+* The HCF can be used in 2 fashions: with and without encapsulation for data transfer.
+* This is controlled at compile time by the HCF_ENC bit of the HCF_ENCAP system constant.
+*
+* Regardless of the HCF_ENCAP system constant, the descriptor list created to describe the frame to be
+* transmitted, must supply space to contain the 802.11 header, preceding the actual frame to be transmitted.
+* Basically, this only supplies working storage to the HCF which passes this on to the DMA engine.
+* As a consequence the contents of this space do not matter.
+* Nevertheless BUF_CNT must take in account this storage.
+* This working space to contain the 802.11 header may not be fragmented, the first buffer must be
+* sufficiently large to contain at least the 802.11 header, i.e. HFS_ADDR_DEST (29 words or 0x3A bytes).
+* This way, the HCF can simply, regardless whether or not the HCF encapsulates the frame, write the parameter
+* tx_cntl at offset 0x36 (HFS_TX_CNTL) in the first buffer.
+* Note that it is allowed to have part or all of the actual frame represented by the first descriptor as long
+* as the requirement for storage for the 802.11 header is met, i.e. the 802.3 frame starts at offset
+* HFS_ADDR_DEST.
+* Except for the Assert on the 1st buffer in case of Encapsualtion, the SIZE fields are ignored.
+*
+* In case the encapsulation feature is compiled in, there are the following additional requirements.
+* o The BUF_CNT of the first buffer changes from a minimum of 0x3A bytes to exactly 0x3A, i.e. the workspace
+*	to store the 802.11 header
+* o The BUF_SIZE of the first buffer is at least the space needed to store the
+*	- 802.11 header (29 words)
+*	- 802.3 header, i.e. 12 bytes addressing information and 2 bytes length field
+*	- 6 bytes SNAP-header
+*   This results in 39 words or 0x4E bytes or HFS_TYPE.
+*   Note that if the BUF_SIZE is larger than 0x4E, this surplus is not used.
+* o The actual frame begins in the 2nd descriptor (which is already implied by the BUF_CNT == 0x3A requirement) and the associated buffer contains at least the 802.3 header, i.e. the 14 bytes representing addressing information and length/type field
+*
+*   When the HCF does not encapsulates (i.e. length/type field <= 1500),  no changes are made to descriptors
+*   or buffers.
+*
+*   When the HCF actually encapsulates (i.e. length/type field > 1500), it successively writes, starting at
+*   offset HFS_ADDR_DEST (0x3A) in the first buffer:
+*     - the 802.3 addressing information, copied from the begin of the second buffer
+*     - the frame length, derived from the total length of the individual fragments, corrected for the SNAP
+*   	header length and Type field and ignoring the Destination Address, Source Address and Length field
+* 	  - the appropriate snap header (Tunnel or 1042, depending on the value of the type field).
+*
+* 	 The information in the first two descriptors is adjusted accordingly:
+* 	  - the first descriptor count is changed from 0x3A to 0x4E (HFS_TYPE), which matches 0x3A + 12 + 2 + 6
+* 	  - the second descriptor count is decreased by 12, being the moved addressing information
+* 	  - the second descriptor (physical) buffer address is increased by 12.
+*
+* When the descriptors are returned by hcf_dma_tx_get, the transformation of the first two descriptors is
+* undone.
+*
+* Under any of the above scenarios, the assert BUF_CNT <= BUF_SIZE must be true for all descriptors
+* In case of encapsulation, BUF_SIZE of the 1st descriptor is asserted to be at least HFS_TYPE (0x4E), so it is NOT tested.
+*
+* Assert fails if
+* - ifbp has a recognizable out-of-range value.
+* - tx_cntl has a recognizable out-of-range value.
+* - NIC interrupts are not disabled while required by parameter action.
+* - in case encapsulation by the HCF is selected:
+*	  -	The FrameList does not consists of at least 2 Descriptors.
+*	  -	The first databuffer does not contain exactly the (space for) the 802.11 header (== 28 words)
+*	  -	The first databuffer does not have a size to additionally accomodate the 802.3 header and the
+*		SNAP header of the frame after encapsulation (== 39 words).
+*	  -	The second databuffer does not contain at least DA, SA and 'type/length' (==14 bytes or 7 words)
+*!! The 2nd part of the list of asserts should be kept in sync with put_frame_lst, in order to get
+*!! them in the WCI-spec !!!!
+* - DMA is not enabled
+* - descriptor list is NULL
+* - a descriptor in the descriptor list is not double word aligned
+* - a count of size field of a descriptor contains control bits, i.e. bits in the high order nibble.
+* - the DELWA descriptor is not a "singleton" DescriptorList.
+* - the DELWA descriptor is not the first Descriptor supplied
+* - a non_DMA descriptor is supplied before the DELWA Descriptor is supplied
+*!! - Possibly more checks could be added !!!!!!!!!!!!!
+*.DIAGRAM
+*
+*.NOTICE
+*
+*.ENDDOC				END DOCUMENTATION
+*
+*
+*1:	Write tx_cntl parameter to HFS_TX_CNTL field into the Hermes-specific header in buffer 1
+*4:	determine whether encapsulation is needed and write the type (tunnel or 1042) already at the appropriate
+*	offset in the 1st buffer
+*6:	Build the encapsualtion enveloppe in the free space at the end of the 1st buffer
+*	- Copy DA/SA fields from the 2nd buffer
+*   - Calculate total length of the message (snap-header + type-field + the length of all buffer fragments
+*     associated with the 802.3 frame (i.e all descriptors except the first), but not the DestinationAddress,
+*     SourceAddress and lenght-field)
+*     Assert the message length
+*	  Write length. Note that the message is in BE format, hence on LE platforms the length must be converted
+*	  ;? THIS IS NOT WHAT CURRENTLY IS IMPLEMENTED
+*	- Write snap header. Note that the last byte of the snap header is NOT copied, that byte is already in
+*	  place as result of the call to hcf_encap.
+*	Note that there are many ways to skin a cat. To express the offsets in the 1st buffer while writing
+*	the snap header, HFS_TYPE is choosen as a reference point to make it easier to grasp that the snap header
+*	and encapsualtion type are at least relative in the right.
+*8:	modify 1st descriptor to reflect moved part of the 802.3 header + Snap-header
+*	modify 2nd descriptor to skip the moved part of the 802.3 header (DA/SA
+*10: set each descriptor to 'DMA owned',  clear all other control bits.
+*	Set SOP bit on first descriptor. Set EOP bit on last descriptor.
+*12: Either append the current frame to an existing descriptor list or
+*14: create a list beginning with the current frame
+*16: remember the new end of the list
+*20: hand the frame over to the DMA engine
+************************************************************************************************************/
+void
+hcf_dma_tx_put( IFBP ifbp, DESC_STRCT *descp, hcf_16 tx_cntl )
+{
+DESC_STRCT	*p = descp->next_desc_addr;
+int			i;
+
+#if HCF_ASSERT
+	int x = ifbp->IFB_FWIdentity.comp_id == COMP_ID_FW_AP ? tx_cntl & ~HFS_TX_CNTL_PORT : tx_cntl;
+	HCFASSERT( (x & ~HCF_TX_CNTL_MASK ) == 0, tx_cntl )
+#endif // HCF_ASSERT
+	HCFLOGENTRY( HCF_TRACE_DMA_TX_PUT, 0xDA03 )
+	HCFASSERT( ifbp->IFB_Magic == HCF_MAGIC, ifbp->IFB_Magic )
+	HCFASSERT_INT
+	HCFASSERT( ( ifbp->IFB_CntlOpt & (USE_DMA|DMA_ENABLED) ) == (USE_DMA|DMA_ENABLED), ifbp->IFB_CntlOpt)
+
+	if ( descp->buf_addr ) {
+		*(hcf_16*)(descp->buf_addr + HFS_TX_CNTL) = tx_cntl;											/*1*/
+#if (HCF_ENCAP) == HCF_ENC
+		HCFASSERT( descp->next_desc_addr, 0 )									//at least 2 descripors
+		HCFASSERT( descp->BUF_CNT == HFS_ADDR_DEST, descp->BUF_CNT )	//exact length required for 1st buffer
+		HCFASSERT( descp->BUF_SIZE >= HCF_DMA_TX_BUF1_SIZE, descp->BUF_SIZE )	//minimal storage for encapsulation
+		HCFASSERT( p->BUF_CNT >= 14, p->BUF_CNT );					//at least DA, SA and 'type' in 2nd buffer
+
+#if (HCF_TYPE) & HCF_TYPE_CCX
+		/* if we are doing PPK +/- CMIC, or we are sending a DDP frame */
+		if ( ( ifbp->IFB_CKIPStat == HCF_ACT_CCX_ON ) ||
+			 ( ( p->BUF_CNT >= 20 )		 && ( ifbp->IFB_CKIPStat == HCF_ACT_CCX_OFF ) &&
+			 ( p->buf_addr[12] == 0xAA ) && ( p->buf_addr[13] == 0xAA ) &&
+			 ( p->buf_addr[14] == 0x03 ) && ( p->buf_addr[15] == 0x00 ) &&
+			 ( p->buf_addr[16] == 0x40 ) && ( p->buf_addr[17] == 0x96 ) &&
+			 ( p->buf_addr[18] == 0x00 ) && ( p->buf_addr[19] == 0x00 )))
+		{
+			/* copy the DA/SA to the first buffer */
+			for ( i = 0; i < HCF_DASA_SIZE; i++ ) {
+				descp->buf_addr[i + HFS_ADDR_DEST] = p->buf_addr[i];
+			}
+			/* calculate the length of the second fragment only */
+			i = 0;
+			do { i += p->BUF_CNT; } while( p = p->next_desc_addr );
+			i -= HCF_DASA_SIZE ;
+			/* convert the length field to big endian, using the endian friendly macros */
+			i = CNV_SHORT_TO_BIG(i);		//!! this converts ONLY on LE platforms, how does that relate to the non-CCX code
+			*(hcf_16*)(&descp->buf_addr[HFS_LEN]) = (hcf_16)i;
+			descp->BUF_CNT = HFS_DAT;
+			// modify 2nd descriptor to skip the 'Da/Sa' fields
+			descp->next_desc_addr->buf_phys_addr += HCF_DASA_SIZE;
+			descp->next_desc_addr->BUF_CNT		 -= HCF_DASA_SIZE;
+		}
+		else
+#endif // HCF_TYPE_CCX
+		{
+			descp->buf_addr[HFS_TYPE-1] = hcf_encap(&descp->next_desc_addr->buf_addr[HCF_DASA_SIZE]);		/*4*/
+			if ( descp->buf_addr[HFS_TYPE-1] != ENC_NONE ) {
+				for ( i=0; i < HCF_DASA_SIZE; i++ ) {														/*6*/
+					descp->buf_addr[i + HFS_ADDR_DEST] = descp->next_desc_addr->buf_addr[i];
+				}
+				i = sizeof(snap_header) + 2 - ( 2*6 + 2 );
+				do { i += p->BUF_CNT; } while ( ( p = p->next_desc_addr ) != NULL );
+				*(hcf_16*)(&descp->buf_addr[HFS_LEN]) = CNV_END_SHORT(i);	//!! this converts on ALL platforms, how does that relate to the CCX code
+				for ( i=0; i < sizeof(snap_header) - 1; i++) {
+					descp->buf_addr[HFS_TYPE - sizeof(snap_header) + i] = snap_header[i];
+				}
+				descp->BUF_CNT = HFS_TYPE;																	/*8*/
+				descp->next_desc_addr->buf_phys_addr	+= HCF_DASA_SIZE;
+				descp->next_desc_addr->BUF_CNT			-= HCF_DASA_SIZE;
+			}
+		}
+#endif // HCF_ENC
+    }
+	put_frame_lst( ifbp, descp, DMA_TX );
+	HCFLOGEXIT( HCF_TRACE_DMA_TX_PUT )
+} // hcf_dma_tx_put
+
+#endif // HCF_DMA
+
+#if (HCF_DL_ONLY) == 0
+/************************************************************************************************************
+*
+*.MODULE		hcf_8 hcf_encap( wci_bufp type )
+*.PURPOSE		test whether RFC1042 or Bridge-Tunnel encapsulation is needed.
+*
+*.ARGUMENTS
+*	type		(Far) pointer to the (Big Endian) Type/Length field in the message
+*
+*.RETURNS
+*	ENC_NONE		len/type is "len" ( (BIG_ENDIAN)type <= 1500 )
+*	ENC_TUNNEL		len/type is "type" and 0x80F3 or 0x8137
+*	ENC_1042		len/type is "type" but not 0x80F3 or 0x8137
+*
+*.CONDITIONS
+*	NIC Interrupts	d.c
+*
+*.DESCRIPTION
+* Type must point to the Len/Type field of the message, this is the 2-byte field immediately after the 6 byte
+* Destination Address and 6 byte Source Address.  The 2 successive bytes addressed by type are interpreted as
+* a Big Endian value.  If that value is less than or equal to 1500, the message is assumed to be in 802.3
+* format.  Otherwise the message is assumed to be in Ethernet-II format.  Depending on the value of Len/Typ,
+* Bridge Tunnel or RFC1042 encapsulation is needed.
+*
+*.DIAGRAM
+*
+*  1:	presume 802.3, hence preset return value at ENC_NONE
+*  2:	convert type from "network" Endian format to native Endian
+*  4:	the litmus test to distinguish type and len.
+*	The hard code "magic" value of 1500 is intentional and should NOT be replaced by a mnemonic because it is
+*	not related at all to the maximum frame size supported  by the Hermes.
+*  6:	check type against:
+*		0x80F3	//AppleTalk Address Resolution Protocol (AARP)
+*		0x8137	//IPX
+*	to determine the type of encapsulation
+*
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+#if HCF_ENCAP	//i.e HCF_ENC or HCF_ENC_SUP
+#if ! ( (HCF_ENCAP) & HCF_ENC_SUP )
+HCF_STATIC
+#endif // HCF_ENCAP
+hcf_8
+hcf_encap( wci_bufp type )
+{
+
+hcf_8	rc = ENC_NONE;																					/* 1 */
+hcf_16	t = (hcf_16)(*type<<8) + *(type+1);																/* 2 */
+
+	if ( t > 1500 ) {																					/* 4 */
+		if ( t == 0x8137 || t == 0x80F3 ) {
+			rc = ENC_TUNNEL;																			/* 6 */
+		} else {
+			rc = ENC_1042;
+		}
+	}
+	return rc;
+} // hcf_encap
+#endif // HCF_ENCAP
+#endif // HCF_DL_ONLY
+
+
+/************************************************************************************************************
+*
+*.MODULE		int hcf_get_info( IFBP ifbp, LTVP ltvp )
+*.PURPOSE		Obtains transient and persistent configuration information from the Card and from the HCF.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*	ltvp		address of LengthTypeValue structure specifying the "what" and the "how much" of the
+*				information to be collected from the HCF or from the Hermes
+*
+*.RETURNS
+*	HCF_ERR_LEN			The provided buffer was too small
+*	HCF_SUCCESS			Success
+*!!	via cmd_exe ( type >= CFG_RID_FW_MIN )
+*	HCF_ERR_NO_NIC		NIC removed during retrieval
+*	HCF_ERR_TIME_OUT	Expected Hermes event did not occure in expected time
+*!!	via cmd_exe and setup_bap (type >= CFG_RID_FW_MIN )
+*	HCF_ERR_DEFUNCT_...	HCF is in defunct mode (bits 0x7F reflect cause)
+*
+*.DESCRIPTION
+* The T-field of the LTV-record (provided by the MSF in parameter ltvp) specifies the RID wanted. The RID
+* information identified by the T-field is copied into the V-field.
+* On entry, the L-field specifies the size of the buffer, also called the "Initial DataLength". The L-value
+* includes the size of the T-field, but not the size of the L-field itself.
+* On return, the L-field indicates the number of words actually contained by the Type and Value fields.
+* As the size of the Type field in the LTV-record is included in the "Initial DataLength" of the record, the
+* V-field can contain at most "Initial DataLength" - 1 words of data.
+* Copying stops if either the complete Information is copied or if the number of words indicated by the
+* "Initial DataLength" were copied.  The "Initial DataLength" acts as a safe guard against Configuration
+* Information blocks that have different sizes for different F/W versions, e.g. when later versions support
+* more tallies than earlier versions.
+* If the size of Value field of the RID exceeds the size of the "Initial DataLength" -1, as much data
+* as fits is copied, and an error status of HCF_ERR_LEN is returned.
+*
+* It is the responsibility of the MSF to detect card removal and re-insertion and not call the HCF when the
+* NIC is absent. The MSF cannot, however, timely detect a Card removal if the Card is removed while
+* hcf_get_info is in progress.  Therefore, the HCF performs its own check on Card presence after the read
+* operation of the NIC data.  If the Card is not present or removed during the execution of hcf_get_info,
+* HCF_ERR_NO_NIC is returned and the content of the Data Buffer is unpredictable. This check is not performed
+* in case of the "HCF embedded" pseudo RIDs like CFG_TALLIES.
+*
+* Assert fails if
+* - ifbp has a recognizable out-of-range value.
+* - reentrancy, may be  caused by calling hcf_functions without adequate protection
+*	against NIC interrupts or multi-threading.
+* - ltvp is a NULL pointer.
+* - length field of the LTV-record at entry is 0 or 1 or has an excessive value (i.e. exceeds HCF_MAX_LTV).
+* - type field of the LTV-record is invalid.
+*
+*.DIAGRAM
+*	Hcf_get_mb_info copies the contents of the oldest MailBox Info block in the MailBox to PC RAM. If len is
+*	less than the size of the MailBox Info block, only as much as fits in the PC RAM buffer is copied. After
+*	the copying the MailBox Read pointer is updated to point to the next MailBox Info block, hence the
+*	remainder of an "oversized" MailBox Info block is lost. The truncation of the MailBox Info block is NOT
+*	reflected in the return status. Note that hcf_get_info guarantees the length of the PC RAM buffer meets
+*	the minimum requirements of at least 2, so no PC RAM buffer overrun.
+*
+*	Calling hcf_get_mb_info when their is no MailBox Info block available or when there is no MailBox at all,
+*	results in a "NULL" MailBox Info block.
+*
+*12:	see NOTICE
+*17: The return status of cmd_wait and the first hcfio_in_string can be ignored, because when one fails, the
+*	other fails via the IFB_DefunctStat mechanism
+*20: "HCFASSERT( rc == HCF_SUCCESS, rc )" is not suitable because this will always trigger as side effect of
+*	the HCFASSERT in hcf_put_info which calls hcf_get_info to figure out whether the RID exists at all.
+
+*.NOTICE
+*
+*	"HCF embedded" pseudo RIDs:
+*	CFG_MB_INFO, CFG_TALLIES, CFG_DRV_IDENTITY, CFG_DRV_SUP_RANGE, CFG_DRV_ACT_RANGES_PRI,
+*	CFG_DRV_ACT_RANGES_STA, CFG_DRV_ACT_RANGES_HSI
+*	Note the HCF_ERR_LEN is NOT adequately set, when L >= 2 but less than needed
+*
+*	Remarks: Transfers operation information and transient and persistent configuration information from the
+*	Card and from the HCF to the MSF.
+*	The exact layout of the provided data structure depends on the action code. Copying stops if either the
+*	complete Configuration Information is copied or if the number of bytes indicated by len is copied.  Len
+*	acts as a safe guard against Configuration Information blocks which have different sizes for different
+*	Hermes versions, e.g. when later versions support more tallies than earlier versions. It is a conscious
+*	decision that unused parts of the PC RAM buffer are not cleared.
+*
+*	Remarks: The only error against which is protected is the "Read error" as result of Card removal. Only the
+*	last hcf_io_string need to be protected because if the first fails the second will fail as well. Checking
+*	for cmd_exe errors is supposed superfluous because problems in cmd_exe are already caught or will be
+*	caught by hcf_enable.
+*
+*	CFG_MB_INFO: copy the oldest MailBox Info Block or the "null" block if none available.
+*
+*	The mechanism to HCF_ASSERT on invalid typ-codes in the LTV record is based on the following strategy:
+*	  - during the pseudo-asynchronous Hermes commands (diagnose, download)	only CFG_MB_INFO is acceptable
+*	  -	some codes (e.g. CFG_TALLIES) are explicitly handled by the HCF which implies that these codes
+*		are valid
+*	  - all other codes in the range 0xFC00 through 0xFFFF are passed to the Hermes.  The Hermes returns an
+*		LTV record with a zero value in the L-field for all Typ-codes it does not recognize. This is
+*		defined and intended behavior, so HCF_ASSERT does not catch on this phenomena.
+*	  -	all remaining codes are invalid and cause an ASSERT.
+*
+*.CONDITIONS
+* In case of USB, HCF_MAX_MSG ;?USED;? to limit the amount of data that can be retrieved via hcf_get_info.
+*
+*
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+int
+hcf_get_info( IFBP ifbp, LTVP ltvp )
+{
+
+int			rc = HCF_SUCCESS;
+hcf_16		len = ltvp->len;
+hcf_16		type = ltvp->typ;
+wci_recordp	p = &ltvp->len;		//destination word pointer (in LTV record)
+hcf_16		*q = NULL;				/* source word pointer  Note!! DOS COM can't cope with FAR
+									 * as a consequence MailBox must be near which is usually true anyway
+									 */
+int			i;
+
+	HCFLOGENTRY( HCF_TRACE_GET_INFO, ltvp->typ )
+	HCFASSERT( ifbp->IFB_Magic == HCF_MAGIC, ifbp->IFB_Magic )
+	HCFASSERT_INT
+	HCFASSERT( ltvp, 0 )
+	HCFASSERT( 1 < ltvp->len && ltvp->len <= HCF_MAX_LTV + 1, MERGE_2( ltvp->typ, ltvp->len ) )
+
+	ltvp->len = 0;								//default to: No Info Available
+#if defined MSF_COMPONENT_ID || (HCF_EXT) & HCF_EXT_MB //filter out all specials
+	for ( i = 0; ( q = xxxx[i] ) != NULL && q[1] != type; i++ ) /*NOP*/;
+#endif // MSF_COMPONENT_ID / HCF_EXT_MB
+#if HCF_TALLIES
+	if ( type == CFG_TALLIES ) {													/*3*/
+		(void)hcf_action( ifbp, HCF_ACT_TALLIES );
+		q = (hcf_16*)&ifbp->IFB_TallyLen;
+	}
+#endif // HCF_TALLIES
+#if (HCF_EXT) & HCF_EXT_MB
+	if ( type == CFG_MB_INFO ) {
+		if ( ifbp->IFB_MBInfoLen ) {
+			if ( ifbp->IFB_MBp[ifbp->IFB_MBRp] == 0xFFFF ) {
+				ifbp->IFB_MBRp = 0; //;?Probably superfluous
+			}
+			q = &ifbp->IFB_MBp[ifbp->IFB_MBRp];
+			ifbp->IFB_MBRp += *q + 1;	//update read pointer
+			if ( ifbp->IFB_MBp[ifbp->IFB_MBRp] == 0xFFFF ) {
+				ifbp->IFB_MBRp = 0;
+			}
+			ifbp->IFB_MBInfoLen = ifbp->IFB_MBp[ifbp->IFB_MBRp];
+		}
+	}
+#endif // HCF_EXT_MB
+	if ( q != NULL ) {						//a special or CFG_TALLIES or CFG_MB_INFO
+		i = min( len, *q ) + 1;				//total size of destination (including T-field)
+		while ( i-- ) {
+			*p++ = *q;
+#if (HCF_TALLIES) & HCF_TALLIES_RESET
+			if ( q > &ifbp->IFB_TallyTyp && type == CFG_TALLIES ) {
+				*q = 0;
+			}
+#endif // HCF_TALLIES_RESET
+			q++;
+		}
+	} else {								// not a special nor CFG_TALLIES nor CFG_MB_INFO
+		if ( type == CFG_CNTL_OPT ) {										//read back effective options
+			ltvp->len = 2;
+			ltvp->val[0] = ifbp->IFB_CntlOpt;
+#if (HCF_EXT) & HCF_EXT_NIC_ACCESS
+		} else if ( type == CFG_PROD_DATA ) {  //only needed for some test tool on top of H-II NDIS driver
+hcf_io		io_port;
+wci_bufp	pt;					//pointer with the "right" type, just to help ease writing macros with embedded assembly
+			OPW( HREG_AUX_PAGE, (hcf_16)(PLUG_DATA_OFFSET >> 7) );
+			OPW( HREG_AUX_OFFSET, (hcf_16)(PLUG_DATA_OFFSET & 0x7E) );
+			io_port = ifbp->IFB_IOBase + HREG_AUX_DATA;		//to prevent side effects of the MSF-defined macro
+			p = ltvp->val;					//destination char pointer (in LTV record)
+			if ( ( i = len - 1 ) > 0 ) {
+				pt = (wci_bufp)p;	//just to help ease writing macros with embedded assembly
+				IN_PORT_STRING_8_16( io_port, pt, i ); //space used by T: -1
+			}
+		} else if ( type == CFG_CMD_HCF ) {
+#define P ((CFG_CMD_HCF_STRCT FAR *)ltvp)
+			HCFASSERT( P->cmd == CFG_CMD_HCF_REG_ACCESS, P->cmd )		//only Hermes register access supported
+			if ( P->cmd == CFG_CMD_HCF_REG_ACCESS ) {
+				HCFASSERT( P->mode < ifbp->IFB_IOBase, P->mode )		//Check Register space
+				ltvp->len = min( len, 4 );								//RESTORE ltv length
+				P->add_info = IPW( P->mode );
+			}
+#undef P
+#endif // HCF_EXT_NIC_ACCESS
+#if (HCF_ASSERT) & HCF_ASSERT_PRINTF
+        } else if (type == CFG_FW_PRINTF) {
+           rc = fw_printf(ifbp, (CFG_FW_PRINTF_STRCT*)ltvp);
+#endif // HCF_ASSERT_PRINTF
+		} else if ( type >= CFG_RID_FW_MIN ) {
+//;? by using HCMD_BUSY option when calling cmd_exe, using a get_frag with length 0 just to set up the
+//;? BAP and calling cmd_cmpl, you could merge the 2 Busy waits. Whether this really helps (and what
+//;? would be the optimal sequence in cmd_exe and get_frag) would have to be MEASURED
+/*17*/		if ( ( rc = cmd_exe( ifbp, HCMD_ACCESS, type ) ) == HCF_SUCCESS &&
+				 ( rc = setup_bap( ifbp, type, 0, IO_IN ) ) == HCF_SUCCESS ) {
+				get_frag( ifbp, (wci_bufp)&ltvp->len, 2*len+2 BE_PAR(2) );
+				if ( IPW( HREG_STAT ) == 0xFFFF ) {					//NIC removal test
+					ltvp->len = 0;
+					HCFASSERT( DO_ASSERT, type )
+				}
+			}
+/*12*/	} else HCFASSERT( DO_ASSERT, type ) /*NOP*/; //NOP in case HCFASSERT is dummy
+	}
+	if ( len < ltvp->len ) {
+		ltvp->len = len;
+		if ( rc == HCF_SUCCESS ) {
+			rc = HCF_ERR_LEN;
+		}
+	}
+	HCFASSERT( rc == HCF_SUCCESS || ( rc == HCF_ERR_LEN && ifbp->IFB_AssertTrace & 1<<HCF_TRACE_PUT_INFO ),
+			   MERGE_2( type, rc ) )																/*20*/
+	HCFLOGEXIT( HCF_TRACE_GET_INFO )
+	return rc;
+} // hcf_get_info
+
+
+/************************************************************************************************************
+*
+*.MODULE		int hcf_put_info( IFBP ifbp, LTVP ltvp )
+*.PURPOSE		Transfers operation and configuration information to the Card and to the HCF.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*	ltvp		specifies the RID (as defined by Hermes I/F) or pseudo-RID (as defined by WCI)
+*
+*.RETURNS
+*	HCF_SUCCESS
+*!!	via cmd_exe
+*	HCF_ERR_NO_NIC 		NIC removed during data retrieval
+*	HCF_ERR_TIME_OUT	Expected F/W event did not occur in time
+*	HCF_ERR_DEFUNCT_...
+*!!	via download				CFG_DLNV_START <= type <= CFG_DL_STOP
+*!!	via put_info				CFG_RID_CFG_MIN <= type <= CFG_RID_CFG_MAX
+*!!	via put_frag
+*
+*.DESCRIPTION
+* The L-field of the LTV-record (provided by the MSF in parameter ltvp) specifies the size of the buffer.
+* The L-value includes the size of the T-field, but not the size of the L-field.
+* The T- field specifies the RID placed in the V-field by the MSF.
+*
+* Not all CFG-codes can be used for hcf_put_info.  The following CFG-codes are valid for hcf_put_info:
+* o One of the CFG-codes in the group "Network Parameters, Static Configuration Entities"
+* Changes made by hcf_put_info to CFG_codes in this group will not affect the F/W
+* and HCF behavior until hcf_cntl_port( HCF_PORT_ENABLE) is called.
+* o One of the CFG-codes in the group "Network Parameters, Dynamic Configuration Entities"
+* Changes made by hcf_put_info to CFG_codes will affect the F/W and HCF behavior immediately.
+* o CFG_PROG.
+* This code is used to initiate and terminate the process to download data either to
+* volatile or to non-volatile RAM on the NIC as well as for the actual download.
+* o CFG-codes related to the HCF behavior.
+* The related CFG-codes are:
+*  - CFG_REG_MB
+*  - CFG_REG_ASSERT_RTNP
+*  - CFG_REG_INFO_LOG
+*  - CFG_CMD_NIC
+*  - CFG_CMD_DONGLE
+*  - CFG_CMD_HCF
+*  - CFG_NOTIFY
+*
+* All LTV-records "unknown" to the HCF are forwarded to the F/W.
+*
+* Assert fails if
+* - ifbp has a recognizable out-of-range value.
+* - ltvp is a NULL pointer.
+* - hcf_put_info was called without prior call to hcf_connect
+* - type field of the LTV-record is invalid, i.e. neither HCF nor F/W can handle the value.
+* - length field of the LTV-record at entry is less than 1 or exceeds MAX_LTV_SIZE.
+* - registering a MailBox with size less than 60 or a non-aligned buffer address is used.
+* - reentrancy, may be  caused by calling hcf_functions without adequate protection against
+*	NIC interrupts or multi-threading.
+*
+*.DIAGRAM
+*
+*.NOTICE
+*	Remarks:  In case of Hermes Configuration LTVs, the codes for the type are "cleverly" chosen to be
+*	identical to the RID. Hermes Configuration information is copied from the provided data structure into the
+*	Card.
+*	In case of HCF Configuration LTVs, the type values are chosen in a range which does not overlap the
+*	RID-range.
+*
+*20:
+*
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+
+int
+hcf_put_info( IFBP ifbp, LTVP ltvp )
+{
+int rc = HCF_SUCCESS;
+
+	HCFLOGENTRY( HCF_TRACE_PUT_INFO, ltvp->typ )
+	HCFASSERT( ifbp->IFB_Magic == HCF_MAGIC, ifbp->IFB_Magic )
+	HCFASSERT_INT
+	HCFASSERT( ltvp, 0 )
+	HCFASSERT( 1 < ltvp->len && ltvp->len <= HCF_MAX_LTV + 1, ltvp->len )
+
+											//all codes between 0xFA00 and 0xFCFF are passed to Hermes
+#if (HCF_TYPE) & HCF_TYPE_WPA
+ {	hcf_16 i;
+	hcf_32 FAR * key_p;
+
+	if ( ltvp->typ == CFG_ADD_TKIP_DEFAULT_KEY || ltvp->typ == CFG_ADD_TKIP_MAPPED_KEY ) {
+		key_p = (hcf_32*)((CFG_ADD_TKIP_MAPPED_KEY_STRCT FAR *)ltvp)->tx_mic_key;
+		i = TX_KEY;		//i.e. TxKeyIndicator == 1, KeyID == 0
+		if ( ltvp->typ == CFG_ADD_TKIP_DEFAULT_KEY ) {
+			key_p = (hcf_32*)((CFG_ADD_TKIP_DEFAULT_KEY_STRCT FAR *)ltvp)->tx_mic_key;
+			i = CNV_LITTLE_TO_SHORT(((CFG_ADD_TKIP_DEFAULT_KEY_STRCT FAR *)ltvp)->tkip_key_id_info);
+		}
+		if ( i & TX_KEY ) {	/* TxKeyIndicator == 1
+							   (either really set by MSF in case of DEFAULT or faked by HCF in case of MAPPED ) */
+			ifbp->IFB_MICTxCntl = (hcf_16)( HFS_TX_CNTL_MIC | (i & KEY_ID )<<8 );
+			ifbp->IFB_MICTxKey[0] = CNV_LONGP_TO_LITTLE( key_p );
+			ifbp->IFB_MICTxKey[1] = CNV_LONGP_TO_LITTLE( (key_p+1) );
+		}
+		i = ( i & KEY_ID ) * 2;
+		ifbp->IFB_MICRxKey[i]   = CNV_LONGP_TO_LITTLE( (key_p+2) );
+		ifbp->IFB_MICRxKey[i+1] = CNV_LONGP_TO_LITTLE( (key_p+3) );
+	}
+#define P ((CFG_REMOVE_TKIP_DEFAULT_KEY_STRCT FAR *)ltvp)
+	if ( ( ltvp->typ == CFG_REMOVE_TKIP_MAPPED_KEY )	||
+		 ( ltvp->typ == CFG_REMOVE_TKIP_DEFAULT_KEY &&
+		   ( (ifbp->IFB_MICTxCntl >> 8) & KEY_ID ) == CNV_SHORT_TO_LITTLE(P->tkip_key_id )
+		 )
+		) { ifbp->IFB_MICTxCntl = 0; }		//disable MIC-engine
+#undef P
+ }
+#endif // HCF_TYPE_WPA
+
+	if ( ltvp->typ == CFG_PROG ) {
+		rc = download( ifbp, (CFG_PROG_STRCT FAR *)ltvp );
+	} else switch (ltvp->typ) {
+#if (HCF_ASSERT) & HCF_ASSERT_RT_MSF_RTN
+	  case CFG_REG_ASSERT_RTNP:											//Register MSF Routines
+#define P ((CFG_REG_ASSERT_RTNP_STRCT FAR *)ltvp)
+		ifbp->IFB_AssertRtn = P->rtnp;
+//		ifbp->IFB_AssertLvl = P->lvl;		//TODO not yet supported so default is set in hcf_connect
+		HCFASSERT( DO_ASSERT, MERGE_2( HCF_ASSERT, 0xCAF1 ) )	//just to proof that the complete assert machinery is working
+#undef P
+		break;
+#endif // HCF_ASSERT_RT_MSF_RTN
+#if (HCF_EXT) & HCF_EXT_INFO_LOG
+	  case CFG_REG_INFO_LOG:											//Register Log filter
+		ifbp->IFB_RIDLogp = ((CFG_RID_LOG_STRCT FAR*)ltvp)->recordp;
+		break;
+#endif // HCF_EXT_INFO_LOG
+	  case CFG_CNTL_OPT:												//overrule option
+		HCFASSERT( ( ltvp->val[0] & ~(USE_DMA | USE_16BIT) ) == 0, ltvp->val[0] )
+		if ( ( ltvp->val[0] & USE_DMA ) == 0 ) ifbp->IFB_CntlOpt &= ~USE_DMA;
+		ifbp->IFB_CntlOpt |=  ltvp->val[0] & USE_16BIT;
+		break;
+#if (HCF_EXT) & HCF_EXT_MB
+	  case CFG_REG_MB:													//Register MailBox
+#define P ((CFG_REG_MB_STRCT FAR *)ltvp)
+		HCFASSERT( ( (hcf_32)P->mb_addr & 0x0001 ) == 0, (hcf_32)P->mb_addr )
+		HCFASSERT( (P)->mb_size >= 60, (P)->mb_size )
+		ifbp->IFB_MBp = P->mb_addr;
+		/* if no MB present, size must be 0 for ;?the old;? put_info_mb to work correctly */
+		ifbp->IFB_MBSize = ifbp->IFB_MBp == NULL ? 0 : P->mb_size;
+		ifbp->IFB_MBWp = ifbp->IFB_MBRp	= 0;
+		ifbp->IFB_MBp[0] = 0;											//flag the MailBox as empty
+		ifbp->IFB_MBInfoLen = 0;
+		HCFASSERT( ifbp->IFB_MBSize >= 60 || ifbp->IFB_MBp == NULL, ifbp->IFB_MBSize )
+#undef P
+		break;
+	  case CFG_MB_INFO:													//store MailBoxInfoBlock
+		rc = put_info_mb( ifbp, (CFG_MB_INFO_STRCT FAR *)ltvp );
+		break;
+#endif // HCF_EXT_MB
+
+#if (HCF_EXT) & HCF_EXT_NIC_ACCESS
+	  case CFG_CMD_NIC:
+#define P ((CFG_CMD_NIC_STRCT FAR *)ltvp)
+		OPW( HREG_PARAM_2, P->parm2 );
+		OPW( HREG_PARAM_1, P->parm1 );
+		rc = cmd_exe( ifbp, P->cmd, P->parm0 );
+		P->hcf_stat = (hcf_16)rc;
+		P->stat = IPW( HREG_STAT );
+		P->resp0 = IPW( HREG_RESP_0 );
+		P->resp1 = IPW( HREG_RESP_1 );
+		P->resp2 = IPW( HREG_RESP_2 );
+		P->ifb_err_cmd = ifbp->IFB_ErrCmd;
+		P->ifb_err_qualifier = ifbp->IFB_ErrQualifier;
+#undef P
+		break;
+	  case CFG_CMD_HCF:
+#define P ((CFG_CMD_HCF_STRCT FAR *)ltvp)
+		HCFASSERT( P->cmd == CFG_CMD_HCF_REG_ACCESS, P->cmd )		//only Hermes register access supported
+		if ( P->cmd == CFG_CMD_HCF_REG_ACCESS ) {
+			HCFASSERT( P->mode < ifbp->IFB_IOBase, P->mode )		//Check Register space
+			OPW( P->mode, P->add_info);
+		}
+#undef P
+		break;
+#endif // HCF_EXT_NIC_ACCESS
+
+#if (HCF_ASSERT) & HCF_ASSERT_PRINTF
+      case CFG_FW_PRINTF_BUFFER_LOCATION:
+        ifbp->IFB_FwPfBuff = *(CFG_FW_PRINTF_BUFFER_LOCATION_STRCT*)ltvp;
+        break;
+#endif // HCF_ASSERT_PRINTF
+
+	  default:						//pass everything unknown above the "FID" range to the Hermes or Dongle
+		rc = put_info( ifbp, ltvp );
+	}
+	//DO NOT !!! HCFASSERT( rc == HCF_SUCCESS, rc )												/* 20 */
+	HCFLOGEXIT( HCF_TRACE_PUT_INFO )
+	return rc;
+} // hcf_put_info
+
+
+#if (HCF_DL_ONLY) == 0
+/************************************************************************************************************
+*
+*.MODULE		int hcf_rcv_msg( IFBP ifbp, DESC_STRCT *descp, unsigned int offset )
+*.PURPOSE		All: decapsulate a message.
+*				pre-HermesII.5: verify MIC.
+*				non-USB, non-DMA mode: Transfer a message from the NIC to the Host and acknowledge reception.
+*				USB: Transform a message from proprietary USB format to 802.3 format
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*	descp		Pointer to the Descriptor List location.
+*	offset		USB: not used
+*				non-USB: specifies the beginning of the data to be obtained (0 corresponds with DestAddr field
+*				of frame).
+*
+*.RETURNS
+*	HCF_SUCCESS			No SSN error ( or HCF_ERR_MIC already reported by hcf_service_nic)
+*	HCF_ERR_MIC			message contains an erroneous MIC ( HCF_SUCCESS is reported if HCF_ERR_MIC is already
+*						reported by hcf_service_nic)
+* 	HCF_ERR_NO_NIC		NIC removed during data retrieval
+* 	HCF_ERR_DEFUNCT...
+*
+*.DESCRIPTION
+* The Receive Message Function can be executed by the MSF to obtain the Data Info fields of the message that
+* is reported to be available by the Service NIC Function.
+*
+* The Receive Message Function copies the message data available in the Card memory into a buffer structure
+* provided by the MSF.
+* Only data of the message indicated by the Service NIC Function can be obtained.
+* Execution of the Service NIC function may result in the availability of a new message, but it definitely
+* makes the message reported by the preceding Service NIC function, unavailable.
+*
+* in non-USB/non-DMA mode, hcf_rcv_msg starts the copy process at the (non-negative) offset requested by the
+* parameter offset, relative to HFS_ADDR_DEST, e.g offset 0 starts copying from the Destination Address, the
+* very begin of the 802.3 frame message. Offset must either lay within the part of the 802.3 frame as stored
+* by hcf_service_nic in the lookahead buffer or be just behind it, i.e. the first byte not yet read.
+* When offset is within lookahead, data is copied from lookahead.
+* When offset is beyond lookahead, data is read directly from RxFS in NIC with disregard of the actual value
+* of offset
+*
+*.NOTICE:
+* o at entry: look ahead buffer as passed with hcf_service_nic is still accessible and unchanged
+* o at exit: Receive Frame in NIC memory is released
+*
+* Description:
+* Starting at the byte indicated by the Offset value, the bytes are copied from the Data Info
+* Part of the current Receive Frame Structure to the Host memory data buffer structure
+* identified by descp.
+* The maximum value for Offset is the number of characters of the 802.3 frame read into the
+* look ahead buffer by hcf_service_nic (i.e. the look ahead buffer size minus
+* Control and 802.11 fields)
+* If Offset is less than the maximum value, copying starts from the look ahead buffer till the
+* end of that buffer is reached
+* Then (or if the maximum value is specified for Offset), the
+* message is directly copied from NIC memory to Host memory.
+* If an invalid (i.e. too large) offset is specified, an assert catches but the buffer contents are
+* undefined.
+* Copying stops if either:
+* o the end of the 802.3 frame is reached
+* o the Descriptor with a NULL pointer in the next_desc_addr field is reached
+*
+* When the copying stops, the receiver is ack'ed, thus freeing the NIC memory where the frame is stored
+* As a consequence, hcf_rcv_msg can only be called once for any particular Rx frame.
+*
+* For the time being (PCI Bus mastering not yet supported), only the following fields of each
+* of the descriptors in the descriptor list must be set by the MSF:
+* o buf_cntl.buf_dim[1]
+* o *next_desc_addr
+* o *buf_addr
+* At return from hcf_rcv_msg, the field buf_cntl.buf_dim[0] of the used Descriptors reflects
+* the number of bytes in the buffer corresponding with the Descriptor.
+* On the last used Descriptor, buf_cntl.buf_dim[0] is less or equal to buf_cntl.buf_dim[1].
+* On all preceding Descriptors buf_cntl.buf_dim[0] is equal to buf_cntl.buf_dim[1].
+* On all succeeding (unused) Descriptors, buf_cntl.buf_dim[0] is zero.
+* Note: this I/F is based on the assumptions how the I/F needed for PCI Bus mastering will
+* be, so it may change.
+*
+* The most likely handling of HCF_ERR_NO_NIC by the MSF is to drop the already copied
+* data as elegantly as possible under the constraints and requirements posed by the (N)OS.
+* If no received Frame Structure is pending, "Success" rather than "Read error" is returned.
+* This error constitutes a logic flaw in the MSF
+* The HCF can only catch a minority of this
+* type of errors
+* Based on consistency ideas, the HCF catches none of these errors.
+*
+* Assert fails if
+* - ifbp has a recognizable out-of-range value
+* - there is no unacknowledged Rx-message available
+* - offset is out of range (outside look ahead buffer)
+* - descp is a NULL pointer
+* - any of the descriptors is not double word aligned
+* - reentrancy, may be  caused by calling hcf_functions without adequate protection
+* 	against NIC interrupts or multi-threading.
+* - Interrupts are enabled.
+*
+*.DIAGRAM
+*
+*.NOTICE
+* - by using unsigned int as type for offset, no need to worry about negative offsets
+* - Asserting on being enabled/present is superfluous, since a non-zero IFB_lal implies that hcf_service_nic
+*   was called and detected a Rx-message. A zero IFB_lal will set the BUF_CNT field of at least the first
+*   descriptor to zero.
+*
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+int
+hcf_rcv_msg( IFBP ifbp, DESC_STRCT *descp, unsigned int offset )
+{
+int			rc = HCF_SUCCESS;
+wci_bufp	cp;										//char oriented working pointer
+hcf_16		i;
+int			tot_len = ifbp->IFB_RxLen - offset;		//total length
+wci_bufp	lap = ifbp->IFB_lap + offset;			//start address in LookAhead Buffer
+hcf_16		lal = ifbp->IFB_lal - offset;			//available data within LookAhead Buffer
+hcf_16		j;
+
+	HCFLOGENTRY( HCF_TRACE_RCV_MSG, offset )
+	HCFASSERT( ifbp->IFB_Magic == HCF_MAGIC, ifbp->IFB_Magic )
+	HCFASSERT_INT
+	HCFASSERT( descp, HCF_TRACE_RCV_MSG )
+	HCFASSERT( ifbp->IFB_RxLen, HCF_TRACE_RCV_MSG )
+	HCFASSERT( ifbp->IFB_RxLen >= offset, MERGE_2( offset, ifbp->IFB_RxLen ) )
+	HCFASSERT( ifbp->IFB_lal >= offset, offset )
+	HCFASSERT( (ifbp->IFB_CntlOpt & USE_DMA) == 0, 0xDADA )
+
+	if ( tot_len < 0 ) {
+		lal = 0; tot_len = 0;				//suppress all copying activity in the do--while loop
+	}
+	do {									//loop over all available fragments
+		// obnoxious hcf.c(1480) : warning C4769: conversion of near pointer to long integer
+		HCFASSERT( ((hcf_32)descp & 3 ) == 0, (hcf_32)descp )
+		cp = descp->buf_addr;
+		j = min( (hcf_16)tot_len, descp->BUF_SIZE );	//minimum of "what's` available" and fragment size
+		descp->BUF_CNT = j;
+		tot_len -= j;						//adjust length still to go
+		if ( lal ) {						//if lookahead Buffer not yet completely copied
+			i = min( lal, j );				//minimum of "what's available" in LookAhead and fragment size
+			lal -= i;						//adjust length still available in LookAhead
+			j -= i;							//adjust length still available in current fragment
+			/*;? while loop could be improved by moving words but that is complicated on platforms with
+			 * alignment requirements*/
+			while ( i-- ) *cp++ = *lap++;
+		}
+		if ( j ) {	//if LookAhead Buffer exhausted but still space in fragment, copy directly from NIC RAM
+			get_frag( ifbp, cp, j BE_PAR(0) );
+			CALC_RX_MIC( cp, j );
+		}
+	} while ( ( descp = descp->next_desc_addr ) != NULL );
+#if (HCF_TYPE) & HCF_TYPE_WPA
+	if ( ifbp->IFB_RxFID ) {
+		rc = check_mic( ifbp );				//prevents MIC error report if hcf_service_nic already consumed all
+	}
+#endif // HCF_TYPE_WPA
+	(void)hcf_action( ifbp, HCF_ACT_RX_ACK );		//only 1 shot to get the data, so free the resources in the NIC
+	HCFASSERT( rc == HCF_SUCCESS, rc )
+	HCFLOGEXIT( HCF_TRACE_RCV_MSG )
+	return rc;
+} // hcf_rcv_msg
+#endif // HCF_DL_ONLY
+
+
+#if (HCF_DL_ONLY) == 0
+/************************************************************************************************************
+*
+*.MODULE		int hcf_send_msg( IFBP ifbp, DESC_STRCT *descp, hcf_16 tx_cntl )
+*.PURPOSE		Encapsulate a message and append padding and MIC.
+*				non-USB: Transfers the resulting message from Host to NIC and initiates transmission.
+*				USB: Transfer resulting message into a flat buffer.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*	descp		pointer to the DescriptorList or NULL
+*	tx_cntl		indicates MAC-port and (Hermes) options
+*					HFS_TX_CNTL_SPECTRALINK
+*					HFS_TX_CNTL_PRIO
+*					HFS_TX_CNTL_TX_OK
+*					HFS_TX_CNTL_TX_EX
+*					HFS_TX_CNTL_TX_DELAY
+*					HFS_TX_CNTL_TX_CONT
+*					HCF_PORT_0				 MAC Port 0 (default)
+*					HCF_PORT_1 (AP only)	 MAC Port 1
+*					HCF_PORT_2 (AP only)	 MAC Port 2
+*					HCF_PORT_3 (AP only)	 MAC Port 3
+*					HCF_PORT_4 (AP only)	 MAC Port 4
+*					HCF_PORT_5 (AP only)	 MAC Port 5
+*					HCF_PORT_6 (AP only)	 MAC Port 6
+*
+*.RETURNS
+*	HCF_SUCCESS
+*	HCF_ERR_DEFUNCT_..
+*	HCF_ERR_TIME_OUT
+*
+*.DESCRIPTION:
+* The Send Message Function embodies 2 functions:
+* o transfers a message (including MAC header) from the provided buffer structure in Host memory to the Transmit
+* Frame Structure (TxFS) in NIC memory.
+* o Issue a send command to the F/W to actually transmit the contents of the TxFS.
+*
+* Control is based on the Resource Indicator IFB_RscInd.
+* The Resource Indicator is maintained by the HCF and should only be interpreted but not changed by the MSF.
+* The MSF must check IFB_RscInd to be non-zero before executing the call to the Send Message Function.
+* When no resources are available, the MSF must handle the queuing of the Transmit frame and check the
+* Resource Indicator periodically after calling hcf_service_nic.
+*
+* The Send Message Functions transfers a message to NIC memory when it is called with a non-NULL descp.
+* Before the Send Message Function is invoked this way, the Resource Indicator (IFB_RscInd) must be checked.
+* If the Resource is not available, Send Message Function execution must be postponed until after processing of
+* a next hcf_service_nic it appears that the Resource has become available.
+* The message is copied from the buffer structure identified by descp to the NIC.
+* Copying stops if a NULL pointer in the next_desc_addr field is reached.
+* Hcf_send_msg does not check for transmit buffer overflow, because the F/W does this protection.
+* In case of a transmit buffer overflow, the surplus which does not fit in the buffer is simply dropped.
+*
+* The Send Message Function activates the F/W to actually send the message to the medium when the
+* HFS_TX_CNTL_TX_DELAY bit of the tx_cntl parameter is not set.
+* If the descp parameter of the current call is non-NULL, the message as represented by descp is send.
+* If the descp parameter of the current call is NULL, and if the preceding call of the Send Message Function had
+* a non-NULL descp and the preceding call had the HFS_TX_CNTL_TX_DELAY bit of tx_cntl set, then the message as
+* represented by the descp of the preceding call is send.
+*
+* Hcf_send_msg supports encapsulation (see HCF_ENCAP) of Ethernet-II frames.
+* An Ethernet-II frame is transferred to the Transmit Frame structure as an 802.3 frame.
+* Hcf_send_msg distinguishes between an 802.3 and an Ethernet-II frame by looking at the data length/type field
+* of the frame. If this field contains a value larger than 1514, the frame is considered to be an Ethernet-II
+* frame, otherwise it is treated as an 802.3 frame.
+* To ease implementation of the HCF, this type/type field must be located in the first descriptor structure,
+* i.e. the 1st fragment must have a size of at least 14 (to contain DestAddr, SrcAddr and Len/Type field).
+* An Ethernet-II frame is encapsulated by inserting a SNAP header between the addressing information and the
+* type field.  This insertion is transparent for the MSF.
+* The HCF contains a fixed table that stores a number of types. If the value specified by the type/type field
+* occurs in this table, Bridge Tunnel Encapsulation is used, otherwise RFC1042 encapsulation is used.
+* Bridge Tunnel uses	AA AA 03 00 00 F8 as SNAP header,
+* RFC1042 uses	AA AA 03 00 00 00 as SNAP header.
+* The table currently contains:
+* 0 0x80F3	AppleTalk Address Resolution Protocol (AARP)
+* 0 0x8137	IPX
+*
+* The algorithm to distinguish between 802.3 and Ethernet-II frames limits the maximum length for frames of
+* 802.3 frames to 1514 bytes.
+* Encapsulation can be suppressed by means of the system constant HCF_ENCAP, e.g. to support proprietary
+* protocols with 802.3 like frames with a size larger than 1514 bytes.
+*
+* In case the HCF encapsulates the frame, the number of bytes that is actually transmitted is determined by the
+* cumulative value of the buf_cntl.buf_dim[0] fields.
+* In case the HCF does not encapsulate the frame, the number of bytes that is actually transmitted is not
+* determined by the cumulative value of the buf_cntl.buf_dim[DESC_CNTL_CNT] fields of the desc_strct's but by
+* the Length field of the 802.3 frame.
+* If there is a conflict between the cumulative value of the buf_cntl.buf_dim[0] fields and the
+* 802.3 Length field the 802.3 Length field determines the number of bytes actually transmitted by the NIC while
+* the cumulative value of the buf_cntl.buf_dim[0] fields determines the position of the MIC, hence a mismatch
+* will result in MIC errors on the Receiving side.
+* Currently this problem is flagged on the Transmit side by an Assert.
+* The following fields of each of the descriptors in the descriptor list must be set by the MSF:
+* o buf_cntl.buf_dim[0]
+* o *next_desc_addr
+* o *buf_addr
+*
+* All bits of the tx_cntl parameter except HFS_TX_CNTL_TX_DELAY and the HCF_PORT# bits are passed to the F/W via
+* the HFS_TX_CNTL field of the TxFS.
+*
+* Note that hcf_send_msg does not detect NIC absence.  The MSF is supposed to have its own -platform dependent-
+* way to recognize card removal/insertion.
+* The total system must be robust against card removal and there is no principal difference between card removal
+* just after hcf_send_msg returns but before the actual transmission took place or sometime earlier.
+*
+* Assert fails if
+* - ifbp has a recognizable out-of-range value
+* - descp is a NULL pointer
+* - no resources for PIF available.
+* - Interrupts are enabled.
+* - reentrancy, may be  caused by calling hcf_functions without adequate protection
+*	against NIC interrupts or multi-threading.
+*
+*.DIAGRAM
+*4:	for the normal case (i.e. no HFS_TX_CNTL_TX_DELAY option active), a fid is acquired via the
+*	routine get_fid.  If no FID is acquired, the remainder is skipped without an error notification.  After
+*	all, the MSF is not supposed to call hcf_send_msg when no Resource is available.
+*7:	The ControlField of the TxFS is written.  Since put_frag can only return the fatal Defunct or "No NIC", the
+*	return status can be ignored because when it fails, cmd_wait will fail as well.  (see also the note on the
+*	need for a return code below).
+*	Note that HFS_TX_CNTL has different values for H-I, H-I/SSN and H-II and HFS_ADDR_DEST has different
+*	values for H-I (regardless of SSN) and H-II.
+*	By writing 17, 1 or 2 ( implying 16, 0 or 1 garbage word after HFS_TX_CNTL) the BAP just gets to
+*	HFS_ADDR_DEST for H-I, H-I/SSN and H-II respectively.
+*10: if neither encapsulation nor MIC calculation is needed, splitting the first fragment in two does not
+*	really help but it makes the flow easier to follow to do not optimize on this difference
+*
+*	hcf_send_msg checks whether the frame is an Ethernet-II rather than an "official" 802.3 frame.
+*	The E-II check is based on the length/type field in the MAC header. If this field has a value larger than
+*	1500, E-II is assumed. The implementation of this test fails if the length/type field is not in the first
+*	descriptor.  If E-II is recognized, a SNAP header is inserted. This SNAP header represents either RFC1042
+*	or Bridge-Tunnel encapsulation, depending on the return status of the support routine hcf_encap.
+*
+*.NOTICE
+*	hcf_send_msg leaves the responsibility to only send messages on enabled ports at the MSF level.
+*	This is considered the strategy which is sufficiently adequate for all "robust" MSFs, have the least
+*	processor utilization and being still acceptable robust at the WCI !!!!!
+*
+*	hcf_send_msg does not NEED a return value to report NIC absence or removal during the execution of
+*	hcf_send_msg(), because the MSF and higher layers must be able to cope anyway with the NIC being removed
+*	after a successful completion of hcf_send_msg() but before the actual transmission took place.
+*	To accommodate user expectations the current implementation does report NIC absence.
+*	Defunct blocks all NIC access and will (also) be reported on a number of other calls.
+*
+*	hcf_send_msg does not check for transmit buffer overflow because the Hermes does this protection.
+*	In case of a transmit buffer overflow, the surplus which does not fit in the buffer is simply dropped.
+*	Note that this possibly results in the transmission of incomplete frames.
+*
+*	After some deliberation with F/W team, it is decided that - being in the twilight zone of not knowing
+*	whether the problem at hand is an MSF bug, HCF buf, F/W bug, H/W malfunction or even something else - there
+*	is no "best thing to do" in case of a failing send, hence the HCF considers the TxFID ownership to be taken
+*	over by the F/W and hopes for an Allocate event in due time
+*
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+int
+hcf_send_msg( IFBP ifbp, DESC_STRCT *descp, hcf_16 tx_cntl )
+{
+int			rc = HCF_SUCCESS;
+DESC_STRCT	*p /* = descp*/;		//working pointer
+hcf_16		len;					// total byte count
+hcf_16		i;
+
+hcf_16		fid = 0;
+
+	HCFASSERT( ifbp->IFB_RscInd || descp == NULL, ifbp->IFB_RscInd )
+	HCFASSERT( (ifbp->IFB_CntlOpt & USE_DMA) == 0, 0xDADB )
+
+	HCFLOGENTRY( HCF_TRACE_SEND_MSG, tx_cntl )
+	HCFASSERT( ifbp->IFB_Magic == HCF_MAGIC, ifbp->IFB_Magic )
+	HCFASSERT_INT
+	/* obnoxious c:/hcf/hcf.c(1480) : warning C4769: conversion of near pointer to long integer,
+	 * so skip */
+	HCFASSERT( ((hcf_32)descp & 3 ) == 0, (hcf_32)descp )
+#if HCF_ASSERT
+{	int x = ifbp->IFB_FWIdentity.comp_id == COMP_ID_FW_AP ? tx_cntl & ~HFS_TX_CNTL_PORT : tx_cntl;
+	HCFASSERT( (x & ~HCF_TX_CNTL_MASK ) == 0, tx_cntl )
+}
+#endif // HCF_ASSERT
+
+	if ( descp ) ifbp->IFB_TxFID = 0;				//cancel a pre-put message
+
+#if (HCF_EXT) & HCF_EXT_TX_CONT				// Continuous transmit test
+	if ( tx_cntl == HFS_TX_CNTL_TX_CONT ) {
+	 	if ( ( fid = get_fid( ifbp ) ) != 0 ) {
+											//setup BAP to begin of TxFS
+			(void)setup_bap( ifbp, fid, 0, IO_OUT );
+											//copy all the fragments in a transparent fashion
+		 	for ( p = descp; p; p = p->next_desc_addr ) {
+			/* obnoxious warning C4769: conversion of near pointer to long integer */
+				HCFASSERT( ((hcf_32)p & 3 ) == 0, (hcf_32)p )
+				put_frag( ifbp, p->buf_addr, p->BUF_CNT BE_PAR(0) );
+			}
+			rc = cmd_exe( ifbp, HCMD_THESEUS | HCMD_BUSY | HCMD_STARTPREAMBLE, fid );
+			if ( ifbp->IFB_RscInd == 0 ) {
+				ifbp->IFB_RscInd = get_fid( ifbp );
+			}
+		}
+											// een slecht voorbeeld doet goed volgen ;?
+		HCFLOGEXIT( HCF_TRACE_SEND_MSG )
+		return rc;
+	}
+#endif // HCF_EXT_TX_CONT
+									/* the following initialization code is redundant for a pre-put message
+									 * but moving it inside the "if fid" logic makes the merging with the
+									 * USB flow awkward
+									 */
+#if (HCF_TYPE) & HCF_TYPE_WPA
+	tx_cntl |= ifbp->IFB_MICTxCntl;
+#endif // HCF_TYPE_WPA
+	if ( (fid = ifbp->IFB_TxFID) == 0 && ( fid = get_fid( ifbp ) ) != 0 ) 		/* 4 */
+			/* skip the next compound statement if:
+			   - pre-put message or
+			   - no fid available (which should never occur if the MSF adheres to the WCI)
+			 */
+	{		// to match the closing curly bracket of above "if" in case of HCF_TYPE_USB
+											//calculate total length ;? superfluous unless CCX or Encapsulation
+		len = 0;
+		p = descp;
+		do len += p->BUF_CNT; while ( ( p = p->next_desc_addr ) != NULL );
+		p = descp;
+//;?	HCFASSERT( len <= HCF_MAX_MSG, len )
+/*7*/	(void)setup_bap( ifbp, fid, HFS_TX_CNTL, IO_OUT );
+#if (HCF_TYPE) & HCF_TYPE_TX_DELAY
+		HCFASSERT( ( descp != NULL ) ^ ( tx_cntl & HFS_TX_CNTL_TX_DELAY ), tx_cntl )
+		if ( tx_cntl & HFS_TX_CNTL_TX_DELAY ) {
+			tx_cntl &= ~HFS_TX_CNTL_TX_DELAY;		//!!HFS_TX_CNTL_TX_DELAY no longer available
+			ifbp->IFB_TxFID = fid;
+			fid = 0;								//!!fid no longer available, be careful when modifying code
+		}
+#endif // HCF_TYPE_TX_DELAY
+		OPW( HREG_DATA_1, tx_cntl ) ;
+		OPW( HREG_DATA_1, 0 );
+#if ! ( (HCF_TYPE) & HCF_TYPE_CCX )
+		HCFASSERT( p->BUF_CNT >= 14, p->BUF_CNT )
+											/* assume DestAddr/SrcAddr/Len/Type ALWAYS contained in 1st fragment
+											 * otherwise life gets too cumbersome for MIC and Encapsulation !!!!!!!!
+		if ( p->BUF_CNT >= 14 ) {	alternatively: add a safety escape !!!!!!!!!!!! }	*/
+#endif // HCF_TYPE_CCX
+		CALC_TX_MIC( NULL, -1 );		//initialize MIC
+/*10*/	put_frag( ifbp, p->buf_addr, HCF_DASA_SIZE BE_PAR(0) );	//write DA, SA with MIC calculation
+		CALC_TX_MIC( p->buf_addr, HCF_DASA_SIZE );		//MIC over DA, SA
+		CALC_TX_MIC( null_addr, 4 );		//MIC over (virtual) priority field
+#if (HCF_TYPE) & HCF_TYPE_CCX
+		//!!be careful do not use positive test on HCF_ACT_CCX_OFF, because IFB_CKIPStat is initially 0
+		if(( ifbp->IFB_CKIPStat == HCF_ACT_CCX_ON ) ||
+           ((GET_BUF_CNT(p) >= 20 )   && ( ifbp->IFB_CKIPStat == HCF_ACT_CCX_OFF ) &&
+            (p->buf_addr[12] == 0xAA) && (p->buf_addr[13] == 0xAA) &&
+            (p->buf_addr[14] == 0x03) && (p->buf_addr[15] == 0x00) &&
+            (p->buf_addr[16] == 0x40) && (p->buf_addr[17] == 0x96) &&
+            (p->buf_addr[18] == 0x00) && (p->buf_addr[19] == 0x00)))
+        {
+            i = HCF_DASA_SIZE;
+
+            OPW( HREG_DATA_1, CNV_SHORT_TO_BIG( len - i ));
+
+            /* need to send out the remainder of the fragment */
+			put_frag( ifbp, &p->buf_addr[i], GET_BUF_CNT(p) - i BE_PAR(0) );
+        }
+        else
+#endif // HCF_TYPE_CCX
+		{
+											//if encapsulation needed
+#if (HCF_ENCAP) == HCF_ENC
+											//write length (with SNAP-header,Type, without //DA,SA,Length ) no MIC calc.
+			if ( ( snap_header[sizeof(snap_header)-1] = hcf_encap( &p->buf_addr[HCF_DASA_SIZE] ) ) != ENC_NONE ) {
+				OPW( HREG_DATA_1, CNV_END_SHORT( len + (sizeof(snap_header) + 2) - ( 2*6 + 2 ) ) );
+											//write splice with MIC calculation
+				put_frag( ifbp, snap_header, sizeof(snap_header) BE_PAR(0) );
+				CALC_TX_MIC( snap_header, sizeof(snap_header) );	//MIC over 6 byte SNAP
+				i = HCF_DASA_SIZE;
+			} else
+#endif // HCF_ENC
+			{
+				OPW( HREG_DATA_1, *(wci_recordp)&p->buf_addr[HCF_DASA_SIZE] );
+				i = 14;
+			}
+											//complete 1st fragment starting with Type with MIC calculation
+			put_frag( ifbp, &p->buf_addr[i], p->BUF_CNT - i BE_PAR(0) );
+			CALC_TX_MIC( &p->buf_addr[i], p->BUF_CNT - i );
+		}
+											//do the remaining fragments with MIC calculation
+		while ( ( p = p->next_desc_addr ) != NULL ) {
+			/* obnoxious c:/hcf/hcf.c(1480) : warning C4769: conversion of near pointer to long integer,
+			 * so skip */
+			HCFASSERT( ((hcf_32)p & 3 ) == 0, (hcf_32)p )
+			put_frag( ifbp, p->buf_addr, p->BUF_CNT BE_PAR(0) );
+			CALC_TX_MIC( p->buf_addr, p->BUF_CNT );
+		}
+											//pad message, finalize MIC calculation and write MIC to NIC
+		put_frag_finalize( ifbp );
+	}
+	if ( fid ) {
+/*16*/	rc = cmd_exe( ifbp, HCMD_BUSY | HCMD_TX | HCMD_RECL, fid );
+		ifbp->IFB_TxFID = 0;
+			/* probably this (i.e. no RscInd AND "HREG_EV_ALLOC") at this point in time occurs so infrequent,
+			 * that it might just as well be acceptable to skip this
+			 * "optimization" code and handle that additional interrupt once in a while
+			 */
+// 180 degree error in logic ;? #if ALLOC_15
+/*20*/	if ( ifbp->IFB_RscInd == 0 ) {
+			ifbp->IFB_RscInd = get_fid( ifbp );
+		}
+// #endif // ALLOC_15
+	}
+//	HCFASSERT( level::ifbp->IFB_RscInd, ifbp->IFB_RscInd )
+	HCFLOGEXIT( HCF_TRACE_SEND_MSG )
+	return rc;
+} // hcf_send_msg
+#endif // HCF_DL_ONLY
+
+
+#if (HCF_DL_ONLY) == 0
+/************************************************************************************************************
+*
+*.MODULE		int hcf_service_nic( IFBP ifbp, wci_bufp bufp, unsigned int len )
+*.PURPOSE		Services (most) NIC events.
+*				Provides received message
+*				Provides status information.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*  In non-DMA mode:
+*	bufp		address of char buffer, sufficiently large to hold the first part of the RxFS up through HFS_TYPE
+*	len			length in bytes of buffer specified by bufp
+*				value between HFS_TYPE + 2 and HFS_ADDR_DEST + HCF_MAX_MSG
+*
+*.RETURNS
+*	HCF_SUCCESS
+*	HCF_ERR_MIC	message contains an erroneous MIC (only if frame fits completely in bufp)
+*
+*.DESCRIPTION
+*
+* MSF-accessible fields of Result Block
+* - IFB_RxLen			0 or Frame size.
+* - IFB_MBInfoLen		0 or the L-field of the oldest MBIB.
+* - IFB_RscInd
+* - IFB_HCF_Tallies		updated if a corresponding event occurred.
+* - IFB_NIC_Tallies		updated if a Tally Info frame received from the NIC.
+* - IFB_DmaPackets
+* - IFB_TxFsStat
+* - IFB_TxFsSwSup
+* - IFB_LinkStat		reflects new link status or 0x0000 if no change relative to previous hcf_service_nic call.
+or
+* - IFB_LinkStat		link status, 0x8000 reflects change relative to previous hcf_service_nic call.
+*
+* When IFB_MBInfoLen is non-zero, at least one MBIB is available.
+*
+* IFB_RxLen	reflects the number of received bytes in 802.3 view (Including DestAddr, SrcAddr and Length,
+* excluding MIC-padding, MIC and sum check) of active Rx Frame Structure. If no Rx Data s available, IFB_RxLen
+* equals 0x0000.
+* Repeated execution causes the Service NIC Function to provide information about subsequently received
+* messages, irrespective whether a hcf_rcv_msg or hcf_action(HCF_ACT_RX) is performed in between.
+*
+* When IFB_RxLen is non-zero, a Received Frame Structure is available to be routed to the protocol stack.
+* When Monitor Mode is not active, this is guaranteed to be an error-free non-WMP frame.
+* In case of Monitor Mode, it may also be a frame with an error or a WMP frame.
+* Erroneous frames have a non-zero error-sub field in the HFS_STAT field in the look ahead buffer.
+*
+* If a Receive message is available in NIC RAM, the Receive Frame Structure is (partly) copied from the NIC to
+* the buffer identified by bufp.
+* Copying stops either after len bytes or when the complete 802.3 frame is copied.
+* During the copying the message is decapsulated (if appropriate).
+* If the frame is read completely by hcf_service_nic (i.e. the frame fits completely in the lookahead buffer),
+* the frame is automatically ACK'ed to the F/W and still available via the look ahead buffer and hcf_rcv_msg.
+* Only if the frame is read completely by hcf_service_nic, hcf_service_nic checks the MIC and sets the return
+* status accordingly.  In this case, hcf_rcv_msg does not check the MIC.
+*
+* The MIC calculation algorithm works more efficient if the length of the look ahead buffer is
+* such that it fits exactly 4 n bytes of the 802.3 frame, i.e. len == HFS_ADDR_DEST + 4*n.
+*
+* The Service NIC Function supports the NIC event service handling process.
+* It performs the appropriate actions to service the NIC, such that the event cause is eliminated and related
+* information is saved.
+* The Service NIC Function is executed by the MSF ISR or polling routine as first step to determine the event
+* cause(s).  It is the responsibility of the MSF to perform all not directly NIC related interrupt service
+* actions, e.g. in a PC environment this includes servicing the PIC, and managing the Processor Interrupt
+* Enabling/Disabling.
+* In case of a polled based system, the Service NIC Function must be executed "frequently".
+* The Service NIC Function may have side effects related to the Mailbox and Resource Indicator (IFB_RscInd).
+*
+* hcf_service_nic returns:
+* - The length of the data in the available MBIB (IFB_MBInfoLen)
+* - Changes in the link status (IFB_LinkStat)
+* - The length of the data in the available Receive Frame Structure (IFB_RxLen)
+* - updated IFB_RscInd
+* - Updated Tallies
+*
+* hcf_service_nic is presumed to neither interrupt other HCF-tasks nor to be interrupted by other HCF-tasks.
+* A way to achieve this is to precede hcf_service_nic as well as all other HCF-tasks with a call to
+* hcf_action to disable the card interrupts and, after all work is completed, with a call to hcf_action to
+* restore (which is not necessarily the same as enabling) the card interrupts.
+* In case of a polled environment, it is assumed that the MSF programmer is sufficiently familiar with the
+* specific requirements of that environment to translate the interrupt strategy to a polled strategy.
+*
+* hcf_service_nic services the following Hermes events:
+* - HREG_EV_INFO		Asynchronous Information Frame
+* - HREG_EV_INFO_DROP	WMAC did not have sufficient RAM to build Unsolicited Information Frame
+* - HREG_EV_TX_EXC		(if applicable, i.e. selected via HCF_EXT_INT_TX_EX bit of HCF_EXT)
+* - HREG_EV_SLEEP_REQ	(if applicable, i.e. selected via HCF_DDS/HCF_CDS bit of HCF_SLEEP)
+* ** in non_DMA mode
+* - HREG_EV_ALLOC		Asynchronous part of Allocation/Reclaim completed while out of resources at
+* 						completion of hcf_send_msg/notify
+* - HREG_EV_RX			the detection of the availability of received messages
+* 						including WaveLAN Management Protocol (WMP) message processing
+* ** in DMA mode
+* - HREG_EV_RDMAD
+* - HREG_EV_TDMAD
+*!! hcf_service_nic does not service the following Hermes events:
+*!! 	HREG_EV_TX 			(the "OK" Tx Event) is no longer supported by the WCI, if it occurs it is unclear
+*!! 						what the cause is, so no meaningful strategy is available. Not acking the bit is
+*!! 						probably the best help that can be given to the debugger.
+*!! 	HREG_EV_CMD			handled in cmd_wait.
+*!! 	HREG_EV_FW_DMA 		(i.e. HREG_EV_RXDMA, HREG_EV_TXDMA and_EV_LPESC) are either not used or used
+*!! 						between the F/W and the DMA engine.
+*!! 	HREG_EV_ACK_REG_READY is only applicable for H-II (i.e. not HII.5 and up, see DAWA)
+*
+*	If, in non-DMA mode, a Rx message is available, its length is reflected by the IFB_RxLen field of the IFB.
+*	This length reflects the data itself and the Destination Address, Source Address and DataLength/Type field
+*	but not the SNAP-header in case of decapsulation by the HCF.  If no message is available, IFB_RxLen is
+*	zero.  Former versions of the HCF handled WMP messages and supported a "monitor" mode in hcf_service_nic,
+*	which deposited certain or all Rx messages in the MailBox. The responsibility to handle these frames is
+*	moved to the MSF. The HCF offers as supports hcf_put_info with CFG_MB_INFO as parameter to emulate the old
+* 	implementation under control of the MSF.
+*
+* **Rx Buffer free strategy
+*	When hcf_service_nic reports the availability of a non-DMA message, the MSF can access that message by
+*	means of hcf_rcv_msg. It must be prevented that the LAN Controller writes new data in the NIC buffer
+*	before the MSF is finished with the current message. The NIC buffer is returned to the LAN Controller
+*	when:
+*	 - the complete frame fits in the lookahead buffer or
+*	 - hcf_rcv_msg is called or
+*	 - hcf_action with HCF_ACT_RX is called or
+*	 - hcf_service_nic is called again
+*	It can be reasoned that hcf_action( INT_ON ) should not be given before the MSF has completely processed
+*	a reported Rx-frame. The reason is that the INT_ON action is guaranteed to cause a (Rx-)interrupt (the
+*	MSF is processing a Rx-frame, hence the Rx-event bit in the Hermes register must be active). This
+*	interrupt will cause hcf_service_nic to be called, which will cause the ack-ing of the "last" Rx-event
+*	to the Hermes, causing the Hermes to discard the associated NIC RAM buffer.
+* Assert fails if
+* - ifbp is zero or other recognizable out-of-range value.
+* - hcf_service_nic is called without a prior call to hcf_connect.
+* - interrupts are enabled.
+* - reentrancy, may be  caused by calling hcf_functions without adequate protection
+*	against NIC interrupts or multi-threading.
+*
+*
+*.DIAGRAM
+*1:	IFB_LinkStat is cleared, if a LinkStatus frame is received, IFB_LinkStat will be updated accordingly
+*	by isr_info.
+or
+*1:	IFB_LinkStat change indication is cleared. If a LinkStatus frame is received, IFB_LinkStat will be updated
+*	accordingly by isr_info.
+*2: IFB_RxLen must be cleared before the NIC presence check otherwise:
+*	 -	this value may stay non-zero if the NIC is pulled out at an inconvenient moment.
+*	 -	the RxAck on a zero-FID needs a zero-value for IFB_RxLen to work
+*	 Note that as side-effect of the hcf_action call, the remainder of Rx related info is re-initialized as
+*	 well.
+*4:	In case of Defunct mode, the information supplied by Hermes is unreliable, so the body of
+*	hcf_service_nic is skipped. Since hcf_cntl turns into a NOP if Primary or Station F/W is incompatible,
+*	hcf_service_nic is also skipped in those cases.
+*	To prevent that hcf_service_nic reports bogus information to the MSF with all - possibly difficult to
+*	debug - undesirable side effects, it is paramount to check the NIC presence. In former days the presence
+*	test was based on the Hermes register HREG_SW_0. Since in HCF_ACT_INT_OFF is choosen for strategy based on
+*	HREG_EV_STAT, this is now also used in hcf_service_nic. The motivation to change strategy is partly
+*	due to inconsistent F/W implementations with respect to HREG_SW_0 manipulation around reset and download.
+*	Note that in polled environments Card Removal is not detected by INT_OFF which makes the check in
+*	hcf_service_nic even more important.
+*8:	The event status register of the Hermes is sampled
+*	The assert checks for unexpected events ;?????????????????????????????????????.
+*	 - HREG_EV_INFO_DROP is explicitly excluded from the acceptable HREG_EV_STAT bits because it indicates
+*	   a too heavily loaded system.
+*	 - HREG_EV_ACK_REG_READY is 0x0000 for H-I (and hopefully H-II.5)
+*
+*
+*	HREG_EV_TX_EXC is accepted (via HREG_EV_TX_EXT) if and only if HCF_EXT_INT_TX_EX set in the HCF_EXT
+*	definition at compile time.
+*	The following activities are handled:
+*	 -	Alloc events are handled by hcf_send_msg (and notify). Only if there is no "spare" resource, the
+*		alloc event is superficially serviced by hcf_service_nic to create a pseudo-resource with value
+*		0x001. This value is recognized by get_fid (called by hcf_send_msg and notify) where the real
+*		TxFid is retrieved and the Hermes is acked and - hopefully - the "normal" case with a spare TxFid
+*		in IFB_RscInd is restored.
+*	 -	Info drop events are handled by incrementing a tally
+*	 -	LinkEvent (including solicited and unsolicited tallies) are handled by procedure isr_info.
+*	-	TxEx (if selected at compile time) is handled by copying the significant part of the TxFS
+*		into the IFB for further processing by the MSF.
+*		Note the complication of the zero-FID protection sub-scheme in DAWA.
+*	Note, the Ack of all of above events is handled at the end of hcf_service_nic
+*16: In case of  non-DMA ( either not compiled in or due to a run-time choice):
+*	If an Rx-frame is available, first the FID of that frame is read, including the complication of the
+*	zero-FID protection sub-scheme in DAWA. Note that such a zero-FID is acknowledged at the end of
+*	hcf_service_nic and that this depends on the IFB_RxLen initialization in the begin of hcf_service_nic.
+*	The Assert validates the HCF assumption about Hermes implementation upon which the range of
+*	Pseudo-RIDs is based.
+*	Then the control fields up to the start of the 802.3 frame are read from the NIC into the lookahead buffer.
+*	The status field is converted to native Endianess.
+*	The length is, after implicit Endianess conversion if needed, and adjustment for the 14 bytes of the
+*	802.3 MAC header, stored in IFB_RxLen.
+*	In MAC Monitor mode, 802.11 control frames with a TOTAL length of 14 are received, so without this
+*	length adjustment, IFB_RxLen could not be used to distinguish these frames from "no frame".
+*	No MIC calculation processes are associated with the reading of these Control fields.
+*26: This length test feels like superfluous robustness against malformed frames, but it turned out to be
+*	needed in the real (hostile) world.
+*	The decapsulation check needs sufficient data to represent DA, SA, L, SNAP and Type which amounts to
+*	22 bytes. In MAC Monitor mode, 802.11 control frames with a smaller length are received. To prevent
+*	that the implementation goes haywire, a check on the length is needed.
+*	The actual decapsulation takes place on the fly in the copying process by overwriting the SNAP header.
+*	Note that in case of decapsulation the SNAP header is not passed to the MSF, hence IFB_RxLen must be
+*	compensated for the SNAP header length.
+*	The 22 bytes needed for decapsulation are (more than) sufficient for the exceptional handling of the
+*	MIC algorithm of the L-field (replacing the 2 byte L-field with 4 0x00 bytes).
+*30: The 12 in the no-SSN branch corresponds with the get_frag, the 2 with the IPW of the SSN branch
+*32: If Hermes reported MIC-presence, than the MIC engine is initialized with the non-dummy MIC calculation
+*	routine address and appropriate key.
+*34: The 8 bytes after the DA, SA, L are read and it is checked whether decapsulation is needed i.e.:
+*	  - the Hermes reported Tunnel encapsulation or
+*	  - the Hermes reported 1042 Encapsulation and hcf_encap reports that the HCF would not have used
+*		1042 as the encapsulation mechanism
+*	Note that the first field of the RxFS in bufp has Native Endianess due to the conversion done by the
+*	BE_PAR in get_frag.
+*36: The Type field is the only word kept (after moving) of the just read 8 bytes, it is moved to the
+*	L-field.  The original L-field and 6 byte SNAP header are discarded, so IFB_RxLen and buf_addr must
+*	be adjusted by 8.
+*40: Determine how much of the frame (starting with DA) fits in the Lookahead buffer, then read the not-yet
+*	read data into the lookahead buffer.
+*	If the lookahead buffer contains the complete message, check the MIC. The majority considered this
+*	I/F more appropriate then have the MSF call hcf_get_data only to check the MIC.
+*44: Since the complete message is copied from NIC RAM to PC RAM, the Rx can be acknowledged to the Hermes
+*	to optimize the flow ( a better chance to get new Rx data in the next pass through hcf_service_nic ).
+*	This acknowledgement can not be done via hcf_action( HCF_ACT_RX_ACK ) because this also clears
+*	IFB_RxLEN thus corrupting the I/F to the MSF.
+*;?: In case of DMA (compiled in and activated):
+
+
+*54: Limiting the number of places where the F/W is acked (e.g. the merging of the Rx-ACK with the other
+*	ACKs), is supposed to diminish the potential of race conditions in the F/W.
+*	Note 1: The CMD event is acknowledged in cmd_cmpl
+*	Note 2: HREG_EV_ACK_REG_READY is 0x0000 for H-I (and hopefully H-II.5)
+*	Note 3: The ALLOC event is acknowledged in get_fid (except for the initialization flow)
+*
+*.NOTICE
+* The Non-DMA HREG_EV_RX is handled different compared with the other F/W events.
+* The HREG_EV_RX event is acknowledged by the first hcf_service_nic call after the
+* hcf_service_nic call that reported the occurrence of this event.
+* This acknowledgment
+* makes the next Receive Frame Structure (if any) available.
+* An updated IFB_RxLen
+* field reflects this availability.
+*
+*.NOTICE
+* The minimum size for Len must supply space for:
+* -	an F/W dependent number of bytes of Control Info field including the 802.11 Header field
+* -	Destination Address
+* -	Source Address
+* -	Length field
+* -	[ SNAP Header]
+* -	[ Ethernet-II Type]
+* This results in 68 for Hermes-I and 80 for Hermes-II
+* This way the minimum amount of information is available needed by the HCF to determine whether the frame
+* must be decapsulated.
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+int
+hcf_service_nic( IFBP ifbp, wci_bufp bufp, unsigned int len )
+{
+
+int			rc = HCF_SUCCESS;
+hcf_16		stat;
+wci_bufp	buf_addr;
+hcf_16 		i;
+
+	HCFLOGENTRY( HCF_TRACE_SERVICE_NIC, ifbp->IFB_IntOffCnt )
+	HCFASSERT( ifbp->IFB_Magic == HCF_MAGIC, ifbp->IFB_Magic )
+	HCFASSERT_INT
+
+	ifbp->IFB_LinkStat = 0; // ;? to be obsoleted ASAP												/* 1*/
+	ifbp->IFB_DSLinkStat &= ~CFG_LINK_STAT_CHANGE;													/* 1*/
+	(void)hcf_action( ifbp, HCF_ACT_RX_ACK );														/* 2*/
+	if ( ifbp->IFB_CardStat == 0 && ( stat = IPW( HREG_EV_STAT ) ) != 0xFFFF ) {					/* 4*/
+/*		IF_NOT_DMA( HCFASSERT( !( stat & ~HREG_EV_BASIC_MASK, stat ) )
+ *		IF_NOT_USE_DMA( HCFASSERT( !( stat & ~HREG_EV_BASIC_MASK, stat ) )
+ *		IF_USE_DMA( HCFASSERT( !( stat & ~( HREG_EV_BASIC_MASK ^ ( HREG_EV_...DMA.... ), stat ) )
+ */
+																									/* 8*/
+		if ( ifbp->IFB_RscInd == 0 && stat & HREG_EV_ALLOC ) { //Note: IFB_RscInd is ALWAYS 1 for DMA
+			ifbp->IFB_RscInd = 1;
+		}
+		IF_TALLY( if ( stat & HREG_EV_INFO_DROP ) ifbp->IFB_HCF_Tallies.NoBufInfo++; )
+#if (HCF_EXT) & HCF_EXT_INT_TICK
+		if ( stat & HREG_EV_TICK ) {
+			ifbp->IFB_TickCnt++;
+		}
+#if 0 // (HCF_SLEEP) & HCF_DDS
+		if ( ifbp->IFB_TickCnt == 3 && ( ifbp->IFB_DSLinkStat & CFG_LINK_STAT_CONNECTED ) == 0 ) {
+CFG_DDS_TICK_TIME_STRCT ltv;
+			// 2 second period (with 1 tick uncertanty) in not-connected mode -->go into DS_OOR
+			hcf_action( ifbp, HCF_ACT_SLEEP );
+			ifbp->IFB_DSLinkStat |= CFG_LINK_STAT_DS_OOR; //set OutOfRange
+			ltv.len = 2;
+			ltv.typ = CFG_DDS_TICK_TIME;
+			ltv.tick_time = ( ( ifbp->IFB_DSLinkStat & CFG_LINK_STAT_TIMER ) + 0x10 ) *64; //78 is more right
+			hcf_put_info( ifbp, (LTVP)&ltv );
+			printk( "<5>Preparing for sleep, link_status: %04X, timer : %d\n",
+					ifbp->IFB_DSLinkStat, ltv.tick_time );//;?remove me 1 day
+			ifbp->IFB_TickCnt++; //;?just to make sure we do not keep on printing above message
+			if ( ltv.tick_time < 300 * 125 ) ifbp->IFB_DSLinkStat += 0x0010;
+
+		}
+#endif // HCF_DDS
+#endif // HCF_EXT_INT_TICK
+		if ( stat & HREG_EV_INFO ) {
+			isr_info( ifbp );
+		}
+#if (HCF_EXT) & HCF_EXT_INT_TX_EX
+		if ( stat & HREG_EV_TX_EXT && ( i = IPW( HREG_TX_COMPL_FID ) ) != 0 /*DAWA*/ ) {
+			DAWA_ZERO_FID( HREG_TX_COMPL_FID )
+			(void)setup_bap( ifbp, i, 0, IO_IN );
+			get_frag( ifbp, &ifbp->IFB_TxFsStat, HFS_SWSUP BE_PAR(1) );
+		}
+#endif // HCF_EXT_INT_TX_EX
+//!rlav DMA engine will handle the rx event, not the driver
+#if HCF_DMA
+		if ( !( ifbp->IFB_CntlOpt & USE_DMA ) ) //!! be aware of the logical indentations
+#endif // HCF_DMA
+/*16*/	  if ( stat & HREG_EV_RX && ( ifbp->IFB_RxFID = IPW( HREG_RX_FID ) ) != 0 ) { //if 0 then DAWA_ACK
+			HCFASSERT( bufp, len )
+			HCFASSERT( len >= HFS_DAT + 2, len )
+			DAWA_ZERO_FID( HREG_RX_FID )
+			HCFASSERT( ifbp->IFB_RxFID < CFG_PROD_DATA, ifbp->IFB_RxFID)
+			(void)setup_bap( ifbp, ifbp->IFB_RxFID, 0, IO_IN );
+			get_frag( ifbp, bufp, HFS_ADDR_DEST BE_PAR(1) );
+			ifbp->IFB_lap = buf_addr = bufp + HFS_ADDR_DEST;
+			ifbp->IFB_RxLen = (hcf_16)(bufp[HFS_DAT_LEN] + (bufp[HFS_DAT_LEN+1]<<8) + 2*6 + 2);
+/*26*/		if ( ifbp->IFB_RxLen >= 22 ) {		// convenient for MIC calculation (5 DWs + 1 "skipped" W)
+												//.  get DA,SA,Len/Type and (SNAP,Type or 8 data bytes)
+/*30*/			get_frag( ifbp, buf_addr, 22 BE_PAR(0) );
+/*32*/			CALC_RX_MIC( bufp, -1 );		//.  initialize MIC
+				CALC_RX_MIC( buf_addr, HCF_DASA_SIZE );	//.  MIC over DA, SA
+				CALC_RX_MIC( null_addr, 4 );	//.  MIC over (virtual) priority field
+				CALC_RX_MIC( buf_addr+14, 8 );	//.  skip Len, MIC over SNAP,Type or 8 data bytes)
+				buf_addr += 22;
+#if (HCF_TYPE) & HCF_TYPE_CCX
+//!!be careful do not use positive test on HCF_ACT_CCX_OFF, because IFB_CKIPStat is initially 0
+				if( ifbp->IFB_CKIPStat != HCF_ACT_CCX_ON  )
+#endif // HCF_TYPE_CCX
+				{
+#if (HCF_ENCAP) == HCF_ENC
+					HCFASSERT( len >= HFS_DAT + 2 + sizeof(snap_header), len )
+/*34*/ 				i = *(wci_recordp)&bufp[HFS_STAT] & ( HFS_STAT_MSG_TYPE | HFS_STAT_ERR );
+					if ( i == HFS_STAT_TUNNEL ||
+						 ( i == HFS_STAT_1042 && hcf_encap( (wci_bufp)&bufp[HFS_TYPE] ) != ENC_TUNNEL ) ) {
+												//.  copy E-II Type to 802.3 LEN field
+/*36*/					bufp[HFS_LEN  ] = bufp[HFS_TYPE  ];
+						bufp[HFS_LEN+1] = bufp[HFS_TYPE+1];
+												//.  discard Snap by overwriting with data
+						ifbp->IFB_RxLen -= (HFS_TYPE - HFS_LEN);
+						buf_addr -= ( HFS_TYPE - HFS_LEN ); // this happens to bring us at a DW boundary of 36
+					}
+#endif // HCF_ENC
+				}
+			}
+/*40*/		ifbp->IFB_lal = min( (hcf_16)(len - HFS_ADDR_DEST), ifbp->IFB_RxLen );
+			i = ifbp->IFB_lal - ( buf_addr - ( bufp + HFS_ADDR_DEST ) );
+			get_frag( ifbp, buf_addr, i BE_PAR(0) );
+			CALC_RX_MIC( buf_addr, i );
+#if (HCF_TYPE) & HCF_TYPE_WPA
+			if ( ifbp->IFB_lal == ifbp->IFB_RxLen ) {
+				rc = check_mic( ifbp );
+			}
+#endif // HCF_TYPE_WPA
+/*44*/		if ( len - HFS_ADDR_DEST >= ifbp->IFB_RxLen ) {
+				ifbp->IFB_RxFID = 0;
+			} else { /* IFB_RxFID is cleared, so  you do not get another Rx_Ack at next entry of hcf_service_nic */
+				stat &= (hcf_16)~HREG_EV_RX;	//don't ack Rx if processing not yet completed
+			}
+		}
+		// in case of DMA: signal availability of rx and/or tx packets to MSF
+		IF_USE_DMA( ifbp->IFB_DmaPackets |= stat & ( HREG_EV_RDMAD | HREG_EV_TDMAD ); )
+		// rlav : pending HREG_EV_RDMAD or HREG_EV_TDMAD events get acknowledged here.
+/*54*/	stat &= (hcf_16)~( HREG_EV_SLEEP_REQ | HREG_EV_CMD | HREG_EV_ACK_REG_READY | HREG_EV_ALLOC | HREG_EV_FW_DMA );
+//a positive mask would be easier to understand /*54*/	stat &= (hcf_16)~( HREG_EV_SLEEP_REQ | HREG_EV_CMD | HREG_EV_ACK_REG_READY | HREG_EV_ALLOC | HREG_EV_FW_DMA );
+		IF_USE_DMA( stat &= (hcf_16)~HREG_EV_RX; )
+		if ( stat ) {
+			DAWA_ACK( stat );	/*DAWA*/
+		}
+	}
+	HCFLOGEXIT( HCF_TRACE_SERVICE_NIC )
+	return rc;
+} // hcf_service_nic
+#endif // HCF_DL_ONLY
+
+
+/************************************************************************************************************
+************************** H C F   S U P P O R T   R O U T I N E S ******************************************
+************************************************************************************************************/
+
+
+/************************************************************************************************************
+*
+*.SUBMODULE		void calc_mic( hcf_32* p, hcf_32 m )
+*.PURPOSE		calculate MIC on a quad byte.
+*
+*.ARGUMENTS
+*	p			address of the MIC
+*	m			32 bit value to be processed by the MIC calculation engine
+*
+*.RETURNS		N.A.
+*
+*.DESCRIPTION
+* calc_mic is the implementation of the MIC algorithm. It is a monkey-see monkey-do copy of
+* Michael::appendByte()
+* of Appendix C of ..........
+*
+*
+*.DIAGRAM
+*
+*.NOTICE
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+
+#if (HCF_TYPE) & HCF_TYPE_WPA
+
+#define ROL32( A, n ) ( ((A) << (n)) | ( ((A)>>(32-(n)))  & ( (1UL << (n)) - 1 ) ) )
+#define ROR32( A, n ) ROL32( (A), 32-(n) )
+
+#define L	*p
+#define R	*(p+1)
+
+void
+calc_mic( hcf_32* p, hcf_32 m )
+{
+#if HCF_BIG_ENDIAN
+	m = (m >> 16) | (m << 16);
+#endif // HCF_BIG_ENDIAN
+	L ^= m;
+	R ^= ROL32( L, 17 );
+	L += R;
+	R ^= ((L & 0xff00ff00) >> 8) | ((L & 0x00ff00ff) << 8);
+	L += R;
+	R ^= ROL32( L, 3 );
+	L += R;
+	R ^= ROR32( L, 2 );
+	L += R;
+} // calc_mic
+#undef R
+#undef L
+#endif // HCF_TYPE_WPA
+
+
+
+#if (HCF_TYPE) & HCF_TYPE_WPA
+/************************************************************************************************************
+*
+*.SUBMODULE		void calc_mic_rx_frag( IFBP ifbp, wci_bufp p, int len )
+*.PURPOSE		calculate MIC on a single fragment.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*	bufp		(byte) address of buffer
+*	len			length in bytes of buffer specified by bufp
+*
+*.RETURNS		N.A.
+*
+*.DESCRIPTION
+* calc_mic_rx_frag ........
+*
+* The MIC is located in the IFB.
+* The MIC is separate for Tx and Rx, thus allowing hcf_send_msg to occur between hcf_service_nic and
+* hcf_rcv_msg.
+*
+*
+*.DIAGRAM
+*
+*.NOTICE
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+void
+calc_mic_rx_frag( IFBP ifbp, wci_bufp p, int len )
+{
+static union { hcf_32 x32; hcf_16 x16[2]; hcf_8 x8[4]; } x;	//* area to accumulate 4 bytes input for MIC engine
+int i;
+
+	if ( len == -1 ) {								//initialize MIC housekeeping
+		i = *(wci_recordp)&p[HFS_STAT];
+		/* i = CNV_SHORTP_TO_LITTLE(&p[HFS_STAT]); should not be neede to prevent alignment poroblems
+		 * since len == -1 if and only if p is lookahaead buffer which MUST be word aligned
+		 * to be re-investigated by NvR
+		 */
+
+		if ( ( i & HFS_STAT_MIC ) == 0 ) {
+			ifbp->IFB_MICRxCarry = 0xFFFF;			//suppress MIC calculation
+		} else {
+			ifbp->IFB_MICRxCarry = 0;
+//*	Note that "coincidentally" the bit positions used in HFS_STAT
+//*	correspond with the offset of the key in IFB_MICKey
+			i = ( i & HFS_STAT_MIC_KEY_ID ) >> 10;	/* coincidentally no shift needed for i itself */
+			ifbp->IFB_MICRx[0] = CNV_LONG_TO_LITTLE(ifbp->IFB_MICRxKey[i  ]);
+			ifbp->IFB_MICRx[1] = CNV_LONG_TO_LITTLE(ifbp->IFB_MICRxKey[i+1]);
+		}
+	} else {
+		if ( ifbp->IFB_MICRxCarry == 0 ) {
+			x.x32 = CNV_LONGP_TO_LITTLE(p);
+			p += 4;
+			if ( len < 4 ) {
+				ifbp->IFB_MICRxCarry = (hcf_16)len;
+			} else {
+				ifbp->IFB_MICRxCarry = 4;
+				len -= 4;
+			}
+		} else while ( ifbp->IFB_MICRxCarry < 4 && len ) {		//note for hcf_16 applies: 0xFFFF > 4
+			x.x8[ifbp->IFB_MICRxCarry++] = *p++;
+			len--;
+		}
+		while ( ifbp->IFB_MICRxCarry == 4 ) {	//contrived so we have only 1 call to calc_mic so we could bring it in-line
+			calc_mic( ifbp->IFB_MICRx, x.x32 );
+			x.x32 = CNV_LONGP_TO_LITTLE(p);
+			p += 4;
+			if ( len < 4 ) {
+				ifbp->IFB_MICRxCarry = (hcf_16)len;
+			}
+			len -= 4;
+		}
+	}
+} // calc_mic_rx_frag
+#endif // HCF_TYPE_WPA
+
+
+#if (HCF_TYPE) & HCF_TYPE_WPA
+/************************************************************************************************************
+*
+*.SUBMODULE		void calc_mic_tx_frag( IFBP ifbp, wci_bufp p, int len )
+*.PURPOSE		calculate MIC on a single fragment.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*	bufp		(byte) address of buffer
+*	len			length in bytes of buffer specified by bufp
+*
+*.RETURNS		N.A.
+*
+*.DESCRIPTION
+* calc_mic_tx_frag ........
+*
+* The MIC is located in the IFB.
+* The MIC is separate for Tx and Rx, thus allowing hcf_send_msg to occur between hcf_service_nic and
+* hcf_rcv_msg.
+*
+*
+*.DIAGRAM
+*
+*.NOTICE
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+void
+calc_mic_tx_frag( IFBP ifbp, wci_bufp p, int len )
+{
+static union { hcf_32 x32; hcf_16 x16[2]; hcf_8 x8[4]; } x;	//* area to accumulate 4 bytes input for MIC engine
+
+														//if initialization request
+	if ( len == -1 ) {
+														//.  presume MIC calculation disabled
+		ifbp->IFB_MICTxCarry = 0xFFFF;
+														//.  if MIC calculation enabled
+		if ( ifbp->IFB_MICTxCntl ) {
+														//.  .  clear MIC carry
+			ifbp->IFB_MICTxCarry = 0;
+														//.  .  initialize MIC-engine
+			ifbp->IFB_MICTx[0] = CNV_LONG_TO_LITTLE(ifbp->IFB_MICTxKey[0]);	/*Tx always uses Key 0 */
+			ifbp->IFB_MICTx[1] = CNV_LONG_TO_LITTLE(ifbp->IFB_MICTxKey[1]);
+		}
+														//else
+	} else {
+														//.  if MIC enabled (Tx) / if MIC present (Rx)
+														//.  and no carry from previous calc_mic_frag
+		if ( ifbp->IFB_MICTxCarry == 0 ) {
+														//.  .  preset accu with 4 bytes from buffer
+			x.x32 = CNV_LONGP_TO_LITTLE(p);
+														//.  .  adjust pointer accordingly
+			p += 4;
+														//.  .  if buffer contained less then 4 bytes
+			if ( len < 4 ) {
+														//.  .  .  promote valid bytes in accu to carry
+														//.  .  .  flag accu to contain incomplete double word
+				ifbp->IFB_MICTxCarry = (hcf_16)len;
+														//.  .  else
+			} else {
+														//.  .  .  flag accu to contain complete double word
+				ifbp->IFB_MICTxCarry = 4;
+														//.  .  adjust remaining buffer length
+				len -= 4;
+			}
+														//.  else if MIC enabled
+														//.  and if carry bytes from previous calc_mic_tx_frag
+														//.  .  move (1-3) bytes from carry into accu
+		} else while ( ifbp->IFB_MICTxCarry < 4 && len ) {		/* note for hcf_16 applies: 0xFFFF > 4 */
+			x.x8[ifbp->IFB_MICTxCarry++] = *p++;
+			len--;
+		}
+														//.  while accu contains complete double word
+														//.  and MIC enabled
+		while ( ifbp->IFB_MICTxCarry == 4 ) {
+														//.  .  pass accu to MIC engine
+			calc_mic( ifbp->IFB_MICTx, x.x32 );
+														//.  .  copy next 4 bytes from buffer to accu
+			x.x32 = CNV_LONGP_TO_LITTLE(p);
+														//.  .  adjust buffer pointer
+			p += 4;
+														//.  .  if buffer contained less then 4 bytes
+														//.  .  .  promote valid bytes in accu to carry
+														//.  .  .  flag accu to contain incomplete double word
+			if ( len < 4 ) {
+				ifbp->IFB_MICTxCarry = (hcf_16)len;
+			}
+														//.  .  adjust remaining buffer length
+			len -= 4;
+		}
+	}
+} // calc_mic_tx_frag
+#endif // HCF_TYPE_WPA
+
+
+#if HCF_PROT_TIME
+/************************************************************************************************************
+*
+*.SUBMODULE		void calibrate( IFBP ifbp )
+*.PURPOSE		calibrates the S/W protection counter against the Hermes Timer tick.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*
+*.RETURNS		N.A.
+*
+*.DESCRIPTION
+* calibrates the S/W protection counter against the Hermes Timer tick
+* IFB_TickIni is the value used to initialize the S/W protection counter such that the expiration period
+* more or less independent of the processor speed. If IFB_TickIni is not yet calibrated, it is done now.
+* This calibration is "reasonably" accurate because the Hermes is in a quiet state as a result of the
+* Initialize command.
+*
+*
+*.DIAGRAM
+*
+*1:	IFB_TickIni is initialized at INI_TICK_INI by hcf_connect. If calibrate succeeds, IFB_TickIni is
+*	guaranteed to be changed. As a consequence there will be only 1 shot at calibration (regardless of the
+*	number of init calls) under normal circumstances.
+*2:	Calibration is done HCF_PROT_TIME_CNT times. This diminish the effects of jitter and interference,
+*	especially in a pre-emptive environment. HCF_PROT_TIME_CNT is in the range of 16 through 32 and derived
+*	from the HCF_PROT_TIME specified by the MSF programmer. The divisor needed to scale HCF_PROT_TIME into the
+*	16-32 range, is used as a multiplicator after the calibration, to scale the found value back to the
+*	requested range. This way a compromise is achieved between accuracy and duration of the calibration
+*	process.
+*3:	Acknowledge the Timer Tick Event.
+*	Each cycle is limited to at most INI_TICK_INI samples of the TimerTick status of the Hermes.
+*	Since the start of calibrate is unrelated to the Hermes Internal Timer, the first interval may last from 0
+*	to the normal interval, all subsequent intervals should be the full length of the Hermes Tick interval.
+*	The Hermes Timer Tick is not reprogrammed by the HCF, hence it is running at the default of 10 k
+*	microseconds.
+*4:	If the Timer Tick Event is continuously up (prot_cnt still has the value INI_TICK_INI) or no Timer Tick
+*	Event occurred before the protection counter expired, reset IFB_TickIni to INI_TICK_INI,
+*	set the defunct bit of IFB_CardStat (thus rendering the Hermes inoperable) and exit the calibrate routine.
+*8:	ifbp->IFB_TickIni is multiplied to scale the found value back to the requested range as explained under 2.
+*
+*.NOTICE
+* o Although there are a number of viewpoints possible, calibrate() uses as error strategy that a single
+*	failure of the Hermes TimerTick is considered fatal.
+* o There is no hard and concrete time-out value defined for Hermes activities. The default 1 seconds is
+*	believed to be sufficiently "relaxed" for real life and to be sufficiently short to be still useful in an
+*	environment with humans.
+* o Note that via IFB_DefunctStat time outs in cmd_wait and in hcfio_string block all Hermes access till the
+*	next init so functions which call a mix of cmd_wait and hcfio_string only need to check the return status
+*	of the last call
+* o The return code is preset at Time out.
+*	The additional complication that no calibrated value for the protection count can be assumed since
+*	calibrate() does not yet have determined a calibrated value (a catch 22), is handled by setting the
+*	initial value at INI_TICK_INI (by hcf_connect). This approach is considered safe, because:
+*	  - the HCF does not use the pipeline mechanism of Hermes commands.
+*	  - the likelihood of failure (the only time when protection count is relevant) is small.
+*	  - the time will be sufficiently large on a fast machine (busy bit drops on good NIC before counter
+*		expires)
+*	  - the time will be sufficiently small on a slow machine (counter expires on bad NIC before the end user
+*	  	switches the power off in despair
+*	The time needed to wrap a 32 bit counter around is longer than many humans want to wait, hence the more or
+*	less arbitrary value of 0x40000L is chosen, assuming it does not take too long on an XT and is not too
+*	short on a scream-machine.
+*
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+HCF_STATIC void
+calibrate( IFBP ifbp )
+{
+int		cnt = HCF_PROT_TIME_CNT;
+hcf_32	prot_cnt;
+
+	HCFTRACE( ifbp, HCF_TRACE_CALIBRATE );
+	if ( ifbp->IFB_TickIni == INI_TICK_INI ) {													/*1*/
+		ifbp->IFB_TickIni = 0;																	/*2*/
+			while ( cnt-- ) {
+				prot_cnt = INI_TICK_INI;
+				OPW( HREG_EV_ACK, HREG_EV_TICK );												/*3*/
+				while ( (IPW( HREG_EV_STAT ) & HREG_EV_TICK) == 0 && --prot_cnt ) {
+					ifbp->IFB_TickIni++;
+				}
+				if ( prot_cnt == 0 || prot_cnt == INI_TICK_INI ) {								/*4*/
+					ifbp->IFB_TickIni = INI_TICK_INI;
+					ifbp->IFB_DefunctStat = HCF_ERR_DEFUNCT_TIMER;
+					ifbp->IFB_CardStat |= CARD_STAT_DEFUNCT;
+					HCFASSERT( DO_ASSERT, prot_cnt )
+				}
+			}
+		ifbp->IFB_TickIni <<= HCF_PROT_TIME_SHFT;												/*8*/
+	}
+	HCFTRACE( ifbp, HCF_TRACE_CALIBRATE | HCF_TRACE_EXIT );
+} // calibrate
+#endif // HCF_PROT_TIME
+
+
+#if (HCF_DL_ONLY) == 0
+#if (HCF_TYPE) & HCF_TYPE_WPA
+/************************************************************************************************************
+*
+*.SUBMODULE		int check_mic( IFBP ifbp )
+*.PURPOSE		verifies the MIC of a received non-USB frame.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*
+*.RETURNS
+*	HCF_SUCCESS
+*	HCF_ERR_MIC
+*
+*.DESCRIPTION
+*
+*
+*.DIAGRAM
+*
+*4:	test whether or not a MIC is reported by the Hermes
+*14: the calculated MIC and the received MIC are compared, the return status is set when there is a mismatch
+*
+*.NOTICE
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+int
+check_mic( IFBP ifbp )
+{
+int		rc = HCF_SUCCESS;
+hcf_32 x32[2];				//* area to save rcvd 8 bytes MIC
+
+													//if MIC present in RxFS
+	if ( *(wci_recordp)&ifbp->IFB_lap[-HFS_ADDR_DEST] & HFS_STAT_MIC ) {
+	//or if ( ifbp->IFB_MICRxCarry != 0xFFFF )
+		CALC_RX_MIC( mic_pad, 8 );					//.  process up to 3 remaining bytes of data and append 5 to 8 bytes of padding to MIC calculation
+		get_frag( ifbp, (wci_bufp)x32, 8 BE_PAR(0));//.  get 8 byte MIC from NIC
+													//.  if calculated and received MIC do not match
+													//.  .  set status at HCF_ERR_MIC
+/*14*/  if ( x32[0] != CNV_LITTLE_TO_LONG(ifbp->IFB_MICRx[0]) ||
+        	 x32[1] != CNV_LITTLE_TO_LONG(ifbp->IFB_MICRx[1])	  ) {
+			rc = HCF_ERR_MIC;
+		}
+	}
+													//return status
+	return rc;
+} // check_mic
+#endif // HCF_TYPE_WPA
+#endif // HCF_DL_ONLY
+
+
+/************************************************************************************************************
+*
+*.SUBMODULE		int cmd_cmpl( IFBP ifbp )
+*.PURPOSE		waits for Hermes Command Completion.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*
+*.RETURNS
+*	IFB_DefunctStat
+*	HCF_ERR_TIME_OUT
+*	HCF_ERR_DEFUNCT_CMD_SEQ
+*	HCF_SUCCESS
+*
+*.DESCRIPTION
+*
+*
+*.DIAGRAM
+*
+*2:	Once cmd_cmpl is called, the Busy option bit in IFB_Cmd must be cleared
+*4:	If Status register and command code don't match either:
+*	 - the Hermes and Host are out of sync ( a fatal error)
+*	 - error bits are reported via the Status Register.
+*	Out of sync is considered fatal and brings the HCF in Defunct mode
+*	Errors reported via the Status Register should be caused by sequence violations in Hermes command
+*	sequences and hence these bugs should have been found during engineering testing. Since there is no
+*	strategy to cope with this problem, it might as well be ignored at run time. Note that for any particular
+*	situation where a strategy is formulated to handle the consequences of a particular bug causing a
+*	particular Error situation reported via the Status Register, the bug should be removed rather than adding
+*	logic to cope with the consequences of the bug.
+*	There have been HCF versions where an error report via the Status Register even brought the HCF in defunct
+*	mode (although it was not yet named like that at that time). This is particular undesirable behavior for a
+*	general library.
+*	Simply reporting the error (as "interesting") is debatable. There also have been HCF versions with this
+*	strategy using the "vague" HCF_FAILURE code.
+*	The error is reported via:
+*	 - MiscErr tally of the HCF Tally set
+*	 - the (informative) fields IFB_ErrCmd and IFB_ErrQualifier
+*	 - the assert mechanism
+*8:	Here the Defunct case and the Status error are separately treated
+*
+*
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+HCF_STATIC int
+cmd_cmpl( IFBP ifbp )
+{
+
+PROT_CNT_INI
+int		rc = HCF_SUCCESS;
+hcf_16	stat;
+
+	HCFLOGENTRY( HCF_TRACE_CMD_CPL, ifbp->IFB_Cmd )
+	ifbp->IFB_Cmd &= ~HCMD_BUSY;												/* 2 */
+	HCF_WAIT_WHILE( (IPW( HREG_EV_STAT) & HREG_EV_CMD) == 0 );					/* 4 */
+	stat = IPW( HREG_STAT );
+#if HCF_PROT_TIME
+	if ( prot_cnt == 0 ) {
+		IF_TALLY( ifbp->IFB_HCF_Tallies.MiscErr++; )
+		rc = HCF_ERR_TIME_OUT;
+		HCFASSERT( DO_ASSERT, ifbp->IFB_Cmd )
+	} else
+#endif // HCF_PROT_TIME
+	{
+		DAWA_ACK( HREG_EV_CMD );
+/*4*/	if ( stat != (ifbp->IFB_Cmd & HCMD_CMD_CODE) ) {
+/*8*/		if ( ( (stat ^ ifbp->IFB_Cmd ) & HCMD_CMD_CODE) != 0 ) {
+				rc = ifbp->IFB_DefunctStat = HCF_ERR_DEFUNCT_CMD_SEQ;
+				ifbp->IFB_CardStat |= CARD_STAT_DEFUNCT;
+			}
+			IF_TALLY( ifbp->IFB_HCF_Tallies.MiscErr++; )
+			ifbp->IFB_ErrCmd = stat;
+			ifbp->IFB_ErrQualifier = IPW( HREG_RESP_0 );
+			HCFASSERT( DO_ASSERT, MERGE_2( IPW( HREG_PARAM_0 ), ifbp->IFB_Cmd ) )
+			HCFASSERT( DO_ASSERT, MERGE_2( ifbp->IFB_ErrQualifier, ifbp->IFB_ErrCmd ) )
+		}
+	}
+	HCFASSERT( rc == HCF_SUCCESS, rc)
+	HCFLOGEXIT( HCF_TRACE_CMD_CPL )
+	return rc;
+} // cmd_cmpl
+
+
+/************************************************************************************************************
+*
+*.SUBMODULE		int cmd_exe( IFBP ifbp, int cmd_code, int par_0 )
+*.PURPOSE		Executes synchronous part of Hermes Command and - optionally - waits for Command Completion.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*	cmd_code
+*	par_0
+*
+*.RETURNS
+*	IFB_DefunctStat
+*	HCF_ERR_DEFUNCT_CMD_SEQ
+*	HCF_SUCCESS
+*	HCF_ERR_TO_BE_ADDED	<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+*
+*.DESCRIPTION
+* Executes synchronous Hermes Command and waits for Command Completion
+*
+* The general HCF strategy is to wait for command completion. As a consequence:
+* - the read of the busy bit before writing the command register is superfluous
+* - the Hermes requirement that no Inquiry command may be executed if there is still an unacknowledged
+*	Inquiry command outstanding, is automatically met.
+* The Tx command uses the "Busy" bit in the cmd_code parameter to deviate from this general HCF strategy.
+* The idea is that by not busy-waiting on completion of this frequently used command the processor
+* utilization is diminished while using the busy-wait on all other seldom used commands the flow is kept
+* simple.
+*
+*
+*
+*.DIAGRAM
+*
+*1:	skip the body of cmd_exe when in defunct mode or when - based on the S/W Support register write and
+*	read back test - there is apparently no NIC.
+*	Note: we gave up on the "old" strategy to write the S/W Support register at magic only when needed. Due to
+*	the intricateness of Hermes F/W varieties ( which behave differently as far as corruption of the S/W
+*	Support register is involved), the increasing number of Hermes commands which do an implicit initialize
+*	(thus modifying the S/W Support register) and the workarounds of some OS/Support S/W induced aspects (e.g.
+*	the System Soft library at WinNT which postpones the actual mapping of I/O space up to 30 seconds after
+*	giving the go-ahead), the "magic" strategy is now reduced to a simple write and read back. This means that
+*	problems like a bug tramping over the memory mapped Hermes registers will no longer be noticed as side
+*	effect of the S/W Support register check.
+*2:	check whether the preceding command skipped the busy wait and if so, check for command completion
+*
+*.NOTICE
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+
+HCF_STATIC int
+cmd_exe( IFBP ifbp, hcf_16 cmd_code, hcf_16 par_0 )	//if HCMD_BUSY of cmd_code set, then do NOT wait for completion
+{
+int rc;
+
+	HCFLOGENTRY( HCF_TRACE_CMD_EXE, cmd_code )
+	HCFASSERT( (cmd_code & HCMD_CMD_CODE) != HCMD_TX || cmd_code & HCMD_BUSY, cmd_code ) //Tx must have Busy bit set
+	OPW( HREG_SW_0, HCF_MAGIC );
+	if ( IPW( HREG_SW_0 ) == HCF_MAGIC ) {														/* 1 */
+		rc = ifbp->IFB_DefunctStat;
+	}
+	else rc = HCF_ERR_NO_NIC;
+	if ( rc == HCF_SUCCESS ) {
+		//;?is this a hot idea, better MEASURE performance impact
+/*2*/	if ( ifbp->IFB_Cmd & HCMD_BUSY ) {
+			rc = cmd_cmpl( ifbp );
+		}
+		OPW( HREG_PARAM_0, par_0 );
+		OPW( HREG_CMD, cmd_code &~HCMD_BUSY );
+		ifbp->IFB_Cmd = cmd_code;
+		if ( (cmd_code & HCMD_BUSY) == 0 ) {	//;?is this a hot idea, better MEASURE performance impact
+			rc = cmd_cmpl( ifbp );
+		}
+	}
+	HCFASSERT( rc == HCF_SUCCESS, MERGE_2( rc, cmd_code ) )
+	HCFLOGEXIT( HCF_TRACE_CMD_EXE )
+	return rc;
+} // cmd_exe
+
+
+/************************************************************************************************************
+*
+*.SUBMODULE		int download( IFBP ifbp, CFG_PROG_STRCT FAR *ltvp )
+*.PURPOSE		downloads F/W image into NIC and initiates execution of the downloaded F/W.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*	ltvp		specifies the pseudo-RID (as defined by WCI)
+*
+*.RETURNS
+*
+*.DESCRIPTION
+*
+*
+*.DIAGRAM
+*1:	First, Ack everything to unblock a (possibly) blocked cmd pipe line
+*	Note 1: it is very likely that an Alloc event is pending and very well possible that a (Send) Cmd event is
+*	pending
+*	Note 2: it is assumed that this strategy takes away the need to ack every conceivable event after an
+*	Hermes Initialize
+*
+*
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+HCF_STATIC int
+download( IFBP ifbp, CFG_PROG_STRCT FAR *ltvp )						//Hermes-II download (volatile only)
+{
+hcf_16				i;
+int					rc = HCF_SUCCESS;
+wci_bufp			cp;
+hcf_io				io_port = ifbp->IFB_IOBase + HREG_AUX_DATA;
+
+	HCFLOGENTRY( HCF_TRACE_DL, ltvp->typ )
+#if (HCF_TYPE) & HCF_TYPE_PRELOADED
+	HCFASSERT( DO_ASSERT, ltvp->mode )
+#else
+													//if initial "program" LTV
+	if ( ifbp->IFB_DLMode == CFG_PROG_STOP && ltvp->mode == CFG_PROG_VOLATILE) {
+													//.  switch Hermes to initial mode
+/*1*/	OPW( HREG_EV_ACK, ~HREG_EV_SLEEP_REQ );
+		rc = cmd_exe( ifbp, HCMD_INI, 0 );	/* HCMD_INI can not be part of init() because that is called on
+											 * other occasions as well */
+		rc = init( ifbp );
+	}
+													//if final "program" LTV
+	if ( ltvp->mode == CFG_PROG_STOP && ifbp->IFB_DLMode == CFG_PROG_VOLATILE) {
+													//.  start tertiary (or secondary)
+		OPW( HREG_PARAM_1, (hcf_16)(ltvp->nic_addr >> 16) );
+		rc = cmd_exe( ifbp, HCMD_EXECUTE, (hcf_16) ltvp->nic_addr );
+		if (rc == HCF_SUCCESS) {
+			rc = init( ifbp );	/*;? do we really want to skip init if cmd_exe failed, i.e.
+								 *	 IFB_FW_Comp_Id is than possibly incorrect */
+	  	}
+													//else (non-final)
+	} else {
+													//.  if mode == Readback SEEPROM
+#if 0	//;? as long as the next if contains a hard coded 0, might as well leave it out even more obvious
+		if ( 0 /*len is definitely not want we want;?*/ && ltvp->mode == CFG_PROG_SEEPROM_READBACK ) {
+			OPW( HREG_PARAM_1, (hcf_16)(ltvp->nic_addr >> 16) );
+			OPW( HREG_PARAM_2, MUL_BY_2(ltvp->len - 4));
+													//.  .  perform Hermes prog cmd with appropriate mode bits
+			rc = cmd_exe( ifbp, HCMD_PROGRAM | ltvp->mode, (hcf_16)ltvp->nic_addr );
+													//.  .  set up NIC RAM addressability according Resp0-1
+			OPW( HREG_AUX_PAGE,   IPW( HREG_RESP_1) );
+			OPW( HREG_AUX_OFFSET, IPW( HREG_RESP_0) );
+													//.  .  set up L-field of LTV according Resp2
+			i = ( IPW( HREG_RESP_2 ) + 1 ) / 2;  // i contains max buffer size in words, a probably not very useful piece of information ;?
+/*Nico's code based on i is the "real amount of data available"
+			if ( ltvp->len - 4 < i ) rc = HCF_ERR_LEN;
+			else ltvp->len = i + 4;
+*/
+/* Rolands code based on the idea that a MSF should not ask for more than is available
+			// check if number of bytes requested exceeds max buffer size
+			if ( ltvp->len - 4 > i ) {
+				rc = HCF_ERR_LEN;
+				ltvp->len = i + 4;
+			}
+*/
+													//.  .  copy data from NIC via AUX port to LTV
+			cp = (wci_bufp)ltvp->host_addr;						/*IN_PORT_STRING_8_16 macro may modify its parameters*/
+			i = ltvp->len - 4;
+			IN_PORT_STRING_8_16( io_port, cp, i );		//!!!WORD length, cp MUST be a char pointer	// $$ char
+													//.  else (non-final programming)
+		} else
+#endif //;? as long as the above if contains a hard coded 0, might as well leave it out even more obvious
+		{											//.  .  get number of words to program
+			HCFASSERT( ltvp->segment_size, *ltvp->host_addr )
+			i = ltvp->segment_size/2;
+													//.  .  copy data (words) from LTV via AUX port to NIC
+			cp = (wci_bufp)ltvp->host_addr;						//OUT_PORT_STRING_8_16 macro may modify its parameters
+													//.  .  if mode == volatile programming
+			if ( ltvp->mode == CFG_PROG_VOLATILE ) {
+													//.  .  .  set up NIC RAM addressability via AUX port
+				OPW( HREG_AUX_PAGE, (hcf_16)(ltvp->nic_addr >> 16 << 9 | (ltvp->nic_addr & 0xFFFF) >> 7 ) );
+				OPW( HREG_AUX_OFFSET, (hcf_16)(ltvp->nic_addr & 0x007E) );
+				OUT_PORT_STRING_8_16( io_port, cp, i );		//!!!WORD length, cp MUST be a char pointer
+			}
+		}
+	}
+	ifbp->IFB_DLMode = ltvp->mode;					//save state in IFB_DLMode
+#endif // HCF_TYPE_PRELOADED
+	HCFASSERT( rc == HCF_SUCCESS, rc )
+	HCFLOGEXIT( HCF_TRACE_DL )
+	return rc;
+} // download
+
+
+#if (HCF_ASSERT) & HCF_ASSERT_PRINTF
+/**************************************************
+* Certain Hermes-II firmware versions can generate
+* debug information. This debug information is
+* contained in a buffer in nic-RAM, and can be read
+* via the aux port.
+**************************************************/
+HCF_STATIC int
+fw_printf(IFBP ifbp, CFG_FW_PRINTF_STRCT FAR *ltvp)
+{
+    int rc = HCF_SUCCESS;
+    hcf_16 fw_cnt;
+//    hcf_32 DbMsgBuffer = 0x29D2, DbMsgCount= 0x000029D0;
+//    hcf_16 DbMsgSize=0x00000080;
+    hcf_32 DbMsgBuffer;
+    CFG_FW_PRINTF_BUFFER_LOCATION_STRCT *p = &ifbp->IFB_FwPfBuff;
+    ltvp->len = 1;
+    if ( p->DbMsgSize != 0 ) {
+        // first, check the counter in nic-RAM and compare it to the latest counter value of the HCF
+        OPW( HREG_AUX_PAGE, (hcf_16)(p->DbMsgCount >> 7) );
+        OPW( HREG_AUX_OFFSET, (hcf_16)(p->DbMsgCount & 0x7E) );
+        fw_cnt = ((IPW( HREG_AUX_DATA) >>1 ) & ((hcf_16)p->DbMsgSize - 1));
+        if ( fw_cnt != ifbp->IFB_DbgPrintF_Cnt ) {
+//    DbgPrint("fw_cnt=%d IFB_DbgPrintF_Cnt=%d\n", fw_cnt, ifbp->IFB_DbgPrintF_Cnt);
+            DbMsgBuffer = p->DbMsgBuffer + ifbp->IFB_DbgPrintF_Cnt * 6; // each entry is 3 words
+            OPW( HREG_AUX_PAGE, (hcf_16)(DbMsgBuffer >> 7) );
+            OPW( HREG_AUX_OFFSET, (hcf_16)(DbMsgBuffer & 0x7E) );
+            ltvp->msg_id     = IPW(HREG_AUX_DATA);
+            ltvp->msg_par    = IPW(HREG_AUX_DATA);
+            ltvp->msg_tstamp = IPW(HREG_AUX_DATA);
+            ltvp->len = 4;
+            ifbp->IFB_DbgPrintF_Cnt++;
+            ifbp->IFB_DbgPrintF_Cnt &= (p->DbMsgSize - 1);
+        }
+    }
+    return rc;
+};
+#endif // HCF_ASSERT_PRINTF
+
+
+#if (HCF_DL_ONLY) == 0
+/************************************************************************************************************
+*
+*.SUBMODULE		hcf_16 get_fid( IFBP ifbp )
+*.PURPOSE		get allocated FID for either transmit or notify.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*
+*.RETURNS
+*	0	no FID available
+*	<>0	FID number
+*
+*.DESCRIPTION
+*
+*
+*.DIAGRAM
+*	The preference is to use a "pending" alloc. If no alloc is pending, then - if available - the "spare" FID
+*	is used.
+*	If the spare FID is used, IFB_RscInd (representing the spare FID) must be cleared
+*	If the pending alloc is used, the alloc event must be acknowledged to the Hermes.
+*	In case the spare FID was depleted and the IFB_RscInd has been "faked" as pseudo resource with a 0x0001
+*	value by hcf_service_nic, IFB_RscInd has to be "corrected" again to its 0x0000 value.
+*
+*	Note that due to the Hermes-II H/W problems which are intended to be worked around by DAWA, the Alloc bit
+*	in the Event register is no longer a reliable indication of the presence/absence of a FID. The "Clear FID"
+*	part of the DAWA logic, together with the choice of the definition of the return information from get_fid,
+*	handle this automatically, i.e. without additional code in get_fid.
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+HCF_STATIC hcf_16
+get_fid( IFBP ifbp )
+{
+
+hcf_16 fid = 0;
+#if ( (HCF_TYPE) & HCF_TYPE_HII5 ) == 0
+PROT_CNT_INI
+#endif // HCF_TYPE_HII5
+
+	IF_DMA( HCFASSERT(!(ifbp->IFB_CntlOpt & USE_DMA), ifbp->IFB_CntlOpt) )
+
+	if ( IPW( HREG_EV_STAT) & HREG_EV_ALLOC) {
+		fid = IPW( HREG_ALLOC_FID );
+		HCFASSERT( fid, ifbp->IFB_RscInd )
+		DAWA_ZERO_FID( HREG_ALLOC_FID )
+#if ( (HCF_TYPE) & HCF_TYPE_HII5 ) == 0
+		HCF_WAIT_WHILE( ( IPW( HREG_EV_STAT ) & HREG_EV_ACK_REG_READY ) == 0 );
+		HCFASSERT( prot_cnt, IPW( HREG_EV_STAT ) )
+#endif // HCF_TYPE_HII5
+		DAWA_ACK( HREG_EV_ALLOC );			//!!note that HREG_EV_ALLOC is written only once
+// 180 degree error in logic ;? #if ALLOC_15
+		if ( ifbp->IFB_RscInd == 1 ) {
+			ifbp->IFB_RscInd = 0;
+		}
+//#endif // ALLOC_15
+	} else {
+// 180 degree error in logic ;? #if ALLOC_15
+		fid = ifbp->IFB_RscInd;
+//#endif // ALLOC_15
+		ifbp->IFB_RscInd = 0;
+	}
+	return fid;
+} // get_fid
+#endif // HCF_DL_ONLY
+
+
+/************************************************************************************************************
+*
+*.SUBMODULE		void get_frag( IFBP ifbp, wci_bufp bufp, int len BE_PAR( int word_len ) )
+*.PURPOSE		reads with 16/32 bit I/O via BAP1 port from NIC RAM to Host memory.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*	bufp		(byte) address of buffer
+*	len			length in bytes of buffer specified by bufp
+*	word_len	Big Endian only: number of leading bytes to swap in pairs
+*
+*.RETURNS		N.A.
+*
+*.DESCRIPTION
+* process the single byte (if applicable) read by the previous get_frag and copy len (or len-1) bytes from
+* NIC to bufp.
+* On a Big Endian platform, the parameter word_len controls the number of leading bytes whose endianess is
+* converted (i.e. byte swapped)
+*
+*
+*.DIAGRAM
+*10: The PCMCIA card can be removed in the middle of the transfer. By depositing a "magic number" in the
+*	HREG_SW_0 register of the Hermes at initialization time and by verifying this register, it can be
+*	determined whether the card is still present. The return status is set accordingly.
+*	Clearing the buffer is a (relative) cheap way to prevent that failing I/O results in run-away behavior
+*	because the garbage in the buffer is interpreted by the caller irrespective of the return status (e.g.
+*	hcf_service_nic has this behavior).
+*
+*.NOTICE
+*	It turns out DOS ODI uses zero length fragments. The HCF code can cope with it, but as a consequence, no
+*	Assert on len is possible
+*
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+HCF_STATIC void
+get_frag( IFBP ifbp, wci_bufp bufp, int len BE_PAR( int word_len ) )
+{
+hcf_io		io_port = ifbp->IFB_IOBase + HREG_DATA_1;	//BAP data register
+wci_bufp	p = bufp;									//working pointer
+int			i;											//prevent side effects from macro
+int			j;
+
+	HCFASSERT( ((hcf_32)bufp & (HCF_ALIGN-1) ) == 0, (hcf_32)bufp )
+
+/*1:	here recovery logic for intervening BAP access between hcf_service_nic and hcf_rcv_msg COULD be added
+ * 	if current access is RxInitial
+ * 	.  persistent_offset += len
+ */
+
+	i = len;
+													//if buffer length > 0 and carry from previous get_frag
+	if ( i && ifbp->IFB_CarryIn ) {
+													//.  move carry to buffer
+													//.  adjust buffer length and pointer accordingly
+		*p++ = (hcf_8)(ifbp->IFB_CarryIn>>8);
+		i--;
+													//.  clear carry flag
+		ifbp->IFB_CarryIn = 0;
+	}
+#if (HCF_IO) & HCF_IO_32BITS
+	//skip zero-length I/O, single byte I/O and I/O not worthwhile (i.e. less than 6 bytes)for DW logic
+													//if buffer length >= 6 and 32 bits I/O support
+	if ( !(ifbp->IFB_CntlOpt & USE_16BIT) && i >= 6 ) {
+hcf_32 FAR	*p4; //prevent side effects from macro
+		if ( ( (hcf_32)p & 0x1 ) == 0 ) {			//.  if buffer at least word aligned
+			if ( (hcf_32)p & 0x2 ) {				//.  .  if buffer not double word aligned
+													//.  .  .  read single word to get double word aligned
+				*(wci_recordp)p = IN_PORT_WORD( io_port );
+													//.  .  .  adjust buffer length and pointer accordingly
+				p += 2;
+				i -= 2;
+			}
+													//.  .  read as many double word as possible
+			p4 = (hcf_32 FAR *)p;
+			j = i/4;
+			IN_PORT_STRING_32( io_port, p4, j );
+													//.  .  adjust buffer length and pointer accordingly
+			p += i & ~0x0003;
+			i &= 0x0003;
+		}
+	}
+#endif // HCF_IO_32BITS
+													//if no 32-bit support OR byte aligned OR 1-3 bytes left
+	if ( i ) {
+													//.  read as many word as possible in "alignment safe" way
+		j = i/2;
+		IN_PORT_STRING_8_16( io_port, p, j );
+													//.  if 1 byte left
+		if ( i & 0x0001 ) {
+													//.  .  read 1 word
+			ifbp->IFB_CarryIn = IN_PORT_WORD( io_port );
+													//.  .  store LSB in last char of buffer
+			bufp[len-1] = (hcf_8)ifbp->IFB_CarryIn;
+													//.  .  save MSB in carry, set carry flag
+			ifbp->IFB_CarryIn |= 0x1;
+		}
+	}
+#if HCF_BIG_ENDIAN
+	HCFASSERT( word_len == 0 || word_len == 2 || word_len == 4, word_len )
+	HCFASSERT( word_len == 0 || ((hcf_32)bufp & 1 ) == 0, (hcf_32)bufp )
+	HCFASSERT( word_len <= len, MERGE2( word_len, len ) )
+	//see put_frag for an alternative implementation, but be carefull about what are int's and what are
+	//hcf_16's
+	if ( word_len ) {								//.  if there is anything to convert
+hcf_8 c;
+		c = bufp[1];								//.  .  convert the 1st hcf_16
+		bufp[1] = bufp[0];
+		bufp[0] = c;
+		if ( word_len > 1 ) {						//.  .  if there is to convert more than 1 word ( i.e 2 )
+			c = bufp[3];							//.  .  .  convert the 2nd hcf_16
+			bufp[3] = bufp[2];
+			bufp[2] = c;
+		}
+	}
+#endif // HCF_BIG_ENDIAN
+} // get_frag
+
+/************************************************************************************************************
+*
+*.SUBMODULE		int init( IFBP ifbp )
+*.PURPOSE		Handles common initialization aspects (H-I init, calibration, config.mngmt, allocation).
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*
+*.RETURNS
+*	HCF_ERR_INCOMP_PRI
+*	HCF_ERR_INCOMP_FW
+*	HCF_ERR_TIME_OUT
+*	>>hcf_get_info
+*		HCF_ERR_NO_NIC
+*		HCF_ERR_LEN
+*
+*.DESCRIPTION
+* init will successively:
+* - in case of a (non-preloaded) H-I, initialize the NIC
+* - calibrate the S/W protection timer against the Hermes Timer
+* - collect HSI, "active" F/W Configuration Management Information
+* - in case active F/W is Primary F/W: collect Primary F/W Configuration Management Information
+* - check HSI and Primary F/W compatibility with the HCF
+* - in case active F/W is Station or AP F/W: check Station or AP F/W compatibility with the HCF
+* - in case active F/W is not Primary F/W: allocate FIDs to be used in transmit/notify process
+*
+*
+*.DIAGRAM
+*2:	drop all error status bits in IFB_CardStat since they are expected to be re-evaluated.
+*4:	Ack everything except HREG_EV_SLEEP_REQ. It is very likely that an Alloc event is pending and
+*	very well possible that a Send Cmd event is pending. Acking HREG_EV_SLEEP_REQ is handled by hcf_action(
+*	HCF_ACT_INT_ON ) !!!
+*10: Calibrate the S/W time-out protection mechanism by calling calibrate(). Note that possible errors
+*	in the calibration process are nor reported by init but will show up via the defunct mechanism in
+*	subsequent hcf-calls.
+*14: usb_check_comp() is called to have the minimal visual clutter for the legacy H-I USB dongle
+*	compatibility check.
+*16: The following configuration management related information is retrieved from the NIC:
+*	 - HSI supplier
+*	 - F/W Identity
+*	 - F/W supplier
+*	 if appropriate:
+*	 - PRI Identity
+*	 - PRI supplier
+*	 appropriate means on H-I: always
+*	 and on H-II if F/W supplier reflects a primary (i.e. only after an Hermes Reset or Init
+*	 command).
+*	 QUESTION ;? !!!!!! should, For each of the above RIDs the Endianess is converted to native Endianess.
+*	 Only the return code of the first hcf_get_info is used. All hcf_get_info calls are made, regardless of
+*	 the success or failure of the 1st hcf_get_info. The assumptions are:
+*	  - if any call fails, they all fail, so remembering the result of the 1st call is adequate
+*	  - a failing call will overwrite the L-field with a 0x0000 value, which services both as an
+*		error indication for the values cached in the IFB as making mmd_check_comp fail.
+*	 In case of H-I, when getting the F/W identity fails, the F/W is assumed to be H-I AP F/W pre-dating
+*	 version 9.0 and the F/W Identity and Supplier are faked accordingly.
+*	 In case of H-II, the Primary, Station and AP Identity are merged into a single F/W Identity.
+*	 The same applies to the Supplier information. As a consequence the PRI information can no longer be
+*	 retrieved when a Tertiary runs. To accommodate MSFs and Utilities who depend on PRI information being
+*	 available at any time, this information is cached in the IFB. In this cache the generic "F/W" value of
+*	 the typ-fields is overwritten with the specific (legacy) "PRI" values. To actually re-route the (legacy)
+*	 PRI request via hcf_get_info, the xxxx-table must be set.  In case of H-I, this caching, modifying and
+*	 re-routing is not needed because PRI information is always available directly from the NIC. For
+*	 consistency the caching fields in the IFB are filled with the PRI information anyway.
+*18: mdd_check_comp() is called to check the Supplier Variant and Range of the Host-S/W I/F (HSI) and the
+*	Primary Firmware Variant and Range against the Top and Bottom level supported by this HCF.  If either of
+*	these tests fails, the CARD_STAT_INCOMP_PRI bit of IFB_CardStat is set
+*	Note: There should always be a primary except during production, so this makes the HCF in its current form
+*	unsuitable for manufacturing test systems like the FTS. This can be remedied by an adding a test like
+*	ifbp->IFB_PRISup.id == COMP_ID_PRI
+*20: In case there is Tertiary F/W and this F/W is Station F/W, the Supplier Variant and Range of the Station
+*	Firmware function as retrieved from the Hermes is checked against the Top and Bottom level supported by
+*	this HCF.
+*	Note: ;? the tertiary F/W compatibility checks could be moved to the DHF, which already has checked the
+*	CFI and MFI compatibility of the image with the NIC before the image was downloaded.
+*28: In case of non-Primary F/W: allocates and acknowledge a (TX or Notify) FID and allocates without
+*	acknowledge another (TX or Notify) FID (the so-called 1.5 alloc scheme) with the following steps:
+*	- execute the allocate command by calling cmd_exe
+*	- wait till either the alloc event or a time-out occurs
+*	- regardless whether the alloc event occurs, call get_fid to
+*	  - read the FID and save it in IFB_RscInd to be used as "spare FID"
+*	  - acknowledge the alloc event
+*	  - do another "half" allocate to complete the "1.5 Alloc scheme"
+*	  Note that above 3 steps do not harm and thus give the "cheapest" acceptable strategy.
+*	  If a time-out occurred, then report time out status (after all)
+*
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+HCF_STATIC int
+init( IFBP ifbp )
+{
+
+int	rc = HCF_SUCCESS;
+
+	HCFLOGENTRY( HCF_TRACE_INIT, 0 )
+
+	ifbp->IFB_CardStat = 0;																			/* 2*/
+	OPW( HREG_EV_ACK, ~HREG_EV_SLEEP_REQ ); 											/* 4*/
+	IF_PROT_TIME( calibrate( ifbp ); ) 													/*10*/
+#if 0 // OOR
+	ifbp->IFB_FWIdentity.len = 2;							//misuse the IFB space for a put
+	ifbp->IFB_FWIdentity.typ = CFG_TICK_TIME;
+	ifbp->IFB_FWIdentity.comp_id = (1000*1000)/1024 + 1;	//roughly 1 second
+	hcf_put_info( ifbp, (LTVP)&ifbp->IFB_FWIdentity.len );
+#endif // OOR
+	ifbp->IFB_FWIdentity.len = sizeof(CFG_FW_IDENTITY_STRCT)/sizeof(hcf_16) - 1;
+	ifbp->IFB_FWIdentity.typ = CFG_FW_IDENTITY;
+	rc = hcf_get_info( ifbp, (LTVP)&ifbp->IFB_FWIdentity.len );
+/* ;? conversion should not be needed for mmd_check_comp */
+#if HCF_BIG_ENDIAN
+	ifbp->IFB_FWIdentity.comp_id       = CNV_LITTLE_TO_SHORT( ifbp->IFB_FWIdentity.comp_id );
+	ifbp->IFB_FWIdentity.variant       = CNV_LITTLE_TO_SHORT( ifbp->IFB_FWIdentity.variant );
+	ifbp->IFB_FWIdentity.version_major = CNV_LITTLE_TO_SHORT( ifbp->IFB_FWIdentity.version_major );
+	ifbp->IFB_FWIdentity.version_minor = CNV_LITTLE_TO_SHORT( ifbp->IFB_FWIdentity.version_minor );
+#endif // HCF_BIG_ENDIAN
+#if defined MSF_COMPONENT_ID																		/*14*/
+	if ( rc == HCF_SUCCESS ) {																		/*16*/
+		ifbp->IFB_HSISup.len = sizeof(CFG_SUP_RANGE_STRCT)/sizeof(hcf_16) - 1;
+		ifbp->IFB_HSISup.typ = CFG_NIC_HSI_SUP_RANGE;
+		rc = hcf_get_info( ifbp, (LTVP)&ifbp->IFB_HSISup.len );
+/* ;? conversion should not be needed for mmd_check_comp , BUT according to a report of a BE-user it is
+ * should be resolved in the WARP release
+ * since some compilers make ugly but unnecessary code of these instructions even for LE,
+ * it is conditionally compiled */
+#if HCF_BIG_ENDIAN
+		ifbp->IFB_HSISup.role    = CNV_LITTLE_TO_SHORT( ifbp->IFB_HSISup.role );
+		ifbp->IFB_HSISup.id      = CNV_LITTLE_TO_SHORT( ifbp->IFB_HSISup.id );
+		ifbp->IFB_HSISup.variant = CNV_LITTLE_TO_SHORT( ifbp->IFB_HSISup.variant );
+		ifbp->IFB_HSISup.bottom  = CNV_LITTLE_TO_SHORT( ifbp->IFB_HSISup.bottom );
+		ifbp->IFB_HSISup.top     = CNV_LITTLE_TO_SHORT( ifbp->IFB_HSISup.top );
+#endif // HCF_BIG_ENDIAN
+		ifbp->IFB_FWSup.len = sizeof(CFG_SUP_RANGE_STRCT)/sizeof(hcf_16) - 1;
+		ifbp->IFB_FWSup.typ = CFG_FW_SUP_RANGE;
+		(void)hcf_get_info( ifbp, (LTVP)&ifbp->IFB_FWSup.len );
+/* ;? conversion should not be needed for mmd_check_comp */
+#if HCF_BIG_ENDIAN
+		ifbp->IFB_FWSup.role    = CNV_LITTLE_TO_SHORT( ifbp->IFB_FWSup.role );
+		ifbp->IFB_FWSup.id      = CNV_LITTLE_TO_SHORT( ifbp->IFB_FWSup.id );
+		ifbp->IFB_FWSup.variant = CNV_LITTLE_TO_SHORT( ifbp->IFB_FWSup.variant );
+		ifbp->IFB_FWSup.bottom  = CNV_LITTLE_TO_SHORT( ifbp->IFB_FWSup.bottom );
+		ifbp->IFB_FWSup.top     = CNV_LITTLE_TO_SHORT( ifbp->IFB_FWSup.top );
+#endif // HCF_BIG_ENDIAN
+
+		if ( ifbp->IFB_FWSup.id == COMP_ID_PRI ) {												/* 20*/
+int i = sizeof( CFG_FW_IDENTITY_STRCT) + sizeof(CFG_SUP_RANGE_STRCT );
+			while ( i-- ) ((hcf_8*)(&ifbp->IFB_PRIIdentity))[i] = ((hcf_8*)(&ifbp->IFB_FWIdentity))[i];
+			ifbp->IFB_PRIIdentity.typ = CFG_PRI_IDENTITY;
+			ifbp->IFB_PRISup.typ = CFG_PRI_SUP_RANGE;
+			xxxx[xxxx_PRI_IDENTITY_OFFSET] = &ifbp->IFB_PRIIdentity.len;
+			xxxx[xxxx_PRI_IDENTITY_OFFSET+1] = &ifbp->IFB_PRISup.len;
+		}
+		if ( !mmd_check_comp( (void*)&cfg_drv_act_ranges_hsi, &ifbp->IFB_HSISup)				 /* 22*/
+#if ( (HCF_TYPE) & HCF_TYPE_PRELOADED ) == 0
+//;? the PRI compatibility check is only relevant for DHF
+			 || !mmd_check_comp( (void*)&cfg_drv_act_ranges_pri, &ifbp->IFB_PRISup)
+#endif // HCF_TYPE_PRELOADED
+		   ) {
+			ifbp->IFB_CardStat = CARD_STAT_INCOMP_PRI;
+			rc = HCF_ERR_INCOMP_PRI;
+		}
+		if ( ( ifbp->IFB_FWSup.id == COMP_ID_STA &&	!mmd_check_comp( (void*)&cfg_drv_act_ranges_sta, &ifbp->IFB_FWSup) ) ||
+			 ( ifbp->IFB_FWSup.id == COMP_ID_APF && !mmd_check_comp( (void*)&cfg_drv_act_ranges_apf, &ifbp->IFB_FWSup) )
+		   ) {																					/* 24 */
+			ifbp->IFB_CardStat |= CARD_STAT_INCOMP_FW;
+			rc = HCF_ERR_INCOMP_FW;
+		}
+	}
+#endif // MSF_COMPONENT_ID
+#if (HCF_DL_ONLY) == 0																			/* 28 */
+	if ( rc == HCF_SUCCESS && ifbp->IFB_FWIdentity.comp_id >= COMP_ID_FW_STA ) {
+PROT_CNT_INI
+		/**************************************************************************************
+		* rlav: the DMA engine needs the host to cause a 'hanging alloc event' for it to consume.
+		* not sure if this is the right spot in the HCF, thinking about hcf_enable...
+		**************************************************************************************/
+		rc = cmd_exe( ifbp, HCMD_ALLOC, 0 );
+// 180 degree error in logic ;? #if ALLOC_15
+//		ifbp->IFB_RscInd = 1;	//let's hope that by the time hcf_send_msg isa called, there will be a FID
+//#else
+		if ( rc == HCF_SUCCESS ) {
+			HCF_WAIT_WHILE( (IPW( HREG_EV_STAT ) & HREG_EV_ALLOC) == 0 );
+			IF_PROT_TIME( HCFASSERT(prot_cnt, IPW( HREG_EV_STAT ) ) /*NOP*/;)
+#if HCF_DMA
+			if ( ! ( ifbp->IFB_CntlOpt & USE_DMA ) )
+#endif // HCF_DMA
+			{
+				ifbp->IFB_RscInd = get_fid( ifbp );
+				HCFASSERT( ifbp->IFB_RscInd, 0 )
+				cmd_exe( ifbp, HCMD_ALLOC, 0 );
+				IF_PROT_TIME( if ( prot_cnt == 0 ) rc = HCF_ERR_TIME_OUT; )
+			}
+		}
+//#endif // ALLOC_15
+	}
+#endif // HCF_DL_ONLY
+	HCFASSERT( rc == HCF_SUCCESS, rc )
+	HCFLOGEXIT( HCF_TRACE_INIT )
+	return rc;
+} // init
+
+#if (HCF_DL_ONLY) == 0
+/************************************************************************************************************
+*
+*.SUBMODULE		void isr_info( IFBP ifbp )
+*.PURPOSE		handles link events.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*
+*.RETURNS		N.A.
+*
+*.DESCRIPTION
+*
+*
+*.DIAGRAM
+*1:	First the FID number corresponding with the InfoEvent is determined.
+*	Note the complication of the zero-FID protection sub-scheme in DAWA.
+*	Next the L-field and the T-field are fetched into scratch buffer info.
+*2:	In case of tallies, the 16 bits Hermes values are accumulated in the IFB into 32 bits values. Info[0]
+*	is (expected to be) HCF_NIC_TAL_CNT + 1. The contraption "while ( info[0]-- >1 )" rather than
+*	"while ( --info[0] )" is used because it is dangerous to determine the length of the Value field by
+*	decrementing info[0]. As a result of a bug in some version of the F/W, info[0] may be 0, resulting
+*	in a very long loop in the pre-decrement logic.
+*4:	In case of a link status frame, the information is copied to the IFB field IFB_linkStat
+*6:	All other than Tallies (including "unknown" ones) are checked against the selection set by the MSF
+*	via CFG_RID_LOG. If a match is found or the selection set has the wild-card type (i.e non-NULL buffer
+*	pointer at the terminating zero-type), the frame is copied to the (type-specific) log buffer.
+*	Note that to accumulate tallies into IFB AND to log them or to log a frame when a specific match occures
+*	AND based on the wild-card selection, you have to call setup_bap again after the 1st copy.
+*
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+HCF_STATIC void
+isr_info( IFBP ifbp )
+{
+hcf_16	info[2], fid;
+#if (HCF_EXT) & HCF_EXT_INFO_LOG
+RID_LOGP	ridp = ifbp->IFB_RIDLogp;	//NULL or pointer to array of RID_LOG structures (terminated by zero typ)
+#endif // HCF_EXT_INFO_LOG
+
+	HCFTRACE( ifbp, HCF_TRACE_ISR_INFO );																/* 1 */
+	fid = IPW( HREG_INFO_FID );
+	DAWA_ZERO_FID( HREG_INFO_FID )
+	if ( fid ) {
+		(void)setup_bap( ifbp, fid, 0, IO_IN );
+		get_frag( ifbp, (wci_bufp)info, 4 BE_PAR(2) );
+		HCFASSERT( info[0] <= HCF_MAX_LTV + 1, MERGE_2( info[1], info[0] ) )  //;? a smaller value makes more sense
+#if (HCF_TALLIES) & HCF_TALLIES_NIC		//Hermes tally support
+		if ( info[1] == CFG_TALLIES ) {
+hcf_32	*p;
+/*2*/		if ( info[0] > HCF_NIC_TAL_CNT ) {
+				info[0] = HCF_NIC_TAL_CNT + 1;
+			}
+			p = (hcf_32*)&ifbp->IFB_NIC_Tallies;
+			while ( info[0]-- >1 ) *p++ += IPW( HREG_DATA_1 );	//request may return zero length
+		}
+		else
+#endif // HCF_TALLIES_NIC
+		{
+/*4*/		if ( info[1] == CFG_LINK_STAT ) {
+				ifbp->IFB_LinkStat = IPW( HREG_DATA_1 );
+			}
+#if (HCF_EXT) & HCF_EXT_INFO_LOG
+/*6*/		while ( 1 ) {
+				if ( ridp->typ == 0 || ridp->typ == info[1] ) {
+					if ( ridp->bufp ) {
+						HCFASSERT( ridp->len >= 2, ridp->typ )
+						ridp->bufp[0] = min((hcf_16)(ridp->len - 1), info[0] ); 	//save L
+						ridp->bufp[1] = info[1];						//save T
+						get_frag( ifbp, (wci_bufp)&ridp->bufp[2], (ridp->bufp[0] - 1)*2 BE_PAR(0) );
+					}
+					break;
+				}
+				ridp++;
+			}
+#endif // HCF_EXT_INFO_LOG
+		}
+		HCFTRACE( ifbp, HCF_TRACE_ISR_INFO | HCF_TRACE_EXIT );
+	}
+	return;
+} // isr_info
+#endif // HCF_DL_ONLY
+
+//
+//
+// #endif // HCF_TALLIES_NIC
+// /*4*/	if ( info[1] == CFG_LINK_STAT ) {
+// 			ifbp->IFB_DSLinkStat = IPW( HREG_DATA_1 ) | CFG_LINK_STAT_CHANGE;	//corrupts BAP !! ;?
+// 			ifbp->IFB_LinkStat = ifbp->IFB_DSLinkStat & CFG_LINK_STAT_FW; //;? to be obsoleted
+// 			printk( "<4>linkstatus: %04x\n", ifbp->IFB_DSLinkStat );		//;?remove me 1 day
+// #if (HCF_SLEEP) & HCF_DDS
+// 			if ( ( ifbp->IFB_DSLinkStat & CFG_LINK_STAT_CONNECTED ) == 0 ) { 	//even values are disconnected etc.
+// 				ifbp->IFB_TickCnt = 0;				//start 2 second period (with 1 tick uncertanty)
+// 				printk( "<5>isr_info: AwaitConnection phase started, IFB_TickCnt = 0\n" );		//;?remove me 1 day
+// 			}
+// #endif // HCF_DDS
+// 		}
+// #if (HCF_EXT) & HCF_EXT_INFO_LOG
+// /*6*/	while ( 1 ) {
+// 			if ( ridp->typ == 0 || ridp->typ == info[1] ) {
+// 				if ( ridp->bufp ) {
+// 					HCFASSERT( ridp->len >= 2, ridp->typ )
+// 					(void)setup_bap( ifbp, fid, 2, IO_IN );			//restore BAP for tallies, linkstat and specific type followed by wild card
+// 					ridp->bufp[0] = min( ridp->len - 1, info[0] ); 	//save L
+// 					get_frag( ifbp, (wci_bufp)&ridp->bufp[1], ridp->bufp[0]*2 BE_PAR(0) );
+// 				}
+// 				break; //;?this break is no longer needed due to setup_bap but lets concentrate on DDS first
+// 			}
+// 			ridp++;
+// 		}
+// #endif // HCF_EXT_INFO_LOG
+// 	}
+// 	HCFTRACE( ifbp, HCF_TRACE_ISR_INFO | HCF_TRACE_EXIT );
+//
+//
+//
+//
+//	return;
+//} // isr_info
+//#endif // HCF_DL_ONLY
+
+
+/************************************************************************************************************
+*
+*.SUBMODULE		void mdd_assert( IFBP ifbp, unsigned int line_number, hcf_32 q )
+*.PURPOSE		filters assert on level and interfaces to the MSF supplied msf_assert routine.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*	line_number	line number of the line which caused the assert
+*	q			qualifier, additional information which may give a clue about the problem
+*
+*.RETURNS		N.A.
+*
+*.DESCRIPTION
+*
+*
+*.DIAGRAM
+*
+*.NOTICE
+* mdd_assert has been through a turmoil, renaming hcf_assert to assert and hcf_assert again and supporting off
+* and on being called from the MSF level and other ( immature ) ModularDriverDevelopment modules like DHF and
+* MMD.
+ * !!!! The assert routine is not an hcf_..... routine in the sense that it may be called by the MSF,
+ *		however it is called from mmd.c and dhf.c, so it must be external.
+ *		To prevent namespace pollution it needs a prefix, to prevent that MSF programmers think that
+ *		they are allowed to call the assert logic, the prefix HCF can't be used, so MDD is selected!!!!
+ *
+* When called from the DHF module the line number is incremented by DHF_FILE_NAME_OFFSET and when called from
+* the MMD module by MMD_FILE_NAME_OFFSET.
+*
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+#if HCF_ASSERT
+void
+mdd_assert( IFBP ifbp, unsigned int line_number, hcf_32 q )
+{
+hcf_16	run_time_flag = ifbp->IFB_AssertLvl;
+
+	if ( run_time_flag /* > ;?????? */ ) { //prevent recursive behavior, later to be extended to level filtering
+		ifbp->IFB_AssertQualifier = q;
+		ifbp->IFB_AssertLine = (hcf_16)line_number;
+#if (HCF_ASSERT) & ( HCF_ASSERT_LNK_MSF_RTN | HCF_ASSERT_RT_MSF_RTN )
+		if ( ifbp->IFB_AssertRtn ) {
+			ifbp->IFB_AssertRtn( line_number, ifbp->IFB_AssertTrace, q );
+		}
+#endif // HCF_ASSERT_LNK_MSF_RTN / HCF_ASSERT_RT_MSF_RTN
+#if (HCF_ASSERT) & HCF_ASSERT_SW_SUP
+		OPW( HREG_SW_2, line_number );
+		OPW( HREG_SW_2, ifbp->IFB_AssertTrace );
+		OPW( HREG_SW_2, (hcf_16)q );
+		OPW( HREG_SW_2, (hcf_16)(q >> 16 ) );
+#endif // HCF_ASSERT_SW_SUP
+
+#if (HCF_EXT) & HCF_EXT_MB && (HCF_ASSERT) & HCF_ASSERT_MB
+		ifbp->IFB_AssertLvl = 0;									// prevent recursive behavior
+		hcf_put_info( ifbp, (LTVP)&ifbp->IFB_AssertStrct );
+		ifbp->IFB_AssertLvl = run_time_flag;						// restore appropriate filter level
+#endif // HCF_EXT_MB / HCF_ASSERT_MB
+	}
+} // mdd_assert
+#endif // HCF_ASSERT
+
+
+/************************************************************************************************************
+*
+*.SUBMODULE		void put_frag( IFBP ifbp, wci_bufp bufp, int len BE_PAR( int word_len ) )
+*.PURPOSE		writes with 16/32 bit I/O via BAP1 port from Host memory to NIC RAM.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*	bufp		(byte) address of buffer
+*	len			length in bytes of buffer specified by bufp
+*	word_len	Big Endian only: number of leading bytes to swap in pairs
+*
+*.RETURNS		N.A.
+*
+*.DESCRIPTION
+* process the single byte (if applicable) not yet written by the previous put_frag and copy len
+* (or len-1) bytes from bufp to NIC.
+*
+*
+*.DIAGRAM
+*
+*.NOTICE
+*	It turns out DOS ODI uses zero length fragments. The HCF code can cope with it, but as a consequence, no
+*	Assert on len is possible
+*
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+HCF_STATIC void
+put_frag( IFBP ifbp, wci_bufp bufp, int len BE_PAR( int word_len ) )
+{
+hcf_io		io_port = ifbp->IFB_IOBase + HREG_DATA_1;	//BAP data register
+int			i;											//prevent side effects from macro
+hcf_16		j;
+	HCFASSERT( ((hcf_32)bufp & (HCF_ALIGN-1) ) == 0, (hcf_32)bufp )
+#if HCF_BIG_ENDIAN
+	HCFASSERT( word_len == 0 || word_len == 2 || word_len == 4, word_len )
+	HCFASSERT( word_len == 0 || ((hcf_32)bufp & 1 ) == 0, (hcf_32)bufp )
+	HCFASSERT( word_len <= len, MERGE_2( word_len, len ) )
+
+	if ( word_len ) {									//if there is anything to convert
+ 														//.  convert and write the 1st hcf_16
+		j = bufp[1] | bufp[0]<<8;
+		OUT_PORT_WORD( io_port, j );
+														//.  update pointer and counter accordingly
+		len -= 2;
+		bufp += 2;
+		if ( word_len > 1 ) {							//.  if there is to convert more than 1 word ( i.e 2 )
+ 														//.  .  convert and write the 2nd hcf_16
+			j = bufp[1] | bufp[0]<<8;	/*bufp is already incremented by 2*/
+			OUT_PORT_WORD( io_port, j );
+														//.  .  update pointer and counter accordingly
+			len -= 2;
+			bufp += 2;
+		}
+	}
+#endif // HCF_BIG_ENDIAN
+	i = len;
+	if ( i && ifbp->IFB_CarryOut ) {					//skip zero-length
+		j = ((*bufp)<<8) + ( ifbp->IFB_CarryOut & 0xFF );
+		OUT_PORT_WORD( io_port, j );
+		bufp++; i--;
+		ifbp->IFB_CarryOut = 0;
+	}
+#if (HCF_IO) & HCF_IO_32BITS
+	//skip zero-length I/O, single byte I/O and I/O not worthwhile (i.e. less than 6 bytes)for DW logic
+													//if buffer length >= 6 and 32 bits I/O support
+	if ( !(ifbp->IFB_CntlOpt & USE_16BIT) && i >= 6 ) {
+hcf_32 FAR	*p4; //prevent side effects from macro
+		if ( ( (hcf_32)bufp & 0x1 ) == 0 ) {			//.  if buffer at least word aligned
+			if ( (hcf_32)bufp & 0x2 ) {				//.  .  if buffer not double word aligned
+                                                 	//.  .  .  write a single word to get double word aligned
+				j = *(wci_recordp)bufp;		//just to help ease writing macros with embedded assembly
+				OUT_PORT_WORD( io_port, j );
+													//.  .  .  adjust buffer length and pointer accordingly
+				bufp += 2; i -= 2;
+			}
+													//.  .  write as many double word as possible
+			p4 = (hcf_32 FAR *)bufp;
+			j = (hcf_16)i/4;
+			OUT_PORT_STRING_32( io_port, p4, j );
+													//.  .  adjust buffer length and pointer accordingly
+			bufp += i & ~0x0003;
+			i &= 0x0003;
+		}
+	}
+#endif // HCF_IO_32BITS
+													//if no 32-bit support OR byte aligned OR 1 word left
+	if ( i ) {
+													//.  if odd number of bytes left
+		if ( i & 0x0001 ) {
+													//.  .  save left over byte (before bufp is corrupted) in carry, set carry flag
+			ifbp->IFB_CarryOut = (hcf_16)bufp[i-1] | 0x0100;	//note that i and bufp are always simultaneously modified, &bufp[i-1] is invariant
+		}
+													//.  write as many word as possible in "alignment safe" way
+		j = (hcf_16)i/2;
+		OUT_PORT_STRING_8_16( io_port, bufp, j );
+	}
+} // put_frag
+
+
+/************************************************************************************************************
+*
+*.SUBMODULE		void put_frag_finalize( IFBP ifbp )
+*.PURPOSE		cleanup after put_frag for trailing odd byte and MIC transfer to NIC.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*
+*.RETURNS		N.A.
+*
+*.DESCRIPTION
+* finalize the MIC calculation with the padding pattern, output the last byte (if applicable)
+* of the message and the MIC to the TxFS
+*
+*
+*.DIAGRAM
+*2:	1 byte of the last put_frag may be still in IFB_CarryOut ( the put_frag carry holder ), so ........
+*	1 - 3 bytes of the last put_frag may be still in IFB_tx_32 ( the MIC engine carry holder ), so ........
+*	The call to the MIC calculation routine feeds these remaining bytes (if any) of put_frag and the
+*	just as many bytes of the padding as needed to the MIC calculation engine. Note that the "unneeded" pad
+*	bytes simply end up in the MIC engine carry holder and are never used.
+*8:	write the remainder of the MIC and possible some garbage to NIC RAM
+*	Note: i is always 4 (a loop-invariant of the while in point 2)
+*
+*.NOTICE
+*
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+HCF_STATIC void
+put_frag_finalize( IFBP ifbp )
+{
+#if (HCF_TYPE) & HCF_TYPE_WPA
+	if ( ifbp->IFB_MICTxCarry != 0xFFFF) {		//if MIC calculation active
+		CALC_TX_MIC( mic_pad, 8);				//.  feed (up to 8 bytes of) virtual padding to MIC engine
+												//.  write (possibly) trailing byte + (most of) MIC
+		put_frag( ifbp, (wci_bufp)ifbp->IFB_MICTx, 8 BE_PAR(0) );
+	}
+#endif // HCF_TYPE_WPA
+	put_frag( ifbp, null_addr, 1 BE_PAR(0) );	//write (possibly) trailing data or MIC byte
+} // put_frag_finalize
+
+
+/************************************************************************************************************
+*
+*.SUBMODULE		int put_info( IFBP ifbp, LTVP ltvp )
+*.PURPOSE		support routine to handle the "basic" task of hcf_put_info to pass RIDs to the NIC.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*	ltvp		address in NIC RAM where LVT-records are located
+*
+*.RETURNS
+*	HCF_SUCCESS
+*	>>put_frag
+*	>>cmd_wait
+*
+*.DESCRIPTION
+*
+*
+*.DIAGRAM
+*20: do not write RIDs to NICs which have incompatible Firmware
+*24: If the RID does not exist, the L-field is set to zero.
+*	Note that some RIDs can not be read, e.g. the pseudo RIDs for direct Hermes commands and CFG_DEFAULT_KEYS
+*28: If the RID is written successful, pass it to the NIC by means of an Access Write command
+*
+*.NOTICE
+*	The mechanism to HCF_ASSERT on invalid typ-codes in the LTV record is based on the following strategy:
+*	  -	some codes (e.g. CFG_REG_MB) are explicitly handled by the HCF which implies that these codes
+*		are valid. These codes are already consumed by hcf_put_info.
+*	  - all other codes are passed to the Hermes. Before the put action is executed, hcf_get_info is called
+*		with an LTV record with a value of 1 in	the L-field and the intended put action type in the Typ-code
+*		field. If the put action type is valid, it is also valid as a get action type code - except
+*		for CFG_DEFAULT_KEYS and CFG_ADD_TKIP_DEFAULT_KEY - so the HCF_ASSERT logic of hcf_get_info should
+*		not catch.
+*
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+HCF_STATIC int
+put_info( IFBP ifbp, LTVP ltvp	)
+{
+
+int rc = HCF_SUCCESS;
+
+	HCFASSERT( ifbp->IFB_CardStat == 0, MERGE_2( ltvp->typ, ifbp->IFB_CardStat ) )
+	HCFASSERT( CFG_RID_CFG_MIN <= ltvp->typ && ltvp->typ <= CFG_RID_CFG_MAX, ltvp->typ )
+
+	if ( ifbp->IFB_CardStat == 0 &&																/* 20*/
+		 ( ( CFG_RID_CFG_MIN <= ltvp->typ    && ltvp->typ <= CFG_RID_CFG_MAX ) ||
+		   ( CFG_RID_ENG_MIN <= ltvp->typ /* && ltvp->typ <= 0xFFFF */       )     ) ) {
+#if HCF_ASSERT //FCC8, FCB0, FCB4, FCB6, FCB7, FCB8, FCC0, FCC4, FCBC, FCBD, FCBE, FCBF
+ {
+ hcf_16		t = ltvp->typ;
+ LTV_STRCT 	x = { 2, t, {0} };															/*24*/
+	hcf_get_info( ifbp, (LTVP)&x );
+	if ( x.len == 0 &&
+		 ( t != CFG_DEFAULT_KEYS && t != CFG_ADD_TKIP_DEFAULT_KEY && t != CFG_REMOVE_TKIP_DEFAULT_KEY &&
+		   t != CFG_ADD_TKIP_MAPPED_KEY && t != CFG_REMOVE_TKIP_MAPPED_KEY &&
+		   t != CFG_HANDOVER_ADDR && t != CFG_DISASSOCIATE_ADDR &&
+		   t != CFG_FCBC && t != CFG_FCBD && t != CFG_FCBE && t != CFG_FCBF &&
+		   t != CFG_DEAUTHENTICATE_ADDR
+		 )
+		) {
+		HCFASSERT( DO_ASSERT, ltvp->typ )
+		}
+ }
+#endif // HCF_ASSERT
+
+		rc = setup_bap( ifbp, ltvp->typ, 0, IO_OUT );
+		put_frag( ifbp, (wci_bufp)ltvp, 2*ltvp->len + 2 BE_PAR(2) );
+/*28*/	if ( rc == HCF_SUCCESS ) {
+			rc = cmd_exe( ifbp, HCMD_ACCESS + HCMD_ACCESS_WRITE, ltvp->typ );
+		}
+	}
+	return rc;
+} // put_info
+
+
+#if (HCF_DL_ONLY) == 0
+/************************************************************************************************************
+*
+*.SUBMODULE		int put_info_mb( IFBP ifbp, CFG_MB_INFO_STRCT FAR * ltvp )
+*.PURPOSE	 	accumulates a ( series of) buffers into a single Info block into the MailBox.
+*
+*.ARGUMENTS
+*	ifbp		address of the Interface Block
+*	ltvp		address of structure specifying the "type" and the fragments of the information to be synthesized
+*				as an LTV into the MailBox
+*
+*.RETURNS
+*
+*.DESCRIPTION
+* If the data does not fit (including no MailBox is available), the IFB_MBTally is incremented and an
+* error status is returned.
+* HCF_ASSERT does not catch.
+* Calling put_info_mb when their is no MailBox available, is considered a design error in the MSF.
+*
+* Note that there is always at least 1 word of unused space in the mail box.
+* As a consequence:
+* - no problem in pointer arithmetic (MB_RP == MB_WP means unambiguously mail box is completely empty
+* - There is always free space to write an L field with a value of zero after each MB_Info block.  This
+*   allows for an easy scan mechanism in the "get MB_Info block" logic.
+*
+*
+*.DIAGRAM
+*1:	Calculate L field of the MBIB, i.e. 1 for the T-field + the cumulative length of the fragments.
+*2:	The free space in the MailBox is calculated (2a: free part from Write Ptr to Read Ptr, 2b: free part
+*	turns out to wrap around) . If this space suffices to store the number of words reflected by len (T-field
+*	+ Value-field) plus the additional MailBox Info L-field + a trailing 0 to act as the L-field of a trailing
+*	dummy or empty LTV record, then a MailBox Info block is build in the MailBox consisting of
+*	  - the value len in the first word
+*	  - type in the second word
+*	  - a copy of the contents of the fragments in the second and higher word
+*
+*4:	Since put_info_mb() can more or less directly be called from the MSF level, the I/F must be robust
+*	against out-of-range variables. As failsafe coding, the MB update is skipped by changing tlen to 0 if
+*	len == 0; This will indirectly cause an assert as result of the violation of the next if clause.
+*6:	Check whether the free space in MailBox suffices (this covers the complete absence of the MailBox).
+*	Note that len is unsigned, so even MSF I/F violation works out O.K.
+*	The '2' in the expression "len+2" is used because 1 word is needed for L itself and 1 word is needed
+*	for the zero-sentinel
+*8:	update MailBox Info length report to MSF with "oldest" MB Info Block size. Be carefull here, if you get
+*	here before the MailBox is registered, you can't read from the buffer addressed by IFB_MBp (it is the
+*	Null buffer) so don't move this code till the end of this routine but keep it where there is garuanteed
+*	a buffer.
+*
+*.NOTICE
+*	boundary testing depends on the fact that IFB_MBSize is guaranteed to be zero if no MailBox is present,
+*	and to a lesser degree, that IFB_MBWp = IFB_MBRp = 0
+*
+*.ENDDOC				END DOCUMENTATION
+*
+************************************************************************************************************/
+#if (HCF_EXT) & HCF_EXT_MB
+
+HCF_STATIC int
+put_info_mb( IFBP ifbp, CFG_MB_INFO_STRCT FAR * ltvp )
+{
+
+int			rc = HCF_SUCCESS;
+hcf_16		i;						//work counter
+hcf_16		*dp;					//destination pointer (in MailBox)
+wci_recordp	sp;						//source pointer
+hcf_16		len;					//total length to copy to MailBox
+hcf_16		tlen;					//free length/working length/offset in WMP frame
+
+	if ( ifbp->IFB_MBp == NULL ) return rc;  //;?not sufficient
+	HCFASSERT( ifbp->IFB_MBp != NULL, 0 )					//!!!be careful, don't get into an endless recursion
+	HCFASSERT( ifbp->IFB_MBSize, 0 )
+
+	len = 1;																							/* 1 */
+	for ( i = 0; i < ltvp->frag_cnt; i++ ) {
+		len += ltvp->frag_buf[i].frag_len;
+	}
+	if ( ifbp->IFB_MBRp > ifbp->IFB_MBWp ) {
+		tlen = ifbp->IFB_MBRp - ifbp->IFB_MBWp;															/* 2a*/
+	} else {
+		if ( ifbp->IFB_MBRp == ifbp->IFB_MBWp ) {
+			ifbp->IFB_MBRp = ifbp->IFB_MBWp = 0;	// optimize Wrapping
+		}
+		tlen = ifbp->IFB_MBSize - ifbp->IFB_MBWp;														/* 2b*/
+		if ( ( tlen <= len + 2 ) && ( len + 2 < ifbp->IFB_MBRp ) ) {	//if trailing space is too small but
+																	//	 leading space is sufficiently large
+			ifbp->IFB_MBp[ifbp->IFB_MBWp] = 0xFFFF;					//flag dummy LTV to fill the trailing space
+			ifbp->IFB_MBWp = 0;										//reset WritePointer to begin of MailBox
+			tlen = ifbp->IFB_MBRp;									//get new available space size
+		}
+	}
+	dp = &ifbp->IFB_MBp[ifbp->IFB_MBWp];
+	if ( len == 0 ) {
+		tlen = 0; //;? what is this good for
+	}
+	if ( len + 2 >= tlen ){																				/* 6 */
+		//Do Not ASSERT, this is a normal condition
+		IF_TALLY( ifbp->IFB_HCF_Tallies.NoBufMB++; ) /*NOP to cover against analomies with empty compound*/;
+		rc = HCF_ERR_LEN;
+	} else {
+		*dp++ = len;									//write Len (= size of T+V in words to MB_Info block
+		*dp++ = ltvp->base_typ;							//write Type to MB_Info block
+		ifbp->IFB_MBWp += len + 1;						//update WritePointer of MailBox
+		for ( i = 0; i < ltvp->frag_cnt; i++ ) {				// process each of the fragments
+			sp = ltvp->frag_buf[i].frag_addr;
+			len = ltvp->frag_buf[i].frag_len;
+			while ( len-- ) *dp++ = *sp++;
+		}
+		ifbp->IFB_MBp[ifbp->IFB_MBWp] = 0;				//to assure get_info for CFG_MB_INFO stops
+		ifbp->IFB_MBInfoLen = ifbp->IFB_MBp[ifbp->IFB_MBRp];											/* 8 */
+	}
+	return rc;
+} // put_info_mb
+
+#endif // HCF_EXT_MB
+#endif // HCF_DL_ONLY
+
+
+/************************************************************************************************************
+*
+*.SUBMODULE		int setup_bap( IFBP ifbp, hcf_16 fid, int offset, int type )
+*.PURPOSE		set up data access to NIC RAM via BAP_1.
+*
+*.ARGUMENTS
+*	ifbp			address of I/F Block
+*	fid				FID/RID
+*	offset			!!even!! offset in FID/RID
+*	type			IO_IN, IO_OUT
+*
+*.RETURNS
+*	HCF_SUCCESS					O.K
+*	HCF_ERR_NO_NIC				card is removed
+*	HCF_ERR_DEFUNCT_TIME_OUT	Fatal malfunction detected
+*	HCF_ERR_DEFUNCT_.....		if and only if IFB_DefunctStat <> 0
+*
+*.DESCRIPTION
+*
+* A non-zero return status indicates:
+* - the NIC is considered nonoperational, e.g. due to a time-out of some Hermes activity in the past
+* - BAP_1 could not properly be initialized
+* - the card is removed before completion of the data transfer
+* In all other cases, a zero is returned.
+* BAP Initialization failure indicates an H/W error which is very likely to signal complete H/W failure.
+* Once a BAP Initialization failure has occurred all subsequent interactions with the Hermes will return a
+* "defunct" status till the Hermes is re-initialized by means of an hcf_connect.
+*
+* A BAP is a set of registers (Offset, Select and Data) offering read/write access to a particular FID or
+* RID. This access is based on a auto-increment feature.
+* There are two BAPs but these days the HCF uses only BAP_1 and leaves BAP_0 to the PCI Busmastering H/W.
+*
+* The BAP-mechanism is based on the Busy bit in the Offset register (see the Hermes definition). The waiting
+* for Busy must occur between writing the Offset register and accessing the Data register. The
+* implementation to wait for the Busy bit drop after each write to the Offset register, implies that the
+* requirement that the Busy bit is low  before the Select register is written, is automatically met.
+* BAP-setup may be time consuming (e.g. 380 usec for large offsets occurs frequently). The wait for Busy bit
+* drop is protected by a loop counter, which is initialized with IFB_TickIni, which is calibrated in init.
+*
+* The NIC I/F is optimized for word transfer and can only handle word transfer at a word boundary in NIC
+* RAM. The intended solution for transfer of a single byte has multiple H/W flaws. There have been different
+* S/W Workaround strategies. RID access is hcf_16 based by "nature", so no byte access problems.  For Tx/Rx
+* FID access,  the byte logic became obsolete by absorbing it in the double word oriented nature of the MIC
+* feature.
+*
+*
+*.DIAGRAM
+*
+*2:	the test on rc checks whether the HCF went into "defunct" mode ( e.g. BAP initialization or a call to
+*	cmd_wait did ever fail).
+*4:	the select register and offset register are set
+*	the offset register is monitored till a successful condition (no busy bit) is detected or till the
+*	(calibrated) protection counter expires
+*	If the counter expires, this is reflected in IFB_DefunctStat, so all subsequent calls to setup_bap fail
+*	immediately ( see 2)
+*6:	initialization of the carry as used by pet/get_frag
+*8:	HREG_OFFSET_ERR is ignored as error because:
+*	 a: the Hermes is robust against it
+*	 b: it is not known what causes it (probably a bug), hence no strategy can be specified which level is
+*		to handle this error in which way. In the past, it could be induced by the MSF level, e.g. by calling
+*		hcf_rcv_msg while there was no Rx-FID available. Since this is an MSF-error which is caught by ASSERT,
+*		there is no run-time action required by the HCF.
+*	Lumping the Offset error in with the Busy bit error, as has been done in the past turns out to be a
+*	disaster or a life saver, just depending on what the cause of the error is. Since no prediction can be
+*	done about the future, it is "felt" to be the best strategy to ignore this error. One day the code was
+*	accompanied by the following comment:
+*	//	ignore HREG_OFFSET_ERR, someone, supposedly the MSF programmer ;) made a bug. Since we don't know
+*	//	what is going on, we might as well go on - under management pressure - by ignoring it
+*
+*.ENDDOC                          END DOCUMENTATION
+*
+************************************************************************************************************/
+HCF_STATIC int
+setup_bap( IFBP ifbp, hcf_16 fid, int offset, int type )
+{
+PROT_CNT_INI
+int	rc;
+
+	HCFTRACE( ifbp, HCF_TRACE_STRIO );
+	if ( ( rc = ifbp->IFB_DefunctStat ) == HCF_SUCCESS ) {										/*2*/
+		OPW( HREG_SELECT_1, fid );																/*4*/
+		OPW( HREG_OFFSET_1, offset );
+		if ( type == IO_IN ) {
+			ifbp->IFB_CarryIn = 0;
+		}
+		else ifbp->IFB_CarryOut = 0;
+		HCF_WAIT_WHILE( IPW( HREG_OFFSET_1) & HCMD_BUSY );
+		HCFASSERT( !( IPW( HREG_OFFSET_1) & HREG_OFFSET_ERR ), MERGE_2( fid, offset ) )			/*8*/
+		if ( prot_cnt == 0 ) {
+			HCFASSERT( DO_ASSERT, MERGE_2( fid, offset ) )
+			rc = ifbp->IFB_DefunctStat = HCF_ERR_DEFUNCT_TIME_OUT;
+			ifbp->IFB_CardStat |= CARD_STAT_DEFUNCT;
+		}
+	}
+	HCFTRACE( ifbp, HCF_TRACE_STRIO | HCF_TRACE_EXIT );
+	return rc;
+} // setup_bap
+
diff --git a/drivers/staging/wlags49_h2/hcf.h b/drivers/staging/wlags49_h2/hcf.h
new file mode 100644
index 0000000..2cd5739
--- /dev/null
+++ b/drivers/staging/wlags49_h2/hcf.h
@@ -0,0 +1,405 @@
+
+//   vim:tw=110:ts=4:
+#ifndef HCF_H
+#define HCF_H 1
+
+/************************************************************************************************************
+*
+* FILE	 : hcf.h
+*
+* DATE   : $Date: 2004/08/05 11:47:10 $   $Revision: 1.7 $
+* Original: 2004/05/19 07:26:01    Revision: 1.56      Tag: hcf7_t20040602_01
+* Original: 2004/05/12 08:47:23    Revision: 1.53      Tag: hcf7_t7_20040513_01
+* Original: 2004/04/15 09:24:42    Revision: 1.46      Tag: hcf7_t7_20040415_01
+* Original: 2004/04/08 15:18:16    Revision: 1.45      Tag: t7_20040413_01
+* Original: 2004/04/01 15:32:55    Revision: 1.43      Tag: t7_20040401_01
+* Original: 2004/03/10 15:39:28    Revision: 1.39      Tag: t20040310_01
+* Original: 2004/03/04 11:03:38    Revision: 1.37      Tag: t20040304_01
+* Original: 2004/03/02 14:51:21    Revision: 1.35      Tag: t20040302_03
+* Original: 2004/02/24 13:00:28    Revision: 1.28      Tag: t20040224_01
+* Original: 2004/02/09 14:50:14    Revision: 1.26      Tag: t20040219_01
+*
+* AUTHOR : Nico Valster
+*
+* SPECIFICATION: ..........
+*
+* DESC   : Definitions and Prototypes for MSF as well as HCF sources
+*
+*		   Customizable via HCFCFG.H
+*
+*
+**************************************************************************************************************
+
+**************************************************************************************************************
+*
+*
+* SOFTWARE LICENSE
+*
+* This software is provided subject to the following terms and conditions,
+* which you should read carefully before using the software.  Using this
+* software indicates your acceptance of these terms and conditions.  If you do
+* not agree with these terms and conditions, do not use the software.
+*
+* COPYRIGHT © 1994 - 1995	by AT&T.				All Rights Reserved
+* COPYRIGHT © 1996 - 2000 by Lucent Technologies.	All Rights Reserved
+* COPYRIGHT © 2001 - 2004	by Agere Systems Inc.	All Rights Reserved
+* All rights reserved.
+*
+* Redistribution and use in source or binary forms, with or without
+* modifications, are permitted provided that the following conditions are met:
+*
+* . Redistributions of source code must retain the above copyright notice, this
+*    list of conditions and the following Disclaimer as comments in the code as
+*    well as in the documentation and/or other materials provided with the
+*    distribution.
+*
+* . Redistributions in binary form must reproduce the above copyright notice,
+*    this list of conditions and the following Disclaimer in the documentation
+*    and/or other materials provided with the distribution.
+*
+* . Neither the name of Agere Systems Inc. nor the names of the contributors
+*    may be used to endorse or promote products derived from this software
+*    without specific prior written permission.
+*
+* Disclaimer
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+* INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+* USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+* RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+* DAMAGE.
+*
+*
+*************************************************************************************************************/
+
+
+#include "hcfcfg.h"	// System Constants to be defined by the MSF-programmer to tailor the HCF
+#include "mdd.h"	// Include file common for HCF, MSF
+
+
+/************************************************************************************************/
+/**************************************  MACROS  ************************************************/
+/************************************************************************************************/
+
+#define LOF(x) 			(sizeof(x)/sizeof(hcf_16)-1)
+
+/*	Endianess
+ *	Little Endian (a.k.a. Intel), least significant byte first
+ *	Big Endian (a.k.a. Motorola), most significant byte first
+ *
+ * The following macros are supplied
+ *  o CNV_LITTLE_TO_SHORT(w)			interprets the 16-bits input value as Little Endian, returns an hcf_16
+ * 	o CNV_BIG_TO_SHORT(w)				interprets the 16-bits input value as Big Endian, returns an hcf_16
+ *
+ */
+
+/* To increase portability, use unsigned char and unsigned char * when accessing parts of larger
+ * types to convert their Endianess
+ */
+
+#define CNV_END_SHORT(w)  (hcf_16)( ((hcf_16)(w) & 0x00FF) << 8 | ((hcf_16)(w) & 0xFF00) >> 8 )
+#define CNV_END_LONG(dw)  (hcf_32)( (dw >> 24) | ((dw >> 8) & 0xff00) | ((dw << 8) & 0xff0000) | (dw << 24) )
+
+#if HCF_BIG_ENDIAN
+//******************************************** B I G   E N D I A N *******************************************
+#define CNV_LITTLE_TO_SHORT(w)	CNV_END_SHORT(w)	//    endianess conversion needed
+#define CNV_BIG_TO_SHORT(w)		(w)				// no endianess conversion needed
+#define CNV_LITTLE_TO_LONG(dw)	CNV_END_LONG(dw)
+#define CNV_LONG_TO_LITTLE(dw)	CNV_END_LONG(dw)
+#else
+//****************************************** L I T T L E   E N D I A N ****************************************
+#define CNV_LITTLE_TO_SHORT(w) 	(w)				// no endianess conversion needed
+#define CNV_BIG_TO_SHORT(w)		CNV_END_SHORT(w)	//    endianess conversion needed
+#define CNV_LITTLE_TO_LONG(dw)	(dw)
+#define CNV_LONG_TO_LITTLE(dw)	(dw)
+
+#if defined HCF_ALIGN && HCF_ALIGN > 1
+#define CNV_SHORTP_TO_LITTLE(pw)	((hcf_16)(*(hcf_8 *)pw)) 			| ((hcf_16)(*((hcf_8 *)pw+1)) << 8)
+#define CNV_LONGP_TO_LITTLE(pdw)	((hcf_32)(*(hcf_8 *)pdw)) 			| ((hcf_32)(*((hcf_8 *)pdw+1)) << 8) 	| \
+									((hcf_32)(*((hcf_8 *)pdw+2)) << 16) | ((hcf_32)(*((hcf_8 *)pdw+3)) << 24)
+#else
+#define CNV_LONGP_TO_LITTLE(pdw)	(*(hcf_32 *)pdw)
+#define CNV_SHORTP_TO_LITTLE(pw)	(*(hcf_16 *)pw)
+#endif
+
+#endif // HCF_BIG_ENDIAN
+
+// conversion macros which can be expressed in other macros
+#define CNV_SHORT_TO_LITTLE(w)	CNV_LITTLE_TO_SHORT(w)
+#define CNV_SHORT_TO_BIG(w)		CNV_BIG_TO_SHORT(w)
+
+/************************************************************************************************/
+/**************************************  END OF MACROS  *****************************************/
+/************************************************************************************************/
+
+/***********************************************************************************************************/
+/*****************                                                  ****************************************/
+/***********************************************************************************************************/
+
+// offsets Transmit/Receive Frame Structure
+#define HFS_STAT				0x0000
+#define HFS_SWSUP				0x0006					//SW Support
+#define HFS_Q_INFO				0x0006					//Signal/Silence level
+#define HFS_RATE				0x0008					//RxFlow/Rate
+#define 	HFS_STAT_ERR		RX_STAT_ERR				//link "natural" HCF name to "natural" MSF name
+#define HFS_TX_CNTL				0x0036
+														// H-I     H-II
+#define HFS_DAT_LEN				(HFS_ADDR_DEST - 2)		// 0x002C  0x0038
+#define HFS_ADDR_DEST			0x003A					// 0x002E  0x003A
+#define HFS_ADDR_SRC			(HFS_ADDR_DEST + 6)		// 0x0034  0x0040
+#define HFS_LEN					(HFS_ADDR_SRC  + 6)		// 0x003A  0x0046
+#define HFS_DAT					(HFS_LEN       + 2)		// 0x003C  0x0048
+#define HFS_TYPE				(HFS_DAT       + 6)		// 0x0042  0x004E
+
+
+//=============================  D E S C R I P T O R   S T R U C T U R E  ==============================
+//;?MDD.H stuff ;?
+
+#if HCF_BIG_ENDIAN
+#define DESC_STRCT_CNT		0
+#define DESC_STRCT_SIZE		1
+#else
+#define DESC_STRCT_CNT		1
+#define DESC_STRCT_SIZE		0
+#endif // HCF_BIG_ENDIAN
+
+#define	BUF_CNT				buf_dim[DESC_STRCT_CNT]
+#define	BUF_SIZE			buf_dim[DESC_STRCT_SIZE]
+
+typedef struct DESC_STRCT {
+	hcf_16					buf_dim[2];
+	hcf_32					buf_phys_addr;
+	hcf_32					next_desc_phys_addr;	// physical address of next descriptor
+	hcf_32					desc_phys_addr;			// physical address of this descriptor
+	struct DESC_STRCT 		*next_desc_addr;
+	hcf_8	FAR				*buf_addr;
+#if (HCF_EXT) & HCF_EXT_DESC_STRCT
+	void FAR			   *DESC_MSFSup;			// pointer for arbitrary use by the MSF
+#endif // HCF_DESC_STRCT_EXT
+} DESC_STRCT;
+
+#define HCF_DASA_SIZE			12							//size in bytes for DA/SA
+
+#define DESC_CNT_MASK 			0x0FFF
+
+#define GET_BUF_SIZE(descp)       ((descp)->BUF_SIZE)
+#define GET_BUF_CNT(descp)        ((descp)->BUF_CNT)
+#define SET_BUF_SIZE(descp, size) (descp)->BUF_SIZE = size;
+#define SET_BUF_CNT(descp, count) (descp)->BUF_CNT = count;
+
+//=========================================  T A L L I E S  ===================================================
+
+typedef struct  {  //Hermes Tallies (IFB substructure)
+  hcf_32	TxUnicastFrames;
+  hcf_32	TxMulticastFrames;
+  hcf_32	TxFragments;
+  hcf_32	TxUnicastOctets;
+  hcf_32	TxMulticastOctets;
+  hcf_32	TxDeferredTransmissions;
+  hcf_32	TxSingleRetryFrames;
+  hcf_32	TxMultipleRetryFrames;
+  hcf_32	TxRetryLimitExceeded;
+  hcf_32	TxDiscards;
+  hcf_32	RxUnicastFrames;
+  hcf_32	RxMulticastFrames;
+  hcf_32	RxFragments;
+  hcf_32	RxUnicastOctets;
+  hcf_32	RxMulticastOctets;
+  hcf_32	RxFCSErrors;
+  hcf_32	RxDiscardsNoBuffer;
+  hcf_32	TxDiscardsWrongSA;
+  hcf_32	RxWEPUndecryptable;
+  hcf_32	RxMsgInMsgFragments;
+  hcf_32	RxMsgInBadMsgFragments;
+  hcf_32	RxDiscardsWEPICVError;
+  hcf_32	RxDiscardsWEPExcluded;
+#if (HCF_EXT) & HCF_EXT_TALLIES_FW
+  hcf_32	TalliesExtra[32];
+#endif // HCF_EXT_TALLIES_FW
+} CFG_HERMES_TALLIES_STRCT;
+
+typedef struct  {  //HCF Tallies (IFB substructure)
+  hcf_32	NoBufInfo;  				//No buffer available for unsolicited Notify frame
+  hcf_32	NoBufMB;					//No space available in MailBox
+  hcf_32	MiscErr;					/* Command errors
+  										 *  - time out on completion synchronous part Hermes Command
+  										 *  - completed Hermes Command doesn't match original command
+  										 *  - status of completed Hermes Command contains error bits
+  										 */
+#if (HCF_EXT) & HCF_EXT_TALLIES_FW
+  hcf_32	EngCnt[8];
+#endif // HCF_EXT_TALLIES_FW
+} CFG_HCF_TALLIES_STRCT;
+
+//Note this way to define ..._TAL_CNT implies that all tallies must keep the same (hcf_32) size
+#if (HCF_TALLIES) & ( HCF_TALLIES_NIC | HCF_TALLIES_HCF )
+#if (HCF_TALLIES) & HCF_TALLIES_NIC	//Hermes tally support
+#define		HCF_NIC_TAL_CNT	(sizeof(CFG_HERMES_TALLIES_STRCT)/ sizeof(hcf_32))
+#else
+#define		HCF_NIC_TAL_CNT	0
+#endif // HCF_TALLIES
+#if (HCF_TALLIES) & HCF_TALLIES_HCF	//HCF tally support
+#define		HCF_HCF_TAL_CNT	(sizeof(CFG_HCF_TALLIES_STRCT)   / sizeof(hcf_32))
+#else
+#define		HCF_HCF_TAL_CNT	0
+#endif // HCF_TALLIES
+#define HCF_TOT_TAL_CNT ( HCF_NIC_TAL_CNT + HCF_NIC_TAL_CNT )
+#endif // HCF_TALLIES_NIC / HCF_TALLIES_HCF
+
+
+/***********************************************************************************************************/
+/********************************** I N T E R F A C E   B L O C K ******************************************/
+/***********************************************************************************************************/
+
+#define IFB_VERSION 0x0E	 			// initially 0, to be incremented by every IFB layout change
+
+typedef struct  {
+  hcf_io		IFB_IOBase;				// I/O address of Hermes chip as passed by MSF at hcf_connect call
+  hcf_16		IFB_IORange;			// I/O Range used by Hermes chip
+  hcf_16		IFB_DLMode;				// Download Mode state
+  hcf_16		IFB_Cmd;				// cmd in progress flag, to be ack-ed before next cmd can be issued
+  hcf_16		IFB_RxFID;				// FID of "current" RxFS (non-DMA mode)
+//;?#if tx_delay option
+  hcf_16		IFB_TxFID;				// fid storage during "delayed" send
+//;?#endif tx_delay option
+  hcf_16		IFB_RxLen;				//
+  hcf_16		IFB_DefunctStat;		// BAP initialization or Cmd Completion failed
+  hcf_16		IFB_ErrCmd;				// contents Status reg when error bits and/or mismatch in cmd_wait
+  hcf_16		IFB_ErrQualifier;		// contents Resp0  reg when error bits and/or mismatch in cmd_wait
+  hcf_16		IFB_lal;				// LookAhead Length
+  wci_bufp		IFB_lap;				// LookAhead Buffer pointer
+  hcf_16		IFB_LinkStat;			// Link Status
+  hcf_16		IFB_DSLinkStat;			// Link Status, new strategy introduced for DeepSleep
+  hcf_16		IFB_CarryIn;			// carry and carry-flag to move 1 byte from one get_frag to the next
+  hcf_16		IFB_CarryOut;			// carry and carry-flag to move 1 byte from one put_frag to the next
+  hcf_16		IFB_Version;			// IFB_VERSION, incremented by every SIGNIFICANT IFB layout change
+  hcf_16		IFB_CardStat;			// NIC error / F/W incompatibility status
+  hcf_16  		IFB_RscInd;				// non-DMA: TxFID available, DMA: always 1
+  hcf_16		IFB_CntlOpt;			// flags: 32 bits I/O, DMA available, DMA enabled
+  hcf_16		IFB_BusType;			// BusType, derived via CFG_NIC_BUS_TYPE
+  CFG_FW_IDENTITY_STRCT	 IFB_FWIdentity; /* keep FWIdentity/Sup and PRIIdentity/Sup in sequence
+										  * because of the (dumb) copy in init() */
+#if defined MSF_COMPONENT_ID
+  CFG_SUP_RANGE_STRCT	 IFB_FWSup;
+  CFG_PRI_IDENTITY_STRCT IFB_PRIIdentity;
+  CFG_SUP_RANGE_STRCT	 IFB_PRISup;
+  CFG_SUP_RANGE_STRCT	 IFB_HSISup;
+#endif // MSF_COMPONENT_ID
+#if (HCF_EXT) & HCF_EXT_INFO_LOG
+  RID_LOGP		IFB_RIDLogp;			// pointer to RID_LOG structure
+#endif // HCF_EXT_INFO_LOG
+#if HCF_PROT_TIME
+  hcf_32	 	IFB_TickIni;			// initialization of S/W counter based protection loop
+#endif // HCF_PROT_TIME
+#if (HCF_EXT) & HCF_EXT_INT_TICK
+  int			IFB_TickCnt;			// Hermes Timer Tick Counter
+#endif // HCF_EXT_INT_TICK
+#if (HCF_EXT) & HCF_EXT_MB
+  hcf_16 	   *IFB_MBp;				// pointer to the MailBox
+  hcf_16		IFB_MBSize;				// size of the MailBox
+  hcf_16		IFB_MBWp;				// zero-based write index into the MailBox
+  hcf_16		IFB_MBRp;				// zero-based read  index into the MailBox
+  hcf_16		IFB_MBInfoLen;			// contents of L-field of the oldest available MailBoxInfoBlock
+#endif // HCF_EXT_MB
+#if (HCF_TYPE) & HCF_TYPE_WPA
+  hcf_16		IFB_MICTxCntl;			// MIC bit and Key index in TxControl field of TxFS
+  hcf_32		IFB_MICTxKey[2];		// calculating key
+  hcf_32		IFB_MICTx[2];   	  	// Tx MIC calculation Engine state
+  hcf_16		IFB_MICTxCarry;			// temp length, carries over from one Tx fragment to another
+  hcf_16		IFB_MICRxCarry;			// temp length, carries over from one Rx fragment to another
+  hcf_32		IFB_MICRxKey[4*2];		// 4 checking keys
+  hcf_32		IFB_MICRx[2]; 	 		// Rx MIC calculation Engine state
+#endif // HCF_TYPE_WPA
+#if HCF_ASSERT
+#if (HCF_ASSERT) & HCF_ASSERT_MB
+  CFG_MB_INFO_RANGE1_STRCT	IFB_AssertStrct; // Add some complication to the HCF as prize for the new MSF I/F
+#endif // HCF_ASSERT_MB
+  										// target of above IFB_AssertStrct
+  hcf_16		IFB_AssertLine;			//  - line number ( + encoded module name )
+  hcf_16		IFB_AssertTrace;		//  - bit based trace of all hcf_.... invocations
+  hcf_32		IFB_AssertQualifier;	//  - qualifier
+  hcf_16		IFB_AssertLvl;			// Assert Filtering, Not yet implemented
+  hcf_16		IFB_AssertWhere;		// Where parameter of the Assert macro
+#if (HCF_ASSERT) & ( HCF_ASSERT_LNK_MSF_RTN | HCF_ASSERT_RT_MSF_RTN )
+  MSF_ASSERT_RTNP	IFB_AssertRtn;		// MSF Assert Call back routine (inspired by GEF, DrDobbs Nov 1998 )
+#endif // HCF_ASSERT_LNK_MSF_RTN
+#if (HCF_ASSERT) & HCF_ASSERT_PRINTF	// engineering facilty intended as F/W debugging aid
+   hcf_16       IFB_DbgPrintF_Cnt;
+   CFG_FW_PRINTF_BUFFER_LOCATION_STRCT IFB_FwPfBuff;
+#endif // HCF_ASSERT_PRINTF
+#endif // HCF_ASSERT
+#if ! defined HCF_INT_OFF
+  hcf_16 volatile IFB_IntOffCnt;		// 0xFFFF based HCF_ACT_INT_OFF nesting counter, DeepSleep flag
+#endif // HCF_INT_OFF
+#if (HCF_TYPE) & HCF_TYPE_CCX
+  hcf_16         IFB_CKIPStat;			// CKIP Status flag
+#endif // HCF_TYPE_CCX
+#if (HCF_TALLIES) & ( HCF_TALLIES_NIC | HCF_TALLIES_HCF )	//Hermes and/or HCF tally support
+  hcf_32		IFB_Silly_you_should_align;	//;?
+  hcf_16		IFB_TallyLen;			// Tally length (to build an LTV)
+  hcf_16		IFB_TallyTyp;			// Tally Type (to build an LTV)
+#endif // HCF_TALLIES_NIC / HCF_TALLIES_HCF
+#if (HCF_TALLIES) & HCF_TALLIES_NIC		//Hermes tally support
+  CFG_HERMES_TALLIES_STRCT	IFB_NIC_Tallies;
+#endif // HCF_TALLIES_NIC
+#if (HCF_TALLIES) & HCF_TALLIES_HCF		//HCF tally support
+  CFG_HCF_TALLIES_STRCT		IFB_HCF_Tallies;
+#endif // HCF_TALLIES_HCF
+#if HCF_DMA
+  //used for a pool of destination_address descriptor/buffers, used during tx encapsulation points to the
+  //first/last descriptor in the descriptor chain, so we can easily remove and append a packet.
+  DESC_STRCT	*IFB_FirstDesc[2];
+  DESC_STRCT	*IFB_LastDesc[2];
+  DESC_STRCT	*IFB_ConfinedDesc[2];	// pointers to descriptor used for host reclaim purposes.
+  hcf_16		IFB_DmaPackets;			// HREG_EV_[TX/RX]DMA_DONE flags, reports DMA Frame availability to MSF
+#endif // HCF_DMA
+#if (HCF_EXT) & HCF_EXT_INT_TX_EX
+  hcf_16		IFB_TxFsStat;			// Tx message monitoring
+  hcf_16		IFB_TxFsGap[2];			//;?make this robust
+  hcf_16		IFB_TxFsSwSup;
+#endif // HCF_EXT_INT_TX_EX
+  hcf_16		IFB_Magic;				/* "Magic" signature, to help the debugger interpret a memory dump
+										 * also the last field cleared at hcf_connect
+										 */
+#if (HCF_EXT) & HCF_EXT_IFB_STRCT		// for usage by the MSF
+  void FAR	   *IFB_MSFSup;				// pointer for arbitrary use by the MSF
+#endif // HCF_EXT_IFB_STRCT_EXT
+} IFB_STRCT;
+
+typedef IFB_STRCT*	IFBP;
+
+
+/***********************************************************************************************************/
+/**********************   W C I    F U N C T I O N S    P R O T O T Y P E S   ******************************/
+/***********************************************************************************************************/
+
+EXTERN_C int		 hcf_action			(IFBP ifbp, hcf_16 cmd );
+EXTERN_C int		 hcf_connect		(IFBP ifbp, hcf_io io_base );
+#if (HCF_ENCAP) & HCF_ENC_SUP
+EXTERN_C hcf_8 		 hcf_encap			(wci_bufp type );
+#endif // HCF_ENC_SUP
+EXTERN_C int		 hcf_get_info		(IFBP ifbp, LTVP ltvp );
+EXTERN_C int		 hcf_service_nic	(IFBP ifbp, wci_bufp bufp, unsigned int len );
+EXTERN_C int		 hcf_cntl			(IFBP ifbp, hcf_16 cmd );
+EXTERN_C int		 hcf_put_info		(IFBP ifbp, LTVP ltvp );
+EXTERN_C int		 hcf_rcv_msg		(IFBP ifbp, DESC_STRCT *descp, unsigned int offset );
+EXTERN_C int		 hcf_send_msg       (IFBP ifbp, DESC_STRCT *dp, hcf_16 tx_cntl );
+#if HCF_DMA
+EXTERN_C void		 hcf_dma_tx_put 	(IFBP ifbp, DESC_STRCT *d, hcf_16 tx_cntl );
+EXTERN_C DESC_STRCT* hcf_dma_tx_get		(IFBP ifbp );
+EXTERN_C DESC_STRCT* hcf_dma_rx_get		(IFBP ifbp );
+EXTERN_C void		 hcf_dma_rx_put		(IFBP ifbp, DESC_STRCT *d );
+#endif // HCF_DMA
+#if (HCF_ASSERT) & HCF_ASSERT_LNK_MSF_RTN
+EXTERN_C void		 msf_assert	 		(unsigned int line_number, hcf_16 trace, hcf_32 qual );
+#endif // HCF_ASSERT_LNK_MSF_RTN
+
+#endif  // HCF_H
+
diff --git a/drivers/staging/wlags49_h2/hcfcfg.h b/drivers/staging/wlags49_h2/hcfcfg.h
new file mode 100644
index 0000000..83475b1
--- /dev/null
+++ b/drivers/staging/wlags49_h2/hcfcfg.h
@@ -0,0 +1,2344 @@
+
+//   vim:tw=110:ts=4:
+#ifndef HCFCFG_H
+#define HCFCFG_H 1
+
+/*************************************************************************************************************
+*
+* FILE	 : hcfcfg.tpl // hcfcfg.h
+*
+* DATE   : $Date: 2004/08/05 11:47:10 $   $Revision: 1.6 $
+* Original: 2004/04/08 15:18:16    Revision: 1.40      Tag: t20040408_01
+* Original: 2004/04/01 15:32:55    Revision: 1.38      Tag: t7_20040401_01
+* Original: 2004/03/10 15:39:28    Revision: 1.34      Tag: t20040310_01
+* Original: 2004/03/03 14:10:12    Revision: 1.32      Tag: t20040304_01
+* Original: 2004/03/02 09:27:12    Revision: 1.30      Tag: t20040302_03
+* Original: 2004/02/24 13:00:28    Revision: 1.25      Tag: t20040224_01
+* Original: 2004/02/18 17:13:57    Revision: 1.23      Tag: t20040219_01
+*
+* AUTHOR : Nico Valster
+*
+* DESC   : HCF Customization Macros
+* hcfcfg.tpl list all #defines which must be specified to:
+*   adjust the HCF functions defined in HCF.C to the characteristics of a specific environment
+*		o maximum sizes for messages
+*		o Endianess
+*	Compiler specific macros
+*		o port I/O macros
+*		o type definitions
+*
+* By copying HCFCFG.TPL to HCFCFG.H and -if needed- modifying the #defines the WCI functionality can be
+* tailored
+*
+* Supported environments:
+* WVLAN_41	Miniport								NDIS 3.1
+* WVLAN_42	Packet									Microsoft Visual C 1.5
+* WVLAN_43	16 bits DOS ODI							Microsoft Visual C 1.5
+* WVLAN_44	32 bits ODI (__NETWARE_386__)			WATCOM
+* WVLAN_45	MAC_OS									MPW?, Symantec?
+* WVLAN_46	Windows CE (_WIN32_WCE)					Microsoft ?
+* WVLAN_47	LINUX  (__LINUX__)						GCC, discarded, based on GPL'ed HCF-light
+* WVLAN_48	Miniport								NDIS 5
+* WVLAN_49	LINUX  (__LINUX__)						GCC, originally based on pre-compiled HCF_library
+* 													migrated to use the HCF sources when Lucent Technologies
+* 													brought the HCF module under GPL
+* WVLAN_51	Miniport USB							NDIS 5
+* WVLAN_52	Miniport								NDIS 4
+* WVLAN_53	VxWorks END Station driver
+* WVLAN_54	VxWorks END Access Point driver
+* WVLAN_81	WavePoint								BORLAND C
+* WCITST	Inhouse test tool						Microsoft Visual C 1.5
+* WSU		WaveLAN Station Update					Microsoft Visual C ??
+* SCO UNIX	not yet actually used ?					?
+* __ppc		OEM supplied							?
+* _AM29K	OEM supplied							?
+* ?			OEM supplied							Microtec Research 80X86 Compiler
+*
+**************************************************************************************************************
+*
+*
+* SOFTWARE LICENSE
+*
+* This software is provided subject to the following terms and conditions,
+* which you should read carefully before using the software.  Using this
+* software indicates your acceptance of these terms and conditions.  If you do
+* not agree with these terms and conditions, do not use the software.
+*
+* COPYRIGHT © 1994 - 1995	by AT&T.				All Rights Reserved
+* COPYRIGHT © 1996 - 2000 by Lucent Technologies.	All Rights Reserved
+* COPYRIGHT © 2001 - 2004	by Agere Systems Inc.	All Rights Reserved
+* All rights reserved.
+*
+* Redistribution and use in source or binary forms, with or without
+* modifications, are permitted provided that the following conditions are met:
+*
+* . Redistributions of source code must retain the above copyright notice, this
+*    list of conditions and the following Disclaimer as comments in the code as
+*    well as in the documentation and/or other materials provided with the
+*    distribution.
+*
+* . Redistributions in binary form must reproduce the above copyright notice,
+*    this list of conditions and the following Disclaimer in the documentation
+*    and/or other materials provided with the distribution.
+*
+* . Neither the name of Agere Systems Inc. nor the names of the contributors
+*    may be used to endorse or promote products derived from this software
+*    without specific prior written permission.
+*
+* Disclaimer
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+* INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+* USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+* RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+* DAMAGE.
+*
+*
+*************************************************************************************************************/
+
+/*	Alignment
+*	Some platforms can access words on odd boundaries (with possibly an performance impact), at other
+*	platforms such an access may result in a memory access violation.
+*	It is assumed that everywhere where the HCF casts a char pointer into a word pointer, the alignment
+*	criteria are met. This put some restrictions on the MSF, which are assumed to be "automatically" fulfilled
+*	at the applicable platforms
+*	To assert this assumption, the macro HCF_ALIGN can be defined. The default value is 1, meaning byte
+*	alignment (or no alignment), a value of 2 means word alignment, a value of 4 means double word alignment
+*/
+
+/*****************************    IN_PORT_STRING_8_16  S a m p l e s *****************************************
+
+		// C implementation which let the processor handle the word-at-byte-boundary problem
+#define IN_PORT_STRING_8_16( port, addr, n) while ( n-- ) 	\
+	{ *(hcf_16 FAR*)addr = IN_PORT_WORD( port ); ((hcf_8 FAR*)addr)+=2; }
+
+		// C implementation which handles the word-at-byte-boundary problem
+#define IN_PORT_STRING_8_16( port, addr, n)	while ( n-- )	 \
+	{ hcf_16 i = IN_PORT_WORD(port); *((hcf_8 FAR*)addr)++ = (hcf_8)i; *((hcf_8 FAR*)addr)++ = (hcf_8)(i>>8);}
+
+		// Assembler implementation
+#define IN_PORT_STRING_8_16( port, addr, len) __asm		\
+{														\
+	__asm push di										\
+	__asm push es										\
+	__asm mov cx,len									\
+	__asm les di,addr									\
+	__asm mov dx,port									\
+	__asm rep insw										\
+	__asm pop es										\
+	__asm pop di										\
+}
+
+
+*****************************   OUT_PORT_STRING_8_16  S a m p l e s ******************************************
+
+		// C implementation which let the processor handle the word-at-byte-boundary problem
+#define OUT_PORT_STRING_8_16( port, addr, n)	while ( n-- ) \
+	{ OUT_PORT_WORD( port, *(hcf_16 FAR*)addr ) ; ((hcf_8 FAR*)addr)+=2; }
+
+		// C implementation which handles the word-at-byte-boundary problem
+#define OUT_PORT_STRING_8_16( port, addr, n)	while ( n-- ) \
+	{ OUT_PORT_WORD( port, *((hcf_8 FAR*)addr) | *(((hcf_8 FAR*)addr)+1)<<8  ); (hcf_8 FAR*)addr+=2; }
+
+		// Assembler implementation
+#define OUT_PORT_STRING_8_16( port, addr, len) __asm	\
+{														\
+	__asm push si										\
+	__asm push ds										\
+	__asm mov cx,len									\
+	__asm lds si,addr									\
+	__asm mov dx,port									\
+	__asm rep outsw										\
+	__asm pop ds										\
+	__asm pop si										\
+}
+
+*************************************************************************************************************/
+
+
+/************************************************************************************************/
+/******************  C O M P I L E R   S P E C I F I C   M A C R O S  ***************************/
+/************************************************************************************************/
+/*************************************************************************************************
+*
+*			!!!!!!!!!!!!!!!!!!!!!!!!! Note to the HCF-implementor !!!!!!!!!!!!!!!!!!!!!!!!!
+*			!!!! Do not call these macros with parameters which introduce side effects !!!!
+*			!!!!!!!!!!!!!!!!!!!!!!!!! Note to the HCF-implementor !!!!!!!!!!!!!!!!!!!!!!!!!
+*
+*
+* By selecting the appropriate Macro definitions by means of modifying the "#ifdef 0/1" lines, the HCF can be
+* adjusted for the I/O characteristics of a specific compiler
+*
+* If needed the macros can be modified or replaced with definitions appropriate for your personal platform.
+* If you need to make such changes it is appreciated if you inform Agere Systems
+* That way the changes can become part of the next release of the WCI
+*
+* For convenience of the MSF-programmer, all macros are allowed to modify their parameters (although some
+* might argue that this would constitute bad coding practice). This has its implications on the HCF, e.g. as a
+* consequence these macros should not be called with parameters which have side effects, e.g auto-increment.
+*
+* in the Microsoft implementation of inline assembly it is O.K. to corrupt all flags except the direction flag
+* and to corrupt all registers except the segment registers and EDI, ESI, ESP and EBP (or their 16 bits
+* equivalents).  Other environments may have other constraints
+*
+* in the Intel environment it is O.K to have a word (as a 16 bits quantity) at a byte boundary, hence
+* IN_/OUT_PORT_STRING_8_16 can move words between PC-memory and NIC-memory with as only constraint that the
+* words are on a word boundary in NIC-memory. This does not hold true for all conceivable environments, e.g.
+* an Motorola 68xxx does not allow this. Probably/hopefully the boundary conditions imposed by these type of
+* platforms prevent this case from materializing.  If this is not the case, OUT_PORT_STRING_8_16 must be coded
+* by combining two Host memory hcf_8 values at a time to a single hcf_16 value to be passed to the NIC and
+* IN_PORT_STRING_8_16 the single hcf_16 retrieved from the NIC must be split in two hcf_8 values to be stored
+* in Host memory (see the sample code above)
+*
+*	The prototypes and functional description of the macros are:
+*
+*	hcf_16	IN_PORT_WORD( hcf_16 port )
+*			Reads a word (16 bits) from the specified port
+*
+*	void	OUT_PORT_WORD( hcf_16 port, hcf_16 value)
+*			Writes a word (16 bits) to the specified port
+*
+*	hcf_16	IN_PORT_DWORD( hcf_16 port )
+*			Reads a dword (32 bits) from the specified port
+*
+*	void	OUT_PORT_DWORD( hcf_16 port, hcf_32 value)
+*			Writes a dword (32 bits) to the specified port
+*
+*	void	IN_PORT_STRING_8_16( port, addr, len)
+*			Reads len number of words (16 bits) from NIC memory via the specified port to the (FAR)
+*			byte-pointer addr in PC-RAM
+*			Note that len specifies the number of words, NOT the number of bytes
+*			!!!NOTE, although len specifies the number of words, addr MUST be a char pointer NOTE!!!
+*			See also the common notes for IN_PORT_STRING_8_16 and OUT_PORT_STRING_8_16
+*
+*	void	OUT_PORT_STRING_8_16( port, addr, len)
+*			Writes len number of words (16 bits) from the (FAR) byte-pointer addr in PC-RAM via the specified
+*			port to NIC memory
+*			Note that len specifies the number of words, NOT the number of bytes.
+*			!!!NOTE, although len specifies the number of words, addr MUST be a char pointer NOTE!!!
+*
+*			The peculiar combination of word-length and char pointers for IN_PORT_STRING_8_16 as well as
+*			OUT_PORT_STRING_8_16 is justified by the assumption that it offers a more optimal algorithm
+*
+*	void	IN_PORT_STRING_32( port, addr, len)
+*			Reads len number of double-words (32 bits) from NIC memory via the specified port to the (FAR)
+*			double-word address addr in PC-RAM
+*
+*	void	OUT_PORT_STRING_32( port, addr, len)
+*			Writes len number of double-words (32 bits) from the (FAR) double-word address addr in PC-RAM via
+*			the specified port to NIC memory
+*
+*			!!!!!!!!!!!!!!!!!!!!!!!!! Note to the HCF-implementor !!!!!!!!!!!!!!!!!!!!!!!!!
+*			!!!! Do not call these macros with parameters which introduce side effects !!!!
+*			!!!!!!!!!!!!!!!!!!!!!!!!! Note to the HCF-implementor !!!!!!!!!!!!!!!!!!!!!!!!!
+*
+*************************************************************************************************/
+
+/****************************  define INT Types  ******************************/
+typedef unsigned char			hcf_8;
+typedef unsigned short			hcf_16;
+typedef unsigned long			hcf_32;
+
+/****************************  define I/O Types  ******************************/
+#define HCF_IO_MEM     			0x0001	// memory mapped I/O	( 0: Port I/O )
+#define HCF_IO_32BITS   	  	0x0002 	// 32Bits support		( 0: only 16 Bits I/O)
+
+/****************************** #define HCF_TYPE ********************************/
+#define HCF_TYPE_NONE			0x0000	// No type
+#define HCF_TYPE_WPA			0x0001	// WPA support
+#define HCF_TYPE_USB			0x0002	// reserved (USB Dongle driver support)
+//#define HCF_TYPE_HII			0x0004	// Hermes-II, to discriminate H-I and H-II CFG_HCF_OPT_STRCT
+#define HCF_TYPE_WARP			0x0008	// WARP F/W
+#define HCF_TYPE_PRELOADED		0x0040	// pre-loaded F/W
+#define HCF_TYPE_HII5			0x0080	// Hermes-2.5 H/W
+#define HCF_TYPE_CCX			0x0100	// CKIP
+#define HCF_TYPE_BEAGLE_HII5	0x0200	// Beagle Hermes-2.5 H/W
+#define HCF_TYPE_TX_DELAY		0x4000	// Delayed transmission ( non-DMA only)
+
+/****************************** #define HCF_ASSERT ******************************/
+#define HCF_ASSERT_NONE			0x0000	// No assert support
+#define HCF_ASSERT_PRINTF		0x0001	// Hermes generated debug info
+#define HCF_ASSERT_SW_SUP		0x0002	// logging via Hermes support register
+#define HCF_ASSERT_MB			0x0004	// logging via Mailbox
+#define HCF_ASSERT_RT_MSF_RTN	0x4000	// dynamically binding of msf_assert routine
+#define HCF_ASSERT_LNK_MSF_RTN	0x8000	// statically binding of msf_assert routine
+
+/****************************** #define HCF_ENCAP *******************************/
+#define HCF_ENC_NONE			0x0000	// No encapsulation support
+#define HCF_ENC					0x0001	// HCF handles En-/Decapsulation
+#define HCF_ENC_SUP				0x0002	// HCF supports MSF to handle En-/Decapsulation
+
+/****************************** #define HCF_EXT *********************************/
+#define HCF_EXT_NONE			0x0000	// No expanded features
+#define HCF_EXT_INFO_LOG		0x0001	// logging of Hermes Info frames
+//#define HCF_EXT_INT_TX_OK		0x0002	// RESERVED!!! monitoring successful Tx message
+#define HCF_EXT_INT_TX_EX		0x0004	// monitoring unsuccessful Tx message
+//#define HCF_EXT_MON_MODE		0x0008	// LEGACY
+#define HCF_EXT_TALLIES_FW		0x0010	// support for up to 32 Hermes Engineering tallies
+#define HCF_EXT_TALLIES_HCF		0x0020	// support for up to 8 HCF Engineering tallies
+#define HCF_EXT_NIC_ACCESS		0x0040	// direct access via Aux-ports and to Hermes registers and commands
+#define HCF_EXT_MB				0x0080	// MailBox code expanded
+#define HCF_EXT_IFB_STRCT 		0x0100	// MSF custom pointer in IFB
+#define HCF_EXT_DESC_STRCT 		0x0200	// MSF custom pointer in Descriptor
+#define HCF_EXT_TX_CONT			0x4000	// Continuous transmit test
+#define HCF_EXT_INT_TICK		0x8000	// enables TimerTick interrupt generation
+
+/****************************** #define HCF_SLEEP *******************************/
+#define HCF_DDS					0x0001	// Disconnected Deep Sleep
+#define HCF_CDS					0x0002	// Connected Deep Sleep
+
+/****************************** #define HCF_TALLIES ******************************/
+#define HCF_TALLIES_NONE		0x0000	// No tally support
+#define HCF_TALLIES_NIC			0x0001	// Hermes Tallies accumulated in IFB
+#define HCF_TALLIES_HCF			0x0002	// HCF Tallies accumulated in IFB
+#define HCF_TALLIES_RESET		0x8000	// Tallies in IFB are reset when reported via hcf_get_info
+
+
+/************************************************************************************************/
+/******************************  M I N I P O R T    N D I S *************************************/
+/************************************************************************************************/
+
+#if defined WVLAN_41 || defined WVLAN_48 || defined WVLAN_52 || defined _WIN32_WCE
+
+#ifndef WVLAN_46
+#define HCF_EXT   (HCF_EXT_INFO_LOG | HCF_EXT_MB | HCF_EXT_NIC_ACCESS )
+#else
+#define HCF_EXT ( HCF_EXT_TX_CONT | HCF_EXT_INFO_LOG | HCF_EXT_MB | HCF_EXT_NIC_ACCESS )
+#endif
+#define HCF_DLV 1			//H-I legacy, superfluous for H-II
+
+#ifdef _WIN32_WCE
+#define HCF_IO     HCF_IO_MEM
+#define HCF_DMA		0			// To enable DMA
+#endif
+
+#if _VARIANT == 7
+#define HCF_SLEEP HCF_CDS
+#endif // _VARIANT == 7
+
+#if _VARIANT == 5 || _VARIANT == 6
+#define _WARP
+#define _AES
+#define HCF_SLEEP HCF_CDS
+#if _VARIANT == 6
+//! #define _RSN
+#endif // _VARIANT == 6
+#ifndef _WIN32_WCE
+#define HCF_IO     HCF_IO_32BITS
+#define HCF_DMA		1			// To enable DMA
+#endif
+#endif // _VARIANT == 5 || _VARIANT == 6
+
+
+//HWi for migration purposes I defined a define which will be TRUE for ALL drivers
+//Meaning that _CCX defined code which we think will get a all driver OK flag can be defined from _CCX to _CCX_OK
+#if defined WVLAN_48 // && !defined _WIN32_WCE
+#if _VARIANT == 4 || _VARIANT == 6
+#define _CCX_OK		1
+#endif // _VARIANT == 4 || _VARIANT == 6
+#endif // WVLAN_48
+
+//#if !defined WVLAN_46
+#if defined WVLAN_48
+#if _VARIANT == 4 || _VARIANT == 6
+#define _CCX
+#define HCF_MAX_MSG_CKIP_PADDING    86 //, use 86 for rx fragmentation. 28 is enuf for MIC+PPK encapsulation
+#define HCF_MAX_MSG					( 1514 + HCF_MAX_MSG_CKIP_PADDING  ) // need extra padding for CKIP (need to subtract 28 for NDIS)
+#endif // _VARIANT == 4 || _VARIANT == 6
+#endif // WVLAN_48
+//#endif // WVLAN_46
+
+#if !defined WVLAN_46
+#define _PEEK
+#endif
+
+#ifndef _WIN32_WCE
+// ASSERT already used by WinCE...
+#ifdef ASSERT
+#undef ASSERT
+#define  ASSERT(x) ASSERTDEBUGMSG((x), (TEXT("SIMULATE ASSERT:")))
+#endif
+#endif
+
+
+#if defined WVLAN_41
+#define	MSF_COMPONENT_ID			COMP_ID_MINIPORT_NDIS_31
+#endif // WVLAN_41
+#if defined WVLAN_48 && !defined _WIN32_WCE
+#define	MSF_COMPONENT_ID			COMP_ID_MINIPORT_NDIS_50
+#endif // WVLAN_48 / _WIN32_WCE
+#if defined WVLAN_52 && !defined _WIN32_WCE
+#define	MSF_COMPONENT_ID			COMP_ID_MINIPORT_NDIS_40
+#endif // WVLAN_52 / _WIN32_WCE
+#if defined WVLAN_46
+#define	MSF_COMPONENT_ID			COMP_ID_WIN_CE
+#endif // _WIN32_WCE
+
+#define	MSF_COMPONENT_VAR			_VARIANT
+
+#define	T1__HCF_TYPE					(HCF_TYPE_NONE)
+
+#define T2__HCF_TYPE					(T1__HCF_TYPE)
+
+#ifdef _WARP
+#define T3__HCF_TYPE					(T2__HCF_TYPE | HCF_TYPE_HII5 | HCF_TYPE_WARP )
+#else
+#if _VARIANT == 7
+#define T3__HCF_TYPE					(T2__HCF_TYPE | HCF_TYPE_HII5)
+#else // _VARIANT == 7
+#define T3__HCF_TYPE					(T2__HCF_TYPE)
+#endif // _VARIANT == 7
+#endif // _WARP
+
+#ifdef _CCX_OK
+#define T4__HCF_TYPE					(T3__HCF_TYPE | HCF_TYPE_CCX)
+#else
+#define T4__HCF_TYPE					(T3__HCF_TYPE)
+#endif // _CCX_OK
+
+//not suitable for H-II #define HCF_CFG_STA_1_BOTTOM        	16
+
+// Default WPA in ON for all drivers except for WARP driver
+#ifdef _WARP
+#define T5__HCF_TYPE					(T4__HCF_TYPE)
+#else // _WARP
+#define T5__HCF_TYPE					(T4__HCF_TYPE | HCF_TYPE_WPA)
+#endif // _WARP
+
+#define HCF_TYPE						(T5__HCF_TYPE)
+
+// This is needed to get aux_ctrl() from the HCF for WlFreezeAndDump()
+#if (defined DBG && DBG != 0)
+#ifndef STATIC
+#define STATIC
+#endif
+#endif
+
+#if !defined SOFTRONICS_CODE && !defined _APIDLL && !defined _WIN32_WCE
+#include <ndis.h>
+#endif // SOFTRONICS_CODE / _APIDLL / _WIN32_WCE
+#if defined _WIN32_WCE
+#include <windows.h>
+#include <winnt.h>
+#endif  // _WIN32_WCE
+#include "version.h"
+
+#define	MSF_COMPONENT_MAJOR_VER		TPI_MAJOR_VERSION
+#define	MSF_COMPONENT_MINOR_VER		TPI_MINOR_VERSION
+
+#if !defined _APIDLL && !defined _WIN32_WCE
+
+__inline UCHAR NDIS_IN_BYTE( ULONG port )
+{
+    UCHAR value;
+    NdisRawReadPortUchar(port , &value);
+    return (value);
+}
+
+__inline ULONG NDIS_IN_LONG( ULONG port )
+{
+    ULONG value;
+    NdisRawReadPortUlong(port , &value);
+    return (value);
+}
+__inline USHORT NDIS_IN_WORD( ULONG port )
+{
+    USHORT value;
+    NdisRawReadPortUshort(port , &value);
+    return (value);
+}
+
+#define IN_PORT_DWORD(port)			NDIS_IN_LONG( (ULONG) (port) )
+#define IN_PORT_WORD(port)			NDIS_IN_WORD( (ULONG) (port) )
+#define OUT_PORT_DWORD(port, value)	NdisRawWritePortUlong((ULONG) (port) , value)
+#define OUT_PORT_WORD(port, value)	NdisRawWritePortUshort((ULONG) (port) , (USHORT) (value))
+
+#define  IN_PORT_STRING_8_16(port, addr, len)	IN_PORT_STRING_16(port, addr, len)
+#define  OUT_PORT_STRING_8_16(port, addr, len)	OUT_PORT_STRING_16(port, addr, len)
+
+#define IN_PORT_STRING_32(port, addr, len)		{					\
+	NdisRawReadPortBufferUlong(port, addr, (len));					\
+}
+
+#define OUT_PORT_STRING_32(port, addr, len)	{						\
+	NdisRawWritePortBufferUlong(port, addr, (len));					\
+}
+
+#define IN_PORT_STRING_16(port, addr, len)	NdisRawReadPortBufferUshort(port, addr, (len));
+#define OUT_PORT_STRING_16(port, addr, len)	NdisRawWritePortBufferUshort(port, addr, (len));
+
+#endif //  _APIDLL / _WIN32_WCE
+
+#if defined _WIN32_WCE
+
+#define HCF_ALIGN 2
+#define HCF_MEM_IO					1 // overrule standard Port I/O with Memory mapped I/O
+#define HCF_PROT_TIME				49
+
+#define  		IN_PORT_BYTE			CE_IN_PORT_BYTE
+#define  		OUT_PORT_BYTE			CE_OUT_PORT_BYTE
+#define  		IN_PORT_WORD			CE_IN_PORT_WORD
+#define  		OUT_PORT_WORD			CE_OUT_PORT_WORD
+#define  		IN_PORT_STRING_16		CE_IN_PORT_STRING
+#define  		OUT_PORT_STRING_16		CE_OUT_PORT_STRING
+
+extern hcf_8  CE_IN_PORT_BYTE(hcf_32 port);
+extern void   CE_OUT_PORT_BYTE(hcf_32 port, hcf_8 value);
+extern hcf_16 CE_IN_PORT_WORD(hcf_32 port);
+extern void   CE_OUT_PORT_WORD(hcf_32 port, hcf_16 value);
+extern void   CE_IN_PORT_STRING(hcf_32 port, void *addr, hcf_16 len);
+extern void   CE_OUT_PORT_STRING(hcf_32 port, void *addr, hcf_16 len);
+
+
+#endif
+
+#if defined _DEBUG || (defined DBG && DBG != 0)
+#define HCF_ASSERT ( HCF_ASSERT_LNK_MSF_RTN | HCF_ASSERT_RT_MSF_RTN | HCF_ASSERT_PRINTF ) //0xC001
+//#define HCF_ASSERT ( HCF_ASSERT_LNK_MSF_RTN | HCF_ASSERT_RT_MSF_RTN | HCF_ASSERT_PRINTF | HCF_ASSERT_MB ) //just to test
+#endif // _DEBUG || DBG
+
+#if defined DEBUG || defined _DEBUG || (defined DBG && DBG != 0)
+#ifdef _WIN32_WCE
+#define DBGA2W(DBGSTR)	CeConvertAnsiToUnicodeLen((char*)DBGSTR)
+#define OUTPUTDEBUGMSG(dprintf_exp)			((void)((! ZONE_DEBUG) ? 0:ce_debug_out dprintf_exp))
+#define ASSERTDEBUGMSG(cond, dprintf_exp)			((void)((cond) ? 0:ce_debug_out dprintf_exp))
+
+#define ZONE_ERROR      DEBUGZONE(0)
+#define ZONE_WARN       DEBUGZONE(1)
+#define ZONE_FUNCTION   DEBUGZONE(2)
+#define ZONE_INIT       DEBUGZONE(3)
+#define ZONE_INTR       DEBUGZONE(4)
+#define ZONE_RCV        DEBUGZONE(5)
+#define ZONE_XMIT		DEBUGZONE(6)
+#define ZONE_ASSERT 	DEBUGZONE(7)
+#define ZONE_DEBUG 		DEBUGZONE(8)
+#define ZONE_OEM 		DEBUGZONE(9)
+#define ZONE_HCF		DEBUGZONE(10)
+#define ZONE_PORTIO		DEBUGZONE(11)
+#define ZONE_LOGTOFILE	DEBUGZONE(15)
+
+#else // !(_WIN32_WCE)
+
+#define OUTPUTDEBUGMSG(dprintf_exp)					((void) (DbgPrint dprintf_exp))
+// the assertdebugmsg macro will print filename, line followed by a caller-defined text, when cond == 0
+#define ASSERTDEBUGMSG(cond, print)	((void)((cond) ? 0: (DbgPrint("%s %s:%d - ", print, __FILE__, __LINE__))))
+
+#define ZONE_ERROR      1
+#define ZONE_WARN       1
+#define ZONE_FUNCTION   1
+#define ZONE_INIT       1
+#define ZONE_INTR       1
+#define ZONE_RCV        1
+#define ZONE_XMIT		1
+#define ZONE_ASSERT 	1
+#define ZONE_DEBUG 		1
+#define ZONE_OEM 		1
+#define ZONE_HCF		1
+#define ZONE_PORTIO		1
+#define ZONE_LOGTOFILE	1
+
+#endif // _WIN32_WCE
+#ifndef DBGA2W
+#define DBGA2W
+#endif	// DBGA2W
+
+#else // !(defined DEBUG || defined _DEBUG || (defined DBG && DBG != 0) )
+#define OUTPUTDEBUGMSG(dprintf_exp)
+#define ASSERTDEBUGMSG(cond, dprintf_exp)
+#endif // DEBUG / DBG
+
+#if !defined HCF_MAX_MSG_CKIP_PADDING
+#define HCF_MAX_MSG_CKIP_PADDING 0
+#endif // 		HCF_MAX_MSG_CKIP_PADDING
+
+#if !defined	HCF_MAX_MSG
+#define			HCF_MAX_MSG				1514
+#endif // 		HCF_MAX_MSG
+
+#define			HCF_LEGACY			1	//;?nv je moet wat
+
+#endif //WVLAN_41 / WVLAN_48 / WVLAN_52 / _WIN32_WCE
+
+
+/************************************************************************************************/
+/****************************  P A C K E T   D R I V E R  ***************************************/
+/**********************************  D O S   O D I  *********************************************/
+/************************************************************************************************/
+
+#if defined WVLAN_42 || defined WVLAN_43
+
+#pragma warning ( disable: 4001 )
+#define FAR  __far										//segmented 16 bits mode
+#define BASED __based(__segname("_CODE"))				//force all the "const" structures in the CODE segment
+
+//#define HCF_IO     0									//no DMA, no 32 bits
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To ease testing the different options ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+#define	HCF_EXT						HCF_EXT_MB
+#define HCF_PROT_TIME				49					//49*10240 microseconds H/W failure protection timer
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To ease testing the different options ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+/********************************  CONFIGURATION MANAGEMENT *****************************************/
+#ifdef WVLAN_42
+#define	MSF_COMPONENT_ID			COMP_ID_PACKET
+#define	MSF_COMPONENT_VAR			1
+#define	MSF_COMPONENT_MAJOR_VER		6
+#define	MSF_COMPONENT_MINOR_VER		12
+#endif // WVLAN_42
+
+#ifdef WVLAN_43
+#define	MSF_COMPONENT_ID			COMP_ID_ODI_16
+#define	MSF_COMPONENT_VAR			1
+#define	MSF_COMPONENT_MAJOR_VER		6
+#define	MSF_COMPONENT_MINOR_VER		10
+#endif // WVLAN_43
+
+/**************************************  INPUT / OUTPUT **********************************************/
+#ifndef H_2_INC
+#include <stdio.h>
+#include <conio.h>
+#if 1 //temorary use functions defined in hcf.c
+#ifndef _DEBUG
+#pragma intrinsic( _inp, _inpw, _outp, _outpw )
+#endif // _DEBUG
+
+#define IN_PORT_WORD(port)			((hcf_16)_inpw( (hcf_io)(port) ))
+#define OUT_PORT_WORD(port, value)	((void)_outpw( (hcf_io)(port), value ))
+
+#if 1		// C implementation which let the processor handle the word-at-byte-boundary problem
+#define IN_PORT_STRING_8_16( port, addr, n)		while (n--) \
+	{ *(hcf_16 FAR*)addr = IN_PORT_WORD( port ); ((hcf_8 FAR*)addr)+=2; }
+#define OUT_PORT_STRING_8_16( port, addr, n)	while (n--) \
+	{ OUT_PORT_WORD( port, *(hcf_16 FAR*)addr ) ; ((hcf_8 FAR*)addr)+=2; }
+#elif 0		// C implementation which handles the word-at-byte-boundary problem
+#define IN_PORT_STRING_8_16( port, addr, n)		while ( n-- ) \
+	{ hcf_16 i = IN_PORT_WORD(port); *((hcf_8 FAR*)addr)++ = (hcf_8)i; *((hcf_8 FAR*)addr)++ = (hcf_8)(i>>8);}
+#define OUT_PORT_STRING_8_16( port, addr, n)	while ( n-- ) \
+	{ OUT_PORT_WORD( port, *((hcf_8 FAR*)addr) | *(((hcf_8 FAR*)addr)+1)<<8  ); (hcf_8 FAR*)addr+=2; }
+#else												// Assembler implementation
+#define IN_PORT_STRING_8_16( port, addr, n) __asm	\
+{													\
+	__asm push di									\
+	__asm push es									\
+	__asm mov cx,n									\
+	__asm les di,addr								\
+	__asm mov dx,port								\
+	__asm rep insw									\
+	__asm pop es									\
+	__asm pop di									\
+}
+
+#define OUT_PORT_STRING_8_16( port, addr, n) __asm	\
+{													\
+	__asm push si									\
+	__asm push ds									\
+	__asm mov cx,n									\
+	__asm lds si,addr								\
+	__asm mov dx,port								\
+	__asm rep outsw									\
+	__asm pop ds									\
+	__asm pop si									\
+}
+
+#endif // Asm or C implementation
+#define IN_PORT_STRING_32( port, addr, n)	{ int n2 = 2*n; IN_PORT_STRING_8_16(port, addr, n2) }
+#define OUT_PORT_STRING_32( port, addr, n)	{ int n2 = 2*n; OUT_PORT_STRING_8_16(port, addr, n2) }
+#endif // 0 //temorary use functions defined in hcf.c
+#endif // H_2_INC
+
+#endif	// WVLAN_42 / WVLAN_43
+
+
+
+/************************************************************************************************/
+/****************************  D O S  H - I / II  L O A D E R  **********************************/
+/************************************************************************************************/
+
+#if defined H0_LDR || defined H1_LDR || defined H2_LDR || defined H5_LDR
+
+#if defined H0_LDR				//implies H-I
+#define HCF_DLV		0			//H-I legacy, meaningless under H-II
+#define HCF_DLNV	1			//H-I legacy, meaningless under H-II
+#endif // H0_LDR
+
+#if defined H1_LDR 				//implies H-I
+#define HCF_DLV		1			//H-I legacy, meaningless under H-II
+#define HCF_DLNV	0			//H-I legacy, meaningless under H-II
+#endif // H1_LDR / H2_LDR
+
+//#if defined H2_LDR : not needed, H-II defaults are O.K for H2_LDR
+
+#ifdef H5_LDR
+#define HCF_TYPE			(HCF_TYPE_HII5 | HCF_TYPE_WARP )
+//;? why does only this subset of the H_LDRs need HCF_TYPE to be defined here
+#endif
+
+#define HCF_ASSERT			HCF_ASSERT_LNK_MSF_RTN	//support dynamic linking of msf_assert routine
+#define HCF_ENCAP			0
+#define HCF_INT_ON			0
+#define HCF_TALLIES			0
+
+#define	MSF_COMPONENT_ID			COMP_ID_ODI_16 //;?By lack of any better
+#define	MSF_COMPONENT_VAR			1
+#define	MSF_COMPONENT_MAJOR_VER		0
+#define	MSF_COMPONENT_MINOR_VER		0
+
+#include <stdio.h>
+#include <conio.h>
+#if defined NDEBUG
+#pragma intrinsic( _inp, _inpw, _outp, _outpw )
+#endif // NDEBUG
+
+#if 0						//use 0 to replace I/O Macros with logging facility
+#define IN_PORT_WORD(port)			((hcf_16)_inpw( (hcf_io)(port) ))
+#define OUT_PORT_WORD(port, value)	((void)_outpw( (hcf_io)(port), value ))
+#define IN_PORT_STRING_16( port, addr, n)	\
+		while ( n-- ) { *(hcf_16 FAR*)addr = IN_PORT_WORD( port ); (cast)addr += 2; }
+#define OUT_PORT_STRING_16( port, addr, n)	\
+		while ( n-- ) { OUT_PORT_WORD( port, *(hcf_16 FAR*)addr ) ; (cast)addr  += 2; }
+#endif						//use 0 to replace I/O Macros with logging facility
+
+#endif	// H0_LDR / H1_LDR / H2_LDR
+
+
+
+/************************************************************************************************/
+/****************************  H C F  D E M O  P R O G R A M  ***********************************/
+/************************************************************************************************/
+
+#if defined HCF_DEMO
+
+#define HCF_DLV		1				//;?should become the default !defaults to 1 anyway for H-II
+//#define HCF_DLNV	0				//defaults to 0 anyway for H-II
+
+#define HCF_ASSERT	HCF_ASSERT_LNK_MSF_RTN			//support dynamic linking of msf_assert routine
+
+#define HCF_ENCAP			0
+#define HCF_INT_ON			0
+#define HCF_TALLIES			( HCF_TALLIES_NIC | HCF_TALLIES_HCF )
+
+//#define	MSF_COMPONENT_ID		NO configuration management
+
+#include <stdio.h>
+#include <conio.h>
+#if defined NDEBUG
+#pragma intrinsic( _inp, _inpw, _outp, _outpw )
+#endif // NDEBUG
+
+#if 0						//use 0 to replace I/O Macros with logging facility
+#define IN_PORT_WORD(port)			((hcf_16)_inpw( (hcf_io)(port) ))
+#define OUT_PORT_WORD(port, value)	((void)_outpw( (hcf_io)(port), value ))
+#define IN_PORT_STRING_16( port, addr, n)	\
+		while ( n-- ) { *(hcf_16 FAR*)addr = IN_PORT_WORD( port ); (cast)addr += 2; }
+#define OUT_PORT_STRING_16( port, addr, n)	\
+		while ( n-- ) { OUT_PORT_WORD( port, *(hcf_16 FAR*)addr ) ; (cast)addr  += 2; }
+#endif						//use 0 to replace I/O Macros with logging facility
+
+#endif	// HCF_DEMO
+
+
+
+/************************************************************************************************/
+/***********************************  M A C  O S   **********************************************/
+/************************************************************************************************/
+
+#if defined WVLAN_45
+
+#include "Version.h"
+
+#define MSF_COMPONENT_ID            COMP_ID_MAC_OS
+#define MSF_COMPONENT_VAR           VARIANT
+#define MSF_COMPONENT_MAJOR_VER     VERSION_MAJOR
+#define MSF_COMPONENT_MINOR_VER     VERSION_MINOR
+
+#define MAC_OS                      1
+
+#define HCF_BIG_ENDIAN 1       		// selects Big Endian (a.k.a. Motorola), most significant byte first
+
+#if defined DEBUG
+#define HCF_ASSERT	HCF_ASSERT_MB	// logging via Mailbox
+#endif // DEBUG
+
+#ifdef  __cplusplus
+extern "C" {
+#endif // __cplusplus
+extern volatile unsigned char *MacIOaddr;
+extern hcf_16 IN_PORT_WORD(hcf_16 port);
+extern void   OUT_PORT_WORD(hcf_16 port, hcf_16 value);
+extern void   IN_PORT_STRING_16(hcf_16 port, void *addr, hcf_16 len);
+extern void   OUT_PORT_STRING_16(hcf_16 port, void *addr, hcf_16 len);
+
+#define SwapBytes(t)    (((t) >> 8) + (((t) & 0xff) << 8))
+
+#ifdef  __cplusplus
+}
+#endif // __cplusplus
+
+#endif  // WVLAN_45
+
+
+
+/************************************************************************************************/
+/******************************************  L I N U X  *****************************************/
+/************************************************************************************************/
+
+#ifdef WVLAN_49
+#include <asm/io.h>
+//#include <linux/module.h>
+#include <wl_version.h>
+
+/* The following macro ensures that no symbols are exported, minimizing the chance of a symbol
+   collision in the kernel */
+//EXPORT_NO_SYMBOLS;  //;?this place seems not appropriately to me
+
+//#define HCF_SLEEP (HCF_CDS | HCF_DDS )
+#define HCF_SLEEP (HCF_CDS)
+
+//#define HCF_TYPE    (HCF_TYPE_HII5|HCF_TYPE_STA|HCF_TYPE_AP)
+#ifdef HERMES25
+#ifdef WARP
+#define HCF_TYPE    ( HCF_TYPE_WARP | HCF_TYPE_HII5 )
+#else
+#define HCF_TYPE    HCF_TYPE_HII5
+#endif // WARP
+#else
+#define HCF_TYPE    HCF_TYPE_NONE
+#endif // HERMES25
+
+#ifdef ENABLE_DMA
+#define HCF_DMA		1
+#endif // ENABLE_DMA
+
+/* We now need a switch to include support for the Mailbox and other necessary extensions */
+#define HCF_EXT ( HCF_EXT_MB | HCF_EXT_INFO_LOG | HCF_EXT_INT_TICK )//get deepsleep exercise going
+
+/* ;? The Linux MSF still uses these definitions; define it here until it's removed */
+#ifndef HCF_TYPE_HII
+#define HCF_TYPE_HII 0x0004
+#endif
+
+#ifndef HCF_TYPE_AP
+#define HCF_TYPE_AP  0x0010
+#endif
+
+#ifndef HCF_TYPE_STA
+#define HCF_TYPE_STA 0x0020
+#endif  // HCF_TYPE_STA
+
+/* Guarantees word alignment */
+#define HCF_ALIGN		2
+
+/* Endian macros CNV_INT_TO_LITTLE() and CNV_LITTLE_TO_INT() were renamed to
+   CNV_SHORT_TO_LITTLE() and CNV_LITTLE_TO_SHORT() */
+#ifndef CNV_INT_TO_LITTLE
+#define CNV_INT_TO_LITTLE   CNV_SHORT_TO_LITTLE
+#endif
+
+#ifndef CNV_LITTLE_TO_INT
+#define CNV_LITTLE_TO_INT   CNV_LITTLE_TO_SHORT
+#endif
+
+#define	HCF_ERR_BUSY			0x06
+
+/* UIL defines were removed from the HCF */
+#define UIL_SUCCESS					HCF_SUCCESS
+#define UIL_ERR_TIME_OUT			HCF_ERR_TIME_OUT
+#define UIL_ERR_NO_NIC				HCF_ERR_NO_NIC
+#define UIL_ERR_LEN					HCF_ERR_LEN
+#define UIL_ERR_MIN					HCF_ERR_MAX	/*end of HCF errors which are passed through to UIL
+												  *** ** *** ****** ***** *** ****** ******* ** ***  */
+#define UIL_ERR_IN_USE				0x44
+#define UIL_ERR_WRONG_IFB			0x46
+#define UIL_ERR_MAX					0x7F		/*upper boundary of UIL errors without HCF-pendant
+                                                  ***** ******** ** *** ****** ******* *** *******  */
+#define UIL_ERR_BUSY			    HCF_ERR_BUSY
+#define UIL_ERR_DIAG_1			    HCF_ERR_DIAG_1
+#define UIL_FAILURE					0xFF	/* 20010705 nv this relick should be eridicated */
+#define UIL_ERR_PIF_CONFLICT		0x40	//obsolete
+#define UIL_ERR_INCOMP_DRV			0x41	//obsolete
+#define UIL_ERR_DOS_CALL			0x43	//obsolete
+#define UIL_ERR_NO_DRV				0x42	//obsolete
+#define UIL_ERR_NSTL				0x45	//obsolete
+
+
+
+#if 0  //;? #ifdef get this going LATER HERMES25
+#define HCF_IO              HCF_IO_32BITS
+#define HCF_DMA             1
+#define HCF_DESC_STRCT_EXT  4
+
+/* Switch for BusMaster DMA support. Note that the above define includes the DMA-specific HCF
+   code in the build. This define sets the MSF to use DMA; if ENABLE_DMA is not defined, then
+   port I/O will be used in the build */
+#ifndef BUS_PCMCIA
+#define ENABLE_DMA
+#endif  // USE_PCMCIA
+
+#endif  // HERMES25
+
+
+/* Overrule standard WaveLAN Packet Size when in DMA mode */
+#ifdef ENABLE_DMA
+#define HCF_MAX_PACKET_SIZE 2304
+#else
+#define HCF_MAX_PACKET_SIZE 1514
+#endif  // ENABLE_DMA
+
+/* The following sets the component ID, as well as the versioning. See also wl_version.h */
+#define	MSF_COMPONENT_ID	COMP_ID_LINUX
+
+#define	MSF_COMPONENT_VAR			DRV_VARIANT
+#define MSF_COMPONENT_MAJOR_VER     DRV_MAJOR_VERSION
+#define MSF_COMPONENT_MINOR_VER     DRV_MINOR_VERSION
+
+/* Define the following to turn on assertions in the HCF */
+//#define HCF_ASSERT  0x8000
+#define HCF_ASSERT			HCF_ASSERT_LNK_MSF_RTN	// statically binding of msf_assert routine
+
+#ifdef USE_BIG_ENDIAN
+#define HCF_BIG_ENDIAN  1
+#else
+#define HCF_BIG_ENDIAN  0
+#endif  /* USE_BIG_ENDIAN */
+
+/* Define the following if your system uses memory-mapped IO */
+//#define HCF_MEM_IO
+
+/* The following defines the standard macros required by the HCF to move data to/from the card */
+#define IN_PORT_BYTE(port)			((hcf_8)inb( (hcf_io)(port) ))
+#define IN_PORT_WORD(port)			((hcf_16)inw( (hcf_io)(port) ))
+#define OUT_PORT_BYTE(port, value)	(outb( (hcf_8) (value), (hcf_io)(port) ))
+#define OUT_PORT_WORD(port, value)	(outw((hcf_16) (value), (hcf_io)(port) ))
+
+#define IN_PORT_STRING_16(port, dst, n)    insw((hcf_io)(port), dst, n)
+#define OUT_PORT_STRING_16(port, src, n)   outsw((hcf_io)(port), src, n)
+//#define IN_PORT_STRINGL(port, dst, n)   insl((port), (dst), (n))
+//#define OUT_PORT_STRINGL(port, src, n)  outsl((port), (src), (n))
+#define IN_PORT_STRING_32(port, dst, n)   insl((port), (dst), (n))
+#define OUT_PORT_STRING_32(port, src, n)  outsl((port), (src), (n))
+#define IN_PORT_HCF32(port)          inl( (hcf_io)(port) )
+#define OUT_PORT_HCF32(port, value)  outl((hcf_32)(value), (hcf_io)(port) )
+
+#define IN_PORT_DWORD(port)          IN_PORT_HCF32(port)
+#define OUT_PORT_DWORD(port, value)  OUT_PORT_HCF32(port, value)
+
+#define  IN_PORT_STRING_8_16(port, addr, len)	IN_PORT_STRING_16(port, addr, len)
+#define  OUT_PORT_STRING_8_16(port, addr, len)	OUT_PORT_STRING_16(port, addr, len)
+
+
+#ifndef OUTPUTDEBUGMSG
+#define OUTPUTDEBUGMSG(dprintf_exp)
+#endif
+
+
+#ifndef ASSERTDEBUGMSG
+#define ASSERTDEBUGMSG(cond, dprintf_exp)
+#endif
+
+#ifndef CFG_SCAN_CHANNELS_2GHZ
+#define CFG_SCAN_CHANNELS_2GHZ 0xFCC2
+#endif /* CFG_SCAN_CHANNELS_2GHZ */
+
+#define HCF_MAX_MSG 1600 //get going ;?
+#endif	// WVLAN_49
+
+
+
+/************************************************************************************************/
+/*********************************************  Q N X  ******************************************/
+/************************************************************************************************/
+
+#if defined  __QNX__ || defined WVLAN_50
+
+#define MSF_COMPONENT_ID		0   //Although there is no DUI support, we need this to get ...
+#define MSF_COMPONENT_VAR		0	//...compatibilty check to function
+#define MSF_COMPONENT_MAJOR_VER	0	//...;?this is worth looking into to make this a more
+#define MSF_COMPONENT_MINOR_VER	0	//..."defined" I/F so OEMers can figure out what to do
+
+#include <conio.h>
+
+#define IN_PORT_WORD(port)			((hcf_16)inpw( (hcf_io)(port) ))
+#define OUT_PORT_WORD(port, value)	(outpw( (hcf_io)(port), (hcf_16) (value) ))
+/*
+#define IN_PORT_STRING_16( port, addr, n)	\
+		while ( n-- ) { *(hcf_16*)addr = IN_PORT_WORD( port ); (cast)addr += 2; }
+#define OUT_PORT_STRING_16( port, addr, n)	\
+		while ( n-- ) { OUT_PORT_WORD( port, *(hcf_16*)addr ) ; (cast)addr  += 2; }
+*/
+
+#endif	// QNX / WVLAN_50
+
+
+
+/************************************************************************************************/
+/*********************************************  B E O S  ****************************************/
+/************************************************************************************************/
+
+#if defined  __BEOS__
+
+#define MSF_COMPONENT_ID		0   //Although there is no DUI support, we need this to get ...
+#define MSF_COMPONENT_VAR		0	//...compatibilty check to function
+#define MSF_COMPONENT_MAJOR_VER	0	//...;?this is worth looking into to make this a more
+#define MSF_COMPONENT_MINOR_VER	0	//..."defined" I/F so OEMers can figure out what to do
+
+#include <drivers/Drivers.h>
+#include <drivers/KernelExport.h>
+
+uint8 read_io_8 (int);
+void write_io_8 (int, uint8);
+uint16 read_io_16 (int);
+void write_io_16 (int, uint16);
+
+#define IN_PORT_WORD(port)			((hcf_16)read_io_16( (hcf_io)(port) ))
+#define OUT_PORT_WORD(port, value)	(write_io_16( (hcf_io)(port), (hcf_16) (value) ))
+/*
+#define IN_PORT_STRING_16( port, addr, n)	\
+		while ( n-- ) { *(hcf_16*)addr = IN_PORT_WORD( port ); (cast)addr += 2; }
+#define OUT_PORT_STRING_16( port, addr, n)	\
+		while ( n-- ) { OUT_PORT_WORD( port, *(hcf_16*)addr ) ; (cast)addr  += 2; }
+*/
+#endif	// __BEOS__
+
+
+
+/************************************************************************************************/
+/********************************  U S B   D O N G L E  *****************************************/
+/************************************************************************************************/
+
+#if defined USB
+#include "gpif.h"
+
+#define	MSF_COMPONENT_MAJOR_VER		0
+#define	MSF_COMPONENT_MINOR_VER		1
+
+#define IN_PORT_WORD(port)			(Hermes_IO_Read( (hcf_8)(port)))
+#define OUT_PORT_WORD(port, value)	(Hermes_IO_Write( (hcf_8)port, /*(hcf_16)*/(value) ) )
+/* !!!! NOTE USB supports only 16-bits I/O and no 8-bits I/O
+ * as a consequence the IN_/OUT_PORT_STRING_16 macros use hcf_16* rather than hcf_8 pointers
+ * to get more optimal code
+ * therefore the pointers are incremented by 1 (which means two "bytes") rather than by 2
+ */
+//#define IN_PORT_STRING_16( port, addr, n)	while ( n-- ) { *((hcf_16*)addr)++ = IN_PORT_WORD( port ); }
+//#define OUT_PORT_STRING_16( port, addr, n)	while ( n-- ) { OUT_PORT_WORD( port, *((hcf_16*)addr)++ ); }
+#define IN_PORT_STRING_16( port, dst, n)	while ( n-- ) { *dst++ = IN_PORT_WORD( port ); }
+#define OUT_PORT_STRING_16( port, src, n)	while ( n-- ) { OUT_PORT_WORD( port, *src++ ); }
+
+//#define HCF_TYPE	( HCF_TYPE_AP | HCF_TYPE_WPA )
+#define HCF_TYPE	HCF_TYPE_WPA
+
+#endif	// USB
+
+
+/************************************************************************************************/
+/******************************************  FreeBSD  *******************************************/
+/************************************************************************************************/
+
+#if defined __FREE_BSD__
+
+#define	MSF_COMPONENT_ID			COMP_ID_FreeBSD
+#define	MSF_COMPONENT_VAR			1
+#define	MSF_COMPONENT_MAJOR_VER		1
+#define	MSF_COMPONENT_MINOR_VER		0
+
+#define HCF_IO 						HCF_IO_MEM		// overrule standard Port I/O with Memory mapped I/O
+
+#include <machine/cpufunc.h>
+
+#define IN_PORT_WORD(port)			((hcf_16)inw( (hcf_io)(port) ))
+#define OUT_PORT_WORD(port, value)	(outw((hcf_io)(port), (hcf_16)(value)))
+
+/*
+#define IN_PORT_STRING_16( port, addr, n)	\
+		while ( n-- ) { *(hcf_16*)addr = IN_PORT_WORD( port ); (cast)addr += 2; }
+#define OUT_PORT_STRING_16( port, addr, n)	\
+		while ( n-- ) { OUT_PORT_WORD( port, *(hcf_16*)addr ) ; (cast)addr  += 2; }
+*/
+#endif	// __FREE_BSD__
+
+
+
+/************************************************************************************************/
+/*********************************  W A V E P O I N T  ******************************************/
+/************************************************************************************************/
+
+#if defined WVLAN_81	/* BORLANDC */
+
+#define EXTERN_C  extern	// needed because DHF uses this instead of 'extern'
+
+#define	MSF_COMPONENT_ID	COMP_ID_AP1
+#define	MSF_COMPONENT_VAR			1
+#define	MSF_COMPONENT_MAJOR_VER		4
+#define	MSF_COMPONENT_MINOR_VER		0
+
+#define HCF_PROT_TIME				49	//49*10240 microseconds H/W failure protection timer
+
+//#define HCF_ASSERT	HCF_ASSERT_MB	// logging via Mailbox	/* debug build only */
+
+#if !defined FAR
+#define FAR  far						// segmented 16 bits mode
+#endif // FAR
+
+#define IN_PORT_WORD(port)					(inport( (hcf_io)(port) ))
+#define OUT_PORT_WORD(port, value)			(outport( (hcf_io)(port), value ))
+
+#define IN_PORT_STRING_16(port, addr, len)	\
+	asm { push di; push es; mov cx,len; les di,addr; mov dx,port; rep insw; pop es; pop di }
+
+#define OUT_PORT_STRING_16(port, addr, len)	\
+	asm { push si; push ds; mov cx,len; lds si,addr; mov dx,port; rep outsw; pop ds; pop si }
+
+#endif // WVLAN_81
+
+
+/************************************************************************************************/
+/********************************  W A V E L A U N C H  *****************************************/
+/************************************************************************************************/
+
+#if defined WVLAUNCH
+
+#include "DriverX.h"
+extern HWDEVICE*	g_pDevice;
+
+//#define	MSF_COMPONENT_ID			0  //;? to get around browser problem
+
+#define IN_PORT_WORD(port)	HwInpw( g_pDevice, port )
+#define OUT_PORT_WORD(port, value)	HwOutpw( g_pDevice, port, value )
+
+
+// C implementation which let the processor handle the word-at-byte-boundary problem
+/*
+#define IN_PORT_STRING_16( port, addr, n)	\
+		while ( n-- ) { *(hcf_16 FAR*)addr = IN_PORT_WORD( port ); (cast)addr += 2; }
+#define OUT_PORT_STRING_16( port, addr, n)	\
+		while ( n-- ) { OUT_PORT_WORD( port, *(hcf_16 FAR*)addr ) ; (cast)addr  += 2; }
+*/
+#endif // WVLAUNCH
+
+
+
+/************************************************************************************************/
+/*************************************  W C I T S T *********************************************/
+/************************************************************************************************/
+
+#if defined WCITST
+#define MSF_COMPONENT_ID		0   //Although there is no DUI support, we need this to get ...
+#define MSF_COMPONENT_VAR		0	//...compatibilty check to function
+#define MSF_COMPONENT_MAJOR_VER	0	//...;?this is worth looking into to make this a more
+#define MSF_COMPONENT_MINOR_VER	0	//..."defined" I/F so OEMers can figure out what to do
+
+//#define HCF_ENCAP				HCF_ENC_NONE	//to get going
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To ease testing the different options ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#define HCF_TYPE (HCF_TYPE_WPA | HCF_TYPE_PRELOADED) // Hermes-I for HCF6, II for HCF7
+#define 		HCF_DMA				1
+//#define LLB	//!!!!MIC Debug Only
+#if defined LLB && !((HCF_TYPE) & HCF_TYPE_WPA)
+err: no LLB unless SSN;
+#endif // LLB / HCF_TYPE_WPA
+//#define HCF_ALIGN 2
+#define HCF_DLV		1			//just to change memory layout ????;?
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To ease testing the different options ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+#define HCF_ASSERT	HCF_ASSERT_SW_SUP	// logging via Hermes support registerr
+//#define HCF_ASSERT		HCF_ASSERT_MB		// logging via Mailbox
+
+#if defined __GNUC__
+#include "stdio.h"
+//#include "unistd.h"	//ioperm   libc5
+#include "sys/io.h"	//ioperm   glibc
+#define extern		//see IO Port Programming mini-HOWTO
+//#include "asm/io.h"	//
+#define IN_PORT_WORD(port)			inw( (hcf_io)(port) )
+#define IN_PORT_DWORD(port)			inl( (hcf_io)(port) )
+#define OUT_PORT_WORD(port, value)	outw( (hcf_io)(port), (hcf_16)(value) )
+#define OUT_PORT_DWORD(port, value)	outl( (hcf_io)(port), (hcf_16)(value) )
+#else
+#pragma warning ( disable: 4001 )
+#define FAR  __far					// segmented 16 bits mode
+
+#include <stdio.h>
+#include <conio.h>
+#ifndef _DEBUG
+#pragma intrinsic( _inp, _inpw, _outp, _outpw )
+#endif // _DEBUG
+
+#ifdef LOG
+extern FILE* utm_logfile;
+hcf_16	ipw( hcf_16 port );
+hcf_8	ipb( hcf_16 port );
+void	opw( hcf_16 port, hcf_16 value );
+void	opb( hcf_16 port, hcf_8 value );
+
+#define IN_PORT_WORD(port)			ipw( (hcf_io)(port) )
+#define OUT_PORT_WORD(port, value)	opw( (hcf_io)(port), (hcf_16)(value) )
+#else // LOG
+#define IN_PORT_WORD(port)			((hcf_16)_inpw( (hcf_io)(port) ))
+#define OUT_PORT_WORD(port, value)	((void)_outpw( (hcf_io)(port), value ))
+#endif // LOG
+
+#if 1 //ASM example
+#define IN_PORT_STRING_16( port, addr, len) __asm		\
+{														\
+	__asm push di										\
+	__asm push es										\
+	__asm mov cx,len									\
+	__asm les di,addr									\
+	__asm mov dx,port									\
+	__asm rep insw										\
+	__asm pop es										\
+	__asm pop di										\
+}
+
+#define OUT_PORT_STRING_16( port, addr, len) __asm		\
+{														\
+	__asm push si										\
+	__asm push ds										\
+	__asm mov cx,len									\
+	__asm lds si,addr									\
+	__asm mov dx,port									\
+	__asm rep outsw										\
+	__asm pop ds										\
+	__asm pop si										\
+}
+
+#endif	// asm example
+
+#endif // __GCC__
+
+#if ! defined IN_PORT_STRING_16
+#define IN_PORT_STRING_16( port, addr, n)  while (n--) \
+	{ *(hcf_16 FAR*)addr = IN_PORT_WORD( port ); ((hcf_16 FAR*)addr)++; }
+#define OUT_PORT_STRING_16( port, addr, n) while (n--) \
+	{ OUT_PORT_WORD( port, *(hcf_16 FAR*)addr ); ((hcf_16 FAR*)addr)++; }
+#endif // IN_PORT_STRING_16
+
+#endif	// WCITST
+
+
+/************************************************************************************************/
+/*******************************  Motorola Power PC 800 family  *********************************/
+/************************************************************************************************/
+/* known users: LH@I
+ */
+
+#if defined I_MPC8XX
+
+#define MSF_COMPONENT_VAR		0
+#define MSF_COMPONENT_ID		0
+#define MSF_COMPONENT_MAJOR_VER	1
+#define MSF_COMPONENT_MINOR_VER	0
+
+#define HCF_HSI_VAR				1
+
+#define HCF_BIG_ENDIAN			1
+#define HCF_IO 					HCF_IO_MEM		// overrule standard Port I/O with Memory mapped I/O
+
+#include "o_portbl.h"
+#include "ipcmcia.h"
+typedef o_uint8_t  hcf_8;
+typedef o_uint16_t hcf_16;
+typedef o_uint32_t hcf_32;
+
+/***************************************************************************/
+
+
+#ifdef _lint
+#else
+asm hcf_16 IN_PORT_WORD(int port)
+{
+% reg port
+    lhbrx r3,r0,port
+    eieio
+}
+#endif // _lint
+
+
+#ifdef _lint
+#else
+asm void OUT_PORT_WORD(int port, hcf_16 value)
+{
+% reg port, value
+    sthbrx value,r0,port
+    eieio
+}
+#endif // _lint
+
+/***************************************************************************/
+
+#define IN_PORT_STRING_16(port, addr, len)               \
+   {                                                  \
+      unsigned l = (len);                             \
+      hcf_16 *d = (volatile hcf_16 *)(addr);          \
+      while (l--)                                     \
+      {                                               \
+         *d++ = *(volatile hcf_16 *)(port);           \
+         EIEIO();                                     \
+      }                                               \
+   }
+
+#define OUT_PORT_STRING_16(port, addr, len)           \
+   {                                                  \
+      unsigned l = (len);                             \
+      hcf_16 *s = (volatile hcf_16 *)(addr);          \
+      while (l--)                                     \
+      {                                               \
+         *(volatile hcf_16 *)(port) = *s++;           \
+         EIEIO();                                     \
+      }                                               \
+   }
+
+#endif	// I_MPC8XX
+
+
+
+/************************************************************************************************/
+/**********************************   Diab or High C 29K   **************************************/
+/************************************************************************************************/
+/* known users: GK@C
+ */
+
+#if defined _AM29K
+
+#define MSF_COMPONENT_VAR		0
+#define MSF_COMPONENT_ID		COMP_ID_AP1
+#define MSF_COMPONENT_MAJOR_VER	1
+#define MSF_COMPONENT_MINOR_VER	0
+
+#define HCF_BIG_ENDIAN			1
+#define HCF_IO 					HCF_IO_MEM		// overrule standard Port I/O with Memory mapped I/O
+
+#define SwapBytes(t)    /*lint -e572*/(((t) >> 8) + (((t) & 0xff) << 8))/*lint +e572*/
+
+#if defined __ppc
+    #ifndef __GNUC__
+        #define __asm__     asm
+    #endif
+
+    #if ! defined _lint
+        #define EIEIO()     __asm__(" eieio")
+    #else
+        #define EIEIO()
+    #endif
+
+    static hcf_16 IN_PORT_WORD(int port) {
+        hcf_16 value = *(volatile hcf_16 *)(port); EIEIO();
+        value = SwapBytes(value);
+        return value;
+    }
+
+    #define OUT_PORT_WORD(port, value)      \
+            { *(volatile hcf_16 *)(port) = SwapBytes(value); EIEIO(); }
+#else
+    #define IN_PORT_WORD(port) (*(volatile hcf_16 *)(port))
+    #define OUT_PORT_WORD(port, value) (*(volatile hcf_16 *)(port) = (value))
+#endif // __ppc
+
+/***************************************************************************/
+
+#define IN_PORT_STRING_16( port, addr, len)        {                       \
+                        unsigned l = (len);                             \
+                        hcf_16 t, *d = (volatile hcf_16 *)(addr);       \
+                        while (l--) {                                   \
+                            t = IN_PORT_WORD(port);                     \
+                            *d++ = SwapBytes(t);                        \
+                        }                                               \
+                                                }
+
+#define OUT_PORT_STRING_16( port, addr, len)        {                       \
+                        unsigned l = (len);                             \
+                        hcf_16 t, *s = (volatile hcf_16 *)(addr);        \
+                        while (l--) {                                   \
+                            t = *s++;                                   \
+                            OUT_PORT_WORD(port, SwapBytes(t));          \
+                        }                                               \
+                                                }
+
+#if PRODUCT == 9150
+    #define HCF_ASSERT	HCF_ASSERT_MB	// logging via Mailbox
+    #undef MSF_COMPONENT_ID
+#endif // 9150
+
+#endif	// _AM29K
+
+
+
+/************************************************************************************************/
+/*****************************************  MPC860 **********************************************/
+/************************************************************************************************/
+/* known users: RR
+ */
+
+#if defined CPU
+#if CPU == PPC860
+
+#define MSF_COMPONENT_VAR		0
+#define MSF_COMPONENT_ID		0
+#define MSF_COMPONENT_MAJOR_VER	1
+#define MSF_COMPONENT_MINOR_VER	0
+
+#define HCF_BIG_ENDIAN			1
+#define HCF_IO 					HCF_IO_MEM		// overrule standard Port I/O with Memory mapped I/O
+
+#define SwapBytes(t)    /*lint -e572*/(((t) >> 8) + (((t) & 0xff) << 8))/*lint +e572*/
+
+#ifndef __GNUC__
+    #define __asm__     asm
+#endif
+
+#if ! defined _lint
+    #define EIEIO()     __asm__(" eieio")
+#else
+    #define EIEIO()
+#endif
+
+static hcf_16 IN_PORT_WORD(int port) {
+    hcf_16 value = *(volatile hcf_16 *)(port); EIEIO();
+    value = SwapBytes(value);
+    return value;
+    #ifdef __GNUC__
+        /* the following serves to avoid the compiler warnings that
+         * IN_PORT_WORD() is not used in some files */
+        (void)IN_PORT_WORD;
+    #endif
+}
+
+#define OUT_PORT_WORD(port, value)      \
+        { *(volatile hcf_16 *)(port) = SwapBytes(value); EIEIO(); }
+
+/***************************************************************************/
+
+#define IN_PORT_STRING_16( port, addr, len)        {                       \
+                        unsigned l = (len);                             \
+                        hcf_16 t;                                       \
+                        volatile hcf_16 *d = (volatile hcf_16 *)(addr); \
+                        while (l--) {                                   \
+                            t = IN_PORT_WORD(port);                     \
+                            *d++ = SwapBytes(t);                        \
+                        }                                               \
+                                                }
+
+#define OUT_PORT_STRING_16( port, addr, len)        {                       \
+                        unsigned l = (len);                             \
+                        hcf_16 t;                                       \
+                        volatile hcf_16 *s = (volatile hcf_16 *)(addr);  \
+                        while (l--) {                                   \
+                            t = *s++;                                   \
+                            OUT_PORT_WORD(port, SwapBytes(t));          \
+                        }                                               \
+                                                }
+
+#if PRODUCT == 9150
+    #define HCF_ASSERT	HCF_ASSERT_MB	// logging via Mailbox
+    #undef MSF_COMPONENT_ID
+#endif
+
+#endif	/* PPC860 */
+#endif	/* CPU */
+
+
+
+/************************************************************************************************/
+/****************************  Microtec Research 80X86 Compiler *********************************/
+/************************************************************************************************/
+
+#if 0
+
+//#undef HCF_TYPE									// Hermes-I Station F/W without SSN support
+
+#define MSF_COMPONENT_VAR       0
+#define MSF_COMPONENT_ID        0
+#define MSF_COMPONENT_MAJOR_VER 1
+#define MSF_COMPONENT_MINOR_VER 0
+
+extern int far inp( int );
+extern void far outp( int, int );
+extern int far inpw( int );
+extern void far outpw( int, int );
+
+#define IN_PORT_WORD(port)		((hcf_16)inpw( (hcf_io)(port) ))
+#define OUT_PORT_WORD(port, value)	((void)outpw( (hcf_io)(port), value ))
+
+#define IN_PORT_STRING_16( port, addr, len)        {                       \
+                        unsigned l = (len);                             \
+                        hcf_16 *d = (hcf_16 *)(addr);                   \
+                        while (l--) *d++ =  IN_PORT_WORD(port);         \
+                                                }
+
+#define OUT_PORT_STRING_16( port, addr, len)        {                       \
+                        unsigned l = (len);                             \
+                        hcf_16 *s = (hcf_16 *)(addr);                    \
+                        while (l--) OUT_PORT_WORD(port, *s++);          \
+                                                }
+#endif	/* Microtec 80X86 C Compiler */
+
+
+
+/************************************************************************************************/
+/******************************  W A V E L A N  E C  ********************************************/
+/************************************************************************************************/
+/* known users: KM
+ */
+
+#ifdef mc68302
+
+#define	MSF_COMPONENT_ID			COMP_ID_EC
+
+#include <version.h>
+
+#define	MSF_COMPONENT_VAR			1
+#define	MSF_COMPONENT_MAJOR_VER		MAJOR_VERSION
+#define	MSF_COMPONENT_MINOR_VER		MINOR_VERSION
+
+#define HCF_BIG_ENDIAN				1
+#define HCF_IO 						HCF_IO_MEM		// overrule standard Port I/O with Memory mapped I/O
+
+#define SwapBytes(t)	/*lint -e572*/(((t) >> 8) + (((t) & 0xff) << 8))/*lint +e572*/
+
+#define PCMCIA_ADDRESS 0xc80000UL
+
+#define IN_PORT_2BYTES(port)			 (*(hcf_16 *)(port))
+#if 0
+static hcf_16 IN_PORT_WORD(hcf_32 port) // should be hcf_io, not hcf_32
+{
+  hcf_16 word = IN_PORT_2BYTES(port);
+  return SwapBytes(word);
+}
+#else
+static hcf_16 swap_var;
+#define IN_PORT_WORD(port) \
+  (((swap_var = IN_PORT_2BYTES(port)) >> 8) + (((swap_var) & 0xff) << 8))
+#endif
+#define OUT_PORT_2BYTES(port, value)	 (*(hcf_16 *)(port) = (hcf_16)(value))
+#define OUT_PORT_WORD(port, value)		 OUT_PORT_2BYTES(port, SwapBytes(value))
+
+/*
+#define IN_PORT_STRING_16(port, addr, len)	  \
+	while ((len)--) {*(hcf_16 *)(addr) = IN_PORT_2BYTES(port); ((cast)addr) += 2; }
+#define OUT_PORT_STRING_16(port, addr, len)	  \
+	while ((len)--) {OUT_PORT_2BYTES((port), *(hcf_16 *)(addr)) ; ((cast)addr)  += 2; }
+*/
+
+#endif	/* mc68302 */
+
+
+
+/************************************************************************************************/
+/*********************************  NGAP   ***************************************/
+/************************************************************************************************/
+
+#if defined __VX_WORKS__	/* VxWorks */
+
+#if defined WLC_STATION
+//#undef HCF_TYPE 				/* Hermes-I Station F/W without SSN support */
+#define MSF_COMPONENT_ID	COMP_ID_VX_WORKS_ENDSTA
+#else
+#define MSF_COMPONENT_ID	COMP_ID_VX_WORKS_ENDAP
+#endif	// WLC_STATION
+
+#define HCF_YIELD (taskDelay(0) == 0)
+
+#define    MSF_COMPONENT_VAR              1
+#define    MSF_COMPONENT_MAJOR_VER        1
+#define    MSF_COMPONENT_MINOR_VER        0
+
+// #define HCF_ASSERT	HCF_ASSERT_MB	// logging via Mailbox
+
+#if defined PC486BSP
+
+#define IN_PORT_WORD(port)            (sysInWord ((hcf_io)(port)))
+#define OUT_PORT_WORD(port, value)        (sysOutWord ((hcf_io)(port), (hcf_16) (value)))
+#define IN_PORT_STRING_16(port, addr, n)        (sysInWordString ((hcf_io)(port), addr, n))
+#define OUT_PORT_STRING_16(port, addr, n)        (sysOutWordString ((hcf_io)(port), addr, n))
+
+#elif defined AS2000BSP
+
+#define HCF_IO 						HCF_IO_MEM		// overrule standard Port I/O with Memory mapped I/O
+
+/* Define PCI stuff here. */
+unsigned short sysRead16( unsigned short *port );
+void sysWrite16( unsigned short *port, unsigned short value );
+
+#define PCI_IN_BYTE( port ) \
+	*(unsigned char *)( port )
+
+#define PCI_IN_WORD( port ) \
+	sysRead16( (unsigned short *)( port ) )
+
+#define PCI_OUT_BYTE( port, value ) \
+	*(unsigned char *)( port ) = (unsigned char)( value )
+
+#define PCI_OUT_WORD( port, value ) \
+	sysWrite16( (unsigned short *)( port ), (unsigned short)( value ) )
+
+#define IN_PORT_WORD( port ) \
+	PCI_IN_WORD( port )
+
+#define OUT_PORT_WORD( port, value ) \
+	PCI_OUT_WORD( port, value )
+
+#define IN_PORT_STRING_16( port, buf, len ) \
+	do { \
+		hcf_16 *p; \
+	 \
+	 	for ( p = (hcf_16 *)(buf); p < &( (hcf_16 *)(buf) )[ (int)len ]; p++ ) { \
+			*p = PCI_IN_WORD( port ); \
+		} \
+	} while ( 0 )
+
+#define OUT_PORT_STRING_16( port, buf, len ) \
+	do { \
+		const hcf_16 *p; \
+	 \
+	 	for ( p = (const hcf_16 *)( buf ); p < &( (const hcf_16 *)(buf) )[ (int)len ]; p++ ) { \
+			PCI_OUT_WORD( port, *p ); \
+		} \
+	} while ( 0 )
+
+#elif defined FADS860BSP /* elif defined AS2000BSP */
+
+#define HCF_BIG_ENDIAN 1
+
+#define HCF_IO 						HCF_IO_MEM		// overrule standard Port I/O with Memory mapped I/O
+
+#ifndef __GNUC__
+    #define __asm__     asm
+#endif
+
+#if ! defined _lint
+    #define EIEIO()     __asm__(" eieio")
+#else
+    #define EIEIO()
+#endif
+
+static hcf_16 IN_PORT_WORD(int port) {
+    hcf_16 value = *(volatile hcf_16 *)(port); EIEIO();
+    value = ((value & 0xff00) >> 8) + ((value & 0x00ff) << 8);
+/*  value = CNV_LITTLE_TO_SHORT(value); */
+    return value;
+    #ifdef __GNUC__
+        /* the following serves to avoid the compiler warnings that
+         * IN_PORT_WORD() is not used in some files */
+        (void)IN_PORT_WORD;
+    #endif
+}
+
+#define OUT_PORT_WORD(port, value)                                      \
+        { *(volatile hcf_16 *)(port) = CNV_SHORT_TO_LITTLE(value); EIEIO(); }
+
+/***********************************************************************/
+
+#define IN_PORT_STRING_16( port, addr, len)        {                       \
+                        unsigned l = (len);                             \
+                        volatile hcf_16 *d = (volatile hcf_16 *)(addr); \
+                        while (l--) {                                   \
+                            *d++ = *(volatile hcf_16 *)(port);          \
+                            EIEIO();                                    \
+                        }                                               \
+                                                }
+
+#define OUT_PORT_STRING_16( port, addr, len)        {                       \
+                        unsigned l = (len);                             \
+                        volatile hcf_16 *s = (volatile hcf_16 *)(addr);  \
+                        while (l--) {                                   \
+                            *(volatile hcf_16 *)(port) = *s++;          \
+                            EIEIO();                                    \
+                        }                                               \
+                                                }
+
+#elif defined DAYTONABSP
+
+#define HCF_BIG_ENDIAN 1
+
+#define HCF_IO 						HCF_IO_MEM		// overrule standard Port I/O with Memory mapped I/O
+
+#ifndef __GNUC__
+    #define __asm__     asm
+#endif
+
+#define IN_PORT_WORD(port)              (sysOrinocoInWord((unsigned long)(port)))
+#define OUT_PORT_WORD(port,value)       (sysOrinocoOutWord((unsigned long)(port), (unsigned short)(value)))
+
+#define IN_PORT_STRING_16(port,addr,len)   (sysOrinocoInString((port), (addr), (len)))
+#define OUT_PORT_STRING_16(port,addr,len)   (sysOrinocoOutString((port), (addr), (len)))
+
+extern unsigned char    sysOrinocoInByte    (unsigned long port);
+extern unsigned short   sysOrinocoInWord    (unsigned long port);
+extern void             sysOrinocoInString  (unsigned long port, void *addr, unsigned short len);
+
+extern void             sysOrinocoOutByte   (unsigned long port, unsigned char value);
+extern void             sysOrinocoOutWord   (unsigned long port, unsigned short value);
+extern void             sysOrinocoOutString (unsigned long port, void *addr, unsigned short len);
+
+#elif defined ALPHA_BSP
+
+#define HCF_BIG_ENDIAN 1
+
+#define HCF_IO 						HCF_IO_MEM		// overrule standard Port I/O with Memory mapped I/O
+
+#ifndef __GNUC__
+    #define __asm__     asm
+#endif
+
+#define IN_PORT_WORD(port)              (sysOrinocoInWord((unsigned long)(port)))
+#define OUT_PORT_WORD(port,value)       (sysOrinocoOutWord((unsigned long)(port), (unsigned short)(value)))
+
+#define IN_PORT_STRING_16(port,addr,len)   (sysOrinocoInString((port), (addr), (len)))
+#define OUT_PORT_STRING_16(port,addr,len)   (sysOrinocoOutString((port), (addr), (len)))
+
+extern unsigned char    sysOrinocoInByte    (unsigned long port);
+extern unsigned short   sysOrinocoInWord    (unsigned long port);
+extern void             sysOrinocoInString  (unsigned long port, void *addr, unsigned short len);
+
+extern void             sysOrinocoOutByte   (unsigned long port, unsigned char value);
+extern void             sysOrinocoOutWord   (unsigned long port, unsigned short value);
+extern void             sysOrinocoOutString (unsigned long port, void *addr, unsigned short len);
+
+#else
+
+err: /* commented here */ /*	"BSP is not defined..." */
+
+#endif	/* else PC486BSP */
+
+#endif	// __VX_WORKS__
+
+
+
+/************************************************************************************************/
+/******************************  VXWORKS. Motorola Sandpoint PowerPC 824X ***********************/
+/************************************************************************************************/
+#ifdef __VX_WORKS_SANDPOINT_824X__
+
+#include <vxWorks.h>
+#include <sysLib.h>
+#include <taskLib.h>
+
+#ifdef WVLAN_53
+#define	MSF_COMPONENT_ID            COMP_ID_VX_WORKS_ENDSTA
+#endif /* WVLAN_53 */
+
+#ifdef WVLAN_54
+#define	MSF_COMPONENT_ID            COMP_ID_VX_WORKS_ENDAP
+#endif /* WVLAN_54 */
+
+#ifdef WVLAN_56
+#define	MSF_COMPONENT_ID            COMP_ID_VX_WORKS_END
+#endif /* WVLAN_56 */
+
+#if !defined MSF_COMPONENT_ID
+#error "you must define an MSF component ID: WVLAN_53, WVLAN_54, WVLAN_56"
+#endif
+
+#define	MSF_COMPONENT_VAR			1
+
+#define HCF_EXT                         HCF_EXT_INFO_LOG
+#define HCF_SLEEP                       ( HCF_CDS | HCF_DDS )
+//#define HCF_SLEEP                       ( HCF_DDS )
+
+#ifndef HCF_ACT_WAKEUP
+#define HCF_ACT_WAKEUP                  0x1D
+#endif // HCF_ACT_WAKEUP
+
+#if defined FATNIC | defined BEAGLE_H253
+#define T1__HCF_TYPE                    HCF_TYPE_STA
+#else
+#define T1__HCF_TYPE                    HCF_TYPE_AP | HCF_TYPE_STA
+#endif
+
+#ifdef HERMES_USB
+#define T2__HCF_TYPE					(T1__HCF_TYPE | HCF_TYPE_USB)
+#else // HERMES_USB
+#define T2__HCF_TYPE					(T1__HCF_TYPE)
+#endif // HERMES_USB
+
+#ifdef _WARP
+#define T3__HCF_TYPE					(T2__HCF_TYPE | HCF_TYPE_HII5)
+#else // _WARP
+#define T3__HCF_TYPE					(T2__HCF_TYPE | HCF_TYPE_WPA | HCF_TYPE_HII)
+#endif // WARP
+
+#ifdef _CCX
+#define T4__HCF_TYPE					(T3__HCF_TYPE | HCF_TYPE_CCX)
+#else // _WARP
+#define T4__HCF_TYPE					(T3__HCF_TYPE)
+#endif // _CCX
+
+#define T5__HCF_TYPE					(T4__HCF_TYPE)
+
+// Default to TYPE_AP + SSN!
+#define HCF_TYPE						(T5__HCF_TYPE )
+
+
+
+#define	MSF_COMPONENT_MAJOR_VER		2
+#define	MSF_COMPONENT_MINOR_VER		0
+
+#define HCF_IO                      HCF_IO_MEM
+#define HCF_DMA                     0
+#define HCF_MEM_IO                  1
+#define HCF_BIG_ENDIAN              1
+
+//#define support_32bits 1
+
+#define IN_PORT_WORD(port)			        (sysInWord( (hcf_io)(port) ))
+#define OUT_PORT_WORD(port, value)	        (sysOutWord( (hcf_io)(port), (hcf_16)(value) ))
+#define IN_PORT_DWORD(port)			        (sysInLong( (hcf_io)(port) ))
+#define OUT_PORT_DWORD(port, value)	        (sysOutLong( (hcf_io)(port), (hcf_16)(value) ))
+#define IN_PORT_STRING_16(port, dst, n)	    (sysInWordString((hcf_io)(port), (hcf_16 *)dst, n))
+#define OUT_PORT_STRING_16(port, src, n)    (sysOutWordString((hcf_io)(port), (hcf_16 *)src, n))
+
+#ifdef WVLAN_DEBUG
+#define DBG                         1
+#define _DEBUG                      1
+#endif
+
+/* we'll need to add these prints someday */
+#define OUTPUTDEBUGMSG(dprintf_exp)
+#define ASSERTDEBUGMSG(cond, dprintf_exp)
+
+#define HCF_INTERFACE_CONNECT(ifbp)
+#define HCF_INTERFACE_DISCONNECT(ifbp)
+#define HCF_ENTER_INTERFACE_FUNCT(ibfb)
+#define HCF_LEAVE_INTERFACE_FUNCT(ifbp)
+
+#define CNV_END_INT(w)    ( ((hcf_16)(w) & 0x00FF) << 8 | ((hcf_16)(w) & 0xFF00) >> 8 )
+#define CNV_LITTLE_TO_INT(w)	CNV_END_INT(w)
+#define CNV_INT_TO_LITTLE(w)	CNV_LITTLE_TO_INT(w)
+
+#endif /* __VX_WORKS_SANDPOINT_824X__ */
+
+/************************************************************************************************/
+/*************************************  VXWORKS. ARM T8300 IPPhone  *****************************/
+/************************************************************************************************/
+#if defined( IPT_T8300 ) || defined( IPT_T8307 )
+
+#include <vxWorks.h>
+#include <sysLib.h>
+#include <taskLib.h>
+
+#define HCF_ALIGN                   4       /* default to 4 byte alignment */
+
+#define BEAGLE_H253	/* Hermes 2.5.3 build, better to be in the project file */
+#define OOR_DDS		/* Hermes 2.5.3 build, better to be in the project file */
+#define FATNIC
+
+
+#ifdef WVLAN_53
+#define	MSF_COMPONENT_ID            COMP_ID_VX_WORKS_ENDSTA
+#endif /* WVLAN_53 */
+
+#ifdef WVLAN_54
+#define	MSF_COMPONENT_ID            COMP_ID_VX_WORKS_ENDAP
+#endif /* WVLAN_54 */
+
+#ifdef WVLAN_56
+#define	MSF_COMPONENT_ID            COMP_ID_VX_WORKS_END
+#endif /* WVLAN_56 */
+
+#if !defined MSF_COMPONENT_ID
+#error "you must define an MSF component ID: WVLAN_53, WVLAN_54, WVLAN_56"
+#endif
+
+#define	MSF_COMPONENT_VAR			1
+
+#define HCF_EXT                         HCF_EXT_INFO_LOG
+//#define HCF_EXT                         HCF_EXT_INFO_LOG | HCF_EXT_MB
+#define HCF_SLEEP                       ( HCF_CDS | HCF_DDS )
+//#define HCF_SLEEP                       ( HCF_DDS )
+
+#ifndef HCF_ACT_WAKEUP
+#define HCF_ACT_WAKEUP                  0x1D
+#endif // HCF_ACT_WAKEUP
+
+#if defined FATNIC || defined BEAGLE_H253
+#define T1__HCF_TYPE                    HCF_TYPE_STA
+#else
+//#define T1__HCF_TYPE                    HCF_TYPE_AP | HCF_TYPE_STA
+#define T1__HCF_TYPE                    HCF_TYPE_STA		/* dz, Station code only */
+#endif
+
+#ifdef HERMES_USB
+#define T2__HCF_TYPE					(T1__HCF_TYPE | HCF_TYPE_USB)
+#else // HERMES_USB
+#define T2__HCF_TYPE					(T1__HCF_TYPE)
+#endif // HERMES_USB
+
+#ifdef _WARP
+#define T3__HCF_TYPE					(T2__HCF_TYPE | HCF_TYPE_HII5)
+#else // _WARP
+#define T3__HCF_TYPE					(T2__HCF_TYPE | HCF_TYPE_WPA | HCF_TYPE_HII)
+//#define T3__HCF_TYPE					(T2__HCF_TYPE | HCF_TYPE_HII)	/* dz. no WPA support at this time, test code */
+#endif // WARP
+
+#ifdef _CCX
+#define T4__HCF_TYPE					(T3__HCF_TYPE | HCF_TYPE_CCX)
+#else // _WARP
+#define T4__HCF_TYPE					(T3__HCF_TYPE)
+#endif // _CCX
+
+#define T5__HCF_TYPE					(T4__HCF_TYPE)
+
+// Default to TYPE_AP + SSN!
+#define HCF_TYPE						(T5__HCF_TYPE )
+
+
+#define	MSF_COMPONENT_MAJOR_VER		2
+#define	MSF_COMPONENT_MINOR_VER		0
+
+#define HCF_IO                      HCF_IO_MEM
+#define HCF_DMA                     0
+#define HCF_MEM_IO                  1
+
+
+/* Endian is determined by vxWorks project compile option */
+#if (_BYTE_ORDER == _BIG_ENDIAN)
+#undef  HCF_LITTLE_ENDIAN
+#define HCF_BIG_ENDIAN              1
+#endif
+
+
+#define CNV_END(w)    ( ((hcf_16)(w) & 0x00FF) << 8 | ((hcf_16)(w) & 0xFF00) >> 8 )
+#if defined HCF_BIG_ENDIAN
+//******************************************** B I G   E N D I A N *******************************************
+#define CNV_LITTLE_TO_INT(w)    CNV_END(w)	//    endianess conversion needed
+#define CNV_BIG_TO_INT(w)		(w)			// no endianess conversion needed
+#else
+//****************************************** L I T T L E   E N D I A N ****************************************
+#define CNV_LITTLE_TO_INT(w) 	(w)			// no endianess conversion needed
+#define CNV_BIG_TO_INT(w)       CNV_END(w)	//    endianess conversion needed
+#endif // HCF_BIG_ENDIAN
+
+// conversion macros which can be expressed in other macros
+#define CNV_INT_TO_LITTLE(w)	CNV_LITTLE_TO_INT(w)
+#define CNV_INT_TO_BIG(w)		CNV_BIG_TO_INT(w)
+
+
+
+#define IN_PORT_WORD( port )            *((volatile hcf_16 *)( port ))
+#define OUT_PORT_WORD( port, value )    *((volatile hcf_16 *)( port )) = ((hcf_16)( value ))
+//#define IN_PORT_BYTE( port )            *((volatile hcf_8 *)( port ))
+
+#define IN_PORT_STRING( port, addr, len) {		\
+	unsigned l = len;								\
+	hcf_16  *d = (hcf_16 *)(addr);					\
+	hcf_16   t;										\
+	while (l--) {									\
+		t = IN_PORT_WORD(port);						\
+		*d++ = CNV_LITTLE_TO_INT(t);				\
+	}												\
+} // IN_PORT_STRING
+
+#define OUT_PORT_STRING( port, addr, len) {		\
+	unsigned l = (len);								\
+	hcf_16  *s = (hcf_16 *)(addr);					\
+	hcf_16   t;										\
+	while (l--) {									\
+		t = *s++;									\
+		t = CNV_LITTLE_TO_INT(t);					\
+		OUT_PORT_WORD(port, t);						\
+	}												\
+} // OUT_PORT_STRING
+
+#define IN_PORT_STRING_16(port, dst, n)	    {	\
+	unsigned l = (n);								\
+	hcf_16  *d = (hcf_16 *)(dst);					\
+	while (l--) {									\
+		*d++ = IN_PORT_WORD(port);					\
+	}												\
+} // IN_PORT_STRING_16
+
+#define OUT_PORT_STRING_16(port, src, n)	{	\
+	hcf_16   t;										\
+	int l = (n);									\
+	hcf_16  *s = (hcf_16 *)(src);					\
+	while (l--) {									\
+		t = *s++;									\
+		OUT_PORT_WORD(port, t);						\
+	}												\
+} // OUT_PORT_STRING_16
+
+/* #define HCF_YIELD                       (taskDelay(0) == 0) */
+
+
+
+#ifdef WVLAN_DEBUG
+#define DBG                         1
+#define _DEBUG                      1
+#endif
+
+/* we'll need to add these prints someday */
+#define OUTPUTDEBUGMSG(dprintf_exp)
+#define ASSERTDEBUGMSG(cond, dprintf_exp)
+
+#define HCF_INTERFACE_CONNECT(ifbp)
+#define HCF_INTERFACE_DISCONNECT(ifbp)
+#define HCF_ENTER_INTERFACE_FUNCT(ibfb)
+#define HCF_LEAVE_INTERFACE_FUNCT(ifbp)
+
+#define sysInWord(offsetAddr)  IN_PORT_WORD(offsetAddr)
+#define sysInByte(offsetAddr)  IN_PORT_BYTE(offsetAddr)
+#define sysOutWord(addr, value) OUT_PORT_WORD(addr, value)
+
+#endif /*IPT_T8300 */
+
+/************************************************************************************************************/
+/***********************************                                   **************************************/
+/************************************************************************************************************/
+#if ! defined 	HCF_ALIGN
+#define 		HCF_ALIGN			1		//default to no alignment
+#endif // 		HCF_ALIGN
+
+#if ! defined 	HCF_ASSERT
+#define 		HCF_ASSERT			0
+#endif //		HCF_ASSERT
+
+#if ! defined	HCF_BIG_ENDIAN
+#define 		HCF_BIG_ENDIAN		0
+#endif // 		HCF_BIG_ENDIAN
+
+#if ! defined	HCF_DL_ONLY
+#define 		HCF_DL_ONLY			0
+#endif // 		HCF_DL_ONLY
+
+#if ! defined	HCF_DMA
+#define 		HCF_DMA				0
+#endif // 		HCF_DMA
+
+#if ! defined	HCF_ENCAP
+#define			HCF_ENCAP			HCF_ENC
+#endif //		HCF_ENCAP
+
+#if ! defined	HCF_ENTRY
+#define			HCF_ENTRY( ifbp )
+#endif //		HCF_ENTRY
+
+#if ! defined	HCF_EXIT
+#define			HCF_EXIT( ifbp )
+#endif //		HCF_EXIT
+
+#if ! defined	HCF_EXT
+#define			HCF_EXT				0
+#endif //		HCF_EXT
+
+#if ! defined	HCF_INT_ON
+#define			HCF_INT_ON			1
+#endif //		HCF_INT_ON
+
+#if ! defined	HCF_IO
+#define			HCF_IO				0		//default 16 bits support only, port I/O
+#endif //		HCF_IO
+
+#if ! defined	HCF_LEGACY
+#define			HCF_LEGACY			0
+#endif //		HCF_LEGACY
+
+#if ! defined	HCF_MAX_LTV
+#define 		HCF_MAX_LTV			1200	// sufficient for all known purposes
+#endif //		HCF_MAX_LTV
+
+#if ! defined	HCF_PROT_TIME
+#define 		HCF_PROT_TIME		100		// number of 10K microsec protection timer against H/W malfunction
+#endif // 		HCF_PROT_TIME
+
+#if ! defined	HCF_SLEEP
+#define			HCF_SLEEP			0
+#endif //		HCF_SLEEP
+
+#if ! defined	HCF_TALLIES
+#define			HCF_TALLIES			( HCF_TALLIES_NIC | HCF_TALLIES_HCF )
+#endif //		HCF_TALLIES
+
+#if ! defined 	HCF_TYPE
+#define 		HCF_TYPE 			0
+#endif //		HCF_TYPE
+
+#if				HCF_BIG_ENDIAN
+#undef			HCF_BIG_ENDIAN
+#define			HCF_BIG_ENDIAN		1		//just for convenience of generating cfg_hcf_opt
+#endif //	 	HCF_BIG_ENDIAN
+
+#if				HCF_DL_ONLY
+#undef			HCF_DL_ONLY
+#define			HCF_DL_ONLY			1		//just for convenience of generating cfg_hcf_opt
+#endif //		HCF_DL_ONLY
+
+#if				HCF_DMA
+#undef			HCF_DMA
+#define			HCF_DMA				1		//just for convenience of generating cfg_hcf_opt
+#endif //		HCF_DMA
+
+#if				HCF_INT_ON
+#undef			HCF_INT_ON
+#define			HCF_INT_ON			1		//just for convenience of generating cfg_hcf_opt
+#endif //		HCF_INT_ON
+
+
+#if ! defined IN_PORT_STRING_8_16
+#define  IN_PORT_STRING_8_16(port, addr, len)	IN_PORT_STRING_16(port, addr, len)
+#define  OUT_PORT_STRING_8_16(port, addr, len)	OUT_PORT_STRING_16(port, addr, len)
+#endif // IN_PORT_STRING_8_16
+
+/************************************************************************************************/
+/**********                                                                         *************/
+/************************************************************************************************/
+
+#if ! defined	FAR
+#define 		FAR						// default to flat 32-bits code
+#endif // 		FAR
+
+typedef hcf_8  FAR *wci_bufp;			// segmented 16-bits or flat 32-bits pointer to 8 bits unit
+typedef hcf_16 FAR *wci_recordp;		// segmented 16-bits or flat 32-bits pointer to 16 bits unit
+
+/*	I/O Address size
+*	Platforms which use port mapped I/O will (in general) have a 64k I/O space, conveniently expressed in a
+*	16-bits quantity
+*	Platforms which use memory mapped I/O will (in general) have an I/O space much larger than 64k, and need a
+*	32-bits quantity to express the I/O base
+*/
+
+#if HCF_IO & HCF_IO_MEM
+typedef hcf_32 hcf_io;
+#else
+typedef hcf_16 hcf_io;
+#endif //HCF_IO
+
+#if 	HCF_PROT_TIME > 128
+#define HCF_PROT_TIME_SHFT	3
+#define HCF_PROT_TIME_DIV	8
+#elif 	HCF_PROT_TIME > 64
+#define HCF_PROT_TIME_SHFT	2
+#define HCF_PROT_TIME_DIV	4
+#elif 	HCF_PROT_TIME > 32
+#define HCF_PROT_TIME_SHFT	1
+#define HCF_PROT_TIME_DIV	2
+#else //HCF_PROT_TIME >= 19
+#define HCF_PROT_TIME_SHFT	0
+#define HCF_PROT_TIME_DIV	1
+#endif
+
+#define HCF_PROT_TIME_CNT (HCF_PROT_TIME / HCF_PROT_TIME_DIV)
+
+
+/************************************************************************************************************/
+/******************************************* . . . . . . . . .  *********************************************/
+/************************************************************************************************************/
+
+/* MSF_COMPONENT_ID is used to define the CFG_IDENTITY_STRCT in HCF.C
+* CFG_IDENTITY_STRCT is defined in HCF.C purely based on convenience arguments.
+* The HCF can not have the knowledge to determine the ComponentId field of the Identity record (aka as
+* Version Record), therefore the MSF part of the Drivers must supply this value via the System Constant
+* MSF_COMPONENT_ID.
+* There is a set of values predefined in MDD.H (format COMP_ID_.....)
+*
+* Note that taking MSF_COMPONENT_ID as a default value for DUI_COMPAT_VAR is purely an implementation
+* convenience, the numerical values of these two quantities have none functional relationship whatsoever.
+*/
+
+#if defined	MSF_COMPONENT_ID
+
+#if ! defined	DUI_COMPAT_VAR
+#define			DUI_COMPAT_VAR		MSF_COMPONENT_ID
+#endif //		DUI_COMPAT_VAR
+
+#if ! defined	DUI_COMPAT_BOT		//;?this way utilities can lower as well raise the bottom
+#define			DUI_COMPAT_BOT		8
+#endif //		DUI_COMPAT_BOT
+
+#if ! defined	DUI_COMPAT_TOP		//;?this way utilities can lower as well raise the top
+#define			DUI_COMPAT_TOP       8
+#endif //		DUI_COMPAT_TOP
+
+#endif // MSF_COMPONENT_ID
+
+#if (HCF_TYPE) & HCF_TYPE_HII5
+
+#if ! defined	HCF_HSI_VAR_5
+#define			HCF_HSI_VAR_5
+#endif //		HCF_HSI_VAR_5
+
+#if ! defined	HCF_APF_VAR_4
+#define			HCF_APF_VAR_4
+#endif //		HCF_APF_VAR_4
+
+#if (HCF_TYPE) & HCF_TYPE_WARP
+#if ! defined	HCF_STA_VAR_4
+#define			HCF_STA_VAR_4
+#endif //		HCF_STA_VAR_4
+#else
+#if ! defined	HCF_STA_VAR_2
+#define			HCF_STA_VAR_2
+#endif //		HCF_STA_VAR_2
+#endif
+
+#if defined HCF_HSI_VAR_4
+err: HSI variants 4 correspond with HII;
+#endif // HCF_HSI_VAR_4
+
+#else
+
+#if ! defined	HCF_HSI_VAR_4
+#define			HCF_HSI_VAR_4		//Hermes-II all types (for the time being!)
+#endif //		HCF_HSI_VAR_4
+
+#if ! defined	HCF_APF_VAR_2
+#define 		HCF_APF_VAR_2
+#endif //		HCF_APF_VAR_2
+
+#if ! defined	HCF_STA_VAR_2
+#define			HCF_STA_VAR_2
+#endif //		HCF_STA_VAR_2
+
+#endif // HCF_TYPE_HII5
+
+#if ! defined	HCF_PRI_VAR_3
+#define		HCF_PRI_VAR_3
+#endif //		HCF_PRI_VAR_3
+
+#if defined HCF_HSI_VAR_1 || defined HCF_HSI_VAR_2 || defined HCF_HSI_VAR_3
+err: HSI variants 1, 2 and 3 correspond with H-I only;
+#endif // HCF_HSI_VAR_1, HCF_HSI_VAR_2, HCF_HSI_VAR_3
+
+#if defined HCF_PRI_VAR_1 || defined HCF_PRI_VAR_2
+err: primary variants 1 and 2 correspond with H-I only;
+#endif // HCF_PRI_VAR_1 / HCF_PRI_VAR_2
+
+
+/************************************************************************************************************/
+/******************************************* . . . . . . . . .  *********************************************/
+/************************************************************************************************************/
+
+
+/* The BASED customization macro is used to resolves the SS!=DS conflict for the Interrupt Service logic in
+ * DOS Drivers. Due to the cumbersomeness of mixing C and assembler local BASED variables still end up in the
+ * wrong segment. The workaround is that the HCF uses only global BASED variables or IFB-based variables.
+ * The "BASED" construction (supposedly) only amounts to something in the small memory model.
+ *
+ * Note that the whole BASED rigmarole is needlessly complicated because both the Microsoft Compiler and
+ * Linker are unnecessary restrictive in what far pointer manipulation they allow
+ */
+
+#if ! defined	BASED
+#define 		BASED
+#endif //		BASED
+
+#if ! defined	EXTERN_C
+#ifdef __cplusplus
+#define			EXTERN_C extern "C"
+#else
+#define			EXTERN_C
+#endif // __cplusplus
+#endif //		EXTERN_C
+
+#if ! defined	NULL
+#define			NULL	((void *) 0)
+#endif //		NULL
+
+#if ! defined	TEXT
+#define			TEXT(x)	x
+#endif //		TEXT
+
+#if !defined	_TCHAR_DEFINED
+#define 		TCHAR	char
+#endif //		_TCHAR_DEFINED
+
+/************************************************************************************************************/
+/*********************** C O N F L I C T   D E T E C T I O N  &  R E S O L U T I O N ************************/
+/************************************************************************************************************/
+#if defined HCF_LITTLE_ENDIAN
+err: HCF_LITTLE_ENDIAN is obsolete;
+#endif // 	HCF_LITTLE_ENDIAN
+
+#if defined HCF_INT_OFF
+err: HCF_INT_OFF is obsolete;
+#endif //HCF_INT_OFF
+
+#if HCF_ALIGN != 1 && HCF_ALIGN != 2 && HCF_ALIGN != 4 && HCF_ALIGN != 8
+err: invalid value for HCF_ALIGN;
+#endif // HCF_ALIGN
+
+#if (HCF_ASSERT) & ~( HCF_ASSERT_PRINTF | HCF_ASSERT_SW_SUP | HCF_ASSERT_MB | HCF_ASSERT_RT_MSF_RTN | \
+					  HCF_ASSERT_LNK_MSF_RTN )
+err: invalid value for HCF_ASSERT;
+#endif // HCF_ASSERT
+
+#if (HCF_ASSERT) & HCF_ASSERT_MB && ! ( (HCF_EXT) & HCF_EXT_MB )		//detect potential conflict
+err: these macros are not used consistently;
+#endif // HCF_ASSERT_MB / HCF_EXT_MB
+
+#if HCF_BIG_ENDIAN != 0 && HCF_BIG_ENDIAN != 1
+err: invalid value for HCF_BIG_ENDIAN;
+#endif // HCF_BIG_ENDIAN
+
+#if HCF_DL_ONLY != 0 && HCF_DL_ONLY != 1
+err: invalid value for HCF_DL_ONLY;
+#endif // HCF_DL_ONLY
+
+#if HCF_DMA != 0 && HCF_DMA != 1
+err: invalid value for HCF_DMA;
+#endif // HCF_DMA
+
+#if (HCF_ENCAP) & ~( HCF_ENC | HCF_ENC_SUP )
+err: invalid value for HCF_ENCAP;
+#endif // HCF_ENCAP
+
+#if (HCF_EXT) & ~( HCF_EXT_INFO_LOG | HCF_EXT_INT_TX_EX | HCF_EXT_TALLIES_FW | HCF_EXT_TALLIES_HCF	| \
+				   HCF_EXT_NIC_ACCESS | HCF_EXT_MB | HCF_EXT_INT_TICK | \
+				   HCF_EXT_IFB_STRCT | HCF_EXT_DESC_STRCT | HCF_EXT_TX_CONT )
+err: invalid value for HCF_EXT;
+#endif // HCF_EXT
+
+#if HCF_INT_ON != 0 && HCF_INT_ON != 1
+err: invalid value for HCF_INT_ON;
+#endif // HCF_INT_ON
+
+#if (HCF_IO) & ~( HCF_IO_MEM | HCF_IO_32BITS )
+err: invalid value for HCF_IO;
+#endif // HCF_IO
+
+#if HCF_LEGACY != 0 && HCF_LEGACY != 1
+err: invalid value for HCF_LEGACY;
+#endif // HCF_LEGACY
+
+#if HCF_MAX_LTV < 16 || HCF_MAX_LTV > 2304
+err: invalid value for HCF_MAX_LTV;
+#endif // HCF_MAX_LTV
+
+#if HCF_PROT_TIME != 0 && ( HCF_PROT_TIME < 19 || 256 < HCF_PROT_TIME )
+err: below minimum .08 second required by Hermes or possibly above hcf_32 capacity;
+#endif // HCF_PROT_TIME
+
+#if (HCF_SLEEP) & ~( HCF_CDS | HCF_DDS )
+err: invalid value for HCF_SLEEP;
+#endif // HCF_SLEEP
+
+#if (HCF_SLEEP) && ! (HCF_INT_ON)
+err: these macros are not used consistently;
+#endif // HCF_SLEEP / HCF_INT_ON
+
+#if (HCF_SLEEP) && ! ( (HCF_EXT) & HCF_EXT_INT_TICK )
+//;? err: these macros are not used consistently;
+#endif // HCF_SLEEP / HCF_EXT_INT_TICK
+
+#if (HCF_TALLIES) & ~( HCF_TALLIES_HCF | HCF_TALLIES_NIC | HCF_TALLIES_RESET ) || \
+	(HCF_TALLIES) == HCF_TALLIES_RESET
+err: invalid value for HCF_TALLIES;
+#endif // HCF_TALLIES
+
+#if (HCF_TYPE) & ~(HCF_TYPE_WPA | HCF_TYPE_USB | HCF_TYPE_PRELOADED | HCF_TYPE_HII5 | HCF_TYPE_WARP | \
+		HCF_TYPE_CCX /* | HCF_TYPE_TX_DELAY */ )
+err: invalid value for HCF_TYPE;
+#endif //HCF_TYPE
+
+#if (HCF_TYPE) & HCF_TYPE_WARP && (HCF_TYPE) & HCF_TYPE_WPA
+err: at most 1 of these macros should be defined;
+#endif //HCF_TYPE_WARP / HCF_TYPE_WPA
+
+#endif //HCFCFG_H
+
diff --git a/drivers/staging/wlags49_h2/hcfdef.h b/drivers/staging/wlags49_h2/hcfdef.h
new file mode 100644
index 0000000..f7e74bf
--- /dev/null
+++ b/drivers/staging/wlags49_h2/hcfdef.h
@@ -0,0 +1,809 @@
+
+//   vim:tw=110:ts=4:
+#ifndef HCFDEFC_H
+#define HCFDEFC_H 1
+
+/*************************************************************************************************
+*
+* FILE	 : HCFDEF.H
+*
+* DATE   : $Date: 2004/08/05 11:47:10 $   $Revision: 1.8 $
+* Original: 2004/05/28 14:05:35    Revision: 1.59      Tag: hcf7_t20040602_01
+* Original: 2004/05/13 15:31:45    Revision: 1.53      Tag: hcf7_t7_20040513_01
+* Original: 2004/04/15 09:24:42    Revision: 1.44      Tag: hcf7_t7_20040415_01
+* Original: 2004/04/13 14:22:45    Revision: 1.43      Tag: t7_20040413_01
+* Original: 2004/04/01 15:32:55    Revision: 1.40      Tag: t7_20040401_01
+* Original: 2004/03/10 15:39:28    Revision: 1.36      Tag: t20040310_01
+* Original: 2004/03/03 14:10:12    Revision: 1.34      Tag: t20040304_01
+* Original: 2004/03/02 09:27:12    Revision: 1.32      Tag: t20040302_03
+* Original: 2004/02/24 13:00:29    Revision: 1.29      Tag: t20040224_01
+* Original: 2004/02/18 17:13:57    Revision: 1.26      Tag: t20040219_01
+*
+* AUTHOR : Nico Valster
+*
+* SPECIFICATION: ...........
+*
+* DESC   : Definitions and Prototypes for HCF only
+*
+**************************************************************************************************
+*
+*
+* SOFTWARE LICENSE
+*
+* This software is provided subject to the following terms and conditions,
+* which you should read carefully before using the software.  Using this
+* software indicates your acceptance of these terms and conditions.  If you do
+* not agree with these terms and conditions, do not use the software.
+*
+* COPYRIGHT © 1994 - 1995	by AT&T.				All Rights Reserved
+* COPYRIGHT © 1996 - 2000 by Lucent Technologies.	All Rights Reserved
+* COPYRIGHT © 2001 - 2004	by Agere Systems Inc.	All Rights Reserved
+* All rights reserved.
+*
+* Redistribution and use in source or binary forms, with or without
+* modifications, are permitted provided that the following conditions are met:
+*
+* . Redistributions of source code must retain the above copyright notice, this
+*    list of conditions and the following Disclaimer as comments in the code as
+*    well as in the documentation and/or other materials provided with the
+*    distribution.
+*
+* . Redistributions in binary form must reproduce the above copyright notice,
+*    this list of conditions and the following Disclaimer in the documentation
+*    and/or other materials provided with the distribution.
+*
+* . Neither the name of Agere Systems Inc. nor the names of the contributors
+*    may be used to endorse or promote products derived from this software
+*    without specific prior written permission.
+*
+* Disclaimer
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+* INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+* USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+* RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+* DAMAGE.
+*
+*
+*************************************************************************************************/
+
+
+/************************************************************************************************/
+/*********************************  P R E F I X E S  ********************************************/
+/************************************************************************************************/
+//IFB_		Interface Block
+//HCMD_		Hermes Command
+//HFS_		Hermes (Transmit/Receive) Frame Structure
+//HREG_		Hermes Register
+
+/*************************************************************************************************/
+
+#if 0 //
+#define BIT0  0x0001
+#define BIT1  0x0002
+#define BIT2  0x0004
+#define BIT3  0x0008
+#define BIT4  0x0010
+#define BIT5  0x0020
+#define BIT6  0x0040
+#define BIT7  0x0080
+#define BIT8  0x0100
+#define BIT9  0x0200
+#define BIT10 0x0400
+#define BIT11 0x0800
+#define BIT12 0x1000
+#define BIT13 0x2000
+#define BIT14 0x4000
+#define BIT15 0x8000
+#define BIT16 0x00010000
+#define BIT17 0x00020000
+#define BIT18 0x00040000
+#define BIT19 0x00080000
+#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
+#endif // 0
+
+/************************************************************************************************/
+/********************************* GENERAL EQUATES **********************************************/
+/************************************************************************************************/
+
+
+#define HCF_MAGIC				0x7D37	// "}7" Handle validation
+
+#define	PLUG_DATA_OFFSET        0x00000800	//needed by some test tool on top of H-II NDIS driver
+
+#define INI_TICK_INI			0x00040000L
+
+#define IO_IN					0		//hcfio_in_string
+#define IO_OUT					1		//hcfio_out_string
+
+//DO_ASSERT, create an artificial FALSE to force an ASSERT without the nasty compiler warning
+#define DO_ASSERT				( assert_ifbp->IFB_Magic != HCF_MAGIC && assert_ifbp->IFB_Magic == HCF_MAGIC )
+#define NT_ASSERT				0x0000		//, NEVER_TESTED
+#define NEVER_TESTED			MERGE_2( 0xEFFE, 0xFEEF )
+#define SE_ASSERT				0x5EFF		/* Side Effect, HCFASSERT invokation which are only called for the
+											 * side effect and which should never trigger */
+#define DHF_FILE_NAME_OFFSET	10000		//to distinguish DHF from HCF asserts by means of line number
+#define MMD_FILE_NAME_OFFSET	20000		//to distinguish MMD from HCF asserts by means of line number
+
+// trace codes used to
+// 1: profile execution times via HCF_TRACE and HCF_TRACE_VALUE
+// 2: hierarchical flow information via HCFLOGENTRY / HCFLOGEXIT
+
+//#define HCF_TRACE_CONNECT		useless
+//#define HCF_TRACE_DISCONNECT	useless
+#define HCF_TRACE_ACTION		0x0000  // 0x0001
+#define HCF_TRACE_CNTL			0x0001  // 0x0002
+#define HCF_TRACE_DMA_RX_GET	0x0002  // 0x0004
+#define HCF_TRACE_DMA_RX_PUT	0x0003  // 0x0008
+#define HCF_TRACE_DMA_TX_GET	0x0004  // 0x0010
+#define HCF_TRACE_DMA_TX_PUT	0x0005  // 0x0020
+#define HCF_TRACE_GET_INFO		0x0006  // 0x0040
+#define HCF_TRACE_PUT_INFO		0x0007  // 0x0080
+#define HCF_TRACE_RCV_MSG		0x0008  // 0x0100
+#define HCF_TRACE_SEND_MSG		0x0009  // 0x0200
+#define HCF_TRACE_SERVICE_NIC	0x000A  // 0x0400
+// #define HCF_TRACE_           0x000C  // 0x1000
+// #define HCF_TRACE_           0x000D  // 0x2000
+// #define HCF_TRACE_           0x000E  // 0x4000
+// #define HCF_TRACE_           0x000F  // 0x8000
+//	============================================ HCF_TRACE_... codes below 0x0010 are asserted on re-entry
+#define HCF_TRACE_ACTION_KLUDGE	0x0010  /* once you start introducing kludges there is no end to it
+										 * this is an escape to do not assert on re-entrancy problem caused
+										 * by HCF_ACT_INT_FORCE_ON used to get Microsofts NDIS drivers going
+										 */
+#define HCF_TRACE_STRIO			0x0020
+#define HCF_TRACE_ALLOC			0X0021
+#define HCF_TRACE_DL			0X0023
+#define HCF_TRACE_ISR_INFO		0X0024
+#define HCF_TRACE_CALIBRATE		0x0026
+
+#define HCF_TRACE_CMD_CPL 		0x0040
+#define HCF_TRACE_CMD_EXE		0x0041
+#define HCF_TRACE_GET_FID		0x0042
+#define HCF_TRACE_GET_FRAG		0x0043
+#define HCF_TRACE_INIT			0x0044
+#define HCF_TRACE_PUT_FRAG		0x0045
+#define HCF_TRACE_SETUP_BAP		0x0046
+
+#define	HCF_TRACE_EXIT 			0x8000	// Keil C warns "long constant truncated to int"
+
+//#define BAP_0					HREG_DATA_0		//Used by DMA controller to access NIC RAM
+#define BAP_1					HREG_DATA_1		//Used by HCF to access NIC RAM
+
+
+//************************* Hermes Receive/Transmit Frame Structures
+//HFS_STAT
+//see MMD.H for HFS_STAT_ERR
+#define 	HFS_STAT_MSG_TYPE	0xE000	//Hermes reported Message Type
+#define 	HFS_STAT_MIC_KEY_ID	0x1800	//MIC key used (if any)
+#define 	HFS_STAT_1042		0x2000	//RFC1042 Encoded
+#define 	HFS_STAT_TUNNEL		0x4000	//Bridge-Tunnel Encoded
+#define 	HFS_STAT_WMP_MSG	0x6000	//WaveLAN-II Management Protocol Frame
+#if (HCF_TYPE) & HCF_TYPE_WPA
+#define 	HFS_STAT_MIC		0x0010	//Frame contains MIC  //;? re-instate when F/W ready
+#endif
+
+//************************* Hermes Register Offsets and Command bits
+#define HREG_IO_RANGE			0x80		//I/O Range used by Hermes
+
+
+//************************* Command/Status
+#define HREG_CMD				0x00		//
+#define 	HCMD_CMD_CODE			0x3F
+#define HREG_PARAM_0			0x02		//
+#define HREG_PARAM_1			0x04		//
+#define HREG_PARAM_2			0x06		//
+#define HREG_STAT				0x08		//
+#define 	HREG_STAT_CMD_CODE		0x003F	//
+#define		HREG_STAT_DIAG_ERR		0x0100
+#define		HREG_STAT_INQUIRE_ERR	0x0500
+#define 	HREG_STAT_CMD_RESULT	0x7F00	//
+#define HREG_RESP_0				0x0A		//
+#define HREG_RESP_1				0x0C		//
+#define HREG_RESP_2				0x0E		//
+
+
+//************************* FID Management
+#define HREG_INFO_FID			0x10		//
+#define HREG_RX_FID				0x20		//
+#define HREG_ALLOC_FID  		0x22		//
+#define HREG_TX_COMPL_FID  		0x24		//
+
+
+//************************* BAP
+//20031030 HWi Inserted this again because the dongle code uses this (GPIF.C)
+//#define HREG_SELECT_0			0x18		//
+//#define HREG_OFFSET_0			0x1C		//
+//#define HREG_DATA_0			0x36		//
+
+//#define 	HREG_OFFSET_BUSY		0x8000	// use HCMD_BUSY
+#define 	HREG_OFFSET_ERR			0x4000	//
+//rsrvd #define 	HREG_OFFSET_DATA_OFFSET	0x0FFF	//
+
+#define HREG_SELECT_1			0x1A		//
+#define HREG_OFFSET_1			0x1E		//
+#define HREG_DATA_1				0x38		//
+
+
+//************************* Event
+#define HREG_EV_STAT			0x30		//
+#define HREG_INT_EN				0x32		//
+#define HREG_EV_ACK				0x34		//
+
+#define    HREG_EV_TICK				0x8000	//Auxiliary Timer Tick
+//#define  HREG_EV_RES				0x4000	//H-I only: H/W error (Wait Time-out)
+#define    HREG_EV_INFO_DROP		0x2000	//WMAC did not have sufficient RAM to build Unsollicited Frame
+#if (HCF_TYPE) & HCF_TYPE_HII5
+#define    HREG_EV_ACK_REG_READY	0x0000
+#else
+#define    HREG_EV_ACK_REG_READY	0x1000	//Workaround Kludge bit for H-II (not H-II.5)
+#endif // HCF_TYPE_HII5
+#if (HCF_SLEEP) & ( HCF_CDS | HCF_DDS )
+#define    HREG_EV_SLEEP_REQ		0x0800
+#else
+#define    HREG_EV_SLEEP_REQ		0x0000
+#endif // HCF_CDS / HCF_DDS
+#if HCF_DMA
+//#define    HREG_EV_LPESC			0x0400 // firmware sets this bit and clears it, not for host usage.
+#define    HREG_EV_RDMAD			0x0200 // rx frame in host memory
+#define    HREG_EV_TDMAD			0x0100 // tx frame in host memory processed
+//#define    HREG_EV_RXDMA			0x0040 // firmware kicks off DMA engine (bit is not for host usage)
+//#define    HREG_EV_TXDMA			0x0020 // firmware kicks off DMA engine (bit is not for host usage)
+#define    HREG_EV_FW_DMA			0x0460 // firmware / DMA engine I/F (bits are not for host usage)
+#else
+#define    HREG_EV_FW_DMA			0x0000
+#endif // HCF_DMA
+#define    HREG_EV_INFO				0x0080	// Asynchronous Information Frame
+#define    HREG_EV_CMD				0x0010	// Command completed, Status and Response available
+#define    HREG_EV_ALLOC			0x0008	// Asynchronous part of Allocation/Reclaim completed
+#define    HREG_EV_TX_EXC			0x0004	// Asynchronous Transmission unsuccessful completed
+#define    HREG_EV_TX				0x0002	// Asynchronous Transmission successful completed
+#define    HREG_EV_RX				0x0001	// Asynchronous Receive Frame
+
+#define    HREG_EV_TX_EXT 			( (HCF_EXT) & (HCF_EXT_INT_TX_EX | HCF_EXT_INT_TICK ) )
+									/* HREG_EV_TX_EXT := 0x0000 or HREG_EV_TX_EXC and/or HREG_EV_TICK
+									 * could be extended with HREG_EV_TX */
+#if HCF_EXT_INT_TX_EX != HREG_EV_TX_EXC
+err: these values should match;
+#endif // HCF_EXT_INT_TX_EX / HREG_EV_TX_EXC
+
+#if HCF_EXT_INT_TICK != HREG_EV_TICK
+err: these values should match;
+#endif // HCF_EXT_INT_TICK / HREG_EV_TICK
+
+//************************* Host Software
+#define HREG_SW_0				0x28		//
+#define HREG_SW_1				0x2A		//
+#define HREG_SW_2				0x2C		//
+//rsrvd #define HREG_SW_3		0x2E		//
+//************************* Control and Auxiliary Port
+
+#define HREG_IO					0x12
+#define		HREG_IO_SRESET			0x0001
+#define		HREG_IO_WAKEUP_ASYNC	0x0002
+#define		HREG_IO_WOKEN_UP		0x0004
+#define HREG_CNTL				0x14		//
+//#define		HREG_CNTL_WAKEUP_SYNC	0x0001
+#define		HREG_CNTL_AUX_ENA_STAT	0xC000
+#define		HREG_CNTL_AUX_DIS_STAT	0x0000
+#define		HREG_CNTL_AUX_ENA_CNTL	0x8000
+#define		HREG_CNTL_AUX_DIS_CNTL	0x4000
+#define		HREG_CNTL_AUX_DSD		0x2000
+#define		HREG_CNTL_AUX_ENA		(HREG_CNTL_AUX_ENA_CNTL | HREG_CNTL_AUX_DIS_CNTL )
+#define HREG_SPARE				0x16		//
+#define HREG_AUX_PAGE			0x3A		//
+#define HREG_AUX_OFFSET			0x3C		//
+#define HREG_AUX_DATA			0x3E		//
+
+#if HCF_DMA
+//************************* DMA (bus mastering)
+	// Be carefull to use these registers only at a genuine 32 bits NIC
+	// On 16 bits NICs, these addresses are mapped into the range 0x00 through 0x3F with all consequences
+	// thereof, e.g.  HREG_DMA_CTRL register maps to HREG_CMD.
+#define HREG_DMA_CTRL						0x0040
+#define HREG_TXDMA_PTR32					0x0044
+#define HREG_TXDMA_PRIO_PTR32				0x0048
+#define HREG_TXDMA_HIPRIO_PTR32				0x004C
+#define HREG_RXDMA_PTR32					0x0050
+#define HREG_CARDDETECT_1					0x007C // contains 7D37
+#define HREG_CARDDETECT_2					0x007E // contains 7DE7
+#define HREG_FREETIMER						0x0058
+#define HREG_DMA_RX_CNT						0x0026
+
+/******************************************************************************
+* Defines for the bits in the DmaControl register (@40h)
+******************************************************************************/
+#define HREG_DMA_CTRL_RXHWEN				0x80000000 // high word enable bit
+#define HREG_DMA_CTRL_RXRESET				0x40000000 // tx dma init bit
+#define HREG_DMA_CTRL_RXBAP1				BIT29
+#define HREG_DMA_CTRL_RX_STALLED			BIT28
+#define HREG_DMA_CTRL_RXAUTOACK_DMADONE		BIT27 // no host involvement req. for TDMADONE event
+#define HREG_DMA_CTRL_RXAUTOACK_INFO		BIT26 // no host involvement req. for alloc event
+#define HREG_DMA_CTRL_RXAUTOACK_DMAEN		0x02000000 // no host involvement req. for TxDMAen event
+#define HREG_DMA_CTRL_RXAUTOACK_RX			0x01000000 // no host involvement req. for tx event
+#define HREG_DMA_CTRL_RX_BUSY				BIT23 // read only bit
+//#define HREG_DMA_CTRL_RX_RBUFCONT_PLAIN		0	  // bits 21..20
+//#define HREG_DMA_CTRL_RX_MODE_PLAIN_DMA		0	  // mode 0
+#define HREG_DMA_CTRL_RX_MODE_SINGLE_PACKET	0x00010000 // mode 1
+#define HREG_DMA_CTRL_RX_MODE_MULTI_PACKET	0x00020000 // mode 2
+//#define HREG_DMA_CTRL_RX_MODE_DISABLE		(0x00020000|0x00010000) // disable tx dma engine
+#define HREG_DMA_CTRL_TXHWEN				0x8000 // low word enable bit
+#define HREG_DMA_CTRL_TXRESET				0x4000 // rx dma init bit
+#define HREG_DMA_CTRL_TXBAP1				BIT13
+#define HREG_DMA_CTRL_TXAUTOACK_DMADONE		BIT11 // no host involvement req. for RxDMADONE event
+#define HREG_DMA_CTRL_TXAUTOACK_DMAEN		0x00000400 // no host involvement req. for RxDMAen event
+#define HREG_DMA_CTRL_TXAUTOACK_DMAALLOC	0x00000200  // no host involvement req. for info event
+#define HREG_DMA_CTRL_TXAUTOACK_TX			0x00000100  // no host involvement req. for rx event
+#define HREG_DMA_CTRL_TX_BUSY				BIT7  // read only bit
+//#define HREG_DMA_CTRL_TX_TBUFCONT_PLAIN		0	  // bits 6..5
+//#define HREG_DMA_CTRL_TX_MODE_PLAIN_DMA		0	  // mode 0
+#define HREG_DMA_CTRL_TX_MODE_SINGLE_PACKET	BIT0 // mode 1
+#define HREG_DMA_CTRL_TX_MODE_MULTI_PACKET	0x00000002 // mode 2
+//#define HREG_DMA_CTRL_TX_MODE_DISABLE		(0x00000001|0x00000002) // disable tx dma engine
+
+//configuration DWORD to configure DMA for mode2 operation, using BAP0 as the DMA BAP.
+#define DMA_CTRLSTAT_GO (HREG_DMA_CTRL_RXHWEN | HREG_DMA_CTRL_RX_MODE_MULTI_PACKET | \
+                         HREG_DMA_CTRL_RXAUTOACK_DMAEN | HREG_DMA_CTRL_RXAUTOACK_RX | \
+                         HREG_DMA_CTRL_TXHWEN | /*;?HREG_DMA_CTRL_TX_TBUFCONT_PLAIN |*/ \
+                         HREG_DMA_CTRL_TX_MODE_MULTI_PACKET | HREG_DMA_CTRL_TXAUTOACK_DMAEN |\
+                         HREG_DMA_CTRL_TXAUTOACK_DMAALLOC)
+
+//configuration DWORD to reset both the Tx and Rx DMA engines
+#define DMA_CTRLSTAT_RESET (HREG_DMA_CTRL_RXHWEN | HREG_DMA_CTRL_RXRESET | HREG_DMA_CTRL_TXHWEN | HREG_DMA_CTRL_TXRESET)
+
+//#define DESC_DMA_OWNED     		0x80000000 					// BIT31
+#define DESC_DMA_OWNED     		0x8000	 					// BIT31
+#define DESC_SOP   			 	0x8000 						// BIT15
+#define DESC_EOP   			 	0x4000 						// BIT14
+
+#define DMA_RX				0
+#define DMA_TX				1
+
+// #define IFB_RxFirstDesc		IFB_FirstDesc[DMA_RX]
+// #define IFB_TxFirstDesc		IFB_FirstDesc[DMA_TX]
+// #define IFB_RxLastDesc		IFB_LastDesc[DMA_RX]
+// #define IFB_TxLastDesc		IFB_LastDesc[DMA_TX]
+
+#endif // HCF_DMA
+//
+/************************************************************************************************/
+/**********************************  EQUATES  ***************************************************/
+/************************************************************************************************/
+
+
+// Hermes Command Codes and Qualifier bits
+#define 	HCMD_BUSY			0x8000	// Busy bit, applicable for all commands
+#define HCMD_INI				0x0000	//
+#define HCMD_ENABLE				HCF_CNTL_ENABLE		// 0x0001
+#define HCMD_DISABLE			HCF_CNTL_DISABLE	// 0x0002
+#define HCMD_CONNECT			HCF_CNTL_CONNECT	// 0x0003
+#define HCMD_EXECUTE			0x0004	//
+#define HCMD_DISCONNECT			HCF_CNTL_DISCONNECT	// 0x0005
+#define HCMD_SLEEP				0x0006	//
+#define HCMD_CONTINUE			HCF_CNTL_CONTINUE	// 0x0007
+#define 	HCMD_RETRY			0x0100	// Retry bit
+#define HCMD_ALLOC				0x000A	//
+#define HCMD_TX					0x000B	//
+#define 	HCMD_RECL			0x0100	// Reclaim bit, applicable for Tx and Inquire
+#define HCMD_INQUIRE			0x0011	//
+#define HCMD_ACCESS				0x0021	//
+#define 	HCMD_ACCESS_WRITE	0x0100	// Write bit
+#define HCMD_PROGRAM			0x0022	//
+#define HCMD_READ_MIF			0x0030
+#define HCMD_WRITE_MIF			0x0031
+#define HCMD_THESEUS			0x0038
+#define 	HCMD_STARTPREAMBLE  0x0E00	// Start continuous preamble Tx
+#define 	HCMD_STOP			0x0F00	// Stop Theseus test mode
+
+
+//Configuration Management
+//
+
+#define CFG_DRV_ACT_RANGES_PRI_3_BOTTOM	1	// Default Bottom Compatibility for Primary Firmware - driver I/F
+#define CFG_DRV_ACT_RANGES_PRI_3_TOP	1	// Default Top    Compatibility for Primary Firmware - driver I/F
+
+#define CFG_DRV_ACT_RANGES_HSI_4_BOTTOM	1	// Default Bottom Compatibility for H/W - driver I/F
+#define CFG_DRV_ACT_RANGES_HSI_4_TOP	1	// Default Top    Compatibility for H/W - driver I/F
+
+#define CFG_DRV_ACT_RANGES_HSI_5_BOTTOM	1	// Default Bottom Compatibility for H/W - driver I/F
+#define CFG_DRV_ACT_RANGES_HSI_5_TOP	1	// Default Top    Compatibility for H/W - driver I/F
+
+#if (HCF_TYPE) & HCF_TYPE_WPA
+#define CFG_DRV_ACT_RANGES_APF_1_BOTTOM	16	// Default Bottom Compatibility for AP Firmware - driver I/F
+#define CFG_DRV_ACT_RANGES_APF_1_TOP    16	// Default Top    Compatibility for AP Firmware - driver I/F
+#else  //;? is this REALLY O.K.
+#define CFG_DRV_ACT_RANGES_APF_1_BOTTOM	1	// Default Bottom Compatibility for AP Firmware - driver I/F
+#define CFG_DRV_ACT_RANGES_APF_1_TOP    1	// Default Top    Compatibility for AP Firmware - driver I/F
+#endif // HCF_TYPE_WPA
+
+#define CFG_DRV_ACT_RANGES_APF_2_BOTTOM	2	// Default Bottom Compatibility for AP Firmware - driver I/F
+#define CFG_DRV_ACT_RANGES_APF_2_TOP    2	// Default Top    Compatibility for AP Firmware - driver I/F
+
+#define CFG_DRV_ACT_RANGES_APF_3_BOTTOM	1	// Default Bottom Compatibility for AP Firmware - driver I/F
+#define CFG_DRV_ACT_RANGES_APF_3_TOP    1	// Default Top    Compatibility for AP Firmware - driver I/F
+
+#define CFG_DRV_ACT_RANGES_APF_4_BOTTOM	1	// Default Bottom Compatibility for AP Firmware - driver I/F
+#define CFG_DRV_ACT_RANGES_APF_4_TOP    1	// Default Top    Compatibility for AP Firmware - driver I/F
+
+#if (HCF_TYPE) & HCF_TYPE_HII5
+#define CFG_DRV_ACT_RANGES_STA_2_BOTTOM	6	// Default Bottom Compatibility for Station Firmware - driver I/F
+#define CFG_DRV_ACT_RANGES_STA_2_TOP    6	// Default Top    Compatibility for Station Firmware - driver I/F
+#else // (HCF_TYPE) & HCF_TYPE_HII5
+#define CFG_DRV_ACT_RANGES_STA_2_BOTTOM	1	// Default Bottom Compatibility for Station Firmware - driver I/F
+#define CFG_DRV_ACT_RANGES_STA_2_TOP    2	// Default Top    Compatibility for Station Firmware - driver I/F
+#endif // (HCF_TYPE) & HCF_TYPE_HII5
+
+#define CFG_DRV_ACT_RANGES_STA_3_BOTTOM	1	// Default Bottom Compatibility for Station Firmware - driver I/F
+#define CFG_DRV_ACT_RANGES_STA_3_TOP    1	// Default Top    Compatibility for Station Firmware - driver I/F
+
+#define CFG_DRV_ACT_RANGES_STA_4_BOTTOM	1	// Default Bottom Compatibility for Station Firmware - driver I/F
+#define CFG_DRV_ACT_RANGES_STA_4_TOP    1	// Default Top    Compatibility for Station Firmware - driver I/F
+
+//---------------------------------------------------------------------------------------------------------------------
+#if defined HCF_CFG_PRI_1_TOP || defined HCF_CFG_PRI_1_BOTTOM
+err: PRI_1 not supported for H-I;	// Compatibility for Primary Firmware - driver I/F
+#endif // HCF_CFG_PRI_1_TOP / HCF_CFG_PRI_1_BOTTOM
+
+#if defined HCF_CFG_PRI_2_TOP || defined HCF_CFG_PRI_2_BOTTOM
+err: PRI_2 not supported for H-I;	// Compatibility for Primary Firmware - driver I/F
+#endif // HCF_CFG_PRI_2_TOP / HCF_CFG_PRI_2_BOTTOM
+
+#ifdef HCF_CFG_PRI_3_TOP									// Top Compatibility for Primary Firmware - driver I/F
+#if HCF_CFG_PRI_3_TOP == 0 || \
+	CFG_DRV_ACT_RANGES_PRI_3_BOTTOM <= HCF_CFG_PRI_3_TOP && HCF_CFG_PRI_3_TOP <= CFG_DRV_ACT_RANGES_PRI_3_TOP
+#undef CFG_DRV_ACT_RANGES_PRI_3_TOP
+#define CFG_DRV_ACT_RANGES_PRI_3_TOP	HCF_CFG_PRI_3_TOP
+#else
+err: ;
+#endif
+#endif // HCF_CFG_PRI_3_TOP
+
+#ifdef HCF_CFG_PRI_3_BOTTOM                       			// Bottom Compatibility for Primary Firmware - driver I/F
+#if CFG_DRV_ACT_RANGES_PRI_3_BOTTOM <= HCF_CFG_PRI_3_BOTTOM && HCF_CFG_PRI_3_BOTTOM <= CFG_DRV_ACT_RANGES_PRI_3_TOP
+#undef CFG_DRV_ACT_RANGES_PRI_3_BOTTOM
+#define CFG_DRV_ACT_RANGES_PRI_3_BOTTOM	HCF_CFG_PRI_3_BOTTOM
+#else
+err: ;
+#endif
+#endif // HCF_CFG_PRI_3_BOTTOM
+
+
+//---------------------------------------------------------------------------------------------------------------------
+#if defined HCF_CFG_HSI_0_TOP || defined HCF_CFG_HSI_0_BOTTOM
+err: HSI_0 not supported for H-I;	// Compatibility for HSI I/F
+#endif // HCF_CFG_HSI_0_TOP / HCF_CFG_HSI_0_BOTTOM
+
+#if defined HCF_CFG_HSI_1_TOP || defined HCF_CFG_HSI_1_BOTTOM
+err: HSI_1 not supported for H-I;	// Compatibility for HSI I/F
+#endif // HCF_CFG_HSI_1_TOP / HCF_CFG_HSI_1_BOTTOM
+
+#if defined HCF_CFG_HSI_2_TOP || defined HCF_CFG_HSI_2_BOTTOM
+err: HSI_2 not supported for H-I;	// Compatibility for HSI I/F
+#endif // HCF_CFG_HSI_2_TOP / HCF_CFG_HSI_2_BOTTOM
+
+#if defined HCF_CFG_HSI_3_TOP || defined HCF_CFG_HSI_3_BOTTOM
+err: HSI_3 not supported for H-I;	// Compatibility for HSI I/F
+#endif // HCF_CFG_HSI_3_TOP / HCF_CFG_HSI_3_BOTTOM
+
+#ifdef HCF_CFG_HSI_4_TOP 									// Top Compatibility for HSI I/F
+#if HCF_CFG_HSI_4_TOP == 0 || \
+	CFG_DRV_ACT_RANGES_HSI_4_BOTTOM <= CF_CFG_HSI_4_TOP && HCF_CFG_HSI_4_TOP <= CFG_DRV_ACT_RANGES_HSI_4_TOP
+#undef CFG_DRV_ACT_RANGES_HSI_4_TOP
+#define CFG_DRV_ACT_RANGES_HSI_4_TOP	HCF_CFG_HSI_4_TOP
+#else
+err: ;
+#endif
+#endif // HCF_CFG_HSI_4_TOP
+
+#ifdef HCF_CFG_HSI_4_BOTTOM								// Bottom Compatibility for HSI I/F
+#if CFG_DRV_ACT_RANGES_HSI_4_BOTTOM <= HCF_CFG_HSI_4_BOTTOM && HCF_CFG_HSI_4_BOTTOM <= CFG_DRV_ACT_RANGES_HSI_4_TOP
+#undef CFG_DRV_ACT_RANGES_HSI_4_BOTTOM
+#define CFG_DRV_ACT_RANGES_HSI_4_BOTTOM	HCF_CFG_HSI_4_BOTTOM
+#else
+err: ;
+#endif
+#endif // HCF_CFG_HSI_4_BOTTOM
+
+#ifdef HCF_CFG_HSI_5_TOP 									// Top Compatibility for HSI I/F
+#if HCF_CFG_HSI_5_TOP == 0 || \
+	CFG_DRV_ACT_RANGES_HSI_5_BOTTOM <= CF_CFG_HSI_5_TOP && HCF_CFG_HSI_5_TOP <= CFG_DRV_ACT_RANGES_HSI_5_TOP
+#undef CFG_DRV_ACT_RANGES_HSI_5_TOP
+#define CFG_DRV_ACT_RANGES_HSI_5_TOP	HCF_CFG_HSI_5_TOP
+#else
+err: ;
+#endif
+#endif // HCF_CFG_HSI_5_TOP
+
+#ifdef HCF_CFG_HSI_5_BOTTOM								// Bottom Compatibility for HSI I/F
+#if CFG_DRV_ACT_RANGES_HSI_5_BOTTOM <= HCF_CFG_HSI_5_BOTTOM && HCF_CFG_HSI_5_BOTTOM <= CFG_DRV_ACT_RANGES_HSI_5_TOP
+#undef CFG_DRV_ACT_RANGES_HSI_5_BOTTOM
+#define CFG_DRV_ACT_RANGES_HSI_5_BOTTOM	HCF_CFG_HSI_5_BOTTOM
+#else
+err: ;
+#endif
+#endif // HCF_CFG_HSI_5_BOTTOM
+//---------------------------------------------------------------------------------------------------------------------
+#if defined HCF_CFG_APF_1_TOP || defined HCF_CFG_APF_1_BOTTOM
+err: APF_1 not supported for H-I;	// Compatibility for AP Firmware - driver I/F
+#endif // HCF_CFG_APF_1_TOP / HCF_CFG_APF_1_BOTTOM
+
+#ifdef HCF_CFG_APF_2_TOP                  					// Top Compatibility for AP Firmware - driver I/F
+#if HCF_CFG_APF_2_TOP == 0 || \
+	CFG_DRV_ACT_RANGES_APF_2_BOTTOM <= HCF_CFG_APF_2_TOP && HCF_CFG_APF_2_TOP <= CFG_DRV_ACT_RANGES_APF_2_TOP
+#undef CFG_DRV_ACT_RANGES_APF_2_TOP
+#define CFG_DRV_ACT_RANGES_APF_2_TOP	HCF_CFG_APF_2_TOP
+#else
+err: ;
+#endif
+#endif // HCF_CFG_APF_TOP
+
+#ifdef HCF_CFG_APF_2_BOTTOM                       			// Bottom Compatibility for AP Firmware - driver I/F
+#if CFG_DRV_ACT_RANGES_APF_2_BOTTOM <= HCF_CFG_APF_2_BOTTOM && HCF_CFG_APF_2_BOTTOM <= CFG_DRV_ACT_RANGES_APF_2_TOP
+#undef CFG_DRV_ACT_RANGES_APF_2_BOTTOM
+#define CFG_DRV_ACT_RANGES_APF_2_BOTTOM	HCF_CFG_APF_2_BOTTOM
+#else
+err: ;
+#endif
+#endif // HCF_CFG_APF_BOTTOM
+
+//---------------------------------------------------------------------------------------------------------------------
+#if defined HCF_CFG_STA_1_TOP || defined HCF_CFG_STA_1_BOTTOM
+err: STA_1 not supported for H-I;	// Compatibility for Station Firmware - driver I/F
+#endif // HCF_CFG_STA_1_TOP / HCF_CFG_STA_1_BOTTOM
+
+#ifdef HCF_CFG_STA_2_TOP                  					// Top Compatibility for Station Firmware - driver I/F
+#if HCF_CFG_STA_2_TOP == 0 || \
+	CFG_DRV_ACT_RANGES_STA_2_BOTTOM <= HCF_CFG_STA_2_TOP && HCF_CFG_STA_2_TOP <= CFG_DRV_ACT_RANGES_STA_2_TOP
+#undef CFG_DRV_ACT_RANGES_STA_2_TOP
+#define CFG_DRV_ACT_RANGES_STA_2_TOP	HCF_CFG_STA_2_TOP
+#else
+err: ;
+#endif
+#endif // HCF_CFG_STA_TOP
+
+#ifdef HCF_CFG_STA_2_BOTTOM                       			// Bottom Compatibility for Station Firmware - driver I/F
+#if CFG_DRV_ACT_RANGES_STA_2_BOTTOM <= HCF_CFG_STA_2_BOTTOM && HCF_CFG_STA_2_BOTTOM <= CFG_DRV_ACT_RANGES_STA_2_TOP
+#undef CFG_DRV_ACT_RANGES_STA_2_BOTTOM
+#define CFG_DRV_ACT_RANGES_STA_2_BOTTOM	HCF_CFG_STA_2_BOTTOM
+#else
+err: ;
+#endif
+#endif // HCF_CFG_STA_BOTTOM
+
+
+/************************************************************************************************/
+/**************************************  MACROS  ************************************************/
+/************************************************************************************************/
+
+/* min and max macros */
+#if ! defined max
+#define max(a,b)  		(((a) > (b)) ? (a) : (b))
+#endif
+#if ! defined min
+#define min(a,b)  		(((a) < (b)) ? (a) : (b))
+#endif
+
+#ifdef HCF_SLEEP
+#if defined MSF_WAIT
+err: MSF should no longer supply this macro;
+#else
+#define MSF_WAIT(x) 																			\
+	{ PROT_CNT_INI														\
+		HCF_WAIT_WHILE( ( IPW( HREG_IO ) & HREG_IO_WOKEN_UP ) == 0 );						\
+		HCFASSERT( prot_cnt, IPW( HREG_IO ) )							\
+	}
+#endif // MSF_WAIT
+#else
+#define MSF_WAIT(x)	/*NOP*/
+#endif // HCF_SLEEP
+
+#define LOF(x) 			(sizeof(x)/sizeof(hcf_16)-1)
+
+#define MUL_BY_2( x )	( (x) << 1 )						//used to multiply by 2
+#define DIV_BY_2( x )	( (x) >> 1 )						//used to divide by 2
+
+//resolve problems on for some 16 bits compilers to create 32 bit values
+#define MERGE_2( hw, lw )	( ( ((hcf_32)(hw)) << 16 ) | ((hcf_16)(lw)) )
+
+#if ! defined HCF_STATIC
+#define		  HCF_STATIC	static
+#endif //	  HCF_STATIC
+
+#if ( (HCF_TYPE) & HCF_TYPE_HII5 ) == 0
+#define DAWA_ACK( mask) {													\
+	OPW( HREG_EV_ACK, mask | HREG_EV_ACK_REG_READY );						\
+	OPW( HREG_EV_ACK, (mask & ~HREG_EV_ALLOC) | HREG_EV_ACK_REG_READY ); 	}
+#define DAWA_ZERO_FID(reg) OPW( reg, 0 );
+#else
+#define DAWA_ACK( mask)   OPW( HREG_EV_ACK, mask );
+#define DAWA_ZERO_FID(reg)
+#endif // HCF_TYPE_HII5
+
+#if (HCF_TYPE) & HCF_TYPE_WPA
+#define	CALC_RX_MIC( p, len ) calc_mic_rx_frag( ifbp, p, len )
+#define	CALC_TX_MIC( p, len ) calc_mic_tx_frag( ifbp, p, len )
+#define IF_SSN(x)  x
+#define IF_NOT_SSN(x)
+#else
+#define	CALC_RX_MIC( p, len )
+#define	CALC_TX_MIC( p, len )
+#define MIC_RX_RTN( mic, dw )
+#define MIC_TX_RTN( mic, dw )
+#define IF_SSN(x)
+#define IF_NOT_SSN(x) x
+#endif // HCF_TYPE_WPA
+
+#if HCF_TALLIES & HCF_TALLIES_HCF		//HCF tally support
+#define IF_TALLY(x)  x
+#else
+#define IF_TALLY(x)
+#endif // HCF_TALLIES_HCF
+
+
+#if HCF_DMA
+#define IF_DMA(x)			x
+#define IF_NOT_DMA(x)
+#define IF_USE_DMA(x) 		if (   ifbp->IFB_CntlOpt & USE_DMA  ) x
+#define IF_NOT_USE_DMA(x)	if ( !(ifbp->IFB_CntlOpt & USE_DMA) ) x
+#else
+#define IF_DMA(x)
+#define IF_NOT_DMA(x)		x
+#define IF_USE_DMA(x)
+#define IF_NOT_USE_DMA(x) 	x
+#endif // HCF_DMA
+
+
+#define IPW(x) ((hcf_16)IN_PORT_WORD( ifbp->IFB_IOBase + (x) ) )
+#define OPW(x, y) OUT_PORT_WORD( ifbp->IFB_IOBase + (x), y )
+	/* make sure the implementation of HCF_WAIT_WHILE is such that there may be multiple HCF_WAIT_WHILE calls
+	 * in a row and that when one fails all subsequent fail immediately without reinitialization of prot_cnt
+	 */
+#if HCF_PROT_TIME == 0
+#define PROT_CNT_INI
+#define IF_PROT_TIME(x)
+#if defined HCF_YIELD
+#define HCF_WAIT_WHILE( x ) while ( (x) && (HCF_YIELD) ) /*NOP*/;
+#else
+#define HCF_WAIT_WHILE( x ) while ( x ) /*NOP*/;
+#endif // HCF_YIELD
+#else
+#define PROT_CNT_INI 	hcf_32 prot_cnt = ifbp->IFB_TickIni;
+#define IF_PROT_TIME(x)	x
+#if defined HCF_YIELD
+#define HCF_WAIT_WHILE( x ) while ( prot_cnt && (x) && (HCF_YIELD) ) prot_cnt--;
+#else
+#include <linux/delay.h>
+#define HCF_WAIT_WHILE( x ) while ( prot_cnt && (x) ) { udelay(2); prot_cnt--; }
+#endif // HCF_YIELD
+#endif // HCF_PROT_TIME
+
+#if defined HCF_EX_INT
+//#if HCF_EX_INT & ~( HCF_EX_INT_TX_EX | HCF_EX_INT_TX_OK | HCF_EX_INT_TICK )
+;? out dated checking
+err: you used an invalid bitmask;
+// #endif // HCF_EX_INT validation
+// #else
+// #define HCF_EX_INT 0x000
+#endif // HCF_EX_INT
+
+#if 0 //get compiler going
+#if HCF_EX_INT_TICK	!= HREG_EV_TICK
+;? out dated checking
+err: someone redefined these macros while the implemenation assumes they are equal;
+#endif
+#if HCF_EX_INT_TX_OK != HFS_TX_CNTL_TX_OK || HFS_TX_CNTL_TX_OK != HREG_EV_TX_OK
+;? out dated checking
+err: someone redefined these macros while the implemenation assumes they are equal;
+#endif
+#if HCF_EX_INT_TX_EX != HFS_TX_CNTL_TX_EX || HFS_TX_CNTL_TX_EX != HREG_EV_TX_EX
+;? out dated checking
+err: someone redefined these macros while the implemenation assumes they are equal;
+#endif
+#endif // 0 get compiler going
+
+
+/* The assert in HCFLOGENTRY checks against re-entrancy. Re-entrancy could be caused by MSF logic at
+ * task-level calling hcf_functions without shielding with HCF_ACT_ON/_OFF. When an interrupt occurs,
+ * the ISR could (either directly or indirectly) cause re-entering of the interrupted HCF-routine.
+ *
+ * The "(ifbp->IFB_AssertWhere = where)" test in HCFLOGENTRY services ALSO as a statement to get around:
+ * #pragma warning: conditional expression is constant
+ * on the if-statement
+ */
+#if HCF_ASSERT
+#define HCFASSERT(x,q) {if (!(x)) {mdd_assert(        ifbp, __LINE__                   , q );}}
+#define MMDASSERT(x,q) {if (!(x)) {mdd_assert( assert_ifbp, __LINE__ + FILE_NAME_OFFSET, q );}}
+
+#define HCFLOGENTRY( where, what ) 														\
+{if ( (ifbp->IFB_AssertWhere = where) <= 15 ) {											\
+	HCF_ENTRY( ifbp ); 																	\
+	HCFASSERT( (ifbp->IFB_AssertTrace & 1<<((where)&0xF)) == 0, ifbp->IFB_AssertTrace );		\
+	ifbp->IFB_AssertTrace |= 1<<((where)&0xF);												\
+	}																					\
+HCFTRACE(ifbp, where )																	\
+HCFTRACEVALUE(ifbp, what )																\
+}
+
+#define HCFLOGEXIT( where ) 															\
+{if ( (ifbp->IFB_AssertWhere = where) <= 15 ) {											\
+  	HCF_EXIT( ifbp ); 																	\
+	ifbp->IFB_AssertTrace &= ~(1<<((where)&0xF));												\
+	}						 															\
+HCFTRACE(ifbp, (where)|HCF_TRACE_EXIT )													\
+}
+
+#else // HCF_ASSERT
+#define HCFASSERT( x, q )
+#define MMDASSERT( x, q )
+#define HCFLOGENTRY( where, what ) 	  	{HCF_ENTRY( ifbp );}
+#define HCFLOGEXIT( where ) 		  	{HCF_EXIT( ifbp );}
+#endif // HCF_ASSERT
+
+#if HCF_INT_ON
+/* ;? HCFASSERT_INT
+ * #if (HCF_SLEEP) & HCF_DDS
+ * #define HCFASSERT_INT HCFASSERT( ifbp->IFB_IntOffCnt != 0xFFFF && ifbp->IFB_IntOffCnt != 0xFFFE, \
+ * 								 ifbp->IFB_IntOffCnt )
+ * #else
+ */
+#define HCFASSERT_INT HCFASSERT( ifbp->IFB_IntOffCnt != 0xFFFF, ifbp->IFB_IntOffCnt )
+// #endif // HCF_DDS
+#else
+#define HCFASSERT_INT
+#endif // HCF_INT_ON
+
+
+#if defined HCF_TRACE
+#define HCFTRACE(ifbp, where )	   {OPW( HREG_SW_1, where );}
+//#define HCFTRACE(ifbp, where )	   {HCFASSERT( DO_ASSERT, where );}
+#define HCFTRACEVALUE(ifbp, what ) {OPW( HREG_SW_2, what  );}
+//#define HCFTRACEVALUE(ifbp, what ) {HCFASSERT( DO_ASSERT, what  );}
+#else
+#define HCFTRACE(ifbp, where )
+#define HCFTRACEVALUE(ifbp, what )
+#endif // HCF_TRACE
+
+
+#if HCF_BIG_ENDIAN
+#define BE_PAR(x)				,x
+#else
+#define BE_PAR(x)
+#endif // HCF_BIG_ENDIAN
+
+/************************************************************************************************/
+/**************************************  END OF MACROS  *****************************************/
+/************************************************************************************************/
+
+/************************************************************************************************/
+/***************************************  PROTOTYPES  *******************************************/
+/************************************************************************************************/
+
+#if HCF_ASSERT
+extern IFBP BASED assert_ifbp;			//to make asserts easily work under MMD and DHF
+EXTERN_C void		 mdd_assert			(IFBP ifbp, unsigned int line_number, hcf_32 q );
+#endif //HCF_ASSERT
+
+#if ! ( (HCF_IO) & HCF_IO_32BITS )				// defined 16 bits only
+#undef OUT_PORT_STRING_32
+#undef IN_PORT_STRING_32
+#endif // HCF_IO
+#endif	//HCFDEFC_H
+
diff --git a/drivers/staging/wlags49_h2/man/wlags49.4 b/drivers/staging/wlags49_h2/man/wlags49.4
new file mode 100644
index 0000000..a345885
--- /dev/null
+++ b/drivers/staging/wlags49_h2/man/wlags49.4
@@ -0,0 +1,734 @@
+.\" vim:tw=78:
+.\" Copyright (c) 1999-2003 Agere Systems Inc. -- http://www.agere.com
+.\" wlags49.4 7.20-abg 04/28/2004 13:30:00
+.\"
+.TH WLAGS49 4 "04/28/2004 13:30:00" "pcmcia-cs"
+.SH NAME
+wlags49 \- Agere Systems Wireless PC Card / PCI device drivers
+
+wlags49_h2_cs.o \- Hermes-II Card Services (PCMCIA/CF) driver
+.br
+wlags49_h2.o    \- Hermes-II MiniPCI driver
+.br
+wlags49_h25.o   \- Hermes-II.5 PCI/CardBus driver
+.br
+wlags49_h25_cs.o\- Hermes-II.5 Card Services (PCMCIA/CF) driver
+
+.SH SYNOPSIS
+.nh
+.fi
+.B insmod wlags49_[h1,h2]_[cs].o
+.br
+.RB [ Authentication=n ]
+.RB [ AuthKeyMngmtSuite=???? ]
+.RB [ BRSC2GHz=b ]\p
+.RB [ BRSC5GHz=b ]
+.RB [ Coexistence=n ]
+.RB [ Configured=???? ]\p
+.RB [ ConnectionControl=???? ]
+.RB [ CreateIBSS=s ]
+.RB [ DebugFlag=n ]\p
+.RB [ DesiredSSID=s ]
+.RB [ DownloadFirmware=n ]
+.RB [ DriverEnable=???? ]\p
+.RB [ EnableEncryption=s ]
+.RB [ Encryption=???? ]
+.RB [ ExcludeUnencrypted=s ]\p
+.RB [ IntraBSSRelay=s ]
+.RB [ IrqList=i,j,... ]
+.RB [ IrqMask=n ]\p
+.RB [ Key1=s ]
+.RB [ Key2=s ]
+.RB [ Key3=s ]
+.RB [ Key4=s ]\p
+.RB [ LoadBalancing=s ]
+.RB [ MaxSleepDuration=n ]
+.RB [ MediumDistribution=s ]\p
+.RB [ MicroWaveRobustness=s ]
+.RB [ MulticastPMBuffering=s ]
+.RB [ MulticastRate=n ]\p
+.RB [ MulticastReceive=s ]
+.RB [ NetworkAddress=n,n,n,n,n,n ]
+.RB [ NetworkType=???? ]\p
+.RB [ OwnATIMWindow=n ]
+.RB [ OwnBeaconInterval=n ]
+.RB [ OwnChannel=n ]\p
+.RB [ OwnDTIMPeriod=n ]
+.RB [ OwnName=s ]
+.RB [ OwnSSID=s ]\p
+.RB [ pc_debug=n ]
+.RB [ PMEnabled=b ]
+.RB [ PMHoldoverDuration=n ]\p
+.RB [ PortType=n ]
+.RB [ PowerMode=???? ]
+.RB [ PromiscuousMode=s ]\p
+.RB [ RejectANY=s ]
+.RB [ RTSThreshold=n ]\p
+.RB [ RTSThreshold1=n ]
+.RB [ RTSThreshold2=n ]
+.RB [ RTSThreshold3=n ]\p
+.RB [ RTSThreshold4=n ]
+.RB [ RTSThreshold5=n ]
+.RB [ RTSThreshold6=n ]\p
+.RB [ SRSC2GHz=b ]
+.RB [ SRSC5GHz=b ]
+.RB [ SystemScale=n ]\p
+.RB [ TxKey=n ]
+.RB [ TxRateControl=n ]\p
+.RB [ TxRateControl1=n ]
+.RB [ TxRateControl2=n ]
+.RB [ TxRateControl3=n ]\p
+.RB [ TxRateControl4=n ]
+.RB [ TxRateControl5=n ]
+.RB [ TxRateControl6=n ]\p
+.RB [ WDSAddress=n,n,n,n,n,n ]\p
+.RB [ WDSAddress1=n,n,n,n,n,n ]
+.RB [ WDSAddress2=n,n,n,n,n,n ]\p
+.RB [ WDSAddress3=n,n,n,n,n,n ]
+.RB [ WDSAddress4=n,n,n,n,n,n ]\p
+.RB [ WDSAddress5=n,n,n,n,n,n ]
+.RB [ WDSAddress6=n,n,n,n,n,n ]\p
+.fi
+
+
+
+.SH DESCRIPTION
+.I wlags49
+is the low-level Card Services / PCI driver for the
+.B Wireless PC Card, Wireless Integrated Card, Wireless Embedded Card
+and other wireless adapters based on the Agere Systems Hermes-II, and Hermes-II.5 wireless MAC. When this driver is attached to a card, it
+allocates the next available ethernet device (eth0..eth#). This
+device name will be passed on to
+.IR cardmgr (8),
+or the PCI subsystem, for the card configuration, and reported in the kernel log file
+with the I/O base address and MAC address used by the card.
+.SH FEATURES
+ \- Hot plug/unplug
+ \- Access Point and peer-to-peer communication
+ \- Card power management
+ \- Support for Hermes-II & Hermes-II.5 based PCMCIA, Mini PCI, and CardBus cards
+ \- Wired Equivalent Privacy (WEP)
+ \- WPA-PSK support (EXPERIMENTAL)
+ \- Driver utility interface (UIL)
+ \- Wireless Extensions
+ \- Software AP mode
+.SH PARAMETERS
+.TP
+.B Authentication=n
+Algorithm used for Authentication.
+.BR
+    1 \- Open System
+.BR
+    2 \- Shared Key
+.BR
+    Default: 1
+.TP
+.B Auth_key_mgmt_suite
+???????????????
+.TP
+.B BRSC2GHz=b
+Sets the card\'s Basic Rate Set in the 2.4GHz band. See SRSC2GHz
+for the value\'s format.
+.BR
+    Default: 15 (or 0x000F, only 11b rates to accept legacy 11b stations)
+.TP
+.B BRSC5GHz-b
+Sets the card\'s Basic Rate Set in the 5.0GHz band. See SRSC2GHz for the
+value\'s format
+.BR
+    Default: 4080 (or 0x0FF0, all 11a rates)
+.TP
+.B Coexistence=n
+Used to make the 802.11a/b/g coexistence behavior more strict.
+.BR
+    Default \- 0 (Use standard behavior)
+.TP
+.B ConnectionControl=n
+Configures the card\'s connection control process in dealing with multiple
+bands (802.11b/g vs. 802.11a).
+.BR
+    0 \- Single Band operation in 2GHz
+.BR
+    1 \- Single Band operation in 5GHz
+.BR
+    2 \- Multiple Band operation starting with 2GHz
+.BR
+    3 \- Multiple Band operation starting with 5GHz
+.BR
+    Default \- 2
+.TP
+.B Configured
+???????????????
+.TP
+.B ConnectionControl
+???????????????
+.TP
+.B CreateIBSS=s
+Enable or disable IBSS Creation.
+For correct operation, specification of a OwnSSID is required.
+This mode requires firmware 6.04 or higher.
+.BR
+    N \- Disable
+.BR
+    Y \- Enable
+.BR
+    Default: N
+.TP
+.B DebugFlag=n
+Selects the driver debugging level. This parameter is only available
+if the module is compiled with debugging enabled. Refer to the
+file
+.B debug.h
+in the source directory for information on the flag values.
+.BR
+    0x00000001L \- DBG_ERROR_ON
+.BR
+    0x00000002L \- DBG_WARNING_ON
+.BR
+    0x00000004L \- DBG_NOTICE_ON
+.BR
+    0x00000008L \- DBG_TRACE_ON
+.BR
+    0x00000010L \- DBG_VERBOSE_ON
+.BR
+    0x00000020L \- DBG_PARAM_ON
+.BR
+    0x00000040L \- DBG_BREAK_ON
+.BR
+    0x00000100L \- DBG_RX_ON
+.BR
+    0x00000200L \- DBG_TX_ON
+.BR
+    0x00000400L \- DBG_DS_ON
+.BR
+If the module is compiled with debugging enabled, DebugFlag
+defaults to DBG_ERROR_ON, DBG_WARNING_ON and DBG_BREAK_ON.
+DebugFlag overrules pc_debug.
+.TP
+.B DesiredSSID=s
+Same as OwnSSID.
+.TP
+.B DownloadFirmware=n
+This release of the driver introduces the ability to perform downloads of the STA/AP
+firmware. In fact, this is required for Hermes-II based cards. This parameter tells
+the driver which version of the firmware to download to the card.
+.BR
+    0 \- No download performed (Hermes-I only)
+.BR
+    1 \- Download STA firmware
+.BR
+    2 \- Download AP firmware
+.BR
+    Default: 1, when STA mode functionality is
+                included in the build
+             2, when code is built exclusively for
+                AP mode
+.TP
+.B DriverEnable
+???????????????
+.TP
+.B EnableEncryption=n
+Set the method of Data encryption.
+.BR
+    0 \- Disable
+.BR
+    1 \- Enable WEP Encryption
+.BR
+    2 \- Enable WPA with TKIP encryption
+.BR
+    Default: 0
+.TP
+.B Encryption
+???????????????
+.TP
+.B ExcludeUnencrypted=s
+Controls how the stations must communicate with the AP.
+.BR
+    Y \- Stations must enable encryption and provide
+         the proper encryption key to communicate
+         with the AP.
+.BR
+    N \- Stations do not need to enable encryption
+         to communicate with the AP.
+.BR
+    Default: N
+.TP
+.B IntraBSSRelay=s
+Controls the automatic relay of received messages that are destined for other
+stations in the BSS.
+.BR
+    Y \- Messages are relayed to the appropriate
+         station(s).
+.BR
+    N \- Messages are passed up to the host.
+.BR
+    Default: Y
+.TP
+.B IrqList=i,j,...
+Specifies the set of interrupts (up to 4) that may be allocated by
+this driver. This overrides the values set in the
+.B IrqMask
+parameter. NOTE: This parameter is for PCMCIA only.
+.TP
+.B IrqMask=n
+Specifies a mask of valid interrupts that may be allocated by this driver.
+If
+.B IrqList
+is also specified, the values in
+.B IrqList
+are used instead. NOTE: This parameter is for PCMCIA only.
+.BR
+    Default: 0xdeb8 (IRQ 3,4,5,7,9,10,11,12,14,15)
+.TP
+.B Key1=s
+Specifies one of 4 possible keys for the Data encryption.
+One of these keys, identified by TxKey,
+is used for the enciphering of Data that is transmitted by this station.
+All keys specified can be used for the deciphering of Data that is received.
+.BR
+The key value can be an ASCII character string or a hexadecimal value.
+The length of the key value can be 5 characters or 10 hexadecimal digits for
+the standard encryption (Silver or Gold card), or 13 characters or 26
+hexadecimal digits for the encryption with extended keys (Gold card only).
+The keys defined in the station must match the keys defined in the access
+points; both on value and number (1 through 4).
+.BR
+In 2.0 series Linux kernel modules, values that begin with a number are
+considered integers. In this case a hexadecimal value string or a character
+string starting with a number, will need to be surrounded by escaped
+double quotes (ie. Key1=\\"0x1122334455\\" Key2=\\"12xyz\\").
+.BR
+    5 or 13, printable character string, or
+.BR
+    10 or 26 hex digits if preceded by "0x".
+.BR
+    If this parameter is omitted, the default of the MAC is used ( = 0-length).
+.TP
+.B Key2=s
+Same as Key1.
+.TP
+.B Key3=s
+Same as Key1.
+.TP
+.B Key4=s
+Same as Key1.
+.TP
+.B LoadBalancing=s
+Control for the Load Balancing algorithm for both STAs and APs. The AP
+includes a load balancing element in the Probe Response and Beacon frames.
+The STA uses this info to select an AP, not only based on comms quality, but
+also on the load of that AP.
+.BR
+    Default: Y
+.TP
+.B MaxDataLength
+???????????????
+.TP
+.B MaxSleepDuration=n
+Set the maximum Power Management sleep duration in milliseconds.
+Valid values are 0 to 65535 milliseconds.
+.BR
+    Default: 100
+.TP
+.B MediumDistribution=s
+Control for the distribution of medium parameters, like communication
+thresholds, microwave robustness, RTS/CTS thresholds, by APs. The associated
+stations replace their own values with the received values.
+.BR
+    Default=Y
+.TP
+.B MicroWaveRobustness=s
+Enable or disable Microwave Oven Robustness.
+.BR
+    N \- Disable
+.BR
+    Y \- Enable
+.BR
+    Default: N
+.TP
+.B MulticastPMBuffering=s
+Controls buffering of multicast MAC frames for transmission after DTIM. If no,
+multicast MAC frames are directly placed in the output queue.
+.BR
+    Default: Y
+.TP
+.B MulticastRate=n
+Sets the data rate for multicast message transmission.
+.BR
+    1 \- Fixed 1Mb/s
+    2 \- Fixed 2Mb/s
+    3 \- Fixed 5.5Mb/s
+    4 \- Fixed 11Mb/s
+.BR
+    Default: 2
+
+For Hermes-II.5, an INTEGER CONVERTED bit mask representing the
+rate to multicast, where the rates supported are as follows:
+
+Bit  : 15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00
+.br
+------------------------------------------------------
+.br
+Rate : XX|XX|XX|XX|54|48|36|24|18|12| 9| 6|11|5.5|2| 1
+
+    Default: 4 (Translates to 0x0004 = 5.5 Mb/sec)
+
+.TP
+.B MulticastReceive=s
+Enable or disable receiving of all multicast packets when Card Power Management
+is enabled. When enabled, the station will wake up frequently
+to receive the multicast frames. This causes less optimal power savings.
+.BR
+    N \- Disable
+.BR
+    Y \- Enable
+.BR
+    Default: Y
+.TP
+.B NetworkAddress=n,n,n,n,n,n
+Sets the adapter hardware ethernet address (MAC address) to the value
+specified. Note that this is to be used to specify a Local MAC address. Do
+not specify this parameter if the card\'s universal address is to be used.
+Valid values are six hexadecimal digit-pairs (prefixed with 0x).
+.BR
+    Default: <factory assigned address>
+.TP
+.B NetworkType
+???????????????
+.TP
+.B OwnATIMWindow=n
+ATIM window time used for creating an IBSS.
+.BR
+    Range: 0..100
+.BR
+    Default: 0
+.TP
+.B OwnBeaconInterval=b
+Beacon Interval in TU
+.BR
+    Range 20..200
+.BR
+    Default \- 100
+.TP
+.B channel=n
+Same as OwnChannel.
+.TP
+.B OwnChannel=n
+Sets the channel the Ad-Hoc or IBSS mode will use.
+The default channel for Ad-Hoc mode is determined by the Wireless PC Card.
+The default channel for IBSS is set to 10 by the driver.
+This value has no effect when the adapter is used with an Access Point
+(BSS network) since the Access Point automatically determines the channel.
+Valid values are 0 to 14. However the channels allowed in
+your region are subject to local regulations and are limited at
+manufacturing time of the Wireless PC Card. When the provided value is
+not allowed, the value remains unchanged.
+.BR
+    0 \- Use default channel
+.BR
+    Default: 0
+.TP
+.B OwnDTIMPeriod=n
+The number of beacon intervals between successive Delivery Traffic Identification
+Maps (DTIMs).
+.BR
+    Range: 1..65535
+.BR
+    Default: 1
+.TP
+.B OwnName=s
+Sets the station name to the specified string value. This parameter
+is used for diagnostic purposes, as a user\-friendly identification
+of this system. This parameter accepts a maximum of 32 characters.
+.BR
+    Default: Linux
+.TP
+.B OwnSSID=s
+Sets the card network name to the specified string value. This parameter
+accepts a maximum of 32 characters. Whitespace in the network name
+will need to be escaped with a backslash (ie. OwnSSID=My\\ Network).
+.BR
+    Default: ANY
+.TP
+.B pc_debug=n
+Selects the PCMCIA debugging level. This parameter is only available
+if the module is compiled with debugging enabled. A non\-zero value
+enables debugging. Higher values yield more information, i.e. for any value all
+lower values are implied.
+.BR
+    8 \- DBG_DS_ON
+.BR
+    7 \- DBG_RX_ON | DBG_TX_ON
+.BR
+    6 \- DBG_PARAM_ON
+.BR
+    5 \- DBG_TRACE_ON
+.BR
+    4 \- DBG_VERBOSE_ON
+.BR
+If the module is compiled with debugging enabled, pc_debug defaults to 5.
+DebugFlag overrules pc_debug.
+.BR
+The name pc_debug rather than PcDebug, since pc_debug is used by many PCMCIA driver.
+.TP
+.B PMEnabled=b
+Sets the card\'s Power Management state.
+.BR
+    0 \- Disable
+.BR
+    1 \- Enable Enhanced Mode
+.BR
+    2 \- Enabled Standard Mode
+.BR
+    0x8000 \- Enhanced?????? Mode (to be combined with 0x0001 or 0x0002)
+
+    Default: 0 (Disabled)
+.TP
+.B PMHoldoverDuration=n
+Time that the station remains in an awake state after a MAC frame transfer if
+Enhanced Power Save is active.
+.BR
+    Range: 1..1000
+.BR
+    Default: 100
+.TP
+.B PowerMode
+???????????????
+.TP
+.B PortType=n
+Selects the type of network operation.
+.BR
+    1 \- Normal Operation (BSS or IBSS)
+.BR
+    3 \- Ad-Hoc Demo Mode
+.BR
+    Default: 1
+.TP
+.B PromiscuousMode=s
+Switch for promiscuous mode reception.
+.BR
+    Default: N
+.TP
+.B RejectANY=s
+Controls how stations associate to the device.
+.BR
+    Y \- Stations must provide the correct SSID to
+         associate to the AP.
+.BR
+    N \- Stations are not required to provide the
+         correct SSID to associate to the AP.
+         Known as an \'open\' network.
+.BR
+    Default - N
+.TP
+.B RTSThreshold=n
+Controls the RTS/CTS handshake threshold for transmissions in Station mode.
+Valid values are 0 to 2347.
+.BR
+    500  \- Hidden Stations
+.BR
+    2347 \- No RTS/CTS
+.BR
+    Default: 2347
+.TP
+.B RTSThreshold1=n
+Same as RTSThreshold, only for port 1 of in AccessPoint mode.
+.TP
+.B RTSThreshold2=n
+Same as RTSThreshold1, only for port 2.
+.TP
+.B RTSThreshold3=n
+Same as RTSThreshold1, only for port 3.
+.TP
+.B RTSThreshold4=n
+Same as RTSThreshold1, only for port 4.
+.TP
+.B RTSThreshold5=n
+Same as RTSThreshold1, only for port 5.
+.TP
+.B RTSThreshold6=n
+Same as RTSThreshold1, only for port 6.
+.TP
+.B SRSC2GHz=b
+Sets the card\'s Supported Rate Set in the 2.4GHz band. The value
+is an INTEGER CONVERTED bit mask representing the rates to support,
+where the rates supported are as follows:
+
+Bit  : 15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00
+.br
+------------------------------------------------------
+.br
+Rate : XX|XX|XX|XX|54|48|36|24|18|12| 9| 6|11|5.5|2| 1
+.BR
+    Default: 4095 (or 0x0FFF, all 11b and 11g rates)
+.TP
+.B SRSC5GHz=b
+Sets the card\'s Supported Rate Set in the 5.0GHz band. See SRSC2GHz
+for the value\'s format.
+.BR
+    Default: 4080 (or 0x0FF0, all 11a rates)
+.TP
+.B SystemScale=n
+Sets the distance between Access Points in the network. This value
+influences the Modem Thresholds (EnergyDetectThreshold,
+CarrierDetectThreshold and DeferThreshold) and
+the Roaming Thresholds (CellSearchThreshold and OutOfRangeThreshold).
+.BR
+    1 \- Large
+.BR
+    2 \- Medium
+.BR
+    3 \- Small
+.BR
+    Default: 1
+.TP
+.B TxRateControl=n
+Sets the data rate to be used by the transmitter. For Hermes-II:
+.BR
+    1 \- Fixed Low (1 Mb/sec)
+.BR
+    2 \- Fixed Standard (2 Mb/sec)
+.BR
+    3 \- Auto Rate Select High (11, 5.5, 2, 1 Mb/sec)
+.BR
+    4 \- Fixed Medium (5.5 Mb/sec)
+.BR
+    5 \- Fixed High (11 Mb/sec)
+.BR
+    6 \- Auto Rate Select Standard (2, 1 Mb/sec)
+.BR
+    7 \- Auto Rate Select Medium (5.5, 2, 1 Mb/sec)
+.BR
+    Default: 3
+
+For Hermes-II.5, an INTEGER CONVERTED bit mask representing all of the
+rates to support, where the rates supported are as follows:
+
+Bit  : 15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00
+.br
+------------------------------------------------------
+.br
+Rate : XX|XX|XX|XX|54|48|36|24|18|12| 9| 6|11|5.5|2| 1
+.BR
+    Default: 4095 (Translates to 0xFFF, which is all rates)
+.TP
+.B RTSThreshold=n
+Sets the number of octets in a message or fragment above which a
+RTS/CTS handshake is performed.
+Valid values are 0 to 2347.
+.BR
+    500  \- Hidden Stations
+.BR
+    2347 \- No RTS/CTS
+.BR
+    Default: 2347
+.TP
+.B TxKey=n
+Designates which of the keys is to be used for the enciphering of data that is
+transmitted by this station.
+.BR
+    Integer in the range 1..4.
+.BR
+    Default: 1
+.TP
+.B TxPowLevel
+???????????????
+.TP
+.B TxRateControl=n
+Sets the data rate to be used by the transmitter in Station mode.
+.BR
+    1 \- Fixed Low
+.BR
+    2 \- Fixed Standard
+.BR
+    3 \- Auto Rate Select (High)
+.BR
+    4 \- Fixed Medium
+.BR
+    5 \- Fixed High
+.BR
+    6 \- Auto Rate Select (Standard)
+.BR
+    7 \- Auto Rate Select (Medium)
+.BR
+    Default: 3
+
+For Hermes-II.5, an INTEGER CONVERTED bit mask representing all of the
+rates to support, where the rates supported are as follows:
+
+Bit  : 15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00
+.br
+------------------------------------------------------
+.br
+Rate : XX|XX|XX|XX|54|48|36|24|18|12| 9| 6|11|5.5|2| 1
+.BR
+    Default: 4095 (Translates to 0xFFF, which is all rates)
+
+.TP
+.B TxRateControl1=n
+Same as TxRateControl, only for port 1 in AccessPoint mode.
+.TP
+.B TxRateControl2=n
+Same as TxRateControl1, only for port 2.
+.TP
+.B TxRateControl3=n
+Same as TxRateControl1, only for port 3.
+.TP
+.B TxRateControl4=n
+Same as TxRateControl1, only for port 4.
+.TP
+.B TxRateControl5=n
+Same as TxRateControl1, only for port 5.
+.TP
+.B TxRateControl6=n
+Same as TxRateControl1, only for port 6.
+.TP
+.B VendorDescription
+???????????????
+.TP
+.B WDSAddress=n,n,n,n,n,n
+MAC address that identifies the corresponding node of the WDS port in Station mode.
+Note that for WDS to work properly, a bridge interface must be setup between the device and
+the wds network devices created by the driver. For more information on bridge
+interfaces, please refer to the man page for \'brctl\'.
+.BR
+    Default: 00:00:00:00:00:00
+.TP
+.B WDSAddress1=n,n,n,n,n,n
+Same as WDSAddress, only for port 1 in AccessPoint mode.
+.TP
+.B WDSAddress2=n,n,n,n,n,n
+Same as WDSAddress1, only for port 2.
+.TP
+.B WDSAddress3=n,n,n,n,n,n
+Same as WDSAddress1, only for port 3.
+.TP
+.B WDSAddress4=n,n,n,n,n,n
+Same as WDSAddress1, only for port 4.
+.TP
+.B WDSAddress5=n,n,n,n,n,n
+Same as WDSAddress1, only for port 5.
+.TP
+.B WDSAddress6=n,n,n,n,n,n
+Same as WDSAddress1, only for port 6.
+.SH SECURITY
+On a multi-user system only the system administrator needs access to the WEP
+encryption keys. In this case, consider removing the read permission for
+normal users of the PCMCIA config.opts file, the system log file, and any
+Agere proprietary iwconfig-eth<n> scripts.
+.SH CONTACT
+If you encounter problems when installing or using this product, or would like
+information about our other "Wireless" products, please contact your local
+Authorized "Wireless" Reseller or Agere Systems sales office.
+
+Addresses and telephone numbers of the Agere Systems sales offices are
+listed on our Agere Systems web site.
+.TP
+.B WWW
+http://www.agere.com
+.SH SEE ALSO
+.BR cardmgr (8),
+.BR pcmcia (5),
+.BR ifconfig (8),
+.BR insmod (8),
+.BR brctl (8).
diff --git a/drivers/staging/wlags49_h2/mdd.h b/drivers/staging/wlags49_h2/mdd.h
new file mode 100644
index 0000000..b45c7dd
--- /dev/null
+++ b/drivers/staging/wlags49_h2/mdd.h
@@ -0,0 +1,1156 @@
+
+//   vim:tw=110:ts=4:
+#ifndef MDD_H
+#define MDD_H 1
+
+/*************************************************************************************************************
+*
+* FILE		: mdd.h
+*
+* DATE		: $Date: 2004/08/05 11:47:10 $   $Revision: 1.6 $
+* Original		: 2004/05/25 05:59:37    Revision: 1.57      Tag: hcf7_t20040602_01
+* Original		: 2004/05/13 15:31:45    Revision: 1.54      Tag: hcf7_t7_20040513_01
+* Original		: 2004/04/15 09:24:41    Revision: 1.47      Tag: hcf7_t7_20040415_01
+* Original		: 2004/04/13 14:22:45    Revision: 1.46      Tag: t7_20040413_01
+* Original		: 2004/04/01 15:32:55    Revision: 1.42      Tag: t7_20040401_01
+* Original		: 2004/03/10 15:39:28    Revision: 1.38      Tag: t20040310_01
+* Original		: 2004/03/04 11:03:37    Revision: 1.36      Tag: t20040304_01
+* Original		: 2004/03/02 09:27:11    Revision: 1.34      Tag: t20040302_03
+* Original		: 2004/02/24 13:00:27    Revision: 1.29      Tag: t20040224_01
+* Original		: 2004/02/18 17:13:57    Revision: 1.26      Tag: t20040219_01
+*
+* AUTHOR	: Nico Valster
+*
+* DESC		: Definitions and Prototypes for HCF, DHF, MMD and MSF
+*
+***************************************************************************************************************
+*
+*
+* SOFTWARE LICENSE
+*
+* This software is provided subject to the following terms and conditions,
+* which you should read carefully before using the software.  Using this
+* software indicates your acceptance of these terms and conditions.  If you do
+* not agree with these terms and conditions, do not use the software.
+*
+* COPYRIGHT © 1994 - 1995	by AT&T.				All Rights Reserved
+* COPYRIGHT © 1996 - 2000 by Lucent Technologies.	All Rights Reserved
+* COPYRIGHT © 2001 - 2004	by Agere Systems Inc.	All Rights Reserved
+* All rights reserved.
+*
+* Redistribution and use in source or binary forms, with or without
+* modifications, are permitted provided that the following conditions are met:
+*
+* . Redistributions of source code must retain the above copyright notice, this
+*    list of conditions and the following Disclaimer as comments in the code as
+*    well as in the documentation and/or other materials provided with the
+*    distribution.
+*
+* . Redistributions in binary form must reproduce the above copyright notice,
+*    this list of conditions and the following Disclaimer in the documentation
+*    and/or other materials provided with the distribution.
+*
+* . Neither the name of Agere Systems Inc. nor the names of the contributors
+*    may be used to endorse or promote products derived from this software
+*    without specific prior written permission.
+*
+* Disclaimer
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+* INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+* USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+* RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+* DAMAGE.
+*
+*
+************************************************************************************************************/
+
+
+/************************************************************************************************************
+*
+* The macros Xn(...) and XXn(...) are used to define the LTV's (short for Length Type Value[ ]) ,
+* aka RIDs, processed by the Hermes.
+* The n in Xn and XXn reflects the number of "Value" fields in these RIDs.
+*
+* Xn(...) : Macros used for RIDs which use only type hcf_16 for the "V" fields of the LTV.
+* Xn takes as parameters a RID name and "n" name(s), one for each of the "V" fields of the LTV.
+*
+* XXn(...) : Macros used for RIDs which use at least one other type then hcf_16 for a "V" field
+* of the LTV.
+* XXn(..) takes as parameters a RID name and "n" pair(s) of type and name, one for each "V" field
+* of the LTV
+
+ ******************************************  e x a m p l e s  ***********************************************
+
+* X1(RID_NAME, parameters...) : expands to :
+*    typedef struct RID_NAME_STRCT {
+*         hcf_16  len;
+*         hcf_16  typ;
+*         hcf_16  par1;
+*    } RID_NAME_STRCT;
+
+* X2(RID_NAME, parameters...) : expands to :
+*    typedef struct RID_NAME_STRCT {
+*         hcf_16  len;
+*         hcf_16  typ;
+*         hcf_16  par1;
+*         hcf_16  par2;
+*    } RID_NAME_STRCT;
+
+
+* XX1(RID_NAME, par1type, par1name, ...) : expands to :
+*    typedef struct RID_NAME_STRCT {
+*       hcf_16    len;
+*       hcf_16    typ;
+*       par1type  par1name;
+*    } RID_NAME_STRCT;
+
+************************************************************************************************************/
+
+/******************************* XX Sub-macro definitions **************************************************/
+
+#define XX1( name, type1, par1 )	\
+typedef struct {				  	\
+	hcf_16	len;                	\
+	hcf_16	typ;                	\
+	type1	par1;               	\
+} name##_STRCT;
+
+#define XX2( name, type1, par1, type2, par2 )	\
+typedef struct {				   	\
+	hcf_16	len;                	\
+	hcf_16	typ;                	\
+	type1	par1;               	\
+	type2	par2;               	\
+} name##_STRCT;
+
+#define XX3( name, type1, par1, type2, par2, type3, par3 )	\
+typedef struct name##_STRCT {   	\
+	hcf_16	len;                	\
+	hcf_16	typ;                	\
+	type1	par1;               	\
+	type2	par2;               	\
+	type3	par3;               	\
+} name##_STRCT;
+
+#define XX4( name, type1, par1, type2, par2, type3, par3, type4, par4 )	\
+typedef struct {				  	\
+	hcf_16	len;                	\
+	hcf_16	typ;                	\
+	type1	par1;               	\
+	type2	par2;               	\
+	type3	par3;               	\
+	type4	par4;               	\
+} name##_STRCT;
+
+#define X1( name, par1 )	\
+typedef struct name##_STRCT {   	\
+	hcf_16	len;                	\
+	hcf_16	typ;                	\
+	hcf_16	par1;               	\
+} name##_STRCT;
+
+#define X2( name, par1, par2 )		\
+typedef struct {			    	\
+	hcf_16	len;                	\
+	hcf_16	typ;                	\
+	hcf_16	par1;               	\
+	hcf_16	par2;               	\
+} name##_STRCT;
+
+#define X3( name, par1, par2, par3 )		\
+typedef struct {			    	\
+	hcf_16	len;                	\
+	hcf_16	typ;                	\
+	hcf_16	par1;               	\
+	hcf_16	par2;               	\
+	hcf_16	par3;               	\
+} name##_STRCT;
+
+#define X4( name, par1, par2, par3, par4 )		\
+typedef struct {			    	\
+	hcf_16	len;                	\
+	hcf_16	typ;                	\
+	hcf_16	par1;               	\
+	hcf_16	par2;               	\
+	hcf_16	par3;               	\
+	hcf_16	par4;               	\
+} name##_STRCT;
+
+#define X5( name, par1, par2, par3, par4, par5 )		\
+typedef struct {			    	\
+	hcf_16	len;                	\
+	hcf_16	typ;                	\
+	hcf_16	par1;               	\
+	hcf_16	par2;               	\
+	hcf_16	par3;               	\
+	hcf_16	par4;               	\
+	hcf_16	par5;               	\
+} name##_STRCT;
+
+#define X6( name, par1, par2, par3, par4, par5, par6 )		\
+typedef struct {			    	\
+	hcf_16	len;                	\
+	hcf_16	typ;                	\
+	hcf_16	par1;               	\
+	hcf_16	par2;               	\
+	hcf_16	par3;               	\
+	hcf_16	par4;               	\
+	hcf_16	par5;               	\
+	hcf_16	par6;               	\
+} name##_STRCT;
+
+#define X8( name, par1, par2, par3, par4, par5, par6, par7, par8 )		\
+typedef struct {			    	\
+	hcf_16	len;                	\
+	hcf_16	typ;                	\
+	hcf_16	par1;               	\
+	hcf_16	par2;               	\
+	hcf_16	par3;               	\
+	hcf_16	par4;               	\
+	hcf_16	par5;               	\
+	hcf_16	par6;               	\
+	hcf_16	par7;               	\
+	hcf_16	par8;               	\
+} name##_STRCT;
+
+#define X11( name, par1, par2, par3, par4, par5, par6, par7, par8, par9, par10, par11 )		\
+typedef struct {			    	\
+	hcf_16	len;                	\
+	hcf_16	typ;                	\
+	hcf_16	par1;               	\
+	hcf_16	par2;               	\
+	hcf_16	par3;               	\
+	hcf_16	par4;               	\
+	hcf_16	par5;               	\
+	hcf_16	par6;               	\
+	hcf_16	par7;               	\
+	hcf_16	par8;               	\
+	hcf_16	par9;               	\
+	hcf_16	par10;               	\
+	hcf_16	par11;               	\
+} name##_STRCT;
+
+/******************************* Substructure definitions **************************************************/
+
+//apparently not needed (CFG_CNF_COUNTRY)
+typedef struct CHANNEL_SET {				//channel set structure used in the CFG_CNF_COUNTRY LTV
+	hcf_16	first_channel;
+	hcf_16	number_of_channels;
+	hcf_16	max_tx_output_level;
+} CHANNEL_SET;
+
+typedef struct KEY_STRCT {					// key structure used in the CFG_DEFAULT_KEYS LTV
+    hcf_16  len;	              				//length of key
+    hcf_8   key[14];							//encryption key
+} KEY_STRCT;
+
+typedef struct SCAN_RS_STRCT {				// Scan Result structure used in the CFG_SCAN LTV
+	hcf_16	channel_id;
+	hcf_16	noise_level;
+	hcf_16	signal_level;
+	hcf_8	bssid[6];
+	hcf_16	beacon_interval_time;
+	hcf_16	capability;
+	hcf_16	ssid_len;
+	hcf_8	ssid_val[32];
+} SCAN_RS_STRCT;
+
+typedef struct CFG_RANGE_SPEC_STRCT {		// range specification structure used in CFG_RANGES, CFG_RANGE1 etc
+	hcf_16	variant;
+	hcf_16	bottom;
+	hcf_16	top;
+} CFG_RANGE_SPEC_STRCT;
+
+typedef struct CFG_RANGE_SPEC_BYTE_STRCT {	// byte oriented range specification structure used in CFG_RANGE_B LTV
+	hcf_8	variant[2];
+	hcf_8	bottom[2];
+	hcf_8	top[2];
+} CFG_RANGE_SPEC_BYTE_STRCT;
+
+//used to set up "T" functionality for Info frames, i.e. log info frames in MSF supplied buffer and MailBox
+XX1( RID_LOG, unsigned short FAR*, bufp )
+typedef RID_LOG_STRCT  FAR *RID_LOGP;
+XX1( CFG_RID_LOG, RID_LOGP, recordp )
+
+ X1( LTV,		val[1] )												/*minimum LTV proto typ	*/
+ X1( LTV_MAX,	val[HCF_MAX_LTV] )										/*maximum LTV proto typ	*/
+XX2( CFG_REG_MB, hcf_16* , mb_addr, hcf_16, mb_size )
+
+typedef struct CFG_MB_INFO_FRAG {	// specification of buffer fragment
+	unsigned short FAR*	frag_addr;
+	hcf_16				frag_len;
+} CFG_MB_INFO_FRAG;
+
+/* Mail Box Info Block structures,
+ * the base form: CFG_MB_INFO_STRCT
+ * and the derived forms: CFG_MB_INFO_RANGE<n>_STRCT with n is 1, 2, 3 or 20
+ * predefined for a payload of 1, and up to 2, 3 and 20 CFG_MB_INFO_FRAG elements */
+XX3( CFG_MB_INFO,		  hcf_16, base_typ, hcf_16, frag_cnt, CFG_MB_INFO_FRAG, frag_buf[ 1] )
+XX3( CFG_MB_INFO_RANGE1,  hcf_16, base_typ, hcf_16, frag_cnt, CFG_MB_INFO_FRAG, frag_buf[ 1] )
+XX3( CFG_MB_INFO_RANGE2,  hcf_16, base_typ, hcf_16, frag_cnt, CFG_MB_INFO_FRAG, frag_buf[ 2] )
+XX3( CFG_MB_INFO_RANGE3,  hcf_16, base_typ, hcf_16, frag_cnt, CFG_MB_INFO_FRAG, frag_buf[ 3] )
+XX3( CFG_MB_INFO_RANGE20, hcf_16, base_typ, hcf_16, frag_cnt, CFG_MB_INFO_FRAG, frag_buf[20] )
+
+XX3( CFG_MB_ASSERT, hcf_16, line, hcf_16, trace, hcf_32, qualifier )	/*MBInfoBlock for asserts	*/
+#if (HCF_ASSERT) & ( HCF_ASSERT_LNK_MSF_RTN | HCF_ASSERT_RT_MSF_RTN )
+typedef void (MSF_ASSERT_RTN)( unsigned int , hcf_16, hcf_32 );
+typedef MSF_ASSERT_RTN /*can't link FAR*/ * MSF_ASSERT_RTNP;
+/* CFG_REG_ASSERT_RTNP (0x0832)	(de-)register MSF Callback routines
+ * lvl:  Assert level filtering (not yet implemented)
+ * rtnp: address of MSF_ASSERT_RTN (native Endian format) */
+XX2( CFG_REG_ASSERT_RTNP, hcf_16, lvl, MSF_ASSERT_RTNP, rtnp )
+#endif // HCF_ASSERT_LNK_MSF_RTN / HCF_ASSERT_RT_MSF_RTN
+
+ X1( CFG_HCF_OPT, val[20] )											  	/*(Compile time) options	*/
+ X3( CFG_CMD_HCF, cmd, mode, add_info )									/*HCF Engineering command	*/
+
+typedef struct {
+	hcf_16		len;
+	hcf_16		typ;
+	hcf_16		mode;			// PROG_STOP/VOLATILE [FLASH/SEEPROM/SEEPROM_READBACK]
+	hcf_16		segment_size;  	// size of the segment in bytes
+	hcf_32		nic_addr;  		// destination address (in NIC memory)
+	hcf_16		flags;			// 0x0001	: CRC Yes/No
+//	hcf_32		flags;			// 0x0001	: CRC Yes/No
+	/* ;? still not the whole story
+	 * flags is extended from 16 to 32 bits to force that compiling FW.C produces the same structures
+	 * in memory as FUPU4 BIN files.
+	 * Note that the problem arises from the violation of the constraint to use packing at byte boundaries
+	 * as was stipulated in the WCI-specification
+	 * The Pack pragma can't resolve this issue, because that impacts all members of the structure with
+	 * disregard of their actual size, so aligning host_addr under MSVC 1.5 at 4 bytes, also aligns
+	 * len, typ etc on 4 bytes
+	 * */
+//	hcf_16		pad; 	 		//!! be careful alignment problems for Bin download versus C download
+	hcf_8 FAR   *host_addr;  	// source address (in Host memory)
+} CFG_PROG_STRCT; // segment_descp;
+
+// a structure used for transporting debug-related information from firmware
+// via the HCF, into the MSF
+typedef struct {
+    hcf_16      len;
+    hcf_16      typ;
+    hcf_16      msg_id, msg_par, msg_tstamp;
+} CFG_FW_PRINTF_STRCT;
+
+// a structure used to define the location and size of a certain debug-related
+// buffer in nic-ram.
+typedef struct {
+    hcf_16      len;
+    hcf_16      typ;
+    hcf_32      DbMsgCount, 	// ds (nicram) address of a counter
+                DbMsgBuffer, 	// ds (nicram) address of the buffer
+                DbMsgSize, 		// number of entries (each 3 word in size) in this buffer
+                DbMsgIntrvl;	// ds (nicram) address of interval for generating InfDrop event
+} CFG_FW_PRINTF_BUFFER_LOCATION_STRCT;
+
+XX3( CFG_RANGES,	hcf_16, role, hcf_16, id, CFG_RANGE_SPEC_STRCT, var_rec[ 1] ) /*Actor/Supplier range (1 variant)*/
+XX3( CFG_RANGE1,	hcf_16, role, hcf_16, id, CFG_RANGE_SPEC_STRCT, var_rec[ 1] ) /*Actor/Supplier range (1 variant)*/
+XX3( CFG_RANGE2,	hcf_16, role, hcf_16, id, CFG_RANGE_SPEC_STRCT, var_rec[ 2] ) /*Actor range ( 2 variants)		*/
+XX3( CFG_RANGE3,	hcf_16, role, hcf_16, id, CFG_RANGE_SPEC_STRCT, var_rec[ 3] ) /*Actor range ( 3 variants)		*/
+XX3( CFG_RANGE4,	hcf_16, role, hcf_16, id, CFG_RANGE_SPEC_STRCT, var_rec[ 4] ) /*Actor range ( 4 variants)		*/
+XX3( CFG_RANGE5,	hcf_16, role, hcf_16, id, CFG_RANGE_SPEC_STRCT, var_rec[ 5] ) /*Actor range ( 5 variants)		*/
+XX3( CFG_RANGE6,	hcf_16, role, hcf_16, id, CFG_RANGE_SPEC_STRCT, var_rec[ 6] ) /*Actor range ( 6 variants)		*/
+XX3( CFG_RANGE7,	hcf_16, role, hcf_16, id, CFG_RANGE_SPEC_STRCT, var_rec[ 7] ) /*Actor range ( 7 variants)		*/
+XX3( CFG_RANGE20,	hcf_16, role, hcf_16, id, CFG_RANGE_SPEC_STRCT, var_rec[20] ) /*Actor range (20 variants)		*/
+
+/*Frames */
+ X3( CFG_ASSOC_STAT,  assoc_stat, station_addr[3], val[46] ) 	/*Association status, basic					*/
+ X2( CFG_ASSOC_STAT3, assoc_stat, station_addr[3] ) 								/*assoc_stat:3			*/
+ X3( CFG_ASSOC_STAT1, assoc_stat, station_addr[3], frame_body[43] )					/*assoc_stat:1			*/
+ X4( CFG_ASSOC_STAT2, assoc_stat, station_addr[3], old_ap_addr[3], frame_body[43] )	/*assoc_stat:2			*/
+
+/*Static Configurations */
+ X1( CFG_CNF_PORT_TYPE,				port_type			 ) /*[STA] Connection control characteristics				*/
+ X1( CFG_MAC_ADDR,					mac_addr[3] 		 ) /*general: FC01,FC08,FC11,FC12,FC13,FC14,FC15,FC16 		*/
+ X1( CFG_CNF_OWN_MAC_ADDR,			mac_addr[3]			 )
+ X1( CFG_ID,						ssid[17]			 ) /*0xFC02, 0xFC04, 0xFC0E 								*/
+/*	X1( CFG_DESIRED_SSID,			ssid[17]			 )	see Dynamic Configurations								*/
+ X1( CFG_CNF_OWN_CHANNEL,			channel				 ) /*Communication channel for BSS creation					*/
+ X1( CFG_CNF_OWN_SSID,				ssid[17]			 )
+ X1( CFG_CNF_OWN_ATIM_WINDOW,		atim_window			 )
+ X1( CFG_CNF_SYSTEM_SCALE,			system_scale		 )
+ X1( CFG_CNF_MAX_DATA_LEN,			max_data_len		 )
+ X1( CFG_CNF_WDS_ADDR,				mac_addr[3]			 ) /*[STA] MAC Address of corresponding WDS Link node		*/
+ X1( CFG_CNF_PM_ENABLED,			pm_enabled			 ) /*[STA] Switch for ESS Power Management (PM) On/Off		*/
+ X1( CFG_CNF_PM_EPS,				pm_eps				 ) /*[STA] Switch for ESS PM EPS/PS Mode					*/
+ X1( CFG_CNF_MCAST_RX,				mcast_rx			 ) /*[STA] Switch for ESS PM Multicast reception On/Off		*/
+ X1( CFG_CNF_MAX_SLEEP_DURATION,	duration			 ) /*[STA] Maximum sleep time for ESS PM					*/
+ X1( CFG_CNF_PM_HOLDOVER_DURATION,	duration			 ) /*[STA] Holdover time for ESS PM							*/
+ X1( CFG_CNF_OWN_NAME,				ssid[17]			 ) /*Identification text for diagnostic purposes			*/
+ X1( CFG_CNF_OWN_DTIM_PERIOD,		period				 ) /*[AP] Beacon intervals between successive DTIMs			*/
+ X1( CFG_CNF_WDS_ADDR1,				mac_addr[3]			 ) /*[AP] Port 1 MAC Adrs of corresponding WDS Link node	*/
+ X1( CFG_CNF_WDS_ADDR2,				mac_addr[3]			 ) /*[AP] Port 2 MAC Adrs of corresponding WDS Link node	*/
+ X1( CFG_CNF_WDS_ADDR3,				mac_addr[3]			 ) /*[AP] Port 3 MAC Adrs of corresponding WDS Link node	*/
+ X1( CFG_CNF_WDS_ADDR4,				mac_addr[3]			 ) /*[AP] Port 4 MAC Adrs of corresponding WDS Link node	*/
+ X1( CFG_CNF_WDS_ADDR5,				mac_addr[3]			 ) /*[AP] Port 5 MAC Adrs of corresponding WDS Link node	*/
+ X1( CFG_CNF_WDS_ADDR6,				mac_addr[3]			 ) /*[AP] Port 6 MAC Adrs of corresponding WDS Link node	*/
+ X1( CFG_CNF_MCAST_PM_BUF,			mcast_pm_buf		 ) /*[AP] Switch for PM buffering of Multicast Messages	*/
+ X1( CFG_CNF_REJECT_ANY,			reject_any			 ) /*[AP] Switch for PM buffering of Multicast Messages	*/
+//X1( CFG_CNF_ENCRYPTION_ENABLED,	encryption			 ) /*specify encryption type of Tx/Rx messages				*/
+ X1( CFG_CNF_ENCRYPTION,			encryption			 ) /*specify encryption type of Tx/Rx messages				*/
+ X1( CFG_CNF_AUTHENTICATION,		authentication		 ) /*selects Authentication algorithm						*/
+ X1( CFG_CNF_EXCL_UNENCRYPTED,		exclude_unencrypted	 ) /*[AP] Switch for 'clear-text' rx message acceptance		*/
+ X1( CFG_CNF_MCAST_RATE,			mcast_rate			 ) /*Transmit Data rate for Multicast frames				*/
+ X1( CFG_CNF_INTRA_BSS_RELAY,		intra_bss_relay		 ) /*[AP] Switch for IntraBBS relay							*/
+ X1( CFG_CNF_MICRO_WAVE,			micro_wave			 ) /*MicroWave (Robustness)									*/
+ X1( CFG_CNF_LOAD_BALANCING,		load_balancing		 ) /*Load Balancing	  (Boolean, 0=OFF, 1=ON, default=1)		*/
+ X1( CFG_CNF_MEDIUM_DISTRIBUTION,	medium_distribution	 ) /*Medium Distribution (Boolean, 0=OFF, 1=ON, default=1)	*/
+ X1( CFG_CNF_GROUP_ADDR_FILTER,		group_addr_filter	 ) /*Group Address Filter								   	*/
+ X1( CFG_CNF_TX_POW_LVL,			tx_pow_lvl			 ) /*Tx Power Level										   	*/
+XX4( CFG_CNF_COUNTRY_INFO,								 \
+		hcf_16, n_channel_sets, hcf_16, country_code[2], \
+		hcf_16, environment, CHANNEL_SET, channel_set[1] ) /*Current Country Info  									*/
+XX4( CFG_CNF_COUNTRY_INFO_MAX,							 \
+		hcf_16, n_channel_sets, hcf_16, country_code[2], \
+		hcf_16, environment, CHANNEL_SET, channel_set[14]) /*Current Country Info  									*/
+
+/*Dynamic Configurations */
+ X1( CFG_DESIRED_SSID,			ssid[17]					 )	/*[STA] Service Set identification for connection	*/
+#define GROUP_ADDR_SIZE			(32 * 6)						//32 6-byte MAC-addresses
+ X1( CFG_GROUP_ADDR,			mac_addr[GROUP_ADDR_SIZE/2]	 )	/*[STA] Multicast MAC Addresses for Rx-message		*/
+ X1( CFG_CREATE_IBSS,			create_ibss					 )	/*[STA] Switch for IBSS creation On/Off				*/
+ X1( CFG_RTS_THRH,				rts_thrh					 )	/*[STA] Frame length used for RTS/CTS handshake		*/
+ X1( CFG_TX_RATE_CNTL,			tx_rate_cntl				 )	/*[STA] Data rate control for message transmission	*/
+ X1( CFG_PROMISCUOUS_MODE,		promiscuous_mode			 )	/*[STA] Switch for Promiscuous mode reception On/Of	*/
+ X1( CFG_WOL,					wake_on_lan					 )	/*[STA] Switch for Wake-On-LAN mode					*/
+ X1( CFG_RTS_THRH0,				rts_thrh					 )	/*[AP] Port 0 frame length for RTS/CTS handshake	*/
+ X1( CFG_RTS_THRH1,				rts_thrh					 )	/*[AP] Port 1 frame length for RTS/CTS handshake	*/
+ X1( CFG_RTS_THRH2,				rts_thrh					 )	/*[AP] Port 2 frame length for RTS/CTS handshake	*/
+ X1( CFG_RTS_THRH3,				rts_thrh					 )	/*[AP] Port 3 frame length for RTS/CTS handshake	*/
+ X1( CFG_RTS_THRH4,				rts_thrh					 )	/*[AP] Port 4 frame length for RTS/CTS handshake	*/
+ X1( CFG_RTS_THRH5,				rts_thrh					 )	/*[AP] Port 5 frame length for RTS/CTS handshake	*/
+ X1( CFG_RTS_THRH6,				rts_thrh					 )	/*[AP] Port 6 frame length for RTS/CTS handshake	*/
+ X1( CFG_TX_RATE_CNTL0,			rate_cntl 					 )	/*[AP] Port 0 data rate control for transmission	*/
+ X1( CFG_TX_RATE_CNTL1,			rate_cntl					 )	/*[AP] Port 1 data rate control for transmission	*/
+ X1( CFG_TX_RATE_CNTL2,			rate_cntl					 )	/*[AP] Port 2 data rate control for transmission	*/
+ X1( CFG_TX_RATE_CNTL3,			rate_cntl					 )	/*[AP] Port 3 data rate control for transmission	*/
+ X1( CFG_TX_RATE_CNTL4,			rate_cntl					 )	/*[AP] Port 4 data rate control for transmission	*/
+ X1( CFG_TX_RATE_CNTL5,			rate_cntl					 )	/*[AP] Port 5 data rate control for transmission	*/
+ X1( CFG_TX_RATE_CNTL6,			rate_cntl					 )	/*[AP] Port 6 data rate control for transmission	*/
+XX1( CFG_DEFAULT_KEYS,			KEY_STRCT, key[4]			 )	/*defines set of encryption keys					*/
+ X1( CFG_TX_KEY_ID,				tx_key_id					 )	/*select key for encryption of Tx messages			*/
+ X1( CFG_SCAN_SSID,				ssid[17]					 )	/*identification for connection						*/
+ X5( CFG_ADD_TKIP_DEFAULT_KEY,								 \
+		 tkip_key_id_info, tkip_key_iv_info[4], tkip_key[8], \
+		 tx_mic_key[4], rx_mic_key[4] 						 )	/*										       		*/
+ X6( CFG_ADD_TKIP_MAPPED_KEY,	bssid[3], tkip_key[8], 		 \
+		 tsc[4], rsc[4], tx_mic_key[4], rx_mic_key[4] 		 )	/*										       		*/
+ X1( CFG_SET_SSN_AUTHENTICATION_SUITE, 						 \
+		 ssn_authentication_suite							 )	/*											   		*/
+ X1( CFG_REMOVE_TKIP_DEFAULT_KEY,tkip_key_id				 )	/*											   		*/
+ X1( CFG_TICK_TIME,				tick_time					 )	/*Auxiliary Timer tick interval						*/
+ X1( CFG_DDS_TICK_TIME,			tick_time					 )	/*Disconnected DeepSleep Timer tick interval		*/
+
+/**********************************************************************
+* Added for Pattern-matching WakeOnLan. (See firmware design note WMDN281C)
+**********************************************************************/
+#define WOL_PATTERNS				5		// maximum of 5 patterns in firmware
+#define WOL_PATTERN_LEN				124		// maximum 124 bytes pattern length per pattern in firmware
+#define WOL_MASK_LEN			 	30		// maximum 30 bytes mask length per pattern in firmware
+#define WOL_BUF_SIZE	(WOL_PATTERNS * (WOL_PATTERN_LEN + WOL_MASK_LEN + 6) / 2)
+X2( CFG_WOL_PATTERNS, nPatterns, buffer[WOL_BUF_SIZE]		 )  /*[STA] WakeOnLan pattern match, room for 5 patterns*/
+
+ X5( CFG_SUP_RANGE,		role, id, variant, bottom, top				   ) /*[PRI] Primary Supplier compatibility range		*/
+/* NIC Information */
+ X4( CFG_IDENTITY,			comp_id, variant, version_major, version_minor ) /*identification Prototype							*/
+#define CFG_DRV_IDENTITY_STRCT	CFG_IDENTITY_STRCT
+#define CFG_PRI_IDENTITY_STRCT	CFG_IDENTITY_STRCT
+#define CFG_NIC_IDENTITY_STRCT	CFG_IDENTITY_STRCT
+#define CFG_FW_IDENTITY_STRCT	CFG_IDENTITY_STRCT
+ X1( CFG_RID_INF_MIN,		y											   ) /*lowest value representing an Information RID		*/
+ X1( CFG_MAX_LOAD_TIME,		max_load_time								   ) /*[PRI] Max response time of the Download command	*/
+ X3( CFG_DL_BUF,			buf_page, buf_offset, buf_len				   ) /*[PRI] Download buffer location and size			*/
+// X5( CFG_PRI_SUP_RANGE,		role, id, variant, bottom, top				   ) /*[PRI] Primary Supplier compatibility range		*/
+ X5( CFG_CFI_ACT_RANGES_PRI,role, id, variant, bottom, top				   ) /*[PRI] Controller Actor compatibility ranges		*/
+// X5( CFG_NIC_HSI_SUP_RANGE,	role, id, variant, bottom, top				   ) /*H/W - S/W I/F supplier range						*/
+ X1( CFG_NIC_SERIAL_NUMBER,	serial_number[17]							   ) /*[PRI] Network I/F Card serial number				*/
+ X5( CFG_NIC_MFI_SUP_RANGE,	role, id, variant, bottom, top				   ) /*[PRI] Modem I/F Supplier compatibility range		*/
+ X5( CFG_NIC_CFI_SUP_RANGE,	role, id, variant, bottom, top				   ) /*[PRI] Controller I/F Supplier compatibility range*/
+//H-I X1( CFG_CHANNEL_LIST,		channel_list								   ) /*Allowed communication channels					*/
+//H-I XX2( CFG_REG_DOMAINS,		hcf_16, num_domain, hcf_8, reg_domains[10]	   ) /*List of intended regulatory domains				*/
+ X1( CFG_NIC_TEMP_TYPE,		temp_type									   ) /*Hardware temperature range code					*/
+//H-I X1( CFG_CIS,				cis[240]									   ) /*PC Card Standard Card Information Structure		*/
+ X5( CFG_NIC_PROFILE,													   \
+		 profile_code, capability_options, allowed_data_rates, val4, val5  ) /*Card Profile										*/
+// X5( CFG_FW_SUP_RANGE,		role, id, variant, bottom, top				   ) /*[STA] Station I/F Supplier compatibility range	*/
+ X5( CFG_MFI_ACT_RANGES,	role, id, variant, bottom, top				   ) /*[STA] Modem I/F Actor compatibility ranges		*/
+ X5( CFG_CFI_ACT_RANGES_STA,role, id, variant, bottom, top				   ) /*[STA] Controller I/F Actor compatibility ranges	*/
+ X5( CFG_MFI_ACT_RANGES_STA,role, id, variant, bottom, top				   ) /*[STA] Controller I/F Actor compatibility ranges	*/
+ X1( CFG_NIC_BUS_TYPE,		nic_bus_type								   ) /*NIC bustype derived from BUSSEL host I/F signals */
+
+/*	MAC INFORMATION	*/
+ X1( CFG_PORT_STAT,				port_stat							 ) /*[STA] Actual MAC Port connection control status		*/
+ X1( CFG_CUR_SSID,				ssid[17]							 ) /*[STA] Identification of the actually connected SS		*/
+ X1( CFG_CUR_BSSID,				mac_addr[3]							 ) /*[STA] Identification of the actually connected BSS		*/
+ X3( CFG_COMMS_QUALITY,			coms_qual, signal_lvl, noise_lvl	 ) /*[STA] Quality of the Basic Service Set connection		*/
+ X1( CFG_CUR_TX_RATE,			rate								 ) /*[STA] Actual transmit data rate						*/
+ X1( CFG_CUR_BEACON_INTERVAL,	interval							 ) /*Beacon transmit interval time for BSS creation			*/
+#if (HCF_TYPE) & HCF_TYPE_WARP
+ X11( CFG_CUR_SCALE_THRH,											 \
+	 carrier_detect_thrh_cck, carrier_detect_thrh_ofdm, defer_thrh,	 \
+	 energy_detect_thrh, rssi_on_thrh_deviation, 					 \
+	 rssi_off_thrh_deviation, cck_drop_thrh, ofdm_drop_thrh, 		 \
+	 cell_search_thrh, out_of_range_thrh, delta_snr				 )
+#else
+ X6( CFG_CUR_SCALE_THRH,											 \
+	 energy_detect_thrh, carrier_detect_thrh, defer_thrh, 			 \
+	 cell_search_thrh, out_of_range_thrh, delta_snr					 ) /*Actual System Scale thresholds settings				*/
+#endif // HCF_TYPE_WARP
+ X1( CFG_PROTOCOL_RSP_TIME,		time								 ) /*Max time to await a response to a request message		*/
+ X1( CFG_CUR_SHORT_RETRY_LIMIT,	limit								 ) /*Max number of transmit attempts for short frames		*/
+ X1( CFG_CUR_LONG_RETRY_LIMIT,	limit								 ) /*Max number of transmit attempts for long frames		*/
+ X1( CFG_MAX_TX_LIFETIME,		time								 ) /*Max transmit frame handling duration					*/
+ X1( CFG_MAX_RX_LIFETIME,		time								 ) /*Max received frame handling duration					*/
+ X1( CFG_CF_POLLABLE,			cf_pollable							 ) /*[STA] Contention Free pollable capability indication	*/
+ X2( CFG_AUTHENTICATION_ALGORITHMS,authentication_type, type_enabled ) /*Authentication Algorithm								*/
+ X1( CFG_PRIVACY_OPT_IMPLEMENTED,privacy_opt_implemented			 ) /*WEP Option availability indication						*/
+ X1( CFG_CUR_REMOTE_RATES,		rates								 ) /*CurrentRemoteRates										*/
+ X1( CFG_CUR_USED_RATES,		rates								 ) /*CurrentUsedRates										*/
+ X1( CFG_CUR_SYSTEM_SCALE,		current_system_scale				 ) /*CurrentUsedRates										*/
+ X1( CFG_CUR_TX_RATE1,			rate 								 ) /*[AP] Actual Port 1 transmit data rate					*/
+ X1( CFG_CUR_TX_RATE2,			rate								 ) /*[AP] Actual Port 2 transmit data rate					*/
+ X1( CFG_CUR_TX_RATE3,			rate								 ) /*[AP] Actual Port 3 transmit data rate					*/
+ X1( CFG_CUR_TX_RATE4,			rate								 ) /*[AP] Actual Port 4 transmit data rate					*/
+ X1( CFG_CUR_TX_RATE5,			rate								 ) /*[AP] Actual Port 5 transmit data rate					*/
+ X1( CFG_CUR_TX_RATE6,			rate								 ) /*[AP] Actual Port 6 transmit data rate					*/
+ X1( CFG_OWN_MAC_ADDR,			mac_addr[3]							 ) /*[AP] Unique local node MAC Address						*/
+ X3( CFG_PCF_INFO,				medium_occupancy_limit, 			 \
+		 						cfp_period, cfp_max_duration 		 ) /*[AP] Point Coordination Function capability info		*/
+ X1( CFG_CUR_SSN_INFO_ELEMENT, ssn_info_element[1]				 	 ) /*    													*/
+ X4( CFG_CUR_TKIP_IV_INFO, 											 \
+		 tkip_seq_cnt0[4], tkip_seq_cnt1[4], 						 \
+		 tkip_seq_cnt2[4], tkip_seq_cnt3[4]  						 ) /*    													*/
+ X2( CFG_CUR_ASSOC_REQ_INFO,	frame_type, frame_body[1]			 ) /*	0xFD8C												*/
+ X2( CFG_CUR_ASSOC_RESP_INFO,	frame_type, frame_body[1]			 ) /*	0xFD8D												*/
+
+
+/*	Modem INFORMATION */
+ X1( CFG_PHY_TYPE,				phy_type 							 ) /*Physical layer type indication							*/
+ X1( CFG_CUR_CHANNEL,			current_channel						 ) /*Actual frequency channel used for transmission			*/
+ X1( CFG_CUR_POWER_STATE,		current_power_state					 ) /*Actual power consumption status						*/
+ X1( CFG_CCAMODE,				cca_mode							 ) /*Clear channel assessment mode indication				*/
+ X1( CFG_SUPPORTED_DATA_RATES,	rates[5]							 ) /*Data rates capability information						*/
+
+
+/* FRAMES */
+XX1( CFG_SCAN,					SCAN_RS_STRCT, scan_result[32]		 ) /*Scan results											*/
+
+
+
+//--------------------------------------------------------------------------------------
+// UIL management function to be passed to WaveLAN/IEEE Drivers in DUI_STRCT field fun
+//--------------------------------------------------------------------------------------
+
+// HCF and UIL Common
+#define MDD_ACT_SCAN			0x06					// Hermes Inquire Scan (F101) command
+#define MDD_ACT_PRS_SCAN 		0x07					// Hermes Probe Response Scan (F102) command
+
+// UIL Specific
+#define UIL_FUN_CONNECT			0x00					// Perform connect command
+#define UIL_FUN_DISCONNECT		0x01					// Perform disconnect command
+#define UIL_FUN_ACTION			0x02					// Perform UIL Action command.
+#define UIL_FUN_SEND_DIAG_MSG	0x03					// Send a diagnostic message.
+#define UIL_FUN_GET_INFO		0x04					// Retrieve information from NIC.
+#define UIL_FUN_PUT_INFO		0x05					// Put information on NIC.
+
+/*	UIL_ACT_TALLIES				0x05		 			* this should not be exported to the USF
+											 			* it is solely intended as a strategic choice for the MSF to either
+											 			* - use HCF_ACT_TALLIES and direct IFB access
+														* - use CFG_TALLIES
+														*/
+#define UIL_ACT_SCAN			MDD_ACT_SCAN
+#define UIL_ACT_PRS_SCAN 		MDD_ACT_PRS_SCAN
+#define UIL_ACT_BLOCK	 		0x0B
+#define UIL_ACT_UNBLOCK	 		0x0C
+#define UIL_ACT_RESET	 		0x80
+#define UIL_ACT_REBIND	 		0x81
+#define UIL_ACT_APPLY	 		0x82
+#define UIL_ACT_DISCONNECT		0x83	//;?040108 possibly obsolete	//Special for WINCE
+
+// HCF Specific
+/* Note that UIL_ACT-codes must match HCF_ACT-codes across a run-time bound I/F
+ * The initial matching is achieved by "#define HCF_ACT_xxx HCF_UIL_ACT_xxx" where appropriate
+ * In other words, these codes should never, ever change to minimize migration problems between
+ * combinations of old drivers and new utilities and vice versa
+ */
+#define HCF_DISCONNECT			0x01					//disconnect request for hcf_connect (invalid as IO Address)
+#define HCF_ACT_TALLIES 		0x05					// ! UIL_ACT_TALLIES does not exist ! Hermes Inquire Tallies (F100) cmd
+#if ( (HCF_TYPE) & HCF_TYPE_WARP ) == 0
+#define HCF_ACT_SCAN			MDD_ACT_SCAN
+#endif // HCF_TYPE_WARP
+#define HCF_ACT_PRS_SCAN		MDD_ACT_PRS_SCAN
+#if HCF_INT_ON
+#define HCF_ACT_INT_OFF 		0x0D					// Disable Interrupt generation
+#define HCF_ACT_INT_ON			0x0E					// Enable Interrupt generation
+#define HCF_ACT_INT_FORCE_ON	0x0F					// Enforce Enable Interrupt generation
+#endif // HCF_INT_ON
+#define HCF_ACT_RX_ACK			0x15					// Receiever ACK (optimization)
+#if (HCF_TYPE) & HCF_TYPE_CCX
+#define HCF_ACT_CCX_ON			0x1A					// enable CKIP
+#define HCF_ACT_CCX_OFF			0x1B					// disable CKIP
+#endif // HCF_TYPE_CCX
+#if (HCF_SLEEP) & HCF_DDS
+#define HCF_ACT_SLEEP			0x1C					// DDS Sleep request
+//#define HCF_ACT_WAKEUP		0x1D					// DDS Wakeup request
+#endif // HCF_DDS
+
+/*	HCF_ACT_MAX							// xxxx: start value for UIL-range, NOT to be passed to HCF
+ *										Too bad, there was originally no spare room created to use
+ *										HCF_ACT_MAX as an equivalent of HCF_ERR_MAX. Since creating
+ *										this room in retrospect would create a backward incompatibility
+ *										we will just have to live with the haphazard sequence of
+ *										UIL- and HCF specific codes. Theoretically this could be
+ *										corrected when and if there will ever be an overall
+ *										incompatibility introduced for another reason
+ */
+
+/*============================================================= HERMES RECORDS	============================*/
+#define CFG_RID_FW_MIN							0xFA00	//lowest value representing a Hermes-II based RID
+// #define CFG_PDA_BEGIN						0xFA	//
+// #define CFG_PDA_END							0xFA	//
+// #define CFG_PDA_NIC_TOP_LVL_ASSEMBLY_NUMBER	0xFA	//
+// #define CFG_PDA_PCB_TRACER_NUMBER			0xFA	//
+// #define CFG_PDA_RMM_TRACER_NUMBER			0xFA	//
+// #define CFG_PDA_RMM_COMP_ID					0xFA	//
+// #define CFG_PDA_								0xFA	//
+
+/*============================================================= CONFIGURATION RECORDS	=====================*/
+/*============================================================= mask 0xFCxx				=====================*/
+#define CFG_RID_CFG_MIN					0xFC00		//lowest value representing a Hermes configuration  RID
+
+//	NETWORK PARAMETERS, STATIC CONFIGURATION ENTITIES
+//FC05, FC0B, FC0C, FC0D: SEE W2DN149
+
+#define CFG_CNF_PORT_TYPE				0xFC00		//[STA] Connection control characteristics
+#define CFG_CNF_OWN_MAC_ADDR			0xFC01		//[STA] MAC Address of this node
+//										0xFC02		see DYNAMIC CONFIGURATION ENTITIES
+#define CFG_CNF_OWN_CHANNEL				0xFC03		//Communication channel for BSS creation
+#define CFG_CNF_OWN_SSID				0xFC04		//IBSS creation (STA) or ESS (AP) Service Set Ident
+#define CFG_CNF_OWN_ATIM_WINDOW			0xFC05		//[STA] ATIM Window time for IBSS creation
+#define CFG_CNF_SYSTEM_SCALE			0xFC06		//System Scale that specifies the AP density
+#define CFG_CNF_MAX_DATA_LEN			0xFC07		//Maximum length of MAC Frame Body data
+#define CFG_CNF_PM_ENABLED				0xFC09		//[STA] Switch for ESS Power Management (PM)
+#define CFG_CNF_MCAST_RX				0xFC0B		//[STA] Switch for ESS PM Multicast reception On/Off
+#define CFG_CNF_MAX_SLEEP_DURATION		0xFC0C		//[STA] Maximum sleep time for ESS PM
+#define CFG_CNF_HOLDOVER_DURATION		0xFC0D		//[STA] Holdover time for ESS PM
+#define CFG_CNF_OWN_NAME				0xFC0E		//Identification text for diagnostic purposes
+
+#define CFG_CNF_OWN_DTIM_PERIOD			0xFC10		//[AP] Beacon intervals between successive DTIMs
+#define CFG_CNF_WDS_ADDR1				0xFC11		//[AP] Port 1 MAC Adrs of corresponding WDS Link node
+#define CFG_CNF_WDS_ADDR2				0xFC12		//[AP] Port 2 MAC Adrs of corresponding WDS Link node
+#define CFG_CNF_WDS_ADDR3				0xFC13		//[AP] Port 3 MAC Adrs of corresponding WDS Link node
+#define CFG_CNF_WDS_ADDR4				0xFC14		//[AP] Port 4 MAC Adrs of corresponding WDS Link node
+#define CFG_CNF_WDS_ADDR5				0xFC15		//[AP] Port 5 MAC Adrs of corresponding WDS Link node
+#define CFG_CNF_WDS_ADDR6				0xFC16		//[AP] Port 6 MAC Adrs of corresponding WDS Link node
+#define CFG_CNF_PM_MCAST_BUF			0xFC17		//[AP] Switch for PM buffereing of Multicast Messages
+#define CFG_CNF_MCAST_PM_BUF			CFG_CNF_PM_MCAST_BUF	//name does not match H-II spec
+#define CFG_CNF_REJECT_ANY				0xFC18		//[AP] Switch for PM buffereing of Multicast Messages
+
+#define CFG_CNF_ENCRYPTION				0xFC20		//select en/de-cryption of Tx/Rx messages
+#define CFG_CNF_AUTHENTICATION			0xFC21		//[STA] selects Authentication algorithm
+#define CFG_CNF_EXCL_UNENCRYPTED		0xFC22		//[AP] Switch for 'clear-text' rx message acceptance
+#define CFG_CNF_MCAST_RATE				0xFC23		//Transmit Data rate for Multicast frames
+#define CFG_CNF_INTRA_BSS_RELAY			0xFC24		//[AP] Switch for IntraBBS relay
+#define CFG_CNF_MICRO_WAVE				0xFC25		//MicroWave (Robustness)
+#define CFG_CNF_LOAD_BALANCING		 	0xFC26		//Load Balancing		 (Boolean, 0=OFF, 1=ON, default=1)
+#define CFG_CNF_MEDIUM_DISTRIBUTION	 	0xFC27		//Medium Distribution	 (Boolean, 0=OFF, 1=ON, default=1)
+#define CFG_CNF_RX_ALL_GROUP_ADDR		0xFC28		//[STA] Group Address Filter
+#define CFG_CNF_COUNTRY_INFO			0xFC29		//Country Info
+#if (HCF_TYPE) & HCF_TYPE_WARP
+#define CFG_CNF_TX_POW_LVL				0xFC2A		//TxPower Level
+#define CFG_CNF_CONNECTION_CNTL			0xFC30		//[STA] Connection Control
+#define CFG_CNF_OWN_BEACON_INTERVAL		0xFC31		//[AP]
+#define CFG_CNF_SHORT_RETRY_LIMIT		0xFC32		//
+#define CFG_CNF_LONG_RETRY_LIMIT		0xFC33		//
+#define CFG_CNF_TX_EVENT_MODE			0xFC34		//
+#define CFG_CNF_WIFI_COMPATIBLE			0xFC35		//[STA] Wifi compatible
+#endif // HCF_TYPE_WARP
+#if (HCF_TYPE) & HCF_TYPE_BEAGLE_HII5
+#define CFG_VOICE_RETRY_LIMIT			0xFC36		/* Voice frame retry limit. Range: 1-15, default: 4 */
+#define CFG_VOICE_CONTENTION_WINDOW		0xFC37		/* Contention window for voice frames. */
+#endif	// BEAGLE_HII5
+
+//	NETWORK PARAMETERS, DYNAMIC CONFIGURATION ENTITIES
+#define CFG_DESIRED_SSID				0xFC02		//[STA] Service Set identification for connection and scan
+
+#define CFG_GROUP_ADDR					0xFC80		//[STA] Multicast MAC Addresses for Rx-message
+#define CFG_CREATE_IBSS					0xFC81		//[STA] Switch for IBSS creation On/Off
+#define CFG_RTS_THRH					0xFC83		//Frame length used for RTS/CTS handshake
+#define CFG_TX_RATE_CNTL				0xFC84		//[STA] Data rate control for message transmission
+#define CFG_PROMISCUOUS_MODE			0xFC85		//[STA] Switch for Promiscuous mode reception On/Off
+#define CFG_WOL							0xFC86		//[STA] Switch for Wake-On-LAN mode
+#define CFG_WOL_PATTERNS				0xFC87		//[STA] Patterns for Wake-On-LAN
+#define CFG_SUPPORTED_RATE_SET_CNTL		0xFC88		//
+#define CFG_BASIC_RATE_SET_CNTL			0xFC89		//
+
+#define CFG_SOFTWARE_ACK_MODE			0xFC90		//
+#define CFG_RTS_THRH0					0xFC97		//[AP] Port 0 frame length for RTS/CTS handshake
+#define CFG_RTS_THRH1					0xFC98		//[AP] Port 1 frame length for RTS/CTS handshake
+#define CFG_RTS_THRH2					0xFC99		//[AP] Port 2 frame length for RTS/CTS handshake
+#define CFG_RTS_THRH3					0xFC9A		//[AP] Port 3 frame length for RTS/CTS handshake
+#define CFG_RTS_THRH4					0xFC9B		//[AP] Port 4 frame length for RTS/CTS handshake
+#define CFG_RTS_THRH5					0xFC9C		//[AP] Port 5 frame length for RTS/CTS handshake
+#define CFG_RTS_THRH6					0xFC9D		//[AP] Port 6 frame length for RTS/CTS handshake
+
+#define CFG_TX_RATE_CNTL0				0xFC9E		//[AP] Port 0 data rate control for transmission
+#define CFG_TX_RATE_CNTL1				0xFC9F		//[AP] Port 1 data rate control for transmission
+#define CFG_TX_RATE_CNTL2				0xFCA0		//[AP] Port 2 data rate control for transmission
+#define CFG_TX_RATE_CNTL3				0xFCA1		//[AP] Port 3 data rate control for transmission
+#define CFG_TX_RATE_CNTL4				0xFCA2		//[AP] Port 4 data rate control for transmission
+#define CFG_TX_RATE_CNTL5				0xFCA3		//[AP] Port 5 data rate control for transmission
+#define CFG_TX_RATE_CNTL6				0xFCA4		//[AP] Port 6 data rate control for transmission
+
+#define CFG_DEFAULT_KEYS				0xFCB0		//defines set of encryption keys
+#define CFG_TX_KEY_ID					0xFCB1		//select key for encryption of Tx messages
+#define CFG_SCAN_SSID					0xFCB2		//Scan SSID
+#define CFG_ADD_TKIP_DEFAULT_KEY		0xFCB4		//set KeyID and TxKey indication
+#define 	KEY_ID							0x0003		//KeyID mask for tkip_key_id_info field
+#define 	TX_KEY							0x8000		//Default Tx Key flag of tkip_key_id_info field
+#define CFG_SET_WPA_AUTH_KEY_MGMT_SUITE	0xFCB5		//Authenticated Key Management Suite
+#define CFG_REMOVE_TKIP_DEFAULT_KEY		0xFCB6		//invalidate KeyID and TxKey indication
+#define CFG_ADD_TKIP_MAPPED_KEY			0xFCB7		//set MAC address pairwise station
+#define CFG_REMOVE_TKIP_MAPPED_KEY		0xFCB8		//invalidate MAC address pairwise station
+#define CFG_SET_WPA_CAPABILITIES_INFO	0xFCB9		//WPA Capabilities
+#define CFG_CACHED_PMK_ADDR				0xFCBA		//set MAC address of pre-authenticated AP
+#define CFG_REMOVE_CACHED_PMK_ADDR		0xFCBB		//invalidate MAC address of pre-authenticated AP
+#define CFG_FCBC	0xFCBC	//FW codes ahead of available documentation, so ???????
+#define CFG_FCBD	0xFCBD	//FW codes ahead of available documentation, so ???????
+#define CFG_FCBE	0xFCBE	//FW codes ahead of available documentation, so ???????
+#define CFG_FCBF	0xFCBF	//FW codes ahead of available documentation, so ???????
+
+#define CFG_HANDOVER_ADDR				0xFCC0		//[AP] Station MAC Adrress re-associated with other AP
+#define CFG_SCAN_CHANNEL				0xFCC2		//Channel set for host requested scan
+//;?#define CFG_SCAN_CHANNEL_MASK			0xFCC2		// contains
+#define CFG_DISASSOCIATE_ADDR			0xFCC4		//[AP] Station MAC Adrress to be disassociated
+#define CFG_PROBE_DATA_RATE				0xFCC5		//WARP connection control
+#define CFG_FRAME_BURST_LIMIT			0xFCC6		//
+#define CFG_COEXISTENSE_BEHAVIOUR		0xFCC7		//[AP]
+#define CFG_DEAUTHENTICATE_ADDR			0xFCC8		//MAC address of Station to be deauthenticated
+
+//	BEHAVIOR PARAMETERS
+#define CFG_TICK_TIME					0xFCE0		//Auxiliary Timer tick interval
+#define CFG_DDS_TICK_TIME				0xFCE1		//Disconnected DeepSleep Timer tick interval
+//#define CFG_CNF_COUNTRY					0xFCFE	apparently not needed ;?
+#define CFG_RID_CFG_MAX					0xFCFF		//highest value representing an Configuration RID
+
+
+/*============================================================= INFORMATION RECORDS 	=====================*/
+/*============================================================= mask 0xFDxx				=====================*/
+//	NIC INFORMATION
+#define CFG_RID_INF_MIN					0xFD00	//lowest value representing an Information RID
+#define CFG_MAX_LOAD_TIME				0xFD00	//[INT] Maximum response time of the Download command.
+#define CFG_DL_BUF						0xFD01	//[INT] Download buffer location and size.
+#define CFG_PRI_IDENTITY				0xFD02	//[PRI] Primary Functions firmware identification.
+#define CFG_PRI_SUP_RANGE				0xFD03	//[PRI] Primary Functions I/F Supplier compatibility range.
+#define CFG_NIC_HSI_SUP_RANGE			0xFD09	//H/W - S/W I/F supplier range
+#define CFG_NIC_SERIAL_NUMBER			0xFD0A	//[PRI] Network Interface Card serial number.
+#define CFG_NIC_IDENTITY				0xFD0B	//[PRI] Network Interface Card identification.
+#define CFG_NIC_MFI_SUP_RANGE			0xFD0C	//[PRI] Modem I/F Supplier compatibility range.
+#define CFG_NIC_CFI_SUP_RANGE			0xFD0D	//[PRI] Controller I/F Supplier compatibility range.
+#define CFG_CHANNEL_LIST				0xFD10	//Allowed communication channels.
+#define CFG_NIC_TEMP_TYPE  				0xFD12	//Hardware temperature range code.
+#define CFG_CIS							0xFD13	//PC Card Standard Card Information Structure
+#define CFG_NIC_PROFILE					0xFD14	//Card Profile
+#define CFG_FW_IDENTITY					0xFD20	//firmware identification.
+#define CFG_FW_SUP_RANGE				0xFD21	//firmware Supplier compatibility range.
+#define CFG_MFI_ACT_RANGES_STA			0xFD22	//[STA] Modem I/F Actor compatibility ranges.
+#define CFG_CFI_ACT_RANGES_STA			0xFD23	//[STA] Controller I/F Actor compatibility ranges.
+#define CFG_NIC_BUS_TYPE				0xFD24	//Card Bustype
+#define 	CFG_NIC_BUS_TYPE_PCCARD_CF		0x0000	//16 bit PC Card or Compact Flash
+#define 	CFG_NIC_BUS_TYPE_USB			0x0001	//USB
+#define 	CFG_NIC_BUS_TYPE_CARDBUS		0x0002	//CardBus
+#define 	CFG_NIC_BUS_TYPE_PCI			0x0003	//(mini)PCI
+#define CFG_DOMAIN_CODE						0xFD25
+
+//	MAC INFORMATION
+#define CFG_PORT_STAT					0xFD40	//Actual MAC Port connection control status
+#define CFG_CUR_SSID					0xFD41	//[STA] Identification of the actually connected SS
+#define CFG_CUR_BSSID					0xFD42	//[STA] Identification of the actually connected BSS
+#define CFG_COMMS_QUALITY				0xFD43	//[STA] Quality of the Basic Service Set connection
+#define CFG_CUR_TX_RATE					0xFD44	//[STA] Actual transmit data rate
+#define CFG_CUR_BEACON_INTERVAL			0xFD45	//Beacon transmit interval time for BSS creation
+#define CFG_CUR_SCALE_THRH				0xFD46	//Actual System Scale thresholds settings
+#define CFG_PROTOCOL_RSP_TIME			0xFD47	//Max time to await a response to a request message
+#define CFG_CUR_SHORT_RETRY_LIMIT		0xFD48	//Max number of transmit attempts for short frames
+#define CFG_CUR_LONG_RETRY_LIMIT		0xFD49	//Max number of transmit attempts for long frames
+#define CFG_MAX_TX_LIFETIME				0xFD4A	//Max transmit frame handling duration
+#define CFG_MAX_RX_LIFETIME				0xFD4B	//Max received frame handling duration
+#define CFG_CF_POLLABLE					0xFD4C	//[STA] Contention Free pollable capability indication
+#define CFG_AUTHENTICATION_ALGORITHMS	0xFD4D	//Available Authentication Algorithms indication
+#define CFG_PRIVACY_OPT_IMPLEMENTED		0xFD4F	//WEP Option availability indication
+
+#define CFG_CUR_REMOTE_RATES			0xFD50	//[STA] CurrentRemoteRates
+#define CFG_CUR_USED_RATES				0xFD51	//[STA] CurrentUsedRates
+#define CFG_CUR_SYSTEM_SCALE			0xFD52	//[STA] CurrentSystemScale
+
+#define CFG_CUR_TX_RATE1				0xFD80	//[AP] Actual Port 1 transmit data rate
+#define CFG_CUR_TX_RATE2				0xFD81	//[AP] Actual Port 2 transmit data rate
+#define CFG_CUR_TX_RATE3				0xFD82	//[AP] Actual Port 3 transmit data rate
+#define CFG_CUR_TX_RATE4				0xFD83	//[AP] Actual Port 4 transmit data rate
+#define CFG_CUR_TX_RATE5				0xFD84	//[AP] Actual Port 5 transmit data rate
+#define CFG_CUR_TX_RATE6				0xFD85	//[AP] Actual Port 6 transmit data rate
+#define CFG_NIC_MAC_ADDR				0xFD86	//Unique local node MAC Address
+#define CFG_PCF_INFO					0xFD87	//[AP] Point Coordination Function capability info
+//*RESERVED* #define CFG_HIGHEST_BASIC_RATE			0xFD88	//
+#define CFG_CUR_COUNTRY_INFO			0xFD89	//
+#define CFG_CUR_SSN_INFO_ELEMENT		0xFD8A	//
+#define CFG_CUR_TKIP_IV_INFO			0xFD8B	//
+#define CFG_CUR_ASSOC_REQ_INFO			0xFD8C	//
+#define CFG_CUR_ASSOC_RESP_INFO			0xFD8D	//
+#define CFG_CUR_LOAD					0xFD8E	//[AP] current load on AP's channel
+
+#define CFG_SECURITY_CAPABILITIES		0xFD90	//Combined capabilities information
+
+//	MODEM INFORMATION
+#define CFG_PHY_TYPE					0xFDC0	//Physical layer type indication
+#define CFG_CUR_CHANNEL					0xFDC1	//Actual frequency channel used for transmission
+#define CFG_CUR_POWER_STATE				0xFDC2	//Actual power consumption status
+#define CFG_CCA_MODE					0xFDC3	//Clear channel assessment mode indication
+#define CFG_SUPPORTED_DATA_RATES		0xFDC6	//Data rates capability information
+
+#define CFG_RID_INF_MAX					0xFDFF	//highest value representing an Information RID
+
+//	ENGINEERING INFORMATION
+#define CFG_RID_ENG_MIN					0xFFE0	//lowest value representing a Hermes engineering RID
+
+
+/****************************** General define *************************************************************/
+
+
+//IFB field related
+//		IFB_CardStat
+#define CARD_STAT_INCOMP_PRI			0x2000U	// no compatible HSI / primary F/W
+#define CARD_STAT_INCOMP_FW				0x1000U	// no compatible station / tertiary F/W
+#define CARD_STAT_DEFUNCT				0x0100U	// HCF is in Defunct mode
+//		IFB_RxStat
+#define RX_STAT_PRIO					0x00E0U	//Priority subfield
+#define RX_STAT_ERR						0x000FU	//Error mask
+#define 	RX_STAT_UNDECR				0x0002U	//Non-decryptable encrypted message
+#define 	RX_STAT_FCS_ERR				0x0001U	//FCS error
+
+// SNAP header for E-II Encapsulation
+#define ENC_NONE			            0xFF
+#define ENC_1042    			        0x00
+#define ENC_TUNNEL      	    		0xF8
+/****************************** Xxxxxxxx *******************************************************************/
+
+
+#define HCF_SUCCESS					0x00	// OK
+#define HCF_ERR_TIME_OUT			0x04	// Expected Hermes event did not occure in expected time
+#define HCF_ERR_NO_NIC				0x05	/* card not found (usually yanked away during hcfio_in_string
+										  	 * Also: card is either absent or disabled while it should be neither */
+#define HCF_ERR_LEN					0x08	/* buffer size insufficient
+		 								  	 *		  -	IFB_ConfigTable too small
+		 								  	 *		  -	hcf_get_info buffer has a size of 0 or 1 or less than needed
+		 							  		 *			to accomodate all data
+		 							  		 *		  -	hcf_put_info: CFG_DLNV_DATA exceeds intermediate
+											 *		  buffer size */
+#define HCF_ERR_INCOMP_PRI			0x09	// primary functions are not compatible
+#define HCF_ERR_INCOMP_FW			0x0A	// station functions are compatible
+#define HCF_ERR_MIC					0x0D	// MIC check fails
+#define HCF_ERR_SLEEP				0x0E	// NIC in sleep mode
+#define HCF_ERR_MAX					0x3F	/* end of HCF range
+											   *** ** *** ****** *** *************** */
+#define HCF_ERR_DEFUNCT				0x80	// BIT, reflecting that the HCF is in defunct mode (bits 0x7F reflect cause)
+#define HCF_ERR_DEFUNCT_AUX			0x82	// Timeout on acknowledgement on en/disabling AUX registers
+#define HCF_ERR_DEFUNCT_TIMER		0x83	// Timeout on timer calibration during initialization process
+#define HCF_ERR_DEFUNCT_TIME_OUT	0x84	// Timeout on Busy bit drop during BAP setup
+#define HCF_ERR_DEFUNCT_CMD_SEQ		0x86	// Hermes and HCF are out of sync in issuing/processing commands
+
+#define HCF_INT_PENDING				0x01	// return status of hcf_act( HCF_ACT_INT_OFF )
+
+#define HCF_PORT_0 					0x0000	// Station supports only single MAC Port
+#define HCF_PORT_1 					0x0100	// HCF_PORT_1 through HCF_PORT_6 are only supported by AP F/W
+#define HCF_PORT_2 					0x0200
+#define HCF_PORT_3 					0x0300
+#define HCF_PORT_4 					0x0400
+#define HCF_PORT_5 					0x0500
+#define HCF_PORT_6 					0x0600
+
+#define HCF_CNTL_ENABLE				0x01
+#define HCF_CNTL_DISABLE			0x02
+#define HCF_CNTL_CONNECT			0x03
+#define HCF_CNTL_DISCONNECT			0x05
+#define HCF_CNTL_CONTINUE			0x07
+
+#define USE_DMA 					0x0001
+#define USE_16BIT 					0x0002
+#define DMA_ENABLED					0x8000	//weak name, it really means: F/W enabled and DMA selected
+
+//#define HCF_DMA_FD_CNT	 		(2*29) 						//size in bytes of one Tx/RxFS minus DA/SA
+//;?the MSF ( H2PCI.C uses the next 2 mnemonics )
+#define HCF_DMA_RX_BUF1_SIZE		(HFS_ADDR_DEST + 8)			//extra bytes for LEN/SNAP if decapsulation
+#define HCF_DMA_TX_BUF1_SIZE		(HFS_ADDR_DEST + 2*6 + 8)	//extra bytes for DA/SA/LEN/SNAP if encapsulation
+
+//HFS_TX_CNTL
+/* Note that the HCF_.... System Constants influence the HFS_.... values below
+ * 								H-I		H-I	 |	H-II	H-II	H-II.5
+ *										WPA	 |			WPA
+ * HFS_TX_CNTL_TX_OK			0002	0002 |	0002	0002	 N/A	<<<<<<<<deprecated
+ * HFS_TX_CNTL_TX_EX			0004	0004 |	0004	0004	 N/A
+ * HFS_TX_CNTL_MIC				 N/A	0010 |	 N/A	0010	 N/A
+ * HFS_TX_CNTL_TID				 N/A	 N/A |	 N/A	 N/A	000F
+ * HFS_TX_CNTL_SERVICE_CLASS	 N/A	 N/A |	 N/A	 N/A	00C0
+ * HFS_TX_CNTL_PORT				0700	0700 |	0700	0700	0700
+ * HFS_TX_CNTL_MIC_KEY_ID		1800	1800 |	0000	1800	 N/A
+ * HFS_TX_CNTL_CKIP				0000	0000 |	0000	2000	2000
+ * HFS_TX_CNTL_TX_DELAY			4000	4000 |	4000	4000	 N/A
+ * HFS_TX_CNTL_ACTION			 N/A	 N/A |	 N/A	 N/A	4000
+ * 								====	==== |	====	====	====
+ * 								5F06	5F16 |	4706	7F06	67CF
+ *
+ * HCF_TX_CNTL_MASK specifies the bits allowed on the Host I/F
+ * note: bit 0x4000 has different meaning for H-II and H-II.5
+ * note: [] indicate bits which are possibly added by the HCF to TxControl at the Host I/F
+ * note: () indicate bits which are supposedly never ever used in a WCI environment
+ * note: ? denote bits which seem not to be documented in the documents I have available
+ */
+//H-I:     HCF_TX_CNTL_MASK	0x47FE	//TX_DELAY, MACPort, Priority, (StrucType), TxEx, TxOK
+//H-I WPA: HCF_TX_CNTL_MASK	0x5FE6	//TX_DELAY, MICKey, MACPort, Priority, (StrucType), TxEx, TxOK
+#if (HCF_TYPE) & HCF_TYPE_WARP
+#define  HCF_TX_CNTL_MASK	0x27E7	//no TX_DELAY?, CCX, MACPort, Priority, (StrucType), TxEx, TxOK, Spectralink
+//#elif (HCF_TYPE) & HCF_TYPE_WPA
+//#define  HCF_TX_CNTL_MASK	0x7F06	//TX_DELAY, CKIP?, MICKeyID, MACPort, [MIC],TxEx, TxOK (TAR419D7)
+#else
+#define  HCF_TX_CNTL_MASK	0x67E7	//TX_DELAY?, CCX, MACPort, Priority, (StrucType), TxEx, TxOK, Spectralink
+#endif // HCF_TYPE_WARP
+
+#define HFS_TX_CNTL_TX_EX			0x0004U
+
+#if (HCF_TYPE) & HCF_TYPE_WPA
+#define HFS_TX_CNTL_MIC				0x0010U	//802.3 format with TKIP		;?changes to 0x0008 for H-II
+#define HFS_TX_CNTL_MIC_KEY_ID		0x1800U	//MIC Key ID subfield
+#endif // HCF_TYPE_WPA
+
+#define HFS_TX_CNTL_PORT			0x0700U	//Port subfield of TxControl field of Transmit Frame Structure
+
+#if (HCF_TYPE) & HCF_TYPE_CCX
+#define HFS_TX_CNTL_CKIP			0x2000U	//CKIP encrypted flag
+#endif // HCF_TYPE_CCX
+
+#if (HCF_TYPE) & HCF_TYPE_TX_DELAY
+#define HFS_TX_CNTL_TX_DELAY		0x4000U	//decouple "put data" and send
+#endif // HCF_TYPE_TX_DELAY
+#define HFS_TX_CNTL_TX_CONT			0x4000u	//engineering: continuous transmit
+
+/*============================================================= HCF Defined RECORDS	=========================*/
+#define CFG_PROD_DATA					0x0800 		//Plug Data (Engineering Test purposes only)
+#define CFG_DL_EEPROM					0x0806		//Up/Download I2PROM for USB
+#define		CFG_PDA							0x0002		//Download PDA
+#define		CFG_MEM_I2PROM					0x0004		//Up/Download EEPROM
+
+#define		CFG_MEM_READ					0x0000
+#define		CFG_MEM_WRITE					0x0001
+
+#define CFG_NULL						0x0820		//Empty Mail Box Info Block
+#define CFG_MB_INFO						0x0820		//Mail Box Info Block
+#define CFG_WMP							0x0822		//WaveLAN Management Protocol
+
+#if defined MSF_COMPONENT_ID
+#define CFG_DRV_INFO					0x0825		//Driver Information structure (see CFG_DRV_INFO_STRCT for details)
+#define CFG_DRV_IDENTITY				0x0826		//driver identity (see CFG_DRV_IDENTITY_STRCT for details)
+#define CFG_DRV_SUP_RANGE				0x0827      //Supplier range of driver - utility I/F
+#define CFG_DRV_ACT_RANGES_PRI			0x0828      //(Acceptable) Actor range for Primary Firmware - driver I/F
+#define CFG_DRV_ACT_RANGES_STA			0x0829      //(Acceptable) Actor range for Station Firmware - driver I/F
+#define CFG_DRV_ACT_RANGES_HSI 			0x082A      //(Acceptable) Actor range for H/W - driver I/F
+#define CFG_DRV_ACT_RANGES_APF			0x082B		//(Acceptable) Actor range for AP Firmware - driver I/F
+#define CFG_HCF_OPT						0x082C		//HCF (Compile time) options
+#endif // MSF_COMPONENT_ID
+
+#define CFG_REG_MB						0x0830		//Register Mail Box
+#define CFG_MB_ASSERT					0x0831		//Assert information
+#define CFG_REG_ASSERT_RTNP				0x0832		//(de-)register MSF Assert Callback routine
+#if (HCF_EXT) & HCF_EXT_INFO_LOG
+#define CFG_REG_INFO_LOG				0x0839		//(de-)register Info frames to Log
+#endif // HCF_INFO_LOG
+#define CFG_CNTL_OPT					0x083A		//Control options
+
+#define CFG_PROG						0x0857		//Program NIC memory
+#define 	CFG_PROG_STOP					0x0000
+#define 	CFG_PROG_VOLATILE				0x0100
+//#define 	CFG_PROG_FLASH					0x0300		//restore if H-II non-volatile is introduced
+//#define 	CFG_PROG_SEEPROM				0x1300		//restore if H-II non-volatile is introduced
+#define 	CFG_PROG_SEEPROM_READBACK 		0x0400
+
+#define CFG_FW_PRINTF                       0x0858      //Related to firmware debug printf functionality
+#define CFG_FW_PRINTF_BUFFER_LOCATION       0x0859      //Also related to firmware debug printf functionality
+
+#define CFG_CMD_NIC						0x0860		//Hermes Engineering command
+#define CFG_CMD_HCF						0x0863		//HCF Engineering command
+#define 	CFG_CMD_HCF_REG_ACCESS			0x0000	//Direct register access
+#define 	CFG_CMD_HCF_RX_MON				0x0001	//Rx-monitor
+
+
+/*============================================================= MSF Defined RECORDS	========================*/
+#define CFG_ENCRYPT_STRING				0x0900		//transfer encryption info from CPL to MSF
+#define CFG_AP_MODE						0x0901		//control mode of STAP driver from CPL
+#define CFG_DRIVER_ENABLE				0x0902		//extend&export En-/Disable facility to Utility
+#define CFG_PCI_COMMAND					0x0903		//PCI adapter (Ooievaar) structure
+#define CFG_WOLAS_ENABLE				0x0904		//extend&export En-/Disable WOLAS facility to Utility
+#define CFG_COUNTRY_STRING				0x0905		//transfer CountryInfo info from CPL to MSF
+#define CFG_FW_DUMP						0x0906		//transfer nic memory to utility
+#define CFG_POWER_MODE					0x0907		//controls the PM mode of the card
+#define CFG_CONNECTION_MODE				0x0908		//controls the mode of the FW (ESS/AP/IBSS/ADHOC)
+#define CFG_IFB							0x0909		//byte wise copy of IFB
+#define CFG_MSF_TALLIES					0x090A		//MSF tallies (int's, rx and tx)
+#define CFG_CURRENT_LINK_STATUS			0x090B		//Latest link status got trough 0xF200 LinkEvent
+
+/*============================================================ INFORMATION FRAMES =========================*/
+#define CFG_INFO_FRAME_MIN				0xF000		//lowest value representing an Informatio Frame
+
+#define CFG_TALLIES						0xF100		//Communications Tallies
+#define CFG_SCAN						0xF101		//Scan results
+#define CFG_PRS_SCAN					0xF102		//Probe Response Scan results
+
+#define CFG_LINK_STAT 					0xF200		//Link Status
+	/* 1 through 5 are F/W defined values, produced by CFG_LINK_STAT frame
+	 * 1 through 5 are shared by CFG_LINK_STAT, IFB_LinkStat and IFB_DSLinkStat
+	 * 1 plays a double role as CFG_LINK_STAT_CONNECTED and as bit reflecting:
+	 *	 - connected: ON
+	 *	 - disconnected: OFF
+	 */
+#define 	CFG_LINK_STAT_CONNECTED			0x0001
+#define 	CFG_LINK_STAT_DISCONNECTED		0x0002
+#define 	CFG_LINK_STAT_AP_CHANGE			0x0003
+#define 	CFG_LINK_STAT_AP_OOR			0x0004
+#define 	CFG_LINK_STAT_AP_IR				0x0005
+#define 	CFG_LINK_STAT_FW				0x000F	//mask to isolate F/W defined bits
+//#define 	CFG_LINK_STAT_TIMER				0x0FF0	//mask to isolate OOR timer
+//#define 	CFG_LINK_STAT_DS_OOR			0x2000	//2000 and up are IFB_LinkStat specific
+//#define 	CFG_LINK_STAT_DS_IR				0x4000
+#define 	CFG_LINK_STAT_CHANGE			0x8000
+#define CFG_ASSOC_STAT					0xF201		//Association Status
+#define CFG_SECURITY_STAT				0xF202		//Security Status
+#define CFG_UPDATED_INFO_RECORD			0xF204		//Updated Info Record
+
+/*============================================================ CONFIGURATION RECORDS ======================*/
+/***********************************************************************************************************/
+
+/****************************** S T R U C T U R E   D E F I N I T I O N S **********************************/
+
+//Quick&Dirty to get download for DOS ODI Hermes-II running typedef LTV_STRCT FAR *	LTVP;
+typedef LTV_STRCT FAR *	LTVP;   // i.s.o #define LTVP LTV_STRCT FAR *
+
+#if defined WVLAN_42 || defined WVLAN_43 //;?keepup with legacy a little while longer (4aug2003)
+typedef struct DUI_STRCT {			/* "legacy", still used by WVLAN42/43, NDIS drivers use WLAPI			*/
+	void  FAR	*ifbp;				/* Pointer to IFB
+									 *	returned from MSF to USF by uil_connect
+				 					 *	passed from USF to MSF as a "magic cookie" by all other UIL function calls
+				 					 */
+	hcf_16		stat;				// status returned from MSF to USF
+	hcf_16		fun;				// command code from USF to MSF
+	LTV_STRCT	ltv;				/* LTV structure
+			 						 *** during uil_put_info:
+						 			 *	  the L, T and V-fields carry information from USF to MSF
+									 *** during uil_get_info:
+									 *	  the L and T fields carry information from USF to MSF
+									 *	  the L and V-fields carry information from MSF to USF
+			 						 */
+} DUI_STRCT;
+typedef DUI_STRCT FAR *	DUIP;
+#endif //defined WVLAN_42 || defined WVLAN_43 //;?keepup with legacy a liitle while longer (4aug2003)
+
+
+typedef struct CFG_CMD_NIC_STRCT {	// CFG_CMD_NIC (0x0860)		Hermes Engineering command
+	hcf_16	len;					//default length of RID
+	hcf_16	typ;					//RID identification as defined by Hermes
+	hcf_16	cmd;					//Command code (0x003F) and control bits (0xFFC0)
+	hcf_16	parm0;					//parameters for Hermes Param0 register
+	hcf_16	parm1;					//parameters for Hermes Param1 register
+	hcf_16	parm2;					//parameters for Hermes Param2 register
+	hcf_16	stat;					//result code from Hermes Status register
+	hcf_16	resp0;					//responses from Hermes Resp0 register
+	hcf_16	resp1;					//responses from Hermes Resp1 register
+	hcf_16	resp2;					//responses from Hermes Resp2 register
+	hcf_16	hcf_stat;				//result code from cmd_exe routine
+	hcf_16	ifb_err_cmd;			//IFB_ErrCmd
+	hcf_16	ifb_err_qualifier;		//IFB_ErrQualifier
+} CFG_CMD_NIC_STRCT;
+
+
+typedef struct CFG_DRV_INFO_STRCT {		//CFG_DRV_INFO (0x0825) driver information
+	hcf_16	len;					//default length of RID
+	hcf_16	typ;					//RID identification as defined by Hermes
+	hcf_8	driver_name[8];			//Driver name, 8 bytes, right zero padded
+	hcf_16	driver_version;			//BCD 2 digit major and 2 digit minor driver version
+	hcf_16	HCF_version;   			//BCD 2 digit major and 2 digit minor HCF version
+	hcf_16	driver_stat;			//
+	hcf_16	IO_address;				//base IO address used by NIC
+	hcf_16	IO_range;				//range of IO addresses used by NIC
+	hcf_16	IRQ_number;				//Interrupt used by NIC
+	hcf_16	card_stat;				/*NIC status
+									@*	0x8000	Card present
+									@*	0x4000	Card Enabled
+									@*	0x2000	Driver incompatible with NIC Primary Functions
+									@*	0x1000	Driver incompatible with NIC Station Functions				*/
+	hcf_16	frame_type;				/*Frame type
+									@*	0x000	802.3
+									@*	0x008	802.11														*/
+	hcf_32	drv_info;				/*driver specific info
+									 * CE: virtual I/O base													*/
+}CFG_DRV_INFO_STRCT;
+
+#define COMP_ID_FW_PRI					21		//Primary Functions Firmware
+#define COMP_ID_FW_INTERMEDIATE			22		//Intermediate Functions Firmware
+#define COMP_ID_FW_STA					31		//Station Functions Firmware
+#define COMP_ID_FW_AP					32		//AP Functions Firmware
+#define COMP_ID_FW_AP_FAKE			   331		//AP Functions Firmware
+
+#define COMP_ID_MINIPORT_NDIS_31		41		//Windows 9x/NT Miniport NDIS 3.1
+#define COMP_ID_PACKET					42		//Packet
+#define COMP_ID_ODI_16					43		//DOS ODI
+#define COMP_ID_ODI_32					44		//32-bits ODI
+#define COMP_ID_MAC_OS					45		//Macintosh OS
+#define COMP_ID_WIN_CE					46		//Windows CE Miniport
+//#define COMP_ID_LINUX_PD				47		//Linux, HCF-light based, MSF source code in Public Domain
+#define COMP_ID_MINIPORT_NDIS_50		48		//Windows 9x/NT Miniport NDIS 5.0
+#define COMP_ID_LINUX					49		/*Linux, GPL'ed HCF based, full source code in Public Domain
+										  		 *thanks to Andreas Neuhaus								*/
+#define COMP_ID_QNX						50		//QNX
+#define COMP_ID_MINIPORT_NDIS_50_USB	51		//Windows 9x/NT Miniport NDIS 4.0
+#define COMP_ID_MINIPORT_NDIS_40		52		//Windows 9x/NT Miniport NDIS 4.0
+#define COMP_ID_VX_WORKS_ENDSTA			53		// VxWorks END Station driver
+#define COMP_ID_VX_WORKS_ENDAP			54		// VxWorks END Access Point driver
+//;?#define COMP_ID_MAC_OS_????			55		//;?check with HM
+#define COMP_ID_VX_WORKS_END			56		// VxWorks END Station/Access Point driver
+//										57		//NucleusOS@ARM Driver.
+#define COMP_ID_WSU						63		/* WaveLAN Station Firmware Update utility
+												 *	variant 1: Windows
+												 *	variant 2: DOS
+												 */
+#define COMP_ID_AP1						81		//WaveLAN/IEEE AP
+#define COMP_ID_EC						83		//WaveLAN/IEEE Ethernet Converter
+#define COMP_ID_UBL						87		//USB Boot Loader
+
+#define COMP_ROLE_SUPL					0x00	//supplier
+#define COMP_ROLE_ACT					0x01	//actor
+
+												//Supplier			  - actor
+#define COMP_ID_MFI						0x01	//Modem		 		  - Firmware	I/F
+#define COMP_ID_CFI						0x02	//Controller		  - Firmware	I/F
+#define COMP_ID_PRI						0x03	//Primary Firmware	  - Driver		I/F
+#define COMP_ID_STA						0x04	//Station Firmware	  - Driver		I/F
+#define COMP_ID_DUI						0x05	//Driver			  - Utility		I/F
+#define COMP_ID_HSI						0x06	//H/W                 - Driver		I/F
+#define COMP_ID_DAI						0x07	//API                 - Driver		I/F
+#define COMP_ID_APF						0x08	//H/W                 - Driver		I/F
+#define COMP_ID_INT						0x09	//Intermediate FW     - Driver		I/F
+
+#ifdef HCF_LEGACY
+#define HCF_ACT_ACS_SCAN				HCF_ACT_PRS_SCAN
+#define UIL_ACT_ACS_SCAN 				UIL_ACT_PRS_SCAN
+#define MDD_ACT_ACS_SCAN	 			MDD_ACT_PRS_SCAN
+#define CFG_ACS_SCAN					CFG_PRS_SCAN
+#endif // HCF_LEGACY
+
+#endif // MDD_H
+
diff --git a/drivers/staging/wlags49_h2/mmd.c b/drivers/staging/wlags49_h2/mmd.c
new file mode 100644
index 0000000..de138c4
--- /dev/null
+++ b/drivers/staging/wlags49_h2/mmd.c
@@ -0,0 +1,251 @@
+
+//   vim:tw=110:ts=4:
+/************************************************************************************************************
+*
+* FILE	  : mmd.c
+*
+* DATE    : $Date: 2004/07/23 11:57:45 $   $Revision: 1.4 $
+* Original: 2004/05/28 14:05:35    Revision: 1.32      Tag: hcf7_t20040602_01
+* Original: 2004/05/13 15:31:45    Revision: 1.30      Tag: hcf7_t7_20040513_01
+* Original: 2004/04/15 09:24:42    Revision: 1.25      Tag: hcf7_t7_20040415_01
+* Original: 2004/04/08 15:18:17    Revision: 1.24      Tag: t7_20040413_01
+* Original: 2004/04/01 15:32:55    Revision: 1.22      Tag: t7_20040401_01
+* Original: 2004/03/10 15:39:28    Revision: 1.18      Tag: t20040310_01
+* Original: 2004/03/03 14:10:12    Revision: 1.16      Tag: t20040304_01
+* Original: 2004/03/02 09:27:12    Revision: 1.14      Tag: t20040302_03
+* Original: 2004/02/24 13:00:29    Revision: 1.12      Tag: t20040224_01
+* Original: 2004/01/30 09:59:33    Revision: 1.11      Tag: t20040219_01
+*
+* AUTHOR  : Nico Valster
+*
+* DESC    : Common routines for HCF, MSF, UIL as well as USF sources
+*
+* Note: relative to Asserts, the following can be observed:
+*	Since the IFB is not known inside the routine, the macro HCFASSERT is replaced with MDDASSERT.
+*	Also the line number reported in the assert is raised by FILE_NAME_OFFSET (20000) to discriminate the
+*	MMD Asserts from HCF and DHF asserts.
+*
+***************************************************************************************************************
+*
+*
+* SOFTWARE LICENSE
+*
+* This software is provided subject to the following terms and conditions,
+* which you should read carefully before using the software.  Using this
+* software indicates your acceptance of these terms and conditions.  If you do
+* not agree with these terms and conditions, do not use the software.
+*
+* COPYRIGHT © 2001 - 2004	by Agere Systems Inc.	All Rights Reserved
+* All rights reserved.
+*
+* Redistribution and use in source or binary forms, with or without
+* modifications, are permitted provided that the following conditions are met:
+*
+* . Redistributions of source code must retain the above copyright notice, this
+*    list of conditions and the following Disclaimer as comments in the code as
+*    well as in the documentation and/or other materials provided with the
+*    distribution.
+*
+* . Redistributions in binary form must reproduce the above copyright notice,
+*    this list of conditions and the following Disclaimer in the documentation
+*    and/or other materials provided with the distribution.
+*
+* . Neither the name of Agere Systems Inc. nor the names of the contributors
+*    may be used to endorse or promote products derived from this software
+*    without specific prior written permission.
+*
+* Disclaimer
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+* INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+* USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+* RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+* DAMAGE.
+*
+*
+**************************************************************************************************************/
+
+#include "hcf.h"				// Needed as long as we do not really sort out the mess
+#include "hcfdef.h"				// get CNV_LITTLE_TO_SHORT
+#include "mmd.h"				// MoreModularDriver common include file
+
+//to distinguish DHF from HCF asserts by means of line number
+#undef	FILE_NAME_OFFSET
+#define FILE_NAME_OFFSET DHF_FILE_NAME_OFFSET
+
+
+/*************************************************************************************************************
+*
+*.MODULE		CFG_RANGE_SPEC_STRCT* mmd_check_comp( CFG_RANGES_STRCT *actp, CFG_SUP_RANGE_STRCT *supp )
+*.PURPOSE		Checks compatibility between an actor and a supplier.
+*
+*.ARGUMENTS
+*	actp
+*	supp
+*
+*.RETURNS
+*	NULL	incompatible
+*	<>NULL	pointer to matching CFG_RANGE_SPEC_STRCT substructure in actor-structure matching the supplier
+*
+*.NARRATIVE
+*
+*  Parameters:
+*	actp	address of the actor specification
+*	supp	address of the supplier specification
+*
+*	Description: mmd_check_comp is a support routine to check the compatibility between an actor and a
+*	supplier.  mmd_check_comp is independent of the endianess of the actp and supp structures. This is
+*	achieved by checking the "bottom" or "role" fields of these structures. Since these fields are restricted
+*	to a limited range, comparing the contents to a value with a known endian-ess gives a clue to their actual
+*	endianess.
+*
+*.DIAGRAM
+*1a: The role-field of the actor structure has a known non-zero, not "byte symmetric" value (namely
+*	COMP_ROLE_ACT or 0x0001), so if and only the contents of this field matches COMP_ROLE_ACT (in Native
+*	Endian format), the actor structure is Native Endian.
+*2a: Since the role-field of the supplier structure is 0x0000, the test as used for the actor does not work
+*	for a supplier. A supplier has always exactly 1 variant,top,bottom record with (officially, but see the
+*	note below) each of these 3 values in the range 1 through 99, so one byte of the word value of variant,
+*	top and bottom words is 0x00 and the other byte is non-zero. Whether the lowest address byte or the
+*	highest address byte is non-zero depends on the Endianess of the LTV. If and only if the word value of
+*	bottom is less than 0x0100, the supplier is Native Endian.
+*	NOTE: the variant field of the supplier structure can not be used for the Endian Detection Algorithm,
+*	because a a zero-valued variant has been used as Controlled Deployment indication in the past.
+*	Note: An actor may have multiple sets of variant,top,bottom records, including dummy sets with variant,
+*	top and bottom fields with a zero-value. As a consequence the endianess of the actor can not be determined
+*	based on its variant,top,bottom values.
+*
+*	Note: the L and T field of the structures are always in Native Endian format, so you can not draw
+*	conclusions concerning the Endianess of the structure based on these two fields.
+*
+*1b/2b
+*	The only purpose of the CFG_RANGE_SPEC_BYTE_STRCT is to give easy access to the non-zero byte of the word
+*	value of variant, top and bottom. The variables sup_endian and act_endian are used for the supplier and
+*	actor structure respectively. These variables must be 0 when the structure has LE format and 1 if the
+*	structure has BE format. This can be phrased as:
+*	the variable is false (i.e 0x0000) if either
+*		(the platform is LE and the LTV is the same as the platform)
+*	or
+*		(the platform is BE and the LTV differs from the platform).
+*	the variable is true (i.e 0x0001) if either
+*		(the platform is BE and the LTV is the same as the platform)
+*	or
+*		(the platform is LE and the LTV differs from the platform).
+*
+*	Alternatively this can be phrased as:
+*	if the platform is LE
+*		if the LTV is LE (i.e the same as the platform), then the variable = 0
+*		else (the LTV is BE (i.e. different from the platform) ), then the variable = 1
+*	if the platform is BE
+*		if the LTV is BE (i.e the same as the platform), then the variable = 1
+*		else (the LTV is LE (i.e. different from the platform) ), then the variable = 0
+*
+*	This is implemented as:
+*	#if HCF_BIG_ENDIAN == 0	//platform is LE
+*		sup/act_endian becomes reverse of structure-endianess as determined in 1a/1b
+*	#endif
+*6:	Each of the actor variant-bottom-top records is checked against the (single) supplier variant-bottom-top
+*	range till either an acceptable match is found or all actor records are tried. As explained above, due to
+*	the limited ranges of these values, checking a byte is acceptable and suitable.
+*8:	depending on whether a match was found or not (as reflected by the value of the control variable of the
+*	for loop), the NULL pointer or a pointer to the matching Number/Bottom/Top record of the Actor structure
+*	is returned.
+*	As an additional safety, checking the supplier length protects against invalid Supplier structures, which
+*	may be caused by failing hcf_get_info (in which case the len-field is zero). Note that the contraption
+*	"supp->len != sizeof(CFG_SUP_RANGE_STRCT)/sizeof(hcf_16) - 1"
+*	did turn out not to work for a compiler which padded the structure definition.
+*
+* Note: when consulting references like DesignNotes and Architecture specifications there is a confusing use
+*	of the notions number and variant. This resulted in an inconsistent use in the HCF nomenclature as well.
+*	This makes the logic hard to follow and one has to be very much aware of the context when walking through
+*	the code.
+* NOTE: The Endian Detection Algorithm places limitations on future extensions of the fields, i.e. they should
+*	stay within the currently defined boundaries of 1 through 99 (although 1 through 255) would work as well
+*	and there should never be used a zero value for the bottom of a valid supplier.
+* Note: relative to Asserts, the following can be observed:
+*	1: Supplier variant 0x0000 has been used for Controlled Deployment
+*	2: An actor may have one or more variant record specifications with a top of zero and a non-zero bottom
+*	to override the HCF default support of a particular variant by the MSF programmer via hcfcfg.h
+*	3:	An actor range can be specified as all zeros, e.g. as padding in the automatically generated firmware
+*	image files.
+*.ENDDOC				END DOCUMENTATION
+*************************************************************************************************************/
+CFG_RANGE_SPEC_STRCT*
+mmd_check_comp( CFG_RANGES_STRCT *actp, CFG_SUP_RANGE_STRCT *supp )
+{
+
+CFG_RANGE_SPEC_BYTE_STRCT  *actq = (CFG_RANGE_SPEC_BYTE_STRCT*)actp->var_rec;
+CFG_RANGE_SPEC_BYTE_STRCT  *supq = (CFG_RANGE_SPEC_BYTE_STRCT*)&(supp->variant);
+hcf_16	i;
+int		act_endian;					//actor endian flag
+int		sup_endian;					//supplier endian flag
+
+	act_endian = actp->role == COMP_ROLE_ACT;	//true if native endian				/* 1a */
+	sup_endian = supp->bottom < 0x0100;		 	//true if native endian				/* 2a */
+
+#if HCF_ASSERT
+	MMDASSERT( supp->len == 6, 																supp->len )
+	MMDASSERT( actp->len >= 6 && actp->len%3 == 0, 											actp->len )
+
+	if ( act_endian ) {							//native endian
+		MMDASSERT( actp->role == COMP_ROLE_ACT,												actp->role )
+		MMDASSERT( 1 <= actp->id && actp->id <= 99,  										actp->id )
+	} else {									//non-native endian
+		MMDASSERT( actp->role == CNV_END_SHORT(COMP_ROLE_ACT),	 							actp->role )
+		MMDASSERT( 1 <= CNV_END_SHORT(actp->id) && CNV_END_SHORT(actp->id) <= 99,				actp->id )
+	}
+	if ( sup_endian ) {							//native endian
+		MMDASSERT( supp->role == COMP_ROLE_SUPL, 											supp->role )
+		MMDASSERT( 1 <= supp->id      && supp->id <= 99,  									supp->id )
+		MMDASSERT( 1 <= supp->variant && supp->variant <= 99,  								supp->variant )
+		MMDASSERT( 1 <= supp->bottom  && supp->bottom <= 99, 								supp->bottom )
+		MMDASSERT( 1 <= supp->top     && supp->top <= 99, 		 							supp->top )
+		MMDASSERT( supp->bottom <= supp->top,							supp->bottom << 8 | supp->top )
+	} else {									//non-native endian
+		MMDASSERT( supp->role == CNV_END_SHORT(COMP_ROLE_SUPL), 								supp->role )
+		MMDASSERT( 1 <= CNV_END_SHORT(supp->id) && CNV_END_SHORT(supp->id) <= 99,				supp->id )
+		MMDASSERT( 1 <= CNV_END_SHORT(supp->variant) && CNV_END_SHORT(supp->variant) <= 99,		supp->variant )
+		MMDASSERT( 1 <= CNV_END_SHORT(supp->bottom)  && CNV_END_SHORT(supp->bottom) <=99,		supp->bottom )
+		MMDASSERT( 1 <= CNV_END_SHORT(supp->top)     && CNV_END_SHORT(supp->top) <=99,  		supp->top )
+		MMDASSERT( CNV_END_SHORT(supp->bottom) <= CNV_END_SHORT(supp->top),	supp->bottom << 8 |	supp->top )
+	}
+#endif // HCF_ASSERT
+
+#if HCF_BIG_ENDIAN == 0
+	act_endian = !act_endian;																		/* 1b*/
+	sup_endian = !sup_endian;																		/* 2b*/
+#endif // HCF_BIG_ENDIAN
+
+	for ( i = actp->len ; i > 3; actq++, i -= 3 ) {													/* 6 */
+		MMDASSERT( actq->variant[act_endian] <= 99, i<<8 | actq->variant[act_endian] )
+		MMDASSERT( actq->bottom[act_endian] <= 99 , i<<8 | actq->bottom[act_endian] )
+		MMDASSERT( actq->top[act_endian] <= 99	  , i<<8 | actq->top[act_endian] )
+		MMDASSERT( actq->bottom[act_endian] <= actq->top[act_endian], i<<8 | actq->bottom[act_endian] )
+		if ( actq->variant[act_endian] == supq->variant[sup_endian] &&
+			 actq->bottom[act_endian]  <= supq->top[sup_endian] &&
+			 actq->top[act_endian]     >= supq->bottom[sup_endian]
+		   ) break;
+	}
+	if ( i <= 3 || supp->len != 6 /*sizeof(CFG_SUP_RANGE_STRCT)/sizeof(hcf_16) - 1 */ ) {
+	   actq = NULL;																					/* 8 */
+	}
+#if HCF_ASSERT
+	if ( actq == NULL ) {
+		for ( i = 0; i <= supp->len; i += 2 ) {
+			MMDASSERT( DO_ASSERT, MERGE_2( ((hcf_16*)supp)[i], ((hcf_16*)supp)[i+1] ) );
+		}
+		for ( i = 0; i <= actp->len; i += 2 ) {
+			MMDASSERT( DO_ASSERT, MERGE_2( ((hcf_16*)actp)[i], ((hcf_16*)actp)[i+1] ) );
+		}
+	}
+#endif // HCF_ASSERT
+	return (CFG_RANGE_SPEC_STRCT*)actq;
+} // mmd_check_comp
+
diff --git a/drivers/staging/wlags49_h2/mmd.h b/drivers/staging/wlags49_h2/mmd.h
new file mode 100644
index 0000000..06890c1
--- /dev/null
+++ b/drivers/staging/wlags49_h2/mmd.h
@@ -0,0 +1,78 @@
+
+//   vim:tw=110:ts=4:
+#ifndef MMD_H
+#define MMD_H 1
+
+/*************************************************************************************************************
+*
+* FILE	  : mmd.h
+*
+* DATE    : $Date: 2004/07/19 08:16:14 $   $Revision: 1.2 $
+* Original: 2004/05/17 07:33:14    Revision: 1.18      Tag: hcf7_t20040602_01
+* Original: 2004/05/11 06:22:59    Revision: 1.17      Tag: hcf7_t7_20040513_01
+* Original: 2004/04/15 09:24:42    Revision: 1.13      Tag: hcf7_t7_20040415_01
+* Original: 2004/04/08 15:18:17    Revision: 1.12      Tag: t7_20040413_01
+* Original: 2004/04/01 15:32:55    Revision: 1.10      Tag: t7_20040401_01
+* Original: 2004/03/04 16:47:50    Revision: 1.7      Tag: t20040310_01
+* Original: 2004/03/03 12:47:05    Revision: 1.6      Tag: t20040304_01
+* Original: 2004/02/25 14:14:39    Revision: 1.5      Tag: t20040302_03
+* Original: 2004/02/24 13:00:29    Revision: 1.4      Tag: t20040224_01
+* Original: 2004/01/30 09:59:33    Revision: 1.3      Tag: t20040219_01
+*
+* AUTHOR  : Nico Valster
+*
+* DESC    : Definitions and Prototypes for HCF, MSF, UIL as well as USF sources
+*
+***************************************************************************************************************
+*
+*
+* SOFTWARE LICENSE
+*
+* This software is provided subject to the following terms and conditions,
+* which you should read carefully before using the software.  Using this
+* software indicates your acceptance of these terms and conditions.  If you do
+* not agree with these terms and conditions, do not use the software.
+*
+* COPYRIGHT © 2001 - 2004	by Agere Systems Inc.	All Rights Reserved
+* All rights reserved.
+*
+* Redistribution and use in source or binary forms, with or without
+* modifications, are permitted provided that the following conditions are met:
+*
+* . Redistributions of source code must retain the above copyright notice, this
+*    list of conditions and the following Disclaimer as comments in the code as
+*    well as in the documentation and/or other materials provided with the
+*    distribution.
+*
+* . Redistributions in binary form must reproduce the above copyright notice,
+*    this list of conditions and the following Disclaimer in the documentation
+*    and/or other materials provided with the distribution.
+*
+* . Neither the name of Agere Systems Inc. nor the names of the contributors
+*    may be used to endorse or promote products derived from this software
+*    without specific prior written permission.
+*
+* Disclaimer
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+* INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+* USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+* RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+* DAMAGE.
+*
+*
+**************************************************************************************************************/
+#ifndef HCF_H
+#include "hcf.h"	//just to get going with swig
+#endif
+
+EXTERN_C CFG_RANGE_SPEC_STRCT* mmd_check_comp( CFG_RANGES_STRCT *actp, CFG_SUP_RANGE_STRCT *supp );
+
+#endif // MMD_H
diff --git a/drivers/staging/wlags49_h2/sta_h2.c b/drivers/staging/wlags49_h2/sta_h2.c
new file mode 100644
index 0000000..f9a3852
--- /dev/null
+++ b/drivers/staging/wlags49_h2/sta_h2.c
@@ -0,0 +1,4480 @@
+/*
+ * File:	sta_h24.236
+ *
+ * Abstract:	This file contains memory image 'fw_image'.
+ *
+ * Contents:	Total size of the memory image: 69294 bytes.
+ *		Total number of blocks: 4 blocks.
+ *		Block  1 : load address 00000060, 390 bytes.
+ *		Block  2 : load address 00000C16, 9496 bytes.
+ *		Block  3 : load address 001E312E, 15786 bytes.
+ *		Block  4 : load address 001F4000, 43622 bytes.
+ *
+ * Identity:	component id: 31 (variant 3) version 2.36
+ *
+ * Compatibility:
+ *		supplying interface 4 (variant 2) : 2 - 5
+ *		acting on interface 1 (variant 4) : 6 - 7
+ *		acting on interface 1 (variant 5) : 6 - 7
+ *		acting on interface 1 (variant 6) : 6 - 7
+ *		acting on interface 2 (variant 2) : 1 - 2
+ *
+ * Generated:	by g:\fw\fupu3.exe version 4.26
+ *
+ * Commandline:	g:\fw\fupu3.exe /f=4 /n=fw_image /i=r3023600.hex
+ */
+
+
+#include "hcfcfg.h"				// to get hcf_16 etc defined as well as
+                                // possible settings which inluence mdd.h or dhf.h
+#include "mdd.h"   				//to get COMP_ID_STA etc defined
+#include "dhf.h"   				//used to be "fhfmem.h", to get memblock,plugrecord,
+
+static const hcf_8 fw_image_1_data[] = {
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x0D, 0x00, 0x00,
+	 0x3A, 0x0C, 0x00, 0x00, 0x3A, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x1B, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x86, 0x19, 0x86, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
+	 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0xEA, 0x00, 0x00, 0xFF, 0x07, 0x01, 0x00, 0x64, 0x00, 0x64, 0x00, 0x10, 0x27, 0x10, 0x27,
+	 0x14, 0x00, 0xD0, 0x07, 0xD0, 0x07, 0x10, 0x27, 0x2F, 0x00, 0x32, 0x00, 0x32, 0x00, 0x05, 0x00,
+	 0x02, 0x00, 0x02, 0x00, 0x10, 0x27, 0x05, 0x00, 0x00, 0x02, 0x00, 0x02, 0x13, 0x00, 0x0A, 0x00,
+	 0x07, 0x00, 0x03, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x09, 0x2B, 0x09, 0x2B, 0x09,
+	 0x03, 0x00, 0x00, 0x00, 0x00, 0x6E, 0x00, 0x14, 0x01, 0x00, 0x40, 0x00, 0x32, 0x00, 0x32, 0x00,
+	 0x0A, 0x00, 0x02, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+};  /* fw_image_1_data */
+
+static const hcf_8 fw_image_2_data[] = {
+	 0x4B, 0xA3, 0x00, 0x0A, 0x10, 0x01, 0x68, 0xA4, 0xB0, 0x01, 0x84, 0x01, 0x30, 0x33, 0x31, 0x33,
+	 0x44, 0x44, 0x30, 0x33, 0x31, 0x33, 0x30, 0x33, 0x31, 0x33, 0x32, 0x33, 0x32, 0x33, 0x90, 0x00,
+	 0x78, 0x04, 0xAE, 0xE4, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
+	 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA5, 0xC6, 0x84, 0xF8, 0x99, 0xEE,
+	 0x8D, 0xF6, 0x0D, 0xFF, 0xBD, 0xD6, 0xB1, 0xDE, 0x54, 0x91, 0x50, 0x60, 0x03, 0x02, 0xA9, 0xCE,
+	 0x7D, 0x56, 0x19, 0xE7, 0x62, 0xB5, 0xE6, 0x4D, 0x9A, 0xEC, 0x45, 0x8F, 0x9D, 0x1F, 0x40, 0x89,
+	 0x87, 0xFA, 0x15, 0xEF, 0xEB, 0xB2, 0xC9, 0x8E, 0x0B, 0xFB, 0xEC, 0x41, 0x67, 0xB3, 0xFD, 0x5F,
+	 0xEA, 0x45, 0xBF, 0x23, 0xF7, 0x53, 0x96, 0xE4, 0x5B, 0x9B, 0xC2, 0x75, 0x1C, 0xE1, 0xAE, 0x3D,
+	 0x6A, 0x4C, 0x5A, 0x6C, 0x41, 0x7E, 0x02, 0xF5, 0x4F, 0x83, 0x5C, 0x68, 0xF4, 0x51, 0x34, 0xD1,
+	 0x08, 0xF9, 0x93, 0xE2, 0x73, 0xAB, 0x53, 0x62, 0x3F, 0x2A, 0x0C, 0x08, 0x52, 0x95, 0x65, 0x46,
+	 0x5E, 0x9D, 0x28, 0x30, 0xA1, 0x37, 0x0F, 0x0A, 0xB5, 0x2F, 0x09, 0x0E, 0x36, 0x24, 0x9B, 0x1B,
+	 0x3D, 0xDF, 0x26, 0xCD, 0x69, 0x4E, 0xCD, 0x7F, 0x9F, 0xEA, 0x1B, 0x12, 0x9E, 0x1D, 0x74, 0x58,
+	 0x2E, 0x34, 0x2D, 0x36, 0xB2, 0xDC, 0xEE, 0xB4, 0xFB, 0x5B, 0xF6, 0xA4, 0x4D, 0x76, 0x61, 0xB7,
+	 0xCE, 0x7D, 0x7B, 0x52, 0x3E, 0xDD, 0x71, 0x5E, 0x97, 0x13, 0xF5, 0xA6, 0x68, 0xB9, 0x00, 0x00,
+	 0x2C, 0xC1, 0x60, 0x40, 0x1F, 0xE3, 0xC8, 0x79, 0xED, 0xB6, 0xBE, 0xD4, 0x46, 0x8D, 0xD9, 0x67,
+	 0x4B, 0x72, 0xDE, 0x94, 0xD4, 0x98, 0xE8, 0xB0, 0x4A, 0x85, 0x6B, 0xBB, 0x2A, 0xC5, 0xE5, 0x4F,
+	 0x16, 0xED, 0xC5, 0x86, 0xD7, 0x9A, 0x55, 0x66, 0x94, 0x11, 0xCF, 0x8A, 0x10, 0xE9, 0x06, 0x04,
+	 0x81, 0xFE, 0xF0, 0xA0, 0x44, 0x78, 0xBA, 0x25, 0xE3, 0x4B, 0xF3, 0xA2, 0xFE, 0x5D, 0xC0, 0x80,
+	 0x8A, 0x05, 0xAD, 0x3F, 0xBC, 0x21, 0x48, 0x70, 0x04, 0xF1, 0xDF, 0x63, 0xC1, 0x77, 0x75, 0xAF,
+	 0x63, 0x42, 0x30, 0x20, 0x1A, 0xE5, 0x0E, 0xFD, 0x6D, 0xBF, 0x4C, 0x81, 0x14, 0x18, 0x35, 0x26,
+	 0x2F, 0xC3, 0xE1, 0xBE, 0xA2, 0x35, 0xCC, 0x88, 0x39, 0x2E, 0x57, 0x93, 0xF2, 0x55, 0x82, 0xFC,
+	 0x47, 0x7A, 0xAC, 0xC8, 0xE7, 0xBA, 0x2B, 0x32, 0x95, 0xE6, 0xA0, 0xC0, 0x98, 0x19, 0xD1, 0x9E,
+	 0x7F, 0xA3, 0x66, 0x44, 0x7E, 0x54, 0xAB, 0x3B, 0x83, 0x0B, 0xCA, 0x8C, 0x29, 0xC7, 0xD3, 0x6B,
+	 0x3C, 0x28, 0x79, 0xA7, 0xE2, 0xBC, 0x1D, 0x16, 0x76, 0xAD, 0x3B, 0xDB, 0x56, 0x64, 0x4E, 0x74,
+	 0x1E, 0x14, 0xDB, 0x92, 0x0A, 0x0C, 0x6C, 0x48, 0xE4, 0xB8, 0x5D, 0x9F, 0x6E, 0xBD, 0xEF, 0x43,
+	 0xA6, 0xC4, 0xA8, 0x39, 0xA4, 0x31, 0x37, 0xD3, 0x8B, 0xF2, 0x32, 0xD5, 0x43, 0x8B, 0x59, 0x6E,
+	 0xB7, 0xDA, 0x8C, 0x01, 0x64, 0xB1, 0xD2, 0x9C, 0xE0, 0x49, 0xB4, 0xD8, 0xFA, 0xAC, 0x07, 0xF3,
+	 0x25, 0xCF, 0xAF, 0xCA, 0x8E, 0xF4, 0xE9, 0x47, 0x18, 0x10, 0xD5, 0x6F, 0x88, 0xF0, 0x6F, 0x4A,
+	 0x72, 0x5C, 0x24, 0x38, 0xF1, 0x57, 0xC7, 0x73, 0x51, 0x97, 0x23, 0xCB, 0x7C, 0xA1, 0x9C, 0xE8,
+	 0x21, 0x3E, 0xDD, 0x96, 0xDC, 0x61, 0x86, 0x0D, 0x85, 0x0F, 0x90, 0xE0, 0x42, 0x7C, 0xC4, 0x71,
+	 0xAA, 0xCC, 0xD8, 0x90, 0x05, 0x06, 0x01, 0xF7, 0x12, 0x1C, 0xA3, 0xC2, 0x5F, 0x6A, 0xF9, 0xAE,
+	 0xD0, 0x69, 0x91, 0x17, 0x58, 0x99, 0x27, 0x3A, 0xB9, 0x27, 0x38, 0xD9, 0x13, 0xEB, 0xB3, 0x2B,
+	 0x33, 0x22, 0xBB, 0xD2, 0x70, 0xA9, 0x89, 0x07, 0xA7, 0x33, 0xB6, 0x2D, 0x22, 0x3C, 0x92, 0x15,
+	 0x20, 0xC9, 0x49, 0x87, 0xFF, 0xAA, 0x78, 0x50, 0x7A, 0xA5, 0x8F, 0x03, 0xF8, 0x59, 0x80, 0x09,
+	 0x17, 0x1A, 0xDA, 0x65, 0x31, 0xD7, 0xC6, 0x84, 0xB8, 0xD0, 0xC3, 0x82, 0xB0, 0x29, 0x77, 0x5A,
+	 0x11, 0x1E, 0xCB, 0x7B, 0xFC, 0xA8, 0xD6, 0x6D, 0x3A, 0x2C, 0x00, 0x30, 0x00, 0x31, 0x00, 0x33,
+	 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x38, 0x00, 0x3A, 0x00, 0x3B,
+	 0x00, 0x3C, 0x00, 0x3D, 0x00, 0x3E, 0x00, 0x3F, 0x00, 0x3F, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0A, 0x02, 0x14,
+	 0x05, 0x32, 0x0B, 0x37, 0x08, 0x50, 0x0B, 0x6E, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x3F, 0x00,
+	 0x0C, 0x00, 0x30, 0x00, 0x03, 0x00, 0x0F, 0x00, 0x3E, 0x00, 0x3C, 0x00, 0x02, 0x00, 0x04, 0x00,
+	 0x0A, 0x00, 0x0B, 0x00, 0x10, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x63, 0x00, 0x20, 0x00, 0x63, 0x00, 0x63, 0x00, 0x20, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x10,
+	 0xEE, 0x10, 0xA6, 0x10, 0xE8, 0x10, 0xAC, 0x10, 0xE2, 0x10, 0xB2, 0x10, 0xDC, 0x10, 0xB8, 0x10,
+	 0xD6, 0x10, 0xBE, 0x10, 0xD0, 0x10, 0xC4, 0x10, 0xCA, 0x10, 0x07, 0x01, 0x00, 0x00, 0x0A, 0x22,
+	 0x00, 0x04, 0x08, 0x01, 0x00, 0x00, 0x0A, 0x26, 0x00, 0x04, 0x09, 0x01, 0x00, 0x00, 0x0A, 0x2A,
+	 0x00, 0x04, 0x0A, 0x01, 0x00, 0x00, 0x0A, 0x2E, 0x00, 0x04, 0x0B, 0x01, 0x00, 0x00, 0x10, 0x24,
+	 0x04, 0x04, 0x0C, 0x01, 0x00, 0x00, 0x10, 0x28, 0x04, 0x04, 0x0D, 0x01, 0x00, 0x00, 0x10, 0x2C,
+	 0x04, 0x04, 0x0E, 0x01, 0x00, 0x00, 0x10, 0x30, 0x04, 0x04, 0x0F, 0x01, 0x00, 0x00, 0x16, 0x34,
+	 0x08, 0x04, 0x10, 0x01, 0x00, 0x00, 0x16, 0x38, 0x08, 0x04, 0x11, 0x01, 0x00, 0x00, 0x16, 0x3C,
+	 0x08, 0x04, 0x12, 0x01, 0x00, 0x00, 0x16, 0x40, 0x08, 0x04, 0x13, 0x01, 0x00, 0x00, 0x17, 0x64,
+	 0x0C, 0x0B, 0x14, 0x01, 0x00, 0x00, 0x17, 0x68, 0x0C, 0x0B, 0x15, 0x01, 0x00, 0x00, 0x17, 0x6C,
+	 0x0C, 0x0B, 0x16, 0x01, 0x00, 0x00, 0x17, 0x70, 0x0C, 0x0B, 0x17, 0x01, 0x00, 0x00, 0x17, 0x74,
+	 0x0C, 0x0B, 0x18, 0x01, 0x00, 0x00, 0x17, 0x78, 0x0C, 0x0B, 0x19, 0x01, 0x00, 0x00, 0x17, 0x7C,
+	 0x0C, 0x0B, 0x1A, 0x01, 0x00, 0x00, 0x17, 0x80, 0x0C, 0x0B, 0x1B, 0x01, 0x00, 0x00, 0x17, 0x84,
+	 0x0C, 0x0B, 0x1C, 0x01, 0x00, 0x00, 0x17, 0x88, 0x0C, 0x0B, 0x1D, 0x01, 0x00, 0x00, 0x17, 0x8C,
+	 0x0C, 0x0B, 0x1E, 0x01, 0x00, 0x00, 0x1D, 0x95, 0x17, 0x04, 0x1F, 0x01, 0x00, 0x00, 0x1D, 0x99,
+	 0x17, 0x04, 0x20, 0x01, 0x00, 0x00, 0x1D, 0x9D, 0x17, 0x04, 0x21, 0x01, 0x00, 0x00, 0x1D, 0xA1,
+	 0x17, 0x04, 0x22, 0x01, 0x00, 0x00, 0x0E, 0xA5, 0x00, 0x00, 0x10, 0x11, 0x30, 0x11, 0x50, 0x11,
+	 0x70, 0x11, 0xC8, 0x11, 0x18, 0x11, 0x38, 0x11, 0x58, 0x11, 0x78, 0x11, 0xD0, 0x11, 0x20, 0x11,
+	 0x40, 0x11, 0x60, 0x11, 0x80, 0x11, 0xD8, 0x11, 0x28, 0x11, 0x48, 0x11, 0x68, 0x11, 0x88, 0x11,
+	 0xE0, 0x11, 0x90, 0x11, 0x98, 0x11, 0xA0, 0x11, 0xA8, 0x11, 0xB0, 0x11, 0xB8, 0x11, 0xC0, 0x11,
+	 0xE8, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x36, 0x25, 0x4F, 0x25, 0x72, 0x25, 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24, 0xAC, 0x25,
+	 0x02, 0x2B, 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24, 0xF3, 0x2D, 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24,
+	 0xE1, 0x24, 0xE1, 0x24, 0x8B, 0x27, 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24,
+	 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24,
+	 0xE1, 0x24, 0xE1, 0x24, 0xE5, 0x27, 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24,
+	 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24,
+	 0xE1, 0x24, 0x59, 0x27, 0x73, 0x27, 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24, 0xE1, 0x24,
+	 0xE1, 0x24, 0x47, 0x23, 0xCE, 0x25, 0xE1, 0x25, 0x91, 0x26, 0x95, 0x26, 0xE1, 0x24, 0xE1, 0x24,
+	 0x44, 0x27, 0x51, 0xEA, 0xFF, 0xE9, 0x00, 0x00, 0x48, 0xEA, 0x00, 0x00, 0x00, 0x00, 0xC9, 0xEA,
+	 0x65, 0x25, 0x89, 0x25, 0x00, 0x00, 0xF8, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x13, 0x2B, 0xE0, 0xFC,
+	 0x4C, 0x28, 0xC6, 0x2A, 0x5A, 0x00, 0x02, 0x00, 0xF9, 0xFF, 0x4C, 0x28, 0x62, 0x28, 0x00, 0x01,
+	 0x02, 0x00, 0xF7, 0xFF, 0x4C, 0x28, 0x62, 0x28, 0x50, 0x28, 0x06, 0x00, 0xF0, 0xFF, 0x4C, 0x28,
+	 0x29, 0x28, 0x00, 0x00, 0x00, 0x02, 0xF6, 0xFF, 0x4C, 0x28, 0x62, 0x28, 0x6C, 0x00, 0x02, 0x00,
+	 0xF4, 0xFF, 0x4C, 0x28, 0x62, 0x28, 0xAA, 0x01, 0x02, 0x00, 0xF5, 0xFF, 0x4C, 0x28, 0xCF, 0x2A,
+	 0x42, 0x28, 0x02, 0x00, 0xE0, 0xFF, 0x4C, 0x28, 0x62, 0x28, 0xCE, 0x2D, 0x02, 0x00, 0xE1, 0xFF,
+	 0x4C, 0x28, 0x62, 0x28, 0xD0, 0x2D, 0x02, 0x00, 0xE2, 0xFF, 0x4C, 0x28, 0x62, 0x28, 0xD2, 0x2D,
+	 0x02, 0x00, 0xE3, 0xFF, 0x4C, 0x28, 0x62, 0x28, 0xCA, 0x2D, 0x02, 0x00, 0x03, 0xFC, 0x4C, 0x28,
+	 0x17, 0x2A, 0x16, 0x2D, 0x02, 0x00, 0x04, 0xFC, 0x4C, 0x28, 0x5C, 0x28, 0x58, 0x28, 0x22, 0x00,
+	 0x06, 0xFC, 0x4C, 0x28, 0x62, 0x28, 0x40, 0x28, 0x02, 0x00, 0x07, 0xFC, 0x4C, 0x28, 0x62, 0x28,
+	 0x9C, 0x28, 0x02, 0x00, 0x0E, 0xFC, 0x4C, 0x28, 0x29, 0x2A, 0xA6, 0x28, 0x22, 0x00, 0xB1, 0xFC,
+	 0x4C, 0x28, 0x1D, 0x2B, 0xA2, 0x29, 0x02, 0x00, 0x20, 0xFC, 0x4C, 0x28, 0x62, 0x28, 0xCC, 0x28,
+	 0x02, 0x00, 0x25, 0xFC, 0x4C, 0x28, 0x62, 0x28, 0xD6, 0x28, 0x02, 0x00, 0x26, 0xFC, 0x4C, 0x28,
+	 0x62, 0x28, 0xD8, 0x28, 0x02, 0x00, 0x27, 0xFC, 0x4C, 0x28, 0x62, 0x28, 0xDA, 0x28, 0x02, 0x00,
+	 0xB2, 0xFC, 0x4C, 0x28, 0x5C, 0x28, 0xC6, 0x29, 0x22, 0x00, 0xC1, 0xFC, 0x4C, 0x28, 0x62, 0x28,
+	 0x5A, 0x2D, 0x20, 0x00, 0xB0, 0xFC, 0x1F, 0x28, 0x22, 0x2B, 0x00, 0x00, 0x00, 0x00, 0xC4, 0xFC,
+	 0x1F, 0x28, 0xE7, 0x2A, 0x00, 0x00, 0x08, 0x00, 0xC8, 0xFC, 0x1F, 0x28, 0xE2, 0x2A, 0x00, 0x00,
+	 0x08, 0x00, 0xB4, 0xFC, 0x1F, 0x28, 0x60, 0x2B, 0x00, 0x00, 0x00, 0x00, 0xB6, 0xFC, 0x1F, 0x28,
+	 0x11, 0x2C, 0x00, 0x00, 0x00, 0x00, 0xB7, 0xFC, 0x1F, 0x28, 0x3B, 0x2C, 0x00, 0x00, 0x00, 0x00,
+	 0xB8, 0xFC, 0x1F, 0x28, 0x98, 0x2C, 0x00, 0x00, 0x00, 0x00, 0xB5, 0xFC, 0x4C, 0x28, 0x62, 0x28,
+	 0xC6, 0x2D, 0x02, 0x00, 0xB9, 0xFC, 0x4C, 0x28, 0x62, 0x28, 0xC8, 0x2D, 0x02, 0x00, 0x90, 0xFD,
+	 0x4C, 0x28, 0x29, 0x28, 0xCC, 0x2D, 0x02, 0x00, 0x23, 0xFC, 0x4C, 0x28, 0x62, 0x28, 0xD2, 0x28,
+	 0x02, 0x00, 0x29, 0xFC, 0x44, 0x29, 0xF1, 0x28, 0x00, 0x00, 0x00, 0x00, 0xC2, 0xFC, 0x4C, 0x28,
+	 0x62, 0x28, 0x0E, 0x2D, 0x02, 0x00, 0x32, 0xFC, 0x4C, 0x28, 0x62, 0x28, 0xA0, 0x01, 0x02, 0x00,
+	 0x33, 0xFC, 0x4C, 0x28, 0x62, 0x28, 0xA2, 0x01, 0x02, 0x00, 0x00, 0xFC, 0x4C, 0x28, 0x62, 0x28,
+	 0x56, 0x28, 0x02, 0x00, 0x01, 0xFC, 0x4C, 0x28, 0x62, 0x28, 0x50, 0x28, 0x06, 0x00, 0x02, 0xFC,
+	 0x4C, 0x28, 0xDC, 0x28, 0xA4, 0x29, 0x22, 0x00, 0x05, 0xFC, 0x4C, 0x28, 0x62, 0x28, 0x46, 0x28,
+	 0x02, 0x00, 0x08, 0xFC, 0x4C, 0x28, 0x62, 0x28, 0x4A, 0x28, 0x06, 0x00, 0x09, 0xFC, 0x4C, 0x28,
+	 0x62, 0x28, 0x9E, 0x28, 0x02, 0x00, 0x0B, 0xFC, 0x4C, 0x28, 0x62, 0x28, 0xA0, 0x28, 0x02, 0x00,
+	 0x0C, 0xFC, 0x4C, 0x28, 0x62, 0x28, 0xA2, 0x28, 0x02, 0x00, 0x0D, 0xFC, 0x4C, 0x28, 0x62, 0x28,
+	 0xA4, 0x28, 0x02, 0x00, 0x21, 0xFC, 0x4C, 0x28, 0x62, 0x28, 0xCE, 0x28, 0x02, 0x00, 0x80, 0xFC,
+	 0xB8, 0x28, 0xC8, 0x28, 0xE2, 0x28, 0xC0, 0x00, 0x81, 0xFC, 0x4C, 0x28, 0x62, 0x28, 0xA8, 0x01,
+	 0x02, 0x00, 0x83, 0xFC, 0x4C, 0x28, 0x62, 0x28, 0xAC, 0x01, 0x02, 0x00, 0x85, 0xFC, 0x4C, 0x28,
+	 0x49, 0x2A, 0xA6, 0x01, 0x02, 0x00, 0x86, 0xFC, 0x4C, 0x28, 0x5B, 0x2A, 0xB2, 0x01, 0x02, 0x00,
+	 0x28, 0xFC, 0x4C, 0x28, 0x62, 0x28, 0xDC, 0x28, 0x02, 0x00, 0x87, 0xFC, 0x4C, 0x28, 0x62, 0x28,
+	 0xEC, 0x29, 0x22, 0x03, 0x84, 0xFC, 0x4C, 0x28, 0x70, 0x2A, 0xB0, 0x01, 0x02, 0x00, 0x2B, 0xFC,
+	 0x4C, 0x28, 0x62, 0x28, 0x14, 0x31, 0x02, 0x00, 0xF8, 0xFF, 0x4C, 0x28, 0x62, 0x28, 0x0E, 0x31,
+	 0x02, 0x00, 0xF3, 0xFF, 0x4C, 0x28, 0x62, 0x28, 0x16, 0x31, 0x02, 0x00, 0x20, 0xFD, 0x7D, 0x28,
+	 0x29, 0x28, 0x23, 0x34, 0x08, 0x00, 0x21, 0xFD, 0x7D, 0x28, 0x29, 0x28, 0x27, 0x34, 0x0A, 0x00,
+	 0x22, 0xFD, 0x7D, 0x28, 0x29, 0x28, 0x2C, 0x34, 0x16, 0x00, 0x23, 0xFD, 0x7D, 0x28, 0x29, 0x28,
+	 0x37, 0x34, 0x0A, 0x00, 0x10, 0xFD, 0x4C, 0x28, 0x29, 0x28, 0x74, 0x01, 0x02, 0x00, 0x45, 0xFD,
+	 0x4C, 0x28, 0x29, 0x28, 0x00, 0x01, 0x02, 0x00, 0x47, 0xFD, 0x4C, 0x28, 0x29, 0x28, 0x78, 0x01,
+	 0x02, 0x00, 0x48, 0xFD, 0x9A, 0x29, 0x29, 0x28, 0xA0, 0x01, 0x02, 0x00, 0x49, 0xFD, 0x9A, 0x29,
+	 0x29, 0x28, 0xA2, 0x01, 0x02, 0x00, 0x4A, 0xFD, 0x4C, 0x28, 0x29, 0x28, 0x98, 0x01, 0x02, 0x00,
+	 0x4B, 0xFD, 0x4C, 0x28, 0x29, 0x28, 0x9A, 0x01, 0x02, 0x00, 0x4D, 0xFD, 0x7D, 0x28, 0x29, 0x28,
+	 0x3C, 0x34, 0x04, 0x00, 0x4F, 0xFD, 0xAE, 0x29, 0x29, 0x28, 0x1A, 0x2D, 0x02, 0x00, 0xC0, 0xFD,
+	 0x7D, 0x28, 0x29, 0x28, 0x3E, 0x34, 0x02, 0x00, 0xC2, 0xFD, 0xA4, 0x29, 0x29, 0x28, 0x00, 0x00,
+	 0x02, 0x00, 0xC3, 0xFD, 0x7D, 0x28, 0x29, 0x28, 0x3F, 0x34, 0x02, 0x00, 0x40, 0xFD, 0x75, 0x28,
+	 0x29, 0x28, 0xB8, 0x01, 0x02, 0x00, 0x24, 0xFD, 0xCB, 0x29, 0x29, 0x28, 0x00, 0x00, 0x02, 0x00,
+	 0x91, 0xFD, 0x4C, 0x28, 0x29, 0x28, 0x20, 0x24, 0x02, 0x00, 0x93, 0xFD, 0x4C, 0x28, 0x29, 0x28,
+	 0x26, 0x24, 0x02, 0x00, 0xC1, 0xFD, 0x4C, 0x28, 0x29, 0x28, 0xFE, 0x00, 0x02, 0x00, 0xC6, 0xFD,
+	 0xAA, 0x28, 0x29, 0x28, 0x28, 0x2D, 0x0A, 0x00, 0x89, 0xFD, 0x5B, 0x29, 0x29, 0x28, 0x00, 0x00,
+	 0x00, 0x00, 0x8A, 0xFD, 0x9A, 0x28, 0x29, 0x28, 0xA0, 0x2D, 0x24, 0x00, 0x41, 0xFD, 0x4C, 0x28,
+	 0x29, 0x28, 0x7A, 0x2D, 0x22, 0x00, 0x42, 0xFD, 0x4C, 0x28, 0x29, 0x28, 0x02, 0x01, 0x06, 0x00,
+	 0x43, 0xFD, 0xD8, 0x29, 0x29, 0x28, 0x00, 0x00, 0x06, 0x00, 0x44, 0xFD, 0xB8, 0x29, 0x29, 0x28,
+	 0xB4, 0x01, 0x02, 0x00, 0x46, 0xFD, 0x4C, 0x28, 0x29, 0x28, 0xBA, 0x01, 0x0C, 0x00, 0x4C, 0xFD,
+	 0x4C, 0x28, 0x29, 0x28, 0xEA, 0x29, 0x02, 0x00, 0x50, 0xFD, 0x4C, 0x28, 0x29, 0x28, 0xF4, 0x00,
+	 0x02, 0x00, 0x51, 0xFD, 0x4C, 0x28, 0x29, 0x28, 0xF6, 0x00, 0x02, 0x00, 0x52, 0xFD, 0x4C, 0x28,
+	 0x29, 0x28, 0xC6, 0x01, 0x02, 0x00, 0x8F, 0xFD, 0xEB, 0x29, 0x29, 0x28, 0x00, 0x00, 0x08, 0x00,
+	 0x92, 0xFD, 0x4C, 0x28, 0x29, 0x28, 0x54, 0x2D, 0x02, 0x00, 0x8C, 0xFD, 0x3F, 0x28, 0x29, 0x28,
+	 0x08, 0x2E, 0x56, 0x00, 0x8D, 0xFD, 0x3F, 0x28, 0x29, 0x28, 0x62, 0x2E, 0x14, 0x00, 0x00, 0xF1,
+	 0x46, 0x00, 0xE3, 0x27, 0x3A, 0x01, 0x01, 0xF1, 0x44, 0x07, 0xE1, 0x27, 0x3C, 0x01, 0x00, 0x03,
+	 0x2A, 0x68, 0x1E, 0x00, 0x76, 0x01, 0xFE, 0x00, 0xD6, 0x01, 0x02, 0x01, 0x3E, 0x01, 0xB8, 0x01,
+	 0x74, 0x27, 0x5A, 0x01, 0x20, 0x24, 0x20, 0x00, 0x00, 0x00, 0xBA, 0x1C, 0x00, 0x00, 0xBE, 0x1E,
+	 0x54, 0x01, 0x0B, 0x00, 0xBA, 0x00, 0xE4, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4, 0xAF, 0x37, 0xAF, 0x43, 0xB0,
+	 0x4C, 0xB0, 0x48, 0xAF, 0xDE, 0xAF, 0xB6, 0xAF, 0x1C, 0x33, 0x7F, 0x32, 0x1C, 0x33, 0xF3, 0x32,
+	 0x89, 0x32, 0x7D, 0x32, 0x3B, 0x33, 0x4C, 0x33, 0x4C, 0x33, 0x4C, 0x33, 0x55, 0x33, 0x70, 0x33,
+	 0xCD, 0x33, 0xE9, 0x33, 0xF4, 0x32, 0x07, 0x33, 0xDB, 0x32, 0x10, 0x00, 0x12, 0x00, 0x13, 0x00,
+	 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00,
+	 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x39, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x14, 0x01,
+	 0x14, 0x01, 0x14, 0x01, 0x14, 0x01, 0x14, 0x01, 0x14, 0x01, 0x14, 0x01, 0x14, 0x01, 0xF3, 0x02,
+	 0xAD, 0x03, 0x60, 0x04, 0x04, 0x05, 0x07, 0x06, 0x08, 0x07, 0x0A, 0x08, 0x16, 0x09, 0x44, 0x0A,
+	 0x04, 0x0B, 0x40, 0x0C, 0x80, 0x0D, 0x00, 0x0E, 0x84, 0x0F, 0x01, 0x10, 0x10, 0x11, 0x02, 0x14,
+	 0x40, 0x20, 0x32, 0x21, 0x32, 0x22, 0x04, 0x23, 0x01, 0x24, 0x0F, 0x25, 0x00, 0x26, 0x00, 0x27,
+	 0x00, 0x28, 0x00, 0x29, 0x00, 0x2A, 0x01, 0x2B, 0x06, 0x2C, 0x00, 0x38, 0x00, 0x39, 0xD6, 0x3A,
+	 0x00, 0x3B, 0x00, 0x3C, 0x14, 0x3D, 0x7F, 0x3E, 0x00, 0x3F, 0x68, 0x40, 0x75, 0x41, 0x07, 0x42,
+	 0x07, 0x43, 0x00, 0x45, 0x3B, 0x4A, 0x00, 0x4B, 0x00, 0x4C, 0x0F, 0x4D, 0x02, 0x75, 0x00, 0x76,
+	 0x80, 0x00, 0x08, 0x01, 0x09, 0x01, 0x09, 0x01, 0x0A, 0x01, 0x0A, 0x01, 0x0B, 0x01, 0x0B, 0x01,
+	 0x0C, 0x01, 0x0C, 0x01, 0x0D, 0x01, 0x0D, 0x01, 0x0E, 0x01, 0x0E, 0x01, 0x0F, 0x01, 0x0F, 0x01,
+	 0x10, 0x01, 0x10, 0x01, 0x11, 0x01, 0x11, 0x01, 0x12, 0x01, 0x12, 0x01, 0x13, 0x01, 0x13, 0x01,
+	 0x14, 0x01, 0x14, 0x01, 0x15, 0x01, 0x15, 0x01, 0x16, 0x01, 0x16, 0x01, 0x17, 0x01, 0x17, 0x01,
+	 0x18, 0x01, 0x18, 0x01, 0x19, 0x01, 0x19, 0x01, 0x4D, 0x01, 0x4D, 0x01, 0x4E, 0x01, 0x4E, 0x01,
+	 0x4F, 0x01, 0x4F, 0x01, 0x50, 0x01, 0x50, 0x01, 0x51, 0x01, 0x51, 0x01, 0x52, 0x01, 0x52, 0x01,
+	 0x53, 0x01, 0x53, 0x01, 0x54, 0x01, 0x54, 0x01, 0x65, 0x01, 0x65, 0x01, 0x66, 0x01, 0x66, 0x01,
+	 0x67, 0x01, 0x67, 0x01, 0x68, 0x01, 0x68, 0x01, 0x69, 0x01, 0x69, 0x01, 0x6A, 0x01, 0x6A, 0x01,
+	 0x6B, 0x01, 0x6B, 0x01, 0x6C, 0x01, 0x6C, 0x01, 0x6D, 0x01, 0x6D, 0x01, 0x6E, 0x01, 0x6E, 0x01,
+	 0x6F, 0x01, 0x6F, 0x01, 0x70, 0x01, 0x70, 0x01, 0x71, 0x01, 0x71, 0x01, 0x72, 0x01, 0x72, 0x01,
+	 0x73, 0x01, 0x73, 0x01, 0x74, 0x01, 0x74, 0x01, 0x75, 0x01, 0x75, 0x01, 0x76, 0x01, 0x76, 0x01,
+	 0x77, 0x01, 0x77, 0x01, 0x78, 0x01, 0x78, 0x01, 0x79, 0x01, 0x79, 0x01, 0x7A, 0x01, 0x7A, 0x01,
+	 0x7B, 0x01, 0x7B, 0x01, 0x7C, 0x01, 0x7C, 0x01, 0x7D, 0x01, 0x7D, 0x01, 0x7E, 0x01, 0x7E, 0x01,
+	 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01,
+	 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01,
+	 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01, 0x7F, 0x01,
+	 0x7F, 0x01, 0x80, 0x12, 0x80, 0x12, 0x80, 0x12, 0x80, 0x12, 0x80, 0x12, 0x80, 0x12, 0x80, 0x12,
+	 0x80, 0x12, 0x80, 0x12, 0x80, 0x12, 0x80, 0x12, 0x80, 0x12, 0x80, 0x12, 0x80, 0x12, 0x80, 0x13,
+	 0x80, 0x13, 0x80, 0x13, 0x80, 0x13, 0x80, 0x13, 0x80, 0x13, 0x80, 0x13, 0x80, 0x13, 0x80, 0x13,
+	 0x80, 0x13, 0x80, 0x13, 0x80, 0x13, 0x80, 0x13, 0x80, 0x13, 0x51, 0x44, 0x51, 0x44, 0x51, 0x44,
+	 0x51, 0x44, 0x51, 0x44, 0x51, 0x44, 0x51, 0x44, 0x51, 0x44, 0x51, 0x44, 0x51, 0x44, 0x51, 0x44,
+	 0x51, 0x44, 0x51, 0x44, 0x51, 0x44, 0x22, 0x46, 0x22, 0x46, 0x22, 0x46, 0x22, 0x46, 0x22, 0x46,
+	 0x22, 0x46, 0x22, 0x46, 0x22, 0x46, 0x22, 0x46, 0x22, 0x46, 0x22, 0x46, 0x23, 0x46, 0x23, 0x46,
+	 0x23, 0x46, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47,
+	 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1D, 0x47, 0x9A, 0x48,
+	 0xDA, 0x48, 0x1A, 0x48, 0x5A, 0x48, 0x9A, 0x48, 0xDA, 0x48, 0x1A, 0x48, 0x5A, 0x48, 0x9A, 0x48,
+	 0xDA, 0x48, 0x1A, 0x48, 0x5A, 0x48, 0x9A, 0x48, 0x33, 0x48, 0x78, 0x49, 0x78, 0x49, 0x79, 0x49,
+	 0x79, 0x49, 0x79, 0x49, 0x79, 0x49, 0x7A, 0x49, 0x7A, 0x49, 0x7A, 0x49, 0x7A, 0x49, 0x7B, 0x49,
+	 0x7B, 0x49, 0x7B, 0x49, 0x7C, 0x49, 0x32, 0x00, 0x46, 0x00, 0x5A, 0x00, 0x6E, 0x00, 0x82, 0x00,
+	 0x96, 0x00, 0xAA, 0x00, 0xBE, 0x00, 0xD2, 0x00, 0xE6, 0x00, 0xFA, 0x00, 0x0E, 0x01, 0x22, 0x01,
+	 0x52, 0x01, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x03, 0x00,
+	 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x03, 0x00, 0x15, 0x00, 0x6E, 0x6F, 0x6E, 0x2D, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65,
+	 0x64, 0x20, 0x53, 0x53, 0x49, 0x44, 0x20, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x01, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x09, 0x00, 0x00, 0x01, 0x00, 0x64, 0x00, 0x64, 0x00,
+	 0x00, 0x00, 0x48, 0x45, 0x52, 0x4D, 0x45, 0x53, 0x20, 0x32, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
+	 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00,
+	 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x03, 0x00, 0x15, 0x00, 0x6E, 0x6F, 0x6E, 0x2D, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65,
+	 0x64, 0x20, 0x53, 0x53, 0x49, 0x44, 0x20, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x01, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x09, 0x00, 0x00, 0x01, 0x00, 0x64, 0x00, 0x64, 0x00,
+	 0x00, 0x00, 0x48, 0x45, 0x52, 0x4D, 0x45, 0x53, 0x20, 0x32, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
+	 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x46, 0x69, 0x72, 0x73, 0x74, 0x20, 0x57, 0x61, 0x76, 0x65, 0x4C, 0x41, 0x4E, 0x20, 0x49, 0x49,
+	 0x20, 0x53, 0x53, 0x49, 0x44, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x19, 0x00, 0x02, 0x01, 0x82, 0x84, 0x8B, 0x96, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x85, 0x00, 0x01,
+	 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x01,
+	 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x53,
+	 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, 0x53, 0x65, 0x74, 0x20, 0x49, 0x64, 0x65, 0x6E, 0x74,
+	 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0xDD, 0x00, 0x50, 0xF2, 0x01,
+	 0x01, 0x00, 0x00, 0x50, 0xF2, 0x05, 0x02, 0x00, 0x00, 0x50, 0xF2, 0x02, 0x00, 0x50, 0xF2, 0x04,
+	 0x02, 0x00, 0x00, 0x50, 0xF2, 0x00, 0x00, 0x50, 0xF2, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x15, 0x00, 0x14, 0x00, 0x15, 0x00, 0x36, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00,
+	 0x11, 0x00, 0x36, 0x00, 0x01, 0x00, 0x04, 0x00, 0x7A, 0x2D, 0x28, 0x2D, 0x0C, 0x2F, 0x10, 0x2F,
+	 0x14, 0x2F, 0xA0, 0x2D, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x29, 0x28, 0x2D,
+	 0xFF, 0xFF, 0x00, 0x00, 0x7A, 0x2D, 0x28, 0x2D, 0x0C, 0x2F, 0x10, 0x2F, 0x14, 0x2F, 0xA0, 0x2D,
+	 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7A, 0x2D, 0x28, 0x2D, 0xFF, 0xFF, 0xE6, 0x2D,
+	 0x34, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x00, 0x02, 0x06, 0x00, 0x00, 0x06, 0x07,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+	 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+};  /* fw_image_2_data */
+
+static const hcf_8 fw_image_3_data[] = {
+	 0x00, 0xE1, 0x30, 0x40, 0x02, 0x36, 0xA1, 0xFF, 0x83, 0xFF, 0x8D, 0xFF, 0x5C, 0x44, 0x5C, 0x43,
+	 0x5C, 0x42, 0x5C, 0x41, 0x5C, 0x40, 0xAC, 0xFF, 0xAD, 0xFF, 0xE7, 0xE1, 0xAD, 0x60, 0x08, 0x78,
+	 0xFF, 0xFF, 0x30, 0x44, 0x02, 0xA8, 0x00, 0xE1, 0x03, 0x02, 0x28, 0xE2, 0x40, 0xFF, 0xA1, 0xFF,
+	 0x84, 0xFF, 0xBB, 0x60, 0x18, 0x64, 0x40, 0x42, 0xB0, 0x60, 0x97, 0x64, 0x40, 0x40, 0xBD, 0xF3,
+	 0x80, 0xFB, 0x0F, 0x60, 0x9A, 0x63, 0xCA, 0xF3, 0xBD, 0xDB, 0x00, 0x60, 0x9A, 0x64, 0xBD, 0xDB,
+	 0x02, 0x64, 0xBD, 0xDB, 0x04, 0x64, 0xA3, 0xDB, 0x5C, 0x49, 0x0A, 0x64, 0x40, 0x4B, 0x5C, 0x5C,
+	 0x01, 0x60, 0x39, 0xE2, 0x04, 0x60, 0x00, 0x7A, 0x89, 0xFF, 0x03, 0x60, 0xFF, 0x73, 0x88, 0xFF,
+	 0xB0, 0x60, 0x97, 0x78, 0xFF, 0xFF, 0x30, 0x44, 0x02, 0xA8, 0x00, 0xE1, 0x06, 0x02, 0x40, 0xFF,
+	 0x42, 0xFF, 0x43, 0xFF, 0x44, 0xFF, 0x45, 0xFF, 0xA1, 0xFF, 0x88, 0xFF, 0x85, 0xFF, 0x21, 0xE1,
+	 0x5C, 0x40, 0xBB, 0x60, 0x20, 0x78, 0xFF, 0xFF, 0xA2, 0xFF, 0x30, 0x44, 0x02, 0xA8, 0x00, 0xE1,
+	 0x01, 0x02, 0xA1, 0xFF, 0x86, 0xFF, 0x88, 0xFF, 0x5C, 0x46, 0x5C, 0x49, 0x5C, 0x40, 0xE7, 0x60,
+	 0x58, 0x4F, 0x31, 0x78, 0xFF, 0xFF, 0xC7, 0x60, 0x58, 0x4F, 0xF6, 0x78, 0xFF, 0xFF, 0xCA, 0x60,
+	 0x58, 0x4F, 0x83, 0x78, 0xFF, 0xFF, 0xDD, 0x60, 0x58, 0x4F, 0x3D, 0x78, 0xFF, 0xFF, 0x1B, 0x60,
+	 0x58, 0x4F, 0x37, 0x78, 0xFF, 0xFF, 0xEC, 0x60, 0x58, 0x4F, 0x75, 0x78, 0xFF, 0xFF, 0xE0, 0x60,
+	 0x58, 0x4F, 0x1B, 0x78, 0xFF, 0xFF, 0xE4, 0x60, 0x58, 0x4F, 0xDC, 0x78, 0xFF, 0xFF, 0xF3, 0x60,
+	 0x58, 0x4F, 0xEB, 0x78, 0xFF, 0xFF, 0x13, 0xE1, 0xA3, 0xFF, 0xBF, 0x60, 0xE7, 0x78, 0xFF, 0xFF,
+	 0x03, 0xE1, 0xA3, 0xFF, 0xFE, 0xFC, 0xFF, 0xFC, 0x23, 0x60, 0xF4, 0x63, 0x17, 0xFD, 0xAE, 0xFF,
+	 0x25, 0x60, 0x11, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x08, 0x26, 0x1A, 0x00,
+	 0x80, 0x3A, 0x15, 0x00, 0x81, 0xF1, 0x32, 0xF2, 0x33, 0xF2, 0xD0, 0x80, 0x82, 0xF1, 0x0F, 0x02,
+	 0xD0, 0x80, 0x34, 0xF2, 0x83, 0xF1, 0x0B, 0x02, 0xD0, 0x80, 0xFF, 0xFF, 0x08, 0x02, 0xDF, 0x60,
+	 0x58, 0x4F, 0x28, 0x78, 0xFF, 0xFF, 0x20, 0x60, 0x58, 0x4F, 0xBF, 0x78, 0xFF, 0xFF, 0x19, 0x60,
+	 0xE8, 0x78, 0xFF, 0xFF, 0x00, 0xF4, 0xAA, 0x60, 0xAA, 0x65, 0x09, 0xF2, 0x5A, 0xD0, 0xD4, 0x80,
+	 0x03, 0x64, 0x12, 0x02, 0xD0, 0x80, 0x1D, 0x60, 0x60, 0x65, 0x0E, 0x02, 0x5A, 0xD2, 0xFF, 0xFF,
+	 0xD4, 0x80, 0x01, 0x60, 0x00, 0x65, 0x08, 0x02, 0x5A, 0xD2, 0xFF, 0xFF, 0xD4, 0x80, 0xFF, 0xFF,
+	 0x03, 0x02, 0x19, 0x60, 0xE8, 0x78, 0xFF, 0xFF, 0x01, 0x60, 0xD6, 0x65, 0xA5, 0xD1, 0x5A, 0xD1,
+	 0x44, 0x48, 0x5A, 0xD1, 0x44, 0x4A, 0x26, 0x46, 0x3F, 0xF2, 0x00, 0xF4, 0x44, 0x4C, 0xD8, 0x83,
+	 0x70, 0x61, 0x68, 0x65, 0xD7, 0x80, 0xFF, 0xFF, 0x07, 0x0E, 0x08, 0xF2, 0x08, 0x00, 0x68, 0x65,
+	 0xD7, 0x80, 0xFF, 0xFF, 0x01, 0x0E, 0x03, 0x00, 0x19, 0x60, 0xFE, 0x78, 0xFF, 0xFF, 0x58, 0x4F,
+	 0x79, 0x00, 0x9C, 0x80, 0x01, 0x65, 0x02, 0x02, 0x00, 0x65, 0x02, 0x00, 0xFF, 0x3B, 0xF7, 0x01,
+	 0x58, 0x4F, 0x70, 0x00, 0x9C, 0x80, 0x45, 0x42, 0xEA, 0x02, 0x58, 0x4F, 0x6B, 0x00, 0x9C, 0x80,
+	 0xFF, 0xFF, 0xE5, 0x02, 0x58, 0x4F, 0x66, 0x00, 0x9C, 0x80, 0xFF, 0xFF, 0x03, 0x02, 0x00, 0x65,
+	 0x45, 0x42, 0xF8, 0x01, 0xFF, 0x3A, 0x29, 0x00, 0x60, 0x47, 0xFF, 0xB5, 0x28, 0x44, 0xFF, 0xB4,
+	 0x94, 0x80, 0xFF, 0xFF, 0xD4, 0x02, 0x60, 0x45, 0x28, 0x47, 0x2A, 0x5F, 0x40, 0x48, 0x2A, 0x47,
+	 0x2C, 0x5F, 0x40, 0x4A, 0x2C, 0x47, 0x65, 0x5F, 0x40, 0x4C, 0x10, 0x64, 0x40, 0x42, 0x28, 0x45,
+	 0x05, 0x00, 0x58, 0x4F, 0x47, 0x00, 0x94, 0x80, 0x28, 0x45, 0x26, 0x02, 0x58, 0x4F, 0x42, 0x00,
+	 0x94, 0x80, 0x2A, 0x45, 0x21, 0x02, 0x58, 0x4F, 0x3D, 0x00, 0x94, 0x80, 0xFF, 0xFF, 0x1C, 0x02,
+	 0x22, 0x44, 0x4C, 0x82, 0x2C, 0x45, 0x31, 0x03, 0xEC, 0x01, 0x10, 0x65, 0x45, 0x42, 0x28, 0x45,
+	 0x94, 0x80, 0x2A, 0x45, 0x21, 0x02, 0x58, 0x4F, 0x2D, 0x00, 0x94, 0x80, 0x2C, 0x45, 0x1C, 0x02,
+	 0x58, 0x4F, 0x28, 0x00, 0x94, 0x80, 0xFF, 0xFF, 0x17, 0x02, 0x22, 0x44, 0x4C, 0x82, 0x28, 0x45,
+	 0x1C, 0x03, 0x58, 0x4F, 0x1F, 0x00, 0xEC, 0x01, 0x40, 0x4B, 0x28, 0x47, 0x40, 0x48, 0x2A, 0x47,
+	 0x40, 0x4A, 0x2C, 0x47, 0x60, 0x45, 0x2A, 0x5E, 0x40, 0x4C, 0x2A, 0x44, 0x28, 0x5E, 0x40, 0x4A,
+	 0x28, 0x44, 0x65, 0x5E, 0x40, 0x48, 0x2B, 0x44, 0x68, 0x65, 0xD7, 0x80, 0xFF, 0xFF, 0x17, 0x0E,
+	 0x90, 0x01, 0x26, 0x46, 0xC5, 0x60, 0x5B, 0x78, 0xFF, 0xFF, 0xB9, 0xFF, 0x26, 0x46, 0xC5, 0x60,
+	 0x5B, 0x78, 0xFF, 0xFF, 0xC9, 0x81, 0xCB, 0x83, 0x07, 0x1C, 0x01, 0x1D, 0x08, 0x00, 0x00, 0xF4,
+	 0x01, 0xF2, 0xFF, 0xFF, 0xFF, 0xB4, 0xD8, 0x81, 0x5A, 0xD2, 0x2F, 0x58, 0xFF, 0xFF, 0x26, 0x46,
+	 0xC5, 0x60, 0x58, 0x4F, 0x78, 0x78, 0xFF, 0xFF, 0x02, 0x60, 0x00, 0x63, 0x00, 0xF4, 0x84, 0x65,
+	 0x78, 0x61, 0xA5, 0xD0, 0xDA, 0x85, 0x80, 0x3A, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0x64, 0x44,
+	 0x00, 0x7F, 0xCD, 0x81, 0xBD, 0xDB, 0x05, 0x03, 0x64, 0x47, 0x00, 0x7F, 0xCD, 0x81, 0xBD, 0xDB,
+	 0xF0, 0x02, 0x1C, 0x60, 0xAC, 0x63, 0x29, 0x60, 0xEC, 0x64, 0x08, 0x65, 0xC4, 0x81, 0x61, 0x44,
+	 0xA3, 0xDB, 0x1C, 0x60, 0xAA, 0x61, 0x00, 0x64, 0xA1, 0xDB, 0x29, 0x60, 0xEC, 0x61, 0xA1, 0xD3,
+	 0xFF, 0xFF, 0x60, 0x43, 0x1C, 0x60, 0xB0, 0x61, 0xA1, 0xDD, 0x1C, 0x60, 0xB0, 0x61, 0xA1, 0xD3,
+	 0xFF, 0xFF, 0x60, 0x45, 0x1C, 0x60, 0xAA, 0x61, 0xA1, 0xD3, 0xFF, 0xFF, 0xD4, 0x80, 0xFF, 0xFF,
+	 0x01, 0x03, 0x03, 0x00, 0x1A, 0x60, 0xD6, 0x78, 0xFF, 0xFF, 0x1C, 0x60, 0xA8, 0x61, 0x01, 0x64,
+	 0xA1, 0xDB, 0x02, 0x60, 0x00, 0x61, 0x41, 0x4C, 0x03, 0x60, 0x00, 0x61, 0x41, 0x4A, 0x1C, 0x60,
+	 0xAC, 0x61, 0xA1, 0xD3, 0xFF, 0xFF, 0x40, 0x48, 0x1C, 0x60, 0xB2, 0x63, 0x28, 0x41, 0x06, 0x65,
+	 0xD5, 0x81, 0xA1, 0xD3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x26, 0x01, 0xA4, 0x60, 0x41, 0xA3, 0xDB,
+	 0x2A, 0x43, 0x28, 0x45, 0xA5, 0xD1, 0xDA, 0x85, 0x64, 0x44, 0x00, 0x7F, 0xCD, 0x81, 0xBD, 0xDB,
+	 0x05, 0x03, 0x64, 0x47, 0x00, 0x7F, 0xCD, 0x81, 0xBD, 0xDB, 0xF4, 0x02, 0x28, 0x41, 0x1C, 0x60,
+	 0xB2, 0x63, 0xA3, 0xD3, 0xFF, 0xFF, 0x60, 0x45, 0x45, 0x8B, 0x1C, 0x60, 0xAE, 0x61, 0x2B, 0xD3,
+	 0xA1, 0xDB, 0x2C, 0x41, 0x28, 0x42, 0x4A, 0xD3, 0xFF, 0xFF, 0x60, 0x45, 0x45, 0x8C, 0x00, 0x7F,
+	 0x01, 0x7E, 0x40, 0x48, 0x1C, 0x60, 0xB2, 0x61, 0xA1, 0xD3, 0xFF, 0xFF, 0x60, 0x45, 0x00, 0x64,
+	 0xD4, 0x80, 0xFF, 0xFF, 0x43, 0x03, 0x65, 0x44, 0xFF, 0xA4, 0xA1, 0xDB, 0x1C, 0x60, 0xAE, 0x61,
+	 0xA1, 0xD3, 0x28, 0x45, 0xA4, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x2C, 0xD3, 0x2A, 0xD3, 0x60, 0x45,
+	 0xD4, 0x80, 0xFF, 0xFF, 0x01, 0x03, 0x14, 0x00, 0x28, 0x44, 0xE0, 0x84, 0xFF, 0xFF, 0x02, 0x24,
+	 0x01, 0x00, 0x08, 0x00, 0x2B, 0x44, 0x58, 0x8B, 0x1C, 0x60, 0xAE, 0x63, 0x2B, 0xD3, 0xA3, 0xDB,
+	 0x00, 0x7F, 0x01, 0x7E, 0x40, 0x48, 0x2A, 0x44, 0x58, 0x8A, 0x2C, 0x44, 0x58, 0x8C, 0xD2, 0x01,
+	 0x1C, 0x60, 0xA8, 0x61, 0x00, 0x64, 0xA1, 0xDB, 0x1C, 0x60, 0xAC, 0x61, 0xA1, 0xD3, 0xFF, 0xFF,
+	 0x60, 0x45, 0xFA, 0xA4, 0x60, 0x41, 0xA1, 0xD3, 0xFF, 0xFF, 0x60, 0x41, 0xC5, 0x81, 0x06, 0xA1,
+	 0x41, 0x48, 0x65, 0x41, 0xFC, 0xA1, 0xA1, 0xD3, 0x28, 0x41, 0x60, 0x40, 0x01, 0x26, 0x01, 0xA4,
+	 0x60, 0x45, 0xC5, 0x81, 0x61, 0x43, 0x1C, 0x60, 0xAC, 0x61, 0xA1, 0xDD, 0x1C, 0x60, 0xA8, 0x61,
+	 0xA1, 0xD3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x26, 0x0D, 0x00, 0x1C, 0x60, 0xAA, 0x61, 0xA1, 0xD3,
+	 0xFF, 0xFF, 0x01, 0xA4, 0xA1, 0xDB, 0xFF, 0xFF, 0x1A, 0x60, 0x2C, 0x78, 0xFF, 0xFF, 0x19, 0x60,
+	 0xE8, 0x78, 0xFF, 0xFF, 0x19, 0x60, 0xEC, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x01, 0x60, 0xBA, 0x61,
+	 0x1F, 0x60, 0x08, 0x63, 0xA1, 0xD3, 0x04, 0xA1, 0x20, 0x7F, 0xBD, 0xDB, 0x32, 0x7E, 0x21, 0x7F,
+	 0xBD, 0xDB, 0xA1, 0xD3, 0xFF, 0xFF, 0x22, 0x7F, 0xA3, 0xDB, 0x10, 0x00, 0x01, 0x60, 0xBA, 0x61,
+	 0x1F, 0x60, 0x08, 0x63, 0xA1, 0xD3, 0x00, 0x66, 0x20, 0x7F, 0xBD, 0xDB, 0x59, 0xD3, 0xFF, 0xFF,
+	 0x21, 0x7F, 0xBD, 0xDB, 0x59, 0xD3, 0xFF, 0xFF, 0x22, 0x7F, 0xA3, 0xDB, 0x0F, 0x60, 0xD8, 0x62,
+	 0xA2, 0xD1, 0x9F, 0x60, 0xFF, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0xDE, 0xFE, 0x0B, 0x04, 0x0F, 0x60,
+	 0xDA, 0x62, 0x40, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0x1A, 0x60, 0xFD, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x24, 0x60, 0x9A, 0x62, 0x1F, 0x60, 0x06, 0x64, 0xA2, 0xDB, 0x20, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x0F, 0x60, 0xDA, 0x62, 0x20, 0x60, 0x00, 0x64, 0xA2, 0xDB,
+	 0x1B, 0x60, 0x25, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xD8, 0x62,
+	 0xA2, 0xD1, 0x9F, 0x60, 0xFF, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0xBE, 0xFE, 0x0F, 0x60, 0xD0, 0x62,
+	 0xA2, 0xD1, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x2E, 0x58, 0xFF, 0xFF,
+	 0x10, 0x60, 0x1E, 0x62, 0x1E, 0x60, 0xF4, 0x64, 0xA2, 0xDB, 0x1A, 0x60, 0x8A, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0x06, 0xA2, 0x10, 0x60, 0x40, 0x64, 0xA2, 0xDB, 0x06, 0x64, 0x5A, 0xDB, 0x5A, 0xDB,
+	 0x1A, 0x60, 0x96, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x06, 0xA2, 0x10, 0x60, 0x44, 0x64, 0xA2, 0xDB,
+	 0x06, 0x64, 0x5A, 0xDB, 0x5A, 0xDB, 0x1A, 0x60, 0xA2, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x06, 0xA2,
+	 0x10, 0x60, 0x48, 0x64, 0xA2, 0xDB, 0x06, 0x64, 0x5A, 0xDB, 0x5A, 0xDB, 0xC0, 0xF1, 0x1A, 0x60,
+	 0xA6, 0x62, 0xA2, 0xD9, 0x10, 0x60, 0x3E, 0x62, 0x20, 0x60, 0x99, 0x64, 0xA2, 0xDB, 0x10, 0x60,
+	 0x42, 0x62, 0x20, 0x60, 0xA3, 0x64, 0xA2, 0xDB, 0x10, 0x60, 0x46, 0x62, 0x20, 0x60, 0xAD, 0x64,
+	 0xA2, 0xDB, 0x00, 0x60, 0x70, 0x61, 0xAE, 0x60, 0x58, 0x4D, 0xC4, 0x78, 0xFF, 0xFF, 0x66, 0x44,
+	 0x63, 0xFB, 0x04, 0x64, 0x03, 0xFA, 0xA9, 0xF3, 0x07, 0xFA, 0x00, 0x64, 0x3E, 0xFA, 0x3F, 0xFA,
+	 0x0F, 0x60, 0xDA, 0x62, 0x00, 0x60, 0x02, 0x64, 0xA2, 0xDB, 0x1B, 0x60, 0x8A, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xD8, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x03, 0x64,
+	 0x6A, 0xFB, 0x0F, 0x4E, 0xE0, 0x60, 0x58, 0x4F, 0x8E, 0x78, 0xFF, 0xFF, 0x0E, 0x4F, 0x00, 0x64,
+	 0x6C, 0xFB, 0x63, 0xF5, 0xEB, 0xF3, 0x2F, 0xFA, 0xEC, 0xF3, 0x30, 0xFA, 0xED, 0xF3, 0x31, 0xFA,
+	 0x81, 0xF3, 0x2C, 0xFA, 0x32, 0xFA, 0x82, 0xF3, 0x2D, 0xFA, 0x33, 0xFA, 0x83, 0xF3, 0x2E, 0xFA,
+	 0x34, 0xFA, 0xBC, 0xF3, 0x19, 0xFA, 0x06, 0x60, 0x80, 0x64, 0x0E, 0xFA, 0x20, 0x60, 0x58, 0x4E,
+	 0x71, 0x78, 0xFF, 0xFF, 0xF7, 0x60, 0xFF, 0x65, 0x20, 0x44, 0x24, 0x80, 0x0F, 0x60, 0xD0, 0x62,
+	 0xA2, 0xD1, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x0F, 0x60, 0xD8, 0x62,
+	 0xA2, 0xD1, 0xFF, 0x60, 0x8F, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0xC1, 0xF1, 0x1A, 0x60, 0x9A, 0x62,
+	 0xA2, 0xD9, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x96, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB,
+	 0xFF, 0xFF, 0x04, 0xFF, 0x00, 0x64, 0x6C, 0xFB, 0x0F, 0x60, 0xDA, 0x62, 0x00, 0x60, 0x74, 0x64,
+	 0xA2, 0xDB, 0x1B, 0x60, 0xDE, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60,
+	 0xD8, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x04, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x05, 0x03, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x1E, 0x60, 0xF4, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x40, 0x64, 0xA0, 0x80, 0x9C, 0x84,
+	 0x03, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xE0, 0x01, 0x00, 0x60, 0x20, 0x64, 0xA0, 0x80, 0x9C, 0x84,
+	 0x11, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x20, 0x40, 0x50, 0x27, 0xD6, 0x01, 0xAF, 0xF3, 0xFF, 0xFF,
+	 0xFE, 0xA0, 0xFF, 0xFF, 0xD1, 0x06, 0x6C, 0xF3, 0xFF, 0xFF, 0xF6, 0xA0, 0xDC, 0x84, 0x01, 0x05,
+	 0xA2, 0xDB, 0xCA, 0x01, 0x00, 0x60, 0x10, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0xCE, 0x03, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x00, 0x00, 0xE0, 0xF3, 0x29, 0x45, 0xD4, 0x80, 0x6C, 0xF3, 0x03, 0x04, 0x1C, 0x60,
+	 0x55, 0x78, 0xFF, 0xFF, 0xF6, 0xA0, 0xFF, 0xFF, 0x03, 0x04, 0x1C, 0x60, 0x55, 0x78, 0xFF, 0xFF,
+	 0x0F, 0x60, 0xDA, 0x62, 0x00, 0x60, 0x64, 0x64, 0xA2, 0xDB, 0x1C, 0x60, 0x2A, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xD8, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x04, 0x64,
+	 0xA0, 0x80, 0x9C, 0x84, 0x05, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x1E, 0x60, 0xF4, 0x78, 0xFF, 0xFF,
+	 0x00, 0x60, 0x40, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x03, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xD2, 0x01,
+	 0x00, 0x60, 0x20, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0xE4, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x20, 0x40,
+	 0x50, 0x27, 0xDF, 0x01, 0xAF, 0xF3, 0xFF, 0xFF, 0xFE, 0xA0, 0xFF, 0xFF, 0xC3, 0x06, 0x6C, 0xF3,
+	 0xFF, 0xFF, 0xF6, 0xA0, 0xDC, 0x84, 0x01, 0x05, 0xA2, 0xDB, 0xBC, 0x01, 0x0F, 0x60, 0xD8, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x20, 0x40, 0x40, 0x2B, 0x0B, 0x00, 0x0F, 0x60, 0xDA, 0x62, 0x80, 0x60,
+	 0x00, 0x64, 0xA2, 0xDB, 0x1C, 0x60, 0x55, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x1C, 0x60, 0x92, 0x65, 0x01, 0x64, 0xA5, 0xDB, 0xC2, 0xF1, 0x1A, 0x60, 0x9A, 0x62, 0xA2, 0xD9,
+	 0x0C, 0x64, 0x53, 0xFB, 0x1C, 0x60, 0x77, 0x64, 0x6B, 0xFB, 0x1F, 0x60, 0x72, 0x78, 0xFF, 0xFF,
+	 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0xA2, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x04, 0xFF, 0x0F, 0x60, 0xD8, 0x62, 0xA2, 0xD1, 0xFF, 0x60, 0xDF, 0x64, 0xA0, 0x84, 0xA2, 0xDB,
+	 0x88, 0xF1, 0x19, 0x60, 0x86, 0x63, 0xD3, 0x80, 0x68, 0xFD, 0x5F, 0x03, 0x68, 0xF3, 0xE2, 0xF1,
+	 0x60, 0x43, 0x29, 0x44, 0xA3, 0xD3, 0xC0, 0x85, 0xD4, 0x80, 0x5B, 0xD3, 0x56, 0x06, 0x60, 0x43,
+	 0x08, 0xA3, 0xBE, 0xD3, 0x83, 0xF1, 0xA3, 0xD3, 0xD0, 0x80, 0x82, 0xF1, 0x05, 0x02, 0xBF, 0xD3,
+	 0xD0, 0x80, 0x81, 0xF1, 0x01, 0x02, 0xD0, 0x80, 0xF8, 0xA3, 0x2B, 0x02, 0x1C, 0x60, 0xAB, 0x64,
+	 0x6B, 0xFB, 0x1F, 0x60, 0x29, 0x78, 0xFF, 0xFF, 0x01, 0xB0, 0x84, 0xF3, 0x3E, 0x03, 0x63, 0xF5,
+	 0x48, 0x7E, 0x2A, 0xFA, 0x24, 0x60, 0x74, 0x62, 0x24, 0x60, 0x28, 0x64, 0xA2, 0xDB, 0x66, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x0F, 0x60, 0xDA, 0x62,
+	 0x00, 0x60, 0x01, 0x64, 0xA2, 0xDB, 0x1C, 0x60, 0xC8, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x0F, 0x60, 0xD8, 0x62, 0xA2, 0xD1, 0xFF, 0x60, 0xFE, 0x64, 0xA0, 0x84, 0xA2, 0xDB,
+	 0x1C, 0x00, 0x2D, 0x60, 0x7A, 0x65, 0xA5, 0xD3, 0x65, 0x41, 0x10, 0xA3, 0x01, 0xA4, 0xFE, 0xB4,
+	 0xC4, 0x85, 0xFE, 0xA1, 0xBD, 0xD3, 0x59, 0xD1, 0xFF, 0xFF, 0xD0, 0x80, 0xD5, 0x80, 0x05, 0x02,
+	 0x01, 0x03, 0xF8, 0x01, 0x1E, 0x60, 0xE8, 0x78, 0xFF, 0xFF, 0x68, 0xF3, 0x88, 0xF1, 0x04, 0xA4,
+	 0xD0, 0x80, 0xFF, 0xFF, 0x02, 0x03, 0x68, 0xFB, 0xA1, 0x01, 0xE0, 0xF3, 0x29, 0x45, 0xD4, 0x80,
+	 0xFF, 0xFF, 0x0C, 0x07, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x96, 0x64, 0xA2, 0xDB, 0x03, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x1B, 0x60, 0xB1, 0x78, 0xFF, 0xFF, 0xE1, 0xF3, 0x29, 0x45,
+	 0xD4, 0x80, 0xFF, 0xFF, 0x17, 0x06, 0x04, 0x65, 0xE9, 0x60, 0x58, 0x4E, 0x7B, 0x78, 0xFF, 0xFF,
+	 0x05, 0x64, 0xDC, 0xFB, 0xF2, 0xF3, 0xFF, 0xFF, 0x01, 0xBC, 0xF2, 0xFB, 0x24, 0x60, 0xAA, 0x62,
+	 0x1A, 0x60, 0x96, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x1D, 0x60,
+	 0x6D, 0x78, 0xFF, 0xFF, 0x0F, 0x60, 0xDA, 0x62, 0x00, 0x60, 0x74, 0x64, 0xA2, 0xDB, 0x1D, 0x60,
+	 0x24, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xD8, 0x62, 0xA2, 0xD1,
+	 0x00, 0x60, 0x04, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x05, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x1E, 0x60,
+	 0xF4, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x40, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x05, 0x03, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x1C, 0x60, 0x87, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x20, 0x64, 0xA0, 0x80, 0x9C, 0x84,
+	 0x17, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x20, 0x40, 0x50, 0x27, 0xA7, 0x01, 0xAF, 0xF3, 0x6C, 0xF3,
+	 0xFE, 0xA0, 0xF6, 0xA0, 0x0A, 0x06, 0x03, 0x04, 0x00, 0x64, 0x55, 0xFB, 0x40, 0x49, 0x6C, 0xF3,
+	 0xFF, 0xFF, 0xF6, 0xA0, 0xDC, 0x84, 0x01, 0x05, 0xA2, 0xDB, 0x1C, 0x60, 0x87, 0x78, 0xFF, 0xFF,
+	 0x00, 0x60, 0x10, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0xC6, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x24, 0x60,
+	 0xAA, 0x62, 0x1A, 0x60, 0xA2, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF,
+	 0x1C, 0x60, 0x55, 0x78, 0xFF, 0xFF, 0x1C, 0x60, 0xEC, 0x78, 0xFF, 0xFF, 0x0F, 0x60, 0xD8, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x20, 0x40, 0x40, 0x2B, 0x0B, 0x00, 0x0F, 0x60, 0xDA, 0x62, 0x80, 0x60,
+	 0x00, 0x64, 0xA2, 0xDB, 0x1D, 0x60, 0x6D, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x1C, 0x60, 0x92, 0x65, 0x00, 0x64, 0xA5, 0xDB, 0xC3, 0xF1, 0x1A, 0x60, 0x9A, 0x62, 0xA2, 0xD9,
+	 0x1F, 0x60, 0x80, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0x08, 0xB4, 0x01, 0xBC, 0x29, 0x02, 0xA2, 0xDB,
+	 0x0F, 0x60, 0xD8, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x0F, 0x4E, 0xE4, 0x60, 0x58, 0x4F, 0xFB, 0x78,
+	 0xFF, 0xFF, 0x0E, 0x4F, 0x0F, 0x60, 0xDA, 0x62, 0x10, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0x1D, 0x60,
+	 0xA4, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x1F, 0x60, 0x80, 0x64, 0xA0, 0xD3,
+	 0xFF, 0xFF, 0x60, 0x40, 0x0C, 0x26, 0x0C, 0x00, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x96, 0x64,
+	 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x1E, 0x60, 0x97, 0x78, 0xFF, 0xFF,
+	 0x01, 0x64, 0x31, 0x60, 0x2A, 0x62, 0xA2, 0xDB, 0x0D, 0x64, 0x53, 0xFB, 0x1D, 0x60, 0xC3, 0x64,
+	 0x6B, 0xFB, 0x1F, 0x60, 0x72, 0x78, 0xFF, 0xFF, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0xA2, 0x64,
+	 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x0F, 0x60, 0xD8, 0x62, 0xA2, 0xD1,
+	 0xFF, 0x60, 0xDF, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x88, 0xF1, 0x19, 0x60, 0x86, 0x63, 0xD3, 0x80,
+	 0x68, 0xFD, 0x01, 0x02, 0x43, 0x00, 0x68, 0xF3, 0x29, 0x41, 0xA0, 0xD1, 0x58, 0xD3, 0xD1, 0x80,
+	 0x64, 0x45, 0x60, 0x43, 0x0F, 0x05, 0x08, 0xA3, 0xBE, 0xD3, 0x83, 0xF1, 0xA3, 0xD3, 0xD0, 0x80,
+	 0x82, 0xF1, 0x05, 0x02, 0xBF, 0xD3, 0xD0, 0x80, 0x81, 0xF1, 0x01, 0x02, 0xD0, 0x80, 0xF8, 0xA3,
+	 0x07, 0x02, 0x45, 0x49, 0x1E, 0x60, 0x2A, 0x64, 0x6B, 0xFB, 0x1F, 0x60, 0x29, 0x78, 0xFF, 0xFF,
+	 0x2D, 0x60, 0x7A, 0x65, 0xA5, 0xD3, 0x65, 0x41, 0x10, 0xA3, 0x01, 0xA4, 0xFE, 0xB4, 0xC4, 0x85,
+	 0xFE, 0xA1, 0xBD, 0xD3, 0x59, 0xD1, 0xFF, 0xFF, 0xD0, 0x80, 0xD5, 0x80, 0x0F, 0x02, 0xF9, 0x02,
+	 0x05, 0x65, 0xE9, 0x60, 0x58, 0x4E, 0x7B, 0x78, 0xFF, 0xFF, 0x04, 0x64, 0xDC, 0xFB, 0xF2, 0xF3,
+	 0xFF, 0xFF, 0xFE, 0xB4, 0xF2, 0xFB, 0x1E, 0x60, 0xE8, 0x78, 0xFF, 0xFF, 0x68, 0xF3, 0x88, 0xF1,
+	 0x04, 0xA4, 0xD0, 0x80, 0xFF, 0xFF, 0x02, 0x03, 0x68, 0xFB, 0xBD, 0x01, 0xE1, 0xF3, 0x29, 0x45,
+	 0xD4, 0x80, 0xFF, 0xFF, 0x75, 0x05, 0x1E, 0x60, 0x2A, 0x63, 0x6B, 0xFD, 0x1A, 0x60, 0x4C, 0x63,
+	 0x1F, 0x60, 0x29, 0x78, 0xFF, 0xFF, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x96, 0x64, 0xA2, 0xDB,
+	 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x05, 0x65, 0xE9, 0x60, 0x58, 0x4E, 0x7B, 0x78,
+	 0xFF, 0xFF, 0x1F, 0x60, 0x52, 0x61, 0x00, 0x64, 0xA1, 0xDB, 0x04, 0x64, 0xDC, 0xFB, 0xF2, 0xF3,
+	 0xFF, 0xFF, 0xFE, 0xB4, 0xF2, 0xFB, 0x84, 0xF3, 0x63, 0xF5, 0x48, 0x7E, 0x2A, 0xFA, 0x02, 0x60,
+	 0x00, 0x65, 0x20, 0x44, 0x34, 0x80, 0x24, 0x60, 0x74, 0x62, 0x24, 0x60, 0x28, 0x64, 0xA2, 0xDB,
+	 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x0F, 0x60,
+	 0xDA, 0x62, 0x00, 0x60, 0x01, 0x64, 0xA2, 0xDB, 0x1E, 0x60, 0x61, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xD8, 0x62, 0xA2, 0xD1, 0xFF, 0x60, 0xFE, 0x64, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x1A, 0x60, 0x9A, 0x62, 0x00, 0x60, 0x32, 0x64, 0xA2, 0xDB, 0x24, 0x60, 0xAA, 0x62,
+	 0x1A, 0x60, 0x96, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x0F, 0x60,
+	 0xDA, 0x62, 0x00, 0x60, 0x10, 0x64, 0xA2, 0xDB, 0x1E, 0x60, 0x81, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xD8, 0x62, 0xA2, 0xD1, 0xFF, 0x60, 0xEF, 0x64, 0xA0, 0x84,
+	 0xA2, 0xDB, 0xFD, 0x60, 0xFF, 0x65, 0x20, 0x44, 0x24, 0x80, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1,
+	 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x1B, 0x60, 0xB1, 0x78, 0xFF, 0xFF,
+	 0x0F, 0x60, 0xDA, 0x62, 0x00, 0x60, 0x74, 0x64, 0xA2, 0xDB, 0x1E, 0x60, 0xA2, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xD8, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x04, 0x64,
+	 0xA0, 0x80, 0x9C, 0x84, 0x05, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x1E, 0x60, 0xF4, 0x78, 0xFF, 0xFF,
+	 0x00, 0x60, 0x40, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x05, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x1D, 0x60,
+	 0xD3, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x20, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x17, 0x03, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x20, 0x40, 0x50, 0x27, 0xDD, 0x01, 0xAF, 0xF3, 0x6C, 0xF3, 0xFE, 0xA0, 0xF6, 0xA0,
+	 0x0A, 0x06, 0x03, 0x04, 0x00, 0x64, 0x55, 0xFB, 0x40, 0x49, 0x6C, 0xF3, 0xFF, 0xFF, 0xF6, 0xA0,
+	 0xDC, 0x84, 0x01, 0x05, 0xA2, 0xDB, 0x1D, 0x60, 0xD3, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x10, 0x64,
+	 0xA0, 0x80, 0x9C, 0x84, 0xC6, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60,
+	 0xA2, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x1D, 0x60, 0x6D, 0x78,
+	 0xFF, 0xFF, 0x08, 0x60, 0x00, 0x65, 0x20, 0x44, 0x34, 0x80, 0x0F, 0x60, 0xEA, 0x62, 0xA2, 0xD1,
+	 0x00, 0x60, 0x20, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60,
+	 0x8A, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x24, 0x60, 0xAA, 0x62,
+	 0x1A, 0x60, 0x96, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x24, 0x60,
+	 0xAA, 0x62, 0x1A, 0x60, 0xA2, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF,
+	 0x0F, 0x60, 0xD8, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x5A, 0xDB, 0x00, 0x64, 0x6A, 0xFB, 0x0F, 0x60,
+	 0xD0, 0x62, 0xA2, 0xD1, 0x02, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x0F, 0x60,
+	 0xDA, 0x62, 0x00, 0x60, 0x02, 0x64, 0xA2, 0xDB, 0x1B, 0x60, 0x8A, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0xA3, 0xD3, 0x7F, 0xF1, 0x7E, 0xFB, 0xD0, 0x80, 0x00, 0x64, 0x40, 0x03,
+	 0x0F, 0x60, 0xD8, 0x62, 0xA2, 0xD1, 0xBF, 0x60, 0xFF, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0xDE, 0xFE,
+	 0x0B, 0x04, 0x0F, 0x60, 0xDA, 0x62, 0x40, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0x1F, 0x60, 0x2F, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xD8, 0x62, 0xA2, 0xD1, 0xDF, 0x60,
+	 0xFF, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x7E, 0xF1, 0x7F, 0xF9, 0x24, 0x60, 0x9A, 0x62, 0xA2, 0xD9,
+	 0x1E, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x0F, 0x60, 0xDA, 0x62, 0x20, 0x60, 0x00, 0x64,
+	 0xA2, 0xDB, 0x1F, 0x60, 0x5E, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0xBE, 0xFE,
+	 0x0F, 0x60, 0xD8, 0x62, 0xA2, 0xD1, 0xDF, 0x60, 0xFF, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x0F, 0x60,
+	 0xD0, 0x62, 0xA2, 0xD1, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x01, 0x64,
+	 0x6B, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0x60, 0x00, 0x65, 0x20, 0x44, 0x34, 0x80, 0x0F, 0x60,
+	 0xD8, 0x62, 0xA2, 0xD1, 0x7F, 0x60, 0xFF, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x20, 0x40, 0x51, 0x23,
+	 0x0B, 0x00, 0x0F, 0x60, 0xDA, 0x62, 0x80, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0x1F, 0x60, 0x76, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xD8, 0x62, 0xA2, 0xD1, 0x7F, 0x60,
+	 0xFF, 0x61, 0xA1, 0x84, 0x5A, 0xD1, 0x4A, 0xDB, 0xA1, 0x84, 0x5A, 0xDB, 0x40, 0x60, 0x00, 0x65,
+	 0x20, 0x44, 0x34, 0x80, 0x02, 0x64, 0x8C, 0xFB, 0xFF, 0xFF, 0xC1, 0xFE, 0x8C, 0xF3, 0x00, 0x65,
+	 0xD4, 0x80, 0xFF, 0xFF, 0x12, 0x03, 0x0F, 0x60, 0xD8, 0x62, 0xA2, 0xD1, 0x7F, 0x60, 0xFF, 0x64,
+	 0xA0, 0x84, 0xA2, 0xDB, 0x0F, 0x60, 0xDA, 0x62, 0x80, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0x1F, 0x60,
+	 0x99, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x2D, 0x60, 0x7A, 0x64, 0x54, 0xFB,
+	 0x0F, 0x60, 0xD8, 0x62, 0xA2, 0xD1, 0xEF, 0x60, 0xFF, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x1A, 0x60,
+	 0x58, 0x4E, 0xDC, 0x78, 0xFF, 0xFF, 0x0F, 0x4E, 0xEC, 0x60, 0x58, 0x4F, 0xB9, 0x78, 0xFF, 0xFF,
+	 0x0E, 0x4F, 0x0F, 0x60, 0xDA, 0x62, 0x10, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0x1F, 0x60, 0xD3, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x1A, 0x60, 0x58, 0x4E, 0xED, 0x78, 0xFF, 0xFF,
+	 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x96, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x04, 0xFF, 0x0F, 0x60, 0xD8, 0x62, 0xA2, 0xD1, 0xEF, 0x60, 0xEF, 0x64, 0xA0, 0x84, 0xA2, 0xDB,
+	 0x01, 0x64, 0x8C, 0xFB, 0xBF, 0x60, 0xFF, 0x65, 0x20, 0x44, 0x24, 0x80, 0x01, 0x60, 0x14, 0x62,
+	 0xA2, 0xD1, 0x12, 0x60, 0x46, 0x63, 0xC3, 0x85, 0xC6, 0xA3, 0x3A, 0xA3, 0xD7, 0x80, 0xAF, 0xF3,
+	 0x09, 0x04, 0xFE, 0xA0, 0x6C, 0xF3, 0x3A, 0x06, 0xF6, 0xA0, 0x00, 0x64, 0x37, 0x04, 0x55, 0xFB,
+	 0x40, 0x49, 0x34, 0x00, 0x08, 0xA3, 0xBE, 0xD3, 0x83, 0xF1, 0xA3, 0xD3, 0xD0, 0x80, 0x82, 0xF1,
+	 0x05, 0x02, 0xBF, 0xD3, 0xD0, 0x80, 0x81, 0xF1, 0x01, 0x02, 0xD0, 0x80, 0xF8, 0xA3, 0xE5, 0x02,
+	 0xBE, 0xD3, 0x5A, 0xD1, 0x60, 0x47, 0x40, 0x4A, 0x64, 0x47, 0x40, 0x48, 0x20, 0x60, 0x58, 0x4E,
+	 0x45, 0x78, 0xFF, 0xFF, 0x0A, 0x48, 0x20, 0x60, 0x58, 0x4E, 0x55, 0x78, 0xFF, 0xFF, 0x20, 0x60,
+	 0x58, 0x4E, 0x71, 0x78, 0xFF, 0xFF, 0x01, 0x60, 0x2E, 0x65, 0x6C, 0xF3, 0xA5, 0xD3, 0xF6, 0xA0,
+	 0x40, 0xBC, 0x06, 0x04, 0xA5, 0xDB, 0x6A, 0xF1, 0xFF, 0x60, 0xFB, 0x64, 0xA0, 0x84, 0x6A, 0xFB,
+	 0x6C, 0xF3, 0xFF, 0xFF, 0x00, 0xB8, 0xCC, 0x84, 0x01, 0x03, 0xA2, 0xDB, 0xFD, 0x60, 0xFF, 0x65,
+	 0x20, 0x44, 0x24, 0x80, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0xC1, 0xFE, 0x6B, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0xF1, 0x28, 0x44,
+	 0xD0, 0x84, 0x03, 0xA4, 0x03, 0x0E, 0xE8, 0x84, 0xE8, 0x84, 0x04, 0x00, 0xFA, 0xA4, 0xE8, 0x84,
+	 0xE8, 0x87, 0xC0, 0xBF, 0xC0, 0x84, 0xA2, 0xDB, 0x2E, 0x58, 0xFF, 0xFF, 0x56, 0xF1, 0x28, 0x44,
+	 0xD0, 0x84, 0x1F, 0xA4, 0x06, 0x0E, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84,
+	 0x07, 0x00, 0xC2, 0xA4, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x87, 0xF8, 0xBF,
+	 0xC0, 0x84, 0x5C, 0xF1, 0x56, 0xFB, 0xD0, 0x80, 0xFF, 0xFF, 0x01, 0x05, 0x64, 0x44, 0x52, 0xFB,
+	 0x2E, 0x58, 0xFF, 0xFF, 0x52, 0xF1, 0x00, 0x65, 0x20, 0x40, 0x20, 0x2A, 0x06, 0x00, 0x5C, 0xF3,
+	 0xFF, 0xFF, 0xD0, 0x80, 0x64, 0x45, 0x01, 0x06, 0x60, 0x45, 0x2F, 0x67, 0xD4, 0x80, 0xFF, 0xFF,
+	 0x01, 0x06, 0x60, 0x45, 0x55, 0xF1, 0x8B, 0x67, 0xD0, 0x80, 0x60, 0x41, 0x02, 0x24, 0x64, 0x41,
+	 0xD5, 0x84, 0x80, 0x65, 0xC4, 0x87, 0x01, 0x05, 0x00, 0x64, 0xFF, 0xB4, 0x40, 0x49, 0x20, 0x40,
+	 0x20, 0x2A, 0x06, 0x00, 0x2E, 0x43, 0xF3, 0x60, 0x58, 0x4E, 0xA8, 0x78, 0xFF, 0xFF, 0x43, 0x4E,
+	 0x2E, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xD8, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x08, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xD8, 0x62, 0xA2, 0xD1, 0x00, 0x60,
+	 0x10, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xD8, 0x62,
+	 0xA2, 0xD1, 0x00, 0x60, 0x20, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x0F, 0x60, 0xF6, 0x62,
+	 0xA2, 0xD1, 0x00, 0x60, 0x40, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x26, 0x46, 0x27, 0xF2, 0x70, 0x63, 0x60, 0x40, 0x0A, 0x36, 0x06, 0x00, 0x14, 0x36, 0x0A, 0x00,
+	 0x37, 0x36, 0x04, 0x00, 0x6E, 0x36, 0x04, 0x00, 0xD0, 0x63, 0x04, 0x00, 0x33, 0x63, 0x02, 0x00,
+	 0x21, 0x63, 0x00, 0x00, 0x1F, 0x60, 0x5A, 0x61, 0xA1, 0xDD, 0x26, 0x46, 0xBF, 0xF2, 0x01, 0x60,
+	 0x00, 0x65, 0xF4, 0xA1, 0xD5, 0x80, 0x00, 0xF4, 0x02, 0x24, 0x65, 0x41, 0x41, 0x48, 0x1E, 0x65,
+	 0x02, 0x60, 0x00, 0x63, 0xA5, 0xD0, 0xDA, 0x85, 0x80, 0x3A, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65,
+	 0x64, 0x44, 0x00, 0x7F, 0xCD, 0x81, 0xBD, 0xDB, 0x05, 0x03, 0x64, 0x47, 0x00, 0x7F, 0xCD, 0x81,
+	 0xBD, 0xDB, 0xF0, 0x02, 0x02, 0x60, 0x00, 0x63, 0x28, 0x41, 0xBD, 0xD3, 0xBD, 0xD1, 0xFD, 0xA0,
+	 0xFF, 0xFF, 0x07, 0x03, 0x64, 0x44, 0xE0, 0x85, 0xD1, 0x81, 0xFE, 0xA1, 0xC7, 0x83, 0xF5, 0x0D,
+	 0x04, 0x00, 0x1A, 0x60, 0x4C, 0x61, 0xA3, 0xD3, 0xA1, 0xDB, 0x31, 0x40, 0x06, 0x26, 0x58, 0x00,
+	 0x00, 0x64, 0x70, 0xFB, 0x02, 0x60, 0x00, 0x63, 0x28, 0x41, 0xBD, 0xD3, 0xBD, 0xD1, 0xFC, 0xA0,
+	 0xFB, 0xA0, 0x08, 0x03, 0x28, 0x03, 0x64, 0x44, 0xE0, 0x85, 0xD1, 0x81, 0xFE, 0xA1, 0xC7, 0x83,
+	 0xF4, 0x0D, 0x46, 0x00, 0xBD, 0xD3, 0xBD, 0xD3, 0x00, 0xB8, 0x70, 0xFB, 0x6F, 0xFB, 0xBD, 0xD3,
+	 0x3F, 0x02, 0xA3, 0xD3, 0x60, 0x45, 0x60, 0x47, 0xB4, 0x84, 0x60, 0x41, 0x3F, 0xB5, 0xE8, 0x84,
+	 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0x72, 0xFB, 0x65, 0x47, 0xE0, 0x84,
+	 0xE0, 0x84, 0x71, 0xFB, 0x64, 0x44, 0xE0, 0x85, 0xFA, 0xA3, 0xC7, 0x83, 0x1A, 0x60, 0x44, 0x62,
+	 0x61, 0x44, 0xA2, 0xDB, 0xD2, 0x01, 0xBD, 0xD3, 0xA3, 0xD3, 0x00, 0xB8, 0x6E, 0xFB, 0x74, 0xFB,
+	 0x1F, 0x02, 0x87, 0xF1, 0x70, 0xF3, 0x6D, 0xF9, 0x04, 0x65, 0x60, 0x40, 0x00, 0x3A, 0x06, 0x65,
+	 0x31, 0x44, 0xB4, 0x84, 0x40, 0x51, 0x02, 0x2A, 0x0B, 0x00, 0x08, 0xBC, 0x40, 0x51, 0x72, 0xF3,
+	 0x71, 0xF1, 0x00, 0xB8, 0x64, 0x45, 0x01, 0x03, 0x67, 0x45, 0x65, 0x50, 0xCC, 0x84, 0x73, 0xFB,
+	 0x0F, 0x60, 0xEA, 0x62, 0xA2, 0xD1, 0x01, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x0F, 0x60, 0xEC, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x60, 0x40, 0x80, 0x2A, 0x84, 0x00, 0x1F, 0x60,
+	 0x52, 0x61, 0x01, 0x64, 0xA1, 0xDB, 0x22, 0x60, 0x58, 0x4E, 0x3E, 0x78, 0xFF, 0xFF, 0x26, 0x46,
+	 0x00, 0xF4, 0x0D, 0xF2, 0x80, 0xFB, 0x00, 0x64, 0x86, 0xFB, 0x0F, 0x60, 0xEA, 0x62, 0xA2, 0xD1,
+	 0x00, 0x60, 0x80, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x26, 0x46, 0x3F, 0xF2, 0x00, 0xF4,
+	 0x1E, 0x65, 0xF4, 0xA4, 0xD4, 0xA0, 0x60, 0x41, 0x01, 0x06, 0x2C, 0x61, 0x41, 0x48, 0x02, 0x60,
+	 0x00, 0x63, 0xA5, 0xD0, 0xDA, 0x85, 0x80, 0x3A, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0x64, 0x44,
+	 0x00, 0x7F, 0xCD, 0x81, 0xBD, 0xDB, 0x05, 0x03, 0x64, 0x47, 0x00, 0x7F, 0xCD, 0x81, 0xBD, 0xDB,
+	 0xF0, 0x02, 0x02, 0x60, 0x00, 0x63, 0x28, 0x41, 0xBD, 0xD3, 0xBD, 0xD1, 0x01, 0xA8, 0xC9, 0x81,
+	 0x06, 0x03, 0x64, 0x44, 0xD1, 0x81, 0xE0, 0x85, 0x42, 0x06, 0xC7, 0x83, 0xF5, 0x01, 0x43, 0x48,
+	 0x2D, 0x60, 0x2A, 0x63, 0x43, 0x4A, 0x64, 0x41, 0x28, 0x43, 0x00, 0x65, 0x45, 0x4C, 0x65, 0x5C,
+	 0xBD, 0xD3, 0x61, 0x40, 0x00, 0x36, 0x27, 0x00, 0xCD, 0x81, 0x60, 0x40, 0x02, 0x36, 0x60, 0x45,
+	 0x04, 0x36, 0x60, 0x45, 0x82, 0x36, 0x60, 0x45, 0x84, 0x36, 0x60, 0x45, 0x0B, 0x36, 0x60, 0x45,
+	 0x8B, 0x36, 0x60, 0x45, 0x16, 0x36, 0x60, 0x45, 0x96, 0x36, 0x60, 0x45, 0x65, 0x40, 0x00, 0x36,
+	 0xE7, 0x01, 0x64, 0x44, 0xDC, 0x9C, 0x2C, 0x44, 0x00, 0x3A, 0x02, 0x00, 0x45, 0x4C, 0xE0, 0x01,
+	 0x2C, 0x5E, 0x65, 0x5F, 0x00, 0x65, 0x45, 0x4C, 0x43, 0x48, 0x2A, 0x43, 0xBD, 0xDB, 0xFF, 0xFF,
+	 0x43, 0x4A, 0x28, 0x43, 0xD5, 0x01, 0x2D, 0x60, 0x28, 0x64, 0x60, 0xFE, 0xA0, 0xD9, 0xFF, 0xFF,
+	 0x20, 0xFE, 0x64, 0x40, 0x01, 0x3A, 0x39, 0x00, 0x2A, 0x43, 0x65, 0x44, 0xA3, 0xDB, 0x35, 0x00,
+	 0x23, 0x60, 0x34, 0x78, 0xFF, 0xFF, 0xDC, 0xF3, 0xFF, 0xFF, 0x03, 0xA8, 0x02, 0xA8, 0x02, 0x03,
+	 0x41, 0x02, 0xF6, 0x01, 0x0F, 0x60, 0xEA, 0x62, 0xA2, 0xD1, 0xFF, 0x60, 0xFB, 0x64, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x66, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB,
+	 0xFF, 0xFF, 0x04, 0xFF, 0x26, 0x46, 0x1F, 0x60, 0x5A, 0x61, 0xA1, 0xD3, 0x25, 0xF2, 0x60, 0x45,
+	 0x24, 0xF0, 0x00, 0xF4, 0x64, 0x43, 0xC7, 0x83, 0x60, 0x41, 0x02, 0x24, 0x01, 0xA1, 0x0A, 0xF0,
+	 0x09, 0xF2, 0xD1, 0x80, 0xFF, 0xFF, 0x09, 0x07, 0x04, 0x04, 0x63, 0x45, 0xD4, 0x80, 0xFF, 0xFF,
+	 0x04, 0x06, 0x22, 0x60, 0x58, 0x4E, 0x3E, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x26, 0xF0, 0xFF, 0x67,
+	 0x20, 0x88, 0x64, 0x5F, 0x40, 0x4A, 0x20, 0x60, 0x58, 0x4E, 0x45, 0x78, 0xFF, 0xFF, 0x0A, 0x48,
+	 0x20, 0x60, 0x58, 0x4E, 0x55, 0x78, 0xFF, 0xFF, 0x20, 0x60, 0x58, 0x4E, 0x71, 0x78, 0xFF, 0xFF,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xDA, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x60, 0x40, 0x40, 0x22,
+	 0xAF, 0x01, 0x01, 0x60, 0x2E, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0xBF, 0xB4, 0xA2, 0xDB, 0x1F, 0x60,
+	 0x5A, 0x61, 0xA1, 0xD3, 0x26, 0x46, 0x60, 0x45, 0x1E, 0x60, 0xFE, 0x63, 0x00, 0xF4, 0x09, 0xF2,
+	 0xBD, 0xDB, 0xFF, 0xFF, 0x0A, 0xF2, 0xBD, 0xDB, 0x0B, 0xF2, 0xFF, 0xFF, 0xBD, 0xDB, 0x0C, 0xF2,
+	 0xA3, 0xDB, 0xFA, 0xA3, 0x26, 0x46, 0xA3, 0xD3, 0x24, 0xF0, 0x00, 0x61, 0xD0, 0x84, 0xF1, 0x81,
+	 0xD4, 0x84, 0xF1, 0x81, 0xBD, 0xDB, 0xA3, 0xD3, 0x03, 0xB1, 0x03, 0xA9, 0x25, 0xF0, 0x42, 0xFE,
+	 0x05, 0x03, 0xFD, 0xA1, 0xCC, 0x84, 0x01, 0x02, 0xCC, 0x84, 0x00, 0x61, 0xF1, 0x81, 0xD0, 0x84,
+	 0xF1, 0x81, 0xBD, 0xDB, 0xA3, 0xD3, 0x03, 0xB1, 0x03, 0xA9, 0x28, 0xF0, 0x42, 0xFE, 0x01, 0x03,
+	 0xCC, 0x84, 0xF1, 0x81, 0xD0, 0x84, 0xF1, 0x81, 0xBD, 0xDB, 0xA3, 0xD3, 0x03, 0xB1, 0x03, 0xA9,
+	 0x29, 0xF0, 0x01, 0x03, 0xCC, 0x84, 0xD0, 0x84, 0xA3, 0xDB, 0x1F, 0x60, 0x52, 0x61, 0xA1, 0xD3,
+	 0xFF, 0xFF, 0x02, 0xA8, 0xFF, 0xFF, 0x02, 0x02, 0x2E, 0x58, 0xFF, 0xFF, 0xF5, 0xFE, 0x1E, 0x60,
+	 0xFE, 0x64, 0xA0, 0xD1, 0x06, 0xA4, 0xA0, 0xD3, 0x64, 0x45, 0x60, 0x40, 0x80, 0x2B, 0x03, 0x00,
+	 0xFF, 0x60, 0xFF, 0x64, 0x94, 0x85, 0x00, 0x60, 0x96, 0x64, 0xD4, 0x80, 0xFF, 0xFF, 0x0B, 0x06,
+	 0x1F, 0x60, 0x52, 0x61, 0xA1, 0xD3, 0x6A, 0xF3, 0x00, 0xA8, 0x04, 0xB0, 0x04, 0x02, 0x03, 0x03,
+	 0x23, 0x60, 0x10, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x00, 0xF4, 0x09, 0xF2, 0x5A, 0xD2, 0x40, 0x48,
+	 0x40, 0x4A, 0x5A, 0xD2, 0x5A, 0xD2, 0x40, 0x4C, 0x60, 0x41, 0x5A, 0xD0, 0x80, 0xF9, 0x40, 0x63,
+	 0xAD, 0x80, 0xF0, 0xA3, 0x09, 0x02, 0x3C, 0x03, 0x2C, 0x41, 0x2A, 0x44, 0x40, 0x4C, 0x28, 0x44,
+	 0x40, 0x4A, 0x00, 0x64, 0x40, 0x48, 0xF4, 0x01, 0xD1, 0x80, 0x01, 0x02, 0x31, 0x04, 0x10, 0xA3,
+	 0x80, 0x60, 0x00, 0x65, 0xA5, 0x80, 0xCF, 0x83, 0x08, 0x02, 0x28, 0x44, 0x60, 0x88, 0x2A, 0x44,
+	 0x70, 0x8A, 0x2C, 0x44, 0x70, 0x8C, 0xF1, 0x81, 0xF5, 0x01, 0xE7, 0xA3, 0x64, 0x44, 0x00, 0xA8,
+	 0x00, 0x62, 0x02, 0x02, 0x00, 0x61, 0x1C, 0x00, 0xE0, 0x84, 0xDE, 0x82, 0xFD, 0x04, 0x42, 0xFE,
+	 0xF8, 0x84, 0x62, 0x45, 0xC7, 0x83, 0x60, 0x45, 0x02, 0xFE, 0xD5, 0x84, 0x02, 0x05, 0x01, 0x05,
+	 0x61, 0x44, 0xCF, 0x83, 0x60, 0x41, 0x08, 0x03, 0x28, 0x44, 0x60, 0x88, 0x2A, 0x44, 0x70, 0x8A,
+	 0x2C, 0x44, 0x70, 0x8C, 0xF1, 0x81, 0xF1, 0x01, 0xCE, 0x82, 0xE9, 0x81, 0xFD, 0x02, 0xF1, 0x81,
+	 0x09, 0xF2, 0xFF, 0xFF, 0x60, 0x47, 0xE8, 0x84, 0xE8, 0x84, 0x5A, 0xD2, 0x3F, 0xB5, 0xE0, 0x84,
+	 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xB4, 0x84, 0x61, 0x45, 0xD4, 0x84,
+	 0xC0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x93, 0x1F, 0x60, 0x52, 0x61, 0xA1, 0xD3,
+	 0xFF, 0xFF, 0x00, 0xA8, 0xFF, 0xFF, 0x02, 0x03, 0x2E, 0x58, 0xFF, 0xFF, 0x10, 0x65, 0x73, 0x44,
+	 0xD4, 0x93, 0x6A, 0xF3, 0x26, 0x46, 0x04, 0xBC, 0xA2, 0xDB, 0x26, 0xF0, 0xFF, 0x67, 0x20, 0x88,
+	 0x64, 0x5F, 0x40, 0x4A, 0x20, 0x60, 0x58, 0x4E, 0x45, 0x78, 0xFF, 0xFF, 0x0A, 0x48, 0x20, 0x60,
+	 0x58, 0x4E, 0x55, 0x78, 0xFF, 0xFF, 0x20, 0x60, 0x58, 0x4E, 0x71, 0x78, 0xFF, 0xFF, 0x6C, 0xF3,
+	 0xFF, 0xFF, 0x00, 0xB8, 0xCC, 0x84, 0x01, 0x03, 0xA2, 0xDB, 0x0F, 0x60, 0xD8, 0x62, 0xA2, 0xD1,
+	 0x00, 0x60, 0x40, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60,
+	 0xA2, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x0F, 0x60, 0xD8, 0x62,
+	 0xA2, 0xD1, 0xFF, 0x60, 0xDF, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x26, 0x46, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x28, 0xF3, 0xFF, 0xFF, 0x60, 0x47, 0x0F, 0xB4, 0x59, 0x00, 0xFF, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x24, 0x60, 0x9E, 0x65, 0x04, 0x64, 0xA5, 0xDB, 0x12, 0x00, 0x24, 0x60, 0x9E, 0x65, 0x0C, 0x64,
+	 0xA5, 0xDB, 0x0D, 0x00, 0x24, 0x60, 0x9E, 0x65, 0x06, 0x64, 0xA5, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF,
+	 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x24, 0x60, 0x9E, 0x65, 0x08, 0x64, 0xA5, 0xDB, 0x23, 0x60,
+	 0xA1, 0x64, 0xA1, 0xFB, 0xFF, 0xFF, 0x2D, 0xFF, 0x25, 0x60, 0x11, 0x78, 0xFF, 0xFF, 0x29, 0xF3,
+	 0x7F, 0xFB, 0xA4, 0xFB, 0x02, 0x60, 0xEE, 0x64, 0xA3, 0xFB, 0x07, 0x64, 0xA5, 0xFB, 0x23, 0x60,
+	 0xA1, 0x64, 0xA1, 0xFB, 0xFF, 0xFF, 0xDF, 0xFE, 0x00, 0x64, 0x19, 0xFF, 0x25, 0x60, 0x11, 0x78,
+	 0xFF, 0xFF, 0x24, 0x60, 0x0D, 0x63, 0x0C, 0x60, 0x16, 0x64, 0xA0, 0xDD, 0x62, 0xFF, 0x23, 0x60,
+	 0x8E, 0x63, 0xA1, 0xFD, 0xFF, 0xFF, 0x1A, 0xFF, 0x25, 0x60, 0x11, 0x78, 0xFF, 0xFF, 0xA3, 0x60,
+	 0x4B, 0x63, 0x0C, 0x60, 0x16, 0x64, 0xA0, 0xDD, 0x62, 0xFF, 0x29, 0xF5, 0x24, 0x60, 0x7A, 0x63,
+	 0x24, 0x60, 0x4C, 0x64, 0xBD, 0xDB, 0x66, 0x44, 0xBD, 0xDB, 0x02, 0x64, 0xA3, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0xF9, 0xFE, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0xA7, 0x01, 0x00, 0x36, 0xA8, 0x01,
+	 0x01, 0x36, 0xAB, 0x01, 0x02, 0x36, 0xAE, 0x01, 0x03, 0x36, 0xB5, 0x01, 0x04, 0x36, 0xD1, 0x01,
+	 0x05, 0x36, 0xCF, 0x01, 0x06, 0x36, 0xF1, 0x01, 0x07, 0x36, 0xCB, 0x01, 0x08, 0x36, 0xB7, 0x01,
+	 0x09, 0x36, 0x0C, 0x00, 0x0A, 0x36, 0x0D, 0x00, 0x0B, 0x36, 0x0E, 0x00, 0x0C, 0x36, 0x17, 0x00,
+	 0x0D, 0x36, 0x0D, 0x00, 0x0E, 0x36, 0x1E, 0x00, 0x0F, 0x36, 0x32, 0x00, 0x02, 0x60, 0x00, 0x64,
+	 0x08, 0x00, 0x04, 0x60, 0x00, 0x64, 0x05, 0x00, 0x00, 0x60, 0x01, 0x64, 0x02, 0x00, 0x20, 0x60,
+	 0x00, 0x64, 0x32, 0x45, 0xB4, 0x85, 0x45, 0x52, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x24, 0x60,
+	 0xD1, 0x63, 0x0C, 0x60, 0x16, 0x64, 0xA0, 0xDD, 0x62, 0xFF, 0xFF, 0xFF, 0x1A, 0xFF, 0x00, 0x67,
+	 0x23, 0x58, 0xFF, 0xFF, 0x3F, 0x40, 0x02, 0x2B, 0x05, 0x00, 0x90, 0x60, 0x00, 0xE8, 0x24, 0x60,
+	 0x0D, 0x63, 0x04, 0x00, 0x91, 0x60, 0x00, 0xE8, 0x24, 0x60, 0xBB, 0x63, 0x28, 0xE8, 0x0C, 0x60,
+	 0x16, 0x64, 0xA0, 0xDD, 0x62, 0xFF, 0xFF, 0xFF, 0x1A, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x91, 0x60, 0x00, 0xE8, 0x28, 0xE8, 0xD9, 0x60, 0xFE, 0x64, 0x32, 0x45, 0xA4, 0x85, 0x45, 0x52,
+	 0x99, 0xFF, 0xA5, 0x4F, 0xFF, 0xB4, 0x07, 0xFB, 0x98, 0xFF, 0xA3, 0x60, 0x4B, 0x63, 0x0C, 0x60,
+	 0x16, 0x64, 0xA0, 0xDD, 0x62, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x08, 0xE1, 0xA1, 0xFF,
+	 0xFF, 0xFF, 0x43, 0xFF, 0x01, 0x60, 0x00, 0xE1, 0x28, 0xF3, 0x47, 0xFF, 0x60, 0x40, 0x07, 0x37,
+	 0x4B, 0x00, 0x05, 0x3B, 0x04, 0x00, 0xFF, 0x0A, 0x80, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x29, 0xF5,
+	 0x2A, 0xF3, 0x47, 0xFF, 0x3F, 0xF0, 0x01, 0x1B, 0x01, 0x64, 0x60, 0x56, 0xAD, 0xE2, 0xB5, 0xFF,
+	 0x6C, 0x40, 0x40, 0xE1, 0xA1, 0xFF, 0x00, 0xF4, 0x6E, 0x61, 0x12, 0x62, 0x64, 0x43, 0x01, 0xE1,
+	 0x03, 0x64, 0xE2, 0xD0, 0xC9, 0x81, 0x64, 0x4C, 0xCC, 0x84, 0xDA, 0x82, 0xFA, 0x02, 0x01, 0x60,
+	 0x00, 0x6B, 0x9A, 0xFF, 0xCA, 0x82, 0x03, 0x00, 0x00, 0xF4, 0x81, 0xF2, 0xFF, 0xFF, 0x7A, 0xD0,
+	 0xA1, 0xFF, 0x64, 0x4C, 0xFC, 0x1C, 0xF8, 0x1D, 0x00, 0xB9, 0x06, 0x1E, 0x02, 0x02, 0x00, 0xF4,
+	 0xDA, 0x82, 0x5A, 0xD2, 0xA1, 0xFF, 0x60, 0x4D, 0x3F, 0x40, 0x02, 0x2B, 0x08, 0x00, 0x28, 0xF3,
+	 0xA5, 0x60, 0xC4, 0x65, 0x60, 0x40, 0x0E, 0x3B, 0x02, 0x00, 0x80, 0x4C, 0xFE, 0x01, 0xA1, 0xFF,
+	 0x87, 0x4E, 0x87, 0x4C, 0x87, 0x4C, 0x87, 0x4C, 0x87, 0x4C, 0x67, 0x4C, 0xFF, 0xFF, 0xBC, 0xFF,
+	 0x00, 0xE1, 0xD5, 0xFE, 0xA1, 0xFF, 0xFF, 0xFF, 0x00, 0x64, 0x40, 0x46, 0x60, 0x41, 0xB5, 0xFF,
+	 0xB7, 0xFF, 0xB4, 0xFF, 0x29, 0xF5, 0x3F, 0xF0, 0x24, 0xF2, 0x44, 0x43, 0x40, 0x44, 0x00, 0xF4,
+	 0xF3, 0x60, 0xA0, 0x65, 0x10, 0x62, 0x5A, 0xD2, 0xD9, 0x81, 0xD4, 0x80, 0xFF, 0xFF, 0xFB, 0x02,
+	 0x61, 0x45, 0x24, 0x44, 0xD4, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xFD, 0xA5, 0x48, 0x60,
+	 0x00, 0x64, 0xC4, 0x9D, 0x0D, 0x60, 0x00, 0x6B, 0x24, 0x44, 0xC0, 0x83, 0xBB, 0xFF, 0x29, 0xF5,
+	 0x01, 0xE1, 0x00, 0xF4, 0x6C, 0x61, 0x10, 0x62, 0x05, 0x00, 0x00, 0xF4, 0x01, 0xF2, 0xFF, 0xFF,
+	 0x60, 0x41, 0x04, 0x62, 0xA1, 0xFF, 0xFF, 0xFF, 0x01, 0x10, 0x1A, 0x00, 0x26, 0x44, 0x01, 0x26,
+	 0x0C, 0x00, 0x24, 0x44, 0xC8, 0x84, 0x40, 0x44, 0x02, 0x03, 0x6C, 0x45, 0xF3, 0x01, 0x03, 0x15,
+	 0x01, 0x64, 0x05, 0xFA, 0x15, 0x00, 0x6C, 0x45, 0xED, 0x01, 0x23, 0x44, 0xC8, 0x84, 0x40, 0x43,
+	 0x02, 0x03, 0x6C, 0x45, 0xE7, 0x01, 0x00, 0x64, 0x01, 0x15, 0x01, 0x64, 0x6C, 0x45, 0x05, 0xFB,
+	 0xE2, 0xD2, 0xDA, 0x82, 0xC9, 0x81, 0x60, 0x4C, 0xDD, 0x1C, 0xD7, 0x03, 0xBC, 0xFF, 0xDA, 0x01,
+	 0x00, 0xE1, 0xD5, 0xFE, 0xA1, 0xFF, 0xFF, 0xFF, 0x08, 0xE1, 0xA1, 0xFF, 0x67, 0x4C, 0x43, 0xFF,
+	 0xAD, 0x4F, 0x02, 0xBC, 0x00, 0x7F, 0xA0, 0x5D, 0x01, 0xE1, 0x01, 0x60, 0x69, 0x6B, 0xA5, 0x60,
+	 0xC4, 0x64, 0x60, 0x4C, 0xBB, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0x60, 0x4C, 0xA1, 0xFF, 0xFF, 0xFF,
+	 0x60, 0x4C, 0xFC, 0x01, 0x29, 0xF3, 0x2A, 0xF1, 0x07, 0xB5, 0x04, 0xE1, 0x65, 0x41, 0x64, 0x54,
+	 0xCD, 0xE2, 0x95, 0x81, 0xA1, 0x5D, 0xA1, 0xFF, 0xFF, 0xFF, 0xF9, 0x01, 0x61, 0x44, 0xFE, 0xFB,
+	 0xFF, 0xFD, 0xFF, 0x01, 0x7F, 0x67, 0x01, 0x61, 0x23, 0x58, 0xFF, 0xFF, 0xB1, 0xFE, 0x08, 0x05,
+	 0xB0, 0xFE, 0x09, 0x05, 0xB2, 0xFE, 0xB3, 0xFE, 0x78, 0x43, 0x01, 0x61, 0x24, 0x60, 0xDD, 0x78,
+	 0x2D, 0x60, 0x5D, 0x78, 0xFF, 0xFF, 0x28, 0xF3, 0x29, 0xF1, 0x40, 0x44, 0x44, 0x45, 0x2A, 0xF1,
+	 0x2B, 0xF1, 0x44, 0x46, 0x44, 0x47, 0x3F, 0xB4, 0xE0, 0x85, 0x1F, 0x60, 0x88, 0x64, 0x44, 0xD7,
+	 0x58, 0x43, 0xFF, 0xFF, 0x60, 0x45, 0x1C, 0x60, 0xB4, 0x7C, 0xA4, 0xD3, 0x61, 0x43, 0x04, 0xB4,
+	 0x24, 0x44, 0x02, 0x03, 0x13, 0xFF, 0x06, 0x00, 0x3F, 0xB4, 0xB4, 0x84, 0xFF, 0x27, 0x05, 0xFD,
+	 0x04, 0xFB, 0x10, 0x75, 0xA1, 0xFF, 0xFF, 0xFF, 0x86, 0x3E, 0xB4, 0xFE, 0x0B, 0x05, 0xB5, 0xFE,
+	 0x02, 0x24, 0xA1, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xB7, 0xFE, 0x07, 0x05, 0x78, 0x43, 0x01, 0x61,
+	 0x24, 0x60, 0xDD, 0x78, 0x2D, 0x60, 0x98, 0x78, 0xFF, 0xFF, 0x36, 0x44, 0x00, 0x7F, 0xF2, 0xA0,
+	 0x60, 0x45, 0x05, 0x05, 0x20, 0x60, 0x16, 0x64, 0x44, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0x78, 0x43,
+	 0x01, 0x61, 0x24, 0x60, 0xDD, 0x78, 0x78, 0x43, 0x01, 0x61, 0x24, 0x60, 0xDD, 0x78, 0x7F, 0x60,
+	 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80, 0x7F, 0x67, 0x02, 0x61, 0x10, 0x02, 0x10, 0x64, 0x40, 0x40,
+	 0x02, 0x64, 0x40, 0x50, 0x61, 0xFF, 0x3F, 0x40, 0x40, 0x26, 0x04, 0x00, 0x10, 0xE0, 0x46, 0x60,
+	 0x09, 0xE0, 0x00, 0x00, 0x27, 0xF1, 0x00, 0x66, 0x20, 0x78, 0x42, 0xFE, 0x23, 0x58, 0xFF, 0xFF,
+	 0x7F, 0x60, 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80, 0x7F, 0x67, 0x02, 0x61, 0x1A, 0x02, 0x1C, 0x60,
+	 0xB4, 0x63, 0xA3, 0xD3, 0x07, 0x7C, 0x20, 0xB5, 0x0C, 0xB5, 0x04, 0x03, 0x03, 0x02, 0xDC, 0xF9,
+	 0x00, 0x67, 0x0F, 0x00, 0x00, 0x61, 0x41, 0x56, 0xC7, 0xFE, 0xAC, 0x01, 0x36, 0x47, 0xFF, 0x23,
+	 0x04, 0x00, 0x00, 0x7F, 0x60, 0x41, 0x7F, 0x67, 0x04, 0x00, 0x20, 0x44, 0x80, 0xBC, 0x40, 0x40,
+	 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x7F, 0x60, 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80, 0x7F, 0x67,
+	 0x02, 0x61, 0x31, 0x02, 0x1C, 0x60, 0xB4, 0x63, 0xA3, 0xD3, 0x01, 0x7C, 0x20, 0xB5, 0x0C, 0xB5,
+	 0x03, 0x03, 0x02, 0x02, 0xDC, 0xF9, 0xFF, 0xFF, 0x02, 0x61, 0x41, 0x56, 0xC7, 0xFE, 0x25, 0x60,
+	 0x11, 0x78, 0xFF, 0xFF, 0x9F, 0xF1, 0x20, 0x44, 0x64, 0x40, 0xFF, 0x26, 0x1B, 0x00, 0x7F, 0xB4,
+	 0x40, 0x40, 0x5C, 0x5E, 0x82, 0xFF, 0x26, 0x44, 0xFD, 0xB4, 0x40, 0x46, 0x5C, 0x41, 0x87, 0xFF,
+	 0x62, 0xFF, 0x00, 0x63, 0x24, 0x60, 0x5E, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46,
+	 0x04, 0x03, 0x09, 0xF2, 0x0F, 0xFC, 0xAC, 0x86, 0xFB, 0x01, 0x24, 0x60, 0x9E, 0x62, 0x06, 0x64,
+	 0xA2, 0xDB, 0x2D, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x00, 0x67, 0x20, 0x40, 0x80, 0x2A,
+	 0x02, 0x00, 0x7F, 0x67, 0x06, 0x61, 0x60, 0x45, 0x1C, 0x60, 0xB4, 0x7C, 0xA4, 0xD3, 0x61, 0x43,
+	 0x04, 0xB4, 0x24, 0x44, 0x02, 0x03, 0x13, 0xFF, 0x55, 0x01, 0x3F, 0xB4, 0xB4, 0x84, 0xFF, 0x27,
+	 0x05, 0xFD, 0x04, 0xFB, 0x20, 0x40, 0x80, 0x2A, 0x02, 0x00, 0x10, 0x75, 0x07, 0x00, 0x2D, 0x60,
+	 0x9C, 0x62, 0x01, 0x64, 0xA2, 0xDB, 0xFF, 0xFF, 0x08, 0x60, 0x10, 0x75, 0x43, 0x01, 0x25, 0x46,
+	 0x01, 0xF2, 0x08, 0xF0, 0x60, 0x47, 0x03, 0xB4, 0x03, 0xAC, 0x7F, 0x67, 0x03, 0x61, 0x08, 0x02,
+	 0x24, 0x60, 0x7A, 0x64, 0x40, 0x4B, 0x2C, 0x60, 0x58, 0x4D, 0xD8, 0x78, 0xFF, 0xFF, 0x00, 0x67,
+	 0x23, 0x58, 0xFF, 0xFF, 0x24, 0x40, 0x01, 0x2B, 0x49, 0x00, 0x25, 0x44, 0x1F, 0xB4, 0xE0, 0x85,
+	 0x25, 0x60, 0xEB, 0x64, 0xC4, 0x98, 0xFF, 0xFF, 0xC0, 0xFE, 0x3D, 0x00, 0xC1, 0xFE, 0x3B, 0x00,
+	 0xC2, 0xFE, 0x39, 0x00, 0xC3, 0xFE, 0x37, 0x00, 0xC4, 0xFE, 0x35, 0x00, 0xC5, 0xFE, 0x33, 0x00,
+	 0xC6, 0xFE, 0x31, 0x00, 0xC7, 0xFE, 0x2F, 0x00, 0xC8, 0xFE, 0x2D, 0x00, 0xC9, 0xFE, 0x2B, 0x00,
+	 0xCA, 0xFE, 0x29, 0x00, 0xCB, 0xFE, 0x27, 0x00, 0xCC, 0xFE, 0x25, 0x00, 0xCD, 0xFE, 0x23, 0x00,
+	 0xCE, 0xFE, 0x21, 0x00, 0xCF, 0xFE, 0x1F, 0x00, 0xD0, 0xFE, 0x1D, 0x00, 0xD1, 0xFE, 0x1B, 0x00,
+	 0xD2, 0xFE, 0x19, 0x00, 0xD3, 0xFE, 0x17, 0x00, 0xD4, 0xFE, 0x15, 0x00, 0xD5, 0xFE, 0x13, 0x00,
+	 0xD6, 0xFE, 0x11, 0x00, 0xD7, 0xFE, 0x0F, 0x00, 0xD8, 0xFE, 0x0D, 0x00, 0xD9, 0xFE, 0x0B, 0x00,
+	 0xDA, 0xFE, 0x09, 0x00, 0xDB, 0xFE, 0x07, 0x00, 0xDC, 0xFE, 0x05, 0x00, 0xDD, 0xFE, 0x03, 0x00,
+	 0xDE, 0xFE, 0x01, 0x00, 0xDF, 0xFE, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x00, 0x64, 0x9F, 0xFE,
+	 0xF0, 0x84, 0xFF, 0xFF, 0x9E, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x9D, 0xFE, 0xF0, 0x84, 0xFF, 0xFF,
+	 0x9C, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x9B, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x9A, 0xFE, 0xF0, 0x84,
+	 0xFF, 0xFF, 0x99, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x98, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x97, 0xFE,
+	 0xF0, 0x84, 0xFF, 0xFF, 0x96, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x95, 0xFE, 0xF0, 0x84, 0xFF, 0xFF,
+	 0x94, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x93, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x92, 0xFE, 0xF0, 0x84,
+	 0xFF, 0xFF, 0x91, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x90, 0xFE, 0xF0, 0x84, 0x06, 0xFB, 0x8F, 0xFE,
+	 0xF0, 0x84, 0xFF, 0xFF, 0x8E, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x8D, 0xFE, 0xF0, 0x84, 0xFF, 0xFF,
+	 0x8C, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x8B, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x8A, 0xFE, 0xF0, 0x84,
+	 0xFF, 0xFF, 0x89, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x88, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x87, 0xFE,
+	 0xF0, 0x84, 0xFF, 0xFF, 0x86, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x85, 0xFE, 0xF0, 0x84, 0xFF, 0xFF,
+	 0x84, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x83, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x82, 0xFE, 0xF0, 0x84,
+	 0xFF, 0xFF, 0x81, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x80, 0xFE, 0xF0, 0x84, 0x05, 0xFB, 0x00, 0x67,
+	 0x23, 0x58, 0xFF, 0xFF, 0x5C, 0x5C, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x24, 0x40, 0x01, 0x27,
+	 0x55, 0x00, 0x05, 0x60, 0x00, 0x63, 0x05, 0xFD, 0x30, 0x44, 0xBD, 0xDB, 0x31, 0x44, 0xBD, 0xDB,
+	 0x32, 0x44, 0xBD, 0xDB, 0x33, 0x44, 0xBD, 0xDB, 0x34, 0x44, 0xBD, 0xDB, 0x35, 0x44, 0xBD, 0xDB,
+	 0x36, 0x44, 0xBD, 0xDB, 0x37, 0x44, 0xBD, 0xDB, 0x38, 0x44, 0xBD, 0xDB, 0x39, 0x44, 0xBD, 0xDB,
+	 0x3A, 0x44, 0xBD, 0xDB, 0x3B, 0x44, 0xBD, 0xDB, 0x3C, 0x44, 0xBD, 0xDB, 0x3D, 0x44, 0xBD, 0xDB,
+	 0x3E, 0x44, 0xBD, 0xDB, 0x3F, 0x44, 0xBD, 0xDB, 0x02, 0x61, 0x61, 0x44, 0x02, 0x36, 0x82, 0xFF,
+	 0x03, 0x36, 0x83, 0xFF, 0x04, 0x36, 0x84, 0xFF, 0x05, 0x36, 0x85, 0xFF, 0x06, 0x36, 0x86, 0xFF,
+	 0x07, 0x36, 0x87, 0xFF, 0x20, 0x44, 0xBD, 0xDB, 0x21, 0x44, 0xBD, 0xDB, 0x22, 0x44, 0xBD, 0xDB,
+	 0x23, 0x44, 0xBD, 0xDB, 0x24, 0x44, 0xBD, 0xDB, 0x25, 0x44, 0xBD, 0xDB, 0x26, 0x44, 0xBD, 0xDB,
+	 0x27, 0x44, 0xBD, 0xDB, 0x28, 0x44, 0xBD, 0xDB, 0x29, 0x44, 0xBD, 0xDB, 0x2A, 0x44, 0xBD, 0xDB,
+	 0x2B, 0x44, 0xBD, 0xDB, 0x2C, 0x44, 0xBD, 0xDB, 0x2D, 0x44, 0xBD, 0xDB, 0x2E, 0x44, 0xBD, 0xDB,
+	 0x2F, 0x44, 0xBD, 0xDB, 0xDD, 0x81, 0x08, 0x3A, 0xD0, 0x01, 0x54, 0x00, 0x27, 0x40, 0x10, 0x26,
+	 0x30, 0x00, 0x26, 0x44, 0x01, 0x36, 0x2D, 0x00, 0x02, 0x36, 0x82, 0xFF, 0x03, 0x36, 0x83, 0xFF,
+	 0x04, 0x36, 0x84, 0xFF, 0x05, 0x36, 0x85, 0xFF, 0x06, 0x36, 0x86, 0xFF, 0x25, 0x44, 0x00, 0x36,
+	 0x44, 0x40, 0x01, 0x36, 0x44, 0x41, 0x02, 0x36, 0x44, 0x42, 0x03, 0x36, 0x44, 0x43, 0x04, 0x36,
+	 0x44, 0x44, 0x05, 0x36, 0x44, 0x45, 0x06, 0x36, 0x44, 0x46, 0x07, 0x36, 0x44, 0x47, 0x08, 0x36,
+	 0x44, 0x48, 0x09, 0x36, 0x44, 0x49, 0x0A, 0x36, 0x44, 0x4A, 0x0B, 0x36, 0x44, 0x4B, 0x0C, 0x36,
+	 0x44, 0x4C, 0x0D, 0x36, 0x44, 0x4D, 0x0E, 0x36, 0x44, 0x4E, 0x0F, 0x36, 0x44, 0x4F, 0x87, 0xFF,
+	 0x21, 0x00, 0x25, 0x44, 0x10, 0x36, 0x44, 0x50, 0x11, 0x36, 0x44, 0x51, 0x12, 0x36, 0x44, 0x52,
+	 0x13, 0x36, 0x44, 0x53, 0x14, 0x36, 0x44, 0x54, 0x15, 0x36, 0x44, 0x55, 0x16, 0x36, 0x44, 0x56,
+	 0x17, 0x36, 0x44, 0x57, 0x18, 0x36, 0x44, 0x58, 0x19, 0x36, 0x44, 0x59, 0x1A, 0x36, 0x44, 0x5A,
+	 0x1B, 0x36, 0x44, 0x5B, 0x1C, 0x36, 0x44, 0x5C, 0x1D, 0x36, 0x44, 0x5D, 0x1E, 0x36, 0x44, 0x5E,
+	 0x1F, 0x36, 0x44, 0x5F, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x25, 0x46, 0xAE, 0x60, 0x58, 0x4F,
+	 0x6F, 0x78, 0xFF, 0xFF, 0x03, 0x61, 0x7F, 0x67, 0x0B, 0x02, 0x00, 0xF0, 0x24, 0x60, 0x7A, 0x62,
+	 0x04, 0x64, 0xA2, 0xDB, 0x5A, 0xD9, 0x0A, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x00, 0x67,
+	 0x23, 0x58, 0xFF, 0xFF, 0x40, 0x60, 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80, 0x7F, 0x67, 0x02, 0x61,
+	 0x11, 0x02, 0x24, 0x60, 0x9E, 0x62, 0x1A, 0x64, 0xA2, 0xDB, 0x00, 0x60, 0x50, 0x63, 0x5A, 0xDD,
+	 0x27, 0x60, 0x6E, 0x64, 0xA1, 0xFB, 0x2D, 0xFF, 0x25, 0x60, 0x11, 0x78, 0xFF, 0xFF, 0x2A, 0xF3,
+	 0x05, 0xFB, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x40, 0x60, 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80,
+	 0x7F, 0x67, 0x02, 0x61, 0x0F, 0x02, 0x24, 0x60, 0x9E, 0x62, 0x1C, 0x64, 0xA2, 0xDB, 0x00, 0x60,
+	 0x50, 0x63, 0x5A, 0xDD, 0x27, 0x60, 0x88, 0x64, 0xA1, 0xFB, 0x2D, 0xFF, 0x25, 0x60, 0x11, 0x78,
+	 0xFF, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x7F, 0x60, 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80,
+	 0x02, 0x61, 0x3E, 0x02, 0x25, 0x45, 0x20, 0x44, 0x80, 0x2A, 0x3A, 0x00, 0xF1, 0x60, 0x00, 0x64,
+	 0xD4, 0x80, 0xFF, 0xFF, 0x0B, 0x03, 0xF1, 0x60, 0x01, 0x64, 0xD4, 0x80, 0xFF, 0xFF, 0x06, 0x03,
+	 0xF1, 0x60, 0x02, 0x64, 0xD4, 0x80, 0xFF, 0xFF, 0x30, 0x03, 0x29, 0x00, 0x2D, 0x60, 0x0E, 0x62,
+	 0xA2, 0xD1, 0xBA, 0xF3, 0x1F, 0x60, 0x82, 0x61, 0xA0, 0x84, 0xA1, 0xDB, 0x25, 0x45, 0x23, 0x60,
+	 0xE4, 0x63, 0x02, 0x61, 0xBD, 0xD3, 0xBD, 0xD1, 0xD4, 0x80, 0xBD, 0xD3, 0xBD, 0xD5, 0xCD, 0x81,
+	 0x02, 0x03, 0x15, 0x03, 0xF7, 0x01, 0xA2, 0xFF, 0xA6, 0xD3, 0x40, 0x4C, 0x00, 0xA8, 0x67, 0x43,
+	 0x0C, 0x02, 0xA2, 0xDD, 0x42, 0x48, 0x64, 0x41, 0xAE, 0x60, 0x58, 0x4D, 0xC4, 0x78, 0xFF, 0xFF,
+	 0x66, 0x44, 0x28, 0xDB, 0x02, 0x03, 0x2C, 0x58, 0xA3, 0xFF, 0x0C, 0x61, 0x03, 0x00, 0x04, 0x61,
+	 0x7F, 0x67, 0x01, 0x00, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x2D, 0x60, 0x0E, 0x62, 0xA2, 0xD1,
+	 0xBA, 0xF3, 0x1F, 0x60, 0x82, 0x61, 0xA0, 0x84, 0xA1, 0xDB, 0x1F, 0x60, 0x86, 0x61, 0x01, 0x64,
+	 0xA1, 0xDB, 0xFF, 0xFF, 0xC4, 0xFE, 0xEE, 0x01, 0xC6, 0xFE, 0xEC, 0x01, 0x7E, 0x60, 0xC0, 0x64,
+	 0x24, 0x45, 0xA4, 0x80, 0x02, 0x61, 0x3F, 0x02, 0x25, 0x45, 0xF8, 0x2B, 0x3B, 0x00, 0x2E, 0xF5,
+	 0x67, 0x44, 0xD4, 0x80, 0x20, 0x60, 0x24, 0x63, 0x39, 0x03, 0x60, 0x61, 0x24, 0x44, 0x01, 0x27,
+	 0x29, 0x00, 0xA3, 0xFC, 0xA4, 0xF8, 0xBD, 0xD3, 0xA3, 0xD1, 0xD4, 0x80, 0xCD, 0x81, 0x08, 0x24,
+	 0x64, 0x58, 0x08, 0xA3, 0xF8, 0x02, 0x08, 0x60, 0x00, 0x63, 0xBD, 0xD3, 0xA3, 0xD1, 0xFE, 0xA0,
+	 0xFA, 0x60, 0x00, 0x64, 0xD0, 0x80, 0x14, 0x02, 0x13, 0x02, 0x04, 0xA3, 0xBE, 0xD3, 0xBD, 0xD1,
+	 0x0F, 0x18, 0xD4, 0x80, 0x0D, 0x18, 0x03, 0x03, 0xC3, 0x83, 0xC3, 0x83, 0xF7, 0x01, 0x64, 0x41,
+	 0xDD, 0x81, 0xE1, 0x81, 0xCB, 0x83, 0x46, 0x65, 0x2F, 0x60, 0x58, 0x4F, 0x01, 0x78, 0xFF, 0xFF,
+	 0x00, 0x67, 0x0A, 0x00, 0xBD, 0xD3, 0xBE, 0xD1, 0xD4, 0x80, 0xCD, 0x81, 0x08, 0x24, 0x64, 0x58,
+	 0x08, 0xA3, 0xF8, 0x02, 0x04, 0x61, 0x7F, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x0F, 0x64, 0x23, 0xFA,
+	 0x67, 0x44, 0x24, 0xFA, 0x62, 0x41, 0x3C, 0x60, 0x00, 0x65, 0x1A, 0x63, 0x68, 0x60, 0x28, 0x64,
+	 0x65, 0x46, 0x58, 0xD0, 0x2E, 0xF5, 0x59, 0xD8, 0xFB, 0x1F, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0xCB, 0x83, 0xBF, 0xD1, 0x4A, 0x65, 0x64, 0x43, 0xBD, 0xD3, 0xFF, 0xFF, 0x60, 0x41, 0x01, 0x26,
+	 0xDC, 0x81, 0xE9, 0x84, 0xDC, 0x84, 0x23, 0xFA, 0x09, 0x00, 0x4B, 0xD3, 0xFF, 0xFF, 0x60, 0x41,
+	 0xE8, 0x84, 0xDC, 0x84, 0x23, 0xFA, 0xBF, 0xD1, 0x4A, 0x65, 0x64, 0x43, 0x2F, 0x60, 0x58, 0x4F,
+	 0x01, 0x78, 0xFF, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x25, 0xF2, 0xFF, 0xFF, 0xE0, 0xA0,
+	 0x20, 0x64, 0x01, 0x06, 0x25, 0xFA, 0x23, 0xF2, 0xDF, 0xD1, 0xCC, 0x84, 0xE0, 0x85, 0x0B, 0x06,
+	 0xBF, 0xD1, 0x64, 0x41, 0xD5, 0x80, 0x64, 0x43, 0x01, 0x06, 0x65, 0x41, 0x4A, 0x65, 0x29, 0x60,
+	 0x58, 0x4F, 0x83, 0x78, 0xFF, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0xDC, 0xF3, 0x02, 0x63,
+	 0x23, 0xFC, 0x07, 0xB4, 0x25, 0xFA, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x4B, 0xD3, 0xBF, 0xD3,
+	 0x60, 0x41, 0xC9, 0x83, 0xE9, 0x81, 0xDD, 0x81, 0xA3, 0xFA, 0xE0, 0x81, 0x3C, 0x60, 0x00, 0x67,
+	 0x02, 0x24, 0x02, 0xA4, 0x60, 0x47, 0x40, 0x4B, 0xC9, 0x81, 0x4A, 0x65, 0xAB, 0x46, 0x59, 0xD0,
+	 0xAB, 0x46, 0xA5, 0xD8, 0xDA, 0x85, 0x80, 0x3A, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0xF6, 0x1F,
+	 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0xFC, 0xA3, 0xA3, 0xD1, 0x4C, 0x65, 0xA4, 0xD3, 0xDA, 0x83,
+	 0x60, 0x47, 0x25, 0xFA, 0x00, 0x7E, 0x60, 0x47, 0x01, 0x26, 0xDC, 0x84, 0x60, 0x41, 0xE8, 0x84,
+	 0xD8, 0x84, 0x23, 0xFA, 0xAB, 0x01, 0xFC, 0xA3, 0xA3, 0xD1, 0x4C, 0x65, 0xA4, 0xD3, 0xDA, 0x83,
+	 0x00, 0x7F, 0x25, 0xFA, 0x60, 0x41, 0x01, 0x26, 0xDD, 0x81, 0xE9, 0x84, 0xD8, 0x84, 0x23, 0xFA,
+	 0x9D, 0x01, 0x28, 0x60, 0xE2, 0x63, 0xBF, 0xD3, 0xFF, 0xFF, 0x60, 0x41, 0xE8, 0x84, 0xDC, 0x84,
+	 0x23, 0xFA, 0x4A, 0x65, 0x2F, 0x60, 0x58, 0x4F, 0x01, 0x78, 0xFF, 0xFF, 0x00, 0x67, 0x23, 0x58,
+	 0xFF, 0xFF, 0x28, 0x60, 0xE2, 0x63, 0x23, 0xF2, 0xC0, 0x65, 0xCC, 0x84, 0xE0, 0x81, 0x0A, 0x04,
+	 0xBF, 0xDB, 0xD5, 0x80, 0x07, 0x03, 0x01, 0x06, 0x65, 0x41, 0x61, 0x44, 0xBF, 0xDB, 0x4A, 0x65,
+	 0x58, 0x4F, 0xAA, 0x00, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x03, 0x4E, 0x28, 0x60, 0x58, 0x43,
+	 0x5C, 0x78, 0xFF, 0xFF, 0x29, 0x60, 0xC6, 0x61, 0x29, 0x60, 0xA4, 0x62, 0xA2, 0xD3, 0xA1, 0xDB,
+	 0xCC, 0x84, 0xA8, 0x83, 0x05, 0x04, 0x29, 0x60, 0xA4, 0x64, 0x58, 0xD1, 0x59, 0xD9, 0xFD, 0x1F,
+	 0x0E, 0x43, 0x81, 0x01, 0x23, 0xF2, 0x1C, 0x60, 0x8E, 0x65, 0x60, 0x41, 0x1C, 0x60, 0x2A, 0x63,
+	 0xA3, 0xDB, 0xFF, 0xA1, 0x48, 0x64, 0x58, 0xD0, 0x7E, 0xA8, 0x5B, 0xD9, 0x02, 0x02, 0x00, 0xF4,
+	 0x02, 0x64, 0xFF, 0xA1, 0xD7, 0x80, 0x02, 0x03, 0x01, 0x03, 0xF5, 0x01, 0x2E, 0xF5, 0x00, 0x60,
+	 0x2F, 0x65, 0x25, 0xF2, 0x00, 0x63, 0xCC, 0x84, 0x03, 0xA3, 0xFD, 0x05, 0x4A, 0x64, 0xD7, 0x80,
+	 0x1B, 0x60, 0xC6, 0x61, 0x2F, 0x05, 0xA1, 0xDD, 0xE3, 0x83, 0xFE, 0xA3, 0x58, 0xD0, 0x7E, 0xA8,
+	 0x59, 0xD9, 0x02, 0x02, 0x00, 0xF4, 0x02, 0x64, 0xF9, 0x1F, 0x00, 0x63, 0x59, 0xDD, 0x2E, 0xF5,
+	 0x1B, 0x60, 0xC6, 0x64, 0x25, 0xF0, 0xA0, 0xD3, 0xD3, 0x80, 0x01, 0xB0, 0x04, 0x03, 0x01, 0xA4,
+	 0x03, 0x03, 0xA2, 0xDB, 0x01, 0x00, 0xA2, 0xDD, 0x1B, 0x60, 0xCE, 0x63, 0x10, 0x60, 0x5A, 0x65,
+	 0xBD, 0xD3, 0xBD, 0xD1, 0xE0, 0x84, 0xC4, 0x82, 0x10, 0x60, 0x7A, 0x65, 0x07, 0x64, 0x64, 0x41,
+	 0x5A, 0xDB, 0xD6, 0x80, 0xCD, 0x81, 0x06, 0x03, 0xFB, 0x02, 0x25, 0xF2, 0x02, 0xA3, 0xCC, 0x84,
+	 0xA2, 0xDA, 0xEC, 0x02, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x1C, 0x60, 0x2A, 0x61, 0xA1, 0xD3,
+	 0x23, 0xFA, 0xE0, 0x83, 0x4A, 0x65, 0x04, 0x02, 0x02, 0x63, 0x23, 0xFC, 0xA5, 0xFC, 0x09, 0x00,
+	 0xDB, 0x83, 0x59, 0xD1, 0xA5, 0xD8, 0xDA, 0x85, 0x80, 0x3A, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65,
+	 0xF8, 0x1F, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x1B, 0x60, 0xC6, 0x62, 0xA2, 0xD3, 0x00, 0x61,
+	 0x02, 0xA4, 0xFE, 0xA0, 0x23, 0xFA, 0x1B, 0x03, 0xFA, 0xA4, 0xFD, 0xA4, 0x01, 0xA1, 0xFD, 0x07,
+	 0x61, 0x43, 0x23, 0xF2, 0x25, 0xFC, 0xE0, 0x83, 0x02, 0xA3, 0x1B, 0x60, 0xC6, 0x61, 0x00, 0x60,
+	 0x4A, 0x64, 0x59, 0xD1, 0x58, 0xD8, 0x7E, 0x3A, 0x02, 0x00, 0x00, 0xF4, 0x02, 0x64, 0xF9, 0x1F,
+	 0x25, 0xF2, 0x23, 0xF2, 0x01, 0xB0, 0xCC, 0x84, 0x04, 0x02, 0x23, 0xFA, 0x02, 0x00, 0x00, 0x64,
+	 0x25, 0xFA, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x41, 0x4B, 0x65, 0x42, 0x80, 0x64, 0xD4, 0x85,
+	 0x2B, 0x41, 0x00, 0xA1, 0x55, 0x8B, 0x0D, 0x03, 0x02, 0x04, 0x65, 0x41, 0x02, 0x00, 0x00, 0x64,
+	 0x40, 0x4B, 0xCA, 0x84, 0x58, 0xD0, 0xC9, 0x81, 0xBD, 0xD9, 0xFC, 0x02, 0x00, 0xF4, 0x04, 0x65,
+	 0xEC, 0x01, 0x2F, 0x58, 0xFF, 0xFF, 0xFC, 0xA3, 0xA3, 0xD3, 0x02, 0x7C, 0xA0, 0xD3, 0x23, 0xF8,
+	 0xDC, 0x84, 0x25, 0xFA, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x02, 0x64, 0x23, 0xFA, 0x01, 0x64,
+	 0x9D, 0xFE, 0x02, 0x28, 0x02, 0x64, 0x25, 0xFA, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x2D, 0x60,
+	 0x1A, 0x62, 0xA2, 0xD3, 0x02, 0x7C, 0x23, 0xF8, 0x01, 0xB4, 0x25, 0xFA, 0x00, 0x67, 0x23, 0x58,
+	 0xFF, 0xFF, 0xFC, 0xA3, 0xA3, 0xD1, 0x02, 0x64, 0x23, 0xFA, 0xA4, 0xD3, 0x00, 0x63, 0x60, 0x40,
+	 0x0A, 0x37, 0x01, 0x63, 0x14, 0x37, 0x02, 0x63, 0x37, 0x37, 0x06, 0x63, 0x6E, 0x37, 0x0B, 0x63,
+	 0x25, 0xFC, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x02, 0x64, 0x23, 0xFA, 0x88, 0xFF, 0x75, 0x44,
+	 0x8D, 0xFF, 0xE8, 0x87, 0xE8, 0x84, 0xE8, 0x84, 0x03, 0xB4, 0x25, 0xFA, 0x00, 0x67, 0x23, 0x58,
+	 0xFF, 0xFF, 0x04, 0x64, 0x23, 0xFA, 0x86, 0xFF, 0x29, 0x44, 0x87, 0xFF, 0x25, 0xFA, 0x55, 0xF3,
+	 0x52, 0xF1, 0x80, 0x65, 0xC4, 0x87, 0x00, 0x7F, 0x26, 0xFA, 0x64, 0x44, 0xC4, 0x87, 0x00, 0x7F,
+	 0x27, 0xFA, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x05, 0x64, 0x23, 0xFA, 0x52, 0x63, 0xB7, 0xF3,
+	 0x4B, 0xDA, 0xB6, 0xF3, 0x4B, 0xDA, 0xB5, 0xF3, 0x4B, 0xDA, 0x60, 0x41, 0x88, 0xFF, 0x72, 0x5C,
+	 0x89, 0xFF, 0x4A, 0xD8, 0xA2, 0x48, 0x20, 0x23, 0x0E, 0x00, 0x64, 0x40, 0x80, 0x27, 0x15, 0x00,
+	 0xDC, 0x84, 0xBD, 0xDA, 0xBD, 0xD2, 0x11, 0x04, 0xDC, 0x84, 0xA2, 0xDA, 0xA3, 0xD2, 0x0D, 0x04,
+	 0xDC, 0x84, 0xA3, 0xDA, 0x0A, 0x00, 0x52, 0x63, 0xB7, 0xF3, 0x4B, 0xDA, 0xB6, 0xF3, 0x4B, 0xDA,
+	 0xB5, 0xF3, 0x4B, 0xDA, 0x54, 0x90, 0x4C, 0x63, 0xE0, 0x02, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x25, 0xF0, 0x2D, 0x60, 0x16, 0x65, 0x23, 0xF2, 0xA5, 0xD9, 0x02, 0xA8, 0x64, 0x44, 0x07, 0x02,
+	 0x00, 0xBC, 0xF2, 0xA4, 0x04, 0x03, 0x03, 0x07, 0x28, 0x60, 0x44, 0x62, 0xA2, 0xD9, 0x00, 0x67,
+	 0x23, 0x58, 0xFF, 0xFF, 0x20, 0x63, 0x28, 0x60, 0xA4, 0x61, 0x48, 0x64, 0x58, 0xD0, 0x59, 0xD9,
+	 0xFD, 0x1F, 0x25, 0xF0, 0x20, 0x64, 0xD0, 0x81, 0xFF, 0xFF, 0x02, 0x07, 0x25, 0xFA, 0x0F, 0x00,
+	 0x28, 0x60, 0xA8, 0x63, 0xC3, 0x83, 0x01, 0x2A, 0x06, 0x00, 0xCF, 0x83, 0xA3, 0xD3, 0xCD, 0x81,
+	 0x00, 0x7F, 0xBD, 0xDB, 0x04, 0x03, 0x00, 0x64, 0xC9, 0x81, 0xBD, 0xDB, 0xFD, 0x02, 0x00, 0x67,
+	 0x23, 0x58, 0xFF, 0xFF, 0x23, 0xF2, 0x25, 0xF0, 0x02, 0xA8, 0x01, 0x60, 0xA6, 0x62, 0x09, 0x02,
+	 0xA2, 0xD9, 0x64, 0x41, 0x32, 0x44, 0x02, 0xB5, 0x00, 0xB9, 0xD4, 0x84, 0x08, 0x28, 0x02, 0xBC,
+	 0x40, 0x52, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x23, 0xF2, 0x25, 0xF0, 0x02, 0xA8, 0x01, 0x60,
+	 0xB2, 0x62, 0x0C, 0x02, 0xA2, 0xD9, 0x64, 0x41, 0x32, 0x44, 0x40, 0xB5, 0x00, 0xB9, 0xD4, 0x84,
+	 0x08, 0x24, 0x03, 0x00, 0x40, 0xBC, 0x02, 0xB5, 0xD4, 0x84, 0x40, 0x52, 0x00, 0x67, 0x23, 0x58,
+	 0xFF, 0xFF, 0x23, 0xF2, 0x25, 0xF0, 0x01, 0x60, 0xB0, 0x63, 0xA3, 0xD9, 0xA9, 0xF1, 0x20, 0x61,
+	 0x41, 0x4B, 0x64, 0x43, 0xD8, 0xF3, 0x63, 0x45, 0x66, 0x41, 0x65, 0x46, 0x8C, 0xFA, 0x60, 0x40,
+	 0x01, 0x36, 0x06, 0x00, 0x02, 0x36, 0x04, 0x00, 0x04, 0x36, 0x02, 0x00, 0x05, 0x3A, 0x02, 0x00,
+	 0x00, 0x64, 0x01, 0x00, 0x01, 0x64, 0x6F, 0xFA, 0x79, 0xF3, 0x7A, 0xF1, 0xFF, 0xFF, 0xA0, 0x84,
+	 0x65, 0x43, 0x02, 0x02, 0x79, 0xF3, 0xFF, 0xFF, 0x60, 0x41, 0x0F, 0x60, 0xAE, 0x65, 0xD8, 0xF3,
+	 0xFF, 0xFF, 0xE0, 0x84, 0x44, 0xD3, 0x61, 0x45, 0xA4, 0x80, 0xFF, 0xFF, 0x04, 0x02, 0xE8, 0x84,
+	 0xA4, 0x80, 0xFF, 0xFF, 0xFC, 0x03, 0xA4, 0x84, 0x7B, 0xFB, 0x6F, 0xF0, 0x60, 0x47, 0x90, 0x84,
+	 0x6F, 0xFA, 0x60, 0x47, 0x60, 0x45, 0x80, 0x64, 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0xFC, 0x03,
+	 0xA4, 0x84, 0x70, 0xF0, 0x70, 0xFA, 0x00, 0x61, 0xE8, 0x84, 0xFF, 0xFF, 0x02, 0x05, 0xDD, 0x81,
+	 0xFB, 0x01, 0xE1, 0x81, 0x0F, 0x60, 0xA2, 0x65, 0x45, 0xD3, 0x0E, 0xFA, 0x66, 0x43, 0x0C, 0xF4,
+	 0x2B, 0x41, 0x4D, 0x8B, 0x02, 0xA3, 0xB6, 0x02, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x23, 0xF2,
+	 0x25, 0xF0, 0x02, 0xA8, 0x00, 0x67, 0x02, 0x02, 0x2D, 0xF9, 0x2C, 0xF9, 0x23, 0x58, 0xFF, 0xFF,
+	 0x28, 0x60, 0x42, 0x61, 0x23, 0xF2, 0x25, 0xF2, 0x02, 0xA8, 0x00, 0xA8, 0x09, 0x02, 0x07, 0x03,
+	 0xD0, 0xA0, 0x30, 0x65, 0x03, 0x04, 0xA7, 0xA0, 0x59, 0x65, 0x01, 0x06, 0x65, 0x44, 0xA1, 0xDB,
+	 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x31, 0x60, 0x2C, 0x61, 0x01, 0x64, 0xA1, 0xDB, 0x04, 0x00,
+	 0x31, 0x60, 0x2C, 0x61, 0x00, 0x64, 0xA1, 0xDB, 0x7E, 0x60, 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80,
+	 0x7F, 0x67, 0x02, 0x61, 0x0E, 0x02, 0x06, 0x61, 0x41, 0x56, 0xC7, 0xFE, 0x25, 0x60, 0x11, 0x78,
+	 0xFF, 0xFF, 0x36, 0x47, 0xFF, 0x23, 0x04, 0x00, 0x00, 0x7F, 0x60, 0x41, 0x7F, 0x67, 0x01, 0x00,
+	 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x7E, 0x60, 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80, 0x7F, 0x67,
+	 0x02, 0x61, 0x12, 0x02, 0x2D, 0x60, 0x58, 0x61, 0x65, 0x43, 0xA1, 0xDD, 0x0C, 0x61, 0x41, 0x56,
+	 0xC7, 0xFE, 0x25, 0x60, 0x11, 0x78, 0xFF, 0xFF, 0x36, 0x47, 0xFF, 0x23, 0x04, 0x00, 0x00, 0x7F,
+	 0x60, 0x41, 0x7F, 0x67, 0x01, 0x00, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x25, 0xF0, 0x29, 0x60,
+	 0xA2, 0x62, 0xA2, 0xD9, 0x19, 0x00, 0x2D, 0x60, 0x1A, 0x64, 0xA0, 0xD1, 0xA0, 0xF9, 0x0C, 0x60,
+	 0x38, 0x62, 0x40, 0x63, 0x00, 0x64, 0x5A, 0xDB, 0xFE, 0x1F, 0x64, 0x40, 0x01, 0x2A, 0x0C, 0x00,
+	 0x04, 0x65, 0x0C, 0x60, 0x38, 0x61, 0x48, 0x64, 0x3E, 0x63, 0x7C, 0xA8, 0x58, 0xD0, 0x59, 0xD9,
+	 0x02, 0x02, 0x00, 0xF4, 0x02, 0x64, 0xF9, 0x1F, 0x29, 0x60, 0xA2, 0x62, 0xA2, 0xD1, 0x0D, 0x60,
+	 0x1C, 0x65, 0x02, 0xFE, 0x64, 0x44, 0xF8, 0x84, 0xF8, 0x84, 0xF8, 0x87, 0x60, 0x41, 0x64, 0x44,
+	 0xE0, 0x84, 0xE0, 0x84, 0xC4, 0x84, 0x3E, 0xFB, 0x60, 0x42, 0x61, 0x44, 0x03, 0xA2, 0x60, 0xFE,
+	 0xA2, 0xDB, 0xFF, 0xFF, 0x20, 0xFE, 0x64, 0x44, 0x0C, 0x60, 0x3A, 0x65, 0xE0, 0x84, 0xE0, 0x84,
+	 0xE0, 0x84, 0xE0, 0x84, 0xC4, 0x84, 0x40, 0xFB, 0xFF, 0xFF, 0x00, 0x67, 0x00, 0x61, 0x23, 0x58,
+	 0xFF, 0xFF, 0x2D, 0x60, 0x1A, 0x64, 0xA0, 0xD1, 0xA0, 0xF9, 0x00, 0x64, 0x40, 0x41, 0x64, 0x40,
+	 0x01, 0x2A, 0xA4, 0x00, 0x4A, 0x64, 0xA0, 0xD2, 0xFF, 0xFF, 0x40, 0x42, 0x80, 0x2B, 0x04, 0x00,
+	 0xFF, 0xB4, 0x40, 0x42, 0x01, 0x64, 0x40, 0x41, 0xA9, 0xF3, 0x46, 0x4B, 0x60, 0x46, 0x20, 0x63,
+	 0xE3, 0x83, 0xAB, 0x46, 0x26, 0xF0, 0xAB, 0x46, 0x55, 0xF8, 0xAB, 0x46, 0x27, 0xF0, 0xAB, 0x46,
+	 0x56, 0xF8, 0xAB, 0x46, 0x28, 0xF0, 0xAB, 0x46, 0x57, 0xF8, 0x66, 0x44, 0x02, 0xA6, 0xF1, 0x1F,
+	 0xA9, 0xF3, 0xFF, 0xFF, 0x60, 0x46, 0xAB, 0x46, 0x0C, 0x60, 0x7A, 0x65, 0x22, 0x44, 0xFF, 0xB4,
+	 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xC4, 0x81, 0xC9, 0x81, 0x52, 0x64, 0x0E, 0x63,
+	 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0x21, 0x44, 0x01, 0x2A, 0x08, 0x00, 0xAB, 0x46, 0xF0, 0xA1,
+	 0x6E, 0x64, 0x0E, 0x63, 0x59, 0xD1, 0x58, 0xD8, 0xFD, 0x1F, 0xAB, 0x46, 0x22, 0x44, 0xFF, 0xB4,
+	 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0x0C, 0x60, 0xDC, 0x65, 0xC4, 0x81, 0x60, 0x45, 0xC9, 0x81,
+	 0x62, 0x64, 0x06, 0x63, 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0x21, 0x44, 0x01, 0x2A, 0x08, 0x00,
+	 0xAB, 0x46, 0xF8, 0xA1, 0xAE, 0x64, 0x06, 0x63, 0x59, 0xD1, 0x58, 0xD8, 0xFD, 0x1F, 0xAB, 0x46,
+	 0x65, 0x44, 0x0C, 0x60, 0xFC, 0x65, 0xC4, 0x81, 0xC9, 0x81, 0x6A, 0x64, 0x06, 0x63, 0x58, 0xD0,
+	 0x59, 0xD9, 0xFD, 0x1F, 0x22, 0x44, 0xFF, 0xB4, 0xE0, 0x84, 0xE0, 0x85, 0xC4, 0x84, 0x0C, 0x60,
+	 0xC2, 0x65, 0xC4, 0x81, 0x72, 0x64, 0x04, 0x63, 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0xAB, 0x46,
+	 0x21, 0x44, 0x01, 0x2A, 0x06, 0x00, 0xFA, 0xA1, 0x88, 0x64, 0x04, 0x63, 0x59, 0xD1, 0x58, 0xD8,
+	 0xFD, 0x1F, 0x37, 0xF0, 0x21, 0x44, 0x01, 0x2A, 0x13, 0x00, 0x22, 0x44, 0x3D, 0xFB, 0x60, 0x41,
+	 0x02, 0xFE, 0xF8, 0x84, 0xF8, 0x84, 0xF8, 0x84, 0x3C, 0xFB, 0x0C, 0x60, 0xBE, 0x63, 0x88, 0xFF,
+	 0xCD, 0x81, 0x06, 0xA3, 0xFD, 0x0D, 0x8D, 0xFF, 0x3B, 0xFD, 0x64, 0x47, 0x80, 0xBF, 0x60, 0x5C,
+	 0x22, 0x43, 0x80, 0x61, 0x88, 0xFF, 0xCF, 0x83, 0xE1, 0x81, 0xFD, 0x0D, 0x8D, 0xFF, 0x61, 0x47,
+	 0x31, 0x91, 0xB1, 0x84, 0x37, 0xFA, 0x1F, 0x63, 0xE3, 0x83, 0x66, 0x44, 0x02, 0xA6, 0x37, 0xF0,
+	 0x66, 0x44, 0xB1, 0x9C, 0x37, 0xF8, 0x02, 0xA6, 0xFA, 0x1F, 0xAB, 0x46, 0x00, 0x67, 0x00, 0x61,
+	 0x23, 0x58, 0xFF, 0xFF, 0x23, 0xF2, 0x25, 0xF0, 0x02, 0xA8, 0x00, 0x67, 0x22, 0x02, 0x3D, 0xF1,
+	 0x64, 0x44, 0x03, 0xB4, 0x40, 0x42, 0xD0, 0x80, 0xA9, 0xF3, 0xFF, 0xFF, 0x60, 0x46, 0xB7, 0xF4,
+	 0x80, 0x61, 0x02, 0x02, 0xE3, 0x83, 0xEB, 0x83, 0x22, 0x44, 0x88, 0xFF, 0xCC, 0x84, 0xE1, 0x81,
+	 0xFD, 0x0D, 0x8D, 0xFF, 0x61, 0x47, 0x31, 0x91, 0x9D, 0x85, 0xA7, 0x83, 0x37, 0xFC, 0x1F, 0x63,
+	 0xE3, 0x83, 0x66, 0x44, 0x02, 0xA6, 0xB7, 0xF2, 0x66, 0x44, 0xA5, 0x81, 0xB7, 0xFA, 0x02, 0xA6,
+	 0xFA, 0x1F, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x2D, 0x60, 0x1A, 0x64, 0xA0, 0xD1, 0xA0, 0xF9,
+	 0x64, 0x40, 0x01, 0x2A, 0x4E, 0x00, 0x27, 0xF2, 0x1C, 0x60, 0xBA, 0x65, 0x60, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46,
+	 0x27, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46, 0x26, 0xF0, 0x63, 0x46,
+	 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46, 0x25, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46, 0xE8, 0x1B, 0xA9, 0xF3, 0x08, 0xFE, 0x60, 0x43,
+	 0x61, 0x46, 0x01, 0x03, 0x2A, 0x00, 0x43, 0x4B, 0xAB, 0x46, 0x37, 0xF2, 0x80, 0x60, 0x30, 0x7C,
+	 0xB0, 0x84, 0xA2, 0xDA, 0x4E, 0x61, 0x6E, 0x64, 0x0E, 0x63, 0xAB, 0x46, 0x59, 0xD0, 0xAB, 0x46,
+	 0x58, 0xD8, 0xFB, 0x1F, 0x88, 0x64, 0x04, 0x63, 0xAB, 0x46, 0x59, 0xD0, 0xAB, 0x46, 0x58, 0xD8,
+	 0xFB, 0x1F, 0xD9, 0x81, 0x98, 0x64, 0x04, 0x63, 0xAB, 0x46, 0x59, 0xD0, 0xAB, 0x46, 0x58, 0xD8,
+	 0xFB, 0x1F, 0xD9, 0x81, 0xAE, 0x64, 0x0E, 0x63, 0xAB, 0x46, 0x59, 0xD0, 0xAB, 0x46, 0x58, 0xD8,
+	 0xFB, 0x1F, 0x00, 0x67, 0x00, 0x61, 0x23, 0x58, 0xFF, 0xFF, 0x01, 0x67, 0x20, 0x61, 0x23, 0x58,
+	 0xFF, 0xFF, 0x2D, 0x60, 0x1A, 0x64, 0xA0, 0xD1, 0xA0, 0xF9, 0x64, 0x40, 0x01, 0x2A, 0x31, 0x00,
+	 0x27, 0xF2, 0x1C, 0x60, 0xBA, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41,
+	 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46, 0x27, 0xF0, 0x63, 0x46, 0xD0, 0x80,
+	 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46, 0x26, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02,
+	 0x61, 0x46, 0x25, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF,
+	 0x63, 0x46, 0xE8, 0x1B, 0xA9, 0xF3, 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0x01, 0x03, 0x0D, 0x00,
+	 0x43, 0x4B, 0xAB, 0x46, 0x37, 0xF2, 0x80, 0x60, 0x30, 0x61, 0x9D, 0x85, 0xA4, 0x84, 0xA2, 0xDA,
+	 0xAB, 0x46, 0x00, 0x67, 0x00, 0x61, 0x23, 0x58, 0xFF, 0xFF, 0x01, 0x67, 0x20, 0x61, 0x23, 0x58,
+	 0xFF, 0xFF, 0xA2, 0xFF, 0x46, 0x45, 0x02, 0xF0, 0x09, 0x60, 0x08, 0x64, 0xD0, 0x80, 0x00, 0xF4,
+	 0x01, 0xF2, 0x66, 0x5C, 0x25, 0x46, 0x56, 0x02, 0x70, 0x27, 0x54, 0x00, 0x12, 0x64, 0x03, 0xFA,
+	 0x04, 0xF8, 0x0E, 0xF2, 0x87, 0xFC, 0x8D, 0xFC, 0x8E, 0xFC, 0xDA, 0x82, 0x16, 0x61, 0x00, 0x63,
+	 0xC9, 0x81, 0x5A, 0xDC, 0xFD, 0x02, 0x60, 0x40, 0xF0, 0x3B, 0x16, 0x00, 0x32, 0x44, 0xAF, 0xF3,
+	 0x01, 0xB0, 0xFA, 0xA0, 0x08, 0x24, 0x2C, 0x05, 0xDC, 0x83, 0xF0, 0x67, 0x0E, 0xFA, 0x24, 0x60,
+	 0x5E, 0x64, 0x2B, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xAF, 0xFD, 0x2B, 0xFF,
+	 0xFE, 0x64, 0x3B, 0x42, 0x4A, 0xDB, 0x4F, 0x00, 0xB0, 0xF3, 0x06, 0x65, 0xD4, 0x80, 0xDC, 0x83,
+	 0x17, 0x05, 0xB0, 0xFD, 0x98, 0xFE, 0x04, 0x04, 0x00, 0x7F, 0x08, 0x7E, 0x0E, 0xFA, 0x3B, 0xFF,
+	 0x24, 0x60, 0x52, 0x64, 0x2B, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0x0E, 0xF2,
+	 0x2B, 0xFF, 0x60, 0x40, 0x08, 0x26, 0xF7, 0xFE, 0xFD, 0x64, 0x3B, 0x42, 0x4A, 0xDB, 0x32, 0x00,
+	 0xAC, 0xF3, 0xFF, 0xFF, 0xD8, 0xA0, 0xFF, 0xFF, 0x0D, 0x04, 0x24, 0x60, 0x6A, 0x64, 0x2B, 0xDB,
+	 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xFC, 0x64, 0x3B, 0x42,
+	 0x4A, 0xDB, 0x21, 0x00, 0x46, 0x45, 0x00, 0x64, 0x2B, 0xDB, 0x25, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xA2, 0xFF, 0x00, 0xF4, 0x01, 0xF0, 0x0A, 0x18, 0x70, 0x67,
+	 0xA0, 0x80, 0xF0, 0x67, 0x06, 0x03, 0xC0, 0x84, 0x01, 0xFA, 0x25, 0x46, 0x25, 0x44, 0x80, 0xFC,
+	 0x05, 0xFA, 0xAF, 0x60, 0x58, 0x4E, 0x95, 0x78, 0xFF, 0xFF, 0xD4, 0xFE, 0xA3, 0xFF, 0xFF, 0x64,
+	 0x3B, 0x42, 0x4A, 0xDB, 0xD4, 0xFE, 0xA3, 0xFF, 0x2D, 0x58, 0xFF, 0xFF, 0x24, 0x60, 0x58, 0x64,
+	 0x40, 0x47, 0x58, 0x4F, 0x0D, 0x00, 0x24, 0x60, 0x4C, 0x64, 0x40, 0x47, 0x58, 0x4F, 0x18, 0x00,
+	 0x24, 0x60, 0x64, 0x64, 0x40, 0x47, 0x58, 0x4F, 0x03, 0x00, 0x25, 0x60, 0x11, 0x78, 0xFF, 0xFF,
+	 0x27, 0xD5, 0x0E, 0xF2, 0x0B, 0x18, 0x60, 0x40, 0x01, 0x2A, 0x08, 0x00, 0x24, 0x60, 0x7A, 0x64,
+	 0x40, 0x4B, 0x2C, 0x60, 0x58, 0x4D, 0xD8, 0x78, 0xFF, 0xFF, 0xF2, 0x01, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x27, 0xD5, 0x0E, 0xF2, 0x14, 0x18, 0x60, 0x40, 0x01, 0x2A, 0x11, 0x00, 0x02, 0xF0, 0x09, 0x60,
+	 0x08, 0x64, 0xD0, 0x80, 0xA2, 0xFF, 0xB0, 0xF3, 0x02, 0x02, 0xCC, 0x84, 0xB0, 0xFB, 0x24, 0x60,
+	 0x7A, 0x64, 0x40, 0x4B, 0x2C, 0x60, 0x58, 0x4D, 0xD8, 0x78, 0xFF, 0xFF, 0xE9, 0x01, 0x2F, 0x58,
+	 0xFF, 0xFF, 0xFB, 0x64, 0x3A, 0x42, 0x4A, 0xDB, 0xA2, 0xFF, 0xB3, 0xF3, 0xAF, 0xF3, 0xCC, 0x80,
+	 0xFD, 0xA0, 0x01, 0x14, 0x1E, 0x05, 0xAE, 0x60, 0x58, 0x4D, 0x9B, 0x78, 0xFF, 0xFF, 0xA2, 0xFF,
+	 0x18, 0x03, 0xF0, 0x67, 0x0E, 0xFA, 0x24, 0x60, 0x7A, 0x62, 0x24, 0x60, 0x5E, 0x64, 0xA2, 0xDB,
+	 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xF6, 0x64, 0x3A, 0x42,
+	 0x4A, 0xDB, 0xB3, 0xF3, 0xAF, 0xF3, 0xCC, 0x83, 0xDC, 0x84, 0x01, 0x15, 0xB3, 0xFD, 0xAF, 0xFB,
+	 0xD4, 0xFE, 0xB2, 0xF3, 0xB0, 0xF3, 0x00, 0xA8, 0xB1, 0xF1, 0x03, 0x02, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x27, 0x05, 0xAE, 0x60, 0x58, 0x4D, 0x9B, 0x78, 0xFF, 0xFF, 0xA2, 0xFF, 0x21, 0x03, 0x00, 0x63,
+	 0xB2, 0xF3, 0x0E, 0xFC, 0xCC, 0x84, 0xFF, 0x3A, 0xB2, 0xFB, 0x98, 0xFE, 0x03, 0x04, 0x08, 0xBB,
+	 0x0E, 0xFC, 0x3B, 0xFF, 0x24, 0x60, 0x7A, 0x62, 0x24, 0x60, 0x52, 0x64, 0xA2, 0xDB, 0x66, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xF7, 0x64, 0x3A, 0x42, 0x4A, 0xDB,
+	 0xB0, 0xF3, 0x0E, 0xF2, 0xDC, 0x83, 0x08, 0xB0, 0xB0, 0xFD, 0x08, 0x28, 0xF7, 0xFE, 0xD4, 0xFE,
+	 0xA3, 0xFF, 0x25, 0x60, 0x11, 0x78, 0xFF, 0xFF, 0xB9, 0xFE, 0x13, 0xFF, 0x24, 0x40, 0x80, 0x2B,
+	 0x0B, 0x00, 0xA2, 0xFF, 0x25, 0x46, 0x09, 0xF4, 0x0E, 0xF2, 0x05, 0x18, 0x08, 0xBC, 0x0E, 0xFA,
+	 0xFF, 0xFF, 0xF7, 0xFE, 0x01, 0x00, 0xD8, 0xFE, 0xA3, 0xFF, 0x25, 0x46, 0x3E, 0xF2, 0x00, 0xF4,
+	 0x08, 0xF0, 0x25, 0x46, 0x06, 0xB4, 0xFF, 0x7F, 0x10, 0xBC, 0x06, 0x26, 0xFD, 0x7F, 0x0E, 0xFA,
+	 0x3E, 0xF2, 0x3F, 0xF2, 0x60, 0x41, 0x08, 0x2A, 0x64, 0x47, 0x3F, 0xFA, 0x60, 0x45, 0x27, 0x60,
+	 0xFC, 0x62, 0xA2, 0xD3, 0xA3, 0xFC, 0xAB, 0xFC, 0x91, 0xFC, 0xD4, 0x80, 0xC0, 0x60, 0xE1, 0x65,
+	 0xA5, 0x80, 0x01, 0x04, 0x07, 0x03, 0x23, 0xF0, 0x08, 0x64, 0xB0, 0x84, 0xA2, 0xDA, 0x2E, 0x60,
+	 0xC5, 0x78, 0xFF, 0xFF, 0x2F, 0x60, 0x58, 0x4F, 0x0F, 0x78, 0xFF, 0xFF, 0x14, 0x04, 0x23, 0xF0,
+	 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDA, 0xB8, 0xF1, 0x27, 0x60, 0x96, 0x64, 0xA0, 0xD3, 0xFF, 0xFF,
+	 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x02, 0x00,
+	 0x20, 0x60, 0x00, 0x75, 0x83, 0x00, 0xDC, 0xF3, 0xA9, 0xF1, 0x07, 0xB4, 0x64, 0x43, 0xFD, 0xA0,
+	 0x2C, 0xF2, 0x71, 0x02, 0x01, 0xB0, 0x64, 0x43, 0x78, 0x02, 0x2E, 0xF2, 0x1C, 0x60, 0xBA, 0x65,
+	 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2,
+	 0x16, 0x18, 0x61, 0x46, 0x2E, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46,
+	 0x2D, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46, 0x2C, 0xF0, 0x63, 0x46,
+	 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46, 0xE8, 0x1B, 0xA9, 0xF3,
+	 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0x51, 0x03, 0x63, 0x46, 0x80, 0xF6, 0x25, 0x46, 0x43, 0x18,
+	 0x2E, 0xF2, 0x66, 0x41, 0x1C, 0x60, 0xBA, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xA9, 0xF1, 0xE0, 0x84,
+	 0x44, 0xD3, 0x64, 0x43, 0x11, 0x18, 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xFC, 0x1B, 0x66, 0x44,
+	 0x64, 0x46, 0x80, 0xF0, 0x60, 0x46, 0x80, 0xF8, 0x65, 0x46, 0x65, 0x43, 0x80, 0xF0, 0x01, 0xFA,
+	 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8, 0x0B, 0x00, 0x64, 0x46, 0x62, 0x43, 0x00, 0xF2, 0xA3, 0xDB,
+	 0x60, 0x46, 0x80, 0xF0, 0x81, 0xFC, 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8, 0x60, 0x43, 0x61, 0x46,
+	 0x43, 0x4B, 0x2C, 0xF0, 0xAD, 0xF0, 0x2E, 0xF2, 0xAB, 0x46, 0x03, 0xF8, 0x84, 0xF8, 0x05, 0xFA,
+	 0x03, 0x64, 0x06, 0xFA, 0xAB, 0x46, 0x1E, 0x60, 0xBC, 0x61, 0xA1, 0xD3, 0x1E, 0x60, 0xFE, 0x7C,
+	 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0xA0, 0xDD, 0xDA, 0x9C, 0xA1, 0xD9, 0x49, 0xD3, 0xFF, 0xFF,
+	 0xDC, 0x84, 0xA1, 0xDB, 0x0A, 0x00, 0xDC, 0xF3, 0x02, 0xA3, 0xFE, 0xA0, 0xF9, 0xA0, 0x01, 0x06,
+	 0x04, 0x02, 0x23, 0xF0, 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDA, 0x07, 0xFC, 0x23, 0xF2, 0xFF, 0xFF,
+	 0x27, 0x1B, 0x27, 0x60, 0xFE, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x60, 0x40, 0x00, 0x3A, 0x10, 0x00,
+	 0x24, 0x60, 0x7A, 0x62, 0x24, 0x60, 0x22, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x0E, 0xF2, 0xC1, 0xFE, 0x10, 0xAC, 0x0E, 0xFA, 0x1F, 0x00,
+	 0x24, 0x60, 0x7A, 0x62, 0x24, 0x60, 0x34, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x0E, 0xF2, 0xC8, 0xFE, 0x10, 0xAC, 0x0E, 0xFA, 0x0F, 0x00,
+	 0x24, 0x60, 0x7A, 0x62, 0x24, 0x60, 0x46, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x0E, 0xF2, 0xCE, 0xFE, 0x10, 0xAC, 0x0E, 0xFA, 0x25, 0x60,
+	 0x11, 0x78, 0xFF, 0xFF, 0xCB, 0x84, 0xC9, 0x83, 0xFF, 0xFF, 0x08, 0x04, 0x58, 0xD1, 0xA5, 0xD8,
+	 0xDA, 0x85, 0x80, 0x3A, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0xF8, 0x1F, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x3E, 0xF2, 0xCC, 0xF1, 0x08, 0xB0, 0x19, 0xF8, 0x3B, 0x02, 0xEB, 0xF1, 0x2F, 0xF8, 0xEC, 0xF3,
+	 0x30, 0xFA, 0x60, 0x45, 0xED, 0xF3, 0x31, 0xFA, 0x46, 0x4A, 0x00, 0xF4, 0x60, 0x43, 0x05, 0xF2,
+	 0x06, 0xF2, 0xD0, 0x80, 0x07, 0xF0, 0x05, 0x02, 0xD4, 0x80, 0xD3, 0x80, 0x02, 0x02, 0xDC, 0xF3,
+	 0x03, 0x03, 0xAA, 0x46, 0x42, 0xFE, 0x25, 0x00, 0x60, 0x40, 0x03, 0x2A, 0x10, 0x00, 0x02, 0xF2,
+	 0x03, 0xF0, 0x04, 0xF2, 0x60, 0x43, 0xAA, 0x46, 0x2C, 0xFC, 0x2D, 0xF8, 0x2E, 0xFA, 0x81, 0xF1,
+	 0x32, 0xF8, 0x82, 0xF1, 0x33, 0xF8, 0x83, 0xF1, 0x34, 0xF8, 0x08, 0x64, 0x10, 0x00, 0x02, 0xF2,
+	 0x03, 0xF0, 0x04, 0xF2, 0x60, 0x43, 0xAA, 0x46, 0x32, 0xFC, 0x33, 0xF8, 0x34, 0xFA, 0x81, 0xF1,
+	 0x2C, 0xF8, 0x82, 0xF1, 0x2D, 0xF8, 0x83, 0xF1, 0x2E, 0xF8, 0x01, 0x60, 0x08, 0x64, 0x2A, 0xFA,
+	 0x02, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x30, 0x44, 0x02, 0xA8, 0x00, 0xE1, 0x03, 0x02, 0x42, 0xFF,
+	 0x47, 0xFF, 0xA1, 0xFF, 0x80, 0xFF, 0x90, 0xFF, 0x98, 0xFF, 0x88, 0xFF, 0x84, 0xE1, 0xFF, 0xFF,
+	 0x00, 0x00, 0xA1, 0xFF, 0xFF, 0xFF, 0x87, 0x3E, 0x2D, 0x60, 0x9C, 0x64, 0xA0, 0xD3, 0xFF, 0xFF,
+	 0x01, 0x1B, 0xF7, 0x01, 0x87, 0xFF, 0x20, 0x44, 0x80, 0xFF, 0x60, 0x40, 0x80, 0x26, 0xF1, 0x01,
+	 0xC0, 0x60, 0x40, 0xEC, 0xC0, 0x60, 0x00, 0xED, 0xC0, 0x60, 0x80, 0xEE, 0xAC, 0x4F, 0xBF, 0xB4,
+	 0xA0, 0x5C, 0x2D, 0x60, 0x1A, 0x62, 0xA2, 0xD1, 0xFF, 0xFF, 0x64, 0x40, 0x02, 0x27, 0x06, 0x00,
+	 0x28, 0xE2, 0x24, 0xE2, 0xBF, 0xFF, 0xFF, 0xFF, 0x75, 0x40, 0x10, 0x00, 0x28, 0xE2, 0x24, 0xE2,
+	 0x00, 0x60, 0x00, 0x61, 0x00, 0x60, 0x94, 0xE0, 0xBF, 0xFF, 0xFF, 0xFF, 0xA1, 0x50, 0x75, 0x40,
+	 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x60, 0x10, 0xE0, 0x2D, 0x60, 0x9C, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x01, 0x60, 0x39, 0xE2, 0x04, 0x60, 0x00, 0x7A, 0xAC, 0x4F, 0x40, 0xBC,
+	 0x00, 0x7F, 0xA0, 0x5C, 0xC0, 0x60, 0xD9, 0xEC, 0xC0, 0x60, 0x0F, 0xED, 0xC0, 0x60, 0x8F, 0xEE,
+	 0xAE, 0x4F, 0x04, 0xBC, 0x00, 0x7F, 0xA0, 0x5E, 0x26, 0x61, 0xCD, 0x81, 0xFF, 0xFF, 0xFD, 0x02,
+	 0xAE, 0x4F, 0xFB, 0xB4, 0xA0, 0x5E, 0xAD, 0x01, 0x80, 0xFF, 0x90, 0xFF, 0x98, 0xFF, 0x2F, 0x60,
+	 0x54, 0x63, 0x20, 0x44, 0xBD, 0xDB, 0x21, 0x44, 0xBD, 0xDB, 0x22, 0x44, 0xBD, 0xDB, 0x23, 0x44,
+	 0xBD, 0xDB, 0x24, 0x44, 0xBD, 0xDB, 0x25, 0x44, 0xBD, 0xDB, 0x26, 0x44, 0xBD, 0xDB, 0x27, 0x44,
+	 0xBD, 0xDB, 0x28, 0x44, 0xBD, 0xDB, 0x29, 0x44, 0xBD, 0xDB, 0x2A, 0x44, 0xBD, 0xDB, 0x2B, 0x44,
+	 0xBD, 0xDB, 0x2C, 0x44, 0xBD, 0xDB, 0x2D, 0x44, 0xBD, 0xDB, 0x2E, 0x44, 0xBD, 0xDB, 0x2F, 0x44,
+	 0xBD, 0xDB, 0x2F, 0x60, 0x48, 0x64, 0xA0, 0xDD, 0x30, 0x60, 0x74, 0x63, 0x2F, 0x60, 0x4A, 0x64,
+	 0xA0, 0xDD, 0x2F, 0x60, 0x4C, 0x63, 0x30, 0x44, 0xA3, 0xDB, 0x2F, 0x60, 0x4E, 0x63, 0x31, 0x44,
+	 0xA3, 0xDB, 0x2F, 0x60, 0x50, 0x63, 0x32, 0x44, 0xA3, 0xDB, 0x2F, 0x60, 0x52, 0x63, 0x33, 0x44,
+	 0xA3, 0xDB, 0x81, 0xFF, 0x91, 0xFF, 0x58, 0x51, 0x4B, 0x00, 0x82, 0xFF, 0x92, 0xFF, 0x58, 0x51,
+	 0x47, 0x00, 0x83, 0xFF, 0x93, 0xFF, 0x58, 0x51, 0x43, 0x00, 0x84, 0xFF, 0x94, 0xFF, 0x58, 0x51,
+	 0x3F, 0x00, 0x85, 0xFF, 0x95, 0xFF, 0x58, 0x51, 0x3B, 0x00, 0x86, 0xFF, 0x96, 0xFF, 0x58, 0x51,
+	 0x37, 0x00, 0x87, 0xFF, 0x97, 0xFF, 0x58, 0x51, 0x33, 0x00, 0x80, 0xFF, 0x90, 0xFF, 0x99, 0xFF,
+	 0x2F, 0x60, 0x48, 0x64, 0xA0, 0xD1, 0x30, 0x44, 0x64, 0x43, 0xBD, 0xDB, 0x31, 0x44, 0xBD, 0xDB,
+	 0x32, 0x44, 0xBD, 0xDB, 0x33, 0x44, 0xBD, 0xDB, 0x34, 0x44, 0xBD, 0xDB, 0x35, 0x44, 0xBD, 0xDB,
+	 0x36, 0x44, 0xBD, 0xDB, 0x37, 0x44, 0xBD, 0xDB, 0x38, 0x44, 0xBD, 0xDB, 0x39, 0x44, 0xBD, 0xDB,
+	 0x3A, 0x44, 0xBD, 0xDB, 0x3B, 0x44, 0xBD, 0xDB, 0x3C, 0x44, 0xBD, 0xDB, 0x3D, 0x44, 0xBD, 0xDB,
+	 0x3E, 0x44, 0xBD, 0xDB, 0x3F, 0x44, 0xBD, 0xDB, 0xEF, 0x60, 0x48, 0x64, 0x0A, 0xFB, 0x40, 0x21,
+	 0xFE, 0x01, 0x80, 0xFF, 0x90, 0xFF, 0x98, 0xFF, 0x88, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0x87, 0x3E,
+	 0x42, 0x50, 0x40, 0x53, 0x2F, 0x60, 0x4A, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x40, 0x52, 0x33, 0x44,
+	 0x32, 0x42, 0xA2, 0xDB, 0xDA, 0x82, 0xA2, 0xDD, 0xDA, 0x83, 0x65, 0x44, 0xBD, 0xDB, 0x61, 0x44,
+	 0xBD, 0xDB, 0x66, 0x44, 0xBD, 0xDB, 0xBD, 0xD9, 0x30, 0x44, 0xBD, 0xDB, 0x99, 0xFF, 0xA4, 0x4C,
+	 0xBD, 0xDB, 0xA5, 0x4C, 0xBD, 0xDB, 0xA0, 0x4C, 0xBD, 0xDB, 0xA1, 0x4C, 0xBD, 0xDB, 0x98, 0xFF,
+	 0x2F, 0x60, 0x4A, 0x64, 0xA0, 0xDD, 0x2F, 0x60, 0x4C, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x40, 0x50,
+	 0x2F, 0x60, 0x50, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x40, 0x52, 0x2F, 0x60, 0x52, 0x62, 0xA2, 0xD3,
+	 0xFF, 0xFF, 0x40, 0x53, 0x31, 0x41, 0x2F, 0x60, 0x4E, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x40, 0x51,
+	 0x2F, 0x60, 0x48, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x60, 0x43, 0x20, 0x44, 0xBD, 0xDB, 0x21, 0x44,
+	 0xBD, 0xDB, 0x22, 0x44, 0xBD, 0xDB, 0x23, 0x44, 0xBD, 0xDB, 0x24, 0x44, 0xBD, 0xDB, 0x25, 0x44,
+	 0xBD, 0xDB, 0x26, 0x44, 0xBD, 0xDB, 0x27, 0x44, 0xBD, 0xDB, 0x28, 0x44, 0xBD, 0xDB, 0x29, 0x44,
+	 0xBD, 0xDB, 0x2A, 0x44, 0xBD, 0xDB, 0x2B, 0x44, 0xBD, 0xDB, 0x2C, 0x44, 0xBD, 0xDB, 0x2D, 0x44,
+	 0xBD, 0xDB, 0x2E, 0x44, 0xBD, 0xDB, 0x2F, 0x44, 0xBD, 0xDB, 0x2F, 0x60, 0x48, 0x64, 0xA0, 0xDD,
+	 0x61, 0x58, 0xFF, 0xFF, 0x24, 0xE2, 0x2D, 0xF3, 0x2C, 0xF3, 0x00, 0xBD, 0xCC, 0x84, 0x08, 0x03,
+	 0x2C, 0xFB, 0x06, 0x02, 0x65, 0x44, 0x2C, 0xFB, 0x8A, 0xFF, 0x80, 0x60, 0x00, 0x75, 0x88, 0xFF,
+	 0xF2, 0xF3, 0x31, 0x40, 0x01, 0x2A, 0x44, 0x00, 0x60, 0x43, 0x04, 0xB0, 0x02, 0xB0, 0x08, 0x24,
+	 0x16, 0x02, 0x29, 0x44, 0xFF, 0xFF, 0x00, 0xA8, 0xCC, 0x81, 0x0E, 0x03, 0x41, 0x49, 0x37, 0x02,
+	 0x63, 0x40, 0x08, 0x2A, 0x09, 0x00, 0xF7, 0xB3, 0x31, 0x60, 0x1E, 0x7C, 0xA4, 0xD1, 0xAD, 0x4F,
+	 0xFD, 0xB4, 0xA0, 0x5D, 0x44, 0x49, 0x2B, 0x00, 0x63, 0x40, 0x02, 0x2A, 0x14, 0x00, 0x31, 0x60,
+	 0x20, 0x64, 0xA0, 0xD3, 0x31, 0x60, 0x1C, 0x7C, 0xA4, 0xDB, 0x40, 0x49, 0x31, 0x60, 0x22, 0x64,
+	 0xA0, 0xD3, 0x31, 0x60, 0x1E, 0x7C, 0xA4, 0xDB, 0x0C, 0xBB, 0xFD, 0xB3, 0xAD, 0x4F, 0x02, 0xBC,
+	 0x00, 0x7F, 0xA0, 0x5D, 0x14, 0x00, 0x31, 0x60, 0x24, 0x64, 0xA0, 0xD3, 0x31, 0x60, 0x1C, 0x7C,
+	 0x0E, 0x18, 0xA4, 0xDB, 0x40, 0x49, 0x31, 0x60, 0x26, 0x64, 0xA0, 0xD3, 0x31, 0x60, 0x1E, 0x7C,
+	 0xA4, 0xDB, 0x08, 0xBB, 0xFB, 0xB3, 0xAD, 0x4F, 0x02, 0xBC, 0x00, 0x7F, 0xA0, 0x5D, 0xF2, 0xFD,
+	 0x01, 0x60, 0x4E, 0x61, 0xA1, 0xD3, 0x61, 0x43, 0x17, 0x18, 0x58, 0xD3, 0x62, 0x41, 0x03, 0x18,
+	 0xCC, 0x84, 0xA1, 0xDB, 0x11, 0x00, 0x49, 0xD3, 0xA3, 0xDB, 0x06, 0xA1, 0xA1, 0xD3, 0x59, 0xD1,
+	 0x60, 0x45, 0xA5, 0xD3, 0x59, 0xD1, 0xB0, 0x84, 0xA5, 0xDB, 0x64, 0x44, 0x06, 0x36, 0xCD, 0xFE,
+	 0x07, 0x36, 0xD6, 0xFE, 0xE5, 0x01, 0x23, 0x46, 0xB0, 0x60, 0xA4, 0x78, 0xFF, 0xFF, 0x46, 0x43,
+	 0x24, 0x60, 0xA4, 0x61, 0xA1, 0xD3, 0x59, 0xD1, 0x06, 0x1B, 0x59, 0xD3, 0x59, 0xD1, 0x03, 0x1B,
+	 0x59, 0xD3, 0x59, 0xD1, 0xF0, 0x18, 0x00, 0x63, 0x49, 0xDD, 0x60, 0x40, 0x02, 0x36, 0x11, 0x00,
+	 0x03, 0x36, 0x32, 0x00, 0x01, 0x36, 0x08, 0x00, 0x05, 0x3A, 0xEA, 0x01, 0xA4, 0xD3, 0x5A, 0xD3,
+	 0x9C, 0x85, 0xA4, 0x84, 0xA2, 0xDB, 0xE4, 0x01, 0x01, 0x60, 0x4E, 0x61, 0x00, 0x64, 0xA1, 0xDB,
+	 0xDF, 0x01, 0x31, 0x60, 0x3C, 0x64, 0x40, 0x45, 0x22, 0x00, 0x01, 0x60, 0x4E, 0x66, 0xA6, 0xD3,
+	 0x04, 0xA1, 0x60, 0x43, 0xA1, 0xD3, 0xC9, 0x81, 0x60, 0x45, 0x00, 0xBB, 0xA1, 0xDB, 0xBE, 0xD3,
+	 0x09, 0x03, 0xD4, 0x84, 0x9C, 0x84, 0xDC, 0x84, 0xFF, 0xFF, 0x04, 0x0E, 0xA3, 0xD1, 0x63, 0x46,
+	 0x64, 0x43, 0xF2, 0x01, 0x9C, 0x84, 0xDC, 0x85, 0x49, 0xDD, 0x61, 0x44, 0x00, 0xBB, 0xA6, 0xDB,
+	 0x02, 0x03, 0x65, 0x44, 0xBE, 0xDB, 0xBC, 0x01, 0x31, 0x60, 0x17, 0x64, 0x40, 0x45, 0x01, 0x60,
+	 0x4E, 0x66, 0xA6, 0xD3, 0xFF, 0xFF, 0xD0, 0x80, 0x0F, 0x18, 0x02, 0x03, 0x60, 0x46, 0xF9, 0x01,
+	 0x58, 0xD3, 0xA4, 0xD3, 0x60, 0x45, 0x00, 0x63, 0xA4, 0xDD, 0x05, 0x18, 0x58, 0xD3, 0xFF, 0xFF,
+	 0xC4, 0x83, 0xA2, 0xDD, 0xCA, 0x84, 0xA6, 0xDB, 0x25, 0x58, 0x64, 0x41, 0x00, 0x60, 0x46, 0x74,
+	 0xCD, 0xE2, 0x04, 0xE1, 0x02, 0x60, 0x00, 0xE1, 0x3F, 0x44, 0x40, 0x26, 0x0B, 0x00, 0x01, 0x2A,
+	 0x05, 0x00, 0x42, 0x60, 0x09, 0xE0, 0x60, 0x60, 0x1C, 0xE0, 0x04, 0x00, 0x42, 0x60, 0x09, 0xE0,
+	 0x80, 0x60, 0x1C, 0xE0, 0x04, 0x29, 0xFE, 0x01, 0xC4, 0xE2, 0x43, 0x64, 0x3A, 0xDB, 0xA4, 0xF3,
+	 0xFF, 0xFF, 0x60, 0x41, 0x3F, 0x44, 0x02, 0x27, 0x84, 0x00, 0x20, 0x2B, 0xFF, 0x01, 0x80, 0xE1,
+	 0x95, 0x60, 0x80, 0xE7, 0x61, 0x40, 0x40, 0x2B, 0x0D, 0x00, 0x05, 0x63, 0x32, 0x60, 0x58, 0x4F,
+	 0x6A, 0x78, 0xFF, 0xFF, 0x28, 0x63, 0xFF, 0xFF, 0xFE, 0x1F, 0x01, 0x63, 0x32, 0x60, 0x58, 0x4F,
+	 0x6A, 0x78, 0xFF, 0xFF, 0xFF, 0xB1, 0xCD, 0x81, 0xE1, 0x85, 0x27, 0x60, 0x3C, 0x64, 0x44, 0xD1,
+	 0xFF, 0xFF, 0x64, 0x43, 0x32, 0x60, 0x58, 0x4F, 0x6A, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x00, 0x63,
+	 0x32, 0x60, 0x58, 0x4F, 0x6A, 0x78, 0xFF, 0xFF, 0x27, 0x60, 0x58, 0x61, 0x29, 0x60, 0xE8, 0x62,
+	 0xA2, 0xD3, 0x45, 0xD1, 0x47, 0xBC, 0xE0, 0x84, 0x62, 0x45, 0x64, 0x5F, 0xE8, 0x83, 0x32, 0x60,
+	 0x58, 0x4F, 0x6A, 0x78, 0xFF, 0xFF, 0xA3, 0xF3, 0xCD, 0xE2, 0x60, 0x54, 0x04, 0xE1, 0x04, 0x29,
+	 0xFE, 0x01, 0xC4, 0xE2, 0x15, 0x60, 0xA2, 0xE7, 0x38, 0x69, 0xFF, 0xFF, 0x68, 0x44, 0x01, 0x16,
+	 0xFD, 0x01, 0x01, 0x2A, 0x36, 0x00, 0x03, 0x60, 0x80, 0x7C, 0xA3, 0x83, 0x29, 0x60, 0xE8, 0x62,
+	 0xA2, 0xD1, 0x43, 0xBB, 0xB3, 0x83, 0x95, 0x60, 0x80, 0xE7, 0x32, 0x60, 0x58, 0x4F, 0x6A, 0x78,
+	 0xFF, 0xFF, 0xE3, 0x83, 0x15, 0x60, 0xA2, 0xE7, 0x38, 0x69, 0xFF, 0xFF, 0x68, 0x41, 0x01, 0x16,
+	 0xFD, 0x01, 0x63, 0x47, 0x61, 0x40, 0x01, 0x2A, 0x03, 0x00, 0x00, 0x3A, 0xCC, 0x84, 0x02, 0x00,
+	 0x07, 0x3A, 0xDC, 0x84, 0xFF, 0xB4, 0xA5, 0xDB, 0x60, 0x47, 0xE8, 0x84, 0x47, 0x65, 0x29, 0x60,
+	 0xE8, 0x62, 0xA2, 0xD3, 0xB4, 0x85, 0xB4, 0x83, 0x80, 0xE1, 0x95, 0x60, 0x80, 0xE7, 0x32, 0x60,
+	 0x58, 0x4F, 0x6A, 0x78, 0xFF, 0xFF, 0xA3, 0xF3, 0xCD, 0xE2, 0x60, 0x54, 0x04, 0x29, 0xFE, 0x01,
+	 0xC4, 0xE2, 0xA4, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x2B, 0x04, 0x00, 0x32, 0x60, 0x43, 0x78,
+	 0xFF, 0xFF, 0xFF, 0x01, 0xA4, 0xF3, 0x80, 0xE1, 0xCC, 0x84, 0xE0, 0x85, 0x15, 0x60, 0xA2, 0xE7,
+	 0x26, 0x60, 0x78, 0x64, 0x58, 0x4F, 0x4F, 0x00, 0x26, 0x60, 0x94, 0x64, 0x58, 0x4F, 0x4B, 0x00,
+	 0x26, 0x60, 0xB0, 0x64, 0x58, 0x4F, 0x47, 0x00, 0x26, 0x60, 0xCC, 0x64, 0x58, 0x4F, 0x43, 0x00,
+	 0x26, 0x60, 0xE8, 0x64, 0x58, 0x4F, 0x3F, 0x00, 0x27, 0x60, 0x04, 0x64, 0x58, 0x4F, 0x3B, 0x00,
+	 0x27, 0x60, 0x20, 0x64, 0x58, 0x4F, 0x37, 0x00, 0x01, 0x68, 0xFF, 0x6A, 0xFF, 0xFF, 0x01, 0x16,
+	 0xFE, 0x01, 0x3F, 0x44, 0x20, 0x27, 0x00, 0x00, 0x3F, 0x40, 0x40, 0x26, 0x08, 0x00, 0x00, 0x60,
+	 0x18, 0x64, 0x00, 0x60, 0x00, 0x65, 0x94, 0x84, 0xA0, 0x50, 0x1D, 0x60, 0x19, 0xE2, 0xC4, 0xE2,
+	 0x00, 0x63, 0xA3, 0xFD, 0x32, 0x7B, 0x4D, 0xE2, 0xBF, 0xFE, 0xC4, 0xE2, 0x41, 0xFF, 0xE0, 0xFE,
+	 0xE1, 0xFE, 0xE2, 0xFE, 0x43, 0xFF, 0x44, 0xFF, 0x46, 0xFF, 0xA5, 0xF3, 0x62, 0xFF, 0x60, 0x40,
+	 0x05, 0x36, 0x2D, 0xFF, 0x07, 0x36, 0xD5, 0xFE, 0x08, 0xE1, 0x88, 0x60, 0x85, 0x71, 0x8D, 0xE2,
+	 0xA2, 0x60, 0x16, 0x78, 0xFF, 0xFF, 0x50, 0xEC, 0x63, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01,
+	 0x40, 0xEC, 0x2F, 0x58, 0xFF, 0xFF, 0x44, 0xD3, 0x80, 0x7C, 0x60, 0x48, 0x60, 0x47, 0x00, 0x7F,
+	 0xB0, 0x8A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x2F, 0x58, 0xFF, 0xFF, 0x42, 0xFF, 0x40, 0xFF,
+	 0xDD, 0xFE, 0xAD, 0x4F, 0x00, 0x7F, 0x01, 0xBC, 0xA0, 0x5D, 0x00, 0xEE, 0x19, 0x61, 0xCD, 0x81,
+	 0xFF, 0xFF, 0xFD, 0x02, 0x43, 0x45, 0x20, 0x44, 0x60, 0xBC, 0x40, 0x40, 0x02, 0x60, 0xEE, 0x63,
+	 0x7F, 0xF3, 0xA3, 0xFD, 0x40, 0x7F, 0xA4, 0xFB, 0x05, 0x64, 0xA5, 0xFB, 0xDF, 0xFE, 0x19, 0xFF,
+	 0x24, 0x60, 0xDD, 0x64, 0x3F, 0x40, 0x01, 0x2B, 0x02, 0x00, 0x32, 0x60, 0xA2, 0x64, 0xA6, 0xFB,
+	 0xBB, 0x60, 0x20, 0x78, 0xFF, 0xFF, 0x04, 0xEE, 0xAD, 0x4F, 0x00, 0x7F, 0x01, 0xBC, 0xA0, 0x5D,
+	 0x19, 0x61, 0xCD, 0x81, 0xFF, 0xFF, 0xFD, 0x02, 0xAD, 0x4F, 0x00, 0x7F, 0x01, 0xBC, 0xA0, 0x5D,
+	 0x00, 0xEE, 0x15, 0x60, 0xA2, 0xE7, 0x25, 0x60, 0x02, 0x63, 0x25, 0x60, 0x76, 0x65, 0xDF, 0xFE,
+	 0x80, 0xE1, 0xBD, 0xD3, 0xFF, 0xFF, 0x60, 0x48, 0x60, 0x47, 0x80, 0xBC, 0x00, 0x7F, 0x60, 0x4A,
+	 0xD7, 0x80, 0xA1, 0xFF, 0xFF, 0xFF, 0xF5, 0x02, 0x25, 0x60, 0x76, 0x63, 0x26, 0x60, 0x78, 0x65,
+	 0xBD, 0xD3, 0xFF, 0xFF, 0x60, 0x48, 0x60, 0x47, 0x80, 0xBC, 0x00, 0x7F, 0x60, 0x4A, 0xD7, 0x80,
+	 0xA1, 0xFF, 0xFF, 0xFF, 0xF5, 0x02, 0x3F, 0x40, 0x20, 0x2B, 0x00, 0x00, 0x01, 0x68, 0xFF, 0x6A,
+	 0xBF, 0xFE, 0x33, 0x60, 0x8A, 0x78, 0xFF, 0xFF, 0x3F, 0x40, 0x20, 0x2B, 0xAD, 0x00, 0x01, 0x16,
+	 0xFE, 0x01, 0x38, 0x69, 0xA1, 0xFF, 0xFF, 0xFF, 0x68, 0x44, 0x01, 0x2A, 0xA5, 0x00, 0x27, 0x60,
+	 0xB4, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xFF, 0xFF, 0x08, 0x28, 0xA2, 0xDB, 0x7F, 0xF1,
+	 0x80, 0x60, 0x00, 0x64, 0xB0, 0x9C, 0x01, 0x00, 0x7F, 0xF1, 0xDD, 0xFE, 0xAD, 0x4F, 0x00, 0x7F,
+	 0x01, 0xBC, 0xA0, 0x5D, 0x00, 0xEE, 0x43, 0x45, 0x20, 0x44, 0x20, 0xBC, 0x40, 0x40, 0x02, 0x60,
+	 0xEE, 0x64, 0xA3, 0xFB, 0xA4, 0xF9, 0x05, 0x64, 0xA5, 0xFB, 0xDF, 0xFE, 0x19, 0xFF, 0x83, 0x00,
+	 0x20, 0x44, 0x20, 0xBC, 0x40, 0x40, 0x43, 0x45, 0xA4, 0xD1, 0xDA, 0x83, 0xC3, 0x85, 0x80, 0xE1,
+	 0xDF, 0xFE, 0xBD, 0xD3, 0xFF, 0xFF, 0x60, 0x48, 0x60, 0x47, 0x80, 0xBC, 0x00, 0x7F, 0x60, 0x4A,
+	 0xD7, 0x80, 0xA1, 0xFF, 0xF6, 0x02, 0xBF, 0xFE, 0x6E, 0x00, 0x3F, 0x40, 0x40, 0x26, 0x13, 0x00,
+	 0x0B, 0x60, 0xF8, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x10, 0x64, 0x90, 0x84, 0xA0, 0x50, 0xF8, 0xA2,
+	 0xA2, 0xD1, 0x0A, 0x60, 0x19, 0x64, 0x90, 0x84, 0xA0, 0x52, 0x06, 0xA2, 0xA2, 0xD1, 0x46, 0x60,
+	 0x09, 0x64, 0x90, 0x84, 0xA0, 0x50, 0xAD, 0x4F, 0xFE, 0xB4, 0xA0, 0x5D, 0xAD, 0x4F, 0xFD, 0xB4,
+	 0xA0, 0x5D, 0x02, 0xEE, 0xBD, 0xFE, 0x50, 0x00, 0x80, 0xE1, 0x01, 0x16, 0xFE, 0x01, 0x64, 0x48,
+	 0x92, 0x6A, 0xA1, 0xFF, 0xFF, 0xFF, 0x68, 0x40, 0x27, 0x60, 0xA2, 0x64, 0xA0, 0xD3, 0xFF, 0xFF,
+	 0xDC, 0x84, 0xFF, 0xFF, 0x08, 0x28, 0xA2, 0xDB, 0x3F, 0x00, 0x80, 0xE1, 0x01, 0x16, 0xFE, 0x01,
+	 0x01, 0x68, 0xA7, 0x6A, 0xA1, 0xFF, 0xFF, 0xFF, 0x68, 0x40, 0x36, 0x00, 0x20, 0x44, 0x20, 0xBC,
+	 0x40, 0x40, 0x80, 0xE1, 0x64, 0x46, 0x01, 0x16, 0xFE, 0x01, 0x21, 0x69, 0xA1, 0xFF, 0xFF, 0xFF,
+	 0x68, 0x5E, 0x01, 0x16, 0xFE, 0x01, 0x22, 0x69, 0xA1, 0xFF, 0xFF, 0xFF, 0x68, 0x5F, 0x26, 0xFA,
+	 0x1C, 0xF2, 0x01, 0x16, 0xFE, 0x01, 0x3A, 0x69, 0xA1, 0xFF, 0xFF, 0xFF, 0x68, 0x5F, 0x27, 0xFA,
+	 0x1B, 0x00, 0x20, 0x44, 0x20, 0xBC, 0x40, 0x40, 0x43, 0x45, 0xBE, 0xD5, 0xA4, 0xD2, 0x5A, 0x86,
+	 0xEF, 0xA0, 0x11, 0x61, 0x01, 0x06, 0x60, 0x41, 0x24, 0x60, 0xE0, 0x63, 0x80, 0xE1, 0xBD, 0xD3,
+	 0x26, 0x42, 0x01, 0x16, 0xFE, 0x01, 0x60, 0x49, 0xA1, 0xFF, 0xFF, 0xFF, 0x68, 0x44, 0xCD, 0x81,
+	 0xA2, 0xDA, 0x5A, 0x86, 0xF4, 0x02, 0x25, 0x43, 0x21, 0xE1, 0x00, 0x64, 0xBF, 0xDB, 0x20, 0x44,
+	 0x20, 0x2A, 0x07, 0x00, 0x07, 0xB4, 0x04, 0x36, 0xC3, 0xFE, 0x06, 0x36, 0xCC, 0xFE, 0x07, 0x36,
+	 0xD5, 0xFE, 0x20, 0x44, 0xD8, 0xB4, 0x40, 0x40, 0x20, 0x44, 0x40, 0x2A, 0x07, 0x00, 0x9F, 0xFE,
+	 0x1E, 0x05, 0xBF, 0xB4, 0x40, 0x40, 0xA6, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0x24, 0x60, 0x80, 0x63,
+	 0xBD, 0xD3, 0x02, 0x61, 0x17, 0x1B, 0x04, 0xA3, 0xBD, 0xD3, 0x02, 0x61, 0x13, 0x1B, 0x04, 0xA3,
+	 0xBD, 0xD3, 0x02, 0x61, 0x0F, 0x1B, 0x04, 0xA3, 0xBD, 0xD3, 0x04, 0x61, 0x0B, 0x1B, 0x04, 0xA3,
+	 0xBD, 0xD3, 0x06, 0x61, 0x07, 0x1B, 0x04, 0xA3, 0xBD, 0xD3, 0x07, 0x61, 0x03, 0x1B, 0xBB, 0x60,
+	 0x20, 0x78, 0xFF, 0xFF, 0xA3, 0xD1, 0x40, 0x44, 0x20, 0x44, 0x07, 0xB5, 0xD4, 0x85, 0x35, 0x80,
+	 0x24, 0x45, 0x24, 0x60, 0xBC, 0x64, 0x44, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xE1, 0x43, 0x45,
+	 0x20, 0x44, 0x20, 0xBC, 0x40, 0x40, 0x64, 0x43, 0xBD, 0xD3, 0xBD, 0xD1, 0x40, 0x44, 0x10, 0x27,
+	 0x10, 0x00, 0xFF, 0x60, 0x7F, 0x65, 0x15, 0x60, 0xA2, 0x64, 0x24, 0x40, 0x08, 0x2B, 0xA4, 0x84,
+	 0xA0, 0x57, 0xFF, 0xFF, 0x64, 0x49, 0xFF, 0xFF, 0x68, 0x44, 0x01, 0x16, 0xFD, 0x01, 0x00, 0x7F,
+	 0xA3, 0xDB, 0xA1, 0x01, 0x80, 0xE1, 0x43, 0x45, 0x20, 0x44, 0x20, 0xBC, 0x40, 0x40, 0x64, 0x43,
+	 0xBD, 0xD3, 0xBD, 0xD1, 0x40, 0x44, 0x10, 0x2B, 0x11, 0x00, 0xA3, 0xD3, 0xFF, 0xFF, 0x15, 0x60,
+	 0x80, 0xE7, 0x24, 0x40, 0x07, 0x27, 0x02, 0x00, 0x50, 0xEC, 0x00, 0x00, 0x60, 0x4A, 0xFF, 0xFF,
+	 0x01, 0x16, 0xFE, 0x01, 0x24, 0x40, 0x20, 0x2B, 0x40, 0xEC, 0x0F, 0x00, 0x15, 0x60, 0x22, 0x64,
+	 0x24, 0x40, 0x08, 0x27, 0x80, 0xBC, 0xA3, 0xD3, 0xA0, 0x57, 0x60, 0x48, 0x64, 0x44, 0x80, 0xBC,
+	 0xFF, 0xB4, 0x60, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x75, 0x01, 0x42, 0x6F, 0x6F, 0x74,
+	 0x63, 0x6F, 0x64, 0x65, 0x20, 0x21, 0x21, 0x20, 0x20, 0x00, 0x53, 0x54, 0x41, 0x2F, 0x41, 0x50,
+	 0x20, 0x46, 0x75, 0x6E, 0x63, 0x27, 0x73, 0x00, 0x1F, 0x00, 0x03, 0x00, 0x02, 0x00, 0x24, 0x00,
+	 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, 0x00, 0x04, 0x00,
+	 0x06, 0x00, 0x07, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x06, 0x00, 0x06, 0x00, 0x07, 0x00,
+	 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00,
+	 0x02, 0x00, 0x40, 0x00, 0x32, 0x00, 0x32, 0x00, 0x0A, 0x00, 0x02, 0x00, 0x06, 0x00, 0x40, 0x00,
+	 0x32, 0x00, 0x36, 0x00, 0x0A, 0x00, 0x02, 0x00, 0x06, 0x00, 0x40, 0x00, 0x3B, 0x00, 0x40, 0x00,
+	 0x17, 0x00, 0x07, 0x00, 0x07, 0x00, 0x4A, 0x00, 0x40, 0x00, 0x4A, 0x00, 0x1E, 0x00, 0x0C, 0x00,
+	 0x08, 0x00, 0x57, 0x00, 0x4D, 0x00, 0x57, 0x00, 0x2B, 0x00, 0x19, 0x00, 0x08, 0x00, 0x5D, 0x00,
+	 0x53, 0x00, 0x5D, 0x00, 0x31, 0x00, 0x1F, 0x00, 0x08, 0x00, 0xA9, 0xF3, 0x21, 0x61, 0x00, 0x7C,
+	 0x01, 0x00, 0x00, 0xFA, 0x60, 0x46, 0xFE, 0x63, 0xA3, 0xD8, 0xFE, 0x1F, 0xCD, 0x81, 0xD8, 0x84,
+	 0xF8, 0x02, 0x21, 0x61, 0x80, 0x67, 0x40, 0x4A, 0xA9, 0xF5, 0x14, 0x60, 0x02, 0x65, 0x01, 0x7C,
+	 0x07, 0x18, 0x2A, 0x43, 0x02, 0xFC, 0x5F, 0x8A, 0x8E, 0xF8, 0x70, 0xF8, 0x00, 0xF4, 0xF8, 0x01,
+	 0x2E, 0x58, 0xFF, 0xFF, 0x3F, 0x40, 0x40, 0x26, 0x0A, 0x00, 0x42, 0x60, 0x09, 0xE0, 0x3F, 0x40,
+	 0x01, 0x2A, 0x03, 0x00, 0x60, 0x60, 0x1C, 0xE0, 0x02, 0x00, 0x80, 0x60, 0x1C, 0xE0, 0x40, 0xEC,
+	 0x00, 0xED, 0x02, 0xEE, 0x80, 0x60, 0x58, 0xEC, 0x80, 0x60, 0x00, 0xED, 0x80, 0x60, 0x82, 0xEE,
+	 0xC0, 0x60, 0x59, 0xEC, 0xC0, 0x60, 0x07, 0xED, 0xAD, 0x4F, 0xFE, 0xB4, 0xA0, 0x5D, 0x00, 0xF3,
+	 0x28, 0xFB, 0x40, 0x44, 0x2F, 0x60, 0x52, 0x7C, 0x20, 0xF9, 0xA2, 0x60, 0x00, 0x7C, 0x21, 0xF9,
+	 0xA2, 0x60, 0xE0, 0x7C, 0x22, 0xF9, 0x18, 0x60, 0x97, 0x7C, 0x23, 0xF9, 0x18, 0x60, 0xA8, 0x7C,
+	 0x24, 0xF9, 0x18, 0x60, 0xD2, 0x7C, 0x25, 0xF9, 0x18, 0x60, 0xE3, 0x7C, 0x26, 0xF9, 0x91, 0x60,
+	 0x00, 0xE8, 0x28, 0xE8, 0x44, 0x60, 0x02, 0xE6, 0x10, 0x67, 0x40, 0x52, 0x10, 0x60, 0x04, 0xE6,
+	 0x08, 0x60, 0x00, 0x63, 0xFA, 0x60, 0x00, 0x65, 0xBD, 0xD3, 0xBD, 0xD3, 0x02, 0xA8, 0xD4, 0x80,
+	 0x4A, 0x02, 0x49, 0x02, 0xDB, 0x83, 0xFA, 0x60, 0x27, 0x65, 0x5B, 0xD3, 0xBF, 0xD1, 0x1A, 0x18,
+	 0xC3, 0x83, 0xD4, 0x80, 0xC3, 0x83, 0xF9, 0x02, 0xDB, 0x83, 0xD3, 0x83, 0xD3, 0x86, 0x64, 0x41,
+	 0xCD, 0x81, 0xA6, 0xD1, 0xDA, 0x86, 0x25, 0x60, 0x02, 0x65, 0x00, 0x60, 0x72, 0x63, 0xA5, 0xD3,
+	 0xDA, 0x85, 0x90, 0x84, 0xFF, 0x27, 0x02, 0x00, 0xA2, 0xD9, 0x01, 0x00, 0xF8, 0x1F, 0xCD, 0x81,
+	 0xFF, 0xFF, 0xEF, 0x02, 0x08, 0x60, 0x06, 0x63, 0xFA, 0x60, 0x28, 0x65, 0x5B, 0xD3, 0xBF, 0xD1,
+	 0x0B, 0x18, 0xC3, 0x83, 0xD4, 0x80, 0xC3, 0x83, 0xF9, 0x02, 0xBF, 0xD3, 0x29, 0x60, 0xE8, 0x62,
+	 0x0E, 0xB4, 0xE0, 0x84, 0xE0, 0x84, 0xA2, 0xDB, 0x08, 0x60, 0x06, 0x63, 0xFD, 0x60, 0x0C, 0x65,
+	 0x5B, 0xD3, 0xBF, 0xD1, 0x10, 0x18, 0xC3, 0x83, 0xD4, 0x80, 0xC3, 0x83, 0xF9, 0x02, 0xFA, 0xA3,
+	 0xA3, 0xD3, 0x02, 0x60, 0x00, 0x65, 0xF7, 0xA0, 0xFC, 0xA0, 0x0D, 0x05, 0x04, 0x05, 0x78, 0x43,
+	 0x02, 0x61, 0x24, 0x60, 0xDD, 0x78, 0x21, 0x60, 0x00, 0x65, 0x3F, 0x43, 0x3F, 0x43, 0x21, 0x60,
+	 0x00, 0x65, 0xC0, 0x60, 0x8F, 0xEE, 0xB7, 0x84, 0x40, 0x5F, 0x00, 0x60, 0x30, 0xE2, 0x00, 0x60,
+	 0x50, 0xE2, 0x00, 0x60, 0x79, 0xE2, 0x00, 0x60, 0x90, 0xE2, 0x01, 0x60, 0xD0, 0xE2, 0x01, 0x60,
+	 0xF0, 0xE2, 0x01, 0x60, 0xB0, 0xE2, 0x26, 0x64, 0x35, 0xFB, 0x01, 0x60, 0x30, 0x64, 0x0A, 0xA4,
+	 0x38, 0xFB, 0x60, 0x45, 0x00, 0x60, 0xF8, 0x64, 0x0A, 0xA4, 0x39, 0xFB, 0x35, 0xF1, 0x0A, 0x64,
+	 0xC4, 0x84, 0x36, 0xFB, 0xC0, 0x84, 0x0A, 0xA4, 0x37, 0xFB, 0x09, 0x60, 0x2A, 0x64, 0xB9, 0xFB,
+	 0x82, 0xFF, 0x92, 0xFF, 0x5C, 0x41, 0x5C, 0x46, 0x5C, 0x47, 0x00, 0xE1, 0xA3, 0x60, 0x4B, 0x63,
+	 0x0C, 0x60, 0x16, 0x64, 0xA0, 0xDD, 0x87, 0xFF, 0x97, 0xFF, 0x0C, 0x60, 0x02, 0x64, 0x40, 0x5A,
+	 0x06, 0xA4, 0x40, 0x5B, 0x5C, 0x5E, 0x5C, 0x51, 0x28, 0x60, 0x44, 0x62, 0xA2, 0xD3, 0x7F, 0xFB,
+	 0x2D, 0x60, 0xCC, 0x61, 0x27, 0x7C, 0xA1, 0xD9, 0x6D, 0x60, 0x1C, 0x63, 0x7F, 0xA3, 0xE3, 0x87,
+	 0x00, 0x7F, 0xAA, 0xFB, 0x02, 0x60, 0x7F, 0x64, 0x00, 0x60, 0x42, 0x65, 0xD4, 0x84, 0xAB, 0xFB,
+	 0xDC, 0x84, 0xA9, 0xFB, 0x24, 0x60, 0x0E, 0x62, 0xA2, 0xDB, 0x34, 0x60, 0x58, 0x4E, 0x64, 0x78,
+	 0xFF, 0xFF, 0xAB, 0xF1, 0xAA, 0xF3, 0x7C, 0x63, 0xAD, 0xFB, 0x60, 0x46, 0x01, 0xFC, 0xDC, 0x84,
+	 0xD0, 0x80, 0x00, 0xFA, 0xFA, 0x04, 0xAE, 0xFB, 0x60, 0x46, 0x00, 0x64, 0x00, 0xFA, 0x63, 0x44,
+	 0x80, 0x7F, 0x01, 0xFA, 0xAB, 0xF3, 0xAA, 0xF1, 0xDC, 0x84, 0xD0, 0x84, 0xAC, 0xFB, 0x03, 0x60,
+	 0x26, 0x61, 0xAE, 0x60, 0x58, 0x4D, 0xB1, 0x78, 0xFF, 0xFF, 0x66, 0x44, 0x2E, 0xFB, 0x82, 0xFF,
+	 0x40, 0x42, 0x87, 0xFF, 0xAC, 0xF3, 0xB4, 0xFB, 0x08, 0x60, 0x00, 0x63, 0xFA, 0x60, 0x00, 0x65,
+	 0xBD, 0xD3, 0xA3, 0xD3, 0x02, 0xA8, 0xD4, 0x80, 0x24, 0x02, 0x23, 0x02, 0x2D, 0x60, 0x1A, 0x62,
+	 0xA2, 0xD1, 0xFF, 0xFF, 0x64, 0x40, 0x80, 0x26, 0x1C, 0x00, 0x04, 0xA3, 0xFD, 0x60, 0x0D, 0x65,
+	 0x5B, 0xD3, 0xBF, 0xD1, 0x16, 0x18, 0xC3, 0x83, 0xD4, 0x80, 0xC3, 0x83, 0xF9, 0x02, 0xBF, 0xD3,
+	 0xAD, 0x49, 0xFE, 0xA0, 0x00, 0x64, 0x0E, 0x04, 0x08, 0xB1, 0x20, 0xBC, 0x08, 0x28, 0x18, 0xBC,
+	 0x1C, 0x60, 0xB8, 0x63, 0x07, 0x7C, 0xA3, 0xD9, 0x1C, 0x60, 0xB6, 0x63, 0x05, 0x7C, 0xA3, 0xD9,
+	 0x01, 0x00, 0x00, 0x64, 0x1C, 0x60, 0xB4, 0x63, 0xA3, 0xDB, 0x00, 0x64, 0x40, 0x50, 0x63, 0xFF,
+	 0x60, 0xFF, 0x66, 0xFF, 0x65, 0xFF, 0x64, 0xFF, 0x61, 0xFF, 0x62, 0xFF, 0x49, 0x60, 0x02, 0xE1,
+	 0x52, 0x60, 0x02, 0xE1, 0x5B, 0x60, 0x02, 0xE1, 0x65, 0x60, 0x02, 0xE1, 0x6C, 0x60, 0x02, 0xE1,
+	 0x76, 0x60, 0x02, 0xE1, 0x41, 0x60, 0x02, 0xE1, 0x04, 0x65, 0x2D, 0x60, 0x18, 0x64, 0x44, 0xD3,
+	 0xEF, 0x60, 0x58, 0x4E, 0xBD, 0x78, 0xFF, 0xFF, 0x24, 0x60, 0x9E, 0x65, 0x0C, 0x64, 0xA5, 0xDB,
+	 0x36, 0x60, 0x1E, 0x64, 0xA1, 0xFB, 0x2D, 0xFF, 0x06, 0x61, 0x41, 0x4B, 0x09, 0x60, 0x08, 0x61,
+	 0xAE, 0x60, 0x58, 0x4D, 0xB1, 0x78, 0xFF, 0xFF, 0xF0, 0x67, 0x0E, 0xFA, 0x24, 0x60, 0x7A, 0x62,
+	 0x24, 0x60, 0x5E, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0x2B, 0x41, 0x4D, 0x8B, 0xFF, 0xFF, 0xE9, 0x02, 0x06, 0x61, 0x41, 0x4B, 0x09, 0x60,
+	 0x08, 0x61, 0xAE, 0x60, 0x58, 0x4D, 0xB1, 0x78, 0xFF, 0xFF, 0x24, 0x60, 0x7A, 0x62, 0x24, 0x60,
+	 0x52, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0x2B, 0x41, 0x4D, 0x8B, 0xFF, 0xFF, 0xEB, 0x02, 0x19, 0x60, 0x17, 0x78, 0xFF, 0xFF, 0x00, 0xEA,
+	 0x00, 0xEB, 0x50, 0x60, 0x03, 0xEA, 0x51, 0x60, 0x13, 0xEA, 0x52, 0x60, 0x30, 0xEA, 0x53, 0x60,
+	 0x40, 0xEA, 0x54, 0x60, 0x52, 0xEA, 0x55, 0x60, 0x6D, 0xEA, 0x56, 0x60, 0x71, 0xEA, 0x57, 0x60,
+	 0x8B, 0xEA, 0x58, 0x60, 0x47, 0xEA, 0x59, 0x60, 0xA0, 0xEA, 0x5A, 0x60, 0xB2, 0xEA, 0x5B, 0x60,
+	 0xC1, 0xEA, 0x5C, 0x60, 0xD7, 0xEA, 0x5D, 0x60, 0xEB, 0xEA, 0x5E, 0x60, 0xA0, 0xEA, 0x50, 0x60,
+	 0x36, 0xEB, 0x51, 0x60, 0x37, 0xEB, 0x52, 0x60, 0x20, 0xEB, 0x53, 0x60, 0xE4, 0xEB, 0x54, 0x60,
+	 0x34, 0xEB, 0x55, 0x60, 0x58, 0xEB, 0x56, 0x60, 0x48, 0xEB, 0x57, 0x60, 0xD0, 0xEB, 0x58, 0x60,
+	 0xC3, 0xEB, 0x59, 0x60, 0xFC, 0xEB, 0x5A, 0x60, 0x34, 0xEB, 0x5B, 0x60, 0x58, 0xEB, 0x5C, 0x60,
+	 0xC0, 0xEB, 0x5D, 0x60, 0xD0, 0xEB, 0x5E, 0x60, 0x91, 0xEB, 0x00, 0xEA, 0x00, 0xEB, 0xE0, 0x60,
+	 0x02, 0xEA, 0xE0, 0x60, 0x03, 0xEB, 0xA0, 0x60, 0x00, 0xEB, 0xB0, 0x60, 0x00, 0xEB, 0xAB, 0x48,
+	 0x40, 0x3B, 0x01, 0x00, 0xFC, 0x01, 0x00, 0xEB, 0x03, 0x60, 0x02, 0x62, 0x62, 0x44, 0xA2, 0xDB,
+	 0x0F, 0x64, 0x60, 0x7F, 0xA0, 0x5A, 0x80, 0x60, 0x00, 0xEA, 0xA0, 0x60, 0x00, 0xEA, 0xD1, 0x60,
+	 0x00, 0xEA, 0x3F, 0x40, 0x40, 0x26, 0x08, 0x00, 0x00, 0x60, 0x18, 0x64, 0x00, 0x60, 0x00, 0x65,
+	 0x94, 0x84, 0xA0, 0x50, 0x1D, 0x60, 0x19, 0xE2, 0x24, 0x44, 0xFF, 0xB4, 0x04, 0xFB, 0x50, 0x60,
+	 0x00, 0x64, 0x05, 0xFB, 0x10, 0x60, 0x10, 0x75, 0x25, 0x60, 0x11, 0x78, 0xFF, 0xFF, 0x3F, 0x41,
+	 0xA5, 0x4C, 0x50, 0x37, 0x04, 0x00, 0x01, 0xB9, 0x41, 0x5F, 0xB5, 0x60, 0x55, 0xE0, 0x0C, 0x60,
+	 0x10, 0x62, 0xA2, 0xD3, 0x01, 0x60, 0x01, 0x65, 0xD4, 0x80, 0x5A, 0xD1, 0x0F, 0x02, 0x5A, 0xD3,
+	 0x3C, 0x60, 0x00, 0x66, 0xE0, 0x87, 0x40, 0x4A, 0x68, 0x60, 0x28, 0x61, 0x64, 0x44, 0xC8, 0x84,
+	 0x0C, 0x63, 0xAA, 0x46, 0x58, 0xD0, 0xAA, 0x46, 0x59, 0xD8, 0xFB, 0x1F, 0x08, 0x60, 0x00, 0x63,
+	 0xFA, 0x60, 0x00, 0x65, 0xBD, 0xD3, 0xA3, 0xD3, 0x02, 0xA8, 0xD4, 0x80, 0x61, 0x02, 0x60, 0x02,
+	 0x6E, 0x60, 0x58, 0x61, 0x3C, 0x60, 0x00, 0x66, 0x41, 0x4B, 0x2B, 0x41, 0x6E, 0x60, 0xA0, 0x7C,
+	 0xD1, 0x80, 0xA1, 0xD2, 0x25, 0x05, 0x59, 0xD0, 0x60, 0x45, 0x59, 0xD2, 0x44, 0x47, 0xE0, 0x87,
+	 0x40, 0x4A, 0x59, 0xD2, 0x59, 0x8B, 0x40, 0x4C, 0x08, 0x60, 0x00, 0x63, 0xBE, 0xD3, 0xBD, 0xD1,
+	 0xEC, 0x18, 0xD4, 0x80, 0xEA, 0x18, 0x03, 0x03, 0xC3, 0x83, 0xC3, 0x83, 0xF7, 0x01, 0x67, 0x44,
+	 0xC0, 0x84, 0xE0, 0x85, 0x2C, 0x44, 0xD4, 0x80, 0x63, 0x41, 0x01, 0x06, 0x65, 0x44, 0xC8, 0x83,
+	 0xAA, 0x46, 0x59, 0xD1, 0x27, 0xD8, 0x5A, 0x87, 0xFC, 0x1F, 0xAA, 0x46, 0x2B, 0x41, 0xD5, 0x01,
+	 0x6E, 0x60, 0xA0, 0x61, 0x41, 0x4B, 0x2B, 0x41, 0x6E, 0x60, 0xD8, 0x7C, 0xD1, 0x80, 0xA1, 0xD2,
+	 0x27, 0x05, 0x59, 0xD0, 0x60, 0x45, 0x59, 0xD2, 0x44, 0x47, 0xE0, 0x87, 0x40, 0x4A, 0x59, 0xD2,
+	 0x59, 0x8B, 0x40, 0x4C, 0x08, 0x60, 0x00, 0x63, 0xBE, 0xD3, 0xBD, 0xD1, 0xEC, 0x18, 0xD4, 0x80,
+	 0xEA, 0x18, 0x03, 0x03, 0xC3, 0x83, 0xC3, 0x83, 0xF7, 0x01, 0x04, 0xA3, 0xA3, 0xD1, 0x5A, 0x88,
+	 0x2C, 0x43, 0xD3, 0x80, 0xFF, 0xFF, 0x01, 0x06, 0x64, 0x43, 0xCF, 0x83, 0xAA, 0x46, 0x60, 0xFE,
+	 0x28, 0xD1, 0x5E, 0x88, 0x27, 0xD8, 0x5A, 0x87, 0xFB, 0x1F, 0x20, 0xFE, 0xAA, 0x46, 0xD3, 0x01,
+	 0xB8, 0xFE, 0xB9, 0xFE, 0xBA, 0xFE, 0xBB, 0xFE, 0xBD, 0xFE, 0xBF, 0xFE, 0x2D, 0x60, 0x1A, 0x62,
+	 0xA2, 0xD3, 0x12, 0x63, 0x60, 0x40, 0x01, 0x27, 0x05, 0x00, 0x0B, 0x60, 0xEA, 0x62, 0x00, 0x64,
+	 0x5A, 0xDB, 0xFE, 0x1F, 0x34, 0x60, 0x81, 0x78, 0xFF, 0xFF, 0xF1, 0xFF, 0xF6, 0x6C, 0x1E, 0x00,
+	 0x04, 0x00, 0xF2, 0xFF, 0xFA, 0x6C, 0x1E, 0x00, 0x04, 0x00, 0xFB, 0xFF, 0x02, 0x6D, 0x1E, 0x00,
+	 0x04, 0x00, 0xF1, 0xFF, 0x8C, 0x64, 0x1E, 0x00, 0x04, 0x00, 0xF2, 0xFF, 0x90, 0x64, 0x1E, 0x00,
+	 0x04, 0x00, 0xFB, 0xFF, 0x98, 0x64, 0x1E, 0x00, 0x04, 0x00, 0x86, 0xFD, 0x50, 0x28, 0x00, 0x00,
+	 0x06, 0x00, 0x10, 0xFD, 0x74, 0x01, 0x00, 0x00, 0x02, 0x00, 0x14, 0xFD, 0x18, 0x2D, 0x00, 0x00,
+	 0x0A, 0x00, 0x20, 0xFA, 0x94, 0x26, 0x00, 0x00, 0x0E, 0x00, 0x21, 0xFA, 0x78, 0x26, 0x00, 0x00,
+	 0x0E, 0x00, 0x22, 0xFA, 0xB0, 0x26, 0x00, 0x00, 0x0E, 0x00, 0x23, 0xFA, 0x64, 0x25, 0x00, 0x00,
+	 0x01, 0x00, 0x24, 0xFA, 0x58, 0x27, 0x00, 0x00, 0x0E, 0x00, 0x25, 0xFA, 0x78, 0x25, 0x00, 0x00,
+	 0x80, 0x00, 0x26, 0xFA, 0x5E, 0x25, 0x00, 0x00, 0x01, 0x00,
+
+};  /* fw_image_3_data */
+
+static const hcf_8 fw_image_4_data[] = {
+	 0xA2, 0x60, 0xDD, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA2, 0x60, 0xC3, 0x78, 0x41, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA2, 0x60, 0xC9, 0x78, 0xC4, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA2, 0x60, 0x19, 0x78, 0x43, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x44, 0xFF, 0x20, 0x54, 0xCD, 0xE2, 0xA2, 0x60, 0xDB, 0x78, 0x08, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA2, 0x60, 0xDD, 0x78, 0x44, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA2, 0x60, 0xDD, 0x78, 0x46, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA2, 0x60, 0xDD, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA8, 0x60, 0x73, 0x78, 0x4C, 0x4E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA7, 0x60, 0xFB, 0x78, 0x4C, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xC4, 0xE2, 0x84, 0xFF, 0x22, 0x58, 0x82, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA3, 0x60, 0x7E, 0x78, 0x43, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xE4, 0xE2, 0xA8, 0x60, 0x14, 0x78, 0xB5, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xBA, 0x60, 0xCE, 0x78, 0x64, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA8, 0x60, 0x87, 0x78, 0xA4, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA8, 0x60, 0x55, 0x78, 0x47, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xAE, 0x60, 0x1E, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xAE, 0x60, 0x4B, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xAC, 0x60, 0xD8, 0x78, 0x42, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xAD, 0x60, 0x08, 0x78, 0x43, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xAD, 0x60, 0x08, 0x78, 0x44, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xAF, 0x60, 0xC0, 0x78, 0x45, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xAD, 0x60, 0x0B, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x00, 0x60, 0x83, 0x64, 0x80, 0x29, 0x09, 0xFB, 0xAD, 0x60, 0xE6, 0x78, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x31, 0x60, 0x16, 0x78, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x30, 0x60, 0xA1, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB9, 0x60, 0x4B, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB8, 0x60, 0xBB, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB0, 0x60, 0x89, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA1, 0xFF, 0xFF, 0xFF, 0x83, 0x3E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xBB, 0x60, 0x25, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0x41, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0x42, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0xB0, 0xFF, 0xB1, 0xFF, 0x40, 0xFF, 0x43, 0xFF, 0xBB, 0x60, 0x20, 0x78, 0x44, 0xFF, 0xFF, 0x01,
+	 0xBB, 0x60, 0x25, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0x33, 0x60, 0x9B, 0x78, 0x45, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0xBB, 0x60, 0x20, 0x78, 0x84, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0xBB, 0x60, 0x1F, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0xBF, 0x60, 0xDB, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xEB, 0x60, 0x1F, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xBF, 0x60, 0xE3, 0x78, 0x42, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xBF, 0x60, 0xE3, 0x78, 0x24, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xE9, 0x60, 0xE3, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xBF, 0x60, 0xE3, 0x78, 0x44, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xBF, 0x60, 0xE3, 0x78, 0x84, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xBF, 0x60, 0xE3, 0x78, 0x47, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x24, 0x60, 0xE5, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x25, 0x60, 0x14, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x25, 0x60, 0x32, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x25, 0x60, 0x11, 0x78, 0x28, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x25, 0x60, 0x11, 0x78, 0x44, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x25, 0x60, 0x11, 0x78, 0x45, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x25, 0x60, 0x11, 0x78, 0x46, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x00, 0x60, 0x87, 0x64, 0x80, 0x29, 0x09, 0xFB, 0x47, 0xFF, 0x25, 0x60, 0x11, 0x78, 0xFF, 0xFF,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x2F, 0x60, 0x63, 0x78, 0x42, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x2F, 0x60, 0xB3, 0x78, 0x47, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x30, 0x44, 0x02, 0xA8, 0x00, 0xE1, 0x07, 0x02, 0x62, 0xFF, 0x63, 0xFF, 0x64, 0xFF, 0x65, 0xFF,
+	 0x66, 0xFF, 0xBF, 0xFE, 0xA1, 0xFF, 0x82, 0xFF, 0x88, 0xFF, 0x6C, 0x40, 0x41, 0xFF, 0xC4, 0xE2,
+	 0x43, 0xFF, 0x5C, 0x49, 0x08, 0xE1, 0xA2, 0x60, 0x16, 0x78, 0xFF, 0xFF, 0xA1, 0xFF, 0x98, 0xFF,
+	 0x80, 0x3E, 0x9F, 0xFE, 0x03, 0x04, 0x31, 0x60, 0x75, 0x78, 0xFF, 0xFF, 0xE2, 0xFE, 0x40, 0x05,
+	 0xE0, 0xFE, 0x5B, 0x05, 0xE1, 0xFE, 0xF2, 0x04, 0x29, 0x40, 0x08, 0x26, 0xEF, 0x01, 0x72, 0x44,
+	 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xB5, 0xF3, 0xE8, 0x85, 0xFF, 0xB7,
+	 0xE0, 0x84, 0xE0, 0x84, 0xB4, 0x85, 0x73, 0x44, 0xD4, 0x84, 0x10, 0x65, 0xD4, 0x80, 0xFF, 0xFF,
+	 0x26, 0x04, 0x3F, 0x40, 0x40, 0x26, 0x13, 0x00, 0x0B, 0x60, 0xF8, 0x62, 0xA2, 0xD1, 0x00, 0x60,
+	 0x10, 0x64, 0x90, 0x84, 0xA0, 0x50, 0xF8, 0xA2, 0xA2, 0xD1, 0x0A, 0x60, 0x19, 0x64, 0x90, 0x84,
+	 0xA0, 0x52, 0x06, 0xA2, 0xA2, 0xD1, 0x46, 0x60, 0x09, 0x64, 0x90, 0x84, 0xA0, 0x50, 0xF2, 0xF4,
+	 0x31, 0x60, 0x18, 0x7C, 0x63, 0x40, 0x01, 0x26, 0x08, 0x00, 0xA4, 0xD3, 0xFF, 0xFF, 0x01, 0xB4,
+	 0xFF, 0xFF, 0x03, 0x02, 0xAD, 0x4F, 0xFE, 0xB4, 0xA0, 0x5D, 0x02, 0xEE, 0xBD, 0xFE, 0xBE, 0x01,
+	 0x21, 0x46, 0x5E, 0x62, 0x9A, 0xFF, 0x07, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x06, 0x25, 0x10, 0x00,
+	 0xA2, 0xDC, 0x7A, 0xDC, 0x7A, 0xDC, 0x62, 0x62, 0x01, 0x5D, 0x7A, 0xDC, 0x7A, 0xDC, 0x7A, 0xDC,
+	 0x7A, 0xDC, 0x44, 0xFF, 0x06, 0x25, 0x04, 0x00, 0x0E, 0xE1, 0x02, 0x60, 0x01, 0xE1, 0x9E, 0x01,
+	 0x62, 0xFF, 0xC4, 0xE2, 0x41, 0xFF, 0x0A, 0xE1, 0x99, 0x01, 0xC8, 0x74, 0xCD, 0xE2, 0x29, 0x44,
+	 0x08, 0xBC, 0x40, 0x49, 0x05, 0xE1, 0x31, 0x60, 0x1A, 0x63, 0xA3, 0xD3, 0xF2, 0xF3, 0x06, 0x18,
+	 0x28, 0x40, 0x08, 0x2A, 0x05, 0x00, 0x28, 0x40, 0x48, 0x36, 0x02, 0x00, 0x02, 0xBC, 0xF2, 0xFB,
+	 0x3F, 0x40, 0x01, 0x2B, 0xFF, 0xFF, 0xA1, 0xFF, 0x67, 0x4C, 0x06, 0x61, 0xCD, 0x81, 0x04, 0x25,
+	 0x30, 0x00, 0x87, 0x4C, 0xFB, 0x02, 0x28, 0x40, 0x40, 0x2B, 0x02, 0x00, 0x15, 0x60, 0x6F, 0x6B,
+	 0xF3, 0x60, 0xA0, 0x64, 0x04, 0x25, 0x25, 0x00, 0x80, 0x4C, 0x30, 0x64, 0x3A, 0xDB, 0x44, 0xFF,
+	 0x04, 0x25, 0x1F, 0x00, 0x04, 0x60, 0x00, 0x65, 0x25, 0x44, 0x37, 0x36, 0xB4, 0x84, 0x6E, 0x36,
+	 0xB4, 0x84, 0x80, 0x4E, 0x24, 0x41, 0x04, 0x25, 0x14, 0x00, 0x61, 0x4C, 0x64, 0xA1, 0x61, 0x54,
+	 0xA1, 0xFF, 0xFF, 0xFF, 0x04, 0x25, 0x0D, 0x00, 0x67, 0x4E, 0x07, 0x64, 0x1C, 0xFB, 0x00, 0xE1,
+	 0x02, 0x60, 0x01, 0xE1, 0x53, 0x01, 0x33, 0xF3, 0xFD, 0x11, 0xFC, 0x18, 0x40, 0x64, 0x3A, 0xDB,
+	 0x0A, 0x00, 0xC4, 0xE2, 0x27, 0x44, 0x20, 0x2A, 0x04, 0x00, 0x42, 0x64, 0x3A, 0xDB, 0x67, 0x4C,
+	 0x02, 0x00, 0x41, 0x64, 0x3A, 0xDB, 0x62, 0xFF, 0x08, 0xE1, 0xE2, 0xFE, 0x72, 0x52, 0x5C, 0x49,
+	 0x32, 0x7B, 0x4D, 0xE2, 0x3B, 0x01, 0x08, 0xE1, 0x39, 0x01, 0xA1, 0xFF, 0x98, 0xFF, 0x80, 0x3E,
+	 0x30, 0x44, 0x02, 0xA8, 0x00, 0xE1, 0x02, 0x02, 0xA1, 0xFF, 0xFF, 0xFF, 0x82, 0xFF, 0x88, 0xFF,
+	 0x48, 0xE2, 0x01, 0x70, 0xCE, 0xF1, 0x00, 0x6B, 0x89, 0xFF, 0x64, 0x54, 0x88, 0xFF, 0x9F, 0xFE,
+	 0x02, 0x05, 0x64, 0x44, 0x60, 0x54, 0xCD, 0xE2, 0xC2, 0x64, 0x3A, 0xDB, 0xBC, 0xFF, 0xB5, 0xFF,
+	 0x1D, 0xFF, 0x26, 0x44, 0x02, 0xB4, 0x40, 0x46, 0x3C, 0x44, 0x00, 0xBC, 0xFF, 0xFF, 0x06, 0x03,
+	 0x27, 0x40, 0x26, 0x22, 0x03, 0x00, 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0x27, 0x44, 0x20, 0x2A,
+	 0x04, 0x00, 0xA0, 0x60, 0x00, 0xEA, 0xB0, 0x60, 0x00, 0xEA, 0x5C, 0x4D, 0x27, 0x44, 0x18, 0xB4,
+	 0x40, 0x47, 0x00, 0xE1, 0x6C, 0x40, 0x44, 0xE2, 0xC4, 0xE2, 0x47, 0xFF, 0xB7, 0xFF, 0xB4, 0xFF,
+	 0x32, 0xF1, 0x08, 0x29, 0x09, 0x00, 0x64, 0x40, 0x07, 0x22, 0x06, 0x00, 0x43, 0xFF, 0x27, 0x44,
+	 0x10, 0xBC, 0x40, 0x47, 0x00, 0x64, 0x32, 0xFB, 0x31, 0x41, 0x3C, 0x44, 0x01, 0xB1, 0x00, 0xBC,
+	 0x0A, 0x02, 0x09, 0x03, 0x32, 0xF3, 0x00, 0x7C, 0x01, 0xB4, 0xFF, 0xFF, 0x04, 0x03, 0x32, 0xF9,
+	 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0x48, 0x60, 0x2D, 0x7D, 0x08, 0x60, 0x00, 0x6B, 0x00, 0x64,
+	 0x33, 0xFB, 0x0C, 0x60, 0x16, 0x64, 0xA0, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0x32, 0xF3, 0x08, 0x29,
+	 0x0A, 0x00, 0x60, 0x40, 0x07, 0x22, 0x07, 0x00, 0xFE, 0xB4, 0x32, 0xFB, 0x27, 0x44, 0x10, 0xBC,
+	 0xF7, 0xB4, 0x40, 0x47, 0x43, 0xFF, 0x00, 0x64, 0x3A, 0xDB, 0x01, 0x60, 0x08, 0xE1, 0x31, 0x40,
+	 0x01, 0x2A, 0x04, 0x00, 0x00, 0x64, 0x33, 0xFB, 0x01, 0x60, 0x0A, 0xE1, 0xE5, 0xFE, 0x1D, 0x05,
+	 0x27, 0x44, 0x10, 0x26, 0x1D, 0x00, 0x9F, 0xFE, 0x02, 0x04, 0x02, 0xE1, 0x10, 0x00, 0x3E, 0xE1,
+	 0x31, 0x44, 0x01, 0x2A, 0x0C, 0x00, 0x0E, 0x0A, 0x28, 0x44, 0x04, 0x27, 0x07, 0x00, 0xD4, 0x36,
+	 0x05, 0x00, 0xC4, 0x36, 0x03, 0x00, 0xAE, 0x4F, 0xF7, 0xB4, 0xA0, 0x5E, 0xBF, 0xE1, 0xA1, 0xFF,
+	 0xFF, 0xFF, 0x81, 0x3E, 0xAB, 0x60, 0x2C, 0x78, 0xFF, 0xFF, 0xA3, 0x60, 0xEC, 0x78, 0xFF, 0xFF,
+	 0x27, 0x44, 0x08, 0x26, 0xFF, 0xFF, 0xBA, 0x60, 0x70, 0x78, 0xFF, 0xFF, 0x48, 0xF3, 0x32, 0xF1,
+	 0x00, 0x63, 0x64, 0x40, 0x03, 0x22, 0x66, 0x00, 0x31, 0x40, 0x08, 0x26, 0xF4, 0x01, 0xCD, 0xE2,
+	 0x84, 0xE1, 0x70, 0x41, 0xAD, 0x80, 0x71, 0x40, 0x80, 0x27, 0xED, 0x12, 0x03, 0x03, 0xBA, 0x60,
+	 0xE7, 0x78, 0xFF, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0xC4, 0xE2, 0x32, 0xFD, 0x60, 0x40, 0x01, 0x2A,
+	 0xDF, 0x01, 0x00, 0x63, 0x32, 0xFD, 0x6C, 0x40, 0x3C, 0x46, 0x3E, 0xF2, 0x2A, 0xF0, 0x27, 0x41,
+	 0x44, 0x48, 0x20, 0xB9, 0x01, 0xB4, 0xF7, 0xB1, 0x0A, 0x03, 0x64, 0x40, 0x08, 0x27, 0x07, 0x00,
+	 0x0F, 0x60, 0x92, 0x63, 0x00, 0x64, 0x45, 0xFB, 0x46, 0xFB, 0xBD, 0xDB, 0xA3, 0xDB, 0xCB, 0x0A,
+	 0x31, 0x60, 0x0E, 0x7C, 0xA4, 0xD3, 0xFF, 0xFF, 0x17, 0x18, 0x28, 0x40, 0xD4, 0x36, 0x14, 0x00,
+	 0xAC, 0x4C, 0x80, 0x2A, 0x11, 0x00, 0x31, 0x60, 0x14, 0x7C, 0xA4, 0xD3, 0xFF, 0xFF, 0x0C, 0x18,
+	 0x31, 0x60, 0x16, 0x7C, 0xA4, 0xD3, 0x31, 0x60, 0x10, 0x7C, 0xA4, 0xD3, 0x60, 0x45, 0xD4, 0x80,
+	 0xDC, 0x84, 0x02, 0x03, 0xA4, 0xDB, 0xAF, 0x01, 0x31, 0x60, 0x10, 0x7C, 0x00, 0x64, 0xA4, 0xDB,
+	 0x41, 0x47, 0x3F, 0x40, 0x01, 0x2B, 0x0D, 0x00, 0xF6, 0xFE, 0x67, 0x4C, 0x05, 0x60, 0x69, 0x6B,
+	 0x31, 0x60, 0x0E, 0x7C, 0xA4, 0xD3, 0xFF, 0xFF, 0x04, 0x18, 0xAE, 0x4F, 0x08, 0xBC, 0x00, 0x7F,
+	 0xA0, 0x5E, 0x02, 0xE1, 0x01, 0x60, 0x08, 0xE1, 0xF0, 0xFE, 0x84, 0xFF, 0xBB, 0x60, 0x18, 0x64,
+	 0x40, 0x42, 0x82, 0xFF, 0xE5, 0xFE, 0x03, 0x04, 0xA8, 0x60, 0x24, 0x78, 0xFF, 0xFF, 0xE4, 0xFE,
+	 0x0A, 0x04, 0x1D, 0xFF, 0x00, 0xEB, 0x60, 0x7F, 0xA0, 0x5A, 0x80, 0x60, 0x00, 0xEA, 0xA0, 0x60,
+	 0x00, 0xEA, 0xD1, 0x60, 0x00, 0xEA, 0x43, 0xFF, 0xE6, 0xFE, 0x03, 0x05, 0xA3, 0x60, 0x4B, 0x78,
+	 0xFF, 0xFF, 0x3C, 0x44, 0x60, 0x46, 0x0F, 0xF0, 0x40, 0x42, 0x64, 0x40, 0x01, 0x2A, 0x03, 0x00,
+	 0xA6, 0x60, 0xB1, 0x78, 0xFF, 0xFF, 0x0B, 0x64, 0x3A, 0xDB, 0x1C, 0x42, 0x22, 0x46, 0x13, 0xF2,
+	 0xFF, 0x65, 0x60, 0x47, 0x2A, 0xF2, 0x40, 0x45, 0x40, 0x48, 0x04, 0x2B, 0x17, 0x00, 0x16, 0xF2,
+	 0x1D, 0xF2, 0x40, 0x43, 0x0F, 0xF2, 0x40, 0x44, 0x25, 0x5E, 0x3F, 0x40, 0x01, 0x27, 0x40, 0x45,
+	 0x0F, 0x64, 0x14, 0xF0, 0x35, 0xF2, 0xA0, 0x82, 0x0F, 0xB4, 0xCA, 0x85, 0xD4, 0x80, 0x10, 0xF2,
+	 0x01, 0x02, 0x2B, 0xFA, 0x27, 0x44, 0x40, 0xBC, 0x40, 0x47, 0x13, 0x00, 0x17, 0xF2, 0x2C, 0xF0,
+	 0x40, 0x43, 0x1B, 0xF2, 0x1D, 0xFA, 0x40, 0x44, 0x64, 0x40, 0x01, 0x2A, 0x02, 0x00, 0xAB, 0xFC,
+	 0x05, 0x00, 0x28, 0x40, 0xA4, 0x36, 0x02, 0x00, 0x11, 0xF2, 0x2B, 0xFA, 0x27, 0x44, 0xBF, 0xB4,
+	 0x40, 0x47, 0x28, 0x40, 0x40, 0x2B, 0xFF, 0xFF, 0xAB, 0x60, 0x4A, 0x78, 0xFF, 0xFF, 0x22, 0x46,
+	 0x2C, 0xF0, 0x27, 0x44, 0xDF, 0xB4, 0x40, 0x47, 0xB5, 0xFF, 0xBC, 0xFF, 0x47, 0xFF, 0xB7, 0xFF,
+	 0xB4, 0xFF, 0x48, 0x60, 0x2D, 0x7D, 0x08, 0x60, 0x00, 0x6B, 0x64, 0x40, 0x01, 0x2A, 0x09, 0x00,
+	 0x28, 0x44, 0x04, 0x27, 0x05, 0x00, 0xD4, 0x3A, 0x03, 0x00, 0xAE, 0x4F, 0xF7, 0xB4, 0xA0, 0x5E,
+	 0x1B, 0x00, 0x2A, 0xF0, 0x01, 0x65, 0x64, 0x40, 0xA4, 0x3A, 0x04, 0x65, 0x27, 0x44, 0x34, 0x87,
+	 0x36, 0xF3, 0xB4, 0xFF, 0x60, 0x5B, 0x4D, 0xE2, 0x04, 0x64, 0x3A, 0xDB, 0x01, 0x60, 0x0A, 0xE1,
+	 0x28, 0x44, 0x04, 0x27, 0x05, 0x00, 0xD4, 0x3A, 0x03, 0x00, 0xAE, 0x4F, 0xF7, 0xB4, 0xA0, 0x5E,
+	 0x2B, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x81, 0x3E, 0x06, 0x64, 0x3A, 0xDB, 0x22, 0x46, 0x01, 0x64,
+	 0x31, 0xFB, 0xC0, 0xFE, 0xBA, 0x60, 0xF0, 0x78, 0xFF, 0xFF, 0xB5, 0xFF, 0xA1, 0xFF, 0x6C, 0x40,
+	 0x3F, 0x40, 0x01, 0x2B, 0x03, 0x00, 0x67, 0x4C, 0x05, 0x60, 0x69, 0x6B, 0x02, 0xE1, 0x01, 0x60,
+	 0x08, 0xE1, 0xC4, 0xE2, 0x08, 0x64, 0x3A, 0xDB, 0xF0, 0xFE, 0x25, 0x46, 0x01, 0xF2, 0x61, 0x45,
+	 0xD4, 0x9E, 0x21, 0x46, 0x16, 0xFA, 0x2A, 0x44, 0x72, 0x45, 0x24, 0xFA, 0xB5, 0xF3, 0x06, 0x04,
+	 0xE4, 0xE2, 0xDC, 0x9C, 0x29, 0x40, 0x01, 0x26, 0x64, 0x44, 0xB5, 0xF9, 0x25, 0xFA, 0xB6, 0xF3,
+	 0x02, 0x04, 0xDC, 0x84, 0xB6, 0xFB, 0x28, 0xFA, 0xB7, 0xF3, 0x02, 0x04, 0xDC, 0x84, 0xB7, 0xFB,
+	 0x29, 0xFA, 0x2D, 0x44, 0x04, 0x2A, 0x06, 0x00, 0x28, 0x40, 0xA4, 0x36, 0x03, 0x00, 0xA5, 0x60,
+	 0x77, 0x78, 0xFF, 0xFF, 0x26, 0x43, 0x84, 0xBB, 0xFC, 0xB3, 0x21, 0x46, 0x01, 0x5D, 0x0F, 0xFC,
+	 0x5C, 0x46, 0x25, 0x44, 0x06, 0xFA, 0x05, 0xFF, 0x27, 0x44, 0x01, 0x2A, 0x13, 0x00, 0x50, 0xFE,
+	 0x28, 0x40, 0x08, 0x3A, 0x12, 0x00, 0x2F, 0xF2, 0x30, 0xF0, 0x60, 0x43, 0x31, 0xF2, 0x22, 0x46,
+	 0x64, 0x41, 0x2C, 0xF0, 0x2D, 0xF0, 0xD3, 0x80, 0x2E, 0xF0, 0xD1, 0x80, 0xD0, 0x80, 0x27, 0x44,
+	 0x09, 0x0C, 0x03, 0x00, 0x27, 0x44, 0x06, 0x22, 0x05, 0x00, 0xB8, 0xB4, 0x40, 0x47, 0x02, 0x64,
+	 0x31, 0xFB, 0xC0, 0xFE, 0xD4, 0x64, 0x40, 0x48, 0x0D, 0x64, 0x3A, 0xDB, 0x31, 0x60, 0x12, 0x7C,
+	 0x7C, 0x44, 0xA4, 0xDB, 0x21, 0x46, 0x1C, 0xF2, 0x7C, 0xF1, 0xFF, 0xB4, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x01, 0x06, 0x64, 0x44, 0x40, 0x45, 0x0A, 0x36, 0x70, 0x64, 0x14, 0x36, 0x38, 0x64, 0x37, 0x3A,
+	 0x03, 0x00, 0x04, 0x7F, 0x40, 0x45, 0x15, 0x64, 0x6E, 0x3A, 0x03, 0x00, 0x84, 0x7F, 0x40, 0x45,
+	 0x0B, 0x64, 0x40, 0x44, 0x00, 0x63, 0x28, 0x44, 0xA4, 0x36, 0x0B, 0x00, 0x04, 0x2B, 0x09, 0x00,
+	 0x30, 0xF3, 0x24, 0x45, 0xD4, 0x84, 0xCA, 0x65, 0xD4, 0x83, 0x31, 0x60, 0x12, 0x7C, 0x01, 0x64,
+	 0xA4, 0xDB, 0xD4, 0x64, 0x1A, 0x00, 0x0F, 0x64, 0x3A, 0xDB, 0x21, 0x46, 0x70, 0x63, 0x1C, 0xF2,
+	 0xCA, 0x65, 0x40, 0x45, 0x0A, 0x36, 0x70, 0x64, 0x14, 0x36, 0x38, 0x64, 0x37, 0x3A, 0x03, 0x00,
+	 0x04, 0x7F, 0x40, 0x45, 0x15, 0x64, 0x6E, 0x3A, 0x03, 0x00, 0x84, 0x7F, 0x40, 0x45, 0x0B, 0x64,
+	 0x40, 0x44, 0x2B, 0xF2, 0xC4, 0x85, 0xD4, 0x83, 0xC4, 0x64, 0x40, 0x48, 0x2F, 0xF0, 0xB0, 0xF0,
+	 0xB1, 0xF2, 0x00, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x80, 0x4E, 0x83, 0x4C, 0x9A, 0xFF, 0x84, 0x4C,
+	 0x85, 0x4C, 0x81, 0x4C, 0xA1, 0xFF, 0x98, 0xFF, 0x87, 0x4F, 0x87, 0x4C, 0x87, 0x4F, 0x87, 0x4D,
+	 0x87, 0x4C, 0x01, 0x08, 0x01, 0x00, 0xFF, 0xFF, 0x87, 0x4C, 0x87, 0x4C, 0x87, 0x4C, 0x87, 0x4C,
+	 0xFF, 0xFF, 0xFF, 0xFF, 0x6A, 0x44, 0xBC, 0xFF, 0xC4, 0xE2, 0x0C, 0x74, 0x04, 0xE1, 0xA1, 0xFF,
+	 0x35, 0xF3, 0xC4, 0xE2, 0x60, 0x54, 0x89, 0xFF, 0x13, 0x74, 0x88, 0xFF, 0xB5, 0xFF, 0x47, 0xFF,
+	 0x29, 0x44, 0xF7, 0xB4, 0x40, 0x49, 0xB7, 0xFF, 0xB4, 0xFF, 0x48, 0x60, 0x2D, 0x7D, 0x08, 0x60,
+	 0x00, 0x6B, 0x28, 0x40, 0xC4, 0x36, 0x08, 0x00, 0x31, 0x60, 0x12, 0x7C, 0xA4, 0xD3, 0xFF, 0xFF,
+	 0x03, 0x1B, 0xAE, 0x4F, 0xF7, 0xB4, 0xA0, 0x5E, 0x27, 0x44, 0x01, 0x2A, 0x05, 0x00, 0xFE, 0xB4,
+	 0x40, 0x47, 0xA4, 0x60, 0x7C, 0x78, 0xFF, 0xFF, 0xA3, 0x60, 0x3E, 0x78, 0xFF, 0xFF, 0x28, 0x40,
+	 0xB4, 0x3A, 0x09, 0x00, 0x27, 0x44, 0x07, 0x22, 0x05, 0x00, 0xF8, 0xB4, 0x40, 0x47, 0x02, 0x64,
+	 0x31, 0xFB, 0xC0, 0xFE, 0x90, 0x01, 0x28, 0x44, 0xD4, 0x36, 0x03, 0x00, 0xA6, 0x60, 0x98, 0x78,
+	 0xFF, 0xFF, 0x48, 0xE2, 0x27, 0x44, 0xFB, 0xB4, 0x40, 0x47, 0x2D, 0x60, 0x5A, 0x63, 0xA3, 0xD3,
+	 0xB0, 0x60, 0x58, 0x4D, 0xD8, 0x78, 0xFF, 0xFF, 0x34, 0xFB, 0x1C, 0x42, 0x22, 0x46, 0x2A, 0xF0,
+	 0xF7, 0x60, 0xFF, 0x64, 0xA0, 0x84, 0xA2, 0xDA, 0x60, 0x40, 0x40, 0x2B, 0xCC, 0x00, 0x22, 0xF2,
+	 0xFF, 0xFF, 0x60, 0x40, 0x22, 0x26, 0x42, 0x00, 0x01, 0x26, 0x03, 0x00, 0x04, 0x26, 0x07, 0x00,
+	 0xC2, 0x00, 0x04, 0x2B, 0xC0, 0x00, 0xA9, 0xF3, 0xFF, 0xFF, 0x60, 0x46, 0x01, 0x00, 0x07, 0xF4,
+	 0x47, 0xF2, 0xFF, 0xFF, 0xDC, 0x84, 0x47, 0xFA, 0x0D, 0x60, 0x3E, 0x62, 0x80, 0xFF, 0xBE, 0x60,
+	 0x78, 0x44, 0x02, 0xA4, 0xA2, 0xDB, 0xDE, 0x78, 0xFF, 0xFF, 0x82, 0xFF, 0xA9, 0xF3, 0x66, 0x5C,
+	 0xD0, 0x80, 0x00, 0x7C, 0x07, 0x03, 0x66, 0x43, 0x22, 0x46, 0x22, 0xF2, 0x63, 0x46, 0x60, 0x40,
+	 0x01, 0x2A, 0x01, 0x00, 0x3C, 0xF1, 0x47, 0xF0, 0x64, 0x41, 0x64, 0x47, 0xFF, 0xB4, 0x60, 0x5F,
+	 0x20, 0xBC, 0x80, 0x26, 0x80, 0xAC, 0x60, 0x47, 0x22, 0x46, 0x3A, 0xFA, 0x64, 0x44, 0x20, 0x7F,
+	 0x34, 0x94, 0x3B, 0xFA, 0x08, 0x60, 0x00, 0xEA, 0x0F, 0x64, 0x60, 0x7F, 0xA0, 0x5A, 0x80, 0x60,
+	 0x00, 0xEA, 0xA0, 0x60, 0x00, 0xEA, 0xD1, 0x60, 0x00, 0xEA, 0x85, 0x00, 0x2A, 0xF2, 0x00, 0x60,
+	 0x7C, 0x62, 0x60, 0x40, 0x40, 0x2B, 0x27, 0x00, 0xA2, 0xD3, 0x00, 0x61, 0x60, 0xFE, 0xA0, 0xD3,
+	 0xDE, 0x82, 0xA2, 0xD1, 0xFF, 0xFF, 0x20, 0xFE, 0x64, 0x5F, 0xDC, 0x84, 0xF1, 0x81, 0xC0, 0x2B,
+	 0x04, 0x00, 0x80, 0x2A, 0x02, 0x00, 0x7F, 0xA4, 0xDC, 0x84, 0xFF, 0x3B, 0x03, 0x00, 0x60, 0x47,
+	 0xDC, 0x87, 0x01, 0x61, 0xC0, 0x80, 0x00, 0x36, 0xDC, 0x84, 0x4E, 0xDB, 0x60, 0xFE, 0xDA, 0x82,
+	 0xA2, 0xD1, 0xFF, 0xFF, 0xC1, 0x84, 0xF0, 0x22, 0x10, 0xA4, 0xF0, 0x2A, 0x01, 0x00, 0x00, 0x64,
+	 0xA2, 0xDB, 0xFF, 0xFF, 0x20, 0xFE, 0x00, 0x60, 0x7C, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0xA0, 0xD3,
+	 0x5A, 0xD1, 0x3A, 0xFA, 0x3B, 0xF8, 0x74, 0x62, 0xA2, 0xD0, 0xFF, 0xFF, 0x64, 0x44, 0xE0, 0x7F,
+	 0xA0, 0x5A, 0x64, 0x47, 0xE1, 0x7F, 0x5A, 0xD0, 0xA0, 0x5A, 0x64, 0x44, 0xE2, 0x7F, 0xA0, 0x5A,
+	 0x00, 0x60, 0x80, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0xA0, 0xD1, 0x5A, 0xD1, 0x64, 0x45, 0x64, 0x44,
+	 0xE3, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xE4, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xE5, 0x7F,
+	 0xA0, 0x5A, 0x64, 0x47, 0xE6, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xE7, 0x7F, 0xA0, 0x5A,
+	 0x65, 0x40, 0x0D, 0x3A, 0x1C, 0x00, 0x64, 0x47, 0xE8, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44,
+	 0xE9, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xEA, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xEB, 0x7F,
+	 0xA0, 0x5A, 0x64, 0x47, 0xEC, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xED, 0x7F, 0xA0, 0x5A,
+	 0x64, 0x47, 0xEE, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xEF, 0x7F, 0xA0, 0x5A, 0x08, 0x60,
+	 0x00, 0xEA, 0x65, 0x44, 0x02, 0xA4, 0x60, 0x7F, 0xA0, 0x5A, 0x80, 0x60, 0x00, 0xEA, 0xA0, 0x60,
+	 0x00, 0xEA, 0xD1, 0x60, 0x00, 0xEA, 0x0B, 0xF2, 0xFF, 0xFF, 0x7F, 0xB4, 0x0C, 0xF0, 0x04, 0x02,
+	 0x64, 0x46, 0x00, 0xF0, 0x04, 0x64, 0x22, 0x46, 0x03, 0xFA, 0x60, 0x41, 0x64, 0x46, 0x01, 0xF2,
+	 0xFC, 0xA1, 0x61, 0x45, 0xD4, 0x84, 0xFF, 0xFF, 0x08, 0x02, 0x00, 0xF0, 0x04, 0x63, 0x64, 0x46,
+	 0x01, 0xF2, 0x22, 0x46, 0x1A, 0xFA, 0x03, 0xFC, 0x02, 0x00, 0x22, 0x46, 0x1A, 0xFA, 0x35, 0xF2,
+	 0x04, 0xF8, 0xDC, 0x84, 0x35, 0xFA, 0x14, 0xF2, 0x0F, 0xB5, 0x0F, 0xB4, 0xCC, 0x84, 0x94, 0x80,
+	 0x04, 0x60, 0x00, 0x65, 0x2A, 0xF2, 0x01, 0x02, 0x94, 0x84, 0x2A, 0xFA, 0x95, 0xFC, 0x06, 0x00,
+	 0xC4, 0x3A, 0x07, 0x00, 0x27, 0x44, 0xFD, 0xB4, 0x40, 0x47, 0x48, 0xE2, 0xA4, 0x60, 0x0B, 0x78,
+	 0xFF, 0xFF, 0x28, 0x44, 0x04, 0x26, 0x05, 0x00, 0x68, 0x3A, 0x03, 0x00, 0x32, 0x44, 0x00, 0x27,
+	 0x03, 0x00, 0xA3, 0x60, 0x4B, 0x78, 0xFF, 0xFF, 0x0A, 0x64, 0x3A, 0xDB, 0xA3, 0x60, 0x4B, 0x78,
+	 0xFF, 0xFF, 0x0E, 0x64, 0x3A, 0xDB, 0x10, 0x60, 0x00, 0x65, 0x3C, 0x46, 0x2A, 0xF2, 0x13, 0xF0,
+	 0xA4, 0x84, 0xB4, 0xBC, 0x40, 0x48, 0x7C, 0xF1, 0x64, 0x47, 0xFF, 0xB4, 0x60, 0x45, 0xD0, 0x80,
+	 0x70, 0x61, 0x01, 0x06, 0x64, 0x44, 0x0A, 0x36, 0x70, 0x64, 0x14, 0x36, 0x38, 0x64, 0x37, 0x36,
+	 0x15, 0x64, 0x6E, 0x36, 0x0B, 0x64, 0x40, 0x4E, 0xA0, 0x63, 0x0A, 0x64, 0x65, 0x40, 0x0A, 0x36,
+	 0x03, 0x00, 0x38, 0x61, 0x14, 0x64, 0xEB, 0x83, 0x40, 0x45, 0x43, 0x44, 0x02, 0x60, 0x5E, 0x65,
+	 0x2A, 0xF2, 0x2B, 0xF2, 0x60, 0x40, 0x04, 0x2B, 0x04, 0x00, 0x2E, 0x45, 0xD4, 0x85, 0xC5, 0x84,
+	 0x05, 0x00, 0x1B, 0xF0, 0xC5, 0x84, 0xC0, 0x84, 0x2E, 0x45, 0xC4, 0x84, 0x60, 0x43, 0x28, 0x44,
+	 0x00, 0xE1, 0xA1, 0xFF, 0x80, 0x4E, 0x83, 0x4C, 0x9A, 0xFF, 0x56, 0x62, 0x7A, 0xD4, 0x7A, 0xD4,
+	 0x7A, 0xD4, 0x5C, 0x62, 0x7A, 0xD4, 0x7A, 0xD4, 0x7A, 0xD4, 0xA1, 0xFF, 0x98, 0xFF, 0x87, 0x4F,
+	 0x87, 0x4C, 0x87, 0x4F, 0x87, 0x4D, 0x87, 0x4C, 0x01, 0x08, 0x01, 0x00, 0xFF, 0xFF, 0x87, 0x4C,
+	 0x87, 0x4C, 0x87, 0x4C, 0x87, 0x4C, 0xFF, 0xFF, 0xFF, 0xFF, 0x6A, 0x44, 0xBC, 0xFF, 0xB5, 0xFF,
+	 0x47, 0xFF, 0x27, 0x44, 0x02, 0xBC, 0x40, 0x47, 0x36, 0xF3, 0xB7, 0xFF, 0xB4, 0xFF, 0x48, 0x60,
+	 0x2D, 0x7D, 0x08, 0x60, 0x00, 0x6B, 0x60, 0x5B, 0x4D, 0xE2, 0xA4, 0x60, 0x6C, 0x78, 0xFF, 0xFF,
+	 0x21, 0x46, 0xB5, 0xFF, 0xBC, 0xFF, 0x47, 0xFF, 0xB7, 0xFF, 0xB4, 0xFF, 0x48, 0x60, 0x2D, 0x7D,
+	 0x08, 0x60, 0x00, 0x6B, 0x28, 0x44, 0x04, 0x27, 0x09, 0x00, 0xD4, 0x36, 0x04, 0x00, 0x0C, 0x22,
+	 0x02, 0x00, 0x0C, 0x3A, 0x03, 0x00, 0xAE, 0x4F, 0xF7, 0xB4, 0xA0, 0x5E, 0x26, 0x43, 0x25, 0x44,
+	 0x06, 0xFA, 0x2A, 0x44, 0x72, 0x45, 0x24, 0xFA, 0xB5, 0xF3, 0x06, 0x04, 0xE4, 0xE2, 0xDC, 0x9C,
+	 0x29, 0x40, 0x01, 0x26, 0x64, 0x44, 0xB5, 0xF9, 0x25, 0xFA, 0xB6, 0xF3, 0x02, 0x04, 0xDC, 0x84,
+	 0xB6, 0xFB, 0x28, 0xFA, 0xB7, 0xF3, 0x02, 0x04, 0xDC, 0x84, 0xB7, 0xFB, 0x29, 0xFA, 0x2D, 0x40,
+	 0x01, 0x2A, 0x0E, 0x00, 0x1D, 0xFF, 0x26, 0x44, 0x02, 0xBC, 0x40, 0x46, 0x27, 0x44, 0x07, 0x22,
+	 0x05, 0x00, 0xF8, 0xB4, 0x40, 0x47, 0x06, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0x30, 0xF1, 0x76, 0x00,
+	 0xFC, 0xB3, 0x32, 0x40, 0x01, 0x2A, 0x06, 0x00, 0x0A, 0xBB, 0x0F, 0xFC, 0xCB, 0xFE, 0xA3, 0x60,
+	 0x4B, 0x78, 0xFF, 0xFF, 0x2D, 0x44, 0x04, 0x26, 0x28, 0x00, 0x0F, 0xFC, 0x05, 0xFF, 0xDC, 0xF3,
+	 0x28, 0x40, 0x80, 0x3A, 0x22, 0x00, 0x60, 0x40, 0x03, 0x3A, 0x1F, 0x00, 0x32, 0xF2, 0x81, 0xF1,
+	 0x33, 0xF2, 0xD0, 0x80, 0x82, 0xF1, 0x19, 0x02, 0xD0, 0x80, 0x34, 0xF2, 0x83, 0xF1, 0x15, 0x02,
+	 0xD0, 0x80, 0x3C, 0x44, 0x12, 0x02, 0xAC, 0x86, 0xBB, 0xFE, 0x0F, 0x03, 0x2A, 0xF2, 0x21, 0x46,
+	 0x60, 0x40, 0x80, 0x3A, 0x0A, 0x00, 0x01, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0x00, 0x64, 0x32, 0xFB,
+	 0x84, 0xFF, 0xBB, 0x60, 0x18, 0x64, 0x40, 0x42, 0x82, 0xFF, 0x30, 0xF1, 0x27, 0x44, 0x05, 0x22,
+	 0x2D, 0x00, 0xFA, 0xB4, 0x40, 0x47, 0x2D, 0x44, 0x10, 0x2A, 0x24, 0x00, 0x28, 0x40, 0xD4, 0x3A,
+	 0x21, 0x00, 0x31, 0x40, 0x08, 0x26, 0x00, 0x7C, 0x2B, 0x44, 0xD0, 0x80, 0x70, 0x45, 0x02, 0x28,
+	 0x64, 0x44, 0xC4, 0x84, 0xFF, 0xFF, 0x04, 0x24, 0x00, 0xB4, 0x60, 0x50, 0x08, 0x28, 0x01, 0x00,
+	 0x20, 0x29, 0x6D, 0xE2, 0x1C, 0x60, 0x9A, 0x63, 0x1D, 0xF0, 0xC0, 0x64, 0xC0, 0x84, 0xA3, 0xD1,
+	 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xC0, 0x84, 0xA3, 0xDB, 0xA4, 0x60,
+	 0x7C, 0x78, 0xFF, 0xFF, 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0x07, 0x00, 0x02, 0x2A, 0x05, 0x00,
+	 0xFD, 0xB4, 0x40, 0x47, 0x06, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0x05, 0x64, 0x3A, 0xDB, 0x28, 0x44,
+	 0xA4, 0x3A, 0x04, 0x00, 0x39, 0xF1, 0x25, 0x44, 0x0A, 0x36, 0x38, 0xF1, 0x31, 0x40, 0x08, 0x26,
+	 0x00, 0x7C, 0x2B, 0x44, 0xD0, 0x80, 0x70, 0x45, 0x02, 0x28, 0x64, 0x44, 0xC4, 0x84, 0xFF, 0xFF,
+	 0x04, 0x24, 0x00, 0xB4, 0x28, 0x40, 0xE4, 0x36, 0x00, 0xB4, 0x60, 0x50, 0x08, 0x28, 0x01, 0x00,
+	 0x20, 0x29, 0x6D, 0xE2, 0xA3, 0x60, 0x3E, 0x78, 0xFF, 0xFF, 0x21, 0x46, 0xB5, 0xFF, 0xBC, 0xFF,
+	 0x47, 0xFF, 0xB7, 0xFF, 0xB4, 0xFF, 0x48, 0x60, 0x2D, 0x7D, 0x08, 0x60, 0x00, 0x6B, 0xAE, 0x4F,
+	 0xF7, 0xB4, 0xA0, 0x5E, 0x27, 0x44, 0x07, 0x22, 0x05, 0x00, 0xF8, 0xB4, 0x40, 0x47, 0x06, 0x64,
+	 0x31, 0xFB, 0xC0, 0xFE, 0xE7, 0x01, 0x27, 0x44, 0x05, 0x22, 0x09, 0x00, 0xBA, 0xB4, 0x40, 0x47,
+	 0x3C, 0x46, 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0xA3, 0x60, 0x4B, 0x78, 0xFF, 0xFF, 0x27, 0x44,
+	 0x02, 0x2A, 0x06, 0x00, 0xFD, 0xB4, 0x40, 0x47, 0x06, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0xF4, 0x01,
+	 0xF3, 0x0A, 0x7C, 0x50, 0x6D, 0xE2, 0xF0, 0x01, 0x72, 0x45, 0xDC, 0x84, 0xB5, 0xFB, 0x11, 0x64,
+	 0x3A, 0xDB, 0xB6, 0xF3, 0x06, 0x04, 0xDC, 0x84, 0xB6, 0xFB, 0xB7, 0xF3, 0x02, 0x04, 0xDC, 0x84,
+	 0xB7, 0xFB, 0xA3, 0x60, 0x56, 0x78, 0xFF, 0xFF, 0x00, 0x61, 0x12, 0x64, 0x3A, 0xDB, 0x1E, 0x60,
+	 0xFE, 0x63, 0xBD, 0xD3, 0x72, 0x45, 0x44, 0x8A, 0x02, 0x28, 0x02, 0x00, 0xE4, 0xE2, 0xDD, 0x81,
+	 0x02, 0x28, 0x02, 0x00, 0xE4, 0xE2, 0xDD, 0x81, 0xBD, 0xD3, 0xB5, 0xF1, 0x61, 0x45, 0xC0, 0x84,
+	 0x00, 0x61, 0x02, 0x24, 0x01, 0xB9, 0xC4, 0x84, 0x60, 0x55, 0x2A, 0x52, 0xB5, 0xFB, 0x02, 0x24,
+	 0x01, 0xB9, 0xBD, 0xD3, 0xB6, 0xF1, 0x61, 0x45, 0xC0, 0x84, 0x00, 0x61, 0x02, 0x24, 0x01, 0xB9,
+	 0xC4, 0x84, 0xB6, 0xFB, 0x02, 0x24, 0x01, 0xB9, 0xBD, 0xD3, 0xB7, 0xF1, 0x61, 0x45, 0xC0, 0x84,
+	 0xC4, 0x84, 0xB7, 0xFB, 0xA3, 0x60, 0xEF, 0x78, 0xFF, 0xFF, 0x31, 0x40, 0x04, 0x0A, 0xAE, 0x4F,
+	 0xF7, 0xB4, 0xA0, 0x5E, 0x09, 0x00, 0x31, 0x60, 0x0E, 0x7C, 0xA4, 0xD3, 0xFF, 0xFF, 0x04, 0x18,
+	 0xAE, 0x4F, 0x08, 0xBC, 0x00, 0x7F, 0xA0, 0x5E, 0x9F, 0x01, 0xA1, 0xFF, 0xFF, 0xFF, 0x01, 0x25,
+	 0x09, 0x00, 0x04, 0x25, 0x03, 0x00, 0x47, 0xFF, 0x32, 0x74, 0x96, 0x01, 0xC4, 0xE2, 0xAB, 0x60,
+	 0x2C, 0x78, 0xFF, 0xFF, 0x4C, 0x4E, 0x47, 0xFF, 0x31, 0x60, 0x0E, 0x7C, 0xA4, 0xD3, 0xFF, 0xFF,
+	 0x04, 0x18, 0xAE, 0x4F, 0x08, 0xBC, 0x00, 0x7F, 0xA0, 0x5E, 0x32, 0x74, 0xCD, 0xE2, 0xA8, 0x60,
+	 0x8A, 0x78, 0x00, 0x61, 0x10, 0x64, 0x3A, 0xDB, 0xA3, 0x60, 0x4B, 0x78, 0xFF, 0xFF, 0xA3, 0x60,
+	 0x4B, 0x78, 0xFF, 0xFF, 0x5C, 0x4D, 0x26, 0x44, 0x02, 0x26, 0x0C, 0x00, 0x3E, 0x46, 0x09, 0xF2,
+	 0x1E, 0x41, 0x03, 0x1B, 0xAA, 0x60, 0xDB, 0x78, 0xFF, 0xFF, 0x40, 0x5E, 0xFD, 0xFB, 0x21, 0x44,
+	 0x02, 0x64, 0x40, 0x46, 0x41, 0x5D, 0x21, 0x46, 0x00, 0xF2, 0x46, 0x45, 0x87, 0xFC, 0x4C, 0xE2,
+	 0x01, 0x64, 0x33, 0xFB, 0x01, 0x60, 0x0E, 0xE1, 0x03, 0xE1, 0x3F, 0x40, 0x01, 0x27, 0x00, 0x00,
+	 0x21, 0x69, 0xB6, 0xFF, 0xA1, 0xFF, 0x6C, 0x5E, 0xB6, 0xFF, 0xB7, 0xFF, 0x60, 0x5C, 0x20, 0x64,
+	 0x3A, 0xDB, 0x68, 0x43, 0x26, 0xFC, 0x22, 0x69, 0x64, 0x44, 0xA1, 0xFF, 0xFF, 0xFF, 0x6C, 0x5F,
+	 0x60, 0x43, 0x26, 0xF2, 0xFF, 0xFF, 0x68, 0x5F, 0x26, 0xFA, 0x3A, 0x69, 0x1D, 0xFC, 0x2E, 0x44,
+	 0x36, 0xF1, 0x1C, 0xFA, 0xC3, 0x94, 0xCD, 0xE2, 0x2E, 0x44, 0x14, 0x36, 0x12, 0x00, 0x0A, 0x36,
+	 0x0F, 0x00, 0x63, 0x45, 0xE3, 0x83, 0xE3, 0x83, 0xC7, 0x83, 0xE3, 0x83, 0xC7, 0x83, 0xFF, 0xFF,
+	 0x37, 0x36, 0x05, 0x00, 0x6E, 0x36, 0x04, 0x00, 0xAA, 0x60, 0xF3, 0x78, 0xFF, 0xFF, 0xEB, 0x83,
+	 0xEB, 0x83, 0xEB, 0x83, 0xEB, 0x83, 0xFF, 0xFF, 0x80, 0x27, 0xCF, 0x83, 0x1B, 0xFC, 0x01, 0x64,
+	 0x51, 0xFB, 0xA1, 0xFF, 0x1C, 0xF2, 0x29, 0x41, 0xF9, 0x81, 0x52, 0x4A, 0x71, 0x89, 0x68, 0x5F,
+	 0x27, 0xFA, 0x6C, 0x40, 0x03, 0x15, 0xAB, 0x60, 0x04, 0x78, 0xFF, 0xFF, 0x88, 0x60, 0x85, 0x71,
+	 0x8D, 0xE2, 0xB9, 0xF1, 0xFC, 0xA3, 0xD3, 0x80, 0x43, 0x43, 0x03, 0x04, 0xAA, 0x60, 0xFB, 0x78,
+	 0xFF, 0xFF, 0x32, 0x40, 0x01, 0x2A, 0x4C, 0x00, 0x9A, 0xFF, 0x23, 0x43, 0x18, 0x61, 0xA1, 0xFF,
+	 0x8C, 0x44, 0xCB, 0x83, 0x2A, 0xFA, 0x40, 0x48, 0x40, 0x27, 0x04, 0xA1, 0x60, 0x40, 0x03, 0x2B,
+	 0x01, 0x00, 0x06, 0xA1, 0x88, 0xB0, 0x88, 0x36, 0xD9, 0x81, 0x62, 0x45, 0x23, 0x44, 0x54, 0x94,
+	 0x28, 0x40, 0x04, 0x26, 0x00, 0x64, 0x3F, 0xFA, 0xC9, 0x81, 0x65, 0x42, 0x7A, 0xDC, 0x00, 0xB9,
+	 0xFD, 0x1C, 0x00, 0xF4, 0x6E, 0x61, 0x10, 0x62, 0x14, 0x02, 0x05, 0x1D, 0x12, 0x1E, 0x0C, 0x00,
+	 0x00, 0xF4, 0x7C, 0x61, 0x02, 0x62, 0x7A, 0xDC, 0x63, 0x40, 0xFD, 0x1C, 0xF9, 0x1D, 0xFF, 0xB1,
+	 0x08, 0x1E, 0x02, 0x02, 0x00, 0xF4, 0x02, 0x62, 0xB6, 0xFF, 0xB7, 0xFF, 0xA1, 0xFF, 0x6C, 0x44,
+	 0x5A, 0xDA, 0x98, 0xFF, 0x01, 0x60, 0x08, 0xE1, 0x81, 0xE1, 0xA1, 0xFF, 0x6C, 0x40, 0xA1, 0xFF,
+	 0x47, 0xFF, 0x26, 0x44, 0xFD, 0xB4, 0x84, 0xBC, 0x01, 0x15, 0x7F, 0xB4, 0x40, 0x46, 0xA1, 0xFF,
+	 0x6C, 0x40, 0x14, 0x63, 0x01, 0x11, 0x01, 0x00, 0xFD, 0x1F, 0xAA, 0x60, 0x6E, 0x78, 0xFF, 0xFF,
+	 0x9A, 0xFF, 0x54, 0x63, 0x12, 0x64, 0x40, 0x46, 0x00, 0x64, 0x0F, 0xFA, 0xA1, 0xFF, 0xEB, 0xF1,
+	 0x12, 0x61, 0x50, 0xFE, 0x2D, 0x60, 0x52, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x2A,
+	 0x0B, 0x00, 0x8C, 0x45, 0x98, 0xF8, 0x00, 0x64, 0x3A, 0xFA, 0x3B, 0xFA, 0x3C, 0xFA, 0x3D, 0xFA,
+	 0xBF, 0x60, 0xFF, 0x64, 0xA4, 0x84, 0x01, 0x00, 0x8C, 0x44, 0xEC, 0xF0, 0xBD, 0xDA, 0x40, 0x48,
+	 0x04, 0x26, 0x40, 0x00, 0xA1, 0xFF, 0x8C, 0x44, 0xBD, 0xDA, 0x30, 0xFB, 0x6C, 0x44, 0xBD, 0xDA,
+	 0xFF, 0xFF, 0x01, 0x26, 0x24, 0x00, 0xD0, 0x80, 0xA1, 0xFF, 0x8C, 0x44, 0x6C, 0x5C, 0xF2, 0xFE,
+	 0xBD, 0xDA, 0xED, 0xF3, 0xD4, 0x80, 0xD0, 0x80, 0xBD, 0xD8, 0x2D, 0x44, 0x15, 0x0C, 0x32, 0x40,
+	 0x02, 0x2A, 0x07, 0x00, 0x28, 0x42, 0x0C, 0xB2, 0x08, 0x3A, 0x03, 0x00, 0x10, 0xBC, 0x40, 0x4D,
+	 0x4D, 0x00, 0x03, 0x0A, 0xAB, 0x60, 0x09, 0x78, 0xFF, 0xFF, 0x11, 0xBC, 0x40, 0x4D, 0x28, 0x45,
+	 0xBF, 0x60, 0xFF, 0x64, 0x24, 0x88, 0x42, 0x00, 0x30, 0xBC, 0x40, 0x4D, 0x3F, 0x00, 0x20, 0xB9,
+	 0x5C, 0x8E, 0xA1, 0xFF, 0x8C, 0x44, 0xBD, 0xDA, 0xDC, 0x9C, 0x6C, 0x44, 0xF2, 0xFE, 0xBD, 0xDA,
+	 0x08, 0x28, 0x44, 0x4E, 0xDC, 0x84, 0x2E, 0x5C, 0xB0, 0x84, 0xEF, 0xB1, 0x08, 0x24, 0x40, 0xB9,
+	 0x41, 0x46, 0x2C, 0x00, 0x8C, 0x44, 0x04, 0x61, 0xBD, 0xDA, 0x50, 0xFE, 0x80, 0x27, 0x00, 0x64,
+	 0x30, 0xFB, 0x8C, 0x44, 0xBD, 0xDA, 0xD0, 0x80, 0x8C, 0x44, 0xBD, 0xDA, 0xD4, 0x80, 0x00, 0x65,
+	 0x8C, 0x44, 0xED, 0xF1, 0xBD, 0xDA, 0xD0, 0x80, 0x28, 0x44, 0x03, 0x0C, 0xA0, 0x2A, 0x0A, 0x00,
+	 0x11, 0x00, 0x10, 0x65, 0x60, 0x40, 0xC4, 0x36, 0x04, 0x00, 0xD4, 0x3A, 0x08, 0x00, 0x27, 0x40,
+	 0x40, 0x26, 0x30, 0x65, 0x00, 0x64, 0x3F, 0xFA, 0x46, 0x4E, 0x35, 0x8D, 0x5F, 0x00, 0x40, 0x26,
+	 0xF9, 0x01, 0x30, 0x65, 0x9D, 0xDC, 0x9D, 0xDC, 0x9D, 0xDC, 0xF4, 0x01, 0x00, 0xE1, 0x23, 0x43,
+	 0xE8, 0xA3, 0x6A, 0x62, 0x9A, 0xFF, 0xA1, 0xFF, 0x28, 0x44, 0x03, 0x2B, 0x04, 0x00, 0x7A, 0xDC,
+	 0x7A, 0xDC, 0x7A, 0xDC, 0x28, 0x44, 0x88, 0xB0, 0x88, 0x2A, 0x03, 0x00, 0x70, 0x62, 0x7A, 0xDC,
+	 0x28, 0x44, 0x40, 0x2B, 0x13, 0x00, 0x72, 0x62, 0x7A, 0xDC, 0x04, 0xE6, 0x7A, 0xDC, 0x3B, 0xF2,
+	 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x2B, 0x02, 0x00, 0x7A, 0xDC, 0x7A, 0xDC, 0x08, 0x60, 0x00, 0xEB,
+	 0xFC, 0xA3, 0x25, 0xFF, 0x3F, 0xFC, 0x04, 0xA3, 0xB0, 0xFF, 0x01, 0x00, 0x3F, 0xFC, 0xCF, 0x83,
+	 0xDF, 0x83, 0x04, 0x02, 0x00, 0xF4, 0x10, 0x62, 0x6C, 0x61, 0x1F, 0x00, 0x27, 0x03, 0xCB, 0x83,
+	 0xFF, 0x60, 0xFE, 0x65, 0x0E, 0xA3, 0xA7, 0x84, 0xF2, 0xA3, 0x00, 0xF4, 0x10, 0x62, 0x6C, 0x61,
+	 0x7A, 0xDC, 0xFE, 0x1C, 0x03, 0x1D, 0x7C, 0xA8, 0xD9, 0x81, 0x0A, 0x02, 0x00, 0xF4, 0x02, 0x62,
+	 0xA7, 0x84, 0x7A, 0x61, 0x7A, 0xDC, 0xFE, 0x1C, 0xF9, 0x1D, 0x7C, 0xA8, 0xD9, 0x81, 0xF6, 0x03,
+	 0xFF, 0xB1, 0x0C, 0x1E, 0x02, 0x02, 0x00, 0xF4, 0x02, 0x62, 0xA1, 0xFF, 0x01, 0x60, 0x0C, 0xE1,
+	 0xB6, 0xFF, 0xB7, 0xFF, 0xA1, 0xFF, 0xCD, 0x81, 0x6C, 0x44, 0x5A, 0xDA, 0x98, 0xFF, 0x00, 0xE6,
+	 0x7C, 0x44, 0x33, 0xFB, 0x01, 0x60, 0x0C, 0xE1, 0x83, 0xE1, 0xA1, 0xFF, 0x8C, 0x44, 0x46, 0x45,
+	 0xA1, 0xFF, 0x14, 0x63, 0x01, 0x10, 0xFE, 0x1F, 0x01, 0x60, 0x08, 0xE1, 0x0A, 0x64, 0x60, 0x54,
+	 0x47, 0xFF, 0x50, 0x4B, 0x67, 0x50, 0x69, 0xE2, 0x6A, 0x40, 0x40, 0x2B, 0x01, 0x15, 0x29, 0x00,
+	 0x6C, 0x40, 0x28, 0x40, 0x03, 0x26, 0x15, 0x00, 0x31, 0x40, 0x20, 0x2A, 0x03, 0x00, 0x28, 0x40,
+	 0x50, 0x3A, 0x0F, 0x00, 0x2D, 0x44, 0x20, 0x2A, 0x0C, 0x00, 0x2B, 0x44, 0xAC, 0x80, 0x28, 0x40,
+	 0xB4, 0x3A, 0x03, 0x00, 0x02, 0x03, 0x30, 0xFB, 0x04, 0x00, 0x2B, 0x50, 0xA4, 0x60, 0x85, 0x78,
+	 0x04, 0xE1, 0x04, 0xE1, 0xA1, 0xFF, 0x35, 0xF1, 0x26, 0x44, 0x64, 0x54, 0xCD, 0xE2, 0x84, 0xBC,
+	 0x2D, 0x40, 0x0C, 0x22, 0xFD, 0xB4, 0x40, 0x46, 0x23, 0x64, 0x3A, 0xDB, 0xA7, 0x60, 0x18, 0x78,
+	 0xFF, 0xFF, 0x27, 0x40, 0x26, 0x22, 0x04, 0x00, 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0xFF, 0xFF,
+	 0x6C, 0x40, 0xB7, 0xFF, 0xB4, 0xFF, 0x48, 0x60, 0x2D, 0x7D, 0x08, 0x60, 0x00, 0x6B, 0x37, 0xF3,
+	 0x2B, 0x45, 0xD4, 0x80, 0xFF, 0xFF, 0x02, 0x28, 0x65, 0x44, 0x60, 0x50, 0xA0, 0x4C, 0x20, 0xBC,
+	 0xFF, 0xB4, 0xA0, 0x51, 0x35, 0xF1, 0x74, 0x44, 0xC0, 0x94, 0x32, 0x40, 0x02, 0x2A, 0x18, 0x00,
+	 0x28, 0x44, 0xA4, 0x36, 0x04, 0x00, 0x0C, 0xB4, 0xFF, 0xFF, 0x04, 0x36, 0x11, 0x00, 0x26, 0x43,
+	 0xFD, 0xB3, 0x04, 0xBB, 0x43, 0x46, 0x01, 0x2A, 0x03, 0x00, 0x28, 0x47, 0x40, 0xBF, 0x40, 0x48,
+	 0x0A, 0xBB, 0x0F, 0xFC, 0x50, 0x4B, 0x67, 0x50, 0x00, 0x64, 0x30, 0xFB, 0x05, 0xFF, 0xC6, 0x01,
+	 0x24, 0x64, 0x3A, 0xDB, 0x28, 0x44, 0x04, 0x2A, 0x06, 0x00, 0xAE, 0x4F, 0xF7, 0xB4, 0xA0, 0x5E,
+	 0xA3, 0x60, 0x3E, 0x78, 0xFF, 0xFF, 0x1D, 0xFF, 0x48, 0xE2, 0x27, 0x44, 0x06, 0x22, 0x05, 0x00,
+	 0xF9, 0xB4, 0x40, 0x47, 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0x26, 0x40, 0x10, 0x2A, 0x18, 0x00,
+	 0x26, 0xF2, 0xFF, 0xFF, 0x60, 0x47, 0xFF, 0xB4, 0xC0, 0xA0, 0xFF, 0xFF, 0x11, 0x0E, 0xB8, 0xF1,
+	 0x27, 0x60, 0x92, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03,
+	 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF,
+	 0xA7, 0x60, 0xE5, 0x78, 0xFF, 0xFF, 0xB8, 0xF1, 0x27, 0x60, 0x94, 0x64, 0xA0, 0xD3, 0xFF, 0xFF,
+	 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00,
+	 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x2A, 0x64, 0x3A, 0xDB, 0x5C, 0x41, 0x87, 0xE1,
+	 0xA1, 0xFF, 0x6C, 0x40, 0x02, 0x00, 0x29, 0x64, 0x3A, 0xDB, 0x01, 0x60, 0x08, 0xE1, 0x87, 0xE1,
+	 0xA1, 0xFF, 0x6C, 0x40, 0x11, 0x00, 0x27, 0x60, 0xA6, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84,
+	 0xFF, 0xFF, 0x08, 0x28, 0xA2, 0xDB, 0xF1, 0x01, 0x01, 0x60, 0x08, 0xE1, 0x21, 0x64, 0x3A, 0xDB,
+	 0x03, 0x00, 0x01, 0x60, 0x08, 0xE1, 0x6C, 0x40, 0x00, 0x64, 0x33, 0xFB, 0x32, 0x74, 0x40, 0x63,
+	 0x01, 0x16, 0xFE, 0x01, 0x01, 0x68, 0x01, 0x11, 0x09, 0x00, 0xA7, 0x6A, 0x22, 0x64, 0x3A, 0xDB,
+	 0x03, 0x60, 0xC9, 0x63, 0x01, 0x11, 0x02, 0x00, 0x6C, 0x40, 0xFC, 0x1F, 0x6C, 0x40, 0xB5, 0xFF,
+	 0x6C, 0x40, 0xBC, 0xFF, 0x6C, 0x40, 0xB7, 0xFF, 0xB4, 0xFF, 0x48, 0x60, 0x2D, 0x7D, 0x08, 0x60,
+	 0x00, 0x6B, 0xAE, 0x4F, 0xF7, 0xB4, 0xA0, 0x5E, 0x03, 0x0A, 0xA3, 0x60, 0x4B, 0x78, 0xFF, 0xFF,
+	 0x01, 0x64, 0x51, 0xFB, 0x31, 0x60, 0x0E, 0x7C, 0xA4, 0xD3, 0xFF, 0xFF, 0x04, 0x18, 0xAE, 0x4F,
+	 0x08, 0xBC, 0x00, 0x7F, 0xA0, 0x5E, 0x27, 0x44, 0x06, 0x22, 0x06, 0x00, 0xF9, 0xB4, 0x40, 0x47,
+	 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0x48, 0xE2, 0x27, 0x64, 0x3A, 0xDB, 0xB3, 0xE1, 0xA1, 0xFF,
+	 0xFF, 0xFF, 0x81, 0x3E, 0x54, 0x62, 0x22, 0x46, 0xA2, 0xD0, 0x16, 0x63, 0x7C, 0x41, 0x44, 0x48,
+	 0x80, 0x36, 0x04, 0x61, 0x28, 0x40, 0x50, 0x36, 0x04, 0x61, 0x41, 0x4E, 0x28, 0x44, 0xA4, 0x36,
+	 0x0E, 0x63, 0x1C, 0x60, 0x9C, 0x62, 0xA2, 0xD1, 0x24, 0x44, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84,
+	 0xE8, 0x84, 0xE8, 0x84, 0xC0, 0x84, 0xA2, 0xDB, 0x9A, 0xFF, 0xA1, 0xFF, 0x2D, 0x60, 0x52, 0x62,
+	 0xA2, 0xD3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x2A, 0x06, 0x00, 0x18, 0xF2, 0xAA, 0xF0, 0xFF, 0xFF,
+	 0xB4, 0x84, 0x08, 0x36, 0x2A, 0xFA, 0x54, 0x62, 0xA2, 0xD2, 0xFF, 0xFF, 0x6A, 0x40, 0x80, 0x4E,
+	 0x7A, 0xD4, 0x7A, 0xD4, 0x7A, 0xD4, 0x7A, 0xD4, 0x7A, 0xD4, 0x7A, 0xD4, 0x7A, 0xD4, 0xFF, 0xFF,
+	 0x01, 0x1D, 0x78, 0x00, 0x7A, 0xD4, 0x7A, 0xD4, 0x7A, 0xD4, 0x7A, 0xD4, 0x28, 0x40, 0x03, 0x2B,
+	 0x04, 0x00, 0x7A, 0xD4, 0x7A, 0xD4, 0x7A, 0xD4, 0x6A, 0x40, 0x70, 0x62, 0x28, 0x44, 0x88, 0xB0,
+	 0x88, 0x36, 0x7A, 0xD4, 0x28, 0x40, 0x40, 0x2B, 0x0B, 0x00, 0x72, 0x62, 0x7A, 0xD4, 0x7A, 0xD4,
+	 0xA2, 0xD2, 0xFF, 0xFF, 0x60, 0x40, 0x20, 0x2B, 0x02, 0x00, 0x7A, 0xD4, 0x7A, 0xD4, 0x46, 0x00,
+	 0x23, 0x43, 0xCF, 0x83, 0xDF, 0x83, 0x02, 0x03, 0x55, 0x03, 0x04, 0x00, 0x03, 0xF0, 0x04, 0xF4,
+	 0x64, 0x42, 0x37, 0x00, 0x2E, 0x40, 0x04, 0x2A, 0x21, 0x00, 0xA1, 0xFF, 0x02, 0xFE, 0x10, 0x25,
+	 0x42, 0xFE, 0x72, 0x45, 0x65, 0x4C, 0xB5, 0xF3, 0x03, 0x04, 0xE4, 0xE2, 0xDC, 0x84, 0xB5, 0xFB,
+	 0xA1, 0xFF, 0x80, 0x4C, 0xB6, 0xF3, 0x02, 0x04, 0xDC, 0x84, 0xB6, 0xFB, 0x80, 0x4C, 0xB7, 0xF3,
+	 0x02, 0x04, 0xDC, 0x84, 0xB7, 0xFB, 0x80, 0x4C, 0x5C, 0x4E, 0xF8, 0xA3, 0x03, 0xF2, 0x9A, 0xF2,
+	 0x04, 0xF4, 0xFF, 0xB1, 0xF8, 0xA1, 0x06, 0xA4, 0x60, 0x42, 0x09, 0x00, 0x03, 0xF2, 0x9A, 0xF2,
+	 0x04, 0xF4, 0xC8, 0x82, 0xFF, 0xB1, 0x03, 0x00, 0x00, 0xF4, 0x81, 0xF2, 0xFF, 0xB1, 0x7A, 0xD4,
+	 0xFF, 0xFF, 0xFD, 0x1C, 0xF9, 0x1D, 0xFF, 0xB1, 0x17, 0x1E, 0x02, 0x02, 0x00, 0xF4, 0xDA, 0x82,
+	 0xDA, 0x82, 0xA2, 0xD2, 0xA1, 0xFF, 0x09, 0x74, 0x80, 0x4D, 0x0E, 0x00, 0x03, 0xF2, 0x9A, 0xF2,
+	 0x04, 0xF4, 0x23, 0x43, 0xA1, 0xFF, 0xA0, 0xD2, 0xFE, 0xA1, 0xCB, 0x83, 0x80, 0x4E, 0xAF, 0x83,
+	 0x02, 0x1D, 0x02, 0x03, 0xED, 0x01, 0xE3, 0x01, 0xA1, 0xFF, 0x28, 0x40, 0x40, 0x2B, 0x02, 0x00,
+	 0x9C, 0x4E, 0x9C, 0x4C, 0xA1, 0xFF, 0xDA, 0x83, 0x66, 0x44, 0x22, 0x46, 0x0C, 0xFA, 0x0B, 0xFC,
+	 0x87, 0x4F, 0x87, 0x4C, 0x87, 0x4F, 0x87, 0x4D, 0x87, 0x4C, 0x01, 0x08, 0x01, 0x00, 0xFF, 0xFF,
+	 0x87, 0x4C, 0x87, 0x4C, 0x87, 0x4C, 0x87, 0x4C, 0xFF, 0xFF, 0xFF, 0xFF, 0x6A, 0x44, 0xBC, 0xFF,
+	 0x01, 0x60, 0x08, 0xE1, 0x0C, 0x74, 0x04, 0xE1, 0xA1, 0xFF, 0x35, 0xF3, 0xC4, 0xE2, 0x60, 0x54,
+	 0x89, 0xFF, 0x13, 0x74, 0x88, 0xFF, 0x29, 0x44, 0xF7, 0xB4, 0x40, 0x49, 0x34, 0x64, 0x3A, 0xDB,
+	 0x06, 0xE1, 0x47, 0xFF, 0xA4, 0x60, 0x47, 0x78, 0xFF, 0xFF, 0xFF, 0x01, 0x10, 0x61, 0x7F, 0x60,
+	 0xC0, 0x64, 0xA0, 0x80, 0x7F, 0x67, 0x02, 0x63, 0x26, 0x02, 0x98, 0xFE, 0x1A, 0x05, 0x24, 0x60,
+	 0x52, 0x62, 0xA2, 0xD5, 0x0E, 0xF2, 0x15, 0x18, 0x02, 0x18, 0x09, 0xF4, 0xFB, 0x01, 0x23, 0x44,
+	 0x00, 0xA8, 0x08, 0x7E, 0x0A, 0x02, 0x66, 0x44, 0x11, 0xFB, 0x46, 0x43, 0x23, 0x47, 0x80, 0xBF,
+	 0x3B, 0x42, 0x04, 0xA2, 0xA2, 0xDB, 0x08, 0xB9, 0x10, 0x7E, 0x00, 0x7F, 0x0E, 0xFA, 0x00, 0x67,
+	 0x0A, 0x00, 0x20, 0x44, 0xDC, 0x85, 0x0F, 0xB4, 0xFA, 0xA0, 0x7F, 0x67, 0x07, 0x63, 0x03, 0x05,
+	 0x45, 0x40, 0x00, 0x67, 0xD8, 0xFE, 0xFF, 0x27, 0x05, 0xFD, 0x0A, 0x7E, 0x04, 0xFB, 0x61, 0x55,
+	 0x4A, 0x00, 0x28, 0xFB, 0x01, 0xF3, 0x29, 0xFB, 0x44, 0x46, 0x40, 0x45, 0x10, 0x61, 0x7E, 0x60,
+	 0xC0, 0x64, 0xA0, 0x80, 0x7F, 0x67, 0x02, 0x63, 0x31, 0x02, 0xAE, 0x60, 0x58, 0x4F, 0x6F, 0x78,
+	 0xFF, 0xFF, 0x7F, 0x67, 0x03, 0x63, 0x2A, 0x02, 0x26, 0x40, 0x01, 0x2B, 0x24, 0x00, 0x98, 0xFE,
+	 0x19, 0x05, 0x24, 0x60, 0x52, 0x62, 0xA2, 0xD5, 0x0E, 0xF2, 0x14, 0x18, 0x02, 0x18, 0x09, 0xF4,
+	 0xFB, 0x01, 0x23, 0x44, 0x00, 0xA8, 0x08, 0x7E, 0x0A, 0x02, 0x66, 0x44, 0x11, 0xFB, 0x46, 0x43,
+	 0x23, 0x47, 0x80, 0xBF, 0x3B, 0x42, 0x04, 0xA2, 0xA2, 0xDB, 0x08, 0xB9, 0x10, 0x7E, 0x00, 0x7F,
+	 0x0E, 0xFA, 0x09, 0x00, 0x20, 0x44, 0xDC, 0x85, 0x0F, 0xB4, 0xFA, 0xA0, 0x7F, 0x67, 0x07, 0x63,
+	 0x05, 0x05, 0x45, 0x40, 0xD8, 0xFE, 0x00, 0x67, 0xD0, 0xFE, 0xD9, 0xFE, 0xFF, 0x27, 0x05, 0xFD,
+	 0x0B, 0x7E, 0x04, 0xFB, 0x1C, 0x60, 0xB4, 0x63, 0xA3, 0xD3, 0xFF, 0xFF, 0x20, 0xB0, 0x80, 0xBC,
+	 0x08, 0x28, 0xA3, 0xDB, 0x61, 0x55, 0x63, 0x00, 0x04, 0xB5, 0x82, 0xB5, 0x25, 0x02, 0x04, 0x03,
+	 0x20, 0x44, 0x7F, 0xB4, 0x40, 0x40, 0xA3, 0xD3, 0x99, 0xFE, 0x04, 0x04, 0x02, 0xBC, 0xFE, 0xB4,
+	 0xA3, 0xDB, 0x56, 0x00, 0xDC, 0xF3, 0x20, 0x40, 0x80, 0x26, 0x52, 0x00, 0xA3, 0xD3, 0xFF, 0xA0,
+	 0xF8, 0xB4, 0x02, 0x02, 0xA3, 0xDB, 0x1C, 0x00, 0x04, 0xBC, 0xBF, 0xB4, 0xA3, 0xDB, 0x08, 0xB0,
+	 0x01, 0x64, 0x08, 0x24, 0x02, 0x64, 0x28, 0xFB, 0x20, 0x44, 0x80, 0xBC, 0x40, 0x40, 0xD0, 0xFE,
+	 0x3F, 0x00, 0xBF, 0xB4, 0xA3, 0xDB, 0x3C, 0x00, 0x40, 0xB0, 0xFF, 0xFF, 0xFA, 0x02, 0xF8, 0xB4,
+	 0xA3, 0xDB, 0x08, 0xB5, 0x07, 0x7C, 0x01, 0x02, 0xDC, 0xF9, 0x20, 0x44, 0x7F, 0xB4, 0x40, 0x40,
+	 0x1C, 0x60, 0xB4, 0x63, 0xA3, 0xD3, 0xFF, 0xFF, 0x20, 0xB5, 0x07, 0xB5, 0x08, 0x28, 0xC4, 0x02,
+	 0x99, 0xFE, 0x26, 0x05, 0x20, 0x44, 0x80, 0x26, 0x23, 0x00, 0x20, 0x2A, 0x00, 0x00, 0x40, 0x2A,
+	 0x1F, 0x00, 0xBF, 0xB4, 0x40, 0x40, 0x09, 0x00, 0xA8, 0xFF, 0x20, 0x44, 0x99, 0xFE, 0x02, 0x05,
+	 0x80, 0x2A, 0x03, 0x00, 0x40, 0xBC, 0x40, 0x40, 0x13, 0x00, 0x00, 0xF1, 0x80, 0xBC, 0x40, 0x40,
+	 0x64, 0x44, 0xE0, 0x84, 0xE8, 0x84, 0x0A, 0x36, 0x29, 0x01, 0x0B, 0x36, 0x5A, 0x01, 0x28, 0xFB,
+	 0x01, 0xF1, 0x29, 0xF9, 0x02, 0xF1, 0x2A, 0xF9, 0x03, 0xF1, 0x2B, 0xF9, 0xD0, 0xFE, 0xAE, 0xFF,
+	 0xA1, 0xFF, 0xFF, 0xFF, 0x82, 0x3E, 0x75, 0x44, 0x02, 0xB0, 0x01, 0xB0, 0x29, 0x02, 0xDC, 0x02,
+	 0x04, 0xB0, 0x08, 0xB0, 0x0B, 0x02, 0x20, 0x02, 0x40, 0x26, 0xA7, 0xFF, 0x8C, 0xFF, 0x75, 0x40,
+	 0x80, 0x2B, 0x01, 0x00, 0xAB, 0xFF, 0x75, 0x44, 0x8D, 0xFF, 0xEA, 0x01, 0x0A, 0xF3, 0xAA, 0xFF,
+	 0x60, 0x40, 0x20, 0x2B, 0x02, 0x00, 0x60, 0xFF, 0x0D, 0x00, 0x01, 0x26, 0x0C, 0x00, 0xC0, 0x60,
+	 0x00, 0x7C, 0xA0, 0x84, 0x80, 0x3B, 0x02, 0x00, 0xC0, 0x67, 0x03, 0x00, 0x40, 0x3B, 0x02, 0x00,
+	 0x00, 0x67, 0x0A, 0xFB, 0xD5, 0x01, 0xD4, 0x01, 0xAB, 0xFF, 0x38, 0xFF, 0x00, 0x00, 0xD0, 0x01,
+	 0x79, 0x63, 0xFF, 0xFF, 0xFF, 0x1F, 0xA9, 0xFF, 0x77, 0x44, 0x60, 0x57, 0x10, 0x60, 0x00, 0x75,
+	 0x40, 0x4A, 0x01, 0x2A, 0x1C, 0x00, 0x24, 0x44, 0xAC, 0x86, 0x08, 0xF2, 0x18, 0x03, 0x24, 0x60,
+	 0x58, 0x65, 0xD4, 0x80, 0x0E, 0xF2, 0x02, 0x03, 0xA5, 0xD5, 0x04, 0x00, 0x01, 0xBC, 0x0E, 0xFA,
+	 0x09, 0xF4, 0xD1, 0xFE, 0x46, 0x44, 0x0B, 0x18, 0x66, 0x44, 0x10, 0xFB, 0x66, 0x47, 0x20, 0xBF,
+	 0x3B, 0x42, 0x04, 0xA2, 0xA2, 0xDB, 0x0E, 0xF2, 0x01, 0x75, 0x10, 0xBC, 0x0E, 0xFA, 0x2A, 0x44,
+	 0x08, 0x2A, 0x18, 0x00, 0x23, 0x44, 0x00, 0xA8, 0x5C, 0x43, 0x14, 0x03, 0x24, 0x60, 0x52, 0x62,
+	 0xA2, 0xD5, 0x01, 0x00, 0x09, 0xF4, 0x0E, 0xF2, 0x0D, 0x18, 0x08, 0xB0, 0x18, 0xAC, 0xFA, 0x03,
+	 0x0E, 0xFA, 0x66, 0x43, 0x11, 0xFD, 0x46, 0x43, 0x23, 0x47, 0x80, 0xBF, 0x3B, 0x42, 0x04, 0xA2,
+	 0xA2, 0xDB, 0x08, 0x75, 0x2A, 0x44, 0x06, 0x22, 0x2D, 0x00, 0x22, 0x44, 0x00, 0xA8, 0x60, 0x46,
+	 0x0E, 0xF2, 0x28, 0x03, 0x10, 0xB0, 0x01, 0xBC, 0x03, 0x02, 0x00, 0x64, 0x40, 0x42, 0x22, 0x00,
+	 0x0E, 0xFA, 0xD1, 0xFE, 0x24, 0x60, 0x4C, 0x64, 0x40, 0x47, 0x58, 0x4F, 0x84, 0x00, 0x46, 0x42,
+	 0x19, 0x02, 0x22, 0x47, 0x40, 0xBF, 0x3B, 0x42, 0x04, 0xA2, 0xA2, 0xDB, 0x23, 0xF2, 0x66, 0x43,
+	 0x00, 0xA8, 0x0E, 0xF2, 0x08, 0x02, 0x60, 0x40, 0x02, 0x2A, 0xE4, 0x01, 0x12, 0xFD, 0x10, 0x64,
+	 0x0E, 0xFA, 0x02, 0x75, 0x07, 0x00, 0x60, 0x40, 0x04, 0x2A, 0xDC, 0x01, 0x12, 0xFD, 0x10, 0x64,
+	 0x0E, 0xFA, 0x04, 0x75, 0x2A, 0x44, 0x80, 0x2A, 0x19, 0x00, 0x21, 0x44, 0xAC, 0x86, 0x0E, 0xF2,
+	 0x15, 0x03, 0x01, 0xBC, 0x0E, 0xFA, 0xD1, 0xFE, 0x24, 0x60, 0x64, 0x64, 0x40, 0x47, 0x58, 0x4F,
+	 0x5A, 0x00, 0x46, 0x41, 0x0B, 0x02, 0x21, 0x47, 0x10, 0xBF, 0x3B, 0x42, 0x04, 0xA2, 0xA2, 0xDB,
+	 0x0E, 0xF2, 0x66, 0x43, 0x08, 0xFD, 0x10, 0xBC, 0x0E, 0xFA, 0x80, 0x75, 0x2A, 0x44, 0x10, 0xB0,
+	 0x20, 0x44, 0x15, 0x03, 0x7F, 0xB4, 0x40, 0x40, 0x1C, 0x60, 0xB4, 0x63, 0xA3, 0xD3, 0xFF, 0xFF,
+	 0x20, 0xB0, 0x80, 0xB0, 0x09, 0x03, 0x08, 0x03, 0x40, 0xBC, 0x7F, 0xB4, 0x04, 0xB0, 0xA3, 0xDB,
+	 0x03, 0x03, 0x20, 0x44, 0x80, 0xBC, 0x40, 0x40, 0xAC, 0x60, 0xD8, 0x78, 0xFF, 0xFF, 0x2A, 0x40,
+	 0x08, 0x2B, 0x01, 0x00, 0x10, 0xFF, 0xAD, 0x60, 0x08, 0x78, 0xFF, 0xFF, 0xE8, 0xFE, 0x14, 0x05,
+	 0xEA, 0xFE, 0x24, 0x05, 0xE9, 0xFE, 0x1C, 0x05, 0xE7, 0xFE, 0x09, 0x05, 0x47, 0xFF, 0x20, 0x44,
+	 0x0F, 0x22, 0x03, 0x00, 0xCC, 0x84, 0x40, 0x40, 0x0F, 0x22, 0xB8, 0xFE, 0xEC, 0x01, 0x23, 0x41,
+	 0x00, 0xB9, 0x5C, 0x4A, 0xE8, 0x02, 0x6A, 0x01, 0x24, 0x41, 0x00, 0xB9, 0x24, 0x60, 0x58, 0x65,
+	 0x45, 0x47, 0xE1, 0x02, 0x58, 0x4F, 0x0F, 0x00, 0xDE, 0x02, 0x5C, 0x4A, 0x46, 0x44, 0x4C, 0x01,
+	 0x22, 0x41, 0x00, 0xB9, 0x5C, 0x4A, 0x08, 0x24, 0x7D, 0x01, 0xD5, 0x01, 0x21, 0x41, 0x00, 0xB9,
+	 0x5C, 0x4A, 0xA2, 0x03, 0xD0, 0x01, 0x27, 0xD3, 0x03, 0x00, 0x10, 0xB0, 0x09, 0xF2, 0x04, 0x03,
+	 0xAC, 0x86, 0x0E, 0xF2, 0xFA, 0x02, 0x08, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0E, 0xF3, 0x0F, 0x60,
+	 0xFE, 0x65, 0x0C, 0xF3, 0x24, 0x86, 0x24, 0x46, 0x60, 0x40, 0xFB, 0x3B, 0x07, 0x00, 0x80, 0x26,
+	 0x02, 0x00, 0x23, 0x46, 0x03, 0x4C, 0x46, 0x61, 0x3A, 0x65, 0x0C, 0x00, 0x2E, 0xF3, 0x40, 0x45,
+	 0xF8, 0x2B, 0x02, 0x00, 0x40, 0x45, 0x03, 0x00, 0x58, 0x4F, 0x39, 0x00, 0x07, 0x02, 0x58, 0x4F,
+	 0x45, 0x00, 0x04, 0x05, 0x66, 0x50, 0x65, 0x52, 0x61, 0x51, 0x09, 0x00, 0x26, 0x47, 0x00, 0xBF,
+	 0x0E, 0xFB, 0x2E, 0xF5, 0x05, 0xF0, 0x80, 0x60, 0x64, 0x50, 0x00, 0x72, 0x7E, 0x71, 0xAC, 0xFF,
+	 0xAD, 0x60, 0x08, 0x78, 0xFF, 0xFF, 0x8E, 0xFF, 0x0F, 0xF3, 0x0F, 0x60, 0xFE, 0x65, 0x24, 0x86,
+	 0x0D, 0xF3, 0x2E, 0xF3, 0x40, 0x45, 0xF8, 0x2B, 0x02, 0x00, 0x40, 0x45, 0x03, 0x00, 0x58, 0x4F,
+	 0x16, 0x00, 0x07, 0x02, 0x58, 0x4F, 0x22, 0x00, 0x04, 0x05, 0x66, 0x50, 0x65, 0x52, 0x61, 0x51,
+	 0x09, 0x00, 0x26, 0x47, 0x00, 0xBF, 0x0F, 0xFB, 0x2E, 0xF5, 0x05, 0xF0, 0x80, 0x60, 0x64, 0x50,
+	 0x00, 0x72, 0x7E, 0x71, 0x8D, 0xFF, 0xAD, 0xFF, 0xAD, 0x60, 0x08, 0x78, 0xFF, 0xFF, 0x25, 0x44,
+	 0xAA, 0xF1, 0xAB, 0xF1, 0xD0, 0x80, 0xD0, 0x80, 0x07, 0x04, 0x01, 0x06, 0x05, 0x00, 0x25, 0x46,
+	 0x01, 0xF0, 0x03, 0x67, 0xA0, 0x85, 0x94, 0x80, 0x2F, 0x58, 0xFF, 0xFF, 0x25, 0x46, 0x26, 0x41,
+	 0x46, 0x63, 0x01, 0xF2, 0xFF, 0xFF, 0xFF, 0xB5, 0xD5, 0x81, 0x00, 0xF2, 0x05, 0x04, 0x04, 0x63,
+	 0x60, 0x46, 0xF7, 0x1B, 0x42, 0xFE, 0x0D, 0x00, 0x61, 0x44, 0xC5, 0x81, 0x63, 0x45, 0xC5, 0x81,
+	 0x9C, 0x84, 0xDC, 0x84, 0x01, 0xF2, 0xF0, 0x85, 0xF0, 0x80, 0x65, 0x44, 0xF8, 0x85, 0xFF, 0xFF,
+	 0x02, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0xA2, 0xFF, 0x24, 0x60, 0x6A, 0x62, 0xA2, 0xD3, 0xFF, 0xFF,
+	 0xAC, 0x86, 0x0E, 0xF2, 0x07, 0x03, 0x00, 0xA8, 0x09, 0xF2, 0xFA, 0x02, 0x01, 0x67, 0x0E, 0xFA,
+	 0x08, 0xFE, 0x17, 0x00, 0xAC, 0xF3, 0xFF, 0xFF, 0xD8, 0xA0, 0x00, 0xB4, 0x12, 0x06, 0x09, 0x60,
+	 0x08, 0x61, 0x41, 0x4A, 0x7C, 0xA1, 0x0E, 0xA1, 0xA2, 0xFF, 0xAE, 0x60, 0x58, 0x4E, 0xE4, 0x78,
+	 0xFF, 0xFF, 0xA3, 0xFF, 0x06, 0x03, 0x2A, 0x43, 0xAF, 0x60, 0x58, 0x4E, 0x05, 0x78, 0xFF, 0xFF,
+	 0x08, 0xFE, 0xA3, 0xFF, 0x2D, 0x58, 0xFF, 0xFF, 0x41, 0x4A, 0x7C, 0xA1, 0x0E, 0xA1, 0xA2, 0xFF,
+	 0xAE, 0x60, 0x58, 0x4E, 0xE4, 0x78, 0xFF, 0xFF, 0x07, 0x03, 0x2A, 0x43, 0xAF, 0x60, 0x58, 0x4E,
+	 0x05, 0x78, 0xFF, 0xFF, 0x08, 0xFE, 0x0D, 0x00, 0x24, 0x60, 0x6A, 0x62, 0xA2, 0xD3, 0xFF, 0xFF,
+	 0xAC, 0x86, 0x0E, 0xF2, 0x06, 0x03, 0x00, 0xA8, 0x09, 0xF2, 0xFA, 0x02, 0x01, 0x67, 0x0E, 0xFA,
+	 0x08, 0xFE, 0xA3, 0xFF, 0x2D, 0x58, 0xFF, 0xFF, 0xAD, 0xF3, 0x7C, 0x63, 0x00, 0xBE, 0x40, 0x45,
+	 0x1A, 0x03, 0x00, 0x65, 0x65, 0x44, 0xDC, 0x85, 0x84, 0xA1, 0x00, 0xF2, 0x06, 0x06, 0x01, 0xFC,
+	 0x00, 0xA8, 0x60, 0x46, 0xF7, 0x02, 0x40, 0x45, 0x0E, 0x00, 0xAC, 0xF3, 0x00, 0x63, 0xD4, 0x84,
+	 0xAC, 0xFB, 0x80, 0x60, 0x7C, 0x64, 0x01, 0xFA, 0x00, 0xF0, 0x00, 0xFC, 0xD3, 0x80, 0xAD, 0xF9,
+	 0x02, 0x02, 0xAE, 0xF9, 0x08, 0xFE, 0x2E, 0x58, 0xFF, 0xFF, 0x66, 0x44, 0x25, 0x46, 0x05, 0xFA,
+	 0x06, 0xFA, 0x01, 0xF0, 0x03, 0x67, 0x02, 0xFC, 0xB0, 0x84, 0x3A, 0x7E, 0x01, 0xFA, 0x12, 0x64,
+	 0x03, 0xFA, 0x00, 0xF0, 0x04, 0xF8, 0x00, 0x64, 0x0C, 0x61, 0x10, 0x63, 0x59, 0xDA, 0xFE, 0x1F,
+	 0x2E, 0x58, 0xFF, 0xFF, 0x27, 0x43, 0xE3, 0x81, 0xE9, 0x81, 0x03, 0x05, 0x16, 0x03, 0x00, 0x61,
+	 0x01, 0x00, 0xE4, 0x63, 0x61, 0x46, 0xBF, 0xD2, 0x27, 0x45, 0xDC, 0x84, 0xA2, 0xDA, 0xBE, 0xD2,
+	 0x25, 0x46, 0x88, 0xF8, 0x04, 0x1B, 0x25, 0x44, 0x61, 0x46, 0xA3, 0xDA, 0x04, 0x00, 0x0A, 0xFA,
+	 0x60, 0x46, 0x25, 0x44, 0x09, 0xFA, 0x61, 0x46, 0xBE, 0xDA, 0x2F, 0x58, 0xFF, 0xFF, 0x25, 0x44,
+	 0x00, 0xA8, 0x07, 0x4B, 0x0C, 0x03, 0x58, 0x4F, 0x33, 0x00, 0x0B, 0x47, 0x24, 0x60, 0x5E, 0x65,
+	 0x27, 0x44, 0xD4, 0x80, 0x00, 0x64, 0x01, 0x02, 0x0F, 0xFA, 0x58, 0x4F, 0xD3, 0x01, 0x70, 0x00,
+	 0x25, 0x43, 0xE3, 0x84, 0x7C, 0x41, 0x02, 0x04, 0xE8, 0x81, 0xE4, 0x63, 0x61, 0x46, 0xA3, 0xD2,
+	 0x00, 0x7C, 0x40, 0x45, 0xBF, 0xD8, 0xA3, 0xD8, 0xBE, 0xD8, 0x27, 0x42, 0x5A, 0xD3, 0x25, 0x5C,
+	 0x60, 0x41, 0x02, 0x1B, 0x27, 0xD9, 0x05, 0x00, 0x25, 0x46, 0x0A, 0xFA, 0x61, 0x46, 0x25, 0x44,
+	 0x09, 0xFA, 0x25, 0x44, 0x27, 0x43, 0x00, 0x61, 0x60, 0x46, 0x09, 0xF2, 0x08, 0xFC, 0x00, 0xA8,
+	 0xDD, 0x81, 0xFA, 0x02, 0xBF, 0xD1, 0x66, 0x44, 0xBE, 0xDB, 0xC1, 0x84, 0xBF, 0xDB, 0x48, 0x00,
+	 0x25, 0x46, 0xE4, 0x63, 0x08, 0xF2, 0x89, 0xF2, 0x1E, 0x18, 0x40, 0x47, 0xE0, 0x84, 0xE8, 0x85,
+	 0x02, 0x05, 0xE8, 0x83, 0x00, 0x65, 0x65, 0x46, 0xBF, 0xD2, 0x61, 0x5C, 0xCC, 0x84, 0xA2, 0xDA,
+	 0x25, 0x46, 0x0A, 0xF2, 0x00, 0xB9, 0x65, 0x46, 0x08, 0x24, 0xBE, 0xDA, 0x02, 0x1B, 0xA3, 0xD8,
+	 0x02, 0x00, 0x60, 0x46, 0x89, 0xFA, 0x00, 0xB9, 0x61, 0x46, 0x08, 0x28, 0x0A, 0xFA, 0x25, 0x46,
+	 0x89, 0xFC, 0x8A, 0xFC, 0x88, 0xFC, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x61, 0x28, 0x65, 0x25, 0x43,
+	 0xAE, 0xF3, 0xAF, 0x83, 0x00, 0xBE, 0x18, 0x03, 0x02, 0x03, 0x00, 0xFC, 0x01, 0x00, 0xAD, 0xFD,
+	 0x63, 0x46, 0x65, 0x44, 0xCC, 0x85, 0x00, 0xF2, 0x07, 0x02, 0xAE, 0xF5, 0x00, 0x64, 0x00, 0xFA,
+	 0xDE, 0x60, 0xAF, 0x64, 0x09, 0xFB, 0x08, 0x00, 0x66, 0x43, 0x00, 0xBE, 0xDD, 0x81, 0xF1, 0x02,
+	 0xAC, 0xF1, 0xAE, 0xFD, 0xC1, 0x84, 0xAC, 0xFB, 0x2E, 0x58, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x45,
+	 0x29, 0x43, 0xFC, 0xA3, 0x66, 0x44, 0xBD, 0xDB, 0x25, 0x44, 0xBD, 0xDB, 0x00, 0x64, 0xBD, 0xDB,
+	 0x03, 0x61, 0x0E, 0x65, 0x24, 0x60, 0x72, 0x63, 0x43, 0x49, 0xA3, 0xD3, 0x06, 0xA3, 0x00, 0xA8,
+	 0xCD, 0x81, 0x04, 0x02, 0xF9, 0x02, 0xAD, 0x60, 0x08, 0x78, 0xFF, 0xFF, 0x01, 0x26, 0xE6, 0x01,
+	 0xD4, 0x80, 0x60, 0x45, 0xE3, 0x05, 0xF6, 0xA3, 0xBD, 0xD1, 0xBD, 0xD1, 0x44, 0x47, 0x44, 0x48,
+	 0x44, 0x45, 0x24, 0x60, 0xB0, 0x64, 0x44, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0x24, 0x60, 0x22, 0x63,
+	 0x0D, 0x65, 0x00, 0x61, 0x41, 0x48, 0xA3, 0xD3, 0x06, 0xA3, 0xAC, 0x86, 0x00, 0x61, 0x09, 0x03,
+	 0x00, 0xF2, 0x09, 0xF0, 0xAC, 0x86, 0x00, 0xF2, 0xDD, 0x81, 0xFC, 0x02, 0x64, 0x44, 0xAC, 0x86,
+	 0xF6, 0x01, 0x61, 0x44, 0x25, 0x46, 0x27, 0xDA, 0x65, 0x44, 0x28, 0x45, 0x45, 0x88, 0xCC, 0x85,
+	 0x5A, 0x87, 0xE9, 0x02, 0x00, 0x64, 0x27, 0xDA, 0x5A, 0xDA, 0x5A, 0x87, 0xA9, 0xF3, 0xA8, 0xF1,
+	 0x02, 0xA4, 0x60, 0x46, 0x60, 0x45, 0x00, 0x61, 0x1E, 0xF2, 0xFF, 0xFF, 0xAC, 0x86, 0x00, 0xF2,
+	 0x04, 0x03, 0xAC, 0x86, 0x00, 0xF2, 0xDD, 0x81, 0xFC, 0x02, 0x65, 0x44, 0x02, 0xA5, 0x65, 0x46,
+	 0x64, 0x44, 0xCC, 0x9C, 0xFF, 0xFF, 0xF0, 0x02, 0x61, 0x44, 0x25, 0x46, 0x27, 0xDA, 0x5A, 0x87,
+	 0x28, 0x45, 0x45, 0x88, 0x00, 0x64, 0x27, 0xDA, 0x5A, 0x87, 0x06, 0x60, 0x40, 0x65, 0xAD, 0xF3,
+	 0x01, 0x61, 0xAC, 0x86, 0x00, 0xF2, 0x03, 0x03, 0xD5, 0x80, 0xDD, 0x81, 0xFA, 0x04, 0xCD, 0x84,
+	 0x25, 0x46, 0x27, 0xDA, 0x28, 0x45, 0xC4, 0x84, 0x5A, 0xDA, 0xDA, 0x81, 0xAC, 0xF1, 0x59, 0xD8,
+	 0x24, 0x60, 0x20, 0x64, 0x18, 0x63, 0xA0, 0xD1, 0x06, 0xA4, 0x59, 0xD8, 0xFC, 0x1F, 0x00, 0x64,
+	 0x59, 0xDA, 0x59, 0xDA, 0x01, 0x60, 0x5C, 0x64, 0x0A, 0x63, 0x58, 0xD1, 0x59, 0xD8, 0xFD, 0x1F,
+	 0xDC, 0xF1, 0x59, 0xD8, 0x75, 0x01, 0x07, 0x4B, 0xAF, 0x60, 0x58, 0x4F, 0x70, 0x78, 0xFF, 0xFF,
+	 0x0B, 0x47, 0x58, 0x4F, 0x21, 0x00, 0x6C, 0x01, 0x07, 0x4B, 0xAF, 0x60, 0x58, 0x4F, 0x70, 0x78,
+	 0xFF, 0xFF, 0x0B, 0x47, 0x27, 0x44, 0x00, 0xBE, 0x08, 0xF0, 0x15, 0x03, 0x64, 0x42, 0x4A, 0xD3,
+	 0x09, 0xF2, 0xDC, 0x83, 0xA2, 0xDD, 0x25, 0x43, 0x09, 0xFC, 0x63, 0x46, 0x27, 0x43, 0x0A, 0xFC,
+	 0x09, 0xFA, 0x08, 0xF8, 0x00, 0xA8, 0x66, 0x43, 0x03, 0x02, 0x64, 0x44, 0x58, 0xDD, 0x03, 0x00,
+	 0x60, 0x46, 0x25, 0x44, 0x0A, 0xFA, 0x4C, 0x01, 0x27, 0x43, 0xE3, 0x81, 0xE9, 0x81, 0x03, 0x05,
+	 0x16, 0x03, 0x00, 0x61, 0x01, 0x00, 0xE4, 0x63, 0x61, 0x46, 0xBF, 0xD2, 0x27, 0x45, 0xDC, 0x84,
+	 0xA2, 0xDA, 0xA3, 0xD2, 0x25, 0x46, 0x88, 0xF8, 0x04, 0x1B, 0x25, 0x44, 0x61, 0x46, 0xBE, 0xDA,
+	 0x04, 0x00, 0x09, 0xFA, 0x60, 0x46, 0x25, 0x44, 0x0A, 0xFA, 0x61, 0x46, 0xA3, 0xDA, 0x2F, 0x58,
+	 0xFF, 0xFF, 0xA0, 0xFE, 0x07, 0x05, 0xA3, 0xFE, 0x07, 0x05, 0xA1, 0xFE, 0x52, 0x05, 0x60, 0x64,
+	 0x3B, 0xDB, 0x12, 0x00, 0x20, 0x58, 0xFF, 0xFF, 0x4F, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0x1C, 0x60,
+	 0xB8, 0x63, 0xA3, 0xD3, 0xFF, 0xFF, 0xFB, 0xB4, 0xA3, 0xDB, 0xA0, 0x4C, 0x59, 0xBC, 0xFF, 0xB4,
+	 0xA0, 0x51, 0xA0, 0x4C, 0x7D, 0xB4, 0xA0, 0x51, 0xA1, 0xFF, 0xFF, 0xFF, 0x83, 0x3E, 0x40, 0x60,
+	 0x0B, 0x65, 0x2B, 0x44, 0x00, 0x63, 0xE8, 0x80, 0xF8, 0x84, 0x02, 0x24, 0x94, 0x84, 0xF3, 0x83,
+	 0xCD, 0x81, 0xFF, 0xFF, 0xF8, 0x02, 0xDF, 0x83, 0x2F, 0x58, 0x40, 0x4B, 0x00, 0x62, 0x01, 0x64,
+	 0xD4, 0x80, 0xE0, 0x84, 0x1A, 0x03, 0xD4, 0x80, 0xE0, 0x84, 0x15, 0x03, 0x61, 0x44, 0x11, 0x61,
+	 0xE0, 0x84, 0xCD, 0x81, 0xFD, 0x04, 0x01, 0x00, 0xE0, 0x84, 0xF2, 0x82, 0xFF, 0xFF, 0x02, 0x24,
+	 0xC6, 0x82, 0x02, 0x28, 0xD6, 0x82, 0xE2, 0x80, 0xCD, 0x81, 0x02, 0x28, 0x01, 0xBC, 0xF4, 0x02,
+	 0x01, 0x2A, 0xC6, 0x82, 0x03, 0x00, 0xE9, 0x81, 0xF2, 0x82, 0x61, 0x44, 0x2D, 0x58, 0xFF, 0xFF,
+	 0x00, 0xA8, 0x10, 0x61, 0x04, 0x03, 0xF0, 0x84, 0xCD, 0x81, 0xFD, 0x04, 0x61, 0x44, 0x2D, 0x58,
+	 0xFF, 0xFF, 0x00, 0x64, 0x3B, 0xDB, 0x3C, 0x44, 0xAC, 0x80, 0xFF, 0xFF, 0xBD, 0x02, 0x8B, 0xF3,
+	 0x8C, 0xF3, 0x02, 0xA8, 0x02, 0xA8, 0x08, 0x02, 0x00, 0x64, 0x8D, 0xFB, 0x8B, 0xFB, 0x8C, 0xFB,
+	 0x00, 0x64, 0x8E, 0xFB, 0xCA, 0xFE, 0x2D, 0x00, 0x03, 0x02, 0x00, 0x64, 0x8C, 0xFB, 0xCA, 0xFE,
+	 0x01, 0x64, 0x3B, 0xDB, 0x24, 0x60, 0x28, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46,
+	 0x14, 0x03, 0xDC, 0xF3, 0x2A, 0xF2, 0xFD, 0xA0, 0x60, 0x40, 0x80, 0x3A, 0x29, 0x00, 0x28, 0x02,
+	 0x9B, 0xFE, 0x26, 0x05, 0x24, 0x60, 0x6E, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xE5, 0x01, 0x8C, 0xF3, 0xFF, 0xFF, 0x01, 0xA8,
+	 0xFF, 0xFF, 0x07, 0x02, 0x24, 0x60, 0x22, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46,
+	 0x0F, 0x02, 0x86, 0xFF, 0x20, 0x40, 0x52, 0x27, 0x07, 0x00, 0x9A, 0xFE, 0x05, 0x04, 0x9D, 0xFE,
+	 0x03, 0x04, 0xF1, 0xFE, 0x12, 0x64, 0x3B, 0xDB, 0x84, 0xFF, 0xB0, 0x60, 0x97, 0x78, 0xFF, 0xFF,
+	 0x66, 0x44, 0xFC, 0xFB, 0x46, 0x5C, 0x2D, 0x60, 0x5A, 0x63, 0xA3, 0xD3, 0xB0, 0x60, 0x58, 0x4D,
+	 0xD8, 0x78, 0xFF, 0xFF, 0x0D, 0xF2, 0x60, 0x5C, 0x64, 0x5F, 0x0D, 0xFA, 0x11, 0x64, 0x3B, 0xDB,
+	 0x9D, 0xFE, 0x0B, 0x05, 0x24, 0x60, 0x92, 0x65, 0x08, 0x64, 0xA5, 0xDB, 0xB1, 0x60, 0x4D, 0x64,
+	 0x4F, 0xFB, 0x2D, 0xFF, 0xB0, 0x60, 0xA4, 0x78, 0xFF, 0xFF, 0x07, 0xF0, 0x00, 0x64, 0xD0, 0x80,
+	 0xA9, 0xF3, 0x07, 0x02, 0x23, 0xF0, 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDA, 0xB8, 0x60, 0x36, 0x78,
+	 0xFF, 0xFF, 0xD0, 0x80, 0xD8, 0xF3, 0x40, 0x03, 0x60, 0x40, 0x03, 0x3A, 0x3D, 0x00, 0x66, 0x41,
+	 0x64, 0x46, 0x6F, 0xF2, 0x61, 0x46, 0x64, 0x41, 0x4D, 0xF1, 0x60, 0x40, 0x03, 0x3A, 0x34, 0x00,
+	 0x64, 0x40, 0xFF, 0x22, 0x31, 0x00, 0x05, 0x7E, 0x66, 0x45, 0x61, 0x46, 0x6F, 0xFA, 0x65, 0x46,
+	 0x07, 0xF0, 0x00, 0x65, 0x65, 0x43, 0x66, 0x41, 0x64, 0x46, 0x70, 0xF2, 0x8C, 0xFA, 0x00, 0xA8,
+	 0x6F, 0xF2, 0x15, 0x03, 0x60, 0x47, 0xFF, 0xB5, 0x70, 0xF2, 0x00, 0xBB, 0xFF, 0xA0, 0x07, 0x03,
+	 0x0E, 0x06, 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0x02, 0x02, 0xFB, 0x04, 0x08, 0x00, 0xB9, 0x81,
+	 0xE8, 0x84, 0xD9, 0x81, 0xFD, 0x04, 0x0F, 0x60, 0xA2, 0x65, 0x45, 0xD3, 0x0E, 0xFA, 0x0C, 0xF4,
+	 0xFF, 0xFF, 0x00, 0x64, 0x4D, 0xFB, 0x4C, 0xFB, 0x07, 0xF0, 0x66, 0x41, 0x64, 0x46, 0x0E, 0xF2,
+	 0x61, 0x46, 0xFF, 0xFF, 0xF0, 0x7E, 0x4E, 0xFB, 0x2A, 0xF2, 0x00, 0x63, 0x40, 0x47, 0x50, 0x36,
+	 0x05, 0x00, 0xA4, 0x36, 0x03, 0x00, 0x80, 0x36, 0x01, 0x00, 0x01, 0x63, 0x48, 0xFD, 0x40, 0x47,
+	 0x08, 0x2A, 0x0A, 0x00, 0x03, 0x2F, 0x08, 0x00, 0x81, 0xF1, 0x2C, 0xF8, 0x82, 0xF1, 0xFF, 0xFF,
+	 0x2D, 0xF8, 0x83, 0xF1, 0x2E, 0xF8, 0xFF, 0xFF, 0x4A, 0xF3, 0x35, 0xFA, 0x10, 0xA4, 0x4A, 0xFB,
+	 0x00, 0x64, 0x15, 0xFA, 0x16, 0xFA, 0x0F, 0xFA, 0xFF, 0xFF, 0x07, 0xF0, 0x66, 0x43, 0x64, 0x46,
+	 0x0E, 0xF0, 0x63, 0x46, 0x00, 0x7F, 0x64, 0x5E, 0x4B, 0xFB, 0x64, 0x44, 0x00, 0x7E, 0xDB, 0xFB,
+	 0x07, 0xF0, 0xA9, 0xF3, 0xFF, 0xFF, 0xD0, 0x80, 0xFF, 0xFF, 0x03, 0x03, 0xDB, 0xF3, 0xDA, 0xFB,
+	 0x60, 0x41, 0x03, 0xF2, 0x00, 0xF4, 0x01, 0xF2, 0xFC, 0xA5, 0x00, 0x7F, 0xD4, 0x84, 0x27, 0x45,
+	 0x3C, 0x46, 0x1A, 0xFA, 0x22, 0x63, 0x7B, 0x60, 0xFF, 0x64, 0xA4, 0x84, 0x03, 0x2B, 0x1C, 0x63,
+	 0x2A, 0xFA, 0x60, 0x40, 0xA4, 0x36, 0x14, 0x63, 0x43, 0x4C, 0x00, 0x7C, 0x22, 0xF8, 0x64, 0x41,
+	 0x07, 0xF0, 0x66, 0x43, 0x64, 0x46, 0x36, 0xF2, 0x63, 0x46, 0xFF, 0xB4, 0x22, 0xFA, 0x60, 0x40,
+	 0x00, 0x36, 0x76, 0x00, 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x08, 0x3A, 0xA5, 0x00, 0x03, 0xF2,
+	 0x00, 0xF4, 0xA0, 0xD2, 0xAA, 0x60, 0xAA, 0x65, 0x5A, 0xD0, 0xD4, 0x80, 0x03, 0x64, 0x0A, 0x02,
+	 0xD0, 0x80, 0x00, 0x64, 0x5A, 0xD0, 0x06, 0x02, 0xD0, 0x80, 0xF8, 0x7F, 0xD0, 0x80, 0x01, 0x03,
+	 0x01, 0x02, 0x01, 0x61, 0x62, 0x43, 0x46, 0x43, 0x3C, 0x46, 0x07, 0xF4, 0x36, 0xF2, 0xFF, 0xFF,
+	 0xA3, 0x46, 0x60, 0x40, 0x22, 0x26, 0x5C, 0x00, 0x60, 0x45, 0x63, 0x42, 0x5A, 0xD0, 0xCD, 0x81,
+	 0x3C, 0x46, 0x14, 0x02, 0x64, 0x44, 0x88, 0x3A, 0x11, 0x00, 0x8E, 0x3B, 0x0F, 0x00, 0x65, 0x44,
+	 0x01, 0x26, 0x7A, 0x00, 0x04, 0x26, 0x03, 0x00, 0x10, 0x26, 0x01, 0x00, 0x2D, 0x00, 0xA3, 0x46,
+	 0x37, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x80, 0x2B, 0x6F, 0x00, 0x56, 0x00, 0xA3, 0x46, 0x65, 0x44,
+	 0x01, 0x26, 0x0B, 0x00, 0x04, 0x26, 0x03, 0x00, 0x10, 0x26, 0x01, 0x00, 0x1D, 0x00, 0x37, 0xF2,
+	 0xFF, 0xFF, 0x60, 0x40, 0x80, 0x27, 0x48, 0x00, 0x17, 0x00, 0xA9, 0xF3, 0xFF, 0xFF, 0x60, 0x46,
+	 0x36, 0xF2, 0x66, 0x43, 0xFF, 0xB4, 0x3C, 0x46, 0x22, 0xF0, 0x60, 0x47, 0xB0, 0x84, 0x22, 0xFA,
+	 0x63, 0x46, 0x37, 0xF0, 0x60, 0x40, 0x04, 0x27, 0x03, 0x00, 0x10, 0x27, 0x01, 0x00, 0x04, 0x00,
+	 0x64, 0x40, 0x80, 0x27, 0x31, 0x00, 0x00, 0x00, 0x3C, 0x46, 0x02, 0x65, 0xB7, 0x60, 0x66, 0x78,
+	 0xFF, 0xFF, 0xCD, 0x81, 0x63, 0x42, 0x5A, 0xD0, 0x3C, 0x46, 0x26, 0x02, 0x64, 0x44, 0x88, 0x3A,
+	 0x23, 0x00, 0x77, 0x37, 0x39, 0x00, 0x78, 0x37, 0x37, 0x00, 0x8E, 0x37, 0x35, 0x00, 0xF1, 0x01,
+	 0x2D, 0x60, 0x52, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x2A, 0x2D, 0x00, 0x07, 0x00,
+	 0x2D, 0x60, 0x52, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x2A, 0xE2, 0x01, 0x3C, 0x46,
+	 0x3E, 0xF2, 0x40, 0x60, 0x00, 0x65, 0xF0, 0x84, 0xA4, 0x84, 0x18, 0xFA, 0x2A, 0xF2, 0xBF, 0x60,
+	 0xFF, 0x65, 0xA4, 0x84, 0x2A, 0xFA, 0x18, 0x00, 0x3C, 0x46, 0x22, 0xF0, 0x80, 0x67, 0xB0, 0x84,
+	 0xA2, 0xDA, 0xFF, 0xFF, 0x3F, 0xF2, 0x3E, 0xF0, 0x08, 0xA4, 0x60, 0x41, 0x22, 0xF2, 0xFF, 0xFF,
+	 0x60, 0x40, 0x01, 0x26, 0x03, 0x00, 0x04, 0x26, 0x03, 0x00, 0x06, 0x00, 0x04, 0x2B, 0x04, 0x00,
+	 0x61, 0x44, 0x64, 0x40, 0x10, 0x26, 0x3F, 0xFA, 0x3C, 0x46, 0x2C, 0xF2, 0x27, 0x40, 0x01, 0x27,
+	 0x32, 0xF2, 0xD5, 0xF1, 0x60, 0x40, 0x01, 0x26, 0x53, 0x00, 0x09, 0x60, 0x00, 0x64, 0xD0, 0x80,
+	 0x3F, 0xF2, 0x09, 0x06, 0x2C, 0x45, 0xC4, 0x84, 0xD0, 0x80, 0x40, 0x4A, 0x40, 0x06, 0x60, 0x43,
+	 0x64, 0x44, 0x54, 0x88, 0x18, 0x00, 0x60, 0x45, 0x28, 0x60, 0x36, 0x64, 0xA0, 0xD3, 0xDB, 0xF3,
+	 0x00, 0xBC, 0x60, 0x47, 0xEC, 0xA0, 0x33, 0x03, 0x32, 0x07, 0x2C, 0x44, 0xC4, 0x81, 0x02, 0x60,
+	 0x1C, 0x65, 0x45, 0x4A, 0xD5, 0x80, 0x2C, 0x45, 0x2A, 0x06, 0x27, 0x40, 0x04, 0x27, 0x30, 0x00,
+	 0x2A, 0x43, 0xD7, 0x85, 0x45, 0x48, 0xD6, 0xF1, 0x0F, 0xF2, 0xD3, 0x80, 0x01, 0x65, 0x01, 0x07,
+	 0x00, 0x65, 0xB4, 0x84, 0x0F, 0xFA, 0x00, 0x63, 0x3F, 0xF2, 0x28, 0x45, 0x60, 0x41, 0xD4, 0x84,
+	 0xDF, 0x83, 0xFC, 0x07, 0x14, 0xFC, 0x61, 0x44, 0x01, 0x36, 0x02, 0x00, 0x09, 0x3A, 0x06, 0x00,
+	 0x28, 0x44, 0x48, 0x88, 0x2A, 0x44, 0xC8, 0x83, 0x43, 0x4A, 0xE5, 0x01, 0x17, 0xFA, 0x04, 0x60,
+	 0x00, 0x64, 0x27, 0x45, 0xB4, 0x84, 0x2A, 0xFA, 0x28, 0x43, 0x16, 0xFC, 0x0D, 0x00, 0x3F, 0xF2,
+	 0x2C, 0x45, 0xD6, 0xF1, 0xC4, 0x81, 0xD1, 0x80, 0x0F, 0xF2, 0x01, 0x06, 0x01, 0xBC, 0x0F, 0xFA,
+	 0x3F, 0xF2, 0x17, 0xFA, 0x01, 0x64, 0x14, 0xFA, 0x07, 0xF0, 0x66, 0x43, 0x64, 0x46, 0x0E, 0xF0,
+	 0x63, 0x46, 0x00, 0x7F, 0x64, 0x5E, 0x4B, 0xFB, 0x64, 0x44, 0x00, 0x7E, 0xDB, 0xFB, 0x7C, 0xF1,
+	 0x60, 0x43, 0x60, 0x47, 0xD0, 0x80, 0xC0, 0x65, 0x01, 0x06, 0x64, 0x44, 0x0A, 0x36, 0x70, 0x64,
+	 0x14, 0x36, 0x38, 0x64, 0x37, 0x36, 0x15, 0x64, 0x6E, 0x36, 0x0B, 0x64, 0x44, 0x86, 0x2A, 0xF2,
+	 0x07, 0xF0, 0x60, 0x40, 0xB0, 0x3A, 0x03, 0x00, 0x40, 0x3B, 0x01, 0x00, 0x12, 0x00, 0x0C, 0xB4,
+	 0x08, 0x3A, 0x55, 0x00, 0x22, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x80, 0x2B, 0x50, 0x00, 0x17, 0xF2,
+	 0x22, 0xF0, 0xFF, 0xFF, 0x64, 0x40, 0x22, 0x22, 0x04, 0x00, 0x00, 0xA8, 0x01, 0xA8, 0x47, 0x03,
+	 0x46, 0x03, 0x3C, 0x46, 0x2A, 0xF0, 0x40, 0x67, 0xB0, 0x84, 0xA2, 0xDA, 0x60, 0x45, 0x22, 0xF2,
+	 0xFF, 0xFF, 0x60, 0x43, 0x60, 0x40, 0x01, 0x26, 0x03, 0x00, 0x04, 0x26, 0x0A, 0x00, 0x02, 0x00,
+	 0x04, 0x27, 0x07, 0x00, 0x65, 0x44, 0x2A, 0x65, 0x60, 0x40, 0x03, 0x2B, 0x24, 0x65, 0x45, 0x4C,
+	 0x2E, 0x00, 0x65, 0x44, 0x2E, 0x65, 0x60, 0x40, 0x03, 0x2B, 0x28, 0x65, 0x45, 0x4C, 0x07, 0xF0,
+	 0xA9, 0xF3, 0xFF, 0xFF, 0xD0, 0x80, 0x00, 0x7C, 0x03, 0x03, 0x63, 0x40, 0x01, 0x2A, 0x01, 0x00,
+	 0x3D, 0xF1, 0x2A, 0xF2, 0xFF, 0xFF, 0x08, 0xB0, 0x3E, 0xF2, 0x19, 0x03, 0x60, 0x47, 0xE8, 0x84,
+	 0xE8, 0x84, 0xE8, 0x84, 0x03, 0xB4, 0xD0, 0x80, 0xFF, 0xFF, 0x11, 0x03, 0x24, 0x60, 0x6E, 0x62,
+	 0x24, 0x60, 0x46, 0x64, 0xA2, 0xDB, 0x3C, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0x5C, 0x5C, 0xFC, 0xFC, 0xCE, 0xFE, 0xB0, 0x60, 0xE1, 0x78, 0xFF, 0xFF, 0xDB, 0xF1,
+	 0x2C, 0x45, 0x64, 0x43, 0x17, 0xF2, 0x4B, 0xF1, 0xC4, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x81,
+	 0x63, 0x40, 0x37, 0x37, 0xE1, 0x81, 0x64, 0x45, 0xB0, 0x60, 0x58, 0x4D, 0xB6, 0x78, 0xFF, 0xFF,
+	 0xAE, 0x82, 0xFC, 0xA2, 0x0A, 0x03, 0x63, 0x40, 0x6E, 0x3B, 0x06, 0x00, 0x60, 0x41, 0x04, 0x0D,
+	 0x63, 0x44, 0x80, 0x7E, 0xDB, 0xFB, 0x61, 0x44, 0xDC, 0x84, 0x2B, 0xF0, 0x1B, 0xFA, 0x64, 0x44,
+	 0x80, 0x27, 0x34, 0x00, 0x16, 0xF2, 0x0F, 0xF0, 0xAC, 0x84, 0x2C, 0x45, 0x29, 0x03, 0x4B, 0xF1,
+	 0xC4, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x81, 0x63, 0x40, 0x37, 0x37, 0xE1, 0x81, 0x64, 0x45,
+	 0x0F, 0xF0, 0xB0, 0x60, 0x58, 0x4D, 0xB6, 0x78, 0xFF, 0xFF, 0xAE, 0x82, 0xFC, 0xA2, 0x0A, 0x03,
+	 0x63, 0x40, 0x6E, 0x3B, 0x06, 0x00, 0x60, 0x41, 0x04, 0x0D, 0x80, 0x67, 0xB0, 0x84, 0x0F, 0xFA,
+	 0x61, 0x44, 0xDC, 0x84, 0x1D, 0xFA, 0xDE, 0x65, 0xC4, 0x85, 0x26, 0x41, 0xE1, 0x81, 0xC5, 0x84,
+	 0x2B, 0xFA, 0x1B, 0xF0, 0xDE, 0x64, 0xC0, 0x85, 0x26, 0x44, 0xE0, 0x84, 0xC4, 0x84, 0x10, 0xFA,
+	 0x26, 0x44, 0x2C, 0xF0, 0x0A, 0xA4, 0x64, 0x40, 0x01, 0x26, 0x00, 0x64, 0x11, 0xFA, 0xDB, 0xF3,
+	 0x13, 0xFA, 0xFF, 0xFF, 0x0D, 0xF2, 0x3E, 0xF0, 0x60, 0x47, 0xFF, 0xB4, 0x64, 0x41, 0x01, 0xB1,
+	 0x01, 0x63, 0x1D, 0x02, 0x60, 0x41, 0xFF, 0x22, 0x04, 0x00, 0xB0, 0x60, 0x58, 0x4F, 0xA7, 0x78,
+	 0xFF, 0xFF, 0x0F, 0x60, 0x92, 0x64, 0xA0, 0xDD, 0x2D, 0x60, 0x5A, 0x62, 0xA2, 0xD3, 0xB0, 0x60,
+	 0x58, 0x4D, 0xD8, 0x78, 0xFF, 0xFF, 0x60, 0x41, 0x01, 0x63, 0x61, 0x40, 0xFF, 0x22, 0x04, 0x00,
+	 0xB0, 0x60, 0x58, 0x4F, 0xA7, 0x78, 0xFF, 0xFF, 0x0F, 0x60, 0x94, 0x64, 0xA0, 0xDD, 0x2A, 0xF2,
+	 0xFF, 0xFF, 0x60, 0x40, 0x40, 0x27, 0x03, 0x00, 0xB5, 0x60, 0x19, 0x78, 0xFF, 0xFF, 0x22, 0xF2,
+	 0x46, 0x43, 0x60, 0x40, 0x22, 0x26, 0x8B, 0x00, 0x01, 0x26, 0x05, 0x00, 0x04, 0x26, 0x0C, 0x00,
+	 0xB5, 0x60, 0x19, 0x78, 0xFF, 0xFF, 0x04, 0x27, 0x03, 0x00, 0xB5, 0x60, 0x19, 0x78, 0xFF, 0xFF,
+	 0xA9, 0xF3, 0xFF, 0xFF, 0x60, 0x46, 0x02, 0x00, 0x07, 0xF4, 0xFF, 0xFF, 0xA3, 0x46, 0x2A, 0xF2,
+	 0xA3, 0x46, 0x60, 0x40, 0x08, 0x27, 0x3B, 0x00, 0xA9, 0xF3, 0x66, 0x5C, 0xD0, 0x80, 0x37, 0xF0,
+	 0x08, 0x03, 0x64, 0x40, 0x10, 0x2A, 0x12, 0x00, 0xFF, 0x60, 0xEF, 0x64, 0xA0, 0x84, 0x37, 0xFA,
+	 0x24, 0x00, 0x3D, 0xF3, 0x01, 0x61, 0x60, 0x43, 0xCF, 0x83, 0xE1, 0x81, 0xFD, 0x0D, 0xE9, 0x81,
+	 0xA1, 0x80, 0xFF, 0xFF, 0x03, 0x03, 0x91, 0x84, 0x37, 0xFA, 0x17, 0x00, 0x47, 0xF2, 0xFF, 0xFF,
+	 0x10, 0xA0, 0xFF, 0xFF, 0x02, 0x04, 0xFF, 0x60, 0xFF, 0x64, 0xDC, 0x84, 0x47, 0xFA, 0x46, 0xF2,
+	 0x16, 0x04, 0xDC, 0x84, 0x46, 0xFA, 0x45, 0xF2, 0x08, 0x04, 0xDC, 0x84, 0x45, 0xFA, 0x05, 0x04,
+	 0x37, 0xF2, 0xFF, 0xFF, 0xE0, 0x84, 0xE8, 0x84, 0x37, 0xFA, 0x0D, 0x60, 0x3E, 0x62, 0x80, 0xFF,
+	 0x78, 0x44, 0x03, 0xA4, 0xA2, 0xDB, 0xBE, 0x60, 0x66, 0x78, 0xFF, 0xFF, 0x84, 0xFF, 0x0D, 0x60,
+	 0x3E, 0x62, 0x80, 0xFF, 0x78, 0x44, 0x03, 0xA4, 0xA2, 0xDB, 0xBE, 0x60, 0xDE, 0x78, 0xFF, 0xFF,
+	 0x84, 0xFF, 0xA9, 0xF3, 0x66, 0x5C, 0xD0, 0x80, 0x00, 0x7C, 0x07, 0x03, 0x66, 0x43, 0x3C, 0x46,
+	 0x22, 0xF2, 0x63, 0x46, 0x60, 0x40, 0x01, 0x2A, 0x01, 0x00, 0x3C, 0xF1, 0x47, 0xF0, 0x64, 0x41,
+	 0x64, 0x47, 0xFF, 0xB4, 0x60, 0x5F, 0x20, 0xBC, 0x80, 0x26, 0x80, 0xAC, 0x60, 0x47, 0xA3, 0x46,
+	 0x3A, 0xFA, 0x64, 0x44, 0x20, 0x7F, 0x34, 0x94, 0x3B, 0xFA, 0xA3, 0x46, 0x46, 0xF2, 0x45, 0xF0,
+	 0xA3, 0x46, 0x3C, 0xFA, 0x3D, 0xF8, 0x08, 0x60, 0x00, 0xEA, 0x0F, 0x64, 0x60, 0x7F, 0xA0, 0x5A,
+	 0x80, 0x60, 0x00, 0xEA, 0xA0, 0x60, 0x00, 0xEA, 0xD1, 0x60, 0x00, 0xEA, 0x8A, 0x00, 0x2A, 0xF2,
+	 0xFF, 0xFF, 0x60, 0x40, 0x08, 0x27, 0x35, 0x00, 0x2A, 0xF2, 0x00, 0x60, 0x7C, 0x62, 0x60, 0x40,
+	 0x40, 0x2B, 0x27, 0x00, 0xA2, 0xD3, 0x00, 0x61, 0x60, 0xFE, 0xA0, 0xD3, 0xDE, 0x82, 0xA2, 0xD1,
+	 0xFF, 0xFF, 0x20, 0xFE, 0x64, 0x5F, 0xDC, 0x84, 0xF1, 0x81, 0xC0, 0x2B, 0x04, 0x00, 0x80, 0x2A,
+	 0x02, 0x00, 0x7F, 0xA4, 0xDC, 0x84, 0xFF, 0x3B, 0x03, 0x00, 0x60, 0x47, 0xDC, 0x87, 0x01, 0x61,
+	 0xC0, 0x80, 0x00, 0x36, 0xDC, 0x84, 0x4E, 0xDB, 0x60, 0xFE, 0xDA, 0x82, 0xA2, 0xD1, 0xFF, 0xFF,
+	 0xC1, 0x84, 0xF0, 0x22, 0x10, 0xA4, 0xF0, 0x2A, 0x01, 0x00, 0x00, 0x64, 0xA2, 0xDB, 0xFF, 0xFF,
+	 0x20, 0xFE, 0x00, 0x60, 0x7C, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0xA0, 0xD3, 0x5A, 0xD1, 0x3A, 0xFA,
+	 0x3B, 0xF8, 0x74, 0x62, 0xA2, 0xD0, 0xFF, 0xFF, 0x64, 0x44, 0xE0, 0x7F, 0xA0, 0x5A, 0x64, 0x47,
+	 0xE1, 0x7F, 0x5A, 0xD0, 0xA0, 0x5A, 0x64, 0x44, 0xE2, 0x7F, 0xA0, 0x5A, 0x00, 0x60, 0x80, 0x62,
+	 0xA2, 0xD3, 0xFF, 0xFF, 0xA0, 0xD1, 0x5A, 0xD1, 0x64, 0x45, 0x64, 0x44, 0xE3, 0x7F, 0xA0, 0x5A,
+	 0x64, 0x47, 0xE4, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xE5, 0x7F, 0xA0, 0x5A, 0x64, 0x47,
+	 0xE6, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xE7, 0x7F, 0xA0, 0x5A, 0x65, 0x40, 0x0D, 0x3A,
+	 0x1C, 0x00, 0x64, 0x47, 0xE8, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xE9, 0x7F, 0xA0, 0x5A,
+	 0x64, 0x47, 0xEA, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xEB, 0x7F, 0xA0, 0x5A, 0x64, 0x47,
+	 0xEC, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xED, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xEE, 0x7F,
+	 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xEF, 0x7F, 0xA0, 0x5A, 0x08, 0x60, 0x00, 0xEA, 0x65, 0x44,
+	 0x02, 0xA4, 0x60, 0x7F, 0xA0, 0x5A, 0x80, 0x60, 0x00, 0xEA, 0xA0, 0x60, 0x00, 0xEA, 0xD1, 0x60,
+	 0x00, 0xEA, 0x02, 0x64, 0x3B, 0xDB, 0xB8, 0x60, 0xBE, 0x78, 0xFF, 0xFF, 0x66, 0x44, 0xFC, 0xFB,
+	 0x07, 0xF0, 0x00, 0x64, 0xD0, 0x80, 0xA9, 0xF3, 0x17, 0x03, 0xD0, 0x80, 0x66, 0x41, 0x64, 0x46,
+	 0x6F, 0xF2, 0x61, 0x46, 0x7B, 0x03, 0x60, 0x40, 0x00, 0x36, 0x78, 0x00, 0x47, 0xF1, 0x07, 0xF0,
+	 0x64, 0x40, 0x02, 0x26, 0x01, 0x00, 0x0B, 0x00, 0x03, 0x12, 0xB6, 0x60, 0x38, 0x78, 0xFF, 0xFF,
+	 0xFC, 0x0A, 0xB7, 0x60, 0x56, 0x78, 0xFF, 0xFF, 0xB7, 0x60, 0x56, 0x78, 0xFF, 0xFF, 0x66, 0x41,
+	 0x64, 0x46, 0x0E, 0xF2, 0x60, 0x45, 0x61, 0x46, 0x10, 0x7E, 0x4E, 0xFB, 0x65, 0x44, 0x60, 0x40,
+	 0x01, 0x36, 0x5C, 0x00, 0x02, 0x36, 0x5D, 0x00, 0x03, 0x36, 0x34, 0x00, 0x04, 0x36, 0x45, 0x00,
+	 0x67, 0x00, 0x00, 0x64, 0x4C, 0xFB, 0x66, 0x41, 0x64, 0x46, 0x6F, 0xF2, 0xFF, 0xFF, 0x05, 0x7E,
+	 0x6F, 0xFA, 0x61, 0x46, 0x00, 0x65, 0x65, 0x43, 0x66, 0x41, 0x64, 0x46, 0x70, 0xF2, 0x8C, 0xFA,
+	 0x00, 0xA8, 0x6F, 0xF2, 0x15, 0x03, 0x60, 0x47, 0xFF, 0xB5, 0x70, 0xF2, 0x00, 0xBB, 0xFF, 0xA0,
+	 0x07, 0x03, 0x0E, 0x06, 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0x02, 0x02, 0xFB, 0x04, 0x08, 0x00,
+	 0xB9, 0x81, 0xE8, 0x84, 0xD9, 0x81, 0xFD, 0x04, 0x0F, 0x60, 0xA2, 0x65, 0x45, 0xD3, 0x0E, 0xFA,
+	 0x0C, 0xF4, 0xFF, 0xFF, 0x66, 0x41, 0x64, 0x46, 0x0E, 0xF2, 0x61, 0x46, 0xFF, 0xFF, 0xA0, 0x7E,
+	 0x4E, 0xFB, 0x24, 0x00, 0x4C, 0xF3, 0xFF, 0xFF, 0xDC, 0x84, 0x4C, 0xFB, 0xCB, 0xF3, 0x60, 0x45,
+	 0xD4, 0x80, 0xFF, 0xFF, 0x1B, 0x02, 0x24, 0x60, 0xA6, 0x62, 0x0F, 0x60, 0x96, 0x64, 0xA2, 0xDB,
+	 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0xBC, 0x01, 0x4C, 0xF3, 0x66, 0x41, 0xDC, 0x84,
+	 0x4C, 0xFB, 0x64, 0x46, 0x6F, 0xF2, 0xFF, 0xFF, 0x03, 0x7E, 0x6F, 0xFA, 0x61, 0x46, 0x66, 0x41,
+	 0x64, 0x46, 0x0E, 0xF2, 0x61, 0x46, 0xFF, 0xFF, 0xA4, 0x7E, 0x4E, 0xFB, 0xB7, 0x60, 0x56, 0x78,
+	 0xFF, 0xFF, 0x66, 0x41, 0x64, 0x46, 0x6F, 0xF2, 0xFF, 0xFF, 0x01, 0x7E, 0x6F, 0xFA, 0x61, 0x46,
+	 0x66, 0x41, 0x64, 0x46, 0x0E, 0xF2, 0x61, 0x46, 0xFF, 0xFF, 0xA8, 0x7E, 0x4E, 0xFB, 0xEE, 0x01,
+	 0x66, 0x41, 0x64, 0x46, 0x6F, 0xF2, 0x8C, 0xFA, 0x60, 0x47, 0x70, 0xF2, 0xFF, 0xB5, 0x08, 0x18,
+	 0xE4, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0x03, 0x02, 0xFB, 0x04, 0x01, 0x64, 0x01, 0x00, 0x00, 0x64,
+	 0x0C, 0xF4, 0x00, 0xA8, 0xFF, 0xFF, 0xDD, 0x02, 0x66, 0x41, 0x64, 0x46, 0x6F, 0xF2, 0xFF, 0xFF,
+	 0x60, 0x47, 0x70, 0xF2, 0xFF, 0xB5, 0x61, 0x46, 0x00, 0xA8, 0xFF, 0xFF, 0x29, 0x03, 0xE0, 0x84,
+	 0xA4, 0x80, 0xFF, 0xFF, 0xFC, 0x03, 0x66, 0x41, 0x64, 0x46, 0x70, 0xFA, 0x61, 0x46, 0x01, 0x65,
+	 0x65, 0x43, 0x66, 0x41, 0x64, 0x46, 0x70, 0xF2, 0x8C, 0xFA, 0x00, 0xA8, 0x6F, 0xF2, 0x15, 0x03,
+	 0x60, 0x47, 0xFF, 0xB5, 0x70, 0xF2, 0x00, 0xBB, 0xFF, 0xA0, 0x07, 0x03, 0x0E, 0x06, 0xE8, 0x84,
+	 0xA4, 0x80, 0xFF, 0xFF, 0x02, 0x02, 0xFB, 0x04, 0x08, 0x00, 0xB9, 0x81, 0xE8, 0x84, 0xD9, 0x81,
+	 0xFD, 0x04, 0x0F, 0x60, 0xA2, 0x65, 0x45, 0xD3, 0x0E, 0xFA, 0x0C, 0xF4, 0xFF, 0xFF, 0x95, 0x01,
+	 0x94, 0x01, 0x65, 0x44, 0x60, 0x40, 0x01, 0x36, 0xA1, 0x01, 0x02, 0x36, 0x01, 0x00, 0x9E, 0x01,
+	 0x66, 0x41, 0x64, 0x46, 0x6F, 0xF2, 0xFF, 0xFF, 0x01, 0x7E, 0x6F, 0xFA, 0x61, 0x46, 0x00, 0x65,
+	 0x65, 0x43, 0x66, 0x41, 0x64, 0x46, 0x70, 0xF2, 0x8C, 0xFA, 0x00, 0xA8, 0x6F, 0xF2, 0x15, 0x03,
+	 0x60, 0x47, 0xFF, 0xB5, 0x70, 0xF2, 0x00, 0xBB, 0xFF, 0xA0, 0x07, 0x03, 0x0E, 0x06, 0xE8, 0x84,
+	 0xA4, 0x80, 0xFF, 0xFF, 0x02, 0x02, 0xFB, 0x04, 0x08, 0x00, 0xB9, 0x81, 0xE8, 0x84, 0xD9, 0x81,
+	 0xFD, 0x04, 0x0F, 0x60, 0xA2, 0x65, 0x45, 0xD3, 0x0E, 0xFA, 0x0C, 0xF4, 0xFF, 0xFF, 0x66, 0x41,
+	 0x64, 0x46, 0x0E, 0xF2, 0x61, 0x46, 0xD0, 0x7E, 0x4E, 0xFB, 0xB7, 0x60, 0x56, 0x78, 0xFF, 0xFF,
+	 0x60, 0x45, 0x66, 0x41, 0x64, 0x46, 0x0E, 0xF2, 0x61, 0x46, 0x20, 0x7E, 0x4E, 0xFB, 0x65, 0x44,
+	 0x60, 0x40, 0x01, 0x36, 0x0B, 0x00, 0x02, 0x36, 0x1A, 0x00, 0x03, 0x36, 0x53, 0x00, 0x04, 0x36,
+	 0x70, 0x00, 0x05, 0x36, 0x14, 0x00, 0xB7, 0x60, 0x56, 0x78, 0xFF, 0xFF, 0x07, 0xF0, 0x66, 0x41,
+	 0x64, 0x46, 0x6F, 0xF2, 0xFF, 0xFF, 0x02, 0x7E, 0x6F, 0xFA, 0x61, 0x46, 0x66, 0x41, 0x64, 0x46,
+	 0x0E, 0xF2, 0x61, 0x46, 0xB0, 0x7E, 0x4E, 0xFB, 0xB7, 0x60, 0x56, 0x78, 0xFF, 0xFF, 0x07, 0xF0,
+	 0x01, 0x65, 0x65, 0x43, 0x66, 0x41, 0x64, 0x46, 0x70, 0xF2, 0x8C, 0xFA, 0x00, 0xA8, 0x6F, 0xF2,
+	 0x15, 0x03, 0x60, 0x47, 0xFF, 0xB5, 0x70, 0xF2, 0x00, 0xBB, 0xFF, 0xA0, 0x07, 0x03, 0x0E, 0x06,
+	 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0x02, 0x02, 0xFB, 0x04, 0x08, 0x00, 0xB9, 0x81, 0xE8, 0x84,
+	 0xD9, 0x81, 0xFD, 0x04, 0x0F, 0x60, 0xA2, 0x65, 0x45, 0xD3, 0x0E, 0xFA, 0x0C, 0xF4, 0xFF, 0xFF,
+	 0x66, 0x41, 0x64, 0x46, 0x6F, 0xF2, 0x00, 0x63, 0x03, 0x7E, 0x6F, 0xFA, 0x61, 0x46, 0x4C, 0xFD,
+	 0x66, 0x41, 0x64, 0x46, 0x0E, 0xF2, 0x61, 0x46, 0xB4, 0x7E, 0x4E, 0xFB, 0x24, 0x60, 0xA6, 0x62,
+	 0x0F, 0x60, 0x96, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0xB7, 0x60,
+	 0x56, 0x78, 0xFF, 0xFF, 0x66, 0x41, 0x64, 0x46, 0x70, 0xF2, 0x4C, 0xF3, 0x02, 0xB0, 0x61, 0x46,
+	 0xCC, 0x84, 0x05, 0x03, 0x04, 0x28, 0x4C, 0xFB, 0xB7, 0x60, 0x56, 0x78, 0xFF, 0xFF, 0x04, 0x28,
+	 0x4C, 0xFB, 0x66, 0x41, 0x64, 0x46, 0x6F, 0xF2, 0xFF, 0xFF, 0x04, 0x7E, 0x6F, 0xFA, 0x61, 0x46,
+	 0x66, 0x41, 0x64, 0x46, 0x0E, 0xF2, 0x61, 0x46, 0xB8, 0x7E, 0x4E, 0xFB, 0xB7, 0x60, 0x56, 0x78,
+	 0xFF, 0xFF, 0x66, 0x41, 0x64, 0x46, 0x6F, 0xF2, 0xFF, 0xFF, 0x60, 0x47, 0xFF, 0xB5, 0x70, 0xF2,
+	 0x61, 0x46, 0xFF, 0xA0, 0xFF, 0xFF, 0x35, 0x06, 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0x02, 0x02,
+	 0xFB, 0x04, 0x2F, 0x00, 0x64, 0x46, 0x70, 0xFA, 0x01, 0x65, 0x65, 0x43, 0x66, 0x41, 0x64, 0x46,
+	 0x70, 0xF2, 0x8C, 0xFA, 0x00, 0xA8, 0x6F, 0xF2, 0x15, 0x03, 0x60, 0x47, 0xFF, 0xB5, 0x70, 0xF2,
+	 0x00, 0xBB, 0xFF, 0xA0, 0x07, 0x03, 0x0E, 0x06, 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0x02, 0x02,
+	 0xFB, 0x04, 0x08, 0x00, 0xB9, 0x81, 0xE8, 0x84, 0xD9, 0x81, 0xFD, 0x04, 0x0F, 0x60, 0xA2, 0x65,
+	 0x45, 0xD3, 0x0E, 0xFA, 0x0C, 0xF4, 0xFF, 0xFF, 0x6F, 0xF2, 0x00, 0x63, 0x03, 0x7E, 0x6F, 0xFA,
+	 0x3C, 0x46, 0x4C, 0xFD, 0x66, 0x41, 0x64, 0x46, 0x0E, 0xF2, 0x61, 0x46, 0xC0, 0x7E, 0x4E, 0xFB,
+	 0x5D, 0x00, 0x5C, 0x00, 0x65, 0x44, 0x60, 0x40, 0x01, 0x36, 0x03, 0x00, 0x02, 0x36, 0x18, 0x00,
+	 0x55, 0x00, 0x66, 0x41, 0x64, 0x46, 0x70, 0xF2, 0x61, 0x46, 0x01, 0xB0, 0xFF, 0xFF, 0x4E, 0x02,
+	 0x07, 0xF0, 0x66, 0x41, 0x64, 0x46, 0x6F, 0xF2, 0xFF, 0xFF, 0x02, 0x7E, 0x6F, 0xFA, 0x61, 0x46,
+	 0x66, 0x41, 0x64, 0x46, 0x0E, 0xF2, 0x61, 0x46, 0xE0, 0x7E, 0x4E, 0xFB, 0x3F, 0x00, 0x3E, 0x00,
+	 0x07, 0xF0, 0x66, 0x41, 0x64, 0x46, 0x6F, 0xF2, 0xFF, 0xFF, 0x01, 0x7E, 0x6F, 0xFA, 0x60, 0x47,
+	 0xFF, 0xB5, 0x70, 0xF2, 0x61, 0x46, 0xFF, 0xA0, 0xFF, 0xFF, 0xF1, 0x06, 0xE8, 0x84, 0xA4, 0x80,
+	 0xFF, 0xFF, 0x02, 0x02, 0xFB, 0x04, 0xEB, 0x01, 0x66, 0x41, 0x64, 0x46, 0x70, 0xFA, 0x61, 0x46,
+	 0x00, 0x65, 0x65, 0x43, 0x66, 0x41, 0x64, 0x46, 0x70, 0xF2, 0x8C, 0xFA, 0x00, 0xA8, 0x6F, 0xF2,
+	 0x15, 0x03, 0x60, 0x47, 0xFF, 0xB5, 0x70, 0xF2, 0x00, 0xBB, 0xFF, 0xA0, 0x07, 0x03, 0x0E, 0x06,
+	 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0x02, 0x02, 0xFB, 0x04, 0x08, 0x00, 0xB9, 0x81, 0xE8, 0x84,
+	 0xD9, 0x81, 0xFD, 0x04, 0x0F, 0x60, 0xA2, 0x65, 0x45, 0xD3, 0x0E, 0xFA, 0x0C, 0xF4, 0xFF, 0xFF,
+	 0x66, 0x41, 0x64, 0x46, 0x0E, 0xF2, 0x61, 0x46, 0xE4, 0x7E, 0x4E, 0xFB, 0x03, 0x64, 0x3B, 0xDB,
+	 0xCA, 0xFE, 0x47, 0xF1, 0x01, 0x65, 0x32, 0x40, 0x04, 0x27, 0x08, 0x00, 0x2C, 0xF2, 0x64, 0x45,
+	 0x02, 0x22, 0x04, 0x00, 0x60, 0x40, 0x01, 0x26, 0x01, 0x00, 0xE3, 0x00, 0x14, 0xF2, 0x65, 0x40,
+	 0x01, 0x26, 0x1D, 0x00, 0x60, 0x45, 0x05, 0x64, 0x3B, 0xDB, 0x65, 0x44, 0xCC, 0x85, 0xB8, 0xF1,
+	 0x27, 0x60, 0x78, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xD8, 0x80, 0xC4, 0x84, 0x0B, 0x03, 0x07, 0x05,
+	 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x09, 0x04, 0xC6, 0xFE, 0x07, 0x00, 0x00, 0x64,
+	 0xB8, 0x84, 0xA2, 0xDB, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0xAF, 0x00, 0x60, 0x41,
+	 0x2A, 0xF0, 0x00, 0x60, 0x0C, 0x64, 0xA0, 0x84, 0x04, 0x36, 0x02, 0x00, 0x0C, 0x3A, 0x01, 0x00,
+	 0xA5, 0x00, 0x61, 0x45, 0x60, 0x41, 0xB8, 0xF1, 0x27, 0x60, 0x78, 0x64, 0xA0, 0xD3, 0xFF, 0xFF,
+	 0xD8, 0x80, 0xC4, 0x84, 0x0B, 0x03, 0x07, 0x05, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB,
+	 0x09, 0x04, 0xC6, 0xFE, 0x07, 0x00, 0x00, 0x64, 0xB8, 0x84, 0xA2, 0xDB, 0x8A, 0xFF, 0x20, 0x60,
+	 0x00, 0x75, 0x88, 0xFF, 0x61, 0x40, 0x08, 0x36, 0x01, 0x00, 0x88, 0x00, 0x14, 0xF2, 0x1C, 0x65,
+	 0x60, 0x41, 0x00, 0x63, 0xCD, 0x81, 0xC7, 0x83, 0xFD, 0x02, 0x3F, 0xF0, 0x2C, 0xF2, 0xC3, 0x83,
+	 0x60, 0x40, 0x01, 0x2A, 0x29, 0x00, 0xB8, 0xF1, 0x27, 0x60, 0x76, 0x64, 0xA0, 0xD3, 0xFF, 0xFF,
+	 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00,
+	 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0xB8, 0xF1, 0x27, 0x60, 0x7C, 0x64, 0xA0, 0xD3,
+	 0x63, 0x45, 0xD8, 0x80, 0xC4, 0x84, 0x0B, 0x03, 0x07, 0x05, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03,
+	 0xA2, 0xDB, 0x09, 0x04, 0xC6, 0xFE, 0x07, 0x00, 0x00, 0x64, 0xB8, 0x84, 0xA2, 0xDB, 0x8A, 0xFF,
+	 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x52, 0x00, 0xB8, 0xF1, 0x27, 0x60, 0x74, 0x64, 0xA0, 0xD3,
+	 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE,
+	 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0xB8, 0xF1, 0x27, 0x60, 0x7A, 0x64,
+	 0xA0, 0xD3, 0x63, 0x45, 0xD8, 0x80, 0xC4, 0x84, 0x0B, 0x03, 0x07, 0x05, 0xDC, 0x80, 0xD0, 0x80,
+	 0x04, 0x03, 0xA2, 0xDB, 0x09, 0x04, 0xC6, 0xFE, 0x07, 0x00, 0x00, 0x64, 0xB8, 0x84, 0xA2, 0xDB,
+	 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x15, 0xF2, 0xFF, 0xFF, 0x0F, 0xB4, 0x00, 0xA8,
+	 0x01, 0xA8, 0x24, 0x03, 0x12, 0x03, 0xB8, 0xF1, 0x27, 0x60, 0x82, 0x64, 0xA0, 0xD3, 0xFF, 0xFF,
+	 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00,
+	 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x11, 0x00, 0xB8, 0xF1, 0x27, 0x60, 0x80, 0x64,
+	 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24,
+	 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x04, 0x64, 0x3B, 0xDB,
+	 0x24, 0x60, 0x6E, 0x62, 0x24, 0x60, 0x46, 0x64, 0xA2, 0xDB, 0x3C, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x5C, 0x5C, 0xFC, 0xFC, 0xCE, 0xFE, 0xB0, 0x60, 0xE1, 0x78,
+	 0xFF, 0xFF, 0x0F, 0xF0, 0x15, 0xF2, 0x64, 0x41, 0x01, 0x2A, 0x02, 0x00, 0xD1, 0xF1, 0x02, 0x00,
+	 0xD0, 0xF1, 0xFF, 0xFF, 0x64, 0x45, 0xDC, 0x84, 0xD4, 0x80, 0x15, 0xFA, 0x30, 0x07, 0x61, 0x40,
+	 0x01, 0x2A, 0x09, 0x00, 0x27, 0x60, 0xA8, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xFF, 0xFF,
+	 0x08, 0x28, 0xA2, 0xDB, 0x08, 0x00, 0x27, 0x60, 0xAA, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84,
+	 0xFF, 0xFF, 0x08, 0x28, 0xA2, 0xDB, 0x2A, 0xF0, 0x08, 0x67, 0xB0, 0x84, 0xA2, 0xDA, 0x00, 0x64,
+	 0x48, 0xFB, 0x2D, 0x60, 0x52, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x2A, 0x0C, 0x00,
+	 0x3C, 0x46, 0x3E, 0xF2, 0x40, 0x60, 0x00, 0x65, 0xF0, 0x84, 0xA4, 0x84, 0x18, 0xFA, 0x2A, 0xF2,
+	 0xBF, 0x60, 0xFF, 0x65, 0xA4, 0x84, 0x2A, 0xFA, 0xB2, 0x60, 0xFC, 0x78, 0xFF, 0xFF, 0x00, 0x64,
+	 0x49, 0xFB, 0xB8, 0xF1, 0x27, 0x60, 0x82, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80,
+	 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60,
+	 0x00, 0x75, 0x88, 0xFF, 0xB8, 0xF1, 0x27, 0x60, 0x84, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84,
+	 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF,
+	 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x2D, 0x60, 0x5A, 0x63, 0xA3, 0xD3, 0xB0, 0x60, 0x58, 0x4D,
+	 0xD8, 0x78, 0xFF, 0xFF, 0x0D, 0xF2, 0x60, 0x5C, 0x64, 0x5F, 0x0D, 0xFA, 0x23, 0xF0, 0x01, 0x64,
+	 0xB0, 0x84, 0xA2, 0xDA, 0x7B, 0x01, 0xB9, 0x60, 0x43, 0x78, 0xFF, 0xFF, 0x21, 0x64, 0x3B, 0xDB,
+	 0x31, 0xF3, 0x01, 0x63, 0xC4, 0xB4, 0x31, 0xFB, 0x32, 0xFD, 0xB8, 0x60, 0xEF, 0x62, 0x42, 0x40,
+	 0xA0, 0x4C, 0x40, 0xBC, 0x7D, 0xB4, 0xA0, 0x51, 0xA0, 0xFE, 0x1A, 0xFF, 0x24, 0x60, 0x3A, 0x64,
+	 0x08, 0xF0, 0x07, 0xF0, 0xD0, 0x80, 0x24, 0x60, 0x40, 0x62, 0x14, 0x02, 0xA2, 0xD3, 0x01, 0x63,
+	 0xAC, 0x86, 0x07, 0xF2, 0x0F, 0x03, 0xD0, 0x80, 0x09, 0xF2, 0xFA, 0x02, 0x23, 0xFC, 0x24, 0x60,
+	 0x6E, 0x62, 0x24, 0x60, 0x46, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB,
+	 0xFF, 0xFF, 0x2B, 0xFF, 0x3C, 0x46, 0x06, 0x64, 0xA1, 0xFF, 0x49, 0xFB, 0x83, 0x3E, 0x31, 0xF3,
+	 0x87, 0x60, 0x80, 0x61, 0x1D, 0xF0, 0x60, 0x40, 0x01, 0x2A, 0x15, 0x00, 0xFE, 0xB4, 0x31, 0xFB,
+	 0x00, 0x64, 0x49, 0xFB, 0x01, 0x64, 0x47, 0xFB, 0x2D, 0x60, 0x5A, 0x63, 0xA3, 0xD3, 0xB0, 0x60,
+	 0x58, 0x4D, 0xD8, 0x78, 0xFF, 0xFF, 0x00, 0x71, 0x64, 0x5F, 0x0D, 0xFA, 0x40, 0x64, 0x3B, 0xDB,
+	 0xB9, 0x60, 0x43, 0x78, 0xFF, 0xFF, 0x02, 0x2A, 0x1B, 0x00, 0xD1, 0x91, 0x8D, 0xE2, 0x41, 0x64,
+	 0x3B, 0xDB, 0x31, 0xF3, 0x2D, 0x60, 0x62, 0x63, 0xFD, 0xB4, 0x31, 0xFB, 0xA3, 0xD3, 0xB0, 0x60,
+	 0x58, 0x4D, 0xD8, 0x78, 0xFF, 0xFF, 0x02, 0x63, 0x60, 0x5C, 0x0D, 0xF2, 0x47, 0xFD, 0xFF, 0xB5,
+	 0x60, 0x47, 0xD0, 0x80, 0xDC, 0x84, 0x1F, 0x03, 0x60, 0x47, 0xB4, 0x84, 0x0D, 0xFA, 0x1B, 0x00,
+	 0x08, 0x2A, 0x07, 0x00, 0x42, 0x64, 0x3B, 0xDB, 0x31, 0xF3, 0xFF, 0xFF, 0xF7, 0xB4, 0x31, 0xFB,
+	 0x12, 0x00, 0x10, 0x2A, 0x09, 0x00, 0x43, 0x64, 0x3B, 0xDB, 0x31, 0xF3, 0xFF, 0xFF, 0xEF, 0xB4,
+	 0x31, 0xFB, 0xB8, 0x60, 0xBE, 0x78, 0xFF, 0xFF, 0x44, 0x64, 0x3B, 0xDB, 0x31, 0xF3, 0xFF, 0xFF,
+	 0xDF, 0xB4, 0x31, 0xFB, 0x00, 0x00, 0x2A, 0x64, 0x3B, 0xDB, 0xB0, 0x60, 0x97, 0x64, 0x40, 0x40,
+	 0xB5, 0x60, 0x1E, 0x78, 0xFF, 0xFF, 0x1C, 0x60, 0xB8, 0x63, 0xA3, 0xD3, 0xFF, 0xFF, 0x02, 0xB5,
+	 0x04, 0xB5, 0x04, 0x03, 0x03, 0x03, 0xBA, 0x60, 0x3C, 0x78, 0xFF, 0xFF, 0x86, 0xFF, 0x20, 0x44,
+	 0x84, 0xFF, 0x20, 0x2A, 0x04, 0x00, 0xF3, 0x60, 0x58, 0x4E, 0x14, 0x78, 0xFF, 0xFF, 0x31, 0x40,
+	 0x01, 0x26, 0x17, 0x00, 0xA0, 0x4C, 0x49, 0xBC, 0xFF, 0xB4, 0xA0, 0x51, 0x1C, 0x60, 0xB8, 0x63,
+	 0xA3, 0xD3, 0xFF, 0xFF, 0x02, 0xB5, 0x04, 0xBC, 0x09, 0x03, 0x60, 0x40, 0x01, 0x26, 0xED, 0xE2,
+	 0xFE, 0xB4, 0xA3, 0xDB, 0xA0, 0x4C, 0x7D, 0xB4, 0xA0, 0x51, 0x03, 0x00, 0xA0, 0x4C, 0x6D, 0xB4,
+	 0xA0, 0x51, 0xDC, 0xF3, 0xFF, 0xFF, 0xFD, 0xA0, 0xFF, 0xFF, 0x48, 0x03, 0x31, 0x40, 0x04, 0x2A,
+	 0x3E, 0x00, 0x6D, 0xF3, 0x74, 0xF3, 0xCC, 0x83, 0x6D, 0xFD, 0xCC, 0x84, 0x74, 0xFB, 0x1F, 0x02,
+	 0x31, 0x40, 0x02, 0x2A, 0x12, 0x00, 0x6F, 0xF3, 0x70, 0xF1, 0xCC, 0x84, 0x6F, 0xFB, 0x0D, 0x02,
+	 0x6F, 0xF9, 0x31, 0x44, 0x08, 0xBC, 0x40, 0x51, 0x72, 0xF3, 0x71, 0xF1, 0x00, 0xB8, 0x64, 0x45,
+	 0x01, 0x03, 0x67, 0x45, 0x65, 0x50, 0xCC, 0x84, 0x73, 0xFB, 0x28, 0x60, 0x00, 0x64, 0xA0, 0xD3,
+	 0x6E, 0xF1, 0x00, 0xB8, 0x74, 0xF9, 0x03, 0x03, 0x87, 0xF3, 0x6D, 0xFB, 0x04, 0x00, 0x6D, 0xF3,
+	 0x87, 0xF1, 0x15, 0x1B, 0x6D, 0xF9, 0x31, 0x40, 0x01, 0x2A, 0x11, 0x00, 0xDD, 0xFE, 0x0F, 0x05,
+	 0xBA, 0xFE, 0xAD, 0x4F, 0x00, 0x7F, 0x01, 0xBC, 0xA0, 0x5D, 0x00, 0xEE, 0x7F, 0xF1, 0x02, 0x60,
+	 0xEE, 0x64, 0xA3, 0xFB, 0xA4, 0xF9, 0x04, 0x64, 0xA5, 0xFB, 0xDF, 0xFE, 0x19, 0xFF, 0x1A, 0x60,
+	 0x42, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0xCC, 0x84, 0xFF, 0x2B, 0xA2, 0xDB, 0x31, 0x40, 0x01, 0x2A,
+	 0x29, 0x00, 0x9D, 0xFE, 0x27, 0x04, 0x26, 0x0A, 0x9F, 0xFE, 0x24, 0x05, 0x85, 0xFF, 0x20, 0x44,
+	 0x84, 0xFF, 0x40, 0x26, 0x1F, 0x00, 0x3F, 0x40, 0x20, 0x2B, 0x1C, 0x00, 0x38, 0x69, 0xFF, 0xFF,
+	 0x68, 0x44, 0x01, 0x16, 0xFD, 0x01, 0x01, 0x2A, 0x15, 0x00, 0x27, 0x60, 0xB4, 0x64, 0xA0, 0xD3,
+	 0xFF, 0xFF, 0xDC, 0x84, 0xFF, 0xFF, 0x08, 0x28, 0xA2, 0xDB, 0x7F, 0xF1, 0x02, 0x60, 0xEE, 0x64,
+	 0xA3, 0xFB, 0xFF, 0xFF, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA4, 0xFB, 0x04, 0x64, 0xA5, 0xFB,
+	 0xDF, 0xFE, 0x19, 0xFF, 0x10, 0x64, 0x3B, 0xDB, 0x80, 0xF3, 0x73, 0x45, 0xE0, 0x84, 0xE0, 0x84,
+	 0xE0, 0x84, 0xE0, 0x84, 0xC4, 0x93, 0xC9, 0xFE, 0x49, 0xF3, 0x3C, 0x46, 0x27, 0x18, 0xCC, 0x84,
+	 0x49, 0xFB, 0x24, 0x02, 0xBB, 0x60, 0x18, 0x64, 0x40, 0x42, 0xFC, 0xFC, 0x00, 0x64, 0x5C, 0x5C,
+	 0x32, 0xFB, 0x82, 0xFF, 0x5C, 0x47, 0x84, 0xFF, 0x62, 0xFF, 0x27, 0x60, 0xA4, 0x64, 0xA0, 0xD3,
+	 0xFF, 0xFF, 0xDC, 0x84, 0xFF, 0xFF, 0x08, 0x28, 0xA2, 0xDB, 0x23, 0xF0, 0x01, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDA, 0x24, 0x60, 0x6E, 0x62, 0x24, 0x60, 0x46, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0xCE, 0xFE, 0x6A, 0xF3, 0xFF, 0xFF,
+	 0x60, 0x41, 0xFD, 0xB4, 0xA2, 0xDB, 0x61, 0x44, 0x01, 0xB0, 0x02, 0xB0, 0x0C, 0x03, 0x0B, 0x02,
+	 0x9D, 0xFE, 0x09, 0x04, 0x24, 0x60, 0xA6, 0x62, 0x1A, 0x60, 0xA2, 0x64, 0xA2, 0xDB, 0x02, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x07, 0x00, 0x80, 0xF3, 0x73, 0x45, 0xE0, 0x84, 0xE0, 0x84,
+	 0xE0, 0x84, 0xE0, 0x84, 0xC4, 0x93, 0x1C, 0x60, 0xB4, 0x63, 0xA3, 0xD3, 0xAD, 0x49, 0x20, 0xB5,
+	 0x08, 0xB1, 0x23, 0x03, 0xE1, 0x81, 0x10, 0xB5, 0x95, 0x81, 0x60, 0x41, 0x18, 0x02, 0x1C, 0x60,
+	 0xB6, 0x7C, 0xA4, 0xD3, 0xFF, 0xFF, 0xCC, 0x84, 0xA4, 0xDB, 0x17, 0x02, 0x05, 0x64, 0xA4, 0xDB,
+	 0x61, 0x44, 0x07, 0xB4, 0xFF, 0xFF, 0x11, 0x02, 0x08, 0xB1, 0xE1, 0x81, 0x95, 0x81, 0xA3, 0xD3,
+	 0x0C, 0x03, 0x08, 0xAC, 0x01, 0xBC, 0xA3, 0xDB, 0xFF, 0xFF, 0x13, 0xFF, 0x06, 0x00, 0x10, 0xAC,
+	 0xA3, 0xDB, 0x1C, 0x60, 0xB6, 0x63, 0x05, 0x7C, 0xA3, 0xD9, 0xB0, 0x60, 0xA4, 0x78, 0xFF, 0xFF,
+	 0x46, 0xF3, 0x45, 0xF1, 0x05, 0x1B, 0x64, 0x44, 0x03, 0x1B, 0x0F, 0x60, 0x92, 0x62, 0xA2, 0xD3,
+	 0x45, 0xFB, 0x00, 0x63, 0x46, 0xFD, 0x60, 0x41, 0x25, 0x64, 0x3B, 0xDB, 0x27, 0x44, 0xEF, 0xB4,
+	 0x40, 0x47, 0x00, 0xB9, 0x71, 0x40, 0x80, 0x27, 0x01, 0x12, 0x2B, 0x03, 0xBA, 0x60, 0x93, 0x62,
+	 0x84, 0xFF, 0x42, 0x42, 0x82, 0xFF, 0xA0, 0x4C, 0x14, 0xBC, 0xFF, 0xB4, 0xA0, 0x51, 0x31, 0x0A,
+	 0xA1, 0xFF, 0xFF, 0xFF, 0x81, 0x3E, 0x70, 0x44, 0xAC, 0x80, 0x2B, 0x0A, 0x71, 0x40, 0x80, 0x27,
+	 0xF7, 0x12, 0x45, 0xF3, 0x4C, 0x02, 0x15, 0x18, 0x31, 0x60, 0x0E, 0x7C, 0xA4, 0xD3, 0xFF, 0xFF,
+	 0x0B, 0x18, 0x31, 0x60, 0x10, 0x7C, 0xA4, 0xD3, 0xFF, 0xFF, 0x06, 0x18, 0xAC, 0x4C, 0x80, 0x26,
+	 0x03, 0x00, 0x00, 0x64, 0x45, 0xFB, 0x05, 0x00, 0x45, 0xF3, 0xFF, 0xFF, 0xCC, 0x84, 0x45, 0xFB,
+	 0xDF, 0x02, 0x06, 0x0A, 0xA0, 0x4C, 0xFB, 0xB4, 0xA0, 0x51, 0xA3, 0x60, 0x99, 0x78, 0xFF, 0xFF,
+	 0x84, 0xFF, 0xBA, 0x60, 0x70, 0x64, 0x40, 0x42, 0x82, 0xFF, 0xA0, 0x4C, 0x14, 0xBC, 0xFF, 0xB4,
+	 0xA0, 0x51, 0xAB, 0x60, 0x2C, 0x78, 0xFF, 0xFF, 0x3C, 0x44, 0xAC, 0x80, 0x32, 0xF1, 0x25, 0x03,
+	 0x64, 0x40, 0x07, 0x22, 0x22, 0x00, 0xA3, 0x60, 0x7B, 0x78, 0xFF, 0xFF, 0xA0, 0x4C, 0x1C, 0xBC,
+	 0xDF, 0xB4, 0xA0, 0x51, 0x31, 0x40, 0x08, 0x2A, 0xEF, 0x01, 0x73, 0xF3, 0x71, 0xF1, 0x00, 0xA0,
+	 0xDC, 0x80, 0x05, 0x03, 0x08, 0x03, 0xCC, 0x84, 0x73, 0xFB, 0x67, 0x50, 0x08, 0x00, 0xCC, 0x84,
+	 0x73, 0xFB, 0x64, 0x50, 0x04, 0x00, 0x31, 0x44, 0xF7, 0xB4, 0x40, 0x51, 0x06, 0x00, 0x28, 0x64,
+	 0x3A, 0xDB, 0xA0, 0x4C, 0x30, 0xBC, 0xF3, 0xB4, 0xA0, 0x51, 0xA1, 0xFF, 0xFF, 0xFF, 0x81, 0x3E,
+	 0x28, 0x64, 0x3B, 0xDB, 0x0F, 0x60, 0x94, 0x62, 0xA2, 0xD3, 0x32, 0x40, 0x02, 0x27, 0x16, 0x00,
+	 0x46, 0xFB, 0x14, 0x18, 0xBB, 0x60, 0x06, 0x64, 0x84, 0xFF, 0x40, 0x42, 0x82, 0xFF, 0xA0, 0x4C,
+	 0x14, 0xBC, 0xF7, 0xB4, 0xA0, 0x51, 0xA1, 0xFF, 0xFF, 0xFF, 0x81, 0x3E, 0x70, 0x44, 0xAC, 0x80,
+	 0x46, 0xF3, 0xB7, 0x0A, 0xDC, 0x02, 0xCC, 0x84, 0x46, 0xFB, 0xF5, 0x02, 0x84, 0xFF, 0xBB, 0x60,
+	 0x18, 0x64, 0x40, 0x42, 0x82, 0xFF, 0x27, 0x44, 0x08, 0xBC, 0x40, 0x47, 0xBB, 0xE1, 0x04, 0x00,
+	 0x3A, 0xE1, 0x31, 0x40, 0x01, 0x26, 0xBB, 0xE1, 0xA3, 0x60, 0x6F, 0x78, 0xFF, 0xFF, 0x43, 0xFF,
+	 0x39, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x84, 0x3E, 0xFB, 0x01, 0xA0, 0x4C, 0x3D, 0x46, 0x2A, 0xF2,
+	 0x46, 0x4D, 0x10, 0x25, 0x0E, 0x00, 0x09, 0xE1, 0xA1, 0xFF, 0x66, 0x40, 0x0F, 0xF2, 0x01, 0x29,
+	 0x02, 0x00, 0x40, 0xFF, 0x0A, 0xBC, 0xA2, 0xDA, 0x08, 0x25, 0xE9, 0x01, 0xCB, 0xFE, 0x5C, 0x5D,
+	 0xE7, 0x01, 0x44, 0xFF, 0x31, 0xF2, 0x1C, 0x60, 0xBA, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84,
+	 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46, 0x31, 0xF0,
+	 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46, 0x30, 0xF0, 0x63, 0x46, 0xD0, 0x80,
+	 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46, 0x2F, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03,
+	 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46, 0xE8, 0x1B, 0xA9, 0xF3, 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46,
+	 0x07, 0xFC, 0x3F, 0xF2, 0x09, 0x60, 0xB0, 0x65, 0xD4, 0x80, 0x2A, 0xF2, 0xC4, 0x05, 0x08, 0x25,
+	 0xB6, 0x01, 0x00, 0x64, 0x0D, 0x60, 0x2C, 0x61, 0x40, 0x4B, 0xA1, 0xDB, 0x2D, 0x46, 0x3B, 0xF2,
+	 0xA9, 0xF1, 0x87, 0xF4, 0x60, 0x40, 0x20, 0x2B, 0x12, 0x00, 0xD3, 0x80, 0x2C, 0xF0, 0xB3, 0x03,
+	 0x07, 0xF4, 0x64, 0x40, 0x01, 0x26, 0xA9, 0xF5, 0xB6, 0xF4, 0x2D, 0x46, 0x04, 0x64, 0x04, 0xB3,
+	 0x22, 0xFA, 0x04, 0x03, 0xBC, 0x60, 0x72, 0x78, 0xFF, 0xFF, 0x01, 0x00, 0xDE, 0x00, 0x74, 0x62,
+	 0xA2, 0xD0, 0xFF, 0xFF, 0x64, 0x44, 0xE0, 0x7F, 0xA0, 0x5B, 0x64, 0x47, 0xE1, 0x7F, 0x5A, 0xD0,
+	 0xA0, 0x5B, 0x64, 0x44, 0xE2, 0x7F, 0xA0, 0x5B, 0x64, 0x47, 0x7C, 0x5F, 0xE8, 0x84, 0xE8, 0x85,
+	 0x0C, 0x60, 0x3A, 0x64, 0x44, 0xD3, 0x5A, 0xD1, 0x03, 0x1B, 0xBC, 0x60, 0x65, 0x78, 0xFF, 0xFF,
+	 0x60, 0x45, 0x64, 0x44, 0xE3, 0x7F, 0xA0, 0x5B, 0x64, 0x47, 0xE4, 0x7F, 0x5A, 0xD1, 0xA0, 0x5B,
+	 0x64, 0x44, 0xE5, 0x7F, 0xA0, 0x5B, 0x64, 0x47, 0xE6, 0x7F, 0x5A, 0xD1, 0xA0, 0x5B, 0x64, 0x44,
+	 0xE7, 0x7F, 0xA0, 0x5B, 0x65, 0x40, 0x0D, 0x3A, 0x1C, 0x00, 0x64, 0x47, 0xE8, 0x7F, 0x5A, 0xD1,
+	 0xA0, 0x5B, 0x64, 0x44, 0xE9, 0x7F, 0xA0, 0x5B, 0x64, 0x47, 0xEA, 0x7F, 0x5A, 0xD1, 0xA0, 0x5B,
+	 0x64, 0x44, 0xEB, 0x7F, 0xA0, 0x5B, 0x64, 0x47, 0xEC, 0x7F, 0x5A, 0xD1, 0xA0, 0x5B, 0x64, 0x44,
+	 0xED, 0x7F, 0xA0, 0x5B, 0x64, 0x47, 0xEE, 0x7F, 0x5A, 0xD1, 0xA0, 0x5B, 0x64, 0x44, 0xEF, 0x7F,
+	 0xA0, 0x5B, 0x65, 0x44, 0xD8, 0x84, 0x08, 0x25, 0x76, 0x00, 0x60, 0x7F, 0xA0, 0x5B, 0x80, 0x60,
+	 0x00, 0xEB, 0xA0, 0x60, 0x00, 0xEB, 0xD1, 0x60, 0x00, 0xEB, 0x3F, 0xF2, 0x04, 0x65, 0xC4, 0x83,
+	 0x0A, 0xE1, 0xB3, 0xFF, 0x9A, 0xFF, 0xCB, 0x83, 0x00, 0xF4, 0x10, 0x62, 0x6C, 0x61, 0x0E, 0xA3,
+	 0xAB, 0x84, 0xF2, 0xA3, 0xA1, 0xFF, 0x08, 0x00, 0x00, 0xF4, 0x81, 0xF2, 0x02, 0x62, 0xC9, 0x81,
+	 0xAB, 0x84, 0xA1, 0xFF, 0x01, 0x00, 0xA2, 0xDC, 0x7A, 0xD4, 0xFD, 0x1C, 0xA2, 0xDC, 0x08, 0x25,
+	 0x52, 0x00, 0xF2, 0x1D, 0x7C, 0xA8, 0xD9, 0x81, 0xEF, 0x03, 0xFF, 0xB1, 0x09, 0x1E, 0x02, 0x02,
+	 0x00, 0xF4, 0x02, 0x62, 0x5A, 0xD2, 0x89, 0xFF, 0x80, 0x4F, 0x6F, 0x44, 0xA2, 0xDA, 0x88, 0xFF,
+	 0x98, 0xFF, 0x09, 0xE1, 0xA1, 0xFF, 0x3D, 0x46, 0x08, 0x25, 0x3D, 0x00, 0x40, 0xFF, 0x0F, 0xF0,
+	 0x0A, 0x64, 0xB0, 0x84, 0x16, 0x14, 0xF7, 0xB4, 0xA2, 0xDA, 0x0D, 0x60, 0x2C, 0x62, 0xA2, 0xD3,
+	 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x2A, 0x0C, 0x00, 0xF1, 0xF5, 0xF0, 0xF4, 0x0D, 0x60, 0x2C, 0x61,
+	 0x59, 0xD1, 0x37, 0xF8, 0x05, 0x64, 0x59, 0xD1, 0xCC, 0x84, 0xBD, 0xD8, 0xFC, 0x02, 0x2D, 0x46,
+	 0x0D, 0x01, 0xA2, 0xDA, 0x2D, 0x46, 0x3B, 0xF0, 0xFF, 0xFF, 0x64, 0x40, 0x20, 0x2B, 0x18, 0x00,
+	 0xF1, 0xF5, 0xB7, 0xF0, 0x2A, 0x44, 0xA4, 0x84, 0xFF, 0xFF, 0x2F, 0x26, 0x10, 0x00, 0x2D, 0x46,
+	 0x64, 0x44, 0x3A, 0xF0, 0xBC, 0xF0, 0x64, 0x5F, 0x3D, 0xF0, 0x07, 0xF4, 0xF0, 0xF4, 0xFF, 0xFF,
+	 0x08, 0xA3, 0x5B, 0xD8, 0x65, 0x5C, 0x5B, 0xD8, 0x5B, 0xDA, 0x2D, 0x46, 0x01, 0x00, 0x2D, 0x46,
+	 0xBB, 0x60, 0x36, 0x78, 0xFF, 0xFF, 0x98, 0xFF, 0x43, 0xFF, 0x40, 0xFF, 0xB0, 0xFF, 0xB1, 0xFF,
+	 0x2D, 0x46, 0x0D, 0x60, 0x2C, 0x61, 0xA1, 0xD3, 0x2D, 0x46, 0x60, 0x40, 0x01, 0x2A, 0x0A, 0x00,
+	 0xF1, 0xF5, 0xF0, 0xF4, 0x59, 0xD1, 0x37, 0xF8, 0x05, 0x64, 0x59, 0xD1, 0xCC, 0x84, 0xBD, 0xD8,
+	 0xFC, 0x02, 0x2D, 0x46, 0xBB, 0x60, 0x20, 0x78, 0xFF, 0xFF, 0x98, 0xFF, 0x09, 0xE1, 0xA1, 0xFF,
+	 0x3D, 0x46, 0x08, 0x25, 0xE0, 0x01, 0x0F, 0xF2, 0x40, 0xFF, 0x02, 0xBC, 0xA2, 0xDA, 0xBB, 0x60,
+	 0x36, 0x78, 0xFF, 0xFF, 0x00, 0x64, 0x0D, 0x60, 0x2C, 0x62, 0xA2, 0xDB, 0x04, 0x64, 0x22, 0xFA,
+	 0x87, 0xF4, 0xA9, 0xF1, 0xFF, 0xFF, 0xD3, 0x80, 0x3B, 0xF2, 0xE7, 0x03, 0x60, 0x47, 0xC0, 0xB7,
+	 0x02, 0xFE, 0xF0, 0x84, 0xF0, 0x84, 0xF0, 0x84, 0x00, 0xA8, 0x40, 0x4A, 0x16, 0x03, 0xE0, 0x81,
+	 0x61, 0x43, 0x42, 0xFE, 0x00, 0x64, 0xF0, 0x84, 0xFE, 0x1F, 0x40, 0x4A, 0xE1, 0x84, 0xE0, 0x84,
+	 0x2D, 0x46, 0x07, 0xF4, 0xE0, 0x81, 0x37, 0xF0, 0x2A, 0x47, 0x0C, 0x60, 0x7A, 0x63, 0xA0, 0x84,
+	 0x47, 0x9C, 0x10, 0x03, 0x7C, 0x44, 0xA0, 0x63, 0x11, 0x00, 0x20, 0x64, 0x40, 0x4A, 0x63, 0x46,
+	 0x37, 0xF0, 0x66, 0x44, 0x64, 0x40, 0x80, 0x2B, 0x05, 0x00, 0x00, 0x60, 0x70, 0x7C, 0x00, 0x60,
+	 0x90, 0x63, 0x04, 0x00, 0x2D, 0x46, 0xBC, 0x60, 0x65, 0x78, 0xFF, 0xFF, 0x2D, 0x46, 0xEE, 0xFB,
+	 0xEF, 0xF9, 0xF0, 0xFD, 0x07, 0xF2, 0xF1, 0xFB, 0x60, 0x46, 0x37, 0xF0, 0x2A, 0x44, 0x0D, 0x60,
+	 0x2C, 0x62, 0x5A, 0xD9, 0x00, 0x65, 0x45, 0x4B, 0xA0, 0x84, 0xFF, 0xFF, 0x3F, 0x22, 0x05, 0x00,
+	 0x90, 0x84, 0x37, 0xFA, 0x01, 0x64, 0x40, 0x4B, 0x21, 0x00, 0xAD, 0x46, 0x0A, 0xA3, 0x3D, 0xF2,
+	 0xAD, 0x46, 0xA3, 0xD0, 0xAD, 0x46, 0xD0, 0x80, 0x3C, 0xF2, 0xAD, 0x46, 0x02, 0x03, 0x16, 0x07,
+	 0x14, 0x04, 0x5B, 0xD0, 0xAD, 0x46, 0xD0, 0x80, 0x3B, 0xF2, 0x03, 0x03, 0xAD, 0x46, 0x0E, 0x07,
+	 0x0C, 0x04, 0x3A, 0xF0, 0xAD, 0x46, 0x5B, 0xD0, 0x64, 0x5F, 0xD0, 0x80, 0x2B, 0x44, 0x18, 0x07,
+	 0x04, 0x03, 0xD0, 0x84, 0x10, 0xA4, 0xFF, 0xFF, 0x13, 0x07, 0x7F, 0x01, 0x01, 0x64, 0x0D, 0x60,
+	 0x2C, 0x62, 0xA2, 0xDB, 0x2D, 0x46, 0x0D, 0x60, 0x3C, 0x62, 0x80, 0xFF, 0x78, 0x44, 0x03, 0xA4,
+	 0xA2, 0xDB, 0xBD, 0x60, 0x0B, 0x78, 0xFF, 0xFF, 0x85, 0xFF, 0x2D, 0x46, 0x08, 0x25, 0x53, 0x01,
+	 0x2D, 0x46, 0x0D, 0x60, 0x3C, 0x62, 0x80, 0xFF, 0x78, 0x44, 0x03, 0xA4, 0xA2, 0xDB, 0xBD, 0x60,
+	 0x94, 0x78, 0xFF, 0xFF, 0x85, 0xFF, 0x2D, 0x46, 0x08, 0x25, 0x45, 0x01, 0x00, 0x60, 0x0F, 0x64,
+	 0xBB, 0x60, 0xD3, 0x78, 0xFF, 0xFF, 0x07, 0xF4, 0x66, 0x41, 0x03, 0xF2, 0x04, 0xF2, 0x40, 0x42,
+	 0x05, 0xF2, 0x40, 0x43, 0x40, 0x44, 0x61, 0x46, 0x3C, 0xF2, 0x3D, 0xF2, 0x40, 0x40, 0x40, 0x41,
+	 0x0D, 0x60, 0x70, 0x65, 0x00, 0x61, 0xEF, 0xF1, 0xEE, 0xF5, 0x44, 0x4C, 0x2C, 0x5C, 0xE9, 0x80,
+	 0x00, 0x64, 0xF0, 0x84, 0xF0, 0x84, 0xC0, 0x83, 0xBD, 0xD2, 0x24, 0x5C, 0x90, 0x9C, 0x64, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47,
+	 0x90, 0x9C, 0x20, 0x44, 0x40, 0x80, 0xDB, 0x83, 0xBD, 0xD2, 0x20, 0x5C, 0x90, 0x9C, 0x64, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47,
+	 0x90, 0x9C, 0x21, 0x44, 0x40, 0x81, 0xDB, 0x83, 0xBD, 0xD2, 0x21, 0x5C, 0x90, 0x9C, 0x64, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47,
+	 0x90, 0x9C, 0x22, 0x44, 0x40, 0x82, 0xDB, 0x83, 0xBD, 0xD2, 0x22, 0x5C, 0x90, 0x9C, 0x64, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47,
+	 0x90, 0x9C, 0x23, 0x44, 0x40, 0x83, 0xF2, 0xA3, 0xBD, 0xD2, 0x23, 0x5C, 0x90, 0x9C, 0x64, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47,
+	 0x90, 0x9C, 0x24, 0x44, 0xC0, 0x9C, 0x41, 0x84, 0xDD, 0x81, 0x08, 0x2A, 0xA7, 0x01, 0x0D, 0x60,
+	 0x2E, 0x61, 0x05, 0x64, 0xF0, 0xF4, 0xF1, 0xF5, 0xFE, 0xA3, 0x5B, 0xD0, 0xCC, 0x84, 0x59, 0xD9,
+	 0xFC, 0x02, 0xF0, 0xF3, 0xF1, 0xF5, 0x60, 0x42, 0x20, 0x44, 0xA2, 0xDA, 0x21, 0x44, 0x5A, 0xDA,
+	 0x22, 0x44, 0x5A, 0xDA, 0x23, 0x44, 0x5A, 0xDA, 0x24, 0x44, 0x5A, 0xDA, 0x61, 0x46, 0x0D, 0x60,
+	 0x3C, 0x62, 0xA2, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x41, 0xF0, 0xF3, 0xF1, 0xF5, 0xA0, 0xD2,
+	 0x5A, 0xD0, 0x40, 0x40, 0x44, 0x41, 0x5A, 0xD2, 0x5A, 0xD0, 0x40, 0x42, 0x5A, 0xD0, 0x44, 0x43,
+	 0x61, 0x46, 0xBA, 0xF0, 0x3B, 0xF2, 0x44, 0x44, 0x65, 0x5F, 0x40, 0x85, 0xEF, 0xF4, 0xEE, 0xF5,
+	 0x43, 0x4C, 0x0D, 0x60, 0x70, 0x65, 0xBD, 0xD2, 0x25, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C,
+	 0x20, 0x44, 0x40, 0x80, 0xBD, 0xD2, 0x20, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84,
+	 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x21, 0x44,
+	 0x40, 0x81, 0xBD, 0xD2, 0x21, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1,
+	 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x22, 0x44, 0x40, 0x82,
+	 0xBD, 0xD2, 0x22, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x23, 0x44, 0x40, 0x83, 0xBD, 0xD2,
+	 0x23, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x24, 0x44, 0x40, 0x84, 0xBD, 0xD2, 0x24, 0x5C,
+	 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84,
+	 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x25, 0x44, 0x40, 0x85, 0x61, 0x46, 0x3A, 0xF0, 0xFF, 0xFF,
+	 0x64, 0x44, 0xE0, 0x7F, 0xA0, 0x5B, 0x64, 0x47, 0xE1, 0x7F, 0x5A, 0xD0, 0xA0, 0x5B, 0x64, 0x44,
+	 0xE2, 0x7F, 0xA0, 0x5B, 0x64, 0x47, 0xEE, 0xF5, 0xBD, 0xD2, 0x25, 0x5C, 0x90, 0x84, 0xE8, 0x80,
+	 0xF8, 0x84, 0x20, 0x5C, 0x40, 0x80, 0x20, 0x44, 0xE4, 0x7F, 0xA0, 0x5B, 0x20, 0x47, 0xE5, 0x7F,
+	 0xA0, 0x5B, 0xBD, 0xD2, 0x20, 0x5C, 0x90, 0x84, 0xE8, 0x80, 0xF8, 0x84, 0x21, 0x5C, 0x40, 0x81,
+	 0x21, 0x44, 0xE6, 0x7F, 0xA0, 0x5B, 0x21, 0x47, 0xE7, 0x7F, 0xA0, 0x5B, 0x21, 0x44, 0xE8, 0x80,
+	 0xF8, 0x84, 0x22, 0x5C, 0x40, 0x82, 0x22, 0x44, 0xE8, 0x7F, 0xA0, 0x5B, 0x22, 0x47, 0xE9, 0x7F,
+	 0xA0, 0x5B, 0x22, 0x44, 0xE8, 0x80, 0xF8, 0x84, 0x23, 0x5C, 0x40, 0x83, 0x23, 0x44, 0xEA, 0x7F,
+	 0xA0, 0x5B, 0x23, 0x47, 0xEB, 0x7F, 0xA0, 0x5B, 0x23, 0x44, 0xE8, 0x80, 0xF8, 0x84, 0x24, 0x5C,
+	 0x40, 0x84, 0x24, 0x44, 0xEC, 0x7F, 0xA0, 0x5B, 0x24, 0x47, 0xED, 0x7F, 0xA0, 0x5B, 0x24, 0x44,
+	 0xE8, 0x80, 0xF8, 0x84, 0x25, 0x5C, 0x40, 0x85, 0x25, 0x44, 0xEE, 0x7F, 0xA0, 0x5B, 0x25, 0x47,
+	 0xEF, 0x7F, 0xA0, 0x5B, 0x2C, 0x43, 0xA3, 0xD2, 0x25, 0x5C, 0x90, 0x81, 0xE9, 0x84, 0xE3, 0x7F,
+	 0xA0, 0x5B, 0x0D, 0x60, 0x3C, 0x62, 0xA2, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0xF3, 0x5A, 0xD3,
+	 0x40, 0x48, 0x5A, 0xD3, 0x40, 0x49, 0x40, 0x4A, 0x00, 0x60, 0x70, 0x7C, 0x44, 0x4D, 0x45, 0xF2,
+	 0x46, 0xF2, 0x40, 0x47, 0x40, 0x46, 0x0D, 0x60, 0x70, 0x65, 0x00, 0x61, 0x2D, 0x5C, 0xE9, 0x80,
+	 0x00, 0x64, 0xF0, 0x84, 0xF0, 0x84, 0xC0, 0x83, 0xBD, 0xD2, 0x2A, 0x5C, 0x90, 0x9C, 0x64, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47,
+	 0x90, 0x9C, 0x26, 0x44, 0x40, 0x86, 0xDB, 0x83, 0xBD, 0xD2, 0x26, 0x5C, 0x90, 0x9C, 0x64, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47,
+	 0x90, 0x9C, 0x27, 0x44, 0x40, 0x87, 0xDB, 0x83, 0xBD, 0xD2, 0x27, 0x5C, 0x90, 0x9C, 0x64, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47,
+	 0x90, 0x9C, 0x28, 0x44, 0x40, 0x88, 0xDB, 0x83, 0xBD, 0xD2, 0x28, 0x5C, 0x90, 0x9C, 0x64, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47,
+	 0x90, 0x9C, 0x29, 0x44, 0x40, 0x89, 0xF2, 0xA3, 0xBD, 0xD2, 0x29, 0x5C, 0x90, 0x9C, 0x64, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47,
+	 0x90, 0x9C, 0x2A, 0x44, 0xC0, 0x9C, 0x41, 0x8A, 0xDD, 0x81, 0x08, 0x2A, 0xA7, 0x01, 0x26, 0x44,
+	 0x40, 0xFA, 0x27, 0x44, 0x41, 0xFA, 0x28, 0x44, 0x42, 0xFA, 0x29, 0x44, 0x43, 0xFA, 0x2A, 0x44,
+	 0x44, 0xFA, 0x0D, 0x60, 0x3E, 0x62, 0xA2, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x60, 0x80, 0x7C,
+	 0x44, 0x4D, 0x2D, 0x42, 0xA2, 0xD2, 0x5A, 0xD0, 0x40, 0x46, 0x44, 0x47, 0x5A, 0xD2, 0x5A, 0xD0,
+	 0x40, 0x48, 0x5A, 0xD0, 0x44, 0x49, 0x47, 0xF2, 0x44, 0x4A, 0x40, 0x8B, 0x60, 0x5C, 0x64, 0x47,
+	 0xE0, 0x7F, 0xA0, 0x5A, 0xFF, 0xB4, 0x20, 0xBC, 0x7F, 0xB4, 0xE1, 0x7F, 0xA0, 0x5A, 0x64, 0x44,
+	 0xE2, 0x7F, 0xA0, 0x5A, 0x00, 0x60, 0x70, 0x63, 0x0D, 0x60, 0x70, 0x65, 0xBD, 0xD2, 0x2B, 0x5C,
+	 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84,
+	 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x26, 0x44, 0x40, 0x86, 0xBD, 0xD2, 0x26, 0x5C, 0x90, 0x9C,
+	 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1,
+	 0x64, 0x47, 0x90, 0x9C, 0x27, 0x44, 0x40, 0x87, 0xBD, 0xD2, 0x27, 0x5C, 0x90, 0x9C, 0x64, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47,
+	 0x90, 0x9C, 0x28, 0x44, 0x40, 0x88, 0xBD, 0xD2, 0x28, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C,
+	 0x29, 0x44, 0x40, 0x89, 0xBD, 0xD2, 0x29, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84,
+	 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x2A, 0x44,
+	 0x40, 0x8A, 0xBD, 0xD2, 0x2A, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1,
+	 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x2B, 0x44, 0x40, 0x8B,
+	 0xBD, 0xD2, 0x2B, 0x5C, 0x90, 0x84, 0xE8, 0x80, 0xF8, 0x84, 0x26, 0x5C, 0x40, 0x86, 0x26, 0x44,
+	 0xE4, 0x7F, 0xA0, 0x5A, 0x26, 0x47, 0xE5, 0x7F, 0xA0, 0x5A, 0xBD, 0xD2, 0x26, 0x5C, 0x90, 0x84,
+	 0xE8, 0x80, 0xF8, 0x84, 0x27, 0x5C, 0x40, 0x87, 0x27, 0x44, 0xE6, 0x7F, 0xA0, 0x5A, 0x27, 0x47,
+	 0xE7, 0x7F, 0xA0, 0x5A, 0x27, 0x44, 0xE8, 0x80, 0xF8, 0x84, 0x28, 0x5C, 0x40, 0x88, 0x28, 0x44,
+	 0xE8, 0x7F, 0xA0, 0x5A, 0x28, 0x47, 0xE9, 0x7F, 0xA0, 0x5A, 0x28, 0x44, 0xE8, 0x80, 0xF8, 0x84,
+	 0x29, 0x5C, 0x40, 0x89, 0x29, 0x44, 0xEA, 0x7F, 0xA0, 0x5A, 0x29, 0x47, 0xEB, 0x7F, 0xA0, 0x5A,
+	 0x29, 0x44, 0xE8, 0x80, 0xF8, 0x84, 0x2A, 0x5C, 0x40, 0x8A, 0x2A, 0x44, 0xEC, 0x7F, 0xA0, 0x5A,
+	 0x2A, 0x47, 0xED, 0x7F, 0xA0, 0x5A, 0x2A, 0x44, 0xE8, 0x80, 0xF8, 0x84, 0x2B, 0x5C, 0x40, 0x8B,
+	 0x2B, 0x44, 0xEE, 0x7F, 0xA0, 0x5A, 0x2B, 0x47, 0xEF, 0x7F, 0xA0, 0x5A, 0x38, 0xF0, 0x2B, 0x44,
+	 0x90, 0x84, 0xE8, 0x84, 0xE3, 0x7F, 0xA0, 0x5A, 0x0D, 0x60, 0x3E, 0x62, 0xA2, 0xD7, 0xFF, 0xFF,
+	 0xFF, 0xFF, 0xE4, 0x60, 0xC8, 0x78, 0xFF, 0xFF, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1, 0x80, 0x60,
+	 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x32, 0x00, 0xDC, 0xF3, 0x31, 0x41, 0x01, 0xB1,
+	 0x03, 0xA8, 0x2D, 0x03, 0x17, 0x02, 0x20, 0x40, 0x04, 0x2B, 0x0C, 0x00, 0xBB, 0xFE, 0xCA, 0xFE,
+	 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x66, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x04, 0xFF, 0x08, 0x00, 0x0F, 0x60, 0xD2, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x04, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x0F, 0x60, 0xF6, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x80, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x0C, 0x00, 0xA9, 0xFE, 0xD8, 0x05, 0xAB, 0xFE, 0x0C, 0x05, 0xA8, 0xFE,
+	 0xC8, 0x05, 0xAA, 0xFE, 0xC9, 0x05, 0x78, 0x43, 0x01, 0x61, 0x24, 0x60, 0xDD, 0x78, 0xA1, 0xFF,
+	 0xFF, 0xFF, 0xFF, 0xFF, 0x85, 0x3E, 0x24, 0x60, 0x5E, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x00, 0xA8,
+	 0x60, 0x46, 0x03, 0x02, 0xBF, 0x60, 0xE7, 0x78, 0xFF, 0xFF, 0x26, 0x45, 0xD4, 0x80, 0x0F, 0xF0,
+	 0xF9, 0x03, 0x64, 0x44, 0x70, 0xB0, 0x70, 0x2A, 0x14, 0x00, 0x27, 0x60, 0xB2, 0x64, 0xA0, 0xD3,
+	 0xFF, 0xFF, 0xDC, 0x84, 0xFF, 0xFF, 0x08, 0x28, 0xA2, 0xDB, 0xA2, 0xFF, 0xAF, 0xF3, 0xFF, 0xFF,
+	 0xCC, 0x84, 0xFE, 0xA0, 0xAF, 0xFB, 0x01, 0x07, 0xD4, 0xFE, 0xA3, 0xFF, 0xC5, 0x60, 0x5B, 0x78,
+	 0xFF, 0xFF, 0x64, 0x40, 0x02, 0x26, 0x09, 0x00, 0x66, 0x45, 0x09, 0xF4, 0x0F, 0xF2, 0x02, 0x18,
+	 0x65, 0x46, 0xE3, 0x1B, 0x00, 0x64, 0x40, 0x46, 0xCA, 0x01, 0xA2, 0xFF, 0xAF, 0xF3, 0x46, 0x46,
+	 0xCC, 0x84, 0xFE, 0xA0, 0xAF, 0xFB, 0x01, 0x07, 0xD4, 0xFE, 0xA3, 0xFF, 0x0F, 0xF0, 0xA3, 0xFC,
+	 0x64, 0x44, 0x80, 0x26, 0x22, 0x00, 0xB8, 0xF1, 0x27, 0x60, 0x92, 0x64, 0xA0, 0xD3, 0xFF, 0xFF,
+	 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00,
+	 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x32, 0x44, 0x01, 0x2A, 0x03, 0x00, 0x07, 0x60,
+	 0x01, 0x64, 0x04, 0x00, 0x02, 0x2A, 0x06, 0x00, 0x00, 0x60, 0x01, 0x64, 0x23, 0xFA, 0xC5, 0x60,
+	 0x67, 0x78, 0xFF, 0xFF, 0xC5, 0x60, 0x5B, 0x78, 0xFF, 0xFF, 0x08, 0x26, 0x3F, 0x00, 0x2A, 0xF2,
+	 0x60, 0x63, 0x60, 0x40, 0x02, 0x2B, 0x66, 0x63, 0xBE, 0xD2, 0x83, 0xF1, 0xA3, 0xD2, 0xD0, 0x80,
+	 0x82, 0xF1, 0x18, 0x02, 0xBF, 0xD2, 0xD0, 0x80, 0x81, 0xF1, 0x14, 0x02, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x11, 0x02, 0xB8, 0xF1, 0x27, 0x60, 0x9E, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80,
+	 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60,
+	 0x00, 0x75, 0x88, 0xFF, 0x32, 0x44, 0x01, 0x2A, 0x03, 0x00, 0x07, 0x60, 0x02, 0x64, 0x04, 0x00,
+	 0x02, 0x2A, 0x06, 0x00, 0x00, 0x60, 0x02, 0x64, 0x23, 0xFA, 0xC5, 0x60, 0x67, 0x78, 0xFF, 0xFF,
+	 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0xB0, 0x3A, 0x06, 0x00, 0x00, 0x60, 0x02, 0x64, 0x23, 0xFA,
+	 0xC1, 0x60, 0x11, 0x78, 0xFF, 0xFF, 0xC5, 0x60, 0x5B, 0x78, 0xFF, 0xFF, 0x32, 0x44, 0x01, 0x2A,
+	 0x4A, 0x00, 0x28, 0x60, 0xE2, 0x63, 0xBF, 0xD3, 0x00, 0x65, 0xB4, 0x81, 0xDB, 0x83, 0x3D, 0x03,
+	 0xBF, 0xD3, 0xA3, 0xD3, 0x40, 0x48, 0xBE, 0xD3, 0x40, 0x4A, 0x2E, 0xF0, 0x40, 0x4C, 0xD0, 0x80,
+	 0x2D, 0xF0, 0x08, 0x02, 0x2A, 0x44, 0xD0, 0x80, 0x2C, 0xF0, 0x04, 0x02, 0x28, 0x44, 0xD0, 0x80,
+	 0xFF, 0xFF, 0x2B, 0x03, 0x31, 0xF0, 0x2C, 0x44, 0xD0, 0x80, 0x30, 0xF0, 0x08, 0x02, 0x2A, 0x44,
+	 0xD0, 0x80, 0x2F, 0xF0, 0x04, 0x02, 0x28, 0x44, 0xD0, 0x80, 0xFF, 0xFF, 0x1E, 0x03, 0x34, 0xF0,
+	 0x2C, 0x44, 0xD0, 0x80, 0x33, 0xF0, 0x08, 0x02, 0x2A, 0x44, 0xD0, 0x80, 0x32, 0xF0, 0x04, 0x02,
+	 0x28, 0x44, 0xD0, 0x80, 0xFF, 0xFF, 0x11, 0x03, 0x38, 0xF0, 0x2C, 0x44, 0xD0, 0x80, 0x37, 0xF0,
+	 0x08, 0x02, 0x2A, 0x44, 0xD0, 0x80, 0x36, 0xF0, 0x04, 0x02, 0x28, 0x44, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x04, 0x03, 0xFA, 0xA1, 0x06, 0xA3, 0xB7, 0x03, 0xC3, 0x01, 0x07, 0x60, 0x00, 0x64, 0x23, 0xFA,
+	 0xC5, 0x60, 0x67, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0x0F, 0xF0, 0x60, 0x45, 0xA4, 0x36, 0x08, 0x00,
+	 0x0C, 0xB4, 0x04, 0x36, 0x02, 0x00, 0x0C, 0x3A, 0x06, 0x00, 0xC5, 0x60, 0x5B, 0x78, 0xFF, 0xFF,
+	 0xC2, 0x60, 0xDD, 0x78, 0xFF, 0xFF, 0x0F, 0xF0, 0x65, 0x40, 0x40, 0x2B, 0x22, 0x00, 0x32, 0x40,
+	 0x08, 0x26, 0x1F, 0x00, 0x07, 0xF4, 0x36, 0xF2, 0xFF, 0xFF, 0x37, 0xB4, 0x26, 0x46, 0x19, 0x02,
+	 0x2C, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x26, 0x11, 0x00, 0xB8, 0xF1, 0x27, 0x60, 0x98, 0x64,
+	 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24,
+	 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0xC5, 0x60, 0x5B, 0x78,
+	 0xFF, 0xFF, 0x2A, 0xF2, 0x64, 0x40, 0x60, 0x26, 0x03, 0x00, 0xC2, 0x60, 0xAF, 0x78, 0xFF, 0xFF,
+	 0x60, 0x41, 0xA9, 0xF3, 0x07, 0xFA, 0x61, 0x44, 0x80, 0x3A, 0x06, 0x00, 0xE5, 0x60, 0x58, 0x4F,
+	 0xE7, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0x10, 0x00, 0x60, 0x40, 0x40, 0x3A, 0x0D, 0x00, 0xDC, 0xF3,
+	 0xFF, 0xFF, 0x07, 0xB4, 0x03, 0x3A, 0xE2, 0x01, 0xC6, 0x60, 0x58, 0x4D, 0x4F, 0x78, 0xFF, 0xFF,
+	 0xDD, 0x02, 0xA9, 0xF3, 0x07, 0xFA, 0xD1, 0x00, 0x5E, 0x63, 0x60, 0x40, 0x02, 0x2B, 0x64, 0x63,
+	 0x50, 0xFE, 0xBD, 0xD2, 0x81, 0xF1, 0xBD, 0xD2, 0xD0, 0x80, 0x82, 0xF1, 0xBD, 0xD2, 0xD0, 0x80,
+	 0x83, 0xF1, 0x2A, 0xF2, 0xD0, 0x80, 0x60, 0x40, 0x08, 0x3A, 0x07, 0x00, 0x01, 0x0C, 0xC6, 0x01,
+	 0xDE, 0x60, 0x58, 0x4F, 0xFE, 0x78, 0xFF, 0xFF, 0xB8, 0x00, 0x26, 0x0C, 0xC6, 0x60, 0x58, 0x4D,
+	 0x4F, 0x78, 0xFF, 0xFF, 0xBB, 0x02, 0x1F, 0x60, 0x52, 0x61, 0x02, 0x64, 0xA1, 0xDB, 0x1F, 0x60,
+	 0x5A, 0x61, 0x00, 0x64, 0xA1, 0xDB, 0x22, 0x60, 0x58, 0x4E, 0x3E, 0x78, 0xFF, 0xFF, 0x1F, 0x60,
+	 0x04, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0x60, 0x40, 0x80, 0x27, 0x08, 0x00, 0x0F, 0x60, 0xEA, 0x62,
+	 0xA2, 0xD1, 0x00, 0x60, 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x1F, 0x60, 0x52, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x9B, 0x01, 0x91, 0x00, 0xC6, 0x60, 0x58, 0x4D, 0x4F, 0x78, 0xFF, 0xFF,
+	 0xFA, 0x02, 0x0F, 0x60, 0xCE, 0x61, 0xA1, 0xD3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x36, 0x07, 0x00,
+	 0x01, 0x64, 0xA1, 0xDB, 0x01, 0x65, 0xE9, 0x60, 0x58, 0x4E, 0x7B, 0x78, 0xFF, 0xFF, 0x26, 0x46,
+	 0x31, 0xF2, 0x1C, 0x60, 0xBA, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41,
+	 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46, 0x31, 0xF0, 0x63, 0x46, 0xD0, 0x80,
+	 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46, 0x30, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02,
+	 0x61, 0x46, 0x2F, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF,
+	 0x63, 0x46, 0xE8, 0x1B, 0xA9, 0xF3, 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0xA9, 0xF1, 0x43, 0x43,
+	 0xD3, 0x80, 0xFF, 0xFF, 0x04, 0x02, 0xC5, 0x60, 0x58, 0x4F, 0xA5, 0x78, 0xFF, 0xFF, 0x32, 0x40,
+	 0x08, 0x2A, 0x05, 0x00, 0x63, 0x46, 0x80, 0x60, 0x02, 0x64, 0x06, 0xFA, 0x26, 0x46, 0xD8, 0xF3,
+	 0x63, 0x45, 0x66, 0x41, 0x65, 0x46, 0x8C, 0xFA, 0x60, 0x40, 0x01, 0x36, 0x06, 0x00, 0x02, 0x36,
+	 0x04, 0x00, 0x04, 0x36, 0x02, 0x00, 0x05, 0x3A, 0x02, 0x00, 0x00, 0x64, 0x01, 0x00, 0x01, 0x64,
+	 0x6F, 0xFA, 0x79, 0xF3, 0x7A, 0xF1, 0xFF, 0xFF, 0xA0, 0x84, 0x65, 0x43, 0x02, 0x02, 0x79, 0xF3,
+	 0xFF, 0xFF, 0x60, 0x41, 0x0F, 0x60, 0xAE, 0x65, 0xD8, 0xF3, 0xFF, 0xFF, 0xE0, 0x84, 0x44, 0xD3,
+	 0x61, 0x45, 0xA4, 0x80, 0xFF, 0xFF, 0x04, 0x02, 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0xFC, 0x03,
+	 0xA4, 0x84, 0x7B, 0xFB, 0x6F, 0xF0, 0x60, 0x47, 0x90, 0x84, 0x6F, 0xFA, 0x60, 0x47, 0x60, 0x45,
+	 0x80, 0x64, 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0xFC, 0x03, 0xA4, 0x84, 0x70, 0xF0, 0x70, 0xFA,
+	 0x00, 0x61, 0xE8, 0x84, 0xFF, 0xFF, 0x02, 0x05, 0xDD, 0x81, 0xFB, 0x01, 0xE1, 0x81, 0x0F, 0x60,
+	 0xA2, 0x65, 0x45, 0xD3, 0x0E, 0xFA, 0x66, 0x43, 0x0C, 0xF4, 0xB8, 0xF1, 0x27, 0x60, 0x8C, 0x64,
+	 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24,
+	 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x27, 0xF2, 0xFF, 0xFF,
+	 0x60, 0x40, 0x01, 0x3B, 0x12, 0x00, 0xB8, 0xF1, 0x27, 0x60, 0x9A, 0x64, 0xA0, 0xD3, 0xFF, 0xFF,
+	 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00,
+	 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x13, 0x00, 0x02, 0x3B, 0x11, 0x00, 0xB8, 0xF1,
+	 0x27, 0x60, 0x9C, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03,
+	 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF,
+	 0x1B, 0xF2, 0xFF, 0xFF, 0xE4, 0xA4, 0x3E, 0xFA, 0x2A, 0xF2, 0x28, 0x41, 0x40, 0xA8, 0x01, 0xB1,
+	 0x02, 0x02, 0x62, 0x02, 0x92, 0x00, 0x60, 0x40, 0x08, 0x2A, 0x2B, 0x00, 0xB8, 0xF1, 0x27, 0x60,
+	 0x8A, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB,
+	 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x1B, 0xF2,
+	 0xFF, 0xFF, 0x60, 0x45, 0xB8, 0xF1, 0x27, 0x60, 0x90, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xD8, 0x80,
+	 0xC4, 0x84, 0x0B, 0x03, 0x07, 0x05, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x09, 0x04,
+	 0xC6, 0xFE, 0x07, 0x00, 0x00, 0x64, 0xB8, 0x84, 0xA2, 0xDB, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75,
+	 0x88, 0xFF, 0x0F, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x40, 0x26, 0x28, 0x00, 0x32, 0x44, 0x02, 0x26,
+	 0x25, 0x00, 0x10, 0x2B, 0x29, 0x00, 0x28, 0x60, 0xE2, 0x63, 0xBF, 0xD3, 0x2C, 0xF0, 0x00, 0xA8,
+	 0x60, 0x41, 0x0D, 0x03, 0x50, 0xFE, 0xBD, 0xD3, 0x2D, 0xF0, 0xD0, 0x80, 0xBD, 0xD3, 0x2E, 0xF0,
+	 0xD0, 0x80, 0xBD, 0xD3, 0x2C, 0xF0, 0xD0, 0x80, 0xFA, 0xA1, 0x10, 0x0C, 0xF3, 0x02, 0x50, 0xFE,
+	 0x60, 0x60, 0x01, 0x64, 0xD0, 0x80, 0x2D, 0xF0, 0x1D, 0x64, 0xD0, 0x80, 0x2E, 0xF0, 0x01, 0x64,
+	 0xD0, 0x80, 0xFF, 0xFF, 0x03, 0x0C, 0xC5, 0x60, 0x5B, 0x78, 0xFF, 0xFF, 0x32, 0x40, 0x40, 0x2A,
+	 0x03, 0x00, 0x19, 0x60, 0x22, 0x78, 0xFF, 0xFF, 0xC5, 0x60, 0x55, 0x78, 0xFF, 0xFF, 0x32, 0x40,
+	 0x40, 0x26, 0xF7, 0x01, 0x2A, 0xF0, 0xFF, 0xFF, 0x64, 0x40, 0x08, 0x2A, 0x2A, 0x00, 0xDC, 0xF3,
+	 0xFF, 0xFF, 0x07, 0xB4, 0x03, 0xA8, 0xFF, 0xFF, 0x03, 0x03, 0x32, 0x40, 0x02, 0x2A, 0x1D, 0x00,
+	 0x03, 0x67, 0xA0, 0x84, 0x00, 0x37, 0x64, 0x63, 0x60, 0x40, 0x02, 0x37, 0x5E, 0x63, 0x60, 0x40,
+	 0x01, 0x37, 0x58, 0x63, 0x60, 0x40, 0x03, 0x37, 0x0D, 0x00, 0xBD, 0xD2, 0x81, 0xF1, 0xBD, 0xD2,
+	 0xD0, 0x80, 0x82, 0xF1, 0x07, 0x02, 0xD0, 0x80, 0xBD, 0xD2, 0x83, 0xF1, 0x03, 0x02, 0xD0, 0x80,
+	 0xFF, 0xFF, 0x03, 0x03, 0xC5, 0x60, 0x5B, 0x78, 0xFF, 0xFF, 0xDE, 0x60, 0x58, 0x4F, 0xFE, 0x78,
+	 0xFF, 0xFF, 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x08, 0x26, 0x06, 0x00, 0x20, 0x40, 0x10, 0x2B,
+	 0x03, 0x00, 0xC5, 0x60, 0x55, 0x78, 0xFF, 0xFF, 0x87, 0xF4, 0xA9, 0xF1, 0x27, 0x1B, 0x31, 0xF2,
+	 0x1C, 0x60, 0xBA, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46,
+	 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46, 0x31, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2,
+	 0x0C, 0x02, 0x61, 0x46, 0x30, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46,
+	 0x2F, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46,
+	 0xE8, 0x1B, 0xA9, 0xF3, 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0x03, 0x00, 0xD3, 0x80, 0xFF, 0xFF,
+	 0xD6, 0x03, 0x43, 0x43, 0xDC, 0xF3, 0x32, 0x40, 0x02, 0x26, 0x04, 0x00, 0x07, 0xB4, 0x03, 0xA8,
+	 0x2A, 0xF2, 0x5F, 0x02, 0xA9, 0xF1, 0x23, 0x43, 0xD3, 0x80, 0xFF, 0xFF, 0x5A, 0x02, 0xC5, 0x60,
+	 0x58, 0x4F, 0xA5, 0x78, 0xFF, 0xFF, 0x32, 0x40, 0x02, 0x2A, 0x05, 0x00, 0x63, 0x46, 0x02, 0x64,
+	 0x06, 0xFA, 0x26, 0x46, 0x4E, 0x00, 0x32, 0x40, 0x08, 0x2A, 0x05, 0x00, 0x63, 0x46, 0x80, 0x60,
+	 0x02, 0x64, 0x06, 0xFA, 0x26, 0x46, 0xD8, 0xF3, 0x63, 0x45, 0x66, 0x41, 0x65, 0x46, 0x8C, 0xFA,
+	 0x60, 0x40, 0x01, 0x36, 0x06, 0x00, 0x02, 0x36, 0x04, 0x00, 0x04, 0x36, 0x02, 0x00, 0x05, 0x3A,
+	 0x02, 0x00, 0x00, 0x64, 0x01, 0x00, 0x01, 0x64, 0x6F, 0xFA, 0x79, 0xF3, 0x7A, 0xF1, 0xFF, 0xFF,
+	 0xA0, 0x84, 0x65, 0x43, 0x02, 0x02, 0x79, 0xF3, 0xFF, 0xFF, 0x60, 0x41, 0x0F, 0x60, 0xAE, 0x65,
+	 0xD8, 0xF3, 0xFF, 0xFF, 0xE0, 0x84, 0x44, 0xD3, 0x61, 0x45, 0xA4, 0x80, 0xFF, 0xFF, 0x04, 0x02,
+	 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0xFC, 0x03, 0xA4, 0x84, 0x7B, 0xFB, 0x6F, 0xF0, 0x60, 0x47,
+	 0x90, 0x84, 0x6F, 0xFA, 0x60, 0x47, 0x60, 0x45, 0x80, 0x64, 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF,
+	 0xFC, 0x03, 0xA4, 0x84, 0x70, 0xF0, 0x70, 0xFA, 0x00, 0x61, 0xE8, 0x84, 0xFF, 0xFF, 0x02, 0x05,
+	 0xDD, 0x81, 0xFB, 0x01, 0xE1, 0x81, 0x0F, 0x60, 0xA2, 0x65, 0x45, 0xD3, 0x0E, 0xFA, 0x66, 0x43,
+	 0x0C, 0xF4, 0x07, 0xFC, 0x43, 0x43, 0x02, 0xFE, 0x1D, 0xF0, 0x1C, 0x60, 0x9A, 0x62, 0xC0, 0x64,
+	 0xC0, 0x84, 0xA2, 0xD1, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xC0, 0x84,
+	 0xA2, 0xDB, 0x2A, 0xF2, 0x63, 0x45, 0x0C, 0xB4, 0x08, 0x3A, 0x0A, 0x00, 0xDC, 0xF3, 0x23, 0x46,
+	 0x07, 0xB4, 0xFD, 0xA0, 0x06, 0xF2, 0x26, 0x46, 0x03, 0x03, 0x60, 0x40, 0x02, 0x2A, 0x0D, 0x00,
+	 0x2A, 0xF2, 0x35, 0xF0, 0x60, 0x40, 0xA4, 0x36, 0x0B, 0x00, 0x08, 0x2B, 0x0C, 0x00, 0x23, 0x46,
+	 0x22, 0xF2, 0x26, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x06, 0x02, 0xC5, 0x60, 0x5B, 0x78, 0xFF, 0xFF,
+	 0xC5, 0x60, 0x55, 0x78, 0xFF, 0xFF, 0x23, 0x46, 0x1E, 0xF2, 0x26, 0x46, 0x44, 0x4C, 0x0F, 0x26,
+	 0x1D, 0x00, 0x00, 0xBC, 0x40, 0x45, 0x0B, 0x03, 0x00, 0x64, 0x23, 0x46, 0x1E, 0xFA, 0x26, 0x46,
+	 0xA2, 0xFF, 0xAF, 0x60, 0x58, 0x4E, 0x95, 0x78, 0xFF, 0xFF, 0xA3, 0xFF, 0x26, 0x46, 0x2A, 0xF0,
+	 0x2C, 0x44, 0x64, 0x40, 0x04, 0x27, 0x0A, 0x00, 0x23, 0x46, 0x22, 0xFA, 0x26, 0x46, 0x1B, 0xF2,
+	 0xFF, 0xFF, 0xE4, 0xA4, 0x3E, 0xFA, 0xC4, 0x60, 0xAD, 0x78, 0xFF, 0xFF, 0x3F, 0xF2, 0x02, 0xFA,
+	 0xA2, 0xFF, 0x16, 0xF0, 0xFF, 0xFF, 0x64, 0x44, 0x01, 0x26, 0xDC, 0x9C, 0xB3, 0xF3, 0x2A, 0xF2,
+	 0xDC, 0x83, 0xB3, 0xFD, 0x06, 0xF4, 0x01, 0xF8, 0x26, 0x46, 0x60, 0x40, 0x40, 0x2B, 0x18, 0x00,
+	 0x64, 0x44, 0x00, 0x65, 0xFF, 0xB4, 0xFC, 0xA4, 0x06, 0xF0, 0x03, 0x03, 0x64, 0x46, 0x0C, 0x0D,
+	 0x02, 0x65, 0x26, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xD0, 0x80, 0xFF, 0xFF, 0x02, 0x03, 0x60, 0x46,
+	 0xF9, 0x01, 0x01, 0xF2, 0xFF, 0xFF, 0xD4, 0x84, 0x01, 0xFA, 0x66, 0x44, 0x26, 0x46, 0x06, 0xFA,
+	 0x06, 0xF4, 0x00, 0xF2, 0x80, 0xFC, 0x40, 0x45, 0xAF, 0x60, 0x58, 0x4E, 0x95, 0x78, 0xFF, 0xFF,
+	 0xA3, 0xFF, 0x26, 0x46, 0x2C, 0x44, 0x0F, 0x26, 0x14, 0x00, 0x23, 0x46, 0x22, 0xFA, 0x26, 0x44,
+	 0x1E, 0xFA, 0x26, 0x46, 0x1B, 0xF2, 0xFF, 0xFF, 0xE4, 0xA4, 0x3E, 0xFA, 0x24, 0x60, 0x74, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0x6F, 0x00, 0xA3, 0x46, 0x22, 0xF2, 0x60, 0x45, 0xDC, 0x84, 0xD4, 0x80, 0x22, 0xFA, 0xA3, 0x46,
+	 0x6C, 0x02, 0x2A, 0xF0, 0xA3, 0x46, 0x1E, 0xF2, 0xA3, 0x46, 0x00, 0xBC, 0x00, 0xF2, 0x01, 0x02,
+	 0x64, 0x00, 0x44, 0x4C, 0x3F, 0xF0, 0x60, 0x43, 0x23, 0x46, 0x1E, 0xF4, 0x09, 0x60, 0x00, 0x65,
+	 0x3F, 0xF2, 0x26, 0x46, 0xC0, 0x84, 0xD4, 0x80, 0x60, 0x45, 0x57, 0x07, 0x80, 0xFC, 0x1B, 0xF2,
+	 0x06, 0xF2, 0x60, 0x41, 0x23, 0x46, 0x1E, 0xF4, 0x1B, 0xF0, 0x06, 0xF0, 0xC1, 0x81, 0x06, 0xFA,
+	 0x05, 0xFA, 0x9B, 0xFA, 0x65, 0x44, 0x3F, 0xFA, 0x64, 0x46, 0x00, 0xFC, 0x63, 0x46, 0x01, 0xF2,
+	 0x10, 0x61, 0xF2, 0xA4, 0x01, 0xFA, 0xC8, 0x83, 0x02, 0x64, 0x59, 0xD0, 0x58, 0xD8, 0xFD, 0x1F,
+	 0x06, 0x45, 0x24, 0x60, 0x74, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x25, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xA2, 0xFF, 0x00, 0xF4, 0x01, 0xF0, 0x0A, 0x18, 0x70, 0x67,
+	 0xA0, 0x80, 0xF0, 0x67, 0x06, 0x03, 0xC0, 0x84, 0x01, 0xFA, 0x25, 0x46, 0x25, 0x44, 0x80, 0xFC,
+	 0x05, 0xFA, 0xAF, 0x60, 0x58, 0x4E, 0x95, 0x78, 0xFF, 0xFF, 0xD4, 0xFE, 0xA3, 0xFF, 0x2C, 0x44,
+	 0x04, 0x27, 0x16, 0x00, 0x23, 0x46, 0x1E, 0xF2, 0x9E, 0xFC, 0x60, 0x46, 0x46, 0x46, 0x3F, 0xF2,
+	 0x00, 0xF4, 0x60, 0x47, 0x08, 0xFA, 0x26, 0x46, 0x2C, 0x43, 0x2A, 0xFC, 0x06, 0xF4, 0x00, 0x64,
+	 0x00, 0xFA, 0x01, 0xF0, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84, 0x01, 0xFA, 0x26, 0x46, 0x1D, 0x00,
+	 0x00, 0x66, 0x46, 0x46, 0xBF, 0x60, 0xEB, 0x78, 0xFF, 0xFF, 0xA3, 0x46, 0x1E, 0xF0, 0x9E, 0xFC,
+	 0x00, 0x63, 0x33, 0x85, 0xA3, 0x46, 0x0D, 0x03, 0xA3, 0x46, 0x22, 0xF2, 0x0F, 0x65, 0xA4, 0x85,
+	 0xD4, 0x84, 0x22, 0xFA, 0xA3, 0x46, 0xA2, 0xFF, 0xAF, 0x60, 0x58, 0x4E, 0x95, 0x78, 0xFF, 0xFF,
+	 0xA3, 0xFF, 0x26, 0x46, 0xC5, 0x60, 0x5B, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0x32, 0xF0, 0x60, 0x40,
+	 0x08, 0x2A, 0x5C, 0x00, 0x01, 0x2B, 0x2F, 0x00, 0x64, 0x40, 0x01, 0x2A, 0x2C, 0x00, 0xB8, 0xF1,
+	 0x27, 0x60, 0x8A, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03,
+	 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF,
+	 0x1B, 0xF2, 0xFF, 0xFF, 0x60, 0x45, 0xB8, 0xF1, 0x27, 0x60, 0x90, 0x64, 0xA0, 0xD3, 0xFF, 0xFF,
+	 0xD8, 0x80, 0xC4, 0x84, 0x0B, 0x03, 0x07, 0x05, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB,
+	 0x09, 0x04, 0xC6, 0xFE, 0x07, 0x00, 0x00, 0x64, 0xB8, 0x84, 0xA2, 0xDB, 0x8A, 0xFF, 0x20, 0x60,
+	 0x00, 0x75, 0x88, 0xFF, 0x2B, 0x00, 0xB8, 0xF1, 0x27, 0x60, 0x88, 0x64, 0xA0, 0xD3, 0xFF, 0xFF,
+	 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00,
+	 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x1B, 0xF2, 0xFF, 0xFF, 0x60, 0x45, 0xB8, 0xF1,
+	 0x27, 0x60, 0x8E, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xD8, 0x80, 0xC4, 0x84, 0x0B, 0x03, 0x07, 0x05,
+	 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x09, 0x04, 0xC6, 0xFE, 0x07, 0x00, 0x00, 0x64,
+	 0xB8, 0x84, 0xA2, 0xDB, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x07, 0xF4, 0xFF, 0xFF,
+	 0x22, 0xF2, 0x26, 0x46, 0x0F, 0xB4, 0xDC, 0x85, 0xB8, 0xF1, 0x27, 0x60, 0x8C, 0x64, 0xA0, 0xD3,
+	 0xFF, 0xFF, 0xD8, 0x80, 0xC4, 0x84, 0x0B, 0x03, 0x07, 0x05, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03,
+	 0xA2, 0xDB, 0x09, 0x04, 0xC6, 0xFE, 0x07, 0x00, 0x00, 0x64, 0xB8, 0x84, 0xA2, 0xDB, 0x8A, 0xFF,
+	 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x27, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x3B, 0x12, 0x00,
+	 0xB8, 0xF1, 0x27, 0x60, 0x9A, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80,
+	 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75,
+	 0x88, 0xFF, 0x13, 0x00, 0x02, 0x3B, 0x11, 0x00, 0xB8, 0xF1, 0x27, 0x60, 0x9C, 0x64, 0xA0, 0xD3,
+	 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE,
+	 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0xC6, 0x60, 0x85, 0x78, 0xFF, 0xFF,
+	 0xBF, 0x60, 0xEB, 0x78, 0xFF, 0xFF, 0x24, 0x60, 0x74, 0x64, 0x40, 0x4B, 0x2C, 0x60, 0x58, 0x4D,
+	 0xD8, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0xBF, 0x60, 0xEB, 0x78, 0xFF, 0xFF, 0x24, 0x60,
+	 0x74, 0x62, 0x24, 0x60, 0x58, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB,
+	 0xFF, 0xFF, 0x2B, 0xFF, 0xF8, 0xFE, 0x00, 0x66, 0x46, 0x46, 0xBF, 0x60, 0xEB, 0x78, 0xFF, 0xFF,
+	 0x2A, 0xF2, 0x58, 0x63, 0x60, 0x47, 0x01, 0x27, 0x64, 0x63, 0x31, 0x60, 0x28, 0x62, 0x61, 0x5C,
+	 0xA2, 0xD9, 0xBD, 0xD0, 0xBD, 0xD0, 0x64, 0x45, 0x64, 0x41, 0xBD, 0xD0, 0x00, 0xF4, 0x04, 0xF8,
+	 0x83, 0xFA, 0x82, 0xF8, 0xA6, 0x46, 0x02, 0xB0, 0x5E, 0x63, 0x04, 0x03, 0x64, 0x63, 0x03, 0xB0,
+	 0x02, 0x3A, 0x6C, 0x63, 0x3F, 0xF2, 0xBD, 0xD0, 0xBD, 0xD0, 0x64, 0x45, 0x64, 0x41, 0xBD, 0xD0,
+	 0xA6, 0x46, 0x07, 0xF8, 0x86, 0xFA, 0x85, 0xF8, 0x60, 0x47, 0x08, 0xFA, 0x31, 0x60, 0x28, 0x62,
+	 0xA2, 0xD1, 0x26, 0x46, 0x64, 0x41, 0x2F, 0x58, 0xFF, 0xFF, 0xA9, 0xF5, 0x00, 0xF2, 0x26, 0x46,
+	 0x31, 0xF0, 0x39, 0x18, 0x66, 0x41, 0x1C, 0x60, 0xBA, 0x65, 0x64, 0x47, 0x00, 0x7F, 0xA9, 0xF1,
+	 0xE0, 0x84, 0x44, 0xD3, 0x64, 0x43, 0x11, 0x18, 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xFC, 0x1B,
+	 0x66, 0x44, 0x64, 0x46, 0x80, 0xF0, 0x60, 0x46, 0x80, 0xF8, 0x65, 0x46, 0x65, 0x43, 0x80, 0xF0,
+	 0x01, 0xFA, 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8, 0x0B, 0x00, 0x64, 0x46, 0x62, 0x43, 0x00, 0xF2,
+	 0xA3, 0xDB, 0x60, 0x46, 0x80, 0xF0, 0x81, 0xFC, 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8, 0x60, 0x43,
+	 0x61, 0x46, 0x1E, 0x60, 0xBC, 0x61, 0xA1, 0xD3, 0x1E, 0x60, 0xFE, 0x7C, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x07, 0x03, 0xA0, 0xDD, 0xDA, 0x9C, 0xA1, 0xD9, 0x49, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xA1, 0xDB,
+	 0xC6, 0x60, 0x40, 0x78, 0xFF, 0xFF, 0x20, 0x7C, 0x72, 0x44, 0xFF, 0xB4, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x02, 0x04, 0xD0, 0x84, 0xFB, 0x01, 0xE0, 0x83, 0xA9, 0xF3, 0x02, 0xA3, 0x43, 0x93, 0xA9, 0xF3,
+	 0xFF, 0xFF, 0x02, 0xA5, 0xD7, 0x80, 0x04, 0xA5, 0x08, 0x24, 0x65, 0x43, 0x66, 0x41, 0x63, 0x46,
+	 0x05, 0xF2, 0x00, 0xF0, 0x81, 0xF0, 0x02, 0x18, 0x64, 0x46, 0x81, 0xF8, 0x07, 0x1B, 0x1C, 0x60,
+	 0xBA, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD9, 0x02, 0x00, 0x65, 0x46, 0x00, 0xF8,
+	 0xA9, 0xF3, 0x63, 0x45, 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xD4, 0x80, 0x01, 0x18, 0xFA, 0x04,
+	 0x80, 0xF8, 0x65, 0x46, 0x00, 0xFA, 0x06, 0xF2, 0xFF, 0xFF, 0x00, 0x7E, 0x06, 0xFA, 0x61, 0x46,
+	 0x31, 0xF0, 0x66, 0x41, 0x1C, 0x60, 0xBA, 0x65, 0x64, 0x47, 0x00, 0x7F, 0xA9, 0xF1, 0xE0, 0x84,
+	 0x44, 0xD3, 0x64, 0x43, 0x11, 0x18, 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xFC, 0x1B, 0x66, 0x44,
+	 0x64, 0x46, 0x80, 0xF0, 0x60, 0x46, 0x80, 0xF8, 0x65, 0x46, 0x65, 0x43, 0x80, 0xF0, 0x01, 0xFA,
+	 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8, 0x0B, 0x00, 0x64, 0x46, 0x62, 0x43, 0x00, 0xF2, 0xA3, 0xDB,
+	 0x60, 0x46, 0x80, 0xF0, 0x81, 0xFC, 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8, 0x60, 0x43, 0x61, 0x46,
+	 0x2F, 0xF2, 0x30, 0xF0, 0x31, 0xF0, 0x64, 0x45, 0x46, 0x43, 0x63, 0x46, 0x03, 0xFA, 0x06, 0xF2,
+	 0x84, 0xF8, 0x00, 0x7E, 0x06, 0xFA, 0x05, 0xF8, 0xA3, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0xDC, 0xF3,
+	 0x2A, 0xF2, 0x07, 0xB0, 0x03, 0x3A, 0x2A, 0x00, 0x00, 0xF4, 0x09, 0xF2, 0x60, 0x45, 0x80, 0x3A,
+	 0x05, 0x00, 0x0E, 0xF2, 0xFF, 0xFF, 0x02, 0xB0, 0x0F, 0xF2, 0x20, 0x03, 0x60, 0x47, 0x00, 0x3A,
+	 0x1D, 0x00, 0x60, 0x41, 0x00, 0x36, 0x13, 0x00, 0xDA, 0x85, 0x2D, 0x60, 0x7A, 0x63, 0xBD, 0xD1,
+	 0xFF, 0xFF, 0xD1, 0x80, 0xFF, 0xFF, 0x12, 0x02, 0x60, 0xFE, 0xBD, 0xD3, 0xA5, 0xD0, 0xDE, 0x85,
+	 0xD0, 0x80, 0xCD, 0x81, 0x0B, 0x02, 0xF9, 0x02, 0x20, 0xFE, 0x00, 0x64, 0x0A, 0x00, 0x26, 0x46,
+	 0x48, 0xFE, 0x65, 0x40, 0x40, 0x3A, 0x02, 0x00, 0x01, 0x64, 0x03, 0x00, 0x08, 0xFE, 0x20, 0xFE,
+	 0x00, 0x64, 0x40, 0x48, 0x26, 0x46, 0x2D, 0x58, 0xFF, 0xFF, 0x2D, 0x60, 0x52, 0x62, 0xA2, 0xD3,
+	 0x18, 0xF2, 0x60, 0x40, 0x01, 0x26, 0x2A, 0xFA, 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x08, 0x26,
+	 0x03, 0x00, 0xC7, 0x60, 0x6D, 0x78, 0xFF, 0xFF, 0x3F, 0xF0, 0x32, 0x40, 0x10, 0x2A, 0x20, 0x00,
+	 0x2C, 0xF0, 0x64, 0x41, 0x60, 0x40, 0x40, 0x27, 0x1B, 0x00, 0xCD, 0x81, 0xDD, 0x81, 0x18, 0x03,
+	 0x17, 0x03, 0x64, 0x40, 0x01, 0x26, 0x14, 0x00, 0x01, 0x61, 0x13, 0x00, 0xB8, 0xF1, 0x27, 0x60,
+	 0xA0, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80, 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB,
+	 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x23, 0x00,
+	 0x00, 0x61, 0x60, 0x40, 0x18, 0x36, 0x1F, 0x00, 0xC5, 0x60, 0x58, 0x4F, 0x78, 0x78, 0xFF, 0xFF,
+	 0x0F, 0xF0, 0xEB, 0xF1, 0x64, 0x44, 0x60, 0x22, 0x19, 0x00, 0xDC, 0xF3, 0xFF, 0xFF, 0x07, 0xB4,
+	 0xFD, 0xA0, 0x2A, 0xF2, 0x03, 0x02, 0x08, 0xB0, 0xFF, 0xFF, 0x10, 0x02, 0x32, 0xF2, 0x33, 0xF2,
+	 0xD0, 0x80, 0xEC, 0xF1, 0x0B, 0x02, 0xD0, 0x80, 0x34, 0xF2, 0x08, 0x02, 0xED, 0xF1, 0xFF, 0xFF,
+	 0xD0, 0x80, 0x0F, 0xF0, 0x03, 0x02, 0xC7, 0x60, 0xB9, 0x78, 0xFF, 0xFF, 0x00, 0xF4, 0xAA, 0x60,
+	 0xAA, 0x65, 0x09, 0xF2, 0x5A, 0xD0, 0xD4, 0x80, 0x03, 0x64, 0x4F, 0x02, 0xD0, 0x80, 0x00, 0x64,
+	 0x5A, 0xD0, 0x4B, 0x02, 0x64, 0x45, 0xD4, 0x80, 0xF8, 0x7F, 0x08, 0x02, 0x5A, 0xD0, 0x26, 0x46,
+	 0x64, 0x45, 0x23, 0xF0, 0x20, 0x67, 0xB0, 0x84, 0xA2, 0xDA, 0x0B, 0x00, 0xD4, 0x80, 0x1D, 0x60,
+	 0x60, 0x64, 0x16, 0x02, 0x5A, 0xD0, 0x26, 0x46, 0x64, 0x45, 0x23, 0xF0, 0x40, 0x67, 0xB0, 0x84,
+	 0xA2, 0xDA, 0x65, 0x44, 0x88, 0x3A, 0x07, 0x00, 0x77, 0x37, 0x08, 0x00, 0x78, 0x37, 0x06, 0x00,
+	 0x8E, 0x37, 0x04, 0x00, 0x2A, 0x00, 0x81, 0x3A, 0x28, 0x00, 0x80, 0x37, 0x00, 0x61, 0x25, 0x00,
+	 0xD4, 0x80, 0x01, 0x60, 0x00, 0x64, 0x5A, 0xD0, 0x20, 0x02, 0xD0, 0x80, 0x5A, 0xD0, 0x1D, 0x02,
+	 0x26, 0x46, 0x64, 0x47, 0x7F, 0xB4, 0xFD, 0xA0, 0x09, 0x03, 0x17, 0x07, 0x32, 0x40, 0x02, 0x26,
+	 0x47, 0x00, 0x23, 0xF0, 0x60, 0x67, 0xB0, 0x84, 0xA2, 0xDA, 0x42, 0x00, 0x0F, 0xF2, 0x32, 0x40,
+	 0x02, 0x26, 0x3E, 0x00, 0xF2, 0xF3, 0xFF, 0xFF, 0x02, 0xBC, 0xF2, 0xFB, 0xEB, 0x60, 0x58, 0x4F,
+	 0xA5, 0x78, 0xFF, 0xFF, 0xC7, 0x60, 0xC3, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x61, 0x40, 0x01, 0x2A,
+	 0x12, 0x00, 0xB8, 0xF1, 0x27, 0x60, 0xA0, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80,
+	 0xD0, 0x80, 0x04, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0x04, 0x00, 0x8A, 0xFF, 0x20, 0x60,
+	 0x00, 0x75, 0x88, 0xFF, 0x6E, 0x00, 0x0F, 0xF2, 0x81, 0xF1, 0x2A, 0xF2, 0x60, 0x40, 0x20, 0x2A,
+	 0x12, 0x00, 0x5E, 0x63, 0x60, 0x40, 0x02, 0x2B, 0x64, 0x63, 0xBD, 0xD2, 0xBD, 0xD2, 0xD0, 0x80,
+	 0x82, 0xF1, 0x08, 0x02, 0xD0, 0x80, 0xA3, 0xD2, 0x83, 0xF1, 0x04, 0x02, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x01, 0x02, 0x06, 0x00, 0x56, 0x00, 0x2A, 0xF2, 0xFF, 0xFF, 0xFF, 0xFF, 0x48, 0x36, 0x51, 0x00,
+	 0xF2, 0xF3, 0xFF, 0xFF, 0x02, 0xBC, 0xF2, 0xFB, 0x59, 0x00, 0x26, 0x46, 0x2A, 0xF2, 0xFF, 0xFF,
+	 0xFF, 0xFF, 0x0C, 0x26, 0x46, 0x00, 0xB0, 0x36, 0x15, 0x00, 0x10, 0x36, 0x13, 0x00, 0x30, 0x36,
+	 0x11, 0x00, 0xC0, 0x36, 0x02, 0x00, 0xA0, 0x3A, 0x12, 0x00, 0x81, 0xF1, 0x32, 0xF2, 0x33, 0xF2,
+	 0xD0, 0x80, 0x82, 0xF1, 0x36, 0x02, 0xD0, 0x80, 0x34, 0xF2, 0x83, 0xF1, 0x32, 0x02, 0xD0, 0x80,
+	 0xFF, 0xFF, 0x2F, 0x02, 0xDB, 0x60, 0x58, 0x4F, 0xD2, 0x78, 0xFF, 0xFF, 0x26, 0x00, 0x50, 0x3A,
+	 0x05, 0x00, 0xEF, 0x60, 0x58, 0x4F, 0xE3, 0x78, 0xFF, 0xFF, 0x1F, 0x00, 0x40, 0x3A, 0x05, 0x00,
+	 0xE8, 0x60, 0x58, 0x4F, 0x60, 0x78, 0xFF, 0xFF, 0x18, 0x00, 0x80, 0x3A, 0x15, 0x00, 0x81, 0xF1,
+	 0x32, 0xF2, 0x33, 0xF2, 0xD0, 0x80, 0x82, 0xF1, 0x14, 0x02, 0xD0, 0x80, 0x34, 0xF2, 0x83, 0xF1,
+	 0x10, 0x02, 0xD0, 0x80, 0xFF, 0xFF, 0x0D, 0x02, 0xDF, 0x60, 0x58, 0x4F, 0x28, 0x78, 0xFF, 0xFF,
+	 0x20, 0x60, 0x58, 0x4F, 0xBF, 0x78, 0xFF, 0xFF, 0x04, 0x00, 0x66, 0x44, 0x00, 0xA8, 0xFF, 0xFF,
+	 0x0A, 0x03, 0x26, 0x46, 0x24, 0x60, 0x74, 0x64, 0x40, 0x4B, 0x2C, 0x60, 0x58, 0x4D, 0xD8, 0x78,
+	 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0xC5, 0x60, 0x58, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0x3B, 0xF0,
+	 0x60, 0x40, 0x40, 0x2B, 0x1E, 0x00, 0xC0, 0x60, 0x00, 0x64, 0x64, 0x40, 0x20, 0x2B, 0x19, 0x00,
+	 0x22, 0xF2, 0xFF, 0xFF, 0x04, 0xB4, 0xFF, 0xFF, 0x14, 0x03, 0xC0, 0x60, 0x00, 0x64, 0x26, 0x46,
+	 0xA0, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0x23, 0xF2, 0x10, 0xBD, 0xB4, 0x9C, 0x3F, 0xF2,
+	 0x23, 0xF8, 0x3F, 0xF2, 0xFF, 0xFF, 0xF8, 0xA4, 0x3F, 0xFA, 0x00, 0xF4, 0x60, 0x47, 0x08, 0xFA,
+	 0x26, 0x46, 0x24, 0x60, 0x74, 0x62, 0x24, 0x60, 0x58, 0x64, 0xA2, 0xDB, 0x26, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xF8, 0xFE, 0xCB, 0x01, 0x00, 0x60, 0x30, 0x61,
+	 0xAE, 0x60, 0x58, 0x4D, 0xC4, 0x78, 0xFF, 0xFF, 0x66, 0x44, 0x60, 0xFB, 0x00, 0x60, 0x30, 0x61,
+	 0xAE, 0x60, 0x58, 0x4D, 0xC4, 0x78, 0xFF, 0xFF, 0x66, 0x44, 0x5F, 0xFB, 0x00, 0x60, 0x02, 0x61,
+	 0xAE, 0x60, 0x58, 0x4D, 0xC4, 0x78, 0xFF, 0xFF, 0x66, 0x44, 0x66, 0xFB, 0x10, 0x60, 0x26, 0x62,
+	 0xC9, 0x60, 0xC7, 0x64, 0xA2, 0xDB, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x64, 0x3B, 0x42, 0x5A, 0xDB,
+	 0x01, 0x64, 0xDC, 0xFB, 0xF2, 0xF3, 0xFF, 0xFF, 0xFE, 0xB4, 0xF2, 0xFB, 0x0F, 0x60, 0xF0, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x00, 0x60, 0x14, 0x63, 0x01, 0x60, 0xC4, 0x61, 0x28, 0x60, 0x3E, 0x64,
+	 0x58, 0xD1, 0x59, 0xD9, 0xFD, 0x1F, 0x00, 0x60, 0x88, 0x63, 0x27, 0x60, 0xB4, 0x61, 0x28, 0x60,
+	 0x54, 0x64, 0x58, 0xD1, 0x59, 0xD9, 0xFD, 0x1F, 0x28, 0x60, 0x2C, 0x62, 0xA2, 0xD1, 0xFF, 0xFF,
+	 0x64, 0x45, 0xA9, 0xF1, 0x66, 0x41, 0x64, 0x46, 0x36, 0xF2, 0xFF, 0xFF, 0x65, 0x40, 0x01, 0x36,
+	 0x22, 0x64, 0x36, 0xFA, 0x61, 0x46, 0x32, 0x45, 0x28, 0x60, 0x3C, 0x62, 0xA2, 0xD1, 0x10, 0x67,
+	 0xB4, 0x85, 0x64, 0x40, 0x01, 0x2A, 0x94, 0x85, 0x45, 0x52, 0xFF, 0x60, 0xE7, 0x65, 0x32, 0x41,
+	 0xA5, 0x81, 0x2D, 0x60, 0x1A, 0x62, 0xA2, 0xD1, 0x28, 0x60, 0x2C, 0x62, 0xA2, 0xD3, 0x64, 0x40,
+	 0x01, 0x2A, 0x0D, 0x00, 0x08, 0x65, 0xFF, 0xA0, 0xFF, 0xFF, 0x01, 0x03, 0x08, 0x00, 0x28, 0x60,
+	 0x30, 0x62, 0xA2, 0xD3, 0xB5, 0x81, 0x10, 0x65, 0x60, 0x40, 0x01, 0x26, 0xB5, 0x81, 0x41, 0x52,
+	 0x2D, 0x60, 0x1A, 0x62, 0xA2, 0xD3, 0x31, 0x60, 0x18, 0x63, 0xF0, 0x84, 0xF0, 0x84, 0xF0, 0x84,
+	 0x01, 0xB5, 0xF0, 0x84, 0xF0, 0x84, 0x03, 0xB4, 0x65, 0x5C, 0xA3, 0xD9, 0x31, 0x60, 0x1A, 0x63,
+	 0x02, 0xA8, 0xA3, 0xDB, 0x1B, 0x02, 0x07, 0x60, 0xD0, 0x64, 0x31, 0x60, 0x1C, 0x63, 0xA3, 0xDB,
+	 0x31, 0x60, 0x24, 0x63, 0xA3, 0xDB, 0x00, 0x60, 0xC8, 0x64, 0x31, 0x60, 0x1E, 0x63, 0xA3, 0xDB,
+	 0x31, 0x60, 0x26, 0x63, 0xA3, 0xDB, 0x00, 0x60, 0x64, 0x64, 0x31, 0x60, 0x20, 0x63, 0xA3, 0xDB,
+	 0x01, 0x60, 0x90, 0x64, 0x31, 0x60, 0x22, 0x63, 0xA3, 0xDB, 0x08, 0x00, 0x0A, 0x64, 0x31, 0x60,
+	 0x20, 0x63, 0xA3, 0xDB, 0x01, 0x64, 0x31, 0x60, 0x22, 0x63, 0xA3, 0xDB, 0x2D, 0x60, 0x1A, 0x62,
+	 0xA2, 0xD1, 0x01, 0x64, 0x64, 0x40, 0x40, 0x2A, 0x03, 0x00, 0x31, 0x60, 0x0E, 0x7C, 0xA4, 0xDB,
+	 0x12, 0x60, 0x28, 0x63, 0xBA, 0xF3, 0x0E, 0x61, 0x60, 0x45, 0x65, 0x44, 0xE8, 0x85, 0x05, 0x64,
+	 0xCD, 0x81, 0x02, 0x28, 0x00, 0x64, 0xBD, 0xDB, 0xF8, 0x02, 0x2D, 0x60, 0x78, 0x61, 0x27, 0x60,
+	 0xB6, 0x64, 0x20, 0x63, 0x58, 0xD1, 0x59, 0xD9, 0xFD, 0x1F, 0xBD, 0xF1, 0x80, 0xF9, 0x1A, 0x63,
+	 0x01, 0x60, 0x00, 0x61, 0x00, 0x64, 0x59, 0xDB, 0xFE, 0x1F, 0x40, 0x40, 0x01, 0x64, 0x87, 0xFB,
+	 0x28, 0x60, 0xCC, 0x61, 0xA1, 0xD3, 0x2E, 0x60, 0x96, 0x61, 0xFE, 0xA4, 0xE0, 0x84, 0x04, 0x24,
+	 0x0F, 0x00, 0xE0, 0x84, 0x41, 0x91, 0x2D, 0x60, 0xCC, 0x62, 0xA2, 0xD3, 0xA1, 0xD1, 0x2D, 0x60,
+	 0xC4, 0x62, 0xA0, 0x83, 0xA2, 0xDD, 0x59, 0xD1, 0x2D, 0x60, 0xC2, 0x62, 0xA0, 0x83, 0xA2, 0xDD,
+	 0xE5, 0xF3, 0x7F, 0xFB, 0x1B, 0x60, 0xC6, 0x61, 0xA1, 0xD3, 0xFF, 0xFF, 0x00, 0xB8, 0x10, 0x60,
+	 0x5C, 0x65, 0x0D, 0x03, 0x1B, 0x60, 0xCE, 0x63, 0xE5, 0xF3, 0xA3, 0xD1, 0xE0, 0x84, 0xC4, 0x84,
+	 0xA0, 0xD3, 0xFF, 0xFF, 0x01, 0xB0, 0xFF, 0xFF, 0x02, 0x02, 0xE5, 0xF9, 0x7F, 0xF9, 0xE5, 0xF3,
+	 0x01, 0x61, 0xCC, 0x84, 0xFF, 0xFF, 0x02, 0x03, 0xE1, 0x81, 0xFB, 0x01, 0xBA, 0xF3, 0x61, 0x45,
+	 0xA4, 0x80, 0xFF, 0xFF, 0x0B, 0x02, 0x00, 0xB8, 0x01, 0x63, 0x08, 0x03, 0xE8, 0x84, 0xFF, 0xFF,
+	 0x02, 0x24, 0x02, 0x00, 0xDF, 0x83, 0xFA, 0x01, 0xE5, 0xFD, 0x7F, 0xFD, 0x0F, 0x60, 0xF0, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE, 0x0B, 0x04, 0x0F, 0x60, 0xF2, 0x62, 0x40, 0x60, 0x00, 0x64,
+	 0xA2, 0xDB, 0xC8, 0x60, 0xF7, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x7F, 0xF1,
+	 0x24, 0x60, 0x9A, 0x62, 0xA2, 0xD9, 0x0C, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x07, 0x64,
+	 0xD0, 0xFB, 0x0F, 0x60, 0xF2, 0x62, 0x20, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xC9, 0x60, 0x34, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xF0, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0xBE, 0xFE, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xCF, 0xFE, 0x01, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0xE3, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x05, 0x3A,
+	 0x03, 0x00, 0x68, 0x60, 0xBA, 0x61, 0x11, 0x00, 0x04, 0x3A, 0x03, 0x00, 0x68, 0x60, 0xAE, 0x61,
+	 0x0C, 0x00, 0x03, 0x3A, 0x03, 0x00, 0x68, 0x60, 0xA2, 0x61, 0x07, 0x00, 0x02, 0x3A, 0x03, 0x00,
+	 0x68, 0x60, 0x96, 0x61, 0x02, 0x00, 0x68, 0x60, 0x8A, 0x61, 0x3C, 0x60, 0x00, 0x66, 0x01, 0x60,
+	 0xB8, 0x64, 0x0A, 0x63, 0x59, 0xD0, 0x58, 0xD9, 0xFD, 0x1F, 0x01, 0x60, 0xBE, 0x61, 0xE4, 0xF3,
+	 0x00, 0x66, 0x00, 0xA8, 0x04, 0x65, 0x01, 0x03, 0xA1, 0xDB, 0x1F, 0x60, 0x08, 0x63, 0x55, 0xD3,
+	 0xFF, 0xFF, 0x20, 0x7F, 0xBD, 0xDB, 0x59, 0xD3, 0xFF, 0xFF, 0x21, 0x7F, 0xBD, 0xDB, 0x59, 0xD3,
+	 0xFF, 0xFF, 0x22, 0x7F, 0xA3, 0xDB, 0x0F, 0x60, 0xF0, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE,
+	 0x0B, 0x04, 0x0F, 0x60, 0xF2, 0x62, 0x40, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xC9, 0x60, 0x7B, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x24, 0x60, 0x9A, 0x62, 0x1F, 0x60, 0x06, 0x64,
+	 0xA2, 0xDB, 0x20, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x0F, 0x60, 0xF2, 0x62, 0x20, 0x60,
+	 0x00, 0x64, 0xA2, 0xDB, 0xC9, 0x60, 0xA0, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0xBE, 0xFE, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xCF, 0xFE, 0xC5, 0xFE, 0x20, 0x40, 0x20, 0x2A, 0x08, 0x00, 0x10, 0x60, 0x02, 0x62, 0xA2, 0xD1,
+	 0x00, 0x60, 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x0F, 0x60, 0xEA, 0x62, 0xA2, 0xD1,
+	 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x0F, 0x60, 0xF0, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0x5A, 0xDB, 0x0E, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x64,
+	 0x3B, 0x42, 0x5A, 0xDB, 0x0F, 0x60, 0xF0, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x8B, 0xFB,
+	 0xFF, 0xFF, 0xC1, 0xFE, 0x10, 0x60, 0x1A, 0x62, 0xA2, 0xD1, 0x01, 0x60, 0xDF, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x24, 0x60, 0xA8, 0x63, 0x01, 0x64, 0xBD, 0xDB, 0xFF, 0xFF, 0x04, 0xFF,
+	 0x0F, 0x60, 0xF0, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x08, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x0F, 0x60, 0xF2, 0x62, 0x00, 0x60, 0x08, 0x64, 0xA2, 0xDB, 0xC9, 0x60, 0xF3, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x0F, 0x60, 0xF0, 0x62,
+	 0xA2, 0xD1, 0x7F, 0x60, 0xFF, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x8B, 0xF3, 0x00, 0x65, 0xD4, 0x80,
+	 0xFF, 0xFF, 0x0B, 0x03, 0x0F, 0x60, 0xF2, 0x62, 0x80, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xC9, 0x60,
+	 0xF3, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0xDE, 0xFE, 0x0E, 0x04, 0x09, 0x64,
+	 0x3B, 0x42, 0x5A, 0xDB, 0x0F, 0x60, 0xF2, 0x62, 0x20, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xCA, 0x60,
+	 0x1D, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0A, 0x64, 0x3B, 0x42, 0x5A, 0xDB,
+	 0x24, 0x60, 0x9A, 0x62, 0x06, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x0F, 0x60, 0xF0, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x5A, 0xDB, 0xBE, 0xFE, 0xDA, 0xFE, 0x24, 0x60, 0x34, 0x61, 0xCA, 0x60,
+	 0x58, 0x4E, 0x57, 0x78, 0xFF, 0xFF, 0x24, 0x60, 0x22, 0x61, 0xCA, 0x60, 0x58, 0x4E, 0x57, 0x78,
+	 0xFF, 0xFF, 0x24, 0x60, 0x28, 0x61, 0xCA, 0x60, 0x58, 0x4E, 0x57, 0x78, 0xFF, 0xFF, 0x24, 0x60,
+	 0x46, 0x61, 0xCA, 0x60, 0x58, 0x4E, 0x57, 0x78, 0xFF, 0xFF, 0x24, 0x60, 0x4C, 0x61, 0xCA, 0x60,
+	 0x58, 0x4E, 0x57, 0x78, 0xFF, 0xFF, 0x24, 0x60, 0x58, 0x61, 0xCA, 0x60, 0x58, 0x4E, 0x57, 0x78,
+	 0xFF, 0xFF, 0xC5, 0xFE, 0x0E, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x2F, 0x58, 0xFF, 0xFF, 0xA1, 0xD3,
+	 0x0E, 0x57, 0x24, 0x00, 0x0E, 0xF2, 0x44, 0x4C, 0x80, 0xB0, 0x10, 0xB0, 0x0B, 0x03, 0x24, 0x60,
+	 0x74, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0x13, 0x00, 0x12, 0x02, 0xF0, 0x37, 0x09, 0x00, 0x02, 0xF0, 0x09, 0x60, 0x08, 0x64,
+	 0xD0, 0x80, 0xA2, 0xFF, 0xB0, 0xF3, 0x02, 0x02, 0xCC, 0x84, 0xB0, 0xFB, 0x24, 0x60, 0x74, 0x64,
+	 0x40, 0x4B, 0x2C, 0x60, 0x58, 0x4D, 0xD8, 0x78, 0xFF, 0xFF, 0x2C, 0x44, 0xAC, 0x86, 0x09, 0xF0,
+	 0xD9, 0x02, 0x37, 0x58, 0xFF, 0xFF, 0x1A, 0x60, 0x66, 0x63, 0x00, 0x64, 0xA3, 0xDB, 0x06, 0xA3,
+	 0x10, 0x60, 0x4C, 0x64, 0xBD, 0xDB, 0xBD, 0xDB, 0x06, 0x64, 0xA3, 0xDB, 0x00, 0x63, 0x10, 0x60,
+	 0x9E, 0x62, 0xA2, 0xDD, 0x10, 0x60, 0x4A, 0x62, 0xCF, 0x60, 0x16, 0x64, 0xA2, 0xDB, 0x10, 0x60,
+	 0x24, 0x62, 0xCE, 0x60, 0xE2, 0x64, 0xA2, 0xDB, 0x0F, 0x60, 0xEC, 0x62, 0x00, 0x60, 0x02, 0x64,
+	 0xA2, 0xDB, 0xCA, 0x60, 0xFB, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x68, 0x60,
+	 0x7E, 0x61, 0x3C, 0x60, 0x00, 0x66, 0x01, 0x60, 0xB8, 0x64, 0x0A, 0x63, 0x59, 0xD0, 0x58, 0xD9,
+	 0xFD, 0x1F, 0x01, 0x60, 0xBE, 0x61, 0xE4, 0xF3, 0x00, 0x66, 0x00, 0xA8, 0x04, 0x65, 0x01, 0x03,
+	 0xA1, 0xDB, 0x1F, 0x60, 0x08, 0x63, 0x55, 0xD3, 0xFF, 0xFF, 0x20, 0x7F, 0xBD, 0xDB, 0x59, 0xD3,
+	 0xFF, 0xFF, 0x21, 0x7F, 0xBD, 0xDB, 0x59, 0xD3, 0xFF, 0xFF, 0x22, 0x7F, 0xA3, 0xDB, 0x0F, 0x60,
+	 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE, 0x0B, 0x04, 0x0F, 0x60, 0xEC, 0x62, 0x40, 0x60,
+	 0x00, 0x64, 0xA2, 0xDB, 0xCA, 0x60, 0xC7, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x24, 0x60, 0x9A, 0x62, 0x1F, 0x60, 0x06, 0x64, 0xA2, 0xDB, 0x20, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x2D, 0xFF, 0x0F, 0x60, 0xEC, 0x62, 0x20, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xCA, 0x60, 0xEC, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0xBE, 0xFE, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xCF, 0xFE, 0x2E, 0x58, 0xFF, 0xFF, 0x10, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x0F, 0x60, 0xEA, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0xBA, 0xFE, 0x27, 0x60, 0xB6, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x03, 0xA8,
+	 0x02, 0xA8, 0x04, 0x03, 0x0F, 0x02, 0xCE, 0x60, 0xB3, 0x78, 0xFF, 0xFF, 0xCD, 0x60, 0xEF, 0x78,
+	 0xFF, 0xFF, 0x1F, 0x60, 0x80, 0x65, 0xA5, 0xD3, 0xFF, 0xFF, 0xF3, 0xB4, 0xA5, 0xDB, 0xCB, 0x60,
+	 0x22, 0x78, 0xFF, 0xFF, 0x01, 0x63, 0x1A, 0x60, 0x40, 0x64, 0xA0, 0xDD, 0x1F, 0x60, 0x80, 0x64,
+	 0x00, 0x63, 0xA0, 0xDD, 0x11, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0xBA, 0xFE, 0x02, 0x64, 0xDC, 0xFB, 0xF2, 0xF3, 0xFF, 0xFF, 0x01, 0xBC, 0xF2, 0xFB,
+	 0x44, 0x60, 0x44, 0x64, 0x81, 0xFB, 0x82, 0xFB, 0x83, 0xFB, 0xFF, 0xFF, 0x20, 0x40, 0x04, 0x2B,
+	 0x19, 0x00, 0x9B, 0xFE, 0x09, 0x04, 0xBB, 0xFE, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1, 0x80, 0x60,
+	 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x12, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x0F, 0x60,
+	 0xEC, 0x62, 0x80, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xCB, 0x60, 0x36, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x00, 0x65, 0x20, 0x44, 0x34, 0x80, 0x0D, 0x64, 0x53, 0xFB,
+	 0x29, 0x60, 0xA4, 0x64, 0x54, 0xFB, 0x13, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x0F, 0x60, 0xCE, 0x61,
+	 0xA1, 0xD1, 0x02, 0x60, 0x00, 0x65, 0x20, 0x44, 0x34, 0x80, 0x64, 0x40, 0x01, 0x2A, 0x07, 0x00,
+	 0x00, 0x64, 0xA1, 0xDB, 0x02, 0x65, 0xE9, 0x60, 0x58, 0x4E, 0x7B, 0x78, 0xFF, 0xFF, 0xCA, 0x60,
+	 0x58, 0x4E, 0xA7, 0x78, 0xFF, 0xFF, 0x1F, 0x60, 0x80, 0x62, 0x1A, 0x60, 0x40, 0x65, 0xA2, 0xD3,
+	 0xA5, 0xD1, 0x60, 0x40, 0x0C, 0x22, 0x04, 0x00, 0x04, 0x61, 0xD1, 0x80, 0xFF, 0xFF, 0x2D, 0x05,
+	 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x0F, 0x4E, 0xE4, 0x60, 0x58, 0x4F, 0xFB, 0x78,
+	 0xFF, 0xFF, 0x0E, 0x4F, 0x0F, 0x60, 0xEC, 0x62, 0x10, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xCB, 0x60,
+	 0x95, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x1F, 0x60, 0x80, 0x64, 0xA0, 0xD3,
+	 0xFF, 0xFF, 0x60, 0x40, 0x0C, 0x26, 0x11, 0x00, 0xFD, 0x60, 0xFF, 0x65, 0x20, 0x44, 0x24, 0x80,
+	 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x38, 0x00, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0x0F, 0x4E, 0xEC, 0x60, 0x58, 0x4F, 0xB9, 0x78, 0xFF, 0xFF, 0x0E, 0x4F, 0x0F, 0x60,
+	 0xEC, 0x62, 0x10, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xCB, 0x60, 0xC2, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x14, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0xFD, 0x60, 0xFF, 0x65, 0x20, 0x44,
+	 0x24, 0x80, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xCF, 0xFE, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x88, 0xF1, 0x19, 0x60, 0x86, 0x63,
+	 0xD3, 0x80, 0x20, 0x44, 0x05, 0x03, 0x10, 0xBC, 0x40, 0x40, 0xCD, 0x60, 0xE8, 0x78, 0xFF, 0xFF,
+	 0x89, 0xF3, 0xFF, 0xFF, 0xD0, 0x80, 0x20, 0x44, 0x06, 0x02, 0xD4, 0xF3, 0xFF, 0xFF, 0x00, 0xA8,
+	 0xFF, 0xFF, 0x1E, 0x02, 0x72, 0x00, 0x10, 0xBC, 0x40, 0x40, 0x64, 0x42, 0x5A, 0xD1, 0x06, 0x63,
+	 0xA4, 0xD1, 0xC3, 0x83, 0x7F, 0xF9, 0xBD, 0xD1, 0x81, 0xF9, 0xBD, 0xD1, 0xFF, 0xFF, 0x82, 0xF9,
+	 0xBD, 0xD1, 0x83, 0xF9, 0x04, 0xA3, 0xBD, 0xD1, 0x2D, 0x60, 0x7A, 0x64, 0x64, 0x41, 0xDD, 0x81,
+	 0xFE, 0xB1, 0xA0, 0xD9, 0x04, 0x03, 0xBD, 0xD1, 0xC9, 0x81, 0x58, 0xD9, 0xFC, 0x02, 0x1E, 0x00,
+	 0xE5, 0xF3, 0x7F, 0xFB, 0x29, 0x60, 0xA4, 0x61, 0xA1, 0xD3, 0xFF, 0xFF, 0x00, 0xA8, 0x2D, 0x60,
+	 0x7A, 0x63, 0x02, 0x02, 0x27, 0x60, 0xB8, 0x61, 0xA1, 0xD3, 0xBD, 0xDB, 0xDC, 0x84, 0xFE, 0xB4,
+	 0x59, 0xD1, 0xC8, 0x84, 0xBD, 0xD9, 0xFC, 0x02, 0xED, 0xF3, 0x72, 0x45, 0xEC, 0xF3, 0x94, 0x83,
+	 0x83, 0xFD, 0x94, 0x83, 0x82, 0xFD, 0x65, 0x5F, 0x02, 0x64, 0x81, 0xFB, 0x0F, 0x60, 0xEA, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE, 0x0B, 0x04, 0x0F, 0x60, 0xEC, 0x62, 0x40, 0x60, 0x00, 0x64,
+	 0xA2, 0xDB, 0xCC, 0x60, 0x26, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x18, 0x64,
+	 0x3B, 0x42, 0x5A, 0xDB, 0x7F, 0xF1, 0x24, 0x60, 0x9A, 0x62, 0xA2, 0xD9, 0x1E, 0x64, 0x4A, 0xDB,
+	 0xFF, 0xFF, 0x2D, 0xFF, 0x0F, 0x60, 0xEC, 0x62, 0x20, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xCC, 0x60,
+	 0x4D, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0xBE, 0xFE, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0xCC, 0x60, 0xAD, 0x78, 0xFF, 0xFF, 0x16, 0x64, 0x3B, 0x42, 0x5A, 0xDB,
+	 0xFF, 0x60, 0xEF, 0x65, 0x20, 0x44, 0x24, 0x80, 0xCA, 0x60, 0x58, 0x4E, 0xA7, 0x78, 0xFF, 0xFF,
+	 0x17, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x02, 0x64, 0xDC, 0xFB, 0xF2, 0xF3, 0xFF, 0xFF, 0x01, 0xBC,
+	 0xF2, 0xFB, 0xF7, 0x60, 0xFF, 0x65, 0x20, 0x44, 0x24, 0x80, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1,
+	 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0xDA, 0xFE, 0xC1, 0xFE, 0x1A, 0x60, 0x40, 0x62, 0xA2, 0xD1, 0x1A, 0x60, 0x6A, 0x62,
+	 0xA2, 0xD9, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x66, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB,
+	 0xFF, 0xFF, 0x04, 0xFF, 0x0F, 0x60, 0xEC, 0x62, 0x00, 0x60, 0x06, 0x64, 0xA2, 0xDB, 0xCB, 0x60,
+	 0x22, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x1A, 0x60, 0x40, 0x61, 0x75, 0x60, 0x30, 0x65, 0xA1, 0xD3,
+	 0xFF, 0xFF, 0xFF, 0xA0, 0xE0, 0x84, 0x02, 0x02, 0x03, 0x60, 0xE8, 0x64, 0xD4, 0x80, 0xFF, 0xFF,
+	 0x01, 0x04, 0x65, 0x44, 0xA1, 0xDB, 0x2F, 0x58, 0xFF, 0xFF, 0x79, 0xF3, 0x7A, 0xFB, 0x1F, 0x60,
+	 0x52, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xFF, 0x60, 0xDF, 0x65, 0x20, 0x44, 0x24, 0x80, 0xBF, 0xF1,
+	 0x1A, 0x60, 0x6A, 0x62, 0xA2, 0xD9, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x66, 0x64, 0xA2, 0xDB,
+	 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0xF7, 0x60, 0xFF, 0x65, 0x20, 0x44, 0x24, 0x80,
+	 0x10, 0x26, 0x67, 0x00, 0x00, 0x64, 0xB5, 0xFB, 0xB6, 0xFB, 0xB7, 0xFB, 0x00, 0x75, 0x00, 0x72,
+	 0xBD, 0xF1, 0x80, 0xF9, 0x64, 0x44, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x93, 0xE6, 0xF1,
+	 0x86, 0xF9, 0x28, 0x60, 0xD2, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x01, 0xA8, 0xFF, 0xFF, 0x08, 0x02,
+	 0x01, 0x60, 0xB0, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x01, 0xA8, 0xFF, 0xFF, 0x01, 0x03, 0x02, 0x64,
+	 0x60, 0x41, 0x2D, 0x60, 0x28, 0x63, 0xBD, 0xD3, 0xA3, 0xD3, 0xFF, 0xB5, 0x65, 0x5C, 0xCD, 0x81,
+	 0x80, 0xBF, 0x0E, 0x03, 0x80, 0xBF, 0xBD, 0xDB, 0x65, 0x44, 0xC8, 0x84, 0xFF, 0xFF, 0x0B, 0x03,
+	 0x60, 0x45, 0xCD, 0x81, 0xA3, 0xD3, 0x07, 0x03, 0xCD, 0x81, 0x80, 0xBF, 0x01, 0x03, 0x80, 0xBC,
+	 0x60, 0x47, 0xBD, 0xDB, 0x00, 0x65, 0x64, 0x41, 0x2D, 0x60, 0x2A, 0x63, 0xBD, 0xD3, 0xFF, 0xFF,
+	 0x80, 0xB0, 0xFF, 0xFF, 0x01, 0x03, 0x60, 0x45, 0x60, 0x47, 0x80, 0xB0, 0xFF, 0xFF, 0x01, 0x03,
+	 0x60, 0x45, 0xC9, 0x81, 0xFF, 0xFF, 0xF2, 0x02, 0x65, 0x44, 0x7F, 0xB4, 0x02, 0x3A, 0x02, 0x00,
+	 0x0A, 0x64, 0x15, 0x00, 0x04, 0x3A, 0x02, 0x00, 0x14, 0x64, 0x11, 0x00, 0x0A, 0x3A, 0x02, 0x00,
+	 0x32, 0x64, 0x0D, 0x00, 0x0B, 0x3A, 0x02, 0x00, 0x37, 0x64, 0x09, 0x00, 0x10, 0x3A, 0x02, 0x00,
+	 0x50, 0x64, 0x05, 0x00, 0x16, 0x3A, 0x02, 0x00, 0x6E, 0x64, 0x01, 0x00, 0x14, 0x64, 0x7C, 0xFB,
+	 0x28, 0x00, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x0F, 0x60, 0xEC, 0x62, 0x00, 0x60,
+	 0x84, 0x64, 0xA2, 0xDB, 0xCD, 0x60, 0x40, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x0F, 0x60, 0xEA, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x80, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x0D, 0x03,
+	 0xA0, 0x84, 0xA2, 0xDB, 0x0F, 0x60, 0xEA, 0x62, 0xA2, 0xD1, 0xFF, 0x60, 0x7F, 0x61, 0xA1, 0x84,
+	 0x5A, 0xD1, 0x4A, 0xDB, 0xA1, 0x84, 0x5A, 0xDB, 0x04, 0x00, 0xBB, 0xFE, 0xCB, 0x60, 0x22, 0x78,
+	 0xFF, 0xFF, 0x28, 0x60, 0x2C, 0x62, 0xA2, 0xD1, 0x00, 0x65, 0x64, 0x40, 0x01, 0x36, 0x22, 0x65,
+	 0x64, 0x40, 0x07, 0x36, 0x01, 0x65, 0xA9, 0xF3, 0x66, 0x5C, 0x60, 0x46, 0x1F, 0x63, 0xE3, 0x83,
+	 0xB6, 0xF8, 0x02, 0xA6, 0x66, 0x44, 0xFC, 0x1F, 0x28, 0x60, 0x2C, 0x62, 0xA2, 0xD3, 0xFF, 0xFF,
+	 0x60, 0x40, 0x07, 0x3A, 0x04, 0x00, 0xA9, 0xF3, 0x04, 0x65, 0x60, 0x46, 0xB6, 0xF8, 0x64, 0x46,
+	 0xA9, 0xF3, 0x32, 0x41, 0x60, 0x45, 0x08, 0xB1, 0x66, 0x41, 0x17, 0x03, 0x65, 0x46, 0x29, 0x60,
+	 0xA2, 0x62, 0xA2, 0xD3, 0x06, 0xF0, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0x80, 0xBF,
+	 0xB0, 0x84, 0x06, 0xFA, 0x66, 0x43, 0x02, 0xA3, 0x63, 0x46, 0x06, 0xF0, 0xFF, 0xFF, 0xB0, 0x84,
+	 0x06, 0xFA, 0x61, 0x46, 0x32, 0x44, 0x10, 0xBC, 0x40, 0x52, 0x1F, 0x60, 0x52, 0x62, 0x01, 0x64,
+	 0xA2, 0xDB, 0x0F, 0x4E, 0xE7, 0x60, 0x58, 0x4F, 0x51, 0x78, 0xFF, 0xFF, 0x0E, 0x4F, 0x0F, 0x60,
+	 0xEA, 0x62, 0xA2, 0xD1, 0xFF, 0x60, 0xFB, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x0F, 0x60, 0xEC, 0x62,
+	 0x00, 0x60, 0x04, 0x64, 0xA2, 0xDB, 0xCB, 0x60, 0x11, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x24, 0x60,
+	 0xAA, 0x62, 0x1A, 0x60, 0x66, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF,
+	 0xBB, 0xFE, 0x20, 0x44, 0x04, 0x27, 0x12, 0x00, 0x10, 0x26, 0x02, 0x00, 0xDB, 0xFE, 0x16, 0x00,
+	 0x0F, 0x60, 0xCE, 0x61, 0xA1, 0xD3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x36, 0x07, 0x00, 0x01, 0x64,
+	 0xA1, 0xDB, 0x01, 0x65, 0xE9, 0x60, 0x58, 0x4E, 0x7B, 0x78, 0xFF, 0xFF, 0x0F, 0x60, 0xD0, 0x62,
+	 0xA2, 0xD1, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x01, 0x64, 0x8C, 0xFB,
+	 0xFF, 0x60, 0xEF, 0x65, 0x20, 0x44, 0x24, 0x80, 0x03, 0x64, 0xDC, 0xFB, 0xF2, 0xF3, 0xFF, 0xFF,
+	 0xFE, 0xB4, 0xF2, 0xFB, 0xC1, 0xFE, 0x1E, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x15, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0xBB, 0xFE, 0xCF, 0x60, 0xD6, 0x78, 0xFF, 0xFF, 0x28, 0x60,
+	 0x2C, 0x62, 0xA2, 0xD1, 0x00, 0x65, 0x64, 0x40, 0x01, 0x36, 0x22, 0x65, 0xA9, 0xF3, 0x66, 0x5C,
+	 0x60, 0x46, 0x1F, 0x63, 0xE3, 0x83, 0xB6, 0xF8, 0x02, 0xA6, 0x66, 0x44, 0xFC, 0x1F, 0x64, 0x46,
+	 0x79, 0xF1, 0xA9, 0xF3, 0x7A, 0xF9, 0x02, 0xA4, 0xD8, 0xF3, 0x60, 0x45, 0x66, 0x41, 0x65, 0x46,
+	 0x8C, 0xFA, 0x60, 0x40, 0x01, 0x36, 0x06, 0x00, 0x02, 0x36, 0x04, 0x00, 0x04, 0x36, 0x02, 0x00,
+	 0x05, 0x3A, 0x02, 0x00, 0x00, 0x64, 0x01, 0x00, 0x01, 0x64, 0x6F, 0xFA, 0x79, 0xF3, 0x7A, 0xF1,
+	 0xFF, 0xFF, 0xA0, 0x84, 0x65, 0x43, 0x02, 0x02, 0x79, 0xF3, 0xFF, 0xFF, 0x60, 0x41, 0x0F, 0x60,
+	 0xAE, 0x65, 0xD8, 0xF3, 0xFF, 0xFF, 0xE0, 0x84, 0x44, 0xD3, 0x61, 0x45, 0xA4, 0x80, 0xFF, 0xFF,
+	 0x04, 0x02, 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0xFC, 0x03, 0xA4, 0x84, 0x7B, 0xFB, 0x6F, 0xF0,
+	 0x60, 0x47, 0x90, 0x84, 0x6F, 0xFA, 0x60, 0x47, 0x60, 0x45, 0x80, 0x64, 0xE8, 0x84, 0xA4, 0x80,
+	 0xFF, 0xFF, 0xFC, 0x03, 0xA4, 0x84, 0x70, 0xF0, 0x70, 0xFA, 0x00, 0x61, 0xE8, 0x84, 0xFF, 0xFF,
+	 0x02, 0x05, 0xDD, 0x81, 0xFB, 0x01, 0xE1, 0x81, 0x0F, 0x60, 0xA2, 0x65, 0x45, 0xD3, 0x0E, 0xFA,
+	 0x66, 0x43, 0x0C, 0xF4, 0xA9, 0xF1, 0x02, 0x64, 0xC0, 0x85, 0x0C, 0x61, 0x32, 0x40, 0x08, 0x2A,
+	 0x15, 0x00, 0x29, 0x60, 0xA2, 0x62, 0xA2, 0xD3, 0x66, 0x41, 0x65, 0x46, 0x06, 0xF0, 0xE0, 0x84,
+	 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0x80, 0xBF, 0xB0, 0x83, 0x06, 0xFC, 0x66, 0x42, 0xFE, 0xA2,
+	 0x62, 0x46, 0x06, 0xF0, 0xFF, 0xFF, 0xB0, 0x84, 0x06, 0xFA, 0x61, 0x46, 0x1D, 0x64, 0x3B, 0x42,
+	 0x5A, 0xDB, 0x0B, 0x64, 0xDC, 0xFB, 0xF2, 0xF3, 0xFF, 0xFF, 0xFE, 0xB4, 0xF2, 0xFB, 0x01, 0x65,
+	 0xE9, 0x60, 0x58, 0x4E, 0x7B, 0x78, 0xFF, 0xFF, 0xE5, 0xF1, 0x7F, 0xF9, 0x0F, 0x60, 0xEA, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE, 0x0B, 0x04, 0x0F, 0x60, 0xEC, 0x62, 0x40, 0x60, 0x00, 0x64,
+	 0xA2, 0xDB, 0xCE, 0x60, 0x76, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x7F, 0xF1,
+	 0x24, 0x60, 0x9A, 0x62, 0xA2, 0xD9, 0x1E, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x0F, 0x60,
+	 0xEC, 0x62, 0x20, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xCE, 0x60, 0x9A, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x5A, 0xDB, 0xBE, 0xFE,
+	 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x01, 0x64, 0x8C, 0xFB, 0xFF, 0x60, 0xDF, 0x65, 0x20, 0x44, 0x24, 0x80, 0x1E, 0x64, 0x3B, 0x42,
+	 0x5A, 0xDB, 0x2F, 0x58, 0xFF, 0xFF, 0x1C, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x06, 0x64, 0xDC, 0xFB,
+	 0xF2, 0xF3, 0xFF, 0xFF, 0xFE, 0xB4, 0xF2, 0xFB, 0xE5, 0xF1, 0x7F, 0xF9, 0x0F, 0x60, 0xEA, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x01, 0x64, 0x8C, 0xFB, 0xFF, 0x60, 0xDF, 0x65, 0x20, 0x44, 0x24, 0x80,
+	 0xA9, 0xF1, 0x66, 0x45, 0x64, 0x46, 0x66, 0x43, 0x02, 0xA3, 0x63, 0x46, 0x02, 0x64, 0x06, 0xFA,
+	 0x04, 0x63, 0x04, 0x61, 0x01, 0x60, 0xCE, 0x64, 0x58, 0xD1, 0x59, 0xD8, 0xFD, 0x1F, 0x65, 0x46,
+	 0x01, 0x65, 0xE9, 0x60, 0x58, 0x4E, 0x7B, 0x78, 0xFF, 0xFF, 0x1E, 0x64, 0x3B, 0x42, 0x5A, 0xDB,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x1F, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x00, 0x64, 0x68, 0xFB, 0x69, 0xFB,
+	 0xA9, 0xF1, 0x0E, 0x64, 0x66, 0x41, 0x64, 0x42, 0x02, 0xA2, 0x62, 0x46, 0x06, 0xF0, 0xFF, 0x60,
+	 0xFC, 0x64, 0xA0, 0x84, 0x06, 0xFA, 0x61, 0x46, 0xDC, 0xF3, 0xFF, 0xFF, 0x04, 0xA8, 0x0F, 0x60,
+	 0xCE, 0x64, 0x07, 0x03, 0xA0, 0xD1, 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x2A, 0x02, 0x00, 0x00, 0x63,
+	 0xA0, 0xDD, 0x01, 0x64, 0xDC, 0xFB, 0xF2, 0xF3, 0xFF, 0xFF, 0xFE, 0xB4, 0xF2, 0xFB, 0x0F, 0x60,
+	 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x0F, 0x60, 0xEC, 0x62, 0x00, 0x60, 0x02, 0x64, 0xA2, 0xDB,
+	 0xCA, 0x60, 0xFB, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xEA, 0x62,
+	 0xA2, 0xD1, 0x00, 0x60, 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x28, 0x60, 0x3A, 0x64, 0xA0, 0xD3, 0x00, 0xF4, 0x60, 0x40, 0x01, 0x3A, 0x42, 0x00, 0x18, 0x65,
+	 0x22, 0x61, 0x02, 0x60, 0x00, 0x63, 0xA5, 0xD0, 0xDA, 0x85, 0x80, 0x3A, 0x02, 0x00, 0x00, 0xF4,
+	 0x04, 0x65, 0x64, 0x44, 0x00, 0x7F, 0xCD, 0x81, 0xBD, 0xDB, 0x05, 0x03, 0x64, 0x47, 0x00, 0x7F,
+	 0xCD, 0x81, 0xBD, 0xDB, 0xF0, 0x02, 0x02, 0x60, 0x00, 0x63, 0xBD, 0xD3, 0xBD, 0xD3, 0x01, 0xA8,
+	 0xE0, 0x85, 0x27, 0x02, 0xC7, 0x83, 0xBD, 0xD3, 0xBD, 0xD3, 0x81, 0xA8, 0x0D, 0xA8, 0x21, 0x02,
+	 0x20, 0x02, 0xBD, 0xD3, 0xBD, 0xD3, 0x00, 0xA8, 0x60, 0xA8, 0x1B, 0x02, 0xBD, 0xD3, 0x19, 0x02,
+	 0x1D, 0xA8, 0xA3, 0xD1, 0x16, 0x02, 0xE3, 0xF9, 0x01, 0x60, 0xB8, 0x64, 0x63, 0x41, 0x0A, 0x63,
+	 0x59, 0xD1, 0x58, 0xD9, 0xFD, 0x1F, 0x59, 0xD1, 0x59, 0xD3, 0xFF, 0xFF, 0x60, 0x47, 0x64, 0x5E,
+	 0xD6, 0xFB, 0x59, 0xD1, 0x28, 0x60, 0x36, 0x64, 0xA0, 0xD9, 0x28, 0x60, 0xD6, 0x64, 0xA0, 0xD9,
+	 0x23, 0x00, 0x28, 0x60, 0x40, 0x64, 0xA0, 0xD3, 0xE3, 0xFB, 0x60, 0x40, 0x05, 0x3A, 0x03, 0x00,
+	 0x68, 0x60, 0xBA, 0x61, 0x11, 0x00, 0x04, 0x3A, 0x03, 0x00, 0x68, 0x60, 0xAE, 0x61, 0x0C, 0x00,
+	 0x03, 0x3A, 0x03, 0x00, 0x68, 0x60, 0xA2, 0x61, 0x07, 0x00, 0x02, 0x3A, 0x03, 0x00, 0x68, 0x60,
+	 0x96, 0x61, 0x02, 0x00, 0x68, 0x60, 0x8A, 0x61, 0x3C, 0x60, 0x00, 0x66, 0x01, 0x60, 0xB8, 0x64,
+	 0x0A, 0x63, 0x59, 0xD0, 0x58, 0xD9, 0xFD, 0x1F, 0x01, 0x60, 0xBE, 0x61, 0xE4, 0xF3, 0x00, 0x66,
+	 0x00, 0xA8, 0x04, 0x65, 0x01, 0x03, 0xA1, 0xDB, 0x1F, 0x60, 0x08, 0x63, 0x55, 0xD3, 0xFF, 0xFF,
+	 0x20, 0x7F, 0xBD, 0xDB, 0x59, 0xD3, 0xFF, 0xFF, 0x21, 0x7F, 0xBD, 0xDB, 0x59, 0xD3, 0xFF, 0xFF,
+	 0x22, 0x7F, 0xA3, 0xDB, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE, 0x0B, 0x04,
+	 0x0F, 0x60, 0xEC, 0x62, 0x40, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xCF, 0x60, 0xA2, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x24, 0x60, 0x9A, 0x62, 0x1F, 0x60, 0x06, 0x64, 0xA2, 0xDB,
+	 0x20, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x0F, 0x60, 0xEC, 0x62, 0x20, 0x60, 0x00, 0x64,
+	 0xA2, 0xDB, 0xCF, 0x60, 0xC7, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60,
+	 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xBE, 0xFE, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1, 0x40, 0x60,
+	 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x2E, 0x58, 0xFF, 0xFF, 0x40, 0x64, 0x3B, 0x42,
+	 0x5A, 0xDB, 0xBC, 0xF1, 0x1A, 0x60, 0x6A, 0x62, 0xA2, 0xD9, 0x60, 0xF5, 0xEB, 0xF1, 0x2F, 0xF8,
+	 0xEC, 0xF1, 0x30, 0xF8, 0xED, 0xF1, 0x31, 0xF8, 0xBC, 0xF1, 0x19, 0xF8, 0xF8, 0x60, 0x80, 0x64,
+	 0x0E, 0xFA, 0x00, 0x64, 0x3E, 0xFA, 0xA9, 0xF1, 0x07, 0xF8, 0x00, 0x60, 0xD0, 0x63, 0x19, 0x60,
+	 0x84, 0x64, 0xA3, 0xDB, 0x44, 0x60, 0x44, 0x64, 0x81, 0xFB, 0x82, 0xFB, 0x83, 0xFB, 0x31, 0x44,
+	 0xF9, 0xB4, 0x40, 0x51, 0x00, 0x60, 0xD0, 0x63, 0x01, 0x60, 0x10, 0x65, 0xA3, 0xD3, 0xA5, 0xD1,
+	 0x04, 0xA4, 0xA3, 0xDB, 0xD0, 0x80, 0xA0, 0xD1, 0x0A, 0x06, 0x41, 0x64, 0x3B, 0x42, 0x5A, 0xDB,
+	 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xCC, 0x60, 0x5D, 0x78, 0xFF, 0xFF, 0x44, 0x47,
+	 0x28, 0x60, 0x2C, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0xFF, 0xA4, 0xFF, 0xFF, 0x08, 0x07, 0x0E, 0x61,
+	 0x41, 0xD3, 0x32, 0x40, 0x08, 0x26, 0x03, 0x00, 0x10, 0xB0, 0xFF, 0xFF, 0xD3, 0x02, 0x42, 0x64,
+	 0x3B, 0x42, 0x5A, 0xDB, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE, 0x0B, 0x04,
+	 0x0F, 0x60, 0xEC, 0x62, 0x40, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xD0, 0x60, 0x22, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x27, 0xD1, 0x7F, 0xF9, 0x24, 0x60, 0x9A, 0x62, 0xA2, 0xD9,
+	 0x1E, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x0F, 0x60, 0xEC, 0x62, 0x20, 0x60, 0x00, 0x64,
+	 0xA2, 0xDB, 0xD0, 0x60, 0x47, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60,
+	 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xBE, 0xFE, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1, 0x40, 0x60,
+	 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x1A, 0x60, 0x6A, 0x62, 0x07, 0x60, 0xD0, 0x64,
+	 0xA2, 0xDB, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x66, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB,
+	 0xFF, 0xFF, 0x04, 0xFF, 0x27, 0x43, 0x06, 0xA3, 0xBD, 0xD3, 0x81, 0xFB, 0xBD, 0xD3, 0x82, 0xFB,
+	 0xA3, 0xD3, 0x83, 0xFB, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x0F, 0x60, 0xEC, 0x62,
+	 0x01, 0x60, 0x04, 0x64, 0xA2, 0xDB, 0xD0, 0x60, 0x79, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0xBC, 0xF1, 0x1A, 0x60, 0x6A, 0x62, 0xA2, 0xD9, 0x0F, 0x60, 0xEA, 0x62, 0xA2, 0xD1,
+	 0xFE, 0x60, 0xFF, 0x61, 0xA1, 0x84, 0x5A, 0xD1, 0x4A, 0xDB, 0xA1, 0x84, 0x5A, 0xDB, 0x0F, 0x60,
+	 0xEA, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x04, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x05, 0x03, 0xA0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0x60, 0xF2, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x08, 0x65, 0x20, 0x44, 0x34, 0x80,
+	 0x5F, 0xF5, 0xEB, 0xF1, 0x2F, 0xF8, 0xEC, 0xF1, 0x30, 0xF8, 0xED, 0xF1, 0x31, 0xF8, 0xBC, 0xF1,
+	 0x19, 0xF8, 0x80, 0x7E, 0xF8, 0x7F, 0x0E, 0xFA, 0x00, 0x64, 0x3E, 0xFA, 0xA9, 0xF1, 0x07, 0xF8,
+	 0x2B, 0xFA, 0xB0, 0x64, 0x2A, 0xFA, 0x27, 0x43, 0x06, 0xA3, 0xBD, 0xD1, 0x2C, 0xF8, 0x32, 0xF8,
+	 0xBD, 0xD1, 0x2D, 0xF8, 0x33, 0xF8, 0xA3, 0xD1, 0x2E, 0xF8, 0x34, 0xF8, 0x06, 0x63, 0x3F, 0xFC,
+	 0x1F, 0x60, 0x54, 0x61, 0xDC, 0xF3, 0xA1, 0xD3, 0x03, 0xA8, 0xAC, 0x83, 0x0F, 0x02, 0x0E, 0x03,
+	 0x1F, 0x60, 0x56, 0x61, 0xA1, 0xD1, 0x66, 0x45, 0x00, 0xF4, 0x09, 0xFC, 0x01, 0x64, 0x0A, 0xFA,
+	 0x0B, 0xF8, 0x1F, 0x60, 0x54, 0x61, 0x00, 0x64, 0xA1, 0xDB, 0x28, 0x00, 0x28, 0x60, 0x2E, 0x64,
+	 0xA0, 0xD3, 0x66, 0x45, 0x00, 0xF4, 0x60, 0x40, 0x01, 0x36, 0x16, 0x00, 0x02, 0x36, 0xC7, 0x00,
+	 0x03, 0x36, 0x07, 0x00, 0x04, 0x36, 0x10, 0x00, 0x05, 0x36, 0xC1, 0x00, 0x06, 0x36, 0x01, 0x00,
+	 0x0B, 0x00, 0x80, 0x64, 0x09, 0xFA, 0x01, 0x63, 0x0A, 0xFC, 0x00, 0x64, 0x0B, 0xFA, 0x2D, 0x60,
+	 0x54, 0x62, 0x03, 0x64, 0xA2, 0xDB, 0x0A, 0x00, 0x00, 0x64, 0x09, 0xFA, 0x01, 0x63, 0x0A, 0xFC,
+	 0x00, 0x64, 0x0B, 0xFA, 0x2D, 0x60, 0x54, 0x62, 0x01, 0x64, 0xA2, 0xDB, 0x24, 0x60, 0x74, 0x62,
+	 0x24, 0x60, 0x28, 0x64, 0xA2, 0xDB, 0x65, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0x00, 0x66, 0xDC, 0xF3, 0x46, 0x46, 0xFD, 0xA0, 0xC1, 0xFE, 0x02, 0x02, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x01, 0x64, 0x69, 0xFB, 0x43, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x1A, 0x60, 0x44, 0x62,
+	 0xA2, 0xD3, 0xFF, 0xFF, 0x64, 0xA4, 0xA2, 0xDB, 0x1A, 0x60, 0x44, 0x62, 0xA2, 0xD1, 0x1A, 0x60,
+	 0x6A, 0x62, 0xA2, 0xD9, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x66, 0x64, 0xA2, 0xDB, 0x02, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x0F, 0x60, 0xEC, 0x62, 0x00, 0x60, 0x0C, 0x64, 0xA2, 0xDB,
+	 0xD1, 0x60, 0x2E, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xEA, 0x62,
+	 0xA2, 0xD1, 0x00, 0x60, 0x08, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x56, 0x03, 0xA0, 0x84, 0xA2, 0xDB,
+	 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x66, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x04, 0xFF, 0x00, 0x64, 0x69, 0xFB, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x26, 0x46,
+	 0x00, 0xF4, 0x09, 0xF2, 0x0A, 0xF2, 0x00, 0xA8, 0x0B, 0xF2, 0x02, 0xA8, 0x16, 0x02, 0x00, 0xA8,
+	 0x1A, 0x02, 0x19, 0x02, 0x26, 0x46, 0x24, 0x60, 0x74, 0x64, 0x40, 0x4B, 0x2C, 0x60, 0x58, 0x4D,
+	 0xD8, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0x20, 0x40, 0x08, 0x2A, 0x03, 0x00, 0xD3, 0x60,
+	 0x48, 0x78, 0xFF, 0xFF, 0xD9, 0x60, 0x68, 0x78, 0xFF, 0xFF, 0x09, 0xF2, 0x0A, 0xF2, 0x80, 0xA8,
+	 0x0B, 0xF2, 0x02, 0xA8, 0xE4, 0x03, 0x44, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x0B, 0xF2, 0x26, 0x46,
+	 0x40, 0x59, 0x02, 0x60, 0x00, 0x61, 0x2F, 0xF2, 0xA1, 0xDB, 0x30, 0xF2, 0x41, 0x58, 0x59, 0xDB,
+	 0x31, 0xF2, 0x59, 0xDB, 0x26, 0x46, 0x24, 0x60, 0x74, 0x64, 0x40, 0x4B, 0x2C, 0x60, 0x58, 0x4D,
+	 0xD8, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0x03, 0x65, 0xE9, 0x60, 0x58, 0x4E, 0x4C, 0x78,
+	 0xFF, 0xFF, 0xDC, 0x60, 0xAA, 0x78, 0xFF, 0xFF, 0xFF, 0x60, 0xFB, 0x64, 0xA0, 0x84, 0xA2, 0xDB,
+	 0x00, 0x64, 0x69, 0xFB, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x20, 0x40, 0x08, 0x2A,
+	 0x03, 0x00, 0xCF, 0x60, 0xF2, 0x78, 0xFF, 0xFF, 0xD7, 0x60, 0xDD, 0x78, 0xFF, 0xFF, 0x01, 0x63,
+	 0x09, 0xFC, 0x32, 0x40, 0x08, 0x26, 0x1A, 0x00, 0x28, 0x60, 0x2C, 0x62, 0xA2, 0xD3, 0xFF, 0xFF,
+	 0x60, 0x40, 0x0B, 0x36, 0x03, 0x00, 0xD0, 0x60, 0xEC, 0x78, 0xFF, 0xFF, 0x01, 0x64, 0xA2, 0xDB,
+	 0x2D, 0x60, 0x56, 0x62, 0x0B, 0x64, 0xA2, 0xDB, 0x2D, 0x60, 0x54, 0x62, 0x02, 0x64, 0xA2, 0xDB,
+	 0xA9, 0xF1, 0x66, 0x41, 0x64, 0x46, 0x22, 0x64, 0x36, 0xFA, 0x61, 0x46, 0x01, 0x64, 0x0A, 0xFA,
+	 0x00, 0x64, 0x0B, 0xFA, 0x01, 0x64, 0x69, 0xFB, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0x24, 0x60, 0x74, 0x62, 0x24, 0x60, 0x28, 0x64, 0xA2, 0xDB, 0x65, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x00, 0x66, 0xDC, 0xF3, 0x46, 0x46, 0xFD, 0xA0, 0xC1, 0xFE,
+	 0x02, 0x02, 0x2F, 0x58, 0xFF, 0xFF, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x66, 0x64, 0xA2, 0xDB,
+	 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x0F, 0x60, 0xEC, 0x62, 0x00, 0x60, 0x0C, 0x64,
+	 0xA2, 0xDB, 0xD1, 0x60, 0xEF, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60,
+	 0xEA, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x08, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x3B, 0x03, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x66, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB,
+	 0xFF, 0xFF, 0x04, 0xFF, 0x00, 0x64, 0x69, 0xFB, 0x26, 0x46, 0x00, 0xF4, 0x09, 0xF2, 0x0A, 0xF2,
+	 0x01, 0xA8, 0x0B, 0xF2, 0x02, 0xA8, 0x04, 0x02, 0x00, 0xA8, 0x02, 0x02, 0x01, 0x02, 0x31, 0x00,
+	 0xD2, 0x60, 0x58, 0x4D, 0xF6, 0x78, 0xFF, 0xFF, 0x0B, 0xF2, 0x26, 0x46, 0x40, 0x59, 0x02, 0x60,
+	 0x00, 0x61, 0x2F, 0xF2, 0xA1, 0xDB, 0x30, 0xF2, 0x41, 0x58, 0x59, 0xDB, 0x31, 0xF2, 0x59, 0xDB,
+	 0x26, 0x46, 0x24, 0x60, 0x74, 0x64, 0x40, 0x4B, 0x2C, 0x60, 0x58, 0x4D, 0xD8, 0x78, 0xFF, 0xFF,
+	 0x00, 0x66, 0x46, 0x46, 0x03, 0x65, 0xE9, 0x60, 0x58, 0x4E, 0x4C, 0x78, 0xFF, 0xFF, 0xDC, 0x60,
+	 0xAA, 0x78, 0xFF, 0xFF, 0xD2, 0x60, 0x58, 0x4D, 0xF6, 0x78, 0xFF, 0xFF, 0x00, 0x64, 0x69, 0xFB,
+	 0x20, 0x40, 0x08, 0x2A, 0x03, 0x00, 0xCF, 0x60, 0xF2, 0x78, 0xFF, 0xFF, 0xD7, 0x60, 0xDD, 0x78,
+	 0xFF, 0xFF, 0x26, 0x46, 0x40, 0x60, 0x00, 0x65, 0x2A, 0xF2, 0x2F, 0xF0, 0xB4, 0x84, 0x2A, 0xFA,
+	 0x2C, 0xF8, 0x32, 0xF8, 0x30, 0xF2, 0x2D, 0xFA, 0x33, 0xFA, 0x31, 0xF2, 0x2E, 0xFA, 0x34, 0xFA,
+	 0xEB, 0xF3, 0x2F, 0xFA, 0xEC, 0xF3, 0x30, 0xFA, 0xED, 0xF3, 0x31, 0xFA, 0xCC, 0xF1, 0x19, 0xF8,
+	 0x1C, 0xF0, 0x13, 0xF8, 0x00, 0x64, 0x3E, 0xFA, 0x00, 0xF4, 0x03, 0x64, 0x0A, 0xFA, 0x00, 0x64,
+	 0x0B, 0xFA, 0x01, 0x63, 0x69, 0xFD, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x24, 0x60,
+	 0x74, 0x62, 0x24, 0x60, 0x28, 0x64, 0xA2, 0xDB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB,
+	 0xFF, 0xFF, 0x2B, 0xFF, 0x00, 0x66, 0xDC, 0xF3, 0x46, 0x46, 0xFD, 0xA0, 0xC1, 0xFE, 0x02, 0x02,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x66, 0x64, 0xA2, 0xDB, 0x02, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x0F, 0x60, 0xEC, 0x62, 0x00, 0x60, 0x0C, 0x64, 0xA2, 0xDB,
+	 0xD2, 0x60, 0x8E, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xEA, 0x62,
+	 0xA2, 0xD1, 0x00, 0x60, 0x08, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x51, 0x03, 0xA0, 0x84, 0xA2, 0xDB,
+	 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x66, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x04, 0xFF, 0x00, 0x64, 0x69, 0xFB, 0x26, 0x46, 0x00, 0xF4, 0x09, 0xF2, 0x0A, 0xF2, 0x01, 0xA8,
+	 0x0B, 0xF2, 0x04, 0xA8, 0x1A, 0x02, 0x00, 0xA8, 0x18, 0x02, 0x17, 0x02, 0xD2, 0x60, 0x58, 0x4D,
+	 0xF6, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x24, 0x60, 0x74, 0x64, 0x40, 0x4B, 0x2C, 0x60, 0x58, 0x4D,
+	 0xD8, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0x20, 0x40, 0x08, 0x2A, 0x03, 0x00, 0xD3, 0x60,
+	 0x48, 0x78, 0xFF, 0xFF, 0xD9, 0x60, 0x68, 0x78, 0xFF, 0xFF, 0xD2, 0x60, 0x58, 0x4D, 0xF6, 0x78,
+	 0xFF, 0xFF, 0x0B, 0xF2, 0x26, 0x46, 0x40, 0x59, 0x02, 0x60, 0x00, 0x61, 0x2F, 0xF2, 0xA1, 0xDB,
+	 0x30, 0xF2, 0x41, 0x58, 0x59, 0xDB, 0x31, 0xF2, 0x59, 0xDB, 0x26, 0x46, 0x24, 0x60, 0x74, 0x64,
+	 0x40, 0x4B, 0x2C, 0x60, 0x58, 0x4D, 0xD8, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0x03, 0x65,
+	 0xE9, 0x60, 0x58, 0x4E, 0x4C, 0x78, 0xFF, 0xFF, 0xDC, 0x60, 0xAA, 0x78, 0xFF, 0xFF, 0xD2, 0x60,
+	 0x58, 0x4D, 0xF6, 0x78, 0xFF, 0xFF, 0x00, 0x64, 0x69, 0xFB, 0x20, 0x40, 0x08, 0x2A, 0x03, 0x00,
+	 0xCF, 0x60, 0xF2, 0x78, 0xFF, 0xFF, 0xD7, 0x60, 0xDD, 0x78, 0xFF, 0xFF, 0x2D, 0x60, 0x56, 0x62,
+	 0xA2, 0xD3, 0xFF, 0xFF, 0x60, 0x40, 0x0B, 0x3A, 0x07, 0x00, 0x28, 0x60, 0x2C, 0x62, 0x0B, 0x64,
+	 0xA2, 0xDB, 0x2D, 0x60, 0x56, 0x62, 0xA2, 0xDF, 0x2D, 0x58, 0xFF, 0xFF, 0x28, 0x60, 0x2C, 0x62,
+	 0xA2, 0xD3, 0x61, 0x43, 0xA5, 0xD2, 0x60, 0x40, 0x0B, 0x2A, 0x30, 0x00, 0x85, 0x3A, 0x30, 0x00,
+	 0x60, 0x41, 0x65, 0x44, 0x0A, 0xA4, 0xA0, 0xD0, 0x2D, 0x60, 0x52, 0x62, 0x64, 0x40, 0x18, 0x26,
+	 0x06, 0x00, 0xA2, 0xDF, 0x28, 0x60, 0x2C, 0x62, 0x01, 0x64, 0xA2, 0xDB, 0x02, 0x00, 0x01, 0x64,
+	 0xA2, 0xDB, 0x61, 0x44, 0x60, 0x47, 0xFF, 0xB4, 0x02, 0xA4, 0x2E, 0x60, 0x62, 0x61, 0xA1, 0xD1,
+	 0xDF, 0x83, 0xC0, 0x84, 0xA1, 0xDB, 0xD0, 0x81, 0xCD, 0x84, 0x4C, 0x91, 0x60, 0x43, 0x60, 0xFE,
+	 0xA5, 0xD2, 0xDE, 0x85, 0x7F, 0x26, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0x5D, 0x93, 0xA3, 0xDB,
+	 0x5D, 0x93, 0xA5, 0xD2, 0xF6, 0x1F, 0x5D, 0x93, 0x20, 0xFE, 0xDF, 0x83, 0x2D, 0x58, 0xFF, 0xFF,
+	 0x2D, 0x60, 0x52, 0x62, 0xA2, 0xDF, 0x28, 0x60, 0x2C, 0x62, 0x01, 0x64, 0xA2, 0xDB, 0xF6, 0x01,
+	 0x45, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x2E, 0x60, 0xEA, 0x7C, 0x2E, 0x60, 0xDE, 0x63, 0xA3, 0xD9,
+	 0x64, 0x41, 0x29, 0x60, 0xA4, 0x63, 0xBD, 0xD3, 0x00, 0x7C, 0x03, 0x1B, 0x27, 0x43, 0x10, 0xA3,
+	 0xBD, 0xD3, 0xFF, 0xFF, 0x60, 0x45, 0x64, 0x5F, 0xA1, 0xDB, 0x65, 0x44, 0xBD, 0xD1, 0xC8, 0x84,
+	 0x59, 0xD8, 0xFC, 0x05, 0x27, 0x41, 0x10, 0xA1, 0xA1, 0xD1, 0xFF, 0xFF, 0xC1, 0x81, 0x01, 0x26,
+	 0xDD, 0x81, 0x41, 0x4C, 0x59, 0xD1, 0x7C, 0x44, 0xB0, 0x84, 0x59, 0xD1, 0x59, 0xD1, 0xB0, 0x84,
+	 0xB0, 0x84, 0xFF, 0xFF, 0x02, 0x02, 0x67, 0x44, 0x5D, 0x00, 0x2D, 0x60, 0xE6, 0x63, 0xDD, 0x60,
+	 0x18, 0x64, 0xBD, 0xDA, 0x50, 0x60, 0x00, 0x64, 0xBD, 0xDA, 0x01, 0x60, 0xF2, 0x64, 0xBD, 0xDA,
+	 0x00, 0x60, 0x01, 0x64, 0xBD, 0xDA, 0x2C, 0x41, 0x59, 0xD3, 0x50, 0x60, 0x00, 0x7C, 0x60, 0x40,
+	 0x02, 0x2A, 0x03, 0x00, 0x01, 0x60, 0xF2, 0x64, 0x0E, 0x00, 0x04, 0x2A, 0x03, 0x00, 0x02, 0x60,
+	 0xF2, 0x64, 0x09, 0x00, 0x10, 0x2A, 0x03, 0x00, 0x04, 0x60, 0xF2, 0x64, 0x04, 0x00, 0x20, 0x2A,
+	 0x04, 0x00, 0x05, 0x60, 0xF2, 0x64, 0xBD, 0xD9, 0xBD, 0xDB, 0x01, 0x64, 0xBD, 0xDB, 0x59, 0xD3,
+	 0x50, 0x60, 0x00, 0x7C, 0x60, 0x40, 0x02, 0x2A, 0x03, 0x00, 0x01, 0x60, 0xF2, 0x64, 0x0E, 0x00,
+	 0x04, 0x2A, 0x03, 0x00, 0x02, 0x60, 0xF2, 0x64, 0x09, 0x00, 0x10, 0x2A, 0x03, 0x00, 0x04, 0x60,
+	 0xF2, 0x64, 0x04, 0x00, 0x20, 0x2A, 0x04, 0x00, 0x05, 0x60, 0xF2, 0x64, 0xBD, 0xD9, 0xBD, 0xDB,
+	 0x01, 0x64, 0xBD, 0xDB, 0x59, 0xD3, 0x50, 0x60, 0x00, 0x7C, 0x60, 0x40, 0x01, 0x2A, 0x03, 0x00,
+	 0x00, 0x60, 0xF2, 0x64, 0x09, 0x00, 0x02, 0x2A, 0x03, 0x00, 0x01, 0x60, 0xF2, 0x64, 0x04, 0x00,
+	 0x04, 0x2A, 0x02, 0x00, 0x02, 0x60, 0xF2, 0x64, 0xBD, 0xD9, 0xBD, 0xDB, 0x59, 0xD3, 0xBD, 0xDA,
+	 0x2D, 0x60, 0xE6, 0x64, 0x2E, 0x60, 0xE4, 0x62, 0xA2, 0xDB, 0x60, 0xF5, 0x00, 0x64, 0x2B, 0xFA,
+	 0x00, 0x64, 0x2A, 0xFA, 0x27, 0x43, 0x06, 0xA3, 0xBD, 0xD1, 0x2C, 0xF8, 0x32, 0xF8, 0xBD, 0xD1,
+	 0x2D, 0xF8, 0x33, 0xF8, 0xA3, 0xD1, 0x2E, 0xF8, 0x34, 0xF8, 0x00, 0xF4, 0x01, 0x63, 0x32, 0x40,
+	 0x08, 0x26, 0x10, 0xBB, 0x28, 0x60, 0x2C, 0x62, 0xA2, 0xD1, 0xFF, 0xFF, 0x64, 0x40, 0xFE, 0x26,
+	 0x10, 0xBB, 0x09, 0xFC, 0x27, 0x42, 0x0C, 0xA2, 0x28, 0x60, 0x02, 0x63, 0xA2, 0xD3, 0xA3, 0xD3,
+	 0x00, 0xBD, 0x01, 0x63, 0xAC, 0x81, 0x09, 0x03, 0x08, 0x03, 0xB0, 0x60, 0x58, 0x4D, 0xB6, 0x78,
+	 0xFF, 0xFF, 0x00, 0xB8, 0x01, 0x63, 0x01, 0x03, 0x60, 0x43, 0x1A, 0x60, 0x3E, 0x64, 0xA0, 0xDD,
+	 0x12, 0x61, 0x59, 0xDC, 0x28, 0x60, 0x2C, 0x62, 0xA2, 0xD3, 0xFF, 0x60, 0xFF, 0x7C, 0x60, 0x40,
+	 0x0B, 0x2A, 0x02, 0x00, 0x2D, 0x60, 0x32, 0x7C, 0x2E, 0x60, 0xE6, 0x62, 0xA2, 0xD9, 0x2E, 0x60,
+	 0xDE, 0x64, 0x40, 0x48, 0xD9, 0x81, 0xFF, 0x60, 0xF2, 0x64, 0xE8, 0x60, 0x58, 0x4D, 0xE8, 0x78,
+	 0xFF, 0xFF, 0x60, 0xF5, 0x3F, 0xFC, 0xDB, 0x83, 0x2E, 0x60, 0x08, 0x62, 0xA2, 0xDD, 0x00, 0x7C,
+	 0x5A, 0xD9, 0x63, 0x41, 0x2E, 0x60, 0x0C, 0x63, 0x12, 0x65, 0x00, 0xF4, 0xCD, 0x84, 0x4C, 0x91,
+	 0x60, 0x43, 0x60, 0xFE, 0xA5, 0xD2, 0xDE, 0x85, 0x7F, 0x26, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65,
+	 0x5D, 0x93, 0xA3, 0xDB, 0x5D, 0x93, 0xA5, 0xD2, 0xF6, 0x1F, 0x5D, 0x93, 0x20, 0xFE, 0xDF, 0x83,
+	 0x60, 0xF5, 0x24, 0x60, 0x74, 0x62, 0x24, 0x60, 0x28, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x00, 0x66, 0x46, 0x46, 0xC1, 0xFE, 0x06, 0x64,
+	 0x69, 0xFB, 0x46, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x66, 0x64,
+	 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x0F, 0x60, 0xEC, 0x62, 0x00, 0x60,
+	 0x1C, 0x64, 0xA2, 0xDB, 0xD4, 0x60, 0x68, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x0F, 0x60, 0xEA, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x08, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x3A, 0x03,
+	 0xA0, 0x84, 0xA2, 0xDB, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x66, 0x64, 0xA2, 0xDB, 0x03, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x26, 0x46,
+	 0x00, 0xF4, 0x0A, 0xF2, 0x00, 0x63, 0x00, 0xA8, 0x69, 0xFD, 0x5A, 0x03, 0x0A, 0xF2, 0x26, 0x46,
+	 0x40, 0x59, 0x02, 0x60, 0x00, 0x61, 0x2F, 0xF2, 0xA1, 0xDB, 0x30, 0xF2, 0x41, 0x58, 0x59, 0xDB,
+	 0x31, 0xF2, 0x59, 0xDB, 0x26, 0x46, 0x24, 0x60, 0x74, 0x64, 0x40, 0x4B, 0x2C, 0x60, 0x58, 0x4D,
+	 0xD8, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0x05, 0x65, 0xE9, 0x60, 0x58, 0x4E, 0x4C, 0x78,
+	 0xFF, 0xFF, 0xDC, 0x60, 0xAA, 0x78, 0xFF, 0xFF, 0x47, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0xCF, 0x60,
+	 0xF2, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x10, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x21, 0x03, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x66, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB,
+	 0xFF, 0xFF, 0x04, 0xFF, 0x26, 0x46, 0x24, 0x60, 0x74, 0x64, 0x40, 0x4B, 0x2C, 0x60, 0x58, 0x4D,
+	 0xD8, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0x00, 0x64, 0x69, 0xFB, 0x0F, 0x60, 0xEA, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x49, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0xD0, 0x60, 0x94, 0x78, 0xFF, 0xFF,
+	 0xFF, 0x60, 0xFB, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x00, 0x64, 0x69, 0xFB, 0x0F, 0x60, 0xEA, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x4A, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0xCF, 0x60, 0xF2, 0x78, 0xFF, 0xFF,
+	 0x48, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x09, 0xF0, 0x2E, 0x60, 0x64, 0x63, 0x10, 0x64, 0xBD, 0xDB,
+	 0xBD, 0xD9, 0x0A, 0xF0, 0xBD, 0xD9, 0x0B, 0xF0, 0xBD, 0xD9, 0x0C, 0xF2, 0xBD, 0xDB, 0x60, 0x47,
+	 0xFF, 0xB4, 0x0A, 0xA5, 0x2E, 0x60, 0x62, 0x61, 0x65, 0x5C, 0xA1, 0xD9, 0x60, 0x41, 0x1A, 0x65,
+	 0xCD, 0x84, 0x4C, 0x91, 0x60, 0x43, 0x60, 0xFE, 0xA5, 0xD2, 0xDE, 0x85, 0x7F, 0x26, 0x02, 0x00,
+	 0x00, 0xF4, 0x04, 0x65, 0x5D, 0x93, 0xA3, 0xDB, 0x5D, 0x93, 0xA5, 0xD2, 0xF6, 0x1F, 0x5D, 0x93,
+	 0x20, 0xFE, 0xDF, 0x83, 0xD3, 0x60, 0x58, 0x4D, 0x06, 0x78, 0xFF, 0xFF, 0x0B, 0xF2, 0xFF, 0xFF,
+	 0x07, 0xB4, 0x01, 0x61, 0x03, 0x03, 0xCC, 0x84, 0xE1, 0x81, 0xFD, 0x02, 0x61, 0x44, 0x96, 0xFB,
+	 0x27, 0x45, 0x02, 0x62, 0x46, 0xD3, 0x5A, 0xD1, 0x60, 0x47, 0x56, 0xFB, 0x64, 0x47, 0x55, 0xFB,
+	 0x00, 0x64, 0x5C, 0xFB, 0x0C, 0x62, 0x46, 0xD3, 0x80, 0xFB, 0x0B, 0xF0, 0x0F, 0x60, 0xFF, 0x64,
+	 0xA0, 0x84, 0x85, 0xFB, 0x26, 0x46, 0x32, 0xF0, 0x81, 0xF9, 0x33, 0xF0, 0x0E, 0x63, 0xC7, 0x81,
+	 0x82, 0xF9, 0x34, 0xF0, 0x83, 0xF9, 0x59, 0xD1, 0xFF, 0xFF, 0x64, 0x44, 0x01, 0x2A, 0xC8, 0x84,
+	 0x60, 0x43, 0x2D, 0x60, 0x78, 0x64, 0x58, 0xD9, 0x59, 0xD1, 0x58, 0xD9, 0xFD, 0x1F, 0x28, 0x60,
+	 0x2C, 0x62, 0xA2, 0xD1, 0x59, 0xD3, 0x64, 0x40, 0x01, 0x36, 0x22, 0x64, 0x64, 0x40, 0x00, 0x36,
+	 0x50, 0x94, 0xA9, 0xF1, 0xFF, 0xFF, 0x44, 0x47, 0xA7, 0x46, 0x36, 0xFA, 0xB7, 0xFC, 0xA7, 0x46,
+	 0x1A, 0x60, 0x3E, 0x62, 0xA2, 0xD3, 0x87, 0xFB, 0x31, 0xF2, 0x1C, 0x60, 0xBA, 0x65, 0x60, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18,
+	 0x61, 0x46, 0x31, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46, 0x30, 0xF0,
+	 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46, 0x2F, 0xF0, 0x63, 0x46, 0xD0, 0x80,
+	 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46, 0xE8, 0x1B, 0xA9, 0xF3, 0x08, 0xFE,
+	 0x60, 0x43, 0x61, 0x46, 0xA9, 0xF1, 0xFF, 0xFF, 0xD3, 0x80, 0x31, 0xF2, 0x27, 0x02, 0x66, 0x41,
+	 0x1C, 0x60, 0xBA, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xA9, 0xF1, 0xE0, 0x84, 0x44, 0xD3, 0x64, 0x43,
+	 0x11, 0x18, 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xFC, 0x1B, 0x66, 0x44, 0x64, 0x46, 0x80, 0xF0,
+	 0x60, 0x46, 0x80, 0xF8, 0x65, 0x46, 0x65, 0x43, 0x80, 0xF0, 0x01, 0xFA, 0x80, 0xFC, 0x64, 0x46,
+	 0x80, 0xF8, 0x0B, 0x00, 0x64, 0x46, 0x62, 0x43, 0x00, 0xF2, 0xA3, 0xDB, 0x60, 0x46, 0x80, 0xF0,
+	 0x81, 0xFC, 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8, 0x60, 0x43, 0x61, 0x46, 0x43, 0x47, 0x00, 0xF4,
+	 0x18, 0x65, 0x0C, 0x61, 0x02, 0x60, 0x00, 0x63, 0xA5, 0xD0, 0xDA, 0x85, 0x64, 0x44, 0x00, 0x7F,
+	 0xCD, 0x81, 0xBD, 0xDB, 0x05, 0x03, 0x64, 0x47, 0x00, 0x7F, 0xCD, 0x81, 0xBD, 0xDB, 0xF4, 0x02,
+	 0x02, 0x60, 0x02, 0x61, 0xA1, 0xD3, 0x00, 0x65, 0x60, 0x43, 0x59, 0xD3, 0xFF, 0xFF, 0x7F, 0xB4,
+	 0x02, 0x3A, 0x02, 0x00, 0x01, 0x64, 0x15, 0x00, 0x04, 0x3A, 0x02, 0x00, 0x02, 0x64, 0x11, 0x00,
+	 0x0A, 0x3A, 0x02, 0x00, 0x04, 0x64, 0x0D, 0x00, 0x0B, 0x3A, 0x02, 0x00, 0x08, 0x64, 0x09, 0x00,
+	 0x10, 0x3A, 0x02, 0x00, 0x10, 0x64, 0x05, 0x00, 0x16, 0x3A, 0x02, 0x00, 0x20, 0x64, 0x01, 0x00,
+	 0x00, 0x64, 0xCF, 0x83, 0xB4, 0x85, 0xE1, 0x02, 0x65, 0x44, 0x7A, 0xFB, 0x02, 0x60, 0x02, 0x61,
+	 0xA1, 0xD3, 0x00, 0x65, 0x60, 0x43, 0x59, 0xD3, 0xFF, 0xFF, 0x80, 0xB0, 0xFF, 0xFF, 0x01, 0x03,
+	 0x60, 0x45, 0xCF, 0x83, 0x65, 0x44, 0xF7, 0x02, 0x7F, 0xB4, 0x02, 0x3A, 0x02, 0x00, 0x0A, 0x64,
+	 0x15, 0x00, 0x04, 0x3A, 0x02, 0x00, 0x14, 0x64, 0x11, 0x00, 0x0A, 0x3A, 0x02, 0x00, 0x32, 0x64,
+	 0x0D, 0x00, 0x0B, 0x3A, 0x02, 0x00, 0x37, 0x64, 0x09, 0x00, 0x10, 0x3A, 0x02, 0x00, 0x50, 0x64,
+	 0x05, 0x00, 0x16, 0x3A, 0x02, 0x00, 0x6E, 0x64, 0x01, 0x00, 0x14, 0x64, 0x7C, 0xFB, 0x27, 0x44,
+	 0xD8, 0xF3, 0x60, 0x45, 0x66, 0x41, 0x65, 0x46, 0x8C, 0xFA, 0x60, 0x40, 0x01, 0x36, 0x06, 0x00,
+	 0x02, 0x36, 0x04, 0x00, 0x04, 0x36, 0x02, 0x00, 0x05, 0x3A, 0x02, 0x00, 0x00, 0x64, 0x01, 0x00,
+	 0x01, 0x64, 0x6F, 0xFA, 0x79, 0xF3, 0x7A, 0xF1, 0xFF, 0xFF, 0xA0, 0x84, 0x65, 0x43, 0x02, 0x02,
+	 0x79, 0xF3, 0xFF, 0xFF, 0x60, 0x41, 0x0F, 0x60, 0xAE, 0x65, 0xD8, 0xF3, 0xFF, 0xFF, 0xE0, 0x84,
+	 0x44, 0xD3, 0x61, 0x45, 0xA4, 0x80, 0xFF, 0xFF, 0x04, 0x02, 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF,
+	 0xFC, 0x03, 0xA4, 0x84, 0x7B, 0xFB, 0x6F, 0xF0, 0x60, 0x47, 0x90, 0x84, 0x6F, 0xFA, 0x60, 0x47,
+	 0x60, 0x45, 0x80, 0x64, 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0xFC, 0x03, 0xA4, 0x84, 0x70, 0xF0,
+	 0x70, 0xFA, 0x00, 0x61, 0xE8, 0x84, 0xFF, 0xFF, 0x02, 0x05, 0xDD, 0x81, 0xFB, 0x01, 0xE1, 0x81,
+	 0x0F, 0x60, 0xA2, 0x65, 0x45, 0xD3, 0x0E, 0xFA, 0x66, 0x43, 0x0C, 0xF4, 0x2D, 0x60, 0xD2, 0x62,
+	 0xA2, 0xD3, 0x2D, 0x60, 0xD0, 0x62, 0xA2, 0xD1, 0x60, 0x47, 0x28, 0x60, 0x2C, 0x62, 0xA2, 0xD1,
+	 0xB0, 0x84, 0x64, 0x40, 0x01, 0x36, 0x22, 0x64, 0x64, 0x40, 0x00, 0x36, 0x50, 0x94, 0xA7, 0x46,
+	 0x36, 0xFA, 0xB7, 0xFC, 0xA7, 0x46, 0x80, 0x60, 0x03, 0x65, 0x32, 0x40, 0x08, 0x2A, 0x03, 0x65,
+	 0xA7, 0x46, 0x06, 0xF0, 0x7F, 0x60, 0xFF, 0x64, 0xA0, 0x84, 0xB4, 0x84, 0x06, 0xFA, 0xB7, 0xFC,
+	 0xA7, 0x46, 0x26, 0x46, 0x2F, 0xF0, 0x30, 0xF0, 0x64, 0x43, 0x31, 0xF2, 0x27, 0x46, 0x03, 0xFC,
+	 0x04, 0xF8, 0x05, 0xFA, 0x26, 0x46, 0xCF, 0x60, 0x58, 0x4E, 0x20, 0x78, 0xFF, 0xFF, 0x26, 0x46,
+	 0x24, 0x60, 0x74, 0x64, 0x40, 0x4B, 0x2C, 0x60, 0x58, 0x4D, 0xD8, 0x78, 0xFF, 0xFF, 0x00, 0x66,
+	 0x46, 0x46, 0x01, 0x64, 0x8C, 0xFB, 0x28, 0x60, 0x38, 0x62, 0xA2, 0xD3, 0x20, 0x41, 0x00, 0xBC,
+	 0x20, 0xB9, 0x01, 0x03, 0x41, 0x40, 0x1F, 0x60, 0x52, 0x61, 0x00, 0x64, 0xA1, 0xDB, 0x04, 0x64,
+	 0xC1, 0xFE, 0xDC, 0xFB, 0xF2, 0xF3, 0xFF, 0xFF, 0xFE, 0xB4, 0xF2, 0xFB, 0xF7, 0x60, 0xFF, 0x65,
+	 0x20, 0x44, 0x24, 0x80, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x01, 0x65, 0xE9, 0x60, 0x58, 0x4E, 0x7B, 0x78, 0xFF, 0xFF, 0x0F, 0x60,
+	 0xD8, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x0C, 0x64,
+	 0x69, 0xFB, 0x0F, 0x60, 0xEC, 0x62, 0x00, 0x60, 0x31, 0x64, 0xA2, 0xDB, 0xD6, 0x60, 0xC4, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x60, 0x0E, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0x5A, 0xDB, 0x0F, 0x60, 0xEA, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x01, 0x64, 0xA0, 0x80, 0x9C, 0x84,
+	 0x10, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x31, 0x60, 0x2C, 0x61, 0xA1, 0xD3, 0xFF, 0xFF, 0x03, 0x1B,
+	 0xDC, 0x60, 0xD0, 0x78, 0xFF, 0xFF, 0xDC, 0x60, 0xD0, 0x78, 0xFF, 0xFF, 0xD7, 0x60, 0x67, 0x78,
+	 0xFF, 0xFF, 0x00, 0x60, 0x10, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0xF8, 0x03, 0xA0, 0x84, 0xA2, 0xDB,
+	 0xA9, 0xF3, 0xFF, 0xFF, 0x02, 0xA4, 0x60, 0x43, 0x66, 0x41, 0x63, 0x46, 0x05, 0xF2, 0x00, 0xF0,
+	 0x81, 0xF0, 0x02, 0x18, 0x64, 0x46, 0x81, 0xF8, 0x07, 0x1B, 0x1C, 0x60, 0xBA, 0x65, 0x60, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD9, 0x02, 0x00, 0x65, 0x46, 0x00, 0xF8, 0xA9, 0xF3, 0x63, 0x45,
+	 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xD4, 0x80, 0x01, 0x18, 0xFA, 0x04, 0x80, 0xF8, 0x65, 0x46,
+	 0x00, 0xFA, 0x06, 0xF2, 0xFF, 0xFF, 0x00, 0x7E, 0x06, 0xFA, 0x61, 0x46, 0x4B, 0x64, 0x3B, 0x42,
+	 0x5A, 0xDB, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x01, 0x60, 0x2E, 0x62, 0xA2, 0xD3,
+	 0xFF, 0xFF, 0x10, 0xB0, 0xFF, 0xFF, 0x13, 0x03, 0x0F, 0x60, 0xEC, 0x62, 0x04, 0x60, 0x00, 0x64,
+	 0xA2, 0xDB, 0xD7, 0x60, 0x2F, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x0F, 0x60, 0xF6, 0x62, 0xA2, 0xD1,
+	 0x01, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x6A, 0xF3,
+	 0xFF, 0xFF, 0x01, 0xB0, 0xFF, 0xFF, 0x13, 0x03, 0x0F, 0x60, 0xD8, 0x62, 0xA2, 0xD1, 0x00, 0x60,
+	 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x0F, 0x60, 0xEC, 0x62, 0x02, 0x60, 0x00, 0x64,
+	 0xA2, 0xDB, 0xD7, 0x60, 0x47, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60,
+	 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x00, 0x64, 0x69, 0xFB, 0xD7, 0x60, 0x58, 0x4E, 0x77, 0x78,
+	 0xFF, 0xFF, 0x02, 0x64, 0x8C, 0xFB, 0x02, 0x64, 0xC1, 0xFE, 0xDC, 0xFB, 0xF2, 0xF3, 0xFF, 0xFF,
+	 0x01, 0xBC, 0xF2, 0xFB, 0x02, 0x65, 0xE9, 0x60, 0x58, 0x4E, 0x7B, 0x78, 0xFF, 0xFF, 0x03, 0x60,
+	 0xE8, 0x63, 0x1A, 0x60, 0x40, 0x64, 0xA0, 0xDD, 0xCB, 0x60, 0x1A, 0x78, 0xFF, 0xFF, 0x00, 0x60,
+	 0x20, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0xFF, 0xFF, 0x08, 0x24, 0x54, 0x01, 0xA0, 0x84, 0xA2, 0xDB,
+	 0x00, 0x63, 0x69, 0xFD, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x15, 0x00, 0x24, 0x60,
+	 0xAA, 0x62, 0x1A, 0x60, 0x66, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF,
+	 0x00, 0x64, 0x69, 0xFB, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x01, 0x64, 0x8C, 0xFB,
+	 0xFF, 0xFF, 0xC1, 0xFE, 0x2E, 0x58, 0xFF, 0xFF, 0x50, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x0F, 0x60,
+	 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x01, 0x60, 0x2E, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x10, 0xB0,
+	 0xFF, 0xFF, 0x13, 0x03, 0x0F, 0x60, 0xF6, 0x62, 0xA2, 0xD1, 0x01, 0x60, 0x00, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x0F, 0x60, 0xEC, 0x62, 0x04, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xD7, 0x60,
+	 0x8F, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0xBC, 0xF1, 0x1A, 0x60, 0x6A, 0x62,
+	 0xA2, 0xD9, 0x7F, 0xF1, 0x7E, 0xF9, 0x02, 0x64, 0x8C, 0xFB, 0xFF, 0xFF, 0xC1, 0xFE, 0x8C, 0xF3,
+	 0x00, 0x65, 0xD4, 0x80, 0xFF, 0xFF, 0x0F, 0x03, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0x0F, 0x60, 0xEC, 0x62, 0x80, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xD7, 0x60, 0xB3, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x51, 0x64,
+	 0x3B, 0x42, 0x5A, 0xDB, 0x19, 0x60, 0x84, 0x64, 0x68, 0xFB, 0x1A, 0x60, 0x46, 0x63, 0x81, 0xF3,
+	 0xBD, 0xDB, 0x82, 0xF3, 0xBD, 0xDB, 0x83, 0xF3, 0xA3, 0xDB, 0x01, 0x60, 0x10, 0x65, 0x68, 0xF3,
+	 0xA5, 0xD1, 0x04, 0xA4, 0x68, 0xFB, 0xD0, 0x80, 0xA0, 0xD3, 0x20, 0x07, 0x40, 0x47, 0x60, 0x41,
+	 0x0E, 0x65, 0x45, 0xD3, 0x28, 0x60, 0x2C, 0x62, 0xA2, 0xD1, 0xFF, 0xFF, 0x03, 0x1B, 0x10, 0xB0,
+	 0xFF, 0xFF, 0xEB, 0x02, 0x27, 0x44, 0x06, 0xA4, 0x60, 0x41, 0xA1, 0xD1, 0x81, 0xF3, 0x82, 0xF1,
+	 0xD0, 0x80, 0x59, 0xD3, 0x08, 0x02, 0xD0, 0x80, 0x83, 0xF3, 0x59, 0xD1, 0x04, 0x02, 0xD0, 0x80,
+	 0xFF, 0xFF, 0x01, 0x02, 0x03, 0x00, 0xD8, 0x60, 0x99, 0x78, 0xFF, 0xFF, 0x1A, 0x60, 0x46, 0x63,
+	 0xBD, 0xD3, 0x81, 0xFB, 0xBD, 0xD3, 0x82, 0xFB, 0xA3, 0xD3, 0x83, 0xFB, 0x53, 0x64, 0x3B, 0x42,
+	 0x5A, 0xDB, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE, 0x0B, 0x04, 0x0F, 0x60,
+	 0xEC, 0x62, 0x40, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xD8, 0x60, 0x06, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x7E, 0xF1, 0x7F, 0xF9, 0x24, 0x60, 0x9A, 0x62, 0xA2, 0xD9, 0x1E, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x0F, 0x60, 0xEC, 0x62, 0x20, 0x60, 0x00, 0x64, 0xA2, 0xDB,
+	 0xD8, 0x60, 0x36, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xEA, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0xBE, 0xFE, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1, 0x40, 0x60, 0x00, 0x64,
+	 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x01, 0x63, 0x8C, 0xFD, 0x0F, 0x60, 0xD8, 0x62, 0xA2, 0xD1,
+	 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0xC1, 0xFE, 0x54, 0x64, 0x3B, 0x42,
+	 0x5A, 0xDB, 0x31, 0x44, 0xF9, 0xB4, 0x40, 0x51, 0x01, 0x60, 0xBA, 0x61, 0x1F, 0x60, 0x08, 0x63,
+	 0xA1, 0xD3, 0xFF, 0xFF, 0x20, 0x7F, 0xBD, 0xDB, 0x59, 0xD3, 0xFF, 0xFF, 0x21, 0x7F, 0xBD, 0xDB,
+	 0x59, 0xD3, 0xFF, 0xFF, 0x22, 0x7F, 0xA3, 0xDB, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0xDE, 0xFE, 0x0B, 0x04, 0x0F, 0x60, 0xEC, 0x62, 0x40, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xD8, 0x60,
+	 0x64, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x24, 0x60, 0x9A, 0x62, 0x1F, 0x60,
+	 0x06, 0x64, 0xA2, 0xDB, 0x20, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x0F, 0x60, 0xEC, 0x62,
+	 0x20, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xD8, 0x60, 0x89, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xBE, 0xFE, 0x0F, 0x60, 0xD0, 0x62,
+	 0xA2, 0xD1, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0xD6, 0x60, 0xB7, 0x78,
+	 0xFF, 0xFF, 0x27, 0x43, 0x2D, 0x60, 0x7A, 0x65, 0xA5, 0xD3, 0x65, 0x41, 0x10, 0xA3, 0x01, 0xA4,
+	 0xFE, 0xB4, 0xC4, 0x85, 0xFE, 0xA1, 0xBD, 0xD3, 0x59, 0xD1, 0xFF, 0xFF, 0xD0, 0x80, 0xD5, 0x80,
+	 0x02, 0x02, 0x04, 0x03, 0xF8, 0x01, 0xD7, 0x60, 0xDD, 0x78, 0xFF, 0xFF, 0x55, 0x64, 0x3B, 0x42,
+	 0x5A, 0xDB, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE, 0x0B, 0x04, 0x0F, 0x60,
+	 0xEC, 0x62, 0x40, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xD8, 0x60, 0xB1, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x27, 0xD1, 0x7F, 0xF9, 0x24, 0x60, 0x9A, 0x62, 0xA2, 0xD9, 0x1E, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x0F, 0x60, 0xEC, 0x62, 0x20, 0x60, 0x00, 0x64, 0xA2, 0xDB,
+	 0xD8, 0x60, 0xD6, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xEA, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0xBE, 0xFE, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1, 0x40, 0x60, 0x00, 0x64,
+	 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x01, 0x60, 0xBA, 0x61, 0x1F, 0x60, 0x08, 0x63, 0xA1, 0xD3,
+	 0xFF, 0xFF, 0x20, 0x7F, 0xBD, 0xDB, 0x21, 0x60, 0x32, 0x64, 0xBD, 0xDB, 0x04, 0xA1, 0xA1, 0xD3,
+	 0xFF, 0xFF, 0x22, 0x7F, 0xA3, 0xDB, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE,
+	 0x0B, 0x04, 0x0F, 0x60, 0xEC, 0x62, 0x40, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xD8, 0x60, 0xF3, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x24, 0x60, 0x9A, 0x62, 0x1F, 0x60, 0x06, 0x64,
+	 0xA2, 0xDB, 0x20, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x0F, 0x60, 0xEC, 0x62, 0x20, 0x60,
+	 0x00, 0x64, 0xA2, 0xDB, 0xD9, 0x60, 0x18, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xBE, 0xFE, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1,
+	 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x1A, 0x60, 0x6A, 0x62, 0x07, 0x60,
+	 0xD0, 0x64, 0xA2, 0xDB, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x66, 0x64, 0xA2, 0xDB, 0x02, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x27, 0x43, 0x06, 0xA3, 0xBD, 0xD3, 0x81, 0xFB, 0xBD, 0xD3,
+	 0x82, 0xFB, 0xA3, 0xD3, 0x83, 0xFB, 0x31, 0x44, 0xF9, 0xB4, 0x40, 0x51, 0x0F, 0x60, 0xEA, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x0F, 0x60, 0xEC, 0x62, 0x01, 0x60, 0x04, 0x64, 0xA2, 0xDB, 0xD9, 0x60,
+	 0x4D, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0xBC, 0xF1, 0x1A, 0x60, 0x6A, 0x62,
+	 0xA2, 0xD9, 0x0F, 0x60, 0xEA, 0x62, 0xA2, 0xD1, 0xFE, 0x60, 0xFF, 0x61, 0xA1, 0x84, 0x5A, 0xD1,
+	 0x4A, 0xDB, 0xA1, 0x84, 0x5A, 0xDB, 0x0F, 0x60, 0xEA, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x04, 0x64,
+	 0xA0, 0x80, 0x9C, 0x84, 0x05, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xD7, 0x60, 0xDD, 0x78, 0xFF, 0xFF,
+	 0x27, 0x42, 0x0C, 0xA2, 0x28, 0x60, 0x02, 0x63, 0xA2, 0xD3, 0xA3, 0xD3, 0x00, 0xBD, 0x01, 0x63,
+	 0xAC, 0x81, 0x09, 0x03, 0x08, 0x03, 0xB0, 0x60, 0x58, 0x4D, 0xB6, 0x78, 0xFF, 0xFF, 0x00, 0xB8,
+	 0x01, 0x63, 0x01, 0x03, 0x60, 0x43, 0x1A, 0x60, 0x3E, 0x64, 0xA0, 0xDD, 0x60, 0xF5, 0x00, 0x64,
+	 0x2B, 0xFA, 0x20, 0x64, 0x2A, 0xFA, 0x27, 0x43, 0x06, 0xA3, 0xBD, 0xD1, 0x2C, 0xF8, 0x32, 0xF8,
+	 0xBD, 0xD1, 0x2D, 0xF8, 0x33, 0xF8, 0xA3, 0xD1, 0x2E, 0xF8, 0x34, 0xF8, 0xEB, 0xF1, 0x2F, 0xF8,
+	 0xEC, 0xF1, 0x30, 0xF8, 0xED, 0xF1, 0x31, 0xF8, 0xBC, 0xF1, 0x19, 0xF8, 0xF8, 0x60, 0x80, 0x64,
+	 0x0E, 0xFA, 0x00, 0xF4, 0x01, 0x63, 0x32, 0x40, 0x08, 0x26, 0x10, 0xBB, 0x28, 0x60, 0x2C, 0x62,
+	 0xA2, 0xD1, 0xFF, 0xFF, 0x64, 0x40, 0xFE, 0x26, 0x10, 0xBB, 0x09, 0xFC, 0x1A, 0x60, 0x3E, 0x64,
+	 0xA0, 0xD3, 0x12, 0x61, 0x59, 0xDA, 0x1A, 0x60, 0x46, 0x63, 0xBD, 0xD1, 0x59, 0xD8, 0xBD, 0xD1,
+	 0x59, 0xD8, 0xA3, 0xD1, 0x59, 0xD8, 0x2E, 0x60, 0xDE, 0x64, 0x40, 0x48, 0xD9, 0x81, 0xFF, 0x60,
+	 0xF2, 0x64, 0xE8, 0x60, 0x58, 0x4D, 0xE8, 0x78, 0xFF, 0xFF, 0x60, 0xF5, 0x3F, 0xFC, 0xDB, 0x83,
+	 0x2E, 0x60, 0x08, 0x62, 0xA2, 0xDD, 0x20, 0x7C, 0x5A, 0xD9, 0x63, 0x41, 0x2E, 0x60, 0x0C, 0x63,
+	 0x12, 0x65, 0x00, 0xF4, 0xCD, 0x84, 0x4C, 0x91, 0x60, 0x43, 0x60, 0xFE, 0xA5, 0xD2, 0xDE, 0x85,
+	 0x7F, 0x26, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0x5D, 0x93, 0xA3, 0xDB, 0x5D, 0x93, 0xA5, 0xD2,
+	 0xF6, 0x1F, 0x5D, 0x93, 0x20, 0xFE, 0xDF, 0x83, 0x60, 0xF5, 0x24, 0x60, 0x74, 0x62, 0x24, 0x60,
+	 0x28, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0x00, 0x66, 0x46, 0x46, 0xC1, 0xFE, 0x14, 0x64, 0x69, 0xFB, 0x56, 0x64, 0x3B, 0x42, 0x5A, 0xDB,
+	 0x1A, 0x60, 0x44, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x64, 0xA4, 0xA2, 0xDB, 0x1A, 0x60, 0x44, 0x62,
+	 0xA2, 0xD1, 0x1A, 0x60, 0x6A, 0x62, 0xA2, 0xD9, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x66, 0x64,
+	 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x0F, 0x60, 0xEC, 0x62, 0x00, 0x60,
+	 0x1C, 0x64, 0xA2, 0xDB, 0xDA, 0x60, 0x10, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x0F, 0x60, 0xEA, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x04, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x0E, 0x03,
+	 0xA0, 0x84, 0xA2, 0xDB, 0x57, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x00, 0x64, 0x69, 0xFB, 0x0F, 0x60,
+	 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xD7, 0x60, 0xDD, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x10, 0x64,
+	 0xA0, 0x80, 0x9C, 0x84, 0x17, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60,
+	 0x66, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x58, 0x64, 0x3B, 0x42,
+	 0x5A, 0xDB, 0x00, 0x64, 0x69, 0xFB, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xDB, 0x60,
+	 0xCB, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x08, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x3A, 0x03, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x66, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB,
+	 0xFF, 0xFF, 0x04, 0xFF, 0x00, 0x64, 0x69, 0xFB, 0x0F, 0x60, 0xEA, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0x26, 0x46, 0x00, 0xF4, 0x0A, 0xF2, 0xFF, 0xFF, 0x2C, 0x18, 0x59, 0x64, 0x3B, 0x42, 0x5A, 0xDB,
+	 0x0A, 0xF2, 0x26, 0x46, 0x40, 0x59, 0x02, 0x60, 0x00, 0x61, 0x2F, 0xF2, 0xA1, 0xDB, 0x30, 0xF2,
+	 0x41, 0x58, 0x59, 0xDB, 0x31, 0xF2, 0x59, 0xDB, 0x26, 0x46, 0x24, 0x60, 0x74, 0x64, 0x40, 0x4B,
+	 0x2C, 0x60, 0x58, 0x4D, 0xD8, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0x05, 0x65, 0xE9, 0x60,
+	 0x58, 0x4E, 0x4C, 0x78, 0xFF, 0xFF, 0xDC, 0x60, 0xAA, 0x78, 0xFF, 0xFF, 0xD7, 0x60, 0xDD, 0x78,
+	 0xFF, 0xFF, 0x5A, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x78, 0x43, 0x02, 0x61, 0x24, 0x60, 0xDD, 0x78,
+	 0xFF, 0xFF, 0x5B, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x09, 0xF0, 0x2E, 0x60, 0x64, 0x63, 0x30, 0x64,
+	 0xBD, 0xDB, 0xBD, 0xD9, 0x0A, 0xF0, 0xBD, 0xD9, 0x0B, 0xF0, 0xBD, 0xD9, 0x0C, 0xF2, 0xBD, 0xDB,
+	 0x60, 0x47, 0xFF, 0xB4, 0x0A, 0xA5, 0x2E, 0x60, 0x62, 0x62, 0x65, 0x5C, 0xA2, 0xD9, 0x60, 0x41,
+	 0x1A, 0x65, 0xCD, 0x84, 0x4C, 0x91, 0x60, 0x43, 0x60, 0xFE, 0xA5, 0xD2, 0xDE, 0x85, 0x7F, 0x26,
+	 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0x5D, 0x93, 0xA3, 0xDB, 0x5D, 0x93, 0xA5, 0xD2, 0xF6, 0x1F,
+	 0x5D, 0x93, 0x20, 0xFE, 0xDF, 0x83, 0xD3, 0x60, 0x58, 0x4D, 0x06, 0x78, 0xFF, 0xFF, 0x0B, 0xF2,
+	 0xFF, 0xFF, 0x07, 0xB4, 0x01, 0x61, 0x03, 0x03, 0xCC, 0x84, 0xE1, 0x81, 0xFD, 0x02, 0x61, 0x44,
+	 0x96, 0xFB, 0x27, 0x45, 0x02, 0x62, 0x46, 0xD3, 0x5A, 0xD1, 0x60, 0x47, 0x56, 0xFB, 0x64, 0x47,
+	 0x55, 0xFB, 0x00, 0x64, 0x5C, 0xFB, 0x0C, 0x62, 0x46, 0xD3, 0x80, 0xFB, 0x0B, 0xF0, 0x0F, 0x60,
+	 0xFF, 0x64, 0xA0, 0x84, 0x85, 0xFB, 0x1A, 0x60, 0x3E, 0x62, 0xA2, 0xD3, 0x87, 0xFB, 0x26, 0x46,
+	 0x32, 0xF0, 0x81, 0xF9, 0x33, 0xF0, 0x82, 0xF9, 0x34, 0xF0, 0x83, 0xF9, 0x00, 0xF4, 0x18, 0x65,
+	 0x0C, 0x61, 0x02, 0x60, 0x00, 0x63, 0xA5, 0xD0, 0xDA, 0x85, 0x64, 0x44, 0x00, 0x7F, 0xCD, 0x81,
+	 0xBD, 0xDB, 0x05, 0x03, 0x64, 0x47, 0x00, 0x7F, 0xCD, 0x81, 0xBD, 0xDB, 0xF4, 0x02, 0x02, 0x60,
+	 0x02, 0x61, 0xA1, 0xD3, 0x00, 0x65, 0x60, 0x43, 0x59, 0xD3, 0xFF, 0xFF, 0x7F, 0xB4, 0x02, 0x3A,
+	 0x02, 0x00, 0x01, 0x64, 0x15, 0x00, 0x04, 0x3A, 0x02, 0x00, 0x02, 0x64, 0x11, 0x00, 0x0A, 0x3A,
+	 0x02, 0x00, 0x04, 0x64, 0x0D, 0x00, 0x0B, 0x3A, 0x02, 0x00, 0x08, 0x64, 0x09, 0x00, 0x10, 0x3A,
+	 0x02, 0x00, 0x10, 0x64, 0x05, 0x00, 0x16, 0x3A, 0x02, 0x00, 0x20, 0x64, 0x01, 0x00, 0x00, 0x64,
+	 0xCF, 0x83, 0xB4, 0x85, 0xE1, 0x02, 0x65, 0x44, 0x7A, 0xFB, 0x02, 0x60, 0x02, 0x61, 0xA1, 0xD3,
+	 0x00, 0x65, 0x60, 0x43, 0x59, 0xD3, 0xFF, 0xFF, 0x80, 0xB0, 0xFF, 0xFF, 0x01, 0x03, 0x60, 0x45,
+	 0xCF, 0x83, 0x65, 0x44, 0xF7, 0x02, 0x7F, 0xB4, 0x02, 0x3A, 0x02, 0x00, 0x0A, 0x64, 0x15, 0x00,
+	 0x04, 0x3A, 0x02, 0x00, 0x14, 0x64, 0x11, 0x00, 0x0A, 0x3A, 0x02, 0x00, 0x32, 0x64, 0x0D, 0x00,
+	 0x0B, 0x3A, 0x02, 0x00, 0x37, 0x64, 0x09, 0x00, 0x10, 0x3A, 0x02, 0x00, 0x50, 0x64, 0x05, 0x00,
+	 0x16, 0x3A, 0x02, 0x00, 0x6E, 0x64, 0x01, 0x00, 0x14, 0x64, 0x7C, 0xFB, 0xA9, 0xF3, 0xFF, 0xFF,
+	 0x02, 0xA4, 0xD8, 0xF3, 0x60, 0x45, 0x66, 0x41, 0x65, 0x46, 0x8C, 0xFA, 0x60, 0x40, 0x01, 0x36,
+	 0x06, 0x00, 0x02, 0x36, 0x04, 0x00, 0x04, 0x36, 0x02, 0x00, 0x05, 0x3A, 0x02, 0x00, 0x00, 0x64,
+	 0x01, 0x00, 0x01, 0x64, 0x6F, 0xFA, 0x79, 0xF3, 0x7A, 0xF1, 0xFF, 0xFF, 0xA0, 0x84, 0x65, 0x43,
+	 0x02, 0x02, 0x79, 0xF3, 0xFF, 0xFF, 0x60, 0x41, 0x0F, 0x60, 0xAE, 0x65, 0xD8, 0xF3, 0xFF, 0xFF,
+	 0xE0, 0x84, 0x44, 0xD3, 0x61, 0x45, 0xA4, 0x80, 0xFF, 0xFF, 0x04, 0x02, 0xE8, 0x84, 0xA4, 0x80,
+	 0xFF, 0xFF, 0xFC, 0x03, 0xA4, 0x84, 0x7B, 0xFB, 0x6F, 0xF0, 0x60, 0x47, 0x90, 0x84, 0x6F, 0xFA,
+	 0x60, 0x47, 0x60, 0x45, 0x80, 0x64, 0xE8, 0x84, 0xA4, 0x80, 0xFF, 0xFF, 0xFC, 0x03, 0xA4, 0x84,
+	 0x70, 0xF0, 0x70, 0xFA, 0x00, 0x61, 0xE8, 0x84, 0xFF, 0xFF, 0x02, 0x05, 0xDD, 0x81, 0xFB, 0x01,
+	 0xE1, 0x81, 0x0F, 0x60, 0xA2, 0x65, 0x45, 0xD3, 0x0E, 0xFA, 0x66, 0x43, 0x0C, 0xF4, 0xA9, 0xF3,
+	 0x1C, 0x60, 0xBA, 0x65, 0x02, 0xA4, 0x60, 0x46, 0x05, 0xF0, 0x60, 0x41, 0x64, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x00, 0x7C, 0x44, 0xD9, 0x26, 0x46, 0x31, 0xF2, 0x61, 0x5C, 0x60, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD9, 0x26, 0x46, 0x2F, 0xF0, 0x61, 0x46, 0x03, 0xF8, 0x26, 0x46, 0x30, 0xF0,
+	 0x61, 0x46, 0x04, 0xF8, 0x26, 0x46, 0x31, 0xF0, 0x61, 0x46, 0x05, 0xF8, 0x26, 0x46, 0xCF, 0x60,
+	 0x58, 0x4E, 0x20, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x24, 0x60, 0x74, 0x64, 0x40, 0x4B, 0x2C, 0x60,
+	 0x58, 0x4D, 0xD8, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0x03, 0x65, 0xE9, 0x60, 0x58, 0x4E,
+	 0x7B, 0x78, 0xFF, 0xFF, 0x01, 0x63, 0x8C, 0xFD, 0x0F, 0x60, 0xD8, 0x62, 0xA2, 0xD1, 0x00, 0x60,
+	 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0xC1, 0xFE, 0x5C, 0x64, 0x3B, 0x42, 0x5A, 0xDB,
+	 0xD6, 0x60, 0xB7, 0x78, 0xFF, 0xFF, 0xFF, 0x60, 0xF7, 0x65, 0x20, 0x44, 0x24, 0x80, 0xD0, 0x60,
+	 0x98, 0x78, 0xFF, 0xFF, 0xDC, 0xF3, 0xFF, 0xFF, 0xFD, 0xA0, 0x2A, 0xF2, 0x03, 0x03, 0xDC, 0x60,
+	 0x7B, 0x78, 0xFF, 0xFF, 0x60, 0x40, 0xB0, 0x36, 0x11, 0x00, 0xC0, 0x36, 0x02, 0x00, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x26, 0x46, 0x24, 0x60, 0x74, 0x64, 0x40, 0x4B, 0x2C, 0x60, 0x58, 0x4D, 0xD8, 0x78,
+	 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0xD0, 0x60, 0x98, 0x78, 0xFF, 0xFF, 0x66, 0x45, 0x00, 0xF4,
+	 0x0A, 0xF2, 0x0B, 0xF2, 0xFE, 0xA0, 0xF3, 0xA0, 0x6F, 0x02, 0x60, 0x41, 0x09, 0xF2, 0x20, 0x03,
+	 0x00, 0xA0, 0xFF, 0xA0, 0x53, 0x03, 0x65, 0x03, 0x00, 0xA0, 0xFF, 0xFF, 0x4F, 0x03, 0x1F, 0x60,
+	 0x54, 0x61, 0x01, 0x64, 0xA1, 0xDB, 0x1F, 0x60, 0x56, 0x61, 0x0D, 0x64, 0xA1, 0xDB, 0x1F, 0x60,
+	 0x58, 0x61, 0x03, 0x64, 0xA1, 0xDB, 0x26, 0x46, 0x24, 0x60, 0x74, 0x64, 0x40, 0x4B, 0x2C, 0x60,
+	 0x58, 0x4D, 0xD8, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0xD0, 0x60, 0x98, 0x78, 0xFF, 0xFF,
+	 0x28, 0x60, 0x2E, 0x61, 0xA1, 0xD3, 0xFF, 0xFF, 0xFE, 0xA0, 0x1F, 0x60, 0x54, 0x61, 0x17, 0x02,
+	 0x01, 0x64, 0xA1, 0xDB, 0x1F, 0x60, 0x56, 0x61, 0x00, 0x64, 0xA1, 0xDB, 0x1F, 0x60, 0x58, 0x61,
+	 0x01, 0x64, 0xA1, 0xDB, 0x26, 0x46, 0x24, 0x60, 0x74, 0x64, 0x40, 0x4B, 0x2C, 0x60, 0x58, 0x4D,
+	 0xD8, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0xD0, 0x60, 0x98, 0x78, 0xFF, 0xFF, 0x02, 0x64,
+	 0xA1, 0xDB, 0x1F, 0x60, 0x56, 0x61, 0x00, 0x64, 0xA1, 0xDB, 0x1F, 0x60, 0x58, 0x61, 0x01, 0x64,
+	 0xA1, 0xDB, 0x26, 0x46, 0x24, 0x60, 0x74, 0x64, 0x40, 0x4B, 0x2C, 0x60, 0x58, 0x4D, 0xD8, 0x78,
+	 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0xD0, 0x60, 0x98, 0x78, 0xFF, 0xFF, 0x65, 0x46, 0x07, 0xF4,
+	 0x06, 0xF2, 0xFF, 0xFF, 0x01, 0x7E, 0x06, 0xFA, 0x65, 0x46, 0x26, 0x46, 0x24, 0x60, 0x74, 0x64,
+	 0x40, 0x4B, 0x2C, 0x60, 0x58, 0x4D, 0xD8, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0x2F, 0x58,
+	 0xFF, 0xFF, 0xD2, 0x60, 0x41, 0x78, 0xFF, 0xFF, 0x0A, 0xF2, 0x09, 0xF2, 0xFC, 0xA0, 0xFF, 0xA0,
+	 0x11, 0x02, 0x0A, 0x02, 0x0B, 0xF2, 0x65, 0x46, 0x0A, 0x1B, 0x66, 0x41, 0x07, 0xF4, 0x06, 0xF2,
+	 0xFF, 0xFF, 0x01, 0x7E, 0x06, 0xFA, 0x61, 0x46, 0xD0, 0x60, 0x98, 0x78, 0xFF, 0xFF, 0x26, 0x46,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x65, 0x46, 0x69, 0xF1, 0x2A, 0xF2, 0x64, 0x41, 0x60, 0x40, 0xA0, 0x3A,
+	 0x02, 0x00, 0x08, 0xB1, 0x04, 0x00, 0xC0, 0x3A, 0x0C, 0x00, 0x04, 0xB1, 0xFF, 0xFF, 0x20, 0x03,
+	 0x0F, 0x60, 0xEA, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x10, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x17, 0x00, 0xB0, 0x3A, 0x02, 0x00, 0x01, 0x65, 0x07, 0x00, 0x10, 0x3A, 0x02, 0x00, 0x02, 0x65,
+	 0x03, 0x00, 0x30, 0x3A, 0x0D, 0x00, 0x10, 0x65, 0xA5, 0x80, 0xFF, 0xFF, 0x09, 0x03, 0x0F, 0x60,
+	 0xEA, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x08, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x00, 0x66,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x28, 0x60, 0x2E, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xFC, 0xA0, 0xFF, 0xFF,
+	 0x16, 0x04, 0x0F, 0x60, 0xEC, 0x62, 0x00, 0x60, 0x02, 0x64, 0xA2, 0xDB, 0xDC, 0x60, 0xBC, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x2D, 0x60, 0x58, 0x65, 0xA5, 0xD1, 0x01, 0x60,
+	 0x00, 0x64, 0xA0, 0x80, 0xFF, 0xFF, 0x03, 0x03, 0xD0, 0x60, 0x98, 0x78, 0xFF, 0xFF, 0x20, 0x40,
+	 0x08, 0x2A, 0x03, 0x00, 0xCF, 0x60, 0xF2, 0x78, 0xFF, 0xFF, 0xD7, 0x60, 0xDD, 0x78, 0xFF, 0xFF,
+	 0x4E, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x2E, 0xF5, 0xFF, 0xFF, 0x27, 0xF2, 0x1C, 0x60, 0xBA, 0x65,
+	 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2,
+	 0x16, 0x18, 0x61, 0x46, 0x27, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46,
+	 0x26, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46, 0x25, 0xF0, 0x63, 0x46,
+	 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46, 0xE8, 0x1B, 0xA9, 0xF3,
+	 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0x25, 0xF2, 0x26, 0xF0, 0xA7, 0xF2, 0xA8, 0xF0, 0x66, 0xF5,
+	 0xFF, 0xFF, 0x00, 0xF4, 0xFF, 0xFF, 0x89, 0xF8, 0x66, 0xF5, 0xFF, 0xFF, 0x07, 0xFC, 0x2C, 0xFA,
+	 0x2D, 0xF8, 0xAE, 0xFA, 0xEB, 0xF3, 0x2F, 0xFA, 0xEC, 0xF3, 0x30, 0xFA, 0xED, 0xF3, 0x31, 0xFA,
+	 0x81, 0xF3, 0x32, 0xFA, 0x82, 0xF3, 0x33, 0xFA, 0x83, 0xF3, 0x34, 0xFA, 0x31, 0x60, 0x2C, 0x61,
+	 0xA1, 0xD3, 0xFF, 0xFF, 0x03, 0x1B, 0x00, 0x60, 0xA0, 0x64, 0x02, 0x00, 0x00, 0x60, 0xC0, 0x64,
+	 0x2A, 0xFA, 0x02, 0x63, 0x3F, 0xFC, 0xAB, 0xFC, 0x00, 0x64, 0x3E, 0xFA, 0xCC, 0xF1, 0x19, 0xF8,
+	 0x24, 0x60, 0x74, 0x62, 0x24, 0x60, 0x28, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x00, 0x66, 0x46, 0x46, 0xC1, 0xFE, 0x0F, 0x60, 0xEA, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0xD6, 0x60, 0xC2, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x3A, 0x61, 0xAE, 0x60,
+	 0x58, 0x4D, 0xC4, 0x78, 0xFF, 0xFF, 0x66, 0x44, 0x62, 0xFB, 0xA9, 0xF3, 0x07, 0xFA, 0x0C, 0x60,
+	 0x80, 0x64, 0xBC, 0xF1, 0x19, 0xF8, 0x0E, 0xFA, 0x00, 0x64, 0x3E, 0xFA, 0x3F, 0xFA, 0x00, 0x60,
+	 0x3A, 0x61, 0xAE, 0x60, 0x58, 0x4D, 0xC4, 0x78, 0xFF, 0xFF, 0x66, 0x44, 0x61, 0xFB, 0xA9, 0xF3,
+	 0x07, 0xFA, 0x0C, 0x60, 0x80, 0x64, 0x0E, 0xFA, 0xBC, 0xF1, 0x19, 0xF8, 0x00, 0x64, 0x3E, 0xFA,
+	 0x3F, 0xFA, 0x10, 0x60, 0x20, 0x62, 0xDE, 0x60, 0xDC, 0x64, 0xA2, 0xDB, 0x0F, 0x60, 0xE0, 0x62,
+	 0x00, 0x60, 0x80, 0x64, 0xA2, 0xDB, 0xDD, 0x60, 0x71, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x20, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x27, 0x60, 0xB6, 0x62, 0xA2, 0xD3, 0xFF, 0xFF,
+	 0x01, 0xA8, 0x03, 0xA8, 0x04, 0x03, 0x03, 0x03, 0xDE, 0x60, 0xCA, 0x78, 0xFF, 0xFF, 0x04, 0x60,
+	 0x00, 0x65, 0x20, 0x44, 0x34, 0x80, 0x0F, 0x60, 0xDE, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x9B, 0xFE,
+	 0x03, 0x05, 0x20, 0x40, 0x4B, 0x23, 0x0E, 0x00, 0x0F, 0x60, 0xE0, 0x62, 0x80, 0x60, 0x00, 0x64,
+	 0xA2, 0xDB, 0xDD, 0x60, 0x83, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x21, 0x64, 0x3B, 0x42, 0x5A, 0xDB,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x1F, 0x60, 0x86, 0x61, 0xA1, 0xD3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x2A,
+	 0x07, 0x00, 0x90, 0x60, 0x00, 0x65, 0x20, 0x44, 0x34, 0x80, 0x00, 0x64, 0xA1, 0xDB, 0x04, 0x00,
+	 0x10, 0x60, 0x00, 0x65, 0x20, 0x44, 0x34, 0x80, 0x8C, 0xF3, 0x58, 0xFB, 0x84, 0xF1, 0xBA, 0xFE,
+	 0x01, 0xA8, 0x59, 0xF9, 0x04, 0x02, 0x02, 0x64, 0x8C, 0xFB, 0xFF, 0xFF, 0xC1, 0xFE, 0x64, 0x47,
+	 0xDC, 0xF3, 0x10, 0xB0, 0x04, 0xA8, 0x33, 0x02, 0x32, 0x02, 0x62, 0xF5, 0xEB, 0xF1, 0x2F, 0xF8,
+	 0xEC, 0xF1, 0x30, 0xF8, 0xED, 0xF1, 0x31, 0xF8, 0x81, 0xF1, 0x2C, 0xF8, 0x32, 0xF8, 0x82, 0xF1,
+	 0x2D, 0xF8, 0x33, 0xF8, 0x83, 0xF1, 0x2E, 0xF8, 0x34, 0xF8, 0x10, 0x60, 0x48, 0x64, 0x2A, 0xFA,
+	 0x24, 0x60, 0x74, 0x62, 0x24, 0x60, 0x28, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x22, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x0F, 0x60,
+	 0xE0, 0x62, 0x00, 0x60, 0x01, 0x64, 0xA2, 0xDB, 0xDD, 0x60, 0xEA, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x23, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x10, 0x67, 0x84, 0xFB, 0x8C, 0xF3,
+	 0xFF, 0xFF, 0x00, 0xA8, 0xFF, 0xFF, 0x0B, 0x03, 0x0F, 0x60, 0xE0, 0x62, 0x80, 0x60, 0x00, 0x64,
+	 0xA2, 0xDB, 0xDD, 0x60, 0xEF, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60,
+	 0xDE, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x1B, 0x60, 0xC6, 0x65, 0x1F, 0x60, 0x80, 0x64, 0xA0, 0xD3,
+	 0x05, 0x7C, 0x08, 0xB0, 0xA5, 0xD3, 0x05, 0x02, 0x00, 0xB8, 0xFF, 0xFF, 0x02, 0x03, 0x15, 0x7C,
+	 0x0B, 0x00, 0xDC, 0xF3, 0x12, 0x60, 0x26, 0x63, 0x03, 0xA8, 0x7F, 0xF3, 0x05, 0x02, 0xE0, 0x85,
+	 0x47, 0xD3, 0xFF, 0xFF, 0x07, 0xBC, 0xA2, 0xDB, 0x53, 0xF9, 0x29, 0x60, 0xC6, 0x64, 0x54, 0xFB,
+	 0x24, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x0F, 0x4E, 0xEC, 0x60, 0x58, 0x4F, 0xB9, 0x78, 0xFF, 0xFF,
+	 0x0E, 0x4F, 0x0F, 0x60, 0xE0, 0x62, 0x10, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0x60, 0x34, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x25, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x59, 0xF3, 0x84, 0xFB, 0x60, 0x40, 0x10, 0x27, 0xDA, 0xFE, 0xDC, 0xF3, 0x00, 0xA8, 0x04, 0xA8,
+	 0x27, 0x02, 0x26, 0x02, 0x61, 0xF5, 0xEB, 0xF1, 0x2F, 0xF8, 0xEC, 0xF1, 0x30, 0xF8, 0xED, 0xF1,
+	 0x31, 0xF8, 0x81, 0xF1, 0x2C, 0xF8, 0x82, 0xF1, 0x2D, 0xF8, 0x83, 0xF1, 0x2E, 0xF8, 0xA4, 0x64,
+	 0x2A, 0xFA, 0x85, 0xF1, 0xC0, 0x67, 0xB0, 0x84, 0x2B, 0xFA, 0x24, 0x60, 0x74, 0x62, 0x24, 0x60,
+	 0x28, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0xC1, 0xFE, 0x20, 0x60, 0x00, 0x65, 0x20, 0x44, 0x34, 0x80, 0x26, 0x64, 0x3B, 0x42, 0x5A, 0xDB,
+	 0x9E, 0xF5, 0xFF, 0xFF, 0x07, 0x1B, 0x20, 0x40, 0x80, 0x2B, 0x5C, 0x00, 0x7F, 0x60, 0xFF, 0x65,
+	 0x20, 0x44, 0x24, 0x80, 0x00, 0x64, 0x41, 0xFB, 0xF1, 0x60, 0x01, 0x64, 0x24, 0xFA, 0xDA, 0x85,
+	 0x19, 0x60, 0x86, 0x63, 0x89, 0xF1, 0x43, 0x4C, 0xD3, 0x80, 0xBE, 0xD1, 0x14, 0x05, 0x65, 0x40,
+	 0x80, 0x2A, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0x64, 0x43, 0x32, 0x61, 0x0F, 0x4E, 0x2F, 0x60,
+	 0x58, 0x4F, 0x01, 0x78, 0xFF, 0xFF, 0x0E, 0x4F, 0x2C, 0x43, 0x04, 0xA3, 0x41, 0xF3, 0xFF, 0xFF,
+	 0x32, 0xA4, 0x41, 0xFB, 0xE7, 0x01, 0x20, 0x47, 0x20, 0xB0, 0x20, 0xAF, 0x0F, 0x03, 0x40, 0x40,
+	 0x0F, 0x60, 0xE0, 0x62, 0x00, 0x60, 0x01, 0x64, 0xA2, 0xDB, 0xDE, 0x60, 0xA3, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x27, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x9E, 0xF1, 0x41, 0xF3,
+	 0xFF, 0xFF, 0x02, 0xA4, 0xE8, 0x84, 0x64, 0x46, 0x23, 0xFA, 0x24, 0x60, 0x74, 0x62, 0x24, 0x60,
+	 0x64, 0x64, 0xA2, 0xDB, 0x5A, 0xD9, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x00, 0x64,
+	 0x9E, 0xFB, 0xFA, 0xFE, 0xEB, 0x60, 0xFF, 0x65, 0x20, 0x44, 0x24, 0x80, 0x0F, 0x60, 0xD0, 0x62,
+	 0xA2, 0xD1, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x58, 0xF3, 0x8C, 0xFB,
+	 0xFF, 0xFF, 0xC1, 0xFE, 0x0F, 0x60, 0xDE, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x0F, 0x60, 0xE0, 0x62,
+	 0x00, 0x60, 0x80, 0x64, 0xA2, 0xDB, 0xDD, 0x60, 0x71, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2E, 0x64,
+	 0x3B, 0x42, 0x5A, 0xDB, 0x2F, 0x58, 0xFF, 0xFF, 0x2F, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x9E, 0xF1,
+	 0x00, 0x64, 0xB0, 0x86, 0x9E, 0xFB, 0x07, 0x03, 0x24, 0x60, 0x74, 0x64, 0x40, 0x4B, 0x2C, 0x60,
+	 0x58, 0x4D, 0xD8, 0x78, 0xFF, 0xFF, 0xEB, 0x60, 0xFF, 0x65, 0x20, 0x44, 0x24, 0x80, 0x0F, 0x60,
+	 0xDE, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x0F, 0x60, 0xE0, 0x62, 0x00, 0x60, 0x80, 0x64, 0xA2, 0xDB,
+	 0xDD, 0x60, 0x71, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x97, 0xF3, 0x26, 0x46,
+	 0x60, 0x43, 0x01, 0x2A, 0x22, 0x00, 0x0F, 0xF2, 0x2A, 0xF0, 0x60, 0x40, 0x10, 0x2A, 0x10, 0x00,
+	 0x64, 0x40, 0x04, 0x27, 0x1A, 0x00, 0xFD, 0xB3, 0x64, 0x40, 0x20, 0x27, 0x02, 0xBB, 0x0F, 0x60,
+	 0xF6, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x08, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x0C, 0x00,
+	 0xFB, 0xB3, 0x64, 0x40, 0x20, 0x27, 0x04, 0xBB, 0x0F, 0x60, 0xF6, 0x62, 0xA2, 0xD1, 0x00, 0x60,
+	 0x10, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x97, 0xFD, 0x26, 0x46, 0x2F, 0x58, 0xFF, 0xFF,
+	 0xDC, 0xF3, 0x3F, 0xF2, 0x04, 0xA8, 0x57, 0xFB, 0x02, 0x03, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0xF4,
+	 0x1E, 0x63, 0x08, 0x64, 0x40, 0x48, 0xBD, 0xD2, 0xFF, 0xFF, 0x60, 0x47, 0x05, 0x36, 0x0B, 0x00,
+	 0xFF, 0xB5, 0xC7, 0x83, 0x01, 0x2A, 0xF7, 0x01, 0x4F, 0xD2, 0x5B, 0xD2, 0x60, 0x40, 0x05, 0x37,
+	 0x08, 0x00, 0xDF, 0x83, 0xF5, 0x01, 0xFF, 0xB5, 0x65, 0x41, 0x47, 0x8A, 0x5B, 0xD2, 0xDF, 0x83,
+	 0x07, 0x00, 0x00, 0x7F, 0xDC, 0x85, 0x47, 0x8A, 0x60, 0x41, 0x5B, 0xD2, 0xDB, 0x83, 0x60, 0x47,
+	 0x01, 0xB0, 0xFE, 0xB5, 0x02, 0x03, 0x02, 0x64, 0x40, 0x48, 0x85, 0xF1, 0x65, 0x44, 0xE0, 0x84,
+	 0xE0, 0x84, 0xE0, 0x84, 0xFD, 0xA1, 0xE1, 0x81, 0xE1, 0x81, 0xE1, 0x85, 0xC4, 0x81, 0xD0, 0x84,
+	 0xD1, 0x80, 0x2A, 0x07, 0x29, 0x06, 0x9C, 0x84, 0xDC, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x85,
+	 0x96, 0xF3, 0xC7, 0x83, 0x01, 0x26, 0x60, 0x47, 0xAB, 0x83, 0xFC, 0xA3, 0x02, 0x00, 0x03, 0x04,
+	 0x00, 0xF4, 0x84, 0xA3, 0xFC, 0x01, 0x80, 0x65, 0x47, 0xD0, 0x28, 0x41, 0xA0, 0x80, 0xFE, 0xA1,
+	 0x16, 0x03, 0x09, 0x02, 0x10, 0x60, 0x14, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x10, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x1E, 0x00, 0x10, 0x60, 0x14, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x04, 0x64,
+	 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x15, 0x00, 0x28, 0x41, 0xFE, 0xA1, 0xFF, 0xFF, 0x09, 0x03,
+	 0x10, 0x60, 0x14, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x08, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x08, 0x00, 0x10, 0x60, 0x14, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xCF, 0xFE, 0x0F, 0x60, 0xF6, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xCF, 0xFE, 0x20, 0x40, 0x20, 0x2A, 0x58, 0x00, 0x26, 0x46, 0x3F, 0xF2, 0x00, 0xF4, 0x60, 0x43,
+	 0xF4, 0xA3, 0x00, 0x60, 0x1D, 0x61, 0x00, 0x60, 0x80, 0x65, 0x60, 0xFE, 0x81, 0xA1, 0x7F, 0xA1,
+	 0x02, 0x06, 0x00, 0xF4, 0x03, 0x61, 0xDD, 0x81, 0xA1, 0xD2, 0xCF, 0x83, 0xD4, 0x80, 0x2D, 0x03,
+	 0x17, 0x03, 0xCF, 0x83, 0x61, 0x44, 0x80, 0xA0, 0x28, 0x03, 0x02, 0x02, 0x00, 0xF4, 0x03, 0x61,
+	 0xDD, 0x81, 0xA1, 0xD2, 0xCF, 0x83, 0x81, 0xA1, 0x20, 0x03, 0x05, 0x07, 0x7F, 0xA1, 0xCC, 0x84,
+	 0xDD, 0x81, 0xE4, 0x03, 0xF7, 0x01, 0x00, 0xF4, 0x00, 0xB8, 0x04, 0x61, 0xE4, 0x03, 0xF2, 0x01,
+	 0x01, 0x60, 0xFF, 0x63, 0x46, 0x48, 0x41, 0x4A, 0xDD, 0x81, 0xA1, 0xD0, 0xDF, 0x83, 0xA3, 0xD9,
+	 0x64, 0x44, 0xDD, 0x81, 0xA1, 0xD0, 0xDF, 0x83, 0xA3, 0xD9, 0xCC, 0x84, 0x81, 0xA1, 0x05, 0x03,
+	 0x7F, 0xA1, 0xF7, 0x04, 0x00, 0xF4, 0x03, 0x61, 0xF4, 0x01, 0x20, 0xFE, 0x00, 0xBB, 0x02, 0x60,
+	 0x00, 0x63, 0x08, 0x24, 0x11, 0x00, 0xBD, 0xD3, 0x06, 0x65, 0xD4, 0x80, 0xBD, 0xD3, 0x0C, 0x02,
+	 0x60, 0x40, 0x60, 0x3A, 0x09, 0x00, 0x1D, 0x3B, 0x07, 0x00, 0xBD, 0xD3, 0xFF, 0xFF, 0xFF, 0xB5,
+	 0x00, 0x7E, 0x5C, 0xFB, 0x65, 0x44, 0x5B, 0xFB, 0x26, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60,
+	 0xF6, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x20, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x0F, 0x60, 0xF6, 0x62, 0xA2, 0xD1, 0x02, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x63, 0x97, 0xFD, 0x1A, 0x60, 0x72, 0x63, 0x00, 0x64,
+	 0xA3, 0xDB, 0x06, 0xA3, 0x10, 0x60, 0x50, 0x64, 0xBD, 0xDB, 0xBD, 0xDB, 0x06, 0x64, 0xA3, 0xDB,
+	 0x10, 0x60, 0x4E, 0x62, 0xE0, 0x60, 0x07, 0x64, 0xA2, 0xDB, 0xD2, 0xF1, 0x1A, 0x60, 0x76, 0x62,
+	 0xA2, 0xD9, 0x1A, 0x60, 0x7E, 0x63, 0x00, 0x64, 0xA3, 0xDB, 0x06, 0xA3, 0x10, 0x60, 0x54, 0x64,
+	 0xBD, 0xDB, 0xBD, 0xDB, 0x06, 0x64, 0xA3, 0xDB, 0x10, 0x60, 0x52, 0x62, 0xE0, 0x60, 0x11, 0x64,
+	 0xA2, 0xDB, 0x28, 0x60, 0x04, 0x62, 0xA2, 0xD1, 0x1A, 0x60, 0x82, 0x62, 0xA2, 0xD9, 0x00, 0x60,
+	 0x3A, 0x61, 0xAE, 0x60, 0x58, 0x4D, 0xC4, 0x78, 0xFF, 0xFF, 0x66, 0x44, 0x64, 0xFB, 0xA9, 0xF3,
+	 0x07, 0xFA, 0xBC, 0xF3, 0x19, 0xFA, 0xF8, 0x60, 0x80, 0x64, 0x0E, 0xFA, 0x00, 0x64, 0x3E, 0xFA,
+	 0x3F, 0xFA, 0x00, 0x60, 0x3A, 0x61, 0xAE, 0x60, 0x58, 0x4D, 0xC4, 0x78, 0xFF, 0xFF, 0x66, 0x44,
+	 0x65, 0xFB, 0xA9, 0xF3, 0x07, 0xFA, 0xBC, 0xF3, 0x19, 0xFA, 0x24, 0x60, 0x80, 0x64, 0x0E, 0xFA,
+	 0x00, 0x64, 0x3E, 0xFA, 0x3F, 0xFA, 0x10, 0x60, 0x14, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x5A, 0xDB,
+	 0x10, 0x60, 0x28, 0x62, 0xE0, 0x60, 0x77, 0x64, 0xA2, 0xDB, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x63,
+	 0x97, 0xFD, 0xBA, 0xFE, 0xFE, 0x60, 0xFF, 0x65, 0x20, 0x44, 0x24, 0x80, 0x84, 0xFD, 0x0F, 0x60,
+	 0xEA, 0x62, 0xA2, 0xD1, 0x04, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x0F, 0x60,
+	 0xF6, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x5A, 0xDB, 0x2F, 0x58, 0xFF, 0xFF, 0x28, 0x60, 0x04, 0x62,
+	 0xA2, 0xD1, 0x1A, 0x60, 0x82, 0x62, 0xA2, 0xD9, 0x27, 0x60, 0xFE, 0x62, 0xA2, 0xD3, 0xFF, 0xFF,
+	 0x0A, 0x1B, 0x00, 0x64, 0x84, 0xFB, 0xBA, 0xFE, 0x0F, 0x60, 0xF6, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0x5A, 0xDB, 0x2F, 0x58, 0xFF, 0xFF, 0xBA, 0xFE, 0x97, 0xF3, 0x00, 0x63, 0x84, 0xFD, 0x10, 0xBC,
+	 0x97, 0xFB, 0xFE, 0x60, 0xFF, 0x65, 0x20, 0x44, 0x24, 0x80, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1,
+	 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x00, 0x60, 0x64, 0x63, 0x1A, 0x60,
+	 0x42, 0x64, 0xA0, 0xDD, 0x0F, 0x60, 0xF6, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x0F, 0x60, 0xF8, 0x62,
+	 0x01, 0x60, 0x04, 0x64, 0xA2, 0xDB, 0xE0, 0x60, 0xC9, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x0F, 0x60, 0xF6, 0x62, 0xA2, 0xD1, 0x01, 0x60, 0x00, 0x64, 0xA0, 0x80, 0x9C, 0x84,
+	 0x03, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xA3, 0x01, 0x31, 0x40, 0x04, 0x2A, 0xE3, 0x01, 0x20, 0x40,
+	 0x52, 0x23, 0x12, 0x00, 0x0F, 0x60, 0xF6, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x10, 0x60, 0x14, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x0F, 0x60, 0xF8, 0x62, 0x81, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xE0, 0x60,
+	 0xC9, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0xDB, 0x01, 0x0F, 0x60, 0xF6, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0x01, 0x60, 0x00, 0x65, 0x20, 0x44, 0x34, 0x80, 0x65, 0xF5, 0xBC, 0xF1, 0x19, 0xF8, 0x81, 0xF1,
+	 0x2C, 0xF8, 0x32, 0xF8, 0x82, 0xF1, 0x2D, 0xF8, 0x33, 0xF8, 0x83, 0xF1, 0x2E, 0xF8, 0x34, 0xF8,
+	 0xEB, 0xF1, 0x2F, 0xF8, 0xEC, 0xF1, 0x30, 0xF8, 0xED, 0xF1, 0x31, 0xF8, 0x11, 0x60, 0x48, 0x64,
+	 0x2A, 0xFA, 0x00, 0x64, 0x2B, 0xFA, 0x23, 0xFA, 0x24, 0x60, 0x74, 0x62, 0x24, 0x60, 0x28, 0x64,
+	 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE,
+	 0x0F, 0x60, 0xF8, 0x62, 0x00, 0x60, 0x01, 0x64, 0xA2, 0xDB, 0xE1, 0x60, 0x23, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x65, 0xF5, 0x23, 0xF2, 0xFF, 0xFF, 0x01, 0x18, 0x7B, 0x01,
+	 0x10, 0x67, 0x84, 0xFB, 0x03, 0x64, 0x98, 0xFB, 0xFE, 0x60, 0xFF, 0x65, 0x20, 0x44, 0x24, 0x80,
+	 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x0F, 0x60, 0xF6, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x0F, 0x60, 0xF8, 0x62, 0x81, 0x60, 0x00, 0x64,
+	 0xA2, 0xDB, 0xE1, 0x60, 0x46, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x0D, 0x00, 0x0F, 0x60, 0xF6, 0x62,
+	 0xA2, 0xD1, 0x01, 0x60, 0x00, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x05, 0x03, 0xA0, 0x84, 0xA2, 0xDB,
+	 0xE0, 0x60, 0x77, 0x78, 0xFF, 0xFF, 0x46, 0x60, 0x00, 0x65, 0x20, 0x41, 0x8E, 0xF3, 0xA5, 0x80,
+	 0x01, 0xB0, 0x01, 0x02, 0x06, 0x00, 0x0F, 0x60, 0xF6, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x1A, 0x60, 0x42, 0x65, 0xA5, 0xD3, 0x01, 0x63, 0x8C, 0xFD, 0x27, 0x1B, 0x00, 0x60,
+	 0x64, 0x64, 0xA5, 0xDB, 0x65, 0xF5, 0xBC, 0xF1, 0x19, 0xF8, 0x81, 0xF1, 0x2C, 0xF8, 0x32, 0xF8,
+	 0x82, 0xF1, 0x2D, 0xF8, 0x33, 0xF8, 0x83, 0xF1, 0x2E, 0xF8, 0x34, 0xF8, 0xEB, 0xF1, 0x2F, 0xF8,
+	 0xEC, 0xF1, 0x30, 0xF8, 0xED, 0xF1, 0x31, 0xF8, 0x11, 0x60, 0x48, 0x64, 0x2A, 0xFA, 0x00, 0x64,
+	 0x2B, 0xFA, 0x23, 0xFA, 0x24, 0x60, 0x74, 0x62, 0x24, 0x60, 0x28, 0x64, 0xA2, 0xDB, 0x66, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x06, 0x00, 0x97, 0xF3, 0x32, 0x40,
+	 0x02, 0x26, 0x02, 0x00, 0x40, 0x2A, 0xDA, 0xFE, 0xC1, 0xFE, 0x0F, 0x60, 0xF6, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0x0F, 0x60, 0xF8, 0x62, 0x01, 0x60, 0x82, 0x64, 0xA2, 0xDB, 0xE1, 0x60, 0xA4, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xF6, 0x62, 0xA2, 0xD1, 0x01, 0x60,
+	 0x00, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x05, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xE0, 0x60, 0x77, 0x78,
+	 0xFF, 0xFF, 0x00, 0x60, 0x02, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x06, 0x03, 0xA0, 0x84, 0xA2, 0xDB,
+	 0xBA, 0xFE, 0xE3, 0x60, 0xC8, 0x78, 0xFF, 0xFF, 0x02, 0x64, 0x8C, 0xFB, 0x01, 0x60, 0x00, 0x65,
+	 0x20, 0x44, 0x34, 0x80, 0xBA, 0xFE, 0xC1, 0xFE, 0x0F, 0x60, 0xF6, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0x10, 0x60, 0x14, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x0F, 0x60, 0xF8, 0x62, 0x01, 0x60, 0x46, 0x64,
+	 0xA2, 0xDB, 0xE1, 0x60, 0xD7, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60,
+	 0xF6, 0x62, 0xA2, 0xD1, 0x01, 0x60, 0x00, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x05, 0x03, 0xA0, 0x84,
+	 0xA2, 0xDB, 0xE0, 0x60, 0x77, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x04, 0x64, 0xA0, 0x80, 0x9C, 0x84,
+	 0x3C, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x10, 0x60, 0x14, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x08, 0x64,
+	 0xA0, 0x80, 0x9C, 0x84, 0x03, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x34, 0x01, 0x00, 0x60, 0x02, 0x64,
+	 0xA0, 0x80, 0x9C, 0x84, 0x0C, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x28, 0x60, 0x00, 0x62, 0xA2, 0xD1,
+	 0x97, 0xF3, 0x00, 0x61, 0xD1, 0x80, 0xF7, 0xB4, 0xF0, 0x03, 0x97, 0xFB, 0x35, 0x00, 0x00, 0x60,
+	 0x10, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x0F, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x28, 0x60, 0x00, 0x62,
+	 0xA2, 0xD1, 0x97, 0xF3, 0x00, 0x61, 0xD1, 0x80, 0x08, 0xBC, 0x03, 0x02, 0xE2, 0x60, 0xE8, 0x78,
+	 0xFF, 0xFF, 0x97, 0xFB, 0x21, 0x00, 0x00, 0x60, 0x04, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x05, 0x03,
+	 0xA0, 0x84, 0xA2, 0xDB, 0xE2, 0x60, 0xE8, 0x78, 0xFF, 0xFF, 0x0F, 0x60, 0xF6, 0x62, 0xA2, 0xD1,
+	 0x00, 0x60, 0x40, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x03, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xC5, 0x01,
+	 0x00, 0x60, 0x02, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x05, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xE3, 0x60,
+	 0xC8, 0x78, 0xFF, 0xFF, 0x2F, 0x58, 0xFF, 0xFF, 0x02, 0x63, 0x97, 0xF3, 0x8C, 0xFD, 0x01, 0xBC,
+	 0xC1, 0xFE, 0x97, 0xFB, 0xD2, 0xF1, 0x1A, 0x60, 0x76, 0x62, 0xA2, 0xD9, 0x0F, 0x60, 0xF6, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x10, 0x60, 0x14, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x0F, 0x60, 0xF8, 0x62,
+	 0x01, 0x60, 0x34, 0x64, 0xA2, 0xDB, 0xE2, 0x60, 0x62, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x24, 0x60,
+	 0xAA, 0x62, 0x1A, 0x60, 0x72, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xF6, 0x62, 0xA2, 0xD1, 0x01, 0x60, 0x00, 0x64, 0xA0, 0x80,
+	 0x9C, 0x84, 0x0E, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x72, 0x64,
+	 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0xE0, 0x60, 0x77, 0x78, 0xFF, 0xFF,
+	 0x00, 0x60, 0x10, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x17, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x97, 0xF3,
+	 0xFF, 0xFF, 0x60, 0x40, 0x04, 0x2A, 0x01, 0x00, 0xD2, 0x01, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60,
+	 0x72, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x97, 0xF3, 0xFF, 0xFF,
+	 0x60, 0x40, 0x08, 0x2A, 0x4D, 0x00, 0x54, 0x00, 0x10, 0x60, 0x14, 0x62, 0xA2, 0xD1, 0x00, 0x60,
+	 0x10, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x08, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x97, 0xF3, 0xFF, 0xFF,
+	 0x08, 0xBC, 0x97, 0xFB, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x60, 0x02, 0x64, 0xA0, 0x80, 0x9C, 0x84,
+	 0x03, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xAB, 0x01, 0x00, 0x60, 0x04, 0x64, 0xA0, 0x80, 0x9C, 0x84,
+	 0x0C, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x72, 0x64, 0xA2, 0xDB,
+	 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x2B, 0x00, 0x00, 0x60, 0x08, 0x64, 0xA0, 0x80,
+	 0x9C, 0x84, 0x0C, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x72, 0x64,
+	 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x13, 0x00, 0x0F, 0x60, 0xF6, 0x62,
+	 0xA2, 0xD1, 0x00, 0x60, 0x20, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x08, 0x03, 0xA0, 0x84, 0xA2, 0xDB,
+	 0x97, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x08, 0x2A, 0x04, 0x00, 0x0A, 0x00, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x00, 0x00, 0x97, 0xF3, 0xFF, 0xFF, 0xFE, 0xB4, 0x97, 0xFB, 0xE1, 0x60, 0x2A, 0x78, 0xFF, 0xFF,
+	 0x27, 0x60, 0xFE, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x01, 0xA8, 0xFF, 0xFF, 0x03, 0x02, 0xE3, 0x60,
+	 0xD1, 0x78, 0xFF, 0xFF, 0x97, 0xF3, 0x01, 0x63, 0x8C, 0xFD, 0x21, 0xBC, 0x97, 0xFB, 0x64, 0xF5,
+	 0x81, 0xF1, 0x2C, 0xF8, 0x82, 0xF1, 0x2D, 0xF8, 0x83, 0xF1, 0x2E, 0xF8, 0x85, 0xF1, 0xC0, 0x67,
+	 0xB0, 0x84, 0x2B, 0xFA, 0xBC, 0xF1, 0x19, 0xF8, 0xEB, 0xF1, 0x2F, 0xF8, 0xEC, 0xF1, 0x30, 0xF8,
+	 0xED, 0xF1, 0x31, 0xF8, 0x10, 0x60, 0xA4, 0x64, 0x2A, 0xFA, 0x24, 0x60, 0x74, 0x62, 0x24, 0x60,
+	 0x28, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0xC1, 0xFE, 0x1A, 0x60, 0x76, 0x62, 0x00, 0x60, 0x50, 0x64, 0xA2, 0xDB, 0x24, 0x60, 0xAA, 0x62,
+	 0x1A, 0x60, 0x72, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x0F, 0x60,
+	 0xF6, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x10, 0x60, 0x14, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x0F, 0x60,
+	 0xF8, 0x62, 0x01, 0x60, 0x2C, 0x64, 0xA2, 0xDB, 0xE3, 0x60, 0x3A, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xF6, 0x62, 0xA2, 0xD1, 0x01, 0x60, 0x00, 0x64, 0xA0, 0x80,
+	 0x9C, 0x84, 0x0E, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x72, 0x64,
+	 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0xE0, 0x60, 0x77, 0x78, 0xFF, 0xFF,
+	 0x10, 0x60, 0x14, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x04, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x03, 0x03,
+	 0xA0, 0x84, 0xA2, 0xDB, 0x8D, 0x01, 0x0F, 0x60, 0xF6, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x08, 0x64,
+	 0xA0, 0x80, 0x9C, 0x84, 0x08, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x97, 0xF3, 0xFF, 0xFF, 0x02, 0xB0,
+	 0xFF, 0xFF, 0x4E, 0x03, 0x7D, 0x01, 0x00, 0x60, 0x08, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x03, 0x03,
+	 0xA0, 0x84, 0xA2, 0xDB, 0x45, 0x00, 0x00, 0x60, 0x02, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x16, 0x03,
+	 0xA0, 0x84, 0xA2, 0xDB, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x72, 0x64, 0xA2, 0xDB, 0x03, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x28, 0x60, 0x00, 0x62, 0xA2, 0xD3, 0x97, 0xF3, 0x00, 0xA8,
+	 0xF7, 0xB4, 0x2E, 0x03, 0x97, 0xFB, 0xE2, 0x60, 0x3C, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x10, 0x64,
+	 0xA0, 0x80, 0x9C, 0x84, 0x17, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60,
+	 0x72, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x28, 0x60, 0x00, 0x62,
+	 0xA2, 0xD3, 0x97, 0xF3, 0x00, 0xA8, 0x08, 0xBC, 0x01, 0x02, 0x42, 0x01, 0x97, 0xFB, 0xE2, 0x60,
+	 0x3C, 0x78, 0xFF, 0xFF, 0x0F, 0x60, 0xF6, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x20, 0x64, 0xA0, 0x80,
+	 0x9C, 0x84, 0x03, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x02, 0x00, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x00,
+	 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x72, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x04, 0xFF, 0x97, 0xF3, 0xFF, 0xFF, 0xFE, 0xB4, 0x97, 0xFB, 0xE1, 0x60, 0x2A, 0x78, 0xFF, 0xFF,
+	 0x97, 0xF3, 0x01, 0x63, 0x8C, 0xFD, 0x01, 0xBC, 0x97, 0xFB, 0x00, 0x64, 0x84, 0xFB, 0xC1, 0xFE,
+	 0x29, 0x00, 0x97, 0xF3, 0x01, 0x63, 0x8C, 0xFD, 0x01, 0xBC, 0x97, 0xFB, 0x00, 0x64, 0x84, 0xFB,
+	 0x64, 0xF5, 0x81, 0xF1, 0x2C, 0xF8, 0x82, 0xF1, 0x2D, 0xF8, 0x83, 0xF1, 0x2E, 0xF8, 0x85, 0xF1,
+	 0xC0, 0x67, 0xB0, 0x84, 0x2B, 0xFA, 0xBC, 0xF1, 0x19, 0xF8, 0xEB, 0xF1, 0x2F, 0xF8, 0xEC, 0xF1,
+	 0x30, 0xF8, 0xED, 0xF1, 0x31, 0xF8, 0x00, 0x60, 0xA4, 0x64, 0x2A, 0xFA, 0x24, 0x60, 0x74, 0x62,
+	 0x24, 0x60, 0x28, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0xC1, 0xFE, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x7E, 0x64, 0xA2, 0xDB, 0x02, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x0F, 0x60, 0xF6, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x10, 0x60,
+	 0x14, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x0F, 0x60, 0xF8, 0x62, 0x03, 0x60, 0x0E, 0x64, 0xA2, 0xDB,
+	 0xE4, 0x60, 0x16, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xF6, 0x62,
+	 0xA2, 0xD1, 0x01, 0x60, 0x00, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x0E, 0x03, 0xA0, 0x84, 0xA2, 0xDB,
+	 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x7E, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x04, 0xFF, 0xE0, 0x60, 0x77, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x0A, 0x64, 0xA0, 0x80, 0x9C, 0x84,
+	 0x03, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xC6, 0x01, 0x00, 0x60, 0x04, 0x64, 0xA0, 0x80, 0x9C, 0x84,
+	 0x15, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x10, 0x60, 0x14, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x04, 0x64,
+	 0xA0, 0x80, 0x9C, 0x84, 0x03, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x8B, 0x01, 0x00, 0x60, 0x12, 0x64,
+	 0xA0, 0x80, 0x9C, 0x84, 0x03, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xAC, 0x01, 0x0F, 0x60, 0xF6, 0x62,
+	 0xA2, 0xD1, 0x02, 0x60, 0x00, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0xAD, 0x03, 0xA0, 0x84, 0xA2, 0xDB,
+	 0x10, 0x67, 0x84, 0xFB, 0x0F, 0x60, 0xF6, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x10, 0x60, 0x14, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x65, 0xF5, 0xBC, 0xF1, 0x19, 0xF8, 0x81, 0xF1, 0x2C, 0xF8, 0x32, 0xF8,
+	 0x82, 0xF1, 0x2D, 0xF8, 0x33, 0xF8, 0x83, 0xF1, 0x2E, 0xF8, 0x34, 0xF8, 0xEB, 0xF1, 0x2F, 0xF8,
+	 0xEC, 0xF1, 0x30, 0xF8, 0xED, 0xF1, 0x31, 0xF8, 0x11, 0x60, 0x48, 0x64, 0x2A, 0xFA, 0x00, 0x64,
+	 0x2B, 0xFA, 0x23, 0xFA, 0x24, 0x60, 0x74, 0x62, 0x24, 0x60, 0x28, 0x64, 0xA2, 0xDB, 0x66, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x97, 0xF3, 0xC1, 0xFE, 0xFE, 0xB4,
+	 0x97, 0xFB, 0x0F, 0x60, 0xF8, 0x62, 0x00, 0x60, 0x03, 0x64, 0xA2, 0xDB, 0xE4, 0x60, 0x94, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xF6, 0x62, 0xA2, 0xD1, 0x00, 0x60,
+	 0x02, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x03, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x29, 0x01, 0x65, 0xF5,
+	 0x23, 0xF2, 0x98, 0xF3, 0x04, 0x18, 0xCC, 0x84, 0x98, 0xFB, 0x01, 0x03, 0x21, 0x01, 0xE1, 0x60,
+	 0x2A, 0x78, 0xFF, 0xFF, 0x27, 0x60, 0xFE, 0x62, 0xA2, 0xD3, 0x84, 0xF1, 0x02, 0xA8, 0x2A, 0xF2,
+	 0x03, 0x02, 0xB0, 0x84, 0x2A, 0xFA, 0x08, 0x00, 0x0F, 0x60, 0xF6, 0x62, 0xA2, 0xD1, 0x00, 0x60,
+	 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x24, 0x60, 0x74, 0x62, 0x24, 0x60, 0x22, 0x64,
+	 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE,
+	 0x24, 0x60, 0x34, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0xDB, 0x02, 0xBF, 0x60,
+	 0xE7, 0x78, 0xFF, 0xFF, 0x0F, 0x60, 0xFC, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x1A, 0x60, 0xAE, 0x63, 0x00, 0x64, 0xA3, 0xDB,
+	 0x06, 0xA3, 0x10, 0x60, 0x5C, 0x64, 0xBD, 0xDB, 0xBD, 0xDB, 0x06, 0x64, 0xA3, 0xDB, 0x10, 0x60,
+	 0x5A, 0x62, 0xE4, 0x60, 0xD2, 0x64, 0xA2, 0xDB, 0x1F, 0x60, 0x5C, 0x62, 0xA2, 0xD1, 0x1A, 0x60,
+	 0xB2, 0x62, 0xA2, 0xD9, 0x10, 0x60, 0x2A, 0x62, 0xE4, 0x60, 0xF9, 0x64, 0xA2, 0xDB, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x2F, 0x58, 0xFF, 0xFF, 0x1F, 0x60, 0x80, 0x65, 0xA5, 0xD3, 0xFF, 0xFF, 0x02, 0xBC,
+	 0xF3, 0xB4, 0x01, 0xB0, 0xA5, 0xDB, 0x0C, 0x02, 0x12, 0x60, 0x26, 0x61, 0x00, 0x64, 0x1A, 0x63,
+	 0x59, 0xDB, 0xFE, 0x1F, 0x1F, 0x60, 0x5C, 0x61, 0x0A, 0x64, 0x1A, 0x63, 0x59, 0xDB, 0xFE, 0x1F,
+	 0x7F, 0xF3, 0x7E, 0xFB, 0x01, 0x64, 0x7F, 0xFB, 0x01, 0x61, 0xCC, 0x84, 0xFF, 0xFF, 0x02, 0x03,
+	 0xE1, 0x81, 0xFB, 0x01, 0xBA, 0xF3, 0x61, 0x45, 0xA4, 0x80, 0xFF, 0xFF, 0x69, 0x03, 0x0F, 0x60,
+	 0xFC, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE, 0x0B, 0x04, 0x0F, 0x60, 0xFE, 0x62, 0x40, 0x60,
+	 0x00, 0x64, 0xA2, 0xDB, 0xE5, 0x60, 0x1F, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x7F, 0xF1, 0x24, 0x60, 0x9A, 0x62, 0xA2, 0xD9, 0x1E, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF,
+	 0x0F, 0x60, 0xFE, 0x62, 0x20, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xE5, 0x60, 0x43, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0xBE, 0xFE, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1, 0x40, 0x60,
+	 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x0F, 0x60, 0xFC, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0x0F, 0x60, 0xFE, 0x62, 0x00, 0x60, 0x1A, 0x64, 0xA2, 0xDB, 0xE5, 0x60, 0x64, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0xAE, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB,
+	 0xFF, 0xFF, 0x04, 0xFF, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xFC, 0x62, 0xA2, 0xD1, 0x00, 0x60,
+	 0x08, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x0C, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x24, 0x60, 0xAA, 0x62,
+	 0x1A, 0x60, 0xAE, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x26, 0x00,
+	 0x00, 0x60, 0x10, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x0B, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x24, 0x60,
+	 0xAA, 0x62, 0x1A, 0x60, 0xAE, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF,
+	 0x12, 0x60, 0x26, 0x65, 0x7F, 0xF3, 0xFF, 0xFF, 0x04, 0xA4, 0xF2, 0xA0, 0xFF, 0xFF, 0x01, 0x06,
+	 0xF1, 0xA4, 0x01, 0x36, 0x0B, 0x00, 0x00, 0x36, 0x04, 0xA4, 0x60, 0x41, 0xE0, 0x84, 0xC4, 0x84,
+	 0xA0, 0xD3, 0xFF, 0xFF, 0x00, 0xB8, 0x61, 0x44, 0xEF, 0x02, 0x75, 0x01, 0x1F, 0x60, 0x80, 0x65,
+	 0xA5, 0xD3, 0x7E, 0xF1, 0xFC, 0xB4, 0xA5, 0xDB, 0x7F, 0xF9, 0x0F, 0x60, 0xFC, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0xDE, 0xFE, 0x0B, 0x04, 0x0F, 0x60, 0xFE, 0x62, 0x40, 0x60, 0x00, 0x64, 0xA2, 0xDB,
+	 0xE5, 0x60, 0xA5, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x7F, 0xF1, 0x24, 0x60,
+	 0x9A, 0x62, 0xA2, 0xD9, 0x1E, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x0F, 0x60, 0xFE, 0x62,
+	 0x20, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xE5, 0x60, 0xC9, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0xBE, 0xFE, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x0F, 0x60, 0xFC, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x5A, 0xDB, 0x0F, 0x60,
+	 0xD0, 0x62, 0xA2, 0xD1, 0x10, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0xE6, 0x60, 0xE9, 0x78, 0xFF, 0xFF, 0xE6, 0x60, 0xED, 0x78, 0xFF, 0xFF, 0x1F, 0x60,
+	 0x80, 0x63, 0xA3, 0xD3, 0x26, 0x46, 0x02, 0xB0, 0x3F, 0xF2, 0xF6, 0x03, 0x02, 0x60, 0x00, 0x63,
+	 0x01, 0x60, 0x00, 0x65, 0xD4, 0x80, 0x00, 0xF4, 0x02, 0x24, 0x65, 0x44, 0x12, 0x65, 0x60, 0x41,
+	 0xA5, 0xD0, 0xDA, 0x85, 0x80, 0x3A, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0x64, 0x44, 0x00, 0x7F,
+	 0xCD, 0x81, 0xBD, 0xDB, 0x05, 0x03, 0x64, 0x47, 0x00, 0x7F, 0xCD, 0x81, 0xBD, 0xDB, 0xF0, 0x02,
+	 0x02, 0x60, 0x14, 0x63, 0xA3, 0xD3, 0xFF, 0xFF, 0x01, 0xB4, 0xFF, 0xFF, 0x37, 0x02, 0x29, 0x60,
+	 0xA4, 0x64, 0xA0, 0xD1, 0x1F, 0x60, 0x0E, 0x63, 0x31, 0x18, 0x64, 0x41, 0x44, 0x4B, 0x29, 0x60,
+	 0xA6, 0x65, 0xA5, 0xD1, 0xDA, 0x85, 0x64, 0x44, 0x00, 0x7F, 0xCD, 0x81, 0xBD, 0xDB, 0x05, 0x03,
+	 0x64, 0x47, 0x00, 0x7F, 0xCD, 0x81, 0xBD, 0xDB, 0xF4, 0x02, 0x02, 0x60, 0x1A, 0x61, 0xA1, 0xD3,
+	 0x2B, 0x45, 0x60, 0x40, 0x00, 0x36, 0x1A, 0x00, 0x01, 0x36, 0x18, 0x00, 0xD4, 0x80, 0x65, 0x43,
+	 0xB0, 0x02, 0x1F, 0x60, 0x0C, 0x64, 0xE3, 0x83, 0xFE, 0xA3, 0x59, 0xD1, 0x58, 0xD3, 0x40, 0x4B,
+	 0xD0, 0x80, 0x2B, 0x44, 0x02, 0x02, 0xF9, 0x1F, 0x09, 0x00, 0x02, 0x60, 0x1A, 0x61, 0x65, 0x43,
+	 0xE3, 0x83, 0xFE, 0xA3, 0x59, 0xD3, 0xFF, 0xFF, 0x9C, 0x1B, 0xFC, 0x1F, 0x26, 0x46, 0x3F, 0xF0,
+	 0x01, 0x60, 0x00, 0x64, 0xD0, 0x80, 0x64, 0x41, 0x01, 0x05, 0x60, 0x41, 0xF4, 0xA1, 0x02, 0x60,
+	 0x18, 0x63, 0xBD, 0xD3, 0xBD, 0xD1, 0xFD, 0xA0, 0xF9, 0xA0, 0x08, 0x03, 0x35, 0x03, 0xFE, 0xA1,
+	 0x64, 0x42, 0xE2, 0x85, 0xD1, 0x81, 0xC7, 0x83, 0x84, 0x06, 0xF3, 0x01, 0x12, 0x60, 0x26, 0x65,
+	 0xBD, 0xD3, 0xFD, 0xA1, 0xE0, 0x84, 0xC4, 0x85, 0x05, 0x64, 0xA5, 0xDB, 0x1F, 0x60, 0x80, 0x65,
+	 0xA5, 0xD3, 0x41, 0x48, 0x04, 0xBC, 0xA5, 0xDB, 0x12, 0x60, 0x28, 0x65, 0x12, 0x60, 0x44, 0x61,
+	 0x49, 0xD3, 0xD6, 0x80, 0x00, 0xB8, 0x0E, 0x03, 0xFB, 0x03, 0x62, 0x45, 0x12, 0x60, 0x26, 0x61,
+	 0x59, 0xD3, 0xD6, 0x80, 0x00, 0xB8, 0x06, 0x03, 0xFB, 0x03, 0x05, 0x64, 0xA2, 0xDB, 0xD6, 0x80,
+	 0x02, 0xA2, 0xFC, 0x02, 0x0F, 0x60, 0xFC, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x10, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x28, 0x41, 0xC5, 0x01, 0x63, 0x45, 0x04, 0x60, 0x00, 0x63, 0xD7, 0x83,
+	 0xEB, 0x83, 0xD3, 0x80, 0x65, 0x43, 0x01, 0x05, 0x54, 0x00, 0xFE, 0xA3, 0x43, 0x4B, 0xA3, 0xD3,
+	 0x63, 0x41, 0x60, 0x43, 0x1B, 0x60, 0xC6, 0x64, 0xA0, 0xDD, 0xE3, 0x83, 0xFE, 0xA3, 0x59, 0xD1,
+	 0x58, 0xD9, 0xFD, 0x1F, 0x00, 0x63, 0x58, 0xDD, 0x2B, 0x43, 0xBD, 0xD1, 0x1F, 0x60, 0x78, 0x64,
+	 0x64, 0x41, 0xBD, 0xD1, 0x58, 0xD9, 0xBD, 0xD1, 0xFC, 0xA1, 0x41, 0x4B, 0x58, 0xD9, 0xBD, 0xD1,
+	 0xA0, 0xD9, 0x12, 0x60, 0x26, 0x61, 0x12, 0x60, 0x42, 0x65, 0x00, 0x64, 0xD5, 0x80, 0x59, 0xDB,
+	 0xFD, 0x02, 0x12, 0x60, 0x24, 0x65, 0xBD, 0xD3, 0xA3, 0xD1, 0xE0, 0x84, 0xC4, 0x82, 0x12, 0x60,
+	 0x44, 0x65, 0x05, 0x64, 0x64, 0x41, 0x5A, 0xDB, 0xD6, 0x80, 0xCD, 0x81, 0x22, 0x03, 0xFB, 0x02,
+	 0x1F, 0x60, 0x5A, 0x61, 0x4B, 0xD1, 0x04, 0xA3, 0xBD, 0xD3, 0xFF, 0xFF, 0xF6, 0xA0, 0xC1, 0x82,
+	 0x05, 0x05, 0x64, 0x41, 0x5A, 0xDB, 0xCD, 0x81, 0xFF, 0xFF, 0xFC, 0x02, 0x2B, 0x41, 0xFD, 0xA1,
+	 0x41, 0x4B, 0xDF, 0x07, 0x0F, 0x60, 0xFC, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x08, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x1F, 0x60, 0x80, 0x65, 0xA5, 0xD3, 0xFF, 0xFF, 0x08, 0xBC, 0xA5, 0xDB,
+	 0xFF, 0xFF, 0x20, 0xFE, 0x26, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x20, 0xFE, 0x9A, 0xFF, 0x5C, 0x61,
+	 0x3F, 0xF2, 0xFF, 0xFF, 0x83, 0xA0, 0xFF, 0xFF, 0x04, 0x28, 0x39, 0x00, 0xF4, 0xA4, 0x60, 0x43,
+	 0x00, 0xF4, 0x1E, 0x62, 0x60, 0xFE, 0xA2, 0xD2, 0xFF, 0xFF, 0x60, 0x40, 0x85, 0x36, 0x10, 0x00,
+	 0xDE, 0x82, 0xA2, 0xD2, 0xFF, 0xFF, 0x20, 0xFE, 0xFF, 0xB4, 0x02, 0xA4, 0x53, 0x93, 0x51, 0x91,
+	 0x05, 0x0E, 0xFF, 0xA4, 0x42, 0x92, 0x63, 0x40, 0x61, 0x40, 0xEC, 0x1C, 0x98, 0xFF, 0xD9, 0x01,
+	 0x20, 0xFE, 0x05, 0x64, 0x00, 0x7C, 0x42, 0x92, 0x60, 0xFE, 0xDE, 0x82, 0xA2, 0xD2, 0xDE, 0x82,
+	 0xA2, 0xD0, 0xFF, 0xFF, 0x20, 0xFE, 0x64, 0x5F, 0x60, 0x43, 0x60, 0xFE, 0xDE, 0x82, 0xA2, 0xD2,
+	 0xDE, 0x82, 0xA2, 0xD0, 0xFF, 0xFF, 0x20, 0xFE, 0x64, 0x5F, 0x98, 0xFF, 0x01, 0xA3, 0x01, 0xA4,
+	 0x2D, 0x60, 0x5A, 0x62, 0xA2, 0xDD, 0x2D, 0x60, 0x5E, 0x62, 0xA2, 0xDB, 0xBA, 0x01, 0x98, 0xFF,
+	 0xB8, 0x01, 0x00, 0x60, 0xA0, 0x61, 0xAE, 0x60, 0x58, 0x4D, 0xC4, 0x78, 0xFF, 0xFF, 0x66, 0x44,
+	 0x5D, 0xFB, 0x04, 0x64, 0x03, 0xFA, 0x80, 0x64, 0x2A, 0xFA, 0xCC, 0xF1, 0x19, 0xF8, 0x00, 0x64,
+	 0x3E, 0xFA, 0x00, 0x60, 0x80, 0x64, 0x0E, 0xFA, 0xA9, 0xF1, 0x07, 0xF8, 0x67, 0x44, 0x2C, 0xFA,
+	 0x2D, 0xFA, 0x2E, 0xFA, 0x10, 0x60, 0x1C, 0x62, 0xE8, 0x60, 0xDF, 0x64, 0xA2, 0xDB, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x5D, 0xF5, 0xEB, 0xF1, 0x2F, 0xF8, 0xEC, 0xF1, 0x30, 0xF8, 0xED, 0xF1, 0x31, 0xF8,
+	 0x81, 0xF1, 0x32, 0xF8, 0x82, 0xF1, 0x33, 0xF8, 0x83, 0xF1, 0x34, 0xF8, 0x28, 0x60, 0x2C, 0x62,
+	 0xA2, 0xD1, 0x02, 0x64, 0x64, 0x40, 0xFE, 0x26, 0x10, 0xBC, 0x32, 0x40, 0x08, 0x26, 0x10, 0xBC,
+	 0x2F, 0x60, 0x44, 0x62, 0xA2, 0xDB, 0x28, 0x60, 0x2A, 0x62, 0xA2, 0xD1, 0x2D, 0x60, 0x7A, 0x64,
+	 0x02, 0x18, 0x27, 0x60, 0xDA, 0x64, 0x2E, 0x60, 0xAE, 0x62, 0xA2, 0xDB, 0x2E, 0x60, 0xCA, 0x62,
+	 0xA2, 0xDB, 0x2D, 0x60, 0xA6, 0x61, 0x28, 0x60, 0xCC, 0x62, 0xA2, 0xD3, 0x2E, 0x60, 0x96, 0x65,
+	 0xFE, 0xA4, 0xE0, 0x84, 0x02, 0x05, 0x67, 0x44, 0x99, 0x00, 0xE0, 0x84, 0xC4, 0x85, 0x2D, 0x60,
+	 0xCC, 0x62, 0xA2, 0xD3, 0xA5, 0xD1, 0xDA, 0x85, 0x2D, 0x60, 0xC4, 0x62, 0xA0, 0x83, 0xA2, 0xDD,
+	 0xA5, 0xD1, 0x2D, 0x60, 0xC2, 0x62, 0xA0, 0x83, 0xA2, 0xDD, 0x2D, 0x60, 0xA0, 0x61, 0xDD, 0x60,
+	 0x06, 0x64, 0xA1, 0xDB, 0x06, 0xA1, 0x2D, 0x60, 0xCA, 0x62, 0xA2, 0xD3, 0x2D, 0x60, 0xC2, 0x62,
+	 0x60, 0x40, 0xFD, 0xA0, 0xA2, 0xD3, 0x74, 0x03, 0x50, 0x60, 0x00, 0x7C, 0x60, 0x40, 0x02, 0x2A,
+	 0x03, 0x00, 0x01, 0x60, 0xF2, 0x63, 0x0E, 0x00, 0x04, 0x2A, 0x03, 0x00, 0x02, 0x60, 0xF2, 0x63,
+	 0x09, 0x00, 0x10, 0x2A, 0x03, 0x00, 0x04, 0x60, 0xF2, 0x63, 0x04, 0x00, 0x20, 0x2A, 0x04, 0x00,
+	 0x05, 0x60, 0xF2, 0x63, 0x59, 0xD9, 0x59, 0xDD, 0x2D, 0x60, 0xCA, 0x62, 0xA2, 0xD3, 0x2D, 0x60,
+	 0xC4, 0x62, 0xFE, 0xA0, 0xA2, 0xD3, 0x54, 0x03, 0x00, 0x60, 0x00, 0x63, 0x59, 0xDD, 0x61, 0x45,
+	 0x60, 0x40, 0x01, 0x2A, 0x04, 0x00, 0x00, 0x60, 0xF2, 0x63, 0x59, 0xD9, 0x59, 0xDD, 0x60, 0x40,
+	 0x02, 0x2A, 0x04, 0x00, 0x01, 0x60, 0xF2, 0x63, 0x59, 0xD9, 0x59, 0xDD, 0x60, 0x40, 0x04, 0x2A,
+	 0x04, 0x00, 0x02, 0x60, 0xF2, 0x63, 0x59, 0xD9, 0x59, 0xDD, 0x60, 0x40, 0x10, 0x2A, 0x04, 0x00,
+	 0x04, 0x60, 0xF2, 0x63, 0x59, 0xD9, 0x59, 0xDD, 0x60, 0x40, 0x20, 0x2A, 0x04, 0x00, 0x05, 0x60,
+	 0xF2, 0x63, 0x59, 0xD9, 0x59, 0xDD, 0xD5, 0x83, 0xEB, 0x83, 0xEB, 0x83, 0xA5, 0xDD, 0x2D, 0x60,
+	 0xCA, 0x62, 0xA2, 0xD3, 0x2D, 0x60, 0xC6, 0x62, 0xFF, 0xA0, 0xA2, 0xD3, 0x21, 0x03, 0x00, 0x60,
+	 0x00, 0x63, 0x59, 0xDD, 0x61, 0x45, 0x60, 0x40, 0x01, 0x2A, 0x04, 0x00, 0x00, 0x60, 0xF2, 0x63,
+	 0x59, 0xD9, 0x59, 0xDD, 0x60, 0x40, 0x02, 0x2A, 0x04, 0x00, 0x01, 0x60, 0xF2, 0x63, 0x59, 0xD9,
+	 0x59, 0xDD, 0x60, 0x40, 0x04, 0x2A, 0x04, 0x00, 0x02, 0x60, 0xF2, 0x63, 0x59, 0xD9, 0x59, 0xDD,
+	 0xD5, 0x83, 0xEB, 0x83, 0xEB, 0x83, 0xA5, 0xDD, 0x2D, 0x60, 0xC8, 0x62, 0xA2, 0xD1, 0x59, 0xD9,
+	 0x2D, 0x60, 0xA0, 0x65, 0xD5, 0x84, 0xDD, 0x7F, 0xA5, 0xDB, 0x65, 0x44, 0x2E, 0x60, 0xB8, 0x62,
+	 0xA2, 0xDB, 0x2E, 0x60, 0xD4, 0x62, 0xA2, 0xDB, 0x0F, 0x60, 0xD4, 0x62, 0x00, 0x60, 0x04, 0x64,
+	 0xA2, 0xDB, 0xE8, 0x60, 0x2F, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60,
+	 0xD2, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x7F, 0xF1, 0x2F, 0x60, 0x0E, 0x62, 0xA2, 0xD9, 0x2E, 0x60,
+	 0xB6, 0x65, 0xE9, 0x60, 0x58, 0x4D, 0x32, 0x78, 0xFF, 0xFF, 0x5D, 0xF5, 0x00, 0xF4, 0x80, 0xF1,
+	 0x06, 0xF8, 0x2F, 0x60, 0x44, 0x62, 0xA2, 0xD3, 0x07, 0xFA, 0x2E, 0x60, 0xAE, 0x64, 0x40, 0x48,
+	 0x10, 0x61, 0x00, 0x60, 0x00, 0x64, 0xE8, 0x60, 0x58, 0x4D, 0xE8, 0x78, 0xFF, 0xFF, 0x5D, 0xF5,
+	 0x3F, 0xFC, 0xDB, 0xFE, 0x24, 0x60, 0x74, 0x62, 0x24, 0x60, 0x28, 0x64, 0xA2, 0xDB, 0x66, 0x44,
+	 0x5A, 0xDB, 0x04, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0xDC, 0xF3, 0x9B, 0xFE, 0xFD, 0xA0, 0x25, 0x04, 0x24, 0x02, 0x04, 0x64, 0x03, 0xFA, 0x00, 0xF4,
+	 0x09, 0xF2, 0xFF, 0xFF, 0x60, 0x47, 0x00, 0x3A, 0x1C, 0x00, 0x60, 0x43, 0x00, 0x36, 0x1C, 0x00,
+	 0xE0, 0xA0, 0xDA, 0x85, 0x16, 0x07, 0x2D, 0x60, 0x7A, 0x61, 0xA1, 0xD1, 0xFF, 0xFF, 0xD3, 0x80,
+	 0xCB, 0x83, 0x0F, 0x02, 0x07, 0x0E, 0x59, 0xD3, 0xA5, 0xD0, 0xDA, 0x85, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x08, 0x02, 0xF9, 0x1F, 0x13, 0x1E, 0xA5, 0xD0, 0x59, 0xD3, 0xFF, 0xFF, 0x90, 0x80, 0xFF, 0x22,
+	 0x0D, 0x00, 0xE8, 0x60, 0xDD, 0x78, 0xFF, 0xFF, 0x28, 0x60, 0x2A, 0x62, 0xA2, 0xD3, 0xFF, 0xFF,
+	 0x60, 0x40, 0x01, 0x2A, 0x03, 0x00, 0x27, 0x60, 0xDA, 0x64, 0x02, 0x00, 0x2D, 0x60, 0x7A, 0x64,
+	 0x2E, 0x60, 0xCA, 0x62, 0xA2, 0xDB, 0x26, 0x46, 0x2F, 0xF2, 0x2C, 0xFA, 0x30, 0xF2, 0x2D, 0xFA,
+	 0x31, 0xF2, 0x2E, 0xFA, 0xEB, 0xF1, 0x2F, 0xF8, 0xEC, 0xF1, 0x30, 0xF8, 0xED, 0xF1, 0x31, 0xF8,
+	 0x81, 0xF1, 0x32, 0xF8, 0x82, 0xF1, 0x33, 0xF8, 0x83, 0xF1, 0x34, 0xF8, 0x50, 0x63, 0x2A, 0xFC,
+	 0xCC, 0xF3, 0x19, 0xFA, 0x00, 0x64, 0x3E, 0xFA, 0xA9, 0xF3, 0x07, 0xFA, 0x00, 0xF4, 0x80, 0xF1,
+	 0x06, 0xF8, 0x2F, 0x60, 0x44, 0x62, 0xA2, 0xD3, 0x07, 0xFA, 0x2E, 0x60, 0xD2, 0x65, 0xE9, 0x60,
+	 0x58, 0x4D, 0x32, 0x78, 0xFF, 0xFF, 0x2E, 0x60, 0xCA, 0x64, 0x40, 0x48, 0x10, 0x61, 0x00, 0x60,
+	 0x00, 0x64, 0xE8, 0x60, 0x58, 0x4D, 0xE8, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x3F, 0xFC, 0x24, 0x60,
+	 0x74, 0x62, 0x24, 0x60, 0x28, 0x64, 0xA2, 0xDB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB,
+	 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x00, 0x66, 0x46, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60,
+	 0xD2, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x5A, 0xDB, 0x00, 0x64, 0x94, 0xFB, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x2F, 0x60, 0x46, 0x62, 0xA2, 0xDB, 0xCD, 0x81, 0x28, 0xD3, 0x5A, 0x88, 0xDC, 0x83, 0x39, 0x18,
+	 0xFB, 0x03, 0x61, 0x40, 0x7F, 0x3A, 0x07, 0x00, 0x2F, 0x60, 0x46, 0x62, 0xA2, 0xD3, 0x03, 0x61,
+	 0x7C, 0xA4, 0xA2, 0xDB, 0x00, 0xF4, 0x60, 0xFE, 0xA3, 0xD1, 0xDD, 0x81, 0xA1, 0xD8, 0x61, 0x40,
+	 0x7F, 0x3A, 0x09, 0x00, 0x20, 0xFE, 0x2F, 0x60, 0x46, 0x62, 0xA2, 0xD3, 0x03, 0x61, 0x7C, 0xA4,
+	 0xA2, 0xDB, 0x00, 0xF4, 0x60, 0xFE, 0xCF, 0x83, 0xA3, 0xD3, 0xDD, 0x81, 0xA1, 0xDA, 0xFF, 0xB4,
+	 0x00, 0x7F, 0x15, 0x03, 0xDB, 0x83, 0x61, 0x40, 0x7F, 0x3A, 0x0B, 0x00, 0x20, 0xFE, 0x60, 0x45,
+	 0x2F, 0x60, 0x46, 0x62, 0xA2, 0xD3, 0x03, 0x61, 0x7C, 0xA4, 0xA2, 0xDB, 0x65, 0x44, 0x00, 0xF4,
+	 0x60, 0xFE, 0xA3, 0xD1, 0xDF, 0x83, 0xDD, 0x81, 0xCC, 0x84, 0xA1, 0xD8, 0xEC, 0x02, 0x20, 0xFE,
+	 0xC3, 0x01, 0x2F, 0x60, 0x46, 0x62, 0xA2, 0xD1, 0xFD, 0xA1, 0xFF, 0xB1, 0xC1, 0x83, 0xA2, 0xDD,
+	 0x2D, 0x58, 0xFF, 0xFF, 0x67, 0x5C, 0x1B, 0x60, 0xC6, 0x61, 0xA1, 0xD3, 0xA5, 0xD9, 0x12, 0x18,
+	 0x60, 0x43, 0x2F, 0x60, 0x14, 0x64, 0xA5, 0xDB, 0x60, 0xFE, 0xA0, 0xDD, 0xFF, 0xFF, 0x20, 0xFE,
+	 0xDC, 0x84, 0xCF, 0x83, 0xE3, 0x83, 0x59, 0xD1, 0xDC, 0x84, 0x60, 0xFE, 0xA0, 0xD9, 0xFF, 0xFF,
+	 0x20, 0xFE, 0xF9, 0x1F, 0x2D, 0x58, 0xFF, 0xFF, 0x0E, 0x57, 0x32, 0x40, 0x40, 0x26, 0x29, 0x00,
+	 0x45, 0x48, 0x00, 0x60, 0x10, 0x61, 0xAE, 0x60, 0x58, 0x4D, 0xC4, 0x78, 0xFF, 0xFF, 0x21, 0x03,
+	 0xF2, 0x60, 0x02, 0x64, 0x24, 0xFA, 0x00, 0x60, 0x48, 0x61, 0x28, 0x44, 0x59, 0xDA, 0x03, 0x64,
+	 0x38, 0x43, 0xBD, 0xD1, 0xCC, 0x84, 0x59, 0xD8, 0xFC, 0x02, 0x39, 0x44, 0x59, 0xDA, 0x28, 0x60,
+	 0x2E, 0x64, 0xA0, 0xD3, 0x59, 0xDA, 0x07, 0x64, 0x23, 0xFA, 0x24, 0x60, 0x74, 0x62, 0x24, 0x60,
+	 0x64, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0xFA, 0xFE, 0x37, 0x58, 0xFF, 0xFF, 0x0E, 0x57, 0x32, 0x40, 0x40, 0x26, 0x1C, 0x00, 0x45, 0x48,
+	 0x00, 0x60, 0x06, 0x61, 0xAE, 0x60, 0x58, 0x4D, 0xC4, 0x78, 0xFF, 0xFF, 0x14, 0x03, 0x02, 0x64,
+	 0x23, 0xFA, 0xF2, 0x60, 0x00, 0x64, 0x5A, 0xDA, 0x28, 0x44, 0x5A, 0xDA, 0xFF, 0xFF, 0x24, 0x60,
+	 0x74, 0x62, 0x24, 0x60, 0x64, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB,
+	 0xFF, 0xFF, 0x2B, 0xFF, 0xFA, 0xFE, 0x37, 0x58, 0xFF, 0xFF, 0xA2, 0xFF, 0x32, 0x40, 0x40, 0x26,
+	 0x3E, 0x00, 0x9D, 0xF3, 0x67, 0x43, 0xDC, 0x84, 0xCC, 0x84, 0x39, 0x03, 0x60, 0x46, 0x0A, 0x02,
+	 0x9D, 0xFD, 0x00, 0x60, 0x46, 0x61, 0xAE, 0x60, 0x58, 0x4D, 0xC4, 0x78, 0xFF, 0xFF, 0x66, 0x44,
+	 0x9D, 0xFB, 0x2E, 0x03, 0x46, 0x4B, 0x27, 0x60, 0x72, 0x61, 0x18, 0x64, 0x23, 0xFA, 0xF1, 0x60,
+	 0x00, 0x64, 0x24, 0xFA, 0x4A, 0x65, 0xA2, 0xFF, 0x2C, 0x63, 0x00, 0x64, 0x59, 0xD1, 0xA2, 0xDB,
+	 0xA5, 0xD8, 0xDA, 0x85, 0x80, 0x3A, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0xF7, 0x1F, 0x12, 0x63,
+	 0x59, 0xD1, 0xA5, 0xD8, 0xDA, 0x85, 0x80, 0x3A, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0xF8, 0x1F,
+	 0x24, 0x60, 0x74, 0x62, 0x24, 0x60, 0x64, 0x64, 0xA2, 0xDB, 0x2B, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xFA, 0xFE, 0xA6, 0xFE, 0x00, 0x64, 0x9D, 0xFB, 0xA3, 0xFF,
+	 0xBF, 0x60, 0xE7, 0x78, 0xFF, 0xFF, 0xA6, 0xFE, 0xB8, 0x05, 0xA7, 0xFE, 0x12, 0x05, 0xA5, 0xFE,
+	 0x03, 0x04, 0xEA, 0x60, 0xC5, 0x78, 0xFF, 0xFF, 0xA4, 0xFE, 0xF2, 0x04, 0x0F, 0x60, 0xDE, 0x62,
+	 0xA2, 0xD1, 0x00, 0x60, 0x80, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0xBF, 0x60, 0xE7, 0x78,
+	 0xFF, 0xFF, 0x36, 0x45, 0x20, 0x60, 0x08, 0x64, 0x44, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0xF3,
+	 0xFF, 0xFF, 0x01, 0xB0, 0x00, 0x64, 0x41, 0x03, 0x9F, 0xFB, 0x31, 0x44, 0xE8, 0xB4, 0x40, 0x51,
+	 0x6A, 0x44, 0xFF, 0xFF, 0x80, 0x26, 0xFC, 0x01, 0x61, 0xFF, 0x62, 0xFF, 0x10, 0x60, 0x1A, 0x62,
+	 0xA2, 0xD1, 0x00, 0x60, 0x20, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x34, 0x60, 0x58, 0x4E,
+	 0x64, 0x78, 0xFF, 0xFF, 0x1E, 0x60, 0xBC, 0x62, 0x1E, 0x60, 0xBE, 0x64, 0xA2, 0xDB, 0x00, 0x64,
+	 0x4A, 0xDB, 0x01, 0x60, 0xFE, 0x63, 0x1C, 0x60, 0xB8, 0x61, 0x00, 0x64, 0x59, 0xDB, 0xFE, 0x1F,
+	 0x1C, 0x63, 0x10, 0x60, 0x5C, 0x64, 0x58, 0xD1, 0xFF, 0xFF, 0x08, 0x1B, 0xFC, 0x1F, 0x00, 0x60,
+	 0x62, 0x63, 0x1B, 0x60, 0xC4, 0x64, 0x00, 0x7C, 0x58, 0xD9, 0xFE, 0x1F, 0x1C, 0x60, 0xB4, 0x63,
+	 0xA3, 0xD3, 0xFF, 0xFF, 0x04, 0xB0, 0xFF, 0xFF, 0x05, 0x03, 0x02, 0x65, 0xE9, 0x60, 0x58, 0x4E,
+	 0x7B, 0x78, 0xFF, 0xFF, 0xBF, 0x60, 0xE7, 0x78, 0xFF, 0xFF, 0xEA, 0x60, 0xC5, 0x78, 0xFF, 0xFF,
+	 0x0F, 0x60, 0xEA, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x01, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x74, 0x00, 0x28, 0x60, 0x50, 0x63, 0xBD, 0xD3, 0xBD, 0xD1, 0xBD, 0xD1, 0xB0, 0x84, 0xB0, 0x84,
+	 0xFF, 0xFF, 0x07, 0x02, 0x8C, 0xFB, 0x31, 0x44, 0xFE, 0xB4, 0x40, 0x51, 0x0D, 0x64, 0x05, 0xFB,
+	 0x64, 0x00, 0x28, 0xF3, 0x9F, 0xF1, 0x60, 0x47, 0x64, 0x41, 0x07, 0xB1, 0x07, 0xB4, 0x08, 0x24,
+	 0x67, 0x4C, 0x50, 0xFB, 0x01, 0x61, 0x03, 0x03, 0xCC, 0x84, 0xE1, 0x81, 0xFD, 0x02, 0xA1, 0x80,
+	 0xB1, 0x83, 0x53, 0x02, 0x9F, 0xFD, 0x28, 0x60, 0x44, 0x62, 0xA2, 0xD3, 0xE5, 0xFB, 0x7F, 0xFB,
+	 0x24, 0x60, 0x5E, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x46, 0x5E, 0x31, 0x44,
+	 0x01, 0xBC, 0x40, 0x51, 0xD8, 0xF3, 0x01, 0x63, 0x03, 0xA8, 0x4E, 0xFD, 0x05, 0x02, 0x02, 0x63,
+	 0x14, 0x60, 0x00, 0x64, 0xDB, 0xFB, 0x0C, 0x00, 0x02, 0xA8, 0x01, 0x63, 0x03, 0x03, 0x0A, 0x60,
+	 0x00, 0x64, 0x03, 0x00, 0x02, 0x63, 0x14, 0x60, 0x00, 0x64, 0xDB, 0xFB, 0x00, 0x64, 0x4E, 0xFB,
+	 0x4B, 0xFD, 0xA9, 0xF5, 0xFF, 0xFF, 0x0E, 0xF0, 0x0F, 0x60, 0xA2, 0x65, 0x28, 0x60, 0xD2, 0x62,
+	 0xA2, 0xD3, 0xFF, 0xFF, 0xFE, 0xA0, 0x03, 0xA8, 0x11, 0x06, 0x79, 0xF1, 0x06, 0x02, 0x64, 0x44,
+	 0x08, 0x2A, 0x09, 0x00, 0x06, 0x64, 0x44, 0xD3, 0x0D, 0x00, 0x64, 0x44, 0x20, 0x2A, 0x03, 0x00,
+	 0x0A, 0x64, 0x44, 0xD3, 0x07, 0x00, 0x01, 0x64, 0x44, 0xD3, 0x04, 0x00, 0xE8, 0x84, 0xE0, 0x84,
+	 0x44, 0xD3, 0x00, 0x00, 0x0E, 0xFA, 0xED, 0xE2, 0x0F, 0x4E, 0xC8, 0x60, 0x58, 0x4F, 0x15, 0x78,
+	 0xFF, 0xFF, 0x0E, 0x4F, 0xBF, 0x60, 0xE7, 0x78, 0xFF, 0xFF, 0xD7, 0xFE, 0xBF, 0x60, 0xE7, 0x78,
+	 0xFF, 0xFF, 0x0F, 0x60, 0xEA, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xCF, 0xFE, 0xF3, 0x01, 0x24, 0x60, 0x46, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46,
+	 0x0E, 0xF2, 0x4D, 0x03, 0x60, 0x40, 0xF0, 0x37, 0x3A, 0x00, 0xFF, 0x37, 0x2F, 0x00, 0xFD, 0x37,
+	 0x27, 0x00, 0xF8, 0x37, 0x0A, 0x00, 0x60, 0x47, 0xFF, 0xB5, 0x0F, 0x60, 0xD2, 0x62, 0x46, 0xD1,
+	 0x00, 0x60, 0x01, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x24, 0x60, 0x74, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xDA, 0x01,
+	 0x06, 0xB4, 0xFD, 0x7F, 0x0E, 0xFA, 0x24, 0x60, 0x74, 0x62, 0x24, 0x60, 0x4C, 0x64, 0xA2, 0xDB,
+	 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xF9, 0xFE, 0xCA, 0x01,
+	 0x23, 0xF0, 0x60, 0x40, 0x04, 0x26, 0xEC, 0x1B, 0x02, 0x26, 0xEA, 0x18, 0xA2, 0xFF, 0x02, 0xF0,
+	 0x09, 0x60, 0x08, 0x64, 0xD0, 0x80, 0xB0, 0xF3, 0x02, 0x02, 0xCC, 0x84, 0xB0, 0xFB, 0x24, 0x60,
+	 0x74, 0x64, 0x40, 0x4B, 0x2C, 0x60, 0x58, 0x4D, 0xD8, 0x78, 0xFF, 0xFF, 0xB3, 0x01, 0xAC, 0xFE,
+	 0x09, 0x05, 0xAD, 0xFE, 0x10, 0x05, 0xAE, 0xFE, 0xAD, 0x05, 0xAF, 0xFE, 0x3A, 0x05, 0xBF, 0x60,
+	 0xE7, 0x78, 0xFF, 0xFF, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1, 0x20, 0x60, 0x00, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0xF4, 0x01, 0x10, 0x60, 0x32, 0x65, 0x0B, 0x61, 0x07, 0x00, 0xA2, 0xDD,
+	 0x58, 0x4F, 0x64, 0x58, 0xFF, 0xFF, 0x00, 0xB9, 0xFF, 0xFF, 0x08, 0x03, 0x00, 0x63, 0xA5, 0xD1,
+	 0x5A, 0xD3, 0xDA, 0x85, 0x00, 0xA8, 0xCD, 0x81, 0xF2, 0x02, 0xF8, 0x02, 0xE0, 0x01, 0x0F, 0x60,
+	 0xCE, 0x62, 0x10, 0x60, 0x12, 0x65, 0xEB, 0x60, 0x5F, 0x63, 0x00, 0x64, 0x5A, 0xDB, 0xD6, 0x80,
+	 0xFF, 0xFF, 0x04, 0x03, 0x5A, 0xDB, 0x5A, 0xDB, 0x5A, 0xDD, 0xF9, 0x01, 0x10, 0x60, 0x30, 0x65,
+	 0x00, 0x64, 0x5A, 0xDB, 0xD6, 0x80, 0xFF, 0xFF, 0x02, 0x03, 0x5A, 0xDD, 0xFB, 0x01, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x0F, 0x60, 0xD2, 0x64, 0x40, 0x41, 0x0F, 0x60, 0xD0, 0x63, 0xA3, 0xD1, 0x00, 0x64,
+	 0xD0, 0x80, 0x0B, 0x61, 0x08, 0x03, 0xBD, 0xDB, 0xA3, 0xD3, 0xFF, 0xFF, 0xB0, 0x84, 0xCD, 0x81,
+	 0xA3, 0xDB, 0x06, 0xA3, 0xF9, 0x02, 0x10, 0x60, 0x1A, 0x63, 0xA3, 0xD1, 0x00, 0x64, 0xD0, 0x80,
+	 0x0C, 0x61, 0x19, 0x03, 0xBD, 0xDB, 0x64, 0x44, 0xFE, 0xA3, 0x02, 0xA3, 0xCD, 0x81, 0xE8, 0x84,
+	 0xE3, 0x03, 0x02, 0x05, 0xE1, 0x03, 0xF9, 0x01, 0x99, 0xFB, 0x9B, 0xFD, 0x61, 0x5C, 0xA3, 0xD3,
+	 0x9A, 0xF9, 0x03, 0x18, 0x58, 0x4F, 0x60, 0x58, 0xFF, 0xFF, 0x9B, 0xF3, 0x9A, 0xF1, 0x60, 0x43,
+	 0x99, 0xF3, 0x64, 0x41, 0xEA, 0x01, 0x21, 0x43, 0x10, 0x60, 0x14, 0x65, 0xD7, 0x80, 0xBD, 0xD1,
+	 0xBD, 0xD3, 0x03, 0x02, 0xBF, 0x60, 0xE7, 0x78, 0xFF, 0xFF, 0xA0, 0x84, 0xBD, 0xD1, 0x43, 0x41,
+	 0xF5, 0x03, 0xEB, 0x60, 0x64, 0x64, 0x64, 0x58, 0x40, 0x4F, 0x2A, 0xF0, 0x83, 0x60, 0xFF, 0x65,
+	 0x64, 0x47, 0x03, 0x2B, 0x01, 0x00, 0x14, 0x00, 0x03, 0x26, 0x03, 0xAC, 0x60, 0x47, 0xA4, 0x84,
+	 0x2A, 0xFA, 0x2F, 0xF2, 0x2C, 0xFA, 0x30, 0xF2, 0x2D, 0xFA, 0x31, 0xF2, 0x2E, 0xFA, 0x64, 0x41,
+	 0xEB, 0xF3, 0x2F, 0xFA, 0x60, 0x43, 0xEC, 0xF3, 0x30, 0xFA, 0xED, 0xF1, 0x31, 0xF8, 0x19, 0x00,
+	 0x60, 0x47, 0xA4, 0x84, 0x2A, 0xFA, 0x2F, 0xF2, 0x2C, 0xFA, 0x30, 0xF2, 0x2D, 0xFA, 0x31, 0xF2,
+	 0x2E, 0xFA, 0x36, 0xF2, 0x32, 0xFA, 0x37, 0xF2, 0x33, 0xFA, 0x38, 0xF2, 0x34, 0xFA, 0xEB, 0xF3,
+	 0x2F, 0xFA, 0x36, 0xFA, 0xEC, 0xF3, 0x30, 0xFA, 0x37, 0xFA, 0xED, 0xF3, 0x31, 0xFA, 0x38, 0xFA,
+	 0x64, 0x41, 0x1C, 0xF2, 0x13, 0xFA, 0x00, 0xF4, 0x0D, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x80, 0x2B,
+	 0x18, 0x00, 0x81, 0x67, 0xA2, 0xDA, 0xEC, 0x60, 0x58, 0x4E, 0x5A, 0x78, 0xFF, 0xFF, 0x26, 0x46,
+	 0x3F, 0xFC, 0x24, 0x60, 0x74, 0x62, 0x24, 0x60, 0x28, 0x64, 0xA2, 0xDB, 0x26, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x00, 0x66, 0x46, 0x46, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x26, 0x46, 0x3F, 0xF0, 0x42, 0x64, 0xD0, 0x80, 0xFF, 0xFF, 0x01, 0x04, 0x3F, 0xFA,
+	 0x07, 0xF2, 0xA9, 0xF1, 0x01, 0x1B, 0x07, 0xF8, 0x1C, 0xF2, 0x13, 0xFA, 0x26, 0xF2, 0x27, 0xF0,
+	 0x60, 0x47, 0x00, 0xF4, 0x1F, 0xFA, 0x64, 0x47, 0x20, 0xFA, 0x61, 0x44, 0x21, 0xFA, 0x01, 0x67,
+	 0x0D, 0xFA, 0x10, 0x61, 0x28, 0x60, 0x06, 0x64, 0x1E, 0x63, 0x58, 0xD1, 0xCD, 0x81, 0xBD, 0xD8,
+	 0xFC, 0x02, 0xBB, 0xF1, 0xD8, 0xF1, 0x64, 0x5E, 0x64, 0x5F, 0x44, 0x63, 0xBD, 0xDA, 0x28, 0x60,
+	 0x00, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0x4A, 0xD3, 0x60, 0x45,
+	 0x60, 0x40, 0x01, 0x36, 0x03, 0x64, 0x02, 0x36, 0x01, 0x64, 0xB4, 0x84, 0x06, 0xA2, 0xA2, 0xD1,
+	 0xBD, 0xDA, 0x64, 0x47, 0xBD, 0xDA, 0xD5, 0xF3, 0xD6, 0xF1, 0x60, 0x47, 0xBD, 0xDA, 0x64, 0x47,
+	 0xE3, 0xF1, 0xBD, 0xDA, 0x64, 0x44, 0xBD, 0xDA, 0x26, 0x46, 0x00, 0x64, 0x23, 0xF0, 0x3B, 0xF0,
+	 0x64, 0x40, 0x10, 0x2A, 0x06, 0x00, 0xC0, 0x67, 0xA0, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84,
+	 0x10, 0xBC, 0x3E, 0xFA, 0x24, 0x60, 0x74, 0x62, 0x24, 0x60, 0x34, 0x64, 0xA2, 0xDB, 0x26, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC8, 0xFE, 0x00, 0x66, 0x46, 0x46,
+	 0x2F, 0x58, 0xFF, 0xFF, 0xB4, 0xF3, 0x1F, 0xFA, 0x32, 0x47, 0x07, 0xFA, 0x24, 0x7E, 0x02, 0x7F,
+	 0x08, 0xFA, 0xD8, 0xF1, 0x09, 0xF8, 0x01, 0x60, 0x01, 0x64, 0x0A, 0xFA, 0x01, 0x64, 0x0B, 0xFA,
+	 0x24, 0x60, 0x74, 0x62, 0x18, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x0A, 0x64, 0x5A, 0xDB,
+	 0xFF, 0xFF, 0x2B, 0xFF, 0x52, 0x63, 0x2E, 0x58, 0xFF, 0xFF, 0x00, 0x60, 0x2A, 0x61, 0xAE, 0x60,
+	 0x58, 0x4D, 0xC4, 0x78, 0xFF, 0xFF, 0x66, 0x44, 0x5E, 0xFB, 0x04, 0x64, 0x03, 0xFA, 0x67, 0x44,
+	 0x2C, 0xFA, 0x2D, 0xFA, 0x2E, 0xFA, 0x32, 0xFA, 0x33, 0xFA, 0x34, 0xFA, 0x12, 0x60, 0x80, 0x64,
+	 0xA9, 0xF1, 0x0E, 0xFA, 0x07, 0xF8, 0x00, 0x64, 0x3E, 0xFA, 0x1A, 0x60, 0x4E, 0x63, 0xA3, 0xDB,
+	 0x06, 0xA3, 0x10, 0x60, 0x38, 0x64, 0xBD, 0xDB, 0x04, 0x64, 0xBD, 0xDB, 0x06, 0x64, 0xA3, 0xDB,
+	 0x10, 0x60, 0x36, 0x62, 0xEF, 0x60, 0xA9, 0x64, 0xA2, 0xDB, 0x1A, 0x60, 0x5A, 0x63, 0x00, 0x64,
+	 0xA3, 0xDB, 0x06, 0xA3, 0x10, 0x60, 0x3C, 0x64, 0xBD, 0xDB, 0x08, 0x64, 0xBD, 0xDB, 0x06, 0x64,
+	 0xA3, 0xDB, 0x10, 0x60, 0x3A, 0x62, 0xEF, 0x60, 0xB3, 0x64, 0xA2, 0xDB, 0x10, 0x60, 0x22, 0x62,
+	 0xEF, 0x60, 0x93, 0x64, 0xA2, 0xDB, 0x00, 0x64, 0x31, 0x60, 0x2A, 0x62, 0xA2, 0xDB, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x5E, 0xF5, 0xEB, 0xF1, 0x2F, 0xF8, 0xEC, 0xF1, 0x30, 0xF8, 0xED, 0xF1, 0x31, 0xF8,
+	 0xCC, 0xF1, 0x19, 0xF8, 0x30, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x0F, 0x60, 0xE4, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0x00, 0x63, 0x8A, 0xFD, 0x1C, 0x60, 0x96, 0x65, 0xA5, 0xDD, 0x19, 0x60, 0x86, 0x63,
+	 0x88, 0xFD, 0x89, 0xFD, 0x20, 0x40, 0x10, 0x2B, 0x05, 0x00, 0x1F, 0x60, 0x82, 0x61, 0xA1, 0xD3,
+	 0xFF, 0xFF, 0x59, 0x18, 0x5E, 0xF5, 0x40, 0x64, 0x2A, 0xFA, 0x54, 0xF3, 0x00, 0xF4, 0x60, 0x43,
+	 0xBD, 0xD1, 0x04, 0x65, 0x64, 0x47, 0xA5, 0xDA, 0x64, 0x41, 0xDD, 0x81, 0xE9, 0x81, 0x62, 0x44,
+	 0x04, 0x03, 0xBD, 0xD1, 0xCD, 0x81, 0x58, 0xD8, 0xFC, 0x02, 0x58, 0x8B, 0x2D, 0x60, 0x28, 0x63,
+	 0xA3, 0xD1, 0x2B, 0x44, 0xC8, 0x84, 0x64, 0x41, 0xFF, 0xB1, 0x61, 0x45, 0x03, 0xA1, 0xE9, 0x81,
+	 0x41, 0x4C, 0xBD, 0xD1, 0xCD, 0x81, 0x58, 0xD8, 0xFC, 0x02, 0x2B, 0xD2, 0x2B, 0x43, 0x60, 0x47,
+	 0x01, 0x7E, 0x54, 0xF1, 0xA3, 0xDA, 0xA4, 0xD3, 0xCB, 0x83, 0x44, 0x8B, 0xF8, 0x84, 0x2C, 0x41,
+	 0x0C, 0x04, 0xBE, 0xD2, 0xFF, 0xFF, 0x60, 0x47, 0xBE, 0xDA, 0x00, 0x7E, 0xA3, 0xD2, 0x60, 0x45,
+	 0x00, 0x7F, 0xB4, 0x84, 0xCD, 0x81, 0xBD, 0xDA, 0xF4, 0x02, 0x5E, 0xF5, 0x2B, 0x44, 0x04, 0xA4,
+	 0x3F, 0xFA, 0x7F, 0xF3, 0x7E, 0xFB, 0x1F, 0x60, 0x84, 0x61, 0x01, 0x64, 0x54, 0xF1, 0xA1, 0xDB,
+	 0x7F, 0xFB, 0xA4, 0xD3, 0x04, 0x65, 0x53, 0xF3, 0x01, 0x18, 0x0C, 0x65, 0xF3, 0xB4, 0xB4, 0x84,
+	 0x53, 0xFB, 0x02, 0xB0, 0xFF, 0xFF, 0x16, 0x03, 0x7F, 0xF3, 0xFF, 0xFF, 0x60, 0x47, 0x0F, 0xB4,
+	 0x7F, 0xFB, 0x01, 0x03, 0x0F, 0x00, 0xEE, 0x60, 0x4F, 0x78, 0xFF, 0xFF, 0x53, 0xF1, 0x7F, 0xF3,
+	 0x64, 0x40, 0x02, 0x26, 0xF8, 0x01, 0xF3, 0xA0, 0x04, 0xA4, 0x01, 0x04, 0xF1, 0xA4, 0x10, 0x36,
+	 0xF2, 0x01, 0x7F, 0xFB, 0x20, 0x40, 0x10, 0x2B, 0x12, 0x00, 0x7F, 0xF3, 0x1F, 0x60, 0x82, 0x61,
+	 0xA1, 0xD1, 0xCC, 0x84, 0x01, 0x61, 0x08, 0x24, 0x03, 0x00, 0xE1, 0x81, 0xCC, 0x84, 0xFB, 0x01,
+	 0xA1, 0x84, 0x53, 0xF1, 0xE4, 0x03, 0x1F, 0x60, 0x84, 0x61, 0xA1, 0xDB, 0x19, 0x00, 0x53, 0xF3,
+	 0xFF, 0xFF, 0x10, 0xB0, 0x12, 0x60, 0x26, 0x63, 0x02, 0x03, 0x10, 0x60, 0x5C, 0x63, 0x31, 0x60,
+	 0x2A, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0x0C, 0x1B, 0x7F, 0xF3, 0xFF, 0xFF, 0xE0, 0x85, 0x47, 0xD3,
+	 0x53, 0xF1, 0x01, 0xB0, 0x06, 0xB0, 0xCB, 0x03, 0x64, 0x40, 0x03, 0x26, 0x01, 0x00, 0xC7, 0x03,
+	 0x7F, 0xF3, 0x01, 0x61, 0xCC, 0x84, 0xFF, 0xFF, 0x02, 0x03, 0xE1, 0x81, 0xFB, 0x01, 0xBA, 0xF3,
+	 0x61, 0x45, 0xA4, 0x80, 0xFF, 0xFF, 0xBB, 0x03, 0x31, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x0F, 0x60,
+	 0xE4, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE, 0x0B, 0x04, 0x0F, 0x60, 0xE6, 0x62, 0x40, 0x60,
+	 0x00, 0x64, 0xA2, 0xDB, 0xED, 0x60, 0x70, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x7F, 0xF1, 0x24, 0x60, 0x9A, 0x62, 0xA2, 0xD9, 0x1E, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF,
+	 0x0F, 0x60, 0xE6, 0x62, 0x20, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xED, 0x60, 0xA3, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0xBE, 0xFE, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1, 0x40, 0x60,
+	 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x0F, 0x60, 0xE4, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0x5E, 0xF5, 0x24, 0x60, 0x74, 0x62, 0x24, 0x60, 0x28, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x00, 0x64, 0x51, 0xFB, 0x0F, 0x60, 0xE6, 0x62,
+	 0x00, 0x60, 0x01, 0x64, 0xA2, 0xDB, 0xED, 0x60, 0xCD, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0xC1, 0xFE,
+	 0x33, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x2F, 0x58, 0xFF, 0xFF, 0x34, 0x64, 0x3B, 0x42, 0x5A, 0xDB,
+	 0x0F, 0x60, 0xE4, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xC6, 0xF1, 0x1A, 0x60, 0x52, 0x62, 0xA2, 0xD9,
+	 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x4E, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x04, 0xFF, 0xC7, 0xF1, 0x1A, 0x60, 0x5E, 0x62, 0xA2, 0xD9, 0x24, 0x60, 0xA8, 0x62, 0xA2, 0xD3,
+	 0xFF, 0xFF, 0xFD, 0x1B, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x5A, 0x64, 0xA2, 0xDB, 0x02, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x0F, 0x60, 0xE6, 0x62, 0x00, 0x60, 0x08, 0x64, 0xA2, 0xDB,
+	 0xED, 0x60, 0xFE, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x51, 0xF1, 0x0F, 0x60,
+	 0xE4, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x64, 0x40, 0xFF, 0x26, 0x03, 0x00, 0xED, 0x60, 0x36, 0x78,
+	 0xFF, 0xFF, 0x02, 0x0A, 0x00, 0x64, 0x51, 0xFB, 0xC8, 0xF1, 0x1A, 0x60, 0x5E, 0x62, 0xA2, 0xD9,
+	 0x0F, 0x60, 0xE6, 0x62, 0x00, 0x60, 0x0C, 0x64, 0xA2, 0xDB, 0xEE, 0x60, 0x24, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x5A, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB,
+	 0xFF, 0xFF, 0x04, 0xFF, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xE4, 0x62, 0xA2, 0xD1, 0x00, 0x60,
+	 0x04, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x0C, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x24, 0x60, 0xAA, 0x62,
+	 0x1A, 0x60, 0x5A, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x14, 0x00,
+	 0xFF, 0x60, 0xF7, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x51, 0xF3, 0xDB, 0x0A, 0x00, 0xA0, 0x00, 0x64,
+	 0x02, 0x03, 0x51, 0xFB, 0xD6, 0x01, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x4E, 0x64, 0xA2, 0xDB,
+	 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0xED, 0x60, 0x36, 0x78, 0xFF, 0xFF, 0x35, 0x64,
+	 0x3B, 0x42, 0x5A, 0xDB, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0x4E, 0x64, 0xA2, 0xDB, 0x03, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x53, 0xF3, 0xFF, 0xFF, 0xE3, 0xB4, 0x53, 0xFB, 0x1F, 0x60,
+	 0x80, 0x64, 0xA0, 0xD3, 0xFF, 0xFF, 0xFE, 0xB4, 0xA2, 0xDB, 0x00, 0x64, 0x31, 0x60, 0x2A, 0x62,
+	 0xA2, 0xDB, 0x0F, 0x60, 0xE4, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE, 0x0E, 0x04, 0x32, 0x64,
+	 0x3B, 0x42, 0x5A, 0xDB, 0x0F, 0x60, 0xE6, 0x62, 0x40, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xEE, 0x60,
+	 0x69, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x7E, 0xF1, 0x7F, 0xF9, 0x24, 0x60,
+	 0x9A, 0x62, 0xA2, 0xD9, 0x1E, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x0F, 0x60, 0xE6, 0x62,
+	 0x20, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xEE, 0x60, 0x91, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0xBE, 0xFE, 0x0F, 0x60, 0xD0, 0x62, 0xA2, 0xD1, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x1A, 0x60, 0x06, 0x63, 0x1C, 0x61, 0x00, 0x64, 0xCD, 0x81, 0xBD, 0xDB,
+	 0xFD, 0x02, 0x12, 0x60, 0x46, 0x61, 0x8A, 0xF3, 0x61, 0x43, 0xC6, 0xA5, 0x47, 0xD1, 0x0F, 0x04,
+	 0xBE, 0xD5, 0x1A, 0x60, 0x02, 0x63, 0xC3, 0x83, 0xC3, 0x83, 0xC3, 0x83, 0x43, 0xD3, 0xBE, 0xD1,
+	 0xDC, 0x84, 0xA3, 0xDB, 0x66, 0x44, 0xC0, 0x84, 0xBE, 0xDB, 0x65, 0x44, 0xED, 0x01, 0x1A, 0x60,
+	 0x06, 0x63, 0x0E, 0x61, 0x41, 0x4B, 0xBD, 0xD3, 0xBD, 0xD1, 0x00, 0xBD, 0x64, 0x41, 0x19, 0x03,
+	 0x01, 0xA8, 0x61, 0x44, 0x02, 0xA8, 0x15, 0x03, 0x02, 0x02, 0xE9, 0x84, 0x12, 0x00, 0x65, 0x47,
+	 0x60, 0x45, 0x61, 0x44, 0x09, 0x61, 0xCD, 0x81, 0xE0, 0x84, 0xFF, 0x23, 0xFC, 0x01, 0x02, 0x24,
+	 0xC4, 0x84, 0x02, 0x28, 0xD4, 0x84, 0xCD, 0x81, 0x01, 0x0E, 0x01, 0xBC, 0x02, 0x03, 0xE0, 0x84,
+	 0xF6, 0x01, 0x00, 0x7F, 0x2B, 0x41, 0x4D, 0x8B, 0xBF, 0xDB, 0xDD, 0x02, 0x12, 0x60, 0x46, 0x61,
+	 0x8A, 0xF3, 0x61, 0x43, 0xC6, 0xA5, 0x47, 0xD1, 0x0A, 0x04, 0xDA, 0x86, 0x1A, 0x60, 0x04, 0x63,
+	 0xC3, 0x83, 0xC3, 0x83, 0xC3, 0x83, 0x43, 0xD1, 0xA6, 0xD9, 0x65, 0x44, 0xF2, 0x01, 0x36, 0x64,
+	 0x3B, 0x42, 0x5A, 0xDB, 0x53, 0xF3, 0x8A, 0xF1, 0xF3, 0xB4, 0x53, 0xFB, 0x12, 0x60, 0x46, 0x63,
+	 0xC3, 0x85, 0x45, 0x4A, 0x19, 0x60, 0x86, 0x65, 0x89, 0xF3, 0x45, 0x4C, 0x40, 0x48, 0x20, 0x40,
+	 0x20, 0x2A, 0x02, 0x00, 0x00, 0x65, 0x45, 0x4B, 0x2A, 0x45, 0xD7, 0x80, 0x02, 0x65, 0x23, 0x05,
+	 0x47, 0xD1, 0x02, 0x65, 0x47, 0xD3, 0x0A, 0x65, 0xD0, 0x81, 0x47, 0xD3, 0x01, 0x05, 0x00, 0x61,
+	 0xF2, 0xA3, 0x01, 0xB0, 0x61, 0x44, 0x11, 0x03, 0x20, 0x40, 0x20, 0x2A, 0x08, 0x00, 0xF3, 0x60,
+	 0x58, 0x4E, 0x3E, 0x78, 0xFF, 0xFF, 0x2B, 0x44, 0x02, 0xA4, 0x40, 0x4B, 0x61, 0x44, 0x2C, 0x42,
+	 0xA2, 0xDB, 0x5A, 0xDD, 0x5A, 0x8C, 0x3A, 0xA3, 0xDF, 0x01, 0x28, 0x42, 0x4A, 0xDD, 0x4A, 0xDB,
+	 0x42, 0x48, 0x3A, 0xA3, 0xD9, 0x01, 0x28, 0x44, 0x88, 0xFB, 0x88, 0xF1, 0x19, 0x60, 0x86, 0x63,
+	 0x44, 0x48, 0x28, 0x45, 0xD7, 0x80, 0xA3, 0xD1, 0x15, 0x05, 0x04, 0x65, 0x46, 0xD3, 0x28, 0x45,
+	 0xD6, 0x80, 0xD0, 0x80, 0x02, 0x04, 0x04, 0xA3, 0xF5, 0x01, 0xF7, 0x06, 0x62, 0x46, 0xA2, 0xD9,
+	 0xA3, 0xDB, 0x5B, 0xD3, 0x66, 0x42, 0x5A, 0xD1, 0xA2, 0xDB, 0xA3, 0xD9, 0xFE, 0xA3, 0xA3, 0xD1,
+	 0x66, 0x42, 0xEB, 0x01, 0x88, 0xF3, 0x89, 0xF1, 0x60, 0x43, 0x44, 0x48, 0x28, 0x45, 0xD7, 0x80,
+	 0xA3, 0xD1, 0x15, 0x05, 0x04, 0x65, 0x46, 0xD3, 0x28, 0x45, 0xD6, 0x80, 0xD0, 0x80, 0x02, 0x04,
+	 0x04, 0xA3, 0xF5, 0x01, 0xF7, 0x06, 0x62, 0x46, 0xA2, 0xD9, 0xA3, 0xDB, 0x5B, 0xD3, 0x66, 0x42,
+	 0x5A, 0xD1, 0xA2, 0xDB, 0xA3, 0xD9, 0xFE, 0xA3, 0xA3, 0xD1, 0x66, 0x42, 0xEB, 0x01, 0x0F, 0x60,
+	 0xD0, 0x62, 0xA2, 0xD1, 0x10, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x20, 0x40,
+	 0x80, 0x2B, 0x17, 0x00, 0x00, 0x60, 0x04, 0x61, 0xAE, 0x60, 0x58, 0x4D, 0xC4, 0x78, 0xFF, 0xFF,
+	 0x01, 0x64, 0x23, 0xFA, 0xF1, 0x60, 0x02, 0x64, 0x24, 0xFA, 0x24, 0x60, 0x74, 0x62, 0x24, 0x60,
+	 0x64, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0xFA, 0xFE, 0x0F, 0x60, 0xE4, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x5A, 0xDB, 0x3E, 0x64, 0x3B, 0x42,
+	 0x5A, 0xDB, 0x2F, 0x58, 0xFF, 0xFF, 0x3F, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x24, 0x60, 0xAA, 0x62,
+	 0x1A, 0x60, 0x4E, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x00, 0x64,
+	 0x53, 0xFB, 0x0F, 0x60, 0xE4, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x5A, 0xDB, 0xBE, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x0F, 0x60, 0xE4, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0F, 0x60, 0xE4, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x08, 0x64,
+	 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x79, 0xFB, 0xAC, 0x85, 0x60, 0x41,
+	 0x20, 0x03, 0x01, 0x60, 0x00, 0x63, 0x08, 0x64, 0xE9, 0x81, 0xCC, 0x84, 0x02, 0x24, 0xDF, 0x83,
+	 0xFB, 0x02, 0x2D, 0x60, 0x28, 0x64, 0xA0, 0xDD, 0x65, 0x41, 0x2D, 0x60, 0x2A, 0x63, 0x0F, 0x60,
+	 0xC0, 0x64, 0xE9, 0x81, 0x58, 0xD1, 0xFD, 0x04, 0xA3, 0xD9, 0x0B, 0x03, 0x58, 0xD1, 0xE9, 0x81,
+	 0x60, 0x45, 0xFC, 0x04, 0xA3, 0xD1, 0x64, 0x47, 0xB0, 0x84, 0xBD, 0xDB, 0x00, 0xB9, 0x65, 0x44,
+	 0xF0, 0x02, 0x2E, 0x58, 0xFF, 0xFF, 0x3C, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x20, 0x40, 0x90, 0x2B,
+	 0x03, 0x00, 0xF2, 0x60, 0xE5, 0x78, 0xFF, 0xFF, 0x53, 0xF3, 0x8A, 0xF1, 0x04, 0xB0, 0x07, 0x60,
+	 0x40, 0x64, 0xD0, 0x80, 0x21, 0x03, 0x20, 0x06, 0x26, 0x46, 0x8A, 0xF1, 0x12, 0x60, 0x46, 0x63,
+	 0xC3, 0x83, 0x7F, 0xF3, 0x26, 0xF0, 0xBD, 0xDB, 0x64, 0x44, 0x00, 0x7F, 0xBD, 0xDB, 0x64, 0x47,
+	 0x00, 0x7F, 0xBD, 0xDB, 0x32, 0xF0, 0xBD, 0xD9, 0x33, 0xF0, 0xBD, 0xD9, 0x34, 0xF0, 0xBD, 0xD9,
+	 0x00, 0xF4, 0x0D, 0xF0, 0xBD, 0xD9, 0x0E, 0xF0, 0xBD, 0xD9, 0x00, 0x64, 0x0F, 0xF0, 0xA3, 0xDB,
+	 0x64, 0x47, 0x60, 0x45, 0x00, 0x37, 0x03, 0x00, 0xF2, 0x60, 0xDF, 0x78, 0xFF, 0xFF, 0xBD, 0xDB,
+	 0xE0, 0xA0, 0x1F, 0x61, 0x00, 0xB8, 0xF8, 0x07, 0xF7, 0x03, 0x60, 0xFE, 0xDD, 0x81, 0xA1, 0xD0,
+	 0xCC, 0x84, 0xBD, 0xD9, 0xFB, 0x02, 0x65, 0x40, 0x01, 0x26, 0xDF, 0x83, 0x20, 0xFE, 0x2D, 0x60,
+	 0xE4, 0x62, 0xA2, 0xDD, 0x60, 0xFE, 0xDD, 0x81, 0xA1, 0xD0, 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x3A,
+	 0x04, 0x00, 0xDD, 0x81, 0xA1, 0xD0, 0xFF, 0xFF, 0xC1, 0x81, 0xDD, 0x81, 0xA1, 0xD0, 0xFF, 0xFF,
+	 0x64, 0x40, 0x03, 0x36, 0x03, 0x00, 0xF2, 0x60, 0xDF, 0x78, 0xFF, 0xFF, 0xD9, 0x81, 0xA1, 0xD0,
+	 0x7F, 0xF3, 0xFF, 0xFF, 0xD0, 0x80, 0x20, 0xFE, 0x08, 0x24, 0x03, 0x00, 0xF2, 0x60, 0xDF, 0x78,
+	 0xFF, 0xFF, 0x26, 0x46, 0x3F, 0xF2, 0x00, 0xF4, 0x60, 0x43, 0xF4, 0xA3, 0x00, 0x60, 0x1D, 0x61,
+	 0x00, 0x60, 0x80, 0x65, 0x60, 0xFE, 0x81, 0xA1, 0x7F, 0xA1, 0x02, 0x06, 0x00, 0xF4, 0x03, 0x61,
+	 0xDD, 0x81, 0xA1, 0xD2, 0xCF, 0x83, 0xD4, 0x80, 0x2D, 0x03, 0x17, 0x03, 0xCF, 0x83, 0x61, 0x44,
+	 0x80, 0xA0, 0x28, 0x03, 0x02, 0x02, 0x00, 0xF4, 0x03, 0x61, 0xDD, 0x81, 0xA1, 0xD2, 0xCF, 0x83,
+	 0x81, 0xA1, 0x20, 0x03, 0x05, 0x07, 0x7F, 0xA1, 0xCC, 0x84, 0xDD, 0x81, 0xE4, 0x03, 0xF7, 0x01,
+	 0x00, 0xF4, 0x00, 0xB8, 0x04, 0x61, 0xE4, 0x03, 0xF2, 0x01, 0x01, 0x60, 0xFF, 0x63, 0x46, 0x48,
+	 0x41, 0x4A, 0xDD, 0x81, 0xA1, 0xD0, 0xDF, 0x83, 0xA3, 0xD9, 0x64, 0x44, 0xDD, 0x81, 0xA1, 0xD0,
+	 0xDF, 0x83, 0xA3, 0xD9, 0xCC, 0x84, 0x81, 0xA1, 0x05, 0x03, 0x7F, 0xA1, 0xF7, 0x04, 0x00, 0xF4,
+	 0x03, 0x61, 0xF4, 0x01, 0x20, 0xFE, 0x00, 0xBB, 0x02, 0x60, 0x00, 0x61, 0x45, 0x03, 0x60, 0xFE,
+	 0xDD, 0x81, 0xA1, 0xD1, 0xFF, 0xFF, 0x64, 0x40, 0x00, 0x3A, 0x3E, 0x00, 0xDD, 0x81, 0xA1, 0xD1,
+	 0xFF, 0xFF, 0x64, 0x40, 0x60, 0x3A, 0x38, 0x00, 0xDD, 0x81, 0xA1, 0xD1, 0xFF, 0xFF, 0x64, 0x40,
+	 0x1D, 0x3A, 0x32, 0x00, 0xDD, 0x81, 0xA1, 0xD3, 0xFF, 0xFF, 0x20, 0xFE, 0xFF, 0xB4, 0x1C, 0x60,
+	 0x96, 0x65, 0xA5, 0xD3, 0x60, 0x5C, 0x02, 0xA4, 0xA5, 0xDB, 0xFE, 0xA5, 0x1A, 0x60, 0xC6, 0x64,
+	 0x44, 0xD9, 0x00, 0x7C, 0x60, 0xFE, 0xDD, 0x81, 0xA1, 0xD1, 0xFF, 0xFF, 0x20, 0xFE, 0x1B, 0x60,
+	 0x06, 0x64, 0xC4, 0x82, 0x64, 0x44, 0xFF, 0xB4, 0xA2, 0xDB, 0x12, 0x60, 0x48, 0x65, 0x8A, 0xF3,
+	 0xFF, 0xFF, 0xC4, 0x82, 0x64, 0x44, 0xA2, 0xD3, 0xFF, 0xB5, 0xD4, 0x80, 0xFF, 0xFF, 0x02, 0x05,
+	 0x65, 0x44, 0xA2, 0xDB, 0x09, 0x00, 0x20, 0xFE, 0x28, 0x46, 0x2A, 0x41, 0xFF, 0xB1, 0x60, 0xFE,
+	 0x82, 0x64, 0xA1, 0xDA, 0xFF, 0xFF, 0x20, 0xFE, 0x26, 0x46, 0x3F, 0xF2, 0x00, 0xF4, 0x60, 0x43,
+	 0xF4, 0xA3, 0x00, 0x60, 0x1D, 0x61, 0x00, 0x60, 0xDD, 0x65, 0x60, 0xFE, 0x81, 0xA1, 0x7F, 0xA1,
+	 0x02, 0x06, 0x00, 0xF4, 0x03, 0x61, 0xDD, 0x81, 0xA1, 0xD2, 0xCF, 0x83, 0xD4, 0x80, 0x2D, 0x03,
+	 0x17, 0x03, 0xCF, 0x83, 0x61, 0x44, 0x80, 0xA0, 0x28, 0x03, 0x02, 0x02, 0x00, 0xF4, 0x03, 0x61,
+	 0xDD, 0x81, 0xA1, 0xD2, 0xCF, 0x83, 0x81, 0xA1, 0x20, 0x03, 0x05, 0x07, 0x7F, 0xA1, 0xCC, 0x84,
+	 0xDD, 0x81, 0xE4, 0x03, 0xF7, 0x01, 0x00, 0xF4, 0x00, 0xB8, 0x04, 0x61, 0xE4, 0x03, 0xF2, 0x01,
+	 0x02, 0x60, 0x00, 0x63, 0x46, 0x48, 0x41, 0x4A, 0xDD, 0x81, 0xA1, 0xD0, 0xDF, 0x83, 0xA3, 0xD9,
+	 0x64, 0x44, 0xDD, 0x81, 0xA1, 0xD0, 0xDF, 0x83, 0xA3, 0xD9, 0xCC, 0x84, 0x81, 0xA1, 0x05, 0x03,
+	 0x7F, 0xA1, 0xF7, 0x04, 0x00, 0xF4, 0x03, 0x61, 0xF4, 0x01, 0x20, 0xFE, 0x00, 0xBB, 0x02, 0x60,
+	 0x00, 0x61, 0x08, 0x24, 0xA6, 0x00, 0x2D, 0x60, 0xD6, 0x62, 0xA2, 0xDF, 0x2D, 0x60, 0xD8, 0x62,
+	 0xA2, 0xDF, 0x2D, 0x60, 0xDA, 0x62, 0xA2, 0xDF, 0x2D, 0x60, 0xDC, 0x62, 0xA2, 0xDF, 0x60, 0xFE,
+	 0xDD, 0x64, 0xA1, 0xDB, 0xDD, 0x81, 0xA1, 0xD3, 0xFF, 0xFF, 0xFA, 0xA4, 0xFF, 0xFF, 0x04, 0x34,
+	 0x9A, 0x01, 0xDD, 0x81, 0xA1, 0xD1, 0xFF, 0xFF, 0x64, 0x40, 0x00, 0x3A, 0x94, 0x01, 0xDD, 0x81,
+	 0xA1, 0xD1, 0xFF, 0xFF, 0x64, 0x40, 0x50, 0x3A, 0x8E, 0x01, 0xDD, 0x81, 0xA1, 0xD1, 0xFF, 0xFF,
+	 0x64, 0x40, 0xF2, 0x3A, 0x88, 0x01, 0xDD, 0x81, 0xA1, 0xD1, 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x3A,
+	 0xDC, 0x00, 0xDD, 0x81, 0xA1, 0xD1, 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x3A, 0xD6, 0x00, 0xDD, 0x81,
+	 0xA1, 0xD1, 0xFF, 0xFF, 0x64, 0x40, 0x00, 0x3A, 0xD0, 0x00, 0x60, 0x5C, 0x00, 0x36, 0x39, 0x00,
+	 0x00, 0x64, 0xF2, 0x60, 0x58, 0x4E, 0x57, 0x78, 0xFF, 0xFF, 0x65, 0x40, 0x08, 0x26, 0xF7, 0x01,
+	 0x2D, 0x60, 0xD6, 0x62, 0xA2, 0xDB, 0x64, 0x40, 0x00, 0x36, 0x31, 0x00, 0xDD, 0x81, 0xA1, 0xD3,
+	 0xDD, 0x81, 0xF2, 0x60, 0x58, 0x4E, 0x57, 0x78, 0xFF, 0xFF, 0x65, 0x40, 0x08, 0x26, 0xF5, 0x01,
+	 0x2D, 0x60, 0xD8, 0x62, 0xA2, 0xDB, 0x64, 0x40, 0x00, 0x36, 0x27, 0x00, 0xDD, 0x81, 0xA1, 0xD3,
+	 0xDD, 0x81, 0xF2, 0x60, 0x58, 0x4E, 0x57, 0x78, 0xFF, 0xFF, 0x65, 0x40, 0x08, 0x26, 0xF5, 0x01,
+	 0x2D, 0x60, 0xDA, 0x62, 0xA2, 0xDB, 0x64, 0x40, 0x00, 0x36, 0x1D, 0x00, 0xDD, 0x81, 0xA1, 0xD1,
+	 0x2D, 0x60, 0xDC, 0x62, 0xA2, 0xD9, 0xDD, 0x81, 0xA1, 0xD1, 0x2D, 0x60, 0xDD, 0x62, 0xA2, 0xD9,
+	 0x18, 0x00, 0x20, 0xFE, 0x2D, 0x60, 0xD6, 0x62, 0x00, 0x60, 0x04, 0x64, 0xA2, 0xDB, 0x20, 0xFE,
+	 0x2D, 0x60, 0xD8, 0x62, 0x00, 0x60, 0x04, 0x64, 0xA2, 0xDB, 0x20, 0xFE, 0x2D, 0x60, 0xDA, 0x62,
+	 0x00, 0x60, 0x02, 0x64, 0xA2, 0xDB, 0x20, 0xFE, 0x2D, 0x60, 0xDC, 0x62, 0x00, 0x60, 0x00, 0x64,
+	 0xA2, 0xDB, 0x20, 0xFE, 0x02, 0x60, 0x00, 0x65, 0x2D, 0x60, 0x9E, 0x63, 0xD5, 0x84, 0xDC, 0x84,
+	 0xBD, 0xDB, 0x60, 0x41, 0x66, 0x44, 0x63, 0x46, 0xCD, 0x83, 0xC7, 0x81, 0x60, 0x45, 0x60, 0xFE,
+	 0x5D, 0x93, 0xA3, 0xD3, 0x5D, 0x93, 0xA6, 0xDB, 0xDE, 0x86, 0xFA, 0x1F, 0x66, 0x43, 0x65, 0x46,
+	 0x20, 0xFE, 0x20, 0xFE, 0x2D, 0x60, 0xE4, 0x62, 0xA2, 0xD1, 0xFF, 0xFF, 0x64, 0x43, 0x00, 0x64,
+	 0x2D, 0x60, 0xCE, 0x61, 0xA1, 0xDB, 0x2D, 0x60, 0xC2, 0x62, 0xA2, 0xD1, 0x2D, 0x60, 0xD6, 0x62,
+	 0xA2, 0xD3, 0xFF, 0xFF, 0xA0, 0x84, 0xFF, 0xFF, 0x10, 0x26, 0x07, 0x00, 0x04, 0x26, 0x07, 0x00,
+	 0x20, 0x26, 0x07, 0x00, 0x02, 0x26, 0x07, 0x00, 0x48, 0x00, 0x10, 0x7C, 0x05, 0x00, 0x04, 0x7C,
+	 0x03, 0x00, 0x20, 0x7C, 0x01, 0x00, 0x02, 0x7C, 0x2D, 0x60, 0xCE, 0x61, 0xA1, 0xD9, 0x50, 0x94,
+	 0x2D, 0x60, 0xD0, 0x61, 0xA1, 0xDB, 0x2D, 0x60, 0xC4, 0x61, 0xA1, 0xD1, 0x2D, 0x60, 0xD8, 0x61,
+	 0xA1, 0xD3, 0x2D, 0x60, 0xCE, 0x61, 0xA0, 0x84, 0xA1, 0xD1, 0xFF, 0xFF, 0x10, 0x26, 0x05, 0x00,
+	 0x04, 0x26, 0x05, 0x00, 0x01, 0x26, 0x08, 0x00, 0x28, 0x00, 0x10, 0x7C, 0x06, 0x00, 0x64, 0x40,
+	 0x10, 0x26, 0x23, 0x00, 0x04, 0x7C, 0x01, 0x00, 0x01, 0x7C, 0x2D, 0x60, 0xD0, 0x61, 0xA1, 0xD9,
+	 0x50, 0x94, 0x2D, 0x60, 0xD2, 0x61, 0xA1, 0xDB, 0x2D, 0x60, 0xC6, 0x61, 0xA1, 0xD1, 0x2D, 0x60,
+	 0xDA, 0x61, 0xA1, 0xD3, 0xFF, 0xFF, 0xA0, 0x84, 0x60, 0x40, 0x02, 0x26, 0x05, 0x00, 0x04, 0x26,
+	 0x05, 0x00, 0x01, 0x26, 0x05, 0x00, 0x09, 0x00, 0x02, 0x7C, 0x03, 0x00, 0x04, 0x7C, 0x01, 0x00,
+	 0x20, 0x7C, 0x2D, 0x60, 0xD2, 0x61, 0xA1, 0xD9, 0x0D, 0x00, 0x50, 0x94, 0x2D, 0x60, 0xCE, 0x62,
+	 0xA2, 0xDB, 0x2D, 0x60, 0xD0, 0x62, 0xA2, 0xDB, 0x2D, 0x60, 0xD2, 0x62, 0xA2, 0xDB, 0x2D, 0x60,
+	 0xD4, 0x62, 0xA2, 0xDB, 0x7C, 0x44, 0x2D, 0x60, 0xCE, 0x61, 0xA1, 0xD1, 0xBD, 0xD9, 0x2D, 0x60,
+	 0xD0, 0x61, 0xA1, 0xD1, 0xB0, 0x84, 0xBD, 0xD9, 0x2D, 0x60, 0xD2, 0x61, 0xA1, 0xD1, 0xB0, 0x84,
+	 0xBD, 0xD9, 0x2D, 0x60, 0xC8, 0x61, 0xA1, 0xD1, 0xB0, 0x84, 0xBD, 0xD9, 0x08, 0x28, 0x68, 0x00,
+	 0x28, 0x60, 0x2C, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0xFF, 0xA0, 0xFF, 0xFF, 0x0C, 0x24, 0x60, 0x00,
+	 0x60, 0x40, 0x0B, 0x36, 0x5D, 0x00, 0x20, 0x40, 0x10, 0x27, 0x5A, 0x00, 0x88, 0x00, 0x20, 0xFE,
+	 0x00, 0x65, 0x60, 0xFE, 0x2D, 0x60, 0xDE, 0x62, 0xA2, 0xDB, 0xE0, 0x84, 0xE0, 0x84, 0x08, 0x20,
+	 0x03, 0x00, 0x01, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x02, 0xA5, 0x64, 0x44, 0xD4, 0x9C, 0xD4, 0x80,
+	 0x2D, 0x60, 0xE0, 0x62, 0x02, 0x05, 0x08, 0x65, 0x41, 0x00, 0xA2, 0xD9, 0x7C, 0x44, 0x2D, 0x60,
+	 0xE2, 0x62, 0xA2, 0xDB, 0xDD, 0x81, 0xA1, 0xD1, 0x00, 0x65, 0x64, 0x40, 0x00, 0x3A, 0x01, 0x65,
+	 0xDD, 0x81, 0xA1, 0xD1, 0xFF, 0xFF, 0x64, 0x40, 0x50, 0x3A, 0x01, 0x65, 0xDD, 0x81, 0xA1, 0xD1,
+	 0xFF, 0xFF, 0x64, 0x40, 0xF2, 0x3A, 0x01, 0x65, 0xDD, 0x81, 0xA1, 0xD1, 0x65, 0x40, 0x00, 0x3A,
+	 0x18, 0x00, 0x00, 0x60, 0x00, 0x65, 0x64, 0x40, 0x00, 0x36, 0x01, 0x65, 0x64, 0x40, 0x01, 0x36,
+	 0x02, 0x65, 0x64, 0x40, 0x02, 0x36, 0x04, 0x65, 0x64, 0x40, 0x04, 0x36, 0x10, 0x65, 0x64, 0x40,
+	 0x05, 0x36, 0x20, 0x65, 0x65, 0x5C, 0x2D, 0x60, 0xE2, 0x62, 0xA2, 0xD3, 0xFF, 0xFF, 0xB0, 0x84,
+	 0xA2, 0xDB, 0x2D, 0x60, 0xDE, 0x62, 0xA2, 0xD3, 0x00, 0x65, 0xFF, 0xA4, 0xA2, 0xDB, 0xCA, 0x02,
+	 0x2D, 0x60, 0xE2, 0x62, 0xA2, 0xD3, 0x2D, 0x60, 0xE0, 0x62, 0xA2, 0xD1, 0x2E, 0x58, 0xFF, 0xFF,
+	 0x20, 0xFE, 0x8A, 0xF3, 0xFF, 0xFF, 0x3A, 0xA4, 0x8A, 0xFB, 0x3D, 0x64, 0x3B, 0x42, 0x5A, 0xDB,
+	 0x89, 0xF3, 0x7F, 0xF1, 0x04, 0xA4, 0x89, 0xFB, 0x12, 0x60, 0x22, 0x63, 0x53, 0xF3, 0x64, 0x41,
+	 0x08, 0xB0, 0xE1, 0x85, 0x1C, 0x03, 0xFE, 0xA1, 0x47, 0xD3, 0x02, 0x06, 0xFB, 0xB4, 0xA3, 0xDB,
+	 0xDD, 0x81, 0x5B, 0xD3, 0x0C, 0x24, 0x02, 0x00, 0xFB, 0xB4, 0xA3, 0xDB, 0x5B, 0xD3, 0xDD, 0x81,
+	 0x02, 0xBC, 0xA3, 0xDB, 0x0E, 0x65, 0xDD, 0x81, 0xD5, 0x80, 0x5B, 0xD3, 0x08, 0x05, 0xFB, 0xB4,
+	 0xA3, 0xDB, 0xDD, 0x81, 0xD5, 0x80, 0x5B, 0xD3, 0x02, 0x03, 0xFB, 0xB4, 0xA3, 0xDB, 0xFF, 0xFF,
+	 0x20, 0xFE, 0x26, 0x46, 0x31, 0x40, 0x20, 0x2A, 0x18, 0x00, 0x3F, 0xF2, 0x47, 0x65, 0xC4, 0x84,
+	 0xE8, 0x84, 0x23, 0xFA, 0xF1, 0x60, 0x02, 0x64, 0x24, 0xFA, 0x24, 0x60, 0x74, 0x62, 0x24, 0x60,
+	 0x64, 0x64, 0xA2, 0xDB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0xFA, 0xFE, 0x00, 0x66, 0x46, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x26, 0x46, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x16, 0x63, 0x1C, 0x60, 0x8C, 0x62, 0x00, 0x64, 0x5A, 0xDB, 0xFE, 0x1F, 0x5B, 0xFB, 0x5C, 0xFB,
+	 0x1C, 0x60, 0x92, 0x63, 0x02, 0x64, 0xA3, 0xDB, 0x1A, 0x60, 0xC6, 0x62, 0x3E, 0x63, 0x00, 0x64,
+	 0x5A, 0xDB, 0xFE, 0x1F, 0x2E, 0x58, 0xFF, 0xFF, 0x1C, 0x60, 0x98, 0x62, 0xA2, 0xD3, 0x00, 0x63,
+	 0xF8, 0xA0, 0x01, 0xA4, 0x03, 0x03, 0xA2, 0xDB, 0x2E, 0x58, 0xFF, 0xFF, 0xA2, 0xDD, 0x1C, 0x60,
+	 0x9A, 0x62, 0xA2, 0xD1, 0xA2, 0xDD, 0x5A, 0xD3, 0xA2, 0xDD, 0xC0, 0x81, 0x61, 0x44, 0x02, 0x24,
+	 0xFF, 0xFF, 0xE9, 0x81, 0xE9, 0x81, 0xE9, 0x81, 0xE9, 0x81, 0x5A, 0xD3, 0xE9, 0x81, 0xE8, 0x83,
+	 0xEB, 0x83, 0xEB, 0x83, 0xEB, 0x83, 0xEB, 0x85, 0xD4, 0x85, 0xC5, 0x83, 0xA2, 0xDD, 0x1C, 0x60,
+	 0x8E, 0x62, 0x63, 0x47, 0x00, 0x7F, 0xA2, 0xDB, 0x2E, 0x58, 0xFF, 0xFF, 0x1C, 0x60, 0xA0, 0x65,
+	 0xA5, 0xDD, 0x1B, 0x60, 0x46, 0x65, 0x61, 0x44, 0x2B, 0x41, 0x45, 0xDB, 0x60, 0x41, 0x1B, 0x60,
+	 0x86, 0x65, 0x0A, 0xA3, 0xA3, 0xD1, 0x2B, 0x44, 0x44, 0xD9, 0x1C, 0x60, 0xA0, 0x65, 0xA5, 0xD3,
+	 0xFF, 0xFF, 0x60, 0x43, 0x00, 0xB9, 0xFF, 0xFF, 0x4C, 0x03, 0x06, 0xA3, 0xBD, 0xD1, 0x81, 0xF3,
+	 0x82, 0xF1, 0xD0, 0x80, 0xBD, 0xD3, 0x22, 0x02, 0x83, 0xF3, 0xD0, 0x80, 0xA3, 0xD1, 0x1E, 0x02,
+	 0xD0, 0x80, 0xFF, 0xFF, 0x1B, 0x02, 0x8A, 0xF3, 0x12, 0x60, 0x46, 0x63, 0xC6, 0xA5, 0x47, 0xD1,
+	 0x7F, 0xF3, 0xFF, 0xFF, 0xD0, 0x80, 0xFF, 0xFF, 0x08, 0x28, 0xFF, 0x61, 0x61, 0x43, 0x1A, 0x60,
+	 0xC6, 0x65, 0x2B, 0x44, 0x44, 0xD1, 0x1C, 0x60, 0x8E, 0x65, 0xA5, 0xD1, 0x64, 0x44, 0xD0, 0x81,
+	 0x1C, 0x60, 0x92, 0x65, 0x01, 0x05, 0x00, 0x61, 0xA5, 0xD3, 0x15, 0x00, 0x1A, 0x60, 0xC6, 0x65,
+	 0x2B, 0x44, 0x44, 0xD1, 0x1C, 0x60, 0x8E, 0x65, 0x64, 0x43, 0xA5, 0xD1, 0x64, 0x65, 0x63, 0x44,
+	 0xC0, 0x84, 0xD4, 0x80, 0xFF, 0xFF, 0x02, 0x06, 0x00, 0x61, 0x13, 0x00, 0x61, 0x43, 0xD0, 0x81,
+	 0x1C, 0x60, 0x92, 0x65, 0xA5, 0xD3, 0xE9, 0x81, 0xE9, 0x81, 0xCC, 0x84, 0xCC, 0x84, 0x02, 0x03,
+	 0x02, 0x03, 0xE9, 0x81, 0xE9, 0x81, 0xE9, 0x81, 0xE9, 0x85, 0xD7, 0x84, 0x60, 0x41, 0x01, 0x05,
+	 0x00, 0x61, 0x1C, 0x60, 0xA0, 0x65, 0xA5, 0xD3, 0xFF, 0xFF, 0x60, 0x43, 0x2E, 0x58, 0xFF, 0xFF,
+	 0x1C, 0x60, 0x94, 0x65, 0xA5, 0xD1, 0x5B, 0xF3, 0x64, 0x41, 0xCD, 0x81, 0xCD, 0x81, 0x02, 0x03,
+	 0x02, 0x03, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x85, 0x29, 0x44, 0x54, 0x89, 0x2E, 0x58,
+	 0xFF, 0xFF, 0xED, 0xF3, 0x1A, 0x60, 0xBE, 0x63, 0x0F, 0xB4, 0x01, 0xA4, 0xE0, 0x87, 0xE0, 0x84,
+	 0xE0, 0x84, 0xBD, 0xDB, 0x10, 0x60, 0x58, 0x64, 0xBD, 0xDB, 0x02, 0x64, 0xBD, 0xDB, 0x06, 0x64,
+	 0xA3, 0xDB, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0xBA, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB,
+	 0xFF, 0xFF, 0x04, 0xFF, 0x2E, 0x58, 0xFF, 0xFF, 0x1A, 0x60, 0xBE, 0x63, 0xEA, 0x60, 0x60, 0x64,
+	 0xBD, 0xDB, 0x10, 0x60, 0x58, 0x64, 0xBD, 0xDB, 0x02, 0x64, 0xBD, 0xDB, 0x06, 0x64, 0xA3, 0xDB,
+	 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60, 0xBA, 0x64, 0xA2, 0xDB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x04, 0xFF, 0x2E, 0x58, 0xFF, 0xFF, 0x16, 0x63, 0x1C, 0x60, 0x8C, 0x62, 0x00, 0x64, 0x5A, 0xDB,
+	 0xFE, 0x1F, 0x5B, 0xFB, 0x5C, 0xFB, 0x1C, 0x60, 0x92, 0x63, 0x02, 0x64, 0xA3, 0xDB, 0x1A, 0x60,
+	 0xC6, 0x62, 0x3E, 0x63, 0x00, 0x64, 0x5A, 0xDB, 0xFE, 0x1F, 0x10, 0x60, 0x56, 0x62, 0xF5, 0x60,
+	 0x29, 0x64, 0xA2, 0xDB, 0x10, 0x60, 0x2C, 0x62, 0xF5, 0x60, 0x15, 0x64, 0xA2, 0xDB, 0x10, 0x60,
+	 0x02, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x10, 0x60, 0x04, 0x62, 0x00, 0x60, 0x04, 0x64, 0xA2, 0xDB,
+	 0xF4, 0x60, 0x16, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x20, 0x44, 0x40, 0x26,
+	 0x03, 0x00, 0xF4, 0x60, 0xEA, 0x78, 0xFF, 0xFF, 0x20, 0x40, 0x52, 0x23, 0x07, 0x00, 0x5A, 0xF3,
+	 0xFF, 0xFF, 0x01, 0xA4, 0x5A, 0xFB, 0xF4, 0x60, 0xD7, 0x78, 0xFF, 0xFF, 0x40, 0x60, 0x00, 0x65,
+	 0x20, 0x44, 0x34, 0x80, 0x1C, 0x60, 0x92, 0x65, 0x02, 0x64, 0xA5, 0xDB, 0x1A, 0x60, 0xC4, 0x62,
+	 0x7E, 0x63, 0x00, 0x64, 0x5A, 0xDB, 0xFE, 0x1F, 0x1C, 0x60, 0x96, 0x62, 0xA2, 0xDD, 0x8C, 0xF3,
+	 0x58, 0xFB, 0x02, 0x64, 0x8C, 0xFB, 0xFF, 0xFF, 0xC1, 0xFE, 0x8C, 0xF3, 0xFF, 0xFF, 0x00, 0xA8,
+	 0xFF, 0xFF, 0x0B, 0x03, 0x10, 0x60, 0x04, 0x62, 0x80, 0x60, 0x00, 0x64, 0xA2, 0xDB, 0xF4, 0x60,
+	 0x3D, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x04, 0x64, 0x53, 0xFB, 0x29, 0x60,
+	 0xA4, 0x64, 0x54, 0xFB, 0x0F, 0x4E, 0xEC, 0x60, 0x58, 0x4F, 0xB9, 0x78, 0xFF, 0xFF, 0x0E, 0x4F,
+	 0x10, 0x60, 0x02, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x10, 0x60, 0x04, 0x62, 0x10, 0x60, 0x00, 0x64,
+	 0xA2, 0xDB, 0xF4, 0x60, 0x67, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x58, 0xF3,
+	 0x8C, 0xFB, 0xCA, 0xFE, 0xC1, 0xFE, 0x1C, 0x60, 0xA2, 0x62, 0x66, 0x44, 0xA2, 0xDB, 0x5A, 0xDD,
+	 0x61, 0x44, 0x5A, 0xDB, 0x67, 0xF5, 0xCC, 0xF1, 0x19, 0xF8, 0xF8, 0x60, 0x80, 0x64, 0x0E, 0xFA,
+	 0xA9, 0xF1, 0x07, 0xF8, 0x01, 0x60, 0x60, 0x67, 0x2C, 0xFA, 0x1D, 0x64, 0x2D, 0xFA, 0x01, 0x64,
+	 0x2E, 0xFA, 0xEB, 0xF1, 0x2F, 0xF8, 0xEC, 0xF1, 0x30, 0xF8, 0xED, 0xF1, 0x31, 0xF8, 0x81, 0xF1,
+	 0x32, 0xF8, 0x82, 0xF1, 0x33, 0xF8, 0x83, 0xF1, 0x34, 0xF8, 0x08, 0x64, 0x2A, 0xFA, 0x40, 0x63,
+	 0x3F, 0xFC, 0x00, 0xF4, 0x02, 0x62, 0xCB, 0x83, 0x00, 0x64, 0x5A, 0xDA, 0xFE, 0x1F, 0x1C, 0x60,
+	 0x8E, 0x65, 0xA5, 0xD3, 0x02, 0xFA, 0x19, 0x60, 0x88, 0x64, 0xA0, 0xD1, 0x0A, 0x61, 0x41, 0xD3,
+	 0x03, 0xFA, 0x06, 0x61, 0x06, 0x63, 0x00, 0x65, 0x1B, 0x60, 0x86, 0x64, 0x44, 0xD1, 0x59, 0xD8,
+	 0x1B, 0x60, 0x46, 0x64, 0x44, 0xD1, 0x59, 0xD8, 0x1A, 0x60, 0xC6, 0x64, 0x44, 0xD1, 0x59, 0xD8,
+	 0x1B, 0x60, 0x06, 0x64, 0x44, 0xD1, 0x59, 0xD8, 0x65, 0x44, 0x02, 0xA4, 0x60, 0x45, 0xEC, 0x1F,
+	 0x67, 0xF5, 0x24, 0x60, 0x74, 0x62, 0x24, 0x60, 0x22, 0x64, 0xA2, 0xDB, 0x66, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x1C, 0x60, 0xA2, 0x62, 0xA2, 0xD5, 0x5A, 0xD3,
+	 0x5A, 0xD3, 0x60, 0x43, 0x60, 0x41, 0x0F, 0x60, 0xEA, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x20, 0x64,
+	 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0xBF, 0x60, 0xFF, 0x65, 0x20, 0x44, 0x24, 0x80, 0xF3, 0x60,
+	 0x58, 0x4E, 0xD4, 0x78, 0xFF, 0xFF, 0x10, 0x60, 0x02, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x10, 0x60,
+	 0x04, 0x62, 0x10, 0x60, 0x02, 0x64, 0xA2, 0xDB, 0xF4, 0x60, 0x16, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x1C, 0x60, 0xA4, 0x63, 0x66, 0x44, 0xA3, 0xDB, 0x00, 0x60, 0x40, 0x61,
+	 0xAE, 0x60, 0x58, 0x4D, 0xC4, 0x78, 0xFF, 0xFF, 0x66, 0x44, 0x67, 0xFB, 0x04, 0x64, 0x03, 0xFA,
+	 0x1C, 0x60, 0xA4, 0x63, 0xA3, 0xD1, 0x00, 0x64, 0x64, 0x46, 0xA3, 0xDB, 0x00, 0x60, 0x40, 0x65,
+	 0x20, 0x44, 0x34, 0x80, 0xF3, 0x60, 0x58, 0x4E, 0xB9, 0x78, 0xFF, 0xFF, 0x10, 0x60, 0x02, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x10, 0x60, 0x04, 0x62, 0x00, 0x60, 0x02, 0x64, 0xA2, 0xDB, 0xF4, 0x60,
+	 0x16, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x24, 0x60, 0xAA, 0x62, 0x1A, 0x60,
+	 0xBA, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x10, 0x60, 0x02, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x5A, 0xDB, 0xFF, 0x60, 0x9F, 0x65, 0x20, 0x44, 0x24, 0x80, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x10, 0x60, 0x02, 0x62, 0xA2, 0xD1, 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+
+};  /* fw_image_4_data */
+
+static const CFG_IDENTITY_STRCT fw_image_infoidentity[] = {
+	{
+		sizeof( CFG_IDENTITY_STRCT ) / sizeof(hcf_16) - 1,
+		CFG_FW_IDENTITY,
+		COMP_ID_FW_STA,
+		3,							//Variant
+		2,							//Major
+		36							//Minor
+	},
+	{ 0000, 0000, 0000, 0000, 0000, 0000 }		//endsentinel
+};
+
+static const CFG_PROG_STRCT fw_image_code[] = {
+	{
+		8,
+		CFG_PROG,
+		CFG_PROG_VOLATILE,			// mode
+		0x0186,		// sizeof(fw_image_1_data),
+		0x00000060,					// Target address in NIC Memory
+		0x0000,						// CRC: yes/no	TYPE: primary/station/tertiary
+		(hcf_8 FAR   *) fw_image_1_data
+	},
+	{
+		8,
+		CFG_PROG,
+		CFG_PROG_VOLATILE,			// mode
+		0x2518,		// sizeof(fw_image_2_data),
+		0x00000C16,					// Target address in NIC Memory
+		0x0000,						// CRC: yes/no	TYPE: primary/station/tertiary
+		(hcf_8 FAR   *) fw_image_2_data
+	},
+	{
+		8,
+		CFG_PROG,
+		CFG_PROG_VOLATILE,			// mode
+		0x3daa,		// sizeof(fw_image_3_data),
+		0x001E312E,					// Target address in NIC Memory
+		0x0000,						// CRC: yes/no	TYPE: primary/station/tertiary
+		(hcf_8 FAR   *) fw_image_3_data
+	},
+	{
+		8,
+		CFG_PROG,
+		CFG_PROG_VOLATILE,			// mode
+		0xaa66,		// sizeof(fw_image_4_data),
+		0x001F4000,					// Target address in NIC Memory
+		0x0000,						// CRC: yes/no	TYPE: primary/station/tertiary
+		(hcf_8 FAR   *) fw_image_4_data
+	},
+	{
+		5,
+		CFG_PROG,
+		CFG_PROG_STOP,				// mode
+		0000,
+ 	0x000F368E,					// Start execution address
+	},
+	{ 0000, 0000, 0000, 0000, 00000000, 0000, 00000000}
+};
+
+static const CFG_RANGE20_STRCT fw_image_infocompat[] = {
+	{	3 + ((20 * sizeof(CFG_RANGE_SPEC_STRCT)) / sizeof(hcf_16)),
+		CFG_FW_SUP_RANGE,
+		COMP_ROLE_SUPL,
+		COMP_ID_STA,
+		{
+			{ 2, 2, 5 }  				//variant, bottom, top
+		}
+	},
+	{	3 + ((20 * sizeof(CFG_RANGE_SPEC_STRCT)) / sizeof(hcf_16)),
+		CFG_MFI_ACT_RANGES_STA,
+		COMP_ROLE_ACT,
+		COMP_ID_MFI,
+		{
+			{ 4, 6, 7 }, 				//variant, bottom, top
+			{ 5, 6, 7 }, 				//variant, bottom, top
+			{ 6, 6, 7 }  				//variant, bottom, top
+		}
+	},
+	{	3 + ((20 * sizeof(CFG_RANGE_SPEC_STRCT)) / sizeof(hcf_16)),
+		CFG_CFI_ACT_RANGES_STA,
+		COMP_ROLE_ACT,
+		COMP_ID_CFI,
+		{
+			{ 2, 1, 2 }  				//variant, bottom, top
+		}
+	},
+	{ 0000, 0000, 0000, 0000, { { 0000, 0000, 0000 } } }	//endsentinel
+};
+
+memimage fw_image = {
+	"FUPU7D37dhfwci\001C",			//signature, <format number>, C/Bin type
+	(CFG_PROG_STRCT *) fw_image_code,
+	0x000F368E,
+	00000000,					//(dummy) pdaplug
+	00000000,					//(dummy) priplug
+	(CFG_RANGE20_STRCT *) fw_image_infocompat,
+	(CFG_IDENTITY_STRCT *) fw_image_infoidentity,
+};
+
diff --git a/drivers/staging/wlags49_h2/sta_h25.c b/drivers/staging/wlags49_h2/sta_h25.c
new file mode 100644
index 0000000..86ca1cdd8
--- /dev/null
+++ b/drivers/staging/wlags49_h2/sta_h25.c
@@ -0,0 +1,5255 @@
+/*
+ * File:	sta_h54.136
+ *
+ * Abstract:	This file contains memory image 'fw_image'.
+ *
+ * Contents:	Total size of the memory image: 81742 bytes.
+ *		Total number of blocks: 4 blocks.
+ *		Block  1 : load address 00000060, 388 bytes.
+ *		Block  2 : load address 00000C16, 11278 bytes.
+ *		Block  3 : load address 001E3824, 21726 bytes.
+ *		Block  4 : load address 001F4000, 48350 bytes.
+ *
+ * Identity:	component id: 31 (variant 4) version 1.36
+ *
+ * Compatibility:
+ *		supplying interface 4 (variant 4) : 1 - 2
+ *		acting on interface 1 (variant 7) : 3 - 3
+ *		acting on interface 1 (variant 8) : 1 - 1
+ *		acting on interface 2 (variant 4) : 1 - 2
+ *
+ * Generated:	by g:\fw\fupu3.exe version 4.26
+ *
+ * Commandline:	g:\fw\fupu3.exe /f=4 /n=fw_image /i=r4013600.hex
+ */
+
+
+#include "hcfcfg.h"				// to get hcf_16 etc defined as well as
+                                // possible settings which inluence mdd.h or dhf.h
+#include "mdd.h"   				//to get COMP_ID_STA etc defined
+#include "dhf.h"   				//used to be "fhfmem.h", to get memblock,plugrecord,
+
+static const hcf_8 fw_image_1_data[] = {
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDA, 0x0C, 0x00, 0x00,
+	 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x65, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x1B, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB2, 0x1B, 0xB2, 0x1B,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+	 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA, 0x00, 0x00, 0xFF, 0x07,
+	 0x01, 0x00, 0x64, 0x00, 0x64, 0x00, 0x10, 0x27, 0x10, 0x27, 0x14, 0x00, 0xD0, 0x07, 0xD0, 0x07,
+	 0x10, 0x27, 0x2F, 0x00, 0x32, 0x00, 0x32, 0x00, 0x05, 0x00, 0x02, 0x00, 0x02, 0x00, 0x10, 0x27,
+	 0x05, 0x00, 0x00, 0x02, 0x00, 0x02, 0x13, 0x00, 0x07, 0x00, 0x03, 0x00, 0x32, 0x00, 0x02, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x09, 0x2B, 0x09, 0x2B, 0x09, 0xFF, 0x0F, 0xF0, 0x0F,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x01, 0x00, 0x40, 0x00, 0x32, 0x00, 0x32, 0x00, 0x0A, 0x00,
+	 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00,
+
+};  /* fw_image_1_data */
+
+static const hcf_8 fw_image_2_data[] = {
+	 0xF4, 0xA3, 0x00, 0x16, 0x08, 0x40, 0x0F, 0xD2, 0xE1, 0x28, 0xA5, 0x7C, 0x50, 0x30, 0xF1, 0x84,
+	 0x44, 0x08, 0xAB, 0xAE, 0xA5, 0xB8, 0xFC, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+	 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA5, 0xC6, 0x84, 0xF8, 0x99, 0xEE,
+	 0x8D, 0xF6, 0x0D, 0xFF, 0xBD, 0xD6, 0xB1, 0xDE, 0x54, 0x91, 0x50, 0x60, 0x03, 0x02, 0xA9, 0xCE,
+	 0x7D, 0x56, 0x19, 0xE7, 0x62, 0xB5, 0xE6, 0x4D, 0x9A, 0xEC, 0x45, 0x8F, 0x9D, 0x1F, 0x40, 0x89,
+	 0x87, 0xFA, 0x15, 0xEF, 0xEB, 0xB2, 0xC9, 0x8E, 0x0B, 0xFB, 0xEC, 0x41, 0x67, 0xB3, 0xFD, 0x5F,
+	 0xEA, 0x45, 0xBF, 0x23, 0xF7, 0x53, 0x96, 0xE4, 0x5B, 0x9B, 0xC2, 0x75, 0x1C, 0xE1, 0xAE, 0x3D,
+	 0x6A, 0x4C, 0x5A, 0x6C, 0x41, 0x7E, 0x02, 0xF5, 0x4F, 0x83, 0x5C, 0x68, 0xF4, 0x51, 0x34, 0xD1,
+	 0x08, 0xF9, 0x93, 0xE2, 0x73, 0xAB, 0x53, 0x62, 0x3F, 0x2A, 0x0C, 0x08, 0x52, 0x95, 0x65, 0x46,
+	 0x5E, 0x9D, 0x28, 0x30, 0xA1, 0x37, 0x0F, 0x0A, 0xB5, 0x2F, 0x09, 0x0E, 0x36, 0x24, 0x9B, 0x1B,
+	 0x3D, 0xDF, 0x26, 0xCD, 0x69, 0x4E, 0xCD, 0x7F, 0x9F, 0xEA, 0x1B, 0x12, 0x9E, 0x1D, 0x74, 0x58,
+	 0x2E, 0x34, 0x2D, 0x36, 0xB2, 0xDC, 0xEE, 0xB4, 0xFB, 0x5B, 0xF6, 0xA4, 0x4D, 0x76, 0x61, 0xB7,
+	 0xCE, 0x7D, 0x7B, 0x52, 0x3E, 0xDD, 0x71, 0x5E, 0x97, 0x13, 0xF5, 0xA6, 0x68, 0xB9, 0x00, 0x00,
+	 0x2C, 0xC1, 0x60, 0x40, 0x1F, 0xE3, 0xC8, 0x79, 0xED, 0xB6, 0xBE, 0xD4, 0x46, 0x8D, 0xD9, 0x67,
+	 0x4B, 0x72, 0xDE, 0x94, 0xD4, 0x98, 0xE8, 0xB0, 0x4A, 0x85, 0x6B, 0xBB, 0x2A, 0xC5, 0xE5, 0x4F,
+	 0x16, 0xED, 0xC5, 0x86, 0xD7, 0x9A, 0x55, 0x66, 0x94, 0x11, 0xCF, 0x8A, 0x10, 0xE9, 0x06, 0x04,
+	 0x81, 0xFE, 0xF0, 0xA0, 0x44, 0x78, 0xBA, 0x25, 0xE3, 0x4B, 0xF3, 0xA2, 0xFE, 0x5D, 0xC0, 0x80,
+	 0x8A, 0x05, 0xAD, 0x3F, 0xBC, 0x21, 0x48, 0x70, 0x04, 0xF1, 0xDF, 0x63, 0xC1, 0x77, 0x75, 0xAF,
+	 0x63, 0x42, 0x30, 0x20, 0x1A, 0xE5, 0x0E, 0xFD, 0x6D, 0xBF, 0x4C, 0x81, 0x14, 0x18, 0x35, 0x26,
+	 0x2F, 0xC3, 0xE1, 0xBE, 0xA2, 0x35, 0xCC, 0x88, 0x39, 0x2E, 0x57, 0x93, 0xF2, 0x55, 0x82, 0xFC,
+	 0x47, 0x7A, 0xAC, 0xC8, 0xE7, 0xBA, 0x2B, 0x32, 0x95, 0xE6, 0xA0, 0xC0, 0x98, 0x19, 0xD1, 0x9E,
+	 0x7F, 0xA3, 0x66, 0x44, 0x7E, 0x54, 0xAB, 0x3B, 0x83, 0x0B, 0xCA, 0x8C, 0x29, 0xC7, 0xD3, 0x6B,
+	 0x3C, 0x28, 0x79, 0xA7, 0xE2, 0xBC, 0x1D, 0x16, 0x76, 0xAD, 0x3B, 0xDB, 0x56, 0x64, 0x4E, 0x74,
+	 0x1E, 0x14, 0xDB, 0x92, 0x0A, 0x0C, 0x6C, 0x48, 0xE4, 0xB8, 0x5D, 0x9F, 0x6E, 0xBD, 0xEF, 0x43,
+	 0xA6, 0xC4, 0xA8, 0x39, 0xA4, 0x31, 0x37, 0xD3, 0x8B, 0xF2, 0x32, 0xD5, 0x43, 0x8B, 0x59, 0x6E,
+	 0xB7, 0xDA, 0x8C, 0x01, 0x64, 0xB1, 0xD2, 0x9C, 0xE0, 0x49, 0xB4, 0xD8, 0xFA, 0xAC, 0x07, 0xF3,
+	 0x25, 0xCF, 0xAF, 0xCA, 0x8E, 0xF4, 0xE9, 0x47, 0x18, 0x10, 0xD5, 0x6F, 0x88, 0xF0, 0x6F, 0x4A,
+	 0x72, 0x5C, 0x24, 0x38, 0xF1, 0x57, 0xC7, 0x73, 0x51, 0x97, 0x23, 0xCB, 0x7C, 0xA1, 0x9C, 0xE8,
+	 0x21, 0x3E, 0xDD, 0x96, 0xDC, 0x61, 0x86, 0x0D, 0x85, 0x0F, 0x90, 0xE0, 0x42, 0x7C, 0xC4, 0x71,
+	 0xAA, 0xCC, 0xD8, 0x90, 0x05, 0x06, 0x01, 0xF7, 0x12, 0x1C, 0xA3, 0xC2, 0x5F, 0x6A, 0xF9, 0xAE,
+	 0xD0, 0x69, 0x91, 0x17, 0x58, 0x99, 0x27, 0x3A, 0xB9, 0x27, 0x38, 0xD9, 0x13, 0xEB, 0xB3, 0x2B,
+	 0x33, 0x22, 0xBB, 0xD2, 0x70, 0xA9, 0x89, 0x07, 0xA7, 0x33, 0xB6, 0x2D, 0x22, 0x3C, 0x92, 0x15,
+	 0x20, 0xC9, 0x49, 0x87, 0xFF, 0xAA, 0x78, 0x50, 0x7A, 0xA5, 0x8F, 0x03, 0xF8, 0x59, 0x80, 0x09,
+	 0x17, 0x1A, 0xDA, 0x65, 0x31, 0xD7, 0xC6, 0x84, 0xB8, 0xD0, 0xC3, 0x82, 0xB0, 0x29, 0x77, 0x5A,
+	 0x11, 0x1E, 0xCB, 0x7B, 0xFC, 0xA8, 0xD6, 0x6D, 0x3A, 0x2C, 0x00, 0x30, 0x00, 0x31, 0x00, 0x33,
+	 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x38, 0x00, 0x3A, 0x00, 0x3B,
+	 0x00, 0x3C, 0x00, 0x3D, 0x00, 0x3E, 0x00, 0x3F, 0x00, 0x3F, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0x28, 0x10, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x01, 0x0A, 0x02, 0x14, 0x05, 0x32, 0x0B, 0x37, 0x08, 0x50, 0x0B, 0x6E,
+	 0x02, 0x00, 0x04, 0x00, 0x0B, 0x00, 0x16, 0x00, 0x0C, 0x00, 0x12, 0x00, 0x18, 0x00, 0x24, 0x00,
+	 0x30, 0x00, 0x48, 0x00, 0x60, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x39, 0x00, 0x20, 0x00, 0x39, 0x00, 0x39, 0x00, 0x20, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x10,
+	 0x3E, 0x11, 0xF6, 0x10, 0x38, 0x11, 0xFC, 0x10, 0x32, 0x11, 0x02, 0x11, 0x2C, 0x11, 0x08, 0x11,
+	 0x26, 0x11, 0x0E, 0x11, 0x20, 0x11, 0x14, 0x11, 0x1A, 0x11, 0x07, 0x01, 0x00, 0x00, 0x16, 0x22,
+	 0x00, 0x04, 0x08, 0x01, 0x00, 0x00, 0x16, 0x26, 0x00, 0x04, 0x09, 0x01, 0x00, 0x00, 0x16, 0x2A,
+	 0x00, 0x04, 0x0A, 0x01, 0x00, 0x00, 0x16, 0x2E, 0x00, 0x04, 0x0B, 0x01, 0x00, 0x00, 0x10, 0x24,
+	 0x04, 0x04, 0x0C, 0x01, 0x00, 0x00, 0x10, 0x28, 0x04, 0x04, 0x0D, 0x01, 0x00, 0x00, 0x10, 0x2C,
+	 0x04, 0x04, 0x0E, 0x01, 0x00, 0x00, 0x10, 0x30, 0x04, 0x04, 0x0F, 0x01, 0x00, 0x00, 0x14, 0x34,
+	 0x08, 0x84, 0x10, 0x01, 0x00, 0x00, 0x14, 0x38, 0x08, 0x84, 0x11, 0x01, 0x00, 0x00, 0x14, 0x3C,
+	 0x08, 0x84, 0x12, 0x01, 0x00, 0x00, 0x14, 0x40, 0x08, 0x84, 0x13, 0x01, 0x00, 0x00, 0x17, 0x64,
+	 0x0C, 0x8B, 0x14, 0x01, 0x00, 0x00, 0x17, 0x68, 0x0C, 0x8B, 0x15, 0x01, 0x00, 0x00, 0x17, 0x6C,
+	 0x0C, 0x8B, 0x16, 0x01, 0x00, 0x00, 0x17, 0x70, 0x0C, 0x8B, 0x17, 0x01, 0x00, 0x00, 0x17, 0x74,
+	 0x0C, 0x8B, 0x18, 0x01, 0x00, 0x00, 0x17, 0x78, 0x0C, 0x8B, 0x19, 0x01, 0x00, 0x00, 0x17, 0x7C,
+	 0x0C, 0x8B, 0x1A, 0x01, 0x00, 0x00, 0x17, 0x80, 0x0C, 0x8B, 0x1B, 0x01, 0x00, 0x00, 0x17, 0x84,
+	 0x0C, 0x8B, 0x1C, 0x01, 0x00, 0x00, 0x17, 0x88, 0x0C, 0x8B, 0x1D, 0x01, 0x00, 0x00, 0x17, 0x8C,
+	 0x0C, 0x8B, 0x1E, 0x01, 0x00, 0x00, 0x0E, 0x95, 0x17, 0x04, 0x1F, 0x01, 0x00, 0x00, 0x0E, 0x99,
+	 0x17, 0x04, 0x20, 0x01, 0x00, 0x00, 0x0E, 0x9D, 0x17, 0x04, 0x21, 0x01, 0x00, 0x00, 0x0E, 0xA1,
+	 0x17, 0x04, 0x22, 0x01, 0x00, 0x00, 0x0E, 0xA5, 0x00, 0x00, 0x60, 0x11, 0x80, 0x11, 0xA0, 0x11,
+	 0xC0, 0x11, 0x18, 0x12, 0x68, 0x11, 0x88, 0x11, 0xA8, 0x11, 0xC8, 0x11, 0x20, 0x12, 0x70, 0x11,
+	 0x90, 0x11, 0xB0, 0x11, 0xD0, 0x11, 0x28, 0x12, 0x78, 0x11, 0x98, 0x11, 0xB8, 0x11, 0xD8, 0x11,
+	 0x30, 0x12, 0xE0, 0x11, 0xE8, 0x11, 0xF0, 0x11, 0xF8, 0x11, 0x00, 0x12, 0x08, 0x12, 0x10, 0x12,
+	 0x38, 0x12, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x0A, 0x0A, 0x7F,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x1E, 0x1E, 0x1E, 0x1E,
+	 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x0A, 0x0A, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x10, 0x10,
+	 0x10, 0x10, 0x17, 0x17, 0x17, 0x17, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+	 0x7F, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
+	 0x14, 0x14, 0x14, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x11, 0x11, 0x11, 0x11, 0x7F, 0x7F, 0x7F, 0x7F,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E,
+	 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x16, 0x16,
+	 0x16, 0x16, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
+	 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x0A,
+	 0x0A, 0x0A, 0x0A, 0x7F, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
+	 0x14, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x10, 0x10, 0x10, 0x10, 0x7F, 0x14, 0x14,
+	 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x0A, 0x0A, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
+	 0x14, 0x14, 0x14, 0x14, 0x14, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+	 0x7F, 0x7F, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+	 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x9D, 0x9D, 0xA1, 0xB4,
+	 0x10, 0x10, 0x00, 0x9D, 0x08, 0x02, 0x06, 0x00, 0xA5, 0xA5, 0xAA, 0xB4, 0x10, 0x10, 0x00, 0xA2,
+	 0x15, 0x05, 0x07, 0x00, 0xAA, 0xAA, 0xB4, 0xB4, 0x10, 0x10, 0x00, 0xA7, 0x1C, 0x0A, 0x08, 0x00,
+	 0xB7, 0xB7, 0xC1, 0xC1, 0x10, 0x10, 0x00, 0xB4, 0x29, 0x17, 0x08, 0x00, 0xBD, 0xBD, 0xC7, 0xC7,
+	 0x10, 0x10, 0x00, 0xBA, 0x2F, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4, 0x1F, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x42, 0x2A, 0x5B, 0x2A, 0x7E, 0x2A, 0x71, 0x30, 0xEE, 0x29, 0x88, 0x30, 0xB8, 0x2A,
+	 0x9F, 0x30, 0xEE, 0x29, 0xEE, 0x29, 0xEE, 0x29, 0x21, 0x35, 0xEE, 0x29, 0xEE, 0x29, 0xEE, 0x29,
+	 0xEE, 0x29, 0xEE, 0x29, 0x93, 0x2C, 0xEE, 0x29, 0xEE, 0x29, 0xEE, 0x29, 0xEE, 0x29, 0xEE, 0x29,
+	 0xEE, 0x29, 0xEE, 0x29, 0xEE, 0x29, 0xEE, 0x29, 0xEE, 0x29, 0xEE, 0x29, 0xEE, 0x29, 0xEE, 0x29,
+	 0xEE, 0x29, 0xEE, 0x29, 0xDE, 0x2C, 0xEE, 0x29, 0xEE, 0x29, 0xEE, 0x29, 0xEE, 0x29, 0xEE, 0x29,
+	 0xEE, 0x29, 0xEE, 0x29, 0xEE, 0x29, 0xEE, 0x29, 0xEE, 0x29, 0xEE, 0x29, 0xEE, 0x29, 0xEE, 0x29,
+	 0xEE, 0x29, 0x61, 0x2C, 0x7C, 0x2C, 0xEE, 0x29, 0xEE, 0x29, 0xEE, 0x29, 0xEE, 0x29, 0xEE, 0x29,
+	 0xEE, 0x29, 0xE1, 0x27, 0xD7, 0x2A, 0xEA, 0x2A, 0x9A, 0x2B, 0x9E, 0x2B, 0xEE, 0x29, 0xEE, 0x29,
+	 0x4D, 0x2C, 0xA1, 0xF2, 0x62, 0xF2, 0x00, 0x00, 0x99, 0xF2, 0xEE, 0xF2, 0x12, 0xF3, 0x48, 0xF3,
+	 0x00, 0x00, 0x00, 0x00, 0x70, 0x2A, 0x94, 0x2A, 0x00, 0x00, 0x67, 0x30, 0x7E, 0x30, 0x95, 0x30,
+	 0xAF, 0x30, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFC, 0x45, 0x2D, 0xF7, 0x2F, 0x5A, 0x00, 0x02, 0x00,
+	 0xF9, 0xFF, 0x45, 0x2D, 0x5B, 0x2D, 0xFC, 0x00, 0x02, 0x00, 0xF7, 0xFF, 0x45, 0x2D, 0x5B, 0x2D,
+	 0xAA, 0x2D, 0x06, 0x00, 0xF0, 0xFF, 0x45, 0x2D, 0x22, 0x2D, 0x00, 0x00, 0x00, 0x02, 0xF6, 0xFF,
+	 0x45, 0x2D, 0x5B, 0x2D, 0x6C, 0x00, 0x02, 0x00, 0xF4, 0xFF, 0x45, 0x2D, 0x5B, 0x2D, 0xA6, 0x01,
+	 0x02, 0x00, 0xF5, 0xFF, 0x45, 0x2D, 0x00, 0x30, 0x9C, 0x2D, 0x02, 0x00, 0xED, 0xFF, 0x45, 0x2D,
+	 0x12, 0x30, 0x98, 0x32, 0x02, 0x00, 0xEC, 0xFF, 0x45, 0x2D, 0x40, 0x30, 0x9A, 0x32, 0x02, 0x00,
+	 0xEB, 0xFF, 0x45, 0x2D, 0x46, 0x30, 0x9C, 0x32, 0x02, 0x00, 0xEE, 0xFF, 0x45, 0x2D, 0x4C, 0x30,
+	 0x12, 0x33, 0x02, 0x00, 0xDA, 0xFF, 0x45, 0x2D, 0x5B, 0x2D, 0xF2, 0x13, 0x0C, 0x00, 0xEA, 0xFF,
+	 0x45, 0x2D, 0x22, 0x2D, 0x4C, 0x33, 0x06, 0x00, 0xE9, 0xFF, 0x45, 0x2D, 0x5B, 0x2D, 0x52, 0x33,
+	 0x02, 0x00, 0xE8, 0xFF, 0x45, 0x2D, 0x5B, 0x2D, 0x54, 0x33, 0x02, 0x00, 0xE7, 0xFF, 0x45, 0x2D,
+	 0x5B, 0x2D, 0x56, 0x33, 0x02, 0x00, 0xE6, 0xFF, 0x45, 0x2D, 0x5B, 0x2D, 0x58, 0x33, 0x02, 0x00,
+	 0xE5, 0xFF, 0x45, 0x2D, 0x5B, 0x2D, 0x5A, 0x33, 0x10, 0x00, 0xE4, 0xFF, 0x45, 0x2D, 0x5B, 0x2D,
+	 0x6A, 0x33, 0x18, 0x00, 0xDB, 0xFF, 0x45, 0x2D, 0x5B, 0x2D, 0x82, 0x33, 0x02, 0x00, 0xDC, 0xFF,
+	 0x45, 0x2D, 0x5B, 0x2D, 0x84, 0x33, 0x02, 0x00, 0xE1, 0xFF, 0x45, 0x2D, 0x5B, 0x2D, 0x5A, 0x34,
+	 0x02, 0x00, 0xE0, 0xFF, 0x45, 0x2D, 0x5B, 0x2D, 0x58, 0x34, 0x02, 0x00, 0xE3, 0xFF, 0x45, 0x2D,
+	 0x5B, 0x2D, 0x3C, 0x34, 0x02, 0x00, 0xE2, 0xFF, 0x93, 0x2D, 0x22, 0x2D, 0xF2, 0x33, 0x24, 0x00,
+	 0x03, 0xFC, 0x45, 0x2D, 0x01, 0x2F, 0x8C, 0x32, 0x02, 0x00, 0x04, 0xFC, 0x45, 0x2D, 0x55, 0x2D,
+	 0xB4, 0x2D, 0x22, 0x00, 0x06, 0xFC, 0x45, 0x2D, 0x5B, 0x2D, 0x9A, 0x2D, 0x02, 0x00, 0x07, 0xFC,
+	 0x45, 0x2D, 0x5B, 0x2D, 0xF8, 0x2D, 0x02, 0x00, 0x0E, 0xFC, 0x45, 0x2D, 0x2A, 0x2F, 0x02, 0x2E,
+	 0x22, 0x00, 0xB1, 0xFC, 0x45, 0x2D, 0x39, 0x31, 0x00, 0x2F, 0x02, 0x00, 0x20, 0xFC, 0x45, 0x2D,
+	 0x5B, 0x2D, 0x28, 0x2E, 0x02, 0x00, 0x25, 0xFC, 0x45, 0x2D, 0x5B, 0x2D, 0x34, 0x2E, 0x02, 0x00,
+	 0x26, 0xFC, 0x45, 0x2D, 0x5B, 0x2D, 0x36, 0x2E, 0x02, 0x00, 0x27, 0xFC, 0x45, 0x2D, 0x5B, 0x2D,
+	 0x38, 0x2E, 0x02, 0x00, 0xB2, 0xFC, 0x45, 0x2D, 0x55, 0x2D, 0x24, 0x2F, 0x22, 0x00, 0xC1, 0xFC,
+	 0x45, 0x2D, 0x5B, 0x2D, 0x9E, 0x33, 0x20, 0x00, 0xB0, 0xFC, 0x18, 0x2D, 0x3D, 0x31, 0x00, 0x00,
+	 0x00, 0x00, 0xC4, 0xFC, 0x18, 0x2D, 0x57, 0x30, 0x00, 0x00, 0x08, 0x00, 0xC8, 0xFC, 0x18, 0x2D,
+	 0x55, 0x30, 0x00, 0x00, 0x08, 0x00, 0xB4, 0xFC, 0x18, 0x2D, 0x71, 0x31, 0x00, 0x00, 0x00, 0x00,
+	 0xB6, 0xFC, 0x18, 0x2D, 0x19, 0x32, 0x00, 0x00, 0x00, 0x00, 0xB7, 0xFC, 0x18, 0x2D, 0x43, 0x32,
+	 0x00, 0x00, 0x00, 0x00, 0xB8, 0xFC, 0x18, 0x2D, 0x99, 0x32, 0x00, 0x00, 0x00, 0x00, 0xBC, 0xFC,
+	 0x18, 0x2D, 0xD2, 0x32, 0x00, 0x00, 0x00, 0x00, 0xBD, 0xFC, 0x18, 0x2D, 0x58, 0x33, 0x00, 0x00,
+	 0x00, 0x00, 0xBE, 0xFC, 0x18, 0x2D, 0x82, 0x33, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFC, 0x18, 0x2D,
+	 0xCF, 0x33, 0x00, 0x00, 0x00, 0x00, 0xB3, 0xFC, 0x45, 0x2D, 0x5B, 0x2D, 0xA0, 0x0F, 0x10, 0x00,
+	 0xB5, 0xFC, 0x45, 0x2D, 0x5B, 0x2D, 0x38, 0x34, 0x02, 0x00, 0xB9, 0xFC, 0x45, 0x2D, 0x5B, 0x2D,
+	 0x3A, 0x34, 0x02, 0x00, 0x90, 0xFD, 0x45, 0x2D, 0x22, 0x2D, 0x3E, 0x34, 0x02, 0x00, 0x88, 0xFC,
+	 0x45, 0x2D, 0x5B, 0x2D, 0x72, 0x32, 0x04, 0x00, 0x89, 0xFC, 0x45, 0x2D, 0x5B, 0x2D, 0x76, 0x32,
+	 0x04, 0x00, 0xC5, 0xFC, 0x45, 0x2D, 0x5B, 0x2D, 0x7A, 0x32, 0x04, 0x00, 0x23, 0xFC, 0x45, 0x2D,
+	 0x5B, 0x2D, 0x2E, 0x2E, 0x04, 0x00, 0x2A, 0xFC, 0x45, 0x2D, 0xE9, 0x2D, 0xB0, 0x2D, 0x02, 0x00,
+	 0xC7, 0xFD, 0x45, 0x2D, 0x22, 0x2D, 0xA0, 0x32, 0x0A, 0x00, 0x29, 0xFC, 0x3C, 0x2E, 0x00, 0x2E,
+	 0x00, 0x00, 0x00, 0x00, 0xC2, 0xFC, 0x45, 0x2D, 0x5B, 0x2D, 0x80, 0x32, 0x08, 0x00, 0x32, 0xFC,
+	 0x45, 0x2D, 0x5B, 0x2D, 0x98, 0x01, 0x02, 0x00, 0x33, 0xFC, 0x45, 0x2D, 0x5B, 0x2D, 0x9A, 0x01,
+	 0x02, 0x00, 0x35, 0xFC, 0x45, 0x2D, 0x5B, 0x2D, 0x88, 0x32, 0x02, 0x00, 0xC7, 0xFC, 0x45, 0x2D,
+	 0xD3, 0x2F, 0x8A, 0x32, 0x02, 0x00, 0x00, 0xFC, 0x45, 0x2D, 0x5B, 0x2D, 0xB2, 0x2D, 0x02, 0x00,
+	 0x01, 0xFC, 0x45, 0x2D, 0x5B, 0x2D, 0xAA, 0x2D, 0x06, 0x00, 0x02, 0xFC, 0x45, 0x2D, 0xD5, 0x2D,
+	 0x02, 0x2F, 0x22, 0x00, 0x05, 0xFC, 0x45, 0x2D, 0x5B, 0x2D, 0xA0, 0x2D, 0x02, 0x00, 0x08, 0xFC,
+	 0x45, 0x2D, 0x5B, 0x2D, 0xA4, 0x2D, 0x06, 0x00, 0x09, 0xFC, 0x45, 0x2D, 0x5B, 0x2D, 0xFA, 0x2D,
+	 0x02, 0x00, 0x0B, 0xFC, 0x45, 0x2D, 0x5B, 0x2D, 0xFC, 0x2D, 0x02, 0x00, 0x0C, 0xFC, 0x45, 0x2D,
+	 0x5B, 0x2D, 0xFE, 0x2D, 0x02, 0x00, 0x0D, 0xFC, 0x45, 0x2D, 0x5B, 0x2D, 0x00, 0x2E, 0x02, 0x00,
+	 0x21, 0xFC, 0x45, 0x2D, 0x5B, 0x2D, 0x2A, 0x2E, 0x02, 0x00, 0x80, 0xFC, 0xB1, 0x2D, 0xC1, 0x2D,
+	 0x40, 0x2E, 0xC0, 0x00, 0x81, 0xFC, 0x45, 0x2D, 0x5B, 0x2D, 0xA4, 0x01, 0x02, 0x00, 0x83, 0xFC,
+	 0x45, 0x2D, 0x5B, 0x2D, 0xA8, 0x01, 0x02, 0x00, 0x85, 0xFC, 0x45, 0x2D, 0x4A, 0x2F, 0xA0, 0x01,
+	 0x02, 0x00, 0x86, 0xFC, 0x45, 0x2D, 0x6E, 0x2F, 0xB0, 0x01, 0x02, 0x00, 0x28, 0xFC, 0x45, 0x2D,
+	 0x5B, 0x2D, 0x3A, 0x2E, 0x02, 0x00, 0x90, 0xFC, 0x45, 0x2D, 0x5C, 0x2F, 0xA2, 0x01, 0x02, 0x00,
+	 0x87, 0xFC, 0x45, 0x2D, 0x8C, 0x2F, 0x50, 0x2F, 0x22, 0x03, 0x30, 0xFC, 0x45, 0x2D, 0x5B, 0x2D,
+	 0x3C, 0x2E, 0x02, 0x00, 0x84, 0xFC, 0x45, 0x2D, 0x92, 0x2F, 0xAC, 0x01, 0x04, 0x00, 0x2B, 0xFC,
+	 0x45, 0x2D, 0x5B, 0x2D, 0xE2, 0x37, 0x02, 0x00, 0xF8, 0xFF, 0x45, 0x2D, 0x5B, 0x2D, 0xDC, 0x37,
+	 0x02, 0x00, 0xF3, 0xFF, 0x45, 0x2D, 0x5B, 0x2D, 0xE4, 0x37, 0x02, 0x00, 0x20, 0xFD, 0x76, 0x2D,
+	 0x22, 0x2D, 0x5E, 0x40, 0x08, 0x00, 0x21, 0xFD, 0x76, 0x2D, 0x22, 0x2D, 0x62, 0x40, 0x0A, 0x00,
+	 0x22, 0xFD, 0x76, 0x2D, 0x22, 0x2D, 0x67, 0x40, 0x16, 0x00, 0x23, 0xFD, 0x76, 0x2D, 0x22, 0x2D,
+	 0x72, 0x40, 0x0A, 0x00, 0x45, 0xFD, 0x45, 0x2D, 0x22, 0x2D, 0xFC, 0x00, 0x02, 0x00, 0x47, 0xFD,
+	 0x45, 0x2D, 0x22, 0x2D, 0x72, 0x01, 0x02, 0x00, 0x48, 0xFD, 0x91, 0x2E, 0x22, 0x2D, 0x98, 0x01,
+	 0x02, 0x00, 0x49, 0xFD, 0x91, 0x2E, 0x22, 0x2D, 0x9A, 0x01, 0x02, 0x00, 0x4A, 0xFD, 0x45, 0x2D,
+	 0x22, 0x2D, 0x92, 0x01, 0x02, 0x00, 0x4B, 0xFD, 0x45, 0x2D, 0x22, 0x2D, 0x94, 0x01, 0x02, 0x00,
+	 0x4D, 0xFD, 0x76, 0x2D, 0x22, 0x2D, 0x77, 0x40, 0x0C, 0x00, 0x4F, 0xFD, 0xA5, 0x2E, 0x22, 0x2D,
+	 0x90, 0x32, 0x02, 0x00, 0xC2, 0xFD, 0x9B, 0x2E, 0x22, 0x2D, 0x00, 0x00, 0x02, 0x00, 0x40, 0xFD,
+	 0x6E, 0x2D, 0x22, 0x2D, 0xB6, 0x01, 0x02, 0x00, 0x24, 0xFD, 0xB5, 0x2E, 0x22, 0x2D, 0x00, 0x00,
+	 0x02, 0x00, 0x91, 0xFD, 0x45, 0x2D, 0x22, 0x2D, 0xC6, 0x25, 0x02, 0x00, 0x93, 0xFD, 0x45, 0x2D,
+	 0x22, 0x2D, 0xCC, 0x25, 0x02, 0x00, 0x8F, 0xFD, 0xD5, 0x2E, 0x22, 0x2D, 0x00, 0x00, 0x08, 0x00,
+	 0xC1, 0xFD, 0x00, 0x31, 0x22, 0x2D, 0xFA, 0x00, 0x02, 0x00, 0xC6, 0xFD, 0x45, 0x2D, 0x22, 0x2D,
+	 0xF8, 0x37, 0x04, 0x00, 0x25, 0xFD, 0x45, 0x2D, 0x22, 0x2D, 0x9E, 0x01, 0x02, 0x00, 0x89, 0xFD,
+	 0xB9, 0x30, 0x22, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x8A, 0xFD, 0x93, 0x2D, 0x22, 0x2D, 0x12, 0x34,
+	 0x24, 0x00, 0x41, 0xFD, 0x45, 0x2D, 0x22, 0x2D, 0xBE, 0x33, 0x22, 0x00, 0x42, 0xFD, 0x45, 0x2D,
+	 0x22, 0x2D, 0xFE, 0x00, 0x06, 0x00, 0x43, 0xFD, 0xC2, 0x2E, 0x22, 0x2D, 0x00, 0x00, 0x06, 0x00,
+	 0x44, 0xFD, 0xAC, 0x2E, 0x22, 0x2D, 0xB2, 0x01, 0x02, 0x00, 0x46, 0xFD, 0x21, 0x31, 0x22, 0x2D,
+	 0x00, 0x00, 0x00, 0x00, 0x4C, 0xFD, 0x45, 0x2D, 0x22, 0x2D, 0x46, 0x2F, 0x02, 0x00, 0x50, 0xFD,
+	 0x45, 0x2D, 0x22, 0x2D, 0xF2, 0x00, 0x02, 0x00, 0x51, 0xFD, 0x45, 0x2D, 0x22, 0x2D, 0xF4, 0x00,
+	 0x02, 0x00, 0x52, 0xFD, 0x45, 0x2D, 0x22, 0x2D, 0xC4, 0x01, 0x02, 0x00, 0x8C, 0xFD, 0x38, 0x2D,
+	 0x22, 0x2D, 0x98, 0x34, 0x56, 0x00, 0x8D, 0xFD, 0x38, 0x2D, 0x22, 0x2D, 0xF2, 0x34, 0x14, 0x00,
+	 0x00, 0xF1, 0x46, 0x00, 0xDC, 0x2C, 0x36, 0x01, 0x01, 0xF1, 0x84, 0x07, 0xDA, 0x2C, 0x38, 0x01,
+	 0x00, 0x03, 0xA0, 0x80, 0x1E, 0x00, 0x70, 0x01, 0xFA, 0x00, 0xD4, 0x01, 0xFE, 0x00, 0x3A, 0x01,
+	 0xB6, 0x01, 0xCC, 0x2C, 0x54, 0x01, 0xC6, 0x25, 0x20, 0x00, 0x00, 0x00, 0xC0, 0x1D, 0x00, 0x00,
+	 0xC4, 0x1F, 0x4E, 0x01, 0x0B, 0x00, 0xB8, 0x00, 0xEC, 0x00, 0x44, 0x00, 0x46, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x1C, 0x09, 0x08, 0x24, 0x28, 0x06, 0x0C, 0x18, 0x08, 0x30, 0x14, 0x0C,
+	 0x08, 0x36, 0x10, 0x12, 0x24, 0xB7, 0x97, 0xB6, 0xA3, 0xB7, 0xAC, 0xB7, 0xA8, 0xB6, 0x3E, 0xB7,
+	 0x16, 0xB7, 0x79, 0x3E, 0x57, 0x3D, 0x79, 0x3E, 0xF9, 0x3D, 0x5F, 0x3D, 0x52, 0x3D, 0x33, 0x3E,
+	 0x55, 0x3E, 0x6A, 0x3E, 0xAC, 0x3E, 0xD8, 0x3E, 0xF8, 0x3D, 0x22, 0x46, 0x22, 0x46, 0x22, 0x46,
+	 0x22, 0x46, 0x22, 0x46, 0x22, 0x46, 0x22, 0x46, 0x22, 0x46, 0x22, 0x46, 0x22, 0x46, 0x22, 0x46,
+	 0x23, 0x46, 0x23, 0x46, 0x23, 0x46, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47,
+	 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47, 0x1C, 0x47,
+	 0x1D, 0x47, 0x9A, 0x48, 0xDA, 0x48, 0x1A, 0x48, 0x5A, 0x48, 0x9A, 0x48, 0xDA, 0x48, 0x1A, 0x48,
+	 0x5A, 0x48, 0x9A, 0x48, 0xDA, 0x48, 0x1A, 0x48, 0x5A, 0x48, 0x9A, 0x48, 0x33, 0x48, 0x78, 0x49,
+	 0x78, 0x49, 0x79, 0x49, 0x79, 0x49, 0x79, 0x49, 0x79, 0x49, 0x7A, 0x49, 0x7A, 0x49, 0x7A, 0x49,
+	 0x7A, 0x49, 0x7B, 0x49, 0x7B, 0x49, 0x7B, 0x49, 0x7C, 0x49, 0xD8, 0x03, 0xDC, 0x03, 0xE0, 0x03,
+	 0xE4, 0x03, 0xF0, 0x03, 0xF4, 0x03, 0xF8, 0x03, 0x0A, 0x04, 0x0E, 0x04, 0x12, 0x04, 0x16, 0x04,
+	 0x0C, 0x04, 0x10, 0x04, 0x14, 0x04, 0x18, 0x04, 0x1C, 0x04, 0x20, 0x04, 0x24, 0x04, 0x28, 0x04,
+	 0x4C, 0x04, 0x50, 0x04, 0x54, 0x04, 0x58, 0x04, 0x5C, 0x04, 0x60, 0x04, 0x64, 0x04, 0x68, 0x04,
+	 0x6C, 0x04, 0x70, 0x04, 0x74, 0x04, 0x7D, 0x04, 0x81, 0x04, 0x85, 0x04, 0x89, 0x04, 0x8D, 0x04,
+	 0x10, 0x00, 0x8E, 0x19, 0xAC, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3C, 0x0C, 0x00, 0x00,
+	 0xFF, 0x3F, 0x44, 0x04, 0x00, 0x00, 0xD3, 0x22, 0x44, 0x04, 0x9C, 0x02, 0xCB, 0x54, 0x44, 0x04,
+	 0x00, 0x00, 0x01, 0x00, 0x44, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x0C, 0x71, 0x00, 0x30, 0x50,
+	 0x20, 0x00, 0x80, 0xBF, 0x1F, 0xA6, 0x28, 0x00, 0x0B, 0x02, 0x60, 0x84, 0x4C, 0x00, 0x02, 0x00,
+	 0x4B, 0x1C, 0x98, 0x00, 0x00, 0x00, 0x20, 0x0B, 0x34, 0x04, 0xFD, 0x34, 0x34, 0x00, 0x38, 0x04,
+	 0xFD, 0x34, 0x34, 0x00, 0x3C, 0x04, 0x01, 0x00, 0x10, 0x00, 0x00, 0x08, 0x00, 0x52, 0x14, 0x00,
+	 0x04, 0x08, 0x0E, 0x32, 0x00, 0xA6, 0x10, 0x08, 0xC4, 0x03, 0x50, 0x60, 0x18, 0x08, 0xF0, 0x3F,
+	 0xFC, 0x01, 0x10, 0x0C, 0x00, 0x00, 0x80, 0x04, 0x14, 0x0C, 0x00, 0x00, 0x00, 0x41, 0x20, 0x0C,
+	 0xB0, 0x00, 0xB0, 0xB8, 0x24, 0x0C, 0x00, 0x00, 0xAB, 0x05, 0x2C, 0x0C, 0x80, 0x05, 0x00, 0xFF,
+	 0x30, 0x0C, 0x00, 0x00, 0xB0, 0x04, 0x34, 0x0C, 0x03, 0x00, 0x00, 0xE8, 0x44, 0x0C, 0x04, 0x00,
+	 0xFF, 0x0F, 0x00, 0x10, 0x2E, 0x00, 0x0C, 0xE3, 0x44, 0x04, 0x00, 0x00, 0x01, 0x04, 0x44, 0x04,
+	 0x00, 0x00, 0x01, 0x01, 0x44, 0x04, 0x00, 0x00, 0x01, 0x00, 0x44, 0x04, 0x00, 0x00, 0x01, 0x04,
+	 0x44, 0x04, 0x00, 0x00, 0x80, 0x03, 0x48, 0x0C, 0x00, 0x00, 0x7F, 0x00, 0x04, 0x04, 0x08, 0x48,
+	 0x00, 0x00, 0x04, 0x04, 0x08, 0x40, 0x00, 0x00, 0x00, 0x0C, 0x71, 0x00, 0x30, 0x30, 0x00, 0x00,
+	 0x5E, 0x40, 0x01, 0x00, 0x18, 0x00, 0x36, 0xC0, 0xE8, 0x0E, 0x1C, 0x00, 0x78, 0xC8, 0xA5, 0x40,
+	 0x24, 0x00, 0x9E, 0xB0, 0xB9, 0x95, 0x08, 0x08, 0x00, 0xEA, 0x40, 0x01, 0x0C, 0x08, 0x00, 0xEA,
+	 0x00, 0x00, 0x1C, 0x08, 0x00, 0x00, 0x42, 0x07, 0x20, 0x08, 0x7B, 0x00, 0xD4, 0x09, 0x2C, 0x04,
+	 0x14, 0x00, 0x50, 0x14, 0x30, 0x04, 0x28, 0x0F, 0x28, 0x7F, 0x18, 0x08, 0x20, 0x00, 0xFC, 0x01,
+	 0x04, 0x10, 0x69, 0x00, 0xFD, 0xC3, 0x08, 0x10, 0x69, 0x00, 0xFD, 0xC3, 0x08, 0x0C, 0x00, 0x00,
+	 0x00, 0x00, 0x48, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x48, 0x0C, 0x00, 0x00, 0x7F, 0x00, 0x04, 0x04,
+	 0x08, 0x48, 0x02, 0x00, 0x00, 0x00, 0x5E, 0x48, 0x00, 0x00, 0x04, 0x04, 0x08, 0x40, 0x02, 0x00,
+	 0x00, 0x0C, 0x71, 0x00, 0x30, 0x50, 0x00, 0x00, 0x5E, 0x48, 0x01, 0x00, 0x18, 0x00, 0x3A, 0xC0,
+	 0xE8, 0x04, 0x1C, 0x00, 0x78, 0xD0, 0xA5, 0x40, 0x24, 0x00, 0x9E, 0xB0, 0xB9, 0x85, 0x2C, 0x04,
+	 0x14, 0x00, 0x50, 0x14, 0x30, 0x04, 0x28, 0x0F, 0x28, 0x7F, 0x08, 0x08, 0x00, 0xEA, 0x40, 0x01,
+	 0x0C, 0x08, 0x00, 0xEA, 0x00, 0x00, 0x1C, 0x08, 0x00, 0x00, 0x42, 0x07, 0x20, 0x08, 0x7B, 0x00,
+	 0xD4, 0x09, 0x18, 0x08, 0xF0, 0x3F, 0xFC, 0x01, 0x04, 0x10, 0x69, 0x00, 0xDD, 0xCD, 0x08, 0x10,
+	 0x69, 0x00, 0xDD, 0xCD, 0x08, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x48, 0x0C, 0x00, 0x00, 0x00, 0x00,
+	 0x08, 0x04, 0x40, 0x01, 0x41, 0x01, 0x0C, 0x04, 0x40, 0x04, 0x41, 0x04, 0x10, 0x04, 0xD6, 0x08,
+	 0x56, 0x0A, 0x14, 0x04, 0x42, 0x02, 0x56, 0x0A, 0x18, 0x04, 0x56, 0x0A, 0x40, 0x02, 0x1C, 0x04,
+	 0x42, 0x0A, 0x42, 0x2A, 0x20, 0x04, 0xC2, 0x00, 0xD6, 0x08, 0x24, 0x04, 0xD6, 0x08, 0xC0, 0x00,
+	 0x28, 0x04, 0xC2, 0x08, 0xC2, 0x28, 0x08, 0x04, 0x40, 0x01, 0x41, 0x01, 0x0C, 0x04, 0x00, 0x01,
+	 0x01, 0x01, 0x10, 0x04, 0x56, 0x0A, 0x56, 0x0A, 0x14, 0x04, 0x42, 0x02, 0x56, 0x0A, 0x18, 0x04,
+	 0x56, 0x0A, 0x40, 0x02, 0x1C, 0x04, 0x42, 0x0A, 0x42, 0x2A, 0x20, 0x04, 0x42, 0x02, 0x56, 0x0A,
+	 0x24, 0x04, 0x56, 0x0A, 0x40, 0x02, 0x28, 0x04, 0x42, 0x0A, 0x42, 0x2A, 0x08, 0x04, 0x40, 0x01,
+	 0x41, 0x01, 0x0C, 0x04, 0x40, 0x04, 0x41, 0x04, 0x10, 0x04, 0xCE, 0x08, 0x4E, 0x0A, 0x14, 0x04,
+	 0x42, 0x02, 0x4E, 0x0A, 0x18, 0x04, 0x4E, 0x0A, 0x40, 0x02, 0x1C, 0x04, 0x42, 0x0A, 0x42, 0x2A,
+	 0x20, 0x04, 0xC2, 0x00, 0xCE, 0x08, 0x24, 0x04, 0xCE, 0x08, 0xC0, 0x00, 0x28, 0x04, 0xC2, 0x08,
+	 0xC2, 0x28, 0x08, 0x04, 0x40, 0x01, 0x41, 0x01, 0x0C, 0x04, 0x00, 0x01, 0x01, 0x01, 0x10, 0x04,
+	 0x4E, 0x0A, 0x4E, 0x0A, 0x14, 0x04, 0x42, 0x02, 0x4E, 0x0A, 0x18, 0x04, 0x4E, 0x0A, 0x40, 0x02,
+	 0x1C, 0x04, 0x42, 0x0A, 0x42, 0x2A, 0x20, 0x04, 0x42, 0x02, 0x4E, 0x0A, 0x24, 0x04, 0x4E, 0x0A,
+	 0x40, 0x02, 0x28, 0x04, 0x42, 0x0A, 0x42, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
+	 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x05, 0x00, 0xA0, 0x16, 0xA0, 0x16,
+	 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16,
+	 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16,
+	 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x16,
+	 0xA0, 0x16, 0xA0, 0x16, 0xA0, 0x17, 0xA0, 0x17, 0xA0, 0x17, 0xA0, 0x18, 0xFF, 0x06, 0xFF, 0x06,
+	 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06,
+	 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06,
+	 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06,
+	 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0xFF, 0x06, 0x00, 0x00, 0x65, 0x00,
+	 0x65, 0x00, 0x65, 0x00, 0x65, 0x00, 0x5D, 0x00, 0x52, 0x00, 0x48, 0x00, 0x40, 0x00, 0x38, 0x00,
+	 0x31, 0x00, 0x2C, 0x00, 0x27, 0x00, 0x23, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x65, 0x00, 0x65, 0x00,
+	 0x65, 0x00, 0x65, 0x00, 0x5D, 0x00, 0x52, 0x00, 0x48, 0x00, 0x40, 0x00, 0x38, 0x00, 0x31, 0x00,
+	 0x2C, 0x00, 0x27, 0x00, 0x23, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x19, 0x00, 0x19, 0x00, 0x19, 0x00,
+	 0x19, 0x00, 0x19, 0x00, 0x19, 0x00, 0x19, 0x00, 0x19, 0x00, 0x19, 0x00, 0x19, 0x00, 0x19, 0x00,
+	 0x19, 0x00, 0x19, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00,
+	 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x15, 0x00, 0x6E, 0x6F, 0x6E, 0x2D,
+	 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x53, 0x53, 0x49, 0x44, 0x20, 0x21,
+	 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0x00, 0x00, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x09,
+	 0x00, 0x00, 0x01, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x48, 0x45, 0x52, 0x4D, 0x45, 0x53,
+	 0x20, 0x32, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x01, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
+	 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x01, 0x00, 0x15, 0x00,
+	 0x6E, 0x6F, 0x6E, 0x2D, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x53, 0x53,
+	 0x49, 0x44, 0x20, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x01, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x00, 0x09, 0x00, 0x00, 0x01, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x48, 0x45,
+	 0x52, 0x4D, 0x45, 0x53, 0x20, 0x32, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00,
+	 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x69,
+	 0x72, 0x73, 0x74, 0x20, 0x57, 0x61, 0x76, 0x65, 0x4C, 0x41, 0x4E, 0x20, 0x49, 0x49, 0x20, 0x53,
+	 0x53, 0x49, 0x44, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xF0, 0x0F,
+	 0x0F, 0x00, 0x50, 0x01, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
+	 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
+	 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
+	 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00,
+	 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x24, 0x00, 0xFF, 0x00, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x0A, 0x00, 0x0A, 0x00,
+	 0x0B, 0x00, 0x0B, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x02, 0x01,
+	 0x02, 0x04, 0x0B, 0x16, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x82, 0x84, 0x8B, 0x96, 0x00, 0x00,
+	 0x00, 0x00, 0x1C, 0x85, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x01, 0x00,
+	 0x00, 0x00, 0x03, 0x00, 0x20, 0x00, 0x1B, 0x00, 0x17, 0x00, 0x11, 0x00, 0x10, 0x00, 0x0B, 0x00,
+	 0x0B, 0x00, 0x09, 0x00, 0x17, 0x00, 0x14, 0x00, 0x10, 0x00, 0x0D, 0x00, 0x0B, 0x00, 0x09, 0x00,
+	 0x08, 0x00, 0x07, 0x00, 0x0D, 0x00, 0x0A, 0x00, 0x09, 0x00, 0x08, 0x00, 0x05, 0x00, 0x05, 0x00,
+	 0xD8, 0x0C, 0xC0, 0x08, 0x90, 0x0D, 0x60, 0x09, 0x48, 0x0E, 0x30, 0x0A, 0x24, 0x0F, 0x18, 0x0B,
+	 0x0B, 0x6E, 0x0B, 0x37, 0x02, 0x14, 0x01, 0x0A, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00,
+	 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x43, 0x75, 0x72, 0x72, 0x65,
+	 0x6E, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, 0x53, 0x65, 0x74, 0x20, 0x49,
+	 0x64, 0x65, 0x6E, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x01, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xDD, 0x00, 0x50,
+	 0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x05, 0x02, 0x00, 0x00, 0x50, 0xF2, 0x02, 0x00, 0x50,
+	 0xF2, 0x04, 0x02, 0x00, 0x00, 0x50, 0xF2, 0x00, 0x00, 0x50, 0xF2, 0x01, 0x06, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x15, 0x00, 0x14, 0x00, 0x15, 0x00, 0x36, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00,
+	 0x11, 0x00, 0x36, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x01, 0x00, 0x10, 0x00, 0xBE, 0x33, 0x1E, 0x33, 0xCC, 0x35, 0xD0, 0x35, 0xD4, 0x35, 0x12, 0x34,
+	 0x04, 0x36, 0x08, 0x36, 0xF2, 0x33, 0x00, 0x00, 0x00, 0x00, 0x24, 0x2F, 0x14, 0x33, 0x08, 0x36,
+	 0xFF, 0xFF, 0x00, 0x00, 0xBE, 0x33, 0x1E, 0x33, 0xCC, 0x35, 0xD0, 0x35, 0xD4, 0x35, 0x12, 0x34,
+	 0x04, 0x36, 0x08, 0x36, 0xF2, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x00, 0x00, 0xBE, 0x33, 0x14, 0x33, 0x08, 0x36, 0x5C, 0x34, 0x2A, 0x33, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x00, 0x02, 0x06, 0x00, 0x00, 0x06, 0x07,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2A,
+	 0x00, 0x00, 0x08, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x30, 0x00, 0xFF, 0xFF, 0x1D, 0xFA,
+	 0xF9, 0xF9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x19, 0x0A,
+	 0x09, 0x46, 0x1C, 0x60, 0x18, 0x00, 0x19, 0x1D, 0x09, 0x42, 0x1C, 0x60, 0x00, 0x00,
+
+};  /* fw_image_2_data */
+
+static const hcf_8 fw_image_3_data[] = {
+	 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x08, 0x26, 0x1A, 0x00, 0x80, 0x3A, 0x15, 0x00, 0x7F, 0xF1,
+	 0x32, 0xF2, 0x33, 0xF2, 0xD0, 0x80, 0x80, 0xF1, 0x0F, 0x02, 0xD0, 0x80, 0x34, 0xF2, 0x81, 0xF1,
+	 0x0B, 0x02, 0xD0, 0x80, 0xFF, 0xFF, 0x08, 0x02, 0xE9, 0x60, 0x58, 0x4F, 0x30, 0x78, 0xFF, 0xFF,
+	 0x24, 0x60, 0x58, 0x4F, 0xE3, 0x78, 0xFF, 0xFF, 0x1C, 0x60, 0xD7, 0x78, 0xFF, 0xFF, 0x00, 0xF4,
+	 0xAA, 0x60, 0xAA, 0x65, 0x09, 0xF2, 0x5A, 0xD0, 0xD4, 0x80, 0x03, 0x64, 0x12, 0x02, 0xD0, 0x80,
+	 0x1D, 0x60, 0x60, 0x65, 0x0E, 0x02, 0x5A, 0xD2, 0xFF, 0xFF, 0xD4, 0x80, 0x01, 0x60, 0x00, 0x65,
+	 0x08, 0x02, 0x5A, 0xD2, 0xFF, 0xFF, 0xD4, 0x80, 0xFF, 0xFF, 0x03, 0x02, 0x1C, 0x60, 0xD7, 0x78,
+	 0xFF, 0xFF, 0x00, 0x60, 0xEA, 0xF1, 0x5A, 0xD1, 0x44, 0x48, 0x5A, 0xD1, 0x44, 0x4A, 0x26, 0x46,
+	 0x3F, 0xF2, 0x00, 0xF4, 0x44, 0x4C, 0xD8, 0x83, 0x70, 0x61, 0x68, 0x65, 0xD7, 0x80, 0xFF, 0xFF,
+	 0x07, 0x0E, 0x08, 0xF2, 0x08, 0x00, 0x68, 0x65, 0xD7, 0x80, 0xFF, 0xFF, 0x01, 0x0E, 0x03, 0x00,
+	 0x1C, 0x60, 0xED, 0x78, 0xFF, 0xFF, 0x58, 0x4F, 0x79, 0x00, 0x9C, 0x80, 0x01, 0x65, 0x02, 0x02,
+	 0x00, 0x65, 0x02, 0x00, 0xFF, 0x3B, 0xF7, 0x01, 0x58, 0x4F, 0x70, 0x00, 0x9C, 0x80, 0x45, 0x42,
+	 0xEA, 0x02, 0x58, 0x4F, 0x6B, 0x00, 0x9C, 0x80, 0xFF, 0xFF, 0xE5, 0x02, 0x58, 0x4F, 0x66, 0x00,
+	 0x9C, 0x80, 0xFF, 0xFF, 0x03, 0x02, 0x00, 0x65, 0x45, 0x42, 0xF8, 0x01, 0xFF, 0x3A, 0x29, 0x00,
+	 0x60, 0x47, 0xFF, 0xB5, 0x28, 0x44, 0xFF, 0xB4, 0x94, 0x80, 0xFF, 0xFF, 0xD4, 0x02, 0x60, 0x45,
+	 0x28, 0x47, 0x2A, 0x5F, 0x40, 0x48, 0x2A, 0x47, 0x2C, 0x5F, 0x40, 0x4A, 0x2C, 0x47, 0x65, 0x5F,
+	 0x40, 0x4C, 0x10, 0x64, 0x40, 0x42, 0x28, 0x45, 0x05, 0x00, 0x58, 0x4F, 0x47, 0x00, 0x94, 0x80,
+	 0x28, 0x45, 0x26, 0x02, 0x58, 0x4F, 0x42, 0x00, 0x94, 0x80, 0x2A, 0x45, 0x21, 0x02, 0x58, 0x4F,
+	 0x3D, 0x00, 0x94, 0x80, 0xFF, 0xFF, 0x1C, 0x02, 0x22, 0x44, 0x4C, 0x82, 0x2C, 0x45, 0x31, 0x03,
+	 0xEC, 0x01, 0x10, 0x65, 0x45, 0x42, 0x28, 0x45, 0x94, 0x80, 0x2A, 0x45, 0x21, 0x02, 0x58, 0x4F,
+	 0x2D, 0x00, 0x94, 0x80, 0x2C, 0x45, 0x1C, 0x02, 0x58, 0x4F, 0x28, 0x00, 0x94, 0x80, 0xFF, 0xFF,
+	 0x17, 0x02, 0x22, 0x44, 0x4C, 0x82, 0x28, 0x45, 0x1C, 0x03, 0x58, 0x4F, 0x1F, 0x00, 0xEC, 0x01,
+	 0x40, 0x4B, 0x28, 0x47, 0x40, 0x48, 0x2A, 0x47, 0x40, 0x4A, 0x2C, 0x47, 0x60, 0x45, 0x2A, 0x5E,
+	 0x40, 0x4C, 0x2A, 0x44, 0x28, 0x5E, 0x40, 0x4A, 0x28, 0x44, 0x65, 0x5E, 0x40, 0x48, 0x2B, 0x44,
+	 0x68, 0x65, 0xD7, 0x80, 0xFF, 0xFF, 0x17, 0x0E, 0x90, 0x01, 0x26, 0x46, 0xD0, 0x60, 0xB5, 0x78,
+	 0xFF, 0xFF, 0xB9, 0xFF, 0x26, 0x46, 0xD0, 0x60, 0xB5, 0x78, 0xFF, 0xFF, 0xC9, 0x81, 0xCB, 0x83,
+	 0x07, 0x1C, 0x01, 0x1D, 0x08, 0x00, 0x00, 0xF4, 0x01, 0xF2, 0xFF, 0xFF, 0xFF, 0xB4, 0xD8, 0x81,
+	 0x5A, 0xD2, 0x2F, 0x58, 0xFF, 0xFF, 0x26, 0x46, 0xD0, 0x60, 0x58, 0x4F, 0xD1, 0x78, 0xFF, 0xFF,
+	 0x01, 0x60, 0xFE, 0x61, 0x00, 0xF4, 0x12, 0x63, 0x6A, 0x64, 0x01, 0x65, 0xBD, 0xD0, 0xC8, 0x84,
+	 0x59, 0xD9, 0xFC, 0x02, 0x65, 0x40, 0x01, 0x3A, 0x05, 0x00, 0x00, 0xF4, 0x00, 0x65, 0x0E, 0x64,
+	 0x04, 0x63, 0xF4, 0x01, 0x2F, 0x60, 0x58, 0x64, 0x0E, 0x60, 0xD9, 0xFB, 0x1D, 0x60, 0xB0, 0x64,
+	 0xA0, 0xDF, 0x17, 0x60, 0xA8, 0xF3, 0x0E, 0x60, 0xDB, 0xFB, 0x0E, 0x60, 0xDB, 0xF3, 0x0E, 0x60,
+	 0xD8, 0xF3, 0x60, 0x45, 0xD4, 0x80, 0xFF, 0xFF, 0x03, 0x02, 0x1D, 0x60, 0x7B, 0x78, 0xFF, 0xFF,
+	 0x01, 0x64, 0x0E, 0x60, 0xD7, 0xFB, 0x0E, 0x60, 0xD9, 0xF3, 0x02, 0x60, 0x00, 0x61, 0x40, 0x48,
+	 0x40, 0x4A, 0xFA, 0xA4, 0xA0, 0xD3, 0x41, 0x4C, 0xDC, 0x84, 0xA8, 0x84, 0x0E, 0x60, 0xDC, 0xFB,
+	 0x28, 0x45, 0x44, 0x8B, 0x2B, 0xD3, 0x0E, 0x60, 0xDA, 0xFB, 0x28, 0x42, 0x4A, 0xD3, 0x2C, 0x45,
+	 0x44, 0x8C, 0x01, 0x64, 0x40, 0x48, 0x0E, 0x60, 0xDC, 0xF3, 0xFF, 0xFF, 0x36, 0x18, 0xCC, 0x84,
+	 0xA2, 0xDB, 0x0E, 0x60, 0xDA, 0xF3, 0x28, 0x45, 0xA4, 0x80, 0xFF, 0xFF, 0x08, 0x03, 0x60, 0xFE,
+	 0x2C, 0xD3, 0x2A, 0xD3, 0x60, 0x45, 0xD4, 0x80, 0x20, 0xFE, 0x01, 0x03, 0x12, 0x00, 0x28, 0x44,
+	 0xE0, 0x84, 0xFF, 0xFF, 0x02, 0x24, 0x01, 0x00, 0x06, 0x00, 0x2B, 0x44, 0x58, 0x8B, 0x2B, 0xD3,
+	 0x0E, 0x60, 0xDA, 0xFB, 0x01, 0x64, 0x40, 0x48, 0x2A, 0x44, 0x5C, 0x8A, 0x2C, 0x44, 0x5C, 0x8C,
+	 0xDA, 0x01, 0x00, 0x64, 0x0E, 0x60, 0xD7, 0xFB, 0x0E, 0x60, 0xD9, 0xF3, 0xFF, 0xFF, 0x60, 0x45,
+	 0xFA, 0xA4, 0xA0, 0xD3, 0xFF, 0xFF, 0xC4, 0x81, 0x65, 0x44, 0xFC, 0xA4, 0xA0, 0xD3, 0x06, 0xA1,
+	 0xDC, 0x84, 0xA8, 0x84, 0x44, 0x94, 0x0E, 0x60, 0xD9, 0xFB, 0x0E, 0x60, 0xD7, 0xF3, 0xFF, 0xFF,
+	 0x60, 0x40, 0x01, 0x26, 0x09, 0x00, 0x0E, 0x60, 0xD8, 0xF3, 0xFF, 0xFF, 0xDC, 0x84, 0xA2, 0xDB,
+	 0x94, 0x01, 0x1C, 0x60, 0xD7, 0x78, 0xFF, 0xFF, 0x1C, 0x60, 0xDB, 0x78, 0xFF, 0xFF, 0x00, 0x60,
+	 0x2E, 0x61, 0xB6, 0x60, 0x58, 0x4D, 0x25, 0x78, 0xFF, 0xFF, 0x66, 0x44, 0x5F, 0xFB, 0x01, 0x60,
+	 0x05, 0x61, 0xB6, 0x60, 0x58, 0x4D, 0x25, 0x78, 0xFF, 0xFF, 0x66, 0x44, 0x5E, 0xFB, 0x00, 0x60,
+	 0x02, 0x61, 0xB6, 0x60, 0x58, 0x4D, 0x25, 0x78, 0xFF, 0xFF, 0x66, 0x44, 0x65, 0xFB, 0x1F, 0x60,
+	 0x6D, 0x64, 0x08, 0x60, 0x36, 0xFB, 0x2F, 0x58, 0xFF, 0xFF, 0x01, 0x64, 0xDB, 0xFB, 0xF1, 0xF3,
+	 0xFF, 0xFF, 0xFE, 0xB4, 0xF1, 0xFB, 0x10, 0x60, 0x30, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x00, 0x60,
+	 0x14, 0x63, 0x01, 0x60, 0xC2, 0x61, 0x2D, 0x60, 0x98, 0x64, 0x58, 0xD1, 0x59, 0xD9, 0xFD, 0x1F,
+	 0x00, 0x60, 0x8A, 0x63, 0x2D, 0x60, 0x0C, 0x61, 0x2D, 0x60, 0xB0, 0x64, 0x58, 0xD1, 0x59, 0xD9,
+	 0xFD, 0x1F, 0x16, 0x60, 0xAB, 0xF3, 0x19, 0x60, 0x48, 0xF1, 0xFF, 0xB5, 0x64, 0x40, 0x02, 0x2B,
+	 0x0B, 0x00, 0x60, 0x40, 0x03, 0x2E, 0x08, 0x00, 0x80, 0x2B, 0x06, 0x00, 0x32, 0x44, 0x00, 0x60,
+	 0x80, 0x63, 0x3C, 0x94, 0x40, 0x52, 0x05, 0x00, 0x32, 0x44, 0xFF, 0x60, 0x7F, 0x63, 0x2C, 0x94,
+	 0x40, 0x52, 0x65, 0x43, 0x16, 0x60, 0xAB, 0xFD, 0x16, 0x60, 0xC2, 0xF1, 0x66, 0x41, 0xA6, 0xF5,
+	 0x3A, 0xF2, 0x64, 0x40, 0x01, 0x36, 0x22, 0x64, 0x3A, 0xFA, 0x61, 0x46, 0x32, 0x45, 0x16, 0x60,
+	 0xCB, 0xF1, 0x10, 0x67, 0xB4, 0x85, 0x64, 0x40, 0x01, 0x2A, 0x94, 0x85, 0x45, 0x52, 0xFF, 0x60,
+	 0xE7, 0x65, 0x32, 0x41, 0xA5, 0x81, 0x16, 0x60, 0xC2, 0xF3, 0x08, 0x65, 0xFF, 0xA0, 0xFF, 0xFF,
+	 0x01, 0x03, 0x07, 0x00, 0x16, 0x60, 0xC4, 0xF3, 0xB5, 0x81, 0x10, 0x65, 0x60, 0x40, 0x01, 0x26,
+	 0xB5, 0x81, 0x41, 0x52, 0x19, 0x60, 0x48, 0xF3, 0x37, 0x60, 0xE6, 0x63, 0xF0, 0x84, 0xF0, 0x84,
+	 0xF0, 0x84, 0x03, 0xB5, 0xF0, 0x84, 0xF0, 0x84, 0x03, 0xB4, 0x65, 0x5C, 0xA3, 0xD9, 0x37, 0x60,
+	 0xE8, 0x63, 0x02, 0xA8, 0xA3, 0xDB, 0x15, 0x02, 0x00, 0x60, 0xC8, 0x64, 0x1B, 0x60, 0xF5, 0xFB,
+	 0x1B, 0x60, 0xF9, 0xFB, 0x07, 0x60, 0xD0, 0x64, 0x1B, 0x60, 0xF6, 0xFB, 0x1B, 0x60, 0xFA, 0xFB,
+	 0x01, 0x60, 0x90, 0x64, 0x1B, 0x60, 0xF7, 0xFB, 0x00, 0x60, 0x64, 0x64, 0x1B, 0x60, 0xF8, 0xFB,
+	 0x06, 0x00, 0x64, 0x64, 0x1B, 0x60, 0xF7, 0xFB, 0x64, 0x64, 0x1B, 0x60, 0xF8, 0xFB, 0x19, 0x60,
+	 0x48, 0xF1, 0x01, 0x64, 0x64, 0x40, 0x40, 0x2A, 0x02, 0x00, 0x1B, 0x60, 0xEE, 0xFB, 0x33, 0x60,
+	 0xBC, 0x61, 0x2D, 0x60, 0x0E, 0x64, 0x20, 0x63, 0x58, 0xD1, 0x59, 0xD9, 0xFD, 0x1F, 0xBA, 0xF1,
+	 0x7E, 0xF9, 0x1A, 0x63, 0x00, 0x60, 0xFC, 0x61, 0x00, 0x64, 0x59, 0xDB, 0xFE, 0x1F, 0x40, 0x40,
+	 0x01, 0x64, 0x85, 0xFB, 0x17, 0x60, 0x14, 0xF3, 0x35, 0x60, 0x36, 0x61, 0xFE, 0xA4, 0xE0, 0x84,
+	 0x04, 0x24, 0x0C, 0x00, 0xE0, 0x84, 0x41, 0x91, 0x1A, 0x60, 0x1F, 0xF3, 0xA1, 0xD1, 0x59, 0xD1,
+	 0xA0, 0x83, 0x1A, 0x60, 0x1B, 0xFD, 0xA0, 0x83, 0x1A, 0x60, 0x1A, 0xFD, 0xE4, 0xF3, 0x7D, 0xFB,
+	 0xCF, 0xF1, 0x10, 0x60, 0xEC, 0x63, 0x2F, 0x18, 0x60, 0x40, 0x01, 0x27, 0x12, 0x00, 0xCC, 0x84,
+	 0x06, 0xA3, 0xFD, 0x02, 0xA3, 0xD3, 0x10, 0x60, 0xF2, 0x63, 0x25, 0x1B, 0x11, 0x60, 0x44, 0x65,
+	 0xA3, 0xD3, 0x06, 0xA3, 0xD7, 0x80, 0x02, 0x1B, 0xFB, 0x04, 0x1D, 0x00, 0xF8, 0xA3, 0xA3, 0xD3,
+	 0x18, 0x00, 0x11, 0x60, 0x60, 0x63, 0x12, 0x60, 0x40, 0x65, 0xA3, 0xD1, 0x08, 0xA3, 0xD0, 0x80,
+	 0xD7, 0x80, 0x02, 0x03, 0xFA, 0x04, 0x0F, 0x00, 0xFA, 0xA3, 0xA3, 0xD3, 0x11, 0x60, 0x62, 0x63,
+	 0x0A, 0x1B, 0xA3, 0xD3, 0x08, 0xA3, 0xD7, 0x80, 0x02, 0x1B, 0xFB, 0x04, 0x04, 0x00, 0xF6, 0xA3,
+	 0xA3, 0xD3, 0xE4, 0xFB, 0x7D, 0xFB, 0x2E, 0x60, 0x2E, 0x64, 0x2D, 0x60, 0x8A, 0x63, 0xA0, 0xD1,
+	 0xA3, 0xD9, 0x64, 0x41, 0x58, 0xD1, 0x5B, 0xD9, 0x7D, 0xF3, 0x66, 0x45, 0xA6, 0xF5, 0x60, 0x40,
+	 0x01, 0x27, 0x08, 0x00, 0x91, 0xFA, 0x61, 0x44, 0xFD, 0x60, 0x58, 0x4E, 0xAC, 0x78, 0xFF, 0xFF,
+	 0x12, 0xFA, 0x07, 0x00, 0x11, 0xF8, 0x64, 0x44, 0xFD, 0x60, 0x58, 0x4E, 0xAC, 0x78, 0xFF, 0xFF,
+	 0x12, 0xFA, 0x65, 0x46, 0x46, 0x48, 0xE2, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x05, 0x3A, 0x03, 0x00,
+	 0x14, 0x60, 0x22, 0x66, 0x11, 0x00, 0x04, 0x3A, 0x03, 0x00, 0x14, 0x60, 0x16, 0x66, 0x0C, 0x00,
+	 0x03, 0x3A, 0x03, 0x00, 0x14, 0x60, 0x0A, 0x66, 0x07, 0x00, 0x02, 0x3A, 0x03, 0x00, 0x13, 0x60,
+	 0xFE, 0x66, 0x02, 0x00, 0x13, 0x60, 0xF2, 0x66, 0x60, 0xFE, 0xA6, 0xD3, 0xDE, 0x86, 0x13, 0x60,
+	 0xDC, 0xFB, 0xA6, 0xD3, 0xDE, 0x86, 0x28, 0x60, 0x29, 0x63, 0xA3, 0xDB, 0x28, 0x60, 0xA1, 0x63,
+	 0xA3, 0xDB, 0xA6, 0xD3, 0xDE, 0x86, 0x13, 0x60, 0xDB, 0xFB, 0xA6, 0xD3, 0xDE, 0x86, 0x27, 0x60,
+	 0xB9, 0x63, 0xA3, 0xDB, 0x20, 0xFE, 0xA6, 0xD3, 0xDA, 0x86, 0x60, 0x43, 0x1F, 0xB3, 0x63, 0x5C,
+	 0x1F, 0x60, 0x00, 0xB4, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xB0, 0x85, 0x14, 0x60, 0x12, 0xF3,
+	 0xFF, 0xFF, 0xFC, 0x60, 0x00, 0xB4, 0xB4, 0x84, 0xA2, 0xDB, 0x14, 0x60, 0x4E, 0xFB, 0x28, 0x60,
+	 0xC4, 0x63, 0xA3, 0xD3, 0xA6, 0xD1, 0xDE, 0x86, 0x80, 0x60, 0x7F, 0xB5, 0x64, 0x44, 0x60, 0x47,
+	 0xE8, 0x84, 0x7F, 0x60, 0x80, 0xB4, 0xB4, 0x84, 0xA3, 0xDB, 0x60, 0xFE, 0xA6, 0xD3, 0xDE, 0x86,
+	 0x13, 0x60, 0xDF, 0xFB, 0xA6, 0xD3, 0xDE, 0x86, 0x00, 0x60, 0xDF, 0xFB, 0xA6, 0xD3, 0xDE, 0x86,
+	 0x00, 0x60, 0xE0, 0xFB, 0xA6, 0xD3, 0x00, 0x60, 0xE1, 0xFB, 0x20, 0xFE, 0x28, 0x46, 0x19, 0x60,
+	 0x4D, 0xF1, 0x00, 0x60, 0xCF, 0xF3, 0x64, 0x40, 0x00, 0x3A, 0x0F, 0x00, 0x60, 0x40, 0x01, 0x36,
+	 0x05, 0x00, 0x02, 0x36, 0x03, 0x00, 0x07, 0x36, 0x01, 0x00, 0x07, 0x00, 0x10, 0x60, 0xF0, 0x64,
+	 0x00, 0x7C, 0x44, 0xA4, 0xA0, 0xD9, 0x06, 0xA4, 0xA0, 0xD9, 0x36, 0x40, 0x08, 0x3A, 0x03, 0x00,
+	 0xF3, 0x60, 0x0A, 0x78, 0xFF, 0xFF, 0x00, 0x63, 0x10, 0x60, 0x10, 0xFD, 0x10, 0x60, 0x30, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE, 0x0A, 0x04, 0x40, 0x60, 0x00, 0x64, 0x08, 0x60, 0x19, 0xFB,
+	 0x1E, 0x60, 0x8D, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x7D, 0xF1, 0x13, 0x60,
+	 0x1A, 0xF9, 0x0C, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x07, 0x64, 0xCC, 0xFB, 0x20, 0x60,
+	 0x00, 0x64, 0x08, 0x60, 0x19, 0xFB, 0x1F, 0x60, 0x53, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x10, 0x60, 0x30, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xBE, 0xFE, 0x08, 0x60, 0x08, 0xF1,
+	 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0xC5, 0xFE, 0x08, 0x60, 0x15, 0xF1,
+	 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x00, 0x64, 0x08, 0x60, 0x18, 0xFB,
+	 0x5A, 0xDB, 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x60, 0x30, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x02, 0x64,
+	 0x89, 0xFB, 0xFF, 0xFF, 0xC1, 0xFE, 0x08, 0x60, 0x30, 0xF1, 0x00, 0x60, 0xDF, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x01, 0x64, 0x13, 0x60, 0x21, 0xFB, 0xFF, 0xFF, 0x04, 0xFF, 0x08, 0x60,
+	 0x18, 0xF1, 0x00, 0x60, 0x08, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x00, 0x60, 0x08, 0x64,
+	 0x08, 0x60, 0x19, 0xFB, 0x1F, 0x60, 0x92, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x08, 0x60, 0x18, 0xF1, 0x7F, 0x60, 0xFF, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x89, 0xF3, 0x00, 0x65,
+	 0xD4, 0x80, 0xFF, 0xFF, 0x0A, 0x03, 0x80, 0x60, 0x00, 0x64, 0x08, 0x60, 0x19, 0xFB, 0x1F, 0x60,
+	 0x92, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x95, 0xF3, 0xFF, 0xFF, 0x7F, 0xB4,
+	 0x95, 0xFB, 0xDE, 0xFE, 0x0A, 0x04, 0x20, 0x60, 0x00, 0x64, 0x08, 0x60, 0x19, 0xFB, 0x1F, 0x60,
+	 0xB7, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x26, 0x60, 0x34, 0x62, 0x06, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x00, 0x64, 0x08, 0x60, 0x18, 0xFB, 0x5A, 0xDB, 0xBE, 0xFE,
+	 0xDA, 0xFE, 0x25, 0x60, 0xDA, 0x61, 0x1F, 0x60, 0x58, 0x4E, 0xEA, 0x78, 0xFF, 0xFF, 0x25, 0x60,
+	 0xC8, 0x61, 0x1F, 0x60, 0x58, 0x4E, 0xEA, 0x78, 0xFF, 0xFF, 0x25, 0x60, 0xCE, 0x61, 0x1F, 0x60,
+	 0x58, 0x4E, 0xEA, 0x78, 0xFF, 0xFF, 0x25, 0x60, 0xEC, 0x61, 0x1F, 0x60, 0x58, 0x4E, 0xEA, 0x78,
+	 0xFF, 0xFF, 0x25, 0x60, 0xF2, 0x61, 0x1F, 0x60, 0x58, 0x4E, 0xEA, 0x78, 0xFF, 0xFF, 0x25, 0x60,
+	 0xFE, 0x61, 0x1F, 0x60, 0x58, 0x4E, 0xEA, 0x78, 0xFF, 0xFF, 0xC5, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0xA1, 0xD3, 0x0E, 0x57, 0x23, 0x00, 0x0E, 0xF2, 0x44, 0x4C, 0x80, 0xB0, 0x10, 0xB0, 0x0A, 0x03,
+	 0x00, 0x64, 0x13, 0x60, 0x0D, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0x13, 0x00, 0x12, 0x02, 0xF0, 0x37, 0x09, 0x00, 0x02, 0xF0, 0x09, 0x60, 0x08, 0x64,
+	 0xD0, 0x80, 0xA2, 0xFF, 0xAD, 0xF3, 0x02, 0x02, 0xCC, 0x84, 0xAD, 0xFB, 0x26, 0x60, 0x1A, 0x64,
+	 0x40, 0x4B, 0x34, 0x60, 0x58, 0x4D, 0x08, 0x78, 0xFF, 0xFF, 0x2C, 0x44, 0xAC, 0x86, 0x09, 0xF0,
+	 0xDA, 0x02, 0x37, 0x58, 0xFF, 0xFF, 0x2E, 0x58, 0xFF, 0xFF, 0x2E, 0x58, 0xFF, 0xFF, 0x23, 0x60,
+	 0x85, 0x64, 0x08, 0x60, 0x32, 0xFB, 0x1C, 0x60, 0xB6, 0x62, 0xA2, 0xDF, 0x06, 0xA2, 0x10, 0x60,
+	 0x88, 0x64, 0xA2, 0xDB, 0x06, 0x64, 0x5A, 0xDB, 0x5A, 0xDB, 0x1C, 0x60, 0xC2, 0x62, 0xA2, 0xDF,
+	 0x06, 0xA2, 0x10, 0x60, 0x8C, 0x64, 0xA2, 0xDB, 0x06, 0x64, 0x5A, 0xDB, 0x5A, 0xDB, 0x1C, 0x60,
+	 0xCE, 0x62, 0xA2, 0xDF, 0x06, 0xA2, 0x10, 0x60, 0x90, 0x64, 0xA2, 0xDB, 0x06, 0x64, 0x5A, 0xDB,
+	 0x5A, 0xDB, 0xBD, 0xF1, 0x0E, 0x60, 0x69, 0xF9, 0x24, 0x60, 0xC1, 0x64, 0x08, 0x60, 0x43, 0xFB,
+	 0x24, 0x60, 0xCA, 0x64, 0x08, 0x60, 0x45, 0xFB, 0x24, 0x60, 0xD3, 0x64, 0x08, 0x60, 0x47, 0xFB,
+	 0x00, 0x60, 0x3A, 0x61, 0xB6, 0x60, 0x58, 0x4D, 0x22, 0x78, 0xFF, 0xFF, 0x66, 0x44, 0x62, 0xFB,
+	 0x04, 0x64, 0x03, 0xFA, 0xA6, 0xF3, 0x07, 0xFA, 0x00, 0x64, 0x3E, 0xFA, 0x3F, 0xFA, 0x00, 0x60,
+	 0x02, 0x64, 0x08, 0x60, 0x0D, 0xFB, 0x20, 0x60, 0x63, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x10, 0x60, 0x18, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x03, 0x64, 0x69, 0xFB, 0x0F, 0x4E,
+	 0xEA, 0x60, 0x58, 0x4F, 0x34, 0x78, 0xFF, 0xFF, 0x0E, 0x4F, 0x00, 0x64, 0x6B, 0xFB, 0x62, 0xF5,
+	 0xEA, 0xF3, 0x2F, 0xFA, 0xEB, 0xF3, 0x30, 0xFA, 0xEC, 0xF3, 0x31, 0xFA, 0x7F, 0xF3, 0x2C, 0xFA,
+	 0x32, 0xFA, 0x80, 0xF3, 0x2D, 0xFA, 0x33, 0xFA, 0x81, 0xF3, 0x2E, 0xFA, 0x34, 0xFA, 0xB9, 0xF3,
+	 0x19, 0xFA, 0x06, 0x60, 0x80, 0x64, 0x0E, 0xFA, 0xF7, 0x60, 0xFF, 0x65, 0x20, 0x44, 0x24, 0x80,
+	 0x08, 0x60, 0x08, 0xF1, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x08, 0x60,
+	 0x0C, 0xF1, 0xFF, 0x60, 0x8F, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0xBE, 0xF1, 0x0E, 0x60, 0x63, 0xF9,
+	 0x1C, 0x60, 0xC2, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF,
+	 0x00, 0x64, 0x6B, 0xFB, 0x00, 0x60, 0x74, 0x64, 0x08, 0x60, 0x0D, 0xFB, 0x20, 0x60, 0xAE, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x0C, 0xF1, 0x00, 0x60, 0x04, 0x64,
+	 0xA0, 0x80, 0x9C, 0x84, 0x05, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x23, 0x60, 0x85, 0x78, 0xFF, 0xFF,
+	 0x00, 0x60, 0x40, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x03, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xE2, 0x01,
+	 0x00, 0x60, 0x20, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x11, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x20, 0x40,
+	 0x50, 0x27, 0xD8, 0x01, 0xAC, 0xF3, 0xFF, 0xFF, 0xFE, 0xA0, 0xFF, 0xFF, 0x0F, 0x06, 0x6B, 0xF3,
+	 0xFF, 0xFF, 0xEC, 0xA0, 0xDC, 0x84, 0x01, 0x05, 0xA2, 0xDB, 0xCC, 0x01, 0x00, 0x60, 0x10, 0x64,
+	 0xA0, 0x80, 0x9C, 0x84, 0xCF, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x01, 0x00, 0xC3, 0x01, 0x01, 0x64,
+	 0x19, 0x60, 0xF3, 0xFB, 0xDF, 0xF3, 0x29, 0x45, 0xD4, 0x80, 0x6B, 0xF3, 0x03, 0x04, 0x21, 0x60,
+	 0x28, 0x78, 0xFF, 0xFF, 0xEC, 0xA0, 0x00, 0x64, 0x04, 0x04, 0x40, 0x49, 0x21, 0x60, 0x28, 0x78,
+	 0xFF, 0xFF, 0x00, 0x60, 0x64, 0x64, 0x08, 0x60, 0x0D, 0xFB, 0x20, 0x60, 0xFD, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x0C, 0xF1, 0x00, 0x60, 0x04, 0x64, 0xA0, 0x80,
+	 0x9C, 0x84, 0x05, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x23, 0x60, 0x85, 0x78, 0xFF, 0xFF, 0x00, 0x60,
+	 0x40, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x03, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xD0, 0x01, 0x00, 0x60,
+	 0x20, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0xE5, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x20, 0x40, 0x50, 0x27,
+	 0xE0, 0x01, 0xAC, 0xF3, 0xFF, 0xFF, 0xFE, 0xA0, 0xFF, 0xFF, 0x07, 0x06, 0x6B, 0xF3, 0xFF, 0xFF,
+	 0xEC, 0xA0, 0xDC, 0x84, 0x01, 0x05, 0xA2, 0xDB, 0xBA, 0x01, 0xB9, 0x01, 0x33, 0x60, 0xE6, 0x65,
+	 0xA5, 0xDF, 0xBF, 0xF1, 0x0E, 0x60, 0x63, 0xF9, 0xE0, 0xF3, 0x29, 0x45, 0x03, 0xA4, 0xD4, 0x80,
+	 0x01, 0x63, 0x01, 0x05, 0x00, 0x63, 0x53, 0xFD, 0x7D, 0xF3, 0x01, 0x60, 0x00, 0x65, 0xA4, 0x80,
+	 0x24, 0x44, 0xFE, 0xB4, 0x01, 0x03, 0x01, 0xBC, 0x40, 0x44, 0x21, 0x60, 0x45, 0x64, 0x6A, 0xFB,
+	 0x23, 0x60, 0xF6, 0x78, 0xFF, 0xFF, 0x1C, 0x60, 0xCE, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x08, 0x60, 0x0C, 0xF1, 0xFF, 0x60, 0xDF, 0x64, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x86, 0xF1, 0x1B, 0x60, 0xB2, 0x63, 0xD3, 0x80, 0x67, 0xFD, 0x43, 0x03, 0x67, 0xF3,
+	 0xE1, 0xF1, 0x60, 0x43, 0x29, 0x44, 0xA3, 0xD3, 0xC0, 0x85, 0xD4, 0x80, 0x5B, 0xD3, 0x3A, 0x06,
+	 0x60, 0x43, 0x08, 0xA3, 0xBE, 0xD3, 0x81, 0xF1, 0xA3, 0xD3, 0xD0, 0x80, 0x80, 0xF1, 0x05, 0x02,
+	 0xBF, 0xD3, 0xD0, 0x80, 0x7F, 0xF1, 0x01, 0x02, 0xD0, 0x80, 0xF8, 0xA3, 0x28, 0x02, 0x21, 0x60,
+	 0x77, 0x64, 0x6A, 0xFB, 0x23, 0x60, 0xB4, 0x78, 0xFF, 0xFF, 0x01, 0xB0, 0x82, 0xF3, 0x22, 0x03,
+	 0x62, 0xF5, 0x48, 0x7E, 0x2A, 0xFA, 0x25, 0x60, 0xCE, 0x64, 0x13, 0x60, 0x0D, 0xFB, 0x66, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x00, 0x60, 0x01, 0x64,
+	 0x08, 0x60, 0x0D, 0xFB, 0x21, 0x60, 0x92, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x08, 0x60, 0x0C, 0xF1, 0xFF, 0x60, 0xFE, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x03, 0x00, 0x23, 0x60,
+	 0x7A, 0x78, 0xFF, 0xFF, 0x6B, 0xF3, 0xFF, 0xFF, 0xEC, 0xA0, 0x00, 0x64, 0x02, 0x04, 0x40, 0x49,
+	 0x15, 0x00, 0xDF, 0xF3, 0x29, 0x45, 0xD4, 0x80, 0xFF, 0xFF, 0x0B, 0x07, 0x1C, 0x60, 0xC2, 0x64,
+	 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x20, 0x60, 0x86, 0x78,
+	 0xFF, 0xFF, 0xE0, 0xF3, 0x29, 0x45, 0xD4, 0x80, 0xFF, 0xFF, 0x16, 0x06, 0x04, 0x65, 0xF1, 0x60,
+	 0x58, 0x4E, 0xC3, 0x78, 0xFF, 0xFF, 0x05, 0x64, 0xDB, 0xFB, 0xF1, 0xF3, 0xFF, 0xFF, 0x01, 0xBC,
+	 0xF1, 0xFB, 0x1C, 0x60, 0xC2, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x04, 0xFF, 0x22, 0x60, 0x1B, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x74, 0x64, 0x08, 0x60, 0x0D, 0xFB,
+	 0x21, 0x60, 0xD8, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x0C, 0xF1,
+	 0x00, 0x60, 0x04, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x05, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x23, 0x60,
+	 0x85, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x40, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x03, 0x03, 0xA0, 0x84,
+	 0xA2, 0xDB, 0xB0, 0x01, 0x00, 0x60, 0x20, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x15, 0x03, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x20, 0x40, 0x50, 0x27, 0xA6, 0x01, 0xAC, 0xF3, 0x6B, 0xF3, 0xFE, 0xA0, 0xEC, 0xA0,
+	 0x0A, 0x06, 0x03, 0x04, 0x00, 0x64, 0x55, 0xFB, 0x40, 0x49, 0x6B, 0xF3, 0xFF, 0xFF, 0xEC, 0xA0,
+	 0xDC, 0x84, 0x01, 0x05, 0xA2, 0xDB, 0x96, 0x01, 0x00, 0x60, 0x10, 0x64, 0xA0, 0x80, 0x9C, 0x84,
+	 0x0D, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x1C, 0x60, 0xCE, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x21, 0x60, 0x28, 0x78, 0xFF, 0xFF, 0x21, 0x60, 0x9C, 0x78,
+	 0xFF, 0xFF, 0x7D, 0xF3, 0x01, 0x60, 0x00, 0x65, 0xA4, 0x80, 0x24, 0x44, 0xFE, 0xB4, 0x01, 0x03,
+	 0x01, 0xBC, 0x02, 0xB0, 0xFB, 0xB4, 0x01, 0x03, 0x04, 0xBC, 0x40, 0x44, 0xC0, 0xF1, 0x0E, 0x60,
+	 0x63, 0xF9, 0xCF, 0xF3, 0x20, 0x60, 0x20, 0x65, 0x30, 0x1B, 0xA5, 0xD3, 0x24, 0x40, 0x01, 0x26,
+	 0x16, 0x00, 0x60, 0x40, 0x20, 0x26, 0x29, 0x00, 0x01, 0xBC, 0xA5, 0xDB, 0x08, 0x60, 0x1E, 0xF1,
+	 0x00, 0x60, 0x20, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x10, 0x60, 0x00, 0x64, 0x08, 0x60,
+	 0x0D, 0xFB, 0x22, 0x60, 0x5F, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x60, 0x40,
+	 0x10, 0x26, 0x13, 0x00, 0x01, 0xBC, 0xA5, 0xDB, 0x08, 0x60, 0x1E, 0xF1, 0x00, 0x60, 0x40, 0x64,
+	 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x10, 0x60, 0x00, 0x64, 0x08, 0x60, 0x0D, 0xFB, 0x22, 0x60,
+	 0x5F, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0D, 0x64, 0x53, 0xFB, 0x22, 0x60,
+	 0x67, 0x64, 0x6A, 0xFB, 0x23, 0x60, 0xF6, 0x78, 0xFF, 0xFF, 0x1C, 0x60, 0xCE, 0x64, 0x13, 0x60,
+	 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x08, 0x60, 0x0C, 0xF1, 0xFF, 0x60,
+	 0xDF, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x86, 0xF1, 0x1B, 0x60, 0xB2, 0x63, 0xD3, 0x80, 0x67, 0xFD,
+	 0x07, 0x02, 0x24, 0x44, 0x04, 0xB0, 0xFF, 0xFF, 0x36, 0x03, 0x05, 0xAC, 0x40, 0x44, 0xA6, 0x01,
+	 0x67, 0xF3, 0x29, 0x41, 0xA0, 0xD1, 0x58, 0xD3, 0xD1, 0x80, 0x64, 0x45, 0x60, 0x43, 0x2B, 0x05,
+	 0x08, 0xA3, 0xBE, 0xD3, 0x81, 0xF1, 0xA3, 0xD3, 0xD0, 0x80, 0x80, 0xF1, 0x05, 0x02, 0xBF, 0xD3,
+	 0xD0, 0x80, 0x7F, 0xF1, 0x01, 0x02, 0xD0, 0x80, 0xF8, 0xA3, 0x07, 0x02, 0x45, 0x49, 0x22, 0x60,
+	 0xCD, 0x64, 0x6A, 0xFB, 0x23, 0x60, 0xB4, 0x78, 0xFF, 0xFF, 0x05, 0x65, 0xF1, 0x60, 0x58, 0x4E,
+	 0xC3, 0x78, 0xFF, 0xFF, 0x04, 0x64, 0xDB, 0xFB, 0xF1, 0xF3, 0xFF, 0xFF, 0xFE, 0xB4, 0xF1, 0xFB,
+	 0x23, 0x60, 0x7A, 0x78, 0xFF, 0xFF, 0x67, 0xF3, 0x86, 0xF1, 0x04, 0xA4, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x02, 0x03, 0x67, 0xFB, 0xCD, 0x01, 0x6B, 0xF3, 0xFF, 0xFF, 0xEC, 0xA0, 0xFF, 0xFF, 0x01, 0x04,
+	 0x75, 0x00, 0xE0, 0xF3, 0x29, 0x45, 0xD4, 0x80, 0xFF, 0xFF, 0x70, 0x05, 0x7D, 0xF3, 0xFF, 0xFF,
+	 0x60, 0x40, 0x01, 0x27, 0x08, 0x00, 0x22, 0x60, 0xCD, 0x63, 0x6A, 0xFD, 0x1C, 0x60, 0x78, 0x63,
+	 0x23, 0x60, 0xB4, 0x78, 0xFF, 0xFF, 0x1C, 0x60, 0xC2, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x05, 0x65, 0xF1, 0x60, 0x58, 0x4E, 0xC3, 0x78, 0xFF, 0xFF,
+	 0x20, 0x60, 0x14, 0x61, 0xA1, 0xDF, 0x04, 0x64, 0xDB, 0xFB, 0xF1, 0xF3, 0xFF, 0xFF, 0xFE, 0xB4,
+	 0xF1, 0xFB, 0x82, 0xF3, 0x62, 0xF5, 0x48, 0x7E, 0x2A, 0xFA, 0x02, 0x60, 0x00, 0x65, 0x20, 0x44,
+	 0x34, 0x80, 0x25, 0x60, 0xCE, 0x64, 0x13, 0x60, 0x0D, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x00, 0x60, 0x01, 0x64, 0x08, 0x60, 0x0D, 0xFB,
+	 0x23, 0x60, 0x00, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x0C, 0xF1,
+	 0xFF, 0x60, 0xFE, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x00, 0x60, 0x32, 0x64, 0x0E, 0x60, 0x63, 0xFB,
+	 0x1C, 0x60, 0xC2, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF,
+	 0x00, 0x60, 0x10, 0x64, 0x08, 0x60, 0x0D, 0xFB, 0x23, 0x60, 0x1C, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x0C, 0xF1, 0xFF, 0x60, 0xEF, 0x64, 0xA0, 0x84, 0xA2, 0xDB,
+	 0xFD, 0x60, 0xFF, 0x65, 0x20, 0x44, 0x24, 0x80, 0x08, 0x60, 0x08, 0xF1, 0x80, 0x60, 0x00, 0x64,
+	 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x20, 0x60, 0x86, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x74, 0x64,
+	 0x08, 0x60, 0x0D, 0xFB, 0x23, 0x60, 0x3A, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x08, 0x60, 0x0C, 0xF1, 0x00, 0x60, 0x04, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x05, 0x03, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x23, 0x60, 0x85, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x40, 0x64, 0xA0, 0x80, 0x9C, 0x84,
+	 0x03, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x67, 0x01, 0x00, 0x60, 0x20, 0x64, 0xA0, 0x80, 0x9C, 0x84,
+	 0x15, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x20, 0x40, 0x50, 0x27, 0xE0, 0x01, 0xAC, 0xF3, 0x6B, 0xF3,
+	 0xFE, 0xA0, 0xEC, 0xA0, 0x0A, 0x06, 0x03, 0x04, 0x00, 0x64, 0x55, 0xFB, 0x40, 0x49, 0x6B, 0xF3,
+	 0xFF, 0xFF, 0xEC, 0xA0, 0xDC, 0x84, 0x01, 0x05, 0xA2, 0xDB, 0x4D, 0x01, 0x00, 0x60, 0x10, 0x64,
+	 0xA0, 0x80, 0x9C, 0x84, 0xCB, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x1C, 0x60, 0xCE, 0x64, 0x13, 0x60,
+	 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x22, 0x60, 0x1B, 0x78, 0xFF, 0xFF,
+	 0x08, 0x60, 0x00, 0x65, 0x20, 0x44, 0x34, 0x80, 0x08, 0x60, 0x15, 0xF1, 0x00, 0x60, 0x20, 0x64,
+	 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x1C, 0x60, 0xB6, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x1C, 0x60, 0xC2, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x1C, 0x60, 0xCE, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x00, 0x64, 0x08, 0x60, 0x0C, 0xFB, 0x5A, 0xDB, 0x00, 0x64,
+	 0x69, 0xFB, 0x08, 0x60, 0x08, 0xF1, 0x02, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x00, 0x60, 0x02, 0x64, 0x08, 0x60, 0x0D, 0xFB, 0x20, 0x60, 0x63, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0xA3, 0xD3, 0x7D, 0xF1, 0x7C, 0xFB, 0xD0, 0x80, 0x00, 0x64, 0x39, 0x03,
+	 0x08, 0x60, 0x0C, 0xF1, 0xBF, 0x60, 0xFF, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0xDE, 0xFE, 0x0A, 0x04,
+	 0x40, 0x60, 0x00, 0x64, 0x08, 0x60, 0x0D, 0xFB, 0x23, 0x60, 0xBA, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x0C, 0xF1, 0xDF, 0x60, 0xFF, 0x64, 0xA0, 0x84, 0xA2, 0xDB,
+	 0x7C, 0xF1, 0x7D, 0xF9, 0x13, 0x60, 0x1A, 0xF9, 0x0E, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF,
+	 0x20, 0x60, 0x00, 0x64, 0x08, 0x60, 0x0D, 0xFB, 0x23, 0x60, 0xE4, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0xBE, 0xFE, 0x08, 0x60, 0x0C, 0xF1, 0xDF, 0x60, 0xFF, 0x64, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x08, 0x60, 0x08, 0xF1, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x01, 0x64, 0x6A, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0x60, 0x00, 0x65, 0x20, 0x44, 0x34, 0x80,
+	 0x08, 0x60, 0x0C, 0xF1, 0x7F, 0x60, 0xFF, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x20, 0x40, 0x51, 0x23,
+	 0x0A, 0x00, 0x80, 0x60, 0x00, 0x64, 0x08, 0x60, 0x0D, 0xFB, 0x23, 0x60, 0xFA, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x0C, 0xF1, 0x7F, 0x60, 0xFF, 0x61, 0xA1, 0x84,
+	 0x5A, 0xD1, 0x4A, 0xDB, 0xA1, 0x84, 0x5A, 0xDB, 0x02, 0x64, 0x8A, 0xFB, 0xFF, 0xFF, 0xC1, 0xFE,
+	 0x8A, 0xF3, 0x00, 0x65, 0xD4, 0x80, 0xFF, 0xFF, 0x10, 0x03, 0x08, 0x60, 0x0C, 0xF1, 0x7F, 0x60,
+	 0xFF, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x80, 0x60, 0x00, 0x64, 0x08, 0x60, 0x0D, 0xFB, 0x24, 0x60,
+	 0x16, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x33, 0x60, 0xBE, 0x64, 0x54, 0xFB,
+	 0x08, 0x60, 0x0C, 0xF1, 0xEF, 0x60, 0xFF, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x24, 0x44, 0x01, 0xB0,
+	 0xFF, 0xFF, 0x08, 0x02, 0x08, 0x60, 0x12, 0xF1, 0x00, 0x60, 0x10, 0x64, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xCF, 0xFE, 0x07, 0x00, 0x08, 0x60, 0x12, 0xF1, 0x00, 0x60, 0x20, 0x64, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xCF, 0xFE, 0x10, 0x60, 0x00, 0x64, 0x08, 0x60, 0x0D, 0xFB, 0x24, 0x60, 0x55, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x1C, 0x60, 0xC2, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x02, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x08, 0x60, 0x0C, 0xF1, 0xEF, 0x60, 0xEF, 0x64, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x01, 0x64, 0x8A, 0xFB, 0x6B, 0xF3, 0x00, 0x60, 0x95, 0xF3, 0xEC, 0xA0, 0x40, 0xBC,
+	 0x06, 0x04, 0xA2, 0xDB, 0x69, 0xF1, 0xFF, 0x60, 0xFB, 0x64, 0xA0, 0x84, 0x69, 0xFB, 0xFD, 0x60,
+	 0xFF, 0x65, 0x20, 0x44, 0x24, 0x80, 0x08, 0x60, 0x08, 0xF1, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0xC1, 0xFE, 0x6A, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0xF1, 0x28, 0x44,
+	 0xD0, 0x84, 0x03, 0xA4, 0x03, 0x0E, 0xE8, 0x84, 0xE8, 0x84, 0x04, 0x00, 0xFA, 0xA4, 0xE8, 0x84,
+	 0xE8, 0x87, 0xC0, 0xBF, 0xC0, 0x84, 0xA2, 0xDB, 0x2E, 0x58, 0xFF, 0xFF, 0x56, 0xF1, 0x28, 0x44,
+	 0xD0, 0x84, 0x1F, 0xA4, 0x06, 0x0E, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84,
+	 0x07, 0x00, 0xC2, 0xA4, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x87, 0xF8, 0xBF,
+	 0xC0, 0x84, 0x5B, 0xF1, 0x56, 0xFB, 0xD0, 0x80, 0xFF, 0xFF, 0x01, 0x05, 0x64, 0x44, 0x52, 0xFB,
+	 0x2E, 0x58, 0xFF, 0xFF, 0x52, 0xF1, 0x2F, 0x67, 0xD0, 0x80, 0x60, 0x45, 0x02, 0x28, 0x64, 0x45,
+	 0x55, 0xF1, 0x8B, 0x67, 0xD0, 0x80, 0x60, 0x41, 0x02, 0x24, 0x64, 0x41, 0xD5, 0x84, 0x80, 0x65,
+	 0xC4, 0x87, 0x01, 0x05, 0x00, 0x64, 0xFF, 0xB4, 0x40, 0x49, 0x2E, 0x58, 0xFF, 0xFF, 0x08, 0x60,
+	 0x0C, 0xF1, 0x00, 0x60, 0x08, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x08, 0x60, 0x0C, 0xF1, 0x00, 0x60, 0x10, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x08, 0x60, 0x0C, 0xF1, 0x00, 0x60, 0x20, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x08, 0x60, 0x1B, 0xF1, 0x00, 0x60, 0x40, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x26, 0x46, 0x27, 0xF2, 0x70, 0x63, 0x60, 0x40, 0x0A, 0x36, 0x10, 0x00, 0x14, 0x36,
+	 0x14, 0x00, 0x37, 0x36, 0x0E, 0x00, 0x6E, 0x36, 0x0E, 0x00, 0x06, 0x36, 0x04, 0x00, 0x09, 0x36,
+	 0x04, 0x00, 0x18, 0x63, 0x0A, 0x00, 0x30, 0x63, 0x08, 0x00, 0x26, 0x63, 0x06, 0x00, 0xD0, 0x63,
+	 0x04, 0x00, 0x33, 0x63, 0x02, 0x00, 0x21, 0x63, 0x00, 0x00, 0x10, 0x60, 0x0E, 0xFD, 0x26, 0x46,
+	 0x3F, 0xF2, 0x87, 0xF0, 0x00, 0xF4, 0x45, 0x43, 0x03, 0x4B, 0x60, 0x43, 0xF4, 0xA3, 0x00, 0x60,
+	 0x1D, 0x61, 0x00, 0x60, 0x01, 0x65, 0x01, 0x60, 0xFF, 0x64, 0x40, 0x4C, 0xFD, 0x60, 0x58, 0x4E,
+	 0x7A, 0x78, 0xFF, 0xFF, 0x00, 0xBB, 0xFF, 0xFF, 0x00, 0x02, 0x00, 0x64, 0x40, 0x4A, 0x60, 0xFE,
+	 0x02, 0x60, 0x00, 0x63, 0xBD, 0xD3, 0xBD, 0xD3, 0x60, 0x41, 0xFE, 0x60, 0x58, 0x4E, 0x2C, 0x78,
+	 0xFF, 0xFF, 0x20, 0xFE, 0x26, 0x46, 0x3F, 0xF2, 0x00, 0xF4, 0x60, 0x43, 0xF4, 0xA3, 0x00, 0x60,
+	 0x1D, 0x61, 0x00, 0x60, 0x32, 0x65, 0x01, 0x60, 0xFF, 0x64, 0x40, 0x4C, 0xFD, 0x60, 0x58, 0x4E,
+	 0x7A, 0x78, 0xFF, 0xFF, 0x00, 0xBB, 0xFF, 0xFF, 0x0B, 0x03, 0x60, 0xFE, 0x02, 0x60, 0x00, 0x63,
+	 0xBD, 0xD3, 0xBD, 0xD3, 0x60, 0x41, 0xFE, 0x60, 0x58, 0x4E, 0x2C, 0x78, 0xFF, 0xFF, 0x20, 0xFE,
+	 0x2A, 0x44, 0xFC, 0x60, 0x58, 0x4E, 0x34, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x3F, 0xF2, 0x01, 0x60,
+	 0x00, 0x65, 0xF4, 0xA4, 0xD4, 0x80, 0x60, 0x41, 0x02, 0x24, 0x65, 0x41, 0x41, 0x48, 0x00, 0xF4,
+	 0x1E, 0x65, 0x02, 0x60, 0x00, 0x63, 0xA5, 0xD0, 0xDA, 0x85, 0x80, 0x3A, 0x02, 0x00, 0x00, 0xF4,
+	 0x04, 0x65, 0x64, 0x44, 0x00, 0x7F, 0xCD, 0x81, 0xBD, 0xDB, 0x05, 0x03, 0x64, 0x47, 0x00, 0x7F,
+	 0xCD, 0x81, 0xBD, 0xDB, 0xF0, 0x02, 0x02, 0x60, 0x00, 0x63, 0x28, 0x41, 0xBD, 0xD3, 0xBD, 0xD1,
+	 0xFD, 0xA0, 0xFE, 0xA1, 0x07, 0x03, 0x09, 0x06, 0x64, 0x44, 0xE0, 0x85, 0xD1, 0x81, 0xC7, 0x83,
+	 0xF5, 0x07, 0x03, 0x00, 0xA3, 0xD3, 0x0E, 0x60, 0x3C, 0xFB, 0x31, 0x40, 0x06, 0x26, 0x57, 0x00,
+	 0x00, 0x64, 0x6F, 0xFB, 0x02, 0x60, 0x00, 0x63, 0x28, 0x41, 0xBD, 0xD3, 0xBD, 0xD1, 0xFC, 0xA0,
+	 0xFB, 0xA0, 0x09, 0x03, 0x28, 0x03, 0x64, 0x44, 0xE0, 0x85, 0xC7, 0x83, 0xD1, 0x81, 0xFE, 0xA1,
+	 0x46, 0x06, 0xF3, 0x07, 0x44, 0x00, 0xBD, 0xD3, 0xBD, 0xD3, 0x00, 0xB8, 0x6F, 0xFB, 0x6E, 0xFB,
+	 0xBD, 0xD3, 0x3D, 0x02, 0xA3, 0xD3, 0x60, 0x45, 0x60, 0x47, 0xB4, 0x84, 0x60, 0x41, 0x3F, 0xB5,
+	 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0x71, 0xFB, 0x65, 0x47,
+	 0xE0, 0x84, 0xE0, 0x84, 0x70, 0xFB, 0x64, 0x44, 0xE0, 0x85, 0xFA, 0xA3, 0xC7, 0x83, 0x61, 0x44,
+	 0x0E, 0x60, 0x38, 0xFB, 0xD2, 0x01, 0xBD, 0xD3, 0xA3, 0xD3, 0x00, 0xB8, 0x6D, 0xFB, 0x73, 0xFB,
+	 0x1E, 0x02, 0x85, 0xF1, 0x6F, 0xF3, 0x6C, 0xF9, 0x04, 0x65, 0x60, 0x40, 0x00, 0x3A, 0x06, 0x65,
+	 0x31, 0x44, 0xB4, 0x84, 0x40, 0x51, 0x02, 0x2A, 0x0B, 0x00, 0x08, 0xBC, 0x40, 0x51, 0x71, 0xF3,
+	 0x70, 0xF1, 0x00, 0xB8, 0x64, 0x45, 0x01, 0x03, 0x67, 0x45, 0x65, 0x50, 0xCC, 0x84, 0x72, 0xFB,
+	 0x08, 0x60, 0x15, 0xF1, 0x01, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x08, 0x60,
+	 0x16, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x80, 0x2A, 0x3F, 0x00, 0x01, 0x64, 0x10, 0x60, 0x0A, 0xFB,
+	 0x26, 0x60, 0x58, 0x4E, 0x65, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x00, 0xF4, 0x0D, 0xF2, 0x7E, 0xFB,
+	 0x00, 0x64, 0x84, 0xFB, 0x26, 0x46, 0x3F, 0xF2, 0x00, 0xF4, 0x60, 0x43, 0xF4, 0xA3, 0x00, 0x60,
+	 0x1D, 0x61, 0x00, 0x60, 0x07, 0x65, 0x01, 0x60, 0xFF, 0x64, 0x40, 0x4C, 0xFD, 0x60, 0x58, 0x4E,
+	 0x7A, 0x78, 0xFF, 0xFF, 0x00, 0xBB, 0xFF, 0xFF, 0x14, 0x03, 0x02, 0x60, 0x00, 0x65, 0xA5, 0xD3,
+	 0x1C, 0x60, 0xE6, 0x63, 0xFF, 0xB4, 0x01, 0xA4, 0x60, 0x41, 0xA5, 0xD1, 0xDA, 0x85, 0x64, 0x44,
+	 0x00, 0x7F, 0xCD, 0x81, 0xBD, 0xDB, 0x05, 0x03, 0x64, 0x47, 0x00, 0x7F, 0xCD, 0x81, 0xBD, 0xDB,
+	 0xF4, 0x02, 0x08, 0x60, 0x15, 0xF1, 0x00, 0x60, 0x80, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x32, 0x00, 0x27, 0x60, 0x57, 0x78, 0xFF, 0xFF, 0xDB, 0xF3, 0xFF, 0xFF, 0x03, 0xA8, 0x02, 0xA8,
+	 0x02, 0x03, 0x3E, 0x02, 0xF6, 0x01, 0x08, 0x60, 0x15, 0xF1, 0xFF, 0x60, 0xFB, 0x64, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x1C, 0x60, 0x92, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x04, 0xFF, 0x26, 0x46, 0x10, 0x60, 0x0E, 0xF3, 0x25, 0xF2, 0x60, 0x45, 0x24, 0xF0, 0x00, 0xF4,
+	 0x64, 0x43, 0xC7, 0x83, 0x60, 0x41, 0x02, 0x24, 0x01, 0xA1, 0x0A, 0xF0, 0x09, 0xF2, 0xD1, 0x80,
+	 0xFF, 0xFF, 0x09, 0x07, 0x04, 0x04, 0x63, 0x45, 0xD4, 0x80, 0xFF, 0xFF, 0x04, 0x06, 0x26, 0x60,
+	 0x58, 0x4E, 0x65, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x26, 0xF0, 0xFF, 0x67, 0x20, 0x88, 0x64, 0x5F,
+	 0x40, 0x4A, 0x24, 0x60, 0x58, 0x4E, 0x80, 0x78, 0xFF, 0xFF, 0x0A, 0x48, 0x24, 0x60, 0x58, 0x4E,
+	 0x90, 0x78, 0xFF, 0xFF, 0x24, 0x60, 0x58, 0x4E, 0xAC, 0x78, 0xFF, 0xFF, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x08, 0x60, 0x0D, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x40, 0x22, 0xB3, 0x01, 0x00, 0x60, 0x95, 0xF3,
+	 0xFF, 0xFF, 0xBF, 0xB4, 0xA2, 0xDB, 0x10, 0x60, 0x0E, 0xF3, 0x26, 0x46, 0x60, 0x45, 0x20, 0x60,
+	 0x04, 0x63, 0x00, 0xF4, 0x09, 0xF2, 0xBD, 0xDB, 0xFF, 0xFF, 0x0A, 0xF2, 0xBD, 0xDB, 0x0B, 0xF2,
+	 0xFF, 0xFF, 0xBD, 0xDB, 0x0C, 0xF2, 0xA3, 0xDB, 0xFA, 0xA3, 0x26, 0x46, 0xA3, 0xD3, 0x24, 0xF0,
+	 0x00, 0x61, 0xD0, 0x84, 0xF1, 0x81, 0xD4, 0x84, 0xF1, 0x81, 0xBD, 0xDB, 0xA3, 0xD3, 0x03, 0xB1,
+	 0x03, 0xA9, 0x25, 0xF0, 0x42, 0xFE, 0x05, 0x03, 0xFD, 0xA1, 0xCC, 0x84, 0x01, 0x02, 0xCC, 0x84,
+	 0x00, 0x61, 0xF1, 0x81, 0xD0, 0x84, 0xF1, 0x81, 0xBD, 0xDB, 0xA3, 0xD3, 0x03, 0xB1, 0x03, 0xA9,
+	 0x28, 0xF0, 0x42, 0xFE, 0x01, 0x03, 0xCC, 0x84, 0xF1, 0x81, 0xD0, 0x84, 0xF1, 0x81, 0xBD, 0xDB,
+	 0xA3, 0xD3, 0x03, 0xB1, 0x03, 0xA9, 0x29, 0xF0, 0x01, 0x03, 0xCC, 0x84, 0xD0, 0x84, 0xA3, 0xDB,
+	 0x10, 0x60, 0x0A, 0xF3, 0xFF, 0xFF, 0x02, 0xA8, 0xFF, 0xFF, 0x02, 0x02, 0x2E, 0x58, 0xFF, 0xFF,
+	 0xF5, 0xFE, 0x10, 0x60, 0x02, 0xF1, 0x06, 0xA2, 0xA2, 0xD3, 0x64, 0x45, 0x60, 0x40, 0x80, 0x2B,
+	 0x03, 0x00, 0xFF, 0x60, 0xFF, 0x64, 0x94, 0x85, 0x00, 0x60, 0x96, 0x64, 0xD4, 0x80, 0xFF, 0xFF,
+	 0x0A, 0x06, 0x10, 0x60, 0x0A, 0xF3, 0x69, 0xF3, 0x00, 0xA8, 0x04, 0xB0, 0x04, 0x02, 0x03, 0x03,
+	 0x27, 0x60, 0x33, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x00, 0xF4, 0x09, 0xF2, 0x5A, 0xD2, 0x40, 0x48,
+	 0x40, 0x4A, 0x5A, 0xD2, 0x5A, 0xD2, 0x40, 0x4C, 0x60, 0x41, 0x5A, 0xD0, 0x7E, 0xF9, 0x40, 0x63,
+	 0xAD, 0x80, 0xF0, 0xA3, 0x09, 0x02, 0x3C, 0x03, 0x2C, 0x41, 0x2A, 0x44, 0x40, 0x4C, 0x28, 0x44,
+	 0x40, 0x4A, 0x00, 0x64, 0x40, 0x48, 0xF4, 0x01, 0xD1, 0x80, 0x01, 0x02, 0x31, 0x04, 0x10, 0xA3,
+	 0x80, 0x60, 0x00, 0x65, 0xA5, 0x80, 0xCF, 0x83, 0x08, 0x02, 0x28, 0x44, 0x60, 0x88, 0x2A, 0x44,
+	 0x70, 0x8A, 0x2C, 0x44, 0x70, 0x8C, 0xF1, 0x81, 0xF5, 0x01, 0xE7, 0xA3, 0x64, 0x44, 0x00, 0xA8,
+	 0x00, 0x62, 0x02, 0x02, 0x00, 0x61, 0x1C, 0x00, 0xE0, 0x84, 0xDE, 0x82, 0xFD, 0x04, 0x42, 0xFE,
+	 0xF8, 0x84, 0x62, 0x45, 0xC7, 0x83, 0x60, 0x45, 0x02, 0xFE, 0xD5, 0x84, 0x02, 0x05, 0x01, 0x05,
+	 0x61, 0x44, 0xCF, 0x83, 0x60, 0x41, 0x08, 0x03, 0x28, 0x44, 0x60, 0x88, 0x2A, 0x44, 0x70, 0x8A,
+	 0x2C, 0x44, 0x70, 0x8C, 0xF1, 0x81, 0xF1, 0x01, 0xCE, 0x82, 0xE9, 0x81, 0xFD, 0x02, 0xF1, 0x81,
+	 0x09, 0xF2, 0xFF, 0xFF, 0x60, 0x47, 0xE8, 0x84, 0xE8, 0x84, 0x5A, 0xD2, 0x3F, 0xB5, 0xE0, 0x84,
+	 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xB4, 0x84, 0x61, 0x45, 0xD4, 0x84,
+	 0xC0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x93, 0x10, 0x60, 0x0A, 0xF3, 0xFF, 0xFF,
+	 0x02, 0x18, 0x2E, 0x58, 0xFF, 0xFF, 0x16, 0x65, 0x32, 0x40, 0x80, 0x26, 0x16, 0x65, 0x73, 0x44,
+	 0xD4, 0x93, 0x69, 0xF3, 0x26, 0x46, 0x04, 0xBC, 0xA2, 0xDB, 0x26, 0xF0, 0xFF, 0x67, 0x20, 0x88,
+	 0x64, 0x5F, 0x40, 0x4A, 0x24, 0x60, 0x58, 0x4E, 0x80, 0x78, 0xFF, 0xFF, 0x0A, 0x48, 0x24, 0x60,
+	 0x58, 0x4E, 0x90, 0x78, 0xFF, 0xFF, 0x24, 0x60, 0x58, 0x4E, 0xAC, 0x78, 0xFF, 0xFF, 0x6B, 0xF3,
+	 0xFF, 0xFF, 0xC8, 0x84, 0xFF, 0xFF, 0x01, 0x05, 0x00, 0x64, 0x6B, 0xFB, 0x08, 0x60, 0x0C, 0xF1,
+	 0x00, 0x60, 0x40, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x1C, 0x60, 0xCE, 0x64, 0x13, 0x60,
+	 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x08, 0x60, 0x0C, 0xF1, 0xFF, 0x60,
+	 0xDF, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x26, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x1E, 0xF1,
+	 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x1C, 0x60,
+	 0xDA, 0x63, 0xA3, 0xDF, 0x06, 0xA3, 0x10, 0x60, 0xA4, 0x64, 0xBD, 0xDB, 0xBD, 0xDB, 0x06, 0x64,
+	 0xA3, 0xDB, 0x27, 0x60, 0x68, 0x64, 0x08, 0x60, 0x51, 0xFB, 0x10, 0x60, 0x0F, 0xF1, 0x0E, 0x60,
+	 0x6F, 0xF9, 0x27, 0x60, 0xCF, 0x64, 0x08, 0x60, 0x38, 0xFB, 0x11, 0x60, 0x44, 0x63, 0x08, 0x60,
+	 0x66, 0xFD, 0x12, 0x60, 0x40, 0x63, 0x08, 0x60, 0x67, 0xFD, 0xCF, 0xF3, 0x02, 0x63, 0x01, 0x1B,
+	 0xCF, 0xFD, 0xCF, 0xF3, 0xFF, 0xFF, 0xF7, 0xA0, 0x01, 0x64, 0x01, 0x06, 0xCF, 0xFB, 0xCF, 0xF3,
+	 0xCF, 0xFB, 0xCF, 0xF3, 0x12, 0x60, 0x78, 0x63, 0x26, 0x18, 0xCC, 0x84, 0xFF, 0xFF, 0x02, 0x03,
+	 0x2A, 0xA3, 0xFB, 0x01, 0x63, 0x46, 0x10, 0x60, 0xF2, 0x63, 0x0E, 0x61, 0x60, 0xFE, 0xA6, 0xD1,
+	 0xDE, 0x86, 0x01, 0x64, 0x64, 0x40, 0x7F, 0x36, 0x00, 0x64, 0xA3, 0xDB, 0xDB, 0x83, 0xA3, 0xD9,
+	 0xCD, 0x81, 0x04, 0xA3, 0xF4, 0x02, 0x11, 0x60, 0x62, 0x63, 0x1C, 0x61, 0xA6, 0xD1, 0xDE, 0x86,
+	 0x01, 0x64, 0x64, 0x40, 0x7F, 0x36, 0x00, 0x64, 0xA3, 0xDB, 0xDB, 0x83, 0xA3, 0xD9, 0xCD, 0x81,
+	 0x06, 0xA3, 0xF4, 0x02, 0x20, 0xFE, 0x00, 0x60, 0x60, 0x64, 0x08, 0x60, 0x1F, 0xFB, 0x27, 0x60,
+	 0xE1, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x11, 0x60, 0x44, 0x63, 0x08, 0x60,
+	 0x66, 0xFD, 0x12, 0x60, 0x40, 0x63, 0x08, 0x60, 0x67, 0xFD, 0x00, 0x60, 0x60, 0x64, 0x08, 0x60,
+	 0x1F, 0xFB, 0x27, 0x60, 0xE1, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x28, 0xF3,
+	 0xFF, 0xFF, 0x60, 0x47, 0x0F, 0xB4, 0x98, 0x00, 0xFF, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x04, 0x64,
+	 0x13, 0x60, 0x1C, 0xFB, 0x27, 0x00, 0x0C, 0x64, 0x3F, 0x40, 0x02, 0x2B, 0x23, 0x00, 0x29, 0xF1,
+	 0x13, 0x60, 0x1C, 0xFB, 0x5A, 0xD9, 0x27, 0x60, 0xFD, 0x64, 0x9F, 0xFB, 0xFF, 0xFF, 0x2D, 0xFF,
+	 0x2A, 0x60, 0x1D, 0x78, 0xFF, 0xFF, 0x29, 0x60, 0x1C, 0x63, 0x09, 0x61, 0x3D, 0x60, 0x58, 0x4D,
+	 0x23, 0x78, 0xFF, 0xFF, 0x75, 0x00, 0x95, 0xF3, 0xFF, 0xFF, 0x7F, 0xB4, 0x95, 0xFB, 0x06, 0x64,
+	 0x13, 0x60, 0x1C, 0xFB, 0xFF, 0xFF, 0x2D, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x08, 0x64,
+	 0x13, 0x60, 0x1C, 0xFB, 0x28, 0x60, 0x7A, 0x64, 0x9F, 0xFB, 0xFF, 0xFF, 0x2D, 0xFF, 0x2A, 0x60,
+	 0x1D, 0x78, 0xFF, 0xFF, 0x29, 0xF3, 0x12, 0x60, 0x45, 0x65, 0x60, 0x5C, 0x3F, 0x40, 0x02, 0x2B,
+	 0x13, 0x00, 0x00, 0x37, 0x11, 0x00, 0x01, 0x3B, 0x53, 0x00, 0x11, 0x60, 0x65, 0x63, 0xFF, 0xB7,
+	 0x60, 0x5C, 0xA3, 0xD3, 0x08, 0xA3, 0x00, 0x7E, 0xD0, 0x80, 0xD7, 0x80, 0x02, 0x03, 0xF9, 0x02,
+	 0x47, 0x00, 0xF4, 0xA3, 0xA3, 0xD3, 0x05, 0x00, 0x00, 0xBC, 0xF2, 0xA4, 0x41, 0x03, 0x40, 0x07,
+	 0x64, 0x44, 0x7D, 0xFB, 0xA1, 0xFB, 0x07, 0x64, 0xA2, 0xFB, 0x28, 0x60, 0x7A, 0x64, 0x9F, 0xFB,
+	 0xFF, 0xFF, 0xDF, 0xFE, 0x00, 0x64, 0x19, 0xFF, 0x2A, 0x60, 0x1D, 0x78, 0xFF, 0xFF, 0x88, 0xFF,
+	 0xBA, 0x60, 0x98, 0x71, 0x8D, 0xE2, 0x01, 0x11, 0x09, 0x00, 0x71, 0x40, 0x80, 0x27, 0xFB, 0x01,
+	 0x88, 0xE2, 0xBA, 0x60, 0xD0, 0x64, 0x03, 0xFB, 0x8D, 0xFF, 0x15, 0x00, 0x8D, 0xFF, 0x28, 0x60,
+	 0xFB, 0x63, 0x06, 0x60, 0x0B, 0xFD, 0xFF, 0xFF, 0x62, 0xFF, 0x28, 0x60, 0x67, 0x63, 0x9F, 0xFD,
+	 0xFF, 0xFF, 0x1A, 0xFF, 0x2A, 0x60, 0x1D, 0x78, 0xFF, 0xFF, 0xA3, 0x60, 0xF4, 0x63, 0x06, 0x60,
+	 0x0B, 0xFD, 0xFF, 0xFF, 0x62, 0xFF, 0x29, 0xF5, 0x26, 0x60, 0x20, 0x63, 0x25, 0x60, 0xF2, 0x64,
+	 0xBD, 0xDB, 0x66, 0x44, 0xBD, 0xDB, 0x02, 0x64, 0xA3, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xF9, 0xFE,
+	 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x68, 0x01, 0x00, 0x36, 0x69, 0x01, 0x01, 0x36, 0x6B, 0x01,
+	 0x02, 0x36, 0x81, 0x01, 0x03, 0x36, 0x8B, 0x01, 0x04, 0x36, 0xC1, 0x01, 0x05, 0x36, 0xBF, 0x01,
+	 0x06, 0x36, 0xF1, 0x01, 0x07, 0x36, 0xBB, 0x01, 0x08, 0x36, 0x8C, 0x01, 0x09, 0x36, 0x0C, 0x00,
+	 0x0A, 0x36, 0x0D, 0x00, 0x0B, 0x36, 0x0E, 0x00, 0x0C, 0x36, 0x17, 0x00, 0x0D, 0x36, 0x0D, 0x00,
+	 0x0E, 0x36, 0x1D, 0x00, 0x0F, 0x36, 0x41, 0x00, 0x02, 0x60, 0x00, 0x64, 0x08, 0x00, 0x04, 0x60,
+	 0x00, 0x64, 0x05, 0x00, 0x00, 0x60, 0x01, 0x64, 0x02, 0x00, 0x20, 0x60, 0x00, 0x64, 0x32, 0x45,
+	 0xB4, 0x85, 0x45, 0x52, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x29, 0x60, 0xDE, 0x63, 0x06, 0x60,
+	 0x0B, 0xFD, 0x62, 0xFF, 0xFF, 0xFF, 0x1A, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x3F, 0x40,
+	 0x02, 0x2B, 0x15, 0x00, 0x88, 0xFF, 0xBA, 0x60, 0x98, 0x71, 0x8D, 0xE2, 0x01, 0x11, 0x09, 0x00,
+	 0x71, 0x40, 0x80, 0x27, 0xFB, 0x01, 0x88, 0xE2, 0xBA, 0x60, 0xD0, 0x64, 0x03, 0xFB, 0x8D, 0xFF,
+	 0x11, 0x00, 0x8D, 0xFF, 0x90, 0x60, 0x00, 0xE8, 0x28, 0x60, 0xFB, 0x63, 0x04, 0x00, 0x91, 0x60,
+	 0x00, 0xE8, 0x29, 0x60, 0xC4, 0x63, 0x2A, 0xE8, 0x06, 0x60, 0x0B, 0xFD, 0xFF, 0xFF, 0x62, 0xFF,
+	 0xFF, 0xFF, 0x1A, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0xF1, 0xF3, 0xFF, 0xFF, 0xEF, 0xB4,
+	 0xF1, 0xFB, 0xAD, 0x4F, 0xFD, 0xB4, 0xA0, 0x5D, 0xD0, 0x60, 0x00, 0xE8, 0x2A, 0xE8, 0xD9, 0x60,
+	 0xFE, 0x64, 0x32, 0x45, 0xA4, 0x85, 0x45, 0x52, 0x99, 0xFF, 0xA5, 0x4F, 0xFF, 0xB4, 0x07, 0xFB,
+	 0x98, 0xFF, 0xA3, 0x60, 0xF4, 0x63, 0x06, 0x60, 0x0B, 0xFD, 0x62, 0xFF, 0x00, 0x67, 0x23, 0x58,
+	 0xFF, 0xFF, 0x08, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x43, 0xFF, 0x01, 0x60, 0x00, 0xE1, 0x28, 0xF3,
+	 0x47, 0xFF, 0x60, 0x40, 0x07, 0x37, 0x66, 0x00, 0x05, 0x3B, 0x04, 0x00, 0xFF, 0x0A, 0x80, 0xE1,
+	 0xA1, 0xFF, 0xFF, 0xFF, 0x1B, 0x60, 0xF3, 0xF1, 0xAD, 0x4F, 0x00, 0x7F, 0xFA, 0xB4, 0x64, 0x41,
+	 0x7D, 0xF1, 0x02, 0xB1, 0x04, 0x65, 0x02, 0x02, 0x64, 0x40, 0x01, 0x2B, 0x01, 0x65, 0xB4, 0x84,
+	 0xA0, 0x5D, 0x29, 0xF5, 0x2A, 0xF3, 0x47, 0xFF, 0x3F, 0xF0, 0x01, 0x1B, 0x01, 0x64, 0x60, 0x56,
+	 0xAD, 0xE2, 0xB5, 0xFF, 0x6C, 0x40, 0x40, 0xE1, 0xA1, 0xFF, 0x00, 0xF4, 0x6E, 0x61, 0x12, 0x62,
+	 0x64, 0x43, 0x01, 0xE1, 0x03, 0x64, 0xE2, 0xD0, 0xC9, 0x81, 0x64, 0x4C, 0xCC, 0x84, 0xDA, 0x82,
+	 0xFA, 0x02, 0x01, 0x60, 0x00, 0x6B, 0x9A, 0xFF, 0xCA, 0x82, 0x03, 0x00, 0x00, 0xF4, 0x81, 0xF2,
+	 0xFF, 0xFF, 0x7A, 0xD0, 0xA1, 0xFF, 0x64, 0x4C, 0xFC, 0x1C, 0xF8, 0x1D, 0x00, 0xB9, 0x06, 0x1E,
+	 0x02, 0x02, 0x00, 0xF4, 0xDA, 0x82, 0x5A, 0xD2, 0xA1, 0xFF, 0x60, 0x4D, 0x3F, 0x40, 0x02, 0x2B,
+	 0x10, 0x00, 0x28, 0xF3, 0xA5, 0x60, 0xC4, 0x65, 0x60, 0x40, 0x0E, 0x3B, 0x0A, 0x00, 0xF1, 0xF3,
+	 0xFF, 0xFF, 0x10, 0xBC, 0xF1, 0xFB, 0xAD, 0x4F, 0x02, 0xBC, 0x00, 0x7F, 0xA0, 0x5D, 0x85, 0x4C,
+	 0xFE, 0x01, 0xF1, 0xF3, 0xFF, 0xFF, 0x02, 0xBC, 0xF1, 0xFB, 0xA1, 0xFF, 0x87, 0x4E, 0x87, 0x4C,
+	 0x87, 0x4C, 0x87, 0x4C, 0x87, 0x4C, 0x67, 0x4C, 0xFF, 0xFF, 0xBC, 0xFF, 0x00, 0xE1, 0xD5, 0xFE,
+	 0xA1, 0xFF, 0xFF, 0xFF, 0x00, 0x64, 0x40, 0x46, 0x60, 0x41, 0xB5, 0xFF, 0xB7, 0xFF, 0xB4, 0xFF,
+	 0x29, 0xF5, 0x3F, 0xF0, 0x24, 0xF2, 0x44, 0x43, 0x40, 0x4D, 0x00, 0xF4, 0xF3, 0x60, 0xA0, 0x65,
+	 0x10, 0x62, 0x5A, 0xD2, 0xD9, 0x81, 0xD4, 0x80, 0xFF, 0xFF, 0xFB, 0x02, 0x61, 0x45, 0x2D, 0x44,
+	 0xD4, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xFD, 0xA5, 0x48, 0x60, 0x00, 0x64, 0xC4, 0x9D,
+	 0x0D, 0x60, 0x00, 0x6B, 0x2D, 0x44, 0xC0, 0x83, 0xBB, 0xFF, 0x29, 0xF5, 0x01, 0xE1, 0x00, 0xF4,
+	 0x6C, 0x61, 0x10, 0x62, 0x05, 0x00, 0x00, 0xF4, 0x01, 0xF2, 0xFF, 0xFF, 0x60, 0x41, 0x04, 0x62,
+	 0xA1, 0xFF, 0xFF, 0xFF, 0x01, 0x10, 0x1A, 0x00, 0x26, 0x44, 0x01, 0x26, 0x0C, 0x00, 0x2D, 0x44,
+	 0xC8, 0x84, 0x40, 0x4D, 0x02, 0x03, 0x6C, 0x45, 0xF3, 0x01, 0x03, 0x15, 0x01, 0x64, 0x05, 0xFA,
+	 0x15, 0x00, 0x6C, 0x45, 0xED, 0x01, 0x23, 0x44, 0xC8, 0x84, 0x40, 0x43, 0x02, 0x03, 0x6C, 0x45,
+	 0xE7, 0x01, 0x00, 0x64, 0x01, 0x15, 0x01, 0x64, 0x6C, 0x45, 0x05, 0xFB, 0xE2, 0xD2, 0xDA, 0x82,
+	 0xC9, 0x81, 0x60, 0x4C, 0xDD, 0x1C, 0xD7, 0x03, 0xBC, 0xFF, 0xDA, 0x01, 0x00, 0xE1, 0xD5, 0xFE,
+	 0xA1, 0xFF, 0xFF, 0xFF, 0x08, 0xE1, 0xA1, 0xFF, 0x67, 0x4C, 0x43, 0xFF, 0xF1, 0xF3, 0xFF, 0xFF,
+	 0x10, 0xBC, 0xF1, 0xFB, 0xAD, 0x4F, 0x02, 0xBC, 0x00, 0x7F, 0xA0, 0x5D, 0x01, 0xE1, 0x01, 0x60,
+	 0x69, 0x6B, 0xA5, 0x60, 0xC4, 0x64, 0x60, 0x4C, 0xBB, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0x60, 0x4C,
+	 0xA1, 0xFF, 0xFF, 0xFF, 0x60, 0x4C, 0xFC, 0x01, 0x29, 0xF3, 0x2A, 0xF1, 0x07, 0xB5, 0x04, 0xE1,
+	 0x65, 0x41, 0x64, 0x54, 0xCD, 0xE2, 0x95, 0x81, 0xA1, 0x5D, 0xA1, 0xFF, 0xFF, 0xFF, 0xF9, 0x01,
+	 0x61, 0x44, 0xFE, 0xFB, 0xFF, 0xFD, 0xFF, 0x01, 0x7F, 0x67, 0x01, 0x61, 0x23, 0x58, 0xFF, 0xFF,
+	 0xB1, 0xFE, 0x08, 0x05, 0xB0, 0xFE, 0x09, 0x05, 0xB2, 0xFE, 0xB3, 0xFE, 0x78, 0x43, 0x01, 0x61,
+	 0x29, 0x60, 0xEA, 0x78, 0x34, 0x60, 0x8D, 0x78, 0xFF, 0xFF, 0x28, 0xF3, 0x29, 0xF1, 0x40, 0x44,
+	 0x44, 0x45, 0x2A, 0xF1, 0x2B, 0xF1, 0x44, 0x46, 0x44, 0x47, 0x3F, 0xB4, 0xE0, 0x85, 0x20, 0x60,
+	 0x28, 0x64, 0x44, 0xD7, 0x58, 0x43, 0xFF, 0xFF, 0x60, 0x45, 0x0E, 0x60, 0xDD, 0xF3, 0x61, 0x43,
+	 0x04, 0xB4, 0x24, 0x44, 0x02, 0x03, 0x13, 0xFF, 0x06, 0x00, 0x3F, 0xB4, 0xB4, 0x84, 0xFF, 0x27,
+	 0x05, 0xFD, 0x04, 0xFB, 0x10, 0x75, 0xA1, 0xFF, 0xFF, 0xFF, 0x86, 0x3E, 0xB4, 0xFE, 0x0B, 0x05,
+	 0xB5, 0xFE, 0x02, 0x24, 0x9F, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xB7, 0xFE, 0x07, 0x05, 0x78, 0x43,
+	 0x01, 0x61, 0x29, 0x60, 0xEA, 0x78, 0x34, 0x60, 0xC8, 0x78, 0xFF, 0xFF, 0x36, 0x44, 0x00, 0x7F,
+	 0xEE, 0xA0, 0x60, 0x45, 0x05, 0x05, 0x20, 0x60, 0xBA, 0x64, 0x44, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x78, 0x43, 0x01, 0x61, 0x29, 0x60, 0xEA, 0x78, 0x78, 0x43, 0x01, 0x61, 0x29, 0x60, 0xEA, 0x78,
+	 0x7F, 0x60, 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80, 0x7F, 0x67, 0x02, 0x61, 0x10, 0x02, 0x10, 0x64,
+	 0x40, 0x40, 0x02, 0x64, 0x40, 0x50, 0x61, 0xFF, 0x3F, 0x40, 0x40, 0x26, 0x04, 0x00, 0x10, 0xE0,
+	 0x46, 0x60, 0x09, 0xE0, 0x00, 0x00, 0x27, 0xF1, 0x00, 0x66, 0x20, 0x78, 0x42, 0xFE, 0x23, 0x58,
+	 0xFF, 0xFF, 0x7F, 0x60, 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80, 0x7F, 0x67, 0x02, 0x61, 0x1A, 0x02,
+	 0x0E, 0x60, 0xDD, 0xF3, 0x07, 0x7C, 0x20, 0xB5, 0x0C, 0xB5, 0x04, 0x03, 0x03, 0x02, 0xDB, 0xF9,
+	 0x00, 0x67, 0x10, 0x00, 0x00, 0x61, 0x41, 0x56, 0xC7, 0xFE, 0xAD, 0x01, 0x36, 0x47, 0xFF, 0x23,
+	 0x04, 0x00, 0x00, 0x7F, 0x60, 0x41, 0x7F, 0x67, 0x05, 0x00, 0x62, 0xFF, 0x20, 0x44, 0x80, 0xBC,
+	 0x40, 0x40, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x7F, 0x60, 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80,
+	 0x7F, 0x67, 0x02, 0x61, 0x31, 0x02, 0x0E, 0x60, 0xDD, 0xF3, 0x01, 0x7C, 0x20, 0xB5, 0x0C, 0xB5,
+	 0x03, 0x03, 0x02, 0x02, 0xDB, 0xF9, 0xFF, 0xFF, 0x02, 0x61, 0x41, 0x56, 0xC7, 0xFE, 0x2A, 0x60,
+	 0x1D, 0x78, 0xFF, 0xFF, 0x9D, 0xF1, 0x20, 0x44, 0x64, 0x40, 0xFF, 0x26, 0x1C, 0x00, 0x7F, 0xB4,
+	 0x40, 0x40, 0x5C, 0x5E, 0x82, 0xFF, 0x26, 0x44, 0xFD, 0xB4, 0x40, 0x46, 0x5C, 0x41, 0x87, 0xFF,
+	 0x62, 0xFF, 0x13, 0x60, 0x02, 0xF3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x04, 0x03, 0x09, 0xF2,
+	 0x8F, 0xFC, 0xAC, 0x86, 0xFB, 0x01, 0x95, 0xF3, 0xFF, 0xFF, 0x7F, 0xB4, 0x95, 0xFB, 0x06, 0x64,
+	 0x13, 0x60, 0x1C, 0xFB, 0x2D, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x00, 0x67, 0x20, 0x40,
+	 0x80, 0x2A, 0x02, 0x00, 0x7F, 0x67, 0x06, 0x61, 0x60, 0x45, 0x0E, 0x60, 0xDD, 0xF3, 0x61, 0x43,
+	 0x04, 0xB4, 0x24, 0x44, 0x02, 0x03, 0x13, 0xFF, 0x56, 0x01, 0x3F, 0xB4, 0xB4, 0x84, 0xFF, 0x27,
+	 0x05, 0xFD, 0x04, 0xFB, 0x20, 0x40, 0x80, 0x2A, 0x02, 0x00, 0x10, 0x75, 0x05, 0x00, 0x01, 0x64,
+	 0x19, 0x60, 0xF7, 0xFB, 0x08, 0x60, 0x10, 0x75, 0x46, 0x01, 0x25, 0x46, 0x01, 0xF2, 0x08, 0xF0,
+	 0x60, 0x47, 0x03, 0xB4, 0x03, 0xAC, 0x7F, 0x67, 0x03, 0x61, 0x08, 0x02, 0x26, 0x60, 0x20, 0x64,
+	 0x40, 0x4B, 0x34, 0x60, 0x58, 0x4D, 0x08, 0x78, 0xFF, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x24, 0x40, 0x01, 0x2B, 0x49, 0x00, 0x25, 0x44, 0x1F, 0xB4, 0xE0, 0x85, 0x2A, 0x60, 0xF4, 0x64,
+	 0xC4, 0x98, 0xFF, 0xFF, 0xC0, 0xFE, 0x3D, 0x00, 0xC1, 0xFE, 0x3B, 0x00, 0xC2, 0xFE, 0x39, 0x00,
+	 0xC3, 0xFE, 0x37, 0x00, 0xC4, 0xFE, 0x35, 0x00, 0xC5, 0xFE, 0x33, 0x00, 0xC6, 0xFE, 0x31, 0x00,
+	 0xC7, 0xFE, 0x2F, 0x00, 0xC8, 0xFE, 0x2D, 0x00, 0xC9, 0xFE, 0x2B, 0x00, 0xCA, 0xFE, 0x29, 0x00,
+	 0xCB, 0xFE, 0x27, 0x00, 0xCC, 0xFE, 0x25, 0x00, 0xCD, 0xFE, 0x23, 0x00, 0xCE, 0xFE, 0x21, 0x00,
+	 0xCF, 0xFE, 0x1F, 0x00, 0xD0, 0xFE, 0x1D, 0x00, 0xD1, 0xFE, 0x1B, 0x00, 0xD2, 0xFE, 0x19, 0x00,
+	 0xD3, 0xFE, 0x17, 0x00, 0xD4, 0xFE, 0x15, 0x00, 0xD5, 0xFE, 0x13, 0x00, 0xD6, 0xFE, 0x11, 0x00,
+	 0xD7, 0xFE, 0x0F, 0x00, 0xD8, 0xFE, 0x0D, 0x00, 0xD9, 0xFE, 0x0B, 0x00, 0xDA, 0xFE, 0x09, 0x00,
+	 0xDB, 0xFE, 0x07, 0x00, 0xDC, 0xFE, 0x05, 0x00, 0xDD, 0xFE, 0x03, 0x00, 0xDE, 0xFE, 0x01, 0x00,
+	 0xDF, 0xFE, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x00, 0x64, 0x9F, 0xFE, 0xF0, 0x84, 0xFF, 0xFF,
+	 0x9E, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x9D, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x9C, 0xFE, 0xF0, 0x84,
+	 0xFF, 0xFF, 0x9B, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x9A, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x99, 0xFE,
+	 0xF0, 0x84, 0xFF, 0xFF, 0x98, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x97, 0xFE, 0xF0, 0x84, 0xFF, 0xFF,
+	 0x96, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x95, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x94, 0xFE, 0xF0, 0x84,
+	 0xFF, 0xFF, 0x93, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x92, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x91, 0xFE,
+	 0xF0, 0x84, 0xFF, 0xFF, 0x90, 0xFE, 0xF0, 0x84, 0x06, 0xFB, 0x8F, 0xFE, 0xF0, 0x84, 0xFF, 0xFF,
+	 0x8E, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x8D, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x8C, 0xFE, 0xF0, 0x84,
+	 0xFF, 0xFF, 0x8B, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x8A, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x89, 0xFE,
+	 0xF0, 0x84, 0xFF, 0xFF, 0x88, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x87, 0xFE, 0xF0, 0x84, 0xFF, 0xFF,
+	 0x86, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x85, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x84, 0xFE, 0xF0, 0x84,
+	 0xFF, 0xFF, 0x83, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x82, 0xFE, 0xF0, 0x84, 0xFF, 0xFF, 0x81, 0xFE,
+	 0xF0, 0x84, 0xFF, 0xFF, 0x80, 0xFE, 0xF0, 0x84, 0x05, 0xFB, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x5C, 0x5C, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x24, 0x40, 0x01, 0x27, 0x55, 0x00, 0x05, 0x60,
+	 0x00, 0x63, 0x05, 0xFD, 0x30, 0x44, 0xBD, 0xDB, 0x31, 0x44, 0xBD, 0xDB, 0x32, 0x44, 0xBD, 0xDB,
+	 0x33, 0x44, 0xBD, 0xDB, 0x34, 0x44, 0xBD, 0xDB, 0x35, 0x44, 0xBD, 0xDB, 0x36, 0x44, 0xBD, 0xDB,
+	 0x37, 0x44, 0xBD, 0xDB, 0x38, 0x44, 0xBD, 0xDB, 0x39, 0x44, 0xBD, 0xDB, 0x3A, 0x44, 0xBD, 0xDB,
+	 0x3B, 0x44, 0xBD, 0xDB, 0x3C, 0x44, 0xBD, 0xDB, 0x3D, 0x44, 0xBD, 0xDB, 0x3E, 0x44, 0xBD, 0xDB,
+	 0x3F, 0x44, 0xBD, 0xDB, 0x02, 0x61, 0x61, 0x44, 0x02, 0x36, 0x82, 0xFF, 0x03, 0x36, 0x83, 0xFF,
+	 0x04, 0x36, 0x84, 0xFF, 0x05, 0x36, 0x85, 0xFF, 0x06, 0x36, 0x86, 0xFF, 0x07, 0x36, 0x87, 0xFF,
+	 0x20, 0x44, 0xBD, 0xDB, 0x21, 0x44, 0xBD, 0xDB, 0x22, 0x44, 0xBD, 0xDB, 0x23, 0x44, 0xBD, 0xDB,
+	 0x24, 0x44, 0xBD, 0xDB, 0x25, 0x44, 0xBD, 0xDB, 0x26, 0x44, 0xBD, 0xDB, 0x27, 0x44, 0xBD, 0xDB,
+	 0x28, 0x44, 0xBD, 0xDB, 0x29, 0x44, 0xBD, 0xDB, 0x2A, 0x44, 0xBD, 0xDB, 0x2B, 0x44, 0xBD, 0xDB,
+	 0x2C, 0x44, 0xBD, 0xDB, 0x2D, 0x44, 0xBD, 0xDB, 0x2E, 0x44, 0xBD, 0xDB, 0x2F, 0x44, 0xBD, 0xDB,
+	 0xDD, 0x81, 0x08, 0x3A, 0xD0, 0x01, 0x54, 0x00, 0x27, 0x40, 0x10, 0x26, 0x30, 0x00, 0x26, 0x44,
+	 0x01, 0x36, 0x2D, 0x00, 0x02, 0x36, 0x82, 0xFF, 0x03, 0x36, 0x83, 0xFF, 0x04, 0x36, 0x84, 0xFF,
+	 0x05, 0x36, 0x85, 0xFF, 0x06, 0x36, 0x86, 0xFF, 0x25, 0x44, 0x00, 0x36, 0x44, 0x40, 0x01, 0x36,
+	 0x44, 0x41, 0x02, 0x36, 0x44, 0x42, 0x03, 0x36, 0x44, 0x43, 0x04, 0x36, 0x44, 0x44, 0x05, 0x36,
+	 0x44, 0x45, 0x06, 0x36, 0x44, 0x46, 0x07, 0x36, 0x44, 0x47, 0x08, 0x36, 0x44, 0x48, 0x09, 0x36,
+	 0x44, 0x49, 0x0A, 0x36, 0x44, 0x4A, 0x0B, 0x36, 0x44, 0x4B, 0x0C, 0x36, 0x44, 0x4C, 0x0D, 0x36,
+	 0x44, 0x4D, 0x0E, 0x36, 0x44, 0x4E, 0x0F, 0x36, 0x44, 0x4F, 0x87, 0xFF, 0x21, 0x00, 0x25, 0x44,
+	 0x10, 0x36, 0x44, 0x50, 0x11, 0x36, 0x44, 0x51, 0x12, 0x36, 0x44, 0x52, 0x13, 0x36, 0x44, 0x53,
+	 0x14, 0x36, 0x44, 0x54, 0x15, 0x36, 0x44, 0x55, 0x16, 0x36, 0x44, 0x56, 0x17, 0x36, 0x44, 0x57,
+	 0x18, 0x36, 0x44, 0x58, 0x19, 0x36, 0x44, 0x59, 0x1A, 0x36, 0x44, 0x5A, 0x1B, 0x36, 0x44, 0x5B,
+	 0x1C, 0x36, 0x44, 0x5C, 0x1D, 0x36, 0x44, 0x5D, 0x1E, 0x36, 0x44, 0x5E, 0x1F, 0x36, 0x44, 0x5F,
+	 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x25, 0x46, 0xB5, 0x60, 0x58, 0x4F, 0xCE, 0x78, 0xFF, 0xFF,
+	 0x03, 0x61, 0x7F, 0x67, 0x0A, 0x02, 0x00, 0xF0, 0x04, 0x64, 0x13, 0x60, 0x10, 0xFB, 0x5A, 0xD9,
+	 0x0A, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x40, 0x60,
+	 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80, 0x7F, 0x67, 0x02, 0x61, 0x12, 0x02, 0x14, 0x64, 0x13, 0x60,
+	 0x1C, 0xFB, 0x00, 0x60, 0x50, 0x63, 0x5A, 0xDD, 0x2C, 0x60, 0x75, 0x64, 0x9F, 0xFB, 0x2D, 0xFF,
+	 0x2A, 0x60, 0x1D, 0x78, 0xFF, 0xFF, 0x2A, 0xF3, 0x05, 0xFB, 0x2B, 0xF3, 0x06, 0xFB, 0x00, 0x67,
+	 0x23, 0x58, 0xFF, 0xFF, 0x40, 0x60, 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80, 0x7F, 0x67, 0x02, 0x61,
+	 0x0E, 0x02, 0x16, 0x64, 0x13, 0x60, 0x1C, 0xFB, 0x00, 0x60, 0x50, 0x63, 0x5A, 0xDD, 0x2C, 0x60,
+	 0x90, 0x64, 0x9F, 0xFB, 0x2D, 0xFF, 0x2A, 0x60, 0x1D, 0x78, 0xFF, 0xFF, 0x00, 0x67, 0x23, 0x58,
+	 0xFF, 0xFF, 0x7F, 0x60, 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80, 0x02, 0x61, 0x38, 0x02, 0x25, 0x45,
+	 0x20, 0x44, 0x80, 0x2A, 0x34, 0x00, 0xF1, 0x60, 0x00, 0x64, 0xD4, 0x80, 0xFF, 0xFF, 0x06, 0x03,
+	 0xF1, 0x60, 0x02, 0x64, 0xD4, 0x80, 0xFF, 0xFF, 0x2F, 0x03, 0x28, 0x00, 0x19, 0x60, 0x40, 0xF1,
+	 0xB7, 0xF3, 0x20, 0x60, 0x22, 0x61, 0xA0, 0x84, 0xA1, 0xDB, 0x25, 0x45, 0x25, 0x60, 0x86, 0x63,
+	 0x02, 0x61, 0xBD, 0xD3, 0xBD, 0xD1, 0xD4, 0x80, 0xBD, 0xD3, 0xBD, 0xD5, 0xCD, 0x81, 0x02, 0x03,
+	 0x15, 0x03, 0xF7, 0x01, 0xA2, 0xFF, 0xA6, 0xD3, 0x40, 0x4C, 0x00, 0xA8, 0x67, 0x43, 0x0C, 0x02,
+	 0xA2, 0xDD, 0x42, 0x48, 0x64, 0x41, 0xB6, 0x60, 0x58, 0x4D, 0x25, 0x78, 0xFF, 0xFF, 0x66, 0x44,
+	 0x28, 0xDB, 0x02, 0x03, 0x2C, 0x58, 0xA3, 0xFF, 0x0C, 0x61, 0x03, 0x00, 0x04, 0x61, 0x7F, 0x67,
+	 0x01, 0x00, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x01, 0x64, 0x10, 0x60, 0x13, 0xFB, 0xFF, 0xFF,
+	 0xC4, 0xFE, 0xF7, 0x01, 0xC6, 0xFE, 0xF5, 0x01, 0x7E, 0x60, 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80,
+	 0x02, 0x61, 0x3F, 0x02, 0x25, 0x45, 0xF8, 0x2B, 0x3B, 0x00, 0x2E, 0xF5, 0x67, 0x44, 0xD4, 0x80,
+	 0x20, 0x60, 0xCC, 0x63, 0x39, 0x03, 0x79, 0x61, 0x24, 0x44, 0x01, 0x27, 0x29, 0x00, 0xA3, 0xFC,
+	 0xA4, 0xF8, 0xBD, 0xD3, 0xA3, 0xD1, 0xD4, 0x80, 0xCD, 0x81, 0x08, 0x24, 0x64, 0x58, 0x08, 0xA3,
+	 0xF8, 0x02, 0x08, 0x60, 0x00, 0x63, 0xBD, 0xD3, 0xA3, 0xD1, 0xFE, 0xA0, 0xFA, 0x60, 0x00, 0x64,
+	 0xD0, 0x80, 0x14, 0x02, 0x13, 0x02, 0x04, 0xA3, 0xBE, 0xD3, 0xBD, 0xD1, 0x0F, 0x18, 0xD4, 0x80,
+	 0x0D, 0x18, 0x03, 0x03, 0xC3, 0x83, 0xC3, 0x83, 0xF7, 0x01, 0x64, 0x41, 0xDD, 0x81, 0xE1, 0x81,
+	 0xCB, 0x83, 0x46, 0x65, 0x36, 0x60, 0x58, 0x4F, 0x22, 0x78, 0xFF, 0xFF, 0x00, 0x67, 0x0A, 0x00,
+	 0xBD, 0xD3, 0xBE, 0xD1, 0xD4, 0x80, 0xCD, 0x81, 0x08, 0x24, 0x64, 0x58, 0x08, 0xA3, 0xF8, 0x02,
+	 0x04, 0x61, 0x7F, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x0F, 0x64, 0x23, 0xFA, 0x67, 0x44, 0x24, 0xFA,
+	 0x62, 0x41, 0x3C, 0x60, 0x00, 0x65, 0x1A, 0x63, 0x80, 0x60, 0x9E, 0x64, 0x65, 0x46, 0x58, 0xD0,
+	 0x2E, 0xF5, 0x59, 0xD8, 0xFB, 0x1F, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0xCB, 0x83, 0xBF, 0xD1,
+	 0x4A, 0x65, 0x64, 0x43, 0xBD, 0xD3, 0xFF, 0xFF, 0x60, 0x41, 0x01, 0x26, 0xDC, 0x81, 0xE9, 0x84,
+	 0xDC, 0x84, 0x23, 0xFA, 0x09, 0x00, 0x4B, 0xD3, 0xFF, 0xFF, 0x60, 0x41, 0xE8, 0x84, 0xDC, 0x84,
+	 0x23, 0xFA, 0xBF, 0xD1, 0x4A, 0x65, 0x64, 0x43, 0x36, 0x60, 0x58, 0x4F, 0x22, 0x78, 0xFF, 0xFF,
+	 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x25, 0xF2, 0xFF, 0xFF, 0xE0, 0xA0, 0x20, 0x64, 0x01, 0x06,
+	 0x25, 0xFA, 0x23, 0xF2, 0xDF, 0xD1, 0xCC, 0x84, 0xE0, 0x85, 0x0B, 0x06, 0xBF, 0xD1, 0x64, 0x41,
+	 0xD5, 0x80, 0x64, 0x43, 0x01, 0x06, 0x65, 0x41, 0x4A, 0x65, 0x2E, 0x60, 0x58, 0x4F, 0x7A, 0x78,
+	 0xFF, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0xDB, 0xF3, 0x02, 0x63, 0x23, 0xFC, 0x07, 0xB4,
+	 0x25, 0xFA, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x4B, 0xD3, 0xBF, 0xD3, 0x60, 0x41, 0xC9, 0x83,
+	 0xE9, 0x81, 0xDD, 0x81, 0xA3, 0xFA, 0xE0, 0x81, 0x3C, 0x60, 0x00, 0x67, 0x02, 0x24, 0x02, 0xA4,
+	 0x60, 0x47, 0x40, 0x4B, 0xC9, 0x81, 0x4A, 0x65, 0xAB, 0x46, 0x59, 0xD0, 0xAB, 0x46, 0xA5, 0xD8,
+	 0xDA, 0x85, 0x80, 0x3A, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0xF6, 0x1F, 0x00, 0x67, 0x23, 0x58,
+	 0xFF, 0xFF, 0xFC, 0xA3, 0xA3, 0xD1, 0x4C, 0x65, 0xA4, 0xD3, 0xDA, 0x83, 0x60, 0x47, 0x25, 0xFA,
+	 0x00, 0x7E, 0x60, 0x47, 0x01, 0x26, 0xDC, 0x84, 0x60, 0x41, 0xE8, 0x84, 0xD8, 0x84, 0x23, 0xFA,
+	 0xAB, 0x01, 0xFC, 0xA3, 0xA3, 0xD1, 0x4C, 0x65, 0xA4, 0xD3, 0xDA, 0x83, 0x00, 0x7F, 0x25, 0xFA,
+	 0x60, 0x41, 0x01, 0x26, 0xDD, 0x81, 0xE9, 0x84, 0xD8, 0x84, 0x23, 0xFA, 0x9D, 0x01, 0x2E, 0x60,
+	 0x40, 0x63, 0xBF, 0xD3, 0xFF, 0xFF, 0x60, 0x41, 0xE8, 0x84, 0xDC, 0x84, 0x23, 0xFA, 0x4A, 0x65,
+	 0x36, 0x60, 0x58, 0x4F, 0x22, 0x78, 0xFF, 0xFF, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x2E, 0x60,
+	 0x40, 0x63, 0x23, 0xF2, 0xC0, 0x65, 0xCC, 0x84, 0xE0, 0x81, 0x0A, 0x04, 0xBF, 0xDB, 0xD5, 0x80,
+	 0x07, 0x03, 0x01, 0x06, 0x65, 0x41, 0x61, 0x44, 0xBF, 0xDB, 0x4A, 0x65, 0x58, 0x4F, 0xA8, 0x00,
+	 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x03, 0x4E, 0x2D, 0x60, 0x58, 0x43, 0x55, 0x78, 0xFF, 0xFF,
+	 0x2F, 0x60, 0x24, 0x61, 0x17, 0x60, 0x81, 0xF3, 0xA1, 0xDB, 0xCC, 0x84, 0xA8, 0x83, 0x05, 0x04,
+	 0x2F, 0x60, 0x02, 0x64, 0x58, 0xD1, 0x59, 0xD9, 0xFD, 0x1F, 0x0E, 0x43, 0x82, 0x01, 0x23, 0xF2,
+	 0x25, 0xF2, 0x02, 0xA8, 0xF8, 0xA0, 0x0F, 0x02, 0xEC, 0xA0, 0x0D, 0x04, 0x0C, 0x07, 0x19, 0x60,
+	 0x4F, 0xF1, 0xFF, 0xFF, 0xD0, 0x80, 0xFF, 0xFF, 0x04, 0x07, 0x19, 0x60, 0x4F, 0xFB, 0x19, 0x60,
+	 0x53, 0xFB, 0x16, 0x60, 0xD8, 0xFB, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x23, 0xF2, 0x1D, 0x60,
+	 0xAE, 0x65, 0x60, 0x41, 0x1D, 0x60, 0x4A, 0x63, 0xA3, 0xDB, 0xFF, 0xA1, 0x48, 0x64, 0x58, 0xD0,
+	 0x7E, 0xA8, 0x5B, 0xD9, 0x02, 0x02, 0x00, 0xF4, 0x02, 0x64, 0xFF, 0xA1, 0xD7, 0x80, 0x02, 0x03,
+	 0x01, 0x03, 0xF5, 0x01, 0x2E, 0xF5, 0x00, 0x60, 0x2F, 0x65, 0x25, 0xF2, 0x00, 0x63, 0xCC, 0x84,
+	 0x03, 0xA3, 0xFD, 0x05, 0x4A, 0x64, 0xD7, 0x80, 0x1C, 0x60, 0xE6, 0x61, 0x18, 0x05, 0xA1, 0xDD,
+	 0xE3, 0x83, 0xFE, 0xA3, 0x58, 0xD0, 0x7E, 0xA8, 0x59, 0xD9, 0x02, 0x02, 0x00, 0xF4, 0x02, 0x64,
+	 0xF9, 0x1F, 0x00, 0x63, 0x59, 0xDD, 0x2E, 0xF5, 0x25, 0xF0, 0x0E, 0x60, 0x73, 0xF3, 0xD3, 0x80,
+	 0x01, 0xB0, 0x04, 0x03, 0x01, 0xA4, 0x03, 0x03, 0xA2, 0xDB, 0x01, 0x00, 0xA2, 0xDD, 0x00, 0x67,
+	 0x23, 0x58, 0xFF, 0xFF, 0x1D, 0x60, 0x4A, 0x61, 0xA1, 0xD3, 0x23, 0xFA, 0xE0, 0x83, 0x4A, 0x65,
+	 0x04, 0x02, 0x02, 0x63, 0x23, 0xFC, 0xA5, 0xFC, 0x09, 0x00, 0xDB, 0x83, 0x59, 0xD1, 0xA5, 0xD8,
+	 0xDA, 0x85, 0x80, 0x3A, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0xF8, 0x1F, 0x00, 0x67, 0x23, 0x58,
+	 0xFF, 0xFF, 0x0E, 0x60, 0x73, 0xF3, 0x00, 0x61, 0x02, 0xA4, 0xFE, 0xA0, 0x23, 0xFA, 0x1B, 0x03,
+	 0xFA, 0xA4, 0xFD, 0xA4, 0x01, 0xA1, 0xFD, 0x07, 0x61, 0x43, 0x23, 0xF2, 0x25, 0xFC, 0xE0, 0x83,
+	 0x02, 0xA3, 0x1C, 0x60, 0xE6, 0x61, 0x00, 0x60, 0x4A, 0x64, 0x59, 0xD1, 0x58, 0xD8, 0x7E, 0x3A,
+	 0x02, 0x00, 0x00, 0xF4, 0x02, 0x64, 0xF9, 0x1F, 0x25, 0xF2, 0x23, 0xF2, 0x01, 0xB0, 0xCC, 0x84,
+	 0x04, 0x02, 0x23, 0xFA, 0x02, 0x00, 0x00, 0x64, 0x25, 0xFA, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x41, 0x4B, 0x65, 0x42, 0x80, 0x64, 0xD4, 0x85, 0x2B, 0x41, 0x00, 0xA1, 0x55, 0x8B, 0x0D, 0x03,
+	 0x02, 0x04, 0x65, 0x41, 0x02, 0x00, 0x00, 0x64, 0x40, 0x4B, 0xCA, 0x84, 0x58, 0xD0, 0xC9, 0x81,
+	 0xBD, 0xD9, 0xFC, 0x02, 0x00, 0xF4, 0x04, 0x65, 0xEC, 0x01, 0x2F, 0x58, 0xFF, 0xFF, 0xFC, 0xA3,
+	 0xA3, 0xD3, 0x02, 0x7C, 0xA0, 0xD3, 0x23, 0xF8, 0xDC, 0x84, 0x25, 0xFA, 0x00, 0x67, 0x23, 0x58,
+	 0xFF, 0xFF, 0x02, 0x64, 0x23, 0xFA, 0x01, 0x64, 0x9D, 0xFE, 0x02, 0x28, 0x02, 0x64, 0x25, 0xFA,
+	 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x02, 0x7C, 0x23, 0xF8, 0x01, 0x64, 0x25, 0xFA, 0x00, 0x67,
+	 0x23, 0x58, 0xFF, 0xFF, 0xFC, 0xA3, 0xA3, 0xD1, 0x02, 0x64, 0x23, 0xFA, 0xA4, 0xD3, 0x25, 0xFA,
+	 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x02, 0x64, 0x23, 0xFA, 0x88, 0xFF, 0x75, 0x44, 0x8D, 0xFF,
+	 0xE8, 0x87, 0xE8, 0x84, 0xE8, 0x84, 0x03, 0xB4, 0x25, 0xFA, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x04, 0x64, 0x23, 0xFA, 0x86, 0xFF, 0x29, 0x44, 0x87, 0xFF, 0x25, 0xFA, 0x55, 0xF3, 0x52, 0xF1,
+	 0x80, 0x65, 0xC4, 0x87, 0x00, 0x7F, 0x26, 0xFA, 0x64, 0x44, 0xC4, 0x87, 0x00, 0x7F, 0x27, 0xFA,
+	 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x05, 0x64, 0x23, 0xFA, 0x52, 0x63, 0xB4, 0xF3, 0x4B, 0xDA,
+	 0xB3, 0xF3, 0x4B, 0xDA, 0xB2, 0xF3, 0x4B, 0xDA, 0x60, 0x41, 0x88, 0xFF, 0x72, 0x5C, 0x89, 0xFF,
+	 0x4A, 0xD8, 0xA2, 0x48, 0x20, 0x23, 0x0E, 0x00, 0x64, 0x40, 0x80, 0x27, 0x15, 0x00, 0xDC, 0x84,
+	 0xBD, 0xDA, 0xBD, 0xD2, 0x11, 0x04, 0xDC, 0x84, 0xA2, 0xDA, 0xA3, 0xD2, 0x0D, 0x04, 0xDC, 0x84,
+	 0xA3, 0xDA, 0x0A, 0x00, 0x52, 0x63, 0xB4, 0xF3, 0x4B, 0xDA, 0xB3, 0xF3, 0x4B, 0xDA, 0xB2, 0xF3,
+	 0x4B, 0xDA, 0x54, 0x90, 0x4C, 0x63, 0xE0, 0x02, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x25, 0xF0,
+	 0x23, 0xF2, 0x19, 0x60, 0x46, 0xF9, 0x02, 0xA8, 0x64, 0x44, 0x1F, 0x02, 0x3F, 0x40, 0x02, 0x2B,
+	 0x16, 0x00, 0x00, 0x37, 0x14, 0x00, 0x01, 0x3B, 0x18, 0x00, 0x12, 0x60, 0x45, 0x65, 0x11, 0x60,
+	 0x65, 0x63, 0xFF, 0xB7, 0x60, 0x5C, 0xA3, 0xD3, 0x08, 0xA3, 0x00, 0x7E, 0xD0, 0x80, 0xD7, 0x80,
+	 0x03, 0x03, 0xF9, 0x02, 0x7F, 0x67, 0x0A, 0x00, 0xF4, 0xA3, 0xA3, 0xD1, 0x04, 0x00, 0x00, 0xBC,
+	 0xF2, 0xA4, 0x03, 0x03, 0x02, 0x07, 0x16, 0x60, 0xCF, 0xF9, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x20, 0x63, 0x2E, 0x60, 0x00, 0x61, 0x48, 0x64, 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0x25, 0xF0,
+	 0x20, 0x64, 0xD0, 0x81, 0xFF, 0xFF, 0x02, 0x07, 0x25, 0xFA, 0x0F, 0x00, 0x2E, 0x60, 0x04, 0x63,
+	 0xC3, 0x83, 0x01, 0x2A, 0x06, 0x00, 0xCF, 0x83, 0xA3, 0xD3, 0xCD, 0x81, 0x00, 0x7F, 0xBD, 0xDB,
+	 0x04, 0x03, 0x00, 0x64, 0xC9, 0x81, 0xBD, 0xDB, 0xFD, 0x02, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x23, 0xF2, 0x25, 0xF0, 0x02, 0xA8, 0x01, 0x60, 0xA0, 0x62, 0x09, 0x02, 0xA2, 0xD9, 0x64, 0x41,
+	 0x32, 0x44, 0x02, 0xB5, 0x00, 0xB9, 0xD4, 0x84, 0x08, 0x28, 0x02, 0xBC, 0x40, 0x52, 0x00, 0x67,
+	 0x23, 0x58, 0xFF, 0xFF, 0x23, 0xF2, 0x25, 0xF0, 0x02, 0xA8, 0x01, 0x60, 0xA2, 0x62, 0x09, 0x02,
+	 0xA2, 0xD9, 0x64, 0x41, 0x32, 0x44, 0x04, 0xB5, 0x00, 0xB9, 0xD4, 0x84, 0x08, 0x28, 0x04, 0xBC,
+	 0x40, 0x52, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x23, 0xF2, 0x25, 0xF0, 0x02, 0xA8, 0x01, 0x60,
+	 0xB0, 0x62, 0x15, 0x02, 0xA2, 0xD9, 0x64, 0x41, 0x32, 0x44, 0x40, 0xB5, 0x00, 0xB9, 0xD4, 0x84,
+	 0x08, 0x24, 0x0C, 0x00, 0x40, 0xBC, 0x02, 0xB5, 0xD4, 0x84, 0x43, 0xF9, 0x37, 0x60, 0x76, 0x63,
+	 0xD3, 0x80, 0x2F, 0x60, 0x50, 0x7C, 0x02, 0x03, 0x43, 0xFD, 0xA4, 0xDF, 0x40, 0x52, 0x00, 0x67,
+	 0x23, 0x58, 0xFF, 0xFF, 0x37, 0x60, 0x76, 0x64, 0x43, 0xFB, 0x2D, 0x60, 0x5B, 0x78, 0xFF, 0xFF,
+	 0x23, 0xF2, 0x25, 0xF0, 0x01, 0x60, 0xAC, 0x63, 0x7F, 0x67, 0x39, 0x18, 0xA3, 0xD9, 0x26, 0xF0,
+	 0x7F, 0x67, 0x35, 0x18, 0x5B, 0xD9, 0x16, 0x60, 0x87, 0xF3, 0x25, 0xF0, 0x60, 0x40, 0x03, 0x3A,
+	 0x2D, 0x00, 0xA6, 0xF3, 0x20, 0x63, 0xE3, 0x83, 0x60, 0x46, 0x0F, 0xF8, 0x30, 0x61, 0x94, 0xFA,
+	 0x01, 0x61, 0x91, 0xFA, 0x16, 0x64, 0x12, 0xFA, 0x60, 0x40, 0x10, 0x36, 0x05, 0x00, 0x12, 0x36,
+	 0x08, 0x00, 0x0C, 0x36, 0x0B, 0x00, 0x0F, 0x00, 0x40, 0x61, 0xA1, 0x80, 0x0A, 0x64, 0x11, 0x02,
+	 0xF3, 0x01, 0x10, 0x61, 0xA1, 0x80, 0x0E, 0x64, 0x0C, 0x02, 0xEE, 0x01, 0x08, 0x61, 0xA1, 0x80,
+	 0x10, 0x64, 0x07, 0x02, 0xE9, 0x01, 0xE1, 0x81, 0xA1, 0x80, 0x05, 0x05, 0xC8, 0x84, 0x01, 0x02,
+	 0xE3, 0x01, 0x12, 0xFA, 0x91, 0xFA, 0x66, 0x44, 0x02, 0xA6, 0xD7, 0x1F, 0x00, 0x67, 0x23, 0x58,
+	 0xFF, 0xFF, 0x25, 0xF2, 0x19, 0x60, 0x45, 0xFB, 0x19, 0x60, 0x4C, 0xF3, 0xFF, 0xFF, 0x60, 0x40,
+	 0x08, 0x26, 0x18, 0x00, 0x19, 0x60, 0x45, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x2A, 0x0A, 0x00,
+	 0x19, 0x60, 0x7B, 0xF3, 0xFF, 0xFF, 0x02, 0xBC, 0x60, 0x44, 0xA2, 0xDB, 0x19, 0x60, 0x45, 0xF3,
+	 0xFF, 0xFF, 0x60, 0x40, 0x02, 0x2A, 0x06, 0x00, 0x19, 0x60, 0x7B, 0xF3, 0xFF, 0xFF, 0x04, 0xBC,
+	 0x60, 0x44, 0xA2, 0xDB, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x23, 0xF2, 0x25, 0xF0, 0x02, 0xA8,
+	 0x00, 0x67, 0x02, 0x02, 0x2D, 0xF9, 0x2C, 0xF9, 0x23, 0x58, 0xFF, 0xFF, 0x23, 0xF2, 0x25, 0xF2,
+	 0x02, 0xA8, 0x00, 0xA8, 0x0A, 0x02, 0x07, 0x03, 0xD0, 0xA0, 0x30, 0x65, 0x03, 0x04, 0xA7, 0xA0,
+	 0x59, 0x65, 0x01, 0x06, 0x65, 0x44, 0x16, 0x60, 0xCE, 0xFB, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x25, 0xF2, 0x19, 0x60, 0x4C, 0xFB, 0xFF, 0xFF, 0x08, 0x2A, 0x25, 0x00, 0x19, 0x60, 0x7B, 0xF3,
+	 0xFF, 0xFF, 0xE9, 0xB4, 0x60, 0x44, 0x19, 0x60, 0x4C, 0xF1, 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x26,
+	 0x02, 0xBC, 0x64, 0x40, 0x02, 0x2A, 0x04, 0xBC, 0x64, 0x40, 0x04, 0x26, 0x08, 0x00, 0x19, 0x60,
+	 0x7B, 0xFB, 0x13, 0x64, 0xCB, 0xFB, 0x01, 0x60, 0x67, 0x64, 0x37, 0xFB, 0x0C, 0x00, 0x10, 0xBC,
+	 0x19, 0x60, 0x7B, 0xFB, 0x08, 0x64, 0xCB, 0xFB, 0xA1, 0xF3, 0x01, 0x60, 0x67, 0x7C, 0x60, 0x40,
+	 0x01, 0x27, 0x5B, 0x7C, 0x37, 0xF9, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x25, 0xF2, 0x19, 0x60,
+	 0x4D, 0xFB, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x25, 0xF2, 0x19, 0x60, 0x4E, 0xFB, 0x00, 0x67,
+	 0x23, 0x58, 0xFF, 0xFF, 0x25, 0xF2, 0x19, 0x60, 0x89, 0xFB, 0xFF, 0xFF, 0x0F, 0x22, 0x41, 0x75,
+	 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x01, 0x64, 0x01, 0x00, 0x00, 0x64, 0x1B, 0x60, 0xFE, 0xFB,
+	 0x7E, 0x60, 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80, 0x7F, 0x67, 0x02, 0x61, 0x0E, 0x02, 0x06, 0x61,
+	 0x41, 0x56, 0xC7, 0xFE, 0x2A, 0x60, 0x1D, 0x78, 0xFF, 0xFF, 0x36, 0x47, 0xFF, 0x23, 0x04, 0x00,
+	 0x00, 0x7F, 0x60, 0x41, 0x7F, 0x67, 0x01, 0x00, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x7F, 0x60,
+	 0xC0, 0x64, 0x24, 0x45, 0xA4, 0x80, 0x7F, 0x67, 0x02, 0x61, 0x0E, 0x02, 0x08, 0x61, 0x41, 0x56,
+	 0xC7, 0xFE, 0x2A, 0x60, 0x1D, 0x78, 0xFF, 0xFF, 0x36, 0x47, 0xFF, 0x23, 0x04, 0x00, 0x00, 0x7F,
+	 0x60, 0x41, 0x7F, 0x67, 0x01, 0x00, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x7F, 0x60, 0xC0, 0x64,
+	 0x24, 0x45, 0xA4, 0x80, 0x7F, 0x67, 0x02, 0x61, 0x0E, 0x02, 0x0A, 0x61, 0x41, 0x56, 0xC7, 0xFE,
+	 0x2A, 0x60, 0x1D, 0x78, 0xFF, 0xFF, 0x36, 0x47, 0xFF, 0x23, 0x04, 0x00, 0x00, 0x7F, 0x60, 0x41,
+	 0x7F, 0x67, 0x01, 0x00, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x7E, 0x60, 0xC0, 0x64, 0x24, 0x45,
+	 0xA4, 0x80, 0x7F, 0x67, 0x02, 0x61, 0x11, 0x02, 0x65, 0x43, 0x19, 0x60, 0xA5, 0xFD, 0x0C, 0x61,
+	 0x41, 0x56, 0xC7, 0xFE, 0x2A, 0x60, 0x1D, 0x78, 0xFF, 0xFF, 0x36, 0x47, 0xFF, 0x23, 0x04, 0x00,
+	 0x00, 0x7F, 0x60, 0x41, 0x7F, 0x67, 0x01, 0x00, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x20, 0x64,
+	 0x23, 0xFA, 0x4A, 0x61, 0x10, 0x60, 0xDA, 0x64, 0xA0, 0xD1, 0xA1, 0xD8, 0x58, 0xD1, 0x59, 0xD8,
+	 0x58, 0xD1, 0x59, 0xD8, 0x01, 0xA1, 0x10, 0x60, 0xF2, 0x63, 0x5D, 0x65, 0xA3, 0xD3, 0x02, 0xA3,
+	 0x02, 0x1B, 0x7F, 0x64, 0x01, 0x00, 0xA3, 0xD3, 0x60, 0xFE, 0x5D, 0xDA, 0x20, 0xFE, 0xD5, 0x80,
+	 0x04, 0xA3, 0xF4, 0x02, 0x01, 0xA1, 0x10, 0x60, 0xE0, 0x64, 0xA0, 0xD1, 0xA1, 0xD8, 0x58, 0xD1,
+	 0x59, 0xD8, 0x58, 0xD1, 0x59, 0xD8, 0x01, 0xA1, 0x60, 0xFE, 0x07, 0x63, 0x7F, 0x64, 0xCF, 0x83,
+	 0x5D, 0xDA, 0xFD, 0x02, 0x20, 0xFE, 0x12, 0x60, 0x40, 0x7C, 0x11, 0x60, 0x62, 0x63, 0x7F, 0x65,
+	 0xA3, 0xD3, 0x02, 0xA3, 0x02, 0x1B, 0x7F, 0x64, 0x01, 0x00, 0xA3, 0xD3, 0x60, 0xFE, 0x5D, 0xDA,
+	 0x20, 0xFE, 0xD5, 0x80, 0x06, 0xA3, 0x03, 0x02, 0x46, 0x45, 0x00, 0xF4, 0x03, 0x61, 0xD3, 0x80,
+	 0xFF, 0xFF, 0xEE, 0x04, 0x25, 0x46, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x02, 0x63, 0x7D, 0xF3,
+	 0x23, 0xFC, 0x60, 0x40, 0x01, 0x23, 0x17, 0x00, 0x01, 0x60, 0xFF, 0x65, 0xA4, 0x84, 0x11, 0x60,
+	 0x60, 0x61, 0x12, 0x60, 0x40, 0x65, 0xA1, 0xD1, 0xD5, 0x80, 0xD0, 0x80, 0x0B, 0x03, 0x02, 0x03,
+	 0x08, 0xA1, 0xF9, 0x01, 0x04, 0xA1, 0xA1, 0xD3, 0x01, 0x60, 0x00, 0x65, 0x60, 0x47, 0xFF, 0xB4,
+	 0xB4, 0x84, 0x01, 0x00, 0xFF, 0x64, 0x25, 0xFA, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x0C, 0x63,
+	 0x23, 0xFC, 0xE2, 0xF3, 0x13, 0x60, 0xF2, 0x63, 0xCC, 0x84, 0xFF, 0xFF, 0x02, 0x06, 0x0C, 0xA3,
+	 0xFB, 0x01, 0x48, 0x61, 0x61, 0x44, 0x18, 0xA5, 0x60, 0xFE, 0xBD, 0xD3, 0x20, 0xFE, 0x00, 0x7F,
+	 0x59, 0xDA, 0xD5, 0x80, 0xFF, 0xFF, 0xF8, 0x04, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF, 0x25, 0xF0,
+	 0x17, 0x60, 0x80, 0xF9, 0x11, 0x00, 0x0C, 0x60, 0xFE, 0x62, 0x40, 0x63, 0x5A, 0xDF, 0xFE, 0x1F,
+	 0x04, 0x65, 0x0C, 0x60, 0xFE, 0x61, 0x48, 0x64, 0x3E, 0x63, 0x7C, 0xA8, 0x58, 0xD0, 0x59, 0xD9,
+	 0x02, 0x02, 0x00, 0xF4, 0x02, 0x64, 0xF9, 0x1F, 0x17, 0x60, 0x80, 0xF1, 0x0C, 0x60, 0xDA, 0x65,
+	 0x02, 0xFE, 0x64, 0x44, 0xF8, 0x84, 0xF8, 0x84, 0xF8, 0x87, 0x60, 0x41, 0x64, 0x44, 0xE0, 0x84,
+	 0xE0, 0x84, 0xC4, 0x84, 0x3E, 0xFB, 0x60, 0x42, 0x61, 0x44, 0x03, 0xA2, 0x60, 0xFE, 0xA2, 0xDB,
+	 0x20, 0xFE, 0x64, 0x44, 0x0D, 0x60, 0x00, 0x65, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84,
+	 0xC4, 0x84, 0x40, 0xFB, 0xFF, 0xFF, 0x00, 0x67, 0x00, 0x61, 0x23, 0x58, 0xFF, 0xFF, 0x5C, 0x41,
+	 0x25, 0xF2, 0xFF, 0xFF, 0x40, 0x42, 0x80, 0x2B, 0x04, 0x00, 0xFF, 0xB4, 0x40, 0x42, 0x01, 0x64,
+	 0x40, 0x41, 0xA6, 0xF3, 0x46, 0x4B, 0x60, 0x46, 0x20, 0x63, 0xE3, 0x83, 0xAB, 0x46, 0x26, 0xF0,
+	 0xAB, 0x46, 0x59, 0xF8, 0xAB, 0x46, 0x27, 0xF0, 0xAB, 0x46, 0x5A, 0xF8, 0xAB, 0x46, 0x28, 0xF0,
+	 0xAB, 0x46, 0x5B, 0xF8, 0x66, 0x44, 0x02, 0xA6, 0xF1, 0x1F, 0xA6, 0xF3, 0xFF, 0xFF, 0x60, 0x46,
+	 0xAB, 0x46, 0x0C, 0x60, 0x38, 0x65, 0x22, 0x44, 0xFF, 0xB4, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84,
+	 0xE0, 0x84, 0xC4, 0x81, 0xC9, 0x81, 0x52, 0x64, 0x0E, 0x63, 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F,
+	 0x21, 0x44, 0x01, 0x2A, 0x08, 0x00, 0xAB, 0x46, 0xF0, 0xA1, 0x76, 0x64, 0x0E, 0x63, 0x59, 0xD1,
+	 0x58, 0xD8, 0xFD, 0x1F, 0xAB, 0x46, 0x22, 0x44, 0xFF, 0xB4, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84,
+	 0x0C, 0x60, 0x9A, 0x65, 0xC4, 0x81, 0x60, 0x45, 0xC9, 0x81, 0x62, 0x64, 0x06, 0x63, 0x58, 0xD0,
+	 0x59, 0xD9, 0xFD, 0x1F, 0x21, 0x44, 0x01, 0x2A, 0x08, 0x00, 0xAB, 0x46, 0xF8, 0xA1, 0xB6, 0x64,
+	 0x06, 0x63, 0x59, 0xD1, 0x58, 0xD8, 0xFD, 0x1F, 0xAB, 0x46, 0x65, 0x44, 0x0C, 0x60, 0xBA, 0x65,
+	 0xC4, 0x81, 0xC9, 0x81, 0x6A, 0x64, 0x06, 0x63, 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0x22, 0x44,
+	 0xFF, 0xB4, 0xE0, 0x84, 0xE0, 0x85, 0xC4, 0x84, 0x0C, 0x60, 0x80, 0x65, 0xC4, 0x81, 0x72, 0x64,
+	 0x04, 0x63, 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0xAB, 0x46, 0x21, 0x44, 0x01, 0x2A, 0x06, 0x00,
+	 0xFA, 0xA1, 0x90, 0x64, 0x04, 0x63, 0x59, 0xD1, 0x58, 0xD8, 0xFD, 0x1F, 0x3B, 0xF0, 0x21, 0x44,
+	 0x01, 0x2A, 0x13, 0x00, 0x22, 0x44, 0x3D, 0xFB, 0x60, 0x41, 0x02, 0xFE, 0xF8, 0x84, 0xF8, 0x84,
+	 0xF8, 0x84, 0x3C, 0xFB, 0x0C, 0x60, 0x7C, 0x63, 0x88, 0xFF, 0xCD, 0x81, 0x06, 0xA3, 0xFD, 0x0D,
+	 0x8D, 0xFF, 0x3B, 0xFD, 0x64, 0x47, 0x80, 0xBF, 0x60, 0x5C, 0x22, 0x43, 0x80, 0x61, 0x88, 0xFF,
+	 0xCF, 0x83, 0xE1, 0x81, 0xFD, 0x0D, 0x8D, 0xFF, 0x61, 0x47, 0x31, 0x91, 0xB1, 0x84, 0x3B, 0xFA,
+	 0x1F, 0x63, 0xE3, 0x83, 0x66, 0x44, 0x02, 0xA6, 0x3B, 0xF0, 0x66, 0x44, 0xB1, 0x9C, 0x3B, 0xF8,
+	 0x02, 0xA6, 0xFA, 0x1F, 0xAB, 0x46, 0x00, 0x67, 0x00, 0x61, 0x23, 0x58, 0xFF, 0xFF, 0x23, 0xF2,
+	 0x25, 0xF0, 0x02, 0xA8, 0x00, 0x67, 0x22, 0x02, 0x3D, 0xF1, 0x64, 0x44, 0x03, 0xB4, 0x40, 0x42,
+	 0xD0, 0x80, 0xA6, 0xF3, 0xFF, 0xFF, 0x60, 0x46, 0xBB, 0xF4, 0x80, 0x61, 0x02, 0x02, 0xE3, 0x83,
+	 0xEB, 0x83, 0x22, 0x44, 0x88, 0xFF, 0xCC, 0x84, 0xE1, 0x81, 0xFD, 0x0D, 0x8D, 0xFF, 0x61, 0x47,
+	 0x31, 0x91, 0x9D, 0x85, 0xA7, 0x83, 0x3B, 0xFC, 0x1F, 0x63, 0xE3, 0x83, 0x66, 0x44, 0x02, 0xA6,
+	 0xBB, 0xF2, 0x66, 0x44, 0xA5, 0x81, 0xBB, 0xFA, 0x02, 0xA6, 0xFA, 0x1F, 0x00, 0x67, 0x23, 0x58,
+	 0xFF, 0xFF, 0x27, 0xF2, 0x1D, 0x60, 0xC0, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3,
+	 0x66, 0x41, 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46, 0x27, 0xF0, 0x63, 0x46,
+	 0xD0, 0x80, 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46, 0x26, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2,
+	 0x06, 0x02, 0x61, 0x46, 0x25, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4,
+	 0xFF, 0xFF, 0x63, 0x46, 0xE8, 0x1B, 0xA6, 0xF3, 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0x01, 0x03,
+	 0x2A, 0x00, 0x43, 0x4B, 0xAB, 0x46, 0x3B, 0xF2, 0x80, 0x60, 0x30, 0x7C, 0xB0, 0x84, 0xA2, 0xDA,
+	 0x4E, 0x61, 0x76, 0x64, 0x0E, 0x63, 0xAB, 0x46, 0x59, 0xD0, 0xAB, 0x46, 0x58, 0xD8, 0xFB, 0x1F,
+	 0x90, 0x64, 0x04, 0x63, 0xAB, 0x46, 0x59, 0xD0, 0xAB, 0x46, 0x58, 0xD8, 0xFB, 0x1F, 0xD9, 0x81,
+	 0xA0, 0x64, 0x04, 0x63, 0xAB, 0x46, 0x59, 0xD0, 0xAB, 0x46, 0x58, 0xD8, 0xFB, 0x1F, 0xD9, 0x81,
+	 0xB6, 0x64, 0x0E, 0x63, 0xAB, 0x46, 0x59, 0xD0, 0xAB, 0x46, 0x58, 0xD8, 0xFB, 0x1F, 0x00, 0x67,
+	 0x00, 0x61, 0x23, 0x58, 0xFF, 0xFF, 0x01, 0x67, 0x20, 0x61, 0x23, 0x58, 0xFF, 0xFF, 0x27, 0xF2,
+	 0x1D, 0x60, 0xC0, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46,
+	 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46, 0x27, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2,
+	 0x0C, 0x02, 0x61, 0x46, 0x26, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46,
+	 0x25, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46,
+	 0xE8, 0x1B, 0xA6, 0xF3, 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0x01, 0x03, 0x0D, 0x00, 0x43, 0x4B,
+	 0xAB, 0x46, 0x3B, 0xF2, 0x80, 0x60, 0x30, 0x61, 0x9D, 0x85, 0xA4, 0x84, 0xA2, 0xDA, 0xAB, 0x46,
+	 0x00, 0x67, 0x00, 0x61, 0x23, 0x58, 0xFF, 0xFF, 0x01, 0x67, 0x20, 0x61, 0x23, 0x58, 0xFF, 0xFF,
+	 0x00, 0x64, 0x40, 0x41, 0x4A, 0x64, 0xA0, 0xD2, 0xFF, 0xFF, 0x40, 0x42, 0x80, 0x2B, 0x04, 0x00,
+	 0xFF, 0xB4, 0x40, 0x42, 0x01, 0x64, 0x40, 0x41, 0xA6, 0xF3, 0x46, 0x4B, 0x60, 0x46, 0x20, 0x63,
+	 0xE3, 0x83, 0xAB, 0x46, 0x32, 0xF0, 0xAB, 0x46, 0x59, 0xF8, 0xAB, 0x46, 0x33, 0xF0, 0xAB, 0x46,
+	 0x5A, 0xF8, 0xAB, 0x46, 0x34, 0xF0, 0xAB, 0x46, 0x5B, 0xF8, 0x66, 0x44, 0x02, 0xA6, 0xF1, 0x1F,
+	 0xA6, 0xF3, 0xFF, 0xFF, 0x60, 0x46, 0xAB, 0x46, 0x0C, 0x60, 0x38, 0x65, 0x22, 0x44, 0xFF, 0xB4,
+	 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xC4, 0x81, 0xC9, 0x81, 0x4A, 0x64, 0x0E, 0x63,
+	 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0x21, 0x44, 0x01, 0x2A, 0x08, 0x00, 0xAB, 0x46, 0xF0, 0xA1,
+	 0x76, 0x64, 0x0E, 0x63, 0x59, 0xD1, 0x58, 0xD8, 0xFD, 0x1F, 0xAB, 0x46, 0x22, 0x44, 0xFF, 0xB4,
+	 0xE0, 0x84, 0xE0, 0x85, 0xC4, 0x84, 0x0C, 0x60, 0x80, 0x65, 0xC4, 0x81, 0x5A, 0x64, 0x04, 0x63,
+	 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0xAB, 0x46, 0x21, 0x44, 0x01, 0x2A, 0x06, 0x00, 0xFA, 0xA1,
+	 0x90, 0x64, 0x04, 0x63, 0x59, 0xD1, 0x58, 0xD8, 0xFD, 0x1F, 0x3B, 0xF0, 0x21, 0x44, 0x01, 0x2A,
+	 0x13, 0x00, 0x22, 0x44, 0x3D, 0xFB, 0x60, 0x41, 0x02, 0xFE, 0xF8, 0x84, 0xF8, 0x84, 0xF8, 0x84,
+	 0x3C, 0xFB, 0x0C, 0x60, 0x7C, 0x63, 0x88, 0xFF, 0xCD, 0x81, 0x06, 0xA3, 0xFD, 0x0D, 0x8D, 0xFF,
+	 0x3B, 0xFD, 0x64, 0x47, 0x80, 0xBF, 0x60, 0x5C, 0x22, 0x43, 0x80, 0x61, 0x88, 0xFF, 0xCF, 0x83,
+	 0xE1, 0x81, 0xFD, 0x0D, 0x8D, 0xFF, 0x61, 0x47, 0x31, 0x91, 0xB1, 0x84, 0x3B, 0xFA, 0x1F, 0x63,
+	 0xE3, 0x83, 0x66, 0x44, 0x02, 0xA6, 0x3B, 0xF0, 0x66, 0x44, 0xB1, 0x9C, 0x3B, 0xF8, 0x02, 0xA6,
+	 0xFA, 0x1F, 0xAB, 0x46, 0x00, 0x67, 0x00, 0x61, 0x23, 0x58, 0xFF, 0xFF, 0x23, 0xF2, 0x25, 0xF0,
+	 0x02, 0xA8, 0x00, 0x67, 0x22, 0x02, 0x3D, 0xF1, 0x64, 0x44, 0x03, 0xB4, 0x40, 0x42, 0xD0, 0x80,
+	 0xA6, 0xF3, 0xFF, 0xFF, 0x60, 0x46, 0xBB, 0xF4, 0x80, 0x61, 0x02, 0x02, 0xE3, 0x83, 0xEB, 0x83,
+	 0x22, 0x44, 0x88, 0xFF, 0xCC, 0x84, 0xE1, 0x81, 0xFD, 0x0D, 0x8D, 0xFF, 0x61, 0x47, 0x31, 0x91,
+	 0x9D, 0x85, 0xA7, 0x83, 0x3B, 0xFC, 0x1F, 0x63, 0xE3, 0x83, 0x66, 0x44, 0x02, 0xA6, 0xBB, 0xF2,
+	 0x66, 0x44, 0xA5, 0x81, 0xBB, 0xFA, 0x02, 0xA6, 0xFA, 0x1F, 0x00, 0x67, 0x23, 0x58, 0xFF, 0xFF,
+	 0x27, 0xF2, 0x1D, 0x60, 0xC0, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41,
+	 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46, 0x27, 0xF0, 0x63, 0x46, 0xD0, 0x80,
+	 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46, 0x26, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02,
+	 0x61, 0x46, 0x25, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF,
+	 0x63, 0x46, 0xE8, 0x1B, 0xA6, 0xF3, 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0x01, 0x03, 0x21, 0x00,
+	 0x43, 0x4B, 0xAB, 0x46, 0x3B, 0xF2, 0x80, 0x60, 0x30, 0x7C, 0xB0, 0x84, 0xA2, 0xDA, 0x4E, 0x61,
+	 0x76, 0x64, 0x0E, 0x63, 0xAB, 0x46, 0x59, 0xD0, 0xAB, 0x46, 0x58, 0xD8, 0xFB, 0x1F, 0x90, 0x64,
+	 0x04, 0x63, 0xAB, 0x46, 0x59, 0xD0, 0xAB, 0x46, 0x58, 0xD8, 0xFB, 0x1F, 0xA0, 0x64, 0x04, 0x63,
+	 0xAB, 0x46, 0x59, 0xD0, 0xAB, 0x46, 0x58, 0xD8, 0xFB, 0x1F, 0x00, 0x67, 0x00, 0x61, 0x23, 0x58,
+	 0xFF, 0xFF, 0x01, 0x67, 0x20, 0x61, 0x23, 0x58, 0xFF, 0xFF, 0x27, 0xF2, 0x1D, 0x60, 0xC0, 0x65,
+	 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2,
+	 0x16, 0x18, 0x61, 0x46, 0x27, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46,
+	 0x26, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46, 0x25, 0xF0, 0x63, 0x46,
+	 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46, 0xE8, 0x1B, 0xA6, 0xF3,
+	 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0x01, 0x03, 0x0D, 0x00, 0x43, 0x4B, 0xAB, 0x46, 0x3B, 0xF2,
+	 0x80, 0x60, 0x30, 0x61, 0x9D, 0x85, 0xA4, 0x84, 0xA2, 0xDA, 0xAB, 0x46, 0x00, 0x67, 0x00, 0x61,
+	 0x23, 0x58, 0xFF, 0xFF, 0x01, 0x67, 0x20, 0x61, 0x23, 0x58, 0xFF, 0xFF, 0xA2, 0xFF, 0x46, 0x45,
+	 0x02, 0xF0, 0x09, 0x60, 0x08, 0x64, 0xD0, 0x80, 0x00, 0xF4, 0x01, 0xF2, 0x66, 0x5C, 0x25, 0x46,
+	 0x56, 0x02, 0x70, 0x27, 0x54, 0x00, 0x12, 0x64, 0x03, 0xFA, 0x04, 0xF8, 0x0E, 0xF2, 0x87, 0xFC,
+	 0x8D, 0xFC, 0x8E, 0xFC, 0xDA, 0x82, 0x16, 0x61, 0x00, 0x63, 0xC9, 0x81, 0x5A, 0xDC, 0xFD, 0x02,
+	 0x60, 0x40, 0xF0, 0x3B, 0x16, 0x00, 0x32, 0x44, 0xAC, 0xF3, 0x01, 0xB0, 0xFA, 0xA0, 0x08, 0x24,
+	 0x2C, 0x05, 0xDC, 0x83, 0xF0, 0x67, 0x0E, 0xFA, 0x26, 0x60, 0x04, 0x64, 0x2B, 0xDB, 0x66, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xAC, 0xFD, 0x2B, 0xFF, 0xFE, 0x64, 0x3B, 0x42, 0x4A, 0xDB,
+	 0x4F, 0x00, 0xAD, 0xF3, 0x05, 0x65, 0xD4, 0x80, 0xDC, 0x83, 0x17, 0x05, 0xAD, 0xFD, 0x98, 0xFE,
+	 0x04, 0x04, 0x00, 0x7F, 0x08, 0x7E, 0x0E, 0xFA, 0x3B, 0xFF, 0x25, 0x60, 0xF8, 0x64, 0x2B, 0xDB,
+	 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0x0E, 0xF2, 0x2B, 0xFF, 0x60, 0x40, 0x08, 0x26,
+	 0xF7, 0xFE, 0xFD, 0x64, 0x3B, 0x42, 0x4A, 0xDB, 0x32, 0x00, 0xA9, 0xF3, 0xFF, 0xFF, 0xD8, 0xA0,
+	 0xFF, 0xFF, 0x0D, 0x04, 0x26, 0x60, 0x10, 0x64, 0x2B, 0xDB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xFC, 0x64, 0x3B, 0x42, 0x4A, 0xDB, 0x21, 0x00, 0x46, 0x45,
+	 0x00, 0x64, 0x2B, 0xDB, 0x25, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0xA2, 0xFF, 0x00, 0xF4, 0x01, 0xF0, 0x0A, 0x18, 0x70, 0x67, 0xA0, 0x80, 0xF0, 0x67, 0x06, 0x03,
+	 0xC0, 0x84, 0x01, 0xFA, 0x25, 0x46, 0x25, 0x44, 0x80, 0xFC, 0x05, 0xFA, 0xB6, 0x60, 0x58, 0x4E,
+	 0xF5, 0x78, 0xFF, 0xFF, 0xD4, 0xFE, 0xA3, 0xFF, 0xFF, 0x64, 0x3B, 0x42, 0x4A, 0xDB, 0xD4, 0xFE,
+	 0xA3, 0xFF, 0x2D, 0x58, 0xFF, 0xFF, 0x25, 0x60, 0xFE, 0x64, 0x40, 0x47, 0x58, 0x4F, 0x0D, 0x00,
+	 0x25, 0x60, 0xF2, 0x64, 0x40, 0x47, 0x58, 0x4F, 0x18, 0x00, 0x26, 0x60, 0x0A, 0x64, 0x40, 0x47,
+	 0x58, 0x4F, 0x03, 0x00, 0x2A, 0x60, 0x1D, 0x78, 0xFF, 0xFF, 0x27, 0xD5, 0x0E, 0xF2, 0x0B, 0x18,
+	 0x60, 0x40, 0x01, 0x2A, 0x08, 0x00, 0x26, 0x60, 0x20, 0x64, 0x40, 0x4B, 0x34, 0x60, 0x58, 0x4D,
+	 0x08, 0x78, 0xFF, 0xFF, 0xF2, 0x01, 0x2F, 0x58, 0xFF, 0xFF, 0x27, 0xD5, 0x0E, 0xF2, 0x14, 0x18,
+	 0x60, 0x40, 0x01, 0x2A, 0x11, 0x00, 0x02, 0xF0, 0x09, 0x60, 0x08, 0x64, 0xD0, 0x80, 0xA2, 0xFF,
+	 0xAD, 0xF3, 0x02, 0x02, 0xCC, 0x84, 0xAD, 0xFB, 0x26, 0x60, 0x20, 0x64, 0x40, 0x4B, 0x34, 0x60,
+	 0x58, 0x4D, 0x08, 0x78, 0xFF, 0xFF, 0xE9, 0x01, 0x2F, 0x58, 0xFF, 0xFF, 0xFB, 0x64, 0x3A, 0x42,
+	 0x4A, 0xDB, 0xA2, 0xFF, 0xB0, 0xF3, 0xAC, 0xF3, 0xCC, 0x80, 0xFD, 0xA0, 0x01, 0x14, 0x1D, 0x05,
+	 0xB5, 0x60, 0x58, 0x4D, 0xFA, 0x78, 0xFF, 0xFF, 0xA2, 0xFF, 0x17, 0x03, 0xF0, 0x67, 0x0E, 0xFA,
+	 0x26, 0x60, 0x04, 0x64, 0x13, 0x60, 0x10, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB,
+	 0xFF, 0xFF, 0x2B, 0xFF, 0xF6, 0x64, 0x3A, 0x42, 0x4A, 0xDB, 0xB0, 0xF3, 0xAC, 0xF3, 0xCC, 0x83,
+	 0xDC, 0x84, 0x01, 0x15, 0xB0, 0xFD, 0xAC, 0xFB, 0xD4, 0xFE, 0xAF, 0xF3, 0xAD, 0xF3, 0x00, 0xA8,
+	 0xAE, 0xF1, 0x03, 0x02, 0xD0, 0x80, 0xFF, 0xFF, 0x26, 0x05, 0xB5, 0x60, 0x58, 0x4D, 0xFA, 0x78,
+	 0xFF, 0xFF, 0xA2, 0xFF, 0x20, 0x03, 0x00, 0x63, 0xAF, 0xF3, 0x0E, 0xFC, 0xCC, 0x84, 0xFF, 0x3A,
+	 0xAF, 0xFB, 0x98, 0xFE, 0x03, 0x04, 0x08, 0xBB, 0x0E, 0xFC, 0x3B, 0xFF, 0x25, 0x60, 0xF8, 0x64,
+	 0x13, 0x60, 0x10, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0xF7, 0x64, 0x3A, 0x42, 0x4A, 0xDB, 0xAD, 0xF3, 0x0E, 0xF2, 0xDC, 0x83, 0x08, 0xB0, 0xAD, 0xFD,
+	 0x08, 0x28, 0xF7, 0xFE, 0xD4, 0xFE, 0xA3, 0xFF, 0x2A, 0x60, 0x1D, 0x78, 0xFF, 0xFF, 0xB9, 0xFE,
+	 0x13, 0xFF, 0x24, 0x40, 0x80, 0x2B, 0x0B, 0x00, 0xA2, 0xFF, 0x25, 0x46, 0x09, 0xF4, 0x0E, 0xF2,
+	 0x05, 0x18, 0x08, 0xBC, 0x0E, 0xFA, 0xFF, 0xFF, 0xF7, 0xFE, 0x01, 0x00, 0xD8, 0xFE, 0xA3, 0xFF,
+	 0x25, 0x46, 0x3E, 0xF2, 0x00, 0xF4, 0x08, 0xF0, 0x25, 0x46, 0x06, 0xB4, 0xFF, 0x7F, 0x10, 0xBC,
+	 0x06, 0x26, 0xFD, 0x7F, 0x0E, 0xFA, 0x3E, 0xF2, 0x3F, 0xF2, 0x60, 0x41, 0x08, 0x2A, 0x64, 0x47,
+	 0x3F, 0xFA, 0x60, 0x45, 0xB9, 0xFC, 0x16, 0x60, 0xAA, 0xF3, 0xA3, 0xFC, 0xAB, 0xFC, 0x91, 0xFC,
+	 0xD4, 0x80, 0x18, 0x60, 0x21, 0x65, 0xA5, 0x80, 0x01, 0x04, 0x07, 0x03, 0x23, 0xF0, 0x08, 0x64,
+	 0xB0, 0x84, 0xA2, 0xDA, 0x35, 0x60, 0xEA, 0x78, 0xFF, 0xFF, 0x36, 0x60, 0x58, 0x4F, 0x30, 0x78,
+	 0xFF, 0xFF, 0x0B, 0x04, 0x23, 0xF0, 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDA, 0x2C, 0x60, 0xEE, 0x64,
+	 0xF1, 0x60, 0x78, 0x41, 0xE4, 0x78, 0xB5, 0xF1, 0x83, 0x00, 0xDB, 0xF3, 0xA6, 0xF1, 0x07, 0xB4,
+	 0x64, 0x43, 0xFD, 0xA0, 0x2C, 0xF2, 0x71, 0x02, 0x01, 0xB0, 0x64, 0x43, 0x78, 0x02, 0x2E, 0xF2,
+	 0x1D, 0x60, 0xC0, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46,
+	 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46, 0x2E, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2,
+	 0x0C, 0x02, 0x61, 0x46, 0x2D, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46,
+	 0x2C, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46,
+	 0xE8, 0x1B, 0xA6, 0xF3, 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0x51, 0x03, 0x63, 0x46, 0x80, 0xF6,
+	 0x25, 0x46, 0x43, 0x18, 0x2E, 0xF2, 0x66, 0x41, 0x1D, 0x60, 0xC0, 0x65, 0x60, 0x47, 0x00, 0x7F,
+	 0xA6, 0xF1, 0xE0, 0x84, 0x44, 0xD3, 0x64, 0x43, 0x11, 0x18, 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF,
+	 0xFC, 0x1B, 0x66, 0x44, 0x64, 0x46, 0x80, 0xF0, 0x60, 0x46, 0x80, 0xF8, 0x65, 0x46, 0x65, 0x43,
+	 0x80, 0xF0, 0x01, 0xFA, 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8, 0x0B, 0x00, 0x64, 0x46, 0x62, 0x43,
+	 0x00, 0xF2, 0xA3, 0xDB, 0x60, 0x46, 0x80, 0xF0, 0x81, 0xFC, 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8,
+	 0x60, 0x43, 0x61, 0x46, 0x43, 0x4B, 0x2C, 0xF0, 0xAD, 0xF0, 0x2E, 0xF2, 0xAB, 0x46, 0x03, 0xF8,
+	 0x84, 0xF8, 0x05, 0xFA, 0x03, 0x64, 0x06, 0xFA, 0xAB, 0x46, 0x1F, 0x60, 0xC2, 0x61, 0xA1, 0xD3,
+	 0x20, 0x60, 0x04, 0x7C, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0xA0, 0xDD, 0xDA, 0x9C, 0xA1, 0xD9,
+	 0x49, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xA1, 0xDB, 0x0A, 0x00, 0xDB, 0xF3, 0x02, 0xA3, 0xFE, 0xA0,
+	 0xF9, 0xA0, 0x01, 0x06, 0x04, 0x02, 0x23, 0xF0, 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDA, 0x07, 0xFC,
+	 0x23, 0xF2, 0xFF, 0xFF, 0x24, 0x1B, 0x16, 0x60, 0xAB, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x00, 0x3A,
+	 0x0F, 0x00, 0x25, 0x60, 0xC8, 0x64, 0x13, 0x60, 0x10, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x0E, 0xF2, 0xC1, 0xFE, 0x10, 0xAC, 0x0E, 0xFA, 0x1D, 0x00,
+	 0x25, 0x60, 0xDA, 0x64, 0x13, 0x60, 0x10, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB,
+	 0xFF, 0xFF, 0x2B, 0xFF, 0x0E, 0xF2, 0xC8, 0xFE, 0x10, 0xAC, 0x0E, 0xFA, 0x0E, 0x00, 0x25, 0x60,
+	 0xEC, 0x64, 0x13, 0x60, 0x10, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0x0E, 0xF2, 0xCE, 0xFE, 0x10, 0xAC, 0x0E, 0xFA, 0x2A, 0x60, 0x1D, 0x78, 0xFF, 0xFF,
+	 0xCB, 0x84, 0xC9, 0x83, 0xFF, 0xFF, 0x08, 0x04, 0x58, 0xD1, 0xA5, 0xD8, 0xDA, 0x85, 0x80, 0x3A,
+	 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0xF8, 0x1F, 0x2F, 0x58, 0xFF, 0xFF, 0x3E, 0xF2, 0xC9, 0xF1,
+	 0x08, 0xB0, 0x19, 0xF8, 0x57, 0x02, 0xEA, 0xF1, 0x2F, 0xF8, 0xEB, 0xF3, 0x30, 0xFA, 0x60, 0x45,
+	 0xEC, 0xF3, 0x31, 0xFA, 0x46, 0x4A, 0x00, 0xF4, 0x60, 0x43, 0x05, 0xF2, 0x06, 0xF2, 0xD0, 0x80,
+	 0x07, 0xF0, 0x05, 0x02, 0xD4, 0x80, 0xD3, 0x80, 0x02, 0x02, 0xDB, 0xF3, 0x03, 0x03, 0xAA, 0x46,
+	 0x42, 0xFE, 0x41, 0x00, 0x60, 0x40, 0x03, 0x2A, 0x20, 0x00, 0x02, 0xF2, 0x03, 0xF0, 0x04, 0xF2,
+	 0x60, 0x43, 0xAA, 0x46, 0x2C, 0xFC, 0x2D, 0xF8, 0x2E, 0xFA, 0x7F, 0xF1, 0x32, 0xF8, 0x80, 0xF1,
+	 0x33, 0xF8, 0x81, 0xF1, 0x34, 0xF8, 0x08, 0x64, 0x32, 0x40, 0x04, 0x2A, 0x0D, 0x00, 0x2C, 0xF0,
+	 0x39, 0xF0, 0x64, 0x40, 0x01, 0x26, 0x08, 0x00, 0x3E, 0xF2, 0xFF, 0xFF, 0x00, 0x60, 0xC0, 0xB4,
+	 0xE8, 0x84, 0xB0, 0x9C, 0x39, 0xF8, 0x88, 0x64, 0x1C, 0x00, 0x02, 0xF2, 0x03, 0xF0, 0x04, 0xF2,
+	 0x60, 0x43, 0xAA, 0x46, 0x32, 0xFC, 0x33, 0xF8, 0x34, 0xFA, 0x7F, 0xF1, 0x2C, 0xF8, 0x80, 0xF1,
+	 0x2D, 0xF8, 0x81, 0xF1, 0x2E, 0xF8, 0x01, 0x60, 0x08, 0x64, 0x32, 0x40, 0x04, 0x2A, 0x09, 0x00,
+	 0x3E, 0xF2, 0x39, 0xF0, 0x00, 0x60, 0xC0, 0xB4, 0xE8, 0x84, 0xB0, 0x9C, 0x39, 0xF8, 0x01, 0x60,
+	 0x88, 0x64, 0x2A, 0xFA, 0x02, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x36, 0x60, 0x22, 0x63, 0x20, 0x44,
+	 0xBD, 0xDB, 0x21, 0x44, 0xBD, 0xDB, 0x22, 0x44, 0xBD, 0xDB, 0x23, 0x44, 0xBD, 0xDB, 0x24, 0x44,
+	 0xBD, 0xDB, 0x25, 0x44, 0xBD, 0xDB, 0x26, 0x44, 0xBD, 0xDB, 0x27, 0x44, 0xBD, 0xDB, 0x28, 0x44,
+	 0xBD, 0xDB, 0x29, 0x44, 0xBD, 0xDB, 0x2A, 0x44, 0xBD, 0xDB, 0x2B, 0x44, 0xBD, 0xDB, 0x2C, 0x44,
+	 0xBD, 0xDB, 0x2D, 0x44, 0xBD, 0xDB, 0x2E, 0x44, 0xBD, 0xDB, 0x2F, 0x44, 0xBD, 0xDB, 0x1B, 0x60,
+	 0x0B, 0xFD, 0x37, 0x60, 0x42, 0x63, 0x1B, 0x60, 0x0C, 0xFD, 0x30, 0x44, 0x1B, 0x60, 0x0D, 0xFB,
+	 0x31, 0x44, 0x1B, 0x60, 0x0E, 0xFB, 0x32, 0x44, 0x1B, 0x60, 0x0F, 0xFB, 0x33, 0x44, 0x1B, 0x60,
+	 0x10, 0xFB, 0x81, 0xFF, 0x91, 0xFF, 0x58, 0x51, 0x44, 0x00, 0x82, 0xFF, 0x92, 0xFF, 0x58, 0x51,
+	 0x40, 0x00, 0x83, 0xFF, 0x93, 0xFF, 0x58, 0x51, 0x3C, 0x00, 0x84, 0xFF, 0x94, 0xFF, 0x58, 0x51,
+	 0x38, 0x00, 0x85, 0xFF, 0x95, 0xFF, 0x58, 0x51, 0x34, 0x00, 0x86, 0xFF, 0x96, 0xFF, 0x58, 0x51,
+	 0x30, 0x00, 0x87, 0xFF, 0x97, 0xFF, 0x58, 0x51, 0x2C, 0x00, 0x80, 0xFF, 0x90, 0xFF, 0x99, 0xFF,
+	 0x1B, 0x60, 0x0B, 0xF1, 0x30, 0x44, 0x64, 0x43, 0xBD, 0xDB, 0x31, 0x44, 0xBD, 0xDB, 0x32, 0x44,
+	 0xBD, 0xDB, 0x33, 0x44, 0xBD, 0xDB, 0x34, 0x44, 0xBD, 0xDB, 0x35, 0x44, 0xBD, 0xDB, 0x36, 0x44,
+	 0xBD, 0xDB, 0x37, 0x44, 0xBD, 0xDB, 0x38, 0x44, 0xBD, 0xDB, 0x39, 0x44, 0xBD, 0xDB, 0x3A, 0x44,
+	 0xBD, 0xDB, 0x3B, 0x44, 0xBD, 0xDB, 0x3C, 0x44, 0xBD, 0xDB, 0x3D, 0x44, 0xBD, 0xDB, 0x3E, 0x44,
+	 0xBD, 0xDB, 0x3F, 0x44, 0xBD, 0xDB, 0xF6, 0x60, 0x16, 0x64, 0x0A, 0xFB, 0x40, 0x21, 0xFE, 0x01,
+	 0x74, 0x00, 0x42, 0x50, 0x40, 0x53, 0x1B, 0x60, 0x0C, 0xF3, 0xFF, 0xFF, 0x40, 0x52, 0x33, 0x44,
+	 0x32, 0x42, 0xA2, 0xDB, 0xDA, 0x82, 0xA2, 0xDD, 0xDA, 0x83, 0x65, 0x44, 0xBD, 0xDB, 0x61, 0x44,
+	 0xBD, 0xDB, 0x66, 0x44, 0xBD, 0xDB, 0xBD, 0xD9, 0x30, 0x44, 0xBD, 0xDB, 0x99, 0xFF, 0xA4, 0x4C,
+	 0xBD, 0xDB, 0xA5, 0x4C, 0xBD, 0xDB, 0xA0, 0x4C, 0xBD, 0xDB, 0xA1, 0x4C, 0xBD, 0xDB, 0x98, 0xFF,
+	 0x1B, 0x60, 0x0C, 0xFD, 0x1B, 0x60, 0x0D, 0xF3, 0xFF, 0xFF, 0x40, 0x50, 0x1B, 0x60, 0x0F, 0xF3,
+	 0xFF, 0xFF, 0x40, 0x52, 0x1B, 0x60, 0x10, 0xF3, 0xFF, 0xFF, 0x40, 0x53, 0x31, 0x41, 0x1B, 0x60,
+	 0x0E, 0xF3, 0xFF, 0xFF, 0x40, 0x51, 0x1B, 0x60, 0x0B, 0xF3, 0xFF, 0xFF, 0x60, 0x43, 0x20, 0x44,
+	 0xBD, 0xDB, 0x21, 0x44, 0xBD, 0xDB, 0x22, 0x44, 0xBD, 0xDB, 0x23, 0x44, 0xBD, 0xDB, 0x24, 0x44,
+	 0xBD, 0xDB, 0x25, 0x44, 0xBD, 0xDB, 0x26, 0x44, 0xBD, 0xDB, 0x27, 0x44, 0xBD, 0xDB, 0x28, 0x44,
+	 0xBD, 0xDB, 0x29, 0x44, 0xBD, 0xDB, 0x2A, 0x44, 0xBD, 0xDB, 0x2B, 0x44, 0xBD, 0xDB, 0x2C, 0x44,
+	 0xBD, 0xDB, 0x2D, 0x44, 0xBD, 0xDB, 0x2E, 0x44, 0xBD, 0xDB, 0x2F, 0x44, 0xBD, 0xDB, 0x1B, 0x60,
+	 0x0B, 0xFD, 0x61, 0x58, 0xFF, 0xFF, 0x2F, 0x60, 0x4E, 0x63, 0xA3, 0xD3, 0x33, 0x5C, 0x02, 0xA4,
+	 0xBD, 0xDB, 0xFE, 0xB4, 0xE0, 0x85, 0xC4, 0x85, 0x47, 0xD9, 0x34, 0x44, 0x5B, 0xDB, 0x44, 0xF3,
+	 0x5B, 0xDB, 0xA1, 0xFF, 0xFF, 0xFF, 0x87, 0x3E, 0x84, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x87, 0x3E,
+	 0xFF, 0x01, 0x86, 0xE1, 0x80, 0xFF, 0x90, 0xFF, 0x88, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0x87, 0x3E,
+	 0x19, 0x60, 0xF7, 0xF3, 0xFF, 0xFF, 0x10, 0x1B, 0x32, 0x40, 0x80, 0x2A, 0xF6, 0x01, 0x9D, 0xFE,
+	 0xF4, 0x05, 0xDB, 0xF3, 0xFF, 0xFF, 0x04, 0xA8, 0x33, 0x60, 0xE2, 0x62, 0x01, 0x02, 0xBD, 0x00,
+	 0xA2, 0xD3, 0xFF, 0xFF, 0x4A, 0x1B, 0xE9, 0x01, 0x87, 0xFF, 0x20, 0x44, 0x80, 0xFF, 0x60, 0x40,
+	 0x80, 0x26, 0xE3, 0x01, 0xF1, 0xFC, 0xAD, 0x4F, 0xFD, 0xB4, 0xA0, 0x5D, 0xC0, 0x60, 0x40, 0xEC,
+	 0xC0, 0x60, 0x00, 0xED, 0xC0, 0x60, 0x80, 0xEE, 0xAC, 0x4F, 0xBF, 0xB4, 0xA0, 0x5C, 0x19, 0x60,
+	 0x48, 0xF1, 0xFF, 0xFF, 0x64, 0x40, 0x02, 0x27, 0x06, 0x00, 0x28, 0xE2, 0x24, 0xE2, 0x40, 0x21,
+	 0xFE, 0x01, 0x75, 0x40, 0x0D, 0x00, 0x28, 0xE2, 0x24, 0xE2, 0x75, 0x40, 0x80, 0x2B, 0xAB, 0xFF,
+	 0x14, 0xE0, 0x94, 0xE0, 0x40, 0x21, 0xFE, 0x01, 0x10, 0xE0, 0x75, 0x40, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x33, 0x60, 0xEE, 0x62, 0xA2, 0xDF, 0x01, 0x60, 0x39, 0xE2, 0x04, 0x60, 0x00, 0x7A, 0xAC, 0x4F,
+	 0x40, 0xBC, 0x00, 0x7F, 0xA0, 0x5C, 0xC0, 0x60, 0x59, 0xEC, 0xC0, 0x60, 0x07, 0xED, 0xC0, 0x60,
+	 0x8F, 0xEE, 0xAE, 0x4F, 0x04, 0xBC, 0x00, 0x7F, 0xA0, 0x5E, 0x26, 0x61, 0xCD, 0x81, 0xFF, 0xFF,
+	 0xFD, 0x02, 0xAE, 0x4F, 0xFB, 0xB4, 0xA0, 0x5E, 0xA0, 0x01, 0xF1, 0xFC, 0xAD, 0x4F, 0xFD, 0xB4,
+	 0xA0, 0x5D, 0x15, 0x60, 0x80, 0xE7, 0xC0, 0x60, 0x40, 0xEC, 0xC0, 0x60, 0x00, 0xED, 0xAC, 0x4F,
+	 0xBF, 0xB4, 0xA0, 0x5C, 0xC0, 0x60, 0x84, 0xEE, 0xAE, 0x4F, 0x04, 0xBC, 0x00, 0x7F, 0xA0, 0x5E,
+	 0x00, 0x7A, 0x0F, 0x60, 0x19, 0xE2, 0x0E, 0x60, 0x36, 0xF3, 0xFF, 0xFF, 0x60, 0x41, 0x75, 0x44,
+	 0x80, 0x2B, 0xAB, 0xFF, 0x80, 0x27, 0x08, 0x00, 0x14, 0xE0, 0x94, 0xE0, 0x34, 0xE2, 0x61, 0x5A,
+	 0x48, 0x21, 0xFE, 0x01, 0x00, 0xE0, 0x75, 0x40, 0x0A, 0x60, 0x19, 0xE2, 0x00, 0x64, 0x19, 0x60,
+	 0xF1, 0xFB, 0x08, 0x60, 0x15, 0xF1, 0x08, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x01, 0x64, 0x19, 0x60, 0xF2, 0xFB, 0xFF, 0xFF, 0x10, 0xE0, 0x01, 0x60, 0x34, 0xE2, 0xFF, 0xFF,
+	 0x05, 0x7A, 0xAC, 0x4F, 0x40, 0xBC, 0x00, 0x7F, 0xA0, 0x5C, 0xC0, 0x60, 0x59, 0xEC, 0xC0, 0x60,
+	 0x07, 0xED, 0xC0, 0x60, 0x8F, 0xEE, 0xAE, 0x4F, 0x04, 0xBC, 0x00, 0x7F, 0xA0, 0x5E, 0x1B, 0x60,
+	 0xF3, 0xF1, 0xAD, 0x4F, 0x00, 0x7F, 0xFA, 0xB4, 0x64, 0x41, 0x7D, 0xF1, 0x02, 0xB1, 0x04, 0x65,
+	 0x02, 0x02, 0x64, 0x40, 0x01, 0x2B, 0x01, 0x65, 0xB4, 0x84, 0xA0, 0x5D, 0x26, 0x61, 0xCD, 0x81,
+	 0xFF, 0xFF, 0xFD, 0x02, 0xAE, 0x4F, 0xFB, 0xB4, 0xA0, 0x5E, 0x1B, 0x60, 0xF3, 0xF1, 0xAD, 0x4F,
+	 0x00, 0x7F, 0xFA, 0xB4, 0x64, 0x41, 0x7D, 0xF1, 0x02, 0xB1, 0x04, 0x65, 0x02, 0x02, 0x64, 0x40,
+	 0x01, 0x2B, 0x01, 0x65, 0xB4, 0x84, 0xA0, 0x5D, 0x30, 0x01, 0x19, 0x60, 0xF3, 0xF3, 0xFF, 0xFF,
+	 0x01, 0x1B, 0x2B, 0x01, 0x31, 0x44, 0x04, 0x2A, 0x28, 0x01, 0x08, 0x26, 0x26, 0x01, 0x19, 0x60,
+	 0xF4, 0xF3, 0xFF, 0xFF, 0x01, 0x18, 0x21, 0x01, 0x7E, 0xF5, 0xF1, 0xFC, 0xAD, 0x4F, 0xFD, 0xB4,
+	 0xA0, 0x5D, 0x15, 0x60, 0x80, 0xE7, 0xC0, 0x60, 0x40, 0xEC, 0xC0, 0x60, 0x00, 0xED, 0xAC, 0x4F,
+	 0xBF, 0xB4, 0xA0, 0x5C, 0xC0, 0x60, 0x84, 0xEE, 0xAE, 0x4F, 0x04, 0xBC, 0x00, 0x7F, 0xA0, 0x5E,
+	 0x00, 0x7A, 0x2D, 0x60, 0x5A, 0x63, 0xA3, 0xD1, 0x05, 0x60, 0xDC, 0x64, 0xD0, 0x80, 0x00, 0x64,
+	 0x01, 0x06, 0x01, 0x64, 0x40, 0x4E, 0xB2, 0xF1, 0x66, 0x41, 0xE1, 0x81, 0xE1, 0x81, 0xE1, 0x81,
+	 0xE1, 0x81, 0x61, 0x46, 0x73, 0x42, 0x5A, 0x92, 0x3F, 0x64, 0xA0, 0x84, 0x60, 0x47, 0xE0, 0x84,
+	 0xE0, 0x85, 0x62, 0x47, 0xE8, 0x84, 0xE8, 0x84, 0x3F, 0xB4, 0x60, 0x41, 0x64, 0x44, 0x14, 0x90,
+	 0x3F, 0x26, 0xCC, 0x84, 0x14, 0x90, 0x3F, 0x26, 0xCC, 0x84, 0x62, 0x41, 0x60, 0x55, 0xB2, 0xFB,
+	 0x72, 0x5C, 0x67, 0x42, 0xD2, 0x80, 0xA2, 0x48, 0x20, 0x2B, 0x05, 0x00, 0x01, 0x02, 0x7C, 0x5C,
+	 0x04, 0x60, 0x00, 0x64, 0xC4, 0x85, 0xE8, 0xE2, 0xE4, 0xE2, 0x61, 0x42, 0x49, 0x91, 0x64, 0x44,
+	 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xB4, 0x84, 0x60, 0x45,
+	 0x51, 0x94, 0x04, 0x60, 0x00, 0x61, 0x01, 0x0D, 0x44, 0x94, 0x62, 0x41, 0x19, 0x60, 0xF5, 0xF1,
+	 0x61, 0x42, 0x64, 0x43, 0xCF, 0x83, 0xCF, 0x83, 0x03, 0x03, 0xE3, 0x83, 0x48, 0x94, 0xFE, 0x1F,
+	 0x2E, 0x40, 0x01, 0x26, 0xE0, 0x84, 0x60, 0x41, 0xE9, 0x81, 0xE9, 0x81, 0xE9, 0x81, 0xE9, 0x81,
+	 0x44, 0x94, 0xE9, 0x81, 0xE9, 0x81, 0x54, 0x94, 0xE9, 0x81, 0xE9, 0x81, 0xE9, 0x81, 0x44, 0x94,
+	 0xE9, 0x81, 0xE9, 0x81, 0xE9, 0x81, 0x54, 0x94, 0x19, 0xE2, 0x2E, 0x40, 0x01, 0x26, 0xE8, 0x84,
+	 0x29, 0x61, 0x54, 0x91, 0x61, 0x43, 0x11, 0x06, 0x75, 0x44, 0x80, 0x2B, 0xAB, 0xFF, 0x80, 0x27,
+	 0x0C, 0x00, 0x14, 0xE0, 0x94, 0xE0, 0x34, 0xE2, 0x61, 0x5A, 0x48, 0x21, 0xFE, 0x01, 0x00, 0xE0,
+	 0x7A, 0x43, 0x15, 0xA1, 0x75, 0x40, 0x80, 0x2B, 0x06, 0xA1, 0x5D, 0x91, 0x61, 0x44, 0x2E, 0x40,
+	 0x01, 0x26, 0xE0, 0x84, 0x60, 0x43, 0xEB, 0x83, 0xEB, 0x83, 0xEB, 0x83, 0x89, 0xFF, 0x10, 0xE0,
+	 0x80, 0x60, 0x00, 0x75, 0x88, 0xFF, 0xEB, 0x83, 0xEB, 0x83, 0x5C, 0x94, 0xEB, 0x83, 0x5C, 0x94,
+	 0xEB, 0x83, 0xEB, 0x83, 0xEB, 0x83, 0xEB, 0x83, 0xEB, 0x83, 0x4C, 0x94, 0x2E, 0x40, 0x01, 0x26,
+	 0xE8, 0x84, 0x60, 0x43, 0x65, 0x41, 0x62, 0x45, 0xD5, 0x85, 0x04, 0x60, 0x00, 0x61, 0x01, 0x0D,
+	 0xC5, 0x85, 0xC4, 0x84, 0x60, 0x43, 0x62, 0x41, 0xE1, 0x81, 0xE1, 0x81, 0xE1, 0x81, 0xE1, 0x81,
+	 0xE1, 0x81, 0xE1, 0x9C, 0x00, 0x61, 0xDD, 0x81, 0x58, 0x94, 0x4A, 0x92, 0xFC, 0x05, 0x41, 0x4F,
+	 0x00, 0x61, 0x62, 0x45, 0x1C, 0x60, 0x0A, 0xF3, 0xE3, 0x83, 0xF1, 0x81, 0xE3, 0x83, 0xF1, 0x81,
+	 0xE3, 0x83, 0xF1, 0x81, 0xE3, 0x83, 0xF1, 0x81, 0xE3, 0x83, 0xF1, 0x81, 0xE3, 0x83, 0xF1, 0x81,
+	 0xA0, 0x52, 0xB2, 0xF3, 0xC3, 0x9C, 0x44, 0x94, 0x01, 0x04, 0xDC, 0x84, 0x60, 0x55, 0xB2, 0xFB,
+	 0x64, 0x52, 0xE9, 0xE2, 0x65, 0x53, 0xB3, 0xF3, 0x06, 0x04, 0xDC, 0x84, 0xB3, 0xFB, 0xB4, 0xF3,
+	 0x02, 0x04, 0xDC, 0x84, 0xB4, 0xFB, 0x2F, 0x43, 0xCF, 0x83, 0x6C, 0xF3, 0xFF, 0xFF, 0x5C, 0x94,
+	 0xFF, 0xFF, 0x0C, 0x24, 0x01, 0x64, 0x6C, 0xFB, 0x16, 0x60, 0xAC, 0xF1, 0xFF, 0xFF, 0x03, 0x1B,
+	 0x31, 0x40, 0x02, 0x2A, 0x07, 0x00, 0x73, 0xF3, 0xFF, 0xFF, 0x5C, 0x94, 0xFF, 0xFF, 0x0C, 0x24,
+	 0x00, 0x64, 0x73, 0xFB, 0x19, 0x60, 0xF5, 0xF3, 0x01, 0x7C, 0x5C, 0x94, 0x00, 0x36, 0x01, 0x64,
+	 0xA2, 0xDB, 0x19, 0x60, 0xF2, 0xF9, 0x01, 0x60, 0x34, 0xE2, 0x32, 0x7A, 0xAC, 0x4F, 0x40, 0xBC,
+	 0x00, 0x7F, 0xA0, 0x5C, 0xC0, 0x60, 0x59, 0xEC, 0xC0, 0x60, 0x07, 0xED, 0xC0, 0x60, 0x8F, 0xEE,
+	 0xAE, 0x4F, 0x04, 0xBC, 0x00, 0x7F, 0xA0, 0x5E, 0x0A, 0x61, 0xCD, 0x81, 0xFF, 0xFF, 0xFD, 0x02,
+	 0xAE, 0x4F, 0xFB, 0xB4, 0xA0, 0x5E, 0x1B, 0x60, 0xF3, 0xF1, 0xAD, 0x4F, 0x00, 0x7F, 0xFA, 0xB4,
+	 0x64, 0x41, 0x7D, 0xF1, 0x02, 0xB1, 0x04, 0x65, 0x02, 0x02, 0x64, 0x40, 0x01, 0x2B, 0x01, 0x65,
+	 0xB4, 0x84, 0xA0, 0x5D, 0x37, 0x60, 0x7F, 0x78, 0xFF, 0xFF, 0x24, 0xE2, 0x2D, 0xF3, 0x2C, 0xF3,
+	 0x00, 0xBD, 0xCC, 0x84, 0x08, 0x03, 0x2C, 0xFB, 0x06, 0x02, 0x65, 0x44, 0x2C, 0xFB, 0x8A, 0xFF,
+	 0x80, 0x60, 0x00, 0x75, 0x88, 0xFF, 0x44, 0xF3, 0xFF, 0xFF, 0xDC, 0x84, 0x44, 0xFB, 0x2F, 0x60,
+	 0x4A, 0x65, 0x2F, 0x60, 0x48, 0x61, 0xA5, 0xD3, 0xA1, 0xD3, 0x11, 0x18, 0xCC, 0x84, 0xA1, 0xDB,
+	 0x0E, 0x02, 0xA5, 0xD3, 0xA1, 0xDB, 0x17, 0x60, 0xA7, 0xF3, 0x17, 0x60, 0xA6, 0xF1, 0xA2, 0xDB,
+	 0xD0, 0x80, 0xFF, 0xFF, 0x04, 0x03, 0x8A, 0xFF, 0x20, 0x60, 0x00, 0x75, 0x88, 0xFF, 0xF1, 0xF3,
+	 0x31, 0x40, 0x01, 0x2A, 0x3D, 0x00, 0x60, 0x43, 0x04, 0xB0, 0x02, 0xB0, 0x08, 0x24, 0x16, 0x02,
+	 0x10, 0xB0, 0x29, 0x44, 0x34, 0x02, 0x00, 0xA8, 0xCC, 0x81, 0x0D, 0x03, 0x41, 0x49, 0x2F, 0x02,
+	 0x63, 0x40, 0x08, 0x2A, 0x08, 0x00, 0xF7, 0xB3, 0x1B, 0x60, 0xF6, 0xF1, 0xAD, 0x4F, 0xFD, 0xB4,
+	 0xA0, 0x5D, 0x44, 0x49, 0x24, 0x00, 0x63, 0x40, 0x02, 0x2A, 0x10, 0x00, 0x1B, 0x60, 0xF7, 0xF3,
+	 0x1B, 0x60, 0xF5, 0xFB, 0x40, 0x49, 0x1B, 0x60, 0xF8, 0xF3, 0x1B, 0x60, 0xF6, 0xFB, 0x0C, 0xBB,
+	 0xFD, 0xB3, 0xAD, 0x4F, 0x02, 0xBC, 0x00, 0x7F, 0xA0, 0x5D, 0x11, 0x00, 0x1B, 0x60, 0xF9, 0xF3,
+	 0x37, 0x60, 0xEA, 0x7C, 0x0C, 0x18, 0xA4, 0xDB, 0x40, 0x49, 0x1B, 0x60, 0xFA, 0xF3, 0x1B, 0x60,
+	 0xF6, 0xFB, 0x08, 0xBB, 0xFB, 0xB3, 0xAD, 0x4F, 0x02, 0xBC, 0x00, 0x7F, 0xA0, 0x5D, 0xF1, 0xFD,
+	 0x00, 0x60, 0xA4, 0xF3, 0x62, 0x43, 0x17, 0x18, 0x58, 0xD3, 0x62, 0x41, 0x03, 0x18, 0xCC, 0x84,
+	 0xA1, 0xDB, 0x11, 0x00, 0x49, 0xD3, 0xA3, 0xDB, 0x06, 0xA1, 0xA1, 0xD3, 0x59, 0xD1, 0x60, 0x45,
+	 0xA5, 0xD3, 0x59, 0xD1, 0xB0, 0x84, 0xA5, 0xDB, 0x64, 0x44, 0x06, 0x36, 0xCD, 0xFE, 0x07, 0x36,
+	 0xD6, 0xFE, 0xE6, 0x01, 0x23, 0x46, 0xB8, 0x60, 0x03, 0x78, 0xFF, 0xFF, 0x46, 0x43, 0x26, 0x60,
+	 0x3E, 0x61, 0xA1, 0xD3, 0x59, 0xD1, 0x06, 0x1B, 0x59, 0xD3, 0x59, 0xD1, 0x03, 0x1B, 0x59, 0xD3,
+	 0x59, 0xD1, 0xF0, 0x18, 0x00, 0x63, 0x49, 0xDD, 0x60, 0x40, 0x02, 0x36, 0x11, 0x00, 0x03, 0x36,
+	 0x32, 0x00, 0x01, 0x36, 0x08, 0x00, 0x05, 0x3A, 0xEA, 0x01, 0xA4, 0xD3, 0x5A, 0xD3, 0x9C, 0x85,
+	 0xA4, 0x84, 0xA2, 0xDB, 0xE4, 0x01, 0x01, 0x60, 0x48, 0x61, 0x00, 0x64, 0xA1, 0xDB, 0xDF, 0x01,
+	 0x3A, 0x60, 0x3E, 0x64, 0x40, 0x45, 0x22, 0x00, 0x01, 0x60, 0x48, 0x66, 0xA6, 0xD3, 0x04, 0xA1,
+	 0x60, 0x43, 0xA1, 0xD3, 0xC9, 0x81, 0x60, 0x45, 0x00, 0xBB, 0xA1, 0xDB, 0xBE, 0xD3, 0x09, 0x03,
+	 0xD4, 0x84, 0x9C, 0x84, 0xDC, 0x84, 0xFF, 0xFF, 0x04, 0x0E, 0xA3, 0xD1, 0x63, 0x46, 0x64, 0x43,
+	 0xF2, 0x01, 0x9C, 0x84, 0xDC, 0x85, 0x49, 0xDD, 0x61, 0x44, 0x00, 0xBB, 0xA6, 0xDB, 0x02, 0x03,
+	 0x65, 0x44, 0xBE, 0xDB, 0xBC, 0x01, 0x3A, 0x60, 0x19, 0x64, 0x40, 0x45, 0x01, 0x60, 0x48, 0x66,
+	 0xA6, 0xD3, 0xFF, 0xFF, 0xD0, 0x80, 0x0F, 0x18, 0x02, 0x03, 0x60, 0x46, 0xF9, 0x01, 0x58, 0xD3,
+	 0xA4, 0xD3, 0x60, 0x45, 0x00, 0x63, 0xA4, 0xDD, 0x05, 0x18, 0x58, 0xD3, 0xFF, 0xFF, 0xC4, 0x83,
+	 0xA2, 0xDD, 0xCA, 0x84, 0xA6, 0xDB, 0x25, 0x58, 0x64, 0x41, 0x00, 0x60, 0x46, 0x74, 0xCD, 0xE2,
+	 0x04, 0xE1, 0x02, 0x60, 0x00, 0xE1, 0x3F, 0x44, 0x40, 0x26, 0x05, 0x00, 0x1C, 0x60, 0x0F, 0xF3,
+	 0x5A, 0xD1, 0xA0, 0x50, 0xA4, 0x50, 0x3F, 0x40, 0x02, 0x2B, 0x03, 0x00, 0x3A, 0x60, 0xB7, 0x78,
+	 0xFF, 0xFF, 0x04, 0x29, 0xFE, 0x01, 0xC4, 0xE2, 0x43, 0x64, 0x3A, 0xDB, 0xA1, 0xF3, 0xFF, 0xFF,
+	 0x60, 0x41, 0x3F, 0x44, 0xFF, 0x01, 0x3F, 0x40, 0x40, 0x26, 0x05, 0x00, 0x1C, 0x60, 0x0D, 0xF3,
+	 0x5A, 0xD1, 0xA0, 0x50, 0xA4, 0x52, 0xC4, 0xE2, 0x32, 0x7B, 0x4D, 0xE2, 0xBF, 0xFE, 0xC4, 0xE2,
+	 0x41, 0xFF, 0xE0, 0xFE, 0xE1, 0xFE, 0xE2, 0xFE, 0x43, 0xFF, 0x44, 0xFF, 0x46, 0xFF, 0xA2, 0xF3,
+	 0x62, 0xFF, 0x60, 0x40, 0x05, 0x36, 0x2D, 0xFF, 0x07, 0x36, 0xD5, 0xFE, 0x08, 0xE1, 0x88, 0x60,
+	 0x85, 0x71, 0x8D, 0xE2, 0xA2, 0x60, 0x41, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x10, 0x62, 0x3D, 0x60,
+	 0x58, 0x4D, 0x3B, 0x78, 0xFF, 0xFF, 0x64, 0x41, 0xA9, 0x9C, 0x60, 0x45, 0x3D, 0x60, 0x58, 0x4D,
+	 0x0F, 0x78, 0xFF, 0xFF, 0xA1, 0xF1, 0x09, 0x60, 0xB4, 0x61, 0x64, 0x44, 0x01, 0x27, 0x24, 0x00,
+	 0x60, 0x40, 0x0E, 0x3A, 0x0D, 0x00, 0x01, 0x7C, 0x14, 0x60, 0x6F, 0xF9, 0x44, 0x60, 0x08, 0x7C,
+	 0x14, 0x60, 0x41, 0xF9, 0x16, 0x60, 0x62, 0xF1, 0x02, 0x60, 0xB0, 0x61, 0xB1, 0x9C, 0x26, 0x00,
+	 0x00, 0x7C, 0x14, 0x60, 0x6F, 0xF9, 0x40, 0x60, 0x08, 0x7C, 0x14, 0x60, 0x41, 0xF9, 0x16, 0x60,
+	 0x62, 0xF1, 0x02, 0x60, 0x90, 0x61, 0xB1, 0x9C, 0x09, 0x60, 0x67, 0x65, 0xFF, 0xB4, 0xC4, 0x85,
+	 0xE0, 0x84, 0xE0, 0x84, 0xC4, 0x81, 0x12, 0x00, 0xFF, 0xB4, 0xED, 0xA0, 0x2C, 0x60, 0xC6, 0x61,
+	 0x04, 0x04, 0xE2, 0xA0, 0xD9, 0x81, 0x01, 0x04, 0xD9, 0x81, 0xA1, 0xD1, 0x02, 0x60, 0x50, 0x61,
+	 0x26, 0x60, 0xF0, 0x65, 0xE0, 0x84, 0x44, 0xD3, 0xB1, 0x9C, 0xC8, 0x81, 0x61, 0x47, 0x00, 0x7E,
+	 0xE9, 0x81, 0x07, 0x60, 0xF0, 0x65, 0xA5, 0x81, 0x0B, 0xB9, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x85,
+	 0xB5, 0x85, 0x04, 0x60, 0x44, 0x62, 0x3D, 0x60, 0x58, 0x4D, 0x0F, 0x78, 0xFF, 0xFF, 0xA1, 0xF3,
+	 0xC8, 0x61, 0x61, 0x54, 0xCD, 0xE2, 0x60, 0x40, 0x01, 0x27, 0x2E, 0x00, 0xCC, 0x84, 0xE0, 0x85,
+	 0x15, 0x60, 0xA2, 0xE7, 0x26, 0x60, 0x80, 0x64, 0x3D, 0x60, 0x58, 0x4F, 0x04, 0x78, 0xFF, 0xFF,
+	 0x26, 0x60, 0x9C, 0x64, 0x3D, 0x60, 0x58, 0x4F, 0x04, 0x78, 0xFF, 0xFF, 0x26, 0x60, 0xB8, 0x64,
+	 0x3D, 0x60, 0x58, 0x4F, 0x04, 0x78, 0xFF, 0xFF, 0x26, 0x60, 0xD4, 0x64, 0x3D, 0x60, 0x58, 0x4F,
+	 0x04, 0x78, 0xFF, 0xFF, 0x75, 0x64, 0x06, 0x61, 0x61, 0x48, 0x60, 0x44, 0x80, 0xBC, 0xFF, 0xB4,
+	 0x60, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x28, 0x60, 0xE6, 0x7C, 0x07, 0x60, 0xE8, 0xF9,
+	 0x28, 0x60, 0x6E, 0x63, 0x14, 0x61, 0x21, 0x00, 0x14, 0x60, 0xDF, 0xF1, 0xFF, 0xB4, 0xED, 0xA0,
+	 0x64, 0x41, 0x04, 0x04, 0xE2, 0xA0, 0xD9, 0x81, 0x01, 0x04, 0xD9, 0x81, 0xA1, 0xD1, 0x14, 0x60,
+	 0x0E, 0xF3, 0x64, 0x41, 0xFF, 0xB1, 0xFF, 0x60, 0x00, 0x65, 0xA4, 0x84, 0x34, 0x94, 0xA2, 0xDB,
+	 0x5A, 0xD3, 0x64, 0x41, 0xA5, 0x81, 0xFF, 0xB4, 0x34, 0x94, 0xA2, 0xDB, 0x29, 0x60, 0x52, 0x7C,
+	 0x07, 0x60, 0xE8, 0xF9, 0x27, 0x60, 0xFC, 0x63, 0x13, 0x61, 0x3D, 0x60, 0x58, 0x4D, 0x23, 0x78,
+	 0xFF, 0xFF, 0x07, 0x60, 0xE8, 0xF3, 0x31, 0x40, 0x80, 0x26, 0x36, 0xA4, 0x07, 0x60, 0xE8, 0xFB,
+	 0x60, 0x43, 0x09, 0x61, 0x3D, 0x60, 0x58, 0x4D, 0x23, 0x78, 0xFF, 0xFF, 0xA1, 0xF3, 0x29, 0x60,
+	 0xBE, 0x61, 0x00, 0x7C, 0x7E, 0x63, 0x59, 0xD9, 0xFE, 0x1F, 0x60, 0x40, 0x01, 0x27, 0x03, 0x00,
+	 0x2A, 0x60, 0x40, 0x65, 0x15, 0x00, 0xFF, 0xB4, 0xF9, 0xA0, 0x2A, 0x60, 0x62, 0x65, 0x01, 0x7C,
+	 0x0D, 0x04, 0xED, 0xA0, 0x2A, 0x60, 0x84, 0x65, 0x11, 0x7C, 0x08, 0x04, 0xE2, 0xA0, 0x2A, 0x60,
+	 0xA6, 0x65, 0x21, 0x7C, 0x03, 0x04, 0x2A, 0x60, 0xC8, 0x65, 0x31, 0x7C, 0x64, 0x5F, 0x7D, 0xFB,
+	 0xA5, 0xD3, 0xDA, 0x85, 0xF0, 0xA0, 0x29, 0x60, 0xBE, 0x61, 0x08, 0x06, 0x40, 0x54, 0x58, 0x53,
+	 0x08, 0xFF, 0x37, 0x60, 0x7A, 0x64, 0x43, 0xFB, 0x08, 0xFF, 0xFF, 0x01, 0x60, 0x43, 0x60, 0x46,
+	 0xA5, 0xD1, 0xDA, 0x85, 0xA5, 0xD3, 0xDA, 0x85, 0x59, 0xD9, 0x59, 0xDB, 0x59, 0xD9, 0x59, 0xDB,
+	 0xFB, 0x1F, 0x0C, 0x63, 0xA5, 0xD1, 0xDA, 0x85, 0xA5, 0xD3, 0xDA, 0x85, 0x59, 0xD9, 0x59, 0xDB,
+	 0x59, 0xD9, 0x59, 0xDB, 0xF7, 0x1F, 0x66, 0x44, 0x0E, 0x63, 0x53, 0x93, 0x60, 0x40, 0x10, 0x36,
+	 0x07, 0x00, 0x65, 0x44, 0x48, 0xD3, 0x59, 0xD9, 0x59, 0xDB, 0x59, 0xD9, 0x59, 0xDB, 0xFB, 0x1F,
+	 0x16, 0x60, 0x39, 0xF1, 0x7D, 0xF3, 0x64, 0x43, 0xDB, 0x81, 0x2C, 0x60, 0x54, 0x65, 0x60, 0x40,
+	 0x01, 0x37, 0x12, 0x00, 0x11, 0x37, 0x17, 0x00, 0x21, 0x37, 0x1D, 0x00, 0x31, 0x37, 0x22, 0x00,
+	 0xA3, 0xD1, 0x16, 0x60, 0x34, 0xF5, 0x64, 0x44, 0xFF, 0xB4, 0x16, 0x60, 0x33, 0xFB, 0x64, 0x47,
+	 0xFF, 0xB4, 0x16, 0x60, 0x2A, 0xF1, 0x1D, 0x00, 0xA1, 0xD3, 0x16, 0x60, 0x35, 0xF5, 0xFF, 0xB4,
+	 0x16, 0x60, 0x2B, 0xF1, 0x16, 0x00, 0xA1, 0xD3, 0x16, 0x60, 0x36, 0xF5, 0x60, 0x47, 0xFF, 0xB4,
+	 0x16, 0x60, 0x2C, 0xF1, 0x0E, 0x00, 0x59, 0xD3, 0x16, 0x60, 0x37, 0xF5, 0xFF, 0xB4, 0x16, 0x60,
+	 0x2D, 0xF1, 0x07, 0x00, 0x59, 0xD3, 0x16, 0x60, 0x38, 0xF5, 0x60, 0x47, 0xFF, 0xB4, 0x16, 0x60,
+	 0x2E, 0xF1, 0x16, 0x60, 0x32, 0xFB, 0x16, 0x60, 0x2F, 0xF9, 0x66, 0x42, 0xFC, 0xA2, 0xA2, 0xD3,
+	 0x2B, 0x60, 0x42, 0x63, 0xCC, 0x84, 0xE8, 0x84, 0xCC, 0x81, 0x63, 0x45, 0xA6, 0xD3, 0xDA, 0x82,
+	 0xFF, 0xB4, 0xFF, 0xFF, 0x03, 0x03, 0x60, 0x40, 0x80, 0x2B, 0x03, 0x00, 0xDA, 0x86, 0xCD, 0x81,
+	 0xF5, 0x01, 0x00, 0xB9, 0xA6, 0xD3, 0x0B, 0x03, 0x5A, 0xD1, 0xDA, 0x86, 0xFF, 0xB4, 0xE0, 0x84,
+	 0xC4, 0x84, 0x5C, 0x90, 0xBD, 0xD9, 0xFD, 0x02, 0xCD, 0x81, 0x66, 0x42, 0xF2, 0x02, 0x5A, 0xD3,
+	 0x2B, 0x60, 0x80, 0x65, 0xD7, 0x80, 0xBD, 0xDB, 0xFD, 0x02, 0x7D, 0xF3, 0x19, 0x60, 0x7B, 0xF1,
+	 0x60, 0x40, 0x01, 0x27, 0x09, 0x00, 0x64, 0x40, 0x10, 0x26, 0x06, 0x00, 0x13, 0x64, 0xCB, 0xFB,
+	 0x01, 0x60, 0x67, 0x64, 0x37, 0xFB, 0x09, 0x00, 0x08, 0x64, 0xCB, 0xFB, 0xA1, 0xF3, 0x01, 0x60,
+	 0x67, 0x7C, 0x60, 0x40, 0x01, 0x27, 0x5B, 0x7C, 0x37, 0xF9, 0x19, 0x60, 0x4D, 0xF1, 0x7D, 0xF3,
+	 0x64, 0x40, 0x00, 0x3A, 0x1B, 0x00, 0x60, 0x40, 0x01, 0x27, 0x0D, 0x00, 0x32, 0x60, 0xAB, 0x63,
+	 0x4C, 0x94, 0x0E, 0xA5, 0x60, 0xFE, 0xA0, 0xD1, 0xA5, 0xD3, 0x19, 0x60, 0x72, 0xF9, 0x19, 0x60,
+	 0x73, 0xFB, 0x20, 0xFE, 0x0B, 0x00, 0xFF, 0xB4, 0xF8, 0xA4, 0x32, 0x60, 0xC8, 0x63, 0x4C, 0x94,
+	 0x60, 0xFE, 0xA0, 0xD1, 0xFF, 0xFF, 0x19, 0x60, 0x73, 0xF9, 0x20, 0xFE, 0x19, 0x60, 0x75, 0xF3,
+	 0x16, 0x60, 0xD8, 0xF1, 0x60, 0x43, 0xD3, 0x80, 0x19, 0x60, 0x76, 0xF3, 0x01, 0x07, 0x63, 0x5C,
+	 0xD0, 0x80, 0xFF, 0xFF, 0x01, 0x07, 0x60, 0x5C, 0x19, 0x60, 0x4F, 0xF9, 0x19, 0x60, 0x53, 0xF9,
+	 0x7D, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x27, 0x0A, 0x00, 0xFF, 0xB5, 0x10, 0x60, 0xF4, 0x63,
+	 0x65, 0x41, 0xCD, 0x81, 0x06, 0xA3, 0xFD, 0x02, 0xFA, 0xA3, 0xA3, 0xD3, 0x0F, 0x00, 0x01, 0x60,
+	 0xFF, 0x65, 0xA4, 0x84, 0x11, 0x60, 0x60, 0x61, 0xA1, 0xD1, 0xFF, 0xFF, 0xD0, 0x80, 0x08, 0xA1,
+	 0xFB, 0x02, 0xFC, 0xA1, 0xA1, 0xD3, 0x19, 0x60, 0x4F, 0xF1, 0xFF, 0xB4, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x04, 0x07, 0x19, 0x60, 0x4F, 0xFB, 0x19, 0x60, 0x53, 0xFB, 0x19, 0x60, 0x4F, 0xF3, 0x19, 0x60,
+	 0x72, 0xF1, 0x19, 0x60, 0x74, 0xFB, 0xD0, 0x80, 0xFF, 0xFF, 0x02, 0x04, 0x19, 0x60, 0x74, 0xF9,
+	 0x2C, 0x60, 0x74, 0x63, 0x2B, 0x60, 0x02, 0x65, 0x16, 0x60, 0x33, 0xF1, 0x2A, 0x60, 0xEA, 0x61,
+	 0x2C, 0x60, 0x62, 0x64, 0x40, 0x4F, 0x04, 0x64, 0xC3, 0x60, 0x58, 0x4D, 0x1A, 0x78, 0xFF, 0xFF,
+	 0x19, 0x60, 0x4F, 0xF3, 0x19, 0x60, 0x73, 0xF1, 0x19, 0x60, 0x74, 0xFB, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x02, 0x04, 0x19, 0x60, 0x74, 0xF9, 0x2C, 0x60, 0x7C, 0x63, 0x16, 0x60, 0x32, 0xF1, 0x2B, 0x60,
+	 0x42, 0x65, 0x2C, 0x60, 0x60, 0x64, 0x40, 0x4F, 0x08, 0x64, 0xC3, 0x60, 0x58, 0x4D, 0x1A, 0x78,
+	 0xFF, 0xFF, 0x7D, 0xF3, 0x08, 0x7C, 0x38, 0xF9, 0x2B, 0x60, 0xDA, 0x61, 0x60, 0x40, 0x01, 0x2B,
+	 0x0E, 0x00, 0x01, 0x37, 0x06, 0x00, 0x11, 0x37, 0x03, 0x00, 0x21, 0x3B, 0x1E, 0xA1, 0x1E, 0xA1,
+	 0x1E, 0xA1, 0x1C, 0x63, 0x2B, 0x60, 0xBC, 0x64, 0x59, 0xD1, 0x58, 0xD9, 0xFD, 0x1F, 0x16, 0x60,
+	 0x2F, 0xF3, 0x00, 0x7C, 0x60, 0x45, 0x70, 0x62, 0x3D, 0x60, 0x58, 0x4D, 0x0F, 0x78, 0xFF, 0xFF,
+	 0x04, 0x29, 0xFE, 0x01, 0x00, 0x60, 0x10, 0x62, 0x3D, 0x60, 0x58, 0x4D, 0x3B, 0x78, 0xFF, 0xFF,
+	 0x01, 0x61, 0xB1, 0x9C, 0x60, 0x45, 0x3D, 0x60, 0x58, 0x4D, 0x0F, 0x78, 0xFF, 0xFF, 0x3A, 0x60,
+	 0x95, 0x78, 0xFF, 0xFF, 0x44, 0xD3, 0x80, 0x7C, 0x60, 0x48, 0x60, 0x47, 0x00, 0x7F, 0xB0, 0x8A,
+	 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x2F, 0x58, 0xFF, 0xFF, 0xD5, 0x60, 0x84, 0xE7, 0x62, 0x47,
+	 0x80, 0xBF, 0x60, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x64, 0x4A, 0xFF, 0xFF, 0x01, 0x16,
+	 0xFE, 0x01, 0x65, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x95, 0x60, 0x84, 0xE7, 0x2D, 0x58,
+	 0xFF, 0xFF, 0x00, 0x7C, 0xBD, 0xD3, 0xD5, 0x60, 0x84, 0xE7, 0x60, 0x47, 0x80, 0xBF, 0x60, 0x4A,
+	 0xBD, 0xD3, 0x01, 0x16, 0xFE, 0x01, 0x90, 0x8A, 0xBD, 0xD3, 0x01, 0x16, 0xFE, 0x01, 0x90, 0x8A,
+	 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0xCD, 0x81, 0x95, 0x60, 0x84, 0xE7, 0xEB, 0x02, 0x2D, 0x58,
+	 0xFF, 0xFF, 0xD5, 0x60, 0x84, 0xE7, 0x62, 0x4A, 0x02, 0x64, 0x01, 0x16, 0xFE, 0x01, 0xCC, 0x84,
+	 0xFF, 0xFF, 0xFD, 0x02, 0x7C, 0x49, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x68, 0x5C, 0x7C, 0x49,
+	 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x68, 0x44, 0x95, 0x60, 0x84, 0xE7, 0x2D, 0x58, 0xFF, 0xFF,
+	 0x40, 0xFF, 0x20, 0x44, 0xBF, 0xB4, 0x40, 0x40, 0x03, 0x00, 0x20, 0x44, 0x40, 0xBC, 0x40, 0x40,
+	 0x43, 0x45, 0x20, 0x44, 0x20, 0xBC, 0x40, 0x40, 0x02, 0x00, 0x43, 0x45, 0xF6, 0x01, 0x00, 0x64,
+	 0x19, 0x60, 0xF2, 0xFB, 0x3F, 0x44, 0x40, 0x26, 0x05, 0x00, 0x1C, 0x60, 0x0F, 0xF3, 0x5A, 0xD1,
+	 0xA0, 0x50, 0xA4, 0x50, 0xAE, 0x4F, 0xFD, 0xB4, 0x04, 0xBC, 0xA0, 0x5E, 0x00, 0x60, 0x02, 0x71,
+	 0x8D, 0xE2, 0x40, 0xE1, 0x40, 0x29, 0xFE, 0x01, 0x04, 0xAC, 0xA0, 0x5E, 0xFF, 0xFF, 0x00, 0x60,
+	 0x10, 0x62, 0x19, 0x60, 0x8E, 0x7C, 0x00, 0x60, 0xAC, 0x65, 0x3D, 0x60, 0x58, 0x4D, 0x0F, 0x78,
+	 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x60, 0x10, 0x62, 0x3D, 0x60, 0x58, 0x4D, 0x3B, 0x78, 0xFF, 0xFF,
+	 0x60, 0x40, 0x19, 0x60, 0x8E, 0x64, 0x64, 0x40, 0xD0, 0x80, 0x14, 0x71, 0x05, 0x03, 0x8D, 0xE2,
+	 0x40, 0xE1, 0x40, 0x29, 0xFE, 0x01, 0xE2, 0x01, 0x3F, 0x44, 0x40, 0x26, 0x05, 0x00, 0x1C, 0x60,
+	 0x0D, 0xF3, 0x5A, 0xD1, 0xA0, 0x50, 0xA4, 0x52, 0x27, 0x60, 0x36, 0x63, 0x1E, 0x61, 0x3D, 0x60,
+	 0x58, 0x4D, 0x23, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x14, 0x71, 0x8D, 0xE2, 0x40, 0xE1, 0x40, 0x29,
+	 0xFE, 0x01, 0x31, 0x44, 0x40, 0x26, 0x02, 0x00, 0x80, 0x26, 0x17, 0x00, 0x28, 0x60, 0xE6, 0x63,
+	 0x07, 0x60, 0xE8, 0xFD, 0x09, 0x61, 0x3D, 0x60, 0x58, 0x4D, 0x23, 0x78, 0xFF, 0xFF, 0x31, 0x44,
+	 0x40, 0x2A, 0x14, 0x00, 0x31, 0x44, 0x7F, 0xB4, 0x40, 0x51, 0xAE, 0x4C, 0x10, 0x26, 0x0E, 0x00,
+	 0x07, 0x60, 0xE9, 0xFB, 0x31, 0x44, 0x80, 0xBC, 0x40, 0x51, 0x29, 0x60, 0x1C, 0x63, 0x07, 0x60,
+	 0xE8, 0xFD, 0x09, 0x61, 0x3D, 0x60, 0x58, 0x4D, 0x23, 0x78, 0xFF, 0xFF, 0x27, 0x60, 0xEA, 0x63,
+	 0x03, 0x61, 0x3D, 0x60, 0x58, 0x4D, 0x23, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x10, 0x62, 0x19, 0x60,
+	 0x8F, 0x7C, 0x00, 0x60, 0xAC, 0x65, 0x3D, 0x60, 0x58, 0x4D, 0x0F, 0x78, 0xFF, 0xFF, 0x80, 0xE1,
+	 0xBF, 0xFE, 0xA1, 0x4F, 0x70, 0xB4, 0x50, 0x36, 0x0C, 0x00, 0x20, 0x36, 0x03, 0x00, 0x3A, 0x60,
+	 0x77, 0x78, 0xFF, 0xFF, 0x01, 0x60, 0x1A, 0xE1, 0xDF, 0xFE, 0x19, 0xFF, 0x00, 0xE1, 0xA1, 0xFF,
+	 0xFF, 0xFF, 0x20, 0x44, 0x40, 0x2A, 0x85, 0x00, 0x7D, 0xF1, 0x3B, 0x00, 0x83, 0x00, 0x19, 0x60,
+	 0xF2, 0xF3, 0xFF, 0xFF, 0x01, 0x18, 0x59, 0x01, 0x43, 0x45, 0x20, 0x44, 0x20, 0xBC, 0x40, 0x40,
+	 0x1C, 0x60, 0x0F, 0xF3, 0x3F, 0x40, 0x40, 0x26, 0x01, 0x00, 0xA0, 0x50, 0xAE, 0x4F, 0xFD, 0xB4,
+	 0xA0, 0x5E, 0xAC, 0x4F, 0x10, 0xBC, 0xA0, 0x5C, 0xFF, 0xFF, 0x10, 0xAC, 0xA0, 0x5C, 0x00, 0x60,
+	 0xC8, 0x71, 0x8D, 0xE2, 0x40, 0xE1, 0x40, 0x29, 0xFE, 0x01, 0x7D, 0xF1, 0x30, 0x61, 0x64, 0x44,
+	 0x01, 0x2B, 0x20, 0xA1, 0x30, 0x64, 0x61, 0x5F, 0x60, 0x45, 0x0C, 0x60, 0x00, 0x62, 0x00, 0x60,
+	 0x71, 0x7C, 0x3D, 0x60, 0x58, 0x4D, 0x0F, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0xC8, 0x71, 0x8D, 0xE2,
+	 0x40, 0xE1, 0x40, 0x29, 0xFE, 0x01, 0x01, 0x60, 0x08, 0xE1, 0x7D, 0xF1, 0x20, 0x44, 0x40, 0xBC,
+	 0x40, 0x40, 0x19, 0x60, 0xF2, 0xF3, 0xFF, 0xFF, 0x03, 0x18, 0x3D, 0x60, 0x57, 0x78, 0xFF, 0xFF,
+	 0x1B, 0x60, 0xF3, 0xF1, 0xAD, 0x4F, 0x00, 0x7F, 0xFA, 0xB4, 0x64, 0x41, 0x7D, 0xF1, 0x02, 0xB1,
+	 0x04, 0x65, 0x02, 0x02, 0x64, 0x40, 0x01, 0x2B, 0x01, 0x65, 0xB4, 0x84, 0xA0, 0x5D, 0x20, 0x44,
+	 0x40, 0x2A, 0x43, 0x45, 0x20, 0xBC, 0x40, 0x40, 0xA1, 0xF9, 0x05, 0x64, 0xA2, 0xFB, 0xDF, 0xFE,
+	 0x19, 0xFF, 0xDD, 0xFE, 0x26, 0x00, 0x20, 0x44, 0x20, 0xBC, 0x40, 0x40, 0x43, 0x45, 0xA4, 0xD1,
+	 0xDA, 0x83, 0xC3, 0x85, 0x80, 0xE1, 0xDF, 0xFE, 0xBD, 0xD3, 0xFF, 0xFF, 0x60, 0x48, 0x60, 0x47,
+	 0x80, 0xBC, 0x00, 0x7F, 0x60, 0x4A, 0xD7, 0x80, 0xA1, 0xFF, 0xF6, 0x02, 0xBF, 0xFE, 0x11, 0x00,
+	 0x43, 0x45, 0xA4, 0xD1, 0xDA, 0x83, 0x0D, 0x18, 0x64, 0x44, 0x00, 0x61, 0xFA, 0xA4, 0xDD, 0x81,
+	 0xFD, 0x02, 0x3D, 0x60, 0x58, 0x4D, 0x23, 0x78, 0xFF, 0xFF, 0xBF, 0xFE, 0x02, 0x00, 0xF1, 0xFE,
+	 0x01, 0x00, 0x25, 0x43, 0x21, 0xE1, 0x00, 0x64, 0xBF, 0xDB, 0x20, 0x44, 0x20, 0x2A, 0x07, 0x00,
+	 0x07, 0xB4, 0x04, 0x36, 0xC3, 0xFE, 0x06, 0x36, 0xCC, 0xFE, 0x07, 0x36, 0xD5, 0xFE, 0x20, 0x44,
+	 0x98, 0xB4, 0x40, 0x40, 0x26, 0x60, 0x26, 0x63, 0xBD, 0xD3, 0x03, 0x61, 0x0F, 0x1B, 0x04, 0xA3,
+	 0xBD, 0xD3, 0x04, 0x61, 0x0B, 0x1B, 0x04, 0xA3, 0xBD, 0xD3, 0x06, 0x61, 0x07, 0x1B, 0x04, 0xA3,
+	 0xBD, 0xD3, 0x07, 0x61, 0x03, 0x1B, 0xC3, 0x60, 0x48, 0x78, 0xFF, 0xFF, 0xA3, 0xD1, 0x40, 0x44,
+	 0x20, 0x44, 0x07, 0xB5, 0xD4, 0x85, 0x35, 0x80, 0x24, 0x45, 0x26, 0x60, 0x66, 0x64, 0x44, 0xD7,
+	 0xFF, 0xFF, 0xFF, 0xFF, 0x43, 0x45, 0x20, 0x44, 0x20, 0xBC, 0x40, 0x40, 0x64, 0x43, 0xBD, 0xD3,
+	 0xBD, 0xD1, 0x40, 0x44, 0x10, 0x27, 0x19, 0x00, 0x3F, 0x40, 0x02, 0x2B, 0x06, 0x00, 0x24, 0x47,
+	 0x08, 0x2B, 0x13, 0x00, 0x07, 0xB4, 0x01, 0x36, 0x11, 0x00, 0xFF, 0x60, 0x7F, 0x65, 0x15, 0x60,
+	 0xA2, 0x64, 0x24, 0x40, 0x08, 0x2B, 0xA4, 0x84, 0xA0, 0x57, 0xFF, 0xFF, 0x64, 0x49, 0xFF, 0xFF,
+	 0x68, 0x44, 0x01, 0x16, 0xFD, 0x01, 0x00, 0x7F, 0xA3, 0xDB, 0xAB, 0x01, 0x64, 0x42, 0x3D, 0x60,
+	 0x58, 0x4D, 0x3B, 0x78, 0xFF, 0xFF, 0xBD, 0xD9, 0xA3, 0xDB, 0xA3, 0x01, 0x43, 0x45, 0x20, 0x44,
+	 0x20, 0xBC, 0x40, 0x40, 0x64, 0x43, 0xBD, 0xD3, 0xA3, 0xD1, 0x40, 0x44, 0x10, 0x2B, 0x16, 0x00,
+	 0xBE, 0xD1, 0xFF, 0xFF, 0x15, 0x60, 0x80, 0xE7, 0x24, 0x40, 0x07, 0x27, 0x04, 0x00, 0xAC, 0x4F,
+	 0x10, 0xBC, 0x00, 0x7F, 0xA0, 0x5C, 0x64, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x24, 0x40,
+	 0x20, 0x27, 0x1D, 0x00, 0xAC, 0x4F, 0xEF, 0xB4, 0xA0, 0x5C, 0x19, 0x00, 0x3F, 0x40, 0x02, 0x2B,
+	 0x06, 0x00, 0x24, 0x47, 0x08, 0x2B, 0x13, 0x00, 0x07, 0xB4, 0x01, 0x36, 0x11, 0x00, 0x15, 0x60,
+	 0x22, 0x64, 0x24, 0x40, 0x08, 0x27, 0x80, 0xBC, 0x7C, 0x48, 0xBE, 0xD3, 0xA0, 0x57, 0x60, 0x48,
+	 0x64, 0x44, 0x80, 0xBC, 0xFF, 0xB4, 0x60, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x69, 0x01,
+	 0x01, 0x61, 0x3D, 0x60, 0x58, 0x4D, 0x23, 0x78, 0xFF, 0xFF, 0x63, 0x01, 0x30, 0x44, 0x02, 0xA8,
+	 0x00, 0xE1, 0x07, 0x02, 0x62, 0xFF, 0x63, 0xFF, 0x64, 0xFF, 0x65, 0xFF, 0x66, 0xFF, 0xBF, 0xFE,
+	 0xA1, 0xFF, 0x82, 0xFF, 0x88, 0xFF, 0x6C, 0x40, 0x41, 0xFF, 0xC4, 0xE2, 0x43, 0xFF, 0x5C, 0x49,
+	 0x08, 0xE1, 0xA2, 0x60, 0x41, 0x78, 0xFF, 0xFF, 0x30, 0x44, 0x02, 0xA8, 0x00, 0xE1, 0x02, 0x02,
+	 0xA1, 0xFF, 0xFF, 0xFF, 0x82, 0xFF, 0x88, 0xFF, 0xA8, 0xE2, 0xCB, 0xF1, 0x00, 0x6B, 0x89, 0xFF,
+	 0x64, 0x54, 0x88, 0xFF, 0x9F, 0xFE, 0x02, 0x05, 0x64, 0x44, 0x60, 0x54, 0xCD, 0xE2, 0xC2, 0x64,
+	 0x3A, 0xDB, 0xBC, 0xFF, 0xB5, 0xFF, 0x1D, 0xFF, 0x26, 0x44, 0x02, 0xB4, 0x40, 0x46, 0x3C, 0x44,
+	 0x00, 0xBC, 0xFF, 0xFF, 0x06, 0x03, 0x27, 0x40, 0x26, 0x22, 0x03, 0x00, 0x02, 0x64, 0x31, 0xFB,
+	 0xC0, 0xFE, 0x27, 0x44, 0x20, 0x2A, 0x04, 0x00, 0xA0, 0x60, 0x00, 0xEA, 0xB0, 0x60, 0x00, 0xEA,
+	 0x5C, 0x44, 0x27, 0x44, 0x18, 0xB4, 0x40, 0x47, 0x00, 0xE1, 0x29, 0x40, 0x50, 0x2B, 0x37, 0x00,
+	 0xEF, 0x60, 0xFF, 0x65, 0x29, 0x44, 0x24, 0x89, 0x31, 0x40, 0x08, 0x26, 0x0B, 0x00, 0x21, 0x46,
+	 0xA7, 0xF4, 0x1D, 0xF2, 0xFF, 0xB3, 0x00, 0x7C, 0x05, 0x03, 0x06, 0x61, 0x5D, 0x91, 0x09, 0x60,
+	 0x02, 0x65, 0x02, 0x03, 0x00, 0x61, 0x15, 0x00, 0xD4, 0x80, 0x63, 0x45, 0xFB, 0x07, 0x65, 0x43,
+	 0x80, 0x60, 0x00, 0x62, 0xF6, 0x82, 0x53, 0x90, 0xE3, 0x83, 0xFC, 0x04, 0xEB, 0x83, 0xEB, 0x83,
+	 0xEA, 0x82, 0x5C, 0x94, 0xB2, 0x9C, 0xF3, 0x07, 0x64, 0x41, 0xDD, 0x81, 0xE1, 0x81, 0xE1, 0x81,
+	 0xE1, 0x81, 0x2B, 0x44, 0x54, 0x90, 0x70, 0x45, 0x02, 0x28, 0x61, 0x44, 0xC4, 0x84, 0xFF, 0xFF,
+	 0x04, 0x24, 0x00, 0xB4, 0x60, 0x50, 0x08, 0x28, 0x01, 0x00, 0x20, 0x29, 0x6D, 0xE2, 0xA4, 0xE2,
+	 0xC4, 0xE2, 0x47, 0xFF, 0xB6, 0xFF, 0xB7, 0xFF, 0xB4, 0xFF, 0x32, 0xF1, 0x08, 0x29, 0x09, 0x00,
+	 0x64, 0x40, 0x07, 0x22, 0x06, 0x00, 0x43, 0xFF, 0x27, 0x44, 0x10, 0xBC, 0x40, 0x47, 0x00, 0x64,
+	 0x32, 0xFB, 0x31, 0x41, 0x3C, 0x44, 0x01, 0xB1, 0x00, 0xBC, 0x0A, 0x02, 0x09, 0x03, 0x32, 0xF3,
+	 0x00, 0x7C, 0x01, 0xB4, 0xFF, 0xFF, 0x04, 0x03, 0x32, 0xF9, 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE,
+	 0xC8, 0x60, 0x09, 0x7D, 0x00, 0x60, 0x00, 0x6B, 0x00, 0x64, 0x33, 0xFB, 0x0C, 0x60, 0x16, 0x64,
+	 0xA0, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xE1, 0x30, 0x40, 0x02, 0x36, 0xA1, 0xFF, 0x83, 0xFF,
+	 0x8D, 0xFF, 0x5C, 0x44, 0x5C, 0x43, 0x5C, 0x42, 0x5C, 0x41, 0x5C, 0x40, 0xAC, 0xFF, 0xAD, 0xFF,
+	 0xE7, 0xE1, 0xB3, 0x60, 0xFC, 0x78, 0xFF, 0xFF, 0x30, 0x44, 0x02, 0xA8, 0x00, 0xE1, 0x03, 0x02,
+	 0x28, 0xE2, 0x40, 0xFF, 0xA1, 0xFF, 0x84, 0xFF, 0xC2, 0x60, 0x45, 0x64, 0x40, 0x42, 0xB7, 0x60,
+	 0xF7, 0x64, 0x40, 0x40, 0xBA, 0xF3, 0x7E, 0xFB, 0x0F, 0x60, 0xE2, 0x63, 0xC7, 0xF3, 0xBD, 0xDB,
+	 0x00, 0x60, 0x9A, 0x64, 0xBD, 0xDB, 0x02, 0x64, 0xBD, 0xDB, 0x04, 0x64, 0xA3, 0xDB, 0x5C, 0x49,
+	 0x0A, 0x64, 0x40, 0x4B, 0x5C, 0x5C, 0x01, 0x60, 0x39, 0xE2, 0x04, 0x60, 0x00, 0x7A, 0x89, 0xFF,
+	 0x03, 0x60, 0xFF, 0x73, 0x88, 0xFF, 0xB7, 0x60, 0xF7, 0x78, 0xFF, 0xFF, 0x30, 0x44, 0x02, 0xA8,
+	 0x00, 0xE1, 0x06, 0x02, 0x40, 0xFF, 0x42, 0xFF, 0x43, 0xFF, 0x44, 0xFF, 0x45, 0xFF, 0xA1, 0xFF,
+	 0x88, 0xFF, 0x85, 0xFF, 0x21, 0xE1, 0x5C, 0x40, 0xC3, 0x60, 0x48, 0x78, 0xFF, 0xFF, 0xA2, 0xFF,
+	 0x30, 0x44, 0x02, 0xA8, 0x00, 0xE1, 0x01, 0x02, 0xA1, 0xFF, 0x86, 0xFF, 0x88, 0xFF, 0x5C, 0x46,
+	 0x5C, 0x49, 0x5C, 0x40, 0xEF, 0x60, 0x58, 0x4F, 0x1B, 0x78, 0xFF, 0xFF, 0x1D, 0x60, 0x58, 0x4F,
+	 0x81, 0x78, 0xFF, 0xFF, 0xD3, 0x60, 0x58, 0x4F, 0x58, 0x78, 0xFF, 0xFF, 0xE7, 0x60, 0x58, 0x4F,
+	 0x99, 0x78, 0xFF, 0xFF, 0x20, 0x60, 0x58, 0x4F, 0x19, 0x78, 0xFF, 0xFF, 0xF4, 0x60, 0x58, 0x4F,
+	 0xE9, 0x78, 0xFF, 0xFF, 0xE9, 0x60, 0x58, 0x4F, 0xCA, 0x78, 0xFF, 0xFF, 0x27, 0x60, 0x58, 0x4F,
+	 0x71, 0x78, 0xFF, 0xFF, 0xEE, 0x60, 0x58, 0x4F, 0x69, 0x78, 0xFF, 0xFF, 0x1F, 0xE1, 0xA3, 0xFF,
+	 0xCA, 0x60, 0xD4, 0x78, 0xFF, 0xFF, 0x03, 0xE1, 0xA3, 0xFF, 0xFE, 0xFC, 0xFF, 0xFC, 0x25, 0x60,
+	 0x96, 0x63, 0x17, 0xFD, 0xAE, 0xFF, 0x2A, 0x60, 0x1D, 0x78, 0xFF, 0xFF, 0x42, 0x6F, 0x6F, 0x74,
+	 0x63, 0x6F, 0x64, 0x65, 0x20, 0x21, 0x21, 0x20, 0x20, 0x00, 0x53, 0x54, 0x41, 0x2F, 0x41, 0x50,
+	 0x20, 0x46, 0x75, 0x6E, 0x63, 0x27, 0x73, 0x00, 0x1F, 0x00, 0x04, 0x00, 0x01, 0x00, 0x24, 0x00,
+	 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x04, 0x00,
+	 0x06, 0x00, 0x07, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x06, 0x00, 0x06, 0x00, 0x07, 0x00,
+	 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00,
+	 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0xA6, 0xF3, 0x21, 0x61, 0x00, 0x7C, 0x01, 0x00, 0x00, 0xFA,
+	 0x60, 0x46, 0xFE, 0x63, 0xA3, 0xD8, 0xFE, 0x1F, 0xCD, 0x81, 0xD8, 0x84, 0xF8, 0x02, 0x21, 0x61,
+	 0x80, 0x67, 0x40, 0x4A, 0xA6, 0xF5, 0x05, 0x18, 0x2A, 0x43, 0x02, 0xFC, 0x5F, 0x8A, 0x00, 0xF4,
+	 0xFA, 0x01, 0x2E, 0x58, 0xFF, 0xFF, 0xA8, 0xF1, 0xA7, 0xF3, 0x7C, 0x63, 0xAA, 0xFB, 0x60, 0x46,
+	 0x01, 0xFC, 0xDC, 0x84, 0xD0, 0x80, 0x00, 0xFA, 0xFA, 0x04, 0xAB, 0xFB, 0x60, 0x46, 0x00, 0x64,
+	 0x00, 0xFA, 0x63, 0x44, 0x80, 0x7F, 0x01, 0xFA, 0xA8, 0xF3, 0xA7, 0xF1, 0xDC, 0x84, 0xD0, 0x84,
+	 0xA9, 0xFB, 0x03, 0x60, 0x26, 0x61, 0xB6, 0x60, 0x58, 0x4D, 0x0F, 0x78, 0xFF, 0xFF, 0x66, 0x44,
+	 0x2E, 0xFB, 0x82, 0xFF, 0x40, 0x42, 0x87, 0xFF, 0xA9, 0xF3, 0xB1, 0xFB, 0x00, 0x64, 0x40, 0x50,
+	 0x63, 0xFF, 0x60, 0xFF, 0x66, 0xFF, 0x65, 0xFF, 0x64, 0xFF, 0x61, 0xFF, 0x62, 0xFF, 0x49, 0x60,
+	 0x02, 0xE1, 0x52, 0x60, 0x02, 0xE1, 0x5C, 0x60, 0x02, 0xE1, 0x65, 0x60, 0x02, 0xE1, 0x6B, 0x60,
+	 0x02, 0xE1, 0x76, 0x60, 0x02, 0xE1, 0x41, 0x60, 0x02, 0xE1, 0x0C, 0x64, 0x13, 0x60, 0x1C, 0xFB,
+	 0x41, 0x60, 0x07, 0x64, 0x9F, 0xFB, 0x2D, 0xFF, 0x06, 0x61, 0x41, 0x4B, 0x09, 0x60, 0x08, 0x61,
+	 0xB6, 0x60, 0x58, 0x4D, 0x0F, 0x78, 0xFF, 0xFF, 0xF0, 0x67, 0x0E, 0xFA, 0x26, 0x60, 0x04, 0x64,
+	 0x13, 0x60, 0x10, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0x2B, 0x41, 0x4D, 0x8B, 0xFF, 0xFF, 0xEA, 0x02, 0x05, 0x61, 0x41, 0x4B, 0x09, 0x60, 0x08, 0x61,
+	 0xB6, 0x60, 0x58, 0x4D, 0x0F, 0x78, 0xFF, 0xFF, 0x25, 0x60, 0xF8, 0x64, 0x13, 0x60, 0x10, 0xFB,
+	 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x2B, 0x41, 0x4D, 0x8B,
+	 0xFF, 0xFF, 0xEC, 0x02, 0x40, 0x60, 0x45, 0x78, 0xFF, 0xFF, 0x00, 0xEA, 0x00, 0xEB, 0x50, 0x60,
+	 0x03, 0xEA, 0x51, 0x60, 0x13, 0xEA, 0x52, 0x60, 0x30, 0xEA, 0x53, 0x60, 0x40, 0xEA, 0x54, 0x60,
+	 0x52, 0xEA, 0x55, 0x60, 0x6D, 0xEA, 0x56, 0x60, 0x71, 0xEA, 0x57, 0x60, 0x8B, 0xEA, 0x58, 0x60,
+	 0x47, 0xEA, 0x59, 0x60, 0xA0, 0xEA, 0x5A, 0x60, 0xB2, 0xEA, 0x5B, 0x60, 0xC1, 0xEA, 0x5C, 0x60,
+	 0xD7, 0xEA, 0x5D, 0x60, 0xEB, 0xEA, 0x5E, 0x60, 0xA0, 0xEA, 0x50, 0x60, 0x36, 0xEB, 0x51, 0x60,
+	 0x37, 0xEB, 0x52, 0x60, 0x20, 0xEB, 0x53, 0x60, 0xE4, 0xEB, 0x54, 0x60, 0x34, 0xEB, 0x55, 0x60,
+	 0x58, 0xEB, 0x56, 0x60, 0x48, 0xEB, 0x57, 0x60, 0xD0, 0xEB, 0x58, 0x60, 0xC3, 0xEB, 0x59, 0x60,
+	 0xFC, 0xEB, 0x5A, 0x60, 0x34, 0xEB, 0x5B, 0x60, 0x58, 0xEB, 0x5C, 0x60, 0xC0, 0xEB, 0x5D, 0x60,
+	 0xD0, 0xEB, 0x5E, 0x60, 0x91, 0xEB, 0x00, 0xEA, 0x00, 0xEB, 0xE0, 0x60, 0x02, 0xEA, 0xE0, 0x60,
+	 0x03, 0xEB, 0xA0, 0x60, 0x00, 0xEB, 0xB0, 0x60, 0x00, 0xEB, 0xAB, 0x48, 0x40, 0x3B, 0x01, 0x00,
+	 0xFC, 0x01, 0x00, 0xEB, 0x03, 0x60, 0x02, 0x64, 0xA0, 0xDB, 0x0F, 0x64, 0x60, 0x7F, 0xA0, 0x5A,
+	 0x80, 0x60, 0x00, 0xEA, 0xA0, 0x60, 0x00, 0xEA, 0xD1, 0x60, 0x00, 0xEA, 0x24, 0x44, 0xFF, 0xB4,
+	 0x04, 0xFB, 0x50, 0x60, 0x00, 0x64, 0x05, 0xFB, 0x10, 0x60, 0x10, 0x75, 0x2A, 0x60, 0x1D, 0x78,
+	 0xFF, 0xFF, 0x3F, 0x40, 0x40, 0x26, 0x40, 0x00, 0x05, 0x60, 0xF9, 0xF1, 0x42, 0x60, 0x08, 0x64,
+	 0x09, 0x60, 0x19, 0x63, 0x64, 0x40, 0x01, 0x2B, 0x04, 0x00, 0x42, 0x60, 0x09, 0x64, 0x0A, 0x60,
+	 0x19, 0x63, 0x1C, 0x60, 0x0F, 0xFB, 0x04, 0x60, 0x00, 0xBC, 0x1C, 0x60, 0x0B, 0xFB, 0x1C, 0x60,
+	 0x0A, 0xFD, 0x1D, 0x60, 0x19, 0x63, 0x1C, 0x60, 0x0E, 0xFD, 0x80, 0x60, 0x1C, 0x64, 0x3F, 0x40,
+	 0x01, 0x2A, 0x02, 0x00, 0x60, 0x60, 0x1C, 0x64, 0x1C, 0x60, 0x10, 0xFB, 0x1C, 0x60, 0x0C, 0xFB,
+	 0x1C, 0x60, 0x0F, 0xF3, 0xA0, 0x50, 0xA0, 0x50, 0x0B, 0x60, 0xF8, 0x63, 0xA3, 0xD1, 0x38, 0x60,
+	 0x12, 0x61, 0xA1, 0xD3, 0xF8, 0xA3, 0x90, 0x84, 0xA2, 0xDB, 0xA3, 0xD1, 0x59, 0xD3, 0x06, 0xA3,
+	 0x90, 0x84, 0xA2, 0xDB, 0xA3, 0xD1, 0x59, 0xD3, 0xFE, 0xA3, 0x90, 0x84, 0xA2, 0xDB, 0xA3, 0xD1,
+	 0x59, 0xD3, 0xFF, 0xFF, 0x90, 0x84, 0xA2, 0xDB, 0x80, 0x60, 0x58, 0xEC, 0x80, 0x60, 0x00, 0xED,
+	 0x80, 0x60, 0x80, 0xEE, 0x40, 0xEC, 0x00, 0xED, 0x00, 0xEE, 0xC0, 0x60, 0x59, 0xEC, 0xC0, 0x60,
+	 0x07, 0xED, 0xC0, 0x60, 0x8F, 0xEE, 0xAD, 0x4F, 0xFA, 0xB4, 0xA0, 0x5D, 0x00, 0xF3, 0x28, 0xFB,
+	 0x40, 0x44, 0x37, 0x60, 0x7B, 0x7C, 0x20, 0xF9, 0x3F, 0x60, 0x18, 0x7C, 0x21, 0xF9, 0x3F, 0x60,
+	 0x2E, 0x7C, 0x22, 0xF9, 0x3F, 0x60, 0xC5, 0x7C, 0x23, 0xF9, 0x3F, 0x60, 0xD6, 0x7C, 0x24, 0xF9,
+	 0x40, 0x60, 0x00, 0x7C, 0x25, 0xF9, 0x40, 0x60, 0x11, 0x7C, 0x26, 0xF9, 0xD0, 0x60, 0x00, 0xE8,
+	 0x28, 0xE8, 0x44, 0x60, 0x01, 0xE6, 0x10, 0x67, 0x40, 0x52, 0x10, 0x60, 0x04, 0xE6, 0x08, 0x60,
+	 0x06, 0x63, 0xFD, 0x60, 0x0C, 0x65, 0x5B, 0xD3, 0xBF, 0xD1, 0x10, 0x18, 0xC3, 0x83, 0xD4, 0x80,
+	 0xC3, 0x83, 0xF9, 0x02, 0xFA, 0xA3, 0xA3, 0xD3, 0x02, 0x60, 0x00, 0x65, 0xF9, 0xA0, 0xFC, 0xA0,
+	 0x0D, 0x05, 0x04, 0x05, 0x78, 0x43, 0x02, 0x61, 0x29, 0x60, 0xEA, 0x78, 0x21, 0x60, 0x00, 0x65,
+	 0x3F, 0x43, 0x21, 0x60, 0x00, 0x65, 0xC0, 0x60, 0x8F, 0xEE, 0x08, 0x00, 0x02, 0x60, 0x00, 0x65,
+	 0x00, 0x60, 0x00, 0x64, 0x18, 0xFB, 0x3F, 0x43, 0x11, 0x60, 0x10, 0xE6, 0xB7, 0x84, 0x40, 0x5F,
+	 0x37, 0x60, 0xF8, 0x63, 0x3F, 0x40, 0x20, 0x27, 0x06, 0x00, 0x0F, 0x60, 0xFF, 0x64, 0xBD, 0xDB,
+	 0x0F, 0x60, 0xF0, 0x64, 0x03, 0x00, 0x0F, 0x64, 0xBD, 0xDB, 0x00, 0x64, 0xA3, 0xDB, 0x00, 0x60,
+	 0x30, 0xE2, 0x00, 0x60, 0x50, 0xE2, 0x00, 0x60, 0x79, 0xE2, 0x00, 0x60, 0x90, 0xE2, 0x01, 0x60,
+	 0xD0, 0xE2, 0x01, 0x60, 0xF0, 0xE2, 0x01, 0x60, 0xB0, 0xE2, 0x13, 0x64, 0xCB, 0xFB, 0x01, 0x60,
+	 0x67, 0x64, 0x37, 0xFB, 0x00, 0x60, 0x28, 0x64, 0x36, 0xFB, 0x09, 0x60, 0x2A, 0x64, 0xB6, 0xFB,
+	 0x82, 0xFF, 0x92, 0xFF, 0x5C, 0x41, 0x5C, 0x46, 0x5C, 0x47, 0x00, 0xE1, 0xA3, 0x60, 0xF4, 0x63,
+	 0x0C, 0x60, 0x16, 0x64, 0xA0, 0xDD, 0x87, 0xFF, 0x97, 0xFF, 0x0C, 0x60, 0x02, 0x64, 0x40, 0x5A,
+	 0x06, 0xA4, 0x40, 0x5B, 0x5C, 0x5E, 0x16, 0x60, 0xCF, 0xF3, 0x7D, 0xFB, 0x3F, 0x40, 0x01, 0x22,
+	 0x03, 0x00, 0x80, 0x60, 0x37, 0x7C, 0x02, 0x00, 0x80, 0x60, 0x27, 0x7C, 0x1A, 0x60, 0x1F, 0xF9,
+	 0x01, 0x60, 0x06, 0x64, 0xA7, 0xFB, 0x02, 0x60, 0x7F, 0x64, 0x00, 0x60, 0x42, 0x65, 0xD4, 0x84,
+	 0xA8, 0xFB, 0xDC, 0x84, 0xA6, 0xFB, 0x12, 0x60, 0xD8, 0xFB, 0x40, 0x60, 0x58, 0x4E, 0x7D, 0x78,
+	 0xFF, 0xFF, 0x3F, 0x40, 0x40, 0x26, 0x05, 0x00, 0x1C, 0x60, 0x0D, 0xF3, 0x5A, 0xD1, 0xA0, 0x50,
+	 0xA4, 0x52, 0x08, 0x60, 0x00, 0x63, 0xFA, 0x60, 0x00, 0x65, 0xBD, 0xD3, 0xA3, 0xD3, 0x02, 0xA8,
+	 0xD4, 0x80, 0x21, 0x02, 0x20, 0x02, 0x19, 0x60, 0x48, 0xF1, 0xFF, 0xFF, 0x64, 0x40, 0x80, 0x26,
+	 0x1A, 0x00, 0x04, 0xA3, 0xFD, 0x60, 0x0D, 0x65, 0x5B, 0xD3, 0xBF, 0xD1, 0x14, 0x18, 0xC3, 0x83,
+	 0xD4, 0x80, 0xC3, 0x83, 0xF9, 0x02, 0xBF, 0xD3, 0xAD, 0x49, 0xFE, 0xA0, 0x00, 0x64, 0x0C, 0x04,
+	 0x08, 0xB1, 0x20, 0xBC, 0x08, 0x28, 0x18, 0xBC, 0x07, 0x7C, 0x0E, 0x60, 0xDF, 0xF9, 0x05, 0x7C,
+	 0x0E, 0x60, 0xDE, 0xF9, 0x01, 0x00, 0x00, 0x64, 0x0E, 0x60, 0xDD, 0xFB, 0x40, 0x60, 0x95, 0x78,
+	 0xFF, 0xFF, 0x5C, 0x51, 0x3F, 0x41, 0xA5, 0x4C, 0x50, 0x37, 0x0B, 0x00, 0x01, 0xB9, 0x41, 0x5F,
+	 0xB5, 0x60, 0x55, 0xE0, 0x05, 0x60, 0xF9, 0xF1, 0xC0, 0x67, 0x90, 0x84, 0x3F, 0x40, 0x01, 0x26,
+	 0xA0, 0x50, 0x06, 0x60, 0x08, 0xF3, 0x01, 0x60, 0x01, 0x65, 0x01, 0x60, 0x02, 0x7C, 0xD4, 0x80,
+	 0xD0, 0x80, 0x01, 0x03, 0x10, 0x02, 0x5A, 0xD1, 0x5A, 0xD3, 0x3C, 0x60, 0x00, 0x66, 0xE0, 0x87,
+	 0x40, 0x4A, 0x80, 0x60, 0x9E, 0x61, 0x64, 0x44, 0xC8, 0x84, 0x0C, 0x63, 0xAA, 0x46, 0x58, 0xD0,
+	 0xAA, 0x46, 0x59, 0xD8, 0xFB, 0x1F, 0x08, 0x60, 0x00, 0x63, 0xFA, 0x60, 0x00, 0x65, 0xBD, 0xD3,
+	 0xA3, 0xD3, 0x02, 0xA8, 0xD4, 0x80, 0x07, 0x02, 0x06, 0x02, 0x8C, 0x60, 0xBA, 0x61, 0x3C, 0x60,
+	 0x00, 0x66, 0x41, 0x4B, 0x03, 0x00, 0x46, 0x60, 0x3B, 0x78, 0xFF, 0xFF, 0x2B, 0x41, 0x8D, 0x60,
+	 0x02, 0x7C, 0xD1, 0x80, 0xA1, 0xD2, 0x25, 0x05, 0x59, 0xD0, 0x60, 0x45, 0x59, 0xD2, 0x44, 0x47,
+	 0xE0, 0x87, 0x40, 0x4A, 0x59, 0xD2, 0x59, 0x8B, 0x40, 0x4C, 0x08, 0x60, 0x00, 0x63, 0xBE, 0xD3,
+	 0xBD, 0xD1, 0xEC, 0x18, 0xD4, 0x80, 0xEA, 0x18, 0x03, 0x03, 0xC3, 0x83, 0xC3, 0x83, 0xF7, 0x01,
+	 0x67, 0x44, 0xC0, 0x84, 0xE0, 0x85, 0x2C, 0x44, 0xD4, 0x80, 0x63, 0x41, 0x01, 0x06, 0x65, 0x44,
+	 0xC8, 0x83, 0xAA, 0x46, 0x59, 0xD1, 0x27, 0xD8, 0x5A, 0x87, 0xFC, 0x1F, 0xAA, 0x46, 0x2B, 0x41,
+	 0xD5, 0x01, 0x8D, 0x60, 0x02, 0x61, 0x41, 0x4B, 0x2B, 0x41, 0x8D, 0x60, 0x02, 0x7C, 0xD1, 0x80,
+	 0xA1, 0xD2, 0x27, 0x05, 0x59, 0xD0, 0x60, 0x45, 0x59, 0xD2, 0x44, 0x47, 0xE0, 0x87, 0x40, 0x4A,
+	 0x59, 0xD2, 0x59, 0x8B, 0x40, 0x4C, 0x08, 0x60, 0x00, 0x63, 0xBE, 0xD3, 0xBD, 0xD1, 0xEC, 0x18,
+	 0xD4, 0x80, 0xEA, 0x18, 0x03, 0x03, 0xC3, 0x83, 0xC3, 0x83, 0xF7, 0x01, 0x04, 0xA3, 0xA3, 0xD1,
+	 0x5A, 0x88, 0x2C, 0x43, 0xD3, 0x80, 0xFF, 0xFF, 0x01, 0x06, 0x64, 0x43, 0xCF, 0x83, 0xAA, 0x46,
+	 0x60, 0xFE, 0x28, 0xD1, 0x5E, 0x88, 0x27, 0xD8, 0x5A, 0x87, 0xFB, 0x1F, 0x20, 0xFE, 0xAA, 0x46,
+	 0xD3, 0x01, 0x07, 0x60, 0xEC, 0xF3, 0x20, 0x60, 0x00, 0x7C, 0x08, 0xB0, 0x10, 0xB0, 0x05, 0x02,
+	 0x04, 0x03, 0x07, 0x60, 0xEB, 0xF9, 0x07, 0x60, 0xEA, 0xF9, 0x02, 0xB0, 0x04, 0xB0, 0x0F, 0x02,
+	 0x13, 0x60, 0xD2, 0xF3, 0x0C, 0x03, 0x02, 0xBC, 0xA2, 0xDB, 0x14, 0x60, 0x65, 0xF3, 0x14, 0x60,
+	 0x29, 0xF3, 0x02, 0xBD, 0x02, 0xBC, 0xA2, 0xDB, 0x65, 0x44, 0x14, 0x60, 0x65, 0xFB, 0x07, 0x60,
+	 0xEC, 0xF3, 0x31, 0x41, 0x60, 0x40, 0x20, 0x2A, 0x40, 0xB9, 0x40, 0x26, 0x03, 0x00, 0x60, 0x40,
+	 0x01, 0x26, 0x80, 0xB9, 0x41, 0x51, 0xFA, 0x60, 0x3A, 0x65, 0x46, 0x60, 0x58, 0x4D, 0x4E, 0x78,
+	 0xFF, 0xFF, 0x03, 0x02, 0x44, 0x60, 0xAD, 0x78, 0xFF, 0xFF, 0x5B, 0xD3, 0xF8, 0x60, 0x3F, 0x65,
+	 0x00, 0x7F, 0xE0, 0x84, 0xE0, 0x84, 0x14, 0x60, 0x74, 0xF3, 0xE0, 0x9C, 0xA4, 0x84, 0xB0, 0x84,
+	 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0xBD, 0xD3, 0xFF, 0xFF,
+	 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0xE0, 0x84, 0x14, 0x60, 0x77, 0xF3, 0xE0, 0x9C, 0xA4, 0x84,
+	 0xB0, 0x84, 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x28, 0x60,
+	 0xF4, 0x61, 0xA3, 0xD3, 0xFF, 0xFF, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0xE0, 0x84, 0xA1, 0xD3,
+	 0xE0, 0x9C, 0xA4, 0x84, 0xB0, 0x84, 0xA1, 0xDB, 0xA3, 0xD3, 0xFF, 0xFF, 0x00, 0x7F, 0xE0, 0x84,
+	 0xE0, 0x84, 0x59, 0xD3, 0xE0, 0x9C, 0xA4, 0x84, 0xB0, 0x84, 0xA1, 0xDB, 0x14, 0x60, 0x7D, 0xF3,
+	 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84,
+	 0xA2, 0xDB, 0x14, 0x60, 0x80, 0xF3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x5A, 0xD3,
+	 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x14, 0x60, 0x83, 0xF3, 0xFF, 0xFF, 0xA4, 0x84,
+	 0xB0, 0x84, 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0xA3, 0xD3,
+	 0xFF, 0xFF, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0xE0, 0x84, 0x14, 0x60, 0x86, 0xF3, 0xE0, 0x9C,
+	 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB,
+	 0x14, 0x60, 0x89, 0xF3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF,
+	 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x14, 0x60, 0x8C, 0xF3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84,
+	 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x02, 0xA3, 0xA3, 0xD3,
+	 0xF8, 0x60, 0x3F, 0x65, 0x00, 0x7F, 0xE0, 0x84, 0xE0, 0x84, 0x14, 0x60, 0x8F, 0xF3, 0xE0, 0x9C,
+	 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xBD, 0xD3, 0xFF, 0xFF, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0xE0, 0x84, 0x14, 0x60, 0x92, 0xF3,
+	 0xE0, 0x9C, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84,
+	 0xA2, 0xDB, 0x29, 0x60, 0x2A, 0x61, 0xA3, 0xD3, 0xFF, 0xFF, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84,
+	 0xE0, 0x84, 0xA1, 0xD3, 0xE0, 0x9C, 0xA4, 0x84, 0xB0, 0x84, 0xA1, 0xDB, 0xA3, 0xD3, 0xFF, 0xFF,
+	 0x00, 0x7F, 0xE0, 0x84, 0xE0, 0x84, 0x59, 0xD3, 0xE0, 0x9C, 0xA4, 0x84, 0xB0, 0x84, 0xA1, 0xDB,
+	 0x14, 0x60, 0x98, 0xF3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF,
+	 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x14, 0x60, 0x9B, 0xF3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84,
+	 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x14, 0x60, 0x9E, 0xF3,
+	 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xA3, 0xD3, 0xFF, 0xFF, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0xE0, 0x84, 0x14, 0x60,
+	 0xA1, 0xF3, 0xE0, 0x9C, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84,
+	 0xB0, 0x84, 0xA2, 0xDB, 0x14, 0x60, 0xA4, 0xF3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB,
+	 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x14, 0x60, 0xA7, 0xF3, 0xFF, 0xFF,
+	 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0xA4, 0x84, 0xB0, 0x84, 0xA2, 0xDB,
+	 0x00, 0x60, 0x6A, 0x63, 0x29, 0x60, 0x50, 0x61, 0x28, 0x60, 0xE4, 0x64, 0x58, 0xD1, 0x59, 0xD9,
+	 0xFD, 0x1F, 0x14, 0x60, 0xB0, 0xF3, 0xFF, 0xFF, 0x18, 0xAC, 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF,
+	 0x18, 0xAC, 0xA2, 0xDB, 0x14, 0x60, 0xB4, 0xF3, 0xFF, 0xFF, 0x18, 0xAC, 0xA2, 0xDB, 0x14, 0x60,
+	 0xB6, 0xF3, 0xFF, 0xFF, 0x18, 0xAC, 0xA2, 0xDB, 0x14, 0x60, 0xBD, 0xF3, 0xFF, 0xFF, 0x18, 0xAC,
+	 0xA2, 0xDB, 0x14, 0x60, 0xBF, 0xF3, 0xFF, 0xFF, 0x18, 0xAC, 0xA2, 0xDB, 0x14, 0x60, 0xCB, 0xF3,
+	 0xFF, 0xFF, 0x18, 0xAC, 0xA2, 0xDB, 0x5A, 0xD3, 0xFF, 0xFF, 0x18, 0xAC, 0xA2, 0xDB, 0x14, 0x60,
+	 0xCF, 0xF3, 0xFF, 0xFF, 0x18, 0xAC, 0xA2, 0xDB, 0x14, 0x60, 0xD1, 0xF3, 0xFF, 0xFF, 0x18, 0xAC,
+	 0xA2, 0xDB, 0x14, 0x60, 0xD8, 0xF3, 0xFF, 0xFF, 0x18, 0xAC, 0xA2, 0xDB, 0x14, 0x60, 0xDA, 0xF3,
+	 0xFF, 0xFF, 0x18, 0xAC, 0xA2, 0xDB, 0xFA, 0x60, 0x2C, 0x65, 0x46, 0x60, 0x58, 0x4D, 0x4E, 0x78,
+	 0xFF, 0xFF, 0x0E, 0x03, 0x63, 0x45, 0x2A, 0x60, 0xEA, 0x63, 0x06, 0x61, 0xA5, 0xD1, 0xDA, 0x85,
+	 0x64, 0x44, 0x0F, 0xB4, 0xBD, 0xDB, 0x64, 0x47, 0x0F, 0xB4, 0xCD, 0x81, 0xBD, 0xDB, 0xF6, 0x02,
+	 0xFA, 0x60, 0x30, 0x65, 0x46, 0x60, 0x58, 0x4D, 0x4E, 0x78, 0xFF, 0xFF, 0x14, 0x03, 0xBD, 0xD3,
+	 0x63, 0x46, 0x2B, 0x60, 0x82, 0x63, 0x15, 0x60, 0xD0, 0xFB, 0xDA, 0x85, 0xBD, 0xDB, 0x0E, 0x61,
+	 0xA6, 0xD1, 0xDA, 0x86, 0x64, 0x44, 0xFF, 0xB4, 0xA5, 0xDB, 0xDA, 0x85, 0x64, 0x47, 0xFF, 0xB4,
+	 0xCD, 0x81, 0xBD, 0xDB, 0xF5, 0x02, 0xFA, 0x60, 0x31, 0x65, 0x46, 0x60, 0x58, 0x4D, 0x4E, 0x78,
+	 0xFF, 0xFF, 0x22, 0x03, 0xBD, 0xD3, 0x15, 0x60, 0xEE, 0xFB, 0x5A, 0x81, 0x15, 0x60, 0xFD, 0xFB,
+	 0x5A, 0x82, 0x16, 0x60, 0x0C, 0xFB, 0x5A, 0x83, 0x16, 0x60, 0x1B, 0xFB, 0x5A, 0x84, 0x0E, 0x61,
+	 0xBD, 0xD1, 0xBD, 0xD5, 0x64, 0x44, 0xFF, 0xB4, 0x21, 0xDB, 0x5A, 0x81, 0x64, 0x47, 0xFF, 0xB4,
+	 0x22, 0xDB, 0x5A, 0x82, 0x66, 0x44, 0xFF, 0xB4, 0x23, 0xDB, 0x5A, 0x83, 0x66, 0x47, 0xFF, 0xB4,
+	 0x24, 0xDB, 0xCD, 0x81, 0x5A, 0x84, 0xEC, 0x02, 0xFA, 0x60, 0x47, 0x65, 0x46, 0x60, 0x58, 0x4D,
+	 0x4E, 0x78, 0xFF, 0xFF, 0x11, 0x03, 0x63, 0x45, 0x2C, 0x60, 0x54, 0x63, 0xA5, 0xD1, 0xDA, 0x85,
+	 0xBD, 0xD9, 0x02, 0x61, 0xA5, 0xD1, 0xDA, 0x85, 0x64, 0x47, 0x00, 0x7E, 0xBD, 0xDB, 0x64, 0x44,
+	 0x00, 0x7E, 0xCD, 0x81, 0xBD, 0xDB, 0xF6, 0x02, 0xFA, 0x60, 0x2E, 0x65, 0x46, 0x60, 0x58, 0x4D,
+	 0x4E, 0x78, 0xFF, 0xFF, 0x1F, 0x03, 0x63, 0x46, 0xFC, 0xA3, 0xA3, 0xD3, 0x2B, 0x60, 0x02, 0x63,
+	 0xCC, 0x84, 0xE8, 0x84, 0xCC, 0x81, 0x00, 0x36, 0x0D, 0x00, 0x63, 0x45, 0xA6, 0xD3, 0x5A, 0xD1,
+	 0xDA, 0x86, 0xFF, 0xB4, 0xE0, 0x84, 0xC4, 0x84, 0x5C, 0x90, 0xBD, 0xD9, 0xFD, 0x02, 0xCD, 0x81,
+	 0x66, 0x42, 0xF4, 0x02, 0x66, 0x42, 0x5A, 0xD3, 0x2B, 0x60, 0x42, 0x65, 0xBD, 0xDB, 0xD7, 0x80,
+	 0xFF, 0xFF, 0xFC, 0x02, 0x2C, 0x60, 0x68, 0x61, 0xFA, 0x60, 0x46, 0x65, 0x46, 0x60, 0x58, 0x4D,
+	 0x4E, 0x78, 0xFF, 0xFF, 0x01, 0x03, 0xA1, 0xDD, 0xD9, 0x81, 0xFA, 0x60, 0x2F, 0x65, 0x46, 0x60,
+	 0x58, 0x4D, 0x4E, 0x78, 0xFF, 0xFF, 0x01, 0x03, 0xA1, 0xDD, 0xD9, 0x81, 0xFA, 0x60, 0x3E, 0x65,
+	 0x46, 0x60, 0x58, 0x4D, 0x4E, 0x78, 0xFF, 0xFF, 0x01, 0x03, 0xA1, 0xDD, 0xD9, 0x81, 0xFA, 0x60,
+	 0x3F, 0x65, 0x46, 0x60, 0x58, 0x4D, 0x4E, 0x78, 0xFF, 0xFF, 0x01, 0x03, 0xA1, 0xDD, 0xD9, 0x81,
+	 0xFA, 0x60, 0x40, 0x65, 0x46, 0x60, 0x58, 0x4D, 0x4E, 0x78, 0xFF, 0xFF, 0x01, 0x03, 0xA1, 0xDD,
+	 0xD9, 0x81, 0xFA, 0x60, 0x3B, 0x65, 0x46, 0x60, 0x58, 0x4D, 0x4E, 0x78, 0xFF, 0xFF, 0x01, 0x03,
+	 0xA1, 0xDD, 0xFA, 0x60, 0x48, 0x65, 0x46, 0x60, 0x58, 0x4D, 0x4E, 0x78, 0xFF, 0xFF, 0x10, 0x03,
+	 0xBD, 0xD3, 0x2C, 0x60, 0xC4, 0x61, 0x0E, 0xB4, 0xBD, 0xD1, 0xA1, 0xDB, 0x64, 0x47, 0x0E, 0xB4,
+	 0xA3, 0xD1, 0x59, 0xDB, 0x64, 0x44, 0x0E, 0xB4, 0x59, 0xDB, 0x64, 0x47, 0x0E, 0xB4, 0x59, 0xDB,
+	 0xFA, 0x60, 0x29, 0x65, 0x46, 0x60, 0x58, 0x4D, 0x4E, 0x78, 0xFF, 0xFF, 0x07, 0x03, 0x04, 0xA3,
+	 0xA3, 0xD3, 0x20, 0x60, 0x00, 0x65, 0xB4, 0x84, 0x13, 0x60, 0xA6, 0xFB, 0xFA, 0x60, 0x2A, 0x65,
+	 0x46, 0x60, 0x58, 0x4D, 0x4E, 0x78, 0xFF, 0xFF, 0x30, 0x03, 0x04, 0xA3, 0xBD, 0xD1, 0x14, 0x60,
+	 0x4A, 0xF3, 0x64, 0x41, 0x64, 0x5E, 0xA2, 0xDB, 0x64, 0x47, 0x5A, 0xD3, 0x60, 0x5C, 0x64, 0x5F,
+	 0xA2, 0xDB, 0x14, 0x60, 0x60, 0xF3, 0xFF, 0x60, 0xC0, 0xB5, 0x61, 0x40, 0x80, 0x27, 0x05, 0x00,
+	 0xE9, 0x87, 0x3F, 0xB4, 0xB4, 0x84, 0xA2, 0xDB, 0x15, 0x00, 0x65, 0x44, 0xA2, 0xDB, 0xE1, 0x80,
+	 0xF9, 0x87, 0x01, 0x7F, 0x14, 0x60, 0x63, 0xF3, 0x60, 0x41, 0xE0, 0x84, 0xE0, 0x84, 0xE9, 0x81,
+	 0xF8, 0x84, 0xE9, 0x81, 0xF8, 0x84, 0xA2, 0xDB, 0x4A, 0xD3, 0xFF, 0x60, 0x80, 0x65, 0xA4, 0x84,
+	 0x34, 0x94, 0xA2, 0xDB, 0xDB, 0x83, 0x14, 0x60, 0xDF, 0xFD, 0xFA, 0x60, 0x2B, 0x65, 0x46, 0x60,
+	 0x58, 0x4D, 0x4E, 0x78, 0xFF, 0xFF, 0x07, 0x03, 0x04, 0xA3, 0xBD, 0xD3, 0x14, 0x60, 0x4D, 0xFB,
+	 0xA3, 0xD3, 0x14, 0x60, 0x11, 0xFB, 0xFA, 0x60, 0x3C, 0x65, 0x46, 0x60, 0x58, 0x4D, 0x4E, 0x78,
+	 0xFF, 0xFF, 0x1F, 0x03, 0xA3, 0xD3, 0xFC, 0x60, 0xFC, 0x65, 0xA4, 0x84, 0x60, 0x5C, 0x00, 0x7E,
+	 0xC0, 0x60, 0x00, 0xA0, 0x60, 0x43, 0x07, 0x04, 0x14, 0x60, 0x51, 0xF3, 0xFF, 0xFF, 0x03, 0x60,
+	 0xFF, 0xB4, 0x3C, 0x94, 0xA2, 0xDB, 0x28, 0x60, 0x2A, 0x61, 0x64, 0x44, 0x00, 0x7F, 0xC0, 0xA0,
+	 0x60, 0x47, 0x07, 0x04, 0x60, 0x43, 0xA1, 0xD3, 0xFF, 0xFF, 0x03, 0x60, 0xFF, 0xB4, 0x3C, 0x94,
+	 0xA1, 0xDB, 0xFA, 0x60, 0x49, 0x65, 0x46, 0x60, 0x58, 0x4D, 0x4E, 0x78, 0xFF, 0xFF, 0x1B, 0x03,
+	 0x32, 0x60, 0xAB, 0x61, 0x1C, 0x7C, 0x60, 0xFE, 0xA3, 0xD3, 0x5D, 0xD3, 0x0F, 0xB5, 0xD4, 0x84,
+	 0xA1, 0xDB, 0xBD, 0xD3, 0xFF, 0xFF, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0x5D, 0xD3,
+	 0x0F, 0xB5, 0xD4, 0x84, 0xA1, 0xDB, 0x67, 0x44, 0xC0, 0x9C, 0x64, 0x40, 0x00, 0x36, 0x10, 0x00,
+	 0x64, 0x40, 0x0E, 0x3A, 0xE9, 0x01, 0x20, 0xFE, 0xFA, 0x60, 0x4A, 0x65, 0x46, 0x60, 0x58, 0x4D,
+	 0x4E, 0x78, 0xFF, 0xFF, 0x05, 0x03, 0x32, 0x60, 0xC7, 0x61, 0x0E, 0x7C, 0x60, 0xFE, 0xDC, 0x01,
+	 0x20, 0xFE, 0xB8, 0xFE, 0xB9, 0xFE, 0xBA, 0xFE, 0xBB, 0xFE, 0xBD, 0xFE, 0xBF, 0xFE, 0x19, 0x60,
+	 0x48, 0xF3, 0x12, 0x63, 0x60, 0x40, 0x01, 0x27, 0x04, 0x00, 0x0B, 0x60, 0xEA, 0x62, 0x5A, 0xDF,
+	 0xFE, 0x1F, 0x41, 0x60, 0x6B, 0x78, 0xFF, 0xFF, 0x08, 0x60, 0x06, 0x63, 0xBE, 0xD3, 0xBD, 0xD1,
+	 0x07, 0x18, 0xD4, 0x80, 0x05, 0x18, 0x03, 0x03, 0xC3, 0x83, 0xC3, 0x83, 0xF7, 0x01, 0xDB, 0x83,
+	 0x00, 0xBC, 0x2D, 0x58, 0xFF, 0xFF, 0x86, 0xFD, 0xAA, 0x2D, 0x00, 0x00, 0x06, 0x00, 0x10, 0xFD,
+	 0x6E, 0x01, 0x00, 0x00, 0x02, 0x00, 0x14, 0xFD, 0x8E, 0x32, 0x00, 0x00, 0x0A, 0x00, 0x41, 0xFA,
+	 0x40, 0x2A, 0x00, 0x00, 0x22, 0x00, 0x42, 0xFA, 0x62, 0x2A, 0x00, 0x00, 0x22, 0x00, 0x43, 0xFA,
+	 0x84, 0x2A, 0x00, 0x00, 0x22, 0x00, 0x44, 0xFA, 0xA6, 0x2A, 0x00, 0x00, 0x22, 0x00, 0x45, 0xFA,
+	 0xC8, 0x2A, 0x00, 0x00, 0x22, 0x00, 0x25, 0xFD, 0x9E, 0x01, 0x00, 0x00, 0x02, 0x00,
+
+};  /* fw_image_3_data */
+
+static const hcf_8 fw_image_4_data[] = {
+	 0x6C, 0x40, 0xA1, 0xFF, 0x98, 0xFF, 0x80, 0x3E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x41, 0xFF, 0x33, 0xF3, 0x02, 0x11, 0x31, 0x18, 0x1E, 0x00, 0x44, 0xFF, 0x2E, 0x00, 0xFF, 0xFF,
+	 0xC4, 0xE2, 0x27, 0x44, 0x20, 0x2A, 0x01, 0x00, 0xFF, 0xFF, 0x42, 0x64, 0x3A, 0xDB, 0x23, 0x00,
+	 0x41, 0xFF, 0xA2, 0x60, 0x45, 0x78, 0xE2, 0xFE, 0x40, 0x49, 0x02, 0x60, 0x01, 0xE1, 0x1D, 0x00,
+	 0x44, 0xFF, 0x1B, 0x09, 0x29, 0x44, 0x10, 0x2A, 0x04, 0x74, 0xCD, 0xE2, 0x10, 0x65, 0x0B, 0x00,
+	 0xA3, 0x60, 0xC1, 0x78, 0xA4, 0xE2, 0x29, 0x44, 0x20, 0x2A, 0x0D, 0x00, 0x20, 0xAC, 0xEC, 0x01,
+	 0xA3, 0x60, 0xC1, 0x78, 0x46, 0xFF, 0xB4, 0x84, 0x40, 0x49, 0xA1, 0xFF, 0xFF, 0xFF, 0x80, 0x3E,
+	 0xA3, 0x60, 0xC1, 0x78, 0xFF, 0xFF, 0x62, 0xFF, 0x08, 0xE1, 0xA1, 0xFF, 0x98, 0xFF, 0x80, 0x3E,
+	 0xAA, 0x60, 0xA5, 0x78, 0x4C, 0x4E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xAA, 0x60, 0xB3, 0x78, 0x44, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xC4, 0xE2, 0x84, 0xFF, 0x22, 0x58, 0x82, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA4, 0x60, 0x39, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0xE1, 0x01, 0xFF, 0xFF,
+	 0x10, 0x29, 0xFA, 0x01, 0xE4, 0xE2, 0xAA, 0x60, 0x5F, 0x78, 0xB2, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xC1, 0x60, 0xFC, 0x78, 0x64, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xAA, 0x60, 0x46, 0x78, 0xAC, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x80, 0x29, 0xE2, 0x01, 0xAA, 0x60, 0xA2, 0x78, 0x47, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB5, 0x60, 0x5C, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB5, 0x60, 0x94, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB3, 0x60, 0xC9, 0x78, 0x42, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB3, 0x60, 0xFC, 0x78, 0x43, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB3, 0x60, 0xFC, 0x78, 0x44, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB7, 0x60, 0x20, 0x78, 0x45, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB3, 0x60, 0xFF, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x00, 0x60, 0x83, 0x64, 0x80, 0x29, 0x09, 0xFB, 0xB5, 0x60, 0x25, 0x78, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x98, 0xFF, 0x3A, 0x60, 0x18, 0x78, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x39, 0x60, 0x8F, 0x78, 0x98, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xC0, 0x60, 0x67, 0x78, 0x98, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xBF, 0x60, 0xE1, 0x78, 0x98, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xB7, 0x60, 0xE9, 0x78, 0x98, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xA1, 0xFF, 0x98, 0xFF, 0x83, 0x3E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xC3, 0x60, 0x4D, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0x41, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0x42, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0xB0, 0xFF, 0xB1, 0xFF, 0x40, 0xFF, 0x43, 0xFF, 0xC3, 0x60, 0x48, 0x78, 0x44, 0xFF, 0xFF, 0x01,
+	 0xC3, 0x60, 0x4D, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0x3E, 0x60, 0x8C, 0x78, 0x45, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0xC3, 0x60, 0x48, 0x78, 0x84, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0xC3, 0x60, 0x47, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+	 0xCA, 0x60, 0xC8, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xF3, 0x60, 0x9A, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x42, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0x85, 0x3E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xCA, 0x60, 0xD0, 0x78, 0x24, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xF2, 0x60, 0x47, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xCA, 0x60, 0xD0, 0x78, 0x44, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xCA, 0x60, 0xD0, 0x78, 0x84, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xCA, 0x60, 0xD0, 0x78, 0x47, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x29, 0x60, 0xF2, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x2A, 0x60, 0x20, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x2A, 0x60, 0x3E, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x2A, 0x60, 0x1D, 0x78, 0x28, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x2A, 0x60, 0x1D, 0x78, 0x44, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x2A, 0x60, 0x1D, 0x78, 0x45, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x2A, 0x60, 0x1D, 0x78, 0x46, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x00, 0x60, 0x87, 0x64, 0x80, 0x29, 0x09, 0xFB, 0x47, 0xFF, 0x2A, 0x60, 0x1D, 0x78, 0xFF, 0xFF,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x43, 0xF7, 0xA7, 0xFF, 0x41, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x37, 0x60, 0x82, 0x78, 0x42, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x36, 0x60, 0x8F, 0x78, 0x47, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0x41, 0xFF, 0x00, 0x60, 0x03, 0xE1, 0x21, 0x46, 0x66, 0x45, 0x00, 0xF4, 0x2E, 0x44, 0x09, 0xFA,
+	 0x6A, 0x61, 0x7F, 0x60, 0xFE, 0x63, 0xA1, 0xFF, 0x9A, 0xFF, 0x05, 0x11, 0x0A, 0x00, 0x00, 0xF4,
+	 0x01, 0xF2, 0x17, 0x18, 0x7A, 0x61, 0x02, 0x25, 0x04, 0x00, 0x6C, 0x44, 0x7A, 0xDA, 0xFB, 0x1C,
+	 0xF6, 0x11, 0xD9, 0x81, 0x41, 0xFF, 0x02, 0x1C, 0x00, 0xF4, 0xDA, 0x82, 0x41, 0xFF, 0xC9, 0x81,
+	 0xCB, 0x83, 0x6C, 0x44, 0x5A, 0xDA, 0x02, 0x1C, 0x00, 0xF4, 0x81, 0xF2, 0x6C, 0x44, 0x5A, 0xDA,
+	 0xCB, 0x83, 0x02, 0x74, 0x02, 0x60, 0x04, 0xE1, 0x80, 0x60, 0x00, 0x61, 0x5D, 0x93, 0xB5, 0xFF,
+	 0x98, 0xFF, 0x26, 0x44, 0xFD, 0xB4, 0x84, 0xBC, 0x40, 0x46, 0x65, 0x46, 0x00, 0x64, 0x23, 0xFA,
+	 0x3F, 0xFC, 0x63, 0x47, 0x0A, 0x63, 0x0F, 0xFC, 0x00, 0xF4, 0x08, 0xFA, 0xCB, 0xFE, 0x18, 0xE1,
+	 0x44, 0xFF, 0xA1, 0xFF, 0x98, 0xFF, 0x80, 0x3E, 0xE2, 0xFE, 0x03, 0x04, 0xA3, 0x60, 0x05, 0x78,
+	 0xFF, 0xFF, 0xE0, 0xFE, 0x03, 0x04, 0xA3, 0x60, 0x1B, 0x78, 0xFF, 0xFF, 0xE1, 0xFE, 0x07, 0x05,
+	 0x9F, 0xFE, 0x03, 0x04, 0x3A, 0x60, 0x77, 0x78, 0xFF, 0xFF, 0x43, 0xFF, 0xA9, 0x01, 0x95, 0xF3,
+	 0xFF, 0xFF, 0x80, 0xB4, 0xFF, 0xFF, 0x08, 0x24, 0x16, 0x00, 0x29, 0x44, 0x08, 0x26, 0xE1, 0x01,
+	 0x72, 0x44, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xB2, 0xF3, 0xE8, 0x85,
+	 0xFF, 0xB7, 0xE0, 0x84, 0xE0, 0x84, 0xB4, 0x85, 0x73, 0x44, 0xD4, 0x84, 0x10, 0x65, 0xD4, 0x80,
+	 0xFF, 0xFF, 0x01, 0x05, 0x8F, 0x00, 0x80, 0x60, 0x01, 0xE0, 0xD5, 0x60, 0x84, 0xE7, 0xA1, 0xF3,
+	 0x7C, 0x45, 0x60, 0x40, 0x01, 0x23, 0x02, 0x65, 0x8C, 0x60, 0x48, 0x6A, 0xFF, 0xFF, 0x01, 0x16,
+	 0xFE, 0x01, 0x00, 0x60, 0x00, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x00, 0x60, 0x7F, 0x6A,
+	 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x84, 0x60, 0x04, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01,
+	 0x48, 0x60, 0x08, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x65, 0x4A, 0xFF, 0xFF, 0x01, 0x16,
+	 0xFE, 0x01, 0x84, 0x60, 0x04, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x40, 0x60, 0x08, 0x6A,
+	 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x65, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x95, 0x60,
+	 0x84, 0xE7, 0xBD, 0xFE, 0x0C, 0x60, 0x00, 0x62, 0x00, 0x60, 0x71, 0x7C, 0x00, 0x60, 0xB1, 0x65,
+	 0x3D, 0x60, 0x58, 0x4D, 0x0F, 0x78, 0xFF, 0xFF, 0x08, 0xE1, 0x62, 0xFF, 0xA3, 0xFF, 0xFF, 0xFF,
+	 0xA2, 0xFF, 0x02, 0x60, 0x08, 0xE1, 0xAE, 0x4F, 0x02, 0xBC, 0x00, 0x7F, 0xA0, 0x5E, 0x3F, 0x40,
+	 0x40, 0x26, 0x09, 0x00, 0x1C, 0x60, 0x09, 0xF3, 0x5A, 0xD1, 0xA0, 0x50, 0xA4, 0x52, 0x5A, 0xD3,
+	 0x5A, 0xD1, 0xA0, 0x50, 0xA4, 0x50, 0xDB, 0xF3, 0xF1, 0xF1, 0x01, 0xA8, 0x07, 0xA8, 0x0A, 0x03,
+	 0x09, 0x03, 0x64, 0x40, 0x01, 0x26, 0x09, 0x00, 0x1B, 0x60, 0xF3, 0xF3, 0xFF, 0xFF, 0x01, 0xB4,
+	 0xFF, 0xFF, 0x03, 0x02, 0xAD, 0x4F, 0xFA, 0xB4, 0xA0, 0x5D, 0x19, 0x60, 0xF6, 0xF1, 0x89, 0xFF,
+	 0x32, 0x40, 0x80, 0x2A, 0x1E, 0x00, 0x31, 0x40, 0x01, 0x2A, 0x1B, 0x00, 0x12, 0x60, 0xFF, 0xF3,
+	 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x05, 0x03, 0x0E, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x2A,
+	 0x10, 0x00, 0x13, 0x60, 0x02, 0xF3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x03, 0x03, 0x0F, 0xF2,
+	 0xFF, 0xFF, 0x07, 0x1B, 0x64, 0x40, 0x01, 0x26, 0x03, 0x00, 0x08, 0x60, 0x00, 0x75, 0x01, 0x00,
+	 0x10, 0xFF, 0x88, 0xFF, 0xA2, 0x60, 0x41, 0x78, 0xFF, 0xFF, 0x21, 0x46, 0x01, 0x5D, 0x5C, 0x62,
+	 0x03, 0xE1, 0x44, 0xFF, 0xA1, 0xFF, 0x9A, 0xFF, 0x7A, 0xDC, 0x7A, 0xDC, 0x7A, 0xDC, 0x62, 0x62,
+	 0x7A, 0xDC, 0x7A, 0xDC, 0x7A, 0xDC, 0xA1, 0xFF, 0x5A, 0xDC, 0x12, 0xE1, 0x02, 0x60, 0x01, 0xE1,
+	 0xA1, 0xFF, 0x98, 0xFF, 0x80, 0x3E, 0x28, 0x40, 0x40, 0x2B, 0x03, 0x00, 0x29, 0x40, 0x20, 0x27,
+	 0xA3, 0x00, 0xC8, 0x74, 0xCD, 0xE2, 0x29, 0x44, 0x08, 0xBC, 0x40, 0x49, 0x44, 0xFF, 0x05, 0xE1,
+	 0xDB, 0xF3, 0x37, 0x60, 0xE8, 0x63, 0x03, 0xA8, 0x04, 0xA8, 0x06, 0x03, 0x05, 0x03, 0xA3, 0xD3,
+	 0xFF, 0xFF, 0x01, 0xA8, 0x07, 0x18, 0x0A, 0x03, 0x28, 0x40, 0x08, 0x2A, 0x07, 0x00, 0x28, 0x40,
+	 0x48, 0x36, 0x04, 0x00, 0xF1, 0xF3, 0xFF, 0xFF, 0x02, 0xBC, 0xF1, 0xFB, 0x29, 0x44, 0xFF, 0x60,
+	 0xEF, 0x65, 0x24, 0x89, 0x40, 0x27, 0x3F, 0x00, 0x00, 0x00, 0x29, 0x40, 0x80, 0x27, 0x0B, 0x00,
+	 0x07, 0x61, 0xA1, 0xFF, 0xCD, 0x81, 0x04, 0x25, 0x61, 0x00, 0x87, 0x4C, 0xFB, 0x02, 0xF3, 0x60,
+	 0xA0, 0x64, 0x80, 0x4C, 0x07, 0x00, 0xA1, 0xFF, 0x9C, 0x4C, 0x9C, 0x4C, 0x9C, 0x4D, 0x05, 0x60,
+	 0xCF, 0x64, 0x80, 0x4C, 0x28, 0x40, 0x40, 0x2B, 0x05, 0x00, 0x29, 0x40, 0x20, 0x27, 0x02, 0x00,
+	 0x15, 0x60, 0x6F, 0x6B, 0x04, 0x25, 0x4A, 0x00, 0x30, 0x64, 0x3A, 0xDB, 0x44, 0xFF, 0x04, 0x25,
+	 0x45, 0x00, 0x04, 0x60, 0x00, 0x65, 0x25, 0x44, 0xB4, 0x84, 0x80, 0x4E, 0x2D, 0x41, 0x04, 0x25,
+	 0x3D, 0x00, 0x61, 0x4C, 0x00, 0x60, 0x8A, 0x65, 0xC5, 0x81, 0x61, 0x54, 0xA1, 0xFF, 0xFF, 0xFF,
+	 0x04, 0x25, 0x34, 0x00, 0x67, 0x4E, 0x07, 0x64, 0x1C, 0xFB, 0x00, 0xE1, 0x02, 0x60, 0x05, 0xE1,
+	 0xA1, 0xFF, 0x98, 0xFF, 0x80, 0x3E, 0x28, 0x40, 0x40, 0x27, 0x0A, 0x00, 0x1C, 0x65, 0x28, 0x40,
+	 0xA4, 0x36, 0x14, 0x65, 0x23, 0x44, 0xC4, 0x84, 0x28, 0x40, 0x08, 0x2A, 0x0C, 0x00, 0x07, 0x00,
+	 0x23, 0x44, 0x1C, 0xA4, 0x29, 0x40, 0x20, 0x27, 0x02, 0x00, 0x11, 0x60, 0x0F, 0x6B, 0x3C, 0x46,
+	 0x98, 0xF0, 0x23, 0x44, 0xC4, 0x84, 0x06, 0x74, 0x25, 0x5C, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84,
+	 0xE0, 0x84, 0xB0, 0x84, 0x80, 0x4C, 0x9C, 0x4C, 0x44, 0xFF, 0x18, 0xE1, 0x0A, 0x64, 0x1E, 0x74,
+	 0x02, 0x60, 0x05, 0xE1, 0x40, 0x40, 0xA1, 0xFF, 0x98, 0xFF, 0x80, 0x3E, 0xC4, 0xE2, 0x27, 0x44,
+	 0x20, 0x2A, 0x06, 0x00, 0x42, 0x64, 0x3A, 0xDB, 0x67, 0x4C, 0xB1, 0x60, 0xAD, 0x78, 0xFF, 0xFF,
+	 0x41, 0x64, 0x3A, 0xDB, 0x62, 0xFF, 0x08, 0xE1, 0xE2, 0xFE, 0x72, 0x52, 0xA1, 0xFF, 0x98, 0xFF,
+	 0x80, 0x3E, 0xA1, 0xFF, 0x98, 0xFF, 0x80, 0x3E, 0x28, 0x40, 0x08, 0x27, 0x5A, 0x01, 0x3C, 0x46,
+	 0x8B, 0xFF, 0x84, 0x60, 0x00, 0xE4, 0x0F, 0x60, 0x90, 0x64, 0xC9, 0x60, 0x58, 0x4F, 0x56, 0x78,
+	 0xFF, 0xFF, 0x3F, 0xF2, 0x00, 0x60, 0x18, 0x70, 0x18, 0x71, 0x20, 0x72, 0x00, 0xF2, 0x60, 0x53,
+	 0x20, 0xE1, 0xA1, 0xFF, 0x88, 0x75, 0x00, 0xE1, 0xFF, 0xFF, 0x60, 0x50, 0x75, 0x44, 0x12, 0x71,
+	 0x6E, 0x72, 0x81, 0x75, 0xFF, 0xFF, 0x88, 0xFF, 0xA3, 0x60, 0x21, 0x78, 0xFF, 0xFF, 0x32, 0xF3,
+	 0x08, 0x29, 0x0A, 0x00, 0x60, 0x40, 0x07, 0x22, 0x07, 0x00, 0xFE, 0xB4, 0x32, 0xFB, 0x27, 0x44,
+	 0x10, 0xBC, 0xF7, 0xB4, 0x40, 0x47, 0x43, 0xFF, 0x00, 0x64, 0x3A, 0xDB, 0x01, 0x60, 0x08, 0xE1,
+	 0x31, 0x40, 0x01, 0x2A, 0x06, 0x00, 0x00, 0x64, 0x33, 0xFB, 0x01, 0x60, 0x0A, 0xE1, 0x25, 0x11,
+	 0x24, 0x0A, 0xE5, 0xFE, 0x2D, 0x05, 0x32, 0x40, 0x80, 0x2A, 0x05, 0x00, 0x19, 0x60, 0xF2, 0xF3,
+	 0xFF, 0xFF, 0x01, 0x18, 0x16, 0x00, 0x9F, 0xFE, 0x14, 0x05, 0x9D, 0xFE, 0x12, 0x04, 0x31, 0x41,
+	 0x40, 0x2A, 0x0F, 0x00, 0x07, 0x60, 0xE9, 0xF1, 0xAE, 0x4C, 0x90, 0x80, 0x10, 0x2A, 0x09, 0x00,
+	 0x7F, 0xB1, 0x07, 0x60, 0xE9, 0xFB, 0x60, 0x40, 0x10, 0x2A, 0x80, 0xB9, 0x41, 0x51, 0xDF, 0xFE,
+	 0x19, 0xFF, 0x9F, 0xFE, 0x02, 0x04, 0x40, 0xE1, 0x08, 0x00, 0x7C, 0xE1, 0x31, 0x44, 0x01, 0x2A,
+	 0x04, 0x00, 0xFD, 0xE1, 0x27, 0x44, 0x10, 0x26, 0x06, 0x00, 0xA1, 0xFF, 0xFF, 0xFF, 0x81, 0x3E,
+	 0xAA, 0x60, 0x6F, 0x78, 0xFF, 0xFF, 0x27, 0x44, 0x08, 0x26, 0xFF, 0xFF, 0xC1, 0x60, 0xA3, 0x78,
+	 0xFF, 0xFF, 0x48, 0xF3, 0x32, 0xF1, 0x00, 0x63, 0x64, 0x40, 0x07, 0x26, 0x03, 0x00, 0xA5, 0x60,
+	 0x0F, 0x78, 0xFF, 0xFF, 0x43, 0xFF, 0x31, 0x40, 0x08, 0x26, 0xF0, 0x01, 0xCD, 0xE2, 0x85, 0xE1,
+	 0x70, 0x41, 0xAD, 0x80, 0x71, 0x40, 0x80, 0x27, 0xE9, 0x12, 0x03, 0x03, 0xC2, 0x60, 0x15, 0x78,
+	 0xFF, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0xC4, 0xE2, 0x32, 0xFD, 0x60, 0x40, 0x01, 0x2A, 0xDB, 0x01,
+	 0x00, 0x63, 0x32, 0xFD, 0x3C, 0x46, 0x3E, 0xF2, 0x2A, 0xF0, 0x27, 0x41, 0x44, 0x48, 0x20, 0xB9,
+	 0x01, 0xB4, 0xF7, 0xB1, 0x0A, 0x03, 0x64, 0x40, 0x08, 0x27, 0x07, 0x00, 0x0F, 0x60, 0xDA, 0x63,
+	 0x00, 0x64, 0x45, 0xFB, 0x46, 0xFB, 0xBD, 0xDB, 0xA3, 0xDB, 0xC8, 0x0A, 0xC7, 0x11, 0x1B, 0x60,
+	 0xEE, 0xF3, 0xFF, 0xFF, 0x14, 0x18, 0x28, 0x40, 0xD4, 0x36, 0x11, 0x00, 0xAC, 0x4C, 0x80, 0x2A,
+	 0x0E, 0x00, 0x1B, 0x60, 0xF1, 0xF3, 0xFF, 0xFF, 0x0A, 0x18, 0x1B, 0x60, 0xF2, 0xF3, 0x1B, 0x60,
+	 0xEF, 0xF3, 0x60, 0x45, 0xD4, 0x80, 0xDC, 0x84, 0x02, 0x03, 0xA2, 0xDB, 0xAF, 0x01, 0x00, 0x64,
+	 0x1B, 0x60, 0xEF, 0xFB, 0x41, 0x47, 0x22, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x10, 0x26, 0x04, 0x00,
+	 0x01, 0x2A, 0x05, 0x00, 0x10, 0x2B, 0x03, 0x00, 0x29, 0x47, 0x20, 0xBF, 0x40, 0x49, 0x1B, 0x60,
+	 0xEE, 0xF3, 0xFF, 0xFF, 0x04, 0x18, 0xAE, 0x4F, 0x08, 0xBC, 0x00, 0x7F, 0xA0, 0x5E, 0x05, 0xE1,
+	 0x01, 0x60, 0x08, 0xE1, 0x2A, 0xE8, 0x3C, 0x46, 0x0F, 0xF0, 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x2A,
+	 0x03, 0x00, 0xA7, 0x60, 0xE1, 0x78, 0xFF, 0xFF, 0x7D, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x27,
+	 0x0E, 0x00, 0x1F, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x40, 0x2B, 0x09, 0x00, 0x19, 0x60, 0x7B, 0xF3,
+	 0xFF, 0xFF, 0x60, 0x40, 0x02, 0x2A, 0x03, 0x00, 0xA8, 0x60, 0xEC, 0x78, 0xFF, 0xFF, 0x1F, 0xF2,
+	 0xC0, 0x60, 0x00, 0x65, 0xA4, 0x9C, 0x3F, 0x60, 0xCF, 0x65, 0x29, 0x44, 0xA4, 0x84, 0x30, 0x89,
+	 0x19, 0x60, 0x77, 0xF3, 0xFF, 0xFF, 0x19, 0x60, 0x55, 0xFB, 0x1F, 0xF2, 0x39, 0xF1, 0xE0, 0x60,
+	 0xFF, 0xB5, 0x0A, 0x18, 0x60, 0x47, 0x1F, 0xB4, 0xD0, 0x84, 0xE0, 0xA0, 0x02, 0x0D, 0x00, 0x64,
+	 0x02, 0x00, 0x01, 0x04, 0x1F, 0x64, 0x60, 0x47, 0xB4, 0x81, 0x07, 0x60, 0xEA, 0xF1, 0xFF, 0xFF,
+	 0xB1, 0x8C, 0x29, 0x40, 0x40, 0x2B, 0x10, 0x00, 0x29, 0x60, 0xC0, 0x65, 0x60, 0x47, 0x1F, 0xB4,
+	 0xE0, 0x84, 0xE0, 0x84, 0x44, 0xD3, 0x5A, 0xD1, 0x01, 0x60, 0x00, 0xE1, 0x01, 0x60, 0x09, 0x6B,
+	 0x60, 0x4C, 0xB5, 0xFF, 0x64, 0x4C, 0x14, 0x00, 0x29, 0x60, 0xC0, 0x65, 0x60, 0x47, 0x1F, 0xB4,
+	 0xE0, 0x84, 0xE0, 0x84, 0x44, 0xD3, 0x5A, 0xD1, 0x01, 0x60, 0x00, 0xE1, 0x05, 0x60, 0x69, 0x6B,
+	 0x60, 0x4C, 0xB5, 0xFF, 0x64, 0x4C, 0x7C, 0x44, 0x29, 0x40, 0x80, 0x2B, 0x67, 0x44, 0x60, 0x4C,
+	 0x00, 0xE1, 0x84, 0xFF, 0xC2, 0x60, 0x45, 0x64, 0x40, 0x42, 0x82, 0xFF, 0x0D, 0x00, 0xE5, 0xFE,
+	 0x03, 0x04, 0xAA, 0x60, 0x6F, 0x78, 0xFF, 0xFF, 0x32, 0xF1, 0xFF, 0xFF, 0x64, 0x40, 0x07, 0x22,
+	 0x43, 0xFF, 0xA3, 0x60, 0xF4, 0x78, 0xFF, 0xFF, 0x0B, 0x64, 0x3A, 0xDB, 0x01, 0x60, 0x0A, 0xE1,
+	 0x1C, 0x42, 0x22, 0x46, 0x13, 0xF2, 0xFF, 0x65, 0x60, 0x47, 0x2A, 0xF2, 0x40, 0x45, 0x40, 0x48,
+	 0x04, 0x2B, 0x13, 0x00, 0x16, 0xF2, 0x1D, 0xF2, 0x40, 0x43, 0x0F, 0xF2, 0x40, 0x4D, 0x0F, 0x64,
+	 0x14, 0xF0, 0x35, 0xF2, 0xA0, 0x82, 0x0F, 0xB4, 0xCA, 0x85, 0xD4, 0x80, 0x10, 0xF2, 0x01, 0x02,
+	 0x2B, 0xFA, 0x27, 0x44, 0x40, 0xBC, 0x40, 0x47, 0x13, 0x00, 0x17, 0xF2, 0x2C, 0xF0, 0x40, 0x43,
+	 0x1B, 0xF2, 0x1D, 0xFA, 0x40, 0x4D, 0x64, 0x40, 0x01, 0x2A, 0x02, 0x00, 0xAB, 0xFC, 0x05, 0x00,
+	 0x28, 0x40, 0xA4, 0x36, 0x02, 0x00, 0x11, 0xF2, 0x2B, 0xFA, 0x27, 0x44, 0xBF, 0xB4, 0x40, 0x47,
+	 0xF0, 0xFE, 0xB0, 0x60, 0xB0, 0x78, 0xFF, 0xFF, 0x22, 0x46, 0x2C, 0xF0, 0x27, 0x44, 0xDF, 0xB4,
+	 0x40, 0x47, 0x64, 0x40, 0x01, 0x26, 0x09, 0x00, 0x2A, 0xF2, 0x39, 0xF0, 0x8F, 0xB0, 0x88, 0x3A,
+	 0x0D, 0x00, 0x64, 0x44, 0x60, 0xB0, 0x20, 0x3A, 0x09, 0x00, 0x28, 0x44, 0x04, 0x27, 0x05, 0x00,
+	 0xD4, 0x3A, 0x03, 0x00, 0xAE, 0x4F, 0xF7, 0xB4, 0xA0, 0x5E, 0x11, 0x00, 0x2A, 0xF0, 0x01, 0x65,
+	 0x64, 0x40, 0xA4, 0x3A, 0x04, 0x65, 0x27, 0x44, 0x34, 0x87, 0x36, 0xF3, 0xFF, 0xFF, 0x60, 0x56,
+	 0xAD, 0xE2, 0x04, 0x64, 0x3A, 0xDB, 0x41, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x81, 0x3E, 0x06, 0x64,
+	 0x3A, 0xDB, 0x22, 0x46, 0x01, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0xC2, 0x60, 0x1E, 0x78, 0xFF, 0xFF,
+	 0x28, 0x40, 0xC4, 0x3A, 0x0C, 0x00, 0x27, 0x44, 0xFD, 0xB4, 0x40, 0x47, 0xA8, 0xE2, 0x05, 0xE1,
+	 0x01, 0x60, 0x08, 0xE1, 0x2A, 0xE8, 0x3C, 0x46, 0xA4, 0x60, 0xBF, 0x78, 0xFF, 0xFF, 0x3F, 0x40,
+	 0x01, 0x2B, 0x05, 0x00, 0x67, 0x4C, 0x01, 0x60, 0x00, 0xE1, 0x05, 0x60, 0x69, 0x6B, 0x07, 0x60,
+	 0xEB, 0xF1, 0x1F, 0xF2, 0x2A, 0xE8, 0xB0, 0x81, 0x29, 0x40, 0x40, 0x2B, 0x14, 0x00, 0x61, 0x4C,
+	 0x29, 0x60, 0xC0, 0x65, 0x61, 0x47, 0x1F, 0xB4, 0xE0, 0x84, 0xE0, 0x84, 0x44, 0xD3, 0x5A, 0xD1,
+	 0x01, 0x60, 0x00, 0xE1, 0x01, 0x60, 0x09, 0x6B, 0x60, 0x4C, 0xB5, 0xFF, 0xFF, 0x60, 0xF2, 0x64,
+	 0x64, 0x4C, 0x40, 0x43, 0x18, 0x00, 0x29, 0x47, 0x80, 0xB7, 0x34, 0x94, 0x60, 0x4C, 0x29, 0x60,
+	 0xC0, 0x65, 0x61, 0x47, 0x1F, 0xB4, 0xE0, 0x84, 0xE0, 0x84, 0x44, 0xD3, 0x5A, 0xD1, 0x01, 0x60,
+	 0x00, 0xE1, 0x05, 0x60, 0x69, 0x6B, 0x60, 0x4C, 0xB5, 0xFF, 0x64, 0x4C, 0x7C, 0x44, 0x29, 0x40,
+	 0x80, 0x2B, 0x67, 0x44, 0x60, 0x4C, 0x40, 0xE1, 0x01, 0x60, 0x08, 0xE1, 0x28, 0x45, 0xBF, 0x60,
+	 0xFF, 0x64, 0x24, 0x88, 0xC4, 0xE2, 0x08, 0x64, 0x3A, 0xDB, 0x21, 0x46, 0x2A, 0x44, 0x72, 0x45,
+	 0x24, 0xFA, 0xB2, 0xF3, 0x06, 0x04, 0xE4, 0xE2, 0xDC, 0x9C, 0x29, 0x40, 0x01, 0x26, 0x64, 0x44,
+	 0xB2, 0xF9, 0x25, 0xFA, 0xB3, 0xF3, 0x02, 0x04, 0xDC, 0x84, 0xB3, 0xFB, 0x28, 0xFA, 0xB4, 0xF3,
+	 0x02, 0x04, 0xDC, 0x84, 0xB4, 0xFB, 0x29, 0xFA, 0x24, 0x44, 0x04, 0x2A, 0x06, 0x00, 0x28, 0x40,
+	 0xA4, 0x36, 0x03, 0x00, 0xA6, 0x60, 0xB1, 0x78, 0xFF, 0xFF, 0x26, 0x43, 0x84, 0xBB, 0xFC, 0xB3,
+	 0x21, 0x46, 0x01, 0x5D, 0x0F, 0xFC, 0x5C, 0x46, 0x05, 0xFF, 0x27, 0x44, 0x01, 0x2A, 0x13, 0x00,
+	 0x50, 0xFE, 0x28, 0x40, 0x08, 0x3A, 0x12, 0x00, 0x2F, 0xF2, 0x30, 0xF0, 0x60, 0x43, 0x31, 0xF2,
+	 0x22, 0x46, 0x64, 0x41, 0x2C, 0xF0, 0x2D, 0xF0, 0xD3, 0x80, 0x2E, 0xF0, 0xD1, 0x80, 0xD0, 0x80,
+	 0x27, 0x44, 0x09, 0x0C, 0x03, 0x00, 0x27, 0x44, 0x06, 0x22, 0x05, 0x00, 0xB8, 0xB4, 0x40, 0x47,
+	 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0xD4, 0x64, 0x40, 0x48, 0x0D, 0x64, 0x3A, 0xDB, 0x7C, 0x44,
+	 0x1B, 0x60, 0xF0, 0xFB, 0x21, 0x46, 0x1C, 0xF2, 0x00, 0xE1, 0xF0, 0xFE, 0x00, 0x63, 0x28, 0x44,
+	 0xA4, 0x36, 0x0A, 0x00, 0x04, 0x2B, 0x08, 0x00, 0x30, 0xF3, 0x2D, 0x45, 0xD4, 0x84, 0xCA, 0x65,
+	 0xD4, 0x83, 0x01, 0x64, 0x1B, 0x60, 0xF0, 0xFB, 0xD4, 0x64, 0x35, 0x00, 0x0F, 0x64, 0x3A, 0xDB,
+	 0x21, 0x46, 0x29, 0x40, 0x40, 0x27, 0x15, 0x00, 0x80, 0x27, 0x02, 0x00, 0xCA, 0x65, 0x01, 0x00,
+	 0x6A, 0x65, 0x1C, 0xF2, 0xFF, 0xFF, 0x04, 0x7F, 0x40, 0x45, 0x0A, 0x36, 0x70, 0x64, 0x14, 0x36,
+	 0x38, 0x64, 0x37, 0x36, 0x15, 0x64, 0x6E, 0x3A, 0x17, 0x00, 0x84, 0x7F, 0x40, 0x45, 0x0B, 0x64,
+	 0x13, 0x00, 0x1C, 0xF2, 0x1E, 0x65, 0x40, 0x45, 0x0B, 0x36, 0x1E, 0x64, 0x0F, 0x36, 0x16, 0x64,
+	 0x0A, 0x36, 0x12, 0x64, 0x0E, 0x36, 0x0E, 0x64, 0x09, 0x36, 0x0E, 0x64, 0x0D, 0x36, 0x0A, 0x64,
+	 0x08, 0x36, 0x0A, 0x64, 0x0C, 0x36, 0x0A, 0x64, 0x40, 0x4D, 0x00, 0xE1, 0xF0, 0xFE, 0x2B, 0xF2,
+	 0xC4, 0x85, 0xD4, 0x83, 0xC4, 0x64, 0x40, 0x48, 0x2F, 0xF0, 0xB0, 0xF0, 0xB1, 0xF2, 0xA1, 0xFF,
+	 0x12, 0x74, 0xCD, 0xE2, 0x80, 0x4E, 0x12, 0x74, 0x83, 0x4C, 0x12, 0x74, 0x9A, 0xFF, 0x84, 0x4C,
+	 0x12, 0x74, 0x85, 0x4C, 0x12, 0x74, 0x81, 0x4C, 0x12, 0x74, 0xA1, 0xFF, 0x98, 0xFF, 0xB2, 0x60,
+	 0x58, 0x4F, 0x2D, 0x78, 0xFF, 0xFF, 0x01, 0x60, 0x18, 0xE1, 0x78, 0x44, 0x03, 0xA4, 0x35, 0xFB,
+	 0xB2, 0x60, 0x70, 0x78, 0xFF, 0xFF, 0x29, 0x44, 0xF7, 0xB4, 0x40, 0x49, 0x28, 0x40, 0xC4, 0x36,
+	 0x07, 0x00, 0x1B, 0x60, 0xF0, 0xF3, 0xFF, 0xFF, 0x03, 0x1B, 0xAE, 0x4F, 0xF7, 0xB4, 0xA0, 0x5E,
+	 0x27, 0x44, 0x01, 0x2A, 0x05, 0x00, 0xFE, 0xB4, 0x40, 0x47, 0xA5, 0x60, 0x7F, 0x78, 0xFF, 0xFF,
+	 0x16, 0x60, 0xAB, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x02, 0x36, 0xC1, 0xFE, 0xA3, 0x60, 0xE7, 0x78,
+	 0xFF, 0xFF, 0x28, 0x40, 0xB4, 0x3A, 0x0B, 0x00, 0x27, 0x44, 0x07, 0x22, 0x05, 0x00, 0xF8, 0xB4,
+	 0x40, 0x47, 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0xA6, 0x60, 0x3E, 0x78, 0xFF, 0xFF, 0x28, 0x44,
+	 0xD4, 0x36, 0x03, 0x00, 0xA7, 0x60, 0xC8, 0x78, 0xFF, 0xFF, 0xA8, 0xE2, 0x27, 0x44, 0xFB, 0xB4,
+	 0x40, 0x47, 0x1C, 0x42, 0x22, 0x46, 0x19, 0x60, 0xCF, 0xF3, 0xFF, 0xFF, 0x34, 0xFB, 0x2A, 0xF0,
+	 0xF7, 0x60, 0xFF, 0x64, 0xA0, 0x84, 0xA2, 0xDA, 0x60, 0x40, 0x40, 0x2B, 0xC4, 0x00, 0x22, 0xF2,
+	 0xFF, 0xFF, 0x60, 0x40, 0x22, 0x26, 0x3F, 0x00, 0x01, 0x26, 0x03, 0x00, 0x04, 0x26, 0x05, 0x00,
+	 0xBA, 0x00, 0x04, 0x2B, 0xB8, 0x00, 0xA6, 0xF5, 0x01, 0x00, 0x07, 0xF4, 0x4B, 0xF2, 0xFF, 0xFF,
+	 0xDC, 0x84, 0x4B, 0xFA, 0x0C, 0x60, 0xFC, 0x62, 0x80, 0xFF, 0xC8, 0x60, 0x78, 0x44, 0x02, 0xA4,
+	 0xA2, 0xDB, 0x8C, 0x78, 0xFF, 0xFF, 0x82, 0xFF, 0xA6, 0xF3, 0x66, 0x5C, 0xD0, 0x80, 0x00, 0x7C,
+	 0x07, 0x03, 0x66, 0x43, 0x22, 0x46, 0x22, 0xF2, 0x63, 0x46, 0x60, 0x40, 0x01, 0x2A, 0x01, 0x00,
+	 0x3C, 0xF1, 0x4B, 0xF0, 0x64, 0x41, 0x64, 0x47, 0x60, 0x5F, 0x20, 0xBC, 0x80, 0x26, 0x80, 0xAC,
+	 0x60, 0x47, 0x22, 0x46, 0x3A, 0xFA, 0x64, 0x44, 0x20, 0x7F, 0x34, 0x94, 0x3B, 0xFA, 0x08, 0x60,
+	 0x00, 0xEA, 0x0F, 0x64, 0x60, 0x7F, 0xA0, 0x5A, 0x80, 0x60, 0x00, 0xEA, 0xA0, 0x60, 0x00, 0xEA,
+	 0xD1, 0x60, 0x00, 0xEA, 0x80, 0x00, 0x2A, 0xF2, 0x00, 0x60, 0x7C, 0x62, 0x60, 0x40, 0x40, 0x2B,
+	 0x24, 0x00, 0xA2, 0xD3, 0x00, 0x61, 0x60, 0xFE, 0xA0, 0xD3, 0x5E, 0xD1, 0xFF, 0xFF, 0x20, 0xFE,
+	 0x64, 0x5F, 0xDC, 0x84, 0xF1, 0x81, 0xC0, 0x2B, 0x04, 0x00, 0x80, 0x2A, 0x02, 0x00, 0x7F, 0xA4,
+	 0xDC, 0x84, 0xFF, 0x3B, 0x03, 0x00, 0x60, 0x47, 0xDC, 0x87, 0x01, 0x61, 0xC0, 0x80, 0x00, 0x36,
+	 0xDC, 0x84, 0x4E, 0xDB, 0x60, 0xFE, 0x5A, 0xD1, 0xFF, 0xFF, 0xC1, 0x84, 0xF0, 0x22, 0x10, 0xA4,
+	 0xF0, 0x2A, 0x01, 0x00, 0x00, 0x64, 0xA2, 0xDB, 0x20, 0xFE, 0x00, 0x60, 0x3E, 0xF3, 0xFF, 0xFF,
+	 0xA0, 0xD3, 0x5A, 0xD1, 0x3A, 0xFA, 0x3B, 0xF8, 0x74, 0x62, 0xA2, 0xD0, 0xFF, 0xFF, 0x64, 0x44,
+	 0xE0, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xE1, 0x7F, 0x5A, 0xD0, 0xA0, 0x5A, 0x64, 0x44, 0xE2, 0x7F,
+	 0xA0, 0x5A, 0x00, 0x60, 0x40, 0xF3, 0xFF, 0xFF, 0xA0, 0xD1, 0x5A, 0xD1, 0x64, 0x45, 0x64, 0x44,
+	 0xE3, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xE4, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xE5, 0x7F,
+	 0xA0, 0x5A, 0x64, 0x47, 0xE6, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xE7, 0x7F, 0xA0, 0x5A,
+	 0x65, 0x40, 0x0D, 0x3A, 0x1C, 0x00, 0x64, 0x47, 0xE8, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44,
+	 0xE9, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xEA, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xEB, 0x7F,
+	 0xA0, 0x5A, 0x64, 0x47, 0xEC, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xED, 0x7F, 0xA0, 0x5A,
+	 0x64, 0x47, 0xEE, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xEF, 0x7F, 0xA0, 0x5A, 0x08, 0x60,
+	 0x00, 0xEA, 0x65, 0x44, 0x02, 0xA4, 0x60, 0x7F, 0xA0, 0x5A, 0x80, 0x60, 0x00, 0xEA, 0xA0, 0x60,
+	 0x00, 0xEA, 0xD1, 0x60, 0x00, 0xEA, 0x0B, 0xF2, 0xFF, 0xFF, 0x7F, 0xB4, 0x0C, 0xF0, 0x04, 0x02,
+	 0x64, 0x46, 0x00, 0xF0, 0x04, 0x64, 0x22, 0x46, 0x03, 0xFA, 0x60, 0x41, 0x64, 0x46, 0x01, 0xF2,
+	 0xFC, 0xA1, 0x61, 0x45, 0xD4, 0x84, 0xFF, 0xFF, 0x08, 0x02, 0x00, 0xF0, 0x04, 0x63, 0x64, 0x46,
+	 0x01, 0xF2, 0x22, 0x46, 0x1A, 0xFA, 0x03, 0xFC, 0x02, 0x00, 0x22, 0x46, 0x1A, 0xFA, 0x35, 0xF2,
+	 0x04, 0xF8, 0xDC, 0x84, 0x35, 0xFA, 0x14, 0xF2, 0x0F, 0xB5, 0x0F, 0xB4, 0xCC, 0x84, 0x94, 0x80,
+	 0x04, 0x60, 0x00, 0x65, 0x2A, 0xF2, 0x01, 0x02, 0x94, 0x84, 0x2A, 0xFA, 0x95, 0xFC, 0x06, 0x00,
+	 0xC4, 0x3A, 0x07, 0x00, 0x27, 0x44, 0xFD, 0xB4, 0x40, 0x47, 0xA8, 0xE2, 0xA5, 0x60, 0x1C, 0x78,
+	 0xFF, 0xFF, 0x28, 0x44, 0x04, 0x26, 0x05, 0x00, 0x68, 0x3A, 0x03, 0x00, 0x32, 0x44, 0x00, 0x27,
+	 0x03, 0x00, 0xA3, 0x60, 0xF4, 0x78, 0xFF, 0xFF, 0x0A, 0x64, 0x3A, 0xDB, 0xA3, 0x60, 0xF4, 0x78,
+	 0xFF, 0xFF, 0x0E, 0x64, 0x3A, 0xDB, 0x3C, 0x44, 0x60, 0x46, 0x1E, 0xF0, 0x40, 0x42, 0x64, 0x40,
+	 0x40, 0x27, 0x48, 0x00, 0x1F, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x40, 0x27, 0x3C, 0x00, 0x80, 0x2B,
+	 0x0B, 0x00, 0xBF, 0x60, 0xFF, 0x65, 0x29, 0x44, 0x24, 0x89, 0x80, 0x60, 0x00, 0x65, 0x29, 0x44,
+	 0x34, 0x89, 0x80, 0x60, 0x00, 0x63, 0x05, 0x00, 0x3F, 0x60, 0xFF, 0x65, 0x29, 0x44, 0x24, 0x89,
+	 0x00, 0x63, 0x1E, 0xF2, 0x39, 0xF1, 0xC0, 0x60, 0xFF, 0xB5, 0x0A, 0x18, 0x60, 0x47, 0x1F, 0xB4,
+	 0xD0, 0x84, 0xE0, 0xA0, 0x02, 0x0D, 0x00, 0x64, 0x02, 0x00, 0x01, 0x04, 0x1F, 0x64, 0x60, 0x47,
+	 0xB4, 0x84, 0x07, 0x60, 0xEA, 0xF1, 0x3C, 0x94, 0xB0, 0x84, 0x60, 0x4C, 0x29, 0x60, 0xC0, 0x65,
+	 0x60, 0x47, 0x1F, 0xB4, 0xE0, 0x84, 0xE0, 0x84, 0x44, 0xD3, 0x5A, 0xD1, 0x01, 0x60, 0x00, 0xE1,
+	 0x05, 0x60, 0x69, 0x6B, 0x60, 0x4C, 0xB5, 0xFF, 0x64, 0x4C, 0x7C, 0x44, 0x29, 0x40, 0x80, 0x2B,
+	 0x67, 0x44, 0x60, 0x4C, 0x32, 0x00, 0x19, 0x60, 0x7B, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x04, 0x26,
+	 0xCB, 0x01, 0xBF, 0x01, 0x40, 0x60, 0x00, 0x65, 0x29, 0x44, 0x34, 0x89, 0x40, 0x60, 0x00, 0x63,
+	 0x9F, 0xF2, 0x1E, 0xF2, 0x39, 0xF1, 0xC0, 0x60, 0xFF, 0xB5, 0x0A, 0x18, 0x60, 0x47, 0x1F, 0xB4,
+	 0xD0, 0x84, 0xE0, 0xA0, 0x02, 0x0D, 0x00, 0x64, 0x02, 0x00, 0x01, 0x04, 0x1F, 0x64, 0x60, 0x47,
+	 0xB4, 0x84, 0x07, 0x60, 0xEA, 0xF1, 0x3C, 0x94, 0xB0, 0x81, 0x61, 0x4C, 0x29, 0x60, 0xC0, 0x65,
+	 0x61, 0x47, 0x1F, 0xB4, 0xE0, 0x84, 0xE0, 0x84, 0x44, 0xD3, 0x5A, 0xD1, 0x01, 0x60, 0x00, 0xE1,
+	 0x01, 0x60, 0x09, 0x6B, 0x60, 0x4C, 0xB5, 0xFF, 0x64, 0x4C, 0x40, 0xE1, 0x01, 0x60, 0x08, 0xE1,
+	 0x84, 0xFF, 0xC2, 0x60, 0x45, 0x64, 0x40, 0x42, 0x82, 0xFF, 0x2A, 0xF2, 0x10, 0x60, 0x00, 0x65,
+	 0xA4, 0x84, 0xB4, 0xBC, 0x1E, 0xF0, 0x40, 0x48, 0x64, 0x40, 0x40, 0x27, 0x17, 0x00, 0x1C, 0xF2,
+	 0xFF, 0xFF, 0x60, 0x40, 0x0A, 0x36, 0x06, 0x00, 0x14, 0x36, 0x07, 0x00, 0x37, 0x36, 0x08, 0x00,
+	 0x6E, 0x36, 0x09, 0x00, 0x70, 0x7C, 0xA0, 0x63, 0x0F, 0x00, 0x38, 0x7C, 0x50, 0x63, 0x0C, 0x00,
+	 0x15, 0x7C, 0x1E, 0x63, 0x09, 0x00, 0x0B, 0x7C, 0x0F, 0x63, 0x06, 0x00, 0x9C, 0xF4, 0xFF, 0x65,
+	 0x63, 0x47, 0xA4, 0x9C, 0xA7, 0x84, 0x23, 0x00, 0x40, 0x45, 0x43, 0x4D, 0x00, 0xE1, 0xF0, 0xFE,
+	 0x29, 0x40, 0x80, 0x2B, 0x03, 0x00, 0x00, 0x60, 0x6A, 0x65, 0x02, 0x00, 0x00, 0x60, 0xCA, 0x65,
+	 0x1F, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x40, 0x27, 0x0E, 0x00, 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40,
+	 0x04, 0x27, 0x03, 0x00, 0x65, 0x44, 0xE0, 0x85, 0x12, 0x00, 0x2B, 0xF2, 0x11, 0xF0, 0xC0, 0x84,
+	 0xD0, 0x84, 0xC4, 0x83, 0x11, 0x00, 0x1E, 0x64, 0xC4, 0x84, 0x60, 0x45, 0x08, 0x00, 0x40, 0x45,
+	 0xFF, 0x60, 0xF8, 0x64, 0x40, 0x43, 0x00, 0xE1, 0xF0, 0xFE, 0x00, 0x60, 0x3C, 0x65, 0x91, 0xF4,
+	 0x1B, 0xF0, 0xC3, 0x84, 0xC4, 0x84, 0xC0, 0x83, 0x28, 0x44, 0xA1, 0xFF, 0x12, 0x74, 0x80, 0x4E,
+	 0x12, 0x74, 0x83, 0x4C, 0x9A, 0xFF, 0x12, 0x74, 0x56, 0x62, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4,
+	 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x5C, 0x62, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74,
+	 0x7A, 0xD4, 0x12, 0x74, 0xA1, 0xFF, 0x98, 0xFF, 0xB2, 0x60, 0x58, 0x4F, 0x2D, 0x78, 0xFF, 0xFF,
+	 0xBC, 0xFF, 0xB5, 0xFF, 0x01, 0x60, 0x18, 0xE1, 0x47, 0xFF, 0x27, 0x44, 0x02, 0xBC, 0x40, 0x47,
+	 0x36, 0xF3, 0xB6, 0xFF, 0xB7, 0xFF, 0xB4, 0xFF, 0xC8, 0x60, 0x09, 0x7D, 0x7C, 0x4B, 0x60, 0x56,
+	 0xAD, 0xE2, 0xA5, 0x60, 0x79, 0x78, 0xFF, 0xFF, 0x19, 0x60, 0x7B, 0xF3, 0x19, 0x60, 0x3B, 0xF3,
+	 0x60, 0x40, 0x04, 0x26, 0x0B, 0x00, 0x07, 0xB4, 0x60, 0x40, 0x01, 0x36, 0x07, 0x00, 0x29, 0x44,
+	 0xBF, 0x60, 0xFF, 0xB7, 0x80, 0xBF, 0x40, 0x49, 0x80, 0x67, 0x05, 0x00, 0x3F, 0x60, 0xFF, 0x65,
+	 0x29, 0x44, 0x24, 0x89, 0x00, 0x64, 0x16, 0x60, 0x50, 0xF1, 0xFF, 0xFF, 0x19, 0x60, 0x55, 0xF9,
+	 0x39, 0xF1, 0x16, 0x60, 0x3C, 0xF1, 0x64, 0x41, 0x64, 0x5E, 0x60, 0x45, 0x64, 0x47, 0x1F, 0xB4,
+	 0x54, 0x94, 0xE0, 0xA0, 0x02, 0x0D, 0x00, 0x64, 0x02, 0x00, 0x01, 0x04, 0x1F, 0x64, 0x60, 0x47,
+	 0x07, 0x60, 0xEA, 0xF1, 0xB4, 0x84, 0xB0, 0x8C, 0x29, 0x60, 0xC0, 0x7C, 0x60, 0x47, 0x1F, 0xB4,
+	 0xE0, 0x84, 0xE0, 0x84, 0x40, 0xD3, 0x5A, 0xD1, 0x01, 0x60, 0x00, 0xE1, 0x05, 0x60, 0x69, 0x6B,
+	 0x60, 0x4C, 0xB5, 0xFF, 0x64, 0x4C, 0x7C, 0x44, 0x29, 0x40, 0x80, 0x2B, 0x67, 0x44, 0x60, 0x4C,
+	 0x40, 0xE1, 0x01, 0x60, 0x08, 0xE1, 0x84, 0xFF, 0xC2, 0x60, 0x45, 0x64, 0x40, 0x42, 0x82, 0xFF,
+	 0x3C, 0x44, 0x60, 0x46, 0x40, 0x42, 0x13, 0x64, 0x3A, 0xDB, 0x10, 0x60, 0x00, 0x65, 0x3C, 0x46,
+	 0x2A, 0xF2, 0x19, 0x60, 0x3B, 0xF1, 0xA4, 0x84, 0xC4, 0xBC, 0x40, 0x48, 0x64, 0x44, 0x04, 0x26,
+	 0x09, 0x00, 0x02, 0x26, 0x0A, 0x00, 0x01, 0x26, 0x0B, 0x00, 0x08, 0x2A, 0x03, 0x00, 0x0B, 0x63,
+	 0x6E, 0x64, 0x08, 0x00, 0x15, 0x63, 0x37, 0x64, 0x05, 0x00, 0x38, 0x63, 0x14, 0x64, 0x02, 0x00,
+	 0x70, 0x63, 0x0A, 0x64, 0x43, 0x4D, 0x40, 0x45, 0x00, 0xE1, 0xF0, 0xFE, 0x00, 0x60, 0x1E, 0x64,
+	 0x1B, 0xF0, 0x11, 0xF0, 0xC0, 0x84, 0xC0, 0x84, 0x60, 0x43, 0x28, 0x44, 0xA1, 0xFF, 0x12, 0x74,
+	 0x80, 0x4E, 0x12, 0x74, 0x83, 0x4C, 0x9A, 0xFF, 0x12, 0x74, 0x5C, 0x62, 0x7A, 0xD4, 0x12, 0x74,
+	 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0xA1, 0xFF, 0x98, 0xFF, 0xB2, 0x60, 0x58, 0x4F,
+	 0x2D, 0x78, 0xFF, 0xFF, 0x01, 0x60, 0x18, 0xE1, 0x78, 0x44, 0x03, 0xA4, 0x35, 0xFB, 0xB2, 0x60,
+	 0x70, 0x78, 0xFF, 0xFF, 0xC4, 0xE2, 0x08, 0x64, 0x3A, 0xDB, 0xA4, 0x60, 0xBF, 0x78, 0xFF, 0xFF,
+	 0x26, 0x43, 0x24, 0x40, 0x01, 0x2A, 0x0E, 0x00, 0x1D, 0xFF, 0x26, 0x44, 0x02, 0xBC, 0x40, 0x46,
+	 0x27, 0x44, 0x07, 0x22, 0x05, 0x00, 0xF8, 0xB4, 0x40, 0x47, 0x06, 0x64, 0x31, 0xFB, 0xC0, 0xFE,
+	 0x30, 0xF1, 0x81, 0x00, 0xFC, 0xB3, 0x32, 0x40, 0x01, 0x2A, 0x06, 0x00, 0x0A, 0xBB, 0x0F, 0xFC,
+	 0xCB, 0xFE, 0xA3, 0x60, 0xF4, 0x78, 0xFF, 0xFF, 0x24, 0x44, 0x04, 0x26, 0x29, 0x00, 0x0F, 0xFC,
+	 0x05, 0xFF, 0xDB, 0xF3, 0x28, 0x40, 0x80, 0x3A, 0x23, 0x00, 0x60, 0x40, 0x03, 0x3A, 0x20, 0x00,
+	 0x32, 0xF2, 0x7F, 0xF1, 0x33, 0xF2, 0xD0, 0x80, 0x80, 0xF1, 0x1A, 0x02, 0xD0, 0x80, 0x34, 0xF2,
+	 0x81, 0xF1, 0x16, 0x02, 0xD0, 0x80, 0x3C, 0x44, 0x13, 0x02, 0xAC, 0x86, 0xBB, 0xFE, 0x10, 0x03,
+	 0x2A, 0xF2, 0x21, 0x46, 0x60, 0x40, 0x80, 0x3A, 0x0B, 0x00, 0x01, 0x64, 0x31, 0xFB, 0xC0, 0xFE,
+	 0x00, 0x64, 0x32, 0xFB, 0x43, 0xFF, 0x84, 0xFF, 0xC2, 0x60, 0x45, 0x64, 0x40, 0x42, 0x82, 0xFF,
+	 0x30, 0xF1, 0x27, 0x44, 0x05, 0x22, 0x34, 0x00, 0xFA, 0xB4, 0x40, 0x47, 0x24, 0x44, 0x10, 0x2A,
+	 0x2B, 0x00, 0x28, 0x40, 0xD4, 0x3A, 0x28, 0x00, 0x31, 0x40, 0x08, 0x26, 0x00, 0x7C, 0x29, 0x40,
+	 0x50, 0x2B, 0x0D, 0x00, 0xEF, 0x60, 0xFF, 0x65, 0x29, 0x44, 0x24, 0x89, 0x31, 0x40, 0x08, 0x2A,
+	 0x06, 0x00, 0x1C, 0x60, 0x11, 0xF3, 0xFF, 0xFF, 0xE0, 0x85, 0x2B, 0x44, 0x05, 0x05, 0x2B, 0x44,
+	 0xFF, 0xA4, 0x01, 0xA4, 0x04, 0x24, 0x00, 0x64, 0xD0, 0x80, 0x70, 0x45, 0x02, 0x28, 0x64, 0x44,
+	 0xC4, 0x84, 0xFF, 0xFF, 0x04, 0x24, 0x00, 0xB4, 0x60, 0x50, 0x08, 0x28, 0x01, 0x00, 0x20, 0x29,
+	 0x6D, 0xE2, 0xA5, 0x60, 0x7F, 0x78, 0xFF, 0xFF, 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0x07, 0x00,
+	 0x02, 0x2A, 0x05, 0x00, 0xFD, 0xB4, 0x40, 0x47, 0x06, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0x05, 0x64,
+	 0x3A, 0xDB, 0x28, 0x44, 0xA4, 0x3A, 0x07, 0x00, 0x01, 0x60, 0x02, 0x7C, 0x25, 0x44, 0x0A, 0x3A,
+	 0x02, 0x00, 0x01, 0x60, 0x3A, 0x7C, 0x31, 0x40, 0x08, 0x26, 0x00, 0x7C, 0x29, 0x40, 0x50, 0x2B,
+	 0x0D, 0x00, 0xEF, 0x60, 0xFF, 0x65, 0x29, 0x44, 0x24, 0x89, 0x31, 0x40, 0x08, 0x2A, 0x06, 0x00,
+	 0x1C, 0x60, 0x11, 0xF3, 0xFF, 0xFF, 0xE0, 0x85, 0x2B, 0x44, 0x05, 0x05, 0x2B, 0x44, 0xFF, 0xA4,
+	 0x01, 0xA4, 0x04, 0x24, 0x00, 0x64, 0xD0, 0x80, 0x70, 0x45, 0x02, 0x28, 0x64, 0x44, 0xC4, 0x84,
+	 0xFF, 0xFF, 0x04, 0x24, 0x00, 0xB4, 0x28, 0x40, 0xE4, 0x36, 0x00, 0xB4, 0x60, 0x50, 0x08, 0x28,
+	 0x01, 0x00, 0x20, 0x29, 0x6D, 0xE2, 0xA3, 0x60, 0xE7, 0x78, 0xFF, 0xFF, 0x27, 0x44, 0x05, 0x22,
+	 0x09, 0x00, 0xBA, 0xB4, 0x40, 0x47, 0x3C, 0x46, 0x02, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0xA3, 0x60,
+	 0xF4, 0x78, 0xFF, 0xFF, 0x27, 0x44, 0x02, 0x2A, 0x06, 0x00, 0xFD, 0xB4, 0x40, 0x47, 0x06, 0x64,
+	 0x31, 0xFB, 0xC0, 0xFE, 0xF4, 0x01, 0xF3, 0x0A, 0x7C, 0x50, 0x6D, 0xE2, 0xF0, 0x01, 0x72, 0x45,
+	 0xDC, 0x84, 0xB2, 0xFB, 0x11, 0x64, 0x3A, 0xDB, 0xB3, 0xF3, 0x06, 0x04, 0xDC, 0x84, 0xB3, 0xFB,
+	 0xB4, 0xF3, 0x02, 0x04, 0xDC, 0x84, 0xB4, 0xFB, 0xA4, 0x60, 0x01, 0x78, 0xFF, 0xFF, 0x00, 0x61,
+	 0x12, 0x64, 0x3A, 0xDB, 0x20, 0x60, 0x04, 0x63, 0xBD, 0xD3, 0x72, 0x45, 0x44, 0x8A, 0x02, 0x28,
+	 0x03, 0x00, 0xE4, 0xE2, 0xDD, 0x81, 0x04, 0x00, 0x02, 0x28, 0x02, 0x00, 0xE4, 0xE2, 0xDD, 0x81,
+	 0xBD, 0xD3, 0xB2, 0xF1, 0x61, 0x45, 0xC0, 0x84, 0x00, 0x61, 0x02, 0x24, 0x01, 0xB9, 0xC4, 0x84,
+	 0x60, 0x55, 0x2A, 0x52, 0xE4, 0xE2, 0xB2, 0xFB, 0x02, 0x24, 0x01, 0xB9, 0xBD, 0xD3, 0xB3, 0xF1,
+	 0x61, 0x45, 0xC0, 0x84, 0x00, 0x61, 0x02, 0x24, 0x01, 0xB9, 0xC4, 0x84, 0xB3, 0xFB, 0x02, 0x24,
+	 0x01, 0xB9, 0xBD, 0xD3, 0xB4, 0xF1, 0x61, 0x45, 0xC0, 0x84, 0xC4, 0x84, 0xB4, 0xFB, 0xA5, 0x60,
+	 0x14, 0x78, 0xFF, 0xFF, 0xB0, 0x60, 0x9E, 0x78, 0xFF, 0xFF, 0x47, 0xFF, 0x1B, 0x60, 0xEE, 0xF3,
+	 0xFF, 0xFF, 0x04, 0x18, 0xAE, 0x4F, 0x08, 0xBC, 0x00, 0x7F, 0xA0, 0x5E, 0xC8, 0x74, 0xCD, 0xE2,
+	 0xAA, 0x60, 0xB9, 0x78, 0x00, 0x61, 0xA3, 0x60, 0xF4, 0x78, 0xFF, 0xFF, 0xAB, 0x60, 0xE8, 0x78,
+	 0xFF, 0xFF, 0x21, 0x46, 0x5C, 0x44, 0x26, 0x44, 0x02, 0x26, 0x01, 0x00, 0x3E, 0x46, 0x09, 0xF2,
+	 0x46, 0x41, 0x66, 0x40, 0xF3, 0x18, 0x40, 0x5E, 0xFD, 0xFB, 0x02, 0x64, 0x40, 0x46, 0x41, 0x5D,
+	 0x00, 0x64, 0x31, 0xFA, 0x00, 0xF2, 0x46, 0x45, 0x87, 0xFC, 0xAC, 0xE2, 0x01, 0x64, 0x33, 0xFB,
+	 0x32, 0x40, 0x01, 0x2A, 0x21, 0x00, 0x19, 0xF3, 0x01, 0x60, 0x1E, 0xE1, 0x1D, 0x18, 0x80, 0x64,
+	 0x40, 0x49, 0x00, 0xE1, 0x19, 0xFF, 0x08, 0x64, 0x2A, 0xFA, 0x5A, 0xDA, 0x2C, 0xFA, 0x5A, 0xDA,
+	 0x5A, 0xDA, 0xF1, 0xF3, 0xFF, 0xFF, 0x02, 0xBC, 0xF1, 0xFB, 0x72, 0x44, 0x24, 0xFA, 0xB2, 0xF3,
+	 0x25, 0xFA, 0xA1, 0xFF, 0xFF, 0xFF, 0xB6, 0xFF, 0xB7, 0xFF, 0xB4, 0xFF, 0xC8, 0x60, 0x09, 0x7D,
+	 0x7C, 0x4B, 0xA3, 0x60, 0xF4, 0x78, 0xFF, 0xFF, 0x01, 0xE1, 0x01, 0x60, 0x1A, 0xE1, 0x3F, 0x60,
+	 0xCF, 0x65, 0x29, 0x44, 0x24, 0x89, 0x2E, 0x44, 0x00, 0x36, 0x48, 0x00, 0x01, 0x3A, 0xE5, 0x00,
+	 0x88, 0xFF, 0x40, 0x67, 0x29, 0x45, 0x34, 0x89, 0x04, 0x64, 0x89, 0xFF, 0x60, 0x54, 0x88, 0xFF,
+	 0xA1, 0xFF, 0x6C, 0x45, 0x65, 0x44, 0x0F, 0xB4, 0x40, 0x45, 0x1C, 0xFA, 0x65, 0x44, 0x29, 0x41,
+	 0xF9, 0x81, 0x52, 0x4A, 0x71, 0x89, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x83, 0x1D, 0xFC,
+	 0x1B, 0xFC, 0x10, 0x60, 0x00, 0x65, 0x29, 0x44, 0x34, 0x89, 0x50, 0x4B, 0x67, 0x50, 0x69, 0xE2,
+	 0xB6, 0xF1, 0xFC, 0xA3, 0xD3, 0x80, 0x43, 0x43, 0x03, 0x04, 0xAB, 0x60, 0xDE, 0x78, 0xFF, 0xFF,
+	 0x09, 0x7C, 0xD3, 0x80, 0x9A, 0xFF, 0x03, 0x07, 0xAB, 0x60, 0xDE, 0x78, 0xFF, 0xFF, 0x25, 0x44,
+	 0x01, 0x26, 0x0F, 0xAC, 0x26, 0x60, 0x4A, 0x65, 0x44, 0xD3, 0x12, 0x65, 0x45, 0x46, 0x60, 0x47,
+	 0x40, 0x7F, 0x27, 0xFA, 0x8F, 0xFC, 0x18, 0x61, 0xEA, 0xF1, 0xA1, 0xFF, 0x6C, 0x44, 0xDC, 0x80,
+	 0xFF, 0xFF, 0x21, 0x03, 0x50, 0xFE, 0xAC, 0x60, 0xC1, 0x78, 0xFF, 0xFF, 0xC8, 0x60, 0x0B, 0x7D,
+	 0x08, 0x60, 0x00, 0x6B, 0xB5, 0xFF, 0xB7, 0xFF, 0xB4, 0xFF, 0xAA, 0x74, 0xCD, 0xE2, 0x01, 0x64,
+	 0x89, 0xFF, 0x60, 0x54, 0x88, 0xFF, 0x01, 0x60, 0x08, 0xE1, 0x05, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF,
+	 0x04, 0x25, 0x8B, 0x00, 0x6C, 0x44, 0x0A, 0x36, 0x07, 0x00, 0x14, 0x36, 0x05, 0x00, 0x37, 0x36,
+	 0x03, 0x00, 0x6E, 0x36, 0x01, 0x00, 0x81, 0x00, 0x40, 0x45, 0x32, 0x74, 0xA1, 0xFF, 0x1C, 0xFA,
+	 0x40, 0x4E, 0x8C, 0x44, 0x60, 0x43, 0x1D, 0xFA, 0x01, 0xE1, 0x20, 0x64, 0x3A, 0xDB, 0x2E, 0x44,
+	 0x14, 0x36, 0x12, 0x00, 0x0A, 0x36, 0x0F, 0x00, 0x63, 0x45, 0xE3, 0x83, 0xE3, 0x83, 0xC7, 0x83,
+	 0xE3, 0x83, 0xC7, 0x83, 0xFF, 0xFF, 0x37, 0x36, 0x05, 0x00, 0x6E, 0x36, 0x04, 0x00, 0xAC, 0x60,
+	 0xBF, 0x78, 0xFF, 0xFF, 0xEB, 0x83, 0xEB, 0x83, 0xEB, 0x83, 0xEB, 0x83, 0xFF, 0xFF, 0x80, 0x27,
+	 0xCF, 0x83, 0x1B, 0xFC, 0x01, 0x64, 0x51, 0xFB, 0xA1, 0xFF, 0x29, 0x41, 0xF9, 0x81, 0x52, 0x4A,
+	 0x71, 0x89, 0x2E, 0x44, 0x27, 0xFA, 0xB6, 0xF1, 0xFC, 0xA3, 0xD3, 0x80, 0x43, 0x43, 0x03, 0x04,
+	 0xAB, 0x60, 0xDE, 0x78, 0xFF, 0xFF, 0x9A, 0xFF, 0x54, 0x63, 0x12, 0x64, 0x40, 0x46, 0x8F, 0xFC,
+	 0x18, 0x61, 0xEA, 0xF1, 0x50, 0xFE, 0x6C, 0x40, 0x9E, 0x15, 0x01, 0x60, 0x08, 0xE1, 0x80, 0xE1,
+	 0x00, 0x64, 0x33, 0xFB, 0x29, 0x40, 0x50, 0x2B, 0x0F, 0x00, 0x2B, 0x44, 0x70, 0x45, 0xC4, 0x84,
+	 0xFF, 0xFF, 0x04, 0x24, 0x00, 0xB4, 0x60, 0x50, 0x08, 0x28, 0x01, 0x00, 0x20, 0x29, 0x6D, 0xE2,
+	 0xEF, 0x60, 0xFF, 0x65, 0x29, 0x44, 0x24, 0x89, 0x01, 0x60, 0x18, 0xE1, 0x01, 0x11, 0x12, 0x00,
+	 0x29, 0x44, 0x20, 0xBC, 0x40, 0x49, 0x01, 0x64, 0x33, 0xFB, 0xB6, 0xFF, 0x00, 0xE1, 0x01, 0x60,
+	 0x1A, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x6C, 0x40, 0xFC, 0x11, 0x01, 0x60, 0x18, 0xE1, 0xAE, 0x4F,
+	 0xF7, 0xB4, 0xA0, 0x5E, 0xB5, 0xFF, 0xB6, 0xFF, 0xB7, 0xFF, 0xB4, 0xFF, 0xC8, 0x60, 0x09, 0x7D,
+	 0x7C, 0x4B, 0x35, 0xE1, 0xAC, 0xE2, 0xAA, 0x60, 0x46, 0x78, 0xFF, 0xFF, 0x16, 0x60, 0x7F, 0xF3,
+	 0xFF, 0xFF, 0xDC, 0x84, 0x00, 0x36, 0x00, 0x3B, 0xA2, 0xDB, 0x21, 0x64, 0x3A, 0xDB, 0xBD, 0x01,
+	 0xAC, 0xE2, 0x01, 0x64, 0x33, 0xFB, 0x01, 0xE1, 0x3F, 0x60, 0xCF, 0x65, 0x29, 0x44, 0x24, 0x89,
+	 0x2E, 0x44, 0x00, 0x36, 0x21, 0x00, 0x01, 0x3A, 0xF0, 0x01, 0x88, 0xFF, 0x40, 0x67, 0x29, 0x45,
+	 0x34, 0x89, 0xA1, 0xFF, 0x6C, 0x45, 0x65, 0x44, 0x0F, 0xB4, 0x40, 0x45, 0x65, 0x44, 0x29, 0x41,
+	 0xF9, 0x81, 0x52, 0x4A, 0x71, 0x89, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x83, 0x0E, 0x7C,
+	 0xD3, 0x80, 0xFF, 0xFF, 0x03, 0x03, 0xAB, 0x60, 0xDE, 0x78, 0xFF, 0xFF, 0xA1, 0xFF, 0x6C, 0x44,
+	 0xDC, 0x80, 0xFF, 0xFF, 0xD2, 0x03, 0x41, 0x00, 0xC8, 0x60, 0x0B, 0x7D, 0x08, 0x60, 0x00, 0x6B,
+	 0xB5, 0xFF, 0xB7, 0xFF, 0xB4, 0xFF, 0xAA, 0x74, 0xCD, 0xE2, 0x01, 0x60, 0x08, 0xE1, 0x05, 0xE1,
+	 0xA1, 0xFF, 0xFF, 0xFF, 0x04, 0x25, 0xC1, 0x01, 0x6C, 0x44, 0x0A, 0x36, 0x07, 0x00, 0x14, 0x36,
+	 0x05, 0x00, 0x37, 0x36, 0x03, 0x00, 0x6E, 0x36, 0x01, 0x00, 0xB7, 0x01, 0x40, 0x45, 0x32, 0x74,
+	 0xA1, 0xFF, 0x40, 0x4E, 0x8C, 0x44, 0x60, 0x43, 0x01, 0xE1, 0x20, 0x64, 0x3A, 0xDB, 0x2E, 0x44,
+	 0x14, 0x36, 0x09, 0x00, 0x0A, 0x36, 0x07, 0x00, 0x37, 0x36, 0x05, 0x00, 0x6E, 0x36, 0x03, 0x00,
+	 0xAC, 0x60, 0xBF, 0x78, 0xFF, 0xFF, 0x01, 0x64, 0x51, 0xFB, 0xA1, 0xFF, 0x29, 0x41, 0xF9, 0x81,
+	 0x52, 0x4A, 0x71, 0x89, 0x0E, 0x7C, 0xD3, 0x80, 0x43, 0x43, 0x03, 0x03, 0xAB, 0x60, 0xDE, 0x78,
+	 0xFF, 0xFF, 0x6C, 0x40, 0xFF, 0xFF, 0x01, 0x15, 0x90, 0x01, 0x12, 0x64, 0x40, 0x46, 0xEA, 0xF1,
+	 0x50, 0xFE, 0xA1, 0xFF, 0x12, 0x61, 0x8C, 0x44, 0xEB, 0xF0, 0x40, 0x48, 0x8C, 0x44, 0x30, 0xFB,
+	 0x04, 0x61, 0x50, 0xFE, 0x8C, 0x44, 0xD0, 0x80, 0x8C, 0x44, 0xD4, 0x80, 0x8C, 0x44, 0xEC, 0xF1,
+	 0x00, 0x65, 0xD0, 0x80, 0x28, 0x44, 0x01, 0x0C, 0x13, 0x00, 0x10, 0x65, 0x60, 0x40, 0xC4, 0x36,
+	 0x04, 0x00, 0xD4, 0x3A, 0x0D, 0x00, 0x27, 0x40, 0x40, 0x26, 0x30, 0x65, 0x35, 0x84, 0xA1, 0xFF,
+	 0x8C, 0x44, 0x47, 0xFF, 0x50, 0x4B, 0x67, 0x50, 0x69, 0xE2, 0x6A, 0x44, 0x40, 0x2B, 0x09, 0x15,
+	 0x2C, 0x60, 0xEC, 0x64, 0xF1, 0x60, 0x78, 0x41, 0xE4, 0x78, 0xB5, 0xF1, 0x2A, 0x64, 0x3A, 0xDB,
+	 0x1C, 0x01, 0x29, 0x40, 0x10, 0x26, 0x02, 0x00, 0x04, 0x74, 0xCD, 0xE2, 0x8C, 0x44, 0xB6, 0xFF,
+	 0xB7, 0xFF, 0x01, 0x60, 0x18, 0xE1, 0x05, 0xE1, 0x00, 0x64, 0x33, 0xFB, 0xA1, 0xFF, 0x6C, 0x44,
+	 0xA1, 0xFF, 0x6C, 0x44, 0x29, 0x40, 0x40, 0x2B, 0x03, 0x00, 0xB6, 0xFF, 0xA1, 0xFF, 0x6C, 0x44,
+	 0xA1, 0xFF, 0x02, 0x74, 0x29, 0x44, 0x40, 0x27, 0x05, 0x74, 0xCD, 0xE2, 0xA1, 0xFF, 0xCB, 0xF3,
+	 0xC4, 0xE2, 0x89, 0xFF, 0x60, 0x54, 0x88, 0xFF, 0xDC, 0x84, 0xE0, 0x94, 0x26, 0x44, 0x84, 0xBC,
+	 0x40, 0x46, 0x23, 0x64, 0x3A, 0xDB, 0xB5, 0xFF, 0xBC, 0xFF, 0x47, 0xFF, 0xB6, 0xFF, 0xB7, 0xFF,
+	 0xB4, 0xFF, 0xC8, 0x60, 0x09, 0x7D, 0x7C, 0x4B, 0xA9, 0x60, 0x88, 0x78, 0xFF, 0xFF, 0x29, 0x64,
+	 0x3A, 0xDB, 0xA2, 0xFC, 0x32, 0x40, 0x01, 0x2A, 0xB9, 0x00, 0x01, 0x60, 0x1A, 0xE1, 0x23, 0x43,
+	 0xA1, 0xFF, 0xEC, 0x44, 0x2A, 0xFA, 0x40, 0x48, 0xA1, 0xFF, 0x7A, 0xDC, 0x7E, 0x36, 0x04, 0xA2,
+	 0xFC, 0x1C, 0x03, 0x1D, 0x00, 0x64, 0x3F, 0xFA, 0x2E, 0x00, 0x03, 0x2B, 0x04, 0x00, 0xA1, 0xFF,
+	 0x7A, 0xDC, 0x7A, 0xDC, 0x7A, 0xDC, 0x8F, 0xB0, 0x88, 0x3A, 0x03, 0x00, 0x70, 0x62, 0xA1, 0xFF,
+	 0x7A, 0xDC, 0x28, 0x40, 0x40, 0x2B, 0x06, 0x00, 0x72, 0x62, 0xA1, 0xFF, 0x7A, 0xDC, 0x7A, 0xDC,
+	 0x7A, 0xDC, 0x7A, 0xDC, 0x3F, 0xFC, 0x00, 0xF4, 0x10, 0x62, 0x6E, 0x61, 0xA1, 0xFF, 0x05, 0x1D,
+	 0x12, 0x1E, 0x0C, 0x00, 0x00, 0xF4, 0x7C, 0x61, 0x02, 0x62, 0x7A, 0xDC, 0x63, 0x40, 0xFD, 0x1C,
+	 0xF9, 0x1D, 0xFF, 0xB1, 0x08, 0x1E, 0x02, 0x02, 0x00, 0xF4, 0x02, 0x62, 0xB6, 0xFF, 0xB7, 0xFF,
+	 0xA1, 0xFF, 0x6C, 0x44, 0x5A, 0xDA, 0x98, 0xFF, 0xA1, 0xFF, 0x6C, 0x40, 0xA1, 0xFF, 0x47, 0xFF,
+	 0x7C, 0x44, 0x33, 0xFB, 0x26, 0x44, 0xFD, 0xB4, 0x84, 0xBC, 0x01, 0x15, 0x7F, 0xB4, 0x40, 0x46,
+	 0x6C, 0x40, 0xB6, 0xFF, 0xB7, 0xFF, 0xA1, 0xFF, 0x6C, 0x45, 0xA1, 0xFF, 0x7F, 0x60, 0x7F, 0x7C,
+	 0x6C, 0x44, 0xA0, 0x84, 0x15, 0xA7, 0x15, 0xA4, 0x21, 0x46, 0x26, 0xFA, 0x29, 0x40, 0x40, 0x2B,
+	 0x07, 0x00, 0xB6, 0xFF, 0x40, 0x60, 0x00, 0x65, 0xA1, 0xFF, 0x6C, 0x44, 0x1A, 0xFA, 0x09, 0x00,
+	 0x65, 0x44, 0x0F, 0xB4, 0x06, 0xA8, 0x80, 0x60, 0x00, 0x65, 0x08, 0x28, 0x7C, 0x45, 0x29, 0x44,
+	 0x34, 0x89, 0x27, 0xF0, 0x65, 0x44, 0x64, 0x5E, 0x27, 0xFA, 0x81, 0xE1, 0x01, 0x60, 0x18, 0xE1,
+	 0x01, 0x11, 0x12, 0x00, 0x29, 0x44, 0x20, 0xBC, 0x40, 0x49, 0x01, 0x64, 0x33, 0xFB, 0xB6, 0xFF,
+	 0x00, 0xE1, 0x01, 0x60, 0x1A, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x6C, 0x40, 0xFC, 0x11, 0x01, 0x60,
+	 0x18, 0xE1, 0xAE, 0x4F, 0xF7, 0xB4, 0xA0, 0x5E, 0x00, 0x70, 0x00, 0x64, 0x40, 0x4B, 0x21, 0x46,
+	 0xB5, 0xFF, 0xBC, 0xFF, 0x47, 0xFF, 0xB6, 0xFF, 0xB7, 0xFF, 0xB4, 0xFF, 0xC8, 0x60, 0x09, 0x7D,
+	 0x7C, 0x4B, 0x28, 0x44, 0x04, 0x27, 0x09, 0x00, 0xD4, 0x36, 0x04, 0x00, 0x0C, 0x22, 0x02, 0x00,
+	 0x0C, 0x3A, 0x03, 0x00, 0xAE, 0x4F, 0xF7, 0xB4, 0xA0, 0x5E, 0x2A, 0x44, 0x72, 0x45, 0x24, 0xFA,
+	 0xB2, 0xF3, 0x06, 0x04, 0xE4, 0xE2, 0xDC, 0x9C, 0x29, 0x40, 0x01, 0x26, 0x64, 0x44, 0xB2, 0xF9,
+	 0x25, 0xFA, 0xB3, 0xF3, 0x02, 0x04, 0xDC, 0x84, 0xB3, 0xFB, 0x28, 0xFA, 0xB4, 0xF3, 0x02, 0x04,
+	 0xDC, 0x84, 0xB4, 0xFB, 0x29, 0xFA, 0xA9, 0x60, 0x88, 0x78, 0xFF, 0xFF, 0xA1, 0xFF, 0x19, 0x60,
+	 0xA3, 0xF3, 0x12, 0x61, 0x60, 0x40, 0x01, 0x2A, 0x08, 0x00, 0x00, 0x64, 0x3B, 0xFA, 0xBF, 0x60,
+	 0xFF, 0x65, 0x8C, 0x44, 0x3D, 0xFA, 0xA4, 0x84, 0x01, 0x00, 0x8C, 0x44, 0xEB, 0xF0, 0x2A, 0xFA,
+	 0x40, 0x48, 0x04, 0x26, 0x48, 0x00, 0xA1, 0xFF, 0x8C, 0x44, 0x5A, 0xDA, 0x30, 0xFB, 0x6C, 0x44,
+	 0x2C, 0xFA, 0xFF, 0xFF, 0x01, 0x26, 0x2B, 0x00, 0xD0, 0x80, 0xA1, 0xFF, 0x8C, 0x44, 0x6C, 0x5C,
+	 0x00, 0xE1, 0xF2, 0xFE, 0x2D, 0xFA, 0xEC, 0xF3, 0xD4, 0x80, 0xD0, 0x80, 0x2E, 0xF8, 0x24, 0x44,
+	 0x16, 0x0C, 0x32, 0x40, 0x02, 0x2A, 0x07, 0x00, 0x28, 0x42, 0x0C, 0xB2, 0x08, 0x3A, 0x03, 0x00,
+	 0x10, 0xBC, 0x40, 0x44, 0x61, 0x00, 0x04, 0x0A, 0xA1, 0xFF, 0xAB, 0x60, 0xE7, 0x78, 0xFF, 0xFF,
+	 0x11, 0xBC, 0x40, 0x44, 0x28, 0x45, 0xBF, 0x60, 0xFF, 0x64, 0x24, 0x88, 0x55, 0x00, 0x30, 0xBC,
+	 0x40, 0x44, 0x22, 0xF0, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDA, 0x4D, 0x00, 0x20, 0xB9,
+	 0x5C, 0x8E, 0xA1, 0xFF, 0x8C, 0x44, 0x2D, 0xFA, 0xDC, 0x9C, 0x6C, 0x44, 0x00, 0xE1, 0xF2, 0xFE,
+	 0x2E, 0xFA, 0x08, 0x28, 0x44, 0x4E, 0xDC, 0x84, 0x2E, 0x5C, 0xB0, 0x84, 0xEF, 0xB1, 0x08, 0x24,
+	 0x40, 0xB9, 0x41, 0x46, 0x39, 0x00, 0x23, 0x41, 0x13, 0x64, 0x51, 0x90, 0x56, 0x63, 0x03, 0x04,
+	 0xAB, 0x60, 0xDE, 0x78, 0xFF, 0xFF, 0x8C, 0x44, 0x04, 0x61, 0x2B, 0xFA, 0x50, 0xFE, 0x80, 0x27,
+	 0x00, 0x64, 0x30, 0xFB, 0x8C, 0x44, 0x2C, 0xFA, 0xD0, 0x80, 0x8C, 0x44, 0x2D, 0xFA, 0xD4, 0x80,
+	 0x00, 0x65, 0x8C, 0x44, 0xEC, 0xF1, 0x2E, 0xFA, 0xD0, 0x80, 0x28, 0x44, 0x03, 0x0C, 0xA0, 0x2A,
+	 0x0A, 0x00, 0x11, 0x00, 0x10, 0x65, 0x60, 0x40, 0xC4, 0x36, 0x04, 0x00, 0xD4, 0x3A, 0x08, 0x00,
+	 0x27, 0x40, 0x40, 0x26, 0x30, 0x65, 0x00, 0x64, 0x3F, 0xFA, 0x46, 0x4E, 0x35, 0x84, 0x64, 0x00,
+	 0x40, 0x26, 0xF9, 0x01, 0x30, 0x65, 0x7A, 0xDC, 0x7A, 0xDC, 0x7A, 0xDC, 0x04, 0x61, 0xF3, 0x01,
+	 0xA1, 0xFF, 0xAB, 0x60, 0xA5, 0x78, 0xFF, 0xFF, 0xFF, 0x60, 0xFE, 0x65, 0x23, 0x43, 0xE8, 0xA3,
+	 0x80, 0x27, 0xF6, 0x01, 0x20, 0xE6, 0x08, 0x60, 0x00, 0xEB, 0x28, 0x44, 0x03, 0x2B, 0x05, 0x00,
+	 0x6A, 0x62, 0x7A, 0xDC, 0x7A, 0xDC, 0x7A, 0xDC, 0x28, 0x44, 0x8F, 0xB0, 0x88, 0x3A, 0x03, 0x00,
+	 0x70, 0x62, 0x7A, 0xDC, 0x28, 0x44, 0x40, 0x2B, 0x0D, 0x00, 0x72, 0x62, 0x7A, 0xDC, 0xA1, 0xFF,
+	 0x6C, 0x5C, 0x5A, 0xD8, 0xE4, 0x40, 0x20, 0x2B, 0x03, 0x00, 0x7A, 0xDC, 0x7A, 0xDC, 0xF8, 0xA3,
+	 0x25, 0xFF, 0xB0, 0xFF, 0x3F, 0xFC, 0x00, 0xF4, 0x10, 0x62, 0x10, 0x61, 0x57, 0x90, 0x6C, 0x61,
+	 0xA1, 0xFF, 0x09, 0x07, 0x02, 0x1D, 0x28, 0x1E, 0x1F, 0x00, 0xCB, 0x83, 0x7A, 0xDC, 0xFE, 0x1C,
+	 0xD9, 0x81, 0x22, 0x1E, 0x19, 0x00, 0xCB, 0x83, 0x0E, 0xA3, 0xA7, 0x84, 0xF2, 0xA3, 0x7A, 0xDC,
+	 0xFE, 0x1C, 0x03, 0x1D, 0x7C, 0xA8, 0xD9, 0x81, 0x0A, 0x02, 0x00, 0xF4, 0x02, 0x62, 0xA7, 0x84,
+	 0x7A, 0x61, 0x7A, 0xDC, 0xFE, 0x1C, 0xF9, 0x1D, 0x7C, 0xA8, 0xD9, 0x81, 0xF6, 0x03, 0xFF, 0xB1,
+	 0x0B, 0x1E, 0x02, 0x02, 0x00, 0xF4, 0x02, 0x62, 0xA1, 0xFF, 0xFF, 0xFF, 0xB6, 0xFF, 0xB7, 0xFF,
+	 0x6C, 0x44, 0x5A, 0xDA, 0xCD, 0x81, 0x64, 0x40, 0x46, 0x45, 0x28, 0x44, 0x40, 0x2B, 0x0E, 0x00,
+	 0x64, 0x40, 0x20, 0x2B, 0x0B, 0x00, 0x01, 0xA2, 0x62, 0x44, 0x46, 0x45, 0x21, 0x46, 0x00, 0xF4,
+	 0x02, 0x62, 0x9A, 0xFF, 0x7A, 0xDC, 0x7A, 0xDC, 0x7A, 0xDC, 0x7A, 0xDC, 0x01, 0x60, 0x18, 0xE1,
+	 0x24, 0x76, 0xAD, 0xE2, 0x41, 0xE1, 0x98, 0xFF, 0x00, 0xE6, 0x01, 0xF2, 0x61, 0x45, 0xD4, 0x9E,
+	 0x21, 0x46, 0x16, 0xFA, 0x25, 0x44, 0x06, 0xFA, 0xA1, 0xFF, 0x8C, 0x44, 0xA1, 0xFF, 0x47, 0xFF,
+	 0x29, 0x40, 0x50, 0x2B, 0x06, 0x00, 0x2B, 0x44, 0x1C, 0x60, 0x11, 0xFB, 0x70, 0x45, 0x44, 0x8B,
+	 0x01, 0x00, 0x50, 0x4B, 0x67, 0x50, 0x69, 0xE2, 0x25, 0x46, 0x01, 0xF2, 0x61, 0x45, 0xD4, 0x9E,
+	 0x21, 0x46, 0x16, 0xFA, 0x25, 0x45, 0x86, 0xF8, 0xFF, 0xFF, 0x6A, 0x44, 0x40, 0x2B, 0x03, 0x15,
+	 0xAF, 0x60, 0xF3, 0x78, 0xFF, 0xFF, 0x29, 0x40, 0x10, 0x26, 0x04, 0x00, 0x04, 0x74, 0xCD, 0xE2,
+	 0xA1, 0xFF, 0xFF, 0xFF, 0x6C, 0x44, 0xB6, 0xFF, 0xB7, 0xFF, 0xC4, 0xE2, 0x01, 0x60, 0x18, 0xE1,
+	 0x05, 0x76, 0xAD, 0xE2, 0x41, 0xE1, 0xA1, 0xFF, 0x6C, 0x45, 0xA1, 0xFF, 0x65, 0x41, 0x7F, 0x60,
+	 0x7F, 0x7C, 0x6C, 0x44, 0xA0, 0x84, 0x15, 0xA7, 0x15, 0xA4, 0x21, 0x46, 0x26, 0xFA, 0x22, 0x46,
+	 0x10, 0xFA, 0x21, 0x46, 0x29, 0x40, 0x40, 0x2B, 0x07, 0x00, 0xB6, 0xFF, 0xA1, 0xFF, 0x40, 0x60,
+	 0x00, 0x65, 0x6C, 0x44, 0x1A, 0xFA, 0x09, 0x00, 0x65, 0x44, 0x0F, 0xB4, 0x06, 0xA8, 0x80, 0x60,
+	 0x00, 0x65, 0x08, 0x28, 0x7C, 0x45, 0x29, 0x44, 0x34, 0x89, 0x00, 0x64, 0x33, 0xFB, 0x40, 0x21,
+	 0x00, 0x00, 0xAC, 0xE2, 0x05, 0xE1, 0x27, 0xF0, 0x65, 0x44, 0x64, 0x5E, 0x27, 0xFA, 0x28, 0x44,
+	 0x8F, 0xB0, 0x88, 0x3A, 0x09, 0x00, 0x39, 0xF2, 0xFF, 0xFF, 0x60, 0xB0, 0x20, 0x3A, 0x04, 0x00,
+	 0x24, 0x44, 0xFF, 0x60, 0xDF, 0xB4, 0x40, 0x44, 0x28, 0x40, 0x03, 0x26, 0xE2, 0x00, 0x31, 0x40,
+	 0x20, 0x2A, 0x03, 0x00, 0x28, 0x40, 0x50, 0x3A, 0xDC, 0x00, 0x24, 0x44, 0x20, 0x2A, 0xD9, 0x00,
+	 0x29, 0x40, 0x50, 0x2B, 0x0D, 0x00, 0xEF, 0x60, 0xFF, 0x65, 0x29, 0x44, 0x24, 0x89, 0x31, 0x40,
+	 0x08, 0x2A, 0x06, 0x00, 0x1C, 0x60, 0x11, 0xF3, 0xFF, 0xFF, 0xE0, 0x85, 0x2B, 0x44, 0x06, 0x05,
+	 0x2B, 0x44, 0xFF, 0xA4, 0x01, 0xA4, 0x04, 0x24, 0x00, 0x64, 0x40, 0x4B, 0xAC, 0x80, 0x28, 0x40,
+	 0xB4, 0x3A, 0x03, 0x00, 0x02, 0x03, 0x30, 0xFB, 0xBC, 0x00, 0x28, 0x44, 0xBF, 0x60, 0xFF, 0x65,
+	 0xA4, 0x84, 0x40, 0x48, 0x2B, 0x50, 0xA1, 0xFF, 0xFF, 0xFF, 0x01, 0x60, 0x08, 0xE1, 0x1C, 0xF2,
+	 0xC4, 0xE2, 0x40, 0x45, 0x28, 0x40, 0xC4, 0x36, 0x9C, 0x00, 0x29, 0x40, 0x40, 0x2B, 0x48, 0x00,
+	 0x32, 0x60, 0xFA, 0x63, 0x60, 0x40, 0x0B, 0x36, 0x20, 0x00, 0x0F, 0x36, 0x1B, 0x00, 0x0A, 0x36,
+	 0x16, 0x00, 0x0E, 0x36, 0x11, 0x00, 0x09, 0x36, 0x0C, 0x00, 0x0D, 0x36, 0x07, 0x00, 0x08, 0x36,
+	 0x02, 0x00, 0xA3, 0xD3, 0x15, 0x00, 0x02, 0xA3, 0xA3, 0xD3, 0x12, 0x00, 0x04, 0xA3, 0xA3, 0xD3,
+	 0x0F, 0x00, 0x06, 0xA3, 0xA3, 0xD3, 0x0C, 0x00, 0x08, 0xA3, 0xA3, 0xD3, 0x09, 0x00, 0x0A, 0xA3,
+	 0xA3, 0xD3, 0x06, 0x00, 0x0C, 0xA3, 0xA3, 0xD3, 0x03, 0x00, 0x0E, 0xA3, 0xA3, 0xD3, 0xFF, 0xFF,
+	 0x2C, 0x60, 0x7C, 0x63, 0x60, 0x40, 0x0C, 0x36, 0x19, 0x00, 0x08, 0x36, 0x15, 0x00, 0x0D, 0x36,
+	 0x11, 0x00, 0x09, 0x36, 0x0D, 0x00, 0x0E, 0x36, 0x09, 0x00, 0x0A, 0x36, 0x05, 0x00, 0x0F, 0x36,
+	 0x01, 0x00, 0x39, 0x00, 0x02, 0xA3, 0x37, 0x00, 0x04, 0xA3, 0x35, 0x00, 0x06, 0xA3, 0x33, 0x00,
+	 0x08, 0xA3, 0x31, 0x00, 0x0A, 0xA3, 0x2F, 0x00, 0x0C, 0xA3, 0x2D, 0x00, 0x0E, 0xA3, 0x2B, 0x00,
+	 0x33, 0x60, 0x0A, 0x63, 0x25, 0x44, 0x0A, 0x36, 0x0C, 0x00, 0x14, 0x36, 0x07, 0x00, 0x37, 0x36,
+	 0x02, 0x00, 0xA3, 0xD3, 0x09, 0x00, 0x02, 0xA3, 0xA3, 0xD3, 0x06, 0x00, 0x04, 0xA3, 0xA3, 0xD3,
+	 0x03, 0x00, 0x06, 0xA3, 0xA3, 0xD3, 0xFF, 0xFF, 0x40, 0x45, 0x0A, 0x36, 0x0D, 0x00, 0x14, 0x36,
+	 0x38, 0x64, 0x37, 0x3A, 0x03, 0x00, 0x04, 0x7F, 0x40, 0x45, 0x15, 0x64, 0x6E, 0x3A, 0x09, 0x00,
+	 0x84, 0x7F, 0x40, 0x45, 0x0B, 0x64, 0x05, 0x00, 0x29, 0x44, 0x7F, 0x60, 0xFF, 0xB4, 0x40, 0x49,
+	 0x70, 0x64, 0x40, 0x4D, 0x02, 0x00, 0x40, 0x45, 0x0A, 0x00, 0x2C, 0x60, 0x74, 0x63, 0x0A, 0x36,
+	 0x06, 0x00, 0x14, 0x36, 0x02, 0xA3, 0x37, 0x36, 0x04, 0xA3, 0x6E, 0x36, 0x06, 0xA3, 0x28, 0xA3,
+	 0xA3, 0xD1, 0xD8, 0xA3, 0x19, 0x60, 0x55, 0xF9, 0x39, 0xF1, 0xA3, 0xD1, 0x64, 0x41, 0x64, 0x5E,
+	 0x60, 0x45, 0x64, 0x47, 0x1F, 0xB4, 0x54, 0x94, 0xE0, 0xA0, 0x02, 0x0D, 0x00, 0x64, 0x02, 0x00,
+	 0x01, 0x04, 0x1F, 0x64, 0x60, 0x47, 0xB4, 0x85, 0x29, 0x44, 0xC0, 0x60, 0x00, 0xB4, 0xB4, 0x84,
+	 0x1F, 0xFA, 0xB5, 0xFF, 0xA1, 0xFF, 0xCB, 0xF3, 0xC4, 0xE2, 0x89, 0xFF, 0x60, 0x54, 0x88, 0xFF,
+	 0xDC, 0x84, 0xE0, 0x94, 0xFF, 0x60, 0xCF, 0x65, 0x29, 0x44, 0x24, 0x89, 0xA5, 0x60, 0x88, 0x78,
+	 0x04, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0xC4, 0xE2, 0xA1, 0xFF, 0xFF, 0x60, 0xCF, 0x65, 0x29, 0x44,
+	 0x24, 0x89, 0xCB, 0xF3, 0xC4, 0xE2, 0x89, 0xFF, 0x60, 0x54, 0x88, 0xFF, 0xDC, 0x84, 0xE0, 0x94,
+	 0x26, 0x44, 0x84, 0xBC, 0x24, 0x40, 0x0C, 0x22, 0xFD, 0xB4, 0x40, 0x46, 0x23, 0x64, 0x3A, 0xDB,
+	 0xAD, 0x60, 0x4F, 0x78, 0xFF, 0xFF, 0x27, 0x40, 0x26, 0x22, 0x05, 0x00, 0xF8, 0xB4, 0x40, 0x47,
+	 0x06, 0x64, 0x31, 0xFB, 0xC0, 0xFE, 0x29, 0x40, 0x10, 0x26, 0x02, 0x00, 0x04, 0x74, 0xCD, 0xE2,
+	 0x01, 0x60, 0x18, 0xE1, 0x01, 0x60, 0x18, 0xE1, 0x01, 0x11, 0x12, 0x00, 0x29, 0x44, 0x20, 0xBC,
+	 0x40, 0x49, 0x01, 0x64, 0x33, 0xFB, 0xB6, 0xFF, 0x00, 0xE1, 0x01, 0x60, 0x1A, 0xE1, 0xA1, 0xFF,
+	 0xFF, 0xFF, 0x6C, 0x40, 0xFC, 0x11, 0x01, 0x60, 0x18, 0xE1, 0xAE, 0x4F, 0xF7, 0xB4, 0xA0, 0x5E,
+	 0xB5, 0xFF, 0x47, 0xFF, 0xB6, 0xFF, 0xB7, 0xFF, 0xB4, 0xFF, 0xC8, 0x60, 0x09, 0x7D, 0x7C, 0x4B,
+	 0x29, 0x40, 0x50, 0x2B, 0x1B, 0x00, 0x31, 0x40, 0x08, 0x2A, 0x0D, 0x00, 0x1C, 0x60, 0x11, 0xF3,
+	 0xFF, 0xFF, 0xE0, 0x85, 0x2B, 0x44, 0x07, 0x04, 0x70, 0x45, 0xC4, 0x84, 0xEF, 0x60, 0xFF, 0x65,
+	 0x29, 0x44, 0x24, 0x89, 0x11, 0x00, 0x2B, 0x44, 0x70, 0x45, 0xC4, 0x84, 0xFF, 0xFF, 0x04, 0x24,
+	 0x00, 0xB4, 0x40, 0x4B, 0xEF, 0x60, 0xFF, 0x65, 0x29, 0x44, 0x24, 0x89, 0x37, 0xF3, 0x2B, 0x45,
+	 0xD4, 0x80, 0xFF, 0xFF, 0x02, 0x28, 0x65, 0x44, 0x60, 0x50, 0xA0, 0x4C, 0x20, 0xBC, 0xFF, 0xB4,
+	 0xA0, 0x51, 0x00, 0x60, 0x2E, 0x7C, 0x74, 0x44, 0xC0, 0x94, 0x32, 0x40, 0x02, 0x2A, 0x19, 0x00,
+	 0x28, 0x44, 0xA4, 0x36, 0x03, 0x00, 0x0C, 0xB4, 0x04, 0x36, 0x13, 0x00, 0x26, 0x43, 0xFD, 0xB3,
+	 0x04, 0xBB, 0x43, 0x46, 0x01, 0x2A, 0x03, 0x00, 0x28, 0x47, 0x40, 0xBF, 0x40, 0x48, 0x0A, 0xBB,
+	 0x0F, 0xFC, 0x50, 0x4B, 0x67, 0x50, 0x00, 0x64, 0x30, 0xFB, 0x05, 0xFF, 0xAD, 0x60, 0x4F, 0x78,
+	 0xFF, 0xFF, 0x24, 0x64, 0x3A, 0xDB, 0x28, 0x44, 0x04, 0x2A, 0x03, 0x00, 0xA3, 0x60, 0xE7, 0x78,
+	 0xFF, 0xFF, 0x32, 0x40, 0x04, 0x2A, 0x1C, 0x00, 0x28, 0x44, 0x0C, 0xB0, 0x08, 0x3A, 0x18, 0x00,
+	 0x2C, 0xF0, 0x22, 0xF0, 0x64, 0x40, 0x01, 0x26, 0x0B, 0x00, 0x64, 0x40, 0x40, 0x2B, 0x10, 0x00,
+	 0x8F, 0xB0, 0x88, 0x3A, 0x0D, 0x00, 0x39, 0xF2, 0xFF, 0xFF, 0x60, 0xB0, 0x20, 0x3A, 0x08, 0x00,
+	 0x26, 0x44, 0xFD, 0xB4, 0x04, 0xBC, 0x40, 0x46, 0xFC, 0xB4, 0x0F, 0xFA, 0x05, 0xFF, 0x01, 0x00,
+	 0x1D, 0xFF, 0x01, 0xE2, 0x26, 0x40, 0x10, 0x2A, 0x06, 0x00, 0x2C, 0x60, 0xEA, 0x64, 0xF1, 0x60,
+	 0x78, 0x41, 0xE4, 0x78, 0xB5, 0xF1, 0xA3, 0x60, 0xE7, 0x78, 0xFF, 0xFF, 0x03, 0x0A, 0xA3, 0x60,
+	 0xF4, 0x78, 0xFF, 0xFF, 0x01, 0x64, 0x51, 0xFB, 0x1B, 0x60, 0xEE, 0xF3, 0xFF, 0xFF, 0x04, 0x18,
+	 0xAE, 0x4F, 0x08, 0xBC, 0x00, 0x7F, 0xA0, 0x5E, 0xE1, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x81, 0x3E,
+	 0x54, 0x62, 0x22, 0x46, 0xA2, 0xD0, 0x16, 0x63, 0x7C, 0x41, 0x44, 0x48, 0x80, 0x36, 0x04, 0x61,
+	 0x28, 0x40, 0x50, 0x36, 0x04, 0x61, 0x41, 0x4E, 0x28, 0x44, 0xA4, 0x36, 0x0E, 0x63, 0x9A, 0xFF,
+	 0xA1, 0xFF, 0x19, 0x60, 0xA3, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x2A, 0x06, 0x00, 0x3D, 0xF2,
+	 0xAA, 0xF0, 0xFF, 0xFF, 0xB4, 0x84, 0x08, 0x36, 0x2A, 0xFA, 0x12, 0x74, 0xCD, 0xE2, 0x54, 0x62,
+	 0xA2, 0xD2, 0xFF, 0xFF, 0x6A, 0x40, 0x80, 0x4E, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4,
+	 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4,
+	 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0xFF, 0xFF, 0x01, 0x1D, 0xB2, 0x00, 0x7A, 0xD4, 0x12, 0x74,
+	 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x28, 0x40, 0x03, 0x2B,
+	 0x06, 0x00, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x70, 0x62,
+	 0x28, 0x44, 0x8F, 0xB0, 0x88, 0x3A, 0x02, 0x00, 0x7A, 0xD4, 0x12, 0x74, 0x28, 0x40, 0x40, 0x2B,
+	 0x16, 0x00, 0x72, 0x62, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD2, 0x12, 0x74, 0x80, 0x4C, 0x20, 0x2B,
+	 0x05, 0x00, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x22, 0xF2, 0xFF, 0xFF,
+	 0x60, 0x40, 0x10, 0x26, 0x04, 0x00, 0x26, 0x26, 0x4D, 0x00, 0x26, 0x27, 0x4B, 0x00, 0x23, 0x43,
+	 0xFF, 0xFF, 0x06, 0x1D, 0x2E, 0x1E, 0x00, 0x00, 0x03, 0xF0, 0x04, 0xF4, 0x64, 0x42, 0x3D, 0x00,
+	 0x2E, 0x40, 0x04, 0x2A, 0x27, 0x00, 0xA1, 0xFF, 0x02, 0xFE, 0x10, 0x25, 0x42, 0xFE, 0x12, 0x74,
+	 0x72, 0x45, 0x65, 0x4C, 0xB2, 0xF3, 0x03, 0x04, 0xE4, 0xE2, 0xDC, 0x84, 0xB2, 0xFB, 0xA1, 0xFF,
+	 0x12, 0x74, 0x80, 0x4C, 0x12, 0x74, 0xB3, 0xF3, 0x02, 0x04, 0xDC, 0x84, 0xB3, 0xFB, 0x80, 0x4C,
+	 0x12, 0x74, 0xB4, 0xF3, 0x02, 0x04, 0xDC, 0x84, 0xB4, 0xFB, 0x80, 0x4C, 0x12, 0x74, 0x5C, 0x4E,
+	 0xF8, 0xA3, 0x03, 0xF2, 0x9A, 0xF2, 0x04, 0xF4, 0xFF, 0xB1, 0xF8, 0xA1, 0x06, 0xA4, 0x60, 0x42,
+	 0x0A, 0x00, 0x4E, 0x00, 0x03, 0xF2, 0x9A, 0xF2, 0x04, 0xF4, 0xC8, 0x82, 0xFF, 0xB1, 0x03, 0x00,
+	 0x00, 0xF4, 0x81, 0xF2, 0xFF, 0xB1, 0x7A, 0xD4, 0x12, 0x74, 0xFD, 0x1C, 0xF9, 0x1D, 0xFF, 0xB1,
+	 0x1B, 0x1E, 0x02, 0x02, 0x00, 0xF4, 0xDA, 0x82, 0xDA, 0x82, 0xA2, 0xD2, 0xA1, 0xFF, 0x09, 0x74,
+	 0x60, 0x4D, 0x12, 0x00, 0x03, 0xF2, 0x9A, 0xF2, 0x04, 0xF4, 0x23, 0x43, 0xA1, 0xFF, 0x12, 0x74,
+	 0xA0, 0xD2, 0xFE, 0xA1, 0xCB, 0x83, 0x60, 0x4E, 0xAF, 0x83, 0x03, 0x1D, 0x05, 0x03, 0x12, 0x74,
+	 0xEB, 0x01, 0xA1, 0xFF, 0x12, 0x74, 0xDF, 0x01, 0x12, 0x74, 0xDA, 0x83, 0x66, 0x44, 0x22, 0x46,
+	 0x0C, 0xFA, 0x22, 0xF2, 0x0B, 0xFC, 0x28, 0x40, 0x40, 0x2B, 0x1A, 0x00, 0x10, 0x26, 0x04, 0x00,
+	 0x26, 0x26, 0x0F, 0x00, 0x26, 0x27, 0x0D, 0x00, 0x00, 0xF4, 0x02, 0x62, 0xA1, 0xFF, 0x12, 0x74,
+	 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74, 0x7A, 0xD4, 0x12, 0x74,
+	 0x07, 0x00, 0xA1, 0xFF, 0x12, 0x74, 0x9C, 0x4E, 0x12, 0x74, 0x9C, 0x4C, 0x12, 0x74, 0x00, 0x00,
+	 0x88, 0xFF, 0xA1, 0xFF, 0xB2, 0x60, 0x58, 0x4F, 0x2D, 0x78, 0xFF, 0xFF, 0x01, 0x60, 0x18, 0xE1,
+	 0x78, 0x44, 0x02, 0xA4, 0x35, 0xFB, 0xCC, 0x00, 0x29, 0x44, 0xF7, 0xB4, 0x40, 0x49, 0x34, 0x64,
+	 0x3A, 0xDB, 0x44, 0xE1, 0xA5, 0x60, 0x54, 0x78, 0xFF, 0xFF, 0x00, 0x6B, 0xBC, 0xFF, 0x15, 0xF3,
+	 0xFF, 0xFF, 0xDC, 0x84, 0x15, 0xFB, 0x78, 0x5C, 0x07, 0x00, 0x78, 0x5C, 0x2F, 0x00, 0x62, 0xFF,
+	 0xFF, 0xFF, 0xA1, 0xFF, 0x98, 0xFF, 0x80, 0x3E, 0x80, 0x60, 0x01, 0xE0, 0xD5, 0x60, 0x84, 0xE7,
+	 0xA1, 0xF3, 0x40, 0x60, 0x60, 0x40, 0x01, 0x23, 0x48, 0x60, 0x5E, 0x65, 0x80, 0x60, 0x00, 0x6A,
+	 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x65, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x00, 0x60,
+	 0x00, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x80, 0x60, 0x00, 0x6A, 0xFF, 0xFF, 0x01, 0x16,
+	 0xFE, 0x01, 0x65, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x00, 0x60, 0x01, 0x6A, 0xFF, 0xFF,
+	 0x01, 0x16, 0xFE, 0x01, 0x95, 0x60, 0x84, 0xE7, 0x64, 0x58, 0xFF, 0xFF, 0x80, 0x60, 0x01, 0xE0,
+	 0xD5, 0x60, 0x84, 0xE7, 0xA1, 0xF3, 0x7C, 0x45, 0x60, 0x40, 0x01, 0x23, 0x02, 0x65, 0x8C, 0x60,
+	 0x48, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x00, 0x60, 0x00, 0x6A, 0xFF, 0xFF, 0x01, 0x16,
+	 0xFE, 0x01, 0x00, 0x60, 0x7F, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x84, 0x60, 0x04, 0x6A,
+	 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x48, 0x60, 0x08, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01,
+	 0x65, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x84, 0x60, 0x04, 0x6A, 0xFF, 0xFF, 0x01, 0x16,
+	 0xFE, 0x01, 0x40, 0x60, 0x08, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x65, 0x4A, 0xFF, 0xFF,
+	 0x01, 0x16, 0xFE, 0x01, 0x8C, 0x60, 0x48, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x00, 0x60,
+	 0x00, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x00, 0x60, 0x00, 0x6A, 0xFF, 0xFF, 0x01, 0x16,
+	 0xFE, 0x01, 0x95, 0x60, 0x84, 0xE7, 0x64, 0x58, 0xFF, 0xFF, 0x12, 0x74, 0x6A, 0x40, 0x87, 0x4F,
+	 0x12, 0x74, 0x87, 0x4C, 0x12, 0x74, 0x29, 0x40, 0x40, 0x2B, 0x08, 0x00, 0x0A, 0x64, 0x89, 0xFF,
+	 0x60, 0x54, 0x88, 0xFF, 0x87, 0x4D, 0x12, 0x74, 0x87, 0x4D, 0x09, 0x00, 0x03, 0x64, 0x89, 0xFF,
+	 0x60, 0x54, 0x88, 0xFF, 0x87, 0x4F, 0x12, 0x74, 0x87, 0x4D, 0x12, 0x74, 0x87, 0x4D, 0x7C, 0x44,
+	 0x01, 0x08, 0x01, 0x00, 0x67, 0x44, 0x12, 0x74, 0x87, 0x4C, 0x12, 0x74, 0x87, 0x4C, 0x12, 0x74,
+	 0x87, 0x4C, 0x12, 0x74, 0x87, 0x4D, 0x12, 0x74, 0x87, 0x4D, 0x12, 0x74, 0x87, 0x4D, 0x12, 0x74,
+	 0x04, 0x21, 0x04, 0x00, 0xFF, 0x2A, 0x01, 0x00, 0x04, 0x00, 0x03, 0x00, 0xFF, 0x2A, 0x0D, 0x00,
+	 0x0C, 0x00, 0xBC, 0xFF, 0x61, 0xFF, 0x78, 0x5C, 0x57, 0x01, 0x78, 0x5C, 0x7F, 0x01, 0xB6, 0xFF,
+	 0xB7, 0xFF, 0xB4, 0xFF, 0xC8, 0x60, 0x09, 0x7D, 0x7C, 0x4B, 0x6A, 0x44, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x04, 0x74, 0xC4, 0xE2, 0x04, 0xE1, 0x29, 0x40, 0x40, 0x2B, 0x05, 0x00, 0xA1, 0xFF, 0xFF, 0xFF,
+	 0xBC, 0xFF, 0x14, 0x74, 0x01, 0x00, 0x04, 0x74, 0xC4, 0xE2, 0x04, 0xE1, 0xBC, 0xFF, 0xB5, 0xFF,
+	 0x47, 0xFF, 0xB6, 0xFF, 0xB7, 0xFF, 0xB4, 0xFF, 0xC8, 0x60, 0x09, 0x7D, 0x7C, 0x4B, 0x29, 0x40,
+	 0x40, 0x27, 0x04, 0x00, 0xC2, 0x60, 0x58, 0x4F, 0xBA, 0x78, 0xFF, 0xFF, 0xA1, 0xFF, 0x29, 0x40,
+	 0x10, 0x26, 0x6D, 0x00, 0x80, 0x60, 0x01, 0xE0, 0xD5, 0x60, 0x84, 0xE7, 0xA1, 0xF3, 0x40, 0x60,
+	 0x60, 0x40, 0x01, 0x23, 0x48, 0x60, 0x5E, 0x65, 0x80, 0x60, 0x00, 0x6A, 0xFF, 0xFF, 0x01, 0x16,
+	 0xFE, 0x01, 0x65, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x00, 0x60, 0x00, 0x6A, 0xFF, 0xFF,
+	 0x01, 0x16, 0xFE, 0x01, 0x80, 0x60, 0x00, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x65, 0x4A,
+	 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x00, 0x60, 0x01, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01,
+	 0x95, 0x60, 0x84, 0xE7, 0x80, 0x60, 0x01, 0xE0, 0xD5, 0x60, 0x84, 0xE7, 0xA1, 0xF3, 0x7C, 0x45,
+	 0x60, 0x40, 0x01, 0x23, 0x02, 0x65, 0x8C, 0x60, 0x48, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01,
+	 0x00, 0x60, 0x00, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x00, 0x60, 0x7F, 0x6A, 0xFF, 0xFF,
+	 0x01, 0x16, 0xFE, 0x01, 0x84, 0x60, 0x04, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x48, 0x60,
+	 0x08, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x65, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01,
+	 0x84, 0x60, 0x04, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x40, 0x60, 0x08, 0x6A, 0xFF, 0xFF,
+	 0x01, 0x16, 0xFE, 0x01, 0x65, 0x4A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x8C, 0x60, 0x48, 0x6A,
+	 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x00, 0x60, 0x00, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01,
+	 0x00, 0x60, 0x00, 0x6A, 0xFF, 0xFF, 0x01, 0x16, 0xFE, 0x01, 0x95, 0x60, 0x84, 0xE7, 0x01, 0x60,
+	 0x08, 0xE1, 0xFF, 0xFF, 0xC4, 0xE2, 0x29, 0x40, 0x40, 0x2B, 0x04, 0x00, 0xC2, 0x60, 0x58, 0x4F,
+	 0xBA, 0x78, 0xFF, 0xFF, 0xC2, 0x60, 0x58, 0x4F, 0xC5, 0x78, 0xFF, 0xFF, 0xA1, 0xFF, 0xCB, 0xF3,
+	 0xC4, 0xE2, 0x89, 0xFF, 0x60, 0x54, 0x88, 0xFF, 0xDC, 0x84, 0xE0, 0x94, 0x35, 0xF7, 0xFF, 0xFF,
+	 0xFF, 0xFF, 0xFF, 0x01, 0x10, 0x61, 0x7F, 0x60, 0xC0, 0x64, 0xA0, 0x80, 0x7F, 0x67, 0x02, 0x63,
+	 0x25, 0x02, 0x98, 0xFE, 0x19, 0x05, 0x12, 0x60, 0xFC, 0xF5, 0x0E, 0xF2, 0x15, 0x18, 0x02, 0x18,
+	 0x09, 0xF4, 0xFB, 0x01, 0x23, 0x44, 0x00, 0xA8, 0x08, 0x7E, 0x0A, 0x02, 0x66, 0x44, 0x11, 0xFB,
+	 0x46, 0x43, 0x23, 0x47, 0x80, 0xBF, 0x3B, 0x42, 0x04, 0xA2, 0xA2, 0xDB, 0x28, 0xB9, 0x10, 0x7E,
+	 0x00, 0x7F, 0x0E, 0xFA, 0x00, 0x67, 0x0A, 0x00, 0x20, 0x44, 0xDC, 0x85, 0x0F, 0xB4, 0xFB, 0xA0,
+	 0x7F, 0x67, 0x07, 0x63, 0x03, 0x05, 0x45, 0x40, 0x00, 0x67, 0xD8, 0xFE, 0xFF, 0x27, 0x05, 0xFD,
+	 0x0A, 0x7E, 0x04, 0xFB, 0x61, 0x55, 0x48, 0x00, 0x28, 0xFB, 0x01, 0xF3, 0x29, 0xFB, 0x44, 0x46,
+	 0x40, 0x45, 0x10, 0x61, 0x7E, 0x60, 0xC0, 0x64, 0xA0, 0x80, 0x7F, 0x67, 0x02, 0x63, 0x30, 0x02,
+	 0xB5, 0x60, 0x58, 0x4F, 0xCE, 0x78, 0xFF, 0xFF, 0x7F, 0x67, 0x03, 0x63, 0x29, 0x02, 0x26, 0x40,
+	 0x01, 0x2B, 0x23, 0x00, 0x98, 0xFE, 0x18, 0x05, 0x12, 0x60, 0xFC, 0xF5, 0x0E, 0xF2, 0x14, 0x18,
+	 0x02, 0x18, 0x09, 0xF4, 0xFB, 0x01, 0x23, 0x44, 0x00, 0xA8, 0x08, 0x7E, 0x0A, 0x02, 0x66, 0x44,
+	 0x11, 0xFB, 0x46, 0x43, 0x23, 0x47, 0x80, 0xBF, 0x3B, 0x42, 0x04, 0xA2, 0xA2, 0xDB, 0x08, 0xB9,
+	 0x10, 0x7E, 0x00, 0x7F, 0x0E, 0xFA, 0x09, 0x00, 0x20, 0x44, 0xDC, 0x85, 0x0F, 0xB4, 0xFB, 0xA0,
+	 0x7F, 0x67, 0x07, 0x63, 0x05, 0x05, 0x45, 0x40, 0xD8, 0xFE, 0x00, 0x67, 0xD0, 0xFE, 0xD9, 0xFE,
+	 0xFF, 0x27, 0x05, 0xFD, 0x0B, 0x7E, 0x04, 0xFB, 0x0E, 0x60, 0xDD, 0xF3, 0xFF, 0xFF, 0x20, 0xB0,
+	 0x80, 0xBC, 0x08, 0x28, 0xA2, 0xDB, 0x61, 0x55, 0x66, 0x00, 0x04, 0xB5, 0x82, 0xB5, 0x25, 0x02,
+	 0x04, 0x03, 0x20, 0x44, 0x7F, 0xB4, 0x40, 0x40, 0xA3, 0xD3, 0x99, 0xFE, 0x04, 0x04, 0x02, 0xBC,
+	 0xFE, 0xB4, 0xA3, 0xDB, 0x59, 0x00, 0xDB, 0xF3, 0x20, 0x40, 0x80, 0x26, 0x55, 0x00, 0xA3, 0xD3,
+	 0xFF, 0xA0, 0xF8, 0xB4, 0x02, 0x02, 0xA3, 0xDB, 0x1C, 0x00, 0x04, 0xBC, 0xBF, 0xB4, 0xA3, 0xDB,
+	 0x08, 0xB0, 0x01, 0x64, 0x08, 0x24, 0x02, 0x64, 0x28, 0xFB, 0x20, 0x44, 0x80, 0xBC, 0x40, 0x40,
+	 0xD0, 0xFE, 0x42, 0x00, 0xBF, 0xB4, 0xA3, 0xDB, 0x3F, 0x00, 0x40, 0xB0, 0xFF, 0xFF, 0xFA, 0x02,
+	 0xF8, 0xB4, 0xA3, 0xDB, 0x08, 0xB5, 0x07, 0x7C, 0x01, 0x02, 0xDB, 0xF9, 0x20, 0x44, 0x7F, 0xB4,
+	 0x40, 0x40, 0x1D, 0x60, 0xBA, 0x63, 0xA3, 0xD3, 0xFF, 0xFF, 0x20, 0xB5, 0x07, 0xB5, 0x08, 0x28,
+	 0xC4, 0x02, 0x99, 0xFE, 0x29, 0x05, 0x20, 0x44, 0x80, 0x26, 0x26, 0x00, 0x20, 0x2A, 0x03, 0x00,
+	 0xDF, 0xB4, 0x40, 0x40, 0x74, 0x00, 0x40, 0x2A, 0x1F, 0x00, 0xBF, 0xB4, 0x40, 0x40, 0x09, 0x00,
+	 0xA8, 0xFF, 0x20, 0x44, 0x99, 0xFE, 0x02, 0x05, 0x80, 0x2A, 0x03, 0x00, 0x40, 0xBC, 0x40, 0x40,
+	 0x13, 0x00, 0x00, 0xF1, 0x80, 0xBC, 0x40, 0x40, 0x64, 0x44, 0xE0, 0x84, 0xE8, 0x84, 0x0A, 0x36,
+	 0x29, 0x01, 0x0B, 0x36, 0x59, 0x01, 0x28, 0xFB, 0x01, 0xF1, 0x29, 0xF9, 0x02, 0xF1, 0x2A, 0xF9,
+	 0x03, 0xF1, 0x2B, 0xF9, 0xD0, 0xFE, 0xAE, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0x82, 0x3E, 0x75, 0x44,
+	 0x02, 0xB0, 0x01, 0xB0, 0x54, 0x02, 0xDC, 0x02, 0x04, 0xB0, 0x08, 0xB0, 0x10, 0x02, 0x2A, 0x02,
+	 0x40, 0x26, 0xA7, 0xFF, 0x8C, 0xFF, 0x75, 0x40, 0x80, 0x2B, 0x06, 0x00, 0xAB, 0xFF, 0x19, 0x60,
+	 0xF6, 0xF3, 0xFF, 0xFF, 0xFE, 0xB4, 0xA2, 0xDB, 0x75, 0x44, 0x8D, 0xFF, 0xE5, 0x01, 0x0A, 0xF3,
+	 0xAA, 0xFF, 0x60, 0x40, 0x20, 0x2B, 0x02, 0x00, 0x38, 0xFF, 0x0D, 0x00, 0x01, 0x26, 0x0C, 0x00,
+	 0xC0, 0x60, 0x00, 0x7C, 0xA0, 0x84, 0x80, 0x3B, 0x02, 0x00, 0xC0, 0x67, 0x03, 0x00, 0x40, 0x3B,
+	 0x02, 0x00, 0x00, 0x67, 0x0A, 0xFB, 0xD0, 0x01, 0x19, 0x60, 0xF6, 0xF3, 0xFF, 0xFF, 0xFE, 0xB4,
+	 0xA2, 0xDB, 0xCA, 0x01, 0x0B, 0xF1, 0xAB, 0xFF, 0x64, 0x44, 0xFF, 0x27, 0x1F, 0x00, 0x20, 0x26,
+	 0x03, 0x00, 0x02, 0x60, 0x00, 0x75, 0x1A, 0x00, 0x19, 0xF3, 0xFF, 0xFF, 0x03, 0x1B, 0x04, 0x60,
+	 0x00, 0x75, 0x0A, 0x64, 0xCC, 0x84, 0x19, 0xFB, 0x01, 0x60, 0x00, 0x75, 0x64, 0x40, 0x03, 0x22,
+	 0x0D, 0x00, 0x20, 0x44, 0x80, 0x2A, 0x03, 0x00, 0x20, 0xBC, 0x40, 0x40, 0x07, 0x00, 0xD9, 0xFE,
+	 0x81, 0x60, 0x0B, 0x64, 0x28, 0xFB, 0x2C, 0x44, 0x29, 0xFB, 0xD0, 0xFE, 0xA5, 0x01, 0xA9, 0xFF,
+	 0x77, 0x44, 0x60, 0x57, 0x40, 0x4A, 0x01, 0x2A, 0x31, 0x00, 0x24, 0x44, 0xAC, 0x86, 0x08, 0xF2,
+	 0x2D, 0x03, 0x25, 0x60, 0xFE, 0x65, 0xD4, 0x80, 0x0E, 0xF2, 0x02, 0x03, 0xA5, 0xD5, 0x04, 0x00,
+	 0x01, 0xBC, 0x0E, 0xFA, 0x09, 0xF4, 0xD1, 0xFE, 0x46, 0x44, 0x11, 0x1B, 0x32, 0x40, 0x80, 0x2A,
+	 0x1D, 0x00, 0x9D, 0xFE, 0x1B, 0x05, 0x13, 0x60, 0x02, 0xF3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46,
+	 0x03, 0x03, 0x0F, 0xF2, 0xFF, 0xFF, 0x12, 0x1B, 0x08, 0x60, 0x00, 0x75, 0x0F, 0x00, 0x3F, 0xF2,
+	 0x48, 0x65, 0xC4, 0x84, 0x13, 0xFB, 0x66, 0x44, 0x10, 0xFB, 0x66, 0x47, 0x20, 0xBF, 0x3B, 0x42,
+	 0x04, 0xA2, 0xA2, 0xDB, 0x0E, 0xF2, 0x41, 0x75, 0x10, 0xBC, 0x0E, 0xFA, 0x2A, 0x44, 0x08, 0x2A,
+	 0x17, 0x00, 0x23, 0x44, 0x00, 0xA8, 0x5C, 0x43, 0x13, 0x03, 0x12, 0x60, 0xFC, 0xF5, 0x01, 0x00,
+	 0x09, 0xF4, 0x0E, 0xF2, 0x0D, 0x18, 0x08, 0xB0, 0x18, 0xAC, 0xFA, 0x03, 0x0E, 0xFA, 0x66, 0x43,
+	 0x11, 0xFD, 0x46, 0x43, 0x23, 0x47, 0x80, 0xBF, 0x3B, 0x42, 0x04, 0xA2, 0xA2, 0xDB, 0x28, 0x75,
+	 0x2A, 0x44, 0x06, 0x22, 0x2D, 0x00, 0x22, 0x44, 0x00, 0xA8, 0x60, 0x46, 0x0E, 0xF2, 0x28, 0x03,
+	 0x10, 0xB0, 0x01, 0xBC, 0x03, 0x02, 0x00, 0x64, 0x40, 0x42, 0x22, 0x00, 0x0E, 0xFA, 0xD1, 0xFE,
+	 0x25, 0x60, 0xF2, 0x64, 0x40, 0x47, 0x58, 0x4F, 0x94, 0x00, 0x46, 0x42, 0x19, 0x02, 0x22, 0x47,
+	 0x40, 0xBF, 0x3B, 0x42, 0x04, 0xA2, 0xA2, 0xDB, 0x23, 0xF2, 0x66, 0x43, 0x00, 0xA8, 0x0E, 0xF2,
+	 0x08, 0x02, 0x60, 0x40, 0x02, 0x2A, 0xE4, 0x01, 0x12, 0xFD, 0x10, 0x64, 0x0E, 0xFA, 0x02, 0x75,
+	 0x07, 0x00, 0x60, 0x40, 0x04, 0x2A, 0xDC, 0x01, 0x12, 0xFD, 0x10, 0x64, 0x0E, 0xFA, 0x04, 0x75,
+	 0x2A, 0x44, 0x80, 0x2A, 0x19, 0x00, 0x21, 0x44, 0xAC, 0x86, 0x0E, 0xF2, 0x15, 0x03, 0x01, 0xBC,
+	 0x0E, 0xFA, 0xD1, 0xFE, 0x26, 0x60, 0x0A, 0x64, 0x40, 0x47, 0x58, 0x4F, 0x6A, 0x00, 0x46, 0x41,
+	 0x0B, 0x02, 0x21, 0x47, 0x10, 0xBF, 0x3B, 0x42, 0x04, 0xA2, 0xA2, 0xDB, 0x0E, 0xF2, 0x66, 0x43,
+	 0x08, 0xFD, 0x10, 0xBC, 0x0E, 0xFA, 0x80, 0x75, 0x2A, 0x44, 0x10, 0xB0, 0x20, 0x44, 0x18, 0x03,
+	 0x7F, 0xB4, 0x40, 0x40, 0x1D, 0x60, 0xBA, 0x63, 0xA3, 0xD3, 0xFF, 0xFF, 0x20, 0xB0, 0x80, 0xB0,
+	 0x09, 0x03, 0x08, 0x03, 0x40, 0xBC, 0x7F, 0xB4, 0x04, 0xB0, 0xA3, 0xDB, 0x03, 0x03, 0x20, 0x44,
+	 0x80, 0xBC, 0x40, 0x40, 0x2A, 0x40, 0x08, 0x27, 0x03, 0x00, 0xB3, 0x60, 0xC9, 0x78, 0xFF, 0xFF,
+	 0x2A, 0x40, 0x08, 0x2B, 0x0F, 0x00, 0x32, 0x40, 0x80, 0x26, 0x05, 0x00, 0x19, 0x60, 0xF7, 0xF3,
+	 0xFF, 0xFF, 0x01, 0x1B, 0x07, 0x00, 0x19, 0x60, 0xF6, 0xF3, 0xFF, 0xFF, 0x01, 0xBC, 0xA2, 0xDB,
+	 0xFF, 0xFF, 0x10, 0xFF, 0xB3, 0x60, 0xFC, 0x78, 0xFF, 0xFF, 0xE8, 0xFE, 0x14, 0x05, 0xEA, 0xFE,
+	 0x23, 0x05, 0xE9, 0xFE, 0x1C, 0x05, 0xE7, 0xFE, 0x09, 0x05, 0x47, 0xFF, 0x20, 0x44, 0x0F, 0x22,
+	 0x03, 0x00, 0xCC, 0x84, 0x40, 0x40, 0x0F, 0x22, 0xB8, 0xFE, 0xEC, 0x01, 0x23, 0x41, 0x00, 0xB9,
+	 0x5C, 0x4A, 0xE8, 0x02, 0x5A, 0x01, 0x24, 0x41, 0x00, 0xB9, 0x25, 0x60, 0xFE, 0x65, 0x45, 0x47,
+	 0xE1, 0x02, 0x58, 0x4F, 0x0E, 0x00, 0xDE, 0x02, 0x5C, 0x4A, 0x46, 0x44, 0x38, 0x01, 0x22, 0x41,
+	 0x00, 0xB9, 0x5C, 0x4A, 0xD7, 0x02, 0x6C, 0x01, 0x21, 0x41, 0x00, 0xB9, 0x5C, 0x4A, 0x92, 0x03,
+	 0xD1, 0x01, 0x27, 0xD3, 0x03, 0x00, 0x10, 0xB0, 0x09, 0xF2, 0x04, 0x03, 0xAC, 0x86, 0x0E, 0xF2,
+	 0xFA, 0x02, 0x08, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x0E, 0xF3, 0x0F, 0x60, 0xFE, 0x65, 0x0C, 0xF3,
+	 0x24, 0x86, 0x24, 0x46, 0x60, 0x40, 0xFB, 0x3B, 0x07, 0x00, 0x80, 0x26, 0x02, 0x00, 0x23, 0x46,
+	 0x03, 0x4C, 0x46, 0x61, 0x3A, 0x65, 0x0C, 0x00, 0x2E, 0xF3, 0x40, 0x45, 0xF8, 0x2B, 0x02, 0x00,
+	 0x40, 0x45, 0x03, 0x00, 0x58, 0x4F, 0x5A, 0x00, 0x07, 0x02, 0x58, 0x4F, 0x66, 0x00, 0x04, 0x05,
+	 0x66, 0x50, 0x65, 0x52, 0x61, 0x51, 0x09, 0x00, 0x26, 0x47, 0x00, 0xBF, 0x0E, 0xFB, 0x2E, 0xF5,
+	 0x05, 0xF0, 0x80, 0x60, 0x64, 0x50, 0x00, 0x72, 0x7E, 0x71, 0xAC, 0xFF, 0x31, 0x40, 0x01, 0x2A,
+	 0x08, 0x00, 0x19, 0x60, 0xF2, 0xF3, 0xFF, 0xFF, 0x04, 0x18, 0x0C, 0x64, 0x13, 0x60, 0x13, 0xFB,
+	 0x2D, 0xFF, 0xB3, 0x60, 0xFC, 0x78, 0xFF, 0xFF, 0x8E, 0xFF, 0x0F, 0xF3, 0x0F, 0x60, 0xFE, 0x65,
+	 0x24, 0x86, 0x0D, 0xF3, 0x24, 0x46, 0x60, 0x40, 0xFB, 0x3B, 0x07, 0x00, 0x80, 0x26, 0x02, 0x00,
+	 0x23, 0x46, 0x03, 0x4C, 0x46, 0x61, 0x3A, 0x65, 0x0C, 0x00, 0x2E, 0xF3, 0x40, 0x45, 0xF8, 0x2B,
+	 0x02, 0x00, 0x40, 0x45, 0x03, 0x00, 0x58, 0x4F, 0x21, 0x00, 0x07, 0x02, 0x58, 0x4F, 0x2D, 0x00,
+	 0x04, 0x05, 0x66, 0x50, 0x65, 0x52, 0x61, 0x51, 0x09, 0x00, 0x26, 0x47, 0x00, 0xBF, 0x0F, 0xFB,
+	 0x2E, 0xF5, 0x05, 0xF0, 0x80, 0x60, 0x64, 0x50, 0x00, 0x72, 0x7E, 0x71, 0x8D, 0xFF, 0xAD, 0xFF,
+	 0x31, 0x40, 0x01, 0x2A, 0xCE, 0x01, 0x19, 0x60, 0xF2, 0xF3, 0xFF, 0xFF, 0x04, 0x18, 0x0C, 0x64,
+	 0x13, 0x60, 0x13, 0xFB, 0x2D, 0xFF, 0xB3, 0x60, 0xFC, 0x78, 0xFF, 0xFF, 0x25, 0x44, 0xA7, 0xF1,
+	 0xA8, 0xF1, 0xD0, 0x80, 0xD0, 0x80, 0x07, 0x04, 0x01, 0x06, 0x05, 0x00, 0x25, 0x46, 0x01, 0xF0,
+	 0x03, 0x67, 0xA0, 0x85, 0x94, 0x80, 0x2F, 0x58, 0xFF, 0xFF, 0x25, 0x46, 0x26, 0x41, 0x46, 0x63,
+	 0x01, 0xF2, 0xFF, 0xFF, 0xFF, 0xB5, 0xD5, 0x81, 0x00, 0xF2, 0x05, 0x04, 0x04, 0x63, 0x60, 0x46,
+	 0xF7, 0x1B, 0x42, 0xFE, 0x0D, 0x00, 0x61, 0x44, 0xC5, 0x81, 0x63, 0x45, 0xC5, 0x81, 0x9C, 0x84,
+	 0xDC, 0x84, 0x01, 0xF2, 0xF0, 0x85, 0xF0, 0x80, 0x65, 0x44, 0xF8, 0x85, 0xFF, 0xFF, 0x02, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0xA2, 0xFF, 0x13, 0x60, 0x08, 0xF3, 0xFF, 0xFF, 0xAC, 0x86, 0x0E, 0xF2,
+	 0x07, 0x03, 0x00, 0xA8, 0x09, 0xF2, 0xFA, 0x02, 0x01, 0x67, 0x0E, 0xFA, 0x08, 0xFE, 0x17, 0x00,
+	 0xA9, 0xF3, 0xFF, 0xFF, 0xD8, 0xA0, 0x00, 0xB4, 0x12, 0x06, 0x09, 0x60, 0x08, 0x61, 0x41, 0x4A,
+	 0x7C, 0xA1, 0x0E, 0xA1, 0xA2, 0xFF, 0xB6, 0x60, 0x58, 0x4E, 0x44, 0x78, 0xFF, 0xFF, 0xA3, 0xFF,
+	 0x06, 0x03, 0x2A, 0x43, 0xB6, 0x60, 0x58, 0x4E, 0x65, 0x78, 0xFF, 0xFF, 0x08, 0xFE, 0xA3, 0xFF,
+	 0x2D, 0x58, 0xFF, 0xFF, 0x41, 0x4A, 0x42, 0xA1, 0x03, 0x00, 0x41, 0x4A, 0x7C, 0xA1, 0x0E, 0xA1,
+	 0xA2, 0xFF, 0xB6, 0x60, 0x58, 0x4E, 0x44, 0x78, 0xFF, 0xFF, 0x07, 0x03, 0x2A, 0x43, 0xB6, 0x60,
+	 0x58, 0x4E, 0x65, 0x78, 0xFF, 0xFF, 0x08, 0xFE, 0x0C, 0x00, 0x13, 0x60, 0x08, 0xF3, 0xFF, 0xFF,
+	 0xAC, 0x86, 0x0E, 0xF2, 0x06, 0x03, 0x00, 0xA8, 0x09, 0xF2, 0xFA, 0x02, 0x01, 0x67, 0x0E, 0xFA,
+	 0x08, 0xFE, 0xA3, 0xFF, 0x2D, 0x58, 0xFF, 0xFF, 0xAA, 0xF3, 0x7C, 0x63, 0x00, 0xBE, 0x40, 0x45,
+	 0x1A, 0x03, 0x00, 0x65, 0x65, 0x44, 0xDC, 0x85, 0x84, 0xA1, 0x00, 0xF2, 0x06, 0x06, 0x01, 0xFC,
+	 0x00, 0xA8, 0x60, 0x46, 0xF7, 0x02, 0x40, 0x45, 0x0E, 0x00, 0xA9, 0xF3, 0x00, 0x63, 0xD4, 0x84,
+	 0xA9, 0xFB, 0x80, 0x60, 0x7C, 0x64, 0x01, 0xFA, 0x00, 0xF0, 0x00, 0xFC, 0xD3, 0x80, 0xAA, 0xF9,
+	 0x02, 0x02, 0xAB, 0xF9, 0x08, 0xFE, 0x2E, 0x58, 0xFF, 0xFF, 0x66, 0x44, 0x25, 0x46, 0x05, 0xFA,
+	 0x06, 0xFA, 0x01, 0xF0, 0x03, 0x67, 0x02, 0xFC, 0xB0, 0x84, 0x3A, 0x7E, 0x01, 0xFA, 0x12, 0x64,
+	 0x03, 0xFA, 0x00, 0xF0, 0x04, 0xF8, 0x00, 0x64, 0x0C, 0x61, 0x10, 0x63, 0x59, 0xDA, 0xFE, 0x1F,
+	 0x2E, 0x58, 0xFF, 0xFF, 0x27, 0x43, 0xE3, 0x81, 0xE9, 0x81, 0x03, 0x05, 0x16, 0x03, 0x00, 0x61,
+	 0x01, 0x00, 0xEC, 0x63, 0x61, 0x46, 0xBF, 0xD2, 0x27, 0x45, 0xDC, 0x84, 0xA2, 0xDA, 0xBE, 0xD2,
+	 0x25, 0x46, 0x88, 0xF8, 0x04, 0x1B, 0x25, 0x44, 0x61, 0x46, 0xA3, 0xDA, 0x04, 0x00, 0x0A, 0xFA,
+	 0x60, 0x46, 0x25, 0x44, 0x09, 0xFA, 0x61, 0x46, 0xBE, 0xDA, 0x2F, 0x58, 0xFF, 0xFF, 0x25, 0x44,
+	 0x00, 0xA8, 0x07, 0x4B, 0x0C, 0x03, 0x58, 0x4F, 0x33, 0x00, 0x0B, 0x47, 0x26, 0x60, 0x04, 0x65,
+	 0x27, 0x44, 0xD4, 0x80, 0x00, 0x64, 0x01, 0x02, 0x0F, 0xFA, 0x58, 0x4F, 0xD3, 0x01, 0x70, 0x00,
+	 0x25, 0x43, 0xE3, 0x84, 0x7C, 0x41, 0x02, 0x04, 0xE8, 0x81, 0xEC, 0x63, 0x61, 0x46, 0xA3, 0xD2,
+	 0x00, 0x7C, 0x40, 0x45, 0xBF, 0xD8, 0xA3, 0xD8, 0xBE, 0xD8, 0x27, 0x42, 0x5A, 0xD3, 0x25, 0x5C,
+	 0x60, 0x41, 0x02, 0x1B, 0x27, 0xD9, 0x05, 0x00, 0x25, 0x46, 0x0A, 0xFA, 0x61, 0x46, 0x25, 0x44,
+	 0x09, 0xFA, 0x25, 0x44, 0x27, 0x43, 0x00, 0x61, 0x60, 0x46, 0x09, 0xF2, 0x08, 0xFC, 0x00, 0xA8,
+	 0xDD, 0x81, 0xFA, 0x02, 0xBF, 0xD1, 0x66, 0x44, 0xBE, 0xDB, 0xC1, 0x84, 0xBF, 0xDB, 0x48, 0x00,
+	 0x25, 0x46, 0xEC, 0x63, 0x08, 0xF2, 0x89, 0xF2, 0x1E, 0x18, 0x40, 0x47, 0xE0, 0x84, 0xE8, 0x85,
+	 0x02, 0x05, 0xE8, 0x83, 0x00, 0x65, 0x65, 0x46, 0xBF, 0xD2, 0x61, 0x5C, 0xCC, 0x84, 0xA2, 0xDA,
+	 0x25, 0x46, 0x0A, 0xF2, 0x00, 0xB9, 0x65, 0x46, 0x08, 0x24, 0xBE, 0xDA, 0x02, 0x1B, 0xA3, 0xD8,
+	 0x02, 0x00, 0x60, 0x46, 0x89, 0xFA, 0x00, 0xB9, 0x61, 0x46, 0x08, 0x28, 0x0A, 0xFA, 0x25, 0x46,
+	 0x89, 0xFC, 0x8A, 0xFC, 0x88, 0xFC, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x61, 0x28, 0x65, 0x25, 0x43,
+	 0xAB, 0xF3, 0xAF, 0x83, 0x00, 0xBE, 0x18, 0x03, 0x02, 0x03, 0x00, 0xFC, 0x01, 0x00, 0xAA, 0xFD,
+	 0x63, 0x46, 0x65, 0x44, 0xCC, 0x85, 0x00, 0xF2, 0x07, 0x02, 0xAB, 0xF5, 0x00, 0x64, 0x00, 0xFA,
+	 0xDE, 0x60, 0xAF, 0x64, 0x09, 0xFB, 0x08, 0x00, 0x66, 0x43, 0x00, 0xBE, 0xDD, 0x81, 0xF1, 0x02,
+	 0xA9, 0xF1, 0xAB, 0xFD, 0xC1, 0x84, 0xA9, 0xFB, 0x2E, 0x58, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x45,
+	 0x29, 0x43, 0xFC, 0xA3, 0x66, 0x44, 0xBD, 0xDB, 0x25, 0x44, 0xBD, 0xDB, 0x00, 0x64, 0xBD, 0xDB,
+	 0x03, 0x61, 0x0E, 0x65, 0x26, 0x60, 0x18, 0x63, 0x43, 0x49, 0xA3, 0xD3, 0x06, 0xA3, 0x00, 0xA8,
+	 0xCD, 0x81, 0x04, 0x02, 0xF9, 0x02, 0xB3, 0x60, 0xFC, 0x78, 0xFF, 0xFF, 0x01, 0x26, 0xE6, 0x01,
+	 0xD4, 0x80, 0x60, 0x45, 0xE3, 0x05, 0xF6, 0xA3, 0xBD, 0xD1, 0xBD, 0xD1, 0x44, 0x47, 0x44, 0x48,
+	 0x44, 0x45, 0x26, 0x60, 0x5A, 0x64, 0x44, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0x25, 0x60, 0xC8, 0x63,
+	 0x0D, 0x65, 0x00, 0x61, 0x41, 0x48, 0xA3, 0xD3, 0x06, 0xA3, 0xAC, 0x86, 0x00, 0x61, 0x09, 0x03,
+	 0x00, 0xF2, 0x09, 0xF0, 0xAC, 0x86, 0x00, 0xF2, 0xDD, 0x81, 0xFC, 0x02, 0x64, 0x44, 0xAC, 0x86,
+	 0xF6, 0x01, 0x61, 0x44, 0x25, 0x46, 0x27, 0xDA, 0x65, 0x44, 0x28, 0x45, 0x45, 0x88, 0xCC, 0x85,
+	 0x5A, 0x87, 0xE9, 0x02, 0x00, 0x64, 0x27, 0xDA, 0x5A, 0xDA, 0x5A, 0x87, 0xA6, 0xF3, 0xA5, 0xF1,
+	 0x02, 0xA4, 0x60, 0x46, 0x60, 0x45, 0x00, 0x61, 0x22, 0xF2, 0xFF, 0xFF, 0xAC, 0x86, 0x00, 0xF2,
+	 0x04, 0x03, 0xAC, 0x86, 0x00, 0xF2, 0xDD, 0x81, 0xFC, 0x02, 0x65, 0x44, 0x02, 0xA5, 0x65, 0x46,
+	 0x64, 0x44, 0xCC, 0x9C, 0xFF, 0xFF, 0xF0, 0x02, 0x61, 0x44, 0x25, 0x46, 0x27, 0xDA, 0x5A, 0x87,
+	 0x28, 0x45, 0x45, 0x88, 0x00, 0x64, 0x27, 0xDA, 0x5A, 0x87, 0x06, 0x60, 0x40, 0x65, 0xAA, 0xF3,
+	 0x01, 0x61, 0xAC, 0x86, 0x00, 0xF2, 0x03, 0x03, 0xD5, 0x80, 0xDD, 0x81, 0xFA, 0x04, 0xCD, 0x84,
+	 0x25, 0x46, 0x27, 0xDA, 0x28, 0x45, 0xC4, 0x84, 0x5A, 0xDA, 0xDA, 0x81, 0xA9, 0xF1, 0x59, 0xD8,
+	 0x25, 0x60, 0xC6, 0x64, 0x18, 0x63, 0xA0, 0xD1, 0x06, 0xA4, 0x59, 0xD8, 0xFC, 0x1F, 0x00, 0x64,
+	 0x59, 0xDA, 0x59, 0xDA, 0x01, 0x60, 0x56, 0x64, 0x0A, 0x63, 0x58, 0xD1, 0x59, 0xD8, 0xFD, 0x1F,
+	 0xDB, 0xF1, 0x59, 0xD8, 0x75, 0x01, 0x07, 0x4B, 0xB6, 0x60, 0x58, 0x4F, 0xD0, 0x78, 0xFF, 0xFF,
+	 0x0B, 0x47, 0x58, 0x4F, 0x21, 0x00, 0x6C, 0x01, 0x07, 0x4B, 0xB6, 0x60, 0x58, 0x4F, 0xD0, 0x78,
+	 0xFF, 0xFF, 0x0B, 0x47, 0x27, 0x44, 0x00, 0xBE, 0x08, 0xF0, 0x15, 0x03, 0x64, 0x42, 0x4A, 0xD3,
+	 0x09, 0xF2, 0xDC, 0x83, 0xA2, 0xDD, 0x25, 0x43, 0x09, 0xFC, 0x63, 0x46, 0x27, 0x43, 0x0A, 0xFC,
+	 0x09, 0xFA, 0x08, 0xF8, 0x00, 0xA8, 0x66, 0x43, 0x03, 0x02, 0x64, 0x44, 0x58, 0xDD, 0x03, 0x00,
+	 0x60, 0x46, 0x25, 0x44, 0x0A, 0xFA, 0x4C, 0x01, 0x27, 0x43, 0xE3, 0x81, 0xE9, 0x81, 0x03, 0x05,
+	 0x16, 0x03, 0x00, 0x61, 0x01, 0x00, 0xEC, 0x63, 0x61, 0x46, 0xBF, 0xD2, 0x27, 0x45, 0xDC, 0x84,
+	 0xA2, 0xDA, 0xA3, 0xD2, 0x25, 0x46, 0x88, 0xF8, 0x04, 0x1B, 0x25, 0x44, 0x61, 0x46, 0xBE, 0xDA,
+	 0x04, 0x00, 0x09, 0xFA, 0x60, 0x46, 0x25, 0x44, 0x0A, 0xFA, 0x61, 0x46, 0xA3, 0xDA, 0x2F, 0x58,
+	 0xFF, 0xFF, 0xA0, 0xFE, 0x07, 0x05, 0xA3, 0xFE, 0x07, 0x05, 0xA1, 0xFE, 0x48, 0x05, 0x60, 0x64,
+	 0x3B, 0xDB, 0x11, 0x00, 0x20, 0x58, 0xFF, 0xFF, 0x4F, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0x0E, 0x60,
+	 0xDF, 0xF3, 0xFF, 0xFF, 0xFB, 0xB4, 0xA2, 0xDB, 0xA0, 0x4C, 0x59, 0xBC, 0xFF, 0xB4, 0xA0, 0x51,
+	 0xA0, 0x4C, 0x7D, 0xB4, 0xA0, 0x51, 0xA1, 0xFF, 0xFF, 0xFF, 0x83, 0x3E, 0x40, 0x60, 0x0B, 0x65,
+	 0x2B, 0x44, 0x00, 0x63, 0xE8, 0x80, 0xF8, 0x84, 0x02, 0x24, 0x94, 0x84, 0xF3, 0x83, 0xCD, 0x81,
+	 0xFF, 0xFF, 0xF8, 0x02, 0xDF, 0x83, 0x2F, 0x58, 0x40, 0x4B, 0x00, 0x62, 0x01, 0x64, 0xD4, 0x80,
+	 0xE0, 0x84, 0x1A, 0x03, 0xD4, 0x80, 0xE0, 0x84, 0x15, 0x03, 0x61, 0x44, 0x11, 0x61, 0xE0, 0x84,
+	 0xCD, 0x81, 0xFD, 0x04, 0x01, 0x00, 0xE0, 0x84, 0xF2, 0x82, 0xFF, 0xFF, 0x02, 0x24, 0xC6, 0x82,
+	 0x02, 0x28, 0xD6, 0x82, 0xE2, 0x80, 0xCD, 0x81, 0x02, 0x28, 0x01, 0xBC, 0xF4, 0x02, 0x01, 0x2A,
+	 0xC6, 0x82, 0x03, 0x00, 0xE9, 0x81, 0xF2, 0x82, 0x61, 0x44, 0x2D, 0x58, 0xFF, 0xFF, 0x00, 0x64,
+	 0x3B, 0xDB, 0x3C, 0x44, 0xAC, 0x80, 0xFF, 0xFF, 0xC6, 0x02, 0x89, 0xF3, 0x8A, 0xF3, 0x02, 0xA8,
+	 0x02, 0xA8, 0x08, 0x02, 0x00, 0x64, 0x8B, 0xFB, 0x89, 0xFB, 0x8A, 0xFB, 0x00, 0x64, 0x8C, 0xFB,
+	 0xCA, 0xFE, 0x2A, 0x00, 0x03, 0x02, 0x00, 0x64, 0x8A, 0xFB, 0xCA, 0xFE, 0x01, 0x64, 0x3B, 0xDB,
+	 0x12, 0x60, 0xE7, 0xF3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x13, 0x03, 0xDB, 0xF3, 0x2A, 0xF2,
+	 0xFD, 0xA0, 0x60, 0x40, 0x80, 0x3A, 0x33, 0x00, 0x32, 0x02, 0x9B, 0xFE, 0x30, 0x05, 0x00, 0x64,
+	 0x13, 0x60, 0x0A, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0xE7, 0x01, 0x8A, 0xF3, 0xFF, 0xFF, 0x01, 0xA8, 0xFF, 0xFF, 0x06, 0x02, 0x12, 0x60, 0xE4, 0xF3,
+	 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x1B, 0x02, 0x86, 0xFF, 0x20, 0x40, 0x12, 0x27, 0x13, 0x00,
+	 0x9A, 0xFE, 0x11, 0x04, 0x9D, 0xFE, 0x0F, 0x04, 0x95, 0xF3, 0xFF, 0xFF, 0x80, 0xBC, 0x95, 0xFB,
+	 0x84, 0xFF, 0xC2, 0x60, 0x45, 0x64, 0x40, 0x42, 0x06, 0x64, 0x13, 0x60, 0x16, 0xFB, 0xFF, 0xFF,
+	 0x2D, 0xFF, 0x12, 0x64, 0x3B, 0xDB, 0x84, 0xFF, 0xB7, 0x60, 0xF7, 0x78, 0xFF, 0xFF, 0x66, 0x44,
+	 0xFC, 0xFB, 0x46, 0x5C, 0x19, 0x60, 0xCF, 0xF3, 0x0D, 0xF2, 0x60, 0x5C, 0x64, 0x5F, 0x0D, 0xFA,
+	 0x11, 0x64, 0x3B, 0xDB, 0x9D, 0xFE, 0x06, 0x05, 0x08, 0x64, 0x13, 0x60, 0x16, 0xFB, 0x2D, 0xFF,
+	 0xFF, 0xFF, 0xA3, 0xFE, 0x07, 0xF0, 0x00, 0x64, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x02, 0x23, 0xF0,
+	 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDA, 0xBF, 0x60, 0x79, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0x00, 0x63,
+	 0x40, 0x47, 0x50, 0x36, 0x05, 0x00, 0xA4, 0x36, 0x03, 0x00, 0x80, 0x36, 0x01, 0x00, 0x01, 0x63,
+	 0x48, 0xFD, 0x40, 0x47, 0x08, 0x2A, 0x08, 0x00, 0x03, 0x2F, 0x06, 0x00, 0x7F, 0xF1, 0x2C, 0xF8,
+	 0x80, 0xF1, 0x2D, 0xF8, 0x81, 0xF1, 0x2E, 0xF8, 0x4A, 0xF3, 0x35, 0xFA, 0x10, 0xA4, 0x4A, 0xFB,
+	 0x00, 0x64, 0x15, 0xFA, 0x16, 0xFA, 0x0F, 0xFA, 0x07, 0xF0, 0xA6, 0xF3, 0xFF, 0xFF, 0xD0, 0x80,
+	 0xFF, 0xFF, 0x05, 0x03, 0x66, 0x43, 0x64, 0x46, 0x11, 0xF2, 0xD9, 0xFB, 0x63, 0x46, 0x03, 0xF2,
+	 0x00, 0xF4, 0x01, 0xF2, 0xFC, 0xA5, 0x00, 0x7F, 0xD4, 0x84, 0x27, 0x45, 0x3C, 0x46, 0x1A, 0xFA,
+	 0x22, 0x63, 0x7B, 0x60, 0xFF, 0x64, 0xA4, 0x84, 0x03, 0x2B, 0x1C, 0x63, 0x2A, 0xFA, 0x8F, 0xB0,
+	 0x88, 0x36, 0x02, 0xA3, 0x60, 0x40, 0xA4, 0x36, 0x14, 0x63, 0x43, 0x4C, 0x18, 0xFC, 0x00, 0x7C,
+	 0x22, 0xF8, 0x64, 0x41, 0x07, 0xF0, 0x66, 0x43, 0x64, 0x46, 0x3A, 0xF2, 0x63, 0x46, 0xFF, 0xB4,
+	 0x22, 0xFA, 0x60, 0x40, 0x00, 0x36, 0x82, 0x00, 0x2A, 0xF2, 0xFF, 0xFF, 0x0C, 0xB0, 0x08, 0x3A,
+	 0xAD, 0x00, 0x60, 0x40, 0x40, 0x26, 0xAA, 0x00, 0x03, 0xF2, 0x00, 0xF4, 0xA0, 0xD2, 0xAA, 0x60,
+	 0xAA, 0x65, 0x5A, 0xD0, 0xD4, 0x80, 0x03, 0x64, 0x0A, 0x02, 0xD0, 0x80, 0x00, 0x64, 0x5A, 0xD0,
+	 0x06, 0x02, 0xD0, 0x80, 0xF8, 0x7F, 0xD0, 0x80, 0x01, 0x03, 0x01, 0x02, 0x01, 0x61, 0x62, 0x43,
+	 0x46, 0x43, 0x3C, 0x46, 0x07, 0xF4, 0x3A, 0xF2, 0xFF, 0xFF, 0xA3, 0x46, 0x60, 0x40, 0x22, 0x26,
+	 0x64, 0x00, 0x60, 0x45, 0x63, 0x42, 0x5A, 0xD0, 0xCD, 0x81, 0x3C, 0x46, 0x1B, 0x02, 0x64, 0x44,
+	 0x88, 0x3A, 0x18, 0x00, 0x8E, 0x37, 0x03, 0x00, 0xC7, 0x37, 0x01, 0x00, 0x13, 0x00, 0x65, 0x44,
+	 0x01, 0x26, 0x7C, 0x00, 0x04, 0x26, 0x03, 0x00, 0x10, 0x26, 0x01, 0x00, 0x31, 0x00, 0xA3, 0x46,
+	 0x3B, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x80, 0x27, 0x5B, 0x00, 0xA3, 0x46, 0x00, 0x7C, 0x22, 0xF8,
+	 0xA3, 0x46, 0x6C, 0x00, 0xA3, 0x46, 0x65, 0x44, 0x01, 0x26, 0x0B, 0x00, 0x04, 0x26, 0x03, 0x00,
+	 0x10, 0x26, 0x01, 0x00, 0x1D, 0x00, 0x3B, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x80, 0x27, 0x48, 0x00,
+	 0x17, 0x00, 0xA6, 0xF3, 0xFF, 0xFF, 0x60, 0x46, 0x3A, 0xF2, 0x66, 0x43, 0xFF, 0xB4, 0x3C, 0x46,
+	 0x22, 0xF0, 0x60, 0x47, 0xB0, 0x84, 0x22, 0xFA, 0x63, 0x46, 0x3B, 0xF0, 0x60, 0x40, 0x04, 0x27,
+	 0x03, 0x00, 0x10, 0x27, 0x01, 0x00, 0x04, 0x00, 0x64, 0x40, 0x80, 0x27, 0x31, 0x00, 0x00, 0x00,
+	 0x3C, 0x46, 0x02, 0x65, 0xBF, 0x60, 0x19, 0x78, 0xFF, 0xFF, 0xCD, 0x81, 0x63, 0x42, 0x5A, 0xD0,
+	 0x3C, 0x46, 0x26, 0x02, 0x64, 0x44, 0x88, 0x3A, 0x23, 0x00, 0x77, 0x37, 0x37, 0x00, 0x78, 0x37,
+	 0x35, 0x00, 0x8E, 0x37, 0x33, 0x00, 0xC7, 0x37, 0x31, 0x00, 0x1A, 0x00, 0x19, 0x60, 0xA3, 0xF3,
+	 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x2A, 0x2A, 0x00, 0x06, 0x00, 0x19, 0x60, 0xA3, 0xF3, 0xFF, 0xFF,
+	 0x60, 0x40, 0x01, 0x2A, 0xE2, 0x01, 0x3C, 0x46, 0x3E, 0xF2, 0x40, 0x60, 0x00, 0x65, 0xF0, 0x84,
+	 0xA4, 0x84, 0x3D, 0xFA, 0x2A, 0xF2, 0xBF, 0x60, 0xFF, 0x65, 0xA4, 0x84, 0x2A, 0xFA, 0x16, 0x00,
+	 0x3C, 0x46, 0x22, 0xF0, 0x80, 0x67, 0xB0, 0x84, 0xA2, 0xDA, 0xFF, 0xFF, 0x3F, 0xF2, 0x3E, 0xF0,
+	 0x08, 0xA4, 0x60, 0x41, 0x22, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x26, 0x03, 0x00, 0x04, 0x26,
+	 0x03, 0x00, 0x04, 0x00, 0x04, 0x2B, 0x02, 0x00, 0x61, 0x44, 0x3F, 0xFA, 0x3C, 0x46, 0x2C, 0xF2,
+	 0x27, 0x40, 0x01, 0x27, 0x32, 0xF2, 0xD3, 0xF1, 0x60, 0x40, 0x01, 0x26, 0x47, 0x00, 0x09, 0x60,
+	 0x00, 0x64, 0xD0, 0x80, 0x3F, 0xF2, 0x09, 0x06, 0x2C, 0x45, 0xC4, 0x84, 0xD0, 0x80, 0x40, 0x4A,
+	 0x34, 0x06, 0x60, 0x43, 0x64, 0x44, 0x54, 0x88, 0x17, 0x00, 0x60, 0x45, 0x16, 0x60, 0xC8, 0xF3,
+	 0xDA, 0xF3, 0x00, 0xBC, 0x60, 0x47, 0xEC, 0xA0, 0x28, 0x03, 0x27, 0x07, 0x2C, 0x44, 0xC4, 0x81,
+	 0x02, 0x60, 0x1C, 0x65, 0x45, 0x4A, 0xD5, 0x80, 0x2C, 0x45, 0x1F, 0x06, 0x27, 0x40, 0x04, 0x27,
+	 0x25, 0x00, 0x2A, 0x43, 0xD7, 0x85, 0x45, 0x48, 0xD4, 0xF1, 0x0F, 0xF2, 0xD3, 0x80, 0x01, 0x65,
+	 0x01, 0x07, 0x00, 0x65, 0xB4, 0x84, 0x0F, 0xFA, 0x00, 0x63, 0x3F, 0xF2, 0x28, 0x45, 0x60, 0x41,
+	 0xD4, 0x84, 0xDF, 0x83, 0xFC, 0x07, 0x14, 0xFC, 0x17, 0xFA, 0x04, 0x60, 0x00, 0x64, 0x27, 0x45,
+	 0xB4, 0x84, 0x2A, 0xFA, 0x28, 0x43, 0x16, 0xFC, 0x0D, 0x00, 0x3F, 0xF2, 0x2C, 0x45, 0xD4, 0xF1,
+	 0xC4, 0x81, 0xD1, 0x80, 0x0F, 0xF2, 0x01, 0x06, 0x01, 0xBC, 0x0F, 0xFA, 0x3F, 0xF2, 0x17, 0xFA,
+	 0x01, 0x64, 0x14, 0xFA, 0xAA, 0xF2, 0x19, 0x60, 0x3F, 0xF3, 0x07, 0xF0, 0x66, 0x43, 0x64, 0x46,
+	 0x44, 0x44, 0x61, 0x40, 0x08, 0x26, 0x02, 0x00, 0x61, 0x40, 0x80, 0x36, 0x12, 0xF2, 0x63, 0x46,
+	 0x33, 0x60, 0x86, 0x61, 0x00, 0x7F, 0x60, 0x45, 0x45, 0xD3, 0xFF, 0xFF, 0x60, 0x45, 0x00, 0x7F,
+	 0x4B, 0xFB, 0x65, 0x44, 0x00, 0x7E, 0xDA, 0xFB, 0x07, 0xF0, 0x66, 0x43, 0x64, 0x46, 0x12, 0xF0,
+	 0x60, 0x47, 0x63, 0x46, 0x64, 0x40, 0x10, 0x2A, 0x1E, 0x00, 0x33, 0x60, 0x0A, 0x63, 0x60, 0x40,
+	 0x0A, 0x36, 0x0C, 0x00, 0x14, 0x36, 0x07, 0x00, 0x37, 0x36, 0x02, 0x00, 0xA3, 0xD3, 0x09, 0x00,
+	 0x02, 0xA3, 0xA3, 0xD3, 0x06, 0x00, 0x04, 0xA3, 0xA3, 0xD3, 0x03, 0x00, 0x06, 0xA3, 0xA3, 0xD3,
+	 0xFF, 0xFF, 0x60, 0x40, 0x0A, 0x36, 0x70, 0x64, 0x14, 0x36, 0x38, 0x64, 0x37, 0x36, 0x15, 0x64,
+	 0x6E, 0x36, 0x0B, 0x64, 0x39, 0x00, 0x32, 0x60, 0xFA, 0x63, 0x60, 0x40, 0x0B, 0x36, 0x20, 0x00,
+	 0x0F, 0x36, 0x1B, 0x00, 0x0A, 0x36, 0x16, 0x00, 0x0E, 0x36, 0x11, 0x00, 0x09, 0x36, 0x0C, 0x00,
+	 0x0D, 0x36, 0x07, 0x00, 0x08, 0x36, 0x02, 0x00, 0xA3, 0xD3, 0x15, 0x00, 0x02, 0xA3, 0xA3, 0xD3,
+	 0x12, 0x00, 0x04, 0xA3, 0xA3, 0xD3, 0x0F, 0x00, 0x06, 0xA3, 0xA3, 0xD3, 0x0C, 0x00, 0x08, 0xA3,
+	 0xA3, 0xD3, 0x09, 0x00, 0x0A, 0xA3, 0xA3, 0xD3, 0x06, 0x00, 0x0C, 0xA3, 0xA3, 0xD3, 0x03, 0x00,
+	 0x0E, 0xA3, 0xA3, 0xD3, 0xFF, 0xFF, 0x60, 0x40, 0x0B, 0x36, 0x1E, 0x64, 0x0F, 0x36, 0x16, 0x64,
+	 0x0A, 0x36, 0x12, 0x64, 0x0E, 0x36, 0x0E, 0x64, 0x09, 0x36, 0x0E, 0x64, 0x0D, 0x36, 0x0A, 0x64,
+	 0x08, 0x36, 0x0A, 0x64, 0x0C, 0x36, 0x0A, 0x64, 0x40, 0x46, 0x2A, 0xF2, 0x07, 0xF0, 0x60, 0x40,
+	 0xB0, 0x3A, 0x03, 0x00, 0x40, 0x3B, 0x01, 0x00, 0x12, 0x00, 0x0C, 0xB4, 0x08, 0x3A, 0x44, 0x00,
+	 0x22, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x80, 0x2B, 0x3F, 0x00, 0x17, 0xF2, 0x22, 0xF0, 0xFF, 0xFF,
+	 0x64, 0x40, 0x22, 0x22, 0x04, 0x00, 0x00, 0xA8, 0x01, 0xA8, 0x36, 0x03, 0x35, 0x03, 0x3C, 0x46,
+	 0x2A, 0xF0, 0x40, 0x67, 0xB0, 0x84, 0xA2, 0xDA, 0x60, 0x45, 0x22, 0xF2, 0xFF, 0xFF, 0x60, 0x43,
+	 0x60, 0x40, 0x01, 0x26, 0x05, 0x00, 0x04, 0x26, 0x1D, 0x00, 0x10, 0x26, 0x10, 0x00, 0x04, 0x00,
+	 0x04, 0x27, 0x18, 0x00, 0x10, 0x27, 0x0B, 0x00, 0x65, 0x44, 0x2A, 0x61, 0x60, 0x40, 0x03, 0x2B,
+	 0x24, 0x61, 0x8F, 0xB0, 0x88, 0x36, 0x02, 0xA1, 0x41, 0x4C, 0x98, 0xFA, 0x15, 0x00, 0x65, 0x44,
+	 0x32, 0x61, 0x60, 0x40, 0x03, 0x2B, 0x2C, 0x61, 0x8F, 0xB0, 0x88, 0x36, 0x02, 0xA1, 0x41, 0x4C,
+	 0x98, 0xFA, 0x0A, 0x00, 0x65, 0x44, 0x2E, 0x61, 0x60, 0x40, 0x03, 0x2B, 0x28, 0x61, 0x8F, 0xB0,
+	 0x88, 0x36, 0x02, 0xA1, 0x41, 0x4C, 0x98, 0xFA, 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x40, 0x27,
+	 0x03, 0x00, 0xBC, 0x60, 0x46, 0x78, 0xFF, 0xFF, 0x22, 0xF2, 0x46, 0x43, 0x60, 0x40, 0x22, 0x26,
+	 0x09, 0x00, 0x01, 0x26, 0x0A, 0x00, 0x04, 0x26, 0x4B, 0x00, 0x10, 0x26, 0x10, 0x00, 0xBC, 0x60,
+	 0x46, 0x78, 0xFF, 0xFF, 0xBB, 0x60, 0xC1, 0x78, 0xFF, 0xFF, 0x04, 0x27, 0x3D, 0x00, 0x10, 0x27,
+	 0x03, 0x00, 0xBC, 0x60, 0x46, 0x78, 0xFF, 0xFF, 0xA6, 0xF3, 0x3C, 0xF1, 0x02, 0x00, 0x07, 0xF2,
+	 0x00, 0x7C, 0x40, 0x43, 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x08, 0x27, 0x21, 0x00, 0xA3, 0x46,
+	 0x4B, 0xF2, 0xFF, 0xFF, 0xDC, 0x84, 0x4B, 0xFA, 0x4A, 0xF2, 0x08, 0x04, 0xDC, 0x84, 0x4A, 0xFA,
+	 0x49, 0xF2, 0x04, 0x04, 0xDC, 0x84, 0x49, 0xFA, 0x01, 0x04, 0xFF, 0xFF, 0xA6, 0xF3, 0x66, 0x5C,
+	 0xD0, 0x80, 0x00, 0x7C, 0x01, 0x02, 0x3C, 0xF1, 0x4B, 0xF0, 0x64, 0x47, 0x20, 0xBF, 0xA3, 0x46,
+	 0x3A, 0xF8, 0x3B, 0xFA, 0xA3, 0x46, 0x4A, 0xF2, 0x49, 0xF0, 0xA3, 0x46, 0x3C, 0xFA, 0x3D, 0xF8,
+	 0x0F, 0x60, 0x9E, 0x64, 0xA3, 0x46, 0x76, 0x61, 0x0E, 0x63, 0x59, 0xD0, 0x58, 0xD9, 0xFD, 0x1F,
+	 0xA3, 0x46, 0xBC, 0x60, 0x46, 0x78, 0xFF, 0xFF, 0xA6, 0xF3, 0xFF, 0xFF, 0x60, 0x46, 0x02, 0x00,
+	 0x07, 0xF4, 0xFF, 0xFF, 0xA3, 0x46, 0x2A, 0xF2, 0xA3, 0x46, 0x60, 0x40, 0x08, 0x27, 0x48, 0x00,
+	 0xA6, 0xF3, 0x66, 0x5C, 0xD0, 0x80, 0x3B, 0xF0, 0x08, 0x03, 0x64, 0x40, 0x10, 0x2A, 0x12, 0x00,
+	 0xFF, 0x60, 0xEF, 0x64, 0xA0, 0x84, 0x3B, 0xFA, 0x24, 0x00, 0x3D, 0xF3, 0x01, 0x61, 0x60, 0x43,
+	 0xCF, 0x83, 0xE1, 0x81, 0xFD, 0x0D, 0xE9, 0x81, 0xA1, 0x80, 0xFF, 0xFF, 0x03, 0x03, 0x91, 0x84,
+	 0x3B, 0xFA, 0x17, 0x00, 0x4B, 0xF2, 0xFF, 0xFF, 0x10, 0xA0, 0xFF, 0xFF, 0x02, 0x04, 0xFF, 0x60,
+	 0xFF, 0x64, 0xDC, 0x84, 0x4B, 0xFA, 0x4A, 0xF2, 0x16, 0x04, 0xDC, 0x84, 0x4A, 0xFA, 0x49, 0xF2,
+	 0x08, 0x04, 0xDC, 0x84, 0x49, 0xFA, 0x05, 0x04, 0x3B, 0xF2, 0xFF, 0xFF, 0xE0, 0x84, 0xE8, 0x84,
+	 0x3B, 0xFA, 0x0C, 0x60, 0xFC, 0x62, 0x80, 0xFF, 0x78, 0x44, 0x03, 0xA4, 0xA2, 0xDB, 0xC8, 0x60,
+	 0x15, 0x78, 0xFF, 0xFF, 0x84, 0xFF, 0x06, 0x60, 0x17, 0xE1, 0x77, 0x40, 0x8B, 0xFF, 0x02, 0x60,
+	 0x00, 0x75, 0xC9, 0x60, 0x58, 0x4F, 0xAD, 0x78, 0xFF, 0xFF, 0x01, 0x64, 0x06, 0x60, 0x7F, 0xFB,
+	 0x0C, 0x60, 0xFC, 0x62, 0x80, 0xFF, 0x78, 0x44, 0x03, 0xA4, 0xA2, 0xDB, 0xC8, 0x60, 0x8C, 0x78,
+	 0xFF, 0xFF, 0x84, 0xFF, 0x00, 0x7C, 0x06, 0x60, 0x7F, 0xF3, 0xA2, 0xD9, 0x60, 0x40, 0x01, 0x2A,
+	 0x04, 0x00, 0xC9, 0x60, 0x58, 0x4F, 0xF6, 0x78, 0xFF, 0xFF, 0x3C, 0x46, 0x07, 0xF4, 0xA6, 0xF3,
+	 0x66, 0x5C, 0xD0, 0x80, 0x00, 0x7C, 0x07, 0x03, 0x66, 0x43, 0x3C, 0x46, 0x22, 0xF2, 0x63, 0x46,
+	 0x60, 0x40, 0x01, 0x2A, 0x01, 0x00, 0x3C, 0xF1, 0x4B, 0xF0, 0x64, 0x41, 0x64, 0x47, 0xFF, 0xB4,
+	 0x60, 0x5F, 0x20, 0xBC, 0x80, 0x26, 0x80, 0xAC, 0x60, 0x47, 0xA3, 0x46, 0x3A, 0xFA, 0x64, 0x44,
+	 0x20, 0x7F, 0x34, 0x94, 0x3B, 0xFA, 0xA3, 0x46, 0x4A, 0xF2, 0x49, 0xF0, 0xA3, 0x46, 0x3C, 0xFA,
+	 0x3D, 0xF8, 0x80, 0x60, 0x10, 0xE0, 0x08, 0x60, 0x00, 0xEA, 0x0F, 0x64, 0x60, 0x7F, 0xA0, 0x5A,
+	 0x80, 0x60, 0x00, 0xEA, 0xA0, 0x60, 0x00, 0xEA, 0xD1, 0x60, 0x00, 0xEA, 0xBC, 0x60, 0x46, 0x78,
+	 0xFF, 0xFF, 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x08, 0x27, 0x31, 0x00, 0x2A, 0xF2, 0x00, 0x60,
+	 0x7C, 0x62, 0x60, 0x40, 0x40, 0x2B, 0x24, 0x00, 0xA2, 0xD3, 0x00, 0x61, 0x60, 0xFE, 0xA0, 0xD3,
+	 0x5E, 0xD1, 0xFF, 0xFF, 0x20, 0xFE, 0x64, 0x5F, 0xDC, 0x84, 0xF1, 0x81, 0xC0, 0x2B, 0x04, 0x00,
+	 0x80, 0x2A, 0x02, 0x00, 0x7F, 0xA4, 0xDC, 0x84, 0xFF, 0x3B, 0x03, 0x00, 0x60, 0x47, 0xDC, 0x87,
+	 0x01, 0x61, 0xC0, 0x80, 0x00, 0x36, 0xDC, 0x84, 0x4E, 0xDB, 0x60, 0xFE, 0x5A, 0xD1, 0xFF, 0xFF,
+	 0xC1, 0x84, 0xF0, 0x22, 0x10, 0xA4, 0xF0, 0x2A, 0x01, 0x00, 0x00, 0x64, 0xA2, 0xDB, 0x20, 0xFE,
+	 0x00, 0x60, 0x3E, 0xF3, 0xFF, 0xFF, 0xA0, 0xD3, 0x5A, 0xD1, 0x3A, 0xFA, 0x3B, 0xF8, 0x74, 0x62,
+	 0xA2, 0xD0, 0xFF, 0xFF, 0x64, 0x44, 0xE0, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xE1, 0x7F, 0x5A, 0xD0,
+	 0xA0, 0x5A, 0x64, 0x44, 0xE2, 0x7F, 0xA0, 0x5A, 0x00, 0x60, 0x40, 0xF3, 0xFF, 0xFF, 0xA0, 0xD1,
+	 0x5A, 0xD1, 0x64, 0x45, 0x64, 0x44, 0xE3, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xE4, 0x7F, 0x5A, 0xD1,
+	 0xA0, 0x5A, 0x64, 0x44, 0xE5, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xE6, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A,
+	 0x64, 0x44, 0xE7, 0x7F, 0xA0, 0x5A, 0x65, 0x40, 0x0D, 0x3A, 0x1C, 0x00, 0x64, 0x47, 0xE8, 0x7F,
+	 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44, 0xE9, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xEA, 0x7F, 0x5A, 0xD1,
+	 0xA0, 0x5A, 0x64, 0x44, 0xEB, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xEC, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A,
+	 0x64, 0x44, 0xED, 0x7F, 0xA0, 0x5A, 0x64, 0x47, 0xEE, 0x7F, 0x5A, 0xD1, 0xA0, 0x5A, 0x64, 0x44,
+	 0xEF, 0x7F, 0xA0, 0x5A, 0x08, 0x60, 0x00, 0xEA, 0x65, 0x44, 0x02, 0xA4, 0x60, 0x7F, 0xA0, 0x5A,
+	 0x80, 0x60, 0x00, 0xEA, 0xA0, 0x60, 0x00, 0xEA, 0xD1, 0x60, 0x00, 0xEA, 0x66, 0x45, 0xAA, 0xF2,
+	 0x19, 0x60, 0x3F, 0xF3, 0x24, 0x46, 0x61, 0x40, 0x08, 0x26, 0x02, 0x00, 0x61, 0x40, 0x80, 0x36,
+	 0x12, 0xF2, 0x65, 0x46, 0x60, 0x40, 0x10, 0x26, 0x34, 0x00, 0x2C, 0x45, 0x17, 0xF2, 0x4B, 0xF1,
+	 0xC4, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x81, 0x64, 0x45, 0x16, 0xA1, 0xB8, 0x60, 0x58, 0x4D,
+	 0x15, 0x78, 0xFF, 0xFF, 0x7D, 0xF1, 0x01, 0xA4, 0xE0, 0x84, 0xE0, 0x84, 0x64, 0x40, 0x01, 0x2B,
+	 0x06, 0xA4, 0x1B, 0xFA, 0xDA, 0xF3, 0x2C, 0x60, 0x7C, 0x65, 0x60, 0x40, 0x0B, 0x37, 0x00, 0x63,
+	 0x0F, 0x37, 0x02, 0x63, 0x0A, 0x37, 0x04, 0x63, 0x0E, 0x37, 0x06, 0x63, 0x09, 0x37, 0x08, 0x63,
+	 0x0D, 0x37, 0x0A, 0x63, 0x08, 0x37, 0x0C, 0x63, 0x0C, 0x37, 0x0E, 0x63, 0x28, 0xA3, 0x47, 0xD1,
+	 0xD8, 0xA3, 0xD7, 0x83, 0x19, 0x60, 0x77, 0xF9, 0x47, 0xD1, 0x40, 0x67, 0xB0, 0x84, 0x1F, 0xFA,
+	 0x58, 0x00, 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x80, 0x36, 0x19, 0x00, 0x50, 0x36, 0x17, 0x00,
+	 0x40, 0x36, 0x15, 0x00, 0x00, 0x36, 0x13, 0x00, 0x20, 0x36, 0x11, 0x00, 0xA0, 0x36, 0x0F, 0x00,
+	 0xB0, 0x36, 0x0D, 0x00, 0xC0, 0x36, 0x0B, 0x00, 0xDA, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x0A, 0x37,
+	 0x06, 0x00, 0x19, 0x60, 0x7B, 0xF3, 0x80, 0x60, 0x00, 0x61, 0x60, 0x40, 0x04, 0x26, 0x00, 0x61,
+	 0xDA, 0xF3, 0x2C, 0x60, 0x74, 0x65, 0x60, 0x40, 0x0A, 0x37, 0x00, 0x63, 0x14, 0x37, 0x02, 0x63,
+	 0x37, 0x37, 0x04, 0x63, 0x6E, 0x37, 0x06, 0x63, 0x28, 0xA3, 0x47, 0xD1, 0xD8, 0xA3, 0xD7, 0x83,
+	 0x19, 0x60, 0x77, 0xF9, 0x47, 0xD1, 0xFF, 0xFF, 0xB1, 0x84, 0x1F, 0xFA, 0xDA, 0xF1, 0x2C, 0x45,
+	 0x64, 0x43, 0x17, 0xF2, 0x4B, 0xF1, 0xC4, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x81, 0x63, 0x40,
+	 0x37, 0x37, 0xE1, 0x81, 0x64, 0x45, 0xB8, 0x60, 0x58, 0x4D, 0x15, 0x78, 0xFF, 0xFF, 0xAE, 0x82,
+	 0xFC, 0xA2, 0x0A, 0x03, 0x63, 0x40, 0x6E, 0x3B, 0x06, 0x00, 0x60, 0x41, 0x04, 0x0D, 0x63, 0x44,
+	 0x80, 0x7E, 0xDA, 0xFB, 0x61, 0x44, 0xDC, 0x84, 0x2B, 0xF0, 0x1B, 0xFA, 0x64, 0x44, 0x80, 0x27,
+	 0x58, 0x00, 0x07, 0xF0, 0x66, 0x45, 0x64, 0x46, 0x12, 0xF2, 0x65, 0x46, 0x60, 0x40, 0x10, 0x2A,
+	 0x31, 0x00, 0x16, 0xF2, 0x0F, 0xF0, 0xAC, 0x84, 0x2C, 0x45, 0x2C, 0x03, 0x4B, 0xF1, 0xC4, 0x84,
+	 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x81, 0x63, 0x40, 0x37, 0x37, 0xE1, 0x81, 0x64, 0x45, 0x0F, 0xF0,
+	 0xB8, 0x60, 0x58, 0x4D, 0x15, 0x78, 0xFF, 0xFF, 0xAE, 0x82, 0xFC, 0xA2, 0x0A, 0x03, 0x63, 0x40,
+	 0x6E, 0x3B, 0x06, 0x00, 0x60, 0x41, 0x04, 0x0D, 0x80, 0x67, 0xB0, 0x84, 0x0F, 0xFA, 0x61, 0x44,
+	 0xDC, 0x84, 0x1D, 0xFA, 0x1F, 0xF0, 0x01, 0x60, 0x3E, 0x65, 0x64, 0x40, 0x80, 0x27, 0x02, 0x00,
+	 0x02, 0x60, 0x5E, 0x65, 0x1B, 0xF0, 0x26, 0x41, 0xE1, 0x81, 0xC5, 0x81, 0x44, 0x94, 0xC1, 0x81,
+	 0x2B, 0xFA, 0x90, 0xFA, 0x26, 0x44, 0x2C, 0xF0, 0x0A, 0xA4, 0x66, 0x45, 0x24, 0x46, 0x92, 0xF2,
+	 0x65, 0x46, 0x9F, 0xF0, 0x61, 0x40, 0x10, 0x2A, 0x05, 0x00, 0x60, 0xA4, 0x65, 0x40, 0x80, 0x2B,
+	 0x60, 0xA4, 0x01, 0x00, 0x14, 0xA4, 0x64, 0x40, 0x01, 0x26, 0x00, 0x64, 0x60, 0x45, 0x2A, 0xF2,
+	 0x39, 0xF0, 0x8F, 0xB0, 0x88, 0x3A, 0x04, 0x00, 0x64, 0x44, 0x60, 0xB0, 0x20, 0x36, 0x00, 0x65,
+	 0x65, 0x44, 0x11, 0xFA, 0xDA, 0xF3, 0x13, 0xFA, 0x7C, 0x44, 0x1D, 0xFA, 0x0F, 0xF0, 0xFF, 0xFF,
+	 0x64, 0x40, 0x01, 0x2A, 0x6F, 0x00, 0x7D, 0xF1, 0x19, 0x60, 0x7B, 0xF3, 0x64, 0x40, 0x01, 0x27,
+	 0x03, 0x00, 0x60, 0x40, 0x02, 0x26, 0x14, 0x00, 0x07, 0xF0, 0x66, 0x43, 0x64, 0x46, 0x12, 0xF0,
+	 0x19, 0x60, 0x7C, 0xF3, 0x63, 0x46, 0x64, 0x40, 0x10, 0x2A, 0x20, 0x00, 0x60, 0x40, 0x02, 0x26,
+	 0x07, 0x00, 0x01, 0x26, 0x08, 0x00, 0x04, 0x26, 0x09, 0x00, 0x06, 0x61, 0x6E, 0x63, 0x08, 0x00,
+	 0x02, 0x61, 0x14, 0x63, 0x05, 0x00, 0x00, 0x61, 0x0A, 0x63, 0x02, 0x00, 0x04, 0x61, 0x37, 0x63,
+	 0x00, 0x64, 0x2C, 0x60, 0x9C, 0x65, 0x45, 0xD1, 0xD5, 0x81, 0x19, 0x60, 0x78, 0xF9, 0x2C, 0x60,
+	 0x74, 0x65, 0x45, 0xD1, 0x1C, 0xFC, 0xB0, 0x84, 0x1E, 0xFA, 0x3C, 0x00, 0x60, 0x40, 0x10, 0x2A,
+	 0x04, 0x00, 0x08, 0x61, 0x1E, 0x60, 0x0B, 0x63, 0x27, 0x00, 0x20, 0x2A, 0x04, 0x00, 0x0A, 0x61,
+	 0x16, 0x60, 0x0F, 0x63, 0x21, 0x00, 0x40, 0x2A, 0x04, 0x00, 0x0C, 0x61, 0x12, 0x60, 0x0A, 0x63,
+	 0x1B, 0x00, 0x80, 0x2A, 0x04, 0x00, 0x0E, 0x61, 0x0E, 0x60, 0x0E, 0x63, 0x15, 0x00, 0x01, 0x2B,
+	 0x04, 0x00, 0x10, 0x61, 0x0E, 0x60, 0x09, 0x63, 0x0F, 0x00, 0x02, 0x2B, 0x04, 0x00, 0x12, 0x61,
+	 0x0A, 0x60, 0x0D, 0x63, 0x09, 0x00, 0x04, 0x2B, 0x04, 0x00, 0x14, 0x61, 0x0A, 0x60, 0x08, 0x63,
+	 0x03, 0x00, 0x16, 0x61, 0x0A, 0x60, 0x0C, 0x63, 0x1E, 0xF0, 0x40, 0x67, 0x2C, 0x60, 0x9C, 0x65,
+	 0x45, 0xD1, 0xD5, 0x81, 0x19, 0x60, 0x78, 0xF9, 0x2C, 0x60, 0x74, 0x65, 0x45, 0xD1, 0x1C, 0xFC,
+	 0xB0, 0x84, 0x1E, 0xFA, 0xFF, 0xFF, 0x0D, 0xF2, 0x3E, 0xF0, 0x60, 0x47, 0xFF, 0xB4, 0x64, 0x41,
+	 0x01, 0xB1, 0x01, 0x63, 0x17, 0x02, 0x60, 0x41, 0xFF, 0x22, 0x04, 0x00, 0xB8, 0x60, 0x58, 0x4F,
+	 0x06, 0x78, 0xFF, 0xFF, 0x07, 0x60, 0xED, 0xFD, 0x19, 0x60, 0xCF, 0xF3, 0xFF, 0xFF, 0x60, 0x41,
+	 0x01, 0x63, 0x61, 0x40, 0xFF, 0x22, 0x04, 0x00, 0xB8, 0x60, 0x58, 0x4F, 0x06, 0x78, 0xFF, 0xFF,
+	 0x07, 0x60, 0xEE, 0xFD, 0x02, 0x64, 0x3B, 0xDB, 0xBF, 0x60, 0xE4, 0x78, 0xFF, 0xFF, 0x66, 0x44,
+	 0xFC, 0xFB, 0x07, 0xF0, 0x00, 0x64, 0xD0, 0x80, 0xA6, 0xF3, 0x0E, 0x03, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x0B, 0x03, 0x47, 0xF1, 0x07, 0xF0, 0x64, 0x40, 0x02, 0x26, 0x01, 0x00, 0x08, 0x00, 0x03, 0x12,
+	 0xBE, 0x60, 0xA0, 0x78, 0xFF, 0xFF, 0xFC, 0x0A, 0xBF, 0x60, 0x00, 0x78, 0xFF, 0xFF, 0x87, 0xF0,
+	 0xA6, 0xF3, 0x10, 0xF0, 0xD4, 0x80, 0xFF, 0xFF, 0x3D, 0x03, 0x66, 0x43, 0x65, 0x46, 0xFF, 0x67,
+	 0x20, 0x85, 0x64, 0x5F, 0x40, 0x44, 0x15, 0xF0, 0x25, 0x44, 0xD0, 0x84, 0x03, 0xA4, 0x03, 0x0E,
+	 0xE8, 0x84, 0xE8, 0x84, 0x04, 0x00, 0xFA, 0xA4, 0xE8, 0x84, 0xE8, 0x87, 0xC0, 0xBF, 0xC0, 0x84,
+	 0x15, 0xFA, 0x40, 0x45, 0x14, 0xF0, 0x24, 0x44, 0xD0, 0x84, 0x1F, 0xA4, 0x06, 0x0E, 0xE8, 0x84,
+	 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0x07, 0x00, 0xC2, 0xA4, 0xE8, 0x84, 0xE8, 0x84,
+	 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x87, 0xF8, 0xBF, 0xC0, 0x84, 0x14, 0xFA, 0x60, 0x5C, 0x2F, 0x67,
+	 0xD0, 0x80, 0x60, 0x45, 0x02, 0x28, 0x64, 0x45, 0x25, 0x5C, 0x8B, 0x67, 0xD0, 0x80, 0x60, 0x41,
+	 0x02, 0x24, 0x64, 0x41, 0xD5, 0x84, 0x80, 0x65, 0xC4, 0x87, 0x01, 0x05, 0x00, 0x64, 0xFF, 0xB4,
+	 0x0E, 0xFA, 0x63, 0x46, 0x07, 0xF0, 0x66, 0x43, 0x64, 0x46, 0x17, 0xF2, 0x63, 0x46, 0x60, 0x40,
+	 0x00, 0x36, 0x2E, 0x00, 0x01, 0x36, 0x1E, 0x00, 0x03, 0x3A, 0x25, 0x00, 0x64, 0x46, 0x10, 0xF2,
+	 0x11, 0xFA, 0x12, 0xF2, 0x00, 0x61, 0x60, 0x47, 0x00, 0x7F, 0x12, 0xFA, 0x97, 0xFA, 0x46, 0x44,
+	 0x63, 0x46, 0xC2, 0x60, 0x58, 0x4E, 0x4C, 0x78, 0xFF, 0xFF, 0x65, 0x40, 0x00, 0x3A, 0x04, 0x00,
+	 0xC2, 0x60, 0x58, 0x4E, 0x96, 0x78, 0xFF, 0xFF, 0x07, 0xF0, 0x66, 0x43, 0x64, 0x46, 0x96, 0xFC,
+	 0x63, 0x46, 0x43, 0x00, 0x64, 0x46, 0x16, 0xF2, 0x00, 0x61, 0x20, 0x28, 0xFF, 0xA4, 0x97, 0xFA,
+	 0x16, 0xFA, 0x63, 0x46, 0x3A, 0x00, 0x64, 0x46, 0x00, 0x61, 0x97, 0xFA, 0x63, 0x46, 0x35, 0x00,
+	 0x07, 0xF0, 0x66, 0x41, 0x64, 0x46, 0x16, 0xF2, 0xFF, 0xFF, 0x20, 0x28, 0xFF, 0xA4, 0x16, 0xFA,
+	 0x93, 0xF4, 0x12, 0xF2, 0x20, 0x28, 0xFF, 0xA3, 0x13, 0xFC, 0x61, 0x46, 0x63, 0x40, 0x00, 0x3A,
+	 0x24, 0x00, 0xC2, 0x60, 0x58, 0x4E, 0x6D, 0x78, 0xFF, 0xFF, 0x61, 0x40, 0xFF, 0x36, 0x1D, 0x00,
+	 0x66, 0x41, 0x64, 0x46, 0x12, 0xF2, 0x93, 0xF4, 0x61, 0x46, 0x20, 0x28, 0x16, 0x00, 0x44, 0x44,
+	 0xC2, 0x60, 0x58, 0x4E, 0x4C, 0x78, 0xFF, 0xFF, 0x24, 0x5C, 0x65, 0x40, 0x00, 0x36, 0x06, 0x00,
+	 0x66, 0x41, 0x64, 0x46, 0x01, 0x64, 0x17, 0xFA, 0x61, 0x46, 0x07, 0x00, 0x66, 0x43, 0x64, 0x46,
+	 0xC2, 0x60, 0x58, 0x4E, 0x96, 0x78, 0xFF, 0xFF, 0x63, 0x46, 0xBF, 0x60, 0x00, 0x78, 0xFF, 0xFF,
+	 0x07, 0xF0, 0x66, 0x43, 0x64, 0x46, 0x17, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0xFF, 0x27, 0xFF, 0xFF,
+	 0x00, 0x36, 0x07, 0x00, 0x01, 0x36, 0x1C, 0x00, 0x02, 0x36, 0x24, 0x00, 0x03, 0x36, 0x43, 0x00,
+	 0xFF, 0xFF, 0x19, 0x60, 0xA9, 0xF1, 0x16, 0xF2, 0x43, 0x44, 0xD0, 0x80, 0x33, 0x60, 0x84, 0x61,
+	 0x09, 0x03, 0xA1, 0xD1, 0x33, 0x60, 0x82, 0x63, 0xC0, 0x84, 0x16, 0xFA, 0xA3, 0xD3, 0xFF, 0xFF,
+	 0x13, 0xFA, 0x39, 0x00, 0x96, 0xFC, 0xC2, 0x60, 0x58, 0x4E, 0x96, 0x78, 0xFF, 0xFF, 0x33, 0x00,
+	 0x43, 0x44, 0xC2, 0x60, 0x58, 0x4E, 0x96, 0x78, 0xFF, 0xFF, 0x19, 0x60, 0xC1, 0xF3, 0x96, 0xFC,
+	 0x13, 0xFA, 0x29, 0x00, 0x63, 0x46, 0x33, 0x60, 0x54, 0x63, 0xA3, 0xD3, 0x15, 0xF2, 0x60, 0x45,
+	 0xD4, 0x80, 0x07, 0xF0, 0x0C, 0x03, 0x66, 0x41, 0x44, 0x44, 0x64, 0x46, 0x12, 0xF2, 0x61, 0x46,
+	 0xC2, 0x60, 0x58, 0x4E, 0x4C, 0x78, 0xFF, 0xFF, 0x65, 0x40, 0x00, 0x3A, 0x19, 0x00, 0x66, 0x43,
+	 0x24, 0x46, 0xC2, 0x60, 0x58, 0x4E, 0x96, 0x78, 0xFF, 0xFF, 0x12, 0xF2, 0x91, 0xF2, 0x90, 0xFA,
+	 0x60, 0x5F, 0x12, 0xFA, 0x04, 0x00, 0xC2, 0x60, 0x58, 0x4E, 0x96, 0x78, 0xFF, 0xFF, 0x03, 0x64,
+	 0x17, 0xFA, 0x63, 0x46, 0x05, 0x00, 0x24, 0x43, 0x02, 0x64, 0x17, 0xFA, 0x63, 0x46, 0x00, 0x00,
+	 0x03, 0x64, 0x3B, 0xDB, 0xCA, 0xFE, 0x47, 0xF1, 0x01, 0x65, 0x32, 0x40, 0x04, 0x27, 0x11, 0x00,
+	 0x2C, 0xF2, 0x64, 0x45, 0x02, 0x22, 0x0D, 0x00, 0x60, 0x40, 0x01, 0x26, 0x0A, 0x00, 0x2A, 0xF2,
+	 0x39, 0xF0, 0x8F, 0xB0, 0x88, 0x3A, 0x77, 0x00, 0x64, 0x44, 0x60, 0xB0, 0x20, 0x36, 0x01, 0x00,
+	 0x72, 0x00, 0x14, 0xF2, 0x65, 0x40, 0x01, 0x26, 0x0C, 0x00, 0x60, 0x45, 0x05, 0x64, 0x3B, 0xDB,
+	 0x65, 0x44, 0xCC, 0x85, 0x2C, 0x60, 0xD0, 0x64, 0xF1, 0x60, 0x78, 0x41, 0xF0, 0x78, 0xB5, 0xF1,
+	 0x50, 0x00, 0x60, 0x41, 0x2A, 0xF0, 0x00, 0x60, 0x0C, 0x64, 0xA0, 0x84, 0x04, 0x36, 0x02, 0x00,
+	 0x0C, 0x3A, 0x01, 0x00, 0x46, 0x00, 0x61, 0x45, 0x60, 0x43, 0x2C, 0x60, 0xD0, 0x64, 0xF1, 0x60,
+	 0x78, 0x41, 0xF0, 0x78, 0xB5, 0xF1, 0x63, 0x40, 0x08, 0x36, 0x01, 0x00, 0x3A, 0x00, 0x14, 0xF2,
+	 0x1C, 0x65, 0x60, 0x41, 0x00, 0x63, 0xCD, 0x81, 0xC7, 0x83, 0xFD, 0x02, 0x3F, 0xF0, 0x2C, 0xF2,
+	 0xC3, 0x83, 0x60, 0x40, 0x01, 0x2A, 0x0D, 0x00, 0x2C, 0x60, 0xCE, 0x64, 0xF1, 0x60, 0x78, 0x41,
+	 0xE4, 0x78, 0xB5, 0xF1, 0x2C, 0x60, 0xD4, 0x64, 0xF1, 0x60, 0x78, 0x41, 0xEF, 0x78, 0x63, 0x45,
+	 0x20, 0x00, 0x2C, 0x60, 0xCC, 0x64, 0xF1, 0x60, 0x78, 0x41, 0xE4, 0x78, 0xB5, 0xF1, 0x2C, 0x60,
+	 0xD2, 0x64, 0xF1, 0x60, 0x78, 0x41, 0xEF, 0x78, 0x63, 0x45, 0x15, 0xF2, 0xFF, 0xFF, 0x0F, 0xB4,
+	 0x00, 0xA8, 0x01, 0xA8, 0x0E, 0x03, 0x07, 0x03, 0x2C, 0x60, 0xDA, 0x64, 0xF1, 0x60, 0x78, 0x41,
+	 0xE4, 0x78, 0xB5, 0xF1, 0x06, 0x00, 0x2C, 0x60, 0xD8, 0x64, 0xF1, 0x60, 0x78, 0x41, 0xE4, 0x78,
+	 0xB5, 0xF1, 0x04, 0x64, 0x3B, 0xDB, 0x25, 0x60, 0xEC, 0x64, 0x13, 0x60, 0x0A, 0xFB, 0x3C, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x5C, 0x5C, 0xFC, 0xFC, 0xCE, 0xFE,
+	 0xB8, 0x60, 0x37, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0xFF, 0xFF, 0x50, 0xA8, 0x02, 0x7C, 0x09, 0x03,
+	 0x0F, 0xF0, 0x15, 0xF2, 0x64, 0x41, 0x01, 0x2A, 0x02, 0x00, 0xCD, 0xF1, 0x02, 0x00, 0xCC, 0xF1,
+	 0xFF, 0xFF, 0x64, 0x45, 0xDC, 0x84, 0xD4, 0x80, 0x15, 0xFA, 0x2D, 0x07, 0x61, 0x40, 0x01, 0x2A,
+	 0x08, 0x00, 0x16, 0x60, 0x80, 0xF3, 0xFF, 0xFF, 0xDC, 0x84, 0x00, 0x36, 0x00, 0x3B, 0xA2, 0xDB,
+	 0x07, 0x00, 0x16, 0x60, 0x81, 0xF3, 0xFF, 0xFF, 0xDC, 0x84, 0x00, 0x36, 0x00, 0x3B, 0xA2, 0xDB,
+	 0x2A, 0xF0, 0x08, 0x67, 0xB0, 0x84, 0xA2, 0xDA, 0x00, 0x64, 0x48, 0xFB, 0x19, 0x60, 0xA3, 0xF3,
+	 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x2A, 0x0C, 0x00, 0x3C, 0x46, 0x3E, 0xF2, 0x40, 0x60, 0x00, 0x65,
+	 0xF0, 0x84, 0xA4, 0x84, 0x3D, 0xFA, 0x2A, 0xF2, 0xBF, 0x60, 0xFF, 0x65, 0xA4, 0x84, 0x2A, 0xFA,
+	 0xBA, 0x60, 0x02, 0x78, 0xFF, 0xFF, 0x00, 0x64, 0x49, 0xFB, 0x2C, 0x60, 0xDA, 0x64, 0xF1, 0x60,
+	 0x78, 0x41, 0xE4, 0x78, 0xB5, 0xF1, 0x2C, 0x60, 0xDC, 0x64, 0xF1, 0x60, 0x78, 0x41, 0xE4, 0x78,
+	 0xB5, 0xF1, 0x27, 0x44, 0xF7, 0xB4, 0x40, 0x47, 0x23, 0xF0, 0x01, 0x64, 0xB0, 0x84, 0xA2, 0xDA,
+	 0x98, 0x01, 0xC0, 0x60, 0x5F, 0x78, 0xFF, 0xFF, 0x21, 0x64, 0x3B, 0xDB, 0x31, 0xF3, 0x01, 0x63,
+	 0xC4, 0xB4, 0x31, 0xFB, 0x32, 0xFD, 0xC0, 0x60, 0x14, 0x62, 0x42, 0x40, 0xA0, 0x4C, 0x40, 0xBC,
+	 0x7D, 0xB4, 0xA0, 0x51, 0xA0, 0xFE, 0x1A, 0xFF, 0x25, 0x60, 0xE0, 0x64, 0x08, 0xF0, 0x07, 0xF0,
+	 0xD0, 0x80, 0x25, 0x60, 0xE6, 0x62, 0x13, 0x02, 0xA2, 0xD3, 0x01, 0x63, 0xAC, 0x86, 0x07, 0xF2,
+	 0x0E, 0x03, 0xD0, 0x80, 0x09, 0xF2, 0xFA, 0x02, 0x23, 0xFC, 0x25, 0x60, 0xEC, 0x64, 0x13, 0x60,
+	 0x0A, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x3C, 0x46,
+	 0x06, 0x64, 0xA1, 0xFF, 0x49, 0xFB, 0x83, 0x3E, 0x31, 0xF3, 0x87, 0x60, 0x80, 0x61, 0x1D, 0xF0,
+	 0x60, 0x40, 0x01, 0x2A, 0x0F, 0x00, 0xFE, 0xB4, 0x31, 0xFB, 0x00, 0x64, 0x49, 0xFB, 0x01, 0x64,
+	 0x47, 0xFB, 0x00, 0x71, 0x05, 0x64, 0x64, 0x5F, 0x0D, 0xFA, 0x40, 0x64, 0x3B, 0xDB, 0xC0, 0x60,
+	 0x5F, 0x78, 0xFF, 0xFF, 0x02, 0x2A, 0x18, 0x00, 0xD1, 0x91, 0x8D, 0xE2, 0x41, 0x64, 0x3B, 0xDB,
+	 0x31, 0xF3, 0x33, 0x60, 0xA6, 0x63, 0xFD, 0xB4, 0x31, 0xFB, 0xA3, 0xD3, 0x02, 0x63, 0x60, 0x5C,
+	 0x0D, 0xF2, 0x47, 0xFD, 0xFF, 0xB5, 0x60, 0x47, 0xFF, 0xB4, 0xD0, 0x80, 0xDC, 0x84, 0x1F, 0x03,
+	 0x60, 0x47, 0xB4, 0x84, 0x0D, 0xFA, 0x1B, 0x00, 0x08, 0x2A, 0x07, 0x00, 0x42, 0x64, 0x3B, 0xDB,
+	 0x31, 0xF3, 0xFF, 0xFF, 0xF7, 0xB4, 0x31, 0xFB, 0x12, 0x00, 0x10, 0x2A, 0x09, 0x00, 0x43, 0x64,
+	 0x3B, 0xDB, 0x31, 0xF3, 0xFF, 0xFF, 0xEF, 0xB4, 0x31, 0xFB, 0xBF, 0x60, 0xE4, 0x78, 0xFF, 0xFF,
+	 0x44, 0x64, 0x3B, 0xDB, 0x31, 0xF3, 0xFF, 0xFF, 0xDF, 0xB4, 0x31, 0xFB, 0x00, 0x00, 0x2A, 0x64,
+	 0x3B, 0xDB, 0xB7, 0x60, 0xF7, 0x64, 0x40, 0x40, 0xBD, 0x60, 0xD7, 0x78, 0xFF, 0xFF, 0x0E, 0x60,
+	 0xDF, 0xF3, 0xFF, 0xFF, 0x02, 0xB5, 0x04, 0xB5, 0x04, 0x03, 0x03, 0x03, 0xC1, 0x60, 0x70, 0x78,
+	 0xFF, 0xFF, 0x31, 0x40, 0x01, 0x26, 0x16, 0x00, 0xA0, 0x4C, 0x49, 0xBC, 0xFF, 0xB4, 0xA0, 0x51,
+	 0x0E, 0x60, 0xDF, 0xF3, 0xFF, 0xFF, 0x02, 0xB5, 0x04, 0xBC, 0x09, 0x03, 0x60, 0x40, 0x01, 0x26,
+	 0xED, 0xE2, 0xFE, 0xB4, 0xA2, 0xDB, 0xA0, 0x4C, 0x7D, 0xB4, 0xA0, 0x51, 0x03, 0x00, 0xA0, 0x4C,
+	 0x6D, 0xB4, 0xA0, 0x51, 0xDB, 0xF3, 0xFF, 0xFF, 0xFD, 0xA0, 0xFF, 0xFF, 0x08, 0x24, 0x59, 0x00,
+	 0x31, 0x40, 0x04, 0x2A, 0x38, 0x00, 0x01, 0x64, 0x19, 0x60, 0xF4, 0xFB, 0x6C, 0xF3, 0x73, 0xF3,
+	 0xCC, 0x83, 0x6C, 0xFD, 0xCC, 0x84, 0x73, 0xFB, 0x1E, 0x02, 0x31, 0x40, 0x02, 0x2A, 0x12, 0x00,
+	 0x6E, 0xF3, 0x6F, 0xF1, 0xCC, 0x84, 0x6E, 0xFB, 0x0D, 0x02, 0x6E, 0xF9, 0x31, 0x44, 0x08, 0xBC,
+	 0x40, 0x51, 0x71, 0xF3, 0x70, 0xF1, 0x00, 0xB8, 0x64, 0x45, 0x01, 0x03, 0x67, 0x45, 0x65, 0x50,
+	 0xCC, 0x84, 0x72, 0xFB, 0x16, 0x60, 0xAC, 0xF3, 0x6D, 0xF1, 0x00, 0xB8, 0x73, 0xF9, 0x03, 0x03,
+	 0x85, 0xF3, 0x6C, 0xFB, 0x04, 0x00, 0x6C, 0xF3, 0x85, 0xF1, 0x0D, 0x1B, 0x6C, 0xF9, 0x31, 0x40,
+	 0x01, 0x2A, 0x09, 0x00, 0x9D, 0xFE, 0x07, 0x05, 0xBA, 0xFE, 0x08, 0x64, 0x13, 0x60, 0x16, 0xFB,
+	 0x2D, 0xFF, 0xFF, 0xFF, 0xA3, 0xFE, 0x32, 0x40, 0x80, 0x2A, 0x12, 0x00, 0x31, 0x40, 0x04, 0x2A,
+	 0x0F, 0x00, 0x16, 0x60, 0xAC, 0xF3, 0x6C, 0xF1, 0x03, 0x1B, 0x31, 0x40, 0x02, 0x2A, 0x06, 0x00,
+	 0x73, 0xF3, 0xFF, 0xFF, 0xD0, 0x80, 0xFF, 0xFF, 0x01, 0x07, 0x60, 0x5C, 0x19, 0x60, 0xF5, 0xF9,
+	 0x00, 0x64, 0x19, 0x60, 0xF4, 0xFB, 0x0E, 0x60, 0x37, 0xF3, 0xFF, 0xFF, 0xCC, 0x84, 0xFF, 0x2B,
+	 0xA2, 0xDB, 0xCF, 0xF1, 0x07, 0x60, 0xE9, 0xF3, 0x64, 0x40, 0x02, 0x3A, 0x3A, 0x00, 0x0A, 0x60,
+	 0x18, 0xF1, 0x10, 0xB4, 0x90, 0x80, 0xFF, 0xFF, 0x34, 0x03, 0x0A, 0x60, 0x18, 0xFB, 0x01, 0x63,
+	 0x60, 0x40, 0x10, 0x22, 0x00, 0x63, 0x08, 0x60, 0xC1, 0xFD, 0x08, 0x60, 0xC5, 0xFD, 0x08, 0x60,
+	 0xC9, 0xFD, 0x08, 0x60, 0xCD, 0xFD, 0x7D, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x23, 0x21, 0x00,
+	 0x0B, 0x36, 0x07, 0x00, 0x0C, 0x36, 0x05, 0x00, 0x0D, 0x36, 0x03, 0x00, 0x0E, 0x36, 0x01, 0x00,
+	 0x18, 0x00, 0xDB, 0xF3, 0x01, 0x63, 0x0E, 0x60, 0x36, 0xFD, 0x60, 0x40, 0x03, 0x3A, 0x08, 0x00,
+	 0x08, 0x60, 0x15, 0xF1, 0x00, 0x60, 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x09, 0x00,
+	 0x04, 0x3A, 0x07, 0x00, 0x08, 0x60, 0x15, 0xF1, 0x00, 0x60, 0x10, 0x64, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xCF, 0xFE, 0x10, 0x64, 0x3B, 0xDB, 0x7E, 0xF3, 0x73, 0x45, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84,
+	 0xE0, 0x84, 0xC4, 0x93, 0xC9, 0xFE, 0x49, 0xF3, 0x3C, 0x46, 0x25, 0x18, 0xCC, 0x84, 0x49, 0xFB,
+	 0x22, 0x02, 0xC2, 0x60, 0x45, 0x64, 0x40, 0x42, 0xFC, 0xFC, 0x00, 0x64, 0x5C, 0x5C, 0x32, 0xFB,
+	 0x82, 0xFF, 0x5C, 0x47, 0x84, 0xFF, 0x62, 0xFF, 0x16, 0x60, 0x7E, 0xF3, 0xFF, 0xFF, 0xDC, 0x84,
+	 0x00, 0x36, 0x00, 0x3B, 0xA2, 0xDB, 0x23, 0xF0, 0x01, 0x64, 0xB0, 0x84, 0xA2, 0xDA, 0x25, 0x60,
+	 0xEC, 0x64, 0x13, 0x60, 0x0A, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0xC1, 0xFE, 0xCE, 0xFE, 0x69, 0xF3, 0xFF, 0xFF, 0x60, 0x41, 0xFD, 0xB4, 0xA2, 0xDB,
+	 0x61, 0x44, 0x01, 0xB0, 0x02, 0xB0, 0x0B, 0x03, 0x0A, 0x02, 0x9D, 0xFE, 0x08, 0x04, 0x1C, 0x60,
+	 0xCE, 0x64, 0x13, 0x60, 0x20, 0xFB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x07, 0x00,
+	 0x7E, 0xF3, 0x73, 0x45, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xC4, 0x93, 0x1D, 0x60,
+	 0xBA, 0x63, 0xA3, 0xD3, 0xAD, 0x49, 0x20, 0xB5, 0x08, 0xB1, 0x22, 0x03, 0xE1, 0x81, 0x10, 0xB5,
+	 0x95, 0x81, 0x60, 0x41, 0x18, 0x02, 0x1D, 0x60, 0xBC, 0x7C, 0xA4, 0xD3, 0xFF, 0xFF, 0xCC, 0x84,
+	 0xA4, 0xDB, 0x16, 0x02, 0x05, 0x64, 0xA4, 0xDB, 0x61, 0x44, 0x07, 0xB4, 0xFF, 0xFF, 0x10, 0x02,
+	 0x08, 0xB1, 0xE1, 0x81, 0x95, 0x81, 0xA3, 0xD3, 0x0B, 0x03, 0x08, 0xAC, 0x01, 0xBC, 0xA3, 0xDB,
+	 0xFF, 0xFF, 0x13, 0xFF, 0x05, 0x00, 0x10, 0xAC, 0xA3, 0xDB, 0x05, 0x7C, 0x0E, 0x60, 0xDE, 0xF9,
+	 0xB8, 0x60, 0x03, 0x78, 0xFF, 0xFF, 0x46, 0xF3, 0x45, 0xF1, 0x04, 0x1B, 0x64, 0x44, 0x02, 0x1B,
+	 0x07, 0x60, 0xED, 0xF3, 0x45, 0xFB, 0x00, 0x63, 0x46, 0xFD, 0x60, 0x41, 0x25, 0x64, 0x3B, 0xDB,
+	 0x27, 0x44, 0xEF, 0xB4, 0x40, 0x47, 0x00, 0xB9, 0x71, 0x40, 0x80, 0x27, 0x01, 0x12, 0x27, 0x03,
+	 0xC1, 0x60, 0xC5, 0x62, 0x84, 0xFF, 0x42, 0x42, 0x82, 0xFF, 0xA0, 0x4C, 0x14, 0xBC, 0xFF, 0xB4,
+	 0xA0, 0x51, 0x2D, 0x0A, 0xA1, 0xFF, 0xFF, 0xFF, 0x81, 0x3E, 0x70, 0x44, 0xAC, 0x80, 0x27, 0x0A,
+	 0x71, 0x40, 0x80, 0x27, 0xF7, 0x12, 0x45, 0xF3, 0x48, 0x02, 0x11, 0x18, 0x1B, 0x60, 0xEE, 0xF3,
+	 0x1B, 0x60, 0xEF, 0xF3, 0x07, 0x18, 0x06, 0x18, 0xAC, 0x4C, 0x80, 0x26, 0x03, 0x00, 0x00, 0x64,
+	 0x45, 0xFB, 0x05, 0x00, 0x45, 0xF3, 0xFF, 0xFF, 0xCC, 0x84, 0x45, 0xFB, 0xE3, 0x02, 0x06, 0x0A,
+	 0xA0, 0x4C, 0xFB, 0xB4, 0xA0, 0x51, 0xA4, 0x60, 0x58, 0x78, 0xFF, 0xFF, 0x84, 0xFF, 0xC1, 0x60,
+	 0xA3, 0x64, 0x40, 0x42, 0x82, 0xFF, 0xA0, 0x4C, 0x14, 0xBC, 0xFF, 0xB4, 0xA0, 0x51, 0xB0, 0x60,
+	 0x9E, 0x78, 0xFF, 0xFF, 0x3C, 0x44, 0xAC, 0x80, 0x32, 0xF1, 0x25, 0x03, 0x64, 0x40, 0x07, 0x22,
+	 0x22, 0x00, 0xA4, 0x60, 0x36, 0x78, 0xFF, 0xFF, 0xA0, 0x4C, 0x1C, 0xBC, 0xDF, 0xB4, 0xA0, 0x51,
+	 0x31, 0x40, 0x08, 0x2A, 0xEF, 0x01, 0x72, 0xF3, 0x70, 0xF1, 0x00, 0xA0, 0xDC, 0x80, 0x05, 0x03,
+	 0x08, 0x03, 0xCC, 0x84, 0x72, 0xFB, 0x67, 0x50, 0x08, 0x00, 0xCC, 0x84, 0x72, 0xFB, 0x64, 0x50,
+	 0x04, 0x00, 0x31, 0x44, 0xF7, 0xB4, 0x40, 0x51, 0x06, 0x00, 0x28, 0x64, 0x3A, 0xDB, 0xA0, 0x4C,
+	 0x30, 0xBC, 0xF3, 0xB4, 0xA0, 0x51, 0xA1, 0xFF, 0xFF, 0xFF, 0x81, 0x3E, 0x28, 0x64, 0x3B, 0xDB,
+	 0x07, 0x60, 0xEE, 0xF3, 0x32, 0x40, 0x02, 0x27, 0x16, 0x00, 0x46, 0xFB, 0x14, 0x18, 0xC2, 0x60,
+	 0x33, 0x64, 0x84, 0xFF, 0x40, 0x42, 0x82, 0xFF, 0xA0, 0x4C, 0x15, 0xBC, 0xF7, 0xB4, 0xA0, 0x51,
+	 0xA1, 0xFF, 0xFF, 0xFF, 0x81, 0x3E, 0x70, 0x44, 0xAC, 0x80, 0x46, 0xF3, 0xB8, 0x0A, 0xDD, 0x02,
+	 0xCC, 0x84, 0x46, 0xFB, 0xF5, 0x02, 0x84, 0xFF, 0xC2, 0x60, 0x45, 0x64, 0x40, 0x42, 0x82, 0xFF,
+	 0x27, 0x44, 0x08, 0xBC, 0x40, 0x47, 0xF9, 0xE1, 0x04, 0x00, 0x78, 0xE1, 0x31, 0x40, 0x01, 0x26,
+	 0xF9, 0xE1, 0xA4, 0x60, 0x2D, 0x78, 0xFF, 0xFF, 0x19, 0x60, 0xAB, 0xF1, 0x60, 0x45, 0x33, 0x60,
+	 0x6A, 0x61, 0xC5, 0x83, 0xA3, 0xD3, 0xFF, 0xFF, 0x60, 0x41, 0x66, 0x45, 0x24, 0x46, 0x0E, 0xF2,
+	 0x65, 0x46, 0x64, 0x45, 0xD5, 0x81, 0x61, 0x45, 0x00, 0x7F, 0xD4, 0x80, 0x64, 0x43, 0x08, 0x04,
+	 0xE3, 0x83, 0x63, 0x45, 0xC5, 0x81, 0x61, 0x45, 0xD4, 0x80, 0x02, 0x65, 0x03, 0x07, 0x03, 0x00,
+	 0x00, 0x65, 0x01, 0x00, 0x01, 0x65, 0x2E, 0x58, 0xFF, 0xFF, 0x66, 0x43, 0x64, 0x46, 0x8F, 0xF0,
+	 0x12, 0xF2, 0x91, 0xF2, 0x60, 0x40, 0x10, 0x36, 0x05, 0x00, 0x12, 0x36, 0x08, 0x00, 0x0C, 0x36,
+	 0x0B, 0x00, 0x0F, 0x00, 0x40, 0x61, 0xA5, 0x80, 0x0A, 0x64, 0x13, 0x02, 0xF3, 0x01, 0x10, 0x61,
+	 0xA5, 0x80, 0x0E, 0x64, 0x0E, 0x02, 0xEE, 0x01, 0x08, 0x61, 0xA5, 0x80, 0x10, 0x64, 0x09, 0x02,
+	 0xE9, 0x01, 0xE1, 0x81, 0xA5, 0x80, 0x03, 0x05, 0xC8, 0x84, 0x03, 0x02, 0xE3, 0x01, 0xFF, 0x61,
+	 0x02, 0x00, 0x12, 0xFA, 0x91, 0xFA, 0x63, 0x46, 0x2E, 0x58, 0xFF, 0xFF, 0x8F, 0xF0, 0x12, 0xF2,
+	 0x91, 0xF2, 0x60, 0x40, 0x0A, 0x36, 0x05, 0x00, 0x0E, 0x36, 0x08, 0x00, 0x10, 0x36, 0x0B, 0x00,
+	 0x0F, 0x00, 0x08, 0x61, 0xA5, 0x80, 0x10, 0x7E, 0x11, 0x02, 0xF3, 0x01, 0x04, 0x61, 0xA5, 0x80,
+	 0x12, 0x7E, 0x0C, 0x02, 0xEE, 0x01, 0x20, 0x61, 0xA5, 0x80, 0x0C, 0x7E, 0x07, 0x02, 0xE9, 0x01,
+	 0xE9, 0x81, 0xA5, 0x80, 0x05, 0x05, 0xD8, 0x84, 0x01, 0x02, 0xE3, 0x01, 0x12, 0xFA, 0x91, 0xFA,
+	 0x2E, 0x58, 0xFF, 0xFF, 0x28, 0x40, 0x08, 0x3A, 0x06, 0x00, 0x04, 0x60, 0x40, 0x62, 0x3D, 0x60,
+	 0x58, 0x4D, 0x3B, 0x78, 0xFF, 0xFF, 0x2F, 0x58, 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x2B, 0x50, 0x00,
+	 0x28, 0x40, 0x08, 0x3A, 0x4D, 0x00, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0x19, 0x60,
+	 0x52, 0xFB, 0x7D, 0xF1, 0x2B, 0x60, 0x82, 0x63, 0x64, 0x40, 0x01, 0x27, 0x3C, 0xA3, 0x29, 0x40,
+	 0x40, 0x2B, 0x1E, 0xA3, 0xBD, 0xD1, 0x63, 0x45, 0x44, 0x4E, 0x0E, 0x61, 0xBD, 0xD1, 0xCD, 0x81,
+	 0xD0, 0x80, 0x01, 0x03, 0xFB, 0x04, 0xCB, 0x83, 0x19, 0x60, 0x55, 0xF3, 0x39, 0xF1, 0xD7, 0x83,
+	 0xEB, 0x83, 0x2E, 0x41, 0x5D, 0x93, 0xDF, 0x83, 0x19, 0x60, 0x51, 0xFD, 0x19, 0x60, 0x50, 0xFB,
+	 0x53, 0x93, 0xDF, 0x80, 0x10, 0x03, 0x38, 0xF3, 0xCF, 0x83, 0x08, 0x03, 0xDF, 0x83, 0x0B, 0x02,
+	 0xDF, 0x83, 0xDC, 0x84, 0xF0, 0xA0, 0x38, 0xFB, 0x06, 0x03, 0x03, 0x00, 0xCC, 0x84, 0x38, 0xFB,
+	 0x02, 0x03, 0x00, 0x63, 0x02, 0x00, 0x08, 0x64, 0x38, 0xFB, 0xE3, 0x80, 0xFB, 0x83, 0xC3, 0x83,
+	 0x63, 0x44, 0xFC, 0xA0, 0x02, 0x0E, 0x08, 0x07, 0x08, 0x00, 0x04, 0xA4, 0xFF, 0xFF, 0x05, 0x0D,
+	 0xFC, 0x64, 0xFF, 0x7F, 0x60, 0x43, 0x01, 0x00, 0x04, 0x63, 0x39, 0xFD, 0x19, 0x60, 0x54, 0xFD,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x19, 0x60, 0x74, 0xF3, 0x40, 0x4E, 0x60, 0x46, 0x2F, 0xDB, 0x44, 0x44,
+	 0xA1, 0xD3, 0xD9, 0x81, 0x48, 0x94, 0x24, 0x5C, 0xD0, 0x9C, 0x66, 0x42, 0x04, 0x06, 0xD2, 0x9C,
+	 0x2F, 0xD9, 0x64, 0x46, 0x24, 0x44, 0xE0, 0x84, 0x44, 0xD3, 0xA3, 0xDB, 0xFF, 0xB4, 0x60, 0x5C,
+	 0x66, 0x44, 0x22, 0xA4, 0xD0, 0x84, 0xE0, 0xA0, 0x02, 0x0D, 0x00, 0x64, 0x02, 0x00, 0x01, 0x04,
+	 0x1F, 0x64, 0xA2, 0xD3, 0x60, 0x5C, 0x64, 0x5E, 0x60, 0x47, 0x2F, 0xD1, 0x28, 0xA3, 0xA3, 0xD9,
+	 0xD8, 0xA3, 0x2E, 0x42, 0x4E, 0x8E, 0xBD, 0xDB, 0xDB, 0x02, 0x2D, 0x58, 0xFF, 0xFF, 0x43, 0xFF,
+	 0x39, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x84, 0x3E, 0xFB, 0x01, 0x3D, 0x44, 0x00, 0xA8, 0xFF, 0xFF,
+	 0x03, 0x02, 0x40, 0xFF, 0x44, 0xFF, 0xF4, 0x01, 0xA0, 0x4C, 0x3D, 0x46, 0x2A, 0xF2, 0x46, 0x4D,
+	 0x92, 0xFC, 0x10, 0x25, 0x12, 0x00, 0x09, 0xE1, 0xA1, 0xFF, 0x2D, 0x46, 0x0F, 0xF2, 0x01, 0x29,
+	 0x06, 0x00, 0x2A, 0xF0, 0x40, 0xFF, 0x64, 0x40, 0x40, 0x2B, 0x08, 0xBC, 0x02, 0xBC, 0x0F, 0xFA,
+	 0x08, 0x25, 0xDD, 0x01, 0xCB, 0xFE, 0x5C, 0x5D, 0xDB, 0x01, 0x44, 0xFF, 0x31, 0xF2, 0x1D, 0x60,
+	 0xC0, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46, 0x60, 0x43,
+	 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46, 0x31, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2, 0x0C, 0x02,
+	 0x61, 0x46, 0x30, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46, 0x2F, 0xF0,
+	 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46, 0xE8, 0x1B,
+	 0xA6, 0xF3, 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0x07, 0xFC, 0x3F, 0xF2, 0x09, 0x60, 0xB0, 0x65,
+	 0xD4, 0x80, 0x2A, 0xF2, 0xC0, 0x05, 0x08, 0x25, 0xAA, 0x01, 0x5C, 0x4B, 0x0C, 0x60, 0xEA, 0x61,
+	 0xA1, 0xDF, 0x2D, 0x46, 0x3B, 0xF2, 0xA6, 0xF1, 0x87, 0xF4, 0x60, 0x40, 0x20, 0x2B, 0xC1, 0x00,
+	 0xD3, 0x80, 0x2C, 0xF0, 0xB0, 0x03, 0x07, 0xF4, 0x64, 0x40, 0x01, 0x26, 0xA6, 0xF5, 0xBA, 0xF4,
+	 0x2D, 0x46, 0x04, 0x64, 0x04, 0xB3, 0x22, 0xF0, 0x03, 0x03, 0xC5, 0x60, 0xE2, 0x78, 0xFF, 0xFF,
+	 0x10, 0x64, 0xB0, 0x9C, 0x3B, 0xF2, 0x22, 0xF8, 0x60, 0x47, 0xC0, 0xB7, 0x02, 0xFE, 0xF0, 0x84,
+	 0xF0, 0x84, 0xF0, 0x84, 0x00, 0xA8, 0x40, 0x4A, 0x17, 0x03, 0xE0, 0x81, 0x61, 0x43, 0x42, 0xFE,
+	 0x00, 0x64, 0xF0, 0x84, 0xFE, 0x1F, 0x40, 0x4A, 0xE1, 0x84, 0xE0, 0x84, 0x2D, 0x46, 0x07, 0xF4,
+	 0xE0, 0x81, 0x3B, 0xF0, 0x2A, 0x47, 0x0C, 0x60, 0x38, 0x63, 0xA0, 0x84, 0x47, 0x9C, 0x10, 0x03,
+	 0x7C, 0x44, 0x00, 0x60, 0xB2, 0x63, 0x1C, 0x00, 0x07, 0xF4, 0x3B, 0xF0, 0x66, 0x44, 0x64, 0x40,
+	 0x80, 0x2B, 0x06, 0x00, 0x00, 0x60, 0x78, 0x7C, 0x00, 0x60, 0xA2, 0x63, 0x43, 0x4C, 0x10, 0x00,
+	 0x2D, 0x46, 0xC5, 0x60, 0xD5, 0x78, 0xFF, 0xFF, 0x2D, 0x46, 0x22, 0xF2, 0x10, 0x60, 0x00, 0x7C,
+	 0xB0, 0x84, 0x22, 0xFA, 0x32, 0x40, 0x04, 0x26, 0x25, 0x00, 0xC5, 0x60, 0xD5, 0x78, 0xFF, 0xFF,
+	 0xED, 0xFB, 0xEE, 0xF9, 0xEF, 0xFD, 0xAD, 0x46, 0x3D, 0xF2, 0xAD, 0x46, 0xA3, 0xD0, 0xAD, 0x46,
+	 0xD0, 0x80, 0x3C, 0xF2, 0xAD, 0x46, 0x02, 0x03, 0x15, 0x07, 0xE6, 0x04, 0x5B, 0xD0, 0xAD, 0x46,
+	 0xD0, 0x80, 0x3A, 0xF2, 0x03, 0x03, 0xAD, 0x46, 0x0D, 0x07, 0xDE, 0x04, 0x3A, 0xF0, 0xAD, 0x46,
+	 0x5B, 0xD0, 0x64, 0x44, 0xD0, 0x80, 0x2B, 0x44, 0x05, 0x07, 0xD6, 0x03, 0xD0, 0x84, 0x10, 0xA4,
+	 0xFF, 0xFF, 0x00, 0x07, 0xEE, 0xF3, 0xED, 0xF5, 0xFE, 0xA4, 0x0F, 0x60, 0xBE, 0x61, 0x0E, 0x63,
+	 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0x2D, 0x46, 0x8B, 0xFF, 0x2D, 0x46, 0x22, 0xF2, 0x20, 0x60,
+	 0x00, 0x7C, 0xB0, 0x84, 0x22, 0xFA, 0x0F, 0x60, 0xB0, 0x64, 0xC9, 0x60, 0x58, 0x4F, 0x56, 0x78,
+	 0xFF, 0xFF, 0x3F, 0xF2, 0x00, 0x60, 0x18, 0x70, 0x18, 0x71, 0x20, 0x72, 0x60, 0x53, 0x88, 0x75,
+	 0x00, 0xF2, 0x09, 0xE1, 0x60, 0x50, 0x12, 0x71, 0x6E, 0x72, 0x83, 0x75, 0xA1, 0xFF, 0xFF, 0xFF,
+	 0x08, 0x25, 0x1D, 0x00, 0x40, 0xFF, 0x02, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x75, 0x40, 0x03, 0x2A,
+	 0x03, 0x00, 0x80, 0x75, 0x0A, 0x64, 0x0B, 0x00, 0x80, 0x75, 0x1B, 0xF3, 0x8B, 0xFF, 0x02, 0x60,
+	 0x00, 0x75, 0xFF, 0xFF, 0x02, 0x60, 0x00, 0x75, 0xDC, 0x84, 0xA2, 0xDB, 0x02, 0x64, 0x98, 0xFF,
+	 0x2D, 0x46, 0x0F, 0xF0, 0xFF, 0xFF, 0xB0, 0x84, 0xA2, 0xDA, 0x88, 0xFF, 0x0B, 0x01, 0x8B, 0xFF,
+	 0x02, 0x60, 0x00, 0x75, 0xFF, 0xFF, 0x02, 0x60, 0x00, 0x75, 0x88, 0xFF, 0xC5, 0x60, 0xBB, 0x78,
+	 0xFF, 0xFF, 0x22, 0xF0, 0x22, 0x64, 0xB0, 0x84, 0x22, 0xFA, 0x3A, 0xF0, 0xFF, 0xFF, 0x64, 0x44,
+	 0xE0, 0x7F, 0xA0, 0x5B, 0x64, 0x47, 0xE1, 0x7F, 0x5A, 0xD0, 0xA0, 0x5B, 0x64, 0x44, 0xE2, 0x7F,
+	 0xA0, 0x5B, 0x64, 0x47, 0x7C, 0x5F, 0xE8, 0x84, 0xE8, 0x85, 0x0D, 0x60, 0x00, 0x64, 0x44, 0xD3,
+	 0x5A, 0xD1, 0x03, 0x1B, 0xC5, 0x60, 0xD5, 0x78, 0xFF, 0xFF, 0x60, 0x45, 0x64, 0x44, 0xE3, 0x7F,
+	 0xA0, 0x5B, 0x64, 0x47, 0xE4, 0x7F, 0x5A, 0xD1, 0xA0, 0x5B, 0x64, 0x44, 0xE5, 0x7F, 0xA0, 0x5B,
+	 0x64, 0x47, 0xE6, 0x7F, 0x5A, 0xD1, 0xA0, 0x5B, 0x64, 0x44, 0xE7, 0x7F, 0xA0, 0x5B, 0x65, 0x40,
+	 0x0D, 0x3A, 0x1C, 0x00, 0x64, 0x47, 0xE8, 0x7F, 0x5A, 0xD1, 0xA0, 0x5B, 0x64, 0x44, 0xE9, 0x7F,
+	 0xA0, 0x5B, 0x64, 0x47, 0xEA, 0x7F, 0x5A, 0xD1, 0xA0, 0x5B, 0x64, 0x44, 0xEB, 0x7F, 0xA0, 0x5B,
+	 0x64, 0x47, 0xEC, 0x7F, 0x5A, 0xD1, 0xA0, 0x5B, 0x64, 0x44, 0xED, 0x7F, 0xA0, 0x5B, 0x64, 0x47,
+	 0xEE, 0x7F, 0x5A, 0xD1, 0xA0, 0x5B, 0x64, 0x44, 0xEF, 0x7F, 0xA0, 0x5B, 0x65, 0x44, 0xD8, 0x84,
+	 0x08, 0x25, 0x25, 0x00, 0x60, 0x7F, 0xA0, 0x5B, 0x80, 0x60, 0x00, 0xEB, 0xA0, 0x60, 0x00, 0xEB,
+	 0xD1, 0x60, 0x00, 0xEB, 0x22, 0xF2, 0x20, 0x60, 0x00, 0x7C, 0xB0, 0x84, 0x22, 0xFA, 0x3F, 0xF2,
+	 0x3B, 0xF0, 0x60, 0x43, 0xFC, 0xA4, 0x64, 0x40, 0x20, 0x2B, 0x04, 0x00, 0x08, 0xA4, 0x3F, 0xFA,
+	 0x08, 0xA3, 0xF8, 0xA3, 0x3F, 0xFA, 0x0A, 0xE1, 0xB3, 0xFF, 0x9A, 0xFF, 0xCB, 0x83, 0x00, 0xF4,
+	 0x10, 0x62, 0x6C, 0x61, 0x0E, 0xA3, 0xAB, 0x84, 0xF2, 0xA3, 0xA1, 0xFF, 0x09, 0x00, 0xDA, 0x00,
+	 0x00, 0xF4, 0x81, 0xF2, 0xFC, 0x18, 0x02, 0x62, 0xC9, 0x81, 0xAB, 0x84, 0x01, 0x00, 0xA2, 0xDC,
+	 0x7A, 0xD4, 0xFD, 0x1C, 0xA2, 0xDC, 0x08, 0x25, 0xCE, 0x00, 0xF2, 0x1D, 0x41, 0x44, 0x7C, 0xA8,
+	 0xD9, 0x81, 0xEE, 0x03, 0xFF, 0xB1, 0x98, 0xFF, 0x09, 0xE1, 0xA1, 0xFF, 0xFF, 0xFF, 0x64, 0x40,
+	 0x20, 0x27, 0x04, 0x00, 0x08, 0x25, 0xBF, 0x00, 0x7B, 0x1E, 0x6F, 0x00, 0x08, 0x25, 0xBB, 0x00,
+	 0x40, 0xFF, 0x42, 0x42, 0x46, 0x43, 0x06, 0x1E, 0x04, 0x02, 0x00, 0xF4, 0x02, 0x62, 0x42, 0x42,
+	 0x46, 0x43, 0x01, 0xA2, 0x63, 0x45, 0x01, 0xA2, 0x62, 0x43, 0x46, 0x4C, 0xC6, 0x60, 0x58, 0x4F,
+	 0x87, 0x78, 0xFF, 0xFF, 0x0A, 0xE1, 0x9A, 0xFF, 0x2D, 0x46, 0x12, 0xF2, 0x3B, 0xF0, 0x33, 0x1B,
+	 0x64, 0x40, 0x20, 0x2B, 0x38, 0x00, 0x2D, 0x5C, 0x24, 0x41, 0x02, 0xA1, 0x65, 0x43, 0x08, 0xA3,
+	 0x23, 0x46, 0x22, 0x42, 0x7E, 0x3A, 0x0A, 0x00, 0x00, 0xF4, 0x81, 0xF2, 0xB8, 0x18, 0x02, 0x62,
+	 0xC9, 0x81, 0xAB, 0x84, 0x03, 0x00, 0xA2, 0xDC, 0x7E, 0x36, 0xF6, 0x01, 0x15, 0x11, 0x7A, 0xD4,
+	 0xFF, 0xFF, 0xF9, 0x1C, 0xA2, 0xDC, 0xF0, 0x1D, 0xD9, 0x81, 0xFF, 0xB1, 0x41, 0x1E, 0x62, 0x40,
+	 0x7E, 0x3A, 0x02, 0x00, 0x00, 0xF4, 0x02, 0x62, 0x07, 0x11, 0x5A, 0xD2, 0x89, 0xFF, 0x80, 0x4F,
+	 0x6F, 0x44, 0xA2, 0xDA, 0x88, 0xFF, 0x34, 0x00, 0x62, 0x45, 0x33, 0xF3, 0xFF, 0xFF, 0x03, 0x1B,
+	 0x65, 0x42, 0xE5, 0x1D, 0xF2, 0x01, 0x98, 0xFF, 0x2D, 0x46, 0x01, 0x64, 0x12, 0xFA, 0x0F, 0xF0,
+	 0x0A, 0x64, 0xB0, 0x84, 0x41, 0x00, 0x24, 0x41, 0x02, 0xA1, 0x65, 0x43, 0x08, 0xA3, 0x23, 0x46,
+	 0x22, 0x42, 0x7E, 0x3A, 0x0A, 0x00, 0x00, 0xF4, 0x81, 0xF2, 0x5C, 0x18, 0x02, 0x62, 0xC9, 0x81,
+	 0xAB, 0x84, 0x03, 0x00, 0xA2, 0xDC, 0x7E, 0x36, 0xF6, 0x01, 0x7A, 0xD4, 0xFF, 0xFF, 0xFA, 0x1C,
+	 0xA2, 0xDC, 0xF1, 0x1D, 0xD9, 0x81, 0xFF, 0xB1, 0x0B, 0x1E, 0x62, 0x40, 0x7E, 0x3A, 0x02, 0x00,
+	 0x00, 0xF4, 0x02, 0x62, 0x5A, 0xD2, 0x89, 0xFF, 0x80, 0x4F, 0x6F, 0x44, 0xA2, 0xDA, 0x88, 0xFF,
+	 0x98, 0xFF, 0x2D, 0x46, 0x0F, 0xF0, 0x0A, 0x64, 0xB0, 0x84, 0x16, 0x14, 0xF7, 0xB4, 0xA2, 0xDA,
+	 0x06, 0x60, 0x75, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x2A, 0x0B, 0x00, 0xF0, 0xF5, 0xEF, 0xF4,
+	 0x0C, 0x60, 0xEA, 0x61, 0x59, 0xD1, 0x3B, 0xF8, 0x05, 0x64, 0x59, 0xD1, 0xCC, 0x84, 0xBD, 0xD8,
+	 0xFC, 0x02, 0xC3, 0x60, 0x6A, 0x78, 0xFF, 0xFF, 0xA2, 0xDA, 0x2D, 0x46, 0x3B, 0xF0, 0xFF, 0xFF,
+	 0x64, 0x40, 0x20, 0x2B, 0x1C, 0x00, 0x07, 0xF4, 0xBB, 0xF0, 0x2A, 0x44, 0xA4, 0x84, 0xFF, 0xFF,
+	 0x2F, 0x26, 0x15, 0x00, 0x2D, 0x46, 0x64, 0x44, 0x3A, 0xF0, 0xBC, 0xF0, 0x64, 0x5F, 0x3D, 0xF0,
+	 0x07, 0xF4, 0xEF, 0xF4, 0xFF, 0xFF, 0x08, 0xA3, 0x5B, 0xD8, 0x65, 0x5C, 0x5B, 0xD8, 0x5B, 0xDA,
+	 0x2D, 0x46, 0xED, 0xF3, 0x3C, 0xFA, 0xEE, 0xF3, 0x3D, 0xFA, 0x2A, 0x44, 0x23, 0xFA, 0xC3, 0x60,
+	 0x6A, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0x98, 0xFF, 0x43, 0xFF, 0x40, 0xFF, 0xB0, 0xFF, 0xB1, 0xFF,
+	 0x2D, 0x46, 0x0C, 0x60, 0xEA, 0x61, 0xA1, 0xD3, 0x2D, 0x46, 0x60, 0x40, 0x01, 0x2A, 0x0A, 0x00,
+	 0xF0, 0xF5, 0xEF, 0xF4, 0x59, 0xD1, 0x3B, 0xF8, 0x05, 0x64, 0x59, 0xD1, 0xCC, 0x84, 0xBD, 0xD8,
+	 0xFC, 0x02, 0x2D, 0x46, 0xC3, 0x60, 0x48, 0x78, 0xFF, 0xFF, 0x98, 0xFF, 0x09, 0xE1, 0xA1, 0xFF,
+	 0x2D, 0x46, 0x08, 0x25, 0xE0, 0x01, 0x0F, 0xF2, 0x40, 0xFF, 0x02, 0xBC, 0xA2, 0xDA, 0xC3, 0x60,
+	 0x6A, 0x78, 0xFF, 0xFF, 0xB0, 0x84, 0x22, 0xFA, 0xA0, 0x60, 0x00, 0xEB, 0xB0, 0x60, 0x00, 0xEB,
+	 0x00, 0x63, 0x3B, 0xF2, 0x06, 0x60, 0x75, 0xFD, 0x60, 0x47, 0xC0, 0xB7, 0x02, 0xFE, 0xF0, 0x84,
+	 0xF0, 0x84, 0xF0, 0x84, 0x00, 0xA8, 0x40, 0x4A, 0x16, 0x03, 0xE0, 0x81, 0x61, 0x43, 0x42, 0xFE,
+	 0x00, 0x64, 0xF0, 0x84, 0xFE, 0x1F, 0x40, 0x4A, 0xE1, 0x84, 0xE0, 0x84, 0x2D, 0x46, 0x07, 0xF4,
+	 0xE0, 0x81, 0x3B, 0xF0, 0x2A, 0x47, 0x0C, 0x60, 0x38, 0x63, 0xA0, 0x84, 0x47, 0x9C, 0x10, 0x03,
+	 0x7C, 0x44, 0xA8, 0x63, 0x0F, 0x00, 0x07, 0xF4, 0x20, 0x64, 0x40, 0x4A, 0x3B, 0xF0, 0x66, 0x44,
+	 0x64, 0x40, 0x80, 0x2B, 0x05, 0x00, 0x00, 0x60, 0x78, 0x7C, 0x00, 0x60, 0x98, 0x63, 0x02, 0x00,
+	 0x2D, 0x46, 0xBB, 0x01, 0x2D, 0x46, 0xED, 0xFB, 0xEE, 0xF9, 0xEF, 0xFD, 0x07, 0xF2, 0xF0, 0xFB,
+	 0x60, 0x46, 0x3B, 0xF0, 0x2A, 0x44, 0x06, 0x60, 0x76, 0xF9, 0x5C, 0x4B, 0xA0, 0x84, 0xFF, 0xFF,
+	 0x3F, 0x22, 0x05, 0x00, 0x90, 0x84, 0x3B, 0xFA, 0x01, 0x64, 0x40, 0x4B, 0x2C, 0x00, 0xAD, 0x46,
+	 0x0A, 0xA3, 0x3D, 0xF2, 0xAD, 0x46, 0xA3, 0xD0, 0xAD, 0x46, 0xD0, 0x80, 0x3C, 0xF2, 0xAD, 0x46,
+	 0x02, 0x03, 0x21, 0x07, 0x14, 0x04, 0x5B, 0xD0, 0xAD, 0x46, 0xD0, 0x80, 0x3B, 0xF2, 0x03, 0x03,
+	 0xAD, 0x46, 0x19, 0x07, 0x0C, 0x04, 0x3A, 0xF0, 0xAD, 0x46, 0x5B, 0xD0, 0x64, 0x5F, 0xD0, 0x80,
+	 0x2B, 0x44, 0x22, 0x07, 0x04, 0x03, 0xD0, 0x84, 0x10, 0xA4, 0xFF, 0xFF, 0x1D, 0x07, 0x2D, 0x46,
+	 0x22, 0xF2, 0x10, 0x60, 0x00, 0x7C, 0xB0, 0x84, 0x22, 0xFA, 0x32, 0x40, 0x04, 0x26, 0x14, 0x00,
+	 0xC5, 0x60, 0xD5, 0x78, 0xFF, 0xFF, 0x01, 0x64, 0x06, 0x60, 0x75, 0xFB, 0x2D, 0x46, 0x0C, 0x60,
+	 0xFA, 0x62, 0x80, 0xFF, 0x78, 0x44, 0x03, 0xA4, 0xA2, 0xDB, 0xC6, 0x60, 0xBC, 0x78, 0xFF, 0xFF,
+	 0x85, 0xFF, 0x2D, 0x46, 0x08, 0x25, 0x4F, 0x01, 0x2D, 0x46, 0x0C, 0x60, 0xFA, 0x62, 0x80, 0xFF,
+	 0x78, 0x44, 0x03, 0xA4, 0xA2, 0xDB, 0xC7, 0x60, 0x44, 0x78, 0xFF, 0xFF, 0x85, 0xFF, 0x2D, 0x46,
+	 0x08, 0x25, 0x41, 0x01, 0x00, 0x60, 0x0F, 0x64, 0x08, 0x25, 0x3C, 0x01, 0x60, 0x7F, 0xA0, 0x5B,
+	 0x80, 0x60, 0x00, 0xEB, 0xD3, 0x60, 0x00, 0xEB, 0xC4, 0x60, 0xC2, 0x78, 0xFF, 0xFF, 0x2D, 0x46,
+	 0x3B, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x20, 0x2B, 0x23, 0x00, 0x08, 0x61, 0x23, 0x11, 0x2D, 0x46,
+	 0x00, 0xF4, 0x0A, 0x62, 0x56, 0x92, 0x5A, 0xD0, 0x2C, 0x46, 0x64, 0x47, 0x63, 0x40, 0x7F, 0x2A,
+	 0x03, 0x00, 0x00, 0xF4, 0x03, 0x63, 0x46, 0x4C, 0x60, 0xFE, 0xDE, 0xD8, 0x7F, 0x3A, 0x03, 0x00,
+	 0x00, 0xF4, 0x03, 0x63, 0x46, 0x4C, 0xDE, 0xDA, 0xFE, 0xA1, 0x20, 0xFE, 0xE7, 0x02, 0x63, 0x41,
+	 0xFD, 0xA1, 0x46, 0x4C, 0x01, 0xF2, 0x2D, 0x46, 0x61, 0x5E, 0x16, 0xFA, 0x2C, 0x44, 0x06, 0xFA,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x2D, 0x5C, 0x3D, 0x44, 0x00, 0xA8, 0xD0, 0x80, 0xD8, 0x03, 0xD7, 0x03,
+	 0x2D, 0x46, 0x01, 0x64, 0x12, 0xFA, 0xF4, 0x01, 0x07, 0xF4, 0x66, 0x41, 0x03, 0xF2, 0x04, 0xF2,
+	 0x40, 0x42, 0x05, 0xF2, 0x40, 0x43, 0x40, 0x44, 0x61, 0x46, 0x3C, 0xF2, 0x3D, 0xF2, 0x40, 0x40,
+	 0x40, 0x41, 0x0D, 0x60, 0x70, 0x65, 0x00, 0x61, 0xEE, 0xF1, 0xED, 0xF5, 0x44, 0x4C, 0x2C, 0x5C,
+	 0xE9, 0x80, 0x00, 0x64, 0xF0, 0x84, 0xF0, 0x84, 0xC0, 0x83, 0xBD, 0xD2, 0x24, 0x5C, 0x90, 0x9C,
+	 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1,
+	 0x64, 0x47, 0x90, 0x9C, 0x20, 0x44, 0x40, 0x80, 0xDB, 0x83, 0xBD, 0xD2, 0x20, 0x5C, 0x90, 0x9C,
+	 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1,
+	 0x64, 0x47, 0x90, 0x9C, 0x21, 0x44, 0x40, 0x81, 0xDB, 0x83, 0xBD, 0xD2, 0x21, 0x5C, 0x90, 0x9C,
+	 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1,
+	 0x64, 0x47, 0x90, 0x9C, 0x22, 0x44, 0x40, 0x82, 0xDB, 0x83, 0xBD, 0xD2, 0x22, 0x5C, 0x90, 0x9C,
+	 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1,
+	 0x64, 0x47, 0x90, 0x9C, 0x23, 0x44, 0x40, 0x83, 0xF2, 0xA3, 0xBD, 0xD2, 0x23, 0x5C, 0x90, 0x9C,
+	 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1,
+	 0x64, 0x47, 0x90, 0x9C, 0x24, 0x44, 0xC0, 0x9C, 0x41, 0x84, 0xDD, 0x81, 0x08, 0x2A, 0xA7, 0x01,
+	 0x0C, 0x60, 0xEC, 0x61, 0x05, 0x64, 0xEF, 0xF4, 0xF0, 0xF5, 0xFE, 0xA3, 0x5B, 0xD0, 0xCC, 0x84,
+	 0x59, 0xD9, 0xFC, 0x02, 0xEF, 0xF3, 0xF0, 0xF5, 0x60, 0x42, 0x20, 0x44, 0xA2, 0xDA, 0x21, 0x44,
+	 0x5A, 0xDA, 0x22, 0x44, 0x5A, 0xDA, 0x23, 0x44, 0x5A, 0xDA, 0x24, 0x44, 0x5A, 0xDA, 0x61, 0x46,
+	 0x06, 0x60, 0x7D, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x41, 0xEF, 0xF3, 0xF0, 0xF5, 0xA0, 0xD2,
+	 0x5A, 0xD0, 0x40, 0x40, 0x44, 0x41, 0x5A, 0xD2, 0x5A, 0xD0, 0x40, 0x42, 0x5A, 0xD0, 0x44, 0x43,
+	 0x61, 0x46, 0xBA, 0xF0, 0x3B, 0xF2, 0x44, 0x44, 0x65, 0x5F, 0x40, 0x85, 0xEE, 0xF4, 0xED, 0xF5,
+	 0x43, 0x4C, 0x0D, 0x60, 0x70, 0x65, 0xBD, 0xD2, 0x25, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C,
+	 0x20, 0x44, 0x40, 0x80, 0xBD, 0xD2, 0x20, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84,
+	 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x21, 0x44,
+	 0x40, 0x81, 0xBD, 0xD2, 0x21, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1,
+	 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x22, 0x44, 0x40, 0x82,
+	 0xBD, 0xD2, 0x22, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x23, 0x44, 0x40, 0x83, 0xBD, 0xD2,
+	 0x23, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x24, 0x44, 0x40, 0x84, 0xBD, 0xD2, 0x24, 0x5C,
+	 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84,
+	 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x25, 0x44, 0x40, 0x85, 0x61, 0x46, 0x3A, 0xF0, 0xFF, 0xFF,
+	 0x64, 0x44, 0xE0, 0x7F, 0xA0, 0x5B, 0x64, 0x47, 0xE1, 0x7F, 0x5A, 0xD0, 0xA0, 0x5B, 0x64, 0x44,
+	 0xE2, 0x7F, 0xA0, 0x5B, 0x64, 0x47, 0xED, 0xF5, 0xBD, 0xD2, 0x25, 0x5C, 0x90, 0x84, 0xE8, 0x80,
+	 0xF8, 0x84, 0x20, 0x5C, 0x40, 0x80, 0x20, 0x44, 0xE4, 0x7F, 0xA0, 0x5B, 0x20, 0x47, 0xE5, 0x7F,
+	 0xA0, 0x5B, 0xBD, 0xD2, 0x20, 0x5C, 0x90, 0x84, 0xE8, 0x80, 0xF8, 0x84, 0x21, 0x5C, 0x40, 0x81,
+	 0x21, 0x44, 0xE6, 0x7F, 0xA0, 0x5B, 0x21, 0x47, 0xE7, 0x7F, 0xA0, 0x5B, 0x21, 0x44, 0xE8, 0x80,
+	 0xF8, 0x84, 0x22, 0x5C, 0x40, 0x82, 0x22, 0x44, 0xE8, 0x7F, 0xA0, 0x5B, 0x22, 0x47, 0xE9, 0x7F,
+	 0xA0, 0x5B, 0x22, 0x44, 0xE8, 0x80, 0xF8, 0x84, 0x23, 0x5C, 0x40, 0x83, 0x23, 0x44, 0xEA, 0x7F,
+	 0xA0, 0x5B, 0x23, 0x47, 0xEB, 0x7F, 0xA0, 0x5B, 0x23, 0x44, 0xE8, 0x80, 0xF8, 0x84, 0x24, 0x5C,
+	 0x40, 0x84, 0x24, 0x44, 0xEC, 0x7F, 0xA0, 0x5B, 0x24, 0x47, 0xED, 0x7F, 0xA0, 0x5B, 0x24, 0x44,
+	 0xE8, 0x80, 0xF8, 0x84, 0x25, 0x5C, 0x40, 0x85, 0x25, 0x44, 0xEE, 0x7F, 0xA0, 0x5B, 0x25, 0x47,
+	 0xEF, 0x7F, 0xA0, 0x5B, 0x2C, 0x43, 0xA3, 0xD2, 0x25, 0x5C, 0x90, 0x81, 0xE9, 0x84, 0xE3, 0x7F,
+	 0xA0, 0x5B, 0x06, 0x60, 0x7D, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xEA, 0xF3, 0x5A, 0xD3, 0x40, 0x48,
+	 0x5A, 0xD3, 0x40, 0x49, 0x40, 0x4A, 0x00, 0x60, 0x78, 0x7C, 0x44, 0x4D, 0x49, 0xF2, 0x4A, 0xF2,
+	 0x40, 0x47, 0x40, 0x46, 0x0D, 0x60, 0x70, 0x65, 0x00, 0x61, 0x2D, 0x5C, 0xE9, 0x80, 0x00, 0x64,
+	 0xF0, 0x84, 0xF0, 0x84, 0xC0, 0x83, 0xBD, 0xD2, 0x2A, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C,
+	 0x26, 0x44, 0x40, 0x86, 0xDB, 0x83, 0xBD, 0xD2, 0x26, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C,
+	 0x27, 0x44, 0x40, 0x87, 0xDB, 0x83, 0xBD, 0xD2, 0x27, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C,
+	 0x28, 0x44, 0x40, 0x88, 0xDB, 0x83, 0xBD, 0xD2, 0x28, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C,
+	 0x29, 0x44, 0x40, 0x89, 0xF2, 0xA3, 0xBD, 0xD2, 0x29, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C,
+	 0x2A, 0x44, 0xC0, 0x9C, 0x41, 0x8A, 0xDD, 0x81, 0x08, 0x2A, 0xA7, 0x01, 0x26, 0x44, 0x44, 0xFA,
+	 0x27, 0x44, 0x45, 0xFA, 0x28, 0x44, 0x46, 0xFA, 0x29, 0x44, 0x47, 0xFA, 0x2A, 0x44, 0x48, 0xFA,
+	 0x06, 0x60, 0x7E, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x60, 0x88, 0x7C, 0x44, 0x4D, 0x2D, 0x42,
+	 0xA2, 0xD2, 0x5A, 0xD0, 0x40, 0x46, 0x44, 0x47, 0x5A, 0xD2, 0x5A, 0xD0, 0x40, 0x48, 0x5A, 0xD0,
+	 0x44, 0x49, 0x4B, 0xF2, 0x44, 0x4A, 0x40, 0x8B, 0x60, 0x5C, 0x64, 0x47, 0xE0, 0x7F, 0xA0, 0x5A,
+	 0xFF, 0xB4, 0x20, 0xBC, 0x7F, 0xB4, 0xE1, 0x7F, 0xA0, 0x5A, 0x64, 0x44, 0xE2, 0x7F, 0xA0, 0x5A,
+	 0x00, 0x60, 0x78, 0x63, 0x0D, 0x60, 0x70, 0x65, 0xBD, 0xD2, 0x2B, 0x5C, 0x90, 0x9C, 0x64, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47,
+	 0x90, 0x9C, 0x26, 0x44, 0x40, 0x86, 0xBD, 0xD2, 0x26, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C,
+	 0x27, 0x44, 0x40, 0x87, 0xBD, 0xD2, 0x27, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84,
+	 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x28, 0x44,
+	 0x40, 0x88, 0xBD, 0xD2, 0x28, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1,
+	 0x64, 0x44, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x29, 0x44, 0x40, 0x89,
+	 0xBD, 0xD2, 0x29, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x2A, 0x44, 0x40, 0x8A, 0xBD, 0xD2,
+	 0x2A, 0x5C, 0x90, 0x9C, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x44, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD1, 0x64, 0x47, 0x90, 0x9C, 0x2B, 0x44, 0x40, 0x8B, 0xBD, 0xD2, 0x2B, 0x5C,
+	 0x90, 0x84, 0xE8, 0x80, 0xF8, 0x84, 0x26, 0x5C, 0x40, 0x86, 0x26, 0x44, 0xE4, 0x7F, 0xA0, 0x5A,
+	 0x26, 0x47, 0xE5, 0x7F, 0xA0, 0x5A, 0xBD, 0xD2, 0x26, 0x5C, 0x90, 0x84, 0xE8, 0x80, 0xF8, 0x84,
+	 0x27, 0x5C, 0x40, 0x87, 0x27, 0x44, 0xE6, 0x7F, 0xA0, 0x5A, 0x27, 0x47, 0xE7, 0x7F, 0xA0, 0x5A,
+	 0x27, 0x44, 0xE8, 0x80, 0xF8, 0x84, 0x28, 0x5C, 0x40, 0x88, 0x28, 0x44, 0xE8, 0x7F, 0xA0, 0x5A,
+	 0x28, 0x47, 0xE9, 0x7F, 0xA0, 0x5A, 0x28, 0x44, 0xE8, 0x80, 0xF8, 0x84, 0x29, 0x5C, 0x40, 0x89,
+	 0x29, 0x44, 0xEA, 0x7F, 0xA0, 0x5A, 0x29, 0x47, 0xEB, 0x7F, 0xA0, 0x5A, 0x29, 0x44, 0xE8, 0x80,
+	 0xF8, 0x84, 0x2A, 0x5C, 0x40, 0x8A, 0x2A, 0x44, 0xEC, 0x7F, 0xA0, 0x5A, 0x2A, 0x47, 0xED, 0x7F,
+	 0xA0, 0x5A, 0x2A, 0x44, 0xE8, 0x80, 0xF8, 0x84, 0x2B, 0x5C, 0x40, 0x8B, 0x2B, 0x44, 0xEE, 0x7F,
+	 0xA0, 0x5A, 0x2B, 0x47, 0xEF, 0x7F, 0xA0, 0x5A, 0x3C, 0xF0, 0x2B, 0x44, 0x90, 0x84, 0xE8, 0x84,
+	 0xE3, 0x7F, 0xA0, 0x5A, 0x06, 0x60, 0x7E, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, 0x45, 0x00, 0xF0,
+	 0x84, 0x60, 0x00, 0xE3, 0x04, 0x71, 0x64, 0x50, 0x01, 0x2A, 0x04, 0x71, 0x5C, 0x61, 0x04, 0x63,
+	 0x59, 0xD0, 0x58, 0xD9, 0xFD, 0x1F, 0x3D, 0xF2, 0x60, 0x43, 0x60, 0x47, 0x5B, 0xDB, 0x3C, 0xF2,
+	 0xFF, 0xFF, 0x60, 0x47, 0x5B, 0xDB, 0x3A, 0xF2, 0xFF, 0xFF, 0x60, 0x47, 0x5B, 0xDB, 0x3F, 0xF2,
+	 0xFF, 0xFF, 0x60, 0x47, 0x5B, 0xDB, 0x81, 0x60, 0x18, 0xE3, 0x65, 0x43, 0xE3, 0x84, 0x60, 0x47,
+	 0x00, 0x7F, 0x60, 0x50, 0x7F, 0x64, 0x23, 0x94, 0x60, 0x51, 0x7C, 0x72, 0x04, 0x75, 0x0C, 0x60,
+	 0x16, 0x61, 0x16, 0x60, 0x00, 0x63, 0x59, 0xDD, 0x2A, 0xF2, 0x87, 0x60, 0x8F, 0x65, 0xA4, 0x87,
+	 0x40, 0xBF, 0x59, 0xDB, 0x56, 0x64, 0x0A, 0x63, 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0x62, 0x64,
+	 0x04, 0x63, 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0x35, 0xF2, 0x0F, 0x65, 0xA4, 0x9C, 0x59, 0xD9,
+	 0x06, 0x63, 0x59, 0xDF, 0xFE, 0x1F, 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x45, 0x03, 0x2B, 0x05, 0x00,
+	 0x6A, 0x64, 0x04, 0x63, 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0x65, 0x40, 0x8F, 0xB0, 0x88, 0x3A,
+	 0x02, 0x00, 0x39, 0xF0, 0x59, 0xD9, 0x2F, 0x58, 0xFF, 0xFF, 0x0C, 0x60, 0x16, 0x61, 0xA3, 0x46,
+	 0x00, 0xF4, 0x02, 0x64, 0x0A, 0x63, 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0x59, 0xDF, 0x59, 0xDF,
+	 0xA0, 0x4C, 0x04, 0xBC, 0xFF, 0xB4, 0xA0, 0x51, 0x23, 0x44, 0x01, 0xA7, 0x80, 0xBF, 0x60, 0x50,
+	 0x80, 0x60, 0x38, 0x71, 0x80, 0x60, 0x7C, 0x72, 0x01, 0x76, 0xFF, 0xFF, 0x76, 0x44, 0x01, 0x3A,
+	 0xFD, 0x01, 0x40, 0x76, 0x40, 0x76, 0x42, 0xFF, 0xFF, 0xFF, 0x40, 0x76, 0x80, 0x60, 0x18, 0x70,
+	 0x80, 0x60, 0x18, 0x71, 0x80, 0x60, 0x7C, 0x72, 0x80, 0x60, 0x10, 0x73, 0x02, 0x76, 0x76, 0x44,
+	 0xFF, 0xFF, 0x76, 0x44, 0x02, 0x3A, 0xFD, 0x01, 0x40, 0x76, 0x42, 0xFF, 0x3C, 0x46, 0x00, 0xF2,
+	 0x80, 0x60, 0x00, 0xBC, 0x60, 0x50, 0x80, 0x60, 0x12, 0x71, 0x80, 0x60, 0x6E, 0x72, 0x3F, 0xF2,
+	 0xFF, 0xFF, 0xF8, 0xA7, 0x80, 0xBF, 0x60, 0x53, 0x04, 0x76, 0xFF, 0xFF, 0x88, 0xFF, 0x3C, 0x46,
+	 0x07, 0xF2, 0xFF, 0xFF, 0x40, 0x43, 0xA3, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x77, 0x40, 0x8B, 0xFF,
+	 0xA0, 0x4B, 0x04, 0xE1, 0xFF, 0xFF, 0x76, 0x44, 0x04, 0x3A, 0xFD, 0x01, 0x40, 0x76, 0x42, 0xFF,
+	 0xFF, 0xFF, 0x10, 0x76, 0xFF, 0xFF, 0x76, 0x44, 0x20, 0x3A, 0xFD, 0x01, 0x40, 0x76, 0x42, 0xFF,
+	 0x63, 0x44, 0x00, 0x7F, 0xA0, 0x51, 0x02, 0x60, 0x00, 0x75, 0x88, 0xFF, 0xA0, 0x4C, 0xFB, 0xB4,
+	 0xA0, 0x51, 0x06, 0x60, 0x1F, 0xE1, 0x16, 0xFF, 0x2F, 0x58, 0xFF, 0xFF, 0x26, 0x46, 0x3F, 0xF2,
+	 0xFF, 0xFF, 0xF8, 0xA4, 0x3F, 0xFA, 0x00, 0xF4, 0x60, 0x47, 0x08, 0xFA, 0xA0, 0x48, 0x08, 0x26,
+	 0x07, 0x00, 0xA0, 0x4C, 0x04, 0xE1, 0xFF, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0x00, 0x7F, 0xA0, 0x51,
+	 0x42, 0xFF, 0x26, 0x46, 0x8B, 0xFF, 0x02, 0x60, 0x00, 0x75, 0x3C, 0xF2, 0x40, 0x76, 0x14, 0x1B,
+	 0x26, 0x46, 0x3B, 0xF2, 0x0C, 0x60, 0xBA, 0x63, 0x60, 0x47, 0xC0, 0xB4, 0xE8, 0x84, 0xE8, 0x84,
+	 0xE8, 0x84, 0x43, 0x93, 0xE3, 0x9C, 0x64, 0x47, 0x80, 0x7C, 0x64, 0x5F, 0x60, 0x50, 0x7F, 0x64,
+	 0x23, 0x97, 0x80, 0xBF, 0x60, 0x51, 0x07, 0x00, 0x01, 0xA7, 0x80, 0xBF, 0x60, 0x50, 0x80, 0x60,
+	 0x40, 0x71, 0x80, 0x60, 0x7C, 0x72, 0x01, 0x76, 0xFF, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0x0C, 0x21,
+	 0xFC, 0x01, 0x04, 0x25, 0xD5, 0x01, 0x40, 0x76, 0x43, 0xFF, 0x0C, 0x60, 0x22, 0x61, 0x26, 0x46,
+	 0x00, 0xF4, 0x02, 0x64, 0x0A, 0x63, 0x58, 0xD0, 0x59, 0xD9, 0xFD, 0x1F, 0x59, 0xDF, 0x59, 0xDF,
+	 0x80, 0x60, 0x18, 0x70, 0x80, 0x60, 0x24, 0x71, 0x80, 0x60, 0x7C, 0x72, 0x80, 0x60, 0x10, 0x73,
+	 0x02, 0x76, 0xFF, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0x0C, 0x21, 0xFC, 0x01, 0x04, 0x25, 0xB8, 0x01,
+	 0x40, 0x76, 0x43, 0xFF, 0x26, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0x60, 0x47, 0x80, 0xBF, 0x60, 0x50,
+	 0x80, 0x60, 0x12, 0x71, 0x3F, 0xF2, 0x80, 0x60, 0x6E, 0x72, 0x60, 0x47, 0x80, 0xBF, 0x60, 0x53,
+	 0x04, 0x76, 0xFF, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0x0C, 0x21, 0xFC, 0x01, 0x04, 0x25, 0xA0, 0x01,
+	 0x40, 0x76, 0x43, 0xFF, 0x08, 0x76, 0xFF, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0x0C, 0x21, 0xFC, 0x01,
+	 0x04, 0x25, 0x96, 0x01, 0x76, 0x5C, 0xFF, 0xFF, 0x40, 0x76, 0x43, 0xFF, 0x88, 0xFF, 0x26, 0x46,
+	 0x2F, 0x58, 0xFF, 0xFF, 0xEE, 0x60, 0x60, 0x78, 0xFF, 0xFF, 0x08, 0x60, 0x08, 0xF1, 0x80, 0x60,
+	 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x2F, 0x00, 0xDB, 0xF3, 0x31, 0x41, 0x01, 0xB1,
+	 0x03, 0xA8, 0x2A, 0x03, 0x15, 0x02, 0x20, 0x40, 0x04, 0x2B, 0x0B, 0x00, 0xBB, 0xFE, 0xCA, 0xFE,
+	 0x1C, 0x60, 0x92, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF,
+	 0x07, 0x00, 0x08, 0x60, 0x09, 0xF1, 0x00, 0x60, 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x08, 0x60, 0x1B, 0xF1, 0x00, 0x60, 0x80, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x0C, 0x00,
+	 0xA9, 0xFE, 0xDB, 0x05, 0xAB, 0xFE, 0x0C, 0x05, 0xA8, 0xFE, 0xCC, 0x05, 0xAA, 0xFE, 0xCD, 0x05,
+	 0x78, 0x43, 0x01, 0x61, 0x29, 0x60, 0xEA, 0x78, 0xA1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x85, 0x3E,
+	 0x13, 0x60, 0x02, 0xF3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x03, 0x02, 0xCA, 0x60, 0xD4, 0x78,
+	 0xFF, 0xFF, 0x26, 0x45, 0xD4, 0x80, 0x0F, 0xF0, 0xF9, 0x03, 0x64, 0x44, 0x70, 0xB0, 0x70, 0x2A,
+	 0x13, 0x00, 0x16, 0x60, 0x85, 0xF3, 0xFF, 0xFF, 0xDC, 0x84, 0x00, 0x36, 0x00, 0x3B, 0xA2, 0xDB,
+	 0xA2, 0xFF, 0xAC, 0xF3, 0xFF, 0xFF, 0xCC, 0x84, 0xFE, 0xA0, 0xAC, 0xFB, 0x01, 0x07, 0xD4, 0xFE,
+	 0xA3, 0xFF, 0xD0, 0x60, 0xB5, 0x78, 0xFF, 0xFF, 0x64, 0x40, 0x02, 0x26, 0x09, 0x00, 0x66, 0x45,
+	 0x09, 0xF4, 0x0F, 0xF2, 0x02, 0x18, 0x65, 0x46, 0xE4, 0x1B, 0x00, 0x64, 0x40, 0x46, 0xCC, 0x01,
+	 0xA2, 0xFF, 0xAC, 0xF3, 0x46, 0x46, 0xCC, 0x84, 0xFE, 0xA0, 0xAC, 0xFB, 0x01, 0x07, 0xD4, 0xFE,
+	 0xA3, 0xFF, 0x0F, 0xF0, 0xA3, 0xFC, 0x64, 0x44, 0x80, 0x26, 0x35, 0x00, 0x2C, 0x60, 0xEA, 0x64,
+	 0xF1, 0x60, 0x78, 0x41, 0xE4, 0x78, 0xB5, 0xF1, 0x32, 0x44, 0x01, 0x2A, 0x03, 0x00, 0x07, 0x60,
+	 0x01, 0x64, 0x22, 0x00, 0x02, 0x2A, 0x03, 0x00, 0x00, 0x60, 0x01, 0x64, 0x1D, 0x00, 0x04, 0x2A,
+	 0x1F, 0x00, 0x2A, 0xF2, 0xFF, 0xFF, 0x0C, 0xB0, 0x08, 0x3A, 0x1A, 0x00, 0x2C, 0xF0, 0x22, 0xF0,
+	 0x64, 0x40, 0x01, 0x26, 0x0B, 0x00, 0x64, 0x40, 0x40, 0x2B, 0x12, 0x00, 0x8F, 0xB0, 0x88, 0x3A,
+	 0x0F, 0x00, 0x39, 0xF2, 0xFF, 0xFF, 0x60, 0xB0, 0x20, 0x3A, 0x0A, 0x00, 0x23, 0xF2, 0x00, 0x60,
+	 0x01, 0x7C, 0xB0, 0x84, 0x23, 0xFA, 0x0C, 0x00, 0x23, 0xFA, 0xD0, 0x60, 0xC1, 0x78, 0xFF, 0xFF,
+	 0xD0, 0x60, 0xB5, 0x78, 0xFF, 0xFF, 0x22, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x10, 0x27, 0xF8, 0x01,
+	 0x0F, 0xF0, 0xFF, 0xFF, 0x64, 0x44, 0x08, 0x26, 0x64, 0x00, 0x2A, 0xF2, 0x60, 0x63, 0x60, 0x40,
+	 0x02, 0x2B, 0x66, 0x63, 0xBE, 0xD2, 0x81, 0xF1, 0xA3, 0xD2, 0xD0, 0x80, 0x80, 0xF1, 0x0D, 0x02,
+	 0xBF, 0xD2, 0xD0, 0x80, 0x7F, 0xF1, 0x09, 0x02, 0xD0, 0x80, 0xFF, 0xFF, 0x06, 0x02, 0x2C, 0x60,
+	 0xF6, 0x64, 0xF1, 0x60, 0x78, 0x41, 0xE4, 0x78, 0xB5, 0xF1, 0x32, 0x44, 0x01, 0x2A, 0x03, 0x00,
+	 0x07, 0x60, 0x02, 0x64, 0x04, 0x00, 0x02, 0x2A, 0x06, 0x00, 0x00, 0x60, 0x02, 0x64, 0x23, 0xFA,
+	 0xD0, 0x60, 0xC1, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0xB0, 0x3A, 0x06, 0x00,
+	 0x00, 0x60, 0x02, 0x64, 0x23, 0xFA, 0xCC, 0x60, 0x31, 0x78, 0xFF, 0xFF, 0x32, 0x40, 0x04, 0x2A,
+	 0x2D, 0x00, 0x2A, 0xF2, 0xFF, 0xFF, 0x0C, 0xB0, 0x08, 0x3A, 0x28, 0x00, 0x2C, 0xF0, 0x22, 0xF0,
+	 0x64, 0x40, 0x01, 0x26, 0x0B, 0x00, 0x64, 0x40, 0x40, 0x2B, 0x20, 0x00, 0x8F, 0xB0, 0x88, 0x3A,
+	 0x1D, 0x00, 0x39, 0xF2, 0xFF, 0xFF, 0x60, 0xB0, 0x20, 0x3A, 0x18, 0x00, 0x2C, 0xF0, 0x66, 0x45,
+	 0x07, 0xF4, 0x64, 0x40, 0x01, 0x26, 0xA6, 0xF5, 0x3A, 0xF2, 0x65, 0x46, 0x60, 0x40, 0x00, 0x36,
+	 0x0D, 0x00, 0x22, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x10, 0x2A, 0x08, 0x00, 0x20, 0x2B, 0x06, 0x00,
+	 0x23, 0xF2, 0x00, 0x60, 0x02, 0x7C, 0xB0, 0x84, 0x23, 0xFA, 0x03, 0x00, 0xD0, 0x60, 0xB5, 0x78,
+	 0xFF, 0xFF, 0x32, 0x44, 0x01, 0x2A, 0x4A, 0x00, 0x2E, 0x60, 0x40, 0x63, 0xBF, 0xD3, 0x00, 0x65,
+	 0xB4, 0x81, 0xDB, 0x83, 0x3D, 0x03, 0xBF, 0xD3, 0xA3, 0xD3, 0x40, 0x48, 0xBE, 0xD3, 0x40, 0x4A,
+	 0x2E, 0xF0, 0x40, 0x4C, 0xD0, 0x80, 0x2D, 0xF0, 0x08, 0x02, 0x2A, 0x44, 0xD0, 0x80, 0x2C, 0xF0,
+	 0x04, 0x02, 0x28, 0x44, 0xD0, 0x80, 0xFF, 0xFF, 0x2B, 0x03, 0x31, 0xF0, 0x2C, 0x44, 0xD0, 0x80,
+	 0x30, 0xF0, 0x08, 0x02, 0x2A, 0x44, 0xD0, 0x80, 0x2F, 0xF0, 0x04, 0x02, 0x28, 0x44, 0xD0, 0x80,
+	 0xFF, 0xFF, 0x1E, 0x03, 0x34, 0xF0, 0x2C, 0x44, 0xD0, 0x80, 0x33, 0xF0, 0x08, 0x02, 0x2A, 0x44,
+	 0xD0, 0x80, 0x32, 0xF0, 0x04, 0x02, 0x28, 0x44, 0xD0, 0x80, 0xFF, 0xFF, 0x11, 0x03, 0x38, 0xF0,
+	 0x2C, 0x44, 0xD0, 0x80, 0x37, 0xF0, 0x08, 0x02, 0x2A, 0x44, 0xD0, 0x80, 0x36, 0xF0, 0x04, 0x02,
+	 0x28, 0x44, 0xD0, 0x80, 0xFF, 0xFF, 0x04, 0x03, 0xFA, 0xA1, 0x06, 0xA3, 0xB7, 0x03, 0xC3, 0x01,
+	 0x07, 0x60, 0x00, 0x64, 0x23, 0xFA, 0xD0, 0x60, 0xC1, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0x0F, 0xF0,
+	 0x60, 0x45, 0xA4, 0x36, 0x08, 0x00, 0x0C, 0xB4, 0x04, 0x36, 0x02, 0x00, 0x0C, 0x3A, 0x06, 0x00,
+	 0xD0, 0x60, 0xB5, 0x78, 0xFF, 0xFF, 0xCE, 0x60, 0x7C, 0x78, 0xFF, 0xFF, 0x0F, 0xF0, 0x65, 0x40,
+	 0x40, 0x2B, 0x17, 0x00, 0x32, 0x40, 0x08, 0x26, 0x14, 0x00, 0x07, 0xF4, 0x3A, 0xF2, 0xFF, 0xFF,
+	 0x37, 0xB4, 0x26, 0x46, 0x0E, 0x02, 0x2C, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x26, 0x06, 0x00,
+	 0x2C, 0x60, 0xF0, 0x64, 0xF1, 0x60, 0x78, 0x41, 0xE4, 0x78, 0xB5, 0xF1, 0xD0, 0x60, 0xB5, 0x78,
+	 0xFF, 0xFF, 0x2A, 0xF2, 0x64, 0x40, 0x60, 0x26, 0x03, 0x00, 0xCE, 0x60, 0x4E, 0x78, 0xFF, 0xFF,
+	 0x60, 0x41, 0xA6, 0xF3, 0x07, 0xFA, 0x61, 0x44, 0x80, 0x3A, 0x02, 0x00, 0x2A, 0xF2, 0x12, 0x00,
+	 0x60, 0x40, 0x40, 0x3A, 0x0F, 0x00, 0xDB, 0xF3, 0xFF, 0xFF, 0x07, 0xB4, 0x03, 0x3A, 0xE6, 0x01,
+	 0xD1, 0x60, 0x58, 0x4D, 0xA6, 0x78, 0xFF, 0xFF, 0xE1, 0x02, 0xA6, 0xF3, 0x07, 0xFA, 0xCD, 0x60,
+	 0xE1, 0x78, 0xFF, 0xFF, 0x5E, 0x63, 0x60, 0x40, 0x02, 0x2B, 0x64, 0x63, 0x50, 0xFE, 0xBD, 0xD2,
+	 0x7F, 0xF1, 0xBD, 0xD2, 0xD0, 0x80, 0x80, 0xF1, 0xBD, 0xD2, 0xD0, 0x80, 0x81, 0xF1, 0x2A, 0xF2,
+	 0xD0, 0x80, 0x60, 0x40, 0x08, 0x3A, 0x09, 0x00, 0x01, 0x0C, 0xC8, 0x01, 0xE9, 0x60, 0x58, 0x4F,
+	 0x08, 0x78, 0xFF, 0xFF, 0xCD, 0x60, 0xE1, 0x78, 0xFF, 0xFF, 0x23, 0x0C, 0xD1, 0x60, 0x58, 0x4D,
+	 0xA6, 0x78, 0xFF, 0xFF, 0xBB, 0x02, 0x02, 0x64, 0x10, 0x60, 0x0A, 0xFB, 0x00, 0x64, 0x10, 0x60,
+	 0x0E, 0xFB, 0x26, 0x60, 0x58, 0x4E, 0x65, 0x78, 0xFF, 0xFF, 0x10, 0x60, 0x05, 0xF3, 0xFF, 0xFF,
+	 0x60, 0x40, 0x80, 0x27, 0x07, 0x00, 0x08, 0x60, 0x15, 0xF1, 0x00, 0x60, 0x04, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x00, 0x64, 0x10, 0x60, 0x0A, 0xFB, 0xA0, 0x01, 0xCD, 0x60, 0xE1, 0x78,
+	 0xFF, 0xFF, 0xDB, 0xF3, 0xFF, 0xFF, 0x07, 0xB4, 0xFD, 0xA0, 0xFF, 0xFF, 0x03, 0x03, 0x20, 0x40,
+	 0x10, 0x22, 0xF4, 0x01, 0x08, 0x60, 0x07, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x36, 0x07, 0x00,
+	 0x01, 0x64, 0xA2, 0xDB, 0x01, 0x65, 0xF1, 0x60, 0x58, 0x4E, 0xC3, 0x78, 0xFF, 0xFF, 0x26, 0x46,
+	 0x31, 0xF2, 0x1D, 0x60, 0xC0, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41,
+	 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46, 0x31, 0xF0, 0x63, 0x46, 0xD0, 0x80,
+	 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46, 0x30, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02,
+	 0x61, 0x46, 0x2F, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF,
+	 0x63, 0x46, 0xE8, 0x1B, 0xA6, 0xF3, 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0xA6, 0xF1, 0x43, 0x43,
+	 0xD3, 0x80, 0xFF, 0xFF, 0x03, 0x03, 0xCD, 0x60, 0xD9, 0x78, 0xFF, 0xFF, 0xD0, 0x60, 0x58, 0x4F,
+	 0xFC, 0x78, 0xFF, 0xFF, 0x03, 0x4B, 0x3F, 0xF2, 0x00, 0xF4, 0x60, 0x43, 0xF4, 0xA3, 0x00, 0x60,
+	 0x1D, 0x61, 0x00, 0x60, 0x01, 0x65, 0x01, 0x60, 0xFF, 0x64, 0x40, 0x4C, 0xFD, 0x60, 0x58, 0x4E,
+	 0x7A, 0x78, 0xFF, 0xFF, 0x00, 0xBB, 0xFF, 0xFF, 0x00, 0x02, 0x00, 0x64, 0x40, 0x4A, 0x60, 0xFE,
+	 0x02, 0x60, 0x00, 0x63, 0xBD, 0xD3, 0xBD, 0xD3, 0x60, 0x41, 0xFE, 0x60, 0x58, 0x4E, 0x2C, 0x78,
+	 0xFF, 0xFF, 0x20, 0xFE, 0x00, 0x65, 0x00, 0x64, 0x19, 0x60, 0x3B, 0xFB, 0x02, 0x00, 0x20, 0xFE,
+	 0xFF, 0x65, 0x02, 0x60, 0x00, 0x63, 0x60, 0xFE, 0xBD, 0xD3, 0xBD, 0xD3, 0x60, 0x41, 0x20, 0xFE,
+	 0xCD, 0x81, 0x60, 0x40, 0x80, 0x2A, 0x39, 0x00, 0x7F, 0xB4, 0x02, 0x3A, 0x02, 0x00, 0x01, 0x64,
+	 0x2E, 0x00, 0x04, 0x3A, 0x02, 0x00, 0x02, 0x64, 0x2A, 0x00, 0x0B, 0x3A, 0x02, 0x00, 0x04, 0x64,
+	 0x26, 0x00, 0x16, 0x3A, 0x02, 0x00, 0x08, 0x64, 0x22, 0x00, 0x0C, 0x3A, 0x02, 0x00, 0x10, 0x64,
+	 0x1E, 0x00, 0x12, 0x3A, 0x02, 0x00, 0x20, 0x64, 0x1A, 0x00, 0x18, 0x3A, 0x02, 0x00, 0x40, 0x64,
+	 0x16, 0x00, 0x24, 0x3A, 0x02, 0x00, 0x80, 0x64, 0x12, 0x00, 0x30, 0x3A, 0x02, 0x00, 0x01, 0x67,
+	 0x0E, 0x00, 0x48, 0x3A, 0x02, 0x00, 0x02, 0x67, 0x0A, 0x00, 0x60, 0x3A, 0x02, 0x00, 0x04, 0x67,
+	 0x06, 0x00, 0x6C, 0x3A, 0x02, 0x00, 0x08, 0x67, 0x02, 0x00, 0x00, 0x64, 0x00, 0x00, 0x19, 0x60,
+	 0x3B, 0xF1, 0xFF, 0xFF, 0xB0, 0x84, 0x19, 0x60, 0x3B, 0xFB, 0x61, 0x40, 0x00, 0x36, 0x05, 0x00,
+	 0x60, 0xFE, 0xBD, 0xD3, 0xFF, 0xFF, 0x20, 0xFE, 0xBB, 0x01, 0x65, 0x40, 0x00, 0x3A, 0x1E, 0x00,
+	 0x26, 0x46, 0x3F, 0xF2, 0x00, 0xF4, 0x60, 0x43, 0xF4, 0xA3, 0x00, 0x60, 0x1D, 0x61, 0x00, 0x60,
+	 0x32, 0x65, 0x01, 0x60, 0xFF, 0x64, 0x40, 0x4C, 0xFD, 0x60, 0x58, 0x4E, 0x7A, 0x78, 0xFF, 0xFF,
+	 0x00, 0xBB, 0xFF, 0xFF, 0x0B, 0x03, 0x60, 0xFE, 0x02, 0x60, 0x00, 0x63, 0xBD, 0xD3, 0xBD, 0xD3,
+	 0x60, 0x41, 0xFE, 0x60, 0x58, 0x4E, 0x2C, 0x78, 0xFF, 0xFF, 0x91, 0x01, 0x20, 0xFE, 0x00, 0x65,
+	 0xFC, 0x60, 0x58, 0x4E, 0xC7, 0x78, 0xFF, 0xFF, 0xA1, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x27,
+	 0x04, 0x00, 0xFD, 0x60, 0x58, 0x4E, 0x11, 0x78, 0xFF, 0xFF, 0x20, 0xFE, 0x37, 0x60, 0xF8, 0x61,
+	 0xA1, 0xD1, 0xA1, 0xF3, 0x01, 0x60, 0xAC, 0x63, 0x60, 0x45, 0x2A, 0x44, 0x79, 0xFB, 0xA3, 0xD5,
+	 0x65, 0x40, 0x01, 0x27, 0x5B, 0xD5, 0x65, 0x40, 0x01, 0x27, 0x59, 0xD1, 0x66, 0x41, 0xA0, 0x84,
+	 0x24, 0x94, 0x2B, 0x46, 0x0F, 0xFA, 0x7A, 0xFB, 0x16, 0x64, 0x12, 0xFA, 0x01, 0x64, 0x11, 0xFA,
+	 0x66, 0x5C, 0xC2, 0x60, 0x58, 0x4E, 0x6D, 0x78, 0xFF, 0xFF, 0x7D, 0xF3, 0xFF, 0xFF, 0x60, 0x40,
+	 0x01, 0x27, 0x28, 0x00, 0x19, 0x60, 0x44, 0xF3, 0x32, 0x60, 0x88, 0x63, 0xA3, 0xD3, 0xFF, 0xFF,
+	 0x60, 0x40, 0x01, 0x2A, 0x0C, 0x00, 0x0F, 0x64, 0xFC, 0x60, 0x58, 0x4E, 0x34, 0x78, 0xFF, 0xFF,
+	 0xFF, 0x60, 0xFF, 0x63, 0x1A, 0x60, 0xB3, 0xFD, 0x1A, 0x60, 0xC3, 0xFD, 0x1C, 0x00, 0x19, 0x60,
+	 0x39, 0xF3, 0x3F, 0x40, 0x01, 0x27, 0x08, 0x00, 0x0F, 0x60, 0xFF, 0x65, 0xA4, 0x84, 0xFC, 0x60,
+	 0x58, 0x4E, 0x34, 0x78, 0xFF, 0xFF, 0x0F, 0x00, 0x0F, 0xB4, 0xFC, 0x60, 0x58, 0x4E, 0x34, 0x78,
+	 0xFF, 0xFF, 0x09, 0x00, 0x19, 0x60, 0x3A, 0xF3, 0x0F, 0x60, 0xFF, 0x65, 0xA4, 0x84, 0xFC, 0x60,
+	 0x58, 0x4E, 0x34, 0x78, 0xFF, 0xFF, 0xD3, 0x60, 0x58, 0x4E, 0x78, 0x78, 0xFF, 0xFF, 0x26, 0x46,
+	 0x23, 0x43, 0x32, 0x40, 0x08, 0x2A, 0x05, 0x00, 0x63, 0x46, 0x80, 0x60, 0x02, 0x64, 0x06, 0xFA,
+	 0x26, 0x46, 0x2C, 0x60, 0xE4, 0x64, 0xF1, 0x60, 0x78, 0x41, 0xE4, 0x78, 0xB5, 0xF1, 0x27, 0xF2,
+	 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x3B, 0x07, 0x00, 0x2C, 0x60, 0xF2, 0x64, 0xF1, 0x60, 0x78, 0x41,
+	 0xE4, 0x78, 0xB5, 0xF1, 0x08, 0x00, 0x02, 0x3B, 0x06, 0x00, 0x2C, 0x60, 0xF4, 0x64, 0xF1, 0x60,
+	 0x78, 0x41, 0xE4, 0x78, 0xB5, 0xF1, 0x1B, 0xF2, 0xFF, 0xFF, 0xE4, 0xA4, 0x3E, 0xFA, 0x2A, 0xF2,
+	 0x28, 0x41, 0x40, 0xA8, 0x01, 0xB1, 0x02, 0x02, 0x46, 0x02, 0x76, 0x00, 0x60, 0x40, 0x08, 0x2A,
+	 0x0F, 0x00, 0x2C, 0x60, 0xE2, 0x64, 0xF1, 0x60, 0x78, 0x41, 0xE4, 0x78, 0xB5, 0xF1, 0x1B, 0xF2,
+	 0xFF, 0xFF, 0x60, 0x45, 0x2C, 0x60, 0xE8, 0x64, 0xF1, 0x60, 0x78, 0x41, 0xF0, 0x78, 0xB5, 0xF1,
+	 0x0F, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x40, 0x26, 0x28, 0x00, 0x32, 0x44, 0x02, 0x26, 0x25, 0x00,
+	 0x10, 0x2B, 0x29, 0x00, 0x2E, 0x60, 0x40, 0x63, 0xBF, 0xD3, 0x2C, 0xF0, 0x00, 0xA8, 0x60, 0x41,
+	 0x0D, 0x03, 0x50, 0xFE, 0xBD, 0xD3, 0x2D, 0xF0, 0xD0, 0x80, 0xBD, 0xD3, 0x2E, 0xF0, 0xD0, 0x80,
+	 0xBD, 0xD3, 0x2C, 0xF0, 0xD0, 0x80, 0xFA, 0xA1, 0x10, 0x0C, 0xF3, 0x02, 0x50, 0xFE, 0x60, 0x60,
+	 0x01, 0x64, 0xD0, 0x80, 0x2D, 0xF0, 0x1D, 0x64, 0xD0, 0x80, 0x2E, 0xF0, 0x01, 0x64, 0xD0, 0x80,
+	 0xFF, 0xFF, 0x03, 0x0C, 0xD0, 0x60, 0xB5, 0x78, 0xFF, 0xFF, 0x32, 0x40, 0x40, 0x2A, 0x03, 0x00,
+	 0x1C, 0x60, 0x12, 0x78, 0xFF, 0xFF, 0xD0, 0x60, 0x6B, 0x78, 0xFF, 0xFF, 0x32, 0x40, 0x40, 0x26,
+	 0xF7, 0x01, 0x2A, 0xF0, 0xFF, 0xFF, 0x64, 0x40, 0x08, 0x2A, 0x2A, 0x00, 0xDB, 0xF3, 0xFF, 0xFF,
+	 0x07, 0xB4, 0x03, 0xA8, 0xFF, 0xFF, 0x03, 0x03, 0x32, 0x40, 0x02, 0x2A, 0x1D, 0x00, 0x03, 0x67,
+	 0xA0, 0x84, 0x00, 0x37, 0x64, 0x63, 0x60, 0x40, 0x02, 0x37, 0x5E, 0x63, 0x60, 0x40, 0x01, 0x37,
+	 0x58, 0x63, 0x60, 0x40, 0x03, 0x37, 0x0D, 0x00, 0xBD, 0xD2, 0x7F, 0xF1, 0xBD, 0xD2, 0xD0, 0x80,
+	 0x80, 0xF1, 0x07, 0x02, 0xD0, 0x80, 0xBD, 0xD2, 0x81, 0xF1, 0x03, 0x02, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x03, 0x03, 0xD0, 0x60, 0xB5, 0x78, 0xFF, 0xFF, 0xE9, 0x60, 0x58, 0x4F, 0x08, 0x78, 0xFF, 0xFF,
+	 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x08, 0x26, 0x06, 0x00, 0x20, 0x40, 0x10, 0x2B, 0x03, 0x00,
+	 0xD0, 0x60, 0x6B, 0x78, 0xFF, 0xFF, 0x87, 0xF4, 0xA6, 0xF1, 0x27, 0x1B, 0x31, 0xF2, 0x1D, 0x60,
+	 0xC0, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46, 0x60, 0x43,
+	 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46, 0x31, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2, 0x0C, 0x02,
+	 0x61, 0x46, 0x30, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46, 0x2F, 0xF0,
+	 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46, 0xE8, 0x1B,
+	 0xA6, 0xF3, 0x08, 0xFE, 0x60, 0x43, 0x61, 0x46, 0x03, 0x00, 0xD3, 0x80, 0xFF, 0xFF, 0xD6, 0x03,
+	 0x43, 0x43, 0xDB, 0xF3, 0x32, 0x40, 0x02, 0x26, 0x04, 0x00, 0x07, 0xB4, 0x03, 0xA8, 0x2A, 0xF2,
+	 0x45, 0x02, 0xA6, 0xF1, 0x23, 0x43, 0xD3, 0x80, 0xFF, 0xFF, 0x40, 0x02, 0xD0, 0x60, 0x58, 0x4F,
+	 0xFC, 0x78, 0xFF, 0xFF, 0x32, 0x40, 0x02, 0x2A, 0x05, 0x00, 0x63, 0x46, 0x02, 0x64, 0x06, 0xFA,
+	 0x26, 0x46, 0x34, 0x00, 0x32, 0x40, 0x08, 0x2A, 0x05, 0x00, 0x63, 0x46, 0x80, 0x60, 0x02, 0x64,
+	 0x06, 0xFA, 0x26, 0x46, 0x43, 0x43, 0x7D, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x27, 0x09, 0x00,
+	 0x19, 0x60, 0x44, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x2A, 0x03, 0x00, 0x23, 0x46, 0x0F, 0x64,
+	 0x10, 0x00, 0x37, 0x60, 0xF8, 0x61, 0xA1, 0xD1, 0xA1, 0xF3, 0x01, 0x60, 0xAC, 0x63, 0x60, 0x45,
+	 0xA3, 0xD3, 0x65, 0x40, 0x01, 0x27, 0x5B, 0xD3, 0x65, 0x40, 0x01, 0x27, 0x59, 0xD1, 0x23, 0x46,
+	 0xA0, 0x84, 0x0F, 0xFA, 0x7A, 0xFB, 0x79, 0xFB, 0x16, 0x64, 0x12, 0xFA, 0x01, 0x64, 0x11, 0xFA,
+	 0x66, 0x5C, 0xC2, 0x60, 0x58, 0x4E, 0x6D, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x07, 0xFC, 0x43, 0x43,
+	 0x2A, 0xF2, 0x63, 0x45, 0x0C, 0xB4, 0x08, 0x3A, 0x0A, 0x00, 0xDB, 0xF3, 0x23, 0x46, 0x07, 0xB4,
+	 0xFD, 0xA0, 0x06, 0xF2, 0x26, 0x46, 0x03, 0x03, 0x60, 0x40, 0x02, 0x2A, 0x0D, 0x00, 0x2A, 0xF2,
+	 0x35, 0xF0, 0x60, 0x40, 0xA4, 0x36, 0x0B, 0x00, 0x08, 0x2B, 0x0C, 0x00, 0x23, 0x46, 0x26, 0xF2,
+	 0x26, 0x46, 0xD0, 0x80, 0xFF, 0xFF, 0x06, 0x02, 0xD0, 0x60, 0xB5, 0x78, 0xFF, 0xFF, 0xD0, 0x60,
+	 0x6B, 0x78, 0xFF, 0xFF, 0x23, 0x46, 0x22, 0xF2, 0x26, 0x46, 0x44, 0x4C, 0x0F, 0x26, 0x1D, 0x00,
+	 0x00, 0xBC, 0x40, 0x45, 0x0B, 0x03, 0x00, 0x64, 0x23, 0x46, 0x22, 0xFA, 0x26, 0x46, 0xA2, 0xFF,
+	 0xB6, 0x60, 0x58, 0x4E, 0xF5, 0x78, 0xFF, 0xFF, 0xA3, 0xFF, 0x26, 0x46, 0x2A, 0xF0, 0x2C, 0x44,
+	 0x64, 0x40, 0x04, 0x27, 0x0A, 0x00, 0x23, 0x46, 0x26, 0xFA, 0x26, 0x46, 0x1B, 0xF2, 0xFF, 0xFF,
+	 0xE4, 0xA4, 0x3E, 0xFA, 0xD0, 0x60, 0x22, 0x78, 0xFF, 0xFF, 0x3F, 0xF2, 0x02, 0xFA, 0xA2, 0xFF,
+	 0x16, 0xF0, 0xFF, 0xFF, 0x64, 0x44, 0x01, 0x26, 0xDC, 0x9C, 0xB0, 0xF3, 0x2A, 0xF2, 0xDC, 0x83,
+	 0xB0, 0xFD, 0x06, 0xF4, 0x01, 0xF8, 0x26, 0x46, 0x60, 0x40, 0x40, 0x2B, 0x18, 0x00, 0x64, 0x44,
+	 0x00, 0x65, 0xFF, 0xB4, 0xFC, 0xA4, 0x06, 0xF0, 0x03, 0x03, 0x64, 0x46, 0x0C, 0x0D, 0x02, 0x65,
+	 0x26, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xD0, 0x80, 0xFF, 0xFF, 0x02, 0x03, 0x60, 0x46, 0xF9, 0x01,
+	 0x01, 0xF2, 0xFF, 0xFF, 0xD4, 0x84, 0x01, 0xFA, 0x66, 0x44, 0x26, 0x46, 0x06, 0xFA, 0x06, 0xF4,
+	 0x00, 0xF2, 0x80, 0xFC, 0x40, 0x45, 0xB6, 0x60, 0x58, 0x4E, 0xF5, 0x78, 0xFF, 0xFF, 0xA3, 0xFF,
+	 0x26, 0x46, 0x2C, 0x44, 0x0F, 0x26, 0x13, 0x00, 0x23, 0x46, 0x26, 0xFA, 0x26, 0x44, 0x22, 0xFA,
+	 0x26, 0x46, 0x1B, 0xF2, 0xFF, 0xFF, 0xE4, 0xA4, 0x3E, 0xFA, 0x00, 0x64, 0x13, 0x60, 0x0D, 0xFB,
+	 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x6E, 0x00, 0xA3, 0x46,
+	 0x26, 0xF2, 0x60, 0x45, 0xDC, 0x84, 0xD4, 0x80, 0x26, 0xFA, 0xA3, 0x46, 0x6B, 0x02, 0x2A, 0xF0,
+	 0xA3, 0x46, 0x22, 0xF2, 0xA3, 0x46, 0x00, 0xBC, 0x00, 0xF2, 0x01, 0x02, 0x63, 0x00, 0x44, 0x4C,
+	 0x3F, 0xF0, 0x60, 0x43, 0x23, 0x46, 0x22, 0xF4, 0x09, 0x60, 0x00, 0x65, 0x3F, 0xF2, 0x26, 0x46,
+	 0xC0, 0x84, 0xD4, 0x80, 0x60, 0x45, 0x56, 0x07, 0x80, 0xFC, 0x1B, 0xF2, 0x06, 0xF2, 0x60, 0x41,
+	 0x23, 0x46, 0x22, 0xF4, 0x1B, 0xF0, 0x06, 0xF0, 0xC1, 0x81, 0x06, 0xFA, 0x05, 0xFA, 0x9B, 0xFA,
+	 0x65, 0x44, 0x3F, 0xFA, 0x64, 0x46, 0x00, 0xFC, 0x63, 0x46, 0x01, 0xF2, 0x10, 0x61, 0xF2, 0xA4,
+	 0x01, 0xFA, 0xC8, 0x83, 0x02, 0x64, 0x59, 0xD0, 0x58, 0xD8, 0xFD, 0x1F, 0x06, 0x45, 0x00, 0x64,
+	 0x13, 0x60, 0x0D, 0xFB, 0x25, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0xA2, 0xFF, 0x00, 0xF4, 0x01, 0xF0, 0x0A, 0x18, 0x70, 0x67, 0xA0, 0x80, 0xF0, 0x67, 0x06, 0x03,
+	 0xC0, 0x84, 0x01, 0xFA, 0x25, 0x46, 0x25, 0x44, 0x80, 0xFC, 0x05, 0xFA, 0xB6, 0x60, 0x58, 0x4E,
+	 0xF5, 0x78, 0xFF, 0xFF, 0xD4, 0xFE, 0xA3, 0xFF, 0x2C, 0x44, 0x04, 0x27, 0x16, 0x00, 0x23, 0x46,
+	 0x22, 0xF2, 0xA2, 0xFC, 0x60, 0x46, 0x46, 0x46, 0x3F, 0xF2, 0x00, 0xF4, 0x60, 0x47, 0x08, 0xFA,
+	 0x26, 0x46, 0x2C, 0x43, 0x2A, 0xFC, 0x06, 0xF4, 0x00, 0x64, 0x00, 0xFA, 0x01, 0xF0, 0x80, 0x60,
+	 0x00, 0x64, 0xB0, 0x84, 0x01, 0xFA, 0x26, 0x46, 0x1D, 0x00, 0x00, 0x66, 0x46, 0x46, 0xCA, 0x60,
+	 0xD8, 0x78, 0xFF, 0xFF, 0xA3, 0x46, 0x22, 0xF0, 0xA2, 0xFC, 0x00, 0x63, 0x33, 0x85, 0xA3, 0x46,
+	 0x0D, 0x03, 0xA3, 0x46, 0x26, 0xF2, 0x0F, 0x65, 0xA4, 0x85, 0xD4, 0x84, 0x26, 0xFA, 0xA3, 0x46,
+	 0xA2, 0xFF, 0xB6, 0x60, 0x58, 0x4E, 0xF5, 0x78, 0xFF, 0xFF, 0xA3, 0xFF, 0x26, 0x46, 0xD0, 0x60,
+	 0xB5, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0x32, 0xF0, 0x60, 0x40, 0x08, 0x2A, 0x24, 0x00, 0x01, 0x2B,
+	 0x13, 0x00, 0x64, 0x40, 0x01, 0x2A, 0x10, 0x00, 0x2C, 0x60, 0xE2, 0x64, 0xF1, 0x60, 0x78, 0x41,
+	 0xE4, 0x78, 0xB5, 0xF1, 0x1B, 0xF2, 0xFF, 0xFF, 0x60, 0x45, 0x2C, 0x60, 0xE8, 0x64, 0xF1, 0x60,
+	 0x78, 0x41, 0xF0, 0x78, 0xB5, 0xF1, 0x0F, 0x00, 0x2C, 0x60, 0xE0, 0x64, 0xF1, 0x60, 0x78, 0x41,
+	 0xE4, 0x78, 0xB5, 0xF1, 0x1B, 0xF2, 0xFF, 0xFF, 0x60, 0x45, 0x2C, 0x60, 0xE6, 0x64, 0xF1, 0x60,
+	 0x78, 0x41, 0xF0, 0x78, 0xB5, 0xF1, 0x07, 0xF4, 0xFF, 0xFF, 0x26, 0xF2, 0x26, 0x46, 0x0F, 0xB4,
+	 0xDC, 0x85, 0x2C, 0x60, 0xE4, 0x64, 0xF1, 0x60, 0x78, 0x41, 0xF0, 0x78, 0xB5, 0xF1, 0x27, 0xF2,
+	 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x3B, 0x07, 0x00, 0x2C, 0x60, 0xF2, 0x64, 0xF1, 0x60, 0x78, 0x41,
+	 0xE4, 0x78, 0xB5, 0xF1, 0x08, 0x00, 0x02, 0x3B, 0x06, 0x00, 0x2C, 0x60, 0xF4, 0x64, 0xF1, 0x60,
+	 0x78, 0x41, 0xE4, 0x78, 0xB5, 0xF1, 0x07, 0xF2, 0x26, 0xF0, 0x41, 0x18, 0x60, 0x46, 0xFF, 0x67,
+	 0x20, 0x88, 0x64, 0x5F, 0x40, 0x4A, 0x15, 0xF0, 0x28, 0x44, 0xD0, 0x84, 0x03, 0xA4, 0x03, 0x0E,
+	 0xE8, 0x84, 0xE8, 0x84, 0x04, 0x00, 0xFA, 0xA4, 0xE8, 0x84, 0xE8, 0x87, 0xC0, 0xBF, 0xC0, 0x84,
+	 0x15, 0xFA, 0x40, 0x48, 0x14, 0xF0, 0x2A, 0x44, 0xD0, 0x84, 0x1F, 0xA4, 0x06, 0x0E, 0xE8, 0x84,
+	 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0x07, 0x00, 0xC2, 0xA4, 0xE8, 0x84, 0xE8, 0x84,
+	 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x87, 0xF8, 0xBF, 0xC0, 0x84, 0x14, 0xFA, 0x33, 0x60, 0x4C, 0x63,
+	 0xBD, 0xDB, 0x60, 0x5C, 0x2F, 0x67, 0xD0, 0x80, 0x60, 0x45, 0x02, 0x28, 0x64, 0x45, 0x28, 0x5C,
+	 0xBD, 0xD9, 0x8B, 0x67, 0xD0, 0x80, 0x60, 0x41, 0x02, 0x24, 0x64, 0x41, 0xD5, 0x84, 0x80, 0x65,
+	 0xC4, 0x87, 0x01, 0x05, 0x00, 0x64, 0xFF, 0xB4, 0x0E, 0xFA, 0xA3, 0xDB, 0x26, 0x46, 0xD1, 0x60,
+	 0xDB, 0x78, 0xFF, 0xFF, 0xCA, 0x60, 0xD8, 0x78, 0xFF, 0xFF, 0x26, 0x60, 0x1A, 0x64, 0x40, 0x4B,
+	 0x34, 0x60, 0x58, 0x4D, 0x08, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0xCA, 0x60, 0xD8, 0x78,
+	 0xFF, 0xFF, 0x25, 0x60, 0xFE, 0x64, 0x13, 0x60, 0x0D, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xF8, 0xFE, 0x00, 0x66, 0x46, 0x46, 0xCA, 0x60, 0xD8, 0x78,
+	 0xFF, 0xFF, 0x2A, 0xF2, 0x58, 0x63, 0x60, 0x47, 0x01, 0x27, 0x64, 0x63, 0x61, 0x5C, 0x1B, 0x60,
+	 0xFB, 0xF9, 0xBD, 0xD0, 0xBD, 0xD0, 0x64, 0x45, 0x64, 0x41, 0xBD, 0xD0, 0x00, 0xF4, 0x04, 0xF8,
+	 0x83, 0xFA, 0x82, 0xF8, 0xA6, 0x46, 0x02, 0xB0, 0x5E, 0x63, 0x04, 0x03, 0x64, 0x63, 0x03, 0xB0,
+	 0x02, 0x3A, 0x6C, 0x63, 0x3F, 0xF2, 0xBD, 0xD0, 0xBD, 0xD0, 0x64, 0x45, 0x64, 0x41, 0xBD, 0xD0,
+	 0xA6, 0x46, 0x07, 0xF8, 0x86, 0xFA, 0x85, 0xF8, 0x60, 0x47, 0x08, 0xFA, 0x1B, 0x60, 0xFB, 0xF1,
+	 0x26, 0x46, 0x64, 0x41, 0x2F, 0x58, 0xFF, 0xFF, 0xA6, 0xF5, 0x00, 0xF2, 0x26, 0x46, 0x31, 0xF0,
+	 0x39, 0x18, 0x66, 0x41, 0x1D, 0x60, 0xC0, 0x65, 0x64, 0x47, 0x00, 0x7F, 0xA6, 0xF1, 0xE0, 0x84,
+	 0x44, 0xD3, 0x64, 0x43, 0x11, 0x18, 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xFC, 0x1B, 0x66, 0x44,
+	 0x64, 0x46, 0x80, 0xF0, 0x60, 0x46, 0x80, 0xF8, 0x65, 0x46, 0x65, 0x43, 0x80, 0xF0, 0x01, 0xFA,
+	 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8, 0x0B, 0x00, 0x64, 0x46, 0x62, 0x43, 0x00, 0xF2, 0xA3, 0xDB,
+	 0x60, 0x46, 0x80, 0xF0, 0x81, 0xFC, 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8, 0x60, 0x43, 0x61, 0x46,
+	 0x1F, 0x60, 0xC2, 0x61, 0xA1, 0xD3, 0x20, 0x60, 0x04, 0x7C, 0xD0, 0x80, 0xFF, 0xFF, 0x07, 0x03,
+	 0xA0, 0xDD, 0xDA, 0x9C, 0xA1, 0xD9, 0x49, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xA1, 0xDB, 0xD1, 0x60,
+	 0x97, 0x78, 0xFF, 0xFF, 0x20, 0x7C, 0x72, 0x44, 0xFF, 0xB4, 0xD0, 0x80, 0xFF, 0xFF, 0x02, 0x04,
+	 0xD0, 0x84, 0xFB, 0x01, 0xE0, 0x83, 0xA6, 0xF3, 0x02, 0xA3, 0x43, 0x93, 0xA6, 0xF3, 0xFF, 0xFF,
+	 0x02, 0xA5, 0xD7, 0x80, 0x04, 0xA5, 0x08, 0x24, 0x65, 0x43, 0x66, 0x41, 0x63, 0x46, 0x05, 0xF2,
+	 0x00, 0xF0, 0x81, 0xF0, 0x02, 0x18, 0x64, 0x46, 0x81, 0xF8, 0x07, 0x1B, 0x1D, 0x60, 0xC0, 0x65,
+	 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD9, 0x02, 0x00, 0x65, 0x46, 0x00, 0xF8, 0xA6, 0xF3,
+	 0x63, 0x45, 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xD4, 0x80, 0x01, 0x18, 0xFA, 0x04, 0x80, 0xF8,
+	 0x65, 0x46, 0x00, 0xFA, 0x06, 0xF2, 0xFF, 0xFF, 0x00, 0x7E, 0x06, 0xFA, 0x61, 0x46, 0x31, 0xF0,
+	 0x66, 0x41, 0x1D, 0x60, 0xC0, 0x65, 0x64, 0x47, 0x00, 0x7F, 0xA6, 0xF1, 0xE0, 0x84, 0x44, 0xD3,
+	 0x64, 0x43, 0x11, 0x18, 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xFC, 0x1B, 0x66, 0x44, 0x64, 0x46,
+	 0x80, 0xF0, 0x60, 0x46, 0x80, 0xF8, 0x65, 0x46, 0x65, 0x43, 0x80, 0xF0, 0x01, 0xFA, 0x80, 0xFC,
+	 0x64, 0x46, 0x80, 0xF8, 0x0B, 0x00, 0x64, 0x46, 0x62, 0x43, 0x00, 0xF2, 0xA3, 0xDB, 0x60, 0x46,
+	 0x80, 0xF0, 0x81, 0xFC, 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8, 0x60, 0x43, 0x61, 0x46, 0x2F, 0xF2,
+	 0x30, 0xF0, 0x31, 0xF0, 0x64, 0x45, 0x46, 0x43, 0x63, 0x46, 0x03, 0xFA, 0x06, 0xF2, 0x84, 0xF8,
+	 0x00, 0x7E, 0x06, 0xFA, 0x05, 0xF8, 0xA3, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0xDB, 0xF3, 0x2A, 0xF2,
+	 0x07, 0xB0, 0x03, 0x3A, 0x2A, 0x00, 0x00, 0xF4, 0x09, 0xF2, 0x60, 0x45, 0x80, 0x3A, 0x05, 0x00,
+	 0x0E, 0xF2, 0xFF, 0xFF, 0x02, 0xB0, 0x0F, 0xF2, 0x20, 0x03, 0x60, 0x47, 0x00, 0x3A, 0x1D, 0x00,
+	 0x60, 0x41, 0x00, 0x36, 0x13, 0x00, 0xDA, 0x85, 0x33, 0x60, 0xBE, 0x63, 0xBD, 0xD1, 0xFF, 0xFF,
+	 0xD1, 0x80, 0xFF, 0xFF, 0x12, 0x02, 0x60, 0xFE, 0xBD, 0xD3, 0xA5, 0xD0, 0xDE, 0x85, 0xD0, 0x80,
+	 0xCD, 0x81, 0x0B, 0x02, 0xF9, 0x02, 0x20, 0xFE, 0x00, 0x64, 0x09, 0x00, 0x26, 0x46, 0x48, 0xFE,
+	 0x65, 0x40, 0x40, 0x3A, 0x02, 0x00, 0x01, 0x64, 0x02, 0x00, 0x28, 0xFE, 0x00, 0x64, 0x40, 0x48,
+	 0x26, 0x46, 0x2D, 0x58, 0xFF, 0xFF, 0x19, 0x60, 0xA3, 0xF3, 0x3D, 0xF2, 0x60, 0x40, 0x01, 0x26,
+	 0x2A, 0xFA, 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x08, 0x26, 0x03, 0x00, 0xD2, 0x60, 0xB5, 0x78,
+	 0xFF, 0xFF, 0x3F, 0xF0, 0x32, 0x40, 0x10, 0x2A, 0x0E, 0x00, 0x2C, 0xF0, 0x64, 0x41, 0x60, 0x40,
+	 0x40, 0x27, 0x09, 0x00, 0xCD, 0x81, 0xDD, 0x81, 0x06, 0x03, 0x05, 0x03, 0x64, 0x40, 0x01, 0x26,
+	 0x02, 0x00, 0x01, 0x61, 0x01, 0x00, 0x00, 0x61, 0x60, 0x40, 0x18, 0x36, 0x1F, 0x00, 0xD0, 0x60,
+	 0x58, 0x4F, 0xD1, 0x78, 0xFF, 0xFF, 0x0F, 0xF0, 0xEA, 0xF1, 0x64, 0x44, 0x60, 0x22, 0x19, 0x00,
+	 0xDB, 0xF3, 0xFF, 0xFF, 0x07, 0xB4, 0xFD, 0xA0, 0x2A, 0xF2, 0x03, 0x02, 0x08, 0xB0, 0xFF, 0xFF,
+	 0x10, 0x02, 0x32, 0xF2, 0x33, 0xF2, 0xD0, 0x80, 0xEB, 0xF1, 0x0B, 0x02, 0xD0, 0x80, 0x34, 0xF2,
+	 0x08, 0x02, 0xEC, 0xF1, 0xFF, 0xFF, 0xD0, 0x80, 0x0F, 0xF0, 0x03, 0x02, 0xD3, 0x60, 0x10, 0x78,
+	 0xFF, 0xFF, 0x00, 0xF4, 0xAA, 0x60, 0xAA, 0x65, 0x09, 0xF2, 0x5A, 0xD0, 0xD4, 0x80, 0x03, 0x64,
+	 0x57, 0x02, 0xD0, 0x80, 0x00, 0x64, 0x5A, 0xD0, 0x53, 0x02, 0x64, 0x45, 0xD4, 0x80, 0xF8, 0x7F,
+	 0x08, 0x02, 0x5A, 0xD0, 0x26, 0x46, 0x64, 0x45, 0x23, 0xF0, 0x20, 0x67, 0xB0, 0x84, 0xA2, 0xDA,
+	 0x0B, 0x00, 0xD4, 0x80, 0x1D, 0x60, 0x60, 0x64, 0x16, 0x02, 0x5A, 0xD0, 0x26, 0x46, 0x64, 0x45,
+	 0x23, 0xF0, 0x40, 0x67, 0xB0, 0x84, 0xA2, 0xDA, 0x65, 0x44, 0x88, 0x3A, 0x07, 0x00, 0x77, 0x37,
+	 0x08, 0x00, 0x78, 0x37, 0x06, 0x00, 0x8E, 0x37, 0x04, 0x00, 0x32, 0x00, 0x81, 0x3A, 0x30, 0x00,
+	 0x80, 0x37, 0x00, 0x61, 0x2D, 0x00, 0xD4, 0x80, 0x01, 0x60, 0x00, 0x64, 0x5A, 0xD0, 0x28, 0x02,
+	 0xD0, 0x80, 0x5A, 0xD0, 0x25, 0x02, 0x26, 0x46, 0x64, 0x47, 0x7F, 0xB4, 0xFD, 0xA0, 0x09, 0x03,
+	 0x1F, 0x07, 0x32, 0x40, 0x02, 0x26, 0x44, 0x00, 0x23, 0xF0, 0x60, 0x67, 0xB0, 0x84, 0xA2, 0xDA,
+	 0x3F, 0x00, 0x0F, 0xF2, 0x32, 0x40, 0x02, 0x26, 0x3B, 0x00, 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40,
+	 0x08, 0x2A, 0x07, 0x00, 0x60, 0x40, 0x48, 0x36, 0x04, 0x00, 0xF1, 0xF3, 0xFF, 0xFF, 0x02, 0xBC,
+	 0xF1, 0xFB, 0xF4, 0x60, 0x58, 0x4F, 0x1D, 0x78, 0xFF, 0xFF, 0xD3, 0x60, 0x1A, 0x78, 0xFF, 0xFF,
+	 0x26, 0x46, 0x61, 0x40, 0x01, 0x2A, 0x07, 0x00, 0x2C, 0x60, 0xF8, 0x64, 0xF1, 0x60, 0x78, 0x41,
+	 0xE4, 0x78, 0xB5, 0xF1, 0x85, 0x00, 0x0F, 0xF2, 0x7F, 0xF1, 0x2A, 0xF2, 0x60, 0x40, 0x20, 0x2A,
+	 0x12, 0x00, 0x5E, 0x63, 0x60, 0x40, 0x02, 0x2B, 0x64, 0x63, 0xBD, 0xD2, 0xBD, 0xD2, 0xD0, 0x80,
+	 0x80, 0xF1, 0x08, 0x02, 0xD0, 0x80, 0xA3, 0xD2, 0x81, 0xF1, 0x04, 0x02, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x01, 0x02, 0x06, 0x00, 0x6D, 0x00, 0x2A, 0xF2, 0xFF, 0xFF, 0xFF, 0xFF, 0x48, 0x36, 0x68, 0x00,
+	 0x2A, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x08, 0x2A, 0x07, 0x00, 0x60, 0x40, 0x48, 0x36, 0x04, 0x00,
+	 0xF1, 0xF3, 0xFF, 0xFF, 0x02, 0xBC, 0xF1, 0xFB, 0x68, 0x00, 0x26, 0x46, 0x2A, 0xF2, 0xFF, 0xFF,
+	 0xFF, 0xFF, 0x0C, 0x26, 0x55, 0x00, 0xB0, 0x36, 0x15, 0x00, 0x10, 0x36, 0x13, 0x00, 0x30, 0x36,
+	 0x11, 0x00, 0xC0, 0x36, 0x02, 0x00, 0xA0, 0x3A, 0x12, 0x00, 0x7F, 0xF1, 0x32, 0xF2, 0x33, 0xF2,
+	 0xD0, 0x80, 0x80, 0xF1, 0x45, 0x02, 0xD0, 0x80, 0x34, 0xF2, 0x81, 0xF1, 0x41, 0x02, 0xD0, 0x80,
+	 0xFF, 0xFF, 0x3E, 0x02, 0xE6, 0x60, 0x58, 0x4F, 0x3D, 0x78, 0xFF, 0xFF, 0x35, 0x00, 0x50, 0x3A,
+	 0x05, 0x00, 0xF8, 0x60, 0x58, 0x4F, 0xE1, 0x78, 0xFF, 0xFF, 0x2E, 0x00, 0x40, 0x3A, 0x05, 0x00,
+	 0xF0, 0x60, 0x58, 0x4F, 0x99, 0x78, 0xFF, 0xFF, 0x27, 0x00, 0x80, 0x3A, 0x24, 0x00, 0x7F, 0xF1,
+	 0x32, 0xF2, 0x33, 0xF2, 0xD0, 0x80, 0x80, 0xF1, 0x23, 0x02, 0xD0, 0x80, 0x34, 0xF2, 0x81, 0xF1,
+	 0x1F, 0x02, 0xD0, 0x80, 0xFF, 0xFF, 0x1C, 0x02, 0xE9, 0x60, 0x58, 0x4F, 0x30, 0x78, 0xFF, 0xFF,
+	 0x7D, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x27, 0x0A, 0x00, 0x19, 0x60, 0x4C, 0xF3, 0xFF, 0xFF,
+	 0x60, 0x40, 0x08, 0x26, 0x04, 0x00, 0xEE, 0x60, 0x58, 0x4F, 0x81, 0x78, 0xFF, 0xFF, 0x24, 0x60,
+	 0x58, 0x4F, 0xE3, 0x78, 0xFF, 0xFF, 0x04, 0x00, 0x66, 0x44, 0x00, 0xA8, 0xFF, 0xFF, 0x0A, 0x03,
+	 0x26, 0x46, 0x26, 0x60, 0x1A, 0x64, 0x40, 0x4B, 0x34, 0x60, 0x58, 0x4D, 0x08, 0x78, 0xFF, 0xFF,
+	 0x00, 0x66, 0x46, 0x46, 0xD0, 0x60, 0xB2, 0x78, 0xFF, 0xFF, 0x2A, 0xF2, 0x3B, 0xF0, 0x60, 0x40,
+	 0x40, 0x2B, 0x06, 0x00, 0xC0, 0x60, 0x00, 0x64, 0x64, 0x40, 0x20, 0x2B, 0x01, 0x00, 0x03, 0x00,
+	 0xD3, 0x60, 0x4C, 0x78, 0xFF, 0xFF, 0x22, 0xF2, 0xFF, 0xFF, 0x04, 0xB4, 0xFF, 0xFF, 0xF8, 0x03,
+	 0x23, 0xF2, 0x07, 0xF4, 0xBB, 0xF0, 0x26, 0x46, 0xA4, 0x84, 0xFF, 0xFF, 0x60, 0x40, 0x2F, 0x26,
+	 0xD7, 0x01, 0x12, 0xF0, 0xFF, 0xFF, 0x10, 0x1B, 0xCA, 0x60, 0x58, 0x4F, 0x16, 0x78, 0xFF, 0xFF,
+	 0x64, 0x40, 0x18, 0x36, 0x09, 0x00, 0x04, 0x65, 0xF1, 0x60, 0x58, 0x4E, 0x96, 0x78, 0xFF, 0xFF,
+	 0x26, 0x46, 0xD3, 0x60, 0x10, 0x78, 0xFF, 0xFF, 0x25, 0x60, 0xFE, 0x64, 0x13, 0x60, 0x0D, 0xFB,
+	 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xF8, 0xFE, 0xC0, 0x01,
+	 0x1C, 0x60, 0x92, 0x63, 0x00, 0x64, 0xA3, 0xDB, 0x06, 0xA3, 0x10, 0x60, 0x94, 0x64, 0xBD, 0xDB,
+	 0xBD, 0xDB, 0x06, 0x64, 0xA3, 0xDB, 0x00, 0x63, 0x08, 0x60, 0x77, 0xFD, 0xD9, 0x60, 0xA5, 0x64,
+	 0x08, 0x60, 0x49, 0xFB, 0xD9, 0x60, 0x6A, 0x64, 0x08, 0x60, 0x35, 0xFB, 0x00, 0x60, 0x02, 0x64,
+	 0x08, 0x60, 0x16, 0xFB, 0xD3, 0x60, 0x9C, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x7D, 0xF3, 0x33, 0x60, 0x20, 0x63, 0x60, 0x40, 0x01, 0x27, 0x03, 0x00, 0x19, 0x60, 0x3B, 0xF3,
+	 0x02, 0x00, 0x19, 0x60, 0x3C, 0xF3, 0x08, 0x61, 0x60, 0xFE, 0xA3, 0xD1, 0xFF, 0xFF, 0x20, 0xFE,
+	 0x00, 0xA8, 0xE8, 0x84, 0x0F, 0x03, 0x60, 0xFE, 0x02, 0x28, 0xF6, 0x01, 0x80, 0x62, 0xB2, 0x9C,
+	 0xBD, 0xD9, 0x7B, 0xF9, 0xCD, 0x81, 0x00, 0x36, 0x01, 0x00, 0xEE, 0x01, 0x36, 0x60, 0x0A, 0x63,
+	 0x08, 0x61, 0xEA, 0x01, 0x2E, 0x58, 0xFF, 0xFF, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0xBA, 0xFE, 0x16, 0x60, 0x87, 0xF3, 0xFF, 0xFF, 0x03, 0xA8, 0x02, 0xA8, 0x04, 0x03, 0x28, 0x02,
+	 0xD9, 0x60, 0x41, 0x78, 0xFF, 0xFF, 0xD8, 0x60, 0xD4, 0x78, 0xFF, 0xFF, 0x08, 0x60, 0x15, 0xF1,
+	 0x00, 0x60, 0x04, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x11, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xAC, 0xF3,
+	 0xFF, 0xFF, 0xFE, 0xA0, 0xFF, 0xFF, 0x0A, 0x07, 0x1C, 0x60, 0x92, 0x64, 0x13, 0x60, 0x22, 0xFB,
+	 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x2F, 0x58, 0xFF, 0xFF, 0x20, 0x60, 0x20, 0x65,
+	 0xA5, 0xDF, 0x00, 0x64, 0x08, 0x60, 0x27, 0xFB, 0x5A, 0xDB, 0xD4, 0x60, 0xF6, 0x78, 0xFF, 0xFF,
+	 0x01, 0x63, 0x0E, 0x60, 0x36, 0xFD, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x00, 0x64,
+	 0x08, 0x60, 0x15, 0xFB, 0x5A, 0xDB, 0xBA, 0xFE, 0x02, 0x64, 0xDB, 0xFB, 0xF1, 0xF3, 0xFF, 0xFF,
+	 0x01, 0xBC, 0xF1, 0xFB, 0x44, 0x60, 0x44, 0x64, 0x7F, 0xFB, 0x80, 0xFB, 0x81, 0xFB, 0x08, 0x60,
+	 0x00, 0x65, 0x20, 0x44, 0x34, 0x80, 0x08, 0x60, 0x77, 0xF3, 0xFF, 0xFF, 0x15, 0x18, 0xA2, 0xDF,
+	 0x40, 0x60, 0x58, 0x4E, 0x7D, 0x78, 0xFF, 0xFF, 0x1F, 0x60, 0xC4, 0x64, 0x0F, 0x60, 0xE1, 0xFB,
+	 0x4A, 0xDF, 0x01, 0x60, 0xFE, 0x63, 0x1D, 0x60, 0xBE, 0x61, 0x00, 0x64, 0x59, 0xDB, 0xFE, 0x1F,
+	 0x10, 0x60, 0x0E, 0x62, 0xA2, 0xDF, 0x5B, 0x00, 0xCF, 0xF3, 0xFF, 0xFF, 0x52, 0x1B, 0x10, 0x60,
+	 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x24, 0x40, 0x02, 0x22, 0x26, 0x00, 0x08, 0x60, 0x1E, 0xF1,
+	 0x00, 0x60, 0x20, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x10, 0x60, 0x00, 0x64, 0x08, 0x60,
+	 0x16, 0xFB, 0xD4, 0x60, 0x1F, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x60,
+	 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x08, 0x60, 0x1E, 0xF1, 0x00, 0x60, 0x40, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x10, 0x60, 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xD4, 0x60, 0x59, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x24, 0x40, 0x01, 0x26, 0x11, 0x00, 0x08, 0x60,
+	 0x1E, 0xF1, 0x00, 0x60, 0x20, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x10, 0x60, 0x00, 0x64,
+	 0x08, 0x60, 0x16, 0xFB, 0xD4, 0x60, 0x59, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x08, 0x60, 0x1E, 0xF1, 0x00, 0x60, 0x40, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x10, 0x60,
+	 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xD4, 0x60, 0x59, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0xFD, 0x60, 0x89, 0x65, 0xF3, 0x60, 0x58, 0x4E, 0x27, 0x78, 0xFF, 0xFF, 0x10, 0x60,
+	 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x00, 0x64, 0x08, 0x60, 0x15, 0xFB, 0x5A, 0xDB, 0x10, 0x60,
+	 0x4E, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xF7, 0x60, 0xFF, 0x65, 0x20, 0x44, 0x24, 0x80, 0x08, 0x60,
+	 0x08, 0xF1, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0xBB, 0xFE, 0xFD, 0x60,
+	 0x40, 0x65, 0xF3, 0x60, 0x58, 0x4E, 0x27, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x03, 0x64, 0x08, 0x60,
+	 0x28, 0xFB, 0xD4, 0x60, 0x87, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60,
+	 0x27, 0xF1, 0x00, 0x60, 0x02, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x07, 0x03, 0xA0, 0x84, 0xA2, 0xDB,
+	 0x10, 0x60, 0x4E, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xE2, 0x01, 0x10, 0x60, 0x4E, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0x00, 0x64, 0x08, 0x60, 0x27, 0xFB, 0x5A, 0xDB, 0x20, 0x40, 0x04, 0x2B, 0x14, 0x00,
+	 0x9B, 0xFE, 0x08, 0x04, 0xBB, 0xFE, 0x08, 0x60, 0x08, 0xF1, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x80, 0x60, 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xD4, 0x60, 0x95, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x00, 0x65, 0x20, 0x44, 0x34, 0x80,
+	 0x16, 0x60, 0xCC, 0xF3, 0x00, 0x61, 0x60, 0x40, 0x00, 0x36, 0x00, 0xB9, 0x60, 0x40, 0x01, 0x36,
+	 0x01, 0xB9, 0x60, 0x40, 0x02, 0x36, 0x06, 0xB9, 0x60, 0x40, 0x03, 0x36, 0x07, 0xB9, 0x41, 0x44,
+	 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE, 0x0A, 0x04, 0x40, 0x60, 0x00, 0x64,
+	 0x08, 0x60, 0x16, 0xFB, 0xD4, 0x60, 0xC8, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x7D, 0xF1, 0x13, 0x60, 0x1A, 0xF9, 0x0C, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x20, 0x60,
+	 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xD4, 0x60, 0xE9, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xBE, 0xFE, 0x08, 0x60, 0x08, 0xF1,
+	 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x75, 0x00, 0x10, 0x60, 0x2A, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0xBA, 0xFE, 0x02, 0x64, 0xDB, 0xFB, 0xF1, 0xF3, 0xFF, 0xFF, 0x01, 0xBC,
+	 0xF1, 0xFB, 0x44, 0x60, 0x44, 0x64, 0x7F, 0xFB, 0x80, 0xFB, 0x81, 0xFB, 0xFF, 0xFF, 0x20, 0x40,
+	 0x04, 0x2B, 0x14, 0x00, 0x9B, 0xFE, 0x08, 0x04, 0xBB, 0xFE, 0x08, 0x60, 0x08, 0xF1, 0x80, 0x60,
+	 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x80, 0x60, 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB,
+	 0xD5, 0x60, 0x07, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x00, 0x65,
+	 0x20, 0x44, 0x34, 0x80, 0x08, 0x60, 0x07, 0xF1, 0x02, 0x60, 0x00, 0x65, 0x20, 0x44, 0x34, 0x80,
+	 0x64, 0x40, 0x01, 0x2A, 0x06, 0x00, 0xA2, 0xDF, 0x02, 0x65, 0xF1, 0x60, 0x58, 0x4E, 0xC3, 0x78,
+	 0xFF, 0xFF, 0xCF, 0xF3, 0x20, 0x60, 0x20, 0x65, 0x36, 0x1B, 0xA5, 0xD3, 0x24, 0x40, 0x01, 0x26,
+	 0x16, 0x00, 0x60, 0x40, 0x20, 0x26, 0x2F, 0x00, 0x01, 0xBC, 0xA5, 0xDB, 0x08, 0x60, 0x1E, 0xF1,
+	 0x00, 0x60, 0x20, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x10, 0x60, 0x00, 0x64, 0x08, 0x60,
+	 0x16, 0xFB, 0xD5, 0x60, 0x65, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x60, 0x40,
+	 0x10, 0x26, 0x19, 0x00, 0x01, 0xBC, 0xA5, 0xDB, 0x08, 0x60, 0x1E, 0xF1, 0x00, 0x60, 0x40, 0x64,
+	 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x10, 0x60, 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xD5, 0x60,
+	 0x65, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0xFD, 0x60, 0x89, 0x65, 0xF3, 0x60,
+	 0x58, 0x4E, 0x27, 0x78, 0xFF, 0xFF, 0xCF, 0xF1, 0x07, 0x60, 0xE9, 0xF3, 0x64, 0x40, 0x02, 0x3A,
+	 0x0C, 0x00, 0x01, 0x63, 0x60, 0x40, 0x10, 0x22, 0x00, 0x63, 0x08, 0x60, 0xC1, 0xFD, 0x08, 0x60,
+	 0xC5, 0xFD, 0x08, 0x60, 0xC9, 0xFD, 0x08, 0x60, 0xCD, 0xFD, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0x01, 0x64, 0x53, 0xFB, 0x2F, 0x60, 0x02, 0x64, 0x54, 0xFB, 0x24, 0x40, 0x01, 0x26,
+	 0x11, 0x00, 0x08, 0x60, 0x12, 0xF1, 0x00, 0x60, 0x10, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x10, 0x60, 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xD5, 0x60, 0xAB, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x12, 0xF1, 0x00, 0x60, 0x20, 0x64, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xCF, 0xFE, 0x10, 0x60, 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xD5, 0x60, 0xAB, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0xFD, 0x60, 0xFF, 0x65, 0x20, 0x44, 0x24, 0x80, 0x08, 0x60,
+	 0x08, 0xF1, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x10, 0x60, 0x2A, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x86, 0xF1, 0x1B, 0x60, 0xB2, 0x63, 0xD3, 0x80, 0x20, 0x44, 0x03, 0x03,
+	 0xD8, 0x60, 0xD0, 0x78, 0xFF, 0xFF, 0x87, 0xF3, 0xFF, 0xFF, 0xD0, 0x80, 0xFF, 0xFF, 0x1B, 0x02,
+	 0x24, 0x44, 0x04, 0x22, 0x12, 0x00, 0x24, 0x44, 0x01, 0xAC, 0xFB, 0xB4, 0x40, 0x44, 0xF7, 0x60,
+	 0xFF, 0x65, 0x20, 0x44, 0x24, 0x80, 0x08, 0x60, 0x08, 0xF1, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0xD4, 0x60, 0xF6, 0x78, 0xFF, 0xFF, 0xD2, 0xF3, 0xFF, 0xFF, 0x00, 0xA8,
+	 0xFF, 0xFF, 0x1F, 0x02, 0x87, 0x00, 0x20, 0x44, 0x10, 0xBC, 0x40, 0x40, 0x64, 0x42, 0x5A, 0xD1,
+	 0x06, 0x63, 0xA4, 0xD1, 0xC3, 0x83, 0x7D, 0xF9, 0xBD, 0xD1, 0x7F, 0xF9, 0xBD, 0xD1, 0xFF, 0xFF,
+	 0x80, 0xF9, 0xBD, 0xD1, 0x81, 0xF9, 0x04, 0xA3, 0xBD, 0xD1, 0x33, 0x60, 0xBE, 0x64, 0x64, 0x41,
+	 0xDD, 0x81, 0xFE, 0xB1, 0xA0, 0xD9, 0x04, 0x03, 0xBD, 0xD1, 0xC9, 0x81, 0x58, 0xD9, 0xFC, 0x02,
+	 0x39, 0x00, 0xE4, 0xF3, 0x7D, 0xFB, 0x66, 0x41, 0x60, 0x40, 0x01, 0x27, 0x06, 0x00, 0x10, 0x60,
+	 0xF0, 0x63, 0x11, 0x60, 0x44, 0x65, 0x06, 0x66, 0x05, 0x00, 0x11, 0x60, 0x60, 0x63, 0x12, 0x60,
+	 0x40, 0x65, 0x08, 0x66, 0xA3, 0xD1, 0x4B, 0x93, 0xD0, 0x80, 0xD7, 0x80, 0x02, 0x03, 0xFA, 0x04,
+	 0x04, 0x00, 0x5B, 0x93, 0x02, 0xA3, 0x01, 0x64, 0xA3, 0xDB, 0x61, 0x46, 0x2F, 0x60, 0x02, 0x61,
+	 0xA1, 0xD3, 0xFF, 0xFF, 0x00, 0xA8, 0x33, 0x60, 0xBE, 0x63, 0x02, 0x02, 0x2D, 0x60, 0x10, 0x61,
+	 0xA1, 0xD3, 0xBD, 0xDB, 0xDC, 0x84, 0xFE, 0xB4, 0x59, 0xD1, 0xC8, 0x84, 0xBD, 0xD9, 0xFC, 0x02,
+	 0xEC, 0xF3, 0x72, 0x45, 0xEB, 0xF3, 0x94, 0x83, 0x81, 0xFD, 0x94, 0x83, 0x80, 0xFD, 0x65, 0x5F,
+	 0x02, 0x64, 0x7F, 0xFB, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE, 0x0A, 0x04,
+	 0x40, 0x60, 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xD6, 0x60, 0x3A, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x7D, 0xF1, 0x13, 0x60, 0x1A, 0xF9, 0x0E, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x2D, 0xFF, 0x20, 0x60, 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xD6, 0x60, 0x5B, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xBE, 0xFE,
+	 0x08, 0x60, 0x08, 0xF1, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0xD7, 0x60,
+	 0x7B, 0x78, 0xFF, 0xFF, 0xFF, 0x60, 0xEF, 0x65, 0x20, 0x44, 0x24, 0x80, 0x02, 0x64, 0xDB, 0xFB,
+	 0xF1, 0xF3, 0xFF, 0xFF, 0x01, 0xBC, 0xF1, 0xFB, 0xF7, 0x60, 0xFF, 0x65, 0x20, 0x44, 0x24, 0x80,
+	 0x08, 0x60, 0x08, 0xF1, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x10, 0x60,
+	 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x24, 0x44, 0x02, 0x22, 0x03, 0x00, 0x01, 0xAC, 0x04, 0xBC,
+	 0x40, 0x44, 0x32, 0x40, 0x80, 0x2A, 0x8C, 0x00, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0xDE, 0xFE, 0x0A, 0x04, 0x40, 0x60, 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xD6, 0x60, 0x8C, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0x95, 0xF3, 0xFF, 0xFF, 0x7F, 0xB4, 0x95, 0xFB, 0x26, 0x60, 0x34, 0x62, 0x06, 0x64, 0x4A, 0xDB,
+	 0xFF, 0xFF, 0x2D, 0xFF, 0xFF, 0xFF, 0xBE, 0xFE, 0x08, 0x60, 0x08, 0xF1, 0x40, 0x60, 0x00, 0x64,
+	 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0xDA, 0xFE, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0x12, 0x60, 0xFF, 0xF3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x05, 0x03, 0x0E, 0xF2, 0xFF, 0xFF,
+	 0x60, 0x40, 0x01, 0x2A, 0x22, 0x00, 0x13, 0x60, 0x02, 0xF3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46,
+	 0x03, 0x03, 0x0F, 0xF2, 0xFF, 0xFF, 0x19, 0x1B, 0x08, 0x60, 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB,
+	 0xD6, 0x60, 0xE5, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x01, 0x64, 0x19, 0x60, 0xF1, 0xFB, 0x19, 0x60,
+	 0xF6, 0xF1, 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x26, 0x05, 0x00, 0x89, 0xFF, 0x08, 0x60, 0x00, 0x75,
+	 0x88, 0xFF, 0x01, 0x00, 0x10, 0xFF, 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0xDE, 0xFE, 0x0A, 0x04, 0x40, 0x60, 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xD6, 0x60,
+	 0xE5, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0x7D, 0xF1, 0x13, 0x60, 0x1A, 0xF9, 0x08, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF,
+	 0x20, 0x60, 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xD7, 0x60, 0x0A, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0xBE, 0xFE, 0x08, 0x60, 0x08, 0xF1, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0xBA, 0xFE, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x1E, 0x00,
+	 0xDA, 0xFE, 0xC1, 0xFE, 0x0E, 0x60, 0x36, 0xF1, 0x0E, 0x60, 0x4B, 0xF9, 0x1C, 0x60, 0x92, 0x64,
+	 0x13, 0x60, 0x22, 0xFB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x00, 0x60, 0x06, 0x64,
+	 0x08, 0x60, 0x16, 0xFB, 0xD7, 0x60, 0x4E, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x00, 0x60, 0x02, 0x64,
+	 0x08, 0x60, 0x28, 0xFB, 0xD7, 0x60, 0x55, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x1C, 0x60, 0x6C, 0x61,
+	 0x75, 0x60, 0x30, 0x65, 0xA1, 0xD3, 0xFF, 0xFF, 0xFF, 0xA0, 0xE0, 0x84, 0x02, 0x02, 0x03, 0x60,
+	 0xE8, 0x64, 0xD4, 0x80, 0xFF, 0xFF, 0x01, 0x04, 0x65, 0x44, 0xA1, 0xDB, 0x32, 0x40, 0x80, 0x2A,
+	 0x03, 0x00, 0xD4, 0x60, 0xF6, 0x78, 0xFF, 0xFF, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x64, 0x08, 0x60,
+	 0x27, 0xFB, 0x5A, 0xDB, 0xD4, 0x60, 0xF6, 0x78, 0xFF, 0xFF, 0x20, 0x40, 0x06, 0x23, 0x10, 0x00,
+	 0x08, 0x60, 0x27, 0xF1, 0x7F, 0x60, 0xFF, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x80, 0x60, 0x00, 0x64,
+	 0x08, 0x60, 0x28, 0xFB, 0xD7, 0x60, 0x55, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x10, 0x60, 0x4E, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x00, 0x64, 0x08, 0x60, 0x27, 0xFB, 0x5A, 0xDB,
+	 0x1C, 0x60, 0x92, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF,
+	 0xD3, 0x60, 0xD0, 0x78, 0xFF, 0xFF, 0x78, 0xF3, 0x79, 0xFB, 0x20, 0x60, 0x14, 0x62, 0xA2, 0xDF,
+	 0xFF, 0x60, 0xDF, 0x65, 0x20, 0x44, 0x24, 0x80, 0xBC, 0xF1, 0x0E, 0x60, 0x4B, 0xF9, 0x1C, 0x60,
+	 0x92, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0xF7, 0x60,
+	 0xFF, 0x65, 0x20, 0x44, 0x24, 0x80, 0x10, 0x26, 0x38, 0x00, 0x00, 0x64, 0xB2, 0xFB, 0xB3, 0xFB,
+	 0xB4, 0xFB, 0x00, 0x75, 0x00, 0x72, 0xBA, 0xF1, 0x7E, 0xF9, 0x64, 0x44, 0xE0, 0x84, 0xE0, 0x84,
+	 0xE0, 0x84, 0xE0, 0x93, 0xE5, 0xF1, 0x84, 0xF9, 0x7D, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x27,
+	 0x1E, 0x00, 0x19, 0x60, 0x44, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x2A, 0x0A, 0x00, 0x0F, 0x64,
+	 0xFC, 0x60, 0x58, 0x4E, 0x34, 0x78, 0xFF, 0xFF, 0x67, 0x43, 0x1A, 0x60, 0xB3, 0xFD, 0x1A, 0x60,
+	 0xC3, 0xFD, 0xD3, 0x60, 0x58, 0x4E, 0x78, 0x78, 0xFF, 0xFF, 0x00, 0x65, 0xFC, 0x60, 0x58, 0x4E,
+	 0xC7, 0x78, 0xFF, 0xFF, 0xFD, 0x60, 0x58, 0x4E, 0x11, 0x78, 0xFF, 0xFF, 0x05, 0x00, 0xFF, 0x65,
+	 0xFC, 0x60, 0x58, 0x4E, 0xC7, 0x78, 0xFF, 0xFF, 0x44, 0x00, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0x00, 0x60, 0x84, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xD7, 0x60, 0xDB, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x15, 0xF1, 0x00, 0x60, 0x80, 0x64, 0xA0, 0x80,
+	 0x9C, 0x84, 0x2B, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x08, 0x60, 0x15, 0xF1, 0xFF, 0x60, 0x7F, 0x61,
+	 0xA1, 0x84, 0x5A, 0xD1, 0x4A, 0xDB, 0xA1, 0x84, 0x5A, 0xDB, 0x2E, 0x60, 0x2E, 0x64, 0x2D, 0x60,
+	 0x8A, 0x63, 0xA0, 0xD1, 0xA3, 0xD9, 0x64, 0x41, 0x58, 0xD1, 0x5B, 0xD9, 0x7D, 0xF3, 0x66, 0x45,
+	 0xA6, 0xF5, 0x60, 0x40, 0x01, 0x27, 0x08, 0x00, 0x91, 0xFA, 0x61, 0x44, 0xFD, 0x60, 0x58, 0x4E,
+	 0xAC, 0x78, 0xFF, 0xFF, 0x12, 0xFA, 0x07, 0x00, 0x11, 0xF8, 0x64, 0x44, 0xFD, 0x60, 0x58, 0x4E,
+	 0xAC, 0x78, 0xFF, 0xFF, 0x12, 0xFA, 0x65, 0x46, 0x04, 0x00, 0xBB, 0xFE, 0xD4, 0x60, 0xF6, 0x78,
+	 0xFF, 0xFF, 0x16, 0x60, 0xC2, 0xF1, 0x00, 0x65, 0x64, 0x40, 0x01, 0x36, 0x22, 0x65, 0x64, 0x40,
+	 0x07, 0x36, 0x01, 0x65, 0x64, 0x40, 0x0A, 0x36, 0x01, 0x65, 0x64, 0x40, 0x0B, 0x36, 0x22, 0x65,
+	 0xA6, 0xF3, 0x66, 0x5C, 0x60, 0x46, 0x1F, 0x63, 0xE3, 0x83, 0xBA, 0xF8, 0x02, 0xA6, 0x66, 0x44,
+	 0xFC, 0x1F, 0x16, 0x60, 0xC2, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x07, 0x36, 0x03, 0x00, 0x0A, 0x36,
+	 0x06, 0x00, 0x09, 0x00, 0xA6, 0xF3, 0x04, 0x65, 0x60, 0x46, 0xBA, 0xF8, 0x04, 0x00, 0xA6, 0xF3,
+	 0x10, 0x65, 0x60, 0x46, 0xBA, 0xF8, 0x64, 0x46, 0xA6, 0xF3, 0x32, 0x41, 0x60, 0x45, 0x08, 0xB1,
+	 0x66, 0x41, 0x16, 0x03, 0x65, 0x46, 0x17, 0x60, 0x80, 0xF3, 0x06, 0xF0, 0xE0, 0x84, 0xE0, 0x84,
+	 0xE0, 0x84, 0xE0, 0x84, 0x80, 0xBF, 0xB0, 0x84, 0x06, 0xFA, 0x66, 0x43, 0x02, 0xA3, 0x63, 0x46,
+	 0x06, 0xF0, 0xFF, 0xFF, 0xB0, 0x84, 0x06, 0xFA, 0x61, 0x46, 0x32, 0x44, 0x10, 0xBC, 0x40, 0x52,
+	 0x01, 0x64, 0x10, 0x60, 0x0A, 0xFB, 0x0F, 0x4E, 0xEF, 0x60, 0x58, 0x4F, 0x3A, 0x78, 0xFF, 0xFF,
+	 0x0E, 0x4F, 0x08, 0x60, 0x15, 0xF1, 0xFF, 0x60, 0xFB, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x00, 0x60,
+	 0x04, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xD3, 0x60, 0xAE, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x1C, 0x60,
+	 0x92, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0xBB, 0xFE,
+	 0x20, 0x44, 0x04, 0x27, 0x11, 0x00, 0x10, 0x26, 0x02, 0x00, 0xDB, 0xFE, 0x14, 0x00, 0x08, 0x60,
+	 0x07, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x36, 0x07, 0x00, 0x01, 0x64, 0xA2, 0xDB, 0x01, 0x65,
+	 0xF1, 0x60, 0x58, 0x4E, 0xC3, 0x78, 0xFF, 0xFF, 0x08, 0x60, 0x08, 0xF1, 0x80, 0x60, 0x00, 0x64,
+	 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x01, 0x64, 0x8A, 0xFB, 0xFF, 0x60, 0xEF, 0x65, 0x20, 0x44,
+	 0x24, 0x80, 0x03, 0x64, 0xDB, 0xFB, 0xF1, 0xF3, 0xFF, 0xFF, 0xFE, 0xB4, 0xF1, 0xFB, 0xC1, 0xFE,
+	 0x00, 0x60, 0x02, 0x64, 0x08, 0x60, 0x28, 0xFB, 0xD8, 0x60, 0xAA, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x20, 0x40, 0x06, 0x23, 0x10, 0x00, 0x08, 0x60, 0x27, 0xF1, 0x7F, 0x60,
+	 0xFF, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x80, 0x60, 0x00, 0x64, 0x08, 0x60, 0x28, 0xFB, 0xD8, 0x60,
+	 0xAA, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x60, 0x4E, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0x00, 0x64, 0x08, 0x60, 0x27, 0xFB, 0x5A, 0xDB, 0x1C, 0x60, 0x92, 0x64, 0x13, 0x60,
+	 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0xD3, 0x60, 0xD0, 0x78, 0xFF, 0xFF,
+	 0xBB, 0xFE, 0xD9, 0x60, 0xB0, 0x78, 0xFF, 0xFF, 0x16, 0x60, 0xC2, 0xF1, 0x00, 0x65, 0x64, 0x40,
+	 0x01, 0x36, 0x22, 0x65, 0xA6, 0xF3, 0x66, 0x5C, 0x60, 0x46, 0x1F, 0x63, 0xE3, 0x83, 0xBA, 0xF8,
+	 0x02, 0xA6, 0x66, 0x44, 0xFC, 0x1F, 0x64, 0x46, 0xA6, 0xF1, 0x02, 0x64, 0xC0, 0x85, 0x0C, 0x61,
+	 0x32, 0x40, 0x08, 0x2A, 0x14, 0x00, 0x17, 0x60, 0x80, 0xF3, 0x66, 0x41, 0x65, 0x46, 0x06, 0xF0,
+	 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0x80, 0xBF, 0xB0, 0x83, 0x06, 0xFC, 0x66, 0x42,
+	 0xFE, 0xA2, 0x62, 0x46, 0x06, 0xF0, 0xFF, 0xFF, 0xB0, 0x84, 0x06, 0xFA, 0x61, 0x46, 0x0B, 0x64,
+	 0xDB, 0xFB, 0xF1, 0xF3, 0xFF, 0xFF, 0xFE, 0xB4, 0xF1, 0xFB, 0x01, 0x65, 0xF1, 0x60, 0x58, 0x4E,
+	 0xC3, 0x78, 0xFF, 0xFF, 0xE4, 0xF1, 0x7D, 0xF9, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0xDE, 0xFE, 0x0A, 0x04, 0x40, 0x60, 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xD9, 0x60, 0x0C, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x7D, 0xF1, 0x13, 0x60, 0x1A, 0xF9, 0x0E, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x20, 0x60, 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xD9, 0x60,
+	 0x2D, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x64, 0x08, 0x60, 0x15, 0xFB,
+	 0x5A, 0xDB, 0xBE, 0xFE, 0x08, 0x60, 0x08, 0xF1, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xCF, 0xFE, 0x01, 0x64, 0x8A, 0xFB, 0xFF, 0x60, 0xDF, 0x65, 0x20, 0x44, 0x24, 0x80, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x06, 0x64, 0xDB, 0xFB, 0xF1, 0xF3, 0xFF, 0xFF, 0xFE, 0xB4, 0xF1, 0xFB, 0xE4, 0xF1,
+	 0x7D, 0xF9, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x01, 0x64, 0x8A, 0xFB, 0xFF, 0x60,
+	 0xDF, 0x65, 0x20, 0x44, 0x24, 0x80, 0xA6, 0xF1, 0x66, 0x45, 0x64, 0x46, 0x66, 0x43, 0x02, 0xA3,
+	 0x63, 0x46, 0x02, 0x64, 0x06, 0xFA, 0x04, 0x63, 0x04, 0x61, 0x01, 0x60, 0xCC, 0x64, 0x58, 0xD1,
+	 0x59, 0xD8, 0xFD, 0x1F, 0x65, 0x46, 0x01, 0x65, 0xF1, 0x60, 0x58, 0x4E, 0xC3, 0x78, 0xFF, 0xFF,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x64, 0x67, 0xFB, 0x68, 0xFB, 0xA6, 0xF1, 0x0E, 0x64, 0x66, 0x41,
+	 0x64, 0x42, 0x02, 0xA2, 0x62, 0x46, 0x06, 0xF0, 0xFF, 0x60, 0xFC, 0x64, 0xA0, 0x84, 0x06, 0xFA,
+	 0x61, 0x46, 0xDB, 0xF3, 0xFF, 0xFF, 0x04, 0xA8, 0x10, 0x60, 0x0E, 0x64, 0x07, 0x03, 0xA0, 0xD1,
+	 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x2A, 0x02, 0x00, 0x00, 0x63, 0xA0, 0xDD, 0x01, 0x64, 0xDB, 0xFB,
+	 0xF1, 0xF3, 0xFF, 0xFF, 0xFE, 0xB4, 0xF1, 0xFB, 0x00, 0x63, 0x08, 0x60, 0x77, 0xFD, 0x10, 0x60,
+	 0x4E, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x00, 0x64, 0x08, 0x60, 0x27, 0xFB, 0x5A, 0xDB, 0x10, 0x60,
+	 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x00, 0x60, 0x02, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xD3, 0x60,
+	 0x9C, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x15, 0xF1, 0x00, 0x60,
+	 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x2E, 0x58, 0xFF, 0xFF,
+	 0x40, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0xB9, 0xF1, 0x0E, 0x60, 0x4B, 0xF9, 0x5F, 0xF5, 0xEA, 0xF1,
+	 0x2F, 0xF8, 0xEB, 0xF1, 0x30, 0xF8, 0xEC, 0xF1, 0x31, 0xF8, 0xB9, 0xF1, 0x19, 0xF8, 0xF8, 0x60,
+	 0x80, 0x64, 0x0E, 0xFA, 0x00, 0x64, 0x3E, 0xFA, 0xA6, 0xF1, 0x07, 0xF8, 0x1B, 0x60, 0xB0, 0x64,
+	 0x00, 0x60, 0x67, 0xFB, 0x44, 0x60, 0x44, 0x64, 0x7F, 0xFB, 0x80, 0xFB, 0x81, 0xFB, 0x31, 0x44,
+	 0xF9, 0xB4, 0x40, 0x51, 0x00, 0x60, 0xCE, 0x63, 0x01, 0x60, 0x0C, 0x65, 0xA3, 0xD3, 0xA5, 0xD1,
+	 0x04, 0xA4, 0xA3, 0xDB, 0xD0, 0x80, 0xA0, 0xD1, 0x0A, 0x06, 0x41, 0x64, 0x3B, 0x42, 0x5A, 0xDB,
+	 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xD6, 0x60, 0x6A, 0x78, 0xFF, 0xFF, 0x44, 0x47,
+	 0x16, 0x60, 0xC2, 0xF3, 0xFF, 0xFF, 0xFF, 0xA4, 0xFF, 0xFF, 0x09, 0x07, 0x0E, 0x61, 0x41, 0xD3,
+	 0x32, 0x40, 0x08, 0x26, 0x04, 0x00, 0x10, 0xB0, 0xFF, 0xFF, 0x01, 0x03, 0xD3, 0x01, 0x42, 0x64,
+	 0x3B, 0x42, 0x5A, 0xDB, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE, 0x0A, 0x04,
+	 0x40, 0x60, 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xD9, 0x60, 0xFA, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x27, 0xD1, 0x7D, 0xF9, 0x13, 0x60, 0x1A, 0xF9, 0x0E, 0x64, 0x4A, 0xDB,
+	 0xFF, 0xFF, 0x2D, 0xFF, 0x20, 0x60, 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xDA, 0x60, 0x1C, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0xBE, 0xFE, 0x08, 0x60, 0x08, 0xF1, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x07, 0x60, 0xD0, 0x64, 0x0E, 0x60, 0x4B, 0xFB, 0x1C, 0x60, 0x92, 0x64, 0x13, 0x60, 0x22, 0xFB,
+	 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x27, 0x43, 0x06, 0xA3, 0xBD, 0xD3, 0x7F, 0xFB,
+	 0xBD, 0xD3, 0x80, 0xFB, 0xA3, 0xD3, 0x81, 0xFB, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0x01, 0x60, 0x04, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xDA, 0x60, 0x4A, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0xB9, 0xF1, 0x0E, 0x60, 0x4B, 0xF9, 0x08, 0x60, 0x15, 0xF1, 0xFE, 0x60,
+	 0xFF, 0x61, 0xA1, 0x84, 0x5A, 0xD1, 0x4A, 0xDB, 0xA1, 0x84, 0x5A, 0xDB, 0x08, 0x60, 0x15, 0xF1,
+	 0x00, 0x60, 0x04, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x05, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xD9, 0x60,
+	 0xCA, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x08, 0x65, 0x20, 0x44, 0x34, 0x80, 0x7D, 0xF1, 0x32, 0x60,
+	 0x7A, 0x61, 0xA1, 0xD3, 0x64, 0x40, 0x01, 0x27, 0x59, 0xD3, 0x32, 0x60, 0x7E, 0x61, 0xFD, 0x60,
+	 0x58, 0x4E, 0xAC, 0x78, 0xFF, 0xFF, 0xA1, 0xDB, 0x5E, 0xF5, 0xEA, 0xF1, 0x2F, 0xF8, 0xEB, 0xF1,
+	 0x30, 0xF8, 0xEC, 0xF1, 0x31, 0xF8, 0xB9, 0xF1, 0x19, 0xF8, 0x80, 0x7E, 0xF8, 0x7F, 0x0E, 0xFA,
+	 0x00, 0x64, 0x3E, 0xFA, 0xA6, 0xF1, 0x07, 0xF8, 0x2B, 0xFA, 0xB0, 0x64, 0x2A, 0xFA, 0x27, 0x43,
+	 0x06, 0xA3, 0xBD, 0xD1, 0x2C, 0xF8, 0x32, 0xF8, 0xBD, 0xD1, 0x2D, 0xF8, 0x33, 0xF8, 0xA3, 0xD1,
+	 0x2E, 0xF8, 0x34, 0xF8, 0x06, 0x63, 0x3F, 0xFC, 0x20, 0x60, 0x16, 0x61, 0xDB, 0xF3, 0xA1, 0xD3,
+	 0x03, 0xA8, 0xAC, 0x83, 0x0E, 0x02, 0x0D, 0x03, 0x20, 0x60, 0x18, 0x61, 0xA1, 0xD1, 0x66, 0x45,
+	 0x00, 0xF4, 0x09, 0xFC, 0x01, 0x64, 0x0A, 0xFA, 0x0B, 0xF8, 0x20, 0x60, 0x16, 0x61, 0xA1, 0xDF,
+	 0x25, 0x00, 0x16, 0x60, 0xC3, 0xF3, 0x66, 0x45, 0x00, 0xF4, 0x60, 0x40, 0x01, 0x36, 0x15, 0x00,
+	 0x02, 0x36, 0xBD, 0x00, 0x03, 0x36, 0x07, 0x00, 0x04, 0x36, 0x0F, 0x00, 0x05, 0x36, 0xB7, 0x00,
+	 0x06, 0x36, 0x01, 0x00, 0x0A, 0x00, 0x80, 0x64, 0x09, 0xFA, 0x01, 0x63, 0x0A, 0xFC, 0x00, 0x64,
+	 0x0B, 0xFA, 0x80, 0x60, 0xF4, 0x62, 0xA2, 0xDF, 0x09, 0x00, 0x00, 0x64, 0x09, 0xFA, 0x01, 0x63,
+	 0x0A, 0xFC, 0x00, 0x64, 0x0B, 0xFA, 0x80, 0x60, 0xF4, 0x62, 0xA2, 0xDF, 0x25, 0x60, 0xCE, 0x64,
+	 0x13, 0x60, 0x0D, 0xFB, 0x65, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0x00, 0x66, 0xDB, 0xF3, 0x46, 0x46, 0xFD, 0xA0, 0xC1, 0xFE, 0x02, 0x02, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x01, 0x64, 0x68, 0xFB, 0x43, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x0E, 0x60, 0x38, 0xF3, 0xFF, 0xFF,
+	 0x64, 0xA4, 0xA2, 0xDB, 0x0E, 0x60, 0x38, 0xF1, 0x0E, 0x60, 0x4B, 0xF9, 0x1C, 0x60, 0x92, 0x64,
+	 0x13, 0x60, 0x22, 0xFB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x00, 0x60, 0x0C, 0x64,
+	 0x08, 0x60, 0x16, 0xFB, 0xDB, 0x60, 0x00, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x08, 0x60, 0x15, 0xF1, 0x00, 0x60, 0x08, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x55, 0x03, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x1C, 0x60, 0x92, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x04, 0xFF, 0x00, 0x64, 0x68, 0xFB, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x26, 0x46,
+	 0x00, 0xF4, 0x09, 0xF2, 0x0A, 0xF2, 0x00, 0xA8, 0x0B, 0xF2, 0x02, 0xA8, 0x16, 0x02, 0x00, 0xA8,
+	 0x1A, 0x02, 0x19, 0x02, 0x26, 0x46, 0x26, 0x60, 0x1A, 0x64, 0x40, 0x4B, 0x34, 0x60, 0x58, 0x4D,
+	 0x08, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0x20, 0x40, 0x08, 0x2A, 0x03, 0x00, 0xDC, 0x60,
+	 0xF6, 0x78, 0xFF, 0xFF, 0xE3, 0x60, 0x69, 0x78, 0xFF, 0xFF, 0x09, 0xF2, 0x0A, 0xF2, 0x80, 0xA8,
+	 0x0B, 0xF2, 0x02, 0xA8, 0xE4, 0x03, 0x44, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x0B, 0xF2, 0x26, 0x46,
+	 0x40, 0x59, 0x02, 0x60, 0x00, 0x61, 0x2F, 0xF2, 0xA1, 0xDB, 0x30, 0xF2, 0x41, 0x58, 0x59, 0xDB,
+	 0x31, 0xF2, 0x59, 0xDB, 0x26, 0x46, 0x26, 0x60, 0x1A, 0x64, 0x40, 0x4B, 0x34, 0x60, 0x58, 0x4D,
+	 0x08, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0x03, 0x65, 0xF1, 0x60, 0x58, 0x4E, 0x96, 0x78,
+	 0xFF, 0xFF, 0xE7, 0x60, 0x0B, 0x78, 0xFF, 0xFF, 0xFF, 0x60, 0xFB, 0x64, 0xA0, 0x84, 0xA2, 0xDB,
+	 0x00, 0x64, 0x68, 0xFB, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x20, 0x40, 0x08, 0x2A,
+	 0x03, 0x00, 0xD9, 0x60, 0xCA, 0x78, 0xFF, 0xFF, 0xE2, 0x60, 0x73, 0x78, 0xFF, 0xFF, 0x01, 0x63,
+	 0x09, 0xFC, 0x32, 0x40, 0x08, 0x26, 0x14, 0x00, 0x16, 0x60, 0xC2, 0xF3, 0xFF, 0xFF, 0x60, 0x40,
+	 0x0B, 0x36, 0x03, 0x00, 0xDA, 0x60, 0xC5, 0x78, 0xFF, 0xFF, 0x01, 0x64, 0xA2, 0xDB, 0x0B, 0x64,
+	 0x19, 0x60, 0xA4, 0xFB, 0xA6, 0xF1, 0x66, 0x41, 0x64, 0x46, 0x22, 0x64, 0x3A, 0xFA, 0x61, 0x46,
+	 0x01, 0x64, 0x0A, 0xFA, 0x00, 0x64, 0x0B, 0xFA, 0x01, 0x64, 0x40, 0x60, 0x7A, 0xFB, 0x01, 0x64,
+	 0x68, 0xFB, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x25, 0x60, 0xCE, 0x64, 0x13, 0x60,
+	 0x0D, 0xFB, 0x65, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x00, 0x66,
+	 0xDB, 0xF3, 0x46, 0x46, 0xFD, 0xA0, 0xC1, 0xFE, 0x02, 0x02, 0x2F, 0x58, 0xFF, 0xFF, 0x1C, 0x60,
+	 0x92, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x00, 0x60,
+	 0x0C, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xDB, 0x60, 0xB9, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x08, 0x60, 0x15, 0xF1, 0x00, 0x60, 0x08, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x3A, 0x03,
+	 0xA0, 0x84, 0xA2, 0xDB, 0x1C, 0x60, 0x92, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB,
+	 0xFF, 0xFF, 0x04, 0xFF, 0x00, 0x64, 0x68, 0xFB, 0x26, 0x46, 0x00, 0xF4, 0x09, 0xF2, 0x0A, 0xF2,
+	 0x01, 0xA8, 0x0B, 0xF2, 0x02, 0xA8, 0x04, 0x02, 0x00, 0xA8, 0x02, 0x02, 0x01, 0x02, 0x31, 0x00,
+	 0xDC, 0x60, 0x58, 0x4D, 0xB9, 0x78, 0xFF, 0xFF, 0x0B, 0xF2, 0x26, 0x46, 0x40, 0x59, 0x02, 0x60,
+	 0x00, 0x61, 0x2F, 0xF2, 0xA1, 0xDB, 0x30, 0xF2, 0x41, 0x58, 0x59, 0xDB, 0x31, 0xF2, 0x59, 0xDB,
+	 0x26, 0x46, 0x26, 0x60, 0x1A, 0x64, 0x40, 0x4B, 0x34, 0x60, 0x58, 0x4D, 0x08, 0x78, 0xFF, 0xFF,
+	 0x00, 0x66, 0x46, 0x46, 0x03, 0x65, 0xF1, 0x60, 0x58, 0x4E, 0x96, 0x78, 0xFF, 0xFF, 0xE7, 0x60,
+	 0x0B, 0x78, 0xFF, 0xFF, 0xDC, 0x60, 0x58, 0x4D, 0xB9, 0x78, 0xFF, 0xFF, 0x00, 0x64, 0x68, 0xFB,
+	 0x20, 0x40, 0x08, 0x2A, 0x03, 0x00, 0xD9, 0x60, 0xCA, 0x78, 0xFF, 0xFF, 0xE2, 0x60, 0x73, 0x78,
+	 0xFF, 0xFF, 0x26, 0x46, 0x40, 0x60, 0x00, 0x65, 0x2A, 0xF2, 0x2F, 0xF0, 0xB4, 0x84, 0x2A, 0xFA,
+	 0x2C, 0xF8, 0x32, 0xF8, 0x30, 0xF2, 0x2D, 0xFA, 0x33, 0xFA, 0x31, 0xF2, 0x2E, 0xFA, 0x34, 0xFA,
+	 0xEA, 0xF3, 0x2F, 0xFA, 0xEB, 0xF3, 0x30, 0xFA, 0xEC, 0xF3, 0x31, 0xFA, 0xC9, 0xF1, 0x19, 0xF8,
+	 0x1C, 0xF0, 0x13, 0xF8, 0x00, 0x64, 0x3E, 0xFA, 0x00, 0xF4, 0x03, 0x64, 0x0A, 0xFA, 0x00, 0x64,
+	 0x0B, 0xFA, 0x01, 0x63, 0x68, 0xFD, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x25, 0x60,
+	 0xCE, 0x64, 0x13, 0x60, 0x0D, 0xFB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0x00, 0x66, 0xDB, 0xF3, 0x46, 0x46, 0xFD, 0xA0, 0xC1, 0xFE, 0x02, 0x02, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x1C, 0x60, 0x92, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x04, 0xFF, 0x00, 0x60, 0x0C, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xDC, 0x60, 0x53, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x15, 0xF1, 0x00, 0x60, 0x08, 0x64, 0xA0, 0x80,
+	 0x9C, 0x84, 0x50, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x1C, 0x60, 0x92, 0x64, 0x13, 0x60, 0x22, 0xFB,
+	 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x00, 0x64, 0x68, 0xFB, 0x26, 0x46, 0x00, 0xF4,
+	 0x09, 0xF2, 0x0A, 0xF2, 0x01, 0xA8, 0x0B, 0xF2, 0x04, 0xA8, 0x1A, 0x02, 0x00, 0xA8, 0x18, 0x02,
+	 0x17, 0x02, 0xDC, 0x60, 0x58, 0x4D, 0xB9, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x26, 0x60, 0x1A, 0x64,
+	 0x40, 0x4B, 0x34, 0x60, 0x58, 0x4D, 0x08, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0x20, 0x40,
+	 0x08, 0x2A, 0x03, 0x00, 0xDC, 0x60, 0xF6, 0x78, 0xFF, 0xFF, 0xE3, 0x60, 0x69, 0x78, 0xFF, 0xFF,
+	 0xDC, 0x60, 0x58, 0x4D, 0xB9, 0x78, 0xFF, 0xFF, 0x0B, 0xF2, 0x26, 0x46, 0x40, 0x59, 0x02, 0x60,
+	 0x00, 0x61, 0x2F, 0xF2, 0xA1, 0xDB, 0x30, 0xF2, 0x41, 0x58, 0x59, 0xDB, 0x31, 0xF2, 0x59, 0xDB,
+	 0x26, 0x46, 0x26, 0x60, 0x1A, 0x64, 0x40, 0x4B, 0x34, 0x60, 0x58, 0x4D, 0x08, 0x78, 0xFF, 0xFF,
+	 0x00, 0x66, 0x46, 0x46, 0x03, 0x65, 0xF1, 0x60, 0x58, 0x4E, 0x96, 0x78, 0xFF, 0xFF, 0xE7, 0x60,
+	 0x0B, 0x78, 0xFF, 0xFF, 0xDC, 0x60, 0x58, 0x4D, 0xB9, 0x78, 0xFF, 0xFF, 0x00, 0x64, 0x68, 0xFB,
+	 0x20, 0x40, 0x08, 0x2A, 0x03, 0x00, 0xD9, 0x60, 0xCA, 0x78, 0xFF, 0xFF, 0xE2, 0x60, 0x73, 0x78,
+	 0xFF, 0xFF, 0x19, 0x60, 0xA4, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x0B, 0x3A, 0x06, 0x00, 0x0B, 0x64,
+	 0x16, 0x60, 0xC2, 0xFB, 0x33, 0x60, 0x48, 0x62, 0xA2, 0xDF, 0x2D, 0x58, 0xFF, 0xFF, 0x16, 0x60,
+	 0xC2, 0xF1, 0xA5, 0xD2, 0x64, 0x40, 0x0B, 0x2A, 0x20, 0x00, 0x85, 0x36, 0x0B, 0x00, 0x32, 0x3A,
+	 0x1E, 0x00, 0x60, 0x47, 0xFF, 0xB4, 0x02, 0xA4, 0xC4, 0x85, 0xA5, 0xD2, 0xFF, 0xFF, 0x60, 0x40,
+	 0x85, 0x3A, 0x15, 0x00, 0x65, 0x44, 0x0A, 0xA4, 0xA0, 0xD0, 0x33, 0x60, 0x46, 0x62, 0x64, 0x40,
+	 0x18, 0x26, 0x09, 0x00, 0xA2, 0xDF, 0x01, 0x64, 0x16, 0x60, 0xC2, 0xFB, 0x32, 0x41, 0x08, 0x65,
+	 0xB5, 0x81, 0x41, 0x52, 0x02, 0x00, 0x01, 0x64, 0xA2, 0xDB, 0x2D, 0x58, 0xFF, 0xFF, 0x33, 0x60,
+	 0x46, 0x62, 0xA2, 0xDF, 0x01, 0x64, 0x16, 0x60, 0xC2, 0xFB, 0xF7, 0x01, 0x45, 0x64, 0x3B, 0x42,
+	 0x5A, 0xDB, 0x35, 0x60, 0xAA, 0x7C, 0x35, 0x60, 0x98, 0x63, 0xA3, 0xD9, 0x64, 0x41, 0x2F, 0x60,
+	 0x02, 0x63, 0xBD, 0xD3, 0x00, 0x7C, 0x03, 0x1B, 0x27, 0x43, 0x10, 0xA3, 0xBD, 0xD3, 0xFF, 0xFF,
+	 0x60, 0x45, 0x64, 0x5F, 0xA1, 0xDB, 0x65, 0x44, 0xBD, 0xD1, 0xC8, 0x84, 0x59, 0xD8, 0xFC, 0x05,
+	 0x27, 0x41, 0x10, 0xA1, 0xA1, 0xD1, 0xFF, 0xFF, 0xC1, 0x81, 0x01, 0x26, 0xDD, 0x81, 0x41, 0x4C,
+	 0x59, 0xD1, 0x7C, 0x44, 0xB0, 0x84, 0x59, 0xD1, 0x59, 0xD1, 0xB0, 0x84, 0xB0, 0x84, 0xFF, 0xFF,
+	 0x02, 0x02, 0x67, 0x44, 0xC2, 0x00, 0x34, 0x60, 0x5C, 0x63, 0xD9, 0x81, 0x59, 0xD3, 0x38, 0x60,
+	 0x10, 0x62, 0x00, 0xBC, 0xA2, 0xDF, 0x09, 0x03, 0x01, 0x7C, 0xA2, 0xD9, 0x30, 0x60, 0x14, 0x64,
+	 0xBD, 0xDA, 0x00, 0x60, 0x01, 0x64, 0xBD, 0xDA, 0x58, 0x00, 0xDD, 0x60, 0x18, 0x64, 0xBD, 0xDA,
+	 0x50, 0x60, 0x00, 0x64, 0xBD, 0xDA, 0x01, 0x60, 0xF2, 0x64, 0xBD, 0xDA, 0x00, 0x60, 0x01, 0x64,
+	 0xBD, 0xDA, 0x2C, 0x41, 0x59, 0xD3, 0x50, 0x60, 0x00, 0x7C, 0x60, 0x40, 0x02, 0x2A, 0x03, 0x00,
+	 0x01, 0x60, 0xF2, 0x64, 0x0E, 0x00, 0x04, 0x2A, 0x03, 0x00, 0x02, 0x60, 0xF2, 0x64, 0x09, 0x00,
+	 0x10, 0x2A, 0x03, 0x00, 0x04, 0x60, 0xF2, 0x64, 0x04, 0x00, 0x20, 0x2A, 0x04, 0x00, 0x05, 0x60,
+	 0xF2, 0x64, 0xBD, 0xD9, 0xBD, 0xDB, 0x01, 0x64, 0xBD, 0xDB, 0x59, 0xD3, 0x50, 0x60, 0x00, 0x7C,
+	 0x60, 0x40, 0x02, 0x2A, 0x03, 0x00, 0x01, 0x60, 0xF2, 0x64, 0x0E, 0x00, 0x04, 0x2A, 0x03, 0x00,
+	 0x02, 0x60, 0xF2, 0x64, 0x09, 0x00, 0x10, 0x2A, 0x03, 0x00, 0x04, 0x60, 0xF2, 0x64, 0x04, 0x00,
+	 0x20, 0x2A, 0x04, 0x00, 0x05, 0x60, 0xF2, 0x64, 0xBD, 0xD9, 0xBD, 0xDB, 0x01, 0x64, 0xBD, 0xDB,
+	 0x59, 0xD3, 0x50, 0x60, 0x00, 0x7C, 0x60, 0x40, 0x01, 0x2A, 0x03, 0x00, 0x00, 0x60, 0xF2, 0x64,
+	 0x09, 0x00, 0x02, 0x2A, 0x03, 0x00, 0x01, 0x60, 0xF2, 0x64, 0x04, 0x00, 0x04, 0x2A, 0x02, 0x00,
+	 0x02, 0x60, 0xF2, 0x64, 0xBD, 0xD9, 0xBD, 0xDB, 0x4B, 0x00, 0x2C, 0x41, 0x59, 0xD3, 0x0F, 0x60,
+	 0x00, 0x7C, 0x60, 0x40, 0x02, 0x2A, 0x03, 0x00, 0x01, 0x60, 0xAC, 0x64, 0x0E, 0x00, 0x04, 0x2A,
+	 0x03, 0x00, 0x02, 0x60, 0xAC, 0x64, 0x09, 0x00, 0x10, 0x2A, 0x03, 0x00, 0x04, 0x60, 0xAC, 0x64,
+	 0x04, 0x00, 0x20, 0x2A, 0x04, 0x00, 0x05, 0x60, 0xAC, 0x64, 0xBD, 0xD9, 0xBD, 0xDB, 0x01, 0x64,
+	 0xBD, 0xDB, 0x59, 0xD3, 0x0F, 0x60, 0x00, 0x7C, 0x60, 0x40, 0x02, 0x2A, 0x03, 0x00, 0x01, 0x60,
+	 0xAC, 0x64, 0x0E, 0x00, 0x04, 0x2A, 0x03, 0x00, 0x02, 0x60, 0xAC, 0x64, 0x09, 0x00, 0x10, 0x2A,
+	 0x03, 0x00, 0x04, 0x60, 0xAC, 0x64, 0x04, 0x00, 0x20, 0x2A, 0x04, 0x00, 0x05, 0x60, 0xAC, 0x64,
+	 0xBD, 0xD9, 0xBD, 0xDB, 0x01, 0x64, 0xBD, 0xDB, 0x59, 0xD3, 0x0F, 0x60, 0x00, 0x7C, 0x60, 0x40,
+	 0x01, 0x2A, 0x03, 0x00, 0x00, 0x60, 0xAC, 0x64, 0x09, 0x00, 0x02, 0x2A, 0x03, 0x00, 0x01, 0x60,
+	 0xAC, 0x64, 0x04, 0x00, 0x04, 0x2A, 0x02, 0x00, 0x02, 0x60, 0xAC, 0x64, 0xBD, 0xD9, 0xBD, 0xDB,
+	 0x1C, 0x60, 0x08, 0xF3, 0xFF, 0xFF, 0x03, 0x18, 0x1A, 0x60, 0x2D, 0xF3, 0x03, 0x00, 0x1A, 0x60,
+	 0x1D, 0xF3, 0xFF, 0xFF, 0xBD, 0xDA, 0x34, 0x60, 0x5C, 0x64, 0x1A, 0x60, 0xCF, 0xFB, 0x5F, 0xF5,
+	 0x00, 0x64, 0x2B, 0xFA, 0x00, 0x64, 0x2A, 0xFA, 0x27, 0x43, 0x06, 0xA3, 0xBD, 0xD1, 0x2C, 0xF8,
+	 0x32, 0xF8, 0xBD, 0xD1, 0x2D, 0xF8, 0x33, 0xF8, 0xA3, 0xD1, 0x2E, 0xF8, 0x34, 0xF8, 0x00, 0xF4,
+	 0x01, 0x63, 0x32, 0x40, 0x08, 0x26, 0x10, 0xBB, 0x16, 0x60, 0xC2, 0xF1, 0xFF, 0xFF, 0x64, 0x40,
+	 0xFE, 0x26, 0x10, 0xBB, 0x7D, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x27, 0x0A, 0x00, 0x19, 0x60,
+	 0x45, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x02, 0x22, 0x20, 0xBB, 0x63, 0x44, 0xFF, 0xFF, 0x04, 0x7F,
+	 0x60, 0x43, 0x09, 0xFC, 0x27, 0x42, 0x0C, 0xA2, 0x2D, 0x60, 0x5A, 0x63, 0xA2, 0xD3, 0xA3, 0xD3,
+	 0x00, 0xBD, 0x01, 0x63, 0xAC, 0x81, 0x09, 0x03, 0x08, 0x03, 0xB8, 0x60, 0x58, 0x4D, 0x15, 0x78,
+	 0xFF, 0xFF, 0x00, 0xB8, 0x01, 0x63, 0x01, 0x03, 0x60, 0x43, 0x0E, 0x60, 0x35, 0xFD, 0x12, 0x61,
+	 0x59, 0xDC, 0x16, 0x60, 0xC2, 0xF3, 0xFF, 0x60, 0xFF, 0x7C, 0x60, 0x40, 0x0B, 0x2A, 0x02, 0x00,
+	 0x33, 0x60, 0x28, 0x7C, 0x1A, 0x60, 0xD0, 0xF9, 0x35, 0x60, 0x98, 0x64, 0x40, 0x48, 0xD9, 0x81,
+	 0xFF, 0x60, 0xF2, 0x64, 0xF1, 0x60, 0x58, 0x4D, 0x34, 0x78, 0xFF, 0xFF, 0x5F, 0xF5, 0x3F, 0xFC,
+	 0xDB, 0x83, 0x1A, 0x60, 0x4C, 0xFD, 0x00, 0x7C, 0x5A, 0xD9, 0x63, 0x41, 0x34, 0x60, 0x9C, 0x63,
+	 0x12, 0x65, 0x00, 0xF4, 0xCD, 0x84, 0x4C, 0x91, 0x60, 0x43, 0x60, 0xFE, 0xA5, 0xD2, 0xDE, 0x85,
+	 0x7F, 0x26, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0x5D, 0x93, 0xA3, 0xDB, 0x5D, 0x93, 0xA5, 0xD2,
+	 0xF6, 0x1F, 0x5D, 0x93, 0x20, 0xFE, 0xDF, 0x83, 0x5F, 0xF5, 0x25, 0x60, 0xCE, 0x64, 0x13, 0x60,
+	 0x0D, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x00, 0x66,
+	 0x46, 0x46, 0xC1, 0xFE, 0x06, 0x64, 0x68, 0xFB, 0x46, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x1C, 0x60,
+	 0x92, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x00, 0x60,
+	 0x1C, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xDE, 0x60, 0x84, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0xDE, 0x60, 0xCA, 0x78, 0xFF, 0xFF, 0x08, 0x60, 0x15, 0xF1, 0x00, 0x60, 0x08, 0x64,
+	 0xA0, 0x80, 0x9C, 0x84, 0xF6, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x1C, 0x60, 0x92, 0x64, 0x13, 0x60,
+	 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0x26, 0x46, 0x00, 0xF4, 0x0A, 0xF2, 0x00, 0x63, 0x00, 0xA8, 0x68, 0xFD, 0x06, 0x02,
+	 0x09, 0xF2, 0xFF, 0xFF, 0x01, 0xB0, 0x01, 0x7C, 0x5A, 0x02, 0x0A, 0xF8, 0x0A, 0xF2, 0x26, 0x46,
+	 0x40, 0x59, 0x02, 0x60, 0x00, 0x61, 0x2F, 0xF2, 0xA1, 0xDB, 0x30, 0xF2, 0x41, 0x58, 0x59, 0xDB,
+	 0x31, 0xF2, 0x59, 0xDB, 0x26, 0x46, 0x26, 0x60, 0x1A, 0x64, 0x40, 0x4B, 0x34, 0x60, 0x58, 0x4D,
+	 0x08, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0x05, 0x65, 0xF1, 0x60, 0x58, 0x4E, 0x96, 0x78,
+	 0xFF, 0xFF, 0xE7, 0x60, 0x0B, 0x78, 0xFF, 0xFF, 0x47, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0xD9, 0x60,
+	 0xCA, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x10, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x20, 0x03, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x1C, 0x60, 0x92, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x04, 0xFF, 0x26, 0x46, 0x26, 0x60, 0x1A, 0x64, 0x40, 0x4B, 0x34, 0x60, 0x58, 0x4D, 0x08, 0x78,
+	 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0x00, 0x64, 0x68, 0xFB, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0x49, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0xDA, 0x60, 0x62, 0x78, 0xFF, 0xFF, 0xFF, 0x60,
+	 0xFB, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x00, 0x64, 0x68, 0xFB, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0x4A, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0xD9, 0x60, 0xCA, 0x78, 0xFF, 0xFF, 0x48, 0x64,
+	 0x3B, 0x42, 0x5A, 0xDB, 0x0C, 0xF2, 0xFF, 0xFF, 0x60, 0x41, 0xFF, 0xB1, 0xFF, 0xA1, 0x60, 0x47,
+	 0xFF, 0xB4, 0x9B, 0x02, 0x9A, 0x03, 0x34, 0x60, 0xF4, 0x63, 0x10, 0x64, 0xBD, 0xDB, 0x66, 0x45,
+	 0x26, 0x46, 0x3F, 0xF2, 0x34, 0x60, 0xF2, 0x61, 0xC2, 0xA0, 0xFF, 0xFF, 0x01, 0x04, 0x3E, 0x64,
+	 0x65, 0x46, 0x02, 0xA4, 0xA1, 0xDB, 0xC8, 0x81, 0x12, 0x65, 0xCD, 0x84, 0x4C, 0x91, 0x60, 0x43,
+	 0x60, 0xFE, 0xA5, 0xD2, 0xDE, 0x85, 0x7F, 0x26, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0x5D, 0x93,
+	 0xA3, 0xDB, 0x5D, 0x93, 0xA5, 0xD2, 0xF6, 0x1F, 0x5D, 0x93, 0x20, 0xFE, 0xDF, 0x83, 0x0C, 0xF2,
+	 0xFF, 0xFF, 0x1A, 0x65, 0x60, 0x47, 0xFF, 0xB4, 0xC4, 0x85, 0xDC, 0x60, 0x58, 0x4D, 0xC7, 0x78,
+	 0xFF, 0xFF, 0x0B, 0xF2, 0xFF, 0xFF, 0x07, 0xB4, 0x01, 0x61, 0x03, 0x03, 0xCC, 0x84, 0xE1, 0x81,
+	 0xFD, 0x02, 0x61, 0x44, 0x94, 0xFB, 0x27, 0x45, 0x02, 0x62, 0x46, 0xD3, 0x5A, 0xD1, 0x60, 0x47,
+	 0x56, 0xFB, 0x64, 0x47, 0x55, 0xFB, 0x00, 0x64, 0x5B, 0xFB, 0x0C, 0x62, 0x46, 0xD3, 0x7E, 0xFB,
+	 0x0B, 0xF0, 0x0F, 0x60, 0xFF, 0x64, 0xA0, 0x84, 0x83, 0xFB, 0x26, 0x46, 0x32, 0xF0, 0x7F, 0xF9,
+	 0x33, 0xF0, 0x0E, 0x63, 0xC7, 0x81, 0x80, 0xF9, 0x34, 0xF0, 0x81, 0xF9, 0x59, 0xD1, 0xFF, 0xFF,
+	 0x64, 0x44, 0x01, 0x2A, 0xC8, 0x84, 0x60, 0x43, 0x33, 0x60, 0xBC, 0x64, 0x58, 0xD9, 0x59, 0xD1,
+	 0x58, 0xD9, 0xFD, 0x1F, 0x16, 0x60, 0xC2, 0xF1, 0x59, 0xD3, 0x64, 0x40, 0x01, 0x36, 0x22, 0x64,
+	 0x64, 0x40, 0x00, 0x36, 0x50, 0x94, 0xA6, 0xF1, 0xFF, 0xFF, 0x44, 0x47, 0xA7, 0x46, 0x3A, 0xFA,
+	 0xBB, 0xFC, 0xA7, 0x46, 0x0E, 0x60, 0x35, 0xF3, 0x85, 0xFB, 0x2E, 0x60, 0x2E, 0x64, 0x2D, 0x60,
+	 0x8A, 0x63, 0xA0, 0xD1, 0xA3, 0xD9, 0x64, 0x41, 0x58, 0xD1, 0x5B, 0xD9, 0x7D, 0xF3, 0x66, 0x45,
+	 0xA6, 0xF5, 0x60, 0x40, 0x01, 0x27, 0x08, 0x00, 0x91, 0xFA, 0x61, 0x44, 0xFD, 0x60, 0x58, 0x4E,
+	 0xAC, 0x78, 0xFF, 0xFF, 0x12, 0xFA, 0x07, 0x00, 0x11, 0xF8, 0x64, 0x44, 0xFD, 0x60, 0x58, 0x4E,
+	 0xAC, 0x78, 0xFF, 0xFF, 0x12, 0xFA, 0x65, 0x46, 0x31, 0xF2, 0x1D, 0x60, 0xC0, 0x65, 0x60, 0x47,
+	 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18,
+	 0x61, 0x46, 0x31, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46, 0x30, 0xF0,
+	 0x63, 0x46, 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46, 0x2F, 0xF0, 0x63, 0x46, 0xD0, 0x80,
+	 0xFF, 0xFF, 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46, 0xE8, 0x1B, 0xA6, 0xF3, 0x08, 0xFE,
+	 0x60, 0x43, 0x61, 0x46, 0xA6, 0xF1, 0xFF, 0xFF, 0xD3, 0x80, 0x31, 0xF2, 0x27, 0x02, 0x66, 0x41,
+	 0x1D, 0x60, 0xC0, 0x65, 0x60, 0x47, 0x00, 0x7F, 0xA6, 0xF1, 0xE0, 0x84, 0x44, 0xD3, 0x64, 0x43,
+	 0x11, 0x18, 0x60, 0x46, 0x00, 0xF2, 0xFF, 0xFF, 0xFC, 0x1B, 0x66, 0x44, 0x64, 0x46, 0x80, 0xF0,
+	 0x60, 0x46, 0x80, 0xF8, 0x65, 0x46, 0x65, 0x43, 0x80, 0xF0, 0x01, 0xFA, 0x80, 0xFC, 0x64, 0x46,
+	 0x80, 0xF8, 0x0B, 0x00, 0x64, 0x46, 0x62, 0x43, 0x00, 0xF2, 0xA3, 0xDB, 0x60, 0x46, 0x80, 0xF0,
+	 0x81, 0xFC, 0x80, 0xFC, 0x64, 0x46, 0x80, 0xF8, 0x60, 0x43, 0x61, 0x46, 0x43, 0x4B, 0x01, 0x65,
+	 0xFD, 0x60, 0x58, 0x4E, 0xDD, 0x78, 0xFF, 0xFF, 0x43, 0x47, 0x3F, 0xF2, 0x00, 0xF4, 0x60, 0x43,
+	 0xFA, 0xA3, 0x00, 0x60, 0x17, 0x61, 0x00, 0x60, 0x01, 0x65, 0x01, 0x60, 0xFF, 0x64, 0x40, 0x4C,
+	 0xFD, 0x60, 0x58, 0x4E, 0x7A, 0x78, 0xFF, 0xFF, 0x00, 0xBB, 0xFF, 0xFF, 0x00, 0x02, 0x00, 0x64,
+	 0x40, 0x4A, 0x60, 0xFE, 0x02, 0x60, 0x00, 0x63, 0xBD, 0xD3, 0xBD, 0xD3, 0x60, 0x41, 0xFE, 0x60,
+	 0x58, 0x4E, 0x2C, 0x78, 0xFF, 0xFF, 0x20, 0xFE, 0x00, 0x65, 0x00, 0x64, 0x19, 0x60, 0x3B, 0xFB,
+	 0x02, 0x00, 0x20, 0xFE, 0xFF, 0x65, 0x02, 0x60, 0x00, 0x63, 0x60, 0xFE, 0xBD, 0xD3, 0xBD, 0xD3,
+	 0x60, 0x41, 0x20, 0xFE, 0xCD, 0x81, 0x60, 0x40, 0x80, 0x2A, 0x39, 0x00, 0x7F, 0xB4, 0x02, 0x3A,
+	 0x02, 0x00, 0x01, 0x64, 0x2E, 0x00, 0x04, 0x3A, 0x02, 0x00, 0x02, 0x64, 0x2A, 0x00, 0x0B, 0x3A,
+	 0x02, 0x00, 0x04, 0x64, 0x26, 0x00, 0x16, 0x3A, 0x02, 0x00, 0x08, 0x64, 0x22, 0x00, 0x0C, 0x3A,
+	 0x02, 0x00, 0x10, 0x64, 0x1E, 0x00, 0x12, 0x3A, 0x02, 0x00, 0x20, 0x64, 0x1A, 0x00, 0x18, 0x3A,
+	 0x02, 0x00, 0x40, 0x64, 0x16, 0x00, 0x24, 0x3A, 0x02, 0x00, 0x80, 0x64, 0x12, 0x00, 0x30, 0x3A,
+	 0x02, 0x00, 0x01, 0x67, 0x0E, 0x00, 0x48, 0x3A, 0x02, 0x00, 0x02, 0x67, 0x0A, 0x00, 0x60, 0x3A,
+	 0x02, 0x00, 0x04, 0x67, 0x06, 0x00, 0x6C, 0x3A, 0x02, 0x00, 0x08, 0x67, 0x02, 0x00, 0x00, 0x64,
+	 0x00, 0x00, 0x19, 0x60, 0x3B, 0xF1, 0xFF, 0xFF, 0xB0, 0x84, 0x19, 0x60, 0x3B, 0xFB, 0x61, 0x40,
+	 0x00, 0x36, 0x05, 0x00, 0x60, 0xFE, 0xBD, 0xD3, 0xFF, 0xFF, 0x20, 0xFE, 0xBB, 0x01, 0x65, 0x40,
+	 0x00, 0x3A, 0x1E, 0x00, 0x26, 0x46, 0x3F, 0xF2, 0x00, 0xF4, 0x60, 0x43, 0xFA, 0xA3, 0x00, 0x60,
+	 0x17, 0x61, 0x00, 0x60, 0x32, 0x65, 0x01, 0x60, 0xFF, 0x64, 0x40, 0x4C, 0xFD, 0x60, 0x58, 0x4E,
+	 0x7A, 0x78, 0xFF, 0xFF, 0x00, 0xBB, 0xFF, 0xFF, 0x0B, 0x03, 0x60, 0xFE, 0x02, 0x60, 0x00, 0x63,
+	 0xBD, 0xD3, 0xBD, 0xD3, 0x60, 0x41, 0xFE, 0x60, 0x58, 0x4E, 0x2C, 0x78, 0xFF, 0xFF, 0x91, 0x01,
+	 0x20, 0xFE, 0x00, 0x65, 0xFC, 0x60, 0x58, 0x4E, 0xC7, 0x78, 0xFF, 0xFF, 0xA1, 0xF3, 0xFF, 0xFF,
+	 0x60, 0x40, 0x01, 0x27, 0x04, 0x00, 0xFD, 0x60, 0x58, 0x4E, 0x11, 0x78, 0xFF, 0xFF, 0x20, 0xFE,
+	 0x37, 0x60, 0xF8, 0x61, 0xA1, 0xD1, 0xA1, 0xF3, 0x01, 0x60, 0xAC, 0x63, 0x60, 0x45, 0x2A, 0x44,
+	 0x79, 0xFB, 0xA3, 0xD5, 0x65, 0x40, 0x01, 0x27, 0x5B, 0xD5, 0x65, 0x40, 0x01, 0x27, 0x59, 0xD1,
+	 0x66, 0x41, 0xA0, 0x84, 0x24, 0x94, 0x2B, 0x46, 0x0F, 0xFA, 0x7A, 0xFB, 0x16, 0x64, 0x12, 0xFA,
+	 0x01, 0x64, 0x11, 0xFA, 0x66, 0x5C, 0xC2, 0x60, 0x58, 0x4E, 0x6D, 0x78, 0xFF, 0xFF, 0x1A, 0x60,
+	 0x22, 0xF3, 0x1A, 0x60, 0x21, 0xF1, 0x60, 0x47, 0xB0, 0x84, 0x1C, 0x60, 0x08, 0xF1, 0xFF, 0xFF,
+	 0x01, 0x18, 0x80, 0xBC, 0x16, 0x60, 0xC2, 0xF1, 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x36, 0x22, 0x64,
+	 0x64, 0x40, 0x00, 0x36, 0x50, 0x94, 0xA7, 0x46, 0x3A, 0xFA, 0xBB, 0xFC, 0xA7, 0x46, 0x80, 0x60,
+	 0x03, 0x65, 0x32, 0x40, 0x08, 0x2A, 0x03, 0x65, 0xA7, 0x46, 0x06, 0xF0, 0x7F, 0x60, 0xFF, 0x64,
+	 0xA0, 0x84, 0xB4, 0x84, 0x06, 0xFA, 0xBB, 0xFC, 0xA7, 0x46, 0x26, 0x46, 0x2F, 0xF0, 0x30, 0xF0,
+	 0x64, 0x43, 0x31, 0xF2, 0x27, 0x46, 0x03, 0xFC, 0x04, 0xF8, 0x05, 0xFA, 0x26, 0x46, 0xD9, 0x60,
+	 0x58, 0x4E, 0xAE, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x26, 0x60, 0x1A, 0x64, 0x40, 0x4B, 0x34, 0x60,
+	 0x58, 0x4D, 0x08, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0x01, 0x64, 0x8A, 0xFB, 0x16, 0x60,
+	 0xC9, 0xF3, 0x20, 0x41, 0x00, 0xBC, 0x20, 0xB9, 0x01, 0x03, 0x41, 0x40, 0x20, 0x60, 0x14, 0x61,
+	 0xA1, 0xDF, 0x04, 0x64, 0xC1, 0xFE, 0xDB, 0xFB, 0xF1, 0xF3, 0xFF, 0xFF, 0xFE, 0xB4, 0xF1, 0xFB,
+	 0xF7, 0x60, 0xFF, 0x65, 0x20, 0x44, 0x24, 0x80, 0x08, 0x60, 0x08, 0xF1, 0x80, 0x60, 0x00, 0x64,
+	 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x01, 0x65, 0xF1, 0x60, 0x58, 0x4E, 0xC3, 0x78, 0xFF, 0xFF,
+	 0x33, 0x60, 0xE6, 0x65, 0xA5, 0xDF, 0x08, 0x60, 0x0C, 0xF1, 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x0C, 0x64, 0x68, 0xFB, 0x00, 0x60, 0x31, 0x64, 0x08, 0x60, 0x16, 0xFB,
+	 0xE1, 0x60, 0x36, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x00, 0x60, 0x02, 0x64, 0x08, 0x60, 0x28, 0xFB,
+	 0xE1, 0x60, 0xF7, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x64, 0x08, 0x60,
+	 0x27, 0xFB, 0x5A, 0xDB, 0x08, 0x60, 0x15, 0xF1, 0x00, 0x60, 0x01, 0x64, 0xA0, 0x80, 0x9C, 0x84,
+	 0x0F, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x1B, 0x60, 0xFE, 0xF3, 0xFF, 0xFF, 0x03, 0x1B, 0xE7, 0x60,
+	 0x2E, 0x78, 0xFF, 0xFF, 0xE7, 0x60, 0x2E, 0x78, 0xFF, 0xFF, 0xE1, 0x60, 0xE7, 0x78, 0xFF, 0xFF,
+	 0x00, 0x60, 0x10, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0xF8, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xA6, 0xF3,
+	 0xFF, 0xFF, 0x02, 0xA4, 0x60, 0x43, 0x66, 0x41, 0x63, 0x46, 0x05, 0xF2, 0x00, 0xF0, 0x81, 0xF0,
+	 0x02, 0x18, 0x64, 0x46, 0x81, 0xF8, 0x07, 0x1B, 0x1D, 0x60, 0xC0, 0x65, 0x60, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD9, 0x02, 0x00, 0x65, 0x46, 0x00, 0xF8, 0xA6, 0xF3, 0x63, 0x45, 0x60, 0x46,
+	 0x00, 0xF2, 0xFF, 0xFF, 0xD4, 0x80, 0x01, 0x18, 0xFA, 0x04, 0x80, 0xF8, 0x65, 0x46, 0x00, 0xFA,
+	 0x06, 0xF2, 0xFF, 0xFF, 0x00, 0x7E, 0x06, 0xFA, 0x61, 0x46, 0x4B, 0x64, 0x3B, 0x42, 0x5A, 0xDB,
+	 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x00, 0x60, 0x95, 0xF3, 0xFF, 0xFF, 0x10, 0xB0,
+	 0xFF, 0xFF, 0x11, 0x03, 0x04, 0x60, 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xE1, 0x60, 0x9B, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x08, 0x60, 0x1B, 0xF1, 0x01, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x69, 0xF3, 0xFF, 0xFF, 0x01, 0xB0, 0xFF, 0xFF, 0x11, 0x03,
+	 0x08, 0x60, 0x0C, 0xF1, 0x00, 0x60, 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x02, 0x60,
+	 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xE1, 0x60, 0xB1, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x00, 0x64, 0x68, 0xFB, 0xE2, 0x60,
+	 0x58, 0x4E, 0x13, 0x78, 0xFF, 0xFF, 0x02, 0x64, 0x8A, 0xFB, 0x02, 0x64, 0xC1, 0xFE, 0xDB, 0xFB,
+	 0xF1, 0xF3, 0xFF, 0xFF, 0x01, 0xBC, 0xF1, 0xFB, 0x02, 0x65, 0xF1, 0x60, 0x58, 0x4E, 0xC3, 0x78,
+	 0xFF, 0xFF, 0x03, 0x60, 0xE8, 0x63, 0x0E, 0x60, 0x36, 0xFD, 0x08, 0x60, 0x77, 0xF3, 0xFF, 0xFF,
+	 0x13, 0x1B, 0x16, 0x60, 0xCC, 0xF3, 0x00, 0x61, 0x60, 0x40, 0x00, 0x36, 0x00, 0xB9, 0x60, 0x40,
+	 0x01, 0x36, 0x01, 0xB9, 0x60, 0x40, 0x02, 0x36, 0x06, 0xB9, 0x60, 0x40, 0x03, 0x36, 0x07, 0xB9,
+	 0x41, 0x44, 0xD4, 0x60, 0xF6, 0x78, 0xFF, 0xFF, 0xD3, 0x60, 0xD0, 0x78, 0xFF, 0xFF, 0x00, 0x60,
+	 0x20, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0xFF, 0xFF, 0x08, 0x24, 0x46, 0x01, 0xA0, 0x84, 0xA2, 0xDB,
+	 0x00, 0x63, 0x68, 0xFD, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x30, 0x00, 0x20, 0x40,
+	 0x06, 0x23, 0x10, 0x00, 0x08, 0x60, 0x27, 0xF1, 0x7F, 0x60, 0xFF, 0x64, 0xA0, 0x84, 0xA2, 0xDB,
+	 0x80, 0x60, 0x00, 0x64, 0x08, 0x60, 0x28, 0xFB, 0xE1, 0x60, 0xF7, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x64, 0x08, 0x60, 0x27, 0xFB, 0x5A, 0xDB, 0x10, 0x60, 0x4E, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x44, 0x01, 0x1C, 0x60, 0x92, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x00, 0x64, 0x68, 0xFB, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0x01, 0x64, 0x8A, 0xFB, 0xFF, 0xFF, 0xC1, 0xFE, 0x2E, 0x58, 0xFF, 0xFF, 0x50, 0x64,
+	 0x3B, 0x42, 0x5A, 0xDB, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x00, 0x60, 0x95, 0xF3,
+	 0xFF, 0xFF, 0x10, 0xB0, 0xFF, 0xFF, 0x11, 0x03, 0x08, 0x60, 0x1B, 0xF1, 0x01, 0x60, 0x00, 0x64,
+	 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x04, 0x60, 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xE2, 0x60,
+	 0x2A, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0xB9, 0xF1, 0x0E, 0x60, 0x4B, 0xF9,
+	 0x7D, 0xF1, 0x7C, 0xF9, 0x02, 0x64, 0x8A, 0xFB, 0xFF, 0xFF, 0xC1, 0xFE, 0x8A, 0xF3, 0x00, 0x65,
+	 0xD4, 0x80, 0xFF, 0xFF, 0x0E, 0x03, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x80, 0x60,
+	 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xE2, 0x60, 0x4A, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x51, 0x64, 0x3B, 0x42, 0x5A, 0xDB,
+	 0x1B, 0x60, 0xB0, 0x64, 0x67, 0xFB, 0x1C, 0x60, 0x72, 0x63, 0x7F, 0xF3, 0xBD, 0xDB, 0x80, 0xF3,
+	 0xBD, 0xDB, 0x81, 0xF3, 0xA3, 0xDB, 0x67, 0xF3, 0x00, 0x60, 0x86, 0xF1, 0x04, 0xA4, 0x67, 0xFB,
+	 0xD0, 0x80, 0xA0, 0xD3, 0x1F, 0x07, 0x40, 0x47, 0x60, 0x41, 0x0E, 0x65, 0x45, 0xD3, 0x16, 0x60,
+	 0xC2, 0xF1, 0xFF, 0xFF, 0x03, 0x1B, 0x10, 0xB0, 0xFF, 0xFF, 0xED, 0x02, 0x27, 0x44, 0x06, 0xA4,
+	 0x60, 0x41, 0xA1, 0xD1, 0x7F, 0xF3, 0x80, 0xF1, 0xD0, 0x80, 0x59, 0xD3, 0x08, 0x02, 0xD0, 0x80,
+	 0x81, 0xF3, 0x59, 0xD1, 0x04, 0x02, 0xD0, 0x80, 0xFF, 0xFF, 0x01, 0x02, 0x03, 0x00, 0xE2, 0x60,
+	 0xE6, 0x78, 0xFF, 0xFF, 0x1C, 0x60, 0x72, 0x63, 0xBD, 0xD3, 0x7F, 0xFB, 0xBD, 0xD3, 0x80, 0xFB,
+	 0xA3, 0xD3, 0x81, 0xFB, 0x53, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0xDE, 0xFE, 0x0A, 0x04, 0x40, 0x60, 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xE2, 0x60,
+	 0x9A, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x7C, 0xF1, 0x7D, 0xF9, 0x13, 0x60,
+	 0x1A, 0xF9, 0x0E, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x20, 0x60, 0x00, 0x64, 0x08, 0x60,
+	 0x16, 0xFB, 0xE2, 0x60, 0xC7, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x60,
+	 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xBE, 0xFE, 0x08, 0x60, 0x08, 0xF1, 0x40, 0x60, 0x00, 0x64,
+	 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x01, 0x63, 0x8A, 0xFD, 0x08, 0x60, 0x0C, 0xF1, 0x00, 0x60,
+	 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0xC1, 0xFE, 0x54, 0x64, 0x3B, 0x42, 0x5A, 0xDB,
+	 0x31, 0x44, 0xF9, 0xB4, 0x40, 0x51, 0xE1, 0x60, 0x22, 0x78, 0xFF, 0xFF, 0x27, 0x43, 0x33, 0x60,
+	 0xBE, 0x65, 0xA5, 0xD3, 0x65, 0x41, 0x10, 0xA3, 0x01, 0xA4, 0xFE, 0xB4, 0xC4, 0x85, 0xFE, 0xA1,
+	 0xBD, 0xD3, 0x59, 0xD1, 0xFF, 0xFF, 0xD0, 0x80, 0xD5, 0x80, 0x02, 0x02, 0x04, 0x03, 0xF8, 0x01,
+	 0xE2, 0x60, 0x73, 0x78, 0xFF, 0xFF, 0x55, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x10, 0x60, 0x2A, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE, 0x0A, 0x04, 0x40, 0x60, 0x00, 0x64, 0x08, 0x60, 0x16, 0xFB,
+	 0xE2, 0x60, 0xFE, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x27, 0xD1, 0x7D, 0xF9,
+	 0x13, 0x60, 0x1A, 0xF9, 0x0E, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x20, 0x60, 0x00, 0x64,
+	 0x08, 0x60, 0x16, 0xFB, 0xE3, 0x60, 0x20, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xBE, 0xFE, 0x08, 0x60, 0x08, 0xF1, 0x40, 0x60,
+	 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x07, 0x60, 0xD0, 0x64, 0x0E, 0x60, 0x4B, 0xFB,
+	 0x1C, 0x60, 0x92, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF,
+	 0x27, 0x43, 0x06, 0xA3, 0xBD, 0xD3, 0x7F, 0xFB, 0xBD, 0xD3, 0x80, 0xFB, 0xA3, 0xD3, 0x81, 0xFB,
+	 0x31, 0x44, 0xF9, 0xB4, 0x40, 0x51, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x01, 0x60,
+	 0x04, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xE3, 0x60, 0x51, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0xB9, 0xF1, 0x0E, 0x60, 0x4B, 0xF9, 0x08, 0x60, 0x15, 0xF1, 0xFE, 0x60, 0xFF, 0x61,
+	 0xA1, 0x84, 0x5A, 0xD1, 0x4A, 0xDB, 0xA1, 0x84, 0x5A, 0xDB, 0x08, 0x60, 0x15, 0xF1, 0x00, 0x60,
+	 0x04, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x05, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xE2, 0x60, 0x73, 0x78,
+	 0xFF, 0xFF, 0x7D, 0xF1, 0x32, 0x60, 0x7A, 0x61, 0xA1, 0xD3, 0x64, 0x40, 0x01, 0x27, 0x59, 0xD3,
+	 0x32, 0x60, 0x7E, 0x61, 0xFD, 0x60, 0x58, 0x4E, 0xAC, 0x78, 0xFF, 0xFF, 0xA1, 0xDB, 0x27, 0x42,
+	 0x0C, 0xA2, 0xA2, 0xD3, 0x16, 0x60, 0xAD, 0xF3, 0x00, 0xBD, 0x01, 0x63, 0xAC, 0x81, 0x09, 0x03,
+	 0x08, 0x03, 0xB8, 0x60, 0x58, 0x4D, 0x15, 0x78, 0xFF, 0xFF, 0x00, 0xB8, 0x01, 0x63, 0x01, 0x03,
+	 0x60, 0x43, 0x0E, 0x60, 0x35, 0xFD, 0x5F, 0xF5, 0x00, 0x64, 0x2B, 0xFA, 0x20, 0x64, 0x2A, 0xFA,
+	 0x27, 0x43, 0x06, 0xA3, 0xBD, 0xD1, 0x2C, 0xF8, 0x32, 0xF8, 0xBD, 0xD1, 0x2D, 0xF8, 0x33, 0xF8,
+	 0xA3, 0xD1, 0x2E, 0xF8, 0x34, 0xF8, 0xEA, 0xF1, 0x2F, 0xF8, 0xEB, 0xF1, 0x30, 0xF8, 0xEC, 0xF1,
+	 0x31, 0xF8, 0xB9, 0xF1, 0x19, 0xF8, 0xF8, 0x60, 0x80, 0x64, 0x0E, 0xFA, 0x00, 0xF4, 0x01, 0x63,
+	 0x32, 0x40, 0x08, 0x26, 0x10, 0xBB, 0x16, 0x60, 0xC2, 0xF1, 0xFF, 0xFF, 0x64, 0x40, 0xFE, 0x26,
+	 0x10, 0xBB, 0x7D, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x27, 0x0A, 0x00, 0x19, 0x60, 0x45, 0xF3,
+	 0xFF, 0xFF, 0x60, 0x40, 0x02, 0x22, 0x20, 0xBB, 0x63, 0x44, 0xFF, 0xFF, 0x04, 0x7F, 0x60, 0x43,
+	 0x09, 0xFC, 0x0E, 0x60, 0x35, 0xF3, 0x12, 0x61, 0x59, 0xDA, 0x1C, 0x60, 0x72, 0x63, 0xBD, 0xD1,
+	 0x59, 0xD8, 0xBD, 0xD1, 0x59, 0xD8, 0xA3, 0xD1, 0x59, 0xD8, 0x35, 0x60, 0x98, 0x64, 0x40, 0x48,
+	 0xD9, 0x81, 0xFF, 0x60, 0xF2, 0x64, 0xF1, 0x60, 0x58, 0x4D, 0x34, 0x78, 0xFF, 0xFF, 0x5F, 0xF5,
+	 0x3F, 0xFC, 0xDB, 0x83, 0x1A, 0x60, 0x4C, 0xFD, 0x20, 0x7C, 0x5A, 0xD9, 0x63, 0x41, 0x34, 0x60,
+	 0x9C, 0x63, 0x12, 0x65, 0x00, 0xF4, 0xCD, 0x84, 0x4C, 0x91, 0x60, 0x43, 0x60, 0xFE, 0xA5, 0xD2,
+	 0xDE, 0x85, 0x7F, 0x26, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0x5D, 0x93, 0xA3, 0xDB, 0x5D, 0x93,
+	 0xA5, 0xD2, 0xF6, 0x1F, 0x5D, 0x93, 0x20, 0xFE, 0xDF, 0x83, 0x5F, 0xF5, 0x25, 0x60, 0xCE, 0x64,
+	 0x13, 0x60, 0x0D, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0x00, 0x66, 0x46, 0x46, 0xC1, 0xFE, 0x16, 0x64, 0x68, 0xFB, 0x56, 0x64, 0x3B, 0x42, 0x5A, 0xDB,
+	 0x0E, 0x60, 0x38, 0xF3, 0xFF, 0xFF, 0x64, 0xA4, 0xA2, 0xDB, 0x0E, 0x60, 0x38, 0xF1, 0x0E, 0x60,
+	 0x4B, 0xF9, 0x1C, 0x60, 0x92, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x04, 0xFF, 0x00, 0x60, 0x1C, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xE4, 0x60, 0x23, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x15, 0xF1, 0x00, 0x60, 0x04, 0x64, 0xA0, 0x80,
+	 0x9C, 0x84, 0x0E, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x57, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x00, 0x64,
+	 0x68, 0xFB, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xE2, 0x60, 0x73, 0x78, 0xFF, 0xFF,
+	 0x00, 0x60, 0x10, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x16, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x1C, 0x60,
+	 0x92, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x58, 0x64,
+	 0x3B, 0x42, 0x5A, 0xDB, 0x00, 0x64, 0x68, 0xFB, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0xE6, 0x60, 0x36, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x08, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x3D, 0x03,
+	 0xA0, 0x84, 0xA2, 0xDB, 0x1C, 0x60, 0x92, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB,
+	 0xFF, 0xFF, 0x04, 0xFF, 0x00, 0x64, 0x68, 0xFB, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0x26, 0x46, 0x00, 0xF4, 0x0A, 0xF2, 0x09, 0xF2, 0x04, 0x1B, 0x01, 0xB0, 0x01, 0x7C, 0x2D, 0x02,
+	 0x0A, 0xF8, 0x59, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0x0A, 0xF2, 0x26, 0x46, 0x40, 0x59, 0x02, 0x60,
+	 0x00, 0x61, 0x2F, 0xF2, 0xA1, 0xDB, 0x30, 0xF2, 0x41, 0x58, 0x59, 0xDB, 0x31, 0xF2, 0x59, 0xDB,
+	 0x26, 0x46, 0x26, 0x60, 0x1A, 0x64, 0x40, 0x4B, 0x34, 0x60, 0x58, 0x4D, 0x08, 0x78, 0xFF, 0xFF,
+	 0x00, 0x66, 0x46, 0x46, 0x05, 0x65, 0xF1, 0x60, 0x58, 0x4E, 0x96, 0x78, 0xFF, 0xFF, 0xE7, 0x60,
+	 0x0B, 0x78, 0xFF, 0xFF, 0xE2, 0x60, 0x73, 0x78, 0xFF, 0xFF, 0x5A, 0x64, 0x3B, 0x42, 0x5A, 0xDB,
+	 0x78, 0x43, 0x02, 0x61, 0x29, 0x60, 0xEA, 0x78, 0xFF, 0xFF, 0x5B, 0x64, 0x3B, 0x42, 0x5A, 0xDB,
+	 0x0C, 0xF2, 0xFF, 0xFF, 0x60, 0x41, 0xFF, 0xB1, 0xFF, 0xA1, 0x60, 0x47, 0xFF, 0xB4, 0xC8, 0x02,
+	 0xC7, 0x03, 0x34, 0x60, 0xF4, 0x63, 0x30, 0x64, 0xBD, 0xDB, 0x66, 0x45, 0x26, 0x46, 0x3F, 0xF2,
+	 0x34, 0x60, 0xF2, 0x61, 0xC2, 0xA0, 0xFF, 0xFF, 0x01, 0x04, 0x3E, 0x64, 0x65, 0x46, 0x02, 0xA4,
+	 0xA1, 0xDB, 0xC8, 0x81, 0x12, 0x65, 0xCD, 0x84, 0x4C, 0x91, 0x60, 0x43, 0x60, 0xFE, 0xA5, 0xD2,
+	 0xDE, 0x85, 0x7F, 0x26, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0x5D, 0x93, 0xA3, 0xDB, 0x5D, 0x93,
+	 0xA5, 0xD2, 0xF6, 0x1F, 0x5D, 0x93, 0x20, 0xFE, 0xDF, 0x83, 0x0C, 0xF2, 0xFF, 0xFF, 0x1A, 0x65,
+	 0x60, 0x47, 0xFF, 0xB4, 0xC4, 0x85, 0xDC, 0x60, 0x58, 0x4D, 0xC7, 0x78, 0xFF, 0xFF, 0x0B, 0xF2,
+	 0xFF, 0xFF, 0x07, 0xB4, 0x01, 0x61, 0x03, 0x03, 0xCC, 0x84, 0xE1, 0x81, 0xFD, 0x02, 0x61, 0x44,
+	 0x94, 0xFB, 0x27, 0x45, 0x02, 0x62, 0x46, 0xD3, 0x5A, 0xD1, 0x60, 0x47, 0x56, 0xFB, 0x64, 0x47,
+	 0x55, 0xFB, 0x00, 0x64, 0x5B, 0xFB, 0x0C, 0x62, 0x46, 0xD3, 0x7E, 0xFB, 0x0B, 0xF0, 0x0F, 0x60,
+	 0xFF, 0x64, 0xA0, 0x84, 0x83, 0xFB, 0x1C, 0x60, 0x6A, 0x62, 0xA2, 0xD3, 0x85, 0xFB, 0x26, 0x46,
+	 0x32, 0xF0, 0x7F, 0xF9, 0x33, 0xF0, 0x80, 0xF9, 0x34, 0xF0, 0x81, 0xF9, 0x2E, 0x60, 0x2E, 0x64,
+	 0x2D, 0x60, 0x8A, 0x63, 0xA0, 0xD1, 0xA3, 0xD9, 0x64, 0x41, 0x58, 0xD1, 0x5B, 0xD9, 0x7D, 0xF3,
+	 0x66, 0x45, 0xA6, 0xF5, 0x60, 0x40, 0x01, 0x27, 0x08, 0x00, 0x91, 0xFA, 0x61, 0x44, 0xFD, 0x60,
+	 0x58, 0x4E, 0xAC, 0x78, 0xFF, 0xFF, 0x12, 0xFA, 0x07, 0x00, 0x11, 0xF8, 0x64, 0x44, 0xFD, 0x60,
+	 0x58, 0x4E, 0xAC, 0x78, 0xFF, 0xFF, 0x12, 0xFA, 0x65, 0x46, 0xA6, 0xF3, 0xFF, 0xFF, 0x02, 0xA4,
+	 0x40, 0x4B, 0x3F, 0xF2, 0x00, 0xF4, 0x60, 0x43, 0xFA, 0xA3, 0x00, 0x60, 0x17, 0x61, 0x00, 0x60,
+	 0x01, 0x65, 0x01, 0x60, 0xFF, 0x64, 0x40, 0x4C, 0xFD, 0x60, 0x58, 0x4E, 0x7A, 0x78, 0xFF, 0xFF,
+	 0x00, 0xBB, 0xFF, 0xFF, 0x00, 0x02, 0x00, 0x64, 0x40, 0x4A, 0x60, 0xFE, 0x02, 0x60, 0x00, 0x63,
+	 0xBD, 0xD3, 0xBD, 0xD3, 0x60, 0x41, 0xFE, 0x60, 0x58, 0x4E, 0x2C, 0x78, 0xFF, 0xFF, 0x20, 0xFE,
+	 0x00, 0x65, 0x00, 0x64, 0x19, 0x60, 0x3B, 0xFB, 0x02, 0x00, 0x20, 0xFE, 0xFF, 0x65, 0x02, 0x60,
+	 0x00, 0x63, 0x60, 0xFE, 0xBD, 0xD3, 0xBD, 0xD3, 0x60, 0x41, 0x20, 0xFE, 0xCD, 0x81, 0x60, 0x40,
+	 0x80, 0x2A, 0x39, 0x00, 0x7F, 0xB4, 0x02, 0x3A, 0x02, 0x00, 0x01, 0x64, 0x2E, 0x00, 0x04, 0x3A,
+	 0x02, 0x00, 0x02, 0x64, 0x2A, 0x00, 0x0B, 0x3A, 0x02, 0x00, 0x04, 0x64, 0x26, 0x00, 0x16, 0x3A,
+	 0x02, 0x00, 0x08, 0x64, 0x22, 0x00, 0x0C, 0x3A, 0x02, 0x00, 0x10, 0x64, 0x1E, 0x00, 0x12, 0x3A,
+	 0x02, 0x00, 0x20, 0x64, 0x1A, 0x00, 0x18, 0x3A, 0x02, 0x00, 0x40, 0x64, 0x16, 0x00, 0x24, 0x3A,
+	 0x02, 0x00, 0x80, 0x64, 0x12, 0x00, 0x30, 0x3A, 0x02, 0x00, 0x01, 0x67, 0x0E, 0x00, 0x48, 0x3A,
+	 0x02, 0x00, 0x02, 0x67, 0x0A, 0x00, 0x60, 0x3A, 0x02, 0x00, 0x04, 0x67, 0x06, 0x00, 0x6C, 0x3A,
+	 0x02, 0x00, 0x08, 0x67, 0x02, 0x00, 0x00, 0x64, 0x00, 0x00, 0x19, 0x60, 0x3B, 0xF1, 0xFF, 0xFF,
+	 0xB0, 0x84, 0x19, 0x60, 0x3B, 0xFB, 0x61, 0x40, 0x00, 0x36, 0x05, 0x00, 0x60, 0xFE, 0xBD, 0xD3,
+	 0xFF, 0xFF, 0x20, 0xFE, 0xBB, 0x01, 0x65, 0x40, 0x00, 0x3A, 0x1E, 0x00, 0x26, 0x46, 0x3F, 0xF2,
+	 0x00, 0xF4, 0x60, 0x43, 0xFA, 0xA3, 0x00, 0x60, 0x17, 0x61, 0x00, 0x60, 0x32, 0x65, 0x01, 0x60,
+	 0xFF, 0x64, 0x40, 0x4C, 0xFD, 0x60, 0x58, 0x4E, 0x7A, 0x78, 0xFF, 0xFF, 0x00, 0xBB, 0xFF, 0xFF,
+	 0x0B, 0x03, 0x60, 0xFE, 0x02, 0x60, 0x00, 0x63, 0xBD, 0xD3, 0xBD, 0xD3, 0x60, 0x41, 0xFE, 0x60,
+	 0x58, 0x4E, 0x2C, 0x78, 0xFF, 0xFF, 0x91, 0x01, 0x20, 0xFE, 0x00, 0x65, 0xFC, 0x60, 0x58, 0x4E,
+	 0xC7, 0x78, 0xFF, 0xFF, 0xA1, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x27, 0x04, 0x00, 0xFD, 0x60,
+	 0x58, 0x4E, 0x11, 0x78, 0xFF, 0xFF, 0x20, 0xFE, 0x37, 0x60, 0xF8, 0x61, 0xA1, 0xD1, 0xA1, 0xF3,
+	 0x01, 0x60, 0xAC, 0x63, 0x60, 0x45, 0x2A, 0x44, 0x79, 0xFB, 0xA3, 0xD5, 0x65, 0x40, 0x01, 0x27,
+	 0x5B, 0xD5, 0x65, 0x40, 0x01, 0x27, 0x59, 0xD1, 0x66, 0x41, 0xA0, 0x84, 0x24, 0x94, 0x2B, 0x46,
+	 0x0F, 0xFA, 0x7A, 0xFB, 0x16, 0x64, 0x12, 0xFA, 0x01, 0x64, 0x11, 0xFA, 0x66, 0x5C, 0xC2, 0x60,
+	 0x58, 0x4E, 0x6D, 0x78, 0xFF, 0xFF, 0xA6, 0xF3, 0xFF, 0xFF, 0x02, 0xA4, 0x40, 0x4B, 0x60, 0x46,
+	 0x00, 0x64, 0x17, 0xFA, 0x00, 0x64, 0x16, 0xFA, 0x13, 0xFA, 0x00, 0x65, 0x26, 0x46, 0xFD, 0x60,
+	 0x58, 0x4E, 0xDD, 0x78, 0xFF, 0xFF, 0xA6, 0xF3, 0x1D, 0x60, 0xC0, 0x65, 0x02, 0xA4, 0x60, 0x46,
+	 0x05, 0xF0, 0x60, 0x41, 0x64, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x00, 0x7C, 0x44, 0xD9, 0x26, 0x46,
+	 0x31, 0xF2, 0x61, 0x5C, 0x60, 0x47, 0x00, 0x7F, 0xE0, 0x84, 0x44, 0xD9, 0x26, 0x46, 0x2F, 0xF0,
+	 0x61, 0x46, 0x03, 0xF8, 0x26, 0x46, 0x30, 0xF0, 0x61, 0x46, 0x04, 0xF8, 0x26, 0x46, 0x31, 0xF0,
+	 0x61, 0x46, 0x05, 0xF8, 0x26, 0x46, 0xD9, 0x60, 0x58, 0x4E, 0xAE, 0x78, 0xFF, 0xFF, 0x26, 0x46,
+	 0x26, 0x60, 0x1A, 0x64, 0x40, 0x4B, 0x34, 0x60, 0x58, 0x4D, 0x08, 0x78, 0xFF, 0xFF, 0x00, 0x66,
+	 0x46, 0x46, 0x03, 0x65, 0xF1, 0x60, 0x58, 0x4E, 0xC3, 0x78, 0xFF, 0xFF, 0x01, 0x63, 0x8A, 0xFD,
+	 0x08, 0x60, 0x0C, 0xF1, 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0xC1, 0xFE,
+	 0x5C, 0x64, 0x3B, 0x42, 0x5A, 0xDB, 0xE1, 0x60, 0x22, 0x78, 0xFF, 0xFF, 0xFF, 0x60, 0xF7, 0x65,
+	 0x20, 0x44, 0x24, 0x80, 0xDA, 0x60, 0x74, 0x78, 0xFF, 0xFF, 0xDB, 0xF3, 0xFF, 0xFF, 0xFD, 0xA0,
+	 0x2A, 0xF2, 0x03, 0x03, 0xE6, 0x60, 0xDE, 0x78, 0xFF, 0xFF, 0x60, 0x40, 0xB0, 0x36, 0x11, 0x00,
+	 0xC0, 0x36, 0x02, 0x00, 0x2F, 0x58, 0xFF, 0xFF, 0x26, 0x46, 0x26, 0x60, 0x1A, 0x64, 0x40, 0x4B,
+	 0x34, 0x60, 0x58, 0x4D, 0x08, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0xDA, 0x60, 0x74, 0x78,
+	 0xFF, 0xFF, 0x66, 0x45, 0x00, 0xF4, 0x0A, 0xF2, 0x0B, 0xF2, 0xFE, 0xA0, 0xF3, 0xA0, 0x67, 0x02,
+	 0x60, 0x41, 0x09, 0xF2, 0x1D, 0x03, 0x00, 0xA0, 0xFF, 0xA0, 0x4B, 0x03, 0x5D, 0x03, 0x00, 0xA0,
+	 0xFF, 0xFF, 0x47, 0x03, 0x01, 0x64, 0x10, 0x60, 0x0B, 0xFB, 0x0D, 0x64, 0x10, 0x60, 0x0C, 0xFB,
+	 0x03, 0x64, 0x10, 0x60, 0x0D, 0xFB, 0x26, 0x46, 0x26, 0x60, 0x1A, 0x64, 0x40, 0x4B, 0x34, 0x60,
+	 0x58, 0x4D, 0x08, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0xDA, 0x60, 0x74, 0x78, 0xFF, 0xFF,
+	 0x16, 0x60, 0xC3, 0xF3, 0xFF, 0xFF, 0xFE, 0xA0, 0x20, 0x60, 0x16, 0x61, 0x15, 0x02, 0x01, 0x64,
+	 0xA1, 0xDB, 0x00, 0x64, 0x10, 0x60, 0x0C, 0xFB, 0x01, 0x64, 0x10, 0x60, 0x0D, 0xFB, 0x26, 0x46,
+	 0x26, 0x60, 0x1A, 0x64, 0x40, 0x4B, 0x34, 0x60, 0x58, 0x4D, 0x08, 0x78, 0xFF, 0xFF, 0x00, 0x66,
+	 0x46, 0x46, 0xDA, 0x60, 0x74, 0x78, 0xFF, 0xFF, 0x02, 0x64, 0xA1, 0xDB, 0x00, 0x64, 0x10, 0x60,
+	 0x0C, 0xFB, 0x01, 0x64, 0x10, 0x60, 0x0D, 0xFB, 0x26, 0x46, 0x26, 0x60, 0x1A, 0x64, 0x40, 0x4B,
+	 0x34, 0x60, 0x58, 0x4D, 0x08, 0x78, 0xFF, 0xFF, 0x00, 0x66, 0x46, 0x46, 0xDA, 0x60, 0x74, 0x78,
+	 0xFF, 0xFF, 0x65, 0x46, 0x07, 0xF4, 0x06, 0xF2, 0xFF, 0xFF, 0x01, 0x7E, 0x06, 0xFA, 0x65, 0x46,
+	 0x26, 0x46, 0x26, 0x60, 0x1A, 0x64, 0x40, 0x4B, 0x34, 0x60, 0x58, 0x4D, 0x08, 0x78, 0xFF, 0xFF,
+	 0x00, 0x66, 0x46, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0xDC, 0x60, 0x09, 0x78, 0xFF, 0xFF, 0x0A, 0xF2,
+	 0x09, 0xF2, 0xFC, 0xA0, 0xFF, 0xA0, 0x11, 0x02, 0x0A, 0x02, 0x0B, 0xF2, 0x65, 0x46, 0x0A, 0x1B,
+	 0x66, 0x41, 0x07, 0xF4, 0x06, 0xF2, 0xFF, 0xFF, 0x01, 0x7E, 0x06, 0xFA, 0x61, 0x46, 0xDA, 0x60,
+	 0x74, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x65, 0x46, 0x68, 0xF1, 0x2A, 0xF2,
+	 0x64, 0x41, 0x60, 0x40, 0xA0, 0x3A, 0x02, 0x00, 0x08, 0xB1, 0x04, 0x00, 0xC0, 0x3A, 0x0B, 0x00,
+	 0x04, 0xB1, 0xFF, 0xFF, 0x1E, 0x03, 0x08, 0x60, 0x15, 0xF1, 0x00, 0x60, 0x10, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x16, 0x00, 0xB0, 0x3A, 0x02, 0x00, 0x01, 0x65, 0x07, 0x00, 0x10, 0x3A,
+	 0x02, 0x00, 0x02, 0x65, 0x03, 0x00, 0x30, 0x3A, 0x0C, 0x00, 0x10, 0x65, 0xA5, 0x80, 0xFF, 0xFF,
+	 0x08, 0x03, 0x08, 0x60, 0x15, 0xF1, 0x00, 0x60, 0x08, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x00, 0x66, 0x2F, 0x58, 0xFF, 0xFF, 0x16, 0x60, 0xC3, 0xF3, 0xFF, 0xFF, 0xFC, 0xA0, 0xFF, 0xFF,
+	 0x14, 0x04, 0x00, 0x60, 0x02, 0x64, 0x08, 0x60, 0x16, 0xFB, 0xE7, 0x60, 0x1B, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x19, 0x60, 0xA5, 0xF1, 0x01, 0x60, 0x00, 0x64, 0xA0, 0x80,
+	 0xFF, 0xFF, 0x03, 0x03, 0xDA, 0x60, 0x74, 0x78, 0xFF, 0xFF, 0x20, 0x40, 0x08, 0x2A, 0x03, 0x00,
+	 0xD9, 0x60, 0xCA, 0x78, 0xFF, 0xFF, 0xE2, 0x60, 0x73, 0x78, 0xFF, 0xFF, 0x4E, 0x64, 0x3B, 0x42,
+	 0x5A, 0xDB, 0x2E, 0xF5, 0xFF, 0xFF, 0x27, 0xF2, 0x1D, 0x60, 0xC0, 0x65, 0x60, 0x47, 0x00, 0x7F,
+	 0xE0, 0x84, 0x44, 0xD3, 0x66, 0x41, 0x60, 0x46, 0x60, 0x43, 0x05, 0xF2, 0x16, 0x18, 0x61, 0x46,
+	 0x27, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0x04, 0xF2, 0x0C, 0x02, 0x61, 0x46, 0x26, 0xF0, 0x63, 0x46,
+	 0xD0, 0x80, 0x03, 0xF2, 0x06, 0x02, 0x61, 0x46, 0x25, 0xF0, 0x63, 0x46, 0xD0, 0x80, 0xFF, 0xFF,
+	 0x07, 0x03, 0x80, 0xF4, 0xFF, 0xFF, 0x63, 0x46, 0xE8, 0x1B, 0xA6, 0xF3, 0x08, 0xFE, 0x60, 0x43,
+	 0x61, 0x46, 0x25, 0xF2, 0x26, 0xF0, 0xA7, 0xF2, 0xA8, 0xF0, 0x65, 0xF5, 0xFF, 0xFF, 0x00, 0xF4,
+	 0xFF, 0xFF, 0x89, 0xF8, 0x65, 0xF5, 0xFF, 0xFF, 0x07, 0xFC, 0x2C, 0xFA, 0x2D, 0xF8, 0xAE, 0xFA,
+	 0xEA, 0xF3, 0x2F, 0xFA, 0xEB, 0xF3, 0x30, 0xFA, 0xEC, 0xF3, 0x31, 0xFA, 0x7F, 0xF3, 0x32, 0xFA,
+	 0x80, 0xF3, 0x33, 0xFA, 0x81, 0xF3, 0x34, 0xFA, 0x1B, 0x60, 0xFE, 0xF3, 0xFF, 0xFF, 0x03, 0x1B,
+	 0x00, 0x60, 0xA0, 0x64, 0x02, 0x00, 0x00, 0x60, 0xC0, 0x64, 0x2A, 0xFA, 0x02, 0x63, 0x3F, 0xFC,
+	 0xAB, 0xFC, 0x00, 0x64, 0x3E, 0xFA, 0xC9, 0xF1, 0x19, 0xF8, 0x25, 0x60, 0xCE, 0x64, 0x13, 0x60,
+	 0x0D, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x00, 0x66,
+	 0x46, 0x46, 0xC1, 0xFE, 0x10, 0x60, 0x2A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xE1, 0x60, 0x34, 0x78,
+	 0xFF, 0xFF, 0x00, 0x60, 0x3A, 0x61, 0xB6, 0x60, 0x58, 0x4D, 0x22, 0x78, 0xFF, 0xFF, 0x66, 0x44,
+	 0x61, 0xFB, 0xA6, 0xF3, 0x07, 0xFA, 0x0C, 0x60, 0x80, 0x64, 0xB9, 0xF1, 0x19, 0xF8, 0x0E, 0xFA,
+	 0x00, 0x64, 0x3E, 0xFA, 0x3F, 0xFA, 0x00, 0x60, 0x3A, 0x61, 0xB6, 0x60, 0x58, 0x4D, 0x22, 0x78,
+	 0xFF, 0xFF, 0x66, 0x44, 0x60, 0xFB, 0xA6, 0xF3, 0x07, 0xFA, 0x0C, 0x60, 0x80, 0x64, 0x0E, 0xFA,
+	 0xB9, 0xF1, 0x19, 0xF8, 0x00, 0x64, 0x3E, 0xFA, 0x3F, 0xFA, 0xE8, 0x60, 0xEA, 0x64, 0x08, 0x60,
+	 0x33, 0xFB, 0x00, 0x60, 0x80, 0x64, 0x08, 0x60, 0x10, 0xFB, 0xE7, 0x60, 0xCB, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x16, 0x60, 0x87, 0xF3, 0xFF, 0xFF, 0x01, 0xA8, 0x03, 0xA8,
+	 0x04, 0x03, 0x03, 0x03, 0xE8, 0x60, 0xDC, 0x78, 0xFF, 0xFF, 0x04, 0x60, 0x00, 0x65, 0x20, 0x44,
+	 0x34, 0x80, 0x10, 0x60, 0x1E, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x9B, 0xFE, 0x03, 0x05, 0x20, 0x40,
+	 0x4B, 0x23, 0x0A, 0x00, 0x80, 0x60, 0x00, 0x64, 0x08, 0x60, 0x10, 0xFB, 0xE7, 0x60, 0xD9, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x60, 0x13, 0xF3, 0xFF, 0xFF, 0x60, 0x40,
+	 0x01, 0x2A, 0x07, 0x00, 0x90, 0x60, 0x00, 0x65, 0x20, 0x44, 0x34, 0x80, 0x00, 0x64, 0xA2, 0xDB,
+	 0x04, 0x00, 0x10, 0x60, 0x00, 0x65, 0x20, 0x44, 0x34, 0x80, 0x8A, 0xF3, 0x58, 0xFB, 0x82, 0xF1,
+	 0xBA, 0xFE, 0x01, 0xA8, 0x59, 0xF9, 0x04, 0x02, 0x02, 0x64, 0x8A, 0xFB, 0xFF, 0xFF, 0xC1, 0xFE,
+	 0x64, 0x47, 0xDB, 0xF3, 0x10, 0xB0, 0x04, 0xA8, 0x2B, 0x02, 0x2A, 0x02, 0x61, 0xF5, 0xEA, 0xF1,
+	 0x2F, 0xF8, 0xEB, 0xF1, 0x30, 0xF8, 0xEC, 0xF1, 0x31, 0xF8, 0x7F, 0xF1, 0x2C, 0xF8, 0x32, 0xF8,
+	 0x80, 0xF1, 0x2D, 0xF8, 0x33, 0xF8, 0x81, 0xF1, 0x2E, 0xF8, 0x34, 0xF8, 0x10, 0x60, 0x48, 0x64,
+	 0x2A, 0xFA, 0x25, 0x60, 0xCE, 0x64, 0x13, 0x60, 0x0D, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x00, 0x60, 0x01, 0x64, 0x08, 0x60, 0x10, 0xFB,
+	 0xE8, 0x60, 0x36, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x67, 0x82, 0xFB,
+	 0x8A, 0xF3, 0xFF, 0xFF, 0x00, 0xA8, 0xFF, 0xFF, 0x0A, 0x03, 0x80, 0x60, 0x00, 0x64, 0x08, 0x60,
+	 0x10, 0xFB, 0xE8, 0x60, 0x38, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x60,
+	 0x1E, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x05, 0x7C, 0x53, 0xF9, 0x2F, 0x60, 0x24, 0x64, 0x54, 0xFB,
+	 0x19, 0x60, 0x40, 0xF3, 0xFF, 0xFF, 0x15, 0x18, 0x10, 0x60, 0x1E, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0x08, 0x60, 0x12, 0xF1, 0x00, 0x60, 0x10, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x10, 0x60,
+	 0x00, 0x64, 0x08, 0x60, 0x10, 0xFB, 0xE8, 0x60, 0x69, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x19, 0x60, 0x41, 0xF3, 0xFF, 0x60, 0x80, 0x65, 0xA4, 0x80, 0x5A, 0xD3, 0x05, 0x02,
+	 0x04, 0x1B, 0x5A, 0xD3, 0xFF, 0xFF, 0x01, 0x1B, 0x15, 0x00, 0x10, 0x60, 0x1E, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0x08, 0x60, 0x12, 0xF1, 0x00, 0x60, 0x20, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x10, 0x60, 0x00, 0x64, 0x08, 0x60, 0x10, 0xFB, 0xE8, 0x60, 0x8A, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0xFF, 0xFF, 0x59, 0xF3, 0x82, 0xFB, 0x60, 0x40, 0x10, 0x27, 0xDA, 0xFE,
+	 0xDB, 0xF3, 0x00, 0xA8, 0x04, 0xA8, 0x23, 0x02, 0x22, 0x02, 0x60, 0xF5, 0xEA, 0xF1, 0x2F, 0xF8,
+	 0xEB, 0xF1, 0x30, 0xF8, 0xEC, 0xF1, 0x31, 0xF8, 0x7F, 0xF1, 0x2C, 0xF8, 0x80, 0xF1, 0x2D, 0xF8,
+	 0x81, 0xF1, 0x2E, 0xF8, 0xA4, 0x64, 0x2A, 0xFA, 0x83, 0xF1, 0xC0, 0x67, 0xB0, 0x84, 0x2B, 0xFA,
+	 0x25, 0x60, 0xCE, 0x64, 0x13, 0x60, 0x0D, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB,
+	 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x20, 0x60, 0x00, 0x65, 0x20, 0x44, 0x34, 0x80, 0x00, 0x60,
+	 0x04, 0x61, 0xB6, 0x60, 0x58, 0x4D, 0x22, 0x78, 0xFF, 0xFF, 0x01, 0x64, 0x23, 0xFA, 0xF1, 0x60,
+	 0x02, 0x64, 0x24, 0xFA, 0x26, 0x60, 0x0A, 0x64, 0x13, 0x60, 0x0D, 0xFB, 0x66, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xFA, 0xFE, 0xEB, 0x60, 0xFF, 0x65, 0x20, 0x44,
+	 0x24, 0x80, 0x08, 0x60, 0x08, 0xF1, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x58, 0xF3, 0x8A, 0xFB, 0xFF, 0xFF, 0xC1, 0xFE, 0x10, 0x60, 0x1E, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0x00, 0x60, 0x80, 0x64, 0x08, 0x60, 0x10, 0xFB, 0xE7, 0x60, 0xCB, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x9C, 0xF1, 0x00, 0x64, 0xB0, 0x86, 0x9C, 0xFB, 0x07, 0x03, 0x26, 0x60,
+	 0x1A, 0x64, 0x40, 0x4B, 0x34, 0x60, 0x58, 0x4D, 0x08, 0x78, 0xFF, 0xFF, 0xEB, 0x60, 0xFF, 0x65,
+	 0x20, 0x44, 0x24, 0x80, 0x10, 0x60, 0x1E, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x00, 0x60, 0x80, 0x64,
+	 0x08, 0x60, 0x10, 0xFB, 0xE7, 0x60, 0xCB, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x95, 0xF3, 0x26, 0x46, 0x60, 0x43, 0x01, 0x2A, 0x20, 0x00, 0x0F, 0xF2, 0x2A, 0xF0, 0x60, 0x40,
+	 0x10, 0x2A, 0x0F, 0x00, 0x64, 0x40, 0x04, 0x27, 0x18, 0x00, 0xFD, 0xB3, 0x64, 0x40, 0x20, 0x27,
+	 0x02, 0xBB, 0x08, 0x60, 0x1B, 0xF1, 0x00, 0x60, 0x08, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x0B, 0x00, 0xFB, 0xB3, 0x64, 0x40, 0x20, 0x27, 0x04, 0xBB, 0x08, 0x60, 0x1B, 0xF1, 0x00, 0x60,
+	 0x10, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x95, 0xFD, 0x26, 0x46, 0x2F, 0x58, 0xFF, 0xFF,
+	 0xDB, 0xF3, 0x3F, 0xF2, 0x04, 0xA8, 0x57, 0xFB, 0x02, 0x03, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0xF4,
+	 0x1E, 0x63, 0x08, 0x64, 0x40, 0x48, 0xBD, 0xD2, 0xFF, 0xFF, 0x60, 0x47, 0x05, 0x36, 0x0B, 0x00,
+	 0xFF, 0xB5, 0xC7, 0x83, 0x01, 0x2A, 0xF7, 0x01, 0x4F, 0xD2, 0x5B, 0xD2, 0x60, 0x40, 0x05, 0x37,
+	 0x0B, 0x00, 0xDF, 0x83, 0xF5, 0x01, 0xFF, 0xB5, 0x65, 0x41, 0xA3, 0xD2, 0x47, 0x8A, 0x60, 0x47,
+	 0x40, 0x4C, 0x5B, 0xD2, 0xDF, 0x83, 0x08, 0x00, 0x40, 0x4C, 0x00, 0x7F, 0xDC, 0x85, 0x47, 0x8A,
+	 0x60, 0x41, 0x5B, 0xD2, 0xDB, 0x83, 0x60, 0x47, 0x01, 0xB0, 0xFE, 0xB5, 0x02, 0x03, 0x02, 0x64,
+	 0x40, 0x48, 0x2C, 0x47, 0xFF, 0xB4, 0x73, 0xF1, 0x08, 0x28, 0x73, 0xFB, 0x83, 0xF1, 0x65, 0x44,
+	 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0xFD, 0xA1, 0xE1, 0x81, 0xE1, 0x81, 0xE1, 0x85, 0xC4, 0x81,
+	 0xD0, 0x84, 0xD1, 0x80, 0x28, 0x07, 0x27, 0x06, 0x9C, 0x84, 0xDC, 0x84, 0xE8, 0x84, 0xE8, 0x84,
+	 0xE8, 0x85, 0x94, 0xF3, 0xC7, 0x83, 0x01, 0x26, 0x60, 0x47, 0xAB, 0x83, 0xFC, 0xA3, 0x02, 0x00,
+	 0x03, 0x04, 0x00, 0xF4, 0x84, 0xA3, 0xFC, 0x01, 0x80, 0x65, 0x47, 0xD0, 0x28, 0x41, 0xA0, 0x80,
+	 0xFE, 0xA1, 0x14, 0x03, 0x08, 0x02, 0x08, 0x60, 0x2D, 0xF1, 0x00, 0x60, 0x10, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x1B, 0x00, 0x08, 0x60, 0x2D, 0xF1, 0x00, 0x60, 0x04, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x13, 0x00, 0x28, 0x41, 0xFE, 0xA1, 0xFF, 0xFF, 0x08, 0x03, 0x08, 0x60,
+	 0x2D, 0xF1, 0x00, 0x60, 0x08, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x07, 0x00, 0x08, 0x60,
+	 0x2D, 0xF1, 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x08, 0x60, 0x1B, 0xF1,
+	 0x00, 0x60, 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x26, 0x46, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x08, 0x60, 0x1B, 0xF1, 0x00, 0x60, 0x20, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x08, 0x60, 0x1B, 0xF1, 0x02, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x63, 0x95, 0xFD, 0x1C, 0x60, 0x9E, 0x63, 0x00, 0x64, 0xA3, 0xDB,
+	 0x06, 0xA3, 0x10, 0x60, 0x98, 0x64, 0xBD, 0xDB, 0xBD, 0xDB, 0x06, 0x64, 0xA3, 0xDB, 0xE9, 0x60,
+	 0xB8, 0x64, 0x08, 0x60, 0x4B, 0xFB, 0xCE, 0xF1, 0x0E, 0x60, 0x51, 0xF9, 0x1C, 0x60, 0xAA, 0x63,
+	 0x00, 0x64, 0xA3, 0xDB, 0x06, 0xA3, 0x10, 0x60, 0x9C, 0x64, 0xBD, 0xDB, 0xBD, 0xDB, 0x06, 0x64,
+	 0xA3, 0xDB, 0xE9, 0x60, 0xC1, 0x64, 0x08, 0x60, 0x4D, 0xFB, 0x16, 0x60, 0xAE, 0xF1, 0x0E, 0x60,
+	 0x57, 0xF9, 0x00, 0x60, 0x3A, 0x61, 0xB6, 0x60, 0x58, 0x4D, 0x22, 0x78, 0xFF, 0xFF, 0x66, 0x44,
+	 0x63, 0xFB, 0xA6, 0xF3, 0x07, 0xFA, 0xB9, 0xF3, 0x19, 0xFA, 0xF8, 0x60, 0x80, 0x64, 0x0E, 0xFA,
+	 0x00, 0x64, 0x3E, 0xFA, 0x3F, 0xFA, 0x00, 0x60, 0x3A, 0x61, 0xB6, 0x60, 0x58, 0x4D, 0x22, 0x78,
+	 0xFF, 0xFF, 0x66, 0x44, 0x64, 0xFB, 0xA6, 0xF3, 0x07, 0xFA, 0xB9, 0xF3, 0x19, 0xFA, 0x24, 0x60,
+	 0x80, 0x64, 0x0E, 0xFA, 0x00, 0x64, 0x3E, 0xFA, 0x3F, 0xFA, 0x00, 0x64, 0x08, 0x60, 0x2D, 0xFB,
+	 0x5A, 0xDB, 0xEA, 0x60, 0x1F, 0x64, 0x08, 0x60, 0x37, 0xFB, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x63,
+	 0x95, 0xFD, 0xBA, 0xFE, 0xFE, 0x60, 0xFF, 0x65, 0x20, 0x44, 0x24, 0x80, 0x82, 0xFD, 0x08, 0x60,
+	 0x15, 0xF1, 0x04, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x00, 0x64, 0x08, 0x60,
+	 0x1B, 0xFB, 0x5A, 0xDB, 0x2F, 0x58, 0xFF, 0xFF, 0x16, 0x60, 0xAB, 0xF3, 0xFF, 0xFF, 0x01, 0xA8,
+	 0xFF, 0xFF, 0x05, 0x03, 0x19, 0x60, 0xF0, 0xF1, 0x0E, 0x60, 0x57, 0xF9, 0x04, 0x00, 0x16, 0x60,
+	 0xAE, 0xF1, 0x0E, 0x60, 0x57, 0xF9, 0x16, 0x60, 0xAB, 0xF3, 0xFF, 0xFF, 0x09, 0x1B, 0x00, 0x64,
+	 0x82, 0xFB, 0xBA, 0xFE, 0x00, 0x64, 0x08, 0x60, 0x1B, 0xFB, 0x5A, 0xDB, 0x2F, 0x58, 0xFF, 0xFF,
+	 0xBA, 0xFE, 0x95, 0xF3, 0x00, 0x63, 0x82, 0xFD, 0x10, 0xBC, 0x95, 0xFB, 0xFE, 0x60, 0xFF, 0x65,
+	 0x20, 0x44, 0x24, 0x80, 0x08, 0x60, 0x08, 0xF1, 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xCF, 0xFE, 0x00, 0x60, 0x64, 0x63, 0x0E, 0x60, 0x37, 0xFD, 0x10, 0x60, 0x36, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0x01, 0x60, 0x04, 0x64, 0x08, 0x60, 0x1C, 0xFB, 0xEA, 0x60, 0x73, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x1B, 0xF1, 0x01, 0x60, 0x00, 0x64, 0xA0, 0x80,
+	 0x9C, 0x84, 0x03, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xA2, 0x01, 0x31, 0x40, 0x04, 0x2A, 0xE5, 0x01,
+	 0x20, 0x40, 0x12, 0x23, 0x11, 0x00, 0x10, 0x60, 0x36, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x10, 0x60,
+	 0x5A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x81, 0x60, 0x00, 0x64, 0x08, 0x60, 0x1C, 0xFB, 0xEA, 0x60,
+	 0x73, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0xDD, 0x01, 0x10, 0x60, 0x36, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0x01, 0x60, 0x00, 0x65, 0x20, 0x44, 0x34, 0x80, 0x64, 0xF5, 0xB9, 0xF1, 0x19, 0xF8, 0x7F, 0xF1,
+	 0x2C, 0xF8, 0x32, 0xF8, 0x80, 0xF1, 0x2D, 0xF8, 0x33, 0xF8, 0x81, 0xF1, 0x2E, 0xF8, 0x34, 0xF8,
+	 0xEA, 0xF1, 0x2F, 0xF8, 0xEB, 0xF1, 0x30, 0xF8, 0xEC, 0xF1, 0x31, 0xF8, 0x11, 0x60, 0x48, 0x64,
+	 0x2A, 0xFA, 0x00, 0x64, 0x2B, 0xFA, 0x23, 0xFA, 0x25, 0x60, 0xCE, 0x64, 0x13, 0x60, 0x0D, 0xFB,
+	 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x00, 0x60,
+	 0x01, 0x64, 0x08, 0x60, 0x1C, 0xFB, 0xEA, 0x60, 0xC9, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x64, 0xF5, 0x23, 0xF2, 0xFF, 0xFF, 0x01, 0x18, 0x82, 0x01, 0x10, 0x67, 0x82, 0xFB,
+	 0x03, 0x64, 0x96, 0xFB, 0xFE, 0x60, 0xFF, 0x65, 0x20, 0x44, 0x24, 0x80, 0x08, 0x60, 0x08, 0xF1,
+	 0x80, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x10, 0x60, 0x36, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0x81, 0x60, 0x00, 0x64, 0x08, 0x60, 0x1C, 0xFB, 0xEA, 0x60, 0xEA, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x0C, 0x00, 0x08, 0x60, 0x1B, 0xF1, 0x01, 0x60, 0x00, 0x64, 0xA0, 0x80, 0x9C, 0x84,
+	 0x05, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xEA, 0x60, 0x1F, 0x78, 0xFF, 0xFF, 0x06, 0x60, 0x00, 0x65,
+	 0x20, 0x41, 0x8C, 0xF3, 0xA5, 0x80, 0x01, 0xB0, 0x01, 0x02, 0x06, 0x00, 0x10, 0x60, 0x36, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x2F, 0x58, 0xFF, 0xFF, 0x1C, 0x60, 0x6E, 0x65, 0xA5, 0xD3, 0x01, 0x63,
+	 0x8A, 0xFD, 0x26, 0x1B, 0x00, 0x60, 0x64, 0x64, 0xA5, 0xDB, 0x64, 0xF5, 0xB9, 0xF1, 0x19, 0xF8,
+	 0x7F, 0xF1, 0x2C, 0xF8, 0x32, 0xF8, 0x80, 0xF1, 0x2D, 0xF8, 0x33, 0xF8, 0x81, 0xF1, 0x2E, 0xF8,
+	 0x34, 0xF8, 0xEA, 0xF1, 0x2F, 0xF8, 0xEB, 0xF1, 0x30, 0xF8, 0xEC, 0xF1, 0x31, 0xF8, 0x11, 0x60,
+	 0x48, 0x64, 0x2A, 0xFA, 0x00, 0x64, 0x2B, 0xFA, 0x23, 0xFA, 0x25, 0x60, 0xCE, 0x64, 0x13, 0x60,
+	 0x0D, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x06, 0x00,
+	 0x95, 0xF3, 0x32, 0x40, 0x02, 0x26, 0x02, 0x00, 0x40, 0x2A, 0xDA, 0xFE, 0xC1, 0xFE, 0x10, 0x60,
+	 0x36, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x01, 0x60, 0x82, 0x64, 0x08, 0x60, 0x1C, 0xFB, 0xEB, 0x60,
+	 0x45, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x1B, 0xF1, 0x01, 0x60,
+	 0x00, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x05, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xEA, 0x60, 0x1F, 0x78,
+	 0xFF, 0xFF, 0x00, 0x60, 0x02, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x06, 0x03, 0xA0, 0x84, 0xA2, 0xDB,
+	 0xBA, 0xFE, 0xED, 0x60, 0x6D, 0x78, 0xFF, 0xFF, 0x02, 0x64, 0x8A, 0xFB, 0x01, 0x60, 0x00, 0x65,
+	 0x20, 0x44, 0x34, 0x80, 0xBA, 0xFE, 0xC1, 0xFE, 0x10, 0x60, 0x36, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0x10, 0x60, 0x5A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x01, 0x60, 0x46, 0x64, 0x08, 0x60, 0x1C, 0xFB,
+	 0xEB, 0x60, 0x76, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x1B, 0xF1,
+	 0x01, 0x60, 0x00, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x05, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xEA, 0x60,
+	 0x1F, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x04, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x45, 0x03, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x08, 0x60, 0x2D, 0xF1, 0x00, 0x60, 0x08, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x0F, 0x03,
+	 0xA0, 0x84, 0xA2, 0xDB, 0x08, 0x60, 0x1B, 0xF1, 0x00, 0x60, 0x02, 0x64, 0xA0, 0x80, 0x9C, 0x84,
+	 0x05, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xED, 0x60, 0x6D, 0x78, 0xFF, 0xFF, 0x31, 0x01, 0x00, 0x60,
+	 0x02, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x0B, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x16, 0x60, 0xAC, 0xF1,
+	 0x95, 0xF3, 0x00, 0x61, 0xD1, 0x80, 0xF7, 0xB4, 0xF1, 0x03, 0x95, 0xFB, 0x33, 0x00, 0x00, 0x60,
+	 0x10, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x0E, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x16, 0x60, 0xAC, 0xF1,
+	 0x95, 0xF3, 0x00, 0x61, 0xD1, 0x80, 0x08, 0xBC, 0x03, 0x02, 0xEC, 0x60, 0x9C, 0x78, 0xFF, 0xFF,
+	 0x95, 0xFB, 0x20, 0x00, 0x00, 0x60, 0x04, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x05, 0x03, 0xA0, 0x84,
+	 0xA2, 0xDB, 0xEC, 0x60, 0x9C, 0x78, 0xFF, 0xFF, 0x08, 0x60, 0x1B, 0xF1, 0x00, 0x60, 0x40, 0x64,
+	 0xA0, 0x80, 0x9C, 0x84, 0x03, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xC8, 0x01, 0x00, 0x60, 0x02, 0x64,
+	 0xA0, 0x80, 0x9C, 0x84, 0x05, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xED, 0x60, 0x6D, 0x78, 0xFF, 0xFF,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x02, 0x63, 0x95, 0xF3, 0x8A, 0xFD, 0x01, 0xBC, 0xC1, 0xFE, 0x95, 0xFB,
+	 0xCE, 0xF1, 0x0E, 0x60, 0x51, 0xF9, 0x10, 0x60, 0x36, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x10, 0x60,
+	 0x5A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x01, 0x60, 0x34, 0x64, 0x08, 0x60, 0x1C, 0xFB, 0xEC, 0x60,
+	 0x05, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x1C, 0x60, 0x9E, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x02, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x1B, 0xF1, 0x01, 0x60,
+	 0x00, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x0D, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x1C, 0x60, 0x9E, 0x64,
+	 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0xEA, 0x60, 0x1F, 0x78,
+	 0xFF, 0xFF, 0x00, 0x60, 0x10, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x22, 0x03, 0xA0, 0x84, 0xA2, 0xDB,
+	 0x95, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x04, 0x2A, 0x01, 0x00, 0xD5, 0x01, 0x1C, 0x60, 0x9E, 0x64,
+	 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x95, 0xF3, 0xFF, 0xFF,
+	 0x60, 0x40, 0x08, 0x2A, 0x01, 0x00, 0x68, 0x00, 0x08, 0x60, 0x1B, 0xF1, 0x00, 0x60, 0x02, 0x64,
+	 0xA0, 0x80, 0x9C, 0x84, 0x59, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xED, 0x60, 0x6D, 0x78, 0xFF, 0xFF,
+	 0x08, 0x60, 0x2D, 0xF1, 0x00, 0x60, 0x10, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x08, 0x03, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x95, 0xF3, 0xFF, 0xFF, 0x08, 0xBC, 0x95, 0xFB, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x60,
+	 0x02, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x03, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xA4, 0x01, 0x00, 0x60,
+	 0x04, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x0B, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x1C, 0x60, 0x9E, 0x64,
+	 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x35, 0x00, 0x00, 0x60,
+	 0x08, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x0B, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x1C, 0x60, 0x9E, 0x64,
+	 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x1E, 0x00, 0x08, 0x60,
+	 0x1B, 0xF1, 0x00, 0x60, 0x20, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x14, 0x03, 0xA0, 0x84, 0xA2, 0xDB,
+	 0x95, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x08, 0x2A, 0x01, 0x00, 0x16, 0x00, 0x08, 0x60, 0x1B, 0xF1,
+	 0x00, 0x60, 0x02, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x08, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xED, 0x60,
+	 0x6D, 0x78, 0xFF, 0xFF, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x00, 0x95, 0xF3, 0xFF, 0xFF, 0xFE, 0xB4,
+	 0x95, 0xFB, 0xEA, 0x60, 0xD0, 0x78, 0xFF, 0xFF, 0x16, 0x60, 0xAB, 0xF3, 0xFF, 0xFF, 0x01, 0xA8,
+	 0xFF, 0xFF, 0x03, 0x02, 0xED, 0x60, 0x76, 0x78, 0xFF, 0xFF, 0x95, 0xF3, 0x01, 0x63, 0x8A, 0xFD,
+	 0x21, 0xBC, 0x95, 0xFB, 0x63, 0xF5, 0x7F, 0xF1, 0x2C, 0xF8, 0x80, 0xF1, 0x2D, 0xF8, 0x81, 0xF1,
+	 0x2E, 0xF8, 0x83, 0xF1, 0xC0, 0x67, 0xB0, 0x84, 0x2B, 0xFA, 0xB9, 0xF1, 0x19, 0xF8, 0xEA, 0xF1,
+	 0x2F, 0xF8, 0xEB, 0xF1, 0x30, 0xF8, 0xEC, 0xF1, 0x31, 0xF8, 0x10, 0x60, 0xA4, 0x64, 0x2A, 0xFA,
+	 0x25, 0x60, 0xCE, 0x64, 0x13, 0x60, 0x0D, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB,
+	 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x00, 0x60, 0x50, 0x64, 0x0E, 0x60, 0x51, 0xFB, 0x1C, 0x60,
+	 0x9E, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x10, 0x60,
+	 0x36, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x10, 0x60, 0x5A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x01, 0x60,
+	 0x2C, 0x64, 0x08, 0x60, 0x1C, 0xFB, 0xEC, 0x60, 0xE9, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x08, 0x60, 0x1B, 0xF1, 0x01, 0x60, 0x00, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x0D, 0x03,
+	 0xA0, 0x84, 0xA2, 0xDB, 0x1C, 0x60, 0x9E, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB,
+	 0xFF, 0xFF, 0x04, 0xFF, 0xEA, 0x60, 0x1F, 0x78, 0xFF, 0xFF, 0x08, 0x60, 0x2D, 0xF1, 0x00, 0x60,
+	 0x04, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x03, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x95, 0x01, 0x08, 0x60,
+	 0x1B, 0xF1, 0x00, 0x60, 0x08, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x08, 0x03, 0xA0, 0x84, 0xA2, 0xDB,
+	 0x95, 0xF3, 0xFF, 0xFF, 0x02, 0xB0, 0xFF, 0xFF, 0x49, 0x03, 0x86, 0x01, 0x00, 0x60, 0x08, 0x64,
+	 0xA0, 0x80, 0x9C, 0x84, 0x03, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x40, 0x00, 0x00, 0x60, 0x02, 0x64,
+	 0xA0, 0x80, 0x9C, 0x84, 0x14, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x1C, 0x60, 0x9E, 0x64, 0x13, 0x60,
+	 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x16, 0x60, 0xAC, 0xF3, 0x95, 0xF3,
+	 0x00, 0xA8, 0xF7, 0xB4, 0x2B, 0x03, 0x95, 0xFB, 0xEB, 0x60, 0xE2, 0x78, 0xFF, 0xFF, 0x00, 0x60,
+	 0x10, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x15, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x1C, 0x60, 0x9E, 0x64,
+	 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x16, 0x60, 0xAC, 0xF3,
+	 0x95, 0xF3, 0x00, 0xA8, 0x08, 0xBC, 0x01, 0x02, 0x4F, 0x01, 0x95, 0xFB, 0xEB, 0x60, 0xE2, 0x78,
+	 0xFF, 0xFF, 0x08, 0x60, 0x1B, 0xF1, 0x00, 0x60, 0x20, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x03, 0x03,
+	 0xA0, 0x84, 0xA2, 0xDB, 0x02, 0x00, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x00, 0x1C, 0x60, 0x9E, 0x64,
+	 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x95, 0xF3, 0xFF, 0xFF,
+	 0xFE, 0xB4, 0x95, 0xFB, 0xEA, 0x60, 0xD0, 0x78, 0xFF, 0xFF, 0x95, 0xF3, 0x01, 0x63, 0x8A, 0xFD,
+	 0x01, 0xBC, 0x95, 0xFB, 0x00, 0x64, 0x82, 0xFB, 0xC1, 0xFE, 0x28, 0x00, 0x95, 0xF3, 0x01, 0x63,
+	 0x8A, 0xFD, 0x01, 0xBC, 0x95, 0xFB, 0x00, 0x64, 0x82, 0xFB, 0x63, 0xF5, 0x7F, 0xF1, 0x2C, 0xF8,
+	 0x80, 0xF1, 0x2D, 0xF8, 0x81, 0xF1, 0x2E, 0xF8, 0x83, 0xF1, 0xC0, 0x67, 0xB0, 0x84, 0x2B, 0xFA,
+	 0xB9, 0xF1, 0x19, 0xF8, 0xEA, 0xF1, 0x2F, 0xF8, 0xEB, 0xF1, 0x30, 0xF8, 0xEC, 0xF1, 0x31, 0xF8,
+	 0x00, 0x60, 0xA4, 0x64, 0x2A, 0xFA, 0x25, 0x60, 0xCE, 0x64, 0x13, 0x60, 0x0D, 0xFB, 0x66, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x1C, 0x60, 0xAA, 0x64,
+	 0x13, 0x60, 0x22, 0xFB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x10, 0x60, 0x36, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x10, 0x60, 0x5A, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x03, 0x60, 0x0E, 0x64,
+	 0x08, 0x60, 0x1C, 0xFB, 0xED, 0x60, 0xB8, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x08, 0x60, 0x1B, 0xF1, 0x01, 0x60, 0x00, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x0D, 0x03, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x1C, 0x60, 0xAA, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x04, 0xFF, 0xEA, 0x60, 0x1F, 0x78, 0xFF, 0xFF, 0x00, 0x60, 0x0A, 0x64, 0xA0, 0x80, 0x9C, 0x84,
+	 0x03, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xCA, 0x01, 0x00, 0x60, 0x04, 0x64, 0xA0, 0x80, 0x9C, 0x84,
+	 0x14, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x08, 0x60, 0x2D, 0xF1, 0x00, 0x60, 0x04, 0x64, 0xA0, 0x80,
+	 0x9C, 0x84, 0x03, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x91, 0x01, 0x00, 0x60, 0x12, 0x64, 0xA0, 0x80,
+	 0x9C, 0x84, 0x03, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0xB1, 0x01, 0x08, 0x60, 0x1B, 0xF1, 0x02, 0x60,
+	 0x00, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0xB2, 0x03, 0xA0, 0x84, 0xA2, 0xDB, 0x10, 0x67, 0x82, 0xFB,
+	 0x10, 0x60, 0x36, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x10, 0x60, 0x5A, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0x64, 0xF5, 0xB9, 0xF1, 0x19, 0xF8, 0x7F, 0xF1, 0x2C, 0xF8, 0x32, 0xF8, 0x80, 0xF1, 0x2D, 0xF8,
+	 0x33, 0xF8, 0x81, 0xF1, 0x2E, 0xF8, 0x34, 0xF8, 0xEA, 0xF1, 0x2F, 0xF8, 0xEB, 0xF1, 0x30, 0xF8,
+	 0xEC, 0xF1, 0x31, 0xF8, 0x11, 0x60, 0x48, 0x64, 0x2A, 0xFA, 0x00, 0x64, 0x2B, 0xFA, 0x23, 0xFA,
+	 0x25, 0x60, 0xCE, 0x64, 0x13, 0x60, 0x0D, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB,
+	 0xFF, 0xFF, 0x2B, 0xFF, 0x95, 0xF3, 0xC1, 0xFE, 0xFE, 0xB4, 0x95, 0xFB, 0x00, 0x60, 0x03, 0x64,
+	 0x08, 0x60, 0x1C, 0xFB, 0xEE, 0x60, 0x30, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x08, 0x60, 0x1B, 0xF1, 0x00, 0x60, 0x02, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x03, 0x03, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x33, 0x01, 0x64, 0xF5, 0x23, 0xF2, 0x96, 0xF3, 0x04, 0x18, 0xCC, 0x84, 0x96, 0xFB,
+	 0x01, 0x03, 0x2B, 0x01, 0xEA, 0x60, 0xD0, 0x78, 0xFF, 0xFF, 0x16, 0x60, 0xAB, 0xF3, 0x82, 0xF1,
+	 0x02, 0xA8, 0x2A, 0xF2, 0x03, 0x02, 0xB0, 0x84, 0x2A, 0xFA, 0x07, 0x00, 0x08, 0x60, 0x1B, 0xF1,
+	 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x25, 0x60, 0xC8, 0x64, 0x13, 0x60,
+	 0x0D, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE,
+	 0x12, 0x60, 0xED, 0xF3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0xDF, 0x02, 0xCA, 0x60, 0xD4, 0x78,
+	 0xFF, 0xFF, 0x10, 0x60, 0x48, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x00, 0x60, 0x06, 0x64, 0x08, 0x60,
+	 0x25, 0xFB, 0xEE, 0x60, 0x77, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x60,
+	 0x18, 0x64, 0x08, 0x60, 0x25, 0xFB, 0xEE, 0x60, 0x77, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x26, 0x46, 0x00, 0xF4, 0xDB, 0xF3, 0xFF, 0xFF, 0x07, 0xB4, 0x03, 0x36, 0x1B, 0x00,
+	 0x0E, 0xF0, 0x19, 0x60, 0x7B, 0xF3, 0xFF, 0xFF, 0xEF, 0xB4, 0x60, 0x44, 0x64, 0x40, 0x04, 0x27,
+	 0x07, 0x00, 0xA2, 0xDB, 0x13, 0x64, 0xCB, 0xFB, 0x01, 0x60, 0x67, 0x64, 0x37, 0xFB, 0x0B, 0x00,
+	 0x10, 0xBC, 0xA2, 0xDB, 0x08, 0x64, 0xCB, 0xFB, 0xA1, 0xF3, 0x01, 0x60, 0x67, 0x7C, 0x60, 0x40,
+	 0x01, 0x27, 0x5B, 0x7C, 0x37, 0xF9, 0x26, 0x46, 0x3F, 0xF2, 0x00, 0xF4, 0x60, 0x43, 0xF4, 0xA3,
+	 0x00, 0x60, 0x1D, 0x61, 0x00, 0x60, 0x2A, 0x65, 0x01, 0x60, 0xFF, 0x64, 0x40, 0x4C, 0xFD, 0x60,
+	 0x58, 0x4E, 0x7A, 0x78, 0xFF, 0xFF, 0x00, 0xBB, 0xFF, 0xFF, 0x01, 0x02, 0x3B, 0x00, 0x02, 0x60,
+	 0x01, 0x63, 0xA3, 0xD1, 0xDB, 0xF3, 0xFF, 0xFF, 0x07, 0xB4, 0x03, 0x36, 0x1F, 0x00, 0x19, 0x60,
+	 0x45, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x26, 0x09, 0x00, 0x19, 0x60, 0x7B, 0xF3, 0xFF, 0xFF,
+	 0xFD, 0xB4, 0x60, 0x44, 0x64, 0x40, 0x02, 0x27, 0x02, 0xBC, 0xA2, 0xDB, 0x19, 0x60, 0x45, 0xF3,
+	 0xFF, 0xFF, 0x60, 0x40, 0x02, 0x26, 0x1C, 0x00, 0x19, 0x60, 0x7B, 0xF3, 0xFF, 0xFF, 0xFB, 0xB4,
+	 0x60, 0x44, 0x64, 0x40, 0x04, 0x27, 0x04, 0xBC, 0xA2, 0xDB, 0x12, 0x00, 0x64, 0x40, 0x02, 0x2B,
+	 0x06, 0x00, 0x19, 0x60, 0x7B, 0xF3, 0xFF, 0xFF, 0x02, 0xBC, 0x60, 0x44, 0xA2, 0xDB, 0x64, 0x40,
+	 0x04, 0x2B, 0x06, 0x00, 0x19, 0x60, 0x7B, 0xF3, 0xFF, 0xFF, 0x04, 0xBC, 0x60, 0x44, 0xA2, 0xDB,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x0E, 0xF0, 0xDB, 0xF3, 0xFF, 0xFF, 0x07, 0xB4, 0x03, 0x36, 0x18, 0x00,
+	 0x19, 0x60, 0x7B, 0xF3, 0xFF, 0xFF, 0x02, 0xBC, 0x60, 0x44, 0xFB, 0xB4, 0x60, 0x44, 0x64, 0x40,
+	 0x20, 0x2A, 0x0A, 0x00, 0x60, 0x43, 0x19, 0x60, 0x45, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x02, 0x26,
+	 0x02, 0x00, 0x63, 0x44, 0x02, 0x00, 0x63, 0x44, 0x04, 0xBC, 0x19, 0x60, 0x7B, 0xFB, 0x09, 0x00,
+	 0x64, 0x40, 0x20, 0x26, 0x06, 0x00, 0x19, 0x60, 0x7B, 0xF3, 0xFF, 0xFF, 0x04, 0xBC, 0x60, 0x44,
+	 0xA2, 0xDB, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x60, 0xB0, 0x61, 0xB6, 0x60, 0x58, 0x4D, 0x25, 0x78,
+	 0xFF, 0xFF, 0x66, 0x44, 0x5C, 0xFB, 0x04, 0x64, 0x03, 0xFA, 0x80, 0x64, 0x2A, 0xFA, 0xC9, 0xF1,
+	 0x19, 0xF8, 0x00, 0x64, 0x3E, 0xFA, 0x00, 0x60, 0x80, 0x64, 0x0E, 0xFA, 0xA6, 0xF1, 0x07, 0xF8,
+	 0x67, 0x44, 0x2C, 0xFA, 0x2D, 0xFA, 0x2E, 0xFA, 0xF1, 0x60, 0x2C, 0x64, 0x08, 0x60, 0x31, 0xFB,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x5C, 0xF5, 0xEA, 0xF1, 0x2F, 0xF8, 0xEB, 0xF1, 0x30, 0xF8, 0xEC, 0xF1,
+	 0x31, 0xF8, 0x7F, 0xF1, 0x32, 0xF8, 0x80, 0xF1, 0x33, 0xF8, 0x81, 0xF1, 0x34, 0xF8, 0x16, 0x60,
+	 0xC2, 0xF1, 0x02, 0x64, 0x64, 0x40, 0xFE, 0x26, 0x10, 0xBC, 0x32, 0x40, 0x08, 0x26, 0x10, 0xBC,
+	 0x20, 0xBC, 0xFB, 0x60, 0xFF, 0x65, 0x60, 0x44, 0xA4, 0x84, 0x1B, 0x60, 0x09, 0xFB, 0x16, 0x60,
+	 0xC1, 0xF1, 0x33, 0x60, 0xBE, 0x64, 0x02, 0x18, 0x2D, 0x60, 0x32, 0x64, 0x1A, 0x60, 0xAD, 0xFB,
+	 0x1A, 0x60, 0xBD, 0xFB, 0x34, 0x60, 0x18, 0x61, 0x17, 0x60, 0x14, 0xF3, 0x35, 0x60, 0x36, 0x65,
+	 0xFE, 0xA4, 0xE0, 0x84, 0x06, 0x05, 0x67, 0x44, 0x1A, 0x60, 0xB5, 0xFB, 0x1A, 0x60, 0xC5, 0xFB,
+	 0x4B, 0x00, 0xE0, 0x84, 0xC4, 0x85, 0x1A, 0x60, 0x1F, 0xF3, 0xA5, 0xD1, 0xDA, 0x85, 0xA0, 0x83,
+	 0x1A, 0x60, 0x1B, 0xFD, 0xA5, 0xD1, 0x34, 0x60, 0x34, 0x62, 0xA0, 0x83, 0xA2, 0xDD, 0x67, 0x44,
+	 0x1A, 0x60, 0xB5, 0xFB, 0x1A, 0x60, 0xC5, 0xFB, 0x1A, 0x60, 0x2C, 0xF3, 0xFF, 0xFF, 0x21, 0x18,
+	 0x33, 0x60, 0xF4, 0x61, 0x0F, 0x60, 0x00, 0x7C, 0x00, 0x60, 0xAC, 0x65, 0xEF, 0x60, 0x58, 0x4D,
+	 0xC1, 0x78, 0xFF, 0xFF, 0x1A, 0x60, 0x2D, 0xF1, 0x59, 0xD9, 0x33, 0x60, 0xF2, 0x65, 0xD5, 0x84,
+	 0x30, 0x7F, 0xA5, 0xDB, 0x65, 0x44, 0x1A, 0x60, 0xB5, 0xFB, 0x1A, 0x60, 0xC5, 0xFB, 0x1A, 0x60,
+	 0x2C, 0xF3, 0xFF, 0xFF, 0xFE, 0xA4, 0xFF, 0xFF, 0x08, 0x24, 0x03, 0x00, 0xFF, 0x60, 0xFF, 0x64,
+	 0x13, 0x00, 0x34, 0x60, 0x18, 0x61, 0x50, 0x60, 0x00, 0x7C, 0x00, 0x60, 0xF2, 0x65, 0xEF, 0x60,
+	 0x58, 0x4D, 0xC1, 0x78, 0xFF, 0xFF, 0x1A, 0x60, 0x1D, 0xF1, 0x59, 0xD9, 0x34, 0x60, 0x12, 0x65,
+	 0xD5, 0x84, 0xDD, 0x7F, 0xA5, 0xDB, 0x65, 0x44, 0x1A, 0x60, 0xB2, 0xFB, 0x1A, 0x60, 0xC2, 0xFB,
+	 0x79, 0x00, 0x1A, 0x60, 0x1E, 0xF3, 0x34, 0x60, 0x34, 0x62, 0xFD, 0xA0, 0xA2, 0xD3, 0xEE, 0x03,
+	 0x60, 0x40, 0x02, 0x2A, 0x02, 0x00, 0x01, 0x63, 0x0B, 0x00, 0x04, 0x2A, 0x02, 0x00, 0x02, 0x63,
+	 0x07, 0x00, 0x10, 0x2A, 0x02, 0x00, 0x04, 0x63, 0x03, 0x00, 0x20, 0x2A, 0x01, 0x00, 0x05, 0x63,
+	 0x63, 0x47, 0xB4, 0x83, 0x59, 0xD9, 0x59, 0xDD, 0x1A, 0x60, 0x1E, 0xF3, 0x1A, 0x60, 0x1B, 0xF3,
+	 0xFE, 0xA0, 0x40, 0x4C, 0xD3, 0x03, 0x00, 0x60, 0x00, 0x63, 0x59, 0xDD, 0x41, 0x4A, 0x2C, 0x40,
+	 0x01, 0x2A, 0x05, 0x00, 0x00, 0x63, 0x63, 0x47, 0xB4, 0x83, 0x59, 0xD9, 0x59, 0xDD, 0x2C, 0x40,
+	 0x02, 0x2A, 0x03, 0x00, 0x01, 0x63, 0x59, 0xD9, 0x59, 0xDD, 0x2C, 0x40, 0x04, 0x2A, 0x05, 0x00,
+	 0x02, 0x63, 0x63, 0x47, 0xB4, 0x83, 0x59, 0xD9, 0x59, 0xDD, 0x2C, 0x40, 0x10, 0x2A, 0x05, 0x00,
+	 0x04, 0x63, 0x63, 0x47, 0xB4, 0x83, 0x59, 0xD9, 0x59, 0xDD, 0x2C, 0x40, 0x20, 0x2A, 0x05, 0x00,
+	 0x05, 0x63, 0x63, 0x47, 0xB4, 0x83, 0x59, 0xD9, 0x59, 0xDD, 0x2A, 0x44, 0x51, 0x93, 0xEB, 0x83,
+	 0xEB, 0x83, 0xA0, 0xDD, 0x1A, 0x60, 0x1E, 0xF3, 0x1A, 0x60, 0x1C, 0xF3, 0xFF, 0xA0, 0x40, 0x4C,
+	 0x9D, 0x03, 0x59, 0xDF, 0x41, 0x4A, 0x2C, 0x40, 0x01, 0x2A, 0x05, 0x00, 0x00, 0x63, 0x63, 0x47,
+	 0xB4, 0x83, 0x59, 0xD9, 0x59, 0xDD, 0x2C, 0x40, 0x02, 0x2A, 0x05, 0x00, 0x01, 0x63, 0x63, 0x47,
+	 0xB4, 0x83, 0x59, 0xD9, 0x59, 0xDD, 0x2C, 0x40, 0x04, 0x2A, 0x05, 0x00, 0x02, 0x63, 0x63, 0x47,
+	 0xB4, 0x83, 0x59, 0xD9, 0x59, 0xDD, 0x2A, 0x44, 0x51, 0x93, 0xEB, 0x83, 0xEB, 0x83, 0xA0, 0xDD,
+	 0x2D, 0x58, 0xFF, 0xFF, 0x00, 0x60, 0x04, 0x64, 0x08, 0x60, 0x0A, 0xFB, 0xF0, 0x60, 0x44, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x60, 0x12, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0x7D, 0xF1, 0x35, 0x60, 0xCC, 0x64, 0x64, 0x40, 0x01, 0x2B, 0x01, 0x00, 0x67, 0x44, 0x1A, 0x60,
+	 0xAF, 0xFB, 0x1A, 0x60, 0xBF, 0xFB, 0x1A, 0x60, 0xE7, 0xF9, 0x35, 0x60, 0x62, 0x65, 0xF1, 0x60,
+	 0x58, 0x4D, 0x74, 0x78, 0xFF, 0xFF, 0x7D, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x2B, 0x05, 0x00,
+	 0xFF, 0x60, 0xFF, 0x63, 0x1A, 0x60, 0xB3, 0xFD, 0x08, 0x00, 0x36, 0x60, 0x04, 0x63, 0x1A, 0x60,
+	 0xB3, 0xFD, 0xF1, 0x60, 0x58, 0x4D, 0x8C, 0x78, 0xFF, 0xFF, 0x5C, 0xF5, 0x00, 0xF4, 0x7E, 0xF1,
+	 0x06, 0xF8, 0x1B, 0x60, 0x09, 0xF3, 0x19, 0x60, 0x7B, 0xF1, 0xFB, 0x60, 0xFF, 0x65, 0x60, 0x44,
+	 0xA4, 0x84, 0x60, 0x47, 0x64, 0x40, 0x10, 0x26, 0x04, 0xBC, 0x60, 0x47, 0x07, 0xFA, 0x35, 0x60,
+	 0x5A, 0x64, 0x40, 0x48, 0x10, 0x61, 0x00, 0x60, 0x00, 0x64, 0xF1, 0x60, 0x58, 0x4D, 0x34, 0x78,
+	 0xFF, 0xFF, 0x5C, 0xF5, 0x3F, 0xFC, 0xDB, 0xFE, 0x25, 0x60, 0xCE, 0x64, 0x13, 0x60, 0x0D, 0xFB,
+	 0x66, 0x44, 0x5A, 0xDB, 0x04, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0xDB, 0xF3, 0x9B, 0xFE, 0xFD, 0xA0, 0x25, 0x04, 0x24, 0x02, 0x04, 0x64, 0x03, 0xFA,
+	 0x00, 0xF4, 0x09, 0xF2, 0xFF, 0xFF, 0x60, 0x47, 0x00, 0x3A, 0x1C, 0x00, 0x60, 0x43, 0x00, 0x36,
+	 0x1C, 0x00, 0xE0, 0xA0, 0xDA, 0x85, 0x16, 0x07, 0x33, 0x60, 0xBE, 0x61, 0xA1, 0xD1, 0xFF, 0xFF,
+	 0xD3, 0x80, 0xCB, 0x83, 0x0F, 0x02, 0x07, 0x0E, 0x59, 0xD3, 0xA5, 0xD0, 0xDA, 0x85, 0xD0, 0x80,
+	 0xFF, 0xFF, 0x08, 0x02, 0xF9, 0x1F, 0x12, 0x1E, 0xA5, 0xD0, 0x59, 0xD3, 0xFF, 0xFF, 0x90, 0x80,
+	 0xFF, 0x22, 0x0C, 0x00, 0xF1, 0x60, 0x2A, 0x78, 0xFF, 0xFF, 0x16, 0x60, 0xC1, 0xF3, 0xFF, 0xFF,
+	 0x60, 0x40, 0x01, 0x2A, 0x03, 0x00, 0x2D, 0x60, 0x32, 0x64, 0x02, 0x00, 0x33, 0x60, 0xBE, 0x64,
+	 0x1A, 0x60, 0xBD, 0xFB, 0x26, 0x46, 0x2F, 0xF2, 0x2C, 0xFA, 0x30, 0xF2, 0x2D, 0xFA, 0x31, 0xF2,
+	 0x2E, 0xFA, 0xEA, 0xF1, 0x2F, 0xF8, 0xEB, 0xF1, 0x30, 0xF8, 0xEC, 0xF1, 0x31, 0xF8, 0x7F, 0xF1,
+	 0x32, 0xF8, 0x80, 0xF1, 0x33, 0xF8, 0x81, 0xF1, 0x34, 0xF8, 0x00, 0x65, 0xFD, 0x60, 0x58, 0x4E,
+	 0xDD, 0x78, 0xFF, 0xFF, 0x61, 0x44, 0x19, 0x60, 0x3F, 0xFB, 0x50, 0x63, 0x2A, 0xFC, 0xC9, 0xF3,
+	 0x19, 0xFA, 0x00, 0x64, 0x3E, 0xFA, 0xA6, 0xF3, 0x07, 0xFA, 0x00, 0xF4, 0x7E, 0xF1, 0x06, 0xF8,
+	 0x1B, 0x60, 0x09, 0xF3, 0x19, 0x60, 0x7B, 0xF1, 0xFB, 0x60, 0xFF, 0xB7, 0x64, 0x40, 0x10, 0x26,
+	 0x04, 0xBC, 0x60, 0x47, 0x07, 0xFA, 0x35, 0x60, 0x82, 0x65, 0xF1, 0x60, 0x58, 0x4D, 0x74, 0x78,
+	 0xFF, 0xFF, 0x7D, 0xF3, 0x36, 0x60, 0x04, 0x63, 0x60, 0x40, 0x01, 0x27, 0x67, 0x43, 0x1A, 0x60,
+	 0xC3, 0xFD, 0x35, 0x60, 0x7A, 0x64, 0x40, 0x48, 0x10, 0x61, 0x00, 0x60, 0x00, 0x64, 0xF1, 0x60,
+	 0x58, 0x4D, 0x34, 0x78, 0xFF, 0xFF, 0x26, 0x46, 0x3F, 0xFC, 0x25, 0x60, 0xCE, 0x64, 0x13, 0x60,
+	 0x0D, 0xFB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE,
+	 0x00, 0x66, 0x46, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x64, 0x08, 0x60, 0x09, 0xFB, 0x5A, 0xDB,
+	 0x00, 0x64, 0x92, 0xFB, 0x2F, 0x58, 0xFF, 0xFF, 0x1B, 0x60, 0x0A, 0xFB, 0xCD, 0x81, 0x28, 0xD3,
+	 0x5A, 0x88, 0xDC, 0x83, 0x31, 0x18, 0xFB, 0x03, 0x61, 0x40, 0x7F, 0x3A, 0x06, 0x00, 0x1B, 0x60,
+	 0x0A, 0xF3, 0x03, 0x61, 0x7C, 0xA4, 0xA2, 0xDB, 0x00, 0xF4, 0x60, 0xFE, 0xA3, 0xD1, 0x5D, 0xD8,
+	 0x61, 0x40, 0x7F, 0x3A, 0x08, 0x00, 0x20, 0xFE, 0x1B, 0x60, 0x0A, 0xF3, 0x03, 0x61, 0x7C, 0xA4,
+	 0xA2, 0xDB, 0x00, 0xF4, 0x60, 0xFE, 0xBF, 0xD3, 0x5D, 0xDA, 0xFF, 0xB4, 0x00, 0x7F, 0x12, 0x03,
+	 0xDF, 0x83, 0x61, 0x40, 0x7F, 0x3A, 0x0A, 0x00, 0x20, 0xFE, 0x60, 0x45, 0x1B, 0x60, 0x0A, 0xF3,
+	 0x03, 0x61, 0x7C, 0xA4, 0xA2, 0xDB, 0x65, 0x44, 0x00, 0xF4, 0x60, 0xFE, 0xBD, 0xD1, 0xCC, 0x84,
+	 0x5D, 0xD8, 0xEF, 0x02, 0x20, 0xFE, 0xCB, 0x01, 0x1B, 0x60, 0x0A, 0xF1, 0xFD, 0xA1, 0xFF, 0xB1,
+	 0xC1, 0x83, 0xA2, 0xDD, 0x2D, 0x58, 0xFF, 0xFF, 0x67, 0x5C, 0x1C, 0x60, 0xE6, 0x61, 0xA1, 0xD3,
+	 0xA5, 0xD9, 0x10, 0x18, 0x60, 0x43, 0x35, 0x60, 0xD4, 0x64, 0xA5, 0xDB, 0x60, 0xFE, 0xA0, 0xDD,
+	 0x20, 0xFE, 0xDC, 0x84, 0xCF, 0x83, 0xE3, 0x83, 0x59, 0xD1, 0xDC, 0x84, 0x60, 0xFE, 0xA0, 0xD9,
+	 0x20, 0xFE, 0xFA, 0x1F, 0x2D, 0x58, 0xFF, 0xFF, 0x19, 0x60, 0x7B, 0xF3, 0x36, 0x60, 0x06, 0x62,
+	 0x07, 0xB4, 0x60, 0xFE, 0xA2, 0xDB, 0x20, 0xFE, 0x2D, 0x58, 0xFF, 0xFF, 0x0E, 0x57, 0x32, 0x40,
+	 0x40, 0x26, 0x27, 0x00, 0x45, 0x48, 0x00, 0x60, 0x10, 0x61, 0xB6, 0x60, 0x58, 0x4D, 0x22, 0x78,
+	 0xFF, 0xFF, 0x1F, 0x03, 0xF2, 0x60, 0x02, 0x64, 0x24, 0xFA, 0x00, 0x60, 0x48, 0x61, 0x28, 0x44,
+	 0x59, 0xDA, 0x03, 0x64, 0x38, 0x43, 0xBD, 0xD1, 0xCC, 0x84, 0x59, 0xD8, 0xFC, 0x02, 0x39, 0x44,
+	 0x59, 0xDA, 0x16, 0x60, 0xC3, 0xF3, 0x59, 0xDA, 0x07, 0x64, 0x23, 0xFA, 0x26, 0x60, 0x0A, 0x64,
+	 0x13, 0x60, 0x0D, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF,
+	 0xFA, 0xFE, 0x37, 0x58, 0xFF, 0xFF, 0x0E, 0x57, 0x32, 0x40, 0x40, 0x26, 0x1B, 0x00, 0x45, 0x48,
+	 0x00, 0x60, 0x06, 0x61, 0xB6, 0x60, 0x58, 0x4D, 0x22, 0x78, 0xFF, 0xFF, 0x13, 0x03, 0x02, 0x64,
+	 0x23, 0xFA, 0xF2, 0x60, 0x00, 0x64, 0x5A, 0xDA, 0x28, 0x44, 0x5A, 0xDA, 0xFF, 0xFF, 0x26, 0x60,
+	 0x0A, 0x64, 0x13, 0x60, 0x0D, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0xFA, 0xFE, 0x37, 0x58, 0xFF, 0xFF, 0xA0, 0xD3, 0xFF, 0xFF, 0xDC, 0x84, 0xDC, 0x80,
+	 0xD0, 0x80, 0x03, 0x03, 0xA2, 0xDB, 0x08, 0x24, 0xC6, 0xFE, 0xDD, 0x98, 0xFF, 0xFF, 0xB5, 0xF1,
+	 0xA0, 0xD3, 0xFF, 0xFF, 0xD8, 0x80, 0xC4, 0x84, 0x0C, 0x03, 0x08, 0x05, 0xDC, 0x80, 0xD0, 0x80,
+	 0x05, 0x03, 0xA2, 0xDB, 0x02, 0x24, 0xC6, 0xFE, 0xDD, 0x98, 0xFF, 0xFF, 0xFF, 0x60, 0xFE, 0x64,
+	 0xA2, 0xDB, 0xDD, 0x98, 0xFF, 0xFF, 0xA2, 0xFF, 0x32, 0x40, 0x40, 0x26, 0x3C, 0x00, 0x9B, 0xF3,
+	 0x67, 0x43, 0xDC, 0x84, 0xCC, 0x84, 0x37, 0x03, 0x60, 0x46, 0x0A, 0x02, 0x9B, 0xFD, 0x00, 0x60,
+	 0x46, 0x61, 0xB6, 0x60, 0x58, 0x4D, 0x22, 0x78, 0xFF, 0xFF, 0x66, 0x44, 0x9B, 0xFB, 0x2C, 0x03,
+	 0x46, 0x4B, 0x2C, 0x60, 0xCA, 0x61, 0x18, 0x64, 0x23, 0xFA, 0xF1, 0x60, 0x00, 0x64, 0x24, 0xFA,
+	 0x4A, 0x65, 0xA2, 0xFF, 0x2C, 0x63, 0x59, 0xD1, 0xA2, 0xDF, 0xA5, 0xD8, 0xDA, 0x85, 0x80, 0x3A,
+	 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0xF7, 0x1F, 0x12, 0x63, 0x59, 0xD1, 0xA5, 0xD8, 0xDA, 0x85,
+	 0x80, 0x3A, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0xF8, 0x1F, 0x26, 0x60, 0x0A, 0x64, 0x13, 0x60,
+	 0x0D, 0xFB, 0x2B, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xFA, 0xFE,
+	 0xA6, 0xFE, 0x00, 0x64, 0x9B, 0xFB, 0xA3, 0xFF, 0xCA, 0x60, 0xD4, 0x78, 0xFF, 0xFF, 0xA6, 0xFE,
+	 0xBA, 0x05, 0xA7, 0xFE, 0x11, 0x05, 0xA5, 0xFE, 0x03, 0x04, 0xF2, 0x60, 0xD8, 0x78, 0xFF, 0xFF,
+	 0xA4, 0xFE, 0xF2, 0x04, 0x08, 0x60, 0x0F, 0xF1, 0x00, 0x60, 0x80, 0x64, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xCF, 0xFE, 0xCA, 0x60, 0xD4, 0x78, 0xFF, 0xFF, 0x36, 0x45, 0x20, 0x60, 0xA8, 0x64, 0x44, 0xD7,
+	 0xFF, 0xFF, 0xFF, 0xFF, 0x9D, 0xF3, 0xFF, 0xFF, 0x01, 0xB0, 0x00, 0x64, 0x2F, 0x03, 0x9D, 0xFB,
+	 0x31, 0x44, 0xE8, 0xB4, 0x40, 0x51, 0x6A, 0x44, 0xFF, 0xFF, 0x80, 0x26, 0xFC, 0x01, 0x61, 0xFF,
+	 0x62, 0xFF, 0x08, 0x60, 0x30, 0xF1, 0x00, 0x60, 0x20, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x40, 0x60, 0x58, 0x4E, 0x7D, 0x78, 0xFF, 0xFF, 0x1F, 0x60, 0xC4, 0x64, 0x0F, 0x60, 0xE1, 0xFB,
+	 0x4A, 0xDF, 0x01, 0x60, 0xFE, 0x63, 0x1D, 0x60, 0xBE, 0x61, 0x00, 0x64, 0x59, 0xDB, 0xFE, 0x1F,
+	 0x0E, 0x60, 0xDD, 0xF3, 0xFF, 0xFF, 0x04, 0xB0, 0xFF, 0xFF, 0x05, 0x03, 0x02, 0x65, 0xF1, 0x60,
+	 0x58, 0x4E, 0xC3, 0x78, 0xFF, 0xFF, 0xCA, 0x60, 0xD4, 0x78, 0xFF, 0xFF, 0xF2, 0x60, 0xD8, 0x78,
+	 0xFF, 0xFF, 0x08, 0x60, 0x15, 0xF1, 0x00, 0x60, 0x01, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x37, 0x00, 0x2D, 0x60, 0xAA, 0x63, 0xBD, 0xD3, 0xBD, 0xD1, 0xBD, 0xD1, 0xB0, 0x84, 0xB0, 0x84,
+	 0xFF, 0xFF, 0x07, 0x02, 0x8A, 0xFB, 0x31, 0x44, 0xFE, 0xB4, 0x40, 0x51, 0x0D, 0x64, 0x05, 0xFB,
+	 0x27, 0x00, 0x28, 0xF3, 0x9D, 0xF1, 0x60, 0x47, 0x64, 0x41, 0x07, 0xB1, 0x07, 0xB4, 0x50, 0xFB,
+	 0x01, 0x61, 0x03, 0x03, 0xCC, 0x84, 0xE1, 0x81, 0xFD, 0x02, 0xA1, 0x80, 0xB1, 0x83, 0x18, 0x02,
+	 0x9D, 0xFD, 0x16, 0x60, 0xCF, 0xF3, 0xE4, 0xFB, 0x7D, 0xFB, 0x13, 0x60, 0x02, 0xF3, 0xFF, 0xFF,
+	 0x00, 0xA8, 0x60, 0x46, 0x46, 0x5E, 0x31, 0x44, 0x01, 0xBC, 0x40, 0x51, 0xED, 0xE2, 0x0F, 0x4E,
+	 0x1D, 0x60, 0x58, 0x4F, 0x9F, 0x78, 0xFF, 0xFF, 0x0E, 0x4F, 0xCA, 0x60, 0xD4, 0x78, 0xFF, 0xFF,
+	 0xD7, 0xFE, 0xCA, 0x60, 0xD4, 0x78, 0xFF, 0xFF, 0xF2, 0x60, 0xE4, 0x64, 0x08, 0x60, 0x3B, 0xFB,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x2F, 0x58, 0xFF, 0xFF, 0x00, 0x64, 0x08, 0x60, 0x27, 0xFB, 0x5A, 0xDB,
+	 0x10, 0x60, 0x4E, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60, 0x28, 0xF3,
+	 0xFF, 0xFF, 0x01, 0xB0, 0xFF, 0xFF, 0x1D, 0x03, 0x20, 0x40, 0x06, 0x23, 0x10, 0x00, 0x08, 0x60,
+	 0x27, 0xF1, 0x7F, 0x60, 0xFF, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x80, 0x60, 0x00, 0x64, 0x08, 0x60,
+	 0x28, 0xFB, 0xF2, 0x60, 0xF4, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x1D, 0x60,
+	 0xA9, 0x78, 0xFF, 0xFF, 0x08, 0x60, 0x27, 0xF1, 0x00, 0x60, 0x01, 0x64, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xCF, 0xFE, 0xC6, 0x01, 0x08, 0x60, 0x27, 0xF1, 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB,
+	 0xCF, 0xFE, 0xDB, 0xF3, 0x01, 0x63, 0xFD, 0xA0, 0x08, 0x60, 0x77, 0xFD, 0x07, 0x02, 0x08, 0x60,
+	 0x30, 0xF1, 0x00, 0x60, 0x01, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0xB1, 0x01, 0x0E, 0x57,
+	 0x32, 0x40, 0x40, 0x26, 0x1B, 0x00, 0x45, 0x48, 0x00, 0x60, 0x06, 0x61, 0xB6, 0x60, 0x58, 0x4D,
+	 0x22, 0x78, 0xFF, 0xFF, 0x13, 0x03, 0x02, 0x64, 0x23, 0xFA, 0xF2, 0x60, 0x04, 0x64, 0x5A, 0xDA,
+	 0x28, 0x44, 0x5A, 0xDA, 0xFF, 0xFF, 0x26, 0x60, 0x0A, 0x64, 0x13, 0x60, 0x0D, 0xFB, 0x66, 0x44,
+	 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xFA, 0xFE, 0x37, 0x58, 0xFF, 0xFF,
+	 0x08, 0x60, 0x15, 0xF1, 0x00, 0x60, 0x02, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x88, 0x01,
+	 0x12, 0x60, 0xF6, 0xF3, 0xFF, 0xFF, 0x00, 0xA8, 0x60, 0x46, 0x0E, 0xF2, 0x4B, 0x03, 0x60, 0x40,
+	 0xF0, 0x37, 0x38, 0x00, 0xFF, 0x37, 0x2D, 0x00, 0xFD, 0x37, 0x25, 0x00, 0xF8, 0x37, 0x0A, 0x00,
+	 0x60, 0x47, 0xFF, 0xB5, 0x10, 0x60, 0x12, 0x62, 0x46, 0xD1, 0x00, 0x60, 0x01, 0x64, 0xB0, 0x84,
+	 0xA2, 0xDB, 0xCF, 0xFE, 0x00, 0x64, 0x13, 0x60, 0x0D, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xDC, 0x01, 0x06, 0xB4, 0xFD, 0x7F, 0x0E, 0xFA, 0x25, 0x60,
+	 0xF2, 0x64, 0x13, 0x60, 0x0D, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF,
+	 0x2B, 0xFF, 0xF9, 0xFE, 0xCD, 0x01, 0x23, 0xF0, 0x60, 0x40, 0x04, 0x26, 0xED, 0x1B, 0x02, 0x26,
+	 0xEB, 0x18, 0xA2, 0xFF, 0x02, 0xF0, 0x09, 0x60, 0x08, 0x64, 0xD0, 0x80, 0xAD, 0xF3, 0x02, 0x02,
+	 0xCC, 0x84, 0xAD, 0xFB, 0x26, 0x60, 0x1A, 0x64, 0x40, 0x4B, 0x34, 0x60, 0x58, 0x4D, 0x08, 0x78,
+	 0xFF, 0xFF, 0xB6, 0x01, 0xAC, 0xFE, 0x09, 0x05, 0xAD, 0xFE, 0x0F, 0x05, 0xAE, 0xFE, 0xB0, 0x05,
+	 0xAF, 0xFE, 0x37, 0x05, 0xCA, 0x60, 0xD4, 0x78, 0xFF, 0xFF, 0x08, 0x60, 0x08, 0xF1, 0x20, 0x60,
+	 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0xF5, 0x01, 0x10, 0x60, 0x7A, 0x65, 0x0D, 0x61,
+	 0x07, 0x00, 0xA2, 0xDD, 0x58, 0x4F, 0x64, 0x58, 0xFF, 0xFF, 0x00, 0xB9, 0xFF, 0xFF, 0x08, 0x03,
+	 0x00, 0x63, 0xA5, 0xD1, 0x5A, 0xD3, 0xDA, 0x85, 0x00, 0xA8, 0xCD, 0x81, 0xF2, 0x02, 0xF8, 0x02,
+	 0xE1, 0x01, 0x10, 0x60, 0x0E, 0x62, 0x10, 0x60, 0x58, 0x65, 0xF3, 0x60, 0xD7, 0x63, 0x5A, 0xDF,
+	 0xD6, 0x80, 0xFF, 0xFF, 0x04, 0x03, 0x5A, 0xDF, 0x5A, 0xDF, 0x5A, 0xDD, 0xF9, 0x01, 0x10, 0x60,
+	 0x78, 0x65, 0x5A, 0xDF, 0xD6, 0x80, 0xFF, 0xFF, 0x02, 0x03, 0x5A, 0xDD, 0xFB, 0x01, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x10, 0x60, 0x12, 0x64, 0x40, 0x41, 0x10, 0x60, 0x10, 0x63, 0xA3, 0xD1, 0x00, 0x64,
+	 0xD0, 0x80, 0x0C, 0x61, 0x08, 0x03, 0xBD, 0xDB, 0xA3, 0xD3, 0xFF, 0xFF, 0xB0, 0x84, 0xCD, 0x81,
+	 0xA3, 0xDB, 0x06, 0xA3, 0xF9, 0x02, 0x10, 0x60, 0x60, 0x63, 0xA3, 0xD1, 0x00, 0x64, 0xD0, 0x80,
+	 0x0D, 0x61, 0x19, 0x03, 0xBD, 0xDB, 0x64, 0x44, 0xFE, 0xA3, 0x02, 0xA3, 0xCD, 0x81, 0xE8, 0x84,
+	 0xE3, 0x03, 0x02, 0x05, 0xE1, 0x03, 0xF9, 0x01, 0x97, 0xFB, 0x99, 0xFD, 0x61, 0x5C, 0xA3, 0xD3,
+	 0x98, 0xF9, 0x03, 0x18, 0x58, 0x4F, 0x60, 0x58, 0xFF, 0xFF, 0x99, 0xF3, 0x98, 0xF1, 0x60, 0x43,
+	 0x97, 0xF3, 0x64, 0x41, 0xEA, 0x01, 0x21, 0x43, 0x10, 0x60, 0x5A, 0x65, 0xD7, 0x80, 0xBD, 0xD1,
+	 0xBD, 0xD3, 0x03, 0x02, 0xCA, 0x60, 0xD4, 0x78, 0xFF, 0xFF, 0xA0, 0x84, 0xBD, 0xD1, 0x43, 0x41,
+	 0xF5, 0x03, 0xF3, 0x60, 0xDC, 0x64, 0x64, 0x58, 0x40, 0x4F, 0x2A, 0xF0, 0x83, 0x60, 0xFF, 0x65,
+	 0x64, 0x47, 0x03, 0x2B, 0x01, 0x00, 0x14, 0x00, 0x03, 0x26, 0x03, 0xAC, 0x60, 0x47, 0xA4, 0x84,
+	 0x2A, 0xFA, 0x2F, 0xF2, 0x2C, 0xFA, 0x30, 0xF2, 0x2D, 0xFA, 0x31, 0xF2, 0x2E, 0xFA, 0x64, 0x41,
+	 0xEA, 0xF3, 0x2F, 0xFA, 0x60, 0x43, 0xEB, 0xF3, 0x30, 0xFA, 0xEC, 0xF1, 0x31, 0xF8, 0x19, 0x00,
+	 0x60, 0x47, 0xA4, 0x84, 0x2A, 0xFA, 0x2F, 0xF2, 0x2C, 0xFA, 0x30, 0xF2, 0x2D, 0xFA, 0x31, 0xF2,
+	 0x2E, 0xFA, 0x36, 0xF2, 0x32, 0xFA, 0x37, 0xF2, 0x33, 0xFA, 0x38, 0xF2, 0x34, 0xFA, 0xEA, 0xF3,
+	 0x2F, 0xFA, 0x36, 0xFA, 0xEB, 0xF3, 0x30, 0xFA, 0x37, 0xFA, 0xEC, 0xF3, 0x31, 0xFA, 0x38, 0xFA,
+	 0x64, 0x41, 0x1C, 0xF2, 0x13, 0xFA, 0x00, 0xF4, 0x0D, 0xF2, 0xFF, 0xFF, 0x60, 0x40, 0x80, 0x2B,
+	 0x17, 0x00, 0x81, 0x67, 0xA2, 0xDA, 0xF4, 0x60, 0x58, 0x4E, 0xCF, 0x78, 0xFF, 0xFF, 0x26, 0x46,
+	 0x3F, 0xFC, 0x25, 0x60, 0xCE, 0x64, 0x13, 0x60, 0x0D, 0xFB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64,
+	 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xC1, 0xFE, 0x00, 0x66, 0x46, 0x46, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x26, 0x46, 0x3F, 0xF0, 0x42, 0x64, 0xD0, 0x80, 0xFF, 0xFF, 0x01, 0x04, 0x3F, 0xFA, 0x07, 0xF2,
+	 0xA6, 0xF1, 0x01, 0x1B, 0x07, 0xF8, 0x1C, 0xF2, 0x13, 0xFA, 0x26, 0xF2, 0x27, 0xF0, 0x60, 0x47,
+	 0x00, 0xF4, 0x1F, 0xFA, 0x64, 0x47, 0x20, 0xFA, 0x61, 0x44, 0x21, 0xFA, 0x01, 0x67, 0x0D, 0xFA,
+	 0x10, 0x61, 0x2D, 0x60, 0x5E, 0x64, 0x1E, 0x63, 0x58, 0xD1, 0xCD, 0x81, 0xBD, 0xD8, 0xFC, 0x02,
+	 0xB8, 0xF1, 0xD6, 0xF1, 0x64, 0x5E, 0x64, 0x5F, 0x44, 0x63, 0xBD, 0xDA, 0x16, 0x60, 0xAC, 0xF3,
+	 0xFF, 0xFF, 0xE0, 0x84, 0xE0, 0x84, 0xE0, 0x84, 0x4A, 0xD3, 0x60, 0x45, 0x60, 0x40, 0x01, 0x36,
+	 0x03, 0x64, 0x02, 0x36, 0x01, 0x64, 0xB4, 0x84, 0x06, 0xA2, 0xA2, 0xD1, 0xBD, 0xDA, 0x64, 0x47,
+	 0xBD, 0xDA, 0xD3, 0xF3, 0xD4, 0xF1, 0x60, 0x47, 0xBD, 0xDA, 0x64, 0x47, 0xE2, 0xF1, 0xBD, 0xDA,
+	 0x64, 0x44, 0xBD, 0xDA, 0x26, 0x46, 0x00, 0x64, 0x23, 0xF0, 0x3B, 0xF0, 0x64, 0x40, 0x10, 0x2A,
+	 0x06, 0x00, 0xC0, 0x67, 0xA0, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0xE8, 0x84, 0x10, 0xBC, 0x3E, 0xFA,
+	 0x25, 0x60, 0xDA, 0x64, 0x13, 0x60, 0x0D, 0xFB, 0x26, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB,
+	 0xFF, 0xFF, 0x2B, 0xFF, 0xC8, 0xFE, 0x00, 0x66, 0x46, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0xB1, 0xF3,
+	 0x1F, 0xFA, 0x32, 0x47, 0x07, 0xFA, 0x24, 0x7E, 0x01, 0x7F, 0x08, 0xFA, 0xD6, 0xF1, 0x09, 0xF8,
+	 0x01, 0x60, 0x01, 0x64, 0x0A, 0xFA, 0x01, 0x64, 0x0B, 0xFA, 0x18, 0x64, 0x13, 0x60, 0x0D, 0xFB,
+	 0x66, 0x44, 0x5A, 0xDB, 0x0A, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x52, 0x63, 0x2E, 0x58,
+	 0xFF, 0xFF, 0x00, 0x60, 0x2A, 0x61, 0xB6, 0x60, 0x58, 0x4D, 0x25, 0x78, 0xFF, 0xFF, 0x66, 0x44,
+	 0x5D, 0xFB, 0x04, 0x64, 0x03, 0xFA, 0x67, 0x44, 0x2C, 0xFA, 0x2D, 0xFA, 0x2E, 0xFA, 0x32, 0xFA,
+	 0x33, 0xFA, 0x34, 0xFA, 0x12, 0x60, 0x80, 0x64, 0xA6, 0xF1, 0x0E, 0xFA, 0x07, 0xF8, 0x00, 0x64,
+	 0x3E, 0xFA, 0x0E, 0x60, 0x3D, 0xFB, 0x06, 0xA2, 0x10, 0x60, 0x80, 0x64, 0xA2, 0xDB, 0x04, 0x64,
+	 0x5A, 0xDB, 0x06, 0x64, 0x5A, 0xDB, 0xF8, 0x60, 0xCF, 0x64, 0x08, 0x60, 0x3F, 0xFB, 0x00, 0x64,
+	 0x0E, 0x60, 0x43, 0xFB, 0x06, 0xA2, 0x10, 0x60, 0x84, 0x64, 0xA2, 0xDB, 0x08, 0x64, 0x5A, 0xDB,
+	 0x06, 0x64, 0x5A, 0xDB, 0xF8, 0x60, 0xD8, 0x64, 0x08, 0x60, 0x41, 0xFB, 0xF8, 0x60, 0xB4, 0x64,
+	 0x08, 0x60, 0x34, 0xFB, 0x00, 0x60, 0x30, 0x64, 0x08, 0x60, 0x13, 0xFB, 0xF5, 0x60, 0x31, 0x64,
+	 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x2F, 0x58, 0xFF, 0xFF, 0xF7, 0x60, 0x6C, 0x78,
+	 0xFF, 0xFF, 0x5D, 0xF5, 0xEA, 0xF1, 0x2F, 0xF8, 0xEB, 0xF1, 0x30, 0xF8, 0xEC, 0xF1, 0x31, 0xF8,
+	 0xC9, 0xF1, 0x19, 0xF8, 0x00, 0x63, 0x88, 0xFD, 0x1B, 0x60, 0xB2, 0x63, 0x86, 0xFD, 0x87, 0xFD,
+	 0x20, 0x40, 0x10, 0x2B, 0x00, 0x00, 0x5D, 0xF5, 0x40, 0x64, 0x2A, 0xFA, 0x7D, 0xF3, 0x7C, 0xFB,
+	 0x08, 0x60, 0x12, 0xF1, 0x00, 0x60, 0x10, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x03, 0x03, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x03, 0x00, 0xF6, 0x60, 0xC6, 0x78, 0xFF, 0xFF, 0x19, 0x60, 0x3D, 0xF3, 0xFD, 0x60,
+	 0x58, 0x4E, 0xAC, 0x78, 0xFF, 0xFF, 0x19, 0x60, 0x3F, 0xFB, 0x19, 0x60, 0x39, 0xF3, 0x3F, 0x40,
+	 0x01, 0x27, 0x08, 0x00, 0x0F, 0x60, 0xFF, 0x65, 0xA4, 0x84, 0xFC, 0x60, 0x58, 0x4E, 0x34, 0x78,
+	 0xFF, 0xFF, 0x05, 0x00, 0x0F, 0xB4, 0xFC, 0x60, 0x58, 0x4E, 0x34, 0x78, 0xFF, 0xFF, 0x5D, 0xF5,
+	 0x35, 0x60, 0x70, 0x64, 0x00, 0xF4, 0x40, 0x48, 0x2F, 0x60, 0x24, 0x64, 0x20, 0x40, 0x10, 0x27,
+	 0x02, 0x00, 0x2F, 0x60, 0x02, 0x64, 0x28, 0xDB, 0x04, 0x61, 0x00, 0x60, 0x00, 0x64, 0xF1, 0x60,
+	 0x58, 0x4D, 0x34, 0x78, 0xFF, 0xFF, 0x5D, 0xF5, 0x3F, 0xFC, 0x01, 0x64, 0x54, 0xF1, 0x10, 0x60,
+	 0x12, 0xFB, 0x7D, 0xFB, 0xA4, 0xD3, 0x04, 0x65, 0x53, 0xF3, 0x01, 0x18, 0x0C, 0x65, 0xF3, 0xB4,
+	 0xB4, 0x84, 0x53, 0xFB, 0x0D, 0x00, 0xF7, 0x60, 0x6C, 0x78, 0xFF, 0xFF, 0x53, 0xF1, 0x7D, 0xF3,
+	 0xFF, 0xFF, 0xF3, 0xA0, 0x04, 0xA4, 0x01, 0x04, 0xF1, 0xA4, 0x10, 0x36, 0xF4, 0x01, 0x7D, 0xFB,
+	 0x20, 0x40, 0x10, 0x2B, 0x10, 0x00, 0x7D, 0xF3, 0x32, 0x60, 0x80, 0x61, 0xA1, 0xD1, 0xCC, 0x84,
+	 0x01, 0x61, 0x08, 0x24, 0x03, 0x00, 0xE1, 0x81, 0xCC, 0x84, 0xFB, 0x01, 0xA1, 0x84, 0x53, 0xF1,
+	 0xE6, 0x03, 0x10, 0x60, 0x12, 0xFB, 0x7D, 0xF3, 0x10, 0x60, 0xF2, 0x61, 0xCC, 0x84, 0xFF, 0xFF,
+	 0x02, 0x03, 0x06, 0xA1, 0xFB, 0x01, 0xA1, 0xD3, 0x53, 0xF1, 0x01, 0xB0, 0x02, 0xB0, 0xD7, 0x03,
+	 0x64, 0x40, 0x01, 0x26, 0x05, 0x00, 0x20, 0x40, 0x10, 0x27, 0x02, 0x00, 0xD0, 0x03, 0x00, 0x00,
+	 0x9D, 0xFE, 0x3D, 0x05, 0xBA, 0xFE, 0x10, 0x60, 0x24, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE,
+	 0x0A, 0x04, 0x40, 0x60, 0x00, 0x64, 0x08, 0x60, 0x13, 0xFB, 0xF5, 0x60, 0xCB, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x60, 0x24, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x7D, 0xF1,
+	 0x13, 0x60, 0x1A, 0xF9, 0x08, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x20, 0x60, 0x00, 0x64,
+	 0x08, 0x60, 0x13, 0xFB, 0xF5, 0x60, 0xF0, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0xBE, 0xFE, 0x08, 0x60, 0x08, 0xF1, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x1B, 0x60, 0xF3, 0xF1, 0xAD, 0x4F, 0x00, 0x7F, 0xFA, 0xB4, 0x64, 0x41, 0x7D, 0xF1, 0x02, 0xB1,
+	 0x04, 0x65, 0x02, 0x02, 0x64, 0x40, 0x01, 0x2B, 0x01, 0x65, 0xB4, 0x84, 0xA0, 0x5D, 0x10, 0x60,
+	 0x24, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0xDE, 0xFE, 0x0A, 0x04, 0x40, 0x60, 0x00, 0x64, 0x08, 0x60,
+	 0x13, 0xFB, 0xF5, 0x60, 0xC8, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x7D, 0xF1,
+	 0x13, 0x60, 0x1A, 0xF9, 0x0E, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x20, 0x60, 0x00, 0x64,
+	 0x08, 0x60, 0x13, 0xFB, 0xF6, 0x60, 0x28, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0xBE, 0xFE, 0x08, 0x60, 0x08, 0xF1, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE,
+	 0x10, 0x60, 0x24, 0x62, 0x00, 0x64, 0xA2, 0xDB, 0x5D, 0xF5, 0x25, 0x60, 0xCE, 0x64, 0x13, 0x60,
+	 0x0D, 0xFB, 0x66, 0x44, 0x5A, 0xDB, 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0x00, 0x64,
+	 0x51, 0xFB, 0x00, 0x60, 0x01, 0x64, 0x08, 0x60, 0x13, 0xFB, 0xF6, 0x60, 0x4C, 0x64, 0x5A, 0xDB,
+	 0xCF, 0xFE, 0xC1, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x10, 0x60, 0x24, 0x62, 0x00, 0x64, 0xA2, 0xDB,
+	 0xC3, 0xF1, 0x0E, 0x60, 0x3F, 0xF9, 0x1C, 0x60, 0x7A, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x02, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0xC4, 0xF1, 0x0E, 0x60, 0x45, 0xF9, 0x26, 0x60, 0x42, 0x62,
+	 0xA2, 0xD3, 0xFF, 0xFF, 0xFD, 0x1B, 0x1C, 0x60, 0x86, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x02, 0x64,
+	 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x00, 0x60, 0x08, 0x64, 0x08, 0x60, 0x13, 0xFB, 0xF6, 0x60,
+	 0x75, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x51, 0xF1, 0x10, 0x60, 0x24, 0x62,
+	 0x00, 0x64, 0xA2, 0xDB, 0x64, 0x40, 0xFF, 0x26, 0x0B, 0x00, 0x53, 0xF3, 0xFF, 0xFF, 0x80, 0xB0,
+	 0xFF, 0xFF, 0x03, 0x03, 0xF7, 0x60, 0x65, 0x78, 0xFF, 0xFF, 0xF5, 0x60, 0x96, 0x78, 0xFF, 0xFF,
+	 0x02, 0x0A, 0x00, 0x64, 0x51, 0xFB, 0xC5, 0xF1, 0x0E, 0x60, 0x45, 0xF9, 0x00, 0x60, 0x0C, 0x64,
+	 0x08, 0x60, 0x13, 0xFB, 0xF6, 0x60, 0xA0, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x1C, 0x60, 0x86, 0x64,
+	 0x13, 0x60, 0x22, 0xFB, 0x02, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x08, 0x60, 0x12, 0xF1, 0x00, 0x60, 0x04, 0x64, 0xA0, 0x80, 0x9C, 0x84, 0x0B, 0x03, 0xA0, 0x84,
+	 0xA2, 0xDB, 0x1C, 0x60, 0x86, 0x64, 0x13, 0x60, 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF,
+	 0x04, 0xFF, 0x13, 0x00, 0xFF, 0x60, 0xF7, 0x64, 0xA0, 0x84, 0xA2, 0xDB, 0x51, 0xF3, 0xDE, 0x0A,
+	 0x00, 0xA0, 0x00, 0x64, 0x02, 0x03, 0x51, 0xFB, 0xD9, 0x01, 0x1C, 0x60, 0x7A, 0x64, 0x13, 0x60,
+	 0x22, 0xFB, 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0xB7, 0x01, 0x19, 0x60, 0x3E, 0xF3,
+	 0xFD, 0x60, 0x58, 0x4E, 0xAC, 0x78, 0xFF, 0xFF, 0x19, 0x60, 0x3F, 0xFB, 0x19, 0x60, 0x3A, 0xF3,
+	 0x0F, 0x60, 0xFF, 0x65, 0xA4, 0x84, 0xFC, 0x60, 0x58, 0x4E, 0x34, 0x78, 0xFF, 0xFF, 0x5D, 0xF5,
+	 0x35, 0x60, 0x70, 0x64, 0x00, 0xF4, 0x40, 0x48, 0x2F, 0x60, 0x24, 0x64, 0x20, 0x40, 0x10, 0x27,
+	 0x02, 0x00, 0x2F, 0x60, 0x02, 0x64, 0x28, 0xDB, 0x04, 0x61, 0x00, 0x60, 0x00, 0x64, 0xF1, 0x60,
+	 0x58, 0x4D, 0x34, 0x78, 0xFF, 0xFF, 0x5D, 0xF5, 0x3F, 0xFC, 0x53, 0xF3, 0x20, 0x40, 0x10, 0x23,
+	 0x02, 0x00, 0x20, 0xBC, 0x04, 0x00, 0x60, 0x40, 0x01, 0x22, 0x40, 0xBC, 0x04, 0xBC, 0x80, 0xBC,
+	 0x53, 0xFB, 0x11, 0x60, 0x62, 0x64, 0x08, 0x60, 0x6C, 0xFB, 0x06, 0x64, 0x08, 0x60, 0x73, 0xFB,
+	 0x19, 0x60, 0x43, 0xF3, 0xFF, 0xFF, 0x07, 0xB4, 0xA2, 0xDB, 0x53, 0xF3, 0x08, 0x60, 0x6C, 0xF1,
+	 0x60, 0x40, 0x20, 0x26, 0x03, 0x00, 0x01, 0x26, 0x32, 0x00, 0x45, 0x00, 0x08, 0x60, 0x73, 0xF3,
+	 0xFF, 0xFF, 0xDD, 0xA0, 0x01, 0xA4, 0x58, 0x03, 0xA2, 0xDB, 0x32, 0x60, 0x82, 0x61, 0xE0, 0xA0,
+	 0xF0, 0xA0, 0x05, 0x05, 0x01, 0x05, 0x05, 0x00, 0x02, 0xA1, 0xF0, 0xA4, 0x02, 0x00, 0x04, 0xA1,
+	 0xE0, 0xA4, 0xA1, 0xD1, 0x01, 0x61, 0xDC, 0x84, 0xCC, 0x84, 0xFF, 0xFF, 0x02, 0x03, 0xE1, 0x81,
+	 0xFB, 0x01, 0xA1, 0x80, 0x10, 0x60, 0xE6, 0x64, 0x01, 0x02, 0xE0, 0x01, 0xA0, 0xD3, 0x11, 0x60,
+	 0x5A, 0x63, 0xFA, 0xA4, 0xCC, 0x84, 0x08, 0xA3, 0xFD, 0x02, 0xCF, 0xF1, 0xA3, 0xD3, 0x01, 0x18,
+	 0xD5, 0x18, 0xFE, 0xA3, 0xA3, 0xD3, 0x7D, 0xFB, 0xF5, 0x60, 0xC8, 0x78, 0xFF, 0xFF, 0x12, 0x60,
+	 0x40, 0x65, 0x64, 0x41, 0xA1, 0xD3, 0xD5, 0x80, 0x00, 0xB8, 0x26, 0x07, 0x02, 0x02, 0x08, 0xA1,
+	 0xF9, 0x01, 0x61, 0x44, 0x08, 0x60, 0x6C, 0xFB, 0x01, 0x64, 0xA1, 0xDB, 0x49, 0xD3, 0x7D, 0xFB,
+	 0xF5, 0x60, 0xC8, 0x78, 0xFF, 0xFF, 0x12, 0x60, 0x40, 0x65, 0x64, 0x41, 0xA1, 0xD3, 0xD5, 0x80,
+	 0x04, 0xB0, 0x12, 0x07, 0x02, 0x02, 0x08, 0xA1, 0xF9, 0x01, 0x61, 0x44, 0x08, 0x60, 0x6C, 0xFB,
+	 0x49, 0xD3, 0x7D, 0xFB, 0xF5, 0x60, 0xC8, 0x78, 0xFF, 0xFF, 0x10, 0x60, 0xD8, 0x65, 0xA5, 0xD3,
+	 0xFF, 0xFF, 0x08, 0xA4, 0xA5, 0xDB, 0x99, 0x01, 0x1C, 0x60, 0x7A, 0x64, 0x13, 0x60, 0x22, 0xFB,
+	 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x53, 0xF3, 0xFF, 0xFF, 0xE3, 0xB4, 0x53, 0xFB,
+	 0x10, 0x60, 0x10, 0xF3, 0xFF, 0xFF, 0xFE, 0xB4, 0xA2, 0xDB, 0x10, 0x60, 0x24, 0x62, 0x00, 0x64,
+	 0xA2, 0xDB, 0xDE, 0xFE, 0x0A, 0x04, 0x40, 0x60, 0x00, 0x64, 0x08, 0x60, 0x13, 0xFB, 0xF7, 0x60,
+	 0x7D, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x7C, 0xF1, 0x7D, 0xF9, 0x13, 0x60,
+	 0x1A, 0xF9, 0x0E, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x2D, 0xFF, 0x20, 0x60, 0x00, 0x64, 0x08, 0x60,
+	 0x13, 0xFB, 0xF7, 0x60, 0x9F, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0xBE, 0xFE,
+	 0x08, 0x60, 0x08, 0xF1, 0x40, 0x60, 0x00, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x53, 0xF3,
+	 0xFF, 0xFF, 0x80, 0xB0, 0xFF, 0xFF, 0x54, 0x02, 0x1C, 0x60, 0x32, 0x63, 0x1C, 0x61, 0xCD, 0x81,
+	 0xBD, 0xDF, 0xFD, 0x02, 0x14, 0x60, 0x32, 0x61, 0x88, 0xF3, 0x61, 0x43, 0xC4, 0xA5, 0x47, 0xD1,
+	 0x0F, 0x04, 0xBE, 0xD5, 0x1C, 0x60, 0x2E, 0x63, 0xC3, 0x83, 0xC3, 0x83, 0xC3, 0x83, 0x43, 0xD3,
+	 0xBE, 0xD1, 0xDC, 0x84, 0xA3, 0xDB, 0x66, 0x44, 0xC0, 0x84, 0xBE, 0xDB, 0x65, 0x44, 0xED, 0x01,
+	 0x1C, 0x60, 0x32, 0x63, 0x0E, 0x61, 0x41, 0x4B, 0xBD, 0xD3, 0xBD, 0xD1, 0x00, 0xBD, 0x64, 0x41,
+	 0x19, 0x03, 0x01, 0xA8, 0x61, 0x44, 0x02, 0xA8, 0x15, 0x03, 0x02, 0x02, 0xE9, 0x84, 0x12, 0x00,
+	 0x65, 0x47, 0x60, 0x45, 0x61, 0x44, 0x09, 0x61, 0xCD, 0x81, 0xE0, 0x84, 0xFF, 0x23, 0xFC, 0x01,
+	 0x02, 0x24, 0xC4, 0x84, 0x02, 0x28, 0xD4, 0x84, 0xCD, 0x81, 0x01, 0x0E, 0x01, 0xBC, 0x02, 0x03,
+	 0xE0, 0x84, 0xF6, 0x01, 0x00, 0x7F, 0x2B, 0x41, 0x4D, 0x8B, 0xBF, 0xDB, 0xDD, 0x02, 0x14, 0x60,
+	 0x32, 0x61, 0x88, 0xF3, 0x61, 0x43, 0xC4, 0xA5, 0x47, 0xD1, 0x0A, 0x04, 0xDA, 0x86, 0x1C, 0x60,
+	 0x30, 0x63, 0xC3, 0x83, 0xC3, 0x83, 0xC3, 0x83, 0x43, 0xD1, 0xA6, 0xD9, 0x65, 0x44, 0xF2, 0x01,
+	 0x53, 0xF3, 0x88, 0xF1, 0xF3, 0xB4, 0x53, 0xFB, 0x14, 0x60, 0x32, 0x63, 0xC3, 0x85, 0x45, 0x4A,
+	 0x1B, 0x60, 0xB2, 0x65, 0x87, 0xF3, 0x45, 0x4C, 0x40, 0x48, 0x2A, 0x45, 0xD7, 0x80, 0x02, 0x65,
+	 0x17, 0x05, 0x47, 0xD1, 0x02, 0x65, 0x47, 0xD3, 0x0A, 0x65, 0xD0, 0x81, 0x47, 0xD3, 0x01, 0x05,
+	 0x00, 0x61, 0xF2, 0xA3, 0x01, 0xB0, 0x61, 0x44, 0x05, 0x03, 0x2C, 0xDB, 0x5A, 0xDD, 0x5A, 0x8C,
+	 0x3C, 0xA3, 0xEB, 0x01, 0x28, 0x42, 0x4A, 0xDD, 0x4A, 0xDB, 0x42, 0x48, 0x3C, 0xA3, 0xE5, 0x01,
+	 0x28, 0x44, 0x86, 0xFB, 0x86, 0xF1, 0x1B, 0x60, 0xB2, 0x63, 0x44, 0x48, 0x28, 0x45, 0xD7, 0x80,
+	 0xA3, 0xD1, 0x15, 0x05, 0x04, 0x65, 0x46, 0xD3, 0x28, 0x45, 0xD6, 0x80, 0xD0, 0x80, 0x02, 0x04,
+	 0x04, 0xA3, 0xF5, 0x01, 0xF7, 0x06, 0x62, 0x46, 0xA2, 0xD9, 0xA3, 0xDB, 0x5B, 0xD3, 0x66, 0x42,
+	 0x5A, 0xD1, 0xA2, 0xDB, 0xA3, 0xD9, 0xFE, 0xA3, 0xA3, 0xD1, 0x66, 0x42, 0xEB, 0x01, 0x86, 0xF3,
+	 0x87, 0xF1, 0x60, 0x43, 0x44, 0x48, 0x28, 0x45, 0xD7, 0x80, 0xA3, 0xD1, 0x15, 0x05, 0x04, 0x65,
+	 0x46, 0xD3, 0x28, 0x45, 0xD6, 0x80, 0xD0, 0x80, 0x02, 0x04, 0x04, 0xA3, 0xF5, 0x01, 0xF7, 0x06,
+	 0x62, 0x46, 0xA2, 0xD9, 0xA3, 0xDB, 0x5B, 0xD3, 0x66, 0x42, 0x5A, 0xD1, 0xA2, 0xDB, 0xA3, 0xD9,
+	 0xFE, 0xA3, 0xA3, 0xD1, 0x66, 0x42, 0xEB, 0x01, 0x08, 0x60, 0x08, 0xF1, 0x10, 0x60, 0x00, 0x64,
+	 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x7D, 0xF1, 0x19, 0x60, 0x3D, 0xF3, 0x64, 0x40, 0x01, 0x27,
+	 0x27, 0x00, 0xFD, 0x60, 0x58, 0x4E, 0xAC, 0x78, 0xFF, 0xFF, 0x19, 0x60, 0x3F, 0xFB, 0x19, 0x60,
+	 0x39, 0xF3, 0x3F, 0x40, 0x01, 0x27, 0x16, 0x00, 0x0F, 0x60, 0xFF, 0x65, 0x60, 0x41, 0xDB, 0xF3,
+	 0xFF, 0xFF, 0x60, 0x40, 0x03, 0x36, 0x07, 0x00, 0x19, 0x60, 0x44, 0xF3, 0xFF, 0xFF, 0x60, 0x40,
+	 0x01, 0x2A, 0x01, 0x00, 0x0F, 0x61, 0x61, 0x44, 0xA4, 0x84, 0xFC, 0x60, 0x58, 0x4E, 0x34, 0x78,
+	 0xFF, 0xFF, 0x16, 0x00, 0x0F, 0xB4, 0xFC, 0x60, 0x58, 0x4E, 0x34, 0x78, 0xFF, 0xFF, 0x10, 0x00,
+	 0x5A, 0xD3, 0xFD, 0x60, 0x58, 0x4E, 0xAC, 0x78, 0xFF, 0xFF, 0x19, 0x60, 0x3F, 0xFB, 0x19, 0x60,
+	 0x3A, 0xF3, 0x0F, 0x60, 0xFF, 0x65, 0xA4, 0x84, 0xFC, 0x60, 0x58, 0x4E, 0x34, 0x78, 0xFF, 0xFF,
+	 0x00, 0x60, 0x30, 0x64, 0x08, 0x60, 0x13, 0xFB, 0xF5, 0x60, 0x31, 0x64, 0x5A, 0xDB, 0xCF, 0xFE,
+	 0x2F, 0x58, 0xFF, 0xFF, 0x2F, 0x58, 0xFF, 0xFF, 0x1C, 0x60, 0x7A, 0x64, 0x13, 0x60, 0x22, 0xFB,
+	 0x03, 0x64, 0x4A, 0xDB, 0xFF, 0xFF, 0x04, 0xFF, 0x00, 0x64, 0x53, 0xFB, 0x00, 0x64, 0x08, 0x60,
+	 0x12, 0xFB, 0x5A, 0xDB, 0xBE, 0xFE, 0x00, 0x60, 0x30, 0x64, 0x08, 0x60, 0x13, 0xFB, 0xF5, 0x60,
+	 0x31, 0x64, 0x5A, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF, 0x2F, 0x58, 0xFF, 0xFF, 0x08, 0x60,
+	 0x12, 0xF1, 0x00, 0x60, 0x04, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x2F, 0x58, 0xFF, 0xFF,
+	 0x08, 0x60, 0x12, 0xF1, 0x00, 0x60, 0x08, 0x64, 0xB0, 0x84, 0xA2, 0xDB, 0xCF, 0xFE, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x20, 0x40, 0x90, 0x2B, 0x03, 0x00, 0xFB, 0x60, 0xFC, 0x78, 0xFF, 0xFF, 0x53, 0xF3,
+	 0x88, 0xF1, 0x04, 0xB0, 0x07, 0x60, 0x80, 0x64, 0xD0, 0x80, 0x20, 0x03, 0x1F, 0x06, 0x26, 0x46,
+	 0x88, 0xF1, 0x14, 0x60, 0x32, 0x63, 0xC3, 0x83, 0x7D, 0xF3, 0x26, 0xF0, 0xBD, 0xDB, 0x64, 0x44,
+	 0x00, 0x7F, 0xBD, 0xDB, 0x64, 0x47, 0x00, 0x7F, 0xBD, 0xDB, 0x32, 0xF0, 0xBD, 0xD9, 0x33, 0xF0,
+	 0xBD, 0xD9, 0x34, 0xF0, 0xBD, 0xD9, 0x00, 0xF4, 0x0D, 0xF0, 0xBD, 0xD9, 0x0E, 0xF0, 0xBD, 0xD9,
+	 0x0F, 0xF0, 0xA3, 0xDF, 0x64, 0x47, 0x60, 0x45, 0x00, 0x37, 0x03, 0x00, 0xFB, 0x60, 0xF7, 0x78,
+	 0xFF, 0xFF, 0xBD, 0xDB, 0xE0, 0xA0, 0x1F, 0x61, 0x00, 0xB8, 0xF8, 0x07, 0xF7, 0x03, 0x60, 0xFE,
+	 0x5D, 0xD0, 0xCC, 0x84, 0xBD, 0xD9, 0xFC, 0x02, 0x65, 0x40, 0x01, 0x26, 0xDF, 0x83, 0x5D, 0xD0,
+	 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x3A, 0x03, 0x00, 0x5D, 0xD0, 0xFF, 0xFF, 0xC1, 0x81, 0x5D, 0xD0,
+	 0xFF, 0xFF, 0x64, 0x40, 0x03, 0x36, 0x07, 0x00, 0x53, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x80, 0x2A,
+	 0xDD, 0x01, 0xCD, 0x81, 0x13, 0x00, 0x53, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x80, 0x2A, 0x04, 0x00,
+	 0x5D, 0xD0, 0xFF, 0xFF, 0xC1, 0x81, 0x0A, 0x00, 0x59, 0xD0, 0x7D, 0xF3, 0xFF, 0xFF, 0xD0, 0x80,
+	 0x20, 0xFE, 0x08, 0x24, 0x03, 0x00, 0xFB, 0x60, 0xF7, 0x78, 0xFF, 0xFF, 0x7C, 0x44, 0x1A, 0x60,
+	 0x24, 0xFB, 0x1A, 0x60, 0x25, 0xFB, 0x1A, 0x60, 0x26, 0xFB, 0x1A, 0x60, 0x27, 0xFB, 0x1C, 0x60,
+	 0x08, 0xFB, 0x1C, 0x60, 0x04, 0xFB, 0x00, 0x64, 0x1C, 0x60, 0x04, 0xFB, 0x20, 0xFE, 0x37, 0x60,
+	 0xFE, 0x64, 0x40, 0x4A, 0xF9, 0x60, 0x58, 0x4D, 0xC3, 0x78, 0xFF, 0xFF, 0x1C, 0x60, 0x04, 0xF3,
+	 0xFF, 0xFF, 0x09, 0x18, 0xFF, 0xFF, 0x1C, 0x60, 0x06, 0xF3, 0x1C, 0x60, 0x07, 0xF5, 0x60, 0x41,
+	 0x00, 0x64, 0x1C, 0x60, 0x04, 0xFB, 0x20, 0xFE, 0x2A, 0xD1, 0xDA, 0x85, 0x64, 0x44, 0x01, 0xA0,
+	 0xFF, 0xFF, 0x01, 0x02, 0x79, 0x00, 0x45, 0x4A, 0x7C, 0x44, 0x60, 0xFE, 0xA1, 0xD2, 0xFF, 0xFF,
+	 0xD0, 0x80, 0x20, 0xFE, 0x01, 0x03, 0xEF, 0x01, 0x1C, 0x60, 0x04, 0xF3, 0xFF, 0xFF, 0x02, 0x18,
+	 0xDD, 0x81, 0x35, 0x00, 0x60, 0xFE, 0x5D, 0xD2, 0xFF, 0xFF, 0x60, 0x5C, 0x41, 0x94, 0x81, 0xA0,
+	 0x20, 0xFE, 0x2D, 0x04, 0x01, 0x64, 0x1C, 0x60, 0x04, 0xFB, 0xC1, 0x84, 0x84, 0xA4, 0x1C, 0x60,
+	 0x06, 0xFB, 0x00, 0xF2, 0x1C, 0x60, 0x07, 0xFB, 0x1C, 0x60, 0x05, 0xFD, 0x02, 0x60, 0x00, 0x63,
+	 0xCD, 0x85, 0x64, 0x44, 0xD8, 0x81, 0xCD, 0x84, 0x4C, 0x91, 0x60, 0x43, 0x60, 0xFE, 0xA5, 0xD2,
+	 0xDE, 0x85, 0x7F, 0x26, 0x02, 0x00, 0x00, 0xF4, 0x04, 0x65, 0x5D, 0x93, 0xA3, 0xDB, 0x5D, 0x93,
+	 0xA5, 0xD2, 0xF6, 0x1F, 0x5D, 0x93, 0x20, 0xFE, 0xDF, 0x83, 0x00, 0x60, 0x01, 0x61, 0x02, 0x60,
+	 0x00, 0x64, 0xE0, 0x87, 0x60, 0x46, 0x1C, 0x60, 0x05, 0xF3, 0xFF, 0xFF, 0x60, 0x43, 0x60, 0xFE,
+	 0xCD, 0x81, 0x20, 0xFE, 0x2A, 0x44, 0x38, 0x60, 0x00, 0x7C, 0xD0, 0x84, 0x38, 0x60, 0x04, 0x65,
+	 0x44, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0x1C, 0x60, 0x04, 0xF3, 0xFF, 0xFF, 0x08, 0x18, 0x1C, 0x60,
+	 0x06, 0xF3, 0x1C, 0x60, 0x07, 0xF5, 0x60, 0x41, 0x00, 0x64, 0x1C, 0x60, 0x04, 0xFB, 0x26, 0x44,
+	 0x01, 0xA4, 0x58, 0x90, 0xFF, 0xFF, 0x03, 0x02, 0x61, 0x44, 0x0B, 0xA5, 0x04, 0x00, 0x61, 0x44,
+	 0xFC, 0xA4, 0x8B, 0x7C, 0xC0, 0x85, 0xDD, 0x81, 0x66, 0x44, 0x1C, 0x60, 0x07, 0xFB, 0x26, 0x46,
+	 0x1B, 0xF0, 0x1C, 0x60, 0x07, 0xF5, 0x64, 0x44, 0xD4, 0x80, 0xFF, 0xFF, 0x02, 0x06, 0x2D, 0x58,
+	 0xFF, 0xFF, 0xFA, 0x60, 0xE7, 0x78, 0xFF, 0xFF, 0x60, 0xFE, 0x5D, 0xD2, 0xFF, 0xFF, 0x20, 0xFE,
+	 0xFF, 0xB4, 0x41, 0x94, 0x81, 0xA0, 0xFF, 0xFF, 0x02, 0x04, 0x00, 0xF4, 0x84, 0xA4, 0x60, 0x41,
+	 0x5D, 0x01, 0x1A, 0x60, 0x2C, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x01, 0x3A, 0x6C, 0x01, 0x61, 0x5C,
+	 0x1A, 0x60, 0x2B, 0xF9, 0x60, 0xFE, 0x5D, 0xD2, 0xFF, 0xFF, 0xFE, 0xA4, 0xFF, 0xFF, 0x04, 0x20,
+	 0x02, 0x00, 0xFF, 0xA1, 0x60, 0x01, 0x5D, 0xD0, 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x36, 0x02, 0x00,
+	 0xFE, 0xA1, 0x59, 0x01, 0x5D, 0xD0, 0xFF, 0xFF, 0x64, 0x40, 0x00, 0x36, 0x02, 0x00, 0xFD, 0xA1,
+	 0x52, 0x01, 0x01, 0x7C, 0x1C, 0x60, 0x08, 0xF9, 0x4C, 0x00, 0x1A, 0x60, 0x2C, 0xF3, 0xFF, 0xFF,
+	 0x01, 0x18, 0x49, 0x01, 0x00, 0x7C, 0x1C, 0x60, 0x08, 0xF9, 0x61, 0x5C, 0x1A, 0x60, 0x2B, 0xF9,
+	 0x60, 0xFE, 0x5D, 0xD2, 0xFF, 0xFF, 0xFA, 0xA4, 0xFF, 0xFF, 0x04, 0x20, 0x04, 0x00, 0xFF, 0xA1,
+	 0xF9, 0x60, 0x6B, 0x78, 0xFF, 0xFF, 0x5D, 0xD0, 0xFF, 0xFF, 0x64, 0x40, 0x00, 0x36, 0x04, 0x00,
+	 0xC9, 0x81, 0xF9, 0x60, 0x6B, 0x78, 0xFF, 0xFF, 0x5D, 0xD0, 0xFF, 0xFF, 0x64, 0x40, 0x50, 0x36,
+	 0x04, 0x00, 0xFD, 0xA1, 0xF9, 0x60, 0x6B, 0x78, 0xFF, 0xFF, 0x5D, 0xD0, 0xFF, 0xFF, 0x64, 0x40,
+	 0xF2, 0x36, 0x04, 0x00, 0xFC, 0xA1, 0xF9, 0x60, 0x6B, 0x78, 0xFF, 0xFF, 0x5D, 0xD0, 0xFF, 0xFF,
+	 0x64, 0x40, 0x01, 0x36, 0x04, 0x00, 0xFB, 0xA1, 0xF9, 0x60, 0x6B, 0x78, 0xFF, 0xFF, 0x5D, 0xD0,
+	 0xFF, 0xFF, 0x64, 0x40, 0x01, 0x36, 0x04, 0x00, 0xFA, 0xA1, 0xF9, 0x60, 0x6B, 0x78, 0xFF, 0xFF,
+	 0x5D, 0xD0, 0xFF, 0xFF, 0x64, 0x40, 0x00, 0x36, 0x04, 0x00, 0xF9, 0xA1, 0xF9, 0x60, 0x6B, 0x78,
+	 0xFF, 0xFF, 0x60, 0x5C, 0x00, 0x36, 0x32, 0x00, 0x00, 0x64, 0xFB, 0x60, 0x58, 0x4E, 0x66, 0x78,
+	 0xFF, 0xFF, 0x65, 0x40, 0x08, 0x26, 0xF7, 0x01, 0x1A, 0x60, 0x24, 0xFB, 0x64, 0x40, 0x00, 0x36,
+	 0x2A, 0x00, 0x5D, 0xD2, 0xDD, 0x81, 0xFB, 0x60, 0x58, 0x4E, 0x66, 0x78, 0xFF, 0xFF, 0x65, 0x40,
+	 0x08, 0x26, 0xF6, 0x01, 0x1A, 0x60, 0x25, 0xFB, 0x64, 0x40, 0x00, 0x36, 0x21, 0x00, 0x5D, 0xD2,
+	 0xDD, 0x81, 0xFB, 0x60, 0x58, 0x4E, 0x66, 0x78, 0xFF, 0xFF, 0x65, 0x40, 0x08, 0x26, 0xF6, 0x01,
+	 0x1A, 0x60, 0x26, 0xFB, 0x64, 0x40, 0x00, 0x36, 0x18, 0x00, 0x5D, 0xD0, 0x34, 0x60, 0x4E, 0x62,
+	 0xA2, 0xD9, 0x5D, 0xD0, 0x34, 0x60, 0x4F, 0x62, 0xA2, 0xD9, 0x14, 0x00, 0x20, 0xFE, 0x00, 0x60,
+	 0x04, 0x64, 0x1A, 0x60, 0x24, 0xFB, 0x20, 0xFE, 0x00, 0x60, 0x04, 0x64, 0x1A, 0x60, 0x25, 0xFB,
+	 0x20, 0xFE, 0x00, 0x60, 0x02, 0x64, 0x1A, 0x60, 0x26, 0xFB, 0x20, 0xFE, 0x00, 0x60, 0x00, 0x64,
+	 0x1A, 0x60, 0x27, 0xFB, 0x20, 0xFE, 0x1C, 0x60, 0x08, 0xF1, 0xFF, 0xFF, 0x03, 0x18, 0x01, 0x7C,
+	 0x1C, 0x60, 0x08, 0xF9, 0x1A, 0x60, 0x2B, 0xF1, 0xA2, 0xDD, 0x61, 0x44, 0x1A, 0x60, 0x28, 0xFB,
+	 0xD1, 0x84, 0xDC, 0x84, 0x64, 0x45, 0x34, 0x60, 0x10, 0x63, 0xBD, 0xDB, 0x60, 0x41, 0xCD, 0x84,
+	 0x4C, 0x91, 0x60, 0x43, 0x60, 0xFE, 0xA5, 0xD2, 0xDE, 0x85, 0x7F, 0x26, 0x02, 0x00, 0x00, 0xF4,
+	 0x04, 0x65, 0x5D, 0x93, 0xA3, 0xDB, 0x5D, 0x93, 0xA5, 0xD2, 0xF6, 0x1F, 0x5D, 0x93, 0x20, 0xFE,
+	 0xDF, 0x83, 0x1A, 0x60, 0x09, 0xF3, 0xFF, 0xFF, 0x60, 0x47, 0xA2, 0xDB, 0x1A, 0x60, 0x28, 0xF3,
+	 0x1A, 0x60, 0x2B, 0xF1, 0x60, 0x41, 0x64, 0x43, 0xF9, 0x60, 0x56, 0x78, 0xFF, 0xFF, 0x20, 0xFE,
+	 0x7C, 0x44, 0x1A, 0x60, 0x20, 0xFB, 0x1A, 0x60, 0x1A, 0xF1, 0x1A, 0x60, 0x24, 0xF3, 0xFF, 0xFF,
+	 0xA0, 0x84, 0xFF, 0xFF, 0x10, 0x26, 0x07, 0x00, 0x04, 0x26, 0x07, 0x00, 0x20, 0x26, 0x07, 0x00,
+	 0x02, 0x26, 0x07, 0x00, 0x3F, 0x00, 0x10, 0x7C, 0x05, 0x00, 0x04, 0x7C, 0x03, 0x00, 0x20, 0x7C,
+	 0x01, 0x00, 0x02, 0x7C, 0x1A, 0x60, 0x20, 0xF9, 0x7C, 0x44, 0x1A, 0x60, 0x21, 0xFB, 0x1A, 0x60,
+	 0x1B, 0xF1, 0x1A, 0x60, 0x25, 0xF3, 0x34, 0x60, 0x40, 0x61, 0xA0, 0x84, 0xA1, 0xD1, 0xFF, 0xFF,
+	 0x10, 0x26, 0x05, 0x00, 0x04, 0x26, 0x05, 0x00, 0x01, 0x26, 0x08, 0x00, 0x23, 0x00, 0x10, 0x7C,
+	 0x06, 0x00, 0x64, 0x40, 0x10, 0x26, 0x1E, 0x00, 0x04, 0x7C, 0x01, 0x00, 0x01, 0x7C, 0x1A, 0x60,
+	 0x21, 0xF9, 0x7C, 0x44, 0x1A, 0x60, 0x22, 0xFB, 0x1A, 0x60, 0x1C, 0xF1, 0x1A, 0x60, 0x26, 0xF3,
+	 0xFF, 0xFF, 0xA0, 0x84, 0x60, 0x40, 0x02, 0x26, 0x05, 0x00, 0x04, 0x26, 0x05, 0x00, 0x01, 0x26,
+	 0x05, 0x00, 0x08, 0x00, 0x02, 0x7C, 0x03, 0x00, 0x04, 0x7C, 0x01, 0x00, 0x20, 0x7C, 0x1A, 0x60,
+	 0x22, 0xF9, 0x09, 0x00, 0x7C, 0x44, 0x1A, 0x60, 0x20, 0xFB, 0x1A, 0x60, 0x21, 0xFB, 0x1A, 0x60,
+	 0x22, 0xFB, 0x1A, 0x60, 0x23, 0xFB, 0x7C, 0x44, 0x1A, 0x60, 0x20, 0xF1, 0xBD, 0xD9, 0x1A, 0x60,
+	 0x21, 0xF1, 0xB0, 0x84, 0xBD, 0xD9, 0x1A, 0x60, 0x22, 0xF1, 0xB0, 0x84, 0xBD, 0xD9, 0x1A, 0x60,
+	 0x1D, 0xF1, 0xB0, 0x84, 0xBD, 0xD9, 0x04, 0x03, 0x1C, 0x60, 0x08, 0xF1, 0xBD, 0xD9, 0x72, 0x00,
+	 0x16, 0x60, 0xC2, 0xF3, 0xFF, 0xFF, 0xFF, 0xA0, 0xFF, 0xFF, 0x0C, 0x24, 0x6B, 0x00, 0x60, 0x40,
+	 0x0B, 0x36, 0x68, 0x00, 0x20, 0x40, 0x10, 0x27, 0x65, 0x00, 0x91, 0x00, 0x20, 0xFE, 0x00, 0x65,
+	 0x60, 0xFE, 0x1A, 0x60, 0x28, 0xFB, 0xE0, 0x84, 0xE0, 0x84, 0x08, 0x20, 0x03, 0x00, 0x01, 0x64,
+	 0xA2, 0xDB, 0x02, 0x64, 0x02, 0xA5, 0x64, 0x44, 0xD4, 0x9C, 0xD4, 0x80, 0x34, 0x60, 0x52, 0x62,
+	 0x02, 0x05, 0x08, 0x65, 0x4D, 0x00, 0xA2, 0xD9, 0x7C, 0x44, 0x34, 0x60, 0x54, 0x62, 0xA2, 0xDB,
+	 0x20, 0xFE, 0x00, 0x64, 0x60, 0xFE, 0x1C, 0x60, 0x08, 0xF3, 0xFF, 0xFF, 0x00, 0xA0, 0x5D, 0xD0,
+	 0x00, 0x65, 0x04, 0x03, 0x64, 0x40, 0x00, 0x3A, 0x01, 0x65, 0x03, 0x00, 0x64, 0x40, 0x00, 0x3A,
+	 0x01, 0x65, 0x5D, 0xD0, 0x04, 0x03, 0x64, 0x40, 0x0F, 0x3A, 0x01, 0x65, 0x03, 0x00, 0x64, 0x40,
+	 0x50, 0x3A, 0x01, 0x65, 0x5D, 0xD0, 0x04, 0x03, 0x64, 0x40, 0xAC, 0x3A, 0x01, 0x65, 0x03, 0x00,
+	 0x64, 0x40, 0xF2, 0x3A, 0x01, 0x65, 0x5D, 0xD0, 0x65, 0x40, 0x00, 0x3A, 0x17, 0x00, 0x00, 0x60,
+	 0x00, 0x65, 0x64, 0x40, 0x00, 0x36, 0x01, 0x65, 0x64, 0x40, 0x01, 0x36, 0x02, 0x65, 0x64, 0x40,
+	 0x02, 0x36, 0x04, 0x65, 0x64, 0x40, 0x04, 0x36, 0x10, 0x65, 0x64, 0x40, 0x05, 0x36, 0x20, 0x65,
+	 0x65, 0x5C, 0x1A, 0x60, 0x2A, 0xF3, 0xFF, 0xFF, 0xB0, 0x84, 0xA2, 0xDB, 0x1A, 0x60, 0x28, 0xF3,
+	 0x00, 0x65, 0xFF, 0xA4, 0xA2, 0xDB, 0xBC, 0x02, 0x1A, 0x60, 0x2A, 0xF3, 0x1A, 0x60, 0x29, 0xF1,
+	 0x2E, 0x58, 0xFF, 0xFF, 0x20, 0xFE, 0x88, 0xF3, 0xFF, 0xFF, 0x3C, 0xA4, 0x88, 0xFB, 0x87, 0xF3,
+	 0x7D, 0xF1, 0x04, 0xA4, 0x87, 0xFB, 0x53, 0xF3, 0xFF, 0xFF, 0x60, 0x40, 0x80, 0x26, 0x0D, 0x00,
+	 0x7D, 0xF3, 0x10, 0x60, 0xF2, 0x61, 0xCC, 0x84, 0xFF, 0xFF, 0x02, 0x03, 0x06, 0xA1, 0xFB, 0x01,
+	 0xA1, 0xD3, 0xFF, 0xFF, 0x02, 0xBC, 0xA1, 0xDB, 0x12, 0x00, 0x7D, 0xF3, 0x11, 0x60, 0x60, 0x63,
+	 0x01, 0x60, 0xFF, 0x65, 0xA4, 0x84, 0x12, 0x60, 0x40, 0x65, 0xA3, 0xD1, 0xD7, 0x80, 0xD0, 0x80,
+	 0x06, 0x03, 0x02, 0x03, 0x08, 0xA3, 0xF9, 0x01, 0x02, 0xA3, 0x04, 0x64, 0xA3, 0xDB, 0x20, 0xFE,
+	 0x26, 0x46, 0x31, 0x40, 0x20, 0x2A, 0x35, 0x00, 0x3F, 0xF2, 0x47, 0x65, 0xC4, 0x84, 0xE8, 0x84,
+	 0x23, 0xFA, 0xF1, 0x60, 0x02, 0x64, 0x24, 0xFA, 0x7D, 0xF3, 0x01, 0x60, 0xFF, 0x65, 0xA4, 0x84,
+	 0x01, 0x23, 0x14, 0x00, 0x11, 0x60, 0x60, 0x61, 0x12, 0x60, 0x40, 0x65, 0xA1, 0xD1, 0xD5, 0x80,
+	 0xD0, 0x80, 0x0B, 0x03, 0x02, 0x03, 0x08, 0xA1, 0xF9, 0x01, 0x04, 0xA1, 0xA1, 0xD3, 0x01, 0x60,
+	 0x00, 0x65, 0x60, 0x47, 0xFF, 0xB4, 0xB4, 0x84, 0x01, 0x00, 0x01, 0x64, 0x00, 0xF4, 0x08, 0xFA,
+	 0xFF, 0xFF, 0x26, 0x46, 0x26, 0x60, 0x0A, 0x64, 0x13, 0x60, 0x0D, 0xFB, 0x26, 0x44, 0x5A, 0xDB,
+	 0x02, 0x64, 0x5A, 0xDB, 0xFF, 0xFF, 0x2B, 0xFF, 0xFA, 0xFE, 0x00, 0x66, 0x46, 0x46, 0x2F, 0x58,
+	 0xFF, 0xFF, 0x26, 0x46, 0x2F, 0x58, 0xFF, 0xFF, 0x78, 0xFB, 0xAC, 0x85, 0x60, 0x41, 0x55, 0x03,
+	 0x32, 0x60, 0x00, 0x63, 0x1B, 0x60, 0x04, 0xFD, 0x62, 0x43, 0x1A, 0x60, 0xB4, 0xFD, 0x1A, 0x60,
+	 0xBA, 0xFD, 0x1A, 0x60, 0xC4, 0xFD, 0x1A, 0x60, 0xCE, 0xFD, 0x00, 0x63, 0xE9, 0x81, 0x08, 0x64,
+	 0x02, 0x24, 0xDF, 0x83, 0xFB, 0x02, 0x53, 0x94, 0x32, 0x7F, 0x03, 0x06, 0x1B, 0x60, 0x04, 0xFB,
+	 0x08, 0x63, 0x63, 0x5E, 0x01, 0x7F, 0x19, 0x60, 0x8A, 0xFB, 0x65, 0x41, 0x33, 0x60, 0x16, 0x65,
+	 0x0F, 0x60, 0xF4, 0x64, 0xE9, 0x81, 0x58, 0xD1, 0xFD, 0x04, 0xCF, 0x83, 0xA5, 0xD9, 0x0C, 0x03,
+	 0xE9, 0x81, 0x58, 0xD1, 0xFD, 0x04, 0x40, 0x48, 0xA5, 0xD1, 0x64, 0x5F, 0x64, 0x5E, 0xA5, 0xDB,
+	 0xDA, 0x85, 0xCF, 0x83, 0x28, 0x44, 0xEE, 0x02, 0x00, 0xB9, 0xD8, 0x83, 0x15, 0x03, 0x36, 0x60,
+	 0x0A, 0x65, 0xE9, 0x81, 0xBD, 0xD1, 0x02, 0x05, 0xFC, 0x02, 0x17, 0x00, 0xA5, 0xD9, 0x15, 0x03,
+	 0xE9, 0x81, 0xBD, 0xD1, 0x02, 0x05, 0xFC, 0x02, 0x10, 0x00, 0xA5, 0xD3, 0xFF, 0xFF, 0x64, 0x5F,
+	 0xA5, 0xDB, 0xDA, 0x85, 0xEE, 0x02, 0x09, 0x00, 0x67, 0x43, 0x1A, 0x60, 0xB4, 0xFD, 0x1A, 0x60,
+	 0xBA, 0xFD, 0x1A, 0x60, 0xC4, 0xFD, 0x1A, 0x60, 0xCE, 0xFD, 0x2E, 0x45, 0x25, 0x60, 0x46, 0x64,
+	 0xD4, 0x80, 0xFF, 0xFF, 0x10, 0x03, 0x20, 0x40, 0x10, 0x27, 0x0D, 0x00, 0x33, 0x60, 0x1E, 0x61,
+	 0x19, 0x60, 0x8A, 0xF3, 0xA1, 0xDB, 0xFF, 0xB4, 0xCC, 0x84, 0xA8, 0x83, 0x33, 0x60, 0x14, 0x64,
+	 0x58, 0xD1, 0x59, 0xD9, 0xFD, 0x1F, 0x7D, 0xF3, 0x33, 0x60, 0x20, 0x63, 0x60, 0x40, 0x01, 0x27,
+	 0x03, 0x00, 0x19, 0x60, 0x3B, 0xF3, 0x02, 0x00, 0x19, 0x60, 0x3C, 0xF3, 0x08, 0x61, 0x60, 0xFE,
+	 0xA3, 0xD1, 0xFF, 0xFF, 0x20, 0xFE, 0x00, 0xA8, 0xE8, 0x84, 0x0F, 0x03, 0x60, 0xFE, 0x02, 0x28,
+	 0xF6, 0x01, 0x80, 0x62, 0xB2, 0x9C, 0xBD, 0xD9, 0x7B, 0xF9, 0xCD, 0x81, 0x00, 0x36, 0x01, 0x00,
+	 0xEE, 0x01, 0x36, 0x60, 0x0A, 0x63, 0x08, 0x61, 0xEA, 0x01, 0x2E, 0x58, 0xFF, 0xFF, 0x32, 0x60,
+	 0x76, 0x63, 0x65, 0x40, 0xFF, 0x36, 0x02, 0xA3, 0xA3, 0xD3, 0xFF, 0xFF, 0xE8, 0x84, 0xE8, 0x84,
+	 0xE8, 0x84, 0xE8, 0x84, 0x40, 0x26, 0x7F, 0xB4, 0x20, 0x26, 0x3F, 0xB4, 0x60, 0x45, 0x80, 0x63,
+	 0xFD, 0x60, 0x58, 0x4D, 0x34, 0x78, 0xFF, 0xFF, 0x19, 0x60, 0x7D, 0xFB, 0x40, 0x63, 0xFD, 0x60,
+	 0x58, 0x4D, 0x34, 0x78, 0xFF, 0xFF, 0x19, 0x60, 0x7E, 0xFB, 0x20, 0x63, 0xFD, 0x60, 0x58, 0x4D,
+	 0x34, 0x78, 0xFF, 0xFF, 0x19, 0x60, 0x7F, 0xFB, 0x10, 0x63, 0xFD, 0x60, 0x58, 0x4D, 0x34, 0x78,
+	 0xFF, 0xFF, 0x19, 0x60, 0x80, 0xFB, 0x08, 0x63, 0xFD, 0x60, 0x58, 0x4D, 0x34, 0x78, 0xFF, 0xFF,
+	 0x19, 0x60, 0x81, 0xFB, 0x04, 0x63, 0xFD, 0x60, 0x58, 0x4D, 0x34, 0x78, 0xFF, 0xFF, 0x19, 0x60,
+	 0x82, 0xFB, 0x02, 0x63, 0xFD, 0x60, 0x58, 0x4D, 0x34, 0x78, 0xFF, 0xFF, 0x19, 0x60, 0x83, 0xFB,
+	 0x01, 0x63, 0xFD, 0x60, 0x58, 0x4D, 0x34, 0x78, 0xFF, 0xFF, 0x19, 0x60, 0x84, 0xFB, 0x2E, 0x58,
+	 0xFF, 0xFF, 0x19, 0x60, 0x3B, 0xF3, 0xFF, 0xFF, 0x0F, 0xB4, 0x60, 0x45, 0x08, 0x63, 0xFD, 0x60,
+	 0x58, 0x4D, 0x5F, 0x78, 0xFF, 0xFF, 0x19, 0x60, 0x85, 0xFB, 0x04, 0x63, 0xFD, 0x60, 0x58, 0x4D,
+	 0x5F, 0x78, 0xFF, 0xFF, 0x19, 0x60, 0x86, 0xFB, 0x02, 0x63, 0xFD, 0x60, 0x58, 0x4D, 0x5F, 0x78,
+	 0xFF, 0xFF, 0x19, 0x60, 0x87, 0xFB, 0x01, 0x63, 0xFD, 0x60, 0x58, 0x4D, 0x5F, 0x78, 0xFF, 0xFF,
+	 0x19, 0x60, 0x88, 0xFB, 0x2E, 0x58, 0xFF, 0xFF, 0x63, 0x5C, 0xA7, 0x84, 0xEB, 0x83, 0x14, 0x02,
+	 0x01, 0x03, 0xFB, 0x01, 0x64, 0x44, 0x01, 0x36, 0x0B, 0x64, 0x02, 0x36, 0x0B, 0x64, 0x04, 0x36,
+	 0x0A, 0x64, 0x08, 0x36, 0x0A, 0x64, 0x10, 0x36, 0x09, 0x64, 0x20, 0x36, 0x09, 0x64, 0x40, 0x36,
+	 0x09, 0x64, 0x80, 0x36, 0x09, 0x64, 0x11, 0x00, 0x60, 0x40, 0x01, 0x36, 0x0B, 0x64, 0x02, 0x36,
+	 0x0F, 0x64, 0x04, 0x36, 0x0A, 0x64, 0x08, 0x36, 0x0E, 0x64, 0x10, 0x36, 0x09, 0x64, 0x20, 0x36,
+	 0x0D, 0x64, 0x40, 0x36, 0x08, 0x64, 0x80, 0x36, 0x0C, 0x64, 0x2D, 0x58, 0xFF, 0xFF, 0x63, 0x5C,
+	 0xA7, 0x84, 0xEB, 0x83, 0x0C, 0x02, 0x01, 0x03, 0xFB, 0x01, 0x64, 0x44, 0x01, 0x36, 0x0A, 0x64,
+	 0x02, 0x36, 0x14, 0x64, 0x04, 0x36, 0x37, 0x64, 0x08, 0x36, 0x6E, 0x64, 0x09, 0x00, 0x60, 0x40,
+	 0x01, 0x36, 0x0A, 0x64, 0x02, 0x36, 0x14, 0x64, 0x04, 0x36, 0x37, 0x64, 0x08, 0x36, 0x6E, 0x64,
+	 0x2D, 0x58, 0xFF, 0xFF, 0x60, 0xFE, 0x81, 0xA1, 0x7F, 0xA1, 0x02, 0x06, 0x00, 0xF4, 0x03, 0x61,
+	 0x5D, 0xD2, 0xCF, 0x83, 0xD4, 0x80, 0x25, 0x03, 0x16, 0x03, 0xCF, 0x83, 0x61, 0x44, 0x80, 0xA0,
+	 0x20, 0x03, 0x02, 0x02, 0x00, 0xF4, 0x03, 0x61, 0x5D, 0xD2, 0xCF, 0x83, 0x81, 0xA1, 0x19, 0x03,
+	 0x05, 0x07, 0x7F, 0xA1, 0xCC, 0x84, 0xDD, 0x81, 0xE6, 0x03, 0xF7, 0x01, 0x00, 0xF4, 0x00, 0xB8,
+	 0x04, 0x61, 0xE6, 0x03, 0xF2, 0x01, 0x2C, 0x43, 0x5D, 0xD0, 0xDE, 0xD9, 0x64, 0x44, 0x5D, 0xD0,
+	 0xDE, 0xD9, 0xCC, 0x84, 0x81, 0xA1, 0x05, 0x03, 0x7F, 0xA1, 0xF9, 0x04, 0x00, 0xF4, 0x03, 0x61,
+	 0xF6, 0x01, 0x20, 0xFE, 0x2E, 0x58, 0xFF, 0xFF, 0x01, 0x3A, 0x02, 0x00, 0x16, 0x64, 0x2B, 0x00,
+	 0x02, 0x3A, 0x02, 0x00, 0x14, 0x64, 0x27, 0x00, 0x04, 0x3A, 0x02, 0x00, 0x12, 0x64, 0x23, 0x00,
+	 0x08, 0x3A, 0x02, 0x00, 0x10, 0x64, 0x1F, 0x00, 0x10, 0x3A, 0x02, 0x00, 0x0E, 0x64, 0x1B, 0x00,
+	 0x20, 0x3A, 0x02, 0x00, 0x0C, 0x64, 0x17, 0x00, 0x40, 0x3A, 0x02, 0x00, 0x0A, 0x64, 0x13, 0x00,
+	 0x80, 0x3A, 0x02, 0x00, 0x08, 0x64, 0x0F, 0x00, 0x01, 0x3B, 0x02, 0x00, 0x06, 0x64, 0x0B, 0x00,
+	 0x02, 0x3B, 0x02, 0x00, 0x04, 0x64, 0x07, 0x00, 0x04, 0x3B, 0x02, 0x00, 0x02, 0x64, 0x03, 0x00,
+	 0x08, 0x3B, 0xFF, 0x01, 0x00, 0x64, 0x2E, 0x58, 0xFF, 0xFF, 0x27, 0xF2, 0xFF, 0xFF, 0x60, 0x40,
+	 0x36, 0x3A, 0x02, 0x00, 0x00, 0x61, 0x30, 0x00, 0x30, 0x3A, 0x02, 0x00, 0x02, 0x61, 0x2C, 0x00,
+	 0x24, 0x3A, 0x02, 0x00, 0x04, 0x61, 0x28, 0x00, 0x18, 0x3A, 0x02, 0x00, 0x06, 0x61, 0x24, 0x00,
+	 0x12, 0x3A, 0x02, 0x00, 0x08, 0x61, 0x20, 0x00, 0x0C, 0x3A, 0x02, 0x00, 0x0A, 0x61, 0x1C, 0x00,
+	 0x09, 0x3A, 0x02, 0x00, 0x0C, 0x61, 0x18, 0x00, 0x06, 0x3A, 0x02, 0x00, 0x0E, 0x61, 0x14, 0x00,
+	 0x6E, 0x3A, 0x02, 0x00, 0x10, 0x61, 0x10, 0x00, 0x37, 0x3A, 0x02, 0x00, 0x12, 0x61, 0x0C, 0x00,
+	 0x14, 0x3A, 0x02, 0x00, 0x14, 0x61, 0x08, 0x00, 0x0A, 0x3A, 0x02, 0x00, 0x16, 0x61, 0x04, 0x00,
+	 0x78, 0x43, 0x03, 0x61, 0x29, 0x60, 0xEA, 0x78, 0x65, 0x40, 0x01, 0x3A, 0x13, 0x00, 0x66, 0x45,
+	 0x2B, 0x46, 0x92, 0xFA, 0x65, 0x46, 0x26, 0xF2, 0xFF, 0xFF, 0x60, 0x41, 0x00, 0x7F, 0x60, 0x45,
+	 0x61, 0x47, 0x00, 0x7F, 0xD4, 0x84, 0x66, 0x41, 0x2B, 0x46, 0x0E, 0xF2, 0x60, 0x45, 0x65, 0x5E,
+	 0x0E, 0xFA, 0x61, 0x46, 0x2E, 0x58, 0xFF, 0xFF, 0xCD, 0x81, 0x7F, 0xB4, 0x02, 0x3A, 0x02, 0x00,
+	 0x01, 0x64, 0x32, 0x00, 0x04, 0x3A, 0x02, 0x00, 0x02, 0x64, 0x2E, 0x00, 0x0B, 0x3A, 0x02, 0x00,
+	 0x04, 0x64, 0x2A, 0x00, 0x16, 0x3A, 0x02, 0x00, 0x08, 0x64, 0x26, 0x00, 0x0C, 0x3A, 0x02, 0x00,
+	 0x10, 0x64, 0x22, 0x00, 0x12, 0x3A, 0x02, 0x00, 0x20, 0x64, 0x1E, 0x00, 0x18, 0x3A, 0x02, 0x00,
+	 0x40, 0x64, 0x1A, 0x00, 0x24, 0x3A, 0x02, 0x00, 0x80, 0x64, 0x16, 0x00, 0x30, 0x3A, 0x03, 0x00,
+	 0x00, 0x7E, 0x01, 0x7F, 0x11, 0x00, 0x48, 0x3A, 0x03, 0x00, 0x00, 0x7E, 0x02, 0x7F, 0x0C, 0x00,
+	 0x60, 0x3A, 0x03, 0x00, 0x00, 0x7E, 0x04, 0x7F, 0x07, 0x00, 0x6C, 0x3A, 0x03, 0x00, 0x00, 0x7E,
+	 0x08, 0x7F, 0x02, 0x00, 0x00, 0x64, 0x00, 0x00, 0x20, 0xFE, 0x2A, 0x45, 0x34, 0x8A, 0x60, 0xFE,
+	 0x61, 0x40, 0x00, 0x36, 0x02, 0x00, 0xBD, 0xD3, 0xBF, 0x01, 0x2E, 0x58, 0xFF, 0xFF,
+
+};  /* fw_image_4_data */
+
+static const CFG_IDENTITY_STRCT fw_image_infoidentity[] = {
+	{
+		sizeof( CFG_IDENTITY_STRCT ) / sizeof(hcf_16) - 1,
+		CFG_FW_IDENTITY,
+		COMP_ID_FW_STA,
+		4,							//Variant
+		1,							//Major
+		36							//Minor
+	},
+	{ 0000, 0000, 0000, 0000, 0000, 0000 }		//endsentinel
+};
+
+static const CFG_PROG_STRCT fw_image_code[] = {
+	{
+		8,
+		CFG_PROG,
+		CFG_PROG_VOLATILE,			// mode
+		0x0184,		// sizeof(fw_image_1_data),
+		0x00000060,					// Target address in NIC Memory
+		0x0000,						// CRC: yes/no	TYPE: primary/station/tertiary
+		(hcf_8 FAR   *) fw_image_1_data
+	},
+	{
+		8,
+		CFG_PROG,
+		CFG_PROG_VOLATILE,			// mode
+		0x2c0e,		// sizeof(fw_image_2_data),
+		0x00000C16,					// Target address in NIC Memory
+		0x0000,						// CRC: yes/no	TYPE: primary/station/tertiary
+		(hcf_8 FAR   *) fw_image_2_data
+	},
+	{
+		8,
+		CFG_PROG,
+		CFG_PROG_VOLATILE,			// mode
+		0x54de,		// sizeof(fw_image_3_data),
+		0x001E3824,					// Target address in NIC Memory
+		0x0000,						// CRC: yes/no	TYPE: primary/station/tertiary
+		(hcf_8 FAR   *) fw_image_3_data
+	},
+	{
+		8,
+		CFG_PROG,
+		CFG_PROG_VOLATILE,			// mode
+		0xbcde,		// sizeof(fw_image_4_data),
+		0x001F4000,					// Target address in NIC Memory
+		0x0000,						// CRC: yes/no	TYPE: primary/station/tertiary
+		(hcf_8 FAR   *) fw_image_4_data
+	},
+	{
+		5,
+		CFG_PROG,
+		CFG_PROG_STOP,				// mode
+		0000,
+ 	0x000F429B,					// Start execution address
+	},
+	{ 0000, 0000, 0000, 0000, 00000000, 0000, 00000000}
+};
+
+static const CFG_RANGE20_STRCT fw_image_infocompat[] = {
+	{	3 + ((20 * sizeof(CFG_RANGE_SPEC_STRCT)) / sizeof(hcf_16)),
+		CFG_FW_SUP_RANGE,
+		COMP_ROLE_SUPL,
+		COMP_ID_STA,
+		{
+			{ 4, 1, 2 }  				//variant, bottom, top
+		}
+	},
+	{	3 + ((20 * sizeof(CFG_RANGE_SPEC_STRCT)) / sizeof(hcf_16)),
+		CFG_MFI_ACT_RANGES_STA,
+		COMP_ROLE_ACT,
+		COMP_ID_MFI,
+		{
+			{ 7, 3, 3 }, 				//variant, bottom, top
+			{ 8, 1, 1 }  				//variant, bottom, top
+		}
+	},
+	{	3 + ((20 * sizeof(CFG_RANGE_SPEC_STRCT)) / sizeof(hcf_16)),
+		CFG_CFI_ACT_RANGES_STA,
+		COMP_ROLE_ACT,
+		COMP_ID_CFI,
+		{
+			{ 4, 1, 2 }  				//variant, bottom, top
+		}
+	},
+	{ 0000, 0000, 0000, 0000, { { 0000, 0000, 0000 } } }	//endsentinel
+};
+
+memimage fw_image = {
+	"FUPU7D37dhfwci\001C",			//signature, <format number>, C/Bin type
+	(CFG_PROG_STRCT *) fw_image_code,
+	0x000F429B,
+	00000000,					//(dummy) pdaplug
+	00000000,					//(dummy) priplug
+	(CFG_RANGE20_STRCT *) fw_image_infocompat,
+	(CFG_IDENTITY_STRCT *) fw_image_infoidentity,
+};
+
diff --git a/drivers/staging/wlags49_h2/wl_cs.c b/drivers/staging/wlags49_h2/wl_cs.c
new file mode 100644
index 0000000..811a8da
--- /dev/null
+++ b/drivers/staging/wlags49_h2/wl_cs.c
@@ -0,0 +1,702 @@
+/*******************************************************************************
+ * Agere Systems Inc.
+ * Wireless device driver for Linux (wlags49).
+ *
+ * Copyright (c) 1998-2003 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * Initially developed by TriplePoint, Inc.
+ *   http://www.triplepoint.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ *   This file contains processing and initialization specific to Card Services
+ *   devices (PCMCIA, CF).
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2003 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following Disclaimer as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ ******************************************************************************/
+
+/*******************************************************************************
+ *  include files
+ ******************************************************************************/
+#include <wl_version.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/in.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/ioport.h>
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ciscode.h>
+#include <pcmcia/ds.h>
+#include <debug.h>
+
+#include <hcf.h>
+#include <dhf.h>
+#include <hcfdef.h>
+
+#include <wl_if.h>
+#include <wl_internal.h>
+#include <wl_util.h>
+#include <wl_main.h>
+#include <wl_netdev.h>
+#include <wl_cs.h>
+#include <wl_sysfs.h>
+
+
+/*******************************************************************************
+ *  macro definitions
+ ******************************************************************************/
+#define CS_CHECK(fn, ret) do { \
+                    last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; \
+            } while (0)
+
+/*******************************************************************************
+ *  global definitions
+ ******************************************************************************/
+#if DBG
+extern dbg_info_t *DbgInfo;
+#endif  /* DBG */
+
+
+/*******************************************************************************
+ *	wl_adapter_attach()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Creates an instance of the driver, allocating local data structures for
+ *  one device. The device is registered with Card Services.
+ *
+ *  PARAMETERS:
+ *
+ *      none
+ *
+ *  RETURNS:
+ *
+ *      pointer to an allocated dev_link_t structure
+ *      NULL on failure
+ *
+ ******************************************************************************/
+static int wl_adapter_attach(struct pcmcia_device *link)
+{
+    struct net_device   *dev;
+    struct wl_private	*lp;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_adapter_attach" );
+    DBG_ENTER( DbgInfo );
+
+    dev = wl_device_alloc();
+    if(dev == NULL) {
+        DBG_ERROR( DbgInfo, "wl_device_alloc returned NULL\n");
+	return -ENOMEM;
+    }
+
+    link->io.NumPorts1      = HCF_NUM_IO_PORTS;
+    link->io.Attributes1    = IO_DATA_PATH_WIDTH_16;
+    link->io.IOAddrLines    = 6;
+    link->irq.Attributes    = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
+    link->irq.IRQInfo1      = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
+    link->irq.Handler       = &wl_isr;
+    link->conf.Attributes   = CONF_ENABLE_IRQ;
+    link->conf.IntType      = INT_MEMORY_AND_IO;
+    link->conf.ConfigIndex  = 5;
+    link->conf.Present      = PRESENT_OPTION;
+
+    link->priv = link->irq.Instance = dev;
+    lp = wl_priv(dev);
+    lp->link = link;
+
+    wl_adapter_insert(link);
+
+    DBG_LEAVE( DbgInfo );
+    return 0;
+} // wl_adapter_attach
+/*============================================================================*/
+
+
+
+/*******************************************************************************
+ *	wl_adapter_detach()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This deletes a driver "instance". The device is de-registered with Card
+ *  Services. If it has been released, then the net device is unregistered, and
+ *  all local data structures are freed. Otherwise, the structures will be
+ *  freed when the device is released.
+ *
+ *  PARAMETERS:
+ *
+ *      link    - pointer to the dev_link_t structure representing the device to
+ *                detach
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+static void wl_adapter_detach(struct pcmcia_device *link)
+{
+    struct net_device   *dev = link->priv;
+    /*------------------------------------------------------------------------*/
+
+
+    DBG_FUNC( "wl_adapter_detach" );
+    DBG_ENTER( DbgInfo );
+    DBG_PARAM( DbgInfo, "link", "0x%p", link );
+
+    wl_adapter_release(link);
+
+    if (dev) {
+	unregister_wlags_sysfs(dev);
+	unregister_netdev(dev);
+    }
+
+    wl_device_dealloc(dev);
+
+    DBG_LEAVE( DbgInfo );
+} // wl_adapter_detach
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wl_adapter_release()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      After a card is removed, this routine will release the PCMCIA
+ *  configuration. If the device is still open, this will be postponed until it
+ *  is closed.
+ *
+ *  PARAMETERS:
+ *
+ *      arg - a u_long representing a pointer to a dev_link_t structure for the
+ *            device to be released.
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_adapter_release( struct pcmcia_device *link )
+{
+    DBG_FUNC( "wl_adapter_release" );
+    DBG_ENTER( DbgInfo );
+    DBG_PARAM( DbgInfo, "link", "0x%p", link);
+
+    /* Stop hardware */
+    wl_remove(link->priv);
+
+    pcmcia_disable_device(link);
+
+    DBG_LEAVE( DbgInfo );
+} // wl_adapter_release
+/*============================================================================*/
+
+static int wl_adapter_suspend(struct pcmcia_device *link)
+{
+    struct net_device *dev = link->priv;
+
+    //if (link->open) {
+	netif_device_detach(dev);
+	wl_suspend(dev);
+//// CHECK!            pcmcia_release_configuration(link->handle);
+    //}
+
+    return 0;
+} // wl_adapter_suspend
+
+static int wl_adapter_resume(struct pcmcia_device *link)
+{
+	struct net_device *dev = link->priv;
+
+	wl_resume(dev);
+
+	netif_device_attach( dev );
+
+	return 0;
+} // wl_adapter_resume
+
+/*******************************************************************************
+ *	wl_adapter_insert()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      wl_adapter_insert() is scheduled to run after a CARD_INSERTION event is
+ *  received, to configure the PCMCIA socket, and to make the ethernet device
+ *  available to the system.
+ *
+ *  PARAMETERS:
+ *
+ *      link    - pointer to the dev_link_t structure representing the device to
+ *                insert
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_adapter_insert( struct pcmcia_device *link )
+{
+    struct net_device       *dev;
+    int i;
+    int                     last_fn, last_ret;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_adapter_insert" );
+    DBG_ENTER( DbgInfo );
+    DBG_PARAM( DbgInfo, "link", "0x%p", link );
+
+    dev     = link->priv;
+
+    /* Do we need to allocate an interrupt? */
+    link->conf.Attributes |= CONF_ENABLE_IRQ;
+
+    CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
+    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+
+
+    dev->irq        = link->irq.AssignedIRQ;
+    dev->base_addr  = link->io.BasePort1;
+
+    SET_NETDEV_DEV(dev, &handle_to_dev(link));
+    if (register_netdev(dev) != 0) {
+	printk("%s: register_netdev() failed\n", MODULE_NAME);
+	goto failed;
+    }
+    link->dev_node = &( wl_priv(dev) )->node;
+    strcpy(( wl_priv(dev) )->node.dev_name, dev->name);
+    register_wlags_sysfs(dev);
+
+    printk(KERN_INFO "%s: Wireless, io_addr %#03lx, irq %d, ""mac_address ",
+               dev->name, dev->base_addr, dev->irq);
+    for( i = 0; i < ETH_ALEN; i++ ) {
+        printk("%02X%c", dev->dev_addr[i], ((i < (ETH_ALEN-1)) ? ':' : '\n'));
+    }
+
+    DBG_LEAVE( DbgInfo );
+    return;
+
+
+cs_failed:
+    cs_error( link, last_fn, last_ret );
+
+
+failed:
+    wl_adapter_release( link );
+
+    DBG_LEAVE(DbgInfo);
+    return;
+} // wl_adapter_insert
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wl_adapter_open()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Open the device.
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to a net_device structure representing the network
+ *            device to open.
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wl_adapter_open( struct net_device *dev )
+{
+    struct wl_private *lp = wl_priv(dev);
+    struct pcmcia_device *link = lp->link;
+    int         result = 0;
+    int         hcf_status = HCF_SUCCESS;
+    /*------------------------------------------------------------------------*/
+
+
+    DBG_FUNC( "wl_adapter_open" );
+    DBG_ENTER( DbgInfo );
+	DBG_PRINT( "%s\n", VERSION_INFO );
+    DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
+
+    if(!pcmcia_dev_present(link))
+    {
+        DBG_LEAVE( DbgInfo );
+        return -ENODEV;
+    }
+
+    link->open++;
+
+    hcf_status = wl_open( dev );
+
+    if( hcf_status != HCF_SUCCESS ) {
+        link->open--;
+        result = -ENODEV;
+    }
+
+    DBG_LEAVE( DbgInfo );
+    return result;
+} // wl_adapter_open
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wl_adapter_close()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Close the device.
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to a net_device structure representing the network
+ *            device to close.
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wl_adapter_close( struct net_device *dev )
+{
+    struct wl_private *lp = wl_priv(dev);
+    struct pcmcia_device *link = lp->link;
+    /*------------------------------------------------------------------------*/
+
+
+    DBG_FUNC( "wl_adapter_close" );
+    DBG_ENTER( DbgInfo );
+    DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
+
+    if( link == NULL ) {
+        DBG_LEAVE( DbgInfo );
+        return -ENODEV;
+    }
+
+    DBG_TRACE( DbgInfo, "%s: Shutting down adapter.\n", dev->name );
+    wl_close( dev );
+
+    link->open--;
+
+    DBG_LEAVE( DbgInfo );
+    return 0;
+} // wl_adapter_close
+/*============================================================================*/
+
+static struct pcmcia_device_id wl_adapter_ids[] = {
+#if ! ((HCF_TYPE) & HCF_TYPE_HII5)
+	PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0003),
+	PCMCIA_DEVICE_PROD_ID12("Agere Systems", "Wireless PC Card Model 0110",
+			    0x33103a9b, 0xe175b0dd),
+#else
+	PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0004),
+	PCMCIA_DEVICE_PROD_ID12("Linksys", "WCF54G_Wireless-G_CompactFlash_Card",
+                            0x0733cc81, 0x98a599e1),
+#endif  // (HCF_TYPE) & HCF_TYPE_HII5
+	PCMCIA_DEVICE_NULL,
+	};
+MODULE_DEVICE_TABLE(pcmcia, wl_adapter_ids);
+
+static struct pcmcia_driver wlags49_driver = {
+    .owner          = THIS_MODULE,
+    .drv            = {
+	.name   = DRIVER_NAME,
+    },
+    .probe	= wl_adapter_attach,
+    .remove	= wl_adapter_detach,
+    .id_table	= wl_adapter_ids,
+    .suspend	= wl_adapter_suspend,
+    .resume	= wl_adapter_resume,
+};
+
+
+
+/*******************************************************************************
+ *	wl_adapter_init_module()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Called by init_module() to perform PCMCIA driver initialization.
+ *
+ *  PARAMETERS:
+ *
+ *      N/A
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      -1 on error
+ *
+ ******************************************************************************/
+int wl_adapter_init_module( void )
+{
+    int ret;
+    /*------------------------------------------------------------------------*/
+
+
+    DBG_FUNC( "wl_adapter_init_module" );
+    DBG_ENTER( DbgInfo );
+    DBG_TRACE( DbgInfo, "wl_adapter_init_module() -- PCMCIA\n" );
+
+    ret = pcmcia_register_driver(&wlags49_driver);
+
+    DBG_LEAVE( DbgInfo );
+    return ret;
+} // wl_adapter_init_module
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wl_adapter_cleanup_module()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Called by cleanup_module() to perform driver uninitialization.
+ *
+ *  PARAMETERS:
+ *
+ *      N/A
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_adapter_cleanup_module( void )
+{
+    DBG_FUNC( "wl_adapter_cleanup_module" );
+    DBG_ENTER( DbgInfo );
+    DBG_TRACE( DbgInfo, "wl_adapter_cleanup_module() -- PCMCIA\n" );
+
+
+    pcmcia_unregister_driver(&wlags49_driver);
+
+    DBG_LEAVE( DbgInfo );
+    return;
+} // wl_adapter_cleanup_module
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wl_adapter_is_open()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Check with Card Services to determine if this device is open.
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the net_device structure whose open status will be
+ *            checked
+ *
+ *  RETURNS:
+ *
+ *      nonzero if device is open
+ *      0 otherwise
+ *
+ ******************************************************************************/
+int wl_adapter_is_open( struct net_device *dev )
+{
+    struct wl_private *lp = wl_priv(dev);
+    struct pcmcia_device *link = lp->link;
+
+    if(!pcmcia_dev_present(link)) {
+        return 0;
+    }
+
+    return( link->open );
+} // wl_adapter_is_open
+/*============================================================================*/
+
+
+#if DBG
+
+/*******************************************************************************
+ *	DbgEvent()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Converts the card serivces events to text for debugging.
+ *
+ *  PARAMETERS:
+ *
+ *      mask    - a integer representing the error(s) being reported by Card
+ *                Services.
+ *
+ *  RETURNS:
+ *
+ *      a pointer to a string describing the error(s)
+ *
+ ******************************************************************************/
+const char* DbgEvent( int mask )
+{
+    static char DbgBuffer[256];
+    char *pBuf;
+    /*------------------------------------------------------------------------*/
+
+
+    pBuf    = DbgBuffer;
+    *pBuf   = '\0';
+
+
+    if( mask & CS_EVENT_WRITE_PROTECT )
+        strcat( pBuf, "WRITE_PROTECT " );
+
+    if(mask & CS_EVENT_CARD_LOCK)
+        strcat( pBuf, "CARD_LOCK " );
+
+    if(mask & CS_EVENT_CARD_INSERTION)
+        strcat( pBuf, "CARD_INSERTION " );
+
+    if(mask & CS_EVENT_CARD_REMOVAL)
+        strcat( pBuf, "CARD_REMOVAL " );
+
+    if(mask & CS_EVENT_BATTERY_DEAD)
+        strcat( pBuf, "BATTERY_DEAD " );
+
+    if(mask & CS_EVENT_BATTERY_LOW)
+        strcat( pBuf, "BATTERY_LOW " );
+
+    if(mask & CS_EVENT_READY_CHANGE)
+        strcat( pBuf, "READY_CHANGE " );
+
+    if(mask & CS_EVENT_CARD_DETECT)
+        strcat( pBuf, "CARD_DETECT " );
+
+    if(mask & CS_EVENT_RESET_REQUEST)
+        strcat( pBuf, "RESET_REQUEST " );
+
+    if(mask & CS_EVENT_RESET_PHYSICAL)
+        strcat( pBuf, "RESET_PHYSICAL " );
+
+    if(mask & CS_EVENT_CARD_RESET)
+        strcat( pBuf, "CARD_RESET " );
+
+    if(mask & CS_EVENT_REGISTRATION_COMPLETE)
+        strcat( pBuf, "REGISTRATION_COMPLETE " );
+
+    // if(mask & CS_EVENT_RESET_COMPLETE)
+    //     strcat( pBuf, "RESET_COMPLETE " );
+
+    if(mask & CS_EVENT_PM_SUSPEND)
+        strcat( pBuf, "PM_SUSPEND " );
+
+    if(mask & CS_EVENT_PM_RESUME)
+        strcat( pBuf, "PM_RESUME " );
+
+    if(mask & CS_EVENT_INSERTION_REQUEST)
+        strcat( pBuf, "INSERTION_REQUEST " );
+
+    if(mask & CS_EVENT_EJECTION_REQUEST)
+        strcat( pBuf, "EJECTION_REQUEST " );
+
+    if(mask & CS_EVENT_MTD_REQUEST)
+        strcat( pBuf, "MTD_REQUEST " );
+
+    if(mask & CS_EVENT_ERASE_COMPLETE)
+        strcat( pBuf, "ERASE_COMPLETE " );
+
+    if(mask & CS_EVENT_REQUEST_ATTENTION)
+        strcat( pBuf, "REQUEST_ATTENTION " );
+
+    if(mask & CS_EVENT_CB_DETECT)
+        strcat( pBuf, "CB_DETECT " );
+
+    if(mask & CS_EVENT_3VCARD)
+        strcat( pBuf, "3VCARD " );
+
+    if(mask & CS_EVENT_XVCARD)
+        strcat( pBuf, "XVCARD " );
+
+
+    if( *pBuf ) {
+        pBuf[strlen(pBuf) - 1] = '\0';
+    } else {
+        if( mask != 0x0 ) {
+            sprintf( pBuf, "<<0x%08x>>", mask );
+        }
+    }
+
+    return pBuf;
+} // DbgEvent
+/*============================================================================*/
+
+#endif  /* DBG */
diff --git a/drivers/staging/wlags49_h2/wl_cs.h b/drivers/staging/wlags49_h2/wl_cs.h
new file mode 100644
index 0000000..2a0e674
--- /dev/null
+++ b/drivers/staging/wlags49_h2/wl_cs.h
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Agere Systems Inc.
+ * Wireless device driver for Linux (wlags49).
+ *
+ * Copyright (c) 1998-2003 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * Initially developed by TriplePoint, Inc.
+ *   http://www.triplepoint.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ *   Header describing information required for the driver to support PCMCIA.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2003 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following Disclaimer as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ ******************************************************************************/
+
+#ifndef __WL_CS_H__
+#define __WL_CS_H__
+
+
+
+
+/*******************************************************************************
+ *  function protoypes
+ ******************************************************************************/
+
+void wl_adapter_insert(struct pcmcia_device *link);
+
+void wl_adapter_release(struct pcmcia_device *link);
+
+int wl_adapter_event(event_t event, int priority, event_callback_args_t *args );
+
+int wl_adapter_init_module( void );
+
+void wl_adapter_cleanup_module( void );
+
+int wl_adapter_open(struct net_device *dev);
+
+int wl_adapter_close(struct net_device *dev);
+
+int wl_adapter_is_open(struct net_device *dev);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+void cs_error(client_handle_t handle, int func, int ret);
+#endif
+
+const char *DbgEvent( int mask );
+
+
+
+#endif  // __WL_CS_H__
diff --git a/drivers/staging/wlags49_h2/wl_enc.c b/drivers/staging/wlags49_h2/wl_enc.c
new file mode 100644
index 0000000..48c44c8
--- /dev/null
+++ b/drivers/staging/wlags49_h2/wl_enc.c
@@ -0,0 +1,231 @@
+
+/*******************************************************************************
+ * Agere Systems Inc.
+ * Wireless device driver for Linux (wlags49).
+ *
+ * Copyright (c) 1998-2003 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * Initially developed by TriplePoint, Inc.
+ *   http://www.triplepoint.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ *   This file defines functions related to WEP key coding/decoding.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2003 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following Disclaimer as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ ******************************************************************************/
+
+/*******************************************************************************
+ *  include files
+ ******************************************************************************/
+#include <wl_version.h>
+
+#include <debug.h>
+#include <hcf.h>
+
+#include <wl_enc.h>
+
+
+
+
+/*******************************************************************************
+ *  global definitions
+ ******************************************************************************/
+#if DBG
+
+extern dbg_info_t *DbgInfo;
+
+#endif  /* DBG */
+
+
+
+
+/*******************************************************************************
+ *	wl_wep_code()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function encodes a set of wep keys for privacy
+ *
+ *  PARAMETERS:
+ *
+ *      szCrypt -
+ *      szDest  -
+ *      Data    -
+ *      nLen    -
+ *
+ *  RETURNS:
+ *
+ *      OK
+ *
+ ******************************************************************************/
+int wl_wep_code( char *szCrypt, char *szDest, void *Data, int nLen )
+{
+    int     i;
+    int     t;
+    int     k ;
+    char    bits;
+    char    *szData = (char *) Data;
+    /*------------------------------------------------------------------------*/
+
+
+    for( i = bits = 0 ; i < MACADDRESS_STR_LEN; i++ ) {
+	    bits ^= szCrypt[i];
+	    bits += szCrypt[i];
+    }
+
+    for( i = t = *szDest = 0; i < nLen; i++, t++ ) {
+	    k = szData[i] ^ ( bits + i );
+
+
+        switch( i % 3 ) {
+
+        case 0 :
+
+            szDest[t]   = ((k & 0xFC) >> 2) + CH_START ;
+			szDest[t+1] = ((k & 0x03) << 4) + CH_START ;
+	        szDest[t+2] = '\0';
+
+            break;
+
+
+        case 1 :
+
+            szDest[t]  += (( k & 0xF0 ) >> 4 );
+			szDest[t+1] = (( k & 0x0F ) << 2 ) + CH_START ;
+	        szDest[t+2] = '\0';
+
+            break;
+
+
+        case 2 :
+
+            szDest[t]  += (( k & 0xC0 ) >> 6 );
+			szDest[t+1] = ( k & 0x3F ) + CH_START ;
+	        szDest[t+2] = '\0';
+	        t++;
+
+            break;
+        }
+    }
+
+    return( strlen( szDest )) ;
+
+}
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wl_wep_decode()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function decodes a set of WEP keys for use by the card.
+ *
+ *  PARAMETERS:
+ *
+ *      szCrypt -
+ *      szDest  -
+ *      Data    -
+ *
+ *  RETURNS:
+ *
+ *      OK
+ *
+ ******************************************************************************/
+int wl_wep_decode( char *szCrypt, void *Dest, char *szData )
+{
+    int     i;
+    int     t;
+    int     nLen;
+    char    bits;
+    char    *szDest = Dest;
+  /*------------------------------------------------------------------------*/
+
+
+  for( i = bits = 0 ; i < 12; i++ ) {
+      bits ^= szCrypt[i] ;
+      bits += szCrypt[i] ;
+  }
+
+  nLen = ( strlen( szData ) * 3) / 4 ;
+
+  for( i = t = 0; i < nLen; i++, t++ ) {
+      switch( i % 3 ) {
+      case 0 :
+
+          szDest[i] = ((( szData[t]-CH_START ) & 0x3f ) << 2 ) +
+                      ((( szData[t+1]-CH_START ) & 0x30 ) >> 4 );
+	      break;
+
+
+      case 1 :
+          szDest[i] = ((( szData[t]-CH_START ) & 0x0f ) << 4 ) +
+                      ((( szData[t+1]-CH_START ) & 0x3c ) >> 2 );
+	      break;
+
+
+      case 2 :
+          szDest[i] = ((( szData[t]-CH_START ) & 0x03 ) << 6 ) +
+                       (( szData[t+1]-CH_START ) & 0x3f );
+	      t++;
+	      break;
+      }
+
+	szDest[i] ^= ( bits + i ) ;
+
+  }
+
+  return( i ) ;
+
+}
+/*============================================================================*/
+
diff --git a/drivers/staging/wlags49_h2/wl_enc.h b/drivers/staging/wlags49_h2/wl_enc.h
new file mode 100644
index 0000000..b4f54d8
--- /dev/null
+++ b/drivers/staging/wlags49_h2/wl_enc.h
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Agere Systems Inc.
+ * Wireless device driver for Linux (wlags49).
+ *
+ * Copyright (c) 1998-2003 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * Initially developed by TriplePoint, Inc.
+ *   http://www.triplepoint.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ *   Header for performing coding/decoding of the WEP keys.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2003 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following Disclaimer as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ ******************************************************************************/
+
+#ifndef __WAVELAN2_ENCRYPTION_H__
+#define __WAVELAN2_ENCRYPTION_H__
+
+
+
+
+/*******************************************************************************
+ * constant definitions
+ ******************************************************************************/
+#define CRYPT_CODE					"57617665A5D6"
+#define ENCRYPTION_LEN				102
+#define ENCRYPTION_MAGIC			0x48576877L	// HWhw
+#define DEF_CRYPT_STR				"G?TIUEA]d5MAdZV'eUb&&6.)'&:,'VF/(FR2)6^5*'*8*W6;+GB>,7NA-'ZD-X&G.H2J/8>M0(JP0XVS1HbV29.Y3):\\3YF_4IRb56"
+
+#define DEFAULT_CRYPT_MAC			"W\x01\x6B\x66\xA5\x5A"
+#define CH_START					'&'
+#define MACADDRESS_STR_LEN			12
+
+#define KEY_LEN                     14
+#define NUM_KEYS                    4
+
+#define KEY_LENGTH_NONE_ASCII       0
+#define KEY_LENGTH_64_BIT_ASCII     5
+#define KEY_LENGTH_128_BIT_ASCII    13
+
+#define KEY_LENGTH_NONE_HEX         ( KEY_LENGTH_NONE_ASCII    * sizeof( unsigned short ))
+#define KEY_LENGTH_64_BIT_HEX       ( KEY_LENGTH_64_BIT_ASCII  * sizeof( unsigned short ))
+#define KEY_LENGTH_128_BIT_HEX      ( KEY_LENGTH_128_BIT_ASCII * sizeof( unsigned short ))
+
+
+
+
+/*******************************************************************************
+ * type definitions
+ ******************************************************************************/
+typedef struct _encstct
+{
+	hcf_32	                   dwMagic;
+	hcf_16	                   wTxKeyID;
+	hcf_16	                   wEnabled;
+	CFG_DEFAULT_KEYS_STRCT     EncStr;
+}
+ENCSTRCT, *PENCSTRCT;
+
+
+
+
+/*******************************************************************************
+ * function prrottypes
+ ******************************************************************************/
+int wl_wep_code( char *szCrypt, char *szDest, void *Data, int nLen );
+
+int wl_wep_decode( char *szCrypt, void *Dest, char *szData );
+
+
+
+
+#endif  // __WAVELAN2_ENCRYPTION_H__
diff --git a/drivers/staging/wlags49_h2/wl_if.h b/drivers/staging/wlags49_h2/wl_if.h
new file mode 100644
index 0000000..ed2b413
--- /dev/null
+++ b/drivers/staging/wlags49_h2/wl_if.h
@@ -0,0 +1,234 @@
+/*******************************************************************************
+ * Agere Systems Inc.
+ * Wireless device driver for Linux (wlags49).
+ *
+ * Copyright (c) 1998-2003 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * Initially developed by TriplePoint, Inc.
+ *   http://www.triplepoint.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ *   Driver common header for info needed by driver source and user-space
+ *   processes communicating with the driver.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2003 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following Disclaimer as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ ******************************************************************************/
+
+#ifndef __WAVELAN2_IF_H__
+#define __WAVELAN2_IF_H__
+
+
+
+
+/*******************************************************************************
+ *  constant definitions
+ ******************************************************************************/
+#define MAX_LTV_BUF_SIZE            (512 - (sizeof(hcf_16) * 2))
+
+#define HCF_TALLIES_SIZE            (sizeof(CFG_HERMES_TALLIES_STRCT) + \
+                                     (sizeof(hcf_16) * 2))
+
+#define HCF_MAX_MULTICAST           16
+#define HCF_MAX_NAME_LEN            32
+#define MAX_LINE_SIZE   			256
+#define HCF_NUM_IO_PORTS            0x80
+#define TX_TIMEOUT                  ((800 * HZ) / 1000)
+
+
+//#define HCF_MIN_COMM_QUALITY        0
+//#define HCF_MAX_COMM_QUALITY        92
+//#define HCF_MIN_SIGNAL_LEVEL        47
+//#define HCF_MAX_SIGNAL_LEVEL        138
+//#define HCF_MIN_NOISE_LEVEL         47
+//#define HCF_MAX_NOISE_LEVEL         138
+//#define HCF_0DBM_OFFSET             149
+
+// PE1DNN
+// Better data from the real world. Not scientific but empirical data gathered
+// from a Thomson Speedtouch 110 which is identified as:
+// PCMCIA Info: "Agere Systems" "Wireless PC Card Model 0110"
+//              Manufacture ID: 0156,0003
+// Lowest measurment for noise floor seen is value 54
+// Highest signal strength in close proximity to the AP seen is value 118
+// Very good must be arround 100 (otherwise its never "full scale"
+// All other constants are derrived from these. This makes the signal gauge
+// work for me...
+#define HCF_MIN_SIGNAL_LEVEL        54
+#define HCF_MAX_SIGNAL_LEVEL        100
+#define HCF_MIN_NOISE_LEVEL         HCF_MIN_SIGNAL_LEVEL
+#define HCF_MAX_NOISE_LEVEL         HCF_MAX_SIGNAL_LEVEL
+#define HCF_0DBM_OFFSET             (HCF_MAX_SIGNAL_LEVEL + 1)
+#define HCF_MIN_COMM_QUALITY        0
+#define HCF_MAX_COMM_QUALITY        (HCF_MAX_SIGNAL_LEVEL - HCF_MIN_NOISE_LEVEL + 1)
+
+
+/* For encryption (WEP) */
+#define MIN_KEY_SIZE                5       // 40 bits RC4 - WEP
+#define MAX_KEY_SIZE                13      // 104 bits
+#define MAX_KEYS                    4
+
+#define RADIO_CHANNELS              14
+#define RADIO_SENSITIVITY_LEVELS    3
+#define RADIO_TX_POWER_MWATT        32
+#define RADIO_TX_POWER_DBM          15
+
+#define MIN_RTS_BYTES               0
+#define MAX_RTS_BYTES               2347
+
+#define MAX_RATES                   8
+#define MEGABIT                     1024*1024
+
+#define HCF_FAILURE                 0xFF
+#define UIL_FAILURE		            0xFF
+#define CFG_UIL_CONNECT             0xA123          // Define differently?
+#define CFG_UIL_CONNECT_ACK_CODE    0x5653435A      // VSCZ
+#define WVLAN2_UIL_CONNECTED        (0x01L << 0)
+#define WVLAN2_UIL_BUSY             (0x01L << 1)
+
+
+
+
+/*******************************************************************************
+ * driver ioctl interface
+ ******************************************************************************/
+#define WVLAN2_IOCTL_UIL            SIOCDEVPRIVATE
+
+/* The UIL Interface used in conjunction with the WVLAN2_IOCTL_UIL code above
+   is defined in mdd.h. A quick reference of the UIL codes is listed below */
+/*
+UIL_FUN_CONNECT
+UIL_FUN_DISCONNECT
+UIL_FUN_ACTION
+    UIL_ACT_BLOCK
+    UIL_ACT_UNBLOCK
+    UIL_ACT_SCA
+    UIL_ACT_DIAG
+    UIL_ACT_APPLY
+UIL_FUN_SEND_DIAG_MSG
+UIL_FUN_GET_INFO
+UIL_FUN_PUT_INFO
+*/
+
+#define SIOCSIWNETNAME              SIOCDEVPRIVATE+1
+#define SIOCGIWNETNAME              SIOCDEVPRIVATE+2
+#define SIOCSIWSTANAME              SIOCDEVPRIVATE+3
+#define SIOCGIWSTANAME              SIOCDEVPRIVATE+4
+#define SIOCSIWPORTTYPE             SIOCDEVPRIVATE+5
+#define SIOCGIWPORTTYPE             SIOCDEVPRIVATE+6
+
+/* IOCTL code for the RTS interface */
+#define WL_IOCTL_RTS                SIOCDEVPRIVATE+7
+
+/* IOCTL subcodes for WL_IOCTL_RTS */
+#define WL_IOCTL_RTS_READ           1
+#define WL_IOCTL_RTS_WRITE          2
+#define WL_IOCTL_RTS_BATCH_READ     3
+#define WL_IOCTL_RTS_BATCH_WRITE    4
+
+
+/*******************************************************************************
+ * STRUCTURE DEFINITIONS
+ ******************************************************************************/
+typedef struct
+{
+    __u16   length;
+    __u8    name[HCF_MAX_NAME_LEN];
+}
+wvName_t;
+
+
+typedef struct
+{
+    hcf_16      len;
+    hcf_16      typ;
+    union
+    {
+        hcf_8       u8[MAX_LTV_BUF_SIZE / sizeof(hcf_8)];
+        hcf_16      u16[MAX_LTV_BUF_SIZE / sizeof(hcf_16)];
+        hcf_32      u32[MAX_LTV_BUF_SIZE / sizeof(hcf_32)];
+    } u;
+}
+ltv_t;
+
+
+struct uilreq
+{
+    union
+    {
+        char    ifrn_name[IFNAMSIZ];
+    } ifr_ifrn;
+
+    IFBP        hcfCtx;
+    __u8        command;
+    __u8        result;
+
+    /* The data field in this structure is typically an LTV of some type. The
+       len field is the size of the buffer in bytes, as opposed to words (like
+       the L-field in the LTV */
+    __u16       len;
+    void       *data;
+};
+
+
+struct rtsreq
+{
+    union
+    {
+        char    ifrn_name[IFNAMSIZ];
+    }
+    ifr_ifrn;
+
+    __u16   typ;
+    __u16   reg;
+    __u16   len;
+    __u16   *data;
+};
+
+
+#endif  // __WAVELAN2_IF_H__
+
diff --git a/drivers/staging/wlags49_h2/wl_internal.h b/drivers/staging/wlags49_h2/wl_internal.h
new file mode 100644
index 0000000..466fb62
--- /dev/null
+++ b/drivers/staging/wlags49_h2/wl_internal.h
@@ -0,0 +1,1056 @@
+/*******************************************************************************
+ * Agere Systems Inc.
+ * Wireless device driver for Linux (wlags49).
+ *
+ * Copyright (c) 1998-2003 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * Initially developed by TriplePoint, Inc.
+ *   http://www.triplepoint.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ *   Header for defintions and macros internal to the drvier.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2003 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following Disclaimer as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ ******************************************************************************/
+
+#ifndef __WAVELAN2_H__
+#define __WAVELAN2_H__
+
+
+
+
+/*******************************************************************************
+ *  include files
+ ******************************************************************************/
+#include <linux/version.h>
+#ifdef BUS_PCMCIA
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+#include <pcmcia/version.h>
+#endif
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ciscode.h>
+#include <pcmcia/ds.h>
+#endif  // BUS_PCMCIA
+
+#ifdef HAS_WIRELESS_EXTENSIONS
+#include <linux/wireless.h>
+#if WIRELESS_EXT > 13
+#include <net/iw_handler.h>
+#endif // WIRELESS_EXT > 13
+#define USE_DBM
+#define RETURN_CURRENT_NETWORKNAME
+#define USE_FREQUENCY
+#endif // HAS_WIRELESS_EXTENSIONS/
+
+#include <linux/list.h>
+
+#include <linux/interrupt.h>
+
+
+
+
+/*******************************************************************************
+ *  constant definitions
+ ******************************************************************************/
+#define p_u8    __u8
+#define p_s8    __s8
+#define p_u16   __u16
+#define p_s16   __s16
+#define p_u32   __u32
+#define p_s32   __s32
+#define p_char  char
+
+#define MAX_KEY_LEN         (2 + (13 * 2)) // 0x plus 13 hex digit pairs
+#define MB_SIZE             1024
+#define MAX_ENC_LEN         104
+
+#define MAX_SCAN_TIME_SEC   8
+#define MAX_NAPS            32
+
+#define CFG_MB_INFO         0x0820		//Mail Box Info Block
+
+#define NUM_WDS_PORTS       6
+
+#define WVLAN_MAX_LOOKAHEAD (HCF_MAX_MSG+46) /* as per s0005MIC_4.doc */
+
+
+/* Min/Max/Default Parameter Values */
+#if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
+//;? why this difference depending on compile option, seems to me it should depend on runtime if anything
+#define PARM_DEFAULT_SSID                       "LinuxAP"
+#else
+#define PARM_DEFAULT_SSID                       "ANY"
+#endif // HCF_TYPE_AP
+
+#define PARM_MIN_NAME_LEN                       1
+#define PARM_MAX_NAME_LEN                       32
+
+
+/* The following definitions pertain to module and profile parameters */
+// #define PARM_AP_MODE                            APMode
+// #define PARM_NAME_AP_MODE						TEXT("APMode")
+// #define PARM_DEFAULT_AP_MODE					FALSE
+
+#define PARM_AUTHENTICATION                     Authentication
+#define PARM_NAME_AUTHENTICATION				TEXT("Authentication")
+#define PARM_MIN_AUTHENTICATION                 1
+#define PARM_MAX_AUTHENTICATION                 2
+#define PARM_DEFAULT_AUTHENTICATION             1
+
+#define PARM_AUTH_KEY_MGMT_SUITE                AuthKeyMgmtSuite
+#define PARM_NAME_AUTH_KEY_MGMT_SUITE           TEXT("AuthKeyMgmtSuite")
+#define PARM_MIN_AUTH_KEY_MGMT_SUITE            0
+#define PARM_MAX_AUTH_KEY_MGMT_SUITE            4
+#define PARM_DEFAULT_AUTH_KEY_MGMT_SUITE        0
+
+#define PARM_BRSC_2GHZ                          BRSC2GHz
+#define PARM_NAME_BRSC_2GHZ                     TEXT("BRSC2GHz")
+#define PARM_MIN_BRSC                           0x0000
+#define PARM_MAX_BRSC                           0x0FFF
+#define PARM_DEFAULT_BRSC_2GHZ                  0x000F
+
+#define PARM_BRSC_5GHZ                          BRSC5GHz
+#define PARM_NAME_BRSC_5GHZ                     TEXT("BRSC5GHz")
+#define PARM_DEFAULT_BRSC_5GHZ                  0x0150
+
+#define PARM_COEXISTENCE                        Coexistence
+#define PARM_NAME_COEXISTENCE                   TEXT("Coexistence")
+#define PARM_MIN_COEXISTENCE                    0x0000
+#define PARM_MAX_COEXISTENCE                    0x0007
+#define PARM_DEFAULT_COEXISTENCE                0x0000
+
+#define PARM_CONFIGURED                         Configured
+#define PARM_NAME_CONFIGURED					TEXT("Configured")
+
+#define PARM_CONNECTION_CONTROL                 ConnectionControl
+#define PARM_NAME_CONNECTION_CONTROL            TEXT("ConnectionControl")
+#define PARM_MIN_CONNECTION_CONTROL             0
+#define PARM_MAX_CONNECTION_CONTROL             3
+#define PARM_DEFAULT_CONNECTION_CONTROL         2
+
+#define PARM_CREATE_IBSS                        CreateIBSS
+#define PARM_NAME_CREATE_IBSS                   TEXT("CreateIBSS")
+#define PARM_DEFAULT_CREATE_IBSS                FALSE
+#define PARM_DEFAULT_CREATE_IBSS_STR            "N"
+
+#define PARM_DEBUG_FLAG             	    	DebugFlag
+#define PARM_NAME_DEBUG_FLAG            		TEXT("DebugFlag")
+#define PARM_MIN_DEBUG_FLAG             		0
+#define PARM_MAX_DEBUG_FLAG             		0xFFFF
+#define PARM_DEFAULT_DEBUG_FLAG         		0xFFFF
+
+#define PARM_DESIRED_SSID                       DesiredSSID
+#define PARM_NAME_DESIRED_SSID                  TEXT("DesiredSSID")
+
+#define PARM_DOWNLOAD_FIRMWARE                  DownloadFirmware
+#define PARM_NAME_DOWNLOAD_FIRMWARE             TEXT("DownloadFirmware")
+
+#define PARM_DRIVER_ENABLE                      DriverEnable
+#define PARM_NAME_DRIVER_ENABLE					TEXT("DriverEnable")
+#define PARM_DEFAULT_DRIVER_ENABLE				TRUE
+
+#define PARM_ENABLE_ENCRYPTION                  EnableEncryption
+#define PARM_NAME_ENABLE_ENCRYPTION             TEXT("EnableEncryption")
+#define PARM_MIN_ENABLE_ENCRYPTION              0
+#define PARM_MAX_ENABLE_ENCRYPTION              7
+#define PARM_DEFAULT_ENABLE_ENCRYPTION          0
+
+#define PARM_ENCRYPTION                         Encryption
+#define PARM_NAME_ENCRYPTION                    TEXT("Encryption")
+
+#define PARM_EXCLUDE_UNENCRYPTED                ExcludeUnencrypted
+#define PARM_NAME_EXCLUDE_UNENCRYPTED           TEXT("ExcludeUnencrypted")
+#define PARM_DEFAULT_EXCLUDE_UNENCRYPTED        TRUE
+#define PARM_DEFAULT_EXCLUDE_UNENCRYPTED_STR    "N"
+
+#define PARM_INTRA_BSS_RELAY                    IntraBSSRelay
+#define PARM_NAME_INTRA_BSS_RELAY               TEXT("IntraBSSRelay")
+#define PARM_DEFAULT_INTRA_BSS_RELAY            TRUE
+#define PARM_DEFAULT_INTRA_BSS_RELAY_STR        "Y"
+
+#define PARM_KEY1                               Key1
+#define PARM_NAME_KEY1                          TEXT("Key1")
+#define PARM_KEY2                               Key2
+#define PARM_NAME_KEY2                          TEXT("Key2")
+#define PARM_KEY3                               Key3
+#define PARM_NAME_KEY3                          TEXT("Key3")
+#define PARM_KEY4                               Key4
+#define PARM_NAME_KEY4                          TEXT("Key4")
+
+//;? #define PARM_KEY_FORMAT                         AsciiHex
+//;? #define PARM_NAME_KEY_FORMAT                    TEXT("AsciiHex")
+
+#define PARM_LOAD_BALANCING                     LoadBalancing
+#define PARM_NAME_LOAD_BALANCING                TEXT("LoadBalancing")
+#define PARM_DEFAULT_LOAD_BALANCING             TRUE
+#define PARM_DEFAULT_LOAD_BALANCING_STR         "Y"
+
+#define PARM_MAX_DATA_LENGTH                    MaxDataLength
+#define PARM_NAME_MAX_DATA_LENGTH				TEXT("MaxDataLength")
+
+#define PARM_MAX_SLEEP                          MaxSleepDuration
+#define PARM_NAME_MAX_SLEEP                     TEXT("MaxSleepDuration")
+#define PARM_MIN_MAX_PM_SLEEP                   1								//;?names nearly right?
+#define PARM_MAX_MAX_PM_SLEEP                   65535
+#define PARM_DEFAULT_MAX_PM_SLEEP               100
+
+#define PARM_MEDIUM_DISTRIBUTION                MediumDistribution
+#define PARM_NAME_MEDIUM_DISTRIBUTION           TEXT("MediumDistribution")
+#define PARM_DEFAULT_MEDIUM_DISTRIBUTION        TRUE
+#define PARM_DEFAULT_MEDIUM_DISTRIBUTION_STR    "Y"
+
+#define PARM_MICROWAVE_ROBUSTNESS               MicroWaveRobustness
+#define PARM_NAME_MICROWAVE_ROBUSTNESS          TEXT("MicroWaveRobustness")
+#define PARM_DEFAULT_MICROWAVE_ROBUSTNESS       FALSE
+#define PARM_DEFAULT_MICROWAVE_ROBUSTNESS_STR   "N"
+
+#define PARM_MULTICAST_PM_BUFFERING             MulticastPMBuffering
+#define PARM_NAME_MULTICAST_PM_BUFFERING	    TEXT("MulticastPMBuffering")
+#define PARM_DEFAULT_MULTICAST_PM_BUFFERING     TRUE
+#define PARM_DEFAULT_MULTICAST_PM_BUFFERING_STR "Y"
+
+#define PARM_MULTICAST_RATE                     MulticastRate
+#define PARM_NAME_MULTICAST_RATE                TEXT("MulticastRate")
+#ifdef WARP
+#define PARM_MIN_MULTICAST_RATE                 0x0001
+#define PARM_MAX_MULTICAST_RATE                 0x0fff
+#define PARM_DEFAULT_MULTICAST_RATE_2GHZ        0x0004
+#define PARM_DEFAULT_MULTICAST_RATE_5GHZ        0x0010
+#else
+#define PARM_MIN_MULTICAST_RATE                 0x0001
+#define PARM_MAX_MULTICAST_RATE                 0x0004
+#define PARM_DEFAULT_MULTICAST_RATE_2GHZ        0x0002
+#define PARM_DEFAULT_MULTICAST_RATE_5GHZ        0x0000
+#endif  // WARP
+
+#define PARM_MULTICAST_RX                       MulticastReceive
+#define PARM_NAME_MULTICAST_RX                  TEXT("MulticastReceive")
+#define PARM_DEFAULT_MULTICAST_RX               TRUE
+#define PARM_DEFAULT_MULTICAST_RX_STR           "Y"
+
+#define PARM_NETWORK_ADDR                       NetworkAddress
+#define PARM_NAME_NETWORK_ADDR                  TEXT("NetworkAddress")
+#define PARM_DEFAULT_NETWORK_ADDR               { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
+
+#define PARM_NETWORK_TYPE                       NetworkType
+#define PARM_NAME_NETWORK_TYPE					TEXT("NetworkType")
+#define PARM_DEFAULT_NETWORK_TYPE   			0
+
+#define PARM_OWN_ATIM_WINDOW                    OwnATIMWindow
+#define PARM_NAME_OWN_ATIM_WINDOW				TEXT("OwnATIMWindow")
+#define PARM_MIN_OWN_ATIM_WINDOW                0
+#define PARM_MAX_OWN_ATIM_WINDOW                100
+#define PARM_DEFAULT_OWN_ATIM_WINDOW            0
+
+#define PARM_OWN_BEACON_INTERVAL                OwnBeaconInterval
+#define PARM_NAME_OWN_BEACON_INTERVAL           TEXT("OwnBeaconInterval")
+#define PARM_MIN_OWN_BEACON_INTERVAL            20
+#define PARM_MAX_OWN_BEACON_INTERVAL            200
+#define PARM_DEFAULT_OWN_BEACON_INTERVAL        100
+
+#define PARM_OWN_CHANNEL                        OwnChannel
+#define PARM_NAME_OWN_CHANNEL                   TEXT("OwnChannel")
+#define PARM_MIN_OWN_CHANNEL                    1
+#define PARM_MAX_OWN_CHANNEL                    161
+#define PARM_DEFAULT_OWN_CHANNEL                10
+
+#define PARM_OWN_DTIM_PERIOD                    OwnDTIMPeriod
+#define PARM_NAME_OWN_DTIM_PERIOD	            TEXT("OwnDTIMPeriod")
+#define PARM_MIN_OWN_DTIM_PERIOD                1
+#define PARM_MAX_OWN_DTIM_PERIOD                65535
+#define PARM_DEFAULT_OWN_DTIM_PERIOD            1
+
+#define PARM_OWN_NAME                           OwnName
+#define PARM_NAME_OWN_NAME                      TEXT("OwnName")
+#define PARM_DEFAULT_OWN_NAME                   "Linux"
+
+#define PARM_OWN_SSID                           OwnSSID
+#define PARM_NAME_OWN_SSID                      TEXT("OwnSSID")
+
+#define PARM_PM_ENABLED                         PMEnabled
+#define PARM_NAME_PM_ENABLED                    TEXT("PMEnabled")
+#define PARM_MAX_PM_ENABLED						3
+
+#define PARM_PMEPS                              PMEPS
+#define PARM_NAME_PMEPS                         TEXT("PMEPS")
+
+#define PARM_PM_HOLDOVER_DURATION               PMHoldoverDuration
+#define PARM_NAME_PM_HOLDOVER_DURATION          TEXT("PMHoldoverDuration")
+#define PARM_MIN_PM_HOLDOVER_DURATION           1
+#define PARM_MAX_PM_HOLDOVER_DURATION           1000
+#define PARM_DEFAULT_PM_HOLDOVER_DURATION       100
+
+#define PARM_PM_MODE                            PowerMode
+#define PARM_NAME_PM_MODE                       TEXT("PowerMode")
+
+#define PARM_PORT_TYPE                          PortType
+#define PARM_NAME_PORT_TYPE                     TEXT("PortType")
+#define PARM_MIN_PORT_TYPE                      1
+#define PARM_MAX_PORT_TYPE                      3
+#define PARM_DEFAULT_PORT_TYPE                  1
+
+#define PARM_PROMISCUOUS_MODE                   PromiscuousMode
+#define PARM_NAME_PROMISCUOUS_MODE              TEXT("PromiscuousMode")
+#define PARM_DEFAULT_PROMISCUOUS_MODE           FALSE
+#define PARM_DEFAULT_PROMISCUOUS_MODE_STR       "N"
+
+#define PARM_REJECT_ANY                         RejectANY
+#define PARM_NAME_REJECT_ANY				    TEXT("RejectANY")
+#define PARM_DEFAULT_REJECT_ANY                 FALSE
+#define PARM_DEFAULT_REJECT_ANY_STR             "N"
+
+#define PARM_RTS_THRESHOLD                      RTSThreshold
+#define PARM_NAME_RTS_THRESHOLD                 TEXT("RTSThreshold")
+#define PARM_MIN_RTS_THRESHOLD                  0
+#define PARM_MAX_RTS_THRESHOLD                  2347
+#define PARM_DEFAULT_RTS_THRESHOLD              2347
+
+#define PARM_RTS_THRESHOLD1                     RTSThreshold1
+#define PARM_NAME_RTS_THRESHOLD1                TEXT("RTSThreshold1")
+#define PARM_RTS_THRESHOLD2                     RTSThreshold2
+#define PARM_NAME_RTS_THRESHOLD2                TEXT("RTSThreshold2")
+#define PARM_RTS_THRESHOLD3                     RTSThreshold3
+#define PARM_NAME_RTS_THRESHOLD3                TEXT("RTSThreshold3")
+#define PARM_RTS_THRESHOLD4                     RTSThreshold4
+#define PARM_NAME_RTS_THRESHOLD4                TEXT("RTSThreshold4")
+#define PARM_RTS_THRESHOLD5                     RTSThreshold5
+#define PARM_NAME_RTS_THRESHOLD5                TEXT("RTSThreshold5")
+#define PARM_RTS_THRESHOLD6                     RTSThreshold6
+#define PARM_NAME_RTS_THRESHOLD6                TEXT("RTSThreshold6")
+
+#define PARM_SRSC_2GHZ                          SRSC2GHz
+#define PARM_NAME_SRSC_2GHZ                     TEXT("SRSC2GHz")
+#define PARM_MIN_SRSC                           0x0000
+#define PARM_MAX_SRSC                           0x0FFF
+#define PARM_DEFAULT_SRSC_2GHZ                  0x0FFF
+
+#define PARM_SRSC_5GHZ                          SRSC5GHz
+#define PARM_NAME_SRSC_5GHZ                     TEXT("SRSC5GHz")
+#define PARM_DEFAULT_SRSC_5GHZ                  0x0FF0
+
+#define PARM_SYSTEM_SCALE                       SystemScale
+#define PARM_NAME_SYSTEM_SCALE                  TEXT("SystemScale")
+#define PARM_MIN_SYSTEM_SCALE                   1
+#define PARM_MAX_SYSTEM_SCALE                   5
+#define PARM_DEFAULT_SYSTEM_SCALE               1
+
+#define PARM_TX_KEY                             TxKey
+#define PARM_NAME_TX_KEY                        TEXT("TxKey")
+#define PARM_MIN_TX_KEY                         1
+#define PARM_MAX_TX_KEY                         4
+#define PARM_DEFAULT_TX_KEY                     1
+
+#define PARM_TX_POW_LEVEL                       TxPowLevel
+#define PARM_NAME_TX_POW_LEVEL                  TEXT("TxPowLevel")
+#define PARM_MIN_TX_POW_LEVEL                   1   // 20 dBm
+#define PARM_MAX_TX_POW_LEVEL                   6   //  8 dBm
+#define PARM_DEFAULT_TX_POW_LEVEL               3   // 15 dBm
+
+#define PARM_TX_RATE                            TxRateControl
+#define PARM_NAME_TX_RATE                       TEXT("TxRateControl")
+#define PARM_MIN_TX_RATE                        0x0001
+#ifdef WARP
+#define PARM_MAX_TX_RATE                        0x0FFF
+#define PARM_DEFAULT_TX_RATE_2GHZ               0x0FFF
+#define PARM_DEFAULT_TX_RATE_5GHZ               0x0FF0
+#else
+#define PARM_MAX_TX_RATE                        0x0007
+#define PARM_DEFAULT_TX_RATE_2GHZ               0x0003
+#define PARM_DEFAULT_TX_RATE_5GHZ               0x0000
+#endif  // WARP
+
+#define PARM_TX_RATE1                           TxRateControl1
+#define PARM_NAME_TX_RATE1                      TEXT("TxRateControl1")
+#define PARM_TX_RATE2                           TxRateControl2
+#define PARM_NAME_TX_RATE2                      TEXT("TxRateControl2")
+#define PARM_TX_RATE3                           TxRateControl3
+#define PARM_NAME_TX_RATE3                      TEXT("TxRateControl3")
+#define PARM_TX_RATE4                           TxRateControl4
+#define PARM_NAME_TX_RATE4                      TEXT("TxRateControl4")
+#define PARM_TX_RATE5                           TxRateControl5
+#define PARM_NAME_TX_RATE5                      TEXT("TxRateControl5")
+#define PARM_TX_RATE6                           TxRateControl6
+#define PARM_NAME_TX_RATE6                      TEXT("TxRateControl6")
+
+#define PARM_VENDORDESCRIPTION                  VendorDescription
+#define PARM_NAME_VENDORDESCRIPTION				TEXT("VendorDescription")
+
+#define PARM_WDS_ADDRESS                        WDSAddress
+#define PARM_NAME_WDS_ADDRESS					TEXT("WDSAddress")
+
+#define PARM_WDS_ADDRESS1                       WDSAddress1
+#define PARM_NAME_WDS_ADDRESS1					TEXT("WDSAddress1")
+#define PARM_WDS_ADDRESS2                       WDSAddress2
+#define PARM_NAME_WDS_ADDRESS2					TEXT("WDSAddress2")
+#define PARM_WDS_ADDRESS3                       WDSAddress3
+#define PARM_NAME_WDS_ADDRESS3					TEXT("WDSAddress3")
+#define PARM_WDS_ADDRESS4                       WDSAddress4
+#define PARM_NAME_WDS_ADDRESS4					TEXT("WDSAddress4")
+#define PARM_WDS_ADDRESS5                       WDSAddress5
+#define PARM_NAME_WDS_ADDRESS5					TEXT("WDSAddress5")
+#define PARM_WDS_ADDRESS6                       WDSAddress6
+#define PARM_NAME_WDS_ADDRESS6					TEXT("WDSAddress6")
+
+/*
+#define PARM_LONG_RETRY_LIMIT                   LongRetryLimit
+#define PARM_NAME_LONG_RETRY_LIMIT              TEXT("LongRetryLimit")
+#define PARM_MIN_LONG_RETRY_LIMIT               1
+#define PARM_MAX_LONG_RETRY_LIMIT               15
+#define PARM_DEFAULT_LONG_RETRY_LIMIT           3
+
+
+#define PARM_PROBE_DATA_RATES                   ProbeDataRates
+#define PARM_NAME_PROBE_DATA_RATES              TEXT("ProbeDataRates")
+#define PARM_MIN_PROBE_DATA_RATES               0x0000
+#define PARM_MAX_PROBE_DATA_RATES               0x0FFF
+#define PARM_DEFAULT_PROBE_DATA_RATES_2GHZ      0x0002
+#define PARM_DEFAULT_PROBE_DATA_RATES_5GHZ      0x0010
+
+#define PARM_SHORT_RETRY_LIMIT                  ShortRetryLimit
+#define PARM_NAME_SHORT_RETRY_LIMIT             TEXT("ShortRetryLimit")
+#define PARM_MIN_SHORT_RETRY_LIMIT              1
+#define PARM_MAX_SHORT_RETRY_LIMIT              15
+#define PARM_DEFAULT_SHORT_RETRY_LIMIT          7
+
+
+*/
+
+/*******************************************************************************
+ *  state definitions
+ ******************************************************************************/
+/* The following constants are used to track state the device */
+#define WL_FRIMWARE_PRESENT     1 // Download if needed
+#define WL_FRIMWARE_NOT_PRESENT	0 // Skip over download, assume its already there
+#define WL_HANDLING_INT         1 // Actually call the HCF to switch interrupts on/off
+#define WL_NOT_HANDLING_INT     0 // Not yet handling interrupts, do not switch on/off
+
+/*******************************************************************************
+ *  macro definitions
+ ******************************************************************************/
+/* The following macro ensures that no symbols are exported, minimizing the
+   chance of a symbol collision in the kernel */
+// EXPORT_NO_SYMBOLS;
+
+#define NELEM(arr) (sizeof(arr) / sizeof(arr[0]))
+
+#define WVLAN_VALID_MAC_ADDRESS( x ) \
+((x[0]!=0xFF) && (x[1]!=0xFF) && (x[2]!=0xFF) && (x[3]!=0xFF) && (x[4]!=0xFF) && (x[5]!=0xFF))
+
+
+
+
+/*******************************************************************************
+ * type definitions
+ ******************************************************************************/
+#undef FALSE
+#undef TRUE
+
+typedef enum
+{
+	FALSE = 0,
+	TRUE  = 1
+}
+bool_t;
+
+
+typedef struct _ScanResult
+{
+	//hcf_16        len;
+	//hcf_16        typ;
+	int             scan_complete;
+	int             num_aps;
+	SCAN_RS_STRCT   APTable [MAX_NAPS];
+}
+ScanResult;
+
+
+typedef struct _LINK_STATUS_STRCT
+{
+	hcf_16  len;
+	hcf_16  typ;
+	hcf_16  linkStatus;     /* 1..5 */
+}
+LINK_STATUS_STRCT;
+
+
+typedef struct _ASSOC_STATUS_STRCT
+{
+	hcf_16  len;
+	hcf_16  typ;
+	hcf_16  assocStatus;            /* 1..3 */
+	hcf_8   staAddr[ETH_ALEN];
+	hcf_8   oldApAddr[ETH_ALEN];
+}
+ASSOC_STATUS_STRCT;
+
+
+typedef struct _SECURITY_STATUS_STRCT
+{
+	hcf_16  len;
+	hcf_16  typ;
+	hcf_16  securityStatus;     /* 1..3 */
+	hcf_8   staAddr[ETH_ALEN];
+	hcf_16  reason;
+}
+SECURITY_STATUS_STRCT;
+
+#define WVLAN_WMP_PDU_TYPE_LT_REQ       0x00
+#define WVLAN_WMP_PDU_TYPE_LT_RSP       0x01
+#define WVLAN_WMP_PDU_TYPE_APL_REQ      0x02
+#define WVLAN_WMP_PDU_TYPE_APL_RSP      0x03
+
+typedef struct wvlan_eth_hdr
+{
+	unsigned char   dst[ETH_ALEN];           /* Destination address. */
+	unsigned char   src[ETH_ALEN];           /* Source address. */
+	unsigned short  len;                    /* Length of the PDU. */
+}
+WVLAN_ETH_HDR, *PWVLAN_ETH_HDR;
+
+typedef struct wvlan_llc_snap
+{
+	unsigned char   dsap;                   /* DSAP (0xAA) */
+	unsigned char   ssap;                   /* SSAP (0xAA) */
+	unsigned char   ctrl;                   /* Control (0x03) */
+	unsigned char   oui[3];                 /* Organization Unique ID (00-60-1d). */
+	unsigned char   specid[2];              /* Specific ID code (00-01). */
+}
+WVLAN_LLC_SNAP, *PWVLAN_LLC_SNAP;
+
+
+typedef struct wvlan_lt_hdr
+{
+	unsigned char   version;                /* Version (0x00) */
+	unsigned char   type;                   /* PDU type: 0-req/1-resp. */
+	unsigned short  id;                     /* Identifier to associate resp to req. */
+}
+WVLAN_LT_HDR, *PWVLAN_LT_HDR;
+
+
+typedef struct wvlan_wmp_hdr
+{
+	unsigned char   version;                /* Version  */
+	unsigned char   type;                   /* PDU type */
+}
+WVLAN_WMP_HDR, *PWVLAN_WMP_HDR;
+
+
+#define FILLER_SIZE             1554
+#define TEST_PATTERN_SIZE       54
+
+
+typedef struct wvlan_lt_req
+{
+	unsigned char   Filler[TEST_PATTERN_SIZE];   /* minimal length of 54 bytes */
+}
+WVLAN_LT_REQ, *PWVLAN_LT_REQ;
+
+
+typedef struct wvlan_lt_rsp
+{
+	char           name[32];
+	/* Measured Data */
+	unsigned char  signal;
+	unsigned char  noise;
+	unsigned char  rxFlow;
+	unsigned char  dataRate;
+	unsigned short protocol;
+	/* Capabilities */
+	unsigned char  station;
+	unsigned char  dataRateCap;
+	unsigned char  powerMgmt[4];
+	unsigned char  robustness[4];
+	unsigned char  scaling;
+	unsigned char  reserved[5];
+}
+WVLAN_LT_RSP, *PWVLAN_LT_RSP;
+
+
+typedef struct wvlan_rx_wmp_hdr
+{
+	unsigned short status;
+	unsigned short reserved1[2];
+	unsigned char  silence;
+	unsigned char  signal;
+	unsigned char  rate;
+	unsigned char  rxFlow;
+	unsigned short reserved2[2];
+	unsigned short frameControl;
+	unsigned short duration;
+	unsigned short address1[3];
+	unsigned short address2[3];
+	unsigned short address3[3];
+	unsigned short sequenceControl;
+	unsigned short address4[3];
+#ifndef HERMES25	//;?just to be on the safe side of inherited but not comprehended code #ifdef HERMES2
+	unsigned short seems_to_be_unused_reserved3[5];  //;?
+	unsigned short seems_to_be_unused_reserved4;	 //;?
+#endif // HERMES25
+	unsigned short HeaderDataLen;
+}
+WVLAN_RX_WMP_HDR, *PWVLAN_RX_WMP_HDR;
+
+
+typedef struct wvlan_linktest_req_pdu
+{
+	WVLAN_ETH_HDR     ethHdr;
+	WVLAN_LLC_SNAP    llcSnap;
+	WVLAN_LT_HDR      ltHdr;
+	WVLAN_LT_REQ      ltReq;
+}
+WVLAN_LINKTEST_REQ_PDU, *PWVLAN_LINKTEST_REQ_PDU;
+
+
+typedef struct wvlan_linktest_rsp_pdu
+{
+	WVLAN_RX_WMP_HDR  wmpRxHdr;
+	WVLAN_ETH_HDR     ethHdr;
+	WVLAN_LLC_SNAP    llcSnap;
+	WVLAN_LT_HDR      ltHdr;
+	WVLAN_LT_RSP      ltRsp;
+}
+WVLAN_LINKTEST_RSP_PDU, *PWVLAN_LINKTEST_RSP_PDU;
+
+
+typedef struct _LINKTEST_RSP_STRCT
+{
+	hcf_16                   len;
+	hcf_16                   typ;
+	WVLAN_LINKTEST_RSP_PDU   ltRsp;
+}
+LINKTEST_RSP_STRCT;
+
+
+typedef struct wvlan_wmp_rsp_pdu
+{
+	WVLAN_RX_WMP_HDR  wmpRxHdr;
+	WVLAN_ETH_HDR     ethHdr;
+	WVLAN_LLC_SNAP    llcSnap;
+	WVLAN_WMP_HDR     wmpHdr;
+}
+WVLAN_WMP_RSP_PDU, *PWVLAN_WMP_RSP_PDU;
+
+
+typedef struct _WMP_RSP_STRCT
+{
+	hcf_16              len;
+	hcf_16              typ;
+	WVLAN_WMP_RSP_PDU   wmpRsp;
+}
+WMP_RSP_STRCT;
+
+
+typedef struct _PROBE_RESP
+{
+	// first part: 802.11
+	hcf_16	length;
+	hcf_16	infoType;
+	hcf_16	reserved0;
+	//hcf_8	signal;
+	hcf_8	silence;
+	hcf_8	signal;     // Moved signal here as signal/noise values were flipped
+	hcf_8	rxFlow;
+	hcf_8	rate;
+	hcf_16	reserved1[2];
+
+	// second part:
+	hcf_16	frameControl;
+	hcf_16	durID;
+	hcf_8	address1[6];
+	hcf_8	address2[6];
+	hcf_8	BSSID[6];					//! this is correct, right ?
+	hcf_16	sequence;
+	hcf_8	address4[6];
+
+#ifndef WARP
+	hcf_8	reserved2[12];
+#endif // WARP
+
+	hcf_16	dataLength;
+										// the information in the next 3 fields (DA/SA/LenType) is actually not filled in.
+	hcf_8	DA[6];
+	hcf_8	SA[6];
+
+#ifdef WARP
+	hcf_8   channel;
+	hcf_8   band;
+#else
+	hcf_16	lenType;
+#endif  // WARP
+
+	hcf_8	timeStamp[8];
+	hcf_16	beaconInterval;
+	hcf_16	capability;
+	hcf_8	rawData[200];				//! <<< think about this number !
+	hcf_16	flags;
+}
+PROBE_RESP, *PPROBE_RESP;
+
+
+typedef struct _ProbeResult
+{
+	int         scan_complete;
+	int         num_aps;
+	PROBE_RESP  ProbeTable[MAX_NAPS];
+}
+ProbeResult;
+
+/* Definitions used to parse capabilities out of the probe responses */
+#define CAPABILITY_ESS      0x0001
+#define CAPABILITY_IBSS     0x0002
+#define CAPABILITY_PRIVACY  0x0010
+
+/* Definitions used to parse the Information Elements out of probe responses */
+#define DS_INFO_ELEM                        0x03
+#define GENERIC_INFO_ELEM                   0xdd
+#define WPA_MAX_IE_LEN                      40
+#define WPA_SELECTOR_LEN                    4
+#define WPA_OUI_TYPE                        { 0x00, 0x50, 0xf2, 1 }
+#define WPA_VERSION                         1
+#define WPA_AUTH_KEY_MGMT_UNSPEC_802_1X     { 0x00, 0x50, 0xf2, 1 }
+#define WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X   { 0x00, 0x50, 0xf2, 2 }
+#define WPA_CIPHER_SUITE_NONE               { 0x00, 0x50, 0xf2, 0 }
+#define WPA_CIPHER_SUITE_WEP40              { 0x00, 0x50, 0xf2, 1 }
+#define WPA_CIPHER_SUITE_TKIP               { 0x00, 0x50, 0xf2, 2 }
+#define WPA_CIPHER_SUITE_WRAP               { 0x00, 0x50, 0xf2, 3 }
+#define WPA_CIPHER_SUITE_CCMP               { 0x00, 0x50, 0xf2, 4 }
+#define WPA_CIPHER_SUITE_WEP104             { 0x00, 0x50, 0xf2, 5 }
+
+typedef enum wvlan_drv_mode
+{
+	WVLAN_DRV_MODE_NO_DOWNLOAD,     /* this is the same as STA for Hermes 1    */
+				                    /* it is also only applicable for Hermes 1 */
+	WVLAN_DRV_MODE_STA,
+	WVLAN_DRV_MODE_AP,
+	WVLAN_DRV_MODE_MAX
+}
+WVLAN_DRV_MODE, *PWVLAN_DRV_MODE;
+
+
+typedef enum wvlan_port_state
+{
+	WVLAN_PORT_STATE_ENABLED,
+	WVLAN_PORT_STATE_DISABLED,
+	WVLAN_PORT_STATE_CONNECTED
+}
+WVLAN_PORT_STATE, *PWVLAN_PORT_STATE;
+
+/*
+typedef enum wvlan_connect_state
+{
+	WVLAN_CONNECT_STATE_CONNECTED,
+	WVLAN_CONNECT_STATE_DISCONNECTED
+}
+WVLAN_CONNECT_STATE, *PWVLAN_CONNECT_STATE;
+*/
+
+typedef enum wvlan_pm_state
+{
+	WVLAN_PM_STATE_DISABLED,
+	WVLAN_PM_STATE_ENHANCED,
+	WVLAN_PM_STATE_STANDARD
+}
+WVLAN_PM_STATE, *PWVLAN_PM_STATE;
+
+
+typedef struct wvlan_frame
+{
+	struct sk_buff  *skb;       /* sk_buff for frame. */
+	hcf_16          port;       /* MAC port for the frame. */
+	hcf_16          len;        /* Length of the frame. */
+}
+WVLAN_FRAME, *PWVLAN_FRAME;
+
+
+typedef struct wvlan_lframe
+{
+	struct list_head    node;   /* Node in the list */
+	WVLAN_FRAME	        frame;  /* Frame. */
+}
+WVLAN_LFRAME, *PWVLAN_LFRAME;
+
+
+
+#define DEFAULT_NUM_TX_FRAMES           48
+#define TX_Q_LOW_WATER_MARK             (DEFAULT_NUM_TX_FRAMES/3)
+
+#define WVLAN_MAX_TX_QUEUES             1
+
+
+#ifdef USE_WDS
+
+typedef struct wvlan_wds_if
+{
+	struct net_device           *dev;
+	int                         is_registered;
+	int                         netif_queue_on;
+	struct net_device_stats     stats;
+	hcf_16                      rtsThreshold;
+	hcf_16                      txRateCntl;
+	hcf_8                       wdsAddress[ETH_ALEN];
+} WVLAN_WDS_IF, *PWVLAN_WDS_IF;
+
+#endif  // USE_WDS
+
+
+
+#define NUM_RX_DESC 5
+#define NUM_TX_DESC 5
+
+typedef struct dma_strct
+{
+	DESC_STRCT  *tx_packet[NUM_TX_DESC];
+	DESC_STRCT  *rx_packet[NUM_RX_DESC];
+	DESC_STRCT  *rx_reclaim_desc, *tx_reclaim_desc; // Descriptors for host-reclaim purposes (see HCF)
+	int         tx_rsc_ind; // DMA Tx resource indicator is maintained in the MSF, not in the HCF
+	int         rx_rsc_ind; // Also added rx rsource indicator so that cleanup can be performed if alloc fails
+	int         status;
+} DMA_STRCT;
+
+
+/* Macros used in DMA support */
+/* get bus address of {rx,tx}dma structure member, in little-endian byte order */
+#define WL_DMA_BUS_ADDR_LE(str, i, mem) \
+	cpu_to_le32(str##_dma_addr[(i)] + ((hcf_8 *)&str[(i)]->mem - (hcf_8 *)str[(i)]))
+
+
+struct wl_private
+{
+
+#ifdef BUS_PCMCIA
+	dev_node_t                  node;
+	struct pcmcia_device	    *link;
+#endif // BUS_PCMCIA
+
+
+	struct net_device           *dev;
+//	struct net_device           *dev_next;
+	spinlock_t                  slock;
+	struct tasklet_struct       task;
+	struct net_device_stats     stats;
+
+
+#ifdef WIRELESS_EXT
+	struct iw_statistics        wstats;
+//	int                         spy_number;
+//	u_char                      spy_address[IW_MAX_SPY][ETH_ALEN];
+//	struct iw_quality           spy_stat[IW_MAX_SPY];
+	struct iw_spy_data          spy_data;
+	struct iw_public_data	wireless_data;
+#endif // WIRELESS_EXT
+
+
+	IFB_STRCT                   hcfCtx;
+//;? struct timer_list			timer_oor;
+//;? hcf_16						timer_oor_cnt;
+	u_long						wlags49_type;		//controls output in /proc/wlags49
+	u_long                      flags;
+	hcf_16						DebugFlag;
+	int                         is_registered;
+	int                         is_handling_int;
+	int                         firmware_present;
+	char                        sysfsCreated;
+	CFG_DRV_INFO_STRCT          driverInfo;
+	CFG_IDENTITY_STRCT          driverIdentity;
+	CFG_FW_IDENTITY_STRCT       StationIdentity;
+	CFG_PRI_IDENTITY_STRCT      PrimaryIdentity;
+	CFG_PRI_IDENTITY_STRCT      NICIdentity;
+
+	ltv_t                       ltvRecord;
+	u_long                      txBytes;
+	hcf_16                      maxPort;        /* 0 for STA, 6 for AP */
+
+	/* Elements used for async notification from hardware */
+	RID_LOG_STRCT				RidList[10];
+	ltv_t                       updatedRecord;
+	PROBE_RESP				    ProbeResp;
+	ASSOC_STATUS_STRCT          assoc_stat;
+	SECURITY_STATUS_STRCT       sec_stat;
+
+	u_char                      lookAheadBuf[WVLAN_MAX_LOOKAHEAD];
+
+	hcf_8                       PortType;           // 1 - 3 (1 [Normal] | 3 [AdHoc])
+	hcf_16                      Channel;            // 0 - 14 (0)
+	hcf_16                      TxRateControl[2];
+	hcf_8                       DistanceBetweenAPs; // 1 - 3 (1)
+	hcf_16                      RTSThreshold;       // 0 - 2347 (2347)
+	hcf_16                      PMEnabled;          // 0 - 2, 8001 - 8002 (0)
+	hcf_8                       MicrowaveRobustness;// 0 - 1 (0)
+	hcf_8                       CreateIBSS;         // 0 - 1 (0)
+	hcf_8                       MulticastReceive;   // 0 - 1 (1)
+	hcf_16                      MaxSleepDuration;   // 0 - 65535 (100)
+	hcf_8                       MACAddress[ETH_ALEN];
+	char                        NetworkName[HCF_MAX_NAME_LEN+1];
+	char                        StationName[HCF_MAX_NAME_LEN+1];
+	hcf_8                       EnableEncryption;   // 0 - 1 (0)
+	char                        Key1[MAX_KEY_LEN+1];
+	char                        Key2[MAX_KEY_LEN+1];
+	char                        Key3[MAX_KEY_LEN+1];
+	char                        Key4[MAX_KEY_LEN+1];
+	hcf_8                       TransmitKeyID;      // 1 - 4 (1)
+	CFG_DEFAULT_KEYS_STRCT	    DefaultKeys;
+	u_char                      mailbox[MB_SIZE];
+	char                        szEncryption[MAX_ENC_LEN];
+
+	hcf_16                      driverEnable;
+	hcf_16                      wolasEnable;
+	hcf_16                      atimWindow;
+	hcf_16                      holdoverDuration;
+	hcf_16                      MulticastRate[2];
+
+	hcf_16                      authentication; // is this AP specific?
+	hcf_16                      promiscuousMode;
+	WVLAN_DRV_MODE              DownloadFirmware;   // 0 - 2 (0 [None] | 1 [STA] | 2 [AP])
+
+	char						fw_image_filename[MAX_LINE_SIZE+1];
+
+	hcf_16                      AuthKeyMgmtSuite;
+
+	hcf_16                      loadBalancing;
+	hcf_16                      mediumDistribution;
+	hcf_16                      txPowLevel;
+	//hcf_16                      shortRetryLimit;
+	//hcf_16                      longRetryLimit;
+	hcf_16                      srsc[2];
+	hcf_16                      brsc[2];
+	hcf_16                      connectionControl;
+	//hcf_16                      probeDataRates[2];
+	hcf_16                      ownBeaconInterval;
+	hcf_16                      coexistence;
+
+	WVLAN_FRAME                 txF;
+	WVLAN_LFRAME                txList[DEFAULT_NUM_TX_FRAMES];
+	struct list_head            txFree;
+	struct list_head            txQ[WVLAN_MAX_TX_QUEUES];
+	int                         netif_queue_on;
+	int                         txQ_count;
+	DESC_STRCT                  desc_rx;
+	DESC_STRCT                  desc_tx;
+
+	WVLAN_PORT_STATE            portState;
+
+	ScanResult                  scan_results;
+	ProbeResult                 probe_results;
+	int                         probe_num_aps;
+
+	int                         use_dma;
+	DMA_STRCT                   dma;
+#ifdef USE_RTS
+	int                         useRTS;
+#endif  // USE_RTS
+	hcf_8                       DTIMPeriod;         // 1 - 255 (1)
+	hcf_16                      multicastPMBuffering;
+	hcf_8                       RejectAny;          // 0 - 1 (0)
+	hcf_8                       ExcludeUnencrypted; // 0 - 1 (1)
+	hcf_16                      intraBSSRelay;
+#ifdef USE_WDS
+	WVLAN_WDS_IF                wds_port[NUM_WDS_PORTS];
+#endif // USE_WDS
+}; // wl_private
+
+#ifdef HAVE_NETDEV_PRIV
+#define wl_priv(dev) ((struct wl_private *) netdev_priv(dev))
+#else
+extern inline struct wl_private *wl_priv(struct net_device *dev)
+{
+    return dev->priv;
+}
+#endif
+
+/********************************************************************/
+/* Locking and synchronization functions                            */
+/********************************************************************/
+
+/* These functions *must* be inline or they will break horribly on
+ * SPARC, due to its weird semantics for save/restore flags. extern
+ * inline should prevent the kernel from linking or module from
+ * loading if they are not inlined. */
+extern inline void wl_lock(struct wl_private *lp,
+	                       unsigned long *flags)
+{
+	spin_lock_irqsave(&lp->slock, *flags);
+}
+
+extern inline void wl_unlock(struct wl_private *lp,
+	                          unsigned long *flags)
+{
+	spin_unlock_irqrestore(&lp->slock, *flags);
+}
+
+/********************************************************************/
+/* Interrupt enable disable functions                               */
+/********************************************************************/
+
+extern inline void wl_act_int_on(struct wl_private *lp)
+{
+	/*
+	 * Only do something when the driver is handling
+	 * interrupts. Handling starts at wl_open and
+	 * ends at wl_close when not in RTS mode
+	 */
+	if(lp->is_handling_int == WL_HANDLING_INT) {
+		hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
+	}
+}
+
+extern inline void wl_act_int_off(struct wl_private *lp)
+{
+	/*
+	 * Only do something when the driver is handling
+	 * interrupts. Handling starts at wl_open and
+	 * ends at wl_close when not in RTS mode
+	 */
+	if(lp->is_handling_int == WL_HANDLING_INT) {
+		hcf_action( &lp->hcfCtx, HCF_ACT_INT_OFF );
+	}
+}
+
+#endif  // __WAVELAN2_H__
diff --git a/drivers/staging/wlags49_h2/wl_main.c b/drivers/staging/wlags49_h2/wl_main.c
new file mode 100644
index 0000000..16764a0
--- /dev/null
+++ b/drivers/staging/wlags49_h2/wl_main.c
@@ -0,0 +1,3866 @@
+/*******************************************************************************
+ * Agere Systems Inc.
+ * Wireless device driver for Linux (wlags49).
+ *
+ * Copyright (c) 1998-2003 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * Initially developed by TriplePoint, Inc.
+ *   http://www.triplepoint.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ *   This file contains the main driver entry points and other adapter
+ *   specific routines.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2003 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following Disclaimer as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ ******************************************************************************/
+
+/*******************************************************************************
+ *  constant definitions
+ ******************************************************************************/
+
+/* Allow support for calling system fcns to access F/W iamge file */
+#define __KERNEL_SYSCALLS__
+
+/*******************************************************************************
+ *  include files
+ ******************************************************************************/
+#include <wl_version.h>
+
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+// #include <linux/sched.h>
+// #include <linux/ptrace.h>
+// #include <linux/slab.h>
+// #include <linux/ctype.h>
+// #include <linux/string.h>
+// #include <linux/timer.h>
+//#include <linux/interrupt.h>
+// #include <linux/tqueue.h>
+// #include <linux/in.h>
+// #include <linux/delay.h>
+// #include <asm/io.h>
+// #include <asm/system.h>
+// #include <asm/bitops.h>
+#include <linux/unistd.h>
+#include <asm/uaccess.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+// #include <linux/skbuff.h>
+// #include <linux/if_arp.h>
+// #include <linux/ioport.h>
+
+#define BIN_DL 0
+#if BIN_DL
+#include <linux/vmalloc.h>
+#endif // BIN_DL
+
+
+#include <debug.h>
+
+#include <hcf.h>
+#include <dhf.h>
+//in order to get around:: wl_main.c:2229: `HREG_EV_RDMAD' undeclared (first use in this function)
+#include <hcfdef.h>
+
+#include <wl_if.h>
+#include <wl_internal.h>
+#include <wl_util.h>
+#include <wl_main.h>
+#include <wl_netdev.h>
+#include <wl_wext.h>
+
+#ifdef USE_PROFILE
+#include <wl_profile.h>
+#endif  /* USE_PROFILE */
+
+#ifdef BUS_PCMCIA
+#include <wl_cs.h>
+#endif  /* BUS_PCMCIA */
+
+#ifdef BUS_PCI
+#include <wl_pci.h>
+#endif  /* BUS_PCI */
+/*******************************************************************************
+ *	macro defintions
+ ******************************************************************************/
+#define VALID_PARAM(C) \
+	{ \
+		if (!(C)) \
+		{ \
+			printk(KERN_INFO "Wireless, parameter error: \"%s\"\n", #C); \
+			goto failed; \
+		} \
+	}
+/*******************************************************************************
+ *	local functions
+ ******************************************************************************/
+void wl_isr_handler( unsigned long p );
+
+#if 0 //SCULL_USE_PROC /* don't waste space if unused */
+//int scull_read_procmem(char *buf, char **start, off_t offset, int len, int unused);
+int scull_read_procmem(char *buf, char **start, off_t offset, int len, int *eof, void *data );
+static int write_int(struct file *file, const char *buffer, unsigned long count, void *data);
+static void proc_write(const char *name, write_proc_t *w, void *data);
+
+#endif /* SCULL_USE_PROC */
+
+/*******************************************************************************
+ * module parameter definitions - set with 'insmod'
+ ******************************************************************************/
+static p_u16    irq_mask                = 0xdeb8; // IRQ3,4,5,7,9,10,11,12,14,15
+static p_s8     irq_list[4]             = { -1 };
+
+#if 0
+MODULE_PARM(irq_mask,               "h");
+MODULE_PARM_DESC(irq_mask,               "IRQ mask [0xdeb8]");
+MODULE_PARM(irq_list,               "1-4b");
+MODULE_PARM_DESC(irq_list,               "IRQ list [<irq_mask>]");
+#endif
+
+static p_u8     PARM_AUTHENTICATION        	= PARM_DEFAULT_AUTHENTICATION;
+static p_u16    PARM_AUTH_KEY_MGMT_SUITE   	= PARM_DEFAULT_AUTH_KEY_MGMT_SUITE;
+static p_u16    PARM_BRSC_2GHZ             	= PARM_DEFAULT_BRSC_2GHZ;
+static p_u16    PARM_BRSC_5GHZ             	= PARM_DEFAULT_BRSC_5GHZ;
+static p_u16    PARM_COEXISTENCE           	= PARM_DEFAULT_COEXISTENCE;
+static p_u16    PARM_CONNECTION_CONTROL    	= PARM_DEFAULT_CONNECTION_CONTROL;  //;?rename and move
+static p_char  *PARM_CREATE_IBSS           	= PARM_DEFAULT_CREATE_IBSS_STR;
+static p_char  *PARM_DESIRED_SSID          	= PARM_DEFAULT_SSID;
+static p_char  *PARM_DOWNLOAD_FIRMWARE      = "";
+static p_u16    PARM_ENABLE_ENCRYPTION     	= PARM_DEFAULT_ENABLE_ENCRYPTION;
+static p_char  *PARM_EXCLUDE_UNENCRYPTED   	= PARM_DEFAULT_EXCLUDE_UNENCRYPTED_STR;
+static p_char  *PARM_INTRA_BSS_RELAY       	= PARM_DEFAULT_INTRA_BSS_RELAY_STR;
+static p_char  *PARM_KEY1                  	= "";
+static p_char  *PARM_KEY2                  	= "";
+static p_char  *PARM_KEY3                  	= "";
+static p_char  *PARM_KEY4                  	= "";
+static p_char  *PARM_LOAD_BALANCING        	= PARM_DEFAULT_LOAD_BALANCING_STR;
+static p_u16    PARM_MAX_SLEEP             	= PARM_DEFAULT_MAX_PM_SLEEP;
+static p_char  *PARM_MEDIUM_DISTRIBUTION   	= PARM_DEFAULT_MEDIUM_DISTRIBUTION_STR;
+static p_char  *PARM_MICROWAVE_ROBUSTNESS  	= PARM_DEFAULT_MICROWAVE_ROBUSTNESS_STR;
+static p_char  *PARM_MULTICAST_PM_BUFFERING	= PARM_DEFAULT_MULTICAST_PM_BUFFERING_STR;
+static p_u16    PARM_MULTICAST_RATE        	= PARM_DEFAULT_MULTICAST_RATE_2GHZ;
+static p_char  *PARM_MULTICAST_RX          	= PARM_DEFAULT_MULTICAST_RX_STR;
+static p_u8     PARM_NETWORK_ADDR[ETH_ALEN]	= PARM_DEFAULT_NETWORK_ADDR;
+static p_u16    PARM_OWN_ATIM_WINDOW       	= PARM_DEFAULT_OWN_ATIM_WINDOW;
+static p_u16    PARM_OWN_BEACON_INTERVAL   	= PARM_DEFAULT_OWN_BEACON_INTERVAL;
+static p_u8     PARM_OWN_CHANNEL           	= PARM_DEFAULT_OWN_CHANNEL;
+static p_u8     PARM_OWN_DTIM_PERIOD       	= PARM_DEFAULT_OWN_DTIM_PERIOD;
+static p_char  *PARM_OWN_NAME              	= PARM_DEFAULT_OWN_NAME;
+static p_char  *PARM_OWN_SSID              	= PARM_DEFAULT_SSID;
+static p_u16	PARM_PM_ENABLED            	= WVLAN_PM_STATE_DISABLED;
+static p_u16    PARM_PM_HOLDOVER_DURATION  	= PARM_DEFAULT_PM_HOLDOVER_DURATION;
+static p_u8     PARM_PORT_TYPE             	= PARM_DEFAULT_PORT_TYPE;
+static p_char  *PARM_PROMISCUOUS_MODE      	= PARM_DEFAULT_PROMISCUOUS_MODE_STR;
+static p_char  *PARM_REJECT_ANY            	= PARM_DEFAULT_REJECT_ANY_STR;
+#ifdef USE_WDS
+static p_u16    PARM_RTS_THRESHOLD1        	= PARM_DEFAULT_RTS_THRESHOLD;
+static p_u16    PARM_RTS_THRESHOLD2        	= PARM_DEFAULT_RTS_THRESHOLD;
+static p_u16    PARM_RTS_THRESHOLD3        	= PARM_DEFAULT_RTS_THRESHOLD;
+static p_u16    PARM_RTS_THRESHOLD4        	= PARM_DEFAULT_RTS_THRESHOLD;
+static p_u16    PARM_RTS_THRESHOLD5        	= PARM_DEFAULT_RTS_THRESHOLD;
+static p_u16    PARM_RTS_THRESHOLD6        	= PARM_DEFAULT_RTS_THRESHOLD;
+#endif // USE_WDS
+static p_u16    PARM_RTS_THRESHOLD         	= PARM_DEFAULT_RTS_THRESHOLD;
+static p_u16    PARM_SRSC_2GHZ             	= PARM_DEFAULT_SRSC_2GHZ;
+static p_u16    PARM_SRSC_5GHZ             	= PARM_DEFAULT_SRSC_5GHZ;
+static p_u8     PARM_SYSTEM_SCALE          	= PARM_DEFAULT_SYSTEM_SCALE;
+static p_u8     PARM_TX_KEY                	= PARM_DEFAULT_TX_KEY;
+static p_u16    PARM_TX_POW_LEVEL          	= PARM_DEFAULT_TX_POW_LEVEL;
+#ifdef USE_WDS
+static p_u16    PARM_TX_RATE1              	= PARM_DEFAULT_TX_RATE_2GHZ;
+static p_u16    PARM_TX_RATE2              	= PARM_DEFAULT_TX_RATE_2GHZ;
+static p_u16    PARM_TX_RATE3              	= PARM_DEFAULT_TX_RATE_2GHZ;
+static p_u16    PARM_TX_RATE4              	= PARM_DEFAULT_TX_RATE_2GHZ;
+static p_u16    PARM_TX_RATE5              	= PARM_DEFAULT_TX_RATE_2GHZ;
+static p_u16    PARM_TX_RATE6              	= PARM_DEFAULT_TX_RATE_2GHZ;
+#endif // USE_WDS
+static p_u16    PARM_TX_RATE               	= PARM_DEFAULT_TX_RATE_2GHZ;
+#ifdef USE_WDS
+static p_u8     PARM_WDS_ADDRESS1[ETH_ALEN]	= PARM_DEFAULT_NETWORK_ADDR;
+static p_u8     PARM_WDS_ADDRESS2[ETH_ALEN]	= PARM_DEFAULT_NETWORK_ADDR;
+static p_u8     PARM_WDS_ADDRESS3[ETH_ALEN]	= PARM_DEFAULT_NETWORK_ADDR;
+static p_u8     PARM_WDS_ADDRESS4[ETH_ALEN]	= PARM_DEFAULT_NETWORK_ADDR;
+static p_u8     PARM_WDS_ADDRESS5[ETH_ALEN]	= PARM_DEFAULT_NETWORK_ADDR;
+static p_u8     PARM_WDS_ADDRESS6[ETH_ALEN]	= PARM_DEFAULT_NETWORK_ADDR;
+#endif // USE_WDS
+
+
+#if 0
+MODULE_PARM(PARM_DESIRED_SSID,          "s");
+MODULE_PARM_DESC(PARM_DESIRED_SSID,             "Network Name (<string>) [ANY]");
+MODULE_PARM(PARM_OWN_SSID,              "s");
+MODULE_PARM_DESC(PARM_OWN_SSID,                 "Network Name (<string>) [ANY]");
+MODULE_PARM(PARM_OWN_CHANNEL,           "b");
+MODULE_PARM_DESC(PARM_OWN_CHANNEL,              "Channel (0 - 14) [0]");
+MODULE_PARM(PARM_SYSTEM_SCALE,          "b");
+MODULE_PARM_DESC(PARM_SYSTEM_SCALE,             "Distance Between APs (1 - 3) [1]");
+MODULE_PARM(PARM_TX_RATE,               "b");
+MODULE_PARM_DESC(PARM_TX_RATE,                  "Transmit Rate Control");
+MODULE_PARM(PARM_RTS_THRESHOLD,         "h");
+MODULE_PARM_DESC(PARM_RTS_THRESHOLD,            "Medium Reservation (RTS/CTS Fragment Length) (256 - 2347) [2347]");
+MODULE_PARM(PARM_MICROWAVE_ROBUSTNESS,  "s");
+MODULE_PARM_DESC(PARM_MICROWAVE_ROBUSTNESS,     "Microwave Oven Robustness Enabled (<string> N or Y) [N]");
+MODULE_PARM(PARM_OWN_NAME,              "s");
+MODULE_PARM_DESC(PARM_OWN_NAME,                 "Station Name (<string>) [Linux]");
+
+MODULE_PARM(PARM_ENABLE_ENCRYPTION,     "b");
+MODULE_PARM_DESC(PARM_ENABLE_ENCRYPTION,        "Encryption Mode (0 - 7) [0]");
+
+MODULE_PARM(PARM_KEY1,                  "s");
+MODULE_PARM_DESC(PARM_KEY1,                     "Data Encryption Key 1 (<string>) []");
+MODULE_PARM(PARM_KEY2,                  "s");
+MODULE_PARM_DESC(PARM_KEY2,                     "Data Encryption Key 2 (<string>) []");
+MODULE_PARM(PARM_KEY3,                  "s");
+MODULE_PARM_DESC(PARM_KEY3,                     "Data Encryption Key 3 (<string>) []");
+MODULE_PARM(PARM_KEY4,                  "s");
+MODULE_PARM_DESC(PARM_KEY4,                     "Data Encryption Key 4 (<string>) []");
+MODULE_PARM(PARM_TX_KEY,                "b");
+MODULE_PARM_DESC(PARM_TX_KEY,                   "Transmit Key ID (1 - 4) [1]");
+MODULE_PARM(PARM_MULTICAST_RATE,        "b");
+MODULE_PARM_DESC(PARM_MULTICAST_RATE,           "Multicast Rate");
+MODULE_PARM(PARM_DOWNLOAD_FIRMWARE,     "s");
+MODULE_PARM_DESC(PARM_DOWNLOAD_FIRMWARE,        "filename of firmware image");
+
+MODULE_PARM(PARM_AUTH_KEY_MGMT_SUITE,   "b");
+MODULE_PARM_DESC(PARM_AUTH_KEY_MGMT_SUITE,      "Authentication Key Management suite (0-4) [0]");
+
+MODULE_PARM(PARM_LOAD_BALANCING,        "s");
+MODULE_PARM_DESC(PARM_LOAD_BALANCING,           "Load Balancing Enabled (<string> N or Y) [Y]");
+MODULE_PARM(PARM_MEDIUM_DISTRIBUTION,   "s");
+MODULE_PARM_DESC(PARM_MEDIUM_DISTRIBUTION,      "Medium Distribution Enabled (<string> N or Y) [Y]");
+MODULE_PARM(PARM_TX_POW_LEVEL,          "b");
+MODULE_PARM_DESC(PARM_TX_POW_LEVEL,             "Transmit Power (0 - 6) [3]");
+MODULE_PARM(PARM_SRSC_2GHZ,             "b");
+MODULE_PARM_DESC(PARM_SRSC_2GHZ,                "Supported Rate Set Control 2.4 GHz");
+MODULE_PARM(PARM_SRSC_5GHZ,             "b");
+MODULE_PARM_DESC(PARM_SRSC_5GHZ,                "Supported Rate Set Control 5.0 GHz");
+MODULE_PARM(PARM_BRSC_2GHZ,             "b");
+MODULE_PARM_DESC(PARM_BRSC_2GHZ,                "Basic Rate Set Control 2.4 GHz");
+MODULE_PARM(PARM_BRSC_5GHZ,             "b");
+MODULE_PARM_DESC(PARM_BRSC_5GHZ,                "Basic Rate Set Control 5.0 GHz");
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
+//;?seems reasonable that even an AP-only driver could afford this small additional footprint
+MODULE_PARM(PARM_PM_ENABLED,            "h");
+MODULE_PARM_DESC(PARM_PM_ENABLED,               "Power Management State (0 - 2, 8001 - 8002) [0]");
+MODULE_PARM(PARM_PORT_TYPE,             "b");
+MODULE_PARM_DESC(PARM_PORT_TYPE,                "Port Type (1 - 3) [1]");
+//;?MODULE_PARM(PARM_CREATE_IBSS,           "s");
+//;?MODULE_PARM_DESC(PARM_CREATE_IBSS,              "Create IBSS (<string> N or Y) [N]");
+//;?MODULE_PARM(PARM_MULTICAST_RX,          "s");
+//;?MODULE_PARM_DESC(PARM_MULTICAST_RX,             "Multicast Receive Enable (<string> N or Y) [Y]");
+//;?MODULE_PARM(PARM_MAX_SLEEP,             "h");
+//;?MODULE_PARM_DESC(PARM_MAX_SLEEP,                "Maximum Power Management Sleep Duration (0 - 65535) [100]");
+//;?MODULE_PARM(PARM_NETWORK_ADDR,          "6b");
+//;?MODULE_PARM_DESC(PARM_NETWORK_ADDR,             "Hardware Ethernet Address ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [<factory value>]");
+//;?MODULE_PARM(PARM_AUTHENTICATION,        "b");
+//
+//tracker 12448
+//;?MODULE_PARM_DESC(PARM_AUTHENTICATION,           "Authentication Type (0-2) [0] 0=Open 1=SharedKey 2=LEAP");
+//;?MODULE_PARM_DESC(authentication,         "Authentication Type (1-2) [1] 1=Open 2=SharedKey");
+//tracker 12448
+//
+//;?MODULE_PARM(PARM_OWN_ATIM_WINDOW,       "b");
+//;?MODULE_PARM_DESC(PARM_OWN_ATIM_WINDOW,          "ATIM Window time in TU for IBSS creation (0-100) [0]");
+//;?MODULE_PARM(PARM_PM_HOLDOVER_DURATION,  "b");
+//;?MODULE_PARM_DESC(PARM_PM_HOLDOVER_DURATION,     "Time station remains awake after MAC frame transfer when PM is on (0-65535) [100]");
+//;?MODULE_PARM(PARM_PROMISCUOUS_MODE,      "s");
+//;?MODULE_PARM_DESC(PARM_PROMISCUOUS_MODE,         "Promiscuous Mode Enable (<string> Y or N ) [N]" );
+//;?
+MODULE_PARM(PARM_CONNECTION_CONTROL,    "b");
+MODULE_PARM_DESC(PARM_CONNECTION_CONTROL,       "Connection Control (0 - 3) [2]");
+#endif /* HCF_STA */
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
+					//;?should we restore this to allow smaller memory footprint
+MODULE_PARM(PARM_OWN_DTIM_PERIOD,       "b");
+MODULE_PARM_DESC(PARM_OWN_DTIM_PERIOD,          "DTIM Period (0 - 255) [1]");
+MODULE_PARM(PARM_REJECT_ANY,            "s");
+MODULE_PARM_DESC(PARM_REJECT_ANY,               "Closed System (<string> N or Y) [N]");
+MODULE_PARM(PARM_EXCLUDE_UNENCRYPTED,   "s");
+MODULE_PARM_DESC(PARM_EXCLUDE_UNENCRYPTED,      "Deny non-encrypted (<string> N or Y) [Y]");
+MODULE_PARM(PARM_MULTICAST_PM_BUFFERING,"s");
+MODULE_PARM_DESC(PARM_MULTICAST_PM_BUFFERING,   "Buffer MAC frames for Tx after DTIM (<string> Y or N) [Y]");
+MODULE_PARM(PARM_INTRA_BSS_RELAY,       "s");
+MODULE_PARM_DESC(PARM_INTRA_BSS_RELAY,          "IntraBSS Relay (<string> N or Y) [Y]");
+MODULE_PARM(PARM_RTS_THRESHOLD1,        "h");
+MODULE_PARM_DESC(PARM_RTS_THRESHOLD1,           "RTS Threshold, WDS Port 1 (256 - 2347) [2347]");
+MODULE_PARM(PARM_RTS_THRESHOLD2,        "h");
+MODULE_PARM_DESC(PARM_RTS_THRESHOLD2,           "RTS Threshold, WDS Port 2 (256 - 2347) [2347]");
+MODULE_PARM(PARM_RTS_THRESHOLD3,        "h");
+MODULE_PARM_DESC(PARM_RTS_THRESHOLD3,           "RTS Threshold, WDS Port 3 (256 - 2347) [2347]");
+MODULE_PARM(PARM_RTS_THRESHOLD4,        "h");
+MODULE_PARM_DESC(PARM_RTS_THRESHOLD4,           "RTS Threshold, WDS Port 4 (256 - 2347) [2347]");
+MODULE_PARM(PARM_RTS_THRESHOLD5,        "h");
+MODULE_PARM_DESC(PARM_RTS_THRESHOLD5,           "RTS Threshold, WDS Port 5 (256 - 2347) [2347]");
+MODULE_PARM(PARM_RTS_THRESHOLD6,        "h");
+MODULE_PARM_DESC(PARM_RTS_THRESHOLD6,           "RTS Threshold, WDS Port 6 (256 - 2347) [2347]");
+MODULE_PARM(PARM_TX_RATE1,              "b");
+MODULE_PARM_DESC(PARM_TX_RATE1,                 "Transmit Rate Control, WDS Port 1 (1 - 7) [3]");
+MODULE_PARM(PARM_TX_RATE2,              "b");
+MODULE_PARM_DESC(PARM_TX_RATE2,                 "Transmit Rate Control, WDS Port 2 (1 - 7) [3]");
+MODULE_PARM(PARM_TX_RATE3,              "b");
+MODULE_PARM_DESC(PARM_TX_RATE3,                 "Transmit Rate Control, WDS Port 3 (1 - 7) [3]");
+MODULE_PARM(PARM_TX_RATE4,              "b");
+MODULE_PARM_DESC(PARM_TX_RATE4,                 "Transmit Rate Control, WDS Port 4 (1 - 7) [3]");
+MODULE_PARM(PARM_TX_RATE5,              "b");
+MODULE_PARM_DESC(PARM_TX_RATE5,                 "Transmit Rate Control, WDS Port 5 (1 - 7) [3]");
+MODULE_PARM(PARM_TX_RATE6,              "b");
+MODULE_PARM_DESC(PARM_TX_RATE6,                 "Transmit Rate Control, WDS Port 6 (1 - 7) [3]");
+MODULE_PARM(PARM_WDS_ADDRESS1,          "6b");
+MODULE_PARM_DESC(PARM_WDS_ADDRESS1,             "MAC Address, WDS Port 1 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
+MODULE_PARM(PARM_WDS_ADDRESS2,          "6b");
+MODULE_PARM_DESC(PARM_WDS_ADDRESS2,             "MAC Address, WDS Port 2 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
+MODULE_PARM(PARM_WDS_ADDRESS3,          "6b");
+MODULE_PARM_DESC(PARM_WDS_ADDRESS3,             "MAC Address, WDS Port 3 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
+MODULE_PARM(PARM_WDS_ADDRESS4,          "6b");
+MODULE_PARM_DESC(PARM_WDS_ADDRESS4,             "MAC Address, WDS Port 4 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
+MODULE_PARM(PARM_WDS_ADDRESS5,          "6b");
+MODULE_PARM_DESC(PARM_WDS_ADDRESS5,             "MAC Address, WDS Port 5 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
+MODULE_PARM(PARM_WDS_ADDRESS6,          "6b");
+MODULE_PARM_DESC(PARM_WDS_ADDRESS6,             "MAC Address, WDS Port 6 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
+
+MODULE_PARM(PARM_OWN_BEACON_INTERVAL,   "b");
+MODULE_PARM_DESC(PARM_OWN_BEACON_INTERVAL,      "Own Beacon Interval (20 - 200) [100]");
+MODULE_PARM(PARM_COEXISTENCE,   "b");
+MODULE_PARM_DESC(PARM_COEXISTENCE,      "Coexistence (0-7) [0]");
+
+#endif /* HCF_AP */
+#endif
+
+/* END NEW PARAMETERS */
+/*******************************************************************************
+ * debugging specifics
+ ******************************************************************************/
+#if DBG
+
+static p_u32    pc_debug = DBG_LVL;
+//MODULE_PARM(pc_debug, "i");
+/*static ;?conflicts with my understanding of CL parameters and breaks now I moved
+ * the correspondig logic to wl_profile
+ */ p_u32    DebugFlag = ~0; //recognizable "undefined value" rather then DBG_DEFAULTS;
+//MODULE_PARM(DebugFlag, "l");
+
+dbg_info_t   wl_info = { DBG_MOD_NAME, 0, 0 };
+dbg_info_t  *DbgInfo = &wl_info;
+
+#endif /* DBG */
+#ifdef USE_RTS
+
+static p_char  *useRTS = "N";
+MODULE_PARM( useRTS, "s" );
+MODULE_PARM_DESC( useRTS, "Use RTS test interface (<string> N or Y) [N]" );
+
+#endif  /* USE_RTS */
+/*******************************************************************************
+ * firmware download specifics
+ ******************************************************************************/
+extern struct CFG_RANGE2_STRCT BASED
+	cfg_drv_act_ranges_pri; 	    // describes primary-actor range of HCF
+
+#if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
+extern memimage ap;                 // AP firmware image to be downloaded
+#endif /* HCF_AP */
+
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
+//extern memimage station;            // STA firmware image to be downloaded
+extern memimage fw_image;            // firmware image to be downloaded
+#endif /* HCF_STA */
+
+
+/*******************************************************************************
+ *	wl_insert()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      wl_insert() is scheduled to run after a CARD_INSERTION event is
+ *  received, to configure the PCMCIA socket, and to make the ethernet device
+ *  available to the system.
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the net_device struct of the wireless device
+ *
+ *  RETURNS:
+ *
+ *      TRUE or FALSE
+ *
+ ******************************************************************************/
+int wl_insert( struct net_device *dev )
+{
+	int                     result = 0;
+	int                     hcf_status = HCF_SUCCESS;
+	int                     i;
+	unsigned long           flags = 0;
+	struct wl_private       *lp = wl_priv(dev);
+	/*------------------------------------------------------------------------*/
+	DBG_FUNC( "wl_insert" );
+	DBG_ENTER( DbgInfo );
+
+	/* Initialize the adapter hardware. */
+	memset( &( lp->hcfCtx ), 0, sizeof( IFB_STRCT ));
+
+	/* Initialize the adapter parameters. */
+	spin_lock_init( &( lp->slock ));
+
+	/* Intialize states */
+	//lp->lockcount = 0; //PE1DNN
+        lp->is_handling_int = WL_NOT_HANDLING_INT;
+	lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
+
+	lp->dev = dev;
+
+	DBG_PARAM( DbgInfo, "irq_mask", "0x%04x", irq_mask & 0x0FFFF );
+	DBG_PARAM( DbgInfo, "irq_list", "0x%02x 0x%02x 0x%02x 0x%02x",
+			   irq_list[0] & 0x0FF, irq_list[1] & 0x0FF,
+			   irq_list[2] & 0x0FF, irq_list[3] & 0x0FF );
+	DBG_PARAM( DbgInfo, PARM_NAME_DESIRED_SSID, "\"%s\"", PARM_DESIRED_SSID );
+	DBG_PARAM( DbgInfo, PARM_NAME_OWN_SSID, "\"%s\"", PARM_OWN_SSID );
+	DBG_PARAM( DbgInfo, PARM_NAME_OWN_CHANNEL, "%d", PARM_OWN_CHANNEL);
+	DBG_PARAM( DbgInfo, PARM_NAME_SYSTEM_SCALE, "%d", PARM_SYSTEM_SCALE );
+	DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE, "%d", PARM_TX_RATE );
+	DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD, "%d", PARM_RTS_THRESHOLD );
+	DBG_PARAM( DbgInfo, PARM_NAME_MICROWAVE_ROBUSTNESS, "\"%s\"", PARM_MICROWAVE_ROBUSTNESS );
+	DBG_PARAM( DbgInfo, PARM_NAME_OWN_NAME, "\"%s\"", PARM_OWN_NAME );
+//;?		DBG_PARAM( DbgInfo, PARM_NAME_ENABLE_ENCRYPTION, "\"%s\"", PARM_ENABLE_ENCRYPTION );
+	DBG_PARAM( DbgInfo, PARM_NAME_KEY1, "\"%s\"", PARM_KEY1 );
+	DBG_PARAM( DbgInfo, PARM_NAME_KEY2, "\"%s\"", PARM_KEY2 );
+	DBG_PARAM( DbgInfo, PARM_NAME_KEY3, "\"%s\"", PARM_KEY3 );
+	DBG_PARAM( DbgInfo, PARM_NAME_KEY4, "\"%s\"", PARM_KEY4 );
+	DBG_PARAM( DbgInfo, PARM_NAME_TX_KEY, "%d", PARM_TX_KEY );
+	DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_RATE, "%d", PARM_MULTICAST_RATE );
+	DBG_PARAM( DbgInfo, PARM_NAME_DOWNLOAD_FIRMWARE, "\"%s\"", PARM_DOWNLOAD_FIRMWARE );
+	DBG_PARAM( DbgInfo, PARM_NAME_AUTH_KEY_MGMT_SUITE, "%d", PARM_AUTH_KEY_MGMT_SUITE );
+//;?#if (HCF_TYPE) & HCF_TYPE_STA
+					//;?should we make this code conditional depending on in STA mode
+//;?        DBG_PARAM( DbgInfo, PARM_NAME_PORT_TYPE, "%d", PARM_PORT_TYPE );
+		DBG_PARAM( DbgInfo, PARM_NAME_PM_ENABLED, "%04x", PARM_PM_ENABLED );
+//;?        DBG_PARAM( DbgInfo, PARM_NAME_CREATE_IBSS, "\"%s\"", PARM_CREATE_IBSS );
+//;?        DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_RX, "\"%s\"", PARM_MULTICAST_RX );
+//;?        DBG_PARAM( DbgInfo, PARM_NAME_MAX_SLEEP, "%d", PARM_MAX_SLEEP );
+//;?        DBG_PARAM( DbgInfo, PARM_NAME_NETWORK_ADDR, "\"%s\"", DbgHwAddr( PARM_NETWORK_ADDR ));
+//;?        DBG_PARAM( DbgInfo, PARM_NAME_AUTHENTICATION, "%d", PARM_AUTHENTICATION );
+//;?        DBG_PARAM( DbgInfo, PARM_NAME_OWN_ATIM_WINDOW, "%d", PARM_OWN_ATIM_WINDOW );
+//;?        DBG_PARAM( DbgInfo, PARM_NAME_PM_HOLDOVER_DURATION, "%d", PARM_PM_HOLDOVER_DURATION );
+//;?        DBG_PARAM( DbgInfo, PARM_NAME_PROMISCUOUS_MODE, "\"%s\"", PARM_PROMISCUOUS_MODE );
+//;?#endif /* HCF_STA */
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
+		//;?should we restore this to allow smaller memory footprint
+		//;?I guess: no, since this is Debug mode only
+	DBG_PARAM( DbgInfo, PARM_NAME_OWN_DTIM_PERIOD, "%d", PARM_OWN_DTIM_PERIOD );
+	DBG_PARAM( DbgInfo, PARM_NAME_REJECT_ANY, "\"%s\"", PARM_REJECT_ANY );
+	DBG_PARAM( DbgInfo, PARM_NAME_EXCLUDE_UNENCRYPTED, "\"%s\"", PARM_EXCLUDE_UNENCRYPTED );
+	DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_PM_BUFFERING, "\"%s\"", PARM_MULTICAST_PM_BUFFERING );
+	DBG_PARAM( DbgInfo, PARM_NAME_INTRA_BSS_RELAY, "\"%s\"", PARM_INTRA_BSS_RELAY );
+#ifdef USE_WDS
+	DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD1, "%d", PARM_RTS_THRESHOLD1 );
+	DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD2, "%d", PARM_RTS_THRESHOLD2 );
+	DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD3, "%d", PARM_RTS_THRESHOLD3 );
+	DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD4, "%d", PARM_RTS_THRESHOLD4 );
+	DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD5, "%d", PARM_RTS_THRESHOLD5 );
+	DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD6, "%d", PARM_RTS_THRESHOLD6 );
+	DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE1, "%d", PARM_TX_RATE1 );
+	DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE2, "%d", PARM_TX_RATE2 );
+	DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE3, "%d", PARM_TX_RATE3 );
+	DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE4, "%d", PARM_TX_RATE4 );
+	DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE5, "%d", PARM_TX_RATE5 );
+	DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE6, "%d", PARM_TX_RATE6 );
+	DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS1, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS1 ));
+	DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS2, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS2 ));
+	DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS3, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS3 ));
+	DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS4, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS4 ));
+	DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS5, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS5 ));
+	DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS6, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS6 ));
+#endif /* USE_WDS */
+#endif /* HCF_AP */
+
+	VALID_PARAM( !PARM_DESIRED_SSID || ( strlen( PARM_DESIRED_SSID ) <= PARM_MAX_NAME_LEN ));
+	VALID_PARAM( !PARM_OWN_SSID || ( strlen( PARM_OWN_SSID ) <= PARM_MAX_NAME_LEN ));
+	VALID_PARAM(( PARM_OWN_CHANNEL <= PARM_MAX_OWN_CHANNEL ));
+	VALID_PARAM(( PARM_SYSTEM_SCALE >= PARM_MIN_SYSTEM_SCALE ) && ( PARM_SYSTEM_SCALE <= PARM_MAX_SYSTEM_SCALE ));
+	VALID_PARAM(( PARM_TX_RATE >= PARM_MIN_TX_RATE ) && ( PARM_TX_RATE <= PARM_MAX_TX_RATE ));
+	VALID_PARAM(( PARM_RTS_THRESHOLD <= PARM_MAX_RTS_THRESHOLD ));
+	VALID_PARAM( !PARM_MICROWAVE_ROBUSTNESS || strchr( "NnYy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL );
+	VALID_PARAM( !PARM_OWN_NAME || ( strlen( PARM_NAME_OWN_NAME ) <= PARM_MAX_NAME_LEN ));
+	VALID_PARAM(( PARM_ENABLE_ENCRYPTION <= PARM_MAX_ENABLE_ENCRYPTION ));
+	VALID_PARAM( is_valid_key_string( PARM_KEY1 ));
+	VALID_PARAM( is_valid_key_string( PARM_KEY2 ));
+	VALID_PARAM( is_valid_key_string( PARM_KEY3 ));
+	VALID_PARAM( is_valid_key_string( PARM_KEY4 ));
+	VALID_PARAM(( PARM_TX_KEY >= PARM_MIN_TX_KEY ) && ( PARM_TX_KEY <= PARM_MAX_TX_KEY ));
+
+	VALID_PARAM(( PARM_MULTICAST_RATE >= PARM_MIN_MULTICAST_RATE ) &&
+					( PARM_MULTICAST_RATE <= PARM_MAX_MULTICAST_RATE ));
+
+	VALID_PARAM( !PARM_DOWNLOAD_FIRMWARE || ( strlen( PARM_DOWNLOAD_FIRMWARE ) <= 255 /*;?*/ ));
+	VALID_PARAM(( PARM_AUTH_KEY_MGMT_SUITE < PARM_MAX_AUTH_KEY_MGMT_SUITE ));
+
+	VALID_PARAM( !PARM_LOAD_BALANCING || strchr( "NnYy", PARM_LOAD_BALANCING[0] ) != NULL );
+	VALID_PARAM( !PARM_MEDIUM_DISTRIBUTION || strchr( "NnYy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL );
+	VALID_PARAM(( PARM_TX_POW_LEVEL <= PARM_MAX_TX_POW_LEVEL ));
+
+ 	VALID_PARAM(( PARM_PORT_TYPE >= PARM_MIN_PORT_TYPE ) && ( PARM_PORT_TYPE <= PARM_MAX_PORT_TYPE ));
+	VALID_PARAM( PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD ||
+				 ( PARM_PM_ENABLED & 0x7FFF ) <= WVLAN_PM_STATE_STANDARD );
+ 	VALID_PARAM( !PARM_CREATE_IBSS || strchr( "NnYy", PARM_CREATE_IBSS[0] ) != NULL );
+ 	VALID_PARAM( !PARM_MULTICAST_RX || strchr( "NnYy", PARM_MULTICAST_RX[0] ) != NULL );
+ 	VALID_PARAM(( PARM_MAX_SLEEP <= PARM_MAX_MAX_PM_SLEEP ));
+ 	VALID_PARAM(( PARM_AUTHENTICATION <= PARM_MAX_AUTHENTICATION ));
+ 	VALID_PARAM(( PARM_OWN_ATIM_WINDOW <= PARM_MAX_OWN_ATIM_WINDOW ));
+ 	VALID_PARAM(( PARM_PM_HOLDOVER_DURATION <= PARM_MAX_PM_HOLDOVER_DURATION ));
+ 	VALID_PARAM( !PARM_PROMISCUOUS_MODE || strchr( "NnYy", PARM_PROMISCUOUS_MODE[0] ) != NULL );
+	VALID_PARAM(( PARM_CONNECTION_CONTROL <= PARM_MAX_CONNECTION_CONTROL ));
+
+	VALID_PARAM(( PARM_OWN_DTIM_PERIOD >= PARM_MIN_OWN_DTIM_PERIOD ));
+	VALID_PARAM( !PARM_REJECT_ANY || strchr( "NnYy", PARM_REJECT_ANY[0] ) != NULL );
+	VALID_PARAM( !PARM_EXCLUDE_UNENCRYPTED || strchr( "NnYy", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL );
+	VALID_PARAM( !PARM_MULTICAST_PM_BUFFERING || strchr( "NnYy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL );
+	VALID_PARAM( !PARM_INTRA_BSS_RELAY || strchr( "NnYy", PARM_INTRA_BSS_RELAY[0] ) != NULL );
+#ifdef USE_WDS
+	VALID_PARAM(( PARM_RTS_THRESHOLD1 <= PARM_MAX_RTS_THRESHOLD ));
+	VALID_PARAM(( PARM_RTS_THRESHOLD2 <= PARM_MAX_RTS_THRESHOLD ));
+	VALID_PARAM(( PARM_RTS_THRESHOLD3 <= PARM_MAX_RTS_THRESHOLD ));
+	VALID_PARAM(( PARM_RTS_THRESHOLD4 <= PARM_MAX_RTS_THRESHOLD ));
+	VALID_PARAM(( PARM_RTS_THRESHOLD5 <= PARM_MAX_RTS_THRESHOLD ));
+	VALID_PARAM(( PARM_RTS_THRESHOLD6 <= PARM_MAX_RTS_THRESHOLD ));
+	VALID_PARAM(( PARM_TX_RATE1 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE1 <= PARM_MAX_TX_RATE ));
+	VALID_PARAM(( PARM_TX_RATE2 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE2 <= PARM_MAX_TX_RATE ));
+	VALID_PARAM(( PARM_TX_RATE3 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE3 <= PARM_MAX_TX_RATE ));
+	VALID_PARAM(( PARM_TX_RATE4 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE4 <= PARM_MAX_TX_RATE ));
+	VALID_PARAM(( PARM_TX_RATE5 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE5 <= PARM_MAX_TX_RATE ));
+	VALID_PARAM(( PARM_TX_RATE6 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE6 <= PARM_MAX_TX_RATE ));
+#endif /* USE_WDS */
+
+	VALID_PARAM(( PARM_OWN_BEACON_INTERVAL >= PARM_MIN_OWN_BEACON_INTERVAL ) && ( PARM_OWN_BEACON_INTERVAL <= PARM_MAX_OWN_BEACON_INTERVAL ));
+	VALID_PARAM(( PARM_COEXISTENCE <= PARM_COEXISTENCE ));
+
+	/* Set the driver parameters from the passed in parameters. */
+
+	/* THESE MODULE PARAMETERS ARE TO BE DEPRECATED IN FAVOR OF A NAMING CONVENTION
+	   WHICH IS INLINE WITH THE FORTHCOMING WAVELAN API */
+
+	/* START NEW PARAMETERS */
+
+	lp->Channel             = PARM_OWN_CHANNEL;
+	lp->DistanceBetweenAPs  = PARM_SYSTEM_SCALE;
+
+	/* Need to determine how to handle the new bands for 5GHz */
+	lp->TxRateControl[0]    = PARM_DEFAULT_TX_RATE_2GHZ;
+	lp->TxRateControl[1]    = PARM_DEFAULT_TX_RATE_5GHZ;
+
+	lp->RTSThreshold        = PARM_RTS_THRESHOLD;
+
+	/* Need to determine how to handle the new bands for 5GHz */
+	lp->MulticastRate[0]    = PARM_DEFAULT_MULTICAST_RATE_2GHZ;
+	lp->MulticastRate[1]    = PARM_DEFAULT_MULTICAST_RATE_5GHZ;
+
+	if ( strchr( "Yy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL ) {
+		lp->MicrowaveRobustness = 1;
+	} else {
+		lp->MicrowaveRobustness = 0;
+	}
+	if ( PARM_DESIRED_SSID && ( strlen( PARM_DESIRED_SSID ) <= HCF_MAX_NAME_LEN )) {
+		strcpy( lp->NetworkName, PARM_DESIRED_SSID );
+	}
+	if ( PARM_OWN_SSID && ( strlen( PARM_OWN_SSID ) <= HCF_MAX_NAME_LEN )) {
+		strcpy( lp->NetworkName, PARM_OWN_SSID );
+	}
+	if ( PARM_OWN_NAME && ( strlen( PARM_OWN_NAME ) <= HCF_MAX_NAME_LEN )) {
+		strcpy( lp->StationName, PARM_OWN_NAME );
+	}
+	lp->EnableEncryption = PARM_ENABLE_ENCRYPTION;
+	if ( PARM_KEY1 && ( strlen( PARM_KEY1 ) <= MAX_KEY_LEN )) {
+		strcpy( lp->Key1, PARM_KEY1 );
+	}
+	if ( PARM_KEY2 && ( strlen( PARM_KEY2 ) <= MAX_KEY_LEN )) {
+		strcpy( lp->Key2, PARM_KEY2 );
+	}
+	if ( PARM_KEY3 && ( strlen( PARM_KEY3 ) <= MAX_KEY_LEN )) {
+		strcpy( lp->Key3, PARM_KEY3 );
+	}
+	if ( PARM_KEY4 && ( strlen( PARM_KEY4 ) <= MAX_KEY_LEN )) {
+		strcpy( lp->Key4, PARM_KEY4 );
+	}
+
+	lp->TransmitKeyID = PARM_TX_KEY;
+
+	key_string2key( lp->Key1, &(lp->DefaultKeys.key[0] ));
+	key_string2key( lp->Key2, &(lp->DefaultKeys.key[1] ));
+	key_string2key( lp->Key3, &(lp->DefaultKeys.key[2] ));
+	key_string2key( lp->Key4, &(lp->DefaultKeys.key[3] ));
+
+	lp->DownloadFirmware = 1 ; //;?to be upgraded PARM_DOWNLOAD_FIRMWARE;
+	lp->AuthKeyMgmtSuite = PARM_AUTH_KEY_MGMT_SUITE;
+
+	if ( strchr( "Yy", PARM_LOAD_BALANCING[0] ) != NULL ) {
+		lp->loadBalancing = 1;
+	} else {
+		lp->loadBalancing = 0;
+	}
+
+	if ( strchr( "Yy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL ) {
+		lp->mediumDistribution = 1;
+	} else {
+		lp->mediumDistribution = 0;
+	}
+
+	lp->txPowLevel = PARM_TX_POW_LEVEL;
+
+	lp->srsc[0] = PARM_SRSC_2GHZ;
+	lp->srsc[1] = PARM_SRSC_5GHZ;
+	lp->brsc[0] = PARM_BRSC_2GHZ;
+	lp->brsc[1] = PARM_BRSC_5GHZ;
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
+//;?seems reasonable that even an AP-only driver could afford this small additional footprint
+	lp->PortType            = PARM_PORT_TYPE;
+	lp->MaxSleepDuration    = PARM_MAX_SLEEP;
+	lp->authentication      = PARM_AUTHENTICATION;
+	lp->atimWindow          = PARM_OWN_ATIM_WINDOW;
+	lp->holdoverDuration    = PARM_PM_HOLDOVER_DURATION;
+	lp->PMEnabled           = PARM_PM_ENABLED;  //;?
+	if ( strchr( "Yy", PARM_CREATE_IBSS[0] ) != NULL ) {
+		lp->CreateIBSS = 1;
+	} else {
+		lp->CreateIBSS = 0;
+	}
+	if ( strchr( "Nn", PARM_MULTICAST_RX[0] ) != NULL ) {
+		lp->MulticastReceive = 0;
+	} else {
+		lp->MulticastReceive = 1;
+	}
+	if ( strchr( "Yy", PARM_PROMISCUOUS_MODE[0] ) != NULL ) {
+		lp->promiscuousMode = 1;
+	} else {
+		lp->promiscuousMode = 0;
+	}
+	for( i = 0; i < ETH_ALEN; i++ ) {
+	   lp->MACAddress[i] = PARM_NETWORK_ADDR[i];
+	}
+
+	lp->connectionControl = PARM_CONNECTION_CONTROL;
+
+#endif /* HCF_STA */
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
+	//;?should we restore this to allow smaller memory footprint
+	lp->DTIMPeriod = PARM_OWN_DTIM_PERIOD;
+
+	if ( strchr( "Yy", PARM_REJECT_ANY[0] ) != NULL ) {
+		lp->RejectAny = 1;
+	} else {
+		lp->RejectAny = 0;
+	}
+	if ( strchr( "Nn", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL ) {
+		lp->ExcludeUnencrypted = 0;
+	} else {
+		lp->ExcludeUnencrypted = 1;
+	}
+	if ( strchr( "Yy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL ) {
+		lp->multicastPMBuffering = 1;
+	} else {
+		lp->multicastPMBuffering = 0;
+	}
+	if ( strchr( "Yy", PARM_INTRA_BSS_RELAY[0] ) != NULL ) {
+		lp->intraBSSRelay = 1;
+	} else {
+		lp->intraBSSRelay = 0;
+	}
+
+	lp->ownBeaconInterval = PARM_OWN_BEACON_INTERVAL;
+	lp->coexistence       = PARM_COEXISTENCE;
+
+#ifdef USE_WDS
+	lp->wds_port[0].rtsThreshold    = PARM_RTS_THRESHOLD1;
+	lp->wds_port[1].rtsThreshold    = PARM_RTS_THRESHOLD2;
+	lp->wds_port[2].rtsThreshold    = PARM_RTS_THRESHOLD3;
+	lp->wds_port[3].rtsThreshold    = PARM_RTS_THRESHOLD4;
+	lp->wds_port[4].rtsThreshold    = PARM_RTS_THRESHOLD5;
+	lp->wds_port[5].rtsThreshold    = PARM_RTS_THRESHOLD6;
+	lp->wds_port[0].txRateCntl      = PARM_TX_RATE1;
+	lp->wds_port[1].txRateCntl      = PARM_TX_RATE2;
+	lp->wds_port[2].txRateCntl      = PARM_TX_RATE3;
+	lp->wds_port[3].txRateCntl      = PARM_TX_RATE4;
+	lp->wds_port[4].txRateCntl      = PARM_TX_RATE5;
+	lp->wds_port[5].txRateCntl      = PARM_TX_RATE6;
+
+	for( i = 0; i < ETH_ALEN; i++ ) {
+		lp->wds_port[0].wdsAddress[i] = PARM_WDS_ADDRESS1[i];
+	}
+	for( i = 0; i < ETH_ALEN; i++ ) {
+		lp->wds_port[1].wdsAddress[i] = PARM_WDS_ADDRESS2[i];
+	}
+	for( i = 0; i < ETH_ALEN; i++ ) {
+		lp->wds_port[2].wdsAddress[i] = PARM_WDS_ADDRESS3[i];
+	}
+	for( i = 0; i < ETH_ALEN; i++ ) {
+		lp->wds_port[3].wdsAddress[i] = PARM_WDS_ADDRESS4[i];
+	}
+	for( i = 0; i < ETH_ALEN; i++ ) {
+		lp->wds_port[4].wdsAddress[i] = PARM_WDS_ADDRESS5[i];
+	}
+	for( i = 0; i < ETH_ALEN; i++ ) {
+		lp->wds_port[5].wdsAddress[i] = PARM_WDS_ADDRESS6[i];
+	}
+#endif  /* USE_WDS */
+#endif  /* HCF_AP */
+#ifdef USE_RTS
+	if ( strchr( "Yy", useRTS[0] ) != NULL ) {
+		lp->useRTS = 1;
+	} else {
+		lp->useRTS = 0;
+	}
+#endif  /* USE_RTS */
+
+
+	/* END NEW PARAMETERS */
+
+
+	wl_lock( lp, &flags );
+
+	/* Initialize the portState variable */
+	lp->portState = WVLAN_PORT_STATE_DISABLED;
+
+	/* Initialize the ScanResult struct */
+	memset( &( lp->scan_results ), 0, sizeof( lp->scan_results ));
+	lp->scan_results.scan_complete = FALSE;
+
+	/* Initialize the ProbeResult struct */
+	memset( &( lp->probe_results ), 0, sizeof( lp->probe_results ));
+	lp->probe_results.scan_complete = FALSE;
+	lp->probe_num_aps = 0;
+
+
+	/* Initialize Tx queue stuff */
+	memset( lp->txList, 0, sizeof( lp->txList ));
+
+	INIT_LIST_HEAD( &( lp->txFree ));
+
+	lp->txF.skb  = NULL;
+	lp->txF.port = 0;
+
+
+	for( i = 0; i < DEFAULT_NUM_TX_FRAMES; i++ ) {
+		list_add_tail( &( lp->txList[i].node ), &( lp->txFree ));
+	}
+
+
+	for( i = 0; i < WVLAN_MAX_TX_QUEUES; i++ ) {
+		INIT_LIST_HEAD( &( lp->txQ[i] ));
+	}
+
+	lp->netif_queue_on = TRUE;
+	lp->txQ_count = 0;
+	/* Initialize the use_dma element in the adapter structure. Not sure if
+	   this should be a compile-time or run-time configurable. So for now,
+	   implement as run-time and just define here */
+#ifdef WARP
+#ifdef ENABLE_DMA
+	DBG_TRACE( DbgInfo, "HERMES 2.5 BUSMASTER DMA MODE\n" );
+	lp->use_dma = 1;
+#else
+	DBG_TRACE( DbgInfo, "HERMES 2.5 PORT I/O MODE\n" );
+	lp->use_dma = 0;
+#endif // ENABLE_DMA
+#endif // WARP
+
+	/* Register the ISR handler information here, so that it's not done
+	   repeatedly in the ISR */
+        tasklet_init(&lp->task, wl_isr_handler, (unsigned long)lp);
+
+        /* Connect to the adapter */
+        DBG_TRACE( DbgInfo, "Calling hcf_connect()...\n" );
+        hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
+	//HCF_ERR_INCOMP_FW is acceptable, because download must still take place
+	//HCF_ERR_INCOMP_PRI is not acceptable
+	if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
+		DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
+		wl_unlock( lp, &flags );
+		goto hcf_failed;
+	}
+
+	//;?should set HCF_version and how about driver_stat
+	lp->driverInfo.IO_address       = dev->base_addr;
+	lp->driverInfo.IO_range         = HCF_NUM_IO_PORTS;	//;?conditionally 0x40 or 0x80 seems better
+	lp->driverInfo.IRQ_number       = dev->irq;
+	lp->driverInfo.card_stat        = lp->hcfCtx.IFB_CardStat;
+	//;? what happened to frame_type
+
+	/* Fill in the driver identity structure */
+	lp->driverIdentity.len              = ( sizeof( lp->driverIdentity ) / sizeof( hcf_16 )) - 1;
+	lp->driverIdentity.typ              = CFG_DRV_IDENTITY;
+	lp->driverIdentity.comp_id          = DRV_IDENTITY;
+	lp->driverIdentity.variant          = DRV_VARIANT;
+	lp->driverIdentity.version_major    = DRV_MAJOR_VERSION;
+	lp->driverIdentity.version_minor    = DRV_MINOR_VERSION;
+
+
+	/* Start the card here - This needs to be done in order to get the
+	   MAC address for the network layer */
+	DBG_TRACE( DbgInfo, "Calling wvlan_go() to perform a card reset...\n" );
+	hcf_status = wl_go( lp );
+
+	if ( hcf_status != HCF_SUCCESS ) {
+		DBG_ERROR( DbgInfo, "wl_go() failed\n" );
+		wl_unlock( lp, &flags );
+		goto hcf_failed;
+	}
+
+	/* Certain RIDs must be set before enabling the ports */
+	wl_put_ltv_init( lp );
+
+#if 0 //;?why was this already commented out in wl_lkm_720
+	/* Enable the ports */
+	if ( wl_adapter_is_open( lp->dev )) {
+		/* Enable the ports */
+		DBG_TRACE( DbgInfo, "Enabling Port 0\n" );
+		hcf_status = wl_enable( lp );
+
+		if ( hcf_status != HCF_SUCCESS ) {
+			DBG_TRACE( DbgInfo, "Enable port 0 failed: 0x%x\n", hcf_status );
+		}
+
+#if (HCF_TYPE) & HCF_TYPE_AP
+		DBG_TRACE( DbgInfo, "Enabling WDS Ports\n" );
+		//wl_enable_wds_ports( lp );
+#endif  /* (HCF_TYPE) & HCF_TYPE_AP */
+
+	}
+#endif
+
+	/* Fill out the MAC address information in the net_device struct */
+	memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN );
+	dev->addr_len = ETH_ALEN;
+
+	lp->is_registered = TRUE;
+
+#ifdef USE_PROFILE
+	/* Parse the config file for the sake of creating WDS ports if WDS is
+	   configured there but not in the module options */
+	parse_config( dev );
+#endif  /* USE_PROFILE */
+
+	/* If we're going into AP Mode, register the "virtual" ethernet devices
+	   needed for WDS */
+	WL_WDS_NETDEV_REGISTER( lp );
+
+	/* Reset the DownloadFirmware variable in the private struct. If the
+	   config file is not used, this will not matter; if it is used, it
+	   will be reparsed in wl_open(). This is done because logic in wl_open
+	   used to check if a firmware download is needed is broken by parsing
+	   the file here; however, this parsing is needed to register WDS ports
+	   in AP mode, if they are configured */
+	lp->DownloadFirmware = WVLAN_DRV_MODE_STA; //;?download_firmware;
+
+#ifdef USE_RTS
+	if ( lp->useRTS == 1 ) {
+		DBG_TRACE( DbgInfo, "ENTERING RTS MODE...\n" );
+                wl_act_int_off( lp );
+                lp->is_handling_int = WL_NOT_HANDLING_INT; // Not handling interrupts anymore
+
+		wl_disable( lp );
+
+        	hcf_connect( &lp->hcfCtx, HCF_DISCONNECT);
+	}
+#endif  /* USE_RTS */
+
+	wl_unlock( lp, &flags );
+
+	DBG_TRACE( DbgInfo, "%s: Wireless, io_addr %#03lx, irq %d, ""mac_address ",
+			   dev->name, dev->base_addr, dev->irq );
+
+	for( i = 0; i < ETH_ALEN; i++ ) {
+		printk( "%02X%c", dev->dev_addr[i], (( i < ( ETH_ALEN-1 )) ? ':' : '\n' ));
+	}
+
+#if 0 //SCULL_USE_PROC /* don't waste space if unused */
+	create_proc_read_entry( "wlags", 0, NULL, scull_read_procmem, dev );
+	proc_mkdir("driver/wlags49", 0);
+	proc_write("driver/wlags49/wlags49_type", write_int, &lp->wlags49_type);
+#endif /* SCULL_USE_PROC */
+
+	DBG_LEAVE( DbgInfo );
+	return result;
+
+hcf_failed:
+	wl_hcf_error( dev, hcf_status );
+
+failed:
+
+	DBG_ERROR( DbgInfo, "wl_insert() FAILED\n" );
+
+	if ( lp->is_registered == TRUE ) {
+		lp->is_registered = FALSE;
+	}
+
+	WL_WDS_NETDEV_DEREGISTER( lp );
+
+	result = -EFAULT;
+
+
+	DBG_LEAVE( DbgInfo );
+	return result;
+} // wl_insert
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wl_reset()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Reset the adapter.
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the net_device struct of the wireless device
+ *
+ *  RETURNS:
+ *
+ *      an HCF status code
+ *
+ ******************************************************************************/
+int wl_reset(struct net_device *dev)
+{
+	struct wl_private  *lp = wl_priv(dev);
+	int                 hcf_status = HCF_SUCCESS;
+	/*------------------------------------------------------------------------*/
+	DBG_FUNC( "wl_reset" );
+	DBG_ENTER( DbgInfo );
+	DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
+	DBG_PARAM( DbgInfo, "dev->base_addr", "(%#03lx)", dev->base_addr );
+
+	/*
+         * The caller should already have a lock and
+         * disable the interrupts, we do not lock here,
+         * nor do we enable/disable interrupts!
+         */
+
+	DBG_TRACE( DbgInfo, "Device Base Address: %#03lx\n", dev->base_addr );
+	if ( dev->base_addr ) {
+		/* Shutdown the adapter. */
+		hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
+
+		/* Reset the driver information. */
+		lp->txBytes = 0;
+
+		/* Connect to the adapter. */
+        	hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
+		if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
+			DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
+			goto out;
+		}
+
+		/* Check if firmware is present, if not change state */
+		if ( hcf_status == HCF_ERR_INCOMP_FW ) {
+			lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
+		}
+
+		/* Initialize the portState variable */
+		lp->portState = WVLAN_PORT_STATE_DISABLED;
+
+		/* Restart the adapter. */
+		hcf_status = wl_go( lp );
+		if ( hcf_status != HCF_SUCCESS ) {
+			DBG_ERROR( DbgInfo, "wl_go() failed, status: 0x%x\n", hcf_status );
+			goto out;
+		}
+
+		/* Certain RIDs must be set before enabling the ports */
+		wl_put_ltv_init( lp );
+	} else {
+		DBG_ERROR( DbgInfo, "Device Base Address INVALID!!!\n" );
+	}
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return hcf_status;
+} // wl_reset
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wl_go()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Reset the adapter.
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the net_device struct of the wireless device
+ *
+ *  RETURNS:
+ *
+ *      an HCF status code
+ *
+ ******************************************************************************/
+int wl_go( struct wl_private *lp )
+{
+	int  	hcf_status = HCF_SUCCESS;
+	char	*cp = NULL;			//fw_image
+	int	retries = 0;
+	/*------------------------------------------------------------------------*/
+	DBG_FUNC( "wl_go" );
+	DBG_ENTER( DbgInfo );
+
+	hcf_status = wl_disable( lp );
+	if ( hcf_status != HCF_SUCCESS ) {
+		DBG_TRACE( DbgInfo, "Disable port 0 failed: 0x%x\n", hcf_status );
+
+		while (( hcf_status != HCF_SUCCESS ) && (retries < 10)) {
+			retries++;
+			hcf_status = wl_disable( lp );
+		}
+		if ( hcf_status == HCF_SUCCESS ) {
+			DBG_TRACE( DbgInfo, "Disable port 0 succes : %d retries\n", retries );
+		} else {
+			DBG_TRACE( DbgInfo, "Disable port 0 failed after: %d retries\n", retries );
+		}
+	}
+
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
+	//DBG_TRACE( DbgInfo, "Disabling WDS Ports\n" );
+	//wl_disable_wds_ports( lp );
+#endif  /* (HCF_TYPE) & HCF_TYPE_AP */
+
+//;?what was the purpose of this
+// 	/* load the appropriate firmware image, depending on driver mode */
+// 	lp->ltvRecord.len   = ( sizeof( CFG_RANGE20_STRCT ) / sizeof( hcf_16 )) - 1;
+// 	lp->ltvRecord.typ   = CFG_DRV_ACT_RANGES_PRI;
+// 	hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+#if BIN_DL
+	if ( strlen( lp->fw_image_filename ) ) {
+mm_segment_t	fs;
+int		    	file_desc;
+int 			rc;
+
+		DBG_TRACE( DbgInfo, "F/W image:%s:\n", lp->fw_image_filename );
+		/* Obtain a user-space process context, storing the original context */
+		fs = get_fs( );
+		set_fs( get_ds( ));
+		file_desc = open( lp->fw_image_filename, O_RDONLY, 0 );
+		if ( file_desc == -1 ) {
+			DBG_ERROR( DbgInfo, "No image file found\n" );
+		} else {
+			DBG_TRACE( DbgInfo, "F/W image file found\n" );
+#define DHF_ALLOC_SIZE 96000			//just below 96K, let's hope it suffices for now and for the future
+			cp = (char*)vmalloc( DHF_ALLOC_SIZE );
+			if ( cp == NULL ) {
+				DBG_ERROR( DbgInfo, "error in vmalloc\n" );
+			} else {
+				rc = read( file_desc, cp, DHF_ALLOC_SIZE );
+				if ( rc == DHF_ALLOC_SIZE ) {
+					DBG_ERROR( DbgInfo, "buffer too small, %d\n", DHF_ALLOC_SIZE );
+				} else if ( rc > 0 ) {
+					DBG_TRACE( DbgInfo, "read O.K.: %d bytes  %.12s\n", rc, cp );
+					rc = read( file_desc, &cp[rc], 1 );
+					if ( rc == 0 ) { //;/change to an until-loop at rc<=0
+						DBG_TRACE( DbgInfo, "no more to read\n" );
+					}
+				}
+				if ( rc != 0 ) {
+					DBG_ERROR( DbgInfo, "file not read in one swoop or other error"\
+										", give up, too complicated, rc = %0X\n", rc );
+					DBG_ERROR( DbgInfo, "still have to change code to get a real download now !!!!!!!!\n" );
+				} else {
+					DBG_TRACE( DbgInfo, "before dhf_download_binary\n" );
+					hcf_status = dhf_download_binary( (memimage *)cp );
+					DBG_TRACE( DbgInfo, "after dhf_download_binary, before dhf_download_fw\n" );
+					//;?improve error flow/handling
+					hcf_status = dhf_download_fw( &lp->hcfCtx, (memimage *)cp );
+					DBG_TRACE( DbgInfo, "after dhf_download_fw\n" );
+				}
+				vfree( cp );
+			}
+			close( file_desc );
+		}
+		set_fs( fs );			/* Return to the original context */
+	}
+#endif // BIN_DL
+
+	/* If firmware is present but the type is unknown then download anyway */
+	if ( (lp->firmware_present == WL_FRIMWARE_PRESENT)
+	     &&
+	     ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_STA )
+	     &&
+	     ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_AP ) ) {
+		/* Unknown type, download needed.  */
+		lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
+	}
+
+	if(lp->firmware_present == WL_FRIMWARE_NOT_PRESENT)
+	{
+		if ( cp == NULL ) {
+			DBG_TRACE( DbgInfo, "Downloading STA firmware...\n" );
+//			hcf_status = dhf_download_fw( &lp->hcfCtx, &station );
+			hcf_status = dhf_download_fw( &lp->hcfCtx, &fw_image );
+		}
+		if ( hcf_status != HCF_SUCCESS ) {
+			DBG_ERROR( DbgInfo, "Firmware Download failed\n" );
+			DBG_LEAVE( DbgInfo );
+			return hcf_status;
+		}
+	}
+	/* Report the FW versions */
+	//;?obsolete, use the available IFB info:: wl_get_pri_records( lp );
+	if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA  ) {
+		DBG_TRACE( DbgInfo, "downloaded station F/W\n" );
+	} else if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
+		DBG_TRACE( DbgInfo, "downloaded AP F/W\n" );
+	} else {
+		DBG_ERROR( DbgInfo, "unknown F/W type\n" );
+	}
+
+	/*
+         * Downloaded, no need to repeat this next time, assume the
+         * contents stays in the card until it is powered off. Note we
+         * do not switch firmware on the fly, the firmware is fixed in
+         * the driver for now.
+         */
+	lp->firmware_present = WL_FRIMWARE_PRESENT;
+
+	DBG_TRACE( DbgInfo, "ComponentID:%04x variant:%04x major:%04x minor:%04x\n",
+				CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ),
+				CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.variant ),
+				CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_major ),
+				CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_minor ));
+
+	/* now we wil get the MAC address of the card */
+	lp->ltvRecord.len = 4;
+	if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
+		lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
+	} else
+	{
+		lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
+	}
+	hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+	if ( hcf_status != HCF_SUCCESS ) {
+		DBG_ERROR( DbgInfo, "Could not retrieve MAC address\n" );
+		DBG_LEAVE( DbgInfo );
+		return hcf_status;
+	}
+	memcpy( lp->MACAddress, &lp->ltvRecord.u.u8[0], ETH_ALEN );
+	DBG_TRACE( DbgInfo, "Card MAC Address: %s\n", DbgHwAddr( lp->MACAddress ));
+
+	/* Write out configuration to the device, enable, and reconnect. However,
+	   only reconnect if in AP mode. For STA mode, need to wait for passive scan
+	   completion before a connect can be issued */
+	wl_put_ltv( lp );
+	/* Enable the ports */
+	hcf_status = wl_enable( lp );
+
+	if ( lp->DownloadFirmware == WVLAN_DRV_MODE_AP ) {
+#ifdef USE_WDS
+		wl_enable_wds_ports( lp );
+#endif // USE_WDS
+		hcf_status = wl_connect( lp );
+	}
+	DBG_LEAVE( DbgInfo );
+	return hcf_status;
+} // wl_go
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wl_set_wep_keys()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Write TxKeyID and WEP keys to the adapter. This is separated from
+ *  wl_apply() to allow dynamic WEP key updates through the wireless
+ *  extensions.
+ *
+ *  PARAMETERS:
+ *
+ *      lp  - a pointer to the wireless adapter's private structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_set_wep_keys( struct wl_private *lp )
+{
+	int count = 0;
+	/*------------------------------------------------------------------------*/
+	DBG_FUNC( "wl_set_wep_keys" );
+	DBG_ENTER( DbgInfo );
+	DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
+	if ( lp->EnableEncryption ) {
+		/* NOTE: CFG_CNF_ENCRYPTION is set in wl_put_ltv() as it's a static
+				 RID */
+
+		/* set TxKeyID */
+		lp->ltvRecord.len = 2;
+		lp->ltvRecord.typ       = CFG_TX_KEY_ID;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE(lp->TransmitKeyID - 1);
+
+		hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		DBG_TRACE( DbgInfo, "Key 1 len: %d\n", lp->DefaultKeys.key[0].len );
+		DBG_TRACE( DbgInfo, "Key 2 len: %d\n", lp->DefaultKeys.key[1].len );
+		DBG_TRACE( DbgInfo, "Key 3 len: %d\n", lp->DefaultKeys.key[2].len );
+		DBG_TRACE( DbgInfo, "Key 4 len: %d\n", lp->DefaultKeys.key[3].len );
+
+		/* write keys */
+		lp->DefaultKeys.len = sizeof( lp->DefaultKeys ) / sizeof( hcf_16 ) - 1;
+		lp->DefaultKeys.typ = CFG_DEFAULT_KEYS;
+
+		/* endian translate the appropriate key information */
+		for( count = 0; count < MAX_KEYS; count++ ) {
+			lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
+		}
+
+		hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->DefaultKeys ));
+
+		/* Reverse the above endian translation, since these keys are accessed
+		   elsewhere */
+		for( count = 0; count < MAX_KEYS; count++ ) {
+			lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
+		}
+
+		DBG_NOTICE( DbgInfo, "encrypt: %d, ID: %d\n", lp->EnableEncryption, lp->TransmitKeyID );
+		DBG_NOTICE( DbgInfo, "set key: %s(%d) [%d]\n", lp->DefaultKeys.key[lp->TransmitKeyID-1].key, lp->DefaultKeys.key[lp->TransmitKeyID-1].len, lp->TransmitKeyID-1 );
+	}
+
+	DBG_LEAVE( DbgInfo );
+} // wl_set_wep_keys
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wl_apply()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Write the parameters to the adapter. (re-)enables the card if device is
+ *  open. Returns hcf_status of hcf_enable().
+ *
+ *  PARAMETERS:
+ *
+ *      lp  - a pointer to the wireless adapter's private structure
+ *
+ *  RETURNS:
+ *
+ *      an HCF status code
+ *
+ ******************************************************************************/
+int wl_apply(struct wl_private *lp)
+{
+	int hcf_status = HCF_SUCCESS;
+	/*------------------------------------------------------------------------*/
+	DBG_FUNC( "wl_apply" );
+	DBG_ENTER( DbgInfo );
+	DBG_ASSERT( lp != NULL);
+	DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
+
+	if ( !( lp->flags & WVLAN2_UIL_BUSY )) {
+		/* The adapter parameters have changed:
+				disable card
+				reload parameters
+				enable card
+		*/
+
+		if ( wl_adapter_is_open( lp->dev )) {
+			/* Disconnect and disable if necessary */
+			hcf_status = wl_disconnect( lp );
+			if ( hcf_status != HCF_SUCCESS ) {
+				DBG_ERROR( DbgInfo, "Disconnect failed\n" );
+				DBG_LEAVE( DbgInfo );
+				return -1;
+			}
+			hcf_status = wl_disable( lp );
+			if ( hcf_status != HCF_SUCCESS ) {
+				DBG_ERROR( DbgInfo, "Disable failed\n" );
+				DBG_LEAVE( DbgInfo );
+				return -1;
+			} else {
+				/* Write out configuration to the device, enable, and reconnect.
+				   However, only reconnect if in AP mode. For STA mode, need to
+				   wait for passive scan completion before a connect can be
+				   issued */
+				hcf_status = wl_put_ltv( lp );
+
+				if ( hcf_status == HCF_SUCCESS ) {
+					hcf_status = wl_enable( lp );
+
+					if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
+						hcf_status = wl_connect( lp );
+					}
+				} else {
+					DBG_WARNING( DbgInfo, "wl_put_ltv() failed\n" );
+				}
+			}
+		}
+	}
+
+	DBG_LEAVE( DbgInfo );
+	return hcf_status;
+} // wl_apply
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wl_put_ltv_init()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Used to set basic parameters for card initialization.
+ *
+ *  PARAMETERS:
+ *
+ *      lp  - a pointer to the wireless adapter's private structure
+ *
+ *  RETURNS:
+ *
+ *      an HCF status code
+ *
+ ******************************************************************************/
+int wl_put_ltv_init( struct wl_private *lp )
+{
+	int i;
+	int hcf_status;
+	CFG_RID_LOG_STRCT *RidLog;
+	/*------------------------------------------------------------------------*/
+	DBG_FUNC( "wl_put_ltv_init" );
+	DBG_ENTER( DbgInfo );
+	if ( lp == NULL ) {
+		DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
+		DBG_LEAVE( DbgInfo );
+		return -1;
+	}
+	/* DMA/IO */
+	lp->ltvRecord.len = 2;
+	lp->ltvRecord.typ = CFG_CNTL_OPT;
+
+	/* The Card Services build must ALWAYS configure for 16-bit I/O. PCI or
+	   CardBus can be set to either 16/32 bit I/O, or Bus Master DMA, but only
+	   for Hermes-2.5 */
+#ifdef BUS_PCMCIA
+	lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_16BIT );
+#else
+	if ( lp->use_dma ) {
+		lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_DMA );
+	} else {
+		lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
+	}
+
+#endif
+	hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+	DBG_TRACE( DbgInfo, "CFG_CNTL_OPT                      : 0x%04x\n",
+			   lp->ltvRecord.u.u16[0] );
+	DBG_TRACE( DbgInfo, "CFG_CNTL_OPT result               : 0x%04x\n",
+			   hcf_status );
+
+	/* Register the list of RIDs on which asynchronous notification is
+	   required. Note that this mechanism replaces the mailbox, so the mailbox
+	   can be queried by the host (if desired) without contention from us */
+	i=0;
+
+	lp->RidList[i].len     = sizeof( lp->ProbeResp );
+	lp->RidList[i].typ     = CFG_ACS_SCAN;
+	lp->RidList[i].bufp    = (wci_recordp)&lp->ProbeResp;
+	//lp->ProbeResp.infoType = 0xFFFF;
+	i++;
+
+	lp->RidList[i].len     = sizeof( lp->assoc_stat );
+	lp->RidList[i].typ     = CFG_ASSOC_STAT;
+	lp->RidList[i].bufp    = (wci_recordp)&lp->assoc_stat;
+	lp->assoc_stat.len     = 0xFFFF;
+	i++;
+
+	lp->RidList[i].len     = 4;
+	lp->RidList[i].typ     = CFG_UPDATED_INFO_RECORD;
+	lp->RidList[i].bufp    = (wci_recordp)&lp->updatedRecord;
+	lp->updatedRecord.len  = 0xFFFF;
+	i++;
+
+	lp->RidList[i].len     = sizeof( lp->sec_stat );
+	lp->RidList[i].typ     = CFG_SECURITY_STAT;
+	lp->RidList[i].bufp    = (wci_recordp)&lp->sec_stat;
+	lp->sec_stat.len       = 0xFFFF;
+	i++;
+
+	lp->RidList[i].typ     = 0;    // Terminate List
+
+	RidLog = (CFG_RID_LOG_STRCT *)&lp->ltvRecord;
+	RidLog->len     = 3;
+	RidLog->typ     = CFG_REG_INFO_LOG;
+	RidLog->recordp = (RID_LOGP)&lp->RidList[0];
+
+	hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+	DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG\n" );
+	DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG result           : 0x%04x\n",
+			   hcf_status );
+	DBG_LEAVE( DbgInfo );
+	return hcf_status;
+} // wl_put_ltv_init
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wl_put_ltv()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Used by wvlan_apply() and wvlan_go to set the card's configuration.
+ *
+ *  PARAMETERS:
+ *
+ *      lp  - a pointer to the wireless adapter's private structure
+ *
+ *  RETURNS:
+ *
+ *      an HCF status code
+ *
+ ******************************************************************************/
+int wl_put_ltv( struct wl_private *lp )
+{
+	int len;
+	int hcf_status;
+	/*------------------------------------------------------------------------*/
+	DBG_FUNC( "wl_put_ltv" );
+	DBG_ENTER( DbgInfo );
+
+	if ( lp == NULL ) {
+		DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
+		return -1;
+	}
+	if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
+		lp->maxPort = 6;			//;?why set this here and not as part of download process
+	} else {
+		lp->maxPort = 0;
+	}
+
+	/* Send our configuration to the card. Perform any endian translation
+	   necessary */
+	/* Register the Mailbox; VxWorks does this elsewhere; why;? */
+	lp->ltvRecord.len       = 4;
+	lp->ltvRecord.typ       = CFG_REG_MB;
+	lp->ltvRecord.u.u32[0]  = (u_long)&( lp->mailbox );
+	lp->ltvRecord.u.u16[2]  = ( MB_SIZE / sizeof( hcf_16 ));
+	hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+	/* Max Data Length */
+	lp->ltvRecord.len       = 2;
+	lp->ltvRecord.typ       = CFG_CNF_MAX_DATA_LEN;
+	lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( HCF_MAX_PACKET_SIZE );
+	hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+	/* System Scale / Distance between APs */
+	lp->ltvRecord.len       = 2;
+	lp->ltvRecord.typ       = CFG_CNF_SYSTEM_SCALE;
+	lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->DistanceBetweenAPs );
+	hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+	/* Channel */
+	if ( lp->CreateIBSS && ( lp->Channel == 0 )) {
+		DBG_TRACE( DbgInfo, "Create IBSS" );
+		lp->Channel = 10;
+	}
+	lp->ltvRecord.len       = 2;
+	lp->ltvRecord.typ       = CFG_CNF_OWN_CHANNEL;
+	lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->Channel );
+	hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+	/* Microwave Robustness */
+	lp->ltvRecord.len       = 2;
+	lp->ltvRecord.typ       = CFG_CNF_MICRO_WAVE;
+	lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->MicrowaveRobustness );
+	hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+	/* Load Balancing */
+	lp->ltvRecord.len       = 2;
+	lp->ltvRecord.typ       = CFG_CNF_LOAD_BALANCING;
+	lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->loadBalancing );
+	hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+	/* Medium Distribution */
+	lp->ltvRecord.len       = 2;
+	lp->ltvRecord.typ       = CFG_CNF_MEDIUM_DISTRIBUTION;
+	lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->mediumDistribution );
+	hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+	/* Country Code */
+
+#ifdef WARP
+	/* Tx Power Level (for supported cards) */
+	lp->ltvRecord.len       = 2;
+	lp->ltvRecord.typ       = CFG_CNF_TX_POW_LVL;
+	lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->txPowLevel );
+	hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+	/* Short Retry Limit */
+	/*lp->ltvRecord.len       = 2;
+	lp->ltvRecord.typ       = 0xFC32;
+	lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->shortRetryLimit );
+	hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+	*/
+
+	/* Long Retry Limit */
+	/*lp->ltvRecord.len       = 2;
+	lp->ltvRecord.typ       = 0xFC33;
+	lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->longRetryLimit );
+	hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+	*/
+
+	/* Supported Rate Set Control */
+	lp->ltvRecord.len       = 3;
+	lp->ltvRecord.typ       = CFG_SUPPORTED_RATE_SET_CNTL; //0xFC88;
+	lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->srsc[0] );
+	lp->ltvRecord.u.u16[1]  = CNV_INT_TO_LITTLE( lp->srsc[1] );
+	hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+	/* Basic Rate Set Control */
+	lp->ltvRecord.len       = 3;
+	lp->ltvRecord.typ       = CFG_BASIC_RATE_SET_CNTL; //0xFC89;
+	lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->brsc[0] );
+	lp->ltvRecord.u.u16[1]  = CNV_INT_TO_LITTLE( lp->brsc[1] );
+	hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+	/* Frame Burst Limit */
+	/* Defined, but not currently available in Firmware */
+
+#endif // WARP
+
+#ifdef WARP
+	/* Multicast Rate */
+	lp->ltvRecord.len       = 3;
+	lp->ltvRecord.typ       = CFG_CNF_MCAST_RATE;
+	lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
+	lp->ltvRecord.u.u16[1]  = CNV_INT_TO_LITTLE( lp->MulticastRate[1] );
+#else
+	lp->ltvRecord.len       = 2;
+	lp->ltvRecord.typ       = CFG_CNF_MCAST_RATE;
+	lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
+#endif // WARP
+	hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+	/* Own Name (Station Nickname) */
+	if (( len = ( strlen( lp->StationName ) + 1 ) & ~0x01 ) != 0 ) {
+		//DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME                  : %s\n",
+		//           lp->StationName );
+
+		lp->ltvRecord.len       = 2 + ( len / sizeof( hcf_16 ));
+		lp->ltvRecord.typ       = CFG_CNF_OWN_NAME;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( strlen( lp->StationName ));
+
+		memcpy( &( lp->ltvRecord.u.u8[2] ), lp->StationName, len );
+	} else {
+		//DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME                  : EMPTY\n" );
+
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_CNF_OWN_NAME;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 0 );
+	}
+
+	hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+	//DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME result           : 0x%04x\n",
+	//           hcf_status );
+
+	/* The following are set in STA mode only */
+	if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA  ) {
+
+		/* RTS Threshold */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_RTS_THRH;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->RTSThreshold );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* Port Type */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_CNF_PORT_TYPE;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->PortType );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* Tx Rate Control */
+#ifdef WARP
+		lp->ltvRecord.len       = 3;
+		lp->ltvRecord.typ       = CFG_TX_RATE_CNTL;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
+		lp->ltvRecord.u.u16[1]  = CNV_INT_TO_LITTLE( lp->TxRateControl[1] );
+#else
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_TX_RATE_CNTL;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
+#endif  // WARP
+
+//;?skip temporarily to see whether the RID or something else is the probelm hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 2.4GHz           : 0x%04x\n",
+				   lp->TxRateControl[0] );
+		DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 5.0GHz           : 0x%04x\n",
+				   lp->TxRateControl[1] );
+		DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL result           : 0x%04x\n",
+				   hcf_status );
+		/* Power Management */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_CNF_PM_ENABLED;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->PMEnabled );
+//		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 0x8001 );
+		DBG_TRACE( DbgInfo, "CFG_CNF_PM_ENABLED                : 0x%04x\n", lp->PMEnabled );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+		/* Multicast Receive */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_CNF_MCAST_RX;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->MulticastReceive );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* Max Sleep Duration */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_CNF_MAX_SLEEP_DURATION;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->MaxSleepDuration );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* Create IBSS */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_CREATE_IBSS;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->CreateIBSS );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* Desired SSID */
+		if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
+			 ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
+			 ( strcmp( lp->NetworkName, "any" ) != 0 )) {
+			//DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID                  : %s\n",
+			//           lp->NetworkName );
+
+			lp->ltvRecord.len       = 2 + (len / sizeof(hcf_16));
+			lp->ltvRecord.typ       = CFG_DESIRED_SSID;
+			lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
+
+			memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
+		} else {
+			//DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID                  : ANY\n" );
+
+			lp->ltvRecord.len       = 2;
+			lp->ltvRecord.typ       = CFG_DESIRED_SSID;
+			lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 0 );
+		}
+
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		//DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID result           : 0x%04x\n",
+		//           hcf_status );
+		/* Own ATIM window */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_CNF_OWN_ATIM_WINDOW;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->atimWindow );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+
+		/* Holdover Duration */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_CNF_HOLDOVER_DURATION;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->holdoverDuration );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* Promiscuous Mode */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_PROMISCUOUS_MODE;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->promiscuousMode );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* Authentication */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_CNF_AUTHENTICATION;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->authentication );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+#ifdef WARP
+		/* Connection Control */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_CNF_CONNECTION_CNTL;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->connectionControl );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+
+
+		/* Probe data rate */
+		/*lp->ltvRecord.len       = 3;
+		lp->ltvRecord.typ       = CFG_PROBE_DATA_RATE;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->probeDataRates[0] );
+		lp->ltvRecord.u.u16[1]  = CNV_INT_TO_LITTLE( lp->probeDataRates[1] );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 2.4GHz        : 0x%04x\n",
+				   lp->probeDataRates[0] );
+		DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 5.0GHz        : 0x%04x\n",
+				   lp->probeDataRates[1] );
+		DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE result        : 0x%04x\n",
+				   hcf_status );*/
+#endif // WARP
+	} else {
+		/* The following are set in AP mode only */
+#if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
+		//;?should we restore this to allow smaller memory footprint
+
+		/* DTIM Period */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_CNF_OWN_DTIM_PERIOD;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->DTIMPeriod );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* Multicast PM Buffering */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_CNF_MCAST_PM_BUF;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->multicastPMBuffering );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* Reject ANY - Closed System */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_CNF_REJECT_ANY;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->RejectAny );
+
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* Exclude Unencrypted */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_CNF_EXCL_UNENCRYPTED;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->ExcludeUnencrypted );
+
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* IntraBSS Relay */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_CNF_INTRA_BSS_RELAY;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->intraBSSRelay );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* RTS Threshold 0 */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_RTS_THRH0;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->RTSThreshold );
+
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* Tx Rate Control 0 */
+#ifdef WARP
+		lp->ltvRecord.len       = 3;
+		lp->ltvRecord.typ       = CFG_TX_RATE_CNTL0;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
+		lp->ltvRecord.u.u16[1]  = CNV_INT_TO_LITTLE( lp->TxRateControl[1] );
+#else
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_TX_RATE_CNTL0;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
+#endif  // WARP
+
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* Own Beacon Interval */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = 0xFC31;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->ownBeaconInterval );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* Co-Existence Behavior */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = 0xFCC7;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->coexistence );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+#ifdef USE_WDS
+
+		/* RTS Threshold 1 */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_RTS_THRH1;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[0].rtsThreshold );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* RTS Threshold 2 */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_RTS_THRH2;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[1].rtsThreshold );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+
+		/* RTS Threshold 3 */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_RTS_THRH3;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[2].rtsThreshold );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+
+		/* RTS Threshold 4 */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_RTS_THRH4;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[3].rtsThreshold );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+
+		/* RTS Threshold 5 */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_RTS_THRH5;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[4].rtsThreshold );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* RTS Threshold 6 */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_RTS_THRH6;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[5].rtsThreshold );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+#if 0
+		/* TX Rate Control 1 */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_TX_RATE_CNTL1;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[0].txRateCntl );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* TX Rate Control 2 */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_TX_RATE_CNTL2;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[1].txRateCntl );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* TX Rate Control 3 */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_TX_RATE_CNTL3;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[2].txRateCntl );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* TX Rate Control 4 */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_TX_RATE_CNTL4;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[3].txRateCntl );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* TX Rate Control 5 */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_TX_RATE_CNTL5;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[4].txRateCntl );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* TX Rate Control 6 */
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_TX_RATE_CNTL6;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[5].txRateCntl );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+#endif
+
+		/* WDS addresses.  It's okay to blindly send these parameters, because
+		   the port needs to be enabled, before anything is done with it. */
+
+		/* WDS Address 1 */
+		lp->ltvRecord.len      = 4;
+		lp->ltvRecord.typ      = CFG_CNF_WDS_ADDR1;
+
+		memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[0].wdsAddress, ETH_ALEN );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* WDS Address 2 */
+		lp->ltvRecord.len      = 4;
+		lp->ltvRecord.typ      = CFG_CNF_WDS_ADDR2;
+
+		memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[1].wdsAddress, ETH_ALEN );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* WDS Address 3 */
+		lp->ltvRecord.len      = 4;
+		lp->ltvRecord.typ      = CFG_CNF_WDS_ADDR3;
+
+		memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[2].wdsAddress, ETH_ALEN );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* WDS Address 4 */
+		lp->ltvRecord.len      = 4;
+		lp->ltvRecord.typ      = CFG_CNF_WDS_ADDR4;
+
+		memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[3].wdsAddress, ETH_ALEN );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* WDS Address 5 */
+		lp->ltvRecord.len      = 4;
+		lp->ltvRecord.typ      = CFG_CNF_WDS_ADDR5;
+
+		memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[4].wdsAddress, ETH_ALEN );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+		/* WDS Address 6 */
+		lp->ltvRecord.len      = 4;
+		lp->ltvRecord.typ      = CFG_CNF_WDS_ADDR6;
+
+		memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[5].wdsAddress, ETH_ALEN );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+#endif  /* USE_WDS */
+#endif  /* (HCF_TYPE) & HCF_TYPE_AP */
+	}
+
+	/* Own MAC Address */
+	//DBG_TRACE( DbgInfo, "MAC Address                       : %s\n",
+	//           DbgHwAddr( lp->MACAddress ));
+
+	if ( WVLAN_VALID_MAC_ADDRESS( lp->MACAddress )) {
+		/* Make the MAC address valid by:
+				Clearing the multicast bit
+				Setting the local MAC address bit
+		*/
+		//lp->MACAddress[0] &= ~0x03;  //;?why is this commented out already in 720
+		//lp->MACAddress[0] |= 0x02;
+
+		lp->ltvRecord.len = 1 + ( ETH_ALEN / sizeof( hcf_16 ));
+		if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
+			//DBG_TRACE( DbgInfo, "CFG_NIC_MAC_ADDR\n" );
+			lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
+		} else {
+			//DBG_TRACE( DbgInfo, "CFG_CNF_OWN_MAC_ADDR\n" );
+			lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
+		}
+		/* MAC address is byte aligned, no endian conversion needed */
+		memcpy( &( lp->ltvRecord.u.u8[0] ), lp->MACAddress, ETH_ALEN );
+		hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+		//DBG_TRACE( DbgInfo, "CFG_XXX_MAC_ADDR result           : 0x%04x\n",
+		//           hcf_status );
+
+		/* Update the MAC address in the netdevice struct */
+		memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN ); //;?what is the purpose of this seemingly complex logic
+	}
+	/* Own SSID */
+	if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
+				 ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
+				 ( strcmp( lp->NetworkName, "any" ) != 0 )) {
+		//DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID                  : %s\n",
+		//           lp->NetworkName );
+		lp->ltvRecord.len       = 2 + (len / sizeof(hcf_16));
+		lp->ltvRecord.typ       = CFG_CNF_OWN_SSID;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
+
+		memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
+	} else {
+		//DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID                  : ANY\n" );
+		lp->ltvRecord.len       = 2;
+		lp->ltvRecord.typ       = CFG_CNF_OWN_SSID;
+		lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 0 );
+	}
+
+	hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+	//DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID result           : 0x%04x\n",
+	//           hcf_status );
+	/* enable/disable encryption */
+	lp->ltvRecord.len       = 2;
+	lp->ltvRecord.typ       = CFG_CNF_ENCRYPTION;
+	lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->EnableEncryption );
+	hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+	/* Set the Authentication Key Management Suite */
+	lp->ltvRecord.len       = 2;
+	lp->ltvRecord.typ       = CFG_SET_WPA_AUTH_KEY_MGMT_SUITE;
+	lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->AuthKeyMgmtSuite );
+	hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+	/* WEP Keys */
+	wl_set_wep_keys( lp );
+
+	/* Country Code */
+	/* countryInfo, ltvCountryInfo, CFG_CNF_COUNTRY_INFO */
+
+	DBG_LEAVE( DbgInfo );
+	return hcf_status;
+} // wl_put_ltv
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	init_module()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Load the kernel module.
+ *
+ *  PARAMETERS:
+ *
+ *      N/A
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      an errno value otherwise
+ *
+ ******************************************************************************/
+static int __init wl_module_init( void )
+{
+	int result;
+	/*------------------------------------------------------------------------*/
+
+	DBG_FUNC( "wl_module_init" );
+
+#if DBG
+	/* Convert "standard" PCMCIA parameter pc_debug to a reasonable DebugFlag value.
+	 * NOTE: The values all fall through to the lower values. */
+	DbgInfo->DebugFlag = 0;
+	DbgInfo->DebugFlag = DBG_TRACE_ON;		//;?get this mess resolved one day
+	if ( pc_debug ) switch( pc_debug ) {
+	  case 8:
+		DbgInfo->DebugFlag |= DBG_DS_ON;
+	  case 7:
+		DbgInfo->DebugFlag |= DBG_RX_ON | DBG_TX_ON;
+	  case 6:
+		DbgInfo->DebugFlag |= DBG_PARAM_ON;
+	  case 5:
+		DbgInfo->DebugFlag |= DBG_TRACE_ON;
+	  case 4:
+		DbgInfo->DebugFlag |= DBG_VERBOSE_ON;
+	  case 1:
+		DbgInfo->DebugFlag |= DBG_DEFAULTS;
+	  default:
+		break;
+	}
+#endif /* DBG */
+
+	DBG_ENTER( DbgInfo );
+	printk(KERN_INFO "%s\n", VERSION_INFO);
+    	printk(KERN_INFO "*** Modified for kernel 2.6 by Henk de Groot <pe1dnn@amsat.org>\n");
+        printk(KERN_INFO "*** Based on 7.18 version by Andrey Borzenkov <arvidjaar@mail.ru> $Revision: 39 $\n");
+
+
+// ;?#if (HCF_TYPE) & HCF_TYPE_AP
+// 	DBG_PRINT( "Access Point Mode (AP) Support: YES\n" );
+// #else
+// 	DBG_PRINT( "Access Point Mode (AP) Support: NO\n" );
+// #endif /* (HCF_TYPE) & HCF_TYPE_AP */
+
+	result = wl_adapter_init_module( );
+	DBG_LEAVE( DbgInfo );
+	return result;
+} // init_module
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	cleanup_module()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Unload the kernel module.
+ *
+ *  PARAMETERS:
+ *
+ *      N/A
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+static void __exit wl_module_exit( void )
+{
+	DBG_FUNC( "wl_module_exit" );
+	DBG_ENTER(DbgInfo);
+
+	wl_adapter_cleanup_module( );
+#if 0 //SCULL_USE_PROC /* don't waste space if unused */
+	remove_proc_entry( "wlags", NULL );		//;?why so a-symmetric compared to location of create_proc_read_entry
+#endif
+
+	DBG_LEAVE( DbgInfo );
+	return;
+} // cleanup_module
+/*============================================================================*/
+
+module_init(wl_module_init);
+module_exit(wl_module_exit);
+
+/*******************************************************************************
+ *	wl_isr()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      The Interrupt Service Routine for the driver.
+ *
+ *  PARAMETERS:
+ *
+ *      irq     -   the irq the interrupt came in on
+ *      dev_id  -   a buffer containing information about the request
+ *      regs    -
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+irqreturn_t wl_isr( int irq, void *dev_id, struct pt_regs *regs )
+{
+	int                 events;
+	struct net_device   *dev = (struct net_device *) dev_id;
+	struct wl_private   *lp = NULL;
+	/*------------------------------------------------------------------------*/
+	if (( dev == NULL ) || ( !netif_device_present( dev ))) {
+		return IRQ_NONE;
+	}
+
+	/* Set the wl_private pointer (lp), now that we know that dev is non-null */
+	lp = wl_priv(dev);
+
+#ifdef USE_RTS
+	if ( lp->useRTS == 1 ) {
+		DBG_PRINT( "EXITING ISR, IN RTS MODE...\n" );
+		return;
+		}
+#endif  /* USE_RTS */
+
+	/* If we have interrupts pending, then put them on a system task
+	   queue. Otherwise turn interrupts back on */
+	events = hcf_action( &lp->hcfCtx, HCF_ACT_INT_OFF );
+
+	if ( events == HCF_INT_PENDING ) {
+		/* Schedule the ISR handler as a bottom-half task in the
+		   tq_immediate queue */
+		tasklet_schedule(&lp->task);
+	} else {
+		//DBG_PRINT( "NOT OUR INTERRUPT\n" );
+		hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
+	}
+
+	return IRQ_RETVAL(events == HCF_INT_PENDING);
+} // wl_isr
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wl_isr_handler()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      The ISR handler, scheduled to run in a deferred context by the ISR. This
+ *      is where the ISR's work actually gets done.
+ *
+ *  PARAMETERS:
+ *
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+#define WVLAN_MAX_INT_SERVICES  50
+
+void wl_isr_handler( unsigned long p )
+{
+	struct net_device       *dev;
+	unsigned long           flags;
+	bool_t                  stop = TRUE;
+	int                     count;
+	int                     result;
+        struct wl_private       *lp = (struct wl_private *)p;
+	/*------------------------------------------------------------------------*/
+
+	if ( lp == NULL ) {
+		DBG_PRINT( "wl_isr_handler  lp adapter pointer is NULL!!!\n" );
+	} else {
+		wl_lock( lp, &flags );
+
+		dev = (struct net_device *)lp->dev;
+		if ( dev != NULL && netif_device_present( dev ) ) stop = FALSE;
+		for( count = 0; stop == FALSE && count < WVLAN_MAX_INT_SERVICES; count++ ) {
+			stop = TRUE;
+			result = hcf_service_nic( &lp->hcfCtx,
+									  (wci_bufp)lp->lookAheadBuf,
+									  sizeof( lp->lookAheadBuf ));
+			if ( result == HCF_ERR_MIC ) {
+				wl_wext_event_mic_failed( dev ); 	/* Send an event that MIC failed */
+				//;?this seems wrong if HCF_ERR_MIC coincides with another event, stop gets FALSE
+				//so why not do it always ;?
+			}
+
+#ifndef USE_MBOX_SYNC
+			if ( lp->hcfCtx.IFB_MBInfoLen != 0 ) {	/* anything in the mailbox */
+				wl_mbx( lp );
+				stop = FALSE;
+			}
+#endif
+			/* Check for a Link status event */
+			if ( ( lp->hcfCtx.IFB_LinkStat & CFG_LINK_STAT_FW ) != 0 ) {
+				wl_process_link_status( lp );
+				stop = FALSE;
+			}
+			/* Check for probe response events */
+			if ( lp->ProbeResp.infoType != 0 &&
+				lp->ProbeResp.infoType != 0xFFFF ) {
+				wl_process_probe_response( lp );
+				memset( &lp->ProbeResp, 0, sizeof( lp->ProbeResp ));
+				lp->ProbeResp.infoType = 0xFFFF;
+				stop = FALSE;
+			}
+			/* Check for updated record events */
+			if ( lp->updatedRecord.len != 0xFFFF ) {
+				wl_process_updated_record( lp );
+				lp->updatedRecord.len = 0xFFFF;
+				stop = FALSE;
+			}
+			/* Check for association status events */
+			if ( lp->assoc_stat.len != 0xFFFF ) {
+				wl_process_assoc_status( lp );
+				lp->assoc_stat.len = 0xFFFF;
+				stop = FALSE;
+			}
+			/* Check for security status events */
+			if ( lp->sec_stat.len != 0xFFFF ) {
+				wl_process_security_status( lp );
+				lp->sec_stat.len = 0xFFFF;
+				stop = FALSE;
+			}
+
+#ifdef ENABLE_DMA
+			if ( lp->use_dma ) {
+				/* Check for DMA Rx packets */
+				if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_RDMAD ) {
+					wl_rx_dma( dev );
+					stop = FALSE;
+				}
+				/* Return Tx DMA descriptors to host */
+				if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_TDMAD ) {
+					wl_pci_dma_hcf_reclaim_tx( lp );
+					stop = FALSE;
+				}
+			}
+			else
+#endif // ENABLE_DMA
+			{
+				/* Check for Rx packets */
+				if ( lp->hcfCtx.IFB_RxLen != 0 ) {
+					wl_rx( dev );
+					stop = FALSE;
+				}
+				/* Make sure that queued frames get sent */
+				if ( wl_send( lp )) {
+					stop = FALSE;
+				}
+			}
+		}
+		/* We're done, so turn interrupts which were turned off in wl_isr, back on */
+		hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
+		wl_unlock( lp, &flags );
+	}
+	return;
+} // wl_isr_handler
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wl_remove()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Notify the adapter that it has been removed. Since the adapter is gone,
+ *  we should no longer try to talk to it.
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the device's net_device structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_remove( struct net_device *dev )
+{
+	struct wl_private   *lp = wl_priv(dev);
+	unsigned long   flags;
+	/*------------------------------------------------------------------------*/
+	DBG_FUNC( "wl_remove" );
+	DBG_ENTER( DbgInfo );
+
+	DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
+
+	wl_lock( lp, &flags );
+
+	/* stop handling interrupts */
+	wl_act_int_off( lp );
+        lp->is_handling_int = WL_NOT_HANDLING_INT;
+
+	/*
+         * Disable the ports: just change state: since the
+         * card is gone it is useless to talk to it and at
+         * disconnect all state information is lost anyway.
+         */
+	/* Reset portState */
+	lp->portState = WVLAN_PORT_STATE_DISABLED;
+
+#if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
+#ifdef USE_WDS
+	//wl_disable_wds_ports( lp );
+#endif // USE_WDS
+#endif  /* (HCF_TYPE) & HCF_TYPE_AP */
+
+	/* Mark the device as unregistered */
+	lp->is_registered = FALSE;
+
+	/* Deregister the WDS ports as well */
+	WL_WDS_NETDEV_DEREGISTER( lp );
+#ifdef USE_RTS
+	if ( lp->useRTS == 1 ) {
+		wl_unlock( lp, &flags );
+
+		DBG_LEAVE( DbgInfo );
+		return;
+	}
+#endif  /* USE_RTS */
+
+	/* Inform the HCF that the card has been removed */
+	hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
+
+	wl_unlock( lp, &flags );
+
+	DBG_LEAVE( DbgInfo );
+	return;
+} // wl_remove
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wl_suspend()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Power-down and halt the adapter.
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the device's net_device structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_suspend( struct net_device *dev )
+{
+	struct wl_private  *lp = wl_priv(dev);
+	unsigned long   flags;
+	/*------------------------------------------------------------------------*/
+	DBG_FUNC( "wl_suspend" );
+	DBG_ENTER( DbgInfo );
+
+	DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
+
+	/* The adapter is suspended:
+			Stop the adapter
+			Power down
+	*/
+	wl_lock( lp, &flags );
+
+	/* Disable interrupt handling */
+	wl_act_int_off( lp );
+
+	/* Disconnect */
+	wl_disconnect( lp );
+
+	/* Disable */
+	wl_disable( lp );
+
+        /* Disconnect from the adapter */
+	hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
+
+	/* Reset portState to be sure (should have been done by wl_disable */
+	lp->portState = WVLAN_PORT_STATE_DISABLED;
+
+	wl_unlock( lp, &flags );
+
+	DBG_LEAVE( DbgInfo );
+	return;
+} // wl_suspend
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wl_resume()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Resume a previously suspended adapter.
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the device's net_device structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_resume(struct net_device *dev)
+{
+	struct wl_private  *lp = wl_priv(dev);
+	unsigned long   flags;
+	/*------------------------------------------------------------------------*/
+	DBG_FUNC( "wl_resume" );
+	DBG_ENTER( DbgInfo );
+
+	DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
+
+	wl_lock( lp, &flags );
+
+        /* Connect to the adapter */
+	hcf_connect( &lp->hcfCtx, dev->base_addr );
+
+	/* Reset portState */
+	lp->portState = WVLAN_PORT_STATE_DISABLED;
+
+	/* Power might have been off, assume the card lost the firmware*/
+	lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
+
+	/* Reload the firmware and restart */
+	wl_reset( dev );
+
+	/* Resume interrupt handling */
+	wl_act_int_on( lp );
+
+	wl_unlock( lp, &flags );
+
+	DBG_LEAVE( DbgInfo );
+	return;
+} // wl_resume
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wl_release()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function perfroms a check on the device and calls wl_remove() if
+ *  necessary. This function can be used for all bus types, but exists mostly
+ *  for the benefit of the Card Services driver, as there are times when
+ *  wl_remove() does not get called.
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the device's net_device structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_release( struct net_device *dev )
+{
+	struct wl_private  *lp = wl_priv(dev);
+	/*------------------------------------------------------------------------*/
+	DBG_FUNC( "wl_release" );
+	DBG_ENTER( DbgInfo );
+
+	DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
+	/* If wl_remove() hasn't been called (i.e. when Card Services is shut
+	   down with the card in the slot), then call it */
+	if ( lp->is_registered == TRUE ) {
+		DBG_TRACE( DbgInfo, "Calling unregister_netdev(), as it wasn't called yet\n" );
+		wl_remove( dev );
+
+		lp->is_registered = FALSE;
+	}
+
+	DBG_LEAVE( DbgInfo );
+	return;
+} // wl_release
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wl_get_irq_mask()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Accessor function to retrieve the irq_mask module parameter
+ *
+ *  PARAMETERS:
+ *
+ *      N/A
+ *
+ *  RETURNS:
+ *
+ *      The irq_mask module parameter
+ *
+ ******************************************************************************/
+p_u16 wl_get_irq_mask( void )
+{
+	return irq_mask;
+} // wl_get_irq_mask
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wl_get_irq_list()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Accessor function to retrieve the irq_list module parameter
+ *
+ *  PARAMETERS:
+ *
+ *      N/A
+ *
+ *  RETURNS:
+ *
+ *      The irq_list module parameter
+ *
+ ******************************************************************************/
+p_s8 * wl_get_irq_list( void )
+{
+	return irq_list;
+} // wl_get_irq_list
+/*============================================================================*/
+
+
+
+/*******************************************************************************
+ *	wl_enable()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Used to enable MAC ports
+ *
+ *  PARAMETERS:
+ *
+ *      lp      - pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+int wl_enable( struct wl_private *lp )
+{
+	int hcf_status = HCF_SUCCESS;
+	/*------------------------------------------------------------------------*/
+	DBG_FUNC( "wl_enable" );
+	DBG_ENTER( DbgInfo );
+
+	if ( lp->portState == WVLAN_PORT_STATE_ENABLED ) {
+		DBG_TRACE( DbgInfo, "No action: Card already enabled\n" );
+	} else if ( lp->portState == WVLAN_PORT_STATE_CONNECTED ) {
+		//;?suspicuous logic, how can you be connected without being enabled so this is probably dead code
+		DBG_TRACE( DbgInfo, "No action: Card already connected\n" );
+	} else {
+		hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_ENABLE );
+		if ( hcf_status == HCF_SUCCESS ) {
+			/* Set the status of the NIC to enabled */
+			lp->portState = WVLAN_PORT_STATE_ENABLED;   //;?bad mnemonic, NIC iso PORT
+#ifdef ENABLE_DMA
+			if ( lp->use_dma ) {
+				wl_pci_dma_hcf_supply( lp );  //;?always succes?
+			}
+#endif
+		}
+	}
+	if ( hcf_status != HCF_SUCCESS ) {  //;?make this an assert
+		DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
+	}
+	DBG_LEAVE( DbgInfo );
+	return hcf_status;
+} // wl_enable
+/*============================================================================*/
+
+
+#ifdef USE_WDS
+/*******************************************************************************
+ *	wl_enable_wds_ports()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Used to enable the WDS MAC ports 1-6
+ *
+ *  PARAMETERS:
+ *
+ *      lp      - pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_enable_wds_ports( struct wl_private * lp )
+{
+
+	DBG_FUNC( "wl_enable_wds_ports" );
+	DBG_ENTER( DbgInfo );
+	if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ){
+		DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
+	}
+	DBG_LEAVE( DbgInfo );
+	return;
+} // wl_enable_wds_ports
+#endif  /* USE_WDS */
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wl_connect()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Used to connect a MAC port
+ *
+ *  PARAMETERS:
+ *
+ *      lp      - pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+int wl_connect( struct wl_private *lp )
+{
+	int hcf_status;
+	/*------------------------------------------------------------------------*/
+
+	DBG_FUNC( "wl_connect" );
+	DBG_ENTER( DbgInfo );
+
+	if ( lp->portState != WVLAN_PORT_STATE_ENABLED ) {
+		DBG_TRACE( DbgInfo, "No action: Not in enabled state\n" );
+		DBG_LEAVE( DbgInfo );
+		return HCF_SUCCESS;
+	}
+	hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_CONNECT );
+	if ( hcf_status == HCF_SUCCESS ) {
+		lp->portState = WVLAN_PORT_STATE_CONNECTED;
+	}
+	DBG_LEAVE( DbgInfo );
+	return hcf_status;
+} // wl_connect
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wl_disconnect()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Used to disconnect a MAC port
+ *
+ *  PARAMETERS:
+ *
+ *      lp      - pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+int wl_disconnect( struct wl_private *lp )
+{
+	int hcf_status;
+	/*------------------------------------------------------------------------*/
+
+	DBG_FUNC( "wl_disconnect" );
+	DBG_ENTER( DbgInfo );
+
+	if ( lp->portState != WVLAN_PORT_STATE_CONNECTED ) {
+		DBG_TRACE( DbgInfo, "No action: Not in connected state\n" );
+		DBG_LEAVE( DbgInfo );
+		return HCF_SUCCESS;
+	}
+	hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISCONNECT );
+	if ( hcf_status == HCF_SUCCESS ) {
+		lp->portState = WVLAN_PORT_STATE_ENABLED;
+	}
+	DBG_LEAVE( DbgInfo );
+	return hcf_status;
+} // wl_disconnect
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wl_disable()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Used to disable MAC ports
+ *
+ *  PARAMETERS:
+ *
+ *      lp      - pointer to the device's private adapter structure
+ *      port    - the MAC port to disable
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+int wl_disable( struct wl_private *lp )
+{
+	int hcf_status = HCF_SUCCESS;
+	/*------------------------------------------------------------------------*/
+	DBG_FUNC( "wl_disable" );
+	DBG_ENTER( DbgInfo );
+
+	if ( lp->portState == WVLAN_PORT_STATE_DISABLED ) {
+		DBG_TRACE( DbgInfo, "No action: Port state is disabled\n" );
+	} else {
+		hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISABLE );
+		if ( hcf_status == HCF_SUCCESS ) {
+			/* Set the status of the port to disabled */ //;?bad mnemonic use NIC iso PORT
+			lp->portState = WVLAN_PORT_STATE_DISABLED;
+
+#ifdef ENABLE_DMA
+			if ( lp->use_dma ) {
+				wl_pci_dma_hcf_reclaim( lp );
+			}
+#endif
+		}
+	}
+	if ( hcf_status != HCF_SUCCESS ) {
+		DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
+	}
+	DBG_LEAVE( DbgInfo );
+	return hcf_status;
+} // wl_disable
+/*============================================================================*/
+
+
+#ifdef USE_WDS
+/*******************************************************************************
+ *	wl_disable_wds_ports()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Used to disable the WDS MAC ports 1-6
+ *
+ *  PARAMETERS:
+ *
+ *      lp      - pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_disable_wds_ports( struct wl_private * lp )
+{
+
+	DBG_FUNC( "wl_disable_wds_ports" );
+	DBG_ENTER( DbgInfo );
+
+	if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ){
+		DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
+	}
+// 	if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
+// 		wl_disable( lp, HCF_PORT_1 );
+// 		wl_disable( lp, HCF_PORT_2 );
+// 		wl_disable( lp, HCF_PORT_3 );
+// 		wl_disable( lp, HCF_PORT_4 );
+// 		wl_disable( lp, HCF_PORT_5 );
+// 		wl_disable( lp, HCF_PORT_6 );
+// 	}
+	DBG_LEAVE( DbgInfo );
+	return;
+} // wl_disable_wds_ports
+#endif // USE_WDS
+/*============================================================================*/
+
+
+#ifndef USE_MBOX_SYNC
+/*******************************************************************************
+ *	wl_mbx()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *      This function is used to read and process a mailbox message.
+ *
+ *
+ *  PARAMETERS:
+ *
+ *      lp      - pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      an HCF status code
+ *
+ ******************************************************************************/
+int wl_mbx( struct wl_private *lp )
+{
+	int hcf_status = HCF_SUCCESS;
+	/*------------------------------------------------------------------------*/
+	DBG_FUNC( "wl_mbx" );
+	DBG_ENTER( DbgInfo );
+	DBG_TRACE( DbgInfo, "Mailbox Info: IFB_MBInfoLen: %d\n",
+			   lp->hcfCtx.IFB_MBInfoLen );
+
+	memset( &( lp->ltvRecord ), 0, sizeof( ltv_t ));
+
+	lp->ltvRecord.len = MB_SIZE;
+	lp->ltvRecord.typ = CFG_MB_INFO;
+	hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
+
+	if ( hcf_status != HCF_SUCCESS ) {
+		DBG_ERROR( DbgInfo, "hcf_get_info returned 0x%x\n", hcf_status );
+
+		DBG_LEAVE( DbgInfo );
+		return hcf_status;
+	}
+
+	if ( lp->ltvRecord.typ == CFG_MB_INFO ) {
+		DBG_LEAVE( DbgInfo );
+		return hcf_status;
+	}
+	/* Endian translate the mailbox data, then process the message */
+	wl_endian_translate_mailbox( &( lp->ltvRecord ));
+	wl_process_mailbox( lp );
+	DBG_LEAVE( DbgInfo );
+	return hcf_status;
+} // wl_mbx
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wl_endian_translate_mailbox()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function will perform the tedious task of endian translating all
+ *  fields withtin a mailbox message which need translating.
+ *
+ *  PARAMETERS:
+ *
+ *      ltv - pointer to the LTV to endian translate
+ *
+ *  RETURNS:
+ *
+ *      none
+ *
+ ******************************************************************************/
+void wl_endian_translate_mailbox( ltv_t *ltv )
+{
+
+	DBG_FUNC( "wl_endian_translate_mailbox" );
+	DBG_ENTER( DbgInfo );
+	switch( ltv->typ ) {
+	  case CFG_TALLIES:
+		break;
+
+	  case CFG_SCAN:
+		{
+			int num_aps;
+			SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)&ltv->u.u8[0];
+
+			num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
+								 ( sizeof( SCAN_RS_STRCT )));
+
+			while( num_aps >= 1 ) {
+				num_aps--;
+
+				aps[num_aps].channel_id =
+					CNV_LITTLE_TO_INT( aps[num_aps].channel_id );
+
+				aps[num_aps].noise_level =
+					CNV_LITTLE_TO_INT( aps[num_aps].noise_level );
+
+				aps[num_aps].signal_level =
+					CNV_LITTLE_TO_INT( aps[num_aps].signal_level );
+
+				aps[num_aps].beacon_interval_time =
+					CNV_LITTLE_TO_INT( aps[num_aps].beacon_interval_time );
+
+				aps[num_aps].capability =
+					CNV_LITTLE_TO_INT( aps[num_aps].capability );
+
+				aps[num_aps].ssid_len =
+					CNV_LITTLE_TO_INT( aps[num_aps].ssid_len );
+
+				aps[num_aps].ssid_val[aps[num_aps].ssid_len] = 0;
+			}
+		}
+		break;
+
+	  case CFG_ACS_SCAN:
+		{
+			PROBE_RESP *probe_resp = (PROBE_RESP *)ltv;
+
+			probe_resp->frameControl   = CNV_LITTLE_TO_INT( probe_resp->frameControl );
+			probe_resp->durID          = CNV_LITTLE_TO_INT( probe_resp->durID );
+			probe_resp->sequence       = CNV_LITTLE_TO_INT( probe_resp->sequence );
+			probe_resp->dataLength     = CNV_LITTLE_TO_INT( probe_resp->dataLength );
+#ifndef WARP
+			probe_resp->lenType        = CNV_LITTLE_TO_INT( probe_resp->lenType );
+#endif // WARP
+			probe_resp->beaconInterval = CNV_LITTLE_TO_INT( probe_resp->beaconInterval );
+			probe_resp->capability     = CNV_LITTLE_TO_INT( probe_resp->capability );
+			probe_resp->flags          = CNV_LITTLE_TO_INT( probe_resp->flags );
+		}
+		break;
+
+	  case CFG_LINK_STAT:
+#define ls ((LINK_STATUS_STRCT *)ltv)
+			ls->linkStatus = CNV_LITTLE_TO_INT( ls->linkStatus );
+		break;
+#undef ls
+
+	  case CFG_ASSOC_STAT:
+		{
+			ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
+
+			as->assocStatus = CNV_LITTLE_TO_INT( as->assocStatus );
+		}
+		break;
+
+	  case CFG_SECURITY_STAT:
+		{
+			SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
+
+			ss->securityStatus  = CNV_LITTLE_TO_INT( ss->securityStatus );
+			ss->reason          = CNV_LITTLE_TO_INT( ss->reason );
+		}
+		break;
+
+	  case CFG_WMP:
+		break;
+
+	  case CFG_NULL:
+		break;
+
+	default:
+		break;
+	}
+
+	DBG_LEAVE( DbgInfo );
+	return;
+} // wl_endian_translate_mailbox
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_process_mailbox()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function will process the mailbox data.
+ *
+ *  PARAMETERS:
+ *
+ *      ltv - pointer to the LTV to be processed.
+ *
+ *  RETURNS:
+ *
+ *      none
+ *
+ ******************************************************************************/
+void wl_process_mailbox( struct wl_private *lp )
+{
+	ltv_t   *ltv;
+	hcf_16  ltv_val = 0xFFFF;
+	/*------------------------------------------------------------------------*/
+	DBG_FUNC( "wl_process_mailbox" );
+	DBG_ENTER( DbgInfo );
+	ltv = &( lp->ltvRecord );
+
+	switch( ltv->typ ) {
+
+	  case CFG_TALLIES:
+		DBG_TRACE( DbgInfo, "CFG_TALLIES\n" );
+		break;
+	  case CFG_SCAN:
+		DBG_TRACE( DbgInfo, "CFG_SCAN\n" );
+
+		{
+			int num_aps;
+			SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)&ltv->u.u8[0];
+
+			num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
+								 ( sizeof( SCAN_RS_STRCT )));
+
+			lp->scan_results.num_aps = num_aps;
+
+			DBG_TRACE( DbgInfo, "Number of APs: %d\n", num_aps );
+
+			while( num_aps >= 1 ) {
+				num_aps--;
+
+				DBG_TRACE( DbgInfo, "AP              : %d\n", num_aps );
+				DBG_TRACE( DbgInfo, "=========================\n" );
+				DBG_TRACE( DbgInfo, "Channel ID      : 0x%04x\n",
+						   aps[num_aps].channel_id );
+				DBG_TRACE( DbgInfo, "Noise Level     : 0x%04x\n",
+						   aps[num_aps].noise_level );
+				DBG_TRACE( DbgInfo, "Signal Level    : 0x%04x\n",
+						   aps[num_aps].signal_level );
+				DBG_TRACE( DbgInfo, "Beacon Interval : 0x%04x\n",
+						   aps[num_aps].beacon_interval_time );
+				DBG_TRACE( DbgInfo, "Capability      : 0x%04x\n",
+						   aps[num_aps].capability );
+				DBG_TRACE( DbgInfo, "SSID Length     : 0x%04x\n",
+						   aps[num_aps].ssid_len );
+				DBG_TRACE( DbgInfo, "BSSID           : %s\n",
+						   DbgHwAddr( aps[num_aps].bssid ));
+
+				if ( aps[num_aps].ssid_len != 0 ) {
+					DBG_TRACE( DbgInfo, "SSID            : %s.\n",
+							   aps[num_aps].ssid_val );
+				} else {
+					DBG_TRACE( DbgInfo, "SSID            : %s.\n", "ANY" );
+				}
+
+				DBG_TRACE( DbgInfo, "\n" );
+
+				/* Copy the info to the ScanResult structure in the private
+				   adapter struct */
+				memcpy( &( lp->scan_results.APTable[num_aps]), &( aps[num_aps] ),
+						sizeof( SCAN_RS_STRCT ));
+			}
+
+			/* Set scan result to true so that any scan requests will
+			   complete */
+			lp->scan_results.scan_complete = TRUE;
+		}
+
+		break;
+	  case CFG_ACS_SCAN:
+		DBG_TRACE( DbgInfo, "CFG_ACS_SCAN\n" );
+
+		{
+			PROBE_RESP  *probe_rsp = (PROBE_RESP *)ltv;
+			hcf_8       *wpa_ie = NULL;
+			hcf_16      wpa_ie_len = 0;
+
+			DBG_TRACE( DbgInfo, "(%s) =========================\n",
+					   lp->dev->name );
+
+			DBG_TRACE( DbgInfo, "(%s) length      : 0x%04x.\n",
+					   lp->dev->name, probe_rsp->length );
+
+			if ( probe_rsp->length > 1 ) {
+				DBG_TRACE( DbgInfo, "(%s) infoType    : 0x%04x.\n",
+						   lp->dev->name, probe_rsp->infoType );
+
+				DBG_TRACE( DbgInfo, "(%s) signal      : 0x%02x.\n",
+						   lp->dev->name, probe_rsp->signal );
+
+				DBG_TRACE( DbgInfo, "(%s) silence     : 0x%02x.\n",
+						   lp->dev->name, probe_rsp->silence );
+
+				DBG_TRACE( DbgInfo, "(%s) rxFlow      : 0x%02x.\n",
+						   lp->dev->name, probe_rsp->rxFlow );
+
+				DBG_TRACE( DbgInfo, "(%s) rate        : 0x%02x.\n",
+						   lp->dev->name, probe_rsp->rate );
+
+				DBG_TRACE( DbgInfo, "(%s) frame cntl  : 0x%04x.\n",
+						   lp->dev->name, probe_rsp->frameControl );
+
+				DBG_TRACE( DbgInfo, "(%s) durID       : 0x%04x.\n",
+						   lp->dev->name, probe_rsp->durID );
+
+				DBG_TRACE( DbgInfo, "(%s) address1    : %s\n",
+						   lp->dev->name, DbgHwAddr( probe_rsp->address1 ));
+
+				DBG_TRACE( DbgInfo, "(%s) address2    : %s\n",
+						   lp->dev->name, DbgHwAddr( probe_rsp->address2 ));
+
+				DBG_TRACE( DbgInfo, "(%s) BSSID       : %s\n",
+						   lp->dev->name, DbgHwAddr( probe_rsp->BSSID ));
+
+				DBG_TRACE( DbgInfo, "(%s) sequence    : 0x%04x.\n",
+						   lp->dev->name, probe_rsp->sequence );
+
+				DBG_TRACE( DbgInfo, "(%s) address4    : %s\n",
+						   lp->dev->name, DbgHwAddr( probe_rsp->address4 ));
+
+				DBG_TRACE( DbgInfo, "(%s) datalength  : 0x%04x.\n",
+						   lp->dev->name, probe_rsp->dataLength );
+
+				DBG_TRACE( DbgInfo, "(%s) DA          : %s\n",
+						   lp->dev->name, DbgHwAddr( probe_rsp->DA ));
+
+				DBG_TRACE( DbgInfo, "(%s) SA          : %s\n",
+						   lp->dev->name, DbgHwAddr( probe_rsp->SA ));
+
+				//DBG_TRACE( DbgInfo, "(%s) lenType     : 0x%04x.\n",
+				//           lp->dev->name, probe_rsp->lenType );
+
+				DBG_TRACE( DbgInfo, "(%s) timeStamp   : %s\n",
+						   lp->dev->name, DbgHwAddr( probe_rsp->timeStamp ));
+
+				DBG_TRACE( DbgInfo, "(%s) beaconInt   : 0x%04x.\n",
+						   lp->dev->name, probe_rsp->beaconInterval );
+
+				DBG_TRACE( DbgInfo, "(%s) capability  : 0x%04x.\n",
+						   lp->dev->name, probe_rsp->capability );
+
+				DBG_TRACE( DbgInfo, "(%s) SSID len    : 0x%04x.\n",
+						   lp->dev->name, probe_rsp->rawData[1] );
+
+				if ( probe_rsp->rawData[1] > 0 ) {
+					char ssid[HCF_MAX_NAME_LEN];
+
+					memset( ssid, 0, sizeof( ssid ));
+					strncpy( ssid, &probe_rsp->rawData[2],
+							 probe_rsp->rawData[1] );
+
+					DBG_TRACE( DbgInfo, "(%s) SSID        : %s\n",
+							   lp->dev->name, ssid );
+				}
+
+				/* Parse out the WPA-IE, if one exists */
+				wpa_ie = wl_parse_wpa_ie( probe_rsp, &wpa_ie_len );
+				if ( wpa_ie != NULL ) {
+					DBG_TRACE( DbgInfo, "(%s) WPA-IE      : %s\n",
+					lp->dev->name, wl_print_wpa_ie( wpa_ie, wpa_ie_len ));
+				}
+
+				DBG_TRACE( DbgInfo, "(%s) flags       : 0x%04x.\n",
+						   lp->dev->name, probe_rsp->flags );
+			}
+
+			DBG_TRACE( DbgInfo, "\n\n" );
+			/* If probe response length is 1, then the scan is complete */
+			if ( probe_rsp->length == 1 ) {
+				DBG_TRACE( DbgInfo, "SCAN COMPLETE\n" );
+				lp->probe_results.num_aps = lp->probe_num_aps;
+				lp->probe_results.scan_complete = TRUE;
+
+				/* Reset the counter for the next scan request */
+				lp->probe_num_aps = 0;
+
+				/* Send a wireless extensions event that the scan completed */
+				wl_wext_event_scan_complete( lp->dev );
+			} else {
+				/* Only copy to the table if the entry is unique; APs sometimes
+				   respond more than once to a probe */
+				if ( lp->probe_num_aps == 0 ) {
+					/* Copy the info to the ScanResult structure in the private
+					adapter struct */
+					memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
+							probe_rsp, sizeof( PROBE_RESP ));
+
+					/* Increment the number of APs detected */
+					lp->probe_num_aps++;
+				} else {
+					int count;
+					int unique = 1;
+
+					for( count = 0; count < lp->probe_num_aps; count++ ) {
+						if ( memcmp( &( probe_rsp->BSSID ),
+							lp->probe_results.ProbeTable[count].BSSID,
+							ETH_ALEN ) == 0 ) {
+							unique = 0;
+						}
+					}
+
+					if ( unique ) {
+						/* Copy the info to the ScanResult structure in the
+						private adapter struct. Only copy if there's room in the
+						table */
+						if ( lp->probe_num_aps < MAX_NAPS )
+						{
+							memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
+									probe_rsp, sizeof( PROBE_RESP ));
+						}
+						else
+						{
+							DBG_WARNING( DbgInfo, "Num of scan results exceeds storage, truncating\n" );
+						}
+
+						/* Increment the number of APs detected. Note I do this
+						   here even when I don't copy the probe response to the
+						   buffer in order to detect the overflow condition */
+						lp->probe_num_aps++;
+					}
+				}
+			}
+		}
+
+		break;
+
+	  case CFG_LINK_STAT:
+#define ls ((LINK_STATUS_STRCT *)ltv)
+		DBG_TRACE( DbgInfo, "CFG_LINK_STAT\n" );
+
+		switch( ls->linkStatus ) {
+		  case 1:
+			DBG_TRACE( DbgInfo, "Link Status : Connected\n" );
+			wl_wext_event_ap( lp->dev );
+			break;
+
+		  case 2:
+			DBG_TRACE( DbgInfo, "Link Status : Disconnected\n"  );
+			break;
+
+		  case 3:
+			DBG_TRACE( DbgInfo, "Link Status : Access Point Change\n" );
+			break;
+
+		  case 4:
+			DBG_TRACE( DbgInfo, "Link Status : Access Point Out of Range\n" );
+			break;
+
+		  case 5:
+			DBG_TRACE( DbgInfo, "Link Status : Access Point In Range\n" );
+			break;
+
+		default:
+			DBG_TRACE( DbgInfo, "Link Status : UNKNOWN (0x%04x)\n",
+					   ls->linkStatus );
+			break;
+		}
+
+		break;
+#undef ls
+
+	  case CFG_ASSOC_STAT:
+		DBG_TRACE( DbgInfo, "CFG_ASSOC_STAT\n" );
+
+		{
+			ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
+
+			switch( as->assocStatus ) {
+			  case 1:
+				DBG_TRACE( DbgInfo, "Association Status : STA Associated\n" );
+				break;
+
+			  case 2:
+				DBG_TRACE( DbgInfo, "Association Status : STA Reassociated\n" );
+				break;
+
+			  case 3:
+				DBG_TRACE( DbgInfo, "Association Status : STA Disassociated\n" );
+				break;
+
+			default:
+				DBG_TRACE( DbgInfo, "Association Status : UNKNOWN (0x%04x)\n",
+						   as->assocStatus );
+				break;
+			}
+
+			DBG_TRACE( DbgInfo, "STA Address        : %s\n",
+					   DbgHwAddr( as->staAddr ));
+
+			if (( as->assocStatus == 2 )  && ( as->len == 8 )) {
+				DBG_TRACE( DbgInfo, "Old AP Address     : %s\n",
+						   DbgHwAddr( as->oldApAddr ));
+			}
+		}
+
+		break;
+
+	  case CFG_SECURITY_STAT:
+		DBG_TRACE( DbgInfo, "CFG_SECURITY_STAT\n" );
+
+		{
+			SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
+
+			switch( ss->securityStatus ) {
+			  case 1:
+				DBG_TRACE( DbgInfo, "Security Status : Dissassociate [AP]\n" );
+				break;
+
+			  case 2:
+				DBG_TRACE( DbgInfo, "Security Status : Deauthenticate [AP]\n" );
+				break;
+
+			  case 3:
+				DBG_TRACE( DbgInfo, "Security Status : Authenticate Fail [STA] or [AP]\n" );
+				break;
+
+			  case 4:
+				DBG_TRACE( DbgInfo, "Security Status : MIC Fail\n" );
+				break;
+
+			  case 5:
+				DBG_TRACE( DbgInfo, "Security Status : Associate Fail\n" );
+				break;
+
+			default:
+				DBG_TRACE( DbgInfo, "Security Status : UNKNOWN %d\n",
+						   ss->securityStatus );
+				break;
+			}
+
+			DBG_TRACE( DbgInfo, "STA Address     : %s\n", DbgHwAddr( ss->staAddr ));
+
+			DBG_TRACE( DbgInfo, "Reason          : 0x%04x \n", ss->reason );
+		}
+
+		break;
+
+	  case CFG_WMP:
+		DBG_TRACE( DbgInfo, "CFG_WMP, size is %d bytes\n", ltv->len );
+		{
+			WMP_RSP_STRCT *wmp_rsp = (WMP_RSP_STRCT *)ltv;
+
+			DBG_TRACE( DbgInfo, "CFG_WMP, pdu type is 0x%x\n",
+					   wmp_rsp->wmpRsp.wmpHdr.type );
+
+			switch( wmp_rsp->wmpRsp.wmpHdr.type ) {
+			  case WVLAN_WMP_PDU_TYPE_LT_RSP:
+				{
+#if DBG
+					LINKTEST_RSP_STRCT  *lt_rsp = (LINKTEST_RSP_STRCT *)ltv;
+#endif // DBG
+					DBG_TRACE( DbgInfo, "LINK TEST RESULT\n" );
+					DBG_TRACE( DbgInfo, "================\n" );
+					DBG_TRACE( DbgInfo, "Length        : %d.\n",     lt_rsp->len );
+
+					DBG_TRACE( DbgInfo, "Name          : %s.\n",     lt_rsp->ltRsp.ltRsp.name );
+					DBG_TRACE( DbgInfo, "Signal Level  : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.signal );
+					DBG_TRACE( DbgInfo, "Noise  Level  : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.noise );
+					DBG_TRACE( DbgInfo, "Receive Flow  : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.rxFlow );
+					DBG_TRACE( DbgInfo, "Data Rate     : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRate );
+					DBG_TRACE( DbgInfo, "Protocol      : 0x%04x.\n", lt_rsp->ltRsp.ltRsp.protocol );
+					DBG_TRACE( DbgInfo, "Station       : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.station );
+					DBG_TRACE( DbgInfo, "Data Rate Cap : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRateCap );
+
+					DBG_TRACE( DbgInfo, "Power Mgmt    : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
+								lt_rsp->ltRsp.ltRsp.powerMgmt[0],
+								lt_rsp->ltRsp.ltRsp.powerMgmt[1],
+								lt_rsp->ltRsp.ltRsp.powerMgmt[2],
+								lt_rsp->ltRsp.ltRsp.powerMgmt[3] );
+
+					DBG_TRACE( DbgInfo, "Robustness    : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
+								lt_rsp->ltRsp.ltRsp.robustness[0],
+								lt_rsp->ltRsp.ltRsp.robustness[1],
+								lt_rsp->ltRsp.ltRsp.robustness[2],
+								lt_rsp->ltRsp.ltRsp.robustness[3] );
+
+					DBG_TRACE( DbgInfo, "Scaling       : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.scaling );
+				}
+
+				break;
+
+			default:
+				break;
+			}
+		}
+
+		break;
+
+	  case CFG_NULL:
+		DBG_TRACE( DbgInfo, "CFG_NULL\n" );
+		break;
+
+	  case CFG_UPDATED_INFO_RECORD:        // Updated Information Record
+		DBG_TRACE( DbgInfo, "UPDATED INFORMATION RECORD\n" );
+
+		ltv_val = CNV_INT_TO_LITTLE( ltv->u.u16[0] );
+
+		/* Check and see which RID was updated */
+		switch( ltv_val ) {
+		  case CFG_CUR_COUNTRY_INFO:  // Indicate Passive Scan Completion
+			DBG_TRACE( DbgInfo, "Updated country info\n" );
+
+			/* Do I need to hold off on updating RIDs until the process is
+			   complete? */
+			wl_connect( lp );
+			break;
+
+		  case CFG_PORT_STAT:    // Wait for Connect Event
+			//wl_connect( lp );
+
+			break;
+
+		default:
+			DBG_WARNING( DbgInfo, "Unknown RID: 0x%04x\n", ltv_val );
+		}
+
+		break;
+
+	default:
+		DBG_TRACE( DbgInfo, "UNKNOWN MESSAGE: 0x%04x\n", ltv->typ );
+		break;
+	}
+	DBG_LEAVE( DbgInfo );
+	return;
+} // wl_process_mailbox
+/*============================================================================*/
+#endif  /* ifndef USE_MBOX_SYNC */
+
+#ifdef USE_WDS
+/*******************************************************************************
+ *	wl_wds_netdev_register()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function registers net_device structures with the system's network
+ *      layer for use with the WDS ports.
+ *
+ *
+ *  PARAMETERS:
+ *
+ *      lp      - pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_wds_netdev_register( struct wl_private *lp )
+{
+	int count;
+	/*------------------------------------------------------------------------*/
+	DBG_FUNC( "wl_wds_netdev_register" );
+	DBG_ENTER( DbgInfo );
+	//;?why is there no USE_WDS clause like in wl_enable_wds_ports
+	if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
+		for( count = 0; count < NUM_WDS_PORTS; count++ ) {
+			if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
+				if ( register_netdev( lp->wds_port[count].dev ) != 0 ) {
+					DBG_WARNING( DbgInfo, "net device for WDS port %d could not be registered\n",
+								( count + 1 ));
+				}
+				lp->wds_port[count].is_registered = TRUE;
+
+				/* Fill out the net_device structs with the MAC addr */
+				memcpy( lp->wds_port[count].dev->dev_addr, lp->MACAddress, ETH_ALEN );
+				lp->wds_port[count].dev->addr_len = ETH_ALEN;
+			}
+		}
+	}
+	DBG_LEAVE( DbgInfo );
+	return;
+} // wl_wds_netdev_register
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wl_wds_netdev_deregister()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function deregisters the WDS net_device structures used by the
+ *      system's network layer.
+ *
+ *
+ *  PARAMETERS:
+ *
+ *      lp      - pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_wds_netdev_deregister( struct wl_private *lp )
+{
+	int count;
+	/*------------------------------------------------------------------------*/
+	DBG_FUNC( "wl_wds_netdev_deregister" );
+	DBG_ENTER( DbgInfo );
+	if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
+		for( count = 0; count < NUM_WDS_PORTS; count++ ) {
+			if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
+				unregister_netdev( lp->wds_port[count].dev );
+			}
+			lp->wds_port[count].is_registered = FALSE;
+		}
+	}
+	DBG_LEAVE( DbgInfo );
+	return;
+} // wl_wds_netdev_deregister
+/*============================================================================*/
+#endif  /* USE_WDS */
+
+
+#if 0 //SCULL_USE_PROC /* don't waste space if unused */
+/*
+ * The proc filesystem: function to read and entry
+ */
+int printf_hcf_16( char *s, char *buf, hcf_16* p, int n );
+int printf_hcf_16( char *s, char *buf, hcf_16* p, int n ) {
+
+int i, len;
+
+	len = sprintf(buf, "%s", s );
+	while ( len < 20 ) len += sprintf(buf+len, " " );
+	len += sprintf(buf+len,": " );
+	for ( i = 0; i < n; i++ ) {
+		if ( len % 80 > 75 ) {
+			len += sprintf(buf+len,"\n" );
+		}
+		len += sprintf(buf+len,"%04X ", p[i] );
+	}
+	len += sprintf(buf+len,"\n" );
+	return len;
+} // printf_hcf_16
+
+int printf_hcf_8( char *s, char *buf, hcf_8* p, int n );
+int printf_hcf_8( char *s, char *buf, hcf_8* p, int n ) {
+
+int i, len;
+
+	len = sprintf(buf, "%s", s );
+	while ( len < 20 ) len += sprintf(buf+len, " " );
+	len += sprintf(buf+len,": " );
+	for ( i = 0; i <= n; i++ ) {
+		if ( len % 80 > 77 ) {
+			len += sprintf(buf+len,"\n" );
+		}
+		len += sprintf(buf+len,"%02X ", p[i] );
+	}
+	len += sprintf(buf+len,"\n" );
+	return len;
+} // printf_hcf8
+
+int printf_strct( char *s, char *buf, hcf_16* p );
+int printf_strct( char *s, char *buf, hcf_16* p ) {
+
+int i, len;
+
+	len = sprintf(buf, "%s", s );
+	while ( len < 20 ) len += sprintf(buf+len, " " );
+	len += sprintf(buf+len,": " );
+	for ( i = 0; i <= *p; i++ ) {
+		if ( len % 80 > 75 ) {
+			len += sprintf(buf+len,"\n" );
+		}
+		len += sprintf(buf+len,"%04X ", p[i] );
+	}
+	len += sprintf(buf+len,"\n" );
+	return len;
+} // printf_strct
+
+int scull_read_procmem(char *buf, char **start, off_t offset, int len, int *eof, void *data )
+{
+	struct wl_private	*lp = NULL;
+	IFBP				ifbp;
+   	CFG_HERMES_TALLIES_STRCT *p;
+
+    #define LIMIT (PAGE_SIZE-80) /* don't print any more after this size */
+
+    len=0;
+
+	if ( ( lp = ((struct net_device *)data)->priv ) == NULL ) {
+        len += sprintf(buf+len,"No wl_private in scull_read_procmem\n" );
+	} else if ( lp->wlags49_type == 0 ){
+   	    ifbp = &lp->hcfCtx;
+   	    len += sprintf(buf+len,"Magic:               0x%04X\n", ifbp->IFB_Magic );
+   	    len += sprintf(buf+len,"IOBase:              0x%04X\n", ifbp->IFB_IOBase );
+   	    len += sprintf(buf+len,"LinkStat:            0x%04X\n", ifbp->IFB_LinkStat );
+   	    len += sprintf(buf+len,"DSLinkStat:          0x%04X\n", ifbp->IFB_DSLinkStat );
+   	    len += sprintf(buf+len,"TickIni:         0x%08lX\n", ifbp->IFB_TickIni );
+   	    len += sprintf(buf+len,"TickCnt:             0x%04X\n", ifbp->IFB_TickCnt );
+   	    len += sprintf(buf+len,"IntOffCnt:           0x%04X\n", ifbp->IFB_IntOffCnt );
+		len += printf_hcf_16( "IFB_FWIdentity", &buf[len],
+							  &ifbp->IFB_FWIdentity.len, ifbp->IFB_FWIdentity.len + 1 );
+	} else if ( lp->wlags49_type == 1 ) {
+   	    len += sprintf(buf+len,"Channel:              0x%04X\n", lp->Channel );
+/****** len += sprintf(buf+len,"slock:                  %d\n", lp->slock );		*/
+//x		struct tq_struct            "task:               0x%04X\n", lp->task );
+//x		struct net_device_stats     "stats:              0x%04X\n", lp->stats );
+#ifdef WIRELESS_EXT
+//x		struct iw_statistics        "wstats:             0x%04X\n", lp->wstats );
+//x   	    len += sprintf(buf+len,"spy_number:           0x%04X\n", lp->spy_number );
+//x		u_char                      spy_address[IW_MAX_SPY][ETH_ALEN];
+//x		struct iw_quality           spy_stat[IW_MAX_SPY];
+#endif // WIRELESS_EXT
+   	    len += sprintf(buf+len,"IFB:                  0x%p\n", &lp->hcfCtx );
+   	    len += sprintf(buf+len,"flags:                %#.8lX\n", lp->flags );  //;?use this format from now on
+   	    len += sprintf(buf+len,"DebugFlag(wl_private) 0x%04X\n", lp->DebugFlag );
+#if DBG
+   	    len += sprintf(buf+len,"DebugFlag (DbgInfo):   0x%08lX\n", DbgInfo->DebugFlag );
+#endif // DBG
+   	    len += sprintf(buf+len,"is_registered:        0x%04X\n", lp->is_registered );
+//x		CFG_DRV_INFO_STRCT          "driverInfo:         0x%04X\n", lp->driverInfo );
+		len += printf_strct( "driverInfo", &buf[len], (hcf_16*)&lp->driverInfo );
+//x		CFG_IDENTITY_STRCT          "driverIdentity:     0x%04X\n", lp->driverIdentity );
+		len += printf_strct( "driverIdentity", &buf[len], (hcf_16*)&lp->driverIdentity );
+//x		CFG_FW_IDENTITY_STRCT       "StationIdentity:    0x%04X\n", lp->StationIdentity );
+		len += printf_strct( "StationIdentity", &buf[len], (hcf_16*)&lp->StationIdentity );
+//x		CFG_PRI_IDENTITY_STRCT      "PrimaryIdentity:    0x%04X\n", lp->PrimaryIdentity );
+		len += printf_strct( "PrimaryIdentity", &buf[len], (hcf_16*)&lp->hcfCtx.IFB_PRIIdentity );
+		len += printf_strct( "PrimarySupplier", &buf[len], (hcf_16*)&lp->hcfCtx.IFB_PRISup );
+//x		CFG_PRI_IDENTITY_STRCT      "NICIdentity:        0x%04X\n", lp->NICIdentity );
+		len += printf_strct( "NICIdentity", &buf[len], (hcf_16*)&lp->NICIdentity );
+//x		ltv_t                       "ltvRecord:          0x%04X\n", lp->ltvRecord );
+   	    len += sprintf(buf+len,"txBytes:              0x%08lX\n", lp->txBytes );
+   	    len += sprintf(buf+len,"maxPort:              0x%04X\n", lp->maxPort );        /* 0 for STA, 6 for AP */
+	/* Elements used for async notification from hardware */
+//x		RID_LOG_STRCT				RidList[10];
+//x		ltv_t                       "updatedRecord:      0x%04X\n", lp->updatedRecord );
+//x		PROBE_RESP				    "ProbeResp:                    0x%04X\n", lp->ProbeResp );
+//x		ASSOC_STATUS_STRCT          "assoc_stat:         0x%04X\n", lp->assoc_stat );
+//x		SECURITY_STATUS_STRCT       "sec_stat:           0x%04X\n", lp->sec_stat );
+//x		u_char                      lookAheadBuf[WVLAN_MAX_LOOKAHEAD];
+   	    len += sprintf(buf+len,"PortType:             0x%04X\n", lp->PortType );           // 1 - 3 (1 [Normal] | 3 [AdHoc])
+   	    len += sprintf(buf+len,"Channel:              0x%04X\n", lp->Channel );            // 0 - 14 (0)
+//x		hcf_16                      TxRateControl[2];
+   	    len += sprintf(buf+len,"TxRateControl[2]:     0x%04X 0x%04X\n",
+						lp->TxRateControl[0], lp->TxRateControl[1] );
+   	    len += sprintf(buf+len,"DistanceBetweenAPs:   0x%04X\n", lp->DistanceBetweenAPs ); // 1 - 3 (1)
+   	    len += sprintf(buf+len,"RTSThreshold:         0x%04X\n", lp->RTSThreshold );       // 0 - 2347 (2347)
+   	    len += sprintf(buf+len,"PMEnabled:            0x%04X\n", lp->PMEnabled );          // 0 - 2, 8001 - 8002 (0)
+   	    len += sprintf(buf+len,"MicrowaveRobustness:  0x%04X\n", lp->MicrowaveRobustness );// 0 - 1 (0)
+   	    len += sprintf(buf+len,"CreateIBSS:           0x%04X\n", lp->CreateIBSS );         // 0 - 1 (0)
+   	    len += sprintf(buf+len,"MulticastReceive:     0x%04X\n", lp->MulticastReceive );   // 0 - 1 (1)
+   	    len += sprintf(buf+len,"MaxSleepDuration:     0x%04X\n", lp->MaxSleepDuration );   // 0 - 65535 (100)
+//x		hcf_8                       MACAddress[ETH_ALEN];
+		len += printf_hcf_8( "MACAddress", &buf[len], lp->MACAddress, ETH_ALEN );
+//x		char                        NetworkName[HCF_MAX_NAME_LEN+1];
+   	    len += sprintf(buf+len,"NetworkName:          %.32s\n", lp->NetworkName );
+//x		char                        StationName[HCF_MAX_NAME_LEN+1];
+   	    len += sprintf(buf+len,"EnableEncryption:     0x%04X\n", lp->EnableEncryption );   // 0 - 1 (0)
+//x		char                        Key1[MAX_KEY_LEN+1];
+		len += printf_hcf_8( "Key1", &buf[len], lp->Key1, MAX_KEY_LEN );
+//x		char                        Key2[MAX_KEY_LEN+1];
+//x		char                        Key3[MAX_KEY_LEN+1];
+//x		char                        Key4[MAX_KEY_LEN+1];
+   	    len += sprintf(buf+len,"TransmitKeyID:        0x%04X\n", lp->TransmitKeyID );      // 1 - 4 (1)
+//x		CFG_DEFAULT_KEYS_STRCT	    "DefaultKeys:         0x%04X\n", lp->DefaultKeys );
+//x		u_char                      mailbox[MB_SIZE];
+//x		char                        szEncryption[MAX_ENC_LEN];
+   	    len += sprintf(buf+len,"driverEnable:         0x%04X\n", lp->driverEnable );
+   	    len += sprintf(buf+len,"wolasEnable:          0x%04X\n", lp->wolasEnable );
+   	    len += sprintf(buf+len,"atimWindow:           0x%04X\n", lp->atimWindow );
+   	    len += sprintf(buf+len,"holdoverDuration:     0x%04X\n", lp->holdoverDuration );
+//x		hcf_16                      MulticastRate[2];
+   	    len += sprintf(buf+len,"authentication:       0x%04X\n", lp->authentication ); // is this AP specific?
+   	    len += sprintf(buf+len,"promiscuousMode:      0x%04X\n", lp->promiscuousMode );
+   	    len += sprintf(buf+len,"DownloadFirmware:     0x%04X\n", lp->DownloadFirmware );   // 0 - 2 (0 [None] | 1 [STA] | 2 [AP])
+   	    len += sprintf(buf+len,"AuthKeyMgmtSuite:     0x%04X\n", lp->AuthKeyMgmtSuite );
+   	    len += sprintf(buf+len,"loadBalancing:        0x%04X\n", lp->loadBalancing );
+   	    len += sprintf(buf+len,"mediumDistribution:   0x%04X\n", lp->mediumDistribution );
+   	    len += sprintf(buf+len,"txPowLevel:           0x%04X\n", lp->txPowLevel );
+//   	    len += sprintf(buf+len,"shortRetryLimit:    0x%04X\n", lp->shortRetryLimit );
+//   	    len += sprintf(buf+len,"longRetryLimit:     0x%04X\n", lp->longRetryLimit );
+//x		hcf_16                      srsc[2];
+//x		hcf_16                      brsc[2];
+   	    len += sprintf(buf+len,"connectionControl:    0x%04X\n", lp->connectionControl );
+//x		//hcf_16                      probeDataRates[2];
+   	    len += sprintf(buf+len,"ownBeaconInterval:    0x%04X\n", lp->ownBeaconInterval );
+   	    len += sprintf(buf+len,"coexistence:          0x%04X\n", lp->coexistence );
+//x		WVLAN_FRAME                 "txF:                0x%04X\n", lp->txF );
+//x		WVLAN_LFRAME                txList[DEFAULT_NUM_TX_FRAMES];
+//x		struct list_head            "txFree:             0x%04X\n", lp->txFree );
+//x		struct list_head            txQ[WVLAN_MAX_TX_QUEUES];
+   	    len += sprintf(buf+len,"netif_queue_on:       0x%04X\n", lp->netif_queue_on );
+   	    len += sprintf(buf+len,"txQ_count:            0x%04X\n", lp->txQ_count );
+//x		DESC_STRCT                  "desc_rx:            0x%04X\n", lp->desc_rx );
+//x		DESC_STRCT                  "desc_tx:            0x%04X\n", lp->desc_tx );
+//x		WVLAN_PORT_STATE            "portState:          0x%04X\n", lp->portState );
+//x		ScanResult                  "scan_results:       0x%04X\n", lp->scan_results );
+//x		ProbeResult                 "probe_results:      0x%04X\n", lp->probe_results );
+   	    len += sprintf(buf+len,"probe_num_aps:        0x%04X\n", lp->probe_num_aps );
+   	    len += sprintf(buf+len,"use_dma:              0x%04X\n", lp->use_dma );
+//x		DMA_STRCT                   "dma:                0x%04X\n", lp->dma );
+#ifdef USE_RTS
+   	    len += sprintf(buf+len,"useRTS:               0x%04X\n", lp->useRTS );
+#endif  // USE_RTS
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
+		//;?should we restore this to allow smaller memory footprint
+		//;?I guess not. This should be brought under Debug mode only
+   	    len += sprintf(buf+len,"DTIMPeriod:           0x%04X\n", lp->DTIMPeriod );         // 1 - 255 (1)
+   	    len += sprintf(buf+len,"multicastPMBuffering: 0x%04X\n", lp->multicastPMBuffering );
+   	    len += sprintf(buf+len,"RejectAny:            0x%04X\n", lp->RejectAny );          // 0 - 1 (0)
+   	    len += sprintf(buf+len,"ExcludeUnencrypted:   0x%04X\n", lp->ExcludeUnencrypted ); // 0 - 1 (1)
+   	    len += sprintf(buf+len,"intraBSSRelay:        0x%04X\n", lp->intraBSSRelay );
+   	    len += sprintf(buf+len,"wlags49_type:             0x%08lX\n", lp->wlags49_type );
+#ifdef USE_WDS
+//x		WVLAN_WDS_IF                wds_port[NUM_WDS_PORTS];
+#endif // USE_WDS
+#endif // HCF_AP
+	} else if ( lp->wlags49_type == 2 ){
+        len += sprintf(buf+len,"tallies to be added\n" );
+//Hermes Tallies (IFB substructure) {
+   	    p = &lp->hcfCtx.IFB_NIC_Tallies;
+        len += sprintf(buf+len,"TxUnicastFrames:          %08lX\n", p->TxUnicastFrames );
+        len += sprintf(buf+len,"TxMulticastFrames:        %08lX\n", p->TxMulticastFrames );
+        len += sprintf(buf+len,"TxFragments:              %08lX\n", p->TxFragments );
+        len += sprintf(buf+len,"TxUnicastOctets:          %08lX\n", p->TxUnicastOctets );
+        len += sprintf(buf+len,"TxMulticastOctets:        %08lX\n", p->TxMulticastOctets );
+        len += sprintf(buf+len,"TxDeferredTransmissions:  %08lX\n", p->TxDeferredTransmissions );
+        len += sprintf(buf+len,"TxSingleRetryFrames:      %08lX\n", p->TxSingleRetryFrames );
+        len += sprintf(buf+len,"TxMultipleRetryFrames:    %08lX\n", p->TxMultipleRetryFrames );
+        len += sprintf(buf+len,"TxRetryLimitExceeded:     %08lX\n", p->TxRetryLimitExceeded );
+        len += sprintf(buf+len,"TxDiscards:               %08lX\n", p->TxDiscards );
+        len += sprintf(buf+len,"RxUnicastFrames:          %08lX\n", p->RxUnicastFrames );
+        len += sprintf(buf+len,"RxMulticastFrames:        %08lX\n", p->RxMulticastFrames );
+        len += sprintf(buf+len,"RxFragments:              %08lX\n", p->RxFragments );
+        len += sprintf(buf+len,"RxUnicastOctets:          %08lX\n", p->RxUnicastOctets );
+        len += sprintf(buf+len,"RxMulticastOctets:        %08lX\n", p->RxMulticastOctets );
+        len += sprintf(buf+len,"RxFCSErrors:              %08lX\n", p->RxFCSErrors );
+        len += sprintf(buf+len,"RxDiscardsNoBuffer:       %08lX\n", p->RxDiscardsNoBuffer );
+        len += sprintf(buf+len,"TxDiscardsWrongSA:        %08lX\n", p->TxDiscardsWrongSA );
+        len += sprintf(buf+len,"RxWEPUndecryptable:       %08lX\n", p->RxWEPUndecryptable );
+        len += sprintf(buf+len,"RxMsgInMsgFragments:      %08lX\n", p->RxMsgInMsgFragments );
+        len += sprintf(buf+len,"RxMsgInBadMsgFragments:   %08lX\n", p->RxMsgInBadMsgFragments );
+        len += sprintf(buf+len,"RxDiscardsWEPICVError:    %08lX\n", p->RxDiscardsWEPICVError );
+        len += sprintf(buf+len,"RxDiscardsWEPExcluded:    %08lX\n", p->RxDiscardsWEPExcluded );
+#if (HCF_EXT) & HCF_EXT_TALLIES_FW
+        //to be added ;?
+#endif // HCF_EXT_TALLIES_FW
+	} else if ( lp->wlags49_type & 0x8000 ) {	//;?kludgy but it is unclear to me were else to place this
+#if DBG
+		DbgInfo->DebugFlag = lp->wlags49_type & 0x7FFF;
+#endif // DBG
+		lp->wlags49_type = 0;				//default to IFB again ;?
+	} else {
+        len += sprintf(buf+len,"unknown value for wlags49_type: 0x%08lX\n", lp->wlags49_type );
+        len += sprintf(buf+len,"0x0000 - IFB\n" );
+        len += sprintf(buf+len,"0x0001 - wl_private\n" );
+        len += sprintf(buf+len,"0x0002 - Tallies\n" );
+        len += sprintf(buf+len,"0x8xxx - Change debufflag\n" );
+        len += sprintf(buf+len,"ERROR    0001\nWARNING  0002\nNOTICE   0004\nTRACE    0008\n" );
+        len += sprintf(buf+len,"VERBOSE  0010\nPARAM    0020\nBREAK    0040\nRX       0100\n" );
+        len += sprintf(buf+len,"TX       0200\nDS       0400\n" );
+	}
+    return len;
+} // scull_read_procmem
+
+static void proc_write(const char *name, write_proc_t *w, void *data)
+{
+	struct proc_dir_entry * entry = create_proc_entry(name, S_IFREG | S_IWUSR, NULL);
+	if (entry) {
+		entry->write_proc = w;
+		entry->data = data;
+	}
+} // proc_write
+
+static int write_int(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+	static char		proc_number[11];
+	unsigned int	nr = 0;
+
+	DBG_FUNC( "write_int" );
+	DBG_ENTER( DbgInfo );
+
+	if (count > 9) {
+		count = -EINVAL;
+	} else if ( copy_from_user(proc_number, buffer, count) ) {
+		count = -EFAULT;
+	}
+	if  (count > 0 ) {
+		proc_number[count] = 0;
+		nr = wl_atoi( proc_number );
+ 		*(unsigned int *)data = nr;
+		if ( nr & 0x8000 ) {	//;?kludgy but it is unclear to me were else to place this
+#if DBG
+			DbgInfo->DebugFlag = nr & 0x7FFF;
+#endif // DBG
+		}
+	}
+	DBG_PRINT( "value: %08X\n", nr );
+	DBG_LEAVE( DbgInfo );
+	return count;
+} // write_int
+
+#endif /* SCULL_USE_PROC */
+
+#ifdef DN554
+#define RUN_AT(x)		(jiffies+(x))		//"borrowed" from include/pcmcia/k_compat.h
+#define DS_OOR	0x8000		//Deepsleep OutOfRange Status
+
+		lp->timer_oor_cnt = DS_OOR;
+		init_timer( &lp->timer_oor );
+		lp->timer_oor.function = timer_oor;
+		lp->timer_oor.data = (unsigned long)lp;
+		lp->timer_oor.expires = RUN_AT( 3 * HZ );
+		add_timer( &lp->timer_oor );
+		printk( "<5>wl_enable: %ld\n", jiffies );		//;?remove me 1 day
+#endif //DN554
+#ifdef DN554
+/*******************************************************************************
+ *	timer_oor()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *
+ *  PARAMETERS:
+ *
+ *      arg - a u_long representing a pointer to a dev_link_t structure for the
+ *            device to be released.
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void timer_oor( u_long arg )
+{
+	struct wl_private       *lp = (struct wl_private *)arg;
+
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "timer_oor" );
+    DBG_ENTER( DbgInfo );
+    DBG_PARAM( DbgInfo, "arg", "0x%08lx", arg );
+
+	printk( "<5>timer_oor: %ld 0x%04X\n", jiffies, lp->timer_oor_cnt );		//;?remove me 1 day
+	lp->timer_oor_cnt += 10;
+    if ( (lp->timer_oor_cnt & ~DS_OOR) > 300 ) {
+		lp->timer_oor_cnt = 300;
+	}
+	lp->timer_oor_cnt |= DS_OOR;
+	init_timer( &lp->timer_oor );
+	lp->timer_oor.function = timer_oor;
+	lp->timer_oor.data = (unsigned long)lp;
+	lp->timer_oor.expires = RUN_AT( (lp->timer_oor_cnt & ~DS_OOR) * HZ );
+	add_timer( &lp->timer_oor );
+
+    DBG_LEAVE( DbgInfo );
+} // timer_oor
+#endif //DN554
+
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/staging/wlags49_h2/wl_main.h b/drivers/staging/wlags49_h2/wl_main.h
new file mode 100644
index 0000000..d593ae5
--- /dev/null
+++ b/drivers/staging/wlags49_h2/wl_main.h
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Agere Systems Inc.
+ * Wireless device driver for Linux (wlags49).
+ *
+ * Copyright (c) 1998-2003 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * Initially developed by TriplePoint, Inc.
+ *   http://www.triplepoint.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ *   Header describing device specific routines and driver init/un-init.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2003 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following Disclaimer as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ ******************************************************************************/
+
+#ifndef __WL_MAIN_H__
+#define __WL_MAIN_H__
+
+
+
+
+/*******************************************************************************
+ *  function prototypes
+ ******************************************************************************/
+int wl_insert( struct net_device *dev );
+
+void wl_set_wep_keys( struct wl_private *lp );
+
+int wl_put_ltv_init( struct wl_private *lp );
+
+int wl_put_ltv( struct wl_private *lp );
+
+p_u16 wl_get_irq_mask( void );
+
+p_s8 * wl_get_irq_list( void );
+
+int wl_reset( struct net_device *dev );
+
+int wl_go( struct wl_private *lp );
+
+int wl_apply( struct wl_private *lp );
+
+irqreturn_t wl_isr( int irq, void *dev_id, struct pt_regs *regs );
+
+void wl_remove( struct net_device *dev );
+
+void wl_suspend( struct net_device *dev );
+
+void wl_resume( struct net_device *dev );
+
+void wl_release( struct net_device *dev );
+
+int wl_enable( struct wl_private *lp );
+
+int wl_connect( struct wl_private *lp );
+
+int wl_disable( struct wl_private *lp );
+
+int wl_disconnect( struct wl_private *lp );
+
+void wl_enable_wds_ports( struct wl_private * lp );
+
+void wl_disable_wds_ports( struct wl_private * lp );
+
+#ifndef USE_MBOX_SYNC
+
+int wl_mbx( struct wl_private *lp );
+void wl_endian_translate_mailbox( ltv_t *ltv );
+void wl_process_mailbox( struct wl_private *lp );
+
+#endif  /* USE_MBOX_SYNC */
+
+
+#ifdef USE_WDS
+
+void wl_wds_netdev_register( struct wl_private *lp );
+void wl_wds_netdev_deregister( struct wl_private *lp );
+
+#endif  /* USE_WDS */
+
+
+#ifdef USE_WDS
+
+#define WL_WDS_NETDEV_REGISTER( ARG )   wl_wds_netdev_register( ARG )
+#define WL_WDS_NETDEV_DEREGISTER( ARG ) wl_wds_netdev_deregister( ARG )
+
+#else
+
+#define WL_WDS_NETDEV_REGISTER( ARG )
+#define WL_WDS_NETDEV_DEREGISTER( ARG )
+
+#endif  /* USE_WDS */
+#endif  // __WL_MAIN_H__
diff --git a/drivers/staging/wlags49_h2/wl_netdev.c b/drivers/staging/wlags49_h2/wl_netdev.c
new file mode 100644
index 0000000..ac38902
--- /dev/null
+++ b/drivers/staging/wlags49_h2/wl_netdev.c
@@ -0,0 +1,2070 @@
+/*******************************************************************************
+ * Agere Systems Inc.
+ * Wireless device driver for Linux (wlags49).
+ *
+ * Copyright (c) 1998-2003 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * Initially developed by TriplePoint, Inc.
+ *   http://www.triplepoint.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ *   This file contains handler functions registered with the net_device
+ *   structure.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2003 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following Disclaimer as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ ******************************************************************************/
+
+/*******************************************************************************
+ * include files
+ ******************************************************************************/
+#include <wl_version.h>
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+// #include <linux/sched.h>
+// #include <linux/ptrace.h>
+// #include <linux/slab.h>
+// #include <linux/ctype.h>
+// #include <linux/string.h>
+//#include <linux/timer.h>
+// #include <linux/interrupt.h>
+// #include <linux/in.h>
+// #include <linux/delay.h>
+// #include <linux/skbuff.h>
+// #include <asm/io.h>
+// #include <asm/system.h>
+// #include <asm/bitops.h>
+
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+#include <linux/etherdevice.h>
+// #include <linux/skbuff.h>
+// #include <linux/if_arp.h>
+// #include <linux/ioport.h>
+
+#include <debug.h>
+
+#include <hcf.h>
+#include <dhf.h>
+// #include <hcfdef.h>
+
+#include <wl_if.h>
+#include <wl_internal.h>
+#include <wl_util.h>
+#include <wl_priv.h>
+#include <wl_main.h>
+#include <wl_netdev.h>
+#include <wl_wext.h>
+
+#ifdef USE_PROFILE
+#include <wl_profile.h>
+#endif  /* USE_PROFILE */
+
+#ifdef BUS_PCMCIA
+#include <wl_cs.h>
+#endif  /* BUS_PCMCIA */
+
+#ifdef BUS_PCI
+#include <wl_pci.h>
+#endif  /* BUS_PCI */
+
+
+/*******************************************************************************
+ * global variables
+ ******************************************************************************/
+#if DBG
+extern dbg_info_t *DbgInfo;
+#endif  /* DBG */
+
+
+#if HCF_ENCAP
+#define MTU_MAX (HCF_MAX_MSG - ETH_HLEN - 8)
+#else
+#define MTU_MAX (HCF_MAX_MSG - ETH_HLEN)
+#endif
+
+//static int mtu = MTU_MAX;
+//MODULE_PARM(mtu, "i");
+//MODULE_PARM_DESC(mtu, "MTU");
+
+/*******************************************************************************
+ * macros
+ ******************************************************************************/
+#define BLOCK_INPUT(buf, len) \
+    desc->buf_addr = buf; \
+    desc->BUF_SIZE = len; \
+    status = hcf_rcv_msg(&(lp->hcfCtx), desc, 0)
+
+#define BLOCK_INPUT_DMA(buf, len) memcpy( buf, desc_next->buf_addr, pktlen )
+
+/*******************************************************************************
+ * function prototypes
+ ******************************************************************************/
+
+/*******************************************************************************
+ *	wl_init()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      We never need to do anything when a "Wireless" device is "initialized"
+ *  by the net software, because we only register already-found cards.
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the device's net_device structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wl_init( struct net_device *dev )
+{
+//    unsigned long       flags;
+//    struct wl_private   *lp = wl_priv(dev);
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_init" );
+    DBG_ENTER( DbgInfo );
+
+    DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
+
+    /* Nothing to do, but grab the spinlock anyway just in case we ever need
+       this routine */
+//  wl_lock( lp, &flags );
+//  wl_unlock( lp, &flags );
+
+    DBG_LEAVE( DbgInfo );
+    return 0;
+} // wl_init
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_config()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Implement the SIOCSIFMAP interface.
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the device's net_device structure
+ *      map - a pointer to the device's ifmap structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno otherwise
+ *
+ ******************************************************************************/
+int wl_config( struct net_device *dev, struct ifmap *map )
+{
+    DBG_FUNC( "wl_config" );
+    DBG_ENTER( DbgInfo );
+
+    DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
+    DBG_PARAM( DbgInfo, "map", "0x%p", map );
+
+    /* The only thing we care about here is a port change. Since this not needed,
+       ignore the request. */
+    DBG_TRACE( DbgInfo, "%s: %s called.\n", dev->name, __FUNC__ );
+
+    DBG_LEAVE( DbgInfo );
+    return 0;
+} // wl_config
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_stats()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Return the current device statistics.
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the device's net_device structure
+ *
+ *  RETURNS:
+ *
+ *      a pointer to a net_device_stats structure containing the network
+ *      statistics.
+ *
+ ******************************************************************************/
+struct net_device_stats *wl_stats( struct net_device *dev )
+{
+#ifdef USE_WDS
+    int                         count;
+#endif  /* USE_WDS */
+    unsigned long               flags;
+    struct net_device_stats     *pStats;
+    struct wl_private           *lp = wl_priv(dev);
+    /*------------------------------------------------------------------------*/
+
+    //DBG_FUNC( "wl_stats" );
+    //DBG_ENTER( DbgInfo );
+    //DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
+
+    pStats = NULL;
+
+    wl_lock( lp, &flags );
+
+#ifdef USE_RTS
+    if( lp->useRTS == 1 ) {
+	wl_unlock( lp, &flags );
+
+	//DBG_LEAVE( DbgInfo );
+	return NULL;
+    }
+#endif  /* USE_RTS */
+
+    /* Return the statistics for the appropriate device */
+#ifdef USE_WDS
+
+    for( count = 0; count < NUM_WDS_PORTS; count++ ) {
+	if( dev == lp->wds_port[count].dev ) {
+	    pStats = &( lp->wds_port[count].stats );
+	}
+    }
+
+#endif  /* USE_WDS */
+
+    /* If pStats is still NULL, then the device is not a WDS port */
+    if( pStats == NULL ) {
+        pStats = &( lp->stats );
+    }
+
+    wl_unlock( lp, &flags );
+
+    //DBG_LEAVE( DbgInfo );
+
+    return pStats;
+} // wl_stats
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_open()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Open the device.
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the device's net_device structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno otherwise
+ *
+ ******************************************************************************/
+int wl_open(struct net_device *dev)
+{
+    int                 status = HCF_SUCCESS;
+    struct wl_private   *lp = wl_priv(dev);
+    unsigned long       flags;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_open" );
+    DBG_ENTER( DbgInfo );
+
+    wl_lock( lp, &flags );
+
+#ifdef USE_RTS
+    if( lp->useRTS == 1 ) {
+	DBG_TRACE( DbgInfo, "Skipping device open, in RTS mode\n" );
+	wl_unlock( lp, &flags );
+	DBG_LEAVE( DbgInfo );
+	return -EIO;
+    }
+#endif  /* USE_RTS */
+
+#ifdef USE_PROFILE
+    parse_config( dev );
+#endif
+
+    if( lp->portState == WVLAN_PORT_STATE_DISABLED ) {
+	DBG_TRACE( DbgInfo, "Enabling Port 0\n" );
+	status = wl_enable( lp );
+
+        if( status != HCF_SUCCESS ) {
+            DBG_TRACE( DbgInfo, "Enable port 0 failed: 0x%x\n", status );
+        }
+    }
+
+    // Holding the lock too long, make a gap to allow other processes
+    wl_unlock(lp, &flags);
+    wl_lock( lp, &flags );
+
+    if ( strlen( lp->fw_image_filename ) ) {
+	DBG_TRACE( DbgInfo, ";???? Kludgy way to force a download\n" );
+	status = wl_go( lp );
+    } else {
+	status = wl_apply( lp );
+    }
+
+    // Holding the lock too long, make a gap to allow other processes
+    wl_unlock(lp, &flags);
+    wl_lock( lp, &flags );
+
+    if( status != HCF_SUCCESS ) {
+	// Unsuccesfull, try reset of the card to recover
+	status = wl_reset( dev );
+    }
+
+    // Holding the lock too long, make a gap to allow other processes
+    wl_unlock(lp, &flags);
+    wl_lock( lp, &flags );
+
+    if( status == HCF_SUCCESS ) {
+	netif_carrier_on( dev );
+	WL_WDS_NETIF_CARRIER_ON( lp );
+
+	lp->is_handling_int = WL_HANDLING_INT; // Start handling interrupts
+        wl_act_int_on( lp );
+
+	netif_start_queue( dev );
+	WL_WDS_NETIF_START_QUEUE( lp );
+    } else {
+        wl_hcf_error( dev, status );		/* Report the error */
+        netif_device_detach( dev );		/* Stop the device and queue */
+    }
+
+    wl_unlock( lp, &flags );
+
+    DBG_LEAVE( DbgInfo );
+    return status;
+} // wl_open
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_close()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Close the device.
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the device's net_device structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno otherwise
+ *
+ ******************************************************************************/
+int wl_close( struct net_device *dev )
+{
+    struct wl_private   *lp = wl_priv(dev);
+    unsigned long   flags;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC("wl_close");
+    DBG_ENTER(DbgInfo);
+    DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
+
+    /* Mark the adapter as busy */
+    netif_stop_queue( dev );
+    WL_WDS_NETIF_STOP_QUEUE( lp );
+
+    netif_carrier_off( dev );
+    WL_WDS_NETIF_CARRIER_OFF( lp );
+
+    /* Shutdown the adapter:
+            Disable adapter interrupts
+            Stop Tx/Rx
+            Update statistics
+            Set low power mode
+    */
+
+    wl_lock( lp, &flags );
+
+    wl_act_int_off( lp );
+    lp->is_handling_int = WL_NOT_HANDLING_INT; // Stop handling interrupts
+
+#ifdef USE_RTS
+    if( lp->useRTS == 1 ) {
+	DBG_TRACE( DbgInfo, "Skipping device close, in RTS mode\n" );
+	wl_unlock( lp, &flags );
+	DBG_LEAVE( DbgInfo );
+	return -EIO;
+    }
+#endif  /* USE_RTS */
+
+    /* Disable the ports */
+    wl_disable( lp );
+
+    wl_unlock( lp, &flags );
+
+    DBG_LEAVE( DbgInfo );
+    return 0;
+} // wl_close
+/*============================================================================*/
+
+static void wl_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+    strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
+    strncpy(info->version, DRV_VERSION_STR, sizeof(info->version) - 1);
+//	strncpy(info.fw_version, priv->fw_name,
+//	sizeof(info.fw_version) - 1);
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20))
+    if (dev->dev.parent) {
+    	dev_set_name(dev->dev.parent, "%s", info->bus_info);
+	//strncpy(info->bus_info, dev->dev.parent->bus_id,
+	//	sizeof(info->bus_info) - 1);
+#else
+	    if (dev->class_dev.parent) {
+		sizeof(info->bus_info) - 1);
+#endif
+    } else {
+	snprintf(info->bus_info, sizeof(info->bus_info) - 1,
+		"PCMCIA FIXME");
+//		    "PCMCIA 0x%lx", priv->hw.iobase);
+    }
+} // wl_get_drvinfo
+
+static struct ethtool_ops wl_ethtool_ops = {
+    .get_drvinfo = wl_get_drvinfo,
+    .get_link = ethtool_op_get_link,
+};
+
+
+/*******************************************************************************
+ *	wl_ioctl()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      The IOCTL handler for the device.
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the device's net_device struct.
+ *      rq  - a pointer to the IOCTL request buffer.
+ *      cmd - the IOCTL command code.
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wl_ioctl( struct net_device *dev, struct ifreq *rq, int cmd )
+{
+    struct wl_private  *lp = wl_priv(dev);
+    unsigned long           flags;
+    int                     ret = 0;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_ioctl" );
+    DBG_ENTER(DbgInfo);
+    DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
+    DBG_PARAM(DbgInfo, "rq", "0x%p", rq);
+    DBG_PARAM(DbgInfo, "cmd", "0x%04x", cmd);
+
+    wl_lock( lp, &flags );
+
+    wl_act_int_off( lp );
+
+#ifdef USE_RTS
+    if( lp->useRTS == 1 ) {
+	/* Handle any RTS IOCTL here */
+	if( cmd == WL_IOCTL_RTS ) {
+	    DBG_TRACE( DbgInfo, "IOCTL: WL_IOCTL_RTS\n" );
+	    ret = wvlan_rts( (struct rtsreq *)rq, dev->base_addr );
+	} else {
+	    DBG_TRACE( DbgInfo, "IOCTL not supported in RTS mode: 0x%X\n", cmd );
+	    ret = -EOPNOTSUPP;
+	}
+
+	goto out_act_int_on_unlock;
+    }
+#endif  /* USE_RTS */
+
+    /* Only handle UIL IOCTL requests when the UIL has the system blocked. */
+    if( !(( lp->flags & WVLAN2_UIL_BUSY ) && ( cmd != WVLAN2_IOCTL_UIL ))) {
+#ifdef USE_UIL
+	struct uilreq  *urq = (struct uilreq *)rq;
+#endif /* USE_UIL */
+
+	switch( cmd ) {
+		// ================== Private IOCTLs (up to 16) ==================
+#ifdef USE_UIL
+	case WVLAN2_IOCTL_UIL:
+	     DBG_TRACE( DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL\n" );
+	     ret = wvlan_uil( urq, lp );
+	     break;
+#endif  /* USE_UIL */
+
+	default:
+	     DBG_TRACE(DbgInfo, "IOCTL CODE NOT SUPPORTED: 0x%X\n", cmd );
+	     ret = -EOPNOTSUPP;
+	     break;
+	}
+    } else {
+	DBG_WARNING( DbgInfo, "DEVICE IS BUSY, CANNOT PROCESS REQUEST\n" );
+	ret = -EBUSY;
+    }
+
+#ifdef USE_RTS
+out_act_int_on_unlock:
+#endif  /* USE_RTS */
+    wl_act_int_on( lp );
+
+    wl_unlock( lp, &flags );
+
+    DBG_LEAVE( DbgInfo );
+    return ret;
+} // wl_ioctl
+/*============================================================================*/
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+void wl_poll(struct net_device *dev)
+{
+    struct wl_private *lp = wl_priv(dev);
+    unsigned long flags;
+    struct pt_regs regs;
+
+    wl_lock( lp, &flags );
+    wl_isr(dev->irq, dev, &regs);
+    wl_unlock( lp, &flags );
+}
+#endif
+
+/*******************************************************************************
+ *	wl_tx_timeout()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      The handler called when, for some reason, a Tx request is not completed.
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the device's net_device struct.
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_tx_timeout( struct net_device *dev )
+{
+#ifdef USE_WDS
+    int                     count;
+#endif  /* USE_WDS */
+    unsigned long           flags;
+    struct wl_private       *lp = wl_priv(dev);
+    struct net_device_stats *pStats = NULL;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_tx_timeout" );
+    DBG_ENTER( DbgInfo );
+
+    DBG_WARNING( DbgInfo, "%s: Transmit timeout.\n", dev->name );
+
+    wl_lock( lp, &flags );
+
+#ifdef USE_RTS
+    if( lp->useRTS == 1 ) {
+	DBG_TRACE( DbgInfo, "Skipping tx_timeout handler, in RTS mode\n" );
+	wl_unlock( lp, &flags );
+
+	DBG_LEAVE( DbgInfo );
+	return;
+    }
+#endif  /* USE_RTS */
+
+    /* Figure out which device (the "root" device or WDS port) this timeout
+       is for */
+#ifdef USE_WDS
+
+    for( count = 0; count < NUM_WDS_PORTS; count++ ) {
+	if( dev == lp->wds_port[count].dev ) {
+	    pStats = &( lp->wds_port[count].stats );
+
+	    /* Break the loop so that we can use the counter to access WDS
+	       information in the private structure */
+	    break;
+	}
+    }
+
+#endif  /* USE_WDS */
+
+    /* If pStats is still NULL, then the device is not a WDS port */
+    if( pStats == NULL ) {
+	pStats = &( lp->stats );
+    }
+
+    /* Accumulate the timeout error */
+    pStats->tx_errors++;
+
+    wl_unlock( lp, &flags );
+
+    DBG_LEAVE( DbgInfo );
+    return;
+} // wl_tx_timeout
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_send()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      The routine which performs data transmits.
+ *
+ *  PARAMETERS:
+ *
+ *      lp  - a pointer to the device's wl_private struct.
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      1 on error
+ *
+ ******************************************************************************/
+int wl_send( struct wl_private *lp )
+{
+
+    int                 status;
+    DESC_STRCT          *desc;
+    WVLAN_LFRAME        *txF = NULL;
+    struct list_head    *element;
+    int                 len;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_send" );
+
+    if( lp == NULL ) {
+        DBG_ERROR( DbgInfo, "Private adapter struct is NULL\n" );
+        return FALSE;
+    }
+    if( lp->dev == NULL ) {
+        DBG_ERROR( DbgInfo, "net_device struct in wl_private is NULL\n" );
+        return FALSE;
+    }
+
+    /* Check for the availability of FIDs; if none are available, don't take any
+       frames off the txQ */
+    if( lp->hcfCtx.IFB_RscInd == 0 ) {
+        return FALSE;
+    }
+
+    /* Reclaim the TxQ Elements and place them back on the free queue */
+    if( !list_empty( &( lp->txQ[0] ))) {
+        element = lp->txQ[0].next;
+
+        txF = (WVLAN_LFRAME * )list_entry( element, WVLAN_LFRAME, node );
+        if( txF != NULL ) {
+            lp->txF.skb  = txF->frame.skb;
+            lp->txF.port = txF->frame.port;
+
+            txF->frame.skb  = NULL;
+            txF->frame.port = 0;
+
+            list_del( &( txF->node ));
+            list_add( element, &( lp->txFree ));
+
+            lp->txQ_count--;
+
+            if( lp->txQ_count < TX_Q_LOW_WATER_MARK ) {
+                if( lp->netif_queue_on == FALSE ) {
+                    DBG_TX( DbgInfo, "Kickstarting Q: %d\n", lp->txQ_count );
+                    netif_wake_queue( lp->dev );
+                    WL_WDS_NETIF_WAKE_QUEUE( lp );
+                    lp->netif_queue_on = TRUE;
+                }
+            }
+        }
+    }
+
+    if( lp->txF.skb == NULL ) {
+        return FALSE;
+    }
+
+    /* If the device has resources (FIDs) available, then Tx the packet */
+    /* Format the TxRequest and send it to the adapter */
+    len = lp->txF.skb->len < ETH_ZLEN ? ETH_ZLEN : lp->txF.skb->len;
+
+    desc                    = &( lp->desc_tx );
+    desc->buf_addr          = lp->txF.skb->data;
+    desc->BUF_CNT           = len;
+    desc->next_desc_addr    = NULL;
+
+    status = hcf_send_msg( &( lp->hcfCtx ), desc, lp->txF.port );
+
+    if( status == HCF_SUCCESS ) {
+        lp->dev->trans_start = jiffies;
+
+        DBG_TX( DbgInfo, "Transmit...\n" );
+
+        if( lp->txF.port == HCF_PORT_0 ) {
+            lp->stats.tx_packets++;
+            lp->stats.tx_bytes += lp->txF.skb->len;
+        }
+
+#ifdef USE_WDS
+        else
+        {
+            lp->wds_port[(( lp->txF.port >> 8 ) - 1)].stats.tx_packets++;
+            lp->wds_port[(( lp->txF.port >> 8 ) - 1)].stats.tx_bytes += lp->txF.skb->len;
+        }
+
+#endif  /* USE_WDS */
+
+        /* Free the skb and perform queue cleanup, as the buffer was
+            transmitted successfully */
+        dev_kfree_skb( lp->txF.skb );
+
+        lp->txF.skb = NULL;
+        lp->txF.port = 0;
+    }
+
+    return TRUE;
+} // wl_send
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_tx()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      The Tx handler function for the network layer.
+ *
+ *  PARAMETERS:
+ *
+ *      skb - a pointer to the sk_buff structure containing the data to transfer.
+ *      dev - a pointer to the device's net_device structure.
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      1 on error
+ *
+ ******************************************************************************/
+int wl_tx( struct sk_buff *skb, struct net_device *dev, int port )
+{
+    unsigned long           flags;
+    struct wl_private       *lp = wl_priv(dev);
+    WVLAN_LFRAME            *txF = NULL;
+    struct list_head        *element;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_tx" );
+
+    /* Grab the spinlock */
+    wl_lock( lp, &flags );
+
+    if( lp->flags & WVLAN2_UIL_BUSY ) {
+        DBG_WARNING( DbgInfo, "UIL has device blocked\n" );
+        /* Start dropping packets here??? */
+	wl_unlock( lp, &flags );
+        return 1;
+    }
+
+#ifdef USE_RTS
+    if( lp->useRTS == 1 ) {
+        DBG_PRINT( "RTS: we're getting a Tx...\n" );
+	wl_unlock( lp, &flags );
+        return 1;
+    }
+#endif  /* USE_RTS */
+
+    if( !lp->use_dma ) {
+        /* Get an element from the queue */
+        element = lp->txFree.next;
+        txF = (WVLAN_LFRAME *)list_entry( element, WVLAN_LFRAME, node );
+        if( txF == NULL ) {
+            DBG_ERROR( DbgInfo, "Problem with list_entry\n" );
+	    wl_unlock( lp, &flags );
+            return 1;
+        }
+        /* Fill out the frame */
+        txF->frame.skb = skb;
+        txF->frame.port = port;
+        /* Move the frame to the txQ */
+        /* NOTE: Here's where we would do priority queueing */
+        list_del( &( txF->node ));
+        list_add( &( txF->node ), &( lp->txQ[0] ));
+
+        lp->txQ_count++;
+        if( lp->txQ_count >= DEFAULT_NUM_TX_FRAMES ) {
+            DBG_TX( DbgInfo, "Q Full: %d\n", lp->txQ_count );
+            if( lp->netif_queue_on == TRUE ) {
+                netif_stop_queue( lp->dev );
+                WL_WDS_NETIF_STOP_QUEUE( lp );
+                lp->netif_queue_on = FALSE;
+            }
+        }
+    }
+    wl_act_int_off( lp ); /* Disable Interrupts */
+
+    /* Send the data to the hardware using the appropriate method */
+#ifdef ENABLE_DMA
+    if( lp->use_dma ) {
+        wl_send_dma( lp, skb, port );
+    }
+    else
+#endif
+    {
+        wl_send( lp );
+    }
+    /* Re-enable Interrupts, release the spinlock and return */
+    wl_act_int_on( lp );
+    wl_unlock( lp, &flags );
+    return 0;
+} // wl_tx
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_rx()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      The routine which performs data reception.
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the device's net_device structure.
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      1 on error
+ *
+ ******************************************************************************/
+int wl_rx(struct net_device *dev)
+{
+    int                     port;
+    struct sk_buff          *skb;
+    struct wl_private       *lp = wl_priv(dev);
+    int                     status;
+    hcf_16                  pktlen;
+    hcf_16                  hfs_stat;
+    DESC_STRCT              *desc;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC("wl_rx")
+    DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
+
+    if(!( lp->flags & WVLAN2_UIL_BUSY )) {
+
+#ifdef USE_RTS
+        if( lp->useRTS == 1 ) {
+            DBG_PRINT( "RTS: We're getting an Rx...\n" );
+            return -EIO;
+        }
+#endif  /* USE_RTS */
+
+        /* Read the HFS_STAT register from the lookahead buffer */
+        hfs_stat = (hcf_16)(( lp->lookAheadBuf[HFS_STAT] ) |
+                            ( lp->lookAheadBuf[HFS_STAT + 1] << 8 ));
+
+        /* Make sure the frame isn't bad */
+        if(( hfs_stat & HFS_STAT_ERR ) != HCF_SUCCESS ) {
+            DBG_WARNING( DbgInfo, "HFS_STAT_ERROR (0x%x) in Rx Packet\n",
+                         lp->lookAheadBuf[HFS_STAT] );
+            return -EIO;
+        }
+
+        /* Determine what port this packet is for */
+        port = ( hfs_stat >> 8 ) & 0x0007;
+        DBG_RX( DbgInfo, "Rx frame for port %d\n", port );
+
+        if(( pktlen = lp->hcfCtx.IFB_RxLen ) != 0 ) {
+            if(( skb = ALLOC_SKB( pktlen )) != NULL ) {
+                /* Set the netdev based on the port */
+                switch( port ) {
+#ifdef USE_WDS
+                case 1:
+                case 2:
+                case 3:
+                case 4:
+                case 5:
+                case 6:
+                    skb->dev = lp->wds_port[port-1].dev;
+                    break;
+#endif  /* USE_WDS */
+
+                case 0:
+                default:
+                    skb->dev = dev;
+                    break;
+                }
+
+                desc = &( lp->desc_rx );
+
+                desc->next_desc_addr = NULL;
+
+/*
+#define BLOCK_INPUT(buf, len) \
+    desc->buf_addr = buf; \
+    desc->BUF_SIZE = len; \
+    status = hcf_rcv_msg(&(lp->hcfCtx), desc, 0)
+*/
+
+                GET_PACKET( skb->dev, skb, pktlen );
+
+                if( status == HCF_SUCCESS ) {
+                    netif_rx( skb );
+
+                    if( port == 0 ) {
+                        lp->stats.rx_packets++;
+                        lp->stats.rx_bytes += pktlen;
+                    }
+#ifdef USE_WDS
+                    else
+                    {
+                        lp->wds_port[port-1].stats.rx_packets++;
+                        lp->wds_port[port-1].stats.rx_bytes += pktlen;
+                    }
+#endif  /* USE_WDS */
+
+                    dev->last_rx = jiffies;
+
+#ifdef WIRELESS_EXT
+#ifdef WIRELESS_SPY
+                    if( lp->spydata.spy_number > 0 ) {
+                        char *srcaddr = skb->mac.raw + MAC_ADDR_SIZE;
+
+                        wl_spy_gather( dev, srcaddr );
+                    }
+#endif /* WIRELESS_SPY */
+#endif /* WIRELESS_EXT */
+                } else {
+                    DBG_ERROR( DbgInfo, "Rx request to card FAILED\n" );
+
+                    if( port == 0 ) {
+                        lp->stats.rx_dropped++;
+                    }
+#ifdef USE_WDS
+                    else
+                    {
+                        lp->wds_port[port-1].stats.rx_dropped++;
+                    }
+#endif  /* USE_WDS */
+
+                    dev_kfree_skb( skb );
+                }
+            } else {
+                DBG_ERROR( DbgInfo, "Could not alloc skb\n" );
+
+                if( port == 0 ) {
+                    lp->stats.rx_dropped++;
+                }
+#ifdef USE_WDS
+                else
+                {
+                    lp->wds_port[port-1].stats.rx_dropped++;
+                }
+#endif  /* USE_WDS */
+            }
+        }
+    }
+
+    return 0;
+} // wl_rx
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_multicast()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Function to handle multicast packets
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the device's net_device structure.
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+#ifdef NEW_MULTICAST
+
+void wl_multicast( struct net_device *dev )
+{
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_STA //;?should we return an error status in AP mode
+//;?seems reasonable that even an AP-only driver could afford this small additional footprint
+
+    int                 x;
+    struct dev_mc_list  *mclist;
+    struct wl_private   *lp = wl_priv(dev);
+    unsigned long       flags;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_multicast" );
+    DBG_ENTER( DbgInfo );
+    DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
+
+    if( !wl_adapter_is_open( dev )) {
+        DBG_LEAVE( DbgInfo );
+        return;
+    }
+
+#if DBG
+    if( DBG_FLAGS( DbgInfo ) & DBG_PARAM_ON ) {
+        DBG_PRINT("  flags: %s%s%s\n",
+            ( dev->flags & IFF_PROMISC ) ? "Promiscous " : "",
+            ( dev->flags & IFF_MULTICAST ) ? "Multicast " : "",
+            ( dev->flags & IFF_ALLMULTI ) ? "All-Multicast" : "" );
+
+        DBG_PRINT( "  mc_count: %d\n", dev->mc_count );
+
+        for( x = 0, mclist = dev->mc_list; mclist && x < dev->mc_count;
+             x++, mclist = mclist->next ) {
+            DBG_PRINT( "    %s (%d)\n", DbgHwAddr(mclist->dmi_addr),
+                       mclist->dmi_addrlen );
+        }
+    }
+#endif /* DBG */
+
+    if(!( lp->flags & WVLAN2_UIL_BUSY )) {
+
+#ifdef USE_RTS
+        if( lp->useRTS == 1 ) {
+            DBG_TRACE( DbgInfo, "Skipping multicast, in RTS mode\n" );
+
+            DBG_LEAVE( DbgInfo );
+            return;
+        }
+#endif  /* USE_RTS */
+
+        wl_lock( lp, &flags );
+        wl_act_int_off( lp );
+
+		if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA  ) {
+            if( dev->flags & IFF_PROMISC ) {
+                /* Enable promiscuous mode */
+                lp->ltvRecord.len       = 2;
+                lp->ltvRecord.typ       = CFG_PROMISCUOUS_MODE;
+                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 1 );
+                DBG_PRINT( "Enabling Promiscuous mode (IFF_PROMISC)\n" );
+                hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+            }
+            else if(( dev->mc_count > HCF_MAX_MULTICAST ) ||
+                    ( dev->flags & IFF_ALLMULTI )) {
+                /* Shutting off this filter will enable all multicast frames to
+                   be sent up from the device; however, this is a static RID, so
+                   a call to wl_apply() is needed */
+                lp->ltvRecord.len       = 2;
+                lp->ltvRecord.typ       = CFG_CNF_RX_ALL_GROUP_ADDR;
+                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 0 );
+                DBG_PRINT( "Enabling all multicast mode (IFF_ALLMULTI)\n" );
+                hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+                wl_apply( lp );
+            }
+            else if( dev->mc_count != 0 ) {
+                /* Set the multicast addresses */
+                lp->ltvRecord.len = ( dev->mc_count * 3 ) + 1;
+                lp->ltvRecord.typ = CFG_GROUP_ADDR;
+
+                for( x = 0, mclist = dev->mc_list;
+                ( x < dev->mc_count ) && ( mclist != NULL );
+                    x++, mclist = mclist->next ) {
+                    memcpy( &( lp->ltvRecord.u.u8[x * ETH_ALEN] ),
+                            mclist->dmi_addr, ETH_ALEN );
+                }
+                DBG_PRINT( "Setting multicast list\n" );
+                hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+            } else {
+                /* Disable promiscuous mode */
+                lp->ltvRecord.len       = 2;
+                lp->ltvRecord.typ       = CFG_PROMISCUOUS_MODE;
+                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 0 );
+                DBG_PRINT( "Disabling Promiscuous mode\n" );
+                hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+
+                /* Disable multicast mode */
+                lp->ltvRecord.len = 2;
+                lp->ltvRecord.typ = CFG_GROUP_ADDR;
+                DBG_PRINT( "Disabling Multicast mode\n" );
+                hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+
+                /* Turning on this filter will prevent all multicast frames from
+                   being sent up from the device; however, this is a static RID,
+                   so a call to wl_apply() is needed */
+                lp->ltvRecord.len       = 2;
+                lp->ltvRecord.typ       = CFG_CNF_RX_ALL_GROUP_ADDR;
+                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 1 );
+                DBG_PRINT( "Disabling all multicast mode (IFF_ALLMULTI)\n" );
+                hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+                wl_apply( lp );
+            }
+        }
+        wl_act_int_on( lp );
+	wl_unlock( lp, &flags );
+    }
+    DBG_LEAVE( DbgInfo );
+#endif /* HCF_STA */
+} // wl_multicast
+/*============================================================================*/
+
+#else /* NEW_MULTICAST */
+
+void wl_multicast( struct net_device *dev, int num_addrs, void *addrs )
+{
+    DBG_FUNC( "wl_multicast");
+    DBG_ENTER(DbgInfo);
+
+    DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
+    DBG_PARAM( DbgInfo, "num_addrs", "%d", num_addrs );
+    DBG_PARAM( DbgInfo, "addrs", "0x%p", addrs );
+
+#error Obsolete set multicast interface!
+
+    DBG_LEAVE( DbgInfo );
+} // wl_multicast
+/*============================================================================*/
+
+#endif /* NEW_MULTICAST */
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30))
+static const struct net_device_ops wl_netdev_ops =
+{
+    .ndo_start_xmit         = &wl_tx_port0,
+
+    .ndo_set_config         = &wl_config,
+    .ndo_get_stats          = &wl_stats,
+    .ndo_set_multicast_list = &wl_multicast,
+
+    .ndo_init               = &wl_insert,
+    .ndo_open               = &wl_adapter_open,
+    .ndo_stop               = &wl_adapter_close,
+    .ndo_do_ioctl           = &wl_ioctl,
+
+#ifdef HAVE_TX_TIMEOUT
+    .ndo_tx_timeout         = &wl_tx_timeout,
+#endif
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+    .ndo_poll_controller    = wl_poll,
+#endif
+};
+#endif // (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30))
+
+/*******************************************************************************
+ *	wl_device_alloc()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Create instances of net_device and wl_private for the new adapter
+ *  and register the device's entry points in the net_device structure.
+ *
+ *  PARAMETERS:
+ *
+ *      N/A
+ *
+ *  RETURNS:
+ *
+ *      a pointer to an allocated and initialized net_device struct for this
+ *      device.
+ *
+ ******************************************************************************/
+struct net_device * wl_device_alloc( void )
+{
+    struct net_device   *dev = NULL;
+    struct wl_private   *lp = NULL;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_device_alloc" );
+    DBG_ENTER( DbgInfo );
+
+    /* Alloc a net_device struct */
+    dev = alloc_etherdev(sizeof(struct wl_private));
+    if (!dev)
+        return NULL;
+
+    /* Initialize the 'next' pointer in the struct. Currently only used for PCI,
+       but do it here just in case it's used for other buses in the future */
+    lp = wl_priv(dev);
+
+
+    /* Check MTU */
+    if( dev->mtu > MTU_MAX )
+    {
+	    DBG_WARNING( DbgInfo, "%s: MTU set too high, limiting to %d.\n",
+                        dev->name, MTU_MAX );
+    	dev->mtu = MTU_MAX;
+    }
+
+    /* Setup the function table in the device structure. */
+
+    dev->wireless_handlers = (struct iw_handler_def *)&wl_iw_handler_def;
+    lp->wireless_data.spy_data = &lp->spy_data;
+    dev->wireless_data = &lp->wireless_data;
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30))
+    dev->netdev_ops = &wl_netdev_ops;
+#else
+    dev->hard_start_xmit    = &wl_tx_port0;
+
+    dev->set_config         = &wl_config;
+    dev->get_stats          = &wl_stats;
+    dev->set_multicast_list = &wl_multicast;
+
+    dev->init               = &wl_insert;
+    dev->open               = &wl_adapter_open;
+    dev->stop               = &wl_adapter_close;
+    dev->do_ioctl           = &wl_ioctl;
+
+#ifdef HAVE_TX_TIMEOUT
+    dev->tx_timeout         = &wl_tx_timeout;
+#endif
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+    dev->poll_controller = wl_poll;
+#endif
+
+#endif // (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30))
+
+#ifdef HAVE_TX_TIMEOUT
+    dev->watchdog_timeo     = TX_TIMEOUT;
+#endif
+
+    dev->ethtool_ops	    = &wl_ethtool_ops;
+
+    netif_stop_queue( dev );
+
+    /* Allocate virutal devices for WDS support if needed */
+    WL_WDS_DEVICE_ALLOC( lp );
+
+    DBG_LEAVE( DbgInfo );
+    return dev;
+} // wl_device_alloc
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_device_dealloc()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Free instances of net_device and wl_private strcutres for an adapter
+ *  and perform basic cleanup.
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the device's net_device structure.
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_device_dealloc( struct net_device *dev )
+{
+//    struct wl_private   *lp = wl_priv(dev);
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_device_dealloc" );
+    DBG_ENTER( DbgInfo );
+
+    /* Dealloc the WDS ports */
+    WL_WDS_DEVICE_DEALLOC( lp );
+
+    free_netdev( dev );
+
+    DBG_LEAVE( DbgInfo );
+    return;
+} // wl_device_dealloc
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_tx_port0()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      The handler routine for Tx over HCF_PORT_0.
+ *
+ *  PARAMETERS:
+ *
+ *      skb - a pointer to the sk_buff to transmit.
+ *      dev - a pointer to a net_device structure representing HCF_PORT_0.
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+int wl_tx_port0( struct sk_buff *skb, struct net_device *dev )
+{
+    DBG_TX( DbgInfo, "Tx on Port 0\n" );
+
+    return wl_tx( skb, dev, HCF_PORT_0 );
+#ifdef ENABLE_DMA
+    return wl_tx_dma( skb, dev, HCF_PORT_0 );
+#endif
+} // wl_tx_port0
+/*============================================================================*/
+
+#ifdef USE_WDS
+
+/*******************************************************************************
+ *	wl_tx_port1()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      The handler routine for Tx over HCF_PORT_1.
+ *
+ *  PARAMETERS:
+ *
+ *      skb - a pointer to the sk_buff to transmit.
+ *      dev - a pointer to a net_device structure representing HCF_PORT_1.
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+int wl_tx_port1( struct sk_buff *skb, struct net_device *dev )
+{
+    DBG_TX( DbgInfo, "Tx on Port 1\n" );
+    return wl_tx( skb, dev, HCF_PORT_1 );
+} // wl_tx_port1
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_tx_port2()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      The handler routine for Tx over HCF_PORT_2.
+ *
+ *  PARAMETERS:
+ *
+ *      skb - a pointer to the sk_buff to transmit.
+ *      dev - a pointer to a net_device structure representing HCF_PORT_2.
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+int wl_tx_port2( struct sk_buff *skb, struct net_device *dev )
+{
+    DBG_TX( DbgInfo, "Tx on Port 2\n" );
+    return wl_tx( skb, dev, HCF_PORT_2 );
+} // wl_tx_port2
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_tx_port3()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      The handler routine for Tx over HCF_PORT_3.
+ *
+ *  PARAMETERS:
+ *
+ *      skb - a pointer to the sk_buff to transmit.
+ *      dev - a pointer to a net_device structure representing HCF_PORT_3.
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+int wl_tx_port3( struct sk_buff *skb, struct net_device *dev )
+{
+    DBG_TX( DbgInfo, "Tx on Port 3\n" );
+    return wl_tx( skb, dev, HCF_PORT_3 );
+} // wl_tx_port3
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_tx_port4()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      The handler routine for Tx over HCF_PORT_4.
+ *
+ *  PARAMETERS:
+ *
+ *      skb - a pointer to the sk_buff to transmit.
+ *      dev - a pointer to a net_device structure representing HCF_PORT_4.
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+int wl_tx_port4( struct sk_buff *skb, struct net_device *dev )
+{
+    DBG_TX( DbgInfo, "Tx on Port 4\n" );
+    return wl_tx( skb, dev, HCF_PORT_4 );
+} // wl_tx_port4
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_tx_port5()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      The handler routine for Tx over HCF_PORT_5.
+ *
+ *  PARAMETERS:
+ *
+ *      skb - a pointer to the sk_buff to transmit.
+ *      dev - a pointer to a net_device structure representing HCF_PORT_5.
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+int wl_tx_port5( struct sk_buff *skb, struct net_device *dev )
+{
+    DBG_TX( DbgInfo, "Tx on Port 5\n" );
+    return wl_tx( skb, dev, HCF_PORT_5 );
+} // wl_tx_port5
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_tx_port6()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      The handler routine for Tx over HCF_PORT_6.
+ *
+ *  PARAMETERS:
+ *
+ *      skb - a pointer to the sk_buff to transmit.
+ *      dev - a pointer to a net_device structure representing HCF_PORT_6.
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+int wl_tx_port6( struct sk_buff *skb, struct net_device *dev )
+{
+    DBG_TX( DbgInfo, "Tx on Port 6\n" );
+    return wl_tx( skb, dev, HCF_PORT_6 );
+} // wl_tx_port6
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_wds_device_alloc()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Create instances of net_device to represent the WDS ports, and register
+ *  the device's entry points in the net_device structure.
+ *
+ *  PARAMETERS:
+ *
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      N/A, but will place pointers to the allocated and initialized net_device
+ *      structs in the private adapter structure.
+ *
+ ******************************************************************************/
+void wl_wds_device_alloc( struct wl_private *lp )
+{
+    int count;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_wds_device_alloc" );
+    DBG_ENTER( DbgInfo );
+
+    /* WDS support requires additional net_device structs to be allocated,
+       so that user space apps can use these virtual devices to specify the
+       port on which to Tx/Rx */
+    for( count = 0; count < NUM_WDS_PORTS; count++ ) {
+        struct net_device *dev_wds = NULL;
+
+        dev_wds = kmalloc( sizeof( struct net_device ), GFP_KERNEL );
+        memset( dev_wds, 0, sizeof( struct net_device ));
+
+        ether_setup( dev_wds );
+
+        lp->wds_port[count].dev = dev_wds;
+
+        /* Re-use wl_init for all the devices, as it currently does nothing, but
+           is required. Re-use the stats/tx_timeout handler for all as well; the
+           WDS port which is requesting these operations can be determined by
+           the net_device pointer. Set the private member of all devices to point
+           to the same net_device struct; that way, all information gets
+           funnelled through the one "real" net_device. Name the WDS ports
+           "wds<n>" */
+        lp->wds_port[count].dev->init           = &wl_init;
+        lp->wds_port[count].dev->get_stats      = &wl_stats;
+        lp->wds_port[count].dev->tx_timeout     = &wl_tx_timeout;
+        lp->wds_port[count].dev->watchdog_timeo = TX_TIMEOUT;
+        lp->wds_port[count].dev->priv           = lp;
+
+        sprintf( lp->wds_port[count].dev->name, "wds%d", count );
+    }
+
+    /* Register the Tx handlers */
+    lp->wds_port[0].dev->hard_start_xmit = &wl_tx_port1;
+    lp->wds_port[1].dev->hard_start_xmit = &wl_tx_port2;
+    lp->wds_port[2].dev->hard_start_xmit = &wl_tx_port3;
+    lp->wds_port[3].dev->hard_start_xmit = &wl_tx_port4;
+    lp->wds_port[4].dev->hard_start_xmit = &wl_tx_port5;
+    lp->wds_port[5].dev->hard_start_xmit = &wl_tx_port6;
+
+    WL_WDS_NETIF_STOP_QUEUE( lp );
+
+    DBG_LEAVE( DbgInfo );
+    return;
+} // wl_wds_device_alloc
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_wds_device_dealloc()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Free instances of net_device structures used to support WDS.
+ *
+ *  PARAMETERS:
+ *
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_wds_device_dealloc( struct wl_private *lp )
+{
+    int count;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_wds_device_dealloc" );
+    DBG_ENTER( DbgInfo );
+
+    for( count = 0; count < NUM_WDS_PORTS; count++ ) {
+        struct net_device *dev_wds = NULL;
+
+        dev_wds = lp->wds_port[count].dev;
+
+        if( dev_wds != NULL ) {
+            if( dev_wds->flags & IFF_UP ) {
+                dev_close( dev_wds );
+                dev_wds->flags &= ~( IFF_UP | IFF_RUNNING );
+            }
+
+            kfree( dev_wds );
+            lp->wds_port[count].dev = NULL;
+        }
+    }
+
+    DBG_LEAVE( DbgInfo );
+    return;
+} // wl_wds_device_dealloc
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_wds_netif_start_queue()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Used to start the netif queues of all the "virtual" network devices
+ *      which repesent the WDS ports.
+ *
+ *  PARAMETERS:
+ *
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_wds_netif_start_queue( struct wl_private *lp )
+{
+    int count;
+    /*------------------------------------------------------------------------*/
+
+    if( lp != NULL ) {
+        for( count = 0; count < NUM_WDS_PORTS; count++ ) {
+            if( lp->wds_port[count].is_registered &&
+                lp->wds_port[count].netif_queue_on == FALSE ) {
+                netif_start_queue( lp->wds_port[count].dev );
+                lp->wds_port[count].netif_queue_on = TRUE;
+            }
+        }
+    }
+
+    return;
+} // wl_wds_netif_start_queue
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_wds_netif_stop_queue()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Used to stop the netif queues of all the "virtual" network devices
+ *      which repesent the WDS ports.
+ *
+ *  PARAMETERS:
+ *
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_wds_netif_stop_queue( struct wl_private *lp )
+{
+    int count;
+    /*------------------------------------------------------------------------*/
+
+    if( lp != NULL ) {
+        for( count = 0; count < NUM_WDS_PORTS; count++ ) {
+            if( lp->wds_port[count].is_registered &&
+                lp->wds_port[count].netif_queue_on == TRUE ) {
+                netif_stop_queue( lp->wds_port[count].dev );
+                lp->wds_port[count].netif_queue_on = FALSE;
+            }
+        }
+    }
+
+    return;
+} // wl_wds_netif_stop_queue
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_wds_netif_wake_queue()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Used to wake the netif queues of all the "virtual" network devices
+ *      which repesent the WDS ports.
+ *
+ *  PARAMETERS:
+ *
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_wds_netif_wake_queue( struct wl_private *lp )
+{
+    int count;
+    /*------------------------------------------------------------------------*/
+
+    if( lp != NULL ) {
+        for( count = 0; count < NUM_WDS_PORTS; count++ ) {
+            if( lp->wds_port[count].is_registered &&
+                lp->wds_port[count].netif_queue_on == FALSE ) {
+                netif_wake_queue( lp->wds_port[count].dev );
+                lp->wds_port[count].netif_queue_on = TRUE;
+            }
+        }
+    }
+
+    return;
+} // wl_wds_netif_wake_queue
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_wds_netif_carrier_on()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Used to signal the network layer that carrier is present on all of the
+ *      "virtual" network devices which repesent the WDS ports.
+ *
+ *  PARAMETERS:
+ *
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_wds_netif_carrier_on( struct wl_private *lp )
+{
+    int count;
+    /*------------------------------------------------------------------------*/
+
+    if( lp != NULL ) {
+        for( count = 0; count < NUM_WDS_PORTS; count++ ) {
+            if( lp->wds_port[count].is_registered ) {
+                netif_carrier_on( lp->wds_port[count].dev );
+            }
+        }
+    }
+
+    return;
+} // wl_wds_netif_carrier_on
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_wds_netif_carrier_off()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Used to signal the network layer that carrier is NOT present on all of
+ *      the "virtual" network devices which repesent the WDS ports.
+ *
+ *  PARAMETERS:
+ *
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_wds_netif_carrier_off( struct wl_private *lp )
+{
+    int count;
+    /*------------------------------------------------------------------------*/
+
+    if( lp != NULL ) {
+        for( count = 0; count < NUM_WDS_PORTS; count++ ) {
+            if( lp->wds_port[count].is_registered ) {
+                netif_carrier_off( lp->wds_port[count].dev );
+            }
+        }
+    }
+
+    return;
+} // wl_wds_netif_carrier_off
+/*============================================================================*/
+
+#endif  /* USE_WDS */
+
+#ifdef ENABLE_DMA
+/*******************************************************************************
+ *	wl_send_dma()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      The routine which performs data transmits when using busmaster DMA.
+ *
+ *  PARAMETERS:
+ *
+ *      lp   - a pointer to the device's wl_private struct.
+ *      skb  - a pointer to the network layer's data buffer.
+ *      port - the Hermes port on which to transmit.
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      1 on error
+ *
+ ******************************************************************************/
+int wl_send_dma( struct wl_private *lp, struct sk_buff *skb, int port )
+{
+    int         len;
+    DESC_STRCT *desc = NULL;
+    DESC_STRCT *desc_next = NULL;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_send_dma" );
+
+    if( lp == NULL )
+    {
+        DBG_ERROR( DbgInfo, "Private adapter struct is NULL\n" );
+        return FALSE;
+    }
+
+    if( lp->dev == NULL )
+    {
+        DBG_ERROR( DbgInfo, "net_device struct in wl_private is NULL\n" );
+        return FALSE;
+    }
+
+    /* AGAIN, ALL THE QUEUEING DONE HERE IN I/O MODE IS NOT PERFORMED */
+
+    if( skb == NULL )
+    {
+        DBG_WARNING (DbgInfo, "Nothing to send.\n");
+        return FALSE;
+    }
+
+    len = skb->len;
+
+    /* Get a free descriptor */
+    desc = wl_pci_dma_get_tx_packet( lp );
+
+    if( desc == NULL )
+    {
+        if( lp->netif_queue_on == TRUE ) {
+            netif_stop_queue( lp->dev );
+            WL_WDS_NETIF_STOP_QUEUE( lp );
+            lp->netif_queue_on = FALSE;
+
+            dev_kfree_skb( skb );
+            return 0;
+        }
+    }
+
+    SET_BUF_CNT( desc, /*HCF_DMA_FD_CNT*/HFS_ADDR_DEST );
+    SET_BUF_SIZE( desc, HCF_DMA_TX_BUF1_SIZE );
+
+    desc_next = desc->next_desc_addr;
+
+    if( desc_next->buf_addr == NULL )
+    {
+        DBG_ERROR( DbgInfo, "DMA descriptor buf_addr is NULL\n" );
+        return FALSE;
+    }
+
+    /* Copy the payload into the DMA packet */
+    memcpy( desc_next->buf_addr, skb->data, len );
+
+    SET_BUF_CNT( desc_next, len );
+    SET_BUF_SIZE( desc_next, HCF_MAX_PACKET_SIZE );
+
+    hcf_dma_tx_put( &( lp->hcfCtx ), desc, 0 );
+
+    /* Free the skb and perform queue cleanup, as the buffer was
+            transmitted successfully */
+    dev_kfree_skb( skb );
+
+    return TRUE;
+} // wl_send_dma
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_rx_dma()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      The routine which performs data reception when using busmaster DMA.
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the device's net_device structure.
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      1 on error
+ *
+ ******************************************************************************/
+int wl_rx_dma( struct net_device *dev )
+{
+    int                      port;
+    hcf_16                   pktlen;
+    hcf_16                   hfs_stat;
+    struct sk_buff          *skb;
+    struct wl_private       *lp = NULL;
+    DESC_STRCT              *desc, *desc_next;
+    //CFG_MB_INFO_RANGE2_STRCT x;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC("wl_rx")
+    DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
+
+    if((( lp = (struct wl_private *)dev->priv ) != NULL ) &&
+          !( lp->flags & WVLAN2_UIL_BUSY )) {
+
+#ifdef USE_RTS
+        if( lp->useRTS == 1 ) {
+            DBG_PRINT( "RTS: We're getting an Rx...\n" );
+            return -EIO;
+        }
+#endif  /* USE_RTS */
+
+        //if( lp->dma.status == 0 )
+        //{
+            desc = hcf_dma_rx_get( &( lp->hcfCtx ));
+
+            if( desc != NULL )
+            {
+                /* Check and see if we rcvd. a WMP frame */
+                /*
+                if((( *(hcf_8 *)&desc->buf_addr[HFS_STAT] ) &
+                    ( HFS_STAT_MSG_TYPE | HFS_STAT_ERR )) == HFS_STAT_WMP_MSG )
+                {
+                    DBG_TRACE( DbgInfo, "Got a WMP frame\n" );
+
+                    x.len = sizeof( CFG_MB_INFO_RANGE2_STRCT ) / sizeof( hcf_16 );
+				    x.typ = CFG_MB_INFO;
+				    x.base_typ = CFG_WMP;
+				    x.frag_cnt = 2;
+				    x.frag_buf[0].frag_len  = GET_BUF_CNT( descp ) / sizeof( hcf_16 );
+				    x.frag_buf[0].frag_addr = (hcf_8 *) descp->buf_addr ;
+				    x.frag_buf[1].frag_len  = ( GET_BUF_CNT( descp->next_desc_addr ) + 1 ) / sizeof( hcf_16 );
+				    x.frag_buf[1].frag_addr = (hcf_8 *) descp->next_desc_addr->buf_addr ;
+
+                    hcf_put_info( &( lp->hcfCtx ), (LTVP)&x );
+                }
+                */
+
+                desc_next = desc->next_desc_addr;
+
+                /* Make sure the buffer isn't empty */
+                if( GET_BUF_CNT( desc ) == 0 ) {
+                    DBG_WARNING( DbgInfo, "Buffer is empty!\n" );
+
+                    /* Give the descriptor back to the HCF */
+                    hcf_dma_rx_put( &( lp->hcfCtx ), desc );
+                    return -EIO;
+                }
+
+                /* Read the HFS_STAT register from the lookahead buffer */
+                hfs_stat = (hcf_16)( desc->buf_addr[HFS_STAT/2] );
+
+                /* Make sure the frame isn't bad */
+                if(( hfs_stat & HFS_STAT_ERR ) != HCF_SUCCESS )
+                {
+                    DBG_WARNING( DbgInfo, "HFS_STAT_ERROR (0x%x) in Rx Packet\n",
+                                desc->buf_addr[HFS_STAT/2] );
+
+                    /* Give the descriptor back to the HCF */
+                    hcf_dma_rx_put( &( lp->hcfCtx ), desc );
+                    return -EIO;
+                }
+
+                /* Determine what port this packet is for */
+                port = ( hfs_stat >> 8 ) & 0x0007;
+                DBG_RX( DbgInfo, "Rx frame for port %d\n", port );
+
+                if(( pktlen = GET_BUF_CNT( desc_next )) != 0 ) {
+                    if(( skb = ALLOC_SKB( pktlen )) != NULL ) {
+                        switch( port ) {
+#ifdef USE_WDS
+                        case 1:
+                        case 2:
+                        case 3:
+                        case 4:
+                        case 5:
+                        case 6:
+                            skb->dev = lp->wds_port[port-1].dev;
+                            break;
+#endif  /* USE_WDS */
+
+                        case 0:
+                        default:
+                            skb->dev = dev;
+                            break;
+                        }
+
+                        GET_PACKET_DMA( skb->dev, skb, pktlen );
+
+                        /* Give the descriptor back to the HCF */
+                        hcf_dma_rx_put( &( lp->hcfCtx ), desc );
+
+                        netif_rx( skb );
+
+                        if( port == 0 ) {
+                            lp->stats.rx_packets++;
+                            lp->stats.rx_bytes += pktlen;
+                        }
+#ifdef USE_WDS
+                        else
+                        {
+                            lp->wds_port[port-1].stats.rx_packets++;
+                            lp->wds_port[port-1].stats.rx_bytes += pktlen;
+                        }
+#endif  /* USE_WDS */
+
+                        dev->last_rx = jiffies;
+
+                    } else {
+                        DBG_ERROR( DbgInfo, "Could not alloc skb\n" );
+
+                        if( port == 0 )
+	                    {
+	                        lp->stats.rx_dropped++;
+	                    }
+#ifdef USE_WDS
+                        else
+                        {
+                            lp->wds_port[port-1].stats.rx_dropped++;
+                        }
+#endif  /* USE_WDS */
+                    }
+                }
+            }
+        //}
+    }
+
+    return 0;
+} // wl_rx_dma
+/*============================================================================*/
+#endif  // ENABLE_DMA
diff --git a/drivers/staging/wlags49_h2/wl_netdev.h b/drivers/staging/wlags49_h2/wl_netdev.h
new file mode 100644
index 0000000..632ab2e
--- /dev/null
+++ b/drivers/staging/wlags49_h2/wl_netdev.h
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Agere Systems Inc.
+ * Wireless device driver for Linux (wlags49).
+ *
+ * Copyright (c) 1998-2003 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * Initially developed by TriplePoint, Inc.
+ *   http://www.triplepoint.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ *   Header describing information required by the network layerentry points
+ *   into the driver.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2003 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following Disclaimer as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ ******************************************************************************/
+
+#ifndef __WL_NETDEV_H__
+#define __WL_NETDEV_H__
+
+
+
+
+/*******************************************************************************
+ *  function prototypes
+ ******************************************************************************/
+int wl_init( struct net_device *dev );
+
+int wl_config( struct net_device *dev, struct ifmap *map );
+
+struct net_device *wl_device_alloc( void );
+
+void wl_device_dealloc( struct net_device *dev );
+
+int wl_open( struct net_device *dev );
+
+int wl_close( struct net_device *dev );
+
+int wl_ioctl( struct net_device *dev, struct ifreq *rq, int cmd );
+
+int wl_tx( struct sk_buff *skb, struct net_device *dev, int port );
+
+int wl_send( struct wl_private *lp );
+
+int wl_rx( struct net_device *dev );
+
+void wl_tx_timeout( struct net_device *dev );
+
+struct net_device_stats *wl_stats( struct net_device *dev );
+
+
+#ifdef ENABLE_DMA
+int wl_send_dma( struct wl_private *lp, struct sk_buff *skb, int port );
+int wl_rx_dma( struct net_device *dev );
+#endif
+
+#ifdef NEW_MULTICAST
+void wl_multicast( struct net_device *dev );
+#else
+void wl_multicast( struct net_device *dev, int num_addrs, void *addrs );
+#endif // NEW_MULTICAST
+
+
+int wl_tx_port0( struct sk_buff *skb, struct net_device *dev );
+
+
+#ifdef USE_WDS
+
+int wl_tx_port1( struct sk_buff *skb, struct net_device *dev );
+int wl_tx_port2( struct sk_buff *skb, struct net_device *dev );
+int wl_tx_port3( struct sk_buff *skb, struct net_device *dev );
+int wl_tx_port4( struct sk_buff *skb, struct net_device *dev );
+int wl_tx_port5( struct sk_buff *skb, struct net_device *dev );
+int wl_tx_port6( struct sk_buff *skb, struct net_device *dev );
+
+void wl_wds_device_alloc( struct wl_private *lp );
+void wl_wds_device_dealloc( struct wl_private *lp );
+void wl_wds_netif_start_queue( struct wl_private *lp );
+void wl_wds_netif_stop_queue( struct wl_private *lp );
+void wl_wds_netif_wake_queue( struct wl_private *lp );
+void wl_wds_netif_carrier_on( struct wl_private *lp );
+void wl_wds_netif_carrier_off( struct wl_private *lp );
+
+#endif  /* USE_WDS */
+
+
+#ifdef USE_WDS
+
+#define WL_WDS_DEVICE_ALLOC( ARG )      wl_wds_device_alloc( ARG )
+#define WL_WDS_DEVICE_DEALLOC( ARG )    wl_wds_device_dealloc( ARG )
+#define WL_WDS_NETIF_START_QUEUE( ARG ) wl_wds_netif_start_queue( ARG )
+#define WL_WDS_NETIF_STOP_QUEUE( ARG )  wl_wds_netif_stop_queue( ARG )
+#define WL_WDS_NETIF_WAKE_QUEUE( ARG )  wl_wds_netif_wake_queue( ARG )
+#define WL_WDS_NETIF_CARRIER_ON( ARG )  wl_wds_netif_carrier_on( ARG )
+#define WL_WDS_NETIF_CARRIER_OFF( ARG ) wl_wds_netif_carrier_off( ARG )
+
+#else
+
+#define WL_WDS_DEVICE_ALLOC( ARG )
+#define WL_WDS_DEVICE_DEALLOC( ARG )
+#define WL_WDS_NETIF_START_QUEUE( ARG )
+#define WL_WDS_NETIF_STOP_QUEUE( ARG )
+#define WL_WDS_NETIF_WAKE_QUEUE( ARG )
+#define WL_WDS_NETIF_CARRIER_ON( ARG )
+#define WL_WDS_NETIF_CARRIER_OFF( ARG )
+
+#endif  /* USE_WDS */
+
+
+#endif  // __WL_NETDEV_H__
diff --git a/drivers/staging/wlags49_h2/wl_pci.c b/drivers/staging/wlags49_h2/wl_pci.c
new file mode 100644
index 0000000..a3db111
--- /dev/null
+++ b/drivers/staging/wlags49_h2/wl_pci.c
@@ -0,0 +1,1581 @@
+/*******************************************************************************
+ * Agere Systems Inc.
+ * Wireless device driver for Linux (wlags49).
+ *
+ * Copyright (c) 1998-2003 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * Initially developed by TriplePoint, Inc.
+ *   http://www.triplepoint.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ *   This file contains processing and initialization specific to PCI/miniPCI
+ *   devices.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2003 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following Disclaimer as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ ******************************************************************************/
+
+/*******************************************************************************
+ * include files
+ ******************************************************************************/
+#include <wireless/wl_version.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+//#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/in.h>
+#include <linux/delay.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/uaccess.h>
+
+#include <linux/ethtool.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/ioport.h>
+
+#include <hcf/debug.h>
+
+#include <hcf.h>
+#include <dhf.h>
+#include <hcfdef.h>
+
+#include <wireless/wl_if.h>
+#include <wireless/wl_internal.h>
+#include <wireless/wl_util.h>
+#include <wireless/wl_main.h>
+#include <wireless/wl_netdev.h>
+#include <wireless/wl_pci.h>
+
+
+/*******************************************************************************
+ * global variables
+ ******************************************************************************/
+#if DBG
+extern dbg_info_t *DbgInfo;
+#endif  // DBG
+
+/* define the PCI device Table Cardname and id tables */
+enum hermes_pci_versions {
+	CH_Agere_Systems_Mini_PCI_V1 = 0,
+};
+
+static struct pci_device_id wl_pci_tbl[] __devinitdata = {
+	{ WL_LKM_PCI_VENDOR_ID, WL_LKM_PCI_DEVICE_ID_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Agere_Systems_Mini_PCI_V1 },
+    { WL_LKM_PCI_VENDOR_ID, WL_LKM_PCI_DEVICE_ID_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Agere_Systems_Mini_PCI_V1 },
+    { WL_LKM_PCI_VENDOR_ID, WL_LKM_PCI_DEVICE_ID_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Agere_Systems_Mini_PCI_V1 },
+	{ }			/* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(pci, wl_pci_tbl);
+
+/*******************************************************************************
+ * function prototypes
+ ******************************************************************************/
+int __devinit wl_pci_probe( struct pci_dev *pdev,
+                                const struct pci_device_id *ent );
+void __devexit wl_pci_remove(struct pci_dev *pdev);
+int wl_pci_setup( struct pci_dev *pdev );
+void wl_pci_enable_cardbus_interrupts( struct pci_dev *pdev );
+
+#ifdef ENABLE_DMA
+int wl_pci_dma_alloc( struct pci_dev *pdev, struct wl_private *lp );
+int wl_pci_dma_free( struct pci_dev *pdev, struct wl_private *lp );
+int wl_pci_dma_alloc_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
+                                DESC_STRCT **desc );
+int wl_pci_dma_free_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
+                                DESC_STRCT **desc );
+int wl_pci_dma_alloc_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
+                                DESC_STRCT **desc );
+int wl_pci_dma_free_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
+                                DESC_STRCT **desc );
+int wl_pci_dma_alloc_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
+                                   DESC_STRCT **desc, int size );
+int wl_pci_dma_free_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
+                                   DESC_STRCT **desc );
+int wl_pci_dma_alloc_desc( struct pci_dev *pdev, struct wl_private *lp,
+                           DESC_STRCT **desc );
+int wl_pci_dma_free_desc( struct pci_dev *pdev, struct wl_private *lp,
+                           DESC_STRCT **desc );
+int wl_pci_dma_alloc_buf( struct pci_dev *pdev, struct wl_private *lp,
+                          DESC_STRCT *desc, int size );
+int wl_pci_dma_free_buf( struct pci_dev *pdev, struct wl_private *lp,
+                          DESC_STRCT *desc );
+
+void wl_pci_dma_hcf_reclaim_rx( struct wl_private *lp );
+#endif  // ENABLE_DMA
+
+/*******************************************************************************
+ * PCI module function registration
+ ******************************************************************************/
+static struct pci_driver wl_driver =
+{
+	name:		MODULE_NAME,
+    id_table:	wl_pci_tbl,
+	probe:		wl_pci_probe,
+	remove:		__devexit_p(wl_pci_remove),
+    suspend:    NULL,
+    resume:     NULL,
+};
+
+/*******************************************************************************
+ *	wl_adapter_init_module()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Called by init_module() to perform PCI-specific driver initialization.
+ *
+ *  PARAMETERS:
+ *
+ *      N/A
+ *
+ *  RETURNS:
+ *
+ *      0
+ *
+ ******************************************************************************/
+int wl_adapter_init_module( void )
+{
+    int result;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_adapter_init_module()" );
+    DBG_ENTER( DbgInfo );
+    DBG_TRACE( DbgInfo, "wl_adapter_init_module() -- PCI\n" );
+
+    result = pci_register_driver( &wl_driver ); //;?replace with pci_module_init, Rubini pg 490
+	//;? why not do something with the result
+
+    DBG_LEAVE( DbgInfo );
+    return 0;
+} // wl_adapter_init_module
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_adapter_cleanup_module()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Called by cleanup_module() to perform PCI-specific driver cleanup.
+ *
+ *  PARAMETERS:
+ *
+ *      N/A
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_adapter_cleanup_module( void )
+{
+	//;?how comes wl_adapter_cleanup_module is located in a seemingly pci specific module
+    DBG_FUNC( "wl_adapter_cleanup_module" );
+    DBG_ENTER( DbgInfo );
+
+	//;?DBG_TRACE below feels like nearly redundant in the light of DBG_ENTER above
+    DBG_TRACE( DbgInfo, "wl_adapter_cleanup_module() -- PCI\n" );
+
+    pci_unregister_driver( &wl_driver );
+
+    DBG_LEAVE( DbgInfo );
+    return;
+} // wl_adapter_cleanup_module
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_adapter_insert()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Called by wl_pci_probe() to continue the process of device insertion.
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the device's net_device structure
+ *
+ *  RETURNS:
+ *
+ *      TRUE or FALSE
+ *
+ ******************************************************************************/
+int wl_adapter_insert( struct net_device *dev )
+{
+    int result = FALSE;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_adapter_insert" );
+    DBG_ENTER( DbgInfo );
+
+    DBG_TRACE( DbgInfo, "wl_adapter_insert() -- PCI\n" );
+
+    if( dev == NULL ) {
+        DBG_ERROR( DbgInfo, "net_device pointer is NULL!!!\n" );
+    } else if( dev->priv == NULL ) {
+        DBG_ERROR( DbgInfo, "wl_private pointer is NULL!!!\n" );
+    } else if( wl_insert( dev ) ) { /* Perform remaining device initialization */
+		result = TRUE;
+	} else {
+        DBG_TRACE( DbgInfo, "wl_insert() FAILED\n" );
+    }
+    DBG_LEAVE( DbgInfo );
+    return result;
+} // wl_adapter_insert
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_adapter_open()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Open the device.
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the device's net_device structure
+ *
+ *  RETURNS:
+ *
+ *      an HCF status code
+ *
+ ******************************************************************************/
+int wl_adapter_open( struct net_device *dev )
+{
+    int         result = 0;
+    int         hcf_status = HCF_SUCCESS;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_adapter_open" );
+    DBG_ENTER( DbgInfo );
+
+    DBG_TRACE( DbgInfo, "wl_adapter_open() -- PCI\n" );
+
+    hcf_status = wl_open( dev );
+
+    if( hcf_status != HCF_SUCCESS ) {
+        result = -ENODEV;
+    }
+
+    DBG_LEAVE( DbgInfo );
+    return result;
+} // wl_adapter_open
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_adapter_close()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Close the device
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the device's net_device structure
+ *
+ *  RETURNS:
+ *
+ *      0
+ *
+ ******************************************************************************/
+int wl_adapter_close( struct net_device *dev )
+{
+    DBG_FUNC( "wl_adapter_close" );
+    DBG_ENTER( DbgInfo );
+
+    DBG_TRACE( DbgInfo, "wl_adapter_close() -- PCI\n" );
+    DBG_TRACE( DbgInfo, "%s: Shutting down adapter.\n", dev->name );
+
+    wl_close( dev );
+
+    DBG_LEAVE( DbgInfo );
+    return 0;
+} // wl_adapter_close
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_adapter_is_open()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Check whether this device is open. Returns
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the device's net_device structure
+ *
+ *  RETURNS:
+ *
+ *      nonzero if device is open.
+ *
+ ******************************************************************************/
+int wl_adapter_is_open( struct net_device *dev )
+{
+    /* This function is used in PCMCIA to check the status of the 'open' field
+       in the dev_link_t structure associated with a network device. There
+       doesn't seem to be an analog to this for PCI, and checking the status
+       contained in the net_device structure doesn't have the same effect.
+       For now, return TRUE, but find out if this is necessary for PCI. */
+
+    return TRUE;
+} // wl_adapter_is_open
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_pci_probe()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Registered in the pci_driver structure, this function is called when the
+ *  PCI subsystem finds a new PCI device which matches the infomation contained
+ *  in the pci_device_id table.
+ *
+ *  PARAMETERS:
+ *
+ *      pdev    - a pointer to the device's pci_dev structure
+ *      ent     - this device's entry in the pci_device_id table
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int __devinit wl_pci_probe( struct pci_dev *pdev,
+                                const struct pci_device_id *ent )
+{
+    int result;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_pci_probe" );
+    DBG_ENTER( DbgInfo );
+	DBG_PRINT( "%s\n", VERSION_INFO );
+
+    result = wl_pci_setup( pdev );
+
+    DBG_LEAVE( DbgInfo );
+
+    return result;
+} // wl_pci_probe
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_pci_remove()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Registered in the pci_driver structure, this function is called when the
+ *  PCI subsystem detects that a PCI device which matches the infomation
+ *  contained in the pci_device_id table has been removed.
+ *
+ *  PARAMETERS:
+ *
+ *      pdev - a pointer to the device's pci_dev structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void __devexit wl_pci_remove(struct pci_dev *pdev)
+{
+    struct net_device       *dev = NULL;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_pci_remove" );
+    DBG_ENTER( DbgInfo );
+
+    /* Make sure the pci_dev pointer passed in is valid */
+    if( pdev == NULL ) {
+        DBG_ERROR( DbgInfo, "PCI subsys passed in an invalid pci_dev pointer\n" );
+        return;
+    }
+
+    dev = (struct net_device *)pci_get_drvdata( pdev );
+    if( dev == NULL ) {
+        DBG_ERROR( DbgInfo, "Could not retrieve net_device structure\n" );
+        return;
+    }
+
+    /* Perform device cleanup */
+    wl_remove( dev );
+    free_irq( dev->irq, dev );
+
+#ifdef ENABLE_DMA
+    wl_pci_dma_free( pdev, (struct wl_private *)dev->priv );
+#endif
+
+    wl_device_dealloc( dev );
+
+    DBG_LEAVE( DbgInfo );
+    return;
+} // wl_pci_remove
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_pci_setup()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Called by wl_pci_probe() to begin a device's initialization process.
+ *
+ *  PARAMETERS:
+ *
+ *      pdev - a pointer to the device's pci_dev structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wl_pci_setup( struct pci_dev *pdev )
+{
+    int                 result = 0;
+    struct net_device   *dev = NULL;
+    struct wl_private   *lp = NULL;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_pci_setup" );
+    DBG_ENTER( DbgInfo );
+
+    /* Make sure the pci_dev pointer passed in is valid */
+    if( pdev == NULL ) {
+        DBG_ERROR( DbgInfo, "PCI subsys passed in an invalid pci_dev pointer\n" );
+        return -ENODEV;
+    }
+
+    result = pci_enable_device( pdev );
+    if( result != 0 ) {
+        DBG_ERROR( DbgInfo, "pci_enable_device() failed\n" );
+        DBG_LEAVE( DbgInfo );
+        return result;
+    }
+
+    /* We found our device! Let's register it with the system */
+    DBG_TRACE( DbgInfo, "Found our device, now registering\n" );
+    dev = wl_device_alloc( );
+    if( dev == NULL ) {
+        DBG_ERROR( DbgInfo, "Could not register device!!!\n" );
+        DBG_LEAVE( DbgInfo );
+        return -ENOMEM;
+    }
+
+    /* Make sure that space was allocated for our private adapter struct */
+    if( dev->priv == NULL ) {
+        DBG_ERROR( DbgInfo, "Private adapter struct was not allocated!!!\n" );
+        DBG_LEAVE( DbgInfo );
+        return -ENOMEM;
+    }
+
+#ifdef ENABLE_DMA
+    /* Allocate DMA Descriptors */
+    if( wl_pci_dma_alloc( pdev, (struct wl_private *)dev->priv ) < 0 ) {
+        DBG_ERROR( DbgInfo, "Could not allocate DMA descriptor memory!!!\n" );
+        DBG_LEAVE( DbgInfo );
+        return -ENOMEM;
+    }
+#endif
+
+    /* Register our private adapter structure with PCI */
+    pci_set_drvdata( pdev, dev );
+
+    /* Fill out bus specific information in the net_device struct */
+    dev->irq = pdev->irq;
+    SET_MODULE_OWNER( dev );
+
+    DBG_TRACE( DbgInfo, "Device Base Address: %#03lx\n", pdev->resource[0].start );
+	dev->base_addr = pdev->resource[0].start;
+
+    /* Initialize our device here */
+    if( !wl_adapter_insert( dev )) {
+        DBG_ERROR( DbgInfo, "wl_adapter_insert() FAILED!!!\n" );
+        wl_device_dealloc( dev );
+        DBG_LEAVE( DbgInfo );
+        return -EINVAL;
+    }
+
+    /* Register our ISR */
+    DBG_TRACE( DbgInfo, "Registering ISR...\n" );
+
+    result = request_irq(dev->irq, wl_isr, SA_SHIRQ, dev->name, dev);
+    if( result ) {
+        DBG_WARNING( DbgInfo, "Could not register ISR!!!\n" );
+        DBG_LEAVE( DbgInfo );
+        return result;
+	}
+
+    /* Make sure interrupts are enabled properly for CardBus */
+    lp = (struct wl_private *)dev->priv;
+
+    if( lp->hcfCtx.IFB_BusType == CFG_NIC_BUS_TYPE_CARDBUS ||
+	    lp->hcfCtx.IFB_BusType == CFG_NIC_BUS_TYPE_PCI 		) {
+        DBG_TRACE( DbgInfo, "This is a PCI/CardBus card, enable interrupts\n" );
+        wl_pci_enable_cardbus_interrupts( pdev );
+    }
+
+    /* Enable bus mastering */
+    pci_set_master( pdev );
+
+    DBG_LEAVE( DbgInfo );
+    return 0;
+} // wl_pci_setup
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_pci_enable_cardbus_interrupts()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Called by wl_pci_setup() to enable interrupts on a CardBus device. This
+ *  is done by writing bit 15 to the function event mask register. This
+ *  CardBus-specific register is located in BAR2 (counting from BAR0), in memory
+ *  space at byte offset 1f4 (7f4 for WARP).
+ *
+ *  PARAMETERS:
+ *
+ *      pdev - a pointer to the device's pci_dev structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_pci_enable_cardbus_interrupts( struct pci_dev *pdev )
+{
+    u32                 bar2_reg;
+    u32                 mem_addr_bus;
+    u32                 func_evt_mask_reg;
+    void                *mem_addr_kern = NULL;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_pci_enable_cardbus_interrupts" );
+    DBG_ENTER( DbgInfo );
+
+    /* Initialize to known bad values */
+    bar2_reg = 0xdeadbeef;
+    mem_addr_bus = 0xdeadbeef;
+
+    /* Read the BAR2 register; this register contains the base address of the
+       memory region where the function event mask register lives */
+    pci_read_config_dword( pdev, PCI_BASE_ADDRESS_2, &bar2_reg );
+    mem_addr_bus = bar2_reg & PCI_BASE_ADDRESS_MEM_MASK;
+
+    /* Once the base address is obtained, remap the memory region to kernel
+       space so we can retrieve the register */
+    mem_addr_kern = ioremap( mem_addr_bus, 0x200 );
+
+#ifdef HERMES25
+#define REG_OFFSET  0x07F4
+#else
+#define REG_OFFSET  0x01F4
+#endif // HERMES25
+
+#define BIT15       0x8000
+
+    /* Retrieve the functional event mask register, enable interrupts by
+       setting Bit 15, and write back the value */
+    func_evt_mask_reg = *(u32 *)( mem_addr_kern + REG_OFFSET );
+    func_evt_mask_reg |= BIT15;
+    *(u32 *)( mem_addr_kern + REG_OFFSET ) = func_evt_mask_reg;
+
+    /* Once complete, unmap the region and exit */
+    iounmap( mem_addr_kern );
+
+    DBG_LEAVE( DbgInfo );
+    return;
+} // wl_pci_enable_cardbus_interrupts
+/*============================================================================*/
+
+#ifdef ENABLE_DMA
+/*******************************************************************************
+ *	wl_pci_dma_alloc()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Allocates all resources needed for PCI/CardBus DMA operation
+ *
+ *  PARAMETERS:
+ *
+ *      pdev - a pointer to the device's pci_dev structure
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wl_pci_dma_alloc( struct pci_dev *pdev, struct wl_private *lp )
+{
+    int i;
+    int status = 0;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_pci_dma_alloc" );
+    DBG_ENTER( DbgInfo );
+
+//     lp->dma.tx_rsc_ind = lp->dma.rx_rsc_ind = 0;
+//
+//     /* Alloc for the Tx chain and its reclaim descriptor */
+//     for( i = 0; i < NUM_TX_DESC; i++ ) {
+//         status = wl_pci_dma_alloc_tx_packet( pdev, lp, &lp->dma.tx_packet[i] );
+//         if( status == 0 ) {
+//             DBG_PRINT( "lp->dma.tx_packet[%d] :                 0x%p\n", i, lp->dma.tx_packet[i] );
+//             DBG_PRINT( "lp->dma.tx_packet[%d]->next_desc_addr : 0x%p\n", i, lp->dma.tx_packet[i]->next_desc_addr );
+//             lp->dma.tx_rsc_ind++;
+//         } else {
+//             DBG_ERROR( DbgInfo, "Could not alloc DMA Tx Packet\n" );
+//             break;
+//         }
+//     }
+//     if( status == 0 ) {
+//         status = wl_pci_dma_alloc_desc( pdev, lp, &lp->dma.tx_reclaim_desc );
+//         DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
+//     }
+//     /* Alloc for the Rx chain and its reclaim descriptor */
+//     if( status == 0 ) {
+//         for( i = 0; i < NUM_RX_DESC; i++ ) {
+//             status = wl_pci_dma_alloc_rx_packet( pdev, lp, &lp->dma.rx_packet[i] );
+//             if( status == 0 ) {
+//                 DBG_PRINT( "lp->dma.rx_packet[%d]                 : 0x%p\n", i, lp->dma.rx_packet[i] );
+//                 DBG_PRINT( "lp->dma.rx_packet[%d]->next_desc_addr : 0x%p\n", i, lp->dma.rx_packet[i]->next_desc_addr );
+//                 lp->dma.rx_rsc_ind++;
+//             } else {
+//                 DBG_ERROR( DbgInfo, "Could not alloc DMA Rx Packet\n" );
+//                 break;
+//             }
+//         }
+//     }
+//     if( status == 0 ) {
+//         status = wl_pci_dma_alloc_desc( pdev, lp, &lp->dma.rx_reclaim_desc );
+//         DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
+//     }
+//     /* Store status, as host should not call HCF functions if this fails */
+//     lp->dma.status = status;  //;?all useages of dma.status have been commented out
+//     DBG_LEAVE( DbgInfo );
+    return status;
+} // wl_pci_dma_alloc
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_pci_dma_free()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Deallocated all resources needed for PCI/CardBus DMA operation
+ *
+ *  PARAMETERS:
+ *
+ *      pdev - a pointer to the device's pci_dev structure
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wl_pci_dma_free( struct pci_dev *pdev, struct wl_private *lp )
+{
+    int i;
+    int status = 0;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_pci_dma_free" );
+    DBG_ENTER( DbgInfo );
+
+    /* Reclaim all Rx packets that were handed over to the HCF */
+    /* Do I need to do this? Before this free is called, I've already disabled
+       the port which will call wl_pci_dma_hcf_reclaim */
+    //if( lp->dma.status == 0 )
+    //{
+    //    wl_pci_dma_hcf_reclaim( lp );
+    //}
+
+    /* Free everything needed for DMA Rx */
+    for( i = 0; i < NUM_RX_DESC; i++ ) {
+        if( lp->dma.rx_packet[i] ) {
+            status = wl_pci_dma_free_rx_packet( pdev, lp, &lp->dma.rx_packet[i] );
+            if( status != 0 ) {
+                DBG_WARNING( DbgInfo, "Problem freeing Rx packet\n" );
+            }
+        }
+    }
+    lp->dma.rx_rsc_ind = 0;
+
+    if( lp->dma.rx_reclaim_desc ) {
+        status = wl_pci_dma_free_desc( pdev, lp, &lp->dma.rx_reclaim_desc );
+        if( status != 0 ) {
+            DBG_WARNING( DbgInfo, "Problem freeing Rx reclaim descriptor\n" );
+        }
+    }
+
+    /* Free everything needed for DMA Tx */
+    for( i = 0; i < NUM_TX_DESC; i++ ) {
+        if( lp->dma.tx_packet[i] ) {
+            status = wl_pci_dma_free_tx_packet( pdev, lp, &lp->dma.tx_packet[i] );
+            if( status != 0 ) {
+                DBG_WARNING( DbgInfo, "Problem freeing Tx packet\n" );
+            }
+        }
+    }
+    lp->dma.tx_rsc_ind = 0;
+
+    if( lp->dma.tx_reclaim_desc ) {
+        status = wl_pci_dma_free_desc( pdev, lp, &lp->dma.tx_reclaim_desc );
+        if( status != 0 ) {
+            DBG_WARNING( DbgInfo, "Problem freeing Tx reclaim descriptor\n" );
+        }
+    }
+
+    DBG_LEAVE( DbgInfo );
+    return status;
+} // wl_pci_dma_free
+
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_pci_dma_alloc_tx_packet()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Allocates a single Tx packet, consisting of several descriptors and
+ *      buffers. Data to transmit is first copied into the 'payload' buffer
+ *      before being transmitted.
+ *
+ *  PARAMETERS:
+ *
+ *      pdev    - a pointer to the device's pci_dev structure
+ *      lp      - the device's private adapter structure
+ *      desc    - a pointer which will reference the descriptor to be alloc'd.
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wl_pci_dma_alloc_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
+                                DESC_STRCT **desc )
+{
+//     int status = 0;
+//     /*------------------------------------------------------------------------*/
+//
+//     if( desc == NULL ) {
+//         status = -EFAULT;
+//     }
+//     if( status == 0 ) {
+//         status = wl_pci_dma_alloc_desc_and_buf( pdev, lp, desc,
+//                                                 HCF_DMA_TX_BUF1_SIZE );
+//
+//         if( status == 0 ) {
+//             status = wl_pci_dma_alloc_desc_and_buf( pdev, lp,
+//                                                     &( (*desc)->next_desc_addr ),
+//                                                     HCF_MAX_PACKET_SIZE );
+//         }
+//     }
+//     if( status == 0 ) {
+//         (*desc)->next_desc_phys_addr = (*desc)->next_desc_addr->desc_phys_addr;
+//     }
+//     return status;
+} // wl_pci_dma_alloc_tx_packet
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_pci_dma_free_tx_packet()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Frees a single Tx packet, described in the corresponding alloc function.
+ *
+ *  PARAMETERS:
+ *
+ *      pdev    - a pointer to the device's pci_dev structure
+ *      lp      - the device's private adapter structure
+ *      desc    - a pointer which will reference the descriptor to be alloc'd.
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wl_pci_dma_free_tx_packet( struct pci_dev *pdev, struct wl_private *lp,
+                                DESC_STRCT **desc )
+{
+    int status = 0;
+    /*------------------------------------------------------------------------*/
+
+    if( *desc == NULL ) {
+        DBG_PRINT( "Null descriptor\n" );
+        status = -EFAULT;
+    }
+	//;?the "limited" NDIS strategy, assuming a frame consists ALWAYS out of 2
+	//descriptors, make this robust
+    if( status == 0 && (*desc)->next_desc_addr ) {
+        status = wl_pci_dma_free_desc_and_buf( pdev, lp, &(*desc)->next_desc_addr );
+    }
+    if( status == 0 ) {
+        status = wl_pci_dma_free_desc_and_buf( pdev, lp, desc );
+    }
+    return status;
+} // wl_pci_dma_free_tx_packet
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_pci_dma_alloc_rx_packet()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Allocates a single Rx packet, consisting of two descriptors and one
+ *      contiguous buffer. THe buffer starts with the hermes-specific header.
+ *      One descriptor points at the start, the other at offset 0x3a of the
+ *      buffer.
+ *
+ *  PARAMETERS:
+ *
+ *      pdev    - a pointer to the device's pci_dev structure
+ *      lp      - the device's private adapter structure
+ *      desc    - a pointer which will reference the descriptor to be alloc'd.
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wl_pci_dma_alloc_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
+                                DESC_STRCT **desc )
+{
+    int         status = 0;
+    DESC_STRCT  *p;
+    /*------------------------------------------------------------------------*/
+
+//     if( desc == NULL ) {
+//         status = -EFAULT;
+//     }
+// 	//;?the "limited" NDIS strategy, assuming a frame consists ALWAYS out of 2
+// 	//descriptors, make this robust
+//     if( status == 0 ) {
+//         status = wl_pci_dma_alloc_desc( pdev, lp, desc );
+// 	}
+//     if( status == 0 ) {
+//         status = wl_pci_dma_alloc_buf( pdev, lp, *desc, HCF_MAX_PACKET_SIZE );
+//     }
+//     if( status == 0 ) {
+//         status = wl_pci_dma_alloc_desc( pdev, lp, &p );
+//     }
+//     if( status == 0 ) {
+//         /* Size of 1st descriptor becomes 0x3a bytes */
+//         SET_BUF_SIZE( *desc, HCF_DMA_RX_BUF1_SIZE );
+//
+//         /* Make 2nd descriptor point at offset 0x3a of the buffer */
+//         SET_BUF_SIZE( p, ( HCF_MAX_PACKET_SIZE - HCF_DMA_RX_BUF1_SIZE ));
+//         p->buf_addr       = (*desc)->buf_addr + HCF_DMA_RX_BUF1_SIZE;
+//         p->buf_phys_addr  = (*desc)->buf_phys_addr + HCF_DMA_RX_BUF1_SIZE;
+//         p->next_desc_addr = NULL;
+//
+//         /* Chain 2nd descriptor to 1st descriptor */
+//         (*desc)->next_desc_addr      = p;
+//         (*desc)->next_desc_phys_addr = p->desc_phys_addr;
+//     }
+
+    return status;
+} // wl_pci_dma_alloc_rx_packet
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_pci_dma_free_rx_packet()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Frees a single Rx packet, described in the corresponding alloc function.
+ *
+ *  PARAMETERS:
+ *
+ *      pdev    - a pointer to the device's pci_dev structure
+ *      lp      - the device's private adapter structure
+ *      desc    - a pointer which will reference the descriptor to be alloc'd.
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wl_pci_dma_free_rx_packet( struct pci_dev *pdev, struct wl_private *lp,
+                                DESC_STRCT **desc )
+{
+    int status = 0;
+    DESC_STRCT *p;
+    /*------------------------------------------------------------------------*/
+
+    if( *desc == NULL ) {
+        status = -EFAULT;
+    }
+    if( status == 0 ) {
+        p = (*desc)->next_desc_addr;
+
+        /* Free the 2nd descriptor */
+        if( p != NULL ) {
+            p->buf_addr      = NULL;
+            p->buf_phys_addr = 0;
+
+            status = wl_pci_dma_free_desc( pdev, lp, &p );
+        }
+    }
+
+    /* Free the buffer and 1st descriptor */
+    if( status == 0 ) {
+        SET_BUF_SIZE( *desc, HCF_MAX_PACKET_SIZE );
+        status = wl_pci_dma_free_desc_and_buf( pdev, lp, desc );
+    }
+    return status;
+} // wl_pci_dma_free_rx_packet
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_pci_dma_alloc_desc_and_buf()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Allocates a DMA descriptor and buffer, and associates them with one
+ *      another.
+ *
+ *  PARAMETERS:
+ *
+ *      pdev  - a pointer to the device's pci_dev structure
+ *      lp    - the device's private adapter structure
+ *      desc  - a pointer which will reference the descriptor to be alloc'd
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wl_pci_dma_alloc_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
+                                   DESC_STRCT **desc, int size )
+{
+    int status = 0;
+    /*------------------------------------------------------------------------*/
+
+//     if( desc == NULL ) {
+//         status = -EFAULT;
+//     }
+//     if( status == 0 ) {
+//         status = wl_pci_dma_alloc_desc( pdev, lp, desc );
+//
+//         if( status == 0 ) {
+//             status = wl_pci_dma_alloc_buf( pdev, lp, *desc, size );
+//         }
+//     }
+    return status;
+} // wl_pci_dma_alloc_desc_and_buf
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_pci_dma_free_desc_and_buf()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Frees a DMA descriptor and associated buffer.
+ *
+ *  PARAMETERS:
+ *
+ *      pdev  - a pointer to the device's pci_dev structure
+ *      lp    - the device's private adapter structure
+ *      desc  - a pointer which will reference the descriptor to be alloc'd
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wl_pci_dma_free_desc_and_buf( struct pci_dev *pdev, struct wl_private *lp,
+                                   DESC_STRCT **desc )
+{
+    int status = 0;
+    /*------------------------------------------------------------------------*/
+
+    if( desc == NULL ) {
+        status = -EFAULT;
+    }
+    if( status == 0 && *desc == NULL ) {
+        status = -EFAULT;
+    }
+    if( status == 0 ) {
+        status = wl_pci_dma_free_buf( pdev, lp, *desc );
+
+        if( status == 0 ) {
+            status = wl_pci_dma_free_desc( pdev, lp, desc );
+        }
+    }
+    return status;
+} // wl_pci_dma_free_desc_and_buf
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_pci_dma_alloc_desc()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Allocates one DMA descriptor in cache coherent memory.
+ *
+ *  PARAMETERS:
+ *
+ *      pdev - a pointer to the device's pci_dev structure
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wl_pci_dma_alloc_desc( struct pci_dev *pdev, struct wl_private *lp,
+                           DESC_STRCT **desc )
+{
+//     int         status = 0;
+//     dma_addr_t  pa;
+//     /*------------------------------------------------------------------------*/
+//
+//     DBG_FUNC( "wl_pci_dma_alloc_desc" );
+//     DBG_ENTER( DbgInfo );
+//
+//     if( desc == NULL ) {
+//         status = -EFAULT;
+//     }
+//     if( status == 0 ) {
+//         *desc = pci_alloc_consistent( pdev, sizeof( DESC_STRCT ), &pa );
+//     }
+//     if( *desc == NULL ) {
+//         DBG_ERROR( DbgInfo, "pci_alloc_consistent() failed\n" );
+//         status = -ENOMEM;
+//     } else {
+//         memset( *desc, 0, sizeof( DESC_STRCT ));
+//         (*desc)->desc_phys_addr = cpu_to_le32( pa );
+//     }
+//     DBG_LEAVE( DbgInfo );
+//     return status;
+} // wl_pci_dma_alloc_desc
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_pci_dma_free_desc()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Frees one DMA descriptor in cache coherent memory.
+ *
+ *  PARAMETERS:
+ *
+ *      pdev - a pointer to the device's pci_dev structure
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wl_pci_dma_free_desc( struct pci_dev *pdev, struct wl_private *lp,
+                           DESC_STRCT **desc )
+{
+    int         status = 0;
+    /*------------------------------------------------------------------------*/
+
+    if( *desc == NULL ) {
+        status = -EFAULT;
+    }
+    if( status == 0 ) {
+        pci_free_consistent( pdev, sizeof( DESC_STRCT ), *desc,
+                             (*desc)->desc_phys_addr );
+    }
+    *desc = NULL;
+    return status;
+} // wl_pci_dma_free_desc
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_pci_dma_alloc_buf()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Allocates one DMA buffer in cache coherent memory, and associates a DMA
+ *      descriptor with this buffer.
+ *
+ *  PARAMETERS:
+ *
+ *      pdev - a pointer to the device's pci_dev structure
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wl_pci_dma_alloc_buf( struct pci_dev *pdev, struct wl_private *lp,
+                          DESC_STRCT *desc, int size )
+{
+    int         status = 0;
+    dma_addr_t  pa;
+    /*------------------------------------------------------------------------*/
+
+//     DBG_FUNC( "wl_pci_dma_alloc_buf" );
+//     DBG_ENTER( DbgInfo );
+//
+//     if( desc == NULL ) {
+//         status = -EFAULT;
+//     }
+//     if( status == 0 && desc->buf_addr != NULL ) {
+//         status = -EFAULT;
+//     }
+//     if( status == 0 ) {
+//         desc->buf_addr = pci_alloc_consistent( pdev, size, &pa );
+//     }
+//     if( desc->buf_addr == NULL ) {
+//         DBG_ERROR( DbgInfo, "pci_alloc_consistent() failed\n" );
+//         status = -ENOMEM;
+//     } else {
+//         desc->buf_phys_addr = cpu_to_le32( pa );
+//         SET_BUF_SIZE( desc, size );
+//     }
+//     DBG_LEAVE( DbgInfo );
+    return status;
+} // wl_pci_dma_alloc_buf
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_pci_dma_free_buf()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Allocates one DMA buffer in cache coherent memory, and associates a DMA
+ *      descriptor with this buffer.
+ *
+ *  PARAMETERS:
+ *
+ *      pdev - a pointer to the device's pci_dev structure
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wl_pci_dma_free_buf( struct pci_dev *pdev, struct wl_private *lp,
+                         DESC_STRCT *desc )
+{
+    int         status = 0;
+    /*------------------------------------------------------------------------*/
+
+    if( desc == NULL ) {
+        status = -EFAULT;
+    }
+    if( status == 0 && desc->buf_addr == NULL ) {
+        status = -EFAULT;
+    }
+    if( status == 0 ) {
+        pci_free_consistent( pdev, GET_BUF_SIZE( desc ), desc->buf_addr,
+                             desc->buf_phys_addr );
+
+        desc->buf_addr = 0;
+        desc->buf_phys_addr = 0;
+        SET_BUF_SIZE( desc, 0 );
+    }
+    return status;
+} // wl_pci_dma_free_buf
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_pci_dma_hcf_supply()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Supply HCF with DMA-related resources. These consist of:
+ *          - buffers and descriptors for receive purposes
+ *          - one 'reclaim' descriptor for the transmit path, used to fulfill a
+ *            certain H25 DMA engine requirement
+ *          - one 'reclaim' descriptor for the receive path, used to fulfill a
+ *            certain H25 DMA engine requirement
+ *
+ *      This function is called at start-of-day or at re-initialization.
+ *
+ *  PARAMETERS:
+ *
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+void wl_pci_dma_hcf_supply( struct wl_private *lp )
+{
+    int i;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_pci_dma_hcf_supply" );
+    DBG_ENTER( DbgInfo );
+
+    //if( lp->dma.status == 0 );
+    //{
+        /* Hand over the Rx/Tx reclaim descriptors to the HCF */
+        if( lp->dma.tx_reclaim_desc ) {
+            DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
+            hcf_dma_tx_put( &lp->hcfCtx, lp->dma.tx_reclaim_desc, 0 );
+            lp->dma.tx_reclaim_desc = NULL;
+            DBG_PRINT( "lp->dma.tx_reclaim_desc: 0x%p\n", lp->dma.tx_reclaim_desc );
+        }
+        if( lp->dma.rx_reclaim_desc ) {
+            DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
+            hcf_dma_rx_put( &lp->hcfCtx, lp->dma.rx_reclaim_desc );
+            lp->dma.rx_reclaim_desc = NULL;
+            DBG_PRINT( "lp->dma.rx_reclaim_desc: 0x%p\n", lp->dma.rx_reclaim_desc );
+        }
+        /* Hand over the Rx descriptor chain to the HCF */
+        for( i = 0; i < NUM_RX_DESC; i++ ) {
+            DBG_PRINT( "lp->dma.rx_packet[%d]:    0x%p\n", i, lp->dma.rx_packet[i] );
+            hcf_dma_rx_put( &lp->hcfCtx, lp->dma.rx_packet[i] );
+            lp->dma.rx_packet[i] = NULL;
+            DBG_PRINT( "lp->dma.rx_packet[%d]:    0x%p\n", i, lp->dma.rx_packet[i] );
+        }
+    //}
+
+    DBG_LEAVE( DbgInfo );
+    return;
+} // wl_pci_dma_hcf_supply
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_pci_dma_hcf_reclaim()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Return DMA-related resources from the HCF. These consist of:
+ *          - buffers and descriptors for receive purposes
+ *          - buffers and descriptors for transmit purposes
+ *          - one 'reclaim' descriptor for the transmit path, used to fulfill a
+ *            certain H25 DMA engine requirement
+ *          - one 'reclaim' descriptor for the receive path, used to fulfill a
+ *            certain H25 DMA engine requirement
+ *
+ *      This function is called at end-of-day or at re-initialization.
+ *
+ *  PARAMETERS:
+ *
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+void wl_pci_dma_hcf_reclaim( struct wl_private *lp )
+{
+    int i;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_pci_dma_hcf_reclaim" );
+    DBG_ENTER( DbgInfo );
+
+    wl_pci_dma_hcf_reclaim_rx( lp );
+    for( i = 0; i < NUM_RX_DESC; i++ ) {
+        DBG_PRINT( "rx_packet[%d] 0x%p\n", i, lp->dma.rx_packet[i] );
+//         if( lp->dma.rx_packet[i] == NULL ) {
+//             DBG_PRINT( "wl_pci_dma_hcf_reclaim: rx_packet[%d] NULL\n", i );
+//         }
+    }
+
+    wl_pci_dma_hcf_reclaim_tx( lp );
+    for( i = 0; i < NUM_TX_DESC; i++ ) {
+        DBG_PRINT( "tx_packet[%d] 0x%p\n", i, lp->dma.tx_packet[i] );
+//         if( lp->dma.tx_packet[i] == NULL ) {
+//             DBG_PRINT( "wl_pci_dma_hcf_reclaim: tx_packet[%d] NULL\n", i );
+//         }
+     }
+
+    DBG_LEAVE( DbgInfo );
+    return;
+} // wl_pci_dma_hcf_reclaim
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_pci_dma_hcf_reclaim_rx()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Reclaim Rx packets that have already been processed by the HCF.
+ *
+ *  PARAMETERS:
+ *
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+void wl_pci_dma_hcf_reclaim_rx( struct wl_private *lp )
+{
+    int         i;
+    DESC_STRCT *p;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_pci_dma_hcf_reclaim_rx" );
+    DBG_ENTER( DbgInfo );
+
+    //if( lp->dma.status == 0 )
+    //{
+        while ( ( p = hcf_dma_rx_get( &lp->hcfCtx ) ) != NULL ) {
+            if( p && p->buf_addr == NULL ) {
+                /* A reclaim descriptor is being given back by the HCF. Reclaim
+                   descriptors have a NULL buf_addr */
+                lp->dma.rx_reclaim_desc = p;
+            	DBG_PRINT( "reclaim_descriptor: 0x%p\n", p );
+                continue;
+            }
+            for( i = 0; i < NUM_RX_DESC; i++ ) {
+                if( lp->dma.rx_packet[i] == NULL ) {
+                    break;
+                }
+            }
+            /* An Rx buffer descriptor is being given back by the HCF */
+            lp->dma.rx_packet[i] = p;
+            lp->dma.rx_rsc_ind++;
+        	DBG_PRINT( "rx_packet[%d] 0x%p\n", i, lp->dma.rx_packet[i] );
+        }
+    //}
+    DBG_LEAVE( DbgInfo );
+} // wl_pci_dma_hcf_reclaim_rx
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_pci_dma_get_tx_packet()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Obtains a Tx descriptor from the chain to use for Tx.
+ *
+ *  PARAMETERS:
+ *
+ *      lp - a pointer to the device's wl_private structure.
+ *
+ *  RETURNS:
+ *
+ *      A pointer to the retrieved descriptor
+ *
+ ******************************************************************************/
+DESC_STRCT * wl_pci_dma_get_tx_packet( struct wl_private *lp )
+{
+    int i;
+    DESC_STRCT *desc = NULL;
+    /*------------------------------------------------------------------------*/
+
+    for( i = 0; i < NUM_TX_DESC; i++ ) {
+        if( lp->dma.tx_packet[i] ) {
+            break;
+        }
+    }
+
+    if( i != NUM_TX_DESC ) {
+        desc = lp->dma.tx_packet[i];
+
+        lp->dma.tx_packet[i] = NULL;
+        lp->dma.tx_rsc_ind--;
+
+        memset( desc->buf_addr, 0, HCF_DMA_TX_BUF1_SIZE );
+    }
+
+    return desc;
+} // wl_pci_dma_get_tx_packet
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_pci_dma_put_tx_packet()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Returns a Tx descriptor to the chain.
+ *
+ *  PARAMETERS:
+ *
+ *      lp   - a pointer to the device's wl_private structure.
+ *      desc - a pointer to the descriptor to return.
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_pci_dma_put_tx_packet( struct wl_private *lp, DESC_STRCT *desc )
+{
+    int i;
+    /*------------------------------------------------------------------------*/
+
+    for( i = 0; i < NUM_TX_DESC; i++ ) {
+        if( lp->dma.tx_packet[i] == NULL ) {
+            break;
+        }
+    }
+
+    if( i != NUM_TX_DESC ) {
+        lp->dma.tx_packet[i] = desc;
+        lp->dma.tx_rsc_ind++;
+    }
+} // wl_pci_dma_put_tx_packet
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wl_pci_dma_hcf_reclaim_tx()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Reclaim Tx packets that have either been processed by the HCF due to a
+ *      port disable or a Tx completion.
+ *
+ *  PARAMETERS:
+ *
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+void wl_pci_dma_hcf_reclaim_tx( struct wl_private *lp )
+{
+    int         i;
+    DESC_STRCT *p;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_pci_dma_hcf_reclaim_tx" );
+    DBG_ENTER( DbgInfo );
+
+    //if( lp->dma.status == 0 )
+    //{
+        while ( ( p = hcf_dma_tx_get( &lp->hcfCtx ) ) != NULL ) {
+
+            if( p != NULL && p->buf_addr == NULL ) {
+                /* A Reclaim descriptor is being given back by the HCF. Reclaim
+                   descriptors have a NULL buf_addr */
+                lp->dma.tx_reclaim_desc = p;
+            	DBG_PRINT( "reclaim_descriptor: 0x%p\n", p );
+                continue;
+            }
+            for( i = 0; i < NUM_TX_DESC; i++ ) {
+                if( lp->dma.tx_packet[i] == NULL ) {
+                    break;
+                }
+            }
+            /* An Rx buffer descriptor is being given back by the HCF */
+            lp->dma.tx_packet[i] = p;
+            lp->dma.tx_rsc_ind++;
+        	DBG_PRINT( "tx_packet[%d] 0x%p\n", i, lp->dma.tx_packet[i] );
+        }
+    //}
+
+    if( lp->netif_queue_on == FALSE ) {
+        netif_wake_queue( lp->dev );
+        WL_WDS_NETIF_WAKE_QUEUE( lp );
+        lp->netif_queue_on = TRUE;
+    }
+    DBG_LEAVE( DbgInfo );
+    return;
+} // wl_pci_dma_hcf_reclaim_tx
+/*============================================================================*/
+#endif  // ENABLE_DMA
diff --git a/drivers/staging/wlags49_h2/wl_pci.h b/drivers/staging/wlags49_h2/wl_pci.h
new file mode 100644
index 0000000..18d7b51
--- /dev/null
+++ b/drivers/staging/wlags49_h2/wl_pci.h
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Agere Systems Inc.
+ * Wireless device driver for Linux (wlags49).
+ *
+ * Copyright (c) 1998-2003 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * Initially developed by TriplePoint, Inc.
+ *   http://www.triplepoint.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ *   Header describing information required for the driver to support PCI.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2003 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following Disclaimer as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ ******************************************************************************/
+
+#ifndef __WL_PCI_H__
+#define __WL_PCI_H__
+
+
+
+
+/*******************************************************************************
+ *  constant definitions
+ ******************************************************************************/
+#define WL_LKM_PCI_VENDOR_ID    0x11C1  // Lucent Microelectronics
+#define WL_LKM_PCI_DEVICE_ID_0  0xAB30  // Mini PCI
+#define WL_LKM_PCI_DEVICE_ID_1  0xAB34  // Mini PCI
+#define WL_LKM_PCI_DEVICE_ID_2  0xAB11  // WARP CardBus
+
+
+
+
+/*******************************************************************************
+ *  function prototypes
+ ******************************************************************************/
+int wl_adapter_init_module( void );
+
+void wl_adapter_cleanup_module( void );
+
+int wl_adapter_insert( struct net_device *dev );
+
+int wl_adapter_open( struct net_device *dev );
+
+int wl_adapter_close( struct net_device *dev );
+
+int wl_adapter_is_open( struct net_device *dev );
+
+
+#ifdef ENABLE_DMA
+
+void wl_pci_dma_hcf_supply( struct wl_private *lp );
+
+void wl_pci_dma_hcf_reclaim( struct wl_private *lp );
+
+DESC_STRCT * wl_pci_dma_get_tx_packet( struct wl_private *lp );
+
+void wl_pci_dma_put_tx_packet( struct wl_private *lp, DESC_STRCT *desc );
+
+void wl_pci_dma_hcf_reclaim_tx( struct wl_private *lp );
+
+#endif  // ENABLE_DMA
+
+
+#endif  // __WL_PCI_H__
diff --git a/drivers/staging/wlags49_h2/wl_priv.c b/drivers/staging/wlags49_h2/wl_priv.c
new file mode 100644
index 0000000..ee610c7
--- /dev/null
+++ b/drivers/staging/wlags49_h2/wl_priv.c
@@ -0,0 +1,2078 @@
+/*******************************************************************************
+ * Agere Systems Inc.
+ * Wireless device driver for Linux (wlags49).
+ *
+ * Copyright (c) 1998-2003 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * Initially developed by TriplePoint, Inc.
+ *   http://www.triplepoint.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ *   This file defines handling routines for the private IOCTLs
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2003 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following Disclaimer as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ ******************************************************************************/
+
+/*******************************************************************************
+ * include files
+ ******************************************************************************/
+#include <wl_version.h>
+
+#include <linux/if_arp.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+
+#include <debug.h>
+#include <hcf.h>
+#include <hcfdef.h>
+
+#include <wl_if.h>
+#include <wl_internal.h>
+#include <wl_enc.h>
+#include <wl_main.h>
+#include <wl_priv.h>
+#include <wl_util.h>
+#include <wl_netdev.h>
+
+int wvlan_uil_connect( struct uilreq *urq, struct wl_private *lp );
+int wvlan_uil_disconnect( struct uilreq *urq, struct wl_private *lp );
+int wvlan_uil_action( struct uilreq *urq, struct wl_private *lp );
+int wvlan_uil_block( struct uilreq *urq, struct wl_private *lp );
+int wvlan_uil_unblock( struct uilreq *urq, struct wl_private *lp );
+int wvlan_uil_send_diag_msg( struct uilreq *urq, struct wl_private *lp );
+int wvlan_uil_put_info( struct uilreq *urq, struct wl_private *lp );
+int wvlan_uil_get_info( struct uilreq *urq, struct wl_private *lp );
+
+int cfg_driver_info( struct uilreq *urq, struct wl_private *lp );
+int cfg_driver_identity( struct uilreq *urq, struct wl_private *lp );
+
+
+/*******************************************************************************
+ * global variables
+ ******************************************************************************/
+#if DBG
+extern dbg_info_t *DbgInfo;
+#endif  // DBG
+
+
+
+
+/* If USE_UIL is not defined, then none of the UIL Interface code below will
+   be included in the build */
+#ifdef USE_UIL
+
+/*******************************************************************************
+ *	wvlan_uil()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      The handler function for the UIL interface.
+ *
+ *  PARAMETERS:
+ *
+ *      urq - a pointer to the UIL request buffer
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wvlan_uil( struct uilreq *urq, struct wl_private *lp )
+{
+	int ioctl_ret = 0;
+	/*------------------------------------------------------------------------*/
+
+	DBG_FUNC( "wvlan_uil" );
+	DBG_ENTER( DbgInfo );
+
+	switch( urq->command ) {
+	  case UIL_FUN_CONNECT:
+		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL -- WVLAN2_UIL_CONNECT\n");
+		ioctl_ret = wvlan_uil_connect( urq, lp );
+		break;
+	  case UIL_FUN_DISCONNECT:
+		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL -- WVLAN2_UIL_DISCONNECT\n");
+		ioctl_ret = wvlan_uil_disconnect( urq, lp );
+		break;
+	  case UIL_FUN_ACTION:
+		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL -- WVLAN2_UIL_ACTION\n" );
+		ioctl_ret = wvlan_uil_action( urq, lp );
+		break;
+	  case UIL_FUN_SEND_DIAG_MSG:
+		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL -- WVLAN2_UIL_SEND_DIAG_MSG\n");
+		ioctl_ret = wvlan_uil_send_diag_msg( urq, lp );
+		break;
+	  case UIL_FUN_GET_INFO:
+		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL -- WVLAN2_UIL_GET_INFO\n");
+		ioctl_ret = wvlan_uil_get_info( urq, lp );
+		break;
+	  case UIL_FUN_PUT_INFO:
+		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL -- WVLAN2_UIL_PUT_INFO\n");
+		ioctl_ret = wvlan_uil_put_info( urq, lp );
+		break;
+	default:
+		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL -- UNSUPPORTED UIL CODE: 0x%X", urq->command );
+		ioctl_ret = -EOPNOTSUPP;
+		break;
+	}
+	DBG_LEAVE( DbgInfo );
+	return ioctl_ret;
+} // wvlan_uil
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wvlan_uil_connect()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Connect to the UIL in order to make a request.
+ *
+ *  PARAMETERS:
+ *
+ *      urq - a pointer to the UIL request buffer
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      UIL_SUCCESS
+ *      UIL_ERR_xxx value otherwise
+ *
+ ******************************************************************************/
+int wvlan_uil_connect( struct uilreq *urq, struct wl_private *lp )
+{
+	int result = 0;
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wvlan_uil_connect" );
+	DBG_ENTER( DbgInfo );
+
+
+	if( !( lp->flags & WVLAN2_UIL_CONNECTED )) {
+		lp->flags |= WVLAN2_UIL_CONNECTED;
+		urq->hcfCtx = &( lp->hcfCtx );
+		urq->result = UIL_SUCCESS;
+	} else {
+		DBG_WARNING( DbgInfo, "UIL_ERR_IN_USE\n" );
+		urq->result = UIL_ERR_IN_USE;
+	}
+
+	DBG_LEAVE( DbgInfo );
+	return result;
+} // wvlan_uil_connect
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wvlan_uil_disconnect()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Disonnect from the UIL after a request has been completed.
+ *
+ *  PARAMETERS:
+ *
+ *      urq - a pointer to the UIL request buffer
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      UIL_SUCCESS
+ *      UIL_ERR_xxx value otherwise
+ *
+ ******************************************************************************/
+int wvlan_uil_disconnect( struct uilreq *urq, struct wl_private *lp )
+{
+	int result = 0;
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wvlan_uil_disconnect" );
+	DBG_ENTER( DbgInfo );
+
+
+	if( urq->hcfCtx == &( lp->hcfCtx )) {
+		if (lp->flags & WVLAN2_UIL_CONNECTED) {
+			lp->flags &= ~WVLAN2_UIL_CONNECTED;
+			/*
+			if (lp->flags & WVLAN2_UIL_BUSY) {
+				lp->flags &= ~WVLAN2_UIL_BUSY;
+				netif_start_queue(lp->dev);
+			}
+			*/
+		}
+
+		urq->hcfCtx = NULL;
+		urq->result = UIL_SUCCESS;
+	} else {
+		DBG_ERROR( DbgInfo, "UIL_ERR_WRONG_IFB\n" );
+		urq->result = UIL_ERR_WRONG_IFB;
+	}
+
+	DBG_LEAVE( DbgInfo );
+	return result;
+} // wvlan_uil_disconnect
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wvlan_uil_action()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Handler for the UIL_ACT_xxx subcodes associated with UIL_FUN_ACTION
+ *
+ *  PARAMETERS:
+ *
+ *      urq - a pointer to the UIL request buffer
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      UIL_SUCCESS
+ *      UIL_ERR_xxx value otherwise
+ *
+ ******************************************************************************/
+int wvlan_uil_action( struct uilreq *urq, struct wl_private *lp )
+{
+	int     result = 0;
+	ltv_t   *ltv;
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wvlan_uil_action" );
+	DBG_ENTER( DbgInfo );
+
+
+	if( urq->hcfCtx == &( lp->hcfCtx )) {
+		/* Make sure there's an LTV in the request buffer */
+		ltv = (ltv_t *)urq->data;
+		if( ltv != NULL ) {
+			/* Switch on the Type field of the LTV contained in the request
+			   buffer */
+			switch( ltv->typ ) {
+			case UIL_ACT_BLOCK:
+				DBG_TRACE( DbgInfo, "UIL_ACT_BLOCK\n" );
+				result = wvlan_uil_block( urq, lp );
+				break;
+			case UIL_ACT_UNBLOCK:
+				DBG_TRACE( DbgInfo, "UIL_ACT_UNBLOCK\n" );
+				result = wvlan_uil_unblock( urq, lp );
+				break;
+			case UIL_ACT_SCAN:
+				DBG_TRACE( DbgInfo, "UIL_ACT_SCAN\n" );
+				urq->result = hcf_action( &( lp->hcfCtx ), MDD_ACT_SCAN );
+				break;
+			case UIL_ACT_APPLY:
+				DBG_TRACE( DbgInfo, "UIL_ACT_APPLY\n" );
+				urq->result = wl_apply( lp );
+				break;
+			case UIL_ACT_RESET:
+				DBG_TRACE( DbgInfo, "UIL_ACT_RESET\n" );
+				urq->result = wl_go( lp );
+				break;
+			default:
+				DBG_WARNING( DbgInfo, "Unknown action code: 0x%x\n", ltv->typ );
+				break;
+			}
+		} else {
+			DBG_ERROR( DbgInfo, "Bad LTV for this action\n" );
+			urq->result = UIL_ERR_LEN;
+		}
+	} else {
+		DBG_ERROR( DbgInfo, "UIL_ERR_WRONG_IFB\n" );
+		urq->result = UIL_ERR_WRONG_IFB;
+	}
+
+	DBG_LEAVE( DbgInfo );
+	return result;
+} // wvlan_uil_action
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wvlan_uil_block()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Sets a block in the driver to prevent access to the card by other
+ *  processes.
+ *
+ *  PARAMETERS:
+ *
+ *      urq - a pointer to the UIL request buffer
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      UIL_SUCCESS
+ *      UIL_ERR_xxx value otherwise
+ *
+ ******************************************************************************/
+
+int wvlan_uil_block( struct uilreq *urq, struct wl_private *lp )
+{
+	int result = 0;
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wvlan_uil_block" );
+	DBG_ENTER( DbgInfo );
+
+	if( urq->hcfCtx == &( lp->hcfCtx )) {
+		if( capable( CAP_NET_ADMIN )) {
+			lp->flags |= WVLAN2_UIL_BUSY;
+			netif_stop_queue(lp->dev);
+			WL_WDS_NETIF_STOP_QUEUE( lp );
+			urq->result = UIL_SUCCESS;
+		} else {
+			DBG_ERROR( DbgInfo, "EPERM\n" );
+			urq->result = UIL_FAILURE;
+			result = -EPERM;
+		}
+	} else {
+		DBG_ERROR( DbgInfo, "UIL_ERR_WRONG_IFB\n" );
+		urq->result = UIL_ERR_WRONG_IFB;
+	}
+
+	DBG_LEAVE( DbgInfo );
+	return result;
+} // wvlan_uil_block
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wvlan_uil_unblock()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Unblocks the driver to restore access to the card by other processes.
+ *
+ *  PARAMETERS:
+ *
+ *      urq - a pointer to the UIL request buffer
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      UIL_SUCCESS
+ *      UIL_ERR_xxx value otherwise
+ *
+ ******************************************************************************/
+int wvlan_uil_unblock( struct uilreq *urq, struct wl_private *lp )
+{
+	int result = 0;
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wvlan_uil_unblock" );
+	DBG_ENTER( DbgInfo );
+
+	if( urq->hcfCtx == &( lp->hcfCtx )) {
+		if( capable( CAP_NET_ADMIN )) {
+			if (lp->flags & WVLAN2_UIL_BUSY) {
+				lp->flags &= ~WVLAN2_UIL_BUSY;
+				netif_wake_queue(lp->dev);
+				WL_WDS_NETIF_WAKE_QUEUE( lp );
+			}
+		} else {
+			DBG_ERROR( DbgInfo, "EPERM\n" );
+			urq->result = UIL_FAILURE;
+			result = -EPERM;
+		}
+	} else {
+		DBG_ERROR( DbgInfo, "UIL_ERR_WRONG_IFB\n" );
+		urq->result = UIL_ERR_WRONG_IFB;
+	}
+
+	DBG_LEAVE( DbgInfo );
+	return result;
+} // wvlan_uil_unblock
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wvlan_uil_send_diag_msg()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Sends a diagnostic message to the card.
+ *
+ *  PARAMETERS:
+ *
+ *      urq - a pointer to the UIL request buffer
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      UIL_SUCCESS
+ *      UIL_ERR_xxx value otherwise
+ *
+ ******************************************************************************/
+int wvlan_uil_send_diag_msg( struct uilreq *urq, struct wl_private *lp )
+{
+	int         result = 0;
+	DESC_STRCT  Descp[1];
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wvlan_uil_send_diag_msg" );
+	DBG_ENTER( DbgInfo );
+
+	if( urq->hcfCtx == &( lp->hcfCtx )) {
+		if( capable( CAP_NET_ADMIN )) {
+			if ((urq->data != NULL) && (urq->len != 0)) {
+				if (lp->hcfCtx.IFB_RscInd != 0) {
+					u_char *data;
+
+					// Verify the user buffer
+					result = verify_area(VERIFY_READ, urq->data, urq->len);
+					if (result != 0) {
+						DBG_ERROR( DbgInfo, "verify_area failed, result: %d\n", result );
+						urq->result = UIL_FAILURE;
+						DBG_LEAVE( DbgInfo );
+						return result;
+					}
+
+					if ((data = kmalloc(urq->len, GFP_KERNEL)) != NULL) {
+						memset( Descp, 0, sizeof( DESC_STRCT ));
+						memcpy( data, urq->data, urq->len );
+
+						Descp[0].buf_addr       = (wci_bufp)data;
+						Descp[0].BUF_CNT        = urq->len;
+						Descp[0].next_desc_addr = 0;    // terminate list
+
+						hcf_send_msg( &(lp->hcfCtx),  &Descp[0], HCF_PORT_0 );
+						kfree( data );
+					} else {
+						DBG_ERROR( DbgInfo, "ENOMEM\n" );
+						urq->result = UIL_FAILURE;
+						result = -ENOMEM;
+						DBG_LEAVE( DbgInfo );
+						return result;
+					}
+
+				} else {
+					urq->result = UIL_ERR_BUSY;
+				}
+
+			} else {
+				urq->result = UIL_FAILURE;
+			}
+		} else {
+			DBG_ERROR( DbgInfo, "EPERM\n" );
+			urq->result = UIL_FAILURE;
+			result = -EPERM;
+		}
+	} else {
+		DBG_ERROR( DbgInfo, "UIL_ERR_WRONG_IFB\n" );
+		urq->result = UIL_ERR_WRONG_IFB;
+	}
+
+	DBG_LEAVE( DbgInfo );
+	return result;
+} // wvlan_uil_send_diag_msg
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wvlan_uil_put_info()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Sends a specific RID directly to the driver to set configuration info.
+ *
+ *  PARAMETERS:
+ *
+ *      urq - a pointer to the UIL request buffer
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      UIL_SUCCESS
+ *      UIL_ERR_xxx value otherwise
+ *
+ ******************************************************************************/
+int wvlan_uil_put_info( struct uilreq *urq, struct wl_private *lp )
+{
+	int                     result = 0;
+	ltv_t                   *pLtv;
+	bool_t                  ltvAllocated = FALSE;
+	ENCSTRCT                sEncryption;
+
+#ifdef USE_WDS
+	hcf_16                  hcfPort  = HCF_PORT_0;
+#endif  /* USE_WDS */
+	/*------------------------------------------------------------------------*/
+	DBG_FUNC( "wvlan_uil_put_info" );
+	DBG_ENTER( DbgInfo );
+
+
+	if( urq->hcfCtx == &( lp->hcfCtx )) {
+		if( capable( CAP_NET_ADMIN )) {
+			if(( urq->data != NULL ) && ( urq->len != 0 )) {
+				/* Make sure that we have at least a command and length to send. */
+				if( urq->len < ( sizeof( hcf_16 ) * 2 )) {
+					urq->len = sizeof( lp->ltvRecord );
+					urq->result = UIL_ERR_LEN;
+					DBG_ERROR( DbgInfo, "No Length/Type in LTV!!!\n" );
+					DBG_ERROR( DbgInfo, "UIL_ERR_LEN\n" );
+					DBG_LEAVE( DbgInfo );
+					return result;
+				}
+
+				/* Verify the user buffer */
+				result = verify_area( VERIFY_READ, urq->data, urq->len );
+				if( result != 0 ) {
+					urq->result = UIL_FAILURE;
+					DBG_ERROR( DbgInfo, "verify_area(), VERIFY_READ FAILED\n" );
+					DBG_LEAVE( DbgInfo );
+					return result;
+				}
+
+				/* Get only the command and length information. */
+				copy_from_user( &( lp->ltvRecord ), urq->data, sizeof( hcf_16 ) * 2 );
+
+				/* Make sure the incoming LTV record length is within the bounds of the
+				   IOCTL length */
+				if((( lp->ltvRecord.len + 1 ) * sizeof( hcf_16 )) > urq->len ) {
+					urq->len = sizeof( lp->ltvRecord );
+					urq->result = UIL_ERR_LEN;
+					DBG_ERROR( DbgInfo, "UIL_ERR_LEN\n" );
+					DBG_LEAVE( DbgInfo );
+					return result;
+				}
+
+				/* If the requested length is greater than the size of our local
+				   LTV record, try to allocate it from the kernel stack.
+				   Otherwise, we just use our local LTV record. */
+				if( urq->len > sizeof( lp->ltvRecord )) {
+					if(( pLtv = (ltv_t *)kmalloc( urq->len, GFP_KERNEL )) != NULL ) {
+						ltvAllocated = TRUE;
+					} else {
+						DBG_ERROR( DbgInfo, "Alloc FAILED\n" );
+						urq->len = sizeof( lp->ltvRecord );
+						urq->result = UIL_ERR_LEN;
+						result = -ENOMEM;
+						DBG_LEAVE( DbgInfo );
+						return result;
+					}
+				} else {
+					pLtv = &( lp->ltvRecord );
+				}
+
+				/* Copy the data from the user's buffer into the local LTV
+				   record data area. */
+				copy_from_user( pLtv, urq->data, urq->len );
+
+
+				/* We need to snoop the commands to see if there is anything we
+				   need to store for the purposes of a reset or start/stop
+				   sequence. Perform endian translation as needed */
+				switch( pLtv->typ ) {
+				case CFG_CNF_PORT_TYPE:
+					lp->PortType    = pLtv->u.u16[0];
+					pLtv->u.u16[0]  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+				case CFG_CNF_OWN_MAC_ADDR:
+					/* TODO: determine if we are going to store anything based on this */
+					break;
+				case CFG_CNF_OWN_CHANNEL:
+					lp->Channel     = pLtv->u.u16[0];
+					pLtv->u.u16[0]  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+				/* CFG_CNF_OWN_SSID currently same as CNF_DESIRED_SSID. Do we
+				   need seperate storage for this? */
+				//case CFG_CNF_OWN_SSID:
+				case CFG_CNF_OWN_ATIM_WINDOW:
+					lp->atimWindow  = pLtv->u.u16[0];
+					pLtv->u.u16[0]  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+				case CFG_CNF_SYSTEM_SCALE:
+					lp->DistanceBetweenAPs  = pLtv->u.u16[0];
+					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+
+				case CFG_CNF_MAX_DATA_LEN:
+					/* TODO: determine if we are going to store anything based
+					   on this */
+					break;
+				case CFG_CNF_PM_ENABLED:
+					lp->PMEnabled   = pLtv->u.u16[0];
+					pLtv->u.u16[0]  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+				case CFG_CNF_MCAST_RX:
+					lp->MulticastReceive    = pLtv->u.u16[0];
+					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+				case CFG_CNF_MAX_SLEEP_DURATION:
+					lp->MaxSleepDuration    = pLtv->u.u16[0];
+					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+				case CFG_CNF_HOLDOVER_DURATION:
+					lp->holdoverDuration    = pLtv->u.u16[0];
+					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+				case CFG_CNF_OWN_NAME:
+					memset( lp->StationName, 0, sizeof( lp->StationName ));
+					memcpy( (void *)lp->StationName, (void *)&pLtv->u.u8[2], (size_t)pLtv->u.u16[0]);
+					pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+				case CFG_CNF_LOAD_BALANCING:
+					lp->loadBalancing       = pLtv->u.u16[0];
+					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+				case CFG_CNF_MEDIUM_DISTRIBUTION:
+					lp->mediumDistribution  = pLtv->u.u16[0];
+					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+#ifdef WARP
+				case CFG_CNF_TX_POW_LVL:
+					lp->txPowLevel          = pLtv->u.u16[0];
+					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+				//case CFG_CNF_SHORT_RETRY_LIMIT:    // Short Retry Limit
+				//case 0xFC33:    // Long Retry Limit
+				case CFG_SUPPORTED_RATE_SET_CNTL:        // Supported Rate Set Control
+					lp->srsc[0]             = pLtv->u.u16[0];
+					lp->srsc[1]             = pLtv->u.u16[1];
+					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					pLtv->u.u16[1]          = CNV_INT_TO_LITTLE( pLtv->u.u16[1] );
+					break;
+				case CFG_BASIC_RATE_SET_CNTL:        // Basic Rate Set Control
+					lp->brsc[0]             = pLtv->u.u16[0];
+					lp->brsc[1]             = pLtv->u.u16[1];
+					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					pLtv->u.u16[1]          = CNV_INT_TO_LITTLE( pLtv->u.u16[1] );
+					break;
+				case CFG_CNF_CONNECTION_CNTL:
+					lp->connectionControl   = pLtv->u.u16[0];
+					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+				//case CFG_PROBE_DATA_RATE:
+#endif  // HERMES25
+
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
+		//;?should we restore this to allow smaller memory footprint
+
+				case CFG_CNF_OWN_DTIM_PERIOD:
+					lp->DTIMPeriod  = pLtv->u.u16[0];
+					pLtv->u.u16[0]  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+#ifdef WARP
+				case CFG_CNF_OWN_BEACON_INTERVAL:        // Own Beacon Interval
+					lp->ownBeaconInterval   = pLtv->u.u16[0];
+					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+#endif // WARP
+				case CFG_COEXISTENSE_BEHAVIOUR:         // Coexistence behavior
+					lp->coexistence         = pLtv->u.u16[0];
+					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+#ifdef USE_WDS
+				case CFG_CNF_WDS_ADDR1:
+					memcpy( &lp->wds_port[0].wdsAddress, &pLtv->u.u8[0], ETH_ALEN );
+					hcfPort = HCF_PORT_1;
+					break;
+				case CFG_CNF_WDS_ADDR2:
+					memcpy( &lp->wds_port[1].wdsAddress, &pLtv->u.u8[0], ETH_ALEN );
+					hcfPort = HCF_PORT_2;
+					break;
+				case CFG_CNF_WDS_ADDR3:
+					memcpy( &lp->wds_port[2].wdsAddress, &pLtv->u.u8[0], ETH_ALEN );
+					hcfPort = HCF_PORT_3;
+					break;
+				case CFG_CNF_WDS_ADDR4:
+					memcpy( &lp->wds_port[3].wdsAddress, &pLtv->u.u8[0], ETH_ALEN );
+					hcfPort = HCF_PORT_4;
+					break;
+				case CFG_CNF_WDS_ADDR5:
+					memcpy( &lp->wds_port[4].wdsAddress, &pLtv->u.u8[0], ETH_ALEN );
+					hcfPort = HCF_PORT_5;
+					break;
+				case CFG_CNF_WDS_ADDR6:
+					memcpy( &lp->wds_port[5].wdsAddress, &pLtv->u.u8[0], ETH_ALEN );
+					hcfPort = HCF_PORT_6;
+					break;
+#endif  /* USE_WDS */
+
+				case CFG_CNF_MCAST_PM_BUF:
+					lp->multicastPMBuffering    = pLtv->u.u16[0];
+					pLtv->u.u16[0]              = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+				case CFG_CNF_REJECT_ANY:
+					lp->RejectAny   = pLtv->u.u16[0];
+					pLtv->u.u16[0]  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+#endif
+
+				case CFG_CNF_ENCRYPTION:
+					lp->EnableEncryption    = pLtv->u.u16[0];
+					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+				case CFG_CNF_AUTHENTICATION:
+					lp->authentication  = pLtv->u.u16[0];
+					pLtv->u.u16[0]      = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
+		//;?should we restore this to allow smaller memory footprint
+
+				//case CFG_CNF_EXCL_UNENCRYPTED:
+					//lp->ExcludeUnencrypted  = pLtv->u.u16[0];
+					//pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					//break;
+				case CFG_CNF_MCAST_RATE:
+					/* TODO: determine if we are going to store anything based on this */
+					break;
+				case CFG_CNF_INTRA_BSS_RELAY:
+					lp->intraBSSRelay   = pLtv->u.u16[0];
+					pLtv->u.u16[0]      = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+#endif
+
+				case CFG_CNF_MICRO_WAVE:
+					/* TODO: determine if we are going to store anything based on this */
+					break;
+				//case CFG_CNF_LOAD_BALANCING:
+					/* TODO: determine if we are going to store anything based on this */
+					//break;
+				//case CFG_CNF_MEDIUM_DISTRIBUTION:
+					/* TODO: determine if we are going to store anything based on this */
+					//break;
+				//case CFG_CNF_RX_ALL_GROUP_ADDRESS:
+					// TODO: determine if we are going to store anything based on this
+					//break;
+				//case CFG_CNF_COUNTRY_INFO:
+					/* TODO: determine if we are going to store anything based on this */
+					//break;
+				case CFG_CNF_OWN_SSID:
+				//case CNF_DESIRED_SSID:
+				case CFG_DESIRED_SSID:
+					memset( lp->NetworkName, 0, sizeof( lp->NetworkName ));
+					memcpy( (void *)lp->NetworkName, (void *)&pLtv->u.u8[2], (size_t)pLtv->u.u16[0] );
+					pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+
+					/* take care of the special network name "ANY" case */
+					if(( strlen( &pLtv->u.u8[2]        ) == 0 ) ||
+					   ( strcmp( &pLtv->u.u8[2], "ANY" ) == 0 ) ||
+					   ( strcmp( &pLtv->u.u8[2], "any" ) == 0 )) {
+						/* set the SSID_STRCT llen field (u16[0]) to zero, and the
+						effectually null the string u8[2] */
+						pLtv->u.u16[0] = 0;
+						pLtv->u.u8[2]  = 0;
+					}
+					break;
+				case CFG_GROUP_ADDR:
+					/* TODO: determine if we are going to store anything based on this */
+					break;
+				case CFG_CREATE_IBSS:
+					lp->CreateIBSS  = pLtv->u.u16[0];
+					pLtv->u.u16[0]  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+				case CFG_RTS_THRH:
+					lp->RTSThreshold    = pLtv->u.u16[0];
+					pLtv->u.u16[0]      = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+				case CFG_TX_RATE_CNTL:
+					lp->TxRateControl[0]    = pLtv->u.u16[0];
+					lp->TxRateControl[1]    = pLtv->u.u16[1];
+					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					pLtv->u.u16[1]          = CNV_INT_TO_LITTLE( pLtv->u.u16[1] );
+					break;
+				case CFG_PROMISCUOUS_MODE:
+					/* TODO: determine if we are going to store anything based on this */
+					break;
+				//case CFG_WAKE_ON_LAN:
+					/* TODO: determine if we are going to store anything based on this */
+					//break;
+#if 1 //;? #if (HCF_TYPE) & HCF_TYPE_AP
+		//;?should we restore this to allow smaller memory footprint
+				case CFG_RTS_THRH0:
+					lp->RTSThreshold    = pLtv->u.u16[0];
+					pLtv->u.u16[0]      = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+				case CFG_TX_RATE_CNTL0:
+//;?no idea what this should be, get going so comment it out					lp->TxRateControl   = pLtv->u.u16[0];
+					pLtv->u.u16[0]      = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+#ifdef USE_WDS
+				case CFG_RTS_THRH1:
+					lp->wds_port[0].rtsThreshold    = pLtv->u.u16[0];
+					pLtv->u.u16[0]                  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					hcfPort                         = HCF_PORT_1;
+					break;
+				case CFG_RTS_THRH2:
+					lp->wds_port[1].rtsThreshold    = pLtv->u.u16[0];
+					pLtv->u.u16[0]                  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					hcfPort                         = HCF_PORT_2;
+					break;
+				case CFG_RTS_THRH3:
+					lp->wds_port[2].rtsThreshold    = pLtv->u.u16[0];
+					pLtv->u.u16[0]                  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					hcfPort                         = HCF_PORT_3;
+					break;
+				case CFG_RTS_THRH4:
+					lp->wds_port[3].rtsThreshold    = pLtv->u.u16[0];
+					pLtv->u.u16[0]                  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					hcfPort                         = HCF_PORT_4;
+					break;
+				case CFG_RTS_THRH5:
+					lp->wds_port[4].rtsThreshold    = pLtv->u.u16[0];
+					pLtv->u.u16[0]                  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					hcfPort                         = HCF_PORT_5;
+					break;
+				case CFG_RTS_THRH6:
+					lp->wds_port[5].rtsThreshold    = pLtv->u.u16[0];
+					pLtv->u.u16[0]                  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					hcfPort                         = HCF_PORT_6;
+					break;
+				case CFG_TX_RATE_CNTL1:
+					lp->wds_port[0].txRateCntl  = pLtv->u.u16[0];
+					pLtv->u.u16[0]              = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					hcfPort                     = HCF_PORT_1;
+					break;
+				case CFG_TX_RATE_CNTL2:
+					lp->wds_port[1].txRateCntl  = pLtv->u.u16[0];
+					pLtv->u.u16[0]              = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					hcfPort                     = HCF_PORT_2;
+					break;
+				case CFG_TX_RATE_CNTL3:
+					lp->wds_port[2].txRateCntl  = pLtv->u.u16[0];
+					pLtv->u.u16[0]              = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					hcfPort                     = HCF_PORT_3;
+					break;
+				case CFG_TX_RATE_CNTL4:
+					lp->wds_port[3].txRateCntl  = pLtv->u.u16[0];
+					pLtv->u.u16[0]              = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					hcfPort                     = HCF_PORT_4;
+					break;
+				case CFG_TX_RATE_CNTL5:
+					lp->wds_port[4].txRateCntl  = pLtv->u.u16[0];
+					pLtv->u.u16[0]              = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					hcfPort                     = HCF_PORT_5;
+					break;
+				case CFG_TX_RATE_CNTL6:
+					lp->wds_port[5].txRateCntl  = pLtv->u.u16[0];
+					pLtv->u.u16[0]              = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					hcfPort                     = HCF_PORT_6;
+					break;
+#endif  /* USE_WDS */
+#endif  /* (HCF_TYPE) & HCF_TYPE_AP */
+
+				case CFG_DEFAULT_KEYS:
+					{
+						CFG_DEFAULT_KEYS_STRCT *pKeys = (CFG_DEFAULT_KEYS_STRCT *)pLtv;
+
+						pKeys->key[0].len = CNV_INT_TO_LITTLE( pKeys->key[0].len );
+						pKeys->key[1].len = CNV_INT_TO_LITTLE( pKeys->key[1].len );
+						pKeys->key[2].len = CNV_INT_TO_LITTLE( pKeys->key[2].len );
+						pKeys->key[3].len = CNV_INT_TO_LITTLE( pKeys->key[3].len );
+
+						memcpy( (void *)&(lp->DefaultKeys), (void *)pKeys,
+								sizeof( CFG_DEFAULT_KEYS_STRCT ));
+					}
+					break;
+				case CFG_TX_KEY_ID:
+					lp->TransmitKeyID   = pLtv->u.u16[0];
+					pLtv->u.u16[0]      = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+				case CFG_SCAN_SSID:
+					/* TODO: determine if we are going to store anything based on this */
+					break;
+				case CFG_TICK_TIME:
+					/* TODO: determine if we are going to store anything based on this */
+					break;
+				/* these RIDS are Info RIDs, and should they be allowed for puts??? */
+				case CFG_MAX_LOAD_TIME:
+				case CFG_DL_BUF:
+				//case CFG_HSI_SUP_RANGE:
+				case CFG_NIC_SERIAL_NUMBER:
+				case CFG_NIC_IDENTITY:
+				case CFG_NIC_MFI_SUP_RANGE:
+				case CFG_NIC_CFI_SUP_RANGE:
+				case CFG_NIC_TEMP_TYPE:
+				case CFG_NIC_PROFILE:
+				case CFG_FW_IDENTITY:
+				case CFG_FW_SUP_RANGE:
+				case CFG_MFI_ACT_RANGES_STA:
+				case CFG_CFI_ACT_RANGES_STA:
+				case CFG_PORT_STAT:
+				case CFG_CUR_SSID:
+				case CFG_CUR_BSSID:
+				case CFG_COMMS_QUALITY:
+				case CFG_CUR_TX_RATE:
+				case CFG_CUR_BEACON_INTERVAL:
+				case CFG_CUR_SCALE_THRH:
+				case CFG_PROTOCOL_RSP_TIME:
+				case CFG_CUR_SHORT_RETRY_LIMIT:
+				case CFG_CUR_LONG_RETRY_LIMIT:
+				case CFG_MAX_TX_LIFETIME:
+				case CFG_MAX_RX_LIFETIME:
+				case CFG_CF_POLLABLE:
+				case CFG_AUTHENTICATION_ALGORITHMS:
+				case CFG_PRIVACY_OPT_IMPLEMENTED:
+				//case CFG_CURRENT_REMOTE_RATES:
+				//case CFG_CURRENT_USED_RATES:
+				//case CFG_CURRENT_SYSTEM_SCALE:
+				//case CFG_CURRENT_TX_RATE1:
+				//case CFG_CURRENT_TX_RATE2:
+				//case CFG_CURRENT_TX_RATE3:
+				//case CFG_CURRENT_TX_RATE4:
+				//case CFG_CURRENT_TX_RATE5:
+				//case CFG_CURRENT_TX_RATE6:
+				case CFG_NIC_MAC_ADDR:
+				case CFG_PCF_INFO:
+				//case CFG_CURRENT_COUNTRY_INFO:
+				case CFG_PHY_TYPE:
+				case CFG_CUR_CHANNEL:
+				//case CFG_CURRENT_POWER_STATE:
+				//case CFG_CCAMODE:
+				case CFG_SUPPORTED_DATA_RATES:
+					break;
+				case CFG_AP_MODE:
+//;?				lp->DownloadFirmware = ( pLtv->u.u16[0] ) + 1;
+					DBG_ERROR( DbgInfo, "set CFG_AP_MODE no longer supported\n" );
+					break;
+				case CFG_ENCRYPT_STRING:
+					/* TODO: ENDIAN TRANSLATION HERE??? */
+					memset( lp->szEncryption, 0, sizeof( lp->szEncryption ));
+					memcpy( (void *)lp->szEncryption,  (void *)&pLtv->u.u8[0],
+							( pLtv->len * sizeof( hcf_16 )) );
+					wl_wep_decode( CRYPT_CODE, &sEncryption,
+								    lp->szEncryption );
+
+					/* the Linux driver likes to use 1-4 for the key IDs, and then
+					convert to 0-3 when sending to the card.  The Windows code
+					base used 0-3 in the API DLL, which was ported to Linux.  For
+					the sake of the user experience, we decided to keep 0-3 as the
+					numbers used in the DLL; and will perform the +1 conversion here.
+					We could have converted  the entire Linux driver, but this is
+					less obtrusive.  This may be a "todo" to convert the whole driver */
+					lp->TransmitKeyID    = sEncryption.wTxKeyID + 1;
+					lp->EnableEncryption = sEncryption.wEnabled;
+
+					memcpy( &lp->DefaultKeys, &sEncryption.EncStr,
+							sizeof( CFG_DEFAULT_KEYS_STRCT ));
+					break;
+				/*case CFG_COUNTRY_STRING:
+					memset( lp->countryString, 0, sizeof( lp->countryString ));
+					memcpy( (void *)lp->countryString, (void *)&pLtv->u.u8[2], (size_t)pLtv->u.u16[0]);
+					break;
+				*/
+
+				case CFG_DRIVER_ENABLE:
+					lp->driverEnable    = pLtv->u.u16[0];
+					pLtv->u.u16[0]      = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+				case CFG_WOLAS_ENABLE:
+					lp->wolasEnable = pLtv->u.u16[0];
+					pLtv->u.u16[0]  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+				case CFG_SET_WPA_AUTH_KEY_MGMT_SUITE:
+					lp->AuthKeyMgmtSuite = pLtv->u.u16[0];
+					pLtv->u.u16[0]  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+				case CFG_DISASSOCIATE_ADDR:
+					pLtv->u.u16[ETH_ALEN / 2] = CNV_INT_TO_LITTLE( pLtv->u.u16[ETH_ALEN / 2] );
+					break;
+				case CFG_ADD_TKIP_DEFAULT_KEY:
+				case CFG_REMOVE_TKIP_DEFAULT_KEY:
+					/* Endian convert the Tx Key Information */
+					pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
+					break;
+				case CFG_ADD_TKIP_MAPPED_KEY:
+					break;
+				case CFG_REMOVE_TKIP_MAPPED_KEY:
+					break;
+				/* some RIDs just can't be put */
+				case CFG_MB_INFO:
+				case CFG_IFB:
+				default:
+					break;
+				}
+
+				/* This code will prevent Static Configuration Entities from
+				   being sent to the card, as they require a call to
+				   UIL_ACT_APPLY to take effect. Dynamic Entities will be sent
+				   immediately */
+				switch( pLtv->typ ) {
+				case CFG_CNF_PORT_TYPE:
+				case CFG_CNF_OWN_MAC_ADDR:
+				case CFG_CNF_OWN_CHANNEL:
+				case CFG_CNF_OWN_SSID:
+				case CFG_CNF_OWN_ATIM_WINDOW:
+				case CFG_CNF_SYSTEM_SCALE:
+				case CFG_CNF_MAX_DATA_LEN:
+				case CFG_CNF_PM_ENABLED:
+				case CFG_CNF_MCAST_RX:
+				case CFG_CNF_MAX_SLEEP_DURATION:
+				case CFG_CNF_HOLDOVER_DURATION:
+				case CFG_CNF_OWN_NAME:
+				case CFG_CNF_LOAD_BALANCING:
+				case CFG_CNF_MEDIUM_DISTRIBUTION:
+#ifdef WARP
+				case CFG_CNF_TX_POW_LVL:
+				case CFG_CNF_CONNECTION_CNTL:
+				//case CFG_PROBE_DATA_RATE:
+#endif // HERMES25
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
+		//;?should we restore this to allow smaller memory footprint
+				case CFG_CNF_OWN_DTIM_PERIOD:
+#ifdef WARP
+				case CFG_CNF_OWN_BEACON_INTERVAL:                    // Own Beacon Interval
+#endif // WARP
+#ifdef USE_WDS
+				case CFG_CNF_WDS_ADDR1:
+				case CFG_CNF_WDS_ADDR2:
+				case CFG_CNF_WDS_ADDR3:
+				case CFG_CNF_WDS_ADDR4:
+				case CFG_CNF_WDS_ADDR5:
+				case CFG_CNF_WDS_ADDR6:
+#endif
+				case CFG_CNF_MCAST_PM_BUF:
+				case CFG_CNF_REJECT_ANY:
+#endif
+
+				case CFG_CNF_ENCRYPTION:
+				case CFG_CNF_AUTHENTICATION:
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
+		//;?should we restore this to allow smaller memory footprint
+
+				case CFG_CNF_EXCL_UNENCRYPTED:
+				case CFG_CNF_MCAST_RATE:
+				case CFG_CNF_INTRA_BSS_RELAY:
+#endif
+
+				case CFG_CNF_MICRO_WAVE:
+				//case CFG_CNF_LOAD_BALANCING:
+				//case CFG_CNF_MEDIUM_DISTRIBUTION:
+				//case CFG_CNF_RX_ALL_GROUP_ADDRESS:
+				//case CFG_CNF_COUNTRY_INFO:
+				//case CFG_COUNTRY_STRING:
+				case CFG_AP_MODE:
+				case CFG_ENCRYPT_STRING:
+				//case CFG_DRIVER_ENABLE:
+				case CFG_WOLAS_ENABLE:
+				case CFG_MB_INFO:
+				case CFG_IFB:
+					break;
+				/* Deal with this dynamic MSF RID, as it's required for WPA */
+				case CFG_DRIVER_ENABLE:
+					if( lp->driverEnable ) {
+						//hcf_cntl_port( &( lp->hcfCtx ),
+						//               HCF_PORT_ENABLE | HCF_PORT_0 );
+						// //hcf_cntl( &( lp->hcfCtx ),
+						// //         HCF_PORT_ENABLE | HCF_PORT_0 );
+						//hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_ENABLE );
+						// //hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_CONNECT );
+
+						hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_ENABLE | HCF_PORT_0 );
+						hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_CONNECT );
+					} else {
+						//hcf_cntl_port( &( lp->hcfCtx ),
+						//               HCF_PORT_DISABLE | HCF_PORT_0 );
+						// //hcf_cntl( &( lp->hcfCtx ),
+						// //         HCF_PORT_DISABLE | HCF_PORT_0 );
+						//hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_DISABLE );
+						// //hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_DISCONNECT );
+
+						hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_DISABLE | HCF_PORT_0 );
+						hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_DISCONNECT );
+					}
+					break;
+				default:
+    					wl_act_int_off( lp );
+					urq->result = hcf_put_info(&(lp->hcfCtx), (LTVP) pLtv);
+    					wl_act_int_on( lp );
+					break;
+				}
+
+				if( ltvAllocated ) {
+					kfree( pLtv );
+				}
+			} else {
+				urq->result = UIL_FAILURE;
+			}
+		} else {
+			DBG_ERROR( DbgInfo, "EPERM\n" );
+			urq->result = UIL_FAILURE;
+			result = -EPERM;
+		}
+	} else {
+		DBG_ERROR( DbgInfo, "UIL_ERR_WRONG_IFB\n" );
+		urq->result = UIL_ERR_WRONG_IFB;
+	}
+
+	DBG_LEAVE( DbgInfo );
+	return result;
+} // wvlan_uil_put_info
+/*============================================================================*/
+
+/*******************************************************************************
+ *	wvlan_uil_get_info()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Sends a specific RID directly to the driver to retrieve configuration
+ *      info.
+ *
+ *  PARAMETERS:
+ *
+ *      urq - a pointer to the UIL request buffer
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      UIL_SUCCESS
+ *      UIL_ERR_xxx value otherwise
+ *
+ ******************************************************************************/
+int wvlan_uil_get_info( struct uilreq *urq, struct wl_private *lp )
+{
+	int result = 0;
+	int i;
+	/*------------------------------------------------------------------------*/
+
+	DBG_FUNC( "wvlan_uil_get_info" );
+	DBG_ENTER( DbgInfo );
+
+	if( urq->hcfCtx == &( lp->hcfCtx )) {
+		if(( urq->data != NULL ) && ( urq->len != 0 )) {
+			ltv_t      *pLtv;
+			bool_t      ltvAllocated = FALSE;
+
+			/* Make sure that we have at least a command and length */
+			if( urq->len < ( sizeof( hcf_16 ) * 2 )) {
+				urq->len = sizeof( lp->ltvRecord );
+				DBG_ERROR( DbgInfo, "No Length/Type in LTV!!!\n" );
+				DBG_ERROR( DbgInfo, "UIL_ERR_LEN\n" );
+				urq->result = UIL_ERR_LEN;
+				DBG_LEAVE( DbgInfo );
+				return result;
+			}
+
+			/* Verify the user's LTV record header. */
+			result = verify_area( VERIFY_READ, urq->data, sizeof( hcf_16 ) * 2 );
+			if( result != 0 ) {
+				DBG_ERROR( DbgInfo, "verify_area(), VERIFY_READ FAILED\n" );
+				urq->result = UIL_FAILURE;
+				DBG_LEAVE( DbgInfo );
+				return result;
+			}
+
+			/* Get only the command and length information. */
+			result = copy_from_user( &( lp->ltvRecord ), urq->data, sizeof( hcf_16 ) * 2 );
+
+			/* Make sure the incoming LTV record length is within the bounds of
+			   the IOCTL length. */
+			if((( lp->ltvRecord.len + 1 ) * sizeof( hcf_16 )) > urq->len ) {
+				DBG_ERROR( DbgInfo, "Incoming LTV too big\n" );
+				urq->len = sizeof( lp->ltvRecord );
+				urq->result = UIL_ERR_LEN;
+				DBG_LEAVE( DbgInfo );
+				return result;
+			}
+
+			/* Determine if hcf_get_info() is needed or not */
+			switch ( lp->ltvRecord.typ ) {
+			case CFG_NIC_IDENTITY:
+				memcpy( &lp->ltvRecord.u.u8[0], &lp->NICIdentity, sizeof( lp->NICIdentity ));
+				break;
+			case CFG_PRI_IDENTITY:
+				memcpy( &lp->ltvRecord.u.u8[0], &lp->PrimaryIdentity, sizeof( lp->PrimaryIdentity ));
+				break;
+			case CFG_AP_MODE:
+				DBG_ERROR( DbgInfo, "set CFG_AP_MODE no longer supported, so is get useful ????\n" );
+				lp->ltvRecord.u.u16[0] =
+					CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP;
+				break;
+			//case CFG_DRV_INFO:
+			case CFG_ENCRYPT_STRING:
+			case CFG_COUNTRY_STRING:
+			case CFG_DRIVER_ENABLE:
+			case CFG_WOLAS_ENABLE:
+				// TODO: determine if we're going to support these
+				urq->result = UIL_FAILURE;
+				break;
+			case CFG_DRV_INFO:
+				DBG_TRACE( DbgInfo, "Intercept CFG_DRV_INFO\n" );
+				result = cfg_driver_info( urq, lp );
+				break;
+			case CFG_DRV_IDENTITY:
+				DBG_TRACE( DbgInfo, "Intercept CFG_DRV_IDENTITY\n" );
+				result = cfg_driver_identity( urq, lp );
+				break;
+			case CFG_IFB:
+				/* IFB can be a security hole */
+				if( !capable( CAP_NET_ADMIN )) {
+					result = -EPERM;
+					break;
+				}
+
+				/* Else fall through to the default */
+
+			case CFG_FW_IDENTITY:   // For Hermes-1, this is cached
+			default:
+
+				/* Verify the user buffer */
+				result = verify_area( VERIFY_WRITE, urq->data, urq->len );
+				if( result != 0 ) {
+					DBG_ERROR( DbgInfo, "verify_area(), VERIFY_WRITE FAILED\n" );
+					urq->result = UIL_FAILURE;
+					break;
+				}
+
+				/* If the requested length is greater than the size of our local
+				   LTV record, try to allocate it from the kernel stack.
+				   Otherwise, we just use our local LTV record. */
+				if( urq->len > sizeof( lp->ltvRecord )) {
+					if(( pLtv = (ltv_t *)kmalloc( urq->len, GFP_KERNEL )) != NULL ) {
+						ltvAllocated = TRUE;
+
+						/* Copy the command/length information into the new buffer. */
+						memcpy( pLtv, &( lp->ltvRecord ), sizeof( hcf_16 ) * 2 );
+					} else {
+						urq->len = sizeof( lp->ltvRecord );
+						urq->result = UIL_ERR_LEN;
+						DBG_ERROR( DbgInfo, "kmalloc FAILED\n" );
+						DBG_ERROR( DbgInfo, "UIL_ERR_LEN\n" );
+						result = -ENOMEM;
+						break;
+					}
+				} else {
+					pLtv = &( lp->ltvRecord );
+				}
+
+    				wl_act_int_off( lp );
+				urq->result = hcf_get_info( &( lp->hcfCtx ), (LTVP) pLtv );
+    				wl_act_int_on( lp );
+
+				// Copy the LTV into the user's buffer.
+				//copy_to_user( urq->data, pLtv, urq->len );
+
+				//if( ltvAllocated )
+				//{
+				//    kfree( pLtv );
+				//}
+
+				//urq->result = UIL_SUCCESS;
+				break;
+			}
+
+			/* Handle endian conversion of special fields */
+			switch( lp->ltvRecord.typ ) {
+			/* simple int gets just need the first hcf_16 byte flipped */
+			case CFG_CNF_PORT_TYPE:
+			case CFG_CNF_OWN_CHANNEL:
+			case CFG_CNF_OWN_ATIM_WINDOW:
+			case CFG_CNF_SYSTEM_SCALE:
+			case CFG_CNF_MAX_DATA_LEN:
+			case CFG_CNF_PM_ENABLED:
+			case CFG_CNF_MCAST_RX:
+			case CFG_CNF_MAX_SLEEP_DURATION:
+			case CFG_CNF_HOLDOVER_DURATION:
+			case CFG_CNF_OWN_DTIM_PERIOD:
+			case CFG_CNF_MCAST_PM_BUF:
+			case CFG_CNF_REJECT_ANY:
+			case CFG_CNF_ENCRYPTION:
+			case CFG_CNF_AUTHENTICATION:
+			case CFG_CNF_EXCL_UNENCRYPTED:
+			case CFG_CNF_INTRA_BSS_RELAY:
+			case CFG_CNF_MICRO_WAVE:
+			case CFG_CNF_LOAD_BALANCING:
+			case CFG_CNF_MEDIUM_DISTRIBUTION:
+#ifdef WARP
+			case CFG_CNF_TX_POW_LVL:
+			case CFG_CNF_CONNECTION_CNTL:
+			case CFG_CNF_OWN_BEACON_INTERVAL:                          // Own Beacon Interval
+			case CFG_COEXISTENSE_BEHAVIOUR:                            // Coexistence Behavior
+			//case CFG_CNF_RX_ALL_GROUP_ADDRESS:
+#endif // HERMES25
+			case CFG_CREATE_IBSS:
+			case CFG_RTS_THRH:
+			case CFG_PROMISCUOUS_MODE:
+			//case CFG_WAKE_ON_LAN:
+			case CFG_RTS_THRH0:
+			case CFG_RTS_THRH1:
+			case CFG_RTS_THRH2:
+			case CFG_RTS_THRH3:
+			case CFG_RTS_THRH4:
+			case CFG_RTS_THRH5:
+			case CFG_RTS_THRH6:
+			case CFG_TX_RATE_CNTL0:
+			case CFG_TX_RATE_CNTL1:
+			case CFG_TX_RATE_CNTL2:
+			case CFG_TX_RATE_CNTL3:
+			case CFG_TX_RATE_CNTL4:
+			case CFG_TX_RATE_CNTL5:
+			case CFG_TX_RATE_CNTL6:
+			case CFG_TX_KEY_ID:
+			case CFG_TICK_TIME:
+			case CFG_MAX_LOAD_TIME:
+			case CFG_NIC_TEMP_TYPE:
+			case CFG_PORT_STAT:
+			case CFG_CUR_TX_RATE:
+			case CFG_CUR_BEACON_INTERVAL:
+			case CFG_PROTOCOL_RSP_TIME:
+			case CFG_CUR_SHORT_RETRY_LIMIT:
+			case CFG_CUR_LONG_RETRY_LIMIT:
+			case CFG_MAX_TX_LIFETIME:
+			case CFG_MAX_RX_LIFETIME:
+			case CFG_CF_POLLABLE:
+			case CFG_PRIVACY_OPT_IMPLEMENTED:
+			//case CFG_CURRENT_REMOTE_RATES:
+			//case CFG_CURRENT_USED_RATES:
+			//case CFG_CURRENT_SYSTEM_SCALE:
+			//case CFG_CURRENT_TX_RATE1:
+			//case CFG_CURRENT_TX_RATE2:
+			//case CFG_CURRENT_TX_RATE3:
+			//case CFG_CURRENT_TX_RATE4:
+			//case CFG_CURRENT_TX_RATE5:
+			//case CFG_CURRENT_TX_RATE6:
+			case CFG_PHY_TYPE:
+			case CFG_CUR_CHANNEL:
+			//case CFG_CURRENT_POWER_STATE:
+			//case CFG_CCAMODE:
+			//    lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] );
+			//    break;
+			/* name string gets just need the first hcf_16 byte flipped (length of string) */
+			case CFG_CNF_OWN_SSID:
+			case CFG_CNF_OWN_NAME:
+			//case CNF_DESIRED_SSID:
+			case CFG_DESIRED_SSID:
+			case CFG_SCAN_SSID:
+			case CFG_CUR_SSID:
+				lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] );
+				break;
+			/* non-length counted strings need no byte flipping */
+			case CFG_CNF_OWN_MAC_ADDR:
+			/* this case is no longer valid: CFG_CNF_WDS_ADDR */
+			case CFG_CNF_WDS_ADDR1:
+			case CFG_CNF_WDS_ADDR2:
+			case CFG_CNF_WDS_ADDR3:
+			case CFG_CNF_WDS_ADDR4:
+			case CFG_CNF_WDS_ADDR5:
+			case CFG_CNF_WDS_ADDR6:
+			case CFG_GROUP_ADDR:
+			case CFG_NIC_SERIAL_NUMBER:
+			case CFG_CUR_BSSID:
+			case CFG_NIC_MAC_ADDR:
+			case CFG_SUPPORTED_DATA_RATES:  /* need to ensure we can treat this as a string */
+				break;
+			//case CFG_CNF_COUNTRY_INFO:      /* special case, see page 75  of 022486, Rev C. */
+			//case CFG_CURRENT_COUNTRY_INFO:  /* special case, see page 101 of 022486, Rev C. */
+			/*
+				lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] );
+				lp->ltvRecord.u.u16[3] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[3] );
+
+				for( i = 4; i < lp->ltvRecord.len; i++ ) {
+					lp->ltvRecord.u.u16[i] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[i] );
+				}
+				break;
+			*/
+
+			case CFG_DEFAULT_KEYS:
+				{
+					CFG_DEFAULT_KEYS_STRCT *pKeys = (CFG_DEFAULT_KEYS_STRCT *)&lp->ltvRecord.u.u8[0];
+
+					pKeys[0].len = CNV_INT_TO_LITTLE( pKeys[0].len );
+					pKeys[1].len = CNV_INT_TO_LITTLE( pKeys[1].len );
+					pKeys[2].len = CNV_INT_TO_LITTLE( pKeys[2].len );
+					pKeys[3].len = CNV_INT_TO_LITTLE( pKeys[3].len );
+				}
+				break;
+			case CFG_CNF_MCAST_RATE:
+			case CFG_TX_RATE_CNTL:
+			case CFG_SUPPORTED_RATE_SET_CNTL:    // Supported Rate Set Control
+			case CFG_BASIC_RATE_SET_CNTL:    // Basic Rate Set Control
+				lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] );
+				lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[1] );
+				break;
+			case CFG_DL_BUF:
+			case CFG_NIC_IDENTITY:
+			case CFG_COMMS_QUALITY:
+			case CFG_PCF_INFO:
+				lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] );
+				lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[1] );
+				lp->ltvRecord.u.u16[2] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[2] );
+				break;
+			case CFG_FW_IDENTITY:
+				lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] );
+				lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[1] );
+				lp->ltvRecord.u.u16[2] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[2] );
+				lp->ltvRecord.u.u16[3] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[3] );
+				break;
+			//case CFG_HSI_SUP_RANGE:
+			case CFG_NIC_MFI_SUP_RANGE:
+			case CFG_NIC_CFI_SUP_RANGE:
+			case CFG_NIC_PROFILE:
+			case CFG_FW_SUP_RANGE:
+				lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] );
+				lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[1] );
+				lp->ltvRecord.u.u16[2] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[2] );
+				lp->ltvRecord.u.u16[3] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[3] );
+				lp->ltvRecord.u.u16[4] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[4] );
+				break;
+			case CFG_MFI_ACT_RANGES_STA:
+			case CFG_CFI_ACT_RANGES_STA:
+			case CFG_CUR_SCALE_THRH:
+			case CFG_AUTHENTICATION_ALGORITHMS:
+				for( i = 0; i < ( lp->ltvRecord.len - 1 ); i++ ) {
+					lp->ltvRecord.u.u16[i] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[i] );
+				}
+				break;
+			/* done at init time, and endian handled then */
+			case CFG_PRI_IDENTITY:
+				break;
+			case CFG_MB_INFO:
+				//wvlanEndianTranslateMailbox( pLtv );
+				break;
+			/* MSF and HCF RIDS */
+			case CFG_IFB:
+			case CFG_DRV_INFO:
+			case CFG_AP_MODE:
+			case CFG_ENCRYPT_STRING:
+			case CFG_COUNTRY_STRING:
+			case CFG_DRIVER_ENABLE:
+			case CFG_WOLAS_ENABLE:
+			default:
+				break;
+			}
+
+			// Copy the LTV into the user's buffer.
+			copy_to_user( urq->data, &( lp->ltvRecord ), urq->len );
+
+			if( ltvAllocated ) {
+				kfree( &( lp->ltvRecord ));
+			}
+
+			urq->result = UIL_SUCCESS;
+		} else {
+			urq->result = UIL_FAILURE;
+		}
+	} else {
+		DBG_ERROR( DbgInfo, "UIL_ERR_WRONG_IFB\n" );
+		urq->result = UIL_ERR_WRONG_IFB;
+	}
+
+	DBG_LEAVE( DbgInfo );
+	return result;
+} // wvlan_uil_get_info
+/*============================================================================*/
+
+
+
+
+
+/*******************************************************************************
+ *	cfg_driver_info()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Retrieves driver information.
+ *
+ *  PARAMETERS:
+ *
+ *      urq - a pointer to the UIL request buffer
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      UIL_SUCCESS
+ *      UIL_ERR_xxx value otherwise
+ *
+ ******************************************************************************/
+int cfg_driver_info( struct uilreq *urq, struct wl_private *lp )
+{
+	int result = 0;
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "cfg_driver_info" );
+	DBG_ENTER( DbgInfo );
+
+
+	/* Make sure that user buffer can handle the driver information buffer */
+	if( urq->len < sizeof( lp->driverInfo )) {
+		urq->len = sizeof( lp->driverInfo );
+		urq->result = UIL_ERR_LEN;
+		DBG_LEAVE( DbgInfo );
+		return result;
+	}
+
+	/* Verify the user buffer. */
+	result = verify_area( VERIFY_WRITE, urq->data, sizeof( lp->driverInfo ));
+	if( result != 0 ) {
+		urq->result = UIL_FAILURE;
+		DBG_LEAVE( DbgInfo );
+		return result;
+	}
+
+	lp->driverInfo.card_stat = lp->hcfCtx.IFB_CardStat;
+
+	// Copy the driver information into the user's buffer.
+	urq->result = UIL_SUCCESS;
+	copy_to_user( urq->data, &( lp->driverInfo ), sizeof( lp->driverInfo ));
+
+	DBG_LEAVE( DbgInfo );
+	return result;
+} // cfg_driver_info
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	cfg_driver_identity()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Retrieves ID information from the card.
+ *
+ *  PARAMETERS:
+ *
+ *      urq - a pointer to the UIL request buffer
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      UIL_SUCCESS
+ *      UIL_ERR_xxx value otherwise
+ *
+ ******************************************************************************/
+int cfg_driver_identity( struct uilreq *urq, struct wl_private *lp )
+{
+	int result = 0;
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wvlan_driver_identity" );
+	DBG_ENTER( DbgInfo );
+
+
+	/* Make sure that user buffer can handle the driver identity structure. */
+	if( urq->len < sizeof( lp->driverIdentity )) {
+		urq->len = sizeof( lp->driverIdentity );
+		urq->result = UIL_ERR_LEN;
+		DBG_LEAVE( DbgInfo );
+		return result;
+	}
+
+	/* Verify the user buffer. */
+	result = verify_area( VERIFY_WRITE, urq->data, sizeof( lp->driverIdentity ));
+	if( result != 0 ) {
+		urq->result = UIL_FAILURE;
+		DBG_LEAVE( DbgInfo );
+		return result;
+	}
+
+	/* Copy the driver identity into the user's buffer. */
+	urq->result = UIL_SUCCESS;
+	copy_to_user( urq->data, &( lp->driverIdentity ), sizeof( lp->driverIdentity ));
+
+	DBG_LEAVE( DbgInfo );
+	return result;
+} // cfg_driver_identity
+/*============================================================================*/
+
+
+#endif  /* USE_UIL */
+
+
+/* If WIRELESS_EXT is not defined, then the functions that follow will not be
+   included in the build. */
+/* NOTE: Are these still even needed? */
+#ifdef WIRELESS_EXT
+
+
+/*******************************************************************************
+ *	wvlan_set_netname()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Set the ESSID of the card.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - a pointer to the wireless request buffer
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wvlan_set_netname(struct net_device *dev,
+		      struct iw_request_info *info,
+		      union iwreq_data *wrqu,
+		      char *extra)
+{
+        struct wl_private *lp = wl_priv(dev);
+        unsigned long flags;
+	int ret = 0;
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wvlan_set_netname" );
+	DBG_ENTER( DbgInfo );
+
+        wl_lock(lp, &flags);
+
+        memset( lp->NetworkName, 0, sizeof( lp->NetworkName ));
+        memcpy( lp->NetworkName, extra, wrqu->data.length);
+
+	/* Commit the adapter parameters */
+	wl_apply(lp);
+        wl_unlock(lp, &flags);
+
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wvlan_set_netname
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wvlan_get_netname()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Get the ESSID of the card.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - a pointer to the wireless request buffer
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wvlan_get_netname(struct net_device *dev,
+		      struct iw_request_info *info,
+		      union iwreq_data *wrqu,
+		      char *extra)
+{
+        struct wl_private *lp = wl_priv(dev);
+        unsigned long flags;
+        int         ret = 0;
+        int         status = -1;
+        wvName_t   *pName;
+	/*------------------------------------------------------------------------*/
+
+
+        DBG_FUNC( "wvlan_get_netname" );
+        DBG_ENTER( DbgInfo );
+
+        wl_lock(lp, &flags);
+
+        /* Get the current network name */
+        lp->ltvRecord.len = 1 + ( sizeof( *pName ) / sizeof( hcf_16 ));
+        lp->ltvRecord.typ = CFG_CUR_SSID;
+
+        status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+
+        if( status == HCF_SUCCESS ) {
+                pName = (wvName_t *)&( lp->ltvRecord.u.u32 );
+
+		memset(extra, '\0', HCF_MAX_NAME_LEN);
+		wrqu->data.length = pName->length;
+
+                memcpy(extra, pName->name, pName->length);
+        } else {
+                ret = -EFAULT;
+	}
+
+        wl_unlock(lp, &flags);
+
+        DBG_LEAVE( DbgInfo );
+        return ret;
+} // wvlan_get_netname
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wvlan_set_station_nickname()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Set the card's station nickname.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - a pointer to the wireless request buffer
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wvlan_set_station_nickname(struct net_device *dev,
+		      struct iw_request_info *info,
+		      union iwreq_data *wrqu,
+		      char *extra)
+{
+        struct wl_private *lp = wl_priv(dev);
+        unsigned long flags;
+        int         ret = 0;
+	/*------------------------------------------------------------------------*/
+
+
+        DBG_FUNC( "wvlan_set_station_nickname" );
+        DBG_ENTER( DbgInfo );
+
+        wl_lock(lp, &flags);
+
+        memset( lp->StationName, 0, sizeof( lp->StationName ));
+
+        memcpy( lp->StationName, extra, wrqu->data.length);
+
+        /* Commit the adapter parameters */
+        wl_apply( lp );
+        wl_unlock(lp, &flags);
+
+        DBG_LEAVE( DbgInfo );
+        return ret;
+} // wvlan_set_station_nickname
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wvlan_get_station_nickname()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Get the card's station nickname.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - a pointer to the wireless request buffer
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wvlan_get_station_nickname(struct net_device *dev,
+		      struct iw_request_info *info,
+		      union iwreq_data *wrqu,
+		      char *extra)
+{
+        struct wl_private *lp = wl_priv(dev);
+        unsigned long flags;
+	int         ret = 0;
+	int         status = -1;
+	wvName_t   *pName;
+	/*------------------------------------------------------------------------*/
+
+
+        DBG_FUNC( "wvlan_get_station_nickname" );
+        DBG_ENTER( DbgInfo );
+
+        wl_lock( lp, &flags );
+
+        /* Get the current station name */
+        lp->ltvRecord.len = 1 + ( sizeof( *pName ) / sizeof( hcf_16 ));
+        lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
+
+        status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+
+        if( status == HCF_SUCCESS ) {
+                pName = (wvName_t *)&( lp->ltvRecord.u.u32 );
+
+		memset(extra, '\0', HCF_MAX_NAME_LEN);
+		wrqu->data.length = pName->length;
+		memcpy(extra, pName->name, pName->length);
+        } else {
+                ret = -EFAULT;
+        }
+
+        wl_unlock(lp, &flags);
+
+//out:
+        DBG_LEAVE( DbgInfo );
+	return ret;
+} // wvlan_get_station_nickname
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wvlan_set_porttype()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Set the card's porttype
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - a pointer to the wireless request buffer
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wvlan_set_porttype(struct net_device *dev,
+		      struct iw_request_info *info,
+		      union iwreq_data *wrqu,
+		      char *extra)
+{
+        struct wl_private *lp = wl_priv(dev);
+        unsigned long flags;
+        int     ret = 0;
+	hcf_16  portType;
+	/*------------------------------------------------------------------------*/
+
+
+        DBG_FUNC( "wvlan_set_porttype" );
+        DBG_ENTER( DbgInfo );
+
+        wl_lock(lp, &flags);
+
+        /* Validate the new value */
+        portType = *((__u32 *)extra);
+
+        if( !(( portType == 1 ) || ( portType == 3 ))) {
+                ret = -EINVAL;
+		goto out_unlock;
+        }
+
+        lp->PortType = portType;
+
+        /* Commit the adapter parameters */
+        wl_apply( lp );
+
+out_unlock:
+        wl_unlock(lp, &flags);
+
+//out:
+        DBG_LEAVE( DbgInfo );
+        return ret;
+}
+
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wvlan_get_porttype()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Get the card's porttype
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - a pointer to the wireless request buffer
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wvlan_get_porttype(struct net_device *dev,
+		      struct iw_request_info *info,
+		      union iwreq_data *wrqu,
+		      char *extra)
+{
+        struct wl_private *lp = wl_priv(dev);
+        unsigned long flags;
+        int     ret = 0;
+        int     status = -1;
+        hcf_16  *pPortType;
+        __u32 *pData = (__u32 *)extra;
+	/*------------------------------------------------------------------------*/
+
+
+        DBG_FUNC( "wvlan_get_porttype" );
+        DBG_ENTER( DbgInfo );
+
+        wl_lock( lp, &flags );
+
+        /* Get the current port type */
+        lp->ltvRecord.len = 1 + ( sizeof( *pPortType ) / sizeof( hcf_16 ));
+        lp->ltvRecord.typ = CFG_CNF_PORT_TYPE;
+
+        status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+
+        if( status == HCF_SUCCESS ) {
+                pPortType = (hcf_16 *)&( lp->ltvRecord.u.u32 );
+
+                *pData = CNV_LITTLE_TO_INT( *pPortType );
+        } else {
+            ret = -EFAULT;
+	}
+
+        wl_unlock(lp, &flags);
+
+//out:
+        DBG_LEAVE( DbgInfo );
+        return ret;
+} // wvlan_get_porttype
+/*============================================================================*/
+
+#endif  // WIRELESS_EXT
+
+
+
+
+#ifdef USE_RTS
+/*******************************************************************************
+ *	wvlan_rts()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      IOCTL handler for RTS commands
+ *
+ *  PARAMETERS:
+ *
+ *      rrq - a pointer to the rts request buffer
+ *      lp  - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wvlan_rts( struct rtsreq *rrq, __u32 io_base )
+{
+	int ioctl_ret = 0;
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wvlan_rts" );
+	DBG_ENTER( DbgInfo );
+
+
+	DBG_PRINT( "io_base: 0x%08x\n", io_base );
+
+	switch( rrq->typ ) {
+	  case WL_IOCTL_RTS_READ:
+		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_RTS -- WL_IOCTL_RTS_READ\n");
+		rrq->data[0] = IN_PORT_WORD( io_base + rrq->reg );
+		DBG_TRACE( DbgInfo, "  reg 0x%04x ==> 0x%04x\n", rrq->reg, CNV_LITTLE_TO_SHORT( rrq->data[0] ) );
+		break;
+	  case WL_IOCTL_RTS_WRITE:
+		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_RTS -- WL_IOCTL_RTS_WRITE\n");
+		OUT_PORT_WORD( io_base + rrq->reg, rrq->data[0] );
+		DBG_TRACE( DbgInfo, "  reg 0x%04x <== 0x%04x\n", rrq->reg, CNV_LITTLE_TO_SHORT( rrq->data[0] ) );
+		break;
+	  case WL_IOCTL_RTS_BATCH_READ:
+		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_RTS -- WL_IOCTL_RTS_BATCH_READ\n");
+		IN_PORT_STRING_16( io_base + rrq->reg, rrq->data, rrq->len );
+		DBG_TRACE( DbgInfo, "  reg 0x%04x ==> %d bytes\n", rrq->reg, rrq->len * sizeof (__u16 ) );
+		break;
+	  case WL_IOCTL_RTS_BATCH_WRITE:
+		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_RTS -- WL_IOCTL_RTS_BATCH_WRITE\n");
+		OUT_PORT_STRING_16( io_base + rrq->reg, rrq->data, rrq->len );
+		DBG_TRACE( DbgInfo, "  reg 0x%04x <== %d bytes\n", rrq->reg, rrq->len * sizeof (__u16) );
+		break;
+	default:
+
+		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_RTS -- UNSUPPORTED RTS CODE: 0x%X", rrq->typ );
+		ioctl_ret = -EOPNOTSUPP;
+		break;
+	}
+
+	DBG_LEAVE( DbgInfo );
+	return ioctl_ret;
+} // wvlan_rts
+/*============================================================================*/
+
+#endif  /* USE_RTS */
diff --git a/drivers/staging/wlags49_h2/wl_priv.h b/drivers/staging/wlags49_h2/wl_priv.h
new file mode 100644
index 0000000..9b02544
--- /dev/null
+++ b/drivers/staging/wlags49_h2/wl_priv.h
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Agere Systems Inc.
+ * Wireless device driver for Linux (wlags49).
+ *
+ * Copyright (c) 1998-2003 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * Initially developed by TriplePoint, Inc.
+ *   http://www.triplepoint.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ *   Header describing information required for the private IOCTL handlers.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2003 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following Disclaimer as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ ******************************************************************************/
+
+#ifndef __WL_PRIV_H__
+#define __WL_PRIV_H__
+
+
+
+
+/*******************************************************************************
+ *  function prototypes
+ ******************************************************************************/
+#ifdef WIRELESS_EXT
+
+
+int wvlan_set_netname( struct net_device *,  struct iw_request_info *, union iwreq_data *, char *extra );
+
+int wvlan_get_netname( struct net_device *,  struct iw_request_info *, union iwreq_data *, char *extra );
+
+int wvlan_set_station_nickname( struct net_device *,  struct iw_request_info *, union iwreq_data *, char *extra );
+
+int wvlan_get_station_nickname( struct net_device *,  struct iw_request_info *, union iwreq_data *, char *extra );
+
+int wvlan_set_porttype( struct net_device *,  struct iw_request_info *, union iwreq_data *, char *extra );
+
+int wvlan_get_porttype( struct net_device *,  struct iw_request_info *, union iwreq_data *, char *extra );
+
+
+#endif  // WIRELESS_EXT
+
+
+
+
+#ifdef USE_UIL
+
+int wvlan_uil( struct uilreq *urq, struct wl_private *lp );
+
+// int wvlan_uil_connect( struct uilreq *urq, struct wl_private *lp );
+// int wvlan_uil_disconnect( struct uilreq *urq, struct wl_private *lp );
+// int wvlan_uil_action( struct uilreq *urq, struct wl_private *lp );
+// int wvlan_uil_block( struct uilreq *urq, struct wl_private *lp );
+// int wvlan_uil_unblock( struct uilreq *urq, struct wl_private *lp );
+// int wvlan_uil_send_diag_msg( struct uilreq *urq, struct wl_private *lp );
+// int wvlan_uil_put_info( struct uilreq *urq, struct wl_private *lp );
+// int wvlan_uil_get_info( struct uilreq *urq, struct wl_private *lp );
+
+//int cfg_driver_info( struct uilreq *urq, struct wl_private *lp );
+//int cfg_driver_identity( struct uilreq *urq, struct wl_private *lp );
+
+#endif  // USE_UIL
+
+
+#ifdef USE_RTS
+
+int wvlan_rts( struct rtsreq *rrq, __u32 io_base );
+int wvlan_rts_read( __u16 reg, __u16 *val, __u32 io_base );
+int wvlan_rts_write( __u16 reg, __u16 val, __u32 io_base );
+int wvlan_rts_batch_read( struct rtsreq *rrq, __u32 io_base );
+int wvlan_rts_batch_write( struct rtsreq *rrq, __u32 io_base );
+
+#endif  // USE_RTS
+
+
+#endif  // __WL_PRIV_H__
diff --git a/drivers/staging/wlags49_h2/wl_profile.c b/drivers/staging/wlags49_h2/wl_profile.c
new file mode 100644
index 0000000..715f027
--- /dev/null
+++ b/drivers/staging/wlags49_h2/wl_profile.c
@@ -0,0 +1,1111 @@
+/*******************************************************************************
+ * Agere Systems Inc.
+ * Wireless device driver for Linux (wlags49).
+ *
+ * Copyright (c) 1998-2003 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * Initially developed by TriplePoint, Inc.
+ *   http://www.triplepoint.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ *   This file defines routines required to parse configuration parameters
+ *   listed in a config file, if that config file exists.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2003 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following Disclaimer as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ ******************************************************************************/
+
+/* Only include this file if USE_PROFILE is defined */
+#ifdef USE_PROFILE
+
+
+
+
+/*******************************************************************************
+ *  constant definitions
+ ******************************************************************************/
+
+
+/* Allow support for calling system fcns to parse config file */
+#define __KERNEL_SYSCALLS__
+
+
+
+
+/*******************************************************************************
+ * include files
+ ******************************************************************************/
+#include <wl_version.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/unistd.h>
+#include <asm/uaccess.h>
+#include <limits.h>
+
+#define BIN_DL 1
+
+#include <debug.h>
+#include <hcf.h>
+//#include <hcfdef.h>
+
+#include <wl_if.h>
+#include <wl_internal.h>
+#include <wl_util.h>
+#include <wl_enc.h>
+#include <wl_main.h>
+#include <wl_profile.h>
+
+
+/*******************************************************************************
+ * global variables
+ ******************************************************************************/
+
+/* Definition needed to prevent unresolved external in unistd.h */
+static int errno;
+
+#if DBG
+extern p_u32    DebugFlag;
+extern dbg_info_t *DbgInfo;
+#endif
+
+int parse_yes_no( char* value );
+
+
+int parse_yes_no( char* value ) {
+int rc = 0;										//default to NO for invalid parameters
+
+	if ( strlen( value ) == 1 ) {
+		if ( ( value[0] | ('Y'^'y') ) == 'y' ) rc = 1;
+//	} else {
+//		this should not be debug time info, it is an enduser data entry error ;?
+//		DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MICROWAVE_ROBUSTNESS );
+	}
+	return rc;
+} // parse_yes_no
+
+
+/*******************************************************************************
+ *	parse_config()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function opens the device's config file and parses the options from
+ *   it, so that it can properly configure itself. If no configuration file
+ *   or configuration is present, then continue to use the options already
+ *   parsed from config.opts or wireless.opts.
+ *
+ *  PARAMETERS:
+ *
+ *      dev - a pointer to the device's net_device structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void parse_config( struct net_device *dev )
+{
+	int				    file_desc;
+#if 0 // BIN_DL
+	int 	 			rc;
+	char				*cp = NULL;
+#endif // BIN_DL
+	char                buffer[MAX_LINE_SIZE];
+	char                filename[MAX_LINE_SIZE];
+	mm_segment_t	    fs;
+	struct wl_private   *wvlan_config = NULL;
+	ENCSTRCT            sEncryption;
+	/*------------------------------------------------------------------------*/
+
+	DBG_FUNC( "parse_config" );
+	DBG_ENTER( DbgInfo );
+
+	/* Get the wavelan specific info for this device */
+	wvlan_config = (struct wl_private *)dev->priv;
+	if ( wvlan_config == NULL ) {
+		DBG_ERROR( DbgInfo, "Wavelan specific info struct not present?\n" );
+		return;
+	}
+
+	/* setup the default encryption string */
+	strcpy( wvlan_config->szEncryption, DEF_CRYPT_STR );
+
+	/* Obtain a user-space process context, storing the original context */
+	fs = get_fs( );
+	set_fs( get_ds( ));
+
+	/* Determine the filename for this device and attempt to open it */
+	sprintf( filename, "%s%s", ROOT_CONFIG_FILENAME, dev->name );
+	file_desc = open( filename, O_RDONLY, 0 );
+	if ( file_desc != -1 ) {
+		DBG_TRACE( DbgInfo, "Wireless config file found. Parsing options...\n" );
+
+		/* Read out the options */
+		while( readline( file_desc, buffer )) {
+			translate_option( buffer, wvlan_config );
+		}
+		/* Close the file */
+		close( file_desc );	//;?even if file_desc == -1 ???
+	} else {
+		DBG_TRACE( DbgInfo, "No iwconfig file found for this device; "
+				   "config.opts or wireless.opts will be used\n" );
+	}
+	/* Return to the original context */
+	set_fs( fs );
+
+	/* convert the WEP keys, if read in as key1, key2, type of data */
+	if ( wvlan_config->EnableEncryption ) {
+		memset( &sEncryption, 0, sizeof( sEncryption ));
+
+		wl_wep_decode( CRYPT_CODE, &sEncryption,
+						   wvlan_config->szEncryption );
+
+		/* the Linux driver likes to use 1-4 for the key IDs, and then
+		   convert to 0-3 when sending to the card.  The Windows code
+		   base used 0-3 in the API DLL, which was ported to Linux.  For
+		   the sake of the user experience, we decided to keep 0-3 as the
+		   numbers used in the DLL; and will perform the +1 conversion here.
+		   We could have converted  the entire Linux driver, but this is
+		   less obtrusive.  This may be a "todo" to convert the whole driver */
+		sEncryption.wEnabled = wvlan_config->EnableEncryption;
+		sEncryption.wTxKeyID = wvlan_config->TransmitKeyID - 1;
+
+		memcpy( &sEncryption.EncStr, &wvlan_config->DefaultKeys,
+				sizeof( CFG_DEFAULT_KEYS_STRCT ));
+
+		memset( wvlan_config->szEncryption, 0, sizeof( wvlan_config->szEncryption ));
+
+		wl_wep_code( CRYPT_CODE, wvlan_config->szEncryption, &sEncryption,
+						 sizeof( sEncryption ));
+	}
+
+	/* decode the encryption string for the call to wl_commit() */
+	wl_wep_decode( CRYPT_CODE, &sEncryption, wvlan_config->szEncryption );
+
+	wvlan_config->TransmitKeyID    = sEncryption.wTxKeyID + 1;
+	wvlan_config->EnableEncryption = sEncryption.wEnabled;
+
+	memcpy( &wvlan_config->DefaultKeys, &sEncryption.EncStr,
+			sizeof( CFG_DEFAULT_KEYS_STRCT ));
+
+#if 0 //BIN_DL
+		/* Obtain a user-space process context, storing the original context */
+		fs = get_fs( );
+		set_fs( get_ds( ));
+
+		//;?just to fake something
+		strcpy(/*wvlan_config->fw_image_*/filename, "/etc/agere/fw.bin" );
+		file_desc = open( /*wvlan_config->fw_image_*/filename, 0, 0 );
+		if ( file_desc == -1 ) {
+			DBG_ERROR( DbgInfo, "No image file found\n" );
+		} else {
+			DBG_TRACE( DbgInfo, "F/W image file found\n" );
+#define DHF_ALLOC_SIZE 96000			//just below 96K, let's hope it suffices for now and for the future
+			cp = (char*)vmalloc( DHF_ALLOC_SIZE );
+			if ( cp == NULL ) {
+				DBG_ERROR( DbgInfo, "error in vmalloc\n" );
+			} else {
+				rc = read( file_desc, cp, DHF_ALLOC_SIZE );
+				if ( rc == DHF_ALLOC_SIZE ) {
+					DBG_ERROR( DbgInfo, "buffer too small, %d\n", DHF_ALLOC_SIZE );
+				} else if ( rc > 0 ) {
+					DBG_TRACE( DbgInfo, "read O.K.: %d bytes  %.12s\n", rc, cp );
+					rc = read( file_desc, &cp[rc], 1 );
+					if ( rc == 0 ) {
+						DBG_TRACE( DbgInfo, "no more to read\n" );
+					}
+				}
+				if ( rc != 0 ) {
+					DBG_ERROR( DbgInfo, "file not read in one swoop or other error"\
+										", give up, too complicated, rc = %0X\n", rc );
+				}
+				vfree( cp );
+			}
+			close( file_desc );
+		}
+		set_fs( fs );			/* Return to the original context */
+#endif // BIN_DL
+
+	DBG_LEAVE( DbgInfo );
+	return;
+} // parse_config
+
+/*******************************************************************************
+ *	readline()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function reads in data from a given file one line at a time,
+ *   converting the detected newline character '\n' to a null '\0'. Note that
+ *   the file descriptor must be valid before calling this function.
+ *
+ *  PARAMETERS:
+ *
+ *      filedesc    - the file descriptor for the open configuration file
+ *      buffer      - a buffer pointer, passed in by the caller, to which the
+ *                    line will be stored.
+ *
+ *  RETURNS:
+ *
+ *      the number of bytes read
+ *      -1 on error
+ *
+ ******************************************************************************/
+int readline( int filedesc, char *buffer )
+{
+	int result = -1;
+	int bytes_read = 0;
+	/*------------------------------------------------------------------------*/
+
+	/* Make sure the file descriptor is good */
+	if ( filedesc != -1 ) {
+		/* Read in from the file byte by byte until a newline is reached */
+		while(( result = read( filedesc, &buffer[bytes_read], 1 )) == 1 ) {
+			if ( buffer[bytes_read] == '\n' ) {
+				buffer[bytes_read] = '\0';
+				bytes_read++;
+				break;
+			}
+			bytes_read++;
+		}
+	}
+
+	/* Return the number of bytes read */
+	if ( result == -1 ) {
+		return result;
+	} else {
+		return bytes_read;
+	}
+} // readline
+/*============================================================================*/
+
+/*******************************************************************************
+ *	translate_option()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function takes a line read in from the config file and parses out
+ *   the key/value pairs. It then determines which key has been parsed and sets
+ *   the card's configuration based on the value given.
+ *
+ *  PARAMETERS:
+ *
+ *      buffer - a buffer containing a line to translate
+ *      config - a pointer to the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void translate_option( char *buffer, struct wl_private *lp )
+{
+	unsigned int value_convert = 0;
+	int string_length = 0;
+	char *key = NULL;
+	char *value = NULL;
+	u_char mac_value[ETH_ALEN];
+	/*------------------------------------------------------------------------*/
+
+	DBG_FUNC( "translate_option" );
+
+	if ( buffer == NULL || lp == NULL ) {
+		DBG_ERROR( DbgInfo, "Config file buffer and/or wavelan buffer ptr NULL\n" );
+		return;
+	}
+
+	ParseConfigLine( buffer, &key, &value );
+
+	if ( key == NULL || value == NULL ) {
+		return;
+	}
+
+	/* Determine which key it is and perform the appropriate action */
+
+	/* Configuration parameters used in all scenarios */
+#if DBG
+	/* handle DebugFlag as early as possible so it starts its influence as early
+	 * as possible
+	 */
+	if ( strcmp( key, PARM_NAME_DEBUG_FLAG ) == 0 ) {
+		if ( DebugFlag == ~0 ) {			//if DebugFlag is not specified on the command line
+			if ( DbgInfo->DebugFlag == 0 ) {	/* if pc_debug did not set DebugFlag (i.e.pc_debug is
+											 * not specified or specified outside the 4-8 range
+											 */
+				DbgInfo->DebugFlag |= DBG_DEFAULTS;
+			}
+		} else {
+			DbgInfo->DebugFlag = wl_atoi( value ); //;?DebugFlag;
+		}
+		DbgInfo->DebugFlag = wl_atoi( value ); //;?Delete ASAP
+	}
+#endif /* DBG */
+	if ( strcmp( key, PARM_NAME_AUTH_KEY_MGMT_SUITE ) == 0 ) {
+		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_AUTH_KEY_MGMT_SUITE, value );
+
+		value_convert = wl_atoi( value );
+		if (( value_convert >= PARM_MIN_AUTH_KEY_MGMT_SUITE ) || ( value_convert <= PARM_MAX_AUTH_KEY_MGMT_SUITE )) {
+			lp->AuthKeyMgmtSuite = value_convert;
+		} else {
+			DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_AUTH_KEY_MGMT_SUITE );
+		}
+	}
+	else if ( strcmp( key, PARM_NAME_BRSC_2GHZ ) == 0 ) {
+		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_2GHZ, value );
+
+		value_convert = wl_atoi( value );
+		if (( value_convert >= PARM_MIN_BRSC ) || ( value_convert <= PARM_MAX_BRSC )) {
+			lp->brsc[0] = value_convert;
+		} else {
+			DBG_WARNING( DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_BRSC_2GHZ );
+		}
+	}
+	else if ( strcmp( key, PARM_NAME_BRSC_5GHZ ) == 0 ) {
+		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_5GHZ, value );
+
+		value_convert = wl_atoi( value );
+		if (( value_convert >= PARM_MIN_BRSC ) || ( value_convert <= PARM_MAX_BRSC )) {
+			lp->brsc[1] = value_convert;
+		} else {
+			DBG_WARNING( DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_BRSC_5GHZ );
+		}
+	}
+	else if (( strcmp( key, PARM_NAME_DESIRED_SSID ) == 0 ) || ( strcmp( key, PARM_NAME_OWN_SSID ) == 0 )) {
+		DBG_TRACE( DbgInfo, "SSID, value: %s\n", value );
+
+		memset( lp->NetworkName, 0, ( PARM_MAX_NAME_LEN + 1 ));
+
+		/* Make sure the value isn't too long */
+		string_length = strlen( value );
+		if ( string_length > PARM_MAX_NAME_LEN ) {
+			DBG_WARNING( DbgInfo, "SSID too long; will be truncated\n" );
+			string_length = PARM_MAX_NAME_LEN;
+		}
+
+		memcpy( lp->NetworkName, value, string_length );
+	}
+#if 0
+	else if ( strcmp( key, PARM_NAME_DOWNLOAD_FIRMWARE ) == 0 ) {
+		DBG_TRACE( DbgInfo, "DOWNLOAD_FIRMWARE, value: %s\n", value );
+		memset( lp->fw_image_filename, 0, ( MAX_LINE_SIZE + 1 ));
+		/* Make sure the value isn't too long */
+		string_length = strlen( value );
+		if ( string_length > MAX_LINE_SIZE ) {
+			DBG_WARNING( DbgInfo, "F/W image file name too long; will be ignored\n" );
+		} else {
+			memcpy( lp->fw_image_filename, value, string_length );
+		}
+	}
+#endif
+	else if ( strcmp( key, PARM_NAME_ENABLE_ENCRYPTION ) == 0 ) {
+		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_ENABLE_ENCRYPTION, value );
+
+		value_convert = wl_atoi( value );
+		if (( value_convert >= PARM_MIN_ENABLE_ENCRYPTION ) && ( value_convert <= PARM_MAX_ENABLE_ENCRYPTION )) {
+			lp->EnableEncryption = value_convert;
+		} else {
+			DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_ENABLE_ENCRYPTION );
+		}
+	}
+	else if ( strcmp( key, PARM_NAME_ENCRYPTION ) == 0 ) {
+		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_ENCRYPTION, value );
+
+		memset( lp->szEncryption, 0, sizeof( lp->szEncryption ));
+
+		/* Make sure the value isn't too long */
+		string_length = strlen( value );
+		if ( string_length > sizeof( lp->szEncryption ) ) {
+			DBG_WARNING( DbgInfo, "%s too long; will be truncated\n", PARM_NAME_ENCRYPTION );
+			string_length = sizeof( lp->szEncryption );
+		}
+
+		memcpy( lp->szEncryption, value, string_length );
+	}
+	else if ( strcmp( key, PARM_NAME_KEY1 ) == 0 ) {
+		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_KEY1, value );
+
+		if ( is_valid_key_string( value )) {
+			memset( lp->DefaultKeys.key[0].key, 0, MAX_KEY_SIZE );
+
+			key_string2key( value, &lp->DefaultKeys.key[0] );
+		} else {
+			 DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY1 );
+		}
+	}
+	else if ( strcmp( key, PARM_NAME_KEY2 ) == 0 ) {
+		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_KEY2, value );
+
+		if ( is_valid_key_string( value )) {
+			memset( lp->DefaultKeys.key[1].key, 0, MAX_KEY_SIZE );
+
+			key_string2key( value, &lp->DefaultKeys.key[1] );
+		} else {
+			 DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY2 );
+		}
+	}
+	else if ( strcmp( key, PARM_NAME_KEY3 ) == 0 ) {
+		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_KEY3, value );
+
+		if ( is_valid_key_string( value )) {
+			memset( lp->DefaultKeys.key[2].key, 0, MAX_KEY_SIZE );
+
+			key_string2key( value, &lp->DefaultKeys.key[2] );
+		} else {
+			 DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY3 );
+		}
+	}
+	else if ( strcmp( key, PARM_NAME_KEY4 ) == 0 ) {
+		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_KEY4, value );
+
+		if ( is_valid_key_string( value )) {
+			memset( lp->DefaultKeys.key[3].key, 0, MAX_KEY_SIZE );
+
+			key_string2key( value, &lp->DefaultKeys.key[3] );
+		} else {
+			 DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY4 );
+		}
+	}
+	/* New Parameters for WARP */
+	else if ( strcmp( key, PARM_NAME_LOAD_BALANCING ) == 0 ) {
+		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_LOAD_BALANCING, value );
+		lp->loadBalancing = parse_yes_no(value);
+	}
+	else if ( strcmp( key, PARM_NAME_MEDIUM_DISTRIBUTION ) == 0 ) {
+		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_MEDIUM_DISTRIBUTION, value );
+		lp->mediumDistribution = parse_yes_no(value);
+	}
+	else if ( strcmp( key, PARM_NAME_MICROWAVE_ROBUSTNESS) == 0 ) {
+		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_MICROWAVE_ROBUSTNESS, value );
+		lp->MicrowaveRobustness = parse_yes_no(value);
+	}
+	else if ( strcmp( key, PARM_NAME_MULTICAST_RATE ) == 0 ) {
+		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_RATE, value );
+
+		value_convert = wl_atoi( value );
+
+		if (( value_convert >= PARM_MIN_MULTICAST_RATE ) && ( value_convert <= PARM_MAX_MULTICAST_RATE )) {
+			lp->MulticastRate[0] = value_convert;
+		} else {
+			DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MULTICAST_RATE );
+		}
+	}
+	else if ( strcmp( key, PARM_NAME_OWN_CHANNEL ) == 0 ) {
+		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_CHANNEL, value );
+
+		value_convert = wl_atoi( value );
+		if ( wl_is_a_valid_chan( value_convert )) {
+			if ( value_convert > 14 ) {
+				value_convert = value_convert | 0x100;
+			}
+			lp->Channel = value_convert;
+		} else {
+			DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_CHANNEL );
+		}
+	}
+	else if ( strcmp( key, PARM_NAME_OWN_NAME ) == 0 ) {
+		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_NAME, value );
+
+		memset( lp->StationName, 0, ( PARM_MAX_NAME_LEN + 1 ));
+
+		/* Make sure the value isn't too long */
+		string_length = strlen( value );
+		if ( string_length > PARM_MAX_NAME_LEN ) {
+			DBG_WARNING( DbgInfo, "%s too long; will be truncated\n", PARM_NAME_OWN_NAME );
+			string_length = PARM_MAX_NAME_LEN;
+		}
+
+		memcpy( lp->StationName, value, string_length );
+	}
+	else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD ) == 0 ) {
+		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD, value );
+
+		value_convert = wl_atoi( value );
+		if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
+			lp->RTSThreshold = value_convert;
+		} else {
+			DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD );
+		}
+	}
+	else if ( strcmp( key, PARM_NAME_SRSC_2GHZ ) == 0 ) {
+		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_2GHZ, value );
+
+		value_convert = wl_atoi( value );
+		if (( value_convert >= PARM_MIN_SRSC ) || ( value_convert <= PARM_MAX_SRSC )) {
+			lp->srsc[0] = value_convert;
+		} else {
+			DBG_WARNING( DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_SRSC_2GHZ );
+		}
+	}
+	else if ( strcmp( key, PARM_NAME_SRSC_5GHZ ) == 0 ) {
+		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_5GHZ, value );
+
+		value_convert = wl_atoi( value );
+		if (( value_convert >= PARM_MIN_SRSC ) || ( value_convert <= PARM_MAX_SRSC )) {
+			lp->srsc[1] = value_convert;
+		} else {
+			DBG_WARNING( DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_SRSC_5GHZ );
+		}
+	}
+	else if ( strcmp( key, PARM_NAME_SYSTEM_SCALE ) == 0 ) {
+		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_SYSTEM_SCALE, value );
+
+		value_convert = wl_atoi( value );
+		if (( value_convert >= PARM_MIN_SYSTEM_SCALE ) && ( value_convert <= PARM_MAX_SYSTEM_SCALE )) {
+			lp->DistanceBetweenAPs = value_convert;
+		} else {
+			DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_SYSTEM_SCALE );
+		}
+	}
+	else if ( strcmp( key, PARM_NAME_TX_KEY ) == 0 ) {
+		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_KEY, value );
+
+		value_convert = wl_atoi( value );
+		if (( value_convert >= PARM_MIN_TX_KEY ) && ( value_convert <= PARM_MAX_TX_KEY )) {
+			lp->TransmitKeyID = wl_atoi( value );
+		} else {
+			DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_KEY );
+		}
+	}
+	else if ( strcmp( key, PARM_NAME_TX_RATE ) == 0 ) {
+		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE, value );
+
+		value_convert = wl_atoi( value );
+		if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
+			lp->TxRateControl[0] = value_convert;
+		} else {
+			DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE );
+		}
+	}
+	else if ( strcmp( key, PARM_NAME_TX_POW_LEVEL ) == 0 ) {
+		DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_POW_LEVEL, value );
+
+		value_convert = wl_atoi( value );
+		if (( value_convert >= PARM_MIN_TX_POW_LEVEL ) || ( value_convert <= PARM_MAX_TX_POW_LEVEL )) {
+			lp->txPowLevel = value_convert;
+		} else {
+			DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_POW_LEVEL );
+		}
+	}
+
+	/* Need to add? : Country code, Short/Long retry */
+
+	/* Configuration parameters specific to STA mode */
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
+//;?seems reasonable that even an AP-only driver could afford this small additional footprint
+	if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA  ) {
+					//;?should we return an error status in AP mode
+		if ( strcmp( key, PARM_NAME_PORT_TYPE ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_PORT_TYPE, value );
+
+			value_convert = wl_atoi( value );
+			if (( value_convert == PARM_MIN_PORT_TYPE ) || ( value_convert == PARM_MAX_PORT_TYPE )) {
+				lp->PortType = value_convert;
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PORT_TYPE );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_PM_ENABLED ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_PM_ENABLED, value );
+			value_convert = wl_atoi( value );
+	/* ;? how about wl_main.c containing
+	 * VALID_PARAM( PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD ||
+	 *					 ( PARM_PM_ENABLED & 0x7FFF ) <= WVLAN_PM_STATE_STANDARD );
+	 */
+			if ( ( value_convert & 0x7FFF ) <= PARM_MAX_PM_ENABLED) {
+				lp->PMEnabled = value_convert;
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PM_ENABLED );
+				//;?this is a data entry error, hence not a DBG_WARNING
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_CREATE_IBSS ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_CREATE_IBSS, value );
+			lp->CreateIBSS = parse_yes_no(value);
+		}
+		else if ( strcmp( key, PARM_NAME_MULTICAST_RX ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_RX, value );
+			lp->MulticastReceive = parse_yes_no(value);
+		}
+		else if ( strcmp( key, PARM_NAME_MAX_SLEEP ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_MAX_SLEEP, value );
+
+			value_convert = wl_atoi( value );
+			if (( value_convert >= 0 ) && ( value_convert <= 65535 )) {
+				lp->MaxSleepDuration = value_convert;
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MAX_SLEEP );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_NETWORK_ADDR ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_NETWORK_ADDR, value );
+
+			if ( parse_mac_address( value, mac_value ) == ETH_ALEN ) {
+				memcpy( lp->MACAddress, mac_value, ETH_ALEN );
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_NETWORK_ADDR );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_AUTHENTICATION ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_AUTHENTICATION, value );
+
+			value_convert = wl_atoi( value );
+			if (( value_convert >= PARM_MIN_AUTHENTICATION ) && ( value_convert <= PARM_MAX_AUTHENTICATION )) {
+				lp->authentication = value_convert;
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_AUTHENTICATION );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_OWN_ATIM_WINDOW ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_ATIM_WINDOW, value );
+
+			value_convert = wl_atoi( value );
+			if (( value_convert >= PARM_MIN_OWN_ATIM_WINDOW ) && ( value_convert <= PARM_MAX_OWN_ATIM_WINDOW )) {
+				lp->atimWindow = value_convert;
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_ATIM_WINDOW );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_PM_HOLDOVER_DURATION ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_PM_HOLDOVER_DURATION, value );
+
+			value_convert = wl_atoi( value );
+			if (( value_convert >= PARM_MIN_PM_HOLDOVER_DURATION ) && ( value_convert <= PARM_MAX_PM_HOLDOVER_DURATION )) {
+				lp->holdoverDuration = value_convert;
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PM_HOLDOVER_DURATION );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_PROMISCUOUS_MODE ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_PROMISCUOUS_MODE, value );
+			lp->promiscuousMode = parse_yes_no(value);
+		}
+		else if ( strcmp( key, PARM_NAME_CONNECTION_CONTROL ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_CONNECTION_CONTROL, value );
+
+			value_convert = wl_atoi( value );
+			if (( value_convert >= PARM_MIN_CONNECTION_CONTROL ) && ( value_convert <= PARM_MAX_CONNECTION_CONTROL )) {
+				lp->connectionControl = value_convert;
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_CONNECTION_CONTROL );
+			}
+		}
+
+		/* Need to add? : Probe Data Rate */
+	}
+#endif  /* (HCF_TYPE) & HCF_TYPE_STA */
+
+	/* Configuration parameters specific to AP mode */
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
+		//;?should we restore this to allow smaller memory footprint
+	if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
+		if ( strcmp( key, PARM_NAME_OWN_DTIM_PERIOD ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_DTIM_PERIOD, value );
+
+			value_convert = wl_atoi( value );
+			if ( value_convert >= PARM_MIN_OWN_DTIM_PERIOD ) {
+				lp->DTIMPeriod = value_convert;
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_DTIM_PERIOD );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_REJECT_ANY ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_REJECT_ANY, value );
+			lp->RejectAny = parse_yes_no(value);
+		}
+		else if ( strcmp( key, PARM_NAME_EXCLUDE_UNENCRYPTED ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_EXCLUDE_UNENCRYPTED, value );
+			lp->ExcludeUnencrypted = parse_yes_no(value);
+		}
+		else if ( strcmp( key, PARM_NAME_MULTICAST_PM_BUFFERING ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_PM_BUFFERING, value );
+			lp->ExcludeUnencrypted = parse_yes_no(value);
+		}
+		else if ( strcmp( key, PARM_NAME_INTRA_BSS_RELAY ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_INTRA_BSS_RELAY, value );
+			lp->ExcludeUnencrypted = parse_yes_no(value);
+		}
+		else if ( strcmp( key, PARM_NAME_OWN_BEACON_INTERVAL ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_BEACON_INTERVAL, value );
+
+			value_convert = wl_atoi( value );
+			if ( value_convert >= PARM_MIN_OWN_BEACON_INTERVAL ) {
+				lp->ownBeaconInterval = value_convert;
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_BEACON_INTERVAL );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_COEXISTENCE ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_COEXISTENCE, value );
+
+			value_convert = wl_atoi( value );
+			if ( value_convert >= PARM_MIN_COEXISTENCE ) {
+				lp->coexistence = value_convert;
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_COEXISTENCE );
+			}
+		}
+
+#ifdef USE_WDS
+		else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD1 ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD1, value );
+
+			value_convert = wl_atoi( value );
+			if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
+				lp->wds_port[0].rtsThreshold = value_convert;
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD1 );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD2 ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD2, value );
+
+			value_convert = wl_atoi( value );
+			if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
+				lp->wds_port[1].rtsThreshold = value_convert;
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD2 );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD3 ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD3, value );
+
+			value_convert = wl_atoi( value );
+			if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
+				lp->wds_port[2].rtsThreshold = value_convert;
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD3 );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD4 ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD4, value );
+
+			value_convert = wl_atoi( value );
+			if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
+				lp->wds_port[3].rtsThreshold = value_convert;
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD4 );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD5 ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD5, value );
+
+			value_convert = wl_atoi( value );
+			if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
+				lp->wds_port[4].rtsThreshold = value_convert;
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD5 );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD6 ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD6, value );
+
+			value_convert = wl_atoi( value );
+			if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
+				lp->wds_port[5].rtsThreshold = value_convert;
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD6 );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_TX_RATE1 ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE1, value );
+
+			value_convert = wl_atoi( value );
+			if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
+				lp->wds_port[0].txRateCntl = value_convert;
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE1 );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_TX_RATE2 ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE2, value );
+
+			value_convert = wl_atoi( value );
+			if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
+				lp->wds_port[1].txRateCntl = value_convert;
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE2 );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_TX_RATE3 ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE3, value );
+
+			value_convert = wl_atoi( value );
+			if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
+				lp->wds_port[2].txRateCntl = value_convert;
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE3 );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_TX_RATE4 ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE4, value );
+
+			value_convert = wl_atoi( value );
+			if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
+				lp->wds_port[3].txRateCntl = value_convert;
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE4 );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_TX_RATE5 ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE5, value );
+
+			value_convert = wl_atoi( value );
+			if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
+				lp->wds_port[4].txRateCntl = value_convert;
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE5 );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_TX_RATE6 ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE6, value );
+
+			value_convert = wl_atoi( value );
+			if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
+				lp->wds_port[5].txRateCntl = value_convert;
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE6 );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_WDS_ADDRESS1 ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS1, value );
+
+			if ( parse_mac_address( value, mac_value ) == ETH_ALEN ) {
+				memcpy( lp->wds_port[0].wdsAddress, mac_value, ETH_ALEN );
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS1 );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_WDS_ADDRESS2 ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS2, value );
+
+			if ( parse_mac_address( value, mac_value ) == ETH_ALEN ) {
+				memcpy( lp->wds_port[1].wdsAddress, mac_value, ETH_ALEN );
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS2 );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_WDS_ADDRESS3 ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS3, value );
+
+			if ( parse_mac_address( value, mac_value ) == ETH_ALEN ) {
+				memcpy( lp->wds_port[2].wdsAddress, mac_value, ETH_ALEN );
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS3 );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_WDS_ADDRESS4 ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS4, value );
+
+			if ( parse_mac_address( value, mac_value ) == ETH_ALEN ) {
+				memcpy( lp->wds_port[3].wdsAddress, mac_value, ETH_ALEN );
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS4 );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_WDS_ADDRESS5 ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS5, value );
+
+			if ( parse_mac_address( value, mac_value ) == ETH_ALEN ) {
+				memcpy( lp->wds_port[4].wdsAddress, mac_value, ETH_ALEN );
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS5 );
+			}
+		}
+		else if ( strcmp( key, PARM_NAME_WDS_ADDRESS6 ) == 0 ) {
+			DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS6, value );
+
+			if ( parse_mac_address( value, mac_value ) == ETH_ALEN ) {
+				memcpy( lp->wds_port[5].wdsAddress, mac_value, ETH_ALEN );
+			} else {
+				DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS6 );
+			}
+		}
+#endif  /* USE_WDS */
+	}
+#endif  /* (HCF_TYPE) & HCF_TYPE_AP */
+
+	return;
+} // translate_option
+/*============================================================================*/
+
+/*******************************************************************************
+ *	parse_mac_address()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function will parse a mac address string and convert it to a byte
+ *   array.
+ *
+ *  PARAMETERS:
+ *
+ *      value       - the MAC address, represented as a string
+ *      byte_array  - the MAC address, represented as a byte array of length
+ *                    ETH_ALEN
+ *
+ *  RETURNS:
+ *
+ *      The number of bytes in the final MAC address, should equal to ETH_ALEN.
+ *
+ ******************************************************************************/
+int parse_mac_address( char *value, u_char *byte_array )
+{
+	int     value_offset = 0;
+	int     array_offset = 0;
+	int     field_offset = 0;
+	char    byte_field[3];
+	/*------------------------------------------------------------------------*/
+
+	memset( byte_field, '\0', 3 );
+
+	while( value[value_offset] != '\0' ) {
+		/* Skip over the colon chars seperating the bytes, if they exist */
+		if ( value[value_offset] == ':' ) {
+			value_offset++;
+			continue;
+		}
+
+		byte_field[field_offset] = value[value_offset];
+		field_offset++;
+		value_offset++;
+
+		/* Once the byte_field is filled, convert it and store it */
+		if ( field_offset == 2 ) {
+			byte_field[field_offset] = '\0';
+			byte_array[array_offset] = simple_strtoul( byte_field, NULL, 16 );
+			field_offset = 0;
+			array_offset++;
+		}
+	}
+
+	/* Use the array_offset as a check; 6 bytes should be written to the
+	   byte_array */
+	return array_offset;
+} // parse_mac_address
+/*============================================================================*/
+
+/*******************************************************************************
+ *	ParseConfigLine()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Parses a line from the configuration file into an L-val and an R-val,
+ *  representing a key/value pair.
+ *
+ *  PARAMETERS:
+ *
+ *      pszLine     - the line from the config file to parse
+ *      ppszLVal    - the resulting L-val (Key)
+ *      ppszRVal    - the resulting R-val (Value)
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void ParseConfigLine( char *pszLine, char **ppszLVal, char **ppszRVal )
+{
+	int i;
+	int size;
+	/*------------------------------------------------------------------------*/
+
+	DBG_FUNC( "ParseConfigLine" );
+	DBG_ENTER( DbgInfo );
+
+	/* get a snapshot of our string size */
+	size      = strlen( pszLine );
+	*ppszLVal = NULL;
+	*ppszRVal = NULL;
+
+	if ( pszLine[0] != '#' &&							/* skip the line if it is a comment */
+		 pszLine[0] != '\n'&&							/* if it's an empty UNIX line, do nothing */
+		 !( pszLine[0] == '\r' && pszLine[1] == '\n' )	/* if it's an empty MS-DOS line, do nothing */
+	    ) {
+		/* advance past any whitespace, and assign the L-value */
+		for( i = 0; i < size; i++ ) {
+			if ( pszLine[i] != ' ' ) {
+				*ppszLVal = &pszLine[i];
+				break;
+			}
+		}
+		/* advance to the end of the l-value*/
+		for( i++; i < size; i++ ) {
+			if ( pszLine[i] == ' ' || pszLine[i] == '=' ) {
+				pszLine[i] = '\0';
+				break;
+			}
+		}
+		/* make any whitespace and the equal sign a NULL character, and
+		   advance to the R-Value */
+		for( i++; i < size; i++ ) {
+			if ( pszLine[i] == ' ' || pszLine[i] == '=' ) {
+				pszLine[i] = '\0';
+				continue;
+			}
+			*ppszRVal = &pszLine[i];
+			break;
+		}
+		/* make the line ending character(s) a NULL */
+		for( i++; i < size; i++ ) {
+			if ( pszLine[i] == '\n' ) {
+				pszLine[i] = '\0';
+			}
+			if (( pszLine[i] == '\r' ) && ( pszLine[i+1] == '\n' )) {
+				pszLine[i] = '\0';
+			}
+		}
+	}
+	DBG_LEAVE( DbgInfo );
+} // ParseConfigLine
+/*============================================================================*/
+
+#endif  // USE_PROFILE
diff --git a/drivers/staging/wlags49_h2/wl_profile.h b/drivers/staging/wlags49_h2/wl_profile.h
new file mode 100644
index 0000000..81db8e8
--- /dev/null
+++ b/drivers/staging/wlags49_h2/wl_profile.h
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Agere Systems Inc.
+ * Wireless device driver for Linux (wlags49).
+ *
+ * Copyright (c) 1998-2003 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * Initially developed by TriplePoint, Inc.
+ *   http://www.triplepoint.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ *   Header describing information required for the config parsing routines.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2003 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following Disclaimer as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ ******************************************************************************/
+
+#ifndef __WL_PROFILE_H__
+#define __WL_PROFILE_H__
+
+
+
+
+/*******************************************************************************
+ *  constant definitions
+ ******************************************************************************/
+#define ROOT_CONFIG_FILENAME "/etc/agere/iwconfig-"
+
+
+/*******************************************************************************
+ *  function prototypes
+ ******************************************************************************/
+void parse_config( struct net_device *dev );
+
+int readline( int filedesc, char *buffer );
+
+void translate_option( char *buffer, struct wl_private *lp );
+
+int parse_mac_address( char *value, u_char *byte_array );
+
+void ParseConfigLine( char *pszLine, char **ppszLVal, char **ppszRVal );
+
+
+#endif  // __WL_PROFILE_H__
diff --git a/drivers/staging/wlags49_h2/wl_sysfs.c b/drivers/staging/wlags49_h2/wl_sysfs.c
new file mode 100644
index 0000000..864e01a
--- /dev/null
+++ b/drivers/staging/wlags49_h2/wl_sysfs.c
@@ -0,0 +1,135 @@
+/*
+ * ex: sw=4
+ */
+
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <net/sock.h>
+#include <linux/rtnetlink.h>
+#include <linux/wireless.h>
+#include <net/iw_handler.h>
+#include <linux/sysfs.h>
+
+#include <debug.h>
+#include <hcf.h>
+#include <hcfdef.h>
+
+#include <wl_if.h>
+#include <wl_internal.h>
+#include <wl_util.h>
+#include <wl_main.h>
+#include <wl_wext.h>
+#include <wl_priv.h>
+
+static inline int dev_isalive(const struct net_device *dev)
+{
+            return dev->reg_state == NETREG_REGISTERED;
+}
+
+/*
+ * empirically even if tallies are defined as 32 bits entities, only
+ * high 16 bits are relevant; low half is always zero. It means tallies
+ * are pretty much useless for traffic counting but at least give overview
+ * about where error come from
+ */
+static ssize_t show_tallies(struct device *d, struct device_attribute *attr,
+			    char *buf)
+{
+    struct net_device *dev = to_net_dev(d);
+    struct wl_private *lp = wl_priv(dev);
+    unsigned long flags;
+    CFG_HERMES_TALLIES_STRCT tallies;
+    ssize_t ret = -EINVAL;
+
+    read_lock(&dev_base_lock);
+    if (dev_isalive(dev)) {
+	wl_lock(lp, &flags);
+
+	if ((ret = wl_get_tallies(lp, &tallies)) == 0) {
+		wl_unlock(lp, &flags);
+		ret = snprintf(buf, PAGE_SIZE,
+		    "TxUnicastFrames:           %u\n"
+		    "TxMulticastFrames:         %u\n"
+		    "TxFragments:               %u\n"
+		    "TxUnicastOctets:           %u\n"
+		    "TxMulticastOctets:         %u\n"
+		    "TxDeferredTransmissions:   %u\n"
+		    "TxSingleRetryFrames:       %u\n"
+		    "TxMultipleRetryFrames:     %u\n"
+		    "TxRetryLimitExceeded:      %u\n"
+		    "TxDiscards:                %u\n"
+		    "RxUnicastFrames:           %u\n"
+		    "RxMulticastFrames:         %u\n"
+		    "RxFragments:               %u\n"
+		    "RxUnicastOctets:           %u\n"
+		    "RxMulticastOctets:         %u\n"
+		    "RxFCSErrors:               %u\n"
+		    "RxDiscardsNoBuffer:        %u\n"
+		    "TxDiscardsWrongSA:         %u\n"
+		    "RxWEPUndecryptable:        %u\n"
+		    "RxMsgInMsgFragments:       %u\n"
+		    "RxMsgInBadMsgFragments:    %u\n"
+		    "RxDiscardsWEPICVError:     %u\n"
+		    "RxDiscardsWEPExcluded:     %u\n"
+		    ,
+		    (unsigned int)tallies.TxUnicastFrames,
+		    (unsigned int)tallies.TxMulticastFrames,
+		    (unsigned int)tallies.TxFragments,
+		    (unsigned int)tallies.TxUnicastOctets,
+		    (unsigned int)tallies.TxMulticastOctets,
+		    (unsigned int)tallies.TxDeferredTransmissions,
+		    (unsigned int)tallies.TxSingleRetryFrames,
+		    (unsigned int)tallies.TxMultipleRetryFrames,
+		    (unsigned int)tallies.TxRetryLimitExceeded,
+		    (unsigned int)tallies.TxDiscards,
+		    (unsigned int)tallies.RxUnicastFrames,
+		    (unsigned int)tallies.RxMulticastFrames,
+		    (unsigned int)tallies.RxFragments,
+		    (unsigned int)tallies.RxUnicastOctets,
+		    (unsigned int)tallies.RxMulticastOctets,
+		    (unsigned int)tallies.RxFCSErrors,
+		    (unsigned int)tallies.RxDiscardsNoBuffer,
+		    (unsigned int)tallies.TxDiscardsWrongSA,
+		    (unsigned int)tallies.RxWEPUndecryptable,
+		    (unsigned int)tallies.RxMsgInMsgFragments,
+		    (unsigned int)tallies.RxMsgInBadMsgFragments,
+		    (unsigned int)tallies.RxDiscardsWEPICVError,
+		    (unsigned int)tallies.RxDiscardsWEPExcluded);
+	    } else {
+		wl_unlock( lp, &flags );
+	    }
+    }
+
+    read_unlock(&dev_base_lock);
+    return ret;
+}
+
+static DEVICE_ATTR(tallies, S_IRUGO, show_tallies, NULL);
+
+static struct attribute *wlags_attrs[] = {
+    &dev_attr_tallies.attr,
+    NULL
+};
+
+static struct attribute_group wlags_group = {
+    .name = "wlags",
+    .attrs = wlags_attrs,
+};
+
+void register_wlags_sysfs(struct net_device *net)
+{
+    struct device *dev = &(net->dev);
+    struct wl_private *lp = wl_priv(net);
+
+    lp->sysfsCreated = sysfs_create_group(&dev->kobj, &wlags_group);
+}
+
+void unregister_wlags_sysfs(struct net_device *net)
+{
+    struct device *dev = &(net->dev);
+    struct wl_private *lp = wl_priv(net);
+
+    if (lp->sysfsCreated)
+	sysfs_remove_group(&dev->kobj, &wlags_group);
+}
diff --git a/drivers/staging/wlags49_h2/wl_sysfs.h b/drivers/staging/wlags49_h2/wl_sysfs.h
new file mode 100644
index 0000000..6d96d03
--- /dev/null
+++ b/drivers/staging/wlags49_h2/wl_sysfs.h
@@ -0,0 +1,7 @@
+#ifdef CONFIG_SYSFS
+extern void register_wlags_sysfs(struct net_device *);
+extern void unregister_wlags_sysfs(struct net_device *);
+#else
+static void register_wlags_sysfs(struct net_device *) { return; };
+static void unregister_wlags_sysfs(struct net_device *) { return; };
+#endif
diff --git a/drivers/staging/wlags49_h2/wl_util.c b/drivers/staging/wlags49_h2/wl_util.c
new file mode 100644
index 0000000..ac1e7f3
--- /dev/null
+++ b/drivers/staging/wlags49_h2/wl_util.c
@@ -0,0 +1,1587 @@
+/*******************************************************************************
+ * Agere Systems Inc.
+ * Wireless device driver for Linux (wlags49).
+ *
+ * Copyright (c) 1998-2003 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * Initially developed by TriplePoint, Inc.
+ *   http://www.triplepoint.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ *   This file defines misc utility functions.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2003 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following Disclaimer as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ ******************************************************************************/
+
+/*******************************************************************************
+ *  include files
+ ******************************************************************************/
+#include <wl_version.h>
+
+#include <linux/kernel.h>
+// #include <linux/sched.h>
+// #include <linux/ptrace.h>
+#include <linux/ctype.h>
+// #include <linux/string.h>
+// #include <linux/timer.h>
+// #include <linux/interrupt.h>
+// #include <linux/in.h>
+// #include <linux/delay.h>
+// #include <asm/io.h>
+// #include <asm/system.h>
+// #include <asm/bitops.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+// #include <linux/skbuff.h>
+// #include <linux/if_arp.h>
+// #include <linux/ioport.h>
+
+#include <debug.h>
+#include <hcf.h>
+// #include <hcfdef.h>
+
+#include <wl_if.h>
+#include <wl_internal.h>
+#include <wl_util.h>
+#include <wl_wext.h>
+#include <wl_main.h>
+
+
+
+/*******************************************************************************
+ * global variables
+ ******************************************************************************/
+
+/* A matrix which maps channels to frequencies */
+#define MAX_CHAN_FREQ_MAP_ENTRIES   50
+static const long chan_freq_list[][MAX_CHAN_FREQ_MAP_ENTRIES] =
+{
+    {1,2412},
+    {2,2417},
+    {3,2422},
+    {4,2427},
+    {5,2432},
+    {6,2437},
+    {7,2442},
+    {8,2447},
+    {9,2452},
+    {10,2457},
+    {11,2462},
+    {12,2467},
+    {13,2472},
+    {14,2484},
+    {36,5180},
+    {40,5200},
+    {44,5220},
+    {48,5240},
+    {52,5260},
+    {56,5280},
+    {60,5300},
+    {64,5320},
+    {149,5745},
+    {153,5765},
+    {157,5785},
+    {161,5805}
+};
+
+#if DBG
+extern dbg_info_t *DbgInfo;
+#endif  /* DBG */
+
+
+
+
+/*******************************************************************************
+ *	dbm()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Return an energy value in dBm.
+ *
+ *  PARAMETERS:
+ *
+ *      value - the energy value to be converted
+ *
+ *  RETURNS:
+ *
+ *      the value in dBm
+ *
+ ******************************************************************************/
+int dbm( int value )
+{
+    /* Truncate the value to be between min and max. */
+    if( value < HCF_MIN_SIGNAL_LEVEL )
+        value = HCF_MIN_SIGNAL_LEVEL;
+
+    if( value > HCF_MAX_SIGNAL_LEVEL )
+        value = HCF_MAX_SIGNAL_LEVEL;
+
+    /* Return the energy value in dBm. */
+    return ( value - HCF_0DBM_OFFSET );
+} // dbm
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	percent()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Return a value as a percentage of min to max.
+ *
+ *  PARAMETERS:
+ *
+ *      value   - the value in question
+ *      min     - the minimum range value
+ *      max     - the maximum range value
+ *
+ *  RETURNS:
+ *
+ *      the percentage value
+ *
+ ******************************************************************************/
+int percent( int value, int min, int max )
+{
+    /* Truncate the value to be between min and max. */
+    if( value < min )
+        value = min;
+
+    if( value > max )
+        value = max;
+
+    /* Return the value as a percentage of min to max. */
+    return ((( value - min ) * 100 ) / ( max - min ));
+} // percent
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	is_valid_key_string()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Checks to determine if the WEP key string is valid
+ *
+ *  PARAMETERS:
+ *
+ *      s - the string in question
+ *
+ *  RETURNS:
+ *
+ *      non-zero if the string contains a valid key
+ *
+ ******************************************************************************/
+int is_valid_key_string( char *s )
+{
+    int l;
+    int i;
+    /*------------------------------------------------------------------------*/
+
+
+    l = strlen( s );
+
+    /* 0x followed by 5 or 13 hexadecimal digit pairs is valid */
+    if( s[0] == '0' && ( s[1] == 'x' || s[1] == 'X' )) {
+        if( l == 12 || l == 28 ) {
+            for( i = 2; i < l; i++ ) {
+                if( !isxdigit( s[i] ))
+                    return 0;
+            }
+
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+
+    /* string with 0, 5, or 13 characters is valid */
+    else
+    {
+        return( l == 0 || l == 5 || l == 13 );
+    }
+} // is_valid_key_string
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	hexdigit2int()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Converts a hexadecimal digit character to an integer
+ *
+ *  PARAMETERS:
+ *
+ *      c   - the hexadecimal digit character
+ *
+ *  RETURNS:
+ *
+ *      the converted integer
+ *
+ ******************************************************************************/
+int hexdigit2int( char c )
+{
+   if( c >= '0' && c <= '9' )
+       return c - '0';
+
+   if( c >= 'A' && c <= 'F' )
+       return c - 'A' + 10;
+
+   if( c >= 'a' && c <= 'f' )
+       return c - 'a' + 10;
+
+   return 0;
+} // hexdigit2int
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	key_string2key()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Converts a key_string to a key, Assumes the key_string is validated with
+ *  is_valid_key_string().
+ *
+ *  PARAMETERS:
+ *
+ *      ks  - the valid key string
+ *      key - a pointer to a KEY_STRUCT where the converted key information will
+ *            be stored.
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void key_string2key( char *ks, KEY_STRCT *key )
+{
+    int l,i,n;
+    char *p;
+    /*------------------------------------------------------------------------*/
+
+
+    l = strlen( ks );
+
+    /* 0x followed by hexadecimal digit pairs */
+    if( ks[0] == '0' && ( ks[1] == 'x' || ks[1] == 'X' )) {
+        n = 0;
+        p = (char *)key->key;
+
+        for( i = 2; i < l; i+=2 ) {
+           *p++ = ( hexdigit2int( ks[i] ) << 4 ) + hexdigit2int (ks[i+1] );
+           n++;
+        }
+
+        /* Note that endian translation of the length field is not needed here
+          because it's performed in wl_put_ltv() */
+        key->len = n;
+    }
+    /* character string */
+    else
+    {
+        strcpy( (char *)key->key, ks );
+        key->len = l;
+    }
+
+    return;
+} // key_string2key
+/*============================================================================*/
+
+
+
+
+#if DBG
+/*******************************************************************************
+ *	DbgHwAddr()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Convert a hardware ethernet address to a character string
+ *
+ *  PARAMETERS:
+ *
+ *      hwAddr  - an ethernet address
+ *
+ *  RETURNS:
+ *
+ *      a pointer to a string representing the ethernet address
+ *
+ ******************************************************************************/
+const char *DbgHwAddr(unsigned char *hwAddr)
+{
+    static char     buffer[18];
+    /*------------------------------------------------------------------------*/
+
+
+    sprintf( buffer, "%02X:%02X:%02X:%02X:%02X:%02X",
+             hwAddr[0], hwAddr[1], hwAddr[2], hwAddr[3], hwAddr[4], hwAddr[5] );
+
+    return buffer;
+} // DbgHwAddr
+/*============================================================================*/
+
+#endif /* DBG */
+
+
+
+
+/*******************************************************************************
+ *	wl_has_wep()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Checks to see if the device supports WEP
+ *
+ *  PARAMETERS:
+ *
+ *      ifbp    - the IFB pointer of the device in question
+ *
+ *  RETURNS:
+ *
+ *      1 if WEP is known enabled, else 0
+ *
+ ******************************************************************************/
+int wl_has_wep (IFBP ifbp)
+{
+    CFG_PRIVACY_OPT_IMPLEMENTED_STRCT ltv;
+	int rc, privacy;
+    /*------------------------------------------------------------------------*/
+
+
+	/* This function allows us to distiguish bronze cards from other types, to
+       know if WEP exists. Does not distinguish (because there's no way to)
+       between silver and gold cards. */
+    ltv.len = 2;
+    ltv.typ = CFG_PRIVACY_OPT_IMPLEMENTED;
+
+	rc = hcf_get_info( ifbp, (LTVP) &ltv );
+
+	privacy = CNV_LITTLE_TO_INT( ltv.privacy_opt_implemented );
+
+	//return rc ? 0 : privacy;
+    return 1;
+} // wl_has_wep
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wl_hcf_error()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Report the type of HCF error message
+ *
+ *  PARAMETERS:
+ *
+ *      none
+ *
+ *  RETURNS:
+ *
+ *      A descriptive string indicating the error, quiet otherwise.
+ *
+ ******************************************************************************/
+void wl_hcf_error( struct net_device *dev, int hcfStatus )
+{
+    char     buffer[64], *pMsg;
+    /*------------------------------------------------------------------------*/
+
+
+    if( hcfStatus != HCF_SUCCESS ) {
+        switch( hcfStatus ) {
+
+        case HCF_ERR_TIME_OUT:
+
+            pMsg = "Expected adapter event did not occur in expected time";
+            break;
+
+
+        case HCF_ERR_NO_NIC:
+
+            pMsg = "Card not found (ejected unexpectedly)";
+            break;
+
+
+        case HCF_ERR_LEN:
+
+            pMsg = "Command buffer size insufficient";
+            break;
+
+
+        case HCF_ERR_INCOMP_PRI:
+
+            pMsg = "Primary functions are not compatible";
+            break;
+
+
+        case HCF_ERR_INCOMP_FW:
+
+            pMsg = "Primary functions are compatible, "
+                "station/ap functions are not";
+            break;
+
+
+        case HCF_ERR_BUSY:
+
+            pMsg = "Inquire cmd while another Inquire in progress";
+            break;
+
+
+        //case HCF_ERR_SEQ_BUG:
+
+        //    pMsg = "Unexpected command completed";
+        //    break;
+
+
+        case HCF_ERR_DEFUNCT_AUX:
+
+            pMsg = "Timeout on ack for enable/disable of AUX registers";
+            break;
+
+
+        case HCF_ERR_DEFUNCT_TIMER:
+            pMsg = "Timeout on timer calibration during initialization process";
+            break;
+
+
+        case HCF_ERR_DEFUNCT_TIME_OUT:
+            pMsg = "Timeout on Busy bit drop during BAP setup";
+            break;
+
+
+        case HCF_ERR_DEFUNCT_CMD_SEQ:
+            pMsg = "Hermes and HCF are out of sync";
+            break;
+
+
+        default:
+
+            sprintf( buffer, "Error code %d", hcfStatus );
+            pMsg = buffer;
+            break;
+        }
+
+        printk( KERN_INFO "%s: Wireless, HCF failure: \"%s\"\n",
+                dev->name, pMsg );
+    }
+} // wl_hcf_error
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wl_endian_translate_event()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Determines what type of data is in the mailbox and performs the proper
+ *  endian translation.
+ *
+ *  PARAMETERS:
+ *
+ *      pLtv - an LTV pointer
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_endian_translate_event( ltv_t *pLtv )
+{
+    DBG_FUNC( "wl_endian_translate_event" );
+    DBG_ENTER( DbgInfo );
+
+
+    switch( pLtv->typ ) {
+    case CFG_TALLIES:
+        break;
+
+
+    case CFG_SCAN:
+        {
+            int numAPs;
+            SCAN_RS_STRCT *pAps = (SCAN_RS_STRCT*)&pLtv->u.u8[0];
+
+            numAPs = (hcf_16)(( (size_t)( pLtv->len - 1 ) * 2 ) /
+                                (sizeof( SCAN_RS_STRCT )));
+
+            while( numAPs >= 1 ) {
+                numAPs--;
+
+                pAps[numAPs].channel_id           =
+                    CNV_LITTLE_TO_INT( pAps[numAPs].channel_id );
+
+                pAps[numAPs].noise_level          =
+                    CNV_LITTLE_TO_INT( pAps[numAPs].noise_level );
+
+                pAps[numAPs].signal_level         =
+                    CNV_LITTLE_TO_INT( pAps[numAPs].signal_level );
+
+                pAps[numAPs].beacon_interval_time =
+                    CNV_LITTLE_TO_INT( pAps[numAPs].beacon_interval_time );
+
+                pAps[numAPs].capability           =
+                    CNV_LITTLE_TO_INT( pAps[numAPs].capability );
+
+                pAps[numAPs].ssid_len             =
+                    CNV_LITTLE_TO_INT( pAps[numAPs].ssid_len );
+
+                pAps[numAPs].ssid_val[pAps[numAPs].ssid_len] = 0;
+
+            }
+        }
+        break;
+
+
+    case CFG_ACS_SCAN:
+        {
+            PROBE_RESP *probe_resp = (PROBE_RESP *)pLtv;
+
+            probe_resp->frameControl   = CNV_LITTLE_TO_INT( probe_resp->frameControl );
+            probe_resp->durID          = CNV_LITTLE_TO_INT( probe_resp->durID );
+            probe_resp->sequence       = CNV_LITTLE_TO_INT( probe_resp->sequence );
+            probe_resp->dataLength     = CNV_LITTLE_TO_INT( probe_resp->dataLength );
+
+#ifndef WARP
+            probe_resp->lenType        = CNV_LITTLE_TO_INT( probe_resp->lenType );
+#endif // WARP
+
+            probe_resp->beaconInterval = CNV_LITTLE_TO_INT( probe_resp->beaconInterval );
+            probe_resp->capability     = CNV_LITTLE_TO_INT( probe_resp->capability );
+            probe_resp->flags          = CNV_LITTLE_TO_INT( probe_resp->flags );
+        }
+        break;
+
+
+    case CFG_LINK_STAT:
+#define ls ((LINK_STATUS_STRCT *)pLtv)
+            ls->linkStatus = CNV_LITTLE_TO_INT( ls->linkStatus );
+        break;
+#undef ls
+
+    case CFG_ASSOC_STAT:
+        {
+            ASSOC_STATUS_STRCT *pAs = (ASSOC_STATUS_STRCT *)pLtv;
+
+            pAs->assocStatus = CNV_LITTLE_TO_INT( pAs->assocStatus );
+        }
+        break;
+
+
+    case CFG_SECURITY_STAT:
+        {
+            SECURITY_STATUS_STRCT *pSs = (SECURITY_STATUS_STRCT *)pLtv;
+
+            pSs->securityStatus = CNV_LITTLE_TO_INT( pSs->securityStatus );
+            pSs->reason         = CNV_LITTLE_TO_INT( pSs->reason );
+        }
+        break;
+
+
+    case CFG_WMP:
+        break;
+
+
+    case CFG_NULL:
+        break;
+
+
+    default:
+        break;
+    }
+
+    DBG_LEAVE( DbgInfo );
+    return;
+} // wl_endian_translate_event
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	msf_assert()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Print statement used to display asserts from within the HCF. Only called
+ *  when asserts in the HCF are turned on. See hcfcfg.h for more information.
+ *
+ *  PARAMETERS:
+ *
+ *      file_namep  - the filename in which the assert occurred.
+ *      line_number - the line number on which the assert occurred.
+ *      trace       - a comment associated with the assert.
+ *      qual        - return code or other value related to the assert
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void msf_assert( unsigned int line_number, hcf_16 trace, hcf_32 qual )
+{
+    DBG_PRINT( "HCF ASSERT: Line %d, VAL: 0x%.8x\n", line_number, /*;?*/(u32)qual );
+} // msf_assert
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wl_parse_ds_ie()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function parses the Direct Sequence Parameter Set IE, used to
+ *      determine channel/frequency information.
+ *
+ *  PARAMETERS:
+ *
+ *      probe_rsp - a pointer to a PROBE_RESP structure containing the probe
+ *                  response.
+ *
+ *  RETURNS:
+ *
+ *      The channel on which the BSS represented by this probe response is
+ *      transmitting.
+ *
+ ******************************************************************************/
+hcf_8 wl_parse_ds_ie( PROBE_RESP *probe_rsp )
+{
+    int     i;
+    int     ie_length = 0;
+    hcf_8   *buf;
+    hcf_8   buf_size;
+    /*------------------------------------------------------------------------*/
+
+
+    if( probe_rsp == NULL ) {
+        return 0;
+    }
+
+    buf      = probe_rsp->rawData;
+    buf_size = sizeof( probe_rsp->rawData );
+
+
+    for( i = 0; i < buf_size; i++ ) {
+        if( buf[i] == DS_INFO_ELEM ) {
+            /* Increment by 1 to get the length, and test it; in a DS element,
+               length should always be 1 */
+            i++;
+            ie_length = buf[i];
+
+            if( buf[i] == 1 ) {
+                /* Get the channel information */
+                i++;
+                return buf[i];
+            }
+        }
+    }
+
+    /* If we get here, we didn't find a DS-IE, which is strange */
+    return 0;
+} // wl_parse_ds_ie
+
+
+/*******************************************************************************
+ *	wl_parse_wpa_ie()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function parses the Probe Response for a valid WPA-IE.
+ *
+ *  PARAMETERS:
+ *
+ *      probe_rsp - a pointer to a PROBE_RESP structure containing the probe
+ *                  response
+ *      length    - a pointer to an hcf_16 in which the size of the WPA-IE will
+ *                  be stored (if found).
+ *
+ *  RETURNS:
+ *
+ *      A pointer to the location in the probe response buffer where a valid
+ *      WPA-IE lives. The length of this IE is written back to the 'length'
+ *      argument passed to the function.
+ *
+ ******************************************************************************/
+hcf_8 * wl_parse_wpa_ie( PROBE_RESP *probe_rsp, hcf_16 *length )
+{
+    int     i;
+    int     ie_length = 0;
+    hcf_8   *buf;
+    hcf_8   buf_size;
+    hcf_8   wpa_oui[] = WPA_OUI_TYPE;
+    /*------------------------------------------------------------------------*/
+
+
+    if( probe_rsp == NULL || length == NULL ) {
+        return NULL;
+    }
+
+    buf      = probe_rsp->rawData;
+    buf_size = sizeof( probe_rsp->rawData );
+    *length  = 0;
+
+
+    for( i = 0; i < buf_size; i++ ) {
+        if( buf[i] == GENERIC_INFO_ELEM ) {
+            /* Increment by one to get the IE length */
+            i++;
+            ie_length = probe_rsp->rawData[i];
+
+            /* Increment by one to point to the IE payload */
+            i++;
+
+            /* Does the IE contain a WPA OUI? If not, it's a proprietary IE */
+            if( memcmp( &buf[i], &wpa_oui, WPA_SELECTOR_LEN ) == 0 ) {
+                /* Pass back length and return a pointer to the WPA-IE */
+                /* NOTE: Length contained in the WPA-IE is only the length of
+                   the payload. The entire WPA-IE, including the IE identifier
+                   and the length, is 2 bytes larger */
+                *length = ie_length + 2;
+
+                /* Back up the pointer 2 bytes to include the IE identifier and
+                   the length in the buffer returned */
+                i -= 2;
+                return &buf[i];
+            }
+
+            /* Increment past this non-WPA IE and continue looking */
+            i += ( ie_length - 1 );
+        }
+    }
+
+    /* If we're here, we didn't find a WPA-IE in the buffer */
+    return NULL;
+} // wl_parse_wpa_ie
+
+
+/*******************************************************************************
+ *	wl_print_wpa_ie()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Function used to take a WPA Information Element (WPA-IE) buffer and
+ *      display it in a readable format.
+ *
+ *  PARAMETERS:
+ *
+ *      buffer - the byte buffer containing the WPA-IE
+ *      length - the length of the above buffer
+ *
+ *  RETURNS:
+ *
+ *      A pointer to the formatted WPA-IE string. Note that the format used is
+ *      byte-by-byte printing as %02x hex values with no spaces. This is
+ *      required for proper operation with some WPA supplicants.
+ *
+ ******************************************************************************/
+hcf_8 * wl_print_wpa_ie( hcf_8 *buffer, int length )
+{
+    int count;
+    int rows;
+    int remainder;
+    int rowsize = 4;
+    hcf_8 row_buf[64];
+    static hcf_8 output[512];
+    /*------------------------------------------------------------------------*/
+
+
+    memset( output, 0, sizeof( output ));
+    memset( row_buf, 0, sizeof( row_buf ));
+
+
+    /* Determine how many rows will be needed, and the remainder */
+    rows = length / rowsize;
+    remainder = length % rowsize;
+
+
+    /* Format the rows */
+    for( count = 0; count < rows; count++ ) {
+        sprintf( row_buf, "%02x%02x%02x%02x",
+                 buffer[count*rowsize], buffer[count*rowsize+1],
+                 buffer[count*rowsize+2], buffer[count*rowsize+3]);
+        strcat( output, row_buf );
+    }
+
+    memset( row_buf, 0, sizeof( row_buf ));
+
+
+    /* Format the remainder */
+    for( count = 0; count < remainder; count++ ) {
+        sprintf( row_buf, "%02x", buffer[(rows*rowsize)+count]);
+        strcat( output, row_buf );
+    }
+
+    return output;
+} // wl_print_wpa_ie
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wl_is_a_valid_chan()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Checks if a given channel is valid
+ *
+ *  PARAMETERS:
+ *
+ *      channel - the channel
+ *
+ *  RETURNS:
+ *
+ *      1 if TRUE
+ *      0 if FALSE
+ *
+ ******************************************************************************/
+int wl_is_a_valid_chan( int channel )
+{
+    int i;
+    /*------------------------------------------------------------------------*/
+
+
+    /* Strip out the high bit set by the FW for 802.11a channels */
+    if( channel & 0x100 ) {
+        channel = channel & 0x0FF;
+    }
+
+    /* Iterate through the matrix and retrieve the frequency */
+    for( i = 0; i < MAX_CHAN_FREQ_MAP_ENTRIES; i++ ) {
+        if( chan_freq_list[i][0] == channel ) {
+            return 1;
+        }
+    }
+
+    return 0;
+} // wl_is_a_valid_chan
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wl_get_chan_from_freq()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Checks if a given frequency is valid
+ *
+ *  PARAMETERS:
+ *
+ *      freq - the frequency
+ *
+ *  RETURNS:
+ *
+ *      1 if TRUE
+ *      0 if FALSE
+ *
+ ******************************************************************************/
+int wl_is_a_valid_freq( long frequency )
+{
+    int i;
+    /*------------------------------------------------------------------------*/
+
+
+    /* Iterate through the matrix and retrieve the channel */
+    for( i = 0; i < MAX_CHAN_FREQ_MAP_ENTRIES; i++ ) {
+        if( chan_freq_list[i][1] == frequency ) {
+            return 1;
+        }
+    }
+
+    return 0;
+} // wl_is_a_valid_freq
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wl_get_freq_from_chan()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Function used to look up the frequency for a given channel on which the
+ *      adapter is Tx/Rx.
+ *
+ *  PARAMETERS:
+ *
+ *      channel - the channel
+ *
+ *  RETURNS:
+ *
+ *      The corresponding frequency
+ *
+ ******************************************************************************/
+long wl_get_freq_from_chan( int channel )
+{
+    int i;
+    /*------------------------------------------------------------------------*/
+
+
+    /* Strip out the high bit set by the FW for 802.11a channels */
+    if( channel & 0x100 ) {
+        channel = channel & 0x0FF;
+    }
+
+    /* Iterate through the matrix and retrieve the frequency */
+    for( i = 0; i < MAX_CHAN_FREQ_MAP_ENTRIES; i++ ) {
+        if( chan_freq_list[i][0] == channel ) {
+            return chan_freq_list[i][1];
+        }
+    }
+
+    return 0;
+} // wl_get_freq_from_chan
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wl_get_chan_from_freq()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Function used to look up the channel for a given frequency on which the
+ *      adapter is Tx/Rx.
+ *
+ *  PARAMETERS:
+ *
+ *      frequency - the frequency
+ *
+ *  RETURNS:
+ *
+ *      The corresponding channel
+ *
+ ******************************************************************************/
+int wl_get_chan_from_freq( long frequency )
+{
+    int i;
+    /*------------------------------------------------------------------------*/
+
+
+    /* Iterate through the matrix and retrieve the channel */
+    for( i = 0; i < MAX_CHAN_FREQ_MAP_ENTRIES; i++ ) {
+        if( chan_freq_list[i][1] == frequency ) {
+            return chan_freq_list[i][0];
+        }
+    }
+
+    return 0;
+} // wl_get_chan_from_freq
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wl_process_link_status()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Process the link status message signaled by the device.
+ *
+ *  PARAMETERS:
+ *
+ *      lp - a pointer to the device's private structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_process_link_status( struct wl_private *lp )
+{
+    hcf_16 link_stat;
+    /*------------------------------------------------------------------------*/
+
+    DBG_FUNC( "wl_process_link_status" );
+    DBG_ENTER( DbgInfo );
+
+    if( lp != NULL ) {
+        //link_stat = lp->hcfCtx.IFB_DSLinkStat & CFG_LINK_STAT_FW;
+        link_stat = lp->hcfCtx.IFB_LinkStat & CFG_LINK_STAT_FW;
+        switch( link_stat ) {
+        case 1:
+            DBG_TRACE( DbgInfo, "Link Status : Connected\n" );
+            wl_wext_event_ap( lp->dev );
+            break;
+        case 2:
+            DBG_TRACE( DbgInfo, "Link Status : Disconnected\n"  );
+            break;
+        case 3:
+            DBG_TRACE( DbgInfo, "Link Status : Access Point Change\n" );
+            break;
+        case 4:
+            DBG_TRACE( DbgInfo, "Link Status : Access Point Out of Range\n" );
+            break;
+        case 5:
+            DBG_TRACE( DbgInfo, "Link Status : Access Point In Range\n" );
+            break;
+        default:
+            DBG_TRACE( DbgInfo, "Link Status : UNKNOWN (0x%04x)\n", link_stat );
+            break;
+        }
+    }
+    DBG_LEAVE( DbgInfo );
+    return;
+} // wl_process_link_status
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wl_process_probe_response()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Process the probe responses retunred by the device as a result of an
+ *      active scan.
+ *
+ *  PARAMETERS:
+ *
+ *      lp - a pointer to the device's private structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_process_probe_response( struct wl_private *lp )
+{
+    PROBE_RESP  *probe_rsp;
+    hcf_8       *wpa_ie = NULL;
+    hcf_16      wpa_ie_len = 0;
+    /*------------------------------------------------------------------------*/
+
+
+    DBG_FUNC( "wl_process_probe_response" );
+    DBG_ENTER( DbgInfo );
+
+
+    if( lp != NULL ) {
+        probe_rsp = (PROBE_RESP *)&lp->ProbeResp;
+
+        wl_endian_translate_event( (ltv_t *)probe_rsp );
+
+        DBG_TRACE( DbgInfo, "(%s) =========================\n", lp->dev->name );
+        DBG_TRACE( DbgInfo, "(%s) length      : 0x%04x.\n",  lp->dev->name,
+                probe_rsp->length );
+
+        if( probe_rsp->length > 1 ) {
+            DBG_TRACE( DbgInfo, "(%s) infoType    : 0x%04x.\n", lp->dev->name,
+                    probe_rsp->infoType );
+
+            DBG_TRACE( DbgInfo, "(%s) signal      : 0x%02x.\n", lp->dev->name,
+                    probe_rsp->signal );
+
+            DBG_TRACE( DbgInfo, "(%s) silence     : 0x%02x.\n", lp->dev->name,
+                    probe_rsp->silence );
+
+            DBG_TRACE( DbgInfo, "(%s) rxFlow      : 0x%02x.\n", lp->dev->name,
+                    probe_rsp->rxFlow );
+
+            DBG_TRACE( DbgInfo, "(%s) rate        : 0x%02x.\n", lp->dev->name,
+                    probe_rsp->rate );
+
+            DBG_TRACE( DbgInfo, "(%s) frame cntl  : 0x%04x.\n", lp->dev->name,
+                    probe_rsp->frameControl );
+
+            DBG_TRACE( DbgInfo, "(%s) durID       : 0x%04x.\n", lp->dev->name,
+                    probe_rsp->durID );
+
+            DBG_TRACE( DbgInfo, "(%s) address1    : %s\n", lp->dev->name,
+                    DbgHwAddr( probe_rsp->address1 ));
+
+            DBG_TRACE( DbgInfo, "(%s) address2    : %s\n", lp->dev->name,
+                    DbgHwAddr( probe_rsp->address2 ));
+
+            DBG_TRACE( DbgInfo, "(%s) BSSID       : %s\n", lp->dev->name,
+                    DbgHwAddr( probe_rsp->BSSID ));
+
+            DBG_TRACE( DbgInfo, "(%s) sequence    : 0x%04x.\n", lp->dev->name,
+                    probe_rsp->sequence );
+
+            DBG_TRACE( DbgInfo, "(%s) address4    : %s\n", lp->dev->name,
+                    DbgHwAddr( probe_rsp->address4 ));
+
+            DBG_TRACE( DbgInfo, "(%s) datalength  : 0x%04x.\n", lp->dev->name,
+                    probe_rsp->dataLength );
+
+            DBG_TRACE( DbgInfo, "(%s) DA          : %s\n", lp->dev->name,
+                    DbgHwAddr( probe_rsp->DA ));
+
+            DBG_TRACE( DbgInfo, "(%s) SA          : %s\n", lp->dev->name,
+                    DbgHwAddr( probe_rsp->SA ));
+
+#ifdef WARP
+
+            DBG_TRACE( DbgInfo, "(%s) channel     : %d\n", lp->dev->name,
+                    probe_rsp->channel );
+
+            DBG_TRACE( DbgInfo, "(%s) band        : %d\n", lp->dev->name,
+                    probe_rsp->band );
+#else
+            DBG_TRACE( DbgInfo, "(%s) lenType     : 0x%04x.\n", lp->dev->name,
+                    probe_rsp->lenType );
+#endif  // WARP
+
+            DBG_TRACE( DbgInfo, "(%s) timeStamp   : %d.%d.%d.%d.%d.%d.%d.%d\n",
+                    lp->dev->name,
+                    probe_rsp->timeStamp[0],
+                    probe_rsp->timeStamp[1],
+                    probe_rsp->timeStamp[2],
+                    probe_rsp->timeStamp[3],
+                    probe_rsp->timeStamp[4],
+                    probe_rsp->timeStamp[5],
+                    probe_rsp->timeStamp[6],
+                    probe_rsp->timeStamp[7]);
+
+            DBG_TRACE( DbgInfo, "(%s) beaconInt   : 0x%04x.\n", lp->dev->name,
+                    probe_rsp->beaconInterval );
+
+            DBG_TRACE( DbgInfo, "(%s) capability  : 0x%04x.\n", lp->dev->name,
+                    probe_rsp->capability );
+
+            DBG_TRACE( DbgInfo, "(%s) SSID len    : 0x%04x.\n", lp->dev->name,
+                    probe_rsp->rawData[1] );
+
+
+            if( probe_rsp->rawData[1] > 0 ) {
+                char ssid[HCF_MAX_NAME_LEN];
+
+                memset( ssid, 0, sizeof( ssid ));
+                strncpy( ssid, &probe_rsp->rawData[2],
+                            probe_rsp->rawData[1] );
+
+                DBG_TRACE( DbgInfo, "(%s) SSID        : %s\n",
+                            lp->dev->name, ssid );
+            }
+
+
+            /* Parse out the WPA-IE, if one exists */
+            wpa_ie = wl_parse_wpa_ie( probe_rsp, &wpa_ie_len );
+            if( wpa_ie != NULL ) {
+                DBG_TRACE( DbgInfo, "(%s) WPA-IE      : %s\n",
+                lp->dev->name, wl_print_wpa_ie( wpa_ie, wpa_ie_len ));
+            }
+
+            DBG_TRACE( DbgInfo, "(%s) flags       : 0x%04x.\n",
+                        lp->dev->name, probe_rsp->flags );
+        }
+
+        DBG_TRACE( DbgInfo, "\n" );
+
+
+        /* If probe response length is 1, then the scan is complete */
+        if( probe_rsp->length == 1 ) {
+            DBG_TRACE( DbgInfo, "SCAN COMPLETE\n" );
+            lp->probe_results.num_aps = lp->probe_num_aps;
+            lp->probe_results.scan_complete = TRUE;
+
+            /* Reset the counter for the next scan request */
+            lp->probe_num_aps = 0;
+
+            /* Send a wireless extensions event that the scan completed */
+            wl_wext_event_scan_complete( lp->dev );
+        } else {
+            /* Only copy to the table if the entry is unique; APs sometimes
+                respond more than once to a probe */
+            if( lp->probe_num_aps == 0 ) {
+                /* Copy the info to the ScanResult structure in the private
+                adapter struct */
+                memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
+                        probe_rsp, sizeof( PROBE_RESP ));
+
+                /* Increment the number of APs detected */
+                lp->probe_num_aps++;
+            } else {
+                int count;
+                int unique = 1;
+
+                for( count = 0; count < lp->probe_num_aps; count++ ) {
+                    if( memcmp( &( probe_rsp->BSSID ),
+                        lp->probe_results.ProbeTable[count].BSSID,
+                        ETH_ALEN ) == 0 ) {
+                        unique = 0;
+                    }
+                }
+
+                if( unique ) {
+                    /* Copy the info to the ScanResult structure in the
+                    private adapter struct. Only copy if there's room in the
+                    table */
+                    if( lp->probe_num_aps < MAX_NAPS )
+                    {
+                        memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
+                                probe_rsp, sizeof( PROBE_RESP ));
+                    }
+                    else
+                    {
+                        DBG_WARNING( DbgInfo, "Num of scan results exceeds storage, truncating\n" );
+                    }
+
+                    /* Increment the number of APs detected. Note I do this
+                        here even when I don't copy the probe response to the
+                        buffer in order to detect the overflow condition */
+                    lp->probe_num_aps++;
+                }
+            }
+        }
+    }
+
+    DBG_LEAVE( DbgInfo );
+    return;
+} // wl_process_probe_response
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wl_process_updated_record()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Process the updated information record message signaled by the device.
+ *
+ *  PARAMETERS:
+ *
+ *      lp - a pointer to the device's private structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_process_updated_record( struct wl_private *lp )
+{
+    DBG_FUNC( "wl_process_updated_record" );
+    DBG_ENTER( DbgInfo );
+
+
+    if( lp != NULL ) {
+        lp->updatedRecord.u.u16[0] = CNV_LITTLE_TO_INT( lp->updatedRecord.u.u16[0] );
+
+        switch( lp->updatedRecord.u.u16[0] ) {
+        case CFG_CUR_COUNTRY_INFO:
+            DBG_TRACE( DbgInfo, "Updated Record: CFG_CUR_COUNTRY_INFO\n" );
+            wl_connect( lp );
+            break;
+
+        case CFG_PORT_STAT:
+            DBG_TRACE( DbgInfo, "Updated Record: WAIT_FOR_CONNECT (0xFD40)\n" );
+            //wl_connect( lp );
+            break;
+
+        default:
+            DBG_TRACE( DbgInfo, "UNKNOWN: 0x%04x\n",
+                       lp->updatedRecord.u.u16[0] );
+        }
+    }
+
+    DBG_LEAVE( DbgInfo );
+    return;
+} // wl_process_updated_record
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wl_process_assoc_status()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Process the association status event signaled by the device.
+ *
+ *  PARAMETERS:
+ *
+ *      lp - a pointer to the device's private structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_process_assoc_status( struct wl_private *lp )
+{
+    ASSOC_STATUS_STRCT *assoc_stat;
+    /*------------------------------------------------------------------------*/
+
+
+    DBG_FUNC( "wl_process_assoc_status" );
+    DBG_ENTER( DbgInfo );
+
+
+    if( lp != NULL ) {
+        assoc_stat = (ASSOC_STATUS_STRCT *)&lp->assoc_stat;
+
+        wl_endian_translate_event( (ltv_t *)assoc_stat );
+
+        switch( assoc_stat->assocStatus ) {
+        case 1:
+            DBG_TRACE( DbgInfo, "Association Status : STA Associated\n" );
+            break;
+
+        case 2:
+            DBG_TRACE( DbgInfo, "Association Status : STA Reassociated\n" );
+            break;
+
+        case 3:
+            DBG_TRACE( DbgInfo, "Association Status : STA Disassociated\n" );
+            break;
+
+        default:
+            DBG_TRACE( DbgInfo, "Association Status : UNKNOWN (0x%04x)\n",
+                        assoc_stat->assocStatus );
+            break;
+        }
+
+        DBG_TRACE( DbgInfo, "STA Address        : %s\n",
+                    DbgHwAddr( assoc_stat->staAddr ));
+
+        if(( assoc_stat->assocStatus == 2 )  && ( assoc_stat->len == 8 )) {
+            DBG_TRACE( DbgInfo, "Old AP Address     : %s\n",
+                        DbgHwAddr( assoc_stat->oldApAddr ));
+        }
+    }
+
+    DBG_LEAVE( DbgInfo );
+    return;
+} // wl_process_assoc_status
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wl_process_security_status()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Process the security status message signaled by the device.
+ *
+ *  PARAMETERS:
+ *
+ *      lp - a pointer to the device's private structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_process_security_status( struct wl_private *lp )
+{
+    SECURITY_STATUS_STRCT *sec_stat;
+    /*------------------------------------------------------------------------*/
+
+
+    DBG_FUNC( "wl_process_security_status" );
+    DBG_ENTER( DbgInfo );
+
+
+    if( lp != NULL ) {
+        sec_stat = (SECURITY_STATUS_STRCT *)&lp->sec_stat;
+
+        wl_endian_translate_event( (ltv_t *)sec_stat );
+
+        switch( sec_stat->securityStatus ) {
+        case 1:
+            DBG_TRACE( DbgInfo, "Security Status : Dissassociate [AP]\n" );
+            break;
+
+        case 2:
+            DBG_TRACE( DbgInfo, "Security Status : Deauthenticate [AP]\n" );
+            break;
+
+        case 3:
+            DBG_TRACE( DbgInfo, "Security Status : Authenticate Fail [STA] or [AP]\n" );
+            break;
+
+        case 4:
+            DBG_TRACE( DbgInfo, "Security Status : MIC Fail\n" );
+            break;
+
+        case 5:
+            DBG_TRACE( DbgInfo, "Security Status : Associate Fail\n" );
+            break;
+
+        default:
+            DBG_TRACE( DbgInfo, "Security Status : UNKNOWN (0x%04x)\n",
+                        sec_stat->securityStatus );
+            break;
+        }
+
+        DBG_TRACE( DbgInfo, "STA Address     : %s\n",
+                   DbgHwAddr( sec_stat->staAddr ));
+        DBG_TRACE( DbgInfo, "Reason          : 0x%04x \n", sec_stat->reason );
+
+    }
+
+    DBG_LEAVE( DbgInfo );
+    return;
+} // wl_process_security_status
+/*============================================================================*/
+
+int wl_get_tallies(struct wl_private *lp,
+		   CFG_HERMES_TALLIES_STRCT *tallies)
+{
+    int ret = 0;
+    int status;
+    CFG_HERMES_TALLIES_STRCT *pTallies;
+
+    DBG_FUNC( "wl_get_tallies" );
+    DBG_ENTER(DbgInfo);
+
+    /* Get the current tallies from the adapter */
+    lp->ltvRecord.len = 1 + HCF_TOT_TAL_CNT * sizeof(hcf_16);
+    lp->ltvRecord.typ = CFG_TALLIES;
+
+    status = hcf_get_info(&(lp->hcfCtx), (LTVP)&(lp->ltvRecord));
+
+    if( status == HCF_SUCCESS ) {
+	pTallies = (CFG_HERMES_TALLIES_STRCT *)&(lp->ltvRecord.u.u32);
+	memcpy(tallies, pTallies, sizeof(*tallies));
+    	DBG_TRACE( DbgInfo, "Get tallies okay, dixe: %d\n", sizeof(*tallies) );
+    } else {
+    	DBG_TRACE( DbgInfo, "Get tallies failed\n" );
+	ret = -EFAULT;
+    }
+
+    DBG_LEAVE( DbgInfo );
+
+    return ret;
+}
+
+/*******************************************************************************
+ *	wl_atoi()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Believe it or not, we need our own implementation of atoi in the kernel.
+ *
+ *  PARAMETERS:
+ *
+ *      string  - the ASCII string to convert to an integer
+ *
+ *  RETURNS:
+ *
+ *      unsigned integer
+ *
+ ******************************************************************************/
+unsigned int wl_atoi( char *string )
+{
+unsigned int base = 10;				//default to decimal
+unsigned int value = 0;
+unsigned int c;
+int i = strlen( string );
+
+	if ( i > 2 && string[0] == '0' && ( string[1] | ('X'^'x') ) == 'x' ) {
+		base = 16;
+		string +=2;
+	}
+	while ( ( c = *string++ ) != '\0' ) {
+		if ( value > UINT_MAX / base ) {	//test for overrun
+			DBG_FUNC( "wl_atoi" );	//don't overload the log file with good messages
+			DBG_ENTER( DbgInfo );
+			DBG_ERROR( DbgInfo, "string \"%s\", lenght exceeds expectations\n", string );
+			printk( "<1>string \"%s\", lenght exceeds expectations\n", string );
+			DBG_LEAVE( DbgInfo );
+			break;
+		}
+		c -= '0';
+		if ( 0 <= c && c <= 9 ) value = base * value + c;
+		else if ( base == 16 ) {
+			c += '0';
+			c |= 'A'^'a';
+			c = c - 'a'+ 10;
+			if ( 10 <= c && c <= 15 ) value = base * value + c;
+		}
+	}
+	return value;
+} // wl_atoi
+
diff --git a/drivers/staging/wlags49_h2/wl_util.h b/drivers/staging/wlags49_h2/wl_util.h
new file mode 100644
index 0000000..16cd6c5
--- /dev/null
+++ b/drivers/staging/wlags49_h2/wl_util.h
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Agere Systems Inc.
+ * Wireless device driver for Linux (wlags49).
+ *
+ * Copyright (c) 1998-2003 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * Initially developed by TriplePoint, Inc.
+ *   http://www.triplepoint.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ *   Header describing information required for utility functions used
+ *   throughout the driver.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2003 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following Disclaimer as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ ******************************************************************************/
+
+#ifndef __WL_UTIL_H__
+#define __WL_UTIL_H__
+
+/*******************************************************************************
+ *  function prototypes
+ ******************************************************************************/
+int dbm( int value );
+
+int is_valid_key_string( char *s );
+
+void key_string2key( char *ks, KEY_STRCT *key );
+
+int hexdigit2int( char c );
+
+void wl_hcf_error( struct net_device *dev, int hcfStatus );
+
+void wl_endian_translate_event( ltv_t *pLtv );
+
+int wl_has_wep( IFBP ifbp );
+
+
+#if DBG
+const char *DbgHwAddr( unsigned char *hwAddr );
+#endif // DBG
+
+hcf_8   wl_parse_ds_ie( PROBE_RESP *probe_rsp );
+hcf_8 * wl_parse_wpa_ie( PROBE_RESP *probe_rsp, hcf_16 *length );
+hcf_8 * wl_print_wpa_ie( hcf_8 *buffer, int length );
+
+int wl_get_tallies(struct wl_private *, CFG_HERMES_TALLIES_STRCT *);
+int wl_is_a_valid_chan( int channel );
+int wl_is_a_valid_freq( long frequency );
+long wl_get_freq_from_chan( int channel );
+int wl_get_chan_from_freq( long frequency );
+
+void wl_process_link_status( struct wl_private *lp );
+void wl_process_probe_response( struct wl_private *lp );
+void wl_process_updated_record( struct wl_private *lp );
+void wl_process_assoc_status( struct wl_private *lp );
+void wl_process_security_status( struct wl_private *lp );
+
+unsigned int wl_atoi( char *string );
+
+#endif  // __WL_UTIL_H__
diff --git a/drivers/staging/wlags49_h2/wl_version.h b/drivers/staging/wlags49_h2/wl_version.h
new file mode 100644
index 0000000..a5e604c
--- /dev/null
+++ b/drivers/staging/wlags49_h2/wl_version.h
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Agere Systems Inc.
+ * Wireless device driver for Linux (wlags49).
+ *
+ * Copyright (c) 1998-2003 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * Initially developed by TriplePoint, Inc.
+ *   http://www.triplepoint.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ *   This header file contains version information for the code base, as well as
+ *   special definitions and macros needed by certain versions of the code.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2003 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following Disclaimer as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ ******************************************************************************/
+
+#ifndef __WL_VERSION_H__
+#define __WL_VERSION_H__
+
+/*******************************************************************************
+ *  include files
+ ******************************************************************************/
+//#include <linux/config.h>
+#include <linux/version.h>
+
+#ifndef CONFIG_MODVERSIONS
+#define __NO_VERSION__
+#endif  // CONFIG_MODVERSIONS
+
+/*******************************************************************************
+ *  constant definitions
+ ******************************************************************************/
+
+#define VENDOR_NAME         "Agere Systems, http://www.agere.com"
+
+#define DRIVER_NAME         "wlags49"
+#define DRV_IDENTITY        49
+
+#define DRV_MAJOR_VERSION   7
+#define DRV_MINOR_VERSION   22
+#define DRV_VERSION_STR     "7.22"
+
+
+#if defined BUS_PCMCIA
+#define BUS_TYPE            "PCMCIA"
+#elif defined BUS_PCI
+#define BUS_TYPE            "PCI"
+#else
+err: define bus type;
+#endif  // BUS_XXX
+
+#if defined HERMES25
+#define HW_TYPE				"HII.5"
+#else
+#define HW_TYPE				"HII"
+#endif // HERMES25
+
+#if defined WARP
+#define FW_TYPE				"WARP"
+#else
+#define FW_TYPE				"BEAGLE"
+#endif // WARP
+
+#if defined HERMES25
+#if defined WARP
+#define DRV_VARIANT         3
+#else
+#define DRV_VARIANT         4
+#endif // WARP
+#else
+#define DRV_VARIANT         2
+#endif // HERMES25
+
+#ifdef BUS_PCMCIA
+#if defined HERMES25
+#define MODULE_NAME         DRIVER_NAME "_h25_cs"
+#else
+#define MODULE_NAME         DRIVER_NAME "_h2_cs"
+#endif  /* HERMES25 */
+#elif defined BUS_PCI
+#if defined HERMES25
+#define MODULE_NAME         DRIVER_NAME "_h25"
+#else
+#define MODULE_NAME         DRIVER_NAME "_h2"
+#endif  /* HERMES25 */
+#endif  /* BUS_XXX */
+
+#ifdef DBG
+#define MODULE_DATE         __DATE__ " " __TIME__
+#else
+#define MODULE_DATE         "07/18/2004 13:30:00"
+#endif // DBG
+
+//#define STR2(m) #m
+//#define STR1(m) STR2(m)
+//#define MODULE_NAME			STR1( MOD_NAME )
+
+#define VERSION_INFO        MODULE_NAME " v" DRV_VERSION_STR \
+							" for " BUS_TYPE ", " 											   	 \
+							MODULE_DATE " by " VENDOR_NAME
+
+#define WIRELESS_SUPPORT    15  // The version of wireless extensions we support
+
+//#define DBG_MOD_NAME         DRIVER_NAME ":" BUS_TYPE ":" HW_TYPE ":" FW_TYPE
+#define DBG_MOD_NAME        MODULE_NAME
+
+
+
+/*******************************************************************************
+ *  bus architechture specific defines, includes, etc.
+ ******************************************************************************/
+/*
+ * There doesn't seem to be a difference for PCMCIA and PCI anymore, at least
+ * for PCMCIA the same defines are needed now as previously only used for PCI
+ */
+#if USE_WEXT
+#define HAS_WIRELESS_EXTENSIONS
+#endif  // USE_WEXT
+
+#define NEW_MULTICAST
+#define ALLOC_SKB(len)   dev_alloc_skb(len+2)
+#define GET_PACKET(dev, skb, count)\
+                        skb_reserve((skb), 2); \
+                        BLOCK_INPUT(skb_put((skb), (count)), (count)); \
+                        (skb)->protocol = eth_type_trans((skb), (dev))
+#define GET_PACKET_DMA(dev, skb, count)\
+                        skb_reserve((skb), 2); \
+                        BLOCK_INPUT_DMA(skb_put((skb), (count)), (count)); \
+                        (skb)->protocol = eth_type_trans((skb), (dev))
+
+
+
+
+#endif  // __WL_VERSION_H__
diff --git a/drivers/staging/wlags49_h2/wl_wext.c b/drivers/staging/wlags49_h2/wl_wext.c
new file mode 100644
index 0000000..4434e00
--- /dev/null
+++ b/drivers/staging/wlags49_h2/wl_wext.c
@@ -0,0 +1,4130 @@
+/*******************************************************************************
+ * Agere Systems Inc.
+ * Wireless device driver for Linux (wlags49).
+ *
+ * Copyright (c) 1998-2003 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * Initially developed by TriplePoint, Inc.
+ *   http://www.triplepoint.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2003 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following Disclaimer as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ ******************************************************************************/
+
+/*******************************************************************************
+ *  include files
+ ******************************************************************************/
+#include <wl_version.h>
+
+#include <linux/if_arp.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+
+#include <debug.h>
+#include <hcf.h>
+#include <hcfdef.h>
+
+#include <wl_if.h>
+#include <wl_internal.h>
+#include <wl_util.h>
+#include <wl_main.h>
+#include <wl_wext.h>
+#include <wl_priv.h>
+
+
+
+/* If WIRELESS_EXT is not defined (as a result of HAS_WIRELESS_EXTENSIONS
+   #including linux/wireless.h), then these functions do not need to be included
+   in the build. */
+#ifdef WIRELESS_EXT
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+#define IWE_STREAM_ADD_EVENT(info, buf, end, iwe, len) \
+    iwe_stream_add_event(buf, end, iwe, len)
+#define IWE_STREAM_ADD_POINT(info, buf, end, iwe, msg) \
+    iwe_stream_add_point(buf, end, iwe, msg)
+#else
+#define IWE_STREAM_ADD_EVENT(info, buf, end, iwe, len) \
+    iwe_stream_add_event(info, buf, end, iwe, len)
+#define IWE_STREAM_ADD_POINT(info, buf, end, iwe, msg) \
+    iwe_stream_add_point(info, buf, end, iwe, msg)
+#endif
+
+
+
+/*******************************************************************************
+ * global definitions
+ ******************************************************************************/
+#if DBG
+extern dbg_info_t *DbgInfo;
+#endif  // DBG
+
+
+
+
+/*******************************************************************************
+ *	wireless_commit()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Commit
+ *  protocol used.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+static int wireless_commit(struct net_device *dev,
+			   struct iw_request_info *info,
+			   union iwreq_data *rqu, char *extra)
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int ret = 0;
+	/*------------------------------------------------------------------------*/
+
+	DBG_FUNC( "wireless_commit" );
+	DBG_ENTER(DbgInfo);
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	wl_apply(lp);
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_commit
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wireless_get_protocol()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Returns a vendor-defined string that should identify the wireless
+ *  protocol used.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+static int wireless_get_protocol(struct net_device *dev, struct iw_request_info *info, char *name, char *extra)
+{
+	DBG_FUNC( "wireless_get_protocol" );
+	DBG_ENTER( DbgInfo );
+
+	/* Originally, the driver was placing the string "Wireless" here. However,
+	   the wireless extensions (/linux/wireless.h) indicate this string should
+	   describe the wireless protocol. */
+
+	strcpy(name, "IEEE 802.11b");
+
+	DBG_LEAVE(DbgInfo);
+	return 0;
+} // wireless_get_protocol
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wireless_set_frequency()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Sets the frequency (channel) on which the card should Tx/Rx.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+static int wireless_set_frequency(struct net_device *dev, struct iw_request_info *info, struct iw_freq *freq, char *extra)
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int channel = 0;
+	int ret     = 0;
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wireless_set_frequency" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	if( !capable( CAP_NET_ADMIN )) {
+		ret = -EPERM;
+		DBG_LEAVE( DbgInfo );
+		return ret;
+	}
+
+
+	/* If frequency specified, look up channel */
+	if( freq->e == 1 ) {
+		int f = freq->m / 100000;
+		channel = wl_get_chan_from_freq( f );
+	}
+
+
+	/* Channel specified */
+	if( freq->e == 0 ) {
+		channel = freq->m;
+	}
+
+
+	/* If the channel is an 802.11a channel, set Bit 8 */
+	if( channel > 14 ) {
+		channel = channel | 0x100;
+	}
+
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	lp->Channel = channel;
+
+
+	/* Commit the adapter parameters */
+	wl_apply( lp );
+
+	/* Send an event that channel/freq has been set */
+	wl_wext_event_freq( lp->dev );
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_set_frequency
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wireless_get_frequency()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Gets the frequency (channel) on which the card is Tx/Rx.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+static int wireless_get_frequency(struct net_device *dev, struct iw_request_info *info, struct iw_freq *freq, char *extra)
+
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int ret = -1;
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wireless_get_frequency" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	lp->ltvRecord.len = 2;
+	lp->ltvRecord.typ = CFG_CUR_CHANNEL;
+
+	ret = hcf_get_info( &(lp->hcfCtx), (LTVP)&( lp->ltvRecord ));
+	if( ret == HCF_SUCCESS ) {
+		hcf_16 channel = CNV_LITTLE_TO_INT( lp->ltvRecord.u.u16[0] );
+
+#ifdef USE_FREQUENCY
+
+		freq->m = wl_get_freq_from_chan( channel ) * 100000;
+		freq->e = 1;
+#else
+
+		freq->m = channel;
+		freq->e = 0;
+
+#endif /* USE_FREQUENCY */
+	}
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+	ret = (ret == HCF_SUCCESS ? 0 : -EFAULT);
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_get_frequency
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wireless_get_range()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function is used to provide misc info and statistics about the
+ *  wireless device.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+static int wireless_get_range(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra)
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long      flags;
+	struct iw_range   *range = (struct iw_range *) extra;
+	int                ret = 0;
+	int                status = -1;
+	int                count;
+	__u16             *pTxRate;
+	int                retries = 0;
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wireless_get_range" );
+	DBG_ENTER( DbgInfo );
+
+	/* Set range information */
+	data->length = sizeof(struct iw_range);
+	memset(range, 0, sizeof(struct iw_range));
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	/* Set range information */
+	memset( range, 0, sizeof( struct iw_range ));
+
+retry:
+	/* Get the current transmit rate from the adapter */
+	lp->ltvRecord.len = 1 + (sizeof(*pTxRate) / sizeof(hcf_16));
+	lp->ltvRecord.typ = CFG_CUR_TX_RATE;
+
+	status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+	if( status != HCF_SUCCESS ) {
+		/* Recovery action: reset and retry up to 10 times */
+		DBG_TRACE( DbgInfo, "Get CFG_CUR_TX_RATE failed: 0x%x\n", status );
+
+		if (retries < 10) {
+			retries++;
+
+			/* Holding the lock too long, make a gap to allow other processes */
+			wl_unlock(lp, &flags);
+			wl_lock( lp, &flags );
+
+			status = wl_reset( dev );
+			if ( status != HCF_SUCCESS ) {
+				DBG_TRACE( DbgInfo, "reset failed: 0x%x\n", status );
+
+				ret = -EFAULT;
+				goto out_unlock;
+			}
+
+			/* Holding the lock too long, make a gap to allow other processes */
+			wl_unlock(lp, &flags);
+			wl_lock( lp, &flags );
+
+			goto retry;
+
+		} else {
+			DBG_TRACE( DbgInfo, "Get CFG_CUR_TX_RATE failed: %d retries\n", retries );
+			ret = -EFAULT;
+			goto out_unlock;
+		}
+	}
+
+	/* Holding the lock too long, make a gap to allow other processes */
+	wl_unlock(lp, &flags);
+	wl_lock( lp, &flags );
+
+	pTxRate = (__u16 *)&( lp->ltvRecord.u.u32 );
+
+	range->throughput = CNV_LITTLE_TO_INT( *pTxRate ) * MEGABIT;
+
+	if (retries > 0) {
+		DBG_TRACE( DbgInfo, "Get CFG_CUR_TX_RATE succes: %d retries\n", retries );
+	}
+
+	// NWID - NOT SUPPORTED
+
+
+	/* Channel/Frequency Info */
+	range->num_channels = RADIO_CHANNELS;
+
+
+	/* Signal Level Thresholds */
+	range->sensitivity = RADIO_SENSITIVITY_LEVELS;
+
+
+	/* Link quality */
+#ifdef USE_DBM
+
+	range->max_qual.qual     = (u_char)HCF_MAX_COMM_QUALITY;
+
+	/* If the value returned in /proc/net/wireless is greater than the maximum range,
+	   iwconfig assumes that the value is in dBm. Because an unsigned char is used,
+	   it requires a bit of contorsion... */
+
+	range->max_qual.level   = (u_char)( dbm( HCF_MIN_SIGNAL_LEVEL ) - 1 );
+	range->max_qual.noise   = (u_char)( dbm( HCF_MIN_NOISE_LEVEL ) - 1 );
+#else
+
+	range->max_qual.qual    = 100;
+	range->max_qual.level   = 100;
+	range->max_qual.noise   = 100;
+
+#endif /* USE_DBM */
+
+
+	/* Set available rates */
+	range->num_bitrates = 0;
+
+	lp->ltvRecord.len = 6;
+	lp->ltvRecord.typ = CFG_SUPPORTED_DATA_RATES;
+
+	status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+	if( status == HCF_SUCCESS ) {
+		for( count = 0; count < MAX_RATES; count++ )
+			if( lp->ltvRecord.u.u8[count+2] != 0 ) {
+				range->bitrate[count] = lp->ltvRecord.u.u8[count+2] * MEGABIT / 2;
+				range->num_bitrates++;
+			}
+	} else {
+		DBG_TRACE( DbgInfo, "CFG_SUPPORTED_DATA_RATES: 0x%x\n", status );
+		ret = -EFAULT;
+		goto out_unlock;
+	}
+
+	/* RTS Threshold info */
+	range->min_rts   = MIN_RTS_BYTES;
+	range->max_rts   = MAX_RTS_BYTES;
+
+	// Frag Threshold info - NOT SUPPORTED
+
+	// Power Management info - NOT SUPPORTED
+
+	/* Encryption */
+
+#if WIRELESS_EXT > 8
+
+	/* Holding the lock too long, make a gap to allow other processes */
+	wl_unlock(lp, &flags);
+	wl_lock( lp, &flags );
+
+	/* Is WEP supported? */
+
+	if( wl_has_wep( &( lp->hcfCtx ))) {
+		/* WEP: RC4 40 bits */
+		range->encoding_size[0]      = MIN_KEY_SIZE;
+
+		/* RC4 ~128 bits */
+		range->encoding_size[1]      = MAX_KEY_SIZE;
+		range->num_encoding_sizes    = 2;
+		range->max_encoding_tokens   = MAX_KEYS;
+	}
+
+#endif /* WIRELESS_EXT > 8 */
+
+	/* Tx Power Info */
+	range->txpower_capa  = IW_TXPOW_MWATT;
+	range->num_txpower   = 1;
+	range->txpower[0]    = RADIO_TX_POWER_MWATT;
+
+#if WIRELESS_EXT > 10
+
+	/* Wireless Extension Info */
+	range->we_version_compiled   = WIRELESS_EXT;
+	range->we_version_source     = WIRELESS_SUPPORT;
+
+	// Retry Limits and Lifetime - NOT SUPPORTED
+
+#endif
+
+
+#if WIRELESS_EXT > 11
+
+	/* Holding the lock too long, make a gap to allow other processes */
+	wl_unlock(lp, &flags);
+	wl_lock( lp, &flags );
+
+	DBG_TRACE( DbgInfo, "calling wl_wireless_stats\n" );
+	wl_wireless_stats( lp->dev );
+	range->avg_qual = lp->wstats.qual;
+	DBG_TRACE( DbgInfo, "wl_wireless_stats done\n" );
+
+#endif
+
+	/* Event capability (kernel + driver) */
+	range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
+				IW_EVENT_CAPA_MASK(SIOCGIWAP) |
+				IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
+	range->event_capa[1] = IW_EVENT_CAPA_K_1;
+	range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVREGISTERED) |
+				IW_EVENT_CAPA_MASK(IWEVCUSTOM) |
+				IW_EVENT_CAPA_MASK(IWEVEXPIRED));
+
+	range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_CIPHER_TKIP;
+
+out_unlock:
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+	DBG_LEAVE(DbgInfo);
+	return ret;
+} // wireless_get_range
+/*============================================================================*/
+
+
+/*******************************************************************************
+ *	wireless_get_bssid()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Gets the BSSID the wireless device is currently associated with.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+static int wireless_get_bssid(struct net_device *dev, struct iw_request_info *info, struct sockaddr *ap_addr, char *extra)
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int ret = 0;
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
+	int status = -1;
+#endif /* (HCF_TYPE) & HCF_TYPE_STA */
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wireless_get_bssid" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	memset( &ap_addr->sa_data, 0, ETH_ALEN );
+
+	ap_addr->sa_family = ARPHRD_ETHER;
+
+	/* Assume AP mode here, which means the BSSID is our own MAC address. In
+	   STA mode, this address will be overwritten with the actual BSSID using
+	   the code below. */
+	memcpy(&ap_addr->sa_data, lp->dev->dev_addr, ETH_ALEN);
+
+
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
+					//;?should we return an error status in AP mode
+
+	if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA  ) {
+		/* Get Current BSSID */
+		lp->ltvRecord.typ = CFG_CUR_BSSID;
+		lp->ltvRecord.len = 4;
+		status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+
+		if( status == HCF_SUCCESS ) {
+			/* Copy info into sockaddr struct */
+			memcpy(&ap_addr->sa_data, lp->ltvRecord.u.u8, ETH_ALEN);
+		} else {
+			ret = -EFAULT;
+		}
+	}
+
+#endif // (HCF_TYPE) & HCF_TYPE_STA
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE(DbgInfo);
+	return ret;
+} // wireless_get_bssid
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wireless_get_ap_list()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Gets the results of a network scan.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ *  NOTE: SIOCGIWAPLIST has been deprecated by SIOCSIWSCAN. This function
+ *       implements SIOCGIWAPLIST only to provide backwards compatibility. For
+ *       all systems using WIRELESS_EXT v14 and higher, use SIOCSIWSCAN!
+ *
+ ******************************************************************************/
+static int wireless_get_ap_list (struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra)
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long	  flags;
+	int                 ret;
+	int                 num_aps = -1;
+	int                 sec_count = 0;
+	hcf_32              count;
+	struct sockaddr     *hwa = NULL;
+	struct iw_quality   *qual = NULL;
+#ifdef WARP
+	ScanResult			*p = &lp->scan_results;
+#else
+	ProbeResult         *p = &lp->probe_results;
+#endif  // WARP
+	/*------------------------------------------------------------------------*/
+
+	DBG_FUNC( "wireless_get_ap_list" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	/* Set the completion state to FALSE */
+	lp->scan_results.scan_complete = FALSE;
+	lp->probe_results.scan_complete = FALSE;
+	/* Channels to scan */
+	lp->ltvRecord.len       = 2;
+	lp->ltvRecord.typ       = CFG_SCAN_CHANNELS_2GHZ;
+	lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 0x7FFF );
+	ret = hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+	DBG_TRACE( DbgInfo, "CFG_SCAN_CHANNELS_2GHZ result: 0x%x\n", ret );
+
+	/* Set the SCAN_SSID to "ANY". Using this RID for scan prevents the need to
+	   disassociate from the network we are currently on */
+	lp->ltvRecord.len       = 2;
+	lp->ltvRecord.typ       = CFG_SCAN_SSID;
+	lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 0 );
+	ret = hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+	DBG_TRACE( DbgInfo, "CFG_SCAN_SSID to 'any' ret: 0x%x\n", ret );
+
+	/* Initiate the scan */
+#ifdef WARP
+	ret = hcf_action( &( lp->hcfCtx ), MDD_ACT_SCAN );
+#else
+	ret = hcf_action( &( lp->hcfCtx ), HCF_ACT_ACS_SCAN );
+#endif  // WARP
+
+    	wl_act_int_on( lp );
+
+	//;? unlock? what about the access to lp below? is it broken?
+	wl_unlock(lp, &flags);
+
+	if( ret == HCF_SUCCESS ) {
+		DBG_TRACE( DbgInfo, "SUCCESSFULLY INITIATED SCAN...\n" );
+		while( (*p).scan_complete == FALSE && ret == HCF_SUCCESS ) {
+			DBG_TRACE( DbgInfo, "Waiting for scan results...\n" );
+			/* Abort the scan if we've waited for more than MAX_SCAN_TIME_SEC */
+			if( sec_count++ > MAX_SCAN_TIME_SEC ) {
+				ret = -EIO;
+			} else {
+				/* Wait for 1 sec in 10ms intervals, scheduling the kernel to do
+				   other things in the meantime, This prevents system lockups by
+				   giving some time back to the kernel */
+				for( count = 0; count < 100; count ++ ) {
+					mdelay( 10 );
+					schedule( );
+				}
+			}
+		}
+
+		rmb();
+
+		if ( ret != HCF_SUCCESS ) {
+			DBG_ERROR( DbgInfo, "timeout waiting for scan results\n" );
+		} else {
+			num_aps             = (*p)/*lp->probe_results*/.num_aps;
+			if (num_aps > IW_MAX_AP) {
+				num_aps = IW_MAX_AP;
+			}
+			data->length = num_aps;
+			hwa = (struct sockaddr *)extra;
+			qual = (struct iw_quality *) extra +
+					( sizeof( struct sockaddr ) * num_aps );
+
+			/* This flag is used to tell the user if we provide quality
+			   information. Since we provide signal/noise levels but no
+			   quality info on a scan, this is set to 0. Setting to 1 and
+			   providing a quality of 0 produces weird results. If we ever
+			   provide quality (or can calculate it), this can be changed */
+			data->flags = 0;
+
+			for( count = 0; count < num_aps; count++ ) {
+#ifdef WARP
+				memcpy( hwa[count].sa_data,
+						(*p)/*lp->scan_results*/.APTable[count].bssid, ETH_ALEN );
+#else  //;?why use BSSID and bssid as names in seemingly very comparable situations
+				DBG_PRINT( "BSSID: %s\n", DbgHwAddr( (*p)/*lp->probe_results*/.ProbeTable[count].BSSID ));
+				memcpy( hwa[count].sa_data,
+						(*p)/*lp->probe_results*/.ProbeTable[count].BSSID, ETH_ALEN );
+#endif // WARP
+			}
+			/* Once the data is copied to the wireless struct, invalidate the
+			   scan result to initiate a rescan on the next request */
+			(*p)/*lp->probe_results*/.scan_complete = FALSE;
+			/* Send the wireless event that the scan has completed, just in case
+			   it's needed */
+			wl_wext_event_scan_complete( lp->dev );
+		}
+	}
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_get_ap_list
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wireless_set_sensitivity()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Sets the sensitivity (distance between APs) of the wireless card.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+static int wireless_set_sensitivity(struct net_device *dev, struct iw_request_info *info, struct iw_param *sens, char *extra)
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int ret = 0;
+	int dens = sens->value;
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wireless_set_sensitivity" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	if(( dens < 1 ) || ( dens > 3 )) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	lp->DistanceBetweenAPs = dens;
+	wl_apply( lp );
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_set_sensitivity
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wireless_get_sensitivity()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Gets the sensitivity (distance between APs) of the wireless card.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+static int wireless_get_sensitivity(struct net_device *dev, struct iw_request_info *info, struct iw_param *sens, char *extra)
+{
+	struct wl_private *lp = wl_priv(dev);
+	int ret = 0;
+	/*------------------------------------------------------------------------*/
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wireless_get_sensitivity" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	/* not worth locking ... */
+	sens->value = lp->DistanceBetweenAPs;
+	sens->fixed = 0;	/* auto */
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_get_sensitivity
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wireless_set_essid()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Sets the ESSID (network name) that the wireless device should associate
+ *  with.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+static int wireless_set_essid(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *ssid)
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int ret = 0;
+
+	DBG_FUNC( "wireless_set_essid" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	if (data->flags != 0 && data->length > HCF_MAX_NAME_LEN + 1) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	memset( lp->NetworkName, 0, sizeof( lp->NetworkName ));
+
+	/* data->flags is zero to ask for "any" */
+	if( data->flags == 0 ) {
+		/* Need this because in STAP build PARM_DEFAULT_SSID is "LinuxAP"
+		 * ;?but there ain't no STAP anymore*/
+		if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA  ) {
+			strcpy( lp->NetworkName, "ANY" );
+		} else {
+			//strcpy( lp->NetworkName, "ANY" );
+			strcpy( lp->NetworkName, PARM_DEFAULT_SSID );
+		}
+	} else {
+		memcpy( lp->NetworkName, ssid, data->length );
+	}
+
+	DBG_NOTICE( DbgInfo, "set NetworkName: %s\n", ssid );
+
+	/* Commit the adapter parameters */
+	wl_apply( lp );
+
+	/* Send an event that ESSID has been set */
+	wl_wext_event_essid( lp->dev );
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_set_essid
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wireless_get_essid()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Gets the ESSID (network name) that the wireless device is associated
+ *  with.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+static int wireless_get_essid(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *essid)
+
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int         ret = 0;
+	int         status = -1;
+	wvName_t    *pName;
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wireless_get_essid" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	/* Get the desired network name */
+	lp->ltvRecord.len = 1 + ( sizeof( *pName ) / sizeof( hcf_16 ));
+
+
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
+					//;?should we return an error status in AP mode
+
+	lp->ltvRecord.typ = CFG_DESIRED_SSID;
+
+#endif
+
+
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
+		//;?should we restore this to allow smaller memory footprint
+
+	if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
+		lp->ltvRecord.typ = CFG_CNF_OWN_SSID;
+	}
+
+#endif // HCF_AP
+
+
+	status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+	if( status == HCF_SUCCESS ) {
+		pName = (wvName_t *)&( lp->ltvRecord.u.u32 );
+
+		/* Endian translate the string length */
+		pName->length = CNV_LITTLE_TO_INT( pName->length );
+
+		/* Copy the information into the user buffer */
+		data->length = pName->length;
+
+		/* NOTE: Null terminating is necessary for proper display of the SSID in
+		   the wireless tools */
+		data->length = pName->length + 1;
+		if( pName->length < HCF_MAX_NAME_LEN ) {
+			pName->name[pName->length] = '\0';
+		}
+
+		data->flags = 1;
+
+
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
+					//;?should we return an error status in AP mode
+#ifdef RETURN_CURRENT_NETWORKNAME
+
+		/* if desired is null ("any"), return current or "any" */
+		if( pName->name[0] == '\0' ) {
+			/* Get the current network name */
+			lp->ltvRecord.len = 1 + ( sizeof(*pName ) / sizeof( hcf_16 ));
+			lp->ltvRecord.typ = CFG_CUR_SSID;
+
+			status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+
+			if( status == HCF_SUCCESS ) {
+				pName = (wvName_t *)&( lp->ltvRecord.u.u32 );
+
+				/* Endian translate the string length */
+				pName->length = CNV_LITTLE_TO_INT( pName->length );
+
+				/* Copy the information into the user buffer */
+				data->length = pName->length + 1;
+				if( pName->length < HCF_MAX_NAME_LEN ) {
+					pName->name[pName->length] = '\0';
+				}
+
+				data->flags = 1;
+			} else {
+				ret = -EFAULT;
+				goto out_unlock;
+			}
+		}
+
+#endif // RETURN_CURRENT_NETWORKNAME
+#endif // HCF_STA
+
+		data->length--;
+
+		if (pName->length > IW_ESSID_MAX_SIZE) {
+			ret = -EFAULT;
+			goto out_unlock;
+		}
+
+		memcpy(essid, pName->name, pName->length);
+	} else {
+		ret = -EFAULT;
+		goto out_unlock;
+	}
+
+out_unlock:
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_get_essid
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wireless_set_encode()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *     Sets the encryption keys and status (enable or disable).
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+static int wireless_set_encode(struct net_device *dev, struct iw_request_info *info, struct iw_point *erq, char *keybuf)
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int     ret = 0;
+
+#if 1 //;? #if WIRELESS_EXT > 8 - used unconditionally in the rest of the code...
+	hcf_8   encryption_state;
+#endif // WIRELESS_EXT > 8
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wireless_set_encode" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	/* Is encryption supported? */
+	if( !wl_has_wep( &( lp->hcfCtx ))) {
+		DBG_WARNING( DbgInfo, "WEP not supported on this device\n" );
+		ret = -EOPNOTSUPP;
+		goto out_unlock;
+	}
+
+	DBG_NOTICE( DbgInfo, "pointer: %p, length: %d, flags: %#x\n",
+				keybuf, erq->length,
+				erq->flags);
+
+	/* Save state of Encryption switch */
+	encryption_state = lp->EnableEncryption;
+
+	/* Basic checking: do we have a key to set? */
+	if((erq->length) != 0) {
+		int index   = ( erq->flags & IW_ENCODE_INDEX ) - 1;
+		int tk      = lp->TransmitKeyID - 1;		// current key
+
+
+		/* Check the size of the key */
+		switch(erq->length) {
+		case 0:
+			break;
+
+		case MIN_KEY_SIZE:
+		case MAX_KEY_SIZE:
+
+			/* Check the index */
+			if(( index < 0 ) || ( index >= MAX_KEYS )) {
+				index = tk;
+			}
+
+			/* Cleanup */
+			memset( lp->DefaultKeys.key[index].key, 0, MAX_KEY_SIZE );
+
+			/* Copy the key in the driver */
+			memcpy( lp->DefaultKeys.key[index].key, keybuf, erq->length);
+
+			/* Set the length */
+			lp->DefaultKeys.key[index].len = erq->length;
+
+			DBG_NOTICE( DbgInfo, "encoding.length: %d\n", erq->length );
+			DBG_NOTICE( DbgInfo, "set key: %s(%d) [%d]\n", lp->DefaultKeys.key[index].key,
+						lp->DefaultKeys.key[index].len, index );
+
+			/* Enable WEP (if possible) */
+			if(( index == tk ) && ( lp->DefaultKeys.key[tk].len > 0 )) {
+				lp->EnableEncryption = 1;
+			}
+
+			break;
+
+		default:
+			DBG_WARNING( DbgInfo, "Invalid Key length\n" );
+			ret = -EINVAL;
+			goto out_unlock;
+		}
+	} else {
+		int index = ( erq->flags & IW_ENCODE_INDEX ) - 1;
+
+
+		/* Do we want to just set the current transmit key? */
+		if(( index >= 0 ) && ( index < MAX_KEYS )) {
+			DBG_NOTICE( DbgInfo, "index: %d; len: %d\n", index,
+						lp->DefaultKeys.key[index].len );
+
+			if( lp->DefaultKeys.key[index].len > 0 ) {
+				lp->TransmitKeyID       = index + 1;
+				lp->EnableEncryption    = 1;
+			} else {
+				DBG_WARNING( DbgInfo, "Problem setting the current TxKey\n" );
+				DBG_LEAVE( DbgInfo );
+				ret = -EINVAL;
+			}
+		}
+	}
+
+	/* Read the flags */
+	if( erq->flags & IW_ENCODE_DISABLED ) {
+		lp->EnableEncryption = 0;	// disable encryption
+	} else {
+		lp->EnableEncryption = 1;
+	}
+
+	if( erq->flags & IW_ENCODE_RESTRICTED ) {
+		DBG_WARNING( DbgInfo, "IW_ENCODE_RESTRICTED invalid\n" );
+		ret = -EINVAL;		// Invalid
+	}
+
+	DBG_TRACE( DbgInfo, "encryption_state :       %d\n", encryption_state );
+	DBG_TRACE( DbgInfo, "lp->EnableEncryption :   %d\n", lp->EnableEncryption );
+	DBG_TRACE( DbgInfo, "erq->length            : %d\n",
+			   erq->length);
+	DBG_TRACE( DbgInfo, "erq->flags             : 0x%x\n",
+			   erq->flags);
+
+	/* Write the changes to the card */
+	if( ret == 0 ) {
+		DBG_NOTICE( DbgInfo, "encrypt: %d, ID: %d\n", lp->EnableEncryption,
+					lp->TransmitKeyID );
+
+		if( lp->EnableEncryption == encryption_state ) {
+			if( erq->length != 0 ) {
+				/* Dynamic WEP key update */
+				wl_set_wep_keys( lp );
+			}
+		} else {
+			/* To switch encryption on/off, soft reset is required */
+			wl_apply( lp );
+		}
+	}
+
+	/* Send an event that Encryption has been set */
+	wl_wext_event_encode( dev );
+
+out_unlock:
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_set_encode
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wireless_get_encode()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *     Gets the encryption keys and status.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+static int wireless_get_encode(struct net_device *dev, struct iw_request_info *info, struct iw_point *erq, char *key)
+
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int ret = 0;
+	int index;
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wireless_get_encode" );
+	DBG_ENTER( DbgInfo );
+	DBG_NOTICE(DbgInfo, "GIWENCODE: encrypt: %d, ID: %d\n", lp->EnableEncryption, lp->TransmitKeyID);
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	/* Only super-user can see WEP key */
+	if( !capable( CAP_NET_ADMIN )) {
+		ret = -EPERM;
+		DBG_LEAVE( DbgInfo );
+		return ret;
+	}
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	/* Is it supported? */
+	if( !wl_has_wep( &( lp->hcfCtx ))) {
+		ret = -EOPNOTSUPP;
+		goto out_unlock;
+	}
+
+	/* Basic checking */
+	index = (erq->flags & IW_ENCODE_INDEX ) - 1;
+
+
+	/* Set the flags */
+	erq->flags = 0;
+
+	if( lp->EnableEncryption == 0 ) {
+		erq->flags |= IW_ENCODE_DISABLED;
+	}
+
+	/* Which key do we want */
+	if(( index < 0 ) || ( index >= MAX_KEYS )) {
+		index = lp->TransmitKeyID - 1;
+	}
+
+	erq->flags |= index + 1;
+
+	/* Copy the key to the user buffer */
+	erq->length = lp->DefaultKeys.key[index].len;
+
+	memcpy(key, lp->DefaultKeys.key[index].key, erq->length);
+
+out_unlock:
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_get_encode
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wireless_set_nickname()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *     Sets the nickname, or station name, of the wireless device.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+static int wireless_set_nickname(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *nickname)
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int ret = 0;
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wireless_set_nickname" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+#if 0 //;? Needed, was present in original code but not in 7.18 Linux 2.6 kernel version
+	if( !capable(CAP_NET_ADMIN )) {
+		ret = -EPERM;
+		DBG_LEAVE( DbgInfo );
+		return ret;
+	}
+#endif
+
+	/* Validate the new value */
+	if(data->length > HCF_MAX_NAME_LEN) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	memset( lp->StationName, 0, sizeof( lp->StationName ));
+
+	memcpy( lp->StationName, nickname, data->length );
+
+	/* Commit the adapter parameters */
+	wl_apply( lp );
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_set_nickname
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wireless_get_nickname()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *     Gets the nickname, or station name, of the wireless device.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+static int wireless_get_nickname(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *nickname)
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int         ret = 0;
+	int         status = -1;
+	wvName_t    *pName;
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wireless_get_nickname" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	/* Get the current station name */
+	lp->ltvRecord.len = 1 + ( sizeof( *pName ) / sizeof( hcf_16 ));
+	lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
+
+	status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+
+	if( status == HCF_SUCCESS ) {
+		pName = (wvName_t *)&( lp->ltvRecord.u.u32 );
+
+		/* Endian translate the length */
+		pName->length = CNV_LITTLE_TO_INT( pName->length );
+
+		if ( pName->length > IW_ESSID_MAX_SIZE ) {
+			ret = -EFAULT;
+		} else {
+			/* Copy the information into the user buffer */
+			data->length = pName->length;
+			memcpy(nickname, pName->name, pName->length);
+		}
+	} else {
+		ret = -EFAULT;
+	}
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE(DbgInfo);
+	return ret;
+} // wireless_get_nickname
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wireless_set_porttype()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *     Sets the port type of the wireless device.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+static int wireless_set_porttype(struct net_device *dev, struct iw_request_info *info, __u32 *mode, char *extra)
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int ret = 0;
+	hcf_16  portType;
+	hcf_16	createIBSS;
+	/*------------------------------------------------------------------------*/
+
+	DBG_FUNC( "wireless_set_porttype" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	/* Validate the new value */
+	switch( *mode ) {
+	case IW_MODE_ADHOC:
+
+		/* When user requests ad-hoc, set IBSS mode! */
+		portType         = 1;
+		createIBSS       = 1;
+
+		lp->DownloadFirmware = WVLAN_DRV_MODE_STA; //1;
+
+		break;
+
+
+	case IW_MODE_AUTO:
+	case IW_MODE_INFRA:
+
+		/* Both automatic and infrastructure set port to BSS/STA mode */
+		portType         = 1;
+		createIBSS       = 0;
+
+		lp->DownloadFirmware = WVLAN_DRV_MODE_STA; //1;
+
+		break;
+
+
+#if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
+
+	case IW_MODE_MASTER:
+
+		/* Set BSS/AP mode */
+		portType             = 1;
+
+		lp->CreateIBSS       = 0;
+		lp->DownloadFirmware = WVLAN_DRV_MODE_AP; //2;
+
+		break;
+
+#endif /* (HCF_TYPE) & HCF_TYPE_AP */
+
+
+	default:
+
+		portType   = 0;
+		createIBSS = 0;
+		ret = -EINVAL;
+	}
+
+	if( portType != 0 ) {
+		/* Only do something if there is a mode change */
+		if( ( lp->PortType != portType ) || (lp->CreateIBSS != createIBSS)) {
+			lp->PortType   = portType;
+			lp->CreateIBSS = createIBSS;
+
+			/* Commit the adapter parameters */
+			wl_go( lp );
+
+			/* Send an event that mode has been set */
+			wl_wext_event_mode( lp->dev );
+		}
+	}
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_set_porttype
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wireless_get_porttype()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *     Gets the port type of the wireless device.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+static int wireless_get_porttype(struct net_device *dev, struct iw_request_info *info, __u32 *mode, char *extra)
+
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int     ret = 0;
+	int     status = -1;
+	hcf_16  *pPortType;
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wireless_get_porttype" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	/* Get the current port type */
+	lp->ltvRecord.len = 1 + ( sizeof( *pPortType ) / sizeof( hcf_16 ));
+	lp->ltvRecord.typ = CFG_CNF_PORT_TYPE;
+
+	status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+
+	if( status == HCF_SUCCESS ) {
+		pPortType = (hcf_16 *)&( lp->ltvRecord.u.u32 );
+
+		*pPortType = CNV_LITTLE_TO_INT( *pPortType );
+
+		switch( *pPortType ) {
+		case 1:
+
+#if 0
+#if (HCF_TYPE) & HCF_TYPE_AP
+
+			if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
+				*mode = IW_MODE_MASTER;
+			} else {
+				*mode = IW_MODE_INFRA;
+			}
+
+#else
+
+			*mode = IW_MODE_INFRA;
+
+#endif  /* (HCF_TYPE) & HCF_TYPE_AP */
+#endif
+
+			if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
+				*mode =  IW_MODE_MASTER;
+			} else {
+				if( lp->CreateIBSS ) {
+					*mode = IW_MODE_ADHOC;
+				} else {
+					*mode = IW_MODE_INFRA;
+				}
+			}
+
+			break;
+
+
+		case 3:
+			*mode = IW_MODE_ADHOC;
+			break;
+
+		default:
+			ret = -EFAULT;
+			break;
+		}
+	} else {
+		ret = -EFAULT;
+	}
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_get_porttype
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wireless_set_power()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *     Sets the power management settings of the wireless device.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+static int wireless_set_power(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra)
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int ret = 0;
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wireless_set_power" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	DBG_PRINT( "THIS CORRUPTS PMEnabled ;?!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" );
+
+#if 0 //;? Needed, was present in original code but not in 7.18 Linux 2.6 kernel version
+	if( !capable( CAP_NET_ADMIN )) {
+		ret = -EPERM;
+
+		DBG_LEAVE( DbgInfo );
+		return ret;
+	}
+#endif
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	/* Set the power management state based on the 'disabled' value */
+	if( wrq->disabled ) {
+		lp->PMEnabled = 0;
+	} else {
+		lp->PMEnabled = 1;
+	}
+
+	/* Commit the adapter parameters */
+	wl_apply( lp );
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_set_power
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wireless_get_power()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *     Gets the power management settings of the wireless device.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+static int wireless_get_power(struct net_device *dev, struct iw_request_info *info, struct iw_param *rrq, char *extra)
+
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int ret = 0;
+	/*------------------------------------------------------------------------*/
+	DBG_FUNC( "wireless_get_power" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	DBG_PRINT( "THIS IS PROBABLY AN OVER-SIMPLIFICATION ;?!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" );
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	rrq->flags = 0;
+	rrq->value = 0;
+
+	if( lp->PMEnabled ) {
+		rrq->disabled = 0;
+	} else {
+		rrq->disabled = 1;
+	}
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_get_power
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wireless_get_tx_power()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *     Gets the transmit power of the wireless device's radio.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+static int wireless_get_tx_power(struct net_device *dev, struct iw_request_info *info, struct iw_param *rrq, char *extra)
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int ret = 0;
+	/*------------------------------------------------------------------------*/
+	DBG_FUNC( "wireless_get_tx_power" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+#ifdef USE_POWER_DBM
+	rrq->value = RADIO_TX_POWER_DBM;
+	rrq->flags = IW_TXPOW_DBM;
+#else
+	rrq->value = RADIO_TX_POWER_MWATT;
+	rrq->flags = IW_TXPOW_MWATT;
+#endif
+	rrq->fixed = 1;
+	rrq->disabled = 0;
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_get_tx_power
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wireless_set_rts_threshold()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *     Sets the RTS threshold for the wireless card.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+static int wireless_set_rts_threshold (struct net_device *dev, struct iw_request_info *info, struct iw_param *rts, char *extra)
+{
+	int ret = 0;
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int rthr = rts->value;
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wireless_set_rts_threshold" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	if(rts->fixed == 0) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+#if WIRELESS_EXT > 8
+	if( rts->disabled ) {
+		rthr = 2347;
+	}
+#endif /* WIRELESS_EXT > 8 */
+
+	if(( rthr < 256 ) || ( rthr > 2347 )) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	lp->RTSThreshold = rthr;
+
+	wl_apply( lp );
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_set_rts_threshold
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wireless_get_rts_threshold()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *     Gets the RTS threshold for the wireless card.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+static int wireless_get_rts_threshold (struct net_device *dev, struct iw_request_info *info, struct iw_param *rts, char *extra)
+{
+	int ret = 0;
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	/*------------------------------------------------------------------------*/
+
+	DBG_FUNC( "wireless_get_rts_threshold" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	rts->value = lp->RTSThreshold;
+
+#if WIRELESS_EXT > 8
+
+	rts->disabled = ( rts->value == 2347 );
+
+#endif /* WIRELESS_EXT > 8 */
+
+	rts->fixed = 1;
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_get_rts_threshold
+/*============================================================================*/
+
+
+
+
+
+/*******************************************************************************
+ *	wireless_set_rate()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Set the default data rate setting used by the wireless device.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+static int wireless_set_rate(struct net_device *dev, struct iw_request_info *info, struct iw_param *rrq, char *extra)
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int ret = 0;
+#ifdef WARP
+	int status = -1;
+	int index = 0;
+#endif  // WARP
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wireless_set_rate" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+#ifdef WARP
+
+	/* Determine if the card is operating in the 2.4 or 5.0 GHz band; check
+	   if Bit 9 is set in the current channel RID */
+	lp->ltvRecord.len = 2;
+	lp->ltvRecord.typ = CFG_CUR_CHANNEL;
+
+	status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+
+	if( status == HCF_SUCCESS ) {
+		index = ( CNV_LITTLE_TO_INT( lp->ltvRecord.u.u16[0] ) & 0x100 ) ? 1 : 0;
+
+		DBG_PRINT( "Index: %d\n", index );
+	} else {
+		DBG_ERROR( DbgInfo, "Could not determine radio frequency\n" );
+		DBG_LEAVE( DbgInfo );
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+	if( rrq->value > 0 &&
+		rrq->value <= 1 * MEGABIT ) {
+		lp->TxRateControl[index] = 0x0001;
+	}
+	else if( rrq->value > 1 * MEGABIT &&
+			rrq->value <= 2 * MEGABIT ) {
+		if( rrq->fixed == 1 ) {
+			lp->TxRateControl[index] = 0x0002;
+		} else {
+			lp->TxRateControl[index] = 0x0003;
+		}
+	}
+	else if( rrq->value > 2 * MEGABIT &&
+			rrq->value <= 5 * MEGABIT ) {
+		if( rrq->fixed == 1 ) {
+			lp->TxRateControl[index] = 0x0004;
+		} else {
+			lp->TxRateControl[index] = 0x0007;
+		}
+	}
+	else if( rrq->value > 5 * MEGABIT &&
+			rrq->value <= 6 * MEGABIT ) {
+		if( rrq->fixed == 1 ) {
+			lp->TxRateControl[index] = 0x0010;
+		} else {
+			lp->TxRateControl[index] = 0x0017;
+		}
+	}
+	else if( rrq->value > 6 * MEGABIT &&
+			rrq->value <= 9 * MEGABIT ) {
+		if( rrq->fixed == 1 ) {
+			lp->TxRateControl[index] = 0x0020;
+		} else {
+			lp->TxRateControl[index] = 0x0037;
+		}
+	}
+	else if( rrq->value > 9 * MEGABIT &&
+			rrq->value <= 11 * MEGABIT ) {
+		if( rrq->fixed == 1 ) {
+			lp->TxRateControl[index] = 0x0008;
+		} else {
+			lp->TxRateControl[index] = 0x003F;
+		}
+	}
+	else if( rrq->value > 11 * MEGABIT &&
+			rrq->value <= 12 * MEGABIT ) {
+		if( rrq->fixed == 1 ) {
+			lp->TxRateControl[index] = 0x0040;
+		} else {
+			lp->TxRateControl[index] = 0x007F;
+		}
+	}
+	else if( rrq->value > 12 * MEGABIT &&
+			rrq->value <= 18 * MEGABIT ) {
+		if( rrq->fixed == 1 ) {
+			lp->TxRateControl[index] = 0x0080;
+		} else {
+			lp->TxRateControl[index] = 0x00FF;
+		}
+	}
+	else if( rrq->value > 18 * MEGABIT &&
+			rrq->value <= 24 * MEGABIT ) {
+		if( rrq->fixed == 1 ) {
+			lp->TxRateControl[index] = 0x0100;
+		} else {
+			lp->TxRateControl[index] = 0x01FF;
+		}
+	}
+	else if( rrq->value > 24 * MEGABIT &&
+			rrq->value <= 36 * MEGABIT ) {
+		if( rrq->fixed == 1 ) {
+			lp->TxRateControl[index] = 0x0200;
+		} else {
+			lp->TxRateControl[index] = 0x03FF;
+		}
+	}
+	else if( rrq->value > 36 * MEGABIT &&
+			rrq->value <= 48 * MEGABIT ) {
+		if( rrq->fixed == 1 ) {
+			lp->TxRateControl[index] = 0x0400;
+		} else {
+			lp->TxRateControl[index] = 0x07FF;
+		}
+	}
+	else if( rrq->value > 48 * MEGABIT &&
+			rrq->value <= 54 * MEGABIT ) {
+		if( rrq->fixed == 1 ) {
+			lp->TxRateControl[index] = 0x0800;
+		} else {
+			lp->TxRateControl[index] = 0x0FFF;
+		}
+	}
+	else if( rrq->fixed == 0 ) {
+		/* In this case, the user has not specified a bitrate, only the "auto"
+		   moniker. So, set to all supported rates */
+		lp->TxRateControl[index] = PARM_MAX_TX_RATE;
+	} else {
+		rrq->value = 0;
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+
+#else
+
+	if( rrq->value > 0 &&
+			rrq->value <= 1 * MEGABIT ) {
+		lp->TxRateControl[0] = 1;
+	}
+	else if( rrq->value > 1 * MEGABIT &&
+			rrq->value <= 2 * MEGABIT ) {
+		if( rrq->fixed ) {
+			lp->TxRateControl[0] = 2;
+		} else {
+			lp->TxRateControl[0] = 6;
+		}
+	}
+	else if( rrq->value > 2 * MEGABIT &&
+			rrq->value <= 5 * MEGABIT ) {
+		if( rrq->fixed ) {
+			lp->TxRateControl[0] = 4;
+		} else {
+			lp->TxRateControl[0] = 7;
+		}
+	}
+	else if( rrq->value > 5 * MEGABIT &&
+			rrq->value <= 11 * MEGABIT ) {
+		if( rrq->fixed)  {
+			lp->TxRateControl[0] = 5;
+		} else {
+			lp->TxRateControl[0] = 3;
+		}
+	}
+	else if( rrq->fixed == 0 ) {
+		/* In this case, the user has not specified a bitrate, only the "auto"
+		   moniker. So, set the rate to 11Mb auto */
+		lp->TxRateControl[0] = 3;
+	} else {
+		rrq->value = 0;
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+#endif  // WARP
+
+
+	/* Commit the adapter parameters */
+	wl_apply( lp );
+
+out_unlock:
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_set_rate
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wireless_get_rate()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Get the default data rate setting used by the wireless device.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+static int wireless_get_rate(struct net_device *dev, struct iw_request_info *info, struct iw_param *rrq, char *extra)
+
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int     ret = 0;
+	int     status = -1;
+	hcf_16  txRate;
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wireless_get_rate" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	/* Get the current transmit rate from the adapter */
+	lp->ltvRecord.len = 1 + ( sizeof(txRate)/sizeof(hcf_16));
+	lp->ltvRecord.typ = CFG_CUR_TX_RATE;
+
+	status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+
+	if( status == HCF_SUCCESS ) {
+#ifdef WARP
+
+		txRate = CNV_LITTLE_TO_INT( lp->ltvRecord.u.u16[0] );
+
+		if( txRate & 0x0001 ) {
+			txRate = 1;
+		}
+		else if( txRate & 0x0002 ) {
+			txRate = 2;
+		}
+		else if( txRate & 0x0004 ) {
+			txRate = 5;
+		}
+		else if( txRate & 0x0008 ) {
+			txRate = 11;
+		}
+		else if( txRate & 0x00010 ) {
+			txRate = 6;
+		}
+		else if( txRate & 0x00020 ) {
+			txRate = 9;
+		}
+		else if( txRate & 0x00040 ) {
+			txRate = 12;
+		}
+		else if( txRate & 0x00080 ) {
+			txRate = 18;
+		}
+		else if( txRate & 0x00100 ) {
+			txRate = 24;
+		}
+		else if( txRate & 0x00200 ) {
+			txRate = 36;
+		}
+		else if( txRate & 0x00400 ) {
+			txRate = 48;
+		}
+		else if( txRate & 0x00800 ) {
+			txRate = 54;
+		}
+
+#else
+
+		txRate = (hcf_16)CNV_LITTLE_TO_LONG( lp->ltvRecord.u.u32[0] );
+
+#endif  // WARP
+
+		rrq->value = txRate * MEGABIT;
+	} else {
+		rrq->value = 0;
+		ret = -EFAULT;
+	}
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_get_rate
+/*============================================================================*/
+
+
+
+
+#if 0 //;? Not used anymore
+/*******************************************************************************
+ *	wireless_get_private_interface()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Returns the Linux Wireless Extensions' compatible private interface of
+ *  the driver.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+int wireless_get_private_interface( struct iwreq *wrq, struct wl_private *lp )
+{
+	int ret = 0;
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wireless_get_private_interface" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	if( wrq->u.data.pointer != NULL ) {
+		struct iw_priv_args priv[] =
+		{
+			{ SIOCSIWNETNAME, IW_PRIV_TYPE_CHAR | HCF_MAX_NAME_LEN, 0, "snetwork_name" },
+			{ SIOCGIWNETNAME, 0, IW_PRIV_TYPE_CHAR | HCF_MAX_NAME_LEN, "gnetwork_name" },
+			{ SIOCSIWSTANAME, IW_PRIV_TYPE_CHAR | HCF_MAX_NAME_LEN, 0, "sstation_name" },
+			{ SIOCGIWSTANAME, 0, IW_PRIV_TYPE_CHAR | HCF_MAX_NAME_LEN, "gstation_name" },
+			{ SIOCSIWPORTTYPE, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "sport_type" },
+			{ SIOCGIWPORTTYPE, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "gport_type" },
+		};
+
+		/* Verify the user buffer */
+		ret = verify_area( VERIFY_WRITE, wrq->u.data.pointer, sizeof( priv ));
+
+		if( ret != 0 ) {
+			DBG_LEAVE( DbgInfo );
+			return ret;
+		}
+
+		/* Copy the data into the user's buffer */
+		wrq->u.data.length = NELEM( priv );
+		copy_to_user( wrq->u.data.pointer, &priv, sizeof( priv ));
+	}
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_get_private_interface
+/*============================================================================*/
+#endif
+
+
+
+#if WIRELESS_EXT > 13
+
+/*******************************************************************************
+ *	wireless_set_scan()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Instructs the driver to initiate a network scan.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+static int wireless_set_scan(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra)
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int                 ret = 0;
+	int                 status = -1;
+	int		    retries = 0;
+	/*------------------------------------------------------------------------*/
+
+	//;? Note: shows results as trace, retruns always 0 unless BUSY
+
+	DBG_FUNC( "wireless_set_scan" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	/*
+         * This looks like a nice place to test if the HCF is still
+         * communicating with the card. It seems that sometimes BAP_1
+         * gets corrupted. By looking at the comments in HCF the
+         * cause is still a mistery. Okay, the communication to the
+         * card is dead, reset the card to revive.
+         */
+	if((lp->hcfCtx.IFB_CardStat & CARD_STAT_DEFUNCT) != 0)
+	{
+		DBG_TRACE( DbgInfo, "CARD is in DEFUNCT mode, reset it to bring it back to life\n" );
+		wl_reset( dev );
+	}
+
+retry:
+	/* Set the completion state to FALSE */
+	lp->probe_results.scan_complete = FALSE;
+
+
+	/* Channels to scan */
+#ifdef WARP
+	lp->ltvRecord.len       = 5;
+	lp->ltvRecord.typ       = CFG_SCAN_CHANNEL;
+	lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 0x3FFF );  // 2.4 GHz Band
+	lp->ltvRecord.u.u16[1]  = CNV_INT_TO_LITTLE( 0xFFFF );  // 5.0 GHz Band
+	lp->ltvRecord.u.u16[2]  = CNV_INT_TO_LITTLE( 0xFFFF );  //      ..
+	lp->ltvRecord.u.u16[3]  = CNV_INT_TO_LITTLE( 0x0007 );  //      ..
+#else
+	lp->ltvRecord.len       = 2;
+	lp->ltvRecord.typ       = CFG_SCAN_CHANNEL;
+	lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 0x7FFF );
+#endif  // WARP
+
+	status = hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+
+	DBG_TRACE( DbgInfo, "CFG_SCAN_CHANNEL result      : 0x%x\n", status );
+
+	// Holding the lock too long, make a gap to allow other processes
+	wl_unlock(lp, &flags);
+	wl_lock( lp, &flags );
+
+	if( status != HCF_SUCCESS ) {
+		//Recovery
+		retries++;
+		if(retries <= 10) {
+			DBG_TRACE( DbgInfo, "Reset card to recover, attempt: %d\n", retries );
+			wl_reset( dev );
+
+			// Holding the lock too long, make a gap to allow other processes
+			wl_unlock(lp, &flags);
+			wl_lock( lp, &flags );
+
+			goto retry;
+		}
+	}
+
+	/* Set the SCAN_SSID to "ANY". Using this RID for scan prevents the need to
+	   disassociate from the network we are currently on */
+	lp->ltvRecord.len       = 18;
+	lp->ltvRecord.typ       = CFG_SCAN_SSID;
+	lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 0 );
+	lp->ltvRecord.u.u16[1]  = CNV_INT_TO_LITTLE( 0 );
+
+	status = hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+
+	// Holding the lock too long, make a gap to allow other processes
+	wl_unlock(lp, &flags);
+	wl_lock( lp, &flags );
+
+	DBG_TRACE( DbgInfo, "CFG_SCAN_SSID to 'any' status: 0x%x\n", status );
+
+	/* Initiate the scan */
+	/* NOTE: Using HCF_ACT_SCAN has been removed, as using HCF_ACT_ACS_SCAN to
+	   retrieve probe responses must always be used to support WPA */
+	status = hcf_action( &( lp->hcfCtx ), HCF_ACT_ACS_SCAN );
+
+	if( status == HCF_SUCCESS ) {
+		DBG_TRACE( DbgInfo, "SUCCESSFULLY INITIATED SCAN...\n" );
+	} else {
+		DBG_TRACE( DbgInfo, "INITIATE SCAN FAILED...\n" );
+	}
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE(DbgInfo);
+	return ret;
+} // wireless_set_scan
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wireless_get_scan()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Instructs the driver to gather and return the results of a network scan.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+static int wireless_get_scan(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra)
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int                 ret = 0;
+	int                 count;
+	char                *buf;
+	char                *buf_end;
+	struct iw_event     iwe;
+	PROBE_RESP          *probe_resp;
+	hcf_8               msg[512];
+	hcf_8               *wpa_ie;
+	hcf_16              wpa_ie_len;
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wireless_get_scan" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	/* If the scan is not done, tell the calling process to try again later */
+	if( !lp->probe_results.scan_complete ) {
+		ret = -EAGAIN;
+		goto out_unlock;
+	}
+
+	DBG_TRACE( DbgInfo, "SCAN COMPLETE, Num of APs: %d\n",
+			   lp->probe_results.num_aps );
+
+	buf     = extra;
+	buf_end = extra + IW_SCAN_MAX_DATA;
+
+	for( count = 0; count < lp->probe_results.num_aps; count++ ) {
+		/* Reference the probe response from the table */
+		probe_resp = (PROBE_RESP *)&lp->probe_results.ProbeTable[count];
+
+
+		/* First entry MUST be the MAC address */
+		memset( &iwe, 0, sizeof( iwe ));
+
+		iwe.cmd                 = SIOCGIWAP;
+		iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+		memcpy( iwe.u.ap_addr.sa_data, probe_resp->BSSID, ETH_ALEN);
+		iwe.len                 = IW_EV_ADDR_LEN;
+
+		buf = IWE_STREAM_ADD_EVENT(info, buf, buf_end, &iwe, IW_EV_ADDR_LEN);
+
+
+		/* Use the mode to indicate if it's a station or AP */
+		/* Won't always be an AP if in IBSS mode */
+		memset( &iwe, 0, sizeof( iwe ));
+
+		iwe.cmd = SIOCGIWMODE;
+
+		if( probe_resp->capability & CAPABILITY_IBSS ) {
+			iwe.u.mode = IW_MODE_INFRA;
+		} else {
+			iwe.u.mode = IW_MODE_MASTER;
+		}
+
+		iwe.len = IW_EV_UINT_LEN;
+
+		buf = IWE_STREAM_ADD_EVENT(info, buf, buf_end, &iwe, IW_EV_UINT_LEN);
+
+
+		/* Any quality information */
+		memset(&iwe, 0, sizeof(iwe));
+
+		iwe.cmd             = IWEVQUAL;
+		iwe.u.qual.level    = dbm(probe_resp->signal);
+		iwe.u.qual.noise    = dbm(probe_resp->silence);
+		iwe.u.qual.qual     = iwe.u.qual.level - iwe.u.qual.noise;
+		iwe.u.qual.updated  = lp->probe_results.scan_complete | IW_QUAL_DBM;
+		iwe.len             = IW_EV_QUAL_LEN;
+
+		buf = IWE_STREAM_ADD_EVENT(info, buf, buf_end, &iwe, IW_EV_QUAL_LEN);
+
+
+		/* ESSID information */
+		if( probe_resp->rawData[1] > 0 ) {
+			memset( &iwe, 0, sizeof( iwe ));
+
+			iwe.cmd = SIOCGIWESSID;
+			iwe.u.data.length = probe_resp->rawData[1];
+			iwe.u.data.flags = 1;
+
+			buf = IWE_STREAM_ADD_POINT(info, buf, buf_end, &iwe, &probe_resp->rawData[2]);
+		}
+
+
+		/* Encryption Information */
+		memset( &iwe, 0, sizeof( iwe ));
+
+		iwe.cmd             = SIOCGIWENCODE;
+		iwe.u.data.length   = 0;
+
+		/* Check the capabilities field of the Probe Response to see if
+		   'privacy' is supported on the AP in question */
+		if( probe_resp->capability & CAPABILITY_PRIVACY ) {
+			iwe.u.data.flags |= IW_ENCODE_ENABLED;
+		} else {
+			iwe.u.data.flags |= IW_ENCODE_DISABLED;
+		}
+
+		buf = IWE_STREAM_ADD_POINT(info, buf, buf_end, &iwe, NULL);
+
+
+		/* Frequency Info */
+		memset( &iwe, 0, sizeof( iwe ));
+
+		iwe.cmd = SIOCGIWFREQ;
+		iwe.len = IW_EV_FREQ_LEN;
+		iwe.u.freq.m = wl_parse_ds_ie( probe_resp );
+		iwe.u.freq.e = 0;
+
+		buf = IWE_STREAM_ADD_EVENT(info, buf, buf_end, &iwe, IW_EV_FREQ_LEN);
+
+
+#if WIRELESS_EXT > 14
+		/* Custom info (Beacon Interval) */
+		memset( &iwe, 0, sizeof( iwe ));
+		memset( msg, 0, sizeof( msg ));
+
+		iwe.cmd = IWEVCUSTOM;
+		sprintf( msg, "beacon_interval=%d", probe_resp->beaconInterval );
+		iwe.u.data.length = strlen( msg );
+
+		buf = IWE_STREAM_ADD_POINT(info, buf, buf_end, &iwe, msg);
+
+
+		/* Custom info (WPA-IE) */
+		wpa_ie = NULL;
+		wpa_ie_len = 0;
+
+		wpa_ie = wl_parse_wpa_ie( probe_resp, &wpa_ie_len );
+		if( wpa_ie != NULL ) {
+			memset( &iwe, 0, sizeof( iwe ));
+			memset( msg, 0, sizeof( msg ));
+
+			iwe.cmd = IWEVCUSTOM;
+			sprintf( msg, "wpa_ie=%s", wl_print_wpa_ie( wpa_ie, wpa_ie_len ));
+			iwe.u.data.length = strlen( msg );
+
+			buf = IWE_STREAM_ADD_POINT(info, buf, buf_end, &iwe, msg);
+		}
+
+		/* Add other custom info in formatted string format as needed... */
+#endif
+	}
+
+	data->length = buf - extra;
+
+out_unlock:
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_get_scan
+/*============================================================================*/
+
+#endif  // WIRELESS_EXT > 13
+
+
+#if WIRELESS_EXT > 17
+
+static int wireless_set_auth(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *data, char *extra)
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int			      ret;
+	int			      iwa_idx = data->flags & IW_AUTH_INDEX;
+	int			      iwa_val = data->value;
+
+	DBG_FUNC( "wireless_set_auth" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	switch (iwa_idx) {
+		case IW_AUTH_WPA_VERSION:
+			DBG_TRACE( DbgInfo, "IW_AUTH_WPA_VERSION\n");
+			/* We do support WPA only; how should DISABLED be treated? */
+			if (iwa_val == IW_AUTH_WPA_VERSION_WPA)
+				ret = 0;
+			else
+				ret = -EINVAL;
+			break;
+
+		case IW_AUTH_WPA_ENABLED:
+			DBG_TRACE( DbgInfo, "IW_AUTH_WPA_ENABLED: val = %d\n", iwa_val);
+			if (iwa_val)
+				lp->EnableEncryption = 2;
+			else
+				lp->EnableEncryption = 0;
+			ret = 0;
+			break;
+
+		case IW_AUTH_TKIP_COUNTERMEASURES:
+			DBG_TRACE( DbgInfo, "IW_AUTH_TKIP_COUNTERMEASURES\n");
+			lp->driverEnable = !iwa_val;
+			if(lp->driverEnable)
+				hcf_cntl(&(lp->hcfCtx), HCF_CNTL_ENABLE | HCF_PORT_0);
+			else
+				hcf_cntl(&(lp->hcfCtx), HCF_CNTL_DISABLE | HCF_PORT_0);
+			ret = 0;
+			break;
+
+		case IW_AUTH_DROP_UNENCRYPTED:
+			DBG_TRACE( DbgInfo, "IW_AUTH_DROP_UNENCRYPTED\n");
+			/* We do not actually do anything here, just to silence
+			 * wpa_supplicant */
+			ret = 0;
+			break;
+
+		case IW_AUTH_CIPHER_PAIRWISE:
+			DBG_TRACE( DbgInfo, "IW_AUTH_CIPHER_PAIRWISE\n");
+			/* not implemented, return an error */
+			ret = -EINVAL;
+			break;
+
+		case IW_AUTH_CIPHER_GROUP:
+			DBG_TRACE( DbgInfo, "IW_AUTH_CIPHER_GROUP\n");
+			/* not implemented, return an error */
+			ret = -EINVAL;
+			break;
+
+		case IW_AUTH_KEY_MGMT:
+			DBG_TRACE( DbgInfo, "IW_AUTH_KEY_MGMT\n");
+			/* not implemented, return an error */
+			ret = -EINVAL;
+			break;
+
+		case IW_AUTH_80211_AUTH_ALG:
+			DBG_TRACE( DbgInfo, "IW_AUTH_80211_AUTH_ALG\n");
+			/* not implemented, return an error */
+			ret = -EINVAL;
+			break;
+
+		case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+			DBG_TRACE( DbgInfo, "IW_AUTH_RX_UNENCRYPTED_EAPOL\n");
+			/* not implemented, return an error */
+			ret = -EINVAL;
+			break;
+
+		case IW_AUTH_ROAMING_CONTROL:
+			DBG_TRACE( DbgInfo, "IW_AUTH_ROAMING_CONTROL\n");
+			/* not implemented, return an error */
+			ret = -EINVAL;
+			break;
+
+		case IW_AUTH_PRIVACY_INVOKED:
+			DBG_TRACE( DbgInfo, "IW_AUTH_PRIVACY_INVOKED\n");
+			/* not implemented, return an error */
+			ret = -EINVAL;
+			break;
+
+		default:
+			DBG_TRACE( DbgInfo, "IW_AUTH_?? (%d) unknown\n", iwa_idx);
+			/* return an error */
+			ret = -EINVAL;
+			break;
+	}
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_set_auth
+/*============================================================================*/
+
+
+
+static int hermes_set_key(ltv_t *ltv, int alg, int key_idx, u8 *addr,
+			  int set_tx, u8 *seq, u8 *key, size_t key_len)
+{
+	int ret = -EINVAL;
+	// int   count = 0;
+	int   buf_idx = 0;
+	hcf_8 tsc[IW_ENCODE_SEQ_MAX_SIZE] =
+		{ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00 };
+
+	DBG_FUNC( "hermes_set_key" );
+	DBG_ENTER( DbgInfo );
+
+	/*
+         * Check the key index here; if 0, load as Pairwise Key, otherwise,
+         * load as a group key. Note that for the Hermes, the RIDs for
+         * group/pariwise keys are different from each other and different
+         * than the default WEP keys as well.
+         */
+	switch (alg)
+	{
+	case IW_ENCODE_ALG_TKIP:
+		DBG_TRACE( DbgInfo, "IW_ENCODE_ALG_TKIP: key(%d)\n", key_idx);
+#if 0
+		/*
+                 * Make sure that there is no data queued up in the firmware
+                 * before setting the TKIP keys. If this check is not
+                 * performed, some data may be sent out with incorrect MIC
+                 * and cause synchronizarion errors with the AP
+                 */
+		/* Check every 1ms for 100ms */
+		for( count = 0; count < 100; count++ )
+		{
+			usleep( 1000 );
+
+			ltv.len = 2;
+			ltv.typ = 0xFD91;  // This RID not defined in HCF yet!!!
+			ltv.u.u16[0] = 0;
+
+			wl_get_info( sock, &ltv, ifname );
+
+			if( ltv.u.u16[0] == 0 )
+			{
+				break;
+			}
+		}
+
+		if( count == 100 )
+		{
+			wpa_printf( MSG_DEBUG, "Timed out waiting for TxQ!" );
+		}
+#endif
+
+		switch (key_idx) {
+		case 0:
+			ltv->len = 28;
+			ltv->typ = CFG_ADD_TKIP_MAPPED_KEY;
+
+			/* Load the BSSID */
+			memcpy(&ltv->u.u8[buf_idx], addr, ETH_ALEN);
+			buf_idx += ETH_ALEN;
+
+			/* Load the TKIP key */
+			memcpy(&ltv->u.u8[buf_idx], &key[0], 16);
+			buf_idx += 16;
+
+			/* Load the TSC */
+			memcpy(&ltv->u.u8[buf_idx], tsc, IW_ENCODE_SEQ_MAX_SIZE);
+			buf_idx += IW_ENCODE_SEQ_MAX_SIZE;
+
+			/* Load the RSC */
+			memcpy(&ltv->u.u8[buf_idx], seq, IW_ENCODE_SEQ_MAX_SIZE);
+			buf_idx += IW_ENCODE_SEQ_MAX_SIZE;
+
+			/* Load the TxMIC key */
+			memcpy(&ltv->u.u8[buf_idx], &key[16], 8);
+			buf_idx += 8;
+
+			/* Load the RxMIC key */
+			memcpy(&ltv->u.u8[buf_idx], &key[24], 8);
+
+			ret = 0;
+			break;
+		case 1:
+		case 2:
+		case 3:
+			ltv->len = 26;
+			ltv->typ = CFG_ADD_TKIP_DEFAULT_KEY;
+
+			/* Load the key Index */
+			ltv->u.u16[buf_idx] = key_idx;
+			/* If this is a Tx Key, set bit 8000 */
+			if(set_tx)
+				ltv->u.u16[buf_idx] |= 0x8000;
+			buf_idx += 2;
+
+			/* Load the RSC */
+			memcpy(&ltv->u.u8[buf_idx], seq, IW_ENCODE_SEQ_MAX_SIZE);
+			buf_idx += IW_ENCODE_SEQ_MAX_SIZE;
+
+			/* Load the TKIP, TxMIC, and RxMIC keys in one shot, because in
+			   CFG_ADD_TKIP_DEFAULT_KEY they are back-to-back */
+			memcpy(&ltv->u.u8[buf_idx], key, key_len);
+			buf_idx += key_len;
+
+			/* Load the TSC */
+			memcpy(&ltv->u.u8[buf_idx], tsc, IW_ENCODE_SEQ_MAX_SIZE);
+
+			ltv->u.u16[0] = CNV_INT_TO_LITTLE(ltv->u.u16[0]);
+
+			ret = 0;
+			break;
+		default:
+			break;
+		}
+
+		break;
+
+	case IW_ENCODE_ALG_WEP:
+		DBG_TRACE( DbgInfo, "IW_ENCODE_ALG_WEP: key(%d)\n", key_idx);
+		break;
+
+	case IW_ENCODE_ALG_CCMP:
+		DBG_TRACE( DbgInfo, "IW_ENCODE_ALG_CCMP: key(%d)\n", key_idx);
+		break;
+
+	case IW_ENCODE_ALG_NONE:
+		DBG_TRACE( DbgInfo, "IW_ENCODE_ALG_NONE: key(%d)\n", key_idx);
+		switch (key_idx) {
+		case 0:
+			if (memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0) {
+			//if (addr != NULL) {
+				ltv->len = 7;
+				ltv->typ = CFG_REMOVE_TKIP_MAPPED_KEY;
+				memcpy(&ltv->u.u8[0], addr, ETH_ALEN);
+				ret = 0;
+			}
+			break;
+		case 1:
+		case 2:
+		case 3:
+			/* Clear the Group TKIP keys by index */
+			ltv->len = 2;
+			ltv->typ = CFG_REMOVE_TKIP_DEFAULT_KEY;
+			ltv->u.u16[0] = key_idx;
+
+			ret = 0;
+			break;
+		default:
+			break;
+		}
+		break;
+	default:
+		DBG_TRACE( DbgInfo, "IW_ENCODE_??: key(%d)\n", key_idx);
+		break;
+	}
+
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // hermes_set_key
+/*============================================================================*/
+
+
+
+static int wireless_set_encodeext (struct net_device *dev,
+					struct iw_request_info *info,
+					struct iw_point *erq, char *keybuf)
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int			      ret;
+	int key_idx = (erq->flags&IW_ENCODE_INDEX) - 1;
+	ltv_t ltv;
+	struct iw_encode_ext *ext = (struct iw_encode_ext *)keybuf;
+
+	DBG_FUNC( "wireless_set_encodeext" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	if (sizeof(ext->rx_seq) != 8) {
+		DBG_TRACE(DbgInfo, "rz_seq size mismatch\n");
+		DBG_LEAVE(DbgInfo);
+		return -EINVAL;
+	}
+
+	/* Handle WEP keys via the old set encode procedure */
+	if(ext->alg == IW_ENCODE_ALG_WEP) {
+		struct iw_point  wep_erq;
+		char            *wep_keybuf;
+
+		/* Build request structure */
+		wep_erq.flags  = erq->flags;   // take over flags with key index
+		wep_erq.length = ext->key_len; // take length from extended key info
+		wep_keybuf     = ext->key;     // pointer to the key text
+
+		/* Call wireless_set_encode tot handle the WEP key */
+		ret = wireless_set_encode(dev, info, &wep_erq, wep_keybuf);
+		goto out;
+	}
+
+	/* Proceed for extended encode functions for WAP and NONE */
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	memset(&ltv, 0, sizeof(ltv));
+	ret = hermes_set_key(&ltv, ext->alg, key_idx, ext->addr.sa_data,
+				ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
+				ext->rx_seq, ext->key, ext->key_len);
+
+	if (ret != 0) {
+		DBG_TRACE( DbgInfo, "hermes_set_key returned != 0, key not set\n");
+		goto out_unlock;
+	}
+
+	/* Put the key in HCF */
+	ret = hcf_put_info(&(lp->hcfCtx), (LTVP)&ltv);
+
+out_unlock:
+	if(ret == HCF_SUCCESS) {
+		DBG_TRACE( DbgInfo, "Put key info succes\n");
+	} else {
+		DBG_TRACE( DbgInfo, "Put key info failed, key not set\n");
+	}
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+} // wireless_set_encodeext
+/*============================================================================*/
+
+
+
+static int wireless_get_genie(struct net_device *dev,
+					   struct iw_request_info *info,
+					   struct iw_point *data, char *extra)
+
+{
+	struct wl_private *lp = wl_priv(dev);
+	unsigned long flags;
+	int   ret = 0;
+	ltv_t ltv;
+
+	DBG_FUNC( "wireless_get_genie" );
+	DBG_ENTER( DbgInfo );
+
+	if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+	memset(&ltv, 0, sizeof(ltv));
+	ltv.len = 2;
+	ltv.typ = CFG_SET_WPA_AUTH_KEY_MGMT_SUITE;
+	lp->AuthKeyMgmtSuite = ltv.u.u16[0] = 4;
+	ltv.u.u16[0]  = CNV_INT_TO_LITTLE(ltv.u.u16[0]);
+
+	ret = hcf_put_info(&(lp->hcfCtx), (LTVP)&ltv);
+
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+out:
+	DBG_LEAVE( DbgInfo );
+	return ret;
+}
+/*============================================================================*/
+
+
+#endif // WIRELESS_EXT > 17
+
+/*******************************************************************************
+ *	wl_wireless_stats()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Return the current device wireless statistics.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+struct iw_statistics * wl_wireless_stats( struct net_device *dev )
+{
+	struct iw_statistics    *pStats;
+	struct wl_private       *lp = wl_priv(dev);
+	/*------------------------------------------------------------------------*/
+
+
+	DBG_FUNC( "wl_wireless_stats" );
+	DBG_ENTER(DbgInfo);
+	DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
+
+	pStats = NULL;
+
+	/* Initialize the statistics */
+	pStats			= &( lp->wstats );
+	pStats->qual.updated    = 0x00;
+
+	if( !( lp->flags & WVLAN2_UIL_BUSY ))
+	{
+		CFG_COMMS_QUALITY_STRCT *pQual;
+		CFG_HERMES_TALLIES_STRCT tallies;
+		int                         status;
+
+		/* Update driver status */
+		pStats->status = 0;
+
+		/* Get the current link quality information */
+		lp->ltvRecord.len = 1 + ( sizeof( *pQual ) / sizeof( hcf_16 ));
+		lp->ltvRecord.typ = CFG_COMMS_QUALITY;
+		status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+
+		if( status == HCF_SUCCESS ) {
+			pQual = (CFG_COMMS_QUALITY_STRCT *)&( lp->ltvRecord );
+
+#ifdef USE_DBM
+			pStats->qual.qual  = (u_char) CNV_LITTLE_TO_INT( pQual->coms_qual );
+			pStats->qual.level = (u_char) dbm( CNV_LITTLE_TO_INT( pQual->signal_lvl ));
+			pStats->qual.noise = (u_char) dbm( CNV_LITTLE_TO_INT( pQual->noise_lvl ));
+
+			pStats->qual.updated |= (IW_QUAL_QUAL_UPDATED  |
+                                                 IW_QUAL_LEVEL_UPDATED |
+                                                 IW_QUAL_NOISE_UPDATED |
+                                                 IW_QUAL_DBM);
+#else
+			pStats->qual.qual = percent( CNV_LITTLE_TO_INT( pQual->coms_qual ),
+						     HCF_MIN_COMM_QUALITY,
+						     HCF_MAX_COMM_QUALITY );
+
+			pStats->qual.level = percent( CNV_LITTLE_TO_INT( pQual->signal_lvl ),
+						      HCF_MIN_SIGNAL_LEVEL,
+						      HCF_MAX_SIGNAL_LEVEL );
+
+			pStats->qual.noise = percent( CNV_LITTLE_TO_INT( pQual->noise_lvl ),
+						      HCF_MIN_NOISE_LEVEL,
+						      HCF_MAX_NOISE_LEVEL );
+
+			pStats->qual.updated |= (IW_QUAL_QUAL_UPDATED  |
+                                                 IW_QUAL_LEVEL_UPDATED |
+                                                 IW_QUAL_NOISE_UPDATED);
+#endif /* USE_DBM */
+		} else {
+			memset( &( pStats->qual ), 0, sizeof( pStats->qual ));
+		}
+
+		/* Get the current tallies from the adapter */
+                /* Only possible when the device is open */
+		if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
+			if( wl_get_tallies( lp, &tallies ) == 0 ) {
+				/* No endian translation is needed here, as CFG_TALLIES is an
+				   MSF RID; all processing is done on the host, not the card! */
+				pStats->discard.nwid = 0L;
+				pStats->discard.code = tallies.RxWEPUndecryptable;
+				pStats->discard.misc = tallies.TxDiscards +
+						       tallies.RxFCSErrors +
+						       //tallies.RxDiscardsNoBuffer +
+						       tallies.TxDiscardsWrongSA;
+				//;? Extra taken over from Linux driver based on 7.18 version
+				pStats->discard.retries = tallies.TxRetryLimitExceeded;
+				pStats->discard.fragment = tallies.RxMsgInBadMsgFragments;
+			} else {
+				memset( &( pStats->discard ), 0, sizeof( pStats->discard ));
+			}
+		} else {
+			memset( &( pStats->discard ), 0, sizeof( pStats->discard ));
+		}
+	}
+
+	DBG_LEAVE( DbgInfo );
+	return pStats;
+} // wl_wireless_stats
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wl_get_wireless_stats()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Return the current device wireless statistics. This function calls
+ *      wl_wireless_stats, but acquires spinlocks first as it can be called
+ *      directly by the network layer.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+struct iw_statistics * wl_get_wireless_stats( struct net_device *dev )
+{
+	unsigned long           flags;
+	struct wl_private       *lp = wl_priv(dev);
+	struct iw_statistics    *pStats = NULL;
+	/*------------------------------------------------------------------------*/
+
+	DBG_FUNC( "wl_get_wireless_stats" );
+	DBG_ENTER(DbgInfo);
+
+	wl_lock( lp, &flags );
+
+    	wl_act_int_off( lp );
+
+#ifdef USE_RTS
+	if( lp->useRTS == 1 ) {
+		DBG_TRACE( DbgInfo, "Skipping wireless stats, in RTS mode\n" );
+	} else
+#endif
+	{
+		pStats = wl_wireless_stats( dev );
+	}
+    	wl_act_int_on( lp );
+
+	wl_unlock(lp, &flags);
+
+	DBG_LEAVE( DbgInfo );
+	return pStats;
+} // wl_get_wireless_stats
+
+
+/*******************************************************************************
+ *	wl_spy_gather()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      Gather wireless spy statistics.
+ *
+ *  PARAMETERS:
+ *
+ *      wrq - the wireless request buffer
+ *      lp  - the device's private adapter structure
+ *
+ *  RETURNS:
+ *
+ *      0 on success
+ *      errno value otherwise
+ *
+ ******************************************************************************/
+inline void wl_spy_gather( struct net_device *dev, u_char *mac )
+{
+	struct iw_quality wstats;
+	int                     status;
+	u_char                  stats[2];
+	DESC_STRCT              desc[1];
+	struct wl_private   *lp = wl_priv(dev);
+	/*------------------------------------------------------------------------*/
+
+	/* shortcut */
+	if (!lp->spy_data.spy_number) {
+		return;
+	}
+
+	/* Gather wireless spy statistics: for each packet, compare the source
+	   address with out list, and if match, get the stats. */
+	memset( stats, 0, sizeof(stats));
+	memset( desc, 0, sizeof(DESC_STRCT));
+
+	desc[0].buf_addr	= stats;
+	desc[0].BUF_SIZE	= sizeof(stats);
+	desc[0].next_desc_addr  = 0;		// terminate list
+
+	status = hcf_rcv_msg( &( lp->hcfCtx ), &desc[0], 0 );
+
+	if( status == HCF_SUCCESS ) {
+		wstats.level = (u_char) dbm(stats[1]);
+		wstats.noise = (u_char) dbm(stats[0]);
+		wstats.qual  = wstats.level > wstats.noise ? wstats.level - wstats.noise : 0;
+
+		wstats.updated = (IW_QUAL_QUAL_UPDATED  |
+				  IW_QUAL_LEVEL_UPDATED |
+				  IW_QUAL_NOISE_UPDATED |
+				  IW_QUAL_DBM);
+
+		wireless_spy_update( dev, mac, &wstats );
+	}
+} // wl_spy_gather
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wl_wext_event_freq()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function is used to send an event that the channel/freq
+ *      configuration for a specific device has changed.
+ *
+ *
+ *  PARAMETERS:
+ *
+ *      dev - the network device for which this event is to be issued
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_wext_event_freq( struct net_device *dev )
+{
+#if WIRELESS_EXT > 13
+	union iwreq_data wrqu;
+	struct wl_private *lp = wl_priv(dev);
+	/*------------------------------------------------------------------------*/
+
+
+	memset( &wrqu, 0, sizeof( wrqu ));
+
+	wrqu.freq.m = lp->Channel;
+	wrqu.freq.e = 0;
+
+	wireless_send_event( dev, SIOCSIWFREQ, &wrqu, NULL );
+#endif /* WIRELESS_EXT > 13 */
+
+	return;
+} // wl_wext_event_freq
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wl_wext_event_mode()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function is used to send an event that the mode of operation
+ *      for a specific device has changed.
+ *
+ *
+ *  PARAMETERS:
+ *
+ *      dev - the network device for which this event is to be issued
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_wext_event_mode( struct net_device *dev )
+{
+#if WIRELESS_EXT > 13
+	union iwreq_data wrqu;
+	struct wl_private *lp = wl_priv(dev);
+	/*------------------------------------------------------------------------*/
+
+
+	memset( &wrqu, 0, sizeof( wrqu ));
+
+	if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA  ) {
+		wrqu.mode = IW_MODE_INFRA;
+	} else {
+		wrqu.mode = IW_MODE_MASTER;
+	}
+
+	wireless_send_event( dev, SIOCSIWMODE, &wrqu, NULL );
+#endif /* WIRELESS_EXT > 13 */
+
+	return;
+} // wl_wext_event_mode
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wl_wext_event_essid()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function is used to send an event that the ESSID configuration for
+ *      a specific device has changed.
+ *
+ *
+ *  PARAMETERS:
+ *
+ *      dev - the network device for which this event is to be issued
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_wext_event_essid( struct net_device *dev )
+{
+#if WIRELESS_EXT > 13
+	union iwreq_data wrqu;
+	struct wl_private *lp = wl_priv(dev);
+	/*------------------------------------------------------------------------*/
+
+
+	memset( &wrqu, 0, sizeof( wrqu ));
+
+	/* Fill out the buffer. Note that the buffer doesn't actually contain the
+	   ESSID, but a pointer to the contents. In addition, the 'extra' field of
+	   the call to wireless_send_event() must also point to where the ESSID
+	   lives */
+	wrqu.essid.length  = strlen( lp->NetworkName );
+	wrqu.essid.pointer = (caddr_t)lp->NetworkName;
+	wrqu.essid.flags   = 1;
+
+	wireless_send_event( dev, SIOCSIWESSID, &wrqu, lp->NetworkName );
+#endif /* WIRELESS_EXT > 13 */
+
+	return;
+} // wl_wext_event_essid
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wl_wext_event_encode()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function is used to send an event that the encryption configuration
+ *      for a specific device has changed.
+ *
+ *
+ *  PARAMETERS:
+ *
+ *      dev - the network device for which this event is to be issued
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_wext_event_encode( struct net_device *dev )
+{
+#if WIRELESS_EXT > 13
+	union iwreq_data wrqu;
+	struct wl_private *lp = wl_priv(dev);
+	int index = 0;
+	/*------------------------------------------------------------------------*/
+
+
+	memset( &wrqu, 0, sizeof( wrqu ));
+
+	if( lp->EnableEncryption == 0 ) {
+		wrqu.encoding.flags = IW_ENCODE_DISABLED;
+	} else {
+		wrqu.encoding.flags |= lp->TransmitKeyID;
+
+		index = lp->TransmitKeyID - 1;
+
+		/* Only set IW_ENCODE_RESTRICTED/OPEN flag using lp->ExcludeUnencrypted
+		   if we're in AP mode */
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
+		//;?should we restore this to allow smaller memory footprint
+
+		if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
+			if( lp->ExcludeUnencrypted ) {
+				wrqu.encoding.flags |= IW_ENCODE_RESTRICTED;
+			} else {
+				wrqu.encoding.flags |= IW_ENCODE_OPEN;
+			}
+		}
+
+#endif  // HCF_TYPE_AP
+
+		/* Only provide the key if permissions allow */
+		if( capable( CAP_NET_ADMIN )) {
+			wrqu.encoding.pointer = (caddr_t)lp->DefaultKeys.key[index].key;
+			wrqu.encoding.length  = lp->DefaultKeys.key[index].len;
+		} else {
+			wrqu.encoding.flags |= IW_ENCODE_NOKEY;
+		}
+	}
+
+	wireless_send_event( dev, SIOCSIWENCODE, &wrqu,
+						 lp->DefaultKeys.key[index].key );
+#endif /* WIRELESS_EXT > 13 */
+
+	return;
+} // wl_wext_event_encode
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wl_wext_event_ap()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function is used to send an event that the device has been
+ *      associated to a new AP.
+ *
+ *
+ *  PARAMETERS:
+ *
+ *      dev - the network device for which this event is to be issued
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_wext_event_ap( struct net_device *dev )
+{
+#if WIRELESS_EXT > 13
+	union iwreq_data wrqu;
+	struct wl_private *lp = wl_priv(dev);
+	int status;
+	/*------------------------------------------------------------------------*/
+
+
+	/* Retrieve the WPA-IEs used by the firmware and send an event. We must send
+	   this event BEFORE sending the association event, as there are timing
+	   issues with the hostap supplicant. The supplicant will attempt to process
+	   an EAPOL-Key frame from an AP before receiving this information, which
+	   is required properly process the said frame. */
+	wl_wext_event_assoc_ie( dev );
+
+	/* Get the BSSID */
+	lp->ltvRecord.typ = CFG_CUR_BSSID;
+	lp->ltvRecord.len = 4;
+
+	status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+	if( status == HCF_SUCCESS ) {
+		memset( &wrqu, 0, sizeof( wrqu ));
+
+		memcpy( wrqu.addr.sa_data, lp->ltvRecord.u.u8, ETH_ALEN );
+
+		wrqu.addr.sa_family = ARPHRD_ETHER;
+
+		wireless_send_event( dev, SIOCGIWAP, &wrqu, NULL );
+	}
+
+#endif /* WIRELESS_EXT > 13 */
+
+	return;
+} // wl_wext_event_ap
+/*============================================================================*/
+
+
+
+/*******************************************************************************
+ *	wl_wext_event_scan_complete()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function is used to send an event that a request for a network scan
+ *      has completed.
+ *
+ *
+ *  PARAMETERS:
+ *
+ *      dev - the network device for which this event is to be issued
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_wext_event_scan_complete( struct net_device *dev )
+{
+#if WIRELESS_EXT > 13
+	union iwreq_data wrqu;
+	/*------------------------------------------------------------------------*/
+
+
+	memset( &wrqu, 0, sizeof( wrqu ));
+
+	wrqu.addr.sa_family = ARPHRD_ETHER;
+	wireless_send_event( dev, SIOCGIWSCAN, &wrqu, NULL );
+#endif /* WIRELESS_EXT > 13 */
+
+	return;
+} // wl_wext_event_scan_complete
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wl_wext_event_new_sta()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function is used to send an event that an AP has registered a new
+ *      station.
+ *
+ *
+ *  PARAMETERS:
+ *
+ *      dev - the network device for which this event is to be issued
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_wext_event_new_sta( struct net_device *dev )
+{
+#if WIRELESS_EXT > 14
+	union iwreq_data wrqu;
+	/*------------------------------------------------------------------------*/
+
+
+	memset( &wrqu, 0, sizeof( wrqu ));
+
+	/* Send the station's mac address here */
+	memcpy( wrqu.addr.sa_data, dev->dev_addr, ETH_ALEN );
+	wrqu.addr.sa_family = ARPHRD_ETHER;
+	wireless_send_event( dev, IWEVREGISTERED, &wrqu, NULL );
+#endif /* WIRELESS_EXT > 14 */
+
+	return;
+} // wl_wext_event_new_sta
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wl_wext_event_expired_sta()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function is used to send an event that an AP has deregistered a
+ *      station.
+ *
+ *
+ *  PARAMETERS:
+ *
+ *      dev - the network device for which this event is to be issued
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_wext_event_expired_sta( struct net_device *dev )
+{
+#if WIRELESS_EXT > 14
+	union iwreq_data wrqu;
+	/*------------------------------------------------------------------------*/
+
+
+	memset( &wrqu, 0, sizeof( wrqu ));
+
+	memcpy( wrqu.addr.sa_data, dev->dev_addr, ETH_ALEN );
+	wrqu.addr.sa_family = ARPHRD_ETHER;
+	wireless_send_event( dev, IWEVEXPIRED, &wrqu, NULL );
+#endif /* WIRELESS_EXT > 14 */
+
+	return;
+} // wl_wext_event_expired_sta
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wl_wext_event_mic_failed()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function is used to send an event that MIC calculations failed.
+ *
+ *
+ *  PARAMETERS:
+ *
+ *      dev - the network device for which this event is to be issued
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_wext_event_mic_failed( struct net_device *dev )
+{
+#if WIRELESS_EXT > 14
+	char               msg[512];
+	union iwreq_data   wrqu;
+	struct wl_private *lp = wl_priv(dev);
+	int                key_idx;
+	char              *addr1;
+	char              *addr2;
+	WVLAN_RX_WMP_HDR  *hdr;
+	/*------------------------------------------------------------------------*/
+
+
+	key_idx = lp->lookAheadBuf[HFS_STAT+1] >> 3;
+	key_idx &= 0x03;
+
+	/* Cast the lookahead buffer into a RFS format */
+	hdr = (WVLAN_RX_WMP_HDR *)&lp->lookAheadBuf[HFS_STAT];
+
+	/* Cast the addresses to byte buffers, as in the above RFS they are word
+	   length */
+	addr1 = (char *)hdr->address1;
+	addr2 = (char *)hdr->address2;
+
+	DBG_PRINT( "MIC FAIL - KEY USED : %d, STATUS : 0x%04x\n", key_idx,
+			   hdr->status );
+
+	memset( &wrqu, 0, sizeof( wrqu ));
+	memset( msg, 0, sizeof( msg ));
+
+
+	/* Becuase MIC failures are not part of the Wireless Extensions yet, they
+	   must be passed as a string using an IWEVCUSTOM event. In order for the
+	   event to be effective, the string format must be known by both the
+	   driver and the supplicant. The following is the string format used by the
+	   hostap project's WPA supplicant, and will be used here until the Wireless
+	   Extensions interface adds this support:
+
+	   MLME-MICHAELMICFAILURE.indication(keyid=# broadcast/unicast addr=addr2)
+   */
+
+	/* NOTE: Format of MAC address (using colons to seperate bytes) may cause
+			 a problem in future versions of the supplicant, if they ever
+			 actually parse these parameters */
+#if DBG
+	sprintf( msg, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
+			 "%s)", key_idx, addr1[0] & 0x01 ? "broad" : "uni",
+			 DbgHwAddr( addr2 ));
+#endif
+	wrqu.data.length = strlen( msg );
+	wireless_send_event( dev, IWEVCUSTOM, &wrqu, msg );
+#endif /* WIRELESS_EXT > 14 */
+
+	return;
+} // wl_wext_event_mic_failed
+/*============================================================================*/
+
+
+
+
+/*******************************************************************************
+ *	wl_wext_event_assoc_ie()
+ *******************************************************************************
+ *
+ *  DESCRIPTION:
+ *
+ *      This function is used to send an event containing the WPA-IE generated
+ *      by the firmware in an association request.
+ *
+ *
+ *  PARAMETERS:
+ *
+ *      dev - the network device for which this event is to be issued
+ *
+ *  RETURNS:
+ *
+ *      N/A
+ *
+ ******************************************************************************/
+void wl_wext_event_assoc_ie( struct net_device *dev )
+{
+#if WIRELESS_EXT > 14
+	char               msg[512];
+	union iwreq_data   wrqu;
+	struct wl_private *lp = wl_priv(dev);
+	int status;
+	PROBE_RESP         data;
+	hcf_16             length;
+	hcf_8              *wpa_ie;
+	/*------------------------------------------------------------------------*/
+
+
+	memset( &wrqu, 0, sizeof( wrqu ));
+	memset( msg, 0, sizeof( msg ));
+
+	/* Retrieve the Association Request IE */
+	lp->ltvRecord.len = 45;
+	lp->ltvRecord.typ = CFG_CUR_ASSOC_REQ_INFO;
+
+	status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
+	if( status == HCF_SUCCESS )
+	{
+		length = 0;
+		memcpy( &data.rawData, &( lp->ltvRecord.u.u8[1] ), 88 );
+		wpa_ie = wl_parse_wpa_ie( &data, &length );
+
+		/* Becuase this event (Association WPA-IE) is not part of the Wireless
+		Extensions yet, it must be passed as a string using an IWEVCUSTOM event.
+		In order for the event to be effective, the string format must be known
+		by both the driver and the supplicant. The following is the string format
+		used by the hostap project's WPA supplicant, and will be used here until
+		the Wireless Extensions interface adds this support:
+
+		ASSOCINFO(ReqIEs=WPA-IE RespIEs=WPA-IE)
+		*/
+
+		if( length != 0 )
+		{
+			sprintf( msg, "ASSOCINFO(ReqIEs=%s)", wl_print_wpa_ie( wpa_ie, length ));
+			wrqu.data.length = strlen( msg );
+			wireless_send_event( dev, IWEVCUSTOM, &wrqu, msg );
+		}
+	}
+#endif /* WIRELESS_EXT > 14 */
+
+	return;
+}  // wl_wext_event_assoc_ie
+/*============================================================================*/
+/* Structures to export the Wireless Handlers */
+
+static const iw_handler wl_handler[] =
+{
+                (iw_handler) wireless_commit,           /* SIOCSIWCOMMIT */
+                (iw_handler) wireless_get_protocol,     /* SIOCGIWNAME */
+                (iw_handler) NULL,                      /* SIOCSIWNWID */
+                (iw_handler) NULL,                      /* SIOCGIWNWID */
+                (iw_handler) wireless_set_frequency,    /* SIOCSIWFREQ */
+                (iw_handler) wireless_get_frequency,    /* SIOCGIWFREQ */
+                (iw_handler) wireless_set_porttype,     /* SIOCSIWMODE */
+                (iw_handler) wireless_get_porttype,     /* SIOCGIWMODE */
+                (iw_handler) wireless_set_sensitivity,  /* SIOCSIWSENS */
+                (iw_handler) wireless_get_sensitivity,  /* SIOCGIWSENS */
+                (iw_handler) NULL ,                     /* SIOCSIWRANGE */
+                (iw_handler) wireless_get_range,        /* SIOCGIWRANGE */
+                (iw_handler) NULL ,                     /* SIOCSIWPRIV */
+                (iw_handler) NULL /* kernel code */,    /* SIOCGIWPRIV */
+                (iw_handler) NULL ,                     /* SIOCSIWSTATS */
+                (iw_handler) NULL /* kernel code */,    /* SIOCGIWSTATS */
+                iw_handler_set_spy,                     /* SIOCSIWSPY */
+                iw_handler_get_spy,                     /* SIOCGIWSPY */
+                NULL,                                   /* SIOCSIWTHRSPY */
+                NULL,                                   /* SIOCGIWTHRSPY */
+                (iw_handler) NULL,                      /* SIOCSIWAP */
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
+                (iw_handler) wireless_get_bssid,        /* SIOCGIWAP */
+#else
+                (iw_handler) NULL,                      /* SIOCGIWAP */
+#endif
+                (iw_handler) NULL,                      /* SIOCSIWMLME */
+                (iw_handler) wireless_get_ap_list,      /* SIOCGIWAPLIST */
+                (iw_handler) wireless_set_scan,         /* SIOCSIWSCAN */
+                (iw_handler) wireless_get_scan,         /* SIOCGIWSCAN */
+                (iw_handler) wireless_set_essid,        /* SIOCSIWESSID */
+                (iw_handler) wireless_get_essid,        /* SIOCGIWESSID */
+                (iw_handler) wireless_set_nickname,     /* SIOCSIWNICKN */
+                (iw_handler) wireless_get_nickname,     /* SIOCGIWNICKN */
+                (iw_handler) NULL,                      /* -- hole -- */
+                (iw_handler) NULL,                      /* -- hole -- */
+                (iw_handler) wireless_set_rate,         /* SIOCSIWRATE */
+                (iw_handler) wireless_get_rate,         /* SIOCGIWRATE */
+                (iw_handler) wireless_set_rts_threshold,/* SIOCSIWRTS */
+                (iw_handler) wireless_get_rts_threshold,/* SIOCGIWRTS */
+                (iw_handler) NULL,                      /* SIOCSIWFRAG */
+                (iw_handler) NULL,                      /* SIOCGIWFRAG */
+                (iw_handler) NULL,                      /* SIOCSIWTXPOW */
+                (iw_handler) wireless_get_tx_power,     /* SIOCGIWTXPOW */
+                (iw_handler) NULL,                      /* SIOCSIWRETRY */
+                (iw_handler) NULL,                      /* SIOCGIWRETRY */
+                (iw_handler) wireless_set_encode,       /* SIOCSIWENCODE */
+                (iw_handler) wireless_get_encode,       /* SIOCGIWENCODE */
+                (iw_handler) wireless_set_power,        /* SIOCSIWPOWER */
+                (iw_handler) wireless_get_power,        /* SIOCGIWPOWER */
+                (iw_handler) NULL,                      /* -- hole -- */
+                (iw_handler) NULL,                      /* -- hole -- */
+                (iw_handler) wireless_get_genie,        /* SIOCSIWGENIE */
+                (iw_handler) NULL,                      /* SIOCGIWGENIE */
+                (iw_handler) wireless_set_auth,         /* SIOCSIWAUTH */
+                (iw_handler) NULL,                      /* SIOCGIWAUTH */
+                (iw_handler) wireless_set_encodeext,    /* SIOCSIWENCODEEXT */
+                (iw_handler) NULL,                      /* SIOCGIWENCODEEXT */
+                (iw_handler) NULL,                      /* SIOCSIWPMKSA */
+                (iw_handler) NULL,                      /* -- hole -- */
+};
+
+static const iw_handler wl_private_handler[] =
+{                                                       /* SIOCIWFIRSTPRIV + */
+                wvlan_set_netname,                      /* 0: SIOCSIWNETNAME */
+                wvlan_get_netname,                      /* 1: SIOCGIWNETNAME */
+                wvlan_set_station_nickname,             /* 2: SIOCSIWSTANAME */
+                wvlan_get_station_nickname,             /* 3: SIOCGIWSTANAME */
+#if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
+                wvlan_set_porttype,                     /* 4: SIOCSIWPORTTYPE */
+                wvlan_get_porttype,                     /* 5: SIOCGIWPORTTYPE */
+#endif
+};
+
+struct iw_priv_args wl_priv_args[] = {
+        {SIOCSIWNETNAME,    IW_PRIV_TYPE_CHAR | HCF_MAX_NAME_LEN, 0, "snetwork_name" },
+        {SIOCGIWNETNAME, 0, IW_PRIV_TYPE_CHAR | HCF_MAX_NAME_LEN,    "gnetwork_name" },
+        {SIOCSIWSTANAME,    IW_PRIV_TYPE_CHAR | HCF_MAX_NAME_LEN, 0, "sstation_name" },
+        {SIOCGIWSTANAME, 0, IW_PRIV_TYPE_CHAR | HCF_MAX_NAME_LEN,    "gstation_name" },
+#if 1 //;? #if (HCF_TYPE) & HCF_TYPE_STA
+        {SIOCSIWPORTTYPE,    IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "sport_type" },
+        {SIOCGIWPORTTYPE, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,    "gport_type" },
+#endif
+};
+
+const struct iw_handler_def wl_iw_handler_def =
+{
+        .num_private        = sizeof(wl_private_handler) / sizeof(iw_handler),
+        .private            = (iw_handler *) wl_private_handler,
+        .private_args       = (struct iw_priv_args *) wl_priv_args,
+        .num_private_args   = sizeof(wl_priv_args) / sizeof(struct iw_priv_args),
+        .num_standard       = sizeof(wl_handler) / sizeof(iw_handler),
+        .standard           = (iw_handler *) wl_handler,
+        .get_wireless_stats = wl_get_wireless_stats,
+};
+
+#endif // WIRELESS_EXT
diff --git a/drivers/staging/wlags49_h2/wl_wext.h b/drivers/staging/wlags49_h2/wl_wext.h
new file mode 100644
index 0000000..39d39a4
--- /dev/null
+++ b/drivers/staging/wlags49_h2/wl_wext.h
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Agere Systems Inc.
+ * Wireless device driver for Linux (wlags49).
+ *
+ * Copyright (c) 1998-2003 Agere Systems Inc.
+ * All rights reserved.
+ *   http://www.agere.com
+ *
+ * Initially developed by TriplePoint, Inc.
+ *   http://www.triplepoint.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ *   Header describing information required for the wireless IOCTL handlers.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software.  Using this
+ * software indicates your acceptance of these terms and conditions.  If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2003 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following Disclaimer as comments in the code as
+ *    well as in the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following Disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ ******************************************************************************/
+
+#ifndef __WL_WEXT_H__
+#define __WL_WEXT_H__
+
+
+#ifdef WIRELESS_EXT
+
+
+/*******************************************************************************
+ *  function protoypes
+ ******************************************************************************/
+
+struct iw_statistics *wl_wireless_stats( struct net_device *dev );
+
+struct iw_statistics * wl_get_wireless_stats( struct net_device *dev );
+
+inline void wl_spy_gather (struct net_device *dev, u_char *mac);
+
+void wl_wext_event_freq( struct net_device *dev );
+void wl_wext_event_mode( struct net_device *dev );
+void wl_wext_event_essid( struct net_device *dev );
+void wl_wext_event_encode( struct net_device *dev );
+void wl_wext_event_ap( struct net_device *dev );
+void wl_wext_event_scan_complete( struct net_device *dev );
+void wl_wext_event_new_sta( struct net_device *dev );
+void wl_wext_event_expired_sta( struct net_device *dev );
+void wl_wext_event_mic_failed( struct net_device *dev );
+void wl_wext_event_assoc_ie( struct net_device *dev );
+
+extern const struct iw_handler_def wl_iw_handler_def;
+
+#else
+#error WIRELESS_EXT
+#endif // WIRELESS_EXT
+
+
+#endif  // __WL_WEXT_H__
diff --git a/drivers/staging/wlags49_h25/Kconfig b/drivers/staging/wlags49_h25/Kconfig
new file mode 100644
index 0000000..304a8c9
--- /dev/null
+++ b/drivers/staging/wlags49_h25/Kconfig
@@ -0,0 +1,9 @@
+config WLAGS49_H25
+	tristate "Linksys HERMES II.5 WCF54G_Wireless-G_CompactFlash_Card"
+	depends on WLAN_80211 && WIRELESS_EXT && PCMCIA
+	select WEXT_SPY
+	---help---
+	  Driver for wireless cards using Agere's HERMES II.5 chipset
+	  which are identified with Manufacture ID: 0156,0004
+	  The software is a modified version of wl_lkm_722_abg.tar.gz
+	  from the Agere Systems website, addapted for Ubuntu 9.04.
diff --git a/drivers/staging/wlags49_h25/Makefile b/drivers/staging/wlags49_h25/Makefile
new file mode 100644
index 0000000..d0b23d4
--- /dev/null
+++ b/drivers/staging/wlags49_h25/Makefile
@@ -0,0 +1,81 @@
+#
+# Makefile for wlags49_h2_cs.ko and wlags49_h25_cs.ko
+#
+# Default build for Hermes-II base cards (possibly identified with
+# "manfid: 0x0156, 0x0003" in "pccardctl ident" output), comment
+# -DHERMES25 below
+#
+# If you want to build for Hermes-II.5 base cards (possibly identified with
+# "manfid: 0x0156, 0x0004" in "pccardctl ident" output), uncomment
+# -DHERMES25 below
+#
+#  If you want to build AP support (untested), comment out -DSTA_ONLY
+
+INSTALLDIR := /lib/modules/$(shell uname -r)/kernel/drivers/net/wireless
+EXTRA_CFLAGS += -I$(KERNELDIR)/include
+EXTRA_CFLAGS += -I$(src) \
+		-DBUS_PCMCIA \
+		-DUSE_WPA \
+		-DUSE_WEXT \
+		-DSTA_ONLY \
+		-DWVLAN_49 \
+		-DHERMES25 \
+#		-DDBG \
+#		-DDBG_LVL=5 \
+#		-DUSE_UIL \
+#		-DUSE_PROFILE \
+
+ifeq ($(findstring HERMES25,$(EXTRA_CFLAGS)),)
+WLNAME := wlags49_h2_cs
+$(WLNAME)-y := sta_h2.o
+ifeq ($(findstring STA_ONLY,$(EXTRA_CFLAGS)),)
+$(WLNAME)-y += ap_h2.o
+endif
+else
+WLNAME=wlags49_h25_cs
+$(WLNAME)-y := sta_h25.o
+ifeq ($(findstring STA_ONLY,$(EXTRA_CFLAGS)),)
+$(WLNAME)-y += ap_h25.o
+endif
+endif
+
+# If KERNELRELEASE is defined, we've been invoked from the
+# kernel build system and can use its language.
+ifneq ($(KERNELRELEASE),)
+
+obj-m		+= $(WLNAME).o
+
+$(WLNAME)-y +=	wl_profile.o \
+		wl_wext.o \
+		wl_priv.o \
+		wl_main.o \
+		wl_enc.o \
+		wl_util.o \
+		wl_netdev.o \
+		wl_cs.o \
+		mmd.o \
+		hcf.o \
+		dhf.o
+
+$(WLNAME)-$(CONFIG_SYSFS)	+= wl_sysfs.o
+
+# Otherwise we were called directly from the command
+# line; invoke the kernel build system.
+else
+	KERNELDIR ?= /lib/modules/$(shell uname -r)/build
+	PWD := $(shell pwd)
+
+default:
+	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
+endif
+
+clean:
+	rm -fr *.o *.ko *.mod.c *.mod.o .*.*.cmd Module.symvers \
+		Module.markers modules.order .tmp_versions
+
+install: default
+	-rmmod $(WLNAME)
+	install -d $(INSTALLDIR)
+	install -m 0644 -o root -g root $(WLNAME).ko $(INSTALLDIR)
+	/sbin/depmod -aq
+
diff --git a/drivers/staging/wlags49_h25/README.txt b/drivers/staging/wlags49_h25/README.txt
new file mode 100644
index 0000000..4c7a836
--- /dev/null
+++ b/drivers/staging/wlags49_h25/README.txt
@@ -0,0 +1,30 @@
+=======================================================================
+WLAN driver for cards using the HERMES II and HERMES II.5 chipset
+
+HERMES II Card
+
+PCMCIA Info: "Agere Systems" "Wireless PC Card Model 0110"
+             Manufacture ID: 0156,0003
+
+HERMES II.5 Card
+
+PCMCIA Info: "Linksys" "WCF54G_Wireless-G_CompactFlash_Card"
+             Manufacture ID: 0156,0004
+
+Based on Agere Systems Linux LKM Wireless Driver Source Code,
+Version 7.22; complies with Open Source BSD License.
+=======================================================================
+
+DESCRIPTION
+
+This directory only contains files that refer to the source in wlags49_h2.
+Only real sourcefiles are the Makefile which has been configured to build
+the driver for the HERMES II.5 chipset and Kconfig to describe the driver.
+
+The wlags49_h2 directory contains the full source, including the files
+exclusively used by this driver.
+
+For more information about the driver look at the wlags49_h2 direcory.
+
+=======================================================================
+
diff --git a/drivers/staging/wlags49_h25/TODO b/drivers/staging/wlags49_h25/TODO
new file mode 100644
index 0000000..14aa415
--- /dev/null
+++ b/drivers/staging/wlags49_h25/TODO
@@ -0,0 +1,33 @@
+First of all, the best thing would be that this driver becomes obsolte by
+adding support for Hermes II and Hermes II.5 cards to the existing orinoco
+driver. The orinoco driver currently only supports Hermes I based cards.
+Since this will not happen by magic and has not happend until now this
+driver provides a stop-gap solution for these type of cards.
+
+Having said that, the following wishlist comes to mind to make the driver
+suitable as fully supported kernel driver. Feel free to expand/enhance the
+list.
+
+TODO:
+	- verify against a Hermes II.5 card
+	- verify with WPA encription (both with H2 and H2.5 cards)
+	- sometimes the card does not initialize correctly, retry mechanisms
+	  are build in to catch most cases but not all
+	- once the driver runs it is very stable, but I have the impression
+	  some the crittical sections take to long
+	- the driver is split into a Hermes II and a Hermes II.5 part, it
+	  would be nice to handle both with one module instead of two
+	- review by the wireless developer community
+	- verify the code against the coding standards for a propper linux
+	  driver
+	- resolve license issues (?)
+
+DONE:
+	- verified against a Hermes II card (Thomson Speedtouch 110 PCMCIA
+	  card)
+	- verified with WEP encription
+
+Please send any patches or complaints about this driver to Greg
+Kroah-Hartman <greg@kroah.com> and Cc: Henk de Groot <pe1dnn@amsat.org>
+Don't bother the upstream wireless kernel developers about it, they
+want nothing to do with it.
diff --git a/drivers/staging/wlags49_h25/ap_h25.c b/drivers/staging/wlags49_h25/ap_h25.c
new file mode 100644
index 0000000..0344fa5
--- /dev/null
+++ b/drivers/staging/wlags49_h25/ap_h25.c
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/ap_h25.c"
diff --git a/drivers/staging/wlags49_h25/debug.h b/drivers/staging/wlags49_h25/debug.h
new file mode 100644
index 0000000..b5fb136
--- /dev/null
+++ b/drivers/staging/wlags49_h25/debug.h
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/debug.h"
diff --git a/drivers/staging/wlags49_h25/dhf.c b/drivers/staging/wlags49_h25/dhf.c
new file mode 100644
index 0000000..81762c8
--- /dev/null
+++ b/drivers/staging/wlags49_h25/dhf.c
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/dhf.c"
diff --git a/drivers/staging/wlags49_h25/dhf.h b/drivers/staging/wlags49_h25/dhf.h
new file mode 100644
index 0000000..54181dc
--- /dev/null
+++ b/drivers/staging/wlags49_h25/dhf.h
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/dhf.h"
diff --git a/drivers/staging/wlags49_h25/dhfcfg.h b/drivers/staging/wlags49_h25/dhfcfg.h
new file mode 100644
index 0000000..2586e39
--- /dev/null
+++ b/drivers/staging/wlags49_h25/dhfcfg.h
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/dhfcfg.h"
diff --git a/drivers/staging/wlags49_h25/hcf.c b/drivers/staging/wlags49_h25/hcf.c
new file mode 100644
index 0000000..eeeba1f
--- /dev/null
+++ b/drivers/staging/wlags49_h25/hcf.c
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/hcf.c"
diff --git a/drivers/staging/wlags49_h25/hcf.h b/drivers/staging/wlags49_h25/hcf.h
new file mode 100644
index 0000000..d1143d9
--- /dev/null
+++ b/drivers/staging/wlags49_h25/hcf.h
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/hcf.h"
diff --git a/drivers/staging/wlags49_h25/hcfcfg.h b/drivers/staging/wlags49_h25/hcfcfg.h
new file mode 100644
index 0000000..f88c4bc
--- /dev/null
+++ b/drivers/staging/wlags49_h25/hcfcfg.h
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/hcfcfg.h"
diff --git a/drivers/staging/wlags49_h25/hcfdef.h b/drivers/staging/wlags49_h25/hcfdef.h
new file mode 100644
index 0000000..f6a0060
--- /dev/null
+++ b/drivers/staging/wlags49_h25/hcfdef.h
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/hcfdef.h"
diff --git a/drivers/staging/wlags49_h25/mdd.h b/drivers/staging/wlags49_h25/mdd.h
new file mode 100644
index 0000000..4d8e142
--- /dev/null
+++ b/drivers/staging/wlags49_h25/mdd.h
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/mdd.h"
diff --git a/drivers/staging/wlags49_h25/mmd.c b/drivers/staging/wlags49_h25/mmd.c
new file mode 100644
index 0000000..b20782d
--- /dev/null
+++ b/drivers/staging/wlags49_h25/mmd.c
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/mmd.c"
diff --git a/drivers/staging/wlags49_h25/mmd.h b/drivers/staging/wlags49_h25/mmd.h
new file mode 100644
index 0000000..8284dd9
--- /dev/null
+++ b/drivers/staging/wlags49_h25/mmd.h
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/mmd.h"
diff --git a/drivers/staging/wlags49_h25/sta_h25.c b/drivers/staging/wlags49_h25/sta_h25.c
new file mode 100644
index 0000000..83c76bb
--- /dev/null
+++ b/drivers/staging/wlags49_h25/sta_h25.c
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/sta_h25.c"
diff --git a/drivers/staging/wlags49_h25/wl_cs.c b/drivers/staging/wlags49_h25/wl_cs.c
new file mode 100644
index 0000000..e6e1f19
--- /dev/null
+++ b/drivers/staging/wlags49_h25/wl_cs.c
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/wl_cs.c"
diff --git a/drivers/staging/wlags49_h25/wl_cs.h b/drivers/staging/wlags49_h25/wl_cs.h
new file mode 100644
index 0000000..657acee
--- /dev/null
+++ b/drivers/staging/wlags49_h25/wl_cs.h
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/wl_cs.h"
diff --git a/drivers/staging/wlags49_h25/wl_enc.c b/drivers/staging/wlags49_h25/wl_enc.c
new file mode 100644
index 0000000..fe59df1
--- /dev/null
+++ b/drivers/staging/wlags49_h25/wl_enc.c
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/wl_enc.c"
diff --git a/drivers/staging/wlags49_h25/wl_enc.h b/drivers/staging/wlags49_h25/wl_enc.h
new file mode 100644
index 0000000..f2e860e
--- /dev/null
+++ b/drivers/staging/wlags49_h25/wl_enc.h
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/wl_enc.h"
diff --git a/drivers/staging/wlags49_h25/wl_if.h b/drivers/staging/wlags49_h25/wl_if.h
new file mode 100644
index 0000000..70d86f0
--- /dev/null
+++ b/drivers/staging/wlags49_h25/wl_if.h
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/wl_if.h"
diff --git a/drivers/staging/wlags49_h25/wl_internal.h b/drivers/staging/wlags49_h25/wl_internal.h
new file mode 100644
index 0000000..c1687a3
--- /dev/null
+++ b/drivers/staging/wlags49_h25/wl_internal.h
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/wl_internal.h"
diff --git a/drivers/staging/wlags49_h25/wl_main.c b/drivers/staging/wlags49_h25/wl_main.c
new file mode 100644
index 0000000..d2c06ad
--- /dev/null
+++ b/drivers/staging/wlags49_h25/wl_main.c
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/wl_main.c"
diff --git a/drivers/staging/wlags49_h25/wl_main.h b/drivers/staging/wlags49_h25/wl_main.h
new file mode 100644
index 0000000..c98376e
--- /dev/null
+++ b/drivers/staging/wlags49_h25/wl_main.h
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/wl_main.h"
diff --git a/drivers/staging/wlags49_h25/wl_netdev.c b/drivers/staging/wlags49_h25/wl_netdev.c
new file mode 100644
index 0000000..f7512c3
--- /dev/null
+++ b/drivers/staging/wlags49_h25/wl_netdev.c
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/wl_netdev.c"
diff --git a/drivers/staging/wlags49_h25/wl_netdev.h b/drivers/staging/wlags49_h25/wl_netdev.h
new file mode 100644
index 0000000..519cd5f
--- /dev/null
+++ b/drivers/staging/wlags49_h25/wl_netdev.h
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/wl_netdev.h"
diff --git a/drivers/staging/wlags49_h25/wl_priv.c b/drivers/staging/wlags49_h25/wl_priv.c
new file mode 100644
index 0000000..160c801
--- /dev/null
+++ b/drivers/staging/wlags49_h25/wl_priv.c
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/wl_priv.c"
diff --git a/drivers/staging/wlags49_h25/wl_priv.h b/drivers/staging/wlags49_h25/wl_priv.h
new file mode 100644
index 0000000..28492b3
--- /dev/null
+++ b/drivers/staging/wlags49_h25/wl_priv.h
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/wl_priv.h"
diff --git a/drivers/staging/wlags49_h25/wl_profile.c b/drivers/staging/wlags49_h25/wl_profile.c
new file mode 100644
index 0000000..6baa201
--- /dev/null
+++ b/drivers/staging/wlags49_h25/wl_profile.c
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/wl_profile.c"
diff --git a/drivers/staging/wlags49_h25/wl_profile.h b/drivers/staging/wlags49_h25/wl_profile.h
new file mode 100644
index 0000000..5f253a5
--- /dev/null
+++ b/drivers/staging/wlags49_h25/wl_profile.h
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/wl_profile.h"
diff --git a/drivers/staging/wlags49_h25/wl_sysfs.c b/drivers/staging/wlags49_h25/wl_sysfs.c
new file mode 100644
index 0000000..6458ee6
--- /dev/null
+++ b/drivers/staging/wlags49_h25/wl_sysfs.c
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/wl_sysfs.c"
diff --git a/drivers/staging/wlags49_h25/wl_sysfs.h b/drivers/staging/wlags49_h25/wl_sysfs.h
new file mode 100644
index 0000000..eb819a5
--- /dev/null
+++ b/drivers/staging/wlags49_h25/wl_sysfs.h
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/wl_sysfs.h"
diff --git a/drivers/staging/wlags49_h25/wl_util.c b/drivers/staging/wlags49_h25/wl_util.c
new file mode 100644
index 0000000..771bebe
--- /dev/null
+++ b/drivers/staging/wlags49_h25/wl_util.c
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/wl_util.c"
diff --git a/drivers/staging/wlags49_h25/wl_util.h b/drivers/staging/wlags49_h25/wl_util.h
new file mode 100644
index 0000000..ccd74e7
--- /dev/null
+++ b/drivers/staging/wlags49_h25/wl_util.h
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/wl_util.h"
diff --git a/drivers/staging/wlags49_h25/wl_version.h b/drivers/staging/wlags49_h25/wl_version.h
new file mode 100644
index 0000000..ad38e8f
--- /dev/null
+++ b/drivers/staging/wlags49_h25/wl_version.h
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/wl_version.h"
diff --git a/drivers/staging/wlags49_h25/wl_wext.c b/drivers/staging/wlags49_h25/wl_wext.c
new file mode 100644
index 0000000..f660e79
--- /dev/null
+++ b/drivers/staging/wlags49_h25/wl_wext.c
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/wl_wext.c"
diff --git a/drivers/staging/wlags49_h25/wl_wext.h b/drivers/staging/wlags49_h25/wl_wext.h
new file mode 100644
index 0000000..31d6386
--- /dev/null
+++ b/drivers/staging/wlags49_h25/wl_wext.h
@@ -0,0 +1,2 @@
+/* Use common source from wlags49_h2 */
+#include "../wlags49_h2/wl_wext.h"
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c
index 40de151..e89304c 100644
--- a/drivers/telephony/ixj.c
+++ b/drivers/telephony/ixj.c
@@ -4190,7 +4190,7 @@
 				ixj_WriteDSPCommand(0x1224, j);
 
 			ixj_WriteDSPCommand(0xE014, j);
-			ixj_WriteDSPCommand(0x0003, j);	/* Lock threashold at 3dB */
+			ixj_WriteDSPCommand(0x0003, j);	/* Lock threshold at 3dB */
 
 			ixj_WriteDSPCommand(0xE338, j);	/* Set Echo Suppresser Attenuation to 0dB */
 
@@ -4235,7 +4235,7 @@
 				ixj_WriteDSPCommand(0x1224, j);
 
 			ixj_WriteDSPCommand(0xE014, j);
-			ixj_WriteDSPCommand(0x0003, j);	/* Lock threashold at 3dB */
+			ixj_WriteDSPCommand(0x0003, j);	/* Lock threshold at 3dB */
 
 			ixj_WriteDSPCommand(0xE338, j);	/* Set Echo Suppresser Attenuation to 0dB */
 
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 2407508..81aac7f 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -60,6 +60,8 @@
 	default y if ARCH_IXP4XX
 	default y if ARCH_W90X900
 	default y if ARCH_AT91SAM9G45
+	default y if ARCH_MXC
+	default y if ARCH_OMAP34XX
 	default PCI
 
 # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index be3c9b8..473aa1a 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -44,3 +44,5 @@
 
 obj-$(CONFIG_USB_ATM)		+= atm/
 obj-$(CONFIG_USB_SPEEDTOUCH)	+= atm/
+
+obj-$(CONFIG_USB_ULPI)		+= otg/
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index d171b56..c539524 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -667,12 +667,12 @@
 	else
 		uea_info(usb, "firmware uploaded\n");
 
-	uea_leaves(usb);
-	return;
+	goto err;
 
 err_fw_corrupted:
 	uea_err(usb, "firmware is corrupted\n");
 err:
+	release_firmware(fw_entry);
 	uea_leaves(usb);
 }
 
@@ -705,7 +705,8 @@
 		break;
 	}
 
-	ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev, usb, uea_upload_pre_firmware);
+	ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev,
+				      GFP_KERNEL, usb, uea_upload_pre_firmware);
 	if (ret)
 		uea_err(usb, "firmware %s is not available\n", fw_name);
 	else
@@ -1958,7 +1959,7 @@
 		goto bad1;
 
 	/* FIXME : ADI930 reply wrong preambule (func = 2, sub = 2) to
-	 * the first MEMACESS cmv. Ignore it...
+	 * the first MEMACCESS cmv. Ignore it...
 	 */
 	if (cmv->bFunction != dsc->function) {
 		if (UEA_CHIP_VERSION(sc) == ADI930
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index e4eca78..34d4eb9 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1461,6 +1461,12 @@
 }
 
 #endif /* CONFIG_PM */
+
+#define NOKIA_PCSUITE_ACM_INFO(x) \
+		USB_DEVICE_AND_INTERFACE_INFO(0x0421, x, \
+		USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, \
+		USB_CDC_ACM_PROTO_VENDOR)
+
 /*
  * USB driver structure.
  */
@@ -1519,6 +1525,57 @@
 	.driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
 	},
 
+	/* Nokia S60 phones expose two ACM channels. The first is
+	 * a modem and is picked up by the standard AT-command
+	 * information below. The second is 'vendor-specific' but
+	 * is treated as a serial device at the S60 end, so we want
+	 * to expose it on Linux too. */
+	{ NOKIA_PCSUITE_ACM_INFO(0x042D), }, /* Nokia 3250 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x04D8), }, /* Nokia 5500 Sport */
+	{ NOKIA_PCSUITE_ACM_INFO(0x04C9), }, /* Nokia E50 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x0419), }, /* Nokia E60 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x044D), }, /* Nokia E61 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x0001), }, /* Nokia E61i */
+	{ NOKIA_PCSUITE_ACM_INFO(0x0475), }, /* Nokia E62 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x0508), }, /* Nokia E65 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x0418), }, /* Nokia E70 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x0425), }, /* Nokia N71 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x0486), }, /* Nokia N73 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x04DF), }, /* Nokia N75 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x000e), }, /* Nokia N77 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x0445), }, /* Nokia N80 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x042F), }, /* Nokia N91 & N91 8GB */
+	{ NOKIA_PCSUITE_ACM_INFO(0x048E), }, /* Nokia N92 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x0420), }, /* Nokia N93 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x04E6), }, /* Nokia N93i  */
+	{ NOKIA_PCSUITE_ACM_INFO(0x04B2), }, /* Nokia 5700 XpressMusic */
+	{ NOKIA_PCSUITE_ACM_INFO(0x0134), }, /* Nokia 6110 Navigator (China) */
+	{ NOKIA_PCSUITE_ACM_INFO(0x046E), }, /* Nokia 6110 Navigator */
+	{ NOKIA_PCSUITE_ACM_INFO(0x002f), }, /* Nokia 6120 classic &  */
+	{ NOKIA_PCSUITE_ACM_INFO(0x0088), }, /* Nokia 6121 classic */
+	{ NOKIA_PCSUITE_ACM_INFO(0x00fc), }, /* Nokia 6124 classic */
+	{ NOKIA_PCSUITE_ACM_INFO(0x0042), }, /* Nokia E51 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x00b0), }, /* Nokia E66 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x00ab), }, /* Nokia E71 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x0481), }, /* Nokia N76 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x0007), }, /* Nokia N81 & N81 8GB */
+	{ NOKIA_PCSUITE_ACM_INFO(0x0071), }, /* Nokia N82 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x04F0), }, /* Nokia N95 & N95-3 NAM */
+	{ NOKIA_PCSUITE_ACM_INFO(0x0070), }, /* Nokia N95 8GB  */
+	{ NOKIA_PCSUITE_ACM_INFO(0x00e9), }, /* Nokia 5320 XpressMusic */
+	{ NOKIA_PCSUITE_ACM_INFO(0x0099), }, /* Nokia 6210 Navigator, RM-367 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x0128), }, /* Nokia 6210 Navigator, RM-419 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x008f), }, /* Nokia 6220 Classic */
+	{ NOKIA_PCSUITE_ACM_INFO(0x00a0), }, /* Nokia 6650 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x007b), }, /* Nokia N78 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x0094), }, /* Nokia N85 */
+	{ NOKIA_PCSUITE_ACM_INFO(0x003a), }, /* Nokia N96 & N96-3  */
+	{ NOKIA_PCSUITE_ACM_INFO(0x00e9), }, /* Nokia 5320 XpressMusic */
+	{ NOKIA_PCSUITE_ACM_INFO(0x0108), }, /* Nokia 5320 XpressMusic 2G */
+	{ NOKIA_PCSUITE_ACM_INFO(0x01f5), }, /* Nokia N97, RM-505 */
+
+	/* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */
+
 	/* control interfaces with various AT-command sets */
 	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
 		USB_CDC_ACM_PROTO_AT_V25TER) },
@@ -1533,7 +1590,6 @@
 	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
 		USB_CDC_ACM_PROTO_AT_CDMA) },
 
-	/* NOTE:  COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
 	{ }
 };
 
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c
index 2473cf0..7c5f4e3 100644
--- a/drivers/usb/class/usbtmc.c
+++ b/drivers/usb/class/usbtmc.c
@@ -1,5 +1,5 @@
 /**
- * drivers/usb/class/usbtmc.c - USB Test & Measurment class driver
+ * drivers/usb/class/usbtmc.c - USB Test & Measurement class driver
  *
  * Copyright (C) 2007 Stefan Kopp, Gechingen, Germany
  * Copyright (C) 2008 Novell, Inc.
@@ -347,13 +347,8 @@
 	goto exit;
 
 usbtmc_abort_bulk_out_clear_halt:
-	rv = usb_control_msg(data->usb_dev,
-			     usb_sndctrlpipe(data->usb_dev, 0),
-			     USB_REQ_CLEAR_FEATURE,
-			     USB_DIR_OUT | USB_TYPE_STANDARD |
-			     USB_RECIP_ENDPOINT,
-			     USB_ENDPOINT_HALT, data->bulk_out, buffer,
-			     0, USBTMC_TIMEOUT);
+	rv = usb_clear_halt(data->usb_dev,
+			    usb_sndbulkpipe(data->usb_dev, data->bulk_out));
 
 	if (rv < 0) {
 		dev_err(dev, "usb_control_msg returned %d\n", rv);
@@ -562,10 +557,16 @@
 		n_bytes = roundup(12 + this_part, 4);
 		memset(buffer + 12 + this_part, 0, n_bytes - (12 + this_part));
 
-		retval = usb_bulk_msg(data->usb_dev,
-				      usb_sndbulkpipe(data->usb_dev,
-						      data->bulk_out),
-				      buffer, n_bytes, &actual, USBTMC_TIMEOUT);
+		do {
+			retval = usb_bulk_msg(data->usb_dev,
+					      usb_sndbulkpipe(data->usb_dev,
+							      data->bulk_out),
+					      buffer, n_bytes,
+					      &actual, USBTMC_TIMEOUT);
+			if (retval != 0)
+				break;
+			n_bytes -= actual;
+		} while (n_bytes);
 
 		data->bTag_last_write = data->bTag;
 		data->bTag++;
@@ -702,14 +703,8 @@
 
 usbtmc_clear_bulk_out_halt:
 
-	rv = usb_control_msg(data->usb_dev,
-			     usb_sndctrlpipe(data->usb_dev, 0),
-			     USB_REQ_CLEAR_FEATURE,
-			     USB_DIR_OUT | USB_TYPE_STANDARD |
-			     USB_RECIP_ENDPOINT,
-			     USB_ENDPOINT_HALT,
-			     data->bulk_out, buffer, 0,
-			     USBTMC_TIMEOUT);
+	rv = usb_clear_halt(data->usb_dev,
+			    usb_sndbulkpipe(data->usb_dev, data->bulk_out));
 	if (rv < 0) {
 		dev_err(dev, "usb_control_msg returned %d\n", rv);
 		goto exit;
@@ -730,13 +725,8 @@
 	if (!buffer)
 		return -ENOMEM;
 
-	rv = usb_control_msg(data->usb_dev,
-			     usb_sndctrlpipe(data->usb_dev, 0),
-			     USB_REQ_CLEAR_FEATURE,
-			     USB_DIR_OUT | USB_TYPE_STANDARD |
-			     USB_RECIP_ENDPOINT,
-			     USB_ENDPOINT_HALT, data->bulk_out,
-			     buffer, 0, USBTMC_TIMEOUT);
+	rv = usb_clear_halt(data->usb_dev,
+			    usb_sndbulkpipe(data->usb_dev, data->bulk_out));
 
 	if (rv < 0) {
 		dev_err(&data->usb_dev->dev, "usb_control_msg returned %d\n",
@@ -759,12 +749,8 @@
 	if (!buffer)
 		return -ENOMEM;
 
-	rv = usb_control_msg(data->usb_dev, usb_sndctrlpipe(data->usb_dev, 0),
-			     USB_REQ_CLEAR_FEATURE,
-			     USB_DIR_OUT | USB_TYPE_STANDARD |
-			     USB_RECIP_ENDPOINT,
-			     USB_ENDPOINT_HALT, data->bulk_in, buffer, 0,
-			     USBTMC_TIMEOUT);
+	rv = usb_clear_halt(data->usb_dev,
+			    usb_rcvbulkpipe(data->usb_dev, data->bulk_in));
 
 	if (rv < 0) {
 		dev_err(&data->usb_dev->dev, "usb_control_msg returned %d\n",
@@ -1109,13 +1095,13 @@
 	kref_put(&data->kref, usbtmc_delete);
 }
 
-static int usbtmc_suspend (struct usb_interface *intf, pm_message_t message)
+static int usbtmc_suspend(struct usb_interface *intf, pm_message_t message)
 {
 	/* this driver does not have pending URBs */
 	return 0;
 }
 
-static int usbtmc_resume (struct usb_interface *intf)
+static int usbtmc_resume(struct usb_interface *intf)
 {
 	return 0;
 }
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 4f86447..60a45f1 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -83,6 +83,47 @@
 }
 static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
 
+/**
+ * store_remove_id - remove a USB device ID from this driver
+ * @driver: target device driver
+ * @buf: buffer for scanning device ID data
+ * @count: input size
+ *
+ * Removes a dynamic usb device ID from this driver.
+ */
+static ssize_t
+store_remove_id(struct device_driver *driver, const char *buf, size_t count)
+{
+	struct usb_dynid *dynid, *n;
+	struct usb_driver *usb_driver = to_usb_driver(driver);
+	u32 idVendor = 0;
+	u32 idProduct = 0;
+	int fields = 0;
+	int retval = 0;
+
+	fields = sscanf(buf, "%x %x", &idVendor, &idProduct);
+	if (fields < 2)
+		return -EINVAL;
+
+	spin_lock(&usb_driver->dynids.lock);
+	list_for_each_entry_safe(dynid, n, &usb_driver->dynids.list, node) {
+		struct usb_device_id *id = &dynid->id;
+		if ((id->idVendor == idVendor) &&
+		    (id->idProduct == idProduct)) {
+			list_del(&dynid->node);
+			kfree(dynid);
+			retval = 0;
+			break;
+		}
+	}
+	spin_unlock(&usb_driver->dynids.lock);
+
+	if (retval)
+		return retval;
+	return count;
+}
+static DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id);
+
 static int usb_create_newid_file(struct usb_driver *usb_drv)
 {
 	int error = 0;
@@ -107,6 +148,21 @@
 				   &driver_attr_new_id);
 }
 
+static int
+usb_create_removeid_file(struct usb_driver *drv)
+{
+	int error = 0;
+	if (drv->probe != NULL)
+		error = driver_create_file(&drv->drvwrap.driver,
+				&driver_attr_remove_id);
+	return error;
+}
+
+static void usb_remove_removeid_file(struct usb_driver *drv)
+{
+	driver_remove_file(&drv->drvwrap.driver, &driver_attr_remove_id);
+}
+
 static void usb_free_dynids(struct usb_driver *usb_drv)
 {
 	struct usb_dynid *dynid, *n;
@@ -128,6 +184,16 @@
 {
 }
 
+static int
+usb_create_removeid_file(struct usb_driver *drv)
+{
+	return 0;
+}
+
+static void usb_remove_removeid_file(struct usb_driver *drv)
+{
+}
+
 static inline void usb_free_dynids(struct usb_driver *usb_drv)
 {
 }
@@ -774,19 +840,34 @@
 	INIT_LIST_HEAD(&new_driver->dynids.list);
 
 	retval = driver_register(&new_driver->drvwrap.driver);
+	if (retval)
+		goto out;
 
-	if (!retval) {
-		pr_info("%s: registered new interface driver %s\n",
+	usbfs_update_special();
+
+	retval = usb_create_newid_file(new_driver);
+	if (retval)
+		goto out_newid;
+
+	retval = usb_create_removeid_file(new_driver);
+	if (retval)
+		goto out_removeid;
+
+	pr_info("%s: registered new interface driver %s\n",
 			usbcore_name, new_driver->name);
-		usbfs_update_special();
-		usb_create_newid_file(new_driver);
-	} else {
-		printk(KERN_ERR "%s: error %d registering interface "
+
+out:
+	return retval;
+
+out_removeid:
+	usb_remove_newid_file(new_driver);
+out_newid:
+	driver_unregister(&new_driver->drvwrap.driver);
+
+	printk(KERN_ERR "%s: error %d registering interface "
 			"	driver %s\n",
 			usbcore_name, retval, new_driver->name);
-	}
-
-	return retval;
+	goto out;
 }
 EXPORT_SYMBOL_GPL(usb_register_driver);
 
@@ -806,6 +887,7 @@
 	pr_info("%s: deregistering interface driver %s\n",
 			usbcore_name, driver->name);
 
+	usb_remove_removeid_file(driver);
 	usb_remove_newid_file(driver);
 	usb_free_dynids(driver);
 	driver_unregister(&driver->drvwrap.driver);
@@ -948,8 +1030,6 @@
 
  done:
 	dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status);
-	if (status == 0)
-		udev->autoresume_disabled = 0;
 	return status;
 }
 
@@ -1280,11 +1360,6 @@
 
 	/* Propagate the resume up the tree, if necessary */
 	if (udev->state == USB_STATE_SUSPENDED) {
-		if ((msg.event & PM_EVENT_AUTO) &&
-				udev->autoresume_disabled) {
-			status = -EPERM;
-			goto done;
-		}
 		if (parent) {
 			status = usb_autoresume_device(parent);
 			if (status == 0) {
@@ -1341,7 +1416,6 @@
 	int	status = 0;
 
 	usb_pm_lock(udev);
-	udev->auto_pm = 1;
 	udev->pm_usage_cnt += inc_usage_cnt;
 	WARN_ON(udev->pm_usage_cnt < 0);
 	if (inc_usage_cnt)
@@ -1473,7 +1547,6 @@
 	if (intf->condition == USB_INTERFACE_UNBOUND)
 		status = -ENODEV;
 	else {
-		udev->auto_pm = 1;
 		atomic_add(inc_usage_cnt, &intf->pm_usage_cnt);
 		udev->last_busy = jiffies;
 		if (inc_usage_cnt >= 0 &&
@@ -1640,8 +1713,6 @@
 
 	if (intf->condition == USB_INTERFACE_UNBOUND)
 		status = -ENODEV;
-	else if (udev->autoresume_disabled)
-		status = -EPERM;
 	else {
 		atomic_inc(&intf->pm_usage_cnt);
 		if (atomic_read(&intf->pm_usage_cnt) > 0 &&
@@ -1654,28 +1725,6 @@
 }
 EXPORT_SYMBOL_GPL(usb_autopm_get_interface_async);
 
-/**
- * usb_autopm_set_interface - set a USB interface's autosuspend state
- * @intf: the usb_interface whose state should be set
- *
- * This routine sets the autosuspend state of @intf's device according
- * to @intf's usage counter, which the caller must have set previously.
- * If the counter is <= 0, the device is autosuspended (if it isn't
- * already suspended and if nothing else prevents the autosuspend).  If
- * the counter is > 0, the device is autoresumed (if it isn't already
- * awake).
- */
-int usb_autopm_set_interface(struct usb_interface *intf)
-{
-	int	status;
-
-	status = usb_autopm_do_interface(intf, 0);
-	dev_vdbg(&intf->dev, "%s: status %d cnt %d\n",
-			__func__, status, atomic_read(&intf->pm_usage_cnt));
-	return status;
-}
-EXPORT_SYMBOL_GPL(usb_autopm_set_interface);
-
 #else
 
 void usb_autosuspend_work(struct work_struct *work)
@@ -1707,7 +1756,6 @@
 
 	do_unbind_rebind(udev, DO_UNBIND);
 	usb_pm_lock(udev);
-	udev->auto_pm = 0;
 	status = usb_suspend_both(udev, msg);
 	usb_pm_unlock(udev);
 	return status;
@@ -1730,7 +1778,6 @@
 	int	status;
 
 	usb_pm_lock(udev);
-	udev->auto_pm = 0;
 	status = usb_resume_both(udev, msg);
 	udev->last_busy = jiffies;
 	usb_pm_unlock(udev);
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
index 222ee07..bfc6c2e 100644
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -99,6 +99,7 @@
 		printk(KERN_ERR "class_create failed for usb devices\n");
 		kfree(usb_class);
 		usb_class = NULL;
+		goto exit;
 	}
 	usb_class->class->devnode = usb_devnode;
 
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
index 05e6d31..bdf87a8 100644
--- a/drivers/usb/core/generic.c
+++ b/drivers/usb/core/generic.c
@@ -139,7 +139,7 @@
 
 	if (best) {
 		i = best->desc.bConfigurationValue;
-		dev_info(&udev->dev,
+		dev_dbg(&udev->dev,
 			"configuration #%d chosen from %d choice%s\n",
 			i, num_configs, plural(num_configs));
 	} else {
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 34de475..6dac3b8 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -38,6 +38,7 @@
 #include <asm/unaligned.h>
 #include <linux/platform_device.h>
 #include <linux/workqueue.h>
+#include <linux/mutex.h>
 
 #include <linux/usb.h>
 
@@ -1275,13 +1276,16 @@
 
 	if (usb_endpoint_xfer_control(&urb->ep->desc)
 	    && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) {
-		if (hcd->self.uses_dma)
+		if (hcd->self.uses_dma) {
 			urb->setup_dma = dma_map_single(
 					hcd->self.controller,
 					urb->setup_packet,
 					sizeof(struct usb_ctrlrequest),
 					DMA_TO_DEVICE);
-		else if (hcd->driver->flags & HCD_LOCAL_MEM)
+			if (dma_mapping_error(hcd->self.controller,
+						urb->setup_dma))
+				return -EAGAIN;
+		} else if (hcd->driver->flags & HCD_LOCAL_MEM)
 			ret = hcd_alloc_coherent(
 					urb->dev->bus, mem_flags,
 					&urb->setup_dma,
@@ -1293,13 +1297,16 @@
 	dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
 	if (ret == 0 && urb->transfer_buffer_length != 0
 	    && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) {
-		if (hcd->self.uses_dma)
+		if (hcd->self.uses_dma) {
 			urb->transfer_dma = dma_map_single (
 					hcd->self.controller,
 					urb->transfer_buffer,
 					urb->transfer_buffer_length,
 					dir);
-		else if (hcd->driver->flags & HCD_LOCAL_MEM) {
+			if (dma_mapping_error(hcd->self.controller,
+						urb->transfer_dma))
+				return -EAGAIN;
+		} else if (hcd->driver->flags & HCD_LOCAL_MEM) {
 			ret = hcd_alloc_coherent(
 					urb->dev->bus, mem_flags,
 					&urb->transfer_dma,
@@ -1589,19 +1596,32 @@
 	}
 }
 
-/* Check whether a new configuration or alt setting for an interface
- * will exceed the bandwidth for the bus (or the host controller resources).
- * Only pass in a non-NULL config or interface, not both!
- * Passing NULL for both new_config and new_intf means the device will be
- * de-configured by issuing a set configuration 0 command.
+/**
+ * Check whether a new bandwidth setting exceeds the bus bandwidth.
+ * @new_config: new configuration to install
+ * @cur_alt: the current alternate interface setting
+ * @new_alt: alternate interface setting that is being installed
+ *
+ * To change configurations, pass in the new configuration in new_config,
+ * and pass NULL for cur_alt and new_alt.
+ *
+ * To reset a device's configuration (put the device in the ADDRESSED state),
+ * pass in NULL for new_config, cur_alt, and new_alt.
+ *
+ * To change alternate interface settings, pass in NULL for new_config,
+ * pass in the current alternate interface setting in cur_alt,
+ * and pass in the new alternate interface setting in new_alt.
+ *
+ * Returns an error if the requested bandwidth change exceeds the
+ * bus bandwidth or host controller internal resources.
  */
-int usb_hcd_check_bandwidth(struct usb_device *udev,
+int usb_hcd_alloc_bandwidth(struct usb_device *udev,
 		struct usb_host_config *new_config,
-		struct usb_interface *new_intf)
+		struct usb_host_interface *cur_alt,
+		struct usb_host_interface *new_alt)
 {
 	int num_intfs, i, j;
-	struct usb_interface_cache *intf_cache;
-	struct usb_host_interface *alt = 0;
+	struct usb_host_interface *alt = NULL;
 	int ret = 0;
 	struct usb_hcd *hcd;
 	struct usb_host_endpoint *ep;
@@ -1611,7 +1631,7 @@
 		return 0;
 
 	/* Configuration is being removed - set configuration 0 */
-	if (!new_config && !new_intf) {
+	if (!new_config && !cur_alt) {
 		for (i = 1; i < 16; ++i) {
 			ep = udev->ep_out[i];
 			if (ep)
@@ -1648,19 +1668,12 @@
 			}
 		}
 		for (i = 0; i < num_intfs; ++i) {
+			/* Set up endpoints for alternate interface setting 0 */
+			alt = usb_find_alt_setting(new_config, i, 0);
+			if (!alt)
+				/* No alt setting 0? Pick the first setting. */
+				alt = &new_config->intf_cache[i]->altsetting[0];
 
-			/* Dig the endpoints for alt setting 0 out of the
-			 * interface cache for this interface
-			 */
-			intf_cache = new_config->intf_cache[i];
-			for (j = 0; j < intf_cache->num_altsetting; j++) {
-				if (intf_cache->altsetting[j].desc.bAlternateSetting == 0)
-					alt = &intf_cache->altsetting[j];
-			}
-			if (!alt) {
-				printk(KERN_DEBUG "Did not find alt setting 0 for intf %d\n", i);
-				continue;
-			}
 			for (j = 0; j < alt->desc.bNumEndpoints; j++) {
 				ret = hcd->driver->add_endpoint(hcd, udev, &alt->endpoint[j]);
 				if (ret < 0)
@@ -1668,6 +1681,22 @@
 			}
 		}
 	}
+	if (cur_alt && new_alt) {
+		/* Drop all the endpoints in the current alt setting */
+		for (i = 0; i < cur_alt->desc.bNumEndpoints; i++) {
+			ret = hcd->driver->drop_endpoint(hcd, udev,
+					&cur_alt->endpoint[i]);
+			if (ret < 0)
+				goto reset;
+		}
+		/* Add all the endpoints in the new alt setting */
+		for (i = 0; i < new_alt->desc.bNumEndpoints; i++) {
+			ret = hcd->driver->add_endpoint(hcd, udev,
+					&new_alt->endpoint[i]);
+			if (ret < 0)
+				goto reset;
+		}
+	}
 	ret = hcd->driver->check_bandwidth(hcd, udev);
 reset:
 	if (ret < 0)
@@ -1984,6 +2013,7 @@
 #ifdef CONFIG_PM
 	INIT_WORK(&hcd->wakeup_work, hcd_resume_work);
 #endif
+	mutex_init(&hcd->bandwidth_mutex);
 
 	hcd->driver = driver;
 	hcd->product_desc = (driver->product_desc) ? driver->product_desc :
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index 79782a1..d8b43ae 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -111,6 +111,20 @@
 	u64			rsrc_len;	/* memory/io resource length */
 	unsigned		power_budget;	/* in mA, 0 = no limit */
 
+	/* bandwidth_mutex should be taken before adding or removing
+	 * any new bus bandwidth constraints:
+	 *   1. Before adding a configuration for a new device.
+	 *   2. Before removing the configuration to put the device into
+	 *      the addressed state.
+	 *   3. Before selecting a different configuration.
+	 *   4. Before selecting an alternate interface setting.
+	 *
+	 * bandwidth_mutex should be dropped after a successful control message
+	 * to the device, or resetting the bandwidth after a failed attempt.
+	 */
+	struct mutex		bandwidth_mutex;
+
+
 #define HCD_BUFFER_POOLS	4
 	struct dma_pool		*pool [HCD_BUFFER_POOLS];
 
@@ -290,9 +304,10 @@
 extern void usb_hcd_reset_endpoint(struct usb_device *udev,
 		struct usb_host_endpoint *ep);
 extern void usb_hcd_synchronize_unlinks(struct usb_device *udev);
-extern int usb_hcd_check_bandwidth(struct usb_device *udev,
+extern int usb_hcd_alloc_bandwidth(struct usb_device *udev,
 		struct usb_host_config *new_config,
-		struct usb_interface *new_intf);
+		struct usb_host_interface *old_alt,
+		struct usb_host_interface *new_alt);
 extern int usb_hcd_get_frame_number(struct usb_device *udev);
 
 extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver,
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 0f857e6..06af970 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -45,7 +45,6 @@
 
 	/* buffer for urb ... with extra space in case of babble */
 	char			(*buffer)[8];
-	dma_addr_t		buffer_dma;	/* DMA address for buffer */
 	union {
 		struct usb_hub_status	hub;
 		struct usb_port_status	port;
@@ -61,6 +60,8 @@
 							status change */
 	unsigned long		busy_bits[1];	/* ports being reset or
 							resumed */
+	unsigned long		removed_bits[1]; /* ports with a "removed"
+							device present */
 #if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */
 #error event_bits[] is too short!
 #endif
@@ -70,6 +71,7 @@
 
 	unsigned		mA_per_port;	/* current for each child */
 
+	unsigned		init_done:1;
 	unsigned		limited_power:1;
 	unsigned		quiescing:1;
 	unsigned		disconnected:1;
@@ -374,12 +376,13 @@
 {
 	unsigned long	flags;
 
-	/* Suppress autosuspend until khubd runs */
-	atomic_set(&to_usb_interface(hub->intfdev)->pm_usage_cnt, 1);
-
 	spin_lock_irqsave(&hub_event_lock, flags);
 	if (!hub->disconnected && list_empty(&hub->event_list)) {
 		list_add_tail(&hub->event_list, &hub_event_list);
+
+		/* Suppress autosuspend until khubd runs */
+		usb_autopm_get_interface_no_resume(
+				to_usb_interface(hub->intfdev));
 		wake_up(&khubd_wait);
 	}
 	spin_unlock_irqrestore(&hub_event_lock, flags);
@@ -636,8 +639,35 @@
  	kick_khubd(hub);
 }
 
+/**
+ * usb_remove_device - disable a device's port on its parent hub
+ * @udev: device to be disabled and removed
+ * Context: @udev locked, must be able to sleep.
+ *
+ * After @udev's port has been disabled, khubd is notified and it will
+ * see that the device has been disconnected.  When the device is
+ * physically unplugged and something is plugged in, the events will
+ * be received and processed normally.
+ */
+int usb_remove_device(struct usb_device *udev)
+{
+	struct usb_hub *hub;
+	struct usb_interface *intf;
+
+	if (!udev->parent)	/* Can't remove a root hub */
+		return -EINVAL;
+	hub = hdev_to_hub(udev->parent);
+	intf = to_usb_interface(hub->intfdev);
+
+	usb_autopm_get_interface(intf);
+	set_bit(udev->portnum, hub->removed_bits);
+	hub_port_logical_disconnect(hub, udev->portnum);
+	usb_autopm_put_interface(intf);
+	return 0;
+}
+
 enum hub_activation_type {
-	HUB_INIT, HUB_INIT2, HUB_INIT3,
+	HUB_INIT, HUB_INIT2, HUB_INIT3,		/* INITs must come first */
 	HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME,
 };
 
@@ -682,8 +712,8 @@
 					msecs_to_jiffies(delay));
 
 			/* Suppress autosuspend until init is done */
-			atomic_set(&to_usb_interface(hub->intfdev)->
-					pm_usage_cnt, 1);
+			usb_autopm_get_interface_no_resume(
+					to_usb_interface(hub->intfdev));
 			return;		/* Continues at init2: below */
 		} else {
 			hub_power_on(hub, true);
@@ -731,6 +761,13 @@
 					USB_PORT_FEAT_C_ENABLE);
 		}
 
+		/* We can forget about a "removed" device when there's a
+		 * physical disconnect or the connect status changes.
+		 */
+		if (!(portstatus & USB_PORT_STAT_CONNECTION) ||
+				(portchange & USB_PORT_STAT_C_CONNECTION))
+			clear_bit(port1, hub->removed_bits);
+
 		if (!udev || udev->state == USB_STATE_NOTATTACHED) {
 			/* Tell khubd to disconnect the device or
 			 * check for a new connection
@@ -783,6 +820,7 @@
 	}
  init3:
 	hub->quiescing = 0;
+	hub->init_done = 1;
 
 	status = usb_submit_urb(hub->urb, GFP_NOIO);
 	if (status < 0)
@@ -792,6 +830,10 @@
 
 	/* Scan all ports that need attention */
 	kick_khubd(hub);
+
+	/* Allow autosuspend if it was suppressed */
+	if (type <= HUB_INIT3)
+		usb_autopm_put_interface_async(to_usb_interface(hub->intfdev));
 }
 
 /* Implement the continuations for the delays above */
@@ -819,6 +861,11 @@
 	int i;
 
 	cancel_delayed_work_sync(&hub->init_work);
+	if (!hub->init_done) {
+		hub->init_done = 1;
+		usb_autopm_put_interface_no_suspend(
+				to_usb_interface(hub->intfdev));
+	}
 
 	/* khubd and related activity won't re-trigger */
 	hub->quiescing = 1;
@@ -869,8 +916,7 @@
 	int maxp, ret;
 	char *message = "out of memory";
 
-	hub->buffer = usb_buffer_alloc(hdev, sizeof(*hub->buffer), GFP_KERNEL,
-			&hub->buffer_dma);
+	hub->buffer = kmalloc(sizeof(*hub->buffer), GFP_KERNEL);
 	if (!hub->buffer) {
 		ret = -ENOMEM;
 		goto fail;
@@ -1111,8 +1157,6 @@
 
 	usb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq,
 		hub, endpoint->bInterval);
-	hub->urb->transfer_dma = hub->buffer_dma;
-	hub->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
 	/* maybe cycle the hub leds */
 	if (hub->has_indicators && blinkenlights)
@@ -1144,7 +1188,10 @@
 
 	/* Take the hub off the event list and don't let it be added again */
 	spin_lock_irq(&hub_event_lock);
-	list_del_init(&hub->event_list);
+	if (!list_empty(&hub->event_list)) {
+		list_del_init(&hub->event_list);
+		usb_autopm_put_interface_no_suspend(intf);
+	}
 	hub->disconnected = 1;
 	spin_unlock_irq(&hub_event_lock);
 
@@ -1162,8 +1209,7 @@
 	kfree(hub->port_owners);
 	kfree(hub->descriptor);
 	kfree(hub->status);
-	usb_buffer_free(hub->hdev, sizeof(*hub->buffer), hub->buffer,
-			hub->buffer_dma);
+	kfree(hub->buffer);
 
 	kref_put(&hub->kref, hub_release);
 }
@@ -1630,7 +1676,7 @@
 	if (!udev->bus->is_b_host
 			&& udev->config
 			&& udev->parent == udev->bus->root_hub) {
-		struct usb_otg_descriptor	*desc = 0;
+		struct usb_otg_descriptor	*desc = NULL;
 		struct usb_bus			*bus = udev->bus;
 
 		/* descriptor may appear anywhere in config */
@@ -2123,9 +2169,13 @@
 				USB_DEVICE_REMOTE_WAKEUP, 0,
 				NULL, 0,
 				USB_CTRL_SET_TIMEOUT);
-		if (status)
+		if (status) {
 			dev_dbg(&udev->dev, "won't remote wakeup, status %d\n",
 					status);
+			/* bail if autosuspend is requested */
+			if (msg.event & PM_EVENT_AUTO)
+				return status;
+		}
 	}
 
 	/* see 7.1.7.6 */
@@ -2134,7 +2184,8 @@
 		dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n",
 				port1, status);
 		/* paranoia:  "should not happen" */
-		(void) usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+		if (udev->do_remote_wakeup)
+			(void) usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 				USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE,
 				USB_DEVICE_REMOTE_WAKEUP, 0,
 				NULL, 0,
@@ -2965,6 +3016,13 @@
 		usb_disconnect(&hdev->children[port1-1]);
 	clear_bit(port1, hub->change_bits);
 
+	/* We can forget about a "removed" device when there's a physical
+	 * disconnect or the connect status changes.
+	 */
+	if (!(portstatus & USB_PORT_STAT_CONNECTION) ||
+			(portchange & USB_PORT_STAT_C_CONNECTION))
+		clear_bit(port1, hub->removed_bits);
+
 	if (portchange & (USB_PORT_STAT_C_CONNECTION |
 				USB_PORT_STAT_C_ENABLE)) {
 		status = hub_port_debounce(hub, port1);
@@ -2978,8 +3036,11 @@
 		}
 	}
 
-	/* Return now if debouncing failed or nothing is connected */
-	if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
+	/* Return now if debouncing failed or nothing is connected or
+	 * the device was "removed".
+	 */
+	if (!(portstatus & USB_PORT_STAT_CONNECTION) ||
+			test_bit(port1, hub->removed_bits)) {
 
 		/* maybe switch power back on (e.g. root hub was reset) */
 		if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2
@@ -3189,7 +3250,7 @@
 		 * disconnected while waiting for the lock to succeed. */
 		usb_lock_device(hdev);
 		if (unlikely(hub->disconnected))
-			goto loop;
+			goto loop2;
 
 		/* If the hub has died, clean up after it */
 		if (hdev->state == USB_STATE_NOTATTACHED) {
@@ -3338,11 +3399,15 @@
 			}
 		}
 
-loop_autopm:
-		/* Allow autosuspend if we're not going to run again */
-		if (list_empty(&hub->event_list))
-			usb_autopm_enable(intf);
-loop:
+ loop_autopm:
+		/* Balance the usb_autopm_get_interface() above */
+		usb_autopm_put_interface_no_suspend(intf);
+ loop:
+		/* Balance the usb_autopm_get_interface_no_resume() in
+		 * kick_khubd() and allow autosuspend.
+		 */
+		usb_autopm_put_interface(intf);
+ loop2:
 		usb_unlock_device(hdev);
 		kref_put(&hub->kref, hub_release);
 
@@ -3534,6 +3599,7 @@
 {
 	struct usb_device		*parent_hdev = udev->parent;
 	struct usb_hub			*parent_hub;
+	struct usb_hcd			*hcd = bus_to_hcd(udev->bus);
 	struct usb_device_descriptor	descriptor = udev->descriptor;
 	int 				i, ret = 0;
 	int				port1 = udev->portnum;
@@ -3577,6 +3643,16 @@
 	/* Restore the device's previous configuration */
 	if (!udev->actconfig)
 		goto done;
+
+	mutex_lock(&hcd->bandwidth_mutex);
+	ret = usb_hcd_alloc_bandwidth(udev, udev->actconfig, NULL, NULL);
+	if (ret < 0) {
+		dev_warn(&udev->dev,
+				"Busted HC?  Not enough HCD resources for "
+				"old configuration.\n");
+		mutex_unlock(&hcd->bandwidth_mutex);
+		goto re_enumerate;
+	}
 	ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 			USB_REQ_SET_CONFIGURATION, 0,
 			udev->actconfig->desc.bConfigurationValue, 0,
@@ -3585,8 +3661,10 @@
 		dev_err(&udev->dev,
 			"can't restore configuration #%d (error=%d)\n",
 			udev->actconfig->desc.bConfigurationValue, ret);
+		mutex_unlock(&hcd->bandwidth_mutex);
 		goto re_enumerate;
   	}
+	mutex_unlock(&hcd->bandwidth_mutex);
 	usb_set_device_state(udev, USB_STATE_CONFIGURED);
 
 	/* Put interfaces back into the same altsettings as before.
@@ -3596,7 +3674,8 @@
 	 * endpoint state.
 	 */
 	for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
-		struct usb_interface *intf = udev->actconfig->interface[i];
+		struct usb_host_config *config = udev->actconfig;
+		struct usb_interface *intf = config->interface[i];
 		struct usb_interface_descriptor *desc;
 
 		desc = &intf->cur_altsetting->desc;
@@ -3605,6 +3684,17 @@
 			usb_enable_interface(udev, intf, true);
 			ret = 0;
 		} else {
+			/* We've just reset the device, so it will think alt
+			 * setting 0 is installed.  For usb_set_interface() to
+			 * work properly, we need to set the current alternate
+			 * interface setting to 0 (or the first alt setting, if
+			 * the device doesn't have alt setting 0).
+			 */
+			intf->cur_altsetting =
+				usb_find_alt_setting(config, i, 0);
+			if (!intf->cur_altsetting)
+				intf->cur_altsetting =
+					&config->intf_cache[i]->altsetting[0];
 			ret = usb_set_interface(udev, desc->bInterfaceNumber,
 					desc->bAlternateSetting);
 		}
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index da718e8..1b99484 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -393,13 +393,7 @@
 	if (io->entries <= 0)
 		return io->entries;
 
-	/* If we're running on an xHCI host controller, queue the whole scatter
-	 * gather list with one call to urb_enqueue().  This is only for bulk,
-	 * as that endpoint type does not care how the data gets broken up
-	 * across frames.
-	 */
-	if (usb_pipebulk(pipe) &&
-			bus_to_hcd(dev->bus)->driver->flags & HCD_USB3) {
+	if (dev->bus->sg_tablesize > 0) {
 		io->urbs = kmalloc(sizeof *io->urbs, mem_flags);
 		use_sg = true;
 	} else {
@@ -409,7 +403,7 @@
 	if (!io->urbs)
 		goto nomem;
 
-	urb_flags = URB_NO_INTERRUPT;
+	urb_flags = 0;
 	if (dma)
 		urb_flags |= URB_NO_TRANSFER_DMA_MAP;
 	if (usb_pipein(pipe))
@@ -441,6 +435,7 @@
 		io->urbs[0]->num_sgs = io->entries;
 		io->entries = 1;
 	} else {
+		urb_flags |= URB_NO_INTERRUPT;
 		for_each_sg(sg, sg, io->entries, i) {
 			unsigned len;
 
@@ -1303,6 +1298,7 @@
 {
 	struct usb_interface *iface;
 	struct usb_host_interface *alt;
+	struct usb_hcd *hcd = bus_to_hcd(dev->bus);
 	int ret;
 	int manual = 0;
 	unsigned int epaddr;
@@ -1325,6 +1321,18 @@
 		return -EINVAL;
 	}
 
+	/* Make sure we have enough bandwidth for this alternate interface.
+	 * Remove the current alt setting and add the new alt setting.
+	 */
+	mutex_lock(&hcd->bandwidth_mutex);
+	ret = usb_hcd_alloc_bandwidth(dev, NULL, iface->cur_altsetting, alt);
+	if (ret < 0) {
+		dev_info(&dev->dev, "Not enough bandwidth for altsetting %d\n",
+				alternate);
+		mutex_unlock(&hcd->bandwidth_mutex);
+		return ret;
+	}
+
 	if (dev->quirks & USB_QUIRK_NO_SET_INTF)
 		ret = -EPIPE;
 	else
@@ -1340,8 +1348,13 @@
 			"manual set_interface for iface %d, alt %d\n",
 			interface, alternate);
 		manual = 1;
-	} else if (ret < 0)
+	} else if (ret < 0) {
+		/* Re-instate the old alt setting */
+		usb_hcd_alloc_bandwidth(dev, NULL, alt, iface->cur_altsetting);
+		mutex_unlock(&hcd->bandwidth_mutex);
 		return ret;
+	}
+	mutex_unlock(&hcd->bandwidth_mutex);
 
 	/* FIXME drivers shouldn't need to replicate/bugfix the logic here
 	 * when they implement async or easily-killable versions of this or
@@ -1423,6 +1436,7 @@
 {
 	int			i, retval;
 	struct usb_host_config	*config;
+	struct usb_hcd *hcd = bus_to_hcd(dev->bus);
 
 	if (dev->state == USB_STATE_SUSPENDED)
 		return -EHOSTUNREACH;
@@ -1438,12 +1452,46 @@
 	}
 
 	config = dev->actconfig;
+	retval = 0;
+	mutex_lock(&hcd->bandwidth_mutex);
+	/* Make sure we have enough bandwidth for each alternate setting 0 */
+	for (i = 0; i < config->desc.bNumInterfaces; i++) {
+		struct usb_interface *intf = config->interface[i];
+		struct usb_host_interface *alt;
+
+		alt = usb_altnum_to_altsetting(intf, 0);
+		if (!alt)
+			alt = &intf->altsetting[0];
+		if (alt != intf->cur_altsetting)
+			retval = usb_hcd_alloc_bandwidth(dev, NULL,
+					intf->cur_altsetting, alt);
+		if (retval < 0)
+			break;
+	}
+	/* If not, reinstate the old alternate settings */
+	if (retval < 0) {
+reset_old_alts:
+		for (; i >= 0; i--) {
+			struct usb_interface *intf = config->interface[i];
+			struct usb_host_interface *alt;
+
+			alt = usb_altnum_to_altsetting(intf, 0);
+			if (!alt)
+				alt = &intf->altsetting[0];
+			if (alt != intf->cur_altsetting)
+				usb_hcd_alloc_bandwidth(dev, NULL,
+						alt, intf->cur_altsetting);
+		}
+		mutex_unlock(&hcd->bandwidth_mutex);
+		return retval;
+	}
 	retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 			USB_REQ_SET_CONFIGURATION, 0,
 			config->desc.bConfigurationValue, 0,
 			NULL, 0, USB_CTRL_SET_TIMEOUT);
 	if (retval < 0)
-		return retval;
+		goto reset_old_alts;
+	mutex_unlock(&hcd->bandwidth_mutex);
 
 	/* re-init hc/hcd interface/endpoint state */
 	for (i = 0; i < config->desc.bNumInterfaces; i++) {
@@ -1585,7 +1633,7 @@
  *
  * See usb_queue_reset_device() for more details
  */
-void __usb_queue_reset_device(struct work_struct *ws)
+static void __usb_queue_reset_device(struct work_struct *ws)
 {
 	int rc;
 	struct usb_interface *iface =
@@ -1652,6 +1700,7 @@
 	int i, ret;
 	struct usb_host_config *cp = NULL;
 	struct usb_interface **new_interfaces = NULL;
+	struct usb_hcd *hcd = bus_to_hcd(dev->bus);
 	int n, nintf;
 
 	if (dev->authorized == 0 || configuration == -1)
@@ -1721,12 +1770,11 @@
 	 * host controller will not allow submissions to dropped endpoints.  If
 	 * this call fails, the device state is unchanged.
 	 */
-	if (cp)
-		ret = usb_hcd_check_bandwidth(dev, cp, NULL);
-	else
-		ret = usb_hcd_check_bandwidth(dev, NULL, NULL);
+	mutex_lock(&hcd->bandwidth_mutex);
+	ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);
 	if (ret < 0) {
 		usb_autosuspend_device(dev);
+		mutex_unlock(&hcd->bandwidth_mutex);
 		goto free_interfaces;
 	}
 
@@ -1752,10 +1800,12 @@
 	dev->actconfig = cp;
 	if (!cp) {
 		usb_set_device_state(dev, USB_STATE_ADDRESS);
-		usb_hcd_check_bandwidth(dev, NULL, NULL);
+		usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
 		usb_autosuspend_device(dev);
+		mutex_unlock(&hcd->bandwidth_mutex);
 		goto free_interfaces;
 	}
+	mutex_unlock(&hcd->bandwidth_mutex);
 	usb_set_device_state(dev, USB_STATE_CONFIGURED);
 
 	/* Initialize the new interface structures and the
@@ -1890,7 +1940,7 @@
  * routine gets around the normal restrictions by using a work thread to
  * submit the change-config request.
  *
- * Returns 0 if the request was succesfully queued, error code otherwise.
+ * Returns 0 if the request was successfully queued, error code otherwise.
  * The caller has no way to know whether the queued request will eventually
  * succeed.
  */
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 7ec3041a..1547700 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -139,6 +139,16 @@
 static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL);
 
 static ssize_t
+show_devpath(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct usb_device *udev;
+
+	udev = to_usb_device(dev);
+	return sprintf(buf, "%s\n", udev->devpath);
+}
+static DEVICE_ATTR(devpath, S_IRUGO, show_devpath, NULL);
+
+static ssize_t
 show_version(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct usb_device *udev;
@@ -317,7 +327,6 @@
 
 static const char on_string[] = "on";
 static const char auto_string[] = "auto";
-static const char suspend_string[] = "suspend";
 
 static ssize_t
 show_level(struct device *dev, struct device_attribute *attr, char *buf)
@@ -325,13 +334,8 @@
 	struct usb_device *udev = to_usb_device(dev);
 	const char *p = auto_string;
 
-	if (udev->state == USB_STATE_SUSPENDED) {
-		if (udev->autoresume_disabled)
-			p = suspend_string;
-	} else {
-		if (udev->autosuspend_disabled)
-			p = on_string;
-	}
+	if (udev->state != USB_STATE_SUSPENDED && udev->autosuspend_disabled)
+		p = on_string;
 	return sprintf(buf, "%s\n", p);
 }
 
@@ -343,7 +347,7 @@
 	int len = count;
 	char *cp;
 	int rc = 0;
-	int old_autosuspend_disabled, old_autoresume_disabled;
+	int old_autosuspend_disabled;
 
 	cp = memchr(buf, '\n', count);
 	if (cp)
@@ -351,7 +355,6 @@
 
 	usb_lock_device(udev);
 	old_autosuspend_disabled = udev->autosuspend_disabled;
-	old_autoresume_disabled = udev->autoresume_disabled;
 
 	/* Setting the flags without calling usb_pm_lock is a subject to
 	 * races, but who cares...
@@ -359,28 +362,18 @@
 	if (len == sizeof on_string - 1 &&
 			strncmp(buf, on_string, len) == 0) {
 		udev->autosuspend_disabled = 1;
-		udev->autoresume_disabled = 0;
 		rc = usb_external_resume_device(udev, PMSG_USER_RESUME);
 
 	} else if (len == sizeof auto_string - 1 &&
 			strncmp(buf, auto_string, len) == 0) {
 		udev->autosuspend_disabled = 0;
-		udev->autoresume_disabled = 0;
 		rc = usb_external_resume_device(udev, PMSG_USER_RESUME);
 
-	} else if (len == sizeof suspend_string - 1 &&
-			strncmp(buf, suspend_string, len) == 0) {
-		udev->autosuspend_disabled = 0;
-		udev->autoresume_disabled = 1;
-		rc = usb_external_suspend_device(udev, PMSG_USER_SUSPEND);
-
 	} else
 		rc = -EINVAL;
 
-	if (rc) {
+	if (rc)
 		udev->autosuspend_disabled = old_autosuspend_disabled;
-		udev->autoresume_disabled = old_autoresume_disabled;
-	}
 	usb_unlock_device(udev);
 	return (rc < 0 ? rc : count);
 }
@@ -508,6 +501,28 @@
 static DEVICE_ATTR(authorized, 0644,
 	    usb_dev_authorized_show, usb_dev_authorized_store);
 
+/* "Safely remove a device" */
+static ssize_t usb_remove_store(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct usb_device *udev = to_usb_device(dev);
+	int rc = 0;
+
+	usb_lock_device(udev);
+	if (udev->state != USB_STATE_NOTATTACHED) {
+
+		/* To avoid races, first unconfigure and then remove */
+		usb_set_configuration(udev, -1);
+		rc = usb_remove_device(udev);
+	}
+	if (rc == 0)
+		rc = count;
+	usb_unlock_device(udev);
+	return rc;
+}
+static DEVICE_ATTR(remove, 0200, NULL, usb_remove_store);
+
 
 static struct attribute *dev_attrs[] = {
 	/* current configuration's attributes */
@@ -516,8 +531,8 @@
 	&dev_attr_bConfigurationValue.attr,
 	&dev_attr_bmAttributes.attr,
 	&dev_attr_bMaxPower.attr,
-	&dev_attr_urbnum.attr,
 	/* device attributes */
+	&dev_attr_urbnum.attr,
 	&dev_attr_idVendor.attr,
 	&dev_attr_idProduct.attr,
 	&dev_attr_bcdDevice.attr,
@@ -529,10 +544,12 @@
 	&dev_attr_speed.attr,
 	&dev_attr_busnum.attr,
 	&dev_attr_devnum.attr,
+	&dev_attr_devpath.attr,
 	&dev_attr_version.attr,
 	&dev_attr_maxchild.attr,
 	&dev_attr_quirks.attr,
 	&dev_attr_authorized.attr,
+	&dev_attr_remove.attr,
 	NULL,
 };
 static struct attribute_group dev_attr_grp = {
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 0885d4a..e7cae13 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -429,8 +429,16 @@
 	case USB_ENDPOINT_XFER_ISOC:
 	case USB_ENDPOINT_XFER_INT:
 		/* too small? */
-		if (urb->interval <= 0)
-			return -EINVAL;
+		switch (dev->speed) {
+		case USB_SPEED_VARIABLE:
+			if (urb->interval < 6)
+				return -EINVAL;
+			break;
+		default:
+			if (urb->interval <= 0)
+				return -EINVAL;
+			break;
+		}
 		/* too big? */
 		switch (dev->speed) {
 		case USB_SPEED_SUPER:	/* units are 125us */
@@ -438,6 +446,10 @@
 			if (urb->interval > (1 << 15))
 				return -EINVAL;
 			max = 1 << 15;
+		case USB_SPEED_VARIABLE:
+			if (urb->interval > 16)
+				return -EINVAL;
+			break;
 		case USB_SPEED_HIGH:	/* units are microframes */
 			/* NOTE usb handles 2^15 */
 			if (urb->interval > (1024 * 8))
@@ -461,8 +473,10 @@
 		default:
 			return -EINVAL;
 		}
-		/* Round down to a power of 2, no more than max */
-		urb->interval = min(max, 1 << ilog2(urb->interval));
+		if (dev->speed != USB_SPEED_VARIABLE) {
+			/* Round down to a power of 2, no more than max */
+			urb->interval = min(max, 1 << ilog2(urb->interval));
+		}
 	}
 
 	return usb_hcd_submit_urb(urb, mem_flags);
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index b1b85ab..4e2c6df 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -64,6 +64,43 @@
 
 
 /**
+ * usb_find_alt_setting() - Given a configuration, find the alternate setting
+ * for the given interface.
+ * @config - the configuration to search (not necessarily the current config).
+ * @iface_num - interface number to search in
+ * @alt_num - alternate interface setting number to search for.
+ *
+ * Search the configuration's interface cache for the given alt setting.
+ */
+struct usb_host_interface *usb_find_alt_setting(
+		struct usb_host_config *config,
+		unsigned int iface_num,
+		unsigned int alt_num)
+{
+	struct usb_interface_cache *intf_cache = NULL;
+	int i;
+
+	for (i = 0; i < config->desc.bNumInterfaces; i++) {
+		if (config->intf_cache[i]->altsetting[0].desc.bInterfaceNumber
+				== iface_num) {
+			intf_cache = config->intf_cache[i];
+			break;
+		}
+	}
+	if (!intf_cache)
+		return NULL;
+	for (i = 0; i < intf_cache->num_altsetting; i++)
+		if (intf_cache->altsetting[i].desc.bAlternateSetting == alt_num)
+			return &intf_cache->altsetting[i];
+
+	printk(KERN_DEBUG "Did not find alt setting %u for intf %u, "
+			"config %u\n", alt_num, iface_num,
+			config->desc.bConfigurationValue);
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(usb_find_alt_setting);
+
+/**
  * usb_ifnum_to_if - get the interface object with a given interface number
  * @dev: the device whose current configuration is considered
  * @ifnum: the desired interface
@@ -130,24 +167,17 @@
 }
 EXPORT_SYMBOL_GPL(usb_altnum_to_altsetting);
 
-struct find_interface_arg {
-	int minor;
-	struct usb_interface *interface;
-};
-
 static int __find_interface(struct device *dev, void *data)
 {
-	struct find_interface_arg *arg = data;
+	int *minor = data;
 	struct usb_interface *intf;
 
 	if (!is_usb_interface(dev))
 		return 0;
 
 	intf = to_usb_interface(dev);
-	if (intf->minor != -1 && intf->minor == arg->minor) {
-		arg->interface = intf;
+	if (intf->minor != -1 && intf->minor == *minor)
 		return 1;
-	}
 	return 0;
 }
 
@@ -156,21 +186,20 @@
  * @drv: the driver whose current configuration is considered
  * @minor: the minor number of the desired device
  *
- * This walks the driver device list and returns a pointer to the interface
+ * This walks the bus device list and returns a pointer to the interface
  * with the matching minor.  Note, this only works for devices that share the
  * USB major number.
  */
 struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor)
 {
-	struct find_interface_arg argb;
-	int retval;
+	struct device *dev;
 
-	argb.minor = minor;
-	argb.interface = NULL;
-	/* eat the error, it will be in argb.interface */
-	retval = driver_for_each_device(&drv->drvwrap.driver, NULL, &argb,
-					__find_interface);
-	return argb.interface;
+	dev = bus_find_device(&usb_bus_type, NULL, &minor, __find_interface);
+
+	/* Drop reference count from bus_find_device */
+	put_device(dev);
+
+	return dev ? to_usb_interface(dev) : NULL;
 }
 EXPORT_SYMBOL_GPL(usb_find_interface);
 
@@ -1038,7 +1067,7 @@
 struct dentry *usb_debug_root;
 EXPORT_SYMBOL_GPL(usb_debug_root);
 
-struct dentry *usb_debug_devices;
+static struct dentry *usb_debug_devices;
 
 static int usb_debugfs_init(void)
 {
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 9a8b15e..4c36c7f 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -24,6 +24,7 @@
 extern int usb_deauthorize_device(struct usb_device *);
 extern int usb_authorize_device(struct usb_device *);
 extern void usb_detect_quirks(struct usb_device *udev);
+extern int usb_remove_device(struct usb_device *udev);
 
 extern int usb_get_device_descriptor(struct usb_device *dev,
 		unsigned int size);
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index a18e3c5..ee41120 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -732,6 +732,24 @@
 	  behavior of USB Mass Storage hosts.  Not needed for
 	  normal operation.
 
+config USB_MASS_STORAGE
+	tristate "Mass Storage Gadget"
+	depends on BLOCK
+	help
+	  The Mass Storage Gadget acts as a USB Mass Storage disk drive.
+	  As its storage repository it can use a regular file or a block
+	  device (in much the same way as the "loop" device driver),
+	  specified as a module parameter or sysfs option.
+
+	  This is heavily based on File-backed Storage Gadget and in most
+	  cases you will want to use FSG instead.  This gadget is mostly
+	  here to test the functionality of the Mass Storage Function
+	  which may be used with composite framework.
+
+	  Say "y" to link the driver statically, or "m" to build
+	  a dynamically linked module called "g_file_storage".  If unsure,
+	  consider File-backed Storage Gadget.
+
 config USB_G_SERIAL
 	tristate "Serial Gadget (with CDC ACM and CDC OBEX support)"
 	help
@@ -794,6 +812,48 @@
 	  Say "y" to link the driver statically, or "m" to build a
 	  dynamically linked module.
 
+config USB_G_MULTI
+	tristate "Multifunction Composite Gadget (EXPERIMENTAL)"
+	depends on BLOCK && NET
+	help
+	  The Multifunction Composite Gadget provides Ethernet (RNDIS
+	  and/or CDC Ethernet), mass storage and ACM serial link
+	  interfaces.
+
+	  You will be asked to choose which of the two configurations is
+	  to be available in the gadget.  At least one configuration must
+	  be chosen to make the gadget usable.  Selecting more than one
+	  configuration will prevent Windows from automatically detecting
+	  the gadget as a composite gadget, so an INF file will be needed to
+	  use the gadget.
+
+	  Say "y" to link the driver statically, or "m" to build a
+	  dynamically linked module called "g_multi".
+
+config USB_G_MULTI_RNDIS
+	bool "RNDIS + CDC Serial + Storage configuration"
+	depends on USB_G_MULTI
+	default y
+	help
+	  This option enables a configuration with RNDIS, CDC Serial and
+	  Mass Storage functions available in the Multifunction Composite
+	  Gadget.  This is the configuration dedicated for Windows since RNDIS
+	  is Microsoft's protocol.
+
+	  If unsure, say "y".
+
+config USB_G_MULTI_CDC
+	bool "CDC Ethernet + CDC Serial + Storage configuration"
+	depends on USB_G_MULTI
+	default n
+	help
+	  This option enables a configuration with CDC Ethernet (ECM), CDC
+	  Serial and Mass Storage functions available in the Multifunction
+	  Composite Gadget.
+
+	  If unsure, say "y".
+
+
 # put drivers that need isochronous transfer support (for audio
 # or video class gadget drivers), or specific hardware, here.
 
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 9d7b87c..2e2c047 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -39,16 +39,20 @@
 g_midi-objs			:= gmidi.o
 gadgetfs-objs			:= inode.o
 g_file_storage-objs		:= file_storage.o
+g_mass_storage-objs		:= mass_storage.o
 g_printer-objs			:= printer.o
 g_cdc-objs			:= cdc2.o
+g_multi-objs			:= multi.o
 
 obj-$(CONFIG_USB_ZERO)		+= g_zero.o
 obj-$(CONFIG_USB_AUDIO)		+= g_audio.o
 obj-$(CONFIG_USB_ETH)		+= g_ether.o
 obj-$(CONFIG_USB_GADGETFS)	+= gadgetfs.o
 obj-$(CONFIG_USB_FILE_STORAGE)	+= g_file_storage.o
+obj-$(CONFIG_USB_MASS_STORAGE)	+= g_mass_storage.o
 obj-$(CONFIG_USB_G_SERIAL)	+= g_serial.o
 obj-$(CONFIG_USB_G_PRINTER)	+= g_printer.o
 obj-$(CONFIG_USB_MIDI_GADGET)	+= g_midi.o
 obj-$(CONFIG_USB_CDC_COMPOSITE) += g_cdc.o
+obj-$(CONFIG_USB_G_MULTI)	+= g_multi.o
 
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 66450a1..043e04d 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -892,7 +892,7 @@
 
 			txvc |= AT91_UDP_TXVC_PUON;
 			at91_udp_write(udc, AT91_UDP_TXVC, txvc);
-		} else if (cpu_is_at91sam9261()) {
+		} else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) {
 			u32	usbpucr;
 
 			usbpucr = at91_sys_read(AT91_MATRIX_USBPUCR);
@@ -910,7 +910,7 @@
 
 			txvc &= ~AT91_UDP_TXVC_PUON;
 			at91_udp_write(udc, AT91_UDP_TXVC, txvc);
-		} else if (cpu_is_at91sam9261()) {
+		} else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) {
 			u32	usbpucr;
 
 			usbpucr = at91_sys_read(AT91_MATRIX_USBPUCR);
@@ -1692,7 +1692,7 @@
 		udc->ep[3].maxpacket = 64;
 		udc->ep[4].maxpacket = 512;
 		udc->ep[5].maxpacket = 512;
-	} else if (cpu_is_at91sam9261()) {
+	} else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) {
 		udc->ep[3].maxpacket = 64;
 	} else if (cpu_is_at91sam9263()) {
 		udc->ep[0].maxpacket = 64;
diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c
index a3a0f4a..58f2203 100644
--- a/drivers/usb/gadget/audio.c
+++ b/drivers/usb/gadget/audio.c
@@ -89,120 +89,6 @@
 
 /*-------------------------------------------------------------------------*/
 
-/**
- * Handle USB audio endpoint set/get command in setup class request
- */
-
-static int audio_set_endpoint_req(struct usb_configuration *c,
-		const struct usb_ctrlrequest *ctrl)
-{
-	struct usb_composite_dev *cdev = c->cdev;
-	int			value = -EOPNOTSUPP;
-	u16			ep = le16_to_cpu(ctrl->wIndex);
-	u16			len = le16_to_cpu(ctrl->wLength);
-	u16			w_value = le16_to_cpu(ctrl->wValue);
-
-	DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n",
-			ctrl->bRequest, w_value, len, ep);
-
-	switch (ctrl->bRequest) {
-	case UAC_SET_CUR:
-		value = 0;
-		break;
-
-	case UAC_SET_MIN:
-		break;
-
-	case UAC_SET_MAX:
-		break;
-
-	case UAC_SET_RES:
-		break;
-
-	case UAC_SET_MEM:
-		break;
-
-	default:
-		break;
-	}
-
-	return value;
-}
-
-static int audio_get_endpoint_req(struct usb_configuration *c,
-		const struct usb_ctrlrequest *ctrl)
-{
-	struct usb_composite_dev *cdev = c->cdev;
-	int value = -EOPNOTSUPP;
-	u8 ep = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF);
-	u16 len = le16_to_cpu(ctrl->wLength);
-	u16 w_value = le16_to_cpu(ctrl->wValue);
-
-	DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n",
-			ctrl->bRequest, w_value, len, ep);
-
-	switch (ctrl->bRequest) {
-	case UAC_GET_CUR:
-	case UAC_GET_MIN:
-	case UAC_GET_MAX:
-	case UAC_GET_RES:
-		value = 3;
-		break;
-	case UAC_GET_MEM:
-		break;
-	default:
-		break;
-	}
-
-	return value;
-}
-
-static int
-audio_setup(struct usb_configuration *c, const struct usb_ctrlrequest *ctrl)
-{
-	struct usb_composite_dev *cdev = c->cdev;
-	struct usb_request *req = cdev->req;
-	int value = -EOPNOTSUPP;
-	u16 w_index = le16_to_cpu(ctrl->wIndex);
-	u16 w_value = le16_to_cpu(ctrl->wValue);
-	u16 w_length = le16_to_cpu(ctrl->wLength);
-
-	/* composite driver infrastructure handles everything except
-	 * Audio class messages; interface activation uses set_alt().
-	 */
-	switch (ctrl->bRequestType) {
-	case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT:
-		value = audio_set_endpoint_req(c, ctrl);
-		break;
-
-	case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT:
-		value = audio_get_endpoint_req(c, ctrl);
-		break;
-
-	default:
-		ERROR(cdev, "Invalid control req%02x.%02x v%04x i%04x l%d\n",
-			ctrl->bRequestType, ctrl->bRequest,
-			w_value, w_index, w_length);
-	}
-
-	/* respond with data transfer or status phase? */
-	if (value >= 0) {
-		DBG(cdev, "Audio req%02x.%02x v%04x i%04x l%d\n",
-			ctrl->bRequestType, ctrl->bRequest,
-			w_value, w_index, w_length);
-		req->zero = 0;
-		req->length = value;
-		value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
-		if (value < 0)
-			ERROR(cdev, "Audio response on err %d\n", value);
-	}
-
-	/* device either stalls (value < 0) or reports success */
-	return value;
-}
-
-/*-------------------------------------------------------------------------*/
-
 static int __init audio_do_config(struct usb_configuration *c)
 {
 	/* FIXME alloc iConfiguration string, set it in c->strings */
@@ -220,7 +106,6 @@
 static struct usb_configuration audio_config_driver = {
 	.label			= DRIVER_DESC,
 	.bind			= audio_do_config,
-	.setup			= audio_setup,
 	.bConfigurationValue	= 1,
 	/* .iConfiguration = DYNAMIC */
 	.bmAttributes		= USB_CONFIG_ATT_SELFPOWER,
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index d05397e..09289bb 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -373,6 +373,8 @@
 	list_for_each_entry(f, &cdev->config->functions, list) {
 		if (f->disable)
 			f->disable(f);
+
+		bitmap_zero(f->endpoints, 32);
 	}
 	cdev->config = NULL;
 }
@@ -418,10 +420,35 @@
 	/* Initialize all interfaces by setting them to altsetting zero. */
 	for (tmp = 0; tmp < MAX_CONFIG_INTERFACES; tmp++) {
 		struct usb_function	*f = c->interface[tmp];
+		struct usb_descriptor_header **descriptors;
 
 		if (!f)
 			break;
 
+		/*
+		 * Record which endpoints are used by the function. This is used
+		 * to dispatch control requests targeted at that endpoint to the
+		 * function's setup callback instead of the current
+		 * configuration's setup callback.
+		 */
+		if (gadget->speed == USB_SPEED_HIGH)
+			descriptors = f->hs_descriptors;
+		else
+			descriptors = f->descriptors;
+
+		for (; *descriptors; ++descriptors) {
+			struct usb_endpoint_descriptor *ep;
+			int addr;
+
+			if ((*descriptors)->bDescriptorType != USB_DT_ENDPOINT)
+				continue;
+
+			ep = (struct usb_endpoint_descriptor *)*descriptors;
+			addr = ((ep->bEndpointAddress & 0x80) >> 3)
+			     |  (ep->bEndpointAddress & 0x0f);
+			set_bit(addr, f->endpoints);
+		}
+
 		result = f->set_alt(f, tmp, 0);
 		if (result < 0) {
 			DBG(cdev, "interface %d (%s/%p) alt 0 --> %d\n",
@@ -688,6 +715,7 @@
 	u16				w_value = le16_to_cpu(ctrl->wValue);
 	u16				w_length = le16_to_cpu(ctrl->wLength);
 	struct usb_function		*f = NULL;
+	u8				endp;
 
 	/* partial re-init of the response message; the function or the
 	 * gadget might need to intercept e.g. a control-OUT completion
@@ -800,23 +828,33 @@
 			ctrl->bRequestType, ctrl->bRequest,
 			w_value, w_index, w_length);
 
-		/* functions always handle their interfaces ... punt other
-		 * recipients (endpoint, other, WUSB, ...) to the current
+		/* functions always handle their interfaces and endpoints...
+		 * punt other recipients (other, WUSB, ...) to the current
 		 * configuration code.
 		 *
 		 * REVISIT it could make sense to let the composite device
 		 * take such requests too, if that's ever needed:  to work
 		 * in config 0, etc.
 		 */
-		if ((ctrl->bRequestType & USB_RECIP_MASK)
-				== USB_RECIP_INTERFACE) {
+		switch (ctrl->bRequestType & USB_RECIP_MASK) {
+		case USB_RECIP_INTERFACE:
 			f = cdev->config->interface[intf];
-			if (f && f->setup)
-				value = f->setup(f, ctrl);
-			else
+			break;
+
+		case USB_RECIP_ENDPOINT:
+			endp = ((w_index & 0x80) >> 3) | (w_index & 0x0f);
+			list_for_each_entry(f, &cdev->config->functions, list) {
+				if (test_bit(endp, f->endpoints))
+					break;
+			}
+			if (&f->list == &cdev->config->functions)
 				f = NULL;
+			break;
 		}
-		if (value < 0 && !f) {
+
+		if (f && f->setup)
+			value = f->setup(f, ctrl);
+		else {
 			struct usb_configuration	*c;
 
 			c = cdev->config;
@@ -1054,7 +1092,8 @@
 	.speed		= USB_SPEED_HIGH,
 
 	.bind		= composite_bind,
-	.unbind		= __exit_p(composite_unbind),
+	/* .unbind		= __exit_p(composite_unbind), */
+	.unbind		= composite_unbind,
 
 	.setup		= composite_setup,
 	.disconnect	= composite_disconnect,
@@ -1103,7 +1142,7 @@
  * This function is used to unregister drivers using the composite
  * driver framework.
  */
-void __exit usb_composite_unregister(struct usb_composite_driver *driver)
+void /* __exit */ usb_composite_unregister(struct usb_composite_driver *driver)
 {
 	if (composite != driver)
 		return;
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 167cb2a..141372b 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -25,6 +25,14 @@
 #include <linux/kernel.h>
 #include <linux/utsname.h>
 
+
+#if defined USB_ETH_RNDIS
+#  undef USB_ETH_RNDIS
+#endif
+#ifdef CONFIG_USB_ETH_RNDIS
+#  define USB_ETH_RNDIS y
+#endif
+
 #include "u_ether.h"
 
 
@@ -66,7 +74,7 @@
 #define DRIVER_DESC		"Ethernet Gadget"
 #define DRIVER_VERSION		"Memorial Day 2008"
 
-#ifdef CONFIG_USB_ETH_RNDIS
+#ifdef USB_ETH_RNDIS
 #define PREFIX			"RNDIS/"
 #else
 #define PREFIX			""
@@ -87,7 +95,7 @@
 
 static inline bool has_rndis(void)
 {
-#ifdef	CONFIG_USB_ETH_RNDIS
+#ifdef	USB_ETH_RNDIS
 	return true;
 #else
 	return false;
@@ -110,7 +118,7 @@
 
 #include "f_ecm.c"
 #include "f_subset.c"
-#ifdef	CONFIG_USB_ETH_RNDIS
+#ifdef	USB_ETH_RNDIS
 #include "f_rndis.c"
 #include "rndis.c"
 #endif
@@ -251,7 +259,7 @@
 
 /*-------------------------------------------------------------------------*/
 
-#ifdef CONFIG_USB_ETH_EEM
+#ifdef USB_ETH_EEM
 static int use_eem = 1;
 #else
 static int use_eem;
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index 7953948..d10353d 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -4,6 +4,8 @@
  * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
  * Copyright (C) 2008 by David Brownell
  * Copyright (C) 2008 by Nokia Corporation
+ * Copyright (C) 2009 by Samsung Electronics
+ * Author: Michal Nazarewicz (m.nazarewicz@samsung.com)
  *
  * This software is distributed under the terms of the GNU General
  * Public License ("GPL") as published by the Free Software Foundation,
@@ -99,6 +101,20 @@
 
 /* interface and class descriptors: */
 
+static struct usb_interface_assoc_descriptor
+acm_iad_descriptor = {
+	.bLength =		sizeof acm_iad_descriptor,
+	.bDescriptorType =	USB_DT_INTERFACE_ASSOCIATION,
+
+	/* .bFirstInterface =	DYNAMIC, */
+	.bInterfaceCount = 	2,	// control + data
+	.bFunctionClass =	USB_CLASS_COMM,
+	.bFunctionSubClass =	USB_CDC_SUBCLASS_ACM,
+	.bFunctionProtocol =	USB_CDC_PROTO_NONE,
+	/* .iFunction =		DYNAMIC */
+};
+
+
 static struct usb_interface_descriptor acm_control_interface_desc __initdata = {
 	.bLength =		USB_DT_INTERFACE_SIZE,
 	.bDescriptorType =	USB_DT_INTERFACE,
@@ -178,6 +194,7 @@
 };
 
 static struct usb_descriptor_header *acm_fs_function[] __initdata = {
+	(struct usb_descriptor_header *) &acm_iad_descriptor,
 	(struct usb_descriptor_header *) &acm_control_interface_desc,
 	(struct usb_descriptor_header *) &acm_header_desc,
 	(struct usb_descriptor_header *) &acm_call_mgmt_descriptor,
@@ -216,6 +233,7 @@
 };
 
 static struct usb_descriptor_header *acm_hs_function[] __initdata = {
+	(struct usb_descriptor_header *) &acm_iad_descriptor,
 	(struct usb_descriptor_header *) &acm_control_interface_desc,
 	(struct usb_descriptor_header *) &acm_header_desc,
 	(struct usb_descriptor_header *) &acm_call_mgmt_descriptor,
@@ -232,11 +250,13 @@
 
 #define ACM_CTRL_IDX	0
 #define ACM_DATA_IDX	1
+#define ACM_IAD_IDX	2
 
 /* static strings, in UTF-8 */
 static struct usb_string acm_string_defs[] = {
 	[ACM_CTRL_IDX].s = "CDC Abstract Control Model (ACM)",
 	[ACM_DATA_IDX].s = "CDC ACM Data",
+	[ACM_IAD_IDX ].s = "CDC Serial",
 	{  /* ZEROES END LIST */ },
 };
 
@@ -432,7 +452,7 @@
  * @length: size of data
  * Context: irqs blocked, acm->lock held, acm_notify_req non-null
  *
- * Returns zero on sucess or a negative errno.
+ * Returns zero on success or a negative errno.
  *
  * See section 6.3.5 of the CDC 1.1 specification for information
  * about the only notification we issue:  SerialState change.
@@ -563,6 +583,7 @@
 	if (status < 0)
 		goto fail;
 	acm->ctrl_id = status;
+	acm_iad_descriptor.bFirstInterface = status;
 
 	acm_control_interface_desc.bInterfaceNumber = status;
 	acm_union_desc .bMasterInterface0 = status;
@@ -732,6 +753,13 @@
 		acm_string_defs[ACM_DATA_IDX].id = status;
 
 		acm_data_interface_desc.iInterface = status;
+
+		status = usb_string_id(c->cdev);
+		if (status < 0)
+			return status;
+		acm_string_defs[ACM_IAD_IDX].id = status;
+
+		acm_iad_descriptor.iFunction = status;
 	}
 
 	/* allocate and initialize one new instance */
diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_audio.c
index 98e9bb9..c43c89f 100644
--- a/drivers/usb/gadget/f_audio.c
+++ b/drivers/usb/gadget/f_audio.c
@@ -445,6 +445,70 @@
 	return len;
 }
 
+static int audio_set_endpoint_req(struct usb_function *f,
+		const struct usb_ctrlrequest *ctrl)
+{
+	struct usb_composite_dev *cdev = f->config->cdev;
+	int			value = -EOPNOTSUPP;
+	u16			ep = le16_to_cpu(ctrl->wIndex);
+	u16			len = le16_to_cpu(ctrl->wLength);
+	u16			w_value = le16_to_cpu(ctrl->wValue);
+
+	DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n",
+			ctrl->bRequest, w_value, len, ep);
+
+	switch (ctrl->bRequest) {
+	case UAC_SET_CUR:
+		value = 0;
+		break;
+
+	case UAC_SET_MIN:
+		break;
+
+	case UAC_SET_MAX:
+		break;
+
+	case UAC_SET_RES:
+		break;
+
+	case UAC_SET_MEM:
+		break;
+
+	default:
+		break;
+	}
+
+	return value;
+}
+
+static int audio_get_endpoint_req(struct usb_function *f,
+		const struct usb_ctrlrequest *ctrl)
+{
+	struct usb_composite_dev *cdev = f->config->cdev;
+	int value = -EOPNOTSUPP;
+	u8 ep = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF);
+	u16 len = le16_to_cpu(ctrl->wLength);
+	u16 w_value = le16_to_cpu(ctrl->wValue);
+
+	DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n",
+			ctrl->bRequest, w_value, len, ep);
+
+	switch (ctrl->bRequest) {
+	case UAC_GET_CUR:
+	case UAC_GET_MIN:
+	case UAC_GET_MAX:
+	case UAC_GET_RES:
+		value = 3;
+		break;
+	case UAC_GET_MEM:
+		break;
+	default:
+		break;
+	}
+
+	return value;
+}
+
 static int
 f_audio_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
 {
@@ -455,8 +519,8 @@
 	u16			w_value = le16_to_cpu(ctrl->wValue);
 	u16			w_length = le16_to_cpu(ctrl->wLength);
 
-	/* composite driver infrastructure handles everything except
-	 * Audio class messages; interface activation uses set_alt().
+	/* composite driver infrastructure handles everything; interface
+	 * activation uses set_alt().
 	 */
 	switch (ctrl->bRequestType) {
 	case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE:
@@ -467,6 +531,14 @@
 		value = audio_get_intf_req(f, ctrl);
 		break;
 
+	case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT:
+		value = audio_set_endpoint_req(f, ctrl);
+		break;
+
+	case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT:
+		value = audio_get_endpoint_req(f, ctrl);
+		break;
+
 	default:
 		ERROR(cdev, "invalid control req%02x.%02x v%04x i%04x l%d\n",
 			ctrl->bRequestType, ctrl->bRequest,
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
new file mode 100644
index 0000000..a37640e
--- /dev/null
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -0,0 +1,3091 @@
+/*
+ * f_mass_storage.c -- Mass Storage USB Composite Function
+ *
+ * Copyright (C) 2003-2008 Alan Stern
+ * Copyright (C) 2009 Samsung Electronics
+ *                    Author: Michal Nazarewicz <m.nazarewicz@samsung.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/*
+ * The Mass Storage Function acts as a USB Mass Storage device,
+ * appearing to the host as a disk drive or as a CD-ROM drive.  In
+ * addition to providing an example of a genuinely useful composite
+ * function for a USB device, it also illustrates a technique of
+ * double-buffering for increased throughput.
+ *
+ * Function supports multiple logical units (LUNs).  Backing storage
+ * for each LUN is provided by a regular file or a block device.
+ * Access for each LUN can be limited to read-only.  Moreover, the
+ * function can indicate that LUN is removable and/or CD-ROM.  (The
+ * later implies read-only access.)
+ *
+ * MSF is configured by specifying a fsg_config structure.  It has the
+ * following fields:
+ *
+ *	nluns		Number of LUNs function have (anywhere from 1
+ *				to FSG_MAX_LUNS which is 8).
+ *	luns		An array of LUN configuration values.  This
+ *				should be filled for each LUN that
+ *				function will include (ie. for "nluns"
+ *				LUNs).  Each element of the array has
+ *				the following fields:
+ *	->filename	The path to the backing file for the LUN.
+ *				Required if LUN is not marked as
+ *				removable.
+ *	->ro		Flag specifying access to the LUN shall be
+ *				read-only.  This is implied if CD-ROM
+ *				emulation is enabled as well as when
+ *				it was impossible to open "filename"
+ *				in R/W mode.
+ *	->removable	Flag specifying that LUN shall be indicated as
+ *				being removable.
+ *	->cdrom		Flag specifying that LUN shall be reported as
+ *				being a CD-ROM.
+ *
+ *	lun_name_format	A printf-like format for names of the LUN
+ *				devices.  This determines how the
+ *				directory in sysfs will be named.
+ *				Unless you are using several MSFs in
+ *				a single gadget (as opposed to single
+ *				MSF in many configurations) you may
+ *				leave it as NULL (in which case
+ *				"lun%d" will be used).  In the format
+ *				you can use "%d" to index LUNs for
+ *				MSF's with more than one LUN.  (Beware
+ *				that there is only one integer given
+ *				as an argument for the format and
+ *				specifying invalid format may cause
+ *				unspecified behaviour.)
+ *	thread_name	Name of the kernel thread process used by the
+ *				MSF.  You can safely set it to NULL
+ *				(in which case default "file-storage"
+ *				will be used).
+ *
+ *	vendor_name
+ *	product_name
+ *	release		Information used as a reply to INQUIRY
+ *				request.  To use default set to NULL,
+ *				NULL, 0xffff respectively.  The first
+ *				field should be 8 and the second 16
+ *				characters or less.
+ *
+ *	can_stall	Set to permit function to halt bulk endpoints.
+ *				Disabled on some USB devices known not
+ *				to work correctly.  You should set it
+ *				to true.
+ *
+ * If "removable" is not set for a LUN then a backing file must be
+ * specified.  If it is set, then NULL filename means the LUN's medium
+ * is not loaded (an empty string as "filename" in the fsg_config
+ * structure causes error).  The CD-ROM emulation includes a single
+ * data track and no audio tracks; hence there need be only one
+ * backing file per LUN.  Note also that the CD-ROM block length is
+ * set to 512 rather than the more common value 2048.
+ *
+ *
+ * MSF includes support for module parameters.  If gadget using it
+ * decides to use it, the following module parameters will be
+ * available:
+ *
+ *	file=filename[,filename...]
+ *			Names of the files or block devices used for
+ *				backing storage.
+ *	ro=b[,b...]	Default false, boolean for read-only access.
+ *	removable=b[,b...]
+ *			Default true, boolean for removable media.
+ *	cdrom=b[,b...]	Default false, boolean for whether to emulate
+ *				a CD-ROM drive.
+ *	luns=N		Default N = number of filenames, number of
+ *				LUNs to support.
+ *	stall		Default determined according to the type of
+ *				USB device controller (usually true),
+ *				boolean to permit the driver to halt
+ *				bulk endpoints.
+ *
+ * The module parameters may be prefixed with some string.  You need
+ * to consult gadget's documentation or source to verify whether it is
+ * using those module parameters and if it does what are the prefixes
+ * (look for FSG_MODULE_PARAMETERS() macro usage, what's inside it is
+ * the prefix).
+ *
+ *
+ * Requirements are modest; only a bulk-in and a bulk-out endpoint are
+ * needed.  The memory requirement amounts to two 16K buffers, size
+ * configurable by a parameter.  Support is included for both
+ * full-speed and high-speed operation.
+ *
+ * Note that the driver is slightly non-portable in that it assumes a
+ * single memory/DMA buffer will be useable for bulk-in, bulk-out, and
+ * interrupt-in endpoints.  With most device controllers this isn't an
+ * issue, but there may be some with hardware restrictions that prevent
+ * a buffer from being used by more than one endpoint.
+ *
+ *
+ * The pathnames of the backing files and the ro settings are
+ * available in the attribute files "file" and "ro" in the lun<n> (or
+ * to be more precise in a directory which name comes from
+ * "lun_name_format" option!) subdirectory of the gadget's sysfs
+ * directory.  If the "removable" option is set, writing to these
+ * files will simulate ejecting/loading the medium (writing an empty
+ * line means eject) and adjusting a write-enable tab.  Changes to the
+ * ro setting are not allowed when the medium is loaded or if CD-ROM
+ * emulation is being used.
+ *
+ *
+ * This function is heavily based on "File-backed Storage Gadget" by
+ * Alan Stern which in turn is heavily based on "Gadget Zero" by David
+ * Brownell.  The driver's SCSI command interface was based on the
+ * "Information technology - Small Computer System Interface - 2"
+ * document from X3T9.2 Project 375D, Revision 10L, 7-SEP-93,
+ * available at <http://www.t10.org/ftp/t10/drafts/s2/s2-r10l.pdf>.
+ * The single exception is opcode 0x23 (READ FORMAT CAPACITIES), which
+ * was based on the "Universal Serial Bus Mass Storage Class UFI
+ * Command Specification" document, Revision 1.0, December 14, 1998,
+ * available at
+ * <http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf>.
+ */
+
+
+/*
+ *				Driver Design
+ *
+ * The MSF is fairly straightforward.  There is a main kernel
+ * thread that handles most of the work.  Interrupt routines field
+ * callbacks from the controller driver: bulk- and interrupt-request
+ * completion notifications, endpoint-0 events, and disconnect events.
+ * Completion events are passed to the main thread by wakeup calls.  Many
+ * ep0 requests are handled at interrupt time, but SetInterface,
+ * SetConfiguration, and device reset requests are forwarded to the
+ * thread in the form of "exceptions" using SIGUSR1 signals (since they
+ * should interrupt any ongoing file I/O operations).
+ *
+ * The thread's main routine implements the standard command/data/status
+ * parts of a SCSI interaction.  It and its subroutines are full of tests
+ * for pending signals/exceptions -- all this polling is necessary since
+ * the kernel has no setjmp/longjmp equivalents.  (Maybe this is an
+ * indication that the driver really wants to be running in userspace.)
+ * An important point is that so long as the thread is alive it keeps an
+ * open reference to the backing file.  This will prevent unmounting
+ * the backing file's underlying filesystem and could cause problems
+ * during system shutdown, for example.  To prevent such problems, the
+ * thread catches INT, TERM, and KILL signals and converts them into
+ * an EXIT exception.
+ *
+ * In normal operation the main thread is started during the gadget's
+ * fsg_bind() callback and stopped during fsg_unbind().  But it can
+ * also exit when it receives a signal, and there's no point leaving
+ * the gadget running when the thread is dead.  At of this moment, MSF
+ * provides no way to deregister the gadget when thread dies -- maybe
+ * a callback functions is needed.
+ *
+ * To provide maximum throughput, the driver uses a circular pipeline of
+ * buffer heads (struct fsg_buffhd).  In principle the pipeline can be
+ * arbitrarily long; in practice the benefits don't justify having more
+ * than 2 stages (i.e., double buffering).  But it helps to think of the
+ * pipeline as being a long one.  Each buffer head contains a bulk-in and
+ * a bulk-out request pointer (since the buffer can be used for both
+ * output and input -- directions always are given from the host's
+ * point of view) as well as a pointer to the buffer and various state
+ * variables.
+ *
+ * Use of the pipeline follows a simple protocol.  There is a variable
+ * (fsg->next_buffhd_to_fill) that points to the next buffer head to use.
+ * At any time that buffer head may still be in use from an earlier
+ * request, so each buffer head has a state variable indicating whether
+ * it is EMPTY, FULL, or BUSY.  Typical use involves waiting for the
+ * buffer head to be EMPTY, filling the buffer either by file I/O or by
+ * USB I/O (during which the buffer head is BUSY), and marking the buffer
+ * head FULL when the I/O is complete.  Then the buffer will be emptied
+ * (again possibly by USB I/O, during which it is marked BUSY) and
+ * finally marked EMPTY again (possibly by a completion routine).
+ *
+ * A module parameter tells the driver to avoid stalling the bulk
+ * endpoints wherever the transport specification allows.  This is
+ * necessary for some UDCs like the SuperH, which cannot reliably clear a
+ * halt on a bulk endpoint.  However, under certain circumstances the
+ * Bulk-only specification requires a stall.  In such cases the driver
+ * will halt the endpoint and set a flag indicating that it should clear
+ * the halt in software during the next device reset.  Hopefully this
+ * will permit everything to work correctly.  Furthermore, although the
+ * specification allows the bulk-out endpoint to halt when the host sends
+ * too much data, implementing this would cause an unavoidable race.
+ * The driver will always use the "no-stall" approach for OUT transfers.
+ *
+ * One subtle point concerns sending status-stage responses for ep0
+ * requests.  Some of these requests, such as device reset, can involve
+ * interrupting an ongoing file I/O operation, which might take an
+ * arbitrarily long time.  During that delay the host might give up on
+ * the original ep0 request and issue a new one.  When that happens the
+ * driver should not notify the host about completion of the original
+ * request, as the host will no longer be waiting for it.  So the driver
+ * assigns to each ep0 request a unique tag, and it keeps track of the
+ * tag value of the request associated with a long-running exception
+ * (device-reset, interface-change, or configuration-change).  When the
+ * exception handler is finished, the status-stage response is submitted
+ * only if the current ep0 request tag is equal to the exception request
+ * tag.  Thus only the most recently received ep0 request will get a
+ * status-stage response.
+ *
+ * Warning: This driver source file is too long.  It ought to be split up
+ * into a header file plus about 3 separate .c files, to handle the details
+ * of the Gadget, USB Mass Storage, and SCSI protocols.
+ */
+
+
+/* #define VERBOSE_DEBUG */
+/* #define DUMP_MSGS */
+
+
+#include <linux/blkdev.h>
+#include <linux/completion.h>
+#include <linux/dcache.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/fcntl.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/kref.h>
+#include <linux/kthread.h>
+#include <linux/limits.h>
+#include <linux/rwsem.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/freezer.h>
+#include <linux/utsname.h>
+
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+
+#include "gadget_chips.h"
+
+
+
+/*------------------------------------------------------------------------*/
+
+#define FSG_DRIVER_DESC		"Mass Storage Function"
+#define FSG_DRIVER_VERSION	"2009/09/11"
+
+static const char fsg_string_interface[] = "Mass Storage";
+
+
+#define FSG_NO_INTR_EP 1
+#define FSG_BUFFHD_STATIC_BUFFER 1
+#define FSG_NO_DEVICE_STRINGS    1
+#define FSG_NO_OTG               1
+#define FSG_NO_INTR_EP           1
+
+#include "storage_common.c"
+
+
+/*-------------------------------------------------------------------------*/
+
+struct fsg_dev;
+
+
+/* Data shared by all the FSG instances. */
+struct fsg_common {
+	struct usb_gadget	*gadget;
+	struct fsg_dev		*fsg;
+	struct fsg_dev		*prev_fsg;
+
+	/* filesem protects: backing files in use */
+	struct rw_semaphore	filesem;
+
+	/* lock protects: state, all the req_busy's */
+	spinlock_t		lock;
+
+	struct usb_ep		*ep0;		/* Copy of gadget->ep0 */
+	struct usb_request	*ep0req;	/* Copy of cdev->req */
+	unsigned int		ep0_req_tag;
+	const char		*ep0req_name;
+
+	struct fsg_buffhd	*next_buffhd_to_fill;
+	struct fsg_buffhd	*next_buffhd_to_drain;
+	struct fsg_buffhd	buffhds[FSG_NUM_BUFFERS];
+
+	int			cmnd_size;
+	u8			cmnd[MAX_COMMAND_SIZE];
+
+	unsigned int		nluns;
+	unsigned int		lun;
+	struct fsg_lun		*luns;
+	struct fsg_lun		*curlun;
+
+	unsigned int		bulk_out_maxpacket;
+	enum fsg_state		state;		/* For exception handling */
+	unsigned int		exception_req_tag;
+
+	u8			config, new_config;
+	enum data_direction	data_dir;
+	u32			data_size;
+	u32			data_size_from_cmnd;
+	u32			tag;
+	u32			residue;
+	u32			usb_amount_left;
+
+	unsigned int		can_stall:1;
+	unsigned int		free_storage_on_release:1;
+	unsigned int		phase_error:1;
+	unsigned int		short_packet_received:1;
+	unsigned int		bad_lun_okay:1;
+	unsigned int		running:1;
+
+	int			thread_wakeup_needed;
+	struct completion	thread_notifier;
+	struct task_struct	*thread_task;
+
+	/* Callback function to call when thread exits. */
+	void			(*thread_exits)(struct fsg_common *common);
+	/* Gadget's private data. */
+	void			*private_data;
+
+	/* Vendor (8 chars), product (16 chars), release (4
+	 * hexadecimal digits) and NUL byte */
+	char inquiry_string[8 + 16 + 4 + 1];
+
+	struct kref		ref;
+};
+
+
+struct fsg_config {
+	unsigned nluns;
+	struct fsg_lun_config {
+		const char *filename;
+		char ro;
+		char removable;
+		char cdrom;
+	} luns[FSG_MAX_LUNS];
+
+	const char		*lun_name_format;
+	const char		*thread_name;
+
+	/* Callback function to call when thread exits. */
+	void			(*thread_exits)(struct fsg_common *common);
+	/* Gadget's private data. */
+	void			*private_data;
+
+	const char *vendor_name;		/*  8 characters or less */
+	const char *product_name;		/* 16 characters or less */
+	u16 release;
+
+	char			can_stall;
+};
+
+
+struct fsg_dev {
+	struct usb_function	function;
+	struct usb_gadget	*gadget;	/* Copy of cdev->gadget */
+	struct fsg_common	*common;
+
+	u16			interface_number;
+
+	unsigned int		bulk_in_enabled:1;
+	unsigned int		bulk_out_enabled:1;
+
+	unsigned long		atomic_bitflags;
+#define IGNORE_BULK_OUT		0
+
+	struct usb_ep		*bulk_in;
+	struct usb_ep		*bulk_out;
+};
+
+
+static inline int __fsg_is_set(struct fsg_common *common,
+			       const char *func, unsigned line)
+{
+	if (common->fsg)
+		return 1;
+	ERROR(common, "common->fsg is NULL in %s at %u\n", func, line);
+	return 0;
+}
+
+#define fsg_is_set(common) likely(__fsg_is_set(common, __func__, __LINE__))
+
+
+static inline struct fsg_dev *fsg_from_func(struct usb_function *f)
+{
+	return container_of(f, struct fsg_dev, function);
+}
+
+
+typedef void (*fsg_routine_t)(struct fsg_dev *);
+
+static int exception_in_progress(struct fsg_common *common)
+{
+	return common->state > FSG_STATE_IDLE;
+}
+
+/* Make bulk-out requests be divisible by the maxpacket size */
+static void set_bulk_out_req_length(struct fsg_common *common,
+		struct fsg_buffhd *bh, unsigned int length)
+{
+	unsigned int	rem;
+
+	bh->bulk_out_intended_length = length;
+	rem = length % common->bulk_out_maxpacket;
+	if (rem > 0)
+		length += common->bulk_out_maxpacket - rem;
+	bh->outreq->length = length;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep)
+{
+	const char	*name;
+
+	if (ep == fsg->bulk_in)
+		name = "bulk-in";
+	else if (ep == fsg->bulk_out)
+		name = "bulk-out";
+	else
+		name = ep->name;
+	DBG(fsg, "%s set halt\n", name);
+	return usb_ep_set_halt(ep);
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/* These routines may be called in process context or in_irq */
+
+/* Caller must hold fsg->lock */
+static void wakeup_thread(struct fsg_common *common)
+{
+	/* Tell the main thread that something has happened */
+	common->thread_wakeup_needed = 1;
+	if (common->thread_task)
+		wake_up_process(common->thread_task);
+}
+
+
+static void raise_exception(struct fsg_common *common, enum fsg_state new_state)
+{
+	unsigned long		flags;
+
+	/* Do nothing if a higher-priority exception is already in progress.
+	 * If a lower-or-equal priority exception is in progress, preempt it
+	 * and notify the main thread by sending it a signal. */
+	spin_lock_irqsave(&common->lock, flags);
+	if (common->state <= new_state) {
+		common->exception_req_tag = common->ep0_req_tag;
+		common->state = new_state;
+		if (common->thread_task)
+			send_sig_info(SIGUSR1, SEND_SIG_FORCED,
+				      common->thread_task);
+	}
+	spin_unlock_irqrestore(&common->lock, flags);
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static int ep0_queue(struct fsg_common *common)
+{
+	int	rc;
+
+	rc = usb_ep_queue(common->ep0, common->ep0req, GFP_ATOMIC);
+	common->ep0->driver_data = common;
+	if (rc != 0 && rc != -ESHUTDOWN) {
+		/* We can't do much more than wait for a reset */
+		WARNING(common, "error in submission: %s --> %d\n",
+			common->ep0->name, rc);
+	}
+	return rc;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* Bulk and interrupt endpoint completion handlers.
+ * These always run in_irq. */
+
+static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req)
+{
+	struct fsg_common	*common = ep->driver_data;
+	struct fsg_buffhd	*bh = req->context;
+
+	if (req->status || req->actual != req->length)
+		DBG(common, "%s --> %d, %u/%u\n", __func__,
+				req->status, req->actual, req->length);
+	if (req->status == -ECONNRESET)		/* Request was cancelled */
+		usb_ep_fifo_flush(ep);
+
+	/* Hold the lock while we update the request and buffer states */
+	smp_wmb();
+	spin_lock(&common->lock);
+	bh->inreq_busy = 0;
+	bh->state = BUF_STATE_EMPTY;
+	wakeup_thread(common);
+	spin_unlock(&common->lock);
+}
+
+static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
+{
+	struct fsg_common	*common = ep->driver_data;
+	struct fsg_buffhd	*bh = req->context;
+
+	dump_msg(common, "bulk-out", req->buf, req->actual);
+	if (req->status || req->actual != bh->bulk_out_intended_length)
+		DBG(common, "%s --> %d, %u/%u\n", __func__,
+				req->status, req->actual,
+				bh->bulk_out_intended_length);
+	if (req->status == -ECONNRESET)		/* Request was cancelled */
+		usb_ep_fifo_flush(ep);
+
+	/* Hold the lock while we update the request and buffer states */
+	smp_wmb();
+	spin_lock(&common->lock);
+	bh->outreq_busy = 0;
+	bh->state = BUF_STATE_FULL;
+	wakeup_thread(common);
+	spin_unlock(&common->lock);
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/* Ep0 class-specific handlers.  These always run in_irq. */
+
+static int fsg_setup(struct usb_function *f,
+		const struct usb_ctrlrequest *ctrl)
+{
+	struct fsg_dev		*fsg = fsg_from_func(f);
+	struct usb_request	*req = fsg->common->ep0req;
+	u16			w_index = le16_to_cpu(ctrl->wIndex);
+	u16			w_value = le16_to_cpu(ctrl->wValue);
+	u16			w_length = le16_to_cpu(ctrl->wLength);
+
+	if (!fsg->common->config)
+		return -EOPNOTSUPP;
+
+	switch (ctrl->bRequest) {
+
+	case USB_BULK_RESET_REQUEST:
+		if (ctrl->bRequestType !=
+		    (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE))
+			break;
+		if (w_index != fsg->interface_number || w_value != 0)
+			return -EDOM;
+
+		/* Raise an exception to stop the current operation
+		 * and reinitialize our state. */
+		DBG(fsg, "bulk reset request\n");
+		raise_exception(fsg->common, FSG_STATE_RESET);
+		return DELAYED_STATUS;
+
+	case USB_BULK_GET_MAX_LUN_REQUEST:
+		if (ctrl->bRequestType !=
+		    (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE))
+			break;
+		if (w_index != fsg->interface_number || w_value != 0)
+			return -EDOM;
+		VDBG(fsg, "get max LUN\n");
+		*(u8 *) req->buf = fsg->common->nluns - 1;
+		return 1;
+	}
+
+	VDBG(fsg,
+	     "unknown class-specific control req "
+	     "%02x.%02x v%04x i%04x l%u\n",
+	     ctrl->bRequestType, ctrl->bRequest,
+	     le16_to_cpu(ctrl->wValue), w_index, w_length);
+	return -EOPNOTSUPP;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/* All the following routines run in process context */
+
+
+/* Use this for bulk or interrupt transfers, not ep0 */
+static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep,
+		struct usb_request *req, int *pbusy,
+		enum fsg_buffer_state *state)
+{
+	int	rc;
+
+	if (ep == fsg->bulk_in)
+		dump_msg(fsg, "bulk-in", req->buf, req->length);
+
+	spin_lock_irq(&fsg->common->lock);
+	*pbusy = 1;
+	*state = BUF_STATE_BUSY;
+	spin_unlock_irq(&fsg->common->lock);
+	rc = usb_ep_queue(ep, req, GFP_KERNEL);
+	if (rc != 0) {
+		*pbusy = 0;
+		*state = BUF_STATE_EMPTY;
+
+		/* We can't do much more than wait for a reset */
+
+		/* Note: currently the net2280 driver fails zero-length
+		 * submissions if DMA is enabled. */
+		if (rc != -ESHUTDOWN && !(rc == -EOPNOTSUPP &&
+						req->length == 0))
+			WARNING(fsg, "error in submission: %s --> %d\n",
+					ep->name, rc);
+	}
+}
+
+#define START_TRANSFER_OR(common, ep_name, req, pbusy, state)		\
+	if (fsg_is_set(common))						\
+		start_transfer((common)->fsg, (common)->fsg->ep_name,	\
+			       req, pbusy, state);			\
+	else
+
+#define START_TRANSFER(common, ep_name, req, pbusy, state)		\
+	START_TRANSFER_OR(common, ep_name, req, pbusy, state) (void)0
+
+
+
+static int sleep_thread(struct fsg_common *common)
+{
+	int	rc = 0;
+
+	/* Wait until a signal arrives or we are woken up */
+	for (;;) {
+		try_to_freeze();
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (signal_pending(current)) {
+			rc = -EINTR;
+			break;
+		}
+		if (common->thread_wakeup_needed)
+			break;
+		schedule();
+	}
+	__set_current_state(TASK_RUNNING);
+	common->thread_wakeup_needed = 0;
+	return rc;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static int do_read(struct fsg_common *common)
+{
+	struct fsg_lun		*curlun = common->curlun;
+	u32			lba;
+	struct fsg_buffhd	*bh;
+	int			rc;
+	u32			amount_left;
+	loff_t			file_offset, file_offset_tmp;
+	unsigned int		amount;
+	unsigned int		partial_page;
+	ssize_t			nread;
+
+	/* Get the starting Logical Block Address and check that it's
+	 * not too big */
+	if (common->cmnd[0] == SC_READ_6)
+		lba = get_unaligned_be24(&common->cmnd[1]);
+	else {
+		lba = get_unaligned_be32(&common->cmnd[2]);
+
+		/* We allow DPO (Disable Page Out = don't save data in the
+		 * cache) and FUA (Force Unit Access = don't read from the
+		 * cache), but we don't implement them. */
+		if ((common->cmnd[1] & ~0x18) != 0) {
+			curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+			return -EINVAL;
+		}
+	}
+	if (lba >= curlun->num_sectors) {
+		curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+		return -EINVAL;
+	}
+	file_offset = ((loff_t) lba) << 9;
+
+	/* Carry out the file reads */
+	amount_left = common->data_size_from_cmnd;
+	if (unlikely(amount_left == 0))
+		return -EIO;		/* No default reply */
+
+	for (;;) {
+
+		/* Figure out how much we need to read:
+		 * Try to read the remaining amount.
+		 * But don't read more than the buffer size.
+		 * And don't try to read past the end of the file.
+		 * Finally, if we're not at a page boundary, don't read past
+		 *	the next page.
+		 * If this means reading 0 then we were asked to read past
+		 *	the end of file. */
+		amount = min(amount_left, FSG_BUFLEN);
+		amount = min((loff_t) amount,
+				curlun->file_length - file_offset);
+		partial_page = file_offset & (PAGE_CACHE_SIZE - 1);
+		if (partial_page > 0)
+			amount = min(amount, (unsigned int) PAGE_CACHE_SIZE -
+					partial_page);
+
+		/* Wait for the next buffer to become available */
+		bh = common->next_buffhd_to_fill;
+		while (bh->state != BUF_STATE_EMPTY) {
+			rc = sleep_thread(common);
+			if (rc)
+				return rc;
+		}
+
+		/* If we were asked to read past the end of file,
+		 * end with an empty buffer. */
+		if (amount == 0) {
+			curlun->sense_data =
+					SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+			curlun->sense_data_info = file_offset >> 9;
+			curlun->info_valid = 1;
+			bh->inreq->length = 0;
+			bh->state = BUF_STATE_FULL;
+			break;
+		}
+
+		/* Perform the read */
+		file_offset_tmp = file_offset;
+		nread = vfs_read(curlun->filp,
+				(char __user *) bh->buf,
+				amount, &file_offset_tmp);
+		VLDBG(curlun, "file read %u @ %llu -> %d\n", amount,
+				(unsigned long long) file_offset,
+				(int) nread);
+		if (signal_pending(current))
+			return -EINTR;
+
+		if (nread < 0) {
+			LDBG(curlun, "error in file read: %d\n",
+					(int) nread);
+			nread = 0;
+		} else if (nread < amount) {
+			LDBG(curlun, "partial file read: %d/%u\n",
+					(int) nread, amount);
+			nread -= (nread & 511);	/* Round down to a block */
+		}
+		file_offset  += nread;
+		amount_left  -= nread;
+		common->residue -= nread;
+		bh->inreq->length = nread;
+		bh->state = BUF_STATE_FULL;
+
+		/* If an error occurred, report it and its position */
+		if (nread < amount) {
+			curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
+			curlun->sense_data_info = file_offset >> 9;
+			curlun->info_valid = 1;
+			break;
+		}
+
+		if (amount_left == 0)
+			break;		/* No more left to read */
+
+		/* Send this buffer and go read some more */
+		bh->inreq->zero = 0;
+		START_TRANSFER_OR(common, bulk_in, bh->inreq,
+			       &bh->inreq_busy, &bh->state)
+			/* Don't know what to do if
+			 * common->fsg is NULL */
+			return -EIO;
+		common->next_buffhd_to_fill = bh->next;
+	}
+
+	return -EIO;		/* No default reply */
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static int do_write(struct fsg_common *common)
+{
+	struct fsg_lun		*curlun = common->curlun;
+	u32			lba;
+	struct fsg_buffhd	*bh;
+	int			get_some_more;
+	u32			amount_left_to_req, amount_left_to_write;
+	loff_t			usb_offset, file_offset, file_offset_tmp;
+	unsigned int		amount;
+	unsigned int		partial_page;
+	ssize_t			nwritten;
+	int			rc;
+
+	if (curlun->ro) {
+		curlun->sense_data = SS_WRITE_PROTECTED;
+		return -EINVAL;
+	}
+	spin_lock(&curlun->filp->f_lock);
+	curlun->filp->f_flags &= ~O_SYNC;	/* Default is not to wait */
+	spin_unlock(&curlun->filp->f_lock);
+
+	/* Get the starting Logical Block Address and check that it's
+	 * not too big */
+	if (common->cmnd[0] == SC_WRITE_6)
+		lba = get_unaligned_be24(&common->cmnd[1]);
+	else {
+		lba = get_unaligned_be32(&common->cmnd[2]);
+
+		/* We allow DPO (Disable Page Out = don't save data in the
+		 * cache) and FUA (Force Unit Access = write directly to the
+		 * medium).  We don't implement DPO; we implement FUA by
+		 * performing synchronous output. */
+		if (common->cmnd[1] & ~0x18) {
+			curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+			return -EINVAL;
+		}
+		if (common->cmnd[1] & 0x08) {	/* FUA */
+			spin_lock(&curlun->filp->f_lock);
+			curlun->filp->f_flags |= O_SYNC;
+			spin_unlock(&curlun->filp->f_lock);
+		}
+	}
+	if (lba >= curlun->num_sectors) {
+		curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+		return -EINVAL;
+	}
+
+	/* Carry out the file writes */
+	get_some_more = 1;
+	file_offset = usb_offset = ((loff_t) lba) << 9;
+	amount_left_to_req = common->data_size_from_cmnd;
+	amount_left_to_write = common->data_size_from_cmnd;
+
+	while (amount_left_to_write > 0) {
+
+		/* Queue a request for more data from the host */
+		bh = common->next_buffhd_to_fill;
+		if (bh->state == BUF_STATE_EMPTY && get_some_more) {
+
+			/* Figure out how much we want to get:
+			 * Try to get the remaining amount.
+			 * But don't get more than the buffer size.
+			 * And don't try to go past the end of the file.
+			 * If we're not at a page boundary,
+			 *	don't go past the next page.
+			 * If this means getting 0, then we were asked
+			 *	to write past the end of file.
+			 * Finally, round down to a block boundary. */
+			amount = min(amount_left_to_req, FSG_BUFLEN);
+			amount = min((loff_t) amount, curlun->file_length -
+					usb_offset);
+			partial_page = usb_offset & (PAGE_CACHE_SIZE - 1);
+			if (partial_page > 0)
+				amount = min(amount,
+	(unsigned int) PAGE_CACHE_SIZE - partial_page);
+
+			if (amount == 0) {
+				get_some_more = 0;
+				curlun->sense_data =
+					SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+				curlun->sense_data_info = usb_offset >> 9;
+				curlun->info_valid = 1;
+				continue;
+			}
+			amount -= (amount & 511);
+			if (amount == 0) {
+
+				/* Why were we were asked to transfer a
+				 * partial block? */
+				get_some_more = 0;
+				continue;
+			}
+
+			/* Get the next buffer */
+			usb_offset += amount;
+			common->usb_amount_left -= amount;
+			amount_left_to_req -= amount;
+			if (amount_left_to_req == 0)
+				get_some_more = 0;
+
+			/* amount is always divisible by 512, hence by
+			 * the bulk-out maxpacket size */
+			bh->outreq->length = amount;
+			bh->bulk_out_intended_length = amount;
+			bh->outreq->short_not_ok = 1;
+			START_TRANSFER_OR(common, bulk_out, bh->outreq,
+					  &bh->outreq_busy, &bh->state)
+				/* Don't know what to do if
+				 * common->fsg is NULL */
+				return -EIO;
+			common->next_buffhd_to_fill = bh->next;
+			continue;
+		}
+
+		/* Write the received data to the backing file */
+		bh = common->next_buffhd_to_drain;
+		if (bh->state == BUF_STATE_EMPTY && !get_some_more)
+			break;			/* We stopped early */
+		if (bh->state == BUF_STATE_FULL) {
+			smp_rmb();
+			common->next_buffhd_to_drain = bh->next;
+			bh->state = BUF_STATE_EMPTY;
+
+			/* Did something go wrong with the transfer? */
+			if (bh->outreq->status != 0) {
+				curlun->sense_data = SS_COMMUNICATION_FAILURE;
+				curlun->sense_data_info = file_offset >> 9;
+				curlun->info_valid = 1;
+				break;
+			}
+
+			amount = bh->outreq->actual;
+			if (curlun->file_length - file_offset < amount) {
+				LERROR(curlun,
+	"write %u @ %llu beyond end %llu\n",
+	amount, (unsigned long long) file_offset,
+	(unsigned long long) curlun->file_length);
+				amount = curlun->file_length - file_offset;
+			}
+
+			/* Perform the write */
+			file_offset_tmp = file_offset;
+			nwritten = vfs_write(curlun->filp,
+					(char __user *) bh->buf,
+					amount, &file_offset_tmp);
+			VLDBG(curlun, "file write %u @ %llu -> %d\n", amount,
+					(unsigned long long) file_offset,
+					(int) nwritten);
+			if (signal_pending(current))
+				return -EINTR;		/* Interrupted! */
+
+			if (nwritten < 0) {
+				LDBG(curlun, "error in file write: %d\n",
+						(int) nwritten);
+				nwritten = 0;
+			} else if (nwritten < amount) {
+				LDBG(curlun, "partial file write: %d/%u\n",
+						(int) nwritten, amount);
+				nwritten -= (nwritten & 511);
+				/* Round down to a block */
+			}
+			file_offset += nwritten;
+			amount_left_to_write -= nwritten;
+			common->residue -= nwritten;
+
+			/* If an error occurred, report it and its position */
+			if (nwritten < amount) {
+				curlun->sense_data = SS_WRITE_ERROR;
+				curlun->sense_data_info = file_offset >> 9;
+				curlun->info_valid = 1;
+				break;
+			}
+
+			/* Did the host decide to stop early? */
+			if (bh->outreq->actual != bh->outreq->length) {
+				common->short_packet_received = 1;
+				break;
+			}
+			continue;
+		}
+
+		/* Wait for something to happen */
+		rc = sleep_thread(common);
+		if (rc)
+			return rc;
+	}
+
+	return -EIO;		/* No default reply */
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static int do_synchronize_cache(struct fsg_common *common)
+{
+	struct fsg_lun	*curlun = common->curlun;
+	int		rc;
+
+	/* We ignore the requested LBA and write out all file's
+	 * dirty data buffers. */
+	rc = fsg_lun_fsync_sub(curlun);
+	if (rc)
+		curlun->sense_data = SS_WRITE_ERROR;
+	return 0;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static void invalidate_sub(struct fsg_lun *curlun)
+{
+	struct file	*filp = curlun->filp;
+	struct inode	*inode = filp->f_path.dentry->d_inode;
+	unsigned long	rc;
+
+	rc = invalidate_mapping_pages(inode->i_mapping, 0, -1);
+	VLDBG(curlun, "invalidate_inode_pages -> %ld\n", rc);
+}
+
+static int do_verify(struct fsg_common *common)
+{
+	struct fsg_lun		*curlun = common->curlun;
+	u32			lba;
+	u32			verification_length;
+	struct fsg_buffhd	*bh = common->next_buffhd_to_fill;
+	loff_t			file_offset, file_offset_tmp;
+	u32			amount_left;
+	unsigned int		amount;
+	ssize_t			nread;
+
+	/* Get the starting Logical Block Address and check that it's
+	 * not too big */
+	lba = get_unaligned_be32(&common->cmnd[2]);
+	if (lba >= curlun->num_sectors) {
+		curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+		return -EINVAL;
+	}
+
+	/* We allow DPO (Disable Page Out = don't save data in the
+	 * cache) but we don't implement it. */
+	if (common->cmnd[1] & ~0x10) {
+		curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+		return -EINVAL;
+	}
+
+	verification_length = get_unaligned_be16(&common->cmnd[7]);
+	if (unlikely(verification_length == 0))
+		return -EIO;		/* No default reply */
+
+	/* Prepare to carry out the file verify */
+	amount_left = verification_length << 9;
+	file_offset = ((loff_t) lba) << 9;
+
+	/* Write out all the dirty buffers before invalidating them */
+	fsg_lun_fsync_sub(curlun);
+	if (signal_pending(current))
+		return -EINTR;
+
+	invalidate_sub(curlun);
+	if (signal_pending(current))
+		return -EINTR;
+
+	/* Just try to read the requested blocks */
+	while (amount_left > 0) {
+
+		/* Figure out how much we need to read:
+		 * Try to read the remaining amount, but not more than
+		 * the buffer size.
+		 * And don't try to read past the end of the file.
+		 * If this means reading 0 then we were asked to read
+		 * past the end of file. */
+		amount = min(amount_left, FSG_BUFLEN);
+		amount = min((loff_t) amount,
+				curlun->file_length - file_offset);
+		if (amount == 0) {
+			curlun->sense_data =
+					SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+			curlun->sense_data_info = file_offset >> 9;
+			curlun->info_valid = 1;
+			break;
+		}
+
+		/* Perform the read */
+		file_offset_tmp = file_offset;
+		nread = vfs_read(curlun->filp,
+				(char __user *) bh->buf,
+				amount, &file_offset_tmp);
+		VLDBG(curlun, "file read %u @ %llu -> %d\n", amount,
+				(unsigned long long) file_offset,
+				(int) nread);
+		if (signal_pending(current))
+			return -EINTR;
+
+		if (nread < 0) {
+			LDBG(curlun, "error in file verify: %d\n",
+					(int) nread);
+			nread = 0;
+		} else if (nread < amount) {
+			LDBG(curlun, "partial file verify: %d/%u\n",
+					(int) nread, amount);
+			nread -= (nread & 511);	/* Round down to a sector */
+		}
+		if (nread == 0) {
+			curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
+			curlun->sense_data_info = file_offset >> 9;
+			curlun->info_valid = 1;
+			break;
+		}
+		file_offset += nread;
+		amount_left -= nread;
+	}
+	return 0;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static int do_inquiry(struct fsg_common *common, struct fsg_buffhd *bh)
+{
+	struct fsg_lun *curlun = common->curlun;
+	u8	*buf = (u8 *) bh->buf;
+
+	if (!curlun) {		/* Unsupported LUNs are okay */
+		common->bad_lun_okay = 1;
+		memset(buf, 0, 36);
+		buf[0] = 0x7f;		/* Unsupported, no device-type */
+		buf[4] = 31;		/* Additional length */
+		return 36;
+	}
+
+	buf[0] = curlun->cdrom ? TYPE_CDROM : TYPE_DISK;
+	buf[1] = curlun->removable ? 0x80 : 0;
+	buf[2] = 2;		/* ANSI SCSI level 2 */
+	buf[3] = 2;		/* SCSI-2 INQUIRY data format */
+	buf[4] = 31;		/* Additional length */
+	buf[5] = 0;		/* No special options */
+	buf[6] = 0;
+	buf[7] = 0;
+	memcpy(buf + 8, common->inquiry_string, sizeof common->inquiry_string);
+	return 36;
+}
+
+
+static int do_request_sense(struct fsg_common *common, struct fsg_buffhd *bh)
+{
+	struct fsg_lun	*curlun = common->curlun;
+	u8		*buf = (u8 *) bh->buf;
+	u32		sd, sdinfo;
+	int		valid;
+
+	/*
+	 * From the SCSI-2 spec., section 7.9 (Unit attention condition):
+	 *
+	 * If a REQUEST SENSE command is received from an initiator
+	 * with a pending unit attention condition (before the target
+	 * generates the contingent allegiance condition), then the
+	 * target shall either:
+	 *   a) report any pending sense data and preserve the unit
+	 *	attention condition on the logical unit, or,
+	 *   b) report the unit attention condition, may discard any
+	 *	pending sense data, and clear the unit attention
+	 *	condition on the logical unit for that initiator.
+	 *
+	 * FSG normally uses option a); enable this code to use option b).
+	 */
+#if 0
+	if (curlun && curlun->unit_attention_data != SS_NO_SENSE) {
+		curlun->sense_data = curlun->unit_attention_data;
+		curlun->unit_attention_data = SS_NO_SENSE;
+	}
+#endif
+
+	if (!curlun) {		/* Unsupported LUNs are okay */
+		common->bad_lun_okay = 1;
+		sd = SS_LOGICAL_UNIT_NOT_SUPPORTED;
+		sdinfo = 0;
+		valid = 0;
+	} else {
+		sd = curlun->sense_data;
+		sdinfo = curlun->sense_data_info;
+		valid = curlun->info_valid << 7;
+		curlun->sense_data = SS_NO_SENSE;
+		curlun->sense_data_info = 0;
+		curlun->info_valid = 0;
+	}
+
+	memset(buf, 0, 18);
+	buf[0] = valid | 0x70;			/* Valid, current error */
+	buf[2] = SK(sd);
+	put_unaligned_be32(sdinfo, &buf[3]);	/* Sense information */
+	buf[7] = 18 - 8;			/* Additional sense length */
+	buf[12] = ASC(sd);
+	buf[13] = ASCQ(sd);
+	return 18;
+}
+
+
+static int do_read_capacity(struct fsg_common *common, struct fsg_buffhd *bh)
+{
+	struct fsg_lun	*curlun = common->curlun;
+	u32		lba = get_unaligned_be32(&common->cmnd[2]);
+	int		pmi = common->cmnd[8];
+	u8		*buf = (u8 *) bh->buf;
+
+	/* Check the PMI and LBA fields */
+	if (pmi > 1 || (pmi == 0 && lba != 0)) {
+		curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+		return -EINVAL;
+	}
+
+	put_unaligned_be32(curlun->num_sectors - 1, &buf[0]);
+						/* Max logical block */
+	put_unaligned_be32(512, &buf[4]);	/* Block length */
+	return 8;
+}
+
+
+static int do_read_header(struct fsg_common *common, struct fsg_buffhd *bh)
+{
+	struct fsg_lun	*curlun = common->curlun;
+	int		msf = common->cmnd[1] & 0x02;
+	u32		lba = get_unaligned_be32(&common->cmnd[2]);
+	u8		*buf = (u8 *) bh->buf;
+
+	if (common->cmnd[1] & ~0x02) {		/* Mask away MSF */
+		curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+		return -EINVAL;
+	}
+	if (lba >= curlun->num_sectors) {
+		curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+		return -EINVAL;
+	}
+
+	memset(buf, 0, 8);
+	buf[0] = 0x01;		/* 2048 bytes of user data, rest is EC */
+	store_cdrom_address(&buf[4], msf, lba);
+	return 8;
+}
+
+
+static int do_read_toc(struct fsg_common *common, struct fsg_buffhd *bh)
+{
+	struct fsg_lun	*curlun = common->curlun;
+	int		msf = common->cmnd[1] & 0x02;
+	int		start_track = common->cmnd[6];
+	u8		*buf = (u8 *) bh->buf;
+
+	if ((common->cmnd[1] & ~0x02) != 0 ||	/* Mask away MSF */
+			start_track > 1) {
+		curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+		return -EINVAL;
+	}
+
+	memset(buf, 0, 20);
+	buf[1] = (20-2);		/* TOC data length */
+	buf[2] = 1;			/* First track number */
+	buf[3] = 1;			/* Last track number */
+	buf[5] = 0x16;			/* Data track, copying allowed */
+	buf[6] = 0x01;			/* Only track is number 1 */
+	store_cdrom_address(&buf[8], msf, 0);
+
+	buf[13] = 0x16;			/* Lead-out track is data */
+	buf[14] = 0xAA;			/* Lead-out track number */
+	store_cdrom_address(&buf[16], msf, curlun->num_sectors);
+	return 20;
+}
+
+
+static int do_mode_sense(struct fsg_common *common, struct fsg_buffhd *bh)
+{
+	struct fsg_lun	*curlun = common->curlun;
+	int		mscmnd = common->cmnd[0];
+	u8		*buf = (u8 *) bh->buf;
+	u8		*buf0 = buf;
+	int		pc, page_code;
+	int		changeable_values, all_pages;
+	int		valid_page = 0;
+	int		len, limit;
+
+	if ((common->cmnd[1] & ~0x08) != 0) {	/* Mask away DBD */
+		curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+		return -EINVAL;
+	}
+	pc = common->cmnd[2] >> 6;
+	page_code = common->cmnd[2] & 0x3f;
+	if (pc == 3) {
+		curlun->sense_data = SS_SAVING_PARAMETERS_NOT_SUPPORTED;
+		return -EINVAL;
+	}
+	changeable_values = (pc == 1);
+	all_pages = (page_code == 0x3f);
+
+	/* Write the mode parameter header.  Fixed values are: default
+	 * medium type, no cache control (DPOFUA), and no block descriptors.
+	 * The only variable value is the WriteProtect bit.  We will fill in
+	 * the mode data length later. */
+	memset(buf, 0, 8);
+	if (mscmnd == SC_MODE_SENSE_6) {
+		buf[2] = (curlun->ro ? 0x80 : 0x00);		/* WP, DPOFUA */
+		buf += 4;
+		limit = 255;
+	} else {			/* SC_MODE_SENSE_10 */
+		buf[3] = (curlun->ro ? 0x80 : 0x00);		/* WP, DPOFUA */
+		buf += 8;
+		limit = 65535;		/* Should really be FSG_BUFLEN */
+	}
+
+	/* No block descriptors */
+
+	/* The mode pages, in numerical order.  The only page we support
+	 * is the Caching page. */
+	if (page_code == 0x08 || all_pages) {
+		valid_page = 1;
+		buf[0] = 0x08;		/* Page code */
+		buf[1] = 10;		/* Page length */
+		memset(buf+2, 0, 10);	/* None of the fields are changeable */
+
+		if (!changeable_values) {
+			buf[2] = 0x04;	/* Write cache enable, */
+					/* Read cache not disabled */
+					/* No cache retention priorities */
+			put_unaligned_be16(0xffff, &buf[4]);
+					/* Don't disable prefetch */
+					/* Minimum prefetch = 0 */
+			put_unaligned_be16(0xffff, &buf[8]);
+					/* Maximum prefetch */
+			put_unaligned_be16(0xffff, &buf[10]);
+					/* Maximum prefetch ceiling */
+		}
+		buf += 12;
+	}
+
+	/* Check that a valid page was requested and the mode data length
+	 * isn't too long. */
+	len = buf - buf0;
+	if (!valid_page || len > limit) {
+		curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+		return -EINVAL;
+	}
+
+	/*  Store the mode data length */
+	if (mscmnd == SC_MODE_SENSE_6)
+		buf0[0] = len - 1;
+	else
+		put_unaligned_be16(len - 2, buf0);
+	return len;
+}
+
+
+static int do_start_stop(struct fsg_common *common)
+{
+	if (!common->curlun) {
+		return -EINVAL;
+	} else if (!common->curlun->removable) {
+		common->curlun->sense_data = SS_INVALID_COMMAND;
+		return -EINVAL;
+	}
+	return 0;
+}
+
+
+static int do_prevent_allow(struct fsg_common *common)
+{
+	struct fsg_lun	*curlun = common->curlun;
+	int		prevent;
+
+	if (!common->curlun) {
+		return -EINVAL;
+	} else if (!common->curlun->removable) {
+		common->curlun->sense_data = SS_INVALID_COMMAND;
+		return -EINVAL;
+	}
+
+	prevent = common->cmnd[4] & 0x01;
+	if ((common->cmnd[4] & ~0x01) != 0) {	/* Mask away Prevent */
+		curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+		return -EINVAL;
+	}
+
+	if (curlun->prevent_medium_removal && !prevent)
+		fsg_lun_fsync_sub(curlun);
+	curlun->prevent_medium_removal = prevent;
+	return 0;
+}
+
+
+static int do_read_format_capacities(struct fsg_common *common,
+			struct fsg_buffhd *bh)
+{
+	struct fsg_lun	*curlun = common->curlun;
+	u8		*buf = (u8 *) bh->buf;
+
+	buf[0] = buf[1] = buf[2] = 0;
+	buf[3] = 8;	/* Only the Current/Maximum Capacity Descriptor */
+	buf += 4;
+
+	put_unaligned_be32(curlun->num_sectors, &buf[0]);
+						/* Number of blocks */
+	put_unaligned_be32(512, &buf[4]);	/* Block length */
+	buf[4] = 0x02;				/* Current capacity */
+	return 12;
+}
+
+
+static int do_mode_select(struct fsg_common *common, struct fsg_buffhd *bh)
+{
+	struct fsg_lun	*curlun = common->curlun;
+
+	/* We don't support MODE SELECT */
+	if (curlun)
+		curlun->sense_data = SS_INVALID_COMMAND;
+	return -EINVAL;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static int halt_bulk_in_endpoint(struct fsg_dev *fsg)
+{
+	int	rc;
+
+	rc = fsg_set_halt(fsg, fsg->bulk_in);
+	if (rc == -EAGAIN)
+		VDBG(fsg, "delayed bulk-in endpoint halt\n");
+	while (rc != 0) {
+		if (rc != -EAGAIN) {
+			WARNING(fsg, "usb_ep_set_halt -> %d\n", rc);
+			rc = 0;
+			break;
+		}
+
+		/* Wait for a short time and then try again */
+		if (msleep_interruptible(100) != 0)
+			return -EINTR;
+		rc = usb_ep_set_halt(fsg->bulk_in);
+	}
+	return rc;
+}
+
+static int wedge_bulk_in_endpoint(struct fsg_dev *fsg)
+{
+	int	rc;
+
+	DBG(fsg, "bulk-in set wedge\n");
+	rc = usb_ep_set_wedge(fsg->bulk_in);
+	if (rc == -EAGAIN)
+		VDBG(fsg, "delayed bulk-in endpoint wedge\n");
+	while (rc != 0) {
+		if (rc != -EAGAIN) {
+			WARNING(fsg, "usb_ep_set_wedge -> %d\n", rc);
+			rc = 0;
+			break;
+		}
+
+		/* Wait for a short time and then try again */
+		if (msleep_interruptible(100) != 0)
+			return -EINTR;
+		rc = usb_ep_set_wedge(fsg->bulk_in);
+	}
+	return rc;
+}
+
+static int pad_with_zeros(struct fsg_dev *fsg)
+{
+	struct fsg_buffhd	*bh = fsg->common->next_buffhd_to_fill;
+	u32			nkeep = bh->inreq->length;
+	u32			nsend;
+	int			rc;
+
+	bh->state = BUF_STATE_EMPTY;		/* For the first iteration */
+	fsg->common->usb_amount_left = nkeep + fsg->common->residue;
+	while (fsg->common->usb_amount_left > 0) {
+
+		/* Wait for the next buffer to be free */
+		while (bh->state != BUF_STATE_EMPTY) {
+			rc = sleep_thread(fsg->common);
+			if (rc)
+				return rc;
+		}
+
+		nsend = min(fsg->common->usb_amount_left, FSG_BUFLEN);
+		memset(bh->buf + nkeep, 0, nsend - nkeep);
+		bh->inreq->length = nsend;
+		bh->inreq->zero = 0;
+		start_transfer(fsg, fsg->bulk_in, bh->inreq,
+				&bh->inreq_busy, &bh->state);
+		bh = fsg->common->next_buffhd_to_fill = bh->next;
+		fsg->common->usb_amount_left -= nsend;
+		nkeep = 0;
+	}
+	return 0;
+}
+
+static int throw_away_data(struct fsg_common *common)
+{
+	struct fsg_buffhd	*bh;
+	u32			amount;
+	int			rc;
+
+	for (bh = common->next_buffhd_to_drain;
+	     bh->state != BUF_STATE_EMPTY || common->usb_amount_left > 0;
+	     bh = common->next_buffhd_to_drain) {
+
+		/* Throw away the data in a filled buffer */
+		if (bh->state == BUF_STATE_FULL) {
+			smp_rmb();
+			bh->state = BUF_STATE_EMPTY;
+			common->next_buffhd_to_drain = bh->next;
+
+			/* A short packet or an error ends everything */
+			if (bh->outreq->actual != bh->outreq->length ||
+					bh->outreq->status != 0) {
+				raise_exception(common,
+						FSG_STATE_ABORT_BULK_OUT);
+				return -EINTR;
+			}
+			continue;
+		}
+
+		/* Try to submit another request if we need one */
+		bh = common->next_buffhd_to_fill;
+		if (bh->state == BUF_STATE_EMPTY
+		 && common->usb_amount_left > 0) {
+			amount = min(common->usb_amount_left, FSG_BUFLEN);
+
+			/* amount is always divisible by 512, hence by
+			 * the bulk-out maxpacket size */
+			bh->outreq->length = amount;
+			bh->bulk_out_intended_length = amount;
+			bh->outreq->short_not_ok = 1;
+			START_TRANSFER_OR(common, bulk_out, bh->outreq,
+					  &bh->outreq_busy, &bh->state)
+				/* Don't know what to do if
+				 * common->fsg is NULL */
+				return -EIO;
+			common->next_buffhd_to_fill = bh->next;
+			common->usb_amount_left -= amount;
+			continue;
+		}
+
+		/* Otherwise wait for something to happen */
+		rc = sleep_thread(common);
+		if (rc)
+			return rc;
+	}
+	return 0;
+}
+
+
+static int finish_reply(struct fsg_common *common)
+{
+	struct fsg_buffhd	*bh = common->next_buffhd_to_fill;
+	int			rc = 0;
+
+	switch (common->data_dir) {
+	case DATA_DIR_NONE:
+		break;			/* Nothing to send */
+
+	/* If we don't know whether the host wants to read or write,
+	 * this must be CB or CBI with an unknown command.  We mustn't
+	 * try to send or receive any data.  So stall both bulk pipes
+	 * if we can and wait for a reset. */
+	case DATA_DIR_UNKNOWN:
+		if (!common->can_stall) {
+			/* Nothing */
+		} else if (fsg_is_set(common)) {
+			fsg_set_halt(common->fsg, common->fsg->bulk_out);
+			rc = halt_bulk_in_endpoint(common->fsg);
+		} else {
+			/* Don't know what to do if common->fsg is NULL */
+			rc = -EIO;
+		}
+		break;
+
+	/* All but the last buffer of data must have already been sent */
+	case DATA_DIR_TO_HOST:
+		if (common->data_size == 0) {
+			/* Nothing to send */
+
+		/* If there's no residue, simply send the last buffer */
+		} else if (common->residue == 0) {
+			bh->inreq->zero = 0;
+			START_TRANSFER_OR(common, bulk_in, bh->inreq,
+					  &bh->inreq_busy, &bh->state)
+				return -EIO;
+			common->next_buffhd_to_fill = bh->next;
+
+		/* For Bulk-only, if we're allowed to stall then send the
+		 * short packet and halt the bulk-in endpoint.  If we can't
+		 * stall, pad out the remaining data with 0's. */
+		} else if (common->can_stall) {
+			bh->inreq->zero = 1;
+			START_TRANSFER_OR(common, bulk_in, bh->inreq,
+					  &bh->inreq_busy, &bh->state)
+				/* Don't know what to do if
+				 * common->fsg is NULL */
+				rc = -EIO;
+			common->next_buffhd_to_fill = bh->next;
+			if (common->fsg)
+				rc = halt_bulk_in_endpoint(common->fsg);
+		} else if (fsg_is_set(common)) {
+			rc = pad_with_zeros(common->fsg);
+		} else {
+			/* Don't know what to do if common->fsg is NULL */
+			rc = -EIO;
+		}
+		break;
+
+	/* We have processed all we want from the data the host has sent.
+	 * There may still be outstanding bulk-out requests. */
+	case DATA_DIR_FROM_HOST:
+		if (common->residue == 0) {
+			/* Nothing to receive */
+
+		/* Did the host stop sending unexpectedly early? */
+		} else if (common->short_packet_received) {
+			raise_exception(common, FSG_STATE_ABORT_BULK_OUT);
+			rc = -EINTR;
+
+		/* We haven't processed all the incoming data.  Even though
+		 * we may be allowed to stall, doing so would cause a race.
+		 * The controller may already have ACK'ed all the remaining
+		 * bulk-out packets, in which case the host wouldn't see a
+		 * STALL.  Not realizing the endpoint was halted, it wouldn't
+		 * clear the halt -- leading to problems later on. */
+#if 0
+		} else if (common->can_stall) {
+			if (fsg_is_set(common))
+				fsg_set_halt(common->fsg,
+					     common->fsg->bulk_out);
+			raise_exception(common, FSG_STATE_ABORT_BULK_OUT);
+			rc = -EINTR;
+#endif
+
+		/* We can't stall.  Read in the excess data and throw it
+		 * all away. */
+		} else {
+			rc = throw_away_data(common);
+		}
+		break;
+	}
+	return rc;
+}
+
+
+static int send_status(struct fsg_common *common)
+{
+	struct fsg_lun		*curlun = common->curlun;
+	struct fsg_buffhd	*bh;
+	struct bulk_cs_wrap	*csw;
+	int			rc;
+	u8			status = USB_STATUS_PASS;
+	u32			sd, sdinfo = 0;
+
+	/* Wait for the next buffer to become available */
+	bh = common->next_buffhd_to_fill;
+	while (bh->state != BUF_STATE_EMPTY) {
+		rc = sleep_thread(common);
+		if (rc)
+			return rc;
+	}
+
+	if (curlun) {
+		sd = curlun->sense_data;
+		sdinfo = curlun->sense_data_info;
+	} else if (common->bad_lun_okay)
+		sd = SS_NO_SENSE;
+	else
+		sd = SS_LOGICAL_UNIT_NOT_SUPPORTED;
+
+	if (common->phase_error) {
+		DBG(common, "sending phase-error status\n");
+		status = USB_STATUS_PHASE_ERROR;
+		sd = SS_INVALID_COMMAND;
+	} else if (sd != SS_NO_SENSE) {
+		DBG(common, "sending command-failure status\n");
+		status = USB_STATUS_FAIL;
+		VDBG(common, "  sense data: SK x%02x, ASC x%02x, ASCQ x%02x;"
+				"  info x%x\n",
+				SK(sd), ASC(sd), ASCQ(sd), sdinfo);
+	}
+
+	/* Store and send the Bulk-only CSW */
+	csw = (void *)bh->buf;
+
+	csw->Signature = cpu_to_le32(USB_BULK_CS_SIG);
+	csw->Tag = common->tag;
+	csw->Residue = cpu_to_le32(common->residue);
+	csw->Status = status;
+
+	bh->inreq->length = USB_BULK_CS_WRAP_LEN;
+	bh->inreq->zero = 0;
+	START_TRANSFER_OR(common, bulk_in, bh->inreq,
+			  &bh->inreq_busy, &bh->state)
+		/* Don't know what to do if common->fsg is NULL */
+		return -EIO;
+
+	common->next_buffhd_to_fill = bh->next;
+	return 0;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/* Check whether the command is properly formed and whether its data size
+ * and direction agree with the values we already have. */
+static int check_command(struct fsg_common *common, int cmnd_size,
+		enum data_direction data_dir, unsigned int mask,
+		int needs_medium, const char *name)
+{
+	int			i;
+	int			lun = common->cmnd[1] >> 5;
+	static const char	dirletter[4] = {'u', 'o', 'i', 'n'};
+	char			hdlen[20];
+	struct fsg_lun		*curlun;
+
+	hdlen[0] = 0;
+	if (common->data_dir != DATA_DIR_UNKNOWN)
+		sprintf(hdlen, ", H%c=%u", dirletter[(int) common->data_dir],
+				common->data_size);
+	VDBG(common, "SCSI command: %s;  Dc=%d, D%c=%u;  Hc=%d%s\n",
+	     name, cmnd_size, dirletter[(int) data_dir],
+	     common->data_size_from_cmnd, common->cmnd_size, hdlen);
+
+	/* We can't reply at all until we know the correct data direction
+	 * and size. */
+	if (common->data_size_from_cmnd == 0)
+		data_dir = DATA_DIR_NONE;
+	if (common->data_size < common->data_size_from_cmnd) {
+		/* Host data size < Device data size is a phase error.
+		 * Carry out the command, but only transfer as much as
+		 * we are allowed. */
+		common->data_size_from_cmnd = common->data_size;
+		common->phase_error = 1;
+	}
+	common->residue = common->data_size;
+	common->usb_amount_left = common->data_size;
+
+	/* Conflicting data directions is a phase error */
+	if (common->data_dir != data_dir
+	 && common->data_size_from_cmnd > 0) {
+		common->phase_error = 1;
+		return -EINVAL;
+	}
+
+	/* Verify the length of the command itself */
+	if (cmnd_size != common->cmnd_size) {
+
+		/* Special case workaround: There are plenty of buggy SCSI
+		 * implementations. Many have issues with cbw->Length
+		 * field passing a wrong command size. For those cases we
+		 * always try to work around the problem by using the length
+		 * sent by the host side provided it is at least as large
+		 * as the correct command length.
+		 * Examples of such cases would be MS-Windows, which issues
+		 * REQUEST SENSE with cbw->Length == 12 where it should
+		 * be 6, and xbox360 issuing INQUIRY, TEST UNIT READY and
+		 * REQUEST SENSE with cbw->Length == 10 where it should
+		 * be 6 as well.
+		 */
+		if (cmnd_size <= common->cmnd_size) {
+			DBG(common, "%s is buggy! Expected length %d "
+			    "but we got %d\n", name,
+			    cmnd_size, common->cmnd_size);
+			cmnd_size = common->cmnd_size;
+		} else {
+			common->phase_error = 1;
+			return -EINVAL;
+		}
+	}
+
+	/* Check that the LUN values are consistent */
+	if (common->lun != lun)
+		DBG(common, "using LUN %d from CBW, not LUN %d from CDB\n",
+		    common->lun, lun);
+
+	/* Check the LUN */
+	if (common->lun >= 0 && common->lun < common->nluns) {
+		curlun = &common->luns[common->lun];
+		common->curlun = curlun;
+		if (common->cmnd[0] != SC_REQUEST_SENSE) {
+			curlun->sense_data = SS_NO_SENSE;
+			curlun->sense_data_info = 0;
+			curlun->info_valid = 0;
+		}
+	} else {
+		common->curlun = NULL;
+		curlun = NULL;
+		common->bad_lun_okay = 0;
+
+		/* INQUIRY and REQUEST SENSE commands are explicitly allowed
+		 * to use unsupported LUNs; all others may not. */
+		if (common->cmnd[0] != SC_INQUIRY &&
+		    common->cmnd[0] != SC_REQUEST_SENSE) {
+			DBG(common, "unsupported LUN %d\n", common->lun);
+			return -EINVAL;
+		}
+	}
+
+	/* If a unit attention condition exists, only INQUIRY and
+	 * REQUEST SENSE commands are allowed; anything else must fail. */
+	if (curlun && curlun->unit_attention_data != SS_NO_SENSE &&
+			common->cmnd[0] != SC_INQUIRY &&
+			common->cmnd[0] != SC_REQUEST_SENSE) {
+		curlun->sense_data = curlun->unit_attention_data;
+		curlun->unit_attention_data = SS_NO_SENSE;
+		return -EINVAL;
+	}
+
+	/* Check that only command bytes listed in the mask are non-zero */
+	common->cmnd[1] &= 0x1f;			/* Mask away the LUN */
+	for (i = 1; i < cmnd_size; ++i) {
+		if (common->cmnd[i] && !(mask & (1 << i))) {
+			if (curlun)
+				curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+			return -EINVAL;
+		}
+	}
+
+	/* If the medium isn't mounted and the command needs to access
+	 * it, return an error. */
+	if (curlun && !fsg_lun_is_open(curlun) && needs_medium) {
+		curlun->sense_data = SS_MEDIUM_NOT_PRESENT;
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+
+static int do_scsi_command(struct fsg_common *common)
+{
+	struct fsg_buffhd	*bh;
+	int			rc;
+	int			reply = -EINVAL;
+	int			i;
+	static char		unknown[16];
+
+	dump_cdb(common);
+
+	/* Wait for the next buffer to become available for data or status */
+	bh = common->next_buffhd_to_fill;
+	common->next_buffhd_to_drain = bh;
+	while (bh->state != BUF_STATE_EMPTY) {
+		rc = sleep_thread(common);
+		if (rc)
+			return rc;
+	}
+	common->phase_error = 0;
+	common->short_packet_received = 0;
+
+	down_read(&common->filesem);	/* We're using the backing file */
+	switch (common->cmnd[0]) {
+
+	case SC_INQUIRY:
+		common->data_size_from_cmnd = common->cmnd[4];
+		reply = check_command(common, 6, DATA_DIR_TO_HOST,
+				      (1<<4), 0,
+				      "INQUIRY");
+		if (reply == 0)
+			reply = do_inquiry(common, bh);
+		break;
+
+	case SC_MODE_SELECT_6:
+		common->data_size_from_cmnd = common->cmnd[4];
+		reply = check_command(common, 6, DATA_DIR_FROM_HOST,
+				      (1<<1) | (1<<4), 0,
+				      "MODE SELECT(6)");
+		if (reply == 0)
+			reply = do_mode_select(common, bh);
+		break;
+
+	case SC_MODE_SELECT_10:
+		common->data_size_from_cmnd =
+			get_unaligned_be16(&common->cmnd[7]);
+		reply = check_command(common, 10, DATA_DIR_FROM_HOST,
+				      (1<<1) | (3<<7), 0,
+				      "MODE SELECT(10)");
+		if (reply == 0)
+			reply = do_mode_select(common, bh);
+		break;
+
+	case SC_MODE_SENSE_6:
+		common->data_size_from_cmnd = common->cmnd[4];
+		reply = check_command(common, 6, DATA_DIR_TO_HOST,
+				      (1<<1) | (1<<2) | (1<<4), 0,
+				      "MODE SENSE(6)");
+		if (reply == 0)
+			reply = do_mode_sense(common, bh);
+		break;
+
+	case SC_MODE_SENSE_10:
+		common->data_size_from_cmnd =
+			get_unaligned_be16(&common->cmnd[7]);
+		reply = check_command(common, 10, DATA_DIR_TO_HOST,
+				      (1<<1) | (1<<2) | (3<<7), 0,
+				      "MODE SENSE(10)");
+		if (reply == 0)
+			reply = do_mode_sense(common, bh);
+		break;
+
+	case SC_PREVENT_ALLOW_MEDIUM_REMOVAL:
+		common->data_size_from_cmnd = 0;
+		reply = check_command(common, 6, DATA_DIR_NONE,
+				      (1<<4), 0,
+				      "PREVENT-ALLOW MEDIUM REMOVAL");
+		if (reply == 0)
+			reply = do_prevent_allow(common);
+		break;
+
+	case SC_READ_6:
+		i = common->cmnd[4];
+		common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
+		reply = check_command(common, 6, DATA_DIR_TO_HOST,
+				      (7<<1) | (1<<4), 1,
+				      "READ(6)");
+		if (reply == 0)
+			reply = do_read(common);
+		break;
+
+	case SC_READ_10:
+		common->data_size_from_cmnd =
+				get_unaligned_be16(&common->cmnd[7]) << 9;
+		reply = check_command(common, 10, DATA_DIR_TO_HOST,
+				      (1<<1) | (0xf<<2) | (3<<7), 1,
+				      "READ(10)");
+		if (reply == 0)
+			reply = do_read(common);
+		break;
+
+	case SC_READ_12:
+		common->data_size_from_cmnd =
+				get_unaligned_be32(&common->cmnd[6]) << 9;
+		reply = check_command(common, 12, DATA_DIR_TO_HOST,
+				      (1<<1) | (0xf<<2) | (0xf<<6), 1,
+				      "READ(12)");
+		if (reply == 0)
+			reply = do_read(common);
+		break;
+
+	case SC_READ_CAPACITY:
+		common->data_size_from_cmnd = 8;
+		reply = check_command(common, 10, DATA_DIR_TO_HOST,
+				      (0xf<<2) | (1<<8), 1,
+				      "READ CAPACITY");
+		if (reply == 0)
+			reply = do_read_capacity(common, bh);
+		break;
+
+	case SC_READ_HEADER:
+		if (!common->curlun || !common->curlun->cdrom)
+			goto unknown_cmnd;
+		common->data_size_from_cmnd =
+			get_unaligned_be16(&common->cmnd[7]);
+		reply = check_command(common, 10, DATA_DIR_TO_HOST,
+				      (3<<7) | (0x1f<<1), 1,
+				      "READ HEADER");
+		if (reply == 0)
+			reply = do_read_header(common, bh);
+		break;
+
+	case SC_READ_TOC:
+		if (!common->curlun || !common->curlun->cdrom)
+			goto unknown_cmnd;
+		common->data_size_from_cmnd =
+			get_unaligned_be16(&common->cmnd[7]);
+		reply = check_command(common, 10, DATA_DIR_TO_HOST,
+				      (7<<6) | (1<<1), 1,
+				      "READ TOC");
+		if (reply == 0)
+			reply = do_read_toc(common, bh);
+		break;
+
+	case SC_READ_FORMAT_CAPACITIES:
+		common->data_size_from_cmnd =
+			get_unaligned_be16(&common->cmnd[7]);
+		reply = check_command(common, 10, DATA_DIR_TO_HOST,
+				      (3<<7), 1,
+				      "READ FORMAT CAPACITIES");
+		if (reply == 0)
+			reply = do_read_format_capacities(common, bh);
+		break;
+
+	case SC_REQUEST_SENSE:
+		common->data_size_from_cmnd = common->cmnd[4];
+		reply = check_command(common, 6, DATA_DIR_TO_HOST,
+				      (1<<4), 0,
+				      "REQUEST SENSE");
+		if (reply == 0)
+			reply = do_request_sense(common, bh);
+		break;
+
+	case SC_START_STOP_UNIT:
+		common->data_size_from_cmnd = 0;
+		reply = check_command(common, 6, DATA_DIR_NONE,
+				      (1<<1) | (1<<4), 0,
+				      "START-STOP UNIT");
+		if (reply == 0)
+			reply = do_start_stop(common);
+		break;
+
+	case SC_SYNCHRONIZE_CACHE:
+		common->data_size_from_cmnd = 0;
+		reply = check_command(common, 10, DATA_DIR_NONE,
+				      (0xf<<2) | (3<<7), 1,
+				      "SYNCHRONIZE CACHE");
+		if (reply == 0)
+			reply = do_synchronize_cache(common);
+		break;
+
+	case SC_TEST_UNIT_READY:
+		common->data_size_from_cmnd = 0;
+		reply = check_command(common, 6, DATA_DIR_NONE,
+				0, 1,
+				"TEST UNIT READY");
+		break;
+
+	/* Although optional, this command is used by MS-Windows.  We
+	 * support a minimal version: BytChk must be 0. */
+	case SC_VERIFY:
+		common->data_size_from_cmnd = 0;
+		reply = check_command(common, 10, DATA_DIR_NONE,
+				      (1<<1) | (0xf<<2) | (3<<7), 1,
+				      "VERIFY");
+		if (reply == 0)
+			reply = do_verify(common);
+		break;
+
+	case SC_WRITE_6:
+		i = common->cmnd[4];
+		common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
+		reply = check_command(common, 6, DATA_DIR_FROM_HOST,
+				      (7<<1) | (1<<4), 1,
+				      "WRITE(6)");
+		if (reply == 0)
+			reply = do_write(common);
+		break;
+
+	case SC_WRITE_10:
+		common->data_size_from_cmnd =
+				get_unaligned_be16(&common->cmnd[7]) << 9;
+		reply = check_command(common, 10, DATA_DIR_FROM_HOST,
+				      (1<<1) | (0xf<<2) | (3<<7), 1,
+				      "WRITE(10)");
+		if (reply == 0)
+			reply = do_write(common);
+		break;
+
+	case SC_WRITE_12:
+		common->data_size_from_cmnd =
+				get_unaligned_be32(&common->cmnd[6]) << 9;
+		reply = check_command(common, 12, DATA_DIR_FROM_HOST,
+				      (1<<1) | (0xf<<2) | (0xf<<6), 1,
+				      "WRITE(12)");
+		if (reply == 0)
+			reply = do_write(common);
+		break;
+
+	/* Some mandatory commands that we recognize but don't implement.
+	 * They don't mean much in this setting.  It's left as an exercise
+	 * for anyone interested to implement RESERVE and RELEASE in terms
+	 * of Posix locks. */
+	case SC_FORMAT_UNIT:
+	case SC_RELEASE:
+	case SC_RESERVE:
+	case SC_SEND_DIAGNOSTIC:
+		/* Fall through */
+
+	default:
+unknown_cmnd:
+		common->data_size_from_cmnd = 0;
+		sprintf(unknown, "Unknown x%02x", common->cmnd[0]);
+		reply = check_command(common, common->cmnd_size,
+				      DATA_DIR_UNKNOWN, 0xff, 0, unknown);
+		if (reply == 0) {
+			common->curlun->sense_data = SS_INVALID_COMMAND;
+			reply = -EINVAL;
+		}
+		break;
+	}
+	up_read(&common->filesem);
+
+	if (reply == -EINTR || signal_pending(current))
+		return -EINTR;
+
+	/* Set up the single reply buffer for finish_reply() */
+	if (reply == -EINVAL)
+		reply = 0;		/* Error reply length */
+	if (reply >= 0 && common->data_dir == DATA_DIR_TO_HOST) {
+		reply = min((u32) reply, common->data_size_from_cmnd);
+		bh->inreq->length = reply;
+		bh->state = BUF_STATE_FULL;
+		common->residue -= reply;
+	}				/* Otherwise it's already set */
+
+	return 0;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
+{
+	struct usb_request	*req = bh->outreq;
+	struct fsg_bulk_cb_wrap	*cbw = req->buf;
+	struct fsg_common	*common = fsg->common;
+
+	/* Was this a real packet?  Should it be ignored? */
+	if (req->status || test_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags))
+		return -EINVAL;
+
+	/* Is the CBW valid? */
+	if (req->actual != USB_BULK_CB_WRAP_LEN ||
+			cbw->Signature != cpu_to_le32(
+				USB_BULK_CB_SIG)) {
+		DBG(fsg, "invalid CBW: len %u sig 0x%x\n",
+				req->actual,
+				le32_to_cpu(cbw->Signature));
+
+		/* The Bulk-only spec says we MUST stall the IN endpoint
+		 * (6.6.1), so it's unavoidable.  It also says we must
+		 * retain this state until the next reset, but there's
+		 * no way to tell the controller driver it should ignore
+		 * Clear-Feature(HALT) requests.
+		 *
+		 * We aren't required to halt the OUT endpoint; instead
+		 * we can simply accept and discard any data received
+		 * until the next reset. */
+		wedge_bulk_in_endpoint(fsg);
+		set_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
+		return -EINVAL;
+	}
+
+	/* Is the CBW meaningful? */
+	if (cbw->Lun >= FSG_MAX_LUNS || cbw->Flags & ~USB_BULK_IN_FLAG ||
+			cbw->Length <= 0 || cbw->Length > MAX_COMMAND_SIZE) {
+		DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, "
+				"cmdlen %u\n",
+				cbw->Lun, cbw->Flags, cbw->Length);
+
+		/* We can do anything we want here, so let's stall the
+		 * bulk pipes if we are allowed to. */
+		if (common->can_stall) {
+			fsg_set_halt(fsg, fsg->bulk_out);
+			halt_bulk_in_endpoint(fsg);
+		}
+		return -EINVAL;
+	}
+
+	/* Save the command for later */
+	common->cmnd_size = cbw->Length;
+	memcpy(common->cmnd, cbw->CDB, common->cmnd_size);
+	if (cbw->Flags & USB_BULK_IN_FLAG)
+		common->data_dir = DATA_DIR_TO_HOST;
+	else
+		common->data_dir = DATA_DIR_FROM_HOST;
+	common->data_size = le32_to_cpu(cbw->DataTransferLength);
+	if (common->data_size == 0)
+		common->data_dir = DATA_DIR_NONE;
+	common->lun = cbw->Lun;
+	common->tag = cbw->Tag;
+	return 0;
+}
+
+
+static int get_next_command(struct fsg_common *common)
+{
+	struct fsg_buffhd	*bh;
+	int			rc = 0;
+
+	/* Wait for the next buffer to become available */
+	bh = common->next_buffhd_to_fill;
+	while (bh->state != BUF_STATE_EMPTY) {
+		rc = sleep_thread(common);
+		if (rc)
+			return rc;
+	}
+
+	/* Queue a request to read a Bulk-only CBW */
+	set_bulk_out_req_length(common, bh, USB_BULK_CB_WRAP_LEN);
+	bh->outreq->short_not_ok = 1;
+	START_TRANSFER_OR(common, bulk_out, bh->outreq,
+			  &bh->outreq_busy, &bh->state)
+		/* Don't know what to do if common->fsg is NULL */
+		return -EIO;
+
+	/* We will drain the buffer in software, which means we
+	 * can reuse it for the next filling.  No need to advance
+	 * next_buffhd_to_fill. */
+
+	/* Wait for the CBW to arrive */
+	while (bh->state != BUF_STATE_FULL) {
+		rc = sleep_thread(common);
+		if (rc)
+			return rc;
+	}
+	smp_rmb();
+	rc = fsg_is_set(common) ? received_cbw(common->fsg, bh) : -EIO;
+	bh->state = BUF_STATE_EMPTY;
+
+	return rc;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static int enable_endpoint(struct fsg_common *common, struct usb_ep *ep,
+		const struct usb_endpoint_descriptor *d)
+{
+	int	rc;
+
+	ep->driver_data = common;
+	rc = usb_ep_enable(ep, d);
+	if (rc)
+		ERROR(common, "can't enable %s, result %d\n", ep->name, rc);
+	return rc;
+}
+
+static int alloc_request(struct fsg_common *common, struct usb_ep *ep,
+		struct usb_request **preq)
+{
+	*preq = usb_ep_alloc_request(ep, GFP_ATOMIC);
+	if (*preq)
+		return 0;
+	ERROR(common, "can't allocate request for %s\n", ep->name);
+	return -ENOMEM;
+}
+
+/*
+ * Reset interface setting and re-init endpoint state (toggle etc).
+ * Call with altsetting < 0 to disable the interface.  The only other
+ * available altsetting is 0, which enables the interface.
+ */
+static int do_set_interface(struct fsg_common *common, int altsetting)
+{
+	int	rc = 0;
+	int	i;
+	const struct usb_endpoint_descriptor	*d;
+
+	if (common->running)
+		DBG(common, "reset interface\n");
+
+reset:
+	/* Deallocate the requests */
+	if (common->prev_fsg) {
+		struct fsg_dev *fsg = common->prev_fsg;
+
+		for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
+			struct fsg_buffhd *bh = &common->buffhds[i];
+
+			if (bh->inreq) {
+				usb_ep_free_request(fsg->bulk_in, bh->inreq);
+				bh->inreq = NULL;
+			}
+			if (bh->outreq) {
+				usb_ep_free_request(fsg->bulk_out, bh->outreq);
+				bh->outreq = NULL;
+			}
+		}
+
+		/* Disable the endpoints */
+		if (fsg->bulk_in_enabled) {
+			usb_ep_disable(fsg->bulk_in);
+			fsg->bulk_in_enabled = 0;
+		}
+		if (fsg->bulk_out_enabled) {
+			usb_ep_disable(fsg->bulk_out);
+			fsg->bulk_out_enabled = 0;
+		}
+
+		common->prev_fsg = 0;
+	}
+
+	common->running = 0;
+	if (altsetting < 0 || rc != 0)
+		return rc;
+
+	DBG(common, "set interface %d\n", altsetting);
+
+	if (fsg_is_set(common)) {
+		struct fsg_dev *fsg = common->fsg;
+		common->prev_fsg = common->fsg;
+
+		/* Enable the endpoints */
+		d = fsg_ep_desc(common->gadget,
+				&fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc);
+		rc = enable_endpoint(common, fsg->bulk_in, d);
+		if (rc)
+			goto reset;
+		fsg->bulk_in_enabled = 1;
+
+		d = fsg_ep_desc(common->gadget,
+				&fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc);
+		rc = enable_endpoint(common, fsg->bulk_out, d);
+		if (rc)
+			goto reset;
+		fsg->bulk_out_enabled = 1;
+		common->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize);
+		clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
+
+		/* Allocate the requests */
+		for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
+			struct fsg_buffhd	*bh = &common->buffhds[i];
+
+			rc = alloc_request(common, fsg->bulk_in, &bh->inreq);
+			if (rc)
+				goto reset;
+			rc = alloc_request(common, fsg->bulk_out, &bh->outreq);
+			if (rc)
+				goto reset;
+			bh->inreq->buf = bh->outreq->buf = bh->buf;
+			bh->inreq->context = bh->outreq->context = bh;
+			bh->inreq->complete = bulk_in_complete;
+			bh->outreq->complete = bulk_out_complete;
+		}
+
+		common->running = 1;
+		for (i = 0; i < common->nluns; ++i)
+			common->luns[i].unit_attention_data = SS_RESET_OCCURRED;
+		return rc;
+	} else {
+		return -EIO;
+	}
+}
+
+
+/*
+ * Change our operational configuration.  This code must agree with the code
+ * that returns config descriptors, and with interface altsetting code.
+ *
+ * It's also responsible for power management interactions.  Some
+ * configurations might not work with our current power sources.
+ * For now we just assume the gadget is always self-powered.
+ */
+static int do_set_config(struct fsg_common *common, u8 new_config)
+{
+	int	rc = 0;
+
+	/* Disable the single interface */
+	if (common->config != 0) {
+		DBG(common, "reset config\n");
+		common->config = 0;
+		rc = do_set_interface(common, -1);
+	}
+
+	/* Enable the interface */
+	if (new_config != 0) {
+		common->config = new_config;
+		rc = do_set_interface(common, 0);
+		if (rc != 0)
+			common->config = 0;	/* Reset on errors */
+	}
+	return rc;
+}
+
+
+/****************************** ALT CONFIGS ******************************/
+
+
+static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
+{
+	struct fsg_dev *fsg = fsg_from_func(f);
+	fsg->common->prev_fsg = fsg->common->fsg;
+	fsg->common->fsg = fsg;
+	fsg->common->new_config = 1;
+	raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
+	return 0;
+}
+
+static void fsg_disable(struct usb_function *f)
+{
+	struct fsg_dev *fsg = fsg_from_func(f);
+	fsg->common->prev_fsg = fsg->common->fsg;
+	fsg->common->fsg = fsg;
+	fsg->common->new_config = 0;
+	raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static void handle_exception(struct fsg_common *common)
+{
+	siginfo_t		info;
+	int			sig;
+	int			i;
+	struct fsg_buffhd	*bh;
+	enum fsg_state		old_state;
+	u8			new_config;
+	struct fsg_lun		*curlun;
+	unsigned int		exception_req_tag;
+	int			rc;
+
+	/* Clear the existing signals.  Anything but SIGUSR1 is converted
+	 * into a high-priority EXIT exception. */
+	for (;;) {
+		sig = dequeue_signal_lock(current, &current->blocked, &info);
+		if (!sig)
+			break;
+		if (sig != SIGUSR1) {
+			if (common->state < FSG_STATE_EXIT)
+				DBG(common, "Main thread exiting on signal\n");
+			raise_exception(common, FSG_STATE_EXIT);
+		}
+	}
+
+	/* Cancel all the pending transfers */
+	if (fsg_is_set(common)) {
+		for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
+			bh = &common->buffhds[i];
+			if (bh->inreq_busy)
+				usb_ep_dequeue(common->fsg->bulk_in, bh->inreq);
+			if (bh->outreq_busy)
+				usb_ep_dequeue(common->fsg->bulk_out,
+					       bh->outreq);
+		}
+
+		/* Wait until everything is idle */
+		for (;;) {
+			int num_active = 0;
+			for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
+				bh = &common->buffhds[i];
+				num_active += bh->inreq_busy + bh->outreq_busy;
+			}
+			if (num_active == 0)
+				break;
+			if (sleep_thread(common))
+				return;
+		}
+
+		/* Clear out the controller's fifos */
+		if (common->fsg->bulk_in_enabled)
+			usb_ep_fifo_flush(common->fsg->bulk_in);
+		if (common->fsg->bulk_out_enabled)
+			usb_ep_fifo_flush(common->fsg->bulk_out);
+	}
+
+	/* Reset the I/O buffer states and pointers, the SCSI
+	 * state, and the exception.  Then invoke the handler. */
+	spin_lock_irq(&common->lock);
+
+	for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
+		bh = &common->buffhds[i];
+		bh->state = BUF_STATE_EMPTY;
+	}
+	common->next_buffhd_to_fill = &common->buffhds[0];
+	common->next_buffhd_to_drain = &common->buffhds[0];
+	exception_req_tag = common->exception_req_tag;
+	new_config = common->new_config;
+	old_state = common->state;
+
+	if (old_state == FSG_STATE_ABORT_BULK_OUT)
+		common->state = FSG_STATE_STATUS_PHASE;
+	else {
+		for (i = 0; i < common->nluns; ++i) {
+			curlun = &common->luns[i];
+			curlun->prevent_medium_removal = 0;
+			curlun->sense_data = SS_NO_SENSE;
+			curlun->unit_attention_data = SS_NO_SENSE;
+			curlun->sense_data_info = 0;
+			curlun->info_valid = 0;
+		}
+		common->state = FSG_STATE_IDLE;
+	}
+	spin_unlock_irq(&common->lock);
+
+	/* Carry out any extra actions required for the exception */
+	switch (old_state) {
+	case FSG_STATE_ABORT_BULK_OUT:
+		send_status(common);
+		spin_lock_irq(&common->lock);
+		if (common->state == FSG_STATE_STATUS_PHASE)
+			common->state = FSG_STATE_IDLE;
+		spin_unlock_irq(&common->lock);
+		break;
+
+	case FSG_STATE_RESET:
+		/* In case we were forced against our will to halt a
+		 * bulk endpoint, clear the halt now.  (The SuperH UDC
+		 * requires this.) */
+		if (!fsg_is_set(common))
+			break;
+		if (test_and_clear_bit(IGNORE_BULK_OUT,
+				       &common->fsg->atomic_bitflags))
+			usb_ep_clear_halt(common->fsg->bulk_in);
+
+		if (common->ep0_req_tag == exception_req_tag)
+			ep0_queue(common);	/* Complete the status stage */
+
+		/* Technically this should go here, but it would only be
+		 * a waste of time.  Ditto for the INTERFACE_CHANGE and
+		 * CONFIG_CHANGE cases. */
+		/* for (i = 0; i < common->nluns; ++i) */
+		/*	common->luns[i].unit_attention_data = */
+		/*		SS_RESET_OCCURRED;  */
+		break;
+
+	case FSG_STATE_CONFIG_CHANGE:
+		rc = do_set_config(common, new_config);
+		if (common->ep0_req_tag != exception_req_tag)
+			break;
+		if (rc != 0) {			/* STALL on errors */
+			DBG(common, "ep0 set halt\n");
+			usb_ep_set_halt(common->ep0);
+		} else {			/* Complete the status stage */
+			ep0_queue(common);
+		}
+		break;
+
+	case FSG_STATE_EXIT:
+	case FSG_STATE_TERMINATED:
+		do_set_config(common, 0);		/* Free resources */
+		spin_lock_irq(&common->lock);
+		common->state = FSG_STATE_TERMINATED;	/* Stop the thread */
+		spin_unlock_irq(&common->lock);
+		break;
+
+	case FSG_STATE_INTERFACE_CHANGE:
+	case FSG_STATE_DISCONNECT:
+	case FSG_STATE_COMMAND_PHASE:
+	case FSG_STATE_DATA_PHASE:
+	case FSG_STATE_STATUS_PHASE:
+	case FSG_STATE_IDLE:
+		break;
+	}
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static int fsg_main_thread(void *common_)
+{
+	struct fsg_common	*common = common_;
+
+	/* Allow the thread to be killed by a signal, but set the signal mask
+	 * to block everything but INT, TERM, KILL, and USR1. */
+	allow_signal(SIGINT);
+	allow_signal(SIGTERM);
+	allow_signal(SIGKILL);
+	allow_signal(SIGUSR1);
+
+	/* Allow the thread to be frozen */
+	set_freezable();
+
+	/* Arrange for userspace references to be interpreted as kernel
+	 * pointers.  That way we can pass a kernel pointer to a routine
+	 * that expects a __user pointer and it will work okay. */
+	set_fs(get_ds());
+
+	/* The main loop */
+	while (common->state != FSG_STATE_TERMINATED) {
+		if (exception_in_progress(common) || signal_pending(current)) {
+			handle_exception(common);
+			continue;
+		}
+
+		if (!common->running) {
+			sleep_thread(common);
+			continue;
+		}
+
+		if (get_next_command(common))
+			continue;
+
+		spin_lock_irq(&common->lock);
+		if (!exception_in_progress(common))
+			common->state = FSG_STATE_DATA_PHASE;
+		spin_unlock_irq(&common->lock);
+
+		if (do_scsi_command(common) || finish_reply(common))
+			continue;
+
+		spin_lock_irq(&common->lock);
+		if (!exception_in_progress(common))
+			common->state = FSG_STATE_STATUS_PHASE;
+		spin_unlock_irq(&common->lock);
+
+		if (send_status(common))
+			continue;
+
+		spin_lock_irq(&common->lock);
+		if (!exception_in_progress(common))
+			common->state = FSG_STATE_IDLE;
+		spin_unlock_irq(&common->lock);
+	}
+
+	spin_lock_irq(&common->lock);
+	common->thread_task = NULL;
+	spin_unlock_irq(&common->lock);
+
+	if (common->thread_exits)
+		common->thread_exits(common);
+
+	/* Let the unbind and cleanup routines know the thread has exited */
+	complete_and_exit(&common->thread_notifier, 0);
+}
+
+
+/*************************** DEVICE ATTRIBUTES ***************************/
+
+/* Write permission is checked per LUN in store_*() functions. */
+static DEVICE_ATTR(ro, 0644, fsg_show_ro, fsg_store_ro);
+static DEVICE_ATTR(file, 0644, fsg_show_file, fsg_store_file);
+
+
+/****************************** FSG COMMON ******************************/
+
+static void fsg_common_release(struct kref *ref);
+
+static void fsg_lun_release(struct device *dev)
+{
+	/* Nothing needs to be done */
+}
+
+static inline void fsg_common_get(struct fsg_common *common)
+{
+	kref_get(&common->ref);
+}
+
+static inline void fsg_common_put(struct fsg_common *common)
+{
+	kref_put(&common->ref, fsg_common_release);
+}
+
+
+static struct fsg_common *fsg_common_init(struct fsg_common *common,
+					  struct usb_composite_dev *cdev,
+					  struct fsg_config *cfg)
+{
+	struct usb_gadget *gadget = cdev->gadget;
+	struct fsg_buffhd *bh;
+	struct fsg_lun *curlun;
+	struct fsg_lun_config *lcfg;
+	int nluns, i, rc;
+	char *pathbuf;
+
+	/* Find out how many LUNs there should be */
+	nluns = cfg->nluns;
+	if (nluns < 1 || nluns > FSG_MAX_LUNS) {
+		dev_err(&gadget->dev, "invalid number of LUNs: %u\n", nluns);
+		return ERR_PTR(-EINVAL);
+	}
+
+	/* Allocate? */
+	if (!common) {
+		common = kzalloc(sizeof *common, GFP_KERNEL);
+		if (!common)
+			return ERR_PTR(-ENOMEM);
+		common->free_storage_on_release = 1;
+	} else {
+		memset(common, 0, sizeof common);
+		common->free_storage_on_release = 0;
+	}
+
+	common->private_data = cfg->private_data;
+
+	common->gadget = gadget;
+	common->ep0 = gadget->ep0;
+	common->ep0req = cdev->req;
+
+	/* Maybe allocate device-global string IDs, and patch descriptors */
+	if (fsg_strings[FSG_STRING_INTERFACE].id == 0) {
+		rc = usb_string_id(cdev);
+		if (rc < 0) {
+			kfree(common);
+			return ERR_PTR(rc);
+		}
+		fsg_strings[FSG_STRING_INTERFACE].id = rc;
+		fsg_intf_desc.iInterface = rc;
+	}
+
+	/* Create the LUNs, open their backing files, and register the
+	 * LUN devices in sysfs. */
+	curlun = kzalloc(nluns * sizeof *curlun, GFP_KERNEL);
+	if (!curlun) {
+		kfree(common);
+		return ERR_PTR(-ENOMEM);
+	}
+	common->luns = curlun;
+
+	init_rwsem(&common->filesem);
+
+	for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun, ++lcfg) {
+		curlun->cdrom = !!lcfg->cdrom;
+		curlun->ro = lcfg->cdrom || lcfg->ro;
+		curlun->removable = lcfg->removable;
+		curlun->dev.release = fsg_lun_release;
+		curlun->dev.parent = &gadget->dev;
+		/* curlun->dev.driver = &fsg_driver.driver; XXX */
+		dev_set_drvdata(&curlun->dev, &common->filesem);
+		dev_set_name(&curlun->dev,
+			     cfg->lun_name_format
+			   ? cfg->lun_name_format
+			   : "lun%d",
+			     i);
+
+		rc = device_register(&curlun->dev);
+		if (rc) {
+			INFO(common, "failed to register LUN%d: %d\n", i, rc);
+			common->nluns = i;
+			goto error_release;
+		}
+
+		rc = device_create_file(&curlun->dev, &dev_attr_ro);
+		if (rc)
+			goto error_luns;
+		rc = device_create_file(&curlun->dev, &dev_attr_file);
+		if (rc)
+			goto error_luns;
+
+		if (lcfg->filename) {
+			rc = fsg_lun_open(curlun, lcfg->filename);
+			if (rc)
+				goto error_luns;
+		} else if (!curlun->removable) {
+			ERROR(common, "no file given for LUN%d\n", i);
+			rc = -EINVAL;
+			goto error_luns;
+		}
+	}
+	common->nluns = nluns;
+
+
+	/* Data buffers cyclic list */
+	/* Buffers in buffhds are static -- no need for additional
+	 * allocation. */
+	bh = common->buffhds;
+	i = FSG_NUM_BUFFERS - 1;
+	do {
+		bh->next = bh + 1;
+	} while (++bh, --i);
+	bh->next = common->buffhds;
+
+
+	/* Prepare inquiryString */
+	if (cfg->release != 0xffff) {
+		i = cfg->release;
+	} else {
+		/* The sa1100 controller is not supported */
+		i = gadget_is_sa1100(gadget)
+			? -1
+			: usb_gadget_controller_number(gadget);
+		if (i >= 0) {
+			i = 0x0300 + i;
+		} else {
+			WARNING(common, "controller '%s' not recognized\n",
+				gadget->name);
+			i = 0x0399;
+		}
+	}
+#define OR(x, y) ((x) ? (x) : (y))
+	snprintf(common->inquiry_string, sizeof common->inquiry_string,
+		 "%-8s%-16s%04x",
+		 OR(cfg->vendor_name, "Linux   "),
+		 /* Assume product name dependent on the first LUN */
+		 OR(cfg->product_name, common->luns->cdrom
+				     ? "File-Stor Gadget"
+				     : "File-CD Gadget  "),
+		 i);
+
+
+	/* Some peripheral controllers are known not to be able to
+	 * halt bulk endpoints correctly.  If one of them is present,
+	 * disable stalls.
+	 */
+	common->can_stall = cfg->can_stall &&
+		!(gadget_is_sh(common->gadget) ||
+		  gadget_is_at91(common->gadget));
+
+
+	spin_lock_init(&common->lock);
+	kref_init(&common->ref);
+
+
+	/* Tell the thread to start working */
+	common->thread_exits = cfg->thread_exits;
+	common->thread_task =
+		kthread_create(fsg_main_thread, common,
+			       OR(cfg->thread_name, "file-storage"));
+	if (IS_ERR(common->thread_task)) {
+		rc = PTR_ERR(common->thread_task);
+		goto error_release;
+	}
+	init_completion(&common->thread_notifier);
+#undef OR
+
+
+	/* Information */
+	INFO(common, FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
+	INFO(common, "Number of LUNs=%d\n", common->nluns);
+
+	pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
+	for (i = 0, nluns = common->nluns, curlun = common->luns;
+	     i < nluns;
+	     ++curlun, ++i) {
+		char *p = "(no medium)";
+		if (fsg_lun_is_open(curlun)) {
+			p = "(error)";
+			if (pathbuf) {
+				p = d_path(&curlun->filp->f_path,
+					   pathbuf, PATH_MAX);
+				if (IS_ERR(p))
+					p = "(error)";
+			}
+		}
+		LINFO(curlun, "LUN: %s%s%sfile: %s\n",
+		      curlun->removable ? "removable " : "",
+		      curlun->ro ? "read only " : "",
+		      curlun->cdrom ? "CD-ROM " : "",
+		      p);
+	}
+	kfree(pathbuf);
+
+	DBG(common, "I/O thread pid: %d\n", task_pid_nr(common->thread_task));
+
+	wake_up_process(common->thread_task);
+
+	return common;
+
+
+error_luns:
+	common->nluns = i + 1;
+error_release:
+	common->state = FSG_STATE_TERMINATED;	/* The thread is dead */
+	/* Call fsg_common_release() directly, ref might be not
+	 * initialised */
+	fsg_common_release(&common->ref);
+	complete(&common->thread_notifier);
+	return ERR_PTR(rc);
+}
+
+
+static void fsg_common_release(struct kref *ref)
+{
+	struct fsg_common *common =
+		container_of(ref, struct fsg_common, ref);
+	unsigned i = common->nluns;
+	struct fsg_lun *lun = common->luns;
+
+	/* If the thread isn't already dead, tell it to exit now */
+	if (common->state != FSG_STATE_TERMINATED) {
+		raise_exception(common, FSG_STATE_EXIT);
+		wait_for_completion(&common->thread_notifier);
+
+		/* The cleanup routine waits for this completion also */
+		complete(&common->thread_notifier);
+	}
+
+	/* Beware tempting for -> do-while optimization: when in error
+	 * recovery nluns may be zero. */
+
+	for (; i; --i, ++lun) {
+		device_remove_file(&lun->dev, &dev_attr_ro);
+		device_remove_file(&lun->dev, &dev_attr_file);
+		fsg_lun_close(lun);
+		device_unregister(&lun->dev);
+	}
+
+	kfree(common->luns);
+	if (common->free_storage_on_release)
+		kfree(common);
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+
+static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
+{
+	struct fsg_dev		*fsg = fsg_from_func(f);
+
+	DBG(fsg, "unbind\n");
+	fsg_common_put(fsg->common);
+	kfree(fsg);
+}
+
+
+static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
+{
+	struct fsg_dev		*fsg = fsg_from_func(f);
+	struct usb_gadget	*gadget = c->cdev->gadget;
+	int			rc;
+	int			i;
+	struct usb_ep		*ep;
+
+	fsg->gadget = gadget;
+
+	/* New interface */
+	i = usb_interface_id(c, f);
+	if (i < 0)
+		return i;
+	fsg_intf_desc.bInterfaceNumber = i;
+	fsg->interface_number = i;
+
+	/* Find all the endpoints we will use */
+	ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc);
+	if (!ep)
+		goto autoconf_fail;
+	ep->driver_data = fsg->common;	/* claim the endpoint */
+	fsg->bulk_in = ep;
+
+	ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_out_desc);
+	if (!ep)
+		goto autoconf_fail;
+	ep->driver_data = fsg->common;	/* claim the endpoint */
+	fsg->bulk_out = ep;
+
+	if (gadget_is_dualspeed(gadget)) {
+		/* Assume endpoint addresses are the same for both speeds */
+		fsg_hs_bulk_in_desc.bEndpointAddress =
+			fsg_fs_bulk_in_desc.bEndpointAddress;
+		fsg_hs_bulk_out_desc.bEndpointAddress =
+			fsg_fs_bulk_out_desc.bEndpointAddress;
+		f->hs_descriptors = fsg_hs_function;
+	}
+
+	return 0;
+
+autoconf_fail:
+	ERROR(fsg, "unable to autoconfigure all endpoints\n");
+	rc = -ENOTSUPP;
+	fsg_unbind(c, f);
+	return rc;
+}
+
+
+/****************************** ADD FUNCTION ******************************/
+
+static struct usb_gadget_strings *fsg_strings_array[] = {
+	&fsg_stringtab,
+	NULL,
+};
+
+static int fsg_add(struct usb_composite_dev *cdev,
+		   struct usb_configuration *c,
+		   struct fsg_common *common)
+{
+	struct fsg_dev *fsg;
+	int rc;
+
+	fsg = kzalloc(sizeof *fsg, GFP_KERNEL);
+	if (unlikely(!fsg))
+		return -ENOMEM;
+
+	fsg->function.name        = FSG_DRIVER_DESC;
+	fsg->function.strings     = fsg_strings_array;
+	fsg->function.descriptors = fsg_fs_function;
+	fsg->function.bind        = fsg_bind;
+	fsg->function.unbind      = fsg_unbind;
+	fsg->function.setup       = fsg_setup;
+	fsg->function.set_alt     = fsg_set_alt;
+	fsg->function.disable     = fsg_disable;
+
+	fsg->common               = common;
+	/* Our caller holds a reference to common structure so we
+	 * don't have to be worry about it being freed until we return
+	 * from this function.  So instead of incrementing counter now
+	 * and decrement in error recovery we increment it only when
+	 * call to usb_add_function() was successful. */
+
+	rc = usb_add_function(c, &fsg->function);
+
+	if (likely(rc == 0))
+		fsg_common_get(fsg->common);
+	else
+		kfree(fsg);
+
+	return rc;
+}
+
+
+
+/************************* Module parameters *************************/
+
+
+struct fsg_module_parameters {
+	char		*file[FSG_MAX_LUNS];
+	int		ro[FSG_MAX_LUNS];
+	int		removable[FSG_MAX_LUNS];
+	int		cdrom[FSG_MAX_LUNS];
+
+	unsigned int	file_count, ro_count, removable_count, cdrom_count;
+	unsigned int	luns;	/* nluns */
+	int		stall;	/* can_stall */
+};
+
+
+#define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc)	\
+	module_param_array_named(prefix ## name, params.name, type,	\
+				 &prefix ## params.name ## _count,	\
+				 S_IRUGO);				\
+	MODULE_PARM_DESC(prefix ## name, desc)
+
+#define _FSG_MODULE_PARAM(prefix, params, name, type, desc)		\
+	module_param_named(prefix ## name, params.name, type,		\
+			   S_IRUGO);					\
+	MODULE_PARM_DESC(prefix ## name, desc)
+
+#define FSG_MODULE_PARAMETERS(prefix, params)				\
+	_FSG_MODULE_PARAM_ARRAY(prefix, params, file, charp,		\
+				"names of backing files or devices");	\
+	_FSG_MODULE_PARAM_ARRAY(prefix, params, ro, bool,		\
+				"true to force read-only");		\
+	_FSG_MODULE_PARAM_ARRAY(prefix, params, removable, bool,	\
+				"true to simulate removable media");	\
+	_FSG_MODULE_PARAM_ARRAY(prefix, params, cdrom, bool,		\
+				"true to simulate CD-ROM instead of disk"); \
+	_FSG_MODULE_PARAM(prefix, params, luns, uint,			\
+			  "number of LUNs");				\
+	_FSG_MODULE_PARAM(prefix, params, stall, bool,			\
+			  "false to prevent bulk stalls")
+
+
+static void
+fsg_config_from_params(struct fsg_config *cfg,
+		       const struct fsg_module_parameters *params)
+{
+	struct fsg_lun_config *lun;
+	unsigned i;
+
+	/* Configure LUNs */
+	cfg->nluns =
+		min(params->luns ?: (params->file_count ?: 1u),
+		    (unsigned)FSG_MAX_LUNS);
+	for (i = 0, lun = cfg->luns; i < cfg->nluns; ++i, ++lun) {
+		lun->ro = !!params->ro[i];
+		lun->cdrom = !!params->cdrom[i];
+		lun->removable = /* Removable by default */
+			params->removable_count <= i || params->removable[i];
+		lun->filename =
+			params->file_count > i && params->file[i][0]
+			? params->file[i]
+			: 0;
+	}
+
+	/* Let MSF use defaults */
+	cfg->lun_name_format = 0;
+	cfg->thread_name = 0;
+	cfg->vendor_name = 0;
+	cfg->product_name = 0;
+	cfg->release = 0xffff;
+
+	cfg->thread_exits = 0;
+	cfg->private_data = 0;
+
+	/* Finalise */
+	cfg->can_stall = params->stall;
+}
+
+static inline struct fsg_common *
+fsg_common_from_params(struct fsg_common *common,
+		       struct usb_composite_dev *cdev,
+		       const struct fsg_module_parameters *params)
+	__attribute__((unused));
+static inline struct fsg_common *
+fsg_common_from_params(struct fsg_common *common,
+		       struct usb_composite_dev *cdev,
+		       const struct fsg_module_parameters *params)
+{
+	struct fsg_config cfg;
+	fsg_config_from_params(&cfg, params);
+	return fsg_common_init(common, cdev, &cfg);
+}
+
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index c9966cc..95dae4c 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -4,6 +4,8 @@
  * Copyright (C) 2003-2005,2008 David Brownell
  * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
  * Copyright (C) 2008 Nokia Corporation
+ * Copyright (C) 2009 Samsung Electronics
+ *                    Author: Michal Nazarewicz (m.nazarewicz@samsung.com)
  *
  * 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
@@ -149,8 +151,8 @@
 	.bDataInterface =	0x01,
 };
 
-static struct usb_cdc_acm_descriptor acm_descriptor __initdata = {
-	.bLength =		sizeof acm_descriptor,
+static struct usb_cdc_acm_descriptor rndis_acm_descriptor __initdata = {
+	.bLength =		sizeof rndis_acm_descriptor,
 	.bDescriptorType =	USB_DT_CS_INTERFACE,
 	.bDescriptorSubType =	USB_CDC_ACM_TYPE,
 
@@ -179,6 +181,20 @@
 	/* .iInterface = DYNAMIC */
 };
 
+
+static struct usb_interface_assoc_descriptor
+rndis_iad_descriptor = {
+	.bLength =		sizeof rndis_iad_descriptor,
+	.bDescriptorType =	USB_DT_INTERFACE_ASSOCIATION,
+
+	.bFirstInterface =	0, /* XXX, hardcoded */
+	.bInterfaceCount = 	2,	// control + data
+	.bFunctionClass =	USB_CLASS_COMM,
+	.bFunctionSubClass =	USB_CDC_SUBCLASS_ETHERNET,
+	.bFunctionProtocol =	USB_CDC_PROTO_NONE,
+	/* .iFunction = DYNAMIC */
+};
+
 /* full speed support: */
 
 static struct usb_endpoint_descriptor fs_notify_desc __initdata = {
@@ -208,11 +224,12 @@
 };
 
 static struct usb_descriptor_header *eth_fs_function[] __initdata = {
+	(struct usb_descriptor_header *) &rndis_iad_descriptor,
 	/* control interface matches ACM, not Ethernet */
 	(struct usb_descriptor_header *) &rndis_control_intf,
 	(struct usb_descriptor_header *) &header_desc,
 	(struct usb_descriptor_header *) &call_mgmt_descriptor,
-	(struct usb_descriptor_header *) &acm_descriptor,
+	(struct usb_descriptor_header *) &rndis_acm_descriptor,
 	(struct usb_descriptor_header *) &rndis_union_desc,
 	(struct usb_descriptor_header *) &fs_notify_desc,
 	/* data interface has no altsetting */
@@ -252,11 +269,12 @@
 };
 
 static struct usb_descriptor_header *eth_hs_function[] __initdata = {
+	(struct usb_descriptor_header *) &rndis_iad_descriptor,
 	/* control interface matches ACM, not Ethernet */
 	(struct usb_descriptor_header *) &rndis_control_intf,
 	(struct usb_descriptor_header *) &header_desc,
 	(struct usb_descriptor_header *) &call_mgmt_descriptor,
-	(struct usb_descriptor_header *) &acm_descriptor,
+	(struct usb_descriptor_header *) &rndis_acm_descriptor,
 	(struct usb_descriptor_header *) &rndis_union_desc,
 	(struct usb_descriptor_header *) &hs_notify_desc,
 	/* data interface has no altsetting */
@@ -271,6 +289,7 @@
 static struct usb_string rndis_string_defs[] = {
 	[0].s = "RNDIS Communications Control",
 	[1].s = "RNDIS Ethernet Data",
+	[2].s = "RNDIS",
 	{  } /* end of list */
 };
 
@@ -587,6 +606,7 @@
 	if (status < 0)
 		goto fail;
 	rndis->ctrl_id = status;
+	rndis_iad_descriptor.bFirstInterface = status;
 
 	rndis_control_intf.bInterfaceNumber = status;
 	rndis_union_desc.bMasterInterface0 = status;
@@ -798,6 +818,13 @@
 			return status;
 		rndis_string_defs[1].id = status;
 		rndis_data_intf.iInterface = status;
+
+		/* IAD iFunction label */
+		status = usb_string_id(c->cdev);
+		if (status < 0)
+			return status;
+		rndis_string_defs[2].id = status;
+		rndis_iad_descriptor.iFunction = status;
 	}
 
 	/* allocate and initialize one new instance */
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index 1e6aa50..29dfb02 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -248,8 +248,6 @@
 #include <linux/freezer.h>
 #include <linux/utsname.h>
 
-#include <asm/unaligned.h>
-
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 
@@ -274,21 +272,20 @@
 #define DRIVER_NAME		"g_file_storage"
 #define DRIVER_VERSION		"20 November 2008"
 
-static const char longname[] = DRIVER_DESC;
-static const char shortname[] = DRIVER_NAME;
+static       char fsg_string_manufacturer[64];
+static const char fsg_string_product[] = DRIVER_DESC;
+static       char fsg_string_serial[13];
+static const char fsg_string_config[] = "Self-powered";
+static const char fsg_string_interface[] = "Mass Storage";
+
+
+#include "storage_common.c"
+
 
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_AUTHOR("Alan Stern");
 MODULE_LICENSE("Dual BSD/GPL");
 
-/* Thanks to NetChip Technologies for donating this product ID.
- *
- * DO NOT REUSE THESE IDs with any other driver!!  Ever!!
- * Instead:  allocate your own, using normal USB-IF procedures. */
-#define DRIVER_VENDOR_ID	0x0525	// NetChip
-#define DRIVER_PRODUCT_ID	0xa4a5	// Linux-USB File-backed Storage Gadget
-
-
 /*
  * This driver assumes self-powered hardware and has no way for users to
  * trigger remote wakeup.  It uses autoconfiguration to select endpoints
@@ -298,54 +295,12 @@
 
 /*-------------------------------------------------------------------------*/
 
-#define LDBG(lun,fmt,args...) \
-	dev_dbg(&(lun)->dev , fmt , ## args)
-#define MDBG(fmt,args...) \
-	pr_debug(DRIVER_NAME ": " fmt , ## args)
-
-#ifndef DEBUG
-#undef VERBOSE_DEBUG
-#undef DUMP_MSGS
-#endif /* !DEBUG */
-
-#ifdef VERBOSE_DEBUG
-#define VLDBG	LDBG
-#else
-#define VLDBG(lun,fmt,args...) \
-	do { } while (0)
-#endif /* VERBOSE_DEBUG */
-
-#define LERROR(lun,fmt,args...) \
-	dev_err(&(lun)->dev , fmt , ## args)
-#define LWARN(lun,fmt,args...) \
-	dev_warn(&(lun)->dev , fmt , ## args)
-#define LINFO(lun,fmt,args...) \
-	dev_info(&(lun)->dev , fmt , ## args)
-
-#define MINFO(fmt,args...) \
-	pr_info(DRIVER_NAME ": " fmt , ## args)
-
-#define DBG(d, fmt, args...) \
-	dev_dbg(&(d)->gadget->dev , fmt , ## args)
-#define VDBG(d, fmt, args...) \
-	dev_vdbg(&(d)->gadget->dev , fmt , ## args)
-#define ERROR(d, fmt, args...) \
-	dev_err(&(d)->gadget->dev , fmt , ## args)
-#define WARNING(d, fmt, args...) \
-	dev_warn(&(d)->gadget->dev , fmt , ## args)
-#define INFO(d, fmt, args...) \
-	dev_info(&(d)->gadget->dev , fmt , ## args)
-
-
-/*-------------------------------------------------------------------------*/
 
 /* Encapsulate the module parameter settings */
 
-#define MAX_LUNS	8
-
 static struct {
-	char		*file[MAX_LUNS];
-	int		ro[MAX_LUNS];
+	char		*file[FSG_MAX_LUNS];
+	int		ro[FSG_MAX_LUNS];
 	unsigned int	num_filenames;
 	unsigned int	num_ros;
 	unsigned int	nluns;
@@ -372,8 +327,8 @@
 	.removable		= 0,
 	.can_stall		= 1,
 	.cdrom			= 0,
-	.vendor			= DRIVER_VENDOR_ID,
-	.product		= DRIVER_PRODUCT_ID,
+	.vendor			= FSG_VENDOR_ID,
+	.product		= FSG_PRODUCT_ID,
 	.release		= 0xffff,	// Use controller chip type
 	.buflen			= 16384,
 	};
@@ -425,125 +380,6 @@
 #endif /* CONFIG_USB_FILE_STORAGE_TEST */
 
 
-/*-------------------------------------------------------------------------*/
-
-/* SCSI device types */
-#define TYPE_DISK	0x00
-#define TYPE_CDROM	0x05
-
-/* USB protocol value = the transport method */
-#define USB_PR_CBI	0x00		// Control/Bulk/Interrupt
-#define USB_PR_CB	0x01		// Control/Bulk w/o interrupt
-#define USB_PR_BULK	0x50		// Bulk-only
-
-/* USB subclass value = the protocol encapsulation */
-#define USB_SC_RBC	0x01		// Reduced Block Commands (flash)
-#define USB_SC_8020	0x02		// SFF-8020i, MMC-2, ATAPI (CD-ROM)
-#define USB_SC_QIC	0x03		// QIC-157 (tape)
-#define USB_SC_UFI	0x04		// UFI (floppy)
-#define USB_SC_8070	0x05		// SFF-8070i (removable)
-#define USB_SC_SCSI	0x06		// Transparent SCSI
-
-/* Bulk-only data structures */
-
-/* Command Block Wrapper */
-struct bulk_cb_wrap {
-	__le32	Signature;		// Contains 'USBC'
-	u32	Tag;			// Unique per command id
-	__le32	DataTransferLength;	// Size of the data
-	u8	Flags;			// Direction in bit 7
-	u8	Lun;			// LUN (normally 0)
-	u8	Length;			// Of the CDB, <= MAX_COMMAND_SIZE
-	u8	CDB[16];		// Command Data Block
-};
-
-#define USB_BULK_CB_WRAP_LEN	31
-#define USB_BULK_CB_SIG		0x43425355	// Spells out USBC
-#define USB_BULK_IN_FLAG	0x80
-
-/* Command Status Wrapper */
-struct bulk_cs_wrap {
-	__le32	Signature;		// Should = 'USBS'
-	u32	Tag;			// Same as original command
-	__le32	Residue;		// Amount not transferred
-	u8	Status;			// See below
-};
-
-#define USB_BULK_CS_WRAP_LEN	13
-#define USB_BULK_CS_SIG		0x53425355	// Spells out 'USBS'
-#define USB_STATUS_PASS		0
-#define USB_STATUS_FAIL		1
-#define USB_STATUS_PHASE_ERROR	2
-
-/* Bulk-only class specific requests */
-#define USB_BULK_RESET_REQUEST		0xff
-#define USB_BULK_GET_MAX_LUN_REQUEST	0xfe
-
-
-/* CBI Interrupt data structure */
-struct interrupt_data {
-	u8	bType;
-	u8	bValue;
-};
-
-#define CBI_INTERRUPT_DATA_LEN		2
-
-/* CBI Accept Device-Specific Command request */
-#define USB_CBI_ADSC_REQUEST		0x00
-
-
-#define MAX_COMMAND_SIZE	16	// Length of a SCSI Command Data Block
-
-/* SCSI commands that we recognize */
-#define SC_FORMAT_UNIT			0x04
-#define SC_INQUIRY			0x12
-#define SC_MODE_SELECT_6		0x15
-#define SC_MODE_SELECT_10		0x55
-#define SC_MODE_SENSE_6			0x1a
-#define SC_MODE_SENSE_10		0x5a
-#define SC_PREVENT_ALLOW_MEDIUM_REMOVAL	0x1e
-#define SC_READ_6			0x08
-#define SC_READ_10			0x28
-#define SC_READ_12			0xa8
-#define SC_READ_CAPACITY		0x25
-#define SC_READ_FORMAT_CAPACITIES	0x23
-#define SC_READ_HEADER			0x44
-#define SC_READ_TOC			0x43
-#define SC_RELEASE			0x17
-#define SC_REQUEST_SENSE		0x03
-#define SC_RESERVE			0x16
-#define SC_SEND_DIAGNOSTIC		0x1d
-#define SC_START_STOP_UNIT		0x1b
-#define SC_SYNCHRONIZE_CACHE		0x35
-#define SC_TEST_UNIT_READY		0x00
-#define SC_VERIFY			0x2f
-#define SC_WRITE_6			0x0a
-#define SC_WRITE_10			0x2a
-#define SC_WRITE_12			0xaa
-
-/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */
-#define SS_NO_SENSE				0
-#define SS_COMMUNICATION_FAILURE		0x040800
-#define SS_INVALID_COMMAND			0x052000
-#define SS_INVALID_FIELD_IN_CDB			0x052400
-#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE	0x052100
-#define SS_LOGICAL_UNIT_NOT_SUPPORTED		0x052500
-#define SS_MEDIUM_NOT_PRESENT			0x023a00
-#define SS_MEDIUM_REMOVAL_PREVENTED		0x055302
-#define SS_NOT_READY_TO_READY_TRANSITION	0x062800
-#define SS_RESET_OCCURRED			0x062900
-#define SS_SAVING_PARAMETERS_NOT_SUPPORTED	0x053900
-#define SS_UNRECOVERED_READ_ERROR		0x031100
-#define SS_WRITE_ERROR				0x030c02
-#define SS_WRITE_PROTECTED			0x072700
-
-#define SK(x)		((u8) ((x) >> 16))	// Sense Key byte, etc.
-#define ASC(x)		((u8) ((x) >> 8))
-#define ASCQ(x)		((u8) (x))
-
-
-/*-------------------------------------------------------------------------*/
-
 /*
  * These definitions will permit the compiler to avoid generating code for
  * parts of the driver that aren't used in the non-TEST version.  Even gcc
@@ -566,81 +402,8 @@
 #endif /* CONFIG_USB_FILE_STORAGE_TEST */
 
 
-struct lun {
-	struct file	*filp;
-	loff_t		file_length;
-	loff_t		num_sectors;
+/*-------------------------------------------------------------------------*/
 
-	unsigned int	ro : 1;
-	unsigned int	prevent_medium_removal : 1;
-	unsigned int	registered : 1;
-	unsigned int	info_valid : 1;
-
-	u32		sense_data;
-	u32		sense_data_info;
-	u32		unit_attention_data;
-
-	struct device	dev;
-};
-
-#define backing_file_is_open(curlun)	((curlun)->filp != NULL)
-
-static struct lun *dev_to_lun(struct device *dev)
-{
-	return container_of(dev, struct lun, dev);
-}
-
-
-/* Big enough to hold our biggest descriptor */
-#define EP0_BUFSIZE	256
-#define DELAYED_STATUS	(EP0_BUFSIZE + 999)	// An impossibly large value
-
-/* Number of buffers we will use.  2 is enough for double-buffering */
-#define NUM_BUFFERS	2
-
-enum fsg_buffer_state {
-	BUF_STATE_EMPTY = 0,
-	BUF_STATE_FULL,
-	BUF_STATE_BUSY
-};
-
-struct fsg_buffhd {
-	void				*buf;
-	enum fsg_buffer_state		state;
-	struct fsg_buffhd		*next;
-
-	/* The NetChip 2280 is faster, and handles some protocol faults
-	 * better, if we don't submit any short bulk-out read requests.
-	 * So we will record the intended request length here. */
-	unsigned int			bulk_out_intended_length;
-
-	struct usb_request		*inreq;
-	int				inreq_busy;
-	struct usb_request		*outreq;
-	int				outreq_busy;
-};
-
-enum fsg_state {
-	FSG_STATE_COMMAND_PHASE = -10,		// This one isn't used anywhere
-	FSG_STATE_DATA_PHASE,
-	FSG_STATE_STATUS_PHASE,
-
-	FSG_STATE_IDLE = 0,
-	FSG_STATE_ABORT_BULK_OUT,
-	FSG_STATE_RESET,
-	FSG_STATE_INTERFACE_CHANGE,
-	FSG_STATE_CONFIG_CHANGE,
-	FSG_STATE_DISCONNECT,
-	FSG_STATE_EXIT,
-	FSG_STATE_TERMINATED
-};
-
-enum data_direction {
-	DATA_DIR_UNKNOWN = 0,
-	DATA_DIR_FROM_HOST,
-	DATA_DIR_TO_HOST,
-	DATA_DIR_NONE
-};
 
 struct fsg_dev {
 	/* lock protects: state, all the req_busy's, and cbbuf_cmnd */
@@ -662,7 +425,7 @@
 	int			intreq_busy;
 	struct fsg_buffhd	*intr_buffhd;
 
- 	unsigned int		bulk_out_maxpacket;
+	unsigned int		bulk_out_maxpacket;
 	enum fsg_state		state;		// For exception handling
 	unsigned int		exception_req_tag;
 
@@ -687,7 +450,7 @@
 
 	struct fsg_buffhd	*next_buffhd_to_fill;
 	struct fsg_buffhd	*next_buffhd_to_drain;
-	struct fsg_buffhd	buffhds[NUM_BUFFERS];
+	struct fsg_buffhd	buffhds[FSG_NUM_BUFFERS];
 
 	int			thread_wakeup_needed;
 	struct completion	thread_notifier;
@@ -712,8 +475,8 @@
 	u8			cbbuf_cmnd[MAX_COMMAND_SIZE];
 
 	unsigned int		nluns;
-	struct lun		*luns;
-	struct lun		*curlun;
+	struct fsg_lun		*luns;
+	struct fsg_lun		*curlun;
 };
 
 typedef void (*fsg_routine_t)(struct fsg_dev *);
@@ -739,49 +502,9 @@
 static struct fsg_dev			*the_fsg;
 static struct usb_gadget_driver		fsg_driver;
 
-static void	close_backing_file(struct lun *curlun);
-
 
 /*-------------------------------------------------------------------------*/
 
-#ifdef DUMP_MSGS
-
-static void dump_msg(struct fsg_dev *fsg, const char *label,
-		const u8 *buf, unsigned int length)
-{
-	if (length < 512) {
-		DBG(fsg, "%s, length %u:\n", label, length);
-		print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET,
-				16, 1, buf, length, 0);
-	}
-}
-
-static void dump_cdb(struct fsg_dev *fsg)
-{}
-
-#else
-
-static void dump_msg(struct fsg_dev *fsg, const char *label,
-		const u8 *buf, unsigned int length)
-{}
-
-#ifdef VERBOSE_DEBUG
-
-static void dump_cdb(struct fsg_dev *fsg)
-{
-	print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE,
-			16, 1, fsg->cmnd, fsg->cmnd_size, 0);
-}
-
-#else
-
-static void dump_cdb(struct fsg_dev *fsg)
-{}
-
-#endif /* VERBOSE_DEBUG */
-#endif /* DUMP_MSGS */
-
-
 static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep)
 {
 	const char	*name;
@@ -799,26 +522,11 @@
 
 /*-------------------------------------------------------------------------*/
 
-/* Routines for unaligned data access */
-
-static u32 get_unaligned_be24(u8 *buf)
-{
-	return 0xffffff & (u32) get_unaligned_be32(buf - 1);
-}
-
-
-/*-------------------------------------------------------------------------*/
-
 /*
  * DESCRIPTORS ... most are static, but strings and (full) configuration
  * descriptors are built on demand.  Also the (static) config and interface
  * descriptors are adjusted during fsg_bind().
  */
-#define STRING_MANUFACTURER	1
-#define STRING_PRODUCT		2
-#define STRING_SERIAL		3
-#define STRING_CONFIG		4
-#define STRING_INTERFACE	5
 
 /* There is only one configuration. */
 #define	CONFIG_VALUE		1
@@ -832,13 +540,13 @@
 	.bDeviceClass =		USB_CLASS_PER_INTERFACE,
 
 	/* The next three values can be overridden by module parameters */
-	.idVendor =		cpu_to_le16(DRIVER_VENDOR_ID),
-	.idProduct =		cpu_to_le16(DRIVER_PRODUCT_ID),
+	.idVendor =		cpu_to_le16(FSG_VENDOR_ID),
+	.idProduct =		cpu_to_le16(FSG_PRODUCT_ID),
 	.bcdDevice =		cpu_to_le16(0xffff),
 
-	.iManufacturer =	STRING_MANUFACTURER,
-	.iProduct =		STRING_PRODUCT,
-	.iSerialNumber =	STRING_SERIAL,
+	.iManufacturer =	FSG_STRING_MANUFACTURER,
+	.iProduct =		FSG_STRING_PRODUCT,
+	.iSerialNumber =	FSG_STRING_SERIAL,
 	.bNumConfigurations =	1,
 };
 
@@ -850,86 +558,12 @@
 	/* wTotalLength computed by usb_gadget_config_buf() */
 	.bNumInterfaces =	1,
 	.bConfigurationValue =	CONFIG_VALUE,
-	.iConfiguration =	STRING_CONFIG,
+	.iConfiguration =	FSG_STRING_CONFIG,
 	.bmAttributes =		USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
 	.bMaxPower =		CONFIG_USB_GADGET_VBUS_DRAW / 2,
 };
 
-static struct usb_otg_descriptor
-otg_desc = {
-	.bLength =		sizeof(otg_desc),
-	.bDescriptorType =	USB_DT_OTG,
 
-	.bmAttributes =		USB_OTG_SRP,
-};
-
-/* There is only one interface. */
-
-static struct usb_interface_descriptor
-intf_desc = {
-	.bLength =		sizeof intf_desc,
-	.bDescriptorType =	USB_DT_INTERFACE,
-
-	.bNumEndpoints =	2,		// Adjusted during fsg_bind()
-	.bInterfaceClass =	USB_CLASS_MASS_STORAGE,
-	.bInterfaceSubClass =	USB_SC_SCSI,	// Adjusted during fsg_bind()
-	.bInterfaceProtocol =	USB_PR_BULK,	// Adjusted during fsg_bind()
-	.iInterface =		STRING_INTERFACE,
-};
-
-/* Three full-speed endpoint descriptors: bulk-in, bulk-out,
- * and interrupt-in. */
-
-static struct usb_endpoint_descriptor
-fs_bulk_in_desc = {
-	.bLength =		USB_DT_ENDPOINT_SIZE,
-	.bDescriptorType =	USB_DT_ENDPOINT,
-
-	.bEndpointAddress =	USB_DIR_IN,
-	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
-	/* wMaxPacketSize set by autoconfiguration */
-};
-
-static struct usb_endpoint_descriptor
-fs_bulk_out_desc = {
-	.bLength =		USB_DT_ENDPOINT_SIZE,
-	.bDescriptorType =	USB_DT_ENDPOINT,
-
-	.bEndpointAddress =	USB_DIR_OUT,
-	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
-	/* wMaxPacketSize set by autoconfiguration */
-};
-
-static struct usb_endpoint_descriptor
-fs_intr_in_desc = {
-	.bLength =		USB_DT_ENDPOINT_SIZE,
-	.bDescriptorType =	USB_DT_ENDPOINT,
-
-	.bEndpointAddress =	USB_DIR_IN,
-	.bmAttributes =		USB_ENDPOINT_XFER_INT,
-	.wMaxPacketSize =	cpu_to_le16(2),
-	.bInterval =		32,	// frames -> 32 ms
-};
-
-static const struct usb_descriptor_header *fs_function[] = {
-	(struct usb_descriptor_header *) &otg_desc,
-	(struct usb_descriptor_header *) &intf_desc,
-	(struct usb_descriptor_header *) &fs_bulk_in_desc,
-	(struct usb_descriptor_header *) &fs_bulk_out_desc,
-	(struct usb_descriptor_header *) &fs_intr_in_desc,
-	NULL,
-};
-#define FS_FUNCTION_PRE_EP_ENTRIES	2
-
-
-/*
- * USB 2.0 devices need to expose both high speed and full speed
- * descriptors, unless they only run at full speed.
- *
- * That means alternate endpoint descriptors (bigger packets)
- * and a "device qualifier" ... plus more construction options
- * for the config descriptor.
- */
 static struct usb_qualifier_descriptor
 dev_qualifier = {
 	.bLength =		sizeof dev_qualifier,
@@ -941,78 +575,6 @@
 	.bNumConfigurations =	1,
 };
 
-static struct usb_endpoint_descriptor
-hs_bulk_in_desc = {
-	.bLength =		USB_DT_ENDPOINT_SIZE,
-	.bDescriptorType =	USB_DT_ENDPOINT,
-
-	/* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */
-	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
-	.wMaxPacketSize =	cpu_to_le16(512),
-};
-
-static struct usb_endpoint_descriptor
-hs_bulk_out_desc = {
-	.bLength =		USB_DT_ENDPOINT_SIZE,
-	.bDescriptorType =	USB_DT_ENDPOINT,
-
-	/* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */
-	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
-	.wMaxPacketSize =	cpu_to_le16(512),
-	.bInterval =		1,	// NAK every 1 uframe
-};
-
-static struct usb_endpoint_descriptor
-hs_intr_in_desc = {
-	.bLength =		USB_DT_ENDPOINT_SIZE,
-	.bDescriptorType =	USB_DT_ENDPOINT,
-
-	/* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */
-	.bmAttributes =		USB_ENDPOINT_XFER_INT,
-	.wMaxPacketSize =	cpu_to_le16(2),
-	.bInterval =		9,	// 2**(9-1) = 256 uframes -> 32 ms
-};
-
-static const struct usb_descriptor_header *hs_function[] = {
-	(struct usb_descriptor_header *) &otg_desc,
-	(struct usb_descriptor_header *) &intf_desc,
-	(struct usb_descriptor_header *) &hs_bulk_in_desc,
-	(struct usb_descriptor_header *) &hs_bulk_out_desc,
-	(struct usb_descriptor_header *) &hs_intr_in_desc,
-	NULL,
-};
-#define HS_FUNCTION_PRE_EP_ENTRIES	2
-
-/* Maxpacket and other transfer characteristics vary by speed. */
-static struct usb_endpoint_descriptor *
-ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs,
-		struct usb_endpoint_descriptor *hs)
-{
-	if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
-		return hs;
-	return fs;
-}
-
-
-/* The CBI specification limits the serial string to 12 uppercase hexadecimal
- * characters. */
-static char				manufacturer[64];
-static char				serial[13];
-
-/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
-static struct usb_string		strings[] = {
-	{STRING_MANUFACTURER,	manufacturer},
-	{STRING_PRODUCT,	longname},
-	{STRING_SERIAL,		serial},
-	{STRING_CONFIG,		"Self-powered"},
-	{STRING_INTERFACE,	"Mass Storage"},
-	{}
-};
-
-static struct usb_gadget_strings	stringtab = {
-	.language	= 0x0409,		// en-us
-	.strings	= strings,
-};
 
 
 /*
@@ -1032,10 +594,9 @@
 
 	if (gadget_is_dualspeed(gadget) && type == USB_DT_OTHER_SPEED_CONFIG)
 		speed = (USB_SPEED_FULL + USB_SPEED_HIGH) - speed;
-	if (gadget_is_dualspeed(gadget) && speed == USB_SPEED_HIGH)
-		function = hs_function;
-	else
-		function = fs_function;
+	function = gadget_is_dualspeed(gadget) && speed == USB_SPEED_HIGH
+		? (const struct usb_descriptor_header **)fsg_hs_function
+		: (const struct usb_descriptor_header **)fsg_fs_function;
 
 	/* for now, don't advertise srp-only devices */
 	if (!gadget_is_otg(gadget))
@@ -1386,7 +947,7 @@
 			VDBG(fsg, "get string descriptor\n");
 
 			/* wIndex == language code */
-			value = usb_gadget_get_string(&stringtab,
+			value = usb_gadget_get_string(&fsg_stringtab,
 					w_value & 0xff, req->buf);
 			break;
 		}
@@ -1551,7 +1112,7 @@
 
 static int do_read(struct fsg_dev *fsg)
 {
-	struct lun		*curlun = fsg->curlun;
+	struct fsg_lun		*curlun = fsg->curlun;
 	u32			lba;
 	struct fsg_buffhd	*bh;
 	int			rc;
@@ -1677,7 +1238,7 @@
 
 static int do_write(struct fsg_dev *fsg)
 {
-	struct lun		*curlun = fsg->curlun;
+	struct fsg_lun		*curlun = fsg->curlun;
 	u32			lba;
 	struct fsg_buffhd	*bh;
 	int			get_some_more;
@@ -1713,7 +1274,7 @@
 		}
 		if (fsg->cmnd[1] & 0x08) {	// FUA
 			spin_lock(&curlun->filp->f_lock);
-			curlun->filp->f_flags |= O_SYNC;
+			curlun->filp->f_flags |= O_DSYNC;
 			spin_unlock(&curlun->filp->f_lock);
 		}
 	}
@@ -1864,33 +1425,14 @@
 
 /*-------------------------------------------------------------------------*/
 
-/* Sync the file data, don't bother with the metadata.
- * This code was copied from fs/buffer.c:sys_fdatasync(). */
-static int fsync_sub(struct lun *curlun)
-{
-	struct file	*filp = curlun->filp;
-
-	if (curlun->ro || !filp)
-		return 0;
-	return vfs_fsync(filp, filp->f_path.dentry, 1);
-}
-
-static void fsync_all(struct fsg_dev *fsg)
-{
-	int	i;
-
-	for (i = 0; i < fsg->nluns; ++i)
-		fsync_sub(&fsg->luns[i]);
-}
-
 static int do_synchronize_cache(struct fsg_dev *fsg)
 {
-	struct lun	*curlun = fsg->curlun;
+	struct fsg_lun	*curlun = fsg->curlun;
 	int		rc;
 
 	/* We ignore the requested LBA and write out all file's
 	 * dirty data buffers. */
-	rc = fsync_sub(curlun);
+	rc = fsg_lun_fsync_sub(curlun);
 	if (rc)
 		curlun->sense_data = SS_WRITE_ERROR;
 	return 0;
@@ -1899,7 +1441,7 @@
 
 /*-------------------------------------------------------------------------*/
 
-static void invalidate_sub(struct lun *curlun)
+static void invalidate_sub(struct fsg_lun *curlun)
 {
 	struct file	*filp = curlun->filp;
 	struct inode	*inode = filp->f_path.dentry->d_inode;
@@ -1911,7 +1453,7 @@
 
 static int do_verify(struct fsg_dev *fsg)
 {
-	struct lun		*curlun = fsg->curlun;
+	struct fsg_lun		*curlun = fsg->curlun;
 	u32			lba;
 	u32			verification_length;
 	struct fsg_buffhd	*bh = fsg->next_buffhd_to_fill;
@@ -1944,7 +1486,7 @@
 	file_offset = ((loff_t) lba) << 9;
 
 	/* Write out all the dirty buffers before invalidating them */
-	fsync_sub(curlun);
+	fsg_lun_fsync_sub(curlun);
 	if (signal_pending(current))
 		return -EINTR;
 
@@ -2041,7 +1583,7 @@
 
 static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
-	struct lun	*curlun = fsg->curlun;
+	struct fsg_lun	*curlun = fsg->curlun;
 	u8		*buf = (u8 *) bh->buf;
 	u32		sd, sdinfo;
 	int		valid;
@@ -2095,7 +1637,7 @@
 
 static int do_read_capacity(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
-	struct lun	*curlun = fsg->curlun;
+	struct fsg_lun	*curlun = fsg->curlun;
 	u32		lba = get_unaligned_be32(&fsg->cmnd[2]);
 	int		pmi = fsg->cmnd[8];
 	u8		*buf = (u8 *) bh->buf;
@@ -2113,27 +1655,9 @@
 }
 
 
-static void store_cdrom_address(u8 *dest, int msf, u32 addr)
-{
-	if (msf) {
-		/* Convert to Minutes-Seconds-Frames */
-		addr >>= 2;		/* Convert to 2048-byte frames */
-		addr += 2*75;		/* Lead-in occupies 2 seconds */
-		dest[3] = addr % 75;	/* Frames */
-		addr /= 75;
-		dest[2] = addr % 60;	/* Seconds */
-		addr /= 60;
-		dest[1] = addr;		/* Minutes */
-		dest[0] = 0;		/* Reserved */
-	} else {
-		/* Absolute sector */
-		put_unaligned_be32(addr, dest);
-	}
-}
-
 static int do_read_header(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
-	struct lun	*curlun = fsg->curlun;
+	struct fsg_lun	*curlun = fsg->curlun;
 	int		msf = fsg->cmnd[1] & 0x02;
 	u32		lba = get_unaligned_be32(&fsg->cmnd[2]);
 	u8		*buf = (u8 *) bh->buf;
@@ -2156,7 +1680,7 @@
 
 static int do_read_toc(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
-	struct lun	*curlun = fsg->curlun;
+	struct fsg_lun	*curlun = fsg->curlun;
 	int		msf = fsg->cmnd[1] & 0x02;
 	int		start_track = fsg->cmnd[6];
 	u8		*buf = (u8 *) bh->buf;
@@ -2184,7 +1708,7 @@
 
 static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
-	struct lun	*curlun = fsg->curlun;
+	struct fsg_lun	*curlun = fsg->curlun;
 	int		mscmnd = fsg->cmnd[0];
 	u8		*buf = (u8 *) bh->buf;
 	u8		*buf0 = buf;
@@ -2265,7 +1789,7 @@
 
 static int do_start_stop(struct fsg_dev *fsg)
 {
-	struct lun	*curlun = fsg->curlun;
+	struct fsg_lun	*curlun = fsg->curlun;
 	int		loej, start;
 
 	if (!mod_data.removable) {
@@ -2295,7 +1819,7 @@
 		if (loej) {		// Simulate an unload/eject
 			up_read(&fsg->filesem);
 			down_write(&fsg->filesem);
-			close_backing_file(curlun);
+			fsg_lun_close(curlun);
 			up_write(&fsg->filesem);
 			down_read(&fsg->filesem);
 		}
@@ -2303,7 +1827,7 @@
 
 		/* Our emulation doesn't support mounting; the medium is
 		 * available for use as soon as it is loaded. */
-		if (!backing_file_is_open(curlun)) {
+		if (!fsg_lun_is_open(curlun)) {
 			curlun->sense_data = SS_MEDIUM_NOT_PRESENT;
 			return -EINVAL;
 		}
@@ -2315,7 +1839,7 @@
 
 static int do_prevent_allow(struct fsg_dev *fsg)
 {
-	struct lun	*curlun = fsg->curlun;
+	struct fsg_lun	*curlun = fsg->curlun;
 	int		prevent;
 
 	if (!mod_data.removable) {
@@ -2330,7 +1854,7 @@
 	}
 
 	if (curlun->prevent_medium_removal && !prevent)
-		fsync_sub(curlun);
+		fsg_lun_fsync_sub(curlun);
 	curlun->prevent_medium_removal = prevent;
 	return 0;
 }
@@ -2339,7 +1863,7 @@
 static int do_read_format_capacities(struct fsg_dev *fsg,
 			struct fsg_buffhd *bh)
 {
-	struct lun	*curlun = fsg->curlun;
+	struct fsg_lun	*curlun = fsg->curlun;
 	u8		*buf = (u8 *) bh->buf;
 
 	buf[0] = buf[1] = buf[2] = 0;
@@ -2356,7 +1880,7 @@
 
 static int do_mode_select(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
-	struct lun	*curlun = fsg->curlun;
+	struct fsg_lun	*curlun = fsg->curlun;
 
 	/* We don't support MODE SELECT */
 	curlun->sense_data = SS_INVALID_COMMAND;
@@ -2599,7 +2123,7 @@
 
 static int send_status(struct fsg_dev *fsg)
 {
-	struct lun		*curlun = fsg->curlun;
+	struct fsg_lun		*curlun = fsg->curlun;
 	struct fsg_buffhd	*bh;
 	int			rc;
 	u8			status = USB_STATUS_PASS;
@@ -2691,7 +2215,7 @@
 	int			lun = fsg->cmnd[1] >> 5;
 	static const char	dirletter[4] = {'u', 'o', 'i', 'n'};
 	char			hdlen[20];
-	struct lun		*curlun;
+	struct fsg_lun		*curlun;
 
 	/* Adjust the expected cmnd_size for protocol encapsulation padding.
 	 * Transparent SCSI doesn't pad. */
@@ -2820,7 +2344,7 @@
 
 	/* If the medium isn't mounted and the command needs to access
 	 * it, return an error. */
-	if (curlun && !backing_file_is_open(curlun) && needs_medium) {
+	if (curlun && !fsg_lun_is_open(curlun) && needs_medium) {
 		curlun->sense_data = SS_MEDIUM_NOT_PRESENT;
 		return -EINVAL;
 	}
@@ -3075,8 +2599,8 @@
 
 static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
-	struct usb_request	*req = bh->outreq;
-	struct bulk_cb_wrap	*cbw = req->buf;
+	struct usb_request		*req = bh->outreq;
+	struct fsg_bulk_cb_wrap	*cbw = req->buf;
 
 	/* Was this a real packet?  Should it be ignored? */
 	if (req->status || test_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags))
@@ -3105,7 +2629,7 @@
 	}
 
 	/* Is the CBW meaningful? */
-	if (cbw->Lun >= MAX_LUNS || cbw->Flags & ~USB_BULK_IN_FLAG ||
+	if (cbw->Lun >= FSG_MAX_LUNS || cbw->Flags & ~USB_BULK_IN_FLAG ||
 			cbw->Length <= 0 || cbw->Length > MAX_COMMAND_SIZE) {
 		DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, "
 				"cmdlen %u\n",
@@ -3238,7 +2762,7 @@
 
 reset:
 	/* Deallocate the requests */
-	for (i = 0; i < NUM_BUFFERS; ++i) {
+	for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
 		struct fsg_buffhd *bh = &fsg->buffhds[i];
 
 		if (bh->inreq) {
@@ -3276,12 +2800,14 @@
 	DBG(fsg, "set interface %d\n", altsetting);
 
 	/* Enable the endpoints */
-	d = ep_desc(fsg->gadget, &fs_bulk_in_desc, &hs_bulk_in_desc);
+	d = fsg_ep_desc(fsg->gadget,
+			&fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc);
 	if ((rc = enable_endpoint(fsg, fsg->bulk_in, d)) != 0)
 		goto reset;
 	fsg->bulk_in_enabled = 1;
 
-	d = ep_desc(fsg->gadget, &fs_bulk_out_desc, &hs_bulk_out_desc);
+	d = fsg_ep_desc(fsg->gadget,
+			&fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc);
 	if ((rc = enable_endpoint(fsg, fsg->bulk_out, d)) != 0)
 		goto reset;
 	fsg->bulk_out_enabled = 1;
@@ -3289,14 +2815,15 @@
 	clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
 
 	if (transport_is_cbi()) {
-		d = ep_desc(fsg->gadget, &fs_intr_in_desc, &hs_intr_in_desc);
+		d = fsg_ep_desc(fsg->gadget,
+				&fsg_fs_intr_in_desc, &fsg_hs_intr_in_desc);
 		if ((rc = enable_endpoint(fsg, fsg->intr_in, d)) != 0)
 			goto reset;
 		fsg->intr_in_enabled = 1;
 	}
 
 	/* Allocate the requests */
-	for (i = 0; i < NUM_BUFFERS; ++i) {
+	for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
 		struct fsg_buffhd	*bh = &fsg->buffhds[i];
 
 		if ((rc = alloc_request(fsg, fsg->bulk_in, &bh->inreq)) != 0)
@@ -3372,7 +2899,7 @@
 	struct fsg_buffhd	*bh;
 	enum fsg_state		old_state;
 	u8			new_config;
-	struct lun		*curlun;
+	struct fsg_lun		*curlun;
 	unsigned int		exception_req_tag;
 	int			rc;
 
@@ -3392,7 +2919,7 @@
 	/* Cancel all the pending transfers */
 	if (fsg->intreq_busy)
 		usb_ep_dequeue(fsg->intr_in, fsg->intreq);
-	for (i = 0; i < NUM_BUFFERS; ++i) {
+	for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
 		bh = &fsg->buffhds[i];
 		if (bh->inreq_busy)
 			usb_ep_dequeue(fsg->bulk_in, bh->inreq);
@@ -3403,7 +2930,7 @@
 	/* Wait until everything is idle */
 	for (;;) {
 		num_active = fsg->intreq_busy;
-		for (i = 0; i < NUM_BUFFERS; ++i) {
+		for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
 			bh = &fsg->buffhds[i];
 			num_active += bh->inreq_busy + bh->outreq_busy;
 		}
@@ -3425,7 +2952,7 @@
 	 * state, and the exception.  Then invoke the handler. */
 	spin_lock_irq(&fsg->lock);
 
-	for (i = 0; i < NUM_BUFFERS; ++i) {
+	for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
 		bh = &fsg->buffhds[i];
 		bh->state = BUF_STATE_EMPTY;
 	}
@@ -3506,7 +3033,8 @@
 		break;
 
 	case FSG_STATE_DISCONNECT:
-		fsync_all(fsg);
+		for (i = 0; i < fsg->nluns; ++i)
+			fsg_lun_fsync_sub(fsg->luns + i);
 		do_set_config(fsg, 0);		// Unconfigured state
 		break;
 
@@ -3595,201 +3123,10 @@
 
 /*-------------------------------------------------------------------------*/
 
-/* If the next two routines are called while the gadget is registered,
- * the caller must own fsg->filesem for writing. */
-
-static int open_backing_file(struct lun *curlun, const char *filename)
-{
-	int				ro;
-	struct file			*filp = NULL;
-	int				rc = -EINVAL;
-	struct inode			*inode = NULL;
-	loff_t				size;
-	loff_t				num_sectors;
-	loff_t				min_sectors;
-
-	/* R/W if we can, R/O if we must */
-	ro = curlun->ro;
-	if (!ro) {
-		filp = filp_open(filename, O_RDWR | O_LARGEFILE, 0);
-		if (-EROFS == PTR_ERR(filp))
-			ro = 1;
-	}
-	if (ro)
-		filp = filp_open(filename, O_RDONLY | O_LARGEFILE, 0);
-	if (IS_ERR(filp)) {
-		LINFO(curlun, "unable to open backing file: %s\n", filename);
-		return PTR_ERR(filp);
-	}
-
-	if (!(filp->f_mode & FMODE_WRITE))
-		ro = 1;
-
-	if (filp->f_path.dentry)
-		inode = filp->f_path.dentry->d_inode;
-	if (inode && S_ISBLK(inode->i_mode)) {
-		if (bdev_read_only(inode->i_bdev))
-			ro = 1;
-	} else if (!inode || !S_ISREG(inode->i_mode)) {
-		LINFO(curlun, "invalid file type: %s\n", filename);
-		goto out;
-	}
-
-	/* If we can't read the file, it's no good.
-	 * If we can't write the file, use it read-only. */
-	if (!filp->f_op || !(filp->f_op->read || filp->f_op->aio_read)) {
-		LINFO(curlun, "file not readable: %s\n", filename);
-		goto out;
-	}
-	if (!(filp->f_op->write || filp->f_op->aio_write))
-		ro = 1;
-
-	size = i_size_read(inode->i_mapping->host);
-	if (size < 0) {
-		LINFO(curlun, "unable to find file size: %s\n", filename);
-		rc = (int) size;
-		goto out;
-	}
-	num_sectors = size >> 9;	// File size in 512-byte blocks
-	min_sectors = 1;
-	if (mod_data.cdrom) {
-		num_sectors &= ~3;	// Reduce to a multiple of 2048
-		min_sectors = 300*4;	// Smallest track is 300 frames
-		if (num_sectors >= 256*60*75*4) {
-			num_sectors = (256*60*75 - 1) * 4;
-			LINFO(curlun, "file too big: %s\n", filename);
-			LINFO(curlun, "using only first %d blocks\n",
-					(int) num_sectors);
-		}
-	}
-	if (num_sectors < min_sectors) {
-		LINFO(curlun, "file too small: %s\n", filename);
-		rc = -ETOOSMALL;
-		goto out;
-	}
-
-	get_file(filp);
-	curlun->ro = ro;
-	curlun->filp = filp;
-	curlun->file_length = size;
-	curlun->num_sectors = num_sectors;
-	LDBG(curlun, "open backing file: %s\n", filename);
-	rc = 0;
-
-out:
-	filp_close(filp, current->files);
-	return rc;
-}
-
-
-static void close_backing_file(struct lun *curlun)
-{
-	if (curlun->filp) {
-		LDBG(curlun, "close backing file\n");
-		fput(curlun->filp);
-		curlun->filp = NULL;
-	}
-}
-
-
-static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct lun	*curlun = dev_to_lun(dev);
-
-	return sprintf(buf, "%d\n", curlun->ro);
-}
-
-static ssize_t show_file(struct device *dev, struct device_attribute *attr,
-		char *buf)
-{
-	struct lun	*curlun = dev_to_lun(dev);
-	struct fsg_dev	*fsg = dev_get_drvdata(dev);
-	char		*p;
-	ssize_t		rc;
-
-	down_read(&fsg->filesem);
-	if (backing_file_is_open(curlun)) {	// Get the complete pathname
-		p = d_path(&curlun->filp->f_path, buf, PAGE_SIZE - 1);
-		if (IS_ERR(p))
-			rc = PTR_ERR(p);
-		else {
-			rc = strlen(p);
-			memmove(buf, p, rc);
-			buf[rc] = '\n';		// Add a newline
-			buf[++rc] = 0;
-		}
-	} else {				// No file, return 0 bytes
-		*buf = 0;
-		rc = 0;
-	}
-	up_read(&fsg->filesem);
-	return rc;
-}
-
-
-static ssize_t store_ro(struct device *dev, struct device_attribute *attr,
-		const char *buf, size_t count)
-{
-	ssize_t		rc = count;
-	struct lun	*curlun = dev_to_lun(dev);
-	struct fsg_dev	*fsg = dev_get_drvdata(dev);
-	int		i;
-
-	if (sscanf(buf, "%d", &i) != 1)
-		return -EINVAL;
-
-	/* Allow the write-enable status to change only while the backing file
-	 * is closed. */
-	down_read(&fsg->filesem);
-	if (backing_file_is_open(curlun)) {
-		LDBG(curlun, "read-only status change prevented\n");
-		rc = -EBUSY;
-	} else {
-		curlun->ro = !!i;
-		LDBG(curlun, "read-only status set to %d\n", curlun->ro);
-	}
-	up_read(&fsg->filesem);
-	return rc;
-}
-
-static ssize_t store_file(struct device *dev, struct device_attribute *attr,
-		const char *buf, size_t count)
-{
-	struct lun	*curlun = dev_to_lun(dev);
-	struct fsg_dev	*fsg = dev_get_drvdata(dev);
-	int		rc = 0;
-
-	if (curlun->prevent_medium_removal && backing_file_is_open(curlun)) {
-		LDBG(curlun, "eject attempt prevented\n");
-		return -EBUSY;				// "Door is locked"
-	}
-
-	/* Remove a trailing newline */
-	if (count > 0 && buf[count-1] == '\n')
-		((char *) buf)[count-1] = 0;		// Ugh!
-
-	/* Eject current medium */
-	down_write(&fsg->filesem);
-	if (backing_file_is_open(curlun)) {
-		close_backing_file(curlun);
-		curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT;
-	}
-
-	/* Load new medium */
-	if (count > 0 && buf[0]) {
-		rc = open_backing_file(curlun, buf);
-		if (rc == 0)
-			curlun->unit_attention_data =
-					SS_NOT_READY_TO_READY_TRANSITION;
-	}
-	up_write(&fsg->filesem);
-	return (rc < 0 ? rc : count);
-}
-
 
 /* The write permissions and store_xxx pointers are set in fsg_bind() */
-static DEVICE_ATTR(ro, 0444, show_ro, NULL);
-static DEVICE_ATTR(file, 0444, show_file, NULL);
+static DEVICE_ATTR(ro, 0444, fsg_show_ro, NULL);
+static DEVICE_ATTR(file, 0444, fsg_show_file, NULL);
 
 
 /*-------------------------------------------------------------------------*/
@@ -3804,7 +3141,9 @@
 
 static void lun_release(struct device *dev)
 {
-	struct fsg_dev	*fsg = dev_get_drvdata(dev);
+	struct rw_semaphore	*filesem = dev_get_drvdata(dev);
+	struct fsg_dev		*fsg =
+		container_of(filesem, struct fsg_dev, filesem);
 
 	kref_put(&fsg->ref, fsg_release);
 }
@@ -3813,7 +3152,7 @@
 {
 	struct fsg_dev		*fsg = get_gadget_data(gadget);
 	int			i;
-	struct lun		*curlun;
+	struct fsg_lun		*curlun;
 	struct usb_request	*req = fsg->ep0req;
 
 	DBG(fsg, "unbind\n");
@@ -3825,7 +3164,7 @@
 		if (curlun->registered) {
 			device_remove_file(&curlun->dev, &dev_attr_ro);
 			device_remove_file(&curlun->dev, &dev_attr_file);
-			close_backing_file(curlun);
+			fsg_lun_close(curlun);
 			device_unregister(&curlun->dev);
 			curlun->registered = 0;
 		}
@@ -3841,7 +3180,7 @@
 	}
 
 	/* Free the data buffers */
-	for (i = 0; i < NUM_BUFFERS; ++i)
+	for (i = 0; i < FSG_NUM_BUFFERS; ++i)
 		kfree(fsg->buffhds[i].buf);
 
 	/* Free the request and buffer for endpoint 0 */
@@ -3948,7 +3287,7 @@
 	struct fsg_dev		*fsg = the_fsg;
 	int			rc;
 	int			i;
-	struct lun		*curlun;
+	struct fsg_lun		*curlun;
 	struct usb_ep		*ep;
 	struct usb_request	*req;
 	char			*pathbuf, *p;
@@ -3963,10 +3302,10 @@
 
 	if (mod_data.removable) {	// Enable the store_xxx attributes
 		dev_attr_file.attr.mode = 0644;
-		dev_attr_file.store = store_file;
+		dev_attr_file.store = fsg_store_file;
 		if (!mod_data.cdrom) {
 			dev_attr_ro.attr.mode = 0644;
-			dev_attr_ro.store = store_ro;
+			dev_attr_ro.store = fsg_store_ro;
 		}
 	}
 
@@ -3974,7 +3313,7 @@
 	i = mod_data.nluns;
 	if (i == 0)
 		i = max(mod_data.num_filenames, 1u);
-	if (i > MAX_LUNS) {
+	if (i > FSG_MAX_LUNS) {
 		ERROR(fsg, "invalid number of LUNs: %d\n", i);
 		rc = -EINVAL;
 		goto out;
@@ -3982,7 +3321,7 @@
 
 	/* Create the LUNs, open their backing files, and register the
 	 * LUN devices in sysfs. */
-	fsg->luns = kzalloc(i * sizeof(struct lun), GFP_KERNEL);
+	fsg->luns = kzalloc(i * sizeof(struct fsg_lun), GFP_KERNEL);
 	if (!fsg->luns) {
 		rc = -ENOMEM;
 		goto out;
@@ -3991,13 +3330,14 @@
 
 	for (i = 0; i < fsg->nluns; ++i) {
 		curlun = &fsg->luns[i];
-		curlun->ro = mod_data.ro[i];
-		if (mod_data.cdrom)
-			curlun->ro = 1;
+		curlun->cdrom = !!mod_data.cdrom;
+		curlun->ro = mod_data.cdrom || mod_data.ro[i];
+		curlun->initially_ro = curlun->ro;
+		curlun->removable = mod_data.removable;
 		curlun->dev.release = lun_release;
 		curlun->dev.parent = &gadget->dev;
 		curlun->dev.driver = &fsg_driver.driver;
-		dev_set_drvdata(&curlun->dev, fsg);
+		dev_set_drvdata(&curlun->dev, &fsg->filesem);
 		dev_set_name(&curlun->dev,"%s-lun%d",
 			     dev_name(&gadget->dev), i);
 
@@ -4016,7 +3356,7 @@
 		kref_get(&fsg->ref);
 
 		if (mod_data.file[i] && *mod_data.file[i]) {
-			if ((rc = open_backing_file(curlun,
+			if ((rc = fsg_lun_open(curlun,
 					mod_data.file[i])) != 0)
 				goto out;
 		} else if (!mod_data.removable) {
@@ -4028,20 +3368,20 @@
 
 	/* Find all the endpoints we will use */
 	usb_ep_autoconfig_reset(gadget);
-	ep = usb_ep_autoconfig(gadget, &fs_bulk_in_desc);
+	ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc);
 	if (!ep)
 		goto autoconf_fail;
 	ep->driver_data = fsg;		// claim the endpoint
 	fsg->bulk_in = ep;
 
-	ep = usb_ep_autoconfig(gadget, &fs_bulk_out_desc);
+	ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_out_desc);
 	if (!ep)
 		goto autoconf_fail;
 	ep->driver_data = fsg;		// claim the endpoint
 	fsg->bulk_out = ep;
 
 	if (transport_is_cbi()) {
-		ep = usb_ep_autoconfig(gadget, &fs_intr_in_desc);
+		ep = usb_ep_autoconfig(gadget, &fsg_fs_intr_in_desc);
 		if (!ep)
 			goto autoconf_fail;
 		ep->driver_data = fsg;		// claim the endpoint
@@ -4055,28 +3395,28 @@
 	device_desc.bcdDevice = cpu_to_le16(mod_data.release);
 
 	i = (transport_is_cbi() ? 3 : 2);	// Number of endpoints
-	intf_desc.bNumEndpoints = i;
-	intf_desc.bInterfaceSubClass = mod_data.protocol_type;
-	intf_desc.bInterfaceProtocol = mod_data.transport_type;
-	fs_function[i + FS_FUNCTION_PRE_EP_ENTRIES] = NULL;
+	fsg_intf_desc.bNumEndpoints = i;
+	fsg_intf_desc.bInterfaceSubClass = mod_data.protocol_type;
+	fsg_intf_desc.bInterfaceProtocol = mod_data.transport_type;
+	fsg_fs_function[i + FSG_FS_FUNCTION_PRE_EP_ENTRIES] = NULL;
 
 	if (gadget_is_dualspeed(gadget)) {
-		hs_function[i + HS_FUNCTION_PRE_EP_ENTRIES] = NULL;
+		fsg_hs_function[i + FSG_HS_FUNCTION_PRE_EP_ENTRIES] = NULL;
 
 		/* Assume ep0 uses the same maxpacket value for both speeds */
 		dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket;
 
 		/* Assume endpoint addresses are the same for both speeds */
-		hs_bulk_in_desc.bEndpointAddress =
-				fs_bulk_in_desc.bEndpointAddress;
-		hs_bulk_out_desc.bEndpointAddress =
-				fs_bulk_out_desc.bEndpointAddress;
-		hs_intr_in_desc.bEndpointAddress =
-				fs_intr_in_desc.bEndpointAddress;
+		fsg_hs_bulk_in_desc.bEndpointAddress =
+			fsg_fs_bulk_in_desc.bEndpointAddress;
+		fsg_hs_bulk_out_desc.bEndpointAddress =
+			fsg_fs_bulk_out_desc.bEndpointAddress;
+		fsg_hs_intr_in_desc.bEndpointAddress =
+			fsg_fs_intr_in_desc.bEndpointAddress;
 	}
 
 	if (gadget_is_otg(gadget))
-		otg_desc.bmAttributes |= USB_OTG_HNP;
+		fsg_otg_desc.bmAttributes |= USB_OTG_HNP;
 
 	rc = -ENOMEM;
 
@@ -4090,7 +3430,7 @@
 	req->complete = ep0_complete;
 
 	/* Allocate the data buffers */
-	for (i = 0; i < NUM_BUFFERS; ++i) {
+	for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
 		struct fsg_buffhd	*bh = &fsg->buffhds[i];
 
 		/* Allocate for the bulk-in endpoint.  We assume that
@@ -4101,23 +3441,24 @@
 			goto out;
 		bh->next = bh + 1;
 	}
-	fsg->buffhds[NUM_BUFFERS - 1].next = &fsg->buffhds[0];
+	fsg->buffhds[FSG_NUM_BUFFERS - 1].next = &fsg->buffhds[0];
 
 	/* This should reflect the actual gadget power source */
 	usb_gadget_set_selfpowered(gadget);
 
-	snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
+	snprintf(fsg_string_manufacturer, sizeof fsg_string_manufacturer,
+			"%s %s with %s",
 			init_utsname()->sysname, init_utsname()->release,
 			gadget->name);
 
 	/* On a real device, serial[] would be loaded from permanent
 	 * storage.  We just encode it from the driver version string. */
-	for (i = 0; i < sizeof(serial) - 2; i += 2) {
+	for (i = 0; i < sizeof fsg_string_serial - 2; i += 2) {
 		unsigned char		c = DRIVER_VERSION[i / 2];
 
 		if (!c)
 			break;
-		sprintf(&serial[i], "%02X", c);
+		sprintf(&fsg_string_serial[i], "%02X", c);
 	}
 
 	fsg->thread_task = kthread_create(fsg_main_thread, fsg,
@@ -4133,7 +3474,7 @@
 	pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
 	for (i = 0; i < fsg->nluns; ++i) {
 		curlun = &fsg->luns[i];
-		if (backing_file_is_open(curlun)) {
+		if (fsg_lun_is_open(curlun)) {
 			p = NULL;
 			if (pathbuf) {
 				p = d_path(&curlun->filp->f_path,
@@ -4203,7 +3544,7 @@
 #else
 	.speed		= USB_SPEED_FULL,
 #endif
-	.function	= (char *) longname,
+	.function	= (char *) fsg_string_product,
 	.bind		= fsg_bind,
 	.unbind		= fsg_unbind,
 	.disconnect	= fsg_disconnect,
@@ -4212,7 +3553,7 @@
 	.resume		= fsg_resume,
 
 	.driver		= {
-		.name		= (char *) shortname,
+		.name		= DRIVER_NAME,
 		.owner		= THIS_MODULE,
 		// .release = ...
 		// .suspend = ...
diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c
new file mode 100644
index 0000000..19619fb
--- /dev/null
+++ b/drivers/usb/gadget/mass_storage.c
@@ -0,0 +1,240 @@
+/*
+ * mass_storage.c -- Mass Storage USB Gadget
+ *
+ * Copyright (C) 2003-2008 Alan Stern
+ * Copyright (C) 2009 Samsung Electronics
+ *                    Author: Michal Nazarewicz <m.nazarewicz@samsung.com>
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+/*
+ * The Mass Storage Gadget acts as a USB Mass Storage device,
+ * appearing to the host as a disk drive or as a CD-ROM drive.  In
+ * addition to providing an example of a genuinely useful gadget
+ * driver for a USB device, it also illustrates a technique of
+ * double-buffering for increased throughput.  Last but not least, it
+ * gives an easy way to probe the behavior of the Mass Storage drivers
+ * in a USB host.
+ *
+ * Since this file serves only administrative purposes and all the
+ * business logic is implemented in f_mass_storage.* file.  Read
+ * comments in this file for more detailed description.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/utsname.h>
+#include <linux/usb/ch9.h>
+
+
+/*-------------------------------------------------------------------------*/
+
+#define DRIVER_DESC		"Mass Storage Gadget"
+#define DRIVER_VERSION		"2009/09/11"
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module.  So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+
+#include "composite.c"
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+#include "f_mass_storage.c"
+
+/*-------------------------------------------------------------------------*/
+
+static struct usb_device_descriptor msg_device_desc = {
+	.bLength =		sizeof msg_device_desc,
+	.bDescriptorType =	USB_DT_DEVICE,
+
+	.bcdUSB =		cpu_to_le16(0x0200),
+	.bDeviceClass =		USB_CLASS_PER_INTERFACE,
+
+	/* Vendor and product id can be overridden by module parameters.  */
+	.idVendor =		cpu_to_le16(FSG_VENDOR_ID),
+	.idProduct =		cpu_to_le16(FSG_PRODUCT_ID),
+	/* .bcdDevice = f(hardware) */
+	/* .iManufacturer = DYNAMIC */
+	/* .iProduct = DYNAMIC */
+	/* NO SERIAL NUMBER */
+	.bNumConfigurations =	1,
+};
+
+static struct usb_otg_descriptor otg_descriptor = {
+	.bLength =		sizeof otg_descriptor,
+	.bDescriptorType =	USB_DT_OTG,
+
+	/* REVISIT SRP-only hardware is possible, although
+	 * it would not be called "OTG" ...
+	 */
+	.bmAttributes =		USB_OTG_SRP | USB_OTG_HNP,
+};
+
+static const struct usb_descriptor_header *otg_desc[] = {
+	(struct usb_descriptor_header *) &otg_descriptor,
+	NULL,
+};
+
+
+/* string IDs are assigned dynamically */
+
+#define STRING_MANUFACTURER_IDX		0
+#define STRING_PRODUCT_IDX		1
+#define STRING_CONFIGURATION_IDX	2
+
+static char manufacturer[50];
+
+static struct usb_string strings_dev[] = {
+	[STRING_MANUFACTURER_IDX].s = manufacturer,
+	[STRING_PRODUCT_IDX].s = DRIVER_DESC,
+	[STRING_CONFIGURATION_IDX].s = "Self Powered",
+	{  } /* end of list */
+};
+
+static struct usb_gadget_strings stringtab_dev = {
+	.language	= 0x0409,	/* en-us */
+	.strings	= strings_dev,
+};
+
+static struct usb_gadget_strings *dev_strings[] = {
+	&stringtab_dev,
+	NULL,
+};
+
+
+
+/****************************** Configurations ******************************/
+
+static struct fsg_module_parameters mod_data = {
+	.stall = 1
+};
+FSG_MODULE_PARAMETERS(/* no prefix */, mod_data);
+
+static unsigned long msg_registered = 0;
+static void msg_cleanup(void);
+
+static int __init msg_do_config(struct usb_configuration *c)
+{
+	struct fsg_common *common;
+	struct fsg_config config;
+	int ret;
+
+	if (gadget_is_otg(c->cdev->gadget)) {
+		c->descriptors = otg_desc;
+		c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+	}
+
+	fsg_config_from_params(&config, &mod_data);
+	config.thread_exits = (void(*)(struct fsg_common*))&msg_cleanup;
+	common = fsg_common_init(0, c->cdev, &config);
+	if (IS_ERR(common))
+		return PTR_ERR(common);
+
+	ret = fsg_add(c->cdev, c, common);
+	fsg_common_put(common);
+	return ret;
+}
+
+static struct usb_configuration msg_config_driver = {
+	.label			= "Linux File-Backed Storage",
+	.bind			= msg_do_config,
+	.bConfigurationValue	= 1,
+	/* .iConfiguration = DYNAMIC */
+	.bmAttributes		= USB_CONFIG_ATT_SELFPOWER,
+};
+
+
+
+/****************************** Gadget Bind ******************************/
+
+
+static int __init msg_bind(struct usb_composite_dev *cdev)
+{
+	struct usb_gadget *gadget = cdev->gadget;
+	int status;
+
+	/* Allocate string descriptor numbers ... note that string
+	 * contents can be overridden by the composite_dev glue.
+	 */
+
+	/* device descriptor strings: manufacturer, product */
+	snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
+	         init_utsname()->sysname, init_utsname()->release,
+	         gadget->name);
+	status = usb_string_id(cdev);
+	if (status < 0)
+		return status;
+	strings_dev[STRING_MANUFACTURER_IDX].id = status;
+	msg_device_desc.iManufacturer = status;
+
+	status = usb_string_id(cdev);
+	if (status < 0)
+		return status;
+	strings_dev[STRING_PRODUCT_IDX].id = status;
+	msg_device_desc.iProduct = status;
+
+	status = usb_string_id(cdev);
+	if (status < 0)
+		return status;
+	strings_dev[STRING_CONFIGURATION_IDX].id = status;
+	msg_config_driver.iConfiguration = status;
+
+	/* register our second configuration */
+	status = usb_add_config(cdev, &msg_config_driver);
+	if (status < 0)
+		return status;
+
+	dev_info(&gadget->dev, DRIVER_DESC ", version: " DRIVER_VERSION "\n");
+	set_bit(0, &msg_registered);
+	return 0;
+}
+
+
+/****************************** Some noise ******************************/
+
+
+static struct usb_composite_driver msg_driver = {
+	.name		= "g_mass_storage",
+	.dev		= &msg_device_desc,
+	.strings	= dev_strings,
+	.bind		= msg_bind,
+};
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Michal Nazarewicz");
+MODULE_LICENSE("GPL");
+
+static int __init msg_init(void)
+{
+	return usb_composite_register(&msg_driver);
+}
+module_init(msg_init);
+
+static void msg_cleanup(void)
+{
+	if (test_and_clear_bit(0, &msg_registered))
+		usb_composite_unregister(&msg_driver);
+}
+module_exit(msg_cleanup);
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
new file mode 100644
index 0000000..4295601
--- /dev/null
+++ b/drivers/usb/gadget/multi.c
@@ -0,0 +1,358 @@
+/*
+ * multi.c -- Multifunction Composite driver
+ *
+ * Copyright (C) 2008 David Brownell
+ * Copyright (C) 2008 Nokia Corporation
+ * Copyright (C) 2009 Samsung Electronics
+ * Author: Michal Nazarewicz (m.nazarewicz@samsung.com)
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/utsname.h>
+
+
+#if defined USB_ETH_RNDIS
+#  undef USB_ETH_RNDIS
+#endif
+#ifdef CONFIG_USB_ETH_RNDIS
+#  define USB_ETH_RNDIS y
+#endif
+
+
+#define DRIVER_DESC		"Multifunction Composite Gadget"
+#define DRIVER_VERSION		"2009/07/21"
+
+/*-------------------------------------------------------------------------*/
+
+#define MULTI_VENDOR_NUM	0x0525	/* XXX NetChip */
+#define MULTI_PRODUCT_NUM	0xa4ab	/* XXX */
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module.  So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+
+#include "composite.c"
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+
+#include "u_serial.c"
+#include "f_acm.c"
+
+#include "f_ecm.c"
+#include "f_subset.c"
+#ifdef USB_ETH_RNDIS
+#  include "f_rndis.c"
+#  include "rndis.c"
+#endif
+#include "u_ether.c"
+
+#undef DBG     /* u_ether.c has broken idea about macros */
+#undef VDBG    /* so clean up after it */
+#undef ERROR
+#undef INFO
+#include "f_mass_storage.c"
+
+/*-------------------------------------------------------------------------*/
+
+static struct usb_device_descriptor device_desc = {
+	.bLength =		sizeof device_desc,
+	.bDescriptorType =	USB_DT_DEVICE,
+
+	.bcdUSB =		cpu_to_le16(0x0200),
+
+	/* .bDeviceClass =		USB_CLASS_COMM, */
+	/* .bDeviceSubClass =	0, */
+	/* .bDeviceProtocol =	0, */
+	.bDeviceClass =		0xEF,
+	.bDeviceSubClass =	2,
+	.bDeviceProtocol =	1,
+	/* .bMaxPacketSize0 = f(hardware) */
+
+	/* Vendor and product id can be overridden by module parameters.  */
+	.idVendor =		cpu_to_le16(MULTI_VENDOR_NUM),
+	.idProduct =		cpu_to_le16(MULTI_PRODUCT_NUM),
+	/* .bcdDevice = f(hardware) */
+	/* .iManufacturer = DYNAMIC */
+	/* .iProduct = DYNAMIC */
+	/* NO SERIAL NUMBER */
+	.bNumConfigurations =	1,
+};
+
+static struct usb_otg_descriptor otg_descriptor = {
+	.bLength =		sizeof otg_descriptor,
+	.bDescriptorType =	USB_DT_OTG,
+
+	/* REVISIT SRP-only hardware is possible, although
+	 * it would not be called "OTG" ...
+	 */
+	.bmAttributes =		USB_OTG_SRP | USB_OTG_HNP,
+};
+
+static const struct usb_descriptor_header *otg_desc[] = {
+	(struct usb_descriptor_header *) &otg_descriptor,
+	NULL,
+};
+
+
+/* string IDs are assigned dynamically */
+
+#define STRING_MANUFACTURER_IDX		0
+#define STRING_PRODUCT_IDX		1
+
+static char manufacturer[50];
+
+static struct usb_string strings_dev[] = {
+	[STRING_MANUFACTURER_IDX].s = manufacturer,
+	[STRING_PRODUCT_IDX].s = DRIVER_DESC,
+	{  } /* end of list */
+};
+
+static struct usb_gadget_strings stringtab_dev = {
+	.language	= 0x0409,	/* en-us */
+	.strings	= strings_dev,
+};
+
+static struct usb_gadget_strings *dev_strings[] = {
+	&stringtab_dev,
+	NULL,
+};
+
+static u8 hostaddr[ETH_ALEN];
+
+
+
+/****************************** Configurations ******************************/
+
+static struct fsg_module_parameters mod_data = {
+	.stall = 1
+};
+FSG_MODULE_PARAMETERS(/* no prefix */, mod_data);
+
+static struct fsg_common *fsg_common;
+
+
+#ifdef USB_ETH_RNDIS
+
+static int __init rndis_do_config(struct usb_configuration *c)
+{
+	int ret;
+
+	if (gadget_is_otg(c->cdev->gadget)) {
+		c->descriptors = otg_desc;
+		c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+	}
+
+	ret = rndis_bind_config(c, hostaddr);
+	if (ret < 0)
+		return ret;
+
+	ret = acm_bind_config(c, 0);
+	if (ret < 0)
+		return ret;
+
+	ret = fsg_add(c->cdev, c, fsg_common);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static struct usb_configuration rndis_config_driver = {
+	.label			= "Multifunction Composite (RNDIS + MS + ACM)",
+	.bind			= rndis_do_config,
+	.bConfigurationValue	= 2,
+	/* .iConfiguration = DYNAMIC */
+	.bmAttributes		= USB_CONFIG_ATT_SELFPOWER,
+};
+
+#endif
+
+#ifdef CONFIG_USB_G_MULTI_CDC
+
+static int __init cdc_do_config(struct usb_configuration *c)
+{
+	int ret;
+
+	if (gadget_is_otg(c->cdev->gadget)) {
+		c->descriptors = otg_desc;
+		c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+	}
+
+	ret = ecm_bind_config(c, hostaddr);
+	if (ret < 0)
+		return ret;
+
+	ret = acm_bind_config(c, 0);
+	if (ret < 0)
+		return ret;
+
+	ret = fsg_add(c->cdev, c, fsg_common);
+	if (ret < 0)
+		return ret;
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static struct usb_configuration cdc_config_driver = {
+	.label			= "Multifunction Composite (CDC + MS + ACM)",
+	.bind			= cdc_do_config,
+	.bConfigurationValue	= 1,
+	/* .iConfiguration = DYNAMIC */
+	.bmAttributes		= USB_CONFIG_ATT_SELFPOWER,
+};
+
+#endif
+
+
+
+/****************************** Gadget Bind ******************************/
+
+
+static int __init multi_bind(struct usb_composite_dev *cdev)
+{
+	struct usb_gadget *gadget = cdev->gadget;
+	int status, gcnum;
+
+	if (!can_support_ecm(cdev->gadget)) {
+		dev_err(&gadget->dev, "controller '%s' not usable\n",
+		        gadget->name);
+		return -EINVAL;
+	}
+
+	/* set up network link layer */
+	status = gether_setup(cdev->gadget, hostaddr);
+	if (status < 0)
+		return status;
+
+	/* set up serial link layer */
+	status = gserial_setup(cdev->gadget, 1);
+	if (status < 0)
+		goto fail0;
+
+	/* set up mass storage function */
+	fsg_common = fsg_common_from_params(0, cdev, &mod_data);
+	if (IS_ERR(fsg_common)) {
+		status = PTR_ERR(fsg_common);
+		goto fail1;
+	}
+
+
+	gcnum = usb_gadget_controller_number(gadget);
+	if (gcnum >= 0)
+		device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
+	else {
+		/* We assume that can_support_ecm() tells the truth;
+		 * but if the controller isn't recognized at all then
+		 * that assumption is a bit more likely to be wrong.
+		 */
+		WARNING(cdev, "controller '%s' not recognized\n",
+		        gadget->name);
+		device_desc.bcdDevice = cpu_to_le16(0x0300 | 0x0099);
+	}
+
+
+	/* Allocate string descriptor numbers ... note that string
+	 * contents can be overridden by the composite_dev glue.
+	 */
+
+	/* device descriptor strings: manufacturer, product */
+	snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
+	         init_utsname()->sysname, init_utsname()->release,
+	         gadget->name);
+	status = usb_string_id(cdev);
+	if (status < 0)
+		goto fail2;
+	strings_dev[STRING_MANUFACTURER_IDX].id = status;
+	device_desc.iManufacturer = status;
+
+	status = usb_string_id(cdev);
+	if (status < 0)
+		goto fail2;
+	strings_dev[STRING_PRODUCT_IDX].id = status;
+	device_desc.iProduct = status;
+
+#ifdef USB_ETH_RNDIS
+	/* register our first configuration */
+	status = usb_add_config(cdev, &rndis_config_driver);
+	if (status < 0)
+		goto fail2;
+#endif
+
+#ifdef CONFIG_USB_G_MULTI_CDC
+	/* register our second configuration */
+	status = usb_add_config(cdev, &cdc_config_driver);
+	if (status < 0)
+		goto fail2;
+#endif
+
+	dev_info(&gadget->dev, DRIVER_DESC ", version: " DRIVER_VERSION "\n");
+	fsg_common_put(fsg_common);
+	return 0;
+
+fail2:
+	fsg_common_put(fsg_common);
+fail1:
+	gserial_cleanup();
+fail0:
+	gether_cleanup();
+	return status;
+}
+
+static int __exit multi_unbind(struct usb_composite_dev *cdev)
+{
+	gserial_cleanup();
+	gether_cleanup();
+	return 0;
+}
+
+
+/****************************** Some noise ******************************/
+
+
+static struct usb_composite_driver multi_driver = {
+	.name		= "g_multi",
+	.dev		= &device_desc,
+	.strings	= dev_strings,
+	.bind		= multi_bind,
+	.unbind		= __exit_p(multi_unbind),
+};
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Michal Nazarewicz");
+MODULE_LICENSE("GPL");
+
+static int __init g_multi_init(void)
+{
+	return usb_composite_register(&multi_driver);
+}
+module_init(g_multi_init);
+
+static void __exit g_multi_cleanup(void)
+{
+	usb_composite_unregister(&multi_driver);
+}
+module_exit(g_multi_cleanup);
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c
index 1937d8c..adda120 100644
--- a/drivers/usb/gadget/pxa27x_udc.c
+++ b/drivers/usb/gadget/pxa27x_udc.c
@@ -1524,7 +1524,7 @@
  * pxa_udc_wakeup - Force udc device out of suspend
  * @_gadget: usb gadget
  *
- * Returns 0 if succesfull, error code otherwise
+ * Returns 0 if successfull, error code otherwise
  */
 static int pxa_udc_wakeup(struct usb_gadget *_gadget)
 {
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
new file mode 100644
index 0000000..868d8ee
--- /dev/null
+++ b/drivers/usb/gadget/storage_common.c
@@ -0,0 +1,778 @@
+/*
+ * storage_common.c -- Common definitions for mass storage functionality
+ *
+ * Copyright (C) 2003-2008 Alan Stern
+ * Copyeight (C) 2009 Samsung Electronics
+ * Author: Michal Nazarewicz (m.nazarewicz@samsung.com)
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+/*
+ * This file requires the following identifiers used in USB strings to
+ * be defined (each of type pointer to char):
+ *  - fsg_string_manufacturer -- name of the manufacturer
+ *  - fsg_string_product      -- name of the product
+ *  - fsg_string_serial       -- product's serial
+ *  - fsg_string_config       -- name of the configuration
+ *  - fsg_string_interface    -- name of the interface
+ * The first four are only needed when FSG_DESCRIPTORS_DEVICE_STRINGS
+ * macro is defined prior to including this file.
+ */
+
+/*
+ * When FSG_NO_INTR_EP is defined fsg_fs_intr_in_desc and
+ * fsg_hs_intr_in_desc objects as well as
+ * FSG_FS_FUNCTION_PRE_EP_ENTRIES and FSG_HS_FUNCTION_PRE_EP_ENTRIES
+ * macros are not defined.
+ *
+ * When FSG_NO_DEVICE_STRINGS is defined FSG_STRING_MANUFACTURER,
+ * FSG_STRING_PRODUCT, FSG_STRING_SERIAL and FSG_STRING_CONFIG are not
+ * defined (as well as corresponding entries in string tables are
+ * missing) and FSG_STRING_INTERFACE has value of zero.
+ *
+ * When FSG_NO_OTG is defined fsg_otg_desc won't be defined.
+ */
+
+/*
+ * When FSG_BUFFHD_STATIC_BUFFER is defined when this file is included
+ * the fsg_buffhd structure's buf field will be an array of FSG_BUFLEN
+ * characters rather then a pointer to void.
+ */
+
+
+#include <asm/unaligned.h>
+
+
+/* Thanks to NetChip Technologies for donating this product ID.
+ *
+ * DO NOT REUSE THESE IDs with any other driver!!  Ever!!
+ * Instead:  allocate your own, using normal USB-IF procedures. */
+#define FSG_VENDOR_ID	0x0525	/* NetChip */
+#define FSG_PRODUCT_ID	0xa4a5	/* Linux-USB File-backed Storage Gadget */
+
+
+/*-------------------------------------------------------------------------*/
+
+
+#ifndef DEBUG
+#undef VERBOSE_DEBUG
+#undef DUMP_MSGS
+#endif /* !DEBUG */
+
+#ifdef VERBOSE_DEBUG
+#define VLDBG	LDBG
+#else
+#define VLDBG(lun, fmt, args...) do { } while (0)
+#endif /* VERBOSE_DEBUG */
+
+#define LDBG(lun, fmt, args...)   dev_dbg (&(lun)->dev, fmt, ## args)
+#define LERROR(lun, fmt, args...) dev_err (&(lun)->dev, fmt, ## args)
+#define LWARN(lun, fmt, args...)  dev_warn(&(lun)->dev, fmt, ## args)
+#define LINFO(lun, fmt, args...)  dev_info(&(lun)->dev, fmt, ## args)
+
+/* Keep those macros in sync with thos in
+ * include/linux/ubs/composite.h or else GCC will complain.  If they
+ * are identical (the same names of arguments, white spaces in the
+ * same places) GCC will allow redefinition otherwise (even if some
+ * white space is removed or added) warning will be issued.  No
+ * checking if those symbols is defined is performed because warning
+ * is desired when those macros were defined by someone else to mean
+ * something else. */
+#define DBG(d, fmt, args...)     dev_dbg(&(d)->gadget->dev , fmt , ## args)
+#define VDBG(d, fmt, args...)    dev_vdbg(&(d)->gadget->dev , fmt , ## args)
+#define ERROR(d, fmt, args...)   dev_err(&(d)->gadget->dev , fmt , ## args)
+#define WARNING(d, fmt, args...) dev_warn(&(d)->gadget->dev , fmt , ## args)
+#define INFO(d, fmt, args...)    dev_info(&(d)->gadget->dev , fmt , ## args)
+
+
+
+#ifdef DUMP_MSGS
+
+#  define dump_msg(fsg, /* const char * */ label,			\
+		   /* const u8 * */ buf, /* unsigned */ length) do {	\
+	if (length < 512) {						\
+		DBG(fsg, "%s, length %u:\n", label, length);		\
+		print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET,	\
+			       16, 1, buf, length, 0);			\
+	}								\
+} while (0)
+
+#  define dump_cdb(fsg) do { } while (0)
+
+#else
+
+#  define dump_msg(fsg, /* const char * */ label, \
+		   /* const u8 * */ buf, /* unsigned */ length) do { } while (0)
+
+#  ifdef VERBOSE_DEBUG
+
+#    define dump_cdb(fsg)						\
+	print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE,	\
+		       16, 1, (fsg)->cmnd, (fsg)->cmnd_size, 0)		\
+
+#  else
+
+#    define dump_cdb(fsg) do { } while (0)
+
+#  endif /* VERBOSE_DEBUG */
+
+#endif /* DUMP_MSGS */
+
+
+
+
+
+/*-------------------------------------------------------------------------*/
+
+/* SCSI device types */
+#define TYPE_DISK	0x00
+#define TYPE_CDROM	0x05
+
+/* USB protocol value = the transport method */
+#define USB_PR_CBI	0x00		/* Control/Bulk/Interrupt */
+#define USB_PR_CB	0x01		/* Control/Bulk w/o interrupt */
+#define USB_PR_BULK	0x50		/* Bulk-only */
+
+/* USB subclass value = the protocol encapsulation */
+#define USB_SC_RBC	0x01		/* Reduced Block Commands (flash) */
+#define USB_SC_8020	0x02		/* SFF-8020i, MMC-2, ATAPI (CD-ROM) */
+#define USB_SC_QIC	0x03		/* QIC-157 (tape) */
+#define USB_SC_UFI	0x04		/* UFI (floppy) */
+#define USB_SC_8070	0x05		/* SFF-8070i (removable) */
+#define USB_SC_SCSI	0x06		/* Transparent SCSI */
+
+/* Bulk-only data structures */
+
+/* Command Block Wrapper */
+struct fsg_bulk_cb_wrap {
+	__le32	Signature;		/* Contains 'USBC' */
+	u32	Tag;			/* Unique per command id */
+	__le32	DataTransferLength;	/* Size of the data */
+	u8	Flags;			/* Direction in bit 7 */
+	u8	Lun;			/* LUN (normally 0) */
+	u8	Length;			/* Of the CDB, <= MAX_COMMAND_SIZE */
+	u8	CDB[16];		/* Command Data Block */
+};
+
+#define USB_BULK_CB_WRAP_LEN	31
+#define USB_BULK_CB_SIG		0x43425355	/* Spells out USBC */
+#define USB_BULK_IN_FLAG	0x80
+
+/* Command Status Wrapper */
+struct bulk_cs_wrap {
+	__le32	Signature;		/* Should = 'USBS' */
+	u32	Tag;			/* Same as original command */
+	__le32	Residue;		/* Amount not transferred */
+	u8	Status;			/* See below */
+};
+
+#define USB_BULK_CS_WRAP_LEN	13
+#define USB_BULK_CS_SIG		0x53425355	/* Spells out 'USBS' */
+#define USB_STATUS_PASS		0
+#define USB_STATUS_FAIL		1
+#define USB_STATUS_PHASE_ERROR	2
+
+/* Bulk-only class specific requests */
+#define USB_BULK_RESET_REQUEST		0xff
+#define USB_BULK_GET_MAX_LUN_REQUEST	0xfe
+
+
+/* CBI Interrupt data structure */
+struct interrupt_data {
+	u8	bType;
+	u8	bValue;
+};
+
+#define CBI_INTERRUPT_DATA_LEN		2
+
+/* CBI Accept Device-Specific Command request */
+#define USB_CBI_ADSC_REQUEST		0x00
+
+
+/* Length of a SCSI Command Data Block */
+#define MAX_COMMAND_SIZE	16
+
+/* SCSI commands that we recognize */
+#define SC_FORMAT_UNIT			0x04
+#define SC_INQUIRY			0x12
+#define SC_MODE_SELECT_6		0x15
+#define SC_MODE_SELECT_10		0x55
+#define SC_MODE_SENSE_6			0x1a
+#define SC_MODE_SENSE_10		0x5a
+#define SC_PREVENT_ALLOW_MEDIUM_REMOVAL	0x1e
+#define SC_READ_6			0x08
+#define SC_READ_10			0x28
+#define SC_READ_12			0xa8
+#define SC_READ_CAPACITY		0x25
+#define SC_READ_FORMAT_CAPACITIES	0x23
+#define SC_READ_HEADER			0x44
+#define SC_READ_TOC			0x43
+#define SC_RELEASE			0x17
+#define SC_REQUEST_SENSE		0x03
+#define SC_RESERVE			0x16
+#define SC_SEND_DIAGNOSTIC		0x1d
+#define SC_START_STOP_UNIT		0x1b
+#define SC_SYNCHRONIZE_CACHE		0x35
+#define SC_TEST_UNIT_READY		0x00
+#define SC_VERIFY			0x2f
+#define SC_WRITE_6			0x0a
+#define SC_WRITE_10			0x2a
+#define SC_WRITE_12			0xaa
+
+/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */
+#define SS_NO_SENSE				0
+#define SS_COMMUNICATION_FAILURE		0x040800
+#define SS_INVALID_COMMAND			0x052000
+#define SS_INVALID_FIELD_IN_CDB			0x052400
+#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE	0x052100
+#define SS_LOGICAL_UNIT_NOT_SUPPORTED		0x052500
+#define SS_MEDIUM_NOT_PRESENT			0x023a00
+#define SS_MEDIUM_REMOVAL_PREVENTED		0x055302
+#define SS_NOT_READY_TO_READY_TRANSITION	0x062800
+#define SS_RESET_OCCURRED			0x062900
+#define SS_SAVING_PARAMETERS_NOT_SUPPORTED	0x053900
+#define SS_UNRECOVERED_READ_ERROR		0x031100
+#define SS_WRITE_ERROR				0x030c02
+#define SS_WRITE_PROTECTED			0x072700
+
+#define SK(x)		((u8) ((x) >> 16))	/* Sense Key byte, etc. */
+#define ASC(x)		((u8) ((x) >> 8))
+#define ASCQ(x)		((u8) (x))
+
+
+/*-------------------------------------------------------------------------*/
+
+
+struct fsg_lun {
+	struct file	*filp;
+	loff_t		file_length;
+	loff_t		num_sectors;
+
+	unsigned int	initially_ro:1;
+	unsigned int	ro:1;
+	unsigned int	removable:1;
+	unsigned int	cdrom:1;
+	unsigned int	prevent_medium_removal:1;
+	unsigned int	registered:1;
+	unsigned int	info_valid:1;
+
+	u32		sense_data;
+	u32		sense_data_info;
+	u32		unit_attention_data;
+
+	struct device	dev;
+};
+
+#define fsg_lun_is_open(curlun)	((curlun)->filp != NULL)
+
+static struct fsg_lun *fsg_lun_from_dev(struct device *dev)
+{
+	return container_of(dev, struct fsg_lun, dev);
+}
+
+
+/* Big enough to hold our biggest descriptor */
+#define EP0_BUFSIZE	256
+#define DELAYED_STATUS	(EP0_BUFSIZE + 999)	/* An impossibly large value */
+
+/* Number of buffers we will use.  2 is enough for double-buffering */
+#define FSG_NUM_BUFFERS	2
+
+/* Default size of buffer length. */
+#define FSG_BUFLEN	((u32)16384)
+
+/* Maximal number of LUNs supported in mass storage function */
+#define FSG_MAX_LUNS	8
+
+enum fsg_buffer_state {
+	BUF_STATE_EMPTY = 0,
+	BUF_STATE_FULL,
+	BUF_STATE_BUSY
+};
+
+struct fsg_buffhd {
+#ifdef FSG_BUFFHD_STATIC_BUFFER
+	char				buf[FSG_BUFLEN];
+#else
+	void				*buf;
+#endif
+	enum fsg_buffer_state		state;
+	struct fsg_buffhd		*next;
+
+	/* The NetChip 2280 is faster, and handles some protocol faults
+	 * better, if we don't submit any short bulk-out read requests.
+	 * So we will record the intended request length here. */
+	unsigned int			bulk_out_intended_length;
+
+	struct usb_request		*inreq;
+	int				inreq_busy;
+	struct usb_request		*outreq;
+	int				outreq_busy;
+};
+
+enum fsg_state {
+	/* This one isn't used anywhere */
+	FSG_STATE_COMMAND_PHASE = -10,
+	FSG_STATE_DATA_PHASE,
+	FSG_STATE_STATUS_PHASE,
+
+	FSG_STATE_IDLE = 0,
+	FSG_STATE_ABORT_BULK_OUT,
+	FSG_STATE_RESET,
+	FSG_STATE_INTERFACE_CHANGE,
+	FSG_STATE_CONFIG_CHANGE,
+	FSG_STATE_DISCONNECT,
+	FSG_STATE_EXIT,
+	FSG_STATE_TERMINATED
+};
+
+enum data_direction {
+	DATA_DIR_UNKNOWN = 0,
+	DATA_DIR_FROM_HOST,
+	DATA_DIR_TO_HOST,
+	DATA_DIR_NONE
+};
+
+
+/*-------------------------------------------------------------------------*/
+
+
+static inline u32 get_unaligned_be24(u8 *buf)
+{
+	return 0xffffff & (u32) get_unaligned_be32(buf - 1);
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+
+enum {
+#ifndef FSG_NO_DEVICE_STRINGS
+	FSG_STRING_MANUFACTURER	= 1,
+	FSG_STRING_PRODUCT,
+	FSG_STRING_SERIAL,
+	FSG_STRING_CONFIG,
+#endif
+	FSG_STRING_INTERFACE
+};
+
+
+#ifndef FSG_NO_OTG
+static struct usb_otg_descriptor
+fsg_otg_desc = {
+	.bLength =		sizeof fsg_otg_desc,
+	.bDescriptorType =	USB_DT_OTG,
+
+	.bmAttributes =		USB_OTG_SRP,
+};
+#endif
+
+/* There is only one interface. */
+
+static struct usb_interface_descriptor
+fsg_intf_desc = {
+	.bLength =		sizeof fsg_intf_desc,
+	.bDescriptorType =	USB_DT_INTERFACE,
+
+	.bNumEndpoints =	2,		/* Adjusted during fsg_bind() */
+	.bInterfaceClass =	USB_CLASS_MASS_STORAGE,
+	.bInterfaceSubClass =	USB_SC_SCSI,	/* Adjusted during fsg_bind() */
+	.bInterfaceProtocol =	USB_PR_BULK,	/* Adjusted during fsg_bind() */
+	.iInterface =		FSG_STRING_INTERFACE,
+};
+
+/* Three full-speed endpoint descriptors: bulk-in, bulk-out,
+ * and interrupt-in. */
+
+static struct usb_endpoint_descriptor
+fsg_fs_bulk_in_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	USB_DIR_IN,
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	/* wMaxPacketSize set by autoconfiguration */
+};
+
+static struct usb_endpoint_descriptor
+fsg_fs_bulk_out_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	USB_DIR_OUT,
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	/* wMaxPacketSize set by autoconfiguration */
+};
+
+#ifndef FSG_NO_INTR_EP
+
+static struct usb_endpoint_descriptor
+fsg_fs_intr_in_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	USB_DIR_IN,
+	.bmAttributes =		USB_ENDPOINT_XFER_INT,
+	.wMaxPacketSize =	cpu_to_le16(2),
+	.bInterval =		32,	/* frames -> 32 ms */
+};
+
+#ifndef FSG_NO_OTG
+#  define FSG_FS_FUNCTION_PRE_EP_ENTRIES	2
+#else
+#  define FSG_FS_FUNCTION_PRE_EP_ENTRIES	1
+#endif
+
+#endif
+
+static struct usb_descriptor_header *fsg_fs_function[] = {
+#ifndef FSG_NO_OTG
+	(struct usb_descriptor_header *) &fsg_otg_desc,
+#endif
+	(struct usb_descriptor_header *) &fsg_intf_desc,
+	(struct usb_descriptor_header *) &fsg_fs_bulk_in_desc,
+	(struct usb_descriptor_header *) &fsg_fs_bulk_out_desc,
+#ifndef FSG_NO_INTR_EP
+	(struct usb_descriptor_header *) &fsg_fs_intr_in_desc,
+#endif
+	NULL,
+};
+
+
+/*
+ * USB 2.0 devices need to expose both high speed and full speed
+ * descriptors, unless they only run at full speed.
+ *
+ * That means alternate endpoint descriptors (bigger packets)
+ * and a "device qualifier" ... plus more construction options
+ * for the config descriptor.
+ */
+static struct usb_endpoint_descriptor
+fsg_hs_bulk_in_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	/* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize =	cpu_to_le16(512),
+};
+
+static struct usb_endpoint_descriptor
+fsg_hs_bulk_out_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	/* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize =	cpu_to_le16(512),
+	.bInterval =		1,	/* NAK every 1 uframe */
+};
+
+#ifndef FSG_NO_INTR_EP
+
+static struct usb_endpoint_descriptor
+fsg_hs_intr_in_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	/* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */
+	.bmAttributes =		USB_ENDPOINT_XFER_INT,
+	.wMaxPacketSize =	cpu_to_le16(2),
+	.bInterval =		9,	/* 2**(9-1) = 256 uframes -> 32 ms */
+};
+
+#ifndef FSG_NO_OTG
+#  define FSG_HS_FUNCTION_PRE_EP_ENTRIES	2
+#else
+#  define FSG_HS_FUNCTION_PRE_EP_ENTRIES	1
+#endif
+
+#endif
+
+static struct usb_descriptor_header *fsg_hs_function[] = {
+#ifndef FSG_NO_OTG
+	(struct usb_descriptor_header *) &fsg_otg_desc,
+#endif
+	(struct usb_descriptor_header *) &fsg_intf_desc,
+	(struct usb_descriptor_header *) &fsg_hs_bulk_in_desc,
+	(struct usb_descriptor_header *) &fsg_hs_bulk_out_desc,
+#ifndef FSG_NO_INTR_EP
+	(struct usb_descriptor_header *) &fsg_hs_intr_in_desc,
+#endif
+	NULL,
+};
+
+/* Maxpacket and other transfer characteristics vary by speed. */
+static struct usb_endpoint_descriptor *
+fsg_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs,
+		struct usb_endpoint_descriptor *hs)
+{
+	if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
+		return hs;
+	return fs;
+}
+
+
+/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
+static struct usb_string		fsg_strings[] = {
+#ifndef FSG_NO_DEVICE_STRINGS
+	{FSG_STRING_MANUFACTURER,	fsg_string_manufacturer},
+	{FSG_STRING_PRODUCT,		fsg_string_product},
+	{FSG_STRING_SERIAL,		fsg_string_serial},
+	{FSG_STRING_CONFIG,		fsg_string_config},
+#endif
+	{FSG_STRING_INTERFACE,		fsg_string_interface},
+	{}
+};
+
+static struct usb_gadget_strings	fsg_stringtab = {
+	.language	= 0x0409,		/* en-us */
+	.strings	= fsg_strings,
+};
+
+
+ /*-------------------------------------------------------------------------*/
+
+/* If the next two routines are called while the gadget is registered,
+ * the caller must own fsg->filesem for writing. */
+
+static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
+{
+	int				ro;
+	struct file			*filp = NULL;
+	int				rc = -EINVAL;
+	struct inode			*inode = NULL;
+	loff_t				size;
+	loff_t				num_sectors;
+	loff_t				min_sectors;
+
+	/* R/W if we can, R/O if we must */
+	ro = curlun->initially_ro;
+	if (!ro) {
+		filp = filp_open(filename, O_RDWR | O_LARGEFILE, 0);
+		if (-EROFS == PTR_ERR(filp))
+			ro = 1;
+	}
+	if (ro)
+		filp = filp_open(filename, O_RDONLY | O_LARGEFILE, 0);
+	if (IS_ERR(filp)) {
+		LINFO(curlun, "unable to open backing file: %s\n", filename);
+		return PTR_ERR(filp);
+	}
+
+	if (!(filp->f_mode & FMODE_WRITE))
+		ro = 1;
+
+	if (filp->f_path.dentry)
+		inode = filp->f_path.dentry->d_inode;
+	if (inode && S_ISBLK(inode->i_mode)) {
+		if (bdev_read_only(inode->i_bdev))
+			ro = 1;
+	} else if (!inode || !S_ISREG(inode->i_mode)) {
+		LINFO(curlun, "invalid file type: %s\n", filename);
+		goto out;
+	}
+
+	/* If we can't read the file, it's no good.
+	 * If we can't write the file, use it read-only. */
+	if (!filp->f_op || !(filp->f_op->read || filp->f_op->aio_read)) {
+		LINFO(curlun, "file not readable: %s\n", filename);
+		goto out;
+	}
+	if (!(filp->f_op->write || filp->f_op->aio_write))
+		ro = 1;
+
+	size = i_size_read(inode->i_mapping->host);
+	if (size < 0) {
+		LINFO(curlun, "unable to find file size: %s\n", filename);
+		rc = (int) size;
+		goto out;
+	}
+	num_sectors = size >> 9;	/* File size in 512-byte blocks */
+	min_sectors = 1;
+	if (curlun->cdrom) {
+		num_sectors &= ~3;	/* Reduce to a multiple of 2048 */
+		min_sectors = 300*4;	/* Smallest track is 300 frames */
+		if (num_sectors >= 256*60*75*4) {
+			num_sectors = (256*60*75 - 1) * 4;
+			LINFO(curlun, "file too big: %s\n", filename);
+			LINFO(curlun, "using only first %d blocks\n",
+					(int) num_sectors);
+		}
+	}
+	if (num_sectors < min_sectors) {
+		LINFO(curlun, "file too small: %s\n", filename);
+		rc = -ETOOSMALL;
+		goto out;
+	}
+
+	get_file(filp);
+	curlun->ro = ro;
+	curlun->filp = filp;
+	curlun->file_length = size;
+	curlun->num_sectors = num_sectors;
+	LDBG(curlun, "open backing file: %s\n", filename);
+	rc = 0;
+
+out:
+	filp_close(filp, current->files);
+	return rc;
+}
+
+
+static void fsg_lun_close(struct fsg_lun *curlun)
+{
+	if (curlun->filp) {
+		LDBG(curlun, "close backing file\n");
+		fput(curlun->filp);
+		curlun->filp = NULL;
+	}
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/* Sync the file data, don't bother with the metadata.
+ * This code was copied from fs/buffer.c:sys_fdatasync(). */
+static int fsg_lun_fsync_sub(struct fsg_lun *curlun)
+{
+	struct file	*filp = curlun->filp;
+
+	if (curlun->ro || !filp)
+		return 0;
+	return vfs_fsync(filp, filp->f_path.dentry, 1);
+}
+
+static void store_cdrom_address(u8 *dest, int msf, u32 addr)
+{
+	if (msf) {
+		/* Convert to Minutes-Seconds-Frames */
+		addr >>= 2;		/* Convert to 2048-byte frames */
+		addr += 2*75;		/* Lead-in occupies 2 seconds */
+		dest[3] = addr % 75;	/* Frames */
+		addr /= 75;
+		dest[2] = addr % 60;	/* Seconds */
+		addr /= 60;
+		dest[1] = addr;		/* Minutes */
+		dest[0] = 0;		/* Reserved */
+	} else {
+		/* Absolute sector */
+		put_unaligned_be32(addr, dest);
+	}
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+
+static ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
+			   char *buf)
+{
+	struct fsg_lun	*curlun = fsg_lun_from_dev(dev);
+
+	return sprintf(buf, "%d\n", fsg_lun_is_open(curlun)
+				  ? curlun->ro
+				  : curlun->initially_ro);
+}
+
+static ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
+			     char *buf)
+{
+	struct fsg_lun	*curlun = fsg_lun_from_dev(dev);
+	struct rw_semaphore	*filesem = dev_get_drvdata(dev);
+	char		*p;
+	ssize_t		rc;
+
+	down_read(filesem);
+	if (fsg_lun_is_open(curlun)) {	/* Get the complete pathname */
+		p = d_path(&curlun->filp->f_path, buf, PAGE_SIZE - 1);
+		if (IS_ERR(p))
+			rc = PTR_ERR(p);
+		else {
+			rc = strlen(p);
+			memmove(buf, p, rc);
+			buf[rc] = '\n';		/* Add a newline */
+			buf[++rc] = 0;
+		}
+	} else {				/* No file, return 0 bytes */
+		*buf = 0;
+		rc = 0;
+	}
+	up_read(filesem);
+	return rc;
+}
+
+
+static ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	ssize_t		rc = count;
+	struct fsg_lun	*curlun = fsg_lun_from_dev(dev);
+	struct rw_semaphore	*filesem = dev_get_drvdata(dev);
+	int		i;
+
+	if (sscanf(buf, "%d", &i) != 1)
+		return -EINVAL;
+
+	/* Allow the write-enable status to change only while the backing file
+	 * is closed. */
+	down_read(filesem);
+	if (fsg_lun_is_open(curlun)) {
+		LDBG(curlun, "read-only status change prevented\n");
+		rc = -EBUSY;
+	} else {
+		curlun->ro = !!i;
+		curlun->initially_ro = !!i;
+		LDBG(curlun, "read-only status set to %d\n", curlun->ro);
+	}
+	up_read(filesem);
+	return rc;
+}
+
+static ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
+			      const char *buf, size_t count)
+{
+	struct fsg_lun	*curlun = fsg_lun_from_dev(dev);
+	struct rw_semaphore	*filesem = dev_get_drvdata(dev);
+	int		rc = 0;
+
+	if (curlun->prevent_medium_removal && fsg_lun_is_open(curlun)) {
+		LDBG(curlun, "eject attempt prevented\n");
+		return -EBUSY;				/* "Door is locked" */
+	}
+
+	/* Remove a trailing newline */
+	if (count > 0 && buf[count-1] == '\n')
+		((char *) buf)[count-1] = 0;		/* Ugh! */
+
+	/* Eject current medium */
+	down_write(filesem);
+	if (fsg_lun_is_open(curlun)) {
+		fsg_lun_close(curlun);
+		curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT;
+	}
+
+	/* Load new medium */
+	if (count > 0 && buf[0]) {
+		rc = fsg_lun_open(curlun, buf);
+		if (rc == 0)
+			curlun->unit_attention_data =
+					SS_NOT_READY_TO_READY_TRANSITION;
+	}
+	up_write(filesem);
+	return (rc < 0 ? rc : count);
+}
diff --git a/drivers/usb/gadget/u_ether.h b/drivers/usb/gadget/u_ether.h
index 91b39ff..fd55f45 100644
--- a/drivers/usb/gadget/u_ether.h
+++ b/drivers/usb/gadget/u_ether.h
@@ -112,7 +112,7 @@
 int ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]);
 int eem_bind_config(struct usb_configuration *c);
 
-#ifdef CONFIG_USB_ETH_RNDIS
+#ifdef USB_ETH_RNDIS
 
 int rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]);
 
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 9b43b22..2678a16 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -90,14 +90,25 @@
 
 config USB_EHCI_BIG_ENDIAN_MMIO
 	bool
-	depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || ARCH_IXP4XX)
+	depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX)
 	default y
 
 config USB_EHCI_BIG_ENDIAN_DESC
 	bool
-	depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX)
+	depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX)
 	default y
 
+config XPS_USB_HCD_XILINX
+	bool "Use Xilinx usb host EHCI controller core"
+	depends on USB_EHCI_HCD && (PPC32 || MICROBLAZE)
+	select USB_EHCI_BIG_ENDIAN_DESC
+	select USB_EHCI_BIG_ENDIAN_MMIO
+	---help---
+		Xilinx xps USB host controller core is EHCI compilant and has
+		transaction translator built-in. It can be configured to either
+		support both high speed and full speed devices, or high speed
+		devices only.
+
 config USB_EHCI_FSL
 	bool "Support for Freescale on-chip EHCI USB controller"
 	depends on USB_EHCI_HCD && FSL_SOC
@@ -105,6 +116,13 @@
 	---help---
 	  Variation of ARC USB block used in some Freescale chips.
 
+config USB_EHCI_MXC
+	bool "Support for Freescale on-chip EHCI USB controller"
+	depends on USB_EHCI_HCD && ARCH_MXC
+	select USB_EHCI_ROOT_HUB_TT
+	---help---
+	  Variation of ARC USB block used in some Freescale chips.
+
 config USB_EHCI_HCD_PPC_OF
 	bool "EHCI support for PPC USB controller on OF platform bus"
 	depends on USB_EHCI_HCD && PPC_OF
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index f5f5601..5859522 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -210,7 +210,7 @@
 	if (error) {
 		ehci_halt(ehci);
 		ehci_to_hcd(ehci)->state = HC_STATE_HALT;
-		ehci_err(ehci, "force halt; handhake %p %08x %08x -> %d\n",
+		ehci_err(ehci, "force halt; handshake %p %08x %08x -> %d\n",
 			ptr, mask, done, error);
 	}
 
@@ -549,7 +549,7 @@
 	/* controllers may cache some of the periodic schedule ... */
 	hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params);
 	if (HCC_ISOC_CACHE(hcc_params))		// full frame cache
-		ehci->i_thresh = 8;
+		ehci->i_thresh = 2 + 8;
 	else					// N microframes cached
 		ehci->i_thresh = 2 + HCC_ISOC_THRES(hcc_params);
 
@@ -605,6 +605,8 @@
 	}
 	ehci->command = temp;
 
+	/* Accept arbitrarily long scatter-gather lists */
+	hcd->self.sg_tablesize = ~0;
 	return 0;
 }
 
@@ -1105,11 +1107,21 @@
 #define	PLATFORM_DRIVER		ehci_fsl_driver
 #endif
 
+#ifdef CONFIG_USB_EHCI_MXC
+#include "ehci-mxc.c"
+#define PLATFORM_DRIVER		ehci_mxc_driver
+#endif
+
 #ifdef CONFIG_SOC_AU1200
 #include "ehci-au1xxx.c"
 #define	PLATFORM_DRIVER		ehci_hcd_au1xxx_driver
 #endif
 
+#ifdef CONFIG_ARCH_OMAP34XX
+#include "ehci-omap.c"
+#define        PLATFORM_DRIVER         ehci_hcd_omap_driver
+#endif
+
 #ifdef CONFIG_PPC_PS3
 #include "ehci-ps3.c"
 #define	PS3_SYSTEM_BUS_DRIVER	ps3_ehci_driver
@@ -1120,6 +1132,11 @@
 #define OF_PLATFORM_DRIVER	ehci_hcd_ppc_of_driver
 #endif
 
+#ifdef CONFIG_XPS_USB_HCD_XILINX
+#include "ehci-xilinx-of.c"
+#define OF_PLATFORM_DRIVER	ehci_hcd_xilinx_of_driver
+#endif
+
 #ifdef CONFIG_PLAT_ORION
 #include "ehci-orion.c"
 #define	PLATFORM_DRIVER		ehci_orion_driver
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 1b6f1c0..2c6571c 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -236,7 +236,7 @@
 	}
 
 	if (unlikely(ehci->debug)) {
-		if (ehci->debug && !dbgp_reset_prep())
+		if (!dbgp_reset_prep())
 			ehci->debug = NULL;
 		else
 			dbgp_external_startup();
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
new file mode 100644
index 0000000..35c56f4
--- /dev/null
+++ b/drivers/usb/host/ehci-mxc.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * 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.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/usb/otg.h>
+
+#include <mach/mxc_ehci.h>
+
+#define ULPI_VIEWPORT_OFFSET	0x170
+#define PORTSC_OFFSET		0x184
+#define USBMODE_OFFSET		0x1a8
+#define USBMODE_CM_HOST		3
+
+struct ehci_mxc_priv {
+	struct clk *usbclk, *ahbclk;
+	struct usb_hcd *hcd;
+};
+
+/* called during probe() after chip reset completes */
+static int ehci_mxc_setup(struct usb_hcd *hcd)
+{
+	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+	int retval;
+
+	/* EHCI registers start at offset 0x100 */
+	ehci->caps = hcd->regs + 0x100;
+	ehci->regs = hcd->regs + 0x100 +
+	    HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
+	dbg_hcs_params(ehci, "reset");
+	dbg_hcc_params(ehci, "reset");
+
+	/* cache this readonly data; minimize chip reads */
+	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
+
+	retval = ehci_halt(ehci);
+	if (retval)
+		return retval;
+
+	/* data structure init */
+	retval = ehci_init(hcd);
+	if (retval)
+		return retval;
+
+	hcd->has_tt = 1;
+
+	ehci->sbrn = 0x20;
+
+	ehci_reset(ehci);
+
+	ehci_port_power(ehci, 0);
+	return 0;
+}
+
+static const struct hc_driver ehci_mxc_hc_driver = {
+	.description = hcd_name,
+	.product_desc = "Freescale On-Chip EHCI Host Controller",
+	.hcd_priv_size = sizeof(struct ehci_hcd),
+
+	/*
+	 * generic hardware linkage
+	 */
+	.irq = ehci_irq,
+	.flags = HCD_USB2 | HCD_MEMORY,
+
+	/*
+	 * basic lifecycle operations
+	 */
+	.reset = ehci_mxc_setup,
+	.start = ehci_run,
+	.stop = ehci_stop,
+	.shutdown = ehci_shutdown,
+
+	/*
+	 * managing i/o requests and associated device resources
+	 */
+	.urb_enqueue = ehci_urb_enqueue,
+	.urb_dequeue = ehci_urb_dequeue,
+	.endpoint_disable = ehci_endpoint_disable,
+
+	/*
+	 * scheduling support
+	 */
+	.get_frame_number = ehci_get_frame,
+
+	/*
+	 * root hub support
+	 */
+	.hub_status_data = ehci_hub_status_data,
+	.hub_control = ehci_hub_control,
+	.bus_suspend = ehci_bus_suspend,
+	.bus_resume = ehci_bus_resume,
+	.relinquish_port = ehci_relinquish_port,
+	.port_handed_over = ehci_port_handed_over,
+};
+
+static int ehci_mxc_drv_probe(struct platform_device *pdev)
+{
+	struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data;
+	struct usb_hcd *hcd;
+	struct resource *res;
+	int irq, ret, temp;
+	struct ehci_mxc_priv *priv;
+	struct device *dev = &pdev->dev;
+
+	dev_info(&pdev->dev, "initializing i.MX USB Controller\n");
+
+	if (!pdata) {
+		dev_err(dev, "No platform data given, bailing out.\n");
+		return -EINVAL;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+
+	hcd = usb_create_hcd(&ehci_mxc_hc_driver, dev, dev_name(dev));
+	if (!hcd)
+		return -ENOMEM;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv) {
+		ret = -ENOMEM;
+		goto err_alloc;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "Found HC with no register addr. Check setup!\n");
+		ret = -ENODEV;
+		goto err_get_resource;
+	}
+
+	hcd->rsrc_start = res->start;
+	hcd->rsrc_len = resource_size(res);
+
+	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+		dev_dbg(dev, "controller already in use\n");
+		ret = -EBUSY;
+		goto err_request_mem;
+	}
+
+	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+	if (!hcd->regs) {
+		dev_err(dev, "error mapping memory\n");
+		ret = -EFAULT;
+		goto err_ioremap;
+	}
+
+	/* enable clocks */
+	priv->usbclk = clk_get(dev, "usb");
+	if (IS_ERR(priv->usbclk)) {
+		ret = PTR_ERR(priv->usbclk);
+		goto err_clk;
+	}
+	clk_enable(priv->usbclk);
+
+	if (!cpu_is_mx35()) {
+		priv->ahbclk = clk_get(dev, "usb_ahb");
+		if (IS_ERR(priv->ahbclk)) {
+			ret = PTR_ERR(priv->ahbclk);
+			goto err_clk_ahb;
+		}
+		clk_enable(priv->ahbclk);
+	}
+
+	/* set USBMODE to host mode */
+	temp = readl(hcd->regs + USBMODE_OFFSET);
+	writel(temp | USBMODE_CM_HOST, hcd->regs + USBMODE_OFFSET);
+
+	/* set up the PORTSCx register */
+	writel(pdata->portsc, hcd->regs + PORTSC_OFFSET);
+	mdelay(10);
+
+	/* setup USBCONTROL. */
+	ret = mxc_set_usbcontrol(pdev->id, pdata->flags);
+	if (ret < 0)
+		goto err_init;
+
+	/* call platform specific init function */
+	if (pdata->init) {
+		ret = pdata->init(pdev);
+		if (ret) {
+			dev_err(dev, "platform init failed\n");
+			goto err_init;
+		}
+	}
+
+	/* most platforms need some time to settle changed IO settings */
+	mdelay(10);
+
+	/* Initialize the transceiver */
+	if (pdata->otg) {
+		pdata->otg->io_priv = hcd->regs + ULPI_VIEWPORT_OFFSET;
+		if (otg_init(pdata->otg) != 0)
+			dev_err(dev, "unable to init transceiver\n");
+		else if (otg_set_vbus(pdata->otg, 1) != 0)
+			dev_err(dev, "unable to enable vbus on transceiver\n");
+	}
+
+	priv->hcd = hcd;
+	platform_set_drvdata(pdev, priv);
+
+	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
+	if (ret)
+		goto err_add;
+
+	return 0;
+
+err_add:
+	if (pdata && pdata->exit)
+		pdata->exit(pdev);
+err_init:
+	if (priv->ahbclk) {
+		clk_disable(priv->ahbclk);
+		clk_put(priv->ahbclk);
+	}
+err_clk_ahb:
+	clk_disable(priv->usbclk);
+	clk_put(priv->usbclk);
+err_clk:
+	iounmap(hcd->regs);
+err_ioremap:
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err_request_mem:
+err_get_resource:
+	kfree(priv);
+err_alloc:
+	usb_put_hcd(hcd);
+	return ret;
+}
+
+static int __exit ehci_mxc_drv_remove(struct platform_device *pdev)
+{
+	struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data;
+	struct ehci_mxc_priv *priv = platform_get_drvdata(pdev);
+	struct usb_hcd *hcd = priv->hcd;
+
+	if (pdata && pdata->exit)
+		pdata->exit(pdev);
+
+	if (pdata->otg)
+		otg_shutdown(pdata->otg);
+
+	usb_remove_hcd(hcd);
+	iounmap(hcd->regs);
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	usb_put_hcd(hcd);
+	platform_set_drvdata(pdev, NULL);
+
+	clk_disable(priv->usbclk);
+	clk_put(priv->usbclk);
+	if (priv->ahbclk) {
+		clk_disable(priv->ahbclk);
+		clk_put(priv->ahbclk);
+	}
+
+	kfree(priv);
+
+	return 0;
+}
+
+static void ehci_mxc_drv_shutdown(struct platform_device *pdev)
+{
+	struct ehci_mxc_priv *priv = platform_get_drvdata(pdev);
+	struct usb_hcd *hcd = priv->hcd;
+
+	if (hcd->driver->shutdown)
+		hcd->driver->shutdown(hcd);
+}
+
+MODULE_ALIAS("platform:mxc-ehci");
+
+static struct platform_driver ehci_mxc_driver = {
+	.probe = ehci_mxc_drv_probe,
+	.remove = __exit_p(ehci_mxc_drv_remove),
+	.shutdown = ehci_mxc_drv_shutdown,
+	.driver = {
+		   .name = "mxc-ehci",
+	},
+};
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
new file mode 100644
index 0000000..12f1ad2
--- /dev/null
+++ b/drivers/usb/host/ehci-omap.c
@@ -0,0 +1,756 @@
+/*
+ * ehci-omap.c - driver for USBHOST on OMAP 34xx processor
+ *
+ * Bus Glue for OMAP34xx USBHOST 3 port EHCI controller
+ * Tested on OMAP3430 ES2.0 SDP
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ *	Author: Vikram Pandita <vikram.pandita@ti.com>
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *	Contact: Felipe Balbi <felipe.balbi@nokia.com>
+ *
+ * Based on "ehci-fsl.c" and "ehci-au1xxx.c" ehci glue layers
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ * TODO (last updated Feb 23rd, 2009):
+ *	- add kernel-doc
+ *	- enable AUTOIDLE
+ *	- move DPLL5 programming to clock fw
+ *	- add suspend/resume
+ *	- move workarounds to board-files
+ */
+
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <mach/usb.h>
+
+/*
+ * OMAP USBHOST Register addresses: VIRTUAL ADDRESSES
+ *	Use ehci_omap_readl()/ehci_omap_writel() functions
+ */
+
+/* TLL Register Set */
+#define	OMAP_USBTLL_REVISION				(0x00)
+#define	OMAP_USBTLL_SYSCONFIG				(0x10)
+#define	OMAP_USBTLL_SYSCONFIG_CACTIVITY			(1 << 8)
+#define	OMAP_USBTLL_SYSCONFIG_SIDLEMODE			(1 << 3)
+#define	OMAP_USBTLL_SYSCONFIG_ENAWAKEUP			(1 << 2)
+#define	OMAP_USBTLL_SYSCONFIG_SOFTRESET			(1 << 1)
+#define	OMAP_USBTLL_SYSCONFIG_AUTOIDLE			(1 << 0)
+
+#define	OMAP_USBTLL_SYSSTATUS				(0x14)
+#define	OMAP_USBTLL_SYSSTATUS_RESETDONE			(1 << 0)
+
+#define	OMAP_USBTLL_IRQSTATUS				(0x18)
+#define	OMAP_USBTLL_IRQENABLE				(0x1C)
+
+#define	OMAP_TLL_SHARED_CONF				(0x30)
+#define	OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN		(1 << 6)
+#define	OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN		(1 << 5)
+#define	OMAP_TLL_SHARED_CONF_USB_DIVRATION		(1 << 2)
+#define	OMAP_TLL_SHARED_CONF_FCLK_REQ			(1 << 1)
+#define	OMAP_TLL_SHARED_CONF_FCLK_IS_ON			(1 << 0)
+
+#define	OMAP_TLL_CHANNEL_CONF(num)			(0x040 + 0x004 * num)
+#define	OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF		(1 << 11)
+#define	OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE		(1 << 10)
+#define	OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE		(1 << 9)
+#define	OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE		(1 << 8)
+#define	OMAP_TLL_CHANNEL_CONF_CHANEN			(1 << 0)
+
+#define	OMAP_TLL_ULPI_FUNCTION_CTRL(num)		(0x804 + 0x100 * num)
+#define	OMAP_TLL_ULPI_INTERFACE_CTRL(num)		(0x807 + 0x100 * num)
+#define	OMAP_TLL_ULPI_OTG_CTRL(num)			(0x80A + 0x100 * num)
+#define	OMAP_TLL_ULPI_INT_EN_RISE(num)			(0x80D + 0x100 * num)
+#define	OMAP_TLL_ULPI_INT_EN_FALL(num)			(0x810 + 0x100 * num)
+#define	OMAP_TLL_ULPI_INT_STATUS(num)			(0x813 + 0x100 * num)
+#define	OMAP_TLL_ULPI_INT_LATCH(num)			(0x814 + 0x100 * num)
+#define	OMAP_TLL_ULPI_DEBUG(num)			(0x815 + 0x100 * num)
+#define	OMAP_TLL_ULPI_SCRATCH_REGISTER(num)		(0x816 + 0x100 * num)
+
+#define OMAP_TLL_CHANNEL_COUNT				3
+#define OMAP_TLL_CHANNEL_1_EN_MASK			(1 << 1)
+#define OMAP_TLL_CHANNEL_2_EN_MASK			(1 << 2)
+#define OMAP_TLL_CHANNEL_3_EN_MASK			(1 << 4)
+
+/* UHH Register Set */
+#define	OMAP_UHH_REVISION				(0x00)
+#define	OMAP_UHH_SYSCONFIG				(0x10)
+#define	OMAP_UHH_SYSCONFIG_MIDLEMODE			(1 << 12)
+#define	OMAP_UHH_SYSCONFIG_CACTIVITY			(1 << 8)
+#define	OMAP_UHH_SYSCONFIG_SIDLEMODE			(1 << 3)
+#define	OMAP_UHH_SYSCONFIG_ENAWAKEUP			(1 << 2)
+#define	OMAP_UHH_SYSCONFIG_SOFTRESET			(1 << 1)
+#define	OMAP_UHH_SYSCONFIG_AUTOIDLE			(1 << 0)
+
+#define	OMAP_UHH_SYSSTATUS				(0x14)
+#define	OMAP_UHH_HOSTCONFIG				(0x40)
+#define	OMAP_UHH_HOSTCONFIG_ULPI_BYPASS			(1 << 0)
+#define	OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS		(1 << 0)
+#define	OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS		(1 << 11)
+#define	OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS		(1 << 12)
+#define OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN		(1 << 2)
+#define OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN		(1 << 3)
+#define OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN		(1 << 4)
+#define OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN		(1 << 5)
+#define OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS		(1 << 8)
+#define OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS		(1 << 9)
+#define OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS		(1 << 10)
+
+#define	OMAP_UHH_DEBUG_CSR				(0x44)
+
+/* EHCI Register Set */
+#define	EHCI_INSNREG05_ULPI				(0xA4)
+#define	EHCI_INSNREG05_ULPI_CONTROL_SHIFT		31
+#define	EHCI_INSNREG05_ULPI_PORTSEL_SHIFT		24
+#define	EHCI_INSNREG05_ULPI_OPSEL_SHIFT			22
+#define	EHCI_INSNREG05_ULPI_REGADD_SHIFT		16
+#define	EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT		8
+#define	EHCI_INSNREG05_ULPI_WRDATA_SHIFT		0
+
+/*-------------------------------------------------------------------------*/
+
+static inline void ehci_omap_writel(void __iomem *base, u32 reg, u32 val)
+{
+	__raw_writel(val, base + reg);
+}
+
+static inline u32 ehci_omap_readl(void __iomem *base, u32 reg)
+{
+	return __raw_readl(base + reg);
+}
+
+static inline void ehci_omap_writeb(void __iomem *base, u8 reg, u8 val)
+{
+	__raw_writeb(val, base + reg);
+}
+
+static inline u8 ehci_omap_readb(void __iomem *base, u8 reg)
+{
+	return __raw_readb(base + reg);
+}
+
+/*-------------------------------------------------------------------------*/
+
+struct ehci_hcd_omap {
+	struct ehci_hcd		*ehci;
+	struct device		*dev;
+
+	struct clk		*usbhost_ick;
+	struct clk		*usbhost2_120m_fck;
+	struct clk		*usbhost1_48m_fck;
+	struct clk		*usbtll_fck;
+	struct clk		*usbtll_ick;
+
+	/* FIXME the following two workarounds are
+	 * board specific not silicon-specific so these
+	 * should be moved to board-file instead.
+	 *
+	 * Maybe someone from TI will know better which
+	 * board is affected and needs the workarounds
+	 * to be applied
+	 */
+
+	/* gpio for resetting phy */
+	int			reset_gpio_port[OMAP3_HS_USB_PORTS];
+
+	/* phy reset workaround */
+	int			phy_reset;
+
+	/* desired phy_mode: TLL, PHY */
+	enum ehci_hcd_omap_mode	port_mode[OMAP3_HS_USB_PORTS];
+
+	void __iomem		*uhh_base;
+	void __iomem		*tll_base;
+	void __iomem		*ehci_base;
+};
+
+/*-------------------------------------------------------------------------*/
+
+static void omap_usb_utmi_init(struct ehci_hcd_omap *omap, u8 tll_channel_mask)
+{
+	unsigned reg;
+	int i;
+
+	/* Program the 3 TLL channels upfront */
+	for (i = 0; i < OMAP_TLL_CHANNEL_COUNT; i++) {
+		reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i));
+
+		/* Disable AutoIdle, BitStuffing and use SDR Mode */
+		reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE
+				| OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF
+				| OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE);
+		ehci_omap_writel(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i), reg);
+	}
+
+	/* Program Common TLL register */
+	reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_SHARED_CONF);
+	reg |= (OMAP_TLL_SHARED_CONF_FCLK_IS_ON
+			| OMAP_TLL_SHARED_CONF_USB_DIVRATION
+			| OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN);
+	reg &= ~OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN;
+
+	ehci_omap_writel(omap->tll_base, OMAP_TLL_SHARED_CONF, reg);
+
+	/* Enable channels now */
+	for (i = 0; i < OMAP_TLL_CHANNEL_COUNT; i++) {
+		reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i));
+
+		/* Enable only the reg that is needed */
+		if (!(tll_channel_mask & 1<<i))
+			continue;
+
+		reg |= OMAP_TLL_CHANNEL_CONF_CHANEN;
+		ehci_omap_writel(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i), reg);
+
+		ehci_omap_writeb(omap->tll_base,
+				OMAP_TLL_ULPI_SCRATCH_REGISTER(i), 0xbe);
+		dev_dbg(omap->dev, "ULPI_SCRATCH_REG[ch=%d]= 0x%02x\n",
+				i+1, ehci_omap_readb(omap->tll_base,
+				OMAP_TLL_ULPI_SCRATCH_REGISTER(i)));
+	}
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* omap_start_ehc
+ *	- Start the TI USBHOST controller
+ */
+static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd)
+{
+	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
+	u8 tll_ch_mask = 0;
+	unsigned reg = 0;
+	int ret = 0;
+
+	dev_dbg(omap->dev, "starting TI EHCI USB Controller\n");
+
+	/* Enable Clocks for USBHOST */
+	omap->usbhost_ick = clk_get(omap->dev, "usbhost_ick");
+	if (IS_ERR(omap->usbhost_ick)) {
+		ret =  PTR_ERR(omap->usbhost_ick);
+		goto err_host_ick;
+	}
+	clk_enable(omap->usbhost_ick);
+
+	omap->usbhost2_120m_fck = clk_get(omap->dev, "usbhost_120m_fck");
+	if (IS_ERR(omap->usbhost2_120m_fck)) {
+		ret = PTR_ERR(omap->usbhost2_120m_fck);
+		goto err_host_120m_fck;
+	}
+	clk_enable(omap->usbhost2_120m_fck);
+
+	omap->usbhost1_48m_fck = clk_get(omap->dev, "usbhost_48m_fck");
+	if (IS_ERR(omap->usbhost1_48m_fck)) {
+		ret = PTR_ERR(omap->usbhost1_48m_fck);
+		goto err_host_48m_fck;
+	}
+	clk_enable(omap->usbhost1_48m_fck);
+
+	if (omap->phy_reset) {
+		/* Refer: ISSUE1 */
+		if (gpio_is_valid(omap->reset_gpio_port[0])) {
+			gpio_request(omap->reset_gpio_port[0],
+						"USB1 PHY reset");
+			gpio_direction_output(omap->reset_gpio_port[0], 0);
+		}
+
+		if (gpio_is_valid(omap->reset_gpio_port[1])) {
+			gpio_request(omap->reset_gpio_port[1],
+						"USB2 PHY reset");
+			gpio_direction_output(omap->reset_gpio_port[1], 0);
+		}
+
+		/* Hold the PHY in RESET for enough time till DIR is high */
+		udelay(10);
+	}
+
+	/* Configure TLL for 60Mhz clk for ULPI */
+	omap->usbtll_fck = clk_get(omap->dev, "usbtll_fck");
+	if (IS_ERR(omap->usbtll_fck)) {
+		ret = PTR_ERR(omap->usbtll_fck);
+		goto err_tll_fck;
+	}
+	clk_enable(omap->usbtll_fck);
+
+	omap->usbtll_ick = clk_get(omap->dev, "usbtll_ick");
+	if (IS_ERR(omap->usbtll_ick)) {
+		ret = PTR_ERR(omap->usbtll_ick);
+		goto err_tll_ick;
+	}
+	clk_enable(omap->usbtll_ick);
+
+	/* perform TLL soft reset, and wait until reset is complete */
+	ehci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG,
+			OMAP_USBTLL_SYSCONFIG_SOFTRESET);
+
+	/* Wait for TLL reset to complete */
+	while (!(ehci_omap_readl(omap->tll_base, OMAP_USBTLL_SYSSTATUS)
+			& OMAP_USBTLL_SYSSTATUS_RESETDONE)) {
+		cpu_relax();
+
+		if (time_after(jiffies, timeout)) {
+			dev_dbg(omap->dev, "operation timed out\n");
+			ret = -EINVAL;
+			goto err_sys_status;
+		}
+	}
+
+	dev_dbg(omap->dev, "TLL RESET DONE\n");
+
+	/* (1<<3) = no idle mode only for initial debugging */
+	ehci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG,
+			OMAP_USBTLL_SYSCONFIG_ENAWAKEUP |
+			OMAP_USBTLL_SYSCONFIG_SIDLEMODE |
+			OMAP_USBTLL_SYSCONFIG_CACTIVITY);
+
+
+	/* Put UHH in NoIdle/NoStandby mode */
+	reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSCONFIG);
+	reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP
+			| OMAP_UHH_SYSCONFIG_SIDLEMODE
+			| OMAP_UHH_SYSCONFIG_CACTIVITY
+			| OMAP_UHH_SYSCONFIG_MIDLEMODE);
+	reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE;
+
+	ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg);
+
+	reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_HOSTCONFIG);
+
+	/* setup ULPI bypass and burst configurations */
+	reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN
+			| OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN
+			| OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN);
+	reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN;
+
+	if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_UNKNOWN)
+		reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS;
+	if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_UNKNOWN)
+		reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS;
+	if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_UNKNOWN)
+		reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS;
+
+	/* Bypass the TLL module for PHY mode operation */
+	 if (omap_rev() <= OMAP3430_REV_ES2_1) {
+		dev_dbg(omap->dev, "OMAP3 ES version <= ES2.1 \n");
+		if ((omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) ||
+			(omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) ||
+				(omap->port_mode[2] == EHCI_HCD_OMAP_MODE_PHY))
+			reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
+		else
+			reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
+	} else {
+		dev_dbg(omap->dev, "OMAP3 ES version > ES2.1\n");
+		if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY)
+			reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS;
+		else if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL)
+			reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS;
+
+		if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY)
+			reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS;
+		else if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL)
+			reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS;
+
+		if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_PHY)
+			reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS;
+		else if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL)
+			reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS;
+
+	}
+	ehci_omap_writel(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg);
+	dev_dbg(omap->dev, "UHH setup done, uhh_hostconfig=%x\n", reg);
+
+
+	if ((omap->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL) ||
+		(omap->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL) ||
+			(omap->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL)) {
+
+		if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL)
+			tll_ch_mask |= OMAP_TLL_CHANNEL_1_EN_MASK;
+		if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL)
+			tll_ch_mask |= OMAP_TLL_CHANNEL_2_EN_MASK;
+		if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL)
+			tll_ch_mask |= OMAP_TLL_CHANNEL_3_EN_MASK;
+
+		/* Enable UTMI mode for required TLL channels */
+		omap_usb_utmi_init(omap, tll_ch_mask);
+	}
+
+	if (omap->phy_reset) {
+		/* Refer ISSUE1:
+		 * Hold the PHY in RESET for enough time till
+		 * PHY is settled and ready
+		 */
+		udelay(10);
+
+		if (gpio_is_valid(omap->reset_gpio_port[0]))
+			gpio_set_value(omap->reset_gpio_port[0], 1);
+
+		if (gpio_is_valid(omap->reset_gpio_port[1]))
+			gpio_set_value(omap->reset_gpio_port[1], 1);
+	}
+
+	return 0;
+
+err_sys_status:
+	clk_disable(omap->usbtll_ick);
+	clk_put(omap->usbtll_ick);
+
+err_tll_ick:
+	clk_disable(omap->usbtll_fck);
+	clk_put(omap->usbtll_fck);
+
+err_tll_fck:
+	clk_disable(omap->usbhost1_48m_fck);
+	clk_put(omap->usbhost1_48m_fck);
+
+	if (omap->phy_reset) {
+		if (gpio_is_valid(omap->reset_gpio_port[0]))
+			gpio_free(omap->reset_gpio_port[0]);
+
+		if (gpio_is_valid(omap->reset_gpio_port[1]))
+			gpio_free(omap->reset_gpio_port[1]);
+	}
+
+err_host_48m_fck:
+	clk_disable(omap->usbhost2_120m_fck);
+	clk_put(omap->usbhost2_120m_fck);
+
+err_host_120m_fck:
+	clk_disable(omap->usbhost_ick);
+	clk_put(omap->usbhost_ick);
+
+err_host_ick:
+	return ret;
+}
+
+static void omap_stop_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd)
+{
+	unsigned long timeout = jiffies + msecs_to_jiffies(100);
+
+	dev_dbg(omap->dev, "stopping TI EHCI USB Controller\n");
+
+	/* Reset OMAP modules for insmod/rmmod to work */
+	ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG,
+			OMAP_UHH_SYSCONFIG_SOFTRESET);
+	while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS)
+				& (1 << 0))) {
+		cpu_relax();
+
+		if (time_after(jiffies, timeout))
+			dev_dbg(omap->dev, "operation timed out\n");
+	}
+
+	while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS)
+				& (1 << 1))) {
+		cpu_relax();
+
+		if (time_after(jiffies, timeout))
+			dev_dbg(omap->dev, "operation timed out\n");
+	}
+
+	while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS)
+				& (1 << 2))) {
+		cpu_relax();
+
+		if (time_after(jiffies, timeout))
+			dev_dbg(omap->dev, "operation timed out\n");
+	}
+
+	ehci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, (1 << 1));
+
+	while (!(ehci_omap_readl(omap->tll_base, OMAP_USBTLL_SYSSTATUS)
+				& (1 << 0))) {
+		cpu_relax();
+
+		if (time_after(jiffies, timeout))
+			dev_dbg(omap->dev, "operation timed out\n");
+	}
+
+	if (omap->usbtll_fck != NULL) {
+		clk_disable(omap->usbtll_fck);
+		clk_put(omap->usbtll_fck);
+		omap->usbtll_fck = NULL;
+	}
+
+	if (omap->usbhost_ick != NULL) {
+		clk_disable(omap->usbhost_ick);
+		clk_put(omap->usbhost_ick);
+		omap->usbhost_ick = NULL;
+	}
+
+	if (omap->usbhost1_48m_fck != NULL) {
+		clk_disable(omap->usbhost1_48m_fck);
+		clk_put(omap->usbhost1_48m_fck);
+		omap->usbhost1_48m_fck = NULL;
+	}
+
+	if (omap->usbhost2_120m_fck != NULL) {
+		clk_disable(omap->usbhost2_120m_fck);
+		clk_put(omap->usbhost2_120m_fck);
+		omap->usbhost2_120m_fck = NULL;
+	}
+
+	if (omap->usbtll_ick != NULL) {
+		clk_disable(omap->usbtll_ick);
+		clk_put(omap->usbtll_ick);
+		omap->usbtll_ick = NULL;
+	}
+
+	if (omap->phy_reset) {
+		if (gpio_is_valid(omap->reset_gpio_port[0]))
+			gpio_free(omap->reset_gpio_port[0]);
+
+		if (gpio_is_valid(omap->reset_gpio_port[1]))
+			gpio_free(omap->reset_gpio_port[1]);
+	}
+
+	dev_dbg(omap->dev, "Clock to USB host has been disabled\n");
+}
+
+/*-------------------------------------------------------------------------*/
+
+static const struct hc_driver ehci_omap_hc_driver;
+
+/* configure so an HC device and id are always provided */
+/* always called with process context; sleeping is OK */
+
+/**
+ * ehci_hcd_omap_probe - initialize TI-based HCDs
+ *
+ * Allocates basic resources for this USB host controller, and
+ * then invokes the start() method for the HCD associated with it
+ * through the hotplug entry's driver_data.
+ */
+static int ehci_hcd_omap_probe(struct platform_device *pdev)
+{
+	struct ehci_hcd_omap_platform_data *pdata = pdev->dev.platform_data;
+	struct ehci_hcd_omap *omap;
+	struct resource *res;
+	struct usb_hcd *hcd;
+
+	int irq = platform_get_irq(pdev, 0);
+	int ret = -ENODEV;
+
+	if (!pdata) {
+		dev_dbg(&pdev->dev, "missing platform_data\n");
+		goto err_pdata;
+	}
+
+	if (usb_disabled())
+		goto err_disabled;
+
+	omap = kzalloc(sizeof(*omap), GFP_KERNEL);
+	if (!omap) {
+		ret = -ENOMEM;
+		goto err_disabled;
+	}
+
+	hcd = usb_create_hcd(&ehci_omap_hc_driver, &pdev->dev,
+			dev_name(&pdev->dev));
+	if (!hcd) {
+		dev_dbg(&pdev->dev, "failed to create hcd with err %d\n", ret);
+		ret = -ENOMEM;
+		goto err_create_hcd;
+	}
+
+	platform_set_drvdata(pdev, omap);
+	omap->dev		= &pdev->dev;
+	omap->phy_reset		= pdata->phy_reset;
+	omap->reset_gpio_port[0]	= pdata->reset_gpio_port[0];
+	omap->reset_gpio_port[1]	= pdata->reset_gpio_port[1];
+	omap->reset_gpio_port[2]	= pdata->reset_gpio_port[2];
+	omap->port_mode[0]		= pdata->port_mode[0];
+	omap->port_mode[1]		= pdata->port_mode[1];
+	omap->port_mode[2]		= pdata->port_mode[2];
+	omap->ehci		= hcd_to_ehci(hcd);
+	omap->ehci->sbrn	= 0x20;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	hcd->rsrc_start = res->start;
+	hcd->rsrc_len = resource_size(res);
+
+	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+	if (!hcd->regs) {
+		dev_err(&pdev->dev, "EHCI ioremap failed\n");
+		ret = -ENOMEM;
+		goto err_ioremap;
+	}
+
+	/* we know this is the memory we want, no need to ioremap again */
+	omap->ehci->caps = hcd->regs;
+	omap->ehci_base = hcd->regs;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	omap->uhh_base = ioremap(res->start, resource_size(res));
+	if (!omap->uhh_base) {
+		dev_err(&pdev->dev, "UHH ioremap failed\n");
+		ret = -ENOMEM;
+		goto err_uhh_ioremap;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+	omap->tll_base = ioremap(res->start, resource_size(res));
+	if (!omap->tll_base) {
+		dev_err(&pdev->dev, "TLL ioremap failed\n");
+		ret = -ENOMEM;
+		goto err_tll_ioremap;
+	}
+
+	ret = omap_start_ehc(omap, hcd);
+	if (ret) {
+		dev_dbg(&pdev->dev, "failed to start ehci\n");
+		goto err_start;
+	}
+
+	omap->ehci->regs = hcd->regs
+		+ HC_LENGTH(readl(&omap->ehci->caps->hc_capbase));
+
+	/* cache this readonly data; minimize chip reads */
+	omap->ehci->hcs_params = readl(&omap->ehci->caps->hcs_params);
+
+	/* SET 1 micro-frame Interrupt interval */
+	writel(readl(&omap->ehci->regs->command) | (1 << 16),
+			&omap->ehci->regs->command);
+
+	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
+	if (ret) {
+		dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret);
+		goto err_add_hcd;
+	}
+
+	return 0;
+
+err_add_hcd:
+	omap_stop_ehc(omap, hcd);
+
+err_start:
+	iounmap(omap->tll_base);
+
+err_tll_ioremap:
+	iounmap(omap->uhh_base);
+
+err_uhh_ioremap:
+	iounmap(hcd->regs);
+
+err_ioremap:
+	usb_put_hcd(hcd);
+
+err_create_hcd:
+	kfree(omap);
+err_disabled:
+err_pdata:
+	return ret;
+}
+
+/* may be called without controller electrically present */
+/* may be called with controller, bus, and devices active */
+
+/**
+ * ehci_hcd_omap_remove - shutdown processing for EHCI HCDs
+ * @pdev: USB Host Controller being removed
+ *
+ * Reverses the effect of usb_ehci_hcd_omap_probe(), first invoking
+ * the HCD's stop() method.  It is always called from a thread
+ * context, normally "rmmod", "apmd", or something similar.
+ */
+static int ehci_hcd_omap_remove(struct platform_device *pdev)
+{
+	struct ehci_hcd_omap *omap = platform_get_drvdata(pdev);
+	struct usb_hcd *hcd = ehci_to_hcd(omap->ehci);
+
+	usb_remove_hcd(hcd);
+	omap_stop_ehc(omap, hcd);
+	iounmap(hcd->regs);
+	iounmap(omap->tll_base);
+	iounmap(omap->uhh_base);
+	usb_put_hcd(hcd);
+
+	return 0;
+}
+
+static void ehci_hcd_omap_shutdown(struct platform_device *pdev)
+{
+	struct ehci_hcd_omap *omap = platform_get_drvdata(pdev);
+	struct usb_hcd *hcd = ehci_to_hcd(omap->ehci);
+
+	if (hcd->driver->shutdown)
+		hcd->driver->shutdown(hcd);
+}
+
+static struct platform_driver ehci_hcd_omap_driver = {
+	.probe			= ehci_hcd_omap_probe,
+	.remove			= ehci_hcd_omap_remove,
+	.shutdown		= ehci_hcd_omap_shutdown,
+	/*.suspend		= ehci_hcd_omap_suspend, */
+	/*.resume		= ehci_hcd_omap_resume, */
+	.driver = {
+		.name		= "ehci-omap",
+	}
+};
+
+/*-------------------------------------------------------------------------*/
+
+static const struct hc_driver ehci_omap_hc_driver = {
+	.description		= hcd_name,
+	.product_desc		= "OMAP-EHCI Host Controller",
+	.hcd_priv_size		= sizeof(struct ehci_hcd),
+
+	/*
+	 * generic hardware linkage
+	 */
+	.irq			= ehci_irq,
+	.flags			= HCD_MEMORY | HCD_USB2,
+
+	/*
+	 * basic lifecycle operations
+	 */
+	.reset			= ehci_init,
+	.start			= ehci_run,
+	.stop			= ehci_stop,
+	.shutdown		= ehci_shutdown,
+
+	/*
+	 * managing i/o requests and associated device resources
+	 */
+	.urb_enqueue		= ehci_urb_enqueue,
+	.urb_dequeue		= ehci_urb_dequeue,
+	.endpoint_disable	= ehci_endpoint_disable,
+	.endpoint_reset		= ehci_endpoint_reset,
+
+	/*
+	 * scheduling support
+	 */
+	.get_frame_number	= ehci_get_frame,
+
+	/*
+	 * root hub support
+	 */
+	.hub_status_data	= ehci_hub_status_data,
+	.hub_control		= ehci_hub_control,
+	.bus_suspend		= ehci_bus_suspend,
+	.bus_resume		= ehci_bus_resume,
+
+	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
+};
+
+MODULE_ALIAS("platform:omap-ehci");
+MODULE_AUTHOR("Texas Instruments, Inc.");
+MODULE_AUTHOR("Felipe Balbi <felipe.balbi@nokia.com>");
+
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 139a2cc..a427d3b 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -616,9 +616,11 @@
 ) {
 	struct ehci_qtd		*qtd, *qtd_prev;
 	dma_addr_t		buf;
-	int			len, maxpacket;
+	int			len, this_sg_len, maxpacket;
 	int			is_input;
 	u32			token;
+	int			i;
+	struct scatterlist	*sg;
 
 	/*
 	 * URBs map to sequences of QTDs:  one logical transaction
@@ -659,7 +661,20 @@
 	/*
 	 * data transfer stage:  buffer setup
 	 */
-	buf = urb->transfer_dma;
+	i = urb->num_sgs;
+	if (len > 0 && i > 0) {
+		sg = urb->sg->sg;
+		buf = sg_dma_address(sg);
+
+		/* urb->transfer_buffer_length may be smaller than the
+		 * size of the scatterlist (or vice versa)
+		 */
+		this_sg_len = min_t(int, sg_dma_len(sg), len);
+	} else {
+		sg = NULL;
+		buf = urb->transfer_dma;
+		this_sg_len = len;
+	}
 
 	if (is_input)
 		token |= (1 /* "in" */ << 8);
@@ -675,7 +690,9 @@
 	for (;;) {
 		int this_qtd_len;
 
-		this_qtd_len = qtd_fill(ehci, qtd, buf, len, token, maxpacket);
+		this_qtd_len = qtd_fill(ehci, qtd, buf, this_sg_len, token,
+				maxpacket);
+		this_sg_len -= this_qtd_len;
 		len -= this_qtd_len;
 		buf += this_qtd_len;
 
@@ -691,8 +708,13 @@
 		if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0)
 			token ^= QTD_TOGGLE;
 
-		if (likely (len <= 0))
-			break;
+		if (likely(this_sg_len <= 0)) {
+			if (--i <= 0 || len <= 0)
+				break;
+			sg = sg_next(sg);
+			buf = sg_dma_address(sg);
+			this_sg_len = min_t(int, sg_dma_len(sg), len);
+		}
 
 		qtd_prev = qtd;
 		qtd = ehci_qtd_alloc (ehci, flags);
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index a5535b5..1e391e6 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -1385,7 +1385,7 @@
  * given EHCI_TUNE_FLS and the slop).  Or, write a smarter scheduler!
  */
 
-#define SCHEDULE_SLOP	10	/* frames */
+#define SCHEDULE_SLOP	80	/* microframes */
 
 static int
 iso_stream_schedule (
@@ -1394,12 +1394,13 @@
 	struct ehci_iso_stream	*stream
 )
 {
-	u32			now, start, max, period;
+	u32			now, next, start, period;
 	int			status;
 	unsigned		mod = ehci->periodic_size << 3;
 	struct ehci_iso_sched	*sched = urb->hcpriv;
+	struct pci_dev		*pdev;
 
-	if (sched->span > (mod - 8 * SCHEDULE_SLOP)) {
+	if (sched->span > (mod - SCHEDULE_SLOP)) {
 		ehci_dbg (ehci, "iso request %p too long\n", urb);
 		status = -EFBIG;
 		goto fail;
@@ -1418,26 +1419,35 @@
 
 	now = ehci_readl(ehci, &ehci->regs->frame_index) % mod;
 
-	/* when's the last uframe this urb could start? */
-	max = now + mod;
-
 	/* Typical case: reuse current schedule, stream is still active.
 	 * Hopefully there are no gaps from the host falling behind
 	 * (irq delays etc), but if there are we'll take the next
 	 * slot in the schedule, implicitly assuming URB_ISO_ASAP.
 	 */
 	if (likely (!list_empty (&stream->td_list))) {
+		pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller);
 		start = stream->next_uframe;
-		if (start < now)
-			start += mod;
+
+		/* For high speed devices, allow scheduling within the
+		 * isochronous scheduling threshold.  For full speed devices,
+		 * don't. (Work around for Intel ICH9 bug.)
+		 */
+		if (!stream->highspeed &&
+				pdev->vendor == PCI_VENDOR_ID_INTEL)
+			next = now + ehci->i_thresh;
+		else
+			next = now;
 
 		/* Fell behind (by up to twice the slop amount)? */
-		if (start >= max - 2 * 8 * SCHEDULE_SLOP)
+		if (((start - next) & (mod - 1)) >=
+				mod - 2 * SCHEDULE_SLOP)
 			start += period * DIV_ROUND_UP(
-					max - start, period) - mod;
+					(next - start) & (mod - 1),
+					period);
 
 		/* Tried to schedule too far into the future? */
-		if (unlikely((start + sched->span) >= max)) {
+		if (unlikely(((start - now) & (mod - 1)) + sched->span
+					>= mod - 2 * SCHEDULE_SLOP)) {
 			status = -EFBIG;
 			goto fail;
 		}
@@ -1451,7 +1461,7 @@
 	 * can also help high bandwidth if the dma and irq loads don't
 	 * jump until after the queue is primed.
 	 */
-	start = SCHEDULE_SLOP * 8 + (now & ~0x07);
+	start = SCHEDULE_SLOP + (now & ~0x07);
 	start %= mod;
 	stream->next_uframe = start;
 
@@ -1482,7 +1492,7 @@
 	/* no room in the schedule */
 	ehci_dbg (ehci, "iso %ssched full %p (now %d max %d)\n",
 		list_empty (&stream->td_list) ? "" : "re",
-		urb, now, max);
+		urb, now, now + mod);
 	status = -ENOSPC;
 
 fail:
diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c
new file mode 100644
index 0000000..a5861531
--- /dev/null
+++ b/drivers/usb/host/ehci-xilinx-of.c
@@ -0,0 +1,300 @@
+/*
+ * EHCI HCD (Host Controller Driver) for USB.
+ *
+ * Bus Glue for Xilinx EHCI core on the of_platform bus
+ *
+ * Copyright (c) 2009 Xilinx, Inc.
+ *
+ * Based on "ehci-ppc-of.c" by Valentine Barshak <vbarshak@ru.mvista.com>
+ * and "ehci-ppc-soc.c" by Stefan Roese <sr@denx.de>
+ * and "ohci-ppc-of.c" by Sylvain Munaut <tnt@246tNt.com>
+ *
+ * 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.
+ *
+ */
+
+#include <linux/signal.h>
+
+#include <linux/of.h>
+#include <linux/of_platform.h>
+
+/**
+ * ehci_xilinx_of_setup - Initialize the device for ehci_reset()
+ * @hcd:	Pointer to the usb_hcd device to which the host controller bound
+ *
+ * called during probe() after chip reset completes.
+ */
+static int ehci_xilinx_of_setup(struct usb_hcd *hcd)
+{
+	struct ehci_hcd	*ehci = hcd_to_ehci(hcd);
+	int		retval;
+
+	retval = ehci_halt(ehci);
+	if (retval)
+		return retval;
+
+	retval = ehci_init(hcd);
+	if (retval)
+		return retval;
+
+	ehci->sbrn = 0x20;
+
+	return ehci_reset(ehci);
+}
+
+/**
+ * ehci_xilinx_port_handed_over - hand the port out if failed to enable it
+ * @hcd:	Pointer to the usb_hcd device to which the host controller bound
+ * @portnum:Port number to which the device is attached.
+ *
+ * This function is used as a place to tell the user that the Xilinx USB host
+ * controller does support LS devices. And in an HS only configuration, it
+ * does not support FS devices either. It is hoped that this can help a
+ * confused user.
+ *
+ * There are cases when the host controller fails to enable the port due to,
+ * for example, insufficient power that can be supplied to the device from
+ * the USB bus. In those cases, the messages printed here are not helpful.
+ */
+static int ehci_xilinx_port_handed_over(struct usb_hcd *hcd, int portnum)
+{
+	dev_warn(hcd->self.controller, "port %d cannot be enabled\n", portnum);
+	if (hcd->has_tt) {
+		dev_warn(hcd->self.controller,
+			"Maybe you have connected a low speed device?\n");
+
+		dev_warn(hcd->self.controller,
+			"We do not support low speed devices\n");
+	} else {
+		dev_warn(hcd->self.controller,
+			"Maybe your device is not a high speed device?\n");
+		dev_warn(hcd->self.controller,
+			"The USB host controller does not support full speed "
+			"nor low speed devices\n");
+		dev_warn(hcd->self.controller,
+			"You can reconfigure the host controller to have "
+			"full speed support\n");
+	}
+
+	return 0;
+}
+
+
+static const struct hc_driver ehci_xilinx_of_hc_driver = {
+	.description		= hcd_name,
+	.product_desc		= "OF EHCI",
+	.hcd_priv_size		= sizeof(struct ehci_hcd),
+
+	/*
+	 * generic hardware linkage
+	 */
+	.irq			= ehci_irq,
+	.flags			= HCD_MEMORY | HCD_USB2,
+
+	/*
+	 * basic lifecycle operations
+	 */
+	.reset			= ehci_xilinx_of_setup,
+	.start			= ehci_run,
+	.stop			= ehci_stop,
+	.shutdown		= ehci_shutdown,
+
+	/*
+	 * managing i/o requests and associated device resources
+	 */
+	.urb_enqueue		= ehci_urb_enqueue,
+	.urb_dequeue		= ehci_urb_dequeue,
+	.endpoint_disable	= ehci_endpoint_disable,
+
+	/*
+	 * scheduling support
+	 */
+	.get_frame_number	= ehci_get_frame,
+
+	/*
+	 * root hub support
+	 */
+	.hub_status_data	= ehci_hub_status_data,
+	.hub_control		= ehci_hub_control,
+#ifdef	CONFIG_PM
+	.bus_suspend		= ehci_bus_suspend,
+	.bus_resume		= ehci_bus_resume,
+#endif
+	.relinquish_port	= NULL,
+	.port_handed_over	= ehci_xilinx_port_handed_over,
+
+	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
+};
+
+/**
+ * ehci_hcd_xilinx_of_probe - Probe method for the USB host controller
+ * @op:		pointer to the of_device to which the host controller bound
+ * @match:	pointer to of_device_id structure, not used
+ *
+ * This function requests resources and sets up appropriate properties for the
+ * host controller. Because the Xilinx USB host controller can be configured
+ * as HS only or HS/FS only, it checks the configuration in the device tree
+ * entry, and sets an appropriate value for hcd->has_tt.
+ */
+static int __devinit
+ehci_hcd_xilinx_of_probe(struct of_device *op, const struct of_device_id *match)
+{
+	struct device_node *dn = op->node;
+	struct usb_hcd *hcd;
+	struct ehci_hcd	*ehci;
+	struct resource res;
+	int irq;
+	int rv;
+	int *value;
+
+	if (usb_disabled())
+		return -ENODEV;
+
+	dev_dbg(&op->dev, "initializing XILINX-OF USB Controller\n");
+
+	rv = of_address_to_resource(dn, 0, &res);
+	if (rv)
+		return rv;
+
+	hcd = usb_create_hcd(&ehci_xilinx_of_hc_driver, &op->dev,
+				"XILINX-OF USB");
+	if (!hcd)
+		return -ENOMEM;
+
+	hcd->rsrc_start = res.start;
+	hcd->rsrc_len = res.end - res.start + 1;
+
+	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+		printk(KERN_ERR __FILE__ ": request_mem_region failed\n");
+		rv = -EBUSY;
+		goto err_rmr;
+	}
+
+	irq = irq_of_parse_and_map(dn, 0);
+	if (irq == NO_IRQ) {
+		printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n");
+		rv = -EBUSY;
+		goto err_irq;
+	}
+
+	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+	if (!hcd->regs) {
+		printk(KERN_ERR __FILE__ ": ioremap failed\n");
+		rv = -ENOMEM;
+		goto err_ioremap;
+	}
+
+	ehci = hcd_to_ehci(hcd);
+
+	/* This core always has big-endian register interface and uses
+	 * big-endian memory descriptors.
+	 */
+	ehci->big_endian_mmio = 1;
+	ehci->big_endian_desc = 1;
+
+	/* Check whether the FS support option is selected in the hardware.
+	 */
+	value = (int *)of_get_property(dn, "xlnx,support-usb-fs", NULL);
+	if (value && (*value == 1)) {
+		ehci_dbg(ehci, "USB host controller supports FS devices\n");
+		hcd->has_tt = 1;
+	} else {
+		ehci_dbg(ehci,
+			"USB host controller is HS only\n");
+		hcd->has_tt = 0;
+	}
+
+	/* Debug registers are at the first 0x100 region
+	 */
+	ehci->caps = hcd->regs + 0x100;
+	ehci->regs = hcd->regs + 0x100 +
+			HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
+
+	/* cache this readonly data; minimize chip reads */
+	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
+
+	rv = usb_add_hcd(hcd, irq, 0);
+	if (rv == 0)
+		return 0;
+
+	iounmap(hcd->regs);
+
+err_ioremap:
+err_irq:
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err_rmr:
+	usb_put_hcd(hcd);
+
+	return rv;
+}
+
+/**
+ * ehci_hcd_xilinx_of_remove - shutdown hcd and release resources
+ * @op:		pointer to of_device structure that is to be removed
+ *
+ * Remove the hcd structure, and release resources that has been requested
+ * during probe.
+ */
+static int ehci_hcd_xilinx_of_remove(struct of_device *op)
+{
+	struct usb_hcd *hcd = dev_get_drvdata(&op->dev);
+	dev_set_drvdata(&op->dev, NULL);
+
+	dev_dbg(&op->dev, "stopping XILINX-OF USB Controller\n");
+
+	usb_remove_hcd(hcd);
+
+	iounmap(hcd->regs);
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+
+	usb_put_hcd(hcd);
+
+	return 0;
+}
+
+/**
+ * ehci_hcd_xilinx_of_shutdown - shutdown the hcd
+ * @op:		pointer to of_device structure that is to be removed
+ *
+ * Properly shutdown the hcd, call driver's shutdown routine.
+ */
+static int ehci_hcd_xilinx_of_shutdown(struct of_device *op)
+{
+	struct usb_hcd *hcd = dev_get_drvdata(&op->dev);
+
+	if (hcd->driver->shutdown)
+		hcd->driver->shutdown(hcd);
+
+	return 0;
+}
+
+
+static struct of_device_id ehci_hcd_xilinx_of_match[] = {
+		{.compatible = "xlnx,xps-usb-host-1.00.a",},
+	{},
+};
+MODULE_DEVICE_TABLE(of, ehci_hcd_xilinx_of_match);
+
+static struct of_platform_driver ehci_hcd_xilinx_of_driver = {
+	.name		= "xilinx-of-ehci",
+	.match_table	= ehci_hcd_xilinx_of_match,
+	.probe		= ehci_hcd_xilinx_of_probe,
+	.remove		= ehci_hcd_xilinx_of_remove,
+	.shutdown	= ehci_hcd_xilinx_of_shutdown,
+	.driver		= {
+		.name	= "xilinx-of-ehci",
+		.owner	= THIS_MODULE,
+	},
+};
diff --git a/drivers/usb/host/fhci-sched.c b/drivers/usb/host/fhci-sched.c
index 62a226b..00a2985 100644
--- a/drivers/usb/host/fhci-sched.c
+++ b/drivers/usb/host/fhci-sched.c
@@ -627,7 +627,7 @@
 
 
 /*
- * Process normal completions(error or sucess) and clean the schedule.
+ * Process normal completions(error or success) and clean the schedule.
  *
  * This is the main path for handing urbs back to drivers. The only other patth
  * is process_del_list(),which unlinks URBs by scanning EDs,instead of scanning
diff --git a/drivers/usb/host/isp1362.h b/drivers/usb/host/isp1362.h
index 1a253eb..5151516 100644
--- a/drivers/usb/host/isp1362.h
+++ b/drivers/usb/host/isp1362.h
@@ -534,8 +534,8 @@
 
 	/* periodic schedule: isochronous */
 	struct list_head	isoc;
-	int			istl_flip:1;
-	int			irq_active:1;
+	unsigned int		istl_flip:1;
+	unsigned int		irq_active:1;
 
 	/* Schedules for the current frame */
 	struct isp1362_ep_queue atl_queue;
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 7ccffcb..68b83ab 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -35,7 +35,7 @@
 
 static void at91_start_clock(void)
 {
-	if (cpu_is_at91sam9261())
+	if (cpu_is_at91sam9261() || cpu_is_at91sam9g10())
 		clk_enable(hclk);
 	clk_enable(iclk);
 	clk_enable(fclk);
@@ -46,7 +46,7 @@
 {
 	clk_disable(fclk);
 	clk_disable(iclk);
-	if (cpu_is_at91sam9261())
+	if (cpu_is_at91sam9261() || cpu_is_at91sam9g10())
 		clk_disable(hclk);
 	clocked = 0;
 }
@@ -142,7 +142,7 @@
 
 	iclk = clk_get(&pdev->dev, "ohci_clk");
 	fclk = clk_get(&pdev->dev, "uhpck");
-	if (cpu_is_at91sam9261())
+	if (cpu_is_at91sam9261() || cpu_is_at91sam9g10())
 		hclk = clk_get(&pdev->dev, "hck0");
 
 	at91_start_hc(pdev);
@@ -155,7 +155,7 @@
 	/* Error handling */
 	at91_stop_hc(pdev);
 
-	if (cpu_is_at91sam9261())
+	if (cpu_is_at91sam9261() || cpu_is_at91sam9g10())
 		clk_put(hclk);
 	clk_put(fclk);
 	clk_put(iclk);
@@ -192,7 +192,7 @@
 	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
 	usb_put_hcd(hcd);
 
-	if (cpu_is_at91sam9261())
+	if (cpu_is_at91sam9261() || cpu_is_at91sam9g10())
 		clk_put(hclk);
 	clk_put(fclk);
 	clk_put(iclk);
diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c
index 100bf3d..2769326 100644
--- a/drivers/usb/host/ohci-pnx4008.c
+++ b/drivers/usb/host/ohci-pnx4008.c
@@ -98,8 +98,8 @@
 #define ISP1301_I2C_INTERRUPT_RISING 0xE
 #define ISP1301_I2C_REG_CLEAR_ADDR 1
 
-struct i2c_driver isp1301_driver;
-struct i2c_client *isp1301_i2c_client;
+static struct i2c_driver isp1301_driver;
+static struct i2c_client *isp1301_i2c_client;
 
 extern int usb_disabled(void);
 extern int ocpi_enable(void);
@@ -120,12 +120,12 @@
 	return 0;
 }
 
-const struct i2c_device_id isp1301_id[] = {
+static const struct i2c_device_id isp1301_id[] = {
 	{ "isp1301_pnx", 0 },
 	{ }
 };
 
-struct i2c_driver isp1301_driver = {
+static struct i2c_driver isp1301_driver = {
 	.driver = {
 		.name = "isp1301_pnx",
 	},
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index e33d362..41dbc70 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -822,8 +822,6 @@
 		return;
 
 	list_for_each_entry_safe(td, next, list, queue) {
-		if (!td)
-			continue;
 		if (td->address != address)
 			continue;
 
@@ -2025,8 +2023,6 @@
 	struct list_head *list = &r8a66597->child_device;
 
 	list_for_each_entry(dev, list, device_list) {
-		if (!dev)
-			continue;
 		if (dev->usb_address != addr)
 			continue;
 
diff --git a/drivers/usb/host/whci/debug.c b/drivers/usb/host/whci/debug.c
index 2273c81..8c1c610 100644
--- a/drivers/usb/host/whci/debug.c
+++ b/drivers/usb/host/whci/debug.c
@@ -31,17 +31,29 @@
 
 void qset_print(struct seq_file *s, struct whc_qset *qset)
 {
+	static const char *qh_type[] = {
+		"ctrl", "isoc", "bulk", "intr", "rsvd", "rsvd", "rsvd", "lpintr", };
 	struct whc_std *std;
 	struct urb *urb = NULL;
 	int i;
 
-	seq_printf(s, "qset %08x\n", (u32)qset->qset_dma);
+	seq_printf(s, "qset %08x", (u32)qset->qset_dma);
+	if (&qset->list_node == qset->whc->async_list.prev) {
+		seq_printf(s, " (dummy)\n");
+	} else {
+		seq_printf(s, " ep%d%s-%s maxpkt: %d\n",
+			   qset->qh.info1 & 0x0f,
+			   (qset->qh.info1 >> 4) & 0x1 ? "in" : "out",
+			   qh_type[(qset->qh.info1 >> 5) & 0x7],
+			   (qset->qh.info1 >> 16) & 0xffff);
+	}
 	seq_printf(s, "  -> %08x\n", (u32)qset->qh.link);
 	seq_printf(s, "  info: %08x %08x %08x\n",
-		qset->qh.info1, qset->qh.info2,  qset->qh.info3);
-	seq_printf(s, "  sts: %04x errs: %d\n", qset->qh.status, qset->qh.err_count);
+		   qset->qh.info1, qset->qh.info2,  qset->qh.info3);
+	seq_printf(s, "  sts: %04x errs: %d curwin: %08x\n",
+		   qset->qh.status, qset->qh.err_count, qset->qh.cur_window);
 	seq_printf(s, "  TD: sts: %08x opts: %08x\n",
-		qset->qh.overlay.qtd.status, qset->qh.overlay.qtd.options);
+		   qset->qh.overlay.qtd.status, qset->qh.overlay.qtd.options);
 
 	for (i = 0; i < WHCI_QSET_TD_MAX; i++) {
 		seq_printf(s, "  %c%c TD[%d]: sts: %08x opts: %08x ptr: %08x\n",
diff --git a/drivers/usb/host/whci/hcd.c b/drivers/usb/host/whci/hcd.c
index 687b622..e0d3401 100644
--- a/drivers/usb/host/whci/hcd.c
+++ b/drivers/usb/host/whci/hcd.c
@@ -250,6 +250,7 @@
 	}
 
 	usb_hcd->wireless = 1;
+	usb_hcd->self.sg_tablesize = 2048; /* somewhat arbitrary */
 
 	wusbhc = usb_hcd_to_wusbhc(usb_hcd);
 	whc = wusbhc_to_whc(wusbhc);
diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c
index 1b9dc15..7d4204d 100644
--- a/drivers/usb/host/whci/qset.c
+++ b/drivers/usb/host/whci/qset.c
@@ -49,16 +49,19 @@
  *        state
  * @urb:  an urb for a transfer to this endpoint
  */
-static void qset_fill_qh(struct whc_qset *qset, struct urb *urb)
+static void qset_fill_qh(struct whc *whc, struct whc_qset *qset, struct urb *urb)
 {
 	struct usb_device *usb_dev = urb->dev;
+	struct wusb_dev *wusb_dev = usb_dev->wusb_dev;
 	struct usb_wireless_ep_comp_descriptor *epcd;
 	bool is_out;
+	uint8_t phy_rate;
 
 	is_out = usb_pipeout(urb->pipe);
 
-	epcd = (struct usb_wireless_ep_comp_descriptor *)qset->ep->extra;
+	qset->max_packet = le16_to_cpu(urb->ep->desc.wMaxPacketSize);
 
+	epcd = (struct usb_wireless_ep_comp_descriptor *)qset->ep->extra;
 	if (epcd) {
 		qset->max_seq = epcd->bMaxSequence;
 		qset->max_burst = epcd->bMaxBurst;
@@ -67,12 +70,28 @@
 		qset->max_burst = 1;
 	}
 
+	/*
+	 * Initial PHY rate is 53.3 Mbit/s for control endpoints or
+	 * the maximum supported by the device for other endpoints
+	 * (unless limited by the user).
+	 */
+	if (usb_pipecontrol(urb->pipe))
+		phy_rate = UWB_PHY_RATE_53;
+	else {
+		uint16_t phy_rates;
+
+		phy_rates = le16_to_cpu(wusb_dev->wusb_cap_descr->wPHYRates);
+		phy_rate = fls(phy_rates) - 1;
+		if (phy_rate > whc->wusbhc.phy_rate)
+			phy_rate = whc->wusbhc.phy_rate;
+	}
+
 	qset->qh.info1 = cpu_to_le32(
 		QH_INFO1_EP(usb_pipeendpoint(urb->pipe))
 		| (is_out ? QH_INFO1_DIR_OUT : QH_INFO1_DIR_IN)
 		| usb_pipe_to_qh_type(urb->pipe)
 		| QH_INFO1_DEV_INFO_IDX(wusb_port_no_to_idx(usb_dev->portnum))
-		| QH_INFO1_MAX_PKT_LEN(usb_maxpacket(urb->dev, urb->pipe, is_out))
+		| QH_INFO1_MAX_PKT_LEN(qset->max_packet)
 		);
 	qset->qh.info2 = cpu_to_le32(
 		QH_INFO2_BURST(qset->max_burst)
@@ -86,7 +105,7 @@
 	 * strength and can presumably guess the Tx power required
 	 * from that? */
 	qset->qh.info3 = cpu_to_le32(
-		QH_INFO3_TX_RATE_53_3
+		QH_INFO3_TX_RATE(phy_rate)
 		| QH_INFO3_TX_PWR(0) /* 0 == max power */
 		);
 
@@ -148,7 +167,7 @@
 
 		qset->ep = urb->ep;
 		urb->ep->hcpriv = qset;
-		qset_fill_qh(qset, urb);
+		qset_fill_qh(whc, qset, urb);
 	}
 	return qset;
 }
@@ -241,6 +260,36 @@
 	qset->ntds--;
 }
 
+static void qset_copy_bounce_to_sg(struct whc *whc, struct whc_std *std)
+{
+	struct scatterlist *sg;
+	void *bounce;
+	size_t remaining, offset;
+
+	bounce = std->bounce_buf;
+	remaining = std->len;
+
+	sg = std->bounce_sg;
+	offset = std->bounce_offset;
+
+	while (remaining) {
+		size_t len;
+
+		len = min(sg->length - offset, remaining);
+		memcpy(sg_virt(sg) + offset, bounce, len);
+
+		bounce += len;
+		remaining -= len;
+
+		offset += len;
+		if (offset >= sg->length) {
+			sg = sg_next(sg);
+			offset = 0;
+		}
+	}
+
+}
+
 /**
  * qset_free_std - remove an sTD and free it.
  * @whc: the WHCI host controller
@@ -249,13 +298,29 @@
 void qset_free_std(struct whc *whc, struct whc_std *std)
 {
 	list_del(&std->list_node);
-	if (std->num_pointers) {
-		dma_unmap_single(whc->wusbhc.dev, std->dma_addr,
-				 std->num_pointers * sizeof(struct whc_page_list_entry),
-				 DMA_TO_DEVICE);
-		kfree(std->pl_virt);
-	}
+	if (std->bounce_buf) {
+		bool is_out = usb_pipeout(std->urb->pipe);
+		dma_addr_t dma_addr;
 
+		if (std->num_pointers)
+			dma_addr = le64_to_cpu(std->pl_virt[0].buf_ptr);
+		else
+			dma_addr = std->dma_addr;
+
+		dma_unmap_single(whc->wusbhc.dev, dma_addr,
+				 std->len, is_out ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+		if (!is_out)
+			qset_copy_bounce_to_sg(whc, std);
+		kfree(std->bounce_buf);
+	}
+	if (std->pl_virt) {
+		if (std->dma_addr)
+			dma_unmap_single(whc->wusbhc.dev, std->dma_addr,
+					 std->num_pointers * sizeof(struct whc_page_list_entry),
+					 DMA_TO_DEVICE);
+		kfree(std->pl_virt);
+		std->pl_virt = NULL;
+	}
 	kfree(std);
 }
 
@@ -293,12 +358,17 @@
 {
 	dma_addr_t dma_addr = std->dma_addr;
 	dma_addr_t sp, ep;
-	size_t std_len = std->len;
 	size_t pl_len;
 	int p;
 
-	sp = ALIGN(dma_addr, WHCI_PAGE_SIZE);
-	ep = dma_addr + std_len;
+	/* Short buffers don't need a page list. */
+	if (std->len <= WHCI_PAGE_SIZE) {
+		std->num_pointers = 0;
+		return 0;
+	}
+
+	sp = dma_addr & ~(WHCI_PAGE_SIZE-1);
+	ep = dma_addr + std->len;
 	std->num_pointers = DIV_ROUND_UP(ep - sp, WHCI_PAGE_SIZE);
 
 	pl_len = std->num_pointers * sizeof(struct whc_page_list_entry);
@@ -309,7 +379,7 @@
 
 	for (p = 0; p < std->num_pointers; p++) {
 		std->pl_virt[p].buf_ptr = cpu_to_le64(dma_addr);
-		dma_addr = ALIGN(dma_addr + WHCI_PAGE_SIZE, WHCI_PAGE_SIZE);
+		dma_addr = (dma_addr + WHCI_PAGE_SIZE) & ~(WHCI_PAGE_SIZE-1);
 	}
 
 	return 0;
@@ -339,6 +409,218 @@
 	spin_unlock_irqrestore(&whc->lock, flags);
 }
 
+static struct whc_std *qset_new_std(struct whc *whc, struct whc_qset *qset,
+				    struct urb *urb, gfp_t mem_flags)
+{
+	struct whc_std *std;
+
+	std = kzalloc(sizeof(struct whc_std), mem_flags);
+	if (std == NULL)
+		return NULL;
+
+	std->urb = urb;
+	std->qtd = NULL;
+
+	INIT_LIST_HEAD(&std->list_node);
+	list_add_tail(&std->list_node, &qset->stds);
+
+	return std;
+}
+
+static int qset_add_urb_sg(struct whc *whc, struct whc_qset *qset, struct urb *urb,
+			   gfp_t mem_flags)
+{
+	size_t remaining;
+	struct scatterlist *sg;
+	int i;
+	int ntds = 0;
+	struct whc_std *std = NULL;
+	struct whc_page_list_entry *entry;
+	dma_addr_t prev_end = 0;
+	size_t pl_len;
+	int p = 0;
+
+	remaining = urb->transfer_buffer_length;
+
+	for_each_sg(urb->sg->sg, sg, urb->num_sgs, i) {
+		dma_addr_t dma_addr;
+		size_t dma_remaining;
+		dma_addr_t sp, ep;
+		int num_pointers;
+
+		if (remaining == 0) {
+			break;
+		}
+
+		dma_addr = sg_dma_address(sg);
+		dma_remaining = min_t(size_t, sg_dma_len(sg), remaining);
+
+		while (dma_remaining) {
+			size_t dma_len;
+
+			/*
+			 * We can use the previous std (if it exists) provided that:
+			 * - the previous one ended on a page boundary.
+			 * - the current one begins on a page boundary.
+			 * - the previous one isn't full.
+			 *
+			 * If a new std is needed but the previous one
+			 * was not a whole number of packets then this
+			 * sg list cannot be mapped onto multiple
+			 * qTDs.  Return an error and let the caller
+			 * sort it out.
+			 */
+			if (!std
+			    || (prev_end & (WHCI_PAGE_SIZE-1))
+			    || (dma_addr & (WHCI_PAGE_SIZE-1))
+			    || std->len + WHCI_PAGE_SIZE > QTD_MAX_XFER_SIZE) {
+				if (std->len % qset->max_packet != 0)
+					return -EINVAL;
+				std = qset_new_std(whc, qset, urb, mem_flags);
+				if (std == NULL) {
+					return -ENOMEM;
+				}
+				ntds++;
+				p = 0;
+			}
+
+			dma_len = dma_remaining;
+
+			/*
+			 * If the remainder of this element doesn't
+			 * fit in a single qTD, limit the qTD to a
+			 * whole number of packets.  This allows the
+			 * remainder to go into the next qTD.
+			 */
+			if (std->len + dma_len > QTD_MAX_XFER_SIZE) {
+				dma_len = (QTD_MAX_XFER_SIZE / qset->max_packet)
+					* qset->max_packet - std->len;
+			}
+
+			std->len += dma_len;
+			std->ntds_remaining = -1; /* filled in later */
+
+			sp = dma_addr & ~(WHCI_PAGE_SIZE-1);
+			ep = dma_addr + dma_len;
+			num_pointers = DIV_ROUND_UP(ep - sp, WHCI_PAGE_SIZE);
+			std->num_pointers += num_pointers;
+
+			pl_len = std->num_pointers * sizeof(struct whc_page_list_entry);
+
+			std->pl_virt = krealloc(std->pl_virt, pl_len, mem_flags);
+			if (std->pl_virt == NULL) {
+				return -ENOMEM;
+			}
+
+			for (;p < std->num_pointers; p++, entry++) {
+				std->pl_virt[p].buf_ptr = cpu_to_le64(dma_addr);
+				dma_addr = (dma_addr + WHCI_PAGE_SIZE) & ~(WHCI_PAGE_SIZE-1);
+			}
+
+			prev_end = dma_addr = ep;
+			dma_remaining -= dma_len;
+			remaining -= dma_len;
+		}
+	}
+
+	/* Now the number of stds is know, go back and fill in
+	   std->ntds_remaining. */
+	list_for_each_entry(std, &qset->stds, list_node) {
+		if (std->ntds_remaining == -1) {
+			pl_len = std->num_pointers * sizeof(struct whc_page_list_entry);
+			std->ntds_remaining = ntds--;
+			std->dma_addr = dma_map_single(whc->wusbhc.dev, std->pl_virt,
+						       pl_len, DMA_TO_DEVICE);
+		}
+	}
+	return 0;
+}
+
+/**
+ * qset_add_urb_sg_linearize - add an urb with sg list, copying the data
+ *
+ * If the URB contains an sg list whose elements cannot be directly
+ * mapped to qTDs then the data must be transferred via bounce
+ * buffers.
+ */
+static int qset_add_urb_sg_linearize(struct whc *whc, struct whc_qset *qset,
+				     struct urb *urb, gfp_t mem_flags)
+{
+	bool is_out = usb_pipeout(urb->pipe);
+	size_t max_std_len;
+	size_t remaining;
+	int ntds = 0;
+	struct whc_std *std = NULL;
+	void *bounce = NULL;
+	struct scatterlist *sg;
+	int i;
+
+	/* limit maximum bounce buffer to 16 * 3.5 KiB ~= 28 k */
+	max_std_len = qset->max_burst * qset->max_packet;
+
+	remaining = urb->transfer_buffer_length;
+
+	for_each_sg(urb->sg->sg, sg, urb->sg->nents, i) {
+		size_t len;
+		size_t sg_remaining;
+		void *orig;
+
+		if (remaining == 0) {
+			break;
+		}
+
+		sg_remaining = min_t(size_t, remaining, sg->length);
+		orig = sg_virt(sg);
+
+		while (sg_remaining) {
+			if (!std || std->len == max_std_len) {
+				std = qset_new_std(whc, qset, urb, mem_flags);
+				if (std == NULL)
+					return -ENOMEM;
+				std->bounce_buf = kmalloc(max_std_len, mem_flags);
+				if (std->bounce_buf == NULL)
+					return -ENOMEM;
+				std->bounce_sg = sg;
+				std->bounce_offset = orig - sg_virt(sg);
+				bounce = std->bounce_buf;
+				ntds++;
+			}
+
+			len = min(sg_remaining, max_std_len - std->len);
+
+			if (is_out)
+				memcpy(bounce, orig, len);
+
+			std->len += len;
+			std->ntds_remaining = -1; /* filled in later */
+
+			bounce += len;
+			orig += len;
+			sg_remaining -= len;
+			remaining -= len;
+		}
+	}
+
+	/*
+	 * For each of the new sTDs, map the bounce buffers, create
+	 * page lists (if necessary), and fill in std->ntds_remaining.
+	 */
+	list_for_each_entry(std, &qset->stds, list_node) {
+		if (std->ntds_remaining != -1)
+			continue;
+
+		std->dma_addr = dma_map_single(&whc->umc->dev, std->bounce_buf, std->len,
+					       is_out ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+
+		if (qset_fill_page_list(whc, std, mem_flags) < 0)
+			return -ENOMEM;
+
+		std->ntds_remaining = ntds--;
+	}
+
+	return 0;
+}
+
 /**
  * qset_add_urb - add an urb to the qset's queue.
  *
@@ -353,10 +635,7 @@
 	int remaining = urb->transfer_buffer_length;
 	u64 transfer_dma = urb->transfer_dma;
 	int ntds_remaining;
-
-	ntds_remaining = DIV_ROUND_UP(remaining, QTD_MAX_XFER_SIZE);
-	if (ntds_remaining == 0)
-		ntds_remaining = 1;
+	int ret;
 
 	wurb = kzalloc(sizeof(struct whc_urb), mem_flags);
 	if (wurb == NULL)
@@ -366,32 +645,39 @@
 	wurb->urb = urb;
 	INIT_WORK(&wurb->dequeue_work, urb_dequeue_work);
 
+	if (urb->sg) {
+		ret = qset_add_urb_sg(whc, qset, urb, mem_flags);
+		if (ret == -EINVAL) {
+			qset_free_stds(qset, urb);
+			ret = qset_add_urb_sg_linearize(whc, qset, urb, mem_flags);
+		}
+		if (ret < 0)
+			goto err_no_mem;
+		return 0;
+	}
+
+	ntds_remaining = DIV_ROUND_UP(remaining, QTD_MAX_XFER_SIZE);
+	if (ntds_remaining == 0)
+		ntds_remaining = 1;
+
 	while (ntds_remaining) {
 		struct whc_std *std;
 		size_t std_len;
 
-		std = kmalloc(sizeof(struct whc_std), mem_flags);
-		if (std == NULL)
-			goto err_no_mem;
-
 		std_len = remaining;
 		if (std_len > QTD_MAX_XFER_SIZE)
 			std_len = QTD_MAX_XFER_SIZE;
 
-		std->urb = urb;
+		std = qset_new_std(whc, qset, urb, mem_flags);
+		if (std == NULL)
+			goto err_no_mem;
+
 		std->dma_addr = transfer_dma;
 		std->len = std_len;
 		std->ntds_remaining = ntds_remaining;
-		std->qtd = NULL;
 
-		INIT_LIST_HEAD(&std->list_node);
-		list_add_tail(&std->list_node, &qset->stds);
-
-		if (std_len > WHCI_PAGE_SIZE) {
-			if (qset_fill_page_list(whc, std, mem_flags) < 0)
-				goto err_no_mem;
-		} else
-			std->num_pointers = 0;
+		if (qset_fill_page_list(whc, std, mem_flags) < 0)
+			goto err_no_mem;
 
 		ntds_remaining--;
 		remaining -= std_len;
diff --git a/drivers/usb/host/whci/whcd.h b/drivers/usb/host/whci/whcd.h
index 24e94d9..c80c7d9 100644
--- a/drivers/usb/host/whci/whcd.h
+++ b/drivers/usb/host/whci/whcd.h
@@ -84,6 +84,11 @@
  * @len: the length of data in the associated TD.
  * @ntds_remaining: number of TDs (starting from this one) in this transfer.
  *
+ * @bounce_buf: a bounce buffer if the std was from an urb with a sg
+ * list that could not be mapped to qTDs directly.
+ * @bounce_sg: the first scatterlist element bounce_buf is for.
+ * @bounce_offset: the offset into bounce_sg for the start of bounce_buf.
+ *
  * Queued URBs may require more TDs than are available in a qset so we
  * use a list of these "software TDs" (sTDs) to hold per-TD data.
  */
@@ -97,6 +102,10 @@
 	int num_pointers;
 	dma_addr_t dma_addr;
 	struct whc_page_list_entry *pl_virt;
+
+	void *bounce_buf;
+	struct scatterlist *bounce_sg;
+	unsigned bounce_offset;
 };
 
 /**
diff --git a/drivers/usb/host/whci/whci-hc.h b/drivers/usb/host/whci/whci-hc.h
index e8d0001..4d4cbc0 100644
--- a/drivers/usb/host/whci/whci-hc.h
+++ b/drivers/usb/host/whci/whci-hc.h
@@ -172,14 +172,7 @@
 #define QH_INFO3_MAX_DELAY(d)    ((d) << 0)  /* maximum stream delay in 125 us units (isoc only) */
 #define QH_INFO3_INTERVAL(i)     ((i) << 16) /* segment interval in 125 us units (isoc only) */
 
-#define QH_INFO3_TX_RATE_53_3    (0 << 24)
-#define QH_INFO3_TX_RATE_80      (1 << 24)
-#define QH_INFO3_TX_RATE_106_7   (2 << 24)
-#define QH_INFO3_TX_RATE_160     (3 << 24)
-#define QH_INFO3_TX_RATE_200     (4 << 24)
-#define QH_INFO3_TX_RATE_320     (5 << 24)
-#define QH_INFO3_TX_RATE_400     (6 << 24)
-#define QH_INFO3_TX_RATE_480     (7 << 24)
+#define QH_INFO3_TX_RATE(r)      ((r) << 24) /* PHY rate (see [ECMA-368] section 10.3.1.1) */
 #define QH_INFO3_TX_PWR(p)       ((p) << 29) /* transmit power (see [WUSB] section 5.2.1.2) */
 
 #define QH_STATUS_FLOW_CTRL      (1 << 15)
@@ -267,8 +260,9 @@
 	unsigned reset:1;
 	struct urb *pause_after_urb;
 	struct completion remove_complete;
-	int max_burst;
-	int max_seq;
+	uint16_t max_packet;
+	uint8_t max_burst;
+	uint8_t max_seq;
 };
 
 static inline void whc_qset_set_link_ptr(u64 *ptr, u64 target)
diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c
index 932f999..5e92c72 100644
--- a/drivers/usb/host/xhci-hcd.c
+++ b/drivers/usb/host/xhci-hcd.c
@@ -67,6 +67,25 @@
 }
 
 /*
+ * Disable interrupts and begin the xHCI halting process.
+ */
+void xhci_quiesce(struct xhci_hcd *xhci)
+{
+	u32 halted;
+	u32 cmd;
+	u32 mask;
+
+	mask = ~(XHCI_IRQS);
+	halted = xhci_readl(xhci, &xhci->op_regs->status) & STS_HALT;
+	if (!halted)
+		mask &= ~CMD_RUN;
+
+	cmd = xhci_readl(xhci, &xhci->op_regs->command);
+	cmd &= mask;
+	xhci_writel(xhci, cmd, &xhci->op_regs->command);
+}
+
+/*
  * Force HC into halt state.
  *
  * Disable any IRQs and clear the run/stop bit.
@@ -77,20 +96,8 @@
  */
 int xhci_halt(struct xhci_hcd *xhci)
 {
-	u32 halted;
-	u32 cmd;
-	u32 mask;
-
 	xhci_dbg(xhci, "// Halt the HC\n");
-	/* Disable all interrupts from the host controller */
-	mask = ~(XHCI_IRQS);
-	halted = xhci_readl(xhci, &xhci->op_regs->status) & STS_HALT;
-	if (!halted)
-		mask &= ~CMD_RUN;
-
-	cmd = xhci_readl(xhci, &xhci->op_regs->command);
-	cmd &= mask;
-	xhci_writel(xhci, cmd, &xhci->op_regs->command);
+	xhci_quiesce(xhci);
 
 	return handshake(xhci, &xhci->op_regs->status,
 			STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC);
@@ -124,28 +131,6 @@
 	return handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 250 * 1000);
 }
 
-/*
- * Stop the HC from processing the endpoint queues.
- */
-static void xhci_quiesce(struct xhci_hcd *xhci)
-{
-	/*
-	 * Queues are per endpoint, so we need to disable an endpoint or slot.
-	 *
-	 * To disable a slot, we need to insert a disable slot command on the
-	 * command ring and ring the doorbell.  This will also free any internal
-	 * resources associated with the slot (which might not be what we want).
-	 *
-	 * A Release Endpoint command sounds better - doesn't free internal HC
-	 * memory, but removes the endpoints from the schedule and releases the
-	 * bandwidth, disables the doorbells, and clears the endpoint enable
-	 * flag.  Usually used prior to a set interface command.
-	 *
-	 * TODO: Implement after command ring code is done.
-	 */
-	BUG_ON(!HC_IS_RUNNING(xhci_to_hcd(xhci)->state));
-	xhci_dbg(xhci, "Finished quiescing -- code not written yet\n");
-}
 
 #if 0
 /* Set up MSI-X table for entry 0 (may claim other entries later) */
@@ -261,8 +246,14 @@
 	/* Flush posted writes */
 	xhci_readl(xhci, &xhci->ir_set->irq_pending);
 
-	/* FIXME this should be a delayed service routine that clears the EHB */
-	xhci_handle_event(xhci);
+	if (xhci->xhc_state & XHCI_STATE_DYING)
+		xhci_dbg(xhci, "xHCI dying, ignoring interrupt. "
+				"Shouldn't IRQs be disabled?\n");
+	else
+		/* FIXME this should be a delayed service routine
+		 * that clears the EHB.
+		 */
+		xhci_handle_event(xhci);
 
 	/* Clear the event handler busy flag (RW1C); the event ring should be empty. */
 	temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
@@ -335,7 +326,7 @@
 	spin_lock_irqsave(&xhci->lock, flags);
 	temp = xhci_readl(xhci, &xhci->op_regs->status);
 	xhci_dbg(xhci, "op reg status = 0x%x\n", temp);
-	if (temp == 0xffffffff) {
+	if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) {
 		xhci_dbg(xhci, "HW died, polling stopped.\n");
 		spin_unlock_irqrestore(&xhci->lock, flags);
 		return;
@@ -490,8 +481,6 @@
 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
 
 	spin_lock_irq(&xhci->lock);
-	if (HC_IS_RUNNING(hcd->state))
-		xhci_quiesce(xhci);
 	xhci_halt(xhci);
 	xhci_reset(xhci);
 	spin_unlock_irq(&xhci->lock);
@@ -727,16 +716,22 @@
 		 * atomic context to this function, which may allocate memory.
 		 */
 		spin_lock_irqsave(&xhci->lock, flags);
+		if (xhci->xhc_state & XHCI_STATE_DYING)
+			goto dying;
 		ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb,
 				slot_id, ep_index);
 		spin_unlock_irqrestore(&xhci->lock, flags);
 	} else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) {
 		spin_lock_irqsave(&xhci->lock, flags);
+		if (xhci->xhc_state & XHCI_STATE_DYING)
+			goto dying;
 		ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb,
 				slot_id, ep_index);
 		spin_unlock_irqrestore(&xhci->lock, flags);
 	} else if (usb_endpoint_xfer_int(&urb->ep->desc)) {
 		spin_lock_irqsave(&xhci->lock, flags);
+		if (xhci->xhc_state & XHCI_STATE_DYING)
+			goto dying;
 		ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb,
 				slot_id, ep_index);
 		spin_unlock_irqrestore(&xhci->lock, flags);
@@ -745,6 +740,12 @@
 	}
 exit:
 	return ret;
+dying:
+	xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for "
+			"non-responsive xHCI host.\n",
+			urb->ep->desc.bEndpointAddress, urb);
+	spin_unlock_irqrestore(&xhci->lock, flags);
+	return -ESHUTDOWN;
 }
 
 /*
@@ -806,6 +807,17 @@
 		kfree(td);
 		return ret;
 	}
+	if (xhci->xhc_state & XHCI_STATE_DYING) {
+		xhci_dbg(xhci, "Ep 0x%x: URB %p to be canceled on "
+				"non-responsive xHCI host.\n",
+				urb->ep->desc.bEndpointAddress, urb);
+		/* Let the stop endpoint command watchdog timer (which set this
+		 * state) finish cleaning up the endpoint TD lists.  We must
+		 * have caught it in the middle of dropping a lock and giving
+		 * back an URB.
+		 */
+		goto done;
+	}
 
 	xhci_dbg(xhci, "Cancel URB %p\n", urb);
 	xhci_dbg(xhci, "Event ring:\n");
@@ -817,12 +829,16 @@
 	xhci_debug_ring(xhci, ep_ring);
 	td = (struct xhci_td *) urb->hcpriv;
 
-	ep->cancels_pending++;
 	list_add_tail(&td->cancelled_td_list, &ep->cancelled_td_list);
 	/* Queue a stop endpoint command, but only if this is
 	 * the first cancellation to be handled.
 	 */
-	if (ep->cancels_pending == 1) {
+	if (!(ep->ep_state & EP_HALT_PENDING)) {
+		ep->ep_state |= EP_HALT_PENDING;
+		ep->stop_cmds_pending++;
+		ep->stop_cmd_timer.expires = jiffies +
+			XHCI_STOP_EP_CMD_TIMEOUT * HZ;
+		add_timer(&ep->stop_cmd_timer);
 		xhci_queue_stop_endpoint(xhci, urb->dev->slot_id, ep_index);
 		xhci_ring_cmd_db(xhci);
 	}
@@ -1246,13 +1262,35 @@
 			LAST_CTX_TO_EP_NUM(slot_ctx->dev_info));
 
 	xhci_zero_in_ctx(xhci, virt_dev);
-	/* Free any old rings */
+	/* Install new rings and free or cache any old rings */
 	for (i = 1; i < 31; ++i) {
-		if (virt_dev->eps[i].new_ring) {
-			xhci_ring_free(xhci, virt_dev->eps[i].ring);
-			virt_dev->eps[i].ring = virt_dev->eps[i].new_ring;
-			virt_dev->eps[i].new_ring = NULL;
+		int rings_cached;
+
+		if (!virt_dev->eps[i].new_ring)
+			continue;
+		/* Only cache or free the old ring if it exists.
+		 * It may not if this is the first add of an endpoint.
+		 */
+		if (virt_dev->eps[i].ring) {
+			rings_cached = virt_dev->num_rings_cached;
+			if (rings_cached < XHCI_MAX_RINGS_CACHED) {
+				virt_dev->num_rings_cached++;
+				rings_cached = virt_dev->num_rings_cached;
+				virt_dev->ring_cache[rings_cached] =
+					virt_dev->eps[i].ring;
+				xhci_dbg(xhci, "Cached old ring, "
+						"%d ring%s cached\n",
+						rings_cached,
+						(rings_cached > 1) ? "s" : "");
+			} else {
+				xhci_ring_free(xhci, virt_dev->eps[i].ring);
+				xhci_dbg(xhci, "Ring cache full (%d rings), "
+						"freeing ring\n",
+						virt_dev->num_rings_cached);
+			}
 		}
+		virt_dev->eps[i].ring = virt_dev->eps[i].new_ring;
+		virt_dev->eps[i].new_ring = NULL;
 	}
 
 	return ret;
@@ -1427,16 +1465,27 @@
 void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
 {
 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+	struct xhci_virt_device *virt_dev;
 	unsigned long flags;
 	u32 state;
+	int i;
 
 	if (udev->slot_id == 0)
 		return;
+	virt_dev = xhci->devs[udev->slot_id];
+	if (!virt_dev)
+		return;
+
+	/* Stop any wayward timer functions (which may grab the lock) */
+	for (i = 0; i < 31; ++i) {
+		virt_dev->eps[i].ep_state &= ~EP_HALT_PENDING;
+		del_timer_sync(&virt_dev->eps[i].stop_cmd_timer);
+	}
 
 	spin_lock_irqsave(&xhci->lock, flags);
 	/* Don't disable the slot if the host controller is dead. */
 	state = xhci_readl(xhci, &xhci->op_regs->status);
-	if (state == 0xffffffff) {
+	if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) {
 		xhci_free_virt_device(xhci, udev->slot_id);
 		spin_unlock_irqrestore(&xhci->lock, flags);
 		return;
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index b8fd270..bffcef7 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -125,6 +125,23 @@
 	kfree(ring);
 }
 
+static void xhci_initialize_ring_info(struct xhci_ring *ring)
+{
+	/* The ring is empty, so the enqueue pointer == dequeue pointer */
+	ring->enqueue = ring->first_seg->trbs;
+	ring->enq_seg = ring->first_seg;
+	ring->dequeue = ring->enqueue;
+	ring->deq_seg = ring->first_seg;
+	/* The ring is initialized to 0. The producer must write 1 to the cycle
+	 * bit to handover ownership of the TRB, so PCS = 1.  The consumer must
+	 * compare CCS to the cycle bit to check ownership, so CCS = 1.
+	 */
+	ring->cycle_state = 1;
+	/* Not necessary for new rings, but needed for re-initialized rings */
+	ring->enq_updates = 0;
+	ring->deq_updates = 0;
+}
+
 /**
  * Create a new ring with zero or more segments.
  *
@@ -173,17 +190,7 @@
 				" segment %p (virtual), 0x%llx (DMA)\n",
 				prev, (unsigned long long)prev->dma);
 	}
-	/* The ring is empty, so the enqueue pointer == dequeue pointer */
-	ring->enqueue = ring->first_seg->trbs;
-	ring->enq_seg = ring->first_seg;
-	ring->dequeue = ring->enqueue;
-	ring->deq_seg = ring->first_seg;
-	/* The ring is initialized to 0. The producer must write 1 to the cycle
-	 * bit to handover ownership of the TRB, so PCS = 1.  The consumer must
-	 * compare CCS to the cycle bit to check ownership, so CCS = 1.
-	 */
-	ring->cycle_state = 1;
-
+	xhci_initialize_ring_info(ring);
 	return ring;
 
 fail:
@@ -191,6 +198,27 @@
 	return 0;
 }
 
+/* Zero an endpoint ring (except for link TRBs) and move the enqueue and dequeue
+ * pointers to the beginning of the ring.
+ */
+static void xhci_reinit_cached_ring(struct xhci_hcd *xhci,
+		struct xhci_ring *ring)
+{
+	struct xhci_segment	*seg = ring->first_seg;
+	do {
+		memset(seg->trbs, 0,
+				sizeof(union xhci_trb)*TRBS_PER_SEGMENT);
+		/* All endpoint rings have link TRBs */
+		xhci_link_segments(xhci, seg, seg->next, 1);
+		seg = seg->next;
+	} while (seg != ring->first_seg);
+	xhci_initialize_ring_info(ring);
+	/* td list should be empty since all URBs have been cancelled,
+	 * but just in case...
+	 */
+	INIT_LIST_HEAD(&ring->td_list);
+}
+
 #define CTX_SIZE(_hcc) (HCC_64BYTE_CONTEXT(_hcc) ? 64 : 32)
 
 struct xhci_container_ctx *xhci_alloc_container_ctx(struct xhci_hcd *xhci,
@@ -248,6 +276,15 @@
 		(ctx->bytes + (ep_index * CTX_SIZE(xhci->hcc_params)));
 }
 
+static void xhci_init_endpoint_timer(struct xhci_hcd *xhci,
+		struct xhci_virt_ep *ep)
+{
+	init_timer(&ep->stop_cmd_timer);
+	ep->stop_cmd_timer.data = (unsigned long) ep;
+	ep->stop_cmd_timer.function = xhci_stop_endpoint_command_watchdog;
+	ep->xhci = xhci;
+}
+
 /* All the xhci_tds in the ring's TD list should be freed at this point */
 void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
 {
@@ -267,6 +304,12 @@
 		if (dev->eps[i].ring)
 			xhci_ring_free(xhci, dev->eps[i].ring);
 
+	if (dev->ring_cache) {
+		for (i = 0; i < dev->num_rings_cached; i++)
+			xhci_ring_free(xhci, dev->ring_cache[i]);
+		kfree(dev->ring_cache);
+	}
+
 	if (dev->in_ctx)
 		xhci_free_container_ctx(xhci, dev->in_ctx);
 	if (dev->out_ctx)
@@ -309,15 +352,25 @@
 	xhci_dbg(xhci, "Slot %d input ctx = 0x%llx (dma)\n", slot_id,
 			(unsigned long long)dev->in_ctx->dma);
 
-	/* Initialize the cancellation list for each endpoint */
-	for (i = 0; i < 31; i++)
+	/* Initialize the cancellation list and watchdog timers for each ep */
+	for (i = 0; i < 31; i++) {
+		xhci_init_endpoint_timer(xhci, &dev->eps[i]);
 		INIT_LIST_HEAD(&dev->eps[i].cancelled_td_list);
+	}
 
 	/* Allocate endpoint 0 ring */
 	dev->eps[0].ring = xhci_ring_alloc(xhci, 1, true, flags);
 	if (!dev->eps[0].ring)
 		goto fail;
 
+	/* Allocate pointers to the ring cache */
+	dev->ring_cache = kzalloc(
+			sizeof(struct xhci_ring *)*XHCI_MAX_RINGS_CACHED,
+			flags);
+	if (!dev->ring_cache)
+		goto fail;
+	dev->num_rings_cached = 0;
+
 	init_completion(&dev->cmd_completion);
 	INIT_LIST_HEAD(&dev->cmd_list);
 
@@ -544,8 +597,16 @@
 	/* Set up the endpoint ring */
 	virt_dev->eps[ep_index].new_ring =
 		xhci_ring_alloc(xhci, 1, true, mem_flags);
-	if (!virt_dev->eps[ep_index].new_ring)
-		return -ENOMEM;
+	if (!virt_dev->eps[ep_index].new_ring) {
+		/* Attempt to use the ring cache */
+		if (virt_dev->num_rings_cached == 0)
+			return -ENOMEM;
+		virt_dev->eps[ep_index].new_ring =
+			virt_dev->ring_cache[virt_dev->num_rings_cached];
+		virt_dev->ring_cache[virt_dev->num_rings_cached] = NULL;
+		virt_dev->num_rings_cached--;
+		xhci_reinit_cached_ring(xhci, virt_dev->eps[ep_index].new_ring);
+	}
 	ep_ring = virt_dev->eps[ep_index].new_ring;
 	ep_ctx->deq = ep_ring->first_seg->dma | ep_ring->cycle_state;
 
@@ -768,14 +829,17 @@
 
 	command->in_ctx =
 		xhci_alloc_container_ctx(xhci, XHCI_CTX_TYPE_INPUT, mem_flags);
-	if (!command->in_ctx)
+	if (!command->in_ctx) {
+		kfree(command);
 		return NULL;
+	}
 
 	if (allocate_completion) {
 		command->completion =
 			kzalloc(sizeof(struct completion), mem_flags);
 		if (!command->completion) {
 			xhci_free_container_ctx(xhci, command->in_ctx);
+			kfree(command);
 			return NULL;
 		}
 		init_completion(command->completion);
@@ -848,6 +912,163 @@
 	xhci->page_shift = 0;
 }
 
+static int xhci_test_trb_in_td(struct xhci_hcd *xhci,
+		struct xhci_segment *input_seg,
+		union xhci_trb *start_trb,
+		union xhci_trb *end_trb,
+		dma_addr_t input_dma,
+		struct xhci_segment *result_seg,
+		char *test_name, int test_number)
+{
+	unsigned long long start_dma;
+	unsigned long long end_dma;
+	struct xhci_segment *seg;
+
+	start_dma = xhci_trb_virt_to_dma(input_seg, start_trb);
+	end_dma = xhci_trb_virt_to_dma(input_seg, end_trb);
+
+	seg = trb_in_td(input_seg, start_trb, end_trb, input_dma);
+	if (seg != result_seg) {
+		xhci_warn(xhci, "WARN: %s TRB math test %d failed!\n",
+				test_name, test_number);
+		xhci_warn(xhci, "Tested TRB math w/ seg %p and "
+				"input DMA 0x%llx\n",
+				input_seg,
+				(unsigned long long) input_dma);
+		xhci_warn(xhci, "starting TRB %p (0x%llx DMA), "
+				"ending TRB %p (0x%llx DMA)\n",
+				start_trb, start_dma,
+				end_trb, end_dma);
+		xhci_warn(xhci, "Expected seg %p, got seg %p\n",
+				result_seg, seg);
+		return -1;
+	}
+	return 0;
+}
+
+/* TRB math checks for xhci_trb_in_td(), using the command and event rings. */
+static int xhci_check_trb_in_td_math(struct xhci_hcd *xhci, gfp_t mem_flags)
+{
+	struct {
+		dma_addr_t		input_dma;
+		struct xhci_segment	*result_seg;
+	} simple_test_vector [] = {
+		/* A zeroed DMA field should fail */
+		{ 0, NULL },
+		/* One TRB before the ring start should fail */
+		{ xhci->event_ring->first_seg->dma - 16, NULL },
+		/* One byte before the ring start should fail */
+		{ xhci->event_ring->first_seg->dma - 1, NULL },
+		/* Starting TRB should succeed */
+		{ xhci->event_ring->first_seg->dma, xhci->event_ring->first_seg },
+		/* Ending TRB should succeed */
+		{ xhci->event_ring->first_seg->dma + (TRBS_PER_SEGMENT - 1)*16,
+			xhci->event_ring->first_seg },
+		/* One byte after the ring end should fail */
+		{ xhci->event_ring->first_seg->dma + (TRBS_PER_SEGMENT - 1)*16 + 1, NULL },
+		/* One TRB after the ring end should fail */
+		{ xhci->event_ring->first_seg->dma + (TRBS_PER_SEGMENT)*16, NULL },
+		/* An address of all ones should fail */
+		{ (dma_addr_t) (~0), NULL },
+	};
+	struct {
+		struct xhci_segment	*input_seg;
+		union xhci_trb		*start_trb;
+		union xhci_trb		*end_trb;
+		dma_addr_t		input_dma;
+		struct xhci_segment	*result_seg;
+	} complex_test_vector [] = {
+		/* Test feeding a valid DMA address from a different ring */
+		{	.input_seg = xhci->event_ring->first_seg,
+			.start_trb = xhci->event_ring->first_seg->trbs,
+			.end_trb = &xhci->event_ring->first_seg->trbs[TRBS_PER_SEGMENT - 1],
+			.input_dma = xhci->cmd_ring->first_seg->dma,
+			.result_seg = NULL,
+		},
+		/* Test feeding a valid end TRB from a different ring */
+		{	.input_seg = xhci->event_ring->first_seg,
+			.start_trb = xhci->event_ring->first_seg->trbs,
+			.end_trb = &xhci->cmd_ring->first_seg->trbs[TRBS_PER_SEGMENT - 1],
+			.input_dma = xhci->cmd_ring->first_seg->dma,
+			.result_seg = NULL,
+		},
+		/* Test feeding a valid start and end TRB from a different ring */
+		{	.input_seg = xhci->event_ring->first_seg,
+			.start_trb = xhci->cmd_ring->first_seg->trbs,
+			.end_trb = &xhci->cmd_ring->first_seg->trbs[TRBS_PER_SEGMENT - 1],
+			.input_dma = xhci->cmd_ring->first_seg->dma,
+			.result_seg = NULL,
+		},
+		/* TRB in this ring, but after this TD */
+		{	.input_seg = xhci->event_ring->first_seg,
+			.start_trb = &xhci->event_ring->first_seg->trbs[0],
+			.end_trb = &xhci->event_ring->first_seg->trbs[3],
+			.input_dma = xhci->event_ring->first_seg->dma + 4*16,
+			.result_seg = NULL,
+		},
+		/* TRB in this ring, but before this TD */
+		{	.input_seg = xhci->event_ring->first_seg,
+			.start_trb = &xhci->event_ring->first_seg->trbs[3],
+			.end_trb = &xhci->event_ring->first_seg->trbs[6],
+			.input_dma = xhci->event_ring->first_seg->dma + 2*16,
+			.result_seg = NULL,
+		},
+		/* TRB in this ring, but after this wrapped TD */
+		{	.input_seg = xhci->event_ring->first_seg,
+			.start_trb = &xhci->event_ring->first_seg->trbs[TRBS_PER_SEGMENT - 3],
+			.end_trb = &xhci->event_ring->first_seg->trbs[1],
+			.input_dma = xhci->event_ring->first_seg->dma + 2*16,
+			.result_seg = NULL,
+		},
+		/* TRB in this ring, but before this wrapped TD */
+		{	.input_seg = xhci->event_ring->first_seg,
+			.start_trb = &xhci->event_ring->first_seg->trbs[TRBS_PER_SEGMENT - 3],
+			.end_trb = &xhci->event_ring->first_seg->trbs[1],
+			.input_dma = xhci->event_ring->first_seg->dma + (TRBS_PER_SEGMENT - 4)*16,
+			.result_seg = NULL,
+		},
+		/* TRB not in this ring, and we have a wrapped TD */
+		{	.input_seg = xhci->event_ring->first_seg,
+			.start_trb = &xhci->event_ring->first_seg->trbs[TRBS_PER_SEGMENT - 3],
+			.end_trb = &xhci->event_ring->first_seg->trbs[1],
+			.input_dma = xhci->cmd_ring->first_seg->dma + 2*16,
+			.result_seg = NULL,
+		},
+	};
+
+	unsigned int num_tests;
+	int i, ret;
+
+	num_tests = sizeof(simple_test_vector) / sizeof(simple_test_vector[0]);
+	for (i = 0; i < num_tests; i++) {
+		ret = xhci_test_trb_in_td(xhci,
+				xhci->event_ring->first_seg,
+				xhci->event_ring->first_seg->trbs,
+				&xhci->event_ring->first_seg->trbs[TRBS_PER_SEGMENT - 1],
+				simple_test_vector[i].input_dma,
+				simple_test_vector[i].result_seg,
+				"Simple", i);
+		if (ret < 0)
+			return ret;
+	}
+
+	num_tests = sizeof(complex_test_vector) / sizeof(complex_test_vector[0]);
+	for (i = 0; i < num_tests; i++) {
+		ret = xhci_test_trb_in_td(xhci,
+				complex_test_vector[i].input_seg,
+				complex_test_vector[i].start_trb,
+				complex_test_vector[i].end_trb,
+				complex_test_vector[i].input_dma,
+				complex_test_vector[i].result_seg,
+				"Complex", i);
+		if (ret < 0)
+			return ret;
+	}
+	xhci_dbg(xhci, "TRB math tests passed.\n");
+	return 0;
+}
+
+
 int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
 {
 	dma_addr_t	dma;
@@ -951,6 +1172,8 @@
 	xhci->event_ring = xhci_ring_alloc(xhci, ERST_NUM_SEGS, false, flags);
 	if (!xhci->event_ring)
 		goto fail;
+	if (xhci_check_trb_in_td_math(xhci, flags) < 0)
+		goto fail;
 
 	xhci->erst.entries = pci_alloc_consistent(to_pci_dev(dev),
 			sizeof(struct xhci_erst_entry)*ERST_NUM_SEGS, &dma);
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 06595ec..e097008 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -54,6 +54,8 @@
 	struct pci_dev		*pdev = to_pci_dev(hcd->self.controller);
 	int			retval;
 
+	hcd->self.sg_tablesize = TRBS_PER_SEGMENT - 1;
+
 	xhci->cap_regs = hcd->regs;
 	xhci->op_regs = hcd->regs +
 		HC_LENGTH(xhci_readl(xhci, &xhci->cap_regs->hc_capbase));
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 821b7b4..ee7bc7e 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -306,7 +306,7 @@
 	/* Don't ring the doorbell for this endpoint if there are pending
 	 * cancellations because the we don't want to interrupt processing.
 	 */
-	if (!ep->cancels_pending && !(ep_state & SET_DEQ_PENDING)
+	if (!(ep_state & EP_HALT_PENDING) && !(ep_state & SET_DEQ_PENDING)
 			&& !(ep_state & EP_HALTED)) {
 		field = xhci_readl(xhci, db_addr) & DB_MASK;
 		xhci_writel(xhci, field | EPI_TO_DB(ep_index), db_addr);
@@ -475,6 +475,35 @@
 	ep->ep_state |= SET_DEQ_PENDING;
 }
 
+static inline void xhci_stop_watchdog_timer_in_irq(struct xhci_hcd *xhci,
+		struct xhci_virt_ep *ep)
+{
+	ep->ep_state &= ~EP_HALT_PENDING;
+	/* Can't del_timer_sync in interrupt, so we attempt to cancel.  If the
+	 * timer is running on another CPU, we don't decrement stop_cmds_pending
+	 * (since we didn't successfully stop the watchdog timer).
+	 */
+	if (del_timer(&ep->stop_cmd_timer))
+		ep->stop_cmds_pending--;
+}
+
+/* Must be called with xhci->lock held in interrupt context */
+static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci,
+		struct xhci_td *cur_td, int status, char *adjective)
+{
+	struct usb_hcd *hcd = xhci_to_hcd(xhci);
+
+	cur_td->urb->hcpriv = NULL;
+	usb_hcd_unlink_urb_from_ep(hcd, cur_td->urb);
+	xhci_dbg(xhci, "Giveback %s URB %p\n", adjective, cur_td->urb);
+
+	spin_unlock(&xhci->lock);
+	usb_hcd_giveback_urb(hcd, cur_td->urb, status);
+	kfree(cur_td);
+	spin_lock(&xhci->lock);
+	xhci_dbg(xhci, "%s URB given back\n", adjective);
+}
+
 /*
  * When we get a command completion for a Stop Endpoint Command, we need to
  * unlink any cancelled TDs from the ring.  There are two ways to do that:
@@ -497,9 +526,6 @@
 	struct xhci_td *last_unlinked_td;
 
 	struct xhci_dequeue_state deq_state;
-#ifdef CONFIG_USB_HCD_STAT
-	ktime_t stop_time = ktime_get();
-#endif
 
 	memset(&deq_state, 0, sizeof(deq_state));
 	slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]);
@@ -507,8 +533,11 @@
 	ep = &xhci->devs[slot_id]->eps[ep_index];
 	ep_ring = ep->ring;
 
-	if (list_empty(&ep->cancelled_td_list))
+	if (list_empty(&ep->cancelled_td_list)) {
+		xhci_stop_watchdog_timer_in_irq(xhci, ep);
+		ring_ep_doorbell(xhci, slot_id, ep_index);
 		return;
+	}
 
 	/* Fix up the ep ring first, so HW stops executing cancelled TDs.
 	 * We have the xHCI lock, so nothing can modify this list until we drop
@@ -535,9 +564,9 @@
 		 * the cancelled TD list for URB completion later.
 		 */
 		list_del(&cur_td->td_list);
-		ep->cancels_pending--;
 	}
 	last_unlinked_td = cur_td;
+	xhci_stop_watchdog_timer_in_irq(xhci, ep);
 
 	/* If necessary, queue a Set Transfer Ring Dequeue Pointer command */
 	if (deq_state.new_deq_ptr && deq_state.new_deq_seg) {
@@ -561,27 +590,136 @@
 		list_del(&cur_td->cancelled_td_list);
 
 		/* Clean up the cancelled URB */
-#ifdef CONFIG_USB_HCD_STAT
-		hcd_stat_update(xhci->tp_stat, cur_td->urb->actual_length,
-				ktime_sub(stop_time, cur_td->start_time));
-#endif
-		cur_td->urb->hcpriv = NULL;
-		usb_hcd_unlink_urb_from_ep(xhci_to_hcd(xhci), cur_td->urb);
-
-		xhci_dbg(xhci, "Giveback cancelled URB %p\n", cur_td->urb);
-		spin_unlock(&xhci->lock);
 		/* Doesn't matter what we pass for status, since the core will
 		 * just overwrite it (because the URB has been unlinked).
 		 */
-		usb_hcd_giveback_urb(xhci_to_hcd(xhci), cur_td->urb, 0);
-		kfree(cur_td);
+		xhci_giveback_urb_in_irq(xhci, cur_td, 0, "cancelled");
 
-		spin_lock(&xhci->lock);
+		/* Stop processing the cancelled list if the watchdog timer is
+		 * running.
+		 */
+		if (xhci->xhc_state & XHCI_STATE_DYING)
+			return;
 	} while (cur_td != last_unlinked_td);
 
 	/* Return to the event handler with xhci->lock re-acquired */
 }
 
+/* Watchdog timer function for when a stop endpoint command fails to complete.
+ * In this case, we assume the host controller is broken or dying or dead.  The
+ * host may still be completing some other events, so we have to be careful to
+ * let the event ring handler and the URB dequeueing/enqueueing functions know
+ * through xhci->state.
+ *
+ * The timer may also fire if the host takes a very long time to respond to the
+ * command, and the stop endpoint command completion handler cannot delete the
+ * timer before the timer function is called.  Another endpoint cancellation may
+ * sneak in before the timer function can grab the lock, and that may queue
+ * another stop endpoint command and add the timer back.  So we cannot use a
+ * simple flag to say whether there is a pending stop endpoint command for a
+ * particular endpoint.
+ *
+ * Instead we use a combination of that flag and a counter for the number of
+ * pending stop endpoint commands.  If the timer is the tail end of the last
+ * stop endpoint command, and the endpoint's command is still pending, we assume
+ * the host is dying.
+ */
+void xhci_stop_endpoint_command_watchdog(unsigned long arg)
+{
+	struct xhci_hcd *xhci;
+	struct xhci_virt_ep *ep;
+	struct xhci_virt_ep *temp_ep;
+	struct xhci_ring *ring;
+	struct xhci_td *cur_td;
+	int ret, i, j;
+
+	ep = (struct xhci_virt_ep *) arg;
+	xhci = ep->xhci;
+
+	spin_lock(&xhci->lock);
+
+	ep->stop_cmds_pending--;
+	if (xhci->xhc_state & XHCI_STATE_DYING) {
+		xhci_dbg(xhci, "Stop EP timer ran, but another timer marked "
+				"xHCI as DYING, exiting.\n");
+		spin_unlock(&xhci->lock);
+		return;
+	}
+	if (!(ep->stop_cmds_pending == 0 && (ep->ep_state & EP_HALT_PENDING))) {
+		xhci_dbg(xhci, "Stop EP timer ran, but no command pending, "
+				"exiting.\n");
+		spin_unlock(&xhci->lock);
+		return;
+	}
+
+	xhci_warn(xhci, "xHCI host not responding to stop endpoint command.\n");
+	xhci_warn(xhci, "Assuming host is dying, halting host.\n");
+	/* Oops, HC is dead or dying or at least not responding to the stop
+	 * endpoint command.
+	 */
+	xhci->xhc_state |= XHCI_STATE_DYING;
+	/* Disable interrupts from the host controller and start halting it */
+	xhci_quiesce(xhci);
+	spin_unlock(&xhci->lock);
+
+	ret = xhci_halt(xhci);
+
+	spin_lock(&xhci->lock);
+	if (ret < 0) {
+		/* This is bad; the host is not responding to commands and it's
+		 * not allowing itself to be halted.  At least interrupts are
+		 * disabled, so we can set HC_STATE_HALT and notify the
+		 * USB core.  But if we call usb_hc_died(), it will attempt to
+		 * disconnect all device drivers under this host.  Those
+		 * disconnect() methods will wait for all URBs to be unlinked,
+		 * so we must complete them.
+		 */
+		xhci_warn(xhci, "Non-responsive xHCI host is not halting.\n");
+		xhci_warn(xhci, "Completing active URBs anyway.\n");
+		/* We could turn all TDs on the rings to no-ops.  This won't
+		 * help if the host has cached part of the ring, and is slow if
+		 * we want to preserve the cycle bit.  Skip it and hope the host
+		 * doesn't touch the memory.
+		 */
+	}
+	for (i = 0; i < MAX_HC_SLOTS; i++) {
+		if (!xhci->devs[i])
+			continue;
+		for (j = 0; j < 31; j++) {
+			temp_ep = &xhci->devs[i]->eps[j];
+			ring = temp_ep->ring;
+			if (!ring)
+				continue;
+			xhci_dbg(xhci, "Killing URBs for slot ID %u, "
+					"ep index %u\n", i, j);
+			while (!list_empty(&ring->td_list)) {
+				cur_td = list_first_entry(&ring->td_list,
+						struct xhci_td,
+						td_list);
+				list_del(&cur_td->td_list);
+				if (!list_empty(&cur_td->cancelled_td_list))
+					list_del(&cur_td->cancelled_td_list);
+				xhci_giveback_urb_in_irq(xhci, cur_td,
+						-ESHUTDOWN, "killed");
+			}
+			while (!list_empty(&temp_ep->cancelled_td_list)) {
+				cur_td = list_first_entry(
+						&temp_ep->cancelled_td_list,
+						struct xhci_td,
+						cancelled_td_list);
+				list_del(&cur_td->cancelled_td_list);
+				xhci_giveback_urb_in_irq(xhci, cur_td,
+						-ESHUTDOWN, "killed");
+			}
+		}
+	}
+	spin_unlock(&xhci->lock);
+	xhci_to_hcd(xhci)->state = HC_STATE_HALT;
+	xhci_dbg(xhci, "Calling usb_hc_died()\n");
+	usb_hc_died(xhci_to_hcd(xhci));
+	xhci_dbg(xhci, "xHCI host controller is dead.\n");
+}
+
 /*
  * When we get a completion for a Set Transfer Ring Dequeue Pointer command,
  * we need to clear the set deq pending flag in the endpoint ring state, so that
@@ -765,28 +903,32 @@
 				virt_dev->in_ctx);
 		/* Input ctx add_flags are the endpoint index plus one */
 		ep_index = xhci_last_valid_endpoint(ctrl_ctx->add_flags) - 1;
-		ep_ring = xhci->devs[slot_id]->eps[ep_index].ring;
-		if (!ep_ring) {
-			/* This must have been an initial configure endpoint */
-			xhci->devs[slot_id]->cmd_status =
-				GET_COMP_CODE(event->status);
-			complete(&xhci->devs[slot_id]->cmd_completion);
-			break;
-		}
-		ep_state = xhci->devs[slot_id]->eps[ep_index].ep_state;
-		xhci_dbg(xhci, "Completed config ep cmd - last ep index = %d, "
-				"state = %d\n", ep_index, ep_state);
+		/* A usb_set_interface() call directly after clearing a halted
+		 * condition may race on this quirky hardware.
+		 * Not worth worrying about, since this is prototype hardware.
+		 */
 		if (xhci->quirks & XHCI_RESET_EP_QUIRK &&
-				ep_state & EP_HALTED) {
+				ep_index != (unsigned int) -1 &&
+				ctrl_ctx->add_flags - SLOT_FLAG ==
+					ctrl_ctx->drop_flags) {
+			ep_ring = xhci->devs[slot_id]->eps[ep_index].ring;
+			ep_state = xhci->devs[slot_id]->eps[ep_index].ep_state;
+			if (!(ep_state & EP_HALTED))
+				goto bandwidth_change;
+			xhci_dbg(xhci, "Completed config ep cmd - "
+					"last ep index = %d, state = %d\n",
+					ep_index, ep_state);
 			/* Clear our internal halted state and restart ring */
 			xhci->devs[slot_id]->eps[ep_index].ep_state &=
 				~EP_HALTED;
 			ring_ep_doorbell(xhci, slot_id, ep_index);
-		} else {
-			xhci->devs[slot_id]->cmd_status =
-				GET_COMP_CODE(event->status);
-			complete(&xhci->devs[slot_id]->cmd_completion);
+			break;
 		}
+bandwidth_change:
+		xhci_dbg(xhci, "Completed config ep cmd\n");
+		xhci->devs[slot_id]->cmd_status =
+			GET_COMP_CODE(event->status);
+		complete(&xhci->devs[slot_id]->cmd_completion);
 		break;
 	case TRB_TYPE(TRB_EVAL_CONTEXT):
 		virt_dev = xhci->devs[slot_id];
@@ -849,8 +991,7 @@
  * TRB in this TD, this function returns that TRB's segment.  Otherwise it
  * returns 0.
  */
-static struct xhci_segment *trb_in_td(
-		struct xhci_segment *start_seg,
+struct xhci_segment *trb_in_td(struct xhci_segment *start_seg,
 		union xhci_trb	*start_trb,
 		union xhci_trb	*end_trb,
 		dma_addr_t	suspect_dma)
@@ -900,6 +1041,45 @@
 	return 0;
 }
 
+static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci,
+		unsigned int slot_id, unsigned int ep_index,
+		struct xhci_td *td, union xhci_trb *event_trb)
+{
+	struct xhci_virt_ep *ep = &xhci->devs[slot_id]->eps[ep_index];
+	ep->ep_state |= EP_HALTED;
+	ep->stopped_td = td;
+	ep->stopped_trb = event_trb;
+	xhci_queue_reset_ep(xhci, slot_id, ep_index);
+	xhci_cleanup_stalled_ring(xhci, td->urb->dev, ep_index);
+	xhci_ring_cmd_db(xhci);
+}
+
+/* Check if an error has halted the endpoint ring.  The class driver will
+ * cleanup the halt for a non-default control endpoint if we indicate a stall.
+ * However, a babble and other errors also halt the endpoint ring, and the class
+ * driver won't clear the halt in that case, so we need to issue a Set Transfer
+ * Ring Dequeue Pointer command manually.
+ */
+static int xhci_requires_manual_halt_cleanup(struct xhci_hcd *xhci,
+		struct xhci_ep_ctx *ep_ctx,
+		unsigned int trb_comp_code)
+{
+	/* TRB completion codes that may require a manual halt cleanup */
+	if (trb_comp_code == COMP_TX_ERR ||
+			trb_comp_code == COMP_BABBLE ||
+			trb_comp_code == COMP_SPLIT_ERR)
+		/* The 0.96 spec says a babbling control endpoint
+		 * is not halted. The 0.96 spec says it is.  Some HW
+		 * claims to be 0.95 compliant, but it halts the control
+		 * endpoint anyway.  Check if a babble halted the
+		 * endpoint.
+		 */
+		if ((ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_HALTED)
+			return 1;
+
+	return 0;
+}
+
 /*
  * If this function returns an error condition, it means it got a Transfer
  * event with a corrupted Slot ID, Endpoint ID, or TRB DMA address.
@@ -1002,6 +1182,7 @@
 		xhci_warn(xhci, "WARN: TRB error on endpoint\n");
 		status = -EILSEQ;
 		break;
+	case COMP_SPLIT_ERR:
 	case COMP_TX_ERR:
 		xhci_warn(xhci, "WARN: transfer error on endpoint\n");
 		status = -EPROTO;
@@ -1015,6 +1196,16 @@
 		status = -ENOSR;
 		break;
 	default:
+		if (trb_comp_code >= 224 && trb_comp_code <= 255) {
+			/* Vendor defined "informational" completion code,
+			 * treat as not-an-error.
+			 */
+			xhci_dbg(xhci, "Vendor defined info completion code %u\n",
+					trb_comp_code);
+			xhci_dbg(xhci, "Treating code as success.\n");
+			status = 0;
+			break;
+		}
 		xhci_warn(xhci, "ERROR Unknown event condition, HC probably busted\n");
 		urb = NULL;
 		goto cleanup;
@@ -1043,15 +1234,14 @@
 			else
 				status = 0;
 			break;
-		case COMP_BABBLE:
-			/* The 0.96 spec says a babbling control endpoint
-			 * is not halted. The 0.96 spec says it is.  Some HW
-			 * claims to be 0.95 compliant, but it halts the control
-			 * endpoint anyway.  Check if a babble halted the
-			 * endpoint.
-			 */
-			if (ep_ctx->ep_info != EP_STATE_HALTED)
+
+		default:
+			if (!xhci_requires_manual_halt_cleanup(xhci,
+						ep_ctx, trb_comp_code))
 				break;
+			xhci_dbg(xhci, "TRB error code %u, "
+					"halted endpoint index = %u\n",
+					trb_comp_code, ep_index);
 			/* else fall through */
 		case COMP_STALL:
 			/* Did we transfer part of the data (middle) phase? */
@@ -1063,15 +1253,9 @@
 			else
 				td->urb->actual_length = 0;
 
-			ep->stopped_td = td;
-			ep->stopped_trb = event_trb;
-			xhci_queue_reset_ep(xhci, slot_id, ep_index);
-			xhci_cleanup_stalled_ring(xhci, td->urb->dev, ep_index);
-			xhci_ring_cmd_db(xhci);
+			xhci_cleanup_halted_endpoint(xhci,
+					slot_id, ep_index, td, event_trb);
 			goto td_cleanup;
-		default:
-			/* Others already handled above */
-			break;
 		}
 		/*
 		 * Did we transfer any data, despite the errors that might have
@@ -1209,16 +1393,25 @@
 		ep->stopped_td = td;
 		ep->stopped_trb = event_trb;
 	} else {
-		if (trb_comp_code == COMP_STALL ||
-				trb_comp_code == COMP_BABBLE) {
+		if (trb_comp_code == COMP_STALL) {
 			/* The transfer is completed from the driver's
 			 * perspective, but we need to issue a set dequeue
 			 * command for this stalled endpoint to move the dequeue
 			 * pointer past the TD.  We can't do that here because
-			 * the halt condition must be cleared first.
+			 * the halt condition must be cleared first.  Let the
+			 * USB class driver clear the stall later.
 			 */
 			ep->stopped_td = td;
 			ep->stopped_trb = event_trb;
+		} else if (xhci_requires_manual_halt_cleanup(xhci,
+					ep_ctx, trb_comp_code)) {
+			/* Other types of errors halt the endpoint, but the
+			 * class driver doesn't call usb_reset_endpoint() unless
+			 * the error is -EPIPE.  Clear the halted status in the
+			 * xHCI hardware manually.
+			 */
+			xhci_cleanup_halted_endpoint(xhci,
+					slot_id, ep_index, td, event_trb);
 		} else {
 			/* Update ring dequeue pointer */
 			while (ep_ring->dequeue != td->last_trb)
@@ -1249,10 +1442,9 @@
 		}
 		list_del(&td->td_list);
 		/* Was this TD slated to be cancelled but completed anyway? */
-		if (!list_empty(&td->cancelled_td_list)) {
+		if (!list_empty(&td->cancelled_td_list))
 			list_del(&td->cancelled_td_list);
-			ep->cancels_pending--;
-		}
+
 		/* Leave the TD around for the reset endpoint function to use
 		 * (but only if it's not a control endpoint, since we already
 		 * queued the Set TR dequeue pointer command for stalled
@@ -1331,6 +1523,14 @@
 	default:
 		xhci->error_bitmask |= 1 << 3;
 	}
+	/* Any of the above functions may drop and re-acquire the lock, so check
+	 * to make sure a watchdog timer didn't mark the host as non-responsive.
+	 */
+	if (xhci->xhc_state & XHCI_STATE_DYING) {
+		xhci_dbg(xhci, "xHCI host dying, returning from "
+				"event handler.\n");
+		return;
+	}
 
 	if (update_ptrs) {
 		/* Update SW and HC event ring dequeue pointer */
@@ -1555,6 +1755,21 @@
 	return xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index);
 }
 
+/*
+ * The TD size is the number of bytes remaining in the TD (including this TRB),
+ * right shifted by 10.
+ * It must fit in bits 21:17, so it can't be bigger than 31.
+ */
+static u32 xhci_td_remainder(unsigned int remainder)
+{
+	u32 max = (1 << (21 - 17 + 1)) - 1;
+
+	if ((remainder >> 10) >= max)
+		return max << 17;
+	else
+		return (remainder >> 10) << 17;
+}
+
 static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 		struct urb *urb, int slot_id, unsigned int ep_index)
 {
@@ -1612,6 +1827,7 @@
 	do {
 		u32 field = 0;
 		u32 length_field = 0;
+		u32 remainder = 0;
 
 		/* Don't change the cycle bit of the first TRB until later */
 		if (first_trb)
@@ -1641,8 +1857,10 @@
 					(unsigned int) (addr + TRB_MAX_BUFF_SIZE) & ~(TRB_MAX_BUFF_SIZE - 1),
 					(unsigned int) addr + trb_buff_len);
 		}
+		remainder = xhci_td_remainder(urb->transfer_buffer_length -
+				running_total) ;
 		length_field = TRB_LEN(trb_buff_len) |
-			TD_REMAINDER(urb->transfer_buffer_length - running_total) |
+			remainder |
 			TRB_INTR_TARGET(0);
 		queue_trb(xhci, ep_ring, false,
 				lower_32_bits(addr),
@@ -1755,6 +1973,7 @@
 
 	/* Queue the first TRB, even if it's zero-length */
 	do {
+		u32 remainder = 0;
 		field = 0;
 
 		/* Don't change the cycle bit of the first TRB until later */
@@ -1773,8 +1992,10 @@
 			td->last_trb = ep_ring->enqueue;
 			field |= TRB_IOC;
 		}
+		remainder = xhci_td_remainder(urb->transfer_buffer_length -
+				running_total);
 		length_field = TRB_LEN(trb_buff_len) |
-			TD_REMAINDER(urb->transfer_buffer_length - running_total) |
+			remainder |
 			TRB_INTR_TARGET(0);
 		queue_trb(xhci, ep_ring, false,
 				lower_32_bits(addr),
@@ -1862,7 +2083,7 @@
 	/* If there's data, queue data TRBs */
 	field = 0;
 	length_field = TRB_LEN(urb->transfer_buffer_length) |
-		TD_REMAINDER(urb->transfer_buffer_length) |
+		xhci_td_remainder(urb->transfer_buffer_length) |
 		TRB_INTR_TARGET(0);
 	if (urb->transfer_buffer_length > 0) {
 		if (setup->bRequestType & USB_DIR_IN)
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 4b254b6..8778135 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -652,13 +652,17 @@
 	struct xhci_ring		*new_ring;
 	unsigned int			ep_state;
 #define SET_DEQ_PENDING		(1 << 0)
-#define EP_HALTED		(1 << 1)
+#define EP_HALTED		(1 << 1)	/* For stall handling */
+#define EP_HALT_PENDING		(1 << 2)	/* For URB cancellation */
 	/* ----  Related to URB cancellation ---- */
 	struct list_head	cancelled_td_list;
-	unsigned int		cancels_pending;
 	/* The TRB that was last reported in a stopped endpoint ring */
 	union xhci_trb		*stopped_trb;
 	struct xhci_td		*stopped_td;
+	/* Watchdog timer for stop endpoint command to cancel URBs */
+	struct timer_list	stop_cmd_timer;
+	int			stop_cmds_pending;
+	struct xhci_hcd		*xhci;
 };
 
 struct xhci_virt_device {
@@ -673,6 +677,10 @@
 	struct xhci_container_ctx       *out_ctx;
 	/* Used for addressing devices and configuration changes */
 	struct xhci_container_ctx       *in_ctx;
+	/* Rings saved to ensure old alt settings can be re-instated */
+	struct xhci_ring		**ring_cache;
+	int				num_rings_cached;
+#define	XHCI_MAX_RINGS_CACHED	31
 	struct xhci_virt_ep		eps[31];
 	struct completion		cmd_completion;
 	/* Status of the last command issued for this device */
@@ -824,9 +832,6 @@
 /* Normal TRB fields */
 /* transfer_len bitmasks - bits 0:16 */
 #define	TRB_LEN(p)		((p) & 0x1ffff)
-/* TD size - number of bytes remaining in the TD (including this TRB):
- * bits 17 - 21.  Shift the number of bytes by 10. */
-#define TD_REMAINDER(p)		((((p) >> 10) & 0x1f) << 17)
 /* Interrupter Target - which MSI-X vector to target the completion event at */
 #define TRB_INTR_TARGET(p)	(((p) & 0x3ff) << 22)
 #define GET_INTR_TARGET(p)	(((p) >> 22) & 0x3ff)
@@ -1022,6 +1027,8 @@
 #define	ERST_ENTRIES	1
 /* Poll every 60 seconds */
 #define	POLL_TIMEOUT	60
+/* Stop endpoint command timeout (secs) for URB cancellation watchdog timer */
+#define XHCI_STOP_EP_CMD_TIMEOUT	5
 /* XXX: Make these module parameters */
 
 
@@ -1083,6 +1090,21 @@
 	struct timer_list	event_ring_timer;
 	int			zombie;
 #endif
+	/* Host controller watchdog timer structures */
+	unsigned int		xhc_state;
+/* Host controller is dying - not responding to commands. "I'm not dead yet!"
+ *
+ * xHC interrupts have been disabled and a watchdog timer will (or has already)
+ * halt the xHCI host, and complete all URBs with an -ESHUTDOWN code.  Any code
+ * that sees this status (other than the timer that set it) should stop touching
+ * hardware immediately.  Interrupt handlers should return immediately when
+ * they see this status (any time they drop and re-acquire xhci->lock).
+ * xhci_urb_dequeue() should call usb_hcd_check_unlink_urb() and return without
+ * putting the TD on the canceled list, etc.
+ *
+ * There are no reports of xHCI host controllers that display this issue.
+ */
+#define XHCI_STATE_DYING	(1 << 0)
 	/* Statistics */
 	int			noops_submitted;
 	int			noops_handled;
@@ -1223,6 +1245,7 @@
 #endif
 
 /* xHCI host controller glue */
+void xhci_quiesce(struct xhci_hcd *xhci);
 int xhci_halt(struct xhci_hcd *xhci);
 int xhci_reset(struct xhci_hcd *xhci);
 int xhci_init(struct usb_hcd *hcd);
@@ -1246,6 +1269,9 @@
 
 /* xHCI ring, segment, TRB, and TD functions */
 dma_addr_t xhci_trb_virt_to_dma(struct xhci_segment *seg, union xhci_trb *trb);
+struct xhci_segment *trb_in_td(struct xhci_segment *start_seg,
+		union xhci_trb *start_trb, union xhci_trb *end_trb,
+		dma_addr_t suspect_dma);
 void xhci_ring_cmd_db(struct xhci_hcd *xhci);
 void *xhci_setup_one_noop(struct xhci_hcd *xhci);
 void xhci_handle_event(struct xhci_hcd *xhci);
@@ -1278,6 +1304,7 @@
 void xhci_queue_config_ep_quirk(struct xhci_hcd *xhci,
 		unsigned int slot_id, unsigned int ep_index,
 		struct xhci_dequeue_state *deq_state);
+void xhci_stop_endpoint_command_watchdog(unsigned long arg);
 
 /* xHCI roothub code */
 int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex,
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index a9f06d7..3dab0c0 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -213,8 +213,9 @@
 }
 
 static unsigned pattern = 0;
-module_param (pattern, uint, S_IRUGO);
-MODULE_PARM_DESC(pattern, "i/o pattern (0 == zeroes)");
+static unsigned mod_pattern;
+module_param_named(pattern, mod_pattern, uint, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(mod_pattern, "i/o pattern (0 == zeroes)");
 
 static inline void simple_fill_buf (struct urb *urb)
 {
@@ -1567,6 +1568,8 @@
 
 	// FIXME USBDEVFS_CONNECTINFO doesn't say how fast the device is.
 
+	pattern = mod_pattern;
+
 	if (code != USBTEST_REQUEST)
 		return -EOPNOTSUPP;
 
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c
index 10f3205..385ec05 100644
--- a/drivers/usb/mon/mon_bin.c
+++ b/drivers/usb/mon/mon_bin.c
@@ -16,6 +16,7 @@
 #include <linux/compat.h>
 #include <linux/mm.h>
 #include <linux/smp_lock.h>
+#include <linux/scatterlist.h>
 
 #include <asm/uaccess.h>
 
@@ -221,7 +222,7 @@
 /*
  * This is a "chunked memcpy". It does not manipulate any counters.
  */
-static void mon_copy_to_buff(const struct mon_reader_bin *this,
+static unsigned int mon_copy_to_buff(const struct mon_reader_bin *this,
     unsigned int off, const unsigned char *from, unsigned int length)
 {
 	unsigned int step_len;
@@ -246,6 +247,7 @@
 		from += step_len;
 		length -= step_len;
 	}
+	return off;
 }
 
 /*
@@ -394,14 +396,44 @@
 	return 0;
 }
 
-static char mon_bin_get_data(const struct mon_reader_bin *rp,
-    unsigned int offset, struct urb *urb, unsigned int length)
+static unsigned int mon_bin_get_data(const struct mon_reader_bin *rp,
+    unsigned int offset, struct urb *urb, unsigned int length,
+    char *flag)
 {
+	int i;
+	struct scatterlist *sg;
+	unsigned int this_len;
 
-	if (urb->transfer_buffer == NULL)
-		return 'Z';
-	mon_copy_to_buff(rp, offset, urb->transfer_buffer, length);
-	return 0;
+	*flag = 0;
+	if (urb->num_sgs == 0) {
+		if (urb->transfer_buffer == NULL) {
+			*flag = 'Z';
+			return length;
+		}
+		mon_copy_to_buff(rp, offset, urb->transfer_buffer, length);
+		length = 0;
+
+	} else {
+		/* If IOMMU coalescing occurred, we cannot trust sg_page */
+		if (urb->sg->nents != urb->num_sgs) {
+			*flag = 'D';
+			return length;
+		}
+
+		/* Copy up to the first non-addressable segment */
+		for_each_sg(urb->sg->sg, sg, urb->num_sgs, i) {
+			if (length == 0 || PageHighMem(sg_page(sg)))
+				break;
+			this_len = min_t(unsigned int, sg->length, length);
+			offset = mon_copy_to_buff(rp, offset, sg_virt(sg),
+					this_len);
+			length -= this_len;
+		}
+		if (i == 0)
+			*flag = 'D';
+	}
+
+	return length;
 }
 
 static void mon_bin_get_isodesc(const struct mon_reader_bin *rp,
@@ -536,8 +568,9 @@
 	}
 
 	if (length != 0) {
-		ep->flag_data = mon_bin_get_data(rp, offset, urb, length);
-		if (ep->flag_data != 0) {	/* Yes, it's 0x00, not '0' */
+		length = mon_bin_get_data(rp, offset, urb, length,
+				&ep->flag_data);
+		if (length > 0) {
 			delta = (ep->len_cap + PKT_ALIGN-1) & ~(PKT_ALIGN-1);
 			ep->len_cap -= length;
 			delta -= (ep->len_cap + PKT_ALIGN-1) & ~(PKT_ALIGN-1);
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c
index 9f1a922..047568f 100644
--- a/drivers/usb/mon/mon_text.c
+++ b/drivers/usb/mon/mon_text.c
@@ -10,6 +10,7 @@
 #include <linux/time.h>
 #include <linux/mutex.h>
 #include <linux/debugfs.h>
+#include <linux/scatterlist.h>
 #include <asm/uaccess.h>
 
 #include "usb_mon.h"
@@ -137,6 +138,8 @@
 static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
     int len, char ev_type, struct mon_bus *mbus)
 {
+	void *src;
+
 	if (len <= 0)
 		return 'L';
 	if (len >= DATA_MAX)
@@ -150,10 +153,24 @@
 			return '>';
 	}
 
-	if (urb->transfer_buffer == NULL)
-		return 'Z';	/* '0' would be not as pretty. */
+	if (urb->num_sgs == 0) {
+		src = urb->transfer_buffer;
+		if (src == NULL)
+			return 'Z';	/* '0' would be not as pretty. */
+	} else {
+		struct scatterlist *sg = urb->sg->sg;
 
-	memcpy(ep->data, urb->transfer_buffer, len);
+		/* If IOMMU coalescing occurred, we cannot trust sg_page */
+		if (urb->sg->nents != urb->num_sgs ||
+				PageHighMem(sg_page(sg)))
+			return 'D';
+
+		/* For the text interface we copy only the first sg buffer */
+		len = min_t(int, sg->length, len);
+		src = sg_virt(sg);
+	}
+
+	memcpy(ep->data, src, len);
 	return 0;
 }
 
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index b84abd8..d9db864 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -9,10 +9,9 @@
 # (M)HDRC = (Multipoint) Highspeed Dual-Role Controller
 config USB_MUSB_HDRC
 	depends on (USB || USB_GADGET)
-	depends on (ARM || BLACKFIN)
-	select NOP_USB_XCEIV if ARCH_DAVINCI
+	depends on (ARM || (BF54x && !BF544) || (BF52x && !BF522 && !BF523))
+	select NOP_USB_XCEIV if (ARCH_DAVINCI || MACH_OMAP3EVM || BLACKFIN)
 	select TWL4030_USB if MACH_OMAP_3430SDP
-	select NOP_USB_XCEIV if MACH_OMAP3EVM
 	select USB_OTG_UTILS
 	tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)'
 	help
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c
index fcec87e..fe4934d 100644
--- a/drivers/usb/musb/blackfin.c
+++ b/drivers/usb/musb/blackfin.c
@@ -53,13 +53,11 @@
 void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
 {
 	void __iomem *fifo = hw_ep->fifo;
+
+#ifdef CONFIG_BF52x
 	u8 epnum = hw_ep->epnum;
 	u16 dma_reg = 0;
 
-	DBG(4, "%cX ep%d fifo %p count %d buf %p\n",
-			'R', hw_ep->epnum, fifo, len, dst);
-
-#ifdef CONFIG_BF52x
 	invalidate_dcache_range((unsigned int)dst,
 		(unsigned int)(dst + len));
 
@@ -102,6 +100,9 @@
 			len & 0x01 ? (len >> 1) + 1 : len >> 1);
 #endif
 
+	DBG(4, "%cX ep%d fifo %p count %d buf %p\n",
+			'R', hw_ep->epnum, fifo, len, dst);
+
 	dump_fifo_data(dst, len);
 }
 
@@ -225,8 +226,9 @@
 	return 0;
 }
 
-void musb_platform_set_mode(struct musb *musb, u8 musb_mode)
+int musb_platform_set_mode(struct musb *musb, u8 musb_mode)
 {
+	return -EIO;
 }
 
 int __init musb_platform_init(struct musb *musb)
@@ -261,10 +263,6 @@
 		SSYNC();
 	}
 
-	/* TODO
-	 * Set SIC-IVG register
-	 */
-
 	/* Configure PLL oscillator register */
 	bfin_write_USB_PLLOSC_CTRL(0x30a8);
 	SSYNC();
diff --git a/drivers/usb/musb/blackfin.h b/drivers/usb/musb/blackfin.h
index a240c1e..10b7d75 100644
--- a/drivers/usb/musb/blackfin.h
+++ b/drivers/usb/musb/blackfin.h
@@ -14,6 +14,43 @@
  * Blackfin specific definitions
  */
 
+/* Anomalies notes:
+ *
+ *  05000450 - USB DMA Mode 1 Short Packet Data Corruption:
+ *             MUSB driver is designed to transfer buffer of N * maxpacket size
+ *             in DMA mode 1 and leave the rest of the data to the next
+ *             transfer in DMA mode 0, so we never transmit a short packet in
+ *             DMA mode 1.
+ *
+ *  05000463 - This anomaly doesn't affect this driver since it
+ *             never uses L1 or L2 memory as data destination.
+ *
+ *  05000464 - This anomaly doesn't affect this driver since it
+ *             never uses L1 or L2 memory as data source.
+ *
+ *  05000465 - The anomaly can be seen when SCLK is over 100 MHz, and there is
+ *             no way to workaround for bulk endpoints.  Since the wMaxPackSize
+ *             of bulk is less than or equal to 512, while the fifo size of
+ *             endpoint 5, 6, 7 is 1024, the double buffer mode is enabled
+ *             automatically when these endpoints are used for bulk OUT.
+ *
+ *  05000466 - This anomaly doesn't affect this driver since it never mixes
+ *             concurrent DMA and core accesses to the TX endpoint FIFOs.
+ *
+ *  05000467 - The workaround for this anomaly will introduce another
+ *             anomaly - 05000465.
+ */
+
+/* The Mentor USB DMA engine on BF52x (silicon v0.0 and v0.1) seems to be
+ * unstable in host mode.  This may be caused by Anomaly 05000380.  After
+ * digging out the root cause, we will change this number accordingly.
+ * So, need to either use silicon v0.2+ or disable DMA mode in MUSB.
+ */
+#if ANOMALY_05000380 && defined(CONFIG_BF52x) && \
+    defined(CONFIG_USB_MUSB_HDRC) && !defined(CONFIG_MUSB_PIO_ONLY)
+# error "Please use PIO mode in MUSB driver on bf52x chip v0.0 and v0.1"
+#endif
+
 #undef DUMP_FIFO_DATA
 #ifdef DUMP_FIFO_DATA
 static void dump_fifo_data(u8 *buf, u16 len)
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 547e0e3..49f2346 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1319,7 +1319,6 @@
 #endif
 	u8 reg;
 	char *type;
-	u16 hwvers, rev_major, rev_minor;
 	char aInfo[78], aRevision[32], aDate[12];
 	void __iomem	*mbase = musb->mregs;
 	int		status = 0;
@@ -1391,11 +1390,10 @@
 	}
 
 	/* log release info */
-	hwvers = musb_read_hwvers(mbase);
-	rev_major = (hwvers >> 10) & 0x1f;
-	rev_minor = hwvers & 0x3ff;
-	snprintf(aRevision, 32, "%d.%d%s", rev_major,
-		rev_minor, (hwvers & 0x8000) ? "RC" : "");
+	musb->hwvers = musb_read_hwvers(mbase);
+	snprintf(aRevision, 32, "%d.%d%s", MUSB_HWVERS_MAJOR(musb->hwvers),
+		MUSB_HWVERS_MINOR(musb->hwvers),
+		(musb->hwvers & MUSB_HWVERS_RC) ? "RC" : "");
 	printk(KERN_DEBUG "%s: %sHDRC RTL version %s %s\n",
 			musb_driver_name, type, aRevision, aDate);
 
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 6aa5f22..03d5090 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -322,6 +322,14 @@
 	struct clk		*clock;
 	irqreturn_t		(*isr)(int, void *);
 	struct work_struct	irq_work;
+#define MUSB_HWVERS_MAJOR(x)	((x >> 10) & 0x1f)
+#define MUSB_HWVERS_MINOR(x)	(x & 0x3ff)
+#define MUSB_HWVERS_RC		0x8000
+#define MUSB_HWVERS_1300	0x52C
+#define MUSB_HWVERS_1400	0x590
+#define MUSB_HWVERS_1800	0x720
+#define MUSB_HWVERS_2000	0x800
+	u16			hwvers;
 
 /* this hub status bit is reserved by USB 2.0 and not seen by usbcore */
 #define MUSB_PORT_STAT_RESUME	(1 << 31)
diff --git a/drivers/usb/musb/musb_dma.h b/drivers/usb/musb/musb_dma.h
index 0a2c4e3..916065b 100644
--- a/drivers/usb/musb/musb_dma.h
+++ b/drivers/usb/musb/musb_dma.h
@@ -80,6 +80,17 @@
 #define tusb_dma_omap()			0
 #endif
 
+/* Anomaly 05000456 - USB Receive Interrupt Is Not Generated in DMA Mode 1
+ *	Only allow DMA mode 1 to be used when the USB will actually generate the
+ *	interrupts we expect.
+ */
+#ifdef CONFIG_BLACKFIN
+# undef USE_MODE1
+# if !ANOMALY_05000456
+#  define USE_MODE1
+# endif
+#endif
+
 /*
  * DMA channel status ... updated by the dma controller driver whenever that
  * status changes, and protected by the overall controller spinlock.
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 74073f9..c49b9ba 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -429,112 +429,102 @@
 	DBG(4, "<== %s, txcsr %04x\n", musb_ep->end_point.name, csr);
 
 	dma = is_dma_capable() ? musb_ep->dma : NULL;
-	do {
-		/* REVISIT for high bandwidth, MUSB_TXCSR_P_INCOMPTX
-		 * probably rates reporting as a host error
+
+	/*
+	 * REVISIT: for high bandwidth, MUSB_TXCSR_P_INCOMPTX
+	 * probably rates reporting as a host error.
+	 */
+	if (csr & MUSB_TXCSR_P_SENTSTALL) {
+		csr |=	MUSB_TXCSR_P_WZC_BITS;
+		csr &= ~MUSB_TXCSR_P_SENTSTALL;
+		musb_writew(epio, MUSB_TXCSR, csr);
+		return;
+	}
+
+	if (csr & MUSB_TXCSR_P_UNDERRUN) {
+		/* We NAKed, no big deal... little reason to care. */
+		csr |=	 MUSB_TXCSR_P_WZC_BITS;
+		csr &= ~(MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_TXPKTRDY);
+		musb_writew(epio, MUSB_TXCSR, csr);
+		DBG(20, "underrun on ep%d, req %p\n", epnum, request);
+	}
+
+	if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
+		/*
+		 * SHOULD NOT HAPPEN... has with CPPI though, after
+		 * changing SENDSTALL (and other cases); harmless?
 		 */
-		if (csr & MUSB_TXCSR_P_SENTSTALL) {
+		DBG(5, "%s dma still busy?\n", musb_ep->end_point.name);
+		return;
+	}
+
+	if (request) {
+		u8	is_dma = 0;
+
+		if (dma && (csr & MUSB_TXCSR_DMAENAB)) {
+			is_dma = 1;
 			csr |= MUSB_TXCSR_P_WZC_BITS;
-			csr &= ~MUSB_TXCSR_P_SENTSTALL;
+			csr &= ~(MUSB_TXCSR_DMAENAB | MUSB_TXCSR_P_UNDERRUN |
+				 MUSB_TXCSR_TXPKTRDY);
 			musb_writew(epio, MUSB_TXCSR, csr);
-			break;
+			/* Ensure writebuffer is empty. */
+			csr = musb_readw(epio, MUSB_TXCSR);
+			request->actual += musb_ep->dma->actual_len;
+			DBG(4, "TXCSR%d %04x, DMA off, len %zu, req %p\n",
+				epnum, csr, musb_ep->dma->actual_len, request);
 		}
 
-		if (csr & MUSB_TXCSR_P_UNDERRUN) {
-			/* we NAKed, no big deal ... little reason to care */
-			csr |= MUSB_TXCSR_P_WZC_BITS;
-			csr &= ~(MUSB_TXCSR_P_UNDERRUN
-					| MUSB_TXCSR_TXPKTRDY);
-			musb_writew(epio, MUSB_TXCSR, csr);
-			DBG(20, "underrun on ep%d, req %p\n", epnum, request);
-		}
-
-		if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
-			/* SHOULD NOT HAPPEN ... has with cppi though, after
-			 * changing SENDSTALL (and other cases); harmless?
+		if (is_dma || request->actual == request->length) {
+			/*
+			 * First, maybe a terminating short packet. Some DMA
+			 * engines might handle this by themselves.
 			 */
-			DBG(5, "%s dma still busy?\n", musb_ep->end_point.name);
-			break;
-		}
-
-		if (request) {
-			u8	is_dma = 0;
-
-			if (dma && (csr & MUSB_TXCSR_DMAENAB)) {
-				is_dma = 1;
-				csr |= MUSB_TXCSR_P_WZC_BITS;
-				csr &= ~(MUSB_TXCSR_DMAENAB
-						| MUSB_TXCSR_P_UNDERRUN
-						| MUSB_TXCSR_TXPKTRDY);
-				musb_writew(epio, MUSB_TXCSR, csr);
-				/* ensure writebuffer is empty */
-				csr = musb_readw(epio, MUSB_TXCSR);
-				request->actual += musb_ep->dma->actual_len;
-				DBG(4, "TXCSR%d %04x, dma off, "
-						"len %zu, req %p\n",
-					epnum, csr,
-					musb_ep->dma->actual_len,
-					request);
-			}
-
-			if (is_dma || request->actual == request->length) {
-
-				/* First, maybe a terminating short packet.
-				 * Some DMA engines might handle this by
-				 * themselves.
-				 */
-				if ((request->zero
-						&& request->length
-						&& (request->length
-							% musb_ep->packet_sz)
-							== 0)
+			if ((request->zero && request->length
+				&& request->length % musb_ep->packet_sz == 0)
 #ifdef CONFIG_USB_INVENTRA_DMA
-					|| (is_dma &&
-						((!dma->desired_mode) ||
-						    (request->actual &
-						    (musb_ep->packet_sz - 1))))
+				|| (is_dma && (!dma->desired_mode ||
+					(request->actual &
+						(musb_ep->packet_sz - 1))))
 #endif
-				) {
-					/* on dma completion, fifo may not
-					 * be available yet ...
-					 */
-					if (csr & MUSB_TXCSR_TXPKTRDY)
-						break;
-
-					DBG(4, "sending zero pkt\n");
-					musb_writew(epio, MUSB_TXCSR,
-							MUSB_TXCSR_MODE
-							| MUSB_TXCSR_TXPKTRDY);
-					request->zero = 0;
-				}
-
-				/* ... or if not, then complete it */
-				musb_g_giveback(musb_ep, request, 0);
-
-				/* kickstart next transfer if appropriate;
-				 * the packet that just completed might not
-				 * be transmitted for hours or days.
-				 * REVISIT for double buffering...
-				 * FIXME revisit for stalls too...
+			) {
+				/*
+				 * On DMA completion, FIFO may not be
+				 * available yet...
 				 */
-				musb_ep_select(mbase, epnum);
-				csr = musb_readw(epio, MUSB_TXCSR);
-				if (csr & MUSB_TXCSR_FIFONOTEMPTY)
-					break;
-				request = musb_ep->desc
-						? next_request(musb_ep)
-						: NULL;
-				if (!request) {
-					DBG(4, "%s idle now\n",
-						musb_ep->end_point.name);
-					break;
-				}
+				if (csr & MUSB_TXCSR_TXPKTRDY)
+					return;
+
+				DBG(4, "sending zero pkt\n");
+				musb_writew(epio, MUSB_TXCSR, MUSB_TXCSR_MODE
+						| MUSB_TXCSR_TXPKTRDY);
+				request->zero = 0;
 			}
 
-			txstate(musb, to_musb_request(request));
+			/* ... or if not, then complete it. */
+			musb_g_giveback(musb_ep, request, 0);
+
+			/*
+			 * Kickstart next transfer if appropriate;
+			 * the packet that just completed might not
+			 * be transmitted for hours or days.
+			 * REVISIT for double buffering...
+			 * FIXME revisit for stalls too...
+			 */
+			musb_ep_select(mbase, epnum);
+			csr = musb_readw(epio, MUSB_TXCSR);
+			if (csr & MUSB_TXCSR_FIFONOTEMPTY)
+				return;
+
+			if (!musb_ep->desc) {
+				DBG(4, "%s idle now\n",
+					musb_ep->end_point.name);
+				return;
+			} else
+				request = next_request(musb_ep);
 		}
 
-	} while (0);
+		txstate(musb, to_musb_request(request));
+	}
 }
 
 /* ------------------------------------------------------------ */
@@ -966,6 +956,7 @@
 
 	musb_ep->desc = desc;
 	musb_ep->busy = 0;
+	musb_ep->wedged = 0;
 	status = 0;
 
 	pr_debug("%s periph: enabled %s for %s %s, %smaxpacket %d\n",
@@ -1220,7 +1211,7 @@
  *
  * exported to ep0 code
  */
-int musb_gadget_set_halt(struct usb_ep *ep, int value)
+static int musb_gadget_set_halt(struct usb_ep *ep, int value)
 {
 	struct musb_ep		*musb_ep = to_musb_ep(ep);
 	u8			epnum = musb_ep->current_epnum;
@@ -1262,7 +1253,8 @@
 				goto done;
 			}
 		}
-	}
+	} else
+		musb_ep->wedged = 0;
 
 	/* set/clear the stall and toggle bits */
 	DBG(2, "%s: %s stall\n", ep->name, value ? "set" : "clear");
@@ -1301,6 +1293,21 @@
 	return status;
 }
 
+/*
+ * Sets the halt feature with the clear requests ignored
+ */
+static int musb_gadget_set_wedge(struct usb_ep *ep)
+{
+	struct musb_ep		*musb_ep = to_musb_ep(ep);
+
+	if (!ep)
+		return -EINVAL;
+
+	musb_ep->wedged = 1;
+
+	return usb_ep_set_halt(ep);
+}
+
 static int musb_gadget_fifo_status(struct usb_ep *ep)
 {
 	struct musb_ep		*musb_ep = to_musb_ep(ep);
@@ -1371,6 +1378,7 @@
 	.queue		= musb_gadget_queue,
 	.dequeue	= musb_gadget_dequeue,
 	.set_halt	= musb_gadget_set_halt,
+	.set_wedge	= musb_gadget_set_wedge,
 	.fifo_status	= musb_gadget_fifo_status,
 	.fifo_flush	= musb_gadget_fifo_flush
 };
diff --git a/drivers/usb/musb/musb_gadget.h b/drivers/usb/musb/musb_gadget.h
index 59502da..c8b1403 100644
--- a/drivers/usb/musb/musb_gadget.h
+++ b/drivers/usb/musb/musb_gadget.h
@@ -75,6 +75,8 @@
 	/* later things are modified based on usage */
 	struct list_head		req_list;
 
+	u8				wedged;
+
 	/* true if lock must be dropped but req_list may not be advanced */
 	u8				busy;
 };
@@ -103,6 +105,4 @@
 
 extern void musb_g_giveback(struct musb_ep *, struct usb_request *, int);
 
-extern int musb_gadget_set_halt(struct usb_ep *ep, int value);
-
 #endif		/* __MUSB_GADGET_H */
diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c
index 522efb3..8fba3f1 100644
--- a/drivers/usb/musb/musb_gadget_ep0.c
+++ b/drivers/usb/musb/musb_gadget_ep0.c
@@ -199,7 +199,6 @@
 static void musb_g_ep0_giveback(struct musb *musb, struct usb_request *req)
 {
 	musb_g_giveback(&musb->endpoints[0].ep_in, req, 0);
-	musb->ep0_state = MUSB_EP0_STAGE_SETUP;
 }
 
 /*
@@ -258,30 +257,53 @@
 			case USB_RECIP_INTERFACE:
 				break;
 			case USB_RECIP_ENDPOINT:{
-				const u8 num = ctrlrequest->wIndex & 0x0f;
-				struct musb_ep *musb_ep;
+				const u8		epnum =
+					ctrlrequest->wIndex & 0x0f;
+				struct musb_ep		*musb_ep;
+				struct musb_hw_ep	*ep;
+				void __iomem		*regs;
+				int			is_in;
+				u16			csr;
 
-				if (num == 0
-						|| num >= MUSB_C_NUM_EPS
-						|| ctrlrequest->wValue
-							!= USB_ENDPOINT_HALT)
+				if (epnum == 0 || epnum >= MUSB_C_NUM_EPS ||
+				    ctrlrequest->wValue != USB_ENDPOINT_HALT)
 					break;
 
-				if (ctrlrequest->wIndex & USB_DIR_IN)
-					musb_ep = &musb->endpoints[num].ep_in;
+				ep = musb->endpoints + epnum;
+				regs = ep->regs;
+				is_in = ctrlrequest->wIndex & USB_DIR_IN;
+				if (is_in)
+					musb_ep = &ep->ep_in;
 				else
-					musb_ep = &musb->endpoints[num].ep_out;
+					musb_ep = &ep->ep_out;
 				if (!musb_ep->desc)
 					break;
 
-				/* REVISIT do it directly, no locking games */
-				spin_unlock(&musb->lock);
-				musb_gadget_set_halt(&musb_ep->end_point, 0);
-				spin_lock(&musb->lock);
+				handled = 1;
+				/* Ignore request if endpoint is wedged */
+				if (musb_ep->wedged)
+					break;
+
+				musb_ep_select(mbase, epnum);
+				if (is_in) {
+					csr  = musb_readw(regs, MUSB_TXCSR);
+					csr |= MUSB_TXCSR_CLRDATATOG |
+					       MUSB_TXCSR_P_WZC_BITS;
+					csr &= ~(MUSB_TXCSR_P_SENDSTALL |
+						 MUSB_TXCSR_P_SENTSTALL |
+						 MUSB_TXCSR_TXPKTRDY);
+					musb_writew(regs, MUSB_TXCSR, csr);
+				} else {
+					csr  = musb_readw(regs, MUSB_RXCSR);
+					csr |= MUSB_RXCSR_CLRDATATOG |
+					       MUSB_RXCSR_P_WZC_BITS;
+					csr &= ~(MUSB_RXCSR_P_SENDSTALL |
+						 MUSB_RXCSR_P_SENTSTALL);
+					musb_writew(regs, MUSB_RXCSR, csr);
+				}
 
 				/* select ep0 again */
 				musb_ep_select(mbase, 0);
-				handled = 1;
 				} break;
 			default:
 				/* class, vendor, etc ... delegate */
@@ -374,10 +396,8 @@
 				int			is_in;
 				u16			csr;
 
-				if (epnum == 0
-						|| epnum >= MUSB_C_NUM_EPS
-						|| ctrlrequest->wValue
-							!= USB_ENDPOINT_HALT)
+				if (epnum == 0 || epnum >= MUSB_C_NUM_EPS ||
+				    ctrlrequest->wValue	!= USB_ENDPOINT_HALT)
 					break;
 
 				ep = musb->endpoints + epnum;
@@ -392,24 +412,20 @@
 
 				musb_ep_select(mbase, epnum);
 				if (is_in) {
-					csr = musb_readw(regs,
-							MUSB_TXCSR);
+					csr = musb_readw(regs, MUSB_TXCSR);
 					if (csr & MUSB_TXCSR_FIFONOTEMPTY)
 						csr |= MUSB_TXCSR_FLUSHFIFO;
 					csr |= MUSB_TXCSR_P_SENDSTALL
 						| MUSB_TXCSR_CLRDATATOG
 						| MUSB_TXCSR_P_WZC_BITS;
-					musb_writew(regs, MUSB_TXCSR,
-							csr);
+					musb_writew(regs, MUSB_TXCSR, csr);
 				} else {
-					csr = musb_readw(regs,
-							MUSB_RXCSR);
+					csr = musb_readw(regs, MUSB_RXCSR);
 					csr |= MUSB_RXCSR_P_SENDSTALL
 						| MUSB_RXCSR_FLUSHFIFO
 						| MUSB_RXCSR_CLRDATATOG
 						| MUSB_RXCSR_P_WZC_BITS;
-					musb_writew(regs, MUSB_RXCSR,
-							csr);
+					musb_writew(regs, MUSB_RXCSR, csr);
 				}
 
 				/* select ep0 again */
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index e3ab40a..74c4c36 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -1642,18 +1642,18 @@
 			c = musb->dma_controller;
 
 			if (usb_pipeisoc(pipe)) {
-				int status = 0;
+				int d_status = 0;
 				struct usb_iso_packet_descriptor *d;
 
 				d = urb->iso_frame_desc + qh->iso_idx;
 
 				if (iso_err) {
-					status = -EILSEQ;
+					d_status = -EILSEQ;
 					urb->error_count++;
 				}
 				if (rx_count > d->length) {
-					if (status == 0) {
-						status = -EOVERFLOW;
+					if (d_status == 0) {
+						d_status = -EOVERFLOW;
 						urb->error_count++;
 					}
 					DBG(2, "** OVERFLOW %d into %d\n",\
@@ -1662,7 +1662,7 @@
 					length = d->length;
 				} else
 					length = rx_count;
-				d->status = status;
+				d->status = d_status;
 				buf = urb->transfer_dma + d->offset;
 			} else {
 				length = rx_count;
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h
index cc1d71b..473a94e 100644
--- a/drivers/usb/musb/musb_regs.h
+++ b/drivers/usb/musb/musb_regs.h
@@ -465,9 +465,9 @@
 	return 0;
 }
 
-static inline u16 musb_read_target_reg_base(u8 i, void __iomem *mbase)
+static inline void __iomem *musb_read_target_reg_base(u8 i, void __iomem *mbase)
 {
-	return 0;
+	return NULL;
 }
 
 static inline void musb_write_rxfunaddr(void __iomem *ep_target_regs,
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c
index 5e83f96..a237550 100644
--- a/drivers/usb/musb/musbhsdma.c
+++ b/drivers/usb/musb/musbhsdma.c
@@ -259,6 +259,11 @@
 	if (!int_hsdma)
 		goto done;
 
+#ifdef CONFIG_BLACKFIN
+	/* Clear DMA interrupt flags */
+	musb_writeb(mbase, MUSB_HSDMA_INTR, int_hsdma);
+#endif
+
 	for (bchannel = 0; bchannel < MUSB_HSDMA_CHANNELS; bchannel++) {
 		if (int_hsdma & (1 << bchannel)) {
 			musb_channel = (struct musb_dma_channel *)
@@ -280,7 +285,7 @@
 				channel->actual_len = addr
 					- musb_channel->start_addr;
 
-				DBG(2, "ch %p, 0x%x -> 0x%x (%d / %d) %s\n",
+				DBG(2, "ch %p, 0x%x -> 0x%x (%zu / %d) %s\n",
 					channel, musb_channel->start_addr,
 					addr, channel->actual_len,
 					musb_channel->len,
@@ -324,11 +329,6 @@
 		}
 	}
 
-#ifdef CONFIG_BLACKFIN
-	/* Clear DMA interrup flags */
-	musb_writeb(mbase, MUSB_HSDMA_INTR, int_hsdma);
-#endif
-
 	retval = IRQ_HANDLED;
 done:
 	spin_unlock_irqrestore(&musb->lock, flags);
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index 6761d20..83beeac 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -315,7 +315,7 @@
 	musb_platform_suspend(musb);
 
 	clk_put(musb->clock);
-	musb->clock = 0;
+	musb->clock = NULL;
 
 	return 0;
 }
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig
index aa884d0..de56b3d 100644
--- a/drivers/usb/otg/Kconfig
+++ b/drivers/usb/otg/Kconfig
@@ -41,6 +41,15 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called isp1301_omap.
 
+config USB_ULPI
+	bool "Generic ULPI Transceiver Driver"
+	depends on ARM
+	help
+	  Enable this to support ULPI connected USB OTG transceivers which
+	  are likely found on embedded boards.
+
+	  The only chip currently supported is NXP's ISP1504
+
 config TWL4030_USB
 	tristate "TWL4030 USB Transceiver Driver"
 	depends on TWL4030_CORE && REGULATOR_TWL4030
diff --git a/drivers/usb/otg/Makefile b/drivers/usb/otg/Makefile
index 2081678..aeb49a8 100644
--- a/drivers/usb/otg/Makefile
+++ b/drivers/usb/otg/Makefile
@@ -10,6 +10,7 @@
 obj-$(CONFIG_ISP1301_OMAP)	+= isp1301_omap.o
 obj-$(CONFIG_TWL4030_USB)	+= twl4030-usb.o
 obj-$(CONFIG_NOP_USB_XCEIV)	+= nop-usb-xceiv.o
+obj-$(CONFIG_USB_ULPI)		+= ulpi.o
 
 ccflags-$(CONFIG_USB_DEBUG)	+= -DDEBUG
 ccflags-$(CONFIG_USB_GADGET_DEBUG) += -DDEBUG
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c
index 9e3e7a5..bd9883f 100644
--- a/drivers/usb/otg/twl4030-usb.c
+++ b/drivers/usb/otg/twl4030-usb.c
@@ -598,12 +598,12 @@
 		 * USB_LINK_VBUS state.  musb_hdrc won't care until it
 		 * starts to handle softconnect right.
 		 */
-		twl4030charger_usb_en(status == USB_LINK_VBUS);
-
 		if (status == USB_LINK_NONE)
 			twl4030_phy_suspend(twl, 0);
 		else
 			twl4030_phy_resume(twl);
+
+		twl4030charger_usb_en(status == USB_LINK_VBUS);
 	}
 	sysfs_notify(&twl->dev->kobj, NULL, "vbus");
 
diff --git a/drivers/usb/otg/ulpi.c b/drivers/usb/otg/ulpi.c
new file mode 100644
index 0000000..8965274
--- /dev/null
+++ b/drivers/usb/otg/ulpi.c
@@ -0,0 +1,136 @@
+/*
+ * Generic ULPI USB transceiver support
+ *
+ * Copyright (C) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * Based on sources from
+ *
+ *   Sascha Hauer <s.hauer@pengutronix.de>
+ *   Freescale Semiconductors
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/usb.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+
+/* ULPI register addresses */
+#define ULPI_VID_LOW         0x00    /* Vendor ID low */
+#define ULPI_VID_HIGH        0x01    /* Vendor ID high */
+#define ULPI_PID_LOW         0x02    /* Product ID low */
+#define ULPI_PID_HIGH        0x03    /* Product ID high */
+#define ULPI_ITFCTL          0x07    /* Interface Control */
+#define ULPI_OTGCTL          0x0A    /* OTG Control */
+
+/* add to above register address to access Set/Clear functions */
+#define ULPI_REG_SET         0x01
+#define ULPI_REG_CLEAR       0x02
+
+/* ULPI OTG Control Register bits */
+#define ID_PULL_UP              (1 << 0)        /* enable ID Pull Up */
+#define DP_PULL_DOWN            (1 << 1)        /* enable DP Pull Down */
+#define DM_PULL_DOWN            (1 << 2)        /* enable DM Pull Down */
+#define DISCHRG_VBUS            (1 << 3)        /* Discharge Vbus */
+#define CHRG_VBUS               (1 << 4)        /* Charge Vbus */
+#define DRV_VBUS                (1 << 5)        /* Drive Vbus */
+#define DRV_VBUS_EXT            (1 << 6)        /* Drive Vbus external */
+#define USE_EXT_VBUS_IND        (1 << 7)        /* Use ext. Vbus indicator */
+
+#define ULPI_ID(vendor, product) (((vendor) << 16) | (product))
+
+#define TR_FLAG(flags, a, b)	(((flags) & a) ? b : 0)
+
+/* ULPI hardcoded IDs, used for probing */
+static unsigned int ulpi_ids[] = {
+	ULPI_ID(0x04cc, 0x1504),	/* NXP ISP1504 */
+};
+
+static int ulpi_set_flags(struct otg_transceiver *otg)
+{
+	unsigned int flags = 0;
+
+	if (otg->flags & USB_OTG_PULLUP_ID)
+		flags |= ID_PULL_UP;
+
+	if (otg->flags & USB_OTG_PULLDOWN_DM)
+		flags |= DM_PULL_DOWN;
+
+	if (otg->flags & USB_OTG_PULLDOWN_DP)
+		flags |= DP_PULL_DOWN;
+
+	if (otg->flags & USB_OTG_EXT_VBUS_INDICATOR)
+		flags |= USE_EXT_VBUS_IND;
+
+	return otg_io_write(otg, flags, ULPI_OTGCTL + ULPI_REG_SET);
+}
+
+static int ulpi_init(struct otg_transceiver *otg)
+{
+	int i, vid, pid;
+
+	vid = (otg_io_read(otg, ULPI_VID_HIGH) << 8) |
+	       otg_io_read(otg, ULPI_VID_LOW);
+	pid = (otg_io_read(otg, ULPI_PID_HIGH) << 8) |
+	       otg_io_read(otg, ULPI_PID_LOW);
+
+	pr_info("ULPI transceiver vendor/product ID 0x%04x/0x%04x\n", vid, pid);
+
+	for (i = 0; i < ARRAY_SIZE(ulpi_ids); i++)
+		if (ulpi_ids[i] == ULPI_ID(vid, pid))
+			return ulpi_set_flags(otg);
+
+	pr_err("ULPI ID does not match any known transceiver.\n");
+	return -ENODEV;
+}
+
+static int ulpi_set_vbus(struct otg_transceiver *otg, bool on)
+{
+	unsigned int flags = otg_io_read(otg, ULPI_OTGCTL);
+
+	flags &= ~(DRV_VBUS | DRV_VBUS_EXT);
+
+	if (on) {
+		if (otg->flags & USB_OTG_DRV_VBUS)
+			flags |= DRV_VBUS;
+
+		if (otg->flags & USB_OTG_DRV_VBUS_EXT)
+			flags |= DRV_VBUS_EXT;
+	}
+
+	return otg_io_write(otg, flags, ULPI_OTGCTL + ULPI_REG_SET);
+}
+
+struct otg_transceiver *
+otg_ulpi_create(struct otg_io_access_ops *ops,
+		unsigned int flags)
+{
+	struct otg_transceiver *otg;
+
+	otg = kzalloc(sizeof(*otg), GFP_KERNEL);
+	if (!otg)
+		return NULL;
+
+	otg->label	= "ULPI";
+	otg->flags	= flags;
+	otg->io_ops	= ops;
+	otg->init	= ulpi_init;
+	otg->set_vbus	= ulpi_set_vbus;
+
+	return otg;
+}
+EXPORT_SYMBOL_GPL(otg_ulpi_create);
+
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c
index 131e61a..a9c2dec 100644
--- a/drivers/usb/serial/ark3116.c
+++ b/drivers/usb/serial/ark3116.c
@@ -1,4 +1,6 @@
 /*
+ * Copyright (C) 2009 by Bart Hartgers (bart.hartgers+ark3116@gmail.com)
+ * Original version:
  * Copyright (C) 2006
  *   Simon Schulz (ark3116_driver <at> auctionant.de)
  *
@@ -6,10 +8,13 @@
  * - implements a driver for the arkmicro ark3116 chipset (vendor=0x6547,
  *   productid=0x0232) (used in a datacable called KQ-U8A)
  *
- * - based on code by krisfx -> thanks !!
- *   (see http://www.linuxquestions.org/questions/showthread.php?p=2184457#post2184457)
+ * Supports full modem status lines, break, hardware flow control. Does not
+ * support software flow control, since I do not know how to enable it in hw.
  *
- *  - based on logs created by usbsnoopy
+ * This driver is a essentially new implementation. I initially dug
+ * into the old ark3116.c driver and suddenly realized the ark3116 is
+ * a 16450 with a USB interface glued to it. See comments at the
+ * bottom of this file.
  *
  * 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
@@ -19,15 +24,31 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/ioctl.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 #include <linux/serial.h>
+#include <linux/serial_reg.h>
 #include <linux/uaccess.h>
-
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
 
 static int debug;
+/*
+ * Version information
+ */
+
+#define DRIVER_VERSION "v0.5"
+#define DRIVER_AUTHOR "Bart Hartgers <bart.hartgers+ark3116@gmail.com>"
+#define DRIVER_DESC "USB ARK3116 serial/IrDA driver"
+#define DRIVER_DEV_DESC "ARK3116 RS232/IrDA"
+#define DRIVER_NAME "ark3116"
+
+/* usb timeout of 1 second */
+#define ARK_TIMEOUT (1*HZ)
 
 static struct usb_device_id id_table [] = {
 	{ USB_DEVICE(0x6547, 0x0232) },
@@ -45,118 +66,152 @@
 	return 0;
 }
 
-static inline void ARK3116_SND(struct usb_serial *serial, int seq,
-			       __u8 request, __u8 requesttype,
-			       __u16 value, __u16 index)
+struct ark3116_private {
+	wait_queue_head_t       delta_msr_wait;
+	struct async_icount	icount;
+	int			irda;	/* 1 for irda device */
+
+	/* protects hw register updates */
+	struct mutex		hw_lock;
+
+	int			quot;	/* baudrate divisor */
+	__u32			lcr;	/* line control register value */
+	__u32			hcr;	/* handshake control register (0x8)
+					 * value */
+	__u32			mcr;	/* modem contol register value */
+
+	/* protects the status values below */
+	spinlock_t		status_lock;
+	__u32			msr;	/* modem status register value */
+	__u32			lsr;	/* line status register value */
+};
+
+static int ark3116_write_reg(struct usb_serial *serial,
+			     unsigned reg, __u8 val)
 {
 	int result;
+	 /* 0xfe 0x40 are magic values taken from original driver */
 	result = usb_control_msg(serial->dev,
 				 usb_sndctrlpipe(serial->dev, 0),
-				 request, requesttype, value, index,
-				 NULL, 0x00, 1000);
-	dbg("%03d > ok", seq);
+				 0xfe, 0x40, val, reg,
+				 NULL, 0, ARK_TIMEOUT);
+	return result;
 }
 
-static inline void ARK3116_RCV(struct usb_serial *serial, int seq,
-			       __u8 request, __u8 requesttype,
-			       __u16 value, __u16 index, __u8 expected,
-			       char *buf)
+static int ark3116_read_reg(struct usb_serial *serial,
+			    unsigned reg, unsigned char *buf)
 {
 	int result;
+	/* 0xfe 0xc0 are magic values taken from original driver */
 	result = usb_control_msg(serial->dev,
 				 usb_rcvctrlpipe(serial->dev, 0),
-				 request, requesttype, value, index,
-				 buf, 0x0000001, 1000);
-	if (result)
-		dbg("%03d < %d bytes [0x%02X]", seq, result,
-		    ((unsigned char *)buf)[0]);
+				 0xfe, 0xc0, 0, reg,
+				 buf, 1, ARK_TIMEOUT);
+	if (result < 0)
+		return result;
 	else
-		dbg("%03d < 0 bytes", seq);
+		return buf[0];
 }
 
-static inline void ARK3116_RCV_QUIET(struct usb_serial *serial,
-				     __u8 request, __u8 requesttype,
-				     __u16 value, __u16 index, char *buf)
+static inline int calc_divisor(int bps)
 {
-	usb_control_msg(serial->dev,
-			usb_rcvctrlpipe(serial->dev, 0),
-			request, requesttype, value, index,
-			buf, 0x0000001, 1000);
+	/* Original ark3116 made some exceptions in rounding here
+	 * because windows did the same. Assume that is not really
+	 * necessary.
+	 * Crystal is 12MHz, probably because of USB, but we divide by 4?
+	 */
+	return (12000000 + 2*bps) / (4*bps);
 }
 
 static int ark3116_attach(struct usb_serial *serial)
 {
-	char *buf;
+	struct usb_serial_port *port = serial->port[0];
+	struct ark3116_private *priv;
 
-	buf = kmalloc(1, GFP_KERNEL);
-	if (!buf) {
-		dbg("error kmalloc -> out of mem?");
+	/* make sure we have our end-points */
+	if ((serial->num_bulk_in == 0) ||
+	    (serial->num_bulk_out == 0) ||
+	    (serial->num_interrupt_in == 0)) {
+		dev_err(&serial->dev->dev,
+			"%s - missing endpoint - "
+			"bulk in: %d, bulk out: %d, int in %d\n",
+			KBUILD_MODNAME,
+			serial->num_bulk_in,
+			serial->num_bulk_out,
+			serial->num_interrupt_in);
+		return -EINVAL;
+	}
+
+	priv = kzalloc(sizeof(struct ark3116_private),
+		       GFP_KERNEL);
+	if (!priv)
 		return -ENOMEM;
+
+	init_waitqueue_head(&priv->delta_msr_wait);
+	mutex_init(&priv->hw_lock);
+	spin_lock_init(&priv->status_lock);
+
+	priv->irda = is_irda(serial);
+
+	usb_set_serial_port_data(port, priv);
+
+	/* setup the hardware */
+	ark3116_write_reg(serial, UART_IER, 0);
+	/* disable DMA */
+	ark3116_write_reg(serial, UART_FCR, 0);
+	/* handshake control */
+	priv->hcr = 0;
+	ark3116_write_reg(serial, 0x8     , 0);
+	/* modem control */
+	priv->mcr = 0;
+	ark3116_write_reg(serial, UART_MCR, 0);
+
+	if (!(priv->irda)) {
+		ark3116_write_reg(serial, 0xb , 0);
+	} else {
+		ark3116_write_reg(serial, 0xb , 1);
+		ark3116_write_reg(serial, 0xc , 0);
+		ark3116_write_reg(serial, 0xd , 0x41);
+		ark3116_write_reg(serial, 0xa , 1);
 	}
 
-	if (is_irda(serial))
-		dbg("IrDA mode");
+	/* setup baudrate */
+	ark3116_write_reg(serial, UART_LCR, UART_LCR_DLAB);
 
-	/* 3 */
-	ARK3116_SND(serial, 3, 0xFE, 0x40, 0x0008, 0x0002);
-	ARK3116_SND(serial, 4, 0xFE, 0x40, 0x0008, 0x0001);
-	ARK3116_SND(serial, 5, 0xFE, 0x40, 0x0000, 0x0008);
-	ARK3116_SND(serial, 6, 0xFE, 0x40, is_irda(serial) ? 0x0001 : 0x0000,
-		    0x000B);
+	/* setup for 9600 8N1 */
+	priv->quot = calc_divisor(9600);
+	ark3116_write_reg(serial, UART_DLL, priv->quot & 0xff);
+	ark3116_write_reg(serial, UART_DLM, (priv->quot>>8) & 0xff);
 
-	if (is_irda(serial)) {
-		ARK3116_SND(serial, 1001, 0xFE, 0x40, 0x0000, 0x000C);
-		ARK3116_SND(serial, 1002, 0xFE, 0x40, 0x0041, 0x000D);
-		ARK3116_SND(serial, 1003, 0xFE, 0x40, 0x0001, 0x000A);
-	}
+	priv->lcr = UART_LCR_WLEN8;
+	ark3116_write_reg(serial, UART_LCR, UART_LCR_WLEN8);
 
-	/* <-- seq7 */
-	ARK3116_RCV(serial,  7, 0xFE, 0xC0, 0x0000, 0x0003, 0x00, buf);
-	ARK3116_SND(serial,  8, 0xFE, 0x40, 0x0080, 0x0003);
-	ARK3116_SND(serial,  9, 0xFE, 0x40, 0x001A, 0x0000);
-	ARK3116_SND(serial, 10, 0xFE, 0x40, 0x0000, 0x0001);
-	ARK3116_SND(serial, 11, 0xFE, 0x40, 0x0000, 0x0003);
+	ark3116_write_reg(serial, 0xe, 0);
 
-	/* <-- seq12 */
-	ARK3116_RCV(serial, 12, 0xFE, 0xC0, 0x0000, 0x0004, 0x00, buf);
-	ARK3116_SND(serial, 13, 0xFE, 0x40, 0x0000, 0x0004);
+	if (priv->irda)
+		ark3116_write_reg(serial, 0x9, 0);
 
-	/* 14 */
-	ARK3116_RCV(serial, 14, 0xFE, 0xC0, 0x0000, 0x0004, 0x00, buf);
-	ARK3116_SND(serial, 15, 0xFE, 0x40, 0x0000, 0x0004);
-
-	/* 16 */
-	ARK3116_RCV(serial, 16, 0xFE, 0xC0, 0x0000, 0x0004, 0x00, buf);
-	/* --> seq17 */
-	ARK3116_SND(serial, 17, 0xFE, 0x40, 0x0001, 0x0004);
-
-	/* <-- seq18 */
-	ARK3116_RCV(serial, 18, 0xFE, 0xC0, 0x0000, 0x0004, 0x01, buf);
-
-	/* --> seq19 */
-	ARK3116_SND(serial, 19, 0xFE, 0x40, 0x0003, 0x0004);
-
-	/* <-- seq20 */
-	/* seems like serial port status info (RTS, CTS, ...) */
-	/* returns modem control line status?! */
-	ARK3116_RCV(serial, 20, 0xFE, 0xC0, 0x0000, 0x0006, 0xFF, buf);
-
-	/* set 9600 baud & do some init?! */
-	ARK3116_SND(serial, 147, 0xFE, 0x40, 0x0083, 0x0003);
-	ARK3116_SND(serial, 148, 0xFE, 0x40, 0x0038, 0x0000);
-	ARK3116_SND(serial, 149, 0xFE, 0x40, 0x0001, 0x0001);
-	if (is_irda(serial))
-		ARK3116_SND(serial, 1004, 0xFE, 0x40, 0x0000, 0x0009);
-	ARK3116_SND(serial, 150, 0xFE, 0x40, 0x0003, 0x0003);
-	ARK3116_RCV(serial, 151, 0xFE, 0xC0, 0x0000, 0x0004, 0x03, buf);
-	ARK3116_SND(serial, 152, 0xFE, 0x40, 0x0000, 0x0003);
-	ARK3116_RCV(serial, 153, 0xFE, 0xC0, 0x0000, 0x0003, 0x00, buf);
-	ARK3116_SND(serial, 154, 0xFE, 0x40, 0x0003, 0x0003);
-
-	kfree(buf);
+	dev_info(&serial->dev->dev,
+		"%s using %s mode\n",
+		KBUILD_MODNAME,
+		priv->irda ? "IrDA" : "RS232");
 	return 0;
 }
 
+static void ark3116_release(struct usb_serial *serial)
+{
+	struct usb_serial_port *port = serial->port[0];
+	struct ark3116_private *priv = usb_get_serial_port_data(port);
+
+	/* device is closed, so URBs and DMA should be down */
+
+	usb_set_serial_port_data(port, NULL);
+
+	mutex_destroy(&priv->hw_lock);
+
+	kfree(priv);
+}
+
 static void ark3116_init_termios(struct tty_struct *tty)
 {
 	struct ktermios *termios = tty->termios;
@@ -172,200 +227,189 @@
 				struct ktermios *old_termios)
 {
 	struct usb_serial *serial = port->serial;
+	struct ark3116_private *priv = usb_get_serial_port_data(port);
 	struct ktermios *termios = tty->termios;
 	unsigned int cflag = termios->c_cflag;
-	int baud;
-	int ark3116_baud;
-	char *buf;
-	char config;
+	int bps = tty_get_baud_rate(tty);
+	int quot;
+	__u8 lcr, hcr, eval;
 
-	config = 0;
-
-	dbg("%s - port %d", __func__, port->number);
-
-
-	cflag = termios->c_cflag;
-	termios->c_cflag &= ~(CMSPAR|CRTSCTS);
-
-	buf = kmalloc(1, GFP_KERNEL);
-	if (!buf) {
-		dbg("error kmalloc");
-		*termios = *old_termios;
-		return;
-	}
-
-	/* set data bit count (8/7/6/5) */
-	if (cflag & CSIZE) {
-		switch (cflag & CSIZE) {
-		case CS5:
-			config |= 0x00;
-			dbg("setting CS5");
-			break;
-		case CS6:
-			config |= 0x01;
-			dbg("setting CS6");
-			break;
-		case CS7:
-			config |= 0x02;
-			dbg("setting CS7");
-			break;
-		default:
-			dbg("CSIZE was set but not CS5-CS8, using CS8!");
-			/* fall through */
-		case CS8:
-			config |= 0x03;
-			dbg("setting CS8");
-			break;
-		}
-	}
-
-	/* set parity (NONE/EVEN/ODD) */
-	if (cflag & PARENB) {
-		if (cflag & PARODD) {
-			config |= 0x08;
-			dbg("setting parity to ODD");
-		} else {
-			config |= 0x18;
-			dbg("setting parity to EVEN");
-		}
-	} else {
-		dbg("setting parity to NONE");
-	}
-
-	/* set stop bit (1/2) */
-	if (cflag & CSTOPB) {
-		config |= 0x04;
-		dbg("setting 2 stop bits");
-	} else {
-		dbg("setting 1 stop bit");
-	}
-
-	/* set baudrate */
-	baud = tty_get_baud_rate(tty);
-
-	switch (baud) {
-	case 75:
-	case 150:
-	case 300:
-	case 600:
-	case 1200:
-	case 1800:
-	case 2400:
-	case 4800:
-	case 9600:
-	case 19200:
-	case 38400:
-	case 57600:
-	case 115200:
-	case 230400:
-	case 460800:
-		/* Report the resulting rate back to the caller */
-		tty_encode_baud_rate(tty, baud, baud);
+	/* set data bit count */
+	switch (cflag & CSIZE) {
+	case CS5:
+		lcr = UART_LCR_WLEN5;
 		break;
-	/* set 9600 as default (if given baudrate is invalid for example) */
+	case CS6:
+		lcr = UART_LCR_WLEN6;
+		break;
+	case CS7:
+		lcr = UART_LCR_WLEN7;
+		break;
 	default:
-		tty_encode_baud_rate(tty, 9600, 9600);
+	case CS8:
+		lcr = UART_LCR_WLEN8;
+		break;
+	}
+	if (cflag & CSTOPB)
+		lcr |= UART_LCR_STOP;
+	if (cflag & PARENB)
+		lcr |= UART_LCR_PARITY;
+	if (!(cflag & PARODD))
+		lcr |= UART_LCR_EPAR;
+#ifdef CMSPAR
+	if (cflag & CMSPAR)
+		lcr |= UART_LCR_SPAR;
+#endif
+	/* handshake control */
+	hcr = (cflag & CRTSCTS) ? 0x03 : 0x00;
+
+	/* calc baudrate */
+	dbg("%s - setting bps to %d", __func__, bps);
+	eval = 0;
+	switch (bps) {
 	case 0:
-		baud = 9600;
+		quot = calc_divisor(9600);
+		break;
+	default:
+		if ((bps < 75) || (bps > 3000000))
+			bps = 9600;
+		quot = calc_divisor(bps);
+		break;
+	case 460800:
+		eval = 1;
+		quot = calc_divisor(bps);
+		break;
+	case 921600:
+		eval = 2;
+		quot = calc_divisor(bps);
+		break;
 	}
 
-	/*
-	 * found by try'n'error, be careful, maybe there are other options
-	 * for multiplicator etc! (3.5 for example)
-	 */
-	if (baud == 460800)
-		/* strange, for 460800 the formula is wrong
-		 * if using round() then 9600baud is wrong) */
-		ark3116_baud = 7;
-	else
-		ark3116_baud = 3000000 / baud;
+	/* Update state: synchronize */
+	mutex_lock(&priv->hw_lock);
 
-	/* ? */
-	ARK3116_RCV(serial, 0, 0xFE, 0xC0, 0x0000, 0x0003, 0x03, buf);
+	/* keep old LCR_SBC bit */
+	lcr |= (priv->lcr & UART_LCR_SBC);
 
-	/* offset = buf[0]; */
-	/* offset = 0x03; */
-	/* dbg("using 0x%04X as target for 0x0003:", 0x0080 + offset); */
+	dbg("%s - setting hcr:0x%02x,lcr:0x%02x,quot:%d",
+	    __func__, hcr, lcr, quot);
 
-	/* set baudrate */
-	dbg("setting baudrate to %d (->reg=%d)", baud, ark3116_baud);
-	ARK3116_SND(serial, 147, 0xFE, 0x40, 0x0083, 0x0003);
-	ARK3116_SND(serial, 148, 0xFE, 0x40,
-			    (ark3116_baud & 0x00FF), 0x0000);
-	ARK3116_SND(serial, 149, 0xFE, 0x40,
-			    (ark3116_baud & 0xFF00) >> 8, 0x0001);
-	ARK3116_SND(serial, 150, 0xFE, 0x40, 0x0003, 0x0003);
+	/* handshake control */
+	if (priv->hcr != hcr) {
+		priv->hcr = hcr;
+		ark3116_write_reg(serial, 0x8, hcr);
+	}
 
-	/* ? */
-	ARK3116_RCV(serial, 151, 0xFE, 0xC0, 0x0000, 0x0004, 0x03, buf);
-	ARK3116_SND(serial, 152, 0xFE, 0x40, 0x0000, 0x0003);
+	/* baudrate */
+	if (priv->quot != quot) {
+		priv->quot = quot;
+		priv->lcr = lcr; /* need to write lcr anyway */
 
-	/* set data bit count, stop bit count & parity: */
-	dbg("updating bit count, stop bit or parity (cfg=0x%02X)", config);
-	ARK3116_RCV(serial, 153, 0xFE, 0xC0, 0x0000, 0x0003, 0x00, buf);
-	ARK3116_SND(serial, 154, 0xFE, 0x40, config, 0x0003);
+		/* disable DMA since transmit/receive is
+		 * shadowed by UART_DLL
+		 */
+		ark3116_write_reg(serial, UART_FCR, 0);
 
-	if (cflag & CRTSCTS)
-		dbg("CRTSCTS not supported by chipset?!");
+		ark3116_write_reg(serial, UART_LCR,
+				  lcr|UART_LCR_DLAB);
+		ark3116_write_reg(serial, UART_DLL, quot & 0xff);
+		ark3116_write_reg(serial, UART_DLM, (quot>>8) & 0xff);
 
-	/* TEST ARK3116_SND(154, 0xFE, 0x40, 0xFFFF, 0x0006); */
+		/* restore lcr */
+		ark3116_write_reg(serial, UART_LCR, lcr);
+		/* magic baudrate thingy: not sure what it does,
+		 * but windows does this as well.
+		 */
+		ark3116_write_reg(serial, 0xe, eval);
 
-	kfree(buf);
+		/* enable DMA */
+		ark3116_write_reg(serial, UART_FCR, UART_FCR_DMA_SELECT);
+	} else if (priv->lcr != lcr) {
+		priv->lcr = lcr;
+		ark3116_write_reg(serial, UART_LCR, lcr);
+	}
 
-	return;
+	mutex_unlock(&priv->hw_lock);
+
+	/* check for software flow control */
+	if (I_IXOFF(tty) || I_IXON(tty)) {
+		dev_warn(&serial->dev->dev,
+			 "%s: don't know how to do software flow control\n",
+			 KBUILD_MODNAME);
+	}
+
+	/* Don't rewrite B0 */
+	if (tty_termios_baud_rate(termios))
+		tty_termios_encode_baud_rate(termios, bps, bps);
+}
+
+static void ark3116_close(struct usb_serial_port *port)
+{
+	struct usb_serial *serial = port->serial;
+
+	if (serial->dev) {
+		/* disable DMA */
+		ark3116_write_reg(serial, UART_FCR, 0);
+
+		/* deactivate interrupts */
+		ark3116_write_reg(serial, UART_IER, 0);
+
+		/* shutdown any bulk reads that might be going on */
+		if (serial->num_bulk_out)
+			usb_kill_urb(port->write_urb);
+		if (serial->num_bulk_in)
+			usb_kill_urb(port->read_urb);
+		if (serial->num_interrupt_in)
+			usb_kill_urb(port->interrupt_in_urb);
+	}
 }
 
 static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
-	struct ktermios tmp_termios;
+	struct ark3116_private *priv = usb_get_serial_port_data(port);
 	struct usb_serial *serial = port->serial;
-	char *buf;
-	int result = 0;
-
-	dbg("%s - port %d", __func__, port->number);
+	unsigned char *buf;
+	int result;
 
 	buf = kmalloc(1, GFP_KERNEL);
-	if (!buf) {
-		dbg("error kmalloc -> out of mem?");
+	if (buf == NULL)
 		return -ENOMEM;
-	}
 
 	result = usb_serial_generic_open(tty, port);
-	if (result)
+	if (result) {
+		dbg("%s - usb_serial_generic_open failed: %d",
+		    __func__, result);
 		goto err_out;
+	}
 
-	/* open */
-	ARK3116_RCV(serial, 111, 0xFE, 0xC0, 0x0000, 0x0003, 0x02, buf);
-
-	ARK3116_SND(serial, 112, 0xFE, 0x40, 0x0082, 0x0003);
-	ARK3116_SND(serial, 113, 0xFE, 0x40, 0x001A, 0x0000);
-	ARK3116_SND(serial, 114, 0xFE, 0x40, 0x0000, 0x0001);
-	ARK3116_SND(serial, 115, 0xFE, 0x40, 0x0002, 0x0003);
-
-	ARK3116_RCV(serial, 116, 0xFE, 0xC0, 0x0000, 0x0004, 0x03, buf);
-	ARK3116_SND(serial, 117, 0xFE, 0x40, 0x0002, 0x0004);
-
-	ARK3116_RCV(serial, 118, 0xFE, 0xC0, 0x0000, 0x0004, 0x02, buf);
-	ARK3116_SND(serial, 119, 0xFE, 0x40, 0x0000, 0x0004);
-
-	ARK3116_RCV(serial, 120, 0xFE, 0xC0, 0x0000, 0x0004, 0x00, buf);
-
-	ARK3116_SND(serial, 121, 0xFE, 0x40, 0x0001, 0x0004);
-
-	ARK3116_RCV(serial, 122, 0xFE, 0xC0, 0x0000, 0x0004, 0x01, buf);
-
-	ARK3116_SND(serial, 123, 0xFE, 0x40, 0x0003, 0x0004);
-
-	/* returns different values (control lines?!) */
-	ARK3116_RCV(serial, 124, 0xFE, 0xC0, 0x0000, 0x0006, 0xFF, buf);
-
-	/* initialise termios */
+	/* setup termios */
 	if (tty)
-		ark3116_set_termios(tty, port, &tmp_termios);
+		ark3116_set_termios(tty, port, NULL);
+
+	/* remove any data still left: also clears error state */
+	ark3116_read_reg(serial, UART_RX, buf);
+
+	/* read modem status */
+	priv->msr = ark3116_read_reg(serial, UART_MSR, buf);
+	/* read line status */
+	priv->lsr = ark3116_read_reg(serial, UART_LSR, buf);
+
+	result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
+	if (result) {
+		dev_err(&port->dev, "submit irq_in urb failed %d\n",
+			result);
+		ark3116_close(port);
+		goto err_out;
+	}
+
+	/* activate interrupts */
+	ark3116_write_reg(port->serial, UART_IER, UART_IER_MSI|UART_IER_RLSI);
+
+	/* enable DMA */
+	ark3116_write_reg(port->serial, UART_FCR, UART_FCR_DMA_SELECT);
 
 err_out:
 	kfree(buf);
-
 	return result;
 }
 
@@ -373,6 +417,7 @@
 			 unsigned int cmd, unsigned long arg)
 {
 	struct usb_serial_port *port = tty->driver_data;
+	struct ark3116_private *priv = usb_get_serial_port_data(port);
 	struct serial_struct serstruct;
 	void __user *user_arg = (void __user *)arg;
 
@@ -394,9 +439,48 @@
 		if (copy_from_user(&serstruct, user_arg, sizeof(serstruct)))
 			return -EFAULT;
 		return 0;
-	default:
-		dbg("%s cmd 0x%04x not supported", __func__, cmd);
+	case TIOCMIWAIT:
+		for (;;) {
+			struct async_icount prev = priv->icount;
+			interruptible_sleep_on(&priv->delta_msr_wait);
+			/* see if a signal did it */
+			if (signal_pending(current))
+				return -ERESTARTSYS;
+			if ((prev.rng == priv->icount.rng) &&
+			    (prev.dsr == priv->icount.dsr) &&
+			    (prev.dcd == priv->icount.dcd) &&
+			    (prev.cts == priv->icount.cts))
+				return -EIO;
+			if ((arg & TIOCM_RNG &&
+			     (prev.rng != priv->icount.rng)) ||
+			    (arg & TIOCM_DSR &&
+			     (prev.dsr != priv->icount.dsr)) ||
+			    (arg & TIOCM_CD  &&
+			     (prev.dcd != priv->icount.dcd)) ||
+			    (arg & TIOCM_CTS &&
+			     (prev.cts != priv->icount.cts)))
+				return 0;
+		}
 		break;
+	case TIOCGICOUNT: {
+		struct serial_icounter_struct icount;
+		struct async_icount cnow = priv->icount;
+		memset(&icount, 0, sizeof(icount));
+		icount.cts = cnow.cts;
+		icount.dsr = cnow.dsr;
+		icount.rng = cnow.rng;
+		icount.dcd = cnow.dcd;
+		icount.rx = cnow.rx;
+		icount.tx = cnow.tx;
+		icount.frame = cnow.frame;
+		icount.overrun = cnow.overrun;
+		icount.parity = cnow.parity;
+		icount.brk = cnow.brk;
+		icount.buf_overrun = cnow.buf_overrun;
+		if (copy_to_user(user_arg, &icount, sizeof(icount)))
+			return -EFAULT;
+		return 0;
+	}
 	}
 
 	return -ENOIOCTLCMD;
@@ -405,32 +489,273 @@
 static int ark3116_tiocmget(struct tty_struct *tty, struct file *file)
 {
 	struct usb_serial_port *port = tty->driver_data;
-	struct usb_serial *serial = port->serial;
-	char *buf;
-	char temp;
+	struct ark3116_private *priv = usb_get_serial_port_data(port);
+	__u32 status;
+	__u32 ctrl;
+	unsigned long flags;
 
-	/* seems like serial port status info (RTS, CTS, ...) is stored
-	 * in reg(?) 0x0006
-	 * pcb connection point 11 = GND -> sets bit4 of response
-	 * pcb connection point  7 = GND -> sets bit6 of response
+	mutex_lock(&priv->hw_lock);
+	ctrl = priv->mcr;
+	mutex_unlock(&priv->hw_lock);
+
+	spin_lock_irqsave(&priv->status_lock, flags);
+	status = priv->msr;
+	spin_unlock_irqrestore(&priv->status_lock, flags);
+
+	return  (status & UART_MSR_DSR  ? TIOCM_DSR  : 0) |
+		(status & UART_MSR_CTS  ? TIOCM_CTS  : 0) |
+		(status & UART_MSR_RI   ? TIOCM_RI   : 0) |
+		(status & UART_MSR_DCD  ? TIOCM_CD   : 0) |
+		(ctrl   & UART_MCR_DTR  ? TIOCM_DTR  : 0) |
+		(ctrl   & UART_MCR_RTS  ? TIOCM_RTS  : 0) |
+		(ctrl   & UART_MCR_OUT1 ? TIOCM_OUT1 : 0) |
+		(ctrl   & UART_MCR_OUT2 ? TIOCM_OUT2 : 0);
+}
+
+static int ark3116_tiocmset(struct tty_struct *tty, struct file *file,
+			unsigned set, unsigned clr)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	struct ark3116_private *priv = usb_get_serial_port_data(port);
+
+	/* we need to take the mutex here, to make sure that the value
+	 * in priv->mcr is actually the one that is in the hardware
 	 */
 
-	buf = kmalloc(1, GFP_KERNEL);
-	if (!buf) {
-		dbg("error kmalloc");
-		return -ENOMEM;
+	mutex_lock(&priv->hw_lock);
+
+	if (set & TIOCM_RTS)
+		priv->mcr |= UART_MCR_RTS;
+	if (set & TIOCM_DTR)
+		priv->mcr |= UART_MCR_DTR;
+	if (set & TIOCM_OUT1)
+		priv->mcr |= UART_MCR_OUT1;
+	if (set & TIOCM_OUT2)
+		priv->mcr |= UART_MCR_OUT2;
+	if (clr & TIOCM_RTS)
+		priv->mcr &= ~UART_MCR_RTS;
+	if (clr & TIOCM_DTR)
+		priv->mcr &= ~UART_MCR_DTR;
+	if (clr & TIOCM_OUT1)
+		priv->mcr &= ~UART_MCR_OUT1;
+	if (clr & TIOCM_OUT2)
+		priv->mcr &= ~UART_MCR_OUT2;
+
+	ark3116_write_reg(port->serial, UART_MCR, priv->mcr);
+
+	mutex_unlock(&priv->hw_lock);
+
+	return 0;
+}
+
+static void ark3116_break_ctl(struct tty_struct *tty, int break_state)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	struct ark3116_private *priv = usb_get_serial_port_data(port);
+
+	/* LCR is also used for other things: protect access */
+	mutex_lock(&priv->hw_lock);
+
+	if (break_state)
+		priv->lcr |= UART_LCR_SBC;
+	else
+		priv->lcr &= ~UART_LCR_SBC;
+
+	ark3116_write_reg(port->serial, UART_LCR, priv->lcr);
+
+	mutex_unlock(&priv->hw_lock);
+}
+
+static void ark3116_update_msr(struct usb_serial_port *port, __u8 msr)
+{
+	struct ark3116_private *priv = usb_get_serial_port_data(port);
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->status_lock, flags);
+	priv->msr = msr;
+	spin_unlock_irqrestore(&priv->status_lock, flags);
+
+	if (msr & UART_MSR_ANY_DELTA) {
+		/* update input line counters */
+		if (msr & UART_MSR_DCTS)
+			priv->icount.cts++;
+		if (msr & UART_MSR_DDSR)
+			priv->icount.dsr++;
+		if (msr & UART_MSR_DDCD)
+			priv->icount.dcd++;
+		if (msr & UART_MSR_TERI)
+			priv->icount.rng++;
+		wake_up_interruptible(&priv->delta_msr_wait);
+	}
+}
+
+static void ark3116_update_lsr(struct usb_serial_port *port, __u8 lsr)
+{
+	struct ark3116_private *priv = usb_get_serial_port_data(port);
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->status_lock, flags);
+	/* combine bits */
+	priv->lsr |= lsr;
+	spin_unlock_irqrestore(&priv->status_lock, flags);
+
+	if (lsr&UART_LSR_BRK_ERROR_BITS) {
+		if (lsr & UART_LSR_BI)
+			priv->icount.brk++;
+		if (lsr & UART_LSR_FE)
+			priv->icount.frame++;
+		if (lsr & UART_LSR_PE)
+			priv->icount.parity++;
+		if (lsr & UART_LSR_OE)
+			priv->icount.overrun++;
+	}
+}
+
+static void ark3116_read_int_callback(struct urb *urb)
+{
+	struct usb_serial_port *port = urb->context;
+	int status = urb->status;
+	const __u8 *data = urb->transfer_buffer;
+	int result;
+
+	switch (status) {
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+		/* this urb is terminated, clean up */
+		dbg("%s - urb shutting down with status: %d",
+		    __func__, status);
+		return;
+	default:
+		dbg("%s - nonzero urb status received: %d",
+		    __func__, status);
+		break;
+	case 0: /* success */
+		/* discovered this by trail and error... */
+		if ((urb->actual_length == 4) && (data[0] == 0xe8)) {
+			const __u8 id = data[1]&UART_IIR_ID;
+			dbg("%s: iir=%02x", __func__, data[1]);
+			if (id == UART_IIR_MSI) {
+				dbg("%s: msr=%02x", __func__, data[3]);
+				ark3116_update_msr(port, data[3]);
+				break;
+			} else if (id == UART_IIR_RLSI) {
+				dbg("%s: lsr=%02x", __func__, data[2]);
+				ark3116_update_lsr(port, data[2]);
+				break;
+			}
+		}
+		/*
+		 * Not sure what this data meant...
+		 */
+		usb_serial_debug_data(debug, &port->dev,
+				      __func__,
+				      urb->actual_length,
+				      urb->transfer_buffer);
+		break;
 	}
 
-	/* read register */
-	ARK3116_RCV_QUIET(serial, 0xFE, 0xC0, 0x0000, 0x0006, buf);
-	temp = buf[0];
-	kfree(buf);
+	result = usb_submit_urb(urb, GFP_ATOMIC);
+	if (result)
+		dev_err(&urb->dev->dev,
+			"%s - Error %d submitting interrupt urb\n",
+			__func__, result);
+}
 
-	/* i do not really know if bit4=CTS and bit6=DSR... just a
-	 * quick guess!
-	 */
-	return (temp & (1<<4) ? TIOCM_CTS : 0)
-	       | (temp & (1<<6) ? TIOCM_DSR : 0);
+
+/* Data comes in via the bulk (data) URB, erors/interrupts via the int URB.
+ * This means that we cannot be sure which data byte has an associated error
+ * condition, so we report an error for all data in the next bulk read.
+ *
+ * Actually, there might even be a window between the bulk data leaving the
+ * ark and reading/resetting the lsr in the read_bulk_callback where an
+ * interrupt for the next data block could come in.
+ * Without somekind of ordering on the ark, we would have to report the
+ * error for the next block of data as well...
+ * For now, let's pretend this can't happen.
+ */
+
+static void send_to_tty(struct tty_struct *tty,
+			const unsigned char *chars,
+			size_t size, char flag)
+{
+	if (size == 0)
+		return;
+	if (flag == TTY_NORMAL) {
+		tty_insert_flip_string(tty, chars, size);
+	} else {
+		int i;
+		for (i = 0; i < size; ++i)
+			tty_insert_flip_char(tty, chars[i], flag);
+	}
+}
+
+static void ark3116_read_bulk_callback(struct urb *urb)
+{
+	struct usb_serial_port *port =  urb->context;
+	struct ark3116_private *priv = usb_get_serial_port_data(port);
+	const __u8 *data = urb->transfer_buffer;
+	int status = urb->status;
+	struct tty_struct *tty;
+	unsigned long flags;
+	int result;
+	char flag;
+	__u32 lsr;
+
+	switch (status) {
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+		/* this urb is terminated, clean up */
+		dbg("%s - urb shutting down with status: %d",
+		    __func__, status);
+		return;
+	default:
+		dbg("%s - nonzero urb status received: %d",
+		    __func__, status);
+		break;
+	case 0: /* success */
+
+		spin_lock_irqsave(&priv->status_lock, flags);
+		lsr = priv->lsr;
+		/* clear error bits */
+		priv->lsr &= ~UART_LSR_BRK_ERROR_BITS;
+		spin_unlock_irqrestore(&priv->status_lock, flags);
+
+		if (unlikely(lsr & UART_LSR_BI))
+			flag = TTY_BREAK;
+		else if (unlikely(lsr & UART_LSR_PE))
+			flag = TTY_PARITY;
+		else if (unlikely(lsr & UART_LSR_FE))
+			flag = TTY_FRAME;
+		else
+			flag = TTY_NORMAL;
+
+		tty = tty_port_tty_get(&port->port);
+		if (tty) {
+			tty_buffer_request_room(tty, urb->actual_length + 1);
+			/* overrun is special, not associated with a char */
+			if (unlikely(lsr & UART_LSR_OE))
+				tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+			send_to_tty(tty, data, urb->actual_length, flag);
+			tty_flip_buffer_push(tty);
+			tty_kref_put(tty);
+		}
+
+		/* Throttle the device if requested by tty */
+		spin_lock_irqsave(&port->lock, flags);
+		port->throttled = port->throttle_req;
+		if (port->throttled) {
+			spin_unlock_irqrestore(&port->lock, flags);
+			return;
+		} else
+			spin_unlock_irqrestore(&port->lock, flags);
+	}
+	/* Continue reading from device */
+	result = usb_submit_urb(urb, GFP_ATOMIC);
+	if (result)
+		dev_err(&urb->dev->dev, "%s - failed resubmitting"
+			" read urb, error %d\n", __func__, result);
 }
 
 static struct usb_driver ark3116_driver = {
@@ -450,11 +775,17 @@
 	.usb_driver =		&ark3116_driver,
 	.num_ports =		1,
 	.attach =		ark3116_attach,
+	.release =		ark3116_release,
 	.set_termios =		ark3116_set_termios,
 	.init_termios =		ark3116_init_termios,
 	.ioctl =		ark3116_ioctl,
 	.tiocmget =		ark3116_tiocmget,
+	.tiocmset =		ark3116_tiocmset,
 	.open =			ark3116_open,
+	.close =		ark3116_close,
+	.break_ctl = 		ark3116_break_ctl,
+	.read_int_callback = 	ark3116_read_int_callback,
+	.read_bulk_callback =	ark3116_read_bulk_callback,
 };
 
 static int __init ark3116_init(void)
@@ -465,7 +796,12 @@
 	if (retval)
 		return retval;
 	retval = usb_register(&ark3116_driver);
-	if (retval)
+	if (retval == 0) {
+		printk(KERN_INFO "%s:"
+		       DRIVER_VERSION ":"
+		       DRIVER_DESC "\n",
+		       KBUILD_MODNAME);
+	} else
 		usb_serial_deregister(&ark3116_device);
 	return retval;
 }
@@ -480,6 +816,109 @@
 module_exit(ark3116_exit);
 MODULE_LICENSE("GPL");
 
-module_param(debug, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Debug enabled or not");
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
 
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Enable debug");
+
+/*
+ * The following describes what I learned from studying the old
+ * ark3116.c driver, disassembling the windows driver, and some lucky
+ * guesses. Since I do not have any datasheet or other
+ * documentation, inaccuracies are almost guaranteed.
+ *
+ * Some specs for the ARK3116 can be found here:
+ * http://web.archive.org/web/20060318000438/
+ *   www.arkmicro.com/en/products/view.php?id=10
+ * On that page, 2 GPIO pins are mentioned: I assume these are the
+ * OUT1 and OUT2 pins of the UART, so I added support for those
+ * through the MCR. Since the pins are not available on my hardware,
+ * I could not verify this.
+ * Also, it states there is "on-chip hardware flow control". I have
+ * discovered how to enable that. Unfortunately, I do not know how to
+ * enable XON/XOFF (software) flow control, which would need support
+ * from the chip as well to work. Because of the wording on the web
+ * page there is a real possibility the chip simply does not support
+ * software flow control.
+ *
+ * I got my ark3116 as part of a mobile phone adapter cable. On the
+ * PCB, the following numbered contacts are present:
+ *
+ *  1:- +5V
+ *  2:o DTR
+ *  3:i RX
+ *  4:i DCD
+ *  5:o RTS
+ *  6:o TX
+ *  7:i RI
+ *  8:i DSR
+ * 10:- 0V
+ * 11:i CTS
+ *
+ * On my chip, all signals seem to be 3.3V, but 5V tolerant. But that
+ * may be different for the one you have ;-).
+ *
+ * The windows driver limits the registers to 0-F, so I assume there
+ * are actually 16 present on the device.
+ *
+ * On an UART interrupt, 4 bytes of data come in on the interrupt
+ * endpoint. The bytes are 0xe8 IIR LSR MSR.
+ *
+ * The baudrate seems to be generated from the 12MHz crystal, using
+ * 4-times subsampling. So quot=12e6/(4*baud). Also see description
+ * of register E.
+ *
+ * Registers 0-7:
+ * These seem to be the same as for a regular 16450. The FCR is set
+ * to UART_FCR_DMA_SELECT (0x8), I guess to enable transfers between
+ * the UART and the USB bridge/DMA engine.
+ *
+ * Register 8:
+ * By trial and error, I found out that bit 0 enables hardware CTS,
+ * stopping TX when CTS is +5V. Bit 1 does the same for RTS, making
+ * RTS +5V when the 3116 cannot transfer the data to the USB bus
+ * (verified by disabling the reading URB). Note that as far as I can
+ * tell, the windows driver does NOT use this, so there might be some
+ * hardware bug or something.
+ *
+ * According to a patch provided here
+ * (http://lkml.org/lkml/2009/7/26/56), the ARK3116 can also be used
+ * as an IrDA dongle. Since I do not have such a thing, I could not
+ * investigate that aspect. However, I can speculate ;-).
+ *
+ * - IrDA encodes data differently than RS232. Most likely, one of
+ *   the bits in registers 9..E enables the IR ENDEC (encoder/decoder).
+ * - Depending on the IR transceiver, the input and output need to be
+ *   inverted, so there are probably bits for that as well.
+ * - IrDA is half-duplex, so there should be a bit for selecting that.
+ *
+ * This still leaves at least two registers unaccounted for. Perhaps
+ * The chip can do XON/XOFF or CRC in HW?
+ *
+ * Register 9:
+ * Set to 0x00 for IrDA, when the baudrate is initialised.
+ *
+ * Register A:
+ * Set to 0x01 for IrDA, at init.
+ *
+ * Register B:
+ * Set to 0x01 for IrDA, 0x00 for RS232, at init.
+ *
+ * Register C:
+ * Set to 00 for IrDA, at init.
+ *
+ * Register D:
+ * Set to 0x41 for IrDA, at init.
+ *
+ * Register E:
+ * Somekind of baudrate override. The windows driver seems to set
+ * this to 0x00 for normal baudrates, 0x01 for 460800, 0x02 for 921600.
+ * Since 460800 and 921600 cannot be obtained by dividing 3MHz by an integer,
+ * it could be somekind of subdivisor thingy.
+ * However,it does not seem to do anything: selecting 921600 (divisor 3,
+ * reg E=2), still gets 1 MHz. I also checked if registers 9, C or F would
+ * work, but they don't.
+ *
+ * Register F: unknown
+ */
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index ebcc6d0..f99498f 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -598,6 +598,20 @@
 	{ USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) },
 	{ USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) },
 	{ USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) },
+	{ USB_DEVICE(BANDB_VID, BANDB_USOPTL4_PID) },
+	{ USB_DEVICE(BANDB_VID, BANDB_USPTL4_PID) },
+	{ USB_DEVICE(BANDB_VID, BANDB_USO9ML2DR_2_PID) },
+	{ USB_DEVICE(BANDB_VID, BANDB_USO9ML2DR_PID) },
+	{ USB_DEVICE(BANDB_VID, BANDB_USOPTL4DR2_PID) },
+	{ USB_DEVICE(BANDB_VID, BANDB_USOPTL4DR_PID) },
+	{ USB_DEVICE(BANDB_VID, BANDB_485USB9F_2W_PID) },
+	{ USB_DEVICE(BANDB_VID, BANDB_485USB9F_4W_PID) },
+	{ USB_DEVICE(BANDB_VID, BANDB_232USB9M_PID) },
+	{ USB_DEVICE(BANDB_VID, BANDB_485USBTB_2W_PID) },
+	{ USB_DEVICE(BANDB_VID, BANDB_485USBTB_4W_PID) },
+	{ USB_DEVICE(BANDB_VID, BANDB_TTL5USB9M_PID) },
+	{ USB_DEVICE(BANDB_VID, BANDB_TTL3USB9M_PID) },
+	{ USB_DEVICE(BANDB_VID, BANDB_ZZ_PROG1_USB_PID) },
 	{ USB_DEVICE(FTDI_VID, EVER_ECO_PRO_CDS) },
 	{ USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) },
@@ -2195,15 +2209,21 @@
 
 	/* Set number of data bits, parity, stop bits */
 
-	termios->c_cflag &= ~CMSPAR;
-
 	urb_value = 0;
 	urb_value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 :
 		      FTDI_SIO_SET_DATA_STOP_BITS_1);
-	urb_value |= (cflag & PARENB ?
-		      (cflag & PARODD ? FTDI_SIO_SET_DATA_PARITY_ODD :
-		       FTDI_SIO_SET_DATA_PARITY_EVEN) :
-		      FTDI_SIO_SET_DATA_PARITY_NONE);
+	if (cflag & PARENB) {
+		if (cflag & CMSPAR)
+			urb_value |= cflag & PARODD ?
+				     FTDI_SIO_SET_DATA_PARITY_MARK :
+				     FTDI_SIO_SET_DATA_PARITY_SPACE;
+		else
+			urb_value |= cflag & PARODD ?
+				     FTDI_SIO_SET_DATA_PARITY_ODD :
+				     FTDI_SIO_SET_DATA_PARITY_EVEN;
+	} else {
+		urb_value |= FTDI_SIO_SET_DATA_PARITY_NONE;
+	}
 	if (cflag & CSIZE) {
 		switch (cflag & CSIZE) {
 		case CS5: urb_value |= 5; dbg("Setting CS5"); break;
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index 6f31e0d..4586a24 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -662,6 +662,20 @@
 #define BANDB_USOTL4_PID	0xAC01	/* USOTL4 Isolated RS-485 Converter */
 #define BANDB_USTL4_PID		0xAC02	/* USTL4 RS-485 Converter */
 #define BANDB_USO9ML2_PID	0xAC03	/* USO9ML2 Isolated RS-232 Converter */
+#define BANDB_USOPTL4_PID	0xAC11
+#define BANDB_USPTL4_PID	0xAC12
+#define BANDB_USO9ML2DR_2_PID	0xAC16
+#define BANDB_USO9ML2DR_PID	0xAC17
+#define BANDB_USOPTL4DR2_PID	0xAC18	/* USOPTL4R-2 2-port Isolated RS-232 Converter */
+#define BANDB_USOPTL4DR_PID	0xAC19
+#define BANDB_485USB9F_2W_PID	0xAC25
+#define BANDB_485USB9F_4W_PID	0xAC26
+#define BANDB_232USB9M_PID	0xAC27
+#define BANDB_485USBTB_2W_PID	0xAC33
+#define BANDB_485USBTB_4W_PID	0xAC34
+#define BANDB_TTL5USB9M_PID	0xAC49
+#define BANDB_TTL3USB9M_PID	0xAC50
+#define BANDB_ZZ_PROG1_USB_PID	0xBA02
 
 /*
  * RM Michaelides CANview USB (http://www.rmcan.com)
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index f11abf5..485fa9c 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -121,8 +121,14 @@
  * moschip_id_table_combined
  */
 #define USB_VENDOR_ID_BANDB             0x0856
-#define BANDB_DEVICE_ID_USOPTL4_4       0xAC44
+#define BANDB_DEVICE_ID_USO9ML2_2	0xAC22
+#define BANDB_DEVICE_ID_USO9ML2_4	0xAC24
+#define BANDB_DEVICE_ID_US9ML2_2	0xAC29
+#define BANDB_DEVICE_ID_US9ML2_4	0xAC30
+#define BANDB_DEVICE_ID_USPTL4_2	0xAC31
+#define BANDB_DEVICE_ID_USPTL4_4	0xAC32
 #define BANDB_DEVICE_ID_USOPTL4_2       0xAC42
+#define BANDB_DEVICE_ID_USOPTL4_4       0xAC44
 
 /* This driver also supports
  * ATEN UC2324 device using Moschip MCS7840
@@ -177,8 +183,14 @@
 static struct usb_device_id moschip_port_id_table[] = {
 	{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
 	{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
-	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
+	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)},
+	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)},
+	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)},
+	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)},
+	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)},
+	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)},
 	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
+	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
 	{USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)},
 	{USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)},
 	{}			/* terminating entry */
@@ -187,8 +199,14 @@
 static __devinitdata struct usb_device_id moschip_id_table_combined[] = {
 	{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
 	{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
-	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
+	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)},
+	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)},
+	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)},
+	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)},
+	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)},
+	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)},
 	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
+	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
 	{USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)},
 	{USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)},
 	{}			/* terminating entry */
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
index 80f59b6..4cdb975 100644
--- a/drivers/usb/serial/opticon.c
+++ b/drivers/usb/serial/opticon.c
@@ -501,12 +501,13 @@
 	struct usb_serial_port *port = serial->port[0];
 	int result;
 
-	mutex_lock(&port->mutex);
-	if (port->port.count)
+	mutex_lock(&port->port.mutex);
+	/* This is protected by the port mutex against close/open */
+	if (test_bit(ASYNCB_INITIALIZED, &port->port.flags))
 		result = usb_submit_urb(priv->bulk_read_urb, GFP_NOIO);
 	else
 		result = 0;
-	mutex_unlock(&port->mutex);
+	mutex_unlock(&port->port.mutex);
 	return result;
 }
 
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 0577e4b..9a2b903 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -580,12 +580,48 @@
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0086, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0104, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0106, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0108, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0117, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0122, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0128, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0142, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0143, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0144, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0145, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0146, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0148, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0149, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0150, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0151, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0153, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0154, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0155, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0156, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0159, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0160, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, /* ZTE CDMA products */
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0027, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0060, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
@@ -599,6 +635,7 @@
 	{ USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) },
 	{ USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */
 	{ USB_DEVICE(ALINK_VENDOR_ID, 0x9000) },
+	{ USB_DEVICE(ALINK_VENDOR_ID, 0xce16) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) },
 	{ USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) },
@@ -1312,7 +1349,7 @@
 
 	dbg("%s entered", __func__);
 
-	if (serial->dev->auto_pm) {
+	if (message.event & PM_EVENT_AUTO) {
 		spin_lock_irq(&intfdata->susp_lock);
 		b = intfdata->in_flight;
 		spin_unlock_irq(&intfdata->susp_lock);
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 5019325..ac1b644 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -16,8 +16,9 @@
   Portions based on the option driver by Matthias Urlichs <smurf@smurf.noris.de>
   Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org>
 */
-
-#define DRIVER_VERSION "v.1.3.8"
+/* Uncomment to log function calls */
+/* #define DEBUG */
+#define DRIVER_VERSION "v.1.7.16"
 #define DRIVER_AUTHOR "Kevin Lloyd, Elina Pasheva, Matthew Safar, Rory Filer"
 #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems"
 
@@ -33,8 +34,10 @@
 #define SWIMS_USB_REQUEST_SetPower	0x00
 #define SWIMS_USB_REQUEST_SetNmea	0x07
 
-#define N_IN_URB	8
-#define N_OUT_URB	64
+#define N_IN_URB_HM	8
+#define N_OUT_URB_HM	64
+#define N_IN_URB	4
+#define N_OUT_URB	4
 #define IN_BUFLEN	4096
 
 #define MAX_TRANSFER		(PAGE_SIZE - 512)
@@ -124,6 +127,23 @@
 	return 0;
 }
 
+static int is_himemory(const u8 ifnum,
+				const struct sierra_iface_info *himemorylist)
+{
+	const u8  *info;
+	int i;
+
+	if (himemorylist) {
+		info = himemorylist->ifaceinfo;
+
+		for (i=0; i < himemorylist->infolen; i++) {
+			if (info[i] == ifnum)
+				return 1;
+		}
+	}
+	return 0;
+}
+
 static int sierra_calc_interface(struct usb_serial *serial)
 {
 	int interface;
@@ -186,6 +206,20 @@
 	return result;
 }
 
+/* interfaces with higher memory requirements */
+static const u8 hi_memory_typeA_ifaces[] = { 0, 2 };
+static const struct sierra_iface_info typeA_interface_list = {
+	.infolen = ARRAY_SIZE(hi_memory_typeA_ifaces),
+	.ifaceinfo = hi_memory_typeA_ifaces,
+};
+
+static const u8 hi_memory_typeB_ifaces[] = { 3, 4, 5, 6 };
+static const struct sierra_iface_info typeB_interface_list = {
+	.infolen = ARRAY_SIZE(hi_memory_typeB_ifaces),
+	.ifaceinfo = hi_memory_typeB_ifaces,
+};
+
+/* 'blacklist' of interfaces not served by this driver */
 static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 };
 static const struct sierra_iface_info direct_ip_interface_blacklist = {
 	.infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces),
@@ -286,8 +320,10 @@
 	struct usb_anchor active;
 	struct usb_anchor delayed;
 
+	int num_out_urbs;
+	int num_in_urbs;
 	/* Input endpoints and buffers for this port */
-	struct urb *in_urbs[N_IN_URB];
+	struct urb *in_urbs[N_IN_URB_HM];
 
 	/* Settings for the port */
 	int rts_state;	/* Handshaking pins (outputs) */
@@ -460,7 +496,7 @@
 	spin_lock_irqsave(&portdata->lock, flags);
 	dev_dbg(&port->dev, "%s - outstanding_urbs: %d\n", __func__,
 		portdata->outstanding_urbs);
-	if (portdata->outstanding_urbs > N_OUT_URB) {
+	if (portdata->outstanding_urbs > portdata->num_out_urbs) {
 		spin_unlock_irqrestore(&portdata->lock, flags);
 		dev_dbg(&port->dev, "%s - write limit hit\n", __func__);
 		return 0;
@@ -665,7 +701,7 @@
 	/* try to give a good number back based on if we have any free urbs at
 	 * this point in time */
 	spin_lock_irqsave(&portdata->lock, flags);
-	if (portdata->outstanding_urbs > N_OUT_URB * 2 / 3) {
+	if (portdata->outstanding_urbs > (portdata->num_out_urbs * 2) / 3) {
 		spin_unlock_irqrestore(&portdata->lock, flags);
 		dev_dbg(&port->dev, "%s - write limit hit\n", __func__);
 		return 0;
@@ -680,7 +716,7 @@
 	int i;
 	struct sierra_port_private *portdata = usb_get_serial_port_data(port);
 
-	for (i = 0; i < ARRAY_SIZE(portdata->in_urbs); i++)
+	for (i = 0; i < portdata->num_in_urbs; i++)
 		usb_kill_urb(portdata->in_urbs[i]);
 
 	usb_kill_urb(port->interrupt_in_urb);
@@ -695,7 +731,7 @@
 	struct sierra_port_private *portdata = usb_get_serial_port_data(port);
 
 	ok_cnt = 0;
-	for (i = 0; i < ARRAY_SIZE(portdata->in_urbs); i++) {
+	for (i = 0; i < portdata->num_in_urbs; i++) {
 		urb = portdata->in_urbs[i];
 		if (!urb)
 			continue;
@@ -791,7 +827,7 @@
 		/* Stop reading urbs */
 		sierra_stop_rx_urbs(port);
 		/* .. and release them */
-		for (i = 0; i < N_IN_URB; i++) {
+		for (i = 0; i < portdata->num_in_urbs; i++) {
 			sierra_release_urb(portdata->in_urbs[i]);
 			portdata->in_urbs[i] = NULL;
 		}
@@ -818,7 +854,7 @@
 
 
 	endpoint = port->bulk_in_endpointAddress;
-	for (i = 0; i < ARRAY_SIZE(portdata->in_urbs); i++) {
+	for (i = 0; i < portdata->num_in_urbs; i++) {
 		urb = sierra_setup_urb(serial, endpoint, USB_DIR_IN, port,
 					IN_BUFLEN, GFP_KERNEL,
 					sierra_indat_callback);
@@ -869,7 +905,9 @@
 {
 	struct usb_serial_port *port;
 	struct sierra_port_private *portdata;
+	struct sierra_iface_info *himemoryp = NULL;
 	int i;
+	u8 ifnum;
 
 	dev_dbg(&serial->dev->dev, "%s\n", __func__);
 
@@ -886,13 +924,40 @@
 		portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
 		if (!portdata) {
 			dev_dbg(&port->dev, "%s: kmalloc for "
-				"sierra_port_private (%d) failed!.\n",
+				"sierra_port_private (%d) failed!\n",
 				__func__, i);
 			return -ENOMEM;
 		}
 		spin_lock_init(&portdata->lock);
 		init_usb_anchor(&portdata->active);
 		init_usb_anchor(&portdata->delayed);
+		ifnum = i;
+		/* Assume low memory requirements */
+		portdata->num_out_urbs = N_OUT_URB;
+		portdata->num_in_urbs  = N_IN_URB;
+
+		/* Determine actual memory requirements */
+		if (serial->num_ports == 1) {
+			/* Get interface number for composite device */
+			ifnum = sierra_calc_interface(serial);
+			himemoryp =
+			    (struct sierra_iface_info *)&typeB_interface_list;
+			if (is_himemory(ifnum, himemoryp)) {
+				portdata->num_out_urbs = N_OUT_URB_HM;
+				portdata->num_in_urbs  = N_IN_URB_HM;
+			}
+		}
+		else {
+			himemoryp =
+			    (struct sierra_iface_info *)&typeA_interface_list;
+			if (is_himemory(i, himemoryp)) {
+				portdata->num_out_urbs = N_OUT_URB_HM;
+				portdata->num_in_urbs  = N_IN_URB_HM;
+			}
+		}
+		dev_dbg(&serial->dev->dev,
+			"Memory usage (urbs) interface #%d, in=%d, out=%d\n",
+			ifnum,portdata->num_in_urbs, portdata->num_out_urbs );
 		/* Set the port private data pointer */
 		usb_set_serial_port_data(port, portdata);
 	}
@@ -940,7 +1005,7 @@
 	struct sierra_intf_private *intfdata;
 	int b;
 
-	if (serial->dev->auto_pm) {
+	if (message.event & PM_EVENT_AUTO) {
 		intfdata = serial->private;
 		spin_lock_irq(&intfdata->susp_lock);
 		b = intfdata->in_flight;
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index bd3fa7f..4543f35 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -247,96 +247,66 @@
 	return retval;
 }
 
-static int serial_open(struct tty_struct *tty, struct file *filp)
+static int serial_activate(struct tty_port *tport, struct tty_struct *tty)
 {
-	struct usb_serial_port *port = tty->driver_data;
+	struct usb_serial_port *port =
+		container_of(tport, struct usb_serial_port, port);
 	struct usb_serial *serial = port->serial;
 	int retval;
 
-	dbg("%s - port %d", __func__, port->number);
-
-	spin_lock_irq(&port->port.lock);
-	if (!tty_hung_up_p(filp))
-		++port->port.count;
-	spin_unlock_irq(&port->port.lock);
-	tty_port_tty_set(&port->port, tty);
-
-	/* Do the device-specific open only if the hardware isn't
-	 * already initialized.
-	 */
-	if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) {
-		if (mutex_lock_interruptible(&port->mutex))
-			return -ERESTARTSYS;
-		mutex_lock(&serial->disc_mutex);
-		if (serial->disconnected)
-			retval = -ENODEV;
-		else
-			retval = port->serial->type->open(tty, port);
-		mutex_unlock(&serial->disc_mutex);
-		mutex_unlock(&port->mutex);
-		if (retval)
-			return retval;
-		set_bit(ASYNCB_INITIALIZED, &port->port.flags);
-	}
-
-	/* Now do the correct tty layer semantics */
-	retval = tty_port_block_til_ready(&port->port, tty, filp);
+	mutex_lock(&serial->disc_mutex);
+	if (serial->disconnected)
+		retval = -ENODEV;
+	else
+		retval = port->serial->type->open(tty, port);
+	mutex_unlock(&serial->disc_mutex);
 	return retval;
 }
 
+static int serial_open(struct tty_struct *tty, struct file *filp)
+{
+	struct usb_serial_port *port = tty->driver_data;
+
+	dbg("%s - port %d", __func__, port->number);
+	return tty_port_open(&port->port, tty, filp);
+}
+
 /**
  * serial_down - shut down hardware
- * @port: port to shut down
+ * @tport: tty port to shut down
  *
  * Shut down a USB serial port unless it is the console.  We never
- * shut down the console hardware as it will always be in use.
+ * shut down the console hardware as it will always be in use. Serialized
+ * against activate by the tport mutex and kept to matching open/close pairs
+ * of calls by the ASYNCB_INITIALIZED flag.
  */
-static void serial_down(struct usb_serial_port *port)
+static void serial_down(struct tty_port *tport)
 {
+	struct usb_serial_port *port =
+		container_of(tport, struct usb_serial_port, port);
 	struct usb_serial_driver *drv = port->serial->type;
-
 	/*
 	 * The console is magical.  Do not hang up the console hardware
 	 * or there will be tears.
 	 */
 	if (port->console)
 		return;
-
-	/* Don't call the close method if the hardware hasn't been
-	 * initialized.
-	 */
-	if (!test_and_clear_bit(ASYNCB_INITIALIZED, &port->port.flags))
-		return;
-
-	mutex_lock(&port->mutex);
 	if (drv->close)
 		drv->close(port);
-	mutex_unlock(&port->mutex);
 }
 
 static void serial_hangup(struct tty_struct *tty)
 {
 	struct usb_serial_port *port = tty->driver_data;
-
 	dbg("%s - port %d", __func__, port->number);
-
-	serial_down(port);
 	tty_port_hangup(&port->port);
 }
 
 static void serial_close(struct tty_struct *tty, struct file *filp)
 {
 	struct usb_serial_port *port = tty->driver_data;
-
 	dbg("%s - port %d", __func__, port->number);
-
-	if (tty_hung_up_p(filp))
-		return;
-	if (tty_port_close_start(&port->port, tty, filp) == 0)
-		return;
-	serial_down(port);
-	tty_port_close_end(&port->port, tty);
-	tty_port_tty_set(&port->port, NULL);
+	tty_port_close(&port->port, tty, filp);
 }
 
 /**
@@ -725,6 +695,8 @@
 static const struct tty_port_operations serial_port_ops = {
 	.carrier_raised = serial_carrier_raised,
 	.dtr_rts = serial_dtr_rts,
+	.activate = serial_activate,
+	.shutdown = serial_down,
 };
 
 int usb_serial_probe(struct usb_interface *interface,
@@ -923,7 +895,8 @@
 		port->port.ops = &serial_port_ops;
 		port->serial = serial;
 		spin_lock_init(&port->lock);
-		mutex_init(&port->mutex);
+		/* Keep this for private driver use for the moment but
+		   should probably go away */
 		INIT_WORK(&port->work, usb_serial_port_work);
 		serial->port[i] = port;
 		port->dev.parent = &interface->dev;
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index cfa26d5..e5e6df3 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -73,7 +73,8 @@
 
 static const char* host_info(struct Scsi_Host *host)
 {
-	return "SCSI emulation for USB Mass Storage devices";
+	struct us_data *us = host_to_us(host);
+	return us->scsi_name;
 }
 
 static int slave_alloc (struct scsi_device *sdev)
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index 589f6b4..cc313d1 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -666,10 +666,11 @@
 	 * to wait for at least one CHECK_CONDITION to determine
 	 * SANE_SENSE support
 	 */
-	if ((srb->cmnd[0] == ATA_16 || srb->cmnd[0] == ATA_12) &&
+	if (unlikely((srb->cmnd[0] == ATA_16 || srb->cmnd[0] == ATA_12) &&
 	    result == USB_STOR_TRANSPORT_GOOD &&
 	    !(us->fflags & US_FL_SANE_SENSE) &&
-	    !(srb->cmnd[2] & 0x20)) {
+	    !(us->fflags & US_FL_BAD_SENSE) &&
+	    !(srb->cmnd[2] & 0x20))) {
 		US_DEBUGP("-- SAT supported, increasing auto-sense\n");
 		us->fflags |= US_FL_SANE_SENSE;
 	}
@@ -718,6 +719,12 @@
 		if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
 			US_DEBUGP("-- auto-sense aborted\n");
 			srb->result = DID_ABORT << 16;
+
+			/* If SANE_SENSE caused this problem, disable it */
+			if (sense_size != US_SENSE_SIZE) {
+				us->fflags &= ~US_FL_SANE_SENSE;
+				us->fflags |= US_FL_BAD_SENSE;
+			}
 			goto Handle_Errors;
 		}
 
@@ -727,10 +734,11 @@
 		 * (small) sense request. This fixes some USB GSM modems
 		 */
 		if (temp_result == USB_STOR_TRANSPORT_FAILED &&
-		    (us->fflags & US_FL_SANE_SENSE) &&
-		    sense_size != US_SENSE_SIZE) {
+				sense_size != US_SENSE_SIZE) {
 			US_DEBUGP("-- auto-sense failure, retry small sense\n");
 			sense_size = US_SENSE_SIZE;
+			us->fflags &= ~US_FL_SANE_SENSE;
+			us->fflags |= US_FL_BAD_SENSE;
 			goto Retry_Sense;
 		}
 
@@ -754,6 +762,7 @@
 		 */
 		if (srb->sense_buffer[7] > (US_SENSE_SIZE - 8) &&
 		    !(us->fflags & US_FL_SANE_SENSE) &&
+		    !(us->fflags & US_FL_BAD_SENSE) &&
 		    (srb->sense_buffer[0] & 0x7C) == 0x70) {
 			US_DEBUGP("-- SANE_SENSE support enabled\n");
 			us->fflags |= US_FL_SANE_SENSE;
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index d4f034e..64a0a2c 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -818,6 +818,13 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_CAPACITY ),
 
+/* Reported by Daniel Kukula <daniel.kuku@gmail.com> */
+UNUSUAL_DEV( 0x067b, 0x1063, 0x0100, 0x0100,
+		"Prolific Technology, Inc.",
+		"Prolific Storage Gadget",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_BAD_SENSE ),
+
 /* Reported by Rogerio Brito <rbrito@ime.usp.br> */
 UNUSUAL_DEV( 0x067b, 0x2317, 0x0001, 0x001,
 		"Prolific Technology, Inc.",
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 8060b85..5a53d4f 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -45,6 +45,10 @@
  * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#ifdef CONFIG_USB_STORAGE_DEBUG
+#define DEBUG
+#endif
+
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/freezer.h>
@@ -228,6 +232,7 @@
 	if (data_len<36) // You lose.
 		return;
 
+	memset(data+8, ' ', 28);
 	if(data[0]&0x20) { /* USB device currently not connected. Return
 			      peripheral qualifier 001b ("...however, the
 			      physical device is not currently connected
@@ -237,15 +242,15 @@
 			      device, it may return zeros or ASCII spaces 
 			      (20h) in those fields until the data is
 			      available from the device."). */
-		memset(data+8,0,28);
 	} else {
 		u16 bcdDevice = le16_to_cpu(us->pusb_dev->descriptor.bcdDevice);
-		memcpy(data+8, us->unusual_dev->vendorName, 
-			strlen(us->unusual_dev->vendorName) > 8 ? 8 :
-			strlen(us->unusual_dev->vendorName));
-		memcpy(data+16, us->unusual_dev->productName, 
-			strlen(us->unusual_dev->productName) > 16 ? 16 :
-			strlen(us->unusual_dev->productName));
+		int n;
+
+		n = strlen(us->unusual_dev->vendorName);
+		memcpy(data+8, us->unusual_dev->vendorName, min(8, n));
+		n = strlen(us->unusual_dev->productName);
+		memcpy(data+16, us->unusual_dev->productName, min(16, n));
+
 		data[32] = 0x30 + ((bcdDevice>>12) & 0x0F);
 		data[33] = 0x30 + ((bcdDevice>>8) & 0x0F);
 		data[34] = 0x30 + ((bcdDevice>>4) & 0x0F);
@@ -459,6 +464,9 @@
 		case 'a':
 			f |= US_FL_SANE_SENSE;
 			break;
+		case 'b':
+			f |= US_FL_BAD_SENSE;
+			break;
 		case 'c':
 			f |= US_FL_FIX_CAPACITY;
 			break;
@@ -808,14 +816,13 @@
 {
 	struct us_data *us = (struct us_data *)__us;
 
-	printk(KERN_DEBUG
-		"usb-storage: device found at %d\n", us->pusb_dev->devnum);
+	dev_dbg(&us->pusb_intf->dev, "device found\n");
 
 	set_freezable();
 	/* Wait for the timeout to expire or for a disconnect */
 	if (delay_use > 0) {
-		printk(KERN_DEBUG "usb-storage: waiting for device "
-				"to settle before scanning\n");
+		dev_dbg(&us->pusb_intf->dev, "waiting for device to settle "
+				"before scanning\n");
 		wait_event_freezable_timeout(us->delay_wait,
 				test_bit(US_FLIDX_DONT_SCAN, &us->dflags),
 				delay_use * HZ);
@@ -832,7 +839,7 @@
 			mutex_unlock(&us->dev_mutex);
 		}
 		scsi_scan_host(us_to_host(us));
-		printk(KERN_DEBUG "usb-storage: device scan complete\n");
+		dev_dbg(&us->pusb_intf->dev, "scan complete\n");
 
 		/* Should we unbind if no devices were detected? */
 	}
@@ -840,6 +847,15 @@
 	complete_and_exit(&us->scanning_done, 0);
 }
 
+static unsigned int usb_stor_sg_tablesize(struct usb_interface *intf)
+{
+	struct usb_device *usb_dev = interface_to_usbdev(intf);
+
+	if (usb_dev->bus->sg_tablesize) {
+		return usb_dev->bus->sg_tablesize;
+	}
+	return SG_ALL;
+}
 
 /* First part of general USB mass-storage probing */
 int usb_stor_probe1(struct us_data **pus,
@@ -868,6 +884,7 @@
 	 * Allow 16-byte CDBs and thus > 2TB
 	 */
 	host->max_cmd_len = 16;
+	host->sg_tablesize = usb_stor_sg_tablesize(intf);
 	*pus = us = host_to_us(host);
 	memset(us, 0, sizeof(struct us_data));
 	mutex_init(&(us->dev_mutex));
@@ -929,6 +946,8 @@
 	result = usb_stor_acquire_resources(us);
 	if (result)
 		goto BadDevice;
+	snprintf(us->scsi_name, sizeof(us->scsi_name), "usb-storage %s",
+					dev_name(&us->pusb_intf->dev));
 	result = scsi_add_host(us_to_host(us), &us->pusb_intf->dev);
 	if (result) {
 		printk(KERN_WARNING USB_STORAGE
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index 2609efb..6971713 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -132,6 +132,7 @@
 	/* SCSI interfaces */
 	struct scsi_cmnd	*srb;		 /* current srb		*/
 	unsigned int		tag;		 /* current dCBWTag	*/
+	char			scsi_name[32];	 /* scsi_host name	*/
 
 	/* control and bulk communications data */
 	struct urb		*current_urb;	 /* USB requests	 */
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
index b62f2bc..b1e579c 100644
--- a/drivers/usb/usb-skeleton.c
+++ b/drivers/usb/usb-skeleton.c
@@ -358,7 +358,7 @@
 		rv = skel_do_read_io(dev, count);
 		if (rv < 0)
 			goto exit;
-		else if (!file->f_flags & O_NONBLOCK)
+		else if (!(file->f_flags & O_NONBLOCK))
 			goto retry;
 		rv = -EAGAIN;
 	}
@@ -411,7 +411,7 @@
 	 * limit the number of URBs in flight to stop a user from using up all
 	 * RAM
 	 */
-	if (!file->f_flags & O_NONBLOCK) {
+	if (!(file->f_flags & O_NONBLOCK)) {
 		if (down_interruptible(&dev->limit_sem)) {
 			retval = -ERESTARTSYS;
 			goto exit;
diff --git a/drivers/usb/wusbcore/crypto.c b/drivers/usb/wusbcore/crypto.c
index 9ec7fd5..9579cf4 100644
--- a/drivers/usb/wusbcore/crypto.c
+++ b/drivers/usb/wusbcore/crypto.c
@@ -111,7 +111,7 @@
  *
  * CCM uses Ax blocks to generate a keystream with which the MIC and
  * the message's payload are encoded. A0 always encrypts/decrypts the
- * MIC. Ax (x>0) are used for the sucesive payload blocks.
+ * MIC. Ax (x>0) are used for the successive payload blocks.
  *
  * The x is the counter, and is increased for each block.
  */
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c
index 4ac4300..dced419 100644
--- a/drivers/usb/wusbcore/devconnect.c
+++ b/drivers/usb/wusbcore/devconnect.c
@@ -119,10 +119,12 @@
 	urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (urb == NULL)
 		goto err;
+	wusb_dev->set_gtk_urb = urb;
 
-	req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
+	req = kmalloc(sizeof(*req), GFP_KERNEL);
 	if (req == NULL)
 		goto err;
+	wusb_dev->set_gtk_req = req;
 
 	req->bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
 	req->bRequest = USB_REQ_SET_DESCRIPTOR;
@@ -130,9 +132,6 @@
 	req->wIndex = 0;
 	req->wLength = cpu_to_le16(wusbhc->gtk.descr.bLength);
 
-	wusb_dev->set_gtk_urb = urb;
-	wusb_dev->set_gtk_req = req;
-
 	return wusb_dev;
 err:
 	wusb_dev_free(wusb_dev);
diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c
index 4516c36..edcd2d7 100644
--- a/drivers/usb/wusbcore/security.c
+++ b/drivers/usb/wusbcore/security.c
@@ -205,15 +205,15 @@
 	const void *itr, *top;
 	char buf[64];
 
-	secd = kmalloc(sizeof(struct usb_security_descriptor), GFP_KERNEL);
+	secd = kmalloc(sizeof(*secd), GFP_KERNEL);
 	if (secd == NULL) {
 		result = -ENOMEM;
 		goto out;
 	}
 
 	result = usb_get_descriptor(usb_dev, USB_DT_SECURITY,
-				    0, secd, sizeof(struct usb_security_descriptor));
-	if (result < sizeof(secd)) {
+				    0, secd, sizeof(*secd));
+	if (result < sizeof(*secd)) {
 		dev_err(dev, "Can't read security descriptor or "
 			"not enough data: %d\n", result);
 		goto out;
diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c
index 613a5fc..489b478 100644
--- a/drivers/usb/wusbcore/wa-xfer.c
+++ b/drivers/usb/wusbcore/wa-xfer.c
@@ -558,7 +558,7 @@
 /*
  * Callback for the segment request
  *
- * If succesful transition state (unless already transitioned or
+ * If successful transition state (unless already transitioned or
  * outbound transfer); otherwise, take a note of the error, mark this
  * segment done and try completion.
  *
@@ -1364,7 +1364,7 @@
 /*
  * Callback for the IN data phase
  *
- * If succesful transition state; otherwise, take a note of the
+ * If successful transition state; otherwise, take a note of the
  * error, mark this segment done and try completion.
  *
  * Note we don't access until we are sure that the transfer hasn't
diff --git a/drivers/usb/wusbcore/wusbhc.c b/drivers/usb/wusbcore/wusbhc.c
index ee6256f..eab86e4 100644
--- a/drivers/usb/wusbcore/wusbhc.c
+++ b/drivers/usb/wusbcore/wusbhc.c
@@ -147,10 +147,40 @@
 }
 static DEVICE_ATTR(wusb_chid, 0644, wusb_chid_show, wusb_chid_store);
 
+
+static ssize_t wusb_phy_rate_show(struct device *dev,
+				  struct device_attribute *attr,
+				  char *buf)
+{
+	struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);
+
+	return sprintf(buf, "%d\n", wusbhc->phy_rate);
+}
+
+static ssize_t wusb_phy_rate_store(struct device *dev,
+				   struct device_attribute *attr,
+				   const char *buf, size_t size)
+{
+	struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);
+	uint8_t phy_rate;
+	ssize_t result;
+
+	result = sscanf(buf, "%hhu", &phy_rate);
+	if (result != 1)
+		return -EINVAL;
+	if (phy_rate >= UWB_PHY_RATE_INVALID)
+		return -EINVAL;
+
+	wusbhc->phy_rate = phy_rate;
+	return size;
+}
+static DEVICE_ATTR(wusb_phy_rate, 0644, wusb_phy_rate_show, wusb_phy_rate_store);
+
 /* Group all the WUSBHC attributes */
 static struct attribute *wusbhc_attrs[] = {
 		&dev_attr_wusb_trust_timeout.attr,
 		&dev_attr_wusb_chid.attr,
+		&dev_attr_wusb_phy_rate.attr,
 		NULL,
 };
 
@@ -177,6 +207,8 @@
 	int result = 0;
 
 	wusbhc->trust_timeout = WUSB_TRUST_TIMEOUT_MS;
+	wusbhc->phy_rate = UWB_PHY_RATE_INVALID - 1;
+
 	mutex_init(&wusbhc->mutex);
 	result = wusbhc_mmcie_create(wusbhc);
 	if (result < 0)
diff --git a/drivers/usb/wusbcore/wusbhc.h b/drivers/usb/wusbcore/wusbhc.h
index 797c245..fd2fd4e 100644
--- a/drivers/usb/wusbcore/wusbhc.h
+++ b/drivers/usb/wusbcore/wusbhc.h
@@ -253,6 +253,7 @@
 
 	unsigned trust_timeout;			/* in jiffies */
 	struct wusb_ckhdid chid;
+	uint8_t phy_rate;
 	struct wuie_host_info *wuie_host_info;
 
 	struct mutex mutex;			/* locks everything else */
diff --git a/drivers/uwb/i1480/dfu/usb.c b/drivers/uwb/i1480/dfu/usb.c
index c7080d4..0bb665a 100644
--- a/drivers/uwb/i1480/dfu/usb.c
+++ b/drivers/uwb/i1480/dfu/usb.c
@@ -229,7 +229,7 @@
  * will verify it.
  *
  * Set i1480->evt_result with the result of getting the event or its
- * size (if succesful).
+ * size (if successful).
  *
  * Delivers the data directly to i1480->evt_buf
  */
diff --git a/drivers/uwb/neh.c b/drivers/uwb/neh.c
index 0af8916..78510a1 100644
--- a/drivers/uwb/neh.c
+++ b/drivers/uwb/neh.c
@@ -150,7 +150,7 @@
  *	 0xff is invalid, so they must not be used. Initialization
  *	 fills up those two in the bitmap so they are not allocated.
  *
- * We spread the allocation around to reduce the posiblity of two
+ * We spread the allocation around to reduce the possibility of two
  * consecutive opened @neh's getting the same context ID assigned (to
  * avoid surprises with late events that timed out long time ago). So
  * first we search from where @rc->ctx_roll is, if not found, we
diff --git a/drivers/uwb/wlp/txrx.c b/drivers/uwb/wlp/txrx.c
index 86a853b..7350ed6 100644
--- a/drivers/uwb/wlp/txrx.c
+++ b/drivers/uwb/wlp/txrx.c
@@ -282,7 +282,7 @@
  *         and transmission will be done by the calling function.
  * @dst:   On return this will contain the device address to which the
  *         frame is destined.
- * @returns: 0 on success no tx : WLP header sucessfully applied to skb buffer,
+ * @returns: 0 on success no tx : WLP header successfully applied to skb buffer,
  *                                calling function can proceed with tx
  *           1 on success with tx : WLP will take over transmission of this
  *                                  frame
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 6b89eb5..bb5fbed 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2066,6 +2066,7 @@
 	select FB_SYS_IMAGEBLIT
 	select FB_SYS_FOPS
 	select FB_DEFERRED_IO
+	select XEN_XENBUS_FRONTEND
 	default y
 	help
 	  This driver implements the front-end of the Xen virtual
@@ -2164,6 +2165,7 @@
 	  a bridge adapter.
 
 source "drivers/video/omap/Kconfig"
+source "drivers/video/omap2/Kconfig"
 
 source "drivers/video/backlight/Kconfig"
 source "drivers/video/display/Kconfig"
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 80232e1..0f8da33 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -124,6 +124,7 @@
 obj-$(CONFIG_FB_XILINX)           += xilinxfb.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/
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index d5e8010..3d886c6 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -964,7 +964,7 @@
 	if (sinfo->atmel_lcdfb_power_control)
 		sinfo->atmel_lcdfb_power_control(1);
 
-	dev_info(dev, "fb%d: Atmel LCDC at 0x%08lx (mapped at %p), irq %lu\n",
+	dev_info(dev, "fb%d: Atmel LCDC at 0x%08lx (mapped at %p), irq %d\n",
 		       info->node, info->fix.mmio_start, sinfo->mmio, sinfo->irq_base);
 
 	return 0;
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 913b4a4..1ddeb4c 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -3276,7 +3276,7 @@
 				txtformat = "24 bit interface";
 				break;
 			default:
-				txtformat = "unkown format";
+				txtformat = "unknown format";
 			}
 		} else {
 			switch (format & 7) {
@@ -3299,7 +3299,7 @@
 				txtformat = "262144 colours (FDPI-2 mode)";
 				break;
 			default:
-				txtformat = "unkown format";
+				txtformat = "unknown format";
 			}
 		}
 		PRINTKI("%s%s %s monitor detected: %s\n",
diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
index 505c082..2cf7ba5 100644
--- a/drivers/video/backlight/atmel-pwm-bl.c
+++ b/drivers/video/backlight/atmel-pwm-bl.c
@@ -158,7 +158,7 @@
 			goto err_free_pwm;
 		}
 
-		/* Turn display off by defatult. */
+		/* Turn display off by default. */
 		retval = gpio_direction_output(pwmbl->gpio_on,
 				0 ^ pdata->on_active_low);
 		if (retval)
diff --git a/drivers/video/backlight/tosa_lcd.c b/drivers/video/backlight/tosa_lcd.c
index 50ec17d..fa32b94 100644
--- a/drivers/video/backlight/tosa_lcd.c
+++ b/drivers/video/backlight/tosa_lcd.c
@@ -177,7 +177,7 @@
 	if (!data)
 		return -ENOMEM;
 
-	data->is_vga = true; /* defaut to VGA mode */
+	data->is_vga = true; /* default to VGA mode */
 
 	/*
 	 * bits_per_word cannot be configured in platform data
diff --git a/drivers/video/broadsheetfb.c b/drivers/video/broadsheetfb.c
index 509cb92..df9ccb9 100644
--- a/drivers/video/broadsheetfb.c
+++ b/drivers/video/broadsheetfb.c
@@ -470,7 +470,7 @@
 	par->read_reg = broadsheet_read_reg;
 	init_waitqueue_head(&par->waitq);
 
-	info->flags = FBINFO_FLAG_DEFAULT;
+	info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB;
 
 	info->fbdefio = &broadsheetfb_defio;
 	fb_deferred_io_init(info);
diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c
index 857b366..6468a29 100644
--- a/drivers/video/console/sticore.c
+++ b/drivers/video/console/sticore.c
@@ -436,7 +436,7 @@
 			    (offs < PCI_BASE_ADDRESS_0 ||
 			     offs > PCI_BASE_ADDRESS_5)) {
 				printk (KERN_WARNING
-					"STI pci region maping for region %d (%02x) can't be mapped\n",
+					"STI pci region mapping for region %d (%02x) can't be mapped\n",
 					i,sti->rm_entry[i]);
 				continue;
 			}
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index da55cca..cc4bbbe 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -585,6 +585,11 @@
 	vgacon_uni_pagedir[1]++;
 	if (!vgacon_uni_pagedir[0] && p)
 		con_set_default_unimap(c);
+
+	/* Only set the default if the user didn't deliberately override it */
+	if (global_cursor_default == -1)
+		global_cursor_default =
+			!(screen_info.flags & VIDEO_FLAGS_NOCURSOR);
 }
 
 static void vgacon_deinit(struct vc_data *c)
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index c27ab1e..44ce908 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -71,7 +71,7 @@
 {
 	struct fb_info *info = file->private_data;
 
-	/* Skip if deferred io is complied-in but disabled on this fbdev */
+	/* Skip if deferred io is compiled-in but disabled on this fbdev */
 	if (!info->fbdefio)
 		return 0;
 
@@ -144,7 +144,9 @@
 static int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
 	vma->vm_ops = &fb_deferred_io_vm_ops;
-	vma->vm_flags |= ( VM_IO | VM_RESERVED | VM_DONTEXPAND );
+	vma->vm_flags |= ( VM_RESERVED | VM_DONTEXPAND );
+	if (!(info->flags & FBINFO_VIRTFB))
+		vma->vm_flags |= VM_IO;
 	vma->vm_private_data = info;
 	return 0;
 }
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
index f67db42..695fa01 100644
--- a/drivers/video/gbefb.c
+++ b/drivers/video/gbefb.c
@@ -701,7 +701,7 @@
 	   blocks of 512x128, 256x128 or 128x128 pixels, respectively for 8bit,
 	   16bit and 32 bit modes (64 kB). They cover the screen with partial
 	   tiles on the right and/or bottom of the screen if needed.
-	   For exemple in 640x480 8 bit mode the mapping is:
+	   For example in 640x480 8 bit mode the mapping is:
 
 	   <-------- 640 ----->
 	   <---- 512 ----><128|384 offscreen>
diff --git a/drivers/video/hecubafb.c b/drivers/video/hecubafb.c
index 0b4bffb..f9d77ad 100644
--- a/drivers/video/hecubafb.c
+++ b/drivers/video/hecubafb.c
@@ -253,7 +253,7 @@
 	par->send_command = apollo_send_command;
 	par->send_data = apollo_send_data;
 
-	info->flags = FBINFO_FLAG_DEFAULT;
+	info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB;
 
 	info->fbdefio = &hecubafb_defio;
 	fb_deferred_io_init(info);
diff --git a/drivers/video/metronomefb.c b/drivers/video/metronomefb.c
index df1f757..661bfd2 100644
--- a/drivers/video/metronomefb.c
+++ b/drivers/video/metronomefb.c
@@ -700,7 +700,7 @@
 	if (retval < 0)
 		goto err_free_irq;
 
-	info->flags = FBINFO_FLAG_DEFAULT;
+	info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB;
 
 	info->fbdefio = &metronomefb_defio;
 	fb_deferred_io_init(info);
diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig
index 551e3e9..455c605 100644
--- a/drivers/video/omap/Kconfig
+++ b/drivers/video/omap/Kconfig
@@ -1,6 +1,7 @@
 config FB_OMAP
 	tristate "OMAP frame buffer support (EXPERIMENTAL)"
-	depends on FB && ARCH_OMAP
+	depends on FB && ARCH_OMAP && (OMAP2_DSS = "n")
+
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
@@ -72,7 +73,7 @@
 
 config FB_OMAP_BOOTLOADER_INIT
 	bool "Check bootloader initialization"
-	depends on FB_OMAP
+	depends on FB_OMAP || FB_OMAP2
 	help
 	  Say Y here if you want to enable checking if the bootloader has
 	  already initialized the display controller. In this case the
diff --git a/drivers/video/omap/blizzard.c b/drivers/video/omap/blizzard.c
index f5d75f2..2ffb34a 100644
--- a/drivers/video/omap/blizzard.c
+++ b/drivers/video/omap/blizzard.c
@@ -27,9 +27,9 @@
 #include <linux/clk.h>
 
 #include <plat/dma.h>
-#include <plat/omapfb.h>
 #include <plat/blizzard.h>
 
+#include "omapfb.h"
 #include "dispc.h"
 
 #define MODULE_NAME				"blizzard"
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
index 7c833db..c7c6455 100644
--- a/drivers/video/omap/dispc.c
+++ b/drivers/video/omap/dispc.c
@@ -24,11 +24,12 @@
 #include <linux/vmalloc.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/platform_device.h>
 
 #include <plat/sram.h>
-#include <plat/omapfb.h>
 #include <plat/board.h>
 
+#include "omapfb.h"
 #include "dispc.h"
 
 #define MODULE_NAME			"dispc"
@@ -188,6 +189,11 @@
 	struct omapfb_color_key	color_key;
 } dispc;
 
+static struct platform_device omapdss_device = {
+	.name		= "omapdss",
+	.id		= -1,
+};
+
 static void enable_lcd_clocks(int enable);
 
 static void inline dispc_write_reg(int idx, u32 val)
@@ -914,20 +920,20 @@
 
 static int get_dss_clocks(void)
 {
-	dispc.dss_ick = clk_get(dispc.fbdev->dev, "ick");
+	dispc.dss_ick = clk_get(&omapdss_device.dev, "ick");
 	if (IS_ERR(dispc.dss_ick)) {
 		dev_err(dispc.fbdev->dev, "can't get ick\n");
 		return PTR_ERR(dispc.dss_ick);
 	}
 
-	dispc.dss1_fck = clk_get(dispc.fbdev->dev, "dss1_fck");
+	dispc.dss1_fck = clk_get(&omapdss_device.dev, "dss1_fck");
 	if (IS_ERR(dispc.dss1_fck)) {
 		dev_err(dispc.fbdev->dev, "can't get dss1_fck\n");
 		clk_put(dispc.dss_ick);
 		return PTR_ERR(dispc.dss1_fck);
 	}
 
-	dispc.dss_54m_fck = clk_get(dispc.fbdev->dev, "tv_fck");
+	dispc.dss_54m_fck = clk_get(&omapdss_device.dev, "tv_fck");
 	if (IS_ERR(dispc.dss_54m_fck)) {
 		dev_err(dispc.fbdev->dev, "can't get tv_fck\n");
 		clk_put(dispc.dss_ick);
@@ -1379,6 +1385,12 @@
 	int skip_init = 0;
 	int i;
 
+	r = platform_device_register(&omapdss_device);
+	if (r) {
+		dev_err(fbdev->dev, "can't register omapdss device\n");
+		return r;
+	}
+
 	memset(&dispc, 0, sizeof(dispc));
 
 	dispc.base = ioremap(DISPC_BASE, SZ_1K);
@@ -1522,6 +1534,7 @@
 	free_irq(INT_24XX_DSS_IRQ, dispc.fbdev);
 	put_dss_clocks();
 	iounmap(dispc.base);
+	platform_device_unregister(&omapdss_device);
 }
 
 const struct lcd_ctrl omap2_int_ctrl = {
diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c
index 17a975e..0016f77 100644
--- a/drivers/video/omap/hwa742.c
+++ b/drivers/video/omap/hwa742.c
@@ -25,10 +25,11 @@
 #include <linux/fb.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
+#include <linux/interrupt.h>
 
 #include <plat/dma.h>
-#include <plat/omapfb.h>
 #include <plat/hwa742.h>
+#include "omapfb.h"
 
 #define HWA742_REV_CODE_REG       0x0
 #define HWA742_CONFIG_REG         0x2
diff --git a/drivers/video/omap/lcd_2430sdp.c b/drivers/video/omap/lcd_2430sdp.c
index fea7feee..760645d 100644
--- a/drivers/video/omap/lcd_2430sdp.c
+++ b/drivers/video/omap/lcd_2430sdp.c
@@ -28,9 +28,10 @@
 #include <linux/i2c/twl4030.h>
 
 #include <plat/mux.h>
-#include <plat/omapfb.h>
 #include <asm/mach-types.h>
 
+#include "omapfb.h"
+
 #define SDP2430_LCD_PANEL_BACKLIGHT_GPIO	91
 #define SDP2430_LCD_PANEL_ENABLE_GPIO		154
 #define SDP3430_LCD_PANEL_BACKLIGHT_GPIO	24
diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/omap/lcd_ams_delta.c
index 3d52772..567db6a 100644
--- a/drivers/video/omap/lcd_ams_delta.c
+++ b/drivers/video/omap/lcd_ams_delta.c
@@ -27,7 +27,8 @@
 
 #include <plat/board-ams-delta.h>
 #include <mach/hardware.h>
-#include <plat/omapfb.h>
+
+#include "omapfb.h"
 
 #define AMS_DELTA_DEFAULT_CONTRAST	112
 
@@ -123,12 +124,12 @@
 	},
 };
 
-static int ams_delta_panel_drv_init(void)
+static int __init ams_delta_panel_drv_init(void)
 {
 	return platform_driver_register(&ams_delta_panel_driver);
 }
 
-static void ams_delta_panel_drv_cleanup(void)
+static void __exit ams_delta_panel_drv_cleanup(void)
 {
 	platform_driver_unregister(&ams_delta_panel_driver);
 }
diff --git a/drivers/video/omap/lcd_apollon.c b/drivers/video/omap/lcd_apollon.c
index 4c5cefc..2be94eb 100644
--- a/drivers/video/omap/lcd_apollon.c
+++ b/drivers/video/omap/lcd_apollon.c
@@ -26,7 +26,8 @@
 
 #include <mach/gpio.h>
 #include <plat/mux.h>
-#include <plat/omapfb.h>
+
+#include "omapfb.h"
 
 /* #define USE_35INCH_LCD 1 */
 
diff --git a/drivers/video/omap/lcd_h3.c b/drivers/video/omap/lcd_h3.c
index 240b4fb..8df6887 100644
--- a/drivers/video/omap/lcd_h3.c
+++ b/drivers/video/omap/lcd_h3.c
@@ -24,7 +24,7 @@
 #include <linux/i2c/tps65010.h>
 
 #include <mach/gpio.h>
-#include <plat/omapfb.h>
+#include "omapfb.h"
 
 #define MODULE_NAME	"omapfb-lcd_h3"
 
diff --git a/drivers/video/omap/lcd_h4.c b/drivers/video/omap/lcd_h4.c
index 720625d..03a06a9 100644
--- a/drivers/video/omap/lcd_h4.c
+++ b/drivers/video/omap/lcd_h4.c
@@ -22,7 +22,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 
-#include <plat/omapfb.h>
+#include "omapfb.h"
 
 static int h4_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
 {
diff --git a/drivers/video/omap/lcd_htcherald.c b/drivers/video/omap/lcd_htcherald.c
index 2e0c81e..a9007c5 100644
--- a/drivers/video/omap/lcd_htcherald.c
+++ b/drivers/video/omap/lcd_htcherald.c
@@ -29,7 +29,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 
-#include <plat/omapfb.h>
+#include "omapfb.h"
 
 static int htcherald_panel_init(struct lcd_panel *panel,
 					struct omapfb_device *fbdev)
diff --git a/drivers/video/omap/lcd_inn1510.c b/drivers/video/omap/lcd_inn1510.c
index aafe9b4..3271f16 100644
--- a/drivers/video/omap/lcd_inn1510.c
+++ b/drivers/video/omap/lcd_inn1510.c
@@ -24,7 +24,7 @@
 #include <linux/io.h>
 
 #include <plat/fpga.h>
-#include <plat/omapfb.h>
+#include "omapfb.h"
 
 static int innovator1510_panel_init(struct lcd_panel *panel,
 				    struct omapfb_device *fbdev)
diff --git a/drivers/video/omap/lcd_inn1610.c b/drivers/video/omap/lcd_inn1610.c
index 0de3382..9fff86f 100644
--- a/drivers/video/omap/lcd_inn1610.c
+++ b/drivers/video/omap/lcd_inn1610.c
@@ -23,7 +23,7 @@
 #include <linux/platform_device.h>
 
 #include <mach/gpio.h>
-#include <plat/omapfb.h>
+#include "omapfb.h"
 
 #define MODULE_NAME	"omapfb-lcd_h3"
 
diff --git a/drivers/video/omap/lcd_ldp.c b/drivers/video/omap/lcd_ldp.c
index 6a260df..5bb7f6f 100644
--- a/drivers/video/omap/lcd_ldp.c
+++ b/drivers/video/omap/lcd_ldp.c
@@ -28,9 +28,10 @@
 
 #include <mach/gpio.h>
 #include <plat/mux.h>
-#include <plat/omapfb.h>
 #include <asm/mach-types.h>
 
+#include "omapfb.h"
+
 #define LCD_PANEL_BACKLIGHT_GPIO	(15 + OMAP_MAX_GPIO_LINES)
 #define LCD_PANEL_ENABLE_GPIO		(7 + OMAP_MAX_GPIO_LINES)
 
diff --git a/drivers/video/omap/lcd_mipid.c b/drivers/video/omap/lcd_mipid.c
index 2162eb0..abe1c76 100644
--- a/drivers/video/omap/lcd_mipid.c
+++ b/drivers/video/omap/lcd_mipid.c
@@ -23,9 +23,10 @@
 #include <linux/workqueue.h>
 #include <linux/spi/spi.h>
 
-#include <plat/omapfb.h>
 #include <plat/lcd_mipid.h>
 
+#include "omapfb.h"
+
 #define MIPID_MODULE_NAME		"lcd_mipid"
 
 #define MIPID_CMD_READ_DISP_ID		0x04
@@ -607,7 +608,7 @@
 	.remove	= __devexit_p(mipid_spi_remove),
 };
 
-static int mipid_drv_init(void)
+static int __init mipid_drv_init(void)
 {
 	spi_register_driver(&mipid_spi_driver);
 
@@ -615,7 +616,7 @@
 }
 module_init(mipid_drv_init);
 
-static void mipid_drv_cleanup(void)
+static void __exit mipid_drv_cleanup(void)
 {
 	spi_unregister_driver(&mipid_spi_driver);
 }
diff --git a/drivers/video/omap/lcd_omap2evm.c b/drivers/video/omap/lcd_omap2evm.c
index e1a38ab..006c2fe 100644
--- a/drivers/video/omap/lcd_omap2evm.c
+++ b/drivers/video/omap/lcd_omap2evm.c
@@ -27,9 +27,10 @@
 #include <linux/i2c/twl4030.h>
 
 #include <plat/mux.h>
-#include <plat/omapfb.h>
 #include <asm/mach-types.h>
 
+#include "omapfb.h"
+
 #define LCD_PANEL_ENABLE_GPIO	154
 #define LCD_PANEL_LR		128
 #define LCD_PANEL_UD		129
diff --git a/drivers/video/omap/lcd_omap3beagle.c b/drivers/video/omap/lcd_omap3beagle.c
index ccec084..fc503d8 100644
--- a/drivers/video/omap/lcd_omap3beagle.c
+++ b/drivers/video/omap/lcd_omap3beagle.c
@@ -26,9 +26,11 @@
 #include <linux/i2c/twl4030.h>
 
 #include <plat/mux.h>
-#include <plat/omapfb.h>
+#include <plat/mux.h>
 #include <asm/mach-types.h>
 
+#include "omapfb.h"
+
 #define LCD_PANEL_ENABLE_GPIO       170
 
 static int omap3beagle_panel_init(struct lcd_panel *panel,
diff --git a/drivers/video/omap/lcd_omap3evm.c b/drivers/video/omap/lcd_omap3evm.c
index 556eb31..ae2edc4 100644
--- a/drivers/video/omap/lcd_omap3evm.c
+++ b/drivers/video/omap/lcd_omap3evm.c
@@ -26,9 +26,10 @@
 #include <linux/i2c/twl4030.h>
 
 #include <plat/mux.h>
-#include <plat/omapfb.h>
 #include <asm/mach-types.h>
 
+#include "omapfb.h"
+
 #define LCD_PANEL_ENABLE_GPIO       153
 #define LCD_PANEL_LR                2
 #define LCD_PANEL_UD                3
diff --git a/drivers/video/omap/lcd_osk.c b/drivers/video/omap/lcd_osk.c
index bb21d7d..b87e8b8 100644
--- a/drivers/video/omap/lcd_osk.c
+++ b/drivers/video/omap/lcd_osk.c
@@ -25,7 +25,7 @@
 
 #include <mach/gpio.h>
 #include <plat/mux.h>
-#include <plat/omapfb.h>
+#include "omapfb.h"
 
 static int osk_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
 {
diff --git a/drivers/video/omap/lcd_overo.c b/drivers/video/omap/lcd_overo.c
index b0f86e5..56ee192 100644
--- a/drivers/video/omap/lcd_overo.c
+++ b/drivers/video/omap/lcd_overo.c
@@ -25,9 +25,10 @@
 
 #include <mach/gpio.h>
 #include <plat/mux.h>
-#include <plat/omapfb.h>
 #include <asm/mach-types.h>
 
+#include "omapfb.h"
+
 #define LCD_ENABLE       144
 
 static int overo_panel_init(struct lcd_panel *panel,
diff --git a/drivers/video/omap/lcd_palmte.c b/drivers/video/omap/lcd_palmte.c
index d302896..4cb3017 100644
--- a/drivers/video/omap/lcd_palmte.c
+++ b/drivers/video/omap/lcd_palmte.c
@@ -24,7 +24,7 @@
 #include <linux/io.h>
 
 #include <plat/fpga.h>
-#include <plat/omapfb.h>
+#include "omapfb.h"
 
 static int palmte_panel_init(struct lcd_panel *panel,
 				struct omapfb_device *fbdev)
diff --git a/drivers/video/omap/lcd_palmtt.c b/drivers/video/omap/lcd_palmtt.c
index 557424f..ff0e6d7 100644
--- a/drivers/video/omap/lcd_palmtt.c
+++ b/drivers/video/omap/lcd_palmtt.c
@@ -30,7 +30,7 @@
 #include <linux/io.h>
 
 #include <mach/gpio.h>
-#include <plat/omapfb.h>
+#include "omapfb.h"
 
 static int palmtt_panel_init(struct lcd_panel *panel,
 	struct omapfb_device *fbdev)
diff --git a/drivers/video/omap/lcd_palmz71.c b/drivers/video/omap/lcd_palmz71.c
index 5f4b5b2c..2334e56 100644
--- a/drivers/video/omap/lcd_palmz71.c
+++ b/drivers/video/omap/lcd_palmz71.c
@@ -24,7 +24,7 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 
-#include <plat/omapfb.h>
+#include "omapfb.h"
 
 static int palmz71_panel_init(struct lcd_panel *panel,
 			      struct omapfb_device *fbdev)
diff --git a/drivers/video/omap/lcdc.c b/drivers/video/omap/lcdc.c
index 5f32caf..b831e1d 100644
--- a/drivers/video/omap/lcdc.c
+++ b/drivers/video/omap/lcdc.c
@@ -30,10 +30,11 @@
 #include <linux/clk.h>
 
 #include <plat/dma.h>
-#include <plat/omapfb.h>
 
 #include <asm/mach-types.h>
 
+#include "omapfb.h"
+
 #include "lcdc.h"
 
 #define MODULE_NAME			"lcdc"
diff --git a/drivers/video/omap/omapfb.h b/drivers/video/omap/omapfb.h
new file mode 100644
index 0000000..46e4714
--- /dev/null
+++ b/drivers/video/omap/omapfb.h
@@ -0,0 +1,227 @@
+/*
+ * File: drivers/video/omap/omapfb.h
+ *
+ * Framebuffer driver for TI OMAP boards
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Author: Imre Deak <imre.deak@nokia.com>
+ *
+ * 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.,
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef __OMAPFB_H
+#define __OMAPFB_H
+
+#include <linux/fb.h>
+#include <linux/mutex.h>
+#include <linux/omapfb.h>
+
+#define OMAPFB_EVENT_READY	1
+#define OMAPFB_EVENT_DISABLED	2
+
+#define OMAP_LCDC_INV_VSYNC             0x0001
+#define OMAP_LCDC_INV_HSYNC             0x0002
+#define OMAP_LCDC_INV_PIX_CLOCK         0x0004
+#define OMAP_LCDC_INV_OUTPUT_EN         0x0008
+#define OMAP_LCDC_HSVS_RISING_EDGE      0x0010
+#define OMAP_LCDC_HSVS_OPPOSITE         0x0020
+
+#define OMAP_LCDC_SIGNAL_MASK		0x003f
+
+#define OMAP_LCDC_PANEL_TFT		0x0100
+
+#define OMAPFB_PLANE_XRES_MIN		8
+#define OMAPFB_PLANE_YRES_MIN		8
+
+struct omapfb_device;
+
+struct lcd_panel {
+	const char	*name;
+	int		config;		/* TFT/STN, signal inversion */
+	int		bpp;		/* Pixel format in fb mem */
+	int		data_lines;	/* Lines on LCD HW interface */
+
+	int		x_res, y_res;
+	int		pixel_clock;	/* In kHz */
+	int		hsw;		/* Horizontal synchronization
+					   pulse width */
+	int		hfp;		/* Horizontal front porch */
+	int		hbp;		/* Horizontal back porch */
+	int		vsw;		/* Vertical synchronization
+					   pulse width */
+	int		vfp;		/* Vertical front porch */
+	int		vbp;		/* Vertical back porch */
+	int		acb;		/* ac-bias pin frequency */
+	int		pcd;		/* pixel clock divider.
+					   Obsolete use pixel_clock instead */
+
+	int		(*init)		(struct lcd_panel *panel,
+					 struct omapfb_device *fbdev);
+	void		(*cleanup)	(struct lcd_panel *panel);
+	int		(*enable)	(struct lcd_panel *panel);
+	void		(*disable)	(struct lcd_panel *panel);
+	unsigned long	(*get_caps)	(struct lcd_panel *panel);
+	int		(*set_bklight_level)(struct lcd_panel *panel,
+					     unsigned int level);
+	unsigned int	(*get_bklight_level)(struct lcd_panel *panel);
+	unsigned int	(*get_bklight_max)  (struct lcd_panel *panel);
+	int		(*run_test)	(struct lcd_panel *panel, int test_num);
+};
+
+struct extif_timings {
+	int cs_on_time;
+	int cs_off_time;
+	int we_on_time;
+	int we_off_time;
+	int re_on_time;
+	int re_off_time;
+	int we_cycle_time;
+	int re_cycle_time;
+	int cs_pulse_width;
+	int access_time;
+
+	int clk_div;
+
+	u32 tim[5];		/* set by extif->convert_timings */
+
+	int converted;
+};
+
+struct lcd_ctrl_extif {
+	int  (*init)		(struct omapfb_device *fbdev);
+	void (*cleanup)		(void);
+	void (*get_clk_info)	(u32 *clk_period, u32 *max_clk_div);
+	unsigned long (*get_max_tx_rate)(void);
+	int  (*convert_timings)	(struct extif_timings *timings);
+	void (*set_timings)	(const struct extif_timings *timings);
+	void (*set_bits_per_cycle)(int bpc);
+	void (*write_command)	(const void *buf, unsigned int len);
+	void (*read_data)	(void *buf, unsigned int len);
+	void (*write_data)	(const void *buf, unsigned int len);
+	void (*transfer_area)	(int width, int height,
+				 void (callback)(void *data), void *data);
+	int  (*setup_tearsync)	(unsigned pin_cnt,
+				 unsigned hs_pulse_time, unsigned vs_pulse_time,
+				 int hs_pol_inv, int vs_pol_inv, int div);
+	int  (*enable_tearsync) (int enable, unsigned line);
+
+	unsigned long		max_transmit_size;
+};
+
+struct omapfb_notifier_block {
+	struct notifier_block	nb;
+	void			*data;
+	int			plane_idx;
+};
+
+typedef int (*omapfb_notifier_callback_t)(struct notifier_block *,
+					  unsigned long event,
+					  void *fbi);
+
+struct lcd_ctrl {
+	const char	*name;
+	void		*data;
+
+	int		(*init)		  (struct omapfb_device *fbdev,
+					   int ext_mode,
+					   struct omapfb_mem_desc *req_md);
+	void		(*cleanup)	  (void);
+	void		(*bind_client)	  (struct omapfb_notifier_block *nb);
+	void		(*get_caps)	  (int plane, struct omapfb_caps *caps);
+	int		(*set_update_mode)(enum omapfb_update_mode mode);
+	enum omapfb_update_mode (*get_update_mode)(void);
+	int		(*setup_plane)	  (int plane, int channel_out,
+					   unsigned long offset,
+					   int screen_width,
+					   int pos_x, int pos_y, int width,
+					   int height, int color_mode);
+	int		(*set_rotate)	  (int angle);
+	int		(*setup_mem)	  (int plane, size_t size,
+					   int mem_type, unsigned long *paddr);
+	int		(*mmap)		  (struct fb_info *info,
+					   struct vm_area_struct *vma);
+	int		(*set_scale)	  (int plane,
+					   int orig_width, int orig_height,
+					   int out_width, int out_height);
+	int		(*enable_plane)	  (int plane, int enable);
+	int		(*update_window)  (struct fb_info *fbi,
+					   struct omapfb_update_window *win,
+					   void (*callback)(void *),
+					   void *callback_data);
+	void		(*sync)		  (void);
+	void		(*suspend)	  (void);
+	void		(*resume)	  (void);
+	int		(*run_test)	  (int test_num);
+	int		(*setcolreg)	  (u_int regno, u16 red, u16 green,
+					   u16 blue, u16 transp,
+					   int update_hw_mem);
+	int		(*set_color_key)  (struct omapfb_color_key *ck);
+	int		(*get_color_key)  (struct omapfb_color_key *ck);
+};
+
+enum omapfb_state {
+	OMAPFB_DISABLED		= 0,
+	OMAPFB_SUSPENDED	= 99,
+	OMAPFB_ACTIVE		= 100
+};
+
+struct omapfb_plane_struct {
+	int				idx;
+	struct omapfb_plane_info	info;
+	enum omapfb_color_format	color_mode;
+	struct omapfb_device		*fbdev;
+};
+
+struct omapfb_device {
+	int			state;
+	int                     ext_lcdc;		/* Using external
+							   LCD controller */
+	struct mutex		rqueue_mutex;
+
+	int			palette_size;
+	u32			pseudo_palette[17];
+
+	struct lcd_panel	*panel;			/* LCD panel */
+	const struct lcd_ctrl	*ctrl;			/* LCD controller */
+	const struct lcd_ctrl	*int_ctrl;		/* internal LCD ctrl */
+	struct lcd_ctrl_extif	*ext_if;		/* LCD ctrl external
+							   interface */
+	struct device		*dev;
+	struct fb_var_screeninfo	new_var;	/* for mode changes */
+
+	struct omapfb_mem_desc		mem_desc;
+	struct fb_info			*fb_info[OMAPFB_PLANE_NUM];
+};
+
+#ifdef CONFIG_ARCH_OMAP1
+extern struct lcd_ctrl omap1_lcd_ctrl;
+#else
+extern struct lcd_ctrl omap2_disp_ctrl;
+#endif
+
+extern void omapfb_register_panel(struct lcd_panel *panel);
+extern void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval);
+extern void omapfb_notify_clients(struct omapfb_device *fbdev,
+				  unsigned long event);
+extern int  omapfb_register_client(struct omapfb_notifier_block *nb,
+				   omapfb_notifier_callback_t callback,
+				   void *callback_data);
+extern int  omapfb_unregister_client(struct omapfb_notifier_block *nb);
+extern int  omapfb_update_window_async(struct fb_info *fbi,
+				       struct omapfb_update_window *win,
+				       void (*callback)(void *),
+				       void *callback_data);
+
+#endif /* __OMAPFB_H */
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index f900a43..c7f59a5 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -29,8 +29,8 @@
 #include <linux/uaccess.h>
 
 #include <plat/dma.h>
-#include <plat/omapfb.h>
 
+#include "omapfb.h"
 #include "lcdc.h"
 #include "dispc.h"
 
diff --git a/drivers/video/omap/rfbi.c b/drivers/video/omap/rfbi.c
index c90fa39..fed7b1b 100644
--- a/drivers/video/omap/rfbi.c
+++ b/drivers/video/omap/rfbi.c
@@ -27,8 +27,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 
-#include <plat/omapfb.h>
-
+#include "omapfb.h"
 #include "dispc.h"
 
 /* To work around an RFBI transfer rate limitation */
diff --git a/drivers/video/omap/sossi.c b/drivers/video/omap/sossi.c
index 79dc84f..8fb7c70 100644
--- a/drivers/video/omap/sossi.c
+++ b/drivers/video/omap/sossi.c
@@ -23,10 +23,11 @@
 #include <linux/clk.h>
 #include <linux/irq.h>
 #include <linux/io.h>
+#include <linux/interrupt.h>
 
 #include <plat/dma.h>
-#include <plat/omapfb.h>
 
+#include "omapfb.h"
 #include "lcdc.h"
 
 #define MODULE_NAME		"omapfb-sossi"
diff --git a/drivers/video/omap2/Kconfig b/drivers/video/omap2/Kconfig
new file mode 100644
index 0000000..d877c36
--- /dev/null
+++ b/drivers/video/omap2/Kconfig
@@ -0,0 +1,9 @@
+config OMAP2_VRAM
+	bool
+
+config OMAP2_VRFB
+	bool
+
+source "drivers/video/omap2/dss/Kconfig"
+source "drivers/video/omap2/omapfb/Kconfig"
+source "drivers/video/omap2/displays/Kconfig"
diff --git a/drivers/video/omap2/Makefile b/drivers/video/omap2/Makefile
new file mode 100644
index 0000000..d853d05
--- /dev/null
+++ b/drivers/video/omap2/Makefile
@@ -0,0 +1,6 @@
+obj-$(CONFIG_OMAP2_VRAM) += vram.o
+obj-$(CONFIG_OMAP2_VRFB) += vrfb.o
+
+obj-y += dss/
+obj-y += omapfb/
+obj-y += displays/
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
new file mode 100644
index 0000000..b12a59c
--- /dev/null
+++ b/drivers/video/omap2/displays/Kconfig
@@ -0,0 +1,22 @@
+menu "OMAP2/3 Display Device Drivers"
+        depends on OMAP2_DSS
+
+config PANEL_GENERIC
+        tristate "Generic Panel"
+        help
+	  Generic panel driver.
+	  Used for DVI output for Beagle and OMAP3 SDP.
+
+config PANEL_SHARP_LS037V7DW01
+        tristate "Sharp LS037V7DW01 LCD Panel"
+        depends on OMAP2_DSS
+        help
+          LCD Panel used in TI's SDP3430 and EVM boards
+
+config PANEL_TAAL
+        tristate "Taal DSI Panel"
+        depends on OMAP2_DSS_DSI
+        help
+          Taal DSI command mode panel from TPO.
+
+endmenu
diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile
new file mode 100644
index 0000000..9556464
--- /dev/null
+++ b/drivers/video/omap2/displays/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_PANEL_GENERIC) += panel-generic.o
+obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
+
+obj-$(CONFIG_PANEL_TAAL) += panel-taal.o
diff --git a/drivers/video/omap2/displays/panel-generic.c b/drivers/video/omap2/displays/panel-generic.c
new file mode 100644
index 0000000..eb48d1a
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-generic.c
@@ -0,0 +1,104 @@
+/*
+ * Generic panel support
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+
+#include <plat/display.h>
+
+static struct omap_video_timings generic_panel_timings = {
+	/* 640 x 480 @ 60 Hz  Reduced blanking VESA CVT 0.31M3-R */
+	.x_res		= 640,
+	.y_res		= 480,
+	.pixel_clock	= 23500,
+	.hfp		= 48,
+	.hsw		= 32,
+	.hbp		= 80,
+	.vfp		= 3,
+	.vsw		= 4,
+	.vbp		= 7,
+};
+
+static int generic_panel_probe(struct omap_dss_device *dssdev)
+{
+	dssdev->panel.config = OMAP_DSS_LCD_TFT;
+	dssdev->panel.timings = generic_panel_timings;
+
+	return 0;
+}
+
+static void generic_panel_remove(struct omap_dss_device *dssdev)
+{
+}
+
+static int generic_panel_enable(struct omap_dss_device *dssdev)
+{
+	int r = 0;
+
+	if (dssdev->platform_enable)
+		r = dssdev->platform_enable(dssdev);
+
+	return r;
+}
+
+static void generic_panel_disable(struct omap_dss_device *dssdev)
+{
+	if (dssdev->platform_disable)
+		dssdev->platform_disable(dssdev);
+}
+
+static int generic_panel_suspend(struct omap_dss_device *dssdev)
+{
+	generic_panel_disable(dssdev);
+	return 0;
+}
+
+static int generic_panel_resume(struct omap_dss_device *dssdev)
+{
+	return generic_panel_enable(dssdev);
+}
+
+static struct omap_dss_driver generic_driver = {
+	.probe		= generic_panel_probe,
+	.remove		= generic_panel_remove,
+
+	.enable		= generic_panel_enable,
+	.disable	= generic_panel_disable,
+	.suspend	= generic_panel_suspend,
+	.resume		= generic_panel_resume,
+
+	.driver         = {
+		.name   = "generic_panel",
+		.owner  = THIS_MODULE,
+	},
+};
+
+static int __init generic_panel_drv_init(void)
+{
+	return omap_dss_register_driver(&generic_driver);
+}
+
+static void __exit generic_panel_drv_exit(void)
+{
+	omap_dss_unregister_driver(&generic_driver);
+}
+
+module_init(generic_panel_drv_init);
+module_exit(generic_panel_drv_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
new file mode 100644
index 0000000..bbe880bb
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
@@ -0,0 +1,153 @@
+/*
+ * LCD panel driver for Sharp LS037V7DW01
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/err.h>
+
+#include <plat/display.h>
+
+struct sharp_data {
+	/* XXX This regulator should actually be in SDP board file, not here,
+	 * as it doesn't actually power the LCD, but something else that
+	 * affects the output to LCD (I think. Somebody clarify). It doesn't do
+	 * harm here, as SDP is the only board using this currently */
+	struct regulator *vdvi_reg;
+};
+
+static struct omap_video_timings sharp_ls_timings = {
+	.x_res = 480,
+	.y_res = 640,
+
+	.pixel_clock	= 19200,
+
+	.hsw		= 2,
+	.hfp		= 1,
+	.hbp		= 28,
+
+	.vsw		= 1,
+	.vfp		= 1,
+	.vbp		= 1,
+};
+
+static int sharp_ls_panel_probe(struct omap_dss_device *dssdev)
+{
+	struct sharp_data *sd;
+
+	dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
+		OMAP_DSS_LCD_IHS;
+	dssdev->panel.acb = 0x28;
+	dssdev->panel.timings = sharp_ls_timings;
+
+	sd = kzalloc(sizeof(*sd), GFP_KERNEL);
+	if (!sd)
+		return -ENOMEM;
+
+	dev_set_drvdata(&dssdev->dev, sd);
+
+	sd->vdvi_reg = regulator_get(&dssdev->dev, "vdvi");
+	if (IS_ERR(sd->vdvi_reg)) {
+		kfree(sd);
+		pr_err("failed to get VDVI regulator\n");
+		return PTR_ERR(sd->vdvi_reg);
+	}
+
+	return 0;
+}
+
+static void sharp_ls_panel_remove(struct omap_dss_device *dssdev)
+{
+	struct sharp_data *sd = dev_get_drvdata(&dssdev->dev);
+
+	regulator_put(sd->vdvi_reg);
+
+	kfree(sd);
+}
+
+static int sharp_ls_panel_enable(struct omap_dss_device *dssdev)
+{
+	struct sharp_data *sd = dev_get_drvdata(&dssdev->dev);
+	int r = 0;
+
+	/* wait couple of vsyncs until enabling the LCD */
+	msleep(50);
+
+	regulator_enable(sd->vdvi_reg);
+
+	if (dssdev->platform_enable)
+		r = dssdev->platform_enable(dssdev);
+
+	return r;
+}
+
+static void sharp_ls_panel_disable(struct omap_dss_device *dssdev)
+{
+	struct sharp_data *sd = dev_get_drvdata(&dssdev->dev);
+
+	if (dssdev->platform_disable)
+		dssdev->platform_disable(dssdev);
+
+	regulator_disable(sd->vdvi_reg);
+
+	/* wait at least 5 vsyncs after disabling the LCD */
+
+	msleep(100);
+}
+
+static int sharp_ls_panel_suspend(struct omap_dss_device *dssdev)
+{
+	sharp_ls_panel_disable(dssdev);
+	return 0;
+}
+
+static int sharp_ls_panel_resume(struct omap_dss_device *dssdev)
+{
+	return sharp_ls_panel_enable(dssdev);
+}
+
+static struct omap_dss_driver sharp_ls_driver = {
+	.probe		= sharp_ls_panel_probe,
+	.remove		= sharp_ls_panel_remove,
+
+	.enable		= sharp_ls_panel_enable,
+	.disable	= sharp_ls_panel_disable,
+	.suspend	= sharp_ls_panel_suspend,
+	.resume		= sharp_ls_panel_resume,
+
+	.driver         = {
+		.name   = "sharp_ls_panel",
+		.owner  = THIS_MODULE,
+	},
+};
+
+static int __init sharp_ls_panel_drv_init(void)
+{
+	return omap_dss_register_driver(&sharp_ls_driver);
+}
+
+static void __exit sharp_ls_panel_drv_exit(void)
+{
+	omap_dss_unregister_driver(&sharp_ls_driver);
+}
+
+module_init(sharp_ls_panel_drv_init);
+module_exit(sharp_ls_panel_drv_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
new file mode 100644
index 0000000..1f01dfc
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -0,0 +1,1003 @@
+/*
+ * Taal DSI command mode panel
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*#define DEBUG*/
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/jiffies.h>
+#include <linux/sched.h>
+#include <linux/backlight.h>
+#include <linux/fb.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/completion.h>
+#include <linux/workqueue.h>
+
+#include <plat/display.h>
+
+/* DSI Virtual channel. Hardcoded for now. */
+#define TCH 0
+
+#define DCS_READ_NUM_ERRORS	0x05
+#define DCS_READ_POWER_MODE	0x0a
+#define DCS_READ_MADCTL		0x0b
+#define DCS_READ_PIXEL_FORMAT	0x0c
+#define DCS_RDDSDR		0x0f
+#define DCS_SLEEP_IN		0x10
+#define DCS_SLEEP_OUT		0x11
+#define DCS_DISPLAY_OFF		0x28
+#define DCS_DISPLAY_ON		0x29
+#define DCS_COLUMN_ADDR		0x2a
+#define DCS_PAGE_ADDR		0x2b
+#define DCS_MEMORY_WRITE	0x2c
+#define DCS_TEAR_OFF		0x34
+#define DCS_TEAR_ON		0x35
+#define DCS_MEM_ACC_CTRL	0x36
+#define DCS_PIXEL_FORMAT	0x3a
+#define DCS_BRIGHTNESS		0x51
+#define DCS_CTRL_DISPLAY	0x53
+#define DCS_WRITE_CABC		0x55
+#define DCS_READ_CABC		0x56
+#define DCS_GET_ID1		0xda
+#define DCS_GET_ID2		0xdb
+#define DCS_GET_ID3		0xdc
+
+/* #define TAAL_USE_ESD_CHECK */
+#define TAAL_ESD_CHECK_PERIOD	msecs_to_jiffies(5000)
+
+struct taal_data {
+	struct backlight_device *bldev;
+
+	unsigned long	hw_guard_end;	/* next value of jiffies when we can
+					 * issue the next sleep in/out command
+					 */
+	unsigned long	hw_guard_wait;	/* max guard time in jiffies */
+
+	struct omap_dss_device *dssdev;
+
+	bool enabled;
+	u8 rotate;
+	bool mirror;
+
+	bool te_enabled;
+	bool use_ext_te;
+	struct completion te_completion;
+
+	bool use_dsi_bl;
+
+	bool cabc_broken;
+	unsigned cabc_mode;
+
+	bool intro_printed;
+
+	struct workqueue_struct *esd_wq;
+	struct delayed_work esd_work;
+};
+
+static void taal_esd_work(struct work_struct *work);
+
+static void hw_guard_start(struct taal_data *td, int guard_msec)
+{
+	td->hw_guard_wait = msecs_to_jiffies(guard_msec);
+	td->hw_guard_end = jiffies + td->hw_guard_wait;
+}
+
+static void hw_guard_wait(struct taal_data *td)
+{
+	unsigned long wait = td->hw_guard_end - jiffies;
+
+	if ((long)wait > 0 && wait <= td->hw_guard_wait) {
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(wait);
+	}
+}
+
+static int taal_dcs_read_1(u8 dcs_cmd, u8 *data)
+{
+	int r;
+	u8 buf[1];
+
+	r = dsi_vc_dcs_read(TCH, dcs_cmd, buf, 1);
+
+	if (r < 0)
+		return r;
+
+	*data = buf[0];
+
+	return 0;
+}
+
+static int taal_dcs_write_0(u8 dcs_cmd)
+{
+	return dsi_vc_dcs_write(TCH, &dcs_cmd, 1);
+}
+
+static int taal_dcs_write_1(u8 dcs_cmd, u8 param)
+{
+	u8 buf[2];
+	buf[0] = dcs_cmd;
+	buf[1] = param;
+	return dsi_vc_dcs_write(TCH, buf, 2);
+}
+
+static int taal_sleep_in(struct taal_data *td)
+
+{
+	u8 cmd;
+	int r;
+
+	hw_guard_wait(td);
+
+	cmd = DCS_SLEEP_IN;
+	r = dsi_vc_dcs_write_nosync(TCH, &cmd, 1);
+	if (r)
+		return r;
+
+	hw_guard_start(td, 120);
+
+	msleep(5);
+
+	return 0;
+}
+
+static int taal_sleep_out(struct taal_data *td)
+{
+	int r;
+
+	hw_guard_wait(td);
+
+	r = taal_dcs_write_0(DCS_SLEEP_OUT);
+	if (r)
+		return r;
+
+	hw_guard_start(td, 120);
+
+	msleep(5);
+
+	return 0;
+}
+
+static int taal_get_id(u8 *id1, u8 *id2, u8 *id3)
+{
+	int r;
+
+	r = taal_dcs_read_1(DCS_GET_ID1, id1);
+	if (r)
+		return r;
+	r = taal_dcs_read_1(DCS_GET_ID2, id2);
+	if (r)
+		return r;
+	r = taal_dcs_read_1(DCS_GET_ID3, id3);
+	if (r)
+		return r;
+
+	return 0;
+}
+
+static int taal_set_addr_mode(u8 rotate, bool mirror)
+{
+	int r;
+	u8 mode;
+	int b5, b6, b7;
+
+	r = taal_dcs_read_1(DCS_READ_MADCTL, &mode);
+	if (r)
+		return r;
+
+	switch (rotate) {
+	default:
+	case 0:
+		b7 = 0;
+		b6 = 0;
+		b5 = 0;
+		break;
+	case 1:
+		b7 = 0;
+		b6 = 1;
+		b5 = 1;
+		break;
+	case 2:
+		b7 = 1;
+		b6 = 1;
+		b5 = 0;
+		break;
+	case 3:
+		b7 = 1;
+		b6 = 0;
+		b5 = 1;
+		break;
+	}
+
+	if (mirror)
+		b6 = !b6;
+
+	mode &= ~((1<<7) | (1<<6) | (1<<5));
+	mode |= (b7 << 7) | (b6 << 6) | (b5 << 5);
+
+	return taal_dcs_write_1(DCS_MEM_ACC_CTRL, mode);
+}
+
+static int taal_set_update_window(u16 x, u16 y, u16 w, u16 h)
+{
+	int r;
+	u16 x1 = x;
+	u16 x2 = x + w - 1;
+	u16 y1 = y;
+	u16 y2 = y + h - 1;
+
+	u8 buf[5];
+	buf[0] = DCS_COLUMN_ADDR;
+	buf[1] = (x1 >> 8) & 0xff;
+	buf[2] = (x1 >> 0) & 0xff;
+	buf[3] = (x2 >> 8) & 0xff;
+	buf[4] = (x2 >> 0) & 0xff;
+
+	r = dsi_vc_dcs_write_nosync(TCH, buf, sizeof(buf));
+	if (r)
+		return r;
+
+	buf[0] = DCS_PAGE_ADDR;
+	buf[1] = (y1 >> 8) & 0xff;
+	buf[2] = (y1 >> 0) & 0xff;
+	buf[3] = (y2 >> 8) & 0xff;
+	buf[4] = (y2 >> 0) & 0xff;
+
+	r = dsi_vc_dcs_write_nosync(TCH, buf, sizeof(buf));
+	if (r)
+		return r;
+
+	dsi_vc_send_bta_sync(TCH);
+
+	return r;
+}
+
+static int taal_bl_update_status(struct backlight_device *dev)
+{
+	struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
+	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	int r;
+	int level;
+
+	if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
+			dev->props.power == FB_BLANK_UNBLANK)
+		level = dev->props.brightness;
+	else
+		level = 0;
+
+	dev_dbg(&dssdev->dev, "update brightness to %d\n", level);
+
+	if (td->use_dsi_bl) {
+		if (td->enabled) {
+			dsi_bus_lock();
+			r = taal_dcs_write_1(DCS_BRIGHTNESS, level);
+			dsi_bus_unlock();
+			if (r)
+				return r;
+		}
+	} else {
+		if (!dssdev->set_backlight)
+			return -EINVAL;
+
+		r = dssdev->set_backlight(dssdev, level);
+		if (r)
+			return r;
+	}
+
+	return 0;
+}
+
+static int taal_bl_get_intensity(struct backlight_device *dev)
+{
+	if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
+			dev->props.power == FB_BLANK_UNBLANK)
+		return dev->props.brightness;
+
+	return 0;
+}
+
+static struct backlight_ops taal_bl_ops = {
+	.get_brightness = taal_bl_get_intensity,
+	.update_status  = taal_bl_update_status,
+};
+
+static void taal_get_timings(struct omap_dss_device *dssdev,
+			struct omap_video_timings *timings)
+{
+	*timings = dssdev->panel.timings;
+}
+
+static void taal_get_resolution(struct omap_dss_device *dssdev,
+		u16 *xres, u16 *yres)
+{
+	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+
+	if (td->rotate == 0 || td->rotate == 2) {
+		*xres = dssdev->panel.timings.x_res;
+		*yres = dssdev->panel.timings.y_res;
+	} else {
+		*yres = dssdev->panel.timings.x_res;
+		*xres = dssdev->panel.timings.y_res;
+	}
+}
+
+static irqreturn_t taal_te_isr(int irq, void *data)
+{
+	struct omap_dss_device *dssdev = data;
+	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+
+	complete_all(&td->te_completion);
+
+	return IRQ_HANDLED;
+}
+
+static ssize_t taal_num_errors_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	u8 errors;
+	int r;
+
+	if (td->enabled) {
+		dsi_bus_lock();
+		r = taal_dcs_read_1(DCS_READ_NUM_ERRORS, &errors);
+		dsi_bus_unlock();
+	} else {
+		r = -ENODEV;
+	}
+
+	if (r)
+		return r;
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", errors);
+}
+
+static ssize_t taal_hw_revision_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	u8 id1, id2, id3;
+	int r;
+
+	if (td->enabled) {
+		dsi_bus_lock();
+		r = taal_get_id(&id1, &id2, &id3);
+		dsi_bus_unlock();
+	} else {
+		r = -ENODEV;
+	}
+
+	if (r)
+		return r;
+
+	return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x\n", id1, id2, id3);
+}
+
+static const char *cabc_modes[] = {
+	"off",		/* used also always when CABC is not supported */
+	"ui",
+	"still-image",
+	"moving-image",
+};
+
+static ssize_t show_cabc_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	const char *mode_str;
+	int mode;
+	int len;
+
+	mode = td->cabc_mode;
+
+	mode_str = "unknown";
+	if (mode >= 0 && mode < ARRAY_SIZE(cabc_modes))
+		mode_str = cabc_modes[mode];
+	len = snprintf(buf, PAGE_SIZE, "%s\n", mode_str);
+
+	return len < PAGE_SIZE - 1 ? len : PAGE_SIZE - 1;
+}
+
+static ssize_t store_cabc_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(cabc_modes); i++) {
+		if (sysfs_streq(cabc_modes[i], buf))
+			break;
+	}
+
+	if (i == ARRAY_SIZE(cabc_modes))
+		return -EINVAL;
+
+	if (td->enabled) {
+		dsi_bus_lock();
+		if (!td->cabc_broken)
+			taal_dcs_write_1(DCS_WRITE_CABC, i);
+		dsi_bus_unlock();
+	}
+
+	td->cabc_mode = i;
+
+	return count;
+}
+
+static ssize_t show_cabc_available_modes(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int len;
+	int i;
+
+	for (i = 0, len = 0;
+	     len < PAGE_SIZE && i < ARRAY_SIZE(cabc_modes); i++)
+		len += snprintf(&buf[len], PAGE_SIZE - len, "%s%s%s",
+			i ? " " : "", cabc_modes[i],
+			i == ARRAY_SIZE(cabc_modes) - 1 ? "\n" : "");
+
+	return len < PAGE_SIZE ? len : PAGE_SIZE - 1;
+}
+
+static DEVICE_ATTR(num_dsi_errors, S_IRUGO, taal_num_errors_show, NULL);
+static DEVICE_ATTR(hw_revision, S_IRUGO, taal_hw_revision_show, NULL);
+static DEVICE_ATTR(cabc_mode, S_IRUGO | S_IWUSR,
+		show_cabc_mode, store_cabc_mode);
+static DEVICE_ATTR(cabc_available_modes, S_IRUGO,
+		show_cabc_available_modes, NULL);
+
+static struct attribute *taal_attrs[] = {
+	&dev_attr_num_dsi_errors.attr,
+	&dev_attr_hw_revision.attr,
+	&dev_attr_cabc_mode.attr,
+	&dev_attr_cabc_available_modes.attr,
+	NULL,
+};
+
+static struct attribute_group taal_attr_group = {
+	.attrs = taal_attrs,
+};
+
+static int taal_probe(struct omap_dss_device *dssdev)
+{
+	struct taal_data *td;
+	struct backlight_device *bldev;
+	int r;
+
+	const struct omap_video_timings taal_panel_timings = {
+		.x_res		= 864,
+		.y_res		= 480,
+	};
+
+	dev_dbg(&dssdev->dev, "probe\n");
+
+	dssdev->panel.config = OMAP_DSS_LCD_TFT;
+	dssdev->panel.timings = taal_panel_timings;
+	dssdev->ctrl.pixel_size = 24;
+
+	td = kzalloc(sizeof(*td), GFP_KERNEL);
+	if (!td) {
+		r = -ENOMEM;
+		goto err0;
+	}
+	td->dssdev = dssdev;
+
+	td->esd_wq = create_singlethread_workqueue("taal_esd");
+	if (td->esd_wq == NULL) {
+		dev_err(&dssdev->dev, "can't create ESD workqueue\n");
+		r = -ENOMEM;
+		goto err2;
+	}
+	INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work);
+
+	dev_set_drvdata(&dssdev->dev, td);
+
+	dssdev->get_timings = taal_get_timings;
+	dssdev->get_resolution = taal_get_resolution;
+
+	/* if no platform set_backlight() defined, presume DSI backlight
+	 * control */
+	if (!dssdev->set_backlight)
+		td->use_dsi_bl = true;
+
+	bldev = backlight_device_register("taal", &dssdev->dev, dssdev,
+			&taal_bl_ops);
+	if (IS_ERR(bldev)) {
+		r = PTR_ERR(bldev);
+		goto err1;
+	}
+
+	td->bldev = bldev;
+
+	bldev->props.fb_blank = FB_BLANK_UNBLANK;
+	bldev->props.power = FB_BLANK_UNBLANK;
+	if (td->use_dsi_bl) {
+		bldev->props.max_brightness = 255;
+		bldev->props.brightness = 255;
+	} else {
+		bldev->props.max_brightness = 127;
+		bldev->props.brightness = 127;
+	}
+
+	taal_bl_update_status(bldev);
+
+	if (dssdev->phy.dsi.ext_te) {
+		int gpio = dssdev->phy.dsi.ext_te_gpio;
+
+		r = gpio_request(gpio, "taal irq");
+		if (r) {
+			dev_err(&dssdev->dev, "GPIO request failed\n");
+			goto err3;
+		}
+
+		gpio_direction_input(gpio);
+
+		r = request_irq(gpio_to_irq(gpio), taal_te_isr,
+				IRQF_DISABLED | IRQF_TRIGGER_RISING,
+				"taal vsync", dssdev);
+
+		if (r) {
+			dev_err(&dssdev->dev, "IRQ request failed\n");
+			gpio_free(gpio);
+			goto err3;
+		}
+
+		init_completion(&td->te_completion);
+
+		td->use_ext_te = true;
+	}
+
+	r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group);
+	if (r) {
+		dev_err(&dssdev->dev, "failed to create sysfs files\n");
+		goto err4;
+	}
+
+	return 0;
+err4:
+	if (td->use_ext_te) {
+		int gpio = dssdev->phy.dsi.ext_te_gpio;
+		free_irq(gpio_to_irq(gpio), dssdev);
+		gpio_free(gpio);
+	}
+err3:
+	backlight_device_unregister(bldev);
+err2:
+	cancel_delayed_work_sync(&td->esd_work);
+	destroy_workqueue(td->esd_wq);
+err1:
+	kfree(td);
+err0:
+	return r;
+}
+
+static void taal_remove(struct omap_dss_device *dssdev)
+{
+	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	struct backlight_device *bldev;
+
+	dev_dbg(&dssdev->dev, "remove\n");
+
+	sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group);
+
+	if (td->use_ext_te) {
+		int gpio = dssdev->phy.dsi.ext_te_gpio;
+		free_irq(gpio_to_irq(gpio), dssdev);
+		gpio_free(gpio);
+	}
+
+	bldev = td->bldev;
+	bldev->props.power = FB_BLANK_POWERDOWN;
+	taal_bl_update_status(bldev);
+	backlight_device_unregister(bldev);
+
+	cancel_delayed_work_sync(&td->esd_work);
+	destroy_workqueue(td->esd_wq);
+
+	kfree(td);
+}
+
+static int taal_enable(struct omap_dss_device *dssdev)
+{
+	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	u8 id1, id2, id3;
+	int r;
+
+	dev_dbg(&dssdev->dev, "enable\n");
+
+	if (dssdev->platform_enable) {
+		r = dssdev->platform_enable(dssdev);
+		if (r)
+			return r;
+	}
+
+	/* it seems we have to wait a bit until taal is ready */
+	msleep(5);
+
+	r = taal_sleep_out(td);
+	if (r)
+		goto err;
+
+	r = taal_get_id(&id1, &id2, &id3);
+	if (r)
+		goto err;
+
+	/* on early revisions CABC is broken */
+	if (id2 == 0x00 || id2 == 0xff || id2 == 0x81)
+		td->cabc_broken = true;
+
+	taal_dcs_write_1(DCS_BRIGHTNESS, 0xff);
+	taal_dcs_write_1(DCS_CTRL_DISPLAY, (1<<2) | (1<<5)); /* BL | BCTRL */
+
+	taal_dcs_write_1(DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */
+
+	taal_set_addr_mode(td->rotate, td->mirror);
+	if (!td->cabc_broken)
+		taal_dcs_write_1(DCS_WRITE_CABC, td->cabc_mode);
+
+	taal_dcs_write_0(DCS_DISPLAY_ON);
+
+#ifdef TAAL_USE_ESD_CHECK
+	queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD);
+#endif
+
+	td->enabled = 1;
+
+	if (!td->intro_printed) {
+		dev_info(&dssdev->dev, "revision %02x.%02x.%02x\n",
+				id1, id2, id3);
+		if (td->cabc_broken)
+			dev_info(&dssdev->dev,
+					"old Taal version, CABC disabled\n");
+		td->intro_printed = true;
+	}
+
+	return 0;
+err:
+	if (dssdev->platform_disable)
+		dssdev->platform_disable(dssdev);
+
+	return r;
+}
+
+static void taal_disable(struct omap_dss_device *dssdev)
+{
+	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+
+	dev_dbg(&dssdev->dev, "disable\n");
+
+	cancel_delayed_work(&td->esd_work);
+
+	taal_dcs_write_0(DCS_DISPLAY_OFF);
+	taal_sleep_in(td);
+
+	/* wait a bit so that the message goes through */
+	msleep(10);
+
+	if (dssdev->platform_disable)
+		dssdev->platform_disable(dssdev);
+
+	td->enabled = 0;
+}
+
+static int taal_suspend(struct omap_dss_device *dssdev)
+{
+	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	struct backlight_device *bldev = td->bldev;
+
+	bldev->props.power = FB_BLANK_POWERDOWN;
+	taal_bl_update_status(bldev);
+
+	return 0;
+}
+
+static int taal_resume(struct omap_dss_device *dssdev)
+{
+	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	struct backlight_device *bldev = td->bldev;
+
+	bldev->props.power = FB_BLANK_UNBLANK;
+	taal_bl_update_status(bldev);
+
+	return 0;
+}
+
+static void taal_setup_update(struct omap_dss_device *dssdev,
+				    u16 x, u16 y, u16 w, u16 h)
+{
+	taal_set_update_window(x, y, w, h);
+}
+
+static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
+{
+	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	int r;
+
+	td->te_enabled = enable;
+
+	if (enable)
+		r = taal_dcs_write_1(DCS_TEAR_ON, 0);
+	else
+		r = taal_dcs_write_0(DCS_TEAR_OFF);
+
+	return r;
+}
+
+static int taal_wait_te(struct omap_dss_device *dssdev)
+{
+	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	long wait = msecs_to_jiffies(500);
+
+	if (!td->use_ext_te || !td->te_enabled)
+		return 0;
+
+	INIT_COMPLETION(td->te_completion);
+	wait = wait_for_completion_timeout(&td->te_completion, wait);
+	if (wait == 0) {
+		dev_err(&dssdev->dev, "timeout waiting TE\n");
+		return -ETIME;
+	}
+
+	return 0;
+}
+
+static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
+{
+	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	int r;
+
+	dev_dbg(&dssdev->dev, "rotate %d\n", rotate);
+
+	if (td->enabled) {
+		r = taal_set_addr_mode(rotate, td->mirror);
+
+		if (r)
+			return r;
+	}
+
+	td->rotate = rotate;
+
+	return 0;
+}
+
+static u8 taal_get_rotate(struct omap_dss_device *dssdev)
+{
+	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	return td->rotate;
+}
+
+static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
+{
+	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	int r;
+
+	dev_dbg(&dssdev->dev, "mirror %d\n", enable);
+
+	if (td->enabled) {
+		r = taal_set_addr_mode(td->rotate, enable);
+
+		if (r)
+			return r;
+	}
+
+	td->mirror = enable;
+
+	return 0;
+}
+
+static bool taal_get_mirror(struct omap_dss_device *dssdev)
+{
+	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	return td->mirror;
+}
+
+static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
+{
+	u8 id1, id2, id3;
+	int r;
+
+	r = taal_dcs_read_1(DCS_GET_ID1, &id1);
+	if (r)
+		return r;
+	r = taal_dcs_read_1(DCS_GET_ID2, &id2);
+	if (r)
+		return r;
+	r = taal_dcs_read_1(DCS_GET_ID3, &id3);
+	if (r)
+		return r;
+
+	return 0;
+}
+
+static int taal_memory_read(struct omap_dss_device *dssdev,
+		void *buf, size_t size,
+		u16 x, u16 y, u16 w, u16 h)
+{
+	int r;
+	int first = 1;
+	int plen;
+	unsigned buf_used = 0;
+
+	if (size < w * h * 3)
+		return -ENOMEM;
+
+	size = min(w * h * 3,
+			dssdev->panel.timings.x_res *
+			dssdev->panel.timings.y_res * 3);
+
+	/* plen 1 or 2 goes into short packet. until checksum error is fixed,
+	 * use short packets. plen 32 works, but bigger packets seem to cause
+	 * an error. */
+	if (size % 2)
+		plen = 1;
+	else
+		plen = 2;
+
+	taal_setup_update(dssdev, x, y, w, h);
+
+	r = dsi_vc_set_max_rx_packet_size(TCH, plen);
+	if (r)
+		return r;
+
+	while (buf_used < size) {
+		u8 dcs_cmd = first ? 0x2e : 0x3e;
+		first = 0;
+
+		r = dsi_vc_dcs_read(TCH, dcs_cmd,
+				buf + buf_used, size - buf_used);
+
+		if (r < 0) {
+			dev_err(&dssdev->dev, "read error\n");
+			goto err;
+		}
+
+		buf_used += r;
+
+		if (r < plen) {
+			dev_err(&dssdev->dev, "short read\n");
+			break;
+		}
+
+		if (signal_pending(current)) {
+			dev_err(&dssdev->dev, "signal pending, "
+					"aborting memory read\n");
+			r = -ERESTARTSYS;
+			goto err;
+		}
+	}
+
+	r = buf_used;
+
+err:
+	dsi_vc_set_max_rx_packet_size(TCH, 1);
+
+	return r;
+}
+
+static void taal_esd_work(struct work_struct *work)
+{
+	struct taal_data *td = container_of(work, struct taal_data,
+			esd_work.work);
+	struct omap_dss_device *dssdev = td->dssdev;
+	u8 state1, state2;
+	int r;
+
+	if (!td->enabled)
+		return;
+
+	dsi_bus_lock();
+
+	r = taal_dcs_read_1(DCS_RDDSDR, &state1);
+	if (r) {
+		dev_err(&dssdev->dev, "failed to read Taal status\n");
+		goto err;
+	}
+
+	/* Run self diagnostics */
+	r = taal_sleep_out(td);
+	if (r) {
+		dev_err(&dssdev->dev, "failed to run Taal self-diagnostics\n");
+		goto err;
+	}
+
+	r = taal_dcs_read_1(DCS_RDDSDR, &state2);
+	if (r) {
+		dev_err(&dssdev->dev, "failed to read Taal status\n");
+		goto err;
+	}
+
+	/* Each sleep out command will trigger a self diagnostic and flip
+	 * Bit6 if the test passes.
+	 */
+	if (!((state1 ^ state2) & (1 << 6))) {
+		dev_err(&dssdev->dev, "LCD self diagnostics failed\n");
+		goto err;
+	}
+	/* Self-diagnostics result is also shown on TE GPIO line. We need
+	 * to re-enable TE after self diagnostics */
+	if (td->use_ext_te && td->te_enabled)
+		taal_enable_te(dssdev, true);
+
+	dsi_bus_unlock();
+
+	queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD);
+
+	return;
+err:
+	dev_err(&dssdev->dev, "performing LCD reset\n");
+
+	taal_disable(dssdev);
+	taal_enable(dssdev);
+
+	dsi_bus_unlock();
+
+	queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD);
+}
+
+static struct omap_dss_driver taal_driver = {
+	.probe		= taal_probe,
+	.remove		= taal_remove,
+
+	.enable		= taal_enable,
+	.disable	= taal_disable,
+	.suspend	= taal_suspend,
+	.resume		= taal_resume,
+
+	.setup_update	= taal_setup_update,
+	.enable_te	= taal_enable_te,
+	.wait_for_te	= taal_wait_te,
+	.set_rotate	= taal_rotate,
+	.get_rotate	= taal_get_rotate,
+	.set_mirror	= taal_mirror,
+	.get_mirror	= taal_get_mirror,
+	.run_test	= taal_run_test,
+	.memory_read	= taal_memory_read,
+
+	.driver         = {
+		.name   = "taal",
+		.owner  = THIS_MODULE,
+	},
+};
+
+static int __init taal_init(void)
+{
+	omap_dss_register_driver(&taal_driver);
+
+	return 0;
+}
+
+static void __exit taal_exit(void)
+{
+	omap_dss_unregister_driver(&taal_driver);
+}
+
+module_init(taal_init);
+module_exit(taal_exit);
+
+MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
+MODULE_DESCRIPTION("Taal Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
new file mode 100644
index 0000000..71d8dec
--- /dev/null
+++ b/drivers/video/omap2/dss/Kconfig
@@ -0,0 +1,89 @@
+menuconfig OMAP2_DSS
+        tristate "OMAP2/3 Display Subsystem support (EXPERIMENTAL)"
+        depends on ARCH_OMAP2 || ARCH_OMAP3
+        help
+          OMAP2/3 Display Subsystem support.
+
+if OMAP2_DSS
+
+config OMAP2_VRAM_SIZE
+	int "VRAM size (MB)"
+	range 0 32
+	default 0
+	help
+	  The amount of SDRAM to reserve at boot time for video RAM use.
+	  This VRAM will be used by omapfb and other drivers that need
+	  large continuous RAM area for video use.
+
+	  You can also set this with "vram=<bytes>" kernel argument, or
+	  in the board file.
+
+config OMAP2_DSS_DEBUG_SUPPORT
+        bool "Debug support"
+	default y
+	help
+	  This enables debug messages. You need to enable printing
+	  with 'debug' module parameter.
+
+config OMAP2_DSS_RFBI
+	bool "RFBI support"
+        default n
+	help
+	  MIPI DBI, or RFBI (Remote Framebuffer Interface), support.
+
+config OMAP2_DSS_VENC
+	bool "VENC support"
+        default y
+	help
+	  OMAP Video Encoder support.
+
+config OMAP2_DSS_SDI
+	bool "SDI support"
+	depends on ARCH_OMAP3
+        default n
+	help
+	  SDI (Serial Display Interface) support.
+
+config OMAP2_DSS_DSI
+	bool "DSI support"
+	depends on ARCH_OMAP3
+        default n
+	help
+	  MIPI DSI support.
+
+config OMAP2_DSS_USE_DSI_PLL
+	bool "Use DSI PLL for PCLK (EXPERIMENTAL)"
+	default n
+	depends on OMAP2_DSS_DSI
+	help
+	  Use DSI PLL to generate pixel clock.  Currently only for DPI output.
+	  DSI PLL can be used to generate higher and more precise pixel clocks.
+
+config OMAP2_DSS_FAKE_VSYNC
+	bool "Fake VSYNC irq from manual update displays"
+	default n
+	help
+	  If this is selected, DSI will generate a fake DISPC VSYNC interrupt
+	  when DSI has sent a frame. This is only needed with DSI or RFBI
+	  displays using manual mode, and you want VSYNC to, for example,
+	  time animation.
+
+config OMAP2_DSS_MIN_FCK_PER_PCK
+	int "Minimum FCK/PCK ratio (for scaling)"
+	range 0 32
+	default 0
+	help
+	  This can be used to adjust the minimum FCK/PCK ratio.
+
+	  With this you can make sure that DISPC FCK is at least
+	  n x PCK. Video plane scaling requires higher FCK than
+	  normally.
+
+	  If this is set to 0, there's no extra constraint on the
+	  DISPC FCK. However, the FCK will at minimum be
+	  2xPCK (if active matrix) or 3xPCK (if passive matrix).
+
+	  Max FCK is 173MHz, so this doesn't work if your PCK
+	  is very high.
+
+endif
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
new file mode 100644
index 0000000..980c72c
--- /dev/null
+++ b/drivers/video/omap2/dss/Makefile
@@ -0,0 +1,6 @@
+obj-$(CONFIG_OMAP2_DSS) += omapdss.o
+omapdss-y := core.o dss.o dispc.o dpi.o display.o manager.o overlay.o
+omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
+omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
+omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
+omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
new file mode 100644
index 0000000..29497a0
--- /dev/null
+++ b/drivers/video/omap2/dss/core.c
@@ -0,0 +1,919 @@
+/*
+ * linux/drivers/video/omap2/dss/core.c
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * Some code and ideas taken from drivers/video/omap/ driver
+ * by Imre Deak.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define DSS_SUBSYS_NAME "CORE"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+#include <linux/io.h>
+#include <linux/device.h>
+
+#include <plat/display.h>
+#include <plat/clock.h>
+
+#include "dss.h"
+
+static struct {
+	struct platform_device *pdev;
+	int		ctx_id;
+
+	struct clk      *dss_ick;
+	struct clk	*dss1_fck;
+	struct clk	*dss2_fck;
+	struct clk      *dss_54m_fck;
+	struct clk	*dss_96m_fck;
+	unsigned	num_clks_enabled;
+} core;
+
+static void dss_clk_enable_all_no_ctx(void);
+static void dss_clk_disable_all_no_ctx(void);
+static void dss_clk_enable_no_ctx(enum dss_clock clks);
+static void dss_clk_disable_no_ctx(enum dss_clock clks);
+
+static char *def_disp_name;
+module_param_named(def_disp, def_disp_name, charp, 0);
+MODULE_PARM_DESC(def_disp_name, "default display name");
+
+#ifdef DEBUG
+unsigned int dss_debug;
+module_param_named(debug, dss_debug, bool, 0644);
+#endif
+
+/* CONTEXT */
+static int dss_get_ctx_id(void)
+{
+	struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
+	int r;
+
+	if (!pdata->get_last_off_on_transaction_id)
+		return 0;
+	r = pdata->get_last_off_on_transaction_id(&core.pdev->dev);
+	if (r < 0) {
+		dev_err(&core.pdev->dev, "getting transaction ID failed, "
+				"will force context restore\n");
+		r = -1;
+	}
+	return r;
+}
+
+int dss_need_ctx_restore(void)
+{
+	int id = dss_get_ctx_id();
+
+	if (id < 0 || id != core.ctx_id) {
+		DSSDBG("ctx id %d -> id %d\n",
+				core.ctx_id, id);
+		core.ctx_id = id;
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+static void save_all_ctx(void)
+{
+	DSSDBG("save context\n");
+
+	dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
+
+	dss_save_context();
+	dispc_save_context();
+#ifdef CONFIG_OMAP2_DSS_DSI
+	dsi_save_context();
+#endif
+
+	dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
+}
+
+static void restore_all_ctx(void)
+{
+	DSSDBG("restore context\n");
+
+	dss_clk_enable_all_no_ctx();
+
+	dss_restore_context();
+	dispc_restore_context();
+#ifdef CONFIG_OMAP2_DSS_DSI
+	dsi_restore_context();
+#endif
+
+	dss_clk_disable_all_no_ctx();
+}
+
+/* CLOCKS */
+static void core_dump_clocks(struct seq_file *s)
+{
+	int i;
+	struct clk *clocks[5] = {
+		core.dss_ick,
+		core.dss1_fck,
+		core.dss2_fck,
+		core.dss_54m_fck,
+		core.dss_96m_fck
+	};
+
+	seq_printf(s, "- CORE -\n");
+
+	seq_printf(s, "internal clk count\t\t%u\n", core.num_clks_enabled);
+
+	for (i = 0; i < 5; i++) {
+		if (!clocks[i])
+			continue;
+		seq_printf(s, "%-15s\t%lu\t%d\n",
+				clocks[i]->name,
+				clk_get_rate(clocks[i]),
+				clocks[i]->usecount);
+	}
+}
+
+static int dss_get_clock(struct clk **clock, const char *clk_name)
+{
+	struct clk *clk;
+
+	clk = clk_get(&core.pdev->dev, clk_name);
+
+	if (IS_ERR(clk)) {
+		DSSERR("can't get clock %s", clk_name);
+		return PTR_ERR(clk);
+	}
+
+	*clock = clk;
+
+	DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk));
+
+	return 0;
+}
+
+static int dss_get_clocks(void)
+{
+	int r;
+
+	core.dss_ick = NULL;
+	core.dss1_fck = NULL;
+	core.dss2_fck = NULL;
+	core.dss_54m_fck = NULL;
+	core.dss_96m_fck = NULL;
+
+	r = dss_get_clock(&core.dss_ick, "ick");
+	if (r)
+		goto err;
+
+	r = dss_get_clock(&core.dss1_fck, "dss1_fck");
+	if (r)
+		goto err;
+
+	r = dss_get_clock(&core.dss2_fck, "dss2_fck");
+	if (r)
+		goto err;
+
+	r = dss_get_clock(&core.dss_54m_fck, "tv_fck");
+	if (r)
+		goto err;
+
+	r = dss_get_clock(&core.dss_96m_fck, "video_fck");
+	if (r)
+		goto err;
+
+	return 0;
+
+err:
+	if (core.dss_ick)
+		clk_put(core.dss_ick);
+	if (core.dss1_fck)
+		clk_put(core.dss1_fck);
+	if (core.dss2_fck)
+		clk_put(core.dss2_fck);
+	if (core.dss_54m_fck)
+		clk_put(core.dss_54m_fck);
+	if (core.dss_96m_fck)
+		clk_put(core.dss_96m_fck);
+
+	return r;
+}
+
+static void dss_put_clocks(void)
+{
+	if (core.dss_96m_fck)
+		clk_put(core.dss_96m_fck);
+	clk_put(core.dss_54m_fck);
+	clk_put(core.dss1_fck);
+	clk_put(core.dss2_fck);
+	clk_put(core.dss_ick);
+}
+
+unsigned long dss_clk_get_rate(enum dss_clock clk)
+{
+	switch (clk) {
+	case DSS_CLK_ICK:
+		return clk_get_rate(core.dss_ick);
+	case DSS_CLK_FCK1:
+		return clk_get_rate(core.dss1_fck);
+	case DSS_CLK_FCK2:
+		return clk_get_rate(core.dss2_fck);
+	case DSS_CLK_54M:
+		return clk_get_rate(core.dss_54m_fck);
+	case DSS_CLK_96M:
+		return clk_get_rate(core.dss_96m_fck);
+	}
+
+	BUG();
+	return 0;
+}
+
+static unsigned count_clk_bits(enum dss_clock clks)
+{
+	unsigned num_clks = 0;
+
+	if (clks & DSS_CLK_ICK)
+		++num_clks;
+	if (clks & DSS_CLK_FCK1)
+		++num_clks;
+	if (clks & DSS_CLK_FCK2)
+		++num_clks;
+	if (clks & DSS_CLK_54M)
+		++num_clks;
+	if (clks & DSS_CLK_96M)
+		++num_clks;
+
+	return num_clks;
+}
+
+static void dss_clk_enable_no_ctx(enum dss_clock clks)
+{
+	unsigned num_clks = count_clk_bits(clks);
+
+	if (clks & DSS_CLK_ICK)
+		clk_enable(core.dss_ick);
+	if (clks & DSS_CLK_FCK1)
+		clk_enable(core.dss1_fck);
+	if (clks & DSS_CLK_FCK2)
+		clk_enable(core.dss2_fck);
+	if (clks & DSS_CLK_54M)
+		clk_enable(core.dss_54m_fck);
+	if (clks & DSS_CLK_96M)
+		clk_enable(core.dss_96m_fck);
+
+	core.num_clks_enabled += num_clks;
+}
+
+void dss_clk_enable(enum dss_clock clks)
+{
+	dss_clk_enable_no_ctx(clks);
+
+	if (cpu_is_omap34xx() && dss_need_ctx_restore())
+		restore_all_ctx();
+}
+
+static void dss_clk_disable_no_ctx(enum dss_clock clks)
+{
+	unsigned num_clks = count_clk_bits(clks);
+
+	if (clks & DSS_CLK_ICK)
+		clk_disable(core.dss_ick);
+	if (clks & DSS_CLK_FCK1)
+		clk_disable(core.dss1_fck);
+	if (clks & DSS_CLK_FCK2)
+		clk_disable(core.dss2_fck);
+	if (clks & DSS_CLK_54M)
+		clk_disable(core.dss_54m_fck);
+	if (clks & DSS_CLK_96M)
+		clk_disable(core.dss_96m_fck);
+
+	core.num_clks_enabled -= num_clks;
+}
+
+void dss_clk_disable(enum dss_clock clks)
+{
+	if (cpu_is_omap34xx()) {
+		unsigned num_clks = count_clk_bits(clks);
+
+		BUG_ON(core.num_clks_enabled < num_clks);
+
+		if (core.num_clks_enabled == num_clks)
+			save_all_ctx();
+	}
+
+	dss_clk_disable_no_ctx(clks);
+}
+
+static void dss_clk_enable_all_no_ctx(void)
+{
+	enum dss_clock clks;
+
+	clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
+	if (cpu_is_omap34xx())
+		clks |= DSS_CLK_96M;
+	dss_clk_enable_no_ctx(clks);
+}
+
+static void dss_clk_disable_all_no_ctx(void)
+{
+	enum dss_clock clks;
+
+	clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
+	if (cpu_is_omap34xx())
+		clks |= DSS_CLK_96M;
+	dss_clk_disable_no_ctx(clks);
+}
+
+static void dss_clk_disable_all(void)
+{
+	enum dss_clock clks;
+
+	clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
+	if (cpu_is_omap34xx())
+		clks |= DSS_CLK_96M;
+	dss_clk_disable(clks);
+}
+
+/* DEBUGFS */
+#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
+static void dss_debug_dump_clocks(struct seq_file *s)
+{
+	core_dump_clocks(s);
+	dss_dump_clocks(s);
+	dispc_dump_clocks(s);
+#ifdef CONFIG_OMAP2_DSS_DSI
+	dsi_dump_clocks(s);
+#endif
+}
+
+static int dss_debug_show(struct seq_file *s, void *unused)
+{
+	void (*func)(struct seq_file *) = s->private;
+	func(s);
+	return 0;
+}
+
+static int dss_debug_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, dss_debug_show, inode->i_private);
+}
+
+static const struct file_operations dss_debug_fops = {
+	.open           = dss_debug_open,
+	.read           = seq_read,
+	.llseek         = seq_lseek,
+	.release        = single_release,
+};
+
+static struct dentry *dss_debugfs_dir;
+
+static int dss_initialize_debugfs(void)
+{
+	dss_debugfs_dir = debugfs_create_dir("omapdss", NULL);
+	if (IS_ERR(dss_debugfs_dir)) {
+		int err = PTR_ERR(dss_debugfs_dir);
+		dss_debugfs_dir = NULL;
+		return err;
+	}
+
+	debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir,
+			&dss_debug_dump_clocks, &dss_debug_fops);
+
+	debugfs_create_file("dss", S_IRUGO, dss_debugfs_dir,
+			&dss_dump_regs, &dss_debug_fops);
+	debugfs_create_file("dispc", S_IRUGO, dss_debugfs_dir,
+			&dispc_dump_regs, &dss_debug_fops);
+#ifdef CONFIG_OMAP2_DSS_RFBI
+	debugfs_create_file("rfbi", S_IRUGO, dss_debugfs_dir,
+			&rfbi_dump_regs, &dss_debug_fops);
+#endif
+#ifdef CONFIG_OMAP2_DSS_DSI
+	debugfs_create_file("dsi", S_IRUGO, dss_debugfs_dir,
+			&dsi_dump_regs, &dss_debug_fops);
+#endif
+#ifdef CONFIG_OMAP2_DSS_VENC
+	debugfs_create_file("venc", S_IRUGO, dss_debugfs_dir,
+			&venc_dump_regs, &dss_debug_fops);
+#endif
+	return 0;
+}
+
+static void dss_uninitialize_debugfs(void)
+{
+	if (dss_debugfs_dir)
+		debugfs_remove_recursive(dss_debugfs_dir);
+}
+#endif /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */
+
+/* PLATFORM DEVICE */
+static int omap_dss_probe(struct platform_device *pdev)
+{
+	struct omap_dss_board_info *pdata = pdev->dev.platform_data;
+	int skip_init = 0;
+	int r;
+	int i;
+
+	core.pdev = pdev;
+
+	dss_init_overlay_managers(pdev);
+	dss_init_overlays(pdev);
+
+	r = dss_get_clocks();
+	if (r)
+		goto fail0;
+
+	dss_clk_enable_all_no_ctx();
+
+	core.ctx_id = dss_get_ctx_id();
+	DSSDBG("initial ctx id %u\n", core.ctx_id);
+
+#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT
+	/* DISPC_CONTROL */
+	if (omap_readl(0x48050440) & 1)	/* LCD enabled? */
+		skip_init = 1;
+#endif
+
+	r = dss_init(skip_init);
+	if (r) {
+		DSSERR("Failed to initialize DSS\n");
+		goto fail0;
+	}
+
+#ifdef CONFIG_OMAP2_DSS_RFBI
+	r = rfbi_init();
+	if (r) {
+		DSSERR("Failed to initialize rfbi\n");
+		goto fail0;
+	}
+#endif
+
+	r = dpi_init();
+	if (r) {
+		DSSERR("Failed to initialize dpi\n");
+		goto fail0;
+	}
+
+	r = dispc_init();
+	if (r) {
+		DSSERR("Failed to initialize dispc\n");
+		goto fail0;
+	}
+#ifdef CONFIG_OMAP2_DSS_VENC
+	r = venc_init(pdev);
+	if (r) {
+		DSSERR("Failed to initialize venc\n");
+		goto fail0;
+	}
+#endif
+	if (cpu_is_omap34xx()) {
+#ifdef CONFIG_OMAP2_DSS_SDI
+		r = sdi_init(skip_init);
+		if (r) {
+			DSSERR("Failed to initialize SDI\n");
+			goto fail0;
+		}
+#endif
+#ifdef CONFIG_OMAP2_DSS_DSI
+		r = dsi_init(pdev);
+		if (r) {
+			DSSERR("Failed to initialize DSI\n");
+			goto fail0;
+		}
+#endif
+	}
+
+#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
+	r = dss_initialize_debugfs();
+	if (r)
+		goto fail0;
+#endif
+
+	for (i = 0; i < pdata->num_devices; ++i) {
+		struct omap_dss_device *dssdev = pdata->devices[i];
+
+		r = omap_dss_register_device(dssdev);
+		if (r)
+			DSSERR("device reg failed %d\n", i);
+
+		if (def_disp_name && strcmp(def_disp_name, dssdev->name) == 0)
+			pdata->default_device = dssdev;
+	}
+
+	dss_clk_disable_all();
+
+	return 0;
+
+	/* XXX fail correctly */
+fail0:
+	return r;
+}
+
+static int omap_dss_remove(struct platform_device *pdev)
+{
+	struct omap_dss_board_info *pdata = pdev->dev.platform_data;
+	int i;
+	int c;
+
+#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
+	dss_uninitialize_debugfs();
+#endif
+
+#ifdef CONFIG_OMAP2_DSS_VENC
+	venc_exit();
+#endif
+	dispc_exit();
+	dpi_exit();
+#ifdef CONFIG_OMAP2_DSS_RFBI
+	rfbi_exit();
+#endif
+	if (cpu_is_omap34xx()) {
+#ifdef CONFIG_OMAP2_DSS_DSI
+		dsi_exit();
+#endif
+#ifdef CONFIG_OMAP2_DSS_SDI
+		sdi_exit();
+#endif
+	}
+
+	dss_exit();
+
+	/* these should be removed at some point */
+	c = core.dss_ick->usecount;
+	if (c > 0) {
+		DSSERR("warning: dss_ick usecount %d, disabling\n", c);
+		while (c-- > 0)
+			clk_disable(core.dss_ick);
+	}
+
+	c = core.dss1_fck->usecount;
+	if (c > 0) {
+		DSSERR("warning: dss1_fck usecount %d, disabling\n", c);
+		while (c-- > 0)
+			clk_disable(core.dss1_fck);
+	}
+
+	c = core.dss2_fck->usecount;
+	if (c > 0) {
+		DSSERR("warning: dss2_fck usecount %d, disabling\n", c);
+		while (c-- > 0)
+			clk_disable(core.dss2_fck);
+	}
+
+	c = core.dss_54m_fck->usecount;
+	if (c > 0) {
+		DSSERR("warning: dss_54m_fck usecount %d, disabling\n", c);
+		while (c-- > 0)
+			clk_disable(core.dss_54m_fck);
+	}
+
+	if (core.dss_96m_fck) {
+		c = core.dss_96m_fck->usecount;
+		if (c > 0) {
+			DSSERR("warning: dss_96m_fck usecount %d, disabling\n",
+					c);
+			while (c-- > 0)
+				clk_disable(core.dss_96m_fck);
+		}
+	}
+
+	dss_put_clocks();
+
+	dss_uninit_overlays(pdev);
+	dss_uninit_overlay_managers(pdev);
+
+	for (i = 0; i < pdata->num_devices; ++i)
+		omap_dss_unregister_device(pdata->devices[i]);
+
+	return 0;
+}
+
+static void omap_dss_shutdown(struct platform_device *pdev)
+{
+	DSSDBG("shutdown\n");
+	dss_disable_all_devices();
+}
+
+static int omap_dss_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	DSSDBG("suspend %d\n", state.event);
+
+	return dss_suspend_all_devices();
+}
+
+static int omap_dss_resume(struct platform_device *pdev)
+{
+	DSSDBG("resume\n");
+
+	return dss_resume_all_devices();
+}
+
+static struct platform_driver omap_dss_driver = {
+	.probe          = omap_dss_probe,
+	.remove         = omap_dss_remove,
+	.shutdown	= omap_dss_shutdown,
+	.suspend	= omap_dss_suspend,
+	.resume		= omap_dss_resume,
+	.driver         = {
+		.name   = "omapdss",
+		.owner  = THIS_MODULE,
+	},
+};
+
+/* BUS */
+static int dss_bus_match(struct device *dev, struct device_driver *driver)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+
+	DSSDBG("bus_match. dev %s/%s, drv %s\n",
+			dev_name(dev), dssdev->driver_name, driver->name);
+
+	return strcmp(dssdev->driver_name, driver->name) == 0;
+}
+
+static ssize_t device_name_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	return snprintf(buf, PAGE_SIZE, "%s\n",
+			dssdev->name ?
+			dssdev->name : "");
+}
+
+static struct device_attribute default_dev_attrs[] = {
+	__ATTR(name, S_IRUGO, device_name_show, NULL),
+	__ATTR_NULL,
+};
+
+static ssize_t driver_name_show(struct device_driver *drv, char *buf)
+{
+	struct omap_dss_driver *dssdrv = to_dss_driver(drv);
+	return snprintf(buf, PAGE_SIZE, "%s\n",
+			dssdrv->driver.name ?
+			dssdrv->driver.name : "");
+}
+static struct driver_attribute default_drv_attrs[] = {
+	__ATTR(name, S_IRUGO, driver_name_show, NULL),
+	__ATTR_NULL,
+};
+
+static struct bus_type dss_bus_type = {
+	.name = "omapdss",
+	.match = dss_bus_match,
+	.dev_attrs = default_dev_attrs,
+	.drv_attrs = default_drv_attrs,
+};
+
+static void dss_bus_release(struct device *dev)
+{
+	DSSDBG("bus_release\n");
+}
+
+static struct device dss_bus = {
+	.release = dss_bus_release,
+};
+
+struct bus_type *dss_get_bus(void)
+{
+	return &dss_bus_type;
+}
+
+/* DRIVER */
+static int dss_driver_probe(struct device *dev)
+{
+	int r;
+	struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver);
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
+	bool force;
+
+	DSSDBG("driver_probe: dev %s/%s, drv %s\n",
+				dev_name(dev), dssdev->driver_name,
+				dssdrv->driver.name);
+
+	dss_init_device(core.pdev, dssdev);
+
+	/* skip this if the device is behind a ctrl */
+	if (!dssdev->panel.ctrl) {
+		force = pdata->default_device == dssdev;
+		dss_recheck_connections(dssdev, force);
+	}
+
+	r = dssdrv->probe(dssdev);
+
+	if (r) {
+		DSSERR("driver probe failed: %d\n", r);
+		return r;
+	}
+
+	DSSDBG("probe done for device %s\n", dev_name(dev));
+
+	dssdev->driver = dssdrv;
+
+	return 0;
+}
+
+static int dss_driver_remove(struct device *dev)
+{
+	struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver);
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+
+	DSSDBG("driver_remove: dev %s/%s\n", dev_name(dev),
+			dssdev->driver_name);
+
+	dssdrv->remove(dssdev);
+
+	dss_uninit_device(core.pdev, dssdev);
+
+	dssdev->driver = NULL;
+
+	return 0;
+}
+
+int omap_dss_register_driver(struct omap_dss_driver *dssdriver)
+{
+	dssdriver->driver.bus = &dss_bus_type;
+	dssdriver->driver.probe = dss_driver_probe;
+	dssdriver->driver.remove = dss_driver_remove;
+	return driver_register(&dssdriver->driver);
+}
+EXPORT_SYMBOL(omap_dss_register_driver);
+
+void omap_dss_unregister_driver(struct omap_dss_driver *dssdriver)
+{
+	driver_unregister(&dssdriver->driver);
+}
+EXPORT_SYMBOL(omap_dss_unregister_driver);
+
+/* DEVICE */
+static void reset_device(struct device *dev, int check)
+{
+	u8 *dev_p = (u8 *)dev;
+	u8 *dev_end = dev_p + sizeof(*dev);
+	void *saved_pdata;
+
+	saved_pdata = dev->platform_data;
+	if (check) {
+		/*
+		 * Check if there is any other setting than platform_data
+		 * in struct device; warn that these will be reset by our
+		 * init.
+		 */
+		dev->platform_data = NULL;
+		while (dev_p < dev_end) {
+			if (*dev_p) {
+				WARN("%s: struct device fields will be "
+						"discarded\n",
+				     __func__);
+				break;
+			}
+			dev_p++;
+		}
+	}
+	memset(dev, 0, sizeof(*dev));
+	dev->platform_data = saved_pdata;
+}
+
+
+static void omap_dss_dev_release(struct device *dev)
+{
+	reset_device(dev, 0);
+}
+
+int omap_dss_register_device(struct omap_dss_device *dssdev)
+{
+	static int dev_num;
+	static int panel_num;
+	int r;
+
+	WARN_ON(!dssdev->driver_name);
+
+	reset_device(&dssdev->dev, 1);
+	dssdev->dev.bus = &dss_bus_type;
+	dssdev->dev.parent = &dss_bus;
+	dssdev->dev.release = omap_dss_dev_release;
+	dev_set_name(&dssdev->dev, "display%d", dev_num++);
+	r = device_register(&dssdev->dev);
+	if (r)
+		return r;
+
+	if (dssdev->ctrl.panel) {
+		struct omap_dss_device *panel = dssdev->ctrl.panel;
+
+		panel->panel.ctrl = dssdev;
+
+		reset_device(&panel->dev, 1);
+		panel->dev.bus = &dss_bus_type;
+		panel->dev.parent = &dssdev->dev;
+		panel->dev.release = omap_dss_dev_release;
+		dev_set_name(&panel->dev, "panel%d", panel_num++);
+		r = device_register(&panel->dev);
+		if (r)
+			return r;
+	}
+
+	return 0;
+}
+
+void omap_dss_unregister_device(struct omap_dss_device *dssdev)
+{
+	device_unregister(&dssdev->dev);
+
+	if (dssdev->ctrl.panel) {
+		struct omap_dss_device *panel = dssdev->ctrl.panel;
+		device_unregister(&panel->dev);
+	}
+}
+
+/* BUS */
+static int omap_dss_bus_register(void)
+{
+	int r;
+
+	r = bus_register(&dss_bus_type);
+	if (r) {
+		DSSERR("bus register failed\n");
+		return r;
+	}
+
+	dev_set_name(&dss_bus, "omapdss");
+	r = device_register(&dss_bus);
+	if (r) {
+		DSSERR("bus driver register failed\n");
+		bus_unregister(&dss_bus_type);
+		return r;
+	}
+
+	return 0;
+}
+
+/* INIT */
+
+#ifdef CONFIG_OMAP2_DSS_MODULE
+static void omap_dss_bus_unregister(void)
+{
+	device_unregister(&dss_bus);
+
+	bus_unregister(&dss_bus_type);
+}
+
+static int __init omap_dss_init(void)
+{
+	int r;
+
+	r = omap_dss_bus_register();
+	if (r)
+		return r;
+
+	r = platform_driver_register(&omap_dss_driver);
+	if (r) {
+		omap_dss_bus_unregister();
+		return r;
+	}
+
+	return 0;
+}
+
+static void __exit omap_dss_exit(void)
+{
+	platform_driver_unregister(&omap_dss_driver);
+
+	omap_dss_bus_unregister();
+}
+
+module_init(omap_dss_init);
+module_exit(omap_dss_exit);
+#else
+static int __init omap_dss_init(void)
+{
+	return omap_dss_bus_register();
+}
+
+static int __init omap_dss_init2(void)
+{
+	return platform_driver_register(&omap_dss_driver);
+}
+
+core_initcall(omap_dss_init);
+device_initcall(omap_dss_init2);
+#endif
+
+MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
+MODULE_DESCRIPTION("OMAP2/3 Display Subsystem");
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
new file mode 100644
index 0000000..6dabf4b
--- /dev/null
+++ b/drivers/video/omap2/dss/dispc.c
@@ -0,0 +1,3091 @@
+/*
+ * linux/drivers/video/omap2/dss/dispc.c
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * Some code and ideas taken from drivers/video/omap/ driver
+ * by Imre Deak.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define DSS_SUBSYS_NAME "DISPC"
+
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/vmalloc.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/seq_file.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+
+#include <plat/sram.h>
+#include <plat/clock.h>
+
+#include <plat/display.h>
+
+#include "dss.h"
+
+/* DISPC */
+#define DISPC_BASE			0x48050400
+
+#define DISPC_SZ_REGS			SZ_1K
+
+struct dispc_reg { u16 idx; };
+
+#define DISPC_REG(idx)			((const struct dispc_reg) { idx })
+
+/* DISPC common */
+#define DISPC_REVISION			DISPC_REG(0x0000)
+#define DISPC_SYSCONFIG			DISPC_REG(0x0010)
+#define DISPC_SYSSTATUS			DISPC_REG(0x0014)
+#define DISPC_IRQSTATUS			DISPC_REG(0x0018)
+#define DISPC_IRQENABLE			DISPC_REG(0x001C)
+#define DISPC_CONTROL			DISPC_REG(0x0040)
+#define DISPC_CONFIG			DISPC_REG(0x0044)
+#define DISPC_CAPABLE			DISPC_REG(0x0048)
+#define DISPC_DEFAULT_COLOR0		DISPC_REG(0x004C)
+#define DISPC_DEFAULT_COLOR1		DISPC_REG(0x0050)
+#define DISPC_TRANS_COLOR0		DISPC_REG(0x0054)
+#define DISPC_TRANS_COLOR1		DISPC_REG(0x0058)
+#define DISPC_LINE_STATUS		DISPC_REG(0x005C)
+#define DISPC_LINE_NUMBER		DISPC_REG(0x0060)
+#define DISPC_TIMING_H			DISPC_REG(0x0064)
+#define DISPC_TIMING_V			DISPC_REG(0x0068)
+#define DISPC_POL_FREQ			DISPC_REG(0x006C)
+#define DISPC_DIVISOR			DISPC_REG(0x0070)
+#define DISPC_GLOBAL_ALPHA		DISPC_REG(0x0074)
+#define DISPC_SIZE_DIG			DISPC_REG(0x0078)
+#define DISPC_SIZE_LCD			DISPC_REG(0x007C)
+
+/* DISPC GFX plane */
+#define DISPC_GFX_BA0			DISPC_REG(0x0080)
+#define DISPC_GFX_BA1			DISPC_REG(0x0084)
+#define DISPC_GFX_POSITION		DISPC_REG(0x0088)
+#define DISPC_GFX_SIZE			DISPC_REG(0x008C)
+#define DISPC_GFX_ATTRIBUTES		DISPC_REG(0x00A0)
+#define DISPC_GFX_FIFO_THRESHOLD	DISPC_REG(0x00A4)
+#define DISPC_GFX_FIFO_SIZE_STATUS	DISPC_REG(0x00A8)
+#define DISPC_GFX_ROW_INC		DISPC_REG(0x00AC)
+#define DISPC_GFX_PIXEL_INC		DISPC_REG(0x00B0)
+#define DISPC_GFX_WINDOW_SKIP		DISPC_REG(0x00B4)
+#define DISPC_GFX_TABLE_BA		DISPC_REG(0x00B8)
+
+#define DISPC_DATA_CYCLE1		DISPC_REG(0x01D4)
+#define DISPC_DATA_CYCLE2		DISPC_REG(0x01D8)
+#define DISPC_DATA_CYCLE3		DISPC_REG(0x01DC)
+
+#define DISPC_CPR_COEF_R		DISPC_REG(0x0220)
+#define DISPC_CPR_COEF_G		DISPC_REG(0x0224)
+#define DISPC_CPR_COEF_B		DISPC_REG(0x0228)
+
+#define DISPC_GFX_PRELOAD		DISPC_REG(0x022C)
+
+/* DISPC Video plane, n = 0 for VID1 and n = 1 for VID2 */
+#define DISPC_VID_REG(n, idx)		DISPC_REG(0x00BC + (n)*0x90 + idx)
+
+#define DISPC_VID_BA0(n)		DISPC_VID_REG(n, 0x0000)
+#define DISPC_VID_BA1(n)		DISPC_VID_REG(n, 0x0004)
+#define DISPC_VID_POSITION(n)		DISPC_VID_REG(n, 0x0008)
+#define DISPC_VID_SIZE(n)		DISPC_VID_REG(n, 0x000C)
+#define DISPC_VID_ATTRIBUTES(n)		DISPC_VID_REG(n, 0x0010)
+#define DISPC_VID_FIFO_THRESHOLD(n)	DISPC_VID_REG(n, 0x0014)
+#define DISPC_VID_FIFO_SIZE_STATUS(n)	DISPC_VID_REG(n, 0x0018)
+#define DISPC_VID_ROW_INC(n)		DISPC_VID_REG(n, 0x001C)
+#define DISPC_VID_PIXEL_INC(n)		DISPC_VID_REG(n, 0x0020)
+#define DISPC_VID_FIR(n)		DISPC_VID_REG(n, 0x0024)
+#define DISPC_VID_PICTURE_SIZE(n)	DISPC_VID_REG(n, 0x0028)
+#define DISPC_VID_ACCU0(n)		DISPC_VID_REG(n, 0x002C)
+#define DISPC_VID_ACCU1(n)		DISPC_VID_REG(n, 0x0030)
+
+/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
+#define DISPC_VID_FIR_COEF_H(n, i)	DISPC_REG(0x00F0 + (n)*0x90 + (i)*0x8)
+/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
+#define DISPC_VID_FIR_COEF_HV(n, i)	DISPC_REG(0x00F4 + (n)*0x90 + (i)*0x8)
+/* coef index i = {0, 1, 2, 3, 4} */
+#define DISPC_VID_CONV_COEF(n, i)	DISPC_REG(0x0130 + (n)*0x90 + (i)*0x4)
+/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
+#define DISPC_VID_FIR_COEF_V(n, i)	DISPC_REG(0x01E0 + (n)*0x20 + (i)*0x4)
+
+#define DISPC_VID_PRELOAD(n)		DISPC_REG(0x230 + (n)*0x04)
+
+
+#define DISPC_IRQ_MASK_ERROR            (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \
+					 DISPC_IRQ_OCP_ERR | \
+					 DISPC_IRQ_VID1_FIFO_UNDERFLOW | \
+					 DISPC_IRQ_VID2_FIFO_UNDERFLOW | \
+					 DISPC_IRQ_SYNC_LOST | \
+					 DISPC_IRQ_SYNC_LOST_DIGIT)
+
+#define DISPC_MAX_NR_ISRS		8
+
+struct omap_dispc_isr_data {
+	omap_dispc_isr_t	isr;
+	void			*arg;
+	u32			mask;
+};
+
+#define REG_GET(idx, start, end) \
+	FLD_GET(dispc_read_reg(idx), start, end)
+
+#define REG_FLD_MOD(idx, val, start, end)				\
+	dispc_write_reg(idx, FLD_MOD(dispc_read_reg(idx), val, start, end))
+
+static const struct dispc_reg dispc_reg_att[] = { DISPC_GFX_ATTRIBUTES,
+	DISPC_VID_ATTRIBUTES(0),
+	DISPC_VID_ATTRIBUTES(1) };
+
+static struct {
+	void __iomem    *base;
+
+	u32	fifo_size[3];
+
+	spinlock_t irq_lock;
+	u32 irq_error_mask;
+	struct omap_dispc_isr_data registered_isr[DISPC_MAX_NR_ISRS];
+	u32 error_irqs;
+	struct work_struct error_work;
+
+	u32		ctx[DISPC_SZ_REGS / sizeof(u32)];
+} dispc;
+
+static void _omap_dispc_set_irqs(void);
+
+static inline void dispc_write_reg(const struct dispc_reg idx, u32 val)
+{
+	__raw_writel(val, dispc.base + idx.idx);
+}
+
+static inline u32 dispc_read_reg(const struct dispc_reg idx)
+{
+	return __raw_readl(dispc.base + idx.idx);
+}
+
+#define SR(reg) \
+	dispc.ctx[(DISPC_##reg).idx / sizeof(u32)] = dispc_read_reg(DISPC_##reg)
+#define RR(reg) \
+	dispc_write_reg(DISPC_##reg, dispc.ctx[(DISPC_##reg).idx / sizeof(u32)])
+
+void dispc_save_context(void)
+{
+	if (cpu_is_omap24xx())
+		return;
+
+	SR(SYSCONFIG);
+	SR(IRQENABLE);
+	SR(CONTROL);
+	SR(CONFIG);
+	SR(DEFAULT_COLOR0);
+	SR(DEFAULT_COLOR1);
+	SR(TRANS_COLOR0);
+	SR(TRANS_COLOR1);
+	SR(LINE_NUMBER);
+	SR(TIMING_H);
+	SR(TIMING_V);
+	SR(POL_FREQ);
+	SR(DIVISOR);
+	SR(GLOBAL_ALPHA);
+	SR(SIZE_DIG);
+	SR(SIZE_LCD);
+
+	SR(GFX_BA0);
+	SR(GFX_BA1);
+	SR(GFX_POSITION);
+	SR(GFX_SIZE);
+	SR(GFX_ATTRIBUTES);
+	SR(GFX_FIFO_THRESHOLD);
+	SR(GFX_ROW_INC);
+	SR(GFX_PIXEL_INC);
+	SR(GFX_WINDOW_SKIP);
+	SR(GFX_TABLE_BA);
+
+	SR(DATA_CYCLE1);
+	SR(DATA_CYCLE2);
+	SR(DATA_CYCLE3);
+
+	SR(CPR_COEF_R);
+	SR(CPR_COEF_G);
+	SR(CPR_COEF_B);
+
+	SR(GFX_PRELOAD);
+
+	/* VID1 */
+	SR(VID_BA0(0));
+	SR(VID_BA1(0));
+	SR(VID_POSITION(0));
+	SR(VID_SIZE(0));
+	SR(VID_ATTRIBUTES(0));
+	SR(VID_FIFO_THRESHOLD(0));
+	SR(VID_ROW_INC(0));
+	SR(VID_PIXEL_INC(0));
+	SR(VID_FIR(0));
+	SR(VID_PICTURE_SIZE(0));
+	SR(VID_ACCU0(0));
+	SR(VID_ACCU1(0));
+
+	SR(VID_FIR_COEF_H(0, 0));
+	SR(VID_FIR_COEF_H(0, 1));
+	SR(VID_FIR_COEF_H(0, 2));
+	SR(VID_FIR_COEF_H(0, 3));
+	SR(VID_FIR_COEF_H(0, 4));
+	SR(VID_FIR_COEF_H(0, 5));
+	SR(VID_FIR_COEF_H(0, 6));
+	SR(VID_FIR_COEF_H(0, 7));
+
+	SR(VID_FIR_COEF_HV(0, 0));
+	SR(VID_FIR_COEF_HV(0, 1));
+	SR(VID_FIR_COEF_HV(0, 2));
+	SR(VID_FIR_COEF_HV(0, 3));
+	SR(VID_FIR_COEF_HV(0, 4));
+	SR(VID_FIR_COEF_HV(0, 5));
+	SR(VID_FIR_COEF_HV(0, 6));
+	SR(VID_FIR_COEF_HV(0, 7));
+
+	SR(VID_CONV_COEF(0, 0));
+	SR(VID_CONV_COEF(0, 1));
+	SR(VID_CONV_COEF(0, 2));
+	SR(VID_CONV_COEF(0, 3));
+	SR(VID_CONV_COEF(0, 4));
+
+	SR(VID_FIR_COEF_V(0, 0));
+	SR(VID_FIR_COEF_V(0, 1));
+	SR(VID_FIR_COEF_V(0, 2));
+	SR(VID_FIR_COEF_V(0, 3));
+	SR(VID_FIR_COEF_V(0, 4));
+	SR(VID_FIR_COEF_V(0, 5));
+	SR(VID_FIR_COEF_V(0, 6));
+	SR(VID_FIR_COEF_V(0, 7));
+
+	SR(VID_PRELOAD(0));
+
+	/* VID2 */
+	SR(VID_BA0(1));
+	SR(VID_BA1(1));
+	SR(VID_POSITION(1));
+	SR(VID_SIZE(1));
+	SR(VID_ATTRIBUTES(1));
+	SR(VID_FIFO_THRESHOLD(1));
+	SR(VID_ROW_INC(1));
+	SR(VID_PIXEL_INC(1));
+	SR(VID_FIR(1));
+	SR(VID_PICTURE_SIZE(1));
+	SR(VID_ACCU0(1));
+	SR(VID_ACCU1(1));
+
+	SR(VID_FIR_COEF_H(1, 0));
+	SR(VID_FIR_COEF_H(1, 1));
+	SR(VID_FIR_COEF_H(1, 2));
+	SR(VID_FIR_COEF_H(1, 3));
+	SR(VID_FIR_COEF_H(1, 4));
+	SR(VID_FIR_COEF_H(1, 5));
+	SR(VID_FIR_COEF_H(1, 6));
+	SR(VID_FIR_COEF_H(1, 7));
+
+	SR(VID_FIR_COEF_HV(1, 0));
+	SR(VID_FIR_COEF_HV(1, 1));
+	SR(VID_FIR_COEF_HV(1, 2));
+	SR(VID_FIR_COEF_HV(1, 3));
+	SR(VID_FIR_COEF_HV(1, 4));
+	SR(VID_FIR_COEF_HV(1, 5));
+	SR(VID_FIR_COEF_HV(1, 6));
+	SR(VID_FIR_COEF_HV(1, 7));
+
+	SR(VID_CONV_COEF(1, 0));
+	SR(VID_CONV_COEF(1, 1));
+	SR(VID_CONV_COEF(1, 2));
+	SR(VID_CONV_COEF(1, 3));
+	SR(VID_CONV_COEF(1, 4));
+
+	SR(VID_FIR_COEF_V(1, 0));
+	SR(VID_FIR_COEF_V(1, 1));
+	SR(VID_FIR_COEF_V(1, 2));
+	SR(VID_FIR_COEF_V(1, 3));
+	SR(VID_FIR_COEF_V(1, 4));
+	SR(VID_FIR_COEF_V(1, 5));
+	SR(VID_FIR_COEF_V(1, 6));
+	SR(VID_FIR_COEF_V(1, 7));
+
+	SR(VID_PRELOAD(1));
+}
+
+void dispc_restore_context(void)
+{
+	RR(SYSCONFIG);
+	RR(IRQENABLE);
+	/*RR(CONTROL);*/
+	RR(CONFIG);
+	RR(DEFAULT_COLOR0);
+	RR(DEFAULT_COLOR1);
+	RR(TRANS_COLOR0);
+	RR(TRANS_COLOR1);
+	RR(LINE_NUMBER);
+	RR(TIMING_H);
+	RR(TIMING_V);
+	RR(POL_FREQ);
+	RR(DIVISOR);
+	RR(GLOBAL_ALPHA);
+	RR(SIZE_DIG);
+	RR(SIZE_LCD);
+
+	RR(GFX_BA0);
+	RR(GFX_BA1);
+	RR(GFX_POSITION);
+	RR(GFX_SIZE);
+	RR(GFX_ATTRIBUTES);
+	RR(GFX_FIFO_THRESHOLD);
+	RR(GFX_ROW_INC);
+	RR(GFX_PIXEL_INC);
+	RR(GFX_WINDOW_SKIP);
+	RR(GFX_TABLE_BA);
+
+	RR(DATA_CYCLE1);
+	RR(DATA_CYCLE2);
+	RR(DATA_CYCLE3);
+
+	RR(CPR_COEF_R);
+	RR(CPR_COEF_G);
+	RR(CPR_COEF_B);
+
+	RR(GFX_PRELOAD);
+
+	/* VID1 */
+	RR(VID_BA0(0));
+	RR(VID_BA1(0));
+	RR(VID_POSITION(0));
+	RR(VID_SIZE(0));
+	RR(VID_ATTRIBUTES(0));
+	RR(VID_FIFO_THRESHOLD(0));
+	RR(VID_ROW_INC(0));
+	RR(VID_PIXEL_INC(0));
+	RR(VID_FIR(0));
+	RR(VID_PICTURE_SIZE(0));
+	RR(VID_ACCU0(0));
+	RR(VID_ACCU1(0));
+
+	RR(VID_FIR_COEF_H(0, 0));
+	RR(VID_FIR_COEF_H(0, 1));
+	RR(VID_FIR_COEF_H(0, 2));
+	RR(VID_FIR_COEF_H(0, 3));
+	RR(VID_FIR_COEF_H(0, 4));
+	RR(VID_FIR_COEF_H(0, 5));
+	RR(VID_FIR_COEF_H(0, 6));
+	RR(VID_FIR_COEF_H(0, 7));
+
+	RR(VID_FIR_COEF_HV(0, 0));
+	RR(VID_FIR_COEF_HV(0, 1));
+	RR(VID_FIR_COEF_HV(0, 2));
+	RR(VID_FIR_COEF_HV(0, 3));
+	RR(VID_FIR_COEF_HV(0, 4));
+	RR(VID_FIR_COEF_HV(0, 5));
+	RR(VID_FIR_COEF_HV(0, 6));
+	RR(VID_FIR_COEF_HV(0, 7));
+
+	RR(VID_CONV_COEF(0, 0));
+	RR(VID_CONV_COEF(0, 1));
+	RR(VID_CONV_COEF(0, 2));
+	RR(VID_CONV_COEF(0, 3));
+	RR(VID_CONV_COEF(0, 4));
+
+	RR(VID_FIR_COEF_V(0, 0));
+	RR(VID_FIR_COEF_V(0, 1));
+	RR(VID_FIR_COEF_V(0, 2));
+	RR(VID_FIR_COEF_V(0, 3));
+	RR(VID_FIR_COEF_V(0, 4));
+	RR(VID_FIR_COEF_V(0, 5));
+	RR(VID_FIR_COEF_V(0, 6));
+	RR(VID_FIR_COEF_V(0, 7));
+
+	RR(VID_PRELOAD(0));
+
+	/* VID2 */
+	RR(VID_BA0(1));
+	RR(VID_BA1(1));
+	RR(VID_POSITION(1));
+	RR(VID_SIZE(1));
+	RR(VID_ATTRIBUTES(1));
+	RR(VID_FIFO_THRESHOLD(1));
+	RR(VID_ROW_INC(1));
+	RR(VID_PIXEL_INC(1));
+	RR(VID_FIR(1));
+	RR(VID_PICTURE_SIZE(1));
+	RR(VID_ACCU0(1));
+	RR(VID_ACCU1(1));
+
+	RR(VID_FIR_COEF_H(1, 0));
+	RR(VID_FIR_COEF_H(1, 1));
+	RR(VID_FIR_COEF_H(1, 2));
+	RR(VID_FIR_COEF_H(1, 3));
+	RR(VID_FIR_COEF_H(1, 4));
+	RR(VID_FIR_COEF_H(1, 5));
+	RR(VID_FIR_COEF_H(1, 6));
+	RR(VID_FIR_COEF_H(1, 7));
+
+	RR(VID_FIR_COEF_HV(1, 0));
+	RR(VID_FIR_COEF_HV(1, 1));
+	RR(VID_FIR_COEF_HV(1, 2));
+	RR(VID_FIR_COEF_HV(1, 3));
+	RR(VID_FIR_COEF_HV(1, 4));
+	RR(VID_FIR_COEF_HV(1, 5));
+	RR(VID_FIR_COEF_HV(1, 6));
+	RR(VID_FIR_COEF_HV(1, 7));
+
+	RR(VID_CONV_COEF(1, 0));
+	RR(VID_CONV_COEF(1, 1));
+	RR(VID_CONV_COEF(1, 2));
+	RR(VID_CONV_COEF(1, 3));
+	RR(VID_CONV_COEF(1, 4));
+
+	RR(VID_FIR_COEF_V(1, 0));
+	RR(VID_FIR_COEF_V(1, 1));
+	RR(VID_FIR_COEF_V(1, 2));
+	RR(VID_FIR_COEF_V(1, 3));
+	RR(VID_FIR_COEF_V(1, 4));
+	RR(VID_FIR_COEF_V(1, 5));
+	RR(VID_FIR_COEF_V(1, 6));
+	RR(VID_FIR_COEF_V(1, 7));
+
+	RR(VID_PRELOAD(1));
+
+	/* enable last, because LCD & DIGIT enable are here */
+	RR(CONTROL);
+}
+
+#undef SR
+#undef RR
+
+static inline void enable_clocks(bool enable)
+{
+	if (enable)
+		dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+	else
+		dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+}
+
+bool dispc_go_busy(enum omap_channel channel)
+{
+	int bit;
+
+	if (channel == OMAP_DSS_CHANNEL_LCD)
+		bit = 5; /* GOLCD */
+	else
+		bit = 6; /* GODIGIT */
+
+	return REG_GET(DISPC_CONTROL, bit, bit) == 1;
+}
+
+void dispc_go(enum omap_channel channel)
+{
+	int bit;
+
+	enable_clocks(1);
+
+	if (channel == OMAP_DSS_CHANNEL_LCD)
+		bit = 0; /* LCDENABLE */
+	else
+		bit = 1; /* DIGITALENABLE */
+
+	/* if the channel is not enabled, we don't need GO */
+	if (REG_GET(DISPC_CONTROL, bit, bit) == 0)
+		goto end;
+
+	if (channel == OMAP_DSS_CHANNEL_LCD)
+		bit = 5; /* GOLCD */
+	else
+		bit = 6; /* GODIGIT */
+
+	if (REG_GET(DISPC_CONTROL, bit, bit) == 1) {
+		DSSERR("GO bit not down for channel %d\n", channel);
+		goto end;
+	}
+
+	DSSDBG("GO %s\n", channel == OMAP_DSS_CHANNEL_LCD ? "LCD" : "DIGIT");
+
+	REG_FLD_MOD(DISPC_CONTROL, 1, bit, bit);
+end:
+	enable_clocks(0);
+}
+
+static void _dispc_write_firh_reg(enum omap_plane plane, int reg, u32 value)
+{
+	BUG_ON(plane == OMAP_DSS_GFX);
+
+	dispc_write_reg(DISPC_VID_FIR_COEF_H(plane-1, reg), value);
+}
+
+static void _dispc_write_firhv_reg(enum omap_plane plane, int reg, u32 value)
+{
+	BUG_ON(plane == OMAP_DSS_GFX);
+
+	dispc_write_reg(DISPC_VID_FIR_COEF_HV(plane-1, reg), value);
+}
+
+static void _dispc_write_firv_reg(enum omap_plane plane, int reg, u32 value)
+{
+	BUG_ON(plane == OMAP_DSS_GFX);
+
+	dispc_write_reg(DISPC_VID_FIR_COEF_V(plane-1, reg), value);
+}
+
+static void _dispc_set_scale_coef(enum omap_plane plane, int hscaleup,
+		int vscaleup, int five_taps)
+{
+	/* Coefficients for horizontal up-sampling */
+	static const u32 coef_hup[8] = {
+		0x00800000,
+		0x0D7CF800,
+		0x1E70F5FF,
+		0x335FF5FE,
+		0xF74949F7,
+		0xF55F33FB,
+		0xF5701EFE,
+		0xF87C0DFF,
+	};
+
+	/* Coefficients for horizontal down-sampling */
+	static const u32 coef_hdown[8] = {
+		0x24382400,
+		0x28371FFE,
+		0x2C361BFB,
+		0x303516F9,
+		0x11343311,
+		0x1635300C,
+		0x1B362C08,
+		0x1F372804,
+	};
+
+	/* Coefficients for horizontal and vertical up-sampling */
+	static const u32 coef_hvup[2][8] = {
+		{
+		0x00800000,
+		0x037B02FF,
+		0x0C6F05FE,
+		0x205907FB,
+		0x00404000,
+		0x075920FE,
+		0x056F0CFF,
+		0x027B0300,
+		},
+		{
+		0x00800000,
+		0x0D7CF8FF,
+		0x1E70F5FE,
+		0x335FF5FB,
+		0xF7404000,
+		0xF55F33FE,
+		0xF5701EFF,
+		0xF87C0D00,
+		},
+	};
+
+	/* Coefficients for horizontal and vertical down-sampling */
+	static const u32 coef_hvdown[2][8] = {
+		{
+		0x24382400,
+		0x28391F04,
+		0x2D381B08,
+		0x3237170C,
+		0x123737F7,
+		0x173732F9,
+		0x1B382DFB,
+		0x1F3928FE,
+		},
+		{
+		0x24382400,
+		0x28371F04,
+		0x2C361B08,
+		0x3035160C,
+		0x113433F7,
+		0x163530F9,
+		0x1B362CFB,
+		0x1F3728FE,
+		},
+	};
+
+	/* Coefficients for vertical up-sampling */
+	static const u32 coef_vup[8] = {
+		0x00000000,
+		0x0000FF00,
+		0x0000FEFF,
+		0x0000FBFE,
+		0x000000F7,
+		0x0000FEFB,
+		0x0000FFFE,
+		0x000000FF,
+	};
+
+
+	/* Coefficients for vertical down-sampling */
+	static const u32 coef_vdown[8] = {
+		0x00000000,
+		0x000004FE,
+		0x000008FB,
+		0x00000CF9,
+		0x0000F711,
+		0x0000F90C,
+		0x0000FB08,
+		0x0000FE04,
+	};
+
+	const u32 *h_coef;
+	const u32 *hv_coef;
+	const u32 *hv_coef_mod;
+	const u32 *v_coef;
+	int i;
+
+	if (hscaleup)
+		h_coef = coef_hup;
+	else
+		h_coef = coef_hdown;
+
+	if (vscaleup) {
+		hv_coef = coef_hvup[five_taps];
+		v_coef = coef_vup;
+
+		if (hscaleup)
+			hv_coef_mod = NULL;
+		else
+			hv_coef_mod = coef_hvdown[five_taps];
+	} else {
+		hv_coef = coef_hvdown[five_taps];
+		v_coef = coef_vdown;
+
+		if (hscaleup)
+			hv_coef_mod = coef_hvup[five_taps];
+		else
+			hv_coef_mod = NULL;
+	}
+
+	for (i = 0; i < 8; i++) {
+		u32 h, hv;
+
+		h = h_coef[i];
+
+		hv = hv_coef[i];
+
+		if (hv_coef_mod) {
+			hv &= 0xffffff00;
+			hv |= (hv_coef_mod[i] & 0xff);
+		}
+
+		_dispc_write_firh_reg(plane, i, h);
+		_dispc_write_firhv_reg(plane, i, hv);
+	}
+
+	if (!five_taps)
+		return;
+
+	for (i = 0; i < 8; i++) {
+		u32 v;
+		v = v_coef[i];
+		_dispc_write_firv_reg(plane, i, v);
+	}
+}
+
+static void _dispc_setup_color_conv_coef(void)
+{
+	const struct color_conv_coef {
+		int  ry,  rcr,  rcb,   gy,  gcr,  gcb,   by,  bcr,  bcb;
+		int  full_range;
+	}  ctbl_bt601_5 = {
+		298,  409,    0,  298, -208, -100,  298,    0,  517, 0,
+	};
+
+	const struct color_conv_coef *ct;
+
+#define CVAL(x, y) (FLD_VAL(x, 26, 16) | FLD_VAL(y, 10, 0))
+
+	ct = &ctbl_bt601_5;
+
+	dispc_write_reg(DISPC_VID_CONV_COEF(0, 0), CVAL(ct->rcr, ct->ry));
+	dispc_write_reg(DISPC_VID_CONV_COEF(0, 1), CVAL(ct->gy,	 ct->rcb));
+	dispc_write_reg(DISPC_VID_CONV_COEF(0, 2), CVAL(ct->gcb, ct->gcr));
+	dispc_write_reg(DISPC_VID_CONV_COEF(0, 3), CVAL(ct->bcr, ct->by));
+	dispc_write_reg(DISPC_VID_CONV_COEF(0, 4), CVAL(0,       ct->bcb));
+
+	dispc_write_reg(DISPC_VID_CONV_COEF(1, 0), CVAL(ct->rcr, ct->ry));
+	dispc_write_reg(DISPC_VID_CONV_COEF(1, 1), CVAL(ct->gy,	 ct->rcb));
+	dispc_write_reg(DISPC_VID_CONV_COEF(1, 2), CVAL(ct->gcb, ct->gcr));
+	dispc_write_reg(DISPC_VID_CONV_COEF(1, 3), CVAL(ct->bcr, ct->by));
+	dispc_write_reg(DISPC_VID_CONV_COEF(1, 4), CVAL(0,       ct->bcb));
+
+#undef CVAL
+
+	REG_FLD_MOD(DISPC_VID_ATTRIBUTES(0), ct->full_range, 11, 11);
+	REG_FLD_MOD(DISPC_VID_ATTRIBUTES(1), ct->full_range, 11, 11);
+}
+
+
+static void _dispc_set_plane_ba0(enum omap_plane plane, u32 paddr)
+{
+	const struct dispc_reg ba0_reg[] = { DISPC_GFX_BA0,
+		DISPC_VID_BA0(0),
+		DISPC_VID_BA0(1) };
+
+	dispc_write_reg(ba0_reg[plane], paddr);
+}
+
+static void _dispc_set_plane_ba1(enum omap_plane plane, u32 paddr)
+{
+	const struct dispc_reg ba1_reg[] = { DISPC_GFX_BA1,
+				      DISPC_VID_BA1(0),
+				      DISPC_VID_BA1(1) };
+
+	dispc_write_reg(ba1_reg[plane], paddr);
+}
+
+static void _dispc_set_plane_pos(enum omap_plane plane, int x, int y)
+{
+	const struct dispc_reg pos_reg[] = { DISPC_GFX_POSITION,
+				      DISPC_VID_POSITION(0),
+				      DISPC_VID_POSITION(1) };
+
+	u32 val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0);
+	dispc_write_reg(pos_reg[plane], val);
+}
+
+static void _dispc_set_pic_size(enum omap_plane plane, int width, int height)
+{
+	const struct dispc_reg siz_reg[] = { DISPC_GFX_SIZE,
+				      DISPC_VID_PICTURE_SIZE(0),
+				      DISPC_VID_PICTURE_SIZE(1) };
+	u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
+	dispc_write_reg(siz_reg[plane], val);
+}
+
+static void _dispc_set_vid_size(enum omap_plane plane, int width, int height)
+{
+	u32 val;
+	const struct dispc_reg vsi_reg[] = { DISPC_VID_SIZE(0),
+				      DISPC_VID_SIZE(1) };
+
+	BUG_ON(plane == OMAP_DSS_GFX);
+
+	val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
+	dispc_write_reg(vsi_reg[plane-1], val);
+}
+
+static void _dispc_setup_global_alpha(enum omap_plane plane, u8 global_alpha)
+{
+
+	BUG_ON(plane == OMAP_DSS_VIDEO1);
+
+	if (cpu_is_omap24xx())
+		return;
+
+	if (plane == OMAP_DSS_GFX)
+		REG_FLD_MOD(DISPC_GLOBAL_ALPHA, global_alpha, 7, 0);
+	else if (plane == OMAP_DSS_VIDEO2)
+		REG_FLD_MOD(DISPC_GLOBAL_ALPHA, global_alpha, 23, 16);
+}
+
+static void _dispc_set_pix_inc(enum omap_plane plane, s32 inc)
+{
+	const struct dispc_reg ri_reg[] = { DISPC_GFX_PIXEL_INC,
+				     DISPC_VID_PIXEL_INC(0),
+				     DISPC_VID_PIXEL_INC(1) };
+
+	dispc_write_reg(ri_reg[plane], inc);
+}
+
+static void _dispc_set_row_inc(enum omap_plane plane, s32 inc)
+{
+	const struct dispc_reg ri_reg[] = { DISPC_GFX_ROW_INC,
+				     DISPC_VID_ROW_INC(0),
+				     DISPC_VID_ROW_INC(1) };
+
+	dispc_write_reg(ri_reg[plane], inc);
+}
+
+static void _dispc_set_color_mode(enum omap_plane plane,
+		enum omap_color_mode color_mode)
+{
+	u32 m = 0;
+
+	switch (color_mode) {
+	case OMAP_DSS_COLOR_CLUT1:
+		m = 0x0; break;
+	case OMAP_DSS_COLOR_CLUT2:
+		m = 0x1; break;
+	case OMAP_DSS_COLOR_CLUT4:
+		m = 0x2; break;
+	case OMAP_DSS_COLOR_CLUT8:
+		m = 0x3; break;
+	case OMAP_DSS_COLOR_RGB12U:
+		m = 0x4; break;
+	case OMAP_DSS_COLOR_ARGB16:
+		m = 0x5; break;
+	case OMAP_DSS_COLOR_RGB16:
+		m = 0x6; break;
+	case OMAP_DSS_COLOR_RGB24U:
+		m = 0x8; break;
+	case OMAP_DSS_COLOR_RGB24P:
+		m = 0x9; break;
+	case OMAP_DSS_COLOR_YUV2:
+		m = 0xa; break;
+	case OMAP_DSS_COLOR_UYVY:
+		m = 0xb; break;
+	case OMAP_DSS_COLOR_ARGB32:
+		m = 0xc; break;
+	case OMAP_DSS_COLOR_RGBA32:
+		m = 0xd; break;
+	case OMAP_DSS_COLOR_RGBX32:
+		m = 0xe; break;
+	default:
+		BUG(); break;
+	}
+
+	REG_FLD_MOD(dispc_reg_att[plane], m, 4, 1);
+}
+
+static void _dispc_set_channel_out(enum omap_plane plane,
+		enum omap_channel channel)
+{
+	int shift;
+	u32 val;
+
+	switch (plane) {
+	case OMAP_DSS_GFX:
+		shift = 8;
+		break;
+	case OMAP_DSS_VIDEO1:
+	case OMAP_DSS_VIDEO2:
+		shift = 16;
+		break;
+	default:
+		BUG();
+		return;
+	}
+
+	val = dispc_read_reg(dispc_reg_att[plane]);
+	val = FLD_MOD(val, channel, shift, shift);
+	dispc_write_reg(dispc_reg_att[plane], val);
+}
+
+void dispc_set_burst_size(enum omap_plane plane,
+		enum omap_burst_size burst_size)
+{
+	int shift;
+	u32 val;
+
+	enable_clocks(1);
+
+	switch (plane) {
+	case OMAP_DSS_GFX:
+		shift = 6;
+		break;
+	case OMAP_DSS_VIDEO1:
+	case OMAP_DSS_VIDEO2:
+		shift = 14;
+		break;
+	default:
+		BUG();
+		return;
+	}
+
+	val = dispc_read_reg(dispc_reg_att[plane]);
+	val = FLD_MOD(val, burst_size, shift+1, shift);
+	dispc_write_reg(dispc_reg_att[plane], val);
+
+	enable_clocks(0);
+}
+
+static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable)
+{
+	u32 val;
+
+	BUG_ON(plane == OMAP_DSS_GFX);
+
+	val = dispc_read_reg(dispc_reg_att[plane]);
+	val = FLD_MOD(val, enable, 9, 9);
+	dispc_write_reg(dispc_reg_att[plane], val);
+}
+
+void dispc_enable_replication(enum omap_plane plane, bool enable)
+{
+	int bit;
+
+	if (plane == OMAP_DSS_GFX)
+		bit = 5;
+	else
+		bit = 10;
+
+	enable_clocks(1);
+	REG_FLD_MOD(dispc_reg_att[plane], enable, bit, bit);
+	enable_clocks(0);
+}
+
+void dispc_set_lcd_size(u16 width, u16 height)
+{
+	u32 val;
+	BUG_ON((width > (1 << 11)) || (height > (1 << 11)));
+	val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
+	enable_clocks(1);
+	dispc_write_reg(DISPC_SIZE_LCD, val);
+	enable_clocks(0);
+}
+
+void dispc_set_digit_size(u16 width, u16 height)
+{
+	u32 val;
+	BUG_ON((width > (1 << 11)) || (height > (1 << 11)));
+	val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
+	enable_clocks(1);
+	dispc_write_reg(DISPC_SIZE_DIG, val);
+	enable_clocks(0);
+}
+
+static void dispc_read_plane_fifo_sizes(void)
+{
+	const struct dispc_reg fsz_reg[] = { DISPC_GFX_FIFO_SIZE_STATUS,
+				      DISPC_VID_FIFO_SIZE_STATUS(0),
+				      DISPC_VID_FIFO_SIZE_STATUS(1) };
+	u32 size;
+	int plane;
+
+	enable_clocks(1);
+
+	for (plane = 0; plane < ARRAY_SIZE(dispc.fifo_size); ++plane) {
+		if (cpu_is_omap24xx())
+			size = FLD_GET(dispc_read_reg(fsz_reg[plane]), 8, 0);
+		else if (cpu_is_omap34xx())
+			size = FLD_GET(dispc_read_reg(fsz_reg[plane]), 10, 0);
+		else
+			BUG();
+
+		dispc.fifo_size[plane] = size;
+	}
+
+	enable_clocks(0);
+}
+
+u32 dispc_get_plane_fifo_size(enum omap_plane plane)
+{
+	return dispc.fifo_size[plane];
+}
+
+void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high)
+{
+	const struct dispc_reg ftrs_reg[] = { DISPC_GFX_FIFO_THRESHOLD,
+				       DISPC_VID_FIFO_THRESHOLD(0),
+				       DISPC_VID_FIFO_THRESHOLD(1) };
+	enable_clocks(1);
+
+	DSSDBG("fifo(%d) low/high old %u/%u, new %u/%u\n",
+			plane,
+			REG_GET(ftrs_reg[plane], 11, 0),
+			REG_GET(ftrs_reg[plane], 27, 16),
+			low, high);
+
+	if (cpu_is_omap24xx())
+		dispc_write_reg(ftrs_reg[plane],
+				FLD_VAL(high, 24, 16) | FLD_VAL(low, 8, 0));
+	else
+		dispc_write_reg(ftrs_reg[plane],
+				FLD_VAL(high, 27, 16) | FLD_VAL(low, 11, 0));
+
+	enable_clocks(0);
+}
+
+void dispc_enable_fifomerge(bool enable)
+{
+	enable_clocks(1);
+
+	DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled");
+	REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14);
+
+	enable_clocks(0);
+}
+
+static void _dispc_set_fir(enum omap_plane plane, int hinc, int vinc)
+{
+	u32 val;
+	const struct dispc_reg fir_reg[] = { DISPC_VID_FIR(0),
+				      DISPC_VID_FIR(1) };
+
+	BUG_ON(plane == OMAP_DSS_GFX);
+
+	if (cpu_is_omap24xx())
+		val = FLD_VAL(vinc, 27, 16) | FLD_VAL(hinc, 11, 0);
+	else
+		val = FLD_VAL(vinc, 28, 16) | FLD_VAL(hinc, 12, 0);
+	dispc_write_reg(fir_reg[plane-1], val);
+}
+
+static void _dispc_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu)
+{
+	u32 val;
+	const struct dispc_reg ac0_reg[] = { DISPC_VID_ACCU0(0),
+				      DISPC_VID_ACCU0(1) };
+
+	BUG_ON(plane == OMAP_DSS_GFX);
+
+	val = FLD_VAL(vaccu, 25, 16) | FLD_VAL(haccu, 9, 0);
+	dispc_write_reg(ac0_reg[plane-1], val);
+}
+
+static void _dispc_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu)
+{
+	u32 val;
+	const struct dispc_reg ac1_reg[] = { DISPC_VID_ACCU1(0),
+				      DISPC_VID_ACCU1(1) };
+
+	BUG_ON(plane == OMAP_DSS_GFX);
+
+	val = FLD_VAL(vaccu, 25, 16) | FLD_VAL(haccu, 9, 0);
+	dispc_write_reg(ac1_reg[plane-1], val);
+}
+
+
+static void _dispc_set_scaling(enum omap_plane plane,
+		u16 orig_width, u16 orig_height,
+		u16 out_width, u16 out_height,
+		bool ilace, bool five_taps,
+		bool fieldmode)
+{
+	int fir_hinc;
+	int fir_vinc;
+	int hscaleup, vscaleup;
+	int accu0 = 0;
+	int accu1 = 0;
+	u32 l;
+
+	BUG_ON(plane == OMAP_DSS_GFX);
+
+	hscaleup = orig_width <= out_width;
+	vscaleup = orig_height <= out_height;
+
+	_dispc_set_scale_coef(plane, hscaleup, vscaleup, five_taps);
+
+	if (!orig_width || orig_width == out_width)
+		fir_hinc = 0;
+	else
+		fir_hinc = 1024 * orig_width / out_width;
+
+	if (!orig_height || orig_height == out_height)
+		fir_vinc = 0;
+	else
+		fir_vinc = 1024 * orig_height / out_height;
+
+	_dispc_set_fir(plane, fir_hinc, fir_vinc);
+
+	l = dispc_read_reg(dispc_reg_att[plane]);
+	l &= ~((0x0f << 5) | (0x3 << 21));
+
+	l |= fir_hinc ? (1 << 5) : 0;
+	l |= fir_vinc ? (1 << 6) : 0;
+
+	l |= hscaleup ? 0 : (1 << 7);
+	l |= vscaleup ? 0 : (1 << 8);
+
+	l |= five_taps ? (1 << 21) : 0;
+	l |= five_taps ? (1 << 22) : 0;
+
+	dispc_write_reg(dispc_reg_att[plane], l);
+
+	/*
+	 * field 0 = even field = bottom field
+	 * field 1 = odd field = top field
+	 */
+	if (ilace && !fieldmode) {
+		accu1 = 0;
+		accu0 = (fir_vinc / 2) & 0x3ff;
+		if (accu0 >= 1024/2) {
+			accu1 = 1024/2;
+			accu0 -= accu1;
+		}
+	}
+
+	_dispc_set_vid_accu0(plane, 0, accu0);
+	_dispc_set_vid_accu1(plane, 0, accu1);
+}
+
+static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
+		bool mirroring, enum omap_color_mode color_mode)
+{
+	if (color_mode == OMAP_DSS_COLOR_YUV2 ||
+			color_mode == OMAP_DSS_COLOR_UYVY) {
+		int vidrot = 0;
+
+		if (mirroring) {
+			switch (rotation) {
+			case OMAP_DSS_ROT_0:
+				vidrot = 2;
+				break;
+			case OMAP_DSS_ROT_90:
+				vidrot = 1;
+				break;
+			case OMAP_DSS_ROT_180:
+				vidrot = 0;
+				break;
+			case OMAP_DSS_ROT_270:
+				vidrot = 3;
+				break;
+			}
+		} else {
+			switch (rotation) {
+			case OMAP_DSS_ROT_0:
+				vidrot = 0;
+				break;
+			case OMAP_DSS_ROT_90:
+				vidrot = 1;
+				break;
+			case OMAP_DSS_ROT_180:
+				vidrot = 2;
+				break;
+			case OMAP_DSS_ROT_270:
+				vidrot = 3;
+				break;
+			}
+		}
+
+		REG_FLD_MOD(dispc_reg_att[plane], vidrot, 13, 12);
+
+		if (rotation == OMAP_DSS_ROT_90 || rotation == OMAP_DSS_ROT_270)
+			REG_FLD_MOD(dispc_reg_att[plane], 0x1, 18, 18);
+		else
+			REG_FLD_MOD(dispc_reg_att[plane], 0x0, 18, 18);
+	} else {
+		REG_FLD_MOD(dispc_reg_att[plane], 0, 13, 12);
+		REG_FLD_MOD(dispc_reg_att[plane], 0, 18, 18);
+	}
+}
+
+static int color_mode_to_bpp(enum omap_color_mode color_mode)
+{
+	switch (color_mode) {
+	case OMAP_DSS_COLOR_CLUT1:
+		return 1;
+	case OMAP_DSS_COLOR_CLUT2:
+		return 2;
+	case OMAP_DSS_COLOR_CLUT4:
+		return 4;
+	case OMAP_DSS_COLOR_CLUT8:
+		return 8;
+	case OMAP_DSS_COLOR_RGB12U:
+	case OMAP_DSS_COLOR_RGB16:
+	case OMAP_DSS_COLOR_ARGB16:
+	case OMAP_DSS_COLOR_YUV2:
+	case OMAP_DSS_COLOR_UYVY:
+		return 16;
+	case OMAP_DSS_COLOR_RGB24P:
+		return 24;
+	case OMAP_DSS_COLOR_RGB24U:
+	case OMAP_DSS_COLOR_ARGB32:
+	case OMAP_DSS_COLOR_RGBA32:
+	case OMAP_DSS_COLOR_RGBX32:
+		return 32;
+	default:
+		BUG();
+	}
+}
+
+static s32 pixinc(int pixels, u8 ps)
+{
+	if (pixels == 1)
+		return 1;
+	else if (pixels > 1)
+		return 1 + (pixels - 1) * ps;
+	else if (pixels < 0)
+		return 1 - (-pixels + 1) * ps;
+	else
+		BUG();
+}
+
+static void calc_vrfb_rotation_offset(u8 rotation, bool mirror,
+		u16 screen_width,
+		u16 width, u16 height,
+		enum omap_color_mode color_mode, bool fieldmode,
+		unsigned int field_offset,
+		unsigned *offset0, unsigned *offset1,
+		s32 *row_inc, s32 *pix_inc)
+{
+	u8 ps;
+
+	/* FIXME CLUT formats */
+	switch (color_mode) {
+	case OMAP_DSS_COLOR_CLUT1:
+	case OMAP_DSS_COLOR_CLUT2:
+	case OMAP_DSS_COLOR_CLUT4:
+	case OMAP_DSS_COLOR_CLUT8:
+		BUG();
+		return;
+	case OMAP_DSS_COLOR_YUV2:
+	case OMAP_DSS_COLOR_UYVY:
+		ps = 4;
+		break;
+	default:
+		ps = color_mode_to_bpp(color_mode) / 8;
+		break;
+	}
+
+	DSSDBG("calc_rot(%d): scrw %d, %dx%d\n", rotation, screen_width,
+			width, height);
+
+	/*
+	 * field 0 = even field = bottom field
+	 * field 1 = odd field = top field
+	 */
+	switch (rotation + mirror * 4) {
+	case OMAP_DSS_ROT_0:
+	case OMAP_DSS_ROT_180:
+		/*
+		 * If the pixel format is YUV or UYVY divide the width
+		 * of the image by 2 for 0 and 180 degree rotation.
+		 */
+		if (color_mode == OMAP_DSS_COLOR_YUV2 ||
+			color_mode == OMAP_DSS_COLOR_UYVY)
+			width = width >> 1;
+	case OMAP_DSS_ROT_90:
+	case OMAP_DSS_ROT_270:
+		*offset1 = 0;
+		if (field_offset)
+			*offset0 = field_offset * screen_width * ps;
+		else
+			*offset0 = 0;
+
+		*row_inc = pixinc(1 + (screen_width - width) +
+				(fieldmode ? screen_width : 0),
+				ps);
+		*pix_inc = pixinc(1, ps);
+		break;
+
+	case OMAP_DSS_ROT_0 + 4:
+	case OMAP_DSS_ROT_180 + 4:
+		/* If the pixel format is YUV or UYVY divide the width
+		 * of the image by 2  for 0 degree and 180 degree
+		 */
+		if (color_mode == OMAP_DSS_COLOR_YUV2 ||
+			color_mode == OMAP_DSS_COLOR_UYVY)
+			width = width >> 1;
+	case OMAP_DSS_ROT_90 + 4:
+	case OMAP_DSS_ROT_270 + 4:
+		*offset1 = 0;
+		if (field_offset)
+			*offset0 = field_offset * screen_width * ps;
+		else
+			*offset0 = 0;
+		*row_inc = pixinc(1 - (screen_width + width) -
+				(fieldmode ? screen_width : 0),
+				ps);
+		*pix_inc = pixinc(1, ps);
+		break;
+
+	default:
+		BUG();
+	}
+}
+
+static void calc_dma_rotation_offset(u8 rotation, bool mirror,
+		u16 screen_width,
+		u16 width, u16 height,
+		enum omap_color_mode color_mode, bool fieldmode,
+		unsigned int field_offset,
+		unsigned *offset0, unsigned *offset1,
+		s32 *row_inc, s32 *pix_inc)
+{
+	u8 ps;
+	u16 fbw, fbh;
+
+	/* FIXME CLUT formats */
+	switch (color_mode) {
+	case OMAP_DSS_COLOR_CLUT1:
+	case OMAP_DSS_COLOR_CLUT2:
+	case OMAP_DSS_COLOR_CLUT4:
+	case OMAP_DSS_COLOR_CLUT8:
+		BUG();
+		return;
+	default:
+		ps = color_mode_to_bpp(color_mode) / 8;
+		break;
+	}
+
+	DSSDBG("calc_rot(%d): scrw %d, %dx%d\n", rotation, screen_width,
+			width, height);
+
+	/* width & height are overlay sizes, convert to fb sizes */
+
+	if (rotation == OMAP_DSS_ROT_0 || rotation == OMAP_DSS_ROT_180) {
+		fbw = width;
+		fbh = height;
+	} else {
+		fbw = height;
+		fbh = width;
+	}
+
+	/*
+	 * field 0 = even field = bottom field
+	 * field 1 = odd field = top field
+	 */
+	switch (rotation + mirror * 4) {
+	case OMAP_DSS_ROT_0:
+		*offset1 = 0;
+		if (field_offset)
+			*offset0 = *offset1 + field_offset * screen_width * ps;
+		else
+			*offset0 = *offset1;
+		*row_inc = pixinc(1 + (screen_width - fbw) +
+				(fieldmode ? screen_width : 0),
+				ps);
+		*pix_inc = pixinc(1, ps);
+		break;
+	case OMAP_DSS_ROT_90:
+		*offset1 = screen_width * (fbh - 1) * ps;
+		if (field_offset)
+			*offset0 = *offset1 + field_offset * ps;
+		else
+			*offset0 = *offset1;
+		*row_inc = pixinc(screen_width * (fbh - 1) + 1 +
+				(fieldmode ? 1 : 0), ps);
+		*pix_inc = pixinc(-screen_width, ps);
+		break;
+	case OMAP_DSS_ROT_180:
+		*offset1 = (screen_width * (fbh - 1) + fbw - 1) * ps;
+		if (field_offset)
+			*offset0 = *offset1 - field_offset * screen_width * ps;
+		else
+			*offset0 = *offset1;
+		*row_inc = pixinc(-1 -
+				(screen_width - fbw) -
+				(fieldmode ? screen_width : 0),
+				ps);
+		*pix_inc = pixinc(-1, ps);
+		break;
+	case OMAP_DSS_ROT_270:
+		*offset1 = (fbw - 1) * ps;
+		if (field_offset)
+			*offset0 = *offset1 - field_offset * ps;
+		else
+			*offset0 = *offset1;
+		*row_inc = pixinc(-screen_width * (fbh - 1) - 1 -
+				(fieldmode ? 1 : 0), ps);
+		*pix_inc = pixinc(screen_width, ps);
+		break;
+
+	/* mirroring */
+	case OMAP_DSS_ROT_0 + 4:
+		*offset1 = (fbw - 1) * ps;
+		if (field_offset)
+			*offset0 = *offset1 + field_offset * screen_width * ps;
+		else
+			*offset0 = *offset1;
+		*row_inc = pixinc(screen_width * 2 - 1 +
+				(fieldmode ? screen_width : 0),
+				ps);
+		*pix_inc = pixinc(-1, ps);
+		break;
+
+	case OMAP_DSS_ROT_90 + 4:
+		*offset1 = 0;
+		if (field_offset)
+			*offset0 = *offset1 + field_offset * ps;
+		else
+			*offset0 = *offset1;
+		*row_inc = pixinc(-screen_width * (fbh - 1) + 1 +
+				(fieldmode ? 1 : 0),
+				ps);
+		*pix_inc = pixinc(screen_width, ps);
+		break;
+
+	case OMAP_DSS_ROT_180 + 4:
+		*offset1 = screen_width * (fbh - 1) * ps;
+		if (field_offset)
+			*offset0 = *offset1 - field_offset * screen_width * ps;
+		else
+			*offset0 = *offset1;
+		*row_inc = pixinc(1 - screen_width * 2 -
+				(fieldmode ? screen_width : 0),
+				ps);
+		*pix_inc = pixinc(1, ps);
+		break;
+
+	case OMAP_DSS_ROT_270 + 4:
+		*offset1 = (screen_width * (fbh - 1) + fbw - 1) * ps;
+		if (field_offset)
+			*offset0 = *offset1 - field_offset * ps;
+		else
+			*offset0 = *offset1;
+		*row_inc = pixinc(screen_width * (fbh - 1) - 1 -
+				(fieldmode ? 1 : 0),
+				ps);
+		*pix_inc = pixinc(-screen_width, ps);
+		break;
+
+	default:
+		BUG();
+	}
+}
+
+static unsigned long calc_fclk_five_taps(u16 width, u16 height,
+		u16 out_width, u16 out_height, enum omap_color_mode color_mode)
+{
+	u32 fclk = 0;
+	/* FIXME venc pclk? */
+	u64 tmp, pclk = dispc_pclk_rate();
+
+	if (height > out_height) {
+		/* FIXME get real display PPL */
+		unsigned int ppl = 800;
+
+		tmp = pclk * height * out_width;
+		do_div(tmp, 2 * out_height * ppl);
+		fclk = tmp;
+
+		if (height > 2 * out_height && ppl != out_width) {
+			tmp = pclk * (height - 2 * out_height) * out_width;
+			do_div(tmp, 2 * out_height * (ppl - out_width));
+			fclk = max(fclk, (u32) tmp);
+		}
+	}
+
+	if (width > out_width) {
+		tmp = pclk * width;
+		do_div(tmp, out_width);
+		fclk = max(fclk, (u32) tmp);
+
+		if (color_mode == OMAP_DSS_COLOR_RGB24U)
+			fclk <<= 1;
+	}
+
+	return fclk;
+}
+
+static unsigned long calc_fclk(u16 width, u16 height,
+		u16 out_width, u16 out_height)
+{
+	unsigned int hf, vf;
+
+	/*
+	 * FIXME how to determine the 'A' factor
+	 * for the no downscaling case ?
+	 */
+
+	if (width > 3 * out_width)
+		hf = 4;
+	else if (width > 2 * out_width)
+		hf = 3;
+	else if (width > out_width)
+		hf = 2;
+	else
+		hf = 1;
+
+	if (height > out_height)
+		vf = 2;
+	else
+		vf = 1;
+
+	/* FIXME venc pclk? */
+	return dispc_pclk_rate() * vf * hf;
+}
+
+void dispc_set_channel_out(enum omap_plane plane, enum omap_channel channel_out)
+{
+	enable_clocks(1);
+	_dispc_set_channel_out(plane, channel_out);
+	enable_clocks(0);
+}
+
+static int _dispc_setup_plane(enum omap_plane plane,
+		u32 paddr, u16 screen_width,
+		u16 pos_x, u16 pos_y,
+		u16 width, u16 height,
+		u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode,
+		bool ilace,
+		enum omap_dss_rotation_type rotation_type,
+		u8 rotation, int mirror,
+		u8 global_alpha)
+{
+	const int maxdownscale = cpu_is_omap34xx() ? 4 : 2;
+	bool five_taps = 0;
+	bool fieldmode = 0;
+	int cconv = 0;
+	unsigned offset0, offset1;
+	s32 row_inc;
+	s32 pix_inc;
+	u16 frame_height = height;
+	unsigned int field_offset = 0;
+
+	if (paddr == 0)
+		return -EINVAL;
+
+	if (ilace && height == out_height)
+		fieldmode = 1;
+
+	if (ilace) {
+		if (fieldmode)
+			height /= 2;
+		pos_y /= 2;
+		out_height /= 2;
+
+		DSSDBG("adjusting for ilace: height %d, pos_y %d, "
+				"out_height %d\n",
+				height, pos_y, out_height);
+	}
+
+	if (plane == OMAP_DSS_GFX) {
+		if (width != out_width || height != out_height)
+			return -EINVAL;
+
+		switch (color_mode) {
+		case OMAP_DSS_COLOR_ARGB16:
+		case OMAP_DSS_COLOR_ARGB32:
+		case OMAP_DSS_COLOR_RGBA32:
+		case OMAP_DSS_COLOR_RGBX32:
+			if (cpu_is_omap24xx())
+				return -EINVAL;
+			/* fall through */
+		case OMAP_DSS_COLOR_RGB12U:
+		case OMAP_DSS_COLOR_RGB16:
+		case OMAP_DSS_COLOR_RGB24P:
+		case OMAP_DSS_COLOR_RGB24U:
+			break;
+
+		default:
+			return -EINVAL;
+		}
+	} else {
+		/* video plane */
+
+		unsigned long fclk = 0;
+
+		if (out_width < width / maxdownscale ||
+		   out_width > width * 8)
+			return -EINVAL;
+
+		if (out_height < height / maxdownscale ||
+		   out_height > height * 8)
+			return -EINVAL;
+
+		switch (color_mode) {
+		case OMAP_DSS_COLOR_RGBX32:
+		case OMAP_DSS_COLOR_RGB12U:
+			if (cpu_is_omap24xx())
+				return -EINVAL;
+			/* fall through */
+		case OMAP_DSS_COLOR_RGB16:
+		case OMAP_DSS_COLOR_RGB24P:
+		case OMAP_DSS_COLOR_RGB24U:
+			break;
+
+		case OMAP_DSS_COLOR_ARGB16:
+		case OMAP_DSS_COLOR_ARGB32:
+		case OMAP_DSS_COLOR_RGBA32:
+			if (cpu_is_omap24xx())
+				return -EINVAL;
+			if (plane == OMAP_DSS_VIDEO1)
+				return -EINVAL;
+			break;
+
+		case OMAP_DSS_COLOR_YUV2:
+		case OMAP_DSS_COLOR_UYVY:
+			cconv = 1;
+			break;
+
+		default:
+			return -EINVAL;
+		}
+
+		/* Must use 5-tap filter? */
+		five_taps = height > out_height * 2;
+
+		if (!five_taps) {
+			fclk = calc_fclk(width, height,
+					out_width, out_height);
+
+			/* Try 5-tap filter if 3-tap fclk is too high */
+			if (cpu_is_omap34xx() && height > out_height &&
+					fclk > dispc_fclk_rate())
+				five_taps = true;
+		}
+
+		if (width > (2048 >> five_taps)) {
+			DSSERR("failed to set up scaling, fclk too low\n");
+			return -EINVAL;
+		}
+
+		if (five_taps)
+			fclk = calc_fclk_five_taps(width, height,
+					out_width, out_height, color_mode);
+
+		DSSDBG("required fclk rate = %lu Hz\n", fclk);
+		DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate());
+
+		if (fclk > dispc_fclk_rate()) {
+			DSSERR("failed to set up scaling, "
+					"required fclk rate = %lu Hz, "
+					"current fclk rate = %lu Hz\n",
+					fclk, dispc_fclk_rate());
+			return -EINVAL;
+		}
+	}
+
+	if (ilace && !fieldmode) {
+		/*
+		 * when downscaling the bottom field may have to start several
+		 * source lines below the top field. Unfortunately ACCUI
+		 * registers will only hold the fractional part of the offset
+		 * so the integer part must be added to the base address of the
+		 * bottom field.
+		 */
+		if (!height || height == out_height)
+			field_offset = 0;
+		else
+			field_offset = height / out_height / 2;
+	}
+
+	/* Fields are independent but interleaved in memory. */
+	if (fieldmode)
+		field_offset = 1;
+
+	if (rotation_type == OMAP_DSS_ROT_DMA)
+		calc_dma_rotation_offset(rotation, mirror,
+				screen_width, width, frame_height, color_mode,
+				fieldmode, field_offset,
+				&offset0, &offset1, &row_inc, &pix_inc);
+	else
+		calc_vrfb_rotation_offset(rotation, mirror,
+				screen_width, width, frame_height, color_mode,
+				fieldmode, field_offset,
+				&offset0, &offset1, &row_inc, &pix_inc);
+
+	DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n",
+			offset0, offset1, row_inc, pix_inc);
+
+	_dispc_set_color_mode(plane, color_mode);
+
+	_dispc_set_plane_ba0(plane, paddr + offset0);
+	_dispc_set_plane_ba1(plane, paddr + offset1);
+
+	_dispc_set_row_inc(plane, row_inc);
+	_dispc_set_pix_inc(plane, pix_inc);
+
+	DSSDBG("%d,%d %dx%d -> %dx%d\n", pos_x, pos_y, width, height,
+			out_width, out_height);
+
+	_dispc_set_plane_pos(plane, pos_x, pos_y);
+
+	_dispc_set_pic_size(plane, width, height);
+
+	if (plane != OMAP_DSS_GFX) {
+		_dispc_set_scaling(plane, width, height,
+				   out_width, out_height,
+				   ilace, five_taps, fieldmode);
+		_dispc_set_vid_size(plane, out_width, out_height);
+		_dispc_set_vid_color_conv(plane, cconv);
+	}
+
+	_dispc_set_rotation_attrs(plane, rotation, mirror, color_mode);
+
+	if (plane != OMAP_DSS_VIDEO1)
+		_dispc_setup_global_alpha(plane, global_alpha);
+
+	return 0;
+}
+
+static void _dispc_enable_plane(enum omap_plane plane, bool enable)
+{
+	REG_FLD_MOD(dispc_reg_att[plane], enable ? 1 : 0, 0, 0);
+}
+
+static void dispc_disable_isr(void *data, u32 mask)
+{
+	struct completion *compl = data;
+	complete(compl);
+}
+
+static void _enable_lcd_out(bool enable)
+{
+	REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0);
+}
+
+void dispc_enable_lcd_out(bool enable)
+{
+	struct completion frame_done_completion;
+	bool is_on;
+	int r;
+
+	enable_clocks(1);
+
+	/* When we disable LCD output, we need to wait until frame is done.
+	 * Otherwise the DSS is still working, and turning off the clocks
+	 * prevents DSS from going to OFF mode */
+	is_on = REG_GET(DISPC_CONTROL, 0, 0);
+
+	if (!enable && is_on) {
+		init_completion(&frame_done_completion);
+
+		r = omap_dispc_register_isr(dispc_disable_isr,
+				&frame_done_completion,
+				DISPC_IRQ_FRAMEDONE);
+
+		if (r)
+			DSSERR("failed to register FRAMEDONE isr\n");
+	}
+
+	_enable_lcd_out(enable);
+
+	if (!enable && is_on) {
+		if (!wait_for_completion_timeout(&frame_done_completion,
+					msecs_to_jiffies(100)))
+			DSSERR("timeout waiting for FRAME DONE\n");
+
+		r = omap_dispc_unregister_isr(dispc_disable_isr,
+				&frame_done_completion,
+				DISPC_IRQ_FRAMEDONE);
+
+		if (r)
+			DSSERR("failed to unregister FRAMEDONE isr\n");
+	}
+
+	enable_clocks(0);
+}
+
+static void _enable_digit_out(bool enable)
+{
+	REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 1, 1);
+}
+
+void dispc_enable_digit_out(bool enable)
+{
+	struct completion frame_done_completion;
+	int r;
+
+	enable_clocks(1);
+
+	if (REG_GET(DISPC_CONTROL, 1, 1) == enable) {
+		enable_clocks(0);
+		return;
+	}
+
+	if (enable) {
+		unsigned long flags;
+		/* When we enable digit output, we'll get an extra digit
+		 * sync lost interrupt, that we need to ignore */
+		spin_lock_irqsave(&dispc.irq_lock, flags);
+		dispc.irq_error_mask &= ~DISPC_IRQ_SYNC_LOST_DIGIT;
+		_omap_dispc_set_irqs();
+		spin_unlock_irqrestore(&dispc.irq_lock, flags);
+	}
+
+	/* 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 */
+	init_completion(&frame_done_completion);
+
+	r = omap_dispc_register_isr(dispc_disable_isr, &frame_done_completion,
+			DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD);
+	if (r)
+		DSSERR("failed to register EVSYNC isr\n");
+
+	_enable_digit_out(enable);
+
+	/* XXX I understand from TRM that we should only wait for the
+	 * current field to complete. But it seems we have to wait
+	 * for both fields */
+	if (!wait_for_completion_timeout(&frame_done_completion,
+				msecs_to_jiffies(100)))
+		DSSERR("timeout waiting for EVSYNC\n");
+
+	if (!wait_for_completion_timeout(&frame_done_completion,
+				msecs_to_jiffies(100)))
+		DSSERR("timeout waiting for EVSYNC\n");
+
+	r = omap_dispc_unregister_isr(dispc_disable_isr,
+			&frame_done_completion,
+			DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD);
+	if (r)
+		DSSERR("failed to unregister EVSYNC isr\n");
+
+	if (enable) {
+		unsigned long flags;
+		spin_lock_irqsave(&dispc.irq_lock, flags);
+		dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR;
+		dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT);
+		_omap_dispc_set_irqs();
+		spin_unlock_irqrestore(&dispc.irq_lock, flags);
+	}
+
+	enable_clocks(0);
+}
+
+void dispc_lcd_enable_signal_polarity(bool act_high)
+{
+	enable_clocks(1);
+	REG_FLD_MOD(DISPC_CONTROL, act_high ? 1 : 0, 29, 29);
+	enable_clocks(0);
+}
+
+void dispc_lcd_enable_signal(bool enable)
+{
+	enable_clocks(1);
+	REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 28, 28);
+	enable_clocks(0);
+}
+
+void dispc_pck_free_enable(bool enable)
+{
+	enable_clocks(1);
+	REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27);
+	enable_clocks(0);
+}
+
+void dispc_enable_fifohandcheck(bool enable)
+{
+	enable_clocks(1);
+	REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 16, 16);
+	enable_clocks(0);
+}
+
+
+void dispc_set_lcd_display_type(enum omap_lcd_display_type type)
+{
+	int mode;
+
+	switch (type) {
+	case OMAP_DSS_LCD_DISPLAY_STN:
+		mode = 0;
+		break;
+
+	case OMAP_DSS_LCD_DISPLAY_TFT:
+		mode = 1;
+		break;
+
+	default:
+		BUG();
+		return;
+	}
+
+	enable_clocks(1);
+	REG_FLD_MOD(DISPC_CONTROL, mode, 3, 3);
+	enable_clocks(0);
+}
+
+void dispc_set_loadmode(enum omap_dss_load_mode mode)
+{
+	enable_clocks(1);
+	REG_FLD_MOD(DISPC_CONFIG, mode, 2, 1);
+	enable_clocks(0);
+}
+
+
+void dispc_set_default_color(enum omap_channel channel, u32 color)
+{
+	const struct dispc_reg def_reg[] = { DISPC_DEFAULT_COLOR0,
+				DISPC_DEFAULT_COLOR1 };
+
+	enable_clocks(1);
+	dispc_write_reg(def_reg[channel], color);
+	enable_clocks(0);
+}
+
+u32 dispc_get_default_color(enum omap_channel channel)
+{
+	const struct dispc_reg def_reg[] = { DISPC_DEFAULT_COLOR0,
+				DISPC_DEFAULT_COLOR1 };
+	u32 l;
+
+	BUG_ON(channel != OMAP_DSS_CHANNEL_DIGIT &&
+	       channel != OMAP_DSS_CHANNEL_LCD);
+
+	enable_clocks(1);
+	l = dispc_read_reg(def_reg[channel]);
+	enable_clocks(0);
+
+	return l;
+}
+
+void dispc_set_trans_key(enum omap_channel ch,
+		enum omap_dss_trans_key_type type,
+		u32 trans_key)
+{
+	const struct dispc_reg tr_reg[] = {
+		DISPC_TRANS_COLOR0, DISPC_TRANS_COLOR1 };
+
+	enable_clocks(1);
+	if (ch == OMAP_DSS_CHANNEL_LCD)
+		REG_FLD_MOD(DISPC_CONFIG, type, 11, 11);
+	else /* OMAP_DSS_CHANNEL_DIGIT */
+		REG_FLD_MOD(DISPC_CONFIG, type, 13, 13);
+
+	dispc_write_reg(tr_reg[ch], trans_key);
+	enable_clocks(0);
+}
+
+void dispc_get_trans_key(enum omap_channel ch,
+		enum omap_dss_trans_key_type *type,
+		u32 *trans_key)
+{
+	const struct dispc_reg tr_reg[] = {
+		DISPC_TRANS_COLOR0, DISPC_TRANS_COLOR1 };
+
+	enable_clocks(1);
+	if (type) {
+		if (ch == OMAP_DSS_CHANNEL_LCD)
+			*type = REG_GET(DISPC_CONFIG, 11, 11);
+		else if (ch == OMAP_DSS_CHANNEL_DIGIT)
+			*type = REG_GET(DISPC_CONFIG, 13, 13);
+		else
+			BUG();
+	}
+
+	if (trans_key)
+		*trans_key = dispc_read_reg(tr_reg[ch]);
+	enable_clocks(0);
+}
+
+void dispc_enable_trans_key(enum omap_channel ch, bool enable)
+{
+	enable_clocks(1);
+	if (ch == OMAP_DSS_CHANNEL_LCD)
+		REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10);
+	else /* OMAP_DSS_CHANNEL_DIGIT */
+		REG_FLD_MOD(DISPC_CONFIG, enable, 12, 12);
+	enable_clocks(0);
+}
+void dispc_enable_alpha_blending(enum omap_channel ch, bool enable)
+{
+	if (cpu_is_omap24xx())
+		return;
+
+	enable_clocks(1);
+	if (ch == OMAP_DSS_CHANNEL_LCD)
+		REG_FLD_MOD(DISPC_CONFIG, enable, 18, 18);
+	else /* OMAP_DSS_CHANNEL_DIGIT */
+		REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19);
+	enable_clocks(0);
+}
+bool dispc_alpha_blending_enabled(enum omap_channel ch)
+{
+	bool enabled;
+
+	if (cpu_is_omap24xx())
+		return false;
+
+	enable_clocks(1);
+	if (ch == OMAP_DSS_CHANNEL_LCD)
+		enabled = REG_GET(DISPC_CONFIG, 18, 18);
+	else if (ch == OMAP_DSS_CHANNEL_DIGIT)
+		enabled = REG_GET(DISPC_CONFIG, 18, 18);
+	else
+		BUG();
+	enable_clocks(0);
+
+	return enabled;
+
+}
+
+
+bool dispc_trans_key_enabled(enum omap_channel ch)
+{
+	bool enabled;
+
+	enable_clocks(1);
+	if (ch == OMAP_DSS_CHANNEL_LCD)
+		enabled = REG_GET(DISPC_CONFIG, 10, 10);
+	else if (ch == OMAP_DSS_CHANNEL_DIGIT)
+		enabled = REG_GET(DISPC_CONFIG, 12, 12);
+	else
+		BUG();
+	enable_clocks(0);
+
+	return enabled;
+}
+
+
+void dispc_set_tft_data_lines(u8 data_lines)
+{
+	int code;
+
+	switch (data_lines) {
+	case 12:
+		code = 0;
+		break;
+	case 16:
+		code = 1;
+		break;
+	case 18:
+		code = 2;
+		break;
+	case 24:
+		code = 3;
+		break;
+	default:
+		BUG();
+		return;
+	}
+
+	enable_clocks(1);
+	REG_FLD_MOD(DISPC_CONTROL, code, 9, 8);
+	enable_clocks(0);
+}
+
+void dispc_set_parallel_interface_mode(enum omap_parallel_interface_mode mode)
+{
+	u32 l;
+	int stallmode;
+	int gpout0 = 1;
+	int gpout1;
+
+	switch (mode) {
+	case OMAP_DSS_PARALLELMODE_BYPASS:
+		stallmode = 0;
+		gpout1 = 1;
+		break;
+
+	case OMAP_DSS_PARALLELMODE_RFBI:
+		stallmode = 1;
+		gpout1 = 0;
+		break;
+
+	case OMAP_DSS_PARALLELMODE_DSI:
+		stallmode = 1;
+		gpout1 = 1;
+		break;
+
+	default:
+		BUG();
+		return;
+	}
+
+	enable_clocks(1);
+
+	l = dispc_read_reg(DISPC_CONTROL);
+
+	l = FLD_MOD(l, stallmode, 11, 11);
+	l = FLD_MOD(l, gpout0, 15, 15);
+	l = FLD_MOD(l, gpout1, 16, 16);
+
+	dispc_write_reg(DISPC_CONTROL, l);
+
+	enable_clocks(0);
+}
+
+static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
+		int vsw, int vfp, int vbp)
+{
+	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
+		if (hsw < 1 || hsw > 64 ||
+				hfp < 1 || hfp > 256 ||
+				hbp < 1 || hbp > 256 ||
+				vsw < 1 || vsw > 64 ||
+				vfp < 0 || vfp > 255 ||
+				vbp < 0 || vbp > 255)
+			return false;
+	} else {
+		if (hsw < 1 || hsw > 256 ||
+				hfp < 1 || hfp > 4096 ||
+				hbp < 1 || hbp > 4096 ||
+				vsw < 1 || vsw > 256 ||
+				vfp < 0 || vfp > 4095 ||
+				vbp < 0 || vbp > 4095)
+			return false;
+	}
+
+	return true;
+}
+
+bool dispc_lcd_timings_ok(struct omap_video_timings *timings)
+{
+	return _dispc_lcd_timings_ok(timings->hsw, timings->hfp,
+			timings->hbp, timings->vsw,
+			timings->vfp, timings->vbp);
+}
+
+static void _dispc_set_lcd_timings(int hsw, int hfp, int hbp,
+				   int vsw, int vfp, int vbp)
+{
+	u32 timing_h, timing_v;
+
+	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
+		timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
+			FLD_VAL(hbp-1, 27, 20);
+
+		timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
+			FLD_VAL(vbp, 27, 20);
+	} else {
+		timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) |
+			FLD_VAL(hbp-1, 31, 20);
+
+		timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) |
+			FLD_VAL(vbp, 31, 20);
+	}
+
+	enable_clocks(1);
+	dispc_write_reg(DISPC_TIMING_H, timing_h);
+	dispc_write_reg(DISPC_TIMING_V, timing_v);
+	enable_clocks(0);
+}
+
+/* change name to mode? */
+void dispc_set_lcd_timings(struct omap_video_timings *timings)
+{
+	unsigned xtot, ytot;
+	unsigned long ht, vt;
+
+	if (!_dispc_lcd_timings_ok(timings->hsw, timings->hfp,
+				timings->hbp, timings->vsw,
+				timings->vfp, timings->vbp))
+		BUG();
+
+	_dispc_set_lcd_timings(timings->hsw, timings->hfp, timings->hbp,
+			timings->vsw, timings->vfp, timings->vbp);
+
+	dispc_set_lcd_size(timings->x_res, timings->y_res);
+
+	xtot = timings->x_res + timings->hfp + timings->hsw + timings->hbp;
+	ytot = timings->y_res + timings->vfp + timings->vsw + timings->vbp;
+
+	ht = (timings->pixel_clock * 1000) / xtot;
+	vt = (timings->pixel_clock * 1000) / xtot / ytot;
+
+	DSSDBG("xres %u yres %u\n", timings->x_res, timings->y_res);
+	DSSDBG("pck %u\n", timings->pixel_clock);
+	DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n",
+			timings->hsw, timings->hfp, timings->hbp,
+			timings->vsw, timings->vfp, timings->vbp);
+
+	DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt);
+}
+
+static void dispc_set_lcd_divisor(u16 lck_div, u16 pck_div)
+{
+	BUG_ON(lck_div < 1);
+	BUG_ON(pck_div < 2);
+
+	enable_clocks(1);
+	dispc_write_reg(DISPC_DIVISOR,
+			FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0));
+	enable_clocks(0);
+}
+
+static void dispc_get_lcd_divisor(int *lck_div, int *pck_div)
+{
+	u32 l;
+	l = dispc_read_reg(DISPC_DIVISOR);
+	*lck_div = FLD_GET(l, 23, 16);
+	*pck_div = FLD_GET(l, 7, 0);
+}
+
+unsigned long dispc_fclk_rate(void)
+{
+	unsigned long r = 0;
+
+	if (dss_get_dispc_clk_source() == 0)
+		r = dss_clk_get_rate(DSS_CLK_FCK1);
+	else
+#ifdef CONFIG_OMAP2_DSS_DSI
+		r = dsi_get_dsi1_pll_rate();
+#else
+	BUG();
+#endif
+	return r;
+}
+
+unsigned long dispc_lclk_rate(void)
+{
+	int lcd;
+	unsigned long r;
+	u32 l;
+
+	l = dispc_read_reg(DISPC_DIVISOR);
+
+	lcd = FLD_GET(l, 23, 16);
+
+	r = dispc_fclk_rate();
+
+	return r / lcd;
+}
+
+unsigned long dispc_pclk_rate(void)
+{
+	int lcd, pcd;
+	unsigned long r;
+	u32 l;
+
+	l = dispc_read_reg(DISPC_DIVISOR);
+
+	lcd = FLD_GET(l, 23, 16);
+	pcd = FLD_GET(l, 7, 0);
+
+	r = dispc_fclk_rate();
+
+	return r / lcd / pcd;
+}
+
+void dispc_dump_clocks(struct seq_file *s)
+{
+	int lcd, pcd;
+
+	enable_clocks(1);
+
+	dispc_get_lcd_divisor(&lcd, &pcd);
+
+	seq_printf(s, "- DISPC -\n");
+
+	seq_printf(s, "dispc fclk source = %s\n",
+			dss_get_dispc_clk_source() == 0 ?
+			"dss1_alwon_fclk" : "dsi1_pll_fclk");
+
+	seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate());
+	seq_printf(s, "lck\t\t%-16lulck div\t%u\n", dispc_lclk_rate(), lcd);
+	seq_printf(s, "pck\t\t%-16lupck div\t%u\n", dispc_pclk_rate(), pcd);
+
+	enable_clocks(0);
+}
+
+void dispc_dump_regs(struct seq_file *s)
+{
+#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r))
+
+	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+
+	DUMPREG(DISPC_REVISION);
+	DUMPREG(DISPC_SYSCONFIG);
+	DUMPREG(DISPC_SYSSTATUS);
+	DUMPREG(DISPC_IRQSTATUS);
+	DUMPREG(DISPC_IRQENABLE);
+	DUMPREG(DISPC_CONTROL);
+	DUMPREG(DISPC_CONFIG);
+	DUMPREG(DISPC_CAPABLE);
+	DUMPREG(DISPC_DEFAULT_COLOR0);
+	DUMPREG(DISPC_DEFAULT_COLOR1);
+	DUMPREG(DISPC_TRANS_COLOR0);
+	DUMPREG(DISPC_TRANS_COLOR1);
+	DUMPREG(DISPC_LINE_STATUS);
+	DUMPREG(DISPC_LINE_NUMBER);
+	DUMPREG(DISPC_TIMING_H);
+	DUMPREG(DISPC_TIMING_V);
+	DUMPREG(DISPC_POL_FREQ);
+	DUMPREG(DISPC_DIVISOR);
+	DUMPREG(DISPC_GLOBAL_ALPHA);
+	DUMPREG(DISPC_SIZE_DIG);
+	DUMPREG(DISPC_SIZE_LCD);
+
+	DUMPREG(DISPC_GFX_BA0);
+	DUMPREG(DISPC_GFX_BA1);
+	DUMPREG(DISPC_GFX_POSITION);
+	DUMPREG(DISPC_GFX_SIZE);
+	DUMPREG(DISPC_GFX_ATTRIBUTES);
+	DUMPREG(DISPC_GFX_FIFO_THRESHOLD);
+	DUMPREG(DISPC_GFX_FIFO_SIZE_STATUS);
+	DUMPREG(DISPC_GFX_ROW_INC);
+	DUMPREG(DISPC_GFX_PIXEL_INC);
+	DUMPREG(DISPC_GFX_WINDOW_SKIP);
+	DUMPREG(DISPC_GFX_TABLE_BA);
+
+	DUMPREG(DISPC_DATA_CYCLE1);
+	DUMPREG(DISPC_DATA_CYCLE2);
+	DUMPREG(DISPC_DATA_CYCLE3);
+
+	DUMPREG(DISPC_CPR_COEF_R);
+	DUMPREG(DISPC_CPR_COEF_G);
+	DUMPREG(DISPC_CPR_COEF_B);
+
+	DUMPREG(DISPC_GFX_PRELOAD);
+
+	DUMPREG(DISPC_VID_BA0(0));
+	DUMPREG(DISPC_VID_BA1(0));
+	DUMPREG(DISPC_VID_POSITION(0));
+	DUMPREG(DISPC_VID_SIZE(0));
+	DUMPREG(DISPC_VID_ATTRIBUTES(0));
+	DUMPREG(DISPC_VID_FIFO_THRESHOLD(0));
+	DUMPREG(DISPC_VID_FIFO_SIZE_STATUS(0));
+	DUMPREG(DISPC_VID_ROW_INC(0));
+	DUMPREG(DISPC_VID_PIXEL_INC(0));
+	DUMPREG(DISPC_VID_FIR(0));
+	DUMPREG(DISPC_VID_PICTURE_SIZE(0));
+	DUMPREG(DISPC_VID_ACCU0(0));
+	DUMPREG(DISPC_VID_ACCU1(0));
+
+	DUMPREG(DISPC_VID_BA0(1));
+	DUMPREG(DISPC_VID_BA1(1));
+	DUMPREG(DISPC_VID_POSITION(1));
+	DUMPREG(DISPC_VID_SIZE(1));
+	DUMPREG(DISPC_VID_ATTRIBUTES(1));
+	DUMPREG(DISPC_VID_FIFO_THRESHOLD(1));
+	DUMPREG(DISPC_VID_FIFO_SIZE_STATUS(1));
+	DUMPREG(DISPC_VID_ROW_INC(1));
+	DUMPREG(DISPC_VID_PIXEL_INC(1));
+	DUMPREG(DISPC_VID_FIR(1));
+	DUMPREG(DISPC_VID_PICTURE_SIZE(1));
+	DUMPREG(DISPC_VID_ACCU0(1));
+	DUMPREG(DISPC_VID_ACCU1(1));
+
+	DUMPREG(DISPC_VID_FIR_COEF_H(0, 0));
+	DUMPREG(DISPC_VID_FIR_COEF_H(0, 1));
+	DUMPREG(DISPC_VID_FIR_COEF_H(0, 2));
+	DUMPREG(DISPC_VID_FIR_COEF_H(0, 3));
+	DUMPREG(DISPC_VID_FIR_COEF_H(0, 4));
+	DUMPREG(DISPC_VID_FIR_COEF_H(0, 5));
+	DUMPREG(DISPC_VID_FIR_COEF_H(0, 6));
+	DUMPREG(DISPC_VID_FIR_COEF_H(0, 7));
+	DUMPREG(DISPC_VID_FIR_COEF_HV(0, 0));
+	DUMPREG(DISPC_VID_FIR_COEF_HV(0, 1));
+	DUMPREG(DISPC_VID_FIR_COEF_HV(0, 2));
+	DUMPREG(DISPC_VID_FIR_COEF_HV(0, 3));
+	DUMPREG(DISPC_VID_FIR_COEF_HV(0, 4));
+	DUMPREG(DISPC_VID_FIR_COEF_HV(0, 5));
+	DUMPREG(DISPC_VID_FIR_COEF_HV(0, 6));
+	DUMPREG(DISPC_VID_FIR_COEF_HV(0, 7));
+	DUMPREG(DISPC_VID_CONV_COEF(0, 0));
+	DUMPREG(DISPC_VID_CONV_COEF(0, 1));
+	DUMPREG(DISPC_VID_CONV_COEF(0, 2));
+	DUMPREG(DISPC_VID_CONV_COEF(0, 3));
+	DUMPREG(DISPC_VID_CONV_COEF(0, 4));
+	DUMPREG(DISPC_VID_FIR_COEF_V(0, 0));
+	DUMPREG(DISPC_VID_FIR_COEF_V(0, 1));
+	DUMPREG(DISPC_VID_FIR_COEF_V(0, 2));
+	DUMPREG(DISPC_VID_FIR_COEF_V(0, 3));
+	DUMPREG(DISPC_VID_FIR_COEF_V(0, 4));
+	DUMPREG(DISPC_VID_FIR_COEF_V(0, 5));
+	DUMPREG(DISPC_VID_FIR_COEF_V(0, 6));
+	DUMPREG(DISPC_VID_FIR_COEF_V(0, 7));
+
+	DUMPREG(DISPC_VID_FIR_COEF_H(1, 0));
+	DUMPREG(DISPC_VID_FIR_COEF_H(1, 1));
+	DUMPREG(DISPC_VID_FIR_COEF_H(1, 2));
+	DUMPREG(DISPC_VID_FIR_COEF_H(1, 3));
+	DUMPREG(DISPC_VID_FIR_COEF_H(1, 4));
+	DUMPREG(DISPC_VID_FIR_COEF_H(1, 5));
+	DUMPREG(DISPC_VID_FIR_COEF_H(1, 6));
+	DUMPREG(DISPC_VID_FIR_COEF_H(1, 7));
+	DUMPREG(DISPC_VID_FIR_COEF_HV(1, 0));
+	DUMPREG(DISPC_VID_FIR_COEF_HV(1, 1));
+	DUMPREG(DISPC_VID_FIR_COEF_HV(1, 2));
+	DUMPREG(DISPC_VID_FIR_COEF_HV(1, 3));
+	DUMPREG(DISPC_VID_FIR_COEF_HV(1, 4));
+	DUMPREG(DISPC_VID_FIR_COEF_HV(1, 5));
+	DUMPREG(DISPC_VID_FIR_COEF_HV(1, 6));
+	DUMPREG(DISPC_VID_FIR_COEF_HV(1, 7));
+	DUMPREG(DISPC_VID_CONV_COEF(1, 0));
+	DUMPREG(DISPC_VID_CONV_COEF(1, 1));
+	DUMPREG(DISPC_VID_CONV_COEF(1, 2));
+	DUMPREG(DISPC_VID_CONV_COEF(1, 3));
+	DUMPREG(DISPC_VID_CONV_COEF(1, 4));
+	DUMPREG(DISPC_VID_FIR_COEF_V(1, 0));
+	DUMPREG(DISPC_VID_FIR_COEF_V(1, 1));
+	DUMPREG(DISPC_VID_FIR_COEF_V(1, 2));
+	DUMPREG(DISPC_VID_FIR_COEF_V(1, 3));
+	DUMPREG(DISPC_VID_FIR_COEF_V(1, 4));
+	DUMPREG(DISPC_VID_FIR_COEF_V(1, 5));
+	DUMPREG(DISPC_VID_FIR_COEF_V(1, 6));
+	DUMPREG(DISPC_VID_FIR_COEF_V(1, 7));
+
+	DUMPREG(DISPC_VID_PRELOAD(0));
+	DUMPREG(DISPC_VID_PRELOAD(1));
+
+	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+#undef DUMPREG
+}
+
+static void _dispc_set_pol_freq(bool onoff, bool rf, bool ieo, bool ipc,
+				bool ihs, bool ivs, u8 acbi, u8 acb)
+{
+	u32 l = 0;
+
+	DSSDBG("onoff %d rf %d ieo %d ipc %d ihs %d ivs %d acbi %d acb %d\n",
+			onoff, rf, ieo, ipc, ihs, ivs, acbi, acb);
+
+	l |= FLD_VAL(onoff, 17, 17);
+	l |= FLD_VAL(rf, 16, 16);
+	l |= FLD_VAL(ieo, 15, 15);
+	l |= FLD_VAL(ipc, 14, 14);
+	l |= FLD_VAL(ihs, 13, 13);
+	l |= FLD_VAL(ivs, 12, 12);
+	l |= FLD_VAL(acbi, 11, 8);
+	l |= FLD_VAL(acb, 7, 0);
+
+	enable_clocks(1);
+	dispc_write_reg(DISPC_POL_FREQ, l);
+	enable_clocks(0);
+}
+
+void dispc_set_pol_freq(enum omap_panel_config config, u8 acbi, u8 acb)
+{
+	_dispc_set_pol_freq((config & OMAP_DSS_LCD_ONOFF) != 0,
+			(config & OMAP_DSS_LCD_RF) != 0,
+			(config & OMAP_DSS_LCD_IEO) != 0,
+			(config & OMAP_DSS_LCD_IPC) != 0,
+			(config & OMAP_DSS_LCD_IHS) != 0,
+			(config & OMAP_DSS_LCD_IVS) != 0,
+			acbi, acb);
+}
+
+/* with fck as input clock rate, find dispc dividers that produce req_pck */
+void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck,
+		struct dispc_clock_info *cinfo)
+{
+	u16 pcd_min = is_tft ? 2 : 3;
+	unsigned long best_pck;
+	u16 best_ld, cur_ld;
+	u16 best_pd, cur_pd;
+
+	best_pck = 0;
+	best_ld = 0;
+	best_pd = 0;
+
+	for (cur_ld = 1; cur_ld <= 255; ++cur_ld) {
+		unsigned long lck = fck / cur_ld;
+
+		for (cur_pd = pcd_min; cur_pd <= 255; ++cur_pd) {
+			unsigned long pck = lck / cur_pd;
+			long old_delta = abs(best_pck - req_pck);
+			long new_delta = abs(pck - req_pck);
+
+			if (best_pck == 0 || new_delta < old_delta) {
+				best_pck = pck;
+				best_ld = cur_ld;
+				best_pd = cur_pd;
+
+				if (pck == req_pck)
+					goto found;
+			}
+
+			if (pck < req_pck)
+				break;
+		}
+
+		if (lck / pcd_min < req_pck)
+			break;
+	}
+
+found:
+	cinfo->lck_div = best_ld;
+	cinfo->pck_div = best_pd;
+	cinfo->lck = fck / cinfo->lck_div;
+	cinfo->pck = cinfo->lck / cinfo->pck_div;
+}
+
+/* calculate clock rates using dividers in cinfo */
+int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
+		struct dispc_clock_info *cinfo)
+{
+	if (cinfo->lck_div > 255 || cinfo->lck_div == 0)
+		return -EINVAL;
+	if (cinfo->pck_div < 2 || cinfo->pck_div > 255)
+		return -EINVAL;
+
+	cinfo->lck = dispc_fclk_rate / cinfo->lck_div;
+	cinfo->pck = cinfo->lck / cinfo->pck_div;
+
+	return 0;
+}
+
+int dispc_set_clock_div(struct dispc_clock_info *cinfo)
+{
+	DSSDBG("lck = %lu (%u)\n", cinfo->lck, cinfo->lck_div);
+	DSSDBG("pck = %lu (%u)\n", cinfo->pck, cinfo->pck_div);
+
+	dispc_set_lcd_divisor(cinfo->lck_div, cinfo->pck_div);
+
+	return 0;
+}
+
+int dispc_get_clock_div(struct dispc_clock_info *cinfo)
+{
+	unsigned long fck;
+
+	fck = dispc_fclk_rate();
+
+	cinfo->lck_div = REG_GET(DISPC_DIVISOR, 23, 16);
+	cinfo->pck_div = REG_GET(DISPC_DIVISOR, 7, 0);
+
+	cinfo->lck = fck / cinfo->lck_div;
+	cinfo->pck = cinfo->lck / cinfo->pck_div;
+
+	return 0;
+}
+
+/* dispc.irq_lock has to be locked by the caller */
+static void _omap_dispc_set_irqs(void)
+{
+	u32 mask;
+	u32 old_mask;
+	int i;
+	struct omap_dispc_isr_data *isr_data;
+
+	mask = dispc.irq_error_mask;
+
+	for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
+		isr_data = &dispc.registered_isr[i];
+
+		if (isr_data->isr == NULL)
+			continue;
+
+		mask |= isr_data->mask;
+	}
+
+	enable_clocks(1);
+
+	old_mask = dispc_read_reg(DISPC_IRQENABLE);
+	/* clear the irqstatus for newly enabled irqs */
+	dispc_write_reg(DISPC_IRQSTATUS, (mask ^ old_mask) & mask);
+
+	dispc_write_reg(DISPC_IRQENABLE, mask);
+
+	enable_clocks(0);
+}
+
+int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
+{
+	int i;
+	int ret;
+	unsigned long flags;
+	struct omap_dispc_isr_data *isr_data;
+
+	if (isr == NULL)
+		return -EINVAL;
+
+	spin_lock_irqsave(&dispc.irq_lock, flags);
+
+	/* check for duplicate entry */
+	for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
+		isr_data = &dispc.registered_isr[i];
+		if (isr_data->isr == isr && isr_data->arg == arg &&
+				isr_data->mask == mask) {
+			ret = -EINVAL;
+			goto err;
+		}
+	}
+
+	isr_data = NULL;
+	ret = -EBUSY;
+
+	for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
+		isr_data = &dispc.registered_isr[i];
+
+		if (isr_data->isr != NULL)
+			continue;
+
+		isr_data->isr = isr;
+		isr_data->arg = arg;
+		isr_data->mask = mask;
+		ret = 0;
+
+		break;
+	}
+
+	_omap_dispc_set_irqs();
+
+	spin_unlock_irqrestore(&dispc.irq_lock, flags);
+
+	return 0;
+err:
+	spin_unlock_irqrestore(&dispc.irq_lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(omap_dispc_register_isr);
+
+int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
+{
+	int i;
+	unsigned long flags;
+	int ret = -EINVAL;
+	struct omap_dispc_isr_data *isr_data;
+
+	spin_lock_irqsave(&dispc.irq_lock, flags);
+
+	for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
+		isr_data = &dispc.registered_isr[i];
+		if (isr_data->isr != isr || isr_data->arg != arg ||
+				isr_data->mask != mask)
+			continue;
+
+		/* found the correct isr */
+
+		isr_data->isr = NULL;
+		isr_data->arg = NULL;
+		isr_data->mask = 0;
+
+		ret = 0;
+		break;
+	}
+
+	if (ret == 0)
+		_omap_dispc_set_irqs();
+
+	spin_unlock_irqrestore(&dispc.irq_lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(omap_dispc_unregister_isr);
+
+#ifdef DEBUG
+static void print_irq_status(u32 status)
+{
+	if ((status & dispc.irq_error_mask) == 0)
+		return;
+
+	printk(KERN_DEBUG "DISPC IRQ: 0x%x: ", status);
+
+#define PIS(x) \
+	if (status & DISPC_IRQ_##x) \
+		printk(#x " ");
+	PIS(GFX_FIFO_UNDERFLOW);
+	PIS(OCP_ERR);
+	PIS(VID1_FIFO_UNDERFLOW);
+	PIS(VID2_FIFO_UNDERFLOW);
+	PIS(SYNC_LOST);
+	PIS(SYNC_LOST_DIGIT);
+#undef PIS
+
+	printk("\n");
+}
+#endif
+
+/* Called from dss.c. Note that we don't touch clocks here,
+ * but we presume they are on because we got an IRQ. However,
+ * an irq handler may turn the clocks off, so we may not have
+ * clock later in the function. */
+void dispc_irq_handler(void)
+{
+	int i;
+	u32 irqstatus;
+	u32 handledirqs = 0;
+	u32 unhandled_errors;
+	struct omap_dispc_isr_data *isr_data;
+	struct omap_dispc_isr_data registered_isr[DISPC_MAX_NR_ISRS];
+
+	spin_lock(&dispc.irq_lock);
+
+	irqstatus = dispc_read_reg(DISPC_IRQSTATUS);
+
+#ifdef DEBUG
+	if (dss_debug)
+		print_irq_status(irqstatus);
+#endif
+	/* Ack the interrupt. Do it here before clocks are possibly turned
+	 * off */
+	dispc_write_reg(DISPC_IRQSTATUS, irqstatus);
+	/* flush posted write */
+	dispc_read_reg(DISPC_IRQSTATUS);
+
+	/* make a copy and unlock, so that isrs can unregister
+	 * themselves */
+	memcpy(registered_isr, dispc.registered_isr,
+			sizeof(registered_isr));
+
+	spin_unlock(&dispc.irq_lock);
+
+	for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
+		isr_data = &registered_isr[i];
+
+		if (!isr_data->isr)
+			continue;
+
+		if (isr_data->mask & irqstatus) {
+			isr_data->isr(isr_data->arg, irqstatus);
+			handledirqs |= isr_data->mask;
+		}
+	}
+
+	spin_lock(&dispc.irq_lock);
+
+	unhandled_errors = irqstatus & ~handledirqs & dispc.irq_error_mask;
+
+	if (unhandled_errors) {
+		dispc.error_irqs |= unhandled_errors;
+
+		dispc.irq_error_mask &= ~unhandled_errors;
+		_omap_dispc_set_irqs();
+
+		schedule_work(&dispc.error_work);
+	}
+
+	spin_unlock(&dispc.irq_lock);
+}
+
+static void dispc_error_worker(struct work_struct *work)
+{
+	int i;
+	u32 errors;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dispc.irq_lock, flags);
+	errors = dispc.error_irqs;
+	dispc.error_irqs = 0;
+	spin_unlock_irqrestore(&dispc.irq_lock, flags);
+
+	if (errors & DISPC_IRQ_GFX_FIFO_UNDERFLOW) {
+		DSSERR("GFX_FIFO_UNDERFLOW, disabling GFX\n");
+		for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
+			struct omap_overlay *ovl;
+			ovl = omap_dss_get_overlay(i);
+
+			if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
+				continue;
+
+			if (ovl->id == 0) {
+				dispc_enable_plane(ovl->id, 0);
+				dispc_go(ovl->manager->id);
+				mdelay(50);
+				break;
+			}
+		}
+	}
+
+	if (errors & DISPC_IRQ_VID1_FIFO_UNDERFLOW) {
+		DSSERR("VID1_FIFO_UNDERFLOW, disabling VID1\n");
+		for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
+			struct omap_overlay *ovl;
+			ovl = omap_dss_get_overlay(i);
+
+			if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
+				continue;
+
+			if (ovl->id == 1) {
+				dispc_enable_plane(ovl->id, 0);
+				dispc_go(ovl->manager->id);
+				mdelay(50);
+				break;
+			}
+		}
+	}
+
+	if (errors & DISPC_IRQ_VID2_FIFO_UNDERFLOW) {
+		DSSERR("VID2_FIFO_UNDERFLOW, disabling VID2\n");
+		for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
+			struct omap_overlay *ovl;
+			ovl = omap_dss_get_overlay(i);
+
+			if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
+				continue;
+
+			if (ovl->id == 2) {
+				dispc_enable_plane(ovl->id, 0);
+				dispc_go(ovl->manager->id);
+				mdelay(50);
+				break;
+			}
+		}
+	}
+
+	if (errors & DISPC_IRQ_SYNC_LOST) {
+		struct omap_overlay_manager *manager = NULL;
+		bool enable = false;
+
+		DSSERR("SYNC_LOST, disabling LCD\n");
+
+		for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
+			struct omap_overlay_manager *mgr;
+			mgr = omap_dss_get_overlay_manager(i);
+
+			if (mgr->id == OMAP_DSS_CHANNEL_LCD) {
+				manager = mgr;
+				enable = mgr->device->state ==
+						OMAP_DSS_DISPLAY_ACTIVE;
+				mgr->device->disable(mgr->device);
+				break;
+			}
+		}
+
+		if (manager) {
+			for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
+				struct omap_overlay *ovl;
+				ovl = omap_dss_get_overlay(i);
+
+				if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
+					continue;
+
+				if (ovl->id != 0 && ovl->manager == manager)
+					dispc_enable_plane(ovl->id, 0);
+			}
+
+			dispc_go(manager->id);
+			mdelay(50);
+			if (enable)
+				manager->device->enable(manager->device);
+		}
+	}
+
+	if (errors & DISPC_IRQ_SYNC_LOST_DIGIT) {
+		struct omap_overlay_manager *manager = NULL;
+		bool enable = false;
+
+		DSSERR("SYNC_LOST_DIGIT, disabling TV\n");
+
+		for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
+			struct omap_overlay_manager *mgr;
+			mgr = omap_dss_get_overlay_manager(i);
+
+			if (mgr->id == OMAP_DSS_CHANNEL_DIGIT) {
+				manager = mgr;
+				enable = mgr->device->state ==
+						OMAP_DSS_DISPLAY_ACTIVE;
+				mgr->device->disable(mgr->device);
+				break;
+			}
+		}
+
+		if (manager) {
+			for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
+				struct omap_overlay *ovl;
+				ovl = omap_dss_get_overlay(i);
+
+				if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
+					continue;
+
+				if (ovl->id != 0 && ovl->manager == manager)
+					dispc_enable_plane(ovl->id, 0);
+			}
+
+			dispc_go(manager->id);
+			mdelay(50);
+			if (enable)
+				manager->device->enable(manager->device);
+		}
+	}
+
+	if (errors & DISPC_IRQ_OCP_ERR) {
+		DSSERR("OCP_ERR\n");
+		for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
+			struct omap_overlay_manager *mgr;
+			mgr = omap_dss_get_overlay_manager(i);
+
+			if (mgr->caps & OMAP_DSS_OVL_CAP_DISPC)
+				mgr->device->disable(mgr->device);
+		}
+	}
+
+	spin_lock_irqsave(&dispc.irq_lock, flags);
+	dispc.irq_error_mask |= errors;
+	_omap_dispc_set_irqs();
+	spin_unlock_irqrestore(&dispc.irq_lock, flags);
+}
+
+int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout)
+{
+	void dispc_irq_wait_handler(void *data, u32 mask)
+	{
+		complete((struct completion *)data);
+	}
+
+	int r;
+	DECLARE_COMPLETION_ONSTACK(completion);
+
+	r = omap_dispc_register_isr(dispc_irq_wait_handler, &completion,
+			irqmask);
+
+	if (r)
+		return r;
+
+	timeout = wait_for_completion_timeout(&completion, timeout);
+
+	omap_dispc_unregister_isr(dispc_irq_wait_handler, &completion, irqmask);
+
+	if (timeout == 0)
+		return -ETIMEDOUT;
+
+	if (timeout == -ERESTARTSYS)
+		return -ERESTARTSYS;
+
+	return 0;
+}
+
+int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
+		unsigned long timeout)
+{
+	void dispc_irq_wait_handler(void *data, u32 mask)
+	{
+		complete((struct completion *)data);
+	}
+
+	int r;
+	DECLARE_COMPLETION_ONSTACK(completion);
+
+	r = omap_dispc_register_isr(dispc_irq_wait_handler, &completion,
+			irqmask);
+
+	if (r)
+		return r;
+
+	timeout = wait_for_completion_interruptible_timeout(&completion,
+			timeout);
+
+	omap_dispc_unregister_isr(dispc_irq_wait_handler, &completion, irqmask);
+
+	if (timeout == 0)
+		return -ETIMEDOUT;
+
+	if (timeout == -ERESTARTSYS)
+		return -ERESTARTSYS;
+
+	return 0;
+}
+
+#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC
+void dispc_fake_vsync_irq(void)
+{
+	u32 irqstatus = DISPC_IRQ_VSYNC;
+	int i;
+
+	local_irq_disable();
+
+	for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
+		struct omap_dispc_isr_data *isr_data;
+		isr_data = &dispc.registered_isr[i];
+
+		if (!isr_data->isr)
+			continue;
+
+		if (isr_data->mask & irqstatus)
+			isr_data->isr(isr_data->arg, irqstatus);
+	}
+
+	local_irq_enable();
+}
+#endif
+
+static void _omap_dispc_initialize_irq(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dispc.irq_lock, flags);
+
+	memset(dispc.registered_isr, 0, sizeof(dispc.registered_isr));
+
+	dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR;
+
+	/* there's SYNC_LOST_DIGIT waiting after enabling the DSS,
+	 * so clear it */
+	dispc_write_reg(DISPC_IRQSTATUS, dispc_read_reg(DISPC_IRQSTATUS));
+
+	_omap_dispc_set_irqs();
+
+	spin_unlock_irqrestore(&dispc.irq_lock, flags);
+}
+
+void dispc_enable_sidle(void)
+{
+	REG_FLD_MOD(DISPC_SYSCONFIG, 2, 4, 3);	/* SIDLEMODE: smart idle */
+}
+
+void dispc_disable_sidle(void)
+{
+	REG_FLD_MOD(DISPC_SYSCONFIG, 1, 4, 3);	/* SIDLEMODE: no idle */
+}
+
+static void _omap_dispc_initial_config(void)
+{
+	u32 l;
+
+	l = dispc_read_reg(DISPC_SYSCONFIG);
+	l = FLD_MOD(l, 2, 13, 12);	/* MIDLEMODE: smart standby */
+	l = FLD_MOD(l, 2, 4, 3);	/* SIDLEMODE: smart idle */
+	l = FLD_MOD(l, 1, 2, 2);	/* ENWAKEUP */
+	l = FLD_MOD(l, 1, 0, 0);	/* AUTOIDLE */
+	dispc_write_reg(DISPC_SYSCONFIG, l);
+
+	/* FUNCGATED */
+	REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9);
+
+	/* L3 firewall setting: enable access to OCM RAM */
+	/* XXX this should be somewhere in plat-omap */
+	if (cpu_is_omap24xx())
+		__raw_writel(0x402000b0, OMAP2_L3_IO_ADDRESS(0x680050a0));
+
+	_dispc_setup_color_conv_coef();
+
+	dispc_set_loadmode(OMAP_DSS_LOAD_FRAME_ONLY);
+
+	dispc_read_plane_fifo_sizes();
+}
+
+int dispc_init(void)
+{
+	u32 rev;
+
+	spin_lock_init(&dispc.irq_lock);
+
+	INIT_WORK(&dispc.error_work, dispc_error_worker);
+
+	dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS);
+	if (!dispc.base) {
+		DSSERR("can't ioremap DISPC\n");
+		return -ENOMEM;
+	}
+
+	enable_clocks(1);
+
+	_omap_dispc_initial_config();
+
+	_omap_dispc_initialize_irq();
+
+	dispc_save_context();
+
+	rev = dispc_read_reg(DISPC_REVISION);
+	printk(KERN_INFO "OMAP DISPC rev %d.%d\n",
+	       FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
+
+	enable_clocks(0);
+
+	return 0;
+}
+
+void dispc_exit(void)
+{
+	iounmap(dispc.base);
+}
+
+int dispc_enable_plane(enum omap_plane plane, bool enable)
+{
+	DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
+
+	enable_clocks(1);
+	_dispc_enable_plane(plane, enable);
+	enable_clocks(0);
+
+	return 0;
+}
+
+int dispc_setup_plane(enum omap_plane plane,
+		       u32 paddr, u16 screen_width,
+		       u16 pos_x, u16 pos_y,
+		       u16 width, u16 height,
+		       u16 out_width, u16 out_height,
+		       enum omap_color_mode color_mode,
+		       bool ilace,
+		       enum omap_dss_rotation_type rotation_type,
+		       u8 rotation, bool mirror, u8 global_alpha)
+{
+	int r = 0;
+
+	DSSDBG("dispc_setup_plane %d, pa %x, sw %d, %d,%d, %dx%d -> "
+	       "%dx%d, ilace %d, cmode %x, rot %d, mir %d\n",
+	       plane, paddr, screen_width, pos_x, pos_y,
+	       width, height,
+	       out_width, out_height,
+	       ilace, color_mode,
+	       rotation, mirror);
+
+	enable_clocks(1);
+
+	r = _dispc_setup_plane(plane,
+			   paddr, screen_width,
+			   pos_x, pos_y,
+			   width, height,
+			   out_width, out_height,
+			   color_mode, ilace,
+			   rotation_type,
+			   rotation, mirror,
+			   global_alpha);
+
+	enable_clocks(0);
+
+	return r;
+}
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
new file mode 100644
index 0000000..3b92b84
--- /dev/null
+++ b/drivers/video/omap2/dss/display.c
@@ -0,0 +1,671 @@
+/*
+ * linux/drivers/video/omap2/dss/display.c
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * Some code and ideas taken from drivers/video/omap/ driver
+ * by Imre Deak.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define DSS_SUBSYS_NAME "DISPLAY"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/jiffies.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+
+#include <plat/display.h>
+#include "dss.h"
+
+static LIST_HEAD(display_list);
+
+static ssize_t display_enabled_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	bool enabled = dssdev->state != OMAP_DSS_DISPLAY_DISABLED;
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", enabled);
+}
+
+static ssize_t display_enabled_store(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t size)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	bool enabled, r;
+
+	enabled = simple_strtoul(buf, NULL, 10);
+
+	if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) {
+		if (enabled) {
+			r = dssdev->enable(dssdev);
+			if (r)
+				return r;
+		} else {
+			dssdev->disable(dssdev);
+		}
+	}
+
+	return size;
+}
+
+static ssize_t display_upd_mode_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	enum omap_dss_update_mode mode = OMAP_DSS_UPDATE_AUTO;
+	if (dssdev->get_update_mode)
+		mode = dssdev->get_update_mode(dssdev);
+	return snprintf(buf, PAGE_SIZE, "%d\n", mode);
+}
+
+static ssize_t display_upd_mode_store(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t size)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	int val, r;
+	enum omap_dss_update_mode mode;
+
+	val = simple_strtoul(buf, NULL, 10);
+
+	switch (val) {
+	case OMAP_DSS_UPDATE_DISABLED:
+	case OMAP_DSS_UPDATE_AUTO:
+	case OMAP_DSS_UPDATE_MANUAL:
+		mode = (enum omap_dss_update_mode)val;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	r = dssdev->set_update_mode(dssdev, mode);
+	if (r)
+		return r;
+
+	return size;
+}
+
+static ssize_t display_tear_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	return snprintf(buf, PAGE_SIZE, "%d\n",
+			dssdev->get_te ? dssdev->get_te(dssdev) : 0);
+}
+
+static ssize_t display_tear_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	unsigned long te;
+	int r;
+
+	if (!dssdev->enable_te || !dssdev->get_te)
+		return -ENOENT;
+
+	te = simple_strtoul(buf, NULL, 0);
+
+	r = dssdev->enable_te(dssdev, te);
+	if (r)
+		return r;
+
+	return size;
+}
+
+static ssize_t display_timings_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	struct omap_video_timings t;
+
+	if (!dssdev->get_timings)
+		return -ENOENT;
+
+	dssdev->get_timings(dssdev, &t);
+
+	return snprintf(buf, PAGE_SIZE, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n",
+			t.pixel_clock,
+			t.x_res, t.hfp, t.hbp, t.hsw,
+			t.y_res, t.vfp, t.vbp, t.vsw);
+}
+
+static ssize_t display_timings_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	struct omap_video_timings t;
+	int r, found;
+
+	if (!dssdev->set_timings || !dssdev->check_timings)
+		return -ENOENT;
+
+	found = 0;
+#ifdef CONFIG_OMAP2_DSS_VENC
+	if (strncmp("pal", buf, 3) == 0) {
+		t = omap_dss_pal_timings;
+		found = 1;
+	} else if (strncmp("ntsc", buf, 4) == 0) {
+		t = omap_dss_ntsc_timings;
+		found = 1;
+	}
+#endif
+	if (!found && sscanf(buf, "%u,%hu/%hu/%hu/%hu,%hu/%hu/%hu/%hu",
+				&t.pixel_clock,
+				&t.x_res, &t.hfp, &t.hbp, &t.hsw,
+				&t.y_res, &t.vfp, &t.vbp, &t.vsw) != 9)
+		return -EINVAL;
+
+	r = dssdev->check_timings(dssdev, &t);
+	if (r)
+		return r;
+
+	dssdev->set_timings(dssdev, &t);
+
+	return size;
+}
+
+static ssize_t display_rotate_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	int rotate;
+	if (!dssdev->get_rotate)
+		return -ENOENT;
+	rotate = dssdev->get_rotate(dssdev);
+	return snprintf(buf, PAGE_SIZE, "%u\n", rotate);
+}
+
+static ssize_t display_rotate_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	unsigned long rot;
+	int r;
+
+	if (!dssdev->set_rotate || !dssdev->get_rotate)
+		return -ENOENT;
+
+	rot = simple_strtoul(buf, NULL, 0);
+
+	r = dssdev->set_rotate(dssdev, rot);
+	if (r)
+		return r;
+
+	return size;
+}
+
+static ssize_t display_mirror_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	int mirror;
+	if (!dssdev->get_mirror)
+		return -ENOENT;
+	mirror = dssdev->get_mirror(dssdev);
+	return snprintf(buf, PAGE_SIZE, "%u\n", mirror);
+}
+
+static ssize_t display_mirror_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	unsigned long mirror;
+	int r;
+
+	if (!dssdev->set_mirror || !dssdev->get_mirror)
+		return -ENOENT;
+
+	mirror = simple_strtoul(buf, NULL, 0);
+
+	r = dssdev->set_mirror(dssdev, mirror);
+	if (r)
+		return r;
+
+	return size;
+}
+
+static ssize_t display_wss_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	unsigned int wss;
+
+	if (!dssdev->get_wss)
+		return -ENOENT;
+
+	wss = dssdev->get_wss(dssdev);
+
+	return snprintf(buf, PAGE_SIZE, "0x%05x\n", wss);
+}
+
+static ssize_t display_wss_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	unsigned long wss;
+	int r;
+
+	if (!dssdev->get_wss || !dssdev->set_wss)
+		return -ENOENT;
+
+	if (strict_strtoul(buf, 0, &wss))
+		return -EINVAL;
+
+	if (wss > 0xfffff)
+		return -EINVAL;
+
+	r = dssdev->set_wss(dssdev, wss);
+	if (r)
+		return r;
+
+	return size;
+}
+
+static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR,
+		display_enabled_show, display_enabled_store);
+static DEVICE_ATTR(update_mode, S_IRUGO|S_IWUSR,
+		display_upd_mode_show, display_upd_mode_store);
+static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR,
+		display_tear_show, display_tear_store);
+static DEVICE_ATTR(timings, S_IRUGO|S_IWUSR,
+		display_timings_show, display_timings_store);
+static DEVICE_ATTR(rotate, S_IRUGO|S_IWUSR,
+		display_rotate_show, display_rotate_store);
+static DEVICE_ATTR(mirror, S_IRUGO|S_IWUSR,
+		display_mirror_show, display_mirror_store);
+static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR,
+		display_wss_show, display_wss_store);
+
+static struct device_attribute *display_sysfs_attrs[] = {
+	&dev_attr_enabled,
+	&dev_attr_update_mode,
+	&dev_attr_tear_elim,
+	&dev_attr_timings,
+	&dev_attr_rotate,
+	&dev_attr_mirror,
+	&dev_attr_wss,
+	NULL
+};
+
+static void default_get_resolution(struct omap_dss_device *dssdev,
+			u16 *xres, u16 *yres)
+{
+	*xres = dssdev->panel.timings.x_res;
+	*yres = dssdev->panel.timings.y_res;
+}
+
+void default_get_overlay_fifo_thresholds(enum omap_plane plane,
+		u32 fifo_size, enum omap_burst_size *burst_size,
+		u32 *fifo_low, u32 *fifo_high)
+{
+	unsigned burst_size_bytes;
+
+	*burst_size = OMAP_DSS_BURST_16x32;
+	burst_size_bytes = 16 * 32 / 8;
+
+	*fifo_high = fifo_size - 1;
+	*fifo_low = fifo_size - burst_size_bytes;
+}
+
+static int default_wait_vsync(struct omap_dss_device *dssdev)
+{
+	unsigned long timeout = msecs_to_jiffies(500);
+	u32 irq;
+
+	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC)
+		irq = DISPC_IRQ_EVSYNC_ODD;
+	else
+		irq = DISPC_IRQ_VSYNC;
+
+	return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
+}
+
+static int default_get_recommended_bpp(struct omap_dss_device *dssdev)
+{
+	if (dssdev->panel.recommended_bpp)
+		return dssdev->panel.recommended_bpp;
+
+	switch (dssdev->type) {
+	case OMAP_DISPLAY_TYPE_DPI:
+		if (dssdev->phy.dpi.data_lines == 24)
+			return 24;
+		else
+			return 16;
+
+	case OMAP_DISPLAY_TYPE_DBI:
+	case OMAP_DISPLAY_TYPE_DSI:
+		if (dssdev->ctrl.pixel_size == 24)
+			return 24;
+		else
+			return 16;
+	case OMAP_DISPLAY_TYPE_VENC:
+	case OMAP_DISPLAY_TYPE_SDI:
+		return 24;
+		return 24;
+	default:
+		BUG();
+	}
+}
+
+/* Checks if replication logic should be used. Only use for active matrix,
+ * when overlay is in RGB12U or RGB16 mode, and LCD interface is
+ * 18bpp or 24bpp */
+bool dss_use_replication(struct omap_dss_device *dssdev,
+		enum omap_color_mode mode)
+{
+	int bpp;
+
+	if (mode != OMAP_DSS_COLOR_RGB12U && mode != OMAP_DSS_COLOR_RGB16)
+		return false;
+
+	if (dssdev->type == OMAP_DISPLAY_TYPE_DPI &&
+			(dssdev->panel.config & OMAP_DSS_LCD_TFT) == 0)
+		return false;
+
+	switch (dssdev->type) {
+	case OMAP_DISPLAY_TYPE_DPI:
+		bpp = dssdev->phy.dpi.data_lines;
+		break;
+	case OMAP_DISPLAY_TYPE_VENC:
+	case OMAP_DISPLAY_TYPE_SDI:
+		bpp = 24;
+		break;
+	case OMAP_DISPLAY_TYPE_DBI:
+	case OMAP_DISPLAY_TYPE_DSI:
+		bpp = dssdev->ctrl.pixel_size;
+		break;
+	default:
+		BUG();
+	}
+
+	return bpp > 16;
+}
+
+void dss_init_device(struct platform_device *pdev,
+		struct omap_dss_device *dssdev)
+{
+	struct device_attribute *attr;
+	int i;
+	int r;
+
+	switch (dssdev->type) {
+	case OMAP_DISPLAY_TYPE_DPI:
+#ifdef CONFIG_OMAP2_DSS_RFBI
+	case OMAP_DISPLAY_TYPE_DBI:
+#endif
+#ifdef CONFIG_OMAP2_DSS_SDI
+	case OMAP_DISPLAY_TYPE_SDI:
+#endif
+#ifdef CONFIG_OMAP2_DSS_DSI
+	case OMAP_DISPLAY_TYPE_DSI:
+#endif
+#ifdef CONFIG_OMAP2_DSS_VENC
+	case OMAP_DISPLAY_TYPE_VENC:
+#endif
+		break;
+	default:
+		DSSERR("Support for display '%s' not compiled in.\n",
+				dssdev->name);
+		return;
+	}
+
+	dssdev->get_resolution = default_get_resolution;
+	dssdev->get_recommended_bpp = default_get_recommended_bpp;
+	dssdev->wait_vsync = default_wait_vsync;
+
+	switch (dssdev->type) {
+	case OMAP_DISPLAY_TYPE_DPI:
+		r = dpi_init_display(dssdev);
+		break;
+#ifdef CONFIG_OMAP2_DSS_RFBI
+	case OMAP_DISPLAY_TYPE_DBI:
+		r = rfbi_init_display(dssdev);
+		break;
+#endif
+#ifdef CONFIG_OMAP2_DSS_VENC
+	case OMAP_DISPLAY_TYPE_VENC:
+		r = venc_init_display(dssdev);
+		break;
+#endif
+#ifdef CONFIG_OMAP2_DSS_SDI
+	case OMAP_DISPLAY_TYPE_SDI:
+		r = sdi_init_display(dssdev);
+		break;
+#endif
+#ifdef CONFIG_OMAP2_DSS_DSI
+	case OMAP_DISPLAY_TYPE_DSI:
+		r = dsi_init_display(dssdev);
+		break;
+#endif
+	default:
+		BUG();
+	}
+
+	if (r) {
+		DSSERR("failed to init display %s\n", dssdev->name);
+		return;
+	}
+
+	/* create device sysfs files */
+	i = 0;
+	while ((attr = display_sysfs_attrs[i++]) != NULL) {
+		r = device_create_file(&dssdev->dev, attr);
+		if (r)
+			DSSERR("failed to create sysfs file\n");
+	}
+
+	/* create display? sysfs links */
+	r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj,
+			dev_name(&dssdev->dev));
+	if (r)
+		DSSERR("failed to create sysfs display link\n");
+}
+
+void dss_uninit_device(struct platform_device *pdev,
+		struct omap_dss_device *dssdev)
+{
+	struct device_attribute *attr;
+	int i = 0;
+
+	sysfs_remove_link(&pdev->dev.kobj, dev_name(&dssdev->dev));
+
+	while ((attr = display_sysfs_attrs[i++]) != NULL)
+		device_remove_file(&dssdev->dev, attr);
+
+	if (dssdev->manager)
+		dssdev->manager->unset_device(dssdev->manager);
+}
+
+static int dss_suspend_device(struct device *dev, void *data)
+{
+	int r;
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
+		dssdev->activate_after_resume = false;
+		return 0;
+	}
+
+	if (!dssdev->suspend) {
+		DSSERR("display '%s' doesn't implement suspend\n",
+				dssdev->name);
+		return -ENOSYS;
+	}
+
+	r = dssdev->suspend(dssdev);
+	if (r)
+		return r;
+
+	dssdev->activate_after_resume = true;
+
+	return 0;
+}
+
+int dss_suspend_all_devices(void)
+{
+	int r;
+	struct bus_type *bus = dss_get_bus();
+
+	r = bus_for_each_dev(bus, NULL, NULL, dss_suspend_device);
+	if (r) {
+		/* resume all displays that were suspended */
+		dss_resume_all_devices();
+		return r;
+	}
+
+	return 0;
+}
+
+static int dss_resume_device(struct device *dev, void *data)
+{
+	int r;
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+
+	if (dssdev->activate_after_resume && dssdev->resume) {
+		r = dssdev->resume(dssdev);
+		if (r)
+			return r;
+	}
+
+	dssdev->activate_after_resume = false;
+
+	return 0;
+}
+
+int dss_resume_all_devices(void)
+{
+	struct bus_type *bus = dss_get_bus();
+
+	return bus_for_each_dev(bus, NULL, NULL, dss_resume_device);
+}
+
+static int dss_disable_device(struct device *dev, void *data)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	dssdev->disable(dssdev);
+	return 0;
+}
+
+void dss_disable_all_devices(void)
+{
+	struct bus_type *bus = dss_get_bus();
+	bus_for_each_dev(bus, NULL, NULL, dss_disable_device);
+}
+
+
+void omap_dss_get_device(struct omap_dss_device *dssdev)
+{
+	get_device(&dssdev->dev);
+}
+EXPORT_SYMBOL(omap_dss_get_device);
+
+void omap_dss_put_device(struct omap_dss_device *dssdev)
+{
+	put_device(&dssdev->dev);
+}
+EXPORT_SYMBOL(omap_dss_put_device);
+
+/* ref count of the found device is incremented. ref count
+ * of from-device is decremented. */
+struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from)
+{
+	struct device *dev;
+	struct device *dev_start = NULL;
+	struct omap_dss_device *dssdev = NULL;
+
+	int match(struct device *dev, void *data)
+	{
+		/* skip panels connected to controllers */
+		if (to_dss_device(dev)->panel.ctrl)
+			return 0;
+
+		return 1;
+	}
+
+	if (from)
+		dev_start = &from->dev;
+	dev = bus_find_device(dss_get_bus(), dev_start, NULL, match);
+	if (dev)
+		dssdev = to_dss_device(dev);
+	if (from)
+		put_device(&from->dev);
+
+	return dssdev;
+}
+EXPORT_SYMBOL(omap_dss_get_next_device);
+
+struct omap_dss_device *omap_dss_find_device(void *data,
+		int (*match)(struct omap_dss_device *dssdev, void *data))
+{
+	struct omap_dss_device *dssdev = NULL;
+
+	while ((dssdev = omap_dss_get_next_device(dssdev)) != NULL) {
+		if (match(dssdev, data))
+			return dssdev;
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL(omap_dss_find_device);
+
+int omap_dss_start_device(struct omap_dss_device *dssdev)
+{
+	int r;
+
+	if (!dssdev->driver) {
+		DSSDBG("no driver\n");
+		r = -ENODEV;
+		goto err0;
+	}
+
+	if (dssdev->ctrl.panel && !dssdev->ctrl.panel->driver) {
+		DSSDBG("no panel driver\n");
+		r = -ENODEV;
+		goto err0;
+	}
+
+	if (!try_module_get(dssdev->dev.driver->owner)) {
+		r = -ENODEV;
+		goto err0;
+	}
+
+	if (dssdev->ctrl.panel) {
+		if (!try_module_get(dssdev->ctrl.panel->dev.driver->owner)) {
+			r = -ENODEV;
+			goto err1;
+		}
+	}
+
+	return 0;
+err1:
+	module_put(dssdev->dev.driver->owner);
+err0:
+	return r;
+}
+EXPORT_SYMBOL(omap_dss_start_device);
+
+void omap_dss_stop_device(struct omap_dss_device *dssdev)
+{
+	if (dssdev->ctrl.panel)
+		module_put(dssdev->ctrl.panel->dev.driver->owner);
+
+	module_put(dssdev->dev.driver->owner);
+}
+EXPORT_SYMBOL(omap_dss_stop_device);
+
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
new file mode 100644
index 0000000..2d71031
--- /dev/null
+++ b/drivers/video/omap2/dss/dpi.c
@@ -0,0 +1,399 @@
+/*
+ * linux/drivers/video/omap2/dss/dpi.c
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * Some code and ideas taken from drivers/video/omap/ driver
+ * by Imre Deak.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define DSS_SUBSYS_NAME "DPI"
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+
+#include <plat/display.h>
+#include <plat/cpu.h>
+
+#include "dss.h"
+
+static struct {
+	int update_enabled;
+} dpi;
+
+#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
+static int dpi_set_dsi_clk(bool is_tft, unsigned long pck_req,
+		unsigned long *fck, int *lck_div, int *pck_div)
+{
+	struct dsi_clock_info dsi_cinfo;
+	struct dispc_clock_info dispc_cinfo;
+	int r;
+
+	r = dsi_pll_calc_clock_div_pck(is_tft, pck_req, &dsi_cinfo,
+			&dispc_cinfo);
+	if (r)
+		return r;
+
+	r = dsi_pll_set_clock_div(&dsi_cinfo);
+	if (r)
+		return r;
+
+	dss_select_clk_source(0, 1);
+
+	r = dispc_set_clock_div(&dispc_cinfo);
+	if (r)
+		return r;
+
+	*fck = dsi_cinfo.dsi1_pll_fclk;
+	*lck_div = dispc_cinfo.lck_div;
+	*pck_div = dispc_cinfo.pck_div;
+
+	return 0;
+}
+#else
+static int dpi_set_dispc_clk(bool is_tft, unsigned long pck_req,
+		unsigned long *fck, int *lck_div, int *pck_div)
+{
+	struct dss_clock_info dss_cinfo;
+	struct dispc_clock_info dispc_cinfo;
+	int r;
+
+	r = dss_calc_clock_div(is_tft, pck_req, &dss_cinfo, &dispc_cinfo);
+	if (r)
+		return r;
+
+	r = dss_set_clock_div(&dss_cinfo);
+	if (r)
+		return r;
+
+	r = dispc_set_clock_div(&dispc_cinfo);
+	if (r)
+		return r;
+
+	*fck = dss_cinfo.fck;
+	*lck_div = dispc_cinfo.lck_div;
+	*pck_div = dispc_cinfo.pck_div;
+
+	return 0;
+}
+#endif
+
+static int dpi_set_mode(struct omap_dss_device *dssdev)
+{
+	struct omap_video_timings *t = &dssdev->panel.timings;
+	int lck_div, pck_div;
+	unsigned long fck;
+	unsigned long pck;
+	bool is_tft;
+	int r = 0;
+
+	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+
+	dispc_set_pol_freq(dssdev->panel.config, dssdev->panel.acbi,
+			dssdev->panel.acb);
+
+	is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
+
+#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
+	r = dpi_set_dsi_clk(is_tft, t->pixel_clock * 1000,
+			&fck, &lck_div, &pck_div);
+#else
+	r = dpi_set_dispc_clk(is_tft, t->pixel_clock * 1000,
+			&fck, &lck_div, &pck_div);
+#endif
+	if (r)
+		goto err0;
+
+	pck = fck / lck_div / pck_div / 1000;
+
+	if (pck != t->pixel_clock) {
+		DSSWARN("Could not find exact pixel clock. "
+				"Requested %d kHz, got %lu kHz\n",
+				t->pixel_clock, pck);
+
+		t->pixel_clock = pck;
+	}
+
+	dispc_set_lcd_timings(t);
+
+err0:
+	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+	return r;
+}
+
+static int dpi_basic_init(struct omap_dss_device *dssdev)
+{
+	bool is_tft;
+
+	is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
+
+	dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_BYPASS);
+	dispc_set_lcd_display_type(is_tft ? OMAP_DSS_LCD_DISPLAY_TFT :
+			OMAP_DSS_LCD_DISPLAY_STN);
+	dispc_set_tft_data_lines(dssdev->phy.dpi.data_lines);
+
+	return 0;
+}
+
+static int dpi_display_enable(struct omap_dss_device *dssdev)
+{
+	int r;
+
+	r = omap_dss_start_device(dssdev);
+	if (r) {
+		DSSERR("failed to start device\n");
+		goto err0;
+	}
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
+		DSSERR("display already enabled\n");
+		r = -EINVAL;
+		goto err1;
+	}
+
+	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+
+	r = dpi_basic_init(dssdev);
+	if (r)
+		goto err2;
+
+#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
+	dss_clk_enable(DSS_CLK_FCK2);
+	r = dsi_pll_init(dssdev, 0, 1);
+	if (r)
+		goto err3;
+#endif
+	r = dpi_set_mode(dssdev);
+	if (r)
+		goto err4;
+
+	mdelay(2);
+
+	dispc_enable_lcd_out(1);
+
+	r = dssdev->driver->enable(dssdev);
+	if (r)
+		goto err5;
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	return 0;
+
+err5:
+	dispc_enable_lcd_out(0);
+err4:
+#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
+	dsi_pll_uninit();
+err3:
+	dss_clk_disable(DSS_CLK_FCK2);
+#endif
+err2:
+	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+err1:
+	omap_dss_stop_device(dssdev);
+err0:
+	return r;
+}
+
+static int dpi_display_resume(struct omap_dss_device *dssdev);
+
+static void dpi_display_disable(struct omap_dss_device *dssdev)
+{
+	if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
+		return;
+
+	if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
+		dpi_display_resume(dssdev);
+
+	dssdev->driver->disable(dssdev);
+
+	dispc_enable_lcd_out(0);
+
+#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
+	dss_select_clk_source(0, 0);
+	dsi_pll_uninit();
+	dss_clk_disable(DSS_CLK_FCK2);
+#endif
+
+	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+
+	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+
+	omap_dss_stop_device(dssdev);
+}
+
+static int dpi_display_suspend(struct omap_dss_device *dssdev)
+{
+	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+		return -EINVAL;
+
+	DSSDBG("dpi_display_suspend\n");
+
+	if (dssdev->driver->suspend)
+		dssdev->driver->suspend(dssdev);
+
+	dispc_enable_lcd_out(0);
+
+	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+
+	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
+
+	return 0;
+}
+
+static int dpi_display_resume(struct omap_dss_device *dssdev)
+{
+	if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED)
+		return -EINVAL;
+
+	DSSDBG("dpi_display_resume\n");
+
+	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+
+	dispc_enable_lcd_out(1);
+
+	if (dssdev->driver->resume)
+		dssdev->driver->resume(dssdev);
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	return 0;
+}
+
+static void dpi_set_timings(struct omap_dss_device *dssdev,
+			struct omap_video_timings *timings)
+{
+	DSSDBG("dpi_set_timings\n");
+	dssdev->panel.timings = *timings;
+	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
+		dpi_set_mode(dssdev);
+		dispc_go(OMAP_DSS_CHANNEL_LCD);
+	}
+}
+
+static int dpi_check_timings(struct omap_dss_device *dssdev,
+			struct omap_video_timings *timings)
+{
+	bool is_tft;
+	int r;
+	int lck_div, pck_div;
+	unsigned long fck;
+	unsigned long pck;
+
+	if (!dispc_lcd_timings_ok(timings))
+		return -EINVAL;
+
+	if (timings->pixel_clock == 0)
+		return -EINVAL;
+
+	is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
+
+#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
+	{
+		struct dsi_clock_info dsi_cinfo;
+		struct dispc_clock_info dispc_cinfo;
+		r = dsi_pll_calc_clock_div_pck(is_tft,
+				timings->pixel_clock * 1000,
+				&dsi_cinfo, &dispc_cinfo);
+
+		if (r)
+			return r;
+
+		fck = dsi_cinfo.dsi1_pll_fclk;
+		lck_div = dispc_cinfo.lck_div;
+		pck_div = dispc_cinfo.pck_div;
+	}
+#else
+	{
+		struct dss_clock_info dss_cinfo;
+		struct dispc_clock_info dispc_cinfo;
+		r = dss_calc_clock_div(is_tft, timings->pixel_clock * 1000,
+				&dss_cinfo, &dispc_cinfo);
+
+		if (r)
+			return r;
+
+		fck = dss_cinfo.fck;
+		lck_div = dispc_cinfo.lck_div;
+		pck_div = dispc_cinfo.pck_div;
+	}
+#endif
+
+	pck = fck / lck_div / pck_div / 1000;
+
+	timings->pixel_clock = pck;
+
+	return 0;
+}
+
+static void dpi_get_timings(struct omap_dss_device *dssdev,
+			struct omap_video_timings *timings)
+{
+	*timings = dssdev->panel.timings;
+}
+
+static int dpi_display_set_update_mode(struct omap_dss_device *dssdev,
+		enum omap_dss_update_mode mode)
+{
+	if (mode == OMAP_DSS_UPDATE_MANUAL)
+		return -EINVAL;
+
+	if (mode == OMAP_DSS_UPDATE_DISABLED) {
+		dispc_enable_lcd_out(0);
+		dpi.update_enabled = 0;
+	} else {
+		dispc_enable_lcd_out(1);
+		dpi.update_enabled = 1;
+	}
+
+	return 0;
+}
+
+static enum omap_dss_update_mode dpi_display_get_update_mode(
+		struct omap_dss_device *dssdev)
+{
+	return dpi.update_enabled ? OMAP_DSS_UPDATE_AUTO :
+		OMAP_DSS_UPDATE_DISABLED;
+}
+
+int dpi_init_display(struct omap_dss_device *dssdev)
+{
+	DSSDBG("init_display\n");
+
+	dssdev->enable = dpi_display_enable;
+	dssdev->disable = dpi_display_disable;
+	dssdev->suspend = dpi_display_suspend;
+	dssdev->resume = dpi_display_resume;
+	dssdev->set_timings = dpi_set_timings;
+	dssdev->check_timings = dpi_check_timings;
+	dssdev->get_timings = dpi_get_timings;
+	dssdev->set_update_mode = dpi_display_set_update_mode;
+	dssdev->get_update_mode = dpi_display_get_update_mode;
+
+	return 0;
+}
+
+int dpi_init(void)
+{
+	return 0;
+}
+
+void dpi_exit(void)
+{
+}
+
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
new file mode 100644
index 0000000..5936487
--- /dev/null
+++ b/drivers/video/omap2/dss/dsi.c
@@ -0,0 +1,3710 @@
+/*
+ * linux/drivers/video/omap2/dss/dsi.c
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define DSS_SUBSYS_NAME "DSI"
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/seq_file.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/kthread.h>
+#include <linux/wait.h>
+
+#include <plat/display.h>
+#include <plat/clock.h>
+
+#include "dss.h"
+
+/*#define VERBOSE_IRQ*/
+#define DSI_CATCH_MISSING_TE
+
+#define DSI_BASE		0x4804FC00
+
+struct dsi_reg { u16 idx; };
+
+#define DSI_REG(idx)		((const struct dsi_reg) { idx })
+
+#define DSI_SZ_REGS		SZ_1K
+/* DSI Protocol Engine */
+
+#define DSI_REVISION			DSI_REG(0x0000)
+#define DSI_SYSCONFIG			DSI_REG(0x0010)
+#define DSI_SYSSTATUS			DSI_REG(0x0014)
+#define DSI_IRQSTATUS			DSI_REG(0x0018)
+#define DSI_IRQENABLE			DSI_REG(0x001C)
+#define DSI_CTRL			DSI_REG(0x0040)
+#define DSI_COMPLEXIO_CFG1		DSI_REG(0x0048)
+#define DSI_COMPLEXIO_IRQ_STATUS	DSI_REG(0x004C)
+#define DSI_COMPLEXIO_IRQ_ENABLE	DSI_REG(0x0050)
+#define DSI_CLK_CTRL			DSI_REG(0x0054)
+#define DSI_TIMING1			DSI_REG(0x0058)
+#define DSI_TIMING2			DSI_REG(0x005C)
+#define DSI_VM_TIMING1			DSI_REG(0x0060)
+#define DSI_VM_TIMING2			DSI_REG(0x0064)
+#define DSI_VM_TIMING3			DSI_REG(0x0068)
+#define DSI_CLK_TIMING			DSI_REG(0x006C)
+#define DSI_TX_FIFO_VC_SIZE		DSI_REG(0x0070)
+#define DSI_RX_FIFO_VC_SIZE		DSI_REG(0x0074)
+#define DSI_COMPLEXIO_CFG2		DSI_REG(0x0078)
+#define DSI_RX_FIFO_VC_FULLNESS		DSI_REG(0x007C)
+#define DSI_VM_TIMING4			DSI_REG(0x0080)
+#define DSI_TX_FIFO_VC_EMPTINESS	DSI_REG(0x0084)
+#define DSI_VM_TIMING5			DSI_REG(0x0088)
+#define DSI_VM_TIMING6			DSI_REG(0x008C)
+#define DSI_VM_TIMING7			DSI_REG(0x0090)
+#define DSI_STOPCLK_TIMING		DSI_REG(0x0094)
+#define DSI_VC_CTRL(n)			DSI_REG(0x0100 + (n * 0x20))
+#define DSI_VC_TE(n)			DSI_REG(0x0104 + (n * 0x20))
+#define DSI_VC_LONG_PACKET_HEADER(n)	DSI_REG(0x0108 + (n * 0x20))
+#define DSI_VC_LONG_PACKET_PAYLOAD(n)	DSI_REG(0x010C + (n * 0x20))
+#define DSI_VC_SHORT_PACKET_HEADER(n)	DSI_REG(0x0110 + (n * 0x20))
+#define DSI_VC_IRQSTATUS(n)		DSI_REG(0x0118 + (n * 0x20))
+#define DSI_VC_IRQENABLE(n)		DSI_REG(0x011C + (n * 0x20))
+
+/* DSIPHY_SCP */
+
+#define DSI_DSIPHY_CFG0			DSI_REG(0x200 + 0x0000)
+#define DSI_DSIPHY_CFG1			DSI_REG(0x200 + 0x0004)
+#define DSI_DSIPHY_CFG2			DSI_REG(0x200 + 0x0008)
+#define DSI_DSIPHY_CFG5			DSI_REG(0x200 + 0x0014)
+
+/* DSI_PLL_CTRL_SCP */
+
+#define DSI_PLL_CONTROL			DSI_REG(0x300 + 0x0000)
+#define DSI_PLL_STATUS			DSI_REG(0x300 + 0x0004)
+#define DSI_PLL_GO			DSI_REG(0x300 + 0x0008)
+#define DSI_PLL_CONFIGURATION1		DSI_REG(0x300 + 0x000C)
+#define DSI_PLL_CONFIGURATION2		DSI_REG(0x300 + 0x0010)
+
+#define REG_GET(idx, start, end) \
+	FLD_GET(dsi_read_reg(idx), start, end)
+
+#define REG_FLD_MOD(idx, val, start, end) \
+	dsi_write_reg(idx, FLD_MOD(dsi_read_reg(idx), val, start, end))
+
+/* Global interrupts */
+#define DSI_IRQ_VC0		(1 << 0)
+#define DSI_IRQ_VC1		(1 << 1)
+#define DSI_IRQ_VC2		(1 << 2)
+#define DSI_IRQ_VC3		(1 << 3)
+#define DSI_IRQ_WAKEUP		(1 << 4)
+#define DSI_IRQ_RESYNC		(1 << 5)
+#define DSI_IRQ_PLL_LOCK	(1 << 7)
+#define DSI_IRQ_PLL_UNLOCK	(1 << 8)
+#define DSI_IRQ_PLL_RECALL	(1 << 9)
+#define DSI_IRQ_COMPLEXIO_ERR	(1 << 10)
+#define DSI_IRQ_HS_TX_TIMEOUT	(1 << 14)
+#define DSI_IRQ_LP_RX_TIMEOUT	(1 << 15)
+#define DSI_IRQ_TE_TRIGGER	(1 << 16)
+#define DSI_IRQ_ACK_TRIGGER	(1 << 17)
+#define DSI_IRQ_SYNC_LOST	(1 << 18)
+#define DSI_IRQ_LDO_POWER_GOOD	(1 << 19)
+#define DSI_IRQ_TA_TIMEOUT	(1 << 20)
+#define DSI_IRQ_ERROR_MASK \
+	(DSI_IRQ_HS_TX_TIMEOUT | DSI_IRQ_LP_RX_TIMEOUT | DSI_IRQ_SYNC_LOST | \
+	DSI_IRQ_TA_TIMEOUT)
+#define DSI_IRQ_CHANNEL_MASK	0xf
+
+/* Virtual channel interrupts */
+#define DSI_VC_IRQ_CS		(1 << 0)
+#define DSI_VC_IRQ_ECC_CORR	(1 << 1)
+#define DSI_VC_IRQ_PACKET_SENT	(1 << 2)
+#define DSI_VC_IRQ_FIFO_TX_OVF	(1 << 3)
+#define DSI_VC_IRQ_FIFO_RX_OVF	(1 << 4)
+#define DSI_VC_IRQ_BTA		(1 << 5)
+#define DSI_VC_IRQ_ECC_NO_CORR	(1 << 6)
+#define DSI_VC_IRQ_FIFO_TX_UDF	(1 << 7)
+#define DSI_VC_IRQ_PP_BUSY_CHANGE (1 << 8)
+#define DSI_VC_IRQ_ERROR_MASK \
+	(DSI_VC_IRQ_CS | DSI_VC_IRQ_ECC_CORR | DSI_VC_IRQ_FIFO_TX_OVF | \
+	DSI_VC_IRQ_FIFO_RX_OVF | DSI_VC_IRQ_ECC_NO_CORR | \
+	DSI_VC_IRQ_FIFO_TX_UDF)
+
+/* ComplexIO interrupts */
+#define DSI_CIO_IRQ_ERRSYNCESC1		(1 << 0)
+#define DSI_CIO_IRQ_ERRSYNCESC2		(1 << 1)
+#define DSI_CIO_IRQ_ERRSYNCESC3		(1 << 2)
+#define DSI_CIO_IRQ_ERRESC1		(1 << 5)
+#define DSI_CIO_IRQ_ERRESC2		(1 << 6)
+#define DSI_CIO_IRQ_ERRESC3		(1 << 7)
+#define DSI_CIO_IRQ_ERRCONTROL1		(1 << 10)
+#define DSI_CIO_IRQ_ERRCONTROL2		(1 << 11)
+#define DSI_CIO_IRQ_ERRCONTROL3		(1 << 12)
+#define DSI_CIO_IRQ_STATEULPS1		(1 << 15)
+#define DSI_CIO_IRQ_STATEULPS2		(1 << 16)
+#define DSI_CIO_IRQ_STATEULPS3		(1 << 17)
+#define DSI_CIO_IRQ_ERRCONTENTIONLP0_1	(1 << 20)
+#define DSI_CIO_IRQ_ERRCONTENTIONLP1_1	(1 << 21)
+#define DSI_CIO_IRQ_ERRCONTENTIONLP0_2	(1 << 22)
+#define DSI_CIO_IRQ_ERRCONTENTIONLP1_2	(1 << 23)
+#define DSI_CIO_IRQ_ERRCONTENTIONLP0_3	(1 << 24)
+#define DSI_CIO_IRQ_ERRCONTENTIONLP1_3	(1 << 25)
+#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL0	(1 << 30)
+#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL1	(1 << 31)
+
+#define DSI_DT_DCS_SHORT_WRITE_0	0x05
+#define DSI_DT_DCS_SHORT_WRITE_1	0x15
+#define DSI_DT_DCS_READ			0x06
+#define DSI_DT_SET_MAX_RET_PKG_SIZE	0x37
+#define DSI_DT_NULL_PACKET		0x09
+#define DSI_DT_DCS_LONG_WRITE		0x39
+
+#define DSI_DT_RX_ACK_WITH_ERR		0x02
+#define DSI_DT_RX_DCS_LONG_READ		0x1c
+#define DSI_DT_RX_SHORT_READ_1		0x21
+#define DSI_DT_RX_SHORT_READ_2		0x22
+
+#define FINT_MAX 2100000
+#define FINT_MIN 750000
+#define REGN_MAX (1 << 7)
+#define REGM_MAX ((1 << 11) - 1)
+#define REGM3_MAX (1 << 4)
+#define REGM4_MAX (1 << 4)
+#define LP_DIV_MAX ((1 << 13) - 1)
+
+enum fifo_size {
+	DSI_FIFO_SIZE_0		= 0,
+	DSI_FIFO_SIZE_32	= 1,
+	DSI_FIFO_SIZE_64	= 2,
+	DSI_FIFO_SIZE_96	= 3,
+	DSI_FIFO_SIZE_128	= 4,
+};
+
+enum dsi_vc_mode {
+	DSI_VC_MODE_L4 = 0,
+	DSI_VC_MODE_VP,
+};
+
+struct dsi_update_region {
+	bool dirty;
+	u16 x, y, w, h;
+	struct omap_dss_device *device;
+};
+
+static struct
+{
+	void __iomem	*base;
+
+	struct dsi_clock_info current_cinfo;
+
+	struct regulator *vdds_dsi_reg;
+
+	struct {
+		enum dsi_vc_mode mode;
+		struct omap_dss_device *dssdev;
+		enum fifo_size fifo_size;
+		int dest_per;	/* destination peripheral 0-3 */
+	} vc[4];
+
+	struct mutex lock;
+	struct mutex bus_lock;
+
+	unsigned pll_locked;
+
+	struct completion bta_completion;
+
+	struct task_struct *thread;
+	wait_queue_head_t waitqueue;
+
+	spinlock_t update_lock;
+	bool framedone_received;
+	struct dsi_update_region update_region;
+	struct dsi_update_region active_update_region;
+	struct completion update_completion;
+
+	enum omap_dss_update_mode user_update_mode;
+	enum omap_dss_update_mode update_mode;
+	bool te_enabled;
+	bool use_ext_te;
+
+#ifdef DSI_CATCH_MISSING_TE
+	struct timer_list te_timer;
+#endif
+
+	unsigned long cache_req_pck;
+	unsigned long cache_clk_freq;
+	struct dsi_clock_info cache_cinfo;
+
+	u32		errors;
+	spinlock_t	errors_lock;
+#ifdef DEBUG
+	ktime_t perf_setup_time;
+	ktime_t perf_start_time;
+	ktime_t perf_start_time_auto;
+	int perf_measure_frames;
+#endif
+	int debug_read;
+	int debug_write;
+} dsi;
+
+#ifdef DEBUG
+static unsigned int dsi_perf;
+module_param_named(dsi_perf, dsi_perf, bool, 0644);
+#endif
+
+static inline void dsi_write_reg(const struct dsi_reg idx, u32 val)
+{
+	__raw_writel(val, dsi.base + idx.idx);
+}
+
+static inline u32 dsi_read_reg(const struct dsi_reg idx)
+{
+	return __raw_readl(dsi.base + idx.idx);
+}
+
+
+void dsi_save_context(void)
+{
+}
+
+void dsi_restore_context(void)
+{
+}
+
+void dsi_bus_lock(void)
+{
+	mutex_lock(&dsi.bus_lock);
+}
+EXPORT_SYMBOL(dsi_bus_lock);
+
+void dsi_bus_unlock(void)
+{
+	mutex_unlock(&dsi.bus_lock);
+}
+EXPORT_SYMBOL(dsi_bus_unlock);
+
+static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum,
+		int value)
+{
+	int t = 100000;
+
+	while (REG_GET(idx, bitnum, bitnum) != value) {
+		if (--t == 0)
+			return !value;
+	}
+
+	return value;
+}
+
+#ifdef DEBUG
+static void dsi_perf_mark_setup(void)
+{
+	dsi.perf_setup_time = ktime_get();
+}
+
+static void dsi_perf_mark_start(void)
+{
+	dsi.perf_start_time = ktime_get();
+}
+
+static void dsi_perf_mark_start_auto(void)
+{
+	dsi.perf_measure_frames = 0;
+	dsi.perf_start_time_auto = ktime_get();
+}
+
+static void dsi_perf_show(const char *name)
+{
+	ktime_t t, setup_time, trans_time;
+	u32 total_bytes;
+	u32 setup_us, trans_us, total_us;
+
+	if (!dsi_perf)
+		return;
+
+	if (dsi.update_mode == OMAP_DSS_UPDATE_DISABLED)
+		return;
+
+	t = ktime_get();
+
+	setup_time = ktime_sub(dsi.perf_start_time, dsi.perf_setup_time);
+	setup_us = (u32)ktime_to_us(setup_time);
+	if (setup_us == 0)
+		setup_us = 1;
+
+	trans_time = ktime_sub(t, dsi.perf_start_time);
+	trans_us = (u32)ktime_to_us(trans_time);
+	if (trans_us == 0)
+		trans_us = 1;
+
+	total_us = setup_us + trans_us;
+
+	total_bytes = dsi.active_update_region.w *
+		dsi.active_update_region.h *
+		dsi.active_update_region.device->ctrl.pixel_size / 8;
+
+	if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO) {
+		static u32 s_total_trans_us, s_total_setup_us;
+		static u32 s_min_trans_us = 0xffffffff, s_min_setup_us;
+		static u32 s_max_trans_us, s_max_setup_us;
+		const int numframes = 100;
+		ktime_t total_time_auto;
+		u32 total_time_auto_us;
+
+		dsi.perf_measure_frames++;
+
+		if (setup_us < s_min_setup_us)
+			s_min_setup_us = setup_us;
+
+		if (setup_us > s_max_setup_us)
+			s_max_setup_us = setup_us;
+
+		s_total_setup_us += setup_us;
+
+		if (trans_us < s_min_trans_us)
+			s_min_trans_us = trans_us;
+
+		if (trans_us > s_max_trans_us)
+			s_max_trans_us = trans_us;
+
+		s_total_trans_us += trans_us;
+
+		if (dsi.perf_measure_frames < numframes)
+			return;
+
+		total_time_auto = ktime_sub(t, dsi.perf_start_time_auto);
+		total_time_auto_us = (u32)ktime_to_us(total_time_auto);
+
+		printk(KERN_INFO "DSI(%s): %u fps, setup %u/%u/%u, "
+				"trans %u/%u/%u\n",
+				name,
+				1000 * 1000 * numframes / total_time_auto_us,
+				s_min_setup_us,
+				s_max_setup_us,
+				s_total_setup_us / numframes,
+				s_min_trans_us,
+				s_max_trans_us,
+				s_total_trans_us / numframes);
+
+		s_total_setup_us = 0;
+		s_min_setup_us = 0xffffffff;
+		s_max_setup_us = 0;
+		s_total_trans_us = 0;
+		s_min_trans_us = 0xffffffff;
+		s_max_trans_us = 0;
+		dsi_perf_mark_start_auto();
+	} else {
+		printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), "
+				"%u bytes, %u kbytes/sec\n",
+				name,
+				setup_us,
+				trans_us,
+				total_us,
+				1000*1000 / total_us,
+				total_bytes,
+				total_bytes * 1000 / total_us);
+	}
+}
+#else
+#define dsi_perf_mark_setup()
+#define dsi_perf_mark_start()
+#define dsi_perf_mark_start_auto()
+#define dsi_perf_show(x)
+#endif
+
+static void print_irq_status(u32 status)
+{
+#ifndef VERBOSE_IRQ
+	if ((status & ~DSI_IRQ_CHANNEL_MASK) == 0)
+		return;
+#endif
+	printk(KERN_DEBUG "DSI IRQ: 0x%x: ", status);
+
+#define PIS(x) \
+	if (status & DSI_IRQ_##x) \
+		printk(#x " ");
+#ifdef VERBOSE_IRQ
+	PIS(VC0);
+	PIS(VC1);
+	PIS(VC2);
+	PIS(VC3);
+#endif
+	PIS(WAKEUP);
+	PIS(RESYNC);
+	PIS(PLL_LOCK);
+	PIS(PLL_UNLOCK);
+	PIS(PLL_RECALL);
+	PIS(COMPLEXIO_ERR);
+	PIS(HS_TX_TIMEOUT);
+	PIS(LP_RX_TIMEOUT);
+	PIS(TE_TRIGGER);
+	PIS(ACK_TRIGGER);
+	PIS(SYNC_LOST);
+	PIS(LDO_POWER_GOOD);
+	PIS(TA_TIMEOUT);
+#undef PIS
+
+	printk("\n");
+}
+
+static void print_irq_status_vc(int channel, u32 status)
+{
+#ifndef VERBOSE_IRQ
+	if ((status & ~DSI_VC_IRQ_PACKET_SENT) == 0)
+		return;
+#endif
+	printk(KERN_DEBUG "DSI VC(%d) IRQ 0x%x: ", channel, status);
+
+#define PIS(x) \
+	if (status & DSI_VC_IRQ_##x) \
+		printk(#x " ");
+	PIS(CS);
+	PIS(ECC_CORR);
+#ifdef VERBOSE_IRQ
+	PIS(PACKET_SENT);
+#endif
+	PIS(FIFO_TX_OVF);
+	PIS(FIFO_RX_OVF);
+	PIS(BTA);
+	PIS(ECC_NO_CORR);
+	PIS(FIFO_TX_UDF);
+	PIS(PP_BUSY_CHANGE);
+#undef PIS
+	printk("\n");
+}
+
+static void print_irq_status_cio(u32 status)
+{
+	printk(KERN_DEBUG "DSI CIO IRQ 0x%x: ", status);
+
+#define PIS(x) \
+	if (status & DSI_CIO_IRQ_##x) \
+		printk(#x " ");
+	PIS(ERRSYNCESC1);
+	PIS(ERRSYNCESC2);
+	PIS(ERRSYNCESC3);
+	PIS(ERRESC1);
+	PIS(ERRESC2);
+	PIS(ERRESC3);
+	PIS(ERRCONTROL1);
+	PIS(ERRCONTROL2);
+	PIS(ERRCONTROL3);
+	PIS(STATEULPS1);
+	PIS(STATEULPS2);
+	PIS(STATEULPS3);
+	PIS(ERRCONTENTIONLP0_1);
+	PIS(ERRCONTENTIONLP1_1);
+	PIS(ERRCONTENTIONLP0_2);
+	PIS(ERRCONTENTIONLP1_2);
+	PIS(ERRCONTENTIONLP0_3);
+	PIS(ERRCONTENTIONLP1_3);
+	PIS(ULPSACTIVENOT_ALL0);
+	PIS(ULPSACTIVENOT_ALL1);
+#undef PIS
+
+	printk("\n");
+}
+
+static int debug_irq;
+
+/* called from dss */
+void dsi_irq_handler(void)
+{
+	u32 irqstatus, vcstatus, ciostatus;
+	int i;
+
+	irqstatus = dsi_read_reg(DSI_IRQSTATUS);
+
+	if (irqstatus & DSI_IRQ_ERROR_MASK) {
+		DSSERR("DSI error, irqstatus %x\n", irqstatus);
+		print_irq_status(irqstatus);
+		spin_lock(&dsi.errors_lock);
+		dsi.errors |= irqstatus & DSI_IRQ_ERROR_MASK;
+		spin_unlock(&dsi.errors_lock);
+	} else if (debug_irq) {
+		print_irq_status(irqstatus);
+	}
+
+#ifdef DSI_CATCH_MISSING_TE
+	if (irqstatus & DSI_IRQ_TE_TRIGGER)
+		del_timer(&dsi.te_timer);
+#endif
+
+	for (i = 0; i < 4; ++i) {
+		if ((irqstatus & (1<<i)) == 0)
+			continue;
+
+		vcstatus = dsi_read_reg(DSI_VC_IRQSTATUS(i));
+
+		if (vcstatus & DSI_VC_IRQ_BTA)
+			complete(&dsi.bta_completion);
+
+		if (vcstatus & DSI_VC_IRQ_ERROR_MASK) {
+			DSSERR("DSI VC(%d) error, vc irqstatus %x\n",
+				       i, vcstatus);
+			print_irq_status_vc(i, vcstatus);
+		} else if (debug_irq) {
+			print_irq_status_vc(i, vcstatus);
+		}
+
+		dsi_write_reg(DSI_VC_IRQSTATUS(i), vcstatus);
+		/* flush posted write */
+		dsi_read_reg(DSI_VC_IRQSTATUS(i));
+	}
+
+	if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) {
+		ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS);
+
+		dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus);
+		/* flush posted write */
+		dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS);
+
+		DSSERR("DSI CIO error, cio irqstatus %x\n", ciostatus);
+		print_irq_status_cio(ciostatus);
+	}
+
+	dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK);
+	/* flush posted write */
+	dsi_read_reg(DSI_IRQSTATUS);
+}
+
+
+static void _dsi_initialize_irq(void)
+{
+	u32 l;
+	int i;
+
+	/* disable all interrupts */
+	dsi_write_reg(DSI_IRQENABLE, 0);
+	for (i = 0; i < 4; ++i)
+		dsi_write_reg(DSI_VC_IRQENABLE(i), 0);
+	dsi_write_reg(DSI_COMPLEXIO_IRQ_ENABLE, 0);
+
+	/* clear interrupt status */
+	l = dsi_read_reg(DSI_IRQSTATUS);
+	dsi_write_reg(DSI_IRQSTATUS, l & ~DSI_IRQ_CHANNEL_MASK);
+
+	for (i = 0; i < 4; ++i) {
+		l = dsi_read_reg(DSI_VC_IRQSTATUS(i));
+		dsi_write_reg(DSI_VC_IRQSTATUS(i), l);
+	}
+
+	l = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS);
+	dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, l);
+
+	/* enable error irqs */
+	l = DSI_IRQ_ERROR_MASK;
+#ifdef DSI_CATCH_MISSING_TE
+	l |= DSI_IRQ_TE_TRIGGER;
+#endif
+	dsi_write_reg(DSI_IRQENABLE, l);
+
+	l = DSI_VC_IRQ_ERROR_MASK;
+	for (i = 0; i < 4; ++i)
+		dsi_write_reg(DSI_VC_IRQENABLE(i), l);
+
+	/* XXX zonda responds incorrectly, causing control error:
+	   Exit from LP-ESC mode to LP11 uses wrong transition states on the
+	   data lines LP0 and LN0. */
+	dsi_write_reg(DSI_COMPLEXIO_IRQ_ENABLE,
+			-1 & (~DSI_CIO_IRQ_ERRCONTROL2));
+}
+
+static u32 dsi_get_errors(void)
+{
+	unsigned long flags;
+	u32 e;
+	spin_lock_irqsave(&dsi.errors_lock, flags);
+	e = dsi.errors;
+	dsi.errors = 0;
+	spin_unlock_irqrestore(&dsi.errors_lock, flags);
+	return e;
+}
+
+static void dsi_vc_enable_bta_irq(int channel)
+{
+	u32 l;
+
+	dsi_write_reg(DSI_VC_IRQSTATUS(channel), DSI_VC_IRQ_BTA);
+
+	l = dsi_read_reg(DSI_VC_IRQENABLE(channel));
+	l |= DSI_VC_IRQ_BTA;
+	dsi_write_reg(DSI_VC_IRQENABLE(channel), l);
+}
+
+static void dsi_vc_disable_bta_irq(int channel)
+{
+	u32 l;
+
+	l = dsi_read_reg(DSI_VC_IRQENABLE(channel));
+	l &= ~DSI_VC_IRQ_BTA;
+	dsi_write_reg(DSI_VC_IRQENABLE(channel), l);
+}
+
+/* DSI func clock. this could also be DSI2_PLL_FCLK */
+static inline void enable_clocks(bool enable)
+{
+	if (enable)
+		dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+	else
+		dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+}
+
+/* source clock for DSI PLL. this could also be PCLKFREE */
+static inline void dsi_enable_pll_clock(bool enable)
+{
+	if (enable)
+		dss_clk_enable(DSS_CLK_FCK2);
+	else
+		dss_clk_disable(DSS_CLK_FCK2);
+
+	if (enable && dsi.pll_locked) {
+		if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1)
+			DSSERR("cannot lock PLL when enabling clocks\n");
+	}
+}
+
+#ifdef DEBUG
+static void _dsi_print_reset_status(void)
+{
+	u32 l;
+
+	if (!dss_debug)
+		return;
+
+	/* A dummy read using the SCP interface to any DSIPHY register is
+	 * required after DSIPHY reset to complete the reset of the DSI complex
+	 * I/O. */
+	l = dsi_read_reg(DSI_DSIPHY_CFG5);
+
+	printk(KERN_DEBUG "DSI resets: ");
+
+	l = dsi_read_reg(DSI_PLL_STATUS);
+	printk("PLL (%d) ", FLD_GET(l, 0, 0));
+
+	l = dsi_read_reg(DSI_COMPLEXIO_CFG1);
+	printk("CIO (%d) ", FLD_GET(l, 29, 29));
+
+	l = dsi_read_reg(DSI_DSIPHY_CFG5);
+	printk("PHY (%x, %d, %d, %d)\n",
+			FLD_GET(l, 28, 26),
+			FLD_GET(l, 29, 29),
+			FLD_GET(l, 30, 30),
+			FLD_GET(l, 31, 31));
+}
+#else
+#define _dsi_print_reset_status()
+#endif
+
+static inline int dsi_if_enable(bool enable)
+{
+	DSSDBG("dsi_if_enable(%d)\n", enable);
+
+	enable = enable ? 1 : 0;
+	REG_FLD_MOD(DSI_CTRL, enable, 0, 0); /* IF_EN */
+
+	if (wait_for_bit_change(DSI_CTRL, 0, enable) != enable) {
+			DSSERR("Failed to set dsi_if_enable to %d\n", enable);
+			return -EIO;
+	}
+
+	return 0;
+}
+
+unsigned long dsi_get_dsi1_pll_rate(void)
+{
+	return dsi.current_cinfo.dsi1_pll_fclk;
+}
+
+static unsigned long dsi_get_dsi2_pll_rate(void)
+{
+	return dsi.current_cinfo.dsi2_pll_fclk;
+}
+
+static unsigned long dsi_get_txbyteclkhs(void)
+{
+	return dsi.current_cinfo.clkin4ddr / 16;
+}
+
+static unsigned long dsi_fclk_rate(void)
+{
+	unsigned long r;
+
+	if (dss_get_dsi_clk_source() == 0) {
+		/* DSI FCLK source is DSS1_ALWON_FCK, which is dss1_fck */
+		r = dss_clk_get_rate(DSS_CLK_FCK1);
+	} else {
+		/* DSI FCLK source is DSI2_PLL_FCLK */
+		r = dsi_get_dsi2_pll_rate();
+	}
+
+	return r;
+}
+
+static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev)
+{
+	unsigned long dsi_fclk;
+	unsigned lp_clk_div;
+	unsigned long lp_clk;
+
+	lp_clk_div = dssdev->phy.dsi.div.lp_clk_div;
+
+	if (lp_clk_div == 0 || lp_clk_div > LP_DIV_MAX)
+		return -EINVAL;
+
+	dsi_fclk = dsi_fclk_rate();
+
+	lp_clk = dsi_fclk / 2 / lp_clk_div;
+
+	DSSDBG("LP_CLK_DIV %u, LP_CLK %lu\n", lp_clk_div, lp_clk);
+	dsi.current_cinfo.lp_clk = lp_clk;
+	dsi.current_cinfo.lp_clk_div = lp_clk_div;
+
+	REG_FLD_MOD(DSI_CLK_CTRL, lp_clk_div, 12, 0);   /* LP_CLK_DIVISOR */
+
+	REG_FLD_MOD(DSI_CLK_CTRL, dsi_fclk > 30000000 ? 1 : 0,
+			21, 21);		/* LP_RX_SYNCHRO_ENABLE */
+
+	return 0;
+}
+
+
+enum dsi_pll_power_state {
+	DSI_PLL_POWER_OFF	= 0x0,
+	DSI_PLL_POWER_ON_HSCLK	= 0x1,
+	DSI_PLL_POWER_ON_ALL	= 0x2,
+	DSI_PLL_POWER_ON_DIV	= 0x3,
+};
+
+static int dsi_pll_power(enum dsi_pll_power_state state)
+{
+	int t = 0;
+
+	REG_FLD_MOD(DSI_CLK_CTRL, state, 31, 30);	/* PLL_PWR_CMD */
+
+	/* PLL_PWR_STATUS */
+	while (FLD_GET(dsi_read_reg(DSI_CLK_CTRL), 29, 28) != state) {
+		udelay(1);
+		if (t++ > 1000) {
+			DSSERR("Failed to set DSI PLL power mode to %d\n",
+					state);
+			return -ENODEV;
+		}
+	}
+
+	return 0;
+}
+
+/* calculate clock rates using dividers in cinfo */
+static int dsi_calc_clock_rates(struct dsi_clock_info *cinfo)
+{
+	if (cinfo->regn == 0 || cinfo->regn > REGN_MAX)
+		return -EINVAL;
+
+	if (cinfo->regm == 0 || cinfo->regm > REGM_MAX)
+		return -EINVAL;
+
+	if (cinfo->regm3 > REGM3_MAX)
+		return -EINVAL;
+
+	if (cinfo->regm4 > REGM4_MAX)
+		return -EINVAL;
+
+	if (cinfo->use_dss2_fck) {
+		cinfo->clkin = dss_clk_get_rate(DSS_CLK_FCK2);
+		/* XXX it is unclear if highfreq should be used
+		 * with DSS2_FCK source also */
+		cinfo->highfreq = 0;
+	} else {
+		cinfo->clkin = dispc_pclk_rate();
+
+		if (cinfo->clkin < 32000000)
+			cinfo->highfreq = 0;
+		else
+			cinfo->highfreq = 1;
+	}
+
+	cinfo->fint = cinfo->clkin / (cinfo->regn * (cinfo->highfreq ? 2 : 1));
+
+	if (cinfo->fint > FINT_MAX || cinfo->fint < FINT_MIN)
+		return -EINVAL;
+
+	cinfo->clkin4ddr = 2 * cinfo->regm * cinfo->fint;
+
+	if (cinfo->clkin4ddr > 1800 * 1000 * 1000)
+		return -EINVAL;
+
+	if (cinfo->regm3 > 0)
+		cinfo->dsi1_pll_fclk = cinfo->clkin4ddr / cinfo->regm3;
+	else
+		cinfo->dsi1_pll_fclk = 0;
+
+	if (cinfo->regm4 > 0)
+		cinfo->dsi2_pll_fclk = cinfo->clkin4ddr / cinfo->regm4;
+	else
+		cinfo->dsi2_pll_fclk = 0;
+
+	return 0;
+}
+
+int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck,
+		struct dsi_clock_info *dsi_cinfo,
+		struct dispc_clock_info *dispc_cinfo)
+{
+	struct dsi_clock_info cur, best;
+	struct dispc_clock_info best_dispc;
+	int min_fck_per_pck;
+	int match = 0;
+	unsigned long dss_clk_fck2;
+
+	dss_clk_fck2 = dss_clk_get_rate(DSS_CLK_FCK2);
+
+	if (req_pck == dsi.cache_req_pck &&
+			dsi.cache_cinfo.clkin == dss_clk_fck2) {
+		DSSDBG("DSI clock info found from cache\n");
+		*dsi_cinfo = dsi.cache_cinfo;
+		dispc_find_clk_divs(is_tft, req_pck, dsi_cinfo->dsi1_pll_fclk,
+				dispc_cinfo);
+		return 0;
+	}
+
+	min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
+
+	if (min_fck_per_pck &&
+		req_pck * min_fck_per_pck > DISPC_MAX_FCK) {
+		DSSERR("Requested pixel clock not possible with the current "
+				"OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning "
+				"the constraint off.\n");
+		min_fck_per_pck = 0;
+	}
+
+	DSSDBG("dsi_pll_calc\n");
+
+retry:
+	memset(&best, 0, sizeof(best));
+	memset(&best_dispc, 0, sizeof(best_dispc));
+
+	memset(&cur, 0, sizeof(cur));
+	cur.clkin = dss_clk_fck2;
+	cur.use_dss2_fck = 1;
+	cur.highfreq = 0;
+
+	/* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */
+	/* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */
+	/* To reduce PLL lock time, keep Fint high (around 2 MHz) */
+	for (cur.regn = 1; cur.regn < REGN_MAX; ++cur.regn) {
+		if (cur.highfreq == 0)
+			cur.fint = cur.clkin / cur.regn;
+		else
+			cur.fint = cur.clkin / (2 * cur.regn);
+
+		if (cur.fint > FINT_MAX || cur.fint < FINT_MIN)
+			continue;
+
+		/* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */
+		for (cur.regm = 1; cur.regm < REGM_MAX; ++cur.regm) {
+			unsigned long a, b;
+
+			a = 2 * cur.regm * (cur.clkin/1000);
+			b = cur.regn * (cur.highfreq + 1);
+			cur.clkin4ddr = a / b * 1000;
+
+			if (cur.clkin4ddr > 1800 * 1000 * 1000)
+				break;
+
+			/* DSI1_PLL_FCLK(MHz) = DSIPHY(MHz) / regm3  < 173MHz */
+			for (cur.regm3 = 1; cur.regm3 < REGM3_MAX;
+					++cur.regm3) {
+				struct dispc_clock_info cur_dispc;
+				cur.dsi1_pll_fclk = cur.clkin4ddr / cur.regm3;
+
+				/* this will narrow down the search a bit,
+				 * but still give pixclocks below what was
+				 * requested */
+				if (cur.dsi1_pll_fclk  < req_pck)
+					break;
+
+				if (cur.dsi1_pll_fclk > DISPC_MAX_FCK)
+					continue;
+
+				if (min_fck_per_pck &&
+					cur.dsi1_pll_fclk <
+						req_pck * min_fck_per_pck)
+					continue;
+
+				match = 1;
+
+				dispc_find_clk_divs(is_tft, req_pck,
+						cur.dsi1_pll_fclk,
+						&cur_dispc);
+
+				if (abs(cur_dispc.pck - req_pck) <
+						abs(best_dispc.pck - req_pck)) {
+					best = cur;
+					best_dispc = cur_dispc;
+
+					if (cur_dispc.pck == req_pck)
+						goto found;
+				}
+			}
+		}
+	}
+found:
+	if (!match) {
+		if (min_fck_per_pck) {
+			DSSERR("Could not find suitable clock settings.\n"
+					"Turning FCK/PCK constraint off and"
+					"trying again.\n");
+			min_fck_per_pck = 0;
+			goto retry;
+		}
+
+		DSSERR("Could not find suitable clock settings.\n");
+
+		return -EINVAL;
+	}
+
+	/* DSI2_PLL_FCLK (regm4) is not used */
+	best.regm4 = 0;
+	best.dsi2_pll_fclk = 0;
+
+	if (dsi_cinfo)
+		*dsi_cinfo = best;
+	if (dispc_cinfo)
+		*dispc_cinfo = best_dispc;
+
+	dsi.cache_req_pck = req_pck;
+	dsi.cache_clk_freq = 0;
+	dsi.cache_cinfo = best;
+
+	return 0;
+}
+
+int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
+{
+	int r = 0;
+	u32 l;
+	int f;
+
+	DSSDBGF();
+
+	dsi.current_cinfo.fint = cinfo->fint;
+	dsi.current_cinfo.clkin4ddr = cinfo->clkin4ddr;
+	dsi.current_cinfo.dsi1_pll_fclk = cinfo->dsi1_pll_fclk;
+	dsi.current_cinfo.dsi2_pll_fclk = cinfo->dsi2_pll_fclk;
+
+	dsi.current_cinfo.regn = cinfo->regn;
+	dsi.current_cinfo.regm = cinfo->regm;
+	dsi.current_cinfo.regm3 = cinfo->regm3;
+	dsi.current_cinfo.regm4 = cinfo->regm4;
+
+	DSSDBG("DSI Fint %ld\n", cinfo->fint);
+
+	DSSDBG("clkin (%s) rate %ld, highfreq %d\n",
+			cinfo->use_dss2_fck ? "dss2_fck" : "pclkfree",
+			cinfo->clkin,
+			cinfo->highfreq);
+
+	/* DSIPHY == CLKIN4DDR */
+	DSSDBG("CLKIN4DDR = 2 * %d / %d * %lu / %d = %lu\n",
+			cinfo->regm,
+			cinfo->regn,
+			cinfo->clkin,
+			cinfo->highfreq + 1,
+			cinfo->clkin4ddr);
+
+	DSSDBG("Data rate on 1 DSI lane %ld Mbps\n",
+			cinfo->clkin4ddr / 1000 / 1000 / 2);
+
+	DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkin4ddr / 4);
+
+	DSSDBG("regm3 = %d, dsi1_pll_fclk = %lu\n",
+			cinfo->regm3, cinfo->dsi1_pll_fclk);
+	DSSDBG("regm4 = %d, dsi2_pll_fclk = %lu\n",
+			cinfo->regm4, cinfo->dsi2_pll_fclk);
+
+	REG_FLD_MOD(DSI_PLL_CONTROL, 0, 0, 0); /* DSI_PLL_AUTOMODE = manual */
+
+	l = dsi_read_reg(DSI_PLL_CONFIGURATION1);
+	l = FLD_MOD(l, 1, 0, 0);		/* DSI_PLL_STOPMODE */
+	l = FLD_MOD(l, cinfo->regn - 1, 7, 1);	/* DSI_PLL_REGN */
+	l = FLD_MOD(l, cinfo->regm, 18, 8);	/* DSI_PLL_REGM */
+	l = FLD_MOD(l, cinfo->regm3 > 0 ? cinfo->regm3 - 1 : 0,
+			22, 19);		/* DSI_CLOCK_DIV */
+	l = FLD_MOD(l, cinfo->regm4 > 0 ? cinfo->regm4 - 1 : 0,
+			26, 23);		/* DSIPROTO_CLOCK_DIV */
+	dsi_write_reg(DSI_PLL_CONFIGURATION1, l);
+
+	BUG_ON(cinfo->fint < 750000 || cinfo->fint > 2100000);
+	if (cinfo->fint < 1000000)
+		f = 0x3;
+	else if (cinfo->fint < 1250000)
+		f = 0x4;
+	else if (cinfo->fint < 1500000)
+		f = 0x5;
+	else if (cinfo->fint < 1750000)
+		f = 0x6;
+	else
+		f = 0x7;
+
+	l = dsi_read_reg(DSI_PLL_CONFIGURATION2);
+	l = FLD_MOD(l, f, 4, 1);		/* DSI_PLL_FREQSEL */
+	l = FLD_MOD(l, cinfo->use_dss2_fck ? 0 : 1,
+			11, 11);		/* DSI_PLL_CLKSEL */
+	l = FLD_MOD(l, cinfo->highfreq,
+			12, 12);		/* DSI_PLL_HIGHFREQ */
+	l = FLD_MOD(l, 1, 13, 13);		/* DSI_PLL_REFEN */
+	l = FLD_MOD(l, 0, 14, 14);		/* DSIPHY_CLKINEN */
+	l = FLD_MOD(l, 1, 20, 20);		/* DSI_HSDIVBYPASS */
+	dsi_write_reg(DSI_PLL_CONFIGURATION2, l);
+
+	REG_FLD_MOD(DSI_PLL_GO, 1, 0, 0);	/* DSI_PLL_GO */
+
+	if (wait_for_bit_change(DSI_PLL_GO, 0, 0) != 0) {
+		DSSERR("dsi pll go bit not going down.\n");
+		r = -EIO;
+		goto err;
+	}
+
+	if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1) {
+		DSSERR("cannot lock PLL\n");
+		r = -EIO;
+		goto err;
+	}
+
+	dsi.pll_locked = 1;
+
+	l = dsi_read_reg(DSI_PLL_CONFIGURATION2);
+	l = FLD_MOD(l, 0, 0, 0);	/* DSI_PLL_IDLE */
+	l = FLD_MOD(l, 0, 5, 5);	/* DSI_PLL_PLLLPMODE */
+	l = FLD_MOD(l, 0, 6, 6);	/* DSI_PLL_LOWCURRSTBY */
+	l = FLD_MOD(l, 0, 7, 7);	/* DSI_PLL_TIGHTPHASELOCK */
+	l = FLD_MOD(l, 0, 8, 8);	/* DSI_PLL_DRIFTGUARDEN */
+	l = FLD_MOD(l, 0, 10, 9);	/* DSI_PLL_LOCKSEL */
+	l = FLD_MOD(l, 1, 13, 13);	/* DSI_PLL_REFEN */
+	l = FLD_MOD(l, 1, 14, 14);	/* DSIPHY_CLKINEN */
+	l = FLD_MOD(l, 0, 15, 15);	/* DSI_BYPASSEN */
+	l = FLD_MOD(l, 1, 16, 16);	/* DSS_CLOCK_EN */
+	l = FLD_MOD(l, 0, 17, 17);	/* DSS_CLOCK_PWDN */
+	l = FLD_MOD(l, 1, 18, 18);	/* DSI_PROTO_CLOCK_EN */
+	l = FLD_MOD(l, 0, 19, 19);	/* DSI_PROTO_CLOCK_PWDN */
+	l = FLD_MOD(l, 0, 20, 20);	/* DSI_HSDIVBYPASS */
+	dsi_write_reg(DSI_PLL_CONFIGURATION2, l);
+
+	DSSDBG("PLL config done\n");
+err:
+	return r;
+}
+
+int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk,
+		bool enable_hsdiv)
+{
+	int r = 0;
+	enum dsi_pll_power_state pwstate;
+
+	DSSDBG("PLL init\n");
+
+	enable_clocks(1);
+	dsi_enable_pll_clock(1);
+
+	r = regulator_enable(dsi.vdds_dsi_reg);
+	if (r)
+		goto err0;
+
+	/* XXX PLL does not come out of reset without this... */
+	dispc_pck_free_enable(1);
+
+	if (wait_for_bit_change(DSI_PLL_STATUS, 0, 1) != 1) {
+		DSSERR("PLL not coming out of reset.\n");
+		r = -ENODEV;
+		goto err1;
+	}
+
+	/* XXX ... but if left on, we get problems when planes do not
+	 * fill the whole display. No idea about this */
+	dispc_pck_free_enable(0);
+
+	if (enable_hsclk && enable_hsdiv)
+		pwstate = DSI_PLL_POWER_ON_ALL;
+	else if (enable_hsclk)
+		pwstate = DSI_PLL_POWER_ON_HSCLK;
+	else if (enable_hsdiv)
+		pwstate = DSI_PLL_POWER_ON_DIV;
+	else
+		pwstate = DSI_PLL_POWER_OFF;
+
+	r = dsi_pll_power(pwstate);
+
+	if (r)
+		goto err1;
+
+	DSSDBG("PLL init done\n");
+
+	return 0;
+err1:
+	regulator_disable(dsi.vdds_dsi_reg);
+err0:
+	enable_clocks(0);
+	dsi_enable_pll_clock(0);
+	return r;
+}
+
+void dsi_pll_uninit(void)
+{
+	enable_clocks(0);
+	dsi_enable_pll_clock(0);
+
+	dsi.pll_locked = 0;
+	dsi_pll_power(DSI_PLL_POWER_OFF);
+	regulator_disable(dsi.vdds_dsi_reg);
+	DSSDBG("PLL uninit done\n");
+}
+
+void dsi_dump_clocks(struct seq_file *s)
+{
+	int clksel;
+	struct dsi_clock_info *cinfo = &dsi.current_cinfo;
+
+	enable_clocks(1);
+
+	clksel = REG_GET(DSI_PLL_CONFIGURATION2, 11, 11);
+
+	seq_printf(s,	"- DSI PLL -\n");
+
+	seq_printf(s,	"dsi pll source = %s\n",
+			clksel == 0 ?
+			"dss2_alwon_fclk" : "pclkfree");
+
+	seq_printf(s,	"Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn);
+
+	seq_printf(s,	"CLKIN4DDR\t%-16luregm %u\n",
+			cinfo->clkin4ddr, cinfo->regm);
+
+	seq_printf(s,	"dsi1_pll_fck\t%-16luregm3 %u\t(%s)\n",
+			cinfo->dsi1_pll_fclk,
+			cinfo->regm3,
+			dss_get_dispc_clk_source() == 0 ? "off" : "on");
+
+	seq_printf(s,	"dsi2_pll_fck\t%-16luregm4 %u\t(%s)\n",
+			cinfo->dsi2_pll_fclk,
+			cinfo->regm4,
+			dss_get_dsi_clk_source() == 0 ? "off" : "on");
+
+	seq_printf(s,	"- DSI -\n");
+
+	seq_printf(s,	"dsi fclk source = %s\n",
+			dss_get_dsi_clk_source() == 0 ?
+			"dss1_alwon_fclk" : "dsi2_pll_fclk");
+
+	seq_printf(s,	"DSI_FCLK\t%lu\n", dsi_fclk_rate());
+
+	seq_printf(s,	"DDR_CLK\t\t%lu\n",
+			cinfo->clkin4ddr / 4);
+
+	seq_printf(s,	"TxByteClkHS\t%lu\n", dsi_get_txbyteclkhs());
+
+	seq_printf(s,	"LP_CLK\t\t%lu\n", cinfo->lp_clk);
+
+	seq_printf(s,	"VP_CLK\t\t%lu\n"
+			"VP_PCLK\t\t%lu\n",
+			dispc_lclk_rate(),
+			dispc_pclk_rate());
+
+	enable_clocks(0);
+}
+
+void dsi_dump_regs(struct seq_file *s)
+{
+#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r))
+
+	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+
+	DUMPREG(DSI_REVISION);
+	DUMPREG(DSI_SYSCONFIG);
+	DUMPREG(DSI_SYSSTATUS);
+	DUMPREG(DSI_IRQSTATUS);
+	DUMPREG(DSI_IRQENABLE);
+	DUMPREG(DSI_CTRL);
+	DUMPREG(DSI_COMPLEXIO_CFG1);
+	DUMPREG(DSI_COMPLEXIO_IRQ_STATUS);
+	DUMPREG(DSI_COMPLEXIO_IRQ_ENABLE);
+	DUMPREG(DSI_CLK_CTRL);
+	DUMPREG(DSI_TIMING1);
+	DUMPREG(DSI_TIMING2);
+	DUMPREG(DSI_VM_TIMING1);
+	DUMPREG(DSI_VM_TIMING2);
+	DUMPREG(DSI_VM_TIMING3);
+	DUMPREG(DSI_CLK_TIMING);
+	DUMPREG(DSI_TX_FIFO_VC_SIZE);
+	DUMPREG(DSI_RX_FIFO_VC_SIZE);
+	DUMPREG(DSI_COMPLEXIO_CFG2);
+	DUMPREG(DSI_RX_FIFO_VC_FULLNESS);
+	DUMPREG(DSI_VM_TIMING4);
+	DUMPREG(DSI_TX_FIFO_VC_EMPTINESS);
+	DUMPREG(DSI_VM_TIMING5);
+	DUMPREG(DSI_VM_TIMING6);
+	DUMPREG(DSI_VM_TIMING7);
+	DUMPREG(DSI_STOPCLK_TIMING);
+
+	DUMPREG(DSI_VC_CTRL(0));
+	DUMPREG(DSI_VC_TE(0));
+	DUMPREG(DSI_VC_LONG_PACKET_HEADER(0));
+	DUMPREG(DSI_VC_LONG_PACKET_PAYLOAD(0));
+	DUMPREG(DSI_VC_SHORT_PACKET_HEADER(0));
+	DUMPREG(DSI_VC_IRQSTATUS(0));
+	DUMPREG(DSI_VC_IRQENABLE(0));
+
+	DUMPREG(DSI_VC_CTRL(1));
+	DUMPREG(DSI_VC_TE(1));
+	DUMPREG(DSI_VC_LONG_PACKET_HEADER(1));
+	DUMPREG(DSI_VC_LONG_PACKET_PAYLOAD(1));
+	DUMPREG(DSI_VC_SHORT_PACKET_HEADER(1));
+	DUMPREG(DSI_VC_IRQSTATUS(1));
+	DUMPREG(DSI_VC_IRQENABLE(1));
+
+	DUMPREG(DSI_VC_CTRL(2));
+	DUMPREG(DSI_VC_TE(2));
+	DUMPREG(DSI_VC_LONG_PACKET_HEADER(2));
+	DUMPREG(DSI_VC_LONG_PACKET_PAYLOAD(2));
+	DUMPREG(DSI_VC_SHORT_PACKET_HEADER(2));
+	DUMPREG(DSI_VC_IRQSTATUS(2));
+	DUMPREG(DSI_VC_IRQENABLE(2));
+
+	DUMPREG(DSI_VC_CTRL(3));
+	DUMPREG(DSI_VC_TE(3));
+	DUMPREG(DSI_VC_LONG_PACKET_HEADER(3));
+	DUMPREG(DSI_VC_LONG_PACKET_PAYLOAD(3));
+	DUMPREG(DSI_VC_SHORT_PACKET_HEADER(3));
+	DUMPREG(DSI_VC_IRQSTATUS(3));
+	DUMPREG(DSI_VC_IRQENABLE(3));
+
+	DUMPREG(DSI_DSIPHY_CFG0);
+	DUMPREG(DSI_DSIPHY_CFG1);
+	DUMPREG(DSI_DSIPHY_CFG2);
+	DUMPREG(DSI_DSIPHY_CFG5);
+
+	DUMPREG(DSI_PLL_CONTROL);
+	DUMPREG(DSI_PLL_STATUS);
+	DUMPREG(DSI_PLL_GO);
+	DUMPREG(DSI_PLL_CONFIGURATION1);
+	DUMPREG(DSI_PLL_CONFIGURATION2);
+
+	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+#undef DUMPREG
+}
+
+enum dsi_complexio_power_state {
+	DSI_COMPLEXIO_POWER_OFF		= 0x0,
+	DSI_COMPLEXIO_POWER_ON		= 0x1,
+	DSI_COMPLEXIO_POWER_ULPS	= 0x2,
+};
+
+static int dsi_complexio_power(enum dsi_complexio_power_state state)
+{
+	int t = 0;
+
+	/* PWR_CMD */
+	REG_FLD_MOD(DSI_COMPLEXIO_CFG1, state, 28, 27);
+
+	/* PWR_STATUS */
+	while (FLD_GET(dsi_read_reg(DSI_COMPLEXIO_CFG1), 26, 25) != state) {
+		udelay(1);
+		if (t++ > 1000) {
+			DSSERR("failed to set complexio power state to "
+					"%d\n", state);
+			return -ENODEV;
+		}
+	}
+
+	return 0;
+}
+
+static void dsi_complexio_config(struct omap_dss_device *dssdev)
+{
+	u32 r;
+
+	int clk_lane   = dssdev->phy.dsi.clk_lane;
+	int data1_lane = dssdev->phy.dsi.data1_lane;
+	int data2_lane = dssdev->phy.dsi.data2_lane;
+	int clk_pol    = dssdev->phy.dsi.clk_pol;
+	int data1_pol  = dssdev->phy.dsi.data1_pol;
+	int data2_pol  = dssdev->phy.dsi.data2_pol;
+
+	r = dsi_read_reg(DSI_COMPLEXIO_CFG1);
+	r = FLD_MOD(r, clk_lane, 2, 0);
+	r = FLD_MOD(r, clk_pol, 3, 3);
+	r = FLD_MOD(r, data1_lane, 6, 4);
+	r = FLD_MOD(r, data1_pol, 7, 7);
+	r = FLD_MOD(r, data2_lane, 10, 8);
+	r = FLD_MOD(r, data2_pol, 11, 11);
+	dsi_write_reg(DSI_COMPLEXIO_CFG1, r);
+
+	/* The configuration of the DSI complex I/O (number of data lanes,
+	   position, differential order) should not be changed while
+	   DSS.DSI_CLK_CRTRL[20] LP_CLK_ENABLE bit is set to 1. In order for
+	   the hardware to take into account a new configuration of the complex
+	   I/O (done in DSS.DSI_COMPLEXIO_CFG1 register), it is recommended to
+	   follow this sequence: First set the DSS.DSI_CTRL[0] IF_EN bit to 1,
+	   then reset the DSS.DSI_CTRL[0] IF_EN to 0, then set
+	   DSS.DSI_CLK_CTRL[20] LP_CLK_ENABLE to 1 and finally set again the
+	   DSS.DSI_CTRL[0] IF_EN bit to 1. If the sequence is not followed, the
+	   DSI complex I/O configuration is unknown. */
+
+	/*
+	REG_FLD_MOD(DSI_CTRL, 1, 0, 0);
+	REG_FLD_MOD(DSI_CTRL, 0, 0, 0);
+	REG_FLD_MOD(DSI_CLK_CTRL, 1, 20, 20);
+	REG_FLD_MOD(DSI_CTRL, 1, 0, 0);
+	*/
+}
+
+static inline unsigned ns2ddr(unsigned ns)
+{
+	/* convert time in ns to ddr ticks, rounding up */
+	unsigned long ddr_clk = dsi.current_cinfo.clkin4ddr / 4;
+	return (ns * (ddr_clk / 1000 / 1000) + 999) / 1000;
+}
+
+static inline unsigned ddr2ns(unsigned ddr)
+{
+	unsigned long ddr_clk = dsi.current_cinfo.clkin4ddr / 4;
+	return ddr * 1000 * 1000 / (ddr_clk / 1000);
+}
+
+static void dsi_complexio_timings(void)
+{
+	u32 r;
+	u32 ths_prepare, ths_prepare_ths_zero, ths_trail, ths_exit;
+	u32 tlpx_half, tclk_trail, tclk_zero;
+	u32 tclk_prepare;
+
+	/* calculate timings */
+
+	/* 1 * DDR_CLK = 2 * UI */
+
+	/* min 40ns + 4*UI	max 85ns + 6*UI */
+	ths_prepare = ns2ddr(70) + 2;
+
+	/* min 145ns + 10*UI */
+	ths_prepare_ths_zero = ns2ddr(175) + 2;
+
+	/* min max(8*UI, 60ns+4*UI) */
+	ths_trail = ns2ddr(60) + 5;
+
+	/* min 100ns */
+	ths_exit = ns2ddr(145);
+
+	/* tlpx min 50n */
+	tlpx_half = ns2ddr(25);
+
+	/* min 60ns */
+	tclk_trail = ns2ddr(60) + 2;
+
+	/* min 38ns, max 95ns */
+	tclk_prepare = ns2ddr(65);
+
+	/* min tclk-prepare + tclk-zero = 300ns */
+	tclk_zero = ns2ddr(260);
+
+	DSSDBG("ths_prepare %u (%uns), ths_prepare_ths_zero %u (%uns)\n",
+		ths_prepare, ddr2ns(ths_prepare),
+		ths_prepare_ths_zero, ddr2ns(ths_prepare_ths_zero));
+	DSSDBG("ths_trail %u (%uns), ths_exit %u (%uns)\n",
+			ths_trail, ddr2ns(ths_trail),
+			ths_exit, ddr2ns(ths_exit));
+
+	DSSDBG("tlpx_half %u (%uns), tclk_trail %u (%uns), "
+			"tclk_zero %u (%uns)\n",
+			tlpx_half, ddr2ns(tlpx_half),
+			tclk_trail, ddr2ns(tclk_trail),
+			tclk_zero, ddr2ns(tclk_zero));
+	DSSDBG("tclk_prepare %u (%uns)\n",
+			tclk_prepare, ddr2ns(tclk_prepare));
+
+	/* program timings */
+
+	r = dsi_read_reg(DSI_DSIPHY_CFG0);
+	r = FLD_MOD(r, ths_prepare, 31, 24);
+	r = FLD_MOD(r, ths_prepare_ths_zero, 23, 16);
+	r = FLD_MOD(r, ths_trail, 15, 8);
+	r = FLD_MOD(r, ths_exit, 7, 0);
+	dsi_write_reg(DSI_DSIPHY_CFG0, r);
+
+	r = dsi_read_reg(DSI_DSIPHY_CFG1);
+	r = FLD_MOD(r, tlpx_half, 22, 16);
+	r = FLD_MOD(r, tclk_trail, 15, 8);
+	r = FLD_MOD(r, tclk_zero, 7, 0);
+	dsi_write_reg(DSI_DSIPHY_CFG1, r);
+
+	r = dsi_read_reg(DSI_DSIPHY_CFG2);
+	r = FLD_MOD(r, tclk_prepare, 7, 0);
+	dsi_write_reg(DSI_DSIPHY_CFG2, r);
+}
+
+
+static int dsi_complexio_init(struct omap_dss_device *dssdev)
+{
+	int r = 0;
+
+	DSSDBG("dsi_complexio_init\n");
+
+	/* CIO_CLK_ICG, enable L3 clk to CIO */
+	REG_FLD_MOD(DSI_CLK_CTRL, 1, 14, 14);
+
+	/* A dummy read using the SCP interface to any DSIPHY register is
+	 * required after DSIPHY reset to complete the reset of the DSI complex
+	 * I/O. */
+	dsi_read_reg(DSI_DSIPHY_CFG5);
+
+	if (wait_for_bit_change(DSI_DSIPHY_CFG5, 30, 1) != 1) {
+		DSSERR("ComplexIO PHY not coming out of reset.\n");
+		r = -ENODEV;
+		goto err;
+	}
+
+	dsi_complexio_config(dssdev);
+
+	r = dsi_complexio_power(DSI_COMPLEXIO_POWER_ON);
+
+	if (r)
+		goto err;
+
+	if (wait_for_bit_change(DSI_COMPLEXIO_CFG1, 29, 1) != 1) {
+		DSSERR("ComplexIO not coming out of reset.\n");
+		r = -ENODEV;
+		goto err;
+	}
+
+	if (wait_for_bit_change(DSI_COMPLEXIO_CFG1, 21, 1) != 1) {
+		DSSERR("ComplexIO LDO power down.\n");
+		r = -ENODEV;
+		goto err;
+	}
+
+	dsi_complexio_timings();
+
+	/*
+	   The configuration of the DSI complex I/O (number of data lanes,
+	   position, differential order) should not be changed while
+	   DSS.DSI_CLK_CRTRL[20] LP_CLK_ENABLE bit is set to 1. For the
+	   hardware to recognize a new configuration of the complex I/O (done
+	   in DSS.DSI_COMPLEXIO_CFG1 register), it is recommended to follow
+	   this sequence: First set the DSS.DSI_CTRL[0] IF_EN bit to 1, next
+	   reset the DSS.DSI_CTRL[0] IF_EN to 0, then set DSS.DSI_CLK_CTRL[20]
+	   LP_CLK_ENABLE to 1, and finally, set again the DSS.DSI_CTRL[0] IF_EN
+	   bit to 1. If the sequence is not followed, the DSi complex I/O
+	   configuration is undetermined.
+	   */
+	dsi_if_enable(1);
+	dsi_if_enable(0);
+	REG_FLD_MOD(DSI_CLK_CTRL, 1, 20, 20); /* LP_CLK_ENABLE */
+	dsi_if_enable(1);
+	dsi_if_enable(0);
+
+	DSSDBG("CIO init done\n");
+err:
+	return r;
+}
+
+static void dsi_complexio_uninit(void)
+{
+	dsi_complexio_power(DSI_COMPLEXIO_POWER_OFF);
+}
+
+static int _dsi_wait_reset(void)
+{
+	int i = 0;
+
+	while (REG_GET(DSI_SYSSTATUS, 0, 0) == 0) {
+		if (i++ > 5) {
+			DSSERR("soft reset failed\n");
+			return -ENODEV;
+		}
+		udelay(1);
+	}
+
+	return 0;
+}
+
+static int _dsi_reset(void)
+{
+	/* Soft reset */
+	REG_FLD_MOD(DSI_SYSCONFIG, 1, 1, 1);
+	return _dsi_wait_reset();
+}
+
+static void dsi_reset_tx_fifo(int channel)
+{
+	u32 mask;
+	u32 l;
+
+	/* set fifosize of the channel to 0, then return the old size */
+	l = dsi_read_reg(DSI_TX_FIFO_VC_SIZE);
+
+	mask = FLD_MASK((8 * channel) + 7, (8 * channel) + 4);
+	dsi_write_reg(DSI_TX_FIFO_VC_SIZE, l & ~mask);
+
+	dsi_write_reg(DSI_TX_FIFO_VC_SIZE, l);
+}
+
+static void dsi_config_tx_fifo(enum fifo_size size1, enum fifo_size size2,
+		enum fifo_size size3, enum fifo_size size4)
+{
+	u32 r = 0;
+	int add = 0;
+	int i;
+
+	dsi.vc[0].fifo_size = size1;
+	dsi.vc[1].fifo_size = size2;
+	dsi.vc[2].fifo_size = size3;
+	dsi.vc[3].fifo_size = size4;
+
+	for (i = 0; i < 4; i++) {
+		u8 v;
+		int size = dsi.vc[i].fifo_size;
+
+		if (add + size > 4) {
+			DSSERR("Illegal FIFO configuration\n");
+			BUG();
+		}
+
+		v = FLD_VAL(add, 2, 0) | FLD_VAL(size, 7, 4);
+		r |= v << (8 * i);
+		/*DSSDBG("TX FIFO vc %d: size %d, add %d\n", i, size, add); */
+		add += size;
+	}
+
+	dsi_write_reg(DSI_TX_FIFO_VC_SIZE, r);
+}
+
+static void dsi_config_rx_fifo(enum fifo_size size1, enum fifo_size size2,
+		enum fifo_size size3, enum fifo_size size4)
+{
+	u32 r = 0;
+	int add = 0;
+	int i;
+
+	dsi.vc[0].fifo_size = size1;
+	dsi.vc[1].fifo_size = size2;
+	dsi.vc[2].fifo_size = size3;
+	dsi.vc[3].fifo_size = size4;
+
+	for (i = 0; i < 4; i++) {
+		u8 v;
+		int size = dsi.vc[i].fifo_size;
+
+		if (add + size > 4) {
+			DSSERR("Illegal FIFO configuration\n");
+			BUG();
+		}
+
+		v = FLD_VAL(add, 2, 0) | FLD_VAL(size, 7, 4);
+		r |= v << (8 * i);
+		/*DSSDBG("RX FIFO vc %d: size %d, add %d\n", i, size, add); */
+		add += size;
+	}
+
+	dsi_write_reg(DSI_RX_FIFO_VC_SIZE, r);
+}
+
+static int dsi_force_tx_stop_mode_io(void)
+{
+	u32 r;
+
+	r = dsi_read_reg(DSI_TIMING1);
+	r = FLD_MOD(r, 1, 15, 15);	/* FORCE_TX_STOP_MODE_IO */
+	dsi_write_reg(DSI_TIMING1, r);
+
+	if (wait_for_bit_change(DSI_TIMING1, 15, 0) != 0) {
+		DSSERR("TX_STOP bit not going down\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static void dsi_vc_print_status(int channel)
+{
+	u32 r;
+
+	r = dsi_read_reg(DSI_VC_CTRL(channel));
+	DSSDBG("vc %d: TX_FIFO_NOT_EMPTY %d, BTA_EN %d, VC_BUSY %d, "
+			"TX_FIFO_FULL %d, RX_FIFO_NOT_EMPTY %d, ",
+			channel,
+			FLD_GET(r, 5, 5),
+			FLD_GET(r, 6, 6),
+			FLD_GET(r, 15, 15),
+			FLD_GET(r, 16, 16),
+			FLD_GET(r, 20, 20));
+
+	r = dsi_read_reg(DSI_TX_FIFO_VC_EMPTINESS);
+	DSSDBG("EMPTINESS %d\n", (r >> (8 * channel)) & 0xff);
+}
+
+static int dsi_vc_enable(int channel, bool enable)
+{
+	if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO)
+		DSSDBG("dsi_vc_enable channel %d, enable %d\n",
+				channel, enable);
+
+	enable = enable ? 1 : 0;
+
+	REG_FLD_MOD(DSI_VC_CTRL(channel), enable, 0, 0);
+
+	if (wait_for_bit_change(DSI_VC_CTRL(channel), 0, enable) != enable) {
+			DSSERR("Failed to set dsi_vc_enable to %d\n", enable);
+			return -EIO;
+	}
+
+	return 0;
+}
+
+static void dsi_vc_initial_config(int channel)
+{
+	u32 r;
+
+	DSSDBGF("%d", channel);
+
+	r = dsi_read_reg(DSI_VC_CTRL(channel));
+
+	if (FLD_GET(r, 15, 15)) /* VC_BUSY */
+		DSSERR("VC(%d) busy when trying to configure it!\n",
+				channel);
+
+	r = FLD_MOD(r, 0, 1, 1); /* SOURCE, 0 = L4 */
+	r = FLD_MOD(r, 0, 2, 2); /* BTA_SHORT_EN  */
+	r = FLD_MOD(r, 0, 3, 3); /* BTA_LONG_EN */
+	r = FLD_MOD(r, 0, 4, 4); /* MODE, 0 = command */
+	r = FLD_MOD(r, 1, 7, 7); /* CS_TX_EN */
+	r = FLD_MOD(r, 1, 8, 8); /* ECC_TX_EN */
+	r = FLD_MOD(r, 0, 9, 9); /* MODE_SPEED, high speed on/off */
+
+	r = FLD_MOD(r, 4, 29, 27); /* DMA_RX_REQ_NB = no dma */
+	r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */
+
+	dsi_write_reg(DSI_VC_CTRL(channel), r);
+
+	dsi.vc[channel].mode = DSI_VC_MODE_L4;
+}
+
+static void dsi_vc_config_l4(int channel)
+{
+	if (dsi.vc[channel].mode == DSI_VC_MODE_L4)
+		return;
+
+	DSSDBGF("%d", channel);
+
+	dsi_vc_enable(channel, 0);
+
+	if (REG_GET(DSI_VC_CTRL(channel), 15, 15)) /* VC_BUSY */
+		DSSERR("vc(%d) busy when trying to config for L4\n", channel);
+
+	REG_FLD_MOD(DSI_VC_CTRL(channel), 0, 1, 1); /* SOURCE, 0 = L4 */
+
+	dsi_vc_enable(channel, 1);
+
+	dsi.vc[channel].mode = DSI_VC_MODE_L4;
+}
+
+static void dsi_vc_config_vp(int channel)
+{
+	if (dsi.vc[channel].mode == DSI_VC_MODE_VP)
+		return;
+
+	DSSDBGF("%d", channel);
+
+	dsi_vc_enable(channel, 0);
+
+	if (REG_GET(DSI_VC_CTRL(channel), 15, 15)) /* VC_BUSY */
+		DSSERR("vc(%d) busy when trying to config for VP\n", channel);
+
+	REG_FLD_MOD(DSI_VC_CTRL(channel), 1, 1, 1); /* SOURCE, 1 = video port */
+
+	dsi_vc_enable(channel, 1);
+
+	dsi.vc[channel].mode = DSI_VC_MODE_VP;
+}
+
+
+static void dsi_vc_enable_hs(int channel, bool enable)
+{
+	DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable);
+
+	dsi_vc_enable(channel, 0);
+	dsi_if_enable(0);
+
+	REG_FLD_MOD(DSI_VC_CTRL(channel), enable, 9, 9);
+
+	dsi_vc_enable(channel, 1);
+	dsi_if_enable(1);
+
+	dsi_force_tx_stop_mode_io();
+}
+
+static void dsi_vc_flush_long_data(int channel)
+{
+	while (REG_GET(DSI_VC_CTRL(channel), 20, 20)) {
+		u32 val;
+		val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel));
+		DSSDBG("\t\tb1 %#02x b2 %#02x b3 %#02x b4 %#02x\n",
+				(val >> 0) & 0xff,
+				(val >> 8) & 0xff,
+				(val >> 16) & 0xff,
+				(val >> 24) & 0xff);
+	}
+}
+
+static void dsi_show_rx_ack_with_err(u16 err)
+{
+	DSSERR("\tACK with ERROR (%#x):\n", err);
+	if (err & (1 << 0))
+		DSSERR("\t\tSoT Error\n");
+	if (err & (1 << 1))
+		DSSERR("\t\tSoT Sync Error\n");
+	if (err & (1 << 2))
+		DSSERR("\t\tEoT Sync Error\n");
+	if (err & (1 << 3))
+		DSSERR("\t\tEscape Mode Entry Command Error\n");
+	if (err & (1 << 4))
+		DSSERR("\t\tLP Transmit Sync Error\n");
+	if (err & (1 << 5))
+		DSSERR("\t\tHS Receive Timeout Error\n");
+	if (err & (1 << 6))
+		DSSERR("\t\tFalse Control Error\n");
+	if (err & (1 << 7))
+		DSSERR("\t\t(reserved7)\n");
+	if (err & (1 << 8))
+		DSSERR("\t\tECC Error, single-bit (corrected)\n");
+	if (err & (1 << 9))
+		DSSERR("\t\tECC Error, multi-bit (not corrected)\n");
+	if (err & (1 << 10))
+		DSSERR("\t\tChecksum Error\n");
+	if (err & (1 << 11))
+		DSSERR("\t\tData type not recognized\n");
+	if (err & (1 << 12))
+		DSSERR("\t\tInvalid VC ID\n");
+	if (err & (1 << 13))
+		DSSERR("\t\tInvalid Transmission Length\n");
+	if (err & (1 << 14))
+		DSSERR("\t\t(reserved14)\n");
+	if (err & (1 << 15))
+		DSSERR("\t\tDSI Protocol Violation\n");
+}
+
+static u16 dsi_vc_flush_receive_data(int channel)
+{
+	/* RX_FIFO_NOT_EMPTY */
+	while (REG_GET(DSI_VC_CTRL(channel), 20, 20)) {
+		u32 val;
+		u8 dt;
+		val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel));
+		DSSDBG("\trawval %#08x\n", val);
+		dt = FLD_GET(val, 5, 0);
+		if (dt == DSI_DT_RX_ACK_WITH_ERR) {
+			u16 err = FLD_GET(val, 23, 8);
+			dsi_show_rx_ack_with_err(err);
+		} else if (dt == DSI_DT_RX_SHORT_READ_1) {
+			DSSDBG("\tDCS short response, 1 byte: %#x\n",
+					FLD_GET(val, 23, 8));
+		} else if (dt == DSI_DT_RX_SHORT_READ_2) {
+			DSSDBG("\tDCS short response, 2 byte: %#x\n",
+					FLD_GET(val, 23, 8));
+		} else if (dt == DSI_DT_RX_DCS_LONG_READ) {
+			DSSDBG("\tDCS long response, len %d\n",
+					FLD_GET(val, 23, 8));
+			dsi_vc_flush_long_data(channel);
+		} else {
+			DSSERR("\tunknown datatype 0x%02x\n", dt);
+		}
+	}
+	return 0;
+}
+
+static int dsi_vc_send_bta(int channel)
+{
+	if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO &&
+			(dsi.debug_write || dsi.debug_read))
+		DSSDBG("dsi_vc_send_bta %d\n", channel);
+
+	WARN_ON(!mutex_is_locked(&dsi.bus_lock));
+
+	if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) {	/* RX_FIFO_NOT_EMPTY */
+		DSSERR("rx fifo not empty when sending BTA, dumping data:\n");
+		dsi_vc_flush_receive_data(channel);
+	}
+
+	REG_FLD_MOD(DSI_VC_CTRL(channel), 1, 6, 6); /* BTA_EN */
+
+	return 0;
+}
+
+int dsi_vc_send_bta_sync(int channel)
+{
+	int r = 0;
+	u32 err;
+
+	INIT_COMPLETION(dsi.bta_completion);
+
+	dsi_vc_enable_bta_irq(channel);
+
+	r = dsi_vc_send_bta(channel);
+	if (r)
+		goto err;
+
+	if (wait_for_completion_timeout(&dsi.bta_completion,
+				msecs_to_jiffies(500)) == 0) {
+		DSSERR("Failed to receive BTA\n");
+		r = -EIO;
+		goto err;
+	}
+
+	err = dsi_get_errors();
+	if (err) {
+		DSSERR("Error while sending BTA: %x\n", err);
+		r = -EIO;
+		goto err;
+	}
+err:
+	dsi_vc_disable_bta_irq(channel);
+
+	return r;
+}
+EXPORT_SYMBOL(dsi_vc_send_bta_sync);
+
+static inline void dsi_vc_write_long_header(int channel, u8 data_type,
+		u16 len, u8 ecc)
+{
+	u32 val;
+	u8 data_id;
+
+	WARN_ON(!mutex_is_locked(&dsi.bus_lock));
+
+	/*data_id = data_type | channel << 6; */
+	data_id = data_type | dsi.vc[channel].dest_per << 6;
+
+	val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) |
+		FLD_VAL(ecc, 31, 24);
+
+	dsi_write_reg(DSI_VC_LONG_PACKET_HEADER(channel), val);
+}
+
+static inline void dsi_vc_write_long_payload(int channel,
+		u8 b1, u8 b2, u8 b3, u8 b4)
+{
+	u32 val;
+
+	val = b4 << 24 | b3 << 16 | b2 << 8  | b1 << 0;
+
+/*	DSSDBG("\twriting %02x, %02x, %02x, %02x (%#010x)\n",
+			b1, b2, b3, b4, val); */
+
+	dsi_write_reg(DSI_VC_LONG_PACKET_PAYLOAD(channel), val);
+}
+
+static int dsi_vc_send_long(int channel, u8 data_type, u8 *data, u16 len,
+		u8 ecc)
+{
+	/*u32 val; */
+	int i;
+	u8 *p;
+	int r = 0;
+	u8 b1, b2, b3, b4;
+
+	if (dsi.debug_write)
+		DSSDBG("dsi_vc_send_long, %d bytes\n", len);
+
+	/* len + header */
+	if (dsi.vc[channel].fifo_size * 32 * 4 < len + 4) {
+		DSSERR("unable to send long packet: packet too long.\n");
+		return -EINVAL;
+	}
+
+	dsi_vc_config_l4(channel);
+
+	dsi_vc_write_long_header(channel, data_type, len, ecc);
+
+	/*dsi_vc_print_status(0); */
+
+	p = data;
+	for (i = 0; i < len >> 2; i++) {
+		if (dsi.debug_write)
+			DSSDBG("\tsending full packet %d\n", i);
+		/*dsi_vc_print_status(0); */
+
+		b1 = *p++;
+		b2 = *p++;
+		b3 = *p++;
+		b4 = *p++;
+
+		dsi_vc_write_long_payload(channel, b1, b2, b3, b4);
+	}
+
+	i = len % 4;
+	if (i) {
+		b1 = 0; b2 = 0; b3 = 0;
+
+		if (dsi.debug_write)
+			DSSDBG("\tsending remainder bytes %d\n", i);
+
+		switch (i) {
+		case 3:
+			b1 = *p++;
+			b2 = *p++;
+			b3 = *p++;
+			break;
+		case 2:
+			b1 = *p++;
+			b2 = *p++;
+			break;
+		case 1:
+			b1 = *p++;
+			break;
+		}
+
+		dsi_vc_write_long_payload(channel, b1, b2, b3, 0);
+	}
+
+	return r;
+}
+
+static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc)
+{
+	u32 r;
+	u8 data_id;
+
+	WARN_ON(!mutex_is_locked(&dsi.bus_lock));
+
+	if (dsi.debug_write)
+		DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n",
+				channel,
+				data_type, data & 0xff, (data >> 8) & 0xff);
+
+	dsi_vc_config_l4(channel);
+
+	if (FLD_GET(dsi_read_reg(DSI_VC_CTRL(channel)), 16, 16)) {
+		DSSERR("ERROR FIFO FULL, aborting transfer\n");
+		return -EINVAL;
+	}
+
+	data_id = data_type | channel << 6;
+
+	r = (data_id << 0) | (data << 8) | (ecc << 24);
+
+	dsi_write_reg(DSI_VC_SHORT_PACKET_HEADER(channel), r);
+
+	return 0;
+}
+
+int dsi_vc_send_null(int channel)
+{
+	u8 nullpkg[] = {0, 0, 0, 0};
+	return dsi_vc_send_long(0, DSI_DT_NULL_PACKET, nullpkg, 4, 0);
+}
+EXPORT_SYMBOL(dsi_vc_send_null);
+
+int dsi_vc_dcs_write_nosync(int channel, u8 *data, int len)
+{
+	int r;
+
+	BUG_ON(len == 0);
+
+	if (len == 1) {
+		r = dsi_vc_send_short(channel, DSI_DT_DCS_SHORT_WRITE_0,
+				data[0], 0);
+	} else if (len == 2) {
+		r = dsi_vc_send_short(channel, DSI_DT_DCS_SHORT_WRITE_1,
+				data[0] | (data[1] << 8), 0);
+	} else {
+		/* 0x39 = DCS Long Write */
+		r = dsi_vc_send_long(channel, DSI_DT_DCS_LONG_WRITE,
+				data, len, 0);
+	}
+
+	return r;
+}
+EXPORT_SYMBOL(dsi_vc_dcs_write_nosync);
+
+int dsi_vc_dcs_write(int channel, u8 *data, int len)
+{
+	int r;
+
+	r = dsi_vc_dcs_write_nosync(channel, data, len);
+	if (r)
+		return r;
+
+	r = dsi_vc_send_bta_sync(channel);
+
+	return r;
+}
+EXPORT_SYMBOL(dsi_vc_dcs_write);
+
+int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
+{
+	u32 val;
+	u8 dt;
+	int r;
+
+	if (dsi.debug_read)
+		DSSDBG("dsi_vc_dcs_read(ch%d, dcs_cmd %u)\n", channel, dcs_cmd);
+
+	r = dsi_vc_send_short(channel, DSI_DT_DCS_READ, dcs_cmd, 0);
+	if (r)
+		return r;
+
+	r = dsi_vc_send_bta_sync(channel);
+	if (r)
+		return r;
+
+	/* RX_FIFO_NOT_EMPTY */
+	if (REG_GET(DSI_VC_CTRL(channel), 20, 20) == 0) {
+		DSSERR("RX fifo empty when trying to read.\n");
+		return -EIO;
+	}
+
+	val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel));
+	if (dsi.debug_read)
+		DSSDBG("\theader: %08x\n", val);
+	dt = FLD_GET(val, 5, 0);
+	if (dt == DSI_DT_RX_ACK_WITH_ERR) {
+		u16 err = FLD_GET(val, 23, 8);
+		dsi_show_rx_ack_with_err(err);
+		return -EIO;
+
+	} else if (dt == DSI_DT_RX_SHORT_READ_1) {
+		u8 data = FLD_GET(val, 15, 8);
+		if (dsi.debug_read)
+			DSSDBG("\tDCS short response, 1 byte: %02x\n", data);
+
+		if (buflen < 1)
+			return -EIO;
+
+		buf[0] = data;
+
+		return 1;
+	} else if (dt == DSI_DT_RX_SHORT_READ_2) {
+		u16 data = FLD_GET(val, 23, 8);
+		if (dsi.debug_read)
+			DSSDBG("\tDCS short response, 2 byte: %04x\n", data);
+
+		if (buflen < 2)
+			return -EIO;
+
+		buf[0] = data & 0xff;
+		buf[1] = (data >> 8) & 0xff;
+
+		return 2;
+	} else if (dt == DSI_DT_RX_DCS_LONG_READ) {
+		int w;
+		int len = FLD_GET(val, 23, 8);
+		if (dsi.debug_read)
+			DSSDBG("\tDCS long response, len %d\n", len);
+
+		if (len > buflen)
+			return -EIO;
+
+		/* two byte checksum ends the packet, not included in len */
+		for (w = 0; w < len + 2;) {
+			int b;
+			val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel));
+			if (dsi.debug_read)
+				DSSDBG("\t\t%02x %02x %02x %02x\n",
+						(val >> 0) & 0xff,
+						(val >> 8) & 0xff,
+						(val >> 16) & 0xff,
+						(val >> 24) & 0xff);
+
+			for (b = 0; b < 4; ++b) {
+				if (w < len)
+					buf[w] = (val >> (b * 8)) & 0xff;
+				/* we discard the 2 byte checksum */
+				++w;
+			}
+		}
+
+		return len;
+
+	} else {
+		DSSERR("\tunknown datatype 0x%02x\n", dt);
+		return -EIO;
+	}
+}
+EXPORT_SYMBOL(dsi_vc_dcs_read);
+
+
+int dsi_vc_set_max_rx_packet_size(int channel, u16 len)
+{
+	int r;
+	r = dsi_vc_send_short(channel, DSI_DT_SET_MAX_RET_PKG_SIZE,
+			len, 0);
+
+	if (r)
+		return r;
+
+	r = dsi_vc_send_bta_sync(channel);
+
+	return r;
+}
+EXPORT_SYMBOL(dsi_vc_set_max_rx_packet_size);
+
+static void dsi_set_lp_rx_timeout(unsigned long ns)
+{
+	u32 r;
+	unsigned x4, x16;
+	unsigned long fck;
+	unsigned long ticks;
+
+	/* ticks in DSI_FCK */
+
+	fck = dsi_fclk_rate();
+	ticks = (fck / 1000 / 1000) * ns / 1000;
+	x4 = 0;
+	x16 = 0;
+
+	if (ticks > 0x1fff) {
+		ticks = (fck / 1000 / 1000) * ns / 1000 / 4;
+		x4 = 1;
+		x16 = 0;
+	}
+
+	if (ticks > 0x1fff) {
+		ticks = (fck / 1000 / 1000) * ns / 1000 / 16;
+		x4 = 0;
+		x16 = 1;
+	}
+
+	if (ticks > 0x1fff) {
+		ticks = (fck / 1000 / 1000) * ns / 1000 / (4 * 16);
+		x4 = 1;
+		x16 = 1;
+	}
+
+	if (ticks > 0x1fff) {
+		DSSWARN("LP_TX_TO over limit, setting it to max\n");
+		ticks = 0x1fff;
+		x4 = 1;
+		x16 = 1;
+	}
+
+	r = dsi_read_reg(DSI_TIMING2);
+	r = FLD_MOD(r, 1, 15, 15);	/* LP_RX_TO */
+	r = FLD_MOD(r, x16, 14, 14);	/* LP_RX_TO_X16 */
+	r = FLD_MOD(r, x4, 13, 13);	/* LP_RX_TO_X4 */
+	r = FLD_MOD(r, ticks, 12, 0);	/* LP_RX_COUNTER */
+	dsi_write_reg(DSI_TIMING2, r);
+
+	DSSDBG("LP_RX_TO %lu ns (%#lx ticks%s%s)\n",
+			(ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1) * 1000) /
+			(fck / 1000 / 1000),
+			ticks, x4 ? " x4" : "", x16 ? " x16" : "");
+}
+
+static void dsi_set_ta_timeout(unsigned long ns)
+{
+	u32 r;
+	unsigned x8, x16;
+	unsigned long fck;
+	unsigned long ticks;
+
+	/* ticks in DSI_FCK */
+	fck = dsi_fclk_rate();
+	ticks = (fck / 1000 / 1000) * ns / 1000;
+	x8 = 0;
+	x16 = 0;
+
+	if (ticks > 0x1fff) {
+		ticks = (fck / 1000 / 1000) * ns / 1000 / 8;
+		x8 = 1;
+		x16 = 0;
+	}
+
+	if (ticks > 0x1fff) {
+		ticks = (fck / 1000 / 1000) * ns / 1000 / 16;
+		x8 = 0;
+		x16 = 1;
+	}
+
+	if (ticks > 0x1fff) {
+		ticks = (fck / 1000 / 1000) * ns / 1000 / (8 * 16);
+		x8 = 1;
+		x16 = 1;
+	}
+
+	if (ticks > 0x1fff) {
+		DSSWARN("TA_TO over limit, setting it to max\n");
+		ticks = 0x1fff;
+		x8 = 1;
+		x16 = 1;
+	}
+
+	r = dsi_read_reg(DSI_TIMING1);
+	r = FLD_MOD(r, 1, 31, 31);	/* TA_TO */
+	r = FLD_MOD(r, x16, 30, 30);	/* TA_TO_X16 */
+	r = FLD_MOD(r, x8, 29, 29);	/* TA_TO_X8 */
+	r = FLD_MOD(r, ticks, 28, 16);	/* TA_TO_COUNTER */
+	dsi_write_reg(DSI_TIMING1, r);
+
+	DSSDBG("TA_TO %lu ns (%#lx ticks%s%s)\n",
+			(ticks * (x16 ? 16 : 1) * (x8 ? 8 : 1) * 1000) /
+			(fck / 1000 / 1000),
+			ticks, x8 ? " x8" : "", x16 ? " x16" : "");
+}
+
+static void dsi_set_stop_state_counter(unsigned long ns)
+{
+	u32 r;
+	unsigned x4, x16;
+	unsigned long fck;
+	unsigned long ticks;
+
+	/* ticks in DSI_FCK */
+
+	fck = dsi_fclk_rate();
+	ticks = (fck / 1000 / 1000) * ns / 1000;
+	x4 = 0;
+	x16 = 0;
+
+	if (ticks > 0x1fff) {
+		ticks = (fck / 1000 / 1000) * ns / 1000 / 4;
+		x4 = 1;
+		x16 = 0;
+	}
+
+	if (ticks > 0x1fff) {
+		ticks = (fck / 1000 / 1000) * ns / 1000 / 16;
+		x4 = 0;
+		x16 = 1;
+	}
+
+	if (ticks > 0x1fff) {
+		ticks = (fck / 1000 / 1000) * ns / 1000 / (4 * 16);
+		x4 = 1;
+		x16 = 1;
+	}
+
+	if (ticks > 0x1fff) {
+		DSSWARN("STOP_STATE_COUNTER_IO over limit, "
+				"setting it to max\n");
+		ticks = 0x1fff;
+		x4 = 1;
+		x16 = 1;
+	}
+
+	r = dsi_read_reg(DSI_TIMING1);
+	r = FLD_MOD(r, 1, 15, 15);	/* FORCE_TX_STOP_MODE_IO */
+	r = FLD_MOD(r, x16, 14, 14);	/* STOP_STATE_X16_IO */
+	r = FLD_MOD(r, x4, 13, 13);	/* STOP_STATE_X4_IO */
+	r = FLD_MOD(r, ticks, 12, 0);	/* STOP_STATE_COUNTER_IO */
+	dsi_write_reg(DSI_TIMING1, r);
+
+	DSSDBG("STOP_STATE_COUNTER %lu ns (%#lx ticks%s%s)\n",
+			(ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1) * 1000) /
+			(fck / 1000 / 1000),
+			ticks, x4 ? " x4" : "", x16 ? " x16" : "");
+}
+
+static void dsi_set_hs_tx_timeout(unsigned long ns)
+{
+	u32 r;
+	unsigned x4, x16;
+	unsigned long fck;
+	unsigned long ticks;
+
+	/* ticks in TxByteClkHS */
+
+	fck = dsi_get_txbyteclkhs();
+	ticks = (fck / 1000 / 1000) * ns / 1000;
+	x4 = 0;
+	x16 = 0;
+
+	if (ticks > 0x1fff) {
+		ticks = (fck / 1000 / 1000) * ns / 1000 / 4;
+		x4 = 1;
+		x16 = 0;
+	}
+
+	if (ticks > 0x1fff) {
+		ticks = (fck / 1000 / 1000) * ns / 1000 / 16;
+		x4 = 0;
+		x16 = 1;
+	}
+
+	if (ticks > 0x1fff) {
+		ticks = (fck / 1000 / 1000) * ns / 1000 / (4 * 16);
+		x4 = 1;
+		x16 = 1;
+	}
+
+	if (ticks > 0x1fff) {
+		DSSWARN("HS_TX_TO over limit, setting it to max\n");
+		ticks = 0x1fff;
+		x4 = 1;
+		x16 = 1;
+	}
+
+	r = dsi_read_reg(DSI_TIMING2);
+	r = FLD_MOD(r, 1, 31, 31);	/* HS_TX_TO */
+	r = FLD_MOD(r, x16, 30, 30);	/* HS_TX_TO_X16 */
+	r = FLD_MOD(r, x4, 29, 29);	/* HS_TX_TO_X8 (4 really) */
+	r = FLD_MOD(r, ticks, 28, 16);	/* HS_TX_TO_COUNTER */
+	dsi_write_reg(DSI_TIMING2, r);
+
+	DSSDBG("HS_TX_TO %lu ns (%#lx ticks%s%s)\n",
+			(ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1) * 1000) /
+			(fck / 1000 / 1000),
+			ticks, x4 ? " x4" : "", x16 ? " x16" : "");
+}
+static int dsi_proto_config(struct omap_dss_device *dssdev)
+{
+	u32 r;
+	int buswidth = 0;
+
+	dsi_config_tx_fifo(DSI_FIFO_SIZE_128,
+			DSI_FIFO_SIZE_0,
+			DSI_FIFO_SIZE_0,
+			DSI_FIFO_SIZE_0);
+
+	dsi_config_rx_fifo(DSI_FIFO_SIZE_128,
+			DSI_FIFO_SIZE_0,
+			DSI_FIFO_SIZE_0,
+			DSI_FIFO_SIZE_0);
+
+	/* XXX what values for the timeouts? */
+	dsi_set_stop_state_counter(1000);
+	dsi_set_ta_timeout(6400000);
+	dsi_set_lp_rx_timeout(48000);
+	dsi_set_hs_tx_timeout(1000000);
+
+	switch (dssdev->ctrl.pixel_size) {
+	case 16:
+		buswidth = 0;
+		break;
+	case 18:
+		buswidth = 1;
+		break;
+	case 24:
+		buswidth = 2;
+		break;
+	default:
+		BUG();
+	}
+
+	r = dsi_read_reg(DSI_CTRL);
+	r = FLD_MOD(r, 1, 1, 1);	/* CS_RX_EN */
+	r = FLD_MOD(r, 1, 2, 2);	/* ECC_RX_EN */
+	r = FLD_MOD(r, 1, 3, 3);	/* TX_FIFO_ARBITRATION */
+	r = FLD_MOD(r, 1, 4, 4);	/* VP_CLK_RATIO, always 1, see errata*/
+	r = FLD_MOD(r, buswidth, 7, 6); /* VP_DATA_BUS_WIDTH */
+	r = FLD_MOD(r, 0, 8, 8);	/* VP_CLK_POL */
+	r = FLD_MOD(r, 2, 13, 12);	/* LINE_BUFFER, 2 lines */
+	r = FLD_MOD(r, 1, 14, 14);	/* TRIGGER_RESET_MODE */
+	r = FLD_MOD(r, 1, 19, 19);	/* EOT_ENABLE */
+	r = FLD_MOD(r, 1, 24, 24);	/* DCS_CMD_ENABLE */
+	r = FLD_MOD(r, 0, 25, 25);	/* DCS_CMD_CODE, 1=start, 0=continue */
+
+	dsi_write_reg(DSI_CTRL, r);
+
+	dsi_vc_initial_config(0);
+
+	/* set all vc targets to peripheral 0 */
+	dsi.vc[0].dest_per = 0;
+	dsi.vc[1].dest_per = 0;
+	dsi.vc[2].dest_per = 0;
+	dsi.vc[3].dest_per = 0;
+
+	return 0;
+}
+
+static void dsi_proto_timings(struct omap_dss_device *dssdev)
+{
+	unsigned tlpx, tclk_zero, tclk_prepare, tclk_trail;
+	unsigned tclk_pre, tclk_post;
+	unsigned ths_prepare, ths_prepare_ths_zero, ths_zero;
+	unsigned ths_trail, ths_exit;
+	unsigned ddr_clk_pre, ddr_clk_post;
+	unsigned enter_hs_mode_lat, exit_hs_mode_lat;
+	unsigned ths_eot;
+	u32 r;
+
+	r = dsi_read_reg(DSI_DSIPHY_CFG0);
+	ths_prepare = FLD_GET(r, 31, 24);
+	ths_prepare_ths_zero = FLD_GET(r, 23, 16);
+	ths_zero = ths_prepare_ths_zero - ths_prepare;
+	ths_trail = FLD_GET(r, 15, 8);
+	ths_exit = FLD_GET(r, 7, 0);
+
+	r = dsi_read_reg(DSI_DSIPHY_CFG1);
+	tlpx = FLD_GET(r, 22, 16) * 2;
+	tclk_trail = FLD_GET(r, 15, 8);
+	tclk_zero = FLD_GET(r, 7, 0);
+
+	r = dsi_read_reg(DSI_DSIPHY_CFG2);
+	tclk_prepare = FLD_GET(r, 7, 0);
+
+	/* min 8*UI */
+	tclk_pre = 20;
+	/* min 60ns + 52*UI */
+	tclk_post = ns2ddr(60) + 26;
+
+	/* ths_eot is 2 for 2 datalanes and 4 for 1 datalane */
+	if (dssdev->phy.dsi.data1_lane != 0 &&
+			dssdev->phy.dsi.data2_lane != 0)
+		ths_eot = 2;
+	else
+		ths_eot = 4;
+
+	ddr_clk_pre = DIV_ROUND_UP(tclk_pre + tlpx + tclk_zero + tclk_prepare,
+			4);
+	ddr_clk_post = DIV_ROUND_UP(tclk_post + ths_trail, 4) + ths_eot;
+
+	BUG_ON(ddr_clk_pre == 0 || ddr_clk_pre > 255);
+	BUG_ON(ddr_clk_post == 0 || ddr_clk_post > 255);
+
+	r = dsi_read_reg(DSI_CLK_TIMING);
+	r = FLD_MOD(r, ddr_clk_pre, 15, 8);
+	r = FLD_MOD(r, ddr_clk_post, 7, 0);
+	dsi_write_reg(DSI_CLK_TIMING, r);
+
+	DSSDBG("ddr_clk_pre %u, ddr_clk_post %u\n",
+			ddr_clk_pre,
+			ddr_clk_post);
+
+	enter_hs_mode_lat = 1 + DIV_ROUND_UP(tlpx, 4) +
+		DIV_ROUND_UP(ths_prepare, 4) +
+		DIV_ROUND_UP(ths_zero + 3, 4);
+
+	exit_hs_mode_lat = DIV_ROUND_UP(ths_trail + ths_exit, 4) + 1 + ths_eot;
+
+	r = FLD_VAL(enter_hs_mode_lat, 31, 16) |
+		FLD_VAL(exit_hs_mode_lat, 15, 0);
+	dsi_write_reg(DSI_VM_TIMING7, r);
+
+	DSSDBG("enter_hs_mode_lat %u, exit_hs_mode_lat %u\n",
+			enter_hs_mode_lat, exit_hs_mode_lat);
+}
+
+
+#define DSI_DECL_VARS \
+	int __dsi_cb = 0; u32 __dsi_cv = 0;
+
+#define DSI_FLUSH(ch) \
+	if (__dsi_cb > 0) { \
+		/*DSSDBG("sending long packet %#010x\n", __dsi_cv);*/ \
+		dsi_write_reg(DSI_VC_LONG_PACKET_PAYLOAD(ch), __dsi_cv); \
+		__dsi_cb = __dsi_cv = 0; \
+	}
+
+#define DSI_PUSH(ch, data) \
+	do { \
+		__dsi_cv |= (data) << (__dsi_cb * 8); \
+		/*DSSDBG("cv = %#010x, cb = %d\n", __dsi_cv, __dsi_cb);*/ \
+		if (++__dsi_cb > 3) \
+			DSI_FLUSH(ch); \
+	} while (0)
+
+static int dsi_update_screen_l4(struct omap_dss_device *dssdev,
+			int x, int y, int w, int h)
+{
+	/* Note: supports only 24bit colors in 32bit container */
+	int first = 1;
+	int fifo_stalls = 0;
+	int max_dsi_packet_size;
+	int max_data_per_packet;
+	int max_pixels_per_packet;
+	int pixels_left;
+	int bytespp = dssdev->ctrl.pixel_size / 8;
+	int scr_width;
+	u32 __iomem *data;
+	int start_offset;
+	int horiz_inc;
+	int current_x;
+	struct omap_overlay *ovl;
+
+	debug_irq = 0;
+
+	DSSDBG("dsi_update_screen_l4 (%d,%d %dx%d)\n",
+			x, y, w, h);
+
+	ovl = dssdev->manager->overlays[0];
+
+	if (ovl->info.color_mode != OMAP_DSS_COLOR_RGB24U)
+		return -EINVAL;
+
+	if (dssdev->ctrl.pixel_size != 24)
+		return -EINVAL;
+
+	scr_width = ovl->info.screen_width;
+	data = ovl->info.vaddr;
+
+	start_offset = scr_width * y + x;
+	horiz_inc = scr_width - w;
+	current_x = x;
+
+	/* We need header(4) + DCSCMD(1) + pixels(numpix*bytespp) bytes
+	 * in fifo */
+
+	/* When using CPU, max long packet size is TX buffer size */
+	max_dsi_packet_size = dsi.vc[0].fifo_size * 32 * 4;
+
+	/* we seem to get better perf if we divide the tx fifo to half,
+	   and while the other half is being sent, we fill the other half
+	   max_dsi_packet_size /= 2; */
+
+	max_data_per_packet = max_dsi_packet_size - 4 - 1;
+
+	max_pixels_per_packet = max_data_per_packet / bytespp;
+
+	DSSDBG("max_pixels_per_packet %d\n", max_pixels_per_packet);
+
+	pixels_left = w * h;
+
+	DSSDBG("total pixels %d\n", pixels_left);
+
+	data += start_offset;
+
+	while (pixels_left > 0) {
+		/* 0x2c = write_memory_start */
+		/* 0x3c = write_memory_continue */
+		u8 dcs_cmd = first ? 0x2c : 0x3c;
+		int pixels;
+		DSI_DECL_VARS;
+		first = 0;
+
+#if 1
+		/* using fifo not empty */
+		/* TX_FIFO_NOT_EMPTY */
+		while (FLD_GET(dsi_read_reg(DSI_VC_CTRL(0)), 5, 5)) {
+			udelay(1);
+			fifo_stalls++;
+			if (fifo_stalls > 0xfffff) {
+				DSSERR("fifo stalls overflow, pixels left %d\n",
+						pixels_left);
+				dsi_if_enable(0);
+				return -EIO;
+			}
+		}
+#elif 1
+		/* using fifo emptiness */
+		while ((REG_GET(DSI_TX_FIFO_VC_EMPTINESS, 7, 0)+1)*4 <
+				max_dsi_packet_size) {
+			fifo_stalls++;
+			if (fifo_stalls > 0xfffff) {
+				DSSERR("fifo stalls overflow, pixels left %d\n",
+					       pixels_left);
+				dsi_if_enable(0);
+				return -EIO;
+			}
+		}
+#else
+		while ((REG_GET(DSI_TX_FIFO_VC_EMPTINESS, 7, 0)+1)*4 == 0) {
+			fifo_stalls++;
+			if (fifo_stalls > 0xfffff) {
+				DSSERR("fifo stalls overflow, pixels left %d\n",
+					       pixels_left);
+				dsi_if_enable(0);
+				return -EIO;
+			}
+		}
+#endif
+		pixels = min(max_pixels_per_packet, pixels_left);
+
+		pixels_left -= pixels;
+
+		dsi_vc_write_long_header(0, DSI_DT_DCS_LONG_WRITE,
+				1 + pixels * bytespp, 0);
+
+		DSI_PUSH(0, dcs_cmd);
+
+		while (pixels-- > 0) {
+			u32 pix = __raw_readl(data++);
+
+			DSI_PUSH(0, (pix >> 16) & 0xff);
+			DSI_PUSH(0, (pix >> 8) & 0xff);
+			DSI_PUSH(0, (pix >> 0) & 0xff);
+
+			current_x++;
+			if (current_x == x+w) {
+				current_x = x;
+				data += horiz_inc;
+			}
+		}
+
+		DSI_FLUSH(0);
+	}
+
+	return 0;
+}
+
+static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
+		u16 x, u16 y, u16 w, u16 h)
+{
+	unsigned bytespp;
+	unsigned bytespl;
+	unsigned bytespf;
+	unsigned total_len;
+	unsigned packet_payload;
+	unsigned packet_len;
+	u32 l;
+	bool use_te_trigger;
+	const unsigned channel = 0;
+	/* line buffer is 1024 x 24bits */
+	/* XXX: for some reason using full buffer size causes considerable TX
+	 * slowdown with update sizes that fill the whole buffer */
+	const unsigned line_buf_size = 1023 * 3;
+
+	use_te_trigger = dsi.te_enabled && !dsi.use_ext_te;
+
+	if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO)
+		DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n",
+				x, y, w, h);
+
+	bytespp	= dssdev->ctrl.pixel_size / 8;
+	bytespl = w * bytespp;
+	bytespf = bytespl * h;
+
+	/* NOTE: packet_payload has to be equal to N * bytespl, where N is
+	 * number of lines in a packet.  See errata about VP_CLK_RATIO */
+
+	if (bytespf < line_buf_size)
+		packet_payload = bytespf;
+	else
+		packet_payload = (line_buf_size) / bytespl * bytespl;
+
+	packet_len = packet_payload + 1;	/* 1 byte for DCS cmd */
+	total_len = (bytespf / packet_payload) * packet_len;
+
+	if (bytespf % packet_payload)
+		total_len += (bytespf % packet_payload) + 1;
+
+	if (0)
+		dsi_vc_print_status(1);
+
+	l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */
+	dsi_write_reg(DSI_VC_TE(channel), l);
+
+	dsi_vc_write_long_header(channel, DSI_DT_DCS_LONG_WRITE, packet_len, 0);
+
+	if (use_te_trigger)
+		l = FLD_MOD(l, 1, 30, 30); /* TE_EN */
+	else
+		l = FLD_MOD(l, 1, 31, 31); /* TE_START */
+	dsi_write_reg(DSI_VC_TE(channel), l);
+
+	/* We put SIDLEMODE to no-idle for the duration of the transfer,
+	 * because DSS interrupts are not capable of waking up the CPU and the
+	 * framedone interrupt could be delayed for quite a long time. I think
+	 * the same goes for any DSS interrupts, but for some reason I have not
+	 * seen the problem anywhere else than here.
+	 */
+	dispc_disable_sidle();
+
+	dss_start_update(dssdev);
+
+	if (use_te_trigger) {
+		/* disable LP_RX_TO, so that we can receive TE.  Time to wait
+		 * for TE is longer than the timer allows */
+		REG_FLD_MOD(DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */
+
+		dsi_vc_send_bta(channel);
+
+#ifdef DSI_CATCH_MISSING_TE
+		mod_timer(&dsi.te_timer, jiffies + msecs_to_jiffies(250));
+#endif
+	}
+}
+
+#ifdef DSI_CATCH_MISSING_TE
+static void dsi_te_timeout(unsigned long arg)
+{
+	DSSERR("TE not received for 250ms!\n");
+}
+#endif
+
+static void dsi_framedone_irq_callback(void *data, u32 mask)
+{
+	/* Note: We get FRAMEDONE when DISPC has finished sending pixels and
+	 * turns itself off. However, DSI still has the pixels in its buffers,
+	 * and is sending the data.
+	 */
+
+	/* SIDLEMODE back to smart-idle */
+	dispc_enable_sidle();
+
+	dsi.framedone_received = true;
+	wake_up(&dsi.waitqueue);
+}
+
+static void dsi_set_update_region(struct omap_dss_device *dssdev,
+		u16 x, u16 y, u16 w, u16 h)
+{
+	spin_lock(&dsi.update_lock);
+	if (dsi.update_region.dirty) {
+		dsi.update_region.x = min(x, dsi.update_region.x);
+		dsi.update_region.y = min(y, dsi.update_region.y);
+		dsi.update_region.w = max(w, dsi.update_region.w);
+		dsi.update_region.h = max(h, dsi.update_region.h);
+	} else {
+		dsi.update_region.x = x;
+		dsi.update_region.y = y;
+		dsi.update_region.w = w;
+		dsi.update_region.h = h;
+	}
+
+	dsi.update_region.device = dssdev;
+	dsi.update_region.dirty = true;
+
+	spin_unlock(&dsi.update_lock);
+
+}
+
+static int dsi_set_update_mode(struct omap_dss_device *dssdev,
+		enum omap_dss_update_mode mode)
+{
+	int r = 0;
+	int i;
+
+	WARN_ON(!mutex_is_locked(&dsi.bus_lock));
+
+	if (dsi.update_mode != mode) {
+		dsi.update_mode = mode;
+
+		/* Mark the overlays dirty, and do apply(), so that we get the
+		 * overlays configured properly after update mode change. */
+		for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
+			struct omap_overlay *ovl;
+			ovl = omap_dss_get_overlay(i);
+			if (ovl->manager == dssdev->manager)
+				ovl->info_dirty = true;
+		}
+
+		r = dssdev->manager->apply(dssdev->manager);
+
+		if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE &&
+				mode == OMAP_DSS_UPDATE_AUTO) {
+			u16 w, h;
+
+			DSSDBG("starting auto update\n");
+
+			dssdev->get_resolution(dssdev, &w, &h);
+
+			dsi_set_update_region(dssdev, 0, 0, w, h);
+
+			dsi_perf_mark_start_auto();
+
+			wake_up(&dsi.waitqueue);
+		}
+	}
+
+	return r;
+}
+
+static int dsi_set_te(struct omap_dss_device *dssdev, bool enable)
+{
+	int r;
+	r = dssdev->driver->enable_te(dssdev, enable);
+	/* XXX for some reason, DSI TE breaks if we don't wait here.
+	 * Panel bug? Needs more studying */
+	msleep(100);
+	return r;
+}
+
+static void dsi_handle_framedone(void)
+{
+	int r;
+	const int channel = 0;
+	bool use_te_trigger;
+
+	use_te_trigger = dsi.te_enabled && !dsi.use_ext_te;
+
+	if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO)
+		DSSDBG("FRAMEDONE\n");
+
+	if (use_te_trigger) {
+		/* enable LP_RX_TO again after the TE */
+		REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
+	}
+
+	/* Send BTA after the frame. We need this for the TE to work, as TE
+	 * trigger is only sent for BTAs without preceding packet. Thus we need
+	 * to BTA after the pixel packets so that next BTA will cause TE
+	 * trigger.
+	 *
+	 * This is not needed when TE is not in use, but we do it anyway to
+	 * make sure that the transfer has been completed. It would be more
+	 * optimal, but more complex, to wait only just before starting next
+	 * transfer. */
+	r = dsi_vc_send_bta_sync(channel);
+	if (r)
+		DSSERR("BTA after framedone failed\n");
+
+	/* RX_FIFO_NOT_EMPTY */
+	if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) {
+		DSSERR("Received error during frame transfer:\n");
+		dsi_vc_flush_receive_data(0);
+	}
+
+#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC
+	dispc_fake_vsync_irq();
+#endif
+}
+
+static int dsi_update_thread(void *data)
+{
+	unsigned long timeout;
+	struct omap_dss_device *device;
+	u16 x, y, w, h;
+
+	while (1) {
+		bool sched;
+
+		wait_event_interruptible(dsi.waitqueue,
+				dsi.update_mode == OMAP_DSS_UPDATE_AUTO ||
+				(dsi.update_mode == OMAP_DSS_UPDATE_MANUAL &&
+				 dsi.update_region.dirty == true) ||
+				kthread_should_stop());
+
+		if (kthread_should_stop())
+			break;
+
+		dsi_bus_lock();
+
+		if (dsi.update_mode == OMAP_DSS_UPDATE_DISABLED ||
+				kthread_should_stop()) {
+			dsi_bus_unlock();
+			break;
+		}
+
+		dsi_perf_mark_setup();
+
+		if (dsi.update_region.dirty) {
+			spin_lock(&dsi.update_lock);
+			dsi.active_update_region = dsi.update_region;
+			dsi.update_region.dirty = false;
+			spin_unlock(&dsi.update_lock);
+		}
+
+		device = dsi.active_update_region.device;
+		x = dsi.active_update_region.x;
+		y = dsi.active_update_region.y;
+		w = dsi.active_update_region.w;
+		h = dsi.active_update_region.h;
+
+		if (device->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
+
+			if (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL)
+				dss_setup_partial_planes(device,
+						&x, &y, &w, &h);
+
+			dispc_set_lcd_size(w, h);
+		}
+
+		if (dsi.active_update_region.dirty) {
+			dsi.active_update_region.dirty = false;
+			/* XXX TODO we don't need to send the coords, if they
+			 * are the same that are already programmed to the
+			 * panel. That should speed up manual update a bit */
+			device->driver->setup_update(device, x, y, w, h);
+		}
+
+		dsi_perf_mark_start();
+
+		if (device->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
+			dsi_vc_config_vp(0);
+
+			if (dsi.te_enabled && dsi.use_ext_te)
+				device->driver->wait_for_te(device);
+
+			dsi.framedone_received = false;
+
+			dsi_update_screen_dispc(device, x, y, w, h);
+
+			/* wait for framedone */
+			timeout = msecs_to_jiffies(1000);
+			wait_event_timeout(dsi.waitqueue,
+					dsi.framedone_received == true,
+					timeout);
+
+			if (!dsi.framedone_received) {
+				DSSERR("framedone timeout\n");
+				DSSERR("failed update %d,%d %dx%d\n",
+						x, y, w, h);
+
+				dispc_enable_sidle();
+				dispc_enable_lcd_out(0);
+
+				dsi_reset_tx_fifo(0);
+			} else {
+				dsi_handle_framedone();
+				dsi_perf_show("DISPC");
+			}
+		} else {
+			dsi_update_screen_l4(device, x, y, w, h);
+			dsi_perf_show("L4");
+		}
+
+		sched = atomic_read(&dsi.bus_lock.count) < 0;
+
+		complete_all(&dsi.update_completion);
+
+		dsi_bus_unlock();
+
+		/* XXX We need to give others chance to get the bus lock. Is
+		 * there a better way for this? */
+		if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO && sched)
+			schedule_timeout_interruptible(1);
+	}
+
+	DSSDBG("update thread exiting\n");
+
+	return 0;
+}
+
+
+
+/* Display funcs */
+
+static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
+{
+	int r;
+
+	r = omap_dispc_register_isr(dsi_framedone_irq_callback, NULL,
+			DISPC_IRQ_FRAMEDONE);
+	if (r) {
+		DSSERR("can't get FRAMEDONE irq\n");
+		return r;
+	}
+
+	dispc_set_lcd_display_type(OMAP_DSS_LCD_DISPLAY_TFT);
+
+	dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_DSI);
+	dispc_enable_fifohandcheck(1);
+
+	dispc_set_tft_data_lines(dssdev->ctrl.pixel_size);
+
+	{
+		struct omap_video_timings timings = {
+			.hsw		= 1,
+			.hfp		= 1,
+			.hbp		= 1,
+			.vsw		= 1,
+			.vfp		= 0,
+			.vbp		= 0,
+		};
+
+		dispc_set_lcd_timings(&timings);
+	}
+
+	return 0;
+}
+
+static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
+{
+	omap_dispc_unregister_isr(dsi_framedone_irq_callback, NULL,
+			DISPC_IRQ_FRAMEDONE);
+}
+
+static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
+{
+	struct dsi_clock_info cinfo;
+	int r;
+
+	/* we always use DSS2_FCK as input clock */
+	cinfo.use_dss2_fck = true;
+	cinfo.regn  = dssdev->phy.dsi.div.regn;
+	cinfo.regm  = dssdev->phy.dsi.div.regm;
+	cinfo.regm3 = dssdev->phy.dsi.div.regm3;
+	cinfo.regm4 = dssdev->phy.dsi.div.regm4;
+	r = dsi_calc_clock_rates(&cinfo);
+	if (r)
+		return r;
+
+	r = dsi_pll_set_clock_div(&cinfo);
+	if (r) {
+		DSSERR("Failed to set dsi clocks\n");
+		return r;
+	}
+
+	return 0;
+}
+
+static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
+{
+	struct dispc_clock_info dispc_cinfo;
+	int r;
+	unsigned long long fck;
+
+	fck = dsi_get_dsi1_pll_rate();
+
+	dispc_cinfo.lck_div = dssdev->phy.dsi.div.lck_div;
+	dispc_cinfo.pck_div = dssdev->phy.dsi.div.pck_div;
+
+	r = dispc_calc_clock_rates(fck, &dispc_cinfo);
+	if (r) {
+		DSSERR("Failed to calc dispc clocks\n");
+		return r;
+	}
+
+	r = dispc_set_clock_div(&dispc_cinfo);
+	if (r) {
+		DSSERR("Failed to set dispc clocks\n");
+		return r;
+	}
+
+	return 0;
+}
+
+static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
+{
+	int r;
+
+	_dsi_print_reset_status();
+
+	r = dsi_pll_init(dssdev, true, true);
+	if (r)
+		goto err0;
+
+	r = dsi_configure_dsi_clocks(dssdev);
+	if (r)
+		goto err1;
+
+	dss_select_clk_source(true, true);
+
+	DSSDBG("PLL OK\n");
+
+	r = dsi_configure_dispc_clocks(dssdev);
+	if (r)
+		goto err2;
+
+	r = dsi_complexio_init(dssdev);
+	if (r)
+		goto err2;
+
+	_dsi_print_reset_status();
+
+	dsi_proto_timings(dssdev);
+	dsi_set_lp_clk_divisor(dssdev);
+
+	if (1)
+		_dsi_print_reset_status();
+
+	r = dsi_proto_config(dssdev);
+	if (r)
+		goto err3;
+
+	/* enable interface */
+	dsi_vc_enable(0, 1);
+	dsi_if_enable(1);
+	dsi_force_tx_stop_mode_io();
+
+	if (dssdev->driver->enable) {
+		r = dssdev->driver->enable(dssdev);
+		if (r)
+			goto err4;
+	}
+
+	/* enable high-speed after initial config */
+	dsi_vc_enable_hs(0, 1);
+
+	return 0;
+err4:
+	dsi_if_enable(0);
+err3:
+	dsi_complexio_uninit();
+err2:
+	dss_select_clk_source(false, false);
+err1:
+	dsi_pll_uninit();
+err0:
+	return r;
+}
+
+static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev)
+{
+	if (dssdev->driver->disable)
+		dssdev->driver->disable(dssdev);
+
+	dss_select_clk_source(false, false);
+	dsi_complexio_uninit();
+	dsi_pll_uninit();
+}
+
+static int dsi_core_init(void)
+{
+	/* Autoidle */
+	REG_FLD_MOD(DSI_SYSCONFIG, 1, 0, 0);
+
+	/* ENWAKEUP */
+	REG_FLD_MOD(DSI_SYSCONFIG, 1, 2, 2);
+
+	/* SIDLEMODE smart-idle */
+	REG_FLD_MOD(DSI_SYSCONFIG, 2, 4, 3);
+
+	_dsi_initialize_irq();
+
+	return 0;
+}
+
+static int dsi_display_enable(struct omap_dss_device *dssdev)
+{
+	int r = 0;
+
+	DSSDBG("dsi_display_enable\n");
+
+	mutex_lock(&dsi.lock);
+	dsi_bus_lock();
+
+	r = omap_dss_start_device(dssdev);
+	if (r) {
+		DSSERR("failed to start device\n");
+		goto err0;
+	}
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
+		DSSERR("dssdev already enabled\n");
+		r = -EINVAL;
+		goto err1;
+	}
+
+	enable_clocks(1);
+	dsi_enable_pll_clock(1);
+
+	r = _dsi_reset();
+	if (r)
+		goto err2;
+
+	dsi_core_init();
+
+	r = dsi_display_init_dispc(dssdev);
+	if (r)
+		goto err2;
+
+	r = dsi_display_init_dsi(dssdev);
+	if (r)
+		goto err3;
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	dsi.use_ext_te = dssdev->phy.dsi.ext_te;
+	r = dsi_set_te(dssdev, dsi.te_enabled);
+	if (r)
+		goto err4;
+
+	dsi_set_update_mode(dssdev, dsi.user_update_mode);
+
+	dsi_bus_unlock();
+	mutex_unlock(&dsi.lock);
+
+	return 0;
+
+err4:
+
+	dsi_display_uninit_dsi(dssdev);
+err3:
+	dsi_display_uninit_dispc(dssdev);
+err2:
+	enable_clocks(0);
+	dsi_enable_pll_clock(0);
+err1:
+	omap_dss_stop_device(dssdev);
+err0:
+	dsi_bus_unlock();
+	mutex_unlock(&dsi.lock);
+	DSSDBG("dsi_display_enable FAILED\n");
+	return r;
+}
+
+static void dsi_display_disable(struct omap_dss_device *dssdev)
+{
+	DSSDBG("dsi_display_disable\n");
+
+	mutex_lock(&dsi.lock);
+	dsi_bus_lock();
+
+	if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
+			dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
+		goto end;
+
+	dsi.update_mode = OMAP_DSS_UPDATE_DISABLED;
+	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+
+	dsi_display_uninit_dispc(dssdev);
+
+	dsi_display_uninit_dsi(dssdev);
+
+	enable_clocks(0);
+	dsi_enable_pll_clock(0);
+
+	omap_dss_stop_device(dssdev);
+end:
+	dsi_bus_unlock();
+	mutex_unlock(&dsi.lock);
+}
+
+static int dsi_display_suspend(struct omap_dss_device *dssdev)
+{
+	DSSDBG("dsi_display_suspend\n");
+
+	mutex_lock(&dsi.lock);
+	dsi_bus_lock();
+
+	if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
+			dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
+		goto end;
+
+	dsi.update_mode = OMAP_DSS_UPDATE_DISABLED;
+	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
+
+	dsi_display_uninit_dispc(dssdev);
+
+	dsi_display_uninit_dsi(dssdev);
+
+	enable_clocks(0);
+	dsi_enable_pll_clock(0);
+end:
+	dsi_bus_unlock();
+	mutex_unlock(&dsi.lock);
+
+	return 0;
+}
+
+static int dsi_display_resume(struct omap_dss_device *dssdev)
+{
+	int r;
+
+	DSSDBG("dsi_display_resume\n");
+
+	mutex_lock(&dsi.lock);
+	dsi_bus_lock();
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
+		DSSERR("dssdev not suspended\n");
+		r = -EINVAL;
+		goto err0;
+	}
+
+	enable_clocks(1);
+	dsi_enable_pll_clock(1);
+
+	r = _dsi_reset();
+	if (r)
+		goto err1;
+
+	dsi_core_init();
+
+	r = dsi_display_init_dispc(dssdev);
+	if (r)
+		goto err1;
+
+	r = dsi_display_init_dsi(dssdev);
+	if (r)
+		goto err2;
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	r = dsi_set_te(dssdev, dsi.te_enabled);
+	if (r)
+		goto err2;
+
+	dsi_set_update_mode(dssdev, dsi.user_update_mode);
+
+	dsi_bus_unlock();
+	mutex_unlock(&dsi.lock);
+
+	return 0;
+
+err2:
+	dsi_display_uninit_dispc(dssdev);
+err1:
+	enable_clocks(0);
+	dsi_enable_pll_clock(0);
+err0:
+	dsi_bus_unlock();
+	mutex_unlock(&dsi.lock);
+	DSSDBG("dsi_display_resume FAILED\n");
+	return r;
+}
+
+static int dsi_display_update(struct omap_dss_device *dssdev,
+			u16 x, u16 y, u16 w, u16 h)
+{
+	int r = 0;
+	u16 dw, dh;
+
+	DSSDBG("dsi_display_update(%d,%d %dx%d)\n", x, y, w, h);
+
+	mutex_lock(&dsi.lock);
+
+	if (dsi.update_mode != OMAP_DSS_UPDATE_MANUAL)
+		goto end;
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+		goto end;
+
+	dssdev->get_resolution(dssdev, &dw, &dh);
+
+	if  (x > dw || y > dh)
+		goto end;
+
+	if (x + w > dw)
+		w = dw - x;
+
+	if (y + h > dh)
+		h = dh - y;
+
+	if (w == 0 || h == 0)
+		goto end;
+
+	if (w == 1) {
+		r = -EINVAL;
+		goto end;
+	}
+
+	dsi_set_update_region(dssdev, x, y, w, h);
+
+	wake_up(&dsi.waitqueue);
+
+end:
+	mutex_unlock(&dsi.lock);
+
+	return r;
+}
+
+static int dsi_display_sync(struct omap_dss_device *dssdev)
+{
+	bool wait;
+
+	DSSDBG("dsi_display_sync()\n");
+
+	mutex_lock(&dsi.lock);
+	dsi_bus_lock();
+
+	if (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL &&
+			dsi.update_region.dirty) {
+		INIT_COMPLETION(dsi.update_completion);
+		wait = true;
+	} else {
+		wait = false;
+	}
+
+	dsi_bus_unlock();
+	mutex_unlock(&dsi.lock);
+
+	if (wait)
+		wait_for_completion_interruptible(&dsi.update_completion);
+
+	DSSDBG("dsi_display_sync() done\n");
+	return 0;
+}
+
+static int dsi_display_set_update_mode(struct omap_dss_device *dssdev,
+		enum omap_dss_update_mode mode)
+{
+	int r = 0;
+
+	DSSDBGF("%d", mode);
+
+	mutex_lock(&dsi.lock);
+	dsi_bus_lock();
+
+	dsi.user_update_mode = mode;
+	r = dsi_set_update_mode(dssdev, mode);
+
+	dsi_bus_unlock();
+	mutex_unlock(&dsi.lock);
+
+	return r;
+}
+
+static enum omap_dss_update_mode dsi_display_get_update_mode(
+		struct omap_dss_device *dssdev)
+{
+	return dsi.update_mode;
+}
+
+
+static int dsi_display_enable_te(struct omap_dss_device *dssdev, bool enable)
+{
+	int r = 0;
+
+	DSSDBGF("%d", enable);
+
+	if (!dssdev->driver->enable_te)
+		return -ENOENT;
+
+	dsi_bus_lock();
+
+	dsi.te_enabled = enable;
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+		goto end;
+
+	r = dsi_set_te(dssdev, enable);
+end:
+	dsi_bus_unlock();
+
+	return r;
+}
+
+static int dsi_display_get_te(struct omap_dss_device *dssdev)
+{
+	return dsi.te_enabled;
+}
+
+static int dsi_display_set_rotate(struct omap_dss_device *dssdev, u8 rotate)
+{
+
+	DSSDBGF("%d", rotate);
+
+	if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
+		return -EINVAL;
+
+	dsi_bus_lock();
+	dssdev->driver->set_rotate(dssdev, rotate);
+	if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO) {
+		u16 w, h;
+		/* the display dimensions may have changed, so set a new
+		 * update region */
+		dssdev->get_resolution(dssdev, &w, &h);
+		dsi_set_update_region(dssdev, 0, 0, w, h);
+	}
+	dsi_bus_unlock();
+
+	return 0;
+}
+
+static u8 dsi_display_get_rotate(struct omap_dss_device *dssdev)
+{
+	if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
+		return 0;
+
+	return dssdev->driver->get_rotate(dssdev);
+}
+
+static int dsi_display_set_mirror(struct omap_dss_device *dssdev, bool mirror)
+{
+	DSSDBGF("%d", mirror);
+
+	if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
+		return -EINVAL;
+
+	dsi_bus_lock();
+	dssdev->driver->set_mirror(dssdev, mirror);
+	dsi_bus_unlock();
+
+	return 0;
+}
+
+static bool dsi_display_get_mirror(struct omap_dss_device *dssdev)
+{
+	if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
+		return 0;
+
+	return dssdev->driver->get_mirror(dssdev);
+}
+
+static int dsi_display_run_test(struct omap_dss_device *dssdev, int test_num)
+{
+	int r;
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+		return -EIO;
+
+	DSSDBGF("%d", test_num);
+
+	dsi_bus_lock();
+
+	/* run test first in low speed mode */
+	dsi_vc_enable_hs(0, 0);
+
+	if (dssdev->driver->run_test) {
+		r = dssdev->driver->run_test(dssdev, test_num);
+		if (r)
+			goto end;
+	}
+
+	/* then in high speed */
+	dsi_vc_enable_hs(0, 1);
+
+	if (dssdev->driver->run_test) {
+		r = dssdev->driver->run_test(dssdev, test_num);
+		if (r)
+			goto end;
+	}
+
+end:
+	dsi_vc_enable_hs(0, 1);
+
+	dsi_bus_unlock();
+
+	return r;
+}
+
+static int dsi_display_memory_read(struct omap_dss_device *dssdev,
+		void *buf, size_t size,
+		u16 x, u16 y, u16 w, u16 h)
+{
+	int r;
+
+	DSSDBGF("");
+
+	if (!dssdev->driver->memory_read)
+		return -EINVAL;
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+		return -EIO;
+
+	dsi_bus_lock();
+
+	r = dssdev->driver->memory_read(dssdev, buf, size,
+			x, y, w, h);
+
+	/* Memory read usually changes the update area. This will
+	 * force the next update to re-set the update area */
+	dsi.active_update_region.dirty = true;
+
+	dsi_bus_unlock();
+
+	return r;
+}
+
+void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
+		u32 fifo_size, enum omap_burst_size *burst_size,
+		u32 *fifo_low, u32 *fifo_high)
+{
+	unsigned burst_size_bytes;
+
+	*burst_size = OMAP_DSS_BURST_16x32;
+	burst_size_bytes = 16 * 32 / 8;
+
+	*fifo_high = fifo_size - burst_size_bytes;
+	*fifo_low = fifo_size - burst_size_bytes * 8;
+}
+
+int dsi_init_display(struct omap_dss_device *dssdev)
+{
+	DSSDBG("DSI init\n");
+
+	dssdev->enable = dsi_display_enable;
+	dssdev->disable = dsi_display_disable;
+	dssdev->suspend = dsi_display_suspend;
+	dssdev->resume = dsi_display_resume;
+	dssdev->update = dsi_display_update;
+	dssdev->sync = dsi_display_sync;
+	dssdev->set_update_mode = dsi_display_set_update_mode;
+	dssdev->get_update_mode = dsi_display_get_update_mode;
+	dssdev->enable_te = dsi_display_enable_te;
+	dssdev->get_te = dsi_display_get_te;
+
+	dssdev->get_rotate = dsi_display_get_rotate;
+	dssdev->set_rotate = dsi_display_set_rotate;
+
+	dssdev->get_mirror = dsi_display_get_mirror;
+	dssdev->set_mirror = dsi_display_set_mirror;
+
+	dssdev->run_test = dsi_display_run_test;
+	dssdev->memory_read = dsi_display_memory_read;
+
+	/* XXX these should be figured out dynamically */
+	dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
+		OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
+
+	dsi.vc[0].dssdev = dssdev;
+	dsi.vc[1].dssdev = dssdev;
+
+	return 0;
+}
+
+int dsi_init(struct platform_device *pdev)
+{
+	u32 rev;
+	int r;
+	struct sched_param param = {
+		.sched_priority = MAX_USER_RT_PRIO-1
+	};
+
+	spin_lock_init(&dsi.errors_lock);
+	dsi.errors = 0;
+
+	init_completion(&dsi.bta_completion);
+	init_completion(&dsi.update_completion);
+
+	dsi.thread = kthread_create(dsi_update_thread, NULL, "dsi");
+	if (IS_ERR(dsi.thread)) {
+		DSSERR("cannot create kthread\n");
+		r = PTR_ERR(dsi.thread);
+		goto err0;
+	}
+	sched_setscheduler(dsi.thread, SCHED_FIFO, &param);
+
+	init_waitqueue_head(&dsi.waitqueue);
+	spin_lock_init(&dsi.update_lock);
+
+	mutex_init(&dsi.lock);
+	mutex_init(&dsi.bus_lock);
+
+#ifdef DSI_CATCH_MISSING_TE
+	init_timer(&dsi.te_timer);
+	dsi.te_timer.function = dsi_te_timeout;
+	dsi.te_timer.data = 0;
+#endif
+
+	dsi.update_mode = OMAP_DSS_UPDATE_DISABLED;
+	dsi.user_update_mode = OMAP_DSS_UPDATE_DISABLED;
+
+	dsi.base = ioremap(DSI_BASE, DSI_SZ_REGS);
+	if (!dsi.base) {
+		DSSERR("can't ioremap DSI\n");
+		r = -ENOMEM;
+		goto err1;
+	}
+
+	dsi.vdds_dsi_reg = regulator_get(&pdev->dev, "vdds_dsi");
+	if (IS_ERR(dsi.vdds_dsi_reg)) {
+		iounmap(dsi.base);
+		DSSERR("can't get VDDS_DSI regulator\n");
+		r = PTR_ERR(dsi.vdds_dsi_reg);
+		goto err2;
+	}
+
+	enable_clocks(1);
+
+	rev = dsi_read_reg(DSI_REVISION);
+	printk(KERN_INFO "OMAP DSI rev %d.%d\n",
+	       FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
+
+	enable_clocks(0);
+
+	wake_up_process(dsi.thread);
+
+	return 0;
+err2:
+	iounmap(dsi.base);
+err1:
+	kthread_stop(dsi.thread);
+err0:
+	return r;
+}
+
+void dsi_exit(void)
+{
+	kthread_stop(dsi.thread);
+
+	regulator_put(dsi.vdds_dsi_reg);
+
+	iounmap(dsi.base);
+
+	DSSDBG("omap_dsi_exit\n");
+}
+
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
new file mode 100644
index 0000000..9b05ee6
--- /dev/null
+++ b/drivers/video/omap2/dss/dss.c
@@ -0,0 +1,596 @@
+/*
+ * linux/drivers/video/omap2/dss/dss.c
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * Some code and ideas taken from drivers/video/omap/ driver
+ * by Imre Deak.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define DSS_SUBSYS_NAME "DSS"
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/seq_file.h>
+#include <linux/clk.h>
+
+#include <plat/display.h>
+#include "dss.h"
+
+#define DSS_BASE			0x48050000
+
+#define DSS_SZ_REGS			SZ_512
+
+struct dss_reg {
+	u16 idx;
+};
+
+#define DSS_REG(idx)			((const struct dss_reg) { idx })
+
+#define DSS_REVISION			DSS_REG(0x0000)
+#define DSS_SYSCONFIG			DSS_REG(0x0010)
+#define DSS_SYSSTATUS			DSS_REG(0x0014)
+#define DSS_IRQSTATUS			DSS_REG(0x0018)
+#define DSS_CONTROL			DSS_REG(0x0040)
+#define DSS_SDI_CONTROL			DSS_REG(0x0044)
+#define DSS_PLL_CONTROL			DSS_REG(0x0048)
+#define DSS_SDI_STATUS			DSS_REG(0x005C)
+
+#define REG_GET(idx, start, end) \
+	FLD_GET(dss_read_reg(idx), start, end)
+
+#define REG_FLD_MOD(idx, val, start, end) \
+	dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end))
+
+static struct {
+	void __iomem    *base;
+
+	struct clk	*dpll4_m4_ck;
+
+	unsigned long	cache_req_pck;
+	unsigned long	cache_prate;
+	struct dss_clock_info cache_dss_cinfo;
+	struct dispc_clock_info cache_dispc_cinfo;
+
+	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
+} dss;
+
+static int _omap_dss_wait_reset(void);
+
+static inline void dss_write_reg(const struct dss_reg idx, u32 val)
+{
+	__raw_writel(val, dss.base + idx.idx);
+}
+
+static inline u32 dss_read_reg(const struct dss_reg idx)
+{
+	return __raw_readl(dss.base + idx.idx);
+}
+
+#define SR(reg) \
+	dss.ctx[(DSS_##reg).idx / sizeof(u32)] = dss_read_reg(DSS_##reg)
+#define RR(reg) \
+	dss_write_reg(DSS_##reg, dss.ctx[(DSS_##reg).idx / sizeof(u32)])
+
+void dss_save_context(void)
+{
+	if (cpu_is_omap24xx())
+		return;
+
+	SR(SYSCONFIG);
+	SR(CONTROL);
+
+#ifdef CONFIG_OMAP2_DSS_SDI
+	SR(SDI_CONTROL);
+	SR(PLL_CONTROL);
+#endif
+}
+
+void dss_restore_context(void)
+{
+	if (_omap_dss_wait_reset())
+		DSSERR("DSS not coming out of reset after sleep\n");
+
+	RR(SYSCONFIG);
+	RR(CONTROL);
+
+#ifdef CONFIG_OMAP2_DSS_SDI
+	RR(SDI_CONTROL);
+	RR(PLL_CONTROL);
+#endif
+}
+
+#undef SR
+#undef RR
+
+void dss_sdi_init(u8 datapairs)
+{
+	u32 l;
+
+	BUG_ON(datapairs > 3 || datapairs < 1);
+
+	l = dss_read_reg(DSS_SDI_CONTROL);
+	l = FLD_MOD(l, 0xf, 19, 15);		/* SDI_PDIV */
+	l = FLD_MOD(l, datapairs-1, 3, 2);	/* SDI_PRSEL */
+	l = FLD_MOD(l, 2, 1, 0);		/* SDI_BWSEL */
+	dss_write_reg(DSS_SDI_CONTROL, l);
+
+	l = dss_read_reg(DSS_PLL_CONTROL);
+	l = FLD_MOD(l, 0x7, 25, 22);	/* SDI_PLL_FREQSEL */
+	l = FLD_MOD(l, 0xb, 16, 11);	/* SDI_PLL_REGN */
+	l = FLD_MOD(l, 0xb4, 10, 1);	/* SDI_PLL_REGM */
+	dss_write_reg(DSS_PLL_CONTROL, l);
+}
+
+int dss_sdi_enable(void)
+{
+	unsigned long timeout;
+
+	dispc_pck_free_enable(1);
+
+	/* Reset SDI PLL */
+	REG_FLD_MOD(DSS_PLL_CONTROL, 1, 18, 18); /* SDI_PLL_SYSRESET */
+	udelay(1);	/* wait 2x PCLK */
+
+	/* Lock SDI PLL */
+	REG_FLD_MOD(DSS_PLL_CONTROL, 1, 28, 28); /* SDI_PLL_GOBIT */
+
+	/* Waiting for PLL lock request to complete */
+	timeout = jiffies + msecs_to_jiffies(500);
+	while (dss_read_reg(DSS_SDI_STATUS) & (1 << 6)) {
+		if (time_after_eq(jiffies, timeout)) {
+			DSSERR("PLL lock request timed out\n");
+			goto err1;
+		}
+	}
+
+	/* Clearing PLL_GO bit */
+	REG_FLD_MOD(DSS_PLL_CONTROL, 0, 28, 28);
+
+	/* Waiting for PLL to lock */
+	timeout = jiffies + msecs_to_jiffies(500);
+	while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 5))) {
+		if (time_after_eq(jiffies, timeout)) {
+			DSSERR("PLL lock timed out\n");
+			goto err1;
+		}
+	}
+
+	dispc_lcd_enable_signal(1);
+
+	/* Waiting for SDI reset to complete */
+	timeout = jiffies + msecs_to_jiffies(500);
+	while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 2))) {
+		if (time_after_eq(jiffies, timeout)) {
+			DSSERR("SDI reset timed out\n");
+			goto err2;
+		}
+	}
+
+	return 0;
+
+ err2:
+	dispc_lcd_enable_signal(0);
+ err1:
+	/* Reset SDI PLL */
+	REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
+
+	dispc_pck_free_enable(0);
+
+	return -ETIMEDOUT;
+}
+
+void dss_sdi_disable(void)
+{
+	dispc_lcd_enable_signal(0);
+
+	dispc_pck_free_enable(0);
+
+	/* Reset SDI PLL */
+	REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
+}
+
+void dss_dump_clocks(struct seq_file *s)
+{
+	unsigned long dpll4_ck_rate;
+	unsigned long dpll4_m4_ck_rate;
+
+	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+
+	dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
+	dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck);
+
+	seq_printf(s, "- DSS -\n");
+
+	seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
+
+	seq_printf(s, "dss1_alwon_fclk = %lu / %lu * 2 = %lu\n",
+			dpll4_ck_rate,
+			dpll4_ck_rate / dpll4_m4_ck_rate,
+			dss_clk_get_rate(DSS_CLK_FCK1));
+
+	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+}
+
+void dss_dump_regs(struct seq_file *s)
+{
+#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r))
+
+	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+
+	DUMPREG(DSS_REVISION);
+	DUMPREG(DSS_SYSCONFIG);
+	DUMPREG(DSS_SYSSTATUS);
+	DUMPREG(DSS_IRQSTATUS);
+	DUMPREG(DSS_CONTROL);
+	DUMPREG(DSS_SDI_CONTROL);
+	DUMPREG(DSS_PLL_CONTROL);
+	DUMPREG(DSS_SDI_STATUS);
+
+	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+#undef DUMPREG
+}
+
+void dss_select_clk_source(bool dsi, bool dispc)
+{
+	u32 r;
+	r = dss_read_reg(DSS_CONTROL);
+	r = FLD_MOD(r, dsi, 1, 1);	/* DSI_CLK_SWITCH */
+	r = FLD_MOD(r, dispc, 0, 0);	/* DISPC_CLK_SWITCH */
+	dss_write_reg(DSS_CONTROL, r);
+}
+
+int dss_get_dsi_clk_source(void)
+{
+	return FLD_GET(dss_read_reg(DSS_CONTROL), 1, 1);
+}
+
+int dss_get_dispc_clk_source(void)
+{
+	return FLD_GET(dss_read_reg(DSS_CONTROL), 0, 0);
+}
+
+/* calculate clock rates using dividers in cinfo */
+int dss_calc_clock_rates(struct dss_clock_info *cinfo)
+{
+	unsigned long prate;
+
+	if (cinfo->fck_div > 16 || cinfo->fck_div == 0)
+		return -EINVAL;
+
+	prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
+
+	cinfo->fck = prate / cinfo->fck_div;
+
+	return 0;
+}
+
+int dss_set_clock_div(struct dss_clock_info *cinfo)
+{
+	unsigned long prate;
+	int r;
+
+	if (cpu_is_omap34xx()) {
+		prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
+		DSSDBG("dpll4_m4 = %ld\n", prate);
+
+		r = clk_set_rate(dss.dpll4_m4_ck, prate / cinfo->fck_div);
+		if (r)
+			return r;
+	}
+
+	DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div);
+
+	return 0;
+}
+
+int dss_get_clock_div(struct dss_clock_info *cinfo)
+{
+	cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK1);
+
+	if (cpu_is_omap34xx()) {
+		unsigned long prate;
+		prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
+		cinfo->fck_div = prate / (cinfo->fck / 2);
+	} else {
+		cinfo->fck_div = 0;
+	}
+
+	return 0;
+}
+
+unsigned long dss_get_dpll4_rate(void)
+{
+	if (cpu_is_omap34xx())
+		return clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
+	else
+		return 0;
+}
+
+int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
+		struct dss_clock_info *dss_cinfo,
+		struct dispc_clock_info *dispc_cinfo)
+{
+	unsigned long prate;
+	struct dss_clock_info best_dss;
+	struct dispc_clock_info best_dispc;
+
+	unsigned long fck;
+
+	u16 fck_div;
+
+	int match = 0;
+	int min_fck_per_pck;
+
+	prate = dss_get_dpll4_rate();
+
+	fck = dss_clk_get_rate(DSS_CLK_FCK1);
+	if (req_pck == dss.cache_req_pck &&
+			((cpu_is_omap34xx() && prate == dss.cache_prate) ||
+			 dss.cache_dss_cinfo.fck == fck)) {
+		DSSDBG("dispc clock info found from cache.\n");
+		*dss_cinfo = dss.cache_dss_cinfo;
+		*dispc_cinfo = dss.cache_dispc_cinfo;
+		return 0;
+	}
+
+	min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
+
+	if (min_fck_per_pck &&
+		req_pck * min_fck_per_pck > DISPC_MAX_FCK) {
+		DSSERR("Requested pixel clock not possible with the current "
+				"OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning "
+				"the constraint off.\n");
+		min_fck_per_pck = 0;
+	}
+
+retry:
+	memset(&best_dss, 0, sizeof(best_dss));
+	memset(&best_dispc, 0, sizeof(best_dispc));
+
+	if (cpu_is_omap24xx()) {
+		struct dispc_clock_info cur_dispc;
+		/* XXX can we change the clock on omap2? */
+		fck = dss_clk_get_rate(DSS_CLK_FCK1);
+		fck_div = 1;
+
+		dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc);
+		match = 1;
+
+		best_dss.fck = fck;
+		best_dss.fck_div = fck_div;
+
+		best_dispc = cur_dispc;
+
+		goto found;
+	} else if (cpu_is_omap34xx()) {
+		for (fck_div = 16; fck_div > 0; --fck_div) {
+			struct dispc_clock_info cur_dispc;
+
+			fck = prate / fck_div * 2;
+
+			if (fck > DISPC_MAX_FCK)
+				continue;
+
+			if (min_fck_per_pck &&
+					fck < req_pck * min_fck_per_pck)
+				continue;
+
+			match = 1;
+
+			dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc);
+
+			if (abs(cur_dispc.pck - req_pck) <
+					abs(best_dispc.pck - req_pck)) {
+
+				best_dss.fck = fck;
+				best_dss.fck_div = fck_div;
+
+				best_dispc = cur_dispc;
+
+				if (cur_dispc.pck == req_pck)
+					goto found;
+			}
+		}
+	} else {
+		BUG();
+	}
+
+found:
+	if (!match) {
+		if (min_fck_per_pck) {
+			DSSERR("Could not find suitable clock settings.\n"
+					"Turning FCK/PCK constraint off and"
+					"trying again.\n");
+			min_fck_per_pck = 0;
+			goto retry;
+		}
+
+		DSSERR("Could not find suitable clock settings.\n");
+
+		return -EINVAL;
+	}
+
+	if (dss_cinfo)
+		*dss_cinfo = best_dss;
+	if (dispc_cinfo)
+		*dispc_cinfo = best_dispc;
+
+	dss.cache_req_pck = req_pck;
+	dss.cache_prate = prate;
+	dss.cache_dss_cinfo = best_dss;
+	dss.cache_dispc_cinfo = best_dispc;
+
+	return 0;
+}
+
+
+
+static irqreturn_t dss_irq_handler_omap2(int irq, void *arg)
+{
+	dispc_irq_handler();
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t dss_irq_handler_omap3(int irq, void *arg)
+{
+	u32 irqstatus;
+
+	irqstatus = dss_read_reg(DSS_IRQSTATUS);
+
+	if (irqstatus & (1<<0))	/* DISPC_IRQ */
+		dispc_irq_handler();
+#ifdef CONFIG_OMAP2_DSS_DSI
+	if (irqstatus & (1<<1))	/* DSI_IRQ */
+		dsi_irq_handler();
+#endif
+
+	return IRQ_HANDLED;
+}
+
+static int _omap_dss_wait_reset(void)
+{
+	unsigned timeout = 1000;
+
+	while (REG_GET(DSS_SYSSTATUS, 0, 0) == 0) {
+		udelay(1);
+		if (!--timeout) {
+			DSSERR("soft reset failed\n");
+			return -ENODEV;
+		}
+	}
+
+	return 0;
+}
+
+static int _omap_dss_reset(void)
+{
+	/* Soft reset */
+	REG_FLD_MOD(DSS_SYSCONFIG, 1, 1, 1);
+	return _omap_dss_wait_reset();
+}
+
+void dss_set_venc_output(enum omap_dss_venc_type type)
+{
+	int l = 0;
+
+	if (type == OMAP_DSS_VENC_TYPE_COMPOSITE)
+		l = 0;
+	else if (type == OMAP_DSS_VENC_TYPE_SVIDEO)
+		l = 1;
+	else
+		BUG();
+
+	/* venc out selection. 0 = comp, 1 = svideo */
+	REG_FLD_MOD(DSS_CONTROL, l, 6, 6);
+}
+
+void dss_set_dac_pwrdn_bgz(bool enable)
+{
+	REG_FLD_MOD(DSS_CONTROL, enable, 5, 5);	/* DAC Power-Down Control */
+}
+
+int dss_init(bool skip_init)
+{
+	int r;
+	u32 rev;
+
+	dss.base = ioremap(DSS_BASE, DSS_SZ_REGS);
+	if (!dss.base) {
+		DSSERR("can't ioremap DSS\n");
+		r = -ENOMEM;
+		goto fail0;
+	}
+
+	if (!skip_init) {
+		/* disable LCD and DIGIT output. This seems to fix the synclost
+		 * problem that we get, if the bootloader starts the DSS and
+		 * the kernel resets it */
+		omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440);
+
+		/* We need to wait here a bit, otherwise we sometimes start to
+		 * get synclost errors, and after that only power cycle will
+		 * restore DSS functionality. I have no idea why this happens.
+		 * And we have to wait _before_ resetting the DSS, but after
+		 * enabling clocks.
+		 */
+		msleep(50);
+
+		_omap_dss_reset();
+	}
+
+	/* autoidle */
+	REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0);
+
+	/* Select DPLL */
+	REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);
+
+#ifdef CONFIG_OMAP2_DSS_VENC
+	REG_FLD_MOD(DSS_CONTROL, 1, 4, 4);	/* venc dac demen */
+	REG_FLD_MOD(DSS_CONTROL, 1, 3, 3);	/* venc clock 4x enable */
+	REG_FLD_MOD(DSS_CONTROL, 0, 2, 2);	/* venc clock mode = normal */
+#endif
+
+	r = request_irq(INT_24XX_DSS_IRQ,
+			cpu_is_omap24xx()
+			? dss_irq_handler_omap2
+			: dss_irq_handler_omap3,
+			0, "OMAP DSS", NULL);
+
+	if (r < 0) {
+		DSSERR("omap2 dss: request_irq failed\n");
+		goto fail1;
+	}
+
+	if (cpu_is_omap34xx()) {
+		dss.dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck");
+		if (IS_ERR(dss.dpll4_m4_ck)) {
+			DSSERR("Failed to get dpll4_m4_ck\n");
+			r = PTR_ERR(dss.dpll4_m4_ck);
+			goto fail2;
+		}
+	}
+
+	dss_save_context();
+
+	rev = dss_read_reg(DSS_REVISION);
+	printk(KERN_INFO "OMAP DSS rev %d.%d\n",
+			FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
+
+	return 0;
+
+fail2:
+	free_irq(INT_24XX_DSS_IRQ, NULL);
+fail1:
+	iounmap(dss.base);
+fail0:
+	return r;
+}
+
+void dss_exit(void)
+{
+	if (cpu_is_omap34xx())
+		clk_put(dss.dpll4_m4_ck);
+
+	free_irq(INT_24XX_DSS_IRQ, NULL);
+
+	iounmap(dss.base);
+}
+
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
new file mode 100644
index 0000000..8da5ac42
--- /dev/null
+++ b/drivers/video/omap2/dss/dss.h
@@ -0,0 +1,370 @@
+/*
+ * linux/drivers/video/omap2/dss/dss.h
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * Some code and ideas taken from drivers/video/omap/ driver
+ * by Imre Deak.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __OMAP2_DSS_H
+#define __OMAP2_DSS_H
+
+#ifdef CONFIG_OMAP2_DSS_DEBUG_SUPPORT
+#define DEBUG
+#endif
+
+#ifdef DEBUG
+extern unsigned int dss_debug;
+#ifdef DSS_SUBSYS_NAME
+#define DSSDBG(format, ...) \
+	if (dss_debug) \
+		printk(KERN_DEBUG "omapdss " DSS_SUBSYS_NAME ": " format, \
+		## __VA_ARGS__)
+#else
+#define DSSDBG(format, ...) \
+	if (dss_debug) \
+		printk(KERN_DEBUG "omapdss: " format, ## __VA_ARGS__)
+#endif
+
+#ifdef DSS_SUBSYS_NAME
+#define DSSDBGF(format, ...) \
+	if (dss_debug) \
+		printk(KERN_DEBUG "omapdss " DSS_SUBSYS_NAME \
+				": %s(" format ")\n", \
+				__func__, \
+				## __VA_ARGS__)
+#else
+#define DSSDBGF(format, ...) \
+	if (dss_debug) \
+		printk(KERN_DEBUG "omapdss: " \
+				": %s(" format ")\n", \
+				__func__, \
+				## __VA_ARGS__)
+#endif
+
+#else /* DEBUG */
+#define DSSDBG(format, ...)
+#define DSSDBGF(format, ...)
+#endif
+
+
+#ifdef DSS_SUBSYS_NAME
+#define DSSERR(format, ...) \
+	printk(KERN_ERR "omapdss " DSS_SUBSYS_NAME " error: " format, \
+	## __VA_ARGS__)
+#else
+#define DSSERR(format, ...) \
+	printk(KERN_ERR "omapdss error: " format, ## __VA_ARGS__)
+#endif
+
+#ifdef DSS_SUBSYS_NAME
+#define DSSINFO(format, ...) \
+	printk(KERN_INFO "omapdss " DSS_SUBSYS_NAME ": " format, \
+	## __VA_ARGS__)
+#else
+#define DSSINFO(format, ...) \
+	printk(KERN_INFO "omapdss: " format, ## __VA_ARGS__)
+#endif
+
+#ifdef DSS_SUBSYS_NAME
+#define DSSWARN(format, ...) \
+	printk(KERN_WARNING "omapdss " DSS_SUBSYS_NAME ": " format, \
+	## __VA_ARGS__)
+#else
+#define DSSWARN(format, ...) \
+	printk(KERN_WARNING "omapdss: " format, ## __VA_ARGS__)
+#endif
+
+/* OMAP TRM gives bitfields as start:end, where start is the higher bit
+   number. For example 7:0 */
+#define FLD_MASK(start, end)	(((1 << ((start) - (end) + 1)) - 1) << (end))
+#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))
+#define FLD_GET(val, start, end) (((val) & FLD_MASK(start, end)) >> (end))
+#define FLD_MOD(orig, val, start, end) \
+	(((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
+
+#define DISPC_MAX_FCK 173000000
+
+enum omap_burst_size {
+	OMAP_DSS_BURST_4x32 = 0,
+	OMAP_DSS_BURST_8x32 = 1,
+	OMAP_DSS_BURST_16x32 = 2,
+};
+
+enum omap_parallel_interface_mode {
+	OMAP_DSS_PARALLELMODE_BYPASS,		/* MIPI DPI */
+	OMAP_DSS_PARALLELMODE_RFBI,		/* MIPI DBI */
+	OMAP_DSS_PARALLELMODE_DSI,
+};
+
+enum dss_clock {
+	DSS_CLK_ICK	= 1 << 0,
+	DSS_CLK_FCK1	= 1 << 1,
+	DSS_CLK_FCK2	= 1 << 2,
+	DSS_CLK_54M	= 1 << 3,
+	DSS_CLK_96M	= 1 << 4,
+};
+
+struct dss_clock_info {
+	/* rates that we get with dividers below */
+	unsigned long fck;
+
+	/* dividers */
+	u16 fck_div;
+};
+
+struct dispc_clock_info {
+	/* rates that we get with dividers below */
+	unsigned long lck;
+	unsigned long pck;
+
+	/* dividers */
+	u16 lck_div;
+	u16 pck_div;
+};
+
+struct dsi_clock_info {
+	/* rates that we get with dividers below */
+	unsigned long fint;
+	unsigned long clkin4ddr;
+	unsigned long clkin;
+	unsigned long dsi1_pll_fclk;
+	unsigned long dsi2_pll_fclk;
+
+	unsigned long lp_clk;
+
+	/* dividers */
+	u16 regn;
+	u16 regm;
+	u16 regm3;
+	u16 regm4;
+
+	u16 lp_clk_div;
+
+	u8 highfreq;
+	bool use_dss2_fck;
+};
+
+struct seq_file;
+struct platform_device;
+
+/* core */
+void dss_clk_enable(enum dss_clock clks);
+void dss_clk_disable(enum dss_clock clks);
+unsigned long dss_clk_get_rate(enum dss_clock clk);
+int dss_need_ctx_restore(void);
+void dss_dump_clocks(struct seq_file *s);
+struct bus_type *dss_get_bus(void);
+
+/* display */
+int dss_suspend_all_devices(void);
+int dss_resume_all_devices(void);
+void dss_disable_all_devices(void);
+
+void dss_init_device(struct platform_device *pdev,
+		struct omap_dss_device *dssdev);
+void dss_uninit_device(struct platform_device *pdev,
+		struct omap_dss_device *dssdev);
+bool dss_use_replication(struct omap_dss_device *dssdev,
+		enum omap_color_mode mode);
+void default_get_overlay_fifo_thresholds(enum omap_plane plane,
+		u32 fifo_size, enum omap_burst_size *burst_size,
+		u32 *fifo_low, u32 *fifo_high);
+
+/* manager */
+int dss_init_overlay_managers(struct platform_device *pdev);
+void dss_uninit_overlay_managers(struct platform_device *pdev);
+int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl);
+void dss_setup_partial_planes(struct omap_dss_device *dssdev,
+				u16 *x, u16 *y, u16 *w, u16 *h);
+void dss_start_update(struct omap_dss_device *dssdev);
+
+/* overlay */
+void dss_init_overlays(struct platform_device *pdev);
+void dss_uninit_overlays(struct platform_device *pdev);
+int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev);
+void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr);
+#ifdef L4_EXAMPLE
+void dss_overlay_setup_l4_manager(struct omap_overlay_manager *mgr);
+#endif
+void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
+
+/* DSS */
+int dss_init(bool skip_init);
+void dss_exit(void);
+
+void dss_save_context(void);
+void dss_restore_context(void);
+
+void dss_dump_regs(struct seq_file *s);
+
+void dss_sdi_init(u8 datapairs);
+int dss_sdi_enable(void);
+void dss_sdi_disable(void);
+
+void dss_select_clk_source(bool dsi, bool dispc);
+int dss_get_dsi_clk_source(void);
+int dss_get_dispc_clk_source(void);
+void dss_set_venc_output(enum omap_dss_venc_type type);
+void dss_set_dac_pwrdn_bgz(bool enable);
+
+unsigned long dss_get_dpll4_rate(void);
+int dss_calc_clock_rates(struct dss_clock_info *cinfo);
+int dss_set_clock_div(struct dss_clock_info *cinfo);
+int dss_get_clock_div(struct dss_clock_info *cinfo);
+int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
+		struct dss_clock_info *dss_cinfo,
+		struct dispc_clock_info *dispc_cinfo);
+
+/* SDI */
+int sdi_init(bool skip_init);
+void sdi_exit(void);
+int sdi_init_display(struct omap_dss_device *display);
+
+/* DSI */
+int dsi_init(struct platform_device *pdev);
+void dsi_exit(void);
+
+void dsi_dump_clocks(struct seq_file *s);
+void dsi_dump_regs(struct seq_file *s);
+
+void dsi_save_context(void);
+void dsi_restore_context(void);
+
+int dsi_init_display(struct omap_dss_device *display);
+void dsi_irq_handler(void);
+unsigned long dsi_get_dsi1_pll_rate(void);
+int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo);
+int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck,
+		struct dsi_clock_info *cinfo,
+		struct dispc_clock_info *dispc_cinfo);
+int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk,
+		bool enable_hsdiv);
+void dsi_pll_uninit(void);
+void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
+		u32 fifo_size, enum omap_burst_size *burst_size,
+		u32 *fifo_low, u32 *fifo_high);
+
+/* DPI */
+int dpi_init(void);
+void dpi_exit(void);
+int dpi_init_display(struct omap_dss_device *dssdev);
+
+/* DISPC */
+int dispc_init(void);
+void dispc_exit(void);
+void dispc_dump_clocks(struct seq_file *s);
+void dispc_dump_regs(struct seq_file *s);
+void dispc_irq_handler(void);
+void dispc_fake_vsync_irq(void);
+
+void dispc_save_context(void);
+void dispc_restore_context(void);
+
+void dispc_enable_sidle(void);
+void dispc_disable_sidle(void);
+
+void dispc_lcd_enable_signal_polarity(bool act_high);
+void dispc_lcd_enable_signal(bool enable);
+void dispc_pck_free_enable(bool enable);
+void dispc_enable_fifohandcheck(bool enable);
+
+void dispc_set_lcd_size(u16 width, u16 height);
+void dispc_set_digit_size(u16 width, u16 height);
+u32 dispc_get_plane_fifo_size(enum omap_plane plane);
+void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high);
+void dispc_enable_fifomerge(bool enable);
+void dispc_set_burst_size(enum omap_plane plane,
+		enum omap_burst_size burst_size);
+
+void dispc_set_plane_ba0(enum omap_plane plane, u32 paddr);
+void dispc_set_plane_ba1(enum omap_plane plane, u32 paddr);
+void dispc_set_plane_pos(enum omap_plane plane, u16 x, u16 y);
+void dispc_set_plane_size(enum omap_plane plane, u16 width, u16 height);
+void dispc_set_channel_out(enum omap_plane plane,
+		enum omap_channel channel_out);
+
+int dispc_setup_plane(enum omap_plane plane,
+		      u32 paddr, u16 screen_width,
+		      u16 pos_x, u16 pos_y,
+		      u16 width, u16 height,
+		      u16 out_width, u16 out_height,
+		      enum omap_color_mode color_mode,
+		      bool ilace,
+		      enum omap_dss_rotation_type rotation_type,
+		      u8 rotation, bool mirror,
+		      u8 global_alpha);
+
+bool dispc_go_busy(enum omap_channel channel);
+void dispc_go(enum omap_channel channel);
+void dispc_enable_lcd_out(bool enable);
+void dispc_enable_digit_out(bool enable);
+int dispc_enable_plane(enum omap_plane plane, bool enable);
+void dispc_enable_replication(enum omap_plane plane, bool enable);
+
+void dispc_set_parallel_interface_mode(enum omap_parallel_interface_mode mode);
+void dispc_set_tft_data_lines(u8 data_lines);
+void dispc_set_lcd_display_type(enum omap_lcd_display_type type);
+void dispc_set_loadmode(enum omap_dss_load_mode mode);
+
+void dispc_set_default_color(enum omap_channel channel, u32 color);
+u32 dispc_get_default_color(enum omap_channel channel);
+void dispc_set_trans_key(enum omap_channel ch,
+		enum omap_dss_trans_key_type type,
+		u32 trans_key);
+void dispc_get_trans_key(enum omap_channel ch,
+		enum omap_dss_trans_key_type *type,
+		u32 *trans_key);
+void dispc_enable_trans_key(enum omap_channel ch, bool enable);
+void dispc_enable_alpha_blending(enum omap_channel ch, bool enable);
+bool dispc_trans_key_enabled(enum omap_channel ch);
+bool dispc_alpha_blending_enabled(enum omap_channel ch);
+
+bool dispc_lcd_timings_ok(struct omap_video_timings *timings);
+void dispc_set_lcd_timings(struct omap_video_timings *timings);
+unsigned long dispc_fclk_rate(void);
+unsigned long dispc_lclk_rate(void);
+unsigned long dispc_pclk_rate(void);
+void dispc_set_pol_freq(enum omap_panel_config config, u8 acbi, u8 acb);
+void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck,
+		struct dispc_clock_info *cinfo);
+int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
+		struct dispc_clock_info *cinfo);
+int dispc_set_clock_div(struct dispc_clock_info *cinfo);
+int dispc_get_clock_div(struct dispc_clock_info *cinfo);
+
+
+/* VENC */
+int venc_init(struct platform_device *pdev);
+void venc_exit(void);
+void venc_dump_regs(struct seq_file *s);
+int venc_init_display(struct omap_dss_device *display);
+
+/* RFBI */
+int rfbi_init(void);
+void rfbi_exit(void);
+void rfbi_dump_regs(struct seq_file *s);
+
+int rfbi_configure(int rfbi_module, int bpp, int lines);
+void rfbi_enable_rfbi(bool enable);
+void rfbi_transfer_area(u16 width, u16 height,
+			     void (callback)(void *data), void *data);
+void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t);
+unsigned long rfbi_get_max_tx_rate(void);
+int rfbi_init_display(struct omap_dss_device *display);
+
+#endif
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
new file mode 100644
index 0000000..27d9c46
--- /dev/null
+++ b/drivers/video/omap2/dss/manager.c
@@ -0,0 +1,1487 @@
+/*
+ * linux/drivers/video/omap2/dss/manager.c
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * Some code and ideas taken from drivers/video/omap/ driver
+ * by Imre Deak.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define DSS_SUBSYS_NAME "MANAGER"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/jiffies.h>
+
+#include <plat/display.h>
+#include <plat/cpu.h>
+
+#include "dss.h"
+
+static int num_managers;
+static struct list_head manager_list;
+
+static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%s\n", mgr->name);
+}
+
+static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%s\n",
+			mgr->device ? mgr->device->name : "<none>");
+}
+
+static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
+		const char *buf, size_t size)
+{
+	int r = 0;
+	size_t len = size;
+	struct omap_dss_device *dssdev = NULL;
+
+	int match(struct omap_dss_device *dssdev, void *data)
+	{
+		const char *str = data;
+		return sysfs_streq(dssdev->name, str);
+	}
+
+	if (buf[size-1] == '\n')
+		--len;
+
+	if (len > 0)
+		dssdev = omap_dss_find_device((void *)buf, match);
+
+	if (len > 0 && dssdev == NULL)
+		return -EINVAL;
+
+	if (dssdev)
+		DSSDBG("display %s found\n", dssdev->name);
+
+	if (mgr->device) {
+		r = mgr->unset_device(mgr);
+		if (r) {
+			DSSERR("failed to unset display\n");
+			goto put_device;
+		}
+	}
+
+	if (dssdev) {
+		r = mgr->set_device(mgr, dssdev);
+		if (r) {
+			DSSERR("failed to set manager\n");
+			goto put_device;
+		}
+
+		r = mgr->apply(mgr);
+		if (r) {
+			DSSERR("failed to apply dispc config\n");
+			goto put_device;
+		}
+	}
+
+put_device:
+	if (dssdev)
+		omap_dss_put_device(dssdev);
+
+	return r ? r : size;
+}
+
+static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr,
+					  char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.default_color);
+}
+
+static ssize_t manager_default_color_store(struct omap_overlay_manager *mgr,
+					   const char *buf, size_t size)
+{
+	struct omap_overlay_manager_info info;
+	u32 color;
+	int r;
+
+	if (sscanf(buf, "%d", &color) != 1)
+		return -EINVAL;
+
+	mgr->get_manager_info(mgr, &info);
+
+	info.default_color = color;
+
+	r = mgr->set_manager_info(mgr, &info);
+	if (r)
+		return r;
+
+	r = mgr->apply(mgr);
+	if (r)
+		return r;
+
+	return size;
+}
+
+static const char *trans_key_type_str[] = {
+	"gfx-destination",
+	"video-source",
+};
+
+static ssize_t manager_trans_key_type_show(struct omap_overlay_manager *mgr,
+					   char *buf)
+{
+	enum omap_dss_trans_key_type key_type;
+
+	key_type = mgr->info.trans_key_type;
+	BUG_ON(key_type >= ARRAY_SIZE(trans_key_type_str));
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", trans_key_type_str[key_type]);
+}
+
+static ssize_t manager_trans_key_type_store(struct omap_overlay_manager *mgr,
+					    const char *buf, size_t size)
+{
+	enum omap_dss_trans_key_type key_type;
+	struct omap_overlay_manager_info info;
+	int r;
+
+	for (key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
+			key_type < ARRAY_SIZE(trans_key_type_str); key_type++) {
+		if (sysfs_streq(buf, trans_key_type_str[key_type]))
+			break;
+	}
+
+	if (key_type == ARRAY_SIZE(trans_key_type_str))
+		return -EINVAL;
+
+	mgr->get_manager_info(mgr, &info);
+
+	info.trans_key_type = key_type;
+
+	r = mgr->set_manager_info(mgr, &info);
+	if (r)
+		return r;
+
+	r = mgr->apply(mgr);
+	if (r)
+		return r;
+
+	return size;
+}
+
+static ssize_t manager_trans_key_value_show(struct omap_overlay_manager *mgr,
+					    char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.trans_key);
+}
+
+static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr,
+					     const char *buf, size_t size)
+{
+	struct omap_overlay_manager_info info;
+	u32 key_value;
+	int r;
+
+	if (sscanf(buf, "%d", &key_value) != 1)
+		return -EINVAL;
+
+	mgr->get_manager_info(mgr, &info);
+
+	info.trans_key = key_value;
+
+	r = mgr->set_manager_info(mgr, &info);
+	if (r)
+		return r;
+
+	r = mgr->apply(mgr);
+	if (r)
+		return r;
+
+	return size;
+}
+
+static ssize_t manager_trans_key_enabled_show(struct omap_overlay_manager *mgr,
+					      char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.trans_enabled);
+}
+
+static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr,
+					       const char *buf, size_t size)
+{
+	struct omap_overlay_manager_info info;
+	int enable;
+	int r;
+
+	if (sscanf(buf, "%d", &enable) != 1)
+		return -EINVAL;
+
+	mgr->get_manager_info(mgr, &info);
+
+	info.trans_enabled = enable ? true : false;
+
+	r = mgr->set_manager_info(mgr, &info);
+	if (r)
+		return r;
+
+	r = mgr->apply(mgr);
+	if (r)
+		return r;
+
+	return size;
+}
+
+static ssize_t manager_alpha_blending_enabled_show(
+		struct omap_overlay_manager *mgr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.alpha_enabled);
+}
+
+static ssize_t manager_alpha_blending_enabled_store(
+		struct omap_overlay_manager *mgr,
+		const char *buf, size_t size)
+{
+	struct omap_overlay_manager_info info;
+	int enable;
+	int r;
+
+	if (sscanf(buf, "%d", &enable) != 1)
+		return -EINVAL;
+
+	mgr->get_manager_info(mgr, &info);
+
+	info.alpha_enabled = enable ? true : false;
+
+	r = mgr->set_manager_info(mgr, &info);
+	if (r)
+		return r;
+
+	r = mgr->apply(mgr);
+	if (r)
+		return r;
+
+	return size;
+}
+
+struct manager_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct omap_overlay_manager *, char *);
+	ssize_t	(*store)(struct omap_overlay_manager *, const char *, size_t);
+};
+
+#define MANAGER_ATTR(_name, _mode, _show, _store) \
+	struct manager_attribute manager_attr_##_name = \
+	__ATTR(_name, _mode, _show, _store)
+
+static MANAGER_ATTR(name, S_IRUGO, manager_name_show, NULL);
+static MANAGER_ATTR(display, S_IRUGO|S_IWUSR,
+		manager_display_show, manager_display_store);
+static MANAGER_ATTR(default_color, S_IRUGO|S_IWUSR,
+		manager_default_color_show, manager_default_color_store);
+static MANAGER_ATTR(trans_key_type, S_IRUGO|S_IWUSR,
+		manager_trans_key_type_show, manager_trans_key_type_store);
+static MANAGER_ATTR(trans_key_value, S_IRUGO|S_IWUSR,
+		manager_trans_key_value_show, manager_trans_key_value_store);
+static MANAGER_ATTR(trans_key_enabled, S_IRUGO|S_IWUSR,
+		manager_trans_key_enabled_show,
+		manager_trans_key_enabled_store);
+static MANAGER_ATTR(alpha_blending_enabled, S_IRUGO|S_IWUSR,
+		manager_alpha_blending_enabled_show,
+		manager_alpha_blending_enabled_store);
+
+
+static struct attribute *manager_sysfs_attrs[] = {
+	&manager_attr_name.attr,
+	&manager_attr_display.attr,
+	&manager_attr_default_color.attr,
+	&manager_attr_trans_key_type.attr,
+	&manager_attr_trans_key_value.attr,
+	&manager_attr_trans_key_enabled.attr,
+	&manager_attr_alpha_blending_enabled.attr,
+	NULL
+};
+
+static ssize_t manager_attr_show(struct kobject *kobj, struct attribute *attr,
+		char *buf)
+{
+	struct omap_overlay_manager *manager;
+	struct manager_attribute *manager_attr;
+
+	manager = container_of(kobj, struct omap_overlay_manager, kobj);
+	manager_attr = container_of(attr, struct manager_attribute, attr);
+
+	if (!manager_attr->show)
+		return -ENOENT;
+
+	return manager_attr->show(manager, buf);
+}
+
+static ssize_t manager_attr_store(struct kobject *kobj, struct attribute *attr,
+		const char *buf, size_t size)
+{
+	struct omap_overlay_manager *manager;
+	struct manager_attribute *manager_attr;
+
+	manager = container_of(kobj, struct omap_overlay_manager, kobj);
+	manager_attr = container_of(attr, struct manager_attribute, attr);
+
+	if (!manager_attr->store)
+		return -ENOENT;
+
+	return manager_attr->store(manager, buf, size);
+}
+
+static struct sysfs_ops manager_sysfs_ops = {
+	.show = manager_attr_show,
+	.store = manager_attr_store,
+};
+
+static struct kobj_type manager_ktype = {
+	.sysfs_ops = &manager_sysfs_ops,
+	.default_attrs = manager_sysfs_attrs,
+};
+
+/*
+ * We have 4 levels of cache for the dispc settings. First two are in SW and
+ * the latter two in HW.
+ *
+ * +--------------------+
+ * |overlay/manager_info|
+ * +--------------------+
+ *          v
+ *        apply()
+ *          v
+ * +--------------------+
+ * |     dss_cache      |
+ * +--------------------+
+ *          v
+ *      configure()
+ *          v
+ * +--------------------+
+ * |  shadow registers  |
+ * +--------------------+
+ *          v
+ * VFP or lcd/digit_enable
+ *          v
+ * +--------------------+
+ * |      registers     |
+ * +--------------------+
+ */
+
+struct overlay_cache_data {
+	/* If true, cache changed, but not written to shadow registers. Set
+	 * in apply(), cleared when registers written. */
+	bool dirty;
+	/* If true, shadow registers contain changed values not yet in real
+	 * registers. Set when writing to shadow registers, cleared at
+	 * VSYNC/EVSYNC */
+	bool shadow_dirty;
+
+	bool enabled;
+
+	u32 paddr;
+	void __iomem *vaddr;
+	u16 screen_width;
+	u16 width;
+	u16 height;
+	enum omap_color_mode color_mode;
+	u8 rotation;
+	enum omap_dss_rotation_type rotation_type;
+	bool mirror;
+
+	u16 pos_x;
+	u16 pos_y;
+	u16 out_width;	/* if 0, out_width == width */
+	u16 out_height;	/* if 0, out_height == height */
+	u8 global_alpha;
+
+	enum omap_channel channel;
+	bool replication;
+	bool ilace;
+
+	enum omap_burst_size burst_size;
+	u32 fifo_low;
+	u32 fifo_high;
+
+	bool manual_update;
+};
+
+struct manager_cache_data {
+	/* If true, cache changed, but not written to shadow registers. Set
+	 * in apply(), cleared when registers written. */
+	bool dirty;
+	/* If true, shadow registers contain changed values not yet in real
+	 * registers. Set when writing to shadow registers, cleared at
+	 * VSYNC/EVSYNC */
+	bool shadow_dirty;
+
+	u32 default_color;
+
+	enum omap_dss_trans_key_type trans_key_type;
+	u32 trans_key;
+	bool trans_enabled;
+
+	bool alpha_enabled;
+
+	bool manual_upd_display;
+	bool manual_update;
+	bool do_manual_update;
+
+	/* manual update region */
+	u16 x, y, w, h;
+};
+
+static struct {
+	spinlock_t lock;
+	struct overlay_cache_data overlay_cache[3];
+	struct manager_cache_data manager_cache[2];
+
+	bool irq_enabled;
+} dss_cache;
+
+
+
+static int omap_dss_set_device(struct omap_overlay_manager *mgr,
+		struct omap_dss_device *dssdev)
+{
+	int i;
+	int r;
+
+	if (dssdev->manager) {
+		DSSERR("display '%s' already has a manager '%s'\n",
+			       dssdev->name, dssdev->manager->name);
+		return -EINVAL;
+	}
+
+	if ((mgr->supported_displays & dssdev->type) == 0) {
+		DSSERR("display '%s' does not support manager '%s'\n",
+			       dssdev->name, mgr->name);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < mgr->num_overlays; i++) {
+		struct omap_overlay *ovl = mgr->overlays[i];
+
+		if (ovl->manager != mgr || !ovl->info.enabled)
+			continue;
+
+		r = dss_check_overlay(ovl, dssdev);
+		if (r)
+			return r;
+	}
+
+	dssdev->manager = mgr;
+	mgr->device = dssdev;
+	mgr->device_changed = true;
+
+	return 0;
+}
+
+static int omap_dss_unset_device(struct omap_overlay_manager *mgr)
+{
+	if (!mgr->device) {
+		DSSERR("failed to unset display, display not set.\n");
+		return -EINVAL;
+	}
+
+	mgr->device->manager = NULL;
+	mgr->device = NULL;
+	mgr->device_changed = true;
+
+	return 0;
+}
+
+static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
+{
+	unsigned long timeout = msecs_to_jiffies(500);
+	struct manager_cache_data *mc;
+	enum omap_channel channel;
+	u32 irq;
+	int r;
+	int i;
+
+	if (!mgr->device)
+		return 0;
+
+	if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) {
+		irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
+		channel = OMAP_DSS_CHANNEL_DIGIT;
+	} else {
+		if (mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
+			enum omap_dss_update_mode mode;
+			mode = mgr->device->get_update_mode(mgr->device);
+			if (mode != OMAP_DSS_UPDATE_AUTO)
+				return 0;
+
+			irq = DISPC_IRQ_FRAMEDONE;
+		} else {
+			irq = DISPC_IRQ_VSYNC;
+		}
+		channel = OMAP_DSS_CHANNEL_LCD;
+	}
+
+	mc = &dss_cache.manager_cache[mgr->id];
+	i = 0;
+	while (1) {
+		unsigned long flags;
+		bool shadow_dirty, dirty;
+
+		spin_lock_irqsave(&dss_cache.lock, flags);
+		dirty = mc->dirty;
+		shadow_dirty = mc->shadow_dirty;
+		spin_unlock_irqrestore(&dss_cache.lock, flags);
+
+		if (!dirty && !shadow_dirty) {
+			r = 0;
+			break;
+		}
+
+		/* 4 iterations is the worst case:
+		 * 1 - initial iteration, dirty = true (between VFP and VSYNC)
+		 * 2 - first VSYNC, dirty = true
+		 * 3 - dirty = false, shadow_dirty = true
+		 * 4 - shadow_dirty = false */
+		if (i++ == 3) {
+			DSSERR("mgr(%d)->wait_for_go() not finishing\n",
+					mgr->id);
+			r = 0;
+			break;
+		}
+
+		r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
+		if (r == -ERESTARTSYS)
+			break;
+
+		if (r) {
+			DSSERR("mgr(%d)->wait_for_go() timeout\n", mgr->id);
+			break;
+		}
+	}
+
+	return r;
+}
+
+int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
+{
+	unsigned long timeout = msecs_to_jiffies(500);
+	enum omap_channel channel;
+	struct overlay_cache_data *oc;
+	struct omap_dss_device *dssdev;
+	u32 irq;
+	int r;
+	int i;
+
+	if (!ovl->manager || !ovl->manager->device)
+		return 0;
+
+	dssdev = ovl->manager->device;
+
+	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
+		irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
+		channel = OMAP_DSS_CHANNEL_DIGIT;
+	} else {
+		if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
+			enum omap_dss_update_mode mode;
+			mode = dssdev->get_update_mode(dssdev);
+			if (mode != OMAP_DSS_UPDATE_AUTO)
+				return 0;
+
+			irq = DISPC_IRQ_FRAMEDONE;
+		} else {
+			irq = DISPC_IRQ_VSYNC;
+		}
+		channel = OMAP_DSS_CHANNEL_LCD;
+	}
+
+	oc = &dss_cache.overlay_cache[ovl->id];
+	i = 0;
+	while (1) {
+		unsigned long flags;
+		bool shadow_dirty, dirty;
+
+		spin_lock_irqsave(&dss_cache.lock, flags);
+		dirty = oc->dirty;
+		shadow_dirty = oc->shadow_dirty;
+		spin_unlock_irqrestore(&dss_cache.lock, flags);
+
+		if (!dirty && !shadow_dirty) {
+			r = 0;
+			break;
+		}
+
+		/* 4 iterations is the worst case:
+		 * 1 - initial iteration, dirty = true (between VFP and VSYNC)
+		 * 2 - first VSYNC, dirty = true
+		 * 3 - dirty = false, shadow_dirty = true
+		 * 4 - shadow_dirty = false */
+		if (i++ == 3) {
+			DSSERR("ovl(%d)->wait_for_go() not finishing\n",
+					ovl->id);
+			r = 0;
+			break;
+		}
+
+		r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
+		if (r == -ERESTARTSYS)
+			break;
+
+		if (r) {
+			DSSERR("ovl(%d)->wait_for_go() timeout\n", ovl->id);
+			break;
+		}
+	}
+
+	return r;
+}
+
+static int overlay_enabled(struct omap_overlay *ovl)
+{
+	return ovl->info.enabled && ovl->manager && ovl->manager->device;
+}
+
+/* Is rect1 a subset of rect2? */
+static bool rectangle_subset(int x1, int y1, int w1, int h1,
+		int x2, int y2, int w2, int h2)
+{
+	if (x1 < x2 || y1 < y2)
+		return false;
+
+	if (x1 + w1 > x2 + w2)
+		return false;
+
+	if (y1 + h1 > y2 + h2)
+		return false;
+
+	return true;
+}
+
+/* Do rect1 and rect2 overlap? */
+static bool rectangle_intersects(int x1, int y1, int w1, int h1,
+		int x2, int y2, int w2, int h2)
+{
+	if (x1 >= x2 + w2)
+		return false;
+
+	if (x2 >= x1 + w1)
+		return false;
+
+	if (y1 >= y2 + h2)
+		return false;
+
+	if (y2 >= y1 + h1)
+		return false;
+
+	return true;
+}
+
+static bool dispc_is_overlay_scaled(struct overlay_cache_data *oc)
+{
+	if (oc->out_width != 0 && oc->width != oc->out_width)
+		return true;
+
+	if (oc->out_height != 0 && oc->height != oc->out_height)
+		return true;
+
+	return false;
+}
+
+static int configure_overlay(enum omap_plane plane)
+{
+	struct overlay_cache_data *c;
+	struct manager_cache_data *mc;
+	u16 outw, outh;
+	u16 x, y, w, h;
+	u32 paddr;
+	int r;
+
+	DSSDBGF("%d", plane);
+
+	c = &dss_cache.overlay_cache[plane];
+
+	if (!c->enabled) {
+		dispc_enable_plane(plane, 0);
+		return 0;
+	}
+
+	mc = &dss_cache.manager_cache[c->channel];
+
+	x = c->pos_x;
+	y = c->pos_y;
+	w = c->width;
+	h = c->height;
+	outw = c->out_width == 0 ? c->width : c->out_width;
+	outh = c->out_height == 0 ? c->height : c->out_height;
+	paddr = c->paddr;
+
+	if (c->manual_update && mc->do_manual_update) {
+		unsigned bpp;
+		/* If the overlay is outside the update region, disable it */
+		if (!rectangle_intersects(mc->x, mc->y, mc->w, mc->h,
+					x, y, outw, outh)) {
+			dispc_enable_plane(plane, 0);
+			return 0;
+		}
+
+		switch (c->color_mode) {
+		case OMAP_DSS_COLOR_RGB16:
+		case OMAP_DSS_COLOR_ARGB16:
+		case OMAP_DSS_COLOR_YUV2:
+		case OMAP_DSS_COLOR_UYVY:
+			bpp = 16;
+			break;
+
+		case OMAP_DSS_COLOR_RGB24P:
+			bpp = 24;
+			break;
+
+		case OMAP_DSS_COLOR_RGB24U:
+		case OMAP_DSS_COLOR_ARGB32:
+		case OMAP_DSS_COLOR_RGBA32:
+		case OMAP_DSS_COLOR_RGBX32:
+			bpp = 32;
+			break;
+
+		default:
+			BUG();
+		}
+
+		if (dispc_is_overlay_scaled(c)) {
+			/* If the overlay is scaled, the update area has
+			 * already been enlarged to cover the whole overlay. We
+			 * only need to adjust x/y here */
+			x = c->pos_x - mc->x;
+			y = c->pos_y - mc->y;
+		} else {
+			if (mc->x > c->pos_x) {
+				x = 0;
+				w -= (mc->x - c->pos_x);
+				paddr += (mc->x - c->pos_x) * bpp / 8;
+			} else {
+				x = c->pos_x - mc->x;
+			}
+
+			if (mc->y > c->pos_y) {
+				y = 0;
+				h -= (mc->y - c->pos_y);
+				paddr += (mc->y - c->pos_y) * c->screen_width *
+					bpp / 8;
+			} else {
+				y = c->pos_y - mc->y;
+			}
+
+			if (mc->w < (x+w))
+				w -= (x+w) - (mc->w);
+
+			if (mc->h < (y+h))
+				h -= (y+h) - (mc->h);
+
+			outw = w;
+			outh = h;
+		}
+	}
+
+	r = dispc_setup_plane(plane,
+			paddr,
+			c->screen_width,
+			x, y,
+			w, h,
+			outw, outh,
+			c->color_mode,
+			c->ilace,
+			c->rotation_type,
+			c->rotation,
+			c->mirror,
+			c->global_alpha);
+
+	if (r) {
+		/* this shouldn't happen */
+		DSSERR("dispc_setup_plane failed for ovl %d\n", plane);
+		dispc_enable_plane(plane, 0);
+		return r;
+	}
+
+	dispc_enable_replication(plane, c->replication);
+
+	dispc_set_burst_size(plane, c->burst_size);
+	dispc_setup_plane_fifo(plane, c->fifo_low, c->fifo_high);
+
+	dispc_enable_plane(plane, 1);
+
+	return 0;
+}
+
+static void configure_manager(enum omap_channel channel)
+{
+	struct manager_cache_data *c;
+
+	DSSDBGF("%d", channel);
+
+	c = &dss_cache.manager_cache[channel];
+
+	dispc_set_trans_key(channel, c->trans_key_type, c->trans_key);
+	dispc_enable_trans_key(channel, c->trans_enabled);
+	dispc_enable_alpha_blending(channel, c->alpha_enabled);
+}
+
+/* configure_dispc() tries to write values from cache to shadow registers.
+ * It writes only to those managers/overlays that are not busy.
+ * returns 0 if everything could be written to shadow registers.
+ * returns 1 if not everything could be written to shadow registers. */
+static int configure_dispc(void)
+{
+	struct overlay_cache_data *oc;
+	struct manager_cache_data *mc;
+	const int num_ovls = ARRAY_SIZE(dss_cache.overlay_cache);
+	const int num_mgrs = ARRAY_SIZE(dss_cache.manager_cache);
+	int i;
+	int r;
+	bool mgr_busy[2];
+	bool mgr_go[2];
+	bool busy;
+
+	r = 0;
+	busy = false;
+
+	mgr_busy[0] = dispc_go_busy(0);
+	mgr_busy[1] = dispc_go_busy(1);
+	mgr_go[0] = false;
+	mgr_go[1] = false;
+
+	/* Commit overlay settings */
+	for (i = 0; i < num_ovls; ++i) {
+		oc = &dss_cache.overlay_cache[i];
+		mc = &dss_cache.manager_cache[oc->channel];
+
+		if (!oc->dirty)
+			continue;
+
+		if (oc->manual_update && !mc->do_manual_update)
+			continue;
+
+		if (mgr_busy[oc->channel]) {
+			busy = true;
+			continue;
+		}
+
+		r = configure_overlay(i);
+		if (r)
+			DSSERR("configure_overlay %d failed\n", i);
+
+		oc->dirty = false;
+		oc->shadow_dirty = true;
+		mgr_go[oc->channel] = true;
+	}
+
+	/* Commit manager settings */
+	for (i = 0; i < num_mgrs; ++i) {
+		mc = &dss_cache.manager_cache[i];
+
+		if (!mc->dirty)
+			continue;
+
+		if (mc->manual_update && !mc->do_manual_update)
+			continue;
+
+		if (mgr_busy[i]) {
+			busy = true;
+			continue;
+		}
+
+		configure_manager(i);
+		mc->dirty = false;
+		mc->shadow_dirty = true;
+		mgr_go[i] = true;
+	}
+
+	/* set GO */
+	for (i = 0; i < num_mgrs; ++i) {
+		mc = &dss_cache.manager_cache[i];
+
+		if (!mgr_go[i])
+			continue;
+
+		/* We don't need GO with manual update display. LCD iface will
+		 * always be turned off after frame, and new settings will be
+		 * taken in to use at next update */
+		if (!mc->manual_upd_display)
+			dispc_go(i);
+	}
+
+	if (busy)
+		r = 1;
+	else
+		r = 0;
+
+	return r;
+}
+
+/* Configure dispc for partial update. Return possibly modified update
+ * area */
+void dss_setup_partial_planes(struct omap_dss_device *dssdev,
+		u16 *xi, u16 *yi, u16 *wi, u16 *hi)
+{
+	struct overlay_cache_data *oc;
+	struct manager_cache_data *mc;
+	const int num_ovls = ARRAY_SIZE(dss_cache.overlay_cache);
+	struct omap_overlay_manager *mgr;
+	int i;
+	u16 x, y, w, h;
+	unsigned long flags;
+
+	x = *xi;
+	y = *yi;
+	w = *wi;
+	h = *hi;
+
+	DSSDBG("dispc_setup_partial_planes %d,%d %dx%d\n",
+		*xi, *yi, *wi, *hi);
+
+	mgr = dssdev->manager;
+
+	if (!mgr) {
+		DSSDBG("no manager\n");
+		return;
+	}
+
+	spin_lock_irqsave(&dss_cache.lock, flags);
+
+	/* We need to show the whole overlay if it is scaled. So look for
+	 * those, and make the update area larger if found.
+	 * Also mark the overlay cache dirty */
+	for (i = 0; i < num_ovls; ++i) {
+		unsigned x1, y1, x2, y2;
+		unsigned outw, outh;
+
+		oc = &dss_cache.overlay_cache[i];
+
+		if (oc->channel != mgr->id)
+			continue;
+
+		oc->dirty = true;
+
+		if (!oc->enabled)
+			continue;
+
+		if (!dispc_is_overlay_scaled(oc))
+			continue;
+
+		outw = oc->out_width == 0 ? oc->width : oc->out_width;
+		outh = oc->out_height == 0 ? oc->height : oc->out_height;
+
+		/* is the overlay outside the update region? */
+		if (!rectangle_intersects(x, y, w, h,
+					oc->pos_x, oc->pos_y,
+					outw, outh))
+			continue;
+
+		/* if the overlay totally inside the update region? */
+		if (rectangle_subset(oc->pos_x, oc->pos_y, outw, outh,
+					x, y, w, h))
+			continue;
+
+		if (x > oc->pos_x)
+			x1 = oc->pos_x;
+		else
+			x1 = x;
+
+		if (y > oc->pos_y)
+			y1 = oc->pos_y;
+		else
+			y1 = y;
+
+		if ((x + w) < (oc->pos_x + outw))
+			x2 = oc->pos_x + outw;
+		else
+			x2 = x + w;
+
+		if ((y + h) < (oc->pos_y + outh))
+			y2 = oc->pos_y + outh;
+		else
+			y2 = y + h;
+
+		x = x1;
+		y = y1;
+		w = x2 - x1;
+		h = y2 - y1;
+
+		DSSDBG("changing upd area due to ovl(%d) scaling %d,%d %dx%d\n",
+				i, x, y, w, h);
+	}
+
+	mc = &dss_cache.manager_cache[mgr->id];
+	mc->do_manual_update = true;
+	mc->x = x;
+	mc->y = y;
+	mc->w = w;
+	mc->h = h;
+
+	configure_dispc();
+
+	mc->do_manual_update = false;
+
+	spin_unlock_irqrestore(&dss_cache.lock, flags);
+
+	*xi = x;
+	*yi = y;
+	*wi = w;
+	*hi = h;
+}
+
+void dss_start_update(struct omap_dss_device *dssdev)
+{
+	struct manager_cache_data *mc;
+	struct overlay_cache_data *oc;
+	const int num_ovls = ARRAY_SIZE(dss_cache.overlay_cache);
+	const int num_mgrs = ARRAY_SIZE(dss_cache.manager_cache);
+	struct omap_overlay_manager *mgr;
+	int i;
+
+	mgr = dssdev->manager;
+
+	for (i = 0; i < num_ovls; ++i) {
+		oc = &dss_cache.overlay_cache[i];
+		if (oc->channel != mgr->id)
+			continue;
+
+		oc->shadow_dirty = false;
+	}
+
+	for (i = 0; i < num_mgrs; ++i) {
+		mc = &dss_cache.manager_cache[i];
+		if (mgr->id != i)
+			continue;
+
+		mc->shadow_dirty = false;
+	}
+
+	dispc_enable_lcd_out(1);
+}
+
+static void dss_apply_irq_handler(void *data, u32 mask)
+{
+	struct manager_cache_data *mc;
+	struct overlay_cache_data *oc;
+	const int num_ovls = ARRAY_SIZE(dss_cache.overlay_cache);
+	const int num_mgrs = ARRAY_SIZE(dss_cache.manager_cache);
+	int i, r;
+	bool mgr_busy[2];
+
+	mgr_busy[0] = dispc_go_busy(0);
+	mgr_busy[1] = dispc_go_busy(1);
+
+	spin_lock(&dss_cache.lock);
+
+	for (i = 0; i < num_ovls; ++i) {
+		oc = &dss_cache.overlay_cache[i];
+		if (!mgr_busy[oc->channel])
+			oc->shadow_dirty = false;
+	}
+
+	for (i = 0; i < num_mgrs; ++i) {
+		mc = &dss_cache.manager_cache[i];
+		if (!mgr_busy[i])
+			mc->shadow_dirty = false;
+	}
+
+	r = configure_dispc();
+	if (r == 1)
+		goto end;
+
+	/* re-read busy flags */
+	mgr_busy[0] = dispc_go_busy(0);
+	mgr_busy[1] = dispc_go_busy(1);
+
+	/* keep running as long as there are busy managers, so that
+	 * we can collect overlay-applied information */
+	for (i = 0; i < num_mgrs; ++i) {
+		if (mgr_busy[i])
+			goto end;
+	}
+
+	omap_dispc_unregister_isr(dss_apply_irq_handler, NULL,
+			DISPC_IRQ_VSYNC	| DISPC_IRQ_EVSYNC_ODD |
+			DISPC_IRQ_EVSYNC_EVEN);
+	dss_cache.irq_enabled = false;
+
+end:
+	spin_unlock(&dss_cache.lock);
+}
+
+static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
+{
+	struct overlay_cache_data *oc;
+	struct manager_cache_data *mc;
+	int i;
+	struct omap_overlay *ovl;
+	int num_planes_enabled = 0;
+	bool use_fifomerge;
+	unsigned long flags;
+	int r;
+
+	DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
+
+	spin_lock_irqsave(&dss_cache.lock, flags);
+
+	/* Configure overlays */
+	for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
+		struct omap_dss_device *dssdev;
+
+		ovl = omap_dss_get_overlay(i);
+
+		if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
+			continue;
+
+		oc = &dss_cache.overlay_cache[ovl->id];
+
+		if (!overlay_enabled(ovl)) {
+			if (oc->enabled) {
+				oc->enabled = false;
+				oc->dirty = true;
+			}
+			continue;
+		}
+
+		if (!ovl->info_dirty) {
+			if (oc->enabled)
+				++num_planes_enabled;
+			continue;
+		}
+
+		dssdev = ovl->manager->device;
+
+		if (dss_check_overlay(ovl, dssdev)) {
+			if (oc->enabled) {
+				oc->enabled = false;
+				oc->dirty = true;
+			}
+			continue;
+		}
+
+		ovl->info_dirty = false;
+		oc->dirty = true;
+
+		oc->paddr = ovl->info.paddr;
+		oc->vaddr = ovl->info.vaddr;
+		oc->screen_width = ovl->info.screen_width;
+		oc->width = ovl->info.width;
+		oc->height = ovl->info.height;
+		oc->color_mode = ovl->info.color_mode;
+		oc->rotation = ovl->info.rotation;
+		oc->rotation_type = ovl->info.rotation_type;
+		oc->mirror = ovl->info.mirror;
+		oc->pos_x = ovl->info.pos_x;
+		oc->pos_y = ovl->info.pos_y;
+		oc->out_width = ovl->info.out_width;
+		oc->out_height = ovl->info.out_height;
+		oc->global_alpha = ovl->info.global_alpha;
+
+		oc->replication =
+			dss_use_replication(dssdev, ovl->info.color_mode);
+
+		oc->ilace = dssdev->type == OMAP_DISPLAY_TYPE_VENC;
+
+		oc->channel = ovl->manager->id;
+
+		oc->enabled = true;
+
+		oc->manual_update =
+			dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE &&
+			dssdev->get_update_mode(dssdev) != OMAP_DSS_UPDATE_AUTO;
+
+		++num_planes_enabled;
+	}
+
+	/* Configure managers */
+	list_for_each_entry(mgr, &manager_list, list) {
+		struct omap_dss_device *dssdev;
+
+		if (!(mgr->caps & OMAP_DSS_OVL_MGR_CAP_DISPC))
+			continue;
+
+		mc = &dss_cache.manager_cache[mgr->id];
+
+		if (mgr->device_changed) {
+			mgr->device_changed = false;
+			mgr->info_dirty  = true;
+		}
+
+		if (!mgr->info_dirty)
+			continue;
+
+		if (!mgr->device)
+			continue;
+
+		dssdev = mgr->device;
+
+		mgr->info_dirty = false;
+		mc->dirty = true;
+
+		mc->default_color = mgr->info.default_color;
+		mc->trans_key_type = mgr->info.trans_key_type;
+		mc->trans_key = mgr->info.trans_key;
+		mc->trans_enabled = mgr->info.trans_enabled;
+		mc->alpha_enabled = mgr->info.alpha_enabled;
+
+		mc->manual_upd_display =
+			dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
+
+		mc->manual_update =
+			dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE &&
+			dssdev->get_update_mode(dssdev) != OMAP_DSS_UPDATE_AUTO;
+	}
+
+	/* XXX TODO: Try to get fifomerge working. The problem is that it
+	 * affects both managers, not individually but at the same time. This
+	 * means the change has to be well synchronized. I guess the proper way
+	 * is to have a two step process for fifo merge:
+	 *        fifomerge enable:
+	 *             1. disable other planes, leaving one plane enabled
+	 *             2. wait until the planes are disabled on HW
+	 *             3. config merged fifo thresholds, enable fifomerge
+	 *        fifomerge disable:
+	 *             1. config unmerged fifo thresholds, disable fifomerge
+	 *             2. wait until fifo changes are in HW
+	 *             3. enable planes
+	 */
+	use_fifomerge = false;
+
+	/* Configure overlay fifos */
+	for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
+		struct omap_dss_device *dssdev;
+		u32 size;
+
+		ovl = omap_dss_get_overlay(i);
+
+		if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
+			continue;
+
+		oc = &dss_cache.overlay_cache[ovl->id];
+
+		if (!oc->enabled)
+			continue;
+
+		dssdev = ovl->manager->device;
+
+		size = dispc_get_plane_fifo_size(ovl->id);
+		if (use_fifomerge)
+			size *= 3;
+
+		switch (dssdev->type) {
+		case OMAP_DISPLAY_TYPE_DPI:
+		case OMAP_DISPLAY_TYPE_DBI:
+		case OMAP_DISPLAY_TYPE_SDI:
+		case OMAP_DISPLAY_TYPE_VENC:
+			default_get_overlay_fifo_thresholds(ovl->id, size,
+					&oc->burst_size, &oc->fifo_low,
+					&oc->fifo_high);
+			break;
+#ifdef CONFIG_OMAP2_DSS_DSI
+		case OMAP_DISPLAY_TYPE_DSI:
+			dsi_get_overlay_fifo_thresholds(ovl->id, size,
+					&oc->burst_size, &oc->fifo_low,
+					&oc->fifo_high);
+			break;
+#endif
+		default:
+			BUG();
+		}
+	}
+
+	r = 0;
+	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+	if (!dss_cache.irq_enabled) {
+		r = omap_dispc_register_isr(dss_apply_irq_handler, NULL,
+				DISPC_IRQ_VSYNC	| DISPC_IRQ_EVSYNC_ODD |
+				DISPC_IRQ_EVSYNC_EVEN);
+		dss_cache.irq_enabled = true;
+	}
+	configure_dispc();
+	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+
+	spin_unlock_irqrestore(&dss_cache.lock, flags);
+
+	return r;
+}
+
+static int dss_check_manager(struct omap_overlay_manager *mgr)
+{
+	/* OMAP supports only graphics source transparency color key and alpha
+	 * blending simultaneously. See TRM 15.4.2.4.2.2 Alpha Mode */
+
+	if (mgr->info.alpha_enabled && mgr->info.trans_enabled &&
+			mgr->info.trans_key_type != OMAP_DSS_COLOR_KEY_GFX_DST)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int omap_dss_mgr_set_info(struct omap_overlay_manager *mgr,
+		struct omap_overlay_manager_info *info)
+{
+	int r;
+	struct omap_overlay_manager_info old_info;
+
+	old_info = mgr->info;
+	mgr->info = *info;
+
+	r = dss_check_manager(mgr);
+	if (r) {
+		mgr->info = old_info;
+		return r;
+	}
+
+	mgr->info_dirty = true;
+
+	return 0;
+}
+
+static void omap_dss_mgr_get_info(struct omap_overlay_manager *mgr,
+		struct omap_overlay_manager_info *info)
+{
+	*info = mgr->info;
+}
+
+static void omap_dss_add_overlay_manager(struct omap_overlay_manager *manager)
+{
+	++num_managers;
+	list_add_tail(&manager->list, &manager_list);
+}
+
+int dss_init_overlay_managers(struct platform_device *pdev)
+{
+	int i, r;
+
+	spin_lock_init(&dss_cache.lock);
+
+	INIT_LIST_HEAD(&manager_list);
+
+	num_managers = 0;
+
+	for (i = 0; i < 2; ++i) {
+		struct omap_overlay_manager *mgr;
+		mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
+
+		BUG_ON(mgr == NULL);
+
+		switch (i) {
+		case 0:
+			mgr->name = "lcd";
+			mgr->id = OMAP_DSS_CHANNEL_LCD;
+			mgr->supported_displays =
+				OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
+				OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI;
+			break;
+		case 1:
+			mgr->name = "tv";
+			mgr->id = OMAP_DSS_CHANNEL_DIGIT;
+			mgr->supported_displays = OMAP_DISPLAY_TYPE_VENC;
+			break;
+		}
+
+		mgr->set_device = &omap_dss_set_device;
+		mgr->unset_device = &omap_dss_unset_device;
+		mgr->apply = &omap_dss_mgr_apply;
+		mgr->set_manager_info = &omap_dss_mgr_set_info;
+		mgr->get_manager_info = &omap_dss_mgr_get_info;
+		mgr->wait_for_go = &dss_mgr_wait_for_go;
+
+		mgr->caps = OMAP_DSS_OVL_MGR_CAP_DISPC;
+
+		dss_overlay_setup_dispc_manager(mgr);
+
+		omap_dss_add_overlay_manager(mgr);
+
+		r = kobject_init_and_add(&mgr->kobj, &manager_ktype,
+				&pdev->dev.kobj, "manager%d", i);
+
+		if (r) {
+			DSSERR("failed to create sysfs file\n");
+			continue;
+		}
+	}
+
+#ifdef L4_EXAMPLE
+	{
+		int omap_dss_mgr_apply_l4(struct omap_overlay_manager *mgr)
+		{
+			DSSDBG("omap_dss_mgr_apply_l4(%s)\n", mgr->name);
+
+			return 0;
+		}
+
+		struct omap_overlay_manager *mgr;
+		mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
+
+		BUG_ON(mgr == NULL);
+
+		mgr->name = "l4";
+		mgr->supported_displays =
+			OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI;
+
+		mgr->set_device = &omap_dss_set_device;
+		mgr->unset_device = &omap_dss_unset_device;
+		mgr->apply = &omap_dss_mgr_apply_l4;
+		mgr->set_manager_info = &omap_dss_mgr_set_info;
+		mgr->get_manager_info = &omap_dss_mgr_get_info;
+
+		dss_overlay_setup_l4_manager(mgr);
+
+		omap_dss_add_overlay_manager(mgr);
+
+		r = kobject_init_and_add(&mgr->kobj, &manager_ktype,
+				&pdev->dev.kobj, "managerl4");
+
+		if (r)
+			DSSERR("failed to create sysfs file\n");
+	}
+#endif
+
+	return 0;
+}
+
+void dss_uninit_overlay_managers(struct platform_device *pdev)
+{
+	struct omap_overlay_manager *mgr;
+
+	while (!list_empty(&manager_list)) {
+		mgr = list_first_entry(&manager_list,
+				struct omap_overlay_manager, list);
+		list_del(&mgr->list);
+		kobject_del(&mgr->kobj);
+		kobject_put(&mgr->kobj);
+		kfree(mgr);
+	}
+
+	num_managers = 0;
+}
+
+int omap_dss_get_num_overlay_managers(void)
+{
+	return num_managers;
+}
+EXPORT_SYMBOL(omap_dss_get_num_overlay_managers);
+
+struct omap_overlay_manager *omap_dss_get_overlay_manager(int num)
+{
+	int i = 0;
+	struct omap_overlay_manager *mgr;
+
+	list_for_each_entry(mgr, &manager_list, list) {
+		if (i++ == num)
+			return mgr;
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL(omap_dss_get_overlay_manager);
+
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
new file mode 100644
index 0000000..b7f9a73
--- /dev/null
+++ b/drivers/video/omap2/dss/overlay.c
@@ -0,0 +1,680 @@
+/*
+ * linux/drivers/video/omap2/dss/overlay.c
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * Some code and ideas taken from drivers/video/omap/ driver
+ * by Imre Deak.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define DSS_SUBSYS_NAME "OVERLAY"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/sysfs.h>
+#include <linux/kobject.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+
+#include <plat/display.h>
+#include <plat/cpu.h>
+
+#include "dss.h"
+
+static int num_overlays;
+static struct list_head overlay_list;
+
+static ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%s\n", ovl->name);
+}
+
+static ssize_t overlay_manager_show(struct omap_overlay *ovl, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%s\n",
+			ovl->manager ? ovl->manager->name : "<none>");
+}
+
+static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf,
+		size_t size)
+{
+	int i, r;
+	struct omap_overlay_manager *mgr = NULL;
+	struct omap_overlay_manager *old_mgr;
+	int len = size;
+
+	if (buf[size-1] == '\n')
+		--len;
+
+	if (len > 0) {
+		for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
+			mgr = omap_dss_get_overlay_manager(i);
+
+			if (strncmp(buf, mgr->name, len) == 0)
+				break;
+
+			mgr = NULL;
+		}
+	}
+
+	if (len > 0 && mgr == NULL)
+		return -EINVAL;
+
+	if (mgr)
+		DSSDBG("manager %s found\n", mgr->name);
+
+	if (mgr == ovl->manager)
+		return size;
+
+	old_mgr = ovl->manager;
+
+	/* detach old manager */
+	if (old_mgr) {
+		r = ovl->unset_manager(ovl);
+		if (r) {
+			DSSERR("detach failed\n");
+			return r;
+		}
+
+		r = old_mgr->apply(old_mgr);
+		if (r)
+			return r;
+	}
+
+	if (mgr) {
+		r = ovl->set_manager(ovl, mgr);
+		if (r) {
+			DSSERR("Failed to attach overlay\n");
+			return r;
+		}
+
+		r = mgr->apply(mgr);
+		if (r)
+			return r;
+	}
+
+	return size;
+}
+
+static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d,%d\n",
+			ovl->info.width, ovl->info.height);
+}
+
+static ssize_t overlay_screen_width_show(struct omap_overlay *ovl, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d\n", ovl->info.screen_width);
+}
+
+static ssize_t overlay_position_show(struct omap_overlay *ovl, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d,%d\n",
+			ovl->info.pos_x, ovl->info.pos_y);
+}
+
+static ssize_t overlay_position_store(struct omap_overlay *ovl,
+		const char *buf, size_t size)
+{
+	int r;
+	char *last;
+	struct omap_overlay_info info;
+
+	ovl->get_overlay_info(ovl, &info);
+
+	info.pos_x = simple_strtoul(buf, &last, 10);
+	++last;
+	if (last - buf >= size)
+		return -EINVAL;
+
+	info.pos_y = simple_strtoul(last, &last, 10);
+
+	r = ovl->set_overlay_info(ovl, &info);
+	if (r)
+		return r;
+
+	if (ovl->manager) {
+		r = ovl->manager->apply(ovl->manager);
+		if (r)
+			return r;
+	}
+
+	return size;
+}
+
+static ssize_t overlay_output_size_show(struct omap_overlay *ovl, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d,%d\n",
+			ovl->info.out_width, ovl->info.out_height);
+}
+
+static ssize_t overlay_output_size_store(struct omap_overlay *ovl,
+		const char *buf, size_t size)
+{
+	int r;
+	char *last;
+	struct omap_overlay_info info;
+
+	ovl->get_overlay_info(ovl, &info);
+
+	info.out_width = simple_strtoul(buf, &last, 10);
+	++last;
+	if (last - buf >= size)
+		return -EINVAL;
+
+	info.out_height = simple_strtoul(last, &last, 10);
+
+	r = ovl->set_overlay_info(ovl, &info);
+	if (r)
+		return r;
+
+	if (ovl->manager) {
+		r = ovl->manager->apply(ovl->manager);
+		if (r)
+			return r;
+	}
+
+	return size;
+}
+
+static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d\n", ovl->info.enabled);
+}
+
+static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
+		size_t size)
+{
+	int r;
+	struct omap_overlay_info info;
+
+	ovl->get_overlay_info(ovl, &info);
+
+	info.enabled = simple_strtoul(buf, NULL, 10);
+
+	r = ovl->set_overlay_info(ovl, &info);
+	if (r)
+		return r;
+
+	if (ovl->manager) {
+		r = ovl->manager->apply(ovl->manager);
+		if (r)
+			return r;
+	}
+
+	return size;
+}
+
+static ssize_t overlay_global_alpha_show(struct omap_overlay *ovl, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d\n",
+			ovl->info.global_alpha);
+}
+
+static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
+		const char *buf, size_t size)
+{
+	int r;
+	struct omap_overlay_info info;
+
+	ovl->get_overlay_info(ovl, &info);
+
+	/* Video1 plane does not support global alpha
+	 * to always make it 255 completely opaque
+	 */
+	if (ovl->id == OMAP_DSS_VIDEO1)
+		info.global_alpha = 255;
+	else
+		info.global_alpha = simple_strtoul(buf, NULL, 10);
+
+	r = ovl->set_overlay_info(ovl, &info);
+	if (r)
+		return r;
+
+	if (ovl->manager) {
+		r = ovl->manager->apply(ovl->manager);
+		if (r)
+			return r;
+	}
+
+	return size;
+}
+
+struct overlay_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct omap_overlay *, char *);
+	ssize_t	(*store)(struct omap_overlay *, const char *, size_t);
+};
+
+#define OVERLAY_ATTR(_name, _mode, _show, _store) \
+	struct overlay_attribute overlay_attr_##_name = \
+	__ATTR(_name, _mode, _show, _store)
+
+static OVERLAY_ATTR(name, S_IRUGO, overlay_name_show, NULL);
+static OVERLAY_ATTR(manager, S_IRUGO|S_IWUSR,
+		overlay_manager_show, overlay_manager_store);
+static OVERLAY_ATTR(input_size, S_IRUGO, overlay_input_size_show, NULL);
+static OVERLAY_ATTR(screen_width, S_IRUGO, overlay_screen_width_show, NULL);
+static OVERLAY_ATTR(position, S_IRUGO|S_IWUSR,
+		overlay_position_show, overlay_position_store);
+static OVERLAY_ATTR(output_size, S_IRUGO|S_IWUSR,
+		overlay_output_size_show, overlay_output_size_store);
+static OVERLAY_ATTR(enabled, S_IRUGO|S_IWUSR,
+		overlay_enabled_show, overlay_enabled_store);
+static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR,
+		overlay_global_alpha_show, overlay_global_alpha_store);
+
+static struct attribute *overlay_sysfs_attrs[] = {
+	&overlay_attr_name.attr,
+	&overlay_attr_manager.attr,
+	&overlay_attr_input_size.attr,
+	&overlay_attr_screen_width.attr,
+	&overlay_attr_position.attr,
+	&overlay_attr_output_size.attr,
+	&overlay_attr_enabled.attr,
+	&overlay_attr_global_alpha.attr,
+	NULL
+};
+
+static ssize_t overlay_attr_show(struct kobject *kobj, struct attribute *attr,
+		char *buf)
+{
+	struct omap_overlay *overlay;
+	struct overlay_attribute *overlay_attr;
+
+	overlay = container_of(kobj, struct omap_overlay, kobj);
+	overlay_attr = container_of(attr, struct overlay_attribute, attr);
+
+	if (!overlay_attr->show)
+		return -ENOENT;
+
+	return overlay_attr->show(overlay, buf);
+}
+
+static ssize_t overlay_attr_store(struct kobject *kobj, struct attribute *attr,
+		const char *buf, size_t size)
+{
+	struct omap_overlay *overlay;
+	struct overlay_attribute *overlay_attr;
+
+	overlay = container_of(kobj, struct omap_overlay, kobj);
+	overlay_attr = container_of(attr, struct overlay_attribute, attr);
+
+	if (!overlay_attr->store)
+		return -ENOENT;
+
+	return overlay_attr->store(overlay, buf, size);
+}
+
+static struct sysfs_ops overlay_sysfs_ops = {
+	.show = overlay_attr_show,
+	.store = overlay_attr_store,
+};
+
+static struct kobj_type overlay_ktype = {
+	.sysfs_ops = &overlay_sysfs_ops,
+	.default_attrs = overlay_sysfs_attrs,
+};
+
+/* Check if overlay parameters are compatible with display */
+int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev)
+{
+	struct omap_overlay_info *info;
+	u16 outw, outh;
+	u16 dw, dh;
+
+	if (!dssdev)
+		return 0;
+
+	if (!ovl->info.enabled)
+		return 0;
+
+	info = &ovl->info;
+
+	if (info->paddr == 0) {
+		DSSDBG("check_overlay failed: paddr 0\n");
+		return -EINVAL;
+	}
+
+	dssdev->get_resolution(dssdev, &dw, &dh);
+
+	DSSDBG("check_overlay %d: (%d,%d %dx%d -> %dx%d) disp (%dx%d)\n",
+			ovl->id,
+			info->pos_x, info->pos_y,
+			info->width, info->height,
+			info->out_width, info->out_height,
+			dw, dh);
+
+	if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
+		outw = info->width;
+		outh = info->height;
+	} else {
+		if (info->out_width == 0)
+			outw = info->width;
+		else
+			outw = info->out_width;
+
+		if (info->out_height == 0)
+			outh = info->height;
+		else
+			outh = info->out_height;
+	}
+
+	if (dw < info->pos_x + outw) {
+		DSSDBG("check_overlay failed 1: %d < %d + %d\n",
+				dw, info->pos_x, outw);
+		return -EINVAL;
+	}
+
+	if (dh < info->pos_y + outh) {
+		DSSDBG("check_overlay failed 2: %d < %d + %d\n",
+				dh, info->pos_y, outh);
+		return -EINVAL;
+	}
+
+	if ((ovl->supported_modes & info->color_mode) == 0) {
+		DSSERR("overlay doesn't support mode %d\n", info->color_mode);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int dss_ovl_set_overlay_info(struct omap_overlay *ovl,
+		struct omap_overlay_info *info)
+{
+	int r;
+	struct omap_overlay_info old_info;
+
+	old_info = ovl->info;
+	ovl->info = *info;
+
+	if (ovl->manager) {
+		r = dss_check_overlay(ovl, ovl->manager->device);
+		if (r) {
+			ovl->info = old_info;
+			return r;
+		}
+	}
+
+	ovl->info_dirty = true;
+
+	return 0;
+}
+
+static void dss_ovl_get_overlay_info(struct omap_overlay *ovl,
+		struct omap_overlay_info *info)
+{
+	*info = ovl->info;
+}
+
+static int dss_ovl_wait_for_go(struct omap_overlay *ovl)
+{
+	return dss_mgr_wait_for_go_ovl(ovl);
+}
+
+static int omap_dss_set_manager(struct omap_overlay *ovl,
+		struct omap_overlay_manager *mgr)
+{
+	if (!mgr)
+		return -EINVAL;
+
+	if (ovl->manager) {
+		DSSERR("overlay '%s' already has a manager '%s'\n",
+				ovl->name, ovl->manager->name);
+		return -EINVAL;
+	}
+
+	if (ovl->info.enabled) {
+		DSSERR("overlay has to be disabled to change the manager\n");
+		return -EINVAL;
+	}
+
+	ovl->manager = mgr;
+
+	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+	/* XXX: on manual update display, in auto update mode, a bug happens
+	 * here. When an overlay is first enabled on LCD, then it's disabled,
+	 * and the manager is changed to TV, we sometimes get SYNC_LOST_DIGIT
+	 * errors. Waiting before changing the channel_out fixes it. I'm
+	 * guessing that the overlay is still somehow being used for the LCD,
+	 * but I don't understand how or why. */
+	msleep(40);
+	dispc_set_channel_out(ovl->id, mgr->id);
+	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+
+	return 0;
+}
+
+static int omap_dss_unset_manager(struct omap_overlay *ovl)
+{
+	int r;
+
+	if (!ovl->manager) {
+		DSSERR("failed to detach overlay: manager not set\n");
+		return -EINVAL;
+	}
+
+	if (ovl->info.enabled) {
+		DSSERR("overlay has to be disabled to unset the manager\n");
+		return -EINVAL;
+	}
+
+	r = ovl->wait_for_go(ovl);
+	if (r)
+		return r;
+
+	ovl->manager = NULL;
+
+	return 0;
+}
+
+int omap_dss_get_num_overlays(void)
+{
+	return num_overlays;
+}
+EXPORT_SYMBOL(omap_dss_get_num_overlays);
+
+struct omap_overlay *omap_dss_get_overlay(int num)
+{
+	int i = 0;
+	struct omap_overlay *ovl;
+
+	list_for_each_entry(ovl, &overlay_list, list) {
+		if (i++ == num)
+			return ovl;
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL(omap_dss_get_overlay);
+
+static void omap_dss_add_overlay(struct omap_overlay *overlay)
+{
+	++num_overlays;
+	list_add_tail(&overlay->list, &overlay_list);
+}
+
+static struct omap_overlay *dispc_overlays[3];
+
+void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr)
+{
+	mgr->num_overlays = 3;
+	mgr->overlays = dispc_overlays;
+}
+
+#ifdef L4_EXAMPLE
+static struct omap_overlay *l4_overlays[1];
+void dss_overlay_setup_l4_manager(struct omap_overlay_manager *mgr)
+{
+	mgr->num_overlays = 1;
+	mgr->overlays = l4_overlays;
+}
+#endif
+
+void dss_init_overlays(struct platform_device *pdev)
+{
+	int i, r;
+
+	INIT_LIST_HEAD(&overlay_list);
+
+	num_overlays = 0;
+
+	for (i = 0; i < 3; ++i) {
+		struct omap_overlay *ovl;
+		ovl = kzalloc(sizeof(*ovl), GFP_KERNEL);
+
+		BUG_ON(ovl == NULL);
+
+		switch (i) {
+		case 0:
+			ovl->name = "gfx";
+			ovl->id = OMAP_DSS_GFX;
+			ovl->supported_modes = cpu_is_omap34xx() ?
+				OMAP_DSS_COLOR_GFX_OMAP3 :
+				OMAP_DSS_COLOR_GFX_OMAP2;
+			ovl->caps = OMAP_DSS_OVL_CAP_DISPC;
+			ovl->info.global_alpha = 255;
+			break;
+		case 1:
+			ovl->name = "vid1";
+			ovl->id = OMAP_DSS_VIDEO1;
+			ovl->supported_modes = cpu_is_omap34xx() ?
+				OMAP_DSS_COLOR_VID1_OMAP3 :
+				OMAP_DSS_COLOR_VID_OMAP2;
+			ovl->caps = OMAP_DSS_OVL_CAP_SCALE |
+				OMAP_DSS_OVL_CAP_DISPC;
+			ovl->info.global_alpha = 255;
+			break;
+		case 2:
+			ovl->name = "vid2";
+			ovl->id = OMAP_DSS_VIDEO2;
+			ovl->supported_modes = cpu_is_omap34xx() ?
+				OMAP_DSS_COLOR_VID2_OMAP3 :
+				OMAP_DSS_COLOR_VID_OMAP2;
+			ovl->caps = OMAP_DSS_OVL_CAP_SCALE |
+				OMAP_DSS_OVL_CAP_DISPC;
+			ovl->info.global_alpha = 255;
+			break;
+		}
+
+		ovl->set_manager = &omap_dss_set_manager;
+		ovl->unset_manager = &omap_dss_unset_manager;
+		ovl->set_overlay_info = &dss_ovl_set_overlay_info;
+		ovl->get_overlay_info = &dss_ovl_get_overlay_info;
+		ovl->wait_for_go = &dss_ovl_wait_for_go;
+
+		omap_dss_add_overlay(ovl);
+
+		r = kobject_init_and_add(&ovl->kobj, &overlay_ktype,
+				&pdev->dev.kobj, "overlay%d", i);
+
+		if (r) {
+			DSSERR("failed to create sysfs file\n");
+			continue;
+		}
+
+		dispc_overlays[i] = ovl;
+	}
+
+#ifdef L4_EXAMPLE
+	{
+		struct omap_overlay *ovl;
+		ovl = kzalloc(sizeof(*ovl), GFP_KERNEL);
+
+		BUG_ON(ovl == NULL);
+
+		ovl->name = "l4";
+		ovl->supported_modes = OMAP_DSS_COLOR_RGB24U;
+
+		ovl->set_manager = &omap_dss_set_manager;
+		ovl->unset_manager = &omap_dss_unset_manager;
+		ovl->set_overlay_info = &dss_ovl_set_overlay_info;
+		ovl->get_overlay_info = &dss_ovl_get_overlay_info;
+
+		omap_dss_add_overlay(ovl);
+
+		r = kobject_init_and_add(&ovl->kobj, &overlay_ktype,
+				&pdev->dev.kobj, "overlayl4");
+
+		if (r)
+			DSSERR("failed to create sysfs file\n");
+
+		l4_overlays[0] = ovl;
+	}
+#endif
+}
+
+/* connect overlays to the new device, if not already connected. if force
+ * selected, connect always. */
+void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
+{
+	int i;
+	struct omap_overlay_manager *lcd_mgr;
+	struct omap_overlay_manager *tv_mgr;
+	struct omap_overlay_manager *mgr = NULL;
+
+	lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD);
+	tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV);
+
+	if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) {
+		if (!lcd_mgr->device || force) {
+			if (lcd_mgr->device)
+				lcd_mgr->unset_device(lcd_mgr);
+			lcd_mgr->set_device(lcd_mgr, dssdev);
+			mgr = lcd_mgr;
+		}
+	}
+
+	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
+		if (!tv_mgr->device || force) {
+			if (tv_mgr->device)
+				tv_mgr->unset_device(tv_mgr);
+			tv_mgr->set_device(tv_mgr, dssdev);
+			mgr = tv_mgr;
+		}
+	}
+
+	if (mgr) {
+		for (i = 0; i < 3; i++) {
+			struct omap_overlay *ovl;
+			ovl = omap_dss_get_overlay(i);
+			if (!ovl->manager || force) {
+				if (ovl->manager)
+					omap_dss_unset_manager(ovl);
+				omap_dss_set_manager(ovl, mgr);
+			}
+		}
+	}
+}
+
+void dss_uninit_overlays(struct platform_device *pdev)
+{
+	struct omap_overlay *ovl;
+
+	while (!list_empty(&overlay_list)) {
+		ovl = list_first_entry(&overlay_list,
+				struct omap_overlay, list);
+		list_del(&ovl->list);
+		kobject_del(&ovl->kobj);
+		kobject_put(&ovl->kobj);
+		kfree(ovl);
+	}
+
+	num_overlays = 0;
+}
+
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
new file mode 100644
index 0000000..d0b3006
--- /dev/null
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -0,0 +1,1309 @@
+/*
+ * linux/drivers/video/omap2/dss/rfbi.c
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * Some code and ideas taken from drivers/video/omap/ driver
+ * by Imre Deak.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define DSS_SUBSYS_NAME "RFBI"
+
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/vmalloc.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/kfifo.h>
+#include <linux/ktime.h>
+#include <linux/hrtimer.h>
+#include <linux/seq_file.h>
+
+#include <plat/display.h>
+#include "dss.h"
+
+/*#define MEASURE_PERF*/
+
+#define RFBI_BASE               0x48050800
+
+struct rfbi_reg { u16 idx; };
+
+#define RFBI_REG(idx)		((const struct rfbi_reg) { idx })
+
+#define RFBI_REVISION		RFBI_REG(0x0000)
+#define RFBI_SYSCONFIG		RFBI_REG(0x0010)
+#define RFBI_SYSSTATUS		RFBI_REG(0x0014)
+#define RFBI_CONTROL		RFBI_REG(0x0040)
+#define RFBI_PIXEL_CNT		RFBI_REG(0x0044)
+#define RFBI_LINE_NUMBER	RFBI_REG(0x0048)
+#define RFBI_CMD		RFBI_REG(0x004c)
+#define RFBI_PARAM		RFBI_REG(0x0050)
+#define RFBI_DATA		RFBI_REG(0x0054)
+#define RFBI_READ		RFBI_REG(0x0058)
+#define RFBI_STATUS		RFBI_REG(0x005c)
+
+#define RFBI_CONFIG(n)		RFBI_REG(0x0060 + (n)*0x18)
+#define RFBI_ONOFF_TIME(n)	RFBI_REG(0x0064 + (n)*0x18)
+#define RFBI_CYCLE_TIME(n)	RFBI_REG(0x0068 + (n)*0x18)
+#define RFBI_DATA_CYCLE1(n)	RFBI_REG(0x006c + (n)*0x18)
+#define RFBI_DATA_CYCLE2(n)	RFBI_REG(0x0070 + (n)*0x18)
+#define RFBI_DATA_CYCLE3(n)	RFBI_REG(0x0074 + (n)*0x18)
+
+#define RFBI_VSYNC_WIDTH	RFBI_REG(0x0090)
+#define RFBI_HSYNC_WIDTH	RFBI_REG(0x0094)
+
+#define RFBI_CMD_FIFO_LEN_BYTES (16 * sizeof(struct update_param))
+
+#define REG_FLD_MOD(idx, val, start, end) \
+	rfbi_write_reg(idx, FLD_MOD(rfbi_read_reg(idx), val, start, end))
+
+/* To work around an RFBI transfer rate limitation */
+#define OMAP_RFBI_RATE_LIMIT    1
+
+enum omap_rfbi_cycleformat {
+	OMAP_DSS_RFBI_CYCLEFORMAT_1_1 = 0,
+	OMAP_DSS_RFBI_CYCLEFORMAT_2_1 = 1,
+	OMAP_DSS_RFBI_CYCLEFORMAT_3_1 = 2,
+	OMAP_DSS_RFBI_CYCLEFORMAT_3_2 = 3,
+};
+
+enum omap_rfbi_datatype {
+	OMAP_DSS_RFBI_DATATYPE_12 = 0,
+	OMAP_DSS_RFBI_DATATYPE_16 = 1,
+	OMAP_DSS_RFBI_DATATYPE_18 = 2,
+	OMAP_DSS_RFBI_DATATYPE_24 = 3,
+};
+
+enum omap_rfbi_parallelmode {
+	OMAP_DSS_RFBI_PARALLELMODE_8 = 0,
+	OMAP_DSS_RFBI_PARALLELMODE_9 = 1,
+	OMAP_DSS_RFBI_PARALLELMODE_12 = 2,
+	OMAP_DSS_RFBI_PARALLELMODE_16 = 3,
+};
+
+enum update_cmd {
+	RFBI_CMD_UPDATE = 0,
+	RFBI_CMD_SYNC   = 1,
+};
+
+static int rfbi_convert_timings(struct rfbi_timings *t);
+static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div);
+static void process_cmd_fifo(void);
+
+static struct {
+	void __iomem	*base;
+
+	unsigned long	l4_khz;
+
+	enum omap_rfbi_datatype datatype;
+	enum omap_rfbi_parallelmode parallelmode;
+
+	enum omap_rfbi_te_mode te_mode;
+	int te_enabled;
+
+	void (*framedone_callback)(void *data);
+	void *framedone_callback_data;
+
+	struct omap_dss_device *dssdev[2];
+
+	struct kfifo      *cmd_fifo;
+	spinlock_t        cmd_lock;
+	struct completion cmd_done;
+	atomic_t          cmd_fifo_full;
+	atomic_t          cmd_pending;
+#ifdef MEASURE_PERF
+	unsigned perf_bytes;
+	ktime_t perf_setup_time;
+	ktime_t perf_start_time;
+#endif
+} rfbi;
+
+struct update_region {
+	u16	x;
+	u16     y;
+	u16     w;
+	u16     h;
+};
+
+struct update_param {
+	u8 rfbi_module;
+	u8 cmd;
+
+	union {
+		struct update_region r;
+		struct completion *sync;
+	} par;
+};
+
+static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
+{
+	__raw_writel(val, rfbi.base + idx.idx);
+}
+
+static inline u32 rfbi_read_reg(const struct rfbi_reg idx)
+{
+	return __raw_readl(rfbi.base + idx.idx);
+}
+
+static void rfbi_enable_clocks(bool enable)
+{
+	if (enable)
+		dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+	else
+		dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+}
+
+void omap_rfbi_write_command(const void *buf, u32 len)
+{
+	rfbi_enable_clocks(1);
+	switch (rfbi.parallelmode) {
+	case OMAP_DSS_RFBI_PARALLELMODE_8:
+	{
+		const u8 *b = buf;
+		for (; len; len--)
+			rfbi_write_reg(RFBI_CMD, *b++);
+		break;
+	}
+
+	case OMAP_DSS_RFBI_PARALLELMODE_16:
+	{
+		const u16 *w = buf;
+		BUG_ON(len & 1);
+		for (; len; len -= 2)
+			rfbi_write_reg(RFBI_CMD, *w++);
+		break;
+	}
+
+	case OMAP_DSS_RFBI_PARALLELMODE_9:
+	case OMAP_DSS_RFBI_PARALLELMODE_12:
+	default:
+		BUG();
+	}
+	rfbi_enable_clocks(0);
+}
+EXPORT_SYMBOL(omap_rfbi_write_command);
+
+void omap_rfbi_read_data(void *buf, u32 len)
+{
+	rfbi_enable_clocks(1);
+	switch (rfbi.parallelmode) {
+	case OMAP_DSS_RFBI_PARALLELMODE_8:
+	{
+		u8 *b = buf;
+		for (; len; len--) {
+			rfbi_write_reg(RFBI_READ, 0);
+			*b++ = rfbi_read_reg(RFBI_READ);
+		}
+		break;
+	}
+
+	case OMAP_DSS_RFBI_PARALLELMODE_16:
+	{
+		u16 *w = buf;
+		BUG_ON(len & ~1);
+		for (; len; len -= 2) {
+			rfbi_write_reg(RFBI_READ, 0);
+			*w++ = rfbi_read_reg(RFBI_READ);
+		}
+		break;
+	}
+
+	case OMAP_DSS_RFBI_PARALLELMODE_9:
+	case OMAP_DSS_RFBI_PARALLELMODE_12:
+	default:
+		BUG();
+	}
+	rfbi_enable_clocks(0);
+}
+EXPORT_SYMBOL(omap_rfbi_read_data);
+
+void omap_rfbi_write_data(const void *buf, u32 len)
+{
+	rfbi_enable_clocks(1);
+	switch (rfbi.parallelmode) {
+	case OMAP_DSS_RFBI_PARALLELMODE_8:
+	{
+		const u8 *b = buf;
+		for (; len; len--)
+			rfbi_write_reg(RFBI_PARAM, *b++);
+		break;
+	}
+
+	case OMAP_DSS_RFBI_PARALLELMODE_16:
+	{
+		const u16 *w = buf;
+		BUG_ON(len & 1);
+		for (; len; len -= 2)
+			rfbi_write_reg(RFBI_PARAM, *w++);
+		break;
+	}
+
+	case OMAP_DSS_RFBI_PARALLELMODE_9:
+	case OMAP_DSS_RFBI_PARALLELMODE_12:
+	default:
+		BUG();
+
+	}
+	rfbi_enable_clocks(0);
+}
+EXPORT_SYMBOL(omap_rfbi_write_data);
+
+void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
+		u16 x, u16 y,
+		u16 w, u16 h)
+{
+	int start_offset = scr_width * y + x;
+	int horiz_offset = scr_width - w;
+	int i;
+
+	rfbi_enable_clocks(1);
+
+	if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_16 &&
+	   rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_8) {
+		const u16 __iomem *pd = buf;
+		pd += start_offset;
+
+		for (; h; --h) {
+			for (i = 0; i < w; ++i) {
+				const u8 __iomem *b = (const u8 __iomem *)pd;
+				rfbi_write_reg(RFBI_PARAM, __raw_readb(b+1));
+				rfbi_write_reg(RFBI_PARAM, __raw_readb(b+0));
+				++pd;
+			}
+			pd += horiz_offset;
+		}
+	} else if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_24 &&
+	   rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_8) {
+		const u32 __iomem *pd = buf;
+		pd += start_offset;
+
+		for (; h; --h) {
+			for (i = 0; i < w; ++i) {
+				const u8 __iomem *b = (const u8 __iomem *)pd;
+				rfbi_write_reg(RFBI_PARAM, __raw_readb(b+2));
+				rfbi_write_reg(RFBI_PARAM, __raw_readb(b+1));
+				rfbi_write_reg(RFBI_PARAM, __raw_readb(b+0));
+				++pd;
+			}
+			pd += horiz_offset;
+		}
+	} else if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_16 &&
+	   rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_16) {
+		const u16 __iomem *pd = buf;
+		pd += start_offset;
+
+		for (; h; --h) {
+			for (i = 0; i < w; ++i) {
+				rfbi_write_reg(RFBI_PARAM, __raw_readw(pd));
+				++pd;
+			}
+			pd += horiz_offset;
+		}
+	} else {
+		BUG();
+	}
+
+	rfbi_enable_clocks(0);
+}
+EXPORT_SYMBOL(omap_rfbi_write_pixels);
+
+#ifdef MEASURE_PERF
+static void perf_mark_setup(void)
+{
+	rfbi.perf_setup_time = ktime_get();
+}
+
+static void perf_mark_start(void)
+{
+	rfbi.perf_start_time = ktime_get();
+}
+
+static void perf_show(const char *name)
+{
+	ktime_t t, setup_time, trans_time;
+	u32 total_bytes;
+	u32 setup_us, trans_us, total_us;
+
+	t = ktime_get();
+
+	setup_time = ktime_sub(rfbi.perf_start_time, rfbi.perf_setup_time);
+	setup_us = (u32)ktime_to_us(setup_time);
+	if (setup_us == 0)
+		setup_us = 1;
+
+	trans_time = ktime_sub(t, rfbi.perf_start_time);
+	trans_us = (u32)ktime_to_us(trans_time);
+	if (trans_us == 0)
+		trans_us = 1;
+
+	total_us = setup_us + trans_us;
+
+	total_bytes = rfbi.perf_bytes;
+
+	DSSINFO("%s update %u us + %u us = %u us (%uHz), %u bytes, "
+			"%u kbytes/sec\n",
+			name,
+			setup_us,
+			trans_us,
+			total_us,
+			1000*1000 / total_us,
+			total_bytes,
+			total_bytes * 1000 / total_us);
+}
+#else
+#define perf_mark_setup()
+#define perf_mark_start()
+#define perf_show(x)
+#endif
+
+void rfbi_transfer_area(u16 width, u16 height,
+			     void (callback)(void *data), void *data)
+{
+	u32 l;
+
+	/*BUG_ON(callback == 0);*/
+	BUG_ON(rfbi.framedone_callback != NULL);
+
+	DSSDBG("rfbi_transfer_area %dx%d\n", width, height);
+
+	dispc_set_lcd_size(width, height);
+
+	dispc_enable_lcd_out(1);
+
+	rfbi.framedone_callback = callback;
+	rfbi.framedone_callback_data = data;
+
+	rfbi_enable_clocks(1);
+
+	rfbi_write_reg(RFBI_PIXEL_CNT, width * height);
+
+	l = rfbi_read_reg(RFBI_CONTROL);
+	l = FLD_MOD(l, 1, 0, 0); /* enable */
+	if (!rfbi.te_enabled)
+		l = FLD_MOD(l, 1, 4, 4); /* ITE */
+
+	perf_mark_start();
+
+	rfbi_write_reg(RFBI_CONTROL, l);
+}
+
+static void framedone_callback(void *data, u32 mask)
+{
+	void (*callback)(void *data);
+
+	DSSDBG("FRAMEDONE\n");
+
+	perf_show("DISPC");
+
+	REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0);
+
+	rfbi_enable_clocks(0);
+
+	callback = rfbi.framedone_callback;
+	rfbi.framedone_callback = NULL;
+
+	/*callback(rfbi.framedone_callback_data);*/
+
+	atomic_set(&rfbi.cmd_pending, 0);
+
+	process_cmd_fifo();
+}
+
+#if 1 /* VERBOSE */
+static void rfbi_print_timings(void)
+{
+	u32 l;
+	u32 time;
+
+	l = rfbi_read_reg(RFBI_CONFIG(0));
+	time = 1000000000 / rfbi.l4_khz;
+	if (l & (1 << 4))
+		time *= 2;
+
+	DSSDBG("Tick time %u ps\n", time);
+	l = rfbi_read_reg(RFBI_ONOFF_TIME(0));
+	DSSDBG("CSONTIME %d, CSOFFTIME %d, WEONTIME %d, WEOFFTIME %d, "
+		"REONTIME %d, REOFFTIME %d\n",
+		l & 0x0f, (l >> 4) & 0x3f, (l >> 10) & 0x0f, (l >> 14) & 0x3f,
+		(l >> 20) & 0x0f, (l >> 24) & 0x3f);
+
+	l = rfbi_read_reg(RFBI_CYCLE_TIME(0));
+	DSSDBG("WECYCLETIME %d, RECYCLETIME %d, CSPULSEWIDTH %d, "
+		"ACCESSTIME %d\n",
+		(l & 0x3f), (l >> 6) & 0x3f, (l >> 12) & 0x3f,
+		(l >> 22) & 0x3f);
+}
+#else
+static void rfbi_print_timings(void) {}
+#endif
+
+
+
+
+static u32 extif_clk_period;
+
+static inline unsigned long round_to_extif_ticks(unsigned long ps, int div)
+{
+	int bus_tick = extif_clk_period * div;
+	return (ps + bus_tick - 1) / bus_tick * bus_tick;
+}
+
+static int calc_reg_timing(struct rfbi_timings *t, int div)
+{
+	t->clk_div = div;
+
+	t->cs_on_time = round_to_extif_ticks(t->cs_on_time, div);
+
+	t->we_on_time = round_to_extif_ticks(t->we_on_time, div);
+	t->we_off_time = round_to_extif_ticks(t->we_off_time, div);
+	t->we_cycle_time = round_to_extif_ticks(t->we_cycle_time, div);
+
+	t->re_on_time = round_to_extif_ticks(t->re_on_time, div);
+	t->re_off_time = round_to_extif_ticks(t->re_off_time, div);
+	t->re_cycle_time = round_to_extif_ticks(t->re_cycle_time, div);
+
+	t->access_time = round_to_extif_ticks(t->access_time, div);
+	t->cs_off_time = round_to_extif_ticks(t->cs_off_time, div);
+	t->cs_pulse_width = round_to_extif_ticks(t->cs_pulse_width, div);
+
+	DSSDBG("[reg]cson %d csoff %d reon %d reoff %d\n",
+	       t->cs_on_time, t->cs_off_time, t->re_on_time, t->re_off_time);
+	DSSDBG("[reg]weon %d weoff %d recyc %d wecyc %d\n",
+	       t->we_on_time, t->we_off_time, t->re_cycle_time,
+	       t->we_cycle_time);
+	DSSDBG("[reg]rdaccess %d cspulse %d\n",
+	       t->access_time, t->cs_pulse_width);
+
+	return rfbi_convert_timings(t);
+}
+
+static int calc_extif_timings(struct rfbi_timings *t)
+{
+	u32 max_clk_div;
+	int div;
+
+	rfbi_get_clk_info(&extif_clk_period, &max_clk_div);
+	for (div = 1; div <= max_clk_div; div++) {
+		if (calc_reg_timing(t, div) == 0)
+			break;
+	}
+
+	if (div <= max_clk_div)
+		return 0;
+
+	DSSERR("can't setup timings\n");
+	return -1;
+}
+
+
+void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t)
+{
+	int r;
+
+	if (!t->converted) {
+		r = calc_extif_timings(t);
+		if (r < 0)
+			DSSERR("Failed to calc timings\n");
+	}
+
+	BUG_ON(!t->converted);
+
+	rfbi_enable_clocks(1);
+	rfbi_write_reg(RFBI_ONOFF_TIME(rfbi_module), t->tim[0]);
+	rfbi_write_reg(RFBI_CYCLE_TIME(rfbi_module), t->tim[1]);
+
+	/* TIMEGRANULARITY */
+	REG_FLD_MOD(RFBI_CONFIG(rfbi_module),
+		    (t->tim[2] ? 1 : 0), 4, 4);
+
+	rfbi_print_timings();
+	rfbi_enable_clocks(0);
+}
+
+static int ps_to_rfbi_ticks(int time, int div)
+{
+	unsigned long tick_ps;
+	int ret;
+
+	/* Calculate in picosecs to yield more exact results */
+	tick_ps = 1000000000 / (rfbi.l4_khz) * div;
+
+	ret = (time + tick_ps - 1) / tick_ps;
+
+	return ret;
+}
+
+#ifdef OMAP_RFBI_RATE_LIMIT
+unsigned long rfbi_get_max_tx_rate(void)
+{
+	unsigned long   l4_rate, dss1_rate;
+	int             min_l4_ticks = 0;
+	int             i;
+
+	/* According to TI this can't be calculated so make the
+	 * adjustments for a couple of known frequencies and warn for
+	 * others.
+	 */
+	static const struct {
+		unsigned long l4_clk;           /* HZ */
+		unsigned long dss1_clk;         /* HZ */
+		unsigned long min_l4_ticks;
+	} ftab[] = {
+		{ 55,   132,    7, },           /* 7.86 MPix/s */
+		{ 110,  110,    12, },          /* 9.16 MPix/s */
+		{ 110,  132,    10, },          /* 11   Mpix/s */
+		{ 120,  120,    10, },          /* 12   Mpix/s */
+		{ 133,  133,    10, },          /* 13.3 Mpix/s */
+	};
+
+	l4_rate = rfbi.l4_khz / 1000;
+	dss1_rate = dss_clk_get_rate(DSS_CLK_FCK1) / 1000000;
+
+	for (i = 0; i < ARRAY_SIZE(ftab); i++) {
+		/* Use a window instead of an exact match, to account
+		 * for different DPLL multiplier / divider pairs.
+		 */
+		if (abs(ftab[i].l4_clk - l4_rate) < 3 &&
+		    abs(ftab[i].dss1_clk - dss1_rate) < 3) {
+			min_l4_ticks = ftab[i].min_l4_ticks;
+			break;
+		}
+	}
+	if (i == ARRAY_SIZE(ftab)) {
+		/* Can't be sure, return anyway the maximum not
+		 * rate-limited. This might cause a problem only for the
+		 * tearing synchronisation.
+		 */
+		DSSERR("can't determine maximum RFBI transfer rate\n");
+		return rfbi.l4_khz * 1000;
+	}
+	return rfbi.l4_khz * 1000 / min_l4_ticks;
+}
+#else
+int rfbi_get_max_tx_rate(void)
+{
+	return rfbi.l4_khz * 1000;
+}
+#endif
+
+static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div)
+{
+	*clk_period = 1000000000 / rfbi.l4_khz;
+	*max_clk_div = 2;
+}
+
+static int rfbi_convert_timings(struct rfbi_timings *t)
+{
+	u32 l;
+	int reon, reoff, weon, weoff, cson, csoff, cs_pulse;
+	int actim, recyc, wecyc;
+	int div = t->clk_div;
+
+	if (div <= 0 || div > 2)
+		return -1;
+
+	/* Make sure that after conversion it still holds that:
+	 * weoff > weon, reoff > reon, recyc >= reoff, wecyc >= weoff,
+	 * csoff > cson, csoff >= max(weoff, reoff), actim > reon
+	 */
+	weon = ps_to_rfbi_ticks(t->we_on_time, div);
+	weoff = ps_to_rfbi_ticks(t->we_off_time, div);
+	if (weoff <= weon)
+		weoff = weon + 1;
+	if (weon > 0x0f)
+		return -1;
+	if (weoff > 0x3f)
+		return -1;
+
+	reon = ps_to_rfbi_ticks(t->re_on_time, div);
+	reoff = ps_to_rfbi_ticks(t->re_off_time, div);
+	if (reoff <= reon)
+		reoff = reon + 1;
+	if (reon > 0x0f)
+		return -1;
+	if (reoff > 0x3f)
+		return -1;
+
+	cson = ps_to_rfbi_ticks(t->cs_on_time, div);
+	csoff = ps_to_rfbi_ticks(t->cs_off_time, div);
+	if (csoff <= cson)
+		csoff = cson + 1;
+	if (csoff < max(weoff, reoff))
+		csoff = max(weoff, reoff);
+	if (cson > 0x0f)
+		return -1;
+	if (csoff > 0x3f)
+		return -1;
+
+	l =  cson;
+	l |= csoff << 4;
+	l |= weon  << 10;
+	l |= weoff << 14;
+	l |= reon  << 20;
+	l |= reoff << 24;
+
+	t->tim[0] = l;
+
+	actim = ps_to_rfbi_ticks(t->access_time, div);
+	if (actim <= reon)
+		actim = reon + 1;
+	if (actim > 0x3f)
+		return -1;
+
+	wecyc = ps_to_rfbi_ticks(t->we_cycle_time, div);
+	if (wecyc < weoff)
+		wecyc = weoff;
+	if (wecyc > 0x3f)
+		return -1;
+
+	recyc = ps_to_rfbi_ticks(t->re_cycle_time, div);
+	if (recyc < reoff)
+		recyc = reoff;
+	if (recyc > 0x3f)
+		return -1;
+
+	cs_pulse = ps_to_rfbi_ticks(t->cs_pulse_width, div);
+	if (cs_pulse > 0x3f)
+		return -1;
+
+	l =  wecyc;
+	l |= recyc    << 6;
+	l |= cs_pulse << 12;
+	l |= actim    << 22;
+
+	t->tim[1] = l;
+
+	t->tim[2] = div - 1;
+
+	t->converted = 1;
+
+	return 0;
+}
+
+/* xxx FIX module selection missing */
+int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
+			     unsigned hs_pulse_time, unsigned vs_pulse_time,
+			     int hs_pol_inv, int vs_pol_inv, int extif_div)
+{
+	int hs, vs;
+	int min;
+	u32 l;
+
+	hs = ps_to_rfbi_ticks(hs_pulse_time, 1);
+	vs = ps_to_rfbi_ticks(vs_pulse_time, 1);
+	if (hs < 2)
+		return -EDOM;
+	if (mode == OMAP_DSS_RFBI_TE_MODE_2)
+		min = 2;
+	else /* OMAP_DSS_RFBI_TE_MODE_1 */
+		min = 4;
+	if (vs < min)
+		return -EDOM;
+	if (vs == hs)
+		return -EINVAL;
+	rfbi.te_mode = mode;
+	DSSDBG("setup_te: mode %d hs %d vs %d hs_inv %d vs_inv %d\n",
+		mode, hs, vs, hs_pol_inv, vs_pol_inv);
+
+	rfbi_enable_clocks(1);
+	rfbi_write_reg(RFBI_HSYNC_WIDTH, hs);
+	rfbi_write_reg(RFBI_VSYNC_WIDTH, vs);
+
+	l = rfbi_read_reg(RFBI_CONFIG(0));
+	if (hs_pol_inv)
+		l &= ~(1 << 21);
+	else
+		l |= 1 << 21;
+	if (vs_pol_inv)
+		l &= ~(1 << 20);
+	else
+		l |= 1 << 20;
+	rfbi_enable_clocks(0);
+
+	return 0;
+}
+EXPORT_SYMBOL(omap_rfbi_setup_te);
+
+/* xxx FIX module selection missing */
+int omap_rfbi_enable_te(bool enable, unsigned line)
+{
+	u32 l;
+
+	DSSDBG("te %d line %d mode %d\n", enable, line, rfbi.te_mode);
+	if (line > (1 << 11) - 1)
+		return -EINVAL;
+
+	rfbi_enable_clocks(1);
+	l = rfbi_read_reg(RFBI_CONFIG(0));
+	l &= ~(0x3 << 2);
+	if (enable) {
+		rfbi.te_enabled = 1;
+		l |= rfbi.te_mode << 2;
+	} else
+		rfbi.te_enabled = 0;
+	rfbi_write_reg(RFBI_CONFIG(0), l);
+	rfbi_write_reg(RFBI_LINE_NUMBER, line);
+	rfbi_enable_clocks(0);
+
+	return 0;
+}
+EXPORT_SYMBOL(omap_rfbi_enable_te);
+
+#if 0
+static void rfbi_enable_config(int enable1, int enable2)
+{
+	u32 l;
+	int cs = 0;
+
+	if (enable1)
+		cs |= 1<<0;
+	if (enable2)
+		cs |= 1<<1;
+
+	rfbi_enable_clocks(1);
+
+	l = rfbi_read_reg(RFBI_CONTROL);
+
+	l = FLD_MOD(l, cs, 3, 2);
+	l = FLD_MOD(l, 0, 1, 1);
+
+	rfbi_write_reg(RFBI_CONTROL, l);
+
+
+	l = rfbi_read_reg(RFBI_CONFIG(0));
+	l = FLD_MOD(l, 0, 3, 2); /* TRIGGERMODE: ITE */
+	/*l |= FLD_VAL(2, 8, 7); */ /* L4FORMAT, 2pix/L4 */
+	/*l |= FLD_VAL(0, 8, 7); */ /* L4FORMAT, 1pix/L4 */
+
+	l = FLD_MOD(l, 0, 16, 16); /* A0POLARITY */
+	l = FLD_MOD(l, 1, 20, 20); /* TE_VSYNC_POLARITY */
+	l = FLD_MOD(l, 1, 21, 21); /* HSYNCPOLARITY */
+
+	l = FLD_MOD(l, OMAP_DSS_RFBI_PARALLELMODE_8, 1, 0);
+	rfbi_write_reg(RFBI_CONFIG(0), l);
+
+	rfbi_enable_clocks(0);
+}
+#endif
+
+int rfbi_configure(int rfbi_module, int bpp, int lines)
+{
+	u32 l;
+	int cycle1 = 0, cycle2 = 0, cycle3 = 0;
+	enum omap_rfbi_cycleformat cycleformat;
+	enum omap_rfbi_datatype datatype;
+	enum omap_rfbi_parallelmode parallelmode;
+
+	switch (bpp) {
+	case 12:
+		datatype = OMAP_DSS_RFBI_DATATYPE_12;
+		break;
+	case 16:
+		datatype = OMAP_DSS_RFBI_DATATYPE_16;
+		break;
+	case 18:
+		datatype = OMAP_DSS_RFBI_DATATYPE_18;
+		break;
+	case 24:
+		datatype = OMAP_DSS_RFBI_DATATYPE_24;
+		break;
+	default:
+		BUG();
+		return 1;
+	}
+	rfbi.datatype = datatype;
+
+	switch (lines) {
+	case 8:
+		parallelmode = OMAP_DSS_RFBI_PARALLELMODE_8;
+		break;
+	case 9:
+		parallelmode = OMAP_DSS_RFBI_PARALLELMODE_9;
+		break;
+	case 12:
+		parallelmode = OMAP_DSS_RFBI_PARALLELMODE_12;
+		break;
+	case 16:
+		parallelmode = OMAP_DSS_RFBI_PARALLELMODE_16;
+		break;
+	default:
+		BUG();
+		return 1;
+	}
+	rfbi.parallelmode = parallelmode;
+
+	if ((bpp % lines) == 0) {
+		switch (bpp / lines) {
+		case 1:
+			cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_1_1;
+			break;
+		case 2:
+			cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_2_1;
+			break;
+		case 3:
+			cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_3_1;
+			break;
+		default:
+			BUG();
+			return 1;
+		}
+	} else if ((2 * bpp % lines) == 0) {
+		if ((2 * bpp / lines) == 3)
+			cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_3_2;
+		else {
+			BUG();
+			return 1;
+		}
+	} else {
+		BUG();
+		return 1;
+	}
+
+	switch (cycleformat) {
+	case OMAP_DSS_RFBI_CYCLEFORMAT_1_1:
+		cycle1 = lines;
+		break;
+
+	case OMAP_DSS_RFBI_CYCLEFORMAT_2_1:
+		cycle1 = lines;
+		cycle2 = lines;
+		break;
+
+	case OMAP_DSS_RFBI_CYCLEFORMAT_3_1:
+		cycle1 = lines;
+		cycle2 = lines;
+		cycle3 = lines;
+		break;
+
+	case OMAP_DSS_RFBI_CYCLEFORMAT_3_2:
+		cycle1 = lines;
+		cycle2 = (lines / 2) | ((lines / 2) << 16);
+		cycle3 = (lines << 16);
+		break;
+	}
+
+	rfbi_enable_clocks(1);
+
+	REG_FLD_MOD(RFBI_CONTROL, 0, 3, 2); /* clear CS */
+
+	l = 0;
+	l |= FLD_VAL(parallelmode, 1, 0);
+	l |= FLD_VAL(0, 3, 2);		/* TRIGGERMODE: ITE */
+	l |= FLD_VAL(0, 4, 4);		/* TIMEGRANULARITY */
+	l |= FLD_VAL(datatype, 6, 5);
+	/* l |= FLD_VAL(2, 8, 7); */	/* L4FORMAT, 2pix/L4 */
+	l |= FLD_VAL(0, 8, 7);	/* L4FORMAT, 1pix/L4 */
+	l |= FLD_VAL(cycleformat, 10, 9);
+	l |= FLD_VAL(0, 12, 11);	/* UNUSEDBITS */
+	l |= FLD_VAL(0, 16, 16);	/* A0POLARITY */
+	l |= FLD_VAL(0, 17, 17);	/* REPOLARITY */
+	l |= FLD_VAL(0, 18, 18);	/* WEPOLARITY */
+	l |= FLD_VAL(0, 19, 19);	/* CSPOLARITY */
+	l |= FLD_VAL(1, 20, 20);	/* TE_VSYNC_POLARITY */
+	l |= FLD_VAL(1, 21, 21);	/* HSYNCPOLARITY */
+	rfbi_write_reg(RFBI_CONFIG(rfbi_module), l);
+
+	rfbi_write_reg(RFBI_DATA_CYCLE1(rfbi_module), cycle1);
+	rfbi_write_reg(RFBI_DATA_CYCLE2(rfbi_module), cycle2);
+	rfbi_write_reg(RFBI_DATA_CYCLE3(rfbi_module), cycle3);
+
+
+	l = rfbi_read_reg(RFBI_CONTROL);
+	l = FLD_MOD(l, rfbi_module+1, 3, 2); /* Select CSx */
+	l = FLD_MOD(l, 0, 1, 1); /* clear bypass */
+	rfbi_write_reg(RFBI_CONTROL, l);
+
+
+	DSSDBG("RFBI config: bpp %d, lines %d, cycles: 0x%x 0x%x 0x%x\n",
+	       bpp, lines, cycle1, cycle2, cycle3);
+
+	rfbi_enable_clocks(0);
+
+	return 0;
+}
+EXPORT_SYMBOL(rfbi_configure);
+
+static int rfbi_find_display(struct omap_dss_device *dssdev)
+{
+	if (dssdev == rfbi.dssdev[0])
+		return 0;
+
+	if (dssdev == rfbi.dssdev[1])
+		return 1;
+
+	BUG();
+	return -1;
+}
+
+
+static void signal_fifo_waiters(void)
+{
+	if (atomic_read(&rfbi.cmd_fifo_full) > 0) {
+		/* DSSDBG("SIGNALING: Fifo not full for waiter!\n"); */
+		complete(&rfbi.cmd_done);
+		atomic_dec(&rfbi.cmd_fifo_full);
+	}
+}
+
+/* returns 1 for async op, and 0 for sync op */
+static int do_update(struct omap_dss_device *dssdev, struct update_region *upd)
+{
+	u16 x = upd->x;
+	u16 y = upd->y;
+	u16 w = upd->w;
+	u16 h = upd->h;
+
+	perf_mark_setup();
+
+	if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
+		/*dssdev->driver->enable_te(dssdev, 1); */
+		dss_setup_partial_planes(dssdev, &x, &y, &w, &h);
+	}
+
+#ifdef MEASURE_PERF
+	rfbi.perf_bytes = w * h * 2; /* XXX always 16bit */
+#endif
+
+	dssdev->driver->setup_update(dssdev, x, y, w, h);
+
+	if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
+		rfbi_transfer_area(w, h, NULL, NULL);
+		return 1;
+	} else {
+		struct omap_overlay *ovl;
+		void __iomem *addr;
+		int scr_width;
+
+		ovl = dssdev->manager->overlays[0];
+		scr_width = ovl->info.screen_width;
+		addr = ovl->info.vaddr;
+
+		omap_rfbi_write_pixels(addr, scr_width, x, y, w, h);
+
+		perf_show("L4");
+
+		return 0;
+	}
+}
+
+static void process_cmd_fifo(void)
+{
+	int len;
+	struct update_param p;
+	struct omap_dss_device *dssdev;
+	unsigned long flags;
+
+	if (atomic_inc_return(&rfbi.cmd_pending) != 1)
+		return;
+
+	while (true) {
+		spin_lock_irqsave(rfbi.cmd_fifo->lock, flags);
+
+		len = __kfifo_get(rfbi.cmd_fifo, (unsigned char *)&p,
+				  sizeof(struct update_param));
+		if (len == 0) {
+			DSSDBG("nothing more in fifo\n");
+			atomic_set(&rfbi.cmd_pending, 0);
+			spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags);
+			break;
+		}
+
+		/* DSSDBG("fifo full %d\n", rfbi.cmd_fifo_full.counter);*/
+
+		spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags);
+
+		BUG_ON(len != sizeof(struct update_param));
+		BUG_ON(p.rfbi_module > 1);
+
+		dssdev = rfbi.dssdev[p.rfbi_module];
+
+		if (p.cmd == RFBI_CMD_UPDATE) {
+			if (do_update(dssdev, &p.par.r))
+				break; /* async op */
+		} else if (p.cmd == RFBI_CMD_SYNC) {
+			DSSDBG("Signaling SYNC done!\n");
+			complete(p.par.sync);
+		} else
+			BUG();
+	}
+
+	signal_fifo_waiters();
+}
+
+static void rfbi_push_cmd(struct update_param *p)
+{
+	int ret;
+
+	while (1) {
+		unsigned long flags;
+		int available;
+
+		spin_lock_irqsave(rfbi.cmd_fifo->lock, flags);
+		available = RFBI_CMD_FIFO_LEN_BYTES -
+			__kfifo_len(rfbi.cmd_fifo);
+
+/*		DSSDBG("%d bytes left in fifo\n", available); */
+		if (available < sizeof(struct update_param)) {
+			DSSDBG("Going to wait because FIFO FULL..\n");
+			spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags);
+			atomic_inc(&rfbi.cmd_fifo_full);
+			wait_for_completion(&rfbi.cmd_done);
+			/*DSSDBG("Woke up because fifo not full anymore\n");*/
+			continue;
+		}
+
+		ret = __kfifo_put(rfbi.cmd_fifo, (unsigned char *)p,
+				  sizeof(struct update_param));
+/*		DSSDBG("pushed %d bytes\n", ret);*/
+
+		spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags);
+
+		BUG_ON(ret != sizeof(struct update_param));
+
+		break;
+	}
+}
+
+static void rfbi_push_update(int rfbi_module, int x, int y, int w, int h)
+{
+	struct update_param p;
+
+	p.rfbi_module = rfbi_module;
+	p.cmd = RFBI_CMD_UPDATE;
+
+	p.par.r.x = x;
+	p.par.r.y = y;
+	p.par.r.w = w;
+	p.par.r.h = h;
+
+	DSSDBG("RFBI pushed %d,%d %dx%d\n", x, y, w, h);
+
+	rfbi_push_cmd(&p);
+
+	process_cmd_fifo();
+}
+
+static void rfbi_push_sync(int rfbi_module, struct completion *sync_comp)
+{
+	struct update_param p;
+
+	p.rfbi_module = rfbi_module;
+	p.cmd = RFBI_CMD_SYNC;
+	p.par.sync = sync_comp;
+
+	rfbi_push_cmd(&p);
+
+	DSSDBG("RFBI sync pushed to cmd fifo\n");
+
+	process_cmd_fifo();
+}
+
+void rfbi_dump_regs(struct seq_file *s)
+{
+#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r))
+
+	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+
+	DUMPREG(RFBI_REVISION);
+	DUMPREG(RFBI_SYSCONFIG);
+	DUMPREG(RFBI_SYSSTATUS);
+	DUMPREG(RFBI_CONTROL);
+	DUMPREG(RFBI_PIXEL_CNT);
+	DUMPREG(RFBI_LINE_NUMBER);
+	DUMPREG(RFBI_CMD);
+	DUMPREG(RFBI_PARAM);
+	DUMPREG(RFBI_DATA);
+	DUMPREG(RFBI_READ);
+	DUMPREG(RFBI_STATUS);
+
+	DUMPREG(RFBI_CONFIG(0));
+	DUMPREG(RFBI_ONOFF_TIME(0));
+	DUMPREG(RFBI_CYCLE_TIME(0));
+	DUMPREG(RFBI_DATA_CYCLE1(0));
+	DUMPREG(RFBI_DATA_CYCLE2(0));
+	DUMPREG(RFBI_DATA_CYCLE3(0));
+
+	DUMPREG(RFBI_CONFIG(1));
+	DUMPREG(RFBI_ONOFF_TIME(1));
+	DUMPREG(RFBI_CYCLE_TIME(1));
+	DUMPREG(RFBI_DATA_CYCLE1(1));
+	DUMPREG(RFBI_DATA_CYCLE2(1));
+	DUMPREG(RFBI_DATA_CYCLE3(1));
+
+	DUMPREG(RFBI_VSYNC_WIDTH);
+	DUMPREG(RFBI_HSYNC_WIDTH);
+
+	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+#undef DUMPREG
+}
+
+int rfbi_init(void)
+{
+	u32 rev;
+	u32 l;
+
+	spin_lock_init(&rfbi.cmd_lock);
+	rfbi.cmd_fifo = kfifo_alloc(RFBI_CMD_FIFO_LEN_BYTES, GFP_KERNEL,
+				    &rfbi.cmd_lock);
+	if (IS_ERR(rfbi.cmd_fifo))
+		return -ENOMEM;
+
+	init_completion(&rfbi.cmd_done);
+	atomic_set(&rfbi.cmd_fifo_full, 0);
+	atomic_set(&rfbi.cmd_pending, 0);
+
+	rfbi.base = ioremap(RFBI_BASE, SZ_256);
+	if (!rfbi.base) {
+		DSSERR("can't ioremap RFBI\n");
+		return -ENOMEM;
+	}
+
+	rfbi_enable_clocks(1);
+
+	msleep(10);
+
+	rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000;
+
+	/* Enable autoidle and smart-idle */
+	l = rfbi_read_reg(RFBI_SYSCONFIG);
+	l |= (1 << 0) | (2 << 3);
+	rfbi_write_reg(RFBI_SYSCONFIG, l);
+
+	rev = rfbi_read_reg(RFBI_REVISION);
+	printk(KERN_INFO "OMAP RFBI rev %d.%d\n",
+	       FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
+
+	rfbi_enable_clocks(0);
+
+	return 0;
+}
+
+void rfbi_exit(void)
+{
+	DSSDBG("rfbi_exit\n");
+
+	kfifo_free(rfbi.cmd_fifo);
+
+	iounmap(rfbi.base);
+}
+
+/* struct omap_display support */
+static int rfbi_display_update(struct omap_dss_device *dssdev,
+			u16 x, u16 y, u16 w, u16 h)
+{
+	int rfbi_module;
+
+	if (w == 0 || h == 0)
+		return 0;
+
+	rfbi_module = rfbi_find_display(dssdev);
+
+	rfbi_push_update(rfbi_module, x, y, w, h);
+
+	return 0;
+}
+
+static int rfbi_display_sync(struct omap_dss_device *dssdev)
+{
+	struct completion sync_comp;
+	int rfbi_module;
+
+	rfbi_module = rfbi_find_display(dssdev);
+
+	init_completion(&sync_comp);
+	rfbi_push_sync(rfbi_module, &sync_comp);
+	DSSDBG("Waiting for SYNC to happen...\n");
+	wait_for_completion(&sync_comp);
+	DSSDBG("Released from SYNC\n");
+	return 0;
+}
+
+static int rfbi_display_enable_te(struct omap_dss_device *dssdev, bool enable)
+{
+	dssdev->driver->enable_te(dssdev, enable);
+	return 0;
+}
+
+static int rfbi_display_enable(struct omap_dss_device *dssdev)
+{
+	int r;
+
+	r = omap_dss_start_device(dssdev);
+	if (r) {
+		DSSERR("failed to start device\n");
+		goto err0;
+	}
+
+	r = omap_dispc_register_isr(framedone_callback, NULL,
+			DISPC_IRQ_FRAMEDONE);
+	if (r) {
+		DSSERR("can't get FRAMEDONE irq\n");
+		goto err1;
+	}
+
+	dispc_set_lcd_display_type(OMAP_DSS_LCD_DISPLAY_TFT);
+
+	dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_RFBI);
+
+	dispc_set_tft_data_lines(dssdev->ctrl.pixel_size);
+
+	rfbi_configure(dssdev->phy.rfbi.channel,
+			       dssdev->ctrl.pixel_size,
+			       dssdev->phy.rfbi.data_lines);
+
+	rfbi_set_timings(dssdev->phy.rfbi.channel,
+			 &dssdev->ctrl.rfbi_timings);
+
+
+	if (dssdev->driver->enable) {
+		r = dssdev->driver->enable(dssdev);
+		if (r)
+			goto err2;
+	}
+
+	return 0;
+err2:
+	omap_dispc_unregister_isr(framedone_callback, NULL,
+			DISPC_IRQ_FRAMEDONE);
+err1:
+	omap_dss_stop_device(dssdev);
+err0:
+	return r;
+}
+
+static void rfbi_display_disable(struct omap_dss_device *dssdev)
+{
+	dssdev->driver->disable(dssdev);
+	omap_dispc_unregister_isr(framedone_callback, NULL,
+			DISPC_IRQ_FRAMEDONE);
+	omap_dss_stop_device(dssdev);
+}
+
+int rfbi_init_display(struct omap_dss_device *dssdev)
+{
+	dssdev->enable = rfbi_display_enable;
+	dssdev->disable = rfbi_display_disable;
+	dssdev->update = rfbi_display_update;
+	dssdev->sync = rfbi_display_sync;
+	dssdev->enable_te = rfbi_display_enable_te;
+
+	rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev;
+
+	dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
+
+	return 0;
+}
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
new file mode 100644
index 0000000..c24f307
--- /dev/null
+++ b/drivers/video/omap2/dss/sdi.c
@@ -0,0 +1,277 @@
+/*
+ * linux/drivers/video/omap2/dss/sdi.c
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define DSS_SUBSYS_NAME "SDI"
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+
+#include <plat/display.h>
+#include "dss.h"
+
+static struct {
+	bool skip_init;
+	bool update_enabled;
+} sdi;
+
+static void sdi_basic_init(void)
+{
+	dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_BYPASS);
+
+	dispc_set_lcd_display_type(OMAP_DSS_LCD_DISPLAY_TFT);
+	dispc_set_tft_data_lines(24);
+	dispc_lcd_enable_signal_polarity(1);
+}
+
+static int sdi_display_enable(struct omap_dss_device *dssdev)
+{
+	struct omap_video_timings *t = &dssdev->panel.timings;
+	struct dss_clock_info dss_cinfo;
+	struct dispc_clock_info dispc_cinfo;
+	u16 lck_div, pck_div;
+	unsigned long fck;
+	unsigned long pck;
+	int r;
+
+	r = omap_dss_start_device(dssdev);
+	if (r) {
+		DSSERR("failed to start device\n");
+		goto err0;
+	}
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
+		DSSERR("dssdev already enabled\n");
+		r = -EINVAL;
+		goto err1;
+	}
+
+	/* In case of skip_init sdi_init has already enabled the clocks */
+	if (!sdi.skip_init)
+		dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+
+	sdi_basic_init();
+
+	/* 15.5.9.1.2 */
+	dssdev->panel.config |= OMAP_DSS_LCD_RF | OMAP_DSS_LCD_ONOFF;
+
+	dispc_set_pol_freq(dssdev->panel.config, dssdev->panel.acbi,
+			dssdev->panel.acb);
+
+	if (!sdi.skip_init) {
+		r = dss_calc_clock_div(1, t->pixel_clock * 1000,
+				&dss_cinfo, &dispc_cinfo);
+	} else {
+		r = dss_get_clock_div(&dss_cinfo);
+		r = dispc_get_clock_div(&dispc_cinfo);
+	}
+
+	if (r)
+		goto err2;
+
+	fck = dss_cinfo.fck;
+	lck_div = dispc_cinfo.lck_div;
+	pck_div = dispc_cinfo.pck_div;
+
+	pck = fck / lck_div / pck_div / 1000;
+
+	if (pck != t->pixel_clock) {
+		DSSWARN("Could not find exact pixel clock. Requested %d kHz, "
+				"got %lu kHz\n",
+				t->pixel_clock, pck);
+
+		t->pixel_clock = pck;
+	}
+
+
+	dispc_set_lcd_timings(t);
+
+	r = dss_set_clock_div(&dss_cinfo);
+	if (r)
+		goto err2;
+
+	r = dispc_set_clock_div(&dispc_cinfo);
+	if (r)
+		goto err2;
+
+	if (!sdi.skip_init) {
+		dss_sdi_init(dssdev->phy.sdi.datapairs);
+		r = dss_sdi_enable();
+		if (r)
+			goto err1;
+		mdelay(2);
+	}
+
+	dispc_enable_lcd_out(1);
+
+	if (dssdev->driver->enable) {
+		r = dssdev->driver->enable(dssdev);
+		if (r)
+			goto err3;
+	}
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	sdi.skip_init = 0;
+
+	return 0;
+err3:
+	dispc_enable_lcd_out(0);
+err2:
+	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+err1:
+	omap_dss_stop_device(dssdev);
+err0:
+	return r;
+}
+
+static int sdi_display_resume(struct omap_dss_device *dssdev);
+
+static void sdi_display_disable(struct omap_dss_device *dssdev)
+{
+	if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
+		return;
+
+	if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
+		if (sdi_display_resume(dssdev))
+			return;
+
+	if (dssdev->driver->disable)
+		dssdev->driver->disable(dssdev);
+
+	dispc_enable_lcd_out(0);
+
+	dss_sdi_disable();
+
+	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+
+	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+
+	omap_dss_stop_device(dssdev);
+}
+
+static int sdi_display_suspend(struct omap_dss_device *dssdev)
+{
+	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+		return -EINVAL;
+
+	if (dssdev->driver->suspend)
+		dssdev->driver->suspend(dssdev);
+
+	dispc_enable_lcd_out(0);
+
+	dss_sdi_disable();
+
+	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+
+	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
+
+	return 0;
+}
+
+static int sdi_display_resume(struct omap_dss_device *dssdev)
+{
+	int r;
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED)
+		return -EINVAL;
+
+	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+
+	r = dss_sdi_enable();
+	if (r)
+		goto err;
+	mdelay(2);
+
+	dispc_enable_lcd_out(1);
+
+	if (dssdev->driver->resume)
+		dssdev->driver->resume(dssdev);
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	return 0;
+err:
+	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+	return r;
+}
+
+static int sdi_display_set_update_mode(struct omap_dss_device *dssdev,
+		enum omap_dss_update_mode mode)
+{
+	if (mode == OMAP_DSS_UPDATE_MANUAL)
+		return -EINVAL;
+
+	if (mode == OMAP_DSS_UPDATE_DISABLED) {
+		dispc_enable_lcd_out(0);
+		sdi.update_enabled = 0;
+	} else {
+		dispc_enable_lcd_out(1);
+		sdi.update_enabled = 1;
+	}
+
+	return 0;
+}
+
+static enum omap_dss_update_mode sdi_display_get_update_mode(
+		struct omap_dss_device *dssdev)
+{
+	return sdi.update_enabled ? OMAP_DSS_UPDATE_AUTO :
+		OMAP_DSS_UPDATE_DISABLED;
+}
+
+static void sdi_get_timings(struct omap_dss_device *dssdev,
+			struct omap_video_timings *timings)
+{
+	*timings = dssdev->panel.timings;
+}
+
+int sdi_init_display(struct omap_dss_device *dssdev)
+{
+	DSSDBG("SDI init\n");
+
+	dssdev->enable = sdi_display_enable;
+	dssdev->disable = sdi_display_disable;
+	dssdev->suspend = sdi_display_suspend;
+	dssdev->resume = sdi_display_resume;
+	dssdev->set_update_mode = sdi_display_set_update_mode;
+	dssdev->get_update_mode = sdi_display_get_update_mode;
+	dssdev->get_timings = sdi_get_timings;
+
+	return 0;
+}
+
+int sdi_init(bool skip_init)
+{
+	/* we store this for first display enable, then clear it */
+	sdi.skip_init = skip_init;
+
+	/*
+	 * Enable clocks already here, otherwise there would be a toggle
+	 * of them until sdi_display_enable is called.
+	 */
+	if (skip_init)
+		dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+	return 0;
+}
+
+void sdi_exit(void)
+{
+}
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
new file mode 100644
index 0000000..749a5a0
--- /dev/null
+++ b/drivers/video/omap2/dss/venc.c
@@ -0,0 +1,797 @@
+/*
+ * linux/drivers/video/omap2/dss/venc.c
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * VENC settings from TI's DSS driver
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define DSS_SUBSYS_NAME "VENC"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/seq_file.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+
+#include <plat/display.h>
+#include <plat/cpu.h>
+
+#include "dss.h"
+
+#define VENC_BASE	0x48050C00
+
+/* Venc registers */
+#define VENC_REV_ID				0x00
+#define VENC_STATUS				0x04
+#define VENC_F_CONTROL				0x08
+#define VENC_VIDOUT_CTRL			0x10
+#define VENC_SYNC_CTRL				0x14
+#define VENC_LLEN				0x1C
+#define VENC_FLENS				0x20
+#define VENC_HFLTR_CTRL				0x24
+#define VENC_CC_CARR_WSS_CARR			0x28
+#define VENC_C_PHASE				0x2C
+#define VENC_GAIN_U				0x30
+#define VENC_GAIN_V				0x34
+#define VENC_GAIN_Y				0x38
+#define VENC_BLACK_LEVEL			0x3C
+#define VENC_BLANK_LEVEL			0x40
+#define VENC_X_COLOR				0x44
+#define VENC_M_CONTROL				0x48
+#define VENC_BSTAMP_WSS_DATA			0x4C
+#define VENC_S_CARR				0x50
+#define VENC_LINE21				0x54
+#define VENC_LN_SEL				0x58
+#define VENC_L21__WC_CTL			0x5C
+#define VENC_HTRIGGER_VTRIGGER			0x60
+#define VENC_SAVID__EAVID			0x64
+#define VENC_FLEN__FAL				0x68
+#define VENC_LAL__PHASE_RESET			0x6C
+#define VENC_HS_INT_START_STOP_X		0x70
+#define VENC_HS_EXT_START_STOP_X		0x74
+#define VENC_VS_INT_START_X			0x78
+#define VENC_VS_INT_STOP_X__VS_INT_START_Y	0x7C
+#define VENC_VS_INT_STOP_Y__VS_EXT_START_X	0x80
+#define VENC_VS_EXT_STOP_X__VS_EXT_START_Y	0x84
+#define VENC_VS_EXT_STOP_Y			0x88
+#define VENC_AVID_START_STOP_X			0x90
+#define VENC_AVID_START_STOP_Y			0x94
+#define VENC_FID_INT_START_X__FID_INT_START_Y	0xA0
+#define VENC_FID_INT_OFFSET_Y__FID_EXT_START_X	0xA4
+#define VENC_FID_EXT_START_Y__FID_EXT_OFFSET_Y	0xA8
+#define VENC_TVDETGP_INT_START_STOP_X		0xB0
+#define VENC_TVDETGP_INT_START_STOP_Y		0xB4
+#define VENC_GEN_CTRL				0xB8
+#define VENC_OUTPUT_CONTROL			0xC4
+#define VENC_OUTPUT_TEST			0xC8
+#define VENC_DAC_B__DAC_C			0xC8
+
+struct venc_config {
+	u32 f_control;
+	u32 vidout_ctrl;
+	u32 sync_ctrl;
+	u32 llen;
+	u32 flens;
+	u32 hfltr_ctrl;
+	u32 cc_carr_wss_carr;
+	u32 c_phase;
+	u32 gain_u;
+	u32 gain_v;
+	u32 gain_y;
+	u32 black_level;
+	u32 blank_level;
+	u32 x_color;
+	u32 m_control;
+	u32 bstamp_wss_data;
+	u32 s_carr;
+	u32 line21;
+	u32 ln_sel;
+	u32 l21__wc_ctl;
+	u32 htrigger_vtrigger;
+	u32 savid__eavid;
+	u32 flen__fal;
+	u32 lal__phase_reset;
+	u32 hs_int_start_stop_x;
+	u32 hs_ext_start_stop_x;
+	u32 vs_int_start_x;
+	u32 vs_int_stop_x__vs_int_start_y;
+	u32 vs_int_stop_y__vs_ext_start_x;
+	u32 vs_ext_stop_x__vs_ext_start_y;
+	u32 vs_ext_stop_y;
+	u32 avid_start_stop_x;
+	u32 avid_start_stop_y;
+	u32 fid_int_start_x__fid_int_start_y;
+	u32 fid_int_offset_y__fid_ext_start_x;
+	u32 fid_ext_start_y__fid_ext_offset_y;
+	u32 tvdetgp_int_start_stop_x;
+	u32 tvdetgp_int_start_stop_y;
+	u32 gen_ctrl;
+};
+
+/* from TRM */
+static const struct venc_config venc_config_pal_trm = {
+	.f_control				= 0,
+	.vidout_ctrl				= 1,
+	.sync_ctrl				= 0x40,
+	.llen					= 0x35F, /* 863 */
+	.flens					= 0x270, /* 624 */
+	.hfltr_ctrl				= 0,
+	.cc_carr_wss_carr			= 0x2F7225ED,
+	.c_phase				= 0,
+	.gain_u					= 0x111,
+	.gain_v					= 0x181,
+	.gain_y					= 0x140,
+	.black_level				= 0x3B,
+	.blank_level				= 0x3B,
+	.x_color				= 0x7,
+	.m_control				= 0x2,
+	.bstamp_wss_data			= 0x3F,
+	.s_carr					= 0x2A098ACB,
+	.line21					= 0,
+	.ln_sel					= 0x01290015,
+	.l21__wc_ctl				= 0x0000F603,
+	.htrigger_vtrigger			= 0,
+
+	.savid__eavid				= 0x06A70108,
+	.flen__fal				= 0x00180270,
+	.lal__phase_reset			= 0x00040135,
+	.hs_int_start_stop_x			= 0x00880358,
+	.hs_ext_start_stop_x			= 0x000F035F,
+	.vs_int_start_x				= 0x01A70000,
+	.vs_int_stop_x__vs_int_start_y		= 0x000001A7,
+	.vs_int_stop_y__vs_ext_start_x		= 0x01AF0000,
+	.vs_ext_stop_x__vs_ext_start_y		= 0x000101AF,
+	.vs_ext_stop_y				= 0x00000025,
+	.avid_start_stop_x			= 0x03530083,
+	.avid_start_stop_y			= 0x026C002E,
+	.fid_int_start_x__fid_int_start_y	= 0x0001008A,
+	.fid_int_offset_y__fid_ext_start_x	= 0x002E0138,
+	.fid_ext_start_y__fid_ext_offset_y	= 0x01380001,
+
+	.tvdetgp_int_start_stop_x		= 0x00140001,
+	.tvdetgp_int_start_stop_y		= 0x00010001,
+	.gen_ctrl				= 0x00FF0000,
+};
+
+/* from TRM */
+static const struct venc_config venc_config_ntsc_trm = {
+	.f_control				= 0,
+	.vidout_ctrl				= 1,
+	.sync_ctrl				= 0x8040,
+	.llen					= 0x359,
+	.flens					= 0x20C,
+	.hfltr_ctrl				= 0,
+	.cc_carr_wss_carr			= 0x043F2631,
+	.c_phase				= 0,
+	.gain_u					= 0x102,
+	.gain_v					= 0x16C,
+	.gain_y					= 0x12F,
+	.black_level				= 0x43,
+	.blank_level				= 0x38,
+	.x_color				= 0x7,
+	.m_control				= 0x1,
+	.bstamp_wss_data			= 0x38,
+	.s_carr					= 0x21F07C1F,
+	.line21					= 0,
+	.ln_sel					= 0x01310011,
+	.l21__wc_ctl				= 0x0000F003,
+	.htrigger_vtrigger			= 0,
+
+	.savid__eavid				= 0x069300F4,
+	.flen__fal				= 0x0016020C,
+	.lal__phase_reset			= 0x00060107,
+	.hs_int_start_stop_x			= 0x008E0350,
+	.hs_ext_start_stop_x			= 0x000F0359,
+	.vs_int_start_x				= 0x01A00000,
+	.vs_int_stop_x__vs_int_start_y		= 0x020701A0,
+	.vs_int_stop_y__vs_ext_start_x		= 0x01AC0024,
+	.vs_ext_stop_x__vs_ext_start_y		= 0x020D01AC,
+	.vs_ext_stop_y				= 0x00000006,
+	.avid_start_stop_x			= 0x03480078,
+	.avid_start_stop_y			= 0x02060024,
+	.fid_int_start_x__fid_int_start_y	= 0x0001008A,
+	.fid_int_offset_y__fid_ext_start_x	= 0x01AC0106,
+	.fid_ext_start_y__fid_ext_offset_y	= 0x01060006,
+
+	.tvdetgp_int_start_stop_x		= 0x00140001,
+	.tvdetgp_int_start_stop_y		= 0x00010001,
+	.gen_ctrl				= 0x00F90000,
+};
+
+static const struct venc_config venc_config_pal_bdghi = {
+	.f_control				= 0,
+	.vidout_ctrl				= 0,
+	.sync_ctrl				= 0,
+	.hfltr_ctrl				= 0,
+	.x_color				= 0,
+	.line21					= 0,
+	.ln_sel					= 21,
+	.htrigger_vtrigger			= 0,
+	.tvdetgp_int_start_stop_x		= 0x00140001,
+	.tvdetgp_int_start_stop_y		= 0x00010001,
+	.gen_ctrl				= 0x00FB0000,
+
+	.llen					= 864-1,
+	.flens					= 625-1,
+	.cc_carr_wss_carr			= 0x2F7625ED,
+	.c_phase				= 0xDF,
+	.gain_u					= 0x111,
+	.gain_v					= 0x181,
+	.gain_y					= 0x140,
+	.black_level				= 0x3e,
+	.blank_level				= 0x3e,
+	.m_control				= 0<<2 | 1<<1,
+	.bstamp_wss_data			= 0x42,
+	.s_carr					= 0x2a098acb,
+	.l21__wc_ctl				= 0<<13 | 0x16<<8 | 0<<0,
+	.savid__eavid				= 0x06A70108,
+	.flen__fal				= 23<<16 | 624<<0,
+	.lal__phase_reset			= 2<<17 | 310<<0,
+	.hs_int_start_stop_x			= 0x00920358,
+	.hs_ext_start_stop_x			= 0x000F035F,
+	.vs_int_start_x				= 0x1a7<<16,
+	.vs_int_stop_x__vs_int_start_y		= 0x000601A7,
+	.vs_int_stop_y__vs_ext_start_x		= 0x01AF0036,
+	.vs_ext_stop_x__vs_ext_start_y		= 0x27101af,
+	.vs_ext_stop_y				= 0x05,
+	.avid_start_stop_x			= 0x03530082,
+	.avid_start_stop_y			= 0x0270002E,
+	.fid_int_start_x__fid_int_start_y	= 0x0005008A,
+	.fid_int_offset_y__fid_ext_start_x	= 0x002E0138,
+	.fid_ext_start_y__fid_ext_offset_y	= 0x01380005,
+};
+
+const struct omap_video_timings omap_dss_pal_timings = {
+	.x_res		= 720,
+	.y_res		= 574,
+	.pixel_clock	= 13500,
+	.hsw		= 64,
+	.hfp		= 12,
+	.hbp		= 68,
+	.vsw		= 5,
+	.vfp		= 5,
+	.vbp		= 41,
+};
+EXPORT_SYMBOL(omap_dss_pal_timings);
+
+const struct omap_video_timings omap_dss_ntsc_timings = {
+	.x_res		= 720,
+	.y_res		= 482,
+	.pixel_clock	= 13500,
+	.hsw		= 64,
+	.hfp		= 16,
+	.hbp		= 58,
+	.vsw		= 6,
+	.vfp		= 6,
+	.vbp		= 31,
+};
+EXPORT_SYMBOL(omap_dss_ntsc_timings);
+
+static struct {
+	void __iomem *base;
+	struct mutex venc_lock;
+	u32 wss_data;
+	struct regulator *vdda_dac_reg;
+} venc;
+
+static inline void venc_write_reg(int idx, u32 val)
+{
+	__raw_writel(val, venc.base + idx);
+}
+
+static inline u32 venc_read_reg(int idx)
+{
+	u32 l = __raw_readl(venc.base + idx);
+	return l;
+}
+
+static void venc_write_config(const struct venc_config *config)
+{
+	DSSDBG("write venc conf\n");
+
+	venc_write_reg(VENC_LLEN, config->llen);
+	venc_write_reg(VENC_FLENS, config->flens);
+	venc_write_reg(VENC_CC_CARR_WSS_CARR, config->cc_carr_wss_carr);
+	venc_write_reg(VENC_C_PHASE, config->c_phase);
+	venc_write_reg(VENC_GAIN_U, config->gain_u);
+	venc_write_reg(VENC_GAIN_V, config->gain_v);
+	venc_write_reg(VENC_GAIN_Y, config->gain_y);
+	venc_write_reg(VENC_BLACK_LEVEL, config->black_level);
+	venc_write_reg(VENC_BLANK_LEVEL, config->blank_level);
+	venc_write_reg(VENC_M_CONTROL, config->m_control);
+	venc_write_reg(VENC_BSTAMP_WSS_DATA, config->bstamp_wss_data |
+			venc.wss_data);
+	venc_write_reg(VENC_S_CARR, config->s_carr);
+	venc_write_reg(VENC_L21__WC_CTL, config->l21__wc_ctl);
+	venc_write_reg(VENC_SAVID__EAVID, config->savid__eavid);
+	venc_write_reg(VENC_FLEN__FAL, config->flen__fal);
+	venc_write_reg(VENC_LAL__PHASE_RESET, config->lal__phase_reset);
+	venc_write_reg(VENC_HS_INT_START_STOP_X, config->hs_int_start_stop_x);
+	venc_write_reg(VENC_HS_EXT_START_STOP_X, config->hs_ext_start_stop_x);
+	venc_write_reg(VENC_VS_INT_START_X, config->vs_int_start_x);
+	venc_write_reg(VENC_VS_INT_STOP_X__VS_INT_START_Y,
+		       config->vs_int_stop_x__vs_int_start_y);
+	venc_write_reg(VENC_VS_INT_STOP_Y__VS_EXT_START_X,
+		       config->vs_int_stop_y__vs_ext_start_x);
+	venc_write_reg(VENC_VS_EXT_STOP_X__VS_EXT_START_Y,
+		       config->vs_ext_stop_x__vs_ext_start_y);
+	venc_write_reg(VENC_VS_EXT_STOP_Y, config->vs_ext_stop_y);
+	venc_write_reg(VENC_AVID_START_STOP_X, config->avid_start_stop_x);
+	venc_write_reg(VENC_AVID_START_STOP_Y, config->avid_start_stop_y);
+	venc_write_reg(VENC_FID_INT_START_X__FID_INT_START_Y,
+		       config->fid_int_start_x__fid_int_start_y);
+	venc_write_reg(VENC_FID_INT_OFFSET_Y__FID_EXT_START_X,
+		       config->fid_int_offset_y__fid_ext_start_x);
+	venc_write_reg(VENC_FID_EXT_START_Y__FID_EXT_OFFSET_Y,
+		       config->fid_ext_start_y__fid_ext_offset_y);
+
+	venc_write_reg(VENC_DAC_B__DAC_C,  venc_read_reg(VENC_DAC_B__DAC_C));
+	venc_write_reg(VENC_VIDOUT_CTRL, config->vidout_ctrl);
+	venc_write_reg(VENC_HFLTR_CTRL, config->hfltr_ctrl);
+	venc_write_reg(VENC_X_COLOR, config->x_color);
+	venc_write_reg(VENC_LINE21, config->line21);
+	venc_write_reg(VENC_LN_SEL, config->ln_sel);
+	venc_write_reg(VENC_HTRIGGER_VTRIGGER, config->htrigger_vtrigger);
+	venc_write_reg(VENC_TVDETGP_INT_START_STOP_X,
+		       config->tvdetgp_int_start_stop_x);
+	venc_write_reg(VENC_TVDETGP_INT_START_STOP_Y,
+		       config->tvdetgp_int_start_stop_y);
+	venc_write_reg(VENC_GEN_CTRL, config->gen_ctrl);
+	venc_write_reg(VENC_F_CONTROL, config->f_control);
+	venc_write_reg(VENC_SYNC_CTRL, config->sync_ctrl);
+}
+
+static void venc_reset(void)
+{
+	int t = 1000;
+
+	venc_write_reg(VENC_F_CONTROL, 1<<8);
+	while (venc_read_reg(VENC_F_CONTROL) & (1<<8)) {
+		if (--t == 0) {
+			DSSERR("Failed to reset venc\n");
+			return;
+		}
+	}
+
+	/* the magical sleep that makes things work */
+	msleep(20);
+}
+
+static void venc_enable_clocks(int enable)
+{
+	if (enable)
+		dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M |
+				DSS_CLK_96M);
+	else
+		dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M |
+				DSS_CLK_96M);
+}
+
+static const struct venc_config *venc_timings_to_config(
+		struct omap_video_timings *timings)
+{
+	if (memcmp(&omap_dss_pal_timings, timings, sizeof(*timings)) == 0)
+		return &venc_config_pal_trm;
+
+	if (memcmp(&omap_dss_ntsc_timings, timings, sizeof(*timings)) == 0)
+		return &venc_config_ntsc_trm;
+
+	BUG();
+}
+
+
+
+
+
+/* driver */
+static int venc_panel_probe(struct omap_dss_device *dssdev)
+{
+	dssdev->panel.timings = omap_dss_pal_timings;
+
+	return 0;
+}
+
+static void venc_panel_remove(struct omap_dss_device *dssdev)
+{
+}
+
+static int venc_panel_enable(struct omap_dss_device *dssdev)
+{
+	int r = 0;
+
+	/* wait couple of vsyncs until enabling the LCD */
+	msleep(50);
+
+	if (dssdev->platform_enable)
+		r = dssdev->platform_enable(dssdev);
+
+	return r;
+}
+
+static void venc_panel_disable(struct omap_dss_device *dssdev)
+{
+	if (dssdev->platform_disable)
+		dssdev->platform_disable(dssdev);
+
+	/* wait at least 5 vsyncs after disabling the LCD */
+
+	msleep(100);
+}
+
+static int venc_panel_suspend(struct omap_dss_device *dssdev)
+{
+	venc_panel_disable(dssdev);
+	return 0;
+}
+
+static int venc_panel_resume(struct omap_dss_device *dssdev)
+{
+	return venc_panel_enable(dssdev);
+}
+
+static struct omap_dss_driver venc_driver = {
+	.probe		= venc_panel_probe,
+	.remove		= venc_panel_remove,
+
+	.enable		= venc_panel_enable,
+	.disable	= venc_panel_disable,
+	.suspend	= venc_panel_suspend,
+	.resume		= venc_panel_resume,
+
+	.driver         = {
+		.name   = "venc",
+		.owner  = THIS_MODULE,
+	},
+};
+/* driver end */
+
+
+
+int venc_init(struct platform_device *pdev)
+{
+	u8 rev_id;
+
+	mutex_init(&venc.venc_lock);
+
+	venc.wss_data = 0;
+
+	venc.base = ioremap(VENC_BASE, SZ_1K);
+	if (!venc.base) {
+		DSSERR("can't ioremap VENC\n");
+		return -ENOMEM;
+	}
+
+	venc.vdda_dac_reg = regulator_get(&pdev->dev, "vdda_dac");
+	if (IS_ERR(venc.vdda_dac_reg)) {
+		iounmap(venc.base);
+		DSSERR("can't get VDDA_DAC regulator\n");
+		return PTR_ERR(venc.vdda_dac_reg);
+	}
+
+	venc_enable_clocks(1);
+
+	rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
+	printk(KERN_INFO "OMAP VENC rev %d\n", rev_id);
+
+	venc_enable_clocks(0);
+
+	return omap_dss_register_driver(&venc_driver);
+}
+
+void venc_exit(void)
+{
+	omap_dss_unregister_driver(&venc_driver);
+
+	regulator_put(venc.vdda_dac_reg);
+
+	iounmap(venc.base);
+}
+
+static void venc_power_on(struct omap_dss_device *dssdev)
+{
+	u32 l;
+
+	venc_enable_clocks(1);
+
+	venc_reset();
+	venc_write_config(venc_timings_to_config(&dssdev->panel.timings));
+
+	dss_set_venc_output(dssdev->phy.venc.type);
+	dss_set_dac_pwrdn_bgz(1);
+
+	l = 0;
+
+	if (dssdev->phy.venc.type == OMAP_DSS_VENC_TYPE_COMPOSITE)
+		l |= 1 << 1;
+	else /* S-Video */
+		l |= (1 << 0) | (1 << 2);
+
+	if (dssdev->phy.venc.invert_polarity == false)
+		l |= 1 << 3;
+
+	venc_write_reg(VENC_OUTPUT_CONTROL, l);
+
+	dispc_set_digit_size(dssdev->panel.timings.x_res,
+			dssdev->panel.timings.y_res/2);
+
+	regulator_enable(venc.vdda_dac_reg);
+
+	if (dssdev->platform_enable)
+		dssdev->platform_enable(dssdev);
+
+	dispc_enable_digit_out(1);
+}
+
+static void venc_power_off(struct omap_dss_device *dssdev)
+{
+	venc_write_reg(VENC_OUTPUT_CONTROL, 0);
+	dss_set_dac_pwrdn_bgz(0);
+
+	dispc_enable_digit_out(0);
+
+	if (dssdev->platform_disable)
+		dssdev->platform_disable(dssdev);
+
+	regulator_disable(venc.vdda_dac_reg);
+
+	venc_enable_clocks(0);
+}
+
+static int venc_enable_display(struct omap_dss_device *dssdev)
+{
+	int r = 0;
+
+	DSSDBG("venc_enable_display\n");
+
+	mutex_lock(&venc.venc_lock);
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
+		r = -EINVAL;
+		goto err;
+	}
+
+	venc_power_on(dssdev);
+
+	venc.wss_data = 0;
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+err:
+	mutex_unlock(&venc.venc_lock);
+
+	return r;
+}
+
+static void venc_disable_display(struct omap_dss_device *dssdev)
+{
+	DSSDBG("venc_disable_display\n");
+
+	mutex_lock(&venc.venc_lock);
+
+	if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
+		goto end;
+
+	if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) {
+		/* suspended is the same as disabled with venc */
+		dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+		goto end;
+	}
+
+	venc_power_off(dssdev);
+
+	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+end:
+	mutex_unlock(&venc.venc_lock);
+}
+
+static int venc_display_suspend(struct omap_dss_device *dssdev)
+{
+	int r = 0;
+
+	DSSDBG("venc_display_suspend\n");
+
+	mutex_lock(&venc.venc_lock);
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
+		r = -EINVAL;
+		goto err;
+	}
+
+	venc_power_off(dssdev);
+
+	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
+err:
+	mutex_unlock(&venc.venc_lock);
+
+	return r;
+}
+
+static int venc_display_resume(struct omap_dss_device *dssdev)
+{
+	int r = 0;
+
+	DSSDBG("venc_display_resume\n");
+
+	mutex_lock(&venc.venc_lock);
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
+		r = -EINVAL;
+		goto err;
+	}
+
+	venc_power_on(dssdev);
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+err:
+	mutex_unlock(&venc.venc_lock);
+
+	return r;
+}
+
+static void venc_get_timings(struct omap_dss_device *dssdev,
+			struct omap_video_timings *timings)
+{
+	*timings = dssdev->panel.timings;
+}
+
+static void venc_set_timings(struct omap_dss_device *dssdev,
+			struct omap_video_timings *timings)
+{
+	DSSDBG("venc_set_timings\n");
+
+	/* Reset WSS data when the TV standard changes. */
+	if (memcmp(&dssdev->panel.timings, timings, sizeof(*timings)))
+		venc.wss_data = 0;
+
+	dssdev->panel.timings = *timings;
+	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
+		/* turn the venc off and on to get new timings to use */
+		venc_disable_display(dssdev);
+		venc_enable_display(dssdev);
+	}
+}
+
+static int venc_check_timings(struct omap_dss_device *dssdev,
+			struct omap_video_timings *timings)
+{
+	DSSDBG("venc_check_timings\n");
+
+	if (memcmp(&omap_dss_pal_timings, timings, sizeof(*timings)) == 0)
+		return 0;
+
+	if (memcmp(&omap_dss_ntsc_timings, timings, sizeof(*timings)) == 0)
+		return 0;
+
+	return -EINVAL;
+}
+
+static u32 venc_get_wss(struct omap_dss_device *dssdev)
+{
+	/* Invert due to VENC_L21_WC_CTL:INV=1 */
+	return (venc.wss_data >> 8) ^ 0xfffff;
+}
+
+static int venc_set_wss(struct omap_dss_device *dssdev,	u32 wss)
+{
+	const struct venc_config *config;
+
+	DSSDBG("venc_set_wss\n");
+
+	mutex_lock(&venc.venc_lock);
+
+	config = venc_timings_to_config(&dssdev->panel.timings);
+
+	/* Invert due to VENC_L21_WC_CTL:INV=1 */
+	venc.wss_data = (wss ^ 0xfffff) << 8;
+
+	venc_enable_clocks(1);
+
+	venc_write_reg(VENC_BSTAMP_WSS_DATA, config->bstamp_wss_data |
+			venc.wss_data);
+
+	venc_enable_clocks(0);
+
+	mutex_unlock(&venc.venc_lock);
+
+	return 0;
+}
+
+static enum omap_dss_update_mode venc_display_get_update_mode(
+		struct omap_dss_device *dssdev)
+{
+	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
+		return OMAP_DSS_UPDATE_AUTO;
+	else
+		return OMAP_DSS_UPDATE_DISABLED;
+}
+
+int venc_init_display(struct omap_dss_device *dssdev)
+{
+	DSSDBG("init_display\n");
+
+	dssdev->enable = venc_enable_display;
+	dssdev->disable = venc_disable_display;
+	dssdev->suspend = venc_display_suspend;
+	dssdev->resume = venc_display_resume;
+	dssdev->get_timings = venc_get_timings;
+	dssdev->set_timings = venc_set_timings;
+	dssdev->check_timings = venc_check_timings;
+	dssdev->get_wss = venc_get_wss;
+	dssdev->set_wss = venc_set_wss;
+	dssdev->get_update_mode = venc_display_get_update_mode;
+
+	return 0;
+}
+
+void venc_dump_regs(struct seq_file *s)
+{
+#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r))
+
+	venc_enable_clocks(1);
+
+	DUMPREG(VENC_F_CONTROL);
+	DUMPREG(VENC_VIDOUT_CTRL);
+	DUMPREG(VENC_SYNC_CTRL);
+	DUMPREG(VENC_LLEN);
+	DUMPREG(VENC_FLENS);
+	DUMPREG(VENC_HFLTR_CTRL);
+	DUMPREG(VENC_CC_CARR_WSS_CARR);
+	DUMPREG(VENC_C_PHASE);
+	DUMPREG(VENC_GAIN_U);
+	DUMPREG(VENC_GAIN_V);
+	DUMPREG(VENC_GAIN_Y);
+	DUMPREG(VENC_BLACK_LEVEL);
+	DUMPREG(VENC_BLANK_LEVEL);
+	DUMPREG(VENC_X_COLOR);
+	DUMPREG(VENC_M_CONTROL);
+	DUMPREG(VENC_BSTAMP_WSS_DATA);
+	DUMPREG(VENC_S_CARR);
+	DUMPREG(VENC_LINE21);
+	DUMPREG(VENC_LN_SEL);
+	DUMPREG(VENC_L21__WC_CTL);
+	DUMPREG(VENC_HTRIGGER_VTRIGGER);
+	DUMPREG(VENC_SAVID__EAVID);
+	DUMPREG(VENC_FLEN__FAL);
+	DUMPREG(VENC_LAL__PHASE_RESET);
+	DUMPREG(VENC_HS_INT_START_STOP_X);
+	DUMPREG(VENC_HS_EXT_START_STOP_X);
+	DUMPREG(VENC_VS_INT_START_X);
+	DUMPREG(VENC_VS_INT_STOP_X__VS_INT_START_Y);
+	DUMPREG(VENC_VS_INT_STOP_Y__VS_EXT_START_X);
+	DUMPREG(VENC_VS_EXT_STOP_X__VS_EXT_START_Y);
+	DUMPREG(VENC_VS_EXT_STOP_Y);
+	DUMPREG(VENC_AVID_START_STOP_X);
+	DUMPREG(VENC_AVID_START_STOP_Y);
+	DUMPREG(VENC_FID_INT_START_X__FID_INT_START_Y);
+	DUMPREG(VENC_FID_INT_OFFSET_Y__FID_EXT_START_X);
+	DUMPREG(VENC_FID_EXT_START_Y__FID_EXT_OFFSET_Y);
+	DUMPREG(VENC_TVDETGP_INT_START_STOP_X);
+	DUMPREG(VENC_TVDETGP_INT_START_STOP_Y);
+	DUMPREG(VENC_GEN_CTRL);
+	DUMPREG(VENC_OUTPUT_CONTROL);
+	DUMPREG(VENC_OUTPUT_TEST);
+
+	venc_enable_clocks(0);
+
+#undef DUMPREG
+}
diff --git a/drivers/video/omap2/omapfb/Kconfig b/drivers/video/omap2/omapfb/Kconfig
new file mode 100644
index 0000000..bb694cc
--- /dev/null
+++ b/drivers/video/omap2/omapfb/Kconfig
@@ -0,0 +1,37 @@
+menuconfig FB_OMAP2
+        tristate "OMAP2/3 frame buffer support (EXPERIMENTAL)"
+        depends on FB && OMAP2_DSS
+
+	select OMAP2_VRAM
+	select OMAP2_VRFB
+        select FB_CFB_FILLRECT
+        select FB_CFB_COPYAREA
+        select FB_CFB_IMAGEBLIT
+        help
+          Frame buffer driver for OMAP2/3 based boards.
+
+config FB_OMAP2_DEBUG_SUPPORT
+	bool "Debug support for OMAP2/3 FB"
+	default y
+	depends on FB_OMAP2
+	help
+	  Support for debug output. You have to enable the actual printing
+	  with debug module parameter.
+
+config FB_OMAP2_FORCE_AUTO_UPDATE
+	bool "Force main display to automatic update mode"
+	depends on FB_OMAP2
+	help
+	  Forces main display to automatic update mode (if possible),
+	  and also enables tearsync (if possible). By default
+	  displays that support manual update are started in manual
+	  update mode.
+
+config FB_OMAP2_NUM_FBS
+	int "Number of framebuffers"
+	range 1 10
+	default 3
+	depends on FB_OMAP2
+	help
+	  Select the number of framebuffers created. OMAP2/3 has 3 overlays
+	  so normally this would be 3.
diff --git a/drivers/video/omap2/omapfb/Makefile b/drivers/video/omap2/omapfb/Makefile
new file mode 100644
index 0000000..51c2e00
--- /dev/null
+++ b/drivers/video/omap2/omapfb/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_FB_OMAP2) += omapfb.o
+omapfb-y := omapfb-main.o omapfb-sysfs.o omapfb-ioctl.o
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
new file mode 100644
index 0000000..4c4bafd
--- /dev/null
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -0,0 +1,755 @@
+/*
+ * linux/drivers/video/omap2/omapfb-ioctl.c
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * Some code and ideas taken from drivers/video/omap/ driver
+ * by Imre Deak.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/fb.h>
+#include <linux/device.h>
+#include <linux/uaccess.h>
+#include <linux/platform_device.h>
+#include <linux/mm.h>
+#include <linux/omapfb.h>
+#include <linux/vmalloc.h>
+
+#include <plat/display.h>
+#include <plat/vrfb.h>
+#include <plat/vram.h>
+
+#include "omapfb.h"
+
+static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
+{
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omapfb2_device *fbdev = ofbi->fbdev;
+	struct omap_overlay *ovl;
+	struct omap_overlay_info info;
+	int r = 0;
+
+	DBG("omapfb_setup_plane\n");
+
+	if (ofbi->num_overlays != 1) {
+		r = -EINVAL;
+		goto out;
+	}
+
+	/* XXX uses only the first overlay */
+	ovl = ofbi->overlays[0];
+
+	if (pi->enabled && !ofbi->region.size) {
+		/*
+		 * This plane's memory was freed, can't enable it
+		 * until it's reallocated.
+		 */
+		r = -EINVAL;
+		goto out;
+	}
+
+	ovl->get_overlay_info(ovl, &info);
+
+	info.pos_x = pi->pos_x;
+	info.pos_y = pi->pos_y;
+	info.out_width = pi->out_width;
+	info.out_height = pi->out_height;
+	info.enabled = pi->enabled;
+
+	r = ovl->set_overlay_info(ovl, &info);
+	if (r)
+		goto out;
+
+	if (ovl->manager) {
+		r = ovl->manager->apply(ovl->manager);
+		if (r)
+			goto out;
+	}
+
+out:
+	if (r)
+		dev_err(fbdev->dev, "setup_plane failed\n");
+	return r;
+}
+
+static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
+{
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+
+	if (ofbi->num_overlays != 1) {
+		memset(pi, 0, sizeof(*pi));
+	} else {
+		struct omap_overlay_info *ovli;
+		struct omap_overlay *ovl;
+
+		ovl = ofbi->overlays[0];
+		ovli = &ovl->info;
+
+		pi->pos_x = ovli->pos_x;
+		pi->pos_y = ovli->pos_y;
+		pi->enabled = ovli->enabled;
+		pi->channel_out = 0; /* xxx */
+		pi->mirror = 0;
+		pi->out_width = ovli->out_width;
+		pi->out_height = ovli->out_height;
+	}
+
+	return 0;
+}
+
+static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
+{
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omapfb2_device *fbdev = ofbi->fbdev;
+	struct omapfb2_mem_region *rg;
+	int r, i;
+	size_t size;
+
+	if (mi->type > OMAPFB_MEMTYPE_MAX)
+		return -EINVAL;
+
+	size = PAGE_ALIGN(mi->size);
+
+	rg = &ofbi->region;
+
+	for (i = 0; i < ofbi->num_overlays; i++) {
+		if (ofbi->overlays[i]->info.enabled)
+			return -EBUSY;
+	}
+
+	if (rg->size != size || rg->type != mi->type) {
+		r = omapfb_realloc_fbmem(fbi, size, mi->type);
+		if (r) {
+			dev_err(fbdev->dev, "realloc fbmem failed\n");
+			return r;
+		}
+	}
+
+	return 0;
+}
+
+static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
+{
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omapfb2_mem_region *rg;
+
+	rg = &ofbi->region;
+	memset(mi, 0, sizeof(*mi));
+
+	mi->size = rg->size;
+	mi->type = rg->type;
+
+	return 0;
+}
+
+static int omapfb_update_window_nolock(struct fb_info *fbi,
+		u32 x, u32 y, u32 w, u32 h)
+{
+	struct omap_dss_device *display = fb2display(fbi);
+	u16 dw, dh;
+
+	if (!display)
+		return 0;
+
+	if (w == 0 || h == 0)
+		return 0;
+
+	display->get_resolution(display, &dw, &dh);
+
+	if (x + w > dw || y + h > dh)
+		return -EINVAL;
+
+	return display->update(display, x, y, w, h);
+}
+
+/* This function is exported for SGX driver use */
+int omapfb_update_window(struct fb_info *fbi,
+		u32 x, u32 y, u32 w, u32 h)
+{
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omapfb2_device *fbdev = ofbi->fbdev;
+	int r;
+
+	omapfb_lock(fbdev);
+	lock_fb_info(fbi);
+
+	r = omapfb_update_window_nolock(fbi, x, y, w, h);
+
+	unlock_fb_info(fbi);
+	omapfb_unlock(fbdev);
+
+	return r;
+}
+EXPORT_SYMBOL(omapfb_update_window);
+
+static int omapfb_set_update_mode(struct fb_info *fbi,
+				   enum omapfb_update_mode mode)
+{
+	struct omap_dss_device *display = fb2display(fbi);
+	enum omap_dss_update_mode um;
+	int r;
+
+	if (!display || !display->set_update_mode)
+		return -EINVAL;
+
+	switch (mode) {
+	case OMAPFB_UPDATE_DISABLED:
+		um = OMAP_DSS_UPDATE_DISABLED;
+		break;
+
+	case OMAPFB_AUTO_UPDATE:
+		um = OMAP_DSS_UPDATE_AUTO;
+		break;
+
+	case OMAPFB_MANUAL_UPDATE:
+		um = OMAP_DSS_UPDATE_MANUAL;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	r = display->set_update_mode(display, um);
+
+	return r;
+}
+
+static int omapfb_get_update_mode(struct fb_info *fbi,
+		enum omapfb_update_mode *mode)
+{
+	struct omap_dss_device *display = fb2display(fbi);
+	enum omap_dss_update_mode m;
+
+	if (!display || !display->get_update_mode)
+		return -EINVAL;
+
+	m = display->get_update_mode(display);
+
+	switch (m) {
+	case OMAP_DSS_UPDATE_DISABLED:
+		*mode = OMAPFB_UPDATE_DISABLED;
+		break;
+	case OMAP_DSS_UPDATE_AUTO:
+		*mode = OMAPFB_AUTO_UPDATE;
+		break;
+	case OMAP_DSS_UPDATE_MANUAL:
+		*mode = OMAPFB_MANUAL_UPDATE;
+		break;
+	default:
+		BUG();
+	}
+
+	return 0;
+}
+
+/* XXX this color key handling is a hack... */
+static struct omapfb_color_key omapfb_color_keys[2];
+
+static int _omapfb_set_color_key(struct omap_overlay_manager *mgr,
+		struct omapfb_color_key *ck)
+{
+	struct omap_overlay_manager_info info;
+	enum omap_dss_trans_key_type kt;
+	int r;
+
+	mgr->get_manager_info(mgr, &info);
+
+	if (ck->key_type == OMAPFB_COLOR_KEY_DISABLED) {
+		info.trans_enabled = false;
+		omapfb_color_keys[mgr->id] = *ck;
+
+		r = mgr->set_manager_info(mgr, &info);
+		if (r)
+			return r;
+
+		r = mgr->apply(mgr);
+
+		return r;
+	}
+
+	switch (ck->key_type) {
+	case OMAPFB_COLOR_KEY_GFX_DST:
+		kt = OMAP_DSS_COLOR_KEY_GFX_DST;
+		break;
+	case OMAPFB_COLOR_KEY_VID_SRC:
+		kt = OMAP_DSS_COLOR_KEY_VID_SRC;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	info.default_color = ck->background;
+	info.trans_key = ck->trans_key;
+	info.trans_key_type = kt;
+	info.trans_enabled = true;
+
+	omapfb_color_keys[mgr->id] = *ck;
+
+	r = mgr->set_manager_info(mgr, &info);
+	if (r)
+		return r;
+
+	r = mgr->apply(mgr);
+
+	return r;
+}
+
+static int omapfb_set_color_key(struct fb_info *fbi,
+		struct omapfb_color_key *ck)
+{
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omapfb2_device *fbdev = ofbi->fbdev;
+	int r;
+	int i;
+	struct omap_overlay_manager *mgr = NULL;
+
+	omapfb_lock(fbdev);
+
+	for (i = 0; i < ofbi->num_overlays; i++) {
+		if (ofbi->overlays[i]->manager) {
+			mgr = ofbi->overlays[i]->manager;
+			break;
+		}
+	}
+
+	if (!mgr) {
+		r = -EINVAL;
+		goto err;
+	}
+
+	r = _omapfb_set_color_key(mgr, ck);
+err:
+	omapfb_unlock(fbdev);
+
+	return r;
+}
+
+static int omapfb_get_color_key(struct fb_info *fbi,
+		struct omapfb_color_key *ck)
+{
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omapfb2_device *fbdev = ofbi->fbdev;
+	struct omap_overlay_manager *mgr = NULL;
+	int r = 0;
+	int i;
+
+	omapfb_lock(fbdev);
+
+	for (i = 0; i < ofbi->num_overlays; i++) {
+		if (ofbi->overlays[i]->manager) {
+			mgr = ofbi->overlays[i]->manager;
+			break;
+		}
+	}
+
+	if (!mgr) {
+		r = -EINVAL;
+		goto err;
+	}
+
+	*ck = omapfb_color_keys[mgr->id];
+err:
+	omapfb_unlock(fbdev);
+
+	return r;
+}
+
+static int omapfb_memory_read(struct fb_info *fbi,
+		struct omapfb_memory_read *mr)
+{
+	struct omap_dss_device *display = fb2display(fbi);
+	void *buf;
+	int r;
+
+	if (!display || !display->memory_read)
+		return -ENOENT;
+
+	if (!access_ok(VERIFY_WRITE, mr->buffer, mr->buffer_size))
+		return -EFAULT;
+
+	if (mr->w * mr->h * 3 > mr->buffer_size)
+		return -EINVAL;
+
+	buf = vmalloc(mr->buffer_size);
+	if (!buf) {
+		DBG("vmalloc failed\n");
+		return -ENOMEM;
+	}
+
+	r = display->memory_read(display, buf, mr->buffer_size,
+			mr->x, mr->y, mr->w, mr->h);
+
+	if (r > 0) {
+		if (copy_to_user(mr->buffer, buf, mr->buffer_size))
+			r = -EFAULT;
+	}
+
+	vfree(buf);
+
+	return r;
+}
+
+static int omapfb_get_ovl_colormode(struct omapfb2_device *fbdev,
+			     struct omapfb_ovl_colormode *mode)
+{
+	int ovl_idx = mode->overlay_idx;
+	int mode_idx = mode->mode_idx;
+	struct omap_overlay *ovl;
+	enum omap_color_mode supported_modes;
+	struct fb_var_screeninfo var;
+	int i;
+
+	if (ovl_idx >= fbdev->num_overlays)
+		return -ENODEV;
+	ovl = fbdev->overlays[ovl_idx];
+	supported_modes = ovl->supported_modes;
+
+	mode_idx = mode->mode_idx;
+
+	for (i = 0; i < sizeof(supported_modes) * 8; i++) {
+		if (!(supported_modes & (1 << i)))
+			continue;
+		/*
+		 * It's possible that the FB doesn't support a mode
+		 * that is supported by the overlay, so call the
+		 * following here.
+		 */
+		if (dss_mode_to_fb_mode(1 << i, &var) < 0)
+			continue;
+
+		mode_idx--;
+		if (mode_idx < 0)
+			break;
+	}
+
+	if (i == sizeof(supported_modes) * 8)
+		return -ENOENT;
+
+	mode->bits_per_pixel = var.bits_per_pixel;
+	mode->nonstd = var.nonstd;
+	mode->red = var.red;
+	mode->green = var.green;
+	mode->blue = var.blue;
+	mode->transp = var.transp;
+
+	return 0;
+}
+
+static int omapfb_wait_for_go(struct fb_info *fbi)
+{
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	int r = 0;
+	int i;
+
+	for (i = 0; i < ofbi->num_overlays; ++i) {
+		struct omap_overlay *ovl = ofbi->overlays[i];
+		r = ovl->wait_for_go(ovl);
+		if (r)
+			break;
+	}
+
+	return r;
+}
+
+int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
+{
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omapfb2_device *fbdev = ofbi->fbdev;
+	struct omap_dss_device *display = fb2display(fbi);
+
+	union {
+		struct omapfb_update_window_old	uwnd_o;
+		struct omapfb_update_window	uwnd;
+		struct omapfb_plane_info	plane_info;
+		struct omapfb_caps		caps;
+		struct omapfb_mem_info          mem_info;
+		struct omapfb_color_key		color_key;
+		struct omapfb_ovl_colormode	ovl_colormode;
+		enum omapfb_update_mode		update_mode;
+		int test_num;
+		struct omapfb_memory_read	memory_read;
+		struct omapfb_vram_info		vram_info;
+		struct omapfb_tearsync_info	tearsync_info;
+	} p;
+
+	int r = 0;
+
+	switch (cmd) {
+	case OMAPFB_SYNC_GFX:
+		DBG("ioctl SYNC_GFX\n");
+		if (!display || !display->sync) {
+			/* DSS1 never returns an error here, so we neither */
+			/*r = -EINVAL;*/
+			break;
+		}
+
+		r = display->sync(display);
+		break;
+
+	case OMAPFB_UPDATE_WINDOW_OLD:
+		DBG("ioctl UPDATE_WINDOW_OLD\n");
+		if (!display || !display->update) {
+			r = -EINVAL;
+			break;
+		}
+
+		if (copy_from_user(&p.uwnd_o,
+					(void __user *)arg,
+					sizeof(p.uwnd_o))) {
+			r = -EFAULT;
+			break;
+		}
+
+		r = omapfb_update_window_nolock(fbi, p.uwnd_o.x, p.uwnd_o.y,
+				p.uwnd_o.width, p.uwnd_o.height);
+		break;
+
+	case OMAPFB_UPDATE_WINDOW:
+		DBG("ioctl UPDATE_WINDOW\n");
+		if (!display || !display->update) {
+			r = -EINVAL;
+			break;
+		}
+
+		if (copy_from_user(&p.uwnd, (void __user *)arg,
+					sizeof(p.uwnd))) {
+			r = -EFAULT;
+			break;
+		}
+
+		r = omapfb_update_window_nolock(fbi, p.uwnd.x, p.uwnd.y,
+				p.uwnd.width, p.uwnd.height);
+		break;
+
+	case OMAPFB_SETUP_PLANE:
+		DBG("ioctl SETUP_PLANE\n");
+		if (copy_from_user(&p.plane_info, (void __user *)arg,
+					sizeof(p.plane_info)))
+			r = -EFAULT;
+		else
+			r = omapfb_setup_plane(fbi, &p.plane_info);
+		break;
+
+	case OMAPFB_QUERY_PLANE:
+		DBG("ioctl QUERY_PLANE\n");
+		r = omapfb_query_plane(fbi, &p.plane_info);
+		if (r < 0)
+			break;
+		if (copy_to_user((void __user *)arg, &p.plane_info,
+					sizeof(p.plane_info)))
+			r = -EFAULT;
+		break;
+
+	case OMAPFB_SETUP_MEM:
+		DBG("ioctl SETUP_MEM\n");
+		if (copy_from_user(&p.mem_info, (void __user *)arg,
+					sizeof(p.mem_info)))
+			r = -EFAULT;
+		else
+			r = omapfb_setup_mem(fbi, &p.mem_info);
+		break;
+
+	case OMAPFB_QUERY_MEM:
+		DBG("ioctl QUERY_MEM\n");
+		r = omapfb_query_mem(fbi, &p.mem_info);
+		if (r < 0)
+			break;
+		if (copy_to_user((void __user *)arg, &p.mem_info,
+					sizeof(p.mem_info)))
+			r = -EFAULT;
+		break;
+
+	case OMAPFB_GET_CAPS:
+		DBG("ioctl GET_CAPS\n");
+		if (!display) {
+			r = -EINVAL;
+			break;
+		}
+
+		memset(&p.caps, 0, sizeof(p.caps));
+		if (display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE)
+			p.caps.ctrl |= OMAPFB_CAPS_MANUAL_UPDATE;
+		if (display->caps & OMAP_DSS_DISPLAY_CAP_TEAR_ELIM)
+			p.caps.ctrl |= OMAPFB_CAPS_TEARSYNC;
+
+		if (copy_to_user((void __user *)arg, &p.caps, sizeof(p.caps)))
+			r = -EFAULT;
+		break;
+
+	case OMAPFB_GET_OVERLAY_COLORMODE:
+		DBG("ioctl GET_OVERLAY_COLORMODE\n");
+		if (copy_from_user(&p.ovl_colormode, (void __user *)arg,
+				   sizeof(p.ovl_colormode))) {
+			r = -EFAULT;
+			break;
+		}
+		r = omapfb_get_ovl_colormode(fbdev, &p.ovl_colormode);
+		if (r < 0)
+			break;
+		if (copy_to_user((void __user *)arg, &p.ovl_colormode,
+				 sizeof(p.ovl_colormode)))
+			r = -EFAULT;
+		break;
+
+	case OMAPFB_SET_UPDATE_MODE:
+		DBG("ioctl SET_UPDATE_MODE\n");
+		if (get_user(p.update_mode, (int __user *)arg))
+			r = -EFAULT;
+		else
+			r = omapfb_set_update_mode(fbi, p.update_mode);
+		break;
+
+	case OMAPFB_GET_UPDATE_MODE:
+		DBG("ioctl GET_UPDATE_MODE\n");
+		r = omapfb_get_update_mode(fbi, &p.update_mode);
+		if (r)
+			break;
+		if (put_user(p.update_mode,
+					(enum omapfb_update_mode __user *)arg))
+			r = -EFAULT;
+		break;
+
+	case OMAPFB_SET_COLOR_KEY:
+		DBG("ioctl SET_COLOR_KEY\n");
+		if (copy_from_user(&p.color_key, (void __user *)arg,
+				   sizeof(p.color_key)))
+			r = -EFAULT;
+		else
+			r = omapfb_set_color_key(fbi, &p.color_key);
+		break;
+
+	case OMAPFB_GET_COLOR_KEY:
+		DBG("ioctl GET_COLOR_KEY\n");
+		r = omapfb_get_color_key(fbi, &p.color_key);
+		if (r)
+			break;
+		if (copy_to_user((void __user *)arg, &p.color_key,
+				 sizeof(p.color_key)))
+			r = -EFAULT;
+		break;
+
+	case OMAPFB_WAITFORVSYNC:
+		DBG("ioctl WAITFORVSYNC\n");
+		if (!display) {
+			r = -EINVAL;
+			break;
+		}
+
+		r = display->wait_vsync(display);
+		break;
+
+	case OMAPFB_WAITFORGO:
+		DBG("ioctl WAITFORGO\n");
+		if (!display) {
+			r = -EINVAL;
+			break;
+		}
+
+		r = omapfb_wait_for_go(fbi);
+		break;
+
+	/* LCD and CTRL tests do the same thing for backward
+	 * compatibility */
+	case OMAPFB_LCD_TEST:
+		DBG("ioctl LCD_TEST\n");
+		if (get_user(p.test_num, (int __user *)arg)) {
+			r = -EFAULT;
+			break;
+		}
+		if (!display || !display->run_test) {
+			r = -EINVAL;
+			break;
+		}
+
+		r = display->run_test(display, p.test_num);
+
+		break;
+
+	case OMAPFB_CTRL_TEST:
+		DBG("ioctl CTRL_TEST\n");
+		if (get_user(p.test_num, (int __user *)arg)) {
+			r = -EFAULT;
+			break;
+		}
+		if (!display || !display->run_test) {
+			r = -EINVAL;
+			break;
+		}
+
+		r = display->run_test(display, p.test_num);
+
+		break;
+
+	case OMAPFB_MEMORY_READ:
+		DBG("ioctl MEMORY_READ\n");
+
+		if (copy_from_user(&p.memory_read, (void __user *)arg,
+					sizeof(p.memory_read))) {
+			r = -EFAULT;
+			break;
+		}
+
+		r = omapfb_memory_read(fbi, &p.memory_read);
+
+		break;
+
+	case OMAPFB_GET_VRAM_INFO: {
+		unsigned long vram, free, largest;
+
+		DBG("ioctl GET_VRAM_INFO\n");
+
+		omap_vram_get_info(&vram, &free, &largest);
+		p.vram_info.total = vram;
+		p.vram_info.free = free;
+		p.vram_info.largest_free_block = largest;
+
+		if (copy_to_user((void __user *)arg, &p.vram_info,
+					sizeof(p.vram_info)))
+			r = -EFAULT;
+		break;
+	}
+
+	case OMAPFB_SET_TEARSYNC: {
+		DBG("ioctl SET_TEARSYNC\n");
+
+		if (copy_from_user(&p.tearsync_info, (void __user *)arg,
+					sizeof(p.tearsync_info))) {
+			r = -EFAULT;
+			break;
+		}
+
+		if (!display->enable_te) {
+			r = -ENODEV;
+			break;
+		}
+
+		r = display->enable_te(display, !!p.tearsync_info.enabled);
+
+		break;
+	}
+
+	default:
+		dev_err(fbdev->dev, "Unknown ioctl 0x%x\n", cmd);
+		r = -EINVAL;
+	}
+
+	if (r < 0)
+		DBG("ioctl failed: %d\n", r);
+
+	return r;
+}
+
+
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
new file mode 100644
index 0000000..ef29983
--- /dev/null
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -0,0 +1,2261 @@
+/*
+ * linux/drivers/video/omap2/omapfb-main.c
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * Some code and ideas taken from drivers/video/omap/ driver
+ * by Imre Deak.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/dma-mapping.h>
+#include <linux/vmalloc.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/omapfb.h>
+
+#include <plat/display.h>
+#include <plat/vram.h>
+#include <plat/vrfb.h>
+
+#include "omapfb.h"
+
+#define MODULE_NAME     "omapfb"
+
+#define OMAPFB_PLANE_XRES_MIN		8
+#define OMAPFB_PLANE_YRES_MIN		8
+
+static char *def_mode;
+static char *def_vram;
+static int def_vrfb;
+static int def_rotate;
+static int def_mirror;
+
+#ifdef DEBUG
+unsigned int omapfb_debug;
+module_param_named(debug, omapfb_debug, bool, 0644);
+static unsigned int omapfb_test_pattern;
+module_param_named(test, omapfb_test_pattern, bool, 0644);
+#endif
+
+static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi);
+
+#ifdef DEBUG
+static void draw_pixel(struct fb_info *fbi, int x, int y, unsigned color)
+{
+	struct fb_var_screeninfo *var = &fbi->var;
+	struct fb_fix_screeninfo *fix = &fbi->fix;
+	void __iomem *addr = fbi->screen_base;
+	const unsigned bytespp = var->bits_per_pixel >> 3;
+	const unsigned line_len = fix->line_length / bytespp;
+
+	int r = (color >> 16) & 0xff;
+	int g = (color >> 8) & 0xff;
+	int b = (color >> 0) & 0xff;
+
+	if (var->bits_per_pixel == 16) {
+		u16 __iomem *p = (u16 __iomem *)addr;
+		p += y * line_len + x;
+
+		r = r * 32 / 256;
+		g = g * 64 / 256;
+		b = b * 32 / 256;
+
+		__raw_writew((r << 11) | (g << 5) | (b << 0), p);
+	} else if (var->bits_per_pixel == 24) {
+		u8 __iomem *p = (u8 __iomem *)addr;
+		p += (y * line_len + x) * 3;
+
+		__raw_writeb(b, p + 0);
+		__raw_writeb(g, p + 1);
+		__raw_writeb(r, p + 2);
+	} else if (var->bits_per_pixel == 32) {
+		u32 __iomem *p = (u32 __iomem *)addr;
+		p += y * line_len + x;
+		__raw_writel(color, p);
+	}
+}
+
+static void fill_fb(struct fb_info *fbi)
+{
+	struct fb_var_screeninfo *var = &fbi->var;
+	const short w = var->xres_virtual;
+	const short h = var->yres_virtual;
+	void __iomem *addr = fbi->screen_base;
+	int y, x;
+
+	if (!addr)
+		return;
+
+	DBG("fill_fb %dx%d, line_len %d bytes\n", w, h, fbi->fix.line_length);
+
+	for (y = 0; y < h; y++) {
+		for (x = 0; x < w; x++) {
+			if (x < 20 && y < 20)
+				draw_pixel(fbi, x, y, 0xffffff);
+			else if (x < 20 && (y > 20 && y < h - 20))
+				draw_pixel(fbi, x, y, 0xff);
+			else if (y < 20 && (x > 20 && x < w - 20))
+				draw_pixel(fbi, x, y, 0xff00);
+			else if (x > w - 20 && (y > 20 && y < h - 20))
+				draw_pixel(fbi, x, y, 0xff0000);
+			else if (y > h - 20 && (x > 20 && x < w - 20))
+				draw_pixel(fbi, x, y, 0xffff00);
+			else if (x == 20 || x == w - 20 ||
+					y == 20 || y == h - 20)
+				draw_pixel(fbi, x, y, 0xffffff);
+			else if (x == y || w - x == h - y)
+				draw_pixel(fbi, x, y, 0xff00ff);
+			else if (w - x == y || x == h - y)
+				draw_pixel(fbi, x, y, 0x00ffff);
+			else if (x > 20 && y > 20 && x < w - 20 && y < h - 20) {
+				int t = x * 3 / w;
+				unsigned r = 0, g = 0, b = 0;
+				unsigned c;
+				if (var->bits_per_pixel == 16) {
+					if (t == 0)
+						b = (y % 32) * 256 / 32;
+					else if (t == 1)
+						g = (y % 64) * 256 / 64;
+					else if (t == 2)
+						r = (y % 32) * 256 / 32;
+				} else {
+					if (t == 0)
+						b = (y % 256);
+					else if (t == 1)
+						g = (y % 256);
+					else if (t == 2)
+						r = (y % 256);
+				}
+				c = (r << 16) | (g << 8) | (b << 0);
+				draw_pixel(fbi, x, y, c);
+			} else {
+				draw_pixel(fbi, x, y, 0);
+			}
+		}
+	}
+}
+#endif
+
+static unsigned omapfb_get_vrfb_offset(struct omapfb_info *ofbi, int rot)
+{
+	struct vrfb *vrfb = &ofbi->region.vrfb;
+	unsigned offset;
+
+	switch (rot) {
+	case FB_ROTATE_UR:
+		offset = 0;
+		break;
+	case FB_ROTATE_CW:
+		offset = vrfb->yoffset;
+		break;
+	case FB_ROTATE_UD:
+		offset = vrfb->yoffset * OMAP_VRFB_LINE_LEN + vrfb->xoffset;
+		break;
+	case FB_ROTATE_CCW:
+		offset = vrfb->xoffset * OMAP_VRFB_LINE_LEN;
+		break;
+	default:
+		BUG();
+	}
+
+	offset *= vrfb->bytespp;
+
+	return offset;
+}
+
+static u32 omapfb_get_region_rot_paddr(struct omapfb_info *ofbi, int rot)
+{
+	if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
+		return ofbi->region.vrfb.paddr[rot]
+			+ omapfb_get_vrfb_offset(ofbi, rot);
+	} else {
+		return ofbi->region.paddr;
+	}
+}
+
+static u32 omapfb_get_region_paddr(struct omapfb_info *ofbi)
+{
+	if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
+		return ofbi->region.vrfb.paddr[0];
+	else
+		return ofbi->region.paddr;
+}
+
+static void __iomem *omapfb_get_region_vaddr(struct omapfb_info *ofbi)
+{
+	if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
+		return ofbi->region.vrfb.vaddr[0];
+	else
+		return ofbi->region.vaddr;
+}
+
+static struct omapfb_colormode omapfb_colormodes[] = {
+	{
+		.dssmode = OMAP_DSS_COLOR_UYVY,
+		.bits_per_pixel = 16,
+		.nonstd = OMAPFB_COLOR_YUV422,
+	}, {
+		.dssmode = OMAP_DSS_COLOR_YUV2,
+		.bits_per_pixel = 16,
+		.nonstd = OMAPFB_COLOR_YUY422,
+	}, {
+		.dssmode = OMAP_DSS_COLOR_ARGB16,
+		.bits_per_pixel = 16,
+		.red	= { .length = 4, .offset = 8, .msb_right = 0 },
+		.green	= { .length = 4, .offset = 4, .msb_right = 0 },
+		.blue	= { .length = 4, .offset = 0, .msb_right = 0 },
+		.transp	= { .length = 4, .offset = 12, .msb_right = 0 },
+	}, {
+		.dssmode = OMAP_DSS_COLOR_RGB16,
+		.bits_per_pixel = 16,
+		.red	= { .length = 5, .offset = 11, .msb_right = 0 },
+		.green	= { .length = 6, .offset = 5, .msb_right = 0 },
+		.blue	= { .length = 5, .offset = 0, .msb_right = 0 },
+		.transp	= { .length = 0, .offset = 0, .msb_right = 0 },
+	}, {
+		.dssmode = OMAP_DSS_COLOR_RGB24P,
+		.bits_per_pixel = 24,
+		.red	= { .length = 8, .offset = 16, .msb_right = 0 },
+		.green	= { .length = 8, .offset = 8, .msb_right = 0 },
+		.blue	= { .length = 8, .offset = 0, .msb_right = 0 },
+		.transp	= { .length = 0, .offset = 0, .msb_right = 0 },
+	}, {
+		.dssmode = OMAP_DSS_COLOR_RGB24U,
+		.bits_per_pixel = 32,
+		.red	= { .length = 8, .offset = 16, .msb_right = 0 },
+		.green	= { .length = 8, .offset = 8, .msb_right = 0 },
+		.blue	= { .length = 8, .offset = 0, .msb_right = 0 },
+		.transp	= { .length = 0, .offset = 0, .msb_right = 0 },
+	}, {
+		.dssmode = OMAP_DSS_COLOR_ARGB32,
+		.bits_per_pixel = 32,
+		.red	= { .length = 8, .offset = 16, .msb_right = 0 },
+		.green	= { .length = 8, .offset = 8, .msb_right = 0 },
+		.blue	= { .length = 8, .offset = 0, .msb_right = 0 },
+		.transp	= { .length = 8, .offset = 24, .msb_right = 0 },
+	}, {
+		.dssmode = OMAP_DSS_COLOR_RGBA32,
+		.bits_per_pixel = 32,
+		.red	= { .length = 8, .offset = 24, .msb_right = 0 },
+		.green	= { .length = 8, .offset = 16, .msb_right = 0 },
+		.blue	= { .length = 8, .offset = 8, .msb_right = 0 },
+		.transp	= { .length = 8, .offset = 0, .msb_right = 0 },
+	}, {
+		.dssmode = OMAP_DSS_COLOR_RGBX32,
+		.bits_per_pixel = 32,
+		.red	= { .length = 8, .offset = 24, .msb_right = 0 },
+		.green	= { .length = 8, .offset = 16, .msb_right = 0 },
+		.blue	= { .length = 8, .offset = 8, .msb_right = 0 },
+		.transp	= { .length = 0, .offset = 0, .msb_right = 0 },
+	},
+};
+
+static bool cmp_var_to_colormode(struct fb_var_screeninfo *var,
+		struct omapfb_colormode *color)
+{
+	bool cmp_component(struct fb_bitfield *f1, struct fb_bitfield *f2)
+	{
+		return f1->length == f2->length &&
+			f1->offset == f2->offset &&
+			f1->msb_right == f2->msb_right;
+	}
+
+	if (var->bits_per_pixel == 0 ||
+			var->red.length == 0 ||
+			var->blue.length == 0 ||
+			var->green.length == 0)
+		return 0;
+
+	return var->bits_per_pixel == color->bits_per_pixel &&
+		cmp_component(&var->red, &color->red) &&
+		cmp_component(&var->green, &color->green) &&
+		cmp_component(&var->blue, &color->blue) &&
+		cmp_component(&var->transp, &color->transp);
+}
+
+static void assign_colormode_to_var(struct fb_var_screeninfo *var,
+		struct omapfb_colormode *color)
+{
+	var->bits_per_pixel = color->bits_per_pixel;
+	var->nonstd = color->nonstd;
+	var->red = color->red;
+	var->green = color->green;
+	var->blue = color->blue;
+	var->transp = color->transp;
+}
+
+static int fb_mode_to_dss_mode(struct fb_var_screeninfo *var,
+		enum omap_color_mode *mode)
+{
+	enum omap_color_mode dssmode;
+	int i;
+
+	/* first match with nonstd field */
+	if (var->nonstd) {
+		for (i = 0; i < ARRAY_SIZE(omapfb_colormodes); ++i) {
+			struct omapfb_colormode *m = &omapfb_colormodes[i];
+			if (var->nonstd == m->nonstd) {
+				assign_colormode_to_var(var, m);
+				*mode = m->dssmode;
+				return 0;
+			}
+		}
+
+		return -EINVAL;
+	}
+
+	/* then try exact match of bpp and colors */
+	for (i = 0; i < ARRAY_SIZE(omapfb_colormodes); ++i) {
+		struct omapfb_colormode *m = &omapfb_colormodes[i];
+		if (cmp_var_to_colormode(var, m)) {
+			assign_colormode_to_var(var, m);
+			*mode = m->dssmode;
+			return 0;
+		}
+	}
+
+	/* match with bpp if user has not filled color fields
+	 * properly */
+	switch (var->bits_per_pixel) {
+	case 1:
+		dssmode = OMAP_DSS_COLOR_CLUT1;
+		break;
+	case 2:
+		dssmode = OMAP_DSS_COLOR_CLUT2;
+		break;
+	case 4:
+		dssmode = OMAP_DSS_COLOR_CLUT4;
+		break;
+	case 8:
+		dssmode = OMAP_DSS_COLOR_CLUT8;
+		break;
+	case 12:
+		dssmode = OMAP_DSS_COLOR_RGB12U;
+		break;
+	case 16:
+		dssmode = OMAP_DSS_COLOR_RGB16;
+		break;
+	case 24:
+		dssmode = OMAP_DSS_COLOR_RGB24P;
+		break;
+	case 32:
+		dssmode = OMAP_DSS_COLOR_RGB24U;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(omapfb_colormodes); ++i) {
+		struct omapfb_colormode *m = &omapfb_colormodes[i];
+		if (dssmode == m->dssmode) {
+			assign_colormode_to_var(var, m);
+			*mode = m->dssmode;
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int check_fb_res_bounds(struct fb_var_screeninfo *var)
+{
+	int xres_min = OMAPFB_PLANE_XRES_MIN;
+	int xres_max = 2048;
+	int yres_min = OMAPFB_PLANE_YRES_MIN;
+	int yres_max = 2048;
+
+	/* XXX: some applications seem to set virtual res to 0. */
+	if (var->xres_virtual == 0)
+		var->xres_virtual = var->xres;
+
+	if (var->yres_virtual == 0)
+		var->yres_virtual = var->yres;
+
+	if (var->xres_virtual < xres_min || var->yres_virtual < yres_min)
+		return -EINVAL;
+
+	if (var->xres < xres_min)
+		var->xres = xres_min;
+	if (var->yres < yres_min)
+		var->yres = yres_min;
+	if (var->xres > xres_max)
+		var->xres = xres_max;
+	if (var->yres > yres_max)
+		var->yres = yres_max;
+
+	if (var->xres > var->xres_virtual)
+		var->xres = var->xres_virtual;
+	if (var->yres > var->yres_virtual)
+		var->yres = var->yres_virtual;
+
+	return 0;
+}
+
+static void shrink_height(unsigned long max_frame_size,
+		struct fb_var_screeninfo *var)
+{
+	DBG("can't fit FB into memory, reducing y\n");
+	var->yres_virtual = max_frame_size /
+		(var->xres_virtual * var->bits_per_pixel >> 3);
+
+	if (var->yres_virtual < OMAPFB_PLANE_YRES_MIN)
+		var->yres_virtual = OMAPFB_PLANE_YRES_MIN;
+
+	if (var->yres > var->yres_virtual)
+		var->yres = var->yres_virtual;
+}
+
+static void shrink_width(unsigned long max_frame_size,
+		struct fb_var_screeninfo *var)
+{
+	DBG("can't fit FB into memory, reducing x\n");
+	var->xres_virtual = max_frame_size / var->yres_virtual /
+		(var->bits_per_pixel >> 3);
+
+	if (var->xres_virtual < OMAPFB_PLANE_XRES_MIN)
+		var->xres_virtual = OMAPFB_PLANE_XRES_MIN;
+
+	if (var->xres > var->xres_virtual)
+		var->xres = var->xres_virtual;
+}
+
+static int check_vrfb_fb_size(unsigned long region_size,
+		const struct fb_var_screeninfo *var)
+{
+	unsigned long min_phys_size = omap_vrfb_min_phys_size(var->xres_virtual,
+		var->yres_virtual, var->bits_per_pixel >> 3);
+
+	return min_phys_size > region_size ? -EINVAL : 0;
+}
+
+static int check_fb_size(const struct omapfb_info *ofbi,
+		struct fb_var_screeninfo *var)
+{
+	unsigned long max_frame_size = ofbi->region.size;
+	int bytespp = var->bits_per_pixel >> 3;
+	unsigned long line_size = var->xres_virtual * bytespp;
+
+	if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
+		/* One needs to check for both VRFB and OMAPFB limitations. */
+		if (check_vrfb_fb_size(max_frame_size, var))
+			shrink_height(omap_vrfb_max_height(
+				max_frame_size, var->xres_virtual, bytespp) *
+				line_size, var);
+
+		if (check_vrfb_fb_size(max_frame_size, var)) {
+			DBG("cannot fit FB to memory\n");
+			return -EINVAL;
+		}
+
+		return 0;
+	}
+
+	DBG("max frame size %lu, line size %lu\n", max_frame_size, line_size);
+
+	if (line_size * var->yres_virtual > max_frame_size)
+		shrink_height(max_frame_size, var);
+
+	if (line_size * var->yres_virtual > max_frame_size) {
+		shrink_width(max_frame_size, var);
+		line_size = var->xres_virtual * bytespp;
+	}
+
+	if (line_size * var->yres_virtual > max_frame_size) {
+		DBG("cannot fit FB to memory\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*
+ * Consider if VRFB assisted rotation is in use and if the virtual space for
+ * the zero degree view needs to be mapped. The need for mapping also acts as
+ * the trigger for setting up the hardware on the context in question. This
+ * ensures that one does not attempt to access the virtual view before the
+ * hardware is serving the address translations.
+ */
+static int setup_vrfb_rotation(struct fb_info *fbi)
+{
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omapfb2_mem_region *rg = &ofbi->region;
+	struct vrfb *vrfb = &rg->vrfb;
+	struct fb_var_screeninfo *var = &fbi->var;
+	struct fb_fix_screeninfo *fix = &fbi->fix;
+	unsigned bytespp;
+	bool yuv_mode;
+	enum omap_color_mode mode;
+	int r;
+	bool reconf;
+
+	if (!rg->size || ofbi->rotation_type != OMAP_DSS_ROT_VRFB)
+		return 0;
+
+	DBG("setup_vrfb_rotation\n");
+
+	r = fb_mode_to_dss_mode(var, &mode);
+	if (r)
+		return r;
+
+	bytespp = var->bits_per_pixel >> 3;
+
+	yuv_mode = mode == OMAP_DSS_COLOR_YUV2 || mode == OMAP_DSS_COLOR_UYVY;
+
+	/* We need to reconfigure VRFB if the resolution changes, if yuv mode
+	 * is enabled/disabled, or if bytes per pixel changes */
+
+	/* XXX we shouldn't allow this when framebuffer is mmapped */
+
+	reconf = false;
+
+	if (yuv_mode != vrfb->yuv_mode)
+		reconf = true;
+	else if (bytespp != vrfb->bytespp)
+		reconf = true;
+	else if (vrfb->xres != var->xres_virtual ||
+			vrfb->yres != var->yres_virtual)
+		reconf = true;
+
+	if (vrfb->vaddr[0] && reconf) {
+		fbi->screen_base = NULL;
+		fix->smem_start = 0;
+		fix->smem_len = 0;
+		iounmap(vrfb->vaddr[0]);
+		vrfb->vaddr[0] = NULL;
+		DBG("setup_vrfb_rotation: reset fb\n");
+	}
+
+	if (vrfb->vaddr[0])
+		return 0;
+
+	omap_vrfb_setup(&rg->vrfb, rg->paddr,
+			var->xres_virtual,
+			var->yres_virtual,
+			bytespp, yuv_mode);
+
+	/* Now one can ioremap the 0 angle view */
+	r = omap_vrfb_map_angle(vrfb, var->yres_virtual, 0);
+	if (r)
+		return r;
+
+	/* used by open/write in fbmem.c */
+	fbi->screen_base = ofbi->region.vrfb.vaddr[0];
+
+	fix->smem_start = ofbi->region.vrfb.paddr[0];
+
+	switch (var->nonstd) {
+	case OMAPFB_COLOR_YUV422:
+	case OMAPFB_COLOR_YUY422:
+		fix->line_length =
+			(OMAP_VRFB_LINE_LEN * var->bits_per_pixel) >> 2;
+		break;
+	default:
+		fix->line_length =
+			(OMAP_VRFB_LINE_LEN * var->bits_per_pixel) >> 3;
+		break;
+	}
+
+	fix->smem_len = var->yres_virtual * fix->line_length;
+
+	return 0;
+}
+
+int dss_mode_to_fb_mode(enum omap_color_mode dssmode,
+			struct fb_var_screeninfo *var)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(omapfb_colormodes); ++i) {
+		struct omapfb_colormode *mode = &omapfb_colormodes[i];
+		if (dssmode == mode->dssmode) {
+			assign_colormode_to_var(var, mode);
+			return 0;
+		}
+	}
+	return -ENOENT;
+}
+
+void set_fb_fix(struct fb_info *fbi)
+{
+	struct fb_fix_screeninfo *fix = &fbi->fix;
+	struct fb_var_screeninfo *var = &fbi->var;
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omapfb2_mem_region *rg = &ofbi->region;
+
+	DBG("set_fb_fix\n");
+
+	/* used by open/write in fbmem.c */
+	fbi->screen_base = (char __iomem *)omapfb_get_region_vaddr(ofbi);
+
+	/* used by mmap in fbmem.c */
+	if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
+		switch (var->nonstd) {
+		case OMAPFB_COLOR_YUV422:
+		case OMAPFB_COLOR_YUY422:
+			fix->line_length =
+				(OMAP_VRFB_LINE_LEN * var->bits_per_pixel) >> 2;
+			break;
+		default:
+			fix->line_length =
+				(OMAP_VRFB_LINE_LEN * var->bits_per_pixel) >> 3;
+			break;
+		}
+
+		fix->smem_len = var->yres_virtual * fix->line_length;
+	} else {
+		fix->line_length =
+			(var->xres_virtual * var->bits_per_pixel) >> 3;
+		fix->smem_len = rg->size;
+	}
+
+	fix->smem_start = omapfb_get_region_paddr(ofbi);
+
+	fix->type = FB_TYPE_PACKED_PIXELS;
+
+	if (var->nonstd)
+		fix->visual = FB_VISUAL_PSEUDOCOLOR;
+	else {
+		switch (var->bits_per_pixel) {
+		case 32:
+		case 24:
+		case 16:
+		case 12:
+			fix->visual = FB_VISUAL_TRUECOLOR;
+			/* 12bpp is stored in 16 bits */
+			break;
+		case 1:
+		case 2:
+		case 4:
+		case 8:
+			fix->visual = FB_VISUAL_PSEUDOCOLOR;
+			break;
+		}
+	}
+
+	fix->accel = FB_ACCEL_NONE;
+
+	fix->xpanstep = 1;
+	fix->ypanstep = 1;
+}
+
+/* check new var and possibly modify it to be ok */
+int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
+{
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omap_dss_device *display = fb2display(fbi);
+	enum omap_color_mode mode = 0;
+	int i;
+	int r;
+
+	DBG("check_fb_var %d\n", ofbi->id);
+
+	if (ofbi->region.size == 0)
+		return 0;
+
+	r = fb_mode_to_dss_mode(var, &mode);
+	if (r) {
+		DBG("cannot convert var to omap dss mode\n");
+		return r;
+	}
+
+	for (i = 0; i < ofbi->num_overlays; ++i) {
+		if ((ofbi->overlays[i]->supported_modes & mode) == 0) {
+			DBG("invalid mode\n");
+			return -EINVAL;
+		}
+	}
+
+	if (var->rotate < 0 || var->rotate > 3)
+		return -EINVAL;
+
+	if (check_fb_res_bounds(var))
+		return -EINVAL;
+
+	if (check_fb_size(ofbi, var))
+		return -EINVAL;
+
+	if (var->xres + var->xoffset > var->xres_virtual)
+		var->xoffset = var->xres_virtual - var->xres;
+	if (var->yres + var->yoffset > var->yres_virtual)
+		var->yoffset = var->yres_virtual - var->yres;
+
+	DBG("xres = %d, yres = %d, vxres = %d, vyres = %d\n",
+			var->xres, var->yres,
+			var->xres_virtual, var->yres_virtual);
+
+	var->height             = -1;
+	var->width              = -1;
+	var->grayscale          = 0;
+
+	if (display && display->get_timings) {
+		struct omap_video_timings timings;
+		display->get_timings(display, &timings);
+
+		/* pixclock in ps, the rest in pixclock */
+		var->pixclock = timings.pixel_clock != 0 ?
+			KHZ2PICOS(timings.pixel_clock) :
+			0;
+		var->left_margin = timings.hfp;
+		var->right_margin = timings.hbp;
+		var->upper_margin = timings.vfp;
+		var->lower_margin = timings.vbp;
+		var->hsync_len = timings.hsw;
+		var->vsync_len = timings.vsw;
+	} else {
+		var->pixclock = 0;
+		var->left_margin = 0;
+		var->right_margin = 0;
+		var->upper_margin = 0;
+		var->lower_margin = 0;
+		var->hsync_len = 0;
+		var->vsync_len = 0;
+	}
+
+	/* TODO: get these from panel->config */
+	var->vmode              = FB_VMODE_NONINTERLACED;
+	var->sync               = 0;
+
+	return 0;
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * fbdev framework callbacks
+ * ---------------------------------------------------------------------------
+ */
+static int omapfb_open(struct fb_info *fbi, int user)
+{
+	return 0;
+}
+
+static int omapfb_release(struct fb_info *fbi, int user)
+{
+#if 0
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omapfb2_device *fbdev = ofbi->fbdev;
+	struct omap_dss_device *display = fb2display(fbi);
+
+	DBG("Closing fb with plane index %d\n", ofbi->id);
+
+	omapfb_lock(fbdev);
+
+	if (display && display->get_update_mode && display->update) {
+		/* XXX this update should be removed, I think. But it's
+		 * good for debugging */
+		if (display->get_update_mode(display) ==
+				OMAP_DSS_UPDATE_MANUAL) {
+			u16 w, h;
+
+			if (display->sync)
+				display->sync(display);
+
+			display->get_resolution(display, &w, &h);
+			display->update(display, 0, 0, w, h);
+		}
+	}
+
+	if (display && display->sync)
+		display->sync(display);
+
+	omapfb_unlock(fbdev);
+#endif
+	return 0;
+}
+
+static unsigned calc_rotation_offset_dma(struct fb_var_screeninfo *var,
+		struct fb_fix_screeninfo *fix, int rotation)
+{
+	unsigned offset;
+
+	offset = var->yoffset * fix->line_length +
+		var->xoffset * (var->bits_per_pixel >> 3);
+
+	return offset;
+}
+
+static unsigned calc_rotation_offset_vrfb(struct fb_var_screeninfo *var,
+		struct fb_fix_screeninfo *fix, int rotation)
+{
+	unsigned offset;
+
+	if (rotation == FB_ROTATE_UD)
+		offset = (var->yres_virtual - var->yres) *
+			fix->line_length;
+	else if (rotation == FB_ROTATE_CW)
+		offset = (var->yres_virtual - var->yres) *
+			(var->bits_per_pixel >> 3);
+	else
+		offset = 0;
+
+	if (rotation == FB_ROTATE_UR)
+		offset += var->yoffset * fix->line_length +
+			var->xoffset * (var->bits_per_pixel >> 3);
+	else if (rotation == FB_ROTATE_UD)
+		offset -= var->yoffset * fix->line_length +
+			var->xoffset * (var->bits_per_pixel >> 3);
+	else if (rotation == FB_ROTATE_CW)
+		offset -= var->xoffset * fix->line_length +
+			var->yoffset * (var->bits_per_pixel >> 3);
+	else if (rotation == FB_ROTATE_CCW)
+		offset += var->xoffset * fix->line_length +
+			var->yoffset * (var->bits_per_pixel >> 3);
+
+	return offset;
+}
+
+
+/* setup overlay according to the fb */
+static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
+		u16 posx, u16 posy, u16 outw, u16 outh)
+{
+	int r = 0;
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct fb_var_screeninfo *var = &fbi->var;
+	struct fb_fix_screeninfo *fix = &fbi->fix;
+	enum omap_color_mode mode = 0;
+	int offset;
+	u32 data_start_p;
+	void __iomem *data_start_v;
+	struct omap_overlay_info info;
+	int xres, yres;
+	int screen_width;
+	int mirror;
+	int rotation = var->rotate;
+	int i;
+
+	for (i = 0; i < ofbi->num_overlays; i++) {
+		if (ovl != ofbi->overlays[i])
+			continue;
+
+		rotation = (rotation + ofbi->rotation[i]) % 4;
+		break;
+	}
+
+	DBG("setup_overlay %d, posx %d, posy %d, outw %d, outh %d\n", ofbi->id,
+			posx, posy, outw, outh);
+
+	if (rotation == FB_ROTATE_CW || rotation == FB_ROTATE_CCW) {
+		xres = var->yres;
+		yres = var->xres;
+	} else {
+		xres = var->xres;
+		yres = var->yres;
+	}
+
+
+	if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
+		data_start_p = omapfb_get_region_rot_paddr(ofbi, rotation);
+		data_start_v = NULL;
+	} else {
+		data_start_p = omapfb_get_region_paddr(ofbi);
+		data_start_v = omapfb_get_region_vaddr(ofbi);
+	}
+
+	if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
+		offset = calc_rotation_offset_vrfb(var, fix, rotation);
+	else
+		offset = calc_rotation_offset_dma(var, fix, rotation);
+
+	data_start_p += offset;
+	data_start_v += offset;
+
+	if (offset)
+		DBG("offset %d, %d = %d\n",
+				var->xoffset, var->yoffset, offset);
+
+	DBG("paddr %x, vaddr %p\n", data_start_p, data_start_v);
+
+	r = fb_mode_to_dss_mode(var, &mode);
+	if (r) {
+		DBG("fb_mode_to_dss_mode failed");
+		goto err;
+	}
+
+	switch (var->nonstd) {
+	case OMAPFB_COLOR_YUV422:
+	case OMAPFB_COLOR_YUY422:
+		if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
+			screen_width = fix->line_length
+				/ (var->bits_per_pixel >> 2);
+			break;
+		}
+	default:
+		screen_width = fix->line_length / (var->bits_per_pixel >> 3);
+		break;
+	}
+
+	ovl->get_overlay_info(ovl, &info);
+
+	if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
+		mirror = 0;
+	else
+		mirror = ofbi->mirror;
+
+	info.paddr = data_start_p;
+	info.vaddr = data_start_v;
+	info.screen_width = screen_width;
+	info.width = xres;
+	info.height = yres;
+	info.color_mode = mode;
+	info.rotation_type = ofbi->rotation_type;
+	info.rotation = rotation;
+	info.mirror = mirror;
+
+	info.pos_x = posx;
+	info.pos_y = posy;
+	info.out_width = outw;
+	info.out_height = outh;
+
+	r = ovl->set_overlay_info(ovl, &info);
+	if (r) {
+		DBG("ovl->setup_overlay_info failed\n");
+		goto err;
+	}
+
+	return 0;
+
+err:
+	DBG("setup_overlay failed\n");
+	return r;
+}
+
+/* apply var to the overlay */
+int omapfb_apply_changes(struct fb_info *fbi, int init)
+{
+	int r = 0;
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct fb_var_screeninfo *var = &fbi->var;
+	struct omap_overlay *ovl;
+	u16 posx, posy;
+	u16 outw, outh;
+	int i;
+
+#ifdef DEBUG
+	if (omapfb_test_pattern)
+		fill_fb(fbi);
+#endif
+
+	for (i = 0; i < ofbi->num_overlays; i++) {
+		ovl = ofbi->overlays[i];
+
+		DBG("apply_changes, fb %d, ovl %d\n", ofbi->id, ovl->id);
+
+		if (ofbi->region.size == 0) {
+			/* the fb is not available. disable the overlay */
+			omapfb_overlay_enable(ovl, 0);
+			if (!init && ovl->manager)
+				ovl->manager->apply(ovl->manager);
+			continue;
+		}
+
+		if (init || (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
+			int rotation = (var->rotate + ofbi->rotation[i]) % 4;
+			if (rotation == FB_ROTATE_CW ||
+					rotation == FB_ROTATE_CCW) {
+				outw = var->yres;
+				outh = var->xres;
+			} else {
+				outw = var->xres;
+				outh = var->yres;
+			}
+		} else {
+			outw = ovl->info.out_width;
+			outh = ovl->info.out_height;
+		}
+
+		if (init) {
+			posx = 0;
+			posy = 0;
+		} else {
+			posx = ovl->info.pos_x;
+			posy = ovl->info.pos_y;
+		}
+
+		r = omapfb_setup_overlay(fbi, ovl, posx, posy, outw, outh);
+		if (r)
+			goto err;
+
+		if (!init && ovl->manager)
+			ovl->manager->apply(ovl->manager);
+	}
+	return 0;
+err:
+	DBG("apply_changes failed\n");
+	return r;
+}
+
+/* checks var and eventually tweaks it to something supported,
+ * DO NOT MODIFY PAR */
+static int omapfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi)
+{
+	int r;
+
+	DBG("check_var(%d)\n", FB2OFB(fbi)->id);
+
+	r = check_fb_var(fbi, var);
+
+	return r;
+}
+
+/* set the video mode according to info->var */
+static int omapfb_set_par(struct fb_info *fbi)
+{
+	int r;
+
+	DBG("set_par(%d)\n", FB2OFB(fbi)->id);
+
+	set_fb_fix(fbi);
+
+	r = setup_vrfb_rotation(fbi);
+	if (r)
+		return r;
+
+	r = omapfb_apply_changes(fbi, 0);
+
+	return r;
+}
+
+static int omapfb_pan_display(struct fb_var_screeninfo *var,
+		struct fb_info *fbi)
+{
+	struct fb_var_screeninfo new_var;
+	int r;
+
+	DBG("pan_display(%d)\n", FB2OFB(fbi)->id);
+
+	if (var->xoffset == fbi->var.xoffset &&
+	    var->yoffset == fbi->var.yoffset)
+		return 0;
+
+	new_var = fbi->var;
+	new_var.xoffset = var->xoffset;
+	new_var.yoffset = var->yoffset;
+
+	fbi->var = new_var;
+
+	r = omapfb_apply_changes(fbi, 0);
+
+	return r;
+}
+
+static void mmap_user_open(struct vm_area_struct *vma)
+{
+	struct omapfb_info *ofbi = (struct omapfb_info *)vma->vm_private_data;
+
+	atomic_inc(&ofbi->map_count);
+}
+
+static void mmap_user_close(struct vm_area_struct *vma)
+{
+	struct omapfb_info *ofbi = (struct omapfb_info *)vma->vm_private_data;
+
+	atomic_dec(&ofbi->map_count);
+}
+
+static struct vm_operations_struct mmap_user_ops = {
+	.open = mmap_user_open,
+	.close = mmap_user_close,
+};
+
+static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
+{
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct fb_fix_screeninfo *fix = &fbi->fix;
+	unsigned long off;
+	unsigned long start;
+	u32 len;
+
+	if (vma->vm_end - vma->vm_start == 0)
+		return 0;
+	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
+		return -EINVAL;
+	off = vma->vm_pgoff << PAGE_SHIFT;
+
+	start = omapfb_get_region_paddr(ofbi);
+	len = fix->smem_len;
+	if (off >= len)
+		return -EINVAL;
+	if ((vma->vm_end - vma->vm_start + off) > len)
+		return -EINVAL;
+
+	off += start;
+
+	DBG("user mmap region start %lx, len %d, off %lx\n", start, len, off);
+
+	vma->vm_pgoff = off >> PAGE_SHIFT;
+	vma->vm_flags |= VM_IO | VM_RESERVED;
+	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+	vma->vm_ops = &mmap_user_ops;
+	vma->vm_private_data = ofbi;
+	if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
+			     vma->vm_end - vma->vm_start, vma->vm_page_prot))
+		return -EAGAIN;
+	/* vm_ops.open won't be called for mmap itself. */
+	atomic_inc(&ofbi->map_count);
+	return 0;
+}
+
+/* Store a single color palette entry into a pseudo palette or the hardware
+ * palette if one is available. For now we support only 16bpp and thus store
+ * the entry only to the pseudo palette.
+ */
+static int _setcolreg(struct fb_info *fbi, u_int regno, u_int red, u_int green,
+		u_int blue, u_int transp, int update_hw_pal)
+{
+	/*struct omapfb_info *ofbi = FB2OFB(fbi);*/
+	/*struct omapfb2_device *fbdev = ofbi->fbdev;*/
+	struct fb_var_screeninfo *var = &fbi->var;
+	int r = 0;
+
+	enum omapfb_color_format mode = OMAPFB_COLOR_RGB24U; /* XXX */
+
+	/*switch (plane->color_mode) {*/
+	switch (mode) {
+	case OMAPFB_COLOR_YUV422:
+	case OMAPFB_COLOR_YUV420:
+	case OMAPFB_COLOR_YUY422:
+		r = -EINVAL;
+		break;
+	case OMAPFB_COLOR_CLUT_8BPP:
+	case OMAPFB_COLOR_CLUT_4BPP:
+	case OMAPFB_COLOR_CLUT_2BPP:
+	case OMAPFB_COLOR_CLUT_1BPP:
+		/*
+		   if (fbdev->ctrl->setcolreg)
+		   r = fbdev->ctrl->setcolreg(regno, red, green, blue,
+		   transp, update_hw_pal);
+		   */
+		/* Fallthrough */
+		r = -EINVAL;
+		break;
+	case OMAPFB_COLOR_RGB565:
+	case OMAPFB_COLOR_RGB444:
+	case OMAPFB_COLOR_RGB24P:
+	case OMAPFB_COLOR_RGB24U:
+		if (r != 0)
+			break;
+
+		if (regno < 0) {
+			r = -EINVAL;
+			break;
+		}
+
+		if (regno < 16) {
+			u16 pal;
+			pal = ((red >> (16 - var->red.length)) <<
+					var->red.offset) |
+				((green >> (16 - var->green.length)) <<
+				 var->green.offset) |
+				(blue >> (16 - var->blue.length));
+			((u32 *)(fbi->pseudo_palette))[regno] = pal;
+		}
+		break;
+	default:
+		BUG();
+	}
+	return r;
+}
+
+static int omapfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+		u_int transp, struct fb_info *info)
+{
+	DBG("setcolreg\n");
+
+	return _setcolreg(info, regno, red, green, blue, transp, 1);
+}
+
+static int omapfb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
+{
+	int count, index, r;
+	u16 *red, *green, *blue, *transp;
+	u16 trans = 0xffff;
+
+	DBG("setcmap\n");
+
+	red     = cmap->red;
+	green   = cmap->green;
+	blue    = cmap->blue;
+	transp  = cmap->transp;
+	index   = cmap->start;
+
+	for (count = 0; count < cmap->len; count++) {
+		if (transp)
+			trans = *transp++;
+		r = _setcolreg(info, index++, *red++, *green++, *blue++, trans,
+				count == cmap->len - 1);
+		if (r != 0)
+			return r;
+	}
+
+	return 0;
+}
+
+static int omapfb_blank(int blank, struct fb_info *fbi)
+{
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omapfb2_device *fbdev = ofbi->fbdev;
+	struct omap_dss_device *display = fb2display(fbi);
+	int do_update = 0;
+	int r = 0;
+
+	omapfb_lock(fbdev);
+
+	switch (blank) {
+	case FB_BLANK_UNBLANK:
+		if (display->state != OMAP_DSS_DISPLAY_SUSPENDED)
+			goto exit;
+
+		if (display->resume)
+			r = display->resume(display);
+
+		if (r == 0 && display->get_update_mode &&
+				display->get_update_mode(display) ==
+				OMAP_DSS_UPDATE_MANUAL)
+			do_update = 1;
+
+		break;
+
+	case FB_BLANK_NORMAL:
+		/* FB_BLANK_NORMAL could be implemented.
+		 * Needs DSS additions. */
+	case FB_BLANK_VSYNC_SUSPEND:
+	case FB_BLANK_HSYNC_SUSPEND:
+	case FB_BLANK_POWERDOWN:
+		if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
+			goto exit;
+
+		if (display->suspend)
+			r = display->suspend(display);
+
+		break;
+
+	default:
+		r = -EINVAL;
+	}
+
+exit:
+	omapfb_unlock(fbdev);
+
+	if (r == 0 && do_update && display->update) {
+		u16 w, h;
+		display->get_resolution(display, &w, &h);
+
+		r = display->update(display, 0, 0, w, h);
+	}
+
+	return r;
+}
+
+#if 0
+/* XXX fb_read and fb_write are needed for VRFB */
+ssize_t omapfb_write(struct fb_info *info, const char __user *buf,
+		size_t count, loff_t *ppos)
+{
+	DBG("omapfb_write %d, %lu\n", count, (unsigned long)*ppos);
+	/* XXX needed for VRFB */
+	return count;
+}
+#endif
+
+static struct fb_ops omapfb_ops = {
+	.owner          = THIS_MODULE,
+	.fb_open        = omapfb_open,
+	.fb_release     = omapfb_release,
+	.fb_fillrect    = cfb_fillrect,
+	.fb_copyarea    = cfb_copyarea,
+	.fb_imageblit   = cfb_imageblit,
+	.fb_blank       = omapfb_blank,
+	.fb_ioctl       = omapfb_ioctl,
+	.fb_check_var   = omapfb_check_var,
+	.fb_set_par     = omapfb_set_par,
+	.fb_pan_display = omapfb_pan_display,
+	.fb_mmap	= omapfb_mmap,
+	.fb_setcolreg	= omapfb_setcolreg,
+	.fb_setcmap	= omapfb_setcmap,
+	/*.fb_write	= omapfb_write,*/
+};
+
+static void omapfb_free_fbmem(struct fb_info *fbi)
+{
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omapfb2_device *fbdev = ofbi->fbdev;
+	struct omapfb2_mem_region *rg;
+
+	rg = &ofbi->region;
+
+	if (rg->paddr)
+		if (omap_vram_free(rg->paddr, rg->size))
+			dev_err(fbdev->dev, "VRAM FREE failed\n");
+
+	if (rg->vaddr)
+		iounmap(rg->vaddr);
+
+	if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
+		/* unmap the 0 angle rotation */
+		if (rg->vrfb.vaddr[0]) {
+			iounmap(rg->vrfb.vaddr[0]);
+			omap_vrfb_release_ctx(&rg->vrfb);
+		}
+	}
+
+	rg->vaddr = NULL;
+	rg->paddr = 0;
+	rg->alloc = 0;
+	rg->size = 0;
+}
+
+static void clear_fb_info(struct fb_info *fbi)
+{
+	memset(&fbi->var, 0, sizeof(fbi->var));
+	memset(&fbi->fix, 0, sizeof(fbi->fix));
+	strlcpy(fbi->fix.id, MODULE_NAME, sizeof(fbi->fix.id));
+}
+
+static int omapfb_free_all_fbmem(struct omapfb2_device *fbdev)
+{
+	int i;
+
+	DBG("free all fbmem\n");
+
+	for (i = 0; i < fbdev->num_fbs; i++) {
+		struct fb_info *fbi = fbdev->fbs[i];
+		omapfb_free_fbmem(fbi);
+		clear_fb_info(fbi);
+	}
+
+	return 0;
+}
+
+static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
+		unsigned long paddr)
+{
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omapfb2_device *fbdev = ofbi->fbdev;
+	struct omapfb2_mem_region *rg;
+	void __iomem *vaddr;
+	int r;
+
+	rg = &ofbi->region;
+	memset(rg, 0, sizeof(*rg));
+
+	size = PAGE_ALIGN(size);
+
+	if (!paddr) {
+		DBG("allocating %lu bytes for fb %d\n", size, ofbi->id);
+		r = omap_vram_alloc(OMAP_VRAM_MEMTYPE_SDRAM, size, &paddr);
+	} else {
+		DBG("reserving %lu bytes at %lx for fb %d\n", size, paddr,
+				ofbi->id);
+		r = omap_vram_reserve(paddr, size);
+	}
+
+	if (r) {
+		dev_err(fbdev->dev, "failed to allocate framebuffer\n");
+		return -ENOMEM;
+	}
+
+	if (ofbi->rotation_type != OMAP_DSS_ROT_VRFB) {
+		vaddr = ioremap_wc(paddr, size);
+
+		if (!vaddr) {
+			dev_err(fbdev->dev, "failed to ioremap framebuffer\n");
+			omap_vram_free(paddr, size);
+			return -ENOMEM;
+		}
+
+		DBG("allocated VRAM paddr %lx, vaddr %p\n", paddr, vaddr);
+	} else {
+		r = omap_vrfb_request_ctx(&rg->vrfb);
+		if (r) {
+			dev_err(fbdev->dev, "vrfb create ctx failed\n");
+			return r;
+		}
+
+		vaddr = NULL;
+	}
+
+	rg->paddr = paddr;
+	rg->vaddr = vaddr;
+	rg->size = size;
+	rg->alloc = 1;
+
+	return 0;
+}
+
+/* allocate fbmem using display resolution as reference */
+static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size,
+		unsigned long paddr)
+{
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omap_dss_device *display;
+	int bytespp;
+
+	display =  fb2display(fbi);
+
+	if (!display)
+		return 0;
+
+	switch (display->get_recommended_bpp(display)) {
+	case 16:
+		bytespp = 2;
+		break;
+	case 24:
+		bytespp = 4;
+		break;
+	default:
+		bytespp = 4;
+		break;
+	}
+
+	if (!size) {
+		u16 w, h;
+
+		display->get_resolution(display, &w, &h);
+
+		if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
+			size = max(omap_vrfb_min_phys_size(w, h, bytespp),
+					omap_vrfb_min_phys_size(h, w, bytespp));
+
+			DBG("adjusting fb mem size for VRFB, %u -> %lu\n",
+					w * h * bytespp, size);
+		} else {
+			size = w * h * bytespp;
+		}
+	}
+
+	if (!size)
+		return 0;
+
+	return omapfb_alloc_fbmem(fbi, size, paddr);
+}
+
+static enum omap_color_mode fb_format_to_dss_mode(enum omapfb_color_format fmt)
+{
+	enum omap_color_mode mode;
+
+	switch (fmt) {
+	case OMAPFB_COLOR_RGB565:
+		mode = OMAP_DSS_COLOR_RGB16;
+		break;
+	case OMAPFB_COLOR_YUV422:
+		mode = OMAP_DSS_COLOR_YUV2;
+		break;
+	case OMAPFB_COLOR_CLUT_8BPP:
+		mode = OMAP_DSS_COLOR_CLUT8;
+		break;
+	case OMAPFB_COLOR_CLUT_4BPP:
+		mode = OMAP_DSS_COLOR_CLUT4;
+		break;
+	case OMAPFB_COLOR_CLUT_2BPP:
+		mode = OMAP_DSS_COLOR_CLUT2;
+		break;
+	case OMAPFB_COLOR_CLUT_1BPP:
+		mode = OMAP_DSS_COLOR_CLUT1;
+		break;
+	case OMAPFB_COLOR_RGB444:
+		mode = OMAP_DSS_COLOR_RGB12U;
+		break;
+	case OMAPFB_COLOR_YUY422:
+		mode = OMAP_DSS_COLOR_UYVY;
+		break;
+	case OMAPFB_COLOR_ARGB16:
+		mode = OMAP_DSS_COLOR_ARGB16;
+		break;
+	case OMAPFB_COLOR_RGB24U:
+		mode = OMAP_DSS_COLOR_RGB24U;
+		break;
+	case OMAPFB_COLOR_RGB24P:
+		mode = OMAP_DSS_COLOR_RGB24P;
+		break;
+	case OMAPFB_COLOR_ARGB32:
+		mode = OMAP_DSS_COLOR_ARGB32;
+		break;
+	case OMAPFB_COLOR_RGBA32:
+		mode = OMAP_DSS_COLOR_RGBA32;
+		break;
+	case OMAPFB_COLOR_RGBX32:
+		mode = OMAP_DSS_COLOR_RGBX32;
+		break;
+	default:
+		mode = -EINVAL;
+	}
+
+	return mode;
+}
+
+static int omapfb_parse_vram_param(const char *param, int max_entries,
+		unsigned long *sizes, unsigned long *paddrs)
+{
+	int fbnum;
+	unsigned long size;
+	unsigned long paddr = 0;
+	char *p, *start;
+
+	start = (char *)param;
+
+	while (1) {
+		p = start;
+
+		fbnum = simple_strtoul(p, &p, 10);
+
+		if (p == param)
+			return -EINVAL;
+
+		if (*p != ':')
+			return -EINVAL;
+
+		if (fbnum >= max_entries)
+			return -EINVAL;
+
+		size = memparse(p + 1, &p);
+
+		if (!size)
+			return -EINVAL;
+
+		paddr = 0;
+
+		if (*p == '@') {
+			paddr = simple_strtoul(p + 1, &p, 16);
+
+			if (!paddr)
+				return -EINVAL;
+
+		}
+
+		paddrs[fbnum] = paddr;
+		sizes[fbnum] = size;
+
+		if (*p == 0)
+			break;
+
+		if (*p != ',')
+			return -EINVAL;
+
+		++p;
+
+		start = p;
+	}
+
+	return 0;
+}
+
+static int omapfb_allocate_all_fbs(struct omapfb2_device *fbdev)
+{
+	int i, r;
+	unsigned long vram_sizes[10];
+	unsigned long vram_paddrs[10];
+
+	memset(&vram_sizes, 0, sizeof(vram_sizes));
+	memset(&vram_paddrs, 0, sizeof(vram_paddrs));
+
+	if (def_vram &&	omapfb_parse_vram_param(def_vram, 10,
+				vram_sizes, vram_paddrs)) {
+		dev_err(fbdev->dev, "failed to parse vram parameter\n");
+
+		memset(&vram_sizes, 0, sizeof(vram_sizes));
+		memset(&vram_paddrs, 0, sizeof(vram_paddrs));
+	}
+
+	if (fbdev->dev->platform_data) {
+		struct omapfb_platform_data *opd;
+		opd = fbdev->dev->platform_data;
+		for (i = 0; i < opd->mem_desc.region_cnt; ++i) {
+			if (!vram_sizes[i]) {
+				unsigned long size;
+				unsigned long paddr;
+
+				size = opd->mem_desc.region[i].size;
+				paddr = opd->mem_desc.region[i].paddr;
+
+				vram_sizes[i] = size;
+				vram_paddrs[i] = paddr;
+			}
+		}
+	}
+
+	for (i = 0; i < fbdev->num_fbs; i++) {
+		/* allocate memory automatically only for fb0, or if
+		 * excplicitly defined with vram or plat data option */
+		if (i == 0 || vram_sizes[i] != 0) {
+			r = omapfb_alloc_fbmem_display(fbdev->fbs[i],
+					vram_sizes[i], vram_paddrs[i]);
+
+			if (r)
+				return r;
+		}
+	}
+
+	for (i = 0; i < fbdev->num_fbs; i++) {
+		struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]);
+		struct omapfb2_mem_region *rg;
+		rg = &ofbi->region;
+
+		DBG("region%d phys %08x virt %p size=%lu\n",
+				i,
+				rg->paddr,
+				rg->vaddr,
+				rg->size);
+	}
+
+	return 0;
+}
+
+int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
+{
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omapfb2_device *fbdev = ofbi->fbdev;
+	struct omap_dss_device *display = fb2display(fbi);
+	struct omapfb2_mem_region *rg = &ofbi->region;
+	unsigned long old_size = rg->size;
+	unsigned long old_paddr = rg->paddr;
+	int old_type = rg->type;
+	int r;
+
+	if (type > OMAPFB_MEMTYPE_MAX)
+		return -EINVAL;
+
+	size = PAGE_ALIGN(size);
+
+	if (old_size == size && old_type == type)
+		return 0;
+
+	if (display && display->sync)
+			display->sync(display);
+
+	omapfb_free_fbmem(fbi);
+
+	if (size == 0) {
+		clear_fb_info(fbi);
+		return 0;
+	}
+
+	r = omapfb_alloc_fbmem(fbi, size, 0);
+
+	if (r) {
+		if (old_size)
+			omapfb_alloc_fbmem(fbi, old_size, old_paddr);
+
+		if (rg->size == 0)
+			clear_fb_info(fbi);
+
+		return r;
+	}
+
+	if (old_size == size)
+		return 0;
+
+	if (old_size == 0) {
+		DBG("initializing fb %d\n", ofbi->id);
+		r = omapfb_fb_init(fbdev, fbi);
+		if (r) {
+			DBG("omapfb_fb_init failed\n");
+			goto err;
+		}
+		r = omapfb_apply_changes(fbi, 1);
+		if (r) {
+			DBG("omapfb_apply_changes failed\n");
+			goto err;
+		}
+	} else {
+		struct fb_var_screeninfo new_var;
+		memcpy(&new_var, &fbi->var, sizeof(new_var));
+		r = check_fb_var(fbi, &new_var);
+		if (r)
+			goto err;
+		memcpy(&fbi->var, &new_var, sizeof(fbi->var));
+		set_fb_fix(fbi);
+		r = setup_vrfb_rotation(fbi);
+		if (r)
+			goto err;
+	}
+
+	return 0;
+err:
+	omapfb_free_fbmem(fbi);
+	clear_fb_info(fbi);
+	return r;
+}
+
+/* initialize fb_info, var, fix to something sane based on the display */
+static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
+{
+	struct fb_var_screeninfo *var = &fbi->var;
+	struct omap_dss_device *display = fb2display(fbi);
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	int r = 0;
+
+	fbi->fbops = &omapfb_ops;
+	fbi->flags = FBINFO_FLAG_DEFAULT;
+	fbi->pseudo_palette = fbdev->pseudo_palette;
+
+	if (ofbi->region.size == 0) {
+		clear_fb_info(fbi);
+		return 0;
+	}
+
+	var->nonstd = 0;
+	var->bits_per_pixel = 0;
+
+	var->rotate = def_rotate;
+
+	/*
+	 * Check if there is a default color format set in the board file,
+	 * and use this format instead the default deducted from the
+	 * display bpp.
+	 */
+	if (fbdev->dev->platform_data) {
+		struct omapfb_platform_data *opd;
+		int id = ofbi->id;
+
+		opd = fbdev->dev->platform_data;
+		if (opd->mem_desc.region[id].format_used) {
+			enum omap_color_mode mode;
+			enum omapfb_color_format format;
+
+			format = opd->mem_desc.region[id].format;
+			mode = fb_format_to_dss_mode(format);
+			if (mode < 0) {
+				r = mode;
+				goto err;
+			}
+			r = dss_mode_to_fb_mode(mode, var);
+			if (r < 0)
+				goto err;
+		}
+	}
+
+	if (display) {
+		u16 w, h;
+		int rotation = (var->rotate + ofbi->rotation[0]) % 4;
+
+		display->get_resolution(display, &w, &h);
+
+		if (rotation == FB_ROTATE_CW ||
+				rotation == FB_ROTATE_CCW) {
+			var->xres = h;
+			var->yres = w;
+		} else {
+			var->xres = w;
+			var->yres = h;
+		}
+
+		var->xres_virtual = var->xres;
+		var->yres_virtual = var->yres;
+
+		if (!var->bits_per_pixel) {
+			switch (display->get_recommended_bpp(display)) {
+			case 16:
+				var->bits_per_pixel = 16;
+				break;
+			case 24:
+				var->bits_per_pixel = 32;
+				break;
+			default:
+				dev_err(fbdev->dev, "illegal display "
+						"bpp\n");
+				return -EINVAL;
+			}
+		}
+	} else {
+		/* if there's no display, let's just guess some basic values */
+		var->xres = 320;
+		var->yres = 240;
+		var->xres_virtual = var->xres;
+		var->yres_virtual = var->yres;
+		if (!var->bits_per_pixel)
+			var->bits_per_pixel = 16;
+	}
+
+	r = check_fb_var(fbi, var);
+	if (r)
+		goto err;
+
+	set_fb_fix(fbi);
+	r = setup_vrfb_rotation(fbi);
+	if (r)
+		goto err;
+
+	r = fb_alloc_cmap(&fbi->cmap, 256, 0);
+	if (r)
+		dev_err(fbdev->dev, "unable to allocate color map memory\n");
+
+err:
+	return r;
+}
+
+static void fbinfo_cleanup(struct omapfb2_device *fbdev, struct fb_info *fbi)
+{
+	fb_dealloc_cmap(&fbi->cmap);
+}
+
+
+static void omapfb_free_resources(struct omapfb2_device *fbdev)
+{
+	int i;
+
+	DBG("free_resources\n");
+
+	if (fbdev == NULL)
+		return;
+
+	for (i = 0; i < fbdev->num_fbs; i++)
+		unregister_framebuffer(fbdev->fbs[i]);
+
+	/* free the reserved fbmem */
+	omapfb_free_all_fbmem(fbdev);
+
+	for (i = 0; i < fbdev->num_fbs; i++) {
+		fbinfo_cleanup(fbdev, fbdev->fbs[i]);
+		framebuffer_release(fbdev->fbs[i]);
+	}
+
+	for (i = 0; i < fbdev->num_displays; i++) {
+		if (fbdev->displays[i]->state != OMAP_DSS_DISPLAY_DISABLED)
+			fbdev->displays[i]->disable(fbdev->displays[i]);
+
+		omap_dss_put_device(fbdev->displays[i]);
+	}
+
+	dev_set_drvdata(fbdev->dev, NULL);
+	kfree(fbdev);
+}
+
+static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
+{
+	int r, i;
+
+	fbdev->num_fbs = 0;
+
+	DBG("create %d framebuffers\n",	CONFIG_FB_OMAP2_NUM_FBS);
+
+	/* allocate fb_infos */
+	for (i = 0; i < CONFIG_FB_OMAP2_NUM_FBS; i++) {
+		struct fb_info *fbi;
+		struct omapfb_info *ofbi;
+
+		fbi = framebuffer_alloc(sizeof(struct omapfb_info),
+				fbdev->dev);
+
+		if (fbi == NULL) {
+			dev_err(fbdev->dev,
+				"unable to allocate memory for plane info\n");
+			return -ENOMEM;
+		}
+
+		clear_fb_info(fbi);
+
+		fbdev->fbs[i] = fbi;
+
+		ofbi = FB2OFB(fbi);
+		ofbi->fbdev = fbdev;
+		ofbi->id = i;
+
+		/* assign these early, so that fb alloc can use them */
+		ofbi->rotation_type = def_vrfb ? OMAP_DSS_ROT_VRFB :
+			OMAP_DSS_ROT_DMA;
+		ofbi->mirror = def_mirror;
+
+		fbdev->num_fbs++;
+	}
+
+	DBG("fb_infos allocated\n");
+
+	/* assign overlays for the fbs */
+	for (i = 0; i < min(fbdev->num_fbs, fbdev->num_overlays); i++) {
+		struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]);
+
+		ofbi->overlays[0] = fbdev->overlays[i];
+		ofbi->num_overlays = 1;
+	}
+
+	/* allocate fb memories */
+	r = omapfb_allocate_all_fbs(fbdev);
+	if (r) {
+		dev_err(fbdev->dev, "failed to allocate fbmem\n");
+		return r;
+	}
+
+	DBG("fbmems allocated\n");
+
+	/* setup fb_infos */
+	for (i = 0; i < fbdev->num_fbs; i++) {
+		r = omapfb_fb_init(fbdev, fbdev->fbs[i]);
+		if (r) {
+			dev_err(fbdev->dev, "failed to setup fb_info\n");
+			return r;
+		}
+	}
+
+	DBG("fb_infos initialized\n");
+
+	for (i = 0; i < fbdev->num_fbs; i++) {
+		r = register_framebuffer(fbdev->fbs[i]);
+		if (r != 0) {
+			dev_err(fbdev->dev,
+				"registering framebuffer %d failed\n", i);
+			return r;
+		}
+	}
+
+	DBG("framebuffers registered\n");
+
+	for (i = 0; i < fbdev->num_fbs; i++) {
+		r = omapfb_apply_changes(fbdev->fbs[i], 1);
+		if (r) {
+			dev_err(fbdev->dev, "failed to change mode\n");
+			return r;
+		}
+	}
+
+	DBG("create sysfs for fbs\n");
+	r = omapfb_create_sysfs(fbdev);
+	if (r) {
+		dev_err(fbdev->dev, "failed to create sysfs entries\n");
+		return r;
+	}
+
+	/* Enable fb0 */
+	if (fbdev->num_fbs > 0) {
+		struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[0]);
+
+		if (ofbi->num_overlays > 0) {
+			struct omap_overlay *ovl = ofbi->overlays[0];
+
+			r = omapfb_overlay_enable(ovl, 1);
+
+			if (r) {
+				dev_err(fbdev->dev,
+						"failed to enable overlay\n");
+				return r;
+			}
+		}
+	}
+
+	DBG("create_framebuffers done\n");
+
+	return 0;
+}
+
+static int omapfb_mode_to_timings(const char *mode_str,
+		struct omap_video_timings *timings, u8 *bpp)
+{
+	struct fb_info fbi;
+	struct fb_var_screeninfo var;
+	struct fb_ops fbops;
+	int r;
+
+#ifdef CONFIG_OMAP2_DSS_VENC
+	if (strcmp(mode_str, "pal") == 0) {
+		*timings = omap_dss_pal_timings;
+		*bpp = 0;
+		return 0;
+	} else if (strcmp(mode_str, "ntsc") == 0) {
+		*timings = omap_dss_ntsc_timings;
+		*bpp = 0;
+		return 0;
+	}
+#endif
+
+	/* this is quite a hack, but I wanted to use the modedb and for
+	 * that we need fb_info and var, so we create dummy ones */
+
+	memset(&fbi, 0, sizeof(fbi));
+	memset(&var, 0, sizeof(var));
+	memset(&fbops, 0, sizeof(fbops));
+	fbi.fbops = &fbops;
+
+	r = fb_find_mode(&var, &fbi, mode_str, NULL, 0, NULL, 24);
+
+	if (r != 0) {
+		timings->pixel_clock = PICOS2KHZ(var.pixclock);
+		timings->hfp = var.left_margin;
+		timings->hbp = var.right_margin;
+		timings->vfp = var.upper_margin;
+		timings->vbp = var.lower_margin;
+		timings->hsw = var.hsync_len;
+		timings->vsw = var.vsync_len;
+		timings->x_res = var.xres;
+		timings->y_res = var.yres;
+
+		switch (var.bits_per_pixel) {
+		case 16:
+			*bpp = 16;
+			break;
+		case 24:
+		case 32:
+		default:
+			*bpp = 24;
+			break;
+		}
+
+		return 0;
+	} else {
+		return -EINVAL;
+	}
+}
+
+static int omapfb_set_def_mode(struct omap_dss_device *display, char *mode_str)
+{
+	int r;
+	u8 bpp;
+	struct omap_video_timings timings;
+
+	r = omapfb_mode_to_timings(mode_str, &timings, &bpp);
+	if (r)
+		return r;
+
+	display->panel.recommended_bpp = bpp;
+
+	if (!display->check_timings || !display->set_timings)
+		return -EINVAL;
+
+	r = display->check_timings(display, &timings);
+	if (r)
+		return r;
+
+	display->set_timings(display, &timings);
+
+	return 0;
+}
+
+static int omapfb_parse_def_modes(struct omapfb2_device *fbdev)
+{
+	char *str, *options, *this_opt;
+	int r = 0;
+
+	str = kmalloc(strlen(def_mode) + 1, GFP_KERNEL);
+	strcpy(str, def_mode);
+	options = str;
+
+	while (!r && (this_opt = strsep(&options, ",")) != NULL) {
+		char *p, *display_str, *mode_str;
+		struct omap_dss_device *display;
+		int i;
+
+		p = strchr(this_opt, ':');
+		if (!p) {
+			r = -EINVAL;
+			break;
+		}
+
+		*p = 0;
+		display_str = this_opt;
+		mode_str = p + 1;
+
+		display = NULL;
+		for (i = 0; i < fbdev->num_displays; ++i) {
+			if (strcmp(fbdev->displays[i]->name,
+						display_str) == 0) {
+				display = fbdev->displays[i];
+				break;
+			}
+		}
+
+		if (!display) {
+			r = -EINVAL;
+			break;
+		}
+
+		r = omapfb_set_def_mode(display, mode_str);
+		if (r)
+			break;
+	}
+
+	kfree(str);
+
+	return r;
+}
+
+static int omapfb_probe(struct platform_device *pdev)
+{
+	struct omapfb2_device *fbdev = NULL;
+	int r = 0;
+	int i;
+	struct omap_overlay *ovl;
+	struct omap_dss_device *def_display;
+	struct omap_dss_device *dssdev;
+
+	DBG("omapfb_probe\n");
+
+	if (pdev->num_resources != 0) {
+		dev_err(&pdev->dev, "probed for an unknown device\n");
+		r = -ENODEV;
+		goto err0;
+	}
+
+	fbdev = kzalloc(sizeof(struct omapfb2_device), GFP_KERNEL);
+	if (fbdev == NULL) {
+		r = -ENOMEM;
+		goto err0;
+	}
+
+	mutex_init(&fbdev->mtx);
+
+	fbdev->dev = &pdev->dev;
+	platform_set_drvdata(pdev, fbdev);
+
+	fbdev->num_displays = 0;
+	dssdev = NULL;
+	for_each_dss_dev(dssdev) {
+		omap_dss_get_device(dssdev);
+		fbdev->displays[fbdev->num_displays++] = dssdev;
+	}
+
+	if (fbdev->num_displays == 0) {
+		dev_err(&pdev->dev, "no displays\n");
+		r = -EINVAL;
+		goto cleanup;
+	}
+
+	fbdev->num_overlays = omap_dss_get_num_overlays();
+	for (i = 0; i < fbdev->num_overlays; i++)
+		fbdev->overlays[i] = omap_dss_get_overlay(i);
+
+	fbdev->num_managers = omap_dss_get_num_overlay_managers();
+	for (i = 0; i < fbdev->num_managers; i++)
+		fbdev->managers[i] = omap_dss_get_overlay_manager(i);
+
+	if (def_mode && strlen(def_mode) > 0) {
+		if (omapfb_parse_def_modes(fbdev))
+			dev_warn(&pdev->dev, "cannot parse default modes\n");
+	}
+
+	r = omapfb_create_framebuffers(fbdev);
+	if (r)
+		goto cleanup;
+
+	for (i = 0; i < fbdev->num_managers; i++) {
+		struct omap_overlay_manager *mgr;
+		mgr = fbdev->managers[i];
+		r = mgr->apply(mgr);
+		if (r)
+			dev_warn(fbdev->dev, "failed to apply dispc config\n");
+	}
+
+	DBG("mgr->apply'ed\n");
+
+	/* gfx overlay should be the default one. find a display
+	 * connected to that, and use it as default display */
+	ovl = omap_dss_get_overlay(0);
+	if (ovl->manager && ovl->manager->device) {
+		def_display = ovl->manager->device;
+	} else {
+		dev_warn(&pdev->dev, "cannot find default display\n");
+		def_display = NULL;
+	}
+
+	if (def_display) {
+#ifndef CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE
+		u16 w, h;
+#endif
+		r = def_display->enable(def_display);
+		if (r)
+			dev_warn(fbdev->dev, "Failed to enable display '%s'\n",
+					def_display->name);
+
+		/* set the update mode */
+		if (def_display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
+#ifdef CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE
+			if (def_display->enable_te)
+				def_display->enable_te(def_display, 1);
+			if (def_display->set_update_mode)
+				def_display->set_update_mode(def_display,
+						OMAP_DSS_UPDATE_AUTO);
+#else /* MANUAL_UPDATE */
+			if (def_display->enable_te)
+				def_display->enable_te(def_display, 0);
+			if (def_display->set_update_mode)
+				def_display->set_update_mode(def_display,
+						OMAP_DSS_UPDATE_MANUAL);
+
+			def_display->get_resolution(def_display, &w, &h);
+			def_display->update(def_display, 0, 0, w, h);
+#endif
+		} else {
+			if (def_display->set_update_mode)
+				def_display->set_update_mode(def_display,
+						OMAP_DSS_UPDATE_AUTO);
+		}
+	}
+
+	return 0;
+
+cleanup:
+	omapfb_free_resources(fbdev);
+err0:
+	dev_err(&pdev->dev, "failed to setup omapfb\n");
+	return r;
+}
+
+static int omapfb_remove(struct platform_device *pdev)
+{
+	struct omapfb2_device *fbdev = platform_get_drvdata(pdev);
+
+	/* FIXME: wait till completion of pending events */
+
+	omapfb_remove_sysfs(fbdev);
+
+	omapfb_free_resources(fbdev);
+
+	return 0;
+}
+
+static struct platform_driver omapfb_driver = {
+	.probe          = omapfb_probe,
+	.remove         = omapfb_remove,
+	.driver         = {
+		.name   = "omapfb",
+		.owner  = THIS_MODULE,
+	},
+};
+
+static int __init omapfb_init(void)
+{
+	DBG("omapfb_init\n");
+
+	if (platform_driver_register(&omapfb_driver)) {
+		printk(KERN_ERR "failed to register omapfb driver\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static void __exit omapfb_exit(void)
+{
+	DBG("omapfb_exit\n");
+	platform_driver_unregister(&omapfb_driver);
+}
+
+module_param_named(mode, def_mode, charp, 0);
+module_param_named(vram, def_vram, charp, 0);
+module_param_named(rotate, def_rotate, int, 0);
+module_param_named(vrfb, def_vrfb, bool, 0);
+module_param_named(mirror, def_mirror, bool, 0);
+
+/* late_initcall to let panel/ctrl drivers loaded first.
+ * I guess better option would be a more dynamic approach,
+ * so that omapfb reacts to new panels when they are loaded */
+late_initcall(omapfb_init);
+/*module_init(omapfb_init);*/
+module_exit(omapfb_exit);
+
+MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
+MODULE_DESCRIPTION("OMAP2/3 Framebuffer");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c
new file mode 100644
index 0000000..62bb88f
--- /dev/null
+++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c
@@ -0,0 +1,507 @@
+/*
+ * linux/drivers/video/omap2/omapfb-sysfs.c
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * Some code and ideas taken from drivers/video/omap/ driver
+ * by Imre Deak.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/fb.h>
+#include <linux/sysfs.h>
+#include <linux/device.h>
+#include <linux/uaccess.h>
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/omapfb.h>
+
+#include <plat/display.h>
+#include <plat/vrfb.h>
+
+#include "omapfb.h"
+
+static ssize_t show_rotate_type(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct fb_info *fbi = dev_get_drvdata(dev);
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", ofbi->rotation_type);
+}
+
+static ssize_t store_rotate_type(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct fb_info *fbi = dev_get_drvdata(dev);
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	enum omap_dss_rotation_type rot_type;
+	int r;
+
+	rot_type = simple_strtoul(buf, NULL, 0);
+
+	if (rot_type != OMAP_DSS_ROT_DMA && rot_type != OMAP_DSS_ROT_VRFB)
+		return -EINVAL;
+
+	lock_fb_info(fbi);
+
+	r = 0;
+	if (rot_type == ofbi->rotation_type)
+		goto out;
+
+	if (ofbi->region.size) {
+		r = -EBUSY;
+		goto out;
+	}
+
+	ofbi->rotation_type = rot_type;
+
+	/*
+	 * Since the VRAM for this FB is not allocated at the moment we don't
+	 * need to do any further parameter checking at this point.
+	 */
+out:
+	unlock_fb_info(fbi);
+
+	return r ? r : count;
+}
+
+
+static ssize_t show_mirror(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct fb_info *fbi = dev_get_drvdata(dev);
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", ofbi->mirror);
+}
+
+static ssize_t store_mirror(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct fb_info *fbi = dev_get_drvdata(dev);
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	bool mirror;
+	int r;
+	struct fb_var_screeninfo new_var;
+
+	mirror = simple_strtoul(buf, NULL, 0);
+
+	if (mirror != 0 && mirror != 1)
+		return -EINVAL;
+
+	lock_fb_info(fbi);
+
+	ofbi->mirror = mirror;
+
+	memcpy(&new_var, &fbi->var, sizeof(new_var));
+	r = check_fb_var(fbi, &new_var);
+	if (r)
+		goto out;
+	memcpy(&fbi->var, &new_var, sizeof(fbi->var));
+
+	set_fb_fix(fbi);
+
+	r = omapfb_apply_changes(fbi, 0);
+	if (r)
+		goto out;
+
+	r = count;
+out:
+	unlock_fb_info(fbi);
+
+	return r;
+}
+
+static ssize_t show_overlays(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct fb_info *fbi = dev_get_drvdata(dev);
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omapfb2_device *fbdev = ofbi->fbdev;
+	ssize_t l = 0;
+	int t;
+
+	omapfb_lock(fbdev);
+	lock_fb_info(fbi);
+
+	for (t = 0; t < ofbi->num_overlays; t++) {
+		struct omap_overlay *ovl = ofbi->overlays[t];
+		int ovlnum;
+
+		for (ovlnum = 0; ovlnum < fbdev->num_overlays; ++ovlnum)
+			if (ovl == fbdev->overlays[ovlnum])
+				break;
+
+		l += snprintf(buf + l, PAGE_SIZE - l, "%s%d",
+				t == 0 ? "" : ",", ovlnum);
+	}
+
+	l += snprintf(buf + l, PAGE_SIZE - l, "\n");
+
+	unlock_fb_info(fbi);
+	omapfb_unlock(fbdev);
+
+	return l;
+}
+
+static struct omapfb_info *get_overlay_fb(struct omapfb2_device *fbdev,
+		struct omap_overlay *ovl)
+{
+	int i, t;
+
+	for (i = 0; i < fbdev->num_fbs; i++) {
+		struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]);
+
+		for (t = 0; t < ofbi->num_overlays; t++) {
+			if (ofbi->overlays[t] == ovl)
+				return ofbi;
+		}
+	}
+
+	return NULL;
+}
+
+static ssize_t store_overlays(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct fb_info *fbi = dev_get_drvdata(dev);
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omapfb2_device *fbdev = ofbi->fbdev;
+	struct omap_overlay *ovls[OMAPFB_MAX_OVL_PER_FB];
+	struct omap_overlay *ovl;
+	int num_ovls, r, i;
+	int len;
+	bool added = false;
+
+	num_ovls = 0;
+
+	len = strlen(buf);
+	if (buf[len - 1] == '\n')
+		len = len - 1;
+
+	omapfb_lock(fbdev);
+	lock_fb_info(fbi);
+
+	if (len > 0) {
+		char *p = (char *)buf;
+		int ovlnum;
+
+		while (p < buf + len) {
+			int found;
+			if (num_ovls == OMAPFB_MAX_OVL_PER_FB) {
+				r = -EINVAL;
+				goto out;
+			}
+
+			ovlnum = simple_strtoul(p, &p, 0);
+			if (ovlnum > fbdev->num_overlays) {
+				r = -EINVAL;
+				goto out;
+			}
+
+			found = 0;
+			for (i = 0; i < num_ovls; ++i) {
+				if (ovls[i] == fbdev->overlays[ovlnum]) {
+					found = 1;
+					break;
+				}
+			}
+
+			if (!found)
+				ovls[num_ovls++] = fbdev->overlays[ovlnum];
+
+			p++;
+		}
+	}
+
+	for (i = 0; i < num_ovls; ++i) {
+		struct omapfb_info *ofbi2 = get_overlay_fb(fbdev, ovls[i]);
+		if (ofbi2 && ofbi2 != ofbi) {
+			dev_err(fbdev->dev, "overlay already in use\n");
+			r = -EINVAL;
+			goto out;
+		}
+	}
+
+	/* detach unused overlays */
+	for (i = 0; i < ofbi->num_overlays; ++i) {
+		int t, found;
+
+		ovl = ofbi->overlays[i];
+
+		found = 0;
+
+		for (t = 0; t < num_ovls; ++t) {
+			if (ovl == ovls[t]) {
+				found = 1;
+				break;
+			}
+		}
+
+		if (found)
+			continue;
+
+		DBG("detaching %d\n", ofbi->overlays[i]->id);
+
+		omapfb_overlay_enable(ovl, 0);
+
+		if (ovl->manager)
+			ovl->manager->apply(ovl->manager);
+
+		for (t = i + 1; t < ofbi->num_overlays; t++) {
+			ofbi->rotation[t-1] = ofbi->rotation[t];
+			ofbi->overlays[t-1] = ofbi->overlays[t];
+		}
+
+		ofbi->num_overlays--;
+		i--;
+	}
+
+	for (i = 0; i < num_ovls; ++i) {
+		int t, found;
+
+		ovl = ovls[i];
+
+		found = 0;
+
+		for (t = 0; t < ofbi->num_overlays; ++t) {
+			if (ovl == ofbi->overlays[t]) {
+				found = 1;
+				break;
+			}
+		}
+
+		if (found)
+			continue;
+		ofbi->rotation[ofbi->num_overlays] = 0;
+		ofbi->overlays[ofbi->num_overlays++] = ovl;
+
+		added = true;
+	}
+
+	if (added) {
+		r = omapfb_apply_changes(fbi, 0);
+		if (r)
+			goto out;
+	}
+
+	r = count;
+out:
+	unlock_fb_info(fbi);
+	omapfb_unlock(fbdev);
+
+	return r;
+}
+
+static ssize_t show_overlays_rotate(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct fb_info *fbi = dev_get_drvdata(dev);
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	ssize_t l = 0;
+	int t;
+
+	lock_fb_info(fbi);
+
+	for (t = 0; t < ofbi->num_overlays; t++) {
+		l += snprintf(buf + l, PAGE_SIZE - l, "%s%d",
+				t == 0 ? "" : ",", ofbi->rotation[t]);
+	}
+
+	l += snprintf(buf + l, PAGE_SIZE - l, "\n");
+
+	unlock_fb_info(fbi);
+
+	return l;
+}
+
+static ssize_t store_overlays_rotate(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct fb_info *fbi = dev_get_drvdata(dev);
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	int num_ovls = 0, r, i;
+	int len;
+	bool changed = false;
+	u8 rotation[OMAPFB_MAX_OVL_PER_FB];
+
+	len = strlen(buf);
+	if (buf[len - 1] == '\n')
+		len = len - 1;
+
+	lock_fb_info(fbi);
+
+	if (len > 0) {
+		char *p = (char *)buf;
+
+		while (p < buf + len) {
+			int rot;
+
+			if (num_ovls == ofbi->num_overlays) {
+				r = -EINVAL;
+				goto out;
+			}
+
+			rot = simple_strtoul(p, &p, 0);
+			if (rot < 0 || rot > 3) {
+				r = -EINVAL;
+				goto out;
+			}
+
+			if (ofbi->rotation[num_ovls] != rot)
+				changed = true;
+
+			rotation[num_ovls++] = rot;
+
+			p++;
+		}
+	}
+
+	if (num_ovls != ofbi->num_overlays) {
+		r = -EINVAL;
+		goto out;
+	}
+
+	if (changed) {
+		for (i = 0; i < num_ovls; ++i)
+			ofbi->rotation[i] = rotation[i];
+
+		r = omapfb_apply_changes(fbi, 0);
+		if (r)
+			goto out;
+
+		/* FIXME error handling? */
+	}
+
+	r = count;
+out:
+	unlock_fb_info(fbi);
+
+	return r;
+}
+
+static ssize_t show_size(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct fb_info *fbi = dev_get_drvdata(dev);
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+
+	return snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region.size);
+}
+
+static ssize_t store_size(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct fb_info *fbi = dev_get_drvdata(dev);
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	unsigned long size;
+	int r;
+	int i;
+
+	size = PAGE_ALIGN(simple_strtoul(buf, NULL, 0));
+
+	lock_fb_info(fbi);
+
+	for (i = 0; i < ofbi->num_overlays; i++) {
+		if (ofbi->overlays[i]->info.enabled) {
+			r = -EBUSY;
+			goto out;
+		}
+	}
+
+	if (size != ofbi->region.size) {
+		r = omapfb_realloc_fbmem(fbi, size, ofbi->region.type);
+		if (r) {
+			dev_err(dev, "realloc fbmem failed\n");
+			goto out;
+		}
+	}
+
+	r = count;
+out:
+	unlock_fb_info(fbi);
+
+	return r;
+}
+
+static ssize_t show_phys(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct fb_info *fbi = dev_get_drvdata(dev);
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+
+	return snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region.paddr);
+}
+
+static ssize_t show_virt(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct fb_info *fbi = dev_get_drvdata(dev);
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+
+	return snprintf(buf, PAGE_SIZE, "%p\n", ofbi->region.vaddr);
+}
+
+static struct device_attribute omapfb_attrs[] = {
+	__ATTR(rotate_type, S_IRUGO | S_IWUSR, show_rotate_type,
+			store_rotate_type),
+	__ATTR(mirror, S_IRUGO | S_IWUSR, show_mirror, store_mirror),
+	__ATTR(size, S_IRUGO | S_IWUSR, show_size, store_size),
+	__ATTR(overlays, S_IRUGO | S_IWUSR, show_overlays, store_overlays),
+	__ATTR(overlays_rotate, S_IRUGO | S_IWUSR, show_overlays_rotate,
+			store_overlays_rotate),
+	__ATTR(phys_addr, S_IRUGO, show_phys, NULL),
+	__ATTR(virt_addr, S_IRUGO, show_virt, NULL),
+};
+
+int omapfb_create_sysfs(struct omapfb2_device *fbdev)
+{
+	int i;
+	int r;
+
+	DBG("create sysfs for fbs\n");
+	for (i = 0; i < fbdev->num_fbs; i++) {
+		int t;
+		for (t = 0; t < ARRAY_SIZE(omapfb_attrs); t++) {
+			r = device_create_file(fbdev->fbs[i]->dev,
+					&omapfb_attrs[t]);
+
+			if (r) {
+				dev_err(fbdev->dev, "failed to create sysfs "
+						"file\n");
+				return r;
+			}
+		}
+	}
+
+	return 0;
+}
+
+void omapfb_remove_sysfs(struct omapfb2_device *fbdev)
+{
+	int i, t;
+
+	DBG("remove sysfs for fbs\n");
+	for (i = 0; i < fbdev->num_fbs; i++) {
+		for (t = 0; t < ARRAY_SIZE(omapfb_attrs); t++)
+			device_remove_file(fbdev->fbs[i]->dev,
+					&omapfb_attrs[t]);
+	}
+}
+
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
new file mode 100644
index 0000000..f7c9c73
--- /dev/null
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -0,0 +1,146 @@
+/*
+ * linux/drivers/video/omap2/omapfb.h
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * Some code and ideas taken from drivers/video/omap/ driver
+ * by Imre Deak.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __DRIVERS_VIDEO_OMAP2_OMAPFB_H__
+#define __DRIVERS_VIDEO_OMAP2_OMAPFB_H__
+
+#ifdef CONFIG_FB_OMAP2_DEBUG_SUPPORT
+#define DEBUG
+#endif
+
+#include <plat/display.h>
+
+#ifdef DEBUG
+extern unsigned int omapfb_debug;
+#define DBG(format, ...) \
+	if (omapfb_debug) \
+		printk(KERN_DEBUG "OMAPFB: " format, ## __VA_ARGS__)
+#else
+#define DBG(format, ...)
+#endif
+
+#define FB2OFB(fb_info) ((struct omapfb_info *)(fb_info->par))
+
+/* max number of overlays to which a framebuffer data can be direct */
+#define OMAPFB_MAX_OVL_PER_FB 3
+
+struct omapfb2_mem_region {
+	u32		paddr;
+	void __iomem	*vaddr;
+	struct vrfb	vrfb;
+	unsigned long	size;
+	u8		type;		/* OMAPFB_PLANE_MEM_* */
+	bool		alloc;		/* allocated by the driver */
+	bool		map;		/* kernel mapped by the driver */
+};
+
+/* appended to fb_info */
+struct omapfb_info {
+	int id;
+	struct omapfb2_mem_region region;
+	atomic_t map_count;
+	int num_overlays;
+	struct omap_overlay *overlays[OMAPFB_MAX_OVL_PER_FB];
+	struct omapfb2_device *fbdev;
+	enum omap_dss_rotation_type rotation_type;
+	u8 rotation[OMAPFB_MAX_OVL_PER_FB];
+	bool mirror;
+};
+
+struct omapfb2_device {
+	struct device *dev;
+	struct mutex  mtx;
+
+	u32 pseudo_palette[17];
+
+	int state;
+
+	unsigned num_fbs;
+	struct fb_info *fbs[10];
+
+	unsigned num_displays;
+	struct omap_dss_device *displays[10];
+	unsigned num_overlays;
+	struct omap_overlay *overlays[10];
+	unsigned num_managers;
+	struct omap_overlay_manager *managers[10];
+};
+
+struct omapfb_colormode {
+	enum omap_color_mode dssmode;
+	u32 bits_per_pixel;
+	u32 nonstd;
+	struct fb_bitfield red;
+	struct fb_bitfield green;
+	struct fb_bitfield blue;
+	struct fb_bitfield transp;
+};
+
+void set_fb_fix(struct fb_info *fbi);
+int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var);
+int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type);
+int omapfb_apply_changes(struct fb_info *fbi, int init);
+
+int omapfb_create_sysfs(struct omapfb2_device *fbdev);
+void omapfb_remove_sysfs(struct omapfb2_device *fbdev);
+
+int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg);
+
+int dss_mode_to_fb_mode(enum omap_color_mode dssmode,
+			struct fb_var_screeninfo *var);
+
+/* find the display connected to this fb, if any */
+static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
+{
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	int i;
+
+	/* XXX: returns the display connected to first attached overlay */
+	for (i = 0; i < ofbi->num_overlays; i++) {
+		if (ofbi->overlays[i]->manager)
+			return ofbi->overlays[i]->manager->device;
+	}
+
+	return NULL;
+}
+
+static inline void omapfb_lock(struct omapfb2_device *fbdev)
+{
+	mutex_lock(&fbdev->mtx);
+}
+
+static inline void omapfb_unlock(struct omapfb2_device *fbdev)
+{
+	mutex_unlock(&fbdev->mtx);
+}
+
+static inline int omapfb_overlay_enable(struct omap_overlay *ovl,
+		int enable)
+{
+	struct omap_overlay_info info;
+
+	ovl->get_overlay_info(ovl, &info);
+	info.enabled = enable;
+	return ovl->set_overlay_info(ovl, &info);
+}
+
+#endif
diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c
new file mode 100644
index 0000000..55a4de5
--- /dev/null
+++ b/drivers/video/omap2/vram.c
@@ -0,0 +1,655 @@
+/*
+ * VRAM manager for OMAP
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.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.
+ *
+ * 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.
+ */
+
+/*#define DEBUG*/
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/list.h>
+#include <linux/seq_file.h>
+#include <linux/bootmem.h>
+#include <linux/completion.h>
+#include <linux/debugfs.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+
+#include <asm/setup.h>
+
+#include <plat/sram.h>
+#include <plat/vram.h>
+#include <plat/dma.h>
+
+#ifdef DEBUG
+#define DBG(format, ...) pr_debug("VRAM: " format, ## __VA_ARGS__)
+#else
+#define DBG(format, ...)
+#endif
+
+#define OMAP2_SRAM_START		0x40200000
+/* Maximum size, in reality this is smaller if SRAM is partially locked. */
+#define OMAP2_SRAM_SIZE			0xa0000		/* 640k */
+
+/* postponed regions are used to temporarily store region information at boot
+ * time when we cannot yet allocate the region list */
+#define MAX_POSTPONED_REGIONS 10
+
+static bool vram_initialized;
+static int postponed_cnt;
+static struct {
+	unsigned long paddr;
+	size_t size;
+} postponed_regions[MAX_POSTPONED_REGIONS];
+
+struct vram_alloc {
+	struct list_head list;
+	unsigned long paddr;
+	unsigned pages;
+};
+
+struct vram_region {
+	struct list_head list;
+	struct list_head alloc_list;
+	unsigned long paddr;
+	unsigned pages;
+};
+
+static DEFINE_MUTEX(region_mutex);
+static LIST_HEAD(region_list);
+
+static inline int region_mem_type(unsigned long paddr)
+{
+	if (paddr >= OMAP2_SRAM_START &&
+	    paddr < OMAP2_SRAM_START + OMAP2_SRAM_SIZE)
+		return OMAP_VRAM_MEMTYPE_SRAM;
+	else
+		return OMAP_VRAM_MEMTYPE_SDRAM;
+}
+
+static struct vram_region *omap_vram_create_region(unsigned long paddr,
+		unsigned pages)
+{
+	struct vram_region *rm;
+
+	rm = kzalloc(sizeof(*rm), GFP_KERNEL);
+
+	if (rm) {
+		INIT_LIST_HEAD(&rm->alloc_list);
+		rm->paddr = paddr;
+		rm->pages = pages;
+	}
+
+	return rm;
+}
+
+#if 0
+static void omap_vram_free_region(struct vram_region *vr)
+{
+	list_del(&vr->list);
+	kfree(vr);
+}
+#endif
+
+static struct vram_alloc *omap_vram_create_allocation(struct vram_region *vr,
+		unsigned long paddr, unsigned pages)
+{
+	struct vram_alloc *va;
+	struct vram_alloc *new;
+
+	new = kzalloc(sizeof(*va), GFP_KERNEL);
+
+	if (!new)
+		return NULL;
+
+	new->paddr = paddr;
+	new->pages = pages;
+
+	list_for_each_entry(va, &vr->alloc_list, list) {
+		if (va->paddr > new->paddr)
+			break;
+	}
+
+	list_add_tail(&new->list, &va->list);
+
+	return new;
+}
+
+static void omap_vram_free_allocation(struct vram_alloc *va)
+{
+	list_del(&va->list);
+	kfree(va);
+}
+
+int omap_vram_add_region(unsigned long paddr, size_t size)
+{
+	struct vram_region *rm;
+	unsigned pages;
+
+	if (vram_initialized) {
+		DBG("adding region paddr %08lx size %d\n",
+				paddr, size);
+
+		size &= PAGE_MASK;
+		pages = size >> PAGE_SHIFT;
+
+		rm = omap_vram_create_region(paddr, pages);
+		if (rm == NULL)
+			return -ENOMEM;
+
+		list_add(&rm->list, &region_list);
+	} else {
+		if (postponed_cnt == MAX_POSTPONED_REGIONS)
+			return -ENOMEM;
+
+		postponed_regions[postponed_cnt].paddr = paddr;
+		postponed_regions[postponed_cnt].size = size;
+
+		++postponed_cnt;
+	}
+	return 0;
+}
+
+int omap_vram_free(unsigned long paddr, size_t size)
+{
+	struct vram_region *rm;
+	struct vram_alloc *alloc;
+	unsigned start, end;
+
+	DBG("free mem paddr %08lx size %d\n", paddr, size);
+
+	size = PAGE_ALIGN(size);
+
+	mutex_lock(&region_mutex);
+
+	list_for_each_entry(rm, &region_list, list) {
+		list_for_each_entry(alloc, &rm->alloc_list, list) {
+			start = alloc->paddr;
+			end = alloc->paddr + (alloc->pages >> PAGE_SHIFT);
+
+			if (start >= paddr && end < paddr + size)
+				goto found;
+		}
+	}
+
+	mutex_unlock(&region_mutex);
+	return -EINVAL;
+
+found:
+	omap_vram_free_allocation(alloc);
+
+	mutex_unlock(&region_mutex);
+	return 0;
+}
+EXPORT_SYMBOL(omap_vram_free);
+
+static int _omap_vram_reserve(unsigned long paddr, unsigned pages)
+{
+	struct vram_region *rm;
+	struct vram_alloc *alloc;
+	size_t size;
+
+	size = pages << PAGE_SHIFT;
+
+	list_for_each_entry(rm, &region_list, list) {
+		unsigned long start, end;
+
+		DBG("checking region %lx %d\n", rm->paddr, rm->pages);
+
+		if (region_mem_type(rm->paddr) != region_mem_type(paddr))
+			continue;
+
+		start = rm->paddr;
+		end = start + (rm->pages << PAGE_SHIFT) - 1;
+		if (start > paddr || end < paddr + size - 1)
+			continue;
+
+		DBG("block ok, checking allocs\n");
+
+		list_for_each_entry(alloc, &rm->alloc_list, list) {
+			end = alloc->paddr - 1;
+
+			if (start <= paddr && end >= paddr + size - 1)
+				goto found;
+
+			start = alloc->paddr + (alloc->pages << PAGE_SHIFT);
+		}
+
+		end = rm->paddr + (rm->pages << PAGE_SHIFT) - 1;
+
+		if (!(start <= paddr && end >= paddr + size - 1))
+			continue;
+found:
+		DBG("found area start %lx, end %lx\n", start, end);
+
+		if (omap_vram_create_allocation(rm, paddr, pages) == NULL)
+			return -ENOMEM;
+
+		return 0;
+	}
+
+	return -ENOMEM;
+}
+
+int omap_vram_reserve(unsigned long paddr, size_t size)
+{
+	unsigned pages;
+	int r;
+
+	DBG("reserve mem paddr %08lx size %d\n", paddr, size);
+
+	size = PAGE_ALIGN(size);
+	pages = size >> PAGE_SHIFT;
+
+	mutex_lock(&region_mutex);
+
+	r = _omap_vram_reserve(paddr, pages);
+
+	mutex_unlock(&region_mutex);
+
+	return r;
+}
+EXPORT_SYMBOL(omap_vram_reserve);
+
+static void _omap_vram_dma_cb(int lch, u16 ch_status, void *data)
+{
+	struct completion *compl = data;
+	complete(compl);
+}
+
+static int _omap_vram_clear(u32 paddr, unsigned pages)
+{
+	struct completion compl;
+	unsigned elem_count;
+	unsigned frame_count;
+	int r;
+	int lch;
+
+	init_completion(&compl);
+
+	r = omap_request_dma(OMAP_DMA_NO_DEVICE, "VRAM DMA",
+			_omap_vram_dma_cb,
+			&compl, &lch);
+	if (r) {
+		pr_err("VRAM: request_dma failed for memory clear\n");
+		return -EBUSY;
+	}
+
+	elem_count = pages * PAGE_SIZE / 4;
+	frame_count = 1;
+
+	omap_set_dma_transfer_params(lch, OMAP_DMA_DATA_TYPE_S32,
+			elem_count, frame_count,
+			OMAP_DMA_SYNC_ELEMENT,
+			0, 0);
+
+	omap_set_dma_dest_params(lch, 0, OMAP_DMA_AMODE_POST_INC,
+			paddr, 0, 0);
+
+	omap_set_dma_color_mode(lch, OMAP_DMA_CONSTANT_FILL, 0x000000);
+
+	omap_start_dma(lch);
+
+	if (wait_for_completion_timeout(&compl, msecs_to_jiffies(1000)) == 0) {
+		omap_stop_dma(lch);
+		pr_err("VRAM: dma timeout while clearing memory\n");
+		r = -EIO;
+		goto err;
+	}
+
+	r = 0;
+err:
+	omap_free_dma(lch);
+
+	return r;
+}
+
+static int _omap_vram_alloc(int mtype, unsigned pages, unsigned long *paddr)
+{
+	struct vram_region *rm;
+	struct vram_alloc *alloc;
+
+	list_for_each_entry(rm, &region_list, list) {
+		unsigned long start, end;
+
+		DBG("checking region %lx %d\n", rm->paddr, rm->pages);
+
+		if (region_mem_type(rm->paddr) != mtype)
+			continue;
+
+		start = rm->paddr;
+
+		list_for_each_entry(alloc, &rm->alloc_list, list) {
+			end = alloc->paddr;
+
+			if (end - start >= pages << PAGE_SHIFT)
+				goto found;
+
+			start = alloc->paddr + (alloc->pages << PAGE_SHIFT);
+		}
+
+		end = rm->paddr + (rm->pages << PAGE_SHIFT);
+found:
+		if (end - start < pages << PAGE_SHIFT)
+			continue;
+
+		DBG("found %lx, end %lx\n", start, end);
+
+		alloc = omap_vram_create_allocation(rm, start, pages);
+		if (alloc == NULL)
+			return -ENOMEM;
+
+		*paddr = start;
+
+		_omap_vram_clear(start, pages);
+
+		return 0;
+	}
+
+	return -ENOMEM;
+}
+
+int omap_vram_alloc(int mtype, size_t size, unsigned long *paddr)
+{
+	unsigned pages;
+	int r;
+
+	BUG_ON(mtype > OMAP_VRAM_MEMTYPE_MAX || !size);
+
+	DBG("alloc mem type %d size %d\n", mtype, size);
+
+	size = PAGE_ALIGN(size);
+	pages = size >> PAGE_SHIFT;
+
+	mutex_lock(&region_mutex);
+
+	r = _omap_vram_alloc(mtype, pages, paddr);
+
+	mutex_unlock(&region_mutex);
+
+	return r;
+}
+EXPORT_SYMBOL(omap_vram_alloc);
+
+void omap_vram_get_info(unsigned long *vram,
+		unsigned long *free_vram,
+		unsigned long *largest_free_block)
+{
+	struct vram_region *vr;
+	struct vram_alloc *va;
+
+	*vram = 0;
+	*free_vram = 0;
+	*largest_free_block = 0;
+
+	mutex_lock(&region_mutex);
+
+	list_for_each_entry(vr, &region_list, list) {
+		unsigned free;
+		unsigned long pa;
+
+		pa = vr->paddr;
+		*vram += vr->pages << PAGE_SHIFT;
+
+		list_for_each_entry(va, &vr->alloc_list, list) {
+			free = va->paddr - pa;
+			*free_vram += free;
+			if (free > *largest_free_block)
+				*largest_free_block = free;
+			pa = va->paddr + (va->pages << PAGE_SHIFT);
+		}
+
+		free = vr->paddr + (vr->pages << PAGE_SHIFT) - pa;
+		*free_vram += free;
+		if (free > *largest_free_block)
+			*largest_free_block = free;
+	}
+
+	mutex_unlock(&region_mutex);
+}
+EXPORT_SYMBOL(omap_vram_get_info);
+
+#if defined(CONFIG_DEBUG_FS)
+static int vram_debug_show(struct seq_file *s, void *unused)
+{
+	struct vram_region *vr;
+	struct vram_alloc *va;
+	unsigned size;
+
+	mutex_lock(&region_mutex);
+
+	list_for_each_entry(vr, &region_list, list) {
+		size = vr->pages << PAGE_SHIFT;
+		seq_printf(s, "%08lx-%08lx (%d bytes)\n",
+				vr->paddr, vr->paddr + size - 1,
+				size);
+
+		list_for_each_entry(va, &vr->alloc_list, list) {
+			size = va->pages << PAGE_SHIFT;
+			seq_printf(s, "    %08lx-%08lx (%d bytes)\n",
+					va->paddr, va->paddr + size - 1,
+					size);
+		}
+	}
+
+	mutex_unlock(&region_mutex);
+
+	return 0;
+}
+
+static int vram_debug_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, vram_debug_show, inode->i_private);
+}
+
+static const struct file_operations vram_debug_fops = {
+	.open           = vram_debug_open,
+	.read           = seq_read,
+	.llseek         = seq_lseek,
+	.release        = single_release,
+};
+
+static int __init omap_vram_create_debugfs(void)
+{
+	struct dentry *d;
+
+	d = debugfs_create_file("vram", S_IRUGO, NULL,
+			NULL, &vram_debug_fops);
+	if (IS_ERR(d))
+		return PTR_ERR(d);
+
+	return 0;
+}
+#endif
+
+static __init int omap_vram_init(void)
+{
+	int i;
+
+	vram_initialized = 1;
+
+	for (i = 0; i < postponed_cnt; i++)
+		omap_vram_add_region(postponed_regions[i].paddr,
+				postponed_regions[i].size);
+
+#ifdef CONFIG_DEBUG_FS
+	if (omap_vram_create_debugfs())
+		pr_err("VRAM: Failed to create debugfs file\n");
+#endif
+
+	return 0;
+}
+
+arch_initcall(omap_vram_init);
+
+/* boottime vram alloc stuff */
+
+/* set from board file */
+static u32 omap_vram_sram_start __initdata;
+static u32 omap_vram_sram_size __initdata;
+
+/* set from board file */
+static u32 omap_vram_sdram_start __initdata;
+static u32 omap_vram_sdram_size __initdata;
+
+/* set from kernel cmdline */
+static u32 omap_vram_def_sdram_size __initdata;
+static u32 omap_vram_def_sdram_start __initdata;
+
+static void __init omap_vram_early_vram(char **p)
+{
+	omap_vram_def_sdram_size = memparse(*p, p);
+	if (**p == ',')
+		omap_vram_def_sdram_start = simple_strtoul((*p) + 1, p, 16);
+}
+__early_param("vram=", omap_vram_early_vram);
+
+/*
+ * Called from map_io. We need to call to this early enough so that we
+ * can reserve the fixed SDRAM regions before VM could get hold of them.
+ */
+void __init omap_vram_reserve_sdram(void)
+{
+	struct bootmem_data	*bdata;
+	unsigned long		sdram_start, sdram_size;
+	u32 paddr;
+	u32 size = 0;
+
+	/* cmdline arg overrides the board file definition */
+	if (omap_vram_def_sdram_size) {
+		size = omap_vram_def_sdram_size;
+		paddr = omap_vram_def_sdram_start;
+	}
+
+	if (!size) {
+		size = omap_vram_sdram_size;
+		paddr = omap_vram_sdram_start;
+	}
+
+#ifdef CONFIG_OMAP2_VRAM_SIZE
+	if (!size) {
+		size = CONFIG_OMAP2_VRAM_SIZE * 1024 * 1024;
+		paddr = 0;
+	}
+#endif
+
+	if (!size)
+		return;
+
+	size = PAGE_ALIGN(size);
+
+	bdata = NODE_DATA(0)->bdata;
+	sdram_start = bdata->node_min_pfn << PAGE_SHIFT;
+	sdram_size = (bdata->node_low_pfn << PAGE_SHIFT) - sdram_start;
+
+	if (paddr) {
+		if ((paddr & ~PAGE_MASK) || paddr < sdram_start ||
+				paddr + size > sdram_start + sdram_size) {
+			pr_err("Illegal SDRAM region for VRAM\n");
+			return;
+		}
+
+		if (reserve_bootmem(paddr, size, BOOTMEM_EXCLUSIVE) < 0) {
+			pr_err("FB: failed to reserve VRAM\n");
+			return;
+		}
+	} else {
+		if (size > sdram_size) {
+			pr_err("Illegal SDRAM size for VRAM\n");
+			return;
+		}
+
+		paddr = virt_to_phys(alloc_bootmem_pages(size));
+		BUG_ON(paddr & ~PAGE_MASK);
+	}
+
+	omap_vram_add_region(paddr, size);
+
+	pr_info("Reserving %u bytes SDRAM for VRAM\n", size);
+}
+
+/*
+ * Called at sram init time, before anything is pushed to the SRAM stack.
+ * Because of the stack scheme, we will allocate everything from the
+ * start of the lowest address region to the end of SRAM. This will also
+ * include padding for page alignment and possible holes between regions.
+ *
+ * As opposed to the SDRAM case, we'll also do any dynamic allocations at
+ * this point, since the driver built as a module would have problem with
+ * freeing / reallocating the regions.
+ */
+unsigned long __init omap_vram_reserve_sram(unsigned long sram_pstart,
+				  unsigned long sram_vstart,
+				  unsigned long sram_size,
+				  unsigned long pstart_avail,
+				  unsigned long size_avail)
+{
+	unsigned long			pend_avail;
+	unsigned long			reserved;
+	u32 paddr;
+	u32 size;
+
+	paddr = omap_vram_sram_start;
+	size = omap_vram_sram_size;
+
+	if (!size)
+		return 0;
+
+	reserved = 0;
+	pend_avail = pstart_avail + size_avail;
+
+	if (!paddr) {
+		/* Dynamic allocation */
+		if ((size_avail & PAGE_MASK) < size) {
+			pr_err("Not enough SRAM for VRAM\n");
+			return 0;
+		}
+		size_avail = (size_avail - size) & PAGE_MASK;
+		paddr = pstart_avail + size_avail;
+	}
+
+	if (paddr < sram_pstart ||
+			paddr + size > sram_pstart + sram_size) {
+		pr_err("Illegal SRAM region for VRAM\n");
+		return 0;
+	}
+
+	/* Reserve everything above the start of the region. */
+	if (pend_avail - paddr > reserved)
+		reserved = pend_avail - paddr;
+	size_avail = pend_avail - reserved - pstart_avail;
+
+	omap_vram_add_region(paddr, size);
+
+	if (reserved)
+		pr_info("Reserving %lu bytes SRAM for VRAM\n", reserved);
+
+	return reserved;
+}
+
+void __init omap_vram_set_sdram_vram(u32 size, u32 start)
+{
+	omap_vram_sdram_start = start;
+	omap_vram_sdram_size = size;
+}
+
+void __init omap_vram_set_sram_vram(u32 size, u32 start)
+{
+	omap_vram_sram_start = start;
+	omap_vram_sram_size = size;
+}
diff --git a/drivers/video/omap2/vrfb.c b/drivers/video/omap2/vrfb.c
new file mode 100644
index 0000000..fd22716
--- /dev/null
+++ b/drivers/video/omap2/vrfb.c
@@ -0,0 +1,315 @@
+/*
+ * VRFB Rotation Engine
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.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.
+ *
+ * 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.
+ */
+
+/*#define DEBUG*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/mutex.h>
+
+#include <mach/io.h>
+#include <plat/vrfb.h>
+#include <plat/sdrc.h>
+
+#ifdef DEBUG
+#define DBG(format, ...) pr_debug("VRFB: " format, ## __VA_ARGS__)
+#else
+#define DBG(format, ...)
+#endif
+
+#define SMS_ROT_VIRT_BASE(context, rot) \
+	(((context >= 4) ? 0xD0000000 : 0x70000000) \
+	 + (0x4000000 * (context)) \
+	 + (0x1000000 * (rot)))
+
+#define OMAP_VRFB_SIZE			(2048 * 2048 * 4)
+
+#define VRFB_PAGE_WIDTH_EXP	5 /* Assuming SDRAM pagesize= 1024 */
+#define VRFB_PAGE_HEIGHT_EXP	5 /* 1024 = 2^5 * 2^5 */
+#define VRFB_PAGE_WIDTH		(1 << VRFB_PAGE_WIDTH_EXP)
+#define VRFB_PAGE_HEIGHT	(1 << VRFB_PAGE_HEIGHT_EXP)
+#define SMS_IMAGEHEIGHT_OFFSET	16
+#define SMS_IMAGEWIDTH_OFFSET	0
+#define SMS_PH_OFFSET		8
+#define SMS_PW_OFFSET		4
+#define SMS_PS_OFFSET		0
+
+#define VRFB_NUM_CTXS 12
+/* bitmap of reserved contexts */
+static unsigned long ctx_map;
+
+static DEFINE_MUTEX(ctx_lock);
+
+/*
+ * Access to this happens from client drivers or the PM core after wake-up.
+ * For the first case we require locking at the driver level, for the second
+ * we don't need locking, since no drivers will run until after the wake-up
+ * has finished.
+ */
+static struct {
+	u32 physical_ba;
+	u32 control;
+	u32 size;
+} vrfb_hw_context[VRFB_NUM_CTXS];
+
+static inline void restore_hw_context(int ctx)
+{
+	omap2_sms_write_rot_control(vrfb_hw_context[ctx].control, ctx);
+	omap2_sms_write_rot_size(vrfb_hw_context[ctx].size, ctx);
+	omap2_sms_write_rot_physical_ba(vrfb_hw_context[ctx].physical_ba, ctx);
+}
+
+static u32 get_image_width_roundup(u16 width, u8 bytespp)
+{
+	unsigned long stride = width * bytespp;
+	unsigned long ceil_pages_per_stride = (stride / VRFB_PAGE_WIDTH) +
+		(stride % VRFB_PAGE_WIDTH != 0);
+
+	return ceil_pages_per_stride * VRFB_PAGE_WIDTH / bytespp;
+}
+
+/*
+ * This the extra space needed in the VRFB physical area for VRFB to safely wrap
+ * any memory accesses to the invisible part of the virtual view to the physical
+ * area.
+ */
+static inline u32 get_extra_physical_size(u16 image_width_roundup, u8 bytespp)
+{
+	return (OMAP_VRFB_LINE_LEN - image_width_roundup) * VRFB_PAGE_HEIGHT *
+		bytespp;
+}
+
+void omap_vrfb_restore_context(void)
+{
+	int i;
+	unsigned long map = ctx_map;
+
+	for (i = ffs(map); i; i = ffs(map)) {
+		/* i=1..32 */
+		i--;
+		map &= ~(1 << i);
+		restore_hw_context(i);
+	}
+}
+
+void omap_vrfb_adjust_size(u16 *width, u16 *height,
+		u8 bytespp)
+{
+	*width = ALIGN(*width * bytespp, VRFB_PAGE_WIDTH) / bytespp;
+	*height = ALIGN(*height, VRFB_PAGE_HEIGHT);
+}
+EXPORT_SYMBOL(omap_vrfb_adjust_size);
+
+u32 omap_vrfb_min_phys_size(u16 width, u16 height, u8 bytespp)
+{
+	unsigned long image_width_roundup = get_image_width_roundup(width,
+		bytespp);
+
+	if (image_width_roundup > OMAP_VRFB_LINE_LEN)
+		return 0;
+
+	return (width * height * bytespp) + get_extra_physical_size(
+		image_width_roundup, bytespp);
+}
+EXPORT_SYMBOL(omap_vrfb_min_phys_size);
+
+u16 omap_vrfb_max_height(u32 phys_size, u16 width, u8 bytespp)
+{
+	unsigned long image_width_roundup = get_image_width_roundup(width,
+		bytespp);
+	unsigned long height;
+	unsigned long extra;
+
+	if (image_width_roundup > OMAP_VRFB_LINE_LEN)
+		return 0;
+
+	extra = get_extra_physical_size(image_width_roundup, bytespp);
+
+	if (phys_size < extra)
+		return 0;
+
+	height = (phys_size - extra) / (width * bytespp);
+
+	/* Virtual views provided by VRFB are limited to 2048x2048. */
+	return min_t(unsigned long, height, 2048);
+}
+EXPORT_SYMBOL(omap_vrfb_max_height);
+
+void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
+		u16 width, u16 height,
+		unsigned bytespp, bool yuv_mode)
+{
+	unsigned pixel_size_exp;
+	u16 vrfb_width;
+	u16 vrfb_height;
+	u8 ctx = vrfb->context;
+	u32 size;
+	u32 control;
+
+	DBG("omapfb_set_vrfb(%d, %lx, %dx%d, %d, %d)\n", ctx, paddr,
+			width, height, bytespp, yuv_mode);
+
+	/* For YUV2 and UYVY modes VRFB needs to handle pixels a bit
+	 * differently. See TRM. */
+	if (yuv_mode) {
+		bytespp *= 2;
+		width /= 2;
+	}
+
+	if (bytespp == 4)
+		pixel_size_exp = 2;
+	else if (bytespp == 2)
+		pixel_size_exp = 1;
+	else
+		BUG();
+
+	vrfb_width = ALIGN(width * bytespp, VRFB_PAGE_WIDTH) / bytespp;
+	vrfb_height = ALIGN(height, VRFB_PAGE_HEIGHT);
+
+	DBG("vrfb w %u, h %u bytespp %d\n", vrfb_width, vrfb_height, bytespp);
+
+	size  = vrfb_width << SMS_IMAGEWIDTH_OFFSET;
+	size |= vrfb_height << SMS_IMAGEHEIGHT_OFFSET;
+
+	control  = pixel_size_exp << SMS_PS_OFFSET;
+	control |= VRFB_PAGE_WIDTH_EXP  << SMS_PW_OFFSET;
+	control |= VRFB_PAGE_HEIGHT_EXP << SMS_PH_OFFSET;
+
+	vrfb_hw_context[ctx].physical_ba = paddr;
+	vrfb_hw_context[ctx].size = size;
+	vrfb_hw_context[ctx].control = control;
+
+	omap2_sms_write_rot_physical_ba(paddr, ctx);
+	omap2_sms_write_rot_size(size, ctx);
+	omap2_sms_write_rot_control(control, ctx);
+
+	DBG("vrfb offset pixels %d, %d\n",
+			vrfb_width - width, vrfb_height - height);
+
+	vrfb->xres = width;
+	vrfb->yres = height;
+	vrfb->xoffset = vrfb_width - width;
+	vrfb->yoffset = vrfb_height - height;
+	vrfb->bytespp = bytespp;
+	vrfb->yuv_mode = yuv_mode;
+}
+EXPORT_SYMBOL(omap_vrfb_setup);
+
+int omap_vrfb_map_angle(struct vrfb *vrfb, u16 height, u8 rot)
+{
+	unsigned long size = height * OMAP_VRFB_LINE_LEN * vrfb->bytespp;
+
+	vrfb->vaddr[rot] = ioremap_wc(vrfb->paddr[rot], size);
+
+	if (!vrfb->vaddr[rot]) {
+		printk(KERN_ERR "vrfb: ioremap failed\n");
+		return -ENOMEM;
+	}
+
+	DBG("ioremapped vrfb area %d of size %lu into %p\n", rot, size,
+		vrfb->vaddr[rot]);
+
+	return 0;
+}
+EXPORT_SYMBOL(omap_vrfb_map_angle);
+
+void omap_vrfb_release_ctx(struct vrfb *vrfb)
+{
+	int rot;
+	int ctx = vrfb->context;
+
+	if (ctx == 0xff)
+		return;
+
+	DBG("release ctx %d\n", ctx);
+
+	mutex_lock(&ctx_lock);
+
+	BUG_ON(!(ctx_map & (1 << ctx)));
+
+	clear_bit(ctx, &ctx_map);
+
+	for (rot = 0; rot < 4; ++rot) {
+		if (vrfb->paddr[rot]) {
+			release_mem_region(vrfb->paddr[rot], OMAP_VRFB_SIZE);
+			vrfb->paddr[rot] = 0;
+		}
+	}
+
+	vrfb->context = 0xff;
+
+	mutex_unlock(&ctx_lock);
+}
+EXPORT_SYMBOL(omap_vrfb_release_ctx);
+
+int omap_vrfb_request_ctx(struct vrfb *vrfb)
+{
+	int rot;
+	u32 paddr;
+	u8 ctx;
+	int r;
+
+	DBG("request ctx\n");
+
+	mutex_lock(&ctx_lock);
+
+	for (ctx = 0; ctx < VRFB_NUM_CTXS; ++ctx)
+		if ((ctx_map & (1 << ctx)) == 0)
+			break;
+
+	if (ctx == VRFB_NUM_CTXS) {
+		pr_err("vrfb: no free contexts\n");
+		r = -EBUSY;
+		goto out;
+	}
+
+	DBG("found free ctx %d\n", ctx);
+
+	set_bit(ctx, &ctx_map);
+
+	memset(vrfb, 0, sizeof(*vrfb));
+
+	vrfb->context = ctx;
+
+	for (rot = 0; rot < 4; ++rot) {
+		paddr = SMS_ROT_VIRT_BASE(ctx, rot);
+		if (!request_mem_region(paddr, OMAP_VRFB_SIZE, "vrfb")) {
+			pr_err("vrfb: failed to reserve VRFB "
+					"area for ctx %d, rotation %d\n",
+					ctx, rot * 90);
+			omap_vrfb_release_ctx(vrfb);
+			r = -ENOMEM;
+			goto out;
+		}
+
+		vrfb->paddr[rot] = paddr;
+
+		DBG("VRFB %d/%d: %lx\n", ctx, rot*90, vrfb->paddr[rot]);
+	}
+
+	r = 0;
+out:
+	mutex_unlock(&ctx_lock);
+	return r;
+}
+EXPORT_SYMBOL(omap_vrfb_request_ctx);
diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c
index bba5371..f860122 100644
--- a/drivers/video/sgivwfb.c
+++ b/drivers/video/sgivwfb.c
@@ -260,13 +260,13 @@
 	var->grayscale = 0;	/* No grayscale for now */
 
 	/* determine valid resolution and timing */
-	for (min_mode = 0; min_mode < DBE_VT_SIZE; min_mode++) {
+	for (min_mode = 0; min_mode < ARRAY_SIZE(dbeVTimings); min_mode++) {
 		if (dbeVTimings[min_mode].width >= var->xres &&
 		    dbeVTimings[min_mode].height >= var->yres)
 			break;
 	}
 
-	if (min_mode == DBE_VT_SIZE)
+	if (min_mode == ARRAY_SIZE(dbeVTimings))
 		return -EINVAL;	/* Resolution to high */
 
 	/* XXX FIXME - should try to pick best refresh rate */
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 3ad5157..b4b5de9 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -281,18 +281,34 @@
 				       struct list_head *pagelist)
 {
 	struct sh_mobile_lcdc_chan *ch = info->par;
-	unsigned int nr_pages;
 
 	/* enable clocks before accessing hardware */
 	sh_mobile_lcdc_clk_on(ch->lcdc);
 
-	nr_pages = sh_mobile_lcdc_sginit(info, pagelist);
-	dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
+	/*
+	 * It's possible to get here without anything on the pagelist via
+	 * sh_mobile_lcdc_deferred_io_touch() or via a userspace fsync()
+	 * invocation. In the former case, the acceleration routines are
+	 * stepped in to when using the framebuffer console causing the
+	 * workqueue to be scheduled without any dirty pages on the list.
+	 *
+	 * Despite this, a panel update is still needed given that the
+	 * acceleration routines have their own methods for writing in
+	 * that still need to be updated.
+	 *
+	 * The fsync() and empty pagelist case could be optimized for,
+	 * but we don't bother, as any application exhibiting such
+	 * behaviour is fundamentally broken anyways.
+	 */
+	if (!list_empty(pagelist)) {
+		unsigned int nr_pages = sh_mobile_lcdc_sginit(info, pagelist);
 
-	/* trigger panel update */
-	lcdc_write_chan(ch, LDSM2R, 1);
-
-	dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
+		/* trigger panel update */
+		dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
+		lcdc_write_chan(ch, LDSM2R, 1);
+		dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
+	} else
+		lcdc_write_chan(ch, LDSM2R, 1);
 }
 
 static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info)
diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c
index 6120f0c..876648e 100644
--- a/drivers/video/stifb.c
+++ b/drivers/video/stifb.c
@@ -756,9 +756,9 @@
 		if (fb->info.var.bits_per_pixel == 32)
 			controlPlaneReg = 0x04000F00;
 		else
-			controlPlaneReg = 0x00000F00;   /* 0x00000800 should be enought, but lets clear all 4 bits */
+			controlPlaneReg = 0x00000F00;   /* 0x00000800 should be enough, but lets clear all 4 bits */
 	else
-		controlPlaneReg = 0x00000F00; /* 0x00000100 should be enought, but lets clear all 4 bits */
+		controlPlaneReg = 0x00000F00; /* 0x00000100 should be enough, but lets clear all 4 bits */
 
 	switch (enable) {
 	case ENABLE:
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index ff43c88..9805483 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -52,7 +52,7 @@
  *
  * 0.1.3 (released 1999-11-02)	added Attila's panning support, code
  *				reorg, hwcursor address page size alignment
- *				(for mmaping both frame buffer and regs),
+ *				(for mmapping both frame buffer and regs),
  *				and my changes to get rid of hardcoded
  *				VGA i/o register locations (uses PCI
  *				configuration info now)
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c
index c5c32b6..67b3693 100644
--- a/drivers/video/via/dvi.c
+++ b/drivers/video/via/dvi.c
@@ -467,7 +467,7 @@
 	default:
 		viaparinfo->tmds_setting_info->dvi_panel_size =
 			VIA_RES_1024X768;
-		DEBUG_MSG(KERN_INFO "Unknow panel size max resolution = %d !\
+		DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d !\
 					 set default panel size.\n", max_h);
 		break;
 	}
@@ -534,7 +534,7 @@
 	default:
 		viaparinfo->tmds_setting_info->dvi_panel_size =
 			VIA_RES_1024X768;
-		DEBUG_MSG(KERN_INFO "Unknow panel size max resolution = %d!\
+		DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d!\
 					set default panel size.\n", HSize);
 		break;
 	}
diff --git a/drivers/video/vt8623fb.c b/drivers/video/vt8623fb.c
index 3df17dc..65ccd21 100644
--- a/drivers/video/vt8623fb.c
+++ b/drivers/video/vt8623fb.c
@@ -446,7 +446,7 @@
 
 	svga_wseq_mask(0x1E, 0xF0, 0xF0); // DI/DVP bus
 	svga_wseq_mask(0x2A, 0x0F, 0x0F); // DI/DVP bus
-	svga_wseq_mask(0x16, 0x08, 0xBF); // FIFO read treshold
+	svga_wseq_mask(0x16, 0x08, 0xBF); // FIFO read threshold
 	vga_wseq(NULL, 0x17, 0x1F);       // FIFO depth
 	vga_wseq(NULL, 0x18, 0x4E);
 	svga_wseq_mask(0x1A, 0x08, 0x08); // enable MMIO ?
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c
index 54cd916..603598f 100644
--- a/drivers/video/xen-fbfront.c
+++ b/drivers/video/xen-fbfront.c
@@ -25,7 +25,10 @@
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/mm.h>
+
 #include <asm/xen/hypervisor.h>
+
+#include <xen/xen.h>
 #include <xen/events.h>
 #include <xen/page.h>
 #include <xen/interface/io/fbif.h>
@@ -440,7 +443,7 @@
 	fb_info->fix.type = FB_TYPE_PACKED_PIXELS;
 	fb_info->fix.accel = FB_ACCEL_NONE;
 
-	fb_info->flags = FBINFO_FLAG_DEFAULT;
+	fb_info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB;
 
 	ret = fb_alloc_cmap(&fb_info->cmap, 256, 0);
 	if (ret < 0) {
diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c
index 381026c..923cc68 100644
--- a/drivers/watchdog/coh901327_wdt.c
+++ b/drivers/watchdog/coh901327_wdt.c
@@ -508,7 +508,7 @@
 	 * deactivating the watchdog before it is shut down by it.
 	 *
 	 * NOTE: on future versions of the watchdog, this restriction is
-	 * gone: the watchdog will be reloaded with a defaul value (1 min)
+	 * gone: the watchdog will be reloaded with a default value (1 min)
 	 * instead of last value, and you can conveniently set the watchdog
 	 * timeout to 10ms (value = 1) without any problems.
 	 */
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index 6a51edd..e44fbb3 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -1,5 +1,5 @@
 /*
- *	intel TCO Watchdog Driver (Used in i82801 and i63xxESB chipsets)
+ *	intel TCO Watchdog Driver
  *
  *	(c) Copyright 2006-2009 Wim Van Sebroeck <wim@iguana.be>.
  *
@@ -14,47 +14,22 @@
  *
  *	The TCO watchdog is implemented in the following I/O controller hubs:
  *	(See the intel documentation on http://developer.intel.com.)
- *	82801AA  (ICH)       : document number 290655-003, 290677-014,
- *	82801AB  (ICHO)      : document number 290655-003, 290677-014,
- *	82801BA  (ICH2)      : document number 290687-002, 298242-027,
- *	82801BAM (ICH2-M)    : document number 290687-002, 298242-027,
- *	82801CA  (ICH3-S)    : document number 290733-003, 290739-013,
- *	82801CAM (ICH3-M)    : document number 290716-001, 290718-007,
- *	82801DB  (ICH4)      : document number 290744-001, 290745-025,
- *	82801DBM (ICH4-M)    : document number 252337-001, 252663-008,
- *	82801E   (C-ICH)     : document number 273599-001, 273645-002,
- *	82801EB  (ICH5)      : document number 252516-001, 252517-028,
- *	82801ER  (ICH5R)     : document number 252516-001, 252517-028,
- *	6300ESB  (6300ESB)   : document number 300641-004, 300884-013,
- *	82801FB  (ICH6)      : document number 301473-002, 301474-026,
- *	82801FR  (ICH6R)     : document number 301473-002, 301474-026,
- *	82801FBM (ICH6-M)    : document number 301473-002, 301474-026,
- *	82801FW  (ICH6W)     : document number 301473-001, 301474-026,
- *	82801FRW (ICH6RW)    : document number 301473-001, 301474-026,
- *	631xESB  (631xESB)   : document number 313082-001, 313075-006,
- *	632xESB  (632xESB)   : document number 313082-001, 313075-006,
- *	82801GB  (ICH7)      : document number 307013-003, 307014-024,
- *	82801GR  (ICH7R)     : document number 307013-003, 307014-024,
- *	82801GDH (ICH7DH)    : document number 307013-003, 307014-024,
- *	82801GBM (ICH7-M)    : document number 307013-003, 307014-024,
- *	82801GHM (ICH7-M DH) : document number 307013-003, 307014-024,
- *	82801GU  (ICH7-U)    : document number 307013-003, 307014-024,
- *	82801HB  (ICH8)      : document number 313056-003, 313057-017,
- *	82801HR  (ICH8R)     : document number 313056-003, 313057-017,
- *	82801HBM (ICH8M)     : document number 313056-003, 313057-017,
- *	82801HH  (ICH8DH)    : document number 313056-003, 313057-017,
- *	82801HO  (ICH8DO)    : document number 313056-003, 313057-017,
- *	82801HEM (ICH8M-E)   : document number 313056-003, 313057-017,
- *	82801IB  (ICH9)      : document number 316972-004, 316973-012,
- *	82801IR  (ICH9R)     : document number 316972-004, 316973-012,
- *	82801IH  (ICH9DH)    : document number 316972-004, 316973-012,
- *	82801IO  (ICH9DO)    : document number 316972-004, 316973-012,
- *	82801IBM (ICH9M)     : document number 316972-004, 316973-012,
- *	82801IEM (ICH9M-E)   : document number 316972-004, 316973-012,
- *	82801JIB (ICH10)     : document number 319973-002, 319974-002,
- *	82801JIR (ICH10R)    : document number 319973-002, 319974-002,
- *	82801JD  (ICH10D)    : document number 319973-002, 319974-002,
- *	82801JDO (ICH10DO)   : document number 319973-002, 319974-002
+ *	document number 290655-003, 290677-014: 82801AA (ICH), 82801AB (ICHO)
+ *	document number 290687-002, 298242-027: 82801BA (ICH2)
+ *	document number 290733-003, 290739-013: 82801CA (ICH3-S)
+ *	document number 290716-001, 290718-007: 82801CAM (ICH3-M)
+ *	document number 290744-001, 290745-025: 82801DB (ICH4)
+ *	document number 252337-001, 252663-008: 82801DBM (ICH4-M)
+ *	document number 273599-001, 273645-002: 82801E (C-ICH)
+ *	document number 252516-001, 252517-028: 82801EB (ICH5), 82801ER (ICH5R)
+ *	document number 300641-004, 300884-013: 6300ESB
+ *	document number 301473-002, 301474-026: 82801F (ICH6)
+ *	document number 313082-001, 313075-006: 631xESB, 632xESB
+ *	document number 307013-003, 307014-024: 82801G (ICH7)
+ *	document number 313056-003, 313057-017: 82801H (ICH8)
+ *	document number 316972-004, 316973-012: 82801I (ICH9)
+ *	document number 319973-002, 319974-002: 82801J (ICH10)
+ *	document number 322169-001, 322170-001: 5 Series, 3400 Series (PCH)
  */
 
 /*
@@ -122,6 +97,9 @@
 	TCO_ICH10R,	/* ICH10R */
 	TCO_ICH10D,	/* ICH10D */
 	TCO_ICH10DO,	/* ICH10DO */
+	TCO_PCH,	/* PCH Desktop Full Featured */
+	TCO_PCHM,	/* PCH Mobile Full Featured */
+	TCO_PCHMSFF,	/* PCH Mobile SFF Full Featured */
 };
 
 static struct {
@@ -162,6 +140,9 @@
 	{"ICH10R", 2},
 	{"ICH10D", 2},
 	{"ICH10DO", 2},
+	{"PCH Desktop Full Featured", 2},
+	{"PCH Mobile Full Featured", 2},
+	{"PCH Mobile SFF Full Featured", 2},
 	{NULL, 0}
 };
 
@@ -230,6 +211,9 @@
 	{ ITCO_PCI_DEVICE(0x3a16,				TCO_ICH10R)},
 	{ ITCO_PCI_DEVICE(0x3a1a,				TCO_ICH10D)},
 	{ ITCO_PCI_DEVICE(0x3a14,				TCO_ICH10DO)},
+	{ ITCO_PCI_DEVICE(0x3b00,				TCO_PCH)},
+	{ ITCO_PCI_DEVICE(0x3b01,				TCO_PCHM)},
+	{ ITCO_PCI_DEVICE(0x3b0d,				TCO_PCHMSFF)},
 	{ 0, },			/* End of list */
 };
 MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl);
diff --git a/drivers/watchdog/machzwd.c b/drivers/watchdog/machzwd.c
index b6b3f59..47d7197 100644
--- a/drivers/watchdog/machzwd.c
+++ b/drivers/watchdog/machzwd.c
@@ -21,7 +21,7 @@
  *      wd#1 - 2 seconds;
  *      wd#2 - 7.2 ms;
  *  After the expiration of wd#1, it can generate a NMI, SCI, SMI, or
- *  a system RESET and it starts wd#2 that unconditionaly will RESET
+ *  a system RESET and it starts wd#2 that unconditionally will RESET
  *  the system when the counter reaches zero.
  *
  *  14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index b57ac6b..85b93e1 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -36,6 +36,7 @@
 #include <linux/clk.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
+#include <linux/cpufreq.h>
 
 #include <mach/map.h>
 
@@ -142,9 +143,14 @@
 	spin_unlock(&wdt_lock);
 }
 
+static inline int s3c2410wdt_is_running(void)
+{
+	return readl(wdt_base + S3C2410_WTCON) & S3C2410_WTCON_ENABLE;
+}
+
 static int s3c2410wdt_set_heartbeat(int timeout)
 {
-	unsigned int freq = clk_get_rate(wdt_clock);
+	unsigned long freq = clk_get_rate(wdt_clock);
 	unsigned int count;
 	unsigned int divisor = 1;
 	unsigned long wtcon;
@@ -155,7 +161,7 @@
 	freq /= 128;
 	count = timeout * freq;
 
-	DBG("%s: count=%d, timeout=%d, freq=%d\n",
+	DBG("%s: count=%d, timeout=%d, freq=%lu\n",
 	    __func__, count, timeout, freq);
 
 	/* if the count is bigger than the watchdog register,
@@ -324,6 +330,73 @@
 	s3c2410wdt_keepalive();
 	return IRQ_HANDLED;
 }
+
+
+#ifdef CONFIG_CPU_FREQ
+
+static int s3c2410wdt_cpufreq_transition(struct notifier_block *nb,
+					  unsigned long val, void *data)
+{
+	int ret;
+
+	if (!s3c2410wdt_is_running())
+		goto done;
+
+	if (val == CPUFREQ_PRECHANGE) {
+		/* To ensure that over the change we don't cause the
+		 * watchdog to trigger, we perform an keep-alive if
+		 * the watchdog is running.
+		 */
+
+		s3c2410wdt_keepalive();
+	} else if (val == CPUFREQ_POSTCHANGE) {
+		s3c2410wdt_stop();
+
+		ret = s3c2410wdt_set_heartbeat(tmr_margin);
+
+		if (ret >= 0)
+			s3c2410wdt_start();
+		else
+			goto err;
+	}
+
+done:
+	return 0;
+
+ err:
+	dev_err(wdt_dev, "cannot set new value for timeout %d\n", tmr_margin);
+	return ret;
+}
+
+static struct notifier_block s3c2410wdt_cpufreq_transition_nb = {
+	.notifier_call	= s3c2410wdt_cpufreq_transition,
+};
+
+static inline int s3c2410wdt_cpufreq_register(void)
+{
+	return cpufreq_register_notifier(&s3c2410wdt_cpufreq_transition_nb,
+					 CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+static inline void s3c2410wdt_cpufreq_deregister(void)
+{
+	cpufreq_unregister_notifier(&s3c2410wdt_cpufreq_transition_nb,
+				    CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+#else
+static inline int s3c2410wdt_cpufreq_register(void)
+{
+	return 0;
+}
+
+static inline void s3c2410wdt_cpufreq_deregister(void)
+{
+}
+#endif
+
+
+
 /* device interface */
 
 static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
@@ -387,6 +460,11 @@
 
 	clk_enable(wdt_clock);
 
+	if (s3c2410wdt_cpufreq_register() < 0) {
+		printk(KERN_ERR PFX "failed to register cpufreq\n");
+		goto err_clk;
+	}
+
 	/* see if we can actually set the requested timer margin, and if
 	 * not, try the default value */
 
@@ -407,7 +485,7 @@
 	if (ret) {
 		dev_err(dev, "cannot register miscdev on minor=%d (%d)\n",
 			WATCHDOG_MINOR, ret);
-		goto err_clk;
+		goto err_cpufreq;
 	}
 
 	if (tmr_atboot && started == 0) {
@@ -432,6 +510,9 @@
 
 	return 0;
 
+ err_cpufreq:
+	s3c2410wdt_cpufreq_deregister();
+
  err_clk:
 	clk_disable(wdt_clock);
 	clk_put(wdt_clock);
@@ -451,6 +532,8 @@
 
 static int __devexit s3c2410wdt_remove(struct platform_device *dev)
 {
+	s3c2410wdt_cpufreq_deregister();
+
 	release_resource(wdt_mem);
 	kfree(wdt_mem);
 	wdt_mem = NULL;
diff --git a/drivers/watchdog/sb_wdog.c b/drivers/watchdog/sb_wdog.c
index 9748eed..c8eadd4 100644
--- a/drivers/watchdog/sb_wdog.c
+++ b/drivers/watchdog/sb_wdog.c
@@ -1,7 +1,7 @@
 /*
  * Watchdog driver for SiByte SB1 SoCs
  *
- * Copyright (C) 2007 OnStor, Inc. * Andrew Sharp <andy.sharp@onstor.com>
+ * Copyright (C) 2007 OnStor, Inc. * Andrew Sharp <andy.sharp@lsi.com>
  *
  * This driver is intended to make the second of two hardware watchdogs
  * on the Sibyte 12XX and 11XX SoCs available to the user.  There are two
@@ -326,7 +326,7 @@
 module_init(sbwdog_init);
 module_exit(sbwdog_exit);
 
-MODULE_AUTHOR("Andrew Sharp <andy.sharp@onstor.com>");
+MODULE_AUTHOR("Andrew Sharp <andy.sharp@lsi.com>");
 MODULE_DESCRIPTION("SiByte Watchdog");
 
 module_param(timeout, ulong, 0);
diff --git a/drivers/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c
index 3bde56b..5bfb1f2 100644
--- a/drivers/watchdog/wdrtas.c
+++ b/drivers/watchdog/wdrtas.c
@@ -542,7 +542,7 @@
 /**
  * wdrtas_get_tokens - reads in RTAS tokens
  *
- * returns 0 on succes, <0 on failure
+ * returns 0 on success, <0 on failure
  *
  * wdrtas_get_tokens reads in the tokens for the RTAS calls used in
  * this watchdog driver. It tolerates, if "get-sensor-state" and
@@ -598,7 +598,7 @@
 /**
  * wdrtas_register_devs - registers the misc dev handlers
  *
- * returns 0 on succes, <0 on failure
+ * returns 0 on success, <0 on failure
  *
  * wdrtas_register_devs registers the watchdog and temperature watchdog
  * misc devs
@@ -630,7 +630,7 @@
 /**
  * wdrtas_init - init function of the watchdog driver
  *
- * returns 0 on succes, <0 on failure
+ * returns 0 on success, <0 on failure
  *
  * registers the file handlers and the reboot notifier
  */
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index d31505b..f6738d8 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -52,6 +52,8 @@
 
 #include <asm/xen/hypervisor.h>
 #include <asm/xen/hypercall.h>
+
+#include <xen/xen.h>
 #include <xen/interface/xen.h>
 #include <xen/interface/memory.h>
 #include <xen/xenbus.h>
@@ -66,8 +68,6 @@
 	/* We aim for 'current allocation' == 'target allocation'. */
 	unsigned long current_pages;
 	unsigned long target_pages;
-	/* We may hit the hard limit in Xen. If we do then we remember it. */
-	unsigned long hard_limit;
 	/*
 	 * Drivers may alter the memory reservation independently, but they
 	 * must inform the balloon driver so we avoid hitting the hard limit.
@@ -136,6 +136,8 @@
 		list_add(&page->lru, &ballooned_pages);
 		balloon_stats.balloon_low++;
 	}
+
+	totalram_pages--;
 }
 
 /* balloon_retrieve: rescue a page from the balloon, if it is not empty. */
@@ -156,6 +158,8 @@
 	else
 		balloon_stats.balloon_low--;
 
+	totalram_pages++;
+
 	return page;
 }
 
@@ -181,7 +185,7 @@
 
 static unsigned long current_target(void)
 {
-	unsigned long target = min(balloon_stats.target_pages, balloon_stats.hard_limit);
+	unsigned long target = balloon_stats.target_pages;
 
 	target = min(target,
 		     balloon_stats.current_pages +
@@ -217,23 +221,10 @@
 	set_xen_guest_handle(reservation.extent_start, frame_list);
 	reservation.nr_extents = nr_pages;
 	rc = HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation);
-	if (rc < nr_pages) {
-		if (rc > 0) {
-			int ret;
-
-			/* We hit the Xen hard limit: reprobe. */
-			reservation.nr_extents = rc;
-			ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
-						   &reservation);
-			BUG_ON(ret != rc);
-		}
-		if (rc >= 0)
-			balloon_stats.hard_limit = (balloon_stats.current_pages + rc -
-						    balloon_stats.driver_pages);
+	if (rc < 0)
 		goto out;
-	}
 
-	for (i = 0; i < nr_pages; i++) {
+	for (i = 0; i < rc; i++) {
 		page = balloon_retrieve();
 		BUG_ON(page == NULL);
 
@@ -259,13 +250,12 @@
 		__free_page(page);
 	}
 
-	balloon_stats.current_pages += nr_pages;
-	totalram_pages = balloon_stats.current_pages;
+	balloon_stats.current_pages += rc;
 
  out:
 	spin_unlock_irqrestore(&balloon_lock, flags);
 
-	return 0;
+	return rc < 0 ? rc : rc != nr_pages;
 }
 
 static int decrease_reservation(unsigned long nr_pages)
@@ -323,7 +313,6 @@
 	BUG_ON(ret != nr_pages);
 
 	balloon_stats.current_pages -= nr_pages;
-	totalram_pages = balloon_stats.current_pages;
 
 	spin_unlock_irqrestore(&balloon_lock, flags);
 
@@ -367,7 +356,6 @@
 static void balloon_set_new_target(unsigned long target)
 {
 	/* No need for lock. Not read-modify-write updates. */
-	balloon_stats.hard_limit   = ~0UL;
 	balloon_stats.target_pages = target;
 	schedule_work(&balloon_worker);
 }
@@ -422,12 +410,10 @@
 	pr_info("xen_balloon: Initialising balloon driver.\n");
 
 	balloon_stats.current_pages = min(xen_start_info->nr_pages, max_pfn);
-	totalram_pages   = balloon_stats.current_pages;
 	balloon_stats.target_pages  = balloon_stats.current_pages;
 	balloon_stats.balloon_low   = 0;
 	balloon_stats.balloon_high  = 0;
 	balloon_stats.driver_pages  = 0UL;
-	balloon_stats.hard_limit    = ~0UL;
 
 	init_timer(&balloon_timer);
 	balloon_timer.data = 0;
@@ -472,9 +458,6 @@
 BALLOON_SHOW(current_kb, "%lu\n", PAGES2KB(balloon_stats.current_pages));
 BALLOON_SHOW(low_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_low));
 BALLOON_SHOW(high_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_high));
-BALLOON_SHOW(hard_limit_kb,
-	     (balloon_stats.hard_limit!=~0UL) ? "%lu\n" : "???\n",
-	     (balloon_stats.hard_limit!=~0UL) ? PAGES2KB(balloon_stats.hard_limit) : 0);
 BALLOON_SHOW(driver_kb, "%lu\n", PAGES2KB(balloon_stats.driver_pages));
 
 static ssize_t show_target_kb(struct sys_device *dev, struct sysdev_attribute *attr,
@@ -544,7 +527,6 @@
 	&attr_current_kb.attr,
 	&attr_low_kb.attr,
 	&attr_high_kb.attr,
-	&attr_hard_limit_kb.attr,
 	&attr_driver_kb.attr,
 	NULL
 };
diff --git a/drivers/xen/cpu_hotplug.c b/drivers/xen/cpu_hotplug.c
index bdfd584..14e2d99 100644
--- a/drivers/xen/cpu_hotplug.c
+++ b/drivers/xen/cpu_hotplug.c
@@ -1,5 +1,6 @@
 #include <linux/notifier.h>
 
+#include <xen/xen.h>
 #include <xen/xenbus.h>
 
 #include <asm/xen/hypervisor.h>
@@ -86,7 +87,7 @@
 	for_each_possible_cpu(cpu) {
 		if (vcpu_online(cpu) == 0) {
 			(void)cpu_down(cpu);
-			cpu_clear(cpu, cpu_present_map);
+			set_cpu_present(cpu, false);
 		}
 	}
 
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 2f57276..ce602dd 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -474,6 +474,9 @@
 		bind_evtchn_to_cpu(evtchn, 0);
 
 		evtchn_to_irq[evtchn] = -1;
+	}
+
+	if (irq_info[irq].type != IRQT_UNBOUND) {
 		irq_info[irq] = mk_unbound_info();
 
 		dynamic_irq_cleanup(irq);
diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c
index 79bedba..f70a4f4 100644
--- a/drivers/xen/evtchn.c
+++ b/drivers/xen/evtchn.c
@@ -48,6 +48,8 @@
 #include <linux/gfp.h>
 #include <linux/mutex.h>
 #include <linux/cpu.h>
+
+#include <xen/xen.h>
 #include <xen/events.h>
 #include <xen/evtchn.h>
 #include <asm/xen/hypervisor.h>
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index 7d8f531..4c6c0bd 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -37,6 +37,7 @@
 #include <linux/vmalloc.h>
 #include <linux/uaccess.h>
 
+#include <xen/xen.h>
 #include <xen/interface/xen.h>
 #include <xen/page.h>
 #include <xen/grant_table.h>
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index 10d03d7..c499793 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -43,7 +43,6 @@
 	if (err) {
 		printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n",
 			err);
-		dpm_resume_noirq(PMSG_RESUME);
 		return err;
 	}
 
@@ -69,7 +68,6 @@
 	}
 
 	sysdev_resume();
-	dpm_resume_noirq(PMSG_RESUME);
 
 	return 0;
 }
@@ -81,6 +79,12 @@
 
 	shutting_down = SHUTDOWN_SUSPEND;
 
+	err = stop_machine_create();
+	if (err) {
+		printk(KERN_ERR "xen suspend: failed to setup stop_machine %d\n", err);
+		goto out;
+	}
+
 #ifdef CONFIG_PREEMPT
 	/* If the kernel is preemptible, we need to freeze all the processes
 	   to prevent them from being in the middle of a pagetable update
@@ -88,29 +92,32 @@
 	err = freeze_processes();
 	if (err) {
 		printk(KERN_ERR "xen suspend: freeze failed %d\n", err);
-		return;
+		goto out_destroy_sm;
 	}
 #endif
 
 	err = dpm_suspend_start(PMSG_SUSPEND);
 	if (err) {
 		printk(KERN_ERR "xen suspend: dpm_suspend_start %d\n", err);
-		goto out;
+		goto out_thaw;
+	}
+
+	err = dpm_suspend_noirq(PMSG_SUSPEND);
+	if (err) {
+		printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err);
+		goto out_resume;
 	}
 
 	printk(KERN_DEBUG "suspending xenstore...\n");
 	xs_suspend();
 
-	err = dpm_suspend_noirq(PMSG_SUSPEND);
-	if (err) {
-		printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err);
-		goto resume_devices;
-	}
-
 	err = stop_machine(xen_suspend, &cancelled, cpumask_of(0));
+
+	dpm_resume_noirq(PMSG_RESUME);
+
 	if (err) {
 		printk(KERN_ERR "failed to start xen_suspend: %d\n", err);
-		goto out;
+		cancelled = 1;
 	}
 
 	if (!cancelled) {
@@ -119,17 +126,21 @@
 	} else
 		xs_suspend_cancel();
 
-	dpm_resume_noirq(PMSG_RESUME);
-
-resume_devices:
+out_resume:
 	dpm_resume_end(PMSG_RESUME);
 
 	/* Make sure timer events get retriggered on all CPUs */
 	clock_was_set();
-out:
+
+out_thaw:
 #ifdef CONFIG_PREEMPT
 	thaw_processes();
+
+out_destroy_sm:
 #endif
+	stop_machine_destroy();
+
+out:
 	shutting_down = SHUTDOWN_INVALID;
 }
 #endif	/* CONFIG_PM_SLEEP */
diff --git a/drivers/xen/sys-hypervisor.c b/drivers/xen/sys-hypervisor.c
index 88a60e0..ae5cb05 100644
--- a/drivers/xen/sys-hypervisor.c
+++ b/drivers/xen/sys-hypervisor.c
@@ -14,6 +14,7 @@
 #include <asm/xen/hypervisor.h>
 #include <asm/xen/hypercall.h>
 
+#include <xen/xen.h>
 #include <xen/xenbus.h>
 #include <xen/interface/xen.h>
 #include <xen/interface/version.h>
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index d42e25d..2f7aaa9 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -49,6 +49,8 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/xen/hypervisor.h>
+
+#include <xen/xen.h>
 #include <xen/xenbus.h>
 #include <xen/events.h>
 #include <xen/page.h>
@@ -454,21 +456,21 @@
 {
 	return sprintf(buf, "%s\n", to_xenbus_device(dev)->nodename);
 }
-DEVICE_ATTR(nodename, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_nodename, NULL);
+static DEVICE_ATTR(nodename, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_nodename, NULL);
 
 static ssize_t xendev_show_devtype(struct device *dev,
 				   struct device_attribute *attr, char *buf)
 {
 	return sprintf(buf, "%s\n", to_xenbus_device(dev)->devicetype);
 }
-DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL);
+static DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL);
 
 static ssize_t xendev_show_modalias(struct device *dev,
 				    struct device_attribute *attr, char *buf)
 {
 	return sprintf(buf, "xen:%s\n", to_xenbus_device(dev)->devicetype);
 }
-DEVICE_ATTR(modalias, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_modalias, NULL);
+static DEVICE_ATTR(modalias, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_modalias, NULL);
 
 int xenbus_probe_node(struct xen_bus_type *bus,
 		      const char *type,
@@ -843,7 +845,7 @@
 
 MODULE_LICENSE("GPL");
 
-static int is_disconnected_device(struct device *dev, void *data)
+static int is_device_connecting(struct device *dev, void *data)
 {
 	struct xenbus_device *xendev = to_xenbus_device(dev);
 	struct device_driver *drv = data;
@@ -861,14 +863,15 @@
 		return 0;
 
 	xendrv = to_xenbus_driver(dev->driver);
-	return (xendev->state != XenbusStateConnected ||
-		(xendrv->is_ready && !xendrv->is_ready(xendev)));
+	return (xendev->state < XenbusStateConnected ||
+		(xendev->state == XenbusStateConnected &&
+		 xendrv->is_ready && !xendrv->is_ready(xendev)));
 }
 
-static int exists_disconnected_device(struct device_driver *drv)
+static int exists_connecting_device(struct device_driver *drv)
 {
 	return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
-				is_disconnected_device);
+				is_device_connecting);
 }
 
 static int print_device_status(struct device *dev, void *data)
@@ -884,10 +887,13 @@
 		/* Information only: is this too noisy? */
 		printk(KERN_INFO "XENBUS: Device with no driver: %s\n",
 		       xendev->nodename);
-	} else if (xendev->state != XenbusStateConnected) {
+	} else if (xendev->state < XenbusStateConnected) {
+		enum xenbus_state rstate = XenbusStateUnknown;
+		if (xendev->otherend)
+			rstate = xenbus_read_driver_state(xendev->otherend);
 		printk(KERN_WARNING "XENBUS: Timeout connecting "
-		       "to device: %s (state %d)\n",
-		       xendev->nodename, xendev->state);
+		       "to device: %s (local state %d, remote state %d)\n",
+		       xendev->nodename, xendev->state, rstate);
 	}
 
 	return 0;
@@ -897,7 +903,7 @@
 static int ready_to_wait_for_devices;
 
 /*
- * On a 10 second timeout, wait for all devices currently configured.  We need
+ * On a 5-minute timeout, wait for all devices currently configured.  We need
  * to do this to guarantee that the filesystems and / or network devices
  * needed for boot are available, before we can allow the boot to proceed.
  *
@@ -912,18 +918,30 @@
  */
 static void wait_for_devices(struct xenbus_driver *xendrv)
 {
-	unsigned long timeout = jiffies + 10*HZ;
+	unsigned long start = jiffies;
 	struct device_driver *drv = xendrv ? &xendrv->driver : NULL;
+	unsigned int seconds_waited = 0;
 
 	if (!ready_to_wait_for_devices || !xen_domain())
 		return;
 
-	while (exists_disconnected_device(drv)) {
-		if (time_after(jiffies, timeout))
-			break;
+	while (exists_connecting_device(drv)) {
+		if (time_after(jiffies, start + (seconds_waited+5)*HZ)) {
+			if (!seconds_waited)
+				printk(KERN_WARNING "XENBUS: Waiting for "
+				       "devices to initialise: ");
+			seconds_waited += 5;
+			printk("%us...", 300 - seconds_waited);
+			if (seconds_waited == 300)
+				break;
+		}
+
 		schedule_timeout_interruptible(HZ/10);
 	}
 
+	if (seconds_waited)
+		printk("\n");
+
 	bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
 			 print_device_status);
 }
diff --git a/drivers/xen/xenfs/super.c b/drivers/xen/xenfs/super.c
index 6559e0c..8924d93 100644
--- a/drivers/xen/xenfs/super.c
+++ b/drivers/xen/xenfs/super.c
@@ -13,6 +13,8 @@
 #include <linux/fs.h>
 #include <linux/magic.h>
 
+#include <xen/xen.h>
+
 #include "xenfs.h"
 
 #include <asm/xen/hypervisor.h>
diff --git a/fs/afs/write.c b/fs/afs/write.c
index c63a3c8..5e15a21 100644
--- a/fs/afs/write.c
+++ b/fs/afs/write.c
@@ -671,7 +671,6 @@
 	struct afs_vnode *vnode = AFS_FS_I(dentry->d_inode);
 	ssize_t result;
 	size_t count = iov_length(iov, nr_segs);
-	int ret;
 
 	_enter("{%x.%u},{%zu},%lu,",
 	       vnode->fid.vid, vnode->fid.vnode, count, nr_segs);
@@ -691,13 +690,6 @@
 		return result;
 	}
 
-	/* return error values for O_SYNC and IS_SYNC() */
-	if (IS_SYNC(&vnode->vfs_inode) || iocb->ki_filp->f_flags & O_SYNC) {
-		ret = afs_fsync(iocb->ki_filp, dentry, 1);
-		if (ret < 0)
-			result = ret;
-	}
-
 	_leave(" = %zd", result);
 	return result;
 }
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index b9b3bb5..d15ea17 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -767,7 +767,7 @@
 	
 	current->mm->start_stack = bprm->p;
 
-	/* Now we do a little grungy work by mmaping the ELF image into
+	/* Now we do a little grungy work by mmapping the ELF image into
 	   the correct location in memory. */
 	for(i = 0, elf_ppnt = elf_phdata;
 	    i < loc->elf_ex.e_phnum; i++, elf_ppnt++) {
diff --git a/fs/bio.c b/fs/bio.c
index e23a63f..76e6713a 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -272,7 +272,7 @@
  *   for a &struct bio to become free. If a %NULL @bs is passed in, we will
  *   fall back to just using @kmalloc to allocate the required memory.
  *
- *   Note that the caller must set ->bi_destructor on succesful return
+ *   Note that the caller must set ->bi_destructor on successful return
  *   of a bio, to do the appropriate freeing of the bio once the reference
  *   count drops to zero.
  **/
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index ccbdcb5..46bea0f 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -256,7 +256,7 @@
  * Insert @em into @tree or perform a simple forward/backward merge with
  * existing mappings.  The extent_map struct passed in will be inserted
  * into the tree directly, with an additional reference taken, or a
- * reference dropped if the merge attempt was sucessfull.
+ * reference dropped if the merge attempt was successfull.
  */
 int add_extent_mapping(struct extent_map_tree *tree,
 		       struct extent_map *em)
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 06550af..77f7593 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -909,7 +909,7 @@
 	unsigned long last_index;
 	int will_write;
 
-	will_write = ((file->f_flags & O_SYNC) || IS_SYNC(inode) ||
+	will_write = ((file->f_flags & O_DSYNC) || IS_SYNC(inode) ||
 		      (file->f_flags & O_DIRECT));
 
 	nrptrs = min((count + PAGE_CACHE_SIZE - 1) / PAGE_CACHE_SIZE,
@@ -1076,7 +1076,7 @@
 		if (err)
 			num_written = err;
 
-		if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) {
+		if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) {
 			trans = btrfs_start_transaction(root, 1);
 			ret = btrfs_log_dentry_safe(trans, root,
 						    file->f_dentry);
diff --git a/fs/cifs/README b/fs/cifs/README
index 79c1a93..a727b7c 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -423,7 +423,7 @@
 		source name to use to represent the client netbios machine 
 		name when doing the RFC1001 netbios session initialize.
   direct        Do not do inode data caching on files opened on this mount.
-		This precludes mmaping files on this mount. In some cases
+		This precludes mmapping files on this mount. In some cases
 		with fast networks and little or no caching benefits on the
 		client (e.g. when the application is doing large sequential
 		reads bigger than page size without rereading the same data) 
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 5d0fde1..4b35f7e 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -39,7 +39,7 @@
 
 /*
  * MAX_REQ is the maximum number of requests that WE will send
- * on one socket concurently. It also matches the most common
+ * on one socket concurrently. It also matches the most common
  * value of max multiplex returned by servers.  We may
  * eventually want to use the negotiated value (in case
  * future servers can handle more) when we are more confident that
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index 2d07f89..3877737 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -1227,7 +1227,7 @@
 /* empty wct response to setattr */
 
 /*******************************************************/
-/* NT Transact structure defintions follow             */
+/* NT Transact structure definitions follow            */
 /* Currently only ioctl, acl (get security descriptor) */
 /* and notify are implemented                          */
 /*******************************************************/
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 1f42f77..6ccf726 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -214,7 +214,8 @@
 		posix_flags |= SMB_O_EXCL;
 	if (oflags & O_TRUNC)
 		posix_flags |= SMB_O_TRUNC;
-	if (oflags & O_SYNC)
+	/* be safe and imply O_SYNC for O_DSYNC */
+	if (oflags & O_DSYNC)
 		posix_flags |= SMB_O_SYNC;
 	if (oflags & O_DIRECTORY)
 		posix_flags |= SMB_O_DIRECTORY;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 429337e..057e1da 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -76,8 +76,10 @@
 	   reopening a file.  They had their effect on the original open */
 	if (flags & O_APPEND)
 		posix_flags |= (fmode_t)O_APPEND;
-	if (flags & O_SYNC)
-		posix_flags |= (fmode_t)O_SYNC;
+	if (flags & O_DSYNC)
+		posix_flags |= (fmode_t)O_DSYNC;
+	if (flags & __O_SYNC)
+		posix_flags |= (fmode_t)__O_SYNC;
 	if (flags & O_DIRECTORY)
 		posix_flags |= (fmode_t)O_DIRECTORY;
 	if (flags & O_NOFOLLOW)
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index cababd8..cf18ee7 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -914,8 +914,8 @@
 /*
  * If dentry->d_inode is null (usually meaning the cached dentry
  * is a negative dentry) then we would attempt a standard SMB delete, but
- * if that fails we can not attempt the fall back mechanisms on EACESS
- * but will return the EACESS to the caller.  Note that the VFS does not call
+ * if that fails we can not attempt the fall back mechanisms on EACCESS
+ * but will return the EACCESS to the caller. Note that the VFS does not call
  * unlink on negative dentries currently.
  */
 int cifs_unlink(struct inode *dir, struct dentry *dentry)
diff --git a/fs/cifs/smbdes.c b/fs/cifs/smbdes.c
index 224a1f4..b6b6dcb 100644
--- a/fs/cifs/smbdes.c
+++ b/fs/cifs/smbdes.c
@@ -371,7 +371,7 @@
 	smbhash(p24 + 16, c8, p21 + 14, 1);
 }
 
-#if 0 /* currently unsued */
+#if 0 /* currently unused */
 static void
 D_P16(unsigned char *p14, unsigned char *in, unsigned char *out)
 {
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 229e722..2346895 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -1920,7 +1920,7 @@
 #endif
 #ifdef TIOCSTART
 /*
- * For these two we have defintions in ioctls.h and/or termios.h on
+ * For these two we have definitions in ioctls.h and/or termios.h on
  * some architectures but no actual implemention.  Some applications
  * like bash call them if they are defined in the headers, so we provide
  * entries here to avoid syslog message spew.
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index d22438e..b486169 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -32,7 +32,9 @@
 static int debugfs_mount_count;
 static bool debugfs_registered;
 
-static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t dev)
+static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t dev,
+				       void *data, const struct file_operations *fops)
+
 {
 	struct inode *inode = new_inode(sb);
 
@@ -44,14 +46,18 @@
 			init_special_inode(inode, mode, dev);
 			break;
 		case S_IFREG:
-			inode->i_fop = &debugfs_file_operations;
+			inode->i_fop = fops ? fops : &debugfs_file_operations;
+			inode->i_private = data;
 			break;
 		case S_IFLNK:
 			inode->i_op = &debugfs_link_operations;
+			inode->i_fop = fops;
+			inode->i_private = data;
 			break;
 		case S_IFDIR:
 			inode->i_op = &simple_dir_inode_operations;
-			inode->i_fop = &simple_dir_operations;
+			inode->i_fop = fops ? fops : &simple_dir_operations;
+			inode->i_private = data;
 
 			/* directory inodes start off with i_nlink == 2
 			 * (for "." entry) */
@@ -64,7 +70,8 @@
 
 /* SMP-safe */
 static int debugfs_mknod(struct inode *dir, struct dentry *dentry,
-			 int mode, dev_t dev)
+			 int mode, dev_t dev, void *data,
+			 const struct file_operations *fops)
 {
 	struct inode *inode;
 	int error = -EPERM;
@@ -72,7 +79,7 @@
 	if (dentry->d_inode)
 		return -EEXIST;
 
-	inode = debugfs_get_inode(dir->i_sb, mode, dev);
+	inode = debugfs_get_inode(dir->i_sb, mode, dev, data, fops);
 	if (inode) {
 		d_instantiate(dentry, inode);
 		dget(dentry);
@@ -81,12 +88,13 @@
 	return error;
 }
 
-static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode,
+			 void *data, const struct file_operations *fops)
 {
 	int res;
 
 	mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
-	res = debugfs_mknod(dir, dentry, mode, 0);
+	res = debugfs_mknod(dir, dentry, mode, 0, data, fops);
 	if (!res) {
 		inc_nlink(dir);
 		fsnotify_mkdir(dir, dentry);
@@ -94,18 +102,20 @@
 	return res;
 }
 
-static int debugfs_link(struct inode *dir, struct dentry *dentry, int mode)
+static int debugfs_link(struct inode *dir, struct dentry *dentry, int mode,
+			void *data, const struct file_operations *fops)
 {
 	mode = (mode & S_IALLUGO) | S_IFLNK;
-	return debugfs_mknod(dir, dentry, mode, 0);
+	return debugfs_mknod(dir, dentry, mode, 0, data, fops);
 }
 
-static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode)
+static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode,
+			  void *data, const struct file_operations *fops)
 {
 	int res;
 
 	mode = (mode & S_IALLUGO) | S_IFREG;
-	res = debugfs_mknod(dir, dentry, mode, 0);
+	res = debugfs_mknod(dir, dentry, mode, 0, data, fops);
 	if (!res)
 		fsnotify_create(dir, dentry);
 	return res;
@@ -139,7 +149,9 @@
 
 static int debugfs_create_by_name(const char *name, mode_t mode,
 				  struct dentry *parent,
-				  struct dentry **dentry)
+				  struct dentry **dentry,
+				  void *data,
+				  const struct file_operations *fops)
 {
 	int error = 0;
 
@@ -164,13 +176,16 @@
 	if (!IS_ERR(*dentry)) {
 		switch (mode & S_IFMT) {
 		case S_IFDIR:
-			error = debugfs_mkdir(parent->d_inode, *dentry, mode);
+			error = debugfs_mkdir(parent->d_inode, *dentry, mode,
+					      data, fops);
 			break;
 		case S_IFLNK:
-			error = debugfs_link(parent->d_inode, *dentry, mode);
+			error = debugfs_link(parent->d_inode, *dentry, mode,
+					     data, fops);
 			break;
 		default:
-			error = debugfs_create(parent->d_inode, *dentry, mode);
+			error = debugfs_create(parent->d_inode, *dentry, mode,
+					       data, fops);
 			break;
 		}
 		dput(*dentry);
@@ -184,7 +199,7 @@
 /**
  * debugfs_create_file - create a file in the debugfs filesystem
  * @name: a pointer to a string containing the name of the file to create.
- * @mode: the permission that the file should have
+ * @mode: the permission that the file should have.
  * @parent: a pointer to the parent dentry for this file.  This should be a
  *          directory dentry if set.  If this paramater is NULL, then the
  *          file will be created in the root of the debugfs filesystem.
@@ -195,8 +210,8 @@
  *        this file.
  *
  * This is the basic "create a file" function for debugfs.  It allows for a
- * wide range of flexibility in createing a file, or a directory (if you
- * want to create a directory, the debugfs_create_dir() function is
+ * wide range of flexibility in creating a file, or a directory (if you want
+ * to create a directory, the debugfs_create_dir() function is
  * recommended to be used instead.)
  *
  * This function will return a pointer to a dentry if it succeeds.  This
@@ -221,19 +236,13 @@
 	if (error)
 		goto exit;
 
-	error = debugfs_create_by_name(name, mode, parent, &dentry);
+	error = debugfs_create_by_name(name, mode, parent, &dentry,
+				       data, fops);
 	if (error) {
 		dentry = NULL;
 		simple_release_fs(&debugfs_mount, &debugfs_mount_count);
 		goto exit;
 	}
-
-	if (dentry->d_inode) {
-		if (data)
-			dentry->d_inode->i_private = data;
-		if (fops)
-			dentry->d_inode->i_fop = fops;
-	}
 exit:
 	return dentry;
 }
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index d5f8c96..8882ecc 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -517,11 +517,23 @@
 
 struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number)
 {
+	struct dentry *dentry;
+	struct tty_struct *tty;
+
 	BUG_ON(pts_inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR));
 
+	/* Ensure dentry has not been deleted by devpts_pty_kill() */
+	dentry = d_find_alias(pts_inode);
+	if (!dentry)
+		return NULL;
+
+	tty = NULL;
 	if (pts_inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC)
-		return (struct tty_struct *)pts_inode->i_private;
-	return NULL;
+		tty = (struct tty_struct *)pts_inode->i_private;
+
+	dput(dentry);
+
+	return tty;
 }
 
 void devpts_pty_kill(struct tty_struct *tty)
diff --git a/fs/dlm/config.c b/fs/dlm/config.c
index fd9859f..0df2438 100644
--- a/fs/dlm/config.c
+++ b/fs/dlm/config.c
@@ -410,10 +410,10 @@
 	struct dlm_comms *cms = NULL;
 	void *gps = NULL;
 
-	cl = kzalloc(sizeof(struct dlm_cluster), GFP_KERNEL);
-	gps = kcalloc(3, sizeof(struct config_group *), GFP_KERNEL);
-	sps = kzalloc(sizeof(struct dlm_spaces), GFP_KERNEL);
-	cms = kzalloc(sizeof(struct dlm_comms), GFP_KERNEL);
+	cl = kzalloc(sizeof(struct dlm_cluster), GFP_NOFS);
+	gps = kcalloc(3, sizeof(struct config_group *), GFP_NOFS);
+	sps = kzalloc(sizeof(struct dlm_spaces), GFP_NOFS);
+	cms = kzalloc(sizeof(struct dlm_comms), GFP_NOFS);
 
 	if (!cl || !gps || !sps || !cms)
 		goto fail;
@@ -482,9 +482,9 @@
 	struct dlm_nodes *nds = NULL;
 	void *gps = NULL;
 
-	sp = kzalloc(sizeof(struct dlm_space), GFP_KERNEL);
-	gps = kcalloc(2, sizeof(struct config_group *), GFP_KERNEL);
-	nds = kzalloc(sizeof(struct dlm_nodes), GFP_KERNEL);
+	sp = kzalloc(sizeof(struct dlm_space), GFP_NOFS);
+	gps = kcalloc(2, sizeof(struct config_group *), GFP_NOFS);
+	nds = kzalloc(sizeof(struct dlm_nodes), GFP_NOFS);
 
 	if (!sp || !gps || !nds)
 		goto fail;
@@ -536,7 +536,7 @@
 {
 	struct dlm_comm *cm;
 
-	cm = kzalloc(sizeof(struct dlm_comm), GFP_KERNEL);
+	cm = kzalloc(sizeof(struct dlm_comm), GFP_NOFS);
 	if (!cm)
 		return ERR_PTR(-ENOMEM);
 
@@ -569,7 +569,7 @@
 	struct dlm_space *sp = config_item_to_space(g->cg_item.ci_parent);
 	struct dlm_node *nd;
 
-	nd = kzalloc(sizeof(struct dlm_node), GFP_KERNEL);
+	nd = kzalloc(sizeof(struct dlm_node), GFP_NOFS);
 	if (!nd)
 		return ERR_PTR(-ENOMEM);
 
@@ -705,7 +705,7 @@
 	if (cm->addr_count >= DLM_MAX_ADDR_COUNT)
 		return -ENOSPC;
 
-	addr = kzalloc(sizeof(*addr), GFP_KERNEL);
+	addr = kzalloc(sizeof(*addr), GFP_NOFS);
 	if (!addr)
 		return -ENOMEM;
 
@@ -868,7 +868,7 @@
 
 	ids_count = sp->members_count;
 
-	ids = kcalloc(ids_count, sizeof(int), GFP_KERNEL);
+	ids = kcalloc(ids_count, sizeof(int), GFP_NOFS);
 	if (!ids) {
 		rv = -ENOMEM;
 		goto out;
@@ -886,7 +886,7 @@
 	if (!new_count)
 		goto out_ids;
 
-	new = kcalloc(new_count, sizeof(int), GFP_KERNEL);
+	new = kcalloc(new_count, sizeof(int), GFP_NOFS);
 	if (!new) {
 		kfree(ids);
 		rv = -ENOMEM;
diff --git a/fs/dlm/debug_fs.c b/fs/dlm/debug_fs.c
index 1c8bb8c..375a235 100644
--- a/fs/dlm/debug_fs.c
+++ b/fs/dlm/debug_fs.c
@@ -404,7 +404,7 @@
 	if (bucket >= ls->ls_rsbtbl_size)
 		return NULL;
 
-	ri = kzalloc(sizeof(struct rsbtbl_iter), GFP_KERNEL);
+	ri = kzalloc(sizeof(struct rsbtbl_iter), GFP_NOFS);
 	if (!ri)
 		return NULL;
 	if (n == 0)
diff --git a/fs/dlm/dir.c b/fs/dlm/dir.c
index c4dfa1d..7b84c1d 100644
--- a/fs/dlm/dir.c
+++ b/fs/dlm/dir.c
@@ -49,8 +49,7 @@
 	spin_unlock(&ls->ls_recover_list_lock);
 
 	if (!found)
-		de = kzalloc(sizeof(struct dlm_direntry) + len,
-			     ls->ls_allocation);
+		de = kzalloc(sizeof(struct dlm_direntry) + len, GFP_NOFS);
 	return de;
 }
 
@@ -212,7 +211,7 @@
 
 	dlm_dir_clear(ls);
 
-	last_name = kmalloc(DLM_RESNAME_MAXLEN, ls->ls_allocation);
+	last_name = kmalloc(DLM_RESNAME_MAXLEN, GFP_NOFS);
 	if (!last_name)
 		goto out;
 
@@ -323,7 +322,7 @@
 	if (namelen > DLM_RESNAME_MAXLEN)
 		return -EINVAL;
 
-	de = kzalloc(sizeof(struct dlm_direntry) + namelen, ls->ls_allocation);
+	de = kzalloc(sizeof(struct dlm_direntry) + namelen, GFP_NOFS);
 	if (!de)
 		return -ENOMEM;
 
diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h
index d01ca0a..826d3dc 100644
--- a/fs/dlm/dlm_internal.h
+++ b/fs/dlm/dlm_internal.h
@@ -473,7 +473,6 @@
 	int			ls_low_nodeid;
 	int			ls_total_weight;
 	int			*ls_node_array;
-	gfp_t			ls_allocation;
 
 	struct dlm_rsb		ls_stub_rsb;	/* for returning errors */
 	struct dlm_lkb		ls_stub_lkb;	/* for returning errors */
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index eb507c4..9c0c1db 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -2689,7 +2689,7 @@
 	   pass into lowcomms_commit and a message buffer (mb) that we
 	   write our data into */
 
-	mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, ls->ls_allocation, &mb);
+	mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, GFP_NOFS, &mb);
 	if (!mh)
 		return -ENOBUFS;
 
@@ -4512,7 +4512,7 @@
 	}
 
 	if (flags & DLM_LKF_VALBLK) {
-		ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_KERNEL);
+		ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_NOFS);
 		if (!ua->lksb.sb_lvbptr) {
 			kfree(ua);
 			__put_lkb(ls, lkb);
@@ -4582,7 +4582,7 @@
 	ua = lkb->lkb_ua;
 
 	if (flags & DLM_LKF_VALBLK && !ua->lksb.sb_lvbptr) {
-		ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_KERNEL);
+		ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_NOFS);
 		if (!ua->lksb.sb_lvbptr) {
 			error = -ENOMEM;
 			goto out_put;
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c
index d489fcc..c010ecf 100644
--- a/fs/dlm/lockspace.c
+++ b/fs/dlm/lockspace.c
@@ -430,7 +430,7 @@
 
 	error = -ENOMEM;
 
-	ls = kzalloc(sizeof(struct dlm_ls) + namelen, GFP_KERNEL);
+	ls = kzalloc(sizeof(struct dlm_ls) + namelen, GFP_NOFS);
 	if (!ls)
 		goto out;
 	memcpy(ls->ls_name, name, namelen);
@@ -443,11 +443,6 @@
 	if (flags & DLM_LSFL_TIMEWARN)
 		set_bit(LSFL_TIMEWARN, &ls->ls_flags);
 
-	if (flags & DLM_LSFL_FS)
-		ls->ls_allocation = GFP_NOFS;
-	else
-		ls->ls_allocation = GFP_KERNEL;
-
 	/* ls_exflags are forced to match among nodes, and we don't
 	   need to require all nodes to have some flags set */
 	ls->ls_exflags = (flags & ~(DLM_LSFL_TIMEWARN | DLM_LSFL_FS |
@@ -456,7 +451,7 @@
 	size = dlm_config.ci_rsbtbl_size;
 	ls->ls_rsbtbl_size = size;
 
-	ls->ls_rsbtbl = kmalloc(sizeof(struct dlm_rsbtable) * size, GFP_KERNEL);
+	ls->ls_rsbtbl = kmalloc(sizeof(struct dlm_rsbtable) * size, GFP_NOFS);
 	if (!ls->ls_rsbtbl)
 		goto out_lsfree;
 	for (i = 0; i < size; i++) {
@@ -468,7 +463,7 @@
 	size = dlm_config.ci_lkbtbl_size;
 	ls->ls_lkbtbl_size = size;
 
-	ls->ls_lkbtbl = kmalloc(sizeof(struct dlm_lkbtable) * size, GFP_KERNEL);
+	ls->ls_lkbtbl = kmalloc(sizeof(struct dlm_lkbtable) * size, GFP_NOFS);
 	if (!ls->ls_lkbtbl)
 		goto out_rsbfree;
 	for (i = 0; i < size; i++) {
@@ -480,7 +475,7 @@
 	size = dlm_config.ci_dirtbl_size;
 	ls->ls_dirtbl_size = size;
 
-	ls->ls_dirtbl = kmalloc(sizeof(struct dlm_dirtable) * size, GFP_KERNEL);
+	ls->ls_dirtbl = kmalloc(sizeof(struct dlm_dirtable) * size, GFP_NOFS);
 	if (!ls->ls_dirtbl)
 		goto out_lkbfree;
 	for (i = 0; i < size; i++) {
@@ -527,7 +522,7 @@
 	mutex_init(&ls->ls_requestqueue_mutex);
 	mutex_init(&ls->ls_clear_proc_locks);
 
-	ls->ls_recover_buf = kmalloc(dlm_config.ci_buffer_size, GFP_KERNEL);
+	ls->ls_recover_buf = kmalloc(dlm_config.ci_buffer_size, GFP_NOFS);
 	if (!ls->ls_recover_buf)
 		goto out_dirfree;
 
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
index 70736eb..52cab16 100644
--- a/fs/dlm/lowcomms.c
+++ b/fs/dlm/lowcomms.c
@@ -1060,7 +1060,7 @@
 		if (dlm_our_addr(&sas, i))
 			break;
 
-		addr = kmalloc(sizeof(*addr), GFP_KERNEL);
+		addr = kmalloc(sizeof(*addr), GFP_NOFS);
 		if (!addr)
 			break;
 		memcpy(addr, &sas, sizeof(*addr));
@@ -1099,7 +1099,7 @@
 	struct sockaddr_storage localaddr;
 	struct sctp_event_subscribe subscribe;
 	int result = -EINVAL, num = 1, i, addr_len;
-	struct connection *con = nodeid2con(0, GFP_KERNEL);
+	struct connection *con = nodeid2con(0, GFP_NOFS);
 	int bufsize = NEEDED_RMEM;
 
 	if (!con)
@@ -1171,7 +1171,7 @@
 static int tcp_listen_for_all(void)
 {
 	struct socket *sock = NULL;
-	struct connection *con = nodeid2con(0, GFP_KERNEL);
+	struct connection *con = nodeid2con(0, GFP_NOFS);
 	int result = -EINVAL;
 
 	if (!con)
diff --git a/fs/dlm/member.c b/fs/dlm/member.c
index b128775..84f70bf 100644
--- a/fs/dlm/member.c
+++ b/fs/dlm/member.c
@@ -48,7 +48,7 @@
 	struct dlm_member *memb;
 	int w, error;
 
-	memb = kzalloc(sizeof(struct dlm_member), ls->ls_allocation);
+	memb = kzalloc(sizeof(struct dlm_member), GFP_NOFS);
 	if (!memb)
 		return -ENOMEM;
 
@@ -143,7 +143,7 @@
 
 	ls->ls_total_weight = total;
 
-	array = kmalloc(sizeof(int) * total, ls->ls_allocation);
+	array = kmalloc(sizeof(int) * total, GFP_NOFS);
 	if (!array)
 		return;
 
@@ -226,7 +226,7 @@
 			continue;
 		log_debug(ls, "new nodeid %d is a re-added member", rv->new[i]);
 
-		memb = kzalloc(sizeof(struct dlm_member), ls->ls_allocation);
+		memb = kzalloc(sizeof(struct dlm_member), GFP_NOFS);
 		if (!memb)
 			return -ENOMEM;
 		memb->nodeid = rv->new[i];
@@ -341,7 +341,7 @@
 	int *ids = NULL, *new = NULL;
 	int error, ids_count = 0, new_count = 0;
 
-	rv = kzalloc(sizeof(struct dlm_recover), ls->ls_allocation);
+	rv = kzalloc(sizeof(struct dlm_recover), GFP_NOFS);
 	if (!rv)
 		return -ENOMEM;
 
diff --git a/fs/dlm/memory.c b/fs/dlm/memory.c
index c1775b8..8e0d00d 100644
--- a/fs/dlm/memory.c
+++ b/fs/dlm/memory.c
@@ -39,7 +39,7 @@
 {
 	char *p;
 
-	p = kzalloc(ls->ls_lvblen, ls->ls_allocation);
+	p = kzalloc(ls->ls_lvblen, GFP_NOFS);
 	return p;
 }
 
@@ -57,7 +57,7 @@
 
 	DLM_ASSERT(namelen <= DLM_RESNAME_MAXLEN,);
 
-	r = kzalloc(sizeof(*r) + namelen, ls->ls_allocation);
+	r = kzalloc(sizeof(*r) + namelen, GFP_NOFS);
 	return r;
 }
 
@@ -72,7 +72,7 @@
 {
 	struct dlm_lkb *lkb;
 
-	lkb = kmem_cache_zalloc(lkb_cache, ls->ls_allocation);
+	lkb = kmem_cache_zalloc(lkb_cache, GFP_NOFS);
 	return lkb;
 }
 
diff --git a/fs/dlm/netlink.c b/fs/dlm/netlink.c
index 55ea369..052095c 100644
--- a/fs/dlm/netlink.c
+++ b/fs/dlm/netlink.c
@@ -26,7 +26,7 @@
 	struct sk_buff *skb;
 	void *data;
 
-	skb = genlmsg_new(size, GFP_KERNEL);
+	skb = genlmsg_new(size, GFP_NOFS);
 	if (!skb)
 		return -ENOMEM;
 
diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c
index 16f682e..b5f89ae 100644
--- a/fs/dlm/plock.c
+++ b/fs/dlm/plock.c
@@ -82,7 +82,7 @@
 	if (!ls)
 		return -EINVAL;
 
-	xop = kzalloc(sizeof(*xop), GFP_KERNEL);
+	xop = kzalloc(sizeof(*xop), GFP_NOFS);
 	if (!xop) {
 		rv = -ENOMEM;
 		goto out;
@@ -143,7 +143,7 @@
 }
 EXPORT_SYMBOL_GPL(dlm_posix_lock);
 
-/* Returns failure iff a succesful lock operation should be canceled */
+/* Returns failure iff a successful lock operation should be canceled */
 static int dlm_plock_callback(struct plock_op *op)
 {
 	struct file *file;
@@ -211,7 +211,7 @@
 	if (!ls)
 		return -EINVAL;
 
-	op = kzalloc(sizeof(*op), GFP_KERNEL);
+	op = kzalloc(sizeof(*op), GFP_NOFS);
 	if (!op) {
 		rv = -ENOMEM;
 		goto out;
@@ -266,7 +266,7 @@
 	if (!ls)
 		return -EINVAL;
 
-	op = kzalloc(sizeof(*op), GFP_KERNEL);
+	op = kzalloc(sizeof(*op), GFP_NOFS);
 	if (!op) {
 		rv = -ENOMEM;
 		goto out;
diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c
index 67522c2..3c83a49 100644
--- a/fs/dlm/rcom.c
+++ b/fs/dlm/rcom.c
@@ -38,7 +38,7 @@
 	char *mb;
 	int mb_len = sizeof(struct dlm_rcom) + len;
 
-	mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, ls->ls_allocation, &mb);
+	mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, GFP_NOFS, &mb);
 	if (!mh) {
 		log_print("create_rcom to %d type %d len %d ENOBUFS",
 			  to_nodeid, type, len);
diff --git a/fs/dlm/requestqueue.c b/fs/dlm/requestqueue.c
index 7a2307c..a44fa22 100644
--- a/fs/dlm/requestqueue.c
+++ b/fs/dlm/requestqueue.c
@@ -35,7 +35,7 @@
 	struct rq_entry *e;
 	int length = ms->m_header.h_length - sizeof(struct dlm_message);
 
-	e = kmalloc(sizeof(struct rq_entry) + length, ls->ls_allocation);
+	e = kmalloc(sizeof(struct rq_entry) + length, GFP_NOFS);
 	if (!e) {
 		log_print("dlm_add_requestqueue: out of memory len %d", length);
 		return;
diff --git a/fs/dlm/user.c b/fs/dlm/user.c
index ebce994..e73a4bb 100644
--- a/fs/dlm/user.c
+++ b/fs/dlm/user.c
@@ -267,7 +267,7 @@
 		goto out;
 	}
 
-	ua = kzalloc(sizeof(struct dlm_user_args), GFP_KERNEL);
+	ua = kzalloc(sizeof(struct dlm_user_args), GFP_NOFS);
 	if (!ua)
 		goto out;
 	ua->proc = proc;
@@ -307,7 +307,7 @@
 	if (!ls)
 		return -ENOENT;
 
-	ua = kzalloc(sizeof(struct dlm_user_args), GFP_KERNEL);
+	ua = kzalloc(sizeof(struct dlm_user_args), GFP_NOFS);
 	if (!ua)
 		goto out;
 	ua->proc = proc;
@@ -352,7 +352,7 @@
 
 	error = -ENOMEM;
 	len = strlen(name) + strlen(name_prefix) + 2;
-	ls->ls_device.name = kzalloc(len, GFP_KERNEL);
+	ls->ls_device.name = kzalloc(len, GFP_NOFS);
 	if (!ls->ls_device.name)
 		goto fail;
 
@@ -520,7 +520,7 @@
 #endif
 		return -EINVAL;
 
-	kbuf = kzalloc(count + 1, GFP_KERNEL);
+	kbuf = kzalloc(count + 1, GFP_NOFS);
 	if (!kbuf)
 		return -ENOMEM;
 
@@ -546,7 +546,7 @@
 
 		/* add 1 after namelen so that the name string is terminated */
 		kbuf = kzalloc(sizeof(struct dlm_write_request) + namelen + 1,
-			       GFP_KERNEL);
+			       GFP_NOFS);
 		if (!kbuf) {
 			kfree(k32buf);
 			return -ENOMEM;
@@ -648,7 +648,7 @@
 	if (!ls)
 		return -ENOENT;
 
-	proc = kzalloc(sizeof(struct dlm_user_proc), GFP_KERNEL);
+	proc = kzalloc(sizeof(struct dlm_user_proc), GFP_NOFS);
 	if (!proc) {
 		dlm_put_lockspace(ls);
 		return -ENOMEM;
diff --git a/fs/exofs/Kbuild b/fs/exofs/Kbuild
index cc2d22d..2d0f757 100644
--- a/fs/exofs/Kbuild
+++ b/fs/exofs/Kbuild
@@ -12,5 +12,5 @@
 # Kbuild - Gets included from the Kernels Makefile and build system
 #
 
-exofs-y := osd.o inode.o file.o symlink.o namei.o dir.o super.o
+exofs-y := ios.o inode.o file.o symlink.o namei.o dir.o super.o
 obj-$(CONFIG_EXOFS_FS) += exofs.o
diff --git a/fs/exofs/common.h b/fs/exofs/common.h
index c6718e4..b1b178e 100644
--- a/fs/exofs/common.h
+++ b/fs/exofs/common.h
@@ -49,6 +49,7 @@
 #define EXOFS_MIN_PID   0x10000	/* Smallest partition ID */
 #define EXOFS_OBJ_OFF	0x10000	/* offset for objects */
 #define EXOFS_SUPER_ID	0x10000	/* object ID for on-disk superblock */
+#define EXOFS_DEVTABLE_ID 0x10001 /* object ID for on-disk device table */
 #define EXOFS_ROOT_ID	0x10002	/* object ID for root directory */
 
 /* exofs Application specific page/attribute */
@@ -78,17 +79,67 @@
 #define EXOFS_SUPER_MAGIC	0x5DF5
 
 /*
- * The file system control block - stored in an object's data (mainly, the one
- * with ID EXOFS_SUPER_ID).  This is where the in-memory superblock is stored
- * on disk.  Right now it just has a magic value, which is basically a sanity
- * check on our ability to communicate with the object store.
+ * The file system control block - stored in object EXOFS_SUPER_ID's data.
+ * This is where the in-memory superblock is stored on disk.
  */
+enum {EXOFS_FSCB_VER = 1, EXOFS_DT_VER = 1};
 struct exofs_fscb {
 	__le64  s_nextid;	/* Highest object ID used */
-	__le32  s_numfiles;	/* Number of files on fs */
+	__le64  s_numfiles;	/* Number of files on fs */
+	__le32	s_version;	/* == EXOFS_FSCB_VER */
 	__le16  s_magic;	/* Magic signature */
 	__le16  s_newfs;	/* Non-zero if this is a new fs */
-};
+
+	/* From here on it's a static part, only written by mkexofs */
+	__le64	s_dev_table_oid;   /* Resurved, not used */
+	__le64	s_dev_table_count; /* == 0 means no dev_table */
+} __packed;
+
+/*
+ * Describes the raid used in the FS. It is part of the device table.
+ * This here is taken from the pNFS-objects definition. In exofs we
+ * use one raid policy through-out the filesystem. (NOTE: the funny
+ * alignment at begining. We take care of it at exofs_device_table.
+ */
+struct exofs_dt_data_map {
+	__le32	cb_num_comps;
+	__le64	cb_stripe_unit;
+	__le32	cb_group_width;
+	__le32	cb_group_depth;
+	__le32	cb_mirror_cnt;
+	__le32	cb_raid_algorithm;
+} __packed;
+
+/*
+ * This is an osd device information descriptor. It is a single entry in
+ * the exofs device table. It describes an osd target lun which
+ * contains data belonging to this FS. (Same partition_id on all devices)
+ */
+struct exofs_dt_device_info {
+	__le32	systemid_len;
+	u8	systemid[OSD_SYSTEMID_LEN];
+	__le64	long_name_offset;	/* If !0 then offset-in-file */
+	__le32	osdname_len;		/* */
+	u8	osdname[44];		/* Embbeded, Ususally an asci uuid */
+} __packed;
+
+/*
+ * The EXOFS device table - stored in object EXOFS_DEVTABLE_ID's data.
+ * It contains the raid used for this multy-device FS and an array of
+ * participating devices.
+ */
+struct exofs_device_table {
+	__le32				dt_version;	/* == EXOFS_DT_VER */
+	struct exofs_dt_data_map	dt_data_map;	/* Raid policy to use */
+
+	/* Resurved space For future use. Total includeing this:
+	 * (8 * sizeof(le64))
+	 */
+	__le64				__Resurved[4];
+
+	__le64				dt_num_devices;	/* Array size */
+	struct exofs_dt_device_info	dt_dev_table[];	/* Array of devices */
+} __packed;
 
 /****************************************************************************
  * inode-related things
@@ -155,22 +206,4 @@
 	(((name_len) + offsetof(struct exofs_dir_entry, name)  + \
 	  EXOFS_DIR_ROUND) & ~EXOFS_DIR_ROUND)
 
-/*************************
- * function declarations *
- *************************/
-/* osd.c                 */
-void exofs_make_credential(u8 cred_a[OSD_CAP_LEN],
-			   const struct osd_obj_id *obj);
-
-int exofs_check_ok_resid(struct osd_request *or, u64 *in_resid, u64 *out_resid);
-static inline int exofs_check_ok(struct osd_request *or)
-{
-	return exofs_check_ok_resid(or, NULL, NULL);
-}
-int exofs_sync_op(struct osd_request *or, int timeout, u8 *cred);
-int exofs_async_op(struct osd_request *or,
-	osd_req_done_fn *async_done, void *caller_context, u8 *cred);
-
-int extract_attr_from_req(struct osd_request *or, struct osd_attr *attr);
-
 #endif /*ifndef __EXOFS_COM_H__*/
diff --git a/fs/exofs/exofs.h b/fs/exofs/exofs.h
index 5ec72e0..c35fd46 100644
--- a/fs/exofs/exofs.h
+++ b/fs/exofs/exofs.h
@@ -30,13 +30,17 @@
  * along with exofs; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
+#ifndef __EXOFS_H__
+#define __EXOFS_H__
 
 #include <linux/fs.h>
 #include <linux/time.h>
 #include "common.h"
 
-#ifndef __EXOFS_H__
-#define __EXOFS_H__
+/* FIXME: Remove once pnfs hits mainline
+ * #include <linux/exportfs/pnfs_osd_xdr.h>
+ */
+#include "pnfs.h"
 
 #define EXOFS_ERR(fmt, a...) printk(KERN_ERR "exofs: " fmt, ##a)
 
@@ -55,7 +59,7 @@
  * our extension to the in-memory superblock
  */
 struct exofs_sb_info {
-	struct osd_dev	*s_dev;			/* returned by get_osd_dev    */
+	struct exofs_fscb s_fscb;		/* Written often, pre-allocate*/
 	osd_id		s_pid;			/* partition ID of file system*/
 	int		s_timeout;		/* timeout for OSD operations */
 	uint64_t	s_nextid;		/* highest object ID used     */
@@ -63,7 +67,11 @@
 	spinlock_t	s_next_gen_lock;	/* spinlock for gen # update  */
 	u32		s_next_generation;	/* next gen # to use          */
 	atomic_t	s_curr_pending;		/* number of pending commands */
-	uint8_t		s_cred[OSD_CAP_LEN];	/* all-powerful credential    */
+	uint8_t		s_cred[OSD_CAP_LEN];	/* credential for the fscb    */
+
+	struct pnfs_osd_data_map data_map;	/* Default raid to use        */
+	unsigned	s_numdevs;		/* Num of devices in array    */
+	struct osd_dev	*s_ods[1];		/* Variable length, minimum 1 */
 };
 
 /*
@@ -79,6 +87,50 @@
 	struct inode   vfs_inode;          /* normal in-memory inode          */
 };
 
+static inline osd_id exofs_oi_objno(struct exofs_i_info *oi)
+{
+	return oi->vfs_inode.i_ino + EXOFS_OBJ_OFF;
+}
+
+struct exofs_io_state;
+typedef void (*exofs_io_done_fn)(struct exofs_io_state *or, void *private);
+
+struct exofs_io_state {
+	struct kref		kref;
+
+	void			*private;
+	exofs_io_done_fn	done;
+
+	struct exofs_sb_info	*sbi;
+	struct osd_obj_id	obj;
+	u8			*cred;
+
+	/* Global read/write IO*/
+	loff_t			offset;
+	unsigned long		length;
+	void			*kern_buff;
+	struct bio		*bio;
+
+	/* Attributes */
+	unsigned		in_attr_len;
+	struct osd_attr 	*in_attr;
+	unsigned		out_attr_len;
+	struct osd_attr 	*out_attr;
+
+	/* Variable array of size numdevs */
+	unsigned numdevs;
+	struct exofs_per_dev_state {
+		struct osd_request *or;
+		struct bio *bio;
+	} per_dev[];
+};
+
+static inline unsigned exofs_io_state_size(unsigned numdevs)
+{
+	return sizeof(struct exofs_io_state) +
+		sizeof(struct exofs_per_dev_state) * numdevs;
+}
+
 /*
  * our inode flags
  */
@@ -130,6 +182,42 @@
 /*************************
  * function declarations *
  *************************/
+
+/* ios.c */
+void exofs_make_credential(u8 cred_a[OSD_CAP_LEN],
+			   const struct osd_obj_id *obj);
+int exofs_read_kern(struct osd_dev *od, u8 *cred, struct osd_obj_id *obj,
+		    u64 offset, void *p, unsigned length);
+
+int  exofs_get_io_state(struct exofs_sb_info *sbi, struct exofs_io_state** ios);
+void exofs_put_io_state(struct exofs_io_state *ios);
+
+int exofs_check_io(struct exofs_io_state *ios, u64 *resid);
+
+int exofs_sbi_create(struct exofs_io_state *ios);
+int exofs_sbi_remove(struct exofs_io_state *ios);
+int exofs_sbi_write(struct exofs_io_state *ios);
+int exofs_sbi_read(struct exofs_io_state *ios);
+
+int extract_attr_from_ios(struct exofs_io_state *ios, struct osd_attr *attr);
+
+int exofs_oi_truncate(struct exofs_i_info *oi, u64 new_len);
+static inline int exofs_oi_write(struct exofs_i_info *oi,
+				 struct exofs_io_state *ios)
+{
+	ios->obj.id = exofs_oi_objno(oi);
+	ios->cred = oi->i_cred;
+	return exofs_sbi_write(ios);
+}
+
+static inline int exofs_oi_read(struct exofs_i_info *oi,
+				struct exofs_io_state *ios)
+{
+	ios->obj.id = exofs_oi_objno(oi);
+	ios->cred = oi->i_cred;
+	return exofs_sbi_read(ios);
+}
+
 /* inode.c               */
 void exofs_truncate(struct inode *inode);
 int exofs_setattr(struct dentry *, struct iattr *);
@@ -169,6 +257,7 @@
 
 /* inode.c           */
 extern const struct address_space_operations exofs_aops;
+extern const struct osd_attr g_attr_logical_length;
 
 /* namei.c           */
 extern const struct inode_operations exofs_dir_inode_operations;
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c
index 6c10f74..698a863 100644
--- a/fs/exofs/inode.c
+++ b/fs/exofs/inode.c
@@ -37,15 +37,18 @@
 
 #include "exofs.h"
 
-#ifdef CONFIG_EXOFS_DEBUG
-#  define EXOFS_DEBUG_OBJ_ISIZE 1
-#endif
+#define EXOFS_DBGMSG2(M...) do {} while (0)
+
+enum { BIO_MAX_PAGES_KMALLOC =
+		(PAGE_SIZE - sizeof(struct bio)) / sizeof(struct bio_vec),
+};
 
 struct page_collect {
 	struct exofs_sb_info *sbi;
 	struct request_queue *req_q;
 	struct inode *inode;
 	unsigned expected_pages;
+	struct exofs_io_state *ios;
 
 	struct bio *bio;
 	unsigned nr_pages;
@@ -54,22 +57,23 @@
 };
 
 static void _pcol_init(struct page_collect *pcol, unsigned expected_pages,
-		struct inode *inode)
+		       struct inode *inode)
 {
 	struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
 
 	pcol->sbi = sbi;
-	pcol->req_q = osd_request_queue(sbi->s_dev);
+	/* Create master bios on first Q, later on cloning, each clone will be
+	 * allocated on it's destination Q
+	 */
+	pcol->req_q = osd_request_queue(sbi->s_ods[0]);
 	pcol->inode = inode;
 	pcol->expected_pages = expected_pages;
 
+	pcol->ios = NULL;
 	pcol->bio = NULL;
 	pcol->nr_pages = 0;
 	pcol->length = 0;
 	pcol->pg_first = -1;
-
-	EXOFS_DBGMSG("_pcol_init ino=0x%lx expected_pages=%u\n", inode->i_ino,
-		     expected_pages);
 }
 
 static void _pcol_reset(struct page_collect *pcol)
@@ -80,35 +84,49 @@
 	pcol->nr_pages = 0;
 	pcol->length = 0;
 	pcol->pg_first = -1;
-	EXOFS_DBGMSG("_pcol_reset ino=0x%lx expected_pages=%u\n",
-		     pcol->inode->i_ino, pcol->expected_pages);
+	pcol->ios = NULL;
 
 	/* this is probably the end of the loop but in writes
 	 * it might not end here. don't be left with nothing
 	 */
 	if (!pcol->expected_pages)
-		pcol->expected_pages = 128;
+		pcol->expected_pages = BIO_MAX_PAGES_KMALLOC;
 }
 
 static int pcol_try_alloc(struct page_collect *pcol)
 {
-	int pages = min_t(unsigned, pcol->expected_pages, BIO_MAX_PAGES);
+	int pages = min_t(unsigned, pcol->expected_pages,
+			  BIO_MAX_PAGES_KMALLOC);
+
+	if (!pcol->ios) { /* First time allocate io_state */
+		int ret = exofs_get_io_state(pcol->sbi, &pcol->ios);
+
+		if (ret)
+			return ret;
+	}
 
 	for (; pages; pages >>= 1) {
-		pcol->bio = bio_alloc(GFP_KERNEL, pages);
+		pcol->bio = bio_kmalloc(GFP_KERNEL, pages);
 		if (likely(pcol->bio))
 			return 0;
 	}
 
-	EXOFS_ERR("Failed to kcalloc expected_pages=%u\n",
+	EXOFS_ERR("Failed to bio_kmalloc expected_pages=%u\n",
 		  pcol->expected_pages);
 	return -ENOMEM;
 }
 
 static void pcol_free(struct page_collect *pcol)
 {
-	bio_put(pcol->bio);
-	pcol->bio = NULL;
+	if (pcol->bio) {
+		bio_put(pcol->bio);
+		pcol->bio = NULL;
+	}
+
+	if (pcol->ios) {
+		exofs_put_io_state(pcol->ios);
+		pcol->ios = NULL;
+	}
 }
 
 static int pcol_add_page(struct page_collect *pcol, struct page *page,
@@ -161,22 +179,17 @@
 /* Called at the end of reads, to optionally unlock pages and update their
  * status.
  */
-static int __readpages_done(struct osd_request *or, struct page_collect *pcol,
-			    bool do_unlock)
+static int __readpages_done(struct page_collect *pcol, bool do_unlock)
 {
 	struct bio_vec *bvec;
 	int i;
 	u64 resid;
 	u64 good_bytes;
 	u64 length = 0;
-	int ret = exofs_check_ok_resid(or, &resid, NULL);
-
-	osd_end_request(or);
+	int ret = exofs_check_io(pcol->ios, &resid);
 
 	if (likely(!ret))
 		good_bytes = pcol->length;
-	else if (!resid)
-		good_bytes = 0;
 	else
 		good_bytes = pcol->length - resid;
 
@@ -198,7 +211,7 @@
 		else
 			page_stat = ret;
 
-		EXOFS_DBGMSG("    readpages_done(0x%lx, 0x%lx) %s\n",
+		EXOFS_DBGMSG2("    readpages_done(0x%lx, 0x%lx) %s\n",
 			  inode->i_ino, page->index,
 			  page_stat ? "bad_bytes" : "good_bytes");
 
@@ -214,13 +227,13 @@
 }
 
 /* callback of async reads */
-static void readpages_done(struct osd_request *or, void *p)
+static void readpages_done(struct exofs_io_state *ios, void *p)
 {
 	struct page_collect *pcol = p;
 
-	__readpages_done(or, pcol, true);
+	__readpages_done(pcol, true);
 	atomic_dec(&pcol->sbi->s_curr_pending);
-	kfree(p);
+	kfree(pcol);
 }
 
 static void _unlock_pcol_pages(struct page_collect *pcol, int ret, int rw)
@@ -238,17 +251,13 @@
 
 		unlock_page(page);
 	}
-	pcol_free(pcol);
 }
 
 static int read_exec(struct page_collect *pcol, bool is_sync)
 {
 	struct exofs_i_info *oi = exofs_i(pcol->inode);
-	struct osd_obj_id obj = {pcol->sbi->s_pid,
-					pcol->inode->i_ino + EXOFS_OBJ_OFF};
-	struct osd_request *or = NULL;
+	struct exofs_io_state *ios = pcol->ios;
 	struct page_collect *pcol_copy = NULL;
-	loff_t i_start = pcol->pg_first << PAGE_CACHE_SHIFT;
 	int ret;
 
 	if (!pcol->bio)
@@ -257,17 +266,13 @@
 	/* see comment in _readpage() about sync reads */
 	WARN_ON(is_sync && (pcol->nr_pages != 1));
 
-	or = osd_start_request(pcol->sbi->s_dev, GFP_KERNEL);
-	if (unlikely(!or)) {
-		ret = -ENOMEM;
-		goto err;
-	}
-
-	osd_req_read(or, &obj, i_start, pcol->bio, pcol->length);
+	ios->bio = pcol->bio;
+	ios->length = pcol->length;
+	ios->offset = pcol->pg_first << PAGE_CACHE_SHIFT;
 
 	if (is_sync) {
-		exofs_sync_op(or, pcol->sbi->s_timeout, oi->i_cred);
-		return __readpages_done(or, pcol, false);
+		exofs_oi_read(oi, pcol->ios);
+		return __readpages_done(pcol, false);
 	}
 
 	pcol_copy = kmalloc(sizeof(*pcol_copy), GFP_KERNEL);
@@ -277,14 +282,16 @@
 	}
 
 	*pcol_copy = *pcol;
-	ret = exofs_async_op(or, readpages_done, pcol_copy, oi->i_cred);
+	ios->done = readpages_done;
+	ios->private = pcol_copy;
+	ret = exofs_oi_read(oi, ios);
 	if (unlikely(ret))
 		goto err;
 
 	atomic_inc(&pcol->sbi->s_curr_pending);
 
 	EXOFS_DBGMSG("read_exec obj=0x%llx start=0x%llx length=0x%lx\n",
-		  obj.id, _LLU(i_start), pcol->length);
+		  ios->obj.id, _LLU(ios->offset), pcol->length);
 
 	/* pages ownership was passed to pcol_copy */
 	_pcol_reset(pcol);
@@ -293,12 +300,10 @@
 err:
 	if (!is_sync)
 		_unlock_pcol_pages(pcol, ret, READ);
-	else /* Pages unlocked by caller in sync mode only free bio */
-		pcol_free(pcol);
+
+	pcol_free(pcol);
 
 	kfree(pcol_copy);
-	if (or)
-		osd_end_request(or);
 	return ret;
 }
 
@@ -370,12 +375,12 @@
 	if (len != PAGE_CACHE_SIZE)
 		zero_user(page, len, PAGE_CACHE_SIZE - len);
 
-	EXOFS_DBGMSG("    readpage_strip(0x%lx, 0x%lx) len=0x%zx\n",
+	EXOFS_DBGMSG2("    readpage_strip(0x%lx, 0x%lx) len=0x%zx\n",
 		     inode->i_ino, page->index, len);
 
 	ret = pcol_add_page(pcol, page, len);
 	if (ret) {
-		EXOFS_DBGMSG("Failed pcol_add_page pages[i]=%p "
+		EXOFS_DBGMSG2("Failed pcol_add_page pages[i]=%p "
 			  "this_len=0x%zx nr_pages=%u length=0x%lx\n",
 			  page, len, pcol->nr_pages, pcol->length);
 
@@ -419,9 +424,8 @@
 
 	_pcol_init(&pcol, 1, page->mapping->host);
 
-	/* readpage_strip might call read_exec(,async) inside at several places
-	 * but this is safe for is_async=0 since read_exec will not do anything
-	 * when we have a single page.
+	/* readpage_strip might call read_exec(,is_sync==false) at several
+	 * places but not if we have a single page.
 	 */
 	ret = readpage_strip(&pcol, page);
 	if (ret) {
@@ -440,8 +444,8 @@
 	return _readpage(page, false);
 }
 
-/* Callback for osd_write. All writes are asynchronouse */
-static void writepages_done(struct osd_request *or, void *p)
+/* Callback for osd_write. All writes are asynchronous */
+static void writepages_done(struct exofs_io_state *ios, void *p)
 {
 	struct page_collect *pcol = p;
 	struct bio_vec *bvec;
@@ -449,16 +453,12 @@
 	u64 resid;
 	u64  good_bytes;
 	u64  length = 0;
+	int ret = exofs_check_io(ios, &resid);
 
-	int ret = exofs_check_ok_resid(or, NULL, &resid);
-
-	osd_end_request(or);
 	atomic_dec(&pcol->sbi->s_curr_pending);
 
 	if (likely(!ret))
 		good_bytes = pcol->length;
-	else if (!resid)
-		good_bytes = 0;
 	else
 		good_bytes = pcol->length - resid;
 
@@ -482,7 +482,7 @@
 
 		update_write_page(page, page_stat);
 		unlock_page(page);
-		EXOFS_DBGMSG("    writepages_done(0x%lx, 0x%lx) status=%d\n",
+		EXOFS_DBGMSG2("    writepages_done(0x%lx, 0x%lx) status=%d\n",
 			     inode->i_ino, page->index, page_stat);
 
 		length += bvec->bv_len;
@@ -496,23 +496,13 @@
 static int write_exec(struct page_collect *pcol)
 {
 	struct exofs_i_info *oi = exofs_i(pcol->inode);
-	struct osd_obj_id obj = {pcol->sbi->s_pid,
-					pcol->inode->i_ino + EXOFS_OBJ_OFF};
-	struct osd_request *or = NULL;
+	struct exofs_io_state *ios = pcol->ios;
 	struct page_collect *pcol_copy = NULL;
-	loff_t i_start = pcol->pg_first << PAGE_CACHE_SHIFT;
 	int ret;
 
 	if (!pcol->bio)
 		return 0;
 
-	or = osd_start_request(pcol->sbi->s_dev, GFP_KERNEL);
-	if (unlikely(!or)) {
-		EXOFS_ERR("write_exec: Faild to osd_start_request()\n");
-		ret = -ENOMEM;
-		goto err;
-	}
-
 	pcol_copy = kmalloc(sizeof(*pcol_copy), GFP_KERNEL);
 	if (!pcol_copy) {
 		EXOFS_ERR("write_exec: Faild to kmalloc(pcol)\n");
@@ -523,16 +513,22 @@
 	*pcol_copy = *pcol;
 
 	pcol_copy->bio->bi_rw |= (1 << BIO_RW); /* FIXME: bio_set_dir() */
-	osd_req_write(or, &obj, i_start, pcol_copy->bio, pcol_copy->length);
-	ret = exofs_async_op(or, writepages_done, pcol_copy, oi->i_cred);
+
+	ios->bio = pcol_copy->bio;
+	ios->offset = pcol_copy->pg_first << PAGE_CACHE_SHIFT;
+	ios->length = pcol_copy->length;
+	ios->done = writepages_done;
+	ios->private = pcol_copy;
+
+	ret = exofs_oi_write(oi, ios);
 	if (unlikely(ret)) {
-		EXOFS_ERR("write_exec: exofs_async_op() Faild\n");
+		EXOFS_ERR("write_exec: exofs_oi_write() Faild\n");
 		goto err;
 	}
 
 	atomic_inc(&pcol->sbi->s_curr_pending);
 	EXOFS_DBGMSG("write_exec(0x%lx, 0x%llx) start=0x%llx length=0x%lx\n",
-		  pcol->inode->i_ino, pcol->pg_first, _LLU(i_start),
+		  pcol->inode->i_ino, pcol->pg_first, _LLU(ios->offset),
 		  pcol->length);
 	/* pages ownership was passed to pcol_copy */
 	_pcol_reset(pcol);
@@ -540,9 +536,9 @@
 
 err:
 	_unlock_pcol_pages(pcol, ret, WRITE);
+	pcol_free(pcol);
 	kfree(pcol_copy);
-	if (or)
-		osd_end_request(or);
+
 	return ret;
 }
 
@@ -586,6 +582,9 @@
 			if (PageError(page))
 				ClearPageError(page);
 			unlock_page(page);
+			EXOFS_DBGMSG("writepage_strip(0x%lx, 0x%lx) "
+				     "outside the limits\n",
+				     inode->i_ino, page->index);
 			return 0;
 		}
 	}
@@ -600,6 +599,9 @@
 		ret = write_exec(pcol);
 		if (unlikely(ret))
 			goto fail;
+
+		EXOFS_DBGMSG("writepage_strip(0x%lx, 0x%lx) Discontinuity\n",
+			     inode->i_ino, page->index);
 		goto try_again;
 	}
 
@@ -609,7 +611,7 @@
 			goto fail;
 	}
 
-	EXOFS_DBGMSG("    writepage_strip(0x%lx, 0x%lx) len=0x%zx\n",
+	EXOFS_DBGMSG2("    writepage_strip(0x%lx, 0x%lx) len=0x%zx\n",
 		     inode->i_ino, page->index, len);
 
 	ret = pcol_add_page(pcol, page, len);
@@ -634,6 +636,8 @@
 	return 0;
 
 fail:
+	EXOFS_DBGMSG("Error: writepage_strip(0x%lx, 0x%lx)=>%d\n",
+		     inode->i_ino, page->index, ret);
 	set_bit(AS_EIO, &page->mapping->flags);
 	unlock_page(page);
 	return ret;
@@ -652,14 +656,17 @@
 			wbc->range_end >> PAGE_CACHE_SHIFT;
 
 	if (start || end)
-		expected_pages = min(end - start + 1, 32L);
+		expected_pages = end - start + 1;
 	else
 		expected_pages = mapping->nrpages;
 
-	EXOFS_DBGMSG("inode(0x%lx) wbc->start=0x%llx wbc->end=0x%llx"
-		     " m->nrpages=%lu start=0x%lx end=0x%lx\n",
+	if (expected_pages < 32L)
+		expected_pages = 32L;
+
+	EXOFS_DBGMSG("inode(0x%lx) wbc->start=0x%llx wbc->end=0x%llx "
+		     "nrpages=%lu start=0x%lx end=0x%lx expected_pages=%ld\n",
 		     mapping->host->i_ino, wbc->range_start, wbc->range_end,
-		     mapping->nrpages, start, end);
+		     mapping->nrpages, start, end, expected_pages);
 
 	_pcol_init(&pcol, expected_pages, mapping->host);
 
@@ -771,19 +778,28 @@
 const struct osd_attr g_attr_logical_length = ATTR_DEF(
 	OSD_APAGE_OBJECT_INFORMATION, OSD_ATTR_OI_LOGICAL_LENGTH, 8);
 
+static int _do_truncate(struct inode *inode)
+{
+	struct exofs_i_info *oi = exofs_i(inode);
+	loff_t isize = i_size_read(inode);
+	int ret;
+
+	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+
+	nobh_truncate_page(inode->i_mapping, isize, exofs_get_block);
+
+	ret = exofs_oi_truncate(oi, (u64)isize);
+	EXOFS_DBGMSG("(0x%lx) size=0x%llx\n", inode->i_ino, isize);
+	return ret;
+}
+
 /*
  * Truncate a file to the specified size - all we have to do is set the size
  * attribute.  We make sure the object exists first.
  */
 void exofs_truncate(struct inode *inode)
 {
-	struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
 	struct exofs_i_info *oi = exofs_i(inode);
-	struct osd_obj_id obj = {sbi->s_pid, inode->i_ino + EXOFS_OBJ_OFF};
-	struct osd_request *or;
-	struct osd_attr attr;
-	loff_t isize = i_size_read(inode);
-	__be64 newsize;
 	int ret;
 
 	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)
@@ -793,22 +809,6 @@
 		return;
 	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
 		return;
-	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-
-	nobh_truncate_page(inode->i_mapping, isize, exofs_get_block);
-
-	or = osd_start_request(sbi->s_dev, GFP_KERNEL);
-	if (unlikely(!or)) {
-		EXOFS_ERR("ERROR: exofs_truncate: osd_start_request failed\n");
-		goto fail;
-	}
-
-	osd_req_set_attributes(or, &obj);
-
-	newsize = cpu_to_be64((u64)isize);
-	attr = g_attr_logical_length;
-	attr.val_ptr = &newsize;
-	osd_req_add_set_attr_list(or, &attr, 1);
 
 	/* if we are about to truncate an object, and it hasn't been
 	 * created yet, wait
@@ -816,8 +816,7 @@
 	if (unlikely(wait_obj_created(oi)))
 		goto fail;
 
-	ret = exofs_sync_op(or, sbi->s_timeout, oi->i_cred);
-	osd_end_request(or);
+	ret = _do_truncate(inode);
 	if (ret)
 		goto fail;
 
@@ -847,65 +846,62 @@
 
 /*
  * Read an inode from the OSD, and return it as is.  We also return the size
- * attribute in the 'sanity' argument if we got compiled with debugging turned
- * on.
+ * attribute in the 'obj_size' argument.
  */
 static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi,
-		    struct exofs_fcb *inode, uint64_t *sanity)
+		    struct exofs_fcb *inode, uint64_t *obj_size)
 {
 	struct exofs_sb_info *sbi = sb->s_fs_info;
-	struct osd_request *or;
-	struct osd_attr attr;
-	struct osd_obj_id obj = {sbi->s_pid,
-				 oi->vfs_inode.i_ino + EXOFS_OBJ_OFF};
+	struct osd_attr attrs[2];
+	struct exofs_io_state *ios;
 	int ret;
 
-	exofs_make_credential(oi->i_cred, &obj);
-
-	or = osd_start_request(sbi->s_dev, GFP_KERNEL);
-	if (unlikely(!or)) {
-		EXOFS_ERR("exofs_get_inode: osd_start_request failed.\n");
-		return -ENOMEM;
+	*obj_size = ~0;
+	ret = exofs_get_io_state(sbi, &ios);
+	if (unlikely(ret)) {
+		EXOFS_ERR("%s: exofs_get_io_state failed.\n", __func__);
+		return ret;
 	}
-	osd_req_get_attributes(or, &obj);
 
-	/* we need the inode attribute */
-	osd_req_add_get_attr_list(or, &g_attr_inode_data, 1);
+	ios->obj.id = exofs_oi_objno(oi);
+	exofs_make_credential(oi->i_cred, &ios->obj);
+	ios->cred = oi->i_cred;
 
-#ifdef EXOFS_DEBUG_OBJ_ISIZE
-	/* we get the size attributes to do a sanity check */
-	osd_req_add_get_attr_list(or, &g_attr_logical_length, 1);
-#endif
+	attrs[0] = g_attr_inode_data;
+	attrs[1] = g_attr_logical_length;
+	ios->in_attr = attrs;
+	ios->in_attr_len = ARRAY_SIZE(attrs);
 
-	ret = exofs_sync_op(or, sbi->s_timeout, oi->i_cred);
+	ret = exofs_sbi_read(ios);
 	if (ret)
 		goto out;
 
-	attr = g_attr_inode_data;
-	ret = extract_attr_from_req(or, &attr);
+	ret = extract_attr_from_ios(ios, &attrs[0]);
 	if (ret) {
-		EXOFS_ERR("exofs_get_inode: extract_attr_from_req failed\n");
+		EXOFS_ERR("%s: extract_attr of inode_data failed\n", __func__);
 		goto out;
 	}
+	WARN_ON(attrs[0].len != EXOFS_INO_ATTR_SIZE);
+	memcpy(inode, attrs[0].val_ptr, EXOFS_INO_ATTR_SIZE);
 
-	WARN_ON(attr.len != EXOFS_INO_ATTR_SIZE);
-	memcpy(inode, attr.val_ptr, EXOFS_INO_ATTR_SIZE);
-
-#ifdef EXOFS_DEBUG_OBJ_ISIZE
-	attr = g_attr_logical_length;
-	ret = extract_attr_from_req(or, &attr);
+	ret = extract_attr_from_ios(ios, &attrs[1]);
 	if (ret) {
-		EXOFS_ERR("ERROR: extract attr from or failed\n");
+		EXOFS_ERR("%s: extract_attr of logical_length failed\n",
+			  __func__);
 		goto out;
 	}
-	*sanity = get_unaligned_be64(attr.val_ptr);
-#endif
+	*obj_size = get_unaligned_be64(attrs[1].val_ptr);
 
 out:
-	osd_end_request(or);
+	exofs_put_io_state(ios);
 	return ret;
 }
 
+static void __oi_init(struct exofs_i_info *oi)
+{
+	init_waitqueue_head(&oi->i_wq);
+	oi->i_flags = 0;
+}
 /*
  * Fill in an inode read from the OSD and set it up for use
  */
@@ -914,7 +910,7 @@
 	struct exofs_i_info *oi;
 	struct exofs_fcb fcb;
 	struct inode *inode;
-	uint64_t uninitialized_var(sanity);
+	uint64_t obj_size;
 	int ret;
 
 	inode = iget_locked(sb, ino);
@@ -923,13 +919,13 @@
 	if (!(inode->i_state & I_NEW))
 		return inode;
 	oi = exofs_i(inode);
+	__oi_init(oi);
 
 	/* read the inode from the osd */
-	ret = exofs_get_inode(sb, oi, &fcb, &sanity);
+	ret = exofs_get_inode(sb, oi, &fcb, &obj_size);
 	if (ret)
 		goto bad_inode;
 
-	init_waitqueue_head(&oi->i_wq);
 	set_obj_created(oi);
 
 	/* copy stuff from on-disk struct to in-memory struct */
@@ -947,14 +943,12 @@
 	inode->i_blkbits = EXOFS_BLKSHIFT;
 	inode->i_generation = le32_to_cpu(fcb.i_generation);
 
-#ifdef EXOFS_DEBUG_OBJ_ISIZE
-	if ((inode->i_size != sanity) &&
+	if ((inode->i_size != obj_size) &&
 		(!exofs_inode_is_fast_symlink(inode))) {
-		EXOFS_ERR("WARNING: Size of object from inode and "
-			  "attributes differ (%lld != %llu)\n",
-			  inode->i_size, _LLU(sanity));
+		EXOFS_ERR("WARNING: Size of inode=%llu != object=%llu\n",
+			  inode->i_size, _LLU(obj_size));
+		/* FIXME: call exofs_inode_recovery() */
 	}
-#endif
 
 	oi->i_dir_start_lookup = 0;
 
@@ -1020,23 +1014,30 @@
  * set the obj_created flag so that other methods know that the object exists on
  * the OSD.
  */
-static void create_done(struct osd_request *or, void *p)
+static void create_done(struct exofs_io_state *ios, void *p)
 {
 	struct inode *inode = p;
 	struct exofs_i_info *oi = exofs_i(inode);
 	struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
 	int ret;
 
-	ret = exofs_check_ok(or);
-	osd_end_request(or);
+	ret = exofs_check_io(ios, NULL);
+	exofs_put_io_state(ios);
+
 	atomic_dec(&sbi->s_curr_pending);
 
 	if (unlikely(ret)) {
 		EXOFS_ERR("object=0x%llx creation faild in pid=0x%llx",
-			  _LLU(sbi->s_pid), _LLU(inode->i_ino + EXOFS_OBJ_OFF));
-		make_bad_inode(inode);
-	} else
-		set_obj_created(oi);
+			  _LLU(exofs_oi_objno(oi)), _LLU(sbi->s_pid));
+		/*TODO: When FS is corrupted creation can fail, object already
+		 * exist. Get rid of this asynchronous creation, if exist
+		 * increment the obj counter and try the next object. Until we
+		 * succeed. All these dangling objects will be made into lost
+		 * files by chkfs.exofs
+		 */
+	}
+
+	set_obj_created(oi);
 
 	atomic_dec(&inode->i_count);
 	wake_up(&oi->i_wq);
@@ -1051,8 +1052,7 @@
 	struct inode *inode;
 	struct exofs_i_info *oi;
 	struct exofs_sb_info *sbi;
-	struct osd_request *or;
-	struct osd_obj_id obj;
+	struct exofs_io_state *ios;
 	int ret;
 
 	sb = dir->i_sb;
@@ -1061,8 +1061,8 @@
 		return ERR_PTR(-ENOMEM);
 
 	oi = exofs_i(inode);
+	__oi_init(oi);
 
-	init_waitqueue_head(&oi->i_wq);
 	set_obj_2bcreated(oi);
 
 	sbi = sb->s_fs_info;
@@ -1089,28 +1089,28 @@
 
 	mark_inode_dirty(inode);
 
-	obj.partition = sbi->s_pid;
-	obj.id = inode->i_ino + EXOFS_OBJ_OFF;
-	exofs_make_credential(oi->i_cred, &obj);
-
-	or = osd_start_request(sbi->s_dev, GFP_KERNEL);
-	if (unlikely(!or)) {
-		EXOFS_ERR("exofs_new_inode: osd_start_request failed\n");
-		return ERR_PTR(-ENOMEM);
+	ret = exofs_get_io_state(sbi, &ios);
+	if (unlikely(ret)) {
+		EXOFS_ERR("exofs_new_inode: exofs_get_io_state failed\n");
+		return ERR_PTR(ret);
 	}
 
-	osd_req_create_object(or, &obj);
+	ios->obj.id = exofs_oi_objno(oi);
+	exofs_make_credential(oi->i_cred, &ios->obj);
 
 	/* increment the refcount so that the inode will still be around when we
 	 * reach the callback
 	 */
 	atomic_inc(&inode->i_count);
 
-	ret = exofs_async_op(or, create_done, inode, oi->i_cred);
+	ios->done = create_done;
+	ios->private = inode;
+	ios->cred = oi->i_cred;
+	ret = exofs_sbi_create(ios);
 	if (ret) {
 		atomic_dec(&inode->i_count);
-		osd_end_request(or);
-		return ERR_PTR(-EIO);
+		exofs_put_io_state(ios);
+		return ERR_PTR(ret);
 	}
 	atomic_inc(&sbi->s_curr_pending);
 
@@ -1128,11 +1128,11 @@
 /*
  * Callback function from exofs_update_inode().
  */
-static void updatei_done(struct osd_request *or, void *p)
+static void updatei_done(struct exofs_io_state *ios, void *p)
 {
 	struct updatei_args *args = p;
 
-	osd_end_request(or);
+	exofs_put_io_state(ios);
 
 	atomic_dec(&args->sbi->s_curr_pending);
 
@@ -1148,8 +1148,7 @@
 	struct exofs_i_info *oi = exofs_i(inode);
 	struct super_block *sb = inode->i_sb;
 	struct exofs_sb_info *sbi = sb->s_fs_info;
-	struct osd_obj_id obj = {sbi->s_pid, inode->i_ino + EXOFS_OBJ_OFF};
-	struct osd_request *or;
+	struct exofs_io_state *ios;
 	struct osd_attr attr;
 	struct exofs_fcb *fcb;
 	struct updatei_args *args;
@@ -1186,18 +1185,16 @@
 	} else
 		memcpy(fcb->i_data, oi->i_data, sizeof(fcb->i_data));
 
-	or = osd_start_request(sbi->s_dev, GFP_KERNEL);
-	if (unlikely(!or)) {
-		EXOFS_ERR("exofs_update_inode: osd_start_request failed.\n");
-		ret = -ENOMEM;
+	ret = exofs_get_io_state(sbi, &ios);
+	if (unlikely(ret)) {
+		EXOFS_ERR("%s: exofs_get_io_state failed.\n", __func__);
 		goto free_args;
 	}
 
-	osd_req_set_attributes(or, &obj);
-
 	attr = g_attr_inode_data;
 	attr.val_ptr = fcb;
-	osd_req_add_set_attr_list(or, &attr, 1);
+	ios->out_attr_len = 1;
+	ios->out_attr = &attr;
 
 	if (!obj_created(oi)) {
 		EXOFS_DBGMSG("!obj_created\n");
@@ -1206,22 +1203,19 @@
 		EXOFS_DBGMSG("wait_event done\n");
 	}
 
-	if (do_sync) {
-		ret = exofs_sync_op(or, sbi->s_timeout, oi->i_cred);
-		osd_end_request(or);
-		goto free_args;
-	} else {
+	if (!do_sync) {
 		args->sbi = sbi;
+		ios->done = updatei_done;
+		ios->private = args;
+	}
 
-		ret = exofs_async_op(or, updatei_done, args, oi->i_cred);
-		if (ret) {
-			osd_end_request(or);
-			goto free_args;
-		}
+	ret = exofs_oi_write(oi, ios);
+	if (!do_sync && !ret) {
 		atomic_inc(&sbi->s_curr_pending);
 		goto out; /* deallocation in updatei_done */
 	}
 
+	exofs_put_io_state(ios);
 free_args:
 	kfree(args);
 out:
@@ -1238,11 +1232,12 @@
  * Callback function from exofs_delete_inode() - don't have much cleaning up to
  * do.
  */
-static void delete_done(struct osd_request *or, void *p)
+static void delete_done(struct exofs_io_state *ios, void *p)
 {
-	struct exofs_sb_info *sbi;
-	osd_end_request(or);
-	sbi = p;
+	struct exofs_sb_info *sbi = p;
+
+	exofs_put_io_state(ios);
+
 	atomic_dec(&sbi->s_curr_pending);
 }
 
@@ -1256,8 +1251,7 @@
 	struct exofs_i_info *oi = exofs_i(inode);
 	struct super_block *sb = inode->i_sb;
 	struct exofs_sb_info *sbi = sb->s_fs_info;
-	struct osd_obj_id obj = {sbi->s_pid, inode->i_ino + EXOFS_OBJ_OFF};
-	struct osd_request *or;
+	struct exofs_io_state *ios;
 	int ret;
 
 	truncate_inode_pages(&inode->i_data, 0);
@@ -1274,25 +1268,26 @@
 
 	clear_inode(inode);
 
-	or = osd_start_request(sbi->s_dev, GFP_KERNEL);
-	if (unlikely(!or)) {
-		EXOFS_ERR("exofs_delete_inode: osd_start_request failed\n");
+	ret = exofs_get_io_state(sbi, &ios);
+	if (unlikely(ret)) {
+		EXOFS_ERR("%s: exofs_get_io_state failed\n", __func__);
 		return;
 	}
 
-	osd_req_remove_object(or, &obj);
-
 	/* if we are deleting an obj that hasn't been created yet, wait */
 	if (!obj_created(oi)) {
 		BUG_ON(!obj_2bcreated(oi));
 		wait_event(oi->i_wq, obj_created(oi));
 	}
 
-	ret = exofs_async_op(or, delete_done, sbi, oi->i_cred);
+	ios->obj.id = exofs_oi_objno(oi);
+	ios->done = delete_done;
+	ios->private = sbi;
+	ios->cred = oi->i_cred;
+	ret = exofs_sbi_remove(ios);
 	if (ret) {
-		EXOFS_ERR(
-		       "ERROR: @exofs_delete_inode exofs_async_op failed\n");
-		osd_end_request(or);
+		EXOFS_ERR("%s: exofs_sbi_remove failed\n", __func__);
+		exofs_put_io_state(ios);
 		return;
 	}
 	atomic_inc(&sbi->s_curr_pending);
diff --git a/fs/exofs/ios.c b/fs/exofs/ios.c
new file mode 100644
index 0000000..5bad01f
--- /dev/null
+++ b/fs/exofs/ios.c
@@ -0,0 +1,421 @@
+/*
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com)
+ * Copyright (C) 2008, 2009
+ * Boaz Harrosh <bharrosh@panasas.com>
+ *
+ * This file is part of exofs.
+ *
+ * exofs 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.  Since it is based on ext2, and the only
+ * valid version of GPL for the Linux kernel is version 2, the only valid
+ * version of GPL for exofs is version 2.
+ *
+ * exofs 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 exofs; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <scsi/scsi_device.h>
+
+#include "exofs.h"
+
+void exofs_make_credential(u8 cred_a[OSD_CAP_LEN], const struct osd_obj_id *obj)
+{
+	osd_sec_init_nosec_doall_caps(cred_a, obj, false, true);
+}
+
+int exofs_read_kern(struct osd_dev *od, u8 *cred, struct osd_obj_id *obj,
+		    u64 offset, void *p, unsigned length)
+{
+	struct osd_request *or = osd_start_request(od, GFP_KERNEL);
+/*	struct osd_sense_info osi = {.key = 0};*/
+	int ret;
+
+	if (unlikely(!or)) {
+		EXOFS_DBGMSG("%s: osd_start_request failed.\n", __func__);
+		return -ENOMEM;
+	}
+	ret = osd_req_read_kern(or, obj, offset, p, length);
+	if (unlikely(ret)) {
+		EXOFS_DBGMSG("%s: osd_req_read_kern failed.\n", __func__);
+		goto out;
+	}
+
+	ret = osd_finalize_request(or, 0, cred, NULL);
+	if (unlikely(ret)) {
+		EXOFS_DBGMSG("Faild to osd_finalize_request() => %d\n", ret);
+		goto out;
+	}
+
+	ret = osd_execute_request(or);
+	if (unlikely(ret))
+		EXOFS_DBGMSG("osd_execute_request() => %d\n", ret);
+	/* osd_req_decode_sense(or, ret); */
+
+out:
+	osd_end_request(or);
+	return ret;
+}
+
+int exofs_get_io_state(struct exofs_sb_info *sbi, struct exofs_io_state** pios)
+{
+	struct exofs_io_state *ios;
+
+	/*TODO: Maybe use kmem_cach per sbi of size
+	 * exofs_io_state_size(sbi->s_numdevs)
+	 */
+	ios = kzalloc(exofs_io_state_size(sbi->s_numdevs), GFP_KERNEL);
+	if (unlikely(!ios)) {
+		*pios = NULL;
+		return -ENOMEM;
+	}
+
+	ios->sbi = sbi;
+	ios->obj.partition = sbi->s_pid;
+	*pios = ios;
+	return 0;
+}
+
+void exofs_put_io_state(struct exofs_io_state *ios)
+{
+	if (ios) {
+		unsigned i;
+
+		for (i = 0; i < ios->numdevs; i++) {
+			struct exofs_per_dev_state *per_dev = &ios->per_dev[i];
+
+			if (per_dev->or)
+				osd_end_request(per_dev->or);
+			if (per_dev->bio)
+				bio_put(per_dev->bio);
+		}
+
+		kfree(ios);
+	}
+}
+
+static void _sync_done(struct exofs_io_state *ios, void *p)
+{
+	struct completion *waiting = p;
+
+	complete(waiting);
+}
+
+static void _last_io(struct kref *kref)
+{
+	struct exofs_io_state *ios = container_of(
+					kref, struct exofs_io_state, kref);
+
+	ios->done(ios, ios->private);
+}
+
+static void _done_io(struct osd_request *or, void *p)
+{
+	struct exofs_io_state *ios = p;
+
+	kref_put(&ios->kref, _last_io);
+}
+
+static int exofs_io_execute(struct exofs_io_state *ios)
+{
+	DECLARE_COMPLETION_ONSTACK(wait);
+	bool sync = (ios->done == NULL);
+	int i, ret;
+
+	if (sync) {
+		ios->done = _sync_done;
+		ios->private = &wait;
+	}
+
+	for (i = 0; i < ios->numdevs; i++) {
+		struct osd_request *or = ios->per_dev[i].or;
+		if (unlikely(!or))
+			continue;
+
+		ret = osd_finalize_request(or, 0, ios->cred, NULL);
+		if (unlikely(ret)) {
+			EXOFS_DBGMSG("Faild to osd_finalize_request() => %d\n",
+				     ret);
+			return ret;
+		}
+	}
+
+	kref_init(&ios->kref);
+
+	for (i = 0; i < ios->numdevs; i++) {
+		struct osd_request *or = ios->per_dev[i].or;
+		if (unlikely(!or))
+			continue;
+
+		kref_get(&ios->kref);
+		osd_execute_request_async(or, _done_io, ios);
+	}
+
+	kref_put(&ios->kref, _last_io);
+	ret = 0;
+
+	if (sync) {
+		wait_for_completion(&wait);
+		ret = exofs_check_io(ios, NULL);
+	}
+	return ret;
+}
+
+int exofs_check_io(struct exofs_io_state *ios, u64 *resid)
+{
+	enum osd_err_priority acumulated_osd_err = 0;
+	int acumulated_lin_err = 0;
+	int i;
+
+	for (i = 0; i < ios->numdevs; i++) {
+		struct osd_sense_info osi;
+		int ret = osd_req_decode_sense(ios->per_dev[i].or, &osi);
+
+		if (likely(!ret))
+			continue;
+
+		if (unlikely(ret == -EFAULT)) {
+			EXOFS_DBGMSG("%s: EFAULT Need page clear\n", __func__);
+			/*FIXME: All the pages in this device range should:
+			 *	clear_highpage(page);
+			 */
+		}
+
+		if (osi.osd_err_pri >= acumulated_osd_err) {
+			acumulated_osd_err = osi.osd_err_pri;
+			acumulated_lin_err = ret;
+		}
+	}
+
+	/* TODO: raid specific residual calculations */
+	if (resid) {
+		if (likely(!acumulated_lin_err))
+			*resid = 0;
+		else
+			*resid = ios->length;
+	}
+
+	return acumulated_lin_err;
+}
+
+int exofs_sbi_create(struct exofs_io_state *ios)
+{
+	int i, ret;
+
+	for (i = 0; i < ios->sbi->s_numdevs; i++) {
+		struct osd_request *or;
+
+		or = osd_start_request(ios->sbi->s_ods[i], GFP_KERNEL);
+		if (unlikely(!or)) {
+			EXOFS_ERR("%s: osd_start_request failed\n", __func__);
+			ret = -ENOMEM;
+			goto out;
+		}
+		ios->per_dev[i].or = or;
+		ios->numdevs++;
+
+		osd_req_create_object(or, &ios->obj);
+	}
+	ret = exofs_io_execute(ios);
+
+out:
+	return ret;
+}
+
+int exofs_sbi_remove(struct exofs_io_state *ios)
+{
+	int i, ret;
+
+	for (i = 0; i < ios->sbi->s_numdevs; i++) {
+		struct osd_request *or;
+
+		or = osd_start_request(ios->sbi->s_ods[i], GFP_KERNEL);
+		if (unlikely(!or)) {
+			EXOFS_ERR("%s: osd_start_request failed\n", __func__);
+			ret = -ENOMEM;
+			goto out;
+		}
+		ios->per_dev[i].or = or;
+		ios->numdevs++;
+
+		osd_req_remove_object(or, &ios->obj);
+	}
+	ret = exofs_io_execute(ios);
+
+out:
+	return ret;
+}
+
+int exofs_sbi_write(struct exofs_io_state *ios)
+{
+	int i, ret;
+
+	for (i = 0; i < ios->sbi->s_numdevs; i++) {
+		struct osd_request *or;
+
+		or = osd_start_request(ios->sbi->s_ods[i], GFP_KERNEL);
+		if (unlikely(!or)) {
+			EXOFS_ERR("%s: osd_start_request failed\n", __func__);
+			ret = -ENOMEM;
+			goto out;
+		}
+		ios->per_dev[i].or = or;
+		ios->numdevs++;
+
+		if (ios->bio) {
+			struct bio *bio;
+
+			if (i != 0) {
+				bio = bio_kmalloc(GFP_KERNEL,
+						  ios->bio->bi_max_vecs);
+				if (unlikely(!bio)) {
+					ret = -ENOMEM;
+					goto out;
+				}
+
+				__bio_clone(bio, ios->bio);
+				bio->bi_bdev = NULL;
+				bio->bi_next = NULL;
+				ios->per_dev[i].bio =  bio;
+			} else {
+				bio = ios->bio;
+			}
+
+			osd_req_write(or, &ios->obj, ios->offset, bio,
+				      ios->length);
+/*			EXOFS_DBGMSG("write sync=%d\n", sync);*/
+		} else if (ios->kern_buff) {
+			osd_req_write_kern(or, &ios->obj, ios->offset,
+					   ios->kern_buff, ios->length);
+/*			EXOFS_DBGMSG("write_kern sync=%d\n", sync);*/
+		} else {
+			osd_req_set_attributes(or, &ios->obj);
+/*			EXOFS_DBGMSG("set_attributes sync=%d\n", sync);*/
+		}
+
+		if (ios->out_attr)
+			osd_req_add_set_attr_list(or, ios->out_attr,
+						  ios->out_attr_len);
+
+		if (ios->in_attr)
+			osd_req_add_get_attr_list(or, ios->in_attr,
+						  ios->in_attr_len);
+	}
+	ret = exofs_io_execute(ios);
+
+out:
+	return ret;
+}
+
+int exofs_sbi_read(struct exofs_io_state *ios)
+{
+	int i, ret;
+
+	for (i = 0; i < 1; i++) {
+		struct osd_request *or;
+		unsigned first_dev = (unsigned)ios->obj.id;
+
+		first_dev %= ios->sbi->s_numdevs;
+		or = osd_start_request(ios->sbi->s_ods[first_dev], GFP_KERNEL);
+		if (unlikely(!or)) {
+			EXOFS_ERR("%s: osd_start_request failed\n", __func__);
+			ret = -ENOMEM;
+			goto out;
+		}
+		ios->per_dev[i].or = or;
+		ios->numdevs++;
+
+		if (ios->bio) {
+			osd_req_read(or, &ios->obj, ios->offset, ios->bio,
+				     ios->length);
+/*			EXOFS_DBGMSG("read sync=%d\n", sync);*/
+		} else if (ios->kern_buff) {
+			osd_req_read_kern(or, &ios->obj, ios->offset,
+					   ios->kern_buff, ios->length);
+/*			EXOFS_DBGMSG("read_kern sync=%d\n", sync);*/
+		} else {
+			osd_req_get_attributes(or, &ios->obj);
+/*			EXOFS_DBGMSG("get_attributes sync=%d\n", sync);*/
+		}
+
+		if (ios->out_attr)
+			osd_req_add_set_attr_list(or, ios->out_attr,
+						  ios->out_attr_len);
+
+		if (ios->in_attr)
+			osd_req_add_get_attr_list(or, ios->in_attr,
+						  ios->in_attr_len);
+	}
+	ret = exofs_io_execute(ios);
+
+out:
+	return ret;
+}
+
+int extract_attr_from_ios(struct exofs_io_state *ios, struct osd_attr *attr)
+{
+	struct osd_attr cur_attr = {.attr_page = 0}; /* start with zeros */
+	void *iter = NULL;
+	int nelem;
+
+	do {
+		nelem = 1;
+		osd_req_decode_get_attr_list(ios->per_dev[0].or,
+					     &cur_attr, &nelem, &iter);
+		if ((cur_attr.attr_page == attr->attr_page) &&
+		    (cur_attr.attr_id == attr->attr_id)) {
+			attr->len = cur_attr.len;
+			attr->val_ptr = cur_attr.val_ptr;
+			return 0;
+		}
+	} while (iter);
+
+	return -EIO;
+}
+
+int exofs_oi_truncate(struct exofs_i_info *oi, u64 size)
+{
+	struct exofs_sb_info *sbi = oi->vfs_inode.i_sb->s_fs_info;
+	struct exofs_io_state *ios;
+	struct osd_attr attr;
+	__be64 newsize;
+	int i, ret;
+
+	if (exofs_get_io_state(sbi, &ios))
+		return -ENOMEM;
+
+	ios->obj.id = exofs_oi_objno(oi);
+	ios->cred = oi->i_cred;
+
+	newsize = cpu_to_be64(size);
+	attr = g_attr_logical_length;
+	attr.val_ptr = &newsize;
+
+	for (i = 0; i < sbi->s_numdevs; i++) {
+		struct osd_request *or;
+
+		or = osd_start_request(sbi->s_ods[i], GFP_KERNEL);
+		if (unlikely(!or)) {
+			EXOFS_ERR("%s: osd_start_request failed\n", __func__);
+			ret = -ENOMEM;
+			goto out;
+		}
+		ios->per_dev[i].or = or;
+		ios->numdevs++;
+
+		osd_req_set_attributes(or, &ios->obj);
+		osd_req_add_set_attr_list(or, &attr, 1);
+	}
+	ret = exofs_io_execute(ios);
+
+out:
+	exofs_put_io_state(ios);
+	return ret;
+}
diff --git a/fs/exofs/osd.c b/fs/exofs/osd.c
deleted file mode 100644
index 4372542..0000000
--- a/fs/exofs/osd.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2005, 2006
- * Avishay Traeger (avishay@gmail.com)
- * Copyright (C) 2008, 2009
- * Boaz Harrosh <bharrosh@panasas.com>
- *
- * This file is part of exofs.
- *
- * exofs 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.  Since it is based on ext2, and the only
- * valid version of GPL for the Linux kernel is version 2, the only valid
- * version of GPL for exofs is version 2.
- *
- * exofs 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 exofs; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <scsi/scsi_device.h>
-#include <scsi/osd_sense.h>
-
-#include "exofs.h"
-
-int exofs_check_ok_resid(struct osd_request *or, u64 *in_resid, u64 *out_resid)
-{
-	struct osd_sense_info osi;
-	int ret = osd_req_decode_sense(or, &osi);
-
-	if (ret) { /* translate to Linux codes */
-		if (osi.additional_code == scsi_invalid_field_in_cdb) {
-			if (osi.cdb_field_offset == OSD_CFO_STARTING_BYTE)
-				ret = -EFAULT;
-			if (osi.cdb_field_offset == OSD_CFO_OBJECT_ID)
-				ret = -ENOENT;
-			else
-				ret = -EINVAL;
-		} else if (osi.additional_code == osd_quota_error)
-			ret = -ENOSPC;
-		else
-			ret = -EIO;
-	}
-
-	/* FIXME: should be include in osd_sense_info */
-	if (in_resid)
-		*in_resid = or->in.req ? or->in.req->resid_len : 0;
-
-	if (out_resid)
-		*out_resid = or->out.req ? or->out.req->resid_len : 0;
-
-	return ret;
-}
-
-void exofs_make_credential(u8 cred_a[OSD_CAP_LEN], const struct osd_obj_id *obj)
-{
-	osd_sec_init_nosec_doall_caps(cred_a, obj, false, true);
-}
-
-/*
- * Perform a synchronous OSD operation.
- */
-int exofs_sync_op(struct osd_request *or, int timeout, uint8_t *credential)
-{
-	int ret;
-
-	or->timeout = timeout;
-	ret = osd_finalize_request(or, 0, credential, NULL);
-	if (ret) {
-		EXOFS_DBGMSG("Faild to osd_finalize_request() => %d\n", ret);
-		return ret;
-	}
-
-	ret = osd_execute_request(or);
-
-	if (ret)
-		EXOFS_DBGMSG("osd_execute_request() => %d\n", ret);
-	/* osd_req_decode_sense(or, ret); */
-	return ret;
-}
-
-/*
- * Perform an asynchronous OSD operation.
- */
-int exofs_async_op(struct osd_request *or, osd_req_done_fn *async_done,
-		   void *caller_context, u8 *cred)
-{
-	int ret;
-
-	ret = osd_finalize_request(or, 0, cred, NULL);
-	if (ret) {
-		EXOFS_DBGMSG("Faild to osd_finalize_request() => %d\n", ret);
-		return ret;
-	}
-
-	ret = osd_execute_request_async(or, async_done, caller_context);
-
-	if (ret)
-		EXOFS_DBGMSG("osd_execute_request_async() => %d\n", ret);
-	return ret;
-}
-
-int extract_attr_from_req(struct osd_request *or, struct osd_attr *attr)
-{
-	struct osd_attr cur_attr = {.attr_page = 0}; /* start with zeros */
-	void *iter = NULL;
-	int nelem;
-
-	do {
-		nelem = 1;
-		osd_req_decode_get_attr_list(or, &cur_attr, &nelem, &iter);
-		if ((cur_attr.attr_page == attr->attr_page) &&
-		    (cur_attr.attr_id == attr->attr_id)) {
-			attr->len = cur_attr.len;
-			attr->val_ptr = cur_attr.val_ptr;
-			return 0;
-		}
-	} while (iter);
-
-	return -EIO;
-}
diff --git a/fs/exofs/pnfs.h b/fs/exofs/pnfs.h
new file mode 100644
index 0000000..423033a
--- /dev/null
+++ b/fs/exofs/pnfs.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008, 2009
+ * Boaz Harrosh <bharrosh@panasas.com>
+ *
+ * This file is part of exofs.
+ *
+ * exofs 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.
+ *
+ */
+
+/* FIXME: Remove this file once pnfs hits mainline */
+
+#ifndef __EXOFS_PNFS_H__
+#define __EXOFS_PNFS_H__
+
+#if defined(CONFIG_PNFS)
+
+
+/* FIXME: move this file to: linux/exportfs/pnfs_osd_xdr.h */
+#include "../nfs/objlayout/pnfs_osd_xdr.h"
+
+#else /* defined(CONFIG_PNFS) */
+
+enum pnfs_iomode {
+	IOMODE_READ = 1,
+	IOMODE_RW = 2,
+	IOMODE_ANY = 3,
+};
+
+/* Layout Structure */
+enum pnfs_osd_raid_algorithm4 {
+	PNFS_OSD_RAID_0		= 1,
+	PNFS_OSD_RAID_4		= 2,
+	PNFS_OSD_RAID_5		= 3,
+	PNFS_OSD_RAID_PQ	= 4     /* Reed-Solomon P+Q */
+};
+
+struct pnfs_osd_data_map {
+	u32	odm_num_comps;
+	u64	odm_stripe_unit;
+	u32	odm_group_width;
+	u32	odm_group_depth;
+	u32	odm_mirror_cnt;
+	u32	odm_raid_algorithm;
+};
+
+#endif /* else defined(CONFIG_PNFS) */
+
+#endif /* __EXOFS_PNFS_H__ */
diff --git a/fs/exofs/super.c b/fs/exofs/super.c
index 9f500de..a1d1e77 100644
--- a/fs/exofs/super.c
+++ b/fs/exofs/super.c
@@ -203,49 +203,45 @@
 {
 	struct exofs_sb_info *sbi;
 	struct exofs_fscb *fscb;
-	struct osd_request *or;
-	struct osd_obj_id obj;
+	struct exofs_io_state *ios;
 	int ret = -ENOMEM;
 
-	fscb = kzalloc(sizeof(struct exofs_fscb), GFP_KERNEL);
-	if (!fscb) {
-		EXOFS_ERR("exofs_write_super: memory allocation failed.\n");
-		return -ENOMEM;
-	}
-
 	lock_super(sb);
 	sbi = sb->s_fs_info;
+	fscb = &sbi->s_fscb;
+
+	ret = exofs_get_io_state(sbi, &ios);
+	if (ret)
+		goto out;
+
+	/* Note: We only write the changing part of the fscb. .i.e upto the
+	 *       the fscb->s_dev_table_oid member. There is no read-modify-write
+	 *       here.
+	 */
+	ios->length = offsetof(struct exofs_fscb, s_dev_table_oid);
+	memset(fscb, 0, ios->length);
 	fscb->s_nextid = cpu_to_le64(sbi->s_nextid);
 	fscb->s_numfiles = cpu_to_le32(sbi->s_numfiles);
 	fscb->s_magic = cpu_to_le16(sb->s_magic);
 	fscb->s_newfs = 0;
+	fscb->s_version = EXOFS_FSCB_VER;
 
-	or = osd_start_request(sbi->s_dev, GFP_KERNEL);
-	if (unlikely(!or)) {
-		EXOFS_ERR("exofs_write_super: osd_start_request failed.\n");
-		goto out;
-	}
+	ios->obj.id = EXOFS_SUPER_ID;
+	ios->offset = 0;
+	ios->kern_buff = fscb;
+	ios->cred = sbi->s_cred;
 
-	obj.partition = sbi->s_pid;
-	obj.id = EXOFS_SUPER_ID;
-	ret = osd_req_write_kern(or, &obj, 0, fscb, sizeof(*fscb));
+	ret = exofs_sbi_write(ios);
 	if (unlikely(ret)) {
-		EXOFS_ERR("exofs_write_super: osd_req_write_kern failed.\n");
-		goto out;
-	}
-
-	ret = exofs_sync_op(or, sbi->s_timeout, sbi->s_cred);
-	if (unlikely(ret)) {
-		EXOFS_ERR("exofs_write_super: exofs_sync_op failed.\n");
+		EXOFS_ERR("%s: exofs_sbi_write failed.\n", __func__);
 		goto out;
 	}
 	sb->s_dirt = 0;
 
 out:
-	if (or)
-		osd_end_request(or);
+	EXOFS_DBGMSG("s_nextid=0x%llx ret=%d\n", _LLU(sbi->s_nextid), ret);
+	exofs_put_io_state(ios);
 	unlock_super(sb);
-	kfree(fscb);
 	return ret;
 }
 
@@ -257,6 +253,29 @@
 		sb->s_dirt = 0;
 }
 
+static void _exofs_print_device(const char *msg, const char *dev_path,
+				struct osd_dev *od, u64 pid)
+{
+	const struct osd_dev_info *odi = osduld_device_info(od);
+
+	printk(KERN_NOTICE "exofs: %s %s osd_name-%s pid-0x%llx\n",
+		msg, dev_path ?: "", odi->osdname, _LLU(pid));
+}
+
+void exofs_free_sbi(struct exofs_sb_info *sbi)
+{
+	while (sbi->s_numdevs) {
+		int i = --sbi->s_numdevs;
+		struct osd_dev *od = sbi->s_ods[i];
+
+		if (od) {
+			sbi->s_ods[i] = NULL;
+			osduld_put_device(od);
+		}
+	}
+	kfree(sbi);
+}
+
 /*
  * This function is called when the vfs is freeing the superblock.  We just
  * need to free our own part.
@@ -279,11 +298,182 @@
 				  msecs_to_jiffies(100));
 	}
 
-	osduld_put_device(sbi->s_dev);
-	kfree(sb->s_fs_info);
+	_exofs_print_device("Unmounting", NULL, sbi->s_ods[0], sbi->s_pid);
+
+	exofs_free_sbi(sbi);
 	sb->s_fs_info = NULL;
 }
 
+static int _read_and_match_data_map(struct exofs_sb_info *sbi, unsigned numdevs,
+				    struct exofs_device_table *dt)
+{
+	sbi->data_map.odm_num_comps   =
+				le32_to_cpu(dt->dt_data_map.cb_num_comps);
+	sbi->data_map.odm_stripe_unit =
+				le64_to_cpu(dt->dt_data_map.cb_stripe_unit);
+	sbi->data_map.odm_group_width =
+				le32_to_cpu(dt->dt_data_map.cb_group_width);
+	sbi->data_map.odm_group_depth =
+				le32_to_cpu(dt->dt_data_map.cb_group_depth);
+	sbi->data_map.odm_mirror_cnt  =
+				le32_to_cpu(dt->dt_data_map.cb_mirror_cnt);
+	sbi->data_map.odm_raid_algorithm  =
+				le32_to_cpu(dt->dt_data_map.cb_raid_algorithm);
+
+/* FIXME: Hard coded mirror only for now. if not so do not mount */
+	if ((sbi->data_map.odm_num_comps != numdevs) ||
+	    (sbi->data_map.odm_stripe_unit != EXOFS_BLKSIZE) ||
+	    (sbi->data_map.odm_raid_algorithm != PNFS_OSD_RAID_0) ||
+	    (sbi->data_map.odm_mirror_cnt != (numdevs - 1)))
+		return -EINVAL;
+	else
+		return 0;
+}
+
+/* @odi is valid only as long as @fscb_dev is valid */
+static int exofs_devs_2_odi(struct exofs_dt_device_info *dt_dev,
+			     struct osd_dev_info *odi)
+{
+	odi->systemid_len = le32_to_cpu(dt_dev->systemid_len);
+	memcpy(odi->systemid, dt_dev->systemid, odi->systemid_len);
+
+	odi->osdname_len = le32_to_cpu(dt_dev->osdname_len);
+	odi->osdname = dt_dev->osdname;
+
+	/* FIXME support long names. Will need a _put function */
+	if (dt_dev->long_name_offset)
+		return -EINVAL;
+
+	/* Make sure osdname is printable!
+	 * mkexofs should give us space for a null-terminator else the
+	 * device-table is invalid.
+	 */
+	if (unlikely(odi->osdname_len >= sizeof(dt_dev->osdname)))
+		odi->osdname_len = sizeof(dt_dev->osdname) - 1;
+	dt_dev->osdname[odi->osdname_len] = 0;
+
+	/* If it's all zeros something is bad we read past end-of-obj */
+	return !(odi->systemid_len || odi->osdname_len);
+}
+
+static int exofs_read_lookup_dev_table(struct exofs_sb_info **psbi,
+				       unsigned table_count)
+{
+	struct exofs_sb_info *sbi = *psbi;
+	struct osd_dev *fscb_od;
+	struct osd_obj_id obj = {.partition = sbi->s_pid,
+				 .id = EXOFS_DEVTABLE_ID};
+	struct exofs_device_table *dt;
+	unsigned table_bytes = table_count * sizeof(dt->dt_dev_table[0]) +
+					     sizeof(*dt);
+	unsigned numdevs, i;
+	int ret;
+
+	dt = kmalloc(table_bytes, GFP_KERNEL);
+	if (unlikely(!dt)) {
+		EXOFS_ERR("ERROR: allocating %x bytes for device table\n",
+			  table_bytes);
+		return -ENOMEM;
+	}
+
+	fscb_od = sbi->s_ods[0];
+	sbi->s_ods[0] = NULL;
+	sbi->s_numdevs = 0;
+	ret = exofs_read_kern(fscb_od, sbi->s_cred, &obj, 0, dt, table_bytes);
+	if (unlikely(ret)) {
+		EXOFS_ERR("ERROR: reading device table\n");
+		goto out;
+	}
+
+	numdevs = le64_to_cpu(dt->dt_num_devices);
+	if (unlikely(!numdevs)) {
+		ret = -EINVAL;
+		goto out;
+	}
+	WARN_ON(table_count != numdevs);
+
+	ret = _read_and_match_data_map(sbi, numdevs, dt);
+	if (unlikely(ret))
+		goto out;
+
+	if (likely(numdevs > 1)) {
+		unsigned size = numdevs * sizeof(sbi->s_ods[0]);
+
+		sbi = krealloc(sbi, sizeof(*sbi) + size, GFP_KERNEL);
+		if (unlikely(!sbi)) {
+			ret = -ENOMEM;
+			goto out;
+		}
+		memset(&sbi->s_ods[1], 0, size - sizeof(sbi->s_ods[0]));
+		*psbi = sbi;
+	}
+
+	for (i = 0; i < numdevs; i++) {
+		struct exofs_fscb fscb;
+		struct osd_dev_info odi;
+		struct osd_dev *od;
+
+		if (exofs_devs_2_odi(&dt->dt_dev_table[i], &odi)) {
+			EXOFS_ERR("ERROR: Read all-zeros device entry\n");
+			ret = -EINVAL;
+			goto out;
+		}
+
+		printk(KERN_NOTICE "Add device[%d]: osd_name-%s\n",
+		       i, odi.osdname);
+
+		/* On all devices the device table is identical. The user can
+		 * specify any one of the participating devices on the command
+		 * line. We always keep them in device-table order.
+		 */
+		if (fscb_od && osduld_device_same(fscb_od, &odi)) {
+			sbi->s_ods[i] = fscb_od;
+			++sbi->s_numdevs;
+			fscb_od = NULL;
+			continue;
+		}
+
+		od = osduld_info_lookup(&odi);
+		if (unlikely(IS_ERR(od))) {
+			ret = PTR_ERR(od);
+			EXOFS_ERR("ERROR: device requested is not found "
+				  "osd_name-%s =>%d\n", odi.osdname, ret);
+			goto out;
+		}
+
+		sbi->s_ods[i] = od;
+		++sbi->s_numdevs;
+
+		/* Read the fscb of the other devices to make sure the FS
+		 * partition is there.
+		 */
+		ret = exofs_read_kern(od, sbi->s_cred, &obj, 0, &fscb,
+				      sizeof(fscb));
+		if (unlikely(ret)) {
+			EXOFS_ERR("ERROR: Malformed participating device "
+				  "error reading fscb osd_name-%s\n",
+				  odi.osdname);
+			goto out;
+		}
+
+		/* TODO: verify other information is correct and FS-uuid
+		 *	 matches. Benny what did you say about device table
+		 *	 generation and old devices?
+		 */
+	}
+
+out:
+	kfree(dt);
+	if (unlikely(!ret && fscb_od)) {
+		EXOFS_ERR(
+		      "ERROR: Bad device-table container device not present\n");
+		osduld_put_device(fscb_od);
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
 /*
  * Read the superblock from the OSD and fill in the fields
  */
@@ -292,24 +482,25 @@
 	struct inode *root;
 	struct exofs_mountopt *opts = data;
 	struct exofs_sb_info *sbi;	/*extended info                  */
+	struct osd_dev *od;		/* Master device                 */
 	struct exofs_fscb fscb;		/*on-disk superblock info        */
-	struct osd_request *or = NULL;
 	struct osd_obj_id obj;
+	unsigned table_count;
 	int ret;
 
 	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
 	if (!sbi)
 		return -ENOMEM;
-	sb->s_fs_info = sbi;
 
 	/* use mount options to fill superblock */
-	sbi->s_dev = osduld_path_lookup(opts->dev_name);
-	if (IS_ERR(sbi->s_dev)) {
-		ret = PTR_ERR(sbi->s_dev);
-		sbi->s_dev = NULL;
+	od = osduld_path_lookup(opts->dev_name);
+	if (IS_ERR(od)) {
+		ret = PTR_ERR(od);
 		goto free_sbi;
 	}
 
+	sbi->s_ods[0] = od;
+	sbi->s_numdevs = 1;
 	sbi->s_pid = opts->pid;
 	sbi->s_timeout = opts->timeout;
 
@@ -323,35 +514,13 @@
 	sb->s_bdev = NULL;
 	sb->s_dev = 0;
 
-	/* read data from on-disk superblock object */
 	obj.partition = sbi->s_pid;
 	obj.id = EXOFS_SUPER_ID;
 	exofs_make_credential(sbi->s_cred, &obj);
 
-	or = osd_start_request(sbi->s_dev, GFP_KERNEL);
-	if (unlikely(!or)) {
-		if (!silent)
-			EXOFS_ERR(
-			       "exofs_fill_super: osd_start_request failed.\n");
-		ret = -ENOMEM;
+	ret = exofs_read_kern(od, sbi->s_cred, &obj, 0, &fscb, sizeof(fscb));
+	if (unlikely(ret))
 		goto free_sbi;
-	}
-	ret = osd_req_read_kern(or, &obj, 0, &fscb, sizeof(fscb));
-	if (unlikely(ret)) {
-		if (!silent)
-			EXOFS_ERR(
-			       "exofs_fill_super: osd_req_read_kern failed.\n");
-		ret = -ENOMEM;
-		goto free_sbi;
-	}
-
-	ret = exofs_sync_op(or, sbi->s_timeout, sbi->s_cred);
-	if (unlikely(ret)) {
-		if (!silent)
-			EXOFS_ERR("exofs_fill_super: exofs_sync_op failed.\n");
-		ret = -EIO;
-		goto free_sbi;
-	}
 
 	sb->s_magic = le16_to_cpu(fscb.s_magic);
 	sbi->s_nextid = le64_to_cpu(fscb.s_nextid);
@@ -364,12 +533,26 @@
 		ret = -EINVAL;
 		goto free_sbi;
 	}
+	if (le32_to_cpu(fscb.s_version) != EXOFS_FSCB_VER) {
+		EXOFS_ERR("ERROR: Bad FSCB version expected-%d got-%d\n",
+			  EXOFS_FSCB_VER, le32_to_cpu(fscb.s_version));
+		ret = -EINVAL;
+		goto free_sbi;
+	}
 
 	/* start generation numbers from a random point */
 	get_random_bytes(&sbi->s_next_generation, sizeof(u32));
 	spin_lock_init(&sbi->s_next_gen_lock);
 
+	table_count = le64_to_cpu(fscb.s_dev_table_count);
+	if (table_count) {
+		ret = exofs_read_lookup_dev_table(&sbi, table_count);
+		if (unlikely(ret))
+			goto free_sbi;
+	}
+
 	/* set up operation vectors */
+	sb->s_fs_info = sbi;
 	sb->s_op = &exofs_sops;
 	sb->s_export_op = &exofs_export_ops;
 	root = exofs_iget(sb, EXOFS_ROOT_ID - EXOFS_OBJ_OFF);
@@ -395,16 +578,15 @@
 		goto free_sbi;
 	}
 
-	ret = 0;
-out:
-	if (or)
-		osd_end_request(or);
-	return ret;
+	_exofs_print_device("Mounting", opts->dev_name, sbi->s_ods[0],
+			    sbi->s_pid);
+	return 0;
 
 free_sbi:
-	osduld_put_device(sbi->s_dev); /* NULL safe */
-	kfree(sbi);
-	goto out;
+	EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n",
+		  opts->dev_name, sbi->s_pid, ret);
+	exofs_free_sbi(sbi);
+	return ret;
 }
 
 /*
@@ -433,7 +615,7 @@
 {
 	struct super_block *sb = dentry->d_sb;
 	struct exofs_sb_info *sbi = sb->s_fs_info;
-	struct osd_obj_id obj = {sbi->s_pid, 0};
+	struct exofs_io_state *ios;
 	struct osd_attr attrs[] = {
 		ATTR_DEF(OSD_APAGE_PARTITION_QUOTAS,
 			OSD_ATTR_PQ_CAPACITY_QUOTA, sizeof(__be64)),
@@ -442,32 +624,33 @@
 	};
 	uint64_t capacity = ULLONG_MAX;
 	uint64_t used = ULLONG_MAX;
-	struct osd_request *or;
 	uint8_t cred_a[OSD_CAP_LEN];
 	int ret;
 
-	/* get used/capacity attributes */
-	exofs_make_credential(cred_a, &obj);
-
-	or = osd_start_request(sbi->s_dev, GFP_KERNEL);
-	if (unlikely(!or)) {
-		EXOFS_DBGMSG("exofs_statfs: osd_start_request failed.\n");
-		return -ENOMEM;
+	ret = exofs_get_io_state(sbi, &ios);
+	if (ret) {
+		EXOFS_DBGMSG("exofs_get_io_state failed.\n");
+		return ret;
 	}
 
-	osd_req_get_attributes(or, &obj);
-	osd_req_add_get_attr_list(or, attrs, ARRAY_SIZE(attrs));
-	ret = exofs_sync_op(or, sbi->s_timeout, cred_a);
+	exofs_make_credential(cred_a, &ios->obj);
+	ios->cred = sbi->s_cred;
+	ios->in_attr = attrs;
+	ios->in_attr_len = ARRAY_SIZE(attrs);
+
+	ret = exofs_sbi_read(ios);
 	if (unlikely(ret))
 		goto out;
 
-	ret = extract_attr_from_req(or, &attrs[0]);
-	if (likely(!ret))
+	ret = extract_attr_from_ios(ios, &attrs[0]);
+	if (likely(!ret)) {
 		capacity = get_unaligned_be64(attrs[0].val_ptr);
-	else
+		if (unlikely(!capacity))
+			capacity = ULLONG_MAX;
+	} else
 		EXOFS_DBGMSG("exofs_statfs: get capacity failed.\n");
 
-	ret = extract_attr_from_req(or, &attrs[1]);
+	ret = extract_attr_from_ios(ios, &attrs[1]);
 	if (likely(!ret))
 		used = get_unaligned_be64(attrs[1].val_ptr);
 	else
@@ -476,15 +659,15 @@
 	/* fill in the stats buffer */
 	buf->f_type = EXOFS_SUPER_MAGIC;
 	buf->f_bsize = EXOFS_BLKSIZE;
-	buf->f_blocks = (capacity >> EXOFS_BLKSHIFT);
-	buf->f_bfree = ((capacity - used) >> EXOFS_BLKSHIFT);
+	buf->f_blocks = capacity >> 9;
+	buf->f_bfree = (capacity - used) >> 9;
 	buf->f_bavail = buf->f_bfree;
 	buf->f_files = sbi->s_numfiles;
 	buf->f_ffree = EXOFS_MAX_ID - sbi->s_numfiles;
 	buf->f_namelen = EXOFS_NAME_LEN;
 
 out:
-	osd_end_request(or);
+	exofs_put_io_state(ios);
 	return ret;
 }
 
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index 6cde970..fc2bd05 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -353,8 +353,8 @@
  *	ext2_find_entry()
  *
  * finds an entry in the specified directory with the wanted name. It
- * returns the page in which the entry was found, and the entry itself
- * (as a parameter - res_dir). Page is returned mapped and unlocked.
+ * returns the page in which the entry was found (as a parameter - res_page),
+ * and the entry itself. Page is returned mapped and unlocked.
  * Entry is guaranteed to be valid.
  */
 struct ext2_dir_entry_2 *ext2_find_entry (struct inode * dir,
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 9a8a8e2..da318b0 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -142,7 +142,7 @@
 /* super.c */
 extern void ext2_error (struct super_block *, const char *, const char *, ...)
 	__attribute__ ((format (printf, 3, 4)));
-extern void ext2_warning (struct super_block *, const char *, const char *, ...)
+extern void ext2_msg(struct super_block *, const char *, const char *, ...)
 	__attribute__ ((format (printf, 3, 4)));
 extern void ext2_update_dynamic_rev (struct super_block *sb);
 extern void ext2_write_super (struct super_block *);
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index ade6340..71b032c 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -137,7 +137,8 @@
 	int final = 0;
 
 	if (i_block < 0) {
-		ext2_warning (inode->i_sb, "ext2_block_to_path", "block < 0");
+		ext2_msg(inode->i_sb, KERN_WARNING,
+			"warning: %s: block < 0", __func__);
 	} else if (i_block < direct_blocks) {
 		offsets[n++] = i_block;
 		final = direct_blocks;
@@ -157,7 +158,8 @@
 		offsets[n++] = i_block & (ptrs - 1);
 		final = ptrs;
 	} else {
-		ext2_warning (inode->i_sb, "ext2_block_to_path", "block > big");
+		ext2_msg(inode->i_sb, KERN_WARNING,
+			"warning: %s: block is too big", __func__);
 	}
 	if (boundary)
 		*boundary = final - 1 - (i_block & (ptrs - 1));
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 1a9ffee..1388802 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -58,27 +58,27 @@
 	}
 
 	va_start(args, fmt);
-	printk(KERN_CRIT "EXT2-fs error (device %s): %s: ",sb->s_id, function);
+	printk(KERN_CRIT "EXT2-fs (%s): error: %s: ", sb->s_id, function);
 	vprintk(fmt, args);
 	printk("\n");
 	va_end(args);
 
 	if (test_opt(sb, ERRORS_PANIC))
-		panic("EXT2-fs panic from previous error\n");
+		panic("EXT2-fs: panic from previous error\n");
 	if (test_opt(sb, ERRORS_RO)) {
-		printk("Remounting filesystem read-only\n");
+		ext2_msg(sb, KERN_CRIT,
+			     "error: remounting filesystem read-only");
 		sb->s_flags |= MS_RDONLY;
 	}
 }
 
-void ext2_warning (struct super_block * sb, const char * function,
-		   const char * fmt, ...)
+void ext2_msg(struct super_block *sb, const char *prefix,
+		const char *fmt, ...)
 {
 	va_list args;
 
 	va_start(args, fmt);
-	printk(KERN_WARNING "EXT2-fs warning (device %s): %s: ",
-	       sb->s_id, function);
+	printk("%sEXT2-fs (%s): ", prefix, sb->s_id);
 	vprintk(fmt, args);
 	printk("\n");
 	va_end(args);
@@ -91,9 +91,9 @@
 	if (le32_to_cpu(es->s_rev_level) > EXT2_GOOD_OLD_REV)
 		return;
 
-	ext2_warning(sb, __func__,
-		     "updating to rev %d because of new feature flag, "
-		     "running e2fsck is recommended",
+	ext2_msg(sb, KERN_WARNING,
+		     "warning: updating to rev %d because of "
+		     "new feature flag, running e2fsck is recommended",
 		     EXT2_DYNAMIC_REV);
 
 	es->s_first_ino = cpu_to_le32(EXT2_GOOD_OLD_FIRST_INO);
@@ -419,10 +419,10 @@
 	{Opt_err, NULL}
 };
 
-static int parse_options (char * options,
-			  struct ext2_sb_info *sbi)
+static int parse_options(char *options, struct super_block *sb)
 {
-	char * p;
+	char *p;
+	struct ext2_sb_info *sbi = EXT2_SB(sb);
 	substring_t args[MAX_OPT_ARGS];
 	int option;
 
@@ -505,7 +505,8 @@
 #else
 		case Opt_user_xattr:
 		case Opt_nouser_xattr:
-			printk("EXT2 (no)user_xattr options not supported\n");
+			ext2_msg(sb, KERN_INFO, "(no)user_xattr options"
+				"not supported");
 			break;
 #endif
 #ifdef CONFIG_EXT2_FS_POSIX_ACL
@@ -518,14 +519,15 @@
 #else
 		case Opt_acl:
 		case Opt_noacl:
-			printk("EXT2 (no)acl options not supported\n");
+			ext2_msg(sb, KERN_INFO,
+				"(no)acl options not supported");
 			break;
 #endif
 		case Opt_xip:
 #ifdef CONFIG_EXT2_FS_XIP
 			set_opt (sbi->s_mount_opt, XIP);
 #else
-			printk("EXT2 xip option not supported\n");
+			ext2_msg(sb, KERN_INFO, "xip option not supported");
 #endif
 			break;
 
@@ -542,19 +544,18 @@
 		case Opt_quota:
 		case Opt_usrquota:
 		case Opt_grpquota:
-			printk(KERN_ERR
-				"EXT2-fs: quota operations not supported.\n");
-
+			ext2_msg(sb, KERN_INFO,
+				"quota operations not supported");
 			break;
 #endif
 
 		case Opt_reservation:
 			set_opt(sbi->s_mount_opt, RESERVATION);
-			printk("reservations ON\n");
+			ext2_msg(sb, KERN_INFO, "reservations ON");
 			break;
 		case Opt_noreservation:
 			clear_opt(sbi->s_mount_opt, RESERVATION);
-			printk("reservations OFF\n");
+			ext2_msg(sb, KERN_INFO, "reservations OFF");
 			break;
 		case Opt_ignore:
 			break;
@@ -573,34 +574,40 @@
 	struct ext2_sb_info *sbi = EXT2_SB(sb);
 
 	if (le32_to_cpu(es->s_rev_level) > EXT2_MAX_SUPP_REV) {
-		printk ("EXT2-fs warning: revision level too high, "
-			"forcing read-only mode\n");
+		ext2_msg(sb, KERN_ERR,
+			"error: revision level too high, "
+			"forcing read-only mode");
 		res = MS_RDONLY;
 	}
 	if (read_only)
 		return res;
 	if (!(sbi->s_mount_state & EXT2_VALID_FS))
-		printk ("EXT2-fs warning: mounting unchecked fs, "
-			"running e2fsck is recommended\n");
+		ext2_msg(sb, KERN_WARNING,
+			"warning: mounting unchecked fs, "
+			"running e2fsck is recommended");
 	else if ((sbi->s_mount_state & EXT2_ERROR_FS))
-		printk ("EXT2-fs warning: mounting fs with errors, "
-			"running e2fsck is recommended\n");
+		ext2_msg(sb, KERN_WARNING,
+			"warning: mounting fs with errors, "
+			"running e2fsck is recommended");
 	else if ((__s16) le16_to_cpu(es->s_max_mnt_count) >= 0 &&
 		 le16_to_cpu(es->s_mnt_count) >=
 		 (unsigned short) (__s16) le16_to_cpu(es->s_max_mnt_count))
-		printk ("EXT2-fs warning: maximal mount count reached, "
-			"running e2fsck is recommended\n");
+		ext2_msg(sb, KERN_WARNING,
+			"warning: maximal mount count reached, "
+			"running e2fsck is recommended");
 	else if (le32_to_cpu(es->s_checkinterval) &&
-		(le32_to_cpu(es->s_lastcheck) + le32_to_cpu(es->s_checkinterval) <= get_seconds()))
-		printk ("EXT2-fs warning: checktime reached, "
-			"running e2fsck is recommended\n");
+		(le32_to_cpu(es->s_lastcheck) +
+			le32_to_cpu(es->s_checkinterval) <= get_seconds()))
+		ext2_msg(sb, KERN_WARNING,
+			"warning: checktime reached, "
+			"running e2fsck is recommended");
 	if (!le16_to_cpu(es->s_max_mnt_count))
 		es->s_max_mnt_count = cpu_to_le16(EXT2_DFL_MAX_MNT_COUNT);
 	le16_add_cpu(&es->s_mnt_count, 1);
 	ext2_write_super(sb);
 	if (test_opt (sb, DEBUG))
-		printk ("[EXT II FS %s, %s, bs=%lu, fs=%lu, gc=%lu, "
-			"bpg=%lu, ipg=%lu, mo=%04lx]\n",
+		ext2_msg(sb, KERN_INFO, "%s, %s, bs=%lu, fs=%lu, gc=%lu, "
+			"bpg=%lu, ipg=%lu, mo=%04lx]",
 			EXT2FS_VERSION, EXT2FS_DATE, sb->s_blocksize,
 			sbi->s_frag_size,
 			sbi->s_groups_count,
@@ -767,7 +774,7 @@
 	 */
 	blocksize = sb_min_blocksize(sb, BLOCK_SIZE);
 	if (!blocksize) {
-		printk ("EXT2-fs: unable to set blocksize\n");
+		ext2_msg(sb, KERN_ERR, "error: unable to set blocksize");
 		goto failed_sbi;
 	}
 
@@ -783,7 +790,7 @@
 	}
 
 	if (!(bh = sb_bread(sb, logic_sb_block))) {
-		printk ("EXT2-fs: unable to read superblock\n");
+		ext2_msg(sb, KERN_ERR, "error: unable to read superblock");
 		goto failed_sbi;
 	}
 	/*
@@ -826,7 +833,7 @@
 	
 	set_opt(sbi->s_mount_opt, RESERVATION);
 
-	if (!parse_options ((char *) data, sbi))
+	if (!parse_options((char *) data, sb))
 		goto failed_mount;
 
 	sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
@@ -840,8 +847,9 @@
 	    (EXT2_HAS_COMPAT_FEATURE(sb, ~0U) ||
 	     EXT2_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||
 	     EXT2_HAS_INCOMPAT_FEATURE(sb, ~0U)))
-		printk("EXT2-fs warning: feature flags set on rev 0 fs, "
-		       "running e2fsck is recommended\n");
+		ext2_msg(sb, KERN_WARNING,
+			"warning: feature flags set on rev 0 fs, "
+			"running e2fsck is recommended");
 	/*
 	 * Check feature flags regardless of the revision level, since we
 	 * previously didn't change the revision level when setting the flags,
@@ -849,16 +857,16 @@
 	 */
 	features = EXT2_HAS_INCOMPAT_FEATURE(sb, ~EXT2_FEATURE_INCOMPAT_SUPP);
 	if (features) {
-		printk("EXT2-fs: %s: couldn't mount because of "
-		       "unsupported optional features (%x).\n",
-		       sb->s_id, le32_to_cpu(features));
+		ext2_msg(sb, KERN_ERR,	"error: couldn't mount because of "
+		       "unsupported optional features (%x)",
+			le32_to_cpu(features));
 		goto failed_mount;
 	}
 	if (!(sb->s_flags & MS_RDONLY) &&
 	    (features = EXT2_HAS_RO_COMPAT_FEATURE(sb, ~EXT2_FEATURE_RO_COMPAT_SUPP))){
-		printk("EXT2-fs: %s: couldn't mount RDWR because of "
-		       "unsupported optional features (%x).\n",
-		       sb->s_id, le32_to_cpu(features));
+		ext2_msg(sb, KERN_ERR, "error: couldn't mount RDWR because of "
+		       "unsupported optional features (%x)",
+		       le32_to_cpu(features));
 		goto failed_mount;
 	}
 
@@ -866,7 +874,8 @@
 
 	if (ext2_use_xip(sb) && blocksize != PAGE_SIZE) {
 		if (!silent)
-			printk("XIP: Unsupported blocksize\n");
+			ext2_msg(sb, KERN_ERR,
+				"error: unsupported blocksize for xip");
 		goto failed_mount;
 	}
 
@@ -875,7 +884,7 @@
 		brelse(bh);
 
 		if (!sb_set_blocksize(sb, blocksize)) {
-			printk(KERN_ERR "EXT2-fs: blocksize too small for device.\n");
+			ext2_msg(sb, KERN_ERR, "error: blocksize is too small");
 			goto failed_sbi;
 		}
 
@@ -883,14 +892,14 @@
 		offset = (sb_block*BLOCK_SIZE) % blocksize;
 		bh = sb_bread(sb, logic_sb_block);
 		if(!bh) {
-			printk("EXT2-fs: Couldn't read superblock on "
-			       "2nd try.\n");
+			ext2_msg(sb, KERN_ERR, "error: couldn't read"
+				"superblock on 2nd try");
 			goto failed_sbi;
 		}
 		es = (struct ext2_super_block *) (((char *)bh->b_data) + offset);
 		sbi->s_es = es;
 		if (es->s_magic != cpu_to_le16(EXT2_SUPER_MAGIC)) {
-			printk ("EXT2-fs: Magic mismatch, very weird !\n");
+			ext2_msg(sb, KERN_ERR, "error: magic mismatch");
 			goto failed_mount;
 		}
 	}
@@ -906,7 +915,8 @@
 		if ((sbi->s_inode_size < EXT2_GOOD_OLD_INODE_SIZE) ||
 		    !is_power_of_2(sbi->s_inode_size) ||
 		    (sbi->s_inode_size > blocksize)) {
-			printk ("EXT2-fs: unsupported inode size: %d\n",
+			ext2_msg(sb, KERN_ERR,
+				"error: unsupported inode size: %d",
 				sbi->s_inode_size);
 			goto failed_mount;
 		}
@@ -943,29 +953,33 @@
 
 	if (sb->s_blocksize != bh->b_size) {
 		if (!silent)
-			printk ("VFS: Unsupported blocksize on dev "
-				"%s.\n", sb->s_id);
+			ext2_msg(sb, KERN_ERR, "error: unsupported blocksize");
 		goto failed_mount;
 	}
 
 	if (sb->s_blocksize != sbi->s_frag_size) {
-		printk ("EXT2-fs: fragsize %lu != blocksize %lu (not supported yet)\n",
+		ext2_msg(sb, KERN_ERR,
+			"error: fragsize %lu != blocksize %lu"
+			"(not supported yet)",
 			sbi->s_frag_size, sb->s_blocksize);
 		goto failed_mount;
 	}
 
 	if (sbi->s_blocks_per_group > sb->s_blocksize * 8) {
-		printk ("EXT2-fs: #blocks per group too big: %lu\n",
+		ext2_msg(sb, KERN_ERR,
+			"error: #blocks per group too big: %lu",
 			sbi->s_blocks_per_group);
 		goto failed_mount;
 	}
 	if (sbi->s_frags_per_group > sb->s_blocksize * 8) {
-		printk ("EXT2-fs: #fragments per group too big: %lu\n",
+		ext2_msg(sb, KERN_ERR,
+			"error: #fragments per group too big: %lu",
 			sbi->s_frags_per_group);
 		goto failed_mount;
 	}
 	if (sbi->s_inodes_per_group > sb->s_blocksize * 8) {
-		printk ("EXT2-fs: #inodes per group too big: %lu\n",
+		ext2_msg(sb, KERN_ERR,
+			"error: #inodes per group too big: %lu",
 			sbi->s_inodes_per_group);
 		goto failed_mount;
 	}
@@ -979,13 +993,13 @@
 		   EXT2_DESC_PER_BLOCK(sb);
 	sbi->s_group_desc = kmalloc (db_count * sizeof (struct buffer_head *), GFP_KERNEL);
 	if (sbi->s_group_desc == NULL) {
-		printk ("EXT2-fs: not enough memory\n");
+		ext2_msg(sb, KERN_ERR, "error: not enough memory");
 		goto failed_mount;
 	}
 	bgl_lock_init(sbi->s_blockgroup_lock);
 	sbi->s_debts = kcalloc(sbi->s_groups_count, sizeof(*sbi->s_debts), GFP_KERNEL);
 	if (!sbi->s_debts) {
-		printk ("EXT2-fs: not enough memory\n");
+		ext2_msg(sb, KERN_ERR, "error: not enough memory");
 		goto failed_mount_group_desc;
 	}
 	for (i = 0; i < db_count; i++) {
@@ -994,12 +1008,13 @@
 		if (!sbi->s_group_desc[i]) {
 			for (j = 0; j < i; j++)
 				brelse (sbi->s_group_desc[j]);
-			printk ("EXT2-fs: unable to read group descriptors\n");
+			ext2_msg(sb, KERN_ERR,
+				"error: unable to read group descriptors");
 			goto failed_mount_group_desc;
 		}
 	}
 	if (!ext2_check_descriptors (sb)) {
-		printk ("EXT2-fs: group descriptors corrupted!\n");
+		ext2_msg(sb, KERN_ERR, "group descriptors corrupted");
 		goto failed_mount2;
 	}
 	sbi->s_gdb_count = db_count;
@@ -1032,7 +1047,7 @@
 				ext2_count_dirs(sb));
 	}
 	if (err) {
-		printk(KERN_ERR "EXT2-fs: insufficient memory\n");
+		ext2_msg(sb, KERN_ERR, "error: insufficient memory");
 		goto failed_mount3;
 	}
 	/*
@@ -1048,27 +1063,28 @@
 	}
 	if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) {
 		iput(root);
-		printk(KERN_ERR "EXT2-fs: corrupt root inode, run e2fsck\n");
+		ext2_msg(sb, KERN_ERR, "error: corrupt root inode, run e2fsck");
 		goto failed_mount3;
 	}
 
 	sb->s_root = d_alloc_root(root);
 	if (!sb->s_root) {
 		iput(root);
-		printk(KERN_ERR "EXT2-fs: get root inode failed\n");
+		ext2_msg(sb, KERN_ERR, "error: get root inode failed");
 		ret = -ENOMEM;
 		goto failed_mount3;
 	}
 	if (EXT2_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL))
-		ext2_warning(sb, __func__,
-			"mounting ext3 filesystem as ext2");
+		ext2_msg(sb, KERN_WARNING,
+			"warning: mounting ext3 filesystem as ext2");
 	ext2_setup_super (sb, es, sb->s_flags & MS_RDONLY);
 	return 0;
 
 cantfind_ext2:
 	if (!silent)
-		printk("VFS: Can't find an ext2 filesystem on dev %s.\n",
-		       sb->s_id);
+		ext2_msg(sb, KERN_ERR,
+			"error: can't find an ext2 filesystem on dev %s.",
+			sb->s_id);
 	goto failed_mount;
 failed_mount3:
 	percpu_counter_destroy(&sbi->s_freeblocks_counter);
@@ -1121,8 +1137,24 @@
 static int ext2_sync_fs(struct super_block *sb, int wait)
 {
 	struct ext2_super_block *es = EXT2_SB(sb)->s_es;
+	struct buffer_head *sbh = EXT2_SB(sb)->s_sbh;
 
 	lock_kernel();
+	if (buffer_write_io_error(sbh)) {
+		/*
+		 * Oh, dear.  A previous attempt to write the
+		 * superblock failed.  This could happen because the
+		 * USB device was yanked out.  Or it could happen to
+		 * be a transient write error and maybe the block will
+		 * be remapped.  Nothing we can do but to retry the
+		 * write and hope for the best.
+		 */
+		ext2_msg(sb, KERN_ERR,
+		       "previous I/O error to superblock detected\n");
+		clear_buffer_write_io_error(sbh);
+		set_buffer_uptodate(sbh);
+	}
+
 	if (es->s_state & cpu_to_le16(EXT2_VALID_FS)) {
 		ext2_debug("setting valid to 0\n");
 		es->s_state &= cpu_to_le16(~EXT2_VALID_FS);
@@ -1170,7 +1202,7 @@
 	/*
 	 * Allow the "check" option to be passed as a remount option.
 	 */
-	if (!parse_options (data, sbi)) {
+	if (!parse_options(data, sb)) {
 		err = -EINVAL;
 		goto restore_opts;
 	}
@@ -1182,7 +1214,8 @@
 				    EXT2_MOUNT_XIP if not */
 
 	if ((ext2_use_xip(sb)) && (sb->s_blocksize != PAGE_SIZE)) {
-		printk("XIP: Unsupported blocksize\n");
+		ext2_msg(sb, KERN_WARNING,
+			"warning: unsupported blocksize for xip");
 		err = -EINVAL;
 		goto restore_opts;
 	}
@@ -1191,8 +1224,8 @@
 	if (((sbi->s_mount_opt & EXT2_MOUNT_XIP) !=
 	    (old_mount_opt & EXT2_MOUNT_XIP)) &&
 	    invalidate_inodes(sb)) {
-		ext2_warning(sb, __func__, "refusing change of xip flag "
-			     "with busy inodes while remounting");
+		ext2_msg(sb, KERN_WARNING, "warning: refusing change of "
+			 "xip flag with busy inodes while remounting");
 		sbi->s_mount_opt &= ~EXT2_MOUNT_XIP;
 		sbi->s_mount_opt |= old_mount_opt & EXT2_MOUNT_XIP;
 	}
@@ -1216,9 +1249,10 @@
 		__le32 ret = EXT2_HAS_RO_COMPAT_FEATURE(sb,
 					       ~EXT2_FEATURE_RO_COMPAT_SUPP);
 		if (ret) {
-			printk("EXT2-fs: %s: couldn't remount RDWR because of "
-			       "unsupported optional features (%x).\n",
-			       sb->s_id, le32_to_cpu(ret));
+			ext2_msg(sb, KERN_WARNING,
+				"warning: couldn't remount RDWR because of "
+				"unsupported optional features (%x).",
+				le32_to_cpu(ret));
 			err = -EROFS;
 			goto restore_opts;
 		}
diff --git a/fs/ext2/xip.c b/fs/ext2/xip.c
index c18fbf3..322a56b 100644
--- a/fs/ext2/xip.c
+++ b/fs/ext2/xip.c
@@ -69,8 +69,9 @@
 	if ((sbi->s_mount_opt & EXT2_MOUNT_XIP) &&
 	    !sb->s_bdev->bd_disk->fops->direct_access) {
 		sbi->s_mount_opt &= (~EXT2_MOUNT_XIP);
-		ext2_warning(sb, __func__,
-			     "ignoring xip option - not supported by bdev");
+		ext2_msg(sb, KERN_WARNING,
+			     "warning: ignoring xip option - "
+			     "not supported by bdev");
 	}
 }
 
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 354ed3b..ad14227 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -1151,6 +1151,16 @@
 	return ext3_journal_get_write_access(handle, bh);
 }
 
+/*
+ * Truncate blocks that were not used by write. We have to truncate the
+ * pagecache as well so that corresponding buffers get properly unmapped.
+ */
+static void ext3_truncate_failed_write(struct inode *inode)
+{
+	truncate_inode_pages(inode->i_mapping, inode->i_size);
+	ext3_truncate(inode);
+}
+
 static int ext3_write_begin(struct file *file, struct address_space *mapping,
 				loff_t pos, unsigned len, unsigned flags,
 				struct page **pagep, void **fsdata)
@@ -1209,7 +1219,7 @@
 		unlock_page(page);
 		page_cache_release(page);
 		if (pos + len > inode->i_size)
-			ext3_truncate(inode);
+			ext3_truncate_failed_write(inode);
 	}
 	if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries))
 		goto retry;
@@ -1304,7 +1314,7 @@
 	page_cache_release(page);
 
 	if (pos + len > inode->i_size)
-		ext3_truncate(inode);
+		ext3_truncate_failed_write(inode);
 	return ret ? ret : copied;
 }
 
@@ -1330,7 +1340,7 @@
 	page_cache_release(page);
 
 	if (pos + len > inode->i_size)
-		ext3_truncate(inode);
+		ext3_truncate_failed_write(inode);
 	return ret ? ret : copied;
 }
 
@@ -1383,7 +1393,7 @@
 	page_cache_release(page);
 
 	if (pos + len > inode->i_size)
-		ext3_truncate(inode);
+		ext3_truncate_failed_write(inode);
 	return ret ? ret : copied;
 }
 
@@ -2033,7 +2043,7 @@
 	int k, err;
 
 	*top = 0;
-	/* Make k index the deepest non-null offest + 1 */
+	/* Make k index the deepest non-null offset + 1 */
 	for (k = depth; k > 1 && !offsets[k-1]; k--)
 		;
 	partial = ext3_get_branch(inode, k, offsets, chain, &err);
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
index 8359e7b..5f83b61 100644
--- a/fs/ext3/resize.c
+++ b/fs/ext3/resize.c
@@ -266,7 +266,7 @@
 			goto exit_bh;
 
 		if (IS_ERR(gdb = bclean(handle, sb, block))) {
-			err = PTR_ERR(bh);
+			err = PTR_ERR(gdb);
 			goto exit_bh;
 		}
 		ext3_journal_dirty_metadata(handle, gdb);
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 427496c..7ad1e8c 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -135,12 +135,24 @@
 	if (is_handle_aborted(handle))
 		return;
 
-	printk(KERN_ERR "%s: aborting transaction: %s in %s\n",
-	       caller, errstr, err_fn);
+	printk(KERN_ERR "EXT3-fs: %s: aborting transaction: %s in %s\n",
+		caller, errstr, err_fn);
 
 	journal_abort_handle(handle);
 }
 
+void ext3_msg(struct super_block *sb, const char *prefix,
+		const char *fmt, ...)
+{
+	va_list args;
+
+	va_start(args, fmt);
+	printk("%sEXT3-fs (%s): ", prefix, sb->s_id);
+	vprintk(fmt, args);
+	printk("\n");
+	va_end(args);
+}
+
 /* Deal with the reporting of failure conditions on a filesystem such as
  * inconsistencies detected or read IO failures.
  *
@@ -174,12 +186,13 @@
 			journal_abort(journal, -EIO);
 	}
 	if (test_opt (sb, ERRORS_RO)) {
-		printk (KERN_CRIT "Remounting filesystem read-only\n");
+		ext3_msg(sb, KERN_CRIT,
+			"error: remounting filesystem read-only");
 		sb->s_flags |= MS_RDONLY;
 	}
 	ext3_commit_super(sb, es, 1);
 	if (test_opt(sb, ERRORS_PANIC))
-		panic("EXT3-fs (device %s): panic forced after error\n",
+		panic("EXT3-fs (%s): panic forced after error\n",
 			sb->s_id);
 }
 
@@ -247,8 +260,7 @@
 		return;
 
 	errstr = ext3_decode_error(sb, errno, nbuf);
-	printk (KERN_CRIT "EXT3-fs error (device %s) in %s: %s\n",
-		sb->s_id, function, errstr);
+	ext3_msg(sb, KERN_CRIT, "error in %s: %s", function, errstr);
 
 	ext3_handle_error(sb);
 }
@@ -268,21 +280,20 @@
 {
 	va_list args;
 
-	printk (KERN_CRIT "ext3_abort called.\n");
-
 	va_start(args, fmt);
-	printk(KERN_CRIT "EXT3-fs error (device %s): %s: ",sb->s_id, function);
+	printk(KERN_CRIT "EXT3-fs (%s): error: %s: ", sb->s_id, function);
 	vprintk(fmt, args);
 	printk("\n");
 	va_end(args);
 
 	if (test_opt(sb, ERRORS_PANIC))
-		panic("EXT3-fs panic from previous error\n");
+		panic("EXT3-fs: panic from previous error\n");
 
 	if (sb->s_flags & MS_RDONLY)
 		return;
 
-	printk(KERN_CRIT "Remounting filesystem read-only\n");
+	ext3_msg(sb, KERN_CRIT,
+		"error: remounting filesystem read-only");
 	EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS;
 	sb->s_flags |= MS_RDONLY;
 	EXT3_SB(sb)->s_mount_opt |= EXT3_MOUNT_ABORT;
@@ -296,7 +307,7 @@
 	va_list args;
 
 	va_start(args, fmt);
-	printk(KERN_WARNING "EXT3-fs warning (device %s): %s: ",
+	printk(KERN_WARNING "EXT3-fs (%s): warning: %s: ",
 	       sb->s_id, function);
 	vprintk(fmt, args);
 	printk("\n");
@@ -310,10 +321,10 @@
 	if (le32_to_cpu(es->s_rev_level) > EXT3_GOOD_OLD_REV)
 		return;
 
-	ext3_warning(sb, __func__,
-		     "updating to rev %d because of new feature flag, "
-		     "running e2fsck is recommended",
-		     EXT3_DYNAMIC_REV);
+	ext3_msg(sb, KERN_WARNING,
+		"warning: updating to rev %d because of "
+		"new feature flag, running e2fsck is recommended",
+		EXT3_DYNAMIC_REV);
 
 	es->s_first_ino = cpu_to_le32(EXT3_GOOD_OLD_FIRST_INO);
 	es->s_inode_size = cpu_to_le16(EXT3_GOOD_OLD_INODE_SIZE);
@@ -331,7 +342,7 @@
 /*
  * Open the external journal device
  */
-static struct block_device *ext3_blkdev_get(dev_t dev)
+static struct block_device *ext3_blkdev_get(dev_t dev, struct super_block *sb)
 {
 	struct block_device *bdev;
 	char b[BDEVNAME_SIZE];
@@ -342,8 +353,9 @@
 	return bdev;
 
 fail:
-	printk(KERN_ERR "EXT3: failed to open journal device %s: %ld\n",
-			__bdevname(dev, b), PTR_ERR(bdev));
+	ext3_msg(sb, "error: failed to open journal device %s: %ld",
+		__bdevname(dev, b), PTR_ERR(bdev));
+
 	return NULL;
 }
 
@@ -378,13 +390,13 @@
 {
 	struct list_head *l;
 
-	printk(KERN_ERR "sb orphan head is %d\n",
+	ext3_msg(sb, KERN_ERR, "error: sb orphan head is %d",
 	       le32_to_cpu(sbi->s_es->s_last_orphan));
 
-	printk(KERN_ERR "sb_info orphan list:\n");
+	ext3_msg(sb, KERN_ERR, "sb_info orphan list:");
 	list_for_each(l, &sbi->s_orphan) {
 		struct inode *inode = orphan_list_entry(l);
-		printk(KERN_ERR "  "
+		ext3_msg(sb, KERN_ERR, "  "
 		       "inode %s:%lu at %p: mode %o, nlink %d, next %d\n",
 		       inode->i_sb->s_id, inode->i_ino, inode,
 		       inode->i_mode, inode->i_nlink,
@@ -527,9 +539,22 @@
 #if defined(CONFIG_QUOTA)
 	struct ext3_sb_info *sbi = EXT3_SB(sb);
 
-	if (sbi->s_jquota_fmt)
-		seq_printf(seq, ",jqfmt=%s",
-		(sbi->s_jquota_fmt == QFMT_VFS_OLD) ? "vfsold": "vfsv0");
+	if (sbi->s_jquota_fmt) {
+		char *fmtname = "";
+
+		switch (sbi->s_jquota_fmt) {
+		case QFMT_VFS_OLD:
+			fmtname = "vfsold";
+			break;
+		case QFMT_VFS_V0:
+			fmtname = "vfsv0";
+			break;
+		case QFMT_VFS_V1:
+			fmtname = "vfsv1";
+			break;
+		}
+		seq_printf(seq, ",jqfmt=%s", fmtname);
+	}
 
 	if (sbi->s_qf_names[USRQUOTA])
 		seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]);
@@ -636,6 +661,9 @@
 	if (test_opt(sb, DATA_ERR_ABORT))
 		seq_puts(seq, ",data_err=abort");
 
+	if (test_opt(sb, NOLOAD))
+		seq_puts(seq, ",norecovery");
+
 	ext3_show_quota_options(seq, sb);
 
 	return 0;
@@ -787,9 +815,9 @@
 	Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
 	Opt_data_err_abort, Opt_data_err_ignore,
 	Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
-	Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
-	Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
-	Opt_grpquota
+	Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota,
+	Opt_noquota, Opt_ignore, Opt_barrier, Opt_err, Opt_resize,
+	Opt_usrquota, Opt_grpquota
 };
 
 static const match_table_t tokens = {
@@ -818,6 +846,7 @@
 	{Opt_reservation, "reservation"},
 	{Opt_noreservation, "noreservation"},
 	{Opt_noload, "noload"},
+	{Opt_noload, "norecovery"},
 	{Opt_nobh, "nobh"},
 	{Opt_bh, "bh"},
 	{Opt_commit, "commit=%u"},
@@ -836,6 +865,7 @@
 	{Opt_grpjquota, "grpjquota=%s"},
 	{Opt_jqfmt_vfsold, "jqfmt=vfsold"},
 	{Opt_jqfmt_vfsv0, "jqfmt=vfsv0"},
+	{Opt_jqfmt_vfsv1, "jqfmt=vfsv1"},
 	{Opt_grpquota, "grpquota"},
 	{Opt_noquota, "noquota"},
 	{Opt_quota, "quota"},
@@ -845,7 +875,7 @@
 	{Opt_err, NULL},
 };
 
-static ext3_fsblk_t get_sb_block(void **data)
+static ext3_fsblk_t get_sb_block(void **data, struct super_block *sb)
 {
 	ext3_fsblk_t	sb_block;
 	char		*options = (char *) *data;
@@ -856,7 +886,7 @@
 	/*todo: use simple_strtoll with >32bit ext3 */
 	sb_block = simple_strtoul(options, &options, 0);
 	if (*options && *options != ',') {
-		printk("EXT3-fs: Invalid sb specification: %s\n",
+		ext3_msg(sb, "error: invalid sb specification: %s",
 		       (char *) *data);
 		return 1;
 	}
@@ -956,7 +986,8 @@
 #else
 		case Opt_user_xattr:
 		case Opt_nouser_xattr:
-			printk("EXT3 (no)user_xattr options not supported\n");
+			ext3_msg(sb, KERN_INFO,
+				"(no)user_xattr options not supported");
 			break;
 #endif
 #ifdef CONFIG_EXT3_FS_POSIX_ACL
@@ -969,7 +1000,8 @@
 #else
 		case Opt_acl:
 		case Opt_noacl:
-			printk("EXT3 (no)acl options not supported\n");
+			ext3_msg(sb, KERN_INFO,
+				"(no)acl options not supported");
 			break;
 #endif
 		case Opt_reservation:
@@ -985,16 +1017,16 @@
 			   user to specify an existing inode to be the
 			   journal file. */
 			if (is_remount) {
-				printk(KERN_ERR "EXT3-fs: cannot specify "
-				       "journal on remount\n");
+				ext3_msg(sb, KERN_ERR, "error: cannot specify "
+					"journal on remount");
 				return 0;
 			}
 			set_opt (sbi->s_mount_opt, UPDATE_JOURNAL);
 			break;
 		case Opt_journal_inum:
 			if (is_remount) {
-				printk(KERN_ERR "EXT3-fs: cannot specify "
-				       "journal on remount\n");
+				ext3_msg(sb, KERN_ERR, "error: cannot specify "
+				       "journal on remount");
 				return 0;
 			}
 			if (match_int(&args[0], &option))
@@ -1003,8 +1035,8 @@
 			break;
 		case Opt_journal_dev:
 			if (is_remount) {
-				printk(KERN_ERR "EXT3-fs: cannot specify "
-				       "journal on remount\n");
+				ext3_msg(sb, KERN_ERR, "error: cannot specify "
+				       "journal on remount");
 				return 0;
 			}
 			if (match_int(&args[0], &option))
@@ -1036,12 +1068,11 @@
 				if ((sbi->s_mount_opt & EXT3_MOUNT_DATA_FLAGS)
 						== data_opt)
 					break;
-				printk(KERN_ERR
-					"EXT3-fs (device %s): Cannot change "
+				ext3_msg(sb, KERN_ERR,
+					"error: cannot change "
 					"data mode on remount. The filesystem "
 					"is mounted in data=%s mode and you "
-					"try to remount it in data=%s mode.\n",
-					sb->s_id,
+					"try to remount it in data=%s mode.",
 					data_mode_string(sbi->s_mount_opt &
 							EXT3_MOUNT_DATA_FLAGS),
 					data_mode_string(data_opt));
@@ -1066,31 +1097,31 @@
 set_qf_name:
 			if (sb_any_quota_loaded(sb) &&
 			    !sbi->s_qf_names[qtype]) {
-				printk(KERN_ERR
-					"EXT3-fs: Cannot change journaled "
-					"quota options when quota turned on.\n");
+				ext3_msg(sb, KERN_ERR,
+					"error: cannot change journaled "
+					"quota options when quota turned on.");
 				return 0;
 			}
 			qname = match_strdup(&args[0]);
 			if (!qname) {
-				printk(KERN_ERR
-					"EXT3-fs: not enough memory for "
-					"storing quotafile name.\n");
+				ext3_msg(sb, KERN_ERR,
+					"error: not enough memory for "
+					"storing quotafile name.");
 				return 0;
 			}
 			if (sbi->s_qf_names[qtype] &&
 			    strcmp(sbi->s_qf_names[qtype], qname)) {
-				printk(KERN_ERR
-					"EXT3-fs: %s quota file already "
-					"specified.\n", QTYPE2NAME(qtype));
+				ext3_msg(sb, KERN_ERR,
+					"error: %s quota file already "
+					"specified.", QTYPE2NAME(qtype));
 				kfree(qname);
 				return 0;
 			}
 			sbi->s_qf_names[qtype] = qname;
 			if (strchr(sbi->s_qf_names[qtype], '/')) {
-				printk(KERN_ERR
-					"EXT3-fs: quotafile must be on "
-					"filesystem root.\n");
+				ext3_msg(sb, KERN_ERR,
+					"error: quotafile must be on "
+					"filesystem root.");
 				kfree(sbi->s_qf_names[qtype]);
 				sbi->s_qf_names[qtype] = NULL;
 				return 0;
@@ -1105,9 +1136,9 @@
 clear_qf_name:
 			if (sb_any_quota_loaded(sb) &&
 			    sbi->s_qf_names[qtype]) {
-				printk(KERN_ERR "EXT3-fs: Cannot change "
+				ext3_msg(sb, KERN_ERR, "error: cannot change "
 					"journaled quota options when "
-					"quota turned on.\n");
+					"quota turned on.");
 				return 0;
 			}
 			/*
@@ -1121,12 +1152,15 @@
 			goto set_qf_format;
 		case Opt_jqfmt_vfsv0:
 			qfmt = QFMT_VFS_V0;
+			goto set_qf_format;
+		case Opt_jqfmt_vfsv1:
+			qfmt = QFMT_VFS_V1;
 set_qf_format:
 			if (sb_any_quota_loaded(sb) &&
 			    sbi->s_jquota_fmt != qfmt) {
-				printk(KERN_ERR "EXT3-fs: Cannot change "
+				ext3_msg(sb, KERN_ERR, "error: cannot change "
 					"journaled quota options when "
-					"quota turned on.\n");
+					"quota turned on.");
 				return 0;
 			}
 			sbi->s_jquota_fmt = qfmt;
@@ -1142,8 +1176,8 @@
 			break;
 		case Opt_noquota:
 			if (sb_any_quota_loaded(sb)) {
-				printk(KERN_ERR "EXT3-fs: Cannot change quota "
-					"options when quota turned on.\n");
+				ext3_msg(sb, KERN_ERR, "error: cannot change "
+					"quota options when quota turned on.");
 				return 0;
 			}
 			clear_opt(sbi->s_mount_opt, QUOTA);
@@ -1154,8 +1188,8 @@
 		case Opt_quota:
 		case Opt_usrquota:
 		case Opt_grpquota:
-			printk(KERN_ERR
-				"EXT3-fs: quota options not supported.\n");
+			ext3_msg(sb, KERN_ERR,
+				"error: quota options not supported.");
 			break;
 		case Opt_usrjquota:
 		case Opt_grpjquota:
@@ -1163,9 +1197,10 @@
 		case Opt_offgrpjquota:
 		case Opt_jqfmt_vfsold:
 		case Opt_jqfmt_vfsv0:
-			printk(KERN_ERR
-				"EXT3-fs: journaled quota options not "
-				"supported.\n");
+		case Opt_jqfmt_vfsv1:
+			ext3_msg(sb, KERN_ERR,
+				"error: journaled quota options not "
+				"supported.");
 			break;
 		case Opt_noquota:
 			break;
@@ -1185,8 +1220,9 @@
 			break;
 		case Opt_resize:
 			if (!is_remount) {
-				printk("EXT3-fs: resize option only available "
-					"for remount\n");
+				ext3_msg(sb, KERN_ERR,
+					"error: resize option only available "
+					"for remount");
 				return 0;
 			}
 			if (match_int(&args[0], &option) != 0)
@@ -1200,9 +1236,9 @@
 			clear_opt(sbi->s_mount_opt, NOBH);
 			break;
 		default:
-			printk (KERN_ERR
-				"EXT3-fs: Unrecognized mount option \"%s\" "
-				"or missing value\n", p);
+			ext3_msg(sb, KERN_ERR,
+				"error: unrecognized mount option \"%s\" "
+				"or missing value", p);
 			return 0;
 		}
 	}
@@ -1220,21 +1256,21 @@
 				(sbi->s_mount_opt & EXT3_MOUNT_GRPQUOTA)) ||
 		    (sbi->s_qf_names[GRPQUOTA] &&
 				(sbi->s_mount_opt & EXT3_MOUNT_USRQUOTA))) {
-			printk(KERN_ERR "EXT3-fs: old and new quota "
-					"format mixing.\n");
+			ext3_msg(sb, KERN_ERR, "error: old and new quota "
+					"format mixing.");
 			return 0;
 		}
 
 		if (!sbi->s_jquota_fmt) {
-			printk(KERN_ERR "EXT3-fs: journaled quota format "
-					"not specified.\n");
+			ext3_msg(sb, KERN_ERR, "error: journaled quota format "
+					"not specified.");
 			return 0;
 		}
 	} else {
 		if (sbi->s_jquota_fmt) {
-			printk(KERN_ERR "EXT3-fs: journaled quota format "
+			ext3_msg(sb, KERN_ERR, "error: journaled quota format "
 					"specified with no journaling "
-					"enabled.\n");
+					"enabled.");
 			return 0;
 		}
 	}
@@ -1249,31 +1285,33 @@
 	int res = 0;
 
 	if (le32_to_cpu(es->s_rev_level) > EXT3_MAX_SUPP_REV) {
-		printk (KERN_ERR "EXT3-fs warning: revision level too high, "
-			"forcing read-only mode\n");
+		ext3_msg(sb, KERN_ERR,
+			"error: revision level too high, "
+			"forcing read-only mode");
 		res = MS_RDONLY;
 	}
 	if (read_only)
 		return res;
 	if (!(sbi->s_mount_state & EXT3_VALID_FS))
-		printk (KERN_WARNING "EXT3-fs warning: mounting unchecked fs, "
-			"running e2fsck is recommended\n");
+		ext3_msg(sb, KERN_WARNING,
+			"warning: mounting unchecked fs, "
+			"running e2fsck is recommended");
 	else if ((sbi->s_mount_state & EXT3_ERROR_FS))
-		printk (KERN_WARNING
-			"EXT3-fs warning: mounting fs with errors, "
-			"running e2fsck is recommended\n");
+		ext3_msg(sb, KERN_WARNING,
+			"warning: mounting fs with errors, "
+			"running e2fsck is recommended");
 	else if ((__s16) le16_to_cpu(es->s_max_mnt_count) >= 0 &&
 		 le16_to_cpu(es->s_mnt_count) >=
 		 (unsigned short) (__s16) le16_to_cpu(es->s_max_mnt_count))
-		printk (KERN_WARNING
-			"EXT3-fs warning: maximal mount count reached, "
-			"running e2fsck is recommended\n");
+		ext3_msg(sb, KERN_WARNING,
+			"warning: maximal mount count reached, "
+			"running e2fsck is recommended");
 	else if (le32_to_cpu(es->s_checkinterval) &&
 		(le32_to_cpu(es->s_lastcheck) +
 			le32_to_cpu(es->s_checkinterval) <= get_seconds()))
-		printk (KERN_WARNING
-			"EXT3-fs warning: checktime reached, "
-			"running e2fsck is recommended\n");
+		ext3_msg(sb, KERN_WARNING,
+			"warning: checktime reached, "
+			"running e2fsck is recommended");
 #if 0
 		/* @@@ We _will_ want to clear the valid bit if we find
                    inconsistencies, to force a fsck at reboot.  But for
@@ -1290,22 +1328,20 @@
 
 	ext3_commit_super(sb, es, 1);
 	if (test_opt(sb, DEBUG))
-		printk(KERN_INFO "[EXT3 FS bs=%lu, gc=%lu, "
-				"bpg=%lu, ipg=%lu, mo=%04lx]\n",
+		ext3_msg(sb, KERN_INFO, "[bs=%lu, gc=%lu, "
+				"bpg=%lu, ipg=%lu, mo=%04lx]",
 			sb->s_blocksize,
 			sbi->s_groups_count,
 			EXT3_BLOCKS_PER_GROUP(sb),
 			EXT3_INODES_PER_GROUP(sb),
 			sbi->s_mount_opt);
 
-	printk(KERN_INFO "EXT3 FS on %s, ", sb->s_id);
 	if (EXT3_SB(sb)->s_journal->j_inode == NULL) {
 		char b[BDEVNAME_SIZE];
-
-		printk("external journal on %s\n",
+		ext3_msg(sb, KERN_INFO, "using external journal on %s",
 			bdevname(EXT3_SB(sb)->s_journal->j_dev, b));
 	} else {
-		printk("internal journal\n");
+		ext3_msg(sb, KERN_INFO, "using internal journal");
 	}
 	return res;
 }
@@ -1399,8 +1435,8 @@
 	}
 
 	if (bdev_read_only(sb->s_bdev)) {
-		printk(KERN_ERR "EXT3-fs: write access "
-			"unavailable, skipping orphan cleanup.\n");
+		ext3_msg(sb, KERN_ERR, "error: write access "
+			"unavailable, skipping orphan cleanup.");
 		return;
 	}
 
@@ -1414,8 +1450,7 @@
 	}
 
 	if (s_flags & MS_RDONLY) {
-		printk(KERN_INFO "EXT3-fs: %s: orphan cleanup on readonly fs\n",
-		       sb->s_id);
+		ext3_msg(sb, KERN_INFO, "orphan cleanup on readonly fs");
 		sb->s_flags &= ~MS_RDONLY;
 	}
 #ifdef CONFIG_QUOTA
@@ -1426,9 +1461,9 @@
 		if (EXT3_SB(sb)->s_qf_names[i]) {
 			int ret = ext3_quota_on_mount(sb, i);
 			if (ret < 0)
-				printk(KERN_ERR
-					"EXT3-fs: Cannot turn on journaled "
-					"quota: error %d\n", ret);
+				ext3_msg(sb, KERN_ERR,
+					"error: cannot turn on journaled "
+					"quota: %d", ret);
 		}
 	}
 #endif
@@ -1466,11 +1501,11 @@
 #define PLURAL(x) (x), ((x)==1) ? "" : "s"
 
 	if (nr_orphans)
-		printk(KERN_INFO "EXT3-fs: %s: %d orphan inode%s deleted\n",
-		       sb->s_id, PLURAL(nr_orphans));
+		ext3_msg(sb, KERN_INFO, "%d orphan inode%s deleted",
+		       PLURAL(nr_orphans));
 	if (nr_truncates)
-		printk(KERN_INFO "EXT3-fs: %s: %d truncate%s cleaned up\n",
-		       sb->s_id, PLURAL(nr_truncates));
+		ext3_msg(sb, KERN_INFO, "%d truncate%s cleaned up",
+		       PLURAL(nr_truncates));
 #ifdef CONFIG_QUOTA
 	/* Turn quotas off */
 	for (i = 0; i < MAXQUOTAS; i++) {
@@ -1554,7 +1589,7 @@
 	struct ext3_super_block *es = NULL;
 	struct ext3_sb_info *sbi;
 	ext3_fsblk_t block;
-	ext3_fsblk_t sb_block = get_sb_block(&data);
+	ext3_fsblk_t sb_block = get_sb_block(&data, sb);
 	ext3_fsblk_t logic_sb_block;
 	unsigned long offset = 0;
 	unsigned int journal_inum = 0;
@@ -1590,7 +1625,7 @@
 
 	blocksize = sb_min_blocksize(sb, EXT3_MIN_BLOCK_SIZE);
 	if (!blocksize) {
-		printk(KERN_ERR "EXT3-fs: unable to set blocksize\n");
+		ext3_msg(sb, KERN_ERR, "error: unable to set blocksize");
 		goto out_fail;
 	}
 
@@ -1606,7 +1641,7 @@
 	}
 
 	if (!(bh = sb_bread(sb, logic_sb_block))) {
-		printk (KERN_ERR "EXT3-fs: unable to read superblock\n");
+		ext3_msg(sb, KERN_ERR, "error: unable to read superblock");
 		goto out_fail;
 	}
 	/*
@@ -1665,9 +1700,9 @@
 	    (EXT3_HAS_COMPAT_FEATURE(sb, ~0U) ||
 	     EXT3_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||
 	     EXT3_HAS_INCOMPAT_FEATURE(sb, ~0U)))
-		printk(KERN_WARNING
-		       "EXT3-fs warning: feature flags set on rev 0 fs, "
-		       "running e2fsck is recommended\n");
+		ext3_msg(sb, KERN_WARNING,
+			"warning: feature flags set on rev 0 fs, "
+			"running e2fsck is recommended");
 	/*
 	 * Check feature flags regardless of the revision level, since we
 	 * previously didn't change the revision level when setting the flags,
@@ -1675,25 +1710,25 @@
 	 */
 	features = EXT3_HAS_INCOMPAT_FEATURE(sb, ~EXT3_FEATURE_INCOMPAT_SUPP);
 	if (features) {
-		printk(KERN_ERR "EXT3-fs: %s: couldn't mount because of "
-		       "unsupported optional features (%x).\n",
-		       sb->s_id, le32_to_cpu(features));
+		ext3_msg(sb, KERN_ERR,
+			"error: couldn't mount because of unsupported "
+			"optional features (%x)", le32_to_cpu(features));
 		goto failed_mount;
 	}
 	features = EXT3_HAS_RO_COMPAT_FEATURE(sb, ~EXT3_FEATURE_RO_COMPAT_SUPP);
 	if (!(sb->s_flags & MS_RDONLY) && features) {
-		printk(KERN_ERR "EXT3-fs: %s: couldn't mount RDWR because of "
-		       "unsupported optional features (%x).\n",
-		       sb->s_id, le32_to_cpu(features));
+		ext3_msg(sb, KERN_ERR,
+			"error: couldn't mount RDWR because of unsupported "
+			"optional features (%x)", le32_to_cpu(features));
 		goto failed_mount;
 	}
 	blocksize = BLOCK_SIZE << le32_to_cpu(es->s_log_block_size);
 
 	if (blocksize < EXT3_MIN_BLOCK_SIZE ||
 	    blocksize > EXT3_MAX_BLOCK_SIZE) {
-		printk(KERN_ERR
-		       "EXT3-fs: Unsupported filesystem blocksize %d on %s.\n",
-		       blocksize, sb->s_id);
+		ext3_msg(sb, KERN_ERR,
+			"error: couldn't mount because of unsupported "
+			"filesystem blocksize %d", blocksize);
 		goto failed_mount;
 	}
 
@@ -1704,30 +1739,31 @@
 		 * than the hardware sectorsize for the machine.
 		 */
 		if (blocksize < hblock) {
-			printk(KERN_ERR "EXT3-fs: blocksize %d too small for "
-			       "device blocksize %d.\n", blocksize, hblock);
+			ext3_msg(sb, KERN_ERR,
+				"error: fsblocksize %d too small for "
+				"hardware sectorsize %d", blocksize, hblock);
 			goto failed_mount;
 		}
 
 		brelse (bh);
 		if (!sb_set_blocksize(sb, blocksize)) {
-			printk(KERN_ERR "EXT3-fs: bad blocksize %d.\n",
-				blocksize);
+			ext3_msg(sb, KERN_ERR,
+				"error: bad blocksize %d", blocksize);
 			goto out_fail;
 		}
 		logic_sb_block = (sb_block * EXT3_MIN_BLOCK_SIZE) / blocksize;
 		offset = (sb_block * EXT3_MIN_BLOCK_SIZE) % blocksize;
 		bh = sb_bread(sb, logic_sb_block);
 		if (!bh) {
-			printk(KERN_ERR
-			       "EXT3-fs: Can't read superblock on 2nd try.\n");
+			ext3_msg(sb, KERN_ERR,
+			       "error: can't read superblock on 2nd try");
 			goto failed_mount;
 		}
 		es = (struct ext3_super_block *)(((char *)bh->b_data) + offset);
 		sbi->s_es = es;
 		if (es->s_magic != cpu_to_le16(EXT3_SUPER_MAGIC)) {
-			printk (KERN_ERR
-				"EXT3-fs: Magic mismatch, very weird !\n");
+			ext3_msg(sb, KERN_ERR,
+				"error: magic mismatch");
 			goto failed_mount;
 		}
 	}
@@ -1743,8 +1779,8 @@
 		if ((sbi->s_inode_size < EXT3_GOOD_OLD_INODE_SIZE) ||
 		    (!is_power_of_2(sbi->s_inode_size)) ||
 		    (sbi->s_inode_size > blocksize)) {
-			printk (KERN_ERR
-				"EXT3-fs: unsupported inode size: %d\n",
+			ext3_msg(sb, KERN_ERR,
+				"error: unsupported inode size: %d",
 				sbi->s_inode_size);
 			goto failed_mount;
 		}
@@ -1752,8 +1788,8 @@
 	sbi->s_frag_size = EXT3_MIN_FRAG_SIZE <<
 				   le32_to_cpu(es->s_log_frag_size);
 	if (blocksize != sbi->s_frag_size) {
-		printk(KERN_ERR
-		       "EXT3-fs: fragsize %lu != blocksize %u (unsupported)\n",
+		ext3_msg(sb, KERN_ERR,
+		       "error: fragsize %lu != blocksize %u (unsupported)",
 		       sbi->s_frag_size, blocksize);
 		goto failed_mount;
 	}
@@ -1789,31 +1825,31 @@
 	}
 
 	if (sbi->s_blocks_per_group > blocksize * 8) {
-		printk (KERN_ERR
-			"EXT3-fs: #blocks per group too big: %lu\n",
+		ext3_msg(sb, KERN_ERR,
+			"#blocks per group too big: %lu",
 			sbi->s_blocks_per_group);
 		goto failed_mount;
 	}
 	if (sbi->s_frags_per_group > blocksize * 8) {
-		printk (KERN_ERR
-			"EXT3-fs: #fragments per group too big: %lu\n",
+		ext3_msg(sb, KERN_ERR,
+			"error: #fragments per group too big: %lu",
 			sbi->s_frags_per_group);
 		goto failed_mount;
 	}
 	if (sbi->s_inodes_per_group > blocksize * 8) {
-		printk (KERN_ERR
-			"EXT3-fs: #inodes per group too big: %lu\n",
+		ext3_msg(sb, KERN_ERR,
+			"error: #inodes per group too big: %lu",
 			sbi->s_inodes_per_group);
 		goto failed_mount;
 	}
 
 	if (le32_to_cpu(es->s_blocks_count) >
 		    (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) {
-		printk(KERN_ERR "EXT3-fs: filesystem on %s:"
-			" too large to mount safely\n", sb->s_id);
+		ext3_msg(sb, KERN_ERR,
+			"error: filesystem is too large to mount safely");
 		if (sizeof(sector_t) < 8)
-			printk(KERN_WARNING "EXT3-fs: CONFIG_LBDAF not "
-					"enabled\n");
+			ext3_msg(sb, KERN_ERR,
+				"error: CONFIG_LBDAF not enabled");
 		goto failed_mount;
 	}
 
@@ -1827,7 +1863,8 @@
 	sbi->s_group_desc = kmalloc(db_count * sizeof (struct buffer_head *),
 				    GFP_KERNEL);
 	if (sbi->s_group_desc == NULL) {
-		printk (KERN_ERR "EXT3-fs: not enough memory\n");
+		ext3_msg(sb, KERN_ERR,
+			"error: not enough memory");
 		goto failed_mount;
 	}
 
@@ -1837,14 +1874,15 @@
 		block = descriptor_loc(sb, logic_sb_block, i);
 		sbi->s_group_desc[i] = sb_bread(sb, block);
 		if (!sbi->s_group_desc[i]) {
-			printk (KERN_ERR "EXT3-fs: "
-				"can't read group descriptor %d\n", i);
+			ext3_msg(sb, KERN_ERR,
+				"error: can't read group descriptor %d", i);
 			db_count = i;
 			goto failed_mount2;
 		}
 	}
 	if (!ext3_check_descriptors (sb)) {
-		printk(KERN_ERR "EXT3-fs: group descriptors corrupted!\n");
+		ext3_msg(sb, KERN_ERR,
+			"error: group descriptors corrupted");
 		goto failed_mount2;
 	}
 	sbi->s_gdb_count = db_count;
@@ -1862,7 +1900,7 @@
 				ext3_count_dirs(sb));
 	}
 	if (err) {
-		printk(KERN_ERR "EXT3-fs: insufficient memory\n");
+		ext3_msg(sb, KERN_ERR, "error: insufficient memory");
 		goto failed_mount3;
 	}
 
@@ -1910,9 +1948,9 @@
 			goto failed_mount3;
 	} else {
 		if (!silent)
-			printk (KERN_ERR
-				"ext3: No journal on filesystem on %s\n",
-				sb->s_id);
+			ext3_msg(sb, KERN_ERR,
+				"error: no journal found. "
+				"mounting ext3 over ext2?");
 		goto failed_mount3;
 	}
 
@@ -1934,8 +1972,9 @@
 	case EXT3_MOUNT_WRITEBACK_DATA:
 		if (!journal_check_available_features
 		    (sbi->s_journal, 0, 0, JFS_FEATURE_INCOMPAT_REVOKE)) {
-			printk(KERN_ERR "EXT3-fs: Journal does not support "
-			       "requested data journaling mode\n");
+			ext3_msg(sb, KERN_ERR,
+				"error: journal does not support "
+				"requested data journaling mode");
 			goto failed_mount4;
 		}
 	default:
@@ -1944,8 +1983,9 @@
 
 	if (test_opt(sb, NOBH)) {
 		if (!(test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA)) {
-			printk(KERN_WARNING "EXT3-fs: Ignoring nobh option - "
-				"its supported only with writeback mode\n");
+			ext3_msg(sb, KERN_WARNING,
+				"warning: ignoring nobh option - "
+				"it is supported only with writeback mode");
 			clear_opt(sbi->s_mount_opt, NOBH);
 		}
 	}
@@ -1956,18 +1996,18 @@
 
 	root = ext3_iget(sb, EXT3_ROOT_INO);
 	if (IS_ERR(root)) {
-		printk(KERN_ERR "EXT3-fs: get root inode failed\n");
+		ext3_msg(sb, KERN_ERR, "error: get root inode failed");
 		ret = PTR_ERR(root);
 		goto failed_mount4;
 	}
 	if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) {
 		iput(root);
-		printk(KERN_ERR "EXT3-fs: corrupt root inode, run e2fsck\n");
+		ext3_msg(sb, KERN_ERR, "error: corrupt root inode, run e2fsck");
 		goto failed_mount4;
 	}
 	sb->s_root = d_alloc_root(root);
 	if (!sb->s_root) {
-		printk(KERN_ERR "EXT3-fs: get root dentry failed\n");
+		ext3_msg(sb, KERN_ERR, "error: get root dentry failed");
 		iput(root);
 		ret = -ENOMEM;
 		goto failed_mount4;
@@ -1986,9 +2026,9 @@
 	ext3_orphan_cleanup(sb, es);
 	EXT3_SB(sb)->s_mount_state &= ~EXT3_ORPHAN_FS;
 	if (needs_recovery)
-		printk (KERN_INFO "EXT3-fs: recovery complete.\n");
+		ext3_msg(sb, KERN_INFO, "recovery complete");
 	ext3_mark_recovery_complete(sb, es);
-	printk (KERN_INFO "EXT3-fs: mounted filesystem with %s data mode.\n",
+	ext3_msg(sb, KERN_INFO, "mounted filesystem with %s data mode",
 		test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA ? "journal":
 		test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered":
 		"writeback");
@@ -1998,7 +2038,8 @@
 
 cantfind_ext3:
 	if (!silent)
-		printk(KERN_ERR "VFS: Can't find ext3 filesystem on dev %s.\n",
+		ext3_msg(sb, KERN_INFO,
+			"error: can't find ext3 filesystem on dev %s.",
 		       sb->s_id);
 	goto failed_mount;
 
@@ -2066,27 +2107,27 @@
 
 	journal_inode = ext3_iget(sb, journal_inum);
 	if (IS_ERR(journal_inode)) {
-		printk(KERN_ERR "EXT3-fs: no journal found.\n");
+		ext3_msg(sb, KERN_ERR, "error: no journal found");
 		return NULL;
 	}
 	if (!journal_inode->i_nlink) {
 		make_bad_inode(journal_inode);
 		iput(journal_inode);
-		printk(KERN_ERR "EXT3-fs: journal inode is deleted.\n");
+		ext3_msg(sb, KERN_ERR, "error: journal inode is deleted");
 		return NULL;
 	}
 
 	jbd_debug(2, "Journal inode found at %p: %Ld bytes\n",
 		  journal_inode, journal_inode->i_size);
 	if (!S_ISREG(journal_inode->i_mode)) {
-		printk(KERN_ERR "EXT3-fs: invalid journal inode.\n");
+		ext3_msg(sb, KERN_ERR, "error: invalid journal inode");
 		iput(journal_inode);
 		return NULL;
 	}
 
 	journal = journal_init_inode(journal_inode);
 	if (!journal) {
-		printk(KERN_ERR "EXT3-fs: Could not load journal inode\n");
+		ext3_msg(sb, KERN_ERR, "error: could not load journal inode");
 		iput(journal_inode);
 		return NULL;
 	}
@@ -2108,13 +2149,13 @@
 	struct ext3_super_block * es;
 	struct block_device *bdev;
 
-	bdev = ext3_blkdev_get(j_dev);
+	bdev = ext3_blkdev_get(j_dev, sb);
 	if (bdev == NULL)
 		return NULL;
 
 	if (bd_claim(bdev, sb)) {
-		printk(KERN_ERR
-		        "EXT3: failed to claim external journal device.\n");
+		ext3_msg(sb, KERN_ERR,
+			"error: failed to claim external journal device");
 		blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
 		return NULL;
 	}
@@ -2122,8 +2163,8 @@
 	blocksize = sb->s_blocksize;
 	hblock = bdev_logical_block_size(bdev);
 	if (blocksize < hblock) {
-		printk(KERN_ERR
-			"EXT3-fs: blocksize too small for journal device.\n");
+		ext3_msg(sb, KERN_ERR,
+			"error: blocksize too small for journal device");
 		goto out_bdev;
 	}
 
@@ -2131,8 +2172,8 @@
 	offset = EXT3_MIN_BLOCK_SIZE % blocksize;
 	set_blocksize(bdev, blocksize);
 	if (!(bh = __bread(bdev, sb_block, blocksize))) {
-		printk(KERN_ERR "EXT3-fs: couldn't read superblock of "
-		       "external journal\n");
+		ext3_msg(sb, KERN_ERR, "error: couldn't read superblock of "
+			"external journal");
 		goto out_bdev;
 	}
 
@@ -2140,14 +2181,14 @@
 	if ((le16_to_cpu(es->s_magic) != EXT3_SUPER_MAGIC) ||
 	    !(le32_to_cpu(es->s_feature_incompat) &
 	      EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
-		printk(KERN_ERR "EXT3-fs: external journal has "
-					"bad superblock\n");
+		ext3_msg(sb, KERN_ERR, "error: external journal has "
+			"bad superblock");
 		brelse(bh);
 		goto out_bdev;
 	}
 
 	if (memcmp(EXT3_SB(sb)->s_es->s_journal_uuid, es->s_uuid, 16)) {
-		printk(KERN_ERR "EXT3-fs: journal UUID does not match\n");
+		ext3_msg(sb, KERN_ERR, "error: journal UUID does not match");
 		brelse(bh);
 		goto out_bdev;
 	}
@@ -2159,19 +2200,21 @@
 	journal = journal_init_dev(bdev, sb->s_bdev,
 					start, len, blocksize);
 	if (!journal) {
-		printk(KERN_ERR "EXT3-fs: failed to create device journal\n");
+		ext3_msg(sb, KERN_ERR,
+			"error: failed to create device journal");
 		goto out_bdev;
 	}
 	journal->j_private = sb;
 	ll_rw_block(READ, 1, &journal->j_sb_buffer);
 	wait_on_buffer(journal->j_sb_buffer);
 	if (!buffer_uptodate(journal->j_sb_buffer)) {
-		printk(KERN_ERR "EXT3-fs: I/O error on journal device\n");
+		ext3_msg(sb, KERN_ERR, "I/O error on journal device");
 		goto out_journal;
 	}
 	if (be32_to_cpu(journal->j_superblock->s_nr_users) != 1) {
-		printk(KERN_ERR "EXT3-fs: External journal has more than one "
-					"user (unsupported) - %d\n",
+		ext3_msg(sb, KERN_ERR,
+			"error: external journal has more than one "
+			"user (unsupported) - %d",
 			be32_to_cpu(journal->j_superblock->s_nr_users));
 		goto out_journal;
 	}
@@ -2197,8 +2240,8 @@
 
 	if (journal_devnum &&
 	    journal_devnum != le32_to_cpu(es->s_journal_dev)) {
-		printk(KERN_INFO "EXT3-fs: external journal device major/minor "
-			"numbers have changed\n");
+		ext3_msg(sb, KERN_INFO, "external journal device major/minor "
+			"numbers have changed");
 		journal_dev = new_decode_dev(journal_devnum);
 	} else
 		journal_dev = new_decode_dev(le32_to_cpu(es->s_journal_dev));
@@ -2213,21 +2256,21 @@
 
 	if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER)) {
 		if (sb->s_flags & MS_RDONLY) {
-			printk(KERN_INFO "EXT3-fs: INFO: recovery "
-					"required on readonly filesystem.\n");
+			ext3_msg(sb, KERN_INFO,
+				"recovery required on readonly filesystem");
 			if (really_read_only) {
-				printk(KERN_ERR "EXT3-fs: write access "
-					"unavailable, cannot proceed.\n");
+				ext3_msg(sb, KERN_ERR, "error: write access "
+					"unavailable, cannot proceed");
 				return -EROFS;
 			}
-			printk (KERN_INFO "EXT3-fs: write access will "
-					"be enabled during recovery.\n");
+			ext3_msg(sb, KERN_INFO,
+				"write access will be enabled during recovery");
 		}
 	}
 
 	if (journal_inum && journal_dev) {
-		printk(KERN_ERR "EXT3-fs: filesystem has both journal "
-		       "and inode journals!\n");
+		ext3_msg(sb, KERN_ERR, "error: filesystem has both journal "
+		       "and inode journals");
 		return -EINVAL;
 	}
 
@@ -2242,7 +2285,7 @@
 	if (!really_read_only && test_opt(sb, UPDATE_JOURNAL)) {
 		err = journal_update_format(journal);
 		if (err)  {
-			printk(KERN_ERR "EXT3-fs: error updating journal.\n");
+			ext3_msg(sb, KERN_ERR, "error updating journal");
 			journal_destroy(journal);
 			return err;
 		}
@@ -2254,7 +2297,7 @@
 		err = journal_load(journal);
 
 	if (err) {
-		printk(KERN_ERR "EXT3-fs: error loading journal.\n");
+		ext3_msg(sb, KERN_ERR, "error loading journal");
 		journal_destroy(journal);
 		return err;
 	}
@@ -2273,16 +2316,17 @@
 	return 0;
 }
 
-static int ext3_create_journal(struct super_block * sb,
-			       struct ext3_super_block * es,
+static int ext3_create_journal(struct super_block *sb,
+			       struct ext3_super_block *es,
 			       unsigned int journal_inum)
 {
 	journal_t *journal;
 	int err;
 
 	if (sb->s_flags & MS_RDONLY) {
-		printk(KERN_ERR "EXT3-fs: readonly filesystem when trying to "
-				"create journal.\n");
+		ext3_msg(sb, KERN_ERR,
+			"error: readonly filesystem when trying to "
+			"create journal");
 		return -EROFS;
 	}
 
@@ -2290,12 +2334,12 @@
 	if (!journal)
 		return -EINVAL;
 
-	printk(KERN_INFO "EXT3-fs: creating new journal on inode %u\n",
+	ext3_msg(sb, KERN_INFO, "creating new journal on inode %u",
 	       journal_inum);
 
 	err = journal_create(journal);
 	if (err) {
-		printk(KERN_ERR "EXT3-fs: error creating journal.\n");
+		ext3_msg(sb, KERN_ERR, "error creating journal");
 		journal_destroy(journal);
 		return -EIO;
 	}
@@ -2376,8 +2420,8 @@
  * has recorded an error from a previous lifetime, move that error to the
  * main filesystem now.
  */
-static void ext3_clear_journal_err(struct super_block * sb,
-				   struct ext3_super_block * es)
+static void ext3_clear_journal_err(struct super_block *sb,
+				   struct ext3_super_block *es)
 {
 	journal_t *journal;
 	int j_errno;
@@ -2568,10 +2612,10 @@
 			__le32 ret;
 			if ((ret = EXT3_HAS_RO_COMPAT_FEATURE(sb,
 					~EXT3_FEATURE_RO_COMPAT_SUPP))) {
-				printk(KERN_WARNING "EXT3-fs: %s: couldn't "
-				       "remount RDWR because of unsupported "
-				       "optional features (%x).\n",
-				       sb->s_id, le32_to_cpu(ret));
+				ext3_msg(sb, KERN_WARNING,
+					"warning: couldn't remount RDWR "
+					"because of unsupported optional "
+					"features (%x)", le32_to_cpu(ret));
 				err = -EROFS;
 				goto restore_opts;
 			}
@@ -2582,11 +2626,10 @@
 			 * require a full umount/remount for now.
 			 */
 			if (es->s_last_orphan) {
-				printk(KERN_WARNING "EXT3-fs: %s: couldn't "
+				ext3_msg(sb, KERN_WARNING, "warning: couldn't "
 				       "remount RDWR because of unprocessed "
 				       "orphan inode list.  Please "
-				       "umount/remount instead.\n",
-				       sb->s_id);
+				       "umount/remount instead.");
 				err = -EINVAL;
 				goto restore_opts;
 			}
@@ -2686,13 +2729,11 @@
 	buf->f_bsize = sb->s_blocksize;
 	buf->f_blocks = le32_to_cpu(es->s_blocks_count) - sbi->s_overhead_last;
 	buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter);
-	es->s_free_blocks_count = cpu_to_le32(buf->f_bfree);
 	buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count);
 	if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count))
 		buf->f_bavail = 0;
 	buf->f_files = le32_to_cpu(es->s_inodes_count);
 	buf->f_ffree = percpu_counter_sum_positive(&sbi->s_freeinodes_counter);
-	es->s_free_inodes_count = cpu_to_le32(buf->f_ffree);
 	buf->f_namelen = EXT3_NAME_LEN;
 	fsid = le64_to_cpup((void *)es->s_uuid) ^
 	       le64_to_cpup((void *)es->s_uuid + sizeof(u64));
@@ -2837,9 +2878,9 @@
 	if (EXT3_SB(sb)->s_qf_names[type]) {
 		/* Quotafile not of fs root? */
 		if (path.dentry->d_parent != sb->s_root)
-			printk(KERN_WARNING
-				"EXT3-fs: Quota file not on filesystem root. "
-				"Journaled quota will not work.\n");
+			ext3_msg(sb, KERN_WARNING,
+				"warning: Quota file not on filesystem root. "
+				"Journaled quota will not work.");
 	}
 
 	/*
@@ -2921,8 +2962,9 @@
 	handle_t *handle = journal_current_handle();
 
 	if (!handle) {
-		printk(KERN_WARNING "EXT3-fs: Quota write (off=%Lu, len=%Lu)"
-			" cancelled because transaction is not started.\n",
+		ext3_msg(sb, KERN_WARNING,
+			"warning: quota write (off=%llu, len=%llu)"
+			" cancelled because transaction is not started.",
 			(unsigned long long)off, (unsigned long long)len);
 		return -EIO;
 	}
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index 545e37c..387d92d 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -960,6 +960,10 @@
 	if (error)
 		goto cleanup;
 
+	error = ext3_journal_get_write_access(handle, is.iloc.bh);
+	if (error)
+		goto cleanup;
+
 	if (EXT3_I(inode)->i_state & EXT3_STATE_NEW) {
 		struct ext3_inode *raw_inode = ext3_raw_inode(&is.iloc);
 		memset(raw_inode, 0, EXT3_SB(inode->i_sb)->s_inode_size);
@@ -985,9 +989,6 @@
 		if (flags & XATTR_CREATE)
 			goto cleanup;
 	}
-	error = ext3_journal_get_write_access(handle, is.iloc.bh);
-	if (error)
-		goto cleanup;
 	if (!value) {
 		if (!is.s.not_found)
 			error = ext3_xattr_ibody_set(handle, inode, &i, &is);
diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig
index 9f2d45d..9acf7e8 100644
--- a/fs/ext4/Kconfig
+++ b/fs/ext4/Kconfig
@@ -26,6 +26,16 @@
 
 	  If unsure, say N.
 
+config EXT4_USE_FOR_EXT23
+	bool "Use ext4 for ext2/ext3 file systems"
+	depends on EXT3_FS=n || EXT2_FS=n
+	default y
+	help
+	  Allow the ext4 file system driver code to be used for ext2 or
+	  ext3 file system mounts.  This allows users to reduce their
+	  compiled kernel size by using one file system driver for
+	  ext2, ext3, and ext4 file systems.
+
 config EXT4_FS_XATTR
 	bool "Ext4 extended attributes"
 	depends on EXT4_FS
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 1d04189..22bc743 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -499,44 +499,6 @@
 }
 
 /**
- * ext4_free_blocks() -- Free given blocks and update quota
- * @handle:		handle for this transaction
- * @inode:		inode
- * @block:		start physical block to free
- * @count:		number of blocks to count
- * @metadata: 		Are these metadata blocks
- */
-void ext4_free_blocks(handle_t *handle, struct inode *inode,
-			ext4_fsblk_t block, unsigned long count,
-			int metadata)
-{
-	struct super_block *sb;
-	unsigned long dquot_freed_blocks;
-
-	/* this isn't the right place to decide whether block is metadata
-	 * inode.c/extents.c knows better, but for safety ... */
-	if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
-		metadata = 1;
-
-	/* We need to make sure we don't reuse
-	 * block released untill the transaction commit.
-	 * writeback mode have weak data consistency so
-	 * don't force data as metadata when freeing block
-	 * for writeback mode.
-	 */
-	if (metadata == 0 && !ext4_should_writeback_data(inode))
-		metadata = 1;
-
-	sb = inode->i_sb;
-
-	ext4_mb_free_blocks(handle, inode, block, count,
-			    metadata, &dquot_freed_blocks);
-	if (dquot_freed_blocks)
-		vfs_dq_free_block(inode, dquot_freed_blocks);
-	return;
-}
-
-/**
  * ext4_has_free_blocks()
  * @sbi:	in-core super block structure.
  * @nblocks:	number of needed blocks
@@ -761,7 +723,13 @@
 static unsigned long ext4_bg_num_gdb_nometa(struct super_block *sb,
 					ext4_group_t group)
 {
-	return ext4_bg_has_super(sb, group) ? EXT4_SB(sb)->s_gdb_count : 0;
+	if (!ext4_bg_has_super(sb, group))
+		return 0;
+
+	if (EXT4_HAS_INCOMPAT_FEATURE(sb,EXT4_FEATURE_INCOMPAT_META_BG))
+		return le32_to_cpu(EXT4_SB(sb)->s_es->s_first_meta_bg);
+	else
+		return EXT4_SB(sb)->s_gdb_count;
 }
 
 /**
diff --git a/fs/ext4/block_validity.c b/fs/ext4/block_validity.c
index 50784ef..4df8621 100644
--- a/fs/ext4/block_validity.c
+++ b/fs/ext4/block_validity.c
@@ -160,7 +160,7 @@
 		if (ext4_bg_has_super(sb, i) &&
 		    ((i < 5) || ((i % flex_size) == 0)))
 			add_system_zone(sbi, ext4_group_first_block_no(sb, i),
-					sbi->s_gdb_count + 1);
+					ext4_bg_num_gdb(sb, i) + 1);
 		gdp = ext4_get_group_desc(sb, i, NULL);
 		ret = add_system_zone(sbi, ext4_block_bitmap(sb, gdp), 1);
 		if (ret)
@@ -228,6 +228,7 @@
 	struct rb_node *n = sbi->system_blks.rb_node;
 
 	if ((start_blk <= le32_to_cpu(sbi->s_es->s_first_data_block)) ||
+	    (start_blk + count < start_blk) ||
 	    (start_blk + count > ext4_blocks_count(sbi->s_es)))
 		return 0;
 	while (n) {
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 8825515..ab31e65 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -376,6 +376,12 @@
 					 EXT4_GET_BLOCKS_DIO_CREATE_EXT)
 
 /*
+ * Flags used by ext4_free_blocks
+ */
+#define EXT4_FREE_BLOCKS_METADATA	0x0001
+#define EXT4_FREE_BLOCKS_FORGET		0x0002
+
+/*
  * ioctl commands
  */
 #define	EXT4_IOC_GETFLAGS		FS_IOC_GETFLAGS
@@ -703,6 +709,13 @@
 	struct list_head i_aio_dio_complete_list;
 	/* current io_end structure for async DIO write*/
 	ext4_io_end_t *cur_aio_dio;
+
+	/*
+	 * Transactions that contain inode's metadata needed to complete
+	 * fsync and fdatasync, respectively.
+	 */
+	tid_t i_sync_tid;
+	tid_t i_datasync_tid;
 };
 
 /*
@@ -750,6 +763,7 @@
 #define EXT4_MOUNT_DELALLOC		0x8000000 /* Delalloc support */
 #define EXT4_MOUNT_DATA_ERR_ABORT	0x10000000 /* Abort on file data write */
 #define EXT4_MOUNT_BLOCK_VALIDITY	0x20000000 /* Block validity checking */
+#define EXT4_MOUNT_DISCARD		0x40000000 /* Issue DISCARD requests */
 
 #define clear_opt(o, opt)		o &= ~EXT4_MOUNT_##opt
 #define set_opt(o, opt)			o |= EXT4_MOUNT_##opt
@@ -1324,8 +1338,6 @@
 			ext4_fsblk_t goal, unsigned long *count, int *errp);
 extern int ext4_claim_free_blocks(struct ext4_sb_info *sbi, s64 nblocks);
 extern int ext4_has_free_blocks(struct ext4_sb_info *sbi, s64 nblocks);
-extern void ext4_free_blocks(handle_t *handle, struct inode *inode,
-			ext4_fsblk_t block, unsigned long count, int metadata);
 extern void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
 				ext4_fsblk_t block, unsigned long count);
 extern ext4_fsblk_t ext4_count_free_blocks(struct super_block *);
@@ -1384,16 +1396,15 @@
 extern void ext4_discard_preallocations(struct inode *);
 extern int __init init_ext4_mballoc(void);
 extern void exit_ext4_mballoc(void);
-extern void ext4_mb_free_blocks(handle_t *, struct inode *,
-		ext4_fsblk_t, unsigned long, int, unsigned long *);
+extern void ext4_free_blocks(handle_t *handle, struct inode *inode,
+			     struct buffer_head *bh, ext4_fsblk_t block,
+			     unsigned long count, int flags);
 extern int ext4_mb_add_groupinfo(struct super_block *sb,
 		ext4_group_t i, struct ext4_group_desc *desc);
 extern int ext4_mb_get_buddy_cache_lock(struct super_block *, ext4_group_t);
 extern void ext4_mb_put_buddy_cache_lock(struct super_block *,
 						ext4_group_t, int);
 /* inode.c */
-int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode,
-		struct buffer_head *bh, ext4_fsblk_t blocknr);
 struct buffer_head *ext4_getblk(handle_t *, struct inode *,
 						ext4_lblk_t, int, int *);
 struct buffer_head *ext4_bread(handle_t *, struct inode *,
diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c
index 6a94099..b57e5c7 100644
--- a/fs/ext4/ext4_jbd2.c
+++ b/fs/ext4/ext4_jbd2.c
@@ -4,6 +4,8 @@
 
 #include "ext4_jbd2.h"
 
+#include <trace/events/ext4.h>
+
 int __ext4_journal_get_undo_access(const char *where, handle_t *handle,
 				struct buffer_head *bh)
 {
@@ -32,35 +34,69 @@
 	return err;
 }
 
-int __ext4_journal_forget(const char *where, handle_t *handle,
-				struct buffer_head *bh)
+/*
+ * The ext4 forget function must perform a revoke if we are freeing data
+ * which has been journaled.  Metadata (eg. indirect blocks) must be
+ * revoked in all cases.
+ *
+ * "bh" may be NULL: a metadata block may have been freed from memory
+ * but there may still be a record of it in the journal, and that record
+ * still needs to be revoked.
+ *
+ * If the handle isn't valid we're not journaling, but we still need to
+ * call into ext4_journal_revoke() to put the buffer head.
+ */
+int __ext4_forget(const char *where, handle_t *handle, int is_metadata,
+		  struct inode *inode, struct buffer_head *bh,
+		  ext4_fsblk_t blocknr)
 {
-	int err = 0;
+	int err;
 
-	if (ext4_handle_valid(handle)) {
-		err = jbd2_journal_forget(handle, bh);
-		if (err)
-			ext4_journal_abort_handle(where, __func__, bh,
-						  handle, err);
-	}
-	else
+	might_sleep();
+
+	trace_ext4_forget(inode, is_metadata, blocknr);
+	BUFFER_TRACE(bh, "enter");
+
+	jbd_debug(4, "forgetting bh %p: is_metadata = %d, mode %o, "
+		  "data mode %x\n",
+		  bh, is_metadata, inode->i_mode,
+		  test_opt(inode->i_sb, DATA_FLAGS));
+
+	/* In the no journal case, we can just do a bforget and return */
+	if (!ext4_handle_valid(handle)) {
 		bforget(bh);
-	return err;
-}
-
-int __ext4_journal_revoke(const char *where, handle_t *handle,
-				ext4_fsblk_t blocknr, struct buffer_head *bh)
-{
-	int err = 0;
-
-	if (ext4_handle_valid(handle)) {
-		err = jbd2_journal_revoke(handle, blocknr, bh);
-		if (err)
-			ext4_journal_abort_handle(where, __func__, bh,
-						  handle, err);
+		return 0;
 	}
-	else
-		bforget(bh);
+
+	/* Never use the revoke function if we are doing full data
+	 * journaling: there is no need to, and a V1 superblock won't
+	 * support it.  Otherwise, only skip the revoke on un-journaled
+	 * data blocks. */
+
+	if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA ||
+	    (!is_metadata && !ext4_should_journal_data(inode))) {
+		if (bh) {
+			BUFFER_TRACE(bh, "call jbd2_journal_forget");
+			err = jbd2_journal_forget(handle, bh);
+			if (err)
+				ext4_journal_abort_handle(where, __func__, bh,
+							  handle, err);
+			return err;
+		}
+		return 0;
+	}
+
+	/*
+	 * data!=journal && (is_metadata || should_journal_data(inode))
+	 */
+	BUFFER_TRACE(bh, "call jbd2_journal_revoke");
+	err = jbd2_journal_revoke(handle, blocknr, bh);
+	if (err) {
+		ext4_journal_abort_handle(where, __func__, bh, handle, err);
+		ext4_abort(inode->i_sb, __func__,
+			   "error %d when attempting revoke", err);
+	}
+	BUFFER_TRACE(bh, "exit");
 	return err;
 }
 
diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h
index a286598..05eca81 100644
--- a/fs/ext4/ext4_jbd2.h
+++ b/fs/ext4/ext4_jbd2.h
@@ -49,7 +49,7 @@
 
 #define EXT4_DATA_TRANS_BLOCKS(sb)	(EXT4_SINGLEDATA_TRANS_BLOCKS(sb) + \
 					 EXT4_XATTR_TRANS_BLOCKS - 2 + \
-					 2*EXT4_QUOTA_TRANS_BLOCKS(sb))
+					 EXT4_MAXQUOTAS_TRANS_BLOCKS(sb))
 
 /*
  * Define the number of metadata blocks we need to account to modify data.
@@ -57,7 +57,7 @@
  * This include super block, inode block, quota blocks and xattr blocks
  */
 #define EXT4_META_TRANS_BLOCKS(sb)	(EXT4_XATTR_TRANS_BLOCKS + \
-					2*EXT4_QUOTA_TRANS_BLOCKS(sb))
+					EXT4_MAXQUOTAS_TRANS_BLOCKS(sb))
 
 /* Delete operations potentially hit one directory's namespace plus an
  * entire inode, plus arbitrary amounts of bitmap/indirection data.  Be
@@ -92,6 +92,7 @@
  * but inode, sb and group updates are done only once */
 #define EXT4_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_INIT_ALLOC*\
 		(EXT4_SINGLEDATA_TRANS_BLOCKS(sb)-3)+3+DQUOT_INIT_REWRITE) : 0)
+
 #define EXT4_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_DEL_ALLOC*\
 		(EXT4_SINGLEDATA_TRANS_BLOCKS(sb)-3)+3+DQUOT_DEL_REWRITE) : 0)
 #else
@@ -99,6 +100,9 @@
 #define EXT4_QUOTA_INIT_BLOCKS(sb) 0
 #define EXT4_QUOTA_DEL_BLOCKS(sb) 0
 #endif
+#define EXT4_MAXQUOTAS_TRANS_BLOCKS(sb) (MAXQUOTAS*EXT4_QUOTA_TRANS_BLOCKS(sb))
+#define EXT4_MAXQUOTAS_INIT_BLOCKS(sb) (MAXQUOTAS*EXT4_QUOTA_INIT_BLOCKS(sb))
+#define EXT4_MAXQUOTAS_DEL_BLOCKS(sb) (MAXQUOTAS*EXT4_QUOTA_DEL_BLOCKS(sb))
 
 int
 ext4_mark_iloc_dirty(handle_t *handle,
@@ -116,12 +120,8 @@
 int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode);
 
 /*
- * Wrapper functions with which ext4 calls into JBD.  The intent here is
- * to allow these to be turned into appropriate stubs so ext4 can control
- * ext2 filesystems, so ext2+ext4 systems only nee one fs.  This work hasn't
- * been done yet.
+ * Wrapper functions with which ext4 calls into JBD.
  */
-
 void ext4_journal_abort_handle(const char *caller, const char *err_fn,
 		struct buffer_head *bh, handle_t *handle, int err);
 
@@ -131,13 +131,9 @@
 int __ext4_journal_get_write_access(const char *where, handle_t *handle,
 				struct buffer_head *bh);
 
-/* When called with an invalid handle, this will still do a put on the BH */
-int __ext4_journal_forget(const char *where, handle_t *handle,
-				struct buffer_head *bh);
-
-/* When called with an invalid handle, this will still do a put on the BH */
-int __ext4_journal_revoke(const char *where, handle_t *handle,
-				ext4_fsblk_t blocknr, struct buffer_head *bh);
+int __ext4_forget(const char *where, handle_t *handle, int is_metadata,
+		  struct inode *inode, struct buffer_head *bh,
+		  ext4_fsblk_t blocknr);
 
 int __ext4_journal_get_create_access(const char *where,
 				handle_t *handle, struct buffer_head *bh);
@@ -149,12 +145,11 @@
 	__ext4_journal_get_undo_access(__func__, (handle), (bh))
 #define ext4_journal_get_write_access(handle, bh) \
 	__ext4_journal_get_write_access(__func__, (handle), (bh))
-#define ext4_journal_revoke(handle, blocknr, bh) \
-	__ext4_journal_revoke(__func__, (handle), (blocknr), (bh))
+#define ext4_forget(handle, is_metadata, inode, bh, block_nr) \
+	__ext4_forget(__func__, (handle), (is_metadata), (inode), (bh),\
+		      (block_nr))
 #define ext4_journal_get_create_access(handle, bh) \
 	__ext4_journal_get_create_access(__func__, (handle), (bh))
-#define ext4_journal_forget(handle, bh) \
-	__ext4_journal_forget(__func__, (handle), (bh))
 #define ext4_handle_dirty_metadata(handle, inode, bh) \
 	__ext4_handle_dirty_metadata(__func__, (handle), (inode), (bh))
 
@@ -254,6 +249,19 @@
 	return 0;
 }
 
+static inline void ext4_update_inode_fsync_trans(handle_t *handle,
+						 struct inode *inode,
+						 int datasync)
+{
+	struct ext4_inode_info *ei = EXT4_I(inode);
+
+	if (ext4_handle_valid(handle)) {
+		ei->i_sync_tid = handle->h_transaction->t_tid;
+		if (datasync)
+			ei->i_datasync_tid = handle->h_transaction->t_tid;
+	}
+}
+
 /* super.c */
 int ext4_force_commit(struct super_block *sb);
 
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 715264b..3a7928f 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -1007,7 +1007,8 @@
 		for (i = 0; i < depth; i++) {
 			if (!ablocks[i])
 				continue;
-			ext4_free_blocks(handle, inode, ablocks[i], 1, 1);
+			ext4_free_blocks(handle, inode, 0, ablocks[i], 1,
+					 EXT4_FREE_BLOCKS_METADATA);
 		}
 	}
 	kfree(ablocks);
@@ -1761,7 +1762,9 @@
 	while (block < last && block != EXT_MAX_BLOCK) {
 		num = last - block;
 		/* find extent for this block */
+		down_read(&EXT4_I(inode)->i_data_sem);
 		path = ext4_ext_find_extent(inode, block, path);
+		up_read(&EXT4_I(inode)->i_data_sem);
 		if (IS_ERR(path)) {
 			err = PTR_ERR(path);
 			path = NULL;
@@ -1957,7 +1960,6 @@
 static int ext4_ext_rm_idx(handle_t *handle, struct inode *inode,
 			struct ext4_ext_path *path)
 {
-	struct buffer_head *bh;
 	int err;
 	ext4_fsblk_t leaf;
 
@@ -1973,9 +1975,8 @@
 	if (err)
 		return err;
 	ext_debug("index is empty, remove it, free block %llu\n", leaf);
-	bh = sb_find_get_block(inode->i_sb, leaf);
-	ext4_forget(handle, 1, inode, bh, leaf);
-	ext4_free_blocks(handle, inode, leaf, 1, 1);
+	ext4_free_blocks(handle, inode, 0, leaf, 1,
+			 EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET);
 	return err;
 }
 
@@ -2042,12 +2043,11 @@
 				struct ext4_extent *ex,
 				ext4_lblk_t from, ext4_lblk_t to)
 {
-	struct buffer_head *bh;
 	unsigned short ee_len =  ext4_ext_get_actual_len(ex);
-	int i, metadata = 0;
+	int flags = EXT4_FREE_BLOCKS_FORGET;
 
 	if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
-		metadata = 1;
+		flags |= EXT4_FREE_BLOCKS_METADATA;
 #ifdef EXTENTS_STATS
 	{
 		struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
@@ -2072,11 +2072,7 @@
 		num = le32_to_cpu(ex->ee_block) + ee_len - from;
 		start = ext_pblock(ex) + ee_len - num;
 		ext_debug("free last %u blocks starting %llu\n", num, start);
-		for (i = 0; i < num; i++) {
-			bh = sb_find_get_block(inode->i_sb, start + i);
-			ext4_forget(handle, 0, inode, bh, start + i);
-		}
-		ext4_free_blocks(handle, inode, start, num, metadata);
+		ext4_free_blocks(handle, inode, 0, start, num, flags);
 	} else if (from == le32_to_cpu(ex->ee_block)
 		   && to <= le32_to_cpu(ex->ee_block) + ee_len - 1) {
 		printk(KERN_INFO "strange request: removal %u-%u from %u:%u\n",
@@ -2167,7 +2163,7 @@
 			correct_index = 1;
 			credits += (ext_depth(inode)) + 1;
 		}
-		credits += 2 * EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb);
+		credits += EXT4_MAXQUOTAS_TRANS_BLOCKS(inode->i_sb);
 
 		err = ext4_ext_truncate_extend_restart(handle, inode, credits);
 		if (err)
@@ -3064,6 +3060,8 @@
 	if (flags == EXT4_GET_BLOCKS_DIO_CONVERT_EXT) {
 		ret = ext4_convert_unwritten_extents_dio(handle, inode,
 							path);
+		if (ret >= 0)
+			ext4_update_inode_fsync_trans(handle, inode, 1);
 		goto out2;
 	}
 	/* buffered IO case */
@@ -3091,6 +3089,8 @@
 	ret = ext4_ext_convert_to_initialized(handle, inode,
 						path, iblock,
 						max_blocks);
+	if (ret >= 0)
+		ext4_update_inode_fsync_trans(handle, inode, 1);
 out:
 	if (ret <= 0) {
 		err = ret;
@@ -3319,8 +3319,8 @@
 		/* not a good idea to call discard here directly,
 		 * but otherwise we'd need to call it every free() */
 		ext4_discard_preallocations(inode);
-		ext4_free_blocks(handle, inode, ext_pblock(&newex),
-					ext4_ext_get_actual_len(&newex), 0);
+		ext4_free_blocks(handle, inode, 0, ext_pblock(&newex),
+				 ext4_ext_get_actual_len(&newex), 0);
 		goto out2;
 	}
 
@@ -3329,10 +3329,16 @@
 	allocated = ext4_ext_get_actual_len(&newex);
 	set_buffer_new(bh_result);
 
-	/* Cache only when it is _not_ an uninitialized extent */
-	if ((flags & EXT4_GET_BLOCKS_UNINIT_EXT) == 0)
+	/*
+	 * Cache the extent and update transaction to commit on fdatasync only
+	 * when it is _not_ an uninitialized extent.
+	 */
+	if ((flags & EXT4_GET_BLOCKS_UNINIT_EXT) == 0) {
 		ext4_ext_put_in_cache(inode, iblock, allocated, newblock,
 						EXT4_EXT_CACHE_EXTENT);
+		ext4_update_inode_fsync_trans(handle, inode, 1);
+	} else
+		ext4_update_inode_fsync_trans(handle, inode, 0);
 out:
 	if (allocated > max_blocks)
 		allocated = max_blocks;
@@ -3720,10 +3726,8 @@
 		 * Walk the extent tree gathering extent information.
 		 * ext4_ext_fiemap_cb will push extents back to user.
 		 */
-		down_read(&EXT4_I(inode)->i_data_sem);
 		error = ext4_ext_walk_space(inode, start_blk, len_blks,
 					  ext4_ext_fiemap_cb, fieinfo);
-		up_read(&EXT4_I(inode)->i_data_sem);
 	}
 
 	return error;
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c
index 2b15312..0b22497 100644
--- a/fs/ext4/fsync.c
+++ b/fs/ext4/fsync.c
@@ -51,25 +51,30 @@
 int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync)
 {
 	struct inode *inode = dentry->d_inode;
+	struct ext4_inode_info *ei = EXT4_I(inode);
 	journal_t *journal = EXT4_SB(inode->i_sb)->s_journal;
-	int err, ret = 0;
+	int ret;
+	tid_t commit_tid;
 
 	J_ASSERT(ext4_journal_current_handle() == NULL);
 
 	trace_ext4_sync_file(file, dentry, datasync);
 
+	if (inode->i_sb->s_flags & MS_RDONLY)
+		return 0;
+
 	ret = flush_aio_dio_completed_IO(inode);
 	if (ret < 0)
-		goto out;
+		return ret;
+	
+	if (!journal)
+		return simple_fsync(file, dentry, datasync);
+
 	/*
-	 * data=writeback:
+	 * data=writeback,ordered:
 	 *  The caller's filemap_fdatawrite()/wait will sync the data.
-	 *  sync_inode() will sync the metadata
-	 *
-	 * data=ordered:
-	 *  The caller's filemap_fdatawrite() will write the data and
-	 *  sync_inode() will write the inode if it is dirty.  Then the caller's
-	 *  filemap_fdatawait() will wait on the pages.
+	 *  Metadata is in the journal, we wait for proper transaction to
+	 *  commit here.
 	 *
 	 * data=journal:
 	 *  filemap_fdatawrite won't do anything (the buffers are clean).
@@ -79,32 +84,13 @@
 	 *  (they were dirtied by commit).  But that's OK - the blocks are
 	 *  safe in-journal, which is all fsync() needs to ensure.
 	 */
-	if (ext4_should_journal_data(inode)) {
-		ret = ext4_force_commit(inode->i_sb);
-		goto out;
-	}
+	if (ext4_should_journal_data(inode))
+		return ext4_force_commit(inode->i_sb);
 
-	if (!journal)
-		ret = sync_mapping_buffers(inode->i_mapping);
-
-	if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
-		goto out;
-
-	/*
-	 * The VFS has written the file data.  If the inode is unaltered
-	 * then we need not start a commit.
-	 */
-	if (inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC)) {
-		struct writeback_control wbc = {
-			.sync_mode = WB_SYNC_ALL,
-			.nr_to_write = 0, /* sys_fsync did this */
-		};
-		err = sync_inode(inode, &wbc);
-		if (ret == 0)
-			ret = err;
-	}
-out:
-	if (journal && (journal->j_flags & JBD2_BARRIER))
+	commit_tid = datasync ? ei->i_datasync_tid : ei->i_sync_tid;
+	if (jbd2_log_start_commit(journal, commit_tid))
+		jbd2_log_wait_commit(journal, commit_tid);
+	else if (journal->j_flags & JBD2_BARRIER)
 		blkdev_issue_flush(inode->i_sb->s_bdev, NULL);
 	return ret;
 }
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 2c8caa5..5352db1 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -71,58 +71,6 @@
 }
 
 /*
- * The ext4 forget function must perform a revoke if we are freeing data
- * which has been journaled.  Metadata (eg. indirect blocks) must be
- * revoked in all cases.
- *
- * "bh" may be NULL: a metadata block may have been freed from memory
- * but there may still be a record of it in the journal, and that record
- * still needs to be revoked.
- *
- * If the handle isn't valid we're not journaling, but we still need to
- * call into ext4_journal_revoke() to put the buffer head.
- */
-int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode,
-		struct buffer_head *bh, ext4_fsblk_t blocknr)
-{
-	int err;
-
-	might_sleep();
-
-	BUFFER_TRACE(bh, "enter");
-
-	jbd_debug(4, "forgetting bh %p: is_metadata = %d, mode %o, "
-		  "data mode %x\n",
-		  bh, is_metadata, inode->i_mode,
-		  test_opt(inode->i_sb, DATA_FLAGS));
-
-	/* Never use the revoke function if we are doing full data
-	 * journaling: there is no need to, and a V1 superblock won't
-	 * support it.  Otherwise, only skip the revoke on un-journaled
-	 * data blocks. */
-
-	if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA ||
-	    (!is_metadata && !ext4_should_journal_data(inode))) {
-		if (bh) {
-			BUFFER_TRACE(bh, "call jbd2_journal_forget");
-			return ext4_journal_forget(handle, bh);
-		}
-		return 0;
-	}
-
-	/*
-	 * data!=journal && (is_metadata || should_journal_data(inode))
-	 */
-	BUFFER_TRACE(bh, "call ext4_journal_revoke");
-	err = ext4_journal_revoke(handle, blocknr, bh);
-	if (err)
-		ext4_abort(inode->i_sb, __func__,
-			   "error %d when attempting revoke", err);
-	BUFFER_TRACE(bh, "exit");
-	return err;
-}
-
-/*
  * Work out how many blocks we need to proceed with the next chunk of a
  * truncate transaction.
  */
@@ -721,7 +669,7 @@
 	return ret;
 failed_out:
 	for (i = 0; i < index; i++)
-		ext4_free_blocks(handle, inode, new_blocks[i], 1, 0);
+		ext4_free_blocks(handle, inode, 0, new_blocks[i], 1, 0);
 	return ret;
 }
 
@@ -817,14 +765,20 @@
 	return err;
 failed:
 	/* Allocation failed, free what we already allocated */
+	ext4_free_blocks(handle, inode, 0, new_blocks[0], 1, 0);
 	for (i = 1; i <= n ; i++) {
-		BUFFER_TRACE(branch[i].bh, "call jbd2_journal_forget");
-		ext4_journal_forget(handle, branch[i].bh);
+		/* 
+		 * branch[i].bh is newly allocated, so there is no
+		 * need to revoke the block, which is why we don't
+		 * need to set EXT4_FREE_BLOCKS_METADATA.
+		 */
+		ext4_free_blocks(handle, inode, 0, new_blocks[i], 1,
+				 EXT4_FREE_BLOCKS_FORGET);
 	}
-	for (i = 0; i < indirect_blks; i++)
-		ext4_free_blocks(handle, inode, new_blocks[i], 1, 0);
+	for (i = n+1; i < indirect_blks; i++)
+		ext4_free_blocks(handle, inode, 0, new_blocks[i], 1, 0);
 
-	ext4_free_blocks(handle, inode, new_blocks[i], num, 0);
+	ext4_free_blocks(handle, inode, 0, new_blocks[i], num, 0);
 
 	return err;
 }
@@ -903,12 +857,16 @@
 
 err_out:
 	for (i = 1; i <= num; i++) {
-		BUFFER_TRACE(where[i].bh, "call jbd2_journal_forget");
-		ext4_journal_forget(handle, where[i].bh);
-		ext4_free_blocks(handle, inode,
-					le32_to_cpu(where[i-1].key), 1, 0);
+		/* 
+		 * branch[i].bh is newly allocated, so there is no
+		 * need to revoke the block, which is why we don't
+		 * need to set EXT4_FREE_BLOCKS_METADATA.
+		 */
+		ext4_free_blocks(handle, inode, where[i].bh, 0, 1,
+				 EXT4_FREE_BLOCKS_FORGET);
 	}
-	ext4_free_blocks(handle, inode, le32_to_cpu(where[num].key), blks, 0);
+	ext4_free_blocks(handle, inode, 0, le32_to_cpu(where[num].key),
+			 blks, 0);
 
 	return err;
 }
@@ -1021,10 +979,12 @@
 	if (!err)
 		err = ext4_splice_branch(handle, inode, iblock,
 					 partial, indirect_blks, count);
-	else
+	if (err)
 		goto cleanup;
 
 	set_buffer_new(bh_result);
+
+	ext4_update_inode_fsync_trans(handle, inode, 1);
 got_it:
 	map_bh(bh_result, inode->i_sb, le32_to_cpu(chain[depth-1].key));
 	if (count > blocks_to_boundary)
@@ -1052,7 +1012,7 @@
 		EXT4_I(inode)->i_reserved_meta_blocks;
 	spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
 
-	return total;
+	return (total << inode->i_blkbits);
 }
 /*
  * Calculate the number of metadata blocks need to reserve
@@ -1534,6 +1494,16 @@
 	return ext4_journal_get_write_access(handle, bh);
 }
 
+/*
+ * Truncate blocks that were not used by write. We have to truncate the
+ * pagecache as well so that corresponding buffers get properly unmapped.
+ */
+static void ext4_truncate_failed_write(struct inode *inode)
+{
+	truncate_inode_pages(inode->i_mapping, inode->i_size);
+	ext4_truncate(inode);
+}
+
 static int ext4_write_begin(struct file *file, struct address_space *mapping,
 			    loff_t pos, unsigned len, unsigned flags,
 			    struct page **pagep, void **fsdata)
@@ -1599,7 +1569,7 @@
 
 		ext4_journal_stop(handle);
 		if (pos + len > inode->i_size) {
-			ext4_truncate(inode);
+			ext4_truncate_failed_write(inode);
 			/*
 			 * If truncate failed early the inode might
 			 * still be on the orphan list; we need to
@@ -1709,7 +1679,7 @@
 		ret = ret2;
 
 	if (pos + len > inode->i_size) {
-		ext4_truncate(inode);
+		ext4_truncate_failed_write(inode);
 		/*
 		 * If truncate failed early the inode might still be
 		 * on the orphan list; we need to make sure the inode
@@ -1751,7 +1721,7 @@
 		ret = ret2;
 
 	if (pos + len > inode->i_size) {
-		ext4_truncate(inode);
+		ext4_truncate_failed_write(inode);
 		/*
 		 * If truncate failed early the inode might still be
 		 * on the orphan list; we need to make sure the inode
@@ -1814,7 +1784,7 @@
 	if (!ret)
 		ret = ret2;
 	if (pos + len > inode->i_size) {
-		ext4_truncate(inode);
+		ext4_truncate_failed_write(inode);
 		/*
 		 * If truncate failed early the inode might still be
 		 * on the orphan list; we need to make sure the inode
@@ -2600,7 +2570,6 @@
 }
 
 static int __ext4_journalled_writepage(struct page *page,
-				       struct writeback_control *wbc,
 				       unsigned int len)
 {
 	struct address_space *mapping = page->mapping;
@@ -2758,7 +2727,7 @@
 		 * doesn't seem much point in redirtying the page here.
 		 */
 		ClearPageChecked(page);
-		return __ext4_journalled_writepage(page, wbc, len);
+		return __ext4_journalled_writepage(page, len);
 	}
 
 	if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode))
@@ -2788,7 +2757,7 @@
 	 * number of contiguous block. So we will limit
 	 * number of contiguous block to a sane value
 	 */
-	if (!(inode->i_flags & EXT4_EXTENTS_FL) &&
+	if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) &&
 	    (max_blocks > EXT4_MAX_TRANS_DATA))
 		max_blocks = EXT4_MAX_TRANS_DATA;
 
@@ -2933,7 +2902,7 @@
 		ret = write_cache_pages(mapping, wbc, __mpage_da_writepage,
 					&mpd);
 		/*
-		 * If we have a contigous extent of pages and we
+		 * If we have a contiguous extent of pages and we
 		 * haven't done the I/O yet, map the blocks and submit
 		 * them for I/O.
 		 */
@@ -3091,7 +3060,7 @@
 		 * i_size_read because we hold i_mutex.
 		 */
 		if (pos + len > inode->i_size)
-			ext4_truncate(inode);
+			ext4_truncate_failed_write(inode);
 	}
 
 	if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
@@ -4064,7 +4033,7 @@
 	int k, err;
 
 	*top = 0;
-	/* Make k index the deepest non-null offest + 1 */
+	/* Make k index the deepest non-null offset + 1 */
 	for (k = depth; k > 1 && !offsets[k-1]; k--)
 		;
 	partial = ext4_get_branch(inode, k, offsets, chain, &err);
@@ -4120,6 +4089,11 @@
 			      __le32 *last)
 {
 	__le32 *p;
+	int	flags = EXT4_FREE_BLOCKS_FORGET;
+
+	if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
+		flags |= EXT4_FREE_BLOCKS_METADATA;
+
 	if (try_to_extend_transaction(handle, inode)) {
 		if (bh) {
 			BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
@@ -4134,27 +4108,10 @@
 		}
 	}
 
-	/*
-	 * Any buffers which are on the journal will be in memory. We
-	 * find them on the hash table so jbd2_journal_revoke() will
-	 * run jbd2_journal_forget() on them.  We've already detached
-	 * each block from the file, so bforget() in
-	 * jbd2_journal_forget() should be safe.
-	 *
-	 * AKPM: turn on bforget in jbd2_journal_forget()!!!
-	 */
-	for (p = first; p < last; p++) {
-		u32 nr = le32_to_cpu(*p);
-		if (nr) {
-			struct buffer_head *tbh;
+	for (p = first; p < last; p++)
+		*p = 0;
 
-			*p = 0;
-			tbh = sb_find_get_block(inode->i_sb, nr);
-			ext4_forget(handle, 0, inode, tbh, nr);
-		}
-	}
-
-	ext4_free_blocks(handle, inode, block_to_free, count, 0);
+	ext4_free_blocks(handle, inode, 0, block_to_free, count, flags);
 }
 
 /**
@@ -4342,7 +4299,8 @@
 					    blocks_for_truncate(inode));
 			}
 
-			ext4_free_blocks(handle, inode, nr, 1, 1);
+			ext4_free_blocks(handle, inode, 0, nr, 1,
+					 EXT4_FREE_BLOCKS_METADATA);
 
 			if (parent_bh) {
 				/*
@@ -4781,8 +4739,8 @@
 	struct ext4_iloc iloc;
 	struct ext4_inode *raw_inode;
 	struct ext4_inode_info *ei;
-	struct buffer_head *bh;
 	struct inode *inode;
+	journal_t *journal = EXT4_SB(sb)->s_journal;
 	long ret;
 	int block;
 
@@ -4793,11 +4751,11 @@
 		return inode;
 
 	ei = EXT4_I(inode);
+	iloc.bh = 0;
 
 	ret = __ext4_get_inode_loc(inode, &iloc, 0);
 	if (ret < 0)
 		goto bad_inode;
-	bh = iloc.bh;
 	raw_inode = ext4_raw_inode(&iloc);
 	inode->i_mode = le16_to_cpu(raw_inode->i_mode);
 	inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
@@ -4820,7 +4778,6 @@
 		if (inode->i_mode == 0 ||
 		    !(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ORPHAN_FS)) {
 			/* this inode is deleted */
-			brelse(bh);
 			ret = -ESTALE;
 			goto bad_inode;
 		}
@@ -4848,11 +4805,35 @@
 		ei->i_data[block] = raw_inode->i_block[block];
 	INIT_LIST_HEAD(&ei->i_orphan);
 
+	/*
+	 * Set transaction id's of transactions that have to be committed
+	 * to finish f[data]sync. We set them to currently running transaction
+	 * as we cannot be sure that the inode or some of its metadata isn't
+	 * part of the transaction - the inode could have been reclaimed and
+	 * now it is reread from disk.
+	 */
+	if (journal) {
+		transaction_t *transaction;
+		tid_t tid;
+
+		spin_lock(&journal->j_state_lock);
+		if (journal->j_running_transaction)
+			transaction = journal->j_running_transaction;
+		else
+			transaction = journal->j_committing_transaction;
+		if (transaction)
+			tid = transaction->t_tid;
+		else
+			tid = journal->j_commit_sequence;
+		spin_unlock(&journal->j_state_lock);
+		ei->i_sync_tid = tid;
+		ei->i_datasync_tid = tid;
+	}
+
 	if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) {
 		ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize);
 		if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize >
 		    EXT4_INODE_SIZE(inode->i_sb)) {
-			brelse(bh);
 			ret = -EIO;
 			goto bad_inode;
 		}
@@ -4884,10 +4865,7 @@
 
 	ret = 0;
 	if (ei->i_file_acl &&
-	    ((ei->i_file_acl <
-	      (le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block) +
-	       EXT4_SB(sb)->s_gdb_count)) ||
-	     (ei->i_file_acl >= ext4_blocks_count(EXT4_SB(sb)->s_es)))) {
+	    !ext4_data_block_valid(EXT4_SB(sb), ei->i_file_acl, 1)) {
 		ext4_error(sb, __func__,
 			   "bad extended attribute block %llu in inode #%lu",
 			   ei->i_file_acl, inode->i_ino);
@@ -4905,10 +4883,8 @@
 		/* Validate block references which are part of inode */
 		ret = ext4_check_inode_blockref(inode);
 	}
-	if (ret) {
-		brelse(bh);
+	if (ret)
 		goto bad_inode;
-	}
 
 	if (S_ISREG(inode->i_mode)) {
 		inode->i_op = &ext4_file_inode_operations;
@@ -4936,7 +4912,6 @@
 			init_special_inode(inode, inode->i_mode,
 			   new_decode_dev(le32_to_cpu(raw_inode->i_block[1])));
 	} else {
-		brelse(bh);
 		ret = -EIO;
 		ext4_error(inode->i_sb, __func__,
 			   "bogus i_mode (%o) for inode=%lu",
@@ -4949,6 +4924,7 @@
 	return inode;
 
 bad_inode:
+	brelse(iloc.bh);
 	iget_failed(inode);
 	return ERR_PTR(ret);
 }
@@ -5108,6 +5084,7 @@
 		err = rc;
 	ei->i_state &= ~EXT4_STATE_NEW;
 
+	ext4_update_inode_fsync_trans(handle, inode, 0);
 out_brelse:
 	brelse(bh);
 	ext4_std_error(inode->i_sb, err);
@@ -5227,8 +5204,8 @@
 
 		/* (user+group)*(old+new) structure, inode write (sb,
 		 * inode block, ? - but truncate inode update has it) */
-		handle = ext4_journal_start(inode, 2*(EXT4_QUOTA_INIT_BLOCKS(inode->i_sb)+
-					EXT4_QUOTA_DEL_BLOCKS(inode->i_sb))+3);
+		handle = ext4_journal_start(inode, (EXT4_MAXQUOTAS_INIT_BLOCKS(inode->i_sb)+
+					EXT4_MAXQUOTAS_DEL_BLOCKS(inode->i_sb))+3);
 		if (IS_ERR(handle)) {
 			error = PTR_ERR(handle);
 			goto err_out;
@@ -5376,7 +5353,7 @@
  * worse case, the indexs blocks spread over different block groups
  *
  * If datablocks are discontiguous, they are possible to spread over
- * different block groups too. If they are contiugous, with flexbg,
+ * different block groups too. If they are contiuguous, with flexbg,
  * they could still across block group boundary.
  *
  * Also account for superblock, inode, quota and xattr blocks
@@ -5452,7 +5429,7 @@
  * Calculate the journal credits for a chunk of data modification.
  *
  * This is called from DIO, fallocate or whoever calling
- * ext4_get_blocks() to map/allocate a chunk of contigous disk blocks.
+ * ext4_get_blocks() to map/allocate a chunk of contiguous disk blocks.
  *
  * journal buffers for data blocks are not included here, as DIO
  * and fallocate do no need to journal data buffers.
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index c1cdf61..b63d193 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -221,31 +221,38 @@
 		struct file *donor_filp;
 		int err;
 
+		if (!(filp->f_mode & FMODE_READ) ||
+		    !(filp->f_mode & FMODE_WRITE))
+			return -EBADF;
+
 		if (copy_from_user(&me,
 			(struct move_extent __user *)arg, sizeof(me)))
 			return -EFAULT;
+		me.moved_len = 0;
 
 		donor_filp = fget(me.donor_fd);
 		if (!donor_filp)
 			return -EBADF;
 
-		if (!capable(CAP_DAC_OVERRIDE)) {
-			if ((current->real_cred->fsuid != inode->i_uid) ||
-				!(inode->i_mode & S_IRUSR) ||
-				!(donor_filp->f_dentry->d_inode->i_mode &
-				S_IRUSR)) {
-				fput(donor_filp);
-				return -EACCES;
-			}
+		if (!(donor_filp->f_mode & FMODE_WRITE)) {
+			err = -EBADF;
+			goto mext_out;
 		}
 
+		err = mnt_want_write(filp->f_path.mnt);
+		if (err)
+			goto mext_out;
+
 		err = ext4_move_extents(filp, donor_filp, me.orig_start,
 					me.donor_start, me.len, &me.moved_len);
-		fput(donor_filp);
+		mnt_drop_write(filp->f_path.mnt);
+		if (me.moved_len > 0)
+			file_remove_suid(donor_filp);
 
 		if (copy_to_user((struct move_extent *)arg, &me, sizeof(me)))
-			return -EFAULT;
-
+			err = -EFAULT;
+mext_out:
+		fput(donor_filp);
 		return err;
 	}
 
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index bba1282..c1e19d5 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -142,7 +142,7 @@
  * 2 blocks and the order of allocation is >= sbi->s_mb_order2_reqs. The
  * value of s_mb_order2_reqs can be tuned via
  * /sys/fs/ext4/<partition>/mb_order2_req.  If the request len is equal to
- * stripe size (sbi->s_stripe), we try to search for contigous block in
+ * stripe size (sbi->s_stripe), we try to search for contiguous block in
  * stripe size. This should result in better allocation on RAID setups. If
  * not, we search in the specific group using bitmap for best extents. The
  * tunable min_to_scan and max_to_scan control the behaviour here.
@@ -2529,7 +2529,6 @@
 	struct ext4_group_info *db;
 	int err, count = 0, count2 = 0;
 	struct ext4_free_data *entry;
-	ext4_fsblk_t discard_block;
 	struct list_head *l, *ltmp;
 
 	list_for_each_safe(l, ltmp, &txn->t_private_list) {
@@ -2559,13 +2558,19 @@
 			page_cache_release(e4b.bd_bitmap_page);
 		}
 		ext4_unlock_group(sb, entry->group);
-		discard_block = (ext4_fsblk_t) entry->group * EXT4_BLOCKS_PER_GROUP(sb)
-			+ entry->start_blk
-			+ le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block);
-		trace_ext4_discard_blocks(sb, (unsigned long long)discard_block,
-					  entry->count);
-		sb_issue_discard(sb, discard_block, entry->count);
+		if (test_opt(sb, DISCARD)) {
+			ext4_fsblk_t discard_block;
+			struct ext4_super_block *es = EXT4_SB(sb)->s_es;
 
+			discard_block = (ext4_fsblk_t)entry->group *
+						EXT4_BLOCKS_PER_GROUP(sb)
+					+ entry->start_blk
+					+ le32_to_cpu(es->s_first_data_block);
+			trace_ext4_discard_blocks(sb,
+					(unsigned long long)discard_block,
+					entry->count);
+			sb_issue_discard(sb, discard_block, entry->count);
+		}
 		kmem_cache_free(ext4_free_ext_cachep, entry);
 		ext4_mb_release_desc(&e4b);
 	}
@@ -3006,6 +3011,24 @@
 }
 
 /*
+ * Called on failure; free up any blocks from the inode PA for this
+ * context.  We don't need this for MB_GROUP_PA because we only change
+ * pa_free in ext4_mb_release_context(), but on failure, we've already
+ * zeroed out ac->ac_b_ex.fe_len, so group_pa->pa_free is not changed.
+ */
+static void ext4_discard_allocated_blocks(struct ext4_allocation_context *ac)
+{
+	struct ext4_prealloc_space *pa = ac->ac_pa;
+	int len;
+
+	if (pa && pa->pa_type == MB_INODE_PA) {
+		len = ac->ac_b_ex.fe_len;
+		pa->pa_free += len;
+	}
+
+}
+
+/*
  * use blocks preallocated to inode
  */
 static void ext4_mb_use_inode_pa(struct ext4_allocation_context *ac,
@@ -4290,6 +4313,7 @@
 			ac->ac_status = AC_STATUS_CONTINUE;
 			goto repeat;
 		} else if (*errp) {
+			ext4_discard_allocated_blocks(ac);
 			ac->ac_b_ex.fe_len = 0;
 			ar->len = 0;
 			ext4_mb_show_ac(ac);
@@ -4422,18 +4446,24 @@
 	return 0;
 }
 
-/*
- * Main entry point into mballoc to free blocks
+/**
+ * ext4_free_blocks() -- Free given blocks and update quota
+ * @handle:		handle for this transaction
+ * @inode:		inode
+ * @block:		start physical block to free
+ * @count:		number of blocks to count
+ * @metadata: 		Are these metadata blocks
  */
-void ext4_mb_free_blocks(handle_t *handle, struct inode *inode,
-			ext4_fsblk_t block, unsigned long count,
-			int metadata, unsigned long *freed)
+void ext4_free_blocks(handle_t *handle, struct inode *inode,
+		      struct buffer_head *bh, ext4_fsblk_t block,
+		      unsigned long count, int flags)
 {
 	struct buffer_head *bitmap_bh = NULL;
 	struct super_block *sb = inode->i_sb;
 	struct ext4_allocation_context *ac = NULL;
 	struct ext4_group_desc *gdp;
 	struct ext4_super_block *es;
+	unsigned long freed = 0;
 	unsigned int overflow;
 	ext4_grpblk_t bit;
 	struct buffer_head *gd_bh;
@@ -4443,13 +4473,16 @@
 	int err = 0;
 	int ret;
 
-	*freed = 0;
+	if (bh) {
+		if (block)
+			BUG_ON(block != bh->b_blocknr);
+		else
+			block = bh->b_blocknr;
+	}
 
 	sbi = EXT4_SB(sb);
 	es = EXT4_SB(sb)->s_es;
-	if (block < le32_to_cpu(es->s_first_data_block) ||
-	    block + count < block ||
-	    block + count > ext4_blocks_count(es)) {
+	if (!ext4_data_block_valid(sbi, block, count)) {
 		ext4_error(sb, __func__,
 			    "Freeing blocks not in datazone - "
 			    "block = %llu, count = %lu", block, count);
@@ -4457,7 +4490,32 @@
 	}
 
 	ext4_debug("freeing block %llu\n", block);
-	trace_ext4_free_blocks(inode, block, count, metadata);
+	trace_ext4_free_blocks(inode, block, count, flags);
+
+	if (flags & EXT4_FREE_BLOCKS_FORGET) {
+		struct buffer_head *tbh = bh;
+		int i;
+
+		BUG_ON(bh && (count > 1));
+
+		for (i = 0; i < count; i++) {
+			if (!bh)
+				tbh = sb_find_get_block(inode->i_sb,
+							block + i);
+			ext4_forget(handle, flags & EXT4_FREE_BLOCKS_METADATA, 
+				    inode, tbh, block + i);
+		}
+	}
+
+	/* 
+	 * We need to make sure we don't reuse the freed block until
+	 * after the transaction is committed, which we can do by
+	 * treating the block as metadata, below.  We make an
+	 * exception if the inode is to be written in writeback mode
+	 * since writeback mode has weak data consistency guarantees.
+	 */
+	if (!ext4_should_writeback_data(inode))
+		flags |= EXT4_FREE_BLOCKS_METADATA;
 
 	ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS);
 	if (ac) {
@@ -4533,7 +4591,8 @@
 	err = ext4_mb_load_buddy(sb, block_group, &e4b);
 	if (err)
 		goto error_return;
-	if (metadata && ext4_handle_valid(handle)) {
+
+	if ((flags & EXT4_FREE_BLOCKS_METADATA) && ext4_handle_valid(handle)) {
 		struct ext4_free_data *new_entry;
 		/*
 		 * blocks being freed are metadata. these blocks shouldn't
@@ -4572,7 +4631,7 @@
 
 	ext4_mb_release_desc(&e4b);
 
-	*freed += count;
+	freed += count;
 
 	/* We dirtied the bitmap block */
 	BUFFER_TRACE(bitmap_bh, "dirtied bitmap block");
@@ -4592,6 +4651,8 @@
 	}
 	sb->s_dirt = 1;
 error_return:
+	if (freed)
+		vfs_dq_free_block(inode, freed);
 	brelse(bitmap_bh);
 	ext4_std_error(sb, err);
 	if (ac)
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
index a93d5b8..8141581 100644
--- a/fs/ext4/migrate.c
+++ b/fs/ext4/migrate.c
@@ -238,7 +238,7 @@
 	 * So allocate a credit of 3. We may update
 	 * quota (user and group).
 	 */
-	needed = 3 + 2*EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb);
+	needed = 3 + EXT4_MAXQUOTAS_TRANS_BLOCKS(inode->i_sb);
 
 	if (ext4_journal_extend(handle, needed) != 0)
 		retval = ext4_journal_restart(handle, needed);
@@ -262,13 +262,17 @@
 	for (i = 0; i < max_entries; i++) {
 		if (tmp_idata[i]) {
 			extend_credit_for_blkdel(handle, inode);
-			ext4_free_blocks(handle, inode,
-					le32_to_cpu(tmp_idata[i]), 1, 1);
+			ext4_free_blocks(handle, inode, 0,
+					 le32_to_cpu(tmp_idata[i]), 1,
+					 EXT4_FREE_BLOCKS_METADATA |
+					 EXT4_FREE_BLOCKS_FORGET);
 		}
 	}
 	put_bh(bh);
 	extend_credit_for_blkdel(handle, inode);
-	ext4_free_blocks(handle, inode, le32_to_cpu(i_data), 1, 1);
+	ext4_free_blocks(handle, inode, 0, le32_to_cpu(i_data), 1,
+			 EXT4_FREE_BLOCKS_METADATA |
+			 EXT4_FREE_BLOCKS_FORGET);
 	return 0;
 }
 
@@ -297,7 +301,9 @@
 	}
 	put_bh(bh);
 	extend_credit_for_blkdel(handle, inode);
-	ext4_free_blocks(handle, inode, le32_to_cpu(i_data), 1, 1);
+	ext4_free_blocks(handle, inode, 0, le32_to_cpu(i_data), 1,
+			 EXT4_FREE_BLOCKS_METADATA |
+			 EXT4_FREE_BLOCKS_FORGET);
 	return 0;
 }
 
@@ -308,8 +314,10 @@
 	/* ei->i_data[EXT4_IND_BLOCK] */
 	if (i_data[0]) {
 		extend_credit_for_blkdel(handle, inode);
-		ext4_free_blocks(handle, inode,
-				le32_to_cpu(i_data[0]), 1, 1);
+		ext4_free_blocks(handle, inode, 0,
+				le32_to_cpu(i_data[0]), 1,
+				 EXT4_FREE_BLOCKS_METADATA |
+				 EXT4_FREE_BLOCKS_FORGET);
 	}
 
 	/* ei->i_data[EXT4_DIND_BLOCK] */
@@ -419,7 +427,8 @@
 	}
 	put_bh(bh);
 	extend_credit_for_blkdel(handle, inode);
-	ext4_free_blocks(handle, inode, block, 1, 1);
+	ext4_free_blocks(handle, inode, 0, block, 1,
+			 EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET);
 	return retval;
 }
 
@@ -477,7 +486,7 @@
 	handle = ext4_journal_start(inode,
 					EXT4_DATA_TRANS_BLOCKS(inode->i_sb) +
 					EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
-					2 * EXT4_QUOTA_INIT_BLOCKS(inode->i_sb)
+					EXT4_MAXQUOTAS_INIT_BLOCKS(inode->i_sb)
 					+ 1);
 	if (IS_ERR(handle)) {
 		retval = PTR_ERR(handle);
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index 25b6b14..82c415b 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -77,12 +77,14 @@
 mext_next_extent(struct inode *inode, struct ext4_ext_path *path,
 		      struct ext4_extent **extent)
 {
+	struct ext4_extent_header *eh;
 	int ppos, leaf_ppos = path->p_depth;
 
 	ppos = leaf_ppos;
 	if (EXT_LAST_EXTENT(path[ppos].p_hdr) > path[ppos].p_ext) {
 		/* leaf block */
 		*extent = ++path[ppos].p_ext;
+		path[ppos].p_block = ext_pblock(path[ppos].p_ext);
 		return 0;
 	}
 
@@ -119,9 +121,18 @@
 					ext_block_hdr(path[cur_ppos+1].p_bh);
 			}
 
+			path[leaf_ppos].p_ext = *extent = NULL;
+
+			eh = path[leaf_ppos].p_hdr;
+			if (le16_to_cpu(eh->eh_entries) == 0)
+				/* empty leaf is found */
+				return -ENODATA;
+
 			/* leaf block */
 			path[leaf_ppos].p_ext = *extent =
 				EXT_FIRST_EXTENT(path[leaf_ppos].p_hdr);
+			path[leaf_ppos].p_block =
+					ext_pblock(path[leaf_ppos].p_ext);
 			return 0;
 		}
 	}
@@ -155,40 +166,15 @@
 }
 
 /**
- * mext_double_down_read - Acquire two inodes' read semaphore
+ * double_down_write_data_sem - Acquire two inodes' write lock of i_data_sem
  *
  * @orig_inode:		original inode structure
  * @donor_inode:	donor inode structure
- * Acquire read semaphore of the two inodes (orig and donor) by i_ino order.
+ * Acquire write lock of i_data_sem of the two inodes (orig and donor) by
+ * i_ino order.
  */
 static void
-mext_double_down_read(struct inode *orig_inode, struct inode *donor_inode)
-{
-	struct inode *first = orig_inode, *second = donor_inode;
-
-	/*
-	 * Use the inode number to provide the stable locking order instead
-	 * of its address, because the C language doesn't guarantee you can
-	 * compare pointers that don't come from the same array.
-	 */
-	if (donor_inode->i_ino < orig_inode->i_ino) {
-		first = donor_inode;
-		second = orig_inode;
-	}
-
-	down_read(&EXT4_I(first)->i_data_sem);
-	down_read(&EXT4_I(second)->i_data_sem);
-}
-
-/**
- * mext_double_down_write - Acquire two inodes' write semaphore
- *
- * @orig_inode:		original inode structure
- * @donor_inode:	donor inode structure
- * Acquire write semaphore of the two inodes (orig and donor) by i_ino order.
- */
-static void
-mext_double_down_write(struct inode *orig_inode, struct inode *donor_inode)
+double_down_write_data_sem(struct inode *orig_inode, struct inode *donor_inode)
 {
 	struct inode *first = orig_inode, *second = donor_inode;
 
@@ -203,32 +189,18 @@
 	}
 
 	down_write(&EXT4_I(first)->i_data_sem);
-	down_write(&EXT4_I(second)->i_data_sem);
+	down_write_nested(&EXT4_I(second)->i_data_sem, SINGLE_DEPTH_NESTING);
 }
 
 /**
- * mext_double_up_read - Release two inodes' read semaphore
+ * double_up_write_data_sem - Release two inodes' write lock of i_data_sem
  *
  * @orig_inode:		original inode structure to be released its lock first
  * @donor_inode:	donor inode structure to be released its lock second
- * Release read semaphore of two inodes (orig and donor).
+ * Release write lock of i_data_sem of two inodes (orig and donor).
  */
 static void
-mext_double_up_read(struct inode *orig_inode, struct inode *donor_inode)
-{
-	up_read(&EXT4_I(orig_inode)->i_data_sem);
-	up_read(&EXT4_I(donor_inode)->i_data_sem);
-}
-
-/**
- * mext_double_up_write - Release two inodes' write semaphore
- *
- * @orig_inode:		original inode structure to be released its lock first
- * @donor_inode:	donor inode structure to be released its lock second
- * Release write semaphore of two inodes (orig and donor).
- */
-static void
-mext_double_up_write(struct inode *orig_inode, struct inode *donor_inode)
+double_up_write_data_sem(struct inode *orig_inode, struct inode *donor_inode)
 {
 	up_write(&EXT4_I(orig_inode)->i_data_sem);
 	up_write(&EXT4_I(donor_inode)->i_data_sem);
@@ -596,7 +568,7 @@
  * @tmp_oext:		the extent that will belong to the donor inode
  * @orig_off:		block offset of original inode
  * @donor_off:		block offset of donor inode
- * @max_count:		the maximun length of extents
+ * @max_count:		the maximum length of extents
  *
  * Return 0 on success, or a negative error value on failure.
  */
@@ -661,6 +633,7 @@
  * @donor_inode:	donor inode
  * @from:		block offset of orig_inode
  * @count:		block count to be replaced
+ * @err:		pointer to save return value
  *
  * Replace original inode extents and donor inode extents page by page.
  * We implement this replacement in the following three steps:
@@ -671,33 +644,33 @@
  * 3. Change the block information of donor inode to point at the saved
  *    original inode blocks in the dummy extents.
  *
- * Return 0 on success, or a negative error value on failure.
+ * Return replaced block count.
  */
 static int
 mext_replace_branches(handle_t *handle, struct inode *orig_inode,
 			   struct inode *donor_inode, ext4_lblk_t from,
-			   ext4_lblk_t count)
+			   ext4_lblk_t count, int *err)
 {
 	struct ext4_ext_path *orig_path = NULL;
 	struct ext4_ext_path *donor_path = NULL;
 	struct ext4_extent *oext, *dext;
 	struct ext4_extent tmp_dext, tmp_oext;
 	ext4_lblk_t orig_off = from, donor_off = from;
-	int err = 0;
 	int depth;
 	int replaced_count = 0;
 	int dext_alen;
 
-	mext_double_down_write(orig_inode, donor_inode);
+	/* Protect extent trees against block allocations via delalloc */
+	double_down_write_data_sem(orig_inode, donor_inode);
 
 	/* Get the original extent for the block "orig_off" */
-	err = get_ext_path(orig_inode, orig_off, &orig_path);
-	if (err)
+	*err = get_ext_path(orig_inode, orig_off, &orig_path);
+	if (*err)
 		goto out;
 
 	/* Get the donor extent for the head */
-	err = get_ext_path(donor_inode, donor_off, &donor_path);
-	if (err)
+	*err = get_ext_path(donor_inode, donor_off, &donor_path);
+	if (*err)
 		goto out;
 	depth = ext_depth(orig_inode);
 	oext = orig_path[depth].p_ext;
@@ -707,9 +680,9 @@
 	dext = donor_path[depth].p_ext;
 	tmp_dext = *dext;
 
-	err = mext_calc_swap_extents(&tmp_dext, &tmp_oext, orig_off,
+	*err = mext_calc_swap_extents(&tmp_dext, &tmp_oext, orig_off,
 				      donor_off, count);
-	if (err)
+	if (*err)
 		goto out;
 
 	/* Loop for the donor extents */
@@ -718,7 +691,7 @@
 		if (!dext) {
 			ext4_error(donor_inode->i_sb, __func__,
 				   "The extent for donor must be found");
-			err = -EIO;
+			*err = -EIO;
 			goto out;
 		} else if (donor_off != le32_to_cpu(tmp_dext.ee_block)) {
 			ext4_error(donor_inode->i_sb, __func__,
@@ -726,20 +699,20 @@
 				"extent(%u) should be equal",
 				donor_off,
 				le32_to_cpu(tmp_dext.ee_block));
-			err = -EIO;
+			*err = -EIO;
 			goto out;
 		}
 
 		/* Set donor extent to orig extent */
-		err = mext_leaf_block(handle, orig_inode,
+		*err = mext_leaf_block(handle, orig_inode,
 					   orig_path, &tmp_dext, &orig_off);
-		if (err < 0)
+		if (*err)
 			goto out;
 
 		/* Set orig extent to donor extent */
-		err = mext_leaf_block(handle, donor_inode,
+		*err = mext_leaf_block(handle, donor_inode,
 					   donor_path, &tmp_oext, &donor_off);
-		if (err < 0)
+		if (*err)
 			goto out;
 
 		dext_alen = ext4_ext_get_actual_len(&tmp_dext);
@@ -753,35 +726,25 @@
 
 		if (orig_path)
 			ext4_ext_drop_refs(orig_path);
-		err = get_ext_path(orig_inode, orig_off, &orig_path);
-		if (err)
+		*err = get_ext_path(orig_inode, orig_off, &orig_path);
+		if (*err)
 			goto out;
 		depth = ext_depth(orig_inode);
 		oext = orig_path[depth].p_ext;
-		if (le32_to_cpu(oext->ee_block) +
-				ext4_ext_get_actual_len(oext) <= orig_off) {
-			err = 0;
-			goto out;
-		}
 		tmp_oext = *oext;
 
 		if (donor_path)
 			ext4_ext_drop_refs(donor_path);
-		err = get_ext_path(donor_inode, donor_off, &donor_path);
-		if (err)
+		*err = get_ext_path(donor_inode, donor_off, &donor_path);
+		if (*err)
 			goto out;
 		depth = ext_depth(donor_inode);
 		dext = donor_path[depth].p_ext;
-		if (le32_to_cpu(dext->ee_block) +
-				ext4_ext_get_actual_len(dext) <= donor_off) {
-			err = 0;
-			goto out;
-		}
 		tmp_dext = *dext;
 
-		err = mext_calc_swap_extents(&tmp_dext, &tmp_oext, orig_off,
+		*err = mext_calc_swap_extents(&tmp_dext, &tmp_oext, orig_off,
 					   donor_off, count - replaced_count);
-		if (err)
+		if (*err)
 			goto out;
 	}
 
@@ -795,8 +758,12 @@
 		kfree(donor_path);
 	}
 
-	mext_double_up_write(orig_inode, donor_inode);
-	return err;
+	ext4_ext_invalidate_cache(orig_inode);
+	ext4_ext_invalidate_cache(donor_inode);
+
+	double_up_write_data_sem(orig_inode, donor_inode);
+
+	return replaced_count;
 }
 
 /**
@@ -808,16 +775,17 @@
  * @data_offset_in_page:	block index where data swapping starts
  * @block_len_in_page:		the number of blocks to be swapped
  * @uninit:			orig extent is uninitialized or not
+ * @err:			pointer to save return value
  *
  * Save the data in original inode blocks and replace original inode extents
  * with donor inode extents by calling mext_replace_branches().
- * Finally, write out the saved data in new original inode blocks. Return 0
- * on success, or a negative error value on failure.
+ * Finally, write out the saved data in new original inode blocks. Return
+ * replaced block count.
  */
 static int
 move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
 		  pgoff_t orig_page_offset, int data_offset_in_page,
-		  int block_len_in_page, int uninit)
+		  int block_len_in_page, int uninit, int *err)
 {
 	struct inode *orig_inode = o_filp->f_dentry->d_inode;
 	struct address_space *mapping = orig_inode->i_mapping;
@@ -829,9 +797,11 @@
 	long long offs = orig_page_offset << PAGE_CACHE_SHIFT;
 	unsigned long blocksize = orig_inode->i_sb->s_blocksize;
 	unsigned int w_flags = 0;
-	unsigned int tmp_data_len, data_len;
+	unsigned int tmp_data_size, data_size, replaced_size;
 	void *fsdata;
-	int ret, i, jblocks;
+	int i, jblocks;
+	int err2 = 0;
+	int replaced_count = 0;
 	int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits;
 
 	/*
@@ -841,8 +811,8 @@
 	jblocks = ext4_writepage_trans_blocks(orig_inode) * 2;
 	handle = ext4_journal_start(orig_inode, jblocks);
 	if (IS_ERR(handle)) {
-		ret = PTR_ERR(handle);
-		return ret;
+		*err = PTR_ERR(handle);
+		return 0;
 	}
 
 	if (segment_eq(get_fs(), KERNEL_DS))
@@ -858,39 +828,36 @@
 	 * Just swap data blocks between orig and donor.
 	 */
 	if (uninit) {
-		ret = mext_replace_branches(handle, orig_inode,
-						 donor_inode, orig_blk_offset,
-						 block_len_in_page);
-
-		/* Clear the inode cache not to refer to the old data */
-		ext4_ext_invalidate_cache(orig_inode);
-		ext4_ext_invalidate_cache(donor_inode);
+		replaced_count = mext_replace_branches(handle, orig_inode,
+						donor_inode, orig_blk_offset,
+						block_len_in_page, err);
 		goto out2;
 	}
 
 	offs = (long long)orig_blk_offset << orig_inode->i_blkbits;
 
-	/* Calculate data_len */
+	/* Calculate data_size */
 	if ((orig_blk_offset + block_len_in_page - 1) ==
 	    ((orig_inode->i_size - 1) >> orig_inode->i_blkbits)) {
 		/* Replace the last block */
-		tmp_data_len = orig_inode->i_size & (blocksize - 1);
+		tmp_data_size = orig_inode->i_size & (blocksize - 1);
 		/*
-		 * If data_len equal zero, it shows data_len is multiples of
+		 * If data_size equal zero, it shows data_size is multiples of
 		 * blocksize. So we set appropriate value.
 		 */
-		if (tmp_data_len == 0)
-			tmp_data_len = blocksize;
+		if (tmp_data_size == 0)
+			tmp_data_size = blocksize;
 
-		data_len = tmp_data_len +
+		data_size = tmp_data_size +
 			((block_len_in_page - 1) << orig_inode->i_blkbits);
-	} else {
-		data_len = block_len_in_page << orig_inode->i_blkbits;
-	}
+	} else
+		data_size = block_len_in_page << orig_inode->i_blkbits;
 
-	ret = a_ops->write_begin(o_filp, mapping, offs, data_len, w_flags,
+	replaced_size = data_size;
+
+	*err = a_ops->write_begin(o_filp, mapping, offs, data_size, w_flags,
 				 &page, &fsdata);
-	if (unlikely(ret < 0))
+	if (unlikely(*err < 0))
 		goto out;
 
 	if (!PageUptodate(page)) {
@@ -911,14 +878,17 @@
 	/* Release old bh and drop refs */
 	try_to_release_page(page, 0);
 
-	ret = mext_replace_branches(handle, orig_inode, donor_inode,
-					 orig_blk_offset, block_len_in_page);
-	if (ret < 0)
-		goto out;
-
-	/* Clear the inode cache not to refer to the old data */
-	ext4_ext_invalidate_cache(orig_inode);
-	ext4_ext_invalidate_cache(donor_inode);
+	replaced_count = mext_replace_branches(handle, orig_inode, donor_inode,
+					orig_blk_offset, block_len_in_page,
+					&err2);
+	if (err2) {
+		if (replaced_count) {
+			block_len_in_page = replaced_count;
+			replaced_size =
+				block_len_in_page << orig_inode->i_blkbits;
+		} else
+			goto out;
+	}
 
 	if (!page_has_buffers(page))
 		create_empty_buffers(page, 1 << orig_inode->i_blkbits, 0);
@@ -928,16 +898,16 @@
 		bh = bh->b_this_page;
 
 	for (i = 0; i < block_len_in_page; i++) {
-		ret = ext4_get_block(orig_inode,
+		*err = ext4_get_block(orig_inode,
 				(sector_t)(orig_blk_offset + i), bh, 0);
-		if (ret < 0)
+		if (*err < 0)
 			goto out;
 
 		if (bh->b_this_page != NULL)
 			bh = bh->b_this_page;
 	}
 
-	ret = a_ops->write_end(o_filp, mapping, offs, data_len, data_len,
+	*err = a_ops->write_end(o_filp, mapping, offs, data_size, replaced_size,
 			       page, fsdata);
 	page = NULL;
 
@@ -951,7 +921,10 @@
 out2:
 	ext4_journal_stop(handle);
 
-	return ret < 0 ? ret : 0;
+	if (err2)
+		*err = err2;
+
+	return replaced_count;
 }
 
 /**
@@ -962,7 +935,6 @@
  * @orig_start:		logical start offset in block for orig
  * @donor_start:	logical start offset in block for donor
  * @len:		the number of blocks to be moved
- * @moved_len:		moved block length
  *
  * Check the arguments of ext4_move_extents() whether the files can be
  * exchanged with each other.
@@ -970,8 +942,8 @@
  */
 static int
 mext_check_arguments(struct inode *orig_inode,
-			  struct inode *donor_inode, __u64 orig_start,
-			  __u64 donor_start, __u64 *len, __u64 moved_len)
+		     struct inode *donor_inode, __u64 orig_start,
+		     __u64 donor_start, __u64 *len)
 {
 	ext4_lblk_t orig_blocks, donor_blocks;
 	unsigned int blkbits = orig_inode->i_blkbits;
@@ -985,6 +957,13 @@
 		return -EINVAL;
 	}
 
+	if (donor_inode->i_mode & (S_ISUID|S_ISGID)) {
+		ext4_debug("ext4 move extent: suid or sgid is set"
+			   " to donor file [ino:orig %lu, donor %lu]\n",
+			   orig_inode->i_ino, donor_inode->i_ino);
+		return -EINVAL;
+	}
+
 	/* Ext4 move extent does not support swapfile */
 	if (IS_SWAPFILE(orig_inode) || IS_SWAPFILE(donor_inode)) {
 		ext4_debug("ext4 move extent: The argument files should "
@@ -1025,13 +1004,6 @@
 		return -EINVAL;
 	}
 
-	if (moved_len) {
-		ext4_debug("ext4 move extent: moved_len should be 0 "
-			"[ino:orig %lu, donor %lu]\n", orig_inode->i_ino,
-			donor_inode->i_ino);
-		return -EINVAL;
-	}
-
 	if ((orig_start > EXT_MAX_BLOCK) ||
 	    (donor_start > EXT_MAX_BLOCK) ||
 	    (*len > EXT_MAX_BLOCK) ||
@@ -1088,7 +1060,7 @@
 	}
 
 	if (!*len) {
-		ext4_debug("ext4 move extent: len shoudld not be 0 "
+		ext4_debug("ext4 move extent: len should not be 0 "
 			"[ino:orig %lu, donor %lu]\n", orig_inode->i_ino,
 			donor_inode->i_ino);
 		return -EINVAL;
@@ -1232,16 +1204,16 @@
 		return -EINVAL;
 	}
 
-	/* protect orig and donor against a truncate */
+	/* Protect orig and donor inodes against a truncate */
 	ret1 = mext_inode_double_lock(orig_inode, donor_inode);
 	if (ret1 < 0)
 		return ret1;
 
-	mext_double_down_read(orig_inode, donor_inode);
+	/* Protect extent tree against block allocations via delalloc */
+	double_down_write_data_sem(orig_inode, donor_inode);
 	/* Check the filesystem environment whether move_extent can be done */
 	ret1 = mext_check_arguments(orig_inode, donor_inode, orig_start,
-					donor_start, &len, *moved_len);
-	mext_double_up_read(orig_inode, donor_inode);
+				    donor_start, &len);
 	if (ret1)
 		goto out;
 
@@ -1355,36 +1327,39 @@
 		seq_start = le32_to_cpu(ext_cur->ee_block);
 		rest_blocks = seq_blocks;
 
-		/* Discard preallocations of two inodes */
-		down_write(&EXT4_I(orig_inode)->i_data_sem);
-		ext4_discard_preallocations(orig_inode);
-		up_write(&EXT4_I(orig_inode)->i_data_sem);
-
-		down_write(&EXT4_I(donor_inode)->i_data_sem);
-		ext4_discard_preallocations(donor_inode);
-		up_write(&EXT4_I(donor_inode)->i_data_sem);
+		/*
+		 * Up semaphore to avoid following problems:
+		 * a. transaction deadlock among ext4_journal_start,
+		 *    ->write_begin via pagefault, and jbd2_journal_commit
+		 * b. racing with ->readpage, ->write_begin, and ext4_get_block
+		 *    in move_extent_per_page
+		 */
+		double_up_write_data_sem(orig_inode, donor_inode);
 
 		while (orig_page_offset <= seq_end_page) {
 
 			/* Swap original branches with new branches */
-			ret1 = move_extent_per_page(o_filp, donor_inode,
+			block_len_in_page = move_extent_per_page(
+						o_filp, donor_inode,
 						orig_page_offset,
 						data_offset_in_page,
-						block_len_in_page, uninit);
-			if (ret1 < 0)
-				goto out;
-			orig_page_offset++;
+						block_len_in_page, uninit,
+						&ret1);
+
 			/* Count how many blocks we have exchanged */
 			*moved_len += block_len_in_page;
+			if (ret1 < 0)
+				break;
 			if (*moved_len > len) {
 				ext4_error(orig_inode->i_sb, __func__,
 					"We replaced blocks too much! "
 					"sum of replaced: %llu requested: %llu",
 					*moved_len, len);
 				ret1 = -EIO;
-				goto out;
+				break;
 			}
 
+			orig_page_offset++;
 			data_offset_in_page = 0;
 			rest_blocks -= block_len_in_page;
 			if (rest_blocks > blocks_per_page)
@@ -1393,6 +1368,10 @@
 				block_len_in_page = rest_blocks;
 		}
 
+		double_down_write_data_sem(orig_inode, donor_inode);
+		if (ret1 < 0)
+			break;
+
 		/* Decrease buffer counter */
 		if (holecheck_path)
 			ext4_ext_drop_refs(holecheck_path);
@@ -1414,6 +1393,11 @@
 
 	}
 out:
+	if (*moved_len) {
+		ext4_discard_preallocations(orig_inode);
+		ext4_discard_preallocations(donor_inode);
+	}
+
 	if (orig_path) {
 		ext4_ext_drop_refs(orig_path);
 		kfree(orig_path);
@@ -1422,7 +1406,7 @@
 		ext4_ext_drop_refs(holecheck_path);
 		kfree(holecheck_path);
 	}
-
+	double_up_write_data_sem(orig_inode, donor_inode);
 	ret2 = mext_inode_double_unlock(orig_inode, donor_inode);
 
 	if (ret1)
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 6d2c1b8..17a17e1 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1292,9 +1292,6 @@
  * add_dirent_to_buf will attempt search the directory block for
  * space.  It will return -ENOSPC if no space is available, and -EIO
  * and -EEXIST if directory entry already exists.
- *
- * NOTE!  bh is NOT released in the case where ENOSPC is returned.  In
- * all other cases bh is released.
  */
 static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
 			     struct inode *inode, struct ext4_dir_entry_2 *de,
@@ -1315,14 +1312,10 @@
 		top = bh->b_data + blocksize - reclen;
 		while ((char *) de <= top) {
 			if (!ext4_check_dir_entry("ext4_add_entry", dir, de,
-						  bh, offset)) {
-				brelse(bh);
+						  bh, offset))
 				return -EIO;
-			}
-			if (ext4_match(namelen, name, de)) {
-				brelse(bh);
+			if (ext4_match(namelen, name, de))
 				return -EEXIST;
-			}
 			nlen = EXT4_DIR_REC_LEN(de->name_len);
 			rlen = ext4_rec_len_from_disk(de->rec_len, blocksize);
 			if ((de->inode? rlen - nlen: rlen) >= reclen)
@@ -1337,7 +1330,6 @@
 	err = ext4_journal_get_write_access(handle, bh);
 	if (err) {
 		ext4_std_error(dir->i_sb, err);
-		brelse(bh);
 		return err;
 	}
 
@@ -1377,7 +1369,6 @@
 	err = ext4_handle_dirty_metadata(handle, dir, bh);
 	if (err)
 		ext4_std_error(dir->i_sb, err);
-	brelse(bh);
 	return 0;
 }
 
@@ -1471,7 +1462,9 @@
 	if (!(de))
 		return retval;
 
-	return add_dirent_to_buf(handle, dentry, inode, de, bh);
+	retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
+	brelse(bh);
+	return retval;
 }
 
 /*
@@ -1514,8 +1507,10 @@
 		if(!bh)
 			return retval;
 		retval = add_dirent_to_buf(handle, dentry, inode, NULL, bh);
-		if (retval != -ENOSPC)
+		if (retval != -ENOSPC) {
+			brelse(bh);
 			return retval;
+		}
 
 		if (blocks == 1 && !dx_fallback &&
 		    EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX))
@@ -1528,7 +1523,9 @@
 	de = (struct ext4_dir_entry_2 *) bh->b_data;
 	de->inode = 0;
 	de->rec_len = ext4_rec_len_to_disk(blocksize, blocksize);
-	return add_dirent_to_buf(handle, dentry, inode, de, bh);
+	retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
+	brelse(bh);
+	return retval;
 }
 
 /*
@@ -1561,10 +1558,8 @@
 		goto journal_error;
 
 	err = add_dirent_to_buf(handle, dentry, inode, NULL, bh);
-	if (err != -ENOSPC) {
-		bh = NULL;
+	if (err != -ENOSPC)
 		goto cleanup;
-	}
 
 	/* Block full, should compress but for now just split */
 	dxtrace(printk(KERN_DEBUG "using %u of %u node entries\n",
@@ -1657,7 +1652,6 @@
 	if (!de)
 		goto cleanup;
 	err = add_dirent_to_buf(handle, dentry, inode, de, bh);
-	bh = NULL;
 	goto cleanup;
 
 journal_error:
@@ -1775,7 +1769,7 @@
 retry:
 	handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
 					EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
-					2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
+					EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb));
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
 
@@ -1809,7 +1803,7 @@
 retry:
 	handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
 					EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
-					2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
+					EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb));
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
 
@@ -1846,7 +1840,7 @@
 retry:
 	handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
 					EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
-					2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
+					EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb));
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
 
@@ -2259,7 +2253,7 @@
 retry:
 	handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
 					EXT4_INDEX_EXTRA_TRANS_BLOCKS + 5 +
-					2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
+					EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb));
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
 
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 3cfc343..3b2c554 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -247,7 +247,7 @@
 			goto exit_bh;
 
 		if (IS_ERR(gdb = bclean(handle, sb, block))) {
-			err = PTR_ERR(bh);
+			err = PTR_ERR(gdb);
 			goto exit_bh;
 		}
 		ext4_handle_dirty_metadata(handle, NULL, gdb);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index d4ca92a..768c111 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -603,10 +603,6 @@
 	if (sb->s_dirt)
 		ext4_commit_super(sb, 1);
 
-	ext4_release_system_zone(sb);
-	ext4_mb_release(sb);
-	ext4_ext_release(sb);
-	ext4_xattr_put_super(sb);
 	if (sbi->s_journal) {
 		err = jbd2_journal_destroy(sbi->s_journal);
 		sbi->s_journal = NULL;
@@ -614,6 +610,12 @@
 			ext4_abort(sb, __func__,
 				   "Couldn't clean up the journal");
 	}
+
+	ext4_release_system_zone(sb);
+	ext4_mb_release(sb);
+	ext4_ext_release(sb);
+	ext4_xattr_put_super(sb);
+
 	if (!(sb->s_flags & MS_RDONLY)) {
 		EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
 		es->s_state = cpu_to_le16(sbi->s_mount_state);
@@ -704,6 +706,8 @@
 	spin_lock_init(&(ei->i_block_reservation_lock));
 	INIT_LIST_HEAD(&ei->i_aio_dio_complete_list);
 	ei->cur_aio_dio = NULL;
+	ei->i_sync_tid = 0;
+	ei->i_datasync_tid = 0;
 
 	return &ei->vfs_inode;
 }
@@ -765,9 +769,22 @@
 #if defined(CONFIG_QUOTA)
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
 
-	if (sbi->s_jquota_fmt)
-		seq_printf(seq, ",jqfmt=%s",
-		(sbi->s_jquota_fmt == QFMT_VFS_OLD) ? "vfsold" : "vfsv0");
+	if (sbi->s_jquota_fmt) {
+		char *fmtname = "";
+
+		switch (sbi->s_jquota_fmt) {
+		case QFMT_VFS_OLD:
+			fmtname = "vfsold";
+			break;
+		case QFMT_VFS_V0:
+			fmtname = "vfsv0";
+			break;
+		case QFMT_VFS_V1:
+			fmtname = "vfsv1";
+			break;
+		}
+		seq_printf(seq, ",jqfmt=%s", fmtname);
+	}
 
 	if (sbi->s_qf_names[USRQUOTA])
 		seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]);
@@ -899,6 +916,12 @@
 	if (test_opt(sb, NO_AUTO_DA_ALLOC))
 		seq_puts(seq, ",noauto_da_alloc");
 
+	if (test_opt(sb, DISCARD))
+		seq_puts(seq, ",discard");
+
+	if (test_opt(sb, NOLOAD))
+		seq_puts(seq, ",norecovery");
+
 	ext4_show_quota_options(seq, sb);
 
 	return 0;
@@ -1074,12 +1097,13 @@
 	Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
 	Opt_data_err_abort, Opt_data_err_ignore,
 	Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
-	Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
-	Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, Opt_resize,
-	Opt_usrquota, Opt_grpquota, Opt_i_version,
+	Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota,
+	Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err,
+	Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version,
 	Opt_stripe, Opt_delalloc, Opt_nodelalloc,
 	Opt_block_validity, Opt_noblock_validity,
-	Opt_inode_readahead_blks, Opt_journal_ioprio
+	Opt_inode_readahead_blks, Opt_journal_ioprio,
+	Opt_discard, Opt_nodiscard,
 };
 
 static const match_table_t tokens = {
@@ -1104,6 +1128,7 @@
 	{Opt_acl, "acl"},
 	{Opt_noacl, "noacl"},
 	{Opt_noload, "noload"},
+	{Opt_noload, "norecovery"},
 	{Opt_nobh, "nobh"},
 	{Opt_bh, "bh"},
 	{Opt_commit, "commit=%u"},
@@ -1125,6 +1150,7 @@
 	{Opt_grpjquota, "grpjquota=%s"},
 	{Opt_jqfmt_vfsold, "jqfmt=vfsold"},
 	{Opt_jqfmt_vfsv0, "jqfmt=vfsv0"},
+	{Opt_jqfmt_vfsv1, "jqfmt=vfsv1"},
 	{Opt_grpquota, "grpquota"},
 	{Opt_noquota, "noquota"},
 	{Opt_quota, "quota"},
@@ -1144,6 +1170,8 @@
 	{Opt_auto_da_alloc, "auto_da_alloc=%u"},
 	{Opt_auto_da_alloc, "auto_da_alloc"},
 	{Opt_noauto_da_alloc, "noauto_da_alloc"},
+	{Opt_discard, "discard"},
+	{Opt_nodiscard, "nodiscard"},
 	{Opt_err, NULL},
 };
 
@@ -1425,6 +1453,9 @@
 			goto set_qf_format;
 		case Opt_jqfmt_vfsv0:
 			qfmt = QFMT_VFS_V0;
+			goto set_qf_format;
+		case Opt_jqfmt_vfsv1:
+			qfmt = QFMT_VFS_V1;
 set_qf_format:
 			if (sb_any_quota_loaded(sb) &&
 			    sbi->s_jquota_fmt != qfmt) {
@@ -1467,6 +1498,7 @@
 		case Opt_offgrpjquota:
 		case Opt_jqfmt_vfsold:
 		case Opt_jqfmt_vfsv0:
+		case Opt_jqfmt_vfsv1:
 			ext4_msg(sb, KERN_ERR,
 				"journaled quota options not supported");
 			break;
@@ -1565,6 +1597,12 @@
 			else
 				set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC);
 			break;
+		case Opt_discard:
+			set_opt(sbi->s_mount_opt, DISCARD);
+			break;
+		case Opt_nodiscard:
+			clear_opt(sbi->s_mount_opt, DISCARD);
+			break;
 		default:
 			ext4_msg(sb, KERN_ERR,
 			       "Unrecognized mount option \"%s\" "
@@ -1673,14 +1711,14 @@
 	size_t size;
 	int i;
 
-	if (!sbi->s_es->s_log_groups_per_flex) {
+	sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex;
+	groups_per_flex = 1 << sbi->s_log_groups_per_flex;
+
+	if (groups_per_flex < 2) {
 		sbi->s_log_groups_per_flex = 0;
 		return 1;
 	}
 
-	sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex;
-	groups_per_flex = 1 << sbi->s_log_groups_per_flex;
-
 	/* We allocate both existing and potentially added groups */
 	flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) +
 			((le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) + 1) <<
@@ -2721,26 +2759,6 @@
 	    EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) {
 		if (ext4_load_journal(sb, es, journal_devnum))
 			goto failed_mount3;
-		if (!(sb->s_flags & MS_RDONLY) &&
-		    EXT4_SB(sb)->s_journal->j_failed_commit) {
-			ext4_msg(sb, KERN_CRIT, "error: "
-			       "ext4_fill_super: Journal transaction "
-			       "%u is corrupt",
-			       EXT4_SB(sb)->s_journal->j_failed_commit);
-			if (test_opt(sb, ERRORS_RO)) {
-				ext4_msg(sb, KERN_CRIT,
-				       "Mounting filesystem read-only");
-				sb->s_flags |= MS_RDONLY;
-				EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS;
-				es->s_state |= cpu_to_le16(EXT4_ERROR_FS);
-			}
-			if (test_opt(sb, ERRORS_PANIC)) {
-				EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS;
-				es->s_state |= cpu_to_le16(EXT4_ERROR_FS);
-				ext4_commit_super(sb, 1);
-				goto failed_mount4;
-			}
-		}
 	} else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) &&
 	      EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) {
 		ext4_msg(sb, KERN_ERR, "required journal recovery "
@@ -3668,13 +3686,11 @@
 	buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last;
 	buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter) -
 		       percpu_counter_sum_positive(&sbi->s_dirtyblocks_counter);
-	ext4_free_blocks_count_set(es, buf->f_bfree);
 	buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es);
 	if (buf->f_bfree < ext4_r_blocks_count(es))
 		buf->f_bavail = 0;
 	buf->f_files = le32_to_cpu(es->s_inodes_count);
 	buf->f_ffree = percpu_counter_sum_positive(&sbi->s_freeinodes_counter);
-	es->s_free_inodes_count = cpu_to_le32(buf->f_ffree);
 	buf->f_namelen = EXT4_NAME_LEN;
 	fsid = le64_to_cpup((void *)es->s_uuid) ^
 	       le64_to_cpup((void *)es->s_uuid + sizeof(u64));
@@ -3966,6 +3982,58 @@
 	return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super,mnt);
 }
 
+#if !defined(CONTIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23)
+static struct file_system_type ext2_fs_type = {
+	.owner		= THIS_MODULE,
+	.name		= "ext2",
+	.get_sb		= ext4_get_sb,
+	.kill_sb	= kill_block_super,
+	.fs_flags	= FS_REQUIRES_DEV,
+};
+
+static inline void register_as_ext2(void)
+{
+	int err = register_filesystem(&ext2_fs_type);
+	if (err)
+		printk(KERN_WARNING
+		       "EXT4-fs: Unable to register as ext2 (%d)\n", err);
+}
+
+static inline void unregister_as_ext2(void)
+{
+	unregister_filesystem(&ext2_fs_type);
+}
+#else
+static inline void register_as_ext2(void) { }
+static inline void unregister_as_ext2(void) { }
+#endif
+
+#if !defined(CONTIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23)
+static struct file_system_type ext3_fs_type = {
+	.owner		= THIS_MODULE,
+	.name		= "ext3",
+	.get_sb		= ext4_get_sb,
+	.kill_sb	= kill_block_super,
+	.fs_flags	= FS_REQUIRES_DEV,
+};
+
+static inline void register_as_ext3(void)
+{
+	int err = register_filesystem(&ext3_fs_type);
+	if (err)
+		printk(KERN_WARNING
+		       "EXT4-fs: Unable to register as ext3 (%d)\n", err);
+}
+
+static inline void unregister_as_ext3(void)
+{
+	unregister_filesystem(&ext3_fs_type);
+}
+#else
+static inline void register_as_ext3(void) { }
+static inline void unregister_as_ext3(void) { }
+#endif
+
 static struct file_system_type ext4_fs_type = {
 	.owner		= THIS_MODULE,
 	.name		= "ext4",
@@ -3995,11 +4063,15 @@
 	err = init_inodecache();
 	if (err)
 		goto out1;
+	register_as_ext2();
+	register_as_ext3();
 	err = register_filesystem(&ext4_fs_type);
 	if (err)
 		goto out;
 	return 0;
 out:
+	unregister_as_ext2();
+	unregister_as_ext3();
 	destroy_inodecache();
 out1:
 	exit_ext4_xattr();
@@ -4015,6 +4087,8 @@
 
 static void __exit exit_ext4_fs(void)
 {
+	unregister_as_ext2();
+	unregister_as_ext3();
 	unregister_filesystem(&ext4_fs_type);
 	destroy_inodecache();
 	exit_ext4_xattr();
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index fed5b01..910bf9a 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -482,9 +482,10 @@
 		ea_bdebug(bh, "refcount now=0; freeing");
 		if (ce)
 			mb_cache_entry_free(ce);
-		ext4_free_blocks(handle, inode, bh->b_blocknr, 1, 1);
 		get_bh(bh);
-		ext4_forget(handle, 1, inode, bh, bh->b_blocknr);
+		ext4_free_blocks(handle, inode, bh, 0, 1,
+				 EXT4_FREE_BLOCKS_METADATA |
+				 EXT4_FREE_BLOCKS_FORGET);
 	} else {
 		le32_add_cpu(&BHDR(bh)->h_refcount, -1);
 		error = ext4_handle_dirty_metadata(handle, inode, bh);
@@ -832,7 +833,8 @@
 			new_bh = sb_getblk(sb, block);
 			if (!new_bh) {
 getblk_failed:
-				ext4_free_blocks(handle, inode, block, 1, 1);
+				ext4_free_blocks(handle, inode, 0, block, 1,
+						 EXT4_FREE_BLOCKS_METADATA);
 				error = -EIO;
 				goto cleanup;
 			}
@@ -988,6 +990,10 @@
 	if (error)
 		goto cleanup;
 
+	error = ext4_journal_get_write_access(handle, is.iloc.bh);
+	if (error)
+		goto cleanup;
+
 	if (EXT4_I(inode)->i_state & EXT4_STATE_NEW) {
 		struct ext4_inode *raw_inode = ext4_raw_inode(&is.iloc);
 		memset(raw_inode, 0, EXT4_SB(inode->i_sb)->s_inode_size);
@@ -1013,9 +1019,6 @@
 		if (flags & XATTR_CREATE)
 			goto cleanup;
 	}
-	error = ext4_journal_get_write_access(handle, is.iloc.bh);
-	if (error)
-		goto cleanup;
 	if (!value) {
 		if (!is.s.not_found)
 			error = ext4_xattr_ibody_set(handle, inode, &i, &is);
diff --git a/fs/isofs/compress.c b/fs/isofs/compress.c
index defb932..0b3fa79 100644
--- a/fs/isofs/compress.c
+++ b/fs/isofs/compress.c
@@ -36,6 +36,260 @@
 static DEFINE_MUTEX(zisofs_zlib_lock);
 
 /*
+ * Read data of @inode from @block_start to @block_end and uncompress
+ * to one zisofs block. Store the data in the @pages array with @pcount
+ * entries. Start storing at offset @poffset of the first page.
+ */
+static loff_t zisofs_uncompress_block(struct inode *inode, loff_t block_start,
+				      loff_t block_end, int pcount,
+				      struct page **pages, unsigned poffset,
+				      int *errp)
+{
+	unsigned int zisofs_block_shift = ISOFS_I(inode)->i_format_parm[1];
+	unsigned int bufsize = ISOFS_BUFFER_SIZE(inode);
+	unsigned int bufshift = ISOFS_BUFFER_BITS(inode);
+	unsigned int bufmask = bufsize - 1;
+	int i, block_size = block_end - block_start;
+	z_stream stream = { .total_out = 0,
+			    .avail_in = 0,
+			    .avail_out = 0, };
+	int zerr;
+	int needblocks = (block_size + (block_start & bufmask) + bufmask)
+				>> bufshift;
+	int haveblocks;
+	blkcnt_t blocknum;
+	struct buffer_head *bhs[needblocks + 1];
+	int curbh, curpage;
+
+	if (block_size > deflateBound(1UL << zisofs_block_shift)) {
+		*errp = -EIO;
+		return 0;
+	}
+	/* Empty block? */
+	if (block_size == 0) {
+		for ( i = 0 ; i < pcount ; i++ ) {
+			if (!pages[i])
+				continue;
+			memset(page_address(pages[i]), 0, PAGE_CACHE_SIZE);
+			flush_dcache_page(pages[i]);
+			SetPageUptodate(pages[i]);
+		}
+		return ((loff_t)pcount) << PAGE_CACHE_SHIFT;
+	}
+
+	/* Because zlib is not thread-safe, do all the I/O at the top. */
+	blocknum = block_start >> bufshift;
+	memset(bhs, 0, (needblocks + 1) * sizeof(struct buffer_head *));
+	haveblocks = isofs_get_blocks(inode, blocknum, bhs, needblocks);
+	ll_rw_block(READ, haveblocks, bhs);
+
+	curbh = 0;
+	curpage = 0;
+	/*
+	 * First block is special since it may be fractional.  We also wait for
+	 * it before grabbing the zlib mutex; odds are that the subsequent
+	 * blocks are going to come in in short order so we don't hold the zlib
+	 * mutex longer than necessary.
+	 */
+
+	if (!bhs[0])
+		goto b_eio;
+
+	wait_on_buffer(bhs[0]);
+	if (!buffer_uptodate(bhs[0])) {
+		*errp = -EIO;
+		goto b_eio;
+	}
+
+	stream.workspace = zisofs_zlib_workspace;
+	mutex_lock(&zisofs_zlib_lock);
+		
+	zerr = zlib_inflateInit(&stream);
+	if (zerr != Z_OK) {
+		if (zerr == Z_MEM_ERROR)
+			*errp = -ENOMEM;
+		else
+			*errp = -EIO;
+		printk(KERN_DEBUG "zisofs: zisofs_inflateInit returned %d\n",
+			       zerr);
+		goto z_eio;
+	}
+
+	while (curpage < pcount && curbh < haveblocks &&
+	       zerr != Z_STREAM_END) {
+		if (!stream.avail_out) {
+			if (pages[curpage]) {
+				stream.next_out = page_address(pages[curpage])
+						+ poffset;
+				stream.avail_out = PAGE_CACHE_SIZE - poffset;
+				poffset = 0;
+			} else {
+				stream.next_out = (void *)&zisofs_sink_page;
+				stream.avail_out = PAGE_CACHE_SIZE;
+			}
+		}
+		if (!stream.avail_in) {
+			wait_on_buffer(bhs[curbh]);
+			if (!buffer_uptodate(bhs[curbh])) {
+				*errp = -EIO;
+				break;
+			}
+			stream.next_in  = bhs[curbh]->b_data +
+						(block_start & bufmask);
+			stream.avail_in = min_t(unsigned, bufsize -
+						(block_start & bufmask),
+						block_size);
+			block_size -= stream.avail_in;
+			block_start = 0;
+		}
+
+		while (stream.avail_out && stream.avail_in) {
+			zerr = zlib_inflate(&stream, Z_SYNC_FLUSH);
+			if (zerr == Z_BUF_ERROR && stream.avail_in == 0)
+				break;
+			if (zerr == Z_STREAM_END)
+				break;
+			if (zerr != Z_OK) {
+				/* EOF, error, or trying to read beyond end of input */
+				if (zerr == Z_MEM_ERROR)
+					*errp = -ENOMEM;
+				else {
+					printk(KERN_DEBUG
+					       "zisofs: zisofs_inflate returned"
+					       " %d, inode = %lu,"
+					       " page idx = %d, bh idx = %d,"
+					       " avail_in = %d,"
+					       " avail_out = %d\n",
+					       zerr, inode->i_ino, curpage,
+					       curbh, stream.avail_in,
+					       stream.avail_out);
+					*errp = -EIO;
+				}
+				goto inflate_out;
+			}
+		}
+
+		if (!stream.avail_out) {
+			/* This page completed */
+			if (pages[curpage]) {
+				flush_dcache_page(pages[curpage]);
+				SetPageUptodate(pages[curpage]);
+			}
+			curpage++;
+		}
+		if (!stream.avail_in)
+			curbh++;
+	}
+inflate_out:
+	zlib_inflateEnd(&stream);
+
+z_eio:
+	mutex_unlock(&zisofs_zlib_lock);
+
+b_eio:
+	for (i = 0; i < haveblocks; i++)
+		brelse(bhs[i]);
+	return stream.total_out;
+}
+
+/*
+ * Uncompress data so that pages[full_page] is fully uptodate and possibly
+ * fills in other pages if we have data for them.
+ */
+static int zisofs_fill_pages(struct inode *inode, int full_page, int pcount,
+			     struct page **pages)
+{
+	loff_t start_off, end_off;
+	loff_t block_start, block_end;
+	unsigned int header_size = ISOFS_I(inode)->i_format_parm[0];
+	unsigned int zisofs_block_shift = ISOFS_I(inode)->i_format_parm[1];
+	unsigned int blockptr;
+	loff_t poffset = 0;
+	blkcnt_t cstart_block, cend_block;
+	struct buffer_head *bh;
+	unsigned int blkbits = ISOFS_BUFFER_BITS(inode);
+	unsigned int blksize = 1 << blkbits;
+	int err;
+	loff_t ret;
+
+	BUG_ON(!pages[full_page]);
+
+	/*
+	 * We want to read at least 'full_page' page. Because we have to
+	 * uncompress the whole compression block anyway, fill the surrounding
+	 * pages with the data we have anyway...
+	 */
+	start_off = page_offset(pages[full_page]);
+	end_off = min_t(loff_t, start_off + PAGE_CACHE_SIZE, inode->i_size);
+
+	cstart_block = start_off >> zisofs_block_shift;
+	cend_block = (end_off + (1 << zisofs_block_shift) - 1)
+			>> zisofs_block_shift;
+
+	WARN_ON(start_off - (full_page << PAGE_CACHE_SHIFT) !=
+		((cstart_block << zisofs_block_shift) & PAGE_CACHE_MASK));
+
+	/* Find the pointer to this specific chunk */
+	/* Note: we're not using isonum_731() here because the data is known aligned */
+	/* Note: header_size is in 32-bit words (4 bytes) */
+	blockptr = (header_size + cstart_block) << 2;
+	bh = isofs_bread(inode, blockptr >> blkbits);
+	if (!bh)
+		return -EIO;
+	block_start = le32_to_cpu(*(__le32 *)
+				(bh->b_data + (blockptr & (blksize - 1))));
+
+	while (cstart_block < cend_block && pcount > 0) {
+		/* Load end of the compressed block in the file */
+		blockptr += 4;
+		/* Traversed to next block? */
+		if (!(blockptr & (blksize - 1))) {
+			brelse(bh);
+
+			bh = isofs_bread(inode, blockptr >> blkbits);
+			if (!bh)
+				return -EIO;
+		}
+		block_end = le32_to_cpu(*(__le32 *)
+				(bh->b_data + (blockptr & (blksize - 1))));
+		if (block_start > block_end) {
+			brelse(bh);
+			return -EIO;
+		}
+		err = 0;
+		ret = zisofs_uncompress_block(inode, block_start, block_end,
+					      pcount, pages, poffset, &err);
+		poffset += ret;
+		pages += poffset >> PAGE_CACHE_SHIFT;
+		pcount -= poffset >> PAGE_CACHE_SHIFT;
+		full_page -= poffset >> PAGE_CACHE_SHIFT;
+		poffset &= ~PAGE_CACHE_MASK;
+
+		if (err) {
+			brelse(bh);
+			/*
+			 * Did we finish reading the page we really wanted
+			 * to read?
+			 */
+			if (full_page < 0)
+				return 0;
+			return err;
+		}
+
+		block_start = block_end;
+		cstart_block++;
+	}
+
+	if (poffset && *pages) {
+		memset(page_address(*pages) + poffset, 0,
+		       PAGE_CACHE_SIZE - poffset);
+		flush_dcache_page(*pages);
+		SetPageUptodate(*pages);
+	}
+	return 0;
+}
+
+/*
  * When decompressing, we typically obtain more than one page
  * per reference.  We inject the additional pages into the page
  * cache as a form of readahead.
@@ -44,278 +298,61 @@
 {
 	struct inode *inode = file->f_path.dentry->d_inode;
 	struct address_space *mapping = inode->i_mapping;
-	unsigned int maxpage, xpage, fpage, blockindex;
-	unsigned long offset;
-	unsigned long blockptr, blockendptr, cstart, cend, csize;
-	struct buffer_head *bh, *ptrbh[2];
-	unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
-	unsigned int bufshift = ISOFS_BUFFER_BITS(inode);
-	unsigned long bufmask  = bufsize - 1;
-	int err = -EIO;
-	int i;
-	unsigned int header_size = ISOFS_I(inode)->i_format_parm[0];
+	int err;
+	int i, pcount, full_page;
 	unsigned int zisofs_block_shift = ISOFS_I(inode)->i_format_parm[1];
-	/* unsigned long zisofs_block_size = 1UL << zisofs_block_shift; */
-	unsigned int zisofs_block_page_shift = zisofs_block_shift-PAGE_CACHE_SHIFT;
-	unsigned long zisofs_block_pages = 1UL << zisofs_block_page_shift;
-	unsigned long zisofs_block_page_mask = zisofs_block_pages-1;
-	struct page *pages[zisofs_block_pages];
-	unsigned long index = page->index;
-	int indexblocks;
+	unsigned int zisofs_pages_per_cblock =
+		PAGE_CACHE_SHIFT <= zisofs_block_shift ?
+		(1 << (zisofs_block_shift - PAGE_CACHE_SHIFT)) : 0;
+	struct page *pages[max_t(unsigned, zisofs_pages_per_cblock, 1)];
+	pgoff_t index = page->index, end_index;
 
-	/* We have already been given one page, this is the one
-	   we must do. */
-	xpage = index & zisofs_block_page_mask;
-	pages[xpage] = page;
- 
-	/* The remaining pages need to be allocated and inserted */
-	offset = index & ~zisofs_block_page_mask;
-	blockindex = offset >> zisofs_block_page_shift;
-	maxpage = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-
+	end_index = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 	/*
 	 * If this page is wholly outside i_size we just return zero;
 	 * do_generic_file_read() will handle this for us
 	 */
-	if (page->index >= maxpage) {
+	if (index >= end_index) {
 		SetPageUptodate(page);
 		unlock_page(page);
 		return 0;
 	}
 
-	maxpage = min(zisofs_block_pages, maxpage-offset);
-
-	for ( i = 0 ; i < maxpage ; i++, offset++ ) {
-		if ( i != xpage ) {
-			pages[i] = grab_cache_page_nowait(mapping, offset);
-		}
-		page = pages[i];
-		if ( page ) {
-			ClearPageError(page);
-			kmap(page);
-		}
-	}
-
-	/* This is the last page filled, plus one; used in case of abort. */
-	fpage = 0;
-
-	/* Find the pointer to this specific chunk */
-	/* Note: we're not using isonum_731() here because the data is known aligned */
-	/* Note: header_size is in 32-bit words (4 bytes) */
-	blockptr = (header_size + blockindex) << 2;
-	blockendptr = blockptr + 4;
-
-	indexblocks = ((blockptr^blockendptr) >> bufshift) ? 2 : 1;
-	ptrbh[0] = ptrbh[1] = NULL;
-
-	if ( isofs_get_blocks(inode, blockptr >> bufshift, ptrbh, indexblocks) != indexblocks ) {
-		if ( ptrbh[0] ) brelse(ptrbh[0]);
-		printk(KERN_DEBUG "zisofs: Null buffer on reading block table, inode = %lu, block = %lu\n",
-		       inode->i_ino, blockptr >> bufshift);
-		goto eio;
-	}
-	ll_rw_block(READ, indexblocks, ptrbh);
-
-	bh = ptrbh[0];
-	if ( !bh || (wait_on_buffer(bh), !buffer_uptodate(bh)) ) {
-		printk(KERN_DEBUG "zisofs: Failed to read block table, inode = %lu, block = %lu\n",
-		       inode->i_ino, blockptr >> bufshift);
-		if ( ptrbh[1] )
-			brelse(ptrbh[1]);
-		goto eio;
-	}
-	cstart = le32_to_cpu(*(__le32 *)(bh->b_data + (blockptr & bufmask)));
-
-	if ( indexblocks == 2 ) {
-		/* We just crossed a block boundary.  Switch to the next block */
-		brelse(bh);
-		bh = ptrbh[1];
-		if ( !bh || (wait_on_buffer(bh), !buffer_uptodate(bh)) ) {
-			printk(KERN_DEBUG "zisofs: Failed to read block table, inode = %lu, block = %lu\n",
-			       inode->i_ino, blockendptr >> bufshift);
-			goto eio;
-		}
-	}
-	cend = le32_to_cpu(*(__le32 *)(bh->b_data + (blockendptr & bufmask)));
-	brelse(bh);
-
-	if (cstart > cend)
-		goto eio;
-		
-	csize = cend-cstart;
-
-	if (csize > deflateBound(1UL << zisofs_block_shift))
-		goto eio;
-
-	/* Now page[] contains an array of pages, any of which can be NULL,
-	   and the locks on which we hold.  We should now read the data and
-	   release the pages.  If the pages are NULL the decompressed data
-	   for that particular page should be discarded. */
-	
-	if ( csize == 0 ) {
-		/* This data block is empty. */
-
-		for ( fpage = 0 ; fpage < maxpage ; fpage++ ) {
-			if ( (page = pages[fpage]) != NULL ) {
-				memset(page_address(page), 0, PAGE_CACHE_SIZE);
-				
-				flush_dcache_page(page);
-				SetPageUptodate(page);
-				kunmap(page);
-				unlock_page(page);
-				if ( fpage == xpage )
-					err = 0; /* The critical page */
-				else
-					page_cache_release(page);
-			}
-		}
+	if (PAGE_CACHE_SHIFT <= zisofs_block_shift) {
+		/* We have already been given one page, this is the one
+		   we must do. */
+		full_page = index & (zisofs_pages_per_cblock - 1);
+		pcount = min_t(int, zisofs_pages_per_cblock,
+			end_index - (index & ~(zisofs_pages_per_cblock - 1)));
+		index -= full_page;
 	} else {
-		/* This data block is compressed. */
-		z_stream stream;
-		int bail = 0, left_out = -1;
-		int zerr;
-		int needblocks = (csize + (cstart & bufmask) + bufmask) >> bufshift;
-		int haveblocks;
-		struct buffer_head *bhs[needblocks+1];
-		struct buffer_head **bhptr;
+		full_page = 0;
+		pcount = 1;
+	}
+	pages[full_page] = page;
 
-		/* Because zlib is not thread-safe, do all the I/O at the top. */
-
-		blockptr = cstart >> bufshift;
-		memset(bhs, 0, (needblocks+1)*sizeof(struct buffer_head *));
-		haveblocks = isofs_get_blocks(inode, blockptr, bhs, needblocks);
-		ll_rw_block(READ, haveblocks, bhs);
-
-		bhptr = &bhs[0];
-		bh = *bhptr++;
-
-		/* First block is special since it may be fractional.
-		   We also wait for it before grabbing the zlib
-		   mutex; odds are that the subsequent blocks are
-		   going to come in in short order so we don't hold
-		   the zlib mutex longer than necessary. */
-
-		if ( !bh || (wait_on_buffer(bh), !buffer_uptodate(bh)) ) {
-			printk(KERN_DEBUG "zisofs: Hit null buffer, fpage = %d, xpage = %d, csize = %ld\n",
-			       fpage, xpage, csize);
-			goto b_eio;
-		}
-		stream.next_in  = bh->b_data + (cstart & bufmask);
-		stream.avail_in = min(bufsize-(cstart & bufmask), csize);
-		csize -= stream.avail_in;
-
-		stream.workspace = zisofs_zlib_workspace;
-		mutex_lock(&zisofs_zlib_lock);
-		
-		zerr = zlib_inflateInit(&stream);
-		if ( zerr != Z_OK ) {
-			if ( err && zerr == Z_MEM_ERROR )
-				err = -ENOMEM;
-			printk(KERN_DEBUG "zisofs: zisofs_inflateInit returned %d\n",
-			       zerr);
-			goto z_eio;
-		}
-
-		while ( !bail && fpage < maxpage ) {
-			page = pages[fpage];
-			if ( page )
-				stream.next_out = page_address(page);
-			else
-				stream.next_out = (void *)&zisofs_sink_page;
-			stream.avail_out = PAGE_CACHE_SIZE;
-
-			while ( stream.avail_out ) {
-				int ao, ai;
-				if ( stream.avail_in == 0 && left_out ) {
-					if ( !csize ) {
-						printk(KERN_WARNING "zisofs: ZF read beyond end of input\n");
-						bail = 1;
-						break;
-					} else {
-						bh = *bhptr++;
-						if ( !bh ||
-						     (wait_on_buffer(bh), !buffer_uptodate(bh)) ) {
-							/* Reached an EIO */
- 							printk(KERN_DEBUG "zisofs: Hit null buffer, fpage = %d, xpage = %d, csize = %ld\n",
-							       fpage, xpage, csize);
-							       
-							bail = 1;
-							break;
-						}
-						stream.next_in = bh->b_data;
-						stream.avail_in = min(csize,bufsize);
-						csize -= stream.avail_in;
-					}
-				}
-				ao = stream.avail_out;  ai = stream.avail_in;
-				zerr = zlib_inflate(&stream, Z_SYNC_FLUSH);
-				left_out = stream.avail_out;
-				if ( zerr == Z_BUF_ERROR && stream.avail_in == 0 )
-					continue;
-				if ( zerr != Z_OK ) {
-					/* EOF, error, or trying to read beyond end of input */
-					if ( err && zerr == Z_MEM_ERROR )
-						err = -ENOMEM;
-					if ( zerr != Z_STREAM_END )
-						printk(KERN_DEBUG "zisofs: zisofs_inflate returned %d, inode = %lu, index = %lu, fpage = %d, xpage = %d, avail_in = %d, avail_out = %d, ai = %d, ao = %d\n",
-						       zerr, inode->i_ino, index,
-						       fpage, xpage,
-						       stream.avail_in, stream.avail_out,
-						       ai, ao);
-					bail = 1;
-					break;
-				}
-			}
-
-			if ( stream.avail_out && zerr == Z_STREAM_END ) {
-				/* Fractional page written before EOF.  This may
-				   be the last page in the file. */
-				memset(stream.next_out, 0, stream.avail_out);
-				stream.avail_out = 0;
-			}
-
-			if ( !stream.avail_out ) {
-				/* This page completed */
-				if ( page ) {
-					flush_dcache_page(page);
-					SetPageUptodate(page);
-					kunmap(page);
-					unlock_page(page);
-					if ( fpage == xpage )
-						err = 0; /* The critical page */
-					else
-						page_cache_release(page);
-				}
-				fpage++;
-			}
-		}
-		zlib_inflateEnd(&stream);
-
-	z_eio:
-		mutex_unlock(&zisofs_zlib_lock);
-
-	b_eio:
-		for ( i = 0 ; i < haveblocks ; i++ ) {
-			if ( bhs[i] )
-				brelse(bhs[i]);
+	for (i = 0; i < pcount; i++, index++) {
+		if (i != full_page)
+			pages[i] = grab_cache_page_nowait(mapping, index);
+		if (pages[i]) {
+			ClearPageError(pages[i]);
+			kmap(pages[i]);
 		}
 	}
 
-eio:
+	err = zisofs_fill_pages(inode, full_page, pcount, pages);
 
 	/* Release any residual pages, do not SetPageUptodate */
-	while ( fpage < maxpage ) {
-		page = pages[fpage];
-		if ( page ) {
-			flush_dcache_page(page);
-			if ( fpage == xpage )
-				SetPageError(page);
-			kunmap(page);
-			unlock_page(page);
-			if ( fpage != xpage )
-				page_cache_release(page);
+	for (i = 0; i < pcount; i++) {
+		if (pages[i]) {
+			flush_dcache_page(pages[i]);
+			if (i == full_page && err)
+				SetPageError(pages[i]);
+			kunmap(pages[i]);
+			unlock_page(pages[i]);
+			if (i != full_page)
+				page_cache_release(pages[i]);
 		}
-		fpage++;
 	}			
 
 	/* At this point, err contains 0 or -EIO depending on the "critical" page */
diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c
index c2fb2dd..96a685c 100644
--- a/fs/isofs/rock.c
+++ b/fs/isofs/rock.c
@@ -518,8 +518,7 @@
 			if (algo == SIG('p', 'z')) {
 				int block_shift =
 					isonum_711(&rr->u.ZF.parms[1]);
-				if (block_shift < PAGE_CACHE_SHIFT
-						|| block_shift > 17) {
+				if (block_shift > 17) {
 					printk(KERN_WARNING "isofs: "
 						"Can't handle ZF block "
 						"size of 2^%d\n",
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index d4cfd6d..6a10238 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -286,7 +286,7 @@
 		if (err) {
 			/*
 			 * Because AS_EIO is cleared by
-			 * wait_on_page_writeback_range(), set it again so
+			 * filemap_fdatawait_range(), set it again so
 			 * that user process can get -EIO from fsync().
 			 */
 			set_bit(AS_EIO,
@@ -636,6 +636,10 @@
 		JBUFFER_TRACE(jh, "ph3: write metadata");
 		flags = jbd2_journal_write_metadata_buffer(commit_transaction,
 						      jh, &new_jh, blocknr);
+		if (flags < 0) {
+			jbd2_journal_abort(journal, flags);
+			continue;
+		}
 		set_bit(BH_JWrite, &jh2bh(new_jh)->b_state);
 		wbuf[bufs++] = jh2bh(new_jh);
 
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index fed85388..b7ca3a9 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -78,6 +78,7 @@
 EXPORT_SYMBOL(jbd2_journal_ack_err);
 EXPORT_SYMBOL(jbd2_journal_clear_err);
 EXPORT_SYMBOL(jbd2_log_wait_commit);
+EXPORT_SYMBOL(jbd2_log_start_commit);
 EXPORT_SYMBOL(jbd2_journal_start_commit);
 EXPORT_SYMBOL(jbd2_journal_force_commit_nested);
 EXPORT_SYMBOL(jbd2_journal_wipe);
@@ -358,6 +359,10 @@
 
 		jbd_unlock_bh_state(bh_in);
 		tmp = jbd2_alloc(bh_in->b_size, GFP_NOFS);
+		if (!tmp) {
+			jbd2_journal_put_journal_head(new_jh);
+			return -ENOMEM;
+		}
 		jbd_lock_bh_state(bh_in);
 		if (jh_in->b_frozen_data) {
 			jbd2_free(tmp, bh_in->b_size);
@@ -1248,6 +1253,13 @@
 	if (jbd2_journal_recover(journal))
 		goto recovery_error;
 
+	if (journal->j_failed_commit) {
+		printk(KERN_ERR "JBD2: journal transaction %u on %s "
+		       "is corrupt.\n", journal->j_failed_commit,
+		       journal->j_devname);
+		return -EIO;
+	}
+
 	/* OK, we've finished with the dynamic journal bits:
 	 * reinitialise the dynamic contents of the superblock in memory
 	 * and reset them on disk. */
diff --git a/fs/jffs2/compr.c b/fs/jffs2/compr.c
index f25e70c..f029441 100644
--- a/fs/jffs2/compr.c
+++ b/fs/jffs2/compr.c
@@ -177,7 +177,7 @@
 		spin_unlock(&jffs2_compressor_list_lock);
 		break;
 	default:
-		printk(KERN_ERR "JFFS2: unknow compression mode.\n");
+		printk(KERN_ERR "JFFS2: unknown compression mode.\n");
 	}
  out:
 	if (ret == JFFS2_COMPR_NONE) {
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index 1a80301..378991c 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -931,7 +931,7 @@
  * Helper function for jffs2_get_inode_nodes().
  * The function detects whether more data should be read and reads it if yes.
  *
- * Returns: 0 on succes;
+ * Returns: 0 on success;
  * 	    negative error code on failure.
  */
 static int read_more(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref,
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c
index 082e844..4b10788 100644
--- a/fs/jffs2/xattr.c
+++ b/fs/jffs2/xattr.c
@@ -31,7 +31,7 @@
  *   is used to release xattr name/value pair and detach from c->xattrindex.
  * reclaim_xattr_datum(c)
  *   is used to reclaim xattr name/value pairs on the xattr name/value pair cache when
- *   memory usage by cache is over c->xdatum_mem_threshold. Currentry, this threshold 
+ *   memory usage by cache is over c->xdatum_mem_threshold. Currently, this threshold 
  *   is hard coded as 32KiB.
  * do_verify_xattr_datum(c, xd)
  *   is used to load the xdatum informations without name/value pair from the medium.
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
index 2bc7d8a..d9b031c 100644
--- a/fs/jfs/jfs_dmap.c
+++ b/fs/jfs/jfs_dmap.c
@@ -755,7 +755,7 @@
 	 * allocation group.
 	 */
 	if ((blkno & (bmp->db_agsize - 1)) == 0)
-		/* check if the AG is currenly being written to.
+		/* check if the AG is currently being written to.
 		 * if so, call dbNextAG() to find a non-busy
 		 * AG with sufficient free space.
 		 */
@@ -3337,7 +3337,7 @@
 	for (i = 0, n = 0; i < agno; n++) {
 		bmp->db_agfree[n] = 0;	/* init collection point */
 
-		/* coalesce cotiguous k AGs; */
+		/* coalesce contiguous k AGs; */
 		for (j = 0; j < k && i < agno; j++, i++) {
 			/* merge AGi to AGn */
 			bmp->db_agfree[n] += bmp->db_agfree[i];
diff --git a/fs/namei.c b/fs/namei.c
index d11f404..87f97ba 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1279,28 +1279,6 @@
 	return __lookup_hash(&this, base, NULL);
 }
 
-/**
- * lookup_one_noperm - bad hack for sysfs
- * @name:	pathname component to lookup
- * @base:	base directory to lookup from
- *
- * This is a variant of lookup_one_len that doesn't perform any permission
- * checks.   It's a horrible hack to work around the braindead sysfs
- * architecture and should not be used anywhere else.
- *
- * DON'T USE THIS FUNCTION EVER, thanks.
- */
-struct dentry *lookup_one_noperm(const char *name, struct dentry *base)
-{
-	int err;
-	struct qstr this;
-
-	err = __lookup_one_len(name, &this, base, strlen(name));
-	if (err)
-		return ERR_PTR(err);
-	return __lookup_hash(&this, base, NULL);
-}
-
 int user_path_at(int dfd, const char __user *name, unsigned flags,
 		 struct path *path)
 {
@@ -1678,6 +1656,15 @@
 	int will_write;
 	int flag = open_to_namei_flags(open_flag);
 
+	/*
+	 * O_SYNC is implemented as __O_SYNC|O_DSYNC.  As many places only
+	 * check for O_DSYNC if the need any syncing at all we enforce it's
+	 * always set instead of having to deal with possibly weird behaviour
+	 * for malicious applications setting only __O_SYNC.
+	 */
+	if (open_flag & __O_SYNC)
+		open_flag |= O_DSYNC;
+
 	if (!acc_mode)
 		acc_mode = MAY_OPEN | ACC_MODE(flag);
 
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c
index 0d58caf..ec8f45f 100644
--- a/fs/ncpfs/ioctl.c
+++ b/fs/ncpfs/ioctl.c
@@ -835,7 +835,7 @@
 	case NCP_IOC_SETROOT:
 		return 0;
 	default:
-		/* unkown IOCTL command, assume write */
+		/* unknown IOCTL command, assume write */
 		return 1;
 	}
 }
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index f5fdd39..6b89132 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -581,7 +581,7 @@
 {
 	struct nfs_open_context *ctx;
 
-	if (IS_SYNC(inode) || (filp->f_flags & O_SYNC))
+	if (IS_SYNC(inode) || (filp->f_flags & O_DSYNC))
 		return 1;
 	ctx = nfs_file_open_context(filp);
 	if (test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags))
@@ -622,7 +622,7 @@
 
 	nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count);
 	result = generic_file_aio_write(iocb, iov, nr_segs, pos);
-	/* Return error values for O_SYNC and IS_SYNC() */
+	/* Return error values for O_DSYNC and IS_SYNC() */
 	if (result >= 0 && nfs_need_sync_write(iocb->ki_filp, inode)) {
 		int err = nfs_do_fsync(nfs_file_open_context(iocb->ki_filp), inode);
 		if (err < 0)
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index c84b5cc..b1ce2ea 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -774,7 +774,7 @@
 	 */
 	if (nfs_write_pageuptodate(page, inode) &&
 			inode->i_flock == NULL &&
-			!(file->f_flags & O_SYNC)) {
+			!(file->f_flags & O_DSYNC)) {
 		count = max(count + offset, nfs_page_length(page));
 		offset = 0;
 	}
diff --git a/fs/nilfs2/alloc.c b/fs/nilfs2/alloc.c
index d69e6ae..3f959f1 100644
--- a/fs/nilfs2/alloc.c
+++ b/fs/nilfs2/alloc.c
@@ -142,29 +142,75 @@
 	}
 }
 
+static int nilfs_palloc_get_block(struct inode *inode, unsigned long blkoff,
+				  int create,
+				  void (*init_block)(struct inode *,
+						     struct buffer_head *,
+						     void *),
+				  struct buffer_head **bhp,
+				  struct nilfs_bh_assoc *prev,
+				  spinlock_t *lock)
+{
+	int ret;
+
+	spin_lock(lock);
+	if (prev->bh && blkoff == prev->blkoff) {
+		get_bh(prev->bh);
+		*bhp = prev->bh;
+		spin_unlock(lock);
+		return 0;
+	}
+	spin_unlock(lock);
+
+	ret = nilfs_mdt_get_block(inode, blkoff, create, init_block, bhp);
+	if (!ret) {
+		spin_lock(lock);
+		/*
+		 * The following code must be safe for change of the
+		 * cache contents during the get block call.
+		 */
+		brelse(prev->bh);
+		get_bh(*bhp);
+		prev->bh = *bhp;
+		prev->blkoff = blkoff;
+		spin_unlock(lock);
+	}
+	return ret;
+}
+
 static int nilfs_palloc_get_desc_block(struct inode *inode,
 				       unsigned long group,
 				       int create, struct buffer_head **bhp)
 {
-	return nilfs_mdt_get_block(inode,
-				   nilfs_palloc_desc_blkoff(inode, group),
-				   create, nilfs_palloc_desc_block_init, bhp);
+	struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache;
+
+	return nilfs_palloc_get_block(inode,
+				      nilfs_palloc_desc_blkoff(inode, group),
+				      create, nilfs_palloc_desc_block_init,
+				      bhp, &cache->prev_desc, &cache->lock);
 }
 
 static int nilfs_palloc_get_bitmap_block(struct inode *inode,
 					 unsigned long group,
 					 int create, struct buffer_head **bhp)
 {
-	return nilfs_mdt_get_block(inode,
-				   nilfs_palloc_bitmap_blkoff(inode, group),
-				   create, NULL, bhp);
+	struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache;
+
+	return nilfs_palloc_get_block(inode,
+				      nilfs_palloc_bitmap_blkoff(inode, group),
+				      create, NULL, bhp,
+				      &cache->prev_bitmap, &cache->lock);
 }
 
 int nilfs_palloc_get_entry_block(struct inode *inode, __u64 nr,
 				 int create, struct buffer_head **bhp)
 {
-	return nilfs_mdt_get_block(inode, nilfs_palloc_entry_blkoff(inode, nr),
-				   create, NULL, bhp);
+	struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache;
+
+	return nilfs_palloc_get_block(inode,
+				      nilfs_palloc_entry_blkoff(inode, nr),
+				      create, NULL, bhp,
+				      &cache->prev_entry, &cache->lock);
 }
 
 static struct nilfs_palloc_group_desc *
@@ -176,13 +222,6 @@
 		group % nilfs_palloc_groups_per_desc_block(inode);
 }
 
-static unsigned char *
-nilfs_palloc_block_get_bitmap(const struct inode *inode,
-			      const struct buffer_head *bh, void *kaddr)
-{
-	return (unsigned char *)(kaddr + bh_offset(bh));
-}
-
 void *nilfs_palloc_block_get_entry(const struct inode *inode, __u64 nr,
 				   const struct buffer_head *bh, void *kaddr)
 {
@@ -289,8 +328,7 @@
 				if (ret < 0)
 					goto out_desc;
 				bitmap_kaddr = kmap(bitmap_bh->b_page);
-				bitmap = nilfs_palloc_block_get_bitmap(
-					inode, bitmap_bh, bitmap_kaddr);
+				bitmap = bitmap_kaddr + bh_offset(bitmap_bh);
 				pos = nilfs_palloc_find_available_slot(
 					inode, group, group_offset, bitmap,
 					entries_per_group);
@@ -351,8 +389,7 @@
 	desc = nilfs_palloc_block_get_group_desc(inode, group,
 						 req->pr_desc_bh, desc_kaddr);
 	bitmap_kaddr = kmap(req->pr_bitmap_bh->b_page);
-	bitmap = nilfs_palloc_block_get_bitmap(inode, req->pr_bitmap_bh,
-					       bitmap_kaddr);
+	bitmap = bitmap_kaddr + bh_offset(req->pr_bitmap_bh);
 
 	if (!nilfs_clear_bit_atomic(nilfs_mdt_bgl_lock(inode, group),
 				    group_offset, bitmap))
@@ -385,8 +422,7 @@
 	desc = nilfs_palloc_block_get_group_desc(inode, group,
 						 req->pr_desc_bh, desc_kaddr);
 	bitmap_kaddr = kmap(req->pr_bitmap_bh->b_page);
-	bitmap = nilfs_palloc_block_get_bitmap(inode, req->pr_bitmap_bh,
-					       bitmap_kaddr);
+	bitmap = bitmap_kaddr + bh_offset(req->pr_bitmap_bh);
 	if (!nilfs_clear_bit_atomic(nilfs_mdt_bgl_lock(inode, group),
 				    group_offset, bitmap))
 		printk(KERN_WARNING "%s: entry numer %llu already freed\n",
@@ -472,8 +508,7 @@
 		desc = nilfs_palloc_block_get_group_desc(
 			inode, group, desc_bh, desc_kaddr);
 		bitmap_kaddr = kmap(bitmap_bh->b_page);
-		bitmap = nilfs_palloc_block_get_bitmap(
-			inode, bitmap_bh, bitmap_kaddr);
+		bitmap = bitmap_kaddr + bh_offset(bitmap_bh);
 		for (j = i, n = 0;
 		     (j < nitems) && nilfs_palloc_group_is_in(inode, group,
 							      entry_nrs[j]);
@@ -502,3 +537,30 @@
 	}
 	return 0;
 }
+
+void nilfs_palloc_setup_cache(struct inode *inode,
+			      struct nilfs_palloc_cache *cache)
+{
+	NILFS_MDT(inode)->mi_palloc_cache = cache;
+	spin_lock_init(&cache->lock);
+}
+
+void nilfs_palloc_clear_cache(struct inode *inode)
+{
+	struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache;
+
+	spin_lock(&cache->lock);
+	brelse(cache->prev_desc.bh);
+	brelse(cache->prev_bitmap.bh);
+	brelse(cache->prev_entry.bh);
+	cache->prev_desc.bh = NULL;
+	cache->prev_bitmap.bh = NULL;
+	cache->prev_entry.bh = NULL;
+	spin_unlock(&cache->lock);
+}
+
+void nilfs_palloc_destroy_cache(struct inode *inode)
+{
+	nilfs_palloc_clear_cache(inode);
+	NILFS_MDT(inode)->mi_palloc_cache = NULL;
+}
diff --git a/fs/nilfs2/alloc.h b/fs/nilfs2/alloc.h
index 4ace5475..f4543ac 100644
--- a/fs/nilfs2/alloc.h
+++ b/fs/nilfs2/alloc.h
@@ -69,4 +69,25 @@
 #define nilfs_clear_bit_atomic		ext2_clear_bit_atomic
 #define nilfs_find_next_zero_bit	ext2_find_next_zero_bit
 
+/*
+ * persistent object allocator cache
+ */
+
+struct nilfs_bh_assoc {
+	unsigned long blkoff;
+	struct buffer_head *bh;
+};
+
+struct nilfs_palloc_cache {
+	spinlock_t lock;
+	struct nilfs_bh_assoc prev_desc;
+	struct nilfs_bh_assoc prev_bitmap;
+	struct nilfs_bh_assoc prev_entry;
+};
+
+void nilfs_palloc_setup_cache(struct inode *inode,
+			      struct nilfs_palloc_cache *cache);
+void nilfs_palloc_clear_cache(struct inode *inode);
+void nilfs_palloc_destroy_cache(struct inode *inode);
+
 #endif	/* _NILFS_ALLOC_H */
diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c
index 08834df..f4a14ea 100644
--- a/fs/nilfs2/bmap.c
+++ b/fs/nilfs2/bmap.c
@@ -402,19 +402,11 @@
 void nilfs_bmap_add_blocks(const struct nilfs_bmap *bmap, int n)
 {
 	inode_add_bytes(bmap->b_inode, (1 << bmap->b_inode->i_blkbits) * n);
-	if (NILFS_MDT(bmap->b_inode))
-		nilfs_mdt_mark_dirty(bmap->b_inode);
-	else
-		mark_inode_dirty(bmap->b_inode);
 }
 
 void nilfs_bmap_sub_blocks(const struct nilfs_bmap *bmap, int n)
 {
 	inode_sub_bytes(bmap->b_inode, (1 << bmap->b_inode->i_blkbits) * n);
-	if (NILFS_MDT(bmap->b_inode))
-		nilfs_mdt_mark_dirty(bmap->b_inode);
-	else
-		mark_inode_dirty(bmap->b_inode);
 }
 
 __u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *bmap,
diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c
index 84c2538..471e269 100644
--- a/fs/nilfs2/btnode.c
+++ b/fs/nilfs2/btnode.c
@@ -68,9 +68,34 @@
 	truncate_inode_pages(btnc, 0);
 }
 
+struct buffer_head *
+nilfs_btnode_create_block(struct address_space *btnc, __u64 blocknr)
+{
+	struct inode *inode = NILFS_BTNC_I(btnc);
+	struct buffer_head *bh;
+
+	bh = nilfs_grab_buffer(inode, btnc, blocknr, 1 << BH_NILFS_Node);
+	if (unlikely(!bh))
+		return NULL;
+
+	if (unlikely(buffer_mapped(bh) || buffer_uptodate(bh) ||
+		     buffer_dirty(bh))) {
+		brelse(bh);
+		BUG();
+	}
+	memset(bh->b_data, 0, 1 << inode->i_blkbits);
+	bh->b_bdev = NILFS_I_NILFS(inode)->ns_bdev;
+	bh->b_blocknr = blocknr;
+	set_buffer_mapped(bh);
+	set_buffer_uptodate(bh);
+
+	unlock_page(bh->b_page);
+	page_cache_release(bh->b_page);
+	return bh;
+}
+
 int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
-			      sector_t pblocknr, struct buffer_head **pbh,
-			      int newblk)
+			      sector_t pblocknr, struct buffer_head **pbh)
 {
 	struct buffer_head *bh;
 	struct inode *inode = NILFS_BTNC_I(btnc);
@@ -81,19 +106,6 @@
 		return -ENOMEM;
 
 	err = -EEXIST; /* internal code */
-	if (newblk) {
-		if (unlikely(buffer_mapped(bh) || buffer_uptodate(bh) ||
-			     buffer_dirty(bh))) {
-			brelse(bh);
-			BUG();
-		}
-		memset(bh->b_data, 0, 1 << inode->i_blkbits);
-		bh->b_bdev = NILFS_I_NILFS(inode)->ns_bdev;
-		bh->b_blocknr = blocknr;
-		set_buffer_mapped(bh);
-		set_buffer_uptodate(bh);
-		goto found;
-	}
 
 	if (buffer_uptodate(bh) || buffer_dirty(bh))
 		goto found;
@@ -135,27 +147,6 @@
 	return err;
 }
 
-int nilfs_btnode_get(struct address_space *btnc, __u64 blocknr,
-		     sector_t pblocknr, struct buffer_head **pbh, int newblk)
-{
-	struct buffer_head *bh;
-	int err;
-
-	err = nilfs_btnode_submit_block(btnc, blocknr, pblocknr, pbh, newblk);
-	if (err == -EEXIST) /* internal code (cache hit) */
-		return 0;
-	if (unlikely(err))
-		return err;
-
-	bh = *pbh;
-	wait_on_buffer(bh);
-	if (!buffer_uptodate(bh)) {
-		brelse(bh);
-		return -EIO;
-	}
-	return 0;
-}
-
 /**
  * nilfs_btnode_delete - delete B-tree node buffer
  * @bh: buffer to be deleted
@@ -244,12 +235,13 @@
 		unlock_page(obh->b_page);
 	}
 
-	err = nilfs_btnode_get(btnc, newkey, 0, &nbh, 1);
-	if (likely(!err)) {
-		BUG_ON(nbh == obh);
-		ctxt->newbh = nbh;
-	}
-	return err;
+	nbh = nilfs_btnode_create_block(btnc, newkey);
+	if (!nbh)
+		return -ENOMEM;
+
+	BUG_ON(nbh == obh);
+	ctxt->newbh = nbh;
+	return 0;
 
  failed_unlock:
 	unlock_page(obh->b_page);
diff --git a/fs/nilfs2/btnode.h b/fs/nilfs2/btnode.h
index 3e22751..07da83f 100644
--- a/fs/nilfs2/btnode.h
+++ b/fs/nilfs2/btnode.h
@@ -40,10 +40,10 @@
 void nilfs_btnode_cache_init_once(struct address_space *);
 void nilfs_btnode_cache_init(struct address_space *, struct backing_dev_info *);
 void nilfs_btnode_cache_clear(struct address_space *);
+struct buffer_head *nilfs_btnode_create_block(struct address_space *btnc,
+					      __u64 blocknr);
 int nilfs_btnode_submit_block(struct address_space *, __u64, sector_t,
-			      struct buffer_head **, int);
-int nilfs_btnode_get(struct address_space *, __u64, sector_t,
-		     struct buffer_head **, int);
+			      struct buffer_head **);
 void nilfs_btnode_delete(struct buffer_head *);
 int nilfs_btnode_prepare_change_key(struct address_space *,
 				    struct nilfs_btnode_chkey_ctxt *);
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
index e25b507..7cdd98b 100644
--- a/fs/nilfs2/btree.c
+++ b/fs/nilfs2/btree.c
@@ -114,7 +114,18 @@
 {
 	struct address_space *btnc =
 		&NILFS_BMAP_I((struct nilfs_bmap *)btree)->i_btnode_cache;
-	return nilfs_btnode_get(btnc, ptr, 0, bhp, 0);
+	int err;
+
+	err = nilfs_btnode_submit_block(btnc, ptr, 0, bhp);
+	if (err)
+		return err == -EEXIST ? 0 : err;
+
+	wait_on_buffer(*bhp);
+	if (!buffer_uptodate(*bhp)) {
+		brelse(*bhp);
+		return -EIO;
+	}
+	return 0;
 }
 
 static int nilfs_btree_get_new_block(const struct nilfs_btree *btree,
@@ -122,12 +133,15 @@
 {
 	struct address_space *btnc =
 		&NILFS_BMAP_I((struct nilfs_bmap *)btree)->i_btnode_cache;
-	int ret;
+	struct buffer_head *bh;
 
-	ret = nilfs_btnode_get(btnc, ptr, 0, bhp, 1);
-	if (!ret)
-		set_buffer_nilfs_volatile(*bhp);
-	return ret;
+	bh = nilfs_btnode_create_block(btnc, ptr);
+	if (!bh)
+		return -ENOMEM;
+
+	set_buffer_nilfs_volatile(bh);
+	*bhp = bh;
+	return 0;
 }
 
 static inline int
@@ -444,6 +458,18 @@
 		nilfs_btree_get_nonroot_node(path, level);
 }
 
+static inline int
+nilfs_btree_bad_node(struct nilfs_btree_node *node, int level)
+{
+	if (unlikely(nilfs_btree_node_get_level(node) != level)) {
+		dump_stack();
+		printk(KERN_CRIT "NILFS: btree level mismatch: %d != %d\n",
+		       nilfs_btree_node_get_level(node), level);
+		return 1;
+	}
+	return 0;
+}
+
 static int nilfs_btree_do_lookup(const struct nilfs_btree *btree,
 				 struct nilfs_btree_path *path,
 				 __u64 key, __u64 *ptrp, int minlevel)
@@ -467,7 +493,8 @@
 		if (ret < 0)
 			return ret;
 		node = nilfs_btree_get_nonroot_node(path, level);
-		BUG_ON(level != nilfs_btree_node_get_level(node));
+		if (nilfs_btree_bad_node(node, level))
+			return -EINVAL;
 		if (!found)
 			found = nilfs_btree_node_lookup(node, key, &index);
 		else
@@ -512,7 +539,8 @@
 		if (ret < 0)
 			return ret;
 		node = nilfs_btree_get_nonroot_node(path, level);
-		BUG_ON(level != nilfs_btree_node_get_level(node));
+		if (nilfs_btree_bad_node(node, level))
+			return -EINVAL;
 		index = nilfs_btree_node_get_nchildren(node) - 1;
 		ptr = nilfs_btree_node_get_ptr(btree, node, index);
 		path[level].bp_index = index;
@@ -638,13 +666,11 @@
 {
 	if (level < nilfs_btree_height(btree) - 1) {
 		do {
-			lock_buffer(path[level].bp_bh);
 			nilfs_btree_node_set_key(
 				nilfs_btree_get_nonroot_node(path, level),
 				path[level].bp_index, key);
 			if (!buffer_dirty(path[level].bp_bh))
 				nilfs_btnode_mark_dirty(path[level].bp_bh);
-			unlock_buffer(path[level].bp_bh);
 		} while ((path[level].bp_index == 0) &&
 			 (++level < nilfs_btree_height(btree) - 1));
 	}
@@ -663,13 +689,11 @@
 	struct nilfs_btree_node *node;
 
 	if (level < nilfs_btree_height(btree) - 1) {
-		lock_buffer(path[level].bp_bh);
 		node = nilfs_btree_get_nonroot_node(path, level);
 		nilfs_btree_node_insert(btree, node, *keyp, *ptrp,
 					path[level].bp_index);
 		if (!buffer_dirty(path[level].bp_bh))
 			nilfs_btnode_mark_dirty(path[level].bp_bh);
-		unlock_buffer(path[level].bp_bh);
 
 		if (path[level].bp_index == 0)
 			nilfs_btree_promote_key(btree, path, level + 1,
@@ -689,9 +713,6 @@
 	struct nilfs_btree_node *node, *left;
 	int nchildren, lnchildren, n, move;
 
-	lock_buffer(path[level].bp_bh);
-	lock_buffer(path[level].bp_sib_bh);
-
 	node = nilfs_btree_get_nonroot_node(path, level);
 	left = nilfs_btree_get_sib_node(path, level);
 	nchildren = nilfs_btree_node_get_nchildren(node);
@@ -712,9 +733,6 @@
 	if (!buffer_dirty(path[level].bp_sib_bh))
 		nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
 
-	unlock_buffer(path[level].bp_bh);
-	unlock_buffer(path[level].bp_sib_bh);
-
 	nilfs_btree_promote_key(btree, path, level + 1,
 				nilfs_btree_node_get_key(node, 0));
 
@@ -740,9 +758,6 @@
 	struct nilfs_btree_node *node, *right;
 	int nchildren, rnchildren, n, move;
 
-	lock_buffer(path[level].bp_bh);
-	lock_buffer(path[level].bp_sib_bh);
-
 	node = nilfs_btree_get_nonroot_node(path, level);
 	right = nilfs_btree_get_sib_node(path, level);
 	nchildren = nilfs_btree_node_get_nchildren(node);
@@ -763,9 +778,6 @@
 	if (!buffer_dirty(path[level].bp_sib_bh))
 		nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
 
-	unlock_buffer(path[level].bp_bh);
-	unlock_buffer(path[level].bp_sib_bh);
-
 	path[level + 1].bp_index++;
 	nilfs_btree_promote_key(btree, path, level + 1,
 				nilfs_btree_node_get_key(right, 0));
@@ -794,9 +806,6 @@
 	__u64 newptr;
 	int nchildren, n, move;
 
-	lock_buffer(path[level].bp_bh);
-	lock_buffer(path[level].bp_sib_bh);
-
 	node = nilfs_btree_get_nonroot_node(path, level);
 	right = nilfs_btree_get_sib_node(path, level);
 	nchildren = nilfs_btree_node_get_nchildren(node);
@@ -815,9 +824,6 @@
 	if (!buffer_dirty(path[level].bp_sib_bh))
 		nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
 
-	unlock_buffer(path[level].bp_bh);
-	unlock_buffer(path[level].bp_sib_bh);
-
 	newkey = nilfs_btree_node_get_key(right, 0);
 	newptr = path[level].bp_newreq.bpr_ptr;
 
@@ -852,8 +858,6 @@
 	struct nilfs_btree_node *root, *child;
 	int n;
 
-	lock_buffer(path[level].bp_sib_bh);
-
 	root = nilfs_btree_get_root(btree);
 	child = nilfs_btree_get_sib_node(path, level);
 
@@ -865,8 +869,6 @@
 	if (!buffer_dirty(path[level].bp_sib_bh))
 		nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
 
-	unlock_buffer(path[level].bp_sib_bh);
-
 	path[level].bp_bh = path[level].bp_sib_bh;
 	path[level].bp_sib_bh = NULL;
 
@@ -1023,11 +1025,9 @@
 
 		stats->bs_nblocks++;
 
-		lock_buffer(bh);
 		nilfs_btree_node_init(btree,
 				      (struct nilfs_btree_node *)bh->b_data,
 				      0, level, 0, NULL, NULL);
-		unlock_buffer(bh);
 		path[level].bp_sib_bh = bh;
 		path[level].bp_op = nilfs_btree_split;
 	}
@@ -1052,10 +1052,8 @@
 	if (ret < 0)
 		goto err_out_curr_node;
 
-	lock_buffer(bh);
 	nilfs_btree_node_init(btree, (struct nilfs_btree_node *)bh->b_data,
 			      0, level, 0, NULL, NULL);
-	unlock_buffer(bh);
 	path[level].bp_sib_bh = bh;
 	path[level].bp_op = nilfs_btree_grow;
 
@@ -1154,13 +1152,11 @@
 	struct nilfs_btree_node *node;
 
 	if (level < nilfs_btree_height(btree) - 1) {
-		lock_buffer(path[level].bp_bh);
 		node = nilfs_btree_get_nonroot_node(path, level);
 		nilfs_btree_node_delete(btree, node, keyp, ptrp,
 					path[level].bp_index);
 		if (!buffer_dirty(path[level].bp_bh))
 			nilfs_btnode_mark_dirty(path[level].bp_bh);
-		unlock_buffer(path[level].bp_bh);
 		if (path[level].bp_index == 0)
 			nilfs_btree_promote_key(btree, path, level + 1,
 				nilfs_btree_node_get_key(node, 0));
@@ -1180,9 +1176,6 @@
 
 	nilfs_btree_do_delete(btree, path, level, keyp, ptrp);
 
-	lock_buffer(path[level].bp_bh);
-	lock_buffer(path[level].bp_sib_bh);
-
 	node = nilfs_btree_get_nonroot_node(path, level);
 	left = nilfs_btree_get_sib_node(path, level);
 	nchildren = nilfs_btree_node_get_nchildren(node);
@@ -1197,9 +1190,6 @@
 	if (!buffer_dirty(path[level].bp_sib_bh))
 		nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
 
-	unlock_buffer(path[level].bp_bh);
-	unlock_buffer(path[level].bp_sib_bh);
-
 	nilfs_btree_promote_key(btree, path, level + 1,
 				nilfs_btree_node_get_key(node, 0));
 
@@ -1217,9 +1207,6 @@
 
 	nilfs_btree_do_delete(btree, path, level, keyp, ptrp);
 
-	lock_buffer(path[level].bp_bh);
-	lock_buffer(path[level].bp_sib_bh);
-
 	node = nilfs_btree_get_nonroot_node(path, level);
 	right = nilfs_btree_get_sib_node(path, level);
 	nchildren = nilfs_btree_node_get_nchildren(node);
@@ -1234,9 +1221,6 @@
 	if (!buffer_dirty(path[level].bp_sib_bh))
 		nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
 
-	unlock_buffer(path[level].bp_bh);
-	unlock_buffer(path[level].bp_sib_bh);
-
 	path[level + 1].bp_index++;
 	nilfs_btree_promote_key(btree, path, level + 1,
 				nilfs_btree_node_get_key(right, 0));
@@ -1255,9 +1239,6 @@
 
 	nilfs_btree_do_delete(btree, path, level, keyp, ptrp);
 
-	lock_buffer(path[level].bp_bh);
-	lock_buffer(path[level].bp_sib_bh);
-
 	node = nilfs_btree_get_nonroot_node(path, level);
 	left = nilfs_btree_get_sib_node(path, level);
 
@@ -1268,9 +1249,6 @@
 	if (!buffer_dirty(path[level].bp_sib_bh))
 		nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
 
-	unlock_buffer(path[level].bp_bh);
-	unlock_buffer(path[level].bp_sib_bh);
-
 	nilfs_btnode_delete(path[level].bp_bh);
 	path[level].bp_bh = path[level].bp_sib_bh;
 	path[level].bp_sib_bh = NULL;
@@ -1286,9 +1264,6 @@
 
 	nilfs_btree_do_delete(btree, path, level, keyp, ptrp);
 
-	lock_buffer(path[level].bp_bh);
-	lock_buffer(path[level].bp_sib_bh);
-
 	node = nilfs_btree_get_nonroot_node(path, level);
 	right = nilfs_btree_get_sib_node(path, level);
 
@@ -1299,9 +1274,6 @@
 	if (!buffer_dirty(path[level].bp_bh))
 		nilfs_btnode_mark_dirty(path[level].bp_bh);
 
-	unlock_buffer(path[level].bp_bh);
-	unlock_buffer(path[level].bp_sib_bh);
-
 	nilfs_btnode_delete(path[level].bp_sib_bh);
 	path[level].bp_sib_bh = NULL;
 	path[level + 1].bp_index++;
@@ -1316,7 +1288,6 @@
 
 	nilfs_btree_do_delete(btree, path, level, keyp, ptrp);
 
-	lock_buffer(path[level].bp_bh);
 	root = nilfs_btree_get_root(btree);
 	child = nilfs_btree_get_nonroot_node(path, level);
 
@@ -1324,7 +1295,6 @@
 	nilfs_btree_node_set_level(root, level);
 	n = nilfs_btree_node_get_nchildren(child);
 	nilfs_btree_node_move_left(btree, root, child, n);
-	unlock_buffer(path[level].bp_bh);
 
 	nilfs_btnode_delete(path[level].bp_bh);
 	path[level].bp_bh = NULL;
@@ -1699,7 +1669,6 @@
 		nilfs_bmap_commit_alloc_ptr(bmap, nreq, dat);
 
 		/* create child node at level 1 */
-		lock_buffer(bh);
 		node = (struct nilfs_btree_node *)bh->b_data;
 		nilfs_btree_node_init(btree, node, 0, 1, n, keys, ptrs);
 		nilfs_btree_node_insert(btree, node,
@@ -1709,7 +1678,6 @@
 		if (!nilfs_bmap_dirty(bmap))
 			nilfs_bmap_set_dirty(bmap);
 
-		unlock_buffer(bh);
 		brelse(bh);
 
 		/* create root node at level 2 */
@@ -2050,7 +2018,7 @@
 	for (level = NILFS_BTREE_LEVEL_NODE_MIN;
 	     level < NILFS_BTREE_LEVEL_MAX;
 	     level++)
-		list_splice(&lists[level], listp->prev);
+		list_splice_tail(&lists[level], listp);
 }
 
 static int nilfs_btree_assign_p(struct nilfs_btree *btree,
diff --git a/fs/nilfs2/btree.h b/fs/nilfs2/btree.h
index 0e72bbb..4b82d84 100644
--- a/fs/nilfs2/btree.h
+++ b/fs/nilfs2/btree.h
@@ -34,28 +34,6 @@
 struct nilfs_btree_path;
 
 /**
- * struct nilfs_btree_node - B-tree node
- * @bn_flags: flags
- * @bn_level: level
- * @bn_nchildren: number of children
- * @bn_pad: padding
- */
-struct nilfs_btree_node {
-	__u8 bn_flags;
-	__u8 bn_level;
-	__le16 bn_nchildren;
-	__le32 bn_pad;
-};
-
-/* flags */
-#define NILFS_BTREE_NODE_ROOT	0x01
-
-/* level */
-#define NILFS_BTREE_LEVEL_DATA		0
-#define NILFS_BTREE_LEVEL_NODE_MIN	(NILFS_BTREE_LEVEL_DATA + 1)
-#define NILFS_BTREE_LEVEL_MAX		14
-
-/**
  * struct nilfs_btree - B-tree structure
  * @bt_bmap: bmap base structure
  */
diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c
index 3f5d5d0..d5ad54e 100644
--- a/fs/nilfs2/cpfile.c
+++ b/fs/nilfs2/cpfile.c
@@ -926,3 +926,29 @@
 	up_read(&NILFS_MDT(cpfile)->mi_sem);
 	return ret;
 }
+
+/**
+ * nilfs_cpfile_read - read cpfile inode
+ * @cpfile: cpfile inode
+ * @raw_inode: on-disk cpfile inode
+ */
+int nilfs_cpfile_read(struct inode *cpfile, struct nilfs_inode *raw_inode)
+{
+	return nilfs_read_inode_common(cpfile, raw_inode);
+}
+
+/**
+ * nilfs_cpfile_new - create cpfile
+ * @nilfs: nilfs object
+ * @cpsize: size of a checkpoint entry
+ */
+struct inode *nilfs_cpfile_new(struct the_nilfs *nilfs, size_t cpsize)
+{
+	struct inode *cpfile;
+
+	cpfile = nilfs_mdt_new(nilfs, NULL, NILFS_CPFILE_INO, 0);
+	if (cpfile)
+		nilfs_mdt_set_entry_size(cpfile, cpsize,
+					 sizeof(struct nilfs_cpfile_header));
+	return cpfile;
+}
diff --git a/fs/nilfs2/cpfile.h b/fs/nilfs2/cpfile.h
index debea89..bc0809e 100644
--- a/fs/nilfs2/cpfile.h
+++ b/fs/nilfs2/cpfile.h
@@ -40,4 +40,7 @@
 ssize_t nilfs_cpfile_get_cpinfo(struct inode *, __u64 *, int, void *, unsigned,
 				size_t);
 
+int nilfs_cpfile_read(struct inode *cpfile, struct nilfs_inode *raw_inode);
+struct inode *nilfs_cpfile_new(struct the_nilfs *nilfs, size_t cpsize);
+
 #endif	/* _NILFS_CPFILE_H */
diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c
index 1ff8e15..187dd07 100644
--- a/fs/nilfs2/dat.c
+++ b/fs/nilfs2/dat.c
@@ -33,6 +33,16 @@
 #define NILFS_CNO_MIN	((__u64)1)
 #define NILFS_CNO_MAX	(~(__u64)0)
 
+struct nilfs_dat_info {
+	struct nilfs_mdt_info mi;
+	struct nilfs_palloc_cache palloc_cache;
+};
+
+static inline struct nilfs_dat_info *NILFS_DAT_I(struct inode *dat)
+{
+	return (struct nilfs_dat_info *)NILFS_MDT(dat);
+}
+
 static int nilfs_dat_prepare_entry(struct inode *dat,
 				   struct nilfs_palloc_req *req, int create)
 {
@@ -425,3 +435,40 @@
 
 	return nvi;
 }
+
+/**
+ * nilfs_dat_read - read dat inode
+ * @dat: dat inode
+ * @raw_inode: on-disk dat inode
+ */
+int nilfs_dat_read(struct inode *dat, struct nilfs_inode *raw_inode)
+{
+	return nilfs_read_inode_common(dat, raw_inode);
+}
+
+/**
+ * nilfs_dat_new - create dat file
+ * @nilfs: nilfs object
+ * @entry_size: size of a dat entry
+ */
+struct inode *nilfs_dat_new(struct the_nilfs *nilfs, size_t entry_size)
+{
+	static struct lock_class_key dat_lock_key;
+	struct inode *dat;
+	struct nilfs_dat_info *di;
+	int err;
+
+	dat = nilfs_mdt_new(nilfs, NULL, NILFS_DAT_INO, sizeof(*di));
+	if (dat) {
+		err = nilfs_palloc_init_blockgroup(dat, entry_size);
+		if (unlikely(err)) {
+			nilfs_mdt_destroy(dat);
+			return NULL;
+		}
+
+		di = NILFS_DAT_I(dat);
+		lockdep_set_class(&di->mi.mi_sem, &dat_lock_key);
+		nilfs_palloc_setup_cache(dat, &di->palloc_cache);
+	}
+	return dat;
+}
diff --git a/fs/nilfs2/dat.h b/fs/nilfs2/dat.h
index 406070d..d31c3aa 100644
--- a/fs/nilfs2/dat.h
+++ b/fs/nilfs2/dat.h
@@ -53,4 +53,7 @@
 int nilfs_dat_move(struct inode *, __u64, sector_t);
 ssize_t nilfs_dat_get_vinfo(struct inode *, void *, unsigned, size_t);
 
+int nilfs_dat_read(struct inode *dat, struct nilfs_inode *raw_inode);
+struct inode *nilfs_dat_new(struct the_nilfs *nilfs, size_t entry_size);
+
 #endif	/* _NILFS_DAT_H */
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index e097099..76d803e 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -99,9 +99,9 @@
 				 NULL, nilfs_get_block);
 }
 
-static int nilfs_commit_chunk(struct page *page,
-			      struct address_space *mapping,
-			      unsigned from, unsigned to)
+static void nilfs_commit_chunk(struct page *page,
+			       struct address_space *mapping,
+			       unsigned from, unsigned to)
 {
 	struct inode *dir = mapping->host;
 	struct nilfs_sb_info *sbi = NILFS_SB(dir->i_sb);
@@ -112,15 +112,13 @@
 
 	nr_dirty = nilfs_page_count_clean_buffers(page, from, to);
 	copied = block_write_end(NULL, mapping, pos, len, len, page, NULL);
-	if (pos + copied > dir->i_size) {
+	if (pos + copied > dir->i_size)
 		i_size_write(dir, pos + copied);
-		mark_inode_dirty(dir);
-	}
 	if (IS_DIRSYNC(dir))
 		nilfs_set_transaction_flag(NILFS_TI_SYNC);
 	err = nilfs_set_file_dirty(sbi, dir, nr_dirty);
+	WARN_ON(err); /* do not happen */
 	unlock_page(page);
-	return err;
 }
 
 static void nilfs_check_page(struct page *page)
@@ -455,11 +453,10 @@
 	BUG_ON(err);
 	de->inode = cpu_to_le64(inode->i_ino);
 	nilfs_set_de_type(de, inode);
-	err = nilfs_commit_chunk(page, mapping, from, to);
+	nilfs_commit_chunk(page, mapping, from, to);
 	nilfs_put_page(page);
 	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
 /*	NILFS_I(dir)->i_flags &= ~NILFS_BTREE_FL; */
-	mark_inode_dirty(dir);
 }
 
 /*
@@ -548,10 +545,10 @@
 	memcpy(de->name, name, namelen);
 	de->inode = cpu_to_le64(inode->i_ino);
 	nilfs_set_de_type(de, inode);
-	err = nilfs_commit_chunk(page, page->mapping, from, to);
+	nilfs_commit_chunk(page, page->mapping, from, to);
 	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
 /*	NILFS_I(dir)->i_flags &= ~NILFS_BTREE_FL; */
-	mark_inode_dirty(dir);
+	nilfs_mark_inode_dirty(dir);
 	/* OFFSET_CACHE */
 out_put:
 	nilfs_put_page(page);
@@ -595,10 +592,9 @@
 	if (pde)
 		pde->rec_len = cpu_to_le16(to - from);
 	dir->inode = 0;
-	err = nilfs_commit_chunk(page, mapping, from, to);
+	nilfs_commit_chunk(page, mapping, from, to);
 	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
 /*	NILFS_I(inode)->i_flags &= ~NILFS_BTREE_FL; */
-	mark_inode_dirty(inode);
 out:
 	nilfs_put_page(page);
 	return err;
@@ -640,7 +636,7 @@
 	memcpy(de->name, "..\0", 4);
 	nilfs_set_de_type(de, inode);
 	kunmap_atomic(kaddr, KM_USER0);
-	err = nilfs_commit_chunk(page, mapping, 0, chunk_size);
+	nilfs_commit_chunk(page, mapping, 0, chunk_size);
 fail:
 	page_cache_release(page);
 	return err;
diff --git a/fs/nilfs2/gcdat.c b/fs/nilfs2/gcdat.c
index 93383c5..dd5f7e0 100644
--- a/fs/nilfs2/gcdat.c
+++ b/fs/nilfs2/gcdat.c
@@ -61,6 +61,8 @@
 
 	nilfs_bmap_commit_gcdat(gii->i_bmap, dii->i_bmap);
 
+	nilfs_palloc_clear_cache(dat);
+	nilfs_palloc_clear_cache(gcdat);
 	nilfs_clear_dirty_pages(mapping);
 	nilfs_copy_back_pages(mapping, gmapping);
 	/* note: mdt dirty flags should be cleared by segctor. */
@@ -79,6 +81,7 @@
 	gcdat->i_state = I_CLEAR;
 	gii->i_flags = 0;
 
+	nilfs_palloc_clear_cache(gcdat);
 	truncate_inode_pages(gcdat->i_mapping, 0);
 	truncate_inode_pages(&gii->i_btnode_cache, 0);
 }
diff --git a/fs/nilfs2/gcinode.c b/fs/nilfs2/gcinode.c
index e6de0a2..e16a666 100644
--- a/fs/nilfs2/gcinode.c
+++ b/fs/nilfs2/gcinode.c
@@ -149,7 +149,7 @@
 				   __u64 vbn, struct buffer_head **out_bh)
 {
 	int ret = nilfs_btnode_submit_block(&NILFS_I(inode)->i_btnode_cache,
-					    vbn ? : pbn, pbn, out_bh, 0);
+					    vbn ? : pbn, pbn, out_bh);
 	if (ret == -EEXIST) /* internal code (cache hit) */
 		ret = 0;
 	return ret;
@@ -212,9 +212,10 @@
 static struct inode *alloc_gcinode(struct the_nilfs *nilfs, ino_t ino,
 				   __u64 cno)
 {
-	struct inode *inode = nilfs_mdt_new_common(nilfs, NULL, ino, GFP_NOFS);
+	struct inode *inode;
 	struct nilfs_inode_info *ii;
 
+	inode = nilfs_mdt_new_common(nilfs, NULL, ino, GFP_NOFS, 0);
 	if (!inode)
 		return NULL;
 
@@ -265,7 +266,6 @@
  */
 void nilfs_clear_gcinode(struct inode *inode)
 {
-	nilfs_mdt_clear(inode);
 	nilfs_mdt_destroy(inode);
 }
 
diff --git a/fs/nilfs2/ifile.c b/fs/nilfs2/ifile.c
index de86401..922d9dd 100644
--- a/fs/nilfs2/ifile.c
+++ b/fs/nilfs2/ifile.c
@@ -29,6 +29,17 @@
 #include "alloc.h"
 #include "ifile.h"
 
+
+struct nilfs_ifile_info {
+	struct nilfs_mdt_info mi;
+	struct nilfs_palloc_cache palloc_cache;
+};
+
+static inline struct nilfs_ifile_info *NILFS_IFILE_I(struct inode *ifile)
+{
+	return (struct nilfs_ifile_info *)NILFS_MDT(ifile);
+}
+
 /**
  * nilfs_ifile_create_inode - create a new disk inode
  * @ifile: ifile inode
@@ -148,3 +159,27 @@
 	}
 	return err;
 }
+
+/**
+ * nilfs_ifile_new - create inode file
+ * @sbi: nilfs_sb_info struct
+ * @inode_size: size of an inode
+ */
+struct inode *nilfs_ifile_new(struct nilfs_sb_info *sbi, size_t inode_size)
+{
+	struct inode *ifile;
+	int err;
+
+	ifile = nilfs_mdt_new(sbi->s_nilfs, sbi->s_super, NILFS_IFILE_INO,
+			      sizeof(struct nilfs_ifile_info));
+	if (ifile) {
+		err = nilfs_palloc_init_blockgroup(ifile, inode_size);
+		if (unlikely(err)) {
+			nilfs_mdt_destroy(ifile);
+			return NULL;
+		}
+		nilfs_palloc_setup_cache(ifile,
+					 &NILFS_IFILE_I(ifile)->palloc_cache);
+	}
+	return ifile;
+}
diff --git a/fs/nilfs2/ifile.h b/fs/nilfs2/ifile.h
index ecc3ba76..cbca32e 100644
--- a/fs/nilfs2/ifile.h
+++ b/fs/nilfs2/ifile.h
@@ -49,4 +49,6 @@
 int nilfs_ifile_delete_inode(struct inode *, ino_t);
 int nilfs_ifile_get_inode_block(struct inode *, ino_t, struct buffer_head **);
 
+struct inode *nilfs_ifile_new(struct nilfs_sb_info *sbi, size_t inode_size);
+
 #endif	/* _NILFS_IFILE_H */
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index 2a0a5a3..7868cc1 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -97,6 +97,7 @@
 			nilfs_transaction_abort(inode->i_sb);
 			goto out;
 		}
+		nilfs_mark_inode_dirty(inode);
 		nilfs_transaction_commit(inode->i_sb); /* never fails */
 		/* Error handling should be detailed */
 		set_buffer_new(bh_result);
@@ -322,7 +323,6 @@
 				    nilfs_init_acl(), proper cancellation of
 				    above jobs should be considered */
 
-	mark_inode_dirty(inode);
 	return inode;
 
  failed_acl:
@@ -525,7 +525,6 @@
 
 	raw_inode = nilfs_ifile_map_inode(sbi->s_ifile, ino, ibh);
 
-	/* The buffer is guarded with lock_buffer() by the caller */
 	if (test_and_clear_bit(NILFS_I_NEW, &ii->i_state))
 		memset(raw_inode, 0, NILFS_MDT(sbi->s_ifile)->mi_entry_size);
 	set_bit(NILFS_I_INODE_DIRTY, &ii->i_state);
@@ -599,6 +598,7 @@
 	if (IS_SYNC(inode))
 		nilfs_set_transaction_flag(NILFS_TI_SYNC);
 
+	nilfs_mark_inode_dirty(inode);
 	nilfs_set_file_dirty(NILFS_SB(sb), inode, 0);
 	nilfs_transaction_commit(sb);
 	/* May construct a logical segment and may fail in sync mode.
@@ -623,6 +623,7 @@
 		truncate_inode_pages(&inode->i_data, 0);
 
 	nilfs_truncate_bmap(ii, 0);
+	nilfs_mark_inode_dirty(inode);
 	nilfs_free_inode(inode);
 	/* nilfs_free_inode() marks inode buffer dirty */
 	if (IS_SYNC(inode))
@@ -745,9 +746,7 @@
 			      "failed to reget inode block.\n");
 		return err;
 	}
-	lock_buffer(ibh);
 	nilfs_update_inode(inode, ibh);
-	unlock_buffer(ibh);
 	nilfs_mdt_mark_buffer_dirty(ibh);
 	nilfs_mdt_mark_dirty(sbi->s_ifile);
 	brelse(ibh);
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index f632611..06713ff 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -186,7 +186,7 @@
 }
 
 static int nilfs_mdt_read_block(struct inode *inode, unsigned long block,
-				struct buffer_head **out_bh)
+				int readahead, struct buffer_head **out_bh)
 {
 	struct buffer_head *first_bh, *bh;
 	unsigned long blkoff;
@@ -200,16 +200,18 @@
 	if (unlikely(err))
 		goto failed;
 
-	blkoff = block + 1;
-	for (i = 0; i < nr_ra_blocks; i++, blkoff++) {
-		err = nilfs_mdt_submit_block(inode, blkoff, READA, &bh);
-		if (likely(!err || err == -EEXIST))
-			brelse(bh);
-		else if (err != -EBUSY)
-			break; /* abort readahead if bmap lookup failed */
-
-		if (!buffer_locked(first_bh))
-			goto out_no_wait;
+	if (readahead) {
+		blkoff = block + 1;
+		for (i = 0; i < nr_ra_blocks; i++, blkoff++) {
+			err = nilfs_mdt_submit_block(inode, blkoff, READA, &bh);
+			if (likely(!err || err == -EEXIST))
+				brelse(bh);
+			else if (err != -EBUSY)
+				break;
+				/* abort readahead if bmap lookup failed */
+			if (!buffer_locked(first_bh))
+				goto out_no_wait;
+		}
 	}
 
 	wait_on_buffer(first_bh);
@@ -263,7 +265,7 @@
 
 	/* Should be rewritten with merging nilfs_mdt_read_block() */
  retry:
-	ret = nilfs_mdt_read_block(inode, blkoff, out_bh);
+	ret = nilfs_mdt_read_block(inode, blkoff, !create, out_bh);
 	if (!create || ret != -ENOENT)
 		return ret;
 
@@ -371,7 +373,7 @@
 	struct buffer_head *bh;
 	int err;
 
-	err = nilfs_mdt_read_block(inode, block, &bh);
+	err = nilfs_mdt_read_block(inode, block, 0, &bh);
 	if (unlikely(err))
 		return err;
 	nilfs_mark_buffer_dirty(bh);
@@ -445,9 +447,17 @@
  * longer than those of the super block structs; they may continue for
  * several consecutive mounts/umounts.  This would need discussions.
  */
+/**
+ * nilfs_mdt_new_common - allocate a pseudo inode for metadata file
+ * @nilfs: nilfs object
+ * @sb: super block instance the metadata file belongs to
+ * @ino: inode number
+ * @gfp_mask: gfp mask for data pages
+ * @objsz: size of the private object attached to inode->i_private
+ */
 struct inode *
 nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb,
-		     ino_t ino, gfp_t gfp_mask)
+		     ino_t ino, gfp_t gfp_mask, size_t objsz)
 {
 	struct inode *inode = nilfs_alloc_inode_common(nilfs);
 
@@ -455,8 +465,9 @@
 		return NULL;
 	else {
 		struct address_space * const mapping = &inode->i_data;
-		struct nilfs_mdt_info *mi = kzalloc(sizeof(*mi), GFP_NOFS);
+		struct nilfs_mdt_info *mi;
 
+		mi = kzalloc(max(sizeof(*mi), objsz), GFP_NOFS);
 		if (!mi) {
 			nilfs_destroy_inode(inode);
 			return NULL;
@@ -513,11 +524,11 @@
 }
 
 struct inode *nilfs_mdt_new(struct the_nilfs *nilfs, struct super_block *sb,
-			    ino_t ino)
+			    ino_t ino, size_t objsz)
 {
-	struct inode *inode = nilfs_mdt_new_common(nilfs, sb, ino,
-						   NILFS_MDT_GFP);
+	struct inode *inode;
 
+	inode = nilfs_mdt_new_common(nilfs, sb, ino, NILFS_MDT_GFP, objsz);
 	if (!inode)
 		return NULL;
 
@@ -544,14 +555,15 @@
 		&NILFS_I(orig)->i_btnode_cache;
 }
 
-void nilfs_mdt_clear(struct inode *inode)
+static void nilfs_mdt_clear(struct inode *inode)
 {
 	struct nilfs_inode_info *ii = NILFS_I(inode);
 
 	invalidate_mapping_pages(inode->i_mapping, 0, -1);
 	truncate_inode_pages(inode->i_mapping, 0);
 
-	nilfs_bmap_clear(ii->i_bmap);
+	if (test_bit(NILFS_I_BMAP, &ii->i_state))
+		nilfs_bmap_clear(ii->i_bmap);
 	nilfs_btnode_cache_clear(&ii->i_btnode_cache);
 }
 
@@ -559,6 +571,10 @@
 {
 	struct nilfs_mdt_info *mdi = NILFS_MDT(inode);
 
+	if (mdi->mi_palloc_cache)
+		nilfs_palloc_destroy_cache(inode);
+	nilfs_mdt_clear(inode);
+
 	kfree(mdi->mi_bgl); /* kfree(NULL) is safe */
 	kfree(mdi);
 	nilfs_destroy_inode(inode);
diff --git a/fs/nilfs2/mdt.h b/fs/nilfs2/mdt.h
index 4315997..6c4bbb0 100644
--- a/fs/nilfs2/mdt.h
+++ b/fs/nilfs2/mdt.h
@@ -36,6 +36,7 @@
  * @mi_entry_size: size of an entry
  * @mi_first_entry_offset: offset to the first entry
  * @mi_entries_per_block: number of entries in a block
+ * @mi_palloc_cache: persistent object allocator cache
  * @mi_blocks_per_group: number of blocks in a group
  * @mi_blocks_per_desc_block: number of blocks per descriptor block
  */
@@ -46,6 +47,7 @@
 	unsigned		mi_entry_size;
 	unsigned		mi_first_entry_offset;
 	unsigned long		mi_entries_per_block;
+	struct nilfs_palloc_cache *mi_palloc_cache;
 	unsigned long		mi_blocks_per_group;
 	unsigned long		mi_blocks_per_desc_block;
 };
@@ -74,11 +76,11 @@
 int nilfs_mdt_mark_block_dirty(struct inode *, unsigned long);
 int nilfs_mdt_fetch_dirty(struct inode *);
 
-struct inode *nilfs_mdt_new(struct the_nilfs *, struct super_block *, ino_t);
+struct inode *nilfs_mdt_new(struct the_nilfs *, struct super_block *, ino_t,
+			    size_t);
 struct inode *nilfs_mdt_new_common(struct the_nilfs *, struct super_block *,
-				   ino_t, gfp_t);
+				   ino_t, gfp_t, size_t);
 void nilfs_mdt_destroy(struct inode *);
-void nilfs_mdt_clear(struct inode *);
 void nilfs_mdt_set_entry_size(struct inode *, unsigned, unsigned);
 void nilfs_mdt_set_shadow(struct inode *, struct inode *);
 
@@ -104,21 +106,4 @@
 #define nilfs_mdt_bgl_lock(inode, bg) \
 	(&NILFS_MDT(inode)->mi_bgl->locks[(bg) & (NR_BG_LOCKS-1)].lock)
 
-
-static inline int
-nilfs_mdt_read_inode_direct(struct inode *inode, struct buffer_head *bh,
-			    unsigned n)
-{
-	return nilfs_read_inode_common(
-		inode, (struct nilfs_inode *)(bh->b_data + n));
-}
-
-static inline void
-nilfs_mdt_write_inode_direct(struct inode *inode, struct buffer_head *bh,
-			     unsigned n)
-{
-	nilfs_write_inode_common(
-		inode, (struct nilfs_inode *)(bh->b_data + n), 1);
-}
-
 #endif /* _NILFS_MDT_H */
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c
index ed02e88..07ba838 100644
--- a/fs/nilfs2/namei.c
+++ b/fs/nilfs2/namei.c
@@ -120,7 +120,7 @@
 		inode->i_op = &nilfs_file_inode_operations;
 		inode->i_fop = &nilfs_file_operations;
 		inode->i_mapping->a_ops = &nilfs_aops;
-		mark_inode_dirty(inode);
+		nilfs_mark_inode_dirty(inode);
 		err = nilfs_add_nondir(dentry, inode);
 	}
 	if (!err)
@@ -148,7 +148,7 @@
 	err = PTR_ERR(inode);
 	if (!IS_ERR(inode)) {
 		init_special_inode(inode, inode->i_mode, rdev);
-		mark_inode_dirty(inode);
+		nilfs_mark_inode_dirty(inode);
 		err = nilfs_add_nondir(dentry, inode);
 	}
 	if (!err)
@@ -188,7 +188,7 @@
 		goto out_fail;
 
 	/* mark_inode_dirty(inode); */
-	/* nilfs_new_inode() and page_symlink() do this */
+	/* page_symlink() do this */
 
 	err = nilfs_add_nondir(dentry, inode);
 out:
@@ -200,7 +200,8 @@
 	return err;
 
 out_fail:
-	inode_dec_link_count(inode);
+	drop_nlink(inode);
+	nilfs_mark_inode_dirty(inode);
 	iput(inode);
 	goto out;
 }
@@ -245,7 +246,7 @@
 	if (err)
 		return err;
 
-	inode_inc_link_count(dir);
+	inc_nlink(dir);
 
 	inode = nilfs_new_inode(dir, S_IFDIR | mode);
 	err = PTR_ERR(inode);
@@ -256,7 +257,7 @@
 	inode->i_fop = &nilfs_dir_operations;
 	inode->i_mapping->a_ops = &nilfs_aops;
 
-	inode_inc_link_count(inode);
+	inc_nlink(inode);
 
 	err = nilfs_make_empty(inode, dir);
 	if (err)
@@ -266,6 +267,7 @@
 	if (err)
 		goto out_fail;
 
+	nilfs_mark_inode_dirty(inode);
 	d_instantiate(dentry, inode);
 out:
 	if (!err)
@@ -276,26 +278,23 @@
 	return err;
 
 out_fail:
-	inode_dec_link_count(inode);
-	inode_dec_link_count(inode);
+	drop_nlink(inode);
+	drop_nlink(inode);
+	nilfs_mark_inode_dirty(inode);
 	iput(inode);
 out_dir:
-	inode_dec_link_count(dir);
+	drop_nlink(dir);
+	nilfs_mark_inode_dirty(dir);
 	goto out;
 }
 
-static int nilfs_unlink(struct inode *dir, struct dentry *dentry)
+static int nilfs_do_unlink(struct inode *dir, struct dentry *dentry)
 {
 	struct inode *inode;
 	struct nilfs_dir_entry *de;
 	struct page *page;
-	struct nilfs_transaction_info ti;
 	int err;
 
-	err = nilfs_transaction_begin(dir->i_sb, &ti, 0);
-	if (err)
-		return err;
-
 	err = -ENOENT;
 	de = nilfs_find_entry(dir, dentry, &page);
 	if (!de)
@@ -317,12 +316,28 @@
 		goto out;
 
 	inode->i_ctime = dir->i_ctime;
-	inode_dec_link_count(inode);
+	drop_nlink(inode);
 	err = 0;
 out:
-	if (!err)
+	return err;
+}
+
+static int nilfs_unlink(struct inode *dir, struct dentry *dentry)
+{
+	struct nilfs_transaction_info ti;
+	int err;
+
+	err = nilfs_transaction_begin(dir->i_sb, &ti, 0);
+	if (err)
+		return err;
+
+	err = nilfs_do_unlink(dir, dentry);
+
+	if (!err) {
+		nilfs_mark_inode_dirty(dir);
+		nilfs_mark_inode_dirty(dentry->d_inode);
 		err = nilfs_transaction_commit(dir->i_sb);
-	else
+	} else
 		nilfs_transaction_abort(dir->i_sb);
 
 	return err;
@@ -340,11 +355,13 @@
 
 	err = -ENOTEMPTY;
 	if (nilfs_empty_dir(inode)) {
-		err = nilfs_unlink(dir, dentry);
+		err = nilfs_do_unlink(dir, dentry);
 		if (!err) {
 			inode->i_size = 0;
-			inode_dec_link_count(inode);
-			inode_dec_link_count(dir);
+			drop_nlink(inode);
+			nilfs_mark_inode_dirty(inode);
+			drop_nlink(dir);
+			nilfs_mark_inode_dirty(dir);
 		}
 	}
 	if (!err)
@@ -395,42 +412,48 @@
 		new_de = nilfs_find_entry(new_dir, new_dentry, &new_page);
 		if (!new_de)
 			goto out_dir;
-		inode_inc_link_count(old_inode);
+		inc_nlink(old_inode);
 		nilfs_set_link(new_dir, new_de, new_page, old_inode);
+		nilfs_mark_inode_dirty(new_dir);
 		new_inode->i_ctime = CURRENT_TIME;
 		if (dir_de)
 			drop_nlink(new_inode);
-		inode_dec_link_count(new_inode);
+		drop_nlink(new_inode);
+		nilfs_mark_inode_dirty(new_inode);
 	} else {
 		if (dir_de) {
 			err = -EMLINK;
 			if (new_dir->i_nlink >= NILFS_LINK_MAX)
 				goto out_dir;
 		}
-		inode_inc_link_count(old_inode);
+		inc_nlink(old_inode);
 		err = nilfs_add_link(new_dentry, old_inode);
 		if (err) {
-			inode_dec_link_count(old_inode);
+			drop_nlink(old_inode);
+			nilfs_mark_inode_dirty(old_inode);
 			goto out_dir;
 		}
-		if (dir_de)
-			inode_inc_link_count(new_dir);
+		if (dir_de) {
+			inc_nlink(new_dir);
+			nilfs_mark_inode_dirty(new_dir);
+		}
 	}
 
 	/*
 	 * Like most other Unix systems, set the ctime for inodes on a
 	 * rename.
-	 * inode_dec_link_count() will mark the inode dirty.
 	 */
 	old_inode->i_ctime = CURRENT_TIME;
 
 	nilfs_delete_entry(old_de, old_page);
-	inode_dec_link_count(old_inode);
+	drop_nlink(old_inode);
 
 	if (dir_de) {
 		nilfs_set_link(old_inode, dir_de, dir_page, new_dir);
-		inode_dec_link_count(old_dir);
+		drop_nlink(old_dir);
 	}
+	nilfs_mark_inode_dirty(old_dir);
+	nilfs_mark_inode_dirty(old_inode);
 
 	err = nilfs_transaction_commit(old_dir->i_sb);
 	return err;
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c
index 6dc8359..c9c96c7 100644
--- a/fs/nilfs2/recovery.c
+++ b/fs/nilfs2/recovery.c
@@ -770,14 +770,8 @@
 		nilfs_finish_roll_forward(nilfs, sbi, ri);
 	}
 
-	nilfs_detach_checkpoint(sbi);
-	return 0;
-
  failed:
 	nilfs_detach_checkpoint(sbi);
-	nilfs_mdt_clear(nilfs->ns_cpfile);
-	nilfs_mdt_clear(nilfs->ns_sufile);
-	nilfs_mdt_clear(nilfs->ns_dat);
 	return err;
 }
 
@@ -804,6 +798,7 @@
 	struct nilfs_segsum_info ssi;
 	sector_t pseg_start, pseg_end, sr_pseg_start = 0;
 	sector_t seg_start, seg_end; /* range of full segment (block number) */
+	sector_t b, end;
 	u64 seg_seq;
 	__u64 segnum, nextnum = 0;
 	__u64 cno;
@@ -819,6 +814,11 @@
 	/* Calculate range of segment */
 	nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end);
 
+	/* Read ahead segment */
+	b = seg_start;
+	while (b <= seg_end)
+		sb_breadahead(sbi->s_super, b++);
+
 	for (;;) {
 		/* Load segment summary */
 		ret = load_segment_summary(sbi, pseg_start, seg_seq, &ssi, 1);
@@ -841,14 +841,20 @@
 		ri->ri_nextnum = nextnum;
 		empty_seg = 0;
 
+		if (!NILFS_SEG_HAS_SR(&ssi) && !scan_newer) {
+			/* This will never happen because a superblock
+			   (last_segment) always points to a pseg
+			   having a super root. */
+			ret = NILFS_SEG_FAIL_CONSISTENCY;
+			goto failed;
+		}
+
+		if (pseg_start == seg_start) {
+			nilfs_get_segment_range(nilfs, nextnum, &b, &end);
+			while (b <= end)
+				sb_breadahead(sbi->s_super, b++);
+		}
 		if (!NILFS_SEG_HAS_SR(&ssi)) {
-			if (!scan_newer) {
-				/* This will never happen because a superblock
-				   (last_segment) always points to a pseg
-				   having a super root. */
-				ret = NILFS_SEG_FAIL_CONSISTENCY;
-				goto failed;
-			}
 			if (!ri->ri_lsegs_start && NILFS_SEG_LOGBGN(&ssi)) {
 				ri->ri_lsegs_start = pseg_start;
 				ri->ri_lsegs_start_seq = seg_seq;
@@ -919,7 +925,7 @@
 
  super_root_found:
 	/* Updating pointers relating to the latest checkpoint */
-	list_splice(&segments, ri->ri_used_segments.prev);
+	list_splice_tail(&segments, &ri->ri_used_segments);
 	nilfs->ns_last_pseg = sr_pseg_start;
 	nilfs->ns_last_seq = nilfs->ns_seg_seq;
 	nilfs->ns_last_cno = ri->ri_cno;
diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c
index e6d9e37..645c786 100644
--- a/fs/nilfs2/segbuf.c
+++ b/fs/nilfs2/segbuf.c
@@ -24,10 +24,22 @@
 #include <linux/buffer_head.h>
 #include <linux/writeback.h>
 #include <linux/crc32.h>
+#include <linux/backing-dev.h>
 #include "page.h"
 #include "segbuf.h"
 
 
+struct nilfs_write_info {
+	struct the_nilfs       *nilfs;
+	struct bio	       *bio;
+	int 			start, end; /* The region to be submitted */
+	int			rest_blocks;
+	int			max_pages;
+	int			nr_vecs;
+	sector_t		blocknr;
+};
+
+
 static struct kmem_cache *nilfs_segbuf_cachep;
 
 static void nilfs_segbuf_init_once(void *obj)
@@ -63,6 +75,11 @@
 	INIT_LIST_HEAD(&segbuf->sb_list);
 	INIT_LIST_HEAD(&segbuf->sb_segsum_buffers);
 	INIT_LIST_HEAD(&segbuf->sb_payload_buffers);
+
+	init_completion(&segbuf->sb_bio_event);
+	atomic_set(&segbuf->sb_err, 0);
+	segbuf->sb_nbio = 0;
+
 	return segbuf;
 }
 
@@ -83,6 +100,22 @@
 		segbuf->sb_fseg_end - segbuf->sb_pseg_start + 1;
 }
 
+/**
+ * nilfs_segbuf_map_cont - map a new log behind a given log
+ * @segbuf: new segment buffer
+ * @prev: segment buffer containing a log to be continued
+ */
+void nilfs_segbuf_map_cont(struct nilfs_segment_buffer *segbuf,
+			   struct nilfs_segment_buffer *prev)
+{
+	segbuf->sb_segnum = prev->sb_segnum;
+	segbuf->sb_fseg_start = prev->sb_fseg_start;
+	segbuf->sb_fseg_end = prev->sb_fseg_end;
+	segbuf->sb_pseg_start = prev->sb_pseg_start + prev->sb_sum.nblocks;
+	segbuf->sb_rest_blocks =
+		segbuf->sb_fseg_end - segbuf->sb_pseg_start + 1;
+}
+
 void nilfs_segbuf_set_next_segnum(struct nilfs_segment_buffer *segbuf,
 				  __u64 nextnum, struct the_nilfs *nilfs)
 {
@@ -132,8 +165,6 @@
 	segbuf->sb_sum.sumbytes = sizeof(struct nilfs_segment_summary);
 	segbuf->sb_sum.nfinfo = segbuf->sb_sum.nfileblk = 0;
 	segbuf->sb_sum.ctime = ctime;
-
-	segbuf->sb_io_error = 0;
 	return 0;
 }
 
@@ -219,7 +250,7 @@
 	raw_sum->ss_datasum = cpu_to_le32(crc);
 }
 
-void nilfs_release_buffers(struct list_head *list)
+static void nilfs_release_buffers(struct list_head *list)
 {
 	struct buffer_head *bh, *n;
 
@@ -241,13 +272,56 @@
 	}
 }
 
+static void nilfs_segbuf_clear(struct nilfs_segment_buffer *segbuf)
+{
+	nilfs_release_buffers(&segbuf->sb_segsum_buffers);
+	nilfs_release_buffers(&segbuf->sb_payload_buffers);
+}
+
+/*
+ * Iterators for segment buffers
+ */
+void nilfs_clear_logs(struct list_head *logs)
+{
+	struct nilfs_segment_buffer *segbuf;
+
+	list_for_each_entry(segbuf, logs, sb_list)
+		nilfs_segbuf_clear(segbuf);
+}
+
+void nilfs_truncate_logs(struct list_head *logs,
+			 struct nilfs_segment_buffer *last)
+{
+	struct nilfs_segment_buffer *n, *segbuf;
+
+	segbuf = list_prepare_entry(last, logs, sb_list);
+	list_for_each_entry_safe_continue(segbuf, n, logs, sb_list) {
+		list_del_init(&segbuf->sb_list);
+		nilfs_segbuf_clear(segbuf);
+		nilfs_segbuf_free(segbuf);
+	}
+}
+
+int nilfs_wait_on_logs(struct list_head *logs)
+{
+	struct nilfs_segment_buffer *segbuf;
+	int err;
+
+	list_for_each_entry(segbuf, logs, sb_list) {
+		err = nilfs_segbuf_wait(segbuf);
+		if (err)
+			return err;
+	}
+	return 0;
+}
+
 /*
  * BIO operations
  */
 static void nilfs_end_bio_write(struct bio *bio, int err)
 {
 	const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
-	struct nilfs_write_info *wi = bio->bi_private;
+	struct nilfs_segment_buffer *segbuf = bio->bi_private;
 
 	if (err == -EOPNOTSUPP) {
 		set_bit(BIO_EOPNOTSUPP, &bio->bi_flags);
@@ -256,21 +330,22 @@
 	}
 
 	if (!uptodate)
-		atomic_inc(&wi->err);
+		atomic_inc(&segbuf->sb_err);
 
 	bio_put(bio);
-	complete(&wi->bio_event);
+	complete(&segbuf->sb_bio_event);
 }
 
-static int nilfs_submit_seg_bio(struct nilfs_write_info *wi, int mode)
+static int nilfs_segbuf_submit_bio(struct nilfs_segment_buffer *segbuf,
+				   struct nilfs_write_info *wi, int mode)
 {
 	struct bio *bio = wi->bio;
 	int err;
 
-	if (wi->nbio > 0 && bdi_write_congested(wi->bdi)) {
-		wait_for_completion(&wi->bio_event);
-		wi->nbio--;
-		if (unlikely(atomic_read(&wi->err))) {
+	if (segbuf->sb_nbio > 0 && bdi_write_congested(wi->nilfs->ns_bdi)) {
+		wait_for_completion(&segbuf->sb_bio_event);
+		segbuf->sb_nbio--;
+		if (unlikely(atomic_read(&segbuf->sb_err))) {
 			bio_put(bio);
 			err = -EIO;
 			goto failed;
@@ -278,7 +353,7 @@
 	}
 
 	bio->bi_end_io = nilfs_end_bio_write;
-	bio->bi_private = wi;
+	bio->bi_private = segbuf;
 	bio_get(bio);
 	submit_bio(mode, bio);
 	if (bio_flagged(bio, BIO_EOPNOTSUPP)) {
@@ -286,7 +361,7 @@
 		err = -EOPNOTSUPP;
 		goto failed;
 	}
-	wi->nbio++;
+	segbuf->sb_nbio++;
 	bio_put(bio);
 
 	wi->bio = NULL;
@@ -301,17 +376,15 @@
 }
 
 /**
- * nilfs_alloc_seg_bio - allocate a bio for writing segment.
- * @sb: super block
- * @start: beginning disk block number of this BIO.
+ * nilfs_alloc_seg_bio - allocate a new bio for writing log
+ * @nilfs: nilfs object
+ * @start: start block number of the bio
  * @nr_vecs: request size of page vector.
  *
- * alloc_seg_bio() allocates a new BIO structure and initialize it.
- *
  * Return Value: On success, pointer to the struct bio is returned.
  * On error, NULL is returned.
  */
-static struct bio *nilfs_alloc_seg_bio(struct super_block *sb, sector_t start,
+static struct bio *nilfs_alloc_seg_bio(struct the_nilfs *nilfs, sector_t start,
 				       int nr_vecs)
 {
 	struct bio *bio;
@@ -322,36 +395,33 @@
 			bio = bio_alloc(GFP_NOIO, nr_vecs);
 	}
 	if (likely(bio)) {
-		bio->bi_bdev = sb->s_bdev;
-		bio->bi_sector = (sector_t)start << (sb->s_blocksize_bits - 9);
+		bio->bi_bdev = nilfs->ns_bdev;
+		bio->bi_sector = start << (nilfs->ns_blocksize_bits - 9);
 	}
 	return bio;
 }
 
-void nilfs_segbuf_prepare_write(struct nilfs_segment_buffer *segbuf,
-				struct nilfs_write_info *wi)
+static void nilfs_segbuf_prepare_write(struct nilfs_segment_buffer *segbuf,
+				       struct nilfs_write_info *wi)
 {
 	wi->bio = NULL;
 	wi->rest_blocks = segbuf->sb_sum.nblocks;
-	wi->max_pages = bio_get_nr_vecs(wi->sb->s_bdev);
+	wi->max_pages = bio_get_nr_vecs(wi->nilfs->ns_bdev);
 	wi->nr_vecs = min(wi->max_pages, wi->rest_blocks);
 	wi->start = wi->end = 0;
-	wi->nbio = 0;
 	wi->blocknr = segbuf->sb_pseg_start;
-
-	atomic_set(&wi->err, 0);
-	init_completion(&wi->bio_event);
 }
 
-static int nilfs_submit_bh(struct nilfs_write_info *wi, struct buffer_head *bh,
-			   int mode)
+static int nilfs_segbuf_submit_bh(struct nilfs_segment_buffer *segbuf,
+				  struct nilfs_write_info *wi,
+				  struct buffer_head *bh, int mode)
 {
 	int len, err;
 
 	BUG_ON(wi->nr_vecs <= 0);
  repeat:
 	if (!wi->bio) {
-		wi->bio = nilfs_alloc_seg_bio(wi->sb, wi->blocknr + wi->end,
+		wi->bio = nilfs_alloc_seg_bio(wi->nilfs, wi->blocknr + wi->end,
 					      wi->nr_vecs);
 		if (unlikely(!wi->bio))
 			return -ENOMEM;
@@ -363,76 +433,83 @@
 		return 0;
 	}
 	/* bio is FULL */
-	err = nilfs_submit_seg_bio(wi, mode);
+	err = nilfs_segbuf_submit_bio(segbuf, wi, mode);
 	/* never submit current bh */
 	if (likely(!err))
 		goto repeat;
 	return err;
 }
 
+/**
+ * nilfs_segbuf_write - submit write requests of a log
+ * @segbuf: buffer storing a log to be written
+ * @nilfs: nilfs object
+ *
+ * Return Value: On Success, 0 is returned. On Error, one of the following
+ * negative error code is returned.
+ *
+ * %-EIO - I/O error
+ *
+ * %-ENOMEM - Insufficient memory available.
+ */
 int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf,
-		       struct nilfs_write_info *wi)
+		       struct the_nilfs *nilfs)
 {
+	struct nilfs_write_info wi;
 	struct buffer_head *bh;
-	int res, rw = WRITE;
+	int res = 0, rw = WRITE;
+
+	wi.nilfs = nilfs;
+	nilfs_segbuf_prepare_write(segbuf, &wi);
 
 	list_for_each_entry(bh, &segbuf->sb_segsum_buffers, b_assoc_buffers) {
-		res = nilfs_submit_bh(wi, bh, rw);
+		res = nilfs_segbuf_submit_bh(segbuf, &wi, bh, rw);
 		if (unlikely(res))
 			goto failed_bio;
 	}
 
 	list_for_each_entry(bh, &segbuf->sb_payload_buffers, b_assoc_buffers) {
-		res = nilfs_submit_bh(wi, bh, rw);
+		res = nilfs_segbuf_submit_bh(segbuf, &wi, bh, rw);
 		if (unlikely(res))
 			goto failed_bio;
 	}
 
-	if (wi->bio) {
+	if (wi.bio) {
 		/*
 		 * Last BIO is always sent through the following
 		 * submission.
 		 */
 		rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG);
-		res = nilfs_submit_seg_bio(wi, rw);
-		if (unlikely(res))
-			goto failed_bio;
+		res = nilfs_segbuf_submit_bio(segbuf, &wi, rw);
 	}
 
-	res = 0;
- out:
-	return res;
-
  failed_bio:
-	atomic_inc(&wi->err);
-	goto out;
+	return res;
 }
 
 /**
  * nilfs_segbuf_wait - wait for completion of requested BIOs
- * @wi: nilfs_write_info
+ * @segbuf: segment buffer
  *
  * Return Value: On Success, 0 is returned. On Error, one of the following
  * negative error code is returned.
  *
  * %-EIO - I/O error
  */
-int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf,
-		      struct nilfs_write_info *wi)
+int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf)
 {
 	int err = 0;
 
-	if (!wi->nbio)
+	if (!segbuf->sb_nbio)
 		return 0;
 
 	do {
-		wait_for_completion(&wi->bio_event);
-	} while (--wi->nbio > 0);
+		wait_for_completion(&segbuf->sb_bio_event);
+	} while (--segbuf->sb_nbio > 0);
 
-	if (unlikely(atomic_read(&wi->err) > 0)) {
+	if (unlikely(atomic_read(&segbuf->sb_err) > 0)) {
 		printk(KERN_ERR "NILFS: IO error writing segment\n");
 		err = -EIO;
-		segbuf->sb_io_error = 1;
 	}
 	return err;
 }
diff --git a/fs/nilfs2/segbuf.h b/fs/nilfs2/segbuf.h
index 0c3076f..6af1630 100644
--- a/fs/nilfs2/segbuf.h
+++ b/fs/nilfs2/segbuf.h
@@ -27,7 +27,6 @@
 #include <linux/buffer_head.h>
 #include <linux/bio.h>
 #include <linux/completion.h>
-#include <linux/backing-dev.h>
 
 /**
  * struct nilfs_segsum_info - On-memory segment summary
@@ -77,7 +76,9 @@
  * @sb_rest_blocks: Number of residual blocks in the current segment
  * @sb_segsum_buffers: List of buffers for segment summaries
  * @sb_payload_buffers: List of buffers for segment payload
- * @sb_io_error: I/O error status
+ * @sb_nbio: Number of flying bio requests
+ * @sb_err: I/O error status
+ * @sb_bio_event: Completion event of log writing
  */
 struct nilfs_segment_buffer {
 	struct super_block     *sb_super;
@@ -96,7 +97,9 @@
 	struct list_head	sb_payload_buffers; /* including super root */
 
 	/* io status */
-	int			sb_io_error;
+	int			sb_nbio;
+	atomic_t		sb_err;
+	struct completion	sb_bio_event;
 };
 
 #define NILFS_LIST_SEGBUF(head)  \
@@ -125,6 +128,8 @@
 void nilfs_segbuf_free(struct nilfs_segment_buffer *);
 void nilfs_segbuf_map(struct nilfs_segment_buffer *, __u64, unsigned long,
 		      struct the_nilfs *);
+void nilfs_segbuf_map_cont(struct nilfs_segment_buffer *segbuf,
+			   struct nilfs_segment_buffer *prev);
 void nilfs_segbuf_set_next_segnum(struct nilfs_segment_buffer *, __u64,
 				  struct the_nilfs *);
 int nilfs_segbuf_reset(struct nilfs_segment_buffer *, unsigned, time_t);
@@ -161,41 +166,18 @@
 	segbuf->sb_sum.nfileblk++;
 }
 
-void nilfs_release_buffers(struct list_head *);
+int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf,
+		       struct the_nilfs *nilfs);
+int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf);
 
-static inline void nilfs_segbuf_clear(struct nilfs_segment_buffer *segbuf)
+void nilfs_clear_logs(struct list_head *logs);
+void nilfs_truncate_logs(struct list_head *logs,
+			 struct nilfs_segment_buffer *last);
+int nilfs_wait_on_logs(struct list_head *logs);
+
+static inline void nilfs_destroy_logs(struct list_head *logs)
 {
-	nilfs_release_buffers(&segbuf->sb_segsum_buffers);
-	nilfs_release_buffers(&segbuf->sb_payload_buffers);
+	nilfs_truncate_logs(logs, NULL);
 }
 
-struct nilfs_write_info {
-	struct bio	       *bio;
-	int 			start, end; /* The region to be submitted */
-	int			rest_blocks;
-	int			max_pages;
-	int			nr_vecs;
-	sector_t		blocknr;
-
-	int			nbio;
-	atomic_t		err;
-	struct completion	bio_event;
-				/* completion event of segment write */
-
-	/*
-	 * The following fields must be set explicitly
-	 */
-	struct super_block     *sb;
-	struct backing_dev_info *bdi; /* backing dev info */
-	struct buffer_head     *bh_sr;
-};
-
-
-void nilfs_segbuf_prepare_write(struct nilfs_segment_buffer *,
-				struct nilfs_write_info *);
-int nilfs_segbuf_write(struct nilfs_segment_buffer *,
-		       struct nilfs_write_info *);
-int nilfs_segbuf_wait(struct nilfs_segment_buffer *,
-		      struct nilfs_write_info *);
-
 #endif /* _NILFS_SEGBUF_H */
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 6eff66a..17584c5 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -974,12 +974,12 @@
 			      nilfs->ns_nongc_ctime : sci->sc_seg_ctime);
 	raw_sr->sr_flags = 0;
 
-	nilfs_mdt_write_inode_direct(
-		nilfs_dat_inode(nilfs), bh_sr, NILFS_SR_DAT_OFFSET(isz));
-	nilfs_mdt_write_inode_direct(
-		nilfs->ns_cpfile, bh_sr, NILFS_SR_CPFILE_OFFSET(isz));
-	nilfs_mdt_write_inode_direct(
-		nilfs->ns_sufile, bh_sr, NILFS_SR_SUFILE_OFFSET(isz));
+	nilfs_write_inode_common(nilfs_dat_inode(nilfs), (void *)raw_sr +
+				 NILFS_SR_DAT_OFFSET(isz), 1);
+	nilfs_write_inode_common(nilfs->ns_cpfile, (void *)raw_sr +
+				 NILFS_SR_CPFILE_OFFSET(isz), 1);
+	nilfs_write_inode_common(nilfs->ns_sufile, (void *)raw_sr +
+				 NILFS_SR_SUFILE_OFFSET(isz), 1);
 }
 
 static void nilfs_redirty_inodes(struct list_head *head)
@@ -1273,73 +1273,75 @@
 	return err;
 }
 
-static int nilfs_touch_segusage(struct inode *sufile, __u64 segnum)
-{
-	struct buffer_head *bh_su;
-	struct nilfs_segment_usage *raw_su;
-	int err;
-
-	err = nilfs_sufile_get_segment_usage(sufile, segnum, &raw_su, &bh_su);
-	if (unlikely(err))
-		return err;
-	nilfs_mdt_mark_buffer_dirty(bh_su);
-	nilfs_mdt_mark_dirty(sufile);
-	nilfs_sufile_put_segment_usage(sufile, segnum, bh_su);
-	return 0;
-}
-
+/**
+ * nilfs_segctor_begin_construction - setup segment buffer to make a new log
+ * @sci: nilfs_sc_info
+ * @nilfs: nilfs object
+ */
 static int nilfs_segctor_begin_construction(struct nilfs_sc_info *sci,
 					    struct the_nilfs *nilfs)
 {
-	struct nilfs_segment_buffer *segbuf, *n;
+	struct nilfs_segment_buffer *segbuf, *prev;
 	__u64 nextnum;
-	int err;
+	int err, alloc = 0;
 
-	if (list_empty(&sci->sc_segbufs)) {
-		segbuf = nilfs_segbuf_new(sci->sc_super);
-		if (unlikely(!segbuf))
-			return -ENOMEM;
-		list_add(&segbuf->sb_list, &sci->sc_segbufs);
-	} else
-		segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs);
+	segbuf = nilfs_segbuf_new(sci->sc_super);
+	if (unlikely(!segbuf))
+		return -ENOMEM;
 
-	nilfs_segbuf_map(segbuf, nilfs->ns_segnum, nilfs->ns_pseg_offset,
-			 nilfs);
+	if (list_empty(&sci->sc_write_logs)) {
+		nilfs_segbuf_map(segbuf, nilfs->ns_segnum,
+				 nilfs->ns_pseg_offset, nilfs);
+		if (segbuf->sb_rest_blocks < NILFS_PSEG_MIN_BLOCKS) {
+			nilfs_shift_to_next_segment(nilfs);
+			nilfs_segbuf_map(segbuf, nilfs->ns_segnum, 0, nilfs);
+		}
 
-	if (segbuf->sb_rest_blocks < NILFS_PSEG_MIN_BLOCKS) {
-		nilfs_shift_to_next_segment(nilfs);
-		nilfs_segbuf_map(segbuf, nilfs->ns_segnum, 0, nilfs);
-	}
-	sci->sc_segbuf_nblocks = segbuf->sb_rest_blocks;
-
-	err = nilfs_touch_segusage(nilfs->ns_sufile, segbuf->sb_segnum);
-	if (unlikely(err))
-		return err;
-
-	if (nilfs->ns_segnum == nilfs->ns_nextnum) {
-		/* Start from the head of a new full segment */
-		err = nilfs_sufile_alloc(nilfs->ns_sufile, &nextnum);
-		if (unlikely(err))
-			return err;
-	} else
+		segbuf->sb_sum.seg_seq = nilfs->ns_seg_seq;
 		nextnum = nilfs->ns_nextnum;
 
-	segbuf->sb_sum.seg_seq = nilfs->ns_seg_seq;
+		if (nilfs->ns_segnum == nilfs->ns_nextnum)
+			/* Start from the head of a new full segment */
+			alloc++;
+	} else {
+		/* Continue logs */
+		prev = NILFS_LAST_SEGBUF(&sci->sc_write_logs);
+		nilfs_segbuf_map_cont(segbuf, prev);
+		segbuf->sb_sum.seg_seq = prev->sb_sum.seg_seq;
+		nextnum = prev->sb_nextnum;
+
+		if (segbuf->sb_rest_blocks < NILFS_PSEG_MIN_BLOCKS) {
+			nilfs_segbuf_map(segbuf, prev->sb_nextnum, 0, nilfs);
+			segbuf->sb_sum.seg_seq++;
+			alloc++;
+		}
+	}
+
+	err = nilfs_sufile_mark_dirty(nilfs->ns_sufile, segbuf->sb_segnum);
+	if (err)
+		goto failed;
+
+	if (alloc) {
+		err = nilfs_sufile_alloc(nilfs->ns_sufile, &nextnum);
+		if (err)
+			goto failed;
+	}
 	nilfs_segbuf_set_next_segnum(segbuf, nextnum, nilfs);
 
-	/* truncating segment buffers */
-	list_for_each_entry_safe_continue(segbuf, n, &sci->sc_segbufs,
-					  sb_list) {
-		list_del_init(&segbuf->sb_list);
-		nilfs_segbuf_free(segbuf);
-	}
+	BUG_ON(!list_empty(&sci->sc_segbufs));
+	list_add_tail(&segbuf->sb_list, &sci->sc_segbufs);
+	sci->sc_segbuf_nblocks = segbuf->sb_rest_blocks;
 	return 0;
+
+ failed:
+	nilfs_segbuf_free(segbuf);
+	return err;
 }
 
 static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci,
 					 struct the_nilfs *nilfs, int nadd)
 {
-	struct nilfs_segment_buffer *segbuf, *prev, *n;
+	struct nilfs_segment_buffer *segbuf, *prev;
 	struct inode *sufile = nilfs->ns_sufile;
 	__u64 nextnextnum;
 	LIST_HEAD(list);
@@ -1352,7 +1354,7 @@
 	 * not be dirty.  The following call ensures that the buffer is dirty
 	 * and will pin the buffer on memory until the sufile is written.
 	 */
-	err = nilfs_touch_segusage(sufile, prev->sb_nextnum);
+	err = nilfs_sufile_mark_dirty(sufile, prev->sb_nextnum);
 	if (unlikely(err))
 		return err;
 
@@ -1378,33 +1380,33 @@
 		list_add_tail(&segbuf->sb_list, &list);
 		prev = segbuf;
 	}
-	list_splice(&list, sci->sc_segbufs.prev);
+	list_splice_tail(&list, &sci->sc_segbufs);
 	return 0;
 
  failed_segbuf:
 	nilfs_segbuf_free(segbuf);
  failed:
-	list_for_each_entry_safe(segbuf, n, &list, sb_list) {
+	list_for_each_entry(segbuf, &list, sb_list) {
 		ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
 		WARN_ON(ret); /* never fails */
-		list_del_init(&segbuf->sb_list);
-		nilfs_segbuf_free(segbuf);
 	}
+	nilfs_destroy_logs(&list);
 	return err;
 }
 
-static void nilfs_segctor_free_incomplete_segments(struct nilfs_sc_info *sci,
-						   struct the_nilfs *nilfs)
+static void nilfs_free_incomplete_logs(struct list_head *logs,
+				       struct the_nilfs *nilfs)
 {
-	struct nilfs_segment_buffer *segbuf;
-	int ret, done = 0;
+	struct nilfs_segment_buffer *segbuf, *prev;
+	struct inode *sufile = nilfs->ns_sufile;
+	int ret;
 
-	segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs);
+	segbuf = NILFS_FIRST_SEGBUF(logs);
 	if (nilfs->ns_nextnum != segbuf->sb_nextnum) {
-		ret = nilfs_sufile_free(nilfs->ns_sufile, segbuf->sb_nextnum);
+		ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
 		WARN_ON(ret); /* never fails */
 	}
-	if (segbuf->sb_io_error) {
+	if (atomic_read(&segbuf->sb_err)) {
 		/* Case 1: The first segment failed */
 		if (segbuf->sb_pseg_start != segbuf->sb_fseg_start)
 			/* Case 1a:  Partial segment appended into an existing
@@ -1413,106 +1415,54 @@
 						segbuf->sb_fseg_end);
 		else /* Case 1b:  New full segment */
 			set_nilfs_discontinued(nilfs);
-		done++;
 	}
 
-	list_for_each_entry_continue(segbuf, &sci->sc_segbufs, sb_list) {
-		ret = nilfs_sufile_free(nilfs->ns_sufile, segbuf->sb_nextnum);
-		WARN_ON(ret); /* never fails */
-		if (!done && segbuf->sb_io_error) {
-			if (segbuf->sb_segnum != nilfs->ns_nextnum)
-				/* Case 2: extended segment (!= next) failed */
-				nilfs_sufile_set_error(nilfs->ns_sufile,
-						       segbuf->sb_segnum);
-			done++;
+	prev = segbuf;
+	list_for_each_entry_continue(segbuf, logs, sb_list) {
+		if (prev->sb_nextnum != segbuf->sb_nextnum) {
+			ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
+			WARN_ON(ret); /* never fails */
 		}
+		if (atomic_read(&segbuf->sb_err) &&
+		    segbuf->sb_segnum != nilfs->ns_nextnum)
+			/* Case 2: extended segment (!= next) failed */
+			nilfs_sufile_set_error(sufile, segbuf->sb_segnum);
+		prev = segbuf;
 	}
 }
 
-static void nilfs_segctor_clear_segment_buffers(struct nilfs_sc_info *sci)
-{
-	struct nilfs_segment_buffer *segbuf;
-
-	list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list)
-		nilfs_segbuf_clear(segbuf);
-	sci->sc_super_root = NULL;
-}
-
-static void nilfs_segctor_destroy_segment_buffers(struct nilfs_sc_info *sci)
-{
-	struct nilfs_segment_buffer *segbuf;
-
-	while (!list_empty(&sci->sc_segbufs)) {
-		segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs);
-		list_del_init(&segbuf->sb_list);
-		nilfs_segbuf_free(segbuf);
-	}
-	/* sci->sc_curseg = NULL; */
-}
-
-static void nilfs_segctor_end_construction(struct nilfs_sc_info *sci,
-					   struct the_nilfs *nilfs, int err)
-{
-	if (unlikely(err)) {
-		nilfs_segctor_free_incomplete_segments(sci, nilfs);
-		if (sci->sc_stage.flags & NILFS_CF_SUFREED) {
-			int ret;
-
-			ret = nilfs_sufile_cancel_freev(nilfs->ns_sufile,
-							sci->sc_freesegs,
-							sci->sc_nfreesegs,
-							NULL);
-			WARN_ON(ret); /* do not happen */
-		}
-	}
-	nilfs_segctor_clear_segment_buffers(sci);
-}
-
 static void nilfs_segctor_update_segusage(struct nilfs_sc_info *sci,
 					  struct inode *sufile)
 {
 	struct nilfs_segment_buffer *segbuf;
-	struct buffer_head *bh_su;
-	struct nilfs_segment_usage *raw_su;
 	unsigned long live_blocks;
 	int ret;
 
 	list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
-		ret = nilfs_sufile_get_segment_usage(sufile, segbuf->sb_segnum,
-						     &raw_su, &bh_su);
-		WARN_ON(ret); /* always succeed because bh_su is dirty */
 		live_blocks = segbuf->sb_sum.nblocks +
 			(segbuf->sb_pseg_start - segbuf->sb_fseg_start);
-		raw_su->su_lastmod = cpu_to_le64(sci->sc_seg_ctime);
-		raw_su->su_nblocks = cpu_to_le32(live_blocks);
-		nilfs_sufile_put_segment_usage(sufile, segbuf->sb_segnum,
-					       bh_su);
+		ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum,
+						     live_blocks,
+						     sci->sc_seg_ctime);
+		WARN_ON(ret); /* always succeed because the segusage is dirty */
 	}
 }
 
-static void nilfs_segctor_cancel_segusage(struct nilfs_sc_info *sci,
-					  struct inode *sufile)
+static void nilfs_cancel_segusage(struct list_head *logs, struct inode *sufile)
 {
 	struct nilfs_segment_buffer *segbuf;
-	struct buffer_head *bh_su;
-	struct nilfs_segment_usage *raw_su;
 	int ret;
 
-	segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs);
-	ret = nilfs_sufile_get_segment_usage(sufile, segbuf->sb_segnum,
-					     &raw_su, &bh_su);
-	WARN_ON(ret); /* always succeed because bh_su is dirty */
-	raw_su->su_nblocks = cpu_to_le32(segbuf->sb_pseg_start -
-					 segbuf->sb_fseg_start);
-	nilfs_sufile_put_segment_usage(sufile, segbuf->sb_segnum, bh_su);
+	segbuf = NILFS_FIRST_SEGBUF(logs);
+	ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum,
+					     segbuf->sb_pseg_start -
+					     segbuf->sb_fseg_start, 0);
+	WARN_ON(ret); /* always succeed because the segusage is dirty */
 
-	list_for_each_entry_continue(segbuf, &sci->sc_segbufs, sb_list) {
-		ret = nilfs_sufile_get_segment_usage(sufile, segbuf->sb_segnum,
-						     &raw_su, &bh_su);
+	list_for_each_entry_continue(segbuf, logs, sb_list) {
+		ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum,
+						     0, 0);
 		WARN_ON(ret); /* always succeed */
-		raw_su->su_nblocks = 0;
-		nilfs_sufile_put_segment_usage(sufile, segbuf->sb_segnum,
-					       bh_su);
 	}
 }
 
@@ -1520,17 +1470,15 @@
 					    struct nilfs_segment_buffer *last,
 					    struct inode *sufile)
 {
-	struct nilfs_segment_buffer *segbuf = last, *n;
+	struct nilfs_segment_buffer *segbuf = last;
 	int ret;
 
-	list_for_each_entry_safe_continue(segbuf, n, &sci->sc_segbufs,
-					  sb_list) {
-		list_del_init(&segbuf->sb_list);
+	list_for_each_entry_continue(segbuf, &sci->sc_segbufs, sb_list) {
 		sci->sc_segbuf_nblocks -= segbuf->sb_rest_blocks;
 		ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
 		WARN_ON(ret);
-		nilfs_segbuf_free(segbuf);
 	}
+	nilfs_truncate_logs(&sci->sc_segbufs, last);
 }
 
 
@@ -1569,7 +1517,7 @@
 							NULL);
 			WARN_ON(err); /* do not happen */
 		}
-		nilfs_segctor_clear_segment_buffers(sci);
+		nilfs_clear_logs(&sci->sc_segbufs);
 
 		err = nilfs_segctor_extend_segments(sci, nilfs, nadd);
 		if (unlikely(err))
@@ -1814,26 +1762,18 @@
 }
 
 static int nilfs_segctor_write(struct nilfs_sc_info *sci,
-			       struct backing_dev_info *bdi)
+			       struct the_nilfs *nilfs)
 {
 	struct nilfs_segment_buffer *segbuf;
-	struct nilfs_write_info wi;
-	int err, res;
-
-	wi.sb = sci->sc_super;
-	wi.bh_sr = sci->sc_super_root;
-	wi.bdi = bdi;
+	int ret = 0;
 
 	list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
-		nilfs_segbuf_prepare_write(segbuf, &wi);
-		err = nilfs_segbuf_write(segbuf, &wi);
-
-		res = nilfs_segbuf_wait(segbuf, &wi);
-		err = err ? : res;
-		if (err)
-			return err;
+		ret = nilfs_segbuf_write(segbuf, nilfs);
+		if (ret)
+			break;
 	}
-	return 0;
+	list_splice_tail_init(&sci->sc_segbufs, &sci->sc_write_logs);
+	return ret;
 }
 
 static void __nilfs_end_page_io(struct page *page, int err)
@@ -1911,15 +1851,17 @@
 	}
 }
 
-static void nilfs_segctor_abort_write(struct nilfs_sc_info *sci,
-				      struct page *failed_page, int err)
+static void nilfs_abort_logs(struct list_head *logs, struct page *failed_page,
+			     struct buffer_head *bh_sr, int err)
 {
 	struct nilfs_segment_buffer *segbuf;
 	struct page *bd_page = NULL, *fs_page = NULL;
+	struct buffer_head *bh;
 
-	list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
-		struct buffer_head *bh;
+	if (list_empty(logs))
+		return;
 
+	list_for_each_entry(segbuf, logs, sb_list) {
 		list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
 				    b_assoc_buffers) {
 			if (bh->b_page != bd_page) {
@@ -1931,7 +1873,7 @@
 
 		list_for_each_entry(bh, &segbuf->sb_payload_buffers,
 				    b_assoc_buffers) {
-			if (bh == sci->sc_super_root) {
+			if (bh == bh_sr) {
 				if (bh->b_page != bd_page) {
 					end_page_writeback(bd_page);
 					bd_page = bh->b_page;
@@ -1941,7 +1883,7 @@
 			if (bh->b_page != fs_page) {
 				nilfs_end_page_io(fs_page, err);
 				if (fs_page && fs_page == failed_page)
-					goto done;
+					return;
 				fs_page = bh->b_page;
 			}
 		}
@@ -1950,8 +1892,34 @@
 		end_page_writeback(bd_page);
 
 	nilfs_end_page_io(fs_page, err);
- done:
+}
+
+static void nilfs_segctor_abort_construction(struct nilfs_sc_info *sci,
+					     struct the_nilfs *nilfs, int err)
+{
+	LIST_HEAD(logs);
+	int ret;
+
+	list_splice_tail_init(&sci->sc_write_logs, &logs);
+	ret = nilfs_wait_on_logs(&logs);
+	if (ret)
+		nilfs_abort_logs(&logs, NULL, sci->sc_super_root, ret);
+
+	list_splice_tail_init(&sci->sc_segbufs, &logs);
+	nilfs_cancel_segusage(&logs, nilfs->ns_sufile);
+	nilfs_free_incomplete_logs(&logs, nilfs);
 	nilfs_clear_copied_buffers(&sci->sc_copied_buffers, err);
+
+	if (sci->sc_stage.flags & NILFS_CF_SUFREED) {
+		ret = nilfs_sufile_cancel_freev(nilfs->ns_sufile,
+						sci->sc_freesegs,
+						sci->sc_nfreesegs,
+						NULL);
+		WARN_ON(ret); /* do not happen */
+	}
+
+	nilfs_destroy_logs(&logs);
+	sci->sc_super_root = NULL;
 }
 
 static void nilfs_set_next_segment(struct the_nilfs *nilfs,
@@ -1973,7 +1941,7 @@
 	struct the_nilfs *nilfs = sbi->s_nilfs;
 	int update_sr = (sci->sc_super_root != NULL);
 
-	list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
+	list_for_each_entry(segbuf, &sci->sc_write_logs, sb_list) {
 		struct buffer_head *bh;
 
 		list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
@@ -2046,7 +2014,7 @@
 
 	sci->sc_nblk_inc += sci->sc_nblk_this_inc;
 
-	segbuf = NILFS_LAST_SEGBUF(&sci->sc_segbufs);
+	segbuf = NILFS_LAST_SEGBUF(&sci->sc_write_logs);
 	nilfs_set_next_segment(nilfs, segbuf);
 
 	if (update_sr) {
@@ -2057,10 +2025,23 @@
 		clear_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags);
 		clear_bit(NILFS_SC_DIRTY, &sci->sc_flags);
 		set_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags);
+		nilfs_segctor_clear_metadata_dirty(sci);
 	} else
 		clear_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags);
 }
 
+static int nilfs_segctor_wait(struct nilfs_sc_info *sci)
+{
+	int ret;
+
+	ret = nilfs_wait_on_logs(&sci->sc_write_logs);
+	if (!ret) {
+		nilfs_segctor_complete_write(sci);
+		nilfs_destroy_logs(&sci->sc_write_logs);
+	}
+	return ret;
+}
+
 static int nilfs_segctor_check_in_files(struct nilfs_sc_info *sci,
 					struct nilfs_sb_info *sbi)
 {
@@ -2173,7 +2154,7 @@
 		/* Avoid empty segment */
 		if (sci->sc_stage.scnt == NILFS_ST_DONE &&
 		    NILFS_SEG_EMPTY(&sci->sc_curseg->sb_sum)) {
-			nilfs_segctor_end_construction(sci, nilfs, 1);
+			nilfs_segctor_abort_construction(sci, nilfs, 1);
 			goto out;
 		}
 
@@ -2187,7 +2168,7 @@
 		if (has_sr) {
 			err = nilfs_segctor_fill_in_checkpoint(sci);
 			if (unlikely(err))
-				goto failed_to_make_up;
+				goto failed_to_write;
 
 			nilfs_segctor_fill_in_super_root(sci, nilfs);
 		}
@@ -2195,42 +2176,46 @@
 
 		/* Write partial segments */
 		err = nilfs_segctor_prepare_write(sci, &failed_page);
-		if (unlikely(err))
+		if (err) {
+			nilfs_abort_logs(&sci->sc_segbufs, failed_page,
+					 sci->sc_super_root, err);
 			goto failed_to_write;
-
+		}
 		nilfs_segctor_fill_in_checksums(sci, nilfs->ns_crc_seed);
 
-		err = nilfs_segctor_write(sci, nilfs->ns_bdi);
+		err = nilfs_segctor_write(sci, nilfs);
 		if (unlikely(err))
 			goto failed_to_write;
 
-		nilfs_segctor_complete_write(sci);
-
-		/* Commit segments */
-		if (has_sr)
-			nilfs_segctor_clear_metadata_dirty(sci);
-
-		nilfs_segctor_end_construction(sci, nilfs, 0);
-
+		if (sci->sc_stage.scnt == NILFS_ST_DONE ||
+		    nilfs->ns_blocksize_bits != PAGE_CACHE_SHIFT) {
+			/*
+			 * At this point, we avoid double buffering
+			 * for blocksize < pagesize because page dirty
+			 * flag is turned off during write and dirty
+			 * buffers are not properly collected for
+			 * pages crossing over segments.
+			 */
+			err = nilfs_segctor_wait(sci);
+			if (err)
+				goto failed_to_write;
+		}
 	} while (sci->sc_stage.scnt != NILFS_ST_DONE);
 
+	sci->sc_super_root = NULL;
+
  out:
-	nilfs_segctor_destroy_segment_buffers(sci);
 	nilfs_segctor_check_out_files(sci, sbi);
 	return err;
 
  failed_to_write:
-	nilfs_segctor_abort_write(sci, failed_page, err);
-	nilfs_segctor_cancel_segusage(sci, nilfs->ns_sufile);
-
- failed_to_make_up:
 	if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED)
 		nilfs_redirty_inodes(&sci->sc_dirty_files);
 
  failed:
 	if (nilfs_doing_gc())
 		nilfs_redirty_inodes(&sci->sc_gc_inodes);
-	nilfs_segctor_end_construction(sci, nilfs, err);
+	nilfs_segctor_abort_construction(sci, nilfs, err);
 	goto out;
 }
 
@@ -2559,7 +2544,7 @@
 
 	sci->sc_freesegs = kbufs[4];
 	sci->sc_nfreesegs = argv[4].v_nmembs;
-	list_splice_init(&nilfs->ns_gc_inodes, sci->sc_gc_inodes.prev);
+	list_splice_tail_init(&nilfs->ns_gc_inodes, &sci->sc_gc_inodes);
 
 	for (;;) {
 		nilfs_segctor_accept(sci, &req);
@@ -2788,6 +2773,7 @@
 	spin_lock_init(&sci->sc_state_lock);
 	INIT_LIST_HEAD(&sci->sc_dirty_files);
 	INIT_LIST_HEAD(&sci->sc_segbufs);
+	INIT_LIST_HEAD(&sci->sc_write_logs);
 	INIT_LIST_HEAD(&sci->sc_gc_inodes);
 	INIT_LIST_HEAD(&sci->sc_copied_buffers);
 
@@ -2855,6 +2841,7 @@
 	}
 
 	WARN_ON(!list_empty(&sci->sc_segbufs));
+	WARN_ON(!list_empty(&sci->sc_write_logs));
 
 	down_write(&sbi->s_nilfs->ns_segctor_sem);
 
diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h
index 0d2a475..3d3ab2f 100644
--- a/fs/nilfs2/segment.h
+++ b/fs/nilfs2/segment.h
@@ -97,6 +97,7 @@
  * @sc_dsync_start: start byte offset of data pages
  * @sc_dsync_end: end byte offset of data pages (inclusive)
  * @sc_segbufs: List of segment buffers
+ * @sc_write_logs: List of segment buffers to hold logs under writing
  * @sc_segbuf_nblocks: Number of available blocks in segment buffers.
  * @sc_curseg: Current segment buffer
  * @sc_super_root: Pointer to the super root buffer
@@ -143,6 +144,7 @@
 
 	/* Segment buffers */
 	struct list_head	sc_segbufs;
+	struct list_head	sc_write_logs;
 	unsigned long		sc_segbuf_nblocks;
 	struct nilfs_segment_buffer *sc_curseg;
 	struct buffer_head     *sc_super_root;
diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c
index 37994d4..b6c36d0 100644
--- a/fs/nilfs2/sufile.c
+++ b/fs/nilfs2/sufile.c
@@ -31,6 +31,16 @@
 #include "sufile.h"
 
 
+struct nilfs_sufile_info {
+	struct nilfs_mdt_info mi;
+	unsigned long ncleansegs;
+};
+
+static inline struct nilfs_sufile_info *NILFS_SUI(struct inode *sufile)
+{
+	return (struct nilfs_sufile_info *)NILFS_MDT(sufile);
+}
+
 static inline unsigned long
 nilfs_sufile_segment_usages_per_block(const struct inode *sufile)
 {
@@ -62,14 +72,6 @@
 		     max - curr + 1);
 }
 
-static inline struct nilfs_sufile_header *
-nilfs_sufile_block_get_header(const struct inode *sufile,
-			      struct buffer_head *bh,
-			      void *kaddr)
-{
-	return kaddr + bh_offset(bh);
-}
-
 static struct nilfs_segment_usage *
 nilfs_sufile_block_get_segment_usage(const struct inode *sufile, __u64 segnum,
 				     struct buffer_head *bh, void *kaddr)
@@ -110,6 +112,15 @@
 }
 
 /**
+ * nilfs_sufile_get_ncleansegs - return the number of clean segments
+ * @sufile: inode of segment usage file
+ */
+unsigned long nilfs_sufile_get_ncleansegs(struct inode *sufile)
+{
+	return NILFS_SUI(sufile)->ncleansegs;
+}
+
+/**
  * nilfs_sufile_updatev - modify multiple segment usages at a time
  * @sufile: inode of segment usage file
  * @segnumv: array of segment numbers
@@ -270,7 +281,7 @@
 	if (ret < 0)
 		goto out_sem;
 	kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
-	header = nilfs_sufile_block_get_header(sufile, header_bh, kaddr);
+	header = kaddr + bh_offset(header_bh);
 	ncleansegs = le64_to_cpu(header->sh_ncleansegs);
 	last_alloc = le64_to_cpu(header->sh_last_alloc);
 	kunmap_atomic(kaddr, KM_USER0);
@@ -302,13 +313,13 @@
 			kunmap_atomic(kaddr, KM_USER0);
 
 			kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
-			header = nilfs_sufile_block_get_header(
-				sufile, header_bh, kaddr);
+			header = kaddr + bh_offset(header_bh);
 			le64_add_cpu(&header->sh_ncleansegs, -1);
 			le64_add_cpu(&header->sh_ndirtysegs, 1);
 			header->sh_last_alloc = cpu_to_le64(segnum);
 			kunmap_atomic(kaddr, KM_USER0);
 
+			NILFS_SUI(sufile)->ncleansegs--;
 			nilfs_mdt_mark_buffer_dirty(header_bh);
 			nilfs_mdt_mark_buffer_dirty(su_bh);
 			nilfs_mdt_mark_dirty(sufile);
@@ -351,6 +362,8 @@
 	kunmap_atomic(kaddr, KM_USER0);
 
 	nilfs_sufile_mod_counter(header_bh, -1, 1);
+	NILFS_SUI(sufile)->ncleansegs--;
+
 	nilfs_mdt_mark_buffer_dirty(su_bh);
 	nilfs_mdt_mark_dirty(sufile);
 }
@@ -380,6 +393,8 @@
 	kunmap_atomic(kaddr, KM_USER0);
 
 	nilfs_sufile_mod_counter(header_bh, clean ? (u64)-1 : 0, dirty ? 0 : 1);
+	NILFS_SUI(sufile)->ncleansegs -= clean;
+
 	nilfs_mdt_mark_buffer_dirty(su_bh);
 	nilfs_mdt_mark_dirty(sufile);
 }
@@ -409,58 +424,61 @@
 	nilfs_mdt_mark_buffer_dirty(su_bh);
 
 	nilfs_sufile_mod_counter(header_bh, 1, sudirty ? (u64)-1 : 0);
+	NILFS_SUI(sufile)->ncleansegs++;
+
 	nilfs_mdt_mark_dirty(sufile);
 }
 
 /**
- * nilfs_sufile_get_segment_usage - get a segment usage
+ * nilfs_sufile_mark_dirty - mark the buffer having a segment usage dirty
  * @sufile: inode of segment usage file
  * @segnum: segment number
- * @sup: pointer to segment usage
- * @bhp: pointer to buffer head
- *
- * Description: nilfs_sufile_get_segment_usage() acquires the segment usage
- * specified by @segnum.
- *
- * Return Value: On success, 0 is returned, and the segment usage and the
- * buffer head of the buffer on which the segment usage is located are stored
- * in the place pointed by @sup and @bhp, respectively. On error, one of the
- * following negative error codes is returned.
- *
- * %-EIO - I/O error.
- *
- * %-ENOMEM - Insufficient amount of memory available.
- *
- * %-EINVAL - Invalid segment usage number.
  */
-int nilfs_sufile_get_segment_usage(struct inode *sufile, __u64 segnum,
-				   struct nilfs_segment_usage **sup,
-				   struct buffer_head **bhp)
+int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum)
+{
+	struct buffer_head *bh;
+	int ret;
+
+	ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0, &bh);
+	if (!ret) {
+		nilfs_mdt_mark_buffer_dirty(bh);
+		nilfs_mdt_mark_dirty(sufile);
+		brelse(bh);
+	}
+	return ret;
+}
+
+/**
+ * nilfs_sufile_set_segment_usage - set usage of a segment
+ * @sufile: inode of segment usage file
+ * @segnum: segment number
+ * @nblocks: number of live blocks in the segment
+ * @modtime: modification time (option)
+ */
+int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum,
+				   unsigned long nblocks, time_t modtime)
 {
 	struct buffer_head *bh;
 	struct nilfs_segment_usage *su;
 	void *kaddr;
 	int ret;
 
-	/* segnum is 0 origin */
-	if (segnum >= nilfs_sufile_get_nsegments(sufile))
-		return -EINVAL;
 	down_write(&NILFS_MDT(sufile)->mi_sem);
-	ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 1, &bh);
+	ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0, &bh);
 	if (ret < 0)
 		goto out_sem;
-	kaddr = kmap(bh->b_page);
-	su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr);
-	if (nilfs_segment_usage_error(su)) {
-		kunmap(bh->b_page);
-		brelse(bh);
-		ret = -EINVAL;
-		goto out_sem;
-	}
 
-	if (sup != NULL)
-		*sup = su;
-	*bhp = bh;
+	kaddr = kmap_atomic(bh->b_page, KM_USER0);
+	su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr);
+	WARN_ON(nilfs_segment_usage_error(su));
+	if (modtime)
+		su->su_lastmod = cpu_to_le64(modtime);
+	su->su_nblocks = cpu_to_le32(nblocks);
+	kunmap_atomic(kaddr, KM_USER0);
+
+	nilfs_mdt_mark_buffer_dirty(bh);
+	nilfs_mdt_mark_dirty(sufile);
+	brelse(bh);
 
  out_sem:
 	up_write(&NILFS_MDT(sufile)->mi_sem);
@@ -468,23 +486,6 @@
 }
 
 /**
- * nilfs_sufile_put_segment_usage - put a segment usage
- * @sufile: inode of segment usage file
- * @segnum: segment number
- * @bh: buffer head
- *
- * Description: nilfs_sufile_put_segment_usage() releases the segment usage
- * specified by @segnum. @bh must be the buffer head which have been returned
- * by a previous call to nilfs_sufile_get_segment_usage() with @segnum.
- */
-void nilfs_sufile_put_segment_usage(struct inode *sufile, __u64 segnum,
-				    struct buffer_head *bh)
-{
-	kunmap(bh->b_page);
-	brelse(bh);
-}
-
-/**
  * nilfs_sufile_get_stat - get segment usage statistics
  * @sufile: inode of segment usage file
  * @stat: pointer to a structure of segment usage statistics
@@ -515,7 +516,7 @@
 		goto out_sem;
 
 	kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
-	header = nilfs_sufile_block_get_header(sufile, header_bh, kaddr);
+	header = kaddr + bh_offset(header_bh);
 	sustat->ss_nsegs = nilfs_sufile_get_nsegments(sufile);
 	sustat->ss_ncleansegs = le64_to_cpu(header->sh_ncleansegs);
 	sustat->ss_ndirtysegs = le64_to_cpu(header->sh_ndirtysegs);
@@ -532,33 +533,6 @@
 	return ret;
 }
 
-/**
- * nilfs_sufile_get_ncleansegs - get the number of clean segments
- * @sufile: inode of segment usage file
- * @nsegsp: pointer to the number of clean segments
- *
- * Description: nilfs_sufile_get_ncleansegs() acquires the number of clean
- * segments.
- *
- * Return Value: On success, 0 is returned and the number of clean segments is
- * stored in the place pointed by @nsegsp. On error, one of the following
- * negative error codes is returned.
- *
- * %-EIO - I/O error.
- *
- * %-ENOMEM - Insufficient amount of memory available.
- */
-int nilfs_sufile_get_ncleansegs(struct inode *sufile, unsigned long *nsegsp)
-{
-	struct nilfs_sustat sustat;
-	int ret;
-
-	ret = nilfs_sufile_get_stat(sufile, &sustat);
-	if (ret == 0)
-		*nsegsp = sustat.ss_ncleansegs;
-	return ret;
-}
-
 void nilfs_sufile_do_set_error(struct inode *sufile, __u64 segnum,
 			       struct buffer_head *header_bh,
 			       struct buffer_head *su_bh)
@@ -577,8 +551,10 @@
 	nilfs_segment_usage_set_error(su);
 	kunmap_atomic(kaddr, KM_USER0);
 
-	if (suclean)
+	if (suclean) {
 		nilfs_sufile_mod_counter(header_bh, -1, 0);
+		NILFS_SUI(sufile)->ncleansegs--;
+	}
 	nilfs_mdt_mark_buffer_dirty(su_bh);
 	nilfs_mdt_mark_dirty(sufile);
 }
@@ -657,3 +633,48 @@
 	up_read(&NILFS_MDT(sufile)->mi_sem);
 	return ret;
 }
+
+/**
+ * nilfs_sufile_read - read sufile inode
+ * @sufile: sufile inode
+ * @raw_inode: on-disk sufile inode
+ */
+int nilfs_sufile_read(struct inode *sufile, struct nilfs_inode *raw_inode)
+{
+	struct nilfs_sufile_info *sui = NILFS_SUI(sufile);
+	struct buffer_head *header_bh;
+	struct nilfs_sufile_header *header;
+	void *kaddr;
+	int ret;
+
+	ret = nilfs_read_inode_common(sufile, raw_inode);
+	if (ret < 0)
+		return ret;
+
+	ret = nilfs_sufile_get_header_block(sufile, &header_bh);
+	if (!ret) {
+		kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
+		header = kaddr + bh_offset(header_bh);
+		sui->ncleansegs = le64_to_cpu(header->sh_ncleansegs);
+		kunmap_atomic(kaddr, KM_USER0);
+		brelse(header_bh);
+	}
+	return ret;
+}
+
+/**
+ * nilfs_sufile_new - create sufile
+ * @nilfs: nilfs object
+ * @susize: size of a segment usage entry
+ */
+struct inode *nilfs_sufile_new(struct the_nilfs *nilfs, size_t susize)
+{
+	struct inode *sufile;
+
+	sufile = nilfs_mdt_new(nilfs, NULL, NILFS_SUFILE_INO,
+			       sizeof(struct nilfs_sufile_info));
+	if (sufile)
+		nilfs_mdt_set_entry_size(sufile, susize,
+					 sizeof(struct nilfs_sufile_header));
+	return sufile;
+}
diff --git a/fs/nilfs2/sufile.h b/fs/nilfs2/sufile.h
index 0e99e5c..15163b8 100644
--- a/fs/nilfs2/sufile.h
+++ b/fs/nilfs2/sufile.h
@@ -34,14 +34,13 @@
 	return NILFS_MDT(sufile)->mi_nilfs->ns_nsegments;
 }
 
+unsigned long nilfs_sufile_get_ncleansegs(struct inode *sufile);
+
 int nilfs_sufile_alloc(struct inode *, __u64 *);
-int nilfs_sufile_get_segment_usage(struct inode *, __u64,
-				   struct nilfs_segment_usage **,
-				   struct buffer_head **);
-void nilfs_sufile_put_segment_usage(struct inode *, __u64,
-				    struct buffer_head *);
+int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum);
+int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum,
+				   unsigned long nblocks, time_t modtime);
 int nilfs_sufile_get_stat(struct inode *, struct nilfs_sustat *);
-int nilfs_sufile_get_ncleansegs(struct inode *, unsigned long *);
 ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, void *, unsigned,
 				size_t);
 
@@ -62,6 +61,9 @@
 void nilfs_sufile_do_set_error(struct inode *, __u64, struct buffer_head *,
 			       struct buffer_head *);
 
+int nilfs_sufile_read(struct inode *sufile, struct nilfs_inode *raw_inode);
+struct inode *nilfs_sufile_new(struct the_nilfs *nilfs, size_t susize);
+
 /**
  * nilfs_sufile_scrap - make a segment garbage
  * @sufile: inode of segment usage file
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 644e667..5403b3e 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -363,14 +363,10 @@
 	list_add(&sbi->s_list, &nilfs->ns_supers);
 	up_write(&nilfs->ns_super_sem);
 
-	sbi->s_ifile = nilfs_mdt_new(nilfs, sbi->s_super, NILFS_IFILE_INO);
+	sbi->s_ifile = nilfs_ifile_new(sbi, nilfs->ns_inode_size);
 	if (!sbi->s_ifile)
 		return -ENOMEM;
 
-	err = nilfs_palloc_init_blockgroup(sbi->s_ifile, nilfs->ns_inode_size);
-	if (unlikely(err))
-		goto failed;
-
 	down_read(&nilfs->ns_segctor_sem);
 	err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, cno, 0, &raw_cp,
 					  &bh_cp);
@@ -411,7 +407,6 @@
 {
 	struct the_nilfs *nilfs = sbi->s_nilfs;
 
-	nilfs_mdt_clear(sbi->s_ifile);
 	nilfs_mdt_destroy(sbi->s_ifile);
 	sbi->s_ifile = NULL;
 	down_write(&nilfs->ns_super_sem);
@@ -419,22 +414,6 @@
 	up_write(&nilfs->ns_super_sem);
 }
 
-static int nilfs_mark_recovery_complete(struct nilfs_sb_info *sbi)
-{
-	struct the_nilfs *nilfs = sbi->s_nilfs;
-	int err = 0;
-
-	down_write(&nilfs->ns_sem);
-	if (!(nilfs->ns_mount_state & NILFS_VALID_FS)) {
-		nilfs->ns_mount_state |= NILFS_VALID_FS;
-		err = nilfs_commit_super(sbi, 1);
-		if (likely(!err))
-			printk(KERN_INFO "NILFS: recovery complete.\n");
-	}
-	up_write(&nilfs->ns_sem);
-	return err;
-}
-
 static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
 	struct super_block *sb = dentry->d_sb;
@@ -490,7 +469,7 @@
 	struct nilfs_sb_info *sbi = NILFS_SB(sb);
 
 	if (!nilfs_test_opt(sbi, BARRIER))
-		seq_printf(seq, ",barrier=off");
+		seq_printf(seq, ",nobarrier");
 	if (nilfs_test_opt(sbi, SNAPSHOT))
 		seq_printf(seq, ",cp=%llu",
 			   (unsigned long long int)sbi->s_snapshot_cno);
@@ -500,6 +479,8 @@
 		seq_printf(seq, ",errors=panic");
 	if (nilfs_test_opt(sbi, STRICT_ORDER))
 		seq_printf(seq, ",order=strict");
+	if (nilfs_test_opt(sbi, NORECOVERY))
+		seq_printf(seq, ",norecovery");
 
 	return 0;
 }
@@ -568,7 +549,7 @@
 
 enum {
 	Opt_err_cont, Opt_err_panic, Opt_err_ro,
-	Opt_barrier, Opt_snapshot, Opt_order,
+	Opt_nobarrier, Opt_snapshot, Opt_order, Opt_norecovery,
 	Opt_err,
 };
 
@@ -576,25 +557,13 @@
 	{Opt_err_cont, "errors=continue"},
 	{Opt_err_panic, "errors=panic"},
 	{Opt_err_ro, "errors=remount-ro"},
-	{Opt_barrier, "barrier=%s"},
+	{Opt_nobarrier, "nobarrier"},
 	{Opt_snapshot, "cp=%u"},
 	{Opt_order, "order=%s"},
+	{Opt_norecovery, "norecovery"},
 	{Opt_err, NULL}
 };
 
-static int match_bool(substring_t *s, int *result)
-{
-	int len = s->to - s->from;
-
-	if (strncmp(s->from, "on", len) == 0)
-		*result = 1;
-	else if (strncmp(s->from, "off", len) == 0)
-		*result = 0;
-	else
-		return 1;
-	return 0;
-}
-
 static int parse_options(char *options, struct super_block *sb)
 {
 	struct nilfs_sb_info *sbi = NILFS_SB(sb);
@@ -612,13 +581,8 @@
 
 		token = match_token(p, tokens, args);
 		switch (token) {
-		case Opt_barrier:
-			if (match_bool(&args[0], &option))
-				return 0;
-			if (option)
-				nilfs_set_opt(sbi, BARRIER);
-			else
-				nilfs_clear_opt(sbi, BARRIER);
+		case Opt_nobarrier:
+			nilfs_clear_opt(sbi, BARRIER);
 			break;
 		case Opt_order:
 			if (strcmp(args[0].from, "relaxed") == 0)
@@ -647,6 +611,9 @@
 			sbi->s_snapshot_cno = option;
 			nilfs_set_opt(sbi, SNAPSHOT);
 			break;
+		case Opt_norecovery:
+			nilfs_set_opt(sbi, NORECOVERY);
+			break;
 		default:
 			printk(KERN_ERR
 			       "NILFS: Unrecognized mount option \"%s\"\n", p);
@@ -672,9 +639,7 @@
 	int mnt_count = le16_to_cpu(sbp->s_mnt_count);
 
 	/* nilfs->sem must be locked by the caller. */
-	if (!(nilfs->ns_mount_state & NILFS_VALID_FS)) {
-		printk(KERN_WARNING "NILFS warning: mounting unchecked fs\n");
-	} else if (nilfs->ns_mount_state & NILFS_ERROR_FS) {
+	if (nilfs->ns_mount_state & NILFS_ERROR_FS) {
 		printk(KERN_WARNING
 		       "NILFS warning: mounting fs with errors\n");
 #if 0
@@ -782,11 +747,10 @@
 	sb->s_root = NULL;
 	sb->s_time_gran = 1;
 
-	if (!nilfs_loaded(nilfs)) {
-		err = load_nilfs(nilfs, sbi);
-		if (err)
-			goto failed_sbi;
-	}
+	err = load_nilfs(nilfs, sbi);
+	if (err)
+		goto failed_sbi;
+
 	cno = nilfs_last_cno(nilfs);
 
 	if (sb->s_flags & MS_RDONLY) {
@@ -854,12 +818,6 @@
 		up_write(&nilfs->ns_sem);
 	}
 
-	err = nilfs_mark_recovery_complete(sbi);
-	if (unlikely(err)) {
-		printk(KERN_ERR "NILFS: recovery failed.\n");
-		goto failed_root;
-	}
-
 	down_write(&nilfs->ns_super_sem);
 	if (!nilfs_test_opt(sbi, SNAPSHOT))
 		nilfs->ns_current = sbi;
@@ -867,10 +825,6 @@
 
 	return 0;
 
- failed_root:
-	dput(sb->s_root);
-	sb->s_root = NULL;
-
  failed_segctor:
 	nilfs_detach_segment_constructor(sbi);
 
@@ -915,6 +869,14 @@
 		goto restore_opts;
 	}
 
+	if (!nilfs_valid_fs(nilfs)) {
+		printk(KERN_WARNING "NILFS (device %s): couldn't "
+		       "remount because the filesystem is in an "
+		       "incomplete recovery state.\n", sb->s_id);
+		err = -EINVAL;
+		goto restore_opts;
+	}
+
 	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
 		goto out;
 	if (*flags & MS_RDONLY) {
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
index ad391a8..6241e17 100644
--- a/fs/nilfs2/the_nilfs.c
+++ b/fs/nilfs2/the_nilfs.c
@@ -146,13 +146,9 @@
 
 	might_sleep();
 	if (nilfs_loaded(nilfs)) {
-		nilfs_mdt_clear(nilfs->ns_sufile);
 		nilfs_mdt_destroy(nilfs->ns_sufile);
-		nilfs_mdt_clear(nilfs->ns_cpfile);
 		nilfs_mdt_destroy(nilfs->ns_cpfile);
-		nilfs_mdt_clear(nilfs->ns_dat);
 		nilfs_mdt_destroy(nilfs->ns_dat);
-		/* XXX: how and when to clear nilfs->ns_gc_dat? */
 		nilfs_mdt_destroy(nilfs->ns_gc_dat);
 	}
 	if (nilfs_init(nilfs)) {
@@ -166,7 +162,6 @@
 static int nilfs_load_super_root(struct the_nilfs *nilfs,
 				 struct nilfs_sb_info *sbi, sector_t sr_block)
 {
-	static struct lock_class_key dat_lock_key;
 	struct buffer_head *bh_sr;
 	struct nilfs_super_root *raw_sr;
 	struct nilfs_super_block **sbp = nilfs->ns_sbp;
@@ -187,51 +182,36 @@
 	inode_size = nilfs->ns_inode_size;
 
 	err = -ENOMEM;
-	nilfs->ns_dat = nilfs_mdt_new(nilfs, NULL, NILFS_DAT_INO);
+	nilfs->ns_dat = nilfs_dat_new(nilfs, dat_entry_size);
 	if (unlikely(!nilfs->ns_dat))
 		goto failed;
 
-	nilfs->ns_gc_dat = nilfs_mdt_new(nilfs, NULL, NILFS_DAT_INO);
+	nilfs->ns_gc_dat = nilfs_dat_new(nilfs, dat_entry_size);
 	if (unlikely(!nilfs->ns_gc_dat))
 		goto failed_dat;
 
-	nilfs->ns_cpfile = nilfs_mdt_new(nilfs, NULL, NILFS_CPFILE_INO);
+	nilfs->ns_cpfile = nilfs_cpfile_new(nilfs, checkpoint_size);
 	if (unlikely(!nilfs->ns_cpfile))
 		goto failed_gc_dat;
 
-	nilfs->ns_sufile = nilfs_mdt_new(nilfs, NULL, NILFS_SUFILE_INO);
+	nilfs->ns_sufile = nilfs_sufile_new(nilfs, segment_usage_size);
 	if (unlikely(!nilfs->ns_sufile))
 		goto failed_cpfile;
 
-	err = nilfs_palloc_init_blockgroup(nilfs->ns_dat, dat_entry_size);
-	if (unlikely(err))
-		goto failed_sufile;
-
-	err = nilfs_palloc_init_blockgroup(nilfs->ns_gc_dat, dat_entry_size);
-	if (unlikely(err))
-		goto failed_sufile;
-
-	lockdep_set_class(&NILFS_MDT(nilfs->ns_dat)->mi_sem, &dat_lock_key);
-	lockdep_set_class(&NILFS_MDT(nilfs->ns_gc_dat)->mi_sem, &dat_lock_key);
-
 	nilfs_mdt_set_shadow(nilfs->ns_dat, nilfs->ns_gc_dat);
-	nilfs_mdt_set_entry_size(nilfs->ns_cpfile, checkpoint_size,
-				 sizeof(struct nilfs_cpfile_header));
-	nilfs_mdt_set_entry_size(nilfs->ns_sufile, segment_usage_size,
-				 sizeof(struct nilfs_sufile_header));
 
-	err = nilfs_mdt_read_inode_direct(
-		nilfs->ns_dat, bh_sr, NILFS_SR_DAT_OFFSET(inode_size));
+	err = nilfs_dat_read(nilfs->ns_dat, (void *)bh_sr->b_data +
+			     NILFS_SR_DAT_OFFSET(inode_size));
 	if (unlikely(err))
 		goto failed_sufile;
 
-	err = nilfs_mdt_read_inode_direct(
-		nilfs->ns_cpfile, bh_sr, NILFS_SR_CPFILE_OFFSET(inode_size));
+	err = nilfs_cpfile_read(nilfs->ns_cpfile, (void *)bh_sr->b_data +
+				NILFS_SR_CPFILE_OFFSET(inode_size));
 	if (unlikely(err))
 		goto failed_sufile;
 
-	err = nilfs_mdt_read_inode_direct(
-		nilfs->ns_sufile, bh_sr, NILFS_SR_SUFILE_OFFSET(inode_size));
+	err = nilfs_sufile_read(nilfs->ns_sufile, (void *)bh_sr->b_data +
+				NILFS_SR_SUFILE_OFFSET(inode_size));
 	if (unlikely(err))
 		goto failed_sufile;
 
@@ -281,29 +261,30 @@
 	struct nilfs_recovery_info ri;
 	unsigned int s_flags = sbi->s_super->s_flags;
 	int really_read_only = bdev_read_only(nilfs->ns_bdev);
-	unsigned valid_fs;
-	int err = 0;
+	int valid_fs = nilfs_valid_fs(nilfs);
+	int err;
+
+	if (nilfs_loaded(nilfs)) {
+		if (valid_fs ||
+		    ((s_flags & MS_RDONLY) && nilfs_test_opt(sbi, NORECOVERY)))
+			return 0;
+		printk(KERN_ERR "NILFS: the filesystem is in an incomplete "
+		       "recovery state.\n");
+		return -EINVAL;
+	}
+
+	if (!valid_fs) {
+		printk(KERN_WARNING "NILFS warning: mounting unchecked fs\n");
+		if (s_flags & MS_RDONLY) {
+			printk(KERN_INFO "NILFS: INFO: recovery "
+			       "required for readonly filesystem.\n");
+			printk(KERN_INFO "NILFS: write access will "
+			       "be enabled during recovery.\n");
+		}
+	}
 
 	nilfs_init_recovery_info(&ri);
 
-	down_write(&nilfs->ns_sem);
-	valid_fs = (nilfs->ns_mount_state & NILFS_VALID_FS);
-	up_write(&nilfs->ns_sem);
-
-	if (!valid_fs && (s_flags & MS_RDONLY)) {
-		printk(KERN_INFO "NILFS: INFO: recovery "
-		       "required for readonly filesystem.\n");
-		if (really_read_only) {
-			printk(KERN_ERR "NILFS: write access "
-			       "unavailable, cannot proceed.\n");
-			err = -EROFS;
-			goto failed;
-		}
-		printk(KERN_INFO "NILFS: write access will "
-		       "be enabled during recovery.\n");
-		sbi->s_super->s_flags &= ~MS_RDONLY;
-	}
-
 	err = nilfs_search_super_root(nilfs, sbi, &ri);
 	if (unlikely(err)) {
 		printk(KERN_ERR "NILFS: error searching super root.\n");
@@ -316,19 +297,56 @@
 		goto failed;
 	}
 
-	if (!valid_fs) {
-		err = nilfs_recover_logical_segments(nilfs, sbi, &ri);
-		if (unlikely(err)) {
-			nilfs_mdt_destroy(nilfs->ns_cpfile);
-			nilfs_mdt_destroy(nilfs->ns_sufile);
-			nilfs_mdt_destroy(nilfs->ns_dat);
-			goto failed;
+	if (valid_fs)
+		goto skip_recovery;
+
+	if (s_flags & MS_RDONLY) {
+		if (nilfs_test_opt(sbi, NORECOVERY)) {
+			printk(KERN_INFO "NILFS: norecovery option specified. "
+			       "skipping roll-forward recovery\n");
+			goto skip_recovery;
 		}
-		if (ri.ri_need_recovery == NILFS_RECOVERY_SR_UPDATED)
-			sbi->s_super->s_dirt = 1;
+		if (really_read_only) {
+			printk(KERN_ERR "NILFS: write access "
+			       "unavailable, cannot proceed.\n");
+			err = -EROFS;
+			goto failed_unload;
+		}
+		sbi->s_super->s_flags &= ~MS_RDONLY;
+	} else if (nilfs_test_opt(sbi, NORECOVERY)) {
+		printk(KERN_ERR "NILFS: recovery cancelled because norecovery "
+		       "option was specified for a read/write mount\n");
+		err = -EINVAL;
+		goto failed_unload;
 	}
 
+	err = nilfs_recover_logical_segments(nilfs, sbi, &ri);
+	if (err)
+		goto failed_unload;
+
+	down_write(&nilfs->ns_sem);
+	nilfs->ns_mount_state |= NILFS_VALID_FS;
+	nilfs->ns_sbp[0]->s_state = cpu_to_le16(nilfs->ns_mount_state);
+	err = nilfs_commit_super(sbi, 1);
+	up_write(&nilfs->ns_sem);
+
+	if (err) {
+		printk(KERN_ERR "NILFS: failed to update super block. "
+		       "recovery unfinished.\n");
+		goto failed_unload;
+	}
+	printk(KERN_INFO "NILFS: recovery complete.\n");
+
+ skip_recovery:
 	set_nilfs_loaded(nilfs);
+	nilfs_clear_recovery_info(&ri);
+	sbi->s_super->s_flags = s_flags;
+	return 0;
+
+ failed_unload:
+	nilfs_mdt_destroy(nilfs->ns_cpfile);
+	nilfs_mdt_destroy(nilfs->ns_sufile);
+	nilfs_mdt_destroy(nilfs->ns_dat);
 
  failed:
 	nilfs_clear_recovery_info(&ri);
@@ -632,30 +650,23 @@
 {
 	struct inode *dat = nilfs_dat_inode(nilfs);
 	unsigned long ncleansegs;
-	int err;
 
 	down_read(&NILFS_MDT(dat)->mi_sem);	/* XXX */
-	err = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile, &ncleansegs);
+	ncleansegs = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile);
 	up_read(&NILFS_MDT(dat)->mi_sem);	/* XXX */
-	if (likely(!err))
-		*nblocks = (sector_t)ncleansegs * nilfs->ns_blocks_per_segment;
-	return err;
+	*nblocks = (sector_t)ncleansegs * nilfs->ns_blocks_per_segment;
+	return 0;
 }
 
 int nilfs_near_disk_full(struct the_nilfs *nilfs)
 {
-	struct inode *sufile = nilfs->ns_sufile;
 	unsigned long ncleansegs, nincsegs;
-	int ret;
 
-	ret = nilfs_sufile_get_ncleansegs(sufile, &ncleansegs);
-	if (likely(!ret)) {
-		nincsegs = atomic_read(&nilfs->ns_ndirtyblks) /
-			nilfs->ns_blocks_per_segment + 1;
-		if (ncleansegs <= nilfs->ns_nrsvsegs + nincsegs)
-			ret++;
-	}
-	return ret;
+	ncleansegs = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile);
+	nincsegs = atomic_read(&nilfs->ns_ndirtyblks) /
+		nilfs->ns_blocks_per_segment + 1;
+
+	return ncleansegs <= nilfs->ns_nrsvsegs + nincsegs;
 }
 
 /**
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h
index 20abd55..589786e 100644
--- a/fs/nilfs2/the_nilfs.h
+++ b/fs/nilfs2/the_nilfs.h
@@ -258,6 +258,16 @@
 		kfree(sbi);
 }
 
+static inline int nilfs_valid_fs(struct the_nilfs *nilfs)
+{
+	unsigned valid_fs;
+
+	down_read(&nilfs->ns_sem);
+	valid_fs = (nilfs->ns_mount_state & NILFS_VALID_FS);
+	up_read(&nilfs->ns_sem);
+	return valid_fs;
+}
+
 static inline void
 nilfs_get_segment_range(struct the_nilfs *nilfs, __u64 segnum,
 			sector_t *seg_start, sector_t *seg_end)
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index 1d1d1a2..5ef5f36 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -741,10 +741,6 @@
 
 	/* create/update an inode mark */
 	ret = inotify_update_watch(group, inode, mask);
-	if (unlikely(ret))
-		goto path_put_and_out;
-
-path_put_and_out:
 	path_put(&path);
 fput_and_out:
 	fput_light(filp, fput_needed);
diff --git a/fs/ntfs/compress.c b/fs/ntfs/compress.c
index 9669541..08f7530 100644
--- a/fs/ntfs/compress.c
+++ b/fs/ntfs/compress.c
@@ -927,7 +927,7 @@
 		return 0;
 
 	ntfs_debug("Failed. Returning error code %s.", err == -EOVERFLOW ?
-			"EOVERFLOW" : (!err ? "EIO" : "unkown error"));
+			"EOVERFLOW" : (!err ? "EIO" : "unknown error"));
 	return err < 0 ? err : -EIO;
 
 read_err:
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index 663c0e3..43179dd 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -399,7 +399,7 @@
  * @cached_page: allocated but as yet unused page
  * @lru_pvec:	lru-buffering pagevec of caller
  *
- * Obtain @nr_pages locked page cache pages from the mapping @maping and
+ * Obtain @nr_pages locked page cache pages from the mapping @mapping and
  * starting at index @index.
  *
  * If a page is newly created, increment its refcount and add it to the
@@ -1281,7 +1281,7 @@
 
 /*
  * Copy as much as we can into the pages and return the number of bytes which
- * were sucessfully copied.  If a fault is encountered then clear the pages
+ * were successfully copied.  If a fault is encountered then clear the pages
  * out to (ofs + bytes) and return the number of bytes which were copied.
  */
 static inline size_t ntfs_copy_from_user(struct page **pages,
diff --git a/fs/ntfs/logfile.c b/fs/ntfs/logfile.c
index 89b0298..4dadcdf 100644
--- a/fs/ntfs/logfile.c
+++ b/fs/ntfs/logfile.c
@@ -338,7 +338,7 @@
  * copy of the complete multi sector transfer deprotected page.  On failure,
  * *@wrp is undefined.
  *
- * Simillarly, if @lsn is not NULL, on succes *@lsn will be set to the current
+ * Simillarly, if @lsn is not NULL, on success *@lsn will be set to the current
  * logfile lsn according to this restart page.  On failure, *@lsn is undefined.
  *
  * The following error codes are defined:
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 38a42f5..7c7198a 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -2398,7 +2398,7 @@
  *
  * The array is assumed to be large enough to hold an entire path (tree depth).
  *
- * Upon succesful return from this function:
+ * Upon successful return from this function:
  *
  * - The 'right_path' array will contain a path to the leaf block
  *   whose range contains e_cpos.
diff --git a/fs/ocfs2/blockcheck.c b/fs/ocfs2/blockcheck.c
index a1163b8..b7428c5 100644
--- a/fs/ocfs2/blockcheck.c
+++ b/fs/ocfs2/blockcheck.c
@@ -47,7 +47,7 @@
  * Calculate the bit offset in the hamming code buffer based on the bit's
  * offset in the data buffer.  Since the hamming code reserves all
  * power-of-two bits for parity, the data bit number and the code bit
- * number are offest by all the parity bits beforehand.
+ * number are offset by all the parity bits beforehand.
  *
  * Recall that bit numbers in hamming code are 1-based.  This function
  * takes the 0-based data bit from the caller.
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index 83bcaf2..03ccf9a 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -2586,7 +2586,7 @@
 	 * is complete everywhere.  if the target dies while this is
 	 * going on, some nodes could potentially see the target as the
 	 * master, so it is important that my recovery finds the migration
-	 * mle and sets the master to UNKNONWN. */
+	 * mle and sets the master to UNKNOWN. */
 
 
 	/* wait for new node to assert master */
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 0d38d67..c5e4a49 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -1855,7 +1855,7 @@
 		 * outstanding lock request, so a cancel convert is
 		 * required. We intentionally overwrite 'ret' - if the
 		 * cancel fails and the lock was granted, it's easier
-		 * to just bubble sucess back up to the user.
+		 * to just bubble success back up to the user.
 		 */
 		ret = ocfs2_flock_handle_signal(lockres, level);
 	} else if (!ret && (level > lockres->l_level)) {
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index de059f4..3d30a1c 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -2006,7 +2006,7 @@
 	/* buffered aio wouldn't have proper lock coverage today */
 	BUG_ON(ret == -EIOCBQUEUED && !(file->f_flags & O_DIRECT));
 
-	if ((file->f_flags & O_SYNC && !direct_io) || IS_SYNC(inode)) {
+	if ((file->f_flags & O_DSYNC && !direct_io) || IS_SYNC(inode)) {
 		ret = filemap_fdatawrite_range(file->f_mapping, pos,
 					       pos + count - 1);
 		if (ret < 0)
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index 54c16b6..bf34c49 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -659,7 +659,7 @@
 
 	default:
 		status = -EINVAL;
-		mlog(ML_ERROR, "Uknown access type!\n");
+		mlog(ML_ERROR, "Unknown access type!\n");
 	}
 	if (!status && ocfs2_meta_ecc(osb) && triggers)
 		jbd2_journal_set_triggers(bh, &triggers->ot_triggers);
diff --git a/fs/ocfs2/quota.h b/fs/ocfs2/quota.h
index e5df9d1..123bc52 100644
--- a/fs/ocfs2/quota.h
+++ b/fs/ocfs2/quota.h
@@ -17,10 +17,6 @@
 
 #include "ocfs2.h"
 
-/* Common stuff */
-/* id number of quota format */
-#define QFMT_OCFS2 3
-
 /*
  * In-memory structures
  */
diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c
index 1a2c50a..21f9e71 100644
--- a/fs/ocfs2/quota_local.c
+++ b/fs/ocfs2/quota_local.c
@@ -1325,7 +1325,7 @@
 	return status;
 }
 
-static struct quota_format_ops ocfs2_format_ops = {
+static const struct quota_format_ops ocfs2_format_ops = {
 	.check_quota_file	= ocfs2_local_check_quota_file,
 	.read_file_info		= ocfs2_local_read_info,
 	.write_file_info	= ocfs2_global_write_info,
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
index 3a0df7a..30967e3 100644
--- a/fs/ocfs2/refcounttree.c
+++ b/fs/ocfs2/refcounttree.c
@@ -2431,7 +2431,7 @@
  * we gonna touch and whether we need to create new blocks.
  *
  * Normally the refcount blocks store these refcount should be
- * continguous also, so that we can get the number easily.
+ * contiguous also, so that we can get the number easily.
  * As for meta_ac, we will at most add split 2 refcount record and
  * 2 more refcount block, so just check it in a rough way.
  *
diff --git a/fs/omfs/bitmap.c b/fs/omfs/bitmap.c
index e1c0ec0..0822345 100644
--- a/fs/omfs/bitmap.c
+++ b/fs/omfs/bitmap.c
@@ -85,7 +85,7 @@
 }
 
 /*
- * Tries to allocate exactly one block.  Returns true if sucessful.
+ * Tries to allocate exactly one block.  Returns true if successful.
  */
 int omfs_allocate_block(struct super_block *sb, u64 block)
 {
diff --git a/fs/qnx4/bitmap.c b/fs/qnx4/bitmap.c
index 0afba06..32f5d13 100644
--- a/fs/qnx4/bitmap.c
+++ b/fs/qnx4/bitmap.c
@@ -67,7 +67,7 @@
 
 	while (total < size) {
 		if ((bh = sb_bread(sb, start + offset)) == NULL) {
-			printk("qnx4: I/O error in counting free blocks\n");
+			printk(KERN_ERR "qnx4: I/O error in counting free blocks\n");
 			break;
 		}
 		count_bits(bh->b_data, size - total, &total_free);
diff --git a/fs/qnx4/dir.c b/fs/qnx4/dir.c
index 86cc39c..6f30c3d 100644
--- a/fs/qnx4/dir.c
+++ b/fs/qnx4/dir.c
@@ -26,8 +26,8 @@
 	int ix, ino;
 	int size;
 
-	QNX4DEBUG(("qnx4_readdir:i_size = %ld\n", (long) inode->i_size));
-	QNX4DEBUG(("filp->f_pos         = %ld\n", (long) filp->f_pos));
+	QNX4DEBUG((KERN_INFO "qnx4_readdir:i_size = %ld\n", (long) inode->i_size));
+	QNX4DEBUG((KERN_INFO "filp->f_pos         = %ld\n", (long) filp->f_pos));
 
 	lock_kernel();
 
@@ -50,7 +50,7 @@
 					size = QNX4_NAME_MAX;
 
 				if ( ( de->di_status & (QNX4_FILE_USED|QNX4_FILE_LINK) ) != 0 ) {
-					QNX4DEBUG(("qnx4_readdir:%.*s\n", size, de->di_fname));
+					QNX4DEBUG((KERN_INFO "qnx4_readdir:%.*s\n", size, de->di_fname));
 					if ( ( de->di_status & QNX4_FILE_LINK ) == 0 )
 						ino = blknum * QNX4_INODES_PER_BLOCK + ix - 1;
 					else {
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index d2cd179..449f5a6 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -107,7 +107,7 @@
 {
 	unsigned long phys;
 
-	QNX4DEBUG(("qnx4: qnx4_get_block inode=[%ld] iblock=[%ld]\n",inode->i_ino,iblock));
+	QNX4DEBUG((KERN_INFO "qnx4: qnx4_get_block inode=[%ld] iblock=[%ld]\n",inode->i_ino,iblock));
 
 	phys = qnx4_block_map( inode, iblock );
 	if ( phys ) {
@@ -142,12 +142,12 @@
 				// read next xtnt block.
 				bh = sb_bread(inode->i_sb, i_xblk - 1);
 				if ( !bh ) {
-					QNX4DEBUG(("qnx4: I/O error reading xtnt block [%ld])\n", i_xblk - 1));
+					QNX4DEBUG((KERN_ERR "qnx4: I/O error reading xtnt block [%ld])\n", i_xblk - 1));
 					return -EIO;
 				}
 				xblk = (struct qnx4_xblk*)bh->b_data;
 				if ( memcmp( xblk->xblk_signature, "IamXblk", 7 ) ) {
-					QNX4DEBUG(("qnx4: block at %ld is not a valid xtnt\n", qnx4_inode->i_xblk));
+					QNX4DEBUG((KERN_ERR "qnx4: block at %ld is not a valid xtnt\n", qnx4_inode->i_xblk));
 					return -EIO;
 				}
 			}
@@ -168,7 +168,7 @@
 			brelse( bh );
 	}
 
-	QNX4DEBUG(("qnx4: mapping block %ld of inode %ld = %ld\n",iblock,inode->i_ino,block));
+	QNX4DEBUG((KERN_INFO "qnx4: mapping block %ld of inode %ld = %ld\n",iblock,inode->i_ino,block));
 	return block;
 }
 
@@ -209,7 +209,7 @@
 	if (*(qnx4_sb(sb)->sb->RootDir.di_fname) != '/') {
 		return "no qnx4 filesystem (no root dir).";
 	} else {
-		QNX4DEBUG(("QNX4 filesystem found on dev %s.\n", sb->s_id));
+		QNX4DEBUG((KERN_NOTICE "QNX4 filesystem found on dev %s.\n", sb->s_id));
 		rd = le32_to_cpu(qnx4_sb(sb)->sb->RootDir.di_first_xtnt.xtnt_blk) - 1;
 		rl = le32_to_cpu(qnx4_sb(sb)->sb->RootDir.di_first_xtnt.xtnt_size);
 		for (j = 0; j < rl; j++) {
@@ -220,7 +220,7 @@
 			for (i = 0; i < QNX4_INODES_PER_BLOCK; i++) {
 				rootdir = (struct qnx4_inode_entry *) (bh->b_data + i * QNX4_DIR_ENTRY_SIZE);
 				if (rootdir->di_fname != NULL) {
-					QNX4DEBUG(("Rootdir entry found : [%s]\n", rootdir->di_fname));
+					QNX4DEBUG((KERN_INFO "rootdir entry found : [%s]\n", rootdir->di_fname));
 					if (!strncmp(rootdir->di_fname, QNX4_BMNAME, sizeof QNX4_BMNAME)) {
 						found = 1;
 						qnx4_sb(sb)->BitMap = kmalloc( sizeof( struct qnx4_inode_entry ), GFP_KERNEL );
@@ -265,12 +265,12 @@
 	   if we don't belong here... */
 	bh = sb_bread(s, 1);
 	if (!bh) {
-		printk("qnx4: unable to read the superblock\n");
+		printk(KERN_ERR "qnx4: unable to read the superblock\n");
 		goto outnobh;
 	}
 	if ( le32_to_cpup((__le32*) bh->b_data) != QNX4_SUPER_MAGIC ) {
 		if (!silent)
-			printk("qnx4: wrong fsid in superblock.\n");
+			printk(KERN_ERR "qnx4: wrong fsid in superblock.\n");
 		goto out;
 	}
 	s->s_op = &qnx4_sops;
@@ -284,14 +284,14 @@
 	errmsg = qnx4_checkroot(s);
 	if (errmsg != NULL) {
  		if (!silent)
- 			printk("qnx4: %s\n", errmsg);
+			printk(KERN_ERR "qnx4: %s\n", errmsg);
 		goto out;
 	}
 
  	/* does root not have inode number QNX4_ROOT_INO ?? */
 	root = qnx4_iget(s, QNX4_ROOT_INO * QNX4_INODES_PER_BLOCK);
 	if (IS_ERR(root)) {
- 		printk("qnx4: get inode failed\n");
+		printk(KERN_ERR "qnx4: get inode failed\n");
 		ret = PTR_ERR(root);
  		goto out;
  	}
@@ -374,7 +374,7 @@
 	qnx4_inode = qnx4_raw_inode(inode);
 	inode->i_mode = 0;
 
-	QNX4DEBUG(("Reading inode : [%d]\n", ino));
+	QNX4DEBUG((KERN_INFO "reading inode : [%d]\n", ino));
 	if (!ino) {
 		printk(KERN_ERR "qnx4: bad inode number on dev %s: %lu is "
 				"out of range\n",
@@ -385,7 +385,7 @@
 	block = ino / QNX4_INODES_PER_BLOCK;
 
 	if (!(bh = sb_bread(sb, block))) {
-		printk("qnx4: major problem: unable to read inode from dev "
+		printk(KERN_ERR "qnx4: major problem: unable to read inode from dev "
 		       "%s\n", sb->s_id);
 		iget_failed(inode);
 		return ERR_PTR(-EIO);
@@ -499,7 +499,7 @@
 		return err;
 	}
 
-	printk("QNX4 filesystem 0.2.3 registered.\n");
+	printk(KERN_INFO "QNX4 filesystem 0.2.3 registered.\n");
 	return 0;
 }
 
diff --git a/fs/qnx4/namei.c b/fs/qnx4/namei.c
index ae1e7ed..58703eb 100644
--- a/fs/qnx4/namei.c
+++ b/fs/qnx4/namei.c
@@ -30,7 +30,7 @@
 	int namelen, thislen;
 
 	if (bh == NULL) {
-		printk("qnx4: matching unassigned buffer !\n");
+		printk(KERN_WARNING "qnx4: matching unassigned buffer !\n");
 		return 0;
 	}
 	de = (struct qnx4_inode_entry *) (bh->b_data + *offset);
@@ -66,7 +66,7 @@
 
 	*res_dir = NULL;
 	if (!dir->i_sb) {
-		printk("qnx4: no superblock on dir.\n");
+		printk(KERN_WARNING "qnx4: no superblock on dir.\n");
 		return NULL;
 	}
 	bh = NULL;
@@ -124,7 +124,7 @@
 	foundinode = qnx4_iget(dir->i_sb, ino);
 	if (IS_ERR(foundinode)) {
 		unlock_kernel();
-		QNX4DEBUG(("qnx4: lookup->iget -> error %ld\n",
+		QNX4DEBUG((KERN_ERR "qnx4: lookup->iget -> error %ld\n",
 			   PTR_ERR(foundinode)));
 		return ERR_CAST(foundinode);
 	}
diff --git a/fs/quota/Kconfig b/fs/quota/Kconfig
index 353e78a..efc02eb 100644
--- a/fs/quota/Kconfig
+++ b/fs/quota/Kconfig
@@ -46,12 +46,14 @@
 	  format say Y here.
 
 config QFMT_V2
-	tristate "Quota format v2 support"
+	tristate "Quota format vfsv0 and vfsv1 support"
 	depends on QUOTA
 	select QUOTA_TREE
 	help
-	  This quota format allows using quotas with 32-bit UIDs/GIDs. If you
-	  need this functionality say Y here.
+	  This config option enables kernel support for vfsv0 and vfsv1 quota
+	  formats. Both these formats support 32-bit UIDs/GIDs and vfsv1 format
+	  also supports 64-bit inode and block quota limits. If you need this
+	  functionality say Y here.
 
 config QUOTACTL
 	bool
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index eb5a755..cd6bb9a 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -2164,7 +2164,9 @@
 	struct dentry *dentry;
 	int error;
 
+	mutex_lock(&sb->s_root->d_inode->i_mutex);
 	dentry = lookup_one_len(qf_name, sb->s_root, strlen(qf_name));
+	mutex_unlock(&sb->s_root->d_inode->i_mutex);
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 
diff --git a/fs/quota/quota_v1.c b/fs/quota/quota_v1.c
index 0edcf42..2ae757e 100644
--- a/fs/quota/quota_v1.c
+++ b/fs/quota/quota_v1.c
@@ -204,7 +204,7 @@
 	return ret;
 }
 
-static struct quota_format_ops v1_format_ops = {
+static const struct quota_format_ops v1_format_ops = {
 	.check_quota_file	= v1_check_quota_file,
 	.read_file_info		= v1_read_file_info,
 	.write_file_info	= v1_write_file_info,
diff --git a/fs/quota/quota_v2.c b/fs/quota/quota_v2.c
index a5475fb..3dfc23e 100644
--- a/fs/quota/quota_v2.c
+++ b/fs/quota/quota_v2.c
@@ -23,14 +23,23 @@
 
 #define __QUOTA_V2_PARANOIA
 
-static void v2_mem2diskdqb(void *dp, struct dquot *dquot);
-static void v2_disk2memdqb(struct dquot *dquot, void *dp);
-static int v2_is_id(void *dp, struct dquot *dquot);
+static void v2r0_mem2diskdqb(void *dp, struct dquot *dquot);
+static void v2r0_disk2memdqb(struct dquot *dquot, void *dp);
+static int v2r0_is_id(void *dp, struct dquot *dquot);
+static void v2r1_mem2diskdqb(void *dp, struct dquot *dquot);
+static void v2r1_disk2memdqb(struct dquot *dquot, void *dp);
+static int v2r1_is_id(void *dp, struct dquot *dquot);
 
-static struct qtree_fmt_operations v2_qtree_ops = {
-	.mem2disk_dqblk = v2_mem2diskdqb,
-	.disk2mem_dqblk = v2_disk2memdqb,
-	.is_id = v2_is_id,
+static struct qtree_fmt_operations v2r0_qtree_ops = {
+	.mem2disk_dqblk = v2r0_mem2diskdqb,
+	.disk2mem_dqblk = v2r0_disk2memdqb,
+	.is_id = v2r0_is_id,
+};
+
+static struct qtree_fmt_operations v2r1_qtree_ops = {
+	.mem2disk_dqblk = v2r1_mem2diskdqb,
+	.disk2mem_dqblk = v2r1_disk2memdqb,
+	.is_id = v2r1_is_id,
 };
 
 #define QUOTABLOCK_BITS 10
@@ -46,23 +55,33 @@
 	return blocks << QUOTABLOCK_BITS;
 }
 
+static int v2_read_header(struct super_block *sb, int type,
+			  struct v2_disk_dqheader *dqhead)
+{
+	ssize_t size;
+
+	size = sb->s_op->quota_read(sb, type, (char *)dqhead,
+				    sizeof(struct v2_disk_dqheader), 0);
+	if (size != sizeof(struct v2_disk_dqheader)) {
+		printk(KERN_WARNING "quota_v2: Failed header read:"
+		       " expected=%zd got=%zd\n",
+			sizeof(struct v2_disk_dqheader), size);
+		return 0;
+	}
+	return 1;
+}
+
 /* Check whether given file is really vfsv0 quotafile */
 static int v2_check_quota_file(struct super_block *sb, int type)
 {
 	struct v2_disk_dqheader dqhead;
-	ssize_t size;
 	static const uint quota_magics[] = V2_INITQMAGICS;
 	static const uint quota_versions[] = V2_INITQVERSIONS;
  
-	size = sb->s_op->quota_read(sb, type, (char *)&dqhead,
-				    sizeof(struct v2_disk_dqheader), 0);
-	if (size != sizeof(struct v2_disk_dqheader)) {
-		printk("quota_v2: failed read expected=%zd got=%zd\n",
-			sizeof(struct v2_disk_dqheader), size);
+	if (!v2_read_header(sb, type, &dqhead))
 		return 0;
-	}
 	if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type] ||
-	    le32_to_cpu(dqhead.dqh_version) != quota_versions[type])
+	    le32_to_cpu(dqhead.dqh_version) > quota_versions[type])
 		return 0;
 	return 1;
 }
@@ -71,14 +90,20 @@
 static int v2_read_file_info(struct super_block *sb, int type)
 {
 	struct v2_disk_dqinfo dinfo;
+	struct v2_disk_dqheader dqhead;
 	struct mem_dqinfo *info = sb_dqinfo(sb, type);
 	struct qtree_mem_dqinfo *qinfo;
 	ssize_t size;
+	unsigned int version;
+
+	if (!v2_read_header(sb, type, &dqhead))
+		return 0;
+	version = le32_to_cpu(dqhead.dqh_version);
 
 	size = sb->s_op->quota_read(sb, type, (char *)&dinfo,
 	       sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
 	if (size != sizeof(struct v2_disk_dqinfo)) {
-		printk(KERN_WARNING "Can't read info structure on device %s.\n",
+		printk(KERN_WARNING "quota_v2: Can't read info structure on device %s.\n",
 			sb->s_id);
 		return -1;
 	}
@@ -89,9 +114,15 @@
 		return -1;
 	}
 	qinfo = info->dqi_priv;
-	/* limits are stored as unsigned 32-bit data */
-	info->dqi_maxblimit = 0xffffffff;
-	info->dqi_maxilimit = 0xffffffff;
+	if (version == 0) {
+		/* limits are stored as unsigned 32-bit data */
+		info->dqi_maxblimit = 0xffffffff;
+		info->dqi_maxilimit = 0xffffffff;
+	} else {
+		/* used space is stored as unsigned 64-bit value */
+		info->dqi_maxblimit = 0xffffffffffffffff;	/* 2^64-1 */
+		info->dqi_maxilimit = 0xffffffffffffffff;
+	}
 	info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace);
 	info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace);
 	info->dqi_flags = le32_to_cpu(dinfo.dqi_flags);
@@ -103,8 +134,13 @@
 	qinfo->dqi_blocksize_bits = V2_DQBLKSIZE_BITS;
 	qinfo->dqi_usable_bs = 1 << V2_DQBLKSIZE_BITS;
 	qinfo->dqi_qtree_depth = qtree_depth(qinfo);
-	qinfo->dqi_entry_size = sizeof(struct v2_disk_dqblk);
-	qinfo->dqi_ops = &v2_qtree_ops;
+	if (version == 0) {
+		qinfo->dqi_entry_size = sizeof(struct v2r0_disk_dqblk);
+		qinfo->dqi_ops = &v2r0_qtree_ops;
+	} else {
+		qinfo->dqi_entry_size = sizeof(struct v2r1_disk_dqblk);
+		qinfo->dqi_ops = &v2r1_qtree_ops;
+	}
 	return 0;
 }
 
@@ -135,9 +171,9 @@
 	return 0;
 }
 
-static void v2_disk2memdqb(struct dquot *dquot, void *dp)
+static void v2r0_disk2memdqb(struct dquot *dquot, void *dp)
 {
-	struct v2_disk_dqblk *d = dp, empty;
+	struct v2r0_disk_dqblk *d = dp, empty;
 	struct mem_dqblk *m = &dquot->dq_dqb;
 
 	m->dqb_ihardlimit = le32_to_cpu(d->dqb_ihardlimit);
@@ -149,15 +185,15 @@
 	m->dqb_curspace = le64_to_cpu(d->dqb_curspace);
 	m->dqb_btime = le64_to_cpu(d->dqb_btime);
 	/* We need to escape back all-zero structure */
-	memset(&empty, 0, sizeof(struct v2_disk_dqblk));
+	memset(&empty, 0, sizeof(struct v2r0_disk_dqblk));
 	empty.dqb_itime = cpu_to_le64(1);
-	if (!memcmp(&empty, dp, sizeof(struct v2_disk_dqblk)))
+	if (!memcmp(&empty, dp, sizeof(struct v2r0_disk_dqblk)))
 		m->dqb_itime = 0;
 }
 
-static void v2_mem2diskdqb(void *dp, struct dquot *dquot)
+static void v2r0_mem2diskdqb(void *dp, struct dquot *dquot)
 {
-	struct v2_disk_dqblk *d = dp;
+	struct v2r0_disk_dqblk *d = dp;
 	struct mem_dqblk *m = &dquot->dq_dqb;
 	struct qtree_mem_dqinfo *info =
 			sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv;
@@ -175,9 +211,60 @@
 		d->dqb_itime = cpu_to_le64(1);
 }
 
-static int v2_is_id(void *dp, struct dquot *dquot)
+static int v2r0_is_id(void *dp, struct dquot *dquot)
 {
-	struct v2_disk_dqblk *d = dp;
+	struct v2r0_disk_dqblk *d = dp;
+	struct qtree_mem_dqinfo *info =
+			sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv;
+
+	if (qtree_entry_unused(info, dp))
+		return 0;
+	return le32_to_cpu(d->dqb_id) == dquot->dq_id;
+}
+
+static void v2r1_disk2memdqb(struct dquot *dquot, void *dp)
+{
+	struct v2r1_disk_dqblk *d = dp, empty;
+	struct mem_dqblk *m = &dquot->dq_dqb;
+
+	m->dqb_ihardlimit = le64_to_cpu(d->dqb_ihardlimit);
+	m->dqb_isoftlimit = le64_to_cpu(d->dqb_isoftlimit);
+	m->dqb_curinodes = le64_to_cpu(d->dqb_curinodes);
+	m->dqb_itime = le64_to_cpu(d->dqb_itime);
+	m->dqb_bhardlimit = v2_qbtos(le64_to_cpu(d->dqb_bhardlimit));
+	m->dqb_bsoftlimit = v2_qbtos(le64_to_cpu(d->dqb_bsoftlimit));
+	m->dqb_curspace = le64_to_cpu(d->dqb_curspace);
+	m->dqb_btime = le64_to_cpu(d->dqb_btime);
+	/* We need to escape back all-zero structure */
+	memset(&empty, 0, sizeof(struct v2r1_disk_dqblk));
+	empty.dqb_itime = cpu_to_le64(1);
+	if (!memcmp(&empty, dp, sizeof(struct v2r1_disk_dqblk)))
+		m->dqb_itime = 0;
+}
+
+static void v2r1_mem2diskdqb(void *dp, struct dquot *dquot)
+{
+	struct v2r1_disk_dqblk *d = dp;
+	struct mem_dqblk *m = &dquot->dq_dqb;
+	struct qtree_mem_dqinfo *info =
+			sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv;
+
+	d->dqb_ihardlimit = cpu_to_le64(m->dqb_ihardlimit);
+	d->dqb_isoftlimit = cpu_to_le64(m->dqb_isoftlimit);
+	d->dqb_curinodes = cpu_to_le64(m->dqb_curinodes);
+	d->dqb_itime = cpu_to_le64(m->dqb_itime);
+	d->dqb_bhardlimit = cpu_to_le64(v2_stoqb(m->dqb_bhardlimit));
+	d->dqb_bsoftlimit = cpu_to_le64(v2_stoqb(m->dqb_bsoftlimit));
+	d->dqb_curspace = cpu_to_le64(m->dqb_curspace);
+	d->dqb_btime = cpu_to_le64(m->dqb_btime);
+	d->dqb_id = cpu_to_le32(dquot->dq_id);
+	if (qtree_entry_unused(info, dp))
+		d->dqb_itime = cpu_to_le64(1);
+}
+
+static int v2r1_is_id(void *dp, struct dquot *dquot)
+{
+	struct v2r1_disk_dqblk *d = dp;
 	struct qtree_mem_dqinfo *info =
 			sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv;
 
@@ -207,7 +294,7 @@
 	return 0;
 }
 
-static struct quota_format_ops v2_format_ops = {
+static const struct quota_format_ops v2_format_ops = {
 	.check_quota_file	= v2_check_quota_file,
 	.read_file_info		= v2_read_file_info,
 	.write_file_info	= v2_write_file_info,
@@ -217,20 +304,32 @@
 	.release_dqblk		= v2_release_dquot,
 };
 
-static struct quota_format_type v2_quota_format = {
+static struct quota_format_type v2r0_quota_format = {
 	.qf_fmt_id	= QFMT_VFS_V0,
 	.qf_ops		= &v2_format_ops,
 	.qf_owner	= THIS_MODULE
 };
 
+static struct quota_format_type v2r1_quota_format = {
+	.qf_fmt_id	= QFMT_VFS_V1,
+	.qf_ops		= &v2_format_ops,
+	.qf_owner	= THIS_MODULE
+};
+
 static int __init init_v2_quota_format(void)
 {
-	return register_quota_format(&v2_quota_format);
+	int ret;
+
+	ret = register_quota_format(&v2r0_quota_format);
+	if (ret)
+		return ret;
+	return register_quota_format(&v2r1_quota_format);
 }
 
 static void __exit exit_v2_quota_format(void)
 {
-	unregister_quota_format(&v2_quota_format);
+	unregister_quota_format(&v2r0_quota_format);
+	unregister_quota_format(&v2r1_quota_format);
 }
 
 module_init(init_v2_quota_format);
diff --git a/fs/quota/quotaio_v2.h b/fs/quota/quotaio_v2.h
index 530fe58..f1966b4 100644
--- a/fs/quota/quotaio_v2.h
+++ b/fs/quota/quotaio_v2.h
@@ -17,8 +17,8 @@
 }
 
 #define V2_INITQVERSIONS {\
-	0,		/* USRQUOTA */\
-	0		/* GRPQUOTA */\
+	1,		/* USRQUOTA */\
+	1		/* GRPQUOTA */\
 }
 
 /* First generic header */
@@ -32,7 +32,7 @@
  * (as it appears on disk) - the file is a radix tree whose leaves point
  * to blocks of these structures.
  */
-struct v2_disk_dqblk {
+struct v2r0_disk_dqblk {
 	__le32 dqb_id;		/* id this quota applies to */
 	__le32 dqb_ihardlimit;	/* absolute limit on allocated inodes */
 	__le32 dqb_isoftlimit;	/* preferred inode limit */
@@ -44,6 +44,19 @@
 	__le64 dqb_itime;	/* time limit for excessive inode use */
 };
 
+struct v2r1_disk_dqblk {
+	__le32 dqb_id;		/* id this quota applies to */
+	__le32 dqb_pad;
+	__le64 dqb_ihardlimit;	/* absolute limit on allocated inodes */
+	__le64 dqb_isoftlimit;	/* preferred inode limit */
+	__le64 dqb_curinodes;	/* current # allocated inodes */
+	__le64 dqb_bhardlimit;	/* absolute limit on disk space (in QUOTABLOCK_SIZE) */
+	__le64 dqb_bsoftlimit;	/* preferred limit on disk space (in QUOTABLOCK_SIZE) */
+	__le64 dqb_curspace;	/* current space occupied (in bytes) */
+	__le64 dqb_btime;	/* time limit for excessive disk use */
+	__le64 dqb_itime;	/* time limit for excessive inode use */
+};
+
 /* Header with type and version specific information */
 struct v2_disk_dqinfo {
 	__le32 dqi_bgrace;	/* Time before block soft limit becomes hard limit */
diff --git a/fs/reiserfs/Makefile b/fs/reiserfs/Makefile
index 7c5ab63..6a9e30c 100644
--- a/fs/reiserfs/Makefile
+++ b/fs/reiserfs/Makefile
@@ -7,7 +7,7 @@
 reiserfs-objs := bitmap.o do_balan.o namei.o inode.o file.o dir.o fix_node.o \
 		 super.o prints.o objectid.o lbalance.o ibalance.o stree.o \
 		 hashes.o tail_conversion.o journal.o resize.o \
-		 item_ops.o ioctl.o procfs.o xattr.o
+		 item_ops.o ioctl.o procfs.o xattr.o lock.o
 
 ifeq ($(CONFIG_REISERFS_FS_XATTR),y)
 reiserfs-objs += xattr_user.o xattr_trusted.o
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c
index e716161..6854957 100644
--- a/fs/reiserfs/bitmap.c
+++ b/fs/reiserfs/bitmap.c
@@ -1249,14 +1249,18 @@
 	else if (bitmap == 0)
 		block = (REISERFS_DISK_OFFSET_IN_BYTES >> sb->s_blocksize_bits) + 1;
 
+	reiserfs_write_unlock(sb);
 	bh = sb_bread(sb, block);
+	reiserfs_write_lock(sb);
 	if (bh == NULL)
 		reiserfs_warning(sb, "sh-2029: %s: bitmap block (#%u) "
 		                 "reading failed", __func__, block);
 	else {
 		if (buffer_locked(bh)) {
 			PROC_INFO_INC(sb, scan_bitmap.wait);
+			reiserfs_write_unlock(sb);
 			__wait_on_buffer(bh);
+			reiserfs_write_lock(sb);
 		}
 		BUG_ON(!buffer_uptodate(bh));
 		BUG_ON(atomic_read(&bh->b_count) == 0);
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
index 6d2668f..c094f58 100644
--- a/fs/reiserfs/dir.c
+++ b/fs/reiserfs/dir.c
@@ -20,7 +20,7 @@
 	.read = generic_read_dir,
 	.readdir = reiserfs_readdir,
 	.fsync = reiserfs_dir_fsync,
-	.ioctl = reiserfs_ioctl,
+	.unlocked_ioctl = reiserfs_ioctl,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl = reiserfs_compat_ioctl,
 #endif
@@ -174,14 +174,22 @@
 				// user space buffer is swapped out. At that time
 				// entry can move to somewhere else
 				memcpy(local_buf, d_name, d_reclen);
+
+				/*
+				 * Since filldir might sleep, we can release
+				 * the write lock here for other waiters
+				 */
+				reiserfs_write_unlock(inode->i_sb);
 				if (filldir
 				    (dirent, local_buf, d_reclen, d_off, d_ino,
 				     DT_UNKNOWN) < 0) {
+					reiserfs_write_lock(inode->i_sb);
 					if (local_buf != small_buf) {
 						kfree(local_buf);
 					}
 					goto end;
 				}
+				reiserfs_write_lock(inode->i_sb);
 				if (local_buf != small_buf) {
 					kfree(local_buf);
 				}
diff --git a/fs/reiserfs/do_balan.c b/fs/reiserfs/do_balan.c
index 128d3f7..60c0804 100644
--- a/fs/reiserfs/do_balan.c
+++ b/fs/reiserfs/do_balan.c
@@ -21,14 +21,6 @@
 #include <linux/buffer_head.h>
 #include <linux/kernel.h>
 
-#ifdef CONFIG_REISERFS_CHECK
-
-struct tree_balance *cur_tb = NULL;	/* detects whether more than one
-					   copy of tb exists as a means
-					   of checking whether schedule
-					   is interrupting do_balance */
-#endif
-
 static inline void buffer_info_init_left(struct tree_balance *tb,
                                          struct buffer_info *bi)
 {
@@ -1840,11 +1832,12 @@
 {
 	int retval = 0;
 
-	if (cur_tb) {
+	if (REISERFS_SB(tb->tb_sb)->cur_tb) {
 		reiserfs_panic(tb->tb_sb, "vs-12335", "suspect that schedule "
 			       "occurred based on cur_tb not being null at "
 			       "this point in code. do_balance cannot properly "
-			       "handle schedule occurring while it runs.");
+			       "handle concurrent tree accesses on a same "
+			       "mount point.");
 	}
 
 	/* double check that buffers that we will modify are unlocked. (fix_nodes should already have
@@ -1986,7 +1979,7 @@
 	     "check");*/
 	RFALSE(check_before_balancing(tb), "PAP-12340: locked buffers in TB");
 #ifdef CONFIG_REISERFS_CHECK
-	cur_tb = tb;
+	REISERFS_SB(tb->tb_sb)->cur_tb = tb;
 #endif
 }
 
@@ -1996,7 +1989,7 @@
 #ifdef CONFIG_REISERFS_CHECK
 	check_leaf_level(tb);
 	check_internal_levels(tb);
-	cur_tb = NULL;
+	REISERFS_SB(tb->tb_sb)->cur_tb = NULL;
 #endif
 
 	/* reiserfs_free_block is no longer schedule safe.  So, we need to
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index 9f43666..da2dba0 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -284,7 +284,7 @@
 const struct file_operations reiserfs_file_operations = {
 	.read = do_sync_read,
 	.write = reiserfs_file_write,
-	.ioctl = reiserfs_ioctl,
+	.unlocked_ioctl = reiserfs_ioctl,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl = reiserfs_compat_ioctl,
 #endif
diff --git a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c
index 5e5a4e6..6591cb2 100644
--- a/fs/reiserfs/fix_node.c
+++ b/fs/reiserfs/fix_node.c
@@ -563,9 +563,6 @@
 	return needed_nodes;
 }
 
-#ifdef CONFIG_REISERFS_CHECK
-extern struct tree_balance *cur_tb;
-#endif
 
 /* Set parameters for balancing.
  * Performs write of results of analysis of balancing into structure tb,
@@ -834,7 +831,7 @@
 		RFALSE(buffer_dirty(new_bh) ||
 		       buffer_journaled(new_bh) ||
 		       buffer_journal_dirty(new_bh),
-		       "PAP-8140: journlaled or dirty buffer %b for the new block",
+		       "PAP-8140: journaled or dirty buffer %b for the new block",
 		       new_bh);
 
 		/* Put empty buffers into the array. */
@@ -1022,7 +1019,11 @@
 	/* Check whether the common parent is locked. */
 
 	if (buffer_locked(*pcom_father)) {
+
+		/* Release the write lock while the buffer is busy */
+		reiserfs_write_unlock(tb->tb_sb);
 		__wait_on_buffer(*pcom_father);
+		reiserfs_write_lock(tb->tb_sb);
 		if (FILESYSTEM_CHANGED_TB(tb)) {
 			brelse(*pcom_father);
 			return REPEAT_SEARCH;
@@ -1927,7 +1928,9 @@
 		return REPEAT_SEARCH;
 
 	if (buffer_locked(bh)) {
+		reiserfs_write_unlock(tb->tb_sb);
 		__wait_on_buffer(bh);
+		reiserfs_write_lock(tb->tb_sb);
 		if (FILESYSTEM_CHANGED_TB(tb))
 			return REPEAT_SEARCH;
 	}
@@ -1965,7 +1968,9 @@
 		     tb->FL[h]) ? tb->lkey[h] : B_NR_ITEMS(tb->
 								       FL[h]);
 		son_number = B_N_CHILD_NUM(tb->FL[h], child_position);
+		reiserfs_write_unlock(sb);
 		bh = sb_bread(sb, son_number);
+		reiserfs_write_lock(sb);
 		if (!bh)
 			return IO_ERROR;
 		if (FILESYSTEM_CHANGED_TB(tb)) {
@@ -2003,7 +2008,9 @@
 		child_position =
 		    (bh == tb->FR[h]) ? tb->rkey[h] + 1 : 0;
 		son_number = B_N_CHILD_NUM(tb->FR[h], child_position);
+		reiserfs_write_unlock(sb);
 		bh = sb_bread(sb, son_number);
+		reiserfs_write_lock(sb);
 		if (!bh)
 			return IO_ERROR;
 		if (FILESYSTEM_CHANGED_TB(tb)) {
@@ -2278,7 +2285,9 @@
 				    REPEAT_SEARCH : CARRY_ON;
 			}
 #endif
+			reiserfs_write_unlock(tb->tb_sb);
 			__wait_on_buffer(locked);
+			reiserfs_write_lock(tb->tb_sb);
 			if (FILESYSTEM_CHANGED_TB(tb))
 				return REPEAT_SEARCH;
 		}
@@ -2349,12 +2358,14 @@
 
 	/* if it possible in indirect_to_direct conversion */
 	if (buffer_locked(tbS0)) {
+		reiserfs_write_unlock(tb->tb_sb);
 		__wait_on_buffer(tbS0);
+		reiserfs_write_lock(tb->tb_sb);
 		if (FILESYSTEM_CHANGED_TB(tb))
 			return REPEAT_SEARCH;
 	}
 #ifdef CONFIG_REISERFS_CHECK
-	if (cur_tb) {
+	if (REISERFS_SB(tb->tb_sb)->cur_tb) {
 		print_cur_tb("fix_nodes");
 		reiserfs_panic(tb->tb_sb, "PAP-8305",
 			       "there is pending do_balance");
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index a14d6cd..3a28e77 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -251,7 +251,6 @@
 	struct cpu_key key;
 	struct buffer_head *bh;
 	struct item_head *ih, tmp_ih;
-	int fs_gen;
 	b_blocknr_t blocknr;
 	char *p = NULL;
 	int chars;
@@ -265,7 +264,6 @@
 		     (loff_t) block * inode->i_sb->s_blocksize + 1, TYPE_ANY,
 		     3);
 
-      research:
 	result = search_for_position_by_key(inode->i_sb, &key, &path);
 	if (result != POSITION_FOUND) {
 		pathrelse(&path);
@@ -340,7 +338,6 @@
 	}
 	// read file tail into part of page
 	offset = (cpu_key_k_offset(&key) - 1) & (PAGE_CACHE_SIZE - 1);
-	fs_gen = get_generation(inode->i_sb);
 	copy_item_head(&tmp_ih, ih);
 
 	/* we only want to kmap if we are reading the tail into the page.
@@ -348,13 +345,9 @@
 	 ** sure we need to.  But, this means the item might move if
 	 ** kmap schedules
 	 */
-	if (!p) {
+	if (!p)
 		p = (char *)kmap(bh_result->b_page);
-		if (fs_changed(fs_gen, inode->i_sb)
-		    && item_moved(&tmp_ih, &path)) {
-			goto research;
-		}
-	}
+
 	p += offset;
 	memset(p, 0, inode->i_sb->s_blocksize);
 	do {
@@ -489,10 +482,14 @@
 	   disappeared */
 	if (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) {
 		int err;
-		lock_kernel();
+
+		reiserfs_write_lock(inode->i_sb);
+
 		err = reiserfs_commit_for_inode(inode);
 		REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
-		unlock_kernel();
+
+		reiserfs_write_unlock(inode->i_sb);
+
 		if (err < 0)
 			ret = err;
 	}
@@ -601,6 +598,7 @@
 	__le32 *item;
 	int done;
 	int fs_gen;
+	int lock_depth;
 	struct reiserfs_transaction_handle *th = NULL;
 	/* space reserved in transaction batch:
 	   . 3 balancings in direct->indirect conversion
@@ -616,12 +614,11 @@
 	loff_t new_offset =
 	    (((loff_t) block) << inode->i_sb->s_blocksize_bits) + 1;
 
-	/* bad.... */
-	reiserfs_write_lock(inode->i_sb);
+	lock_depth = reiserfs_write_lock_once(inode->i_sb);
 	version = get_inode_item_key_version(inode);
 
 	if (!file_capable(inode, block)) {
-		reiserfs_write_unlock(inode->i_sb);
+		reiserfs_write_unlock_once(inode->i_sb, lock_depth);
 		return -EFBIG;
 	}
 
@@ -633,7 +630,7 @@
 		/* find number of block-th logical block of the file */
 		ret = _get_block_create_0(inode, block, bh_result,
 					  create | GET_BLOCK_READ_DIRECT);
-		reiserfs_write_unlock(inode->i_sb);
+		reiserfs_write_unlock_once(inode->i_sb, lock_depth);
 		return ret;
 	}
 	/*
@@ -751,7 +748,7 @@
 		if (!dangle && th)
 			retval = reiserfs_end_persistent_transaction(th);
 
-		reiserfs_write_unlock(inode->i_sb);
+		reiserfs_write_unlock_once(inode->i_sb, lock_depth);
 
 		/* the item was found, so new blocks were not added to the file
 		 ** there is no need to make sure the inode is updated with this
@@ -935,7 +932,7 @@
 			if (blocks_needed == 1) {
 				un = &unf_single;
 			} else {
-				un = kzalloc(min(blocks_needed, max_to_insert) * UNFM_P_SIZE, GFP_ATOMIC);	// We need to avoid scheduling.
+				un = kzalloc(min(blocks_needed, max_to_insert) * UNFM_P_SIZE, GFP_NOFS);
 				if (!un) {
 					un = &unf_single;
 					blocks_needed = 1;
@@ -997,10 +994,16 @@
 			if (retval)
 				goto failure;
 		}
-		/* inserting indirect pointers for a hole can take a
-		 ** long time.  reschedule if needed
+		/*
+		 * inserting indirect pointers for a hole can take a
+		 * long time.  reschedule if needed and also release the write
+		 * lock for others.
 		 */
-		cond_resched();
+		if (need_resched()) {
+			reiserfs_write_unlock_once(inode->i_sb, lock_depth);
+			schedule();
+			lock_depth = reiserfs_write_lock_once(inode->i_sb);
+		}
 
 		retval = search_for_position_by_key(inode->i_sb, &key, &path);
 		if (retval == IO_ERROR) {
@@ -1035,7 +1038,7 @@
 			retval = err;
 	}
 
-	reiserfs_write_unlock(inode->i_sb);
+	reiserfs_write_unlock_once(inode->i_sb, lock_depth);
 	reiserfs_check_path(&path);
 	return retval;
 }
@@ -2072,8 +2075,9 @@
 	int error;
 	struct buffer_head *bh = NULL;
 	int err2;
+	int lock_depth;
 
-	reiserfs_write_lock(inode->i_sb);
+	lock_depth = reiserfs_write_lock_once(inode->i_sb);
 
 	if (inode->i_size > 0) {
 		error = grab_tail_page(inode, &page, &bh);
@@ -2142,14 +2146,17 @@
 		page_cache_release(page);
 	}
 
-	reiserfs_write_unlock(inode->i_sb);
+	reiserfs_write_unlock_once(inode->i_sb, lock_depth);
+
 	return 0;
       out:
 	if (page) {
 		unlock_page(page);
 		page_cache_release(page);
 	}
-	reiserfs_write_unlock(inode->i_sb);
+
+	reiserfs_write_unlock_once(inode->i_sb, lock_depth);
+
 	return error;
 }
 
@@ -2608,7 +2615,10 @@
 	int ret;
 	int old_ref = 0;
 
+	reiserfs_write_unlock(inode->i_sb);
 	reiserfs_wait_on_write_block(inode->i_sb);
+	reiserfs_write_lock(inode->i_sb);
+
 	fix_tail_page_for_writing(page);
 	if (reiserfs_transaction_running(inode->i_sb)) {
 		struct reiserfs_transaction_handle *th;
@@ -2664,6 +2674,8 @@
 	int update_sd = 0;
 	struct reiserfs_transaction_handle *th;
 	unsigned start;
+	int lock_depth = 0;
+	bool locked = false;
 
 	if ((unsigned long)fsdata & AOP_FLAG_CONT_EXPAND)
 		pos ++;
@@ -2690,9 +2702,11 @@
 	 ** to do the i_size updates here.
 	 */
 	pos += copied;
+
 	if (pos > inode->i_size) {
 		struct reiserfs_transaction_handle myth;
-		reiserfs_write_lock(inode->i_sb);
+		lock_depth = reiserfs_write_lock_once(inode->i_sb);
+		locked = true;
 		/* If the file have grown beyond the border where it
 		   can have a tail, unmark it as needing a tail
 		   packing */
@@ -2703,10 +2717,9 @@
 			REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
 
 		ret = journal_begin(&myth, inode->i_sb, 1);
-		if (ret) {
-			reiserfs_write_unlock(inode->i_sb);
+		if (ret)
 			goto journal_error;
-		}
+
 		reiserfs_update_inode_transaction(inode);
 		inode->i_size = pos;
 		/*
@@ -2718,34 +2731,36 @@
 		reiserfs_update_sd(&myth, inode);
 		update_sd = 1;
 		ret = journal_end(&myth, inode->i_sb, 1);
-		reiserfs_write_unlock(inode->i_sb);
 		if (ret)
 			goto journal_error;
 	}
 	if (th) {
-		reiserfs_write_lock(inode->i_sb);
+		if (!locked) {
+			lock_depth = reiserfs_write_lock_once(inode->i_sb);
+			locked = true;
+		}
 		if (!update_sd)
 			mark_inode_dirty(inode);
 		ret = reiserfs_end_persistent_transaction(th);
-		reiserfs_write_unlock(inode->i_sb);
 		if (ret)
 			goto out;
 	}
 
       out:
+	if (locked)
+		reiserfs_write_unlock_once(inode->i_sb, lock_depth);
 	unlock_page(page);
 	page_cache_release(page);
 	return ret == 0 ? copied : ret;
 
       journal_error:
+	reiserfs_write_unlock_once(inode->i_sb, lock_depth);
+	locked = false;
 	if (th) {
-		reiserfs_write_lock(inode->i_sb);
 		if (!update_sd)
 			reiserfs_update_sd(th, inode);
 		ret = reiserfs_end_persistent_transaction(th);
-		reiserfs_write_unlock(inode->i_sb);
 	}
-
 	goto out;
 }
 
@@ -2758,7 +2773,10 @@
 	int update_sd = 0;
 	struct reiserfs_transaction_handle *th = NULL;
 
+	reiserfs_write_unlock(inode->i_sb);
 	reiserfs_wait_on_write_block(inode->i_sb);
+	reiserfs_write_lock(inode->i_sb);
+
 	if (reiserfs_transaction_running(inode->i_sb)) {
 		th = current->journal_info;
 	}
@@ -2770,7 +2788,6 @@
 	 */
 	if (pos > inode->i_size) {
 		struct reiserfs_transaction_handle myth;
-		reiserfs_write_lock(inode->i_sb);
 		/* If the file have grown beyond the border where it
 		   can have a tail, unmark it as needing a tail
 		   packing */
@@ -2781,10 +2798,9 @@
 			REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
 
 		ret = journal_begin(&myth, inode->i_sb, 1);
-		if (ret) {
-			reiserfs_write_unlock(inode->i_sb);
+		if (ret)
 			goto journal_error;
-		}
+
 		reiserfs_update_inode_transaction(inode);
 		inode->i_size = pos;
 		/*
@@ -2796,16 +2812,13 @@
 		reiserfs_update_sd(&myth, inode);
 		update_sd = 1;
 		ret = journal_end(&myth, inode->i_sb, 1);
-		reiserfs_write_unlock(inode->i_sb);
 		if (ret)
 			goto journal_error;
 	}
 	if (th) {
-		reiserfs_write_lock(inode->i_sb);
 		if (!update_sd)
 			mark_inode_dirty(inode);
 		ret = reiserfs_end_persistent_transaction(th);
-		reiserfs_write_unlock(inode->i_sb);
 		if (ret)
 			goto out;
 	}
@@ -2815,11 +2828,9 @@
 
       journal_error:
 	if (th) {
-		reiserfs_write_lock(inode->i_sb);
 		if (!update_sd)
 			reiserfs_update_sd(th, inode);
 		ret = reiserfs_end_persistent_transaction(th);
-		reiserfs_write_unlock(inode->i_sb);
 	}
 
 	return ret;
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c
index 0ccc3fd..ace7745 100644
--- a/fs/reiserfs/ioctl.c
+++ b/fs/reiserfs/ioctl.c
@@ -13,44 +13,52 @@
 #include <linux/compat.h>
 
 /*
-** reiserfs_ioctl - handler for ioctl for inode
-** supported commands:
-**  1) REISERFS_IOC_UNPACK - try to unpack tail from direct item into indirect
-**                           and prevent packing file (argument arg has to be non-zero)
-**  2) REISERFS_IOC_[GS]ETFLAGS, REISERFS_IOC_[GS]ETVERSION
-**  3) That's all for a while ...
-*/
-int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
-		   unsigned long arg)
+ * reiserfs_ioctl - handler for ioctl for inode
+ * supported commands:
+ *  1) REISERFS_IOC_UNPACK - try to unpack tail from direct item into indirect
+ *                           and prevent packing file (argument arg has to be non-zero)
+ *  2) REISERFS_IOC_[GS]ETFLAGS, REISERFS_IOC_[GS]ETVERSION
+ *  3) That's all for a while ...
+ */
+long reiserfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
+	struct inode *inode = filp->f_path.dentry->d_inode;
 	unsigned int flags;
 	int err = 0;
 
+	reiserfs_write_lock(inode->i_sb);
+
 	switch (cmd) {
 	case REISERFS_IOC_UNPACK:
 		if (S_ISREG(inode->i_mode)) {
 			if (arg)
-				return reiserfs_unpack(inode, filp);
-			else
-				return 0;
+				err = reiserfs_unpack(inode, filp);
 		} else
-			return -ENOTTY;
-		/* following two cases are taken from fs/ext2/ioctl.c by Remy
-		   Card (card@masi.ibp.fr) */
+			err = -ENOTTY;
+		break;
+		/*
+		 * following two cases are taken from fs/ext2/ioctl.c by Remy
+		 * Card (card@masi.ibp.fr)
+		 */
 	case REISERFS_IOC_GETFLAGS:
-		if (!reiserfs_attrs(inode->i_sb))
-			return -ENOTTY;
+		if (!reiserfs_attrs(inode->i_sb)) {
+			err = -ENOTTY;
+			break;
+		}
 
 		flags = REISERFS_I(inode)->i_attrs;
 		i_attrs_to_sd_attrs(inode, (__u16 *) & flags);
-		return put_user(flags, (int __user *)arg);
+		err = put_user(flags, (int __user *)arg);
+		break;
 	case REISERFS_IOC_SETFLAGS:{
-			if (!reiserfs_attrs(inode->i_sb))
-				return -ENOTTY;
+			if (!reiserfs_attrs(inode->i_sb)) {
+				err = -ENOTTY;
+				break;
+			}
 
 			err = mnt_want_write(filp->f_path.mnt);
 			if (err)
-				return err;
+				break;
 
 			if (!is_owner_or_cap(inode)) {
 				err = -EPERM;
@@ -90,16 +98,18 @@
 			mark_inode_dirty(inode);
 setflags_out:
 			mnt_drop_write(filp->f_path.mnt);
-			return err;
+			break;
 		}
 	case REISERFS_IOC_GETVERSION:
-		return put_user(inode->i_generation, (int __user *)arg);
+		err = put_user(inode->i_generation, (int __user *)arg);
+		break;
 	case REISERFS_IOC_SETVERSION:
 		if (!is_owner_or_cap(inode))
-			return -EPERM;
+			err = -EPERM;
+			break;
 		err = mnt_want_write(filp->f_path.mnt);
 		if (err)
-			return err;
+			break;
 		if (get_user(inode->i_generation, (int __user *)arg)) {
 			err = -EFAULT;
 			goto setversion_out;
@@ -108,19 +118,20 @@
 		mark_inode_dirty(inode);
 setversion_out:
 		mnt_drop_write(filp->f_path.mnt);
-		return err;
+		break;
 	default:
-		return -ENOTTY;
+		err = -ENOTTY;
 	}
+
+	reiserfs_write_unlock(inode->i_sb);
+
+	return err;
 }
 
 #ifdef CONFIG_COMPAT
 long reiserfs_compat_ioctl(struct file *file, unsigned int cmd,
 				unsigned long arg)
 {
-	struct inode *inode = file->f_path.dentry->d_inode;
-	int ret;
-
 	/* These are just misnamed, they actually get/put from/to user an int */
 	switch (cmd) {
 	case REISERFS_IOC32_UNPACK:
@@ -141,10 +152,8 @@
 	default:
 		return -ENOIOCTLCMD;
 	}
-	lock_kernel();
-	ret = reiserfs_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg));
-	unlock_kernel();
-	return ret;
+
+	return reiserfs_ioctl(file, cmd, (unsigned long) compat_ptr(arg));
 }
 #endif
 
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index 9062220..2f8a7e7 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -429,21 +429,6 @@
 	clear_buffer_journal_restore_dirty(bh);
 }
 
-/* utility function to force a BUG if it is called without the big
-** kernel lock held.  caller is the string printed just before calling BUG()
-*/
-void reiserfs_check_lock_depth(struct super_block *sb, char *caller)
-{
-#ifdef CONFIG_SMP
-	if (current->lock_depth < 0) {
-		reiserfs_panic(sb, "journal-1", "%s called without kernel "
-			       "lock held", caller);
-	}
-#else
-	;
-#endif
-}
-
 /* return a cnode with same dev, block number and size in table, or null if not found */
 static inline struct reiserfs_journal_cnode *get_journal_hash_dev(struct
 								  super_block
@@ -556,7 +541,8 @@
 static inline void lock_journal(struct super_block *sb)
 {
 	PROC_INFO_INC(sb, journal.lock_journal);
-	mutex_lock(&SB_JOURNAL(sb)->j_mutex);
+
+	reiserfs_mutex_lock_safe(&SB_JOURNAL(sb)->j_mutex, sb);
 }
 
 /* unlock the current transaction */
@@ -708,7 +694,9 @@
 		disable_barrier(s);
 		set_buffer_uptodate(bh);
 		set_buffer_dirty(bh);
+		reiserfs_write_unlock(s);
 		sync_dirty_buffer(bh);
+		reiserfs_write_lock(s);
 	}
 }
 
@@ -996,8 +984,13 @@
 {
 	DEFINE_WAIT(wait);
 	struct reiserfs_journal *j = SB_JOURNAL(s);
-	if (atomic_read(&j->j_async_throttle))
+
+	if (atomic_read(&j->j_async_throttle)) {
+		reiserfs_write_unlock(s);
 		congestion_wait(BLK_RW_ASYNC, HZ / 10);
+		reiserfs_write_lock(s);
+	}
+
 	return 0;
 }
 
@@ -1043,7 +1036,8 @@
 	}
 
 	/* make sure nobody is trying to flush this one at the same time */
-	mutex_lock(&jl->j_commit_mutex);
+	reiserfs_mutex_lock_safe(&jl->j_commit_mutex, s);
+
 	if (!journal_list_still_alive(s, trans_id)) {
 		mutex_unlock(&jl->j_commit_mutex);
 		goto put_jl;
@@ -1061,12 +1055,17 @@
 
 	if (!list_empty(&jl->j_bh_list)) {
 		int ret;
-		unlock_kernel();
+
+		/*
+		 * We might sleep in numerous places inside
+		 * write_ordered_buffers. Relax the write lock.
+		 */
+		reiserfs_write_unlock(s);
 		ret = write_ordered_buffers(&journal->j_dirty_buffers_lock,
 					    journal, jl, &jl->j_bh_list);
 		if (ret < 0 && retval == 0)
 			retval = ret;
-		lock_kernel();
+		reiserfs_write_lock(s);
 	}
 	BUG_ON(!list_empty(&jl->j_bh_list));
 	/*
@@ -1085,8 +1084,11 @@
 		    SB_ONDISK_JOURNAL_SIZE(s);
 		tbh = journal_find_get_block(s, bn);
 		if (tbh) {
-			if (buffer_dirty(tbh))
-			    ll_rw_block(WRITE, 1, &tbh) ;
+			if (buffer_dirty(tbh)) {
+		            reiserfs_write_unlock(s);
+			    ll_rw_block(WRITE, 1, &tbh);
+			    reiserfs_write_lock(s);
+			}
 			put_bh(tbh) ;
 		}
 	}
@@ -1114,12 +1116,19 @@
 		bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) +
 		    (jl->j_start + i) % SB_ONDISK_JOURNAL_SIZE(s);
 		tbh = journal_find_get_block(s, bn);
+
+		reiserfs_write_unlock(s);
 		wait_on_buffer(tbh);
+		reiserfs_write_lock(s);
 		// since we're using ll_rw_blk above, it might have skipped over
 		// a locked buffer.  Double check here
 		//
-		if (buffer_dirty(tbh))	/* redundant, sync_dirty_buffer() checks */
+		/* redundant, sync_dirty_buffer() checks */
+		if (buffer_dirty(tbh)) {
+			reiserfs_write_unlock(s);
 			sync_dirty_buffer(tbh);
+			reiserfs_write_lock(s);
+		}
 		if (unlikely(!buffer_uptodate(tbh))) {
 #ifdef CONFIG_REISERFS_CHECK
 			reiserfs_warning(s, "journal-601",
@@ -1143,10 +1152,15 @@
 			if (buffer_dirty(jl->j_commit_bh))
 				BUG();
 			mark_buffer_dirty(jl->j_commit_bh) ;
+			reiserfs_write_unlock(s);
 			sync_dirty_buffer(jl->j_commit_bh) ;
+			reiserfs_write_lock(s);
 		}
-	} else
+	} else {
+		reiserfs_write_unlock(s);
 		wait_on_buffer(jl->j_commit_bh);
+		reiserfs_write_lock(s);
+	}
 
 	check_barrier_completion(s, jl->j_commit_bh);
 
@@ -1286,7 +1300,9 @@
 
 	if (trans_id >= journal->j_last_flush_trans_id) {
 		if (buffer_locked((journal->j_header_bh))) {
+			reiserfs_write_unlock(sb);
 			wait_on_buffer((journal->j_header_bh));
+			reiserfs_write_lock(sb);
 			if (unlikely(!buffer_uptodate(journal->j_header_bh))) {
 #ifdef CONFIG_REISERFS_CHECK
 				reiserfs_warning(sb, "journal-699",
@@ -1312,12 +1328,16 @@
 				disable_barrier(sb);
 				goto sync;
 			}
+			reiserfs_write_unlock(sb);
 			wait_on_buffer(journal->j_header_bh);
+			reiserfs_write_lock(sb);
 			check_barrier_completion(sb, journal->j_header_bh);
 		} else {
 		      sync:
 			set_buffer_dirty(journal->j_header_bh);
+			reiserfs_write_unlock(sb);
 			sync_dirty_buffer(journal->j_header_bh);
+			reiserfs_write_lock(sb);
 		}
 		if (!buffer_uptodate(journal->j_header_bh)) {
 			reiserfs_warning(sb, "journal-837",
@@ -1409,7 +1429,7 @@
 
 	/* if flushall == 0, the lock is already held */
 	if (flushall) {
-		mutex_lock(&journal->j_flush_mutex);
+		reiserfs_mutex_lock_safe(&journal->j_flush_mutex, s);
 	} else if (mutex_trylock(&journal->j_flush_mutex)) {
 		BUG();
 	}
@@ -1553,7 +1573,11 @@
 					reiserfs_panic(s, "journal-1011",
 						       "cn->bh is NULL");
 				}
+
+				reiserfs_write_unlock(s);
 				wait_on_buffer(cn->bh);
+				reiserfs_write_lock(s);
+
 				if (!cn->bh) {
 					reiserfs_panic(s, "journal-1012",
 						       "cn->bh is NULL");
@@ -1769,7 +1793,7 @@
 	struct reiserfs_journal *journal = SB_JOURNAL(s);
 	chunk.nr = 0;
 
-	mutex_lock(&journal->j_flush_mutex);
+	reiserfs_mutex_lock_safe(&journal->j_flush_mutex, s);
 	if (!journal_list_still_alive(s, orig_trans_id)) {
 		goto done;
 	}
@@ -1973,11 +1997,19 @@
 	reiserfs_mounted_fs_count--;
 	/* wait for all commits to finish */
 	cancel_delayed_work(&SB_JOURNAL(sb)->j_work);
+
+	/*
+	 * We must release the write lock here because
+	 * the workqueue job (flush_async_commit) needs this lock
+	 */
+	reiserfs_write_unlock(sb);
 	flush_workqueue(commit_wq);
+
 	if (!reiserfs_mounted_fs_count) {
 		destroy_workqueue(commit_wq);
 		commit_wq = NULL;
 	}
+	reiserfs_write_lock(sb);
 
 	free_journal_ram(sb);
 
@@ -2243,7 +2275,11 @@
 	/* read in the log blocks, memcpy to the corresponding real block */
 	ll_rw_block(READ, get_desc_trans_len(desc), log_blocks);
 	for (i = 0; i < get_desc_trans_len(desc); i++) {
+
+		reiserfs_write_unlock(sb);
 		wait_on_buffer(log_blocks[i]);
+		reiserfs_write_lock(sb);
+
 		if (!buffer_uptodate(log_blocks[i])) {
 			reiserfs_warning(sb, "journal-1212",
 					 "REPLAY FAILURE fsck required! "
@@ -2765,11 +2801,27 @@
 		goto free_and_return;
 	}
 
+	/*
+	 * We need to unlock here to avoid creating the following
+	 * dependency:
+	 * reiserfs_lock -> sysfs_mutex
+	 * Because the reiserfs mmap path creates the following dependency:
+	 * mm->mmap -> reiserfs_lock, hence we have
+	 * mm->mmap -> reiserfs_lock ->sysfs_mutex
+	 * This would ends up in a circular dependency with sysfs readdir path
+	 * which does sysfs_mutex -> mm->mmap_sem
+	 * This is fine because the reiserfs lock is useless in mount path,
+	 * at least until we call journal_begin. We keep it for paranoid
+	 * reasons.
+	 */
+	reiserfs_write_unlock(sb);
 	if (journal_init_dev(sb, journal, j_dev_name) != 0) {
+		reiserfs_write_lock(sb);
 		reiserfs_warning(sb, "sh-462",
 				 "unable to initialize jornal device");
 		goto free_and_return;
 	}
+	reiserfs_write_lock(sb);
 
 	rs = SB_DISK_SUPER_BLOCK(sb);
 
@@ -2881,8 +2933,11 @@
 	}
 
 	reiserfs_mounted_fs_count++;
-	if (reiserfs_mounted_fs_count <= 1)
+	if (reiserfs_mounted_fs_count <= 1) {
+		reiserfs_write_unlock(sb);
 		commit_wq = create_workqueue("reiserfs");
+		reiserfs_write_lock(sb);
+	}
 
 	INIT_DELAYED_WORK(&journal->j_work, flush_async_commits);
 	journal->j_work_sb = sb;
@@ -2964,8 +3019,11 @@
 	init_waitqueue_entry(&wait, current);
 	add_wait_queue(&journal->j_join_wait, &wait);
 	set_current_state(TASK_UNINTERRUPTIBLE);
-	if (test_bit(J_WRITERS_QUEUED, &journal->j_state))
+	if (test_bit(J_WRITERS_QUEUED, &journal->j_state)) {
+		reiserfs_write_unlock(s);
 		schedule();
+		reiserfs_write_lock(s);
+	}
 	__set_current_state(TASK_RUNNING);
 	remove_wait_queue(&journal->j_join_wait, &wait);
 }
@@ -2982,7 +3040,9 @@
 	struct reiserfs_journal *journal = SB_JOURNAL(sb);
 	unsigned long bcount = journal->j_bcount;
 	while (1) {
+		reiserfs_write_unlock(sb);
 		schedule_timeout_uninterruptible(1);
+		reiserfs_write_lock(sb);
 		journal->j_current_jl->j_state |= LIST_COMMIT_PENDING;
 		while ((atomic_read(&journal->j_wcount) > 0 ||
 			atomic_read(&journal->j_jlock)) &&
@@ -3033,7 +3093,9 @@
 
 	if (test_bit(J_WRITERS_BLOCKED, &journal->j_state)) {
 		unlock_journal(sb);
+		reiserfs_write_unlock(sb);
 		reiserfs_wait_on_write_block(sb);
+		reiserfs_write_lock(sb);
 		PROC_INFO_INC(sb, journal.journal_relock_writers);
 		goto relock;
 	}
@@ -3506,14 +3568,14 @@
 	struct reiserfs_journal_list *jl;
 	struct list_head *entry;
 
-	lock_kernel();
+	reiserfs_write_lock(sb);
 	if (!list_empty(&journal->j_journal_list)) {
 		/* last entry is the youngest, commit it and you get everything */
 		entry = journal->j_journal_list.prev;
 		jl = JOURNAL_LIST_ENTRY(entry);
 		flush_commit_list(sb, jl, 1);
 	}
-	unlock_kernel();
+	reiserfs_write_unlock(sb);
 }
 
 /*
@@ -4041,7 +4103,7 @@
 	 * the new transaction is fully setup, and we've already flushed the
 	 * ordered bh list
 	 */
-	mutex_lock(&jl->j_commit_mutex);
+	reiserfs_mutex_lock_safe(&jl->j_commit_mutex, sb);
 
 	/* save the transaction id in case we need to commit it later */
 	commit_trans_id = jl->j_trans_id;
@@ -4156,7 +4218,9 @@
 		next = cn->next;
 		free_cnode(sb, cn);
 		cn = next;
+		reiserfs_write_unlock(sb);
 		cond_resched();
+		reiserfs_write_lock(sb);
 	}
 
 	/* we are done  with both the c_bh and d_bh, but
@@ -4203,10 +4267,10 @@
 	 * is lost.
 	 */
 	if (!list_empty(&jl->j_tail_bh_list)) {
-		unlock_kernel();
+		reiserfs_write_unlock(sb);
 		write_ordered_buffers(&journal->j_dirty_buffers_lock,
 				      journal, jl, &jl->j_tail_bh_list);
-		lock_kernel();
+		reiserfs_write_lock(sb);
 	}
 	BUG_ON(!list_empty(&jl->j_tail_bh_list));
 	mutex_unlock(&jl->j_commit_mutex);
diff --git a/fs/reiserfs/lock.c b/fs/reiserfs/lock.c
new file mode 100644
index 0000000..ee2cfc0
--- /dev/null
+++ b/fs/reiserfs/lock.c
@@ -0,0 +1,88 @@
+#include <linux/reiserfs_fs.h>
+#include <linux/mutex.h>
+
+/*
+ * The previous reiserfs locking scheme was heavily based on
+ * the tricky properties of the Bkl:
+ *
+ * - it was acquired recursively by a same task
+ * - the performances relied on the release-while-schedule() property
+ *
+ * Now that we replace it by a mutex, we still want to keep the same
+ * recursive property to avoid big changes in the code structure.
+ * We use our own lock_owner here because the owner field on a mutex
+ * is only available in SMP or mutex debugging, also we only need this field
+ * for this mutex, no need for a system wide mutex facility.
+ *
+ * Also this lock is often released before a call that could block because
+ * reiserfs performances were partialy based on the release while schedule()
+ * property of the Bkl.
+ */
+void reiserfs_write_lock(struct super_block *s)
+{
+	struct reiserfs_sb_info *sb_i = REISERFS_SB(s);
+
+	if (sb_i->lock_owner != current) {
+		mutex_lock(&sb_i->lock);
+		sb_i->lock_owner = current;
+	}
+
+	/* No need to protect it, only the current task touches it */
+	sb_i->lock_depth++;
+}
+
+void reiserfs_write_unlock(struct super_block *s)
+{
+	struct reiserfs_sb_info *sb_i = REISERFS_SB(s);
+
+	/*
+	 * Are we unlocking without even holding the lock?
+	 * Such a situation must raise a BUG() if we don't want
+	 * to corrupt the data.
+	 */
+	BUG_ON(sb_i->lock_owner != current);
+
+	if (--sb_i->lock_depth == -1) {
+		sb_i->lock_owner = NULL;
+		mutex_unlock(&sb_i->lock);
+	}
+}
+
+/*
+ * If we already own the lock, just exit and don't increase the depth.
+ * Useful when we don't want to lock more than once.
+ *
+ * We always return the lock_depth we had before calling
+ * this function.
+ */
+int reiserfs_write_lock_once(struct super_block *s)
+{
+	struct reiserfs_sb_info *sb_i = REISERFS_SB(s);
+
+	if (sb_i->lock_owner != current) {
+		mutex_lock(&sb_i->lock);
+		sb_i->lock_owner = current;
+		return sb_i->lock_depth++;
+	}
+
+	return sb_i->lock_depth;
+}
+
+void reiserfs_write_unlock_once(struct super_block *s, int lock_depth)
+{
+	if (lock_depth == -1)
+		reiserfs_write_unlock(s);
+}
+
+/*
+ * Utility function to force a BUG if it is called without the superblock
+ * write lock held.  caller is the string printed just before calling BUG()
+ */
+void reiserfs_check_lock_depth(struct super_block *sb, char *caller)
+{
+	struct reiserfs_sb_info *sb_i = REISERFS_SB(sb);
+
+	if (sb_i->lock_depth < 0)
+		reiserfs_panic(sb, "%s called without kernel lock held %d",
+			       caller);
+}
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index 2715791..e296ff7 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -324,6 +324,7 @@
 				      struct nameidata *nd)
 {
 	int retval;
+	int lock_depth;
 	struct inode *inode = NULL;
 	struct reiserfs_dir_entry de;
 	INITIALIZE_PATH(path_to_entry);
@@ -331,7 +332,13 @@
 	if (REISERFS_MAX_NAME(dir->i_sb->s_blocksize) < dentry->d_name.len)
 		return ERR_PTR(-ENAMETOOLONG);
 
-	reiserfs_write_lock(dir->i_sb);
+	/*
+	 * Might be called with or without the write lock, must be careful
+	 * to not recursively hold it in case we want to release the lock
+	 * before rescheduling.
+	 */
+	lock_depth = reiserfs_write_lock_once(dir->i_sb);
+
 	de.de_gen_number_bit_string = NULL;
 	retval =
 	    reiserfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len,
@@ -341,7 +348,7 @@
 		inode = reiserfs_iget(dir->i_sb,
 				      (struct cpu_key *)&(de.de_dir_id));
 		if (!inode || IS_ERR(inode)) {
-			reiserfs_write_unlock(dir->i_sb);
+			reiserfs_write_unlock_once(dir->i_sb, lock_depth);
 			return ERR_PTR(-EACCES);
 		}
 
@@ -350,7 +357,7 @@
 		if (IS_PRIVATE(dir))
 			inode->i_flags |= S_PRIVATE;
 	}
-	reiserfs_write_unlock(dir->i_sb);
+	reiserfs_write_unlock_once(dir->i_sb, lock_depth);
 	if (retval == IO_ERROR) {
 		return ERR_PTR(-EIO);
 	}
@@ -725,6 +732,7 @@
 	struct inode *inode;
 	struct reiserfs_transaction_handle th;
 	struct reiserfs_security_handle security;
+	int lock_depth;
 	/* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */
 	int jbegin_count =
 	    JOURNAL_PER_BALANCE_CNT * 3 +
@@ -748,7 +756,7 @@
 		return retval;
 	}
 	jbegin_count += retval;
-	reiserfs_write_lock(dir->i_sb);
+	lock_depth = reiserfs_write_lock_once(dir->i_sb);
 
 	retval = journal_begin(&th, dir->i_sb, jbegin_count);
 	if (retval) {
@@ -798,8 +806,8 @@
 	d_instantiate(dentry, inode);
 	unlock_new_inode(inode);
 	retval = journal_end(&th, dir->i_sb, jbegin_count);
-      out_failed:
-	reiserfs_write_unlock(dir->i_sb);
+out_failed:
+	reiserfs_write_unlock_once(dir->i_sb, lock_depth);
 	return retval;
 }
 
diff --git a/fs/reiserfs/prints.c b/fs/reiserfs/prints.c
index 536eaca..adbc6f5 100644
--- a/fs/reiserfs/prints.c
+++ b/fs/reiserfs/prints.c
@@ -349,10 +349,6 @@
 
    .  */
 
-#ifdef CONFIG_REISERFS_CHECK
-extern struct tree_balance *cur_tb;
-#endif
-
 void __reiserfs_panic(struct super_block *sb, const char *id,
 		      const char *function, const char *fmt, ...)
 {
diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c
index 18b315d..b3a94d2 100644
--- a/fs/reiserfs/resize.c
+++ b/fs/reiserfs/resize.c
@@ -141,7 +141,9 @@
 
 			set_buffer_uptodate(bh);
 			mark_buffer_dirty(bh);
+			reiserfs_write_unlock(s);
 			sync_dirty_buffer(bh);
+			reiserfs_write_lock(s);
 			// update bitmap_info stuff
 			bitmap[i].free_count = sb_blocksize(sb) * 8 - 1;
 			brelse(bh);
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
index d036ee5..5fa7118 100644
--- a/fs/reiserfs/stree.c
+++ b/fs/reiserfs/stree.c
@@ -222,9 +222,6 @@
 	return ITEM_NOT_FOUND;
 }
 
-#ifdef CONFIG_REISERFS_CHECK
-extern struct tree_balance *cur_tb;
-#endif
 
 /* Minimal possible key. It is never in the tree. */
 const struct reiserfs_key MIN_KEY = { 0, 0, {{0, 0},} };
@@ -519,25 +516,48 @@
 
 #define SEARCH_BY_KEY_READA 16
 
-/* The function is NOT SCHEDULE-SAFE! */
-static void search_by_key_reada(struct super_block *s,
+/*
+ * The function is NOT SCHEDULE-SAFE!
+ * It might unlock the write lock if we needed to wait for a block
+ * to be read. Note that in this case it won't recover the lock to avoid
+ * high contention resulting from too much lock requests, especially
+ * the caller (search_by_key) will perform other schedule-unsafe
+ * operations just after calling this function.
+ *
+ * @return true if we have unlocked
+ */
+static bool search_by_key_reada(struct super_block *s,
 				struct buffer_head **bh,
 				b_blocknr_t *b, int num)
 {
 	int i, j;
+	bool unlocked = false;
 
 	for (i = 0; i < num; i++) {
 		bh[i] = sb_getblk(s, b[i]);
 	}
+	/*
+	 * We are going to read some blocks on which we
+	 * have a reference. It's safe, though we might be
+	 * reading blocks concurrently changed if we release
+	 * the lock. But it's still fine because we check later
+	 * if the tree changed
+	 */
 	for (j = 0; j < i; j++) {
 		/*
 		 * note, this needs attention if we are getting rid of the BKL
 		 * you have to make sure the prepared bit isn't set on this buffer
 		 */
-		if (!buffer_uptodate(bh[j]))
+		if (!buffer_uptodate(bh[j])) {
+			if (!unlocked) {
+				reiserfs_write_unlock(s);
+				unlocked = true;
+			}
 			ll_rw_block(READA, 1, bh + j);
+		}
 		brelse(bh[j]);
 	}
+	return unlocked;
 }
 
 /**************************************************************************
@@ -625,11 +645,26 @@
 		   have a pointer to it. */
 		if ((bh = last_element->pe_buffer =
 		     sb_getblk(sb, block_number))) {
+			bool unlocked = false;
+
 			if (!buffer_uptodate(bh) && reada_count > 1)
-				search_by_key_reada(sb, reada_bh,
+				/* may unlock the write lock */
+				unlocked = search_by_key_reada(sb, reada_bh,
 						    reada_blocks, reada_count);
+			/*
+			 * If we haven't already unlocked the write lock,
+			 * then we need to do that here before reading
+			 * the current block
+			 */
+			if (!buffer_uptodate(bh) && !unlocked) {
+				reiserfs_write_unlock(sb);
+				unlocked = true;
+			}
 			ll_rw_block(READ, 1, &bh);
 			wait_on_buffer(bh);
+
+			if (unlocked)
+				reiserfs_write_lock(sb);
 			if (!buffer_uptodate(bh))
 				goto io_error;
 		} else {
@@ -673,7 +708,7 @@
 		       !key_in_buffer(search_path, key, sb),
 		       "PAP-5130: key is not in the buffer");
 #ifdef CONFIG_REISERFS_CHECK
-		if (cur_tb) {
+		if (REISERFS_SB(sb)->cur_tb) {
 			print_cur_tb("5140");
 			reiserfs_panic(sb, "PAP-5140",
 				       "schedule occurred in do_balance!");
@@ -1024,7 +1059,9 @@
 			reiserfs_free_block(th, inode, block, 1);
 		    }
 
+		    reiserfs_write_unlock(sb);
 		    cond_resched();
+		    reiserfs_write_lock(sb);
 
 		    if (item_moved (&s_ih, path))  {
 			need_re_search = 1;
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index f0ad05f..339b0ba 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -465,7 +465,7 @@
 	struct reiserfs_transaction_handle th;
 	th.t_trans_id = 0;
 
-	lock_kernel();
+	reiserfs_write_lock(s);
 
 	if (s->s_dirt)
 		reiserfs_write_super(s);
@@ -499,10 +499,10 @@
 
 	reiserfs_proc_info_done(s);
 
+	reiserfs_write_unlock(s);
+	mutex_destroy(&REISERFS_SB(s)->lock);
 	kfree(s->s_fs_info);
 	s->s_fs_info = NULL;
-
-	unlock_kernel();
 }
 
 static struct kmem_cache *reiserfs_inode_cachep;
@@ -554,25 +554,28 @@
 	struct reiserfs_transaction_handle th;
 
 	int err = 0;
+	int lock_depth;
+
 	if (inode->i_sb->s_flags & MS_RDONLY) {
 		reiserfs_warning(inode->i_sb, "clm-6006",
 				 "writing inode %lu on readonly FS",
 				 inode->i_ino);
 		return;
 	}
-	reiserfs_write_lock(inode->i_sb);
+	lock_depth = reiserfs_write_lock_once(inode->i_sb);
 
 	/* this is really only used for atime updates, so they don't have
 	 ** to be included in O_SYNC or fsync
 	 */
 	err = journal_begin(&th, inode->i_sb, 1);
-	if (err) {
-		reiserfs_write_unlock(inode->i_sb);
-		return;
-	}
+	if (err)
+		goto out;
+
 	reiserfs_update_sd(&th, inode);
 	journal_end(&th, inode->i_sb, 1);
-	reiserfs_write_unlock(inode->i_sb);
+
+out:
+	reiserfs_write_unlock_once(inode->i_sb, lock_depth);
 }
 
 #ifdef CONFIG_QUOTA
@@ -1168,11 +1171,14 @@
 	unsigned int qfmt = 0;
 #ifdef CONFIG_QUOTA
 	int i;
+#endif
 
+	reiserfs_write_lock(s);
+
+#ifdef CONFIG_QUOTA
 	memcpy(qf_names, REISERFS_SB(s)->s_qf_names, sizeof(qf_names));
 #endif
 
-	lock_kernel();
 	rs = SB_DISK_SUPER_BLOCK(s);
 
 	if (!reiserfs_parse_options
@@ -1295,12 +1301,12 @@
 
 out_ok:
 	replace_mount_options(s, new_opts);
-	unlock_kernel();
+	reiserfs_write_unlock(s);
 	return 0;
 
 out_err:
 	kfree(new_opts);
-	unlock_kernel();
+	reiserfs_write_unlock(s);
 	return err;
 }
 
@@ -1404,7 +1410,9 @@
 static int reread_meta_blocks(struct super_block *s)
 {
 	ll_rw_block(READ, 1, &(SB_BUFFER_WITH_SB(s)));
+	reiserfs_write_unlock(s);
 	wait_on_buffer(SB_BUFFER_WITH_SB(s));
+	reiserfs_write_lock(s);
 	if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) {
 		reiserfs_warning(s, "reiserfs-2504", "error reading the super");
 		return 1;
@@ -1613,7 +1621,7 @@
 	sbi = kzalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL);
 	if (!sbi) {
 		errval = -ENOMEM;
-		goto error;
+		goto error_alloc;
 	}
 	s->s_fs_info = sbi;
 	/* Set default values for options: non-aggressive tails, RO on errors */
@@ -1627,6 +1635,20 @@
 	/* setup default block allocator options */
 	reiserfs_init_alloc_options(s);
 
+	mutex_init(&REISERFS_SB(s)->lock);
+	REISERFS_SB(s)->lock_depth = -1;
+
+	/*
+	 * This function is called with the bkl, which also was the old
+	 * locking used here.
+	 * do_journal_begin() will soon check if we hold the lock (ie: was the
+	 * bkl). This is likely because do_journal_begin() has several another
+	 * callers because at this time, it doesn't seem to be necessary to
+	 * protect against anything.
+	 * Anyway, let's be conservative and lock for now.
+	 */
+	reiserfs_write_lock(s);
+
 	jdev_name = NULL;
 	if (reiserfs_parse_options
 	    (s, (char *)data, &(sbi->s_mount_opt), &blocks, &jdev_name,
@@ -1852,9 +1874,13 @@
 	init_waitqueue_head(&(sbi->s_wait));
 	spin_lock_init(&sbi->bitmap_lock);
 
+	reiserfs_write_unlock(s);
+
 	return (0);
 
 error:
+	reiserfs_write_unlock(s);
+error_alloc:
 	if (jinit_done) {	/* kill the commit thread, free journal ram */
 		journal_release_error(NULL, s);
 	}
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index 6925b83..58aa8e7 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -975,7 +975,7 @@
 	int err = 0;
 
 	/* If we don't have the privroot located yet - go find it */
-	mutex_lock(&s->s_root->d_inode->i_mutex);
+	reiserfs_mutex_lock_safe(&s->s_root->d_inode->i_mutex, s);
 	dentry = lookup_one_len(PRIVROOT_NAME, s->s_root,
 				strlen(PRIVROOT_NAME));
 	if (!IS_ERR(dentry)) {
@@ -1004,14 +1004,14 @@
 		goto error;
 
 	if (!privroot->d_inode && !(mount_flags & MS_RDONLY)) {
-		mutex_lock(&s->s_root->d_inode->i_mutex);
+		reiserfs_mutex_lock_safe(&s->s_root->d_inode->i_mutex, s);
 		err = create_privroot(REISERFS_SB(s)->priv_root);
 		mutex_unlock(&s->s_root->d_inode->i_mutex);
 	}
 
 	if (privroot->d_inode) {
 		s->s_xattr = reiserfs_xattr_handlers;
-		mutex_lock(&privroot->d_inode->i_mutex);
+		reiserfs_mutex_lock_safe(&privroot->d_inode->i_mutex, s);
 		if (!REISERFS_SB(s)->xattr_root) {
 			struct dentry *dentry;
 			dentry = lookup_one_len(XAROOT_NAME, privroot,
diff --git a/fs/sync.c b/fs/sync.c
index d104591..36752a6 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -295,10 +295,11 @@
  */
 int generic_write_sync(struct file *file, loff_t pos, loff_t count)
 {
-	if (!(file->f_flags & O_SYNC) && !IS_SYNC(file->f_mapping->host))
+	if (!(file->f_flags & O_DSYNC) && !IS_SYNC(file->f_mapping->host))
 		return 0;
 	return vfs_fsync_range(file, file->f_path.dentry, pos,
-			       pos + count - 1, 1);
+			       pos + count - 1,
+			       (file->f_flags & __O_SYNC) ? 0 : 1);
 }
 EXPORT_SYMBOL(generic_write_sync);
 
@@ -452,9 +453,7 @@
 
 	ret = 0;
 	if (flags & SYNC_FILE_RANGE_WAIT_BEFORE) {
-		ret = wait_on_page_writeback_range(mapping,
-					offset >> PAGE_CACHE_SHIFT,
-					endbyte >> PAGE_CACHE_SHIFT);
+		ret = filemap_fdatawait_range(mapping, offset, endbyte);
 		if (ret < 0)
 			goto out;
 	}
@@ -467,9 +466,7 @@
 	}
 
 	if (flags & SYNC_FILE_RANGE_WAIT_AFTER) {
-		ret = wait_on_page_writeback_range(mapping,
-					offset >> PAGE_CACHE_SHIFT,
-					endbyte >> PAGE_CACHE_SHIFT);
+		ret = filemap_fdatawait_range(mapping, offset, endbyte);
 	}
 out:
 	return ret;
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index e020183..f05f230 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -25,7 +25,6 @@
 #include "sysfs.h"
 
 DEFINE_MUTEX(sysfs_mutex);
-DEFINE_MUTEX(sysfs_rename_mutex);
 DEFINE_SPINLOCK(sysfs_assoc_lock);
 
 static DEFINE_SPINLOCK(sysfs_ino_lock);
@@ -85,46 +84,6 @@
 }
 
 /**
- *	sysfs_get_dentry - get dentry for the given sysfs_dirent
- *	@sd: sysfs_dirent of interest
- *
- *	Get dentry for @sd.  Dentry is looked up if currently not
- *	present.  This function descends from the root looking up
- *	dentry for each step.
- *
- *	LOCKING:
- *	mutex_lock(sysfs_rename_mutex)
- *
- *	RETURNS:
- *	Pointer to found dentry on success, ERR_PTR() value on error.
- */
-struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd)
-{
-	struct dentry *dentry = dget(sysfs_sb->s_root);
-
-	while (dentry->d_fsdata != sd) {
-		struct sysfs_dirent *cur;
-		struct dentry *parent;
-
-		/* find the first ancestor which hasn't been looked up */
-		cur = sd;
-		while (cur->s_parent != dentry->d_fsdata)
-			cur = cur->s_parent;
-
-		/* look it up */
-		parent = dentry;
-		mutex_lock(&parent->d_inode->i_mutex);
-		dentry = lookup_one_noperm(cur->s_name, parent);
-		mutex_unlock(&parent->d_inode->i_mutex);
-		dput(parent);
-
-		if (IS_ERR(dentry))
-			break;
-	}
-	return dentry;
-}
-
-/**
  *	sysfs_get_active - get an active reference to sysfs_dirent
  *	@sd: sysfs_dirent to get an active reference to
  *
@@ -298,7 +257,61 @@
 		goto repeat;
 }
 
-static void sysfs_d_iput(struct dentry * dentry, struct inode * inode)
+static int sysfs_dentry_delete(struct dentry *dentry)
+{
+	struct sysfs_dirent *sd = dentry->d_fsdata;
+	return !!(sd->s_flags & SYSFS_FLAG_REMOVED);
+}
+
+static int sysfs_dentry_revalidate(struct dentry *dentry, struct nameidata *nd)
+{
+	struct sysfs_dirent *sd = dentry->d_fsdata;
+	int is_dir;
+
+	mutex_lock(&sysfs_mutex);
+
+	/* The sysfs dirent has been deleted */
+	if (sd->s_flags & SYSFS_FLAG_REMOVED)
+		goto out_bad;
+
+	/* The sysfs dirent has been moved? */
+	if (dentry->d_parent->d_fsdata != sd->s_parent)
+		goto out_bad;
+
+	/* The sysfs dirent has been renamed */
+	if (strcmp(dentry->d_name.name, sd->s_name) != 0)
+		goto out_bad;
+
+	mutex_unlock(&sysfs_mutex);
+out_valid:
+	return 1;
+out_bad:
+	/* Remove the dentry from the dcache hashes.
+	 * If this is a deleted dentry we use d_drop instead of d_delete
+	 * so sysfs doesn't need to cope with negative dentries.
+	 *
+	 * If this is a dentry that has simply been renamed we
+	 * use d_drop to remove it from the dcache lookup on its
+	 * old parent.  If this dentry persists later when a lookup
+	 * is performed at its new name the dentry will be readded
+	 * to the dcache hashes.
+	 */
+	is_dir = (sysfs_type(sd) == SYSFS_DIR);
+	mutex_unlock(&sysfs_mutex);
+	if (is_dir) {
+		/* If we have submounts we must allow the vfs caches
+		 * to lie about the state of the filesystem to prevent
+		 * leaks and other nasty things.
+		 */
+		if (have_submounts(dentry))
+			goto out_valid;
+		shrink_dcache_parent(dentry);
+	}
+	d_drop(dentry);
+	return 0;
+}
+
+static void sysfs_dentry_iput(struct dentry *dentry, struct inode *inode)
 {
 	struct sysfs_dirent * sd = dentry->d_fsdata;
 
@@ -307,7 +320,9 @@
 }
 
 static const struct dentry_operations sysfs_dentry_ops = {
-	.d_iput		= sysfs_d_iput,
+	.d_revalidate	= sysfs_dentry_revalidate,
+	.d_delete	= sysfs_dentry_delete,
+	.d_iput		= sysfs_dentry_iput,
 };
 
 struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type)
@@ -344,12 +359,6 @@
 	return NULL;
 }
 
-static int sysfs_ilookup_test(struct inode *inode, void *arg)
-{
-	struct sysfs_dirent *sd = arg;
-	return inode->i_ino == sd->s_ino;
-}
-
 /**
  *	sysfs_addrm_start - prepare for sysfs_dirent add/remove
  *	@acxt: pointer to sysfs_addrm_cxt to be used
@@ -357,47 +366,20 @@
  *
  *	This function is called when the caller is about to add or
  *	remove sysfs_dirent under @parent_sd.  This function acquires
- *	sysfs_mutex, grabs inode for @parent_sd if available and lock
- *	i_mutex of it.  @acxt is used to keep and pass context to
+ *	sysfs_mutex.  @acxt is used to keep and pass context to
  *	other addrm functions.
  *
  *	LOCKING:
  *	Kernel thread context (may sleep).  sysfs_mutex is locked on
- *	return.  i_mutex of parent inode is locked on return if
- *	available.
+ *	return.
  */
 void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
 		       struct sysfs_dirent *parent_sd)
 {
-	struct inode *inode;
-
 	memset(acxt, 0, sizeof(*acxt));
 	acxt->parent_sd = parent_sd;
 
-	/* Lookup parent inode.  inode initialization is protected by
-	 * sysfs_mutex, so inode existence can be determined by
-	 * looking up inode while holding sysfs_mutex.
-	 */
 	mutex_lock(&sysfs_mutex);
-
-	inode = ilookup5(sysfs_sb, parent_sd->s_ino, sysfs_ilookup_test,
-			 parent_sd);
-	if (inode) {
-		WARN_ON(inode->i_state & I_NEW);
-
-		/* parent inode available */
-		acxt->parent_inode = inode;
-
-		/* sysfs_mutex is below i_mutex in lock hierarchy.
-		 * First, trylock i_mutex.  If fails, unlock
-		 * sysfs_mutex and lock them in order.
-		 */
-		if (!mutex_trylock(&inode->i_mutex)) {
-			mutex_unlock(&sysfs_mutex);
-			mutex_lock(&inode->i_mutex);
-			mutex_lock(&sysfs_mutex);
-		}
-	}
 }
 
 /**
@@ -422,18 +404,22 @@
  */
 int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
 {
+	struct sysfs_inode_attrs *ps_iattr;
+
 	if (sysfs_find_dirent(acxt->parent_sd, sd->s_name))
 		return -EEXIST;
 
 	sd->s_parent = sysfs_get(acxt->parent_sd);
 
-	if (sysfs_type(sd) == SYSFS_DIR && acxt->parent_inode)
-		inc_nlink(acxt->parent_inode);
-
-	acxt->cnt++;
-
 	sysfs_link_sibling(sd);
 
+	/* Update timestamps on the parent */
+	ps_iattr = acxt->parent_sd->s_iattr;
+	if (ps_iattr) {
+		struct iattr *ps_iattrs = &ps_iattr->ia_iattr;
+		ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME;
+	}
+
 	return 0;
 }
 
@@ -512,70 +498,22 @@
  */
 void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
 {
+	struct sysfs_inode_attrs *ps_iattr;
+
 	BUG_ON(sd->s_flags & SYSFS_FLAG_REMOVED);
 
 	sysfs_unlink_sibling(sd);
 
+	/* Update timestamps on the parent */
+	ps_iattr = acxt->parent_sd->s_iattr;
+	if (ps_iattr) {
+		struct iattr *ps_iattrs = &ps_iattr->ia_iattr;
+		ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME;
+	}
+
 	sd->s_flags |= SYSFS_FLAG_REMOVED;
 	sd->s_sibling = acxt->removed;
 	acxt->removed = sd;
-
-	if (sysfs_type(sd) == SYSFS_DIR && acxt->parent_inode)
-		drop_nlink(acxt->parent_inode);
-
-	acxt->cnt++;
-}
-
-/**
- *	sysfs_drop_dentry - drop dentry for the specified sysfs_dirent
- *	@sd: target sysfs_dirent
- *
- *	Drop dentry for @sd.  @sd must have been unlinked from its
- *	parent on entry to this function such that it can't be looked
- *	up anymore.
- */
-static void sysfs_drop_dentry(struct sysfs_dirent *sd)
-{
-	struct inode *inode;
-	struct dentry *dentry;
-
-	inode = ilookup(sysfs_sb, sd->s_ino);
-	if (!inode)
-		return;
-
-	/* Drop any existing dentries associated with sd.
-	 *
-	 * For the dentry to be properly freed we need to grab a
-	 * reference to the dentry under the dcache lock,  unhash it,
-	 * and then put it.  The playing with the dentry count allows
-	 * dput to immediately free the dentry  if it is not in use.
-	 */
-repeat:
-	spin_lock(&dcache_lock);
-	list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
-		if (d_unhashed(dentry))
-			continue;
-		dget_locked(dentry);
-		spin_lock(&dentry->d_lock);
-		__d_drop(dentry);
-		spin_unlock(&dentry->d_lock);
-		spin_unlock(&dcache_lock);
-		dput(dentry);
-		goto repeat;
-	}
-	spin_unlock(&dcache_lock);
-
-	/* adjust nlink and update timestamp */
-	mutex_lock(&inode->i_mutex);
-
-	inode->i_ctime = CURRENT_TIME;
-	drop_nlink(inode);
-	if (sysfs_type(sd) == SYSFS_DIR)
-		drop_nlink(inode);
-
-	mutex_unlock(&inode->i_mutex);
-
-	iput(inode);
 }
 
 /**
@@ -584,25 +522,15 @@
  *
  *	Finish up sysfs_dirent add/remove.  Resources acquired by
  *	sysfs_addrm_start() are released and removed sysfs_dirents are
- *	cleaned up.  Timestamps on the parent inode are updated.
+ *	cleaned up.
  *
  *	LOCKING:
- *	All mutexes acquired by sysfs_addrm_start() are released.
+ *	sysfs_mutex is released.
  */
 void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
 {
 	/* release resources acquired by sysfs_addrm_start() */
 	mutex_unlock(&sysfs_mutex);
-	if (acxt->parent_inode) {
-		struct inode *inode = acxt->parent_inode;
-
-		/* if added/removed, update timestamps on the parent */
-		if (acxt->cnt)
-			inode->i_ctime = inode->i_mtime = CURRENT_TIME;
-
-		mutex_unlock(&inode->i_mutex);
-		iput(inode);
-	}
 
 	/* kill removed sysfs_dirents */
 	while (acxt->removed) {
@@ -611,7 +539,6 @@
 		acxt->removed = sd->s_sibling;
 		sd->s_sibling = NULL;
 
-		sysfs_drop_dentry(sd);
 		sysfs_deactivate(sd);
 		unmap_bin_file(sd);
 		sysfs_put(sd);
@@ -751,10 +678,15 @@
 	}
 
 	/* instantiate and hash dentry */
-	dentry->d_op = &sysfs_dentry_ops;
-	dentry->d_fsdata = sysfs_get(sd);
-	d_instantiate(dentry, inode);
-	d_rehash(dentry);
+	ret = d_find_alias(inode);
+	if (!ret) {
+		dentry->d_op = &sysfs_dentry_ops;
+		dentry->d_fsdata = sysfs_get(sd);
+		d_add(dentry, inode);
+	} else {
+		d_move(ret, dentry);
+		iput(inode);
+	}
 
  out_unlock:
 	mutex_unlock(&sysfs_mutex);
@@ -763,7 +695,9 @@
 
 const struct inode_operations sysfs_dir_inode_operations = {
 	.lookup		= sysfs_lookup,
+	.permission	= sysfs_permission,
 	.setattr	= sysfs_setattr,
+	.getattr	= sysfs_getattr,
 	.setxattr	= sysfs_setxattr,
 };
 
@@ -826,141 +760,65 @@
 	__sysfs_remove_dir(sd);
 }
 
-int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
+int sysfs_rename(struct sysfs_dirent *sd,
+	struct sysfs_dirent *new_parent_sd, const char *new_name)
 {
-	struct sysfs_dirent *sd = kobj->sd;
-	struct dentry *parent = NULL;
-	struct dentry *old_dentry = NULL, *new_dentry = NULL;
 	const char *dup_name = NULL;
 	int error;
 
-	mutex_lock(&sysfs_rename_mutex);
-
-	error = 0;
-	if (strcmp(sd->s_name, new_name) == 0)
-		goto out;	/* nothing to rename */
-
-	/* get the original dentry */
-	old_dentry = sysfs_get_dentry(sd);
-	if (IS_ERR(old_dentry)) {
-		error = PTR_ERR(old_dentry);
-		old_dentry = NULL;
-		goto out;
-	}
-
-	parent = old_dentry->d_parent;
-
-	/* lock parent and get dentry for new name */
-	mutex_lock(&parent->d_inode->i_mutex);
 	mutex_lock(&sysfs_mutex);
 
-	error = -EEXIST;
-	if (sysfs_find_dirent(sd->s_parent, new_name))
-		goto out_unlock;
+	error = 0;
+	if ((sd->s_parent == new_parent_sd) &&
+	    (strcmp(sd->s_name, new_name) == 0))
+		goto out;	/* nothing to rename */
 
-	error = -ENOMEM;
-	new_dentry = d_alloc_name(parent, new_name);
-	if (!new_dentry)
-		goto out_unlock;
+	error = -EEXIST;
+	if (sysfs_find_dirent(new_parent_sd, new_name))
+		goto out;
 
 	/* rename sysfs_dirent */
-	error = -ENOMEM;
-	new_name = dup_name = kstrdup(new_name, GFP_KERNEL);
-	if (!new_name)
-		goto out_unlock;
+	if (strcmp(sd->s_name, new_name) != 0) {
+		error = -ENOMEM;
+		new_name = dup_name = kstrdup(new_name, GFP_KERNEL);
+		if (!new_name)
+			goto out;
 
-	dup_name = sd->s_name;
-	sd->s_name = new_name;
+		dup_name = sd->s_name;
+		sd->s_name = new_name;
+	}
 
-	/* rename */
-	d_add(new_dentry, NULL);
-	d_move(old_dentry, new_dentry);
+	/* Remove from old parent's list and insert into new parent's list. */
+	if (sd->s_parent != new_parent_sd) {
+		sysfs_unlink_sibling(sd);
+		sysfs_get(new_parent_sd);
+		sysfs_put(sd->s_parent);
+		sd->s_parent = new_parent_sd;
+		sysfs_link_sibling(sd);
+	}
 
 	error = 0;
- out_unlock:
-	mutex_unlock(&sysfs_mutex);
-	mutex_unlock(&parent->d_inode->i_mutex);
-	kfree(dup_name);
-	dput(old_dentry);
-	dput(new_dentry);
  out:
-	mutex_unlock(&sysfs_rename_mutex);
+	mutex_unlock(&sysfs_mutex);
+	kfree(dup_name);
 	return error;
 }
 
+int sysfs_rename_dir(struct kobject *kobj, const char *new_name)
+{
+	return sysfs_rename(kobj->sd, kobj->sd->s_parent, new_name);
+}
+
 int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj)
 {
 	struct sysfs_dirent *sd = kobj->sd;
 	struct sysfs_dirent *new_parent_sd;
-	struct dentry *old_parent, *new_parent = NULL;
-	struct dentry *old_dentry = NULL, *new_dentry = NULL;
-	int error;
 
-	mutex_lock(&sysfs_rename_mutex);
 	BUG_ON(!sd->s_parent);
-	new_parent_sd = (new_parent_kobj && new_parent_kobj->sd) ?
+	new_parent_sd = new_parent_kobj && new_parent_kobj->sd ?
 		new_parent_kobj->sd : &sysfs_root;
 
-	error = 0;
-	if (sd->s_parent == new_parent_sd)
-		goto out;	/* nothing to move */
-
-	/* get dentries */
-	old_dentry = sysfs_get_dentry(sd);
-	if (IS_ERR(old_dentry)) {
-		error = PTR_ERR(old_dentry);
-		old_dentry = NULL;
-		goto out;
-	}
-	old_parent = old_dentry->d_parent;
-
-	new_parent = sysfs_get_dentry(new_parent_sd);
-	if (IS_ERR(new_parent)) {
-		error = PTR_ERR(new_parent);
-		new_parent = NULL;
-		goto out;
-	}
-
-again:
-	mutex_lock(&old_parent->d_inode->i_mutex);
-	if (!mutex_trylock(&new_parent->d_inode->i_mutex)) {
-		mutex_unlock(&old_parent->d_inode->i_mutex);
-		goto again;
-	}
-	mutex_lock(&sysfs_mutex);
-
-	error = -EEXIST;
-	if (sysfs_find_dirent(new_parent_sd, sd->s_name))
-		goto out_unlock;
-
-	error = -ENOMEM;
-	new_dentry = d_alloc_name(new_parent, sd->s_name);
-	if (!new_dentry)
-		goto out_unlock;
-
-	error = 0;
-	d_add(new_dentry, NULL);
-	d_move(old_dentry, new_dentry);
-
-	/* Remove from old parent's list and insert into new parent's list. */
-	sysfs_unlink_sibling(sd);
-	sysfs_get(new_parent_sd);
-	drop_nlink(old_parent->d_inode);
-	sysfs_put(sd->s_parent);
-	sd->s_parent = new_parent_sd;
-	inc_nlink(new_parent->d_inode);
-	sysfs_link_sibling(sd);
-
- out_unlock:
-	mutex_unlock(&sysfs_mutex);
-	mutex_unlock(&new_parent->d_inode->i_mutex);
-	mutex_unlock(&old_parent->d_inode->i_mutex);
- out:
-	dput(new_parent);
-	dput(old_dentry);
-	dput(new_dentry);
-	mutex_unlock(&sysfs_rename_mutex);
-	return error;
+	return sysfs_rename(sd, new_parent_sd, sd->s_name);
 }
 
 /* Relationship between s_mode and the DT_xxx types */
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index f5ea468..dc30d9e 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -579,46 +579,23 @@
  */
 int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode)
 {
-	struct sysfs_dirent *victim_sd = NULL;
-	struct dentry *victim = NULL;
-	struct inode * inode;
+	struct sysfs_dirent *sd;
 	struct iattr newattrs;
 	int rc;
 
+	mutex_lock(&sysfs_mutex);
+
 	rc = -ENOENT;
-	victim_sd = sysfs_get_dirent(kobj->sd, attr->name);
-	if (!victim_sd)
+	sd = sysfs_find_dirent(kobj->sd, attr->name);
+	if (!sd)
 		goto out;
 
-	mutex_lock(&sysfs_rename_mutex);
-	victim = sysfs_get_dentry(victim_sd);
-	mutex_unlock(&sysfs_rename_mutex);
-	if (IS_ERR(victim)) {
-		rc = PTR_ERR(victim);
-		victim = NULL;
-		goto out;
-	}
+	newattrs.ia_mode = (mode & S_IALLUGO) | (sd->s_mode & ~S_IALLUGO);
+	newattrs.ia_valid = ATTR_MODE;
+	rc = sysfs_sd_setattr(sd, &newattrs);
 
-	inode = victim->d_inode;
-
-	mutex_lock(&inode->i_mutex);
-
-	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
-	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
-	newattrs.ia_ctime = current_fs_time(inode->i_sb);
-	rc = sysfs_setattr(victim, &newattrs);
-
-	if (rc == 0) {
-		fsnotify_change(victim, newattrs.ia_valid);
-		mutex_lock(&sysfs_mutex);
-		victim_sd->s_mode = newattrs.ia_mode;
-		mutex_unlock(&sysfs_mutex);
-	}
-
-	mutex_unlock(&inode->i_mutex);
  out:
-	dput(victim);
-	sysfs_put(victim_sd);
+	mutex_unlock(&sysfs_mutex);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(sysfs_chmod_file);
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index e28cecf..220b758 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -37,7 +37,9 @@
 };
 
 static const struct inode_operations sysfs_inode_operations ={
+	.permission	= sysfs_permission,
 	.setattr	= sysfs_setattr,
+	.getattr	= sysfs_getattr,
 	.setxattr	= sysfs_setxattr,
 };
 
@@ -46,7 +48,7 @@
 	return bdi_init(&sysfs_backing_dev_info);
 }
 
-struct sysfs_inode_attrs *sysfs_init_inode_attrs(struct sysfs_dirent *sd)
+static struct sysfs_inode_attrs *sysfs_init_inode_attrs(struct sysfs_dirent *sd)
 {
 	struct sysfs_inode_attrs *attrs;
 	struct iattr *iattrs;
@@ -64,30 +66,15 @@
 
 	return attrs;
 }
-int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
+
+int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr * iattr)
 {
-	struct inode * inode = dentry->d_inode;
-	struct sysfs_dirent * sd = dentry->d_fsdata;
 	struct sysfs_inode_attrs *sd_attrs;
 	struct iattr *iattrs;
 	unsigned int ia_valid = iattr->ia_valid;
-	int error;
-
-	if (!sd)
-		return -EINVAL;
 
 	sd_attrs = sd->s_iattr;
 
-	error = inode_change_ok(inode, iattr);
-	if (error)
-		return error;
-
-	iattr->ia_valid &= ~ATTR_SIZE; /* ignore size changes */
-
-	error = inode_setattr(inode, iattr);
-	if (error)
-		return error;
-
 	if (!sd_attrs) {
 		/* setting attributes for the first time, allocate now */
 		sd_attrs = sysfs_init_inode_attrs(sd);
@@ -103,42 +90,78 @@
 		if (ia_valid & ATTR_GID)
 			iattrs->ia_gid = iattr->ia_gid;
 		if (ia_valid & ATTR_ATIME)
-			iattrs->ia_atime = timespec_trunc(iattr->ia_atime,
-					inode->i_sb->s_time_gran);
+			iattrs->ia_atime = iattr->ia_atime;
 		if (ia_valid & ATTR_MTIME)
-			iattrs->ia_mtime = timespec_trunc(iattr->ia_mtime,
-					inode->i_sb->s_time_gran);
+			iattrs->ia_mtime = iattr->ia_mtime;
 		if (ia_valid & ATTR_CTIME)
-			iattrs->ia_ctime = timespec_trunc(iattr->ia_ctime,
-					inode->i_sb->s_time_gran);
+			iattrs->ia_ctime = iattr->ia_ctime;
 		if (ia_valid & ATTR_MODE) {
 			umode_t mode = iattr->ia_mode;
-
-			if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
-				mode &= ~S_ISGID;
 			iattrs->ia_mode = sd->s_mode = mode;
 		}
 	}
+	return 0;
+}
+
+int sysfs_setattr(struct dentry *dentry, struct iattr *iattr)
+{
+	struct inode *inode = dentry->d_inode;
+	struct sysfs_dirent *sd = dentry->d_fsdata;
+	int error;
+
+	if (!sd)
+		return -EINVAL;
+
+	error = inode_change_ok(inode, iattr);
+	if (error)
+		return error;
+
+	iattr->ia_valid &= ~ATTR_SIZE; /* ignore size changes */
+
+	error = inode_setattr(inode, iattr);
+	if (error)
+		return error;
+
+	mutex_lock(&sysfs_mutex);
+	error = sysfs_sd_setattr(sd, iattr);
+	mutex_unlock(&sysfs_mutex);
+
 	return error;
 }
 
+static int sysfs_sd_setsecdata(struct sysfs_dirent *sd, void **secdata, u32 *secdata_len)
+{
+	struct sysfs_inode_attrs *iattrs;
+	void *old_secdata;
+	size_t old_secdata_len;
+
+	iattrs = sd->s_iattr;
+	if (!iattrs)
+		iattrs = sysfs_init_inode_attrs(sd);
+	if (!iattrs)
+		return -ENOMEM;
+
+	old_secdata = iattrs->ia_secdata;
+	old_secdata_len = iattrs->ia_secdata_len;
+
+	iattrs->ia_secdata = *secdata;
+	iattrs->ia_secdata_len = *secdata_len;
+
+	*secdata = old_secdata;
+	*secdata_len = old_secdata_len;
+	return 0;
+}
+
 int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value,
 		size_t size, int flags)
 {
 	struct sysfs_dirent *sd = dentry->d_fsdata;
-	struct sysfs_inode_attrs *iattrs;
 	void *secdata;
 	int error;
 	u32 secdata_len = 0;
 
 	if (!sd)
 		return -EINVAL;
-	if (!sd->s_iattr)
-		sd->s_iattr = sysfs_init_inode_attrs(sd);
-	if (!sd->s_iattr)
-		return -ENOMEM;
-
-	iattrs = sd->s_iattr;
 
 	if (!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN)) {
 		const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
@@ -150,12 +173,13 @@
 						&secdata, &secdata_len);
 		if (error)
 			goto out;
-		if (iattrs->ia_secdata)
-			security_release_secctx(iattrs->ia_secdata,
-						iattrs->ia_secdata_len);
-		iattrs->ia_secdata = secdata;
-		iattrs->ia_secdata_len = secdata_len;
 
+		mutex_lock(&sysfs_mutex);
+		error = sysfs_sd_setsecdata(sd, &secdata, &secdata_len);
+		mutex_unlock(&sysfs_mutex);
+
+		if (secdata)
+			security_release_secctx(secdata, secdata_len);
 	} else
 		return -EINVAL;
 out:
@@ -170,7 +194,6 @@
 
 static inline void set_inode_attr(struct inode * inode, struct iattr * iattr)
 {
-	inode->i_mode = iattr->ia_mode;
 	inode->i_uid = iattr->ia_uid;
 	inode->i_gid = iattr->ia_gid;
 	inode->i_atime = iattr->ia_atime;
@@ -178,17 +201,6 @@
 	inode->i_ctime = iattr->ia_ctime;
 }
 
-
-/*
- * sysfs has a different i_mutex lock order behavior for i_mutex than other
- * filesystems; sysfs i_mutex is called in many places with subsystem locks
- * held. At the same time, many of the VFS locking rules do not apply to
- * sysfs at all (cross directory rename for example). To untangle this mess
- * (which gives false positives in lockdep), we're giving sysfs inodes their
- * own class for i_mutex.
- */
-static struct lock_class_key sysfs_inode_imutex_key;
-
 static int sysfs_count_nlink(struct sysfs_dirent *sd)
 {
 	struct sysfs_dirent *child;
@@ -201,38 +213,55 @@
 	return nr + 2;
 }
 
+static void sysfs_refresh_inode(struct sysfs_dirent *sd, struct inode *inode)
+{
+	struct sysfs_inode_attrs *iattrs = sd->s_iattr;
+
+	inode->i_mode = sd->s_mode;
+	if (iattrs) {
+		/* sysfs_dirent has non-default attributes
+		 * get them from persistent copy in sysfs_dirent
+		 */
+		set_inode_attr(inode, &iattrs->ia_iattr);
+		security_inode_notifysecctx(inode,
+					    iattrs->ia_secdata,
+					    iattrs->ia_secdata_len);
+	}
+
+	if (sysfs_type(sd) == SYSFS_DIR)
+		inode->i_nlink = sysfs_count_nlink(sd);
+}
+
+int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+{
+	struct sysfs_dirent *sd = dentry->d_fsdata;
+	struct inode *inode = dentry->d_inode;
+
+	mutex_lock(&sysfs_mutex);
+	sysfs_refresh_inode(sd, inode);
+	mutex_unlock(&sysfs_mutex);
+
+	generic_fillattr(inode, stat);
+	return 0;
+}
+
 static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
 {
 	struct bin_attribute *bin_attr;
-	struct sysfs_inode_attrs *iattrs;
 
 	inode->i_private = sysfs_get(sd);
 	inode->i_mapping->a_ops = &sysfs_aops;
 	inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info;
 	inode->i_op = &sysfs_inode_operations;
-	inode->i_ino = sd->s_ino;
-	lockdep_set_class(&inode->i_mutex, &sysfs_inode_imutex_key);
 
-	iattrs = sd->s_iattr;
-	if (iattrs) {
-		/* sysfs_dirent has non-default attributes
-		 * get them for the new inode from persistent copy
-		 * in sysfs_dirent
-		 */
-		set_inode_attr(inode, &iattrs->ia_iattr);
-		if (iattrs->ia_secdata)
-			security_inode_notifysecctx(inode,
-						iattrs->ia_secdata,
-						iattrs->ia_secdata_len);
-	} else
-		set_default_inode_attr(inode, sd->s_mode);
+	set_default_inode_attr(inode, sd->s_mode);
+	sysfs_refresh_inode(sd, inode);
 
 	/* initialize inode according to type */
 	switch (sysfs_type(sd)) {
 	case SYSFS_DIR:
 		inode->i_op = &sysfs_dir_inode_operations;
 		inode->i_fop = &sysfs_dir_operations;
-		inode->i_nlink = sysfs_count_nlink(sd);
 		break;
 	case SYSFS_KOBJ_ATTR:
 		inode->i_size = PAGE_SIZE;
@@ -315,3 +344,14 @@
 	else
 		return -ENOENT;
 }
+
+int sysfs_permission(struct inode *inode, int mask)
+{
+	struct sysfs_dirent *sd = inode->i_private;
+
+	mutex_lock(&sysfs_mutex);
+	sysfs_refresh_inode(sd, inode);
+	mutex_unlock(&sysfs_mutex);
+
+	return generic_permission(inode, mask, NULL);
+}
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index c5081ad..c5eff49 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -210,10 +210,13 @@
 }
 
 const struct inode_operations sysfs_symlink_inode_operations = {
-	.setxattr = sysfs_setxattr,
-	.readlink = generic_readlink,
-	.follow_link = sysfs_follow_link,
-	.put_link = sysfs_put_link,
+	.setxattr	= sysfs_setxattr,
+	.readlink	= generic_readlink,
+	.follow_link	= sysfs_follow_link,
+	.put_link	= sysfs_put_link,
+	.setattr	= sysfs_setattr,
+	.getattr	= sysfs_getattr,
+	.permission	= sysfs_permission,
 };
 
 
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index af4c4e7..ca52e7b 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -89,9 +89,7 @@
  */
 struct sysfs_addrm_cxt {
 	struct sysfs_dirent	*parent_sd;
-	struct inode		*parent_inode;
 	struct sysfs_dirent	*removed;
-	int			cnt;
 };
 
 /*
@@ -105,7 +103,6 @@
  * dir.c
  */
 extern struct mutex sysfs_mutex;
-extern struct mutex sysfs_rename_mutex;
 extern spinlock_t sysfs_assoc_lock;
 
 extern const struct file_operations sysfs_dir_operations;
@@ -133,6 +130,9 @@
 			struct sysfs_dirent **p_sd);
 void sysfs_remove_subdir(struct sysfs_dirent *sd);
 
+int sysfs_rename(struct sysfs_dirent *sd,
+	struct sysfs_dirent *new_parent_sd, const char *new_name);
+
 static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd)
 {
 	if (sd) {
@@ -155,7 +155,10 @@
  */
 struct inode *sysfs_get_inode(struct sysfs_dirent *sd);
 void sysfs_delete_inode(struct inode *inode);
+int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr);
+int sysfs_permission(struct inode *inode, int mask);
 int sysfs_setattr(struct dentry *dentry, struct iattr *iattr);
+int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);
 int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value,
 		size_t size, int flags);
 int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name);
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index dbc093a..8a771c5 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -2014,7 +2014,7 @@
 		inum = key_inum_flash(c, &dent->key);
 		fscki1 = read_add_inode(c, priv, inum);
 		if (IS_ERR(fscki1)) {
-			err = PTR_ERR(fscki);
+			err = PTR_ERR(fscki1);
 			ubifs_err("error %d while processing entry node and "
 				  "trying to find parent inode node %lu",
 				  err, (unsigned long)inum);
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 1009adc..39849f8 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1389,7 +1389,6 @@
 			       unsigned long nr_segs, loff_t pos)
 {
 	int err;
-	ssize_t ret;
 	struct inode *inode = iocb->ki_filp->f_mapping->host;
 	struct ubifs_info *c = inode->i_sb->s_fs_info;
 
@@ -1397,17 +1396,7 @@
 	if (err)
 		return err;
 
-	ret = generic_file_aio_write(iocb, iov, nr_segs, pos);
-	if (ret < 0)
-		return ret;
-
-	if (ret > 0 && (IS_SYNC(inode) || iocb->ki_filp->f_flags & O_SYNC)) {
-		err = ubifs_sync_wbufs_by_inode(c, inode);
-		if (err)
-			return err;
-	}
-
-	return ret;
+	return generic_file_aio_write(iocb, iov, nr_segs, pos);
 }
 
 static int ubifs_set_page_dirty(struct page *page)
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c
index f94ddf7..868a55e 100644
--- a/fs/ubifs/recovery.c
+++ b/fs/ubifs/recovery.c
@@ -23,7 +23,7 @@
 /*
  * This file implements functions needed to recover from unclean un-mounts.
  * When UBIFS is mounted, it checks a flag on the master node to determine if
- * an un-mount was completed sucessfully. If not, the process of mounting
+ * an un-mount was completed successfully. If not, the process of mounting
  * incorparates additional checking and fixing of on-flash data structures.
  * UBIFS always cleans away all remnants of an unclean un-mount, so that
  * errors do not accumulate. However UBIFS defers recovery if it is mounted
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 333e181e..943ad56 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -1842,22 +1842,32 @@
  * @name: UBI volume name
  * @mode: UBI volume open mode
  *
- * There are several ways to specify UBI volumes when mounting UBIFS:
- * o ubiX_Y    - UBI device number X, volume Y;
- * o ubiY      - UBI device number 0, volume Y;
+ * The primary method of mounting UBIFS is by specifying the UBI volume
+ * character device node path. However, UBIFS may also be mounted withoug any
+ * character device node using one of the following methods:
+ *
+ * o ubiX_Y    - mount UBI device number X, volume Y;
+ * o ubiY      - mount UBI device number 0, volume Y;
  * o ubiX:NAME - mount UBI device X, volume with name NAME;
  * o ubi:NAME  - mount UBI device 0, volume with name NAME.
  *
  * Alternative '!' separator may be used instead of ':' (because some shells
  * like busybox may interpret ':' as an NFS host name separator). This function
- * returns ubi volume object in case of success and a negative error code in
- * case of failure.
+ * returns UBI volume description object in case of success and a negative
+ * error code in case of failure.
  */
 static struct ubi_volume_desc *open_ubi(const char *name, int mode)
 {
+	struct ubi_volume_desc *ubi;
 	int dev, vol;
 	char *endptr;
 
+	/* First, try to open using the device node path method */
+	ubi = ubi_open_volume_path(name, mode);
+	if (!IS_ERR(ubi))
+		return ubi;
+
+	/* Try the "nodev" method */
 	if (name[0] != 'u' || name[1] != 'b' || name[2] != 'i')
 		return ERR_PTR(-EINVAL);
 
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 70f9898..87813e4 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -235,71 +235,36 @@
 }
 
 /*
- * Buffered IO write completion for delayed allocate extents.
+ * IO write completion.
  */
 STATIC void
-xfs_end_bio_delalloc(
-	struct work_struct	*work)
-{
-	xfs_ioend_t		*ioend =
-		container_of(work, xfs_ioend_t, io_work);
-
-	xfs_setfilesize(ioend);
-	xfs_destroy_ioend(ioend);
-}
-
-/*
- * Buffered IO write completion for regular, written extents.
- */
-STATIC void
-xfs_end_bio_written(
-	struct work_struct	*work)
-{
-	xfs_ioend_t		*ioend =
-		container_of(work, xfs_ioend_t, io_work);
-
-	xfs_setfilesize(ioend);
-	xfs_destroy_ioend(ioend);
-}
-
-/*
- * IO write completion for unwritten extents.
- *
- * Issue transactions to convert a buffer range from unwritten
- * to written extents.
- */
-STATIC void
-xfs_end_bio_unwritten(
+xfs_end_io(
 	struct work_struct	*work)
 {
 	xfs_ioend_t		*ioend =
 		container_of(work, xfs_ioend_t, io_work);
 	struct xfs_inode	*ip = XFS_I(ioend->io_inode);
-	xfs_off_t		offset = ioend->io_offset;
-	size_t			size = ioend->io_size;
 
-	if (likely(!ioend->io_error)) {
-		if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
-			int error;
-			error = xfs_iomap_write_unwritten(ip, offset, size);
-			if (error)
-				ioend->io_error = error;
-		}
-		xfs_setfilesize(ioend);
+	/*
+	 * For unwritten extents we need to issue transactions to convert a
+	 * range to normal written extens after the data I/O has finished.
+	 */
+	if (ioend->io_type == IOMAP_UNWRITTEN &&
+	    likely(!ioend->io_error && !XFS_FORCED_SHUTDOWN(ip->i_mount))) {
+		int error;
+
+		error = xfs_iomap_write_unwritten(ip, ioend->io_offset,
+						 ioend->io_size);
+		if (error)
+			ioend->io_error = error;
 	}
-	xfs_destroy_ioend(ioend);
-}
 
-/*
- * IO read completion for regular, written extents.
- */
-STATIC void
-xfs_end_bio_read(
-	struct work_struct	*work)
-{
-	xfs_ioend_t		*ioend =
-		container_of(work, xfs_ioend_t, io_work);
-
+	/*
+	 * We might have to update the on-disk file size after extending
+	 * writes.
+	 */
+	if (ioend->io_type != IOMAP_READ)
+		xfs_setfilesize(ioend);
 	xfs_destroy_ioend(ioend);
 }
 
@@ -314,10 +279,10 @@
 	int		wait)
 {
 	if (atomic_dec_and_test(&ioend->io_remaining)) {
-		struct workqueue_struct *wq = xfsdatad_workqueue;
-		if (ioend->io_work.func == xfs_end_bio_unwritten)
-			wq = xfsconvertd_workqueue;
+		struct workqueue_struct *wq;
 
+		wq = (ioend->io_type == IOMAP_UNWRITTEN) ?
+			xfsconvertd_workqueue : xfsdatad_workqueue;
 		queue_work(wq, &ioend->io_work);
 		if (wait)
 			flush_workqueue(wq);
@@ -355,15 +320,7 @@
 	ioend->io_offset = 0;
 	ioend->io_size = 0;
 
-	if (type == IOMAP_UNWRITTEN)
-		INIT_WORK(&ioend->io_work, xfs_end_bio_unwritten);
-	else if (type == IOMAP_DELAY)
-		INIT_WORK(&ioend->io_work, xfs_end_bio_delalloc);
-	else if (type == IOMAP_READ)
-		INIT_WORK(&ioend->io_work, xfs_end_bio_read);
-	else
-		INIT_WORK(&ioend->io_work, xfs_end_bio_written);
-
+	INIT_WORK(&ioend->io_work, xfs_end_io);
 	return ioend;
 }
 
@@ -380,7 +337,7 @@
 	return -xfs_iomap(XFS_I(inode), offset, count, flags, mapp, &nmaps);
 }
 
-STATIC_INLINE int
+STATIC int
 xfs_iomap_valid(
 	xfs_iomap_t		*iomapp,
 	loff_t			offset)
@@ -412,8 +369,9 @@
 
 STATIC void
 xfs_submit_ioend_bio(
-	xfs_ioend_t	*ioend,
-	struct bio	*bio)
+	struct writeback_control *wbc,
+	xfs_ioend_t		*ioend,
+	struct bio		*bio)
 {
 	atomic_inc(&ioend->io_remaining);
 	bio->bi_private = ioend;
@@ -426,7 +384,8 @@
 	if (xfs_ioend_new_eof(ioend))
 		xfs_mark_inode_dirty_sync(XFS_I(ioend->io_inode));
 
-	submit_bio(WRITE, bio);
+	submit_bio(wbc->sync_mode == WB_SYNC_ALL ?
+		   WRITE_SYNC_PLUG : WRITE, bio);
 	ASSERT(!bio_flagged(bio, BIO_EOPNOTSUPP));
 	bio_put(bio);
 }
@@ -505,6 +464,7 @@
  */
 STATIC void
 xfs_submit_ioend(
+	struct writeback_control *wbc,
 	xfs_ioend_t		*ioend)
 {
 	xfs_ioend_t		*head = ioend;
@@ -533,19 +493,19 @@
  retry:
 				bio = xfs_alloc_ioend_bio(bh);
 			} else if (bh->b_blocknr != lastblock + 1) {
-				xfs_submit_ioend_bio(ioend, bio);
+				xfs_submit_ioend_bio(wbc, ioend, bio);
 				goto retry;
 			}
 
 			if (bio_add_buffer(bio, bh) != bh->b_size) {
-				xfs_submit_ioend_bio(ioend, bio);
+				xfs_submit_ioend_bio(wbc, ioend, bio);
 				goto retry;
 			}
 
 			lastblock = bh->b_blocknr;
 		}
 		if (bio)
-			xfs_submit_ioend_bio(ioend, bio);
+			xfs_submit_ioend_bio(wbc, ioend, bio);
 		xfs_finish_ioend(ioend, 0);
 	} while ((ioend = next) != NULL);
 }
@@ -1191,7 +1151,7 @@
 	}
 
 	if (iohead)
-		xfs_submit_ioend(iohead);
+		xfs_submit_ioend(wbc, iohead);
 
 	return page_dirty;
 
@@ -1528,7 +1488,7 @@
 		 * didn't map an unwritten extent so switch it's completion
 		 * handler.
 		 */
-		INIT_WORK(&ioend->io_work, xfs_end_bio_written);
+		ioend->io_type = IOMAP_NEW;
 		xfs_finish_ioend(ioend, 0);
 	}
 
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index 965df12..4ddc973 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -149,7 +149,7 @@
 	return mask;
 }
 
-STATIC_INLINE void
+STATIC void
 set_page_region(
 	struct page	*page,
 	size_t		offset,
@@ -161,7 +161,7 @@
 		SetPageUptodate(page);
 }
 
-STATIC_INLINE int
+STATIC int
 test_page_region(
 	struct page	*page,
 	size_t		offset,
@@ -582,7 +582,7 @@
  *	although backing storage may not be.
  */
 xfs_buf_t *
-xfs_buf_get_flags(
+xfs_buf_get(
 	xfs_buftarg_t		*target,/* target for buffer		*/
 	xfs_off_t		ioff,	/* starting offset of range	*/
 	size_t			isize,	/* length of range		*/
@@ -661,7 +661,7 @@
 }
 
 xfs_buf_t *
-xfs_buf_read_flags(
+xfs_buf_read(
 	xfs_buftarg_t		*target,
 	xfs_off_t		ioff,
 	size_t			isize,
@@ -671,7 +671,7 @@
 
 	flags |= XBF_READ;
 
-	bp = xfs_buf_get_flags(target, ioff, isize, flags);
+	bp = xfs_buf_get(target, ioff, isize, flags);
 	if (bp) {
 		if (!XFS_BUF_ISDONE(bp)) {
 			XB_TRACE(bp, "read", (unsigned long)flags);
@@ -718,7 +718,7 @@
 		return;
 
 	flags |= (XBF_TRYLOCK|XBF_ASYNC|XBF_READ_AHEAD);
-	xfs_buf_read_flags(target, ioff, isize, flags);
+	xfs_buf_read(target, ioff, isize, flags);
 }
 
 xfs_buf_t *
@@ -1113,7 +1113,7 @@
 	xfs_buf_delwri_queue(bp, 1);
 }
 
-STATIC_INLINE void
+STATIC void
 _xfs_buf_ioend(
 	xfs_buf_t		*bp,
 	int			schedule)
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h
index 9b4d666..5f07dd9 100644
--- a/fs/xfs/linux-2.6/xfs_buf.h
+++ b/fs/xfs/linux-2.6/xfs_buf.h
@@ -186,15 +186,10 @@
 #define xfs_incore(buftarg,blkno,len,lockit) \
 	_xfs_buf_find(buftarg, blkno ,len, lockit, NULL)
 
-extern xfs_buf_t *xfs_buf_get_flags(xfs_buftarg_t *, xfs_off_t, size_t,
+extern xfs_buf_t *xfs_buf_get(xfs_buftarg_t *, xfs_off_t, size_t,
 				xfs_buf_flags_t);
-#define xfs_buf_get(target, blkno, len, flags) \
-	xfs_buf_get_flags((target), (blkno), (len), XBF_LOCK | XBF_MAPPED)
-
-extern xfs_buf_t *xfs_buf_read_flags(xfs_buftarg_t *, xfs_off_t, size_t,
+extern xfs_buf_t *xfs_buf_read(xfs_buftarg_t *, xfs_off_t, size_t,
 				xfs_buf_flags_t);
-#define xfs_buf_read(target, blkno, len, flags) \
-	xfs_buf_read_flags((target), (blkno), (len), XBF_LOCK | XBF_MAPPED)
 
 extern xfs_buf_t *xfs_buf_get_empty(size_t, xfs_buftarg_t *);
 extern xfs_buf_t *xfs_buf_get_noaddr(size_t, xfs_buftarg_t *);
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index eff61e2..e4caeb2 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -52,7 +52,7 @@
 	loff_t			pos)
 {
 	struct file		*file = iocb->ki_filp;
-	int			ioflags = IO_ISAIO;
+	int			ioflags = 0;
 
 	BUG_ON(iocb->ki_pos != pos);
 	if (unlikely(file->f_flags & O_DIRECT))
@@ -71,7 +71,7 @@
 	loff_t			pos)
 {
 	struct file		*file = iocb->ki_filp;
-	int			ioflags = IO_ISAIO;
+	int			ioflags = 0;
 
 	BUG_ON(iocb->ki_pos != pos);
 	if (unlikely(file->f_flags & O_DIRECT))
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index cd42ef7..1f3b4b8 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -573,8 +573,8 @@
 	bf.l_len = len;
 
 	xfs_ilock(ip, XFS_IOLOCK_EXCL);
-	error = xfs_change_file_space(ip, XFS_IOC_RESVSP, &bf,
-				      0, XFS_ATTR_NOLOCK);
+	error = -xfs_change_file_space(ip, XFS_IOC_RESVSP, &bf,
+				       0, XFS_ATTR_NOLOCK);
 	if (!error && !(mode & FALLOC_FL_KEEP_SIZE) &&
 	    offset + len > i_size_read(inode))
 		new_size = offset + len;
@@ -585,7 +585,7 @@
 
 		iattr.ia_valid = ATTR_SIZE;
 		iattr.ia_size = new_size;
-		error = xfs_setattr(ip, &iattr, XFS_ATTR_NOLOCK);
+		error = -xfs_setattr(ip, &iattr, XFS_ATTR_NOLOCK);
 	}
 
 	xfs_iunlock(ip, XFS_IOLOCK_EXCL);
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 072050f..1bf47f2 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -255,8 +255,6 @@
 
 	iocb->ki_pos = *offset;
 	ret = generic_file_aio_read(iocb, iovp, segs, *offset);
-	if (ret == -EIOCBQUEUED && !(ioflags & IO_ISAIO))
-		ret = wait_on_sync_kiocb(iocb);
 	if (ret > 0)
 		XFS_STATS_ADD(xs_read_bytes, ret);
 
@@ -774,9 +772,6 @@
 
 	current->backing_dev_info = NULL;
 
-	if (ret == -EIOCBQUEUED && !(ioflags & IO_ISAIO))
-		ret = wait_on_sync_kiocb(iocb);
-
 	isize = i_size_read(inode);
 	if (unlikely(ret < 0 && ret != -EFAULT && *offset > isize))
 		*offset = isize;
@@ -811,7 +806,7 @@
 	XFS_STATS_ADD(xs_write_bytes, ret);
 
 	/* Handle various SYNC-type writes */
-	if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) {
+	if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) {
 		loff_t end = pos + ret - 1;
 		int error2;
 
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 18a4b8e..1bfb0e9 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -930,13 +930,39 @@
  */
 STATIC void
 xfs_fs_destroy_inode(
-	struct inode	*inode)
+	struct inode		*inode)
 {
-	xfs_inode_t		*ip = XFS_I(inode);
+	struct xfs_inode	*ip = XFS_I(inode);
+
+	xfs_itrace_entry(ip);
 
 	XFS_STATS_INC(vn_reclaim);
-	if (xfs_reclaim(ip))
-		panic("%s: cannot reclaim 0x%p\n", __func__, inode);
+
+	/* bad inode, get out here ASAP */
+	if (is_bad_inode(inode))
+		goto out_reclaim;
+
+	xfs_ioend_wait(ip);
+
+	ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0);
+
+	/*
+	 * We should never get here with one of the reclaim flags already set.
+	 */
+	ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_IRECLAIMABLE));
+	ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_IRECLAIM));
+
+	/*
+	 * If we have nothing to flush with this inode then complete the
+	 * teardown now, otherwise delay the flush operation.
+	 */
+	if (!xfs_inode_clean(ip)) {
+		xfs_inode_set_reclaim_tag(ip);
+		return;
+	}
+
+out_reclaim:
+	xfs_ireclaim(ip);
 }
 
 /*
@@ -973,7 +999,6 @@
 
 	mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER,
 		     "xfsino", ip->i_ino);
-	mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
 }
 
 /*
@@ -1075,6 +1100,20 @@
 	XFS_STATS_INC(vn_remove);
 	XFS_STATS_DEC(vn_active);
 
+	/*
+	 * The iolock is used by the file system to coordinate reads,
+	 * writes, and block truncates.  Up to this point the lock
+	 * protected concurrent accesses by users of the inode.  But
+	 * from here forward we're doing some final processing of the
+	 * inode because we're done with it, and although we reuse the
+	 * iolock for protection it is really a distinct lock class
+	 * (in the lockdep sense) from before.  To keep lockdep happy
+	 * (and basically indicate what we are doing), we explicitly
+	 * re-init the iolock here.
+	 */
+	ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock));
+	mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
+
 	xfs_inactive(ip);
 }
 
@@ -1092,8 +1131,6 @@
 	struct super_block	*sb)
 {
 	struct xfs_mount	*mp = XFS_M(sb);
-	struct xfs_inode	*rip = mp->m_rootip;
-	int			unmount_event_flags = 0;
 
 	xfs_syncd_stop(mp);
 
@@ -1109,20 +1146,7 @@
 		xfs_sync_attr(mp, 0);
 	}
 
-#ifdef HAVE_DMAPI
-	if (mp->m_flags & XFS_MOUNT_DMAPI) {
-		unmount_event_flags =
-			(mp->m_dmevmask & (1 << DM_EVENT_UNMOUNT)) ?
-				0 : DM_FLAGS_UNWANTED;
-		/*
-		 * Ignore error from dmapi here, first unmount is not allowed
-		 * to fail anyway, and second we wouldn't want to fail a
-		 * unmount because of dmapi.
-		 */
-		XFS_SEND_PREUNMOUNT(mp, rip, DM_RIGHT_NULL, rip, DM_RIGHT_NULL,
-				NULL, NULL, 0, 0, unmount_event_flags);
-	}
-#endif
+	XFS_SEND_PREUNMOUNT(mp);
 
 	/*
 	 * Blow away any referenced inode in the filestreams cache.
@@ -1133,10 +1157,7 @@
 
 	XFS_bflush(mp->m_ddev_targp);
 
-	if (mp->m_flags & XFS_MOUNT_DMAPI) {
-		XFS_SEND_UNMOUNT(mp, rip, DM_RIGHT_NULL, 0, 0,
-				unmount_event_flags);
-	}
+	XFS_SEND_UNMOUNT(mp);
 
 	xfs_unmountfs(mp);
 	xfs_freesb(mp);
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c
index 961df0a..d895a3a 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/linux-2.6/xfs_sync.c
@@ -663,10 +663,9 @@
 	kthread_stop(mp->m_sync_task);
 }
 
-int
+STATIC int
 xfs_reclaim_inode(
 	xfs_inode_t	*ip,
-	int		locked,
 	int		sync_mode)
 {
 	xfs_perag_t	*pag = xfs_get_perag(ip->i_mount, ip->i_ino);
@@ -682,10 +681,6 @@
 	    !__xfs_iflags_test(ip, XFS_IRECLAIMABLE)) {
 		spin_unlock(&ip->i_flags_lock);
 		write_unlock(&pag->pag_ici_lock);
-		if (locked) {
-			xfs_ifunlock(ip);
-			xfs_iunlock(ip, XFS_ILOCK_EXCL);
-		}
 		return -EAGAIN;
 	}
 	__xfs_iflags_set(ip, XFS_IRECLAIM);
@@ -704,10 +699,8 @@
 	 * We get the flush lock regardless, though, just to make sure
 	 * we don't free it while it is being flushed.
 	 */
-	if (!locked) {
-		xfs_ilock(ip, XFS_ILOCK_EXCL);
-		xfs_iflock(ip);
-	}
+	xfs_ilock(ip, XFS_ILOCK_EXCL);
+	xfs_iflock(ip);
 
 	/*
 	 * In the case of a forced shutdown we rely on xfs_iflush() to
@@ -778,7 +771,7 @@
 	}
 	read_unlock(&pag->pag_ici_lock);
 
-	return xfs_reclaim_inode(ip, 0, flags);
+	return xfs_reclaim_inode(ip, flags);
 }
 
 int
diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/linux-2.6/xfs_sync.h
index 27920eb..a500b4d 100644
--- a/fs/xfs/linux-2.6/xfs_sync.h
+++ b/fs/xfs/linux-2.6/xfs_sync.h
@@ -44,7 +44,6 @@
 
 void xfs_flush_inodes(struct xfs_inode *ip);
 
-int xfs_reclaim_inode(struct xfs_inode *ip, int locked, int sync_mode);
 int xfs_reclaim_inodes(struct xfs_mount *mp, int mode);
 
 void xfs_inode_set_reclaim_tag(struct xfs_inode *ip);
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index ad7fbea..00cabf5 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -36,7 +36,6 @@
 /*
  * Flags for read/write calls - same values as IRIX
  */
-#define IO_ISAIO	0x00001		/* don't wait for completion */
 #define IO_ISDIRECT	0x00004		/* bypass page cache */
 #define IO_INVIS	0x00020		/* don't update inode timestamps */
 
diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h
index 6533ead..a2c16bc 100644
--- a/fs/xfs/quota/xfs_dquot.h
+++ b/fs/xfs/quota/xfs_dquot.h
@@ -98,7 +98,7 @@
 #define dq_flags	q_lists.dqm_flags
 
 /*
- * Lock hierachy for q_qlock:
+ * Lock hierarchy for q_qlock:
  *	XFS_QLOCK_NORMAL is the implicit default,
  * 	XFS_QLOCK_NESTED is the dquot with the higher id in xfs_dqlock2
  */
diff --git a/fs/xfs/support/debug.h b/fs/xfs/support/debug.h
index 6f4fd37..d2d2046 100644
--- a/fs/xfs/support/debug.h
+++ b/fs/xfs/support/debug.h
@@ -41,10 +41,6 @@
 # define STATIC static noinline
 #endif
 
-#ifndef STATIC_INLINE
-# define STATIC_INLINE static inline
-#endif
-
 #else /* DEBUG */
 
 #define ASSERT(expr)	\
@@ -54,19 +50,5 @@
 # define STATIC noinline
 #endif
 
-/*
- * We stop inlining of inline functions in debug mode.
- * Unfortunately, this means static inline in header files
- * get multiple definitions, so they need to remain static.
- * This then gives tonnes of warnings about unused but defined
- * functions, so we need to add the unused attribute to prevent
- * these spurious warnings.
- */
-#ifndef STATIC_INLINE
-# define STATIC_INLINE static __attribute__ ((unused)) noinline
-#endif
-
 #endif /* DEBUG */
-
-
 #endif  /* __XFS_SUPPORT_DEBUG_H__ */
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index 4ece190..8fe6f6b 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -123,9 +123,13 @@
  * Overall external interface routines.
  *========================================================================*/
 
-int
-xfs_attr_fetch(xfs_inode_t *ip, struct xfs_name *name,
-		char *value, int *valuelenp, int flags)
+STATIC int
+xfs_attr_get_int(
+	struct xfs_inode	*ip,
+	struct xfs_name		*name,
+	char			*value,
+	int			*valuelenp,
+	int			flags)
 {
 	xfs_da_args_t   args;
 	int             error;
@@ -188,7 +192,7 @@
 		return error;
 
 	xfs_ilock(ip, XFS_ILOCK_SHARED);
-	error = xfs_attr_fetch(ip, &xname, value, valuelenp, flags);
+	error = xfs_attr_get_int(ip, &xname, value, valuelenp, flags);
 	xfs_iunlock(ip, XFS_ILOCK_SHARED);
 	return(error);
 }
@@ -2143,8 +2147,8 @@
 		dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock),
 		blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount);
 
-		bp = xfs_buf_get_flags(mp->m_ddev_targp, dblkno, blkcnt,
-				       XFS_BUF_LOCK | XBF_DONT_BLOCK);
+		bp = xfs_buf_get(mp->m_ddev_targp, dblkno, blkcnt,
+				 XFS_BUF_LOCK | XBF_DONT_BLOCK);
 		ASSERT(bp);
 		ASSERT(!XFS_BUF_GETERROR(bp));
 
diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h
index fb3b2a6..12f0be3 100644
--- a/fs/xfs/xfs_attr.h
+++ b/fs/xfs/xfs_attr.h
@@ -131,7 +131,6 @@
  */
 int xfs_attr_calc_size(struct xfs_inode *, int, int, int *);
 int xfs_attr_inactive(struct xfs_inode *dp);
-int xfs_attr_fetch(struct xfs_inode *, struct xfs_name *, char *, int *, int);
 int xfs_attr_rmtval_get(struct xfs_da_args *args);
 int xfs_attr_list_int(struct xfs_attr_list_context *);
 
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index afdc891..0b68735 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -98,7 +98,7 @@
  * If namespace bits don't match return 0.
  * If all match then return 1.
  */
-STATIC_INLINE int
+STATIC int
 xfs_attr_namesp_match(int arg_flags, int ondisk_flags)
 {
 	return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags);
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
index eb7b702..6f5cced 100644
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -98,8 +98,7 @@
  * This code must be in sync with the routines xfs_bmbt_get_startoff,
  * xfs_bmbt_get_startblock, xfs_bmbt_get_blockcount and xfs_bmbt_get_state.
  */
-
-STATIC_INLINE void
+STATIC void
 __xfs_bmbt_get_all(
 		__uint64_t l0,
 		__uint64_t l1,
diff --git a/fs/xfs/xfs_filestream.h b/fs/xfs/xfs_filestream.h
index f655f7d..4aba67c 100644
--- a/fs/xfs/xfs_filestream.h
+++ b/fs/xfs/xfs_filestream.h
@@ -79,7 +79,7 @@
  * the cache that reference per-ag array elements that have since been
  * reallocated.
  */
-STATIC_INLINE int
+static inline int
 xfs_filestream_peek_ag(
 	xfs_mount_t	*mp,
 	xfs_agnumber_t	agno)
@@ -87,7 +87,7 @@
 	return atomic_read(&mp->m_perag[agno].pagf_fstrms);
 }
 
-STATIC_INLINE int
+static inline int
 xfs_filestream_get_ag(
 	xfs_mount_t	*mp,
 	xfs_agnumber_t	agno)
@@ -95,7 +95,7 @@
 	return atomic_inc_return(&mp->m_perag[agno].pagf_fstrms);
 }
 
-STATIC_INLINE int
+static inline int
 xfs_filestream_put_ag(
 	xfs_mount_t	*mp,
 	xfs_agnumber_t	agno)
@@ -122,7 +122,7 @@
 
 
 /* filestreams for the inode? */
-STATIC_INLINE int
+static inline int
 xfs_inode_is_filestream(
 	struct xfs_inode	*ip)
 {
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 2d0b3e1..36079aa 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -201,8 +201,8 @@
 		 * AG freelist header block
 		 */
 		bp = xfs_buf_get(mp->m_ddev_targp,
-				  XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
-				  XFS_FSS_TO_BB(mp, 1), 0);
+				 XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
+				 XFS_FSS_TO_BB(mp, 1), XBF_LOCK | XBF_MAPPED);
 		agf = XFS_BUF_TO_AGF(bp);
 		memset(agf, 0, mp->m_sb.sb_sectsize);
 		agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC);
@@ -233,8 +233,8 @@
 		 * AG inode header block
 		 */
 		bp = xfs_buf_get(mp->m_ddev_targp,
-				  XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
-				  XFS_FSS_TO_BB(mp, 1), 0);
+				 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
+				 XFS_FSS_TO_BB(mp, 1), XBF_LOCK | XBF_MAPPED);
 		agi = XFS_BUF_TO_AGI(bp);
 		memset(agi, 0, mp->m_sb.sb_sectsize);
 		agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC);
@@ -257,8 +257,9 @@
 		 * BNO btree root block
 		 */
 		bp = xfs_buf_get(mp->m_ddev_targp,
-			XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp)),
-			BTOBB(mp->m_sb.sb_blocksize), 0);
+				 XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp)),
+				 BTOBB(mp->m_sb.sb_blocksize),
+				 XBF_LOCK | XBF_MAPPED);
 		block = XFS_BUF_TO_BLOCK(bp);
 		memset(block, 0, mp->m_sb.sb_blocksize);
 		block->bb_magic = cpu_to_be32(XFS_ABTB_MAGIC);
@@ -278,8 +279,9 @@
 		 * CNT btree root block
 		 */
 		bp = xfs_buf_get(mp->m_ddev_targp,
-			XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp)),
-			BTOBB(mp->m_sb.sb_blocksize), 0);
+				 XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp)),
+				 BTOBB(mp->m_sb.sb_blocksize),
+				 XBF_LOCK | XBF_MAPPED);
 		block = XFS_BUF_TO_BLOCK(bp);
 		memset(block, 0, mp->m_sb.sb_blocksize);
 		block->bb_magic = cpu_to_be32(XFS_ABTC_MAGIC);
@@ -300,8 +302,9 @@
 		 * INO btree root block
 		 */
 		bp = xfs_buf_get(mp->m_ddev_targp,
-			XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp)),
-			BTOBB(mp->m_sb.sb_blocksize), 0);
+				 XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp)),
+				 BTOBB(mp->m_sb.sb_blocksize),
+				 XBF_LOCK | XBF_MAPPED);
 		block = XFS_BUF_TO_BLOCK(bp);
 		memset(block, 0, mp->m_sb.sb_blocksize);
 		block->bb_magic = cpu_to_be32(XFS_IBT_MAGIC);
@@ -611,7 +614,7 @@
 	xfs_inode_t	*ip;
 	int		error;
 
-	tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1);
+	tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1, KM_SLEEP);
 	error = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0);
 	if (error) {
 		xfs_trans_cancel(tp, 0);
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index 0785797..cb907ba 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -425,7 +425,7 @@
 	return 0;
 }
 
-STATIC_INLINE xfs_agnumber_t
+STATIC xfs_agnumber_t
 xfs_ialloc_next_ag(
 	xfs_mount_t	*mp)
 {
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index 80e5264..073bb4a 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -73,6 +73,9 @@
 	ASSERT(atomic_read(&ip->i_pincount) == 0);
 	ASSERT(!spin_is_locked(&ip->i_flags_lock));
 	ASSERT(completion_done(&ip->i_flush));
+	ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock));
+
+	mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
 
 	/* initialise the xfs inode */
 	ip->i_ino = ino;
@@ -290,7 +293,7 @@
 	struct xfs_inode	**ipp,
 	xfs_daddr_t		bno,
 	int			flags,
-	int			lock_flags) __releases(pag->pag_ici_lock)
+	int			lock_flags)
 {
 	struct xfs_inode	*ip;
 	int			error;
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 67ae5555..7294abc 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -860,8 +860,15 @@
 		 * set up a transaction to convert the range of extents
 		 * from unwritten to real. Do allocations in a loop until
 		 * we have covered the range passed in.
+		 *
+		 * Note that we open code the transaction allocation here
+		 * to pass KM_NOFS--we can't risk to recursing back into
+		 * the filesystem here as we might be asked to write out
+		 * the same inode that we complete here and might deadlock
+		 * on the iolock.
 		 */
-		tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE);
+		xfs_wait_for_freeze(mp, SB_FREEZE_TRANS);
+		tp = _xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE, KM_NOFS);
 		tp->t_flags |= XFS_TRANS_RESERVE;
 		error = xfs_trans_reserve(tp, resblks,
 				XFS_WRITE_LOG_RES(mp), 0,
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index fb17f82..1ec98ed 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -2206,6 +2206,7 @@
 	xfs_daddr_t		blkno;
 	int			len;
 	ushort			flags;
+	uint			buf_flags;
 
 	buf_f = (xfs_buf_log_format_t *)item->ri_buf[0].i_addr;
 
@@ -2246,12 +2247,11 @@
 	}
 
 	mp = log->l_mp;
-	if (flags & XFS_BLI_INODE_BUF) {
-		bp = xfs_buf_read_flags(mp->m_ddev_targp, blkno, len,
-								XFS_BUF_LOCK);
-	} else {
-		bp = xfs_buf_read(mp->m_ddev_targp, blkno, len, 0);
-	}
+	buf_flags = XFS_BUF_LOCK;
+	if (!(flags & XFS_BLI_INODE_BUF))
+		buf_flags |= XFS_BUF_MAPPED;
+
+	bp = xfs_buf_read(mp->m_ddev_targp, blkno, len, buf_flags);
 	if (XFS_BUF_ISERROR(bp)) {
 		xfs_ioerror_alert("xlog_recover_do..(read#1)", log->l_mp,
 				  bp, blkno);
@@ -2350,8 +2350,8 @@
 		goto error;
 	}
 
-	bp = xfs_buf_read_flags(mp->m_ddev_targp, in_f->ilf_blkno,
-				in_f->ilf_len, XFS_BUF_LOCK);
+	bp = xfs_buf_read(mp->m_ddev_targp, in_f->ilf_blkno, in_f->ilf_len,
+			  XFS_BUF_LOCK);
 	if (XFS_BUF_ISERROR(bp)) {
 		xfs_ioerror_alert("xlog_recover_do..(read#2)", mp,
 				  bp, in_f->ilf_blkno);
@@ -3517,7 +3517,7 @@
 {
 	xlog_rec_header_t	*rhead;
 	xfs_daddr_t		blk_no;
-	xfs_caddr_t		bufaddr, offset;
+	xfs_caddr_t		offset;
 	xfs_buf_t		*hbp, *dbp;
 	int			error = 0, h_size;
 	int			bblks, split_bblks;
@@ -3610,7 +3610,7 @@
 			/*
 			 * Check for header wrapping around physical end-of-log
 			 */
-			offset = NULL;
+			offset = XFS_BUF_PTR(hbp);
 			split_hblks = 0;
 			wrapped_hblks = 0;
 			if (blk_no + hblks <= log->l_logBBsize) {
@@ -3646,9 +3646,8 @@
 				 *   - order is important.
 				 */
 				wrapped_hblks = hblks - split_hblks;
-				bufaddr = XFS_BUF_PTR(hbp);
 				error = XFS_BUF_SET_PTR(hbp,
-						bufaddr + BBTOB(split_hblks),
+						offset + BBTOB(split_hblks),
 						BBTOB(hblks - split_hblks));
 				if (error)
 					goto bread_err2;
@@ -3658,14 +3657,10 @@
 				if (error)
 					goto bread_err2;
 
-				error = XFS_BUF_SET_PTR(hbp, bufaddr,
+				error = XFS_BUF_SET_PTR(hbp, offset,
 							BBTOB(hblks));
 				if (error)
 					goto bread_err2;
-
-				if (!offset)
-					offset = xlog_align(log, 0,
-							wrapped_hblks, hbp);
 			}
 			rhead = (xlog_rec_header_t *)offset;
 			error = xlog_valid_rec_header(log, rhead,
@@ -3685,7 +3680,7 @@
 			} else {
 				/* This log record is split across the
 				 * physical end of log */
-				offset = NULL;
+				offset = XFS_BUF_PTR(dbp);
 				split_bblks = 0;
 				if (blk_no != log->l_logBBsize) {
 					/* some data is before the physical
@@ -3714,9 +3709,8 @@
 				 *   _first_, then the log start (LR header end)
 				 *   - order is important.
 				 */
-				bufaddr = XFS_BUF_PTR(dbp);
 				error = XFS_BUF_SET_PTR(dbp,
-						bufaddr + BBTOB(split_bblks),
+						offset + BBTOB(split_bblks),
 						BBTOB(bblks - split_bblks));
 				if (error)
 					goto bread_err2;
@@ -3727,13 +3721,9 @@
 				if (error)
 					goto bread_err2;
 
-				error = XFS_BUF_SET_PTR(dbp, bufaddr, h_size);
+				error = XFS_BUF_SET_PTR(dbp, offset, h_size);
 				if (error)
 					goto bread_err2;
-
-				if (!offset)
-					offset = xlog_align(log, wrapped_hblks,
-						bblks - split_bblks, dbp);
 			}
 			xlog_unpack_data(rhead, offset, log);
 			if ((error = xlog_recover_process_data(log, rhash,
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 8b6c9e8..66a888a 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -583,8 +583,8 @@
 	sector_size = xfs_getsize_buftarg(mp->m_ddev_targp);
 	extra_flags = XFS_BUF_LOCK | XFS_BUF_MANAGE | XFS_BUF_MAPPED;
 
-	bp = xfs_buf_read_flags(mp->m_ddev_targp, XFS_SB_DADDR,
-				BTOBB(sector_size), extra_flags);
+	bp = xfs_buf_read(mp->m_ddev_targp, XFS_SB_DADDR, BTOBB(sector_size),
+			  extra_flags);
 	if (!bp || XFS_BUF_ISERROR(bp)) {
 		xfs_fs_mount_cmn_err(flags, "SB read failed");
 		error = bp ? XFS_BUF_GETERROR(bp) : ENOMEM;
@@ -624,8 +624,8 @@
 		XFS_BUF_UNMANAGE(bp);
 		xfs_buf_relse(bp);
 		sector_size = mp->m_sb.sb_sectsize;
-		bp = xfs_buf_read_flags(mp->m_ddev_targp, XFS_SB_DADDR,
-					BTOBB(sector_size), extra_flags);
+		bp = xfs_buf_read(mp->m_ddev_targp, XFS_SB_DADDR,
+				  BTOBB(sector_size), extra_flags);
 		if (!bp || XFS_BUF_ISERROR(bp)) {
 			xfs_fs_mount_cmn_err(flags, "SB re-read failed");
 			error = bp ? XFS_BUF_GETERROR(bp) : ENOMEM;
@@ -1471,7 +1471,7 @@
 	if (!xfs_sb_version_haslazysbcount(&mp->m_sb))
 		return 0;
 
-	tp = _xfs_trans_alloc(mp, XFS_TRANS_SB_COUNT);
+	tp = _xfs_trans_alloc(mp, XFS_TRANS_SB_COUNT, KM_SLEEP);
 	error = xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0,
 					XFS_DEFAULT_LOG_COUNT);
 	if (error) {
@@ -2123,7 +2123,7 @@
 	mutex_destroy(&mp->m_icsb_mutex);
 }
 
-STATIC_INLINE void
+STATIC void
 xfs_icsb_lock_cntr(
 	xfs_icsb_cnts_t	*icsbp)
 {
@@ -2132,7 +2132,7 @@
 	}
 }
 
-STATIC_INLINE void
+STATIC void
 xfs_icsb_unlock_cntr(
 	xfs_icsb_cnts_t	*icsbp)
 {
@@ -2140,7 +2140,7 @@
 }
 
 
-STATIC_INLINE void
+STATIC void
 xfs_icsb_lock_all_counters(
 	xfs_mount_t	*mp)
 {
@@ -2153,7 +2153,7 @@
 	}
 }
 
-STATIC_INLINE void
+STATIC void
 xfs_icsb_unlock_all_counters(
 	xfs_mount_t	*mp)
 {
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index a6c023b..1df7e45 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -93,6 +93,9 @@
 	xfs_send_unmount_t	xfs_send_unmount;
 } xfs_dmops_t;
 
+#define XFS_DMAPI_UNMOUNT_FLAGS(mp) \
+	(((mp)->m_dmevmask & (1 << DM_EVENT_UNMOUNT)) ? 0 : DM_FLAGS_UNWANTED)
+
 #define XFS_SEND_DATA(mp, ev,ip,off,len,fl,lock) \
 	(*(mp)->m_dm_ops->xfs_send_data)(ev,ip,off,len,fl,lock)
 #define XFS_SEND_MMAP(mp, vma,fl) \
@@ -101,12 +104,24 @@
 	(*(mp)->m_dm_ops->xfs_send_destroy)(ip,right)
 #define XFS_SEND_NAMESP(mp, ev,b1,r1,b2,r2,n1,n2,mode,rval,fl) \
 	(*(mp)->m_dm_ops->xfs_send_namesp)(ev,NULL,b1,r1,b2,r2,n1,n2,mode,rval,fl)
-#define XFS_SEND_PREUNMOUNT(mp,b1,r1,b2,r2,n1,n2,mode,rval,fl) \
-	(*(mp)->m_dm_ops->xfs_send_namesp)(DM_EVENT_PREUNMOUNT,mp,b1,r1,b2,r2,n1,n2,mode,rval,fl)
 #define XFS_SEND_MOUNT(mp,right,path,name) \
 	(*(mp)->m_dm_ops->xfs_send_mount)(mp,right,path,name)
-#define XFS_SEND_UNMOUNT(mp, ip,right,mode,rval,fl) \
-	(*(mp)->m_dm_ops->xfs_send_unmount)(mp,ip,right,mode,rval,fl)
+#define XFS_SEND_PREUNMOUNT(mp) \
+do { \
+	if (mp->m_flags & XFS_MOUNT_DMAPI) { \
+		(*(mp)->m_dm_ops->xfs_send_namesp)(DM_EVENT_PREUNMOUNT, mp, \
+			(mp)->m_rootip, DM_RIGHT_NULL, \
+			(mp)->m_rootip, DM_RIGHT_NULL, \
+			NULL, NULL, 0, 0, XFS_DMAPI_UNMOUNT_FLAGS(mp)); \
+	} \
+} while (0)
+#define XFS_SEND_UNMOUNT(mp) \
+do { \
+	if (mp->m_flags & XFS_MOUNT_DMAPI) { \
+		(*(mp)->m_dm_ops->xfs_send_unmount)(mp, (mp)->m_rootip, \
+			DM_RIGHT_NULL, 0, 0, XFS_DMAPI_UNMOUNT_FLAGS(mp)); \
+	} \
+} while (0)
 
 
 #ifdef HAVE_PERCPU_SB
@@ -387,13 +402,13 @@
  * Per-cpu superblock locking functions
  */
 #ifdef HAVE_PERCPU_SB
-STATIC_INLINE void
+static inline void
 xfs_icsb_lock(xfs_mount_t *mp)
 {
 	mutex_lock(&mp->m_icsb_mutex);
 }
 
-STATIC_INLINE void
+static inline void
 xfs_icsb_unlock(xfs_mount_t *mp)
 {
 	mutex_unlock(&mp->m_icsb_mutex);
diff --git a/fs/xfs/xfs_rw.c b/fs/xfs/xfs_rw.c
index 3f816ad..4c199d1 100644
--- a/fs/xfs/xfs_rw.c
+++ b/fs/xfs/xfs_rw.c
@@ -277,10 +277,10 @@
 	xfs_buf_t	 *bp;
 	int		 error;
 
-	if (flags)
-		bp = xfs_buf_read_flags(target, blkno, len, flags);
-	else
-		bp = xfs_buf_read(target, blkno, len, flags);
+	if (!flags)
+		flags = XBF_LOCK | XBF_MAPPED;
+
+	bp = xfs_buf_read(target, blkno, len, flags);
 	if (!bp)
 		return XFS_ERROR(EIO);
 	error = XFS_BUF_GETERROR(bp);
@@ -336,3 +336,25 @@
 	}
 	return (error);
 }
+
+/*
+ * helper function to extract extent size hint from inode
+ */
+xfs_extlen_t
+xfs_get_extsz_hint(
+	struct xfs_inode	*ip)
+{
+	xfs_extlen_t		extsz;
+
+	if (unlikely(XFS_IS_REALTIME_INODE(ip))) {
+		extsz = (ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE)
+				? ip->i_d.di_extsize
+				: ip->i_mount->m_sb.sb_rextsize;
+		ASSERT(extsz);
+	} else {
+		extsz = (ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE)
+				? ip->i_d.di_extsize : 0;
+	}
+
+	return extsz;
+}
diff --git a/fs/xfs/xfs_rw.h b/fs/xfs/xfs_rw.h
index f5e4874..571f217 100644
--- a/fs/xfs/xfs_rw.h
+++ b/fs/xfs/xfs_rw.h
@@ -37,34 +37,6 @@
 }
 
 /*
- * Flags for xfs_free_eofblocks
- */
-#define XFS_FREE_EOF_LOCK	(1<<0)
-#define XFS_FREE_EOF_NOLOCK	(1<<1)
-
-
-/*
- * helper function to extract extent size hint from inode
- */
-STATIC_INLINE xfs_extlen_t
-xfs_get_extsz_hint(
-	xfs_inode_t	*ip)
-{
-	xfs_extlen_t	extsz;
-
-	if (unlikely(XFS_IS_REALTIME_INODE(ip))) {
-		extsz = (ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE)
-				? ip->i_d.di_extsize
-				: ip->i_mount->m_sb.sb_rextsize;
-		ASSERT(extsz);
-	} else {
-		extsz = (ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE)
-				? ip->i_d.di_extsize : 0;
-	}
-	return extsz;
-}
-
-/*
  * Prototypes for functions in xfs_rw.c.
  */
 extern int xfs_write_clear_setuid(struct xfs_inode *ip);
@@ -76,5 +48,6 @@
 			struct xfs_buf **bpp);
 extern void xfs_ioerror_alert(char *func, struct xfs_mount *mp,
 				xfs_buf_t *bp, xfs_daddr_t blkno);
+extern xfs_extlen_t xfs_get_extsz_hint(struct xfs_inode *ip);
 
 #endif /* __XFS_RW_H__ */
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 66b8493..237badc 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -236,19 +236,20 @@
 	uint		type)
 {
 	xfs_wait_for_freeze(mp, SB_FREEZE_TRANS);
-	return _xfs_trans_alloc(mp, type);
+	return _xfs_trans_alloc(mp, type, KM_SLEEP);
 }
 
 xfs_trans_t *
 _xfs_trans_alloc(
 	xfs_mount_t	*mp,
-	uint		type)
+	uint		type,
+	uint		memflags)
 {
 	xfs_trans_t	*tp;
 
 	atomic_inc(&mp->m_active_trans);
 
-	tp = kmem_zone_zalloc(xfs_trans_zone, KM_SLEEP);
+	tp = kmem_zone_zalloc(xfs_trans_zone, memflags);
 	tp->t_magic = XFS_TRANS_MAGIC;
 	tp->t_type = type;
 	tp->t_mountp = mp;
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index ed47fc7..a0574f5 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -924,7 +924,7 @@
  * XFS transaction mechanism exported interfaces.
  */
 xfs_trans_t	*xfs_trans_alloc(struct xfs_mount *, uint);
-xfs_trans_t	*_xfs_trans_alloc(struct xfs_mount *, uint);
+xfs_trans_t	*_xfs_trans_alloc(struct xfs_mount *, uint, uint);
 xfs_trans_t	*xfs_trans_dup(xfs_trans_t *);
 int		xfs_trans_reserve(xfs_trans_t *, uint, uint, uint,
 				  uint, uint);
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
index 218829e..03a1f70 100644
--- a/fs/xfs/xfs_trans_buf.c
+++ b/fs/xfs/xfs_trans_buf.c
@@ -79,11 +79,8 @@
 	/*
 	 * Default to a normal get_buf() call if the tp is NULL.
 	 */
-	if (tp == NULL) {
-		bp = xfs_buf_get_flags(target_dev, blkno, len,
-							flags | BUF_BUSY);
-		return(bp);
-	}
+	if (tp == NULL)
+		return xfs_buf_get(target_dev, blkno, len, flags | BUF_BUSY);
 
 	/*
 	 * If we find the buffer in the cache with this transaction
@@ -129,7 +126,7 @@
 	 * easily deadlock with our current transaction as well as cause
 	 * us to run out of stack space.
 	 */
-	bp = xfs_buf_get_flags(target_dev, blkno, len, flags | BUF_BUSY);
+	bp = xfs_buf_get(target_dev, blkno, len, flags | BUF_BUSY);
 	if (bp == NULL) {
 		return NULL;
 	}
@@ -302,7 +299,7 @@
 	 * Default to a normal get_buf() call if the tp is NULL.
 	 */
 	if (tp == NULL) {
-		bp = xfs_buf_read_flags(target, blkno, len, flags | BUF_BUSY);
+		bp = xfs_buf_read(target, blkno, len, flags | BUF_BUSY);
 		if (!bp)
 			return (flags & XFS_BUF_TRYLOCK) ?
 					EAGAIN : XFS_ERROR(ENOMEM);
@@ -398,7 +395,7 @@
 	 * easily deadlock with our current transaction as well as cause
 	 * us to run out of stack space.
 	 */
-	bp = xfs_buf_read_flags(target, blkno, len, flags | BUF_BUSY);
+	bp = xfs_buf_read(target, blkno, len, flags | BUF_BUSY);
 	if (bp == NULL) {
 		*bpp = NULL;
 		return 0;
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index b572f7e..578f3f5 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -538,9 +538,8 @@
 		d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
 		byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
 
-		bp = xfs_buf_read_flags(mp->m_ddev_targp, d, BTOBB(byte_cnt),
-					XBF_LOCK | XBF_MAPPED |
-					XBF_DONT_BLOCK);
+		bp = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt),
+				  XBF_LOCK | XBF_MAPPED | XBF_DONT_BLOCK);
 		error = XFS_BUF_GETERROR(bp);
 		if (error) {
 			xfs_ioerror_alert("xfs_readlink",
@@ -709,6 +708,11 @@
 }
 
 /*
+ * Flags for xfs_free_eofblocks
+ */
+#define XFS_FREE_EOF_TRYLOCK	(1<<0)
+
+/*
  * This is called by xfs_inactive to free any blocks beyond eof
  * when the link count isn't zero and by xfs_dm_punch_hole() when
  * punching a hole to EOF.
@@ -726,7 +730,6 @@
 	xfs_filblks_t	map_len;
 	int		nimaps;
 	xfs_bmbt_irec_t	imap;
-	int		use_iolock = (flags & XFS_FREE_EOF_LOCK);
 
 	/*
 	 * Figure out if there are any blocks beyond the end
@@ -768,14 +771,19 @@
 		 * cache and we can't
 		 * do that within a transaction.
 		 */
-		if (use_iolock)
+		if (flags & XFS_FREE_EOF_TRYLOCK) {
+			if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) {
+				xfs_trans_cancel(tp, 0);
+				return 0;
+			}
+		} else {
 			xfs_ilock(ip, XFS_IOLOCK_EXCL);
+		}
 		error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE,
 				    ip->i_size);
 		if (error) {
 			xfs_trans_cancel(tp, 0);
-			if (use_iolock)
-				xfs_iunlock(ip, XFS_IOLOCK_EXCL);
+			xfs_iunlock(ip, XFS_IOLOCK_EXCL);
 			return error;
 		}
 
@@ -812,8 +820,7 @@
 			error = xfs_trans_commit(tp,
 						XFS_TRANS_RELEASE_LOG_RES);
 		}
-		xfs_iunlock(ip, (use_iolock ? (XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL)
-					    : XFS_ILOCK_EXCL));
+		xfs_iunlock(ip, XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL);
 	}
 	return error;
 }
@@ -1113,7 +1120,17 @@
 		     (ip->i_df.if_flags & XFS_IFEXTENTS))  &&
 		    (!(ip->i_d.di_flags &
 				(XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)))) {
-			error = xfs_free_eofblocks(mp, ip, XFS_FREE_EOF_LOCK);
+
+			/*
+			 * If we can't get the iolock just skip truncating
+			 * the blocks past EOF because we could deadlock
+			 * with the mmap_sem otherwise.  We'll get another
+			 * chance to drop them once the last reference to
+			 * the inode is dropped, so we'll never leak blocks
+			 * permanently.
+			 */
+			error = xfs_free_eofblocks(mp, ip,
+						   XFS_FREE_EOF_TRYLOCK);
 			if (error)
 				return error;
 		}
@@ -1184,7 +1201,7 @@
 		     (!(ip->i_d.di_flags &
 				(XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) ||
 		      (ip->i_delayed_blks != 0)))) {
-			error = xfs_free_eofblocks(mp, ip, XFS_FREE_EOF_LOCK);
+			error = xfs_free_eofblocks(mp, ip, 0);
 			if (error)
 				return VN_INACTIVE_CACHE;
 		}
@@ -2456,46 +2473,6 @@
 	return error;
 }
 
-int
-xfs_reclaim(
-	xfs_inode_t	*ip)
-{
-
-	xfs_itrace_entry(ip);
-
-	ASSERT(!VN_MAPPED(VFS_I(ip)));
-
-	/* bad inode, get out here ASAP */
-	if (is_bad_inode(VFS_I(ip))) {
-		xfs_ireclaim(ip);
-		return 0;
-	}
-
-	xfs_ioend_wait(ip);
-
-	ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0);
-
-	/*
-	 * If we have nothing to flush with this inode then complete the
-	 * teardown now, otherwise break the link between the xfs inode and the
-	 * linux inode and clean up the xfs inode later. This avoids flushing
-	 * the inode to disk during the delete operation itself.
-	 *
-	 * When breaking the link, we need to set the XFS_IRECLAIMABLE flag
-	 * first to ensure that xfs_iunpin() will never see an xfs inode
-	 * that has a linux inode being reclaimed. Synchronisation is provided
-	 * by the i_flags_lock.
-	 */
-	if (!ip->i_update_core && (ip->i_itemp == NULL)) {
-		xfs_ilock(ip, XFS_ILOCK_EXCL);
-		xfs_iflock(ip);
-		xfs_iflags_set(ip, XFS_IRECLAIMABLE);
-		return xfs_reclaim_inode(ip, 1, XFS_IFLUSH_DELWRI_ELSE_SYNC);
-	}
-	xfs_inode_set_reclaim_tag(ip);
-	return 0;
-}
-
 /*
  * xfs_alloc_file_space()
  *      This routine allocates disk space for the given file.
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h
index a9e102d..167a467 100644
--- a/fs/xfs/xfs_vnodeops.h
+++ b/fs/xfs/xfs_vnodeops.h
@@ -38,7 +38,6 @@
 		const char *target_path, mode_t mode, struct xfs_inode **ipp,
 		cred_t *credp);
 int xfs_set_dmattrs(struct xfs_inode *ip, u_int evmask, u_int16_t state);
-int xfs_reclaim(struct xfs_inode *ip);
 int xfs_change_file_space(struct xfs_inode *ip, int cmd,
 		xfs_flock64_t *bf, xfs_off_t offset, int attr_flags);
 int xfs_rename(struct xfs_inode *src_dp, struct xfs_name *src_name,
diff --git a/include/acpi/acpi_hest.h b/include/acpi/acpi_hest.h
new file mode 100644
index 0000000..63194d0
--- /dev/null
+++ b/include/acpi/acpi_hest.h
@@ -0,0 +1,12 @@
+#ifndef __ACPI_HEST_H
+#define __ACPI_HEST_H
+
+#include <linux/pci.h>
+
+#ifdef CONFIG_ACPI
+extern int acpi_hest_firmware_first_pci(struct pci_dev *pci);
+#else
+static inline int acpi_hest_firmware_first_pci(struct pci_dev *pci) { return 0; }
+#endif
+
+#endif
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index e723b0f..5e1ad3c 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -47,7 +47,7 @@
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20090903
+#define ACPI_CA_VERSION                 0x20091112
 
 #include "actypes.h"
 #include "actbl.h"
@@ -154,7 +154,8 @@
 acpi_walk_namespace(acpi_object_type type,
 		    acpi_handle start_object,
 		    u32 max_depth,
-		    acpi_walk_callback user_function,
+		    acpi_walk_callback pre_order_visit,
+		    acpi_walk_callback post_order_visit,
 		    void *context, void **return_value);
 
 acpi_status
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 740ac3a..8b668ea 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -295,6 +295,7 @@
 void acpi_processor_ppc_init(void);
 void acpi_processor_ppc_exit(void);
 int acpi_processor_ppc_has_changed(struct acpi_processor *pr);
+extern int acpi_processor_get_bios_limit(int cpu, unsigned int *limit);
 #else
 static inline void acpi_processor_ppc_init(void)
 {
@@ -316,6 +317,11 @@
 	}
 	return 0;
 }
+static inline int acpi_processor_get_bios_limit(int cpu, unsigned int *limit)
+{
+	return -ENODEV;
+}
+
 #endif				/* CONFIG_CPU_FREQ */
 
 /* in processor_throttling.c */
diff --git a/include/asm-generic/fcntl.h b/include/asm-generic/fcntl.h
index 495dc8a..681ddf3 100644
--- a/include/asm-generic/fcntl.h
+++ b/include/asm-generic/fcntl.h
@@ -3,8 +3,6 @@
 
 #include <linux/types.h>
 
-/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
-   located on an ext2 file system */
 #define O_ACCMODE	00000003
 #define O_RDONLY	00000000
 #define O_WRONLY	00000001
@@ -27,8 +25,8 @@
 #ifndef O_NONBLOCK
 #define O_NONBLOCK	00004000
 #endif
-#ifndef O_SYNC
-#define O_SYNC		00010000
+#ifndef O_DSYNC
+#define O_DSYNC		00010000	/* used to be O_SYNC, see below */
 #endif
 #ifndef FASYNC
 #define FASYNC		00020000	/* fcntl, for BSD compatibility */
@@ -51,6 +49,25 @@
 #ifndef O_CLOEXEC
 #define O_CLOEXEC	02000000	/* set close_on_exec */
 #endif
+
+/*
+ * Before Linux 2.6.32 only O_DSYNC semantics were implemented, but using
+ * the O_SYNC flag.  We continue to use the existing numerical value
+ * for O_DSYNC semantics now, but using the correct symbolic name for it.
+ * This new value is used to request true Posix O_SYNC semantics.  It is
+ * defined in this strange way to make sure applications compiled against
+ * new headers get at least O_DSYNC semantics on older kernels.
+ *
+ * This has the nice side-effect that we can simply test for O_DSYNC
+ * wherever we do not care if O_DSYNC or O_SYNC is used.
+ *
+ * Note: __O_SYNC must never be used directly.
+ */
+#ifndef O_SYNC
+#define __O_SYNC	04000000
+#define O_SYNC		(__O_SYNC|O_DSYNC)
+#endif
+
 #ifndef O_NDELAY
 #define O_NDELAY	O_NONBLOCK
 #endif
diff --git a/include/asm-generic/memory_model.h b/include/asm-generic/memory_model.h
index 4c8d0af..fb2d63f 100644
--- a/include/asm-generic/memory_model.h
+++ b/include/asm-generic/memory_model.h
@@ -47,7 +47,7 @@
 
 #elif defined(CONFIG_SPARSEMEM_VMEMMAP)
 
-/* memmap is virtually contigious.  */
+/* memmap is virtually contiguous.  */
 #define __pfn_to_page(pfn)	(vmemmap + (pfn))
 #define __page_to_pfn(page)	(unsigned long)((page) - vmemmap)
 
diff --git a/include/asm-generic/unistd.h b/include/asm-generic/unistd.h
index d76b66a..7c38c14 100644
--- a/include/asm-generic/unistd.h
+++ b/include/asm-generic/unistd.h
@@ -631,7 +631,7 @@
  * these are provided for both review and as a porting
  * help for the C library version.
 *
- * Last chance: are any of these important enought to
+ * Last chance: are any of these important enough to
  * enable by default?
  */
 #ifdef __ARCH_WANT_SYSCALL_NO_AT
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h
index 1ffb53f..fc0d575 100644
--- a/include/crypto/algapi.h
+++ b/include/crypto/algapi.h
@@ -106,7 +106,6 @@
 extern const struct crypto_type crypto_ablkcipher_type;
 extern const struct crypto_type crypto_aead_type;
 extern const struct crypto_type crypto_blkcipher_type;
-extern const struct crypto_type crypto_hash_type;
 
 void crypto_mod_put(struct crypto_alg *alg);
 
diff --git a/include/crypto/cryptd.h b/include/crypto/cryptd.h
index 2f65a6e..1c96b25 100644
--- a/include/crypto/cryptd.h
+++ b/include/crypto/cryptd.h
@@ -39,6 +39,7 @@
 struct cryptd_ahash *cryptd_alloc_ahash(const char *alg_name,
 					u32 type, u32 mask);
 struct crypto_shash *cryptd_ahash_child(struct cryptd_ahash *tfm);
+struct shash_desc *cryptd_shash_desc(struct ahash_request *req);
 void cryptd_free_ahash(struct cryptd_ahash *tfm);
 
 #endif
diff --git a/include/drm/Kbuild b/include/drm/Kbuild
index b940fdf..cfa6af4 100644
--- a/include/drm/Kbuild
+++ b/include/drm/Kbuild
@@ -8,3 +8,4 @@
 unifdef-y += sis_drm.h
 unifdef-y += savage_drm.h
 unifdef-y += via_drm.h
+unifdef-y += nouveau_drm.h
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 7cb50bd..e3f46e0 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -36,17 +36,27 @@
 #ifndef _DRM_H_
 #define _DRM_H_
 
-#include <linux/types.h>
-#include <asm/ioctl.h>		/* For _IO* macros */
-#define DRM_IOCTL_NR(n)		_IOC_NR(n)
-#define DRM_IOC_VOID		_IOC_NONE
-#define DRM_IOC_READ		_IOC_READ
-#define DRM_IOC_WRITE		_IOC_WRITE
-#define DRM_IOC_READWRITE	_IOC_READ|_IOC_WRITE
-#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
+#if defined(__linux__)
 
-#define DRM_MAJOR       226
-#define DRM_MAX_MINOR   15
+#include <linux/types.h>
+#include <asm/ioctl.h>
+typedef unsigned int drm_handle_t;
+
+#else /* One of the BSDs */
+
+#include <sys/ioccom.h>
+#include <sys/types.h>
+typedef int8_t   __s8;
+typedef uint8_t  __u8;
+typedef int16_t  __s16;
+typedef uint16_t __u16;
+typedef int32_t  __s32;
+typedef uint32_t __u32;
+typedef int64_t  __s64;
+typedef uint64_t __u64;
+typedef unsigned long drm_handle_t;
+
+#endif
 
 #define DRM_NAME	"drm"	  /**< Name in kernel, /dev, and /proc */
 #define DRM_MIN_ORDER	5	  /**< At least 2^5 bytes = 32 bytes */
@@ -59,7 +69,6 @@
 #define _DRM_LOCK_IS_CONT(lock)	   ((lock) & _DRM_LOCK_CONT)
 #define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT))
 
-typedef unsigned int drm_handle_t;
 typedef unsigned int drm_context_t;
 typedef unsigned int drm_drawable_t;
 typedef unsigned int drm_magic_t;
@@ -454,6 +463,7 @@
 enum drm_vblank_seq_type {
 	_DRM_VBLANK_ABSOLUTE = 0x0,	/**< Wait for specific vblank sequence number */
 	_DRM_VBLANK_RELATIVE = 0x1,	/**< Wait for given number of vblanks */
+	_DRM_VBLANK_EVENT = 0x4000000,   /**< Send event instead of blocking */
 	_DRM_VBLANK_FLIP = 0x8000000,   /**< Scheduled buffer swap should flip */
 	_DRM_VBLANK_NEXTONMISS = 0x10000000,	/**< If missed, wait for next vblank */
 	_DRM_VBLANK_SECONDARY = 0x20000000,	/**< Secondary display controller */
@@ -461,8 +471,8 @@
 };
 
 #define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE)
-#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_SIGNAL | _DRM_VBLANK_SECONDARY | \
-				_DRM_VBLANK_NEXTONMISS)
+#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_EVENT | _DRM_VBLANK_SIGNAL | \
+				_DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS)
 
 struct drm_wait_vblank_request {
 	enum drm_vblank_seq_type type;
@@ -686,6 +696,8 @@
 #define DRM_IOCTL_MODE_GETFB		DRM_IOWR(0xAD, struct drm_mode_fb_cmd)
 #define DRM_IOCTL_MODE_ADDFB		DRM_IOWR(0xAE, struct drm_mode_fb_cmd)
 #define DRM_IOCTL_MODE_RMFB		DRM_IOWR(0xAF, unsigned int)
+#define DRM_IOCTL_MODE_PAGE_FLIP	DRM_IOWR(0xB0, struct drm_mode_crtc_page_flip)
+#define DRM_IOCTL_MODE_DIRTYFB		DRM_IOWR(0xB1, struct drm_mode_fb_dirty_cmd)
 
 /**
  * Device specific ioctls should only be in their respective headers
@@ -698,6 +710,35 @@
 #define DRM_COMMAND_BASE                0x40
 #define DRM_COMMAND_END			0xA0
 
+/**
+ * Header for events written back to userspace on the drm fd.  The
+ * type defines the type of event, the length specifies the total
+ * length of the event (including the header), and user_data is
+ * typically a 64 bit value passed with the ioctl that triggered the
+ * event.  A read on the drm fd will always only return complete
+ * events, that is, if for example the read buffer is 100 bytes, and
+ * there are two 64 byte events pending, only one will be returned.
+ *
+ * Event types 0 - 0x7fffffff are generic drm events, 0x80000000 and
+ * up are chipset specific.
+ */
+struct drm_event {
+	__u32 type;
+	__u32 length;
+};
+
+#define DRM_EVENT_VBLANK 0x01
+#define DRM_EVENT_FLIP_COMPLETE 0x02
+
+struct drm_event_vblank {
+	struct drm_event base;
+	__u64 user_data;
+	__u32 tv_sec;
+	__u32 tv_usec;
+	__u32 sequence;
+	__u32 reserved;
+};
+
 /* typedef area */
 #ifndef __KERNEL__
 typedef struct drm_clip_rect drm_clip_rect_t;
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index c8e64bb..19ef8eb 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -245,16 +245,6 @@
 
 #endif
 
-#define DRM_PROC_LIMIT (PAGE_SIZE-80)
-
-#define DRM_PROC_PRINT(fmt, arg...)					\
-   len += sprintf(&buf[len], fmt , ##arg);				\
-   if (len > DRM_PROC_LIMIT) { *eof = 1; return len - offset; }
-
-#define DRM_PROC_PRINT_RET(ret, fmt, arg...)				\
-   len += sprintf(&buf[len], fmt , ##arg);				\
-   if (len > DRM_PROC_LIMIT) { ret; *eof = 1; return len - offset; }
-
 /*@}*/
 
 /***********************************************************************/
@@ -265,19 +255,8 @@
 
 #define DRM_LEFTCOUNT(x) (((x)->rp + (x)->count - (x)->wp) % ((x)->count + 1))
 #define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x))
-#define DRM_WAITCOUNT(dev,idx) DRM_BUFCOUNT(&dev->queuelist[idx]->waitlist)
 
 #define DRM_IF_VERSION(maj, min) (maj << 16 | min)
-/**
- * Get the private SAREA mapping.
- *
- * \param _dev DRM device.
- * \param _ctx context number.
- * \param _map output mapping.
- */
-#define DRM_GET_PRIV_SAREA(_dev, _ctx, _map) do {	\
-	(_map) = (_dev)->context_sareas[_ctx];		\
-} while(0)
 
 /**
  * Test that the hardware lock is held by the caller, returning otherwise.
@@ -297,18 +276,6 @@
 } while (0)
 
 /**
- * Copy and IOCTL return string to user space
- */
-#define DRM_COPY( name, value )						\
-	len = strlen( value );						\
-	if ( len > name##_len ) len = name##_len;			\
-	name##_len = strlen( value );					\
-	if ( len && name ) {						\
-		if ( copy_to_user( name, value, len ) )			\
-			return -EFAULT;					\
-	}
-
-/**
  * Ioctl function type.
  *
  * \param inode device inode.
@@ -322,6 +289,9 @@
 typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
 			       unsigned long arg);
 
+#define DRM_IOCTL_NR(n)                _IOC_NR(n)
+#define DRM_MAJOR       226
+
 #define DRM_AUTH	0x1
 #define	DRM_MASTER	0x2
 #define DRM_ROOT_ONLY	0x4
@@ -426,6 +396,14 @@
 	struct drm_freelist freelist;
 };
 
+/* Event queued up for userspace to read */
+struct drm_pending_event {
+	struct drm_event *event;
+	struct list_head link;
+	struct drm_file *file_priv;
+	void (*destroy)(struct drm_pending_event *event);
+};
+
 /** File private data */
 struct drm_file {
 	int authenticated;
@@ -449,6 +427,10 @@
 	struct drm_master *master; /* master this node is currently associated with
 				      N.B. not always minor->master */
 	struct list_head fbs;
+
+	wait_queue_head_t event_wait;
+	struct list_head event_list;
+	int event_space;
 };
 
 /** Wait queue */
@@ -795,6 +777,15 @@
 	/* Master routines */
 	int (*master_create)(struct drm_device *dev, struct drm_master *master);
 	void (*master_destroy)(struct drm_device *dev, struct drm_master *master);
+	/**
+	 * master_set is called whenever the minor master is set.
+	 * master_drop is called whenever the minor master is dropped.
+	 */
+
+	int (*master_set)(struct drm_device *dev, struct drm_file *file_priv,
+			  bool from_open);
+	void (*master_drop)(struct drm_device *dev, struct drm_file *file_priv,
+			    bool from_release);
 
 	int (*proc_init)(struct drm_minor *minor);
 	void (*proc_cleanup)(struct drm_minor *minor);
@@ -900,6 +891,12 @@
 	struct drm_mode_group mode_group;
 };
 
+struct drm_pending_vblank_event {
+	struct drm_pending_event base;
+	int pipe;
+	struct drm_event_vblank event;
+};
+
 /**
  * DRM device structure. This structure represent a complete card that
  * may contain multiple heads.
@@ -999,6 +996,12 @@
 
 	u32 max_vblank_count;           /**< size of vblank counter register */
 
+	/**
+	 * List of events
+	 */
+	struct list_head vblank_event_list;
+	spinlock_t event_lock;
+
 	/*@} */
 	cycles_t ctx_start;
 	cycles_t lck_start;
@@ -1135,6 +1138,8 @@
 extern int drm_open(struct inode *inode, struct file *filp);
 extern int drm_stub_open(struct inode *inode, struct file *filp);
 extern int drm_fasync(int fd, struct file *filp, int on);
+extern ssize_t drm_read(struct file *filp, char __user *buffer,
+			size_t count, loff_t *offset);
 extern int drm_release(struct inode *inode, struct file *filp);
 
 				/* Mapping support (drm_vm.h) */
@@ -1295,6 +1300,7 @@
 extern void drm_handle_vblank(struct drm_device *dev, int crtc);
 extern int drm_vblank_get(struct drm_device *dev, int crtc);
 extern void drm_vblank_put(struct drm_device *dev, int crtc);
+extern void drm_vblank_off(struct drm_device *dev, int crtc);
 extern void drm_vblank_cleanup(struct drm_device *dev);
 /* Modesetting support */
 extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc);
@@ -1519,16 +1525,29 @@
 
 static __inline__ void *drm_calloc_large(size_t nmemb, size_t size)
 {
-	if (size * nmemb <= PAGE_SIZE)
-	    return kcalloc(nmemb, size, GFP_KERNEL);
-
 	if (size != 0 && nmemb > ULONG_MAX / size)
 		return NULL;
 
+	if (size * nmemb <= PAGE_SIZE)
+	    return kcalloc(nmemb, size, GFP_KERNEL);
+
 	return __vmalloc(size * nmemb,
 			 GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
 }
 
+/* Modeled after cairo's malloc_ab, it's like calloc but without the zeroing. */
+static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size)
+{
+	if (size != 0 && nmemb > ULONG_MAX / size)
+		return NULL;
+
+	if (size * nmemb <= PAGE_SIZE)
+	    return kmalloc(nmemb * size, GFP_KERNEL);
+
+	return __vmalloc(size * nmemb,
+			 GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
+}
+
 static __inline void drm_free_large(void *ptr)
 {
 	if (!is_vmalloc_addr(ptr))
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index b69347b..fdf43ab 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -123,7 +123,7 @@
 	int type;
 
 	/* Proposed mode values */
-	int clock;
+	int clock;		/* in kHz */
 	int hdisplay;
 	int hsync_start;
 	int hsync_end;
@@ -164,8 +164,8 @@
 	int *private;
 	int private_flags;
 
-	int vrefresh;
-	float hsync;
+	int vrefresh;		/* in Hz */
+	int hsync;		/* in kHz */
 };
 
 enum drm_connector_status {
@@ -242,6 +242,21 @@
 	int (*create_handle)(struct drm_framebuffer *fb,
 			     struct drm_file *file_priv,
 			     unsigned int *handle);
+	/**
+	 * Optinal callback for the dirty fb ioctl.
+	 *
+	 * Userspace can notify the driver via this callback
+	 * that a area of the framebuffer has changed and should
+	 * be flushed to the display hardware.
+	 *
+	 * See documentation in drm_mode.h for the struct
+	 * drm_mode_fb_dirty_cmd for more information as all
+	 * the semantics and arguments have a one to one mapping
+	 * on this function.
+	 */
+	int (*dirty)(struct drm_framebuffer *framebuffer, unsigned flags,
+		     unsigned color, struct drm_clip_rect *clips,
+		     unsigned num_clips);
 };
 
 struct drm_framebuffer {
@@ -256,7 +271,7 @@
 	unsigned int depth;
 	int bits_per_pixel;
 	int flags;
-	void *fbdev;
+	struct fb_info *fbdev;
 	u32 pseudo_palette[17];
 	struct list_head filp_head;
 	/* if you are using the helper */
@@ -290,6 +305,7 @@
 struct drm_crtc;
 struct drm_connector;
 struct drm_encoder;
+struct drm_pending_vblank_event;
 
 /**
  * drm_crtc_funcs - control CRTCs for a given device
@@ -333,6 +349,19 @@
 	void (*destroy)(struct drm_crtc *crtc);
 
 	int (*set_config)(struct drm_mode_set *set);
+
+	/*
+	 * Flip to the given framebuffer.  This implements the page
+	 * flip ioctl descibed in drm_mode.h, specifically, the
+	 * implementation must return immediately and block all
+	 * rendering to the current fb until the flip has completed.
+	 * If userspace set the event flag in the ioctl, the event
+	 * argument will point to an event to send back when the flip
+	 * completes, otherwise it will be NULL.
+	 */
+	int (*page_flip)(struct drm_crtc *crtc,
+			 struct drm_framebuffer *fb,
+			 struct drm_pending_vblank_event *event);
 };
 
 /**
@@ -596,6 +625,7 @@
 	/* Optional properties */
 	struct drm_property *scaling_mode_property;
 	struct drm_property *dithering_mode_property;
+	struct drm_property *dirty_info_property;
 };
 
 #define obj_to_crtc(x) container_of(x, struct drm_crtc, base)
@@ -667,6 +697,7 @@
 extern void drm_mode_prune_invalid(struct drm_device *dev,
 				   struct list_head *mode_list, bool verbose);
 extern void drm_mode_sort(struct list_head *mode_list);
+extern int drm_mode_hsync(struct drm_display_mode *mode);
 extern int drm_mode_vrefresh(struct drm_display_mode *mode);
 extern void drm_mode_set_crtcinfo(struct drm_display_mode *p,
 				  int adjust_flags);
@@ -703,6 +734,7 @@
 				     char *formats[]);
 extern int drm_mode_create_scaling_mode_property(struct drm_device *dev);
 extern int drm_mode_create_dithering_property(struct drm_device *dev);
+extern int drm_mode_create_dirty_info_property(struct drm_device *dev);
 extern char *drm_get_encoder_name(struct drm_encoder *encoder);
 
 extern int drm_mode_connector_attach_encoder(struct drm_connector *connector,
@@ -711,7 +743,8 @@
 					   struct drm_encoder *encoder);
 extern bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
 					 int gamma_size);
-extern void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type);
+extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
+		uint32_t id, uint32_t type);
 /* IOCTLs */
 extern int drm_mode_getresources(struct drm_device *dev,
 				 void *data, struct drm_file *file_priv);
@@ -730,6 +763,8 @@
 			 void *data, struct drm_file *file_priv);
 extern int drm_mode_getfb(struct drm_device *dev,
 			  void *data, struct drm_file *file_priv);
+extern int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
+				  void *data, struct drm_file *file_priv);
 extern int drm_mode_addmode_ioctl(struct drm_device *dev,
 				  void *data, struct drm_file *file_priv);
 extern int drm_mode_rmmode_ioctl(struct drm_device *dev,
@@ -756,6 +791,8 @@
 extern int drm_mode_gamma_set_ioctl(struct drm_device *dev,
 				    void *data, struct drm_file *file_priv);
 extern bool drm_detect_hdmi_monitor(struct edid *edid);
+extern int drm_mode_page_flip_ioctl(struct drm_device *dev,
+				    void *data, struct drm_file *file_priv);
 extern struct drm_display_mode *drm_cvt_mode(struct drm_device *dev,
 				int hdisplay, int vdisplay, int vrefresh,
 				bool reduced, bool interlaced, bool margins);
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
new file mode 100644
index 0000000..a49e791
--- /dev/null
+++ b/include/drm/drm_dp_helper.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright © 2008 Keith Packard
+ *
+ * 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.
+ */
+
+#ifndef _DRM_DP_HELPER_H_
+#define _DRM_DP_HELPER_H_
+
+/* From the VESA DisplayPort spec */
+
+#define AUX_NATIVE_WRITE	0x8
+#define AUX_NATIVE_READ		0x9
+#define AUX_I2C_WRITE		0x0
+#define AUX_I2C_READ		0x1
+#define AUX_I2C_STATUS		0x2
+#define AUX_I2C_MOT		0x4
+
+#define AUX_NATIVE_REPLY_ACK	(0x0 << 4)
+#define AUX_NATIVE_REPLY_NACK	(0x1 << 4)
+#define AUX_NATIVE_REPLY_DEFER	(0x2 << 4)
+#define AUX_NATIVE_REPLY_MASK	(0x3 << 4)
+
+#define AUX_I2C_REPLY_ACK	(0x0 << 6)
+#define AUX_I2C_REPLY_NACK	(0x1 << 6)
+#define AUX_I2C_REPLY_DEFER	(0x2 << 6)
+#define AUX_I2C_REPLY_MASK	(0x3 << 6)
+
+/* AUX CH addresses */
+/* DPCD */
+#define DP_DPCD_REV                         0x000
+
+#define DP_MAX_LINK_RATE                    0x001
+
+#define DP_MAX_LANE_COUNT                   0x002
+# define DP_MAX_LANE_COUNT_MASK		    0x1f
+# define DP_ENHANCED_FRAME_CAP		    (1 << 7)
+
+#define DP_MAX_DOWNSPREAD                   0x003
+# define DP_NO_AUX_HANDSHAKE_LINK_TRAINING  (1 << 6)
+
+#define DP_NORP                             0x004
+
+#define DP_DOWNSTREAMPORT_PRESENT           0x005
+# define DP_DWN_STRM_PORT_PRESENT           (1 << 0)
+# define DP_DWN_STRM_PORT_TYPE_MASK         0x06
+/* 00b = DisplayPort */
+/* 01b = Analog */
+/* 10b = TMDS or HDMI */
+/* 11b = Other */
+# define DP_FORMAT_CONVERSION               (1 << 3)
+
+#define DP_MAIN_LINK_CHANNEL_CODING         0x006
+
+/* link configuration */
+#define	DP_LINK_BW_SET		            0x100
+# define DP_LINK_BW_1_62		    0x06
+# define DP_LINK_BW_2_7			    0x0a
+
+#define DP_LANE_COUNT_SET	            0x101
+# define DP_LANE_COUNT_MASK		    0x0f
+# define DP_LANE_COUNT_ENHANCED_FRAME_EN    (1 << 7)
+
+#define DP_TRAINING_PATTERN_SET	            0x102
+# define DP_TRAINING_PATTERN_DISABLE	    0
+# define DP_TRAINING_PATTERN_1		    1
+# define DP_TRAINING_PATTERN_2		    2
+# define DP_TRAINING_PATTERN_MASK	    0x3
+
+# define DP_LINK_QUAL_PATTERN_DISABLE	    (0 << 2)
+# define DP_LINK_QUAL_PATTERN_D10_2	    (1 << 2)
+# define DP_LINK_QUAL_PATTERN_ERROR_RATE    (2 << 2)
+# define DP_LINK_QUAL_PATTERN_PRBS7	    (3 << 2)
+# define DP_LINK_QUAL_PATTERN_MASK	    (3 << 2)
+
+# define DP_RECOVERED_CLOCK_OUT_EN	    (1 << 4)
+# define DP_LINK_SCRAMBLING_DISABLE	    (1 << 5)
+
+# define DP_SYMBOL_ERROR_COUNT_BOTH	    (0 << 6)
+# define DP_SYMBOL_ERROR_COUNT_DISPARITY    (1 << 6)
+# define DP_SYMBOL_ERROR_COUNT_SYMBOL	    (2 << 6)
+# define DP_SYMBOL_ERROR_COUNT_MASK	    (3 << 6)
+
+#define DP_TRAINING_LANE0_SET		    0x103
+#define DP_TRAINING_LANE1_SET		    0x104
+#define DP_TRAINING_LANE2_SET		    0x105
+#define DP_TRAINING_LANE3_SET		    0x106
+
+# define DP_TRAIN_VOLTAGE_SWING_MASK	    0x3
+# define DP_TRAIN_VOLTAGE_SWING_SHIFT	    0
+# define DP_TRAIN_MAX_SWING_REACHED	    (1 << 2)
+# define DP_TRAIN_VOLTAGE_SWING_400	    (0 << 0)
+# define DP_TRAIN_VOLTAGE_SWING_600	    (1 << 0)
+# define DP_TRAIN_VOLTAGE_SWING_800	    (2 << 0)
+# define DP_TRAIN_VOLTAGE_SWING_1200	    (3 << 0)
+
+# define DP_TRAIN_PRE_EMPHASIS_MASK	    (3 << 3)
+# define DP_TRAIN_PRE_EMPHASIS_0	    (0 << 3)
+# define DP_TRAIN_PRE_EMPHASIS_3_5	    (1 << 3)
+# define DP_TRAIN_PRE_EMPHASIS_6	    (2 << 3)
+# define DP_TRAIN_PRE_EMPHASIS_9_5	    (3 << 3)
+
+# define DP_TRAIN_PRE_EMPHASIS_SHIFT	    3
+# define DP_TRAIN_MAX_PRE_EMPHASIS_REACHED  (1 << 5)
+
+#define DP_DOWNSPREAD_CTRL		    0x107
+# define DP_SPREAD_AMP_0_5		    (1 << 4)
+
+#define DP_MAIN_LINK_CHANNEL_CODING_SET	    0x108
+# define DP_SET_ANSI_8B10B		    (1 << 0)
+
+#define DP_LANE0_1_STATUS		    0x202
+#define DP_LANE2_3_STATUS		    0x203
+# define DP_LANE_CR_DONE		    (1 << 0)
+# define DP_LANE_CHANNEL_EQ_DONE	    (1 << 1)
+# define DP_LANE_SYMBOL_LOCKED		    (1 << 2)
+
+#define DP_CHANNEL_EQ_BITS (DP_LANE_CR_DONE |		\
+			    DP_LANE_CHANNEL_EQ_DONE |	\
+			    DP_LANE_SYMBOL_LOCKED)
+
+#define DP_LANE_ALIGN_STATUS_UPDATED	    0x204
+
+#define DP_INTERLANE_ALIGN_DONE		    (1 << 0)
+#define DP_DOWNSTREAM_PORT_STATUS_CHANGED   (1 << 6)
+#define DP_LINK_STATUS_UPDATED		    (1 << 7)
+
+#define DP_SINK_STATUS			    0x205
+
+#define DP_RECEIVE_PORT_0_STATUS	    (1 << 0)
+#define DP_RECEIVE_PORT_1_STATUS	    (1 << 1)
+
+#define DP_ADJUST_REQUEST_LANE0_1	    0x206
+#define DP_ADJUST_REQUEST_LANE2_3	    0x207
+# define DP_ADJUST_VOLTAGE_SWING_LANE0_MASK  0x03
+# define DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT 0
+# define DP_ADJUST_PRE_EMPHASIS_LANE0_MASK   0x0c
+# define DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT  2
+# define DP_ADJUST_VOLTAGE_SWING_LANE1_MASK  0x30
+# define DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT 4
+# define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK   0xc0
+# define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT  6
+
+#define DP_SET_POWER                        0x600
+# define DP_SET_POWER_D0                    0x1
+# define DP_SET_POWER_D3                    0x2
+
+#define MODE_I2C_START	1
+#define MODE_I2C_WRITE	2
+#define MODE_I2C_READ	4
+#define MODE_I2C_STOP	8
+
+struct i2c_algo_dp_aux_data {
+	bool running;
+	u16 address;
+	int (*aux_ch) (struct i2c_adapter *adapter,
+		       int mode, uint8_t write_byte,
+		       uint8_t *read_byte);
+};
+
+int
+i2c_dp_aux_add_bus(struct i2c_adapter *adapter);
+
+#endif /* _DRM_DP_HELPER_H_ */
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 7d6c9a2..d33c3e0 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -106,6 +106,10 @@
 	u8 wpindex2[3];
 } __attribute__((packed));
 
+struct cvt_timing {
+	u8 code[3];
+} __attribute__((packed));
+
 struct detailed_non_pixel {
 	u8 pad1;
 	u8 type; /* ff=serial, fe=string, fd=monitor range, fc=monitor name
@@ -117,9 +121,13 @@
 		struct detailed_data_monitor_range range;
 		struct detailed_data_wpindex color;
 		struct std_timing timings[5];
+		struct cvt_timing cvt[4];
 	} data;
 } __attribute__((packed));
 
+#define EDID_DETAIL_EST_TIMINGS 0xf7
+#define EDID_DETAIL_CVT_3BYTE 0xf8
+#define EDID_DETAIL_COLOR_MGMT_DATA 0xf9
 #define EDID_DETAIL_STD_MODES 0xfa
 #define EDID_DETAIL_MONITOR_CPDATA 0xfb
 #define EDID_DETAIL_MONITOR_NAME 0xfc
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index 62329f9..4c10be3 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -66,6 +66,13 @@
 						    unsigned long size,
 						    unsigned alignment,
 						    int atomic);
+extern struct drm_mm_node *drm_mm_get_block_range_generic(
+						struct drm_mm_node *node,
+						unsigned long size,
+						unsigned alignment,
+						unsigned long start,
+						unsigned long end,
+						int atomic);
 static inline struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *parent,
 						   unsigned long size,
 						   unsigned alignment)
@@ -78,11 +85,38 @@
 {
 	return drm_mm_get_block_generic(parent, size, alignment, 1);
 }
+static inline struct drm_mm_node *drm_mm_get_block_range(
+						struct drm_mm_node *parent,
+						unsigned long size,
+						unsigned alignment,
+						unsigned long start,
+						unsigned long end)
+{
+	return drm_mm_get_block_range_generic(parent, size, alignment,
+						start, end, 0);
+}
+static inline struct drm_mm_node *drm_mm_get_block_atomic_range(
+						struct drm_mm_node *parent,
+						unsigned long size,
+						unsigned alignment,
+						unsigned long start,
+						unsigned long end)
+{
+	return drm_mm_get_block_range_generic(parent, size, alignment,
+						start, end, 1);
+}
 extern void drm_mm_put_block(struct drm_mm_node *cur);
 extern struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
 					      unsigned long size,
 					      unsigned alignment,
 					      int best_match);
+extern struct drm_mm_node *drm_mm_search_free_in_range(
+						const struct drm_mm *mm,
+						unsigned long size,
+						unsigned alignment,
+						unsigned long start,
+						unsigned long end,
+						int best_match);
 extern int drm_mm_init(struct drm_mm *mm, unsigned long start,
 		       unsigned long size);
 extern void drm_mm_takedown(struct drm_mm *mm);
@@ -99,6 +133,7 @@
 	return block->mm;
 }
 
+extern void drm_mm_debug_table(struct drm_mm *mm, const char *prefix);
 #ifdef CONFIG_DEBUG_FS
 int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm);
 #endif
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index 1f90841..43009bc 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -27,9 +27,6 @@
 #ifndef _DRM_MODE_H
 #define _DRM_MODE_H
 
-#include <linux/kernel.h>
-#include <linux/types.h>
-
 #define DRM_DISPLAY_INFO_LEN	32
 #define DRM_CONNECTOR_NAME_LEN	32
 #define DRM_DISPLAY_MODE_LEN	32
@@ -78,6 +75,11 @@
 #define DRM_MODE_DITHERING_OFF	0
 #define DRM_MODE_DITHERING_ON	1
 
+/* Dirty info options */
+#define DRM_MODE_DIRTY_OFF      0
+#define DRM_MODE_DIRTY_ON       1
+#define DRM_MODE_DIRTY_ANNOTATE 2
+
 struct drm_mode_modeinfo {
 	__u32 clock;
 	__u16 hdisplay, hsync_start, hsync_end, htotal, hskew;
@@ -225,6 +227,45 @@
 	__u32 handle;
 };
 
+#define DRM_MODE_FB_DIRTY_ANNOTATE_COPY 0x01
+#define DRM_MODE_FB_DIRTY_ANNOTATE_FILL 0x02
+#define DRM_MODE_FB_DIRTY_FLAGS         0x03
+
+/*
+ * Mark a region of a framebuffer as dirty.
+ *
+ * Some hardware does not automatically update display contents
+ * as a hardware or software draw to a framebuffer. This ioctl
+ * allows userspace to tell the kernel and the hardware what
+ * regions of the framebuffer have changed.
+ *
+ * The kernel or hardware is free to update more then just the
+ * region specified by the clip rects. The kernel or hardware
+ * may also delay and/or coalesce several calls to dirty into a
+ * single update.
+ *
+ * Userspace may annotate the updates, the annotates are a
+ * promise made by the caller that the change is either a copy
+ * of pixels or a fill of a single color in the region specified.
+ *
+ * If the DRM_MODE_FB_DIRTY_ANNOTATE_COPY flag is given then
+ * the number of updated regions are half of num_clips given,
+ * where the clip rects are paired in src and dst. The width and
+ * height of each one of the pairs must match.
+ *
+ * If the DRM_MODE_FB_DIRTY_ANNOTATE_FILL flag is given the caller
+ * promises that the region specified of the clip rects is filled
+ * completely with a single color as given in the color argument.
+ */
+
+struct drm_mode_fb_dirty_cmd {
+	__u32 fb_id;
+	__u32 flags;
+	__u32 color;
+	__u32 num_clips;
+	__u64 clips_ptr;
+};
+
 struct drm_mode_mode_cmd {
 	__u32 connector_id;
 	struct drm_mode_modeinfo mode;
@@ -268,4 +309,37 @@
 	__u64 blue;
 };
 
+#define DRM_MODE_PAGE_FLIP_EVENT 0x01
+#define DRM_MODE_PAGE_FLIP_FLAGS DRM_MODE_PAGE_FLIP_EVENT
+
+/*
+ * Request a page flip on the specified crtc.
+ *
+ * This ioctl will ask KMS to schedule a page flip for the specified
+ * crtc.  Once any pending rendering targeting the specified fb (as of
+ * ioctl time) has completed, the crtc will be reprogrammed to display
+ * that fb after the next vertical refresh.  The ioctl returns
+ * immediately, but subsequent rendering to the current fb will block
+ * in the execbuffer ioctl until the page flip happens.  If a page
+ * flip is already pending as the ioctl is called, EBUSY will be
+ * returned.
+ *
+ * The ioctl supports one flag, DRM_MODE_PAGE_FLIP_EVENT, which will
+ * request that drm sends back a vblank event (see drm.h: struct
+ * drm_event_vblank) when the page flip is done.  The user_data field
+ * passed in with this ioctl will be returned as the user_data field
+ * in the vblank event struct.
+ *
+ * The reserved field must be zero until we figure out something
+ * clever to use it for.
+ */
+
+struct drm_mode_crtc_page_flip {
+	__u32 crtc_id;
+	__u32 fb_id;
+	__u32 flags;
+	__u32 reserved;
+	__u64 user_data;
+};
+
 #endif
diff --git a/include/drm/drm_os_linux.h b/include/drm/drm_os_linux.h
index 26641e95..3933691 100644
--- a/include/drm/drm_os_linux.h
+++ b/include/drm/drm_os_linux.h
@@ -123,5 +123,5 @@
 	remove_wait_queue(&(queue), &entry);			\
 } while (0)
 
-#define DRM_WAKEUP( queue ) wake_up_interruptible( queue )
+#define DRM_WAKEUP( queue ) wake_up( queue )
 #define DRM_INIT_WAITQUEUE( queue ) init_waitqueue_head( queue )
diff --git a/include/drm/i2c/ch7006.h b/include/drm/i2c/ch7006.h
new file mode 100644
index 0000000..8390b43
--- /dev/null
+++ b/include/drm/i2c/ch7006.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2009 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __DRM_I2C_CH7006_H__
+#define __DRM_I2C_CH7006_H__
+
+/**
+ * struct ch7006_encoder_params
+ *
+ * Describes how the ch7006 is wired up with the GPU. It should be
+ * used as the @params parameter of its @set_config method.
+ *
+ * See "http://www.chrontel.com/pdf/7006.pdf" for their precise
+ * meaning.
+ */
+struct ch7006_encoder_params {
+	enum {
+		CH7006_FORMAT_RGB16 = 0,
+		CH7006_FORMAT_YCrCb24m16,
+		CH7006_FORMAT_RGB24m16,
+		CH7006_FORMAT_RGB15,
+		CH7006_FORMAT_RGB24m12C,
+		CH7006_FORMAT_RGB24m12I,
+		CH7006_FORMAT_RGB24m8,
+		CH7006_FORMAT_RGB16m8,
+		CH7006_FORMAT_RGB15m8,
+		CH7006_FORMAT_YCrCb24m8,
+	} input_format;
+
+	enum {
+		CH7006_CLOCK_SLAVE = 0,
+		CH7006_CLOCK_MASTER,
+	} clock_mode;
+
+	enum {
+		CH7006_CLOCK_EDGE_NEG = 0,
+		CH7006_CLOCK_EDGE_POS,
+	} clock_edge;
+
+	int xcm, pcm;
+
+	enum {
+		CH7006_SYNC_SLAVE = 0,
+		CH7006_SYNC_MASTER,
+	} sync_direction;
+
+	enum {
+		CH7006_SYNC_SEPARATED = 0,
+		CH7006_SYNC_EMBEDDED,
+	} sync_encoding;
+
+	enum {
+		CH7006_POUT_1_8V = 0,
+		CH7006_POUT_3_3V,
+	} pout_level;
+
+	enum {
+		CH7006_ACTIVE_HSYNC = 0,
+		CH7006_ACTIVE_DSTART,
+	} active_detect;
+};
+
+#endif
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index 7e0cb1d..ec3f5e80 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -27,11 +27,11 @@
 #ifndef _I915_DRM_H_
 #define _I915_DRM_H_
 
+#include "drm.h"
+
 /* Please note that modifications to all structs defined here are
  * subject to backwards-compatibility constraints.
  */
-#include <linux/types.h>
-#include "drm.h"
 
 /* Each region is a minimum of 16k, and there are at most 255 of them.
  */
@@ -186,6 +186,8 @@
 #define DRM_I915_GEM_MMAP_GTT	0x24
 #define DRM_I915_GET_PIPE_FROM_CRTC_ID	0x25
 #define DRM_I915_GEM_MADVISE	0x26
+#define DRM_I915_OVERLAY_PUT_IMAGE	0x27
+#define DRM_I915_OVERLAY_ATTRS	0x28
 
 #define DRM_IOCTL_I915_INIT		DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
 #define DRM_IOCTL_I915_FLUSH		DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -221,8 +223,10 @@
 #define DRM_IOCTL_I915_GEM_SET_TILING	DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling)
 #define DRM_IOCTL_I915_GEM_GET_TILING	DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling)
 #define DRM_IOCTL_I915_GEM_GET_APERTURE	DRM_IOR  (DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture)
-#define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_intel_get_pipe_from_crtc_id)
+#define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_i915_get_pipe_from_crtc_id)
 #define DRM_IOCTL_I915_GEM_MADVISE	DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise)
+#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE	DRM_IOW(DRM_COMMAND_BASE + DRM_IOCTL_I915_OVERLAY_ATTRS, struct drm_intel_overlay_put_image)
+#define DRM_IOCTL_I915_OVERLAY_ATTRS	DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_OVERLAY_ATTRS, struct drm_intel_overlay_attrs)
 
 /* Allow drivers to submit batchbuffers directly to hardware, relying
  * on the security mechanisms provided by hardware.
@@ -266,6 +270,8 @@
 #define I915_PARAM_CHIPSET_ID            4
 #define I915_PARAM_HAS_GEM               5
 #define I915_PARAM_NUM_FENCES_AVAIL      6
+#define I915_PARAM_HAS_OVERLAY           7
+#define I915_PARAM_HAS_PAGEFLIPPING	 8
 
 typedef struct drm_i915_getparam {
 	int param;
@@ -686,4 +692,70 @@
 	__u32 retained;
 };
 
+/* flags */
+#define I915_OVERLAY_TYPE_MASK 		0xff
+#define I915_OVERLAY_YUV_PLANAR 	0x01
+#define I915_OVERLAY_YUV_PACKED 	0x02
+#define I915_OVERLAY_RGB		0x03
+
+#define I915_OVERLAY_DEPTH_MASK		0xff00
+#define I915_OVERLAY_RGB24		0x1000
+#define I915_OVERLAY_RGB16		0x2000
+#define I915_OVERLAY_RGB15		0x3000
+#define I915_OVERLAY_YUV422		0x0100
+#define I915_OVERLAY_YUV411		0x0200
+#define I915_OVERLAY_YUV420		0x0300
+#define I915_OVERLAY_YUV410		0x0400
+
+#define I915_OVERLAY_SWAP_MASK		0xff0000
+#define I915_OVERLAY_NO_SWAP		0x000000
+#define I915_OVERLAY_UV_SWAP		0x010000
+#define I915_OVERLAY_Y_SWAP		0x020000
+#define I915_OVERLAY_Y_AND_UV_SWAP	0x030000
+
+#define I915_OVERLAY_FLAGS_MASK		0xff000000
+#define I915_OVERLAY_ENABLE		0x01000000
+
+struct drm_intel_overlay_put_image {
+	/* various flags and src format description */
+	__u32 flags;
+	/* source picture description */
+	__u32 bo_handle;
+	/* stride values and offsets are in bytes, buffer relative */
+	__u16 stride_Y; /* stride for packed formats */
+	__u16 stride_UV;
+	__u32 offset_Y; /* offset for packet formats */
+	__u32 offset_U;
+	__u32 offset_V;
+	/* in pixels */
+	__u16 src_width;
+	__u16 src_height;
+	/* to compensate the scaling factors for partially covered surfaces */
+	__u16 src_scan_width;
+	__u16 src_scan_height;
+	/* output crtc description */
+	__u32 crtc_id;
+	__u16 dst_x;
+	__u16 dst_y;
+	__u16 dst_width;
+	__u16 dst_height;
+};
+
+/* flags */
+#define I915_OVERLAY_UPDATE_ATTRS	(1<<0)
+#define I915_OVERLAY_UPDATE_GAMMA	(1<<1)
+struct drm_intel_overlay_attrs {
+	__u32 flags;
+	__u32 color_key;
+	__s32 brightness;
+	__u32 contrast;
+	__u32 saturation;
+	__u32 gamma0;
+	__u32 gamma1;
+	__u32 gamma2;
+	__u32 gamma3;
+	__u32 gamma4;
+	__u32 gamma5;
+};
+
 #endif				/* _I915_DRM_H_ */
diff --git a/include/drm/mga_drm.h b/include/drm/mga_drm.h
index 325fd6f..3ffbc47 100644
--- a/include/drm/mga_drm.h
+++ b/include/drm/mga_drm.h
@@ -35,7 +35,7 @@
 #ifndef __MGA_DRM_H__
 #define __MGA_DRM_H__
 
-#include <linux/types.h>
+#include "drm.h"
 
 /* WARNING: If you change any of these defines, make sure to change the
  * defines in the Xserver file (mga_sarea.h)
diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h
new file mode 100644
index 0000000..1e67c44
--- /dev/null
+++ b/include/drm/nouveau_drm.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2005 Stephane Marchesin.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __NOUVEAU_DRM_H__
+#define __NOUVEAU_DRM_H__
+
+#define NOUVEAU_DRM_HEADER_PATCHLEVEL 15
+
+struct drm_nouveau_channel_alloc {
+	uint32_t     fb_ctxdma_handle;
+	uint32_t     tt_ctxdma_handle;
+
+	int          channel;
+
+	/* Notifier memory */
+	uint32_t     notifier_handle;
+
+	/* DRM-enforced subchannel assignments */
+	struct {
+		uint32_t handle;
+		uint32_t grclass;
+	} subchan[8];
+	uint32_t nr_subchan;
+};
+
+struct drm_nouveau_channel_free {
+	int channel;
+};
+
+struct drm_nouveau_grobj_alloc {
+	int      channel;
+	uint32_t handle;
+	int      class;
+};
+
+struct drm_nouveau_notifierobj_alloc {
+	uint32_t channel;
+	uint32_t handle;
+	uint32_t size;
+	uint32_t offset;
+};
+
+struct drm_nouveau_gpuobj_free {
+	int      channel;
+	uint32_t handle;
+};
+
+/* FIXME : maybe unify {GET,SET}PARAMs */
+#define NOUVEAU_GETPARAM_PCI_VENDOR      3
+#define NOUVEAU_GETPARAM_PCI_DEVICE      4
+#define NOUVEAU_GETPARAM_BUS_TYPE        5
+#define NOUVEAU_GETPARAM_FB_PHYSICAL     6
+#define NOUVEAU_GETPARAM_AGP_PHYSICAL    7
+#define NOUVEAU_GETPARAM_FB_SIZE         8
+#define NOUVEAU_GETPARAM_AGP_SIZE        9
+#define NOUVEAU_GETPARAM_PCI_PHYSICAL    10
+#define NOUVEAU_GETPARAM_CHIPSET_ID      11
+#define NOUVEAU_GETPARAM_VM_VRAM_BASE    12
+struct drm_nouveau_getparam {
+	uint64_t param;
+	uint64_t value;
+};
+
+struct drm_nouveau_setparam {
+	uint64_t param;
+	uint64_t value;
+};
+
+#define NOUVEAU_GEM_DOMAIN_CPU       (1 << 0)
+#define NOUVEAU_GEM_DOMAIN_VRAM      (1 << 1)
+#define NOUVEAU_GEM_DOMAIN_GART      (1 << 2)
+#define NOUVEAU_GEM_DOMAIN_MAPPABLE  (1 << 3)
+
+struct drm_nouveau_gem_info {
+	uint32_t handle;
+	uint32_t domain;
+	uint64_t size;
+	uint64_t offset;
+	uint64_t map_handle;
+	uint32_t tile_mode;
+	uint32_t tile_flags;
+};
+
+struct drm_nouveau_gem_new {
+	struct drm_nouveau_gem_info info;
+	uint32_t channel_hint;
+	uint32_t align;
+};
+
+struct drm_nouveau_gem_pushbuf_bo {
+	uint64_t user_priv;
+	uint32_t handle;
+	uint32_t read_domains;
+	uint32_t write_domains;
+	uint32_t valid_domains;
+	uint32_t presumed_ok;
+	uint32_t presumed_domain;
+	uint64_t presumed_offset;
+};
+
+#define NOUVEAU_GEM_RELOC_LOW  (1 << 0)
+#define NOUVEAU_GEM_RELOC_HIGH (1 << 1)
+#define NOUVEAU_GEM_RELOC_OR   (1 << 2)
+struct drm_nouveau_gem_pushbuf_reloc {
+	uint32_t bo_index;
+	uint32_t reloc_index;
+	uint32_t flags;
+	uint32_t data;
+	uint32_t vor;
+	uint32_t tor;
+};
+
+#define NOUVEAU_GEM_MAX_BUFFERS 1024
+#define NOUVEAU_GEM_MAX_RELOCS 1024
+
+struct drm_nouveau_gem_pushbuf {
+	uint32_t channel;
+	uint32_t nr_dwords;
+	uint32_t nr_buffers;
+	uint32_t nr_relocs;
+	uint64_t dwords;
+	uint64_t buffers;
+	uint64_t relocs;
+};
+
+struct drm_nouveau_gem_pushbuf_call {
+	uint32_t channel;
+	uint32_t handle;
+	uint32_t offset;
+	uint32_t nr_buffers;
+	uint32_t nr_relocs;
+	uint32_t nr_dwords;
+	uint64_t buffers;
+	uint64_t relocs;
+	uint32_t suffix0;
+	uint32_t suffix1;
+	/* below only accessed for CALL2 */
+	uint64_t vram_available;
+	uint64_t gart_available;
+};
+
+struct drm_nouveau_gem_pin {
+	uint32_t handle;
+	uint32_t domain;
+	uint64_t offset;
+};
+
+struct drm_nouveau_gem_unpin {
+	uint32_t handle;
+};
+
+#define NOUVEAU_GEM_CPU_PREP_NOWAIT                                  0x00000001
+#define NOUVEAU_GEM_CPU_PREP_NOBLOCK                                 0x00000002
+#define NOUVEAU_GEM_CPU_PREP_WRITE                                   0x00000004
+struct drm_nouveau_gem_cpu_prep {
+	uint32_t handle;
+	uint32_t flags;
+};
+
+struct drm_nouveau_gem_cpu_fini {
+	uint32_t handle;
+};
+
+struct drm_nouveau_gem_tile {
+	uint32_t handle;
+	uint32_t offset;
+	uint32_t size;
+	uint32_t tile_mode;
+	uint32_t tile_flags;
+};
+
+enum nouveau_bus_type {
+	NV_AGP     = 0,
+	NV_PCI     = 1,
+	NV_PCIE    = 2,
+};
+
+struct drm_nouveau_sarea {
+};
+
+#define DRM_NOUVEAU_CARD_INIT          0x00
+#define DRM_NOUVEAU_GETPARAM           0x01
+#define DRM_NOUVEAU_SETPARAM           0x02
+#define DRM_NOUVEAU_CHANNEL_ALLOC      0x03
+#define DRM_NOUVEAU_CHANNEL_FREE       0x04
+#define DRM_NOUVEAU_GROBJ_ALLOC        0x05
+#define DRM_NOUVEAU_NOTIFIEROBJ_ALLOC  0x06
+#define DRM_NOUVEAU_GPUOBJ_FREE        0x07
+#define DRM_NOUVEAU_GEM_NEW            0x40
+#define DRM_NOUVEAU_GEM_PUSHBUF        0x41
+#define DRM_NOUVEAU_GEM_PUSHBUF_CALL   0x42
+#define DRM_NOUVEAU_GEM_PIN            0x43 /* !KMS only */
+#define DRM_NOUVEAU_GEM_UNPIN          0x44 /* !KMS only */
+#define DRM_NOUVEAU_GEM_CPU_PREP       0x45
+#define DRM_NOUVEAU_GEM_CPU_FINI       0x46
+#define DRM_NOUVEAU_GEM_INFO           0x47
+#define DRM_NOUVEAU_GEM_PUSHBUF_CALL2  0x48
+
+#endif /* __NOUVEAU_DRM_H__ */
diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h
index 3b9932a..39537f3 100644
--- a/include/drm/radeon_drm.h
+++ b/include/drm/radeon_drm.h
@@ -33,7 +33,7 @@
 #ifndef __RADEON_DRM_H__
 #define __RADEON_DRM_H__
 
-#include <linux/types.h>
+#include "drm.h"
 
 /* WARNING: If you change any of these defines, make sure to change the
  * defines in the X server file (radeon_sarea.h)
diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h
index 4911461..81eb9f4 100644
--- a/include/drm/ttm/ttm_bo_api.h
+++ b/include/drm/ttm/ttm_bo_api.h
@@ -44,6 +44,29 @@
 
 struct drm_mm_node;
 
+
+/**
+ * struct ttm_placement
+ *
+ * @fpfn:		first valid page frame number to put the object
+ * @lpfn:		last valid page frame number to put the object
+ * @num_placement:	number of prefered placements
+ * @placement:		prefered placements
+ * @num_busy_placement:	number of prefered placements when need to evict buffer
+ * @busy_placement:	prefered placements when need to evict buffer
+ *
+ * Structure indicating the placement you request for an object.
+ */
+struct ttm_placement {
+	unsigned	fpfn;
+	unsigned	lpfn;
+	unsigned	num_placement;
+	const uint32_t	*placement;
+	unsigned	num_busy_placement;
+	const uint32_t	*busy_placement;
+};
+
+
 /**
  * struct ttm_mem_reg
  *
@@ -109,10 +132,6 @@
  * the object is destroyed.
  * @event_queue: Queue for processes waiting on buffer object status change.
  * @lock: spinlock protecting mostly synchronization members.
- * @proposed_placement: Proposed placement for the buffer. Changed only by the
- * creator prior to validation as opposed to bo->mem.proposed_flags which is
- * changed by the implementation prior to a buffer move if it wants to outsmart
- * the buffer creator / user. This latter happens, for example, at eviction.
  * @mem: structure describing current placement.
  * @persistant_swap_storage: Usually the swap storage is deleted for buffers
  * pinned in physical memory. If this behaviour is not desired, this member
@@ -177,7 +196,6 @@
 	 * Members protected by the bo::reserved lock.
 	 */
 
-	uint32_t proposed_placement;
 	struct ttm_mem_reg mem;
 	struct file *persistant_swap_storage;
 	struct ttm_tt *ttm;
@@ -285,29 +303,30 @@
  * Note: It might be necessary to block validations before the
  * wait by reserving the buffer.
  * Returns -EBUSY if no_wait is true and the buffer is busy.
- * Returns -ERESTART if interrupted by a signal.
+ * Returns -ERESTARTSYS if interrupted by a signal.
  */
 extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy,
 		       bool interruptible, bool no_wait);
 /**
- * ttm_buffer_object_validate
+ * ttm_bo_validate
  *
  * @bo: The buffer object.
- * @proposed_placement: Proposed_placement for the buffer object.
+ * @placement: Proposed placement for the buffer object.
  * @interruptible: Sleep interruptible if sleeping.
  * @no_wait: Return immediately if the buffer is busy.
  *
  * Changes placement and caching policy of the buffer object
- * according to bo::proposed_flags.
+ * according proposed placement.
  * Returns
- * -EINVAL on invalid proposed_flags.
+ * -EINVAL on invalid proposed placement.
  * -ENOMEM on out-of-memory condition.
  * -EBUSY if no_wait is true and buffer busy.
- * -ERESTART if interrupted by a signal.
+ * -ERESTARTSYS if interrupted by a signal.
  */
-extern int ttm_buffer_object_validate(struct ttm_buffer_object *bo,
-				      uint32_t proposed_placement,
-				      bool interruptible, bool no_wait);
+extern int ttm_bo_validate(struct ttm_buffer_object *bo,
+				struct ttm_placement *placement,
+				bool interruptible, bool no_wait);
+
 /**
  * ttm_bo_unref
  *
@@ -328,7 +347,7 @@
  * waiting for buffer idle. This lock is recursive.
  * Returns
  * -EBUSY if the buffer is busy and no_wait is true.
- * -ERESTART if interrupted by a signal.
+ * -ERESTARTSYS if interrupted by a signal.
  */
 
 extern int
@@ -343,7 +362,7 @@
 extern void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo);
 
 /**
- * ttm_buffer_object_init
+ * ttm_bo_init
  *
  * @bdev: Pointer to a ttm_bo_device struct.
  * @bo: Pointer to a ttm_buffer_object to be initialized.
@@ -371,20 +390,20 @@
  * Returns
  * -ENOMEM: Out of memory.
  * -EINVAL: Invalid placement flags.
- * -ERESTART: Interrupted by signal while sleeping waiting for resources.
+ * -ERESTARTSYS: Interrupted by signal while sleeping waiting for resources.
  */
 
-extern int ttm_buffer_object_init(struct ttm_bo_device *bdev,
-				  struct ttm_buffer_object *bo,
-				  unsigned long size,
-				  enum ttm_bo_type type,
-				  uint32_t flags,
-				  uint32_t page_alignment,
-				  unsigned long buffer_start,
-				  bool interrubtible,
-				  struct file *persistant_swap_storage,
-				  size_t acc_size,
-				  void (*destroy) (struct ttm_buffer_object *));
+extern int ttm_bo_init(struct ttm_bo_device *bdev,
+			struct ttm_buffer_object *bo,
+			unsigned long size,
+			enum ttm_bo_type type,
+			struct ttm_placement *placement,
+			uint32_t page_alignment,
+			unsigned long buffer_start,
+			bool interrubtible,
+			struct file *persistant_swap_storage,
+			size_t acc_size,
+			void (*destroy) (struct ttm_buffer_object *));
 /**
  * ttm_bo_synccpu_object_init
  *
@@ -405,47 +424,43 @@
  * GEM user interface.
  * @p_bo: On successful completion *p_bo points to the created object.
  *
- * This function allocates a ttm_buffer_object, and then calls
- * ttm_buffer_object_init on that object.
- * The destroy function is set to kfree().
+ * This function allocates a ttm_buffer_object, and then calls ttm_bo_init
+ * on that object. The destroy function is set to kfree().
  * Returns
  * -ENOMEM: Out of memory.
  * -EINVAL: Invalid placement flags.
- * -ERESTART: Interrupted by signal while waiting for resources.
+ * -ERESTARTSYS: Interrupted by signal while waiting for resources.
  */
 
-extern int ttm_buffer_object_create(struct ttm_bo_device *bdev,
-				    unsigned long size,
-				    enum ttm_bo_type type,
-				    uint32_t flags,
-				    uint32_t page_alignment,
-				    unsigned long buffer_start,
-				    bool interruptible,
-				    struct file *persistant_swap_storage,
-				    struct ttm_buffer_object **p_bo);
+extern int ttm_bo_create(struct ttm_bo_device *bdev,
+				unsigned long size,
+				enum ttm_bo_type type,
+				struct ttm_placement *placement,
+				uint32_t page_alignment,
+				unsigned long buffer_start,
+				bool interruptible,
+				struct file *persistant_swap_storage,
+				struct ttm_buffer_object **p_bo);
 
 /**
  * ttm_bo_check_placement
  *
- * @bo: the buffer object.
- * @set_flags: placement flags to set.
- * @clr_flags: placement flags to clear.
+ * @bo:		the buffer object.
+ * @placement:	placements
  *
  * Performs minimal validity checking on an intended change of
  * placement flags.
  * Returns
  * -EINVAL: Intended change is invalid or not allowed.
  */
-
 extern int ttm_bo_check_placement(struct ttm_buffer_object *bo,
-				  uint32_t set_flags, uint32_t clr_flags);
+					struct ttm_placement *placement);
 
 /**
  * ttm_bo_init_mm
  *
  * @bdev: Pointer to a ttm_bo_device struct.
  * @mem_type: The memory type.
- * @p_offset: offset for managed area in pages.
  * @p_size: size managed area in pages.
  *
  * Initialize a manager for a given memory type.
@@ -458,7 +473,7 @@
  */
 
 extern int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type,
-			  unsigned long p_offset, unsigned long p_size);
+				unsigned long p_size);
 /**
  * ttm_bo_clean_mm
  *
@@ -503,7 +518,7 @@
  *
  * Returns:
  * -EINVAL: Invalid or uninitialized memory type.
- * -ERESTART: The call was interrupted by a signal while waiting to
+ * -ERESTARTSYS: The call was interrupted by a signal while waiting to
  * evict a buffer.
  */
 
@@ -606,7 +621,7 @@
  * be called from the fops::read and fops::write method.
  * Returns:
  * See man (2) write, man(2) read. In particular,
- * the function may return -EINTR if
+ * the function may return -ERESTARTSYS if
  * interrupted by a signal.
  */
 
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
index e8cd6d2..ff7664e 100644
--- a/include/drm/ttm/ttm_bo_driver.h
+++ b/include/drm/ttm/ttm_bo_driver.h
@@ -242,12 +242,6 @@
 /**
  * struct ttm_bo_driver
  *
- * @mem_type_prio: Priority array of memory types to place a buffer object in
- * if it fits without evicting buffers from any of these memory types.
- * @mem_busy_prio: Priority array of memory types to place a buffer object in
- * if it needs to evict buffers to make room.
- * @num_mem_type_prio: Number of elements in the @mem_type_prio array.
- * @num_mem_busy_prio: Number of elements in the @num_mem_busy_prio array.
  * @create_ttm_backend_entry: Callback to create a struct ttm_backend.
  * @invalidate_caches: Callback to invalidate read caches when a buffer object
  * has been evicted.
@@ -265,11 +259,6 @@
  */
 
 struct ttm_bo_driver {
-	const uint32_t *mem_type_prio;
-	const uint32_t *mem_busy_prio;
-	uint32_t num_mem_type_prio;
-	uint32_t num_mem_busy_prio;
-
 	/**
 	 * struct ttm_bo_driver member create_ttm_backend_entry
 	 *
@@ -306,7 +295,8 @@
 	 * finished, they'll end up in bo->mem.flags
 	 */
 
-	 uint32_t(*evict_flags) (struct ttm_buffer_object *bo);
+	 void(*evict_flags) (struct ttm_buffer_object *bo,
+				struct ttm_placement *placement);
 	/**
 	 * struct ttm_bo_driver member move:
 	 *
@@ -545,6 +535,15 @@
 extern int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem);
 
 /**
+ * ttm_tt_populate:
+ *
+ * @ttm: The struct ttm_tt to contain the backing pages.
+ *
+ * Add backing pages to all of @ttm
+ */
+extern int ttm_tt_populate(struct ttm_tt *ttm);
+
+/**
  * ttm_ttm_destroy:
  *
  * @ttm: The struct ttm_tt.
@@ -639,12 +638,12 @@
  * -EBUSY: No space available (only if no_wait == 1).
  * -ENOMEM: Could not allocate memory for the buffer object, either due to
  * fragmentation or concurrent allocators.
- * -ERESTART: An interruptible sleep was interrupted by a signal.
+ * -ERESTARTSYS: An interruptible sleep was interrupted by a signal.
  */
 extern int ttm_bo_mem_space(struct ttm_buffer_object *bo,
-			    uint32_t proposed_placement,
-			    struct ttm_mem_reg *mem,
-			    bool interruptible, bool no_wait);
+				struct ttm_placement *placement,
+				struct ttm_mem_reg *mem,
+				bool interruptible, bool no_wait);
 /**
  * ttm_bo_wait_for_cpu
  *
@@ -654,7 +653,7 @@
  * Wait until a buffer object is no longer sync'ed for CPU access.
  * Returns:
  * -EBUSY: Buffer object was sync'ed for CPU access. (only if no_wait == 1).
- * -ERESTART: An interruptible sleep was interrupted by a signal.
+ * -ERESTARTSYS: An interruptible sleep was interrupted by a signal.
  */
 
 extern int ttm_bo_wait_cpu(struct ttm_buffer_object *bo, bool no_wait);
@@ -758,7 +757,7 @@
  * -EAGAIN: The reservation may cause a deadlock.
  * Release all buffer reservations, wait for @bo to become unreserved and
  * try again. (only if use_sequence == 1).
- * -ERESTART: A wait for the buffer to become unreserved was interrupted by
+ * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by
  * a signal. Release all buffer reservations and return to user-space.
  */
 extern int ttm_bo_reserve(struct ttm_buffer_object *bo,
@@ -799,7 +798,7 @@
  *
  * Returns:
  * -EBUSY: If no_wait == 1 and the buffer is already reserved.
- * -ERESTART: If interruptible == 1 and the process received a signal
+ * -ERESTARTSYS: If interruptible == 1 and the process received a signal
  * while sleeping.
  */
 extern int ttm_bo_block_reservation(struct ttm_buffer_object *bo,
diff --git a/include/drm/ttm/ttm_execbuf_util.h b/include/drm/ttm/ttm_execbuf_util.h
new file mode 100644
index 0000000..cd2c475
--- /dev/null
+++ b/include/drm/ttm/ttm_execbuf_util.h
@@ -0,0 +1,107 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+
+#ifndef _TTM_EXECBUF_UTIL_H_
+#define _TTM_EXECBUF_UTIL_H_
+
+#include "ttm/ttm_bo_api.h"
+#include <linux/list.h>
+
+/**
+ * struct ttm_validate_buffer
+ *
+ * @head:           list head for thread-private list.
+ * @bo:             refcounted buffer object pointer.
+ * @new_sync_obj_arg: New sync_obj_arg for @bo, to be used once
+ * adding a new sync object.
+ * @reservied:      Indicates whether @bo has been reserved for validation.
+ */
+
+struct ttm_validate_buffer {
+	struct list_head head;
+	struct ttm_buffer_object *bo;
+	void *new_sync_obj_arg;
+	bool reserved;
+};
+
+/**
+ * function ttm_eu_backoff_reservation
+ *
+ * @list:     thread private list of ttm_validate_buffer structs.
+ *
+ * Undoes all buffer validation reservations for bos pointed to by
+ * the list entries.
+ */
+
+extern void ttm_eu_backoff_reservation(struct list_head *list);
+
+/**
+ * function ttm_eu_reserve_buffers
+ *
+ * @list:    thread private list of ttm_validate_buffer structs.
+ * @val_seq: A unique sequence number.
+ *
+ * Tries to reserve bos pointed to by the list entries for validation.
+ * If the function returns 0, all buffers are marked as "unfenced",
+ * taken off the lru lists and are not synced for write CPU usage.
+ *
+ * If the function detects a deadlock due to multiple threads trying to
+ * reserve the same buffers in reverse order, all threads except one will
+ * back off and retry. This function may sleep while waiting for
+ * CPU write reservations to be cleared, and for other threads to
+ * unreserve their buffers.
+ *
+ * This function may return -ERESTART or -EAGAIN if the calling process
+ * receives a signal while waiting. In that case, no buffers on the list
+ * will be reserved upon return.
+ *
+ * Buffers reserved by this function should be unreserved by
+ * a call to either ttm_eu_backoff_reservation() or
+ * ttm_eu_fence_buffer_objects() when command submission is complete or
+ * has failed.
+ */
+
+extern int ttm_eu_reserve_buffers(struct list_head *list, uint32_t val_seq);
+
+/**
+ * function ttm_eu_fence_buffer_objects.
+ *
+ * @list:        thread private list of ttm_validate_buffer structs.
+ * @sync_obj:    The new sync object for the buffers.
+ *
+ * This function should be called when command submission is complete, and
+ * it will add a new sync object to bos pointed to by entries on @list.
+ * It also unreserves all buffers, putting them on lru lists.
+ *
+ */
+
+extern void ttm_eu_fence_buffer_objects(struct list_head *list, void *sync_obj);
+
+#endif
diff --git a/include/drm/ttm/ttm_lock.h b/include/drm/ttm/ttm_lock.h
new file mode 100644
index 0000000..81ba0b0
--- /dev/null
+++ b/include/drm/ttm/ttm_lock.h
@@ -0,0 +1,247 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2007-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+
+/** @file ttm_lock.h
+ * This file implements a simple replacement for the buffer manager use
+ * of the DRM heavyweight hardware lock.
+ * The lock is a read-write lock. Taking it in read mode and write mode
+ * is relatively fast, and intended for in-kernel use only.
+ *
+ * The vt mode is used only when there is a need to block all
+ * user-space processes from validating buffers.
+ * It's allowed to leave kernel space with the vt lock held.
+ * If a user-space process dies while having the vt-lock,
+ * it will be released during the file descriptor release. The vt lock
+ * excludes write lock and read lock.
+ *
+ * The suspend mode is used to lock out all TTM users when preparing for
+ * and executing suspend operations.
+ *
+ */
+
+#ifndef _TTM_LOCK_H_
+#define _TTM_LOCK_H_
+
+#include "ttm/ttm_object.h"
+#include <linux/wait.h>
+#include <asm/atomic.h>
+
+/**
+ * struct ttm_lock
+ *
+ * @base: ttm base object used solely to release the lock if the client
+ * holding the lock dies.
+ * @queue: Queue for processes waiting for lock change-of-status.
+ * @lock: Spinlock protecting some lock members.
+ * @rw: Read-write lock counter. Protected by @lock.
+ * @flags: Lock state. Protected by @lock.
+ * @kill_takers: Boolean whether to kill takers of the lock.
+ * @signal: Signal to send when kill_takers is true.
+ */
+
+struct ttm_lock {
+	struct ttm_base_object base;
+	wait_queue_head_t queue;
+	spinlock_t lock;
+	int32_t rw;
+	uint32_t flags;
+	bool kill_takers;
+	int signal;
+	struct ttm_object_file *vt_holder;
+};
+
+
+/**
+ * ttm_lock_init
+ *
+ * @lock: Pointer to a struct ttm_lock
+ * Initializes the lock.
+ */
+extern void ttm_lock_init(struct ttm_lock *lock);
+
+/**
+ * ttm_read_unlock
+ *
+ * @lock: Pointer to a struct ttm_lock
+ *
+ * Releases a read lock.
+ */
+extern void ttm_read_unlock(struct ttm_lock *lock);
+
+/**
+ * ttm_read_lock
+ *
+ * @lock: Pointer to a struct ttm_lock
+ * @interruptible: Interruptible sleeping while waiting for a lock.
+ *
+ * Takes the lock in read mode.
+ * Returns:
+ * -ERESTARTSYS If interrupted by a signal and interruptible is true.
+ */
+extern int ttm_read_lock(struct ttm_lock *lock, bool interruptible);
+
+/**
+ * ttm_read_trylock
+ *
+ * @lock: Pointer to a struct ttm_lock
+ * @interruptible: Interruptible sleeping while waiting for a lock.
+ *
+ * Tries to take the lock in read mode. If the lock is already held
+ * in write mode, the function will return -EBUSY. If the lock is held
+ * in vt or suspend mode, the function will sleep until these modes
+ * are unlocked.
+ *
+ * Returns:
+ * -EBUSY The lock was already held in write mode.
+ * -ERESTARTSYS If interrupted by a signal and interruptible is true.
+ */
+extern int ttm_read_trylock(struct ttm_lock *lock, bool interruptible);
+
+/**
+ * ttm_write_unlock
+ *
+ * @lock: Pointer to a struct ttm_lock
+ *
+ * Releases a write lock.
+ */
+extern void ttm_write_unlock(struct ttm_lock *lock);
+
+/**
+ * ttm_write_lock
+ *
+ * @lock: Pointer to a struct ttm_lock
+ * @interruptible: Interruptible sleeping while waiting for a lock.
+ *
+ * Takes the lock in write mode.
+ * Returns:
+ * -ERESTARTSYS If interrupted by a signal and interruptible is true.
+ */
+extern int ttm_write_lock(struct ttm_lock *lock, bool interruptible);
+
+/**
+ * ttm_lock_downgrade
+ *
+ * @lock: Pointer to a struct ttm_lock
+ *
+ * Downgrades a write lock to a read lock.
+ */
+extern void ttm_lock_downgrade(struct ttm_lock *lock);
+
+/**
+ * ttm_suspend_lock
+ *
+ * @lock: Pointer to a struct ttm_lock
+ *
+ * Takes the lock in suspend mode. Excludes read and write mode.
+ */
+extern void ttm_suspend_lock(struct ttm_lock *lock);
+
+/**
+ * ttm_suspend_unlock
+ *
+ * @lock: Pointer to a struct ttm_lock
+ *
+ * Releases a suspend lock
+ */
+extern void ttm_suspend_unlock(struct ttm_lock *lock);
+
+/**
+ * ttm_vt_lock
+ *
+ * @lock: Pointer to a struct ttm_lock
+ * @interruptible: Interruptible sleeping while waiting for a lock.
+ * @tfile: Pointer to a struct ttm_object_file to register the lock with.
+ *
+ * Takes the lock in vt mode.
+ * Returns:
+ * -ERESTARTSYS If interrupted by a signal and interruptible is true.
+ * -ENOMEM: Out of memory when locking.
+ */
+extern int ttm_vt_lock(struct ttm_lock *lock, bool interruptible,
+		       struct ttm_object_file *tfile);
+
+/**
+ * ttm_vt_unlock
+ *
+ * @lock: Pointer to a struct ttm_lock
+ *
+ * Releases a vt lock.
+ * Returns:
+ * -EINVAL If the lock was not held.
+ */
+extern int ttm_vt_unlock(struct ttm_lock *lock);
+
+/**
+ * ttm_write_unlock
+ *
+ * @lock: Pointer to a struct ttm_lock
+ *
+ * Releases a write lock.
+ */
+extern void ttm_write_unlock(struct ttm_lock *lock);
+
+/**
+ * ttm_write_lock
+ *
+ * @lock: Pointer to a struct ttm_lock
+ * @interruptible: Interruptible sleeping while waiting for a lock.
+ *
+ * Takes the lock in write mode.
+ * Returns:
+ * -ERESTARTSYS If interrupted by a signal and interruptible is true.
+ */
+extern int ttm_write_lock(struct ttm_lock *lock, bool interruptible);
+
+/**
+ * ttm_lock_set_kill
+ *
+ * @lock: Pointer to a struct ttm_lock
+ * @val: Boolean whether to kill processes taking the lock.
+ * @signal: Signal to send to the process taking the lock.
+ *
+ * The kill-when-taking-lock functionality is used to kill processes that keep
+ * on using the TTM functionality when its resources has been taken down, for
+ * example when the X server exits. A typical sequence would look like this:
+ * - X server takes lock in write mode.
+ * - ttm_lock_set_kill() is called with @val set to true.
+ * - As part of X server exit, TTM resources are taken down.
+ * - X server releases the lock on file release.
+ * - Another dri client wants to render, takes the lock and is killed.
+ *
+ */
+static inline void ttm_lock_set_kill(struct ttm_lock *lock, bool val,
+				     int signal)
+{
+	lock->kill_takers = val;
+	if (val)
+		lock->signal = signal;
+}
+
+#endif
diff --git a/include/drm/ttm/ttm_memory.h b/include/drm/ttm/ttm_memory.h
index 6983a7c..b199170 100644
--- a/include/drm/ttm/ttm_memory.h
+++ b/include/drm/ttm/ttm_memory.h
@@ -33,6 +33,7 @@
 #include <linux/wait.h>
 #include <linux/errno.h>
 #include <linux/kobject.h>
+#include <linux/mm.h>
 
 /**
  * struct ttm_mem_shrink - callback to shrink TTM memory usage.
diff --git a/include/drm/ttm/ttm_object.h b/include/drm/ttm/ttm_object.h
new file mode 100644
index 0000000..703ca4d
--- /dev/null
+++ b/include/drm/ttm/ttm_object.h
@@ -0,0 +1,267 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+/** @file ttm_object.h
+ *
+ * Base- and reference object implementation for the various
+ * ttm objects. Implements reference counting, minimal security checks
+ * and release on file close.
+ */
+
+#ifndef _TTM_OBJECT_H_
+#define _TTM_OBJECT_H_
+
+#include <linux/list.h>
+#include "drm_hashtab.h"
+#include <linux/kref.h>
+#include <ttm/ttm_memory.h>
+
+/**
+ * enum ttm_ref_type
+ *
+ * Describes what type of reference a ref object holds.
+ *
+ * TTM_REF_USAGE is a simple refcount on a base object.
+ *
+ * TTM_REF_SYNCCPU_READ is a SYNCCPU_READ reference on a
+ * buffer object.
+ *
+ * TTM_REF_SYNCCPU_WRITE is a SYNCCPU_WRITE reference on a
+ * buffer object.
+ *
+ */
+
+enum ttm_ref_type {
+	TTM_REF_USAGE,
+	TTM_REF_SYNCCPU_READ,
+	TTM_REF_SYNCCPU_WRITE,
+	TTM_REF_NUM
+};
+
+/**
+ * enum ttm_object_type
+ *
+ * One entry per ttm object type.
+ * Device-specific types should use the
+ * ttm_driver_typex types.
+ */
+
+enum ttm_object_type {
+	ttm_fence_type,
+	ttm_buffer_type,
+	ttm_lock_type,
+	ttm_driver_type0 = 256,
+	ttm_driver_type1
+};
+
+struct ttm_object_file;
+struct ttm_object_device;
+
+/**
+ * struct ttm_base_object
+ *
+ * @hash: hash entry for the per-device object hash.
+ * @type: derived type this object is base class for.
+ * @shareable: Other ttm_object_files can access this object.
+ *
+ * @tfile: Pointer to ttm_object_file of the creator.
+ * NULL if the object was not created by a user request.
+ * (kernel object).
+ *
+ * @refcount: Number of references to this object, not
+ * including the hash entry. A reference to a base object can
+ * only be held by a ref object.
+ *
+ * @refcount_release: A function to be called when there are
+ * no more references to this object. This function should
+ * destroy the object (or make sure destruction eventually happens),
+ * and when it is called, the object has
+ * already been taken out of the per-device hash. The parameter
+ * "base" should be set to NULL by the function.
+ *
+ * @ref_obj_release: A function to be called when a reference object
+ * with another ttm_ref_type than TTM_REF_USAGE is deleted.
+ * this function may, for example, release a lock held by a user-space
+ * process.
+ *
+ * This struct is intended to be used as a base struct for objects that
+ * are visible to user-space. It provides a global name, race-safe
+ * access and refcounting, minimal access contol and hooks for unref actions.
+ */
+
+struct ttm_base_object {
+	struct drm_hash_item hash;
+	enum ttm_object_type object_type;
+	bool shareable;
+	struct ttm_object_file *tfile;
+	struct kref refcount;
+	void (*refcount_release) (struct ttm_base_object **base);
+	void (*ref_obj_release) (struct ttm_base_object *base,
+				 enum ttm_ref_type ref_type);
+};
+
+/**
+ * ttm_base_object_init
+ *
+ * @tfile: Pointer to a struct ttm_object_file.
+ * @base: The struct ttm_base_object to initialize.
+ * @shareable: This object is shareable with other applcations.
+ * (different @tfile pointers.)
+ * @type: The object type.
+ * @refcount_release: See the struct ttm_base_object description.
+ * @ref_obj_release: See the struct ttm_base_object description.
+ *
+ * Initializes a struct ttm_base_object.
+ */
+
+extern int ttm_base_object_init(struct ttm_object_file *tfile,
+				struct ttm_base_object *base,
+				bool shareable,
+				enum ttm_object_type type,
+				void (*refcount_release) (struct ttm_base_object
+							  **),
+				void (*ref_obj_release) (struct ttm_base_object
+							 *,
+							 enum ttm_ref_type
+							 ref_type));
+
+/**
+ * ttm_base_object_lookup
+ *
+ * @tfile: Pointer to a struct ttm_object_file.
+ * @key: Hash key
+ *
+ * Looks up a struct ttm_base_object with the key @key.
+ * Also verifies that the object is visible to the application, by
+ * comparing the @tfile argument and checking the object shareable flag.
+ */
+
+extern struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file
+						      *tfile, uint32_t key);
+
+/**
+ * ttm_base_object_unref
+ *
+ * @p_base: Pointer to a pointer referncing a struct ttm_base_object.
+ *
+ * Decrements the base object refcount and clears the pointer pointed to by
+ * p_base.
+ */
+
+extern void ttm_base_object_unref(struct ttm_base_object **p_base);
+
+/**
+ * ttm_ref_object_add.
+ *
+ * @tfile: A struct ttm_object_file representing the application owning the
+ * ref_object.
+ * @base: The base object to reference.
+ * @ref_type: The type of reference.
+ * @existed: Upon completion, indicates that an identical reference object
+ * already existed, and the refcount was upped on that object instead.
+ *
+ * Adding a ref object to a base object is basically like referencing the
+ * base object, but a user-space application holds the reference. When the
+ * file corresponding to @tfile is closed, all its reference objects are
+ * deleted. A reference object can have different types depending on what
+ * it's intended for. It can be refcounting to prevent object destruction,
+ * When user-space takes a lock, it can add a ref object to that lock to
+ * make sure the lock is released if the application dies. A ref object
+ * will hold a single reference on a base object.
+ */
+extern int ttm_ref_object_add(struct ttm_object_file *tfile,
+			      struct ttm_base_object *base,
+			      enum ttm_ref_type ref_type, bool *existed);
+/**
+ * ttm_ref_object_base_unref
+ *
+ * @key: Key representing the base object.
+ * @ref_type: Ref type of the ref object to be dereferenced.
+ *
+ * Unreference a ref object with type @ref_type
+ * on the base object identified by @key. If there are no duplicate
+ * references, the ref object will be destroyed and the base object
+ * will be unreferenced.
+ */
+extern int ttm_ref_object_base_unref(struct ttm_object_file *tfile,
+				     unsigned long key,
+				     enum ttm_ref_type ref_type);
+
+/**
+ * ttm_object_file_init - initialize a struct ttm_object file
+ *
+ * @tdev: A struct ttm_object device this file is initialized on.
+ * @hash_order: Order of the hash table used to hold the reference objects.
+ *
+ * This is typically called by the file_ops::open function.
+ */
+
+extern struct ttm_object_file *ttm_object_file_init(struct ttm_object_device
+						    *tdev,
+						    unsigned int hash_order);
+
+/**
+ * ttm_object_file_release - release data held by a ttm_object_file
+ *
+ * @p_tfile: Pointer to pointer to the ttm_object_file object to release.
+ * *p_tfile will be set to NULL by this function.
+ *
+ * Releases all data associated by a ttm_object_file.
+ * Typically called from file_ops::release. The caller must
+ * ensure that there are no concurrent users of tfile.
+ */
+
+extern void ttm_object_file_release(struct ttm_object_file **p_tfile);
+
+/**
+ * ttm_object device init - initialize a struct ttm_object_device
+ *
+ * @hash_order: Order of hash table used to hash the base objects.
+ *
+ * This function is typically called on device initialization to prepare
+ * data structures needed for ttm base and ref objects.
+ */
+
+extern struct ttm_object_device *ttm_object_device_init
+    (struct ttm_mem_global *mem_glob, unsigned int hash_order);
+
+/**
+ * ttm_object_device_release - release data held by a ttm_object_device
+ *
+ * @p_tdev: Pointer to pointer to the ttm_object_device object to release.
+ * *p_tdev will be set to NULL by this function.
+ *
+ * Releases all data associated by a ttm_object_device.
+ * Typically called from driver::unload before the destruction of the
+ * device private data structure.
+ */
+
+extern void ttm_object_device_release(struct ttm_object_device **p_tdev);
+
+#endif
diff --git a/include/drm/via_drm.h b/include/drm/via_drm.h
index 170786e..fd11a5b 100644
--- a/include/drm/via_drm.h
+++ b/include/drm/via_drm.h
@@ -24,7 +24,7 @@
 #ifndef _VIA_DRM_H_
 #define _VIA_DRM_H_
 
-#include <linux/types.h>
+#include "drm.h"
 
 /* WARNING: These defines must be the same as what the Xserver uses.
  * if you change them, you must change the defines in the Xserver.
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 5a53857..f72914d 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -214,7 +214,6 @@
 unifdef-y += fs.h
 unifdef-y += gameport.h
 unifdef-y += generic_serial.h
-unifdef-y += hayesesp.h
 unifdef-y += hdlcdrv.h
 unifdef-y += hdlc.h
 unifdef-y += hdreg.h
diff --git a/include/linux/cciss_ioctl.h b/include/linux/cciss_ioctl.h
index cb57c30..eb130b4 100644
--- a/include/linux/cciss_ioctl.h
+++ b/include/linux/cciss_ioctl.h
@@ -39,7 +39,7 @@
 #ifndef CCISS_CMD_H
 // This defines are duplicated in cciss_cmd.h in the driver directory 
 
-//general boundary defintions
+//general boundary definitions
 #define SENSEINFOBYTES          32//note that this value may vary between host implementations
 
 //Command Status value
diff --git a/include/linux/chio.h b/include/linux/chio.h
index 519248d..d9bac7f 100644
--- a/include/linux/chio.h
+++ b/include/linux/chio.h
@@ -21,7 +21,7 @@
  *    query vendor-specific element types
  *
  *    accessing elements works by specifing type and unit of the element.
- *    for eample, storage elements are addressed with type = CHET_ST and
+ *    for example, storage elements are addressed with type = CHET_ST and
  *    unit = 0 .. cp_nslots-1
  *
  */
diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index 3a1dbba..0cf725b 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -77,10 +77,10 @@
 struct clock_event_device {
 	const char		*name;
 	unsigned int		features;
-	unsigned long		max_delta_ns;
-	unsigned long		min_delta_ns;
-	unsigned long		mult;
-	int			shift;
+	u64			max_delta_ns;
+	u64			min_delta_ns;
+	u32			mult;
+	u32			shift;
 	int			rating;
 	int			irq;
 	const struct cpumask	*cpumask;
@@ -116,8 +116,8 @@
 }
 
 /* Clock event layer functions */
-extern unsigned long clockevent_delta2ns(unsigned long latch,
-					 struct clock_event_device *evt);
+extern u64 clockevent_delta2ns(unsigned long latch,
+			       struct clock_event_device *evt);
 extern void clockevents_register_device(struct clock_event_device *dev);
 
 extern void clockevents_exchange_device(struct clock_event_device *old,
@@ -130,6 +130,13 @@
 
 extern void clockevents_handle_noop(struct clock_event_device *dev);
 
+static inline void
+clockevents_calc_mult_shift(struct clock_event_device *ce, u32 freq, u32 minsec)
+{
+	return clocks_calc_mult_shift(&ce->mult, &ce->shift, NSEC_PER_SEC,
+				      freq, minsec);
+}
+
 #ifdef CONFIG_GENERIC_CLOCKEVENTS
 extern void clockevents_notify(unsigned long reason, void *arg);
 #else
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index 83d2fbd..8a4a130 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -151,6 +151,7 @@
  *			subtraction of non 64 bit counters
  * @mult:		cycle to nanosecond multiplier
  * @shift:		cycle to nanosecond divisor (power of two)
+ * @max_idle_ns:	max idle time permitted by the clocksource (nsecs)
  * @flags:		flags describing special properties
  * @vread:		vsyscall based read
  * @resume:		resume function for the clocksource, if necessary
@@ -168,6 +169,7 @@
 	cycle_t mask;
 	u32 mult;
 	u32 shift;
+	u64 max_idle_ns;
 	unsigned long flags;
 	cycle_t (*vread)(void);
 	void (*resume)(void);
@@ -279,11 +281,23 @@
 extern struct clocksource * __init __weak clocksource_default_clock(void);
 extern void clocksource_mark_unstable(struct clocksource *cs);
 
+extern void
+clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 minsec);
+
+static inline void
+clocksource_calc_mult_shift(struct clocksource *cs, u32 freq, u32 minsec)
+{
+	return clocks_calc_mult_shift(&cs->mult, &cs->shift, freq,
+				      NSEC_PER_SEC, minsec);
+}
+
 #ifdef CONFIG_GENERIC_TIME_VSYSCALL
-extern void update_vsyscall(struct timespec *ts, struct clocksource *c);
+extern void
+update_vsyscall(struct timespec *ts, struct clocksource *c, u32 mult);
 extern void update_vsyscall_tz(void);
 #else
-static inline void update_vsyscall(struct timespec *ts, struct clocksource *c)
+static inline void
+update_vsyscall(struct timespec *ts, struct clocksource *c, u32 mult)
 {
 }
 
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 79a2340..4de02b1 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -232,6 +232,7 @@
 	/* optional */
 	unsigned int (*getavg)	(struct cpufreq_policy *policy,
 				 unsigned int cpu);
+	int	(*bios_limit)	(int cpu, unsigned int *limit);
 
 	int	(*exit)		(struct cpufreq_policy *policy);
 	int	(*suspend)	(struct cpufreq_policy *policy, pm_message_t pmsg);
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index fd92988..24d2e30 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -250,29 +250,6 @@
 	void (*cia_decrypt)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
 };
 
-struct digest_alg {
-	unsigned int dia_digestsize;
-	void (*dia_init)(struct crypto_tfm *tfm);
-	void (*dia_update)(struct crypto_tfm *tfm, const u8 *data,
-			   unsigned int len);
-	void (*dia_final)(struct crypto_tfm *tfm, u8 *out);
-	int (*dia_setkey)(struct crypto_tfm *tfm, const u8 *key,
-	                  unsigned int keylen);
-};
-
-struct hash_alg {
-	int (*init)(struct hash_desc *desc);
-	int (*update)(struct hash_desc *desc, struct scatterlist *sg,
-		      unsigned int nbytes);
-	int (*final)(struct hash_desc *desc, u8 *out);
-	int (*digest)(struct hash_desc *desc, struct scatterlist *sg,
-		      unsigned int nbytes, u8 *out);
-	int (*setkey)(struct crypto_hash *tfm, const u8 *key,
-		      unsigned int keylen);
-
-	unsigned int digestsize;
-};
-
 struct compress_alg {
 	int (*coa_compress)(struct crypto_tfm *tfm, const u8 *src,
 			    unsigned int slen, u8 *dst, unsigned int *dlen);
@@ -293,8 +270,6 @@
 #define cra_aead	cra_u.aead
 #define cra_blkcipher	cra_u.blkcipher
 #define cra_cipher	cra_u.cipher
-#define cra_digest	cra_u.digest
-#define cra_hash	cra_u.hash
 #define cra_compress	cra_u.compress
 #define cra_rng		cra_u.rng
 
@@ -320,8 +295,6 @@
 		struct aead_alg aead;
 		struct blkcipher_alg blkcipher;
 		struct cipher_alg cipher;
-		struct digest_alg digest;
-		struct hash_alg hash;
 		struct compress_alg compress;
 		struct rng_alg rng;
 	} cra_u;
diff --git a/include/linux/device.h b/include/linux/device.h
index 2ea3e49..2a73d9b 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -558,7 +558,7 @@
 #ifdef CONFIG_DEVTMPFS
 extern int devtmpfs_create_node(struct device *dev);
 extern int devtmpfs_delete_node(struct device *dev);
-extern int devtmpfs_mount(const char *mountpoint);
+extern int devtmpfs_mount(const char *mntdir);
 #else
 static inline int devtmpfs_create_node(struct device *dev) { return 0; }
 static inline int devtmpfs_delete_node(struct device *dev) { return 0; }
diff --git a/include/linux/dm-log-userspace.h b/include/linux/dm-log-userspace.h
index 8a1f972..0c3c3a2 100644
--- a/include/linux/dm-log-userspace.h
+++ b/include/linux/dm-log-userspace.h
@@ -363,7 +363,7 @@
  * various request types above.  The remaining 24-bits are currently
  * set to zero and are reserved for future use and compatibility concerns.
  *
- * User-space should always use DM_ULOG_REQUEST_TYPE to aquire the
+ * User-space should always use DM_ULOG_REQUEST_TYPE to acquire the
  * request type from the 'request_type' field to maintain forward compatibility.
  */
 #define DM_ULOG_REQUEST_MASK 0xFF
diff --git a/include/linux/dmar.h b/include/linux/dmar.h
index 5de4c9e..d7cecc9 100644
--- a/include/linux/dmar.h
+++ b/include/linux/dmar.h
@@ -126,7 +126,9 @@
 extern int irq_remapped(int irq);
 extern struct intel_iommu *map_dev_to_ir(struct pci_dev *dev);
 extern struct intel_iommu *map_ioapic_to_ir(int apic);
+extern struct intel_iommu *map_hpet_to_ir(u8 id);
 extern int set_ioapic_sid(struct irte *irte, int apic);
+extern int set_hpet_sid(struct irte *irte, u8 id);
 extern int set_msi_sid(struct irte *irte, struct pci_dev *dev);
 #else
 static inline int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
@@ -158,10 +160,18 @@
 {
 	return NULL;
 }
+static inline struct intel_iommu *map_hpet_to_ir(unsigned int hpet_id)
+{
+	return NULL;
+}
 static inline int set_ioapic_sid(struct irte *irte, int apic)
 {
 	return 0;
 }
+static inline int set_hpet_sid(struct irte *irte, u8 id)
+{
+	return -1;
+}
 static inline int set_msi_sid(struct irte *irte, struct pci_dev *dev)
 {
 	return 0;
diff --git a/include/linux/ext2_fs.h b/include/linux/ext2_fs.h
index 121720d..2dfa707 100644
--- a/include/linux/ext2_fs.h
+++ b/include/linux/ext2_fs.h
@@ -565,14 +565,14 @@
  * other bits are reserved for now.
  */
 enum {
-	EXT2_FT_UNKNOWN,
-	EXT2_FT_REG_FILE,
-	EXT2_FT_DIR,
-	EXT2_FT_CHRDEV,
-	EXT2_FT_BLKDEV,
-	EXT2_FT_FIFO,
-	EXT2_FT_SOCK,
-	EXT2_FT_SYMLINK,
+	EXT2_FT_UNKNOWN		= 0,
+	EXT2_FT_REG_FILE	= 1,
+	EXT2_FT_DIR		= 2,
+	EXT2_FT_CHRDEV		= 3,
+	EXT2_FT_BLKDEV		= 4,
+	EXT2_FT_FIFO		= 5,
+	EXT2_FT_SOCK		= 6,
+	EXT2_FT_SYMLINK		= 7,
 	EXT2_FT_MAX
 };
 
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index 7499b36..6b04903 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -918,6 +918,8 @@
 	__attribute__ ((format (printf, 3, 4)));
 extern void ext3_warning (struct super_block *, const char *, const char *, ...)
 	__attribute__ ((format (printf, 3, 4)));
+extern void ext3_msg(struct super_block *, const char *, const char *, ...)
+	__attribute__ ((format (printf, 3, 4)));
 extern void ext3_update_dynamic_rev (struct super_block *sb);
 
 #define ext3_std_error(sb, errno)				\
diff --git a/include/linux/fb.h b/include/linux/fb.h
index de9c722..369767b 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -763,6 +763,7 @@
 	 *  takes over; acceleration engine should be in a quiescent state */
 
 /* hints */
+#define FBINFO_VIRTFB		0x0004 /* FB is System RAM, not device. */
 #define FBINFO_PARTIAL_PAN_OK	0x0040 /* otw use pan only for double-buffering */
 #define FBINFO_READS_FAST	0x0080 /* soft-copy faster than rendering */
 
diff --git a/include/linux/firmware.h b/include/linux/firmware.h
index d315446..043811f 100644
--- a/include/linux/firmware.h
+++ b/include/linux/firmware.h
@@ -4,6 +4,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/compiler.h>
+#include <linux/gfp.h>
 
 #define FW_ACTION_NOHOTPLUG 0
 #define FW_ACTION_HOTPLUG 1
@@ -38,7 +39,7 @@
 		     struct device *device);
 int request_firmware_nowait(
 	struct module *module, int uevent,
-	const char *name, struct device *device, void *context,
+	const char *name, struct device *device, gfp_t gfp, void *context,
 	void (*cont)(const struct firmware *fw, void *context));
 
 void release_firmware(const struct firmware *fw);
@@ -51,7 +52,7 @@
 }
 static inline int request_firmware_nowait(
 	struct module *module, int uevent,
-	const char *name, struct device *device, void *context,
+	const char *name, struct device *device, gfp_t gfp, void *context,
 	void (*cont)(const struct firmware *fw, void *context))
 {
 	return -EINVAL;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 891f7d6..a057f48 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2091,8 +2091,6 @@
 extern int filemap_write_and_wait(struct address_space *mapping);
 extern int filemap_write_and_wait_range(struct address_space *mapping,
 				        loff_t lstart, loff_t lend);
-extern int wait_on_page_writeback_range(struct address_space *mapping,
-				pgoff_t start, pgoff_t end);
 extern int __filemap_fdatawrite_range(struct address_space *mapping,
 				loff_t start, loff_t end, int sync_mode);
 extern int filemap_fdatawrite_range(struct address_space *mapping,
diff --git a/include/linux/hayesesp.h b/include/linux/hayesesp.h
deleted file mode 100644
index 92b08cf..0000000
--- a/include/linux/hayesesp.h
+++ /dev/null
@@ -1,114 +0,0 @@
-#ifndef HAYESESP_H
-#define HAYESESP_H
-
-struct hayes_esp_config {
-	short flow_on;
-	short flow_off;
-	short rx_trigger;
-	short tx_trigger;
-	short pio_threshold;
-	unsigned char rx_timeout;
-	char dma_channel;
-};
-
-#ifdef __KERNEL__
-
-#define ESP_DMA_CHANNEL   0
-#define ESP_RX_TRIGGER    768
-#define ESP_TX_TRIGGER    768
-#define ESP_FLOW_OFF      1016
-#define ESP_FLOW_ON       944
-#define ESP_RX_TMOUT      128
-#define ESP_PIO_THRESHOLD 32
-
-#define ESP_IN_MAJOR	57	/* major dev # for dial in */
-#define ESP_OUT_MAJOR	58	/* major dev # for dial out */
-#define ESPC_SCALE 	3
-#define UART_ESI_BASE	0x00
-#define UART_ESI_SID	0x01
-#define UART_ESI_RX	0x02
-#define UART_ESI_TX	0x02
-#define UART_ESI_CMD1	0x04
-#define UART_ESI_CMD2	0x05
-#define UART_ESI_STAT1	0x04
-#define UART_ESI_STAT2	0x05
-#define UART_ESI_RWS	0x07
-
-#define UART_IER_DMA_TMOUT	0x80
-#define UART_IER_DMA_TC		0x08
-
-#define ESI_SET_IRQ		0x04
-#define ESI_SET_DMA_TMOUT	0x05
-#define ESI_SET_SRV_MASK	0x06
-#define ESI_SET_ERR_MASK	0x07
-#define ESI_SET_FLOW_CNTL	0x08
-#define ESI_SET_FLOW_CHARS	0x09
-#define ESI_SET_FLOW_LVL	0x0a
-#define ESI_SET_TRIGGER		0x0b
-#define ESI_SET_RX_TIMEOUT	0x0c
-#define ESI_SET_FLOW_TMOUT	0x0d
-#define ESI_WRITE_UART		0x0e
-#define ESI_READ_UART		0x0f
-#define ESI_SET_MODE		0x10
-#define ESI_GET_ERR_STAT	0x12
-#define ESI_GET_UART_STAT	0x13
-#define ESI_GET_RX_AVAIL	0x14
-#define ESI_GET_TX_AVAIL	0x15
-#define ESI_START_DMA_RX	0x16
-#define ESI_START_DMA_TX	0x17
-#define ESI_ISSUE_BREAK		0x1a
-#define ESI_FLUSH_RX		0x1b
-#define ESI_FLUSH_TX		0x1c
-#define ESI_SET_BAUD		0x1d
-#define ESI_SET_ENH_IRQ		0x1f
-#define ESI_SET_REINTR		0x20
-#define ESI_SET_PRESCALAR	0x23
-#define ESI_NO_COMMAND		0xff
-
-#define ESP_STAT_RX_TIMEOUT	0x01
-#define ESP_STAT_DMA_RX		0x02
-#define ESP_STAT_DMA_TX		0x04
-#define ESP_STAT_NEVER_DMA      0x08
-#define ESP_STAT_USE_PIO        0x10
-
-#define ESP_MAGIC		0x53ee
-#define ESP_XMIT_SIZE		4096
-
-struct esp_struct {
-	int			magic;
-	struct tty_port		port;
-	spinlock_t		lock;
-	int			io_port;
-	int			irq;
-	int			read_status_mask;
-	int			ignore_status_mask;
-	int			timeout;
-	int			stat_flags;
-	int			custom_divisor;
-	int			close_delay;
-	unsigned short		closing_wait;
-	unsigned short		closing_wait2;
-	int			IER; 	/* Interrupt Enable Register */
-	int			MCR; 	/* Modem control register */
-	unsigned long		last_active;
-	int			line;
-	unsigned char 		*xmit_buf;
-	int			xmit_head;
-	int			xmit_tail;
-	int			xmit_cnt;
-	wait_queue_head_t	break_wait;
-	struct async_icount	icount;	/* kernel counters for the 4 input interrupts */
-	struct hayes_esp_config config; /* port configuration */
-	struct esp_struct	*next_port; /* For the linked list */
-};
-
-struct esp_pio_buffer {
-	unsigned char data[1024];
-	struct esp_pio_buffer *next;
-};
-
-#endif /* __KERNEL__ */
-
-
-#endif /* ESP_H */
-
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 10f6284..8709365 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -312,6 +312,7 @@
 #define HID_QUIRK_MULTI_INPUT			0x00000040
 #define HID_QUIRK_SKIP_OUTPUT_REPORTS		0x00010000
 #define HID_QUIRK_FULLSPEED_INTERVAL		0x10000000
+#define HID_QUIRK_NO_INIT_REPORTS		0x20000000
 
 /*
  * This is the global environment of the parser. This information is
diff --git a/include/linux/hpet.h b/include/linux/hpet.h
index 79f63a2..219ca4f 100644
--- a/include/linux/hpet.h
+++ b/include/linux/hpet.h
@@ -126,4 +126,6 @@
 #define	HPET_DPI	_IO('h', 0x05)	/* disable periodic */
 #define	HPET_IRQFREQ	_IOW('h', 0x6, unsigned long)	/* IRQFREQ usec */
 
+#define MAX_HPET_TBS	8		/* maximum hpet timer blocks */
+
 #endif				/* !__HPET__ */
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index ff037f0..9bace4b 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -446,7 +446,7 @@
 
 static inline void timer_stats_account_hrtimer(struct hrtimer *timer)
 {
-	if (likely(!timer->start_site))
+	if (likely(!timer_stats_active))
 		return;
 	timer_stats_update_stats(timer, timer->start_pid, timer->start_site,
 				 timer->function, timer->start_comm, 0);
@@ -457,8 +457,6 @@
 
 static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer)
 {
-	if (likely(!timer_stats_active))
-		return;
 	__timer_stats_hrtimer_set_start_info(timer, __builtin_return_address(0));
 }
 
diff --git a/include/linux/hw_random.h b/include/linux/hw_random.h
index 7244456..9bede76 100644
--- a/include/linux/hw_random.h
+++ b/include/linux/hw_random.h
@@ -22,10 +22,12 @@
  * @cleanup:		Cleanup callback (can be NULL).
  * @data_present:	Callback to determine if data is available
  *			on the RNG. If NULL, it is assumed that
- *			there is always data available.
+ *			there is always data available.  *OBSOLETE*
  * @data_read:		Read data from the RNG device.
  *			Returns the number of lower random bytes in "data".
- *			Must not be NULL.
+ *			Must not be NULL.    *OSOLETE*
+ * @read:		New API. drivers can fill up to max bytes of data
+ *			into the buffer. The buffer is aligned for any type.
  * @priv:		Private data, for use by the RNG driver.
  */
 struct hwrng {
@@ -34,6 +36,7 @@
 	void (*cleanup)(struct hwrng *rng);
 	int (*data_present)(struct hwrng *rng, int wait);
 	int (*data_read)(struct hwrng *rng, u32 *data);
+	int (*read)(struct hwrng *rng, void *data, size_t max, bool wait);
 	unsigned long priv;
 
 	/* internal. */
diff --git a/include/linux/ide.h b/include/linux/ide.h
index e4135d6..0ec6129 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -125,8 +125,8 @@
  * Timeouts for various operations:
  */
 enum {
-	/* spec allows up to 20ms */
-	WAIT_DRQ	= HZ / 10,	/* 100ms */
+	/* spec allows up to 20ms, but CF cards and SSD drives need more */
+	WAIT_DRQ	= 1 * HZ,	/* 1s */
 	/* some laptops are very slow */
 	WAIT_READY	= 5 * HZ,	/* 5s */
 	/* should be less than 3ms (?), if all ATAPI CD is closed at boot */
diff --git a/include/linux/in6.h b/include/linux/in6.h
index dfa2916..bd55c6e 100644
--- a/include/linux/in6.h
+++ b/include/linux/in6.h
@@ -110,7 +110,7 @@
 #define IPV6_FLOWINFO_FLOWLABEL		0x000fffff
 #define IPV6_FLOWINFO_PRIORITY		0x0ff00000
 
-/* These defintions are obsolete */
+/* These definitions are obsolete */
 #define IPV6_PRIORITY_UNCHARACTERIZED	0x0000
 #define IPV6_PRIORITY_FILLER		0x0100
 #define IPV6_PRIORITY_UNATTENDED	0x0200
diff --git a/include/linux/input-polldev.h b/include/linux/input-polldev.h
index 597a007..5e3dddf 100644
--- a/include/linux/input-polldev.h
+++ b/include/linux/input-polldev.h
@@ -14,12 +14,19 @@
 
 /**
  * struct input_polled_dev - simple polled input device
- * @private: private driver data
- * @flush: driver-supplied method that flushes device's state upon
- *	opening (optional)
+ * @private: private driver data.
+ * @open: driver-supplied method that prepares device for polling
+ *	(enabled the device and maybe flushes device state).
+ * @close: driver-supplied method that is called when device is no
+ *	longer being polled. Used to put device into low power mode.
  * @poll: driver-supplied method that polls the device and posts
  *	input events (mandatory).
- * @poll_interval: specifies how often the poll() method shoudl be called.
+ * @poll_interval: specifies how often the poll() method should be called.
+ *	Defaults to 500 msec unless overriden when registering the device.
+ * @poll_interval_max: specifies upper bound for the poll interval.
+ *	Defaults to the initial value of @poll_interval.
+ * @poll_interval_min: specifies lower bound for the poll interval.
+ *	Defaults to 0.
  * @input: input device structire associated with the polled device.
  *	Must be properly initialized by the driver (id, name, phys, bits).
  *
@@ -30,11 +37,16 @@
 struct input_polled_dev {
 	void *private;
 
-	void (*flush)(struct input_polled_dev *dev);
+	void (*open)(struct input_polled_dev *dev);
+	void (*close)(struct input_polled_dev *dev);
 	void (*poll)(struct input_polled_dev *dev);
 	unsigned int poll_interval; /* msec */
+	unsigned int poll_interval_max; /* msec */
+	unsigned int poll_interval_min; /* msec */
 
 	struct input_dev *input;
+
+/* private: */
 	struct delayed_work work;
 };
 
diff --git a/include/linux/input.h b/include/linux/input.h
index 84b501a..7be8a65 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -895,7 +895,7 @@
 	struct ff_envelope envelope;
 
 	__u32 custom_len;
-	__s16 *custom_data;
+	__s16 __user *custom_data;
 };
 
 /**
@@ -1021,9 +1021,12 @@
  * @keycodesize: size of elements in keycode table
  * @keycode: map of scancodes to keycodes for this device
  * @setkeycode: optional method to alter current keymap, used to implement
- *	sparse keymaps. If not supplied default mechanism will be used
+ *	sparse keymaps. If not supplied default mechanism will be used.
+ *	The method is being called while holding event_lock and thus must
+ *	not sleep
  * @getkeycode: optional method to retrieve current keymap. If not supplied
- *	default mechanism will be used
+ *	default mechanism will be used. The method is being called while
+ *	holding event_lock and thus must not sleep
  * @ff: force feedback structure associated with the device if device
  *	supports force feedback effects
  * @repeat_key: stores key code of the last key pressed; used to implement
@@ -1040,6 +1043,7 @@
  * @absmin: minimum values for events coming from absolute axes
  * @absfuzz: describes noisiness for axes
  * @absflat: size of the center flat position (used by joydev)
+ * @absres: resolution used for events coming form absolute axes
  * @open: this method is called when the very first user calls
  *	input_open_device(). The driver must prepare the device
  *	to start generating events (start polling thread,
@@ -1294,6 +1298,9 @@
 int __must_check input_register_handler(struct input_handler *);
 void input_unregister_handler(struct input_handler *);
 
+int input_handler_for_each_handle(struct input_handler *, void *data,
+				  int (*fn)(struct input_handle *, void *));
+
 int input_register_handle(struct input_handle *);
 void input_unregister_handle(struct input_handle *);
 
diff --git a/include/linux/input/matrix_keypad.h b/include/linux/input/matrix_keypad.h
index b3cd42d5..3bd018b 100644
--- a/include/linux/input/matrix_keypad.h
+++ b/include/linux/input/matrix_keypad.h
@@ -41,6 +41,9 @@
  * @col_scan_delay_us: delay, measured in microseconds, that is
  *	needed before we can keypad after activating column gpio
  * @debounce_ms: debounce interval in milliseconds
+ * @active_low: gpio polarity
+ * @wakeup: controls whether the device should be set up as wakeup
+ *	source
  *
  * This structure represents platform-specific data that use used by
  * matrix_keypad driver to perform proper initialization.
diff --git a/include/linux/input/sh_keysc.h b/include/linux/input/sh_keysc.h
new file mode 100644
index 0000000..c211b5c
--- /dev/null
+++ b/include/linux/input/sh_keysc.h
@@ -0,0 +1,14 @@
+#ifndef __SH_KEYSC_H__
+#define __SH_KEYSC_H__
+
+#define SH_KEYSC_MAXKEYS 30
+
+struct sh_keysc_info {
+	enum { SH_KEYSC_MODE_1, SH_KEYSC_MODE_2, SH_KEYSC_MODE_3 } mode;
+	int scan_timing; /* 0 -> 7, see KYCR1, SCN[2:0] */
+	int delay;
+	int kycr2_delay;
+	int keycodes[SH_KEYSC_MAXKEYS];
+};
+
+#endif /* __SH_KEYSC_H__ */
diff --git a/include/linux/input/sparse-keymap.h b/include/linux/input/sparse-keymap.h
new file mode 100644
index 0000000..52db620
--- /dev/null
+++ b/include/linux/input/sparse-keymap.h
@@ -0,0 +1,62 @@
+#ifndef _SPARSE_KEYMAP_H
+#define _SPARSE_KEYMAP_H
+
+/*
+ * Copyright (c) 2009 Dmitry Torokhov
+ *
+ * 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 KE_END		0	/* Indicates end of keymap */
+#define KE_KEY		1	/* Ordinary key/button */
+#define KE_SW		2	/* Switch (predetermined value) */
+#define KE_VSW		3	/* Switch (value supplied at runtime) */
+#define KE_IGNORE	4	/* Known entry that should be ignored */
+#define KE_LAST		KE_IGNORE
+
+/**
+ * struct key_entry - keymap entry for use in sparse keymap
+ * @type: Type of the key entry (KE_KEY, KE_SW, KE_VSW, KE_END);
+ *	drivers are allowed to extend the list with their own
+ *	private definitions.
+ * @code: Device-specific data identifying the button/switch
+ * @keycode: KEY_* code assigned to a key/button
+ * @sw.code: SW_* code assigned to a switch
+ * @sw.value: Value that should be sent in an input even when KE_SW
+ *	switch is toggled. KE_VSW switches ignore this field and
+ *	expect driver to supply value for the event.
+ *
+ * This structure defines an entry in a sparse keymap used by some
+ * input devices for which traditional table-based approach is not
+ * suitable.
+ */
+struct key_entry {
+	int type;		/* See KE_* above */
+	u32 code;
+	union {
+		u16 keycode;		/* For KE_KEY */
+		struct {		/* For KE_SW, KE_VSW */
+			u8 code;
+			u8 value;	/* For KE_SW, ignored by KE_VSW */
+		} sw;
+	};
+};
+
+struct key_entry *sparse_keymap_entry_from_scancode(struct input_dev *dev,
+						    unsigned int code);
+struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev,
+						   unsigned int code);
+int sparse_keymap_setup(struct input_dev *dev,
+			const struct key_entry *keymap,
+			int (*setup)(struct input_dev *, struct key_entry *));
+void sparse_keymap_free(struct input_dev *dev);
+
+void sparse_keymap_report_entry(struct input_dev *dev, const struct key_entry *ke,
+				unsigned int value, bool autorelease);
+
+bool sparse_keymap_report_event(struct input_dev *dev, unsigned int code,
+				unsigned int value, bool autorelease);
+
+#endif /* _SPARSE_KEYMAP_H */
diff --git a/include/linux/irq.h b/include/linux/irq.h
index ae9653d..a287cfc 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -282,7 +282,7 @@
 
 /*
  * Built-in IRQ handlers for various IRQ types,
- * callable via desc->chip->handle_irq()
+ * callable via desc->handle_irq()
  */
 extern void handle_level_irq(unsigned int irq, struct irq_desc *desc);
 extern void handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc);
diff --git a/include/linux/isicom.h b/include/linux/isicom.h
index bbd4219..b92e056 100644
--- a/include/linux/isicom.h
+++ b/include/linux/isicom.h
@@ -67,6 +67,7 @@
 
 #define		FIRMWARE_LOADED		0x0001
 #define		BOARD_ACTIVE		0x0002
+#define		BOARD_INIT		0x0004
 
  	/* isi_port status bitmap  */
 
diff --git a/include/linux/libata.h b/include/linux/libata.h
index a5b3dc7..6a9c4dd 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1024,7 +1024,7 @@
 extern int ata_scsi_slave_config(struct scsi_device *sdev);
 extern void ata_scsi_slave_destroy(struct scsi_device *sdev);
 extern int ata_scsi_change_queue_depth(struct scsi_device *sdev,
-				       int queue_depth);
+				       int queue_depth, int reason);
 extern struct ata_device *ata_dev_pair(struct ata_device *adev);
 extern int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev);
 
diff --git a/include/linux/mfd/ezx-pcap.h b/include/linux/mfd/ezx-pcap.h
index e5124ce..3402042d 100644
--- a/include/linux/mfd/ezx-pcap.h
+++ b/include/linux/mfd/ezx-pcap.h
@@ -45,7 +45,7 @@
 #define PCAP_CLEAR_INTERRUPT_REGISTER	0x01ffffff
 #define PCAP_MASK_ALL_INTERRUPT		0x01ffffff
 
-/* registers acessible by both pcap ports */
+/* registers accessible by both pcap ports */
 #define PCAP_REG_ISR		0x0	/* Interrupt Status */
 #define PCAP_REG_MSR		0x1	/* Interrupt Mask */
 #define PCAP_REG_PSTAT		0x2	/* Processor Status */
@@ -67,7 +67,7 @@
 #define PCAP_REG_VENDOR_TEST1	0x1e
 #define PCAP_REG_VENDOR_TEST2	0x1f
 
-/* registers acessible by pcap port 1 only (a1200, e2 & e6) */
+/* registers accessible by pcap port 1 only (a1200, e2 & e6) */
 #define PCAP_REG_INT_SEL	0x3	/* Interrupt Select */
 #define PCAP_REG_SWCTRL		0x4	/* Switching Regulator Control */
 #define PCAP_REG_VREG1		0x5	/* Regulator Bank 1 Control */
diff --git a/include/linux/mfd/sh_mobile_sdhi.h b/include/linux/mfd/sh_mobile_sdhi.h
new file mode 100644
index 0000000..3bcd716
--- /dev/null
+++ b/include/linux/mfd/sh_mobile_sdhi.h
@@ -0,0 +1,8 @@
+#ifndef __SH_MOBILE_SDHI_H__
+#define __SH_MOBILE_SDHI_H__
+
+struct sh_mobile_sdhi_info {
+	void (*set_pwr)(struct platform_device *pdev, int state);
+};
+
+#endif /* __SH_MOBILE_SDHI_H__ */
diff --git a/include/linux/mtd/ubi.h b/include/linux/mtd/ubi.h
index 6913b71..b31bd9e 100644
--- a/include/linux/mtd/ubi.h
+++ b/include/linux/mtd/ubi.h
@@ -174,6 +174,8 @@
 struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode);
 struct ubi_volume_desc *ubi_open_volume_nm(int ubi_num, const char *name,
 					   int mode);
+struct ubi_volume_desc *ubi_open_volume_path(const char *pathname, int mode);
+
 int ubi_register_volume_notifier(struct notifier_block *nb,
 				 int ignore_existing);
 int ubi_unregister_volume_notifier(struct notifier_block *nb);
diff --git a/include/linux/namei.h b/include/linux/namei.h
index ec0f607..0289467 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -76,7 +76,6 @@
 extern void release_open_intent(struct nameidata *);
 
 extern struct dentry *lookup_one_len(const char *, struct dentry *, int);
-extern struct dentry *lookup_one_noperm(const char *, struct dentry *);
 
 extern int follow_down(struct path *);
 extern int follow_up(struct path *);
diff --git a/include/linux/nilfs2_fs.h b/include/linux/nilfs2_fs.h
index ce52040..3fe02cf 100644
--- a/include/linux/nilfs2_fs.h
+++ b/include/linux/nilfs2_fs.h
@@ -151,6 +151,8 @@
 #define NILFS_MOUNT_BARRIER		0x1000  /* Use block barriers */
 #define NILFS_MOUNT_STRICT_ORDER	0x2000  /* Apply strict in-order
 						   semantics also for data */
+#define NILFS_MOUNT_NORECOVERY		0x4000  /* Disable write access during
+						   mount-time recovery */
 
 
 /**
@@ -403,6 +405,28 @@
 #define NILFS_SS_GC     0x0010  /* segment written for cleaner operation */
 
 /**
+ * struct nilfs_btree_node - B-tree node
+ * @bn_flags: flags
+ * @bn_level: level
+ * @bn_nchildren: number of children
+ * @bn_pad: padding
+ */
+struct nilfs_btree_node {
+	__u8 bn_flags;
+	__u8 bn_level;
+	__le16 bn_nchildren;
+	__le32 bn_pad;
+};
+
+/* flags */
+#define NILFS_BTREE_NODE_ROOT   0x01
+
+/* level */
+#define NILFS_BTREE_LEVEL_DATA          0
+#define NILFS_BTREE_LEVEL_NODE_MIN      (NILFS_BTREE_LEVEL_DATA + 1)
+#define NILFS_BTREE_LEVEL_MAX           14
+
+/**
  * struct nilfs_palloc_group_desc - block group descriptor
  * @pg_nfrees: number of free entries in block group
  */
diff --git a/include/linux/omapfb.h b/include/linux/omapfb.h
new file mode 100644
index 0000000..f46c40a
--- /dev/null
+++ b/include/linux/omapfb.h
@@ -0,0 +1,251 @@
+/*
+ * File: include/linux/omapfb.h
+ *
+ * Framebuffer driver for TI OMAP boards
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Author: Imre Deak <imre.deak@nokia.com>
+ *
+ * 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.,
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef __LINUX_OMAPFB_H__
+#define __LINUX_OMAPFB_H__
+
+#include <linux/fb.h>
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+/* IOCTL commands. */
+
+#define OMAP_IOW(num, dtype)	_IOW('O', num, dtype)
+#define OMAP_IOR(num, dtype)	_IOR('O', num, dtype)
+#define OMAP_IOWR(num, dtype)	_IOWR('O', num, dtype)
+#define OMAP_IO(num)		_IO('O', num)
+
+#define OMAPFB_MIRROR		OMAP_IOW(31, int)
+#define OMAPFB_SYNC_GFX		OMAP_IO(37)
+#define OMAPFB_VSYNC		OMAP_IO(38)
+#define OMAPFB_SET_UPDATE_MODE	OMAP_IOW(40, int)
+#define OMAPFB_GET_CAPS		OMAP_IOR(42, struct omapfb_caps)
+#define OMAPFB_GET_UPDATE_MODE	OMAP_IOW(43, int)
+#define OMAPFB_LCD_TEST		OMAP_IOW(45, int)
+#define OMAPFB_CTRL_TEST	OMAP_IOW(46, int)
+#define OMAPFB_UPDATE_WINDOW_OLD OMAP_IOW(47, struct omapfb_update_window_old)
+#define OMAPFB_SET_COLOR_KEY	OMAP_IOW(50, struct omapfb_color_key)
+#define OMAPFB_GET_COLOR_KEY	OMAP_IOW(51, struct omapfb_color_key)
+#define OMAPFB_SETUP_PLANE	OMAP_IOW(52, struct omapfb_plane_info)
+#define OMAPFB_QUERY_PLANE	OMAP_IOW(53, struct omapfb_plane_info)
+#define OMAPFB_UPDATE_WINDOW	OMAP_IOW(54, struct omapfb_update_window)
+#define OMAPFB_SETUP_MEM	OMAP_IOW(55, struct omapfb_mem_info)
+#define OMAPFB_QUERY_MEM	OMAP_IOW(56, struct omapfb_mem_info)
+#define OMAPFB_WAITFORVSYNC	OMAP_IO(57)
+#define OMAPFB_MEMORY_READ	OMAP_IOR(58, struct omapfb_memory_read)
+#define OMAPFB_GET_OVERLAY_COLORMODE OMAP_IOR(59, struct omapfb_ovl_colormode)
+#define OMAPFB_WAITFORGO	OMAP_IO(60)
+#define OMAPFB_GET_VRAM_INFO	OMAP_IOR(61, struct omapfb_vram_info)
+#define OMAPFB_SET_TEARSYNC	OMAP_IOW(62, struct omapfb_tearsync_info)
+
+#define OMAPFB_CAPS_GENERIC_MASK	0x00000fff
+#define OMAPFB_CAPS_LCDC_MASK		0x00fff000
+#define OMAPFB_CAPS_PANEL_MASK		0xff000000
+
+#define OMAPFB_CAPS_MANUAL_UPDATE	0x00001000
+#define OMAPFB_CAPS_TEARSYNC		0x00002000
+#define OMAPFB_CAPS_PLANE_RELOCATE_MEM	0x00004000
+#define OMAPFB_CAPS_PLANE_SCALE		0x00008000
+#define OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE	0x00010000
+#define OMAPFB_CAPS_WINDOW_SCALE	0x00020000
+#define OMAPFB_CAPS_WINDOW_OVERLAY	0x00040000
+#define OMAPFB_CAPS_WINDOW_ROTATE	0x00080000
+#define OMAPFB_CAPS_SET_BACKLIGHT	0x01000000
+
+/* Values from DSP must map to lower 16-bits */
+#define OMAPFB_FORMAT_MASK		0x00ff
+#define OMAPFB_FORMAT_FLAG_DOUBLE	0x0100
+#define OMAPFB_FORMAT_FLAG_TEARSYNC	0x0200
+#define OMAPFB_FORMAT_FLAG_FORCE_VSYNC	0x0400
+#define OMAPFB_FORMAT_FLAG_ENABLE_OVERLAY	0x0800
+#define OMAPFB_FORMAT_FLAG_DISABLE_OVERLAY	0x1000
+
+#define OMAPFB_MEMTYPE_SDRAM		0
+#define OMAPFB_MEMTYPE_SRAM		1
+#define OMAPFB_MEMTYPE_MAX		1
+
+enum omapfb_color_format {
+	OMAPFB_COLOR_RGB565 = 0,
+	OMAPFB_COLOR_YUV422,
+	OMAPFB_COLOR_YUV420,
+	OMAPFB_COLOR_CLUT_8BPP,
+	OMAPFB_COLOR_CLUT_4BPP,
+	OMAPFB_COLOR_CLUT_2BPP,
+	OMAPFB_COLOR_CLUT_1BPP,
+	OMAPFB_COLOR_RGB444,
+	OMAPFB_COLOR_YUY422,
+
+	OMAPFB_COLOR_ARGB16,
+	OMAPFB_COLOR_RGB24U,	/* RGB24, 32-bit container */
+	OMAPFB_COLOR_RGB24P,	/* RGB24, 24-bit container */
+	OMAPFB_COLOR_ARGB32,
+	OMAPFB_COLOR_RGBA32,
+	OMAPFB_COLOR_RGBX32,
+};
+
+struct omapfb_update_window {
+	__u32 x, y;
+	__u32 width, height;
+	__u32 format;
+	__u32 out_x, out_y;
+	__u32 out_width, out_height;
+	__u32 reserved[8];
+};
+
+struct omapfb_update_window_old {
+	__u32 x, y;
+	__u32 width, height;
+	__u32 format;
+};
+
+enum omapfb_plane {
+	OMAPFB_PLANE_GFX = 0,
+	OMAPFB_PLANE_VID1,
+	OMAPFB_PLANE_VID2,
+};
+
+enum omapfb_channel_out {
+	OMAPFB_CHANNEL_OUT_LCD = 0,
+	OMAPFB_CHANNEL_OUT_DIGIT,
+};
+
+struct omapfb_plane_info {
+	__u32 pos_x;
+	__u32 pos_y;
+	__u8  enabled;
+	__u8  channel_out;
+	__u8  mirror;
+	__u8  reserved1;
+	__u32 out_width;
+	__u32 out_height;
+	__u32 reserved2[12];
+};
+
+struct omapfb_mem_info {
+	__u32 size;
+	__u8  type;
+	__u8  reserved[3];
+};
+
+struct omapfb_caps {
+	__u32 ctrl;
+	__u32 plane_color;
+	__u32 wnd_color;
+};
+
+enum omapfb_color_key_type {
+	OMAPFB_COLOR_KEY_DISABLED = 0,
+	OMAPFB_COLOR_KEY_GFX_DST,
+	OMAPFB_COLOR_KEY_VID_SRC,
+};
+
+struct omapfb_color_key {
+	__u8  channel_out;
+	__u32 background;
+	__u32 trans_key;
+	__u8  key_type;
+};
+
+enum omapfb_update_mode {
+	OMAPFB_UPDATE_DISABLED = 0,
+	OMAPFB_AUTO_UPDATE,
+	OMAPFB_MANUAL_UPDATE
+};
+
+struct omapfb_memory_read {
+	__u16 x;
+	__u16 y;
+	__u16 w;
+	__u16 h;
+	size_t buffer_size;
+	void __user *buffer;
+};
+
+struct omapfb_ovl_colormode {
+	__u8 overlay_idx;
+	__u8 mode_idx;
+	__u32 bits_per_pixel;
+	__u32 nonstd;
+	struct fb_bitfield red;
+	struct fb_bitfield green;
+	struct fb_bitfield blue;
+	struct fb_bitfield transp;
+};
+
+struct omapfb_vram_info {
+	__u32 total;
+	__u32 free;
+	__u32 largest_free_block;
+	__u32 reserved[5];
+};
+
+struct omapfb_tearsync_info {
+	__u8 enabled;
+	__u8 reserved1[3];
+	__u16 line;
+	__u16 reserved2;
+};
+
+#ifdef __KERNEL__
+
+#include <plat/board.h>
+
+#ifdef CONFIG_ARCH_OMAP1
+#define OMAPFB_PLANE_NUM		1
+#else
+#define OMAPFB_PLANE_NUM		3
+#endif
+
+struct omapfb_mem_region {
+	u32		paddr;
+	void __iomem	*vaddr;
+	unsigned long	size;
+	u8		type;		/* OMAPFB_PLANE_MEM_* */
+	enum omapfb_color_format format;/* OMAPFB_COLOR_* */
+	unsigned	format_used:1;	/* Must be set when format is set.
+					 * Needed b/c of the badly chosen 0
+					 * base for OMAPFB_COLOR_* values
+					 */
+	unsigned	alloc:1;	/* allocated by the driver */
+	unsigned	map:1;		/* kernel mapped by the driver */
+};
+
+struct omapfb_mem_desc {
+	int				region_cnt;
+	struct omapfb_mem_region	region[OMAPFB_PLANE_NUM];
+};
+
+struct omapfb_platform_data {
+	struct omap_lcd_config		lcd;
+	struct omapfb_mem_desc		mem_desc;
+	void				*ctrl_platform_data;
+};
+
+/* in arch/arm/plat-omap/fb.c */
+extern void omapfb_set_platform_data(struct omapfb_platform_data *data);
+extern void omapfb_set_ctrl_platform_data(void *pdata);
+extern void omapfb_reserve_sdram(void);
+
+#endif
+
+#endif /* __OMAPFB_H */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index f5c7cd3..04771b9 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -218,6 +218,7 @@
 	unsigned int	class;		/* 3 bytes: (base,sub,prog-if) */
 	u8		revision;	/* PCI revision, low byte of class word */
 	u8		hdr_type;	/* PCI header type (`multi' flag masked out) */
+	u8		pcie_cap;	/* PCI-E capability offset */
 	u8		pcie_type;	/* PCI-E device/port type */
 	u8		rom_base_reg;	/* which config register controls the ROM */
 	u8		pin;  		/* which interrupt pin this device uses */
@@ -280,6 +281,7 @@
 	unsigned int	is_virtfn:1;
 	unsigned int	reset_fn:1;
 	unsigned int    is_hotplug_bridge:1;
+	unsigned int    aer_firmware_first:1;
 	pci_dev_flags_t dev_flags;
 	atomic_t	enable_cnt;	/* pci_enable_device has been called */
 
@@ -635,7 +637,13 @@
 				unsigned int ss_vendor, unsigned int ss_device,
 				struct pci_dev *from);
 struct pci_dev *pci_get_slot(struct pci_bus *bus, unsigned int devfn);
-struct pci_dev *pci_get_bus_and_slot(unsigned int bus, unsigned int devfn);
+struct pci_dev *pci_get_domain_bus_and_slot(int domain, unsigned int bus,
+					    unsigned int devfn);
+static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus,
+						   unsigned int devfn)
+{
+	return pci_get_domain_bus_and_slot(0, bus, devfn);
+}
 struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from);
 int pci_dev_present(const struct pci_device_id *ids);
 
@@ -701,6 +709,7 @@
 void pci_set_master(struct pci_dev *dev);
 void pci_clear_master(struct pci_dev *dev);
 int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state);
+int pci_set_cacheline_size(struct pci_dev *dev);
 #define HAVE_PCI_SET_MWI
 int __must_check pci_set_mwi(struct pci_dev *dev);
 int pci_try_set_mwi(struct pci_dev *dev);
@@ -1246,6 +1255,8 @@
 
 extern unsigned long pci_cardbus_io_size;
 extern unsigned long pci_cardbus_mem_size;
+extern u8 pci_dfl_cache_line_size;
+extern u8 pci_cache_line_size;
 
 extern unsigned long pci_hotplug_io_size;
 extern unsigned long pci_hotplug_mem_size;
@@ -1290,5 +1301,34 @@
 extern void pci_hp_remove_module_link(struct pci_slot *pci_slot);
 #endif
 
+/**
+ * pci_pcie_cap - get the saved PCIe capability offset
+ * @dev: PCI device
+ *
+ * PCIe capability offset is calculated at PCI device initialization
+ * time and saved in the data structure. This function returns saved
+ * PCIe capability offset. Using this instead of pci_find_capability()
+ * reduces unnecessary search in the PCI configuration space. If you
+ * need to calculate PCIe capability offset from raw device for some
+ * reasons, please use pci_find_capability() instead.
+ */
+static inline int pci_pcie_cap(struct pci_dev *dev)
+{
+	return dev->pcie_cap;
+}
+
+/**
+ * pci_is_pcie - check if the PCI device is PCI Express capable
+ * @dev: PCI device
+ *
+ * Retrun true if the PCI device is PCI Express capable, false otherwise.
+ */
+static inline bool pci_is_pcie(struct pci_dev *dev)
+{
+	return !!pci_pcie_cap(dev);
+}
+
+void pci_request_acs(void);
+
 #endif /* __KERNEL__ */
 #endif /* LINUX_PCI_H */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index cabf074..eae1f86 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1587,6 +1587,8 @@
 #define PCI_VENDOR_ID_COMPEX		0x11f6
 #define PCI_DEVICE_ID_COMPEX_ENET100VG4	0x0112
 
+#define PCI_VENDOR_ID_PMC_Sierra	0x11f8
+
 #define PCI_VENDOR_ID_RP		0x11fe
 #define PCI_DEVICE_ID_RP32INTF		0x0001
 #define PCI_DEVICE_ID_RP8INTF		0x0002
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
index dd0bed4..9f2ad0a 100644
--- a/include/linux/pci_regs.h
+++ b/include/linux/pci_regs.h
@@ -365,6 +365,11 @@
 #define  PCI_X_STATUS_266MHZ	0x40000000	/* 266 MHz capable */
 #define  PCI_X_STATUS_533MHZ	0x80000000	/* 533 MHz capable */
 
+/* PCI Bridge Subsystem ID registers */
+
+#define PCI_SSVID_VENDOR_ID     4	/* PCI-Bridge subsystem vendor id register */
+#define PCI_SSVID_DEVICE_ID     6	/* PCI-Bridge subsystem device id register */
+
 /* PCI Express capability registers */
 
 #define PCI_EXP_FLAGS		2	/* Capabilities register */
@@ -502,6 +507,7 @@
 #define PCI_EXT_CAP_ID_VC	2
 #define PCI_EXT_CAP_ID_DSN	3
 #define PCI_EXT_CAP_ID_PWR	4
+#define PCI_EXT_CAP_ID_ACS	13
 #define PCI_EXT_CAP_ID_ARI	14
 #define PCI_EXT_CAP_ID_ATS	15
 #define PCI_EXT_CAP_ID_SRIOV	16
@@ -662,4 +668,16 @@
 #define  PCI_SRIOV_VFM_MO	0x2	/* Active.MigrateOut */
 #define  PCI_SRIOV_VFM_AV	0x3	/* Active.Available */
 
+/* Access Control Service */
+#define PCI_ACS_CAP		0x04	/* ACS Capability Register */
+#define  PCI_ACS_SV		0x01	/* Source Validation */
+#define  PCI_ACS_TB		0x02	/* Translation Blocking */
+#define  PCI_ACS_RR		0x04	/* P2P Request Redirect */
+#define  PCI_ACS_CR		0x08	/* P2P Completion Redirect */
+#define  PCI_ACS_UF		0x10	/* Upstream Forwarding */
+#define  PCI_ACS_EC		0x20	/* P2P Egress Control */
+#define  PCI_ACS_DT		0x40	/* Direct Translated P2P */
+#define PCI_ACS_CTRL		0x06	/* ACS Control Register */
+#define PCI_ACS_EGRESS_CTL_V	0x08	/* ACS Egress Control Vector */
+
 #endif /* LINUX_PCI_REGS_H */
diff --git a/include/linux/pcieport_if.h b/include/linux/pcieport_if.h
index b4c7954..6775532 100644
--- a/include/linux/pcieport_if.h
+++ b/include/linux/pcieport_if.h
@@ -10,10 +10,7 @@
 #define _PCIEPORT_IF_H_
 
 /* Port Type */
-#define PCIE_RC_PORT			4	/* Root port of RC */
-#define PCIE_SW_UPSTREAM_PORT		5	/* Upstream port of Switch */
-#define PCIE_SW_DOWNSTREAM_PORT		6	/* Downstream port of Switch */
-#define PCIE_ANY_PORT			7
+#define PCIE_ANY_PORT			(~0)
 
 /* Service Type */
 #define PCIE_PORT_SERVICE_PME_SHIFT	0	/* Power Management Event */
@@ -25,17 +22,6 @@
 #define PCIE_PORT_SERVICE_VC_SHIFT	3	/* Virtual Channel */
 #define PCIE_PORT_SERVICE_VC		(1 << PCIE_PORT_SERVICE_VC_SHIFT)
 
-/* Root/Upstream/Downstream Port's Interrupt Mode */
-#define PCIE_PORT_NO_IRQ		(-1)
-#define PCIE_PORT_INTx_MODE		0
-#define PCIE_PORT_MSI_MODE		1
-#define PCIE_PORT_MSIX_MODE		2
-
-struct pcie_port_data {
-	int port_type;		/* Type of the port */
-	int port_irq_mode;	/* [0:INTx | 1:MSI | 2:MSI-X] */
-};
-
 struct pcie_device {
 	int 		irq;	    /* Service IRQ/MSI/MSI-X Vector */
 	struct pci_dev *port;	    /* Root/Upstream/Downstream Port */
diff --git a/include/linux/pktcdvd.h b/include/linux/pktcdvd.h
index d745f5b..76e5053 100644
--- a/include/linux/pktcdvd.h
+++ b/include/linux/pktcdvd.h
@@ -30,7 +30,7 @@
 
 /*
  * use drive write caching -- we need deferred error handling to be
- * able to sucessfully recover with this option (drive will return good
+ * able to successfully recover with this option (drive will return good
  * status as soon as the cdb is validated).
  */
 #if defined(CONFIG_CDROM_PKTCDVD_WCACHE)
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 3c6675c..71ff887 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -83,6 +83,8 @@
 	struct platform_driver *pdrv;
 	struct list_head list;
 	int requested_id;
+	char *buffer;
+	int bufsize;
 };
 
 #define EARLY_PLATFORM_ID_UNSET -2
@@ -102,21 +104,29 @@
 				       int nr_probe, int user_only);
 extern void early_platform_cleanup(void);
 
+#define early_platform_init(class_string, platdrv)		\
+	early_platform_init_buffer(class_string, platdrv, NULL, 0)
 
 #ifndef MODULE
-#define early_platform_init(class_string, platform_driver)		\
+#define early_platform_init_buffer(class_string, platdrv, buf, bufsiz)	\
 static __initdata struct early_platform_driver early_driver = {		\
 	.class_str = class_string,					\
-	.pdrv = platform_driver,					\
+	.buffer = buf,							\
+	.bufsize = bufsiz,						\
+	.pdrv = platdrv,						\
 	.requested_id = EARLY_PLATFORM_ID_UNSET,			\
 };									\
-static int __init early_platform_driver_setup_func(char *buf)		\
+static int __init early_platform_driver_setup_func(char *buffer)	\
 {									\
-	return early_platform_driver_register(&early_driver, buf);	\
+	return early_platform_driver_register(&early_driver, buffer);	\
 }									\
 early_param(class_string, early_platform_driver_setup_func)
 #else /* MODULE */
-#define early_platform_init(class_string, platform_driver)
+#define early_platform_init_buffer(class_string, platdrv, buf, bufsiz)	\
+static inline char *early_platform_driver_setup_func(void)		\
+{									\
+	return bufsiz ? buf : NULL;					\
+}
 #endif /* MODULE */
 
 #endif /* _PLATFORM_DEVICE_H_ */
diff --git a/include/linux/quota.h b/include/linux/quota.h
index ce9a9b2..e70e621 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -73,6 +73,8 @@
 /* Quota format type IDs */
 #define	QFMT_VFS_OLD 1
 #define	QFMT_VFS_V0 2
+#define QFMT_OCFS2 3
+#define	QFMT_VFS_V1 4
 
 /* Size of block in which space limits are passed through the quota
  * interface */
@@ -334,7 +336,7 @@
 
 struct quota_format_type {
 	int qf_fmt_id;	/* Quota format id */
-	struct quota_format_ops *qf_ops;	/* Operations of format */
+	const struct quota_format_ops *qf_ops;	/* Operations of format */
 	struct module *qf_owner;		/* Module implementing quota format */
 	struct quota_format_type *qf_next;
 };
@@ -394,7 +396,7 @@
 	struct rw_semaphore dqptr_sem;		/* serialize ops using quota_info struct, pointers from inode to dquots */
 	struct inode *files[MAXQUOTAS];		/* inodes of quotafiles */
 	struct mem_dqinfo info[MAXQUOTAS];	/* Information for each quota type */
-	struct quota_format_ops *ops[MAXQUOTAS];	/* Operations for each type */
+	const struct quota_format_ops *ops[MAXQUOTAS];	/* Operations for each type */
 };
 
 int register_quota_format(struct quota_format_type *fmt);
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index dd31e7b..a05b4a2 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -52,11 +52,63 @@
 #define REISERFS_IOC32_GETVERSION	FS_IOC32_GETVERSION
 #define REISERFS_IOC32_SETVERSION	FS_IOC32_SETVERSION
 
-/* Locking primitives */
-/* Right now we are still falling back to (un)lock_kernel, but eventually that
-   would evolve into real per-fs locks */
-#define reiserfs_write_lock( sb ) lock_kernel()
-#define reiserfs_write_unlock( sb ) unlock_kernel()
+/*
+ * Locking primitives. The write lock is a per superblock
+ * special mutex that has properties close to the Big Kernel Lock
+ * which was used in the previous locking scheme.
+ */
+void reiserfs_write_lock(struct super_block *s);
+void reiserfs_write_unlock(struct super_block *s);
+int reiserfs_write_lock_once(struct super_block *s);
+void reiserfs_write_unlock_once(struct super_block *s, int lock_depth);
+
+/*
+ * Several mutexes depend on the write lock.
+ * However sometimes we want to relax the write lock while we hold
+ * these mutexes, according to the release/reacquire on schedule()
+ * properties of the Bkl that were used.
+ * Reiserfs performances and locking were based on this scheme.
+ * Now that the write lock is a mutex and not the bkl anymore, doing so
+ * may result in a deadlock:
+ *
+ * A acquire write_lock
+ * A acquire j_commit_mutex
+ * A release write_lock and wait for something
+ * B acquire write_lock
+ * B can't acquire j_commit_mutex and sleep
+ * A can't acquire write lock anymore
+ * deadlock
+ *
+ * What we do here is avoiding such deadlock by playing the same game
+ * than the Bkl: if we can't acquire a mutex that depends on the write lock,
+ * we release the write lock, wait a bit and then retry.
+ *
+ * The mutexes concerned by this hack are:
+ * - The commit mutex of a journal list
+ * - The flush mutex
+ * - The journal lock
+ * - The inode mutex
+ */
+static inline void reiserfs_mutex_lock_safe(struct mutex *m,
+			       struct super_block *s)
+{
+	reiserfs_write_unlock(s);
+	mutex_lock(m);
+	reiserfs_write_lock(s);
+}
+
+/*
+ * When we schedule, we usually want to also release the write lock,
+ * according to the previous bkl based locking scheme of reiserfs.
+ */
+static inline void reiserfs_cond_resched(struct super_block *s)
+{
+	if (need_resched()) {
+		reiserfs_write_unlock(s);
+		schedule();
+		reiserfs_write_lock(s);
+	}
+}
 
 struct fid;
 
@@ -1329,7 +1381,11 @@
 #define get_generation(s) atomic_read (&fs_generation(s))
 #define FILESYSTEM_CHANGED_TB(tb)  (get_generation((tb)->tb_sb) != (tb)->fs_gen)
 #define __fs_changed(gen,s) (gen != get_generation (s))
-#define fs_changed(gen,s) ({cond_resched(); __fs_changed(gen, s);})
+#define fs_changed(gen,s)		\
+({					\
+	reiserfs_cond_resched(s);	\
+	__fs_changed(gen, s);		\
+})
 
 /***************************************************************************/
 /*                  FIXATE NODES                                           */
@@ -2258,8 +2314,7 @@
 #define SPARE_SPACE 500
 
 /* prototypes from ioctl.c */
-int reiserfs_ioctl(struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg);
+long reiserfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
 long reiserfs_compat_ioctl(struct file *filp,
 		   unsigned int cmd, unsigned long arg);
 int reiserfs_unpack(struct inode *inode, struct file *filp);
diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h
index dab68bb..52c83b6 100644
--- a/include/linux/reiserfs_fs_sb.h
+++ b/include/linux/reiserfs_fs_sb.h
@@ -7,6 +7,8 @@
 #ifdef __KERNEL__
 #include <linux/workqueue.h>
 #include <linux/rwsem.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
 #endif
 
 typedef enum {
@@ -355,6 +357,13 @@
 	struct reiserfs_journal *s_journal;	/* pointer to journal information */
 	unsigned short s_mount_state;	/* reiserfs state (valid, invalid) */
 
+	/* Serialize writers access, replace the old bkl */
+	struct mutex lock;
+	/* Owner of the lock (can be recursive) */
+	struct task_struct *lock_owner;
+	/* Depth of the lock, start from -1 like the bkl */
+	int lock_depth;
+
 	/* Comment? -Hans */
 	void (*end_io_handler) (struct buffer_head *, int);
 	hashf_t s_hash_function;	/* pointer to function which is used
@@ -408,6 +417,17 @@
 	char *s_qf_names[MAXQUOTAS];
 	int s_jquota_fmt;
 #endif
+#ifdef CONFIG_REISERFS_CHECK
+
+	struct tree_balance *cur_tb;	/*
+					 * Detects whether more than one
+					 * copy of tb exists per superblock
+					 * as a means of checking whether
+					 * do_balance is executing concurrently
+					 * against another tree reader/writer
+					 * on a same mount point.
+					 */
+#endif
 };
 
 /* Definitions of reiserfs on-disk properties: */
diff --git a/include/linux/screen_info.h b/include/linux/screen_info.h
index 1ee2c05..899fbb4 100644
--- a/include/linux/screen_info.h
+++ b/include/linux/screen_info.h
@@ -14,7 +14,8 @@
 	__u16 orig_video_page;	/* 0x04 */
 	__u8  orig_video_mode;	/* 0x06 */
 	__u8  orig_video_cols;	/* 0x07 */
-	__u16 unused2;		/* 0x08 */
+	__u8  flags;		/* 0x08 */
+	__u8  unused2;		/* 0x09 */
 	__u16 orig_video_ega_bx;/* 0x0a */
 	__u16 unused3;		/* 0x0c */
 	__u8  orig_video_lines;	/* 0x0e */
@@ -65,6 +66,8 @@
 
 #define VIDEO_TYPE_EFI		0x70	/* EFI graphic mode		*/
 
+#define VIDEO_FLAGS_NOCURSOR	(1 << 0) /* The video mode has no cursor set */
+
 #ifdef __KERNEL__
 extern struct screen_info screen_info;
 
diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h
index 850db2e..cf9327c 100644
--- a/include/linux/serial_reg.h
+++ b/include/linux/serial_reg.h
@@ -216,10 +216,10 @@
 
 #define UART_IIR_TOD	0x08	/* Character Timeout Indication Detected */
 
-#define UART_FCR_PXAR1	0x00	/* receive FIFO treshold = 1 */
-#define UART_FCR_PXAR8	0x40	/* receive FIFO treshold = 8 */
-#define UART_FCR_PXAR16	0x80	/* receive FIFO treshold = 16 */
-#define UART_FCR_PXAR32	0xc0	/* receive FIFO treshold = 32 */
+#define UART_FCR_PXAR1	0x00	/* receive FIFO threshold = 1 */
+#define UART_FCR_PXAR8	0x40	/* receive FIFO threshold = 8 */
+#define UART_FCR_PXAR16	0x80	/* receive FIFO threshold = 16 */
+#define UART_FCR_PXAR32	0xc0	/* receive FIFO threshold = 32 */
 
 
 
diff --git a/include/linux/serio.h b/include/linux/serio.h
index a640bc2..e2f3044 100644
--- a/include/linux/serio.h
+++ b/include/linux/serio.h
@@ -215,5 +215,6 @@
 #define SERIO_INEXIO	0x37
 #define SERIO_TOUCHIT213	0x38
 #define SERIO_W8001	0x39
+#define SERIO_DYNAPRO	0x3a
 
 #endif
diff --git a/include/linux/sh_intc.h b/include/linux/sh_intc.h
index 68e212f..4ef246f 100644
--- a/include/linux/sh_intc.h
+++ b/include/linux/sh_intc.h
@@ -57,10 +57,8 @@
 	struct intc_sense_reg *sense_regs;
 	unsigned int nr_sense_regs;
 	char *name;
-#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
 	struct intc_mask_reg *ack_regs;
 	unsigned int nr_ack_regs;
-#endif
 };
 
 #define _INTC_ARRAY(a) a, sizeof(a)/sizeof(*a)
@@ -73,7 +71,6 @@
 	chipname,							\
 }
 
-#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
 #define DECLARE_INTC_DESC_ACK(symbol, chipname, vectors, groups,	\
 	mask_regs, prio_regs, sense_regs, ack_regs)			\
 struct intc_desc symbol __initdata = {					\
@@ -83,9 +80,11 @@
 	chipname,							\
 	_INTC_ARRAY(ack_regs),						\
 }
-#endif
 
 void __init register_intc_controller(struct intc_desc *desc);
 int intc_set_priority(unsigned int irq, unsigned int prio);
 
+int reserve_irq_vector(unsigned int irq);
+void reserve_irq_legacy(void);
+
 #endif /* __SH_INTC_H */
diff --git a/include/linux/sh_pfc.h b/include/linux/sh_pfc.h
new file mode 100644
index 0000000..07c08af
--- /dev/null
+++ b/include/linux/sh_pfc.h
@@ -0,0 +1,96 @@
+/*
+ * SuperH Pin Function Controller Support
+ *
+ * Copyright (c) 2008 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef __SH_PFC_H
+#define __SH_PFC_H
+
+#include <asm-generic/gpio.h>
+
+typedef unsigned short pinmux_enum_t;
+typedef unsigned short pinmux_flag_t;
+
+#define PINMUX_TYPE_NONE            0
+#define PINMUX_TYPE_FUNCTION        1
+#define PINMUX_TYPE_GPIO            2
+#define PINMUX_TYPE_OUTPUT          3
+#define PINMUX_TYPE_INPUT           4
+#define PINMUX_TYPE_INPUT_PULLUP    5
+#define PINMUX_TYPE_INPUT_PULLDOWN  6
+
+#define PINMUX_FLAG_TYPE            (0x7)
+#define PINMUX_FLAG_WANT_PULLUP     (1 << 3)
+#define PINMUX_FLAG_WANT_PULLDOWN   (1 << 4)
+
+#define PINMUX_FLAG_DBIT_SHIFT      5
+#define PINMUX_FLAG_DBIT            (0x1f << PINMUX_FLAG_DBIT_SHIFT)
+#define PINMUX_FLAG_DREG_SHIFT      10
+#define PINMUX_FLAG_DREG            (0x3f << PINMUX_FLAG_DREG_SHIFT)
+
+struct pinmux_gpio {
+	pinmux_enum_t enum_id;
+	pinmux_flag_t flags;
+};
+
+#define PINMUX_GPIO(gpio, data_or_mark) [gpio] = { data_or_mark }
+#define PINMUX_DATA(data_or_mark, ids...) data_or_mark, ids, 0
+
+struct pinmux_cfg_reg {
+	unsigned long reg, reg_width, field_width;
+	unsigned long *cnt;
+	pinmux_enum_t *enum_ids;
+};
+
+#define PINMUX_CFG_REG(name, r, r_width, f_width) \
+	.reg = r, .reg_width = r_width, .field_width = f_width,		\
+	.cnt = (unsigned long [r_width / f_width]) {}, \
+	.enum_ids = (pinmux_enum_t [(r_width / f_width) * (1 << f_width)]) \
+
+struct pinmux_data_reg {
+	unsigned long reg, reg_width, reg_shadow;
+	pinmux_enum_t *enum_ids;
+};
+
+#define PINMUX_DATA_REG(name, r, r_width) \
+	.reg = r, .reg_width = r_width,	\
+	.enum_ids = (pinmux_enum_t [r_width]) \
+
+struct pinmux_range {
+	pinmux_enum_t begin;
+	pinmux_enum_t end;
+	pinmux_enum_t force;
+};
+
+struct pinmux_info {
+	char *name;
+	pinmux_enum_t reserved_id;
+	struct pinmux_range data;
+	struct pinmux_range input;
+	struct pinmux_range input_pd;
+	struct pinmux_range input_pu;
+	struct pinmux_range output;
+	struct pinmux_range mark;
+	struct pinmux_range function;
+
+	unsigned first_gpio, last_gpio;
+
+	struct pinmux_gpio *gpios;
+	struct pinmux_cfg_reg *cfg_regs;
+	struct pinmux_data_reg *data_regs;
+
+	pinmux_enum_t *gpio_data;
+	unsigned int gpio_data_size;
+
+	unsigned long *gpio_in_use;
+	struct gpio_chip chip;
+};
+
+int register_pinmux(struct pinmux_info *pip);
+
+#endif /* __SH_PFC_H */
diff --git a/include/linux/spi/spi_bitbang.h b/include/linux/spi/spi_bitbang.h
index eed4254..3274c50 100644
--- a/include/linux/spi/spi_bitbang.h
+++ b/include/linux/spi/spi_bitbang.h
@@ -15,7 +15,7 @@
  * Some hardware works well with requests at spi_transfer scope:
  *
  *   -	Drivers leveraging smarter hardware, with fifos or DMA; or for half
- *	duplex (MicroWire) controllers.  Provide chipslect() and txrx_bufs(),
+ *	duplex (MicroWire) controllers.  Provide chipselect() and txrx_bufs(),
  *	and custom setup()/cleanup() methods.
  */
 
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index bc70c58..939a615 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -834,4 +834,8 @@
 asmlinkage long sys_perf_event_open(
 		struct perf_event_attr __user *attr_uptr,
 		pid_t pid, int cpu, int group_fd, unsigned long flags);
+
+asmlinkage long sys_mmap_pgoff(unsigned long addr, unsigned long len,
+			unsigned long prot, unsigned long flags,
+			unsigned long fd, unsigned long pgoff);
 #endif
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 56af3ca..877ba03 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -89,8 +89,8 @@
 	KERN_VERSION=4,		/* string: compile time info */
 	KERN_SECUREMASK=5,	/* struct: maximum rights mask */
 	KERN_PROF=6,		/* table: profiling information */
-	KERN_NODENAME=7,
-	KERN_DOMAINNAME=8,
+	KERN_NODENAME=7,	/* string: hostname */
+	KERN_DOMAINNAME=8,	/* string: domainname */
 
 	KERN_PANIC=15,		/* int: panic timeout */
 	KERN_REALROOTDEV=16,	/* real root device to mount after initrd */
@@ -102,8 +102,8 @@
 	KERN_PPC_HTABRECLAIM=25, /* turn htab reclaimation on/off on PPC */
 	KERN_PPC_ZEROPAGED=26,	/* turn idle page zeroing on/off on PPC */
 	KERN_PPC_POWERSAVE_NAP=27, /* use nap mode for power saving */
-	KERN_MODPROBE=28,
-	KERN_SG_BIG_BUFF=29,
+	KERN_MODPROBE=28,	/* string: modprobe path */
+	KERN_SG_BIG_BUFF=29,	/* int: sg driver reserved buffer size */
 	KERN_ACCT=30,		/* BSD process accounting parameters */
 	KERN_PPC_L2CR=31,	/* l2cr register on PPC */
 
@@ -150,7 +150,7 @@
 	KERN_ACPI_VIDEO_FLAGS=71, /* int: flags for setting up video after ACPI sleep */
 	KERN_IA64_UNALIGNED=72, /* int: ia64 unaligned userland trap enable */
 	KERN_COMPAT_LOG=73,	/* int: print compat layer  messages */
-	KERN_MAX_LOCK_DEPTH=74,
+	KERN_MAX_LOCK_DEPTH=74, /* int: rtmutex's maximum lock depth */
 	KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */
 	KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
 };
diff --git a/include/linux/tick.h b/include/linux/tick.h
index 0482229..d2ae79e 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -43,6 +43,7 @@
  * @idle_exittime:	Time when the idle state was left
  * @idle_sleeptime:	Sum of the time slept in idle with sched tick stopped
  * @sleep_length:	Duration of the current idle sleep
+ * @do_timer_lst:	CPU was the last one doing do_timer before going idle
  */
 struct tick_sched {
 	struct hrtimer			sched_timer;
@@ -64,6 +65,7 @@
 	unsigned long			last_jiffies;
 	unsigned long			next_jiffies;
 	ktime_t				idle_expires;
+	int				do_timer_last;
 };
 
 extern void __init tick_init(void);
@@ -98,6 +100,9 @@
 extern struct tick_sched *tick_get_tick_sched(int cpu);
 extern void tick_check_idle(int cpu);
 extern int tick_oneshot_mode_active(void);
+#  ifndef arch_needs_cpu
+#   define arch_needs_cpu(cpu) (0)
+#  endif
 # else
 static inline void tick_clock_notify(void) { }
 static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
diff --git a/include/linux/time.h b/include/linux/time.h
index fe04e5e..6e026e4 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -148,6 +148,7 @@
 
 extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
 extern int timekeeping_valid_for_hres(void);
+extern u64 timekeeping_max_deferment(void);
 extern void update_wall_time(void);
 extern void update_xtime_cache(u64 nsec);
 extern void timekeeping_leap_insert(int leapsecond);
diff --git a/include/linux/timex.h b/include/linux/timex.h
index e6967d1..94f8fae 100644
--- a/include/linux/timex.h
+++ b/include/linux/timex.h
@@ -115,13 +115,16 @@
 #define ADJ_OFFSET_SS_READ	0xa001	/* read-only adjtime */
 #endif
 
-/* xntp 3.4 compatibility names */
+/* NTP userland likes the MOD_ prefix better */
 #define MOD_OFFSET	ADJ_OFFSET
 #define MOD_FREQUENCY	ADJ_FREQUENCY
 #define MOD_MAXERROR	ADJ_MAXERROR
 #define MOD_ESTERROR	ADJ_ESTERROR
 #define MOD_STATUS	ADJ_STATUS
 #define MOD_TIMECONST	ADJ_TIMECONST
+#define MOD_TAI	ADJ_TAI
+#define MOD_MICRO	ADJ_MICRO
+#define MOD_NANO	ADJ_NANO
 
 
 /*
@@ -261,11 +264,7 @@
 
 #define NTP_SCALE_SHIFT		32
 
-#ifdef CONFIG_NO_HZ
-#define NTP_INTERVAL_FREQ  (2)
-#else
 #define NTP_INTERVAL_FREQ  (HZ)
-#endif
 #define NTP_INTERVAL_LENGTH (NSEC_PER_SEC/NTP_INTERVAL_FREQ)
 
 /* Returns how long ticks are at present, in ns / 2^NTP_SCALE_SHIFT. */
diff --git a/include/linux/tty.h b/include/linux/tty.h
index f0f43d0..405a903 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -190,9 +190,17 @@
 	/* Control the DTR line */
 	void (*dtr_rts)(struct tty_port *port, int raise);
 	/* Called when the last close completes or a hangup finishes
-	   IFF the port was initialized. Do not use to free resources */
+	   IFF the port was initialized. Do not use to free resources. Called
+	   under the port mutex to serialize against activate/shutdowns */
 	void (*shutdown)(struct tty_port *port);
 	void (*drop)(struct tty_port *port);
+	/* Called under the port mutex from tty_port_open, serialized using
+	   the port mutex */
+        /* FIXME: long term getting the tty argument *out* of this would be
+           good for consoles */
+	int (*activate)(struct tty_port *port, struct tty_struct *tty);
+	/* Called on the final put of a port */
+	void (*destruct)(struct tty_port *port);
 };
 	
 struct tty_port {
@@ -206,12 +214,14 @@
 	wait_queue_head_t	delta_msr_wait;	/* Modem status change */
 	unsigned long		flags;		/* TTY flags ASY_*/
 	struct mutex		mutex;		/* Locking */
+	struct mutex		buf_mutex;	/* Buffer alloc lock */
 	unsigned char		*xmit_buf;	/* Optional buffer */
 	unsigned int		close_delay;	/* Close port delay */
 	unsigned int		closing_wait;	/* Delay for output */
 	int			drain_delay;	/* Set to zero if no pure time
 						   based drain is needed else
 						   set to size of fifo */
+	struct kref		kref;		/* Ref counter */
 };
 
 /*
@@ -439,7 +449,7 @@
 		struct tty_driver *driver, int idx);
 extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
 								int first_ok);
-extern void tty_release_dev(struct file *filp);
+extern int tty_release(struct inode *inode, struct file *filp);
 extern int tty_init_termios(struct tty_struct *tty);
 
 extern struct tty_struct *tty_pair_get_tty(struct tty_struct *tty);
@@ -454,6 +464,15 @@
 extern void tty_port_init(struct tty_port *port);
 extern int tty_port_alloc_xmit_buf(struct tty_port *port);
 extern void tty_port_free_xmit_buf(struct tty_port *port);
+extern void tty_port_put(struct tty_port *port);
+
+extern inline struct tty_port *tty_port_get(struct tty_port *port)
+{
+	if (port)
+		kref_get(&port->kref);
+	return port;
+}
+
 extern struct tty_struct *tty_port_tty_get(struct tty_port *port);
 extern void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty);
 extern int tty_port_carrier_raised(struct tty_port *port);
@@ -467,6 +486,8 @@
 extern void tty_port_close_end(struct tty_port *port, struct tty_struct *tty);
 extern void tty_port_close(struct tty_port *port,
 				struct tty_struct *tty, struct file *filp);
+extern int tty_port_open(struct tty_port *port,
+				struct tty_struct *tty, struct file *filp);
 extern inline int tty_port_users(struct tty_port *port)
 {
 	return port->count + port->blocked_open;
diff --git a/include/linux/ucb1400.h b/include/linux/ucb1400.h
index adb4406..1b47909 100644
--- a/include/linux/ucb1400.h
+++ b/include/linux/ucb1400.h
@@ -110,6 +110,10 @@
 	struct platform_device	*ucb1400_gpio;
 };
 
+struct ucb1400_pdata {
+	int	irq;
+};
+
 static inline u16 ucb1400_reg_read(struct snd_ac97 *ac97, u16 reg)
 {
 	return ac97->bus->ops->read(ac97, reg);
diff --git a/include/linux/usb.h b/include/linux/usb.h
index a34fa89..e101a2d 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -331,6 +331,7 @@
 	u8 otg_port;			/* 0, or number of OTG/HNP port */
 	unsigned is_b_host:1;		/* true during some HNP roleswitches */
 	unsigned b_hnp_enable:1;	/* OTG: did A-Host enable HNP? */
+	unsigned sg_tablesize;		/* 0 or largest number of sg list entries */
 
 	int devnum_next;		/* Next open device number in
 					 * round-robin allocation */
@@ -428,11 +429,9 @@
  * @last_busy: time of last use
  * @autosuspend_delay: in jiffies
  * @connect_time: time device was first connected
- * @auto_pm: autosuspend/resume in progress
  * @do_remote_wakeup:  remote wakeup should be enabled
  * @reset_resume: needs reset instead of resume
  * @autosuspend_disabled: autosuspend disabled by the user
- * @autoresume_disabled: autoresume disabled by the user
  * @skip_sys_resume: skip the next system resume
  * @wusb_dev: if this is a Wireless USB device, link to the WUSB
  *	specific data for the device.
@@ -513,11 +512,9 @@
 	int autosuspend_delay;
 	unsigned long connect_time;
 
-	unsigned auto_pm:1;
 	unsigned do_remote_wakeup:1;
 	unsigned reset_resume:1;
 	unsigned autosuspend_disabled:1;
-	unsigned autoresume_disabled:1;
 	unsigned skip_sys_resume:1;
 #endif
 	struct wusb_dev *wusb_dev;
@@ -543,22 +540,20 @@
 
 /* USB autosuspend and autoresume */
 #ifdef CONFIG_USB_SUSPEND
-extern int usb_autopm_set_interface(struct usb_interface *intf);
 extern int usb_autopm_get_interface(struct usb_interface *intf);
 extern void usb_autopm_put_interface(struct usb_interface *intf);
 extern int usb_autopm_get_interface_async(struct usb_interface *intf);
 extern void usb_autopm_put_interface_async(struct usb_interface *intf);
 
-static inline void usb_autopm_enable(struct usb_interface *intf)
+static inline void usb_autopm_get_interface_no_resume(
+		struct usb_interface *intf)
 {
-	atomic_set(&intf->pm_usage_cnt, 0);
-	usb_autopm_set_interface(intf);
+	atomic_inc(&intf->pm_usage_cnt);
 }
-
-static inline void usb_autopm_disable(struct usb_interface *intf)
+static inline void usb_autopm_put_interface_no_suspend(
+		struct usb_interface *intf)
 {
-	atomic_set(&intf->pm_usage_cnt, 1);
-	usb_autopm_set_interface(intf);
+	atomic_dec(&intf->pm_usage_cnt);
 }
 
 static inline void usb_mark_last_busy(struct usb_device *udev)
@@ -568,12 +563,8 @@
 
 #else
 
-static inline int usb_autopm_set_interface(struct usb_interface *intf)
-{ return 0; }
-
 static inline int usb_autopm_get_interface(struct usb_interface *intf)
 { return 0; }
-
 static inline int usb_autopm_get_interface_async(struct usb_interface *intf)
 { return 0; }
 
@@ -581,9 +572,11 @@
 { }
 static inline void usb_autopm_put_interface_async(struct usb_interface *intf)
 { }
-static inline void usb_autopm_enable(struct usb_interface *intf)
+static inline void usb_autopm_get_interface_no_resume(
+		struct usb_interface *intf)
 { }
-static inline void usb_autopm_disable(struct usb_interface *intf)
+static inline void usb_autopm_put_interface_no_suspend(
+		struct usb_interface *intf)
 { }
 static inline void usb_mark_last_busy(struct usb_device *udev)
 { }
@@ -626,6 +619,10 @@
 		unsigned ifnum);
 extern struct usb_host_interface *usb_altnum_to_altsetting(
 		const struct usb_interface *intf, unsigned int altnum);
+extern struct usb_host_interface *usb_find_alt_setting(
+		struct usb_host_config *config,
+		unsigned int iface_num,
+		unsigned int alt_num);
 
 
 /**
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index 4f6bb3d..738ea1a 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -127,6 +127,7 @@
 	/* private: */
 	/* internals */
 	struct list_head		list;
+	DECLARE_BITMAP(endpoints, 32);
 };
 
 int usb_add_function(struct usb_configuration *, struct usb_function *);
diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h
index 2443c0e..52bb917 100644
--- a/include/linux/usb/otg.h
+++ b/include/linux/usb/otg.h
@@ -33,6 +33,23 @@
 	OTG_STATE_A_VBUS_ERR,
 };
 
+#define USB_OTG_PULLUP_ID		(1 << 0)
+#define USB_OTG_PULLDOWN_DP		(1 << 1)
+#define USB_OTG_PULLDOWN_DM		(1 << 2)
+#define USB_OTG_EXT_VBUS_INDICATOR	(1 << 3)
+#define USB_OTG_DRV_VBUS		(1 << 4)
+#define USB_OTG_DRV_VBUS_EXT		(1 << 5)
+
+struct otg_transceiver;
+
+/* for transceivers connected thru an ULPI interface, the user must
+ * provide access ops
+ */
+struct otg_io_access_ops {
+	int (*read)(struct otg_transceiver *otg, u32 reg);
+	int (*write)(struct otg_transceiver *otg, u32 val, u32 reg);
+};
+
 /*
  * the otg driver needs to interact with both device side and host side
  * usb controllers.  it decides which controller is active at a given
@@ -42,6 +59,7 @@
 struct otg_transceiver {
 	struct device		*dev;
 	const char		*label;
+	unsigned int		 flags;
 
 	u8			default_a;
 	enum usb_otg_state	state;
@@ -49,10 +67,17 @@
 	struct usb_bus		*host;
 	struct usb_gadget	*gadget;
 
+	struct otg_io_access_ops	*io_ops;
+	void __iomem			*io_priv;
+
 	/* to pass extra port status to the root hub */
 	u16			port_status;
 	u16			port_change;
 
+	/* initialize/shutdown the OTG controller */
+	int	(*init)(struct otg_transceiver *otg);
+	void	(*shutdown)(struct otg_transceiver *otg);
+
 	/* bind/unbind the host controller */
 	int	(*set_host)(struct otg_transceiver *otg,
 				struct usb_bus *host);
@@ -65,6 +90,10 @@
 	int	(*set_power)(struct otg_transceiver *otg,
 				unsigned mA);
 
+	/* effective for A-peripheral, ignored for B devices */
+	int	(*set_vbus)(struct otg_transceiver *otg,
+				bool enabled);
+
 	/* for non-OTG B devices: set transceiver into suspend mode */
 	int	(*set_suspend)(struct otg_transceiver *otg,
 				int suspend);
@@ -85,6 +114,38 @@
 extern void usb_nop_xceiv_register(void);
 extern void usb_nop_xceiv_unregister(void);
 
+/* helpers for direct access thru low-level io interface */
+static inline int otg_io_read(struct otg_transceiver *otg, u32 reg)
+{
+	if (otg->io_ops && otg->io_ops->read)
+		return otg->io_ops->read(otg, reg);
+
+	return -EINVAL;
+}
+
+static inline int otg_io_write(struct otg_transceiver *otg, u32 reg, u32 val)
+{
+	if (otg->io_ops && otg->io_ops->write)
+		return otg->io_ops->write(otg, reg, val);
+
+	return -EINVAL;
+}
+
+static inline int
+otg_init(struct otg_transceiver *otg)
+{
+	if (otg->init)
+		return otg->init(otg);
+
+	return 0;
+}
+
+static inline void
+otg_shutdown(struct otg_transceiver *otg)
+{
+	if (otg->shutdown)
+		otg->shutdown(otg);
+}
 
 /* for usb host and peripheral controller drivers */
 extern struct otg_transceiver *otg_get_transceiver(void);
@@ -97,6 +158,12 @@
 	return otg->start_hnp(otg);
 }
 
+/* Context: can sleep */
+static inline int
+otg_set_vbus(struct otg_transceiver *otg, bool enabled)
+{
+	return otg->set_vbus(otg, enabled);
+}
 
 /* for HCDs */
 static inline int
@@ -105,7 +172,6 @@
 	return otg->set_host(otg, host);
 }
 
-
 /* for usb peripheral controller drivers */
 
 /* Context: can sleep */
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index ce911eb..acf6e45 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -39,8 +39,6 @@
  * @serial: pointer back to the struct usb_serial owner of this port.
  * @port: pointer to the corresponding tty_port for this port.
  * @lock: spinlock to grab when updating portions of this structure.
- * @mutex: mutex used to synchronize serial_open() and serial_close()
- *	access for this port.
  * @number: the number of the port (the minor number).
  * @interrupt_in_buffer: pointer to the interrupt in buffer for this port.
  * @interrupt_in_urb: pointer to the interrupt in struct urb for this port.
@@ -77,7 +75,6 @@
 	struct usb_serial	*serial;
 	struct tty_port		port;
 	spinlock_t		lock;
-	struct mutex            mutex;
 	unsigned char		number;
 
 	unsigned char		*interrupt_in_buffer;
diff --git a/include/linux/usb/ulpi.h b/include/linux/usb/ulpi.h
new file mode 100644
index 0000000..20675c6
--- /dev/null
+++ b/include/linux/usb/ulpi.h
@@ -0,0 +1,7 @@
+#ifndef __LINUX_USB_ULPI_H
+#define __LINUX_USB_ULPI_H
+
+struct otg_transceiver *otg_ulpi_create(struct otg_io_access_ops *ops,
+					unsigned int flags);
+
+#endif /* __LINUX_USB_ULPI_H */
diff --git a/include/linux/usb/wusb.h b/include/linux/usb/wusb.h
index 429c631..63ebdcc 100644
--- a/include/linux/usb/wusb.h
+++ b/include/linux/usb/wusb.h
@@ -74,7 +74,7 @@
  * WUSB defines that CHIDs, CDIDs and CKs are a 16 byte string of
  * data. In order to avoid confusion and enforce types, we wrap it.
  *
- * Make it packed, as we use it in some hw defintions.
+ * Make it packed, as we use it in some hw definitions.
  */
 struct wusb_ckhdid {
 	u8 data[16];
diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h
index 3d15fb9..a4b947e 100644
--- a/include/linux/usb_usual.h
+++ b/include/linux/usb_usual.h
@@ -56,7 +56,9 @@
 	US_FLAG(SANE_SENSE,     0x00008000)			\
 		/* Sane Sense (> 18 bytes) */			\
 	US_FLAG(CAPACITY_OK,	0x00010000)			\
-		/* READ CAPACITY response is correct */
+		/* READ CAPACITY response is correct */		\
+	US_FLAG(BAD_SENSE,	0x00020000)			\
+		/* Bad Sense (never more than 18 bytes) */
 
 #define US_FLAG(name, value)	US_FL_##name = value ,
 enum { US_DO_ALL_FLAGS };
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index b59e78c..32b9229 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -361,6 +361,7 @@
 #define V4L2_PIX_FMT_PJPG     v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */
 #define V4L2_PIX_FMT_OV511    v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */
 #define V4L2_PIX_FMT_OV518    v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */
+#define V4L2_PIX_FMT_STV0680  v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */
 
 /*
  *	F O R M A T   E N U M E R A T I O N
@@ -490,7 +491,7 @@
 				 * you do, leave them untouched.
 				 * Inluding less markers will make the
 				 * resulting code smaller, but there will
-				 * be fewer aplications which can read it.
+				 * be fewer applications which can read it.
 				 * The presence of the APP and COM marker
 				 * is influenced by APP_len and COM_len
 				 * ONLY, not by this property! */
@@ -563,6 +564,7 @@
 #define V4L2_FBUF_CAP_LOCAL_ALPHA	0x0010
 #define V4L2_FBUF_CAP_GLOBAL_ALPHA	0x0020
 #define V4L2_FBUF_CAP_LOCAL_INV_ALPHA	0x0040
+#define V4L2_FBUF_CAP_SRC_CHROMAKEY	0x0080
 /*  Flags for the 'flags' field. */
 #define V4L2_FBUF_FLAG_PRIMARY		0x0001
 #define V4L2_FBUF_FLAG_OVERLAY		0x0002
@@ -570,6 +572,7 @@
 #define V4L2_FBUF_FLAG_LOCAL_ALPHA	0x0008
 #define V4L2_FBUF_FLAG_GLOBAL_ALPHA	0x0010
 #define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA	0x0020
+#define V4L2_FBUF_FLAG_SRC_CHROMAKEY	0x0040
 
 struct v4l2_clip {
 	struct v4l2_rect        c;
@@ -912,8 +915,10 @@
 #define V4L2_CID_AUTOBRIGHTNESS			(V4L2_CID_BASE+32)
 #define V4L2_CID_BAND_STOP_FILTER		(V4L2_CID_BASE+33)
 
+#define V4L2_CID_ROTATE				(V4L2_CID_BASE+34)
+#define V4L2_CID_BG_COLOR			(V4L2_CID_BASE+35)
 /* last CID + 1 */
-#define V4L2_CID_LASTP1                         (V4L2_CID_BASE+34)
+#define V4L2_CID_LASTP1                         (V4L2_CID_BASE+36)
 
 /*  MPEG-class control IDs defined by V4L2 */
 #define V4L2_CID_MPEG_BASE 			(V4L2_CTRL_CLASS_MPEG | 0x900)
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index c0c4e11..7f56db4 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -110,6 +110,7 @@
 extern struct mutex con_buf_mtx;
 extern char vt_dont_switch;
 extern int default_utf8;
+extern int global_cursor_default;
 
 struct vt_spawn_console {
 	spinlock_t lock;
@@ -130,4 +131,6 @@
 extern int register_vt_notifier(struct notifier_block *nb);
 extern int unregister_vt_notifier(struct notifier_block *nb);
 
+extern void hide_boot_cursor(bool hide);
+
 #endif /* _VT_KERN_H */
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index cf24c20..9466e86 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -25,6 +25,7 @@
 struct work_struct {
 	atomic_long_t data;
 #define WORK_STRUCT_PENDING 0		/* T if work item pending execution */
+#define WORK_STRUCT_STATIC  1		/* static initializer (debugobjects) */
 #define WORK_STRUCT_FLAG_MASK (3UL)
 #define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK)
 	struct list_head entry;
@@ -35,6 +36,7 @@
 };
 
 #define WORK_DATA_INIT()	ATOMIC_LONG_INIT(0)
+#define WORK_DATA_STATIC_INIT()	ATOMIC_LONG_INIT(2)
 
 struct delayed_work {
 	struct work_struct work;
@@ -63,7 +65,7 @@
 #endif
 
 #define __WORK_INITIALIZER(n, f) {				\
-	.data = WORK_DATA_INIT(),				\
+	.data = WORK_DATA_STATIC_INIT(),			\
 	.entry	= { &(n).entry, &(n).entry },			\
 	.func = (f),						\
 	__WORK_INIT_LOCKDEP_MAP(#n, &(n))			\
@@ -91,6 +93,14 @@
 #define PREPARE_DELAYED_WORK(_work, _func)			\
 	PREPARE_WORK(&(_work)->work, (_func))
 
+#ifdef CONFIG_DEBUG_OBJECTS_WORK
+extern void __init_work(struct work_struct *work, int onstack);
+extern void destroy_work_on_stack(struct work_struct *work);
+#else
+static inline void __init_work(struct work_struct *work, int onstack) { }
+static inline void destroy_work_on_stack(struct work_struct *work) { }
+#endif
+
 /*
  * initialize all of a work item in one go
  *
@@ -99,24 +109,36 @@
  * to generate better code.
  */
 #ifdef CONFIG_LOCKDEP
-#define INIT_WORK(_work, _func)						\
+#define __INIT_WORK(_work, _func, _onstack)				\
 	do {								\
 		static struct lock_class_key __key;			\
 									\
+		__init_work((_work), _onstack);				\
 		(_work)->data = (atomic_long_t) WORK_DATA_INIT();	\
 		lockdep_init_map(&(_work)->lockdep_map, #_work, &__key, 0);\
 		INIT_LIST_HEAD(&(_work)->entry);			\
 		PREPARE_WORK((_work), (_func));				\
 	} while (0)
 #else
-#define INIT_WORK(_work, _func)						\
+#define __INIT_WORK(_work, _func, _onstack)				\
 	do {								\
+		__init_work((_work), _onstack);				\
 		(_work)->data = (atomic_long_t) WORK_DATA_INIT();	\
 		INIT_LIST_HEAD(&(_work)->entry);			\
 		PREPARE_WORK((_work), (_func));				\
 	} while (0)
 #endif
 
+#define INIT_WORK(_work, _func)					\
+	do {							\
+		__INIT_WORK((_work), (_func), 0);		\
+	} while (0)
+
+#define INIT_WORK_ON_STACK(_work, _func)			\
+	do {							\
+		__INIT_WORK((_work), (_func), 1);		\
+	} while (0)
+
 #define INIT_DELAYED_WORK(_work, _func)				\
 	do {							\
 		INIT_WORK(&(_work)->work, (_func));		\
@@ -125,22 +147,16 @@
 
 #define INIT_DELAYED_WORK_ON_STACK(_work, _func)		\
 	do {							\
-		INIT_WORK(&(_work)->work, (_func));		\
+		INIT_WORK_ON_STACK(&(_work)->work, (_func));	\
 		init_timer_on_stack(&(_work)->timer);		\
 	} while (0)
 
-#define INIT_DELAYED_WORK_DEFERRABLE(_work, _func)			\
+#define INIT_DELAYED_WORK_DEFERRABLE(_work, _func)		\
 	do {							\
 		INIT_WORK(&(_work)->work, (_func));		\
 		init_timer_deferrable(&(_work)->timer);		\
 	} while (0)
 
-#define INIT_DELAYED_WORK_ON_STACK(_work, _func)		\
-	do {							\
-		INIT_WORK(&(_work)->work, (_func));		\
-		init_timer_on_stack(&(_work)->timer);		\
-	} while (0)
-
 /**
  * work_pending - Find out whether a work item is currently pending
  * @work: The work item in question
diff --git a/include/media/cx25840.h b/include/media/cx25840.h
index 2c3fbaa..0b0cb17 100644
--- a/include/media/cx25840.h
+++ b/include/media/cx25840.h
@@ -84,6 +84,7 @@
 	CX25840_NONE0_CH3 = 0x80000080,
 	CX25840_NONE1_CH3 = 0x800000c0,
 	CX25840_SVIDEO_ON = 0x80000100,
+	CX25840_COMPONENT_ON = 0x80000200,
 };
 
 enum cx25840_audio_input {
diff --git a/include/media/davinci/vpfe_capture.h b/include/media/davinci/vpfe_capture.h
index 71d8982..d863e5e 100644
--- a/include/media/davinci/vpfe_capture.h
+++ b/include/media/davinci/vpfe_capture.h
@@ -83,6 +83,8 @@
 struct vpfe_config {
 	/* Number of sub devices connected to vpfe */
 	int num_subdevs;
+	/* i2c bus adapter no */
+	int i2c_adapter_id;
 	/* information about each subdev */
 	struct vpfe_subdev_info *sub_devs;
 	/* evm card info */
diff --git a/include/media/ir-common.h b/include/media/ir-common.h
index 29f0e53..e41a99e 100644
--- a/include/media/ir-common.h
+++ b/include/media/ir-common.h
@@ -26,14 +26,16 @@
 #include <linux/input.h>
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
+#include <linux/spinlock.h>
+
+extern int media_ir_debug;    /* media_ir_debug level (0,1,2) */
+#define IR_dprintk(level, fmt, arg...)	if (media_ir_debug >= level) \
+	printk(KERN_DEBUG "%s: " fmt , __func__, ## arg)
 
 #define IR_TYPE_RC5     1
 #define IR_TYPE_PD      2 /* Pulse distance encoded IR */
 #define IR_TYPE_OTHER  99
 
-#define IR_KEYTAB_TYPE u32
-#define IR_KEYTAB_SIZE	128  /* enougth for rc5, probably need more some day */
-
 struct ir_scancode {
 	u16	scancode;
 	u32	keycode;
@@ -42,11 +44,9 @@
 struct ir_scancode_table {
 	struct ir_scancode *scan;
 	int size;
+	spinlock_t lock;
 };
 
-#define IR_KEYCODE(tab,code)	(((unsigned)code < IR_KEYTAB_SIZE) \
-				 ? tab[code] : KEY_RESERVED)
-
 #define RC5_START(x)	(((x)>>12)&3)
 #define RC5_TOGGLE(x)	(((x)>>11)&1)
 #define RC5_ADDR(x)	(((x)>>6)&31)
@@ -55,11 +55,11 @@
 struct ir_input_state {
 	/* configuration */
 	int                ir_type;
-	IR_KEYTAB_TYPE     ir_codes[IR_KEYTAB_SIZE];
+
+	struct ir_scancode_table keytable;
 
 	/* key info */
-	u32                ir_raw;      /* raw data */
-	u32                ir_key;      /* ir key code */
+	u32                ir_key;      /* ir scancode */
 	u32                keycode;     /* linux key code */
 	int                keypressed;  /* current state */
 };
@@ -102,20 +102,36 @@
 	struct tasklet_struct   tlet;
 };
 
-void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
+/* Routines from ir-functions.c */
+
+int ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
 		   int ir_type, struct ir_scancode_table *ir_codes);
 void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir);
 void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
-		      u32 ir_key, u32 ir_raw);
+		      u32 ir_key);
 u32  ir_extract_bits(u32 data, u32 mask);
 int  ir_dump_samples(u32 *samples, int count);
 int  ir_decode_biphase(u32 *samples, int count, int low, int high);
 int  ir_decode_pulsedistance(u32 *samples, int count, int low, int high);
+u32  ir_rc5_decode(unsigned int code);
 
 void ir_rc5_timer_end(unsigned long data);
 void ir_rc5_timer_keyup(unsigned long data);
 
-/* Keymaps to be used by other modules */
+/* Routines from ir-keytable.c */
+
+u32 ir_g_keycode_from_table(struct input_dev *input_dev,
+			    u32 scancode);
+
+int ir_set_keycode_table(struct input_dev *input_dev,
+			 struct ir_scancode_table *rc_tab);
+
+int ir_roundup_tablesize(int n_elems);
+int ir_copy_table(struct ir_scancode_table *destin,
+		 const struct ir_scancode_table *origin);
+void ir_input_free(struct input_dev *input_dev);
+
+/* scancode->keycode map tables from ir-keymaps.c */
 
 extern struct ir_scancode_table ir_codes_empty_table;
 extern struct ir_scancode_table ir_codes_avermedia_table;
@@ -150,6 +166,7 @@
 extern struct ir_scancode_table ir_codes_winfast_table;
 extern struct ir_scancode_table ir_codes_pinnacle_color_table;
 extern struct ir_scancode_table ir_codes_hauppauge_new_table;
+extern struct ir_scancode_table ir_codes_rc5_hauppauge_new_table;
 extern struct ir_scancode_table ir_codes_npgtech_table;
 extern struct ir_scancode_table ir_codes_norwood_table;
 extern struct ir_scancode_table ir_codes_proteus_2309_table;
@@ -172,6 +189,8 @@
 extern struct ir_scancode_table ir_codes_kworld_plus_tv_analog_table;
 extern struct ir_scancode_table ir_codes_kaiomy_table;
 extern struct ir_scancode_table ir_codes_dm1105_nec_table;
+extern struct ir_scancode_table ir_codes_tevii_nec_table;
+extern struct ir_scancode_table ir_codes_tbs_nec_table;
 extern struct ir_scancode_table ir_codes_evga_indtube_table;
 extern struct ir_scancode_table ir_codes_terratec_cinergy_xs_table;
 extern struct ir_scancode_table ir_codes_videomate_s350_table;
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h
index cf16689..91942db 100644
--- a/include/media/v4l2-chip-ident.h
+++ b/include/media/v4l2-chip-ident.h
@@ -64,6 +64,7 @@
 	V4L2_IDENT_OV9650 = 254,
 	V4L2_IDENT_OV9655 = 255,
 	V4L2_IDENT_SOI968 = 256,
+	V4L2_IDENT_OV9640 = 257,
 
 	/* module saa7146: reserved range 300-309 */
 	V4L2_IDENT_SAA7146 = 300,
@@ -72,6 +73,7 @@
 	V4L2_IDENT_CX23418_843 = 403, /* Integrated A/V Decoder on the '418 */
 	V4L2_IDENT_CX23415 = 415,
 	V4L2_IDENT_CX23416 = 416,
+	V4L2_IDENT_CX23417 = 417,
 	V4L2_IDENT_CX23418 = 418,
 
 	/* module au0828 */
@@ -129,6 +131,9 @@
 	V4L2_IDENT_SAA6752HS = 6752,
 	V4L2_IDENT_SAA6752HS_AC3 = 6753,
 
+	/* modules tef6862: just ident 6862 */
+	V4L2_IDENT_TEF6862 = 6862,
+
 	/* module adv7170: just ident 7170 */
 	V4L2_IDENT_ADV7170 = 7170,
 
@@ -165,12 +170,27 @@
 	/* module mt9v011, just ident 8243 */
 	V4L2_IDENT_MT9V011 = 8243,
 
+	/* module cx23885 and cx25840 */
+	V4L2_IDENT_CX23885    = 8850,
+	V4L2_IDENT_CX23885_AV = 8851, /* Integrated A/V decoder */
+	V4L2_IDENT_CX23887    = 8870,
+	V4L2_IDENT_CX23887_AV = 8871, /* Integrated A/V decoder */
+	V4L2_IDENT_CX23888    = 8880,
+	V4L2_IDENT_CX23888_AV = 8881, /* Integrated A/V decoder */
+	V4L2_IDENT_CX23888_IR = 8882, /* Integrated infrared controller */
+
 	/* module tw9910: just ident 9910 */
 	V4L2_IDENT_TW9910 = 9910,
 
 	/* module sn9c20x: just ident 10000 */
 	V4L2_IDENT_SN9C20X = 10000,
 
+	/* module cx231xx and cx25840 */
+	V4L2_IDENT_CX2310X_AV = 23099, /* Integrated A/V decoder; not in '100 */
+	V4L2_IDENT_CX23100    = 23100,
+	V4L2_IDENT_CX23101    = 23101,
+	V4L2_IDENT_CX23102    = 23102,
+
 	/* module msp3400: reserved range 34000-34999 and 44000-44999 */
 	V4L2_IDENT_MSPX4XX  = 34000, /* generic MSPX4XX identifier, only
 					use internally (tveeprom.c). */
@@ -264,6 +284,9 @@
 
 	/* module m52790: just ident 52790 */
 	V4L2_IDENT_M52790 = 52790,
+
+	/* Sharp RJ54N1CB0C, 0xCB0C = 51980 */
+	V4L2_IDENT_RJ54N1CB0C = 51980,
 };
 
 #endif
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index d411345..00bf176 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -23,6 +23,16 @@
 
 #include <media/v4l2-common.h>
 
+/* generic v4l2_device notify callback notification values */
+#define V4L2_SUBDEV_IR_RX_NOTIFY		_IOW('v', 0, u32)
+#define V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ	0x00000001
+#define V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED	0x00000002
+#define V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN	0x00000004
+#define V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN	0x00000008
+
+#define V4L2_SUBDEV_IR_TX_NOTIFY		_IOW('v', 1, u32)
+#define V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ	0x00000001
+
 struct v4l2_device;
 struct v4l2_subdev;
 struct tuner_setup;
@@ -96,6 +106,9 @@
 
    s_gpio: set GPIO pins. Very simple right now, might need to be extended with
 	a direction argument if needed.
+
+   s_power: puts subdevice in power saving mode (on == 0) or normal operation
+	mode (on == 1).
  */
 struct v4l2_subdev_core_ops {
 	int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip);
@@ -118,6 +131,7 @@
 	int (*g_register)(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg);
 	int (*s_register)(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg);
 #endif
+	int (*s_power)(struct v4l2_subdev *sd, int on);
 };
 
 /* s_mode: switch the tuner to a specific tuner mode. Replacement of s_radio.
@@ -127,8 +141,6 @@
    s_type_addr: sets tuner type and its I2C addr.
 
    s_config: sets tda9887 specific stuff, like port1, port2 and qss
-
-   s_standby: puts tuner on powersaving state, disabling it, except for i2c.
  */
 struct v4l2_subdev_tuner_ops {
 	int (*s_mode)(struct v4l2_subdev *sd, enum v4l2_tuner_type);
@@ -141,7 +153,6 @@
 	int (*s_modulator)(struct v4l2_subdev *sd, struct v4l2_modulator *vm);
 	int (*s_type_addr)(struct v4l2_subdev *sd, struct tuner_setup *type);
 	int (*s_config)(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *config);
-	int (*s_standby)(struct v4l2_subdev *sd);
 };
 
 /* s_clock_freq: set the frequency (in Hz) of the audio clock output.
@@ -231,11 +242,95 @@
 	int (*enum_frameintervals)(struct v4l2_subdev *sd, struct v4l2_frmivalenum *fival);
 };
 
+/*
+   interrupt_service_routine: Called by the bridge chip's interrupt service
+	handler, when an IR interrupt status has be raised due to this subdev,
+	so that this subdev can handle the details.  It may schedule work to be
+	performed later.  It must not sleep.  *Called from an IRQ context*.
+
+   [rt]x_g_parameters: Get the current operating parameters and state of the
+	the IR receiver or transmitter.
+
+   [rt]x_s_parameters: Set the current operating parameters and state of the
+	the IR receiver or transmitter.  It is recommended to call
+	[rt]x_g_parameters first to fill out the current state, and only change
+	the fields that need to be changed.  Upon return, the actual device
+	operating parameters and state will be returned.  Note that hardware
+	limitations may prevent the actual settings from matching the requested
+	settings - e.g. an actual carrier setting of 35,904 Hz when 36,000 Hz
+	was requested.  An exception is when the shutdown parameter is true.
+	The last used operational parameters will be returned, but the actual
+	state of the hardware be different to minimize power consumption and
+	processing when shutdown is true.
+
+   rx_read: Reads received codes or pulse width data.
+	The semantics are similar to a non-blocking read() call.
+
+   tx_write: Writes codes or pulse width data for transmission.
+	The semantics are similar to a non-blocking write() call.
+ */
+
+enum v4l2_subdev_ir_mode {
+	V4L2_SUBDEV_IR_MODE_PULSE_WIDTH, /* space & mark widths in nanosecs */
+};
+
+/* Data format of data read or written for V4L2_SUBDEV_IR_MODE_PULSE_WIDTH */
+#define V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS	0x7fffffff
+#define V4L2_SUBDEV_IR_PULSE_LEVEL_MASK		0x80000000
+#define V4L2_SUBDEV_IR_PULSE_RX_SEQ_END		0xffffffff
+
+struct v4l2_subdev_ir_parameters {
+	/* Either Rx or Tx */
+	unsigned int bytes_per_data_element; /* of data in read or write call */
+	enum v4l2_subdev_ir_mode mode;
+
+	bool enable;
+	bool interrupt_enable;
+	bool shutdown; /* true: set hardware to low/no power, false: normal */
+
+	bool modulation;           /* true: uses carrier, false: baseband */
+	u32 max_pulse_width;       /* ns,      valid only for baseband signal */
+	unsigned int carrier_freq; /* Hz,      valid only for modulated signal*/
+	unsigned int duty_cycle;   /* percent, valid only for modulated signal*/
+	bool invert;		   /* logically invert sense of mark/space */
+
+	/* Rx only */
+	u32 noise_filter_min_width;       /* ns, min time of a valid pulse */
+	unsigned int carrier_range_lower; /* Hz, valid only for modulated sig */
+	unsigned int carrier_range_upper; /* Hz, valid only for modulated sig */
+	u32 resolution;                   /* ns */
+};
+
+struct v4l2_subdev_ir_ops {
+	/* Common to receiver and transmitter */
+	int (*interrupt_service_routine)(struct v4l2_subdev *sd,
+						u32 status, bool *handled);
+
+	/* Receiver */
+	int (*rx_read)(struct v4l2_subdev *sd, u8 *buf, size_t count,
+				ssize_t *num);
+
+	int (*rx_g_parameters)(struct v4l2_subdev *sd,
+				struct v4l2_subdev_ir_parameters *params);
+	int (*rx_s_parameters)(struct v4l2_subdev *sd,
+				struct v4l2_subdev_ir_parameters *params);
+
+	/* Transmitter */
+	int (*tx_write)(struct v4l2_subdev *sd, u8 *buf, size_t count,
+				ssize_t *num);
+
+	int (*tx_g_parameters)(struct v4l2_subdev *sd,
+				struct v4l2_subdev_ir_parameters *params);
+	int (*tx_s_parameters)(struct v4l2_subdev *sd,
+				struct v4l2_subdev_ir_parameters *params);
+};
+
 struct v4l2_subdev_ops {
 	const struct v4l2_subdev_core_ops  *core;
 	const struct v4l2_subdev_tuner_ops *tuner;
 	const struct v4l2_subdev_audio_ops *audio;
 	const struct v4l2_subdev_video_ops *video;
+	const struct v4l2_subdev_ir_ops    *ir;
 };
 
 #define V4L2_SUBDEV_NAME_SIZE 32
@@ -290,7 +385,7 @@
    Example: err = v4l2_subdev_call(sd, core, g_chip_ident, &chip);
  */
 #define v4l2_subdev_call(sd, o, f, args...)				\
-	(!(sd) ? -ENODEV : (((sd) && (sd)->ops->o && (sd)->ops->o->f) ?	\
+	(!(sd) ? -ENODEV : (((sd)->ops->o && (sd)->ops->o->f) ?	\
 		(sd)->ops->o->f((sd) , ##args) : -ENOIOCTLCMD))
 
 /* Send a notification to v4l2_device. */
diff --git a/include/media/videobuf-core.h b/include/media/videobuf-core.h
index 1c5946c..316fdcc 100644
--- a/include/media/videobuf-core.h
+++ b/include/media/videobuf-core.h
@@ -166,7 +166,7 @@
 	enum v4l2_field            field;
 	enum v4l2_field            last;   /* for field=V4L2_FIELD_ALTERNATE */
 	struct videobuf_buffer     *bufs[VIDEO_MAX_FRAME];
-	struct videobuf_queue_ops  *ops;
+	const struct videobuf_queue_ops  *ops;
 	struct videobuf_qtype_ops  *int_ops;
 
 	unsigned int               streaming:1;
@@ -195,7 +195,7 @@
 				 struct videobuf_buffer *buf);
 
 void videobuf_queue_core_init(struct videobuf_queue *q,
-			 struct videobuf_queue_ops *ops,
+			 const struct videobuf_queue_ops *ops,
 			 struct device *dev,
 			 spinlock_t *irqlock,
 			 enum v4l2_buf_type type,
diff --git a/include/media/videobuf-dma-contig.h b/include/media/videobuf-dma-contig.h
index 5493866..ebaa9bc 100644
--- a/include/media/videobuf-dma-contig.h
+++ b/include/media/videobuf-dma-contig.h
@@ -17,7 +17,7 @@
 #include <media/videobuf-core.h>
 
 void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
-				    struct videobuf_queue_ops *ops,
+				    const struct videobuf_queue_ops *ops,
 				    struct device *dev,
 				    spinlock_t *irqlock,
 				    enum v4l2_buf_type type,
diff --git a/include/media/videobuf-dma-sg.h b/include/media/videobuf-dma-sg.h
index dda47f0..53e72f7 100644
--- a/include/media/videobuf-dma-sg.h
+++ b/include/media/videobuf-dma-sg.h
@@ -103,7 +103,7 @@
 void *videobuf_sg_alloc(size_t size);
 
 void videobuf_queue_sg_init(struct videobuf_queue* q,
-			 struct videobuf_queue_ops *ops,
+			 const struct videobuf_queue_ops *ops,
 			 struct device *dev,
 			 spinlock_t *irqlock,
 			 enum v4l2_buf_type type,
diff --git a/include/media/videobuf-dvb.h b/include/media/videobuf-dvb.h
index 6ba4f12..07cf4b9 100644
--- a/include/media/videobuf-dvb.h
+++ b/include/media/videobuf-dvb.h
@@ -42,7 +42,9 @@
 			  void *adapter_priv,
 			  struct device *device,
 			  short *adapter_nr,
-			  int mfe_shared);
+			  int mfe_shared,
+			  int (*fe_ioctl_override)(struct dvb_frontend *,
+					unsigned int, void *, unsigned int));
 
 void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f);
 
diff --git a/include/media/videobuf-vmalloc.h b/include/media/videobuf-vmalloc.h
index e87222c..4b419a257 100644
--- a/include/media/videobuf-vmalloc.h
+++ b/include/media/videobuf-vmalloc.h
@@ -30,8 +30,8 @@
 };
 
 void videobuf_queue_vmalloc_init(struct videobuf_queue* q,
-			 struct videobuf_queue_ops *ops,
-			 void *dev,
+			 const struct videobuf_queue_ops *ops,
+			 struct device *dev,
 			 spinlock_t *irqlock,
 			 enum v4l2_buf_type type,
 			 enum v4l2_field field,
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 7571e32..ff30177 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -989,7 +989,7 @@
 	int init_sent_count;
 
 	/* state       : The current state of this destination,
-	 *             : i.e. SCTP_ACTIVE, SCTP_INACTIVE, SCTP_UNKOWN.
+	 *             : i.e. SCTP_ACTIVE, SCTP_INACTIVE, SCTP_UNKNOWN.
 	 */
 	int state;
 
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 0248c18..1b6f7d3 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1261,7 +1261,6 @@
 #define tcp_for_write_queue_from_safe(skb, tmp, sk)			\
 	skb_queue_walk_from_safe(&(sk)->sk_write_queue, skb, tmp)
 
-
 static inline struct sk_buff *tcp_send_head(struct sock *sk)
 {
 	return sk->sk_send_head;
diff --git a/include/net/wimax.h b/include/net/wimax.h
index d69c4a7..3461aa1 100644
--- a/include/net/wimax.h
+++ b/include/net/wimax.h
@@ -79,7 +79,7 @@
  * drivers have to only report state changes due to external
  * conditions.
  *
- * All API operations are 'atomic', serialized thorough a mutex in the
+ * All API operations are 'atomic', serialized through a mutex in the
  * `struct wimax_dev`.
  *
  * EXPORTING TO USER SPACE THROUGH GENERIC NETLINK
diff --git a/include/scsi/Kbuild b/include/scsi/Kbuild
index 33b2750..b3a0ee6 100644
--- a/include/scsi/Kbuild
+++ b/include/scsi/Kbuild
@@ -2,3 +2,4 @@
 header-y += scsi_netlink.h
 header-y += scsi_netlink_fc.h
 header-y += scsi_bsg_fc.h
+header-y += fc/
diff --git a/include/scsi/fc/Kbuild b/include/scsi/fc/Kbuild
new file mode 100644
index 0000000..5660381
--- /dev/null
+++ b/include/scsi/fc/Kbuild
@@ -0,0 +1,4 @@
+header-y += fc_els.h
+header-y += fc_fs.h
+header-y += fc_gs.h
+header-y += fc_ns.h
diff --git a/include/scsi/fc/fc_els.h b/include/scsi/fc/fc_els.h
index 195ca01..f943281 100644
--- a/include/scsi/fc/fc_els.h
+++ b/include/scsi/fc/fc_els.h
@@ -20,6 +20,8 @@
 #ifndef _FC_ELS_H_
 #define	_FC_ELS_H_
 
+#include <linux/types.h>
+
 /*
  * Fibre Channel Switch - Enhanced Link Services definitions.
  * From T11 FC-LS Rev 1.2 June 7, 2005.
@@ -248,10 +250,12 @@
 /*
  * sp_features
  */
-#define	FC_SP_FT_CIRO	0x8000	/* continuously increasing rel. off. */
+#define	FC_SP_FT_NPIV	0x8000	/* multiple N_Port_ID support (FLOGI) */
+#define	FC_SP_FT_CIRO	0x8000	/* continuously increasing rel off (PLOGI) */
 #define	FC_SP_FT_CLAD	0x8000	/* clean address (in FLOGI LS_ACC) */
 #define	FC_SP_FT_RAND	0x4000	/* random relative offset */
 #define	FC_SP_FT_VAL	0x2000	/* valid vendor version level */
+#define	FC_SP_FT_NPIV_ACC	0x2000	/* NPIV assignment (FLOGI LS_ACC) */
 #define	FC_SP_FT_FPORT	0x1000	/* F port (1) vs. N port (0) */
 #define	FC_SP_FT_ABB	0x0800	/* alternate BB_credit management */
 #define	FC_SP_FT_EDTR	0x0400	/* E_D_TOV Resolution is nanoseconds */
diff --git a/include/scsi/fc/fc_fcoe.h b/include/scsi/fc/fc_fcoe.h
index ccb3dbe..e6ad3d2 100644
--- a/include/scsi/fc/fc_fcoe.h
+++ b/include/scsi/fc/fc_fcoe.h
@@ -86,6 +86,18 @@
 #define FCOE_MIN_FRAME 46
 
 /*
+ * FCoE Link Error Status Block: T11 FC-BB-5 Rev2.0, Clause 7.10.
+ */
+struct fcoe_fc_els_lesb {
+	__be32		lesb_link_fail;	/* link failure count */
+	__be32		lesb_vlink_fail; /* virtual link failure count */
+	__be32		lesb_miss_fka;	/* missing FIP keep-alive count */
+	__be32		lesb_symb_err;	/* symbol error during carrier count */
+	__be32		lesb_err_block;	/* errored block count */
+	__be32		lesb_fcs_error; /* frame check sequence error count */
+};
+
+/*
  * fc_fcoe_set_mac - Store OUI + DID into MAC address field.
  * @mac: mac address to be set
  * @did: fc dest id to use
diff --git a/include/scsi/fc/fc_fcp.h b/include/scsi/fc/fc_fcp.h
index 5d38f19..747e2c7 100644
--- a/include/scsi/fc/fc_fcp.h
+++ b/include/scsi/fc/fc_fcp.h
@@ -83,6 +83,8 @@
  * fc_tm_flags - task management flags field.
  */
 #define	FCP_TMF_CLR_ACA		0x40	/* clear ACA condition */
+#define	FCP_TMF_TGT_RESET	0x20	/* target reset task management,
+					   deprecated as of FCP-3 */
 #define	FCP_TMF_LUN_RESET	0x10	/* logical unit reset task management */
 #define	FCP_TMF_CLR_TASK_SET	0x04	/* clear task set */
 #define	FCP_TMF_ABT_TASK_SET	0x02	/* abort task set */
@@ -196,4 +198,10 @@
 	__u8		srr_resvd2[3];	/* reserved */
 };
 
+/*
+ * Feature bits in name server FC-4 Features object.
+ */
+#define	FCP_FEAT_TARG	(1 << 0)	/* target function supported */
+#define	FCP_FEAT_INIT	(1 << 1)	/* initiator function supported */
+
 #endif /* _FC_FCP_H_ */
diff --git a/include/scsi/fc/fc_fip.h b/include/scsi/fc/fc_fip.h
index 3d138c1..17baa19 100644
--- a/include/scsi/fc/fc_fip.h
+++ b/include/scsi/fc/fc_fip.h
@@ -214,11 +214,21 @@
  */
 struct fip_fka_desc {
 	struct fip_desc fd_desc;
-	__u8		fd_resvd[2];
+	__u8		fd_resvd;
+	__u8		fd_flags;	/* bit0 is fka disable flag */
 	__be32		fd_fka_period;	/* adv./keep-alive period in mS */
 } __attribute__((packed));
 
 /*
+ * flags for fip_fka_desc.fd_flags
+ */
+enum fip_fka_flags {
+	FIP_FKA_ADV_D =	0x01,		/* no need for FKA from ENode */
+};
+
+/* FIP_DT_FKA flags */
+
+/*
  * FIP_DT_VENDOR descriptor.
  */
 struct fip_vendor_desc {
diff --git a/include/scsi/fc/fc_fs.h b/include/scsi/fc/fc_fs.h
index ac4cd38..50f28b1 100644
--- a/include/scsi/fc/fc_fs.h
+++ b/include/scsi/fc/fc_fs.h
@@ -20,6 +20,8 @@
 #ifndef _FC_FS_H_
 #define _FC_FS_H_
 
+#include <linux/types.h>
+
 /*
  * Fibre Channel Framing and Signalling definitions.
  * From T11 FC-FS-2 Rev 0.90 - 9 August 2005.
diff --git a/include/scsi/fc/fc_gs.h b/include/scsi/fc/fc_gs.h
index 324dd0e..a37346d 100644
--- a/include/scsi/fc/fc_gs.h
+++ b/include/scsi/fc/fc_gs.h
@@ -20,6 +20,8 @@
 #ifndef _FC_GS_H_
 #define	_FC_GS_H_
 
+#include <linux/types.h>
+
 /*
  * Fibre Channel Services - Common Transport.
  * From T11.org FC-GS-2 Rev 5.3 November 1998.
diff --git a/include/scsi/fc/fc_ns.h b/include/scsi/fc/fc_ns.h
index 790d7b9..e7d3ac4 100644
--- a/include/scsi/fc/fc_ns.h
+++ b/include/scsi/fc/fc_ns.h
@@ -20,6 +20,8 @@
 #ifndef _FC_NS_H_
 #define	_FC_NS_H_
 
+#include <linux/types.h>
+
 /*
  * Fibre Channel Services - Name Service (dNS)
  * From T11.org FC-GS-2 Rev 5.3 November 1998.
@@ -44,9 +46,12 @@
 	FC_NS_GID_FT =	0x0171,		/* get IDs by FC4 type */
 	FC_NS_GPN_FT =	0x0172,		/* get port names by FC4 type */
 	FC_NS_GID_PT =	0x01a1,		/* get IDs by port type */
-	FC_NS_RFT_ID =	0x0217,		/* reg FC4 type for ID */
 	FC_NS_RPN_ID =	0x0212,		/* reg port name for ID */
 	FC_NS_RNN_ID =	0x0213,		/* reg node name for ID */
+	FC_NS_RFT_ID =	0x0217,		/* reg FC4 type for ID */
+	FC_NS_RSPN_ID =	0x0218,		/* reg symbolic port name */
+	FC_NS_RFF_ID =	0x021f,		/* reg FC4 Features for ID */
+	FC_NS_RSNN_NN =	0x0239,		/* reg symbolic node name */
 };
 
 /*
@@ -156,4 +161,32 @@
 	__be64		fr_wwn;		/* node name or port name */
 } __attribute__((__packed__));
 
+/*
+ * RSNN_NN request - register symbolic node name
+ */
+struct fc_ns_rsnn {
+	__be64		fr_wwn;		/* node name */
+	__u8		fr_name_len;
+	char		fr_name[];
+} __attribute__((__packed__));
+
+/*
+ * RSPN_ID request - register symbolic port name
+ */
+struct fc_ns_rspn {
+	struct fc_ns_fid fr_fid;	/* port ID object */
+	__u8		fr_name_len;
+	char		fr_name[];
+} __attribute__((__packed__));
+
+/*
+ * RFF_ID request - register FC-4 Features for ID.
+ */
+struct fc_ns_rff_id {
+	struct fc_ns_fid fr_fid;	/* port ID object */
+	__u8		fr_resvd[2];
+	__u8		fr_feat;	/* FC-4 Feature bits */
+	__u8		fr_type;	/* FC-4 type */
+} __attribute__((__packed__));
+
 #endif /* _FC_NS_H_ */
diff --git a/include/scsi/fc_encode.h b/include/scsi/fc_encode.h
index 27dad70..8eb0a0f 100644
--- a/include/scsi/fc_encode.h
+++ b/include/scsi/fc_encode.h
@@ -32,7 +32,10 @@
 		struct fc_ns_gid_ft gid;
 		struct fc_ns_rn_id  rn;
 		struct fc_ns_rft rft;
+		struct fc_ns_rff_id rff;
 		struct fc_ns_fid fid;
+		struct fc_ns_rsnn snn;
+		struct fc_ns_rspn spn;
 	} payload;
 };
 
@@ -109,6 +112,7 @@
 		      enum fc_fh_type *fh_type)
 {
 	struct fc_ct_req *ct;
+	size_t len;
 
 	switch (op) {
 	case FC_NS_GPN_FT:
@@ -128,12 +132,41 @@
 		ct->payload.rft.fts = lport->fcts;
 		break;
 
-	case FC_NS_RPN_ID:
+	case FC_NS_RFF_ID:
+		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rff_id));
+		hton24(ct->payload.rff.fr_fid.fp_fid,
+		       fc_host_port_id(lport->host));
+		ct->payload.rff.fr_type = FC_TYPE_FCP;
+		if (lport->service_params & FCP_SPPF_INIT_FCN)
+			ct->payload.rff.fr_feat = FCP_FEAT_INIT;
+		if (lport->service_params & FCP_SPPF_TARG_FCN)
+			ct->payload.rff.fr_feat |= FCP_FEAT_TARG;
+		break;
+
+	case FC_NS_RNN_ID:
 		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id));
 		hton24(ct->payload.rn.fr_fid.fp_fid,
 		       fc_host_port_id(lport->host));
-		ct->payload.rft.fts = lport->fcts;
-		put_unaligned_be64(lport->wwpn, &ct->payload.rn.fr_wwn);
+		put_unaligned_be64(lport->wwnn, &ct->payload.rn.fr_wwn);
+		break;
+
+	case FC_NS_RSPN_ID:
+		len = strnlen(fc_host_symbolic_name(lport->host), 255);
+		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rspn) + len);
+		hton24(ct->payload.spn.fr_fid.fp_fid,
+		       fc_host_port_id(lport->host));
+		strncpy(ct->payload.spn.fr_name,
+			fc_host_symbolic_name(lport->host), len);
+		ct->payload.spn.fr_name_len = len;
+		break;
+
+	case FC_NS_RSNN_NN:
+		len = strnlen(fc_host_symbolic_name(lport->host), 255);
+		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rsnn) + len);
+		put_unaligned_be64(lport->wwnn, &ct->payload.snn.fr_wwn);
+		strncpy(ct->payload.snn.fr_name,
+			fc_host_symbolic_name(lport->host), len);
+		ct->payload.snn.fr_name_len = len;
 		break;
 
 	default:
@@ -198,6 +231,31 @@
 	sp->sp_bb_data = htons((u16) lport->mfs);
 	cp = &flogi->fl_cssp[3 - 1];	/* class 3 parameters */
 	cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
+	if (lport->does_npiv)
+		sp->sp_features = htons(FC_SP_FT_NPIV);
+}
+
+/**
+ * fc_fdisc_fill - Fill in a fdisc request frame.
+ */
+static inline void fc_fdisc_fill(struct fc_lport *lport, struct fc_frame *fp)
+{
+	struct fc_els_csp *sp;
+	struct fc_els_cssp *cp;
+	struct fc_els_flogi *fdisc;
+
+	fdisc = fc_frame_payload_get(fp, sizeof(*fdisc));
+	memset(fdisc, 0, sizeof(*fdisc));
+	fdisc->fl_cmd = (u8) ELS_FDISC;
+	put_unaligned_be64(lport->wwpn, &fdisc->fl_wwpn);
+	put_unaligned_be64(lport->wwnn, &fdisc->fl_wwnn);
+	sp = &fdisc->fl_csp;
+	sp->sp_hi_ver = 0x20;
+	sp->sp_lo_ver = 0x20;
+	sp->sp_bb_cred = htons(10);	/* this gets set by gateway */
+	sp->sp_bb_data = htons((u16) lport->mfs);
+	cp = &fdisc->fl_cssp[3 - 1];	/* class 3 parameters */
+	cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
 }
 
 /**
@@ -296,6 +354,10 @@
 		fc_flogi_fill(lport, fp);
 		break;
 
+	case ELS_FDISC:
+		fc_fdisc_fill(lport, fp);
+		break;
+
 	case ELS_LOGO:
 		fc_logo_fill(lport, fp);
 		break;
diff --git a/include/scsi/fc_frame.h b/include/scsi/fc_frame.h
index c35d238..4d3e9c7 100644
--- a/include/scsi/fc_frame.h
+++ b/include/scsi/fc_frame.h
@@ -28,6 +28,8 @@
 #include <scsi/fc/fc_fcp.h>
 #include <scsi/fc/fc_encaps.h>
 
+#include <linux/if_ether.h>
+
 /*
  * The fc_frame interface is used to pass frame data between functions.
  * The frame includes the data buffer, length, and SOF / EOF delimiter types.
@@ -37,6 +39,9 @@
 #define	FC_FRAME_HEADROOM	32	/* headroom for VLAN + FCoE headers */
 #define	FC_FRAME_TAILROOM	8	/* trailer space for FCoE */
 
+/* Max number of skb frags allowed, reserving one for fcoe_crc_eof page */
+#define FC_FRAME_SG_LEN		(MAX_SKB_FRAGS - 1)
+
 #define fp_skb(fp)	(&((fp)->skb))
 #define fr_hdr(fp)	((fp)->skb.data)
 #define fr_len(fp)	((fp)->skb.len)
@@ -64,6 +69,7 @@
 	enum fc_sof	fr_sof;		/* start of frame delimiter */
 	enum fc_eof	fr_eof;		/* end of frame delimiter */
 	u8		fr_flags;	/* flags - see below */
+	u8		granted_mac[ETH_ALEN]; /* FCoE MAC address */
 };
 
 
@@ -94,17 +100,7 @@
 }
 
 struct fc_frame *fc_frame_alloc_fill(struct fc_lport *, size_t payload_len);
-
-struct fc_frame *__fc_frame_alloc(size_t payload_len);
-
-/*
- * Get frame for sending via port.
- */
-static inline struct fc_frame *_fc_frame_alloc(struct fc_lport *dev,
-					       size_t payload_len)
-{
-	return __fc_frame_alloc(payload_len);
-}
+struct fc_frame *_fc_frame_alloc(size_t payload_len);
 
 /*
  * Allocate fc_frame structure and buffer.  Set the initial length to
@@ -118,10 +114,10 @@
 	 * Note: Since len will often be a constant multiple of 4,
 	 * this check will usually be evaluated and eliminated at compile time.
 	 */
-	if ((len % 4) != 0)
+	if (len && len % 4)
 		fp = fc_frame_alloc_fill(dev, len);
 	else
-		fp = _fc_frame_alloc(dev, len);
+		fp = _fc_frame_alloc(len);
 	return fp;
 }
 
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
index d67dda2..66d377b 100644
--- a/include/scsi/iscsi_if.h
+++ b/include/scsi/iscsi_if.h
@@ -311,6 +311,8 @@
 	ISCSI_PARAM_IFACE_NAME,
 	ISCSI_PARAM_ISID,
 	ISCSI_PARAM_INITIATOR_NAME,
+
+	ISCSI_PARAM_TGT_RESET_TMO,
 	/* must always be last */
 	ISCSI_PARAM_MAX,
 };
@@ -350,6 +352,7 @@
 #define ISCSI_IFACE_NAME		(1ULL << ISCSI_PARAM_IFACE_NAME)
 #define ISCSI_ISID			(1ULL << ISCSI_PARAM_ISID)
 #define ISCSI_INITIATOR_NAME		(1ULL << ISCSI_PARAM_INITIATOR_NAME)
+#define ISCSI_TGT_RESET_TMO		(1ULL << ISCSI_PARAM_TGT_RESET_TMO)
 
 /* iSCSI HBA params */
 enum iscsi_host_param {
diff --git a/include/scsi/iscsi_proto.h b/include/scsi/iscsi_proto.h
index f2a2c11..dd0a52c 100644
--- a/include/scsi/iscsi_proto.h
+++ b/include/scsi/iscsi_proto.h
@@ -279,6 +279,8 @@
 #define ISCSI_TM_FUNC_TARGET_COLD_RESET		7
 #define ISCSI_TM_FUNC_TASK_REASSIGN		8
 
+#define ISCSI_TM_FUNC_VALUE(hdr) ((hdr)->flags & ISCSI_FLAG_TM_FUNC_MASK)
+
 /* SCSI Task Management Response Header */
 struct iscsi_tm_rsp {
 	uint8_t opcode;
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index 65dc9aa..4b912ee 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -26,6 +26,7 @@
 
 #include <scsi/scsi_transport.h>
 #include <scsi/scsi_transport_fc.h>
+#include <scsi/scsi_bsg_fc.h>
 
 #include <scsi/fc/fc_fcp.h>
 #include <scsi/fc/fc_ns.h>
@@ -34,67 +35,6 @@
 
 #include <scsi/fc_frame.h>
 
-#define FC_LIBFC_LOGGING 0x01 /* General logging, not categorized */
-#define FC_LPORT_LOGGING 0x02 /* lport layer logging */
-#define FC_DISC_LOGGING  0x04 /* discovery layer logging */
-#define FC_RPORT_LOGGING 0x08 /* rport layer logging */
-#define FC_FCP_LOGGING   0x10 /* I/O path logging */
-#define FC_EM_LOGGING    0x20 /* Exchange Manager logging */
-#define FC_EXCH_LOGGING  0x40 /* Exchange/Sequence logging */
-#define FC_SCSI_LOGGING  0x80 /* SCSI logging (mostly error handling) */
-
-extern unsigned int fc_debug_logging;
-
-#define FC_CHECK_LOGGING(LEVEL, CMD)				\
-do {								\
-	if (unlikely(fc_debug_logging & LEVEL))			\
-		do {						\
-			CMD;					\
-		} while (0);					\
-} while (0)
-
-#define FC_LIBFC_DBG(fmt, args...)					\
-	FC_CHECK_LOGGING(FC_LIBFC_LOGGING,				\
-			 printk(KERN_INFO "libfc: " fmt, ##args))
-
-#define FC_LPORT_DBG(lport, fmt, args...)				\
-	FC_CHECK_LOGGING(FC_LPORT_LOGGING,				\
-			 printk(KERN_INFO "host%u: lport %6x: " fmt,	\
-				(lport)->host->host_no,			\
-				fc_host_port_id((lport)->host), ##args))
-
-#define FC_DISC_DBG(disc, fmt, args...)					\
-	FC_CHECK_LOGGING(FC_DISC_LOGGING,				\
-			 printk(KERN_INFO "host%u: disc: " fmt,		\
-				(disc)->lport->host->host_no,		\
-				##args))
-
-#define FC_RPORT_ID_DBG(lport, port_id, fmt, args...)			\
-	FC_CHECK_LOGGING(FC_RPORT_LOGGING,				\
-			 printk(KERN_INFO "host%u: rport %6x: " fmt,	\
-				(lport)->host->host_no,			\
-				(port_id), ##args))
-
-#define FC_RPORT_DBG(rdata, fmt, args...)				\
-	FC_RPORT_ID_DBG((rdata)->local_port, (rdata)->ids.port_id, fmt, ##args)
-
-#define FC_FCP_DBG(pkt, fmt, args...)					\
-	FC_CHECK_LOGGING(FC_FCP_LOGGING,				\
-			 printk(KERN_INFO "host%u: fcp: %6x: " fmt,	\
-				(pkt)->lp->host->host_no,		\
-				pkt->rport->port_id, ##args))
-
-#define FC_EXCH_DBG(exch, fmt, args...)					\
-	FC_CHECK_LOGGING(FC_EXCH_LOGGING,				\
-			 printk(KERN_INFO "host%u: xid %4x: " fmt,	\
-				(exch)->lp->host->host_no,		\
-				exch->xid, ##args))
-
-#define FC_SCSI_DBG(lport, fmt, args...)				\
-	FC_CHECK_LOGGING(FC_SCSI_LOGGING,                               \
-			 printk(KERN_INFO "host%u: scsi: " fmt,		\
-				(lport)->host->host_no,	##args))
-
 /*
  * libfc error codes
  */
@@ -115,15 +55,28 @@
 		p[2] = ((v) & 0xFF);		\
 	} while (0)
 
-/*
- * FC HBA status
+/**
+ * enum fc_lport_state - Local port states
+ * @LPORT_ST_DISABLED: Disabled
+ * @LPORT_ST_FLOGI:    Fabric login (FLOGI) sent
+ * @LPORT_ST_DNS:      Waiting for name server remote port to become ready
+ * @LPORT_ST_RPN_ID:   Register port name by ID (RPN_ID) sent
+ * @LPORT_ST_RFT_ID:   Register Fibre Channel types by ID (RFT_ID) sent
+ * @LPORT_ST_RFF_ID:   Register FC-4 Features by ID (RFF_ID) sent
+ * @LPORT_ST_SCR:      State Change Register (SCR) sent
+ * @LPORT_ST_READY:    Ready for use
+ * @LPORT_ST_LOGO:     Local port logout (LOGO) sent
+ * @LPORT_ST_RESET:    Local port reset
  */
 enum fc_lport_state {
 	LPORT_ST_DISABLED = 0,
 	LPORT_ST_FLOGI,
 	LPORT_ST_DNS,
-	LPORT_ST_RPN_ID,
+	LPORT_ST_RNN_ID,
+	LPORT_ST_RSNN_NN,
+	LPORT_ST_RSPN_ID,
 	LPORT_ST_RFT_ID,
+	LPORT_ST_RFF_ID,
 	LPORT_ST_SCR,
 	LPORT_ST_READY,
 	LPORT_ST_LOGO,
@@ -136,15 +89,28 @@
 	DISC_EV_FAILED
 };
 
+/**
+ * enum fc_rport_state - Remote port states
+ * @RPORT_ST_INIT:    Initialized
+ * @RPORT_ST_PLOGI:   Waiting for PLOGI completion
+ * @RPORT_ST_PRLI:    Waiting for PRLI completion
+ * @RPORT_ST_RTV:     Waiting for RTV completion
+ * @RPORT_ST_READY:   Ready for use
+ * @RPORT_ST_LOGO:    Remote port logout (LOGO) sent
+ * @RPORT_ST_ADISC:   Discover Address sent
+ * @RPORT_ST_DELETE:  Remote port being deleted
+ * @RPORT_ST_RESTART: Remote port being deleted and will restart
+*/
 enum fc_rport_state {
-	RPORT_ST_INIT,		/* initialized */
-	RPORT_ST_PLOGI,		/* waiting for PLOGI completion */
-	RPORT_ST_PRLI,		/* waiting for PRLI completion */
-	RPORT_ST_RTV,		/* waiting for RTV completion */
-	RPORT_ST_READY,		/* ready for use */
-	RPORT_ST_LOGO,		/* port logout sent */
-	RPORT_ST_ADISC,		/* Discover Address sent */
-	RPORT_ST_DELETE,	/* port being deleted */
+	RPORT_ST_INIT,
+	RPORT_ST_PLOGI,
+	RPORT_ST_PRLI,
+	RPORT_ST_RTV,
+	RPORT_ST_READY,
+	RPORT_ST_LOGO,
+	RPORT_ST_ADISC,
+	RPORT_ST_DELETE,
+	RPORT_ST_RESTART,
 };
 
 /**
@@ -155,12 +121,20 @@
  * @port_id:    Port ID of the discovered port
  */
 struct fc_disc_port {
-	struct fc_lport             *lp;
-	struct list_head            peers;
-	struct work_struct	    rport_work;
-	u32                         port_id;
+	struct fc_lport    *lp;
+	struct list_head   peers;
+	struct work_struct rport_work;
+	u32                port_id;
 };
 
+/**
+ * enum fc_rport_event - Remote port events
+ * @RPORT_EV_NONE:   No event
+ * @RPORT_EV_READY:  Remote port is ready for use
+ * @RPORT_EV_FAILED: State machine failed, remote port is not ready
+ * @RPORT_EV_STOP:   Remote port has been stopped
+ * @RPORT_EV_LOGO:   Remote port logout (LOGO) sent
+ */
 enum fc_rport_event {
 	RPORT_EV_NONE = 0,
 	RPORT_EV_READY,
@@ -171,6 +145,10 @@
 
 struct fc_rport_priv;
 
+/**
+ * struct fc_rport_operations - Operations for a remote port
+ * @event_callback: Function to be called for remote port events
+ */
 struct fc_rport_operations {
 	void (*event_callback)(struct fc_lport *, struct fc_rport_priv *,
 			       enum fc_rport_event);
@@ -178,11 +156,11 @@
 
 /**
  * struct fc_rport_libfc_priv - libfc internal information about a remote port
- * @local_port: Fibre Channel host port instance
- * @rp_state: indicates READY for I/O or DELETE when blocked.
- * @flags: REC and RETRY supported flags
- * @e_d_tov: error detect timeout value (in msec)
- * @r_a_tov: resource allocation timeout value (in msec)
+ * @local_port: The associated local port
+ * @rp_state:   Indicates READY for I/O or DELETE when blocked
+ * @flags:      REC and RETRY supported flags
+ * @e_d_tov:    Error detect timeout value (in msec)
+ * @r_a_tov:    Resource allocation timeout value (in msec)
  */
 struct fc_rport_libfc_priv {
 	struct fc_lport		   *local_port;
@@ -195,47 +173,66 @@
 };
 
 /**
- * struct fc_rport_priv - libfc rport and discovery info about a remote port
- * @local_port: Fibre Channel host port instance
- * @rport: transport remote port
- * @kref: reference counter
- * @rp_state: state tracks progress of PLOGI, PRLI, and RTV exchanges
- * @ids: remote port identifiers and roles
- * @flags: REC and RETRY supported flags
- * @max_seq: maximum number of concurrent sequences
- * @disc_id: discovery identifier
- * @maxframe_size: maximum frame size
- * @retries: retry count in current state
- * @e_d_tov: error detect timeout value (in msec)
- * @r_a_tov: resource allocation timeout value (in msec)
- * @rp_mutex: mutex protects rport
- * @retry_work:
- * @event_callback: Callback for rport READY, FAILED or LOGO
+ * struct fc_rport_priv - libfc remote port and discovery info
+ * @local_port:     The associated local port
+ * @rport:          The FC transport remote port
+ * @kref:           Reference counter
+ * @rp_state:       Enumeration that tracks progress of PLOGI, PRLI,
+ *                  and RTV exchanges
+ * @ids:            The remote port identifiers and roles
+ * @flags:          REC and RETRY supported flags
+ * @max_seq:        Maximum number of concurrent sequences
+ * @disc_id:        The discovery identifier
+ * @maxframe_size:  The maximum frame size
+ * @retries:        The retry count for the current state
+ * @e_d_tov:        Error detect timeout value (in msec)
+ * @r_a_tov:        Resource allocation timeout value (in msec)
+ * @rp_mutex:       The mutex that protects the remote port
+ * @retry_work:     Handle for retries
+ * @event_callback: Callback when READY, FAILED or LOGO states complete
  */
 struct fc_rport_priv {
-	struct fc_lport		   *local_port;
-	struct fc_rport		   *rport;
-	struct kref		   kref;
-	enum fc_rport_state        rp_state;
+	struct fc_lport		    *local_port;
+	struct fc_rport		    *rport;
+	struct kref		    kref;
+	enum fc_rport_state         rp_state;
 	struct fc_rport_identifiers ids;
-	u16			   flags;
-	u16		           max_seq;
-	u16			   disc_id;
-	u16			   maxframe_size;
-	unsigned int	           retries;
-	unsigned int	           e_d_tov;
-	unsigned int	           r_a_tov;
-	struct mutex               rp_mutex;
-	struct delayed_work	   retry_work;
-	enum fc_rport_event        event;
-	struct fc_rport_operations *ops;
-	struct list_head           peers;
-	struct work_struct         event_work;
-	u32			   supported_classes;
+	u16			    flags;
+	u16		            max_seq;
+	u16			    disc_id;
+	u16			    maxframe_size;
+	unsigned int	            retries;
+	unsigned int	            e_d_tov;
+	unsigned int	            r_a_tov;
+	struct mutex                rp_mutex;
+	struct delayed_work	    retry_work;
+	enum fc_rport_event         event;
+	struct fc_rport_operations  *ops;
+	struct list_head            peers;
+	struct work_struct          event_work;
+	u32			    supported_classes;
 };
 
-/*
- * fcoe stats structure
+/**
+ * struct fcoe_dev_stats - fcoe stats structure
+ * @SecondsSinceLastReset: Seconds since the last reset
+ * @TxFrames:              Number of transmitted frames
+ * @TxWords:               Number of transmitted words
+ * @RxFrames:              Number of received frames
+ * @RxWords:               Number of received words
+ * @ErrorFrames:           Number of received error frames
+ * @DumpedFrames:          Number of dumped frames
+ * @LinkFailureCount:      Number of link failures
+ * @LossOfSignalCount:     Number for signal losses
+ * @InvalidTxWordCount:    Number of invalid transmitted words
+ * @InvalidCRCCount:       Number of invalid CRCs
+ * @InputRequests:         Number of input requests
+ * @OutputRequests:        Number of output requests
+ * @ControlRequests:       Number of control requests
+ * @InputMegabytes:        Number of received megabytes
+ * @OutputMegabytes:       Number of transmitted megabytes
+ * @VLinkFailureCount:     Number of virtual link failures
+ * @MissDiscAdvCount:      Number of missing FIP discovery advertisement
  */
 struct fcoe_dev_stats {
 	u64		SecondsSinceLastReset;
@@ -254,12 +251,17 @@
 	u64		ControlRequests;
 	u64		InputMegabytes;
 	u64		OutputMegabytes;
+	u64		VLinkFailureCount;
+	u64		MissDiscAdvCount;
 };
 
-/*
- * els data is used for passing ELS respone specific
- * data to send ELS response mainly using infomation
- * in exchange and sequence in EM layer.
+/**
+ * struct fc_seq_els_data - ELS data used for passing ELS specific responses
+ * @fp:     The ELS frame
+ * @reason: The reason for rejection
+ * @explan: The explaination of the rejection
+ *
+ * Mainly used by the exchange manager layer.
  */
 struct fc_seq_els_data {
 	struct fc_frame *fp;
@@ -267,77 +269,87 @@
 	enum fc_els_rjt_explan explan;
 };
 
-/*
- * FCP request structure, one for each scsi cmd request
+/**
+ * struct fc_fcp_pkt - FCP request structure (one for each scsi_cmnd request)
+ * @lp:              The associated local port
+ * @state:           The state of the I/O
+ * @tgt_flags:       Target's flags
+ * @ref_cnt:         Reference count
+ * @scsi_pkt_lock:   Lock to protect the SCSI packet (must be taken before the
+ *                   host_lock if both are to be held at the same time)
+ * @cmd:             The SCSI command (set and clear with the host_lock held)
+ * @list:            Tracks queued commands (accessed with the host_lock held)
+ * @timer:           The command timer
+ * @tm_done:         Completion indicator
+ * @wait_for_comp:   Indicator to wait for completion of the I/O (in jiffies)
+ * @start_time:      Timestamp indicating the start of the I/O (in jiffies)
+ * @end_time:        Timestamp indicating the end of the I/O (in jiffies)
+ * @last_pkt_time:   Timestamp of the last frame received (in jiffies)
+ * @data_len:        The length of the data
+ * @cdb_cmd:         The CDB command
+ * @xfer_len:        The transfer length
+ * @xfer_ddp:        Indicates if this transfer used DDP (XID of the exchange
+ *                   will be set here if DDP was setup)
+ * @xfer_contig_end: The offset into the buffer if the buffer is contiguous
+ *                   (Tx and Rx)
+ * @max_payload:     The maximum payload size (in bytes)
+ * @io_status:       SCSI result (upper 24 bits)
+ * @cdb_status:      CDB status
+ * @status_code:     FCP I/O status
+ * @scsi_comp_flags: Completion flags (bit 3 Underrun bit 2: overrun)
+ * @req_flags:       Request flags (bit 0: read bit:1 write)
+ * @scsi_resid:      SCSI residule length
+ * @rport:           The remote port that the SCSI command is targeted at
+ * @seq_ptr:         The sequence that will carry the SCSI command
+ * @recov_retry:     Number of recovery retries
+ * @recov_seq:       The sequence for REC or SRR
  */
 struct fc_fcp_pkt {
-	/*
-	 * housekeeping stuff
-	 */
-	struct fc_lport *lp;	/* handle to hba struct */
-	u16		state;		/* scsi_pkt state state */
-	u16		tgt_flags;	/* target flags	 */
-	atomic_t	ref_cnt;	/* fcp pkt ref count */
-	spinlock_t	scsi_pkt_lock;	/* Must be taken before the host lock
-					 * if both are held at the same time */
-	/*
-	 * SCSI I/O related stuff
-	 */
-	struct scsi_cmnd *cmd;		/* scsi command pointer. set/clear
-					 * under host lock */
-	struct list_head list;		/* tracks queued commands. access under
-					 * host lock */
-	/*
-	 * timeout related stuff
-	 */
-	struct timer_list timer;	/* command timer */
+	/* Housekeeping information */
+	struct fc_lport   *lp;
+	u16		  state;
+	u16		  tgt_flags;
+	atomic_t	  ref_cnt;
+	spinlock_t	  scsi_pkt_lock;
+
+	/* SCSI I/O related information */
+	struct scsi_cmnd  *cmd;
+	struct list_head  list;
+
+	/* Timeout related information */
+	struct timer_list timer;
 	struct completion tm_done;
-	int	wait_for_comp;
-	unsigned long	start_time;	/* start jiffie */
-	unsigned long	end_time;	/* end jiffie */
-	unsigned long	last_pkt_time;	 /* jiffies of last frame received */
+	int	          wait_for_comp;
+	unsigned long	  start_time;
+	unsigned long	  end_time;
+	unsigned long	  last_pkt_time;
 
-	/*
-	 * scsi cmd and data transfer information
-	 */
-	u32		data_len;
-	/*
-	 * transport related veriables
-	 */
-	struct fcp_cmnd cdb_cmd;
-	size_t		xfer_len;
-	u16		xfer_ddp;	/* this xfer is ddped */
-	u32		xfer_contig_end; /* offset of end of contiguous xfer */
-	u16		max_payload;	/* max payload size in bytes */
+	/* SCSI command and data transfer information */
+	u32		  data_len;
 
-	/*
-	 * scsi/fcp return status
-	 */
-	u32		io_status;	/* SCSI result upper 24 bits */
-	u8		cdb_status;
-	u8		status_code;	/* FCP I/O status */
-	/* bit 3 Underrun bit 2: overrun */
-	u8		scsi_comp_flags;
-	u32		req_flags;	/* bit 0: read bit:1 write */
-	u32		scsi_resid;	/* residule length */
+	/* Transport related veriables */
+	struct fcp_cmnd   cdb_cmd;
+	size_t		  xfer_len;
+	u16		  xfer_ddp;
+	u32		  xfer_contig_end;
+	u16		  max_payload;
 
-	struct fc_rport	*rport;		/* remote port pointer */
-	struct fc_seq	*seq_ptr;	/* current sequence pointer */
-	/*
-	 * Error Processing
-	 */
-	u8		recov_retry;	/* count of recovery retries */
-	struct fc_seq	*recov_seq;	/* sequence for REC or SRR */
+	/* SCSI/FCP return status */
+	u32		  io_status;
+	u8		  cdb_status;
+	u8		  status_code;
+	u8		  scsi_comp_flags;
+	u32		  req_flags;
+	u32		  scsi_resid;
+
+	/* Associated structures */
+	struct fc_rport	  *rport;
+	struct fc_seq	  *seq_ptr;
+
+	/* Error Processing information */
+	u8		  recov_retry;
+	struct fc_seq	  *recov_seq;
 };
-/*
- * FC_FCP HELPER FUNCTIONS
- *****************************/
-static inline bool fc_fcp_is_read(const struct fc_fcp_pkt *fsp)
-{
-	if (fsp && fsp->cmd)
-		return fsp->cmd->sc_data_direction == DMA_FROM_DEVICE;
-	return false;
-}
 
 /*
  * Structure and function definitions for managing Fibre Channel Exchanges
@@ -350,23 +362,51 @@
 
 struct fc_exch_mgr;
 struct fc_exch_mgr_anchor;
-extern u16	fc_cpu_mask;	/* cpu mask for possible cpus */
+extern u16 fc_cpu_mask;	/* cpu mask for possible cpus */
 
-/*
- * Sequence.
+/**
+ * struct fc_seq - FC sequence
+ * @id:       The sequence ID
+ * @ssb_stat: Status flags for the sequence status block (SSB)
+ * @cnt:      Number of frames sent so far
+ * @rec_data: FC-4 value for REC
  */
 struct fc_seq {
-	u8	id;		/* seq ID */
-	u16	ssb_stat;	/* status flags for sequence status block */
-	u16	cnt;		/* frames sent so far on sequence */
-	u32	rec_data;	/* FC-4 value for REC */
+	u8  id;
+	u16 ssb_stat;
+	u16 cnt;
+	u32 rec_data;
 };
 
 #define FC_EX_DONE		(1 << 0) /* ep is completed */
 #define FC_EX_RST_CLEANUP	(1 << 1) /* reset is forcing completion */
 
-/*
- * Exchange.
+/**
+ * struct fc_exch - Fibre Channel Exchange
+ * @em:           Exchange manager
+ * @pool:         Exchange pool
+ * @state:        The exchange's state
+ * @xid:          The exchange ID
+ * @ex_list:      Handle used by the EM to track free exchanges
+ * @ex_lock:      Lock that protects the exchange
+ * @ex_refcnt:    Reference count
+ * @timeout_work: Handle for timeout handler
+ * @lp:           The local port that this exchange is on
+ * @oxid:         Originator's exchange ID
+ * @rxid:         Responder's exchange ID
+ * @oid:          Originator's FCID
+ * @sid:          Source FCID
+ * @did:          Destination FCID
+ * @esb_stat:     ESB exchange status
+ * @r_a_tov:      Resouce allocation time out value (in msecs)
+ * @seq_id:       The next sequence ID to use
+ * @f_ctl:        F_CTL flags for the sequence
+ * @fh_type:      The frame type
+ * @class:        The class of service
+ * @seq:          The sequence in use on this exchange
+ * @resp:         Callback for responses on this exchange
+ * @destructor:   Called when destroying the exchange
+ * @arg:          Passed as a void pointer to the resp() callback
  *
  * Locking notes: The ex_lock protects following items:
  *	state, esb_stat, f_ctl, seq.ssb_stat
@@ -374,76 +414,59 @@
  *	sequence allocation
  */
 struct fc_exch {
-	struct fc_exch_mgr *em;		/* exchange manager */
-	struct fc_exch_pool *pool;	/* per cpu exches pool */
-	u32		state;		/* internal driver state */
-	u16		xid;		/* our exchange ID */
-	struct list_head	ex_list;	/* free or busy list linkage */
-	spinlock_t	ex_lock;	/* lock covering exchange state */
-	atomic_t	ex_refcnt;	/* reference counter */
-	struct delayed_work timeout_work; /* timer for upper level protocols */
-	struct fc_lport	*lp;		/* fc device instance */
-	u16		oxid;		/* originator's exchange ID */
-	u16		rxid;		/* responder's exchange ID */
-	u32		oid;		/* originator's FCID */
-	u32		sid;		/* source FCID */
-	u32		did;		/* destination FCID */
-	u32		esb_stat;	/* exchange status for ESB */
-	u32		r_a_tov;	/* r_a_tov from rport (msec) */
-	u8		seq_id;		/* next sequence ID to use */
-	u32		f_ctl;		/* F_CTL flags for sequences */
-	u8		fh_type;	/* frame type */
-	enum fc_class	class;		/* class of service */
-	struct fc_seq	seq;		/* single sequence */
-	/*
-	 * Handler for responses to this current exchange.
-	 */
-	void		(*resp)(struct fc_seq *, struct fc_frame *, void *);
-	void		(*destructor)(struct fc_seq *, void *);
-	/*
-	 * arg is passed as void pointer to exchange
-	 * resp and destructor handlers
-	 */
-	void		*arg;
+	struct fc_exch_mgr  *em;
+	struct fc_exch_pool *pool;
+	u32		    state;
+	u16		    xid;
+	struct list_head    ex_list;
+	spinlock_t	    ex_lock;
+	atomic_t	    ex_refcnt;
+	struct delayed_work timeout_work;
+	struct fc_lport	    *lp;
+	u16		    oxid;
+	u16		    rxid;
+	u32		    oid;
+	u32		    sid;
+	u32		    did;
+	u32		    esb_stat;
+	u32		    r_a_tov;
+	u8		    seq_id;
+	u32		    f_ctl;
+	u8		    fh_type;
+	enum fc_class	    class;
+	struct fc_seq	    seq;
+
+	void		    (*resp)(struct fc_seq *, struct fc_frame *, void *);
+	void		    *arg;
+
+	void		    (*destructor)(struct fc_seq *, void *);
+
 };
 #define	fc_seq_exch(sp) container_of(sp, struct fc_exch, seq)
 
-struct libfc_function_template {
 
+struct libfc_function_template {
 	/*
 	 * Interface to send a FC frame
 	 *
 	 * STATUS: REQUIRED
 	 */
-	int (*frame_send)(struct fc_lport *lp, struct fc_frame *fp);
+	int (*frame_send)(struct fc_lport *, struct fc_frame *);
 
 	/*
 	 * Interface to send ELS/CT frames
 	 *
 	 * STATUS: OPTIONAL
 	 */
-	struct fc_seq *(*elsct_send)(struct fc_lport *lport,
-				     u32 did,
-				     struct fc_frame *fp,
-				     unsigned int op,
+	struct fc_seq *(*elsct_send)(struct fc_lport *, u32 did,
+				     struct fc_frame *, unsigned int op,
 				     void (*resp)(struct fc_seq *,
-					     struct fc_frame *fp,
-					     void *arg),
+					     struct fc_frame *, void *arg),
 				     void *arg, u32 timer_msec);
 
 	/*
 	 * Send the FC frame payload using a new exchange and sequence.
 	 *
-	 * The frame pointer with some of the header's fields must be
-	 * filled before calling exch_seq_send(), those fields are,
-	 *
-	 * - routing control
-	 * - FC port did
-	 * - FC port sid
-	 * - FC header type
-	 * - frame control
-	 * - parameter or relative offset
-	 *
 	 * The exchange response handler is set in this routine to resp()
 	 * function pointer. It can be called in two scenarios: if a timeout
 	 * occurs or if a response frame is received for the exchange. The
@@ -464,14 +487,13 @@
 	 *
 	 * STATUS: OPTIONAL
 	 */
-	struct fc_seq *(*exch_seq_send)(struct fc_lport *lp,
-					struct fc_frame *fp,
-					void (*resp)(struct fc_seq *sp,
-						     struct fc_frame *fp,
-						     void *arg),
-					void (*destructor)(struct fc_seq *sp,
-							   void *arg),
-					void *arg, unsigned int timer_msec);
+	struct fc_seq *(*exch_seq_send)(struct fc_lport *, struct fc_frame *,
+					void (*resp)(struct fc_seq *,
+						     struct fc_frame *,
+						     void *),
+					void (*destructor)(struct fc_seq *,
+							   void *),
+					void *, unsigned int timer_msec);
 
 	/*
 	 * Sets up the DDP context for a given exchange id on the given
@@ -479,22 +501,28 @@
 	 *
 	 * STATUS: OPTIONAL
 	 */
-	int (*ddp_setup)(struct fc_lport *lp, u16 xid,
-			 struct scatterlist *sgl, unsigned int sgc);
+	int (*ddp_setup)(struct fc_lport *, u16, struct scatterlist *,
+			 unsigned int);
 	/*
 	 * Completes the DDP transfer and returns the length of data DDPed
 	 * for the given exchange id.
 	 *
 	 * STATUS: OPTIONAL
 	 */
-	int (*ddp_done)(struct fc_lport *lp, u16 xid);
+	int (*ddp_done)(struct fc_lport *, u16);
+	/*
+	 * Allow LLD to fill its own Link Error Status Block
+	 *
+	 * STATUS: OPTIONAL
+	 */
+	void (*get_lesb)(struct fc_lport *, struct fc_els_lesb *lesb);
 	/*
 	 * Send a frame using an existing sequence and exchange.
 	 *
 	 * STATUS: OPTIONAL
 	 */
-	int (*seq_send)(struct fc_lport *lp, struct fc_seq *sp,
-			struct fc_frame *fp);
+	int (*seq_send)(struct fc_lport *, struct fc_seq *,
+			struct fc_frame *);
 
 	/*
 	 * Send an ELS response using infomation from a previous
@@ -502,8 +530,8 @@
 	 *
 	 * STATUS: OPTIONAL
 	 */
-	void (*seq_els_rsp_send)(struct fc_seq *sp, enum fc_els_cmd els_cmd,
-				 struct fc_seq_els_data *els_data);
+	void (*seq_els_rsp_send)(struct fc_seq *, enum fc_els_cmd,
+				 struct fc_seq_els_data *);
 
 	/*
 	 * Abort an exchange and sequence. Generally called because of a
@@ -515,7 +543,7 @@
 	 *
 	 * STATUS: OPTIONAL
 	 */
-	int (*seq_exch_abort)(const struct fc_seq *req_sp,
+	int (*seq_exch_abort)(const struct fc_seq *,
 			      unsigned int timer_msec);
 
 	/*
@@ -524,14 +552,14 @@
 	 *
 	 * STATUS: OPTIONAL
 	 */
-	void (*exch_done)(struct fc_seq *sp);
+	void (*exch_done)(struct fc_seq *);
 
 	/*
 	 * Start a new sequence on the same exchange/sequence tuple.
 	 *
 	 * STATUS: OPTIONAL
 	 */
-	struct fc_seq *(*seq_start_next)(struct fc_seq *sp);
+	struct fc_seq *(*seq_start_next)(struct fc_seq *);
 
 	/*
 	 * Reset an exchange manager, completing all sequences and exchanges.
@@ -540,8 +568,7 @@
 	 *
 	 * STATUS: OPTIONAL
 	 */
-	void (*exch_mgr_reset)(struct fc_lport *,
-			       u32 s_id, u32 d_id);
+	void (*exch_mgr_reset)(struct fc_lport *, u32 s_id, u32 d_id);
 
 	/*
 	 * Flush the rport work queue. Generally used before shutdown.
@@ -555,8 +582,8 @@
 	 *
 	 * STATUS: OPTIONAL
 	 */
-	void (*lport_recv)(struct fc_lport *lp, struct fc_seq *sp,
-			   struct fc_frame *fp);
+	void (*lport_recv)(struct fc_lport *, struct fc_seq *,
+			   struct fc_frame *);
 
 	/*
 	 * Reset the local port.
@@ -566,6 +593,26 @@
 	int (*lport_reset)(struct fc_lport *);
 
 	/*
+	 * Set the local port FC_ID.
+	 *
+	 * This may be provided by the LLD to allow it to be
+	 * notified when the local port is assigned a FC-ID.
+	 *
+	 * The frame, if non-NULL, is the incoming frame with the
+	 * FLOGI LS_ACC or FLOGI, and may contain the granted MAC
+	 * address for the LLD.  The frame pointer may be NULL if
+	 * no MAC is associated with this assignment (LOGO or PLOGI).
+	 *
+	 * If FC_ID is non-zero, r_a_tov and e_d_tov must be valid.
+	 *
+	 * Note: this is called with the local port mutex held.
+	 *
+	 * STATUS: OPTIONAL
+	 */
+	void (*lport_set_port_id)(struct fc_lport *, u32 port_id,
+				  struct fc_frame *);
+
+	/*
 	 * Create a remote port with a given port ID
 	 *
 	 * STATUS: OPTIONAL
@@ -622,31 +669,31 @@
 	 *
 	 * STATUS: OPTIONAL
 	 */
-	int (*fcp_cmd_send)(struct fc_lport *lp, struct fc_fcp_pkt *fsp,
-			    void (*resp)(struct fc_seq *, struct fc_frame *fp,
-					 void *arg));
+	int (*fcp_cmd_send)(struct fc_lport *, struct fc_fcp_pkt *,
+			    void (*resp)(struct fc_seq *, struct fc_frame *,
+					 void *));
 
 	/*
 	 * Cleanup the FCP layer, used durring link down and reset
 	 *
 	 * STATUS: OPTIONAL
 	 */
-	void (*fcp_cleanup)(struct fc_lport *lp);
+	void (*fcp_cleanup)(struct fc_lport *);
 
 	/*
 	 * Abort all I/O on a local port
 	 *
 	 * STATUS: OPTIONAL
 	 */
-	void (*fcp_abort_io)(struct fc_lport *lp);
+	void (*fcp_abort_io)(struct fc_lport *);
 
 	/*
 	 * Receive a request for the discovery layer.
 	 *
 	 * STATUS: OPTIONAL
 	 */
-	void (*disc_recv_req)(struct fc_seq *,
-			      struct fc_frame *, struct fc_lport *);
+	void (*disc_recv_req)(struct fc_seq *, struct fc_frame *,
+			      struct fc_lport *);
 
 	/*
 	 * Start discovery for a local port.
@@ -675,419 +722,340 @@
 	void (*disc_stop_final) (struct fc_lport *);
 };
 
-/* information used by the discovery layer */
+/**
+ * struct fc_disc - Discovery context
+ * @retry_count:   Number of retries
+ * @pending:       1 if discovery is pending, 0 if not
+ * @requesting:    1 if discovery has been requested, 0 if not
+ * @seq_count:     Number of sequences used for discovery
+ * @buf_len:       Length of the discovery buffer
+ * @disc_id:       Discovery ID
+ * @rports:        List of discovered remote ports
+ * @lport:         The local port that discovery is for
+ * @disc_mutex:    Mutex that protects the discovery context
+ * @partial_buf:   Partial name buffer (if names are returned
+ *                 in multiple frames)
+ * @disc_work:     handle for delayed work context
+ * @disc_callback: Callback routine called when discovery completes
+ */
 struct fc_disc {
-	unsigned char		retry_count;
-	unsigned char		pending;
-	unsigned char		requested;
-	unsigned short		seq_count;
-	unsigned char		buf_len;
-	u16			disc_id;
+	unsigned char         retry_count;
+	unsigned char         pending;
+	unsigned char         requested;
+	unsigned short        seq_count;
+	unsigned char         buf_len;
+	u16                   disc_id;
+
+	struct list_head      rports;
+	struct fc_lport	      *lport;
+	struct mutex	      disc_mutex;
+	struct fc_gpn_ft_resp partial_buf;
+	struct delayed_work   disc_work;
 
 	void (*disc_callback)(struct fc_lport *,
 			      enum fc_disc_event);
-
-	struct list_head	 rports;
-	struct fc_lport		*lport;
-	struct mutex		disc_mutex;
-	struct fc_gpn_ft_resp	partial_buf;	/* partial name buffer */
-	struct delayed_work	disc_work;
 };
 
+/**
+ * struct fc_lport - Local port
+ * @host:                  The SCSI host associated with a local port
+ * @ema_list:              Exchange manager anchor list
+ * @dns_rdata:             The directory server remote port
+ * @ptp_rdata:             Point to point remote port
+ * @scsi_priv:             FCP layer internal data
+ * @disc:                  Discovery context
+ * @vports:                Child vports if N_Port
+ * @vport:                 Parent vport if VN_Port
+ * @tt:                    Libfc function template
+ * @link_up:               Link state (1 = link up, 0 = link down)
+ * @qfull:                 Queue state (1 queue is full, 0 queue is not full)
+ * @state:                 Identifies the state
+ * @boot_time:             Timestamp indicating when the local port came online
+ * @host_stats:            SCSI host statistics
+ * @dev_stats:             FCoE device stats (TODO: libfc should not be
+ *                         FCoE aware)
+ * @retry_count:           Number of retries in the current state
+ * @wwpn:                  World Wide Port Name
+ * @wwnn:                  World Wide Node Name
+ * @service_params:        Common service parameters
+ * @e_d_tov:               Error detection timeout value
+ * @r_a_tov:               Resouce allocation timeout value
+ * @rnid_gen:              RNID information
+ * @sg_supp:               Indicates if scatter gather is supported
+ * @seq_offload:           Indicates if sequence offload is supported
+ * @crc_offload:           Indicates if CRC offload is supported
+ * @lro_enabled:           Indicates if large receive offload is supported
+ * @does_npiv:             Supports multiple vports
+ * @npiv_enabled:          Switch/fabric allows NPIV
+ * @mfs:                   The maximum Fibre Channel payload size
+ * @max_retry_count:       The maximum retry attempts
+ * @max_rport_retry_count: The maximum remote port retry attempts
+ * @lro_xid:               The maximum XID for LRO
+ * @lso_max:               The maximum large offload send size
+ * @fcts:                  FC-4 type mask
+ * @lp_mutex:              Mutex to protect the local port
+ * @list:                  Handle for list of local ports
+ * @retry_work:            Handle to local port for delayed retry context
+ */
 struct fc_lport {
-	struct list_head list;
-
 	/* Associations */
-	struct Scsi_Host	*host;
-	struct list_head	ema_list;
-	struct fc_rport_priv	*dns_rp;
-	struct fc_rport_priv	*ptp_rp;
-	void			*scsi_priv;
-	struct fc_disc          disc;
+	struct Scsi_Host	       *host;
+	struct list_head	       ema_list;
+	struct fc_rport_priv	       *dns_rdata;
+	struct fc_rport_priv	       *ptp_rdata;
+	void			       *scsi_priv;
+	struct fc_disc                 disc;
+
+	/* Virtual port information */
+	struct list_head	       vports;
+	struct fc_vport		       *vport;
 
 	/* Operational Information */
 	struct libfc_function_template tt;
-	u8			link_up;
-	u8			qfull;
-	enum fc_lport_state	state;
-	unsigned long		boot_time;
+	u8			       link_up;
+	u8			       qfull;
+	enum fc_lport_state	       state;
+	unsigned long		       boot_time;
+	struct fc_host_statistics      host_stats;
+	struct fcoe_dev_stats	       *dev_stats;
+	u8			       retry_count;
 
-	struct fc_host_statistics host_stats;
-	struct fcoe_dev_stats	*dev_stats;
-
-	u64			wwpn;
-	u64			wwnn;
-	u8			retry_count;
+	/* Fabric information */
+	u64			       wwpn;
+	u64			       wwnn;
+	unsigned int		       service_params;
+	unsigned int		       e_d_tov;
+	unsigned int		       r_a_tov;
+	struct fc_els_rnid_gen	       rnid_gen;
 
 	/* Capabilities */
-	u32			sg_supp:1;	/* scatter gather supported */
-	u32			seq_offload:1;	/* seq offload supported */
-	u32			crc_offload:1;	/* crc offload supported */
-	u32			lro_enabled:1;	/* large receive offload */
-	u32			mfs;	        /* max FC payload size */
-	unsigned int		service_params;
-	unsigned int		e_d_tov;
-	unsigned int		r_a_tov;
-	u8			max_retry_count;
-	u8			max_rport_retry_count;
-	u16			link_speed;
-	u16			link_supported_speeds;
-	u16			lro_xid;	/* max xid for fcoe lro */
-	unsigned int		lso_max;	/* max large send size */
-	struct fc_ns_fts	fcts;	        /* FC-4 type masks */
-	struct fc_els_rnid_gen	rnid_gen;	/* RNID information */
-
-	/* Semaphores */
-	struct mutex lp_mutex;
+	u32			       sg_supp:1;
+	u32			       seq_offload:1;
+	u32			       crc_offload:1;
+	u32			       lro_enabled:1;
+	u32			       does_npiv:1;
+	u32			       npiv_enabled:1;
+	u32			       mfs;
+	u8			       max_retry_count;
+	u8			       max_rport_retry_count;
+	u16			       link_speed;
+	u16			       link_supported_speeds;
+	u16			       lro_xid;
+	unsigned int		       lso_max;
+	struct fc_ns_fts	       fcts;
 
 	/* Miscellaneous */
-	struct delayed_work	retry_work;
-	struct delayed_work	disc_work;
+	struct mutex                   lp_mutex;
+	struct list_head               list;
+	struct delayed_work	       retry_work;
 };
 
 /*
  * FC_LPORT HELPER FUNCTIONS
  *****************************/
-static inline int fc_lport_test_ready(struct fc_lport *lp)
+
+/**
+ * fc_lport_test_ready() - Determine if a local port is in the READY state
+ * @lport: The local port to test
+ */
+static inline int fc_lport_test_ready(struct fc_lport *lport)
 {
-	return lp->state == LPORT_ST_READY;
+	return lport->state == LPORT_ST_READY;
 }
 
-static inline void fc_set_wwnn(struct fc_lport *lp, u64 wwnn)
+/**
+ * fc_set_wwnn() - Set the World Wide Node Name of a local port
+ * @lport: The local port whose WWNN is to be set
+ * @wwnn:  The new WWNN
+ */
+static inline void fc_set_wwnn(struct fc_lport *lport, u64 wwnn)
 {
-	lp->wwnn = wwnn;
+	lport->wwnn = wwnn;
 }
 
-static inline void fc_set_wwpn(struct fc_lport *lp, u64 wwnn)
+/**
+ * fc_set_wwpn() - Set the World Wide Port Name of a local port
+ * @lport: The local port whose WWPN is to be set
+ * @wwnn:  The new WWPN
+ */
+static inline void fc_set_wwpn(struct fc_lport *lport, u64 wwnn)
 {
-	lp->wwpn = wwnn;
+	lport->wwpn = wwnn;
 }
 
-static inline void fc_lport_state_enter(struct fc_lport *lp,
+/**
+ * fc_lport_state_enter() - Change a local port's state
+ * @lport: The local port whose state is to change
+ * @state: The new state
+ */
+static inline void fc_lport_state_enter(struct fc_lport *lport,
 					enum fc_lport_state state)
 {
-	if (state != lp->state)
-		lp->retry_count = 0;
-	lp->state = state;
+	if (state != lport->state)
+		lport->retry_count = 0;
+	lport->state = state;
 }
 
-static inline int fc_lport_init_stats(struct fc_lport *lp)
+/**
+ * fc_lport_init_stats() - Allocate per-CPU statistics for a local port
+ * @lport: The local port whose statistics are to be initialized
+ */
+static inline int fc_lport_init_stats(struct fc_lport *lport)
 {
-	/* allocate per cpu stats block */
-	lp->dev_stats = alloc_percpu(struct fcoe_dev_stats);
-	if (!lp->dev_stats)
+	lport->dev_stats = alloc_percpu(struct fcoe_dev_stats);
+	if (!lport->dev_stats)
 		return -ENOMEM;
 	return 0;
 }
 
-static inline void fc_lport_free_stats(struct fc_lport *lp)
+/**
+ * fc_lport_free_stats() - Free memory for a local port's statistics
+ * @lport: The local port whose statistics are to be freed
+ */
+static inline void fc_lport_free_stats(struct fc_lport *lport)
 {
-	free_percpu(lp->dev_stats);
-}
-
-static inline struct fcoe_dev_stats *fc_lport_get_stats(struct fc_lport *lp)
-{
-	return per_cpu_ptr(lp->dev_stats, smp_processor_id());
-}
-
-static inline void *lport_priv(const struct fc_lport *lp)
-{
-	return (void *)(lp + 1);
+	free_percpu(lport->dev_stats);
 }
 
 /**
- * libfc_host_alloc() - Allocate a Scsi_Host with room for the fc_lport
- * @sht: ptr to the scsi host templ
- * @priv_size: size of private data after fc_lport
- *
- * Returns: ptr to Scsi_Host
+ * fc_lport_get_stats() - Get a local port's statistics
+ * @lport: The local port whose statistics are to be retreived
  */
-static inline struct Scsi_Host *
+static inline struct fcoe_dev_stats *fc_lport_get_stats(struct fc_lport *lport)
+{
+	return per_cpu_ptr(lport->dev_stats, smp_processor_id());
+}
+
+/**
+ * lport_priv() - Return the private data from a local port
+ * @lport: The local port whose private data is to be retreived
+ */
+static inline void *lport_priv(const struct fc_lport *lport)
+{
+	return (void *)(lport + 1);
+}
+
+/**
+ * libfc_host_alloc() - Allocate a Scsi_Host with room for a local port and
+ *                      LLD private data
+ * @sht:       The SCSI host template
+ * @priv_size: Size of private data
+ *
+ * Returns: libfc lport
+ */
+static inline struct fc_lport *
 libfc_host_alloc(struct scsi_host_template *sht, int priv_size)
 {
-	return scsi_host_alloc(sht, sizeof(struct fc_lport) + priv_size);
+	struct fc_lport *lport;
+	struct Scsi_Host *shost;
+
+	shost = scsi_host_alloc(sht, sizeof(*lport) + priv_size);
+	if (!shost)
+		return NULL;
+	lport = shost_priv(shost);
+	lport->host = shost;
+	INIT_LIST_HEAD(&lport->ema_list);
+	INIT_LIST_HEAD(&lport->vports);
+	return lport;
+}
+
+/*
+ * FC_FCP HELPER FUNCTIONS
+ *****************************/
+static inline bool fc_fcp_is_read(const struct fc_fcp_pkt *fsp)
+{
+	if (fsp && fsp->cmd)
+		return fsp->cmd->sc_data_direction == DMA_FROM_DEVICE;
+	return false;
 }
 
 /*
  * LOCAL PORT LAYER
  *****************************/
-int fc_lport_init(struct fc_lport *lp);
-
-/*
- * Destroy the specified local port by finding and freeing all
- * fc_rports associated with it and then by freeing the fc_lport
- * itself.
- */
-int fc_lport_destroy(struct fc_lport *lp);
-
-/*
- * Logout the specified local port from the fabric
- */
-int fc_fabric_logoff(struct fc_lport *lp);
-
-/*
- * Initiate the LP state machine. This handler will use fc_host_attr
- * to store the FLOGI service parameters, so fc_host_attr must be
- * initialized before calling this handler.
- */
-int fc_fabric_login(struct fc_lport *lp);
-
-/*
- * The link is up for the given local port.
- */
+int fc_lport_init(struct fc_lport *);
+int fc_lport_destroy(struct fc_lport *);
+int fc_fabric_logoff(struct fc_lport *);
+int fc_fabric_login(struct fc_lport *);
+void __fc_linkup(struct fc_lport *);
 void fc_linkup(struct fc_lport *);
-
-/*
- * Link is down for the given local port.
- */
+void __fc_linkdown(struct fc_lport *);
 void fc_linkdown(struct fc_lport *);
-
-/*
- * Configure the local port.
- */
+void fc_vport_setlink(struct fc_lport *);
+void fc_vports_linkchange(struct fc_lport *);
 int fc_lport_config(struct fc_lport *);
-
-/*
- * Reset the local port.
- */
 int fc_lport_reset(struct fc_lport *);
-
-/*
- * Set the mfs or reset
- */
-int fc_set_mfs(struct fc_lport *lp, u32 mfs);
-
+int fc_set_mfs(struct fc_lport *, u32 mfs);
+struct fc_lport *libfc_vport_create(struct fc_vport *, int privsize);
+struct fc_lport *fc_vport_id_lookup(struct fc_lport *, u32 port_id);
+int fc_lport_bsg_request(struct fc_bsg_job *);
 
 /*
  * REMOTE PORT LAYER
  *****************************/
-int fc_rport_init(struct fc_lport *lp);
-void fc_rport_terminate_io(struct fc_rport *rp);
+int fc_rport_init(struct fc_lport *);
+void fc_rport_terminate_io(struct fc_rport *);
 
 /*
  * DISCOVERY LAYER
  *****************************/
-int fc_disc_init(struct fc_lport *lp);
-
+int fc_disc_init(struct fc_lport *);
 
 /*
- * SCSI LAYER
+ * FCP LAYER
  *****************************/
-/*
- * Initialize the SCSI block of libfc
- */
 int fc_fcp_init(struct fc_lport *);
-
-/*
- * This section provides an API which allows direct interaction
- * with the SCSI-ml. Each of these functions satisfies a function
- * pointer defined in Scsi_Host and therefore is always called
- * directly from the SCSI-ml.
- */
-int fc_queuecommand(struct scsi_cmnd *sc_cmd,
-		    void (*done)(struct scsi_cmnd *));
-
-/*
- * complete processing of a fcp packet
- *
- * This function may sleep if a fsp timer is pending.
- * The host lock must not be held by caller.
- */
-void fc_fcp_complete(struct fc_fcp_pkt *fsp);
-
-/*
- * Send an ABTS frame to the target device. The sc_cmd argument
- * is a pointer to the SCSI command to be aborted.
- */
-int fc_eh_abort(struct scsi_cmnd *sc_cmd);
-
-/*
- * Reset a LUN by sending send the tm cmd to the target.
- */
-int fc_eh_device_reset(struct scsi_cmnd *sc_cmd);
-
-/*
- * Reset the host adapter.
- */
-int fc_eh_host_reset(struct scsi_cmnd *sc_cmd);
-
-/*
- * Check rport status.
- */
-int fc_slave_alloc(struct scsi_device *sdev);
-
-/*
- * Adjust the queue depth.
- */
-int fc_change_queue_depth(struct scsi_device *sdev, int qdepth);
-
-/*
- * Change the tag type.
- */
-int fc_change_queue_type(struct scsi_device *sdev, int tag_type);
-
-/*
- * Free memory pools used by the FCP layer.
- */
 void fc_fcp_destroy(struct fc_lport *);
 
 /*
- * Set up direct-data placement for this I/O request
- */
-void fc_fcp_ddp_setup(struct fc_fcp_pkt *fsp, u16 xid);
+ * SCSI INTERACTION LAYER
+ *****************************/
+int fc_queuecommand(struct scsi_cmnd *,
+		    void (*done)(struct scsi_cmnd *));
+int fc_eh_abort(struct scsi_cmnd *);
+int fc_eh_device_reset(struct scsi_cmnd *);
+int fc_eh_host_reset(struct scsi_cmnd *);
+int fc_slave_alloc(struct scsi_device *);
+int fc_change_queue_depth(struct scsi_device *, int qdepth, int reason);
+int fc_change_queue_type(struct scsi_device *, int tag_type);
 
 /*
  * ELS/CT interface
  *****************************/
-/*
- * Initializes ELS/CT interface
- */
-int fc_elsct_init(struct fc_lport *lp);
+int fc_elsct_init(struct fc_lport *);
+struct fc_seq *fc_elsct_send(struct fc_lport *, u32 did,
+				    struct fc_frame *,
+				    unsigned int op,
+				    void (*resp)(struct fc_seq *,
+						 struct fc_frame *,
+						 void *arg),
+				    void *arg, u32 timer_msec);
+void fc_lport_flogi_resp(struct fc_seq *, struct fc_frame *, void *);
+void fc_lport_logo_resp(struct fc_seq *, struct fc_frame *, void *);
 
 
 /*
  * EXCHANGE MANAGER LAYER
  *****************************/
-/*
- * Initializes Exchange Manager related
- * function pointers in struct libfc_function_template.
- */
-int fc_exch_init(struct fc_lport *lp);
-
-/*
- * Adds Exchange Manager (EM) mp to lport.
- *
- * Adds specified mp to lport using struct fc_exch_mgr_anchor,
- * the struct fc_exch_mgr_anchor allows same EM sharing by
- * more than one lport with their specified match function,
- * the match function is used in allocating exchange from
- * added mp.
- */
-struct fc_exch_mgr_anchor *fc_exch_mgr_add(struct fc_lport *lport,
-					   struct fc_exch_mgr *mp,
+int fc_exch_init(struct fc_lport *);
+struct fc_exch_mgr_anchor *fc_exch_mgr_add(struct fc_lport *,
+					   struct fc_exch_mgr *,
 					   bool (*match)(struct fc_frame *));
-
-/*
- * Deletes Exchange Manager (EM) from lport by removing
- * its anchor ema from lport.
- *
- * If removed anchor ema was the last user of its associated EM
- * then also destroys associated EM.
- */
-void fc_exch_mgr_del(struct fc_exch_mgr_anchor *ema);
-
-/*
- * Allocates an Exchange Manager (EM).
- *
- * The EM manages exchanges for their allocation and
- * free, also allows exchange lookup for received
- * frame.
- *
- * The class is used for initializing FC class of
- * allocated exchange from EM.
- *
- * The min_xid and max_xid will limit new
- * exchange ID (XID) within this range for
- * a new exchange.
- * The LLD may choose to have multiple EMs,
- * e.g. one EM instance per CPU receive thread in LLD.
- *
- * Specified match function is used in allocating exchanges
- * from newly allocated EM.
- */
-struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
-				      enum fc_class class,
-				      u16 min_xid,
-				      u16 max_xid,
+void fc_exch_mgr_del(struct fc_exch_mgr_anchor *);
+int fc_exch_mgr_list_clone(struct fc_lport *src, struct fc_lport *dst);
+struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *, enum fc_class class,
+				      u16 min_xid, u16 max_xid,
 				      bool (*match)(struct fc_frame *));
-
-/*
- * Free all exchange managers of a lport.
- */
-void fc_exch_mgr_free(struct fc_lport *lport);
-
-/*
- * Receive a frame on specified local port and exchange manager.
- */
-void fc_exch_recv(struct fc_lport *lp, struct fc_frame *fp);
-
-/*
- * This function is for exch_seq_send function pointer in
- * struct libfc_function_template, see comment block on
- * exch_seq_send for description of this function.
- */
-struct fc_seq *fc_exch_seq_send(struct fc_lport *lp,
-				struct fc_frame *fp,
-				void (*resp)(struct fc_seq *sp,
-					     struct fc_frame *fp,
-					     void *arg),
-				void (*destructor)(struct fc_seq *sp,
-						   void *arg),
-				void *arg, u32 timer_msec);
-
-/*
- * send a frame using existing sequence and exchange.
- */
-int fc_seq_send(struct fc_lport *lp, struct fc_seq *sp, struct fc_frame *fp);
-
-/*
- * Send ELS response using mainly infomation
- * in exchange and sequence in EM layer.
- */
-void fc_seq_els_rsp_send(struct fc_seq *sp, enum fc_els_cmd els_cmd,
-			 struct fc_seq_els_data *els_data);
-
-/*
- * This function is for seq_exch_abort function pointer in
- * struct libfc_function_template, see comment block on
- * seq_exch_abort for description of this function.
- */
-int fc_seq_exch_abort(const struct fc_seq *req_sp, unsigned int timer_msec);
-
-/*
- * Indicate that an exchange/sequence tuple is complete and the memory
- * allocated for the related objects may be freed.
- */
-void fc_exch_done(struct fc_seq *sp);
-
-/*
- * Allocate a new exchange and sequence pair.
- */
-struct fc_exch *fc_exch_alloc(struct fc_lport *lport, struct fc_frame *fp);
-/*
- * Start a new sequence on the same exchange as the supplied sequence.
- */
-struct fc_seq *fc_seq_start_next(struct fc_seq *sp);
-
-
-/*
- * Reset all EMs of a lport, releasing its all sequences and
- * exchanges. If sid is non-zero, then reset only exchanges
- * we sourced from that FID. If did is non-zero, reset only
- * exchanges destined to that FID.
- */
+void fc_exch_mgr_free(struct fc_lport *);
+void fc_exch_recv(struct fc_lport *, struct fc_frame *);
 void fc_exch_mgr_reset(struct fc_lport *, u32 s_id, u32 d_id);
 
 /*
  * Functions for fc_functions_template
  */
-void fc_get_host_speed(struct Scsi_Host *shost);
-void fc_get_host_port_type(struct Scsi_Host *shost);
-void fc_get_host_port_state(struct Scsi_Host *shost);
-void fc_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout);
+void fc_get_host_speed(struct Scsi_Host *);
+void fc_get_host_port_type(struct Scsi_Host *);
+void fc_get_host_port_state(struct Scsi_Host *);
+void fc_set_rport_loss_tmo(struct fc_rport *, u32 timeout);
 struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *);
 
-/*
- * module setup functions.
- */
-int fc_setup_exch_mgr(void);
-void fc_destroy_exch_mgr(void);
-int fc_setup_rport(void);
-void fc_destroy_rport(void);
-
-/*
- * Internal libfc functions.
- */
-const char *fc_els_resp_type(struct fc_frame *);
-
 #endif /* _LIBFC_H_ */
diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h
index b241060..c603f4a 100644
--- a/include/scsi/libfcoe.h
+++ b/include/scsi/libfcoe.h
@@ -53,33 +53,36 @@
 };
 
 /**
- * struct fcoe_ctlr - FCoE Controller and FIP state.
- * @state:	internal FIP state for network link and FIP or non-FIP mode.
- * @lp:		&fc_lport: libfc local port.
- * @sel_fcf:	currently selected FCF, or NULL.
- * @fcfs:	list of discovered FCFs.
- * @fcf_count:	number of discovered FCF entries.
- * @sol_time:	time when a multicast solicitation was last sent.
- * @sel_time:	time after which to select an FCF.
- * @port_ka_time: time of next port keep-alive.
- * @ctlr_ka_time: time of next controller keep-alive.
- * @timer:	timer struct used for all delayed events.
- * @link_work:	&work_struct for doing FCF selection.
- * @recv_work:	&work_struct for receiving FIP frames.
+ * struct fcoe_ctlr - FCoE Controller and FIP state
+ * @state:	   internal FIP state for network link and FIP or non-FIP mode.
+ * @mode:	   LLD-selected mode.
+ * @lp:		   &fc_lport: libfc local port.
+ * @sel_fcf:	   currently selected FCF, or NULL.
+ * @fcfs:	   list of discovered FCFs.
+ * @fcf_count:	   number of discovered FCF entries.
+ * @sol_time:	   time when a multicast solicitation was last sent.
+ * @sel_time:	   time after which to select an FCF.
+ * @port_ka_time:  time of next port keep-alive.
+ * @ctlr_ka_time:  time of next controller keep-alive.
+ * @timer:	   timer struct used for all delayed events.
+ * @link_work:	   &work_struct for doing FCF selection.
+ * @recv_work:	   &work_struct for receiving FIP frames.
  * @fip_recv_list: list of received FIP frames.
- * @user_mfs:	configured maximum FC frame size, including FC header.
- * @flogi_oxid: exchange ID of most recent fabric login.
- * @flogi_count: number of FLOGI attempts in AUTO mode.
- * @link:	current link status for libfc.
- * @last_link:	last link state reported to libfc.
- * @map_dest:	use the FC_MAP mode for destination MAC addresses.
- * @spma:	supports SPMA server-provided MACs mode
- * @dest_addr:	MAC address of the selected FC forwarder.
- * @ctl_src_addr: the native MAC address of our local port.
- * @data_src_addr: the assigned MAC address for the local port after FLOGI.
- * @send:	LLD-supplied function to handle sending of FIP Ethernet frames.
- * @update_mac: LLD-supplied function to handle changes to MAC addresses.
- * @lock:	lock protecting this structure.
+ * @user_mfs:	   configured maximum FC frame size, including FC header.
+ * @flogi_oxid:    exchange ID of most recent fabric login.
+ * @flogi_count:   number of FLOGI attempts in AUTO mode.
+ * @link:	   current link status for libfc.
+ * @last_link:	   last link state reported to libfc.
+ * @map_dest:	   use the FC_MAP mode for destination MAC addresses.
+ * @spma:	   supports SPMA server-provided MACs mode
+ * @send_ctlr_ka:  need to send controller keep alive
+ * @send_port_ka:  need to send port keep alives
+ * @dest_addr:	   MAC address of the selected FC forwarder.
+ * @ctl_src_addr:  the native MAC address of our local port.
+ * @send:	   LLD-supplied function to handle sending FIP Ethernet frames
+ * @update_mac:    LLD-supplied function to handle changes to MAC addresses.
+ * @get_src_addr:  LLD-supplied function to supply a source MAC address.
+ * @lock:	   lock protecting this structure.
  *
  * This structure is used by all FCoE drivers.  It contains information
  * needed by all FCoE low-level drivers (LLDs) as well as internal state
@@ -87,6 +90,7 @@
  */
 struct fcoe_ctlr {
 	enum fip_state state;
+	enum fip_state mode;
 	struct fc_lport *lp;
 	struct fcoe_fcf *sel_fcf;
 	struct list_head fcfs;
@@ -104,29 +108,32 @@
 	u8 flogi_count;
 	u8 link;
 	u8 last_link;
+	u8 reset_req;
 	u8 map_dest;
 	u8 spma;
+	u8 send_ctlr_ka;
+	u8 send_port_ka;
 	u8 dest_addr[ETH_ALEN];
 	u8 ctl_src_addr[ETH_ALEN];
-	u8 data_src_addr[ETH_ALEN];
 
 	void (*send)(struct fcoe_ctlr *, struct sk_buff *);
-	void (*update_mac)(struct fcoe_ctlr *, u8 *old, u8 *new);
+	void (*update_mac)(struct fc_lport *, u8 *addr);
+	u8 * (*get_src_addr)(struct fc_lport *);
 	spinlock_t lock;
 };
 
-/*
- * struct fcoe_fcf - Fibre-Channel Forwarder.
- * @list:	list linkage.
- * @time:	system time (jiffies) when an advertisement was last received.
- * @switch_name: WWN of switch from advertisement.
- * @fabric_name: WWN of fabric from advertisement.
- * @fc_map:	FC_MAP value from advertisement.
- * @fcf_mac:	Ethernet address of the FCF.
- * @vfid:	virtual fabric ID.
- * @pri:	seletion priority, smaller values are better.
- * @flags:	flags received from advertisement.
- * @fka_period:	keep-alive period, in jiffies.
+/**
+ * struct fcoe_fcf - Fibre-Channel Forwarder
+ * @list:	 list linkage
+ * @time:	 system time (jiffies) when an advertisement was last received
+ * @switch_name: WWN of switch from advertisement
+ * @fabric_name: WWN of fabric from advertisement
+ * @fc_map:	 FC_MAP value from advertisement
+ * @fcf_mac:	 Ethernet address of the FCF
+ * @vfid:	 virtual fabric ID
+ * @pri:	 selection priority, smaller values are better
+ * @flags:	 flags received from advertisement
+ * @fka_period:	 keep-alive period, in jiffies
  *
  * A Fibre-Channel Forwarder (FCF) is the entity on the Ethernet that
  * passes FCoE frames on to an FC fabric.  This structure represents
@@ -148,6 +155,7 @@
 	u8 pri;
 	u16 flags;
 	u32 fka_period;
+	u8 fd_flags:1;
 };
 
 /* FIP API functions */
@@ -155,9 +163,10 @@
 void fcoe_ctlr_destroy(struct fcoe_ctlr *);
 void fcoe_ctlr_link_up(struct fcoe_ctlr *);
 int fcoe_ctlr_link_down(struct fcoe_ctlr *);
-int fcoe_ctlr_els_send(struct fcoe_ctlr *, struct sk_buff *);
+int fcoe_ctlr_els_send(struct fcoe_ctlr *, struct fc_lport *, struct sk_buff *);
 void fcoe_ctlr_recv(struct fcoe_ctlr *, struct sk_buff *);
-int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_frame *fp, u8 *sa);
+int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_lport *,
+			 struct fc_frame *);
 
 /* libfcoe funcs */
 u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int);
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index a72edd4..7394e3b 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -267,6 +267,7 @@
 	/* configuration */
 	int			abort_timeout;
 	int			lu_reset_timeout;
+	int			tgt_reset_timeout;
 	int			initial_r2t_en;
 	unsigned		max_r2t;
 	int			imm_data_en;
@@ -333,7 +334,8 @@
 /*
  * scsi host template
  */
-extern int iscsi_change_queue_depth(struct scsi_device *sdev, int depth);
+extern int iscsi_change_queue_depth(struct scsi_device *sdev, int depth,
+				    int reason);
 extern int iscsi_eh_abort(struct scsi_cmnd *sc);
 extern int iscsi_eh_target_reset(struct scsi_cmnd *sc);
 extern int iscsi_eh_device_reset(struct scsi_cmnd *sc);
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h
index e78d3b6..9eaa3f0 100644
--- a/include/scsi/libsas.h
+++ b/include/scsi/libsas.h
@@ -634,7 +634,8 @@
 extern int sas_slave_alloc(struct scsi_device *);
 extern int sas_slave_configure(struct scsi_device *);
 extern void sas_slave_destroy(struct scsi_device *);
-extern int sas_change_queue_depth(struct scsi_device *, int new_depth);
+extern int sas_change_queue_depth(struct scsi_device *, int new_depth,
+				  int reason);
 extern int sas_change_queue_type(struct scsi_device *, int qt);
 extern int sas_bios_param(struct scsi_device *,
 			  struct block_device *,
diff --git a/include/scsi/osd_initiator.h b/include/scsi/osd_initiator.h
index 02bd9f7..39d6d10 100644
--- a/include/scsi/osd_initiator.h
+++ b/include/scsi/osd_initiator.h
@@ -48,7 +48,6 @@
  */
 struct osd_dev {
 	struct scsi_device *scsi_device;
-	struct file *file;
 	unsigned def_timeout;
 
 #ifdef OSD_VER1_SUPPORT
@@ -56,10 +55,24 @@
 #endif
 };
 
-/* Retrieve/return osd_dev(s) for use by Kernel clients */
-struct osd_dev *osduld_path_lookup(const char *dev_name); /*Use IS_ERR/ERR_PTR*/
+/* Unique Identification of an OSD device */
+struct osd_dev_info {
+	unsigned systemid_len;
+	u8 systemid[OSD_SYSTEMID_LEN];
+	unsigned osdname_len;
+	u8 *osdname;
+};
+
+/* Retrieve/return osd_dev(s) for use by Kernel clients
+ * Use IS_ERR/ERR_PTR on returned "osd_dev *".
+ */
+struct osd_dev *osduld_path_lookup(const char *dev_name);
+struct osd_dev *osduld_info_lookup(const struct osd_dev_info *odi);
 void osduld_put_device(struct osd_dev *od);
 
+const struct osd_dev_info *osduld_device_info(struct osd_dev *od);
+bool osduld_device_same(struct osd_dev *od, const struct osd_dev_info *odi);
+
 /* Add/remove test ioctls from external modules */
 typedef int (do_test_fn)(struct osd_dev *od, unsigned cmd, unsigned long arg);
 int osduld_register_test(unsigned ioctl, do_test_fn *do_test);
@@ -69,8 +82,24 @@
 void osd_dev_init(struct osd_dev *od, struct scsi_device *scsi_device);
 void osd_dev_fini(struct osd_dev *od);
 
-/* some hi level device operations */
-int osd_auto_detect_ver(struct osd_dev *od, void *caps);    /* GFP_KERNEL */
+/**
+ * osd_auto_detect_ver - Detect the OSD version, return Unique Identification
+ *
+ * @od:     OSD target lun handle
+ * @caps:   Capabilities authorizing OSD root read attributes access
+ * @odi:    Retrieved information uniquely identifying the osd target lun
+ *          Note: odi->osdname must be kfreed by caller.
+ *
+ * Auto detects the OSD version of the OSD target and sets the @od
+ * accordingly. Meanwhile also returns the "system id" and "osd name" root
+ * attributes which uniquely identify the OSD target. This member is usually
+ * called by the ULD. ULD users should call osduld_device_info().
+ * This rutine allocates osd requests and memory at GFP_KERNEL level and might
+ * sleep.
+ */
+int osd_auto_detect_ver(struct osd_dev *od,
+	void *caps, struct osd_dev_info *odi);
+
 static inline struct request_queue *osd_request_queue(struct osd_dev *od)
 {
 	return od->scsi_device->request_queue;
@@ -84,6 +113,15 @@
 #endif
 }
 
+static inline bool osd_dev_is_ver1(struct osd_dev *od)
+{
+#ifdef OSD_VER1_SUPPORT
+	return od->version == OSD_VER1;
+#else
+	return false;
+#endif
+}
+
 struct osd_request;
 typedef void (osd_req_done_fn)(struct osd_request *or, void *private);
 
@@ -120,14 +158,9 @@
 	int async_error;
 };
 
-/* OSD Version control */
 static inline bool osd_req_is_ver1(struct osd_request *or)
 {
-#ifdef OSD_VER1_SUPPORT
-	return or->osd_dev->version == OSD_VER1;
-#else
-	return false;
-#endif
+	return osd_dev_is_ver1(or->osd_dev);
 }
 
 /*
@@ -234,7 +267,7 @@
  * @bad_attr_list - List of failing attributes (optional)
  * @max_attr      - Size of @bad_attr_list.
  *
- * After execution, sense + return code can be analyzed using this function. The
+ * After execution, osd_request results are analyzed using this function. The
  * return code is the final disposition on the error. So it is possible that a
  * CHECK_CONDITION was returned from target but this will return NO_ERROR, for
  * example on recovered errors. All parameters are optional if caller does
@@ -243,7 +276,31 @@
  * of the SCSI_OSD_DPRINT_SENSE Kconfig value. Set @silent if you know the
  * command would routinely fail, to not spam the dmsg file.
  */
+
+/**
+ * osd_err_priority - osd categorized return codes in ascending severity.
+ *
+ * The categories are borrowed from the pnfs_osd_errno enum.
+ * See comments for translated Linux codes returned by osd_req_decode_sense.
+ */
+enum osd_err_priority {
+	OSD_ERR_PRI_NO_ERROR	= 0,
+	/* Recoverable, caller should clear_highpage() all pages */
+	OSD_ERR_PRI_CLEAR_PAGES = 1, /* -EFAULT */
+	OSD_ERR_PRI_RESOURCE	= 2, /* -ENOMEM */
+	OSD_ERR_PRI_BAD_CRED	= 3, /* -EINVAL */
+	OSD_ERR_PRI_NO_ACCESS	= 4, /* -EACCES */
+	OSD_ERR_PRI_UNREACHABLE	= 5, /* any other */
+	OSD_ERR_PRI_NOT_FOUND	= 6, /* -ENOENT */
+	OSD_ERR_PRI_NO_SPACE	= 7, /* -ENOSPC */
+	OSD_ERR_PRI_EIO		= 8, /* -EIO    */
+};
+
 struct osd_sense_info {
+	u64 out_resid;		/* Zero on success otherwise out residual */
+	u64 in_resid;		/* Zero on success otherwise in residual */
+	enum osd_err_priority osd_err_pri;
+
 	int key;		/* one of enum scsi_sense_keys */
 	int additional_code ;	/* enum osd_additional_sense_codes */
 	union { /* Sense specific information */
diff --git a/include/scsi/osd_protocol.h b/include/scsi/osd_protocol.h
index 2cc8e8b..6856612 100644
--- a/include/scsi/osd_protocol.h
+++ b/include/scsi/osd_protocol.h
@@ -17,6 +17,7 @@
 #define __OSD_PROTOCOL_H__
 
 #include <linux/types.h>
+#include <linux/kernel.h>
 #include <asm/unaligned.h>
 #include <scsi/scsi.h>
 
diff --git a/include/scsi/osd_sense.h b/include/scsi/osd_sense.h
index ff9b33c..91db543 100644
--- a/include/scsi/osd_sense.h
+++ b/include/scsi/osd_sense.h
@@ -255,6 +255,9 @@
 	OSD_CFO_STARTING_BYTE	= OSD_CDB_OFFSET(v2.start_address),
 	OSD_CFO_PARTITION_ID	= OSD_CDB_OFFSET(partition),
 	OSD_CFO_OBJECT_ID	= OSD_CDB_OFFSET(object),
+	OSD_CFO_PERMISSIONS	= sizeof(struct osd_cdb_head) +
+					offsetof(struct osd_capability_head,
+						 permissions_bit_mask),
 };
 
 #endif /* ndef __OSD_SENSE_H__ */
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index 34c46ab..8b4deca 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -94,6 +94,7 @@
 #define WRITE_LONG            0x3f
 #define CHANGE_DEFINITION     0x40
 #define WRITE_SAME            0x41
+#define UNMAP		      0x42
 #define READ_TOC              0x43
 #define LOG_SELECT            0x4c
 #define LOG_SENSE             0x4d
@@ -122,9 +123,11 @@
 #define READ_16               0x88
 #define WRITE_16              0x8a
 #define VERIFY_16	      0x8f
+#define WRITE_SAME_16	      0x93
 #define SERVICE_ACTION_IN     0x9e
 /* values for service action in */
 #define	SAI_READ_CAPACITY_16  0x10
+#define SAI_GET_LBA_STATUS    0x12
 /* values for maintenance in */
 #define MI_REPORT_TARGET_PGS  0x0a
 /* values for maintenance out */
@@ -132,6 +135,7 @@
 /* values for variable length command */
 #define READ_32		      0x09
 #define WRITE_32	      0x0b
+#define WRITE_SAME_32	      0x0d
 
 /* Values for T10/04-262r7 */
 #define	ATA_16		      0x85	/* 16-byte pass-thru */
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index f097ae3..7c44499 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -81,11 +81,14 @@
 	struct list_head starved_entry;
 	struct scsi_cmnd *current_cmnd;	/* currently active command */
 	unsigned short queue_depth;	/* How deep of a queue we want */
+	unsigned short max_queue_depth;	/* max queue depth */
 	unsigned short last_queue_full_depth; /* These two are used by */
 	unsigned short last_queue_full_count; /* scsi_track_queue_full() */
-	unsigned long last_queue_full_time;/* don't let QUEUE_FULLs on the same
-					   jiffie count on our counter, they
-					   could all be from the same event. */
+	unsigned long last_queue_full_time;	/* last queue full time */
+	unsigned long queue_ramp_up_period;	/* ramp up period in jiffies */
+#define SCSI_DEFAULT_RAMP_UP_PERIOD	(120 * HZ)
+
+	unsigned long last_queue_ramp_up;	/* last queue ramp up time */
 
 	unsigned int id, lun, channel;
 
@@ -175,6 +178,7 @@
 	char *model;
 };
 
+typedef void (*activate_complete)(void *, int);
 struct scsi_device_handler {
 	/* Used by the infrastructure */
 	struct list_head list; /* list of scsi_device_handlers */
@@ -186,7 +190,7 @@
 	int (*check_sense)(struct scsi_device *, struct scsi_sense_hdr *);
 	int (*attach)(struct scsi_device *);
 	void (*detach)(struct scsi_device *);
-	int (*activate)(struct scsi_device *);
+	int (*activate)(struct scsi_device *, activate_complete, void *);
 	int (*prep_fn)(struct scsi_device *, struct request *);
 	int (*set_params)(struct scsi_device *, const char *);
 };
diff --git a/include/scsi/scsi_dh.h b/include/scsi/scsi_dh.h
index ff24074..e3f2db2 100644
--- a/include/scsi/scsi_dh.h
+++ b/include/scsi/scsi_dh.h
@@ -56,14 +56,16 @@
 	SCSI_DH_DRIVER_MAX,
 };
 #if defined(CONFIG_SCSI_DH) || defined(CONFIG_SCSI_DH_MODULE)
-extern int scsi_dh_activate(struct request_queue *);
+extern int scsi_dh_activate(struct request_queue *, activate_complete, void *);
 extern int scsi_dh_handler_exist(const char *);
 extern int scsi_dh_attach(struct request_queue *, const char *);
 extern void scsi_dh_detach(struct request_queue *);
 extern int scsi_dh_set_params(struct request_queue *, const char *);
 #else
-static inline int scsi_dh_activate(struct request_queue *req)
+static inline int scsi_dh_activate(struct request_queue *req,
+					activate_complete fn, void *data)
 {
+	fn(data, 0);
 	return 0;
 }
 static inline int scsi_dh_handler_exist(const char *name)
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 47941fc..c50a97f 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -43,6 +43,12 @@
 #define DISABLE_CLUSTERING 0
 #define ENABLE_CLUSTERING 1
 
+enum {
+	SCSI_QDEPTH_DEFAULT,	/* default requested change, e.g. from sysfs */
+	SCSI_QDEPTH_QFULL,	/* scsi-ml requested due to queue full */
+	SCSI_QDEPTH_RAMP_UP,	/* scsi-ml requested due to threshhold event */
+};
+
 struct scsi_host_template {
 	struct module *module;
 	const char *name;
@@ -294,7 +300,7 @@
 	 *
 	 * Status: OPTIONAL
 	 */
-	int (* change_queue_depth)(struct scsi_device *, int);
+	int (* change_queue_depth)(struct scsi_device *, int, int);
 
 	/*
 	 * Fill in this function to allow the changing of tag types
@@ -677,6 +683,12 @@
 	void *shost_data;
 
 	/*
+	 * Points to the physical bus device we'd use to do DMA
+	 * Needed just in case we have virtual hosts.
+	 */
+	struct device *dma_dev;
+
+	/*
 	 * We should ensure that this is aligned, both for better performance
 	 * and also because some compilers (m68k) don't automatically force
 	 * alignment to a long boundary.
@@ -720,7 +732,9 @@
 extern void scsi_flush_work(struct Scsi_Host *);
 
 extern struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *, int);
-extern int __must_check scsi_add_host(struct Scsi_Host *, struct device *);
+extern int __must_check scsi_add_host_with_dma(struct Scsi_Host *,
+					       struct device *,
+					       struct device *);
 extern void scsi_scan_host(struct Scsi_Host *);
 extern void scsi_rescan_device(struct device *);
 extern void scsi_remove_host(struct Scsi_Host *);
@@ -731,6 +745,12 @@
 
 extern u64 scsi_calculate_bounce_limit(struct Scsi_Host *);
 
+static inline int __must_check scsi_add_host(struct Scsi_Host *host,
+					     struct device *dev)
+{
+	return scsi_add_host_with_dma(host, dev, dev);
+}
+
 static inline struct device *scsi_get_device(struct Scsi_Host *shost)
 {
         return shost->shost_gendev.parent;
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index fc50bd6..8e86a94 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -807,5 +807,6 @@
 struct fc_vport *fc_vport_create(struct Scsi_Host *shost, int channel,
 		struct fc_vport_identifiers *);
 int fc_vport_terminate(struct fc_vport *vport);
+void fc_block_scsi_eh(struct scsi_cmnd *cmnd);
 
 #endif /* SCSI_TRANSPORT_FC_H */
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index 3dae3f7..4940045 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -593,7 +593,7 @@
 
 struct ac97_quirk {
 	unsigned short subvendor; /* PCI subsystem vendor id */
-	unsigned short subdevice; /* PCI sybsystem device id */
+	unsigned short subdevice; /* PCI subsystem device id */
 	unsigned short mask;	/* device id bit mask, 0 = accept all */
 	unsigned int codec_id;	/* codec id (if any), 0 = accept all */
 	const char *name;	/* name shown as info */
diff --git a/include/sound/wm8993.h b/include/sound/wm8993.h
index 9c661f2..eee19f6 100644
--- a/include/sound/wm8993.h
+++ b/include/sound/wm8993.h
@@ -36,7 +36,7 @@
 	unsigned int micbias1_lvl:1;
 	unsigned int micbias2_lvl:1;
 
-	/* Jack detect threashold levels, see datasheet for values */
+	/* Jack detect threshold levels, see datasheet for values */
 	unsigned int jd_scthr:2;
 	unsigned int jd_thr:2;
 };
diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
index 318f765..d0b6cd3 100644
--- a/include/trace/events/ext4.h
+++ b/include/trace/events/ext4.h
@@ -38,7 +38,7 @@
 		__entry->blocks	= inode->i_blocks;
 	),
 
-	TP_printk("dev %s ino %lu mode %d uid %u gid %u blocks %llu",
+	TP_printk("dev %s ino %lu mode 0%o uid %u gid %u blocks %llu",
 		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
 		  __entry->mode, __entry->uid, __entry->gid,
 		  (unsigned long long) __entry->blocks)
@@ -61,7 +61,7 @@
 		__entry->mode	= mode;
 	),
 
-	TP_printk("dev %s dir %lu mode %d",
+	TP_printk("dev %s dir %lu mode 0%o",
 		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->dir,
 		  __entry->mode)
 );
@@ -85,7 +85,7 @@
 		__entry->mode	= mode;
 	),
 
-	TP_printk("dev %s ino %lu dir %lu mode %d",
+	TP_printk("dev %s ino %lu dir %lu mode 0%o",
 		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
 		  (unsigned long) __entry->dir, __entry->mode)
 );
@@ -305,7 +305,6 @@
 		__field(	int,	ret			)
 		__field(	int,	pages_written		)
 		__field(	long,	pages_skipped		)
-		__field(	char,	encountered_congestion	)
 		__field(	char,	more_io			)	
 		__field(	char,	no_nrwrite_index_update )
 		__field(       pgoff_t,	writeback_index		)
@@ -317,17 +316,16 @@
 		__entry->ret		= ret;
 		__entry->pages_written	= pages_written;
 		__entry->pages_skipped	= wbc->pages_skipped;
-		__entry->encountered_congestion	= wbc->encountered_congestion;
 		__entry->more_io	= wbc->more_io;
 		__entry->no_nrwrite_index_update = wbc->no_nrwrite_index_update;
 		__entry->writeback_index = inode->i_mapping->writeback_index;
 	),
 
-	TP_printk("dev %s ino %lu ret %d pages_written %d pages_skipped %ld congestion %d more_io %d no_nrwrite_index_update %d writeback_index %lu",
+	TP_printk("dev %s ino %lu ret %d pages_written %d pages_skipped %ld more_io %d no_nrwrite_index_update %d writeback_index %lu",
 		  jbd2_dev_to_name(__entry->dev),
 		  (unsigned long) __entry->ino, __entry->ret,
 		  __entry->pages_written, __entry->pages_skipped,
-		  __entry->encountered_congestion, __entry->more_io,
+		  __entry->more_io,
 		  __entry->no_nrwrite_index_update,
 		  (unsigned long) __entry->writeback_index)
 );
@@ -591,30 +589,32 @@
 
 TRACE_EVENT(ext4_free_blocks,
 	TP_PROTO(struct inode *inode, __u64 block, unsigned long count,
-			int metadata),
+		 int flags),
 
-	TP_ARGS(inode, block, count, metadata),
+	TP_ARGS(inode, block, count, flags),
 
 	TP_STRUCT__entry(
 		__field(	dev_t,	dev			)
 		__field(	ino_t,	ino			)
+		__field(      umode_t, mode			)
 		__field(	__u64,	block			)
 		__field(	unsigned long,	count		)
-		__field(	int,	metadata		)
-
+		__field(	 int,	flags			)
 	),
 
 	TP_fast_assign(
 		__entry->dev		= inode->i_sb->s_dev;
 		__entry->ino		= inode->i_ino;
+		__entry->mode		= inode->i_mode;
 		__entry->block		= block;
 		__entry->count		= count;
-		__entry->metadata	= metadata;
+		__entry->flags		= flags;
 	),
 
-	TP_printk("dev %s ino %lu block %llu count %lu metadata %d",
+	TP_printk("dev %s ino %lu mode 0%o block %llu count %lu flags %d",
 		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
-		  __entry->block, __entry->count, __entry->metadata)
+		  __entry->mode, __entry->block, __entry->count,
+		  __entry->flags)
 );
 
 TRACE_EVENT(ext4_sync_file,
@@ -848,6 +848,32 @@
 		  __entry->result_len, __entry->result_logical)
 );
 
+TRACE_EVENT(ext4_forget,
+	TP_PROTO(struct inode *inode, int is_metadata, __u64 block),
+
+	TP_ARGS(inode, is_metadata, block),
+
+	TP_STRUCT__entry(
+		__field(	dev_t,	dev			)
+		__field(	ino_t,	ino			)
+		__field(	umode_t, mode			)
+		__field(	int,	is_metadata		)
+		__field(	__u64,	block			)
+	),
+
+	TP_fast_assign(
+		__entry->dev	= inode->i_sb->s_dev;
+		__entry->ino	= inode->i_ino;
+		__entry->mode	= inode->i_mode;
+		__entry->is_metadata = is_metadata;
+		__entry->block	= block;
+	),
+
+	TP_printk("dev %s ino %lu mode 0%o is_metadata %d block %llu",
+		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
+		  __entry->mode, __entry->is_metadata, __entry->block)
+);
+
 #endif /* _TRACE_EXT4_H */
 
 /* This part must be outside protection */
diff --git a/include/video/sgivw.h b/include/video/sgivw.h
index 55f2a7c..f6aa569 100644
--- a/include/video/sgivw.h
+++ b/include/video/sgivw.h
@@ -351,7 +351,7 @@
 struct dbe_timing_info
 {
   dbe_timing_t type;
-  int flags;				
+  int flags;
   short width;		    /* Monitor resolution		*/
   short height;
   int fields_sec;	    /* fields/sec  (Hz -3 dec. places */
@@ -389,11 +389,11 @@
   {
     DBE_VT_640_480_60,
     /*	flags,	width,			height,		fields_sec,		cfreq */
-    0,  	640,			480,		59940,			25175,
+    0,	        640,			480,		59940,			25175,
     /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    800,	640,		    800,		656,	    	752,
+    800,	640,		        800,		656,		752,
     /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    525,	480,		    525,		490,		    492,
+    525,	480,		        525,		490,		    492,
     /*	pll_m,	pll_n,			pll_p */
     15,	    2,				3
   },
@@ -650,7 +650,7 @@
     /* pll_m,  pll_n,          pll_p */
     6,      1,              0
   },
-	
+
   {
     DBE_VT_1920_1200_60,
     /* flags,  width,          height,         fields_sec,     cfreq */
@@ -676,7 +676,6 @@
   }
 };
 
-#define DBE_VT_SIZE  (sizeof(dbeVTimings)/sizeof(dbeVTimings[0]))
 #endif // INCLUDE_TIMING_TABLE_DATA
 
 #endif // ! __SGIVWFB_H__
diff --git a/include/xen/xen.h b/include/xen/xen.h
new file mode 100644
index 0000000..a164024
--- /dev/null
+++ b/include/xen/xen.h
@@ -0,0 +1,32 @@
+#ifndef _XEN_XEN_H
+#define _XEN_XEN_H
+
+enum xen_domain_type {
+	XEN_NATIVE,		/* running on bare hardware    */
+	XEN_PV_DOMAIN,		/* running in a PV domain      */
+	XEN_HVM_DOMAIN,		/* running in a Xen hvm domain */
+};
+
+#ifdef CONFIG_XEN
+extern enum xen_domain_type xen_domain_type;
+#else
+#define xen_domain_type		XEN_NATIVE
+#endif
+
+#define xen_domain()		(xen_domain_type != XEN_NATIVE)
+#define xen_pv_domain()		(xen_domain() &&			\
+				 xen_domain_type == XEN_PV_DOMAIN)
+#define xen_hvm_domain()	(xen_domain() &&			\
+				 xen_domain_type == XEN_HVM_DOMAIN)
+
+#ifdef CONFIG_XEN_DOM0
+#include <xen/interface/xen.h>
+#include <asm/xen/hypervisor.h>
+
+#define xen_initial_domain()	(xen_pv_domain() && \
+				 xen_start_info->flags & SIF_INITDOMAIN)
+#else  /* !CONFIG_XEN_DOM0 */
+#define xen_initial_domain()	(0)
+#endif	/* CONFIG_XEN_DOM0 */
+
+#endif	/* _XEN_XEN_H */
diff --git a/init/Kconfig b/init/Kconfig
index 3889924..54c655c 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -615,7 +615,7 @@
 	bool
 
 config SYSFS_DEPRECATED_V2
-	bool "enable deprecated sysfs features which may confuse old userspace tools"
+	bool "enable deprecated sysfs features to support old userspace tools"
 	depends on SYSFS
 	default n
 	select SYSFS_DEPRECATED
diff --git a/init/calibrate.c b/init/calibrate.c
index a379c90..6eb48e5 100644
--- a/init/calibrate.c
+++ b/init/calibrate.c
@@ -123,23 +123,26 @@
 {
 	unsigned long ticks, loopbit;
 	int lps_precision = LPS_PREC;
+	static bool printed;
 
 	if (preset_lpj) {
 		loops_per_jiffy = preset_lpj;
-		printk(KERN_INFO
-			"Calibrating delay loop (skipped) preset value.. ");
-	} else if ((smp_processor_id() == 0) && lpj_fine) {
+		if (!printed)
+			pr_info("Calibrating delay loop (skipped) "
+				"preset value.. ");
+	} else if ((!printed) && lpj_fine) {
 		loops_per_jiffy = lpj_fine;
-		printk(KERN_INFO
-			"Calibrating delay loop (skipped), "
+		pr_info("Calibrating delay loop (skipped), "
 			"value calculated using timer frequency.. ");
 	} else if ((loops_per_jiffy = calibrate_delay_direct()) != 0) {
-		printk(KERN_INFO
-			"Calibrating delay using timer specific routine.. ");
+		if (!printed)
+			pr_info("Calibrating delay using timer "
+				"specific routine.. ");
 	} else {
 		loops_per_jiffy = (1<<12);
 
-		printk(KERN_INFO "Calibrating delay loop... ");
+		if (!printed)
+			pr_info("Calibrating delay loop... ");
 		while ((loops_per_jiffy <<= 1) != 0) {
 			/* wait for "start of" clock tick */
 			ticks = jiffies;
@@ -170,7 +173,10 @@
 				loops_per_jiffy &= ~loopbit;
 		}
 	}
-	printk(KERN_CONT "%lu.%02lu BogoMIPS (lpj=%lu)\n",
+	if (!printed)
+		pr_cont("%lu.%02lu BogoMIPS (lpj=%lu)\n",
 			loops_per_jiffy/(500000/HZ),
 			(loops_per_jiffy/(5000/HZ)) % 100, loops_per_jiffy);
+
+	printed = true;
 }
diff --git a/ipc/msg.c b/ipc/msg.c
index 2ceab7f..085bd58 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -412,7 +412,7 @@
 		       struct msqid_ds __user *buf, int version)
 {
 	struct kern_ipc_perm *ipcp;
-	struct msqid64_ds msqid64;
+	struct msqid64_ds uninitialized_var(msqid64);
 	struct msg_queue *msq;
 	int err;
 
diff --git a/ipc/shm.c b/ipc/shm.c
index 464694e..11bec62 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -290,28 +290,28 @@
 	unsigned long flags)
 {
 	struct shm_file_data *sfd = shm_file_data(file);
-	return get_unmapped_area(sfd->file, addr, len, pgoff, flags);
-}
-
-int is_file_shm_hugepages(struct file *file)
-{
-	int ret = 0;
-
-	if (file->f_op == &shm_file_operations) {
-		struct shm_file_data *sfd;
-		sfd = shm_file_data(file);
-		ret = is_file_hugepages(sfd->file);
-	}
-	return ret;
+	return sfd->file->f_op->get_unmapped_area(sfd->file, addr, len,
+						pgoff, flags);
 }
 
 static const struct file_operations shm_file_operations = {
 	.mmap		= shm_mmap,
 	.fsync		= shm_fsync,
 	.release	= shm_release,
+};
+
+static const struct file_operations shm_file_operations_huge = {
+	.mmap		= shm_mmap,
+	.fsync		= shm_fsync,
+	.release	= shm_release,
 	.get_unmapped_area	= shm_get_unmapped_area,
 };
 
+int is_file_shm_hugepages(struct file *file)
+{
+	return file->f_op == &shm_file_operations_huge;
+}
+
 static const struct vm_operations_struct shm_vm_ops = {
 	.open	= shm_open,	/* callback for a new vm-area open */
 	.close	= shm_close,	/* callback for when the vm-area is released */
@@ -889,7 +889,10 @@
 	if (!sfd)
 		goto out_put_dentry;
 
-	file = alloc_file(path.mnt, path.dentry, f_mode, &shm_file_operations);
+	file = alloc_file(path.mnt, path.dentry, f_mode,
+			is_file_hugepages(shp->shm_file) ?
+				&shm_file_operations_huge :
+				&shm_file_operations);
 	if (!file)
 		goto out_free;
 	ima_counts_get(file);
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 6ba0f1e..7c4e271 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -392,10 +392,9 @@
 		if (cpu == first_cpu)
 			continue;
 		error = _cpu_down(cpu, 1);
-		if (!error) {
+		if (!error)
 			cpumask_set_cpu(cpu, frozen_cpus);
-			printk("CPU%d is down\n", cpu);
-		} else {
+		else {
 			printk(KERN_ERR "Error taking CPU%d down: %d\n",
 				cpu, error);
 			break;
diff --git a/kernel/exit.c b/kernel/exit.c
index 1143012..6f50ef5 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -971,7 +971,7 @@
 	exit_thread();
 	cgroup_exit(tsk, 1);
 
-	if (group_dead && tsk->signal->leader)
+	if (group_dead)
 		disassociate_ctty(1);
 
 	module_put(task_thread_info(tsk)->exec_domain->module);
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 3e1c36e..ede5277 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -1238,7 +1238,8 @@
 	force_clock_reprogram = 1;
 	dev->min_delta_ns = (unsigned long)try_time.tv64 * 3;
 	printk(KERN_WARNING "hrtimer: interrupt too slow, "
-		"forcing clock min delta to %lu ns\n", dev->min_delta_ns);
+	       "forcing clock min delta to %llu ns\n",
+	       (unsigned long long) dev->min_delta_ns);
 }
 /*
  * High resolution timer interrupt
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index bde4c66..7305b29 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1067,7 +1067,7 @@
 		kfree(action);
 
 #ifdef CONFIG_DEBUG_SHIRQ
-	if (irqflags & IRQF_SHARED) {
+	if (!retval && (irqflags & IRQF_SHARED)) {
 		/*
 		 * It's a shared IRQ -- the driver ought to be prepared for it
 		 * to happen immediately, so let's make sure....
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index 22b0a6e..e49ea1c 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -220,7 +220,7 @@
 		/*
 		 * If we are seeing only the odd spurious IRQ caused by
 		 * bus asynchronicity then don't eventually trigger an error,
-		 * otherwise the couter becomes a doomsday timer for otherwise
+		 * otherwise the counter becomes a doomsday timer for otherwise
 		 * working systems
 		 */
 		if (time_after(jiffies, desc->last_unhandled + HZ/10))
diff --git a/kernel/itimer.c b/kernel/itimer.c
index b03451e..d802883 100644
--- a/kernel/itimer.c
+++ b/kernel/itimer.c
@@ -146,6 +146,7 @@
 {
 	cputime_t cval, nval, cinterval, ninterval;
 	s64 ns_ninterval, ns_nval;
+	u32 error, incr_error;
 	struct cpu_itimer *it = &tsk->signal->it[clock_id];
 
 	nval = timeval_to_cputime(&value->it_value);
@@ -153,8 +154,8 @@
 	ninterval = timeval_to_cputime(&value->it_interval);
 	ns_ninterval = timeval_to_ns(&value->it_interval);
 
-	it->incr_error = cputime_sub_ns(ninterval, ns_ninterval);
-	it->error = cputime_sub_ns(nval, ns_nval);
+	error = cputime_sub_ns(nval, ns_nval);
+	incr_error = cputime_sub_ns(ninterval, ns_ninterval);
 
 	spin_lock_irq(&tsk->sighand->siglock);
 
@@ -168,6 +169,8 @@
 	}
 	it->expires = nval;
 	it->incr = ninterval;
+	it->error = error;
+	it->incr_error = incr_error;
 	trace_itimer_state(clock_id == CPUCLOCK_VIRT ?
 			   ITIMER_VIRTUAL : ITIMER_PROF, value, nval);
 
diff --git a/kernel/kgdb.c b/kernel/kgdb.c
index 7d70146..2eb517e 100644
--- a/kernel/kgdb.c
+++ b/kernel/kgdb.c
@@ -129,6 +129,7 @@
 struct task_struct		*kgdb_contthread;
 
 int				kgdb_single_step;
+pid_t				kgdb_sstep_pid;
 
 /* Our I/O buffers. */
 static char			remcom_in_buffer[BUFMAX];
@@ -541,12 +542,17 @@
 	 */
 	if (tid == 0 || tid == -1)
 		tid = -atomic_read(&kgdb_active) - 2;
-	if (tid < 0) {
+	if (tid < -1 && tid > -NR_CPUS - 2) {
 		if (kgdb_info[-tid - 2].task)
 			return kgdb_info[-tid - 2].task;
 		else
 			return idle_task(-tid - 2);
 	}
+	if (tid <= 0) {
+		printk(KERN_ERR "KGDB: Internal thread select error\n");
+		dump_stack();
+		return NULL;
+	}
 
 	/*
 	 * find_task_by_pid_ns() does not take the tasklist lock anymore
@@ -619,7 +625,8 @@
 static int kgdb_activate_sw_breakpoints(void)
 {
 	unsigned long addr;
-	int error = 0;
+	int error;
+	int ret = 0;
 	int i;
 
 	for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) {
@@ -629,13 +636,16 @@
 		addr = kgdb_break[i].bpt_addr;
 		error = kgdb_arch_set_breakpoint(addr,
 				kgdb_break[i].saved_instr);
-		if (error)
-			return error;
+		if (error) {
+			ret = error;
+			printk(KERN_INFO "KGDB: BP install failed: %lx", addr);
+			continue;
+		}
 
 		kgdb_flush_swbreak_addr(addr);
 		kgdb_break[i].state = BP_ACTIVE;
 	}
-	return 0;
+	return ret;
 }
 
 static int kgdb_set_sw_break(unsigned long addr)
@@ -682,7 +692,8 @@
 static int kgdb_deactivate_sw_breakpoints(void)
 {
 	unsigned long addr;
-	int error = 0;
+	int error;
+	int ret = 0;
 	int i;
 
 	for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) {
@@ -691,13 +702,15 @@
 		addr = kgdb_break[i].bpt_addr;
 		error = kgdb_arch_remove_breakpoint(addr,
 					kgdb_break[i].saved_instr);
-		if (error)
-			return error;
+		if (error) {
+			printk(KERN_INFO "KGDB: BP remove failed: %lx\n", addr);
+			ret = error;
+		}
 
 		kgdb_flush_swbreak_addr(addr);
 		kgdb_break[i].state = BP_SET;
 	}
-	return 0;
+	return ret;
 }
 
 static int kgdb_remove_sw_break(unsigned long addr)
@@ -1204,8 +1217,10 @@
 		return 1;
 
 	} else {
-		error_packet(remcom_out_buffer, -EINVAL);
-		return 0;
+		kgdb_msg_write("KGDB only knows signal 9 (pass)"
+			" and 15 (pass and disconnect)\n"
+			"Executing a continue without signal passing\n", 0);
+		remcom_in_buffer[0] = 'c';
 	}
 
 	/* Indicate fall through */
@@ -1395,6 +1410,7 @@
 	struct kgdb_state kgdb_var;
 	struct kgdb_state *ks = &kgdb_var;
 	unsigned long flags;
+	int sstep_tries = 100;
 	int error = 0;
 	int i, cpu;
 
@@ -1425,13 +1441,14 @@
 		cpu_relax();
 
 	/*
-	 * Do not start the debugger connection on this CPU if the last
-	 * instance of the exception handler wanted to come into the
-	 * debugger on a different CPU via a single step
+	 * For single stepping, try to only enter on the processor
+	 * that was single stepping.  To gaurd against a deadlock, the
+	 * kernel will only try for the value of sstep_tries before
+	 * giving up and continuing on.
 	 */
 	if (atomic_read(&kgdb_cpu_doing_single_step) != -1 &&
-	    atomic_read(&kgdb_cpu_doing_single_step) != cpu) {
-
+	    (kgdb_info[cpu].task &&
+	     kgdb_info[cpu].task->pid != kgdb_sstep_pid) && --sstep_tries) {
 		atomic_set(&kgdb_active, -1);
 		touch_softlockup_watchdog();
 		clocksource_touch_watchdog();
@@ -1524,6 +1541,13 @@
 	}
 
 kgdb_restore:
+	if (atomic_read(&kgdb_cpu_doing_single_step) != -1) {
+		int sstep_cpu = atomic_read(&kgdb_cpu_doing_single_step);
+		if (kgdb_info[sstep_cpu].task)
+			kgdb_sstep_pid = kgdb_info[sstep_cpu].task->pid;
+		else
+			kgdb_sstep_pid = 0;
+	}
 	/* Free kgdb_active */
 	atomic_set(&kgdb_active, -1);
 	touch_softlockup_watchdog();
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 6b7ddba..40a996e 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -476,7 +476,7 @@
 	if (!task) {
 		/*
 		 * Per cpu events are removed via an smp call and
-		 * the removal is always sucessful.
+		 * the removal is always successful.
 		 */
 		smp_call_function_single(event->cpu,
 					 __perf_event_remove_from_context,
@@ -845,7 +845,7 @@
 	if (!task) {
 		/*
 		 * Per cpu events are installed via an smp call and
-		 * the install is always sucessful.
+		 * the install is always successful.
 		 */
 		smp_call_function_single(cpu, __perf_install_in_context,
 					 event, 1);
diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c
index dfdec52..3db49b9 100644
--- a/kernel/pm_qos_params.c
+++ b/kernel/pm_qos_params.c
@@ -29,7 +29,6 @@
 
 #include <linux/pm_qos_params.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/time.h>
@@ -344,37 +343,33 @@
 }
 EXPORT_SYMBOL_GPL(pm_qos_remove_notifier);
 
-#define PID_NAME_LEN sizeof("process_1234567890")
-static char name[PID_NAME_LEN];
+#define PID_NAME_LEN 32
 
 static int pm_qos_power_open(struct inode *inode, struct file *filp)
 {
 	int ret;
 	long pm_qos_class;
+	char name[PID_NAME_LEN];
 
-	lock_kernel();
 	pm_qos_class = find_pm_qos_object_by_minor(iminor(inode));
 	if (pm_qos_class >= 0) {
 		filp->private_data = (void *)pm_qos_class;
-		sprintf(name, "process_%d", current->pid);
+		snprintf(name, PID_NAME_LEN, "process_%d", current->pid);
 		ret = pm_qos_add_requirement(pm_qos_class, name,
 					PM_QOS_DEFAULT_VALUE);
-		if (ret >= 0) {
-			unlock_kernel();
+		if (ret >= 0)
 			return 0;
-		}
 	}
-	unlock_kernel();
-
 	return -EPERM;
 }
 
 static int pm_qos_power_release(struct inode *inode, struct file *filp)
 {
 	int pm_qos_class;
+	char name[PID_NAME_LEN];
 
 	pm_qos_class = (long)filp->private_data;
-	sprintf(name, "process_%d", current->pid);
+	snprintf(name, PID_NAME_LEN, "process_%d", current->pid);
 	pm_qos_remove_requirement(pm_qos_class, name);
 
 	return 0;
@@ -385,13 +380,14 @@
 {
 	s32 value;
 	int pm_qos_class;
+	char name[PID_NAME_LEN];
 
 	pm_qos_class = (long)filp->private_data;
 	if (count != sizeof(s32))
 		return -EINVAL;
 	if (copy_from_user(&value, buf, sizeof(s32)))
 		return -EFAULT;
-	sprintf(name, "process_%d", current->pid);
+	snprintf(name, PID_NAME_LEN, "process_%d", current->pid);
 	pm_qos_update_requirement(pm_qos_class, name, value);
 
 	return  sizeof(s32);
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index 5c9dc22..438ff45 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -384,7 +384,8 @@
 
 /*
  * Validate the clockid_t for a new CPU-clock timer, and initialize the timer.
- * This is called from sys_timer_create with the new timer already locked.
+ * This is called from sys_timer_create() and do_cpu_nanosleep() with the
+ * new timer already all-zeros initialized.
  */
 int posix_cpu_timer_create(struct k_itimer *new_timer)
 {
@@ -396,8 +397,6 @@
 		return -EINVAL;
 
 	INIT_LIST_HEAD(&new_timer->it.cpu.entry);
-	new_timer->it.cpu.incr.sched = 0;
-	new_timer->it.cpu.expires.sched = 0;
 
 	read_lock(&tasklist_lock);
 	if (CPUCLOCK_PERTHREAD(new_timer->it_clock)) {
diff --git a/kernel/resource.c b/kernel/resource.c
index fb11a58..dc15686 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -308,35 +308,37 @@
 			 void *alignf_data)
 {
 	struct resource *this = root->child;
+	resource_size_t start, end;
 
-	new->start = root->start;
+	start = root->start;
 	/*
 	 * Skip past an allocated resource that starts at 0, since the assignment
 	 * of this->start - 1 to new->end below would cause an underflow.
 	 */
 	if (this && this->start == 0) {
-		new->start = this->end + 1;
+		start = this->end + 1;
 		this = this->sibling;
 	}
 	for(;;) {
 		if (this)
-			new->end = this->start - 1;
+			end = this->start - 1;
 		else
-			new->end = root->end;
-		if (new->start < min)
-			new->start = min;
-		if (new->end > max)
-			new->end = max;
-		new->start = ALIGN(new->start, align);
+			end = root->end;
+		if (start < min)
+			start = min;
+		if (end > max)
+			end = max;
+		start = ALIGN(start, align);
 		if (alignf)
 			alignf(alignf_data, new, size, align);
-		if (new->start < new->end && new->end - new->start >= size - 1) {
-			new->end = new->start + size - 1;
+		if (start < end && end - start >= size - 1) {
+			new->start = start;
+			new->end = start + size - 1;
 			return 0;
 		}
 		if (!this)
 			break;
-		new->start = this->end + 1;
+		start = this->end + 1;
 		this = this->sibling;
 	}
 	return -EBUSY;
diff --git a/kernel/sys.c b/kernel/sys.c
index 9968c5f..585d6cd 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -8,7 +8,6 @@
 #include <linux/mm.h>
 #include <linux/utsname.h>
 #include <linux/mman.h>
-#include <linux/smp_lock.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/prctl.h>
@@ -349,6 +348,9 @@
 	machine_power_off();
 }
 EXPORT_SYMBOL_GPL(kernel_power_off);
+
+static DEFINE_MUTEX(reboot_mutex);
+
 /*
  * Reboot system call: for obvious reasons only root may call it,
  * and even root needs to set up some magic numbers in the registers
@@ -381,7 +383,7 @@
 	if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
 		cmd = LINUX_REBOOT_CMD_HALT;
 
-	lock_kernel();
+	mutex_lock(&reboot_mutex);
 	switch (cmd) {
 	case LINUX_REBOOT_CMD_RESTART:
 		kernel_restart(NULL);
@@ -397,20 +399,18 @@
 
 	case LINUX_REBOOT_CMD_HALT:
 		kernel_halt();
-		unlock_kernel();
 		do_exit(0);
 		panic("cannot halt");
 
 	case LINUX_REBOOT_CMD_POWER_OFF:
 		kernel_power_off();
-		unlock_kernel();
 		do_exit(0);
 		break;
 
 	case LINUX_REBOOT_CMD_RESTART2:
 		if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1) < 0) {
-			unlock_kernel();
-			return -EFAULT;
+			ret = -EFAULT;
+			break;
 		}
 		buffer[sizeof(buffer) - 1] = '\0';
 
@@ -433,7 +433,7 @@
 		ret = -EINVAL;
 		break;
 	}
-	unlock_kernel();
+	mutex_unlock(&reboot_mutex);
 	return ret;
 }
 
diff --git a/kernel/time.c b/kernel/time.c
index 8047980..c6324d9 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -136,7 +136,6 @@
 	write_seqlock_irq(&xtime_lock);
 	wall_to_monotonic.tv_sec -= sys_tz.tz_minuteswest * 60;
 	xtime.tv_sec += sys_tz.tz_minuteswest * 60;
-	update_xtime_cache(0);
 	write_sequnlock_irq(&xtime_lock);
 	clock_was_set();
 }
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 620b58a..20a8920 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -20,6 +20,8 @@
 #include <linux/sysdev.h>
 #include <linux/tick.h>
 
+#include "tick-internal.h"
+
 /* The registered clock event devices */
 static LIST_HEAD(clockevent_devices);
 static LIST_HEAD(clockevents_released);
@@ -37,10 +39,9 @@
  *
  * Math helper, returns latch value converted to nanoseconds (bound checked)
  */
-unsigned long clockevent_delta2ns(unsigned long latch,
-				  struct clock_event_device *evt)
+u64 clockevent_delta2ns(unsigned long latch, struct clock_event_device *evt)
 {
-	u64 clc = ((u64) latch << evt->shift);
+	u64 clc = (u64) latch << evt->shift;
 
 	if (unlikely(!evt->mult)) {
 		evt->mult = 1;
@@ -50,10 +51,10 @@
 	do_div(clc, evt->mult);
 	if (clc < 1000)
 		clc = 1000;
-	if (clc > LONG_MAX)
-		clc = LONG_MAX;
+	if (clc > KTIME_MAX)
+		clc = KTIME_MAX;
 
-	return (unsigned long) clc;
+	return clc;
 }
 EXPORT_SYMBOL_GPL(clockevent_delta2ns);
 
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index 4a31090..e85c234 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -107,6 +107,59 @@
 }
 EXPORT_SYMBOL_GPL(timecounter_cyc2time);
 
+/**
+ * clocks_calc_mult_shift - calculate mult/shift factors for scaled math of clocks
+ * @mult:	pointer to mult variable
+ * @shift:	pointer to shift variable
+ * @from:	frequency to convert from
+ * @to:		frequency to convert to
+ * @minsec:	guaranteed runtime conversion range in seconds
+ *
+ * The function evaluates the shift/mult pair for the scaled math
+ * operations of clocksources and clockevents.
+ *
+ * @to and @from are frequency values in HZ. For clock sources @to is
+ * NSEC_PER_SEC == 1GHz and @from is the counter frequency. For clock
+ * event @to is the counter frequency and @from is NSEC_PER_SEC.
+ *
+ * The @minsec conversion range argument controls the time frame in
+ * seconds which must be covered by the runtime conversion with the
+ * calculated mult and shift factors. This guarantees that no 64bit
+ * overflow happens when the input value of the conversion is
+ * multiplied with the calculated mult factor. Larger ranges may
+ * reduce the conversion accuracy by chosing smaller mult and shift
+ * factors.
+ */
+void
+clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 minsec)
+{
+	u64 tmp;
+	u32 sft, sftacc= 32;
+
+	/*
+	 * Calculate the shift factor which is limiting the conversion
+	 * range:
+	 */
+	tmp = ((u64)minsec * from) >> 32;
+	while (tmp) {
+		tmp >>=1;
+		sftacc--;
+	}
+
+	/*
+	 * Find the conversion shift/mult pair which has the best
+	 * accuracy and fits the maxsec conversion range:
+	 */
+	for (sft = 32; sft > 0; sft--) {
+		tmp = (u64) to << sft;
+		do_div(tmp, from);
+		if ((tmp >> sftacc) == 0)
+			break;
+	}
+	*mult = tmp;
+	*shift = sft;
+}
+
 /*[Clocksource internal variables]---------
  * curr_clocksource:
  *	currently selected clocksource.
@@ -413,6 +466,47 @@
 	clocksource_resume_watchdog();
 }
 
+/**
+ * clocksource_max_deferment - Returns max time the clocksource can be deferred
+ * @cs:         Pointer to clocksource
+ *
+ */
+static u64 clocksource_max_deferment(struct clocksource *cs)
+{
+	u64 max_nsecs, max_cycles;
+
+	/*
+	 * Calculate the maximum number of cycles that we can pass to the
+	 * cyc2ns function without overflowing a 64-bit signed result. The
+	 * maximum number of cycles is equal to ULLONG_MAX/cs->mult which
+	 * is equivalent to the below.
+	 * max_cycles < (2^63)/cs->mult
+	 * max_cycles < 2^(log2((2^63)/cs->mult))
+	 * max_cycles < 2^(log2(2^63) - log2(cs->mult))
+	 * max_cycles < 2^(63 - log2(cs->mult))
+	 * max_cycles < 1 << (63 - log2(cs->mult))
+	 * Please note that we add 1 to the result of the log2 to account for
+	 * any rounding errors, ensure the above inequality is satisfied and
+	 * no overflow will occur.
+	 */
+	max_cycles = 1ULL << (63 - (ilog2(cs->mult) + 1));
+
+	/*
+	 * The actual maximum number of cycles we can defer the clocksource is
+	 * determined by the minimum of max_cycles and cs->mask.
+	 */
+	max_cycles = min_t(u64, max_cycles, (u64) cs->mask);
+	max_nsecs = clocksource_cyc2ns(max_cycles, cs->mult, cs->shift);
+
+	/*
+	 * To ensure that the clocksource does not wrap whilst we are idle,
+	 * limit the time the clocksource can be deferred by 12.5%. Please
+	 * note a margin of 12.5% is used because this can be computed with
+	 * a shift, versus say 10% which would require division.
+	 */
+	return max_nsecs - (max_nsecs >> 5);
+}
+
 #ifdef CONFIG_GENERIC_TIME
 
 /**
@@ -511,6 +605,9 @@
  */
 int clocksource_register(struct clocksource *cs)
 {
+	/* calculate max idle time permitted for this clocksource */
+	cs->max_idle_ns = clocksource_max_deferment(cs);
+
 	mutex_lock(&clocksource_mutex);
 	clocksource_enqueue(cs);
 	clocksource_select();
@@ -580,7 +677,7 @@
  * @count:	length of buffer
  *
  * Takes input from sysfs interface for manually overriding the default
- * clocksource selction.
+ * clocksource selection.
  */
 static ssize_t sysfs_override_clocksource(struct sys_device *dev,
 					  struct sysdev_attribute *attr,
diff --git a/kernel/time/tick-oneshot.c b/kernel/time/tick-oneshot.c
index a96c0e2..0a8a213 100644
--- a/kernel/time/tick-oneshot.c
+++ b/kernel/time/tick-oneshot.c
@@ -50,9 +50,9 @@
 				dev->min_delta_ns += dev->min_delta_ns >> 1;
 
 			printk(KERN_WARNING
-			       "CE: %s increasing min_delta_ns to %lu nsec\n",
+			       "CE: %s increasing min_delta_ns to %llu nsec\n",
 			       dev->name ? dev->name : "?",
-			       dev->min_delta_ns << 1);
+			       (unsigned long long) dev->min_delta_ns << 1);
 
 			i = 0;
 		}
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 89aed59..f992762 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -134,18 +134,13 @@
  * value. We do this unconditionally on any cpu, as we don't know whether the
  * cpu, which has the update task assigned is in a long sleep.
  */
-static void tick_nohz_update_jiffies(void)
+static void tick_nohz_update_jiffies(ktime_t now)
 {
 	int cpu = smp_processor_id();
 	struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
 	unsigned long flags;
-	ktime_t now;
-
-	if (!ts->tick_stopped)
-		return;
 
 	cpumask_clear_cpu(cpu, nohz_cpu_mask);
-	now = ktime_get();
 	ts->idle_waketime = now;
 
 	local_irq_save(flags);
@@ -155,20 +150,17 @@
 	touch_softlockup_watchdog();
 }
 
-static void tick_nohz_stop_idle(int cpu)
+static void tick_nohz_stop_idle(int cpu, ktime_t now)
 {
 	struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
+	ktime_t delta;
 
-	if (ts->idle_active) {
-		ktime_t now, delta;
-		now = ktime_get();
-		delta = ktime_sub(now, ts->idle_entrytime);
-		ts->idle_lastupdate = now;
-		ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta);
-		ts->idle_active = 0;
+	delta = ktime_sub(now, ts->idle_entrytime);
+	ts->idle_lastupdate = now;
+	ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta);
+	ts->idle_active = 0;
 
-		sched_clock_idle_wakeup_event(0);
-	}
+	sched_clock_idle_wakeup_event(0);
 }
 
 static ktime_t tick_nohz_start_idle(struct tick_sched *ts)
@@ -216,6 +208,7 @@
 	struct tick_sched *ts;
 	ktime_t last_update, expires, now;
 	struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev;
+	u64 time_delta;
 	int cpu;
 
 	local_irq_save(flags);
@@ -263,7 +256,7 @@
 
 		if (ratelimit < 10) {
 			printk(KERN_ERR "NOHZ: local_softirq_pending %02x\n",
-			       local_softirq_pending());
+			       (unsigned int) local_softirq_pending());
 			ratelimit++;
 		}
 		goto end;
@@ -275,14 +268,18 @@
 		seq = read_seqbegin(&xtime_lock);
 		last_update = last_jiffies_update;
 		last_jiffies = jiffies;
+		time_delta = timekeeping_max_deferment();
 	} while (read_seqretry(&xtime_lock, seq));
 
-	/* Get the next timer wheel timer */
-	next_jiffies = get_next_timer_interrupt(last_jiffies);
-	delta_jiffies = next_jiffies - last_jiffies;
-
-	if (rcu_needs_cpu(cpu) || printk_needs_cpu(cpu))
+	if (rcu_needs_cpu(cpu) || printk_needs_cpu(cpu) ||
+	    arch_needs_cpu(cpu)) {
+		next_jiffies = last_jiffies + 1;
 		delta_jiffies = 1;
+	} else {
+		/* Get the next timer wheel timer */
+		next_jiffies = get_next_timer_interrupt(last_jiffies);
+		delta_jiffies = next_jiffies - last_jiffies;
+	}
 	/*
 	 * Do not stop the tick, if we are only one off
 	 * or if the cpu is required for rcu
@@ -294,22 +291,51 @@
 	if ((long)delta_jiffies >= 1) {
 
 		/*
-		* calculate the expiry time for the next timer wheel
-		* timer
-		*/
-		expires = ktime_add_ns(last_update, tick_period.tv64 *
-				   delta_jiffies);
-
-		/*
 		 * If this cpu is the one which updates jiffies, then
 		 * give up the assignment and let it be taken by the
 		 * cpu which runs the tick timer next, which might be
 		 * this cpu as well. If we don't drop this here the
 		 * jiffies might be stale and do_timer() never
-		 * invoked.
+		 * invoked. Keep track of the fact that it was the one
+		 * which had the do_timer() duty last. If this cpu is
+		 * the one which had the do_timer() duty last, we
+		 * limit the sleep time to the timekeeping
+		 * max_deferement value which we retrieved
+		 * above. Otherwise we can sleep as long as we want.
 		 */
-		if (cpu == tick_do_timer_cpu)
+		if (cpu == tick_do_timer_cpu) {
 			tick_do_timer_cpu = TICK_DO_TIMER_NONE;
+			ts->do_timer_last = 1;
+		} else if (tick_do_timer_cpu != TICK_DO_TIMER_NONE) {
+			time_delta = KTIME_MAX;
+			ts->do_timer_last = 0;
+		} else if (!ts->do_timer_last) {
+			time_delta = KTIME_MAX;
+		}
+
+		/*
+		 * calculate the expiry time for the next timer wheel
+		 * timer. delta_jiffies >= NEXT_TIMER_MAX_DELTA signals
+		 * that there is no timer pending or at least extremely
+		 * far into the future (12 days for HZ=1000). In this
+		 * case we set the expiry to the end of time.
+		 */
+		if (likely(delta_jiffies < NEXT_TIMER_MAX_DELTA)) {
+			/*
+			 * Calculate the time delta for the next timer event.
+			 * If the time delta exceeds the maximum time delta
+			 * permitted by the current clocksource then adjust
+			 * the time delta accordingly to ensure the
+			 * clocksource does not wrap.
+			 */
+			time_delta = min_t(u64, time_delta,
+					   tick_period.tv64 * delta_jiffies);
+		}
+
+		if (time_delta < KTIME_MAX)
+			expires = ktime_add_ns(last_update, time_delta);
+		else
+			expires.tv64 = KTIME_MAX;
 
 		if (delta_jiffies > 1)
 			cpumask_set_cpu(cpu, nohz_cpu_mask);
@@ -342,22 +368,19 @@
 
 		ts->idle_sleeps++;
 
+		/* Mark expires */
+		ts->idle_expires = expires;
+
 		/*
-		 * delta_jiffies >= NEXT_TIMER_MAX_DELTA signals that
-		 * there is no timer pending or at least extremly far
-		 * into the future (12 days for HZ=1000). In this case
-		 * we simply stop the tick timer:
+		 * If the expiration time == KTIME_MAX, then
+		 * in this case we simply stop the tick timer.
 		 */
-		if (unlikely(delta_jiffies >= NEXT_TIMER_MAX_DELTA)) {
-			ts->idle_expires.tv64 = KTIME_MAX;
+		 if (unlikely(expires.tv64 == KTIME_MAX)) {
 			if (ts->nohz_mode == NOHZ_MODE_HIGHRES)
 				hrtimer_cancel(&ts->sched_timer);
 			goto out;
 		}
 
-		/* Mark expiries */
-		ts->idle_expires = expires;
-
 		if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
 			hrtimer_start(&ts->sched_timer, expires,
 				      HRTIMER_MODE_ABS_PINNED);
@@ -436,7 +459,11 @@
 	ktime_t now;
 
 	local_irq_disable();
-	tick_nohz_stop_idle(cpu);
+	if (ts->idle_active || (ts->inidle && ts->tick_stopped))
+		now = ktime_get();
+
+	if (ts->idle_active)
+		tick_nohz_stop_idle(cpu, now);
 
 	if (!ts->inidle || !ts->tick_stopped) {
 		ts->inidle = 0;
@@ -450,7 +477,6 @@
 
 	/* Update jiffies first */
 	select_nohz_load_balancer(0);
-	now = ktime_get();
 	tick_do_update_jiffies64(now);
 	cpumask_clear_cpu(cpu, nohz_cpu_mask);
 
@@ -584,22 +610,18 @@
  * timer and do not touch the other magic bits which need to be done
  * when idle is left.
  */
-static void tick_nohz_kick_tick(int cpu)
+static void tick_nohz_kick_tick(int cpu, ktime_t now)
 {
 #if 0
 	/* Switch back to 2.6.27 behaviour */
 
 	struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
-	ktime_t delta, now;
-
-	if (!ts->tick_stopped)
-		return;
+	ktime_t delta;
 
 	/*
 	 * Do not touch the tick device, when the next expiry is either
 	 * already reached or less/equal than the tick period.
 	 */
-	now = ktime_get();
 	delta =	ktime_sub(hrtimer_get_expires(&ts->sched_timer), now);
 	if (delta.tv64 <= tick_period.tv64)
 		return;
@@ -608,9 +630,26 @@
 #endif
 }
 
+static inline void tick_check_nohz(int cpu)
+{
+	struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
+	ktime_t now;
+
+	if (!ts->idle_active && !ts->tick_stopped)
+		return;
+	now = ktime_get();
+	if (ts->idle_active)
+		tick_nohz_stop_idle(cpu, now);
+	if (ts->tick_stopped) {
+		tick_nohz_update_jiffies(now);
+		tick_nohz_kick_tick(cpu, now);
+	}
+}
+
 #else
 
 static inline void tick_nohz_switch_to_nohz(void) { }
+static inline void tick_check_nohz(int cpu) { }
 
 #endif /* NO_HZ */
 
@@ -620,11 +659,7 @@
 void tick_check_idle(int cpu)
 {
 	tick_check_oneshot_broadcast(cpu);
-#ifdef CONFIG_NO_HZ
-	tick_nohz_stop_idle(cpu);
-	tick_nohz_update_jiffies();
-	tick_nohz_kick_tick(cpu);
-#endif
+	tick_check_nohz(cpu);
 }
 
 /*
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index c3a4e29..af4135f 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -165,19 +165,12 @@
 /* flag for if timekeeping is suspended */
 int __read_mostly timekeeping_suspended;
 
-static struct timespec xtime_cache __attribute__ ((aligned (16)));
-void update_xtime_cache(u64 nsec)
-{
-	xtime_cache = xtime;
-	timespec_add_ns(&xtime_cache, nsec);
-}
-
 /* must hold xtime_lock */
 void timekeeping_leap_insert(int leapsecond)
 {
 	xtime.tv_sec += leapsecond;
 	wall_to_monotonic.tv_sec -= leapsecond;
-	update_vsyscall(&xtime, timekeeper.clock);
+	update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult);
 }
 
 #ifdef CONFIG_GENERIC_TIME
@@ -332,12 +325,10 @@
 
 	xtime = *tv;
 
-	update_xtime_cache(0);
-
 	timekeeper.ntp_error = 0;
 	ntp_clear();
 
-	update_vsyscall(&xtime, timekeeper.clock);
+	update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult);
 
 	write_sequnlock_irqrestore(&xtime_lock, flags);
 
@@ -488,6 +479,17 @@
 }
 
 /**
+ * timekeeping_max_deferment - Returns max time the clocksource can be deferred
+ *
+ * Caller must observe xtime_lock via read_seqbegin/read_seqretry to
+ * ensure that the clocksource does not change!
+ */
+u64 timekeeping_max_deferment(void)
+{
+	return timekeeper.clock->max_idle_ns;
+}
+
+/**
  * read_persistent_clock -  Return time from the persistent clock.
  *
  * Weak dummy function for arches that do not yet support it.
@@ -548,7 +550,6 @@
 	}
 	set_normalized_timespec(&wall_to_monotonic,
 				-boot.tv_sec, -boot.tv_nsec);
-	update_xtime_cache(0);
 	total_sleep_time.tv_sec = 0;
 	total_sleep_time.tv_nsec = 0;
 	write_sequnlock_irqrestore(&xtime_lock, flags);
@@ -582,7 +583,6 @@
 		wall_to_monotonic = timespec_sub(wall_to_monotonic, ts);
 		total_sleep_time = timespec_add_safe(total_sleep_time, ts);
 	}
-	update_xtime_cache(0);
 	/* re-base the last cycle value */
 	timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock);
 	timekeeper.ntp_error = 0;
@@ -723,6 +723,49 @@
 }
 
 /**
+ * logarithmic_accumulation - shifted accumulation of cycles
+ *
+ * This functions accumulates a shifted interval of cycles into
+ * into a shifted interval nanoseconds. Allows for O(log) accumulation
+ * loop.
+ *
+ * Returns the unconsumed cycles.
+ */
+static cycle_t logarithmic_accumulation(cycle_t offset, int shift)
+{
+	u64 nsecps = (u64)NSEC_PER_SEC << timekeeper.shift;
+
+	/* If the offset is smaller then a shifted interval, do nothing */
+	if (offset < timekeeper.cycle_interval<<shift)
+		return offset;
+
+	/* Accumulate one shifted interval */
+	offset -= timekeeper.cycle_interval << shift;
+	timekeeper.clock->cycle_last += timekeeper.cycle_interval << shift;
+
+	timekeeper.xtime_nsec += timekeeper.xtime_interval << shift;
+	while (timekeeper.xtime_nsec >= nsecps) {
+		timekeeper.xtime_nsec -= nsecps;
+		xtime.tv_sec++;
+		second_overflow();
+	}
+
+	/* Accumulate into raw time */
+	raw_time.tv_nsec += timekeeper.raw_interval << shift;;
+	while (raw_time.tv_nsec >= NSEC_PER_SEC) {
+		raw_time.tv_nsec -= NSEC_PER_SEC;
+		raw_time.tv_sec++;
+	}
+
+	/* Accumulate error between NTP and clock interval */
+	timekeeper.ntp_error += tick_length << shift;
+	timekeeper.ntp_error -= timekeeper.xtime_interval <<
+				(timekeeper.ntp_error_shift + shift);
+
+	return offset;
+}
+
+/**
  * update_wall_time - Uses the current clocksource to increment the wall time
  *
  * Called from the timer interrupt, must hold a write on xtime_lock.
@@ -731,7 +774,7 @@
 {
 	struct clocksource *clock;
 	cycle_t offset;
-	u64 nsecs;
+	int shift = 0, maxshift;
 
 	/* Make sure we're fully resumed: */
 	if (unlikely(timekeeping_suspended))
@@ -745,33 +788,22 @@
 #endif
 	timekeeper.xtime_nsec = (s64)xtime.tv_nsec << timekeeper.shift;
 
-	/* normally this loop will run just once, however in the
-	 * case of lost or late ticks, it will accumulate correctly.
+	/*
+	 * With NO_HZ we may have to accumulate many cycle_intervals
+	 * (think "ticks") worth of time at once. To do this efficiently,
+	 * we calculate the largest doubling multiple of cycle_intervals
+	 * that is smaller then the offset. We then accumulate that
+	 * chunk in one go, and then try to consume the next smaller
+	 * doubled multiple.
 	 */
+	shift = ilog2(offset) - ilog2(timekeeper.cycle_interval);
+	shift = max(0, shift);
+	/* Bound shift to one less then what overflows tick_length */
+	maxshift = (8*sizeof(tick_length) - (ilog2(tick_length)+1)) - 1;
+	shift = min(shift, maxshift);
 	while (offset >= timekeeper.cycle_interval) {
-		u64 nsecps = (u64)NSEC_PER_SEC << timekeeper.shift;
-
-		/* accumulate one interval */
-		offset -= timekeeper.cycle_interval;
-		clock->cycle_last += timekeeper.cycle_interval;
-
-		timekeeper.xtime_nsec += timekeeper.xtime_interval;
-		if (timekeeper.xtime_nsec >= nsecps) {
-			timekeeper.xtime_nsec -= nsecps;
-			xtime.tv_sec++;
-			second_overflow();
-		}
-
-		raw_time.tv_nsec += timekeeper.raw_interval;
-		if (raw_time.tv_nsec >= NSEC_PER_SEC) {
-			raw_time.tv_nsec -= NSEC_PER_SEC;
-			raw_time.tv_sec++;
-		}
-
-		/* accumulate error between NTP and clock interval */
-		timekeeper.ntp_error += tick_length;
-		timekeeper.ntp_error -= timekeeper.xtime_interval <<
-					timekeeper.ntp_error_shift;
+		offset = logarithmic_accumulation(offset, shift);
+		shift--;
 	}
 
 	/* correct the clock when NTP error is too big */
@@ -807,11 +839,8 @@
 	timekeeper.ntp_error +=	timekeeper.xtime_nsec <<
 				timekeeper.ntp_error_shift;
 
-	nsecs = clocksource_cyc2ns(offset, timekeeper.mult, timekeeper.shift);
-	update_xtime_cache(nsecs);
-
 	/* check to see if there is a new clocksource to use */
-	update_vsyscall(&xtime, timekeeper.clock);
+	update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult);
 }
 
 /**
@@ -846,13 +875,13 @@
 
 unsigned long get_seconds(void)
 {
-	return xtime_cache.tv_sec;
+	return xtime.tv_sec;
 }
 EXPORT_SYMBOL(get_seconds);
 
 struct timespec __current_kernel_time(void)
 {
-	return xtime_cache;
+	return xtime;
 }
 
 struct timespec current_kernel_time(void)
@@ -862,8 +891,7 @@
 
 	do {
 		seq = read_seqbegin(&xtime_lock);
-
-		now = xtime_cache;
+		now = xtime;
 	} while (read_seqretry(&xtime_lock, seq));
 
 	return now;
@@ -877,8 +905,7 @@
 
 	do {
 		seq = read_seqbegin(&xtime_lock);
-
-		now = xtime_cache;
+		now = xtime;
 		mono = wall_to_monotonic;
 	} while (read_seqretry(&xtime_lock, seq));
 
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
index 1b5b7aa..665c76e 100644
--- a/kernel/time/timer_list.c
+++ b/kernel/time/timer_list.c
@@ -204,10 +204,12 @@
 		return;
 	}
 	SEQ_printf(m, "%s\n", dev->name);
-	SEQ_printf(m, " max_delta_ns:   %lu\n", dev->max_delta_ns);
-	SEQ_printf(m, " min_delta_ns:   %lu\n", dev->min_delta_ns);
-	SEQ_printf(m, " mult:           %lu\n", dev->mult);
-	SEQ_printf(m, " shift:          %d\n", dev->shift);
+	SEQ_printf(m, " max_delta_ns:   %llu\n",
+		   (unsigned long long) dev->max_delta_ns);
+	SEQ_printf(m, " min_delta_ns:   %llu\n",
+		   (unsigned long long) dev->min_delta_ns);
+	SEQ_printf(m, " mult:           %u\n", dev->mult);
+	SEQ_printf(m, " shift:          %u\n", dev->shift);
 	SEQ_printf(m, " mode:           %d\n", dev->mode);
 	SEQ_printf(m, " next_event:     %Ld nsecs\n",
 		   (unsigned long long) ktime_to_ns(dev->next_event));
diff --git a/kernel/user-return-notifier.c b/kernel/user-return-notifier.c
index 03e2d6f..eb27fd3 100644
--- a/kernel/user-return-notifier.c
+++ b/kernel/user-return-notifier.c
@@ -6,8 +6,6 @@
 
 static DEFINE_PER_CPU(struct hlist_head, return_notifier_list);
 
-#define URN_LIST_HEAD per_cpu(return_notifier_list, raw_smp_processor_id())
-
 /*
  * Request a notification when the current cpu returns to userspace.  Must be
  * called in atomic context.  The notifier will also be called in atomic
@@ -16,7 +14,7 @@
 void user_return_notifier_register(struct user_return_notifier *urn)
 {
 	set_tsk_thread_flag(current, TIF_USER_RETURN_NOTIFY);
-	hlist_add_head(&urn->link, &URN_LIST_HEAD);
+	hlist_add_head(&urn->link, &__get_cpu_var(return_notifier_list));
 }
 EXPORT_SYMBOL_GPL(user_return_notifier_register);
 
@@ -27,7 +25,7 @@
 void user_return_notifier_unregister(struct user_return_notifier *urn)
 {
 	hlist_del(&urn->link);
-	if (hlist_empty(&URN_LIST_HEAD))
+	if (hlist_empty(&__get_cpu_var(return_notifier_list)))
 		clear_tsk_thread_flag(current, TIF_USER_RETURN_NOTIFY);
 }
 EXPORT_SYMBOL_GPL(user_return_notifier_unregister);
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 67e526b..dee4865 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -68,6 +68,116 @@
 #endif
 };
 
+#ifdef CONFIG_DEBUG_OBJECTS_WORK
+
+static struct debug_obj_descr work_debug_descr;
+
+/*
+ * fixup_init is called when:
+ * - an active object is initialized
+ */
+static int work_fixup_init(void *addr, enum debug_obj_state state)
+{
+	struct work_struct *work = addr;
+
+	switch (state) {
+	case ODEBUG_STATE_ACTIVE:
+		cancel_work_sync(work);
+		debug_object_init(work, &work_debug_descr);
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+/*
+ * fixup_activate is called when:
+ * - an active object is activated
+ * - an unknown object is activated (might be a statically initialized object)
+ */
+static int work_fixup_activate(void *addr, enum debug_obj_state state)
+{
+	struct work_struct *work = addr;
+
+	switch (state) {
+
+	case ODEBUG_STATE_NOTAVAILABLE:
+		/*
+		 * This is not really a fixup. The work struct was
+		 * statically initialized. We just make sure that it
+		 * is tracked in the object tracker.
+		 */
+		if (test_bit(WORK_STRUCT_STATIC, work_data_bits(work))) {
+			debug_object_init(work, &work_debug_descr);
+			debug_object_activate(work, &work_debug_descr);
+			return 0;
+		}
+		WARN_ON_ONCE(1);
+		return 0;
+
+	case ODEBUG_STATE_ACTIVE:
+		WARN_ON(1);
+
+	default:
+		return 0;
+	}
+}
+
+/*
+ * fixup_free is called when:
+ * - an active object is freed
+ */
+static int work_fixup_free(void *addr, enum debug_obj_state state)
+{
+	struct work_struct *work = addr;
+
+	switch (state) {
+	case ODEBUG_STATE_ACTIVE:
+		cancel_work_sync(work);
+		debug_object_free(work, &work_debug_descr);
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+static struct debug_obj_descr work_debug_descr = {
+	.name		= "work_struct",
+	.fixup_init	= work_fixup_init,
+	.fixup_activate	= work_fixup_activate,
+	.fixup_free	= work_fixup_free,
+};
+
+static inline void debug_work_activate(struct work_struct *work)
+{
+	debug_object_activate(work, &work_debug_descr);
+}
+
+static inline void debug_work_deactivate(struct work_struct *work)
+{
+	debug_object_deactivate(work, &work_debug_descr);
+}
+
+void __init_work(struct work_struct *work, int onstack)
+{
+	if (onstack)
+		debug_object_init_on_stack(work, &work_debug_descr);
+	else
+		debug_object_init(work, &work_debug_descr);
+}
+EXPORT_SYMBOL_GPL(__init_work);
+
+void destroy_work_on_stack(struct work_struct *work)
+{
+	debug_object_free(work, &work_debug_descr);
+}
+EXPORT_SYMBOL_GPL(destroy_work_on_stack);
+
+#else
+static inline void debug_work_activate(struct work_struct *work) { }
+static inline void debug_work_deactivate(struct work_struct *work) { }
+#endif
+
 /* Serializes the accesses to the list of workqueues. */
 static DEFINE_SPINLOCK(workqueue_lock);
 static LIST_HEAD(workqueues);
@@ -145,6 +255,7 @@
 {
 	unsigned long flags;
 
+	debug_work_activate(work);
 	spin_lock_irqsave(&cwq->lock, flags);
 	insert_work(cwq, work, &cwq->worklist);
 	spin_unlock_irqrestore(&cwq->lock, flags);
@@ -280,6 +391,7 @@
 		struct lockdep_map lockdep_map = work->lockdep_map;
 #endif
 		trace_workqueue_execution(cwq->thread, work);
+		debug_work_deactivate(work);
 		cwq->current_work = work;
 		list_del_init(cwq->worklist.next);
 		spin_unlock_irq(&cwq->lock);
@@ -350,11 +462,18 @@
 static void insert_wq_barrier(struct cpu_workqueue_struct *cwq,
 			struct wq_barrier *barr, struct list_head *head)
 {
-	INIT_WORK(&barr->work, wq_barrier_func);
+	/*
+	 * debugobject calls are safe here even with cwq->lock locked
+	 * as we know for sure that this will not trigger any of the
+	 * checks and call back into the fixup functions where we
+	 * might deadlock.
+	 */
+	INIT_WORK_ON_STACK(&barr->work, wq_barrier_func);
 	__set_bit(WORK_STRUCT_PENDING, work_data_bits(&barr->work));
 
 	init_completion(&barr->done);
 
+	debug_work_activate(&barr->work);
 	insert_work(cwq, &barr->work, head);
 }
 
@@ -372,8 +491,10 @@
 	}
 	spin_unlock_irq(&cwq->lock);
 
-	if (active)
+	if (active) {
 		wait_for_completion(&barr.done);
+		destroy_work_on_stack(&barr.work);
+	}
 
 	return active;
 }
@@ -451,6 +572,7 @@
 		return 0;
 
 	wait_for_completion(&barr.done);
+	destroy_work_on_stack(&barr.work);
 	return 1;
 }
 EXPORT_SYMBOL_GPL(flush_work);
@@ -485,6 +607,7 @@
 		 */
 		smp_rmb();
 		if (cwq == get_wq_data(work)) {
+			debug_work_deactivate(work);
 			list_del_init(&work->entry);
 			ret = 1;
 		}
@@ -507,8 +630,10 @@
 	}
 	spin_unlock_irq(&cwq->lock);
 
-	if (unlikely(running))
+	if (unlikely(running)) {
 		wait_for_completion(&barr.done);
+		destroy_work_on_stack(&barr.work);
+	}
 }
 
 static void wait_on_work(struct work_struct *work)
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 0b8f359..2f22cf4 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -105,7 +105,7 @@
 	bool "Enable full Section mismatch analysis"
 	depends on UNDEFINED
 	# This option is on purpose disabled for now.
-	# It will be enabled when we are down to a resonable number
+	# It will be enabled when we are down to a reasonable number
 	# of section mismatch warnings (< 10 for an allyesconfig build)
 	help
 	  The section mismatch analysis checks if there are illegal
@@ -298,6 +298,14 @@
 	  timer routines to track the life time of timer objects and
 	  validate the timer operations.
 
+config DEBUG_OBJECTS_WORK
+	bool "Debug work objects"
+	depends on DEBUG_OBJECTS
+	help
+	  If you say Y here, additional code will be inserted into the
+	  work queue routines to track the life time of work objects and
+	  validate the work operations.
+
 config DEBUG_OBJECTS_ENABLE_DEFAULT
 	int "debug_objects bootup default value (0-1)"
         range 0 1
diff --git a/lib/decompress_bunzip2.c b/lib/decompress_bunzip2.c
index 600f473..7607420 100644
--- a/lib/decompress_bunzip2.c
+++ b/lib/decompress_bunzip2.c
@@ -299,7 +299,7 @@
 		   again when using them (during symbol decoding).*/
 		base = hufGroup->base-1;
 		limit = hufGroup->limit-1;
-		/* Calculate permute[].  Concurently, initialize
+		/* Calculate permute[].  Concurrently, initialize
 		 * temp[] and limit[]. */
 		pp = 0;
 		for (i = minLen; i <= maxLen; i++) {
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index ce6b7ea..d9b08e0 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -259,7 +259,7 @@
 		 * times. Without a hardware IOMMU this results in the
 		 * same device addresses being put into the dma-debug
 		 * hash multiple times too. This can result in false
-		 * positives being reported. Therfore we implement a
+		 * positives being reported. Therefore we implement a
 		 * best-fit algorithm here which returns the entry from
 		 * the hash which fits best to the reference value
 		 * instead of the first-fit.
diff --git a/lib/idr.c b/lib/idr.c
index 80ca9ac..1cac726 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -281,7 +281,7 @@
 /**
  * idr_get_new_above - allocate new idr entry above or equal to a start id
  * @idp: idr handle
- * @ptr: pointer you want associated with the ide
+ * @ptr: pointer you want associated with the id
  * @start_id: id to start search at
  * @id: pointer to the allocated handle
  *
@@ -313,7 +313,7 @@
 /**
  * idr_get_new - allocate new idr entry
  * @idp: idr handle
- * @ptr: pointer you want associated with the ide
+ * @ptr: pointer you want associated with the id
  * @id: pointer to the allocated handle
  *
  * This is the allocate id function.  It should be called with any
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 795472d..5bc0180 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -485,7 +485,7 @@
 
 	/*
 	 * Return the buffer to the free list by setting the corresponding
-	 * entries to indicate the number of contigous entries available.
+	 * entries to indicate the number of contiguous entries available.
 	 * While returning the entries to the free list, we merge the entries
 	 * with slots below and above the pool being returned.
 	 */
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 33bed5e..6438cd5 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -595,37 +595,89 @@
 }
 
 static char *resource_string(char *buf, char *end, struct resource *res,
-				struct printf_spec spec)
+				struct printf_spec spec, const char *fmt)
 {
 #ifndef IO_RSRC_PRINTK_SIZE
-#define IO_RSRC_PRINTK_SIZE	4
+#define IO_RSRC_PRINTK_SIZE	6
 #endif
 
 #ifndef MEM_RSRC_PRINTK_SIZE
-#define MEM_RSRC_PRINTK_SIZE	8
+#define MEM_RSRC_PRINTK_SIZE	10
 #endif
-	struct printf_spec num_spec = {
+	struct printf_spec hex_spec = {
 		.base = 16,
 		.precision = -1,
 		.flags = SPECIAL | SMALL | ZEROPAD,
 	};
-	/* room for the actual numbers, the two "0x", -, [, ] and the final zero */
-	char sym[4*sizeof(resource_size_t) + 8];
-	char *p = sym, *pend = sym + sizeof(sym);
-	int size = -1;
+	struct printf_spec dec_spec = {
+		.base = 10,
+		.precision = -1,
+		.flags = 0,
+	};
+	struct printf_spec str_spec = {
+		.field_width = -1,
+		.precision = 10,
+		.flags = LEFT,
+	};
+	struct printf_spec flag_spec = {
+		.base = 16,
+		.precision = -1,
+		.flags = SPECIAL | SMALL,
+	};
 
-	if (res->flags & IORESOURCE_IO)
+	/* 32-bit res (sizeof==4): 10 chars in dec, 10 in hex ("0x" + 8)
+	 * 64-bit res (sizeof==8): 20 chars in dec, 18 in hex ("0x" + 16) */
+#define RSRC_BUF_SIZE		((2 * sizeof(resource_size_t)) + 4)
+#define FLAG_BUF_SIZE		(2 * sizeof(res->flags))
+#define DECODED_BUF_SIZE	sizeof("[mem - 64bit pref disabled]")
+#define RAW_BUF_SIZE		sizeof("[mem - flags 0x]")
+	char sym[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE,
+		     2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)];
+
+	char *p = sym, *pend = sym + sizeof(sym);
+	int size = -1, addr = 0;
+	int decode = (fmt[0] == 'R') ? 1 : 0;
+
+	if (res->flags & IORESOURCE_IO) {
 		size = IO_RSRC_PRINTK_SIZE;
-	else if (res->flags & IORESOURCE_MEM)
+		addr = 1;
+	} else if (res->flags & IORESOURCE_MEM) {
 		size = MEM_RSRC_PRINTK_SIZE;
+		addr = 1;
+	}
 
 	*p++ = '[';
-	num_spec.field_width = size;
-	p = number(p, pend, res->start, num_spec);
-	*p++ = '-';
-	p = number(p, pend, res->end, num_spec);
+	if (res->flags & IORESOURCE_IO)
+		p = string(p, pend, "io  ", str_spec);
+	else if (res->flags & IORESOURCE_MEM)
+		p = string(p, pend, "mem ", str_spec);
+	else if (res->flags & IORESOURCE_IRQ)
+		p = string(p, pend, "irq ", str_spec);
+	else if (res->flags & IORESOURCE_DMA)
+		p = string(p, pend, "dma ", str_spec);
+	else {
+		p = string(p, pend, "??? ", str_spec);
+		decode = 0;
+	}
+	hex_spec.field_width = size;
+	p = number(p, pend, res->start, addr ? hex_spec : dec_spec);
+	if (res->start != res->end) {
+		*p++ = '-';
+		p = number(p, pend, res->end, addr ? hex_spec : dec_spec);
+	}
+	if (decode) {
+		if (res->flags & IORESOURCE_MEM_64)
+			p = string(p, pend, " 64bit", str_spec);
+		if (res->flags & IORESOURCE_PREFETCH)
+			p = string(p, pend, " pref", str_spec);
+		if (res->flags & IORESOURCE_DISABLED)
+			p = string(p, pend, " disabled", str_spec);
+	} else {
+		p = string(p, pend, " flags ", str_spec);
+		p = number(p, pend, res->flags, flag_spec);
+	}
 	*p++ = ']';
-	*p = 0;
+	*p = '\0';
 
 	return string(buf, end, sym, spec);
 }
@@ -801,8 +853,8 @@
  * - 'f' For simple symbolic function names without offset
  * - 'S' For symbolic direct pointers with offset
  * - 's' For symbolic direct pointers without offset
- * - 'R' For a struct resource pointer, it prints the range of
- *       addresses (not the name nor the flags)
+ * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref]
+ * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201]
  * - 'M' For a 6-byte MAC address, it prints the address in the
  *       usual colon-separated hex notation
  * - 'm' For a 6-byte MAC address, it prints the hex address without colons
@@ -833,7 +885,8 @@
 	case 'S':
 		return symbol_string(buf, end, ptr, spec, *fmt);
 	case 'R':
-		return resource_string(buf, end, ptr, spec);
+	case 'r':
+		return resource_string(buf, end, ptr, spec, fmt);
 	case 'M':			/* Colon separated: 00:01:02:03:04:05 */
 	case 'm':			/* Contiguous: 000102030405 */
 		return mac_address_string(buf, end, ptr, spec, fmt);
diff --git a/mm/filemap.c b/mm/filemap.c
index ef169f3..8b4d88f 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -260,27 +260,27 @@
 EXPORT_SYMBOL(filemap_flush);
 
 /**
- * wait_on_page_writeback_range - wait for writeback to complete
- * @mapping:	target address_space
- * @start:	beginning page index
- * @end:	ending page index
+ * filemap_fdatawait_range - wait for writeback to complete
+ * @mapping:		address space structure to wait for
+ * @start_byte:		offset in bytes where the range starts
+ * @end_byte:		offset in bytes where the range ends (inclusive)
  *
- * Wait for writeback to complete against pages indexed by start->end
- * inclusive
+ * Walk the list of under-writeback pages of the given address space
+ * in the given range and wait for all of them.
  */
-int wait_on_page_writeback_range(struct address_space *mapping,
-				pgoff_t start, pgoff_t end)
+int filemap_fdatawait_range(struct address_space *mapping, loff_t start_byte,
+			    loff_t end_byte)
 {
+	pgoff_t index = start_byte >> PAGE_CACHE_SHIFT;
+	pgoff_t end = end_byte >> PAGE_CACHE_SHIFT;
 	struct pagevec pvec;
 	int nr_pages;
 	int ret = 0;
-	pgoff_t index;
 
-	if (end < start)
+	if (end_byte < start_byte)
 		return 0;
 
 	pagevec_init(&pvec, 0);
-	index = start;
 	while ((index <= end) &&
 			(nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
 			PAGECACHE_TAG_WRITEBACK,
@@ -310,25 +310,6 @@
 
 	return ret;
 }
-
-/**
- * filemap_fdatawait_range - wait for all under-writeback pages to complete in a given range
- * @mapping: address space structure to wait for
- * @start:	offset in bytes where the range starts
- * @end:	offset in bytes where the range ends (inclusive)
- *
- * Walk the list of under-writeback pages of the given address space
- * in the given range and wait for all of them.
- *
- * This is just a simple wrapper so that callers don't have to convert offsets
- * to page indexes themselves
- */
-int filemap_fdatawait_range(struct address_space *mapping, loff_t start,
-			    loff_t end)
-{
-	return wait_on_page_writeback_range(mapping, start >> PAGE_CACHE_SHIFT,
-					    end >> PAGE_CACHE_SHIFT);
-}
 EXPORT_SYMBOL(filemap_fdatawait_range);
 
 /**
@@ -345,8 +326,7 @@
 	if (i_size == 0)
 		return 0;
 
-	return wait_on_page_writeback_range(mapping, 0,
-				(i_size - 1) >> PAGE_CACHE_SHIFT);
+	return filemap_fdatawait_range(mapping, 0, i_size - 1);
 }
 EXPORT_SYMBOL(filemap_fdatawait);
 
@@ -393,9 +373,8 @@
 						 WB_SYNC_ALL);
 		/* See comment of filemap_write_and_wait() */
 		if (err != -EIO) {
-			int err2 = wait_on_page_writeback_range(mapping,
-						lstart >> PAGE_CACHE_SHIFT,
-						lend >> PAGE_CACHE_SHIFT);
+			int err2 = filemap_fdatawait_range(mapping,
+						lstart, lend);
 			if (!err)
 				err = err2;
 		}
@@ -1844,7 +1823,7 @@
 
 /*
  * Copy as much as we can into the page and return the number of bytes which
- * were sucessfully copied.  If a fault is encountered then return the number of
+ * were successfully copied.  If a fault is encountered then return the number of
  * bytes which were copied.
  */
 size_t iov_iter_copy_from_user_atomic(struct page *page,
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 8bf765c..13f33b3 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -1050,8 +1050,8 @@
 	unsigned long flags;
 
 	/*
-	 * Once the object->lock is aquired, the corresponding memory block
-	 * cannot be freed (the same lock is aquired in delete_object).
+	 * Once the object->lock is acquired, the corresponding memory block
+	 * cannot be freed (the same lock is acquired in delete_object).
 	 */
 	spin_lock_irqsave(&object->lock, flags);
 	if (object->flags & OBJECT_NO_SCAN)
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index f99f599..c31a310 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -209,7 +209,7 @@
 	int	prev_priority;	/* for recording reclaim priority */
 
 	/*
-	 * While reclaiming in a hiearchy, we cache the last child we
+	 * While reclaiming in a hierarchy, we cache the last child we
 	 * reclaimed from.
 	 */
 	int last_scanned_child;
@@ -1720,7 +1720,7 @@
 /*
  * While swap-in, try_charge -> commit or cancel, the page is locked.
  * And when try_charge() successfully returns, one refcnt to memcg without
- * struct page_cgroup is aquired. This refcnt will be cumsumed by
+ * struct page_cgroup is acquired. This refcnt will be consumed by
  * "commit()" or removed by "cancel()"
  */
 int mem_cgroup_try_charge_swapin(struct mm_struct *mm,
@@ -2466,7 +2466,7 @@
 
 	cgroup_lock();
 	/*
-	 * If parent's use_hiearchy is set, we can't make any modifications
+	 * If parent's use_hierarchy is set, we can't make any modifications
 	 * in the child subtrees. If it is unset, then the change can
 	 * occur, provided the current cgroup has no children.
 	 *
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index dacc641..1ac49fe 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -174,7 +174,7 @@
 	list_for_each_entry_safe (tk, next, to_kill, nd) {
 		if (doit) {
 			/*
-			 * In case something went wrong with munmaping
+			 * In case something went wrong with munmapping
 			 * make sure the process doesn't catch the
 			 * signal and then access the memory. Just kill it.
 			 * the signal handlers
diff --git a/mm/mmap.c b/mm/mmap.c
index 292ddc3..ed70a68 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -931,13 +931,9 @@
 	if (!(flags & MAP_FIXED))
 		addr = round_hint_to_min(addr);
 
-	error = arch_mmap_check(addr, len, flags);
-	if (error)
-		return error;
-
 	/* Careful about overflows.. */
 	len = PAGE_ALIGN(len);
-	if (!len || len > TASK_SIZE)
+	if (!len)
 		return -ENOMEM;
 
 	/* offset overflow? */
@@ -948,24 +944,6 @@
 	if (mm->map_count > sysctl_max_map_count)
 		return -ENOMEM;
 
-	if (flags & MAP_HUGETLB) {
-		struct user_struct *user = NULL;
-		if (file)
-			return -EINVAL;
-
-		/*
-		 * VM_NORESERVE is used because the reservations will be
-		 * taken when vm_ops->mmap() is called
-		 * A dummy user value is used because we are not locking
-		 * memory so no accounting is necessary
-		 */
-		len = ALIGN(len, huge_page_size(&default_hstate));
-		file = hugetlb_file_setup(HUGETLB_ANON_FILE, len, VM_NORESERVE,
-						&user, HUGETLB_ANONHUGE_INODE);
-		if (IS_ERR(file))
-			return PTR_ERR(file);
-	}
-
 	/* Obtain the address to map to. we verify (or select) it and ensure
 	 * that it represents a valid section of the address space.
 	 */
@@ -1455,6 +1433,14 @@
 	unsigned long (*get_area)(struct file *, unsigned long,
 				  unsigned long, unsigned long, unsigned long);
 
+	unsigned long error = arch_mmap_check(addr, len, flags);
+	if (error)
+		return error;
+
+	/* Careful about overflows.. */
+	if (len > TASK_SIZE)
+		return -ENOMEM;
+
 	get_area = current->mm->get_unmapped_area;
 	if (file && file->f_op && file->f_op->get_unmapped_area)
 		get_area = file->f_op->get_unmapped_area;
@@ -1999,20 +1985,14 @@
 	if (!len)
 		return addr;
 
-	if ((addr + len) > TASK_SIZE || (addr + len) < addr)
-		return -EINVAL;
-
-	if (is_hugepage_only_range(mm, addr, len))
-		return -EINVAL;
-
 	error = security_file_mmap(NULL, 0, 0, 0, addr, 1);
 	if (error)
 		return error;
 
 	flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
 
-	error = arch_mmap_check(addr, len, flags);
-	if (error)
+	error = get_unmapped_area(NULL, addr, len, 0, MAP_FIXED);
+	if (error & ~PAGE_MASK)
 		return error;
 
 	/*
diff --git a/mm/mremap.c b/mm/mremap.c
index 97bff25..8451908 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -261,6 +261,137 @@
 	return new_addr;
 }
 
+static struct vm_area_struct *vma_to_resize(unsigned long addr,
+	unsigned long old_len, unsigned long new_len, unsigned long *p)
+{
+	struct mm_struct *mm = current->mm;
+	struct vm_area_struct *vma = find_vma(mm, addr);
+
+	if (!vma || vma->vm_start > addr)
+		goto Efault;
+
+	if (is_vm_hugetlb_page(vma))
+		goto Einval;
+
+	/* We can't remap across vm area boundaries */
+	if (old_len > vma->vm_end - addr)
+		goto Efault;
+
+	if (vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP)) {
+		if (new_len > old_len)
+			goto Efault;
+	}
+
+	if (vma->vm_flags & VM_LOCKED) {
+		unsigned long locked, lock_limit;
+		locked = mm->locked_vm << PAGE_SHIFT;
+		lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
+		locked += new_len - old_len;
+		if (locked > lock_limit && !capable(CAP_IPC_LOCK))
+			goto Eagain;
+	}
+
+	if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT))
+		goto Enomem;
+
+	if (vma->vm_flags & VM_ACCOUNT) {
+		unsigned long charged = (new_len - old_len) >> PAGE_SHIFT;
+		if (security_vm_enough_memory(charged))
+			goto Efault;
+		*p = charged;
+	}
+
+	return vma;
+
+Efault:	/* very odd choice for most of the cases, but... */
+	return ERR_PTR(-EFAULT);
+Einval:
+	return ERR_PTR(-EINVAL);
+Enomem:
+	return ERR_PTR(-ENOMEM);
+Eagain:
+	return ERR_PTR(-EAGAIN);
+}
+
+static unsigned long mremap_to(unsigned long addr,
+	unsigned long old_len, unsigned long new_addr,
+	unsigned long new_len)
+{
+	struct mm_struct *mm = current->mm;
+	struct vm_area_struct *vma;
+	unsigned long ret = -EINVAL;
+	unsigned long charged = 0;
+	unsigned long map_flags;
+
+	if (new_addr & ~PAGE_MASK)
+		goto out;
+
+	if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
+		goto out;
+
+	/* Check if the location we're moving into overlaps the
+	 * old location at all, and fail if it does.
+	 */
+	if ((new_addr <= addr) && (new_addr+new_len) > addr)
+		goto out;
+
+	if ((addr <= new_addr) && (addr+old_len) > new_addr)
+		goto out;
+
+	ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
+	if (ret)
+		goto out;
+
+	ret = do_munmap(mm, new_addr, new_len);
+	if (ret)
+		goto out;
+
+	if (old_len >= new_len) {
+		ret = do_munmap(mm, addr+new_len, old_len - new_len);
+		if (ret && old_len != new_len)
+			goto out;
+		old_len = new_len;
+	}
+
+	vma = vma_to_resize(addr, old_len, new_len, &charged);
+	if (IS_ERR(vma)) {
+		ret = PTR_ERR(vma);
+		goto out;
+	}
+
+	map_flags = MAP_FIXED;
+	if (vma->vm_flags & VM_MAYSHARE)
+		map_flags |= MAP_SHARED;
+
+	ret = get_unmapped_area(vma->vm_file, new_addr, new_len, vma->vm_pgoff +
+				((addr - vma->vm_start) >> PAGE_SHIFT),
+				map_flags);
+	if (ret & ~PAGE_MASK)
+		goto out1;
+
+	ret = move_vma(vma, addr, old_len, new_len, new_addr);
+	if (!(ret & ~PAGE_MASK))
+		goto out;
+out1:
+	vm_unacct_memory(charged);
+
+out:
+	return ret;
+}
+
+static int vma_expandable(struct vm_area_struct *vma, unsigned long delta)
+{
+	unsigned long end = vma->vm_end + delta;
+	if (end < vma->vm_end) /* overflow */
+		return 0;
+	if (vma->vm_next && vma->vm_next->vm_start < end) /* intersection */
+		return 0;
+	if (get_unmapped_area(NULL, vma->vm_start, end - vma->vm_start,
+			      0, MAP_FIXED) & ~PAGE_MASK)
+		return 0;
+	return 1;
+}
+
 /*
  * Expand (or shrink) an existing mapping, potentially moving it at the
  * same time (controlled by the MREMAP_MAYMOVE flag and available VM space)
@@ -294,32 +425,10 @@
 	if (!new_len)
 		goto out;
 
-	/* new_addr is only valid if MREMAP_FIXED is specified */
 	if (flags & MREMAP_FIXED) {
-		if (new_addr & ~PAGE_MASK)
-			goto out;
-		if (!(flags & MREMAP_MAYMOVE))
-			goto out;
-
-		if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
-			goto out;
-
-		/* Check if the location we're moving into overlaps the
-		 * old location at all, and fail if it does.
-		 */
-		if ((new_addr <= addr) && (new_addr+new_len) > addr)
-			goto out;
-
-		if ((addr <= new_addr) && (addr+old_len) > new_addr)
-			goto out;
-
-		ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
-		if (ret)
-			goto out;
-
-		ret = do_munmap(mm, new_addr, new_len);
-		if (ret)
-			goto out;
+		if (flags & MREMAP_MAYMOVE)
+			ret = mremap_to(addr, old_len, new_addr, new_len);
+		goto out;
 	}
 
 	/*
@@ -332,60 +441,23 @@
 		if (ret && old_len != new_len)
 			goto out;
 		ret = addr;
-		if (!(flags & MREMAP_FIXED) || (new_addr == addr))
-			goto out;
-		old_len = new_len;
+		goto out;
 	}
 
 	/*
-	 * Ok, we need to grow..  or relocate.
+	 * Ok, we need to grow..
 	 */
-	ret = -EFAULT;
-	vma = find_vma(mm, addr);
-	if (!vma || vma->vm_start > addr)
+	vma = vma_to_resize(addr, old_len, new_len, &charged);
+	if (IS_ERR(vma)) {
+		ret = PTR_ERR(vma);
 		goto out;
-	if (is_vm_hugetlb_page(vma)) {
-		ret = -EINVAL;
-		goto out;
-	}
-	/* We can't remap across vm area boundaries */
-	if (old_len > vma->vm_end - addr)
-		goto out;
-	if (vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP)) {
-		if (new_len > old_len)
-			goto out;
-	}
-	if (vma->vm_flags & VM_LOCKED) {
-		unsigned long locked, lock_limit;
-		locked = mm->locked_vm << PAGE_SHIFT;
-		lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
-		locked += new_len - old_len;
-		ret = -EAGAIN;
-		if (locked > lock_limit && !capable(CAP_IPC_LOCK))
-			goto out;
-	}
-	if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT)) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	if (vma->vm_flags & VM_ACCOUNT) {
-		charged = (new_len - old_len) >> PAGE_SHIFT;
-		if (security_vm_enough_memory(charged))
-			goto out_nc;
 	}
 
 	/* old_len exactly to the end of the area..
-	 * And we're not relocating the area.
 	 */
-	if (old_len == vma->vm_end - addr &&
-	    !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
-	    (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
-		unsigned long max_addr = TASK_SIZE;
-		if (vma->vm_next)
-			max_addr = vma->vm_next->vm_start;
+	if (old_len == vma->vm_end - addr) {
 		/* can we just expand the current mapping? */
-		if (max_addr - addr >= new_len) {
+		if (vma_expandable(vma, new_len - old_len)) {
 			int pages = (new_len - old_len) >> PAGE_SHIFT;
 
 			vma_adjust(vma, vma->vm_start,
@@ -409,28 +481,27 @@
 	 */
 	ret = -ENOMEM;
 	if (flags & MREMAP_MAYMOVE) {
-		if (!(flags & MREMAP_FIXED)) {
-			unsigned long map_flags = 0;
-			if (vma->vm_flags & VM_MAYSHARE)
-				map_flags |= MAP_SHARED;
+		unsigned long map_flags = 0;
+		if (vma->vm_flags & VM_MAYSHARE)
+			map_flags |= MAP_SHARED;
 
-			new_addr = get_unmapped_area(vma->vm_file, 0, new_len,
-						vma->vm_pgoff, map_flags);
-			if (new_addr & ~PAGE_MASK) {
-				ret = new_addr;
-				goto out;
-			}
-
-			ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
-			if (ret)
-				goto out;
+		new_addr = get_unmapped_area(vma->vm_file, 0, new_len,
+					vma->vm_pgoff +
+					((addr - vma->vm_start) >> PAGE_SHIFT),
+					map_flags);
+		if (new_addr & ~PAGE_MASK) {
+			ret = new_addr;
+			goto out;
 		}
+
+		ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
+		if (ret)
+			goto out;
 		ret = move_vma(vma, addr, old_len, new_len, new_addr);
 	}
 out:
 	if (ret & ~PAGE_MASK)
 		vm_unacct_memory(charged);
-out_nc:
 	return ret;
 }
 
diff --git a/mm/truncate.c b/mm/truncate.c
index 450cebd..2c147a7 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -490,7 +490,7 @@
  * Any pages which are found to be mapped into pagetables are unmapped prior to
  * invalidation.
  *
- * Returns -EIO if any pages could not be invalidated.
+ * Returns -EBUSY if any pages could not be invalidated.
  */
 int invalidate_inode_pages2(struct address_space *mapping)
 {
diff --git a/mm/util.c b/mm/util.c
index 7c35ad9..b377ce4 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -4,6 +4,10 @@
 #include <linux/module.h>
 #include <linux/err.h>
 #include <linux/sched.h>
+#include <linux/hugetlb.h>
+#include <linux/syscalls.h>
+#include <linux/mman.h>
+#include <linux/file.h>
 #include <asm/uaccess.h>
 
 #define CREATE_TRACE_POINTS
@@ -268,6 +272,46 @@
 }
 EXPORT_SYMBOL_GPL(get_user_pages_fast);
 
+SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
+		unsigned long, prot, unsigned long, flags,
+		unsigned long, fd, unsigned long, pgoff)
+{
+	struct file * file = NULL;
+	unsigned long retval = -EBADF;
+
+	if (!(flags & MAP_ANONYMOUS)) {
+		if (unlikely(flags & MAP_HUGETLB))
+			return -EINVAL;
+		file = fget(fd);
+		if (!file)
+			goto out;
+	} else if (flags & MAP_HUGETLB) {
+		struct user_struct *user = NULL;
+		/*
+		 * VM_NORESERVE is used because the reservations will be
+		 * taken when vm_ops->mmap() is called
+		 * A dummy user value is used because we are not locking
+		 * memory so no accounting is necessary
+		 */
+		len = ALIGN(len, huge_page_size(&default_hstate));
+		file = hugetlb_file_setup(HUGETLB_ANON_FILE, len, VM_NORESERVE,
+						&user, HUGETLB_ANONHUGE_INODE);
+		if (IS_ERR(file))
+			return PTR_ERR(file);
+	}
+
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	down_write(&current->mm->mmap_sem);
+	retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+
+	if (file)
+		fput(file);
+out:
+	return retval;
+}
+
 /* Tracepoints definitions. */
 EXPORT_TRACEPOINT_SYMBOL(kmalloc);
 EXPORT_TRACEPOINT_SYMBOL(kmem_cache_alloc);
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index 29b1b22..ef09c7b 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -78,7 +78,7 @@
 static void __bnep_link_session(struct bnep_session *s)
 {
 	/* It's safe to call __module_get() here because sessions are added
-	   by the socket layer which has to hold the refference to this module.
+	   by the socket layer which has to hold the reference to this module.
 	 */
 	__module_get(THIS_MODULE);
 	list_add(&s->list, &bnep_session_list);
@@ -632,7 +632,7 @@
 	s = __bnep_get_session(req->dst);
 	if (s) {
 		/* Wakeup user-space which is polling for socket errors.
-		 * This is temporary hack untill we have shutdown in L2CAP */
+		 * This is temporary hack until we have shutdown in L2CAP */
 		s->sock->sk->sk_err = EUNATCH;
 
 		/* Kill session thread */
diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c
index 549e206..ea5cea2 100644
--- a/net/ipv4/netfilter/ipt_ECN.c
+++ b/net/ipv4/netfilter/ipt_ECN.c
@@ -50,7 +50,7 @@
 	struct tcphdr _tcph, *tcph;
 	__be16 oldval;
 
-	/* Not enought header? */
+	/* Not enough header? */
 	tcph = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_tcph), &_tcph);
 	if (!tcph)
 		return false;
diff --git a/net/irda/irlap.c b/net/irda/irlap.c
index 356e65b..783c5f3 100644
--- a/net/irda/irlap.c
+++ b/net/irda/irlap.c
@@ -450,10 +450,10 @@
 
 	/* Check if we are in the right state for disconnecting */
 	switch (self->state) {
-	case LAP_XMIT_P:        /* FALLTROUGH */
-	case LAP_XMIT_S:        /* FALLTROUGH */
-	case LAP_CONN:          /* FALLTROUGH */
-	case LAP_RESET_WAIT:    /* FALLTROUGH */
+	case LAP_XMIT_P:        /* FALLTHROUGH */
+	case LAP_XMIT_S:        /* FALLTHROUGH */
+	case LAP_CONN:          /* FALLTHROUGH */
+	case LAP_RESET_WAIT:    /* FALLTHROUGH */
 	case LAP_RESET_CHECK:
 		irlap_do_event(self, DISCONNECT_REQUEST, NULL, NULL);
 		break;
@@ -485,9 +485,9 @@
 		IRDA_DEBUG(1, "%s(), Sending reset request!\n", __func__);
 		irlap_do_event(self, RESET_REQUEST, NULL, NULL);
 		break;
-	case LAP_NO_RESPONSE:	   /* FALLTROUGH */
-	case LAP_DISC_INDICATION:  /* FALLTROUGH */
-	case LAP_FOUND_NONE:       /* FALLTROUGH */
+	case LAP_NO_RESPONSE:	   /* FALLTHROUGH */
+	case LAP_DISC_INDICATION:  /* FALLTHROUGH */
+	case LAP_FOUND_NONE:       /* FALLTHROUGH */
 	case LAP_MEDIA_BUSY:
 		irlmp_link_disconnect_indication(self->notify.instance, self,
 						 reason, NULL);
diff --git a/net/irda/irlap_event.c b/net/irda/irlap_event.c
index c5c5195..94a9884 100644
--- a/net/irda/irlap_event.c
+++ b/net/irda/irlap_event.c
@@ -1741,7 +1741,7 @@
  * Function irlap_state_xmit_s (event, skb, info)
  *
  *   XMIT_S, The secondary station has been given the right to transmit,
- *   and we therefor do not expect to receive any transmissions from other
+ *   and we therefore do not expect to receive any transmissions from other
  *   stations.
  */
 static int irlap_state_xmit_s(struct irlap_cb *self, IRLAP_EVENT event,
diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c
index 7bf5b91..0e7d8bd 100644
--- a/net/irda/irlmp.c
+++ b/net/irda/irlmp.c
@@ -105,7 +105,7 @@
 
 	init_timer(&irlmp->discovery_timer);
 
-	/* Do discovery every 3 seconds, conditionaly */
+	/* Do discovery every 3 seconds, conditionally */
 	if (sysctl_discovery)
 		irlmp_start_discovery_timer(irlmp,
 					    sysctl_discovery_timeout*HZ);
@@ -1842,7 +1842,7 @@
 		reason = LM_CONNECT_FAILURE;
 		break;
 	default:
-		IRDA_DEBUG(1, "%s(), Unknow IrLAP disconnect reason %d!\n",
+		IRDA_DEBUG(1, "%s(), Unknown IrLAP disconnect reason %d!\n",
 			   __func__, lap_reason);
 		reason = LM_LAP_DISCONNECT;
 		break;
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index a8da239..0192cfd 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -244,7 +244,7 @@
  * @addr: destination address of the path (ETH_ALEN length)
  * @sdata: local subif
  *
- * Returns: 0 on sucess
+ * Returns: 0 on success
  *
  * State: the initial state of the new path is set to 0
  */
@@ -532,7 +532,7 @@
  * @addr: dst address (ETH_ALEN length)
  * @sdata: local subif
  *
- * Returns: 0 if succesful
+ * Returns: 0 if successful
  */
 int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata)
 {
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c
index 7a10bbe..c5d9f97 100644
--- a/net/netlabel/netlabel_domainhash.c
+++ b/net/netlabel/netlabel_domainhash.c
@@ -682,7 +682,7 @@
  * buckets and @skip_chain entries.  For each entry in the table call
  * @callback, if @callback returns a negative value stop 'walking' through the
  * table and return.  Updates the values in @skip_bkt and @skip_chain on
- * return.  Returns zero on succcess, negative values on failure.
+ * return.  Returns zero on success, negative values on failure.
  *
  */
 int netlbl_domhsh_walk(u32 *skip_bkt,
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 2a74003..64f5e32 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -598,7 +598,7 @@
 		goto errout;
 
 	/* compat_mode being true specifies a call that is supposed
-	 * to add additional backward compatiblity statistic TLVs.
+	 * to add additional backward compatibility statistic TLVs.
 	 */
 	if (compat_mode) {
 		if (a->type == TCA_OLD_COMPAT)
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index d771cc1..4e4ca65 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -717,7 +717,7 @@
 
 	if (sctp_style(sk, TCP)) {
 		/* Change the sk->sk_state of a TCP-style socket that has
-		 * sucessfully completed a connect() call.
+		 * successfully completed a connect() call.
 		 */
 		if (sctp_state(asoc, ESTABLISHED) && sctp_sstate(sk, CLOSED))
 			sk->sk_state = SCTP_SS_ESTABLISHED;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 1ef9de9..47bc20d 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -3577,7 +3577,7 @@
 	 * To do this properly, we'll set the destination address of the chunk
 	 * and at the transmit time, will try look up the transport to use.
 	 * Since ASCONFs may be bundled, the correct transport may not be
-	 * created untill we process the entire packet, thus this workaround.
+	 * created until we process the entire packet, thus this workaround.
 	 */
 	asconf_ack->dest = chunk->source;
 	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(asconf_ack));
diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
index f11be72..b15e1eb 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
@@ -54,7 +54,7 @@
  * Assumptions:
  * - head[0] is physically contiguous.
  * - tail[0] is physically contiguous.
- * - pages[] is not physically or virtually contigous and consists of
+ * - pages[] is not physically or virtually contiguous and consists of
  *   PAGE_SIZE elements.
  *
  * Output:
diff --git a/net/wimax/op-reset.c b/net/wimax/op-reset.c
index ca26917..35f3700 100644
--- a/net/wimax/op-reset.c
+++ b/net/wimax/op-reset.c
@@ -62,7 +62,7 @@
  * Called when wanting to reset the device for any reason. Device is
  * taken back to power on status.
  *
- * This call blocks; on succesful return, the device has completed the
+ * This call blocks; on successful return, the device has completed the
  * reset process and is ready to operate.
  */
 int wimax_reset(struct wimax_dev *wimax_dev)
diff --git a/samples/Kconfig b/samples/Kconfig
index e4be84a..8924f72 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -1,5 +1,3 @@
-# samples/Kconfig
-
 menuconfig SAMPLES
 	bool "Sample kernel code"
 	help
@@ -47,4 +45,3 @@
 	  This builds kernel hardware breakpoint example modules.
 
 endif # SAMPLES
-
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index d829535..8413cf3 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -213,7 +213,7 @@
 	"to modify that configuration.\n"
 	"\n"
 	"If you are uncertain, then you have probably never used alternate\n"
-	"configuration files.  You should therefor leave this blank to abort.\n"),
+	"configuration files. You should therefore leave this blank to abort.\n"),
 save_config_text[] = N_(
 	"Enter a filename to which this configuration should be saved "
 	"as an alternate.  Leave blank to abort."),
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 62a9025..6f426af 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -104,7 +104,7 @@
 static void do_usb_entry(struct usb_device_id *id,
 			 unsigned int bcdDevice_initial, int bcdDevice_initial_digits,
 			 unsigned char range_lo, unsigned char range_hi,
-			 struct module *mod)
+			 unsigned char max, struct module *mod)
 {
 	char alias[500];
 	strcpy(alias, "usb:");
@@ -118,9 +118,22 @@
 		sprintf(alias + strlen(alias), "%0*X",
 			bcdDevice_initial_digits, bcdDevice_initial);
 	if (range_lo == range_hi)
-		sprintf(alias + strlen(alias), "%u", range_lo);
-	else if (range_lo > 0 || range_hi < 9)
-		sprintf(alias + strlen(alias), "[%u-%u]", range_lo, range_hi);
+		sprintf(alias + strlen(alias), "%X", range_lo);
+	else if (range_lo > 0 || range_hi < max) {
+		if (range_lo > 0x9 || range_hi < 0xA)
+			sprintf(alias + strlen(alias),
+				"[%X-%X]",
+				range_lo,
+				range_hi);
+		else {
+			sprintf(alias + strlen(alias),
+				range_lo < 0x9 ? "[%X-9" : "[%X",
+				range_lo);
+			sprintf(alias + strlen(alias),
+				range_hi > 0xA ? "a-%X]" : "%X]",
+				range_lo);
+		}
+	}
 	if (bcdDevice_initial_digits < (sizeof(id->bcdDevice_lo) * 2 - 1))
 		strcat(alias, "*");
 
@@ -147,10 +160,49 @@
 		   "MODULE_ALIAS(\"%s\");\n", alias);
 }
 
+/* Handles increment/decrement of BCD formatted integers */
+/* Returns the previous value, so it works like i++ or i-- */
+static unsigned int incbcd(unsigned int *bcd,
+			   int inc,
+			   unsigned char max,
+			   size_t chars)
+{
+	unsigned int init = *bcd, i, j;
+	unsigned long long c, dec = 0;
+
+	/* If bcd is not in BCD format, just increment */
+	if (max > 0x9) {
+		*bcd += inc;
+		return init;
+	}
+
+	/* Convert BCD to Decimal */
+	for (i=0 ; i < chars ; i++) {
+		c = (*bcd >> (i << 2)) & 0xf;
+		c = c > 9 ? 9 : c; /* force to bcd just in case */
+		for (j=0 ; j < i ; j++)
+			c = c * 10;
+		dec += c;
+	}
+
+	/* Do our increment/decrement */
+	dec += inc;
+	*bcd  = 0;
+
+	/* Convert back to BCD */
+	for (i=0 ; i < chars ; i++) {
+		for (c=1,j=0 ; j < i ; j++)
+			c = c * 10;
+		c = (dec / c) % 10;
+		*bcd += c << (i << 2);
+	}
+	return init;
+}
+
 static void do_usb_entry_multi(struct usb_device_id *id, struct module *mod)
 {
 	unsigned int devlo, devhi;
-	unsigned char chi, clo;
+	unsigned char chi, clo, max;
 	int ndigits;
 
 	id->match_flags = TO_NATIVE(id->match_flags);
@@ -162,6 +214,17 @@
 	devhi = id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI ?
 		TO_NATIVE(id->bcdDevice_hi) : ~0x0U;
 
+	/* Figure out if this entry is in bcd or hex format */
+	max = 0x9; /* Default to decimal format */
+	for (ndigits = 0 ; ndigits < sizeof(id->bcdDevice_lo) * 2 ; ndigits++) {
+		clo = (devlo >> (ndigits << 2)) & 0xf;
+		chi = ((devhi > 0x9999 ? 0x9999 : devhi) >> (ndigits << 2)) & 0xf;
+		if (clo > max || chi > max) {
+			max = 0xf;
+			break;
+		}
+	}
+
 	/*
 	 * Some modules (visor) have empty slots as placeholder for
 	 * run-time specification that results in catch-all alias
@@ -173,21 +236,27 @@
 	for (ndigits = sizeof(id->bcdDevice_lo) * 2 - 1; devlo <= devhi; ndigits--) {
 		clo = devlo & 0xf;
 		chi = devhi & 0xf;
-		if (chi > 9)	/* it's bcd not hex */
-			chi = 9;
+		if (chi > max)	/* If we are in bcd mode, truncate if necessary */
+			chi = max;
 		devlo >>= 4;
 		devhi >>= 4;
 
 		if (devlo == devhi || !ndigits) {
-			do_usb_entry(id, devlo, ndigits, clo, chi, mod);
+			do_usb_entry(id, devlo, ndigits, clo, chi, max, mod);
 			break;
 		}
 
-		if (clo > 0)
-			do_usb_entry(id, devlo++, ndigits, clo, 9, mod);
+		if (clo > 0x0)
+			do_usb_entry(id,
+				     incbcd(&devlo, 1, max,
+					    sizeof(id->bcdDevice_lo) * 2),
+				     ndigits, clo, max, max, mod);
 
-		if (chi < 9)
-			do_usb_entry(id, devhi--, ndigits, 0, chi, mod);
+		if (chi < max)
+			do_usb_entry(id,
+				     incbcd(&devhi, -1, max,
+					    sizeof(id->bcdDevice_lo) * 2),
+				     ndigits, 0x0, chi, max, mod);
 	}
 }
 
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index e688237..2534400 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -204,7 +204,7 @@
  *
  * Description
  * Call the NetLabel mechanism to set the label of a packet using @sid.
- * Returns zero on auccess, negative values on failure.
+ * Returns zero on success, negative values on failure.
  *
  */
 int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index d6bb20c..b3efae2 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -836,7 +836,7 @@
 		goto out;
 	}
 
-	/* type/domain unchaned */
+	/* type/domain unchanged */
 	if (old_context->type == new_context->type) {
 		rc = 0;
 		goto out;
diff --git a/sound/Kconfig b/sound/Kconfig
index b3e53e6..fcad760 100644
--- a/sound/Kconfig
+++ b/sound/Kconfig
@@ -1,6 +1,3 @@
-# sound/Config.in
-#
-
 menuconfig SOUND
 	tristate "Sound card support"
 	depends on HAS_IOMEM
@@ -136,4 +133,3 @@
 	  sound subsystem and other function drivers completely unrelated to
 	  sound although they're sharing the AC97 bus. Concerned drivers
 	  should "select" this.
-
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 2f76612..0f5a194 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -1257,7 +1257,7 @@
 			break;
 		count -= count1;
 	}
-	if (file->f_flags & O_SYNC) {
+	if (file->f_flags & O_DSYNC) {
 		spin_lock_irq(&runtime->lock);
 		while (runtime->avail != runtime->buffer_size) {
 			wait_queue_t wait;
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index 93fa672..cc15d1d 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -177,7 +177,7 @@
 	{ .id = "CSC0437", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
 	/* Digital PC 5000 Onboard - CS4236B */
 	{ .id = "CSC0735", .devs = { { "CSC0000" }, { "CSC0010" } } },
-	/* some uknown CS4236B */
+	/* some unknown CS4236B */
 	{ .id = "CSC0b35", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
 	/* Intel PR440FX Onboard sound */
 	{ .id = "CSC0b36", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index 6123c75..b865e45 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -133,7 +133,7 @@
 static struct snd_miro_aci aci_device;
 
 static char * snd_opti9xx_names[] = {
-	"unkown",
+	"unknown",
 	"82C928", "82C929",
 	"82C924", "82C925",
 	"82C930", "82C931", "82C933"
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index d08c389..106be6e 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -135,6 +135,8 @@
 	unsigned long mc_base_size;
 #ifdef OPTi93X
 	unsigned long mc_indir_index;
+	unsigned long mc_indir_size;
+	struct resource *res_mc_indir;
 	struct snd_wss *codec;
 #endif	/* OPTi93X */
 	unsigned long pwd_reg;
@@ -177,7 +179,7 @@
 #endif
 
 static char * snd_opti9xx_names[] = {
-	"unkown",
+	"unknown",
 	"82C928",	"82C929",
 	"82C924",	"82C925",
 	"82C930",	"82C931",	"82C933"
@@ -231,7 +233,10 @@
 	case OPTi9XX_HW_82C931:
 	case OPTi9XX_HW_82C933:
 		chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d;
-		chip->mc_indir_index = 0xe0e;
+		if (!chip->mc_indir_index) {
+			chip->mc_indir_index = 0xe0e;
+			chip->mc_indir_size = 2;
+		}
 		chip->password = 0xe4;
 		chip->pwd_reg = 0;
 		break;
@@ -560,6 +565,48 @@
 
 #endif /* OPTi93X */
 
+static int __devinit snd_opti9xx_read_check(struct snd_opti9xx *chip)
+{
+	unsigned char value;
+#ifdef OPTi93X
+	unsigned long flags;
+#endif
+
+	chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size,
+					   "OPTi9xx MC");
+	if (chip->res_mc_base == NULL)
+		return -EBUSY;
+#ifndef OPTi93X
+	value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(1));
+	if (value != 0xff && value != inb(chip->mc_base + OPTi9XX_MC_REG(1)))
+		if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)))
+			return 0;
+#else	/* OPTi93X */
+	chip->res_mc_indir = request_region(chip->mc_indir_index,
+					    chip->mc_indir_size,
+					    "OPTi93x MC");
+	if (chip->res_mc_indir == NULL)
+		return -EBUSY;
+
+	spin_lock_irqsave(&chip->lock, flags);
+	outb(chip->password, chip->mc_base + chip->pwd_reg);
+	outb(((chip->mc_indir_index & 0x1f0) >> 4), chip->mc_base);
+	spin_unlock_irqrestore(&chip->lock, flags);
+
+	value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(7));
+	snd_opti9xx_write(chip, OPTi9XX_MC_REG(7), 0xff - value);
+	if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value)
+		return 0;
+
+	release_and_free_resource(chip->res_mc_indir);
+	chip->res_mc_indir = NULL;
+#endif	/* OPTi93X */
+	release_and_free_resource(chip->res_mc_base);
+	chip->res_mc_base = NULL;
+
+	return -ENODEV;
+}
+
 static int __devinit snd_card_opti9xx_detect(struct snd_card *card,
 					     struct snd_opti9xx *chip)
 {
@@ -567,50 +614,20 @@
 
 #ifndef OPTi93X
 	for (i = OPTi9XX_HW_82C928; i < OPTi9XX_HW_82C930; i++) {
-		unsigned char value;
-
-		if ((err = snd_opti9xx_init(chip, i)) < 0)
-			return err;
-
-		if ((chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL)
-			continue;
-
-		value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(1));
-		if ((value != 0xff) && (value != inb(chip->mc_base + 1)))
-			if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)))
-				return 1;
-
-		release_and_free_resource(chip->res_mc_base);
-		chip->res_mc_base = NULL;
-
-	}
-#else	/* OPTi93X */
+#else
 	for (i = OPTi9XX_HW_82C931; i >= OPTi9XX_HW_82C930; i--) {
-		unsigned long flags;
-		unsigned char value;
-
-		if ((err = snd_opti9xx_init(chip, i)) < 0)
+#endif
+		err = snd_opti9xx_init(chip, i);
+		if (err < 0)
 			return err;
 
-		if ((chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL)
-			continue;
-
-		spin_lock_irqsave(&chip->lock, flags);
-		outb(chip->password, chip->mc_base + chip->pwd_reg);
-		outb(((chip->mc_indir_index & (1 << 8)) >> 4) |
-			((chip->mc_indir_index & 0xf0) >> 4), chip->mc_base);
-		spin_unlock_irqrestore(&chip->lock, flags);
-
-		value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(7));
-		snd_opti9xx_write(chip, OPTi9XX_MC_REG(7), 0xff - value);
-		if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value)
+		err = snd_opti9xx_read_check(chip);
+		if (err == 0)
 			return 1;
-
-		release_and_free_resource(chip->res_mc_base);
-		chip->res_mc_base = NULL;
+#ifdef OPTi93X
+		chip->mc_indir_index = 0;
+#endif
 	}
-#endif	/* OPTi93X */
-
 	return -ENODEV;
 }
 
@@ -639,6 +656,8 @@
 #ifdef OPTi93X
 	port = pnp_port_start(pdev, 0) - 4;
 	fm_port = pnp_port_start(pdev, 1) + 8;
+	chip->mc_indir_index = pnp_port_start(pdev, 3) + 2;
+	chip->mc_indir_size = pnp_port_len(pdev, 3) - 2;
 #else
 	if (pid->driver_data != 0x0924)
 		port = pnp_port_start(pdev, 1);
@@ -669,7 +688,7 @@
 static void snd_card_opti9xx_free(struct snd_card *card)
 {
 	struct snd_opti9xx *chip = card->private_data;
-        
+
 	if (chip) {
 #ifdef OPTi93X
 		struct snd_wss *codec = chip->codec;
@@ -677,6 +696,7 @@
 			disable_irq(codec->irq);
 			free_irq(codec->irq, codec);
 		}
+		release_and_free_resource(chip->res_mc_indir);
 #endif
 		release_and_free_resource(chip->res_mc_base);
 	}
@@ -696,11 +716,6 @@
 	struct snd_rawmidi *rmidi;
 	struct snd_hwdep *synth;
 
-	if (! chip->res_mc_base &&
-	    (chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size,
-						"OPTi9xx MC")) == NULL)
-		return -ENOMEM;
-
 #if defined(CS4231) || defined(OPTi93X)
 	xdma2 = dma2;
 #else
@@ -954,6 +969,13 @@
 	}
 	if (hw <= OPTi9XX_HW_82C930)
 		chip->mc_base -= 0x80;
+
+	error = snd_opti9xx_read_check(chip);
+	if (error) {
+		snd_printk(KERN_ERR "OPTI chip not found\n");
+		snd_card_free(card);
+		return error;
+	}
 	snd_card_set_dev(card, &pcard->card->dev);
 	if ((error = snd_opti9xx_probe(card)) < 0) {
 		snd_card_free(card);
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
index 135a2b7..a513651 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -1,5 +1,3 @@
-# drivers/sound/Config.in
-#
 # 18 Apr 1998, Michael Elizabeth Chastain, <mailto:mec@shout.net>
 # More hacking for modularisation.
 #
diff --git a/sound/oss/dmasound/dmasound_paula.c b/sound/oss/dmasound/dmasound_paula.c
index 06e9e88..bb14e4c 100644
--- a/sound/oss/dmasound/dmasound_paula.c
+++ b/sound/oss/dmasound/dmasound_paula.c
@@ -657,7 +657,7 @@
 	len += sprintf(buffer+len, "\tsound.volume_right = %d [0...64]\n",
 		       dmasound.volume_right);
 	if (len >= space) {
-		printk(KERN_ERR "dmasound_paula: overlowed state buffer alloc.\n") ;
+		printk(KERN_ERR "dmasound_paula: overflowed state buffer alloc.\n") ;
 		len = space ;
 	}
 	return len;
diff --git a/sound/pci/ca0106/ca0106_proc.c b/sound/pci/ca0106/ca0106_proc.c
index 15523e6..0470461 100644
--- a/sound/pci/ca0106/ca0106_proc.c
+++ b/sound/pci/ca0106/ca0106_proc.c
@@ -233,7 +233,7 @@
 			snd_iprintf(buffer, "user-defined\n");
 			break;
 		default:
-			snd_iprintf(buffer, "unkown\n");
+			snd_iprintf(buffer, "unknown\n");
 			break;
 		}
 		snd_iprintf(buffer, "Sample Bits: ");
diff --git a/sound/pci/cs46xx/imgs/cwcdma.asp b/sound/pci/cs46xx/imgs/cwcdma.asp
index 09d24c7..a65e119 100644
--- a/sound/pci/cs46xx/imgs/cwcdma.asp
+++ b/sound/pci/cs46xx/imgs/cwcdma.asp
@@ -26,10 +26,11 @@
 //
 //
 // The purpose of this code is very simple: make it possible to tranfser
-// the samples 'as they are' with no alteration from a PCMreader SCB (DMA from host)
-// to any other SCB. This is useful for AC3 throug SPDIF. SRC (source rate converters) 
-// task always alters the samples in some how, however it's from 48khz -> 48khz. The
-// alterations are not audible, but AC3 wont work. 
+// the samples 'as they are' with no alteration from a PCMreader
+// SCB (DMA from host) to any other SCB. This is useful for AC3 through SPDIF.
+// SRC (source rate converters) task always alters the samples in somehow,
+// however it's from 48khz -> 48khz.
+// The alterations are not audible, but AC3 wont work. 
 //
 //        ...
 //         |
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 6b8ae7b..1d369ff 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -184,7 +184,7 @@
  * The hardware has 3 channels for playback and 1 for capture.
  *  - channel 0 is the front channel
  *  - channel 1 is the rear channel
- *  - channel 2 is the center/lfe chanel
+ *  - channel 2 is the center/lfe channel
  * Volume is controlled by the AC97 for the front and rear channels by
  * the PCM Playback Volume, Sigmatel Surround Playback Volume and 
  * Surround Playback Volume. The Sigmatel 4-Speaker Stereo switch affects
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index d822bfc..efcc4f7 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -2450,6 +2450,11 @@
 		}
 	}
 
+	/* disable 64bit DMA address for Teradici */
+	/* it does not work with device 6549:1200 subsys e4a2:040b */
+	if (chip->driver_type == AZX_DRIVER_TERA)
+		gcap &= ~ICH6_GCAP_64OK;
+
 	/* allow 64bit DMA address if supported by H/W */
 	if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
 		pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64));
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 455a049..447eda1 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -72,7 +72,8 @@
 	hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
 
 	unsigned int jack_present :1;
-	unsigned int inv_jack_detect:1;
+	unsigned int inv_jack_detect:1;	/* inverted jack-detection */
+	unsigned int inv_eapd:1;	/* inverted EAPD implementation */
 
 #ifdef CONFIG_SND_HDA_POWER_SAVE
 	struct hda_loopback_check loopback;
@@ -458,7 +459,7 @@
 
 /*
  * EAPD control
- * the private value = nid | (invert << 8)
+ * the private value = nid
  */
 #define ad198x_eapd_info	snd_ctl_boolean_mono_info
 
@@ -467,8 +468,7 @@
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct ad198x_spec *spec = codec->spec;
-	int invert = (kcontrol->private_value >> 8) & 1;
-	if (invert)
+	if (spec->inv_eapd)
 		ucontrol->value.integer.value[0] = ! spec->cur_eapd;
 	else
 		ucontrol->value.integer.value[0] = spec->cur_eapd;
@@ -480,11 +480,10 @@
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct ad198x_spec *spec = codec->spec;
-	int invert = (kcontrol->private_value >> 8) & 1;
 	hda_nid_t nid = kcontrol->private_value & 0xff;
 	unsigned int eapd;
 	eapd = !!ucontrol->value.integer.value[0];
-	if (invert)
+	if (spec->inv_eapd)
 		eapd = !eapd;
 	if (eapd == spec->cur_eapd)
 		return 0;
@@ -705,7 +704,7 @@
 		.info = ad198x_eapd_info,
 		.get = ad198x_eapd_get,
 		.put = ad198x_eapd_put,
-		.private_value = 0x1b | (1 << 8), /* port-D, inversed */
+		.private_value = 0x1b, /* port-D */
 	},
 	{ } /* end */
 };
@@ -1074,6 +1073,7 @@
 	spec->loopback.amplist = ad1986a_loopbacks;
 #endif
 	spec->vmaster_nid = 0x1b;
+	spec->inv_eapd = 1; /* AD1986A has the inverted EAPD implementation */
 
 	codec->patch_ops = ad198x_patch_ops;
 
@@ -2124,7 +2124,7 @@
 		.info = ad198x_eapd_info,
 		.get = ad198x_eapd_get,
 		.put = ad198x_eapd_put,
-		.private_value = 0x12 | (1 << 8), /* port-D, inversed */
+		.private_value = 0x12, /* port-D */
 	},
 
 	{ } /* end */
@@ -3065,6 +3065,7 @@
 		spec->input_mux = &ad1988_laptop_capture_source;
 		spec->num_mixers = 1;
 		spec->mixers[0] = ad1988_laptop_mixers;
+		spec->inv_eapd = 1; /* inverted EAPD */
 		spec->num_init_verbs = 1;
 		spec->init_verbs[0] = ad1988_laptop_init_verbs;
 		if (board_config == AD1988_LAPTOP_DIG)
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 2439e84..4b200da 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -938,7 +938,7 @@
 		coef |= 0x0500; /* DMIC2 enable 2 channels, disable GPIO1 */
 	if (is_active_pin(codec, CS_DMIC1_PIN_NID))
 		coef |= 0x1800; /* DMIC1 enable 2 channels, disable GPIO0 
-				 * No effect if SPDIF_OUT2 is slected in 
+				 * No effect if SPDIF_OUT2 is selected in 
 				 * IDX_SPDIF_CTL.
 				  */
 	cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index 85c81fe..a45c116 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -66,7 +66,7 @@
 
 	struct hda_pcm pcm_rec[2];	/* PCM information */
 
-	/* pin deafault configuration */
+	/* pin default configuration */
 	hda_nid_t pin_nid[NUM_PINS];
 	unsigned int def_conf[NUM_PINS];
 	unsigned int pin_def_confs;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index d967836..888b631 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -208,6 +208,7 @@
 	ALC885_MBP3,
 	ALC885_MB5,
 	ALC885_IMAC24,
+	ALC885_IMAC91,
 	ALC883_3ST_2ch_DIG,
 	ALC883_3ST_6ch_DIG,
 	ALC883_3ST_6ch,
@@ -2400,6 +2401,8 @@
 	"Speaker Playback Switch",
 	"Mono Playback Switch",
 	"IEC958 Playback Switch",
+	"Line-Out Playback Switch",
+	"PCM Playback Switch",
 	NULL,
 };
 
@@ -6618,7 +6621,7 @@
 		/* Front Mic (0x01) unused */
 		{ "Line", 0x2 },
 		/* Line 2 (0x03) unused */
-		/* CD (0x04) unsused? */
+		/* CD (0x04) unused? */
 	},
 };
 
@@ -7050,6 +7053,20 @@
 	{ } /* end */
 };
 
+static struct snd_kcontrol_new alc885_imac91_mixer[] = {
+	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
+	HDA_BIND_MUTE   ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT),
+	HDA_CODEC_MUTE  ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+	HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
+	HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
+	{ } /* end */
+};
+
+
 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
@@ -7505,6 +7522,66 @@
 	{ }
 };
 
+/* iMac 9,1 */
+static struct hda_verb alc885_imac91_init_verbs[] = {
+	/* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	/* Rear mixer */
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	/* HP Pin: output 0 (0x0c) */
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+	/* Internal Speakers: output 0 (0x0d) */
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+	/* Mic (rear) pin: input vref at 80% */
+	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	/* Front Mic pin: input vref at 80% */
+	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	/* Line In pin: use output 1 when in LineOut mode */
+	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
+
+	/* FIXME: use matrix-type input source selection */
+	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
+	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
+	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
+	/* Input mixer2 */
+	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
+	/* Input mixer3 */
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
+	/* ADC1: mute amp left and right */
+	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
+	/* ADC2: mute amp left and right */
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
+	/* ADC3: mute amp left and right */
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
+
+	{ }
+};
+
 /* iMac 24 mixer. */
 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
 	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
@@ -7551,6 +7628,26 @@
 	spec->autocfg.speaker_pins[0] = 0x14;
 }
 
+static void alc885_imac91_automute(struct hda_codec *codec)
+{
+ 	unsigned int present;
+
+	present = snd_hda_codec_read(codec, 0x14, 0,
+				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
+				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
+				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+
+}
+
+static void alc885_imac91_unsol_event(struct hda_codec *codec,
+				    unsigned int res)
+{
+	/* Headphone insertion or removal. */
+	if ((res >> 26) == ALC880_HP_EVENT)
+		alc885_imac91_automute(codec);
+}
 
 static struct hda_verb alc882_targa_verbs[] = {
 	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -8718,6 +8815,7 @@
 	[ALC885_MB5]		= "mb5",
 	[ALC885_MBP3]		= "mbp3",
 	[ALC885_IMAC24]		= "imac24",
+	[ALC885_IMAC91]		= "imac91",
 	[ALC883_3ST_2ch_DIG]	= "3stack-2ch-dig",
 	[ALC883_3ST_6ch_DIG]	= "3stack-6ch-dig",
 	[ALC883_3ST_6ch]	= "3stack-6ch",
@@ -8891,6 +8989,7 @@
 	SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
 	SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
 	SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
+	SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
 	SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
 	/* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
 	 * so apparently no perfect solution yet
@@ -9002,6 +9101,20 @@
 		.setup = alc885_imac24_setup,
 		.init_hook = alc885_imac24_init_hook,
 	},
+	[ALC885_IMAC91] = {
+		.mixers = { alc885_imac91_mixer, alc882_chmode_mixer },
+		.init_verbs = { alc885_imac91_init_verbs,
+				alc880_gpio1_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
+		.dac_nids = alc882_dac_nids,
+		.channel_mode = alc885_mbp_4ch_modes,
+		.num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
+		.input_mux = &alc882_capture_source,
+		.dig_out_nid = ALC882_DIGOUT_NID,
+		.dig_in_nid = ALC882_DIGIN_NID,
+		.unsol_event = alc885_imac91_unsol_event,
+		.init_hook = alc885_imac91_automute,
+	},
 	[ALC882_TARGA] = {
 		.mixers = { alc882_targa_mixer, alc882_chmode_mixer },
 		.init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
@@ -9908,10 +10021,12 @@
 		spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
 
 	if (!spec->adc_nids && spec->input_mux) {
-		int i;
+		int i, j;
 		spec->num_adc_nids = 0;
 		for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
+			const struct hda_input_mux *imux = spec->input_mux;
 			hda_nid_t cap;
+			hda_nid_t items[16];
 			hda_nid_t nid = alc882_adc_nids[i];
 			unsigned int wcap = get_wcaps(codec, nid);
 			/* get type */
@@ -9922,6 +10037,15 @@
 			err = snd_hda_get_connections(codec, nid, &cap, 1);
 			if (err < 0)
 				continue;
+			err = snd_hda_get_connections(codec, cap, items,
+						      ARRAY_SIZE(items));
+			if (err < 0)
+				continue;
+			for (j = 0; j < imux->num_items; j++)
+				if (imux->items[j].index >= err)
+					break;
+			if (j < imux->num_items)
+				continue;
 			spec->private_capsrc_nids[spec->num_adc_nids] = cap;
 			spec->num_adc_nids++;
 		}
@@ -16846,6 +16970,7 @@
 					ALC662_3ST_6ch_DIG),
 	SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
 			   ALC663_ASUS_H13),
+	SND_PCI_QUIRK(0x8086, 0xd604, "Intel mobo", ALC662_3ST_2ch_DIG),
 	{}
 };
 
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 110d16e..765d7bd 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -689,32 +689,14 @@
 	return change;
 }
 
-static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
+static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -10000, 100, 1);
 static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
 static const DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0);
 static const DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0);
 static const DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0);
 
-/*
- * Logarithmic volume values for WM8770
- * Computed as 20 * Log10(255 / x)
- */
-static const unsigned char wm_vol[256] = {
-	127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
-	23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
-	17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
-	13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11,
-	11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
-	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
-	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-	5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3,
-	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0
-};
-
-#define WM_VOL_MAX	(sizeof(wm_vol) - 1)
+#define WM_VOL_MAX	100
+#define WM_VOL_CNT	101	/* 0dB .. -100dB */
 #define WM_VOL_MUTE	0x8000
 
 static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
@@ -724,7 +706,8 @@
 	if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
 		nvol = 0;
 	else
-		nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
+		nvol = ((vol % WM_VOL_CNT) * (master % WM_VOL_CNT)) /
+								WM_VOL_MAX;
 
 	wm_put(ice, index, nvol);
 	wm_put_nocache(ice, index, 0x180 | nvol);
@@ -820,7 +803,7 @@
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = voices;
 	uinfo->value.integer.min = 0;		/* mute (-101dB) */
-	uinfo->value.integer.max = 0x7F;	/* 0dB */
+	uinfo->value.integer.max = WM_VOL_MAX;	/* 0dB */
 	return 0;
 }
 
@@ -850,7 +833,7 @@
 	snd_ice1712_save_gpio_status(ice);
 	for (i = 0; i < voices; i++) {
 		unsigned int vol = ucontrol->value.integer.value[i];
-		if (vol > 0x7f)
+		if (vol > WM_VOL_MAX)
 			continue;
 		vol |= spec->vol[ofs+i];
 		if (vol != spec->vol[ofs+i]) {
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c
index 0c9413d..98bc3b7 100644
--- a/sound/pci/ice1712/juli.c
+++ b/sound/pci/ice1712/juli.c
@@ -380,7 +380,7 @@
 	 * inputs) are fed from Xilinx.
 	 *
 	 * I even checked traces on board and coded a support in driver for
-	 * an alternative possiblity - the unused I2S ICE output channels
+	 * an alternative possibility - the unused I2S ICE output channels
 	 * switched to HW-IN/SPDIF-IN and providing the monitoring signal to
 	 * the DAC - to no avail. The I2S outputs seem to be unconnected.
 	 *
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 0dce331..a1b10d1 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -3017,7 +3017,7 @@
 		insel = "Coaxial";
 		break;
 	default:
-		insel = "Unkown";
+		insel = "Unknown";
 	}
 
 	switch (hdspm->control_register & HDSPM_SyncRefMask) {
@@ -3028,7 +3028,7 @@
 		syncref = "MADI";
 		break;
 	default:
-		syncref = "Unkown";
+		syncref = "Unknown";
 	}
 	snd_iprintf(buffer, "Inputsel = %s, SyncRef = %s\n", insel,
 		    syncref);
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index aa40d98..3e99fe5 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -101,7 +101,7 @@
 	pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value);
 
 	if (reg >= UDA134X_REGS_NUM) {
-		printk(KERN_ERR "%s unkown register: reg: %u",
+		printk(KERN_ERR "%s unknown register: reg: %u",
 		       __func__, reg);
 		return -EINVAL;
 	}
@@ -552,7 +552,7 @@
 					ARRAY_SIZE(uda1341_snd_controls));
 	break;
 	default:
-		printk(KERN_ERR "%s unkown codec type: %d",
+		printk(KERN_ERR "%s unknown codec type: %d",
 			__func__, pd->model);
 	return -EINVAL;
 	}
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index b8cae17..ce5515e 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -607,7 +607,7 @@
 SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0),
 SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0),
 SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1),
-SOC_SINGLE_TLV("DRC Compressor Threashold Volume", WM8903_DRC_3, 5, 124, 1,
+SOC_SINGLE_TLV("DRC Compressor Threshold Volume", WM8903_DRC_3, 5, 124, 1,
 	       drc_tlv_thresh),
 SOC_SINGLE_TLV("DRC Volume", WM8903_DRC_3, 0, 30, 1, drc_tlv_amp),
 SOC_SINGLE_TLV("DRC Minimum Gain Volume", WM8903_DRC_1, 2, 3, 1, drc_tlv_min),
@@ -617,11 +617,11 @@
 SOC_ENUM("DRC FF Delay", drc_ff_delay),
 SOC_SINGLE("DRC Anticlip Switch", WM8903_DRC_0, 1, 1, 0),
 SOC_SINGLE("DRC QR Switch", WM8903_DRC_0, 2, 1, 0),
-SOC_SINGLE_TLV("DRC QR Threashold Volume", WM8903_DRC_0, 6, 3, 0, drc_tlv_max),
+SOC_SINGLE_TLV("DRC QR Threshold Volume", WM8903_DRC_0, 6, 3, 0, drc_tlv_max),
 SOC_ENUM("DRC QR Decay Rate", drc_qr_decay),
 SOC_SINGLE("DRC Smoothing Switch", WM8903_DRC_0, 3, 1, 0),
 SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8903_DRC_0, 0, 1, 0),
-SOC_ENUM("DRC Smoothing Threashold", drc_smoothing),
+SOC_ENUM("DRC Smoothing Threshold", drc_smoothing),
 SOC_SINGLE_TLV("DRC Startup Volume", WM8903_DRC_0, 6, 18, 0, drc_tlv_startup),
 
 SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT,
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 5e32f2e..2981afa 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -689,7 +689,7 @@
 
 SOC_SINGLE("DRC Switch", WM8993_DRC_CONTROL_1, 15, 1, 0),
 SOC_ENUM("DRC Path", drc_path),
-SOC_SINGLE_TLV("DRC Compressor Threashold Volume", WM8993_DRC_CONTROL_2,
+SOC_SINGLE_TLV("DRC Compressor Threshold Volume", WM8993_DRC_CONTROL_2,
 	       2, 60, 1, drc_comp_threash),
 SOC_SINGLE_TLV("DRC Compressor Amplitude Volume", WM8993_DRC_CONTROL_3,
 	       11, 30, 1, drc_comp_amp),
@@ -709,7 +709,7 @@
 SOC_ENUM("DRC Quick Release Rate", drc_qr_rate),
 SOC_SINGLE("DRC Smoothing Switch", WM8993_DRC_CONTROL_1, 11, 1, 0),
 SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8993_DRC_CONTROL_1, 8, 1, 0),
-SOC_ENUM("DRC Smoothing Hysteresis Threashold", drc_smooth),
+SOC_ENUM("DRC Smoothing Hysteresis Threshold", drc_smooth),
 SOC_SINGLE_TLV("DRC Startup Volume", WM8993_DRC_CONTROL_4, 8, 18, 0,
 	       drc_startup_tlv),
 
diff --git a/sound/soc/imx/mx1_mx2-pcm.c b/sound/soc/imx/mx1_mx2-pcm.c
index b838665..bffffcd 100644
--- a/sound/soc/imx/mx1_mx2-pcm.c
+++ b/sound/soc/imx/mx1_mx2-pcm.c
@@ -322,12 +322,12 @@
 
 	pr_debug("%s: Requesting dma channel (%s)\n", __func__,
 						prtd->dma_params->name);
-	prtd->dma_ch = imx_dma_request_by_prio(prtd->dma_params->name,
-						DMA_PRIO_HIGH);
-	if (prtd->dma_ch < 0) {
+	ret = imx_dma_request_by_prio(prtd->dma_params->name, DMA_PRIO_HIGH);
+	if (ret < 0) {
 		printk(KERN_ERR "Error %d requesting dma channel\n", ret);
 		return ret;
 	}
+	prtd->dma_ch = ret;
 	imx_dma_config_burstlen(prtd->dma_ch,
 				prtd->dma_params->watermark_level);
 
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.c b/sound/soc/s3c24xx/s3c24xx_simtec.c
index 507b2ed..d441c3b 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec.c
+++ b/sound/soc/s3c24xx/s3c24xx_simtec.c
@@ -270,7 +270,7 @@
 		gpio_direction_output(pd->amp_gain[1], 0);
 	}
 
-	/* note, curently we assume GPA0 isn't valid amp */
+	/* note, currently we assume GPA0 isn't valid amp */
 	if (pdata->amp_gpio > 0) {
 		ret = gpio_request(pd->amp_gpio, "gpio-amp");
 		if (ret) {
diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c
index 0eb1722..1d61109 100644
--- a/sound/soc/s6000/s6000-pcm.c
+++ b/sound/soc/s6000/s6000-pcm.c
@@ -196,7 +196,7 @@
 			   0 /* destination skip after chunk (impossible) */,
 			   4 /* 16 byte burst size */,
 			   -1 /* don't conserve bandwidth */,
-			   0 /* low watermark irq descriptor theshold */,
+			   0 /* low watermark irq descriptor threshold */,
 			   0 /* disable hardware timestamps */,
 			   1 /* enable channel */);
 
diff --git a/sound/sound_core.c b/sound/sound_core.c
index 49c9981..dbca7c9 100644
--- a/sound/sound_core.c
+++ b/sound/sound_core.c
@@ -353,7 +353,7 @@
  *      @dev: device pointer
  *
  *	Allocate a special sound device by minor number from the sound
- *	subsystem. The allocated number is returned on succes. On failure
+ *	subsystem. The allocated number is returned on success. On failure
  *	a negative error code is returned.
  */
  
diff --git a/sound/synth/emux/soundfont.c b/sound/synth/emux/soundfont.c
index 63c8f45..67c9123 100644
--- a/sound/synth/emux/soundfont.c
+++ b/sound/synth/emux/soundfont.c
@@ -374,7 +374,7 @@
 
 
 /*
- * increment sample couter
+ * increment sample counter
  */
 static void
 set_sample_counter(struct snd_sf_list *sflist, struct snd_soundfont *sf,
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index f71cd28..91bb296 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -194,7 +194,8 @@
 	if (!us122l->first)
 		us122l->first = file;
 
-	if (us122l->dev->descriptor.idProduct == USB_ID_US144) {
+	if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
+	    us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
 		iface = usb_ifnum_to_if(us122l->dev, 0);
 		usb_autopm_get_interface(iface);
 	}
@@ -209,7 +210,8 @@
 	struct usb_interface *iface;
 	snd_printdd(KERN_DEBUG "%p %p\n", hw, file);
 
-	if (us122l->dev->descriptor.idProduct == USB_ID_US144) {
+	if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
+	    us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
 		iface = usb_ifnum_to_if(us122l->dev, 0);
 		usb_autopm_put_interface(iface);
 	}
@@ -476,7 +478,8 @@
 	int err;
 	struct us122l *us122l = US122L(card);
 
-	if (us122l->dev->descriptor.idProduct == USB_ID_US144) {
+	if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
+	    us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
 		err = usb_set_interface(us122l->dev, 0, 1);
 		if (err) {
 			snd_printk(KERN_ERR "usb_set_interface error \n");
@@ -495,7 +498,8 @@
 	if (!us122l_start(us122l, 44100, 256))
 		return false;
 
-	if (us122l->dev->descriptor.idProduct == USB_ID_US144)
+	if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
+	    us122l->dev->descriptor.idProduct == USB_ID_US144MKII)
 		err = us144_create_usbmidi(card);
 	else
 		err = us122l_create_usbmidi(card);
@@ -597,7 +601,8 @@
 	struct snd_card *card;
 	int err;
 
-	if (device->descriptor.idProduct == USB_ID_US144
+	if ((device->descriptor.idProduct == USB_ID_US144 ||
+	     device->descriptor.idProduct == USB_ID_US144MKII)
 		&& device->speed == USB_SPEED_HIGH) {
 		snd_printk(KERN_ERR "disable ehci-hcd to run US-144 \n");
 		return -ENODEV;
@@ -692,7 +697,8 @@
 
 	mutex_lock(&us122l->mutex);
 	/* needed, doesn't restart without: */
-	if (us122l->dev->descriptor.idProduct == USB_ID_US144) {
+	if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
+	    us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
 		err = usb_set_interface(us122l->dev, 0, 1);
 		if (err) {
 			snd_printk(KERN_ERR "usb_set_interface error \n");
@@ -737,6 +743,16 @@
 		.idVendor =	0x0644,
 		.idProduct =	USB_ID_US144
 	},
+	{
+		.match_flags =	USB_DEVICE_ID_MATCH_DEVICE,
+		.idVendor =	0x0644,
+		.idProduct =	USB_ID_US122MKII
+	},
+	{
+		.match_flags =	USB_DEVICE_ID_MATCH_DEVICE,
+		.idVendor =	0x0644,
+		.idProduct =	USB_ID_US144MKII
+	},
 	{ /* terminator */ }
 };
 
diff --git a/sound/usb/usx2y/us122l.h b/sound/usb/usx2y/us122l.h
index 4daf198..f263b3f 100644
--- a/sound/usb/usx2y/us122l.h
+++ b/sound/usb/usx2y/us122l.h
@@ -25,5 +25,7 @@
 
 #define USB_ID_US122L 0x800E
 #define USB_ID_US144 0x800F
+#define USB_ID_US122MKII 0x8021
+#define USB_ID_US144MKII 0x8020
 
 #endif